diff --git a/plugin/ippcp/examples/Makefile b/plugin/ippcp/examples/Makefile index ce9a1dbec..81226b53d 100644 --- a/plugin/ippcp/examples/Makefile +++ b/plugin/ippcp/examples/Makefile @@ -1,12 +1,12 @@ include ../../../make_config.mk -PLATFORM_LDFLAGS += -lrocksdb -lippcp -L../../.. -L../../../../ipp-crypto/_build/.build/RELEASE/lib +PLATFORM_LDFLAGS += -lrocksdb -lippcp -L../../.. -L../library/lib .PHONY: clean all: ippcp_example ippcp_example: ippcp_example.cc - $(CXX) $(CXXFLAGS) $@.cc -o$@ -I../../../include -O2 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) -I../../../../ipp-crypto/_build/.build/RELEASE/include + $(CXX) $(CXXFLAGS) $@.cc -o$@ -I../../../include -O2 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) -I../library/include clean: rm -rf ./ippcp_example diff --git a/plugin/ippcp/examples2/Makefile b/plugin/ippcp/examples2/Makefile index ce9a1dbec..81226b53d 100644 --- a/plugin/ippcp/examples2/Makefile +++ b/plugin/ippcp/examples2/Makefile @@ -1,12 +1,12 @@ include ../../../make_config.mk -PLATFORM_LDFLAGS += -lrocksdb -lippcp -L../../.. -L../../../../ipp-crypto/_build/.build/RELEASE/lib +PLATFORM_LDFLAGS += -lrocksdb -lippcp -L../../.. -L../library/lib .PHONY: clean all: ippcp_example ippcp_example: ippcp_example.cc - $(CXX) $(CXXFLAGS) $@.cc -o$@ -I../../../include -O2 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) -I../../../../ipp-crypto/_build/.build/RELEASE/include + $(CXX) $(CXXFLAGS) $@.cc -o$@ -I../../../include -O2 $(PLATFORM_LDFLAGS) $(PLATFORM_CXXFLAGS) -I../library/include clean: rm -rf ./ippcp_example diff --git a/plugin/ippcp/examples2/ippcp_example b/plugin/ippcp/examples2/ippcp_example old mode 100644 new mode 100755 index 6f49211c5..3ed6d67b3 Binary files a/plugin/ippcp/examples2/ippcp_example and b/plugin/ippcp/examples2/ippcp_example differ diff --git a/plugin/ippcp/ippcp.mk b/plugin/ippcp/ippcp.mk index ff38c32dc..c30049bfe 100644 --- a/plugin/ippcp/ippcp.mk +++ b/plugin/ippcp/ippcp.mk @@ -1,4 +1,4 @@ ippcp_SOURCES = ippcp_provider.cc ippcp_HEADERS = ippcp_provider.h ippcp_LDFLAGS = -lippcp -ippcp_CXXFLAGS = -I../ipp-crypto/_build/.build/RELEASE/include \ No newline at end of file +ippcp_CXXFLAGS = -Iplugin/ippcp/library/include \ No newline at end of file diff --git a/plugin/ippcp/library/include/crypto_mb/cpu_features.h b/plugin/ippcp/library/include/crypto_mb/cpu_features.h new file mode 100644 index 000000000..577f81d37 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/cpu_features.h @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef CPU_FEATURES_H +#define CPU_FEATURES_H + +#include + +/* definition of cpu features */ +#define mbcpCPUID_MMX 0x00000001LL /* Intel® architecture with MMX(TM) technology supported */ +#define mbcpCPUID_SSE 0x00000002LL /* Intel® Streaming SIMD Extensions (Intel® SSE) instruction set */ +#define mbcpCPUID_SSE2 0x00000004LL /* Intel® Streaming SIMD Extensions 2 (Intel® SSE2) instruction set */ +#define mbcpCPUID_SSE3 0x00000008LL /* Intel® Streaming SIMD Extensions 3 (Intel® SSE3) instruction set */ +#define mbcpCPUID_SSSE3 0x00000010LL /* Supplemental Streaming SIMD Extensions 3 (SSSE3) instruction set */ +#define mbcpCPUID_MOVBE 0x00000020LL /* Intel® instruction MOVBE */ +#define mbcpCPUID_SSE41 0x00000040LL /* Intel® Streaming SIMD Extensions 4.1 (Intel® SSE4.1) instruction set */ +#define mbcpCPUID_SSE42 0x00000080LL /* Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) instruction set */ +#define mbcpCPUID_AVX 0x00000100LL /* Intel® Advanced Vector Extensions (Intel® AVX) instruction set */ +#define mbcpAVX_ENABLEDBYOS 0x00000200LL /* Intel® Advanced Vector Extensions (Intel® AVX) instruction set is supported by OS */ +#define mbcpCPUID_AES 0x00000400LL /* AES */ +#define mbcpCPUID_CLMUL 0x00000800LL /* Intel® instruction PCLMULQDQ */ +#define mbcpCPUID_ABR 0x00001000LL /* Reserved */ +#define mbcpCPUID_RDRAND 0x00002000LL /* Intel® instruction RDRAND */ +#define mbcpCPUID_F16C 0x00004000LL /* Intel® instruction F16C */ +#define mbcpCPUID_AVX2 0x00008000LL /* Intel® Advanced Vector Extensions 2 (Intel® AVX2) */ +#define mbcpCPUID_ADX 0x00010000LL /* Intel® instructions ADOX/ADCX */ +#define mbcpCPUID_RDSEED 0x00020000LL /* Intel® instruction RDSEED */ +#define mbcpCPUID_PREFETCHW 0x00040000LL /* Intel® instruction PREFETCHW */ +#define mbcpCPUID_SHA 0x00080000LL /* Intel® Secure Hash Algorithm Extensions (Intel® SHA Extensions) */ +#define mbcpCPUID_AVX512F 0x00100000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) Foundation instruction set */ +#define mbcpCPUID_AVX512CD 0x00200000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) CD instruction set */ +#define mbcpCPUID_AVX512ER 0x00400000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) ER instruction set */ +#define mbcpCPUID_AVX512PF 0x00800000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) PF instruction set */ +#define mbcpCPUID_AVX512BW 0x01000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) BW instruction set */ +#define mbcpCPUID_AVX512DQ 0x02000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) DQ instruction set */ +#define mbcpCPUID_AVX512VL 0x04000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) VL instruction set */ +#define mbcpCPUID_AVX512VBMI 0x08000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) Bit Manipulation instructions */ +#define mbcpCPUID_MPX 0x10000000LL /* Intel® Memory Protection Extensions (Intel® MPX) */ +#define mbcpCPUID_AVX512_4FMADDPS 0x20000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) DL floating-point single precision */ +#define mbcpCPUID_AVX512_4VNNIW 0x40000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) DL enhanced word variable precision */ +#define mbcpCPUID_KNC 0x80000000LL /* Intel® Xeon® Phi(TM) Coprocessor */ +#define mbcpCPUID_AVX512IFMA 0x100000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) IFMA (PMADD52) instruction set */ +#define mbcpAVX512_ENABLEDBYOS 0x200000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) is supported by OS */ +#define mbcpCPUID_AVX512GFNI 0x400000000LL /* GFNI */ +#define mbcpCPUID_AVX512VAES 0x800000000LL /* VAES */ +#define mbcpCPUID_AVX512VCLMUL 0x1000000000LL /* VCLMUL */ +#define mbcpCPUID_AVX512VBMI2 0x2000000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) Bit Manipulation instructions 2 */ +#define mbcpCPUID_BMI1 0x4000000000LL /* BMI1 */ +#define mbcpCPUID_BMI2 0x8000000000LL /* BMI2 */ + +/* map cpu features */ +EXTERN_C int64u mbx_get_cpu_features(void); + +/* check if crypto_mb is applicable */ +EXTERN_C int mbx_is_crypto_mb_applicable(int64u cpu_features); + +/* supported algorithm */ +enum MBX_ALGO { + MBX_ALGO_RSA_1K, + MBX_ALGO_RSA_2K, + MBX_ALGO_RSA_3K, + MBX_ALGO_RSA_4K, + MBX_ALGO_X25519, + MBX_ALGO_EC_NIST_P256, + MBX_ALGO_ECDHE_NIST_P256 = MBX_ALGO_EC_NIST_P256, + MBX_ALGO_ECDSA_NIST_P256 = MBX_ALGO_EC_NIST_P256, + MBX_ALGO_EC_NIST_P384, + MBX_ALGO_ECDHE_NIST_P384 = MBX_ALGO_EC_NIST_P384, + MBX_ALGO_ECDSA_NIST_P384 = MBX_ALGO_EC_NIST_P384, + MBX_ALGO_EC_NIST_P521, + MBX_ALGO_ECDHE_NIST_P521 = MBX_ALGO_EC_NIST_P521, + MBX_ALGO_ECDSA_NIST_P521 = MBX_ALGO_EC_NIST_P521, + MBX_ALGO_EC_SM2, + MBX_ALGO_ECDHE_SM2 = MBX_ALGO_EC_SM2, + MBX_ALGO_ECDSA_SM2 = MBX_ALGO_EC_SM2, + MBX_ALGO_SM3, + MBX_ALGO_SM4, + MBX_ALGO_ECB_SM4 = MBX_ALGO_SM4, + MBX_ALGO_CBC_SM4 = MBX_ALGO_SM4, + MBX_ALGO_CTR_SM4 = MBX_ALGO_SM4, + MBX_ALGO_OFB_SM4 = MBX_ALGO_SM4, + MBX_ALGO_OFB128_SM4 = MBX_ALGO_SM4, +}; + +/* multi-buffer width implemented by library */ +enum MBX_WIDTH { + MBX_WIDTH_MB8 = 8, + MBX_WIDTH_MB16 = 16, + MBX_WIDTH_ANY = (1 << 16) - 1 +}; + +typedef int64u MBX_ALGO_INFO; + +/* check if algorithm is supported on current platform + * returns: multi-buffer width mask or 0 if algorithm not supported +*/ +EXTERN_C MBX_ALGO_INFO mbx_get_algo_info(enum MBX_ALGO algo); + +#endif /* CPU_FEATURES_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/defs.h b/plugin/ippcp/library/include/crypto_mb/defs.h new file mode 100644 index 000000000..aa5a2346b --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/defs.h @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef DEFS_H +#define DEFS_H + +/* data types */ +typedef unsigned char int8u; +typedef unsigned short int16u; +typedef unsigned int int32u; +typedef unsigned long long int64u; + +#ifndef NULL + #define NULL ((void *)0) +#endif + +/* alignment & inline */ +#if defined(__GNUC__) + #if !defined(__ALIGN64) + #define __ALIGN64 __attribute__((aligned(64))) + #endif + + #if !defined(__INLINE) + #define __INLINE static __inline__ + #endif + + #if !defined(__NOINLINE) + #define __NOINLINE __attribute__((noinline)) + #endif +#else + #if !defined(__ALIGN64) + #define __ALIGN64 __declspec(align(64)) + #endif + + #if !defined(__INLINE) + #define __INLINE static __forceinline + #endif + + #if !defined(__NOINLINE) + #define __NOINLINE __declspec(noinline) + #endif +#endif + + +/* externals */ +#undef EXTERN_C + +#ifdef __cplusplus + #define EXTERN_C extern "C" +#else + #define EXTERN_C +#endif + +#endif /* DEFS_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/ec_nistp256.h b/plugin/ippcp/library/include/crypto_mb/ec_nistp256.h new file mode 100644 index 000000000..2ffa7c58d --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/ec_nistp256.h @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_NISTP256_H +#define EC_NISTP256_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + + +/* +// ECDHE +*/ + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp256_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp256_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp256_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp256_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + + +/* +// ECDSA signature generation +*/ + +/* +// Pre-computes ECDSA signature +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer); +/* +// computes ECDSA signature +// +// pa_sign_pr[] array of pointers to the r-components of the signatures +// pa_sign_ps[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sgn_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages that have been signed +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_setup_ssl_mb8(BIGNUM* pa_inv_eph_skey[8], + BIGNUM* pa_sign_pr[8], + const BIGNUM* const pa_eph_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_complete_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_sgn_rp[8], + const BIGNUM* const pa_inv_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp256_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sig[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +#endif // BN_OPENSSL_DISABLE +#endif /* EC_NISTP256_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/ec_nistp384.h b/plugin/ippcp/library/include/crypto_mb/ec_nistp384.h new file mode 100644 index 000000000..4c3fa9895 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/ec_nistp384.h @@ -0,0 +1,186 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_NISTP384_H +#define EC_NISTP384_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + + +/* +// ECDHE +*/ + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp384_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp384_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp384_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp384_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + + +/* +// ECDSA signature generation +*/ + +/* +// Pre-computes ECDSA signature +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer); +/* +// computes ECDSA signature +// +// pa_sign_pr[] array of pointers to the r-components of the signatures +// pa_sign_ps[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sgn_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages that have been signed +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_setup_ssl_mb8(BIGNUM* pa_inv_eph_skey[8], + BIGNUM* pa_sign_pr[8], + const BIGNUM* const pa_eph_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_complete_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_sgn_rp[8], + const BIGNUM* const pa_inv_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp384_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sign[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE +#endif /* EC_NISTP384_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/ec_nistp521.h b/plugin/ippcp/library/include/crypto_mb/ec_nistp521.h new file mode 100644 index 000000000..1e938c386 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/ec_nistp521.h @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_NISTP521_H +#define EC_NISTP521_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + + +/* +// ECDHE +*/ + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp521_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp521_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp521_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp521_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + + +/* +// ECDSA signature generation +*/ + +/* +// Pre-computes ECDSA signature +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer); +/* +// computes ECDSA signature +// +// pa_sign_pr[] array of pointers to the r-components of the signatures +// pa_sign_ps[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sgn_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_setup_ssl_mb8(BIGNUM* pa_inv_eph_skey[8], + BIGNUM* pa_sign_pr[8], + const BIGNUM* const pa_eph_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_complete_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_sgn_rp[8], + const BIGNUM* const pa_inv_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp521_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sig[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +#endif // BN_OPENSSL_DISABLE +#endif /* EC_NISTP521_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/ec_sm2.h b/plugin/ippcp/library/include/crypto_mb/ec_sm2.h new file mode 100644 index 000000000..43d6f970a --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/ec_sm2.h @@ -0,0 +1,154 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_SM2_H +#define EC_SM2_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates (or NULL, if affine coordinate requested) +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_sm2_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); + +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +// +// Note: +// This function implements ECDHE over SM2 curve according to IEEE 1363-2000 standard. +*/ +EXTERN_C mbx_status mbx_sm2_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + +/* +// Computes SM2 ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_user_id[] array of pointers to the users ID +// user_id_len[] array of users ID length +// pa_msg[] array of pointers to the messages are being signed +// msg_len[] array of messages length +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_sm2_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + +/* +// Verifies SM2 ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_user_id[] array of pointers to the users ID +// user_id_len[] array of users ID length +// pa_msg[] array of pointers to the messages are being signed +// msg_len[] array of messages length +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_sm2_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_sm2_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_sm2_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_sm2_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_sm2_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sig[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE +#endif /* EC_SM2_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/ed25519.h b/plugin/ippcp/library/include/crypto_mb/ed25519.h new file mode 100644 index 000000000..8cc737dac --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/ed25519.h @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef ED25519_H +#define ED25519_H + +#include +#include + +typedef int8u ed25519_sign_component[32]; +typedef ed25519_sign_component ed25519_sign[2]; + +typedef int8u ed25519_public_key[32]; +typedef int8u ed25519_private_key[32]; + +/* +// Computes ed25519 public key +// pa_public_key[] array of pointers to the public keys +// pa_private_key[] array of pointers to the public keys Y-coordinates +*/ +EXTERN_C mbx_status mbx_ed25519_public_key_mb8(ed25519_public_key* pa_public_key[8], + const ed25519_private_key* const pa_private_key[8]); + +/* +// Computes ed25519 signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// msgLen[] lengths of the messages are being signed +// pa_private_key[] array of pointers to the signer's private keys +// pa_public_key[] array of pointers to the signer's public keys +*/ +EXTERN_C mbx_status mbx_ed25519_sign_mb8(ed25519_sign_component* pa_sign_r[8], + ed25519_sign_component* pa_sign_s[8], + const int8u* const pa_msg[8], const int32u msgLen[8], + const ed25519_private_key* const pa_private_key[8], + const ed25519_public_key* const pa_public_key[8]); + +/* +// Verifies ed25519 signature +// pa_sign_r[] array of pointers to the r-components of the verified signatures +// pa_sign_s[] array of pointers to the s-components of the verified signatures +// pa_msg[] array of pointers to the signed messages +// msgLen[] array of signed messages lengths +// pa_public_key[] array of pointers to the signer's public keys +*/ +EXTERN_C mbx_status mbx_ed25519_verify_mb8(const ed25519_sign_component* const pa_sign_r[8], + const ed25519_sign_component* const pa_sign_s[8], + const int8u* const pa_msg[8], const int32u msgLen[8], + const ed25519_public_key* const pa_public_key[8]); + +#endif /* ED25519_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/exp.h b/plugin/ippcp/library/include/crypto_mb/exp.h new file mode 100644 index 000000000..b5a76b8ae --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/exp.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EXP_H +#define EXP_H + +#include +#include + + +/* size of scratch buffer */ +EXTERN_C int mbx_exp_BufferSize(int modulusBits); + +/* exp operation */ +EXTERN_C mbx_status mbx_exp1024_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp2048_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp3072_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp4096_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +#endif /* EXP_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/rsa.h b/plugin/ippcp/library/include/crypto_mb/rsa.h new file mode 100644 index 000000000..f71f2d596 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/rsa.h @@ -0,0 +1,104 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef RSA_H +#define RSA_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include + +EXTERN_C mbx_status mbx_rsa_public_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const e_pa[8], + const BIGNUM* const n_pa[8], + int expected_rsa_bitsize); + +EXTERN_C mbx_status mbx_rsa_private_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const d_pa[8], + const BIGNUM* const n_pa[8], + int expected_rsa_bitsize); + +EXTERN_C mbx_status mbx_rsa_private_crt_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8], + int expected_rsa_bitsize); +#endif /* BN_OPENSSL_DISABLE */ + + +/* +// rsa cp methods +*/ +typedef struct _ifma_rsa_method mbx_RSA_Method; + +/* rsa public key opertaion */ +EXTERN_C const mbx_RSA_Method* mbx_RSA1K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA2K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA3K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA4K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA_pub65537_Method(int rsaBitsize); + +/* rsa private key opertaion */ +EXTERN_C const mbx_RSA_Method* mbx_RSA1K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA2K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA3K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA4K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA_private_Method(int rsaBitsize); + +/* rsa private key opertaion (ctr) */ +EXTERN_C const mbx_RSA_Method* mbx_RSA1K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA2K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA3K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA4K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA_private_crt_Method(int rsaBitsize); + +EXTERN_C int mbx_RSA_Method_BufSize(const mbx_RSA_Method* m); + + +EXTERN_C mbx_status mbx_rsa_public_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); + +EXTERN_C mbx_status mbx_rsa_private_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const d_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); + +EXTERN_C mbx_status mbx_rsa_private_crt_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const p_pa[8], + const int64u* const q_pa[8], + const int64u* const dp_pa[8], + const int64u* const dq_pa[8], + const int64u* const iq_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); +#endif /* RSA_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/sm3.h b/plugin/ippcp/library/include/crypto_mb/sm3.h new file mode 100644 index 000000000..8f7f7d8b3 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/sm3.h @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#ifndef SM3_H +#define SM3_H + +#include +#include + +#define SM3_SIZE_IN_BITS (256) /* sm3 size in bits */ +#define SM3_SIZE_IN_WORDS (SM3_SIZE_IN_BITS/(sizeof(int32u)*8)) /* sm3 hash size in words */ +#define SM3_MSG_BLOCK_SIZE (64) /* messge block size */ + +#define SM3_NUM_BUFFERS (16) /* max number of buffers in sm3 multi-buffer */ + +/* +// sm3 context for mb16 +*/ + +typedef int32u sm3_hash_mb[SM3_SIZE_IN_WORDS][SM3_NUM_BUFFERS]; /* sm3 hash value in multi-buffer format */ + +struct _sm3_context_mb16 { + int msg_buff_idx[SM3_NUM_BUFFERS]; /* buffer entry */ + int64u msg_len[SM3_NUM_BUFFERS]; /* message length */ + int8u msg_buffer[SM3_NUM_BUFFERS][SM3_MSG_BLOCK_SIZE]; /* buffer */ + __ALIGN64 + sm3_hash_mb msg_hash; /* intermediate hash */ +}; + +typedef struct _sm3_context_mb16 SM3_CTX_mb16; + +EXTERN_C mbx_status16 mbx_sm3_init_mb16(SM3_CTX_mb16* p_state); + +EXTERN_C mbx_status16 mbx_sm3_update_mb16(const int8u* const msg_pa[16], + int len[16], + SM3_CTX_mb16* p_state); + +EXTERN_C mbx_status16 mbx_sm3_final_mb16(int8u* hash_pa[16], + SM3_CTX_mb16* p_state); + +EXTERN_C mbx_status16 mbx_sm3_msg_digest_mb16(const int8u* const msg_pa[16], + int len[16], + int8u* hash_pa[16]); + +#endif /* SM3_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/sm4.h b/plugin/ippcp/library/include/crypto_mb/sm4.h new file mode 100644 index 000000000..144fb6f56 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/sm4.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#ifndef SM4_H +#define SM4_H + +#include +#include + +#define SM4_LINES (16) /* Max number of buffers */ +#define SM4_BLOCK_SIZE (16) /* SM4 data block size (bytes) */ +#define SM4_KEY_SIZE (16) /* SM4 key size (bytes) */ +#define SM4_ROUNDS (32) /* SM4 number of rounds */ +#define SM4_XTS_MAX_SIZE ((1 << 20) * SM4_BLOCK_SIZE) /* SM4 max buffer size (bytes) */ + +typedef int8u sm4_key[SM4_KEY_SIZE]; +typedef int8u sm4_xts_key[SM4_KEY_SIZE*2]; +typedef int32u mbx_sm4_key_schedule[SM4_ROUNDS][SM4_LINES]; + +EXTERN_C mbx_status16 mbx_sm4_set_key_mb16(mbx_sm4_key_schedule* key_sched, const sm4_key* pa_key[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_xts_set_keys_mb16(mbx_sm4_key_schedule* key_sched1, mbx_sm4_key_schedule* key_sched2, const sm4_xts_key* pa_key[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_ecb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched); +EXTERN_C mbx_status16 mbx_sm4_decrypt_ecb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_cbc_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_cbc_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_ctr128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_ctr[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_ctr128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_ctr[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_ofb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_iv[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_ofb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_iv[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_cfb128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_cfb128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_xts_encrypt_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], + const mbx_sm4_key_schedule* key_sched1, const mbx_sm4_key_schedule* key_sched2, + const int8u* pa_tweak[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_xts_decrypt_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], + const mbx_sm4_key_schedule* key_sched1, const mbx_sm4_key_schedule* key_sched2, + const int8u* pa_tweak[SM4_LINES]); +#endif /* SM4_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/sm4_ccm.h b/plugin/ippcp/library/include/crypto_mb/sm4_ccm.h new file mode 100644 index 000000000..45128b777 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/sm4_ccm.h @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef SM4_CCM_H +#define SM4_CCM_H + +#include + +#include + +#define MIN_CCM_IV_LENGTH 7 +#define MAX_CCM_IV_LENGTH 13 +#define MIN_CCM_TAG_LENGTH 4 +#define MAX_CCM_TAG_LENGTH 16 +#define MAX_CCM_AAD_LENGTH 65280 /* 2^16 - 2^8 */ + +#define SM4_CCM_CONTEXT_BUFFER_SLOT_TYPE int64u + +#define SM4_CCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES (sizeof(SM4_CCM_CONTEXT_BUFFER_SLOT_TYPE)) +#define SM4_CCM_CONTEXT_BUFFER_SIZE_BYTES ((SM4_LINES * SM4_BLOCK_SIZE) / SM4_CCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES) + +/* +// Enum to control call sequence +// +// Valid call sequence: +// +// 1) mbx_sm4_ccm_init_mb16 +// 2) mbx_sm4_ccm_update_aad_mb16 – optional +// 3) mbx_sm4_ccm_encrypt_mb16/mbx_sm4_ccm_decrypt_mb16 – optional, can be called as many times as necessary +// 4) mbx_sm4_ccm_get_tag_mb16 +// +// Call sequence restrictions: +// +// * mbx_sm4_ccm_get_tag_mb16 can be called after mbx_sm4_ccm_init_mb16 has been called. +// * functions at steps 2-3 can be called as many times as needed to process payload while this functions processes buffers +// with full blocks (Blocks of 16 bytes size) or empty buffers and length of processed payload is not overflowed. +// * if functions at steps 2-3 called to process a partial block, it can’t be called again. +// * if mbx_sm4_ccm_encrypt_mb16 or mbx_sm4_ccm_decrypt_mb16 was called, mbx_sm4_ccm_update_aad_mb16 can’t be called. +// * if mbx_sm4_ccm_encrypt_mb16 was called, mbx_sm4_ccm_decrypt_mb16 can’t be called. +// * if mbx_sm4_ccm_decrypt_mb16 was called, mbx_sm4_ccm_encrypt_mb16 can’t be called. +*/ +typedef enum { sm4_ccm_update_aad = 0xF0A1, sm4_ccm_start_encdec, sm4_ccm_enc, sm4_ccm_dec, sm4_ccm_get_tag } sm4_ccm_state; + +struct _sm4_ccm_context_mb16 { + int64u msg_len[SM4_LINES]; /* Message length (in bytes) of all lines */ + int64u total_processed_len[SM4_LINES]; /* Total processed plaintext/ciphertext length (in bytes) of all lines */ + int tag_len[SM4_LINES]; /* Tag length (in bytes) of all lines */ + int iv_len[SM4_LINES]; /* Total IV length (in bytes) of all lines */ + __m128i ctr0[SM4_LINES]; /* CTR0 content */ + __m128i ctr[SM4_LINES]; /* CTR content */ + __m128i hash[SM4_LINES]; /* hash value accumulator for AAD and TXT processing */ + + mbx_sm4_key_schedule key_sched; /* SM4 key schedule */ + sm4_ccm_state state; /* call sequence state */ +}; + +typedef struct _sm4_ccm_context_mb16 SM4_CCM_CTX_mb16; + +/* + * Initializes SM4-CCM context. + * + * @param[in] pa_key Array of key pointers + * @param[in] pa_iv Array of IV pointers + * @param[in] iv_len Array of IV lengths + * @param[in] tag_len Array of authentication tag lengths + * @param[in] msg_len Array of total message lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_init_mb16(const sm4_key *const pa_key[SM4_LINES], + const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + const int tag_len[SM4_LINES], + const int64u msg_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Digests additional authenticated data (AAD) for 16 buffers + * + * @param[in] pa_aad Array of AAD pointers + * @param[in] aad_len Array of AAD lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], + const int aad_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Retrieves authentication tag for 16 buffers + * + * @param[out] pa_tag Array of authentication tag pointers + * @param[in] tag_len Array of tag lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_get_tag_mb16(int8u *pa_tag[SM4_LINES], + const int tag_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Encrypts 16 buffers with SM4-CCM. + * + * @param[out] pa_out Array of ciphertext pointers + * @param[in] pa_in Array of plaintext pointers + * @param[in] in_len Array of plaintext lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Decrypts 16 buffers with SM4-CCM. + * + * @param[out] pa_out Array of plaintext pointers + * @param[in] pa_in Array of ciphertext pointers + * @param[in] in_len Array of ciphertext lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +#endif /* SM4_CCM_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/sm4_gcm.h b/plugin/ippcp/library/include/crypto_mb/sm4_gcm.h new file mode 100644 index 000000000..9dede98e9 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/sm4_gcm.h @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef SM4_GCM_H +#define SM4_GCM_H + +#include + +#include + +#define SM4_GCM_CONTEXT_BUFFER_SLOT_TYPE int64u + +#define SM4_GCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES (sizeof(SM4_GCM_CONTEXT_BUFFER_SLOT_TYPE)) +#define SM4_GCM_CONTEXT_BUFFER_SIZE_BYTES ((SM4_LINES * SM4_BLOCK_SIZE) / SM4_GCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES) + +#define SM4_GCM_HASHKEY_PWR_NUM 8 + +/* +// Enum to control call sequence +// +// Valid call sequence: +// +// 1) mbx_sm4_gcm_init_mb16 +// 2) mbx_sm4_gcm_update_iv_mb16 – optional, can be called as many times as necessary +// 3) mbx_sm4_gcm_update_aad_mb16 – optional, can be called as many times as necessary +// 4) mbx_sm4_gcm_encrypt_mb16/mbx_sm4_gcm_decrypt_mb16 – optional, can be called as many times as necessary +// 5) mbx_sm4_gcm_get_tag_mb16 +// +// Call sequence restrictions: +// +// * mbx_sm4_gcm_get_tag_mb16 can be called after IV is fully processed. +// IV is fully processed if buffer with partial block (Block of less than 16 bytes size) was processed or if mbx_sm4_gcm_update_aad_mb16 was called +// * functions at steps 2-4 can be called as many times as needed to process payload while this functions processes buffers +// with full blocks (Blocks of 16 bytes size) or empty buffers and length of processed payload is not overflowed. +// * if functions at steps 2-4 called to process a partial block, it can’t be called again. +// * if mbx_sm4_gcm_update_aad_mb16 was called, mbx_sm4_gcm_update_iv_mb16 can’t be called. +// * if mbx_sm4_gcm_encrypt_mb16 or mbx_sm4_gcm_decrypt_mb16 was called, mbx_sm4_gcm_update_aad_mb16 and mbx_sm4_gcm_update_iv_mb16 can’t be called. +// * if mbx_sm4_gcm_encrypt_mb16 was called, mbx_sm4_gcm_decrypt_mb16 can’t be called. +// * if mbx_sm4_gcm_decrypt_mb16 was called, mbx_sm4_gcm_encrypt_mb16 can’t be called. +*/ +typedef enum { sm4_gcm_update_iv = 0xF0A1, sm4_gcm_update_aad, sm4_gcm_start_encdec, sm4_gcm_enc, sm4_gcm_dec, sm4_gcm_get_tag } sm4_gcm_state; + +struct _sm4_gcm_context_mb16 { + __m128i hashkey[SM4_GCM_HASHKEY_PWR_NUM][SM4_LINES]; /* Set of hashkeys for ghash computation */ + __m128i j0[SM4_LINES]; /* J0 value accumulator for IV processing */ + __m128i ghash[SM4_LINES]; /* ghash value accumulator for AAD and TXT processing */ + __m128i ctr[SM4_LINES]; /* counter for gctr encryption */ + + /* + // buffer to store IV, AAD and TXT length in bytes + // + // this buffer is used to store IV length to compute J0 block + // and reused to store AAD and TXT length to compute ghash + // + // length is stored as follow: + // + // J0 computation: + // [64 bits with IV len (buffer 0)] + // [64 bits with IV len (buffer 1)] + // .. + // [64 bits with IV len (buffer SM4_LINES-1)] + // + // Only half of buffer is used for J0 computation + // + // ghash computation: + // [64 bits with AAD len (buffer 0)][64 bits with TXT len (buffer 0)] + // [64 bits with AAD len (buffer 1)][64 bits with TXT len (buffer 1)] + // .. + // [64 bits with AAD len (buffer SM4_LINES-1)][64 bits with TXT len (buffer SM4_LINES-1)] + // + */ + int64u len[SM4_LINES * 2]; + + mbx_sm4_key_schedule key_sched; /* SM4 key schedule */ + sm4_gcm_state state; /* call sequence state */ +}; + +typedef struct _sm4_gcm_context_mb16 SM4_GCM_CTX_mb16; + +EXTERN_C mbx_status16 mbx_sm4_gcm_init_mb16(const sm4_key *const pa_key[SM4_LINES], + const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C mbx_status16 mbx_sm4_gcm_update_iv_mb16(const int8u *const pa_iv[SM4_LINES], const int iv_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_state); +EXTERN_C mbx_status16 mbx_sm4_gcm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], const int aad_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_state); + +EXTERN_C mbx_status16 mbx_sm4_gcm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_GCM_CTX_mb16 *p_context); +EXTERN_C mbx_status16 mbx_sm4_gcm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C mbx_status16 mbx_sm4_gcm_get_tag_mb16(int8u *pa_tag[SM4_LINES], const int tag_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_context); + +#endif /* SM4_GCM_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/status.h b/plugin/ippcp/library/include/crypto_mb/status.h new file mode 100644 index 000000000..add3b5c04 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/status.h @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef STATUS_H +#define STATUS_H + +#include + +typedef int32u mbx_status; +typedef int64u mbx_status16; + +// error statuses and manipulators +#define MBX_STATUS_OK (0) +#define MBX_STATUS_MISMATCH_PARAM_ERR (1) +#define MBX_STATUS_NULL_PARAM_ERR (2) +#define MBX_STATUS_LOW_ORDER_ERR (4) +#define MBX_STATUS_SIGNATURE_ERR (8) + +__INLINE mbx_status MBX_SET_STS(mbx_status status, int numb, mbx_status sttVal) +{ + numb &= 7; /* 0 <= numb < 8 */ + status &= (mbx_status)(~(0xF << (numb*4))); + return status |= (sttVal & 0xF) << (numb*4); +} + +__INLINE mbx_status MBX_GET_STS(mbx_status status, int numb) +{ + return (status >>(numb*4)) & 0xF; +} +__INLINE mbx_status MBX_SET_STS_ALL(mbx_status stsVal) +{ + return (stsVal<<4*7) | (stsVal<<4*6) | (stsVal<<4*5) | (stsVal<<4*4) | (stsVal<<4*3) | (stsVal<<4*2) | (stsVal<<4*1) | stsVal; +} + +__INLINE mbx_status MBX_SET_STS_BY_MASK(mbx_status status, int8u mask, mbx_status sttVal) +{ + int numb; + + for(numb=0; numb<8; numb++) { + mbx_status buf_stt = (0 - ((mask>>numb) &1)) & sttVal; + status = MBX_SET_STS(status, numb, buf_stt); + } + return status; +} + +__INLINE int MBX_IS_ANY_OK_STS(mbx_status status) +{ + int ret = MBX_STATUS_OK==MBX_GET_STS(status, 0) + || MBX_STATUS_OK==MBX_GET_STS(status, 1) + || MBX_STATUS_OK==MBX_GET_STS(status, 2) + || MBX_STATUS_OK==MBX_GET_STS(status, 3) + || MBX_STATUS_OK==MBX_GET_STS(status, 4) + || MBX_STATUS_OK==MBX_GET_STS(status, 5) + || MBX_STATUS_OK==MBX_GET_STS(status, 6) + || MBX_STATUS_OK==MBX_GET_STS(status, 7); + return ret; +} + +/* +// Helpers for 64-bit status mbx_status16 +*/ + +/* Accessors for the low and high part of 64-bit status */ +__INLINE mbx_status MBX_GET_HIGH_PART_STS16(mbx_status16 status16) +{ + return ((mbx_status)(((mbx_status16)(status16) >> 32) & 0xFFFFFFFF)); +} + +__INLINE mbx_status MBX_GET_LOW_PART_STS16(mbx_status16 status16) +{ + return ((mbx_status)(status16)); +} + +__INLINE mbx_status16 MBX_SET_STS16_ALL(mbx_status16 stsVal) +{ + return (stsVal<<4*15) | (stsVal<<4*14) | (stsVal<<4*13) | (stsVal<<4*12) | (stsVal<<4*11) | (stsVal<<4*10) | (stsVal<<4*9) | (stsVal<<4*8) | \ + (stsVal<<4*7) | (stsVal<<4*6) | (stsVal<<4*5) | (stsVal<<4*4) | (stsVal<<4*3) | (stsVal<<4*2) | (stsVal<<4*1) | stsVal; +} + +__INLINE mbx_status16 MBX_SET_STS16(mbx_status16 status, int numb, mbx_status16 sttVal) +{ + numb &= 15; /* 0 <= numb < 16 */ + status &= (mbx_status16)(~((int64u)0xF << (numb*4))); + return status |= (sttVal & 0xF) << (numb*4); +} + +__INLINE mbx_status16 MBX_SET_STS16_BY_MASK(mbx_status16 status, int16u mask, mbx_status16 sttVal) +{ + int numb; + for (numb = 0; numb < 16; numb++) { + mbx_status16 buf_stt = (0 - ((mask >> numb) & 1)) & sttVal; + status = MBX_SET_STS16(status, numb, buf_stt); + } + return status; +} + +__INLINE int MBX_IS_ANY_OK_STS16(mbx_status16 status) +{ + return MBX_IS_ANY_OK_STS(MBX_GET_HIGH_PART_STS16(status)) || \ + MBX_IS_ANY_OK_STS(MBX_GET_LOW_PART_STS16(status)); +} + +#endif /* STATUS_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/version.h b/plugin/ippcp/library/include/crypto_mb/version.h new file mode 100644 index 000000000..8e6c86375 --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/version.h @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef VERSION_H +#define VERSION_H + +#include + +/* crypto_mb name & version */ +#define MBX_LIB_NAME() "crypto_mb" +#define MBX_VER_MAJOR 1 +#define MBX_VER_MINOR 0 +#define MBX_VER_REV 9 + +/* major interface version */ +#define MBX_INTERFACE_VERSION_MAJOR 11 +/* minor interface version */ +#define MBX_INTERFACE_VERSION_MINOR 9 + +typedef struct { + int major; /* e.g. 1 */ + int minor; /* e.g. 2 */ + int revision; /* e.g. 3 */ + const char* name; /* e,g. "crypto_mb" */ + const char* buildDate; /* e.g. "Oct 28 2019" */ + const char* strVersion;/* e.g. "crypto_mb (ver 1.2.3 Oct 28 2019)" */ +} mbxVersion; + +EXTERN_C const mbxVersion* mbx_getversion(void); + +#endif /* VERSION_H */ diff --git a/plugin/ippcp/library/include/crypto_mb/x25519.h b/plugin/ippcp/library/include/crypto_mb/x25519.h new file mode 100644 index 000000000..ab0231fab --- /dev/null +++ b/plugin/ippcp/library/include/crypto_mb/x25519.h @@ -0,0 +1,31 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef X25519_H +#define X25519_H + +#include +#include + +EXTERN_C mbx_status mbx_x25519_public_key_mb8(int8u* const pa_public_key[8], + const int8u* const pa_private_key[8]); + +EXTERN_C mbx_status mbx_x25519_mb8(int8u* const pa_shared_key[8], + const int8u* const pa_private_key[8], + const int8u* const pa_public_key[8]); + +#endif /* X25519_H */ diff --git a/plugin/ippcp/library/include/ippcp.h b/plugin/ippcp/library/include/ippcp.h new file mode 100644 index 000000000..9d7e467fb --- /dev/null +++ b/plugin/ippcp/library/include/ippcp.h @@ -0,0 +1,1541 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +*/ + +#if !defined( IPPCP_H__ ) || defined( _OWN_BLDPCS ) +#define IPPCP_H__ + + +#ifndef IPPCPDEFS_H__ + #include "ippcpdefs.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined( IPP_NO_DEFAULT_LIB ) + #if defined( _IPP_SEQUENTIAL_DYNAMIC ) + #pragma comment( lib, __FILE__ "/../../lib/" INTEL_PLATFORM "ippcp" ) + #elif defined( _IPP_SEQUENTIAL_STATIC ) + #pragma comment( lib, __FILE__ "/../../lib/" INTEL_PLATFORM "ippcpmt" ) + #endif +#endif + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) +#pragma warning(push) +#pragma warning(disable : 4100) // for MSVC, unreferenced parameter +#endif + +/* ///////////////////////////////////////////////////////////////////////////// +// Name: ippcpGetLibVersion +// Purpose: getting of the library version +// Returns: the structure of information about version of ippCP library +// Parameters: +// +// Notes: not necessary to release the returned structure +*/ +IPPAPI( const IppLibraryVersion*, ippcpGetLibVersion, (void) ) + + +/* +// ========================================================= +// Symmetric Ciphers +// ========================================================= +*/ + +/* TDES */ + +#define TDES_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: AES" + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESGetSize,(int *size)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESInit,(const Ipp8u* pKey, IppsDESSpec* pCtx)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESPack,(const IppsDESSpec* pCtx, Ipp8u* pBuffer)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESUnpack,(const Ipp8u* pBuffer, IppsDESSpec* pCtx)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + IppsCPPadding padding)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + IppsCPPadding padding)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pIV)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pIV)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pCtrValue, int ctrNumBitSize)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pCtrValue, int ctrNumBitSize)) + +/* AES */ +IPPAPI(IppStatus, ippsAESGetSize,(int *pSize)) +IPPAPI(IppStatus, ippsAESInit,(const Ipp8u* pKey, int keyLen, IppsAESSpec* pCtx, int ctxSize)) +IPPAPI(IppStatus, ippsAESSetKey,(const Ipp8u* pKey, int keyLen, IppsAESSpec* pCtx)) + +IPPAPI(IppStatus, ippsAESPack,(const IppsAESSpec* pCtx, Ipp8u* pBuffer, int bufSize)) +IPPAPI(IppStatus, ippsAESUnpack,(const Ipp8u* pBuffer, IppsAESSpec* pCtx, int ctxSize)) + +#define ECB_DEPRECATED "ECB functionality remains in the library, but it is not safe when used as is. \ +It is recommended to use any other mode, for example CBC." + +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsAESEncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx)) +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsAESDecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx)) + +IPPAPI(IppStatus, ippsAESEncryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESEncryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESEncryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESEncryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsAESEncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsAESEncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsAESSpec* pCtx, + Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsAESSpec* pCtx, + Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsAESEncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) +IPPAPI(IppStatus, ippsAESDecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) + +IPPAPI(IppStatus, ippsAESEncryptXTS_Direct,(const Ipp8u* pSrc, Ipp8u* pDst, int encBitsize, int aesBlkNo, + const Ipp8u* pTweakPT, + const Ipp8u* pKey, int keyBitsize, + int dataUnitBitsize)) +IPPAPI(IppStatus, ippsAESDecryptXTS_Direct,(const Ipp8u* pSrc, Ipp8u* pDst, int encBitsize, int aesBlkNo, + const Ipp8u* pTweakPT, + const Ipp8u* pKey, int keyBitsize, + int dataUnitBitsize)) + +IPPAPI(IppStatus, ippsAESSetupNoise,(Ipp32u noiseLevel, IppsAESSpec* pCtx)) +IPPAPI(IppStatus, ippsAES_GCMSetupNoise,(Ipp32u noiseLevel, IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_CMACSetupNoise,(Ipp32u noiseLevel, IppsAES_CMACState* pState)) + +/* AES multi-buffer functions */ +IPPAPI(IppStatus, ippsAES_EncryptCFB16_MB, (const Ipp8u* pSrc[], Ipp8u* pDst[], int len[], + const IppsAESSpec* pCtx[], + const Ipp8u* pIV[], + IppStatus status[], + int numBuffers)) + +/* SMS4 */ +IPPAPI(IppStatus, ippsSMS4GetSize,(int *pSize)) +IPPAPI(IppStatus, ippsSMS4Init,(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx, int ctxSize)) +IPPAPI(IppStatus, ippsSMS4SetKey,(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx)) + +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsSMS4EncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx)) +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsSMS4DecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx)) + +IPPAPI(IppStatus, ippsSMS4EncryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4EncryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4EncryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4EncryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsSMS4EncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsSMS4EncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsSMS4Spec* pCtx, + Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsSMS4Spec* pCtx, + Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsSMS4EncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) +IPPAPI(IppStatus, ippsSMS4DecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) + +/* SMS4-CCM */ +IPPAPI(IppStatus, ippsSMS4_CCMGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsSMS4_CCMInit,(const Ipp8u* pKey, int keyLen, IppsSMS4_CCMState* pCtx, int ctxSize)) + +IPPAPI(IppStatus, ippsSMS4_CCMMessageLen,(Ipp64u msgLen, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMTagLen,(int tagLen, IppsSMS4_CCMState* pCtx)) + +IPPAPI(IppStatus, ippsSMS4_CCMStart,(const Ipp8u* pIV, int ivLen, const Ipp8u* pAD, int adLen, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMGetTag,(Ipp8u* pTag, int tagLen, const IppsSMS4_CCMState* pCtx)) + +/* +// ========================================================= +// AES based authentication & confidence Primitives +// ========================================================= +*/ + +/* AES-CCM */ +IPPAPI(IppStatus, ippsAES_CCMGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsAES_CCMInit,(const Ipp8u* pKey, int keyLen, IppsAES_CCMState* pState, int ctxSize)) + +IPPAPI(IppStatus, ippsAES_CCMMessageLen,(Ipp64u msgLen, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMTagLen,(int tagLen, IppsAES_CCMState* pState)) + +IPPAPI(IppStatus, ippsAES_CCMStart,(const Ipp8u* pIV, int ivLen, const Ipp8u* pAD, int adLen, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMGetTag,(Ipp8u* pTag, int tagLen, const IppsAES_CCMState* pState)) + +/* AES-GCM */ +IPPAPI(IppStatus, ippsAES_GCMGetSize,(int * pSize)) +IPPAPI(IppStatus, ippsAES_GCMInit,(const Ipp8u* pKey, int keyLen, IppsAES_GCMState* pState, int ctxSize)) +IPPAPI(IppStatus, ippsAES_GCMReinit,(IppsAES_GCMState* pState)) + +IPPAPI(IppStatus, ippsAES_GCMReset,(IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMProcessIV,(const Ipp8u* pIV, int ivLen, + IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMProcessAAD,(const Ipp8u* pAAD, int aadLen, + IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMStart,(const Ipp8u* pIV, int ivLen, + const Ipp8u* pAAD, int aadLen, + IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMGetTag,(Ipp8u* pDstTag, int tagLen, const IppsAES_GCMState* pState)) + +/* AES-XTS */ +IPPAPI(IppStatus, ippsAES_XTSGetSize,(int * pSize)) +IPPAPI(IppStatus, ippsAES_XTSInit,(const Ipp8u* pKey, int keyLen, + int duBitsize, + IppsAES_XTSSpec* pCtx,int ctxSize)) +IPPAPI(IppStatus, ippsAES_XTSEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int bitSizeLen, + const IppsAES_XTSSpec* pCtx, + const Ipp8u* pTweak, + int startCipherBlkNo)) +IPPAPI(IppStatus, ippsAES_XTSDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int bitSizeLen, + const IppsAES_XTSSpec* pCtx, + const Ipp8u* pTweak, + int startCipherBlkNo)) + +/* AES-SIV (RFC 5297) */ +IPPAPI(IppStatus, ippsAES_S2V_CMAC,(const Ipp8u* pKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD, + Ipp8u* pV)) +IPPAPI(IppStatus, ippsAES_SIVEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + Ipp8u* pSIV, + const Ipp8u* pAuthKey, const Ipp8u* pConfKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD)) +IPPAPI(IppStatus, ippsAES_SIVDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + int* pAuthPassed, + const Ipp8u* pAuthKey, const Ipp8u* pConfKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD, + const Ipp8u* pSIV)) + +/* AES-CMAC */ +IPPAPI(IppStatus, ippsAES_CMACGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsAES_CMACInit,(const Ipp8u* pKey, int keyLen, IppsAES_CMACState* pState, int ctxSize)) + +IPPAPI(IppStatus, ippsAES_CMACUpdate,(const Ipp8u* pSrc, int len, IppsAES_CMACState* pState)) +IPPAPI(IppStatus, ippsAES_CMACFinal,(Ipp8u* pMD, int mdLen, IppsAES_CMACState* pState)) +IPPAPI(IppStatus, ippsAES_CMACGetTag,(Ipp8u* pMD, int mdLen, const IppsAES_CMACState* pState)) + + +/* +// ========================================================= +// RC4 Stream Ciphers +// ========================================================= +*/ + +#define RC4_DEPRECATED "is deprecated. This algorithm is considered weak due to known attacks on it. \ +It is obsolete and will be removed in one of the future Intel IPP Cryptography releases." + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourCheckKey, (const Ipp8u *pKey, int keyLen, IppBool* pIsWeak)) + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourGetSize, (int* pSize)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourInit, (const Ipp8u *pKey, int keyLen, IppsARCFourState *pCtx)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourReset, (IppsARCFourState* pCtx)) + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourPack,(const IppsARCFourState* pCtx, Ipp8u* pBuffer)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourUnpack,(const Ipp8u* pBuffer, IppsARCFourState* pCtx)) + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourEncrypt, (const Ipp8u *pSrc, Ipp8u *pDst, int length, IppsARCFourState *pCtx)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourDecrypt, (const Ipp8u *pSrc, Ipp8u *pDst, int length, IppsARCFourState *pCtx)) + + +/* +// ========================================================= +// One-Way Hash Functions +// ========================================================= +*/ + +#define OBSOLETE_API "is deprecated. This API is considered obsolete and will be removed in one of future Intel IPP Cryptography releases. \ +Use the following link for opening a ticket and providing feedback: https://supporttickets.intel.com/ if you have concerns." + +#define SHA1_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: SHA-2" + +/* SHA1 Hash Primitives */ +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1GetSize,(int* pSize)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Init,(IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Duplicate,(const IppsSHA1State* pSrcState, IppsSHA1State* pDstState)) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Pack,(const IppsSHA1State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Unpack,(const Ipp8u* pBuffer, IppsSHA1State* pState)) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Update,(const Ipp8u* pSrc, int len, IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Final,(Ipp8u* pMD, IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA224 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Init,(IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Duplicate,(const IppsSHA224State* pSrcState, IppsSHA224State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Pack,(const IppsSHA224State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Unpack,(const Ipp8u* pBuffer, IppsSHA224State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Update,(const Ipp8u* pSrc, int len, IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Final,(Ipp8u* pMD, IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA256 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Init,(IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Duplicate,(const IppsSHA256State* pSrcState, IppsSHA256State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Pack,(const IppsSHA256State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Unpack,(const Ipp8u* pBuffer, IppsSHA256State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Update,(const Ipp8u* pSrc, int len, IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Final,(Ipp8u* pMD, IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA384 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Init,(IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Duplicate,(const IppsSHA384State* pSrcState, IppsSHA384State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Pack,(const IppsSHA384State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Unpack,(const Ipp8u* pBuffer, IppsSHA384State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Update,(const Ipp8u* pSrc, int len, IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Final,(Ipp8u* pMD, IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA512 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Init,(IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Duplicate,(const IppsSHA512State* pSrcState, IppsSHA512State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Pack,(const IppsSHA512State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Unpack,(const Ipp8u* pBuffer, IppsSHA512State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Update,(const Ipp8u* pSrc, int len, IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Final,(Ipp8u* pMD, IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* MD5 Hash Primitives */ + +#define MD5_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: SHA-2" + +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5GetSize,(int* pSize)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Init,(IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Duplicate,(const IppsMD5State* pSrcState, IppsMD5State* pDstState)) + +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Pack,(const IppsMD5State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Unpack,(const Ipp8u* pBuffer, IppsMD5State* pState)) + +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Update,(const Ipp8u* pSrc, int len, IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Final,(Ipp8u* pMD, IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SM3 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Init,(IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Duplicate,(const IppsSM3State* pSrcState, IppsSM3State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Pack,(const IppsSM3State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Unpack,(const Ipp8u* pBuffer, IppsSM3State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Update,(const Ipp8u* pSrc, int len, IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Final,(Ipp8u* pMD, IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* generalized Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashGetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashInit,(IppsHashState* pState, IppHashAlgId hashAlg)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashPack,(const IppsHashState* pState, Ipp8u* pBuffer, int bufSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashUnpack,(const Ipp8u* pBuffer, IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashDuplicate,(const IppsHashState* pSrcState, IppsHashState* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashUpdate,(const Ipp8u* pSrc, int len, IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashGetTag,(Ipp8u* pTag, int tagLen, const IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashFinal,(Ipp8u* pMD, IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashMessage,(const Ipp8u* pMsg, int len, Ipp8u* pMD, IppHashAlgId hashAlg)) + +/* method based generalized (reduced memory footprint) Hash Primitives */ +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_MD5, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SM3, (void) ) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA1, (void) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA1_NI, (void) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA1_TT, (void) ) + +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA256, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA256_NI, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA256_TT, (void) ) + +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA224, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA224_NI, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA224_TT, (void) ) + +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA512, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA384, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA512_256, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA512_224, (void) ) + +IPPAPI( IppStatus, ippsHashMethodGetSize, (int* pSize) ) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_MD5, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SM3, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SM3, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_SHA1, (IppsHashMethod* pMethod) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_SHA1_NI, (IppsHashMethod* pMethod) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_SHA1_TT, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashMethodSet_SHA256, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA256_NI, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA256_TT, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA256, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA256_NI, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA256_TT, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashMethodSet_SHA224, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA224_NI, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA224_TT, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA224, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA224_NI, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA224_TT, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashMethodSet_SHA512, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA384, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA512_256, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA512_224, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA512, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA384, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA512_256, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA512_224, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPPAPI(IppStatus, ippsHashGetSize_rmf,(int* pSize)) +IPPAPI(IppStatus, ippsHashInit_rmf,(IppsHashState_rmf* pState, const IppsHashMethod* pMethod)) + +IPPAPI(IppStatus, ippsHashPack_rmf,(const IppsHashState_rmf* pState, Ipp8u* pBuffer, int bufSize)) +IPPAPI(IppStatus, ippsHashUnpack_rmf,(const Ipp8u* pBuffer, IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashDuplicate_rmf,(const IppsHashState_rmf* pSrcState, IppsHashState_rmf* pDstState)) + +IPPAPI(IppStatus, ippsHashUpdate_rmf,(const Ipp8u* pSrc, int len, IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashGetTag_rmf,(Ipp8u* pMD, int tagLen, const IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashFinal_rmf,(Ipp8u* pMD, IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashMessage_rmf,(const Ipp8u* pMsg, int len, Ipp8u* pMD, const IppsHashMethod* pMethod)) + +IPPAPI(IppStatus, ippsHashMethodGetInfo,(IppsHashInfo* pInfo, const IppsHashMethod* pMethod)) +IPPAPI(IppStatus, ippsHashGetInfo_rmf,(IppsHashInfo* pInfo, const IppsHashState_rmf* pState)) + +/* general MGF Primitives*/ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsMGF,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, IppHashAlgId hashAlg)) +IPPAPI(IppStatus, ippsMGF1_rmf,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, const IppsHashMethod* pMethod)) +IPPAPI(IppStatus, ippsMGF2_rmf,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, const IppsHashMethod* pMethod)) + + +/* +// ========================================================= +// Keyed-Hash Message Authentication Codes +// ========================================================= +*/ + +/* generalized Keyed HMAC primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Init,(const Ipp8u* pKey, int keyLen, IppsHMACState* pCtx, IppHashAlgId hashAlg)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Pack,(const IppsHMACState* pCtx, Ipp8u* pBuffer, int bufSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Unpack,(const Ipp8u* pBuffer, IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Duplicate,(const IppsHMACState* pSrcCtx, IppsHMACState* pDstCtx)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Update,(const Ipp8u* pSrc, int len, IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Final,(Ipp8u* pMD, int mdLen, IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_GetTag,(Ipp8u* pMD, int mdLen, const IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Message,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pKey, int keyLen, + Ipp8u* pMD, int mdLen, + IppHashAlgId hashAlg)) + +/* method based generalized (reduced memory footprint) Keyed HMAC primitives */ +IPPAPI(IppStatus, ippsHMACGetSize_rmf,(int* pSize)) +IPPAPI(IppStatus, ippsHMACInit_rmf,(const Ipp8u* pKey, int keyLen, + IppsHMACState_rmf* pCtx, + const IppsHashMethod* pMethod)) + +IPPAPI(IppStatus, ippsHMACPack_rmf,(const IppsHMACState_rmf* pCtx, Ipp8u* pBuffer, int bufSize)) +IPPAPI(IppStatus, ippsHMACUnpack_rmf,(const Ipp8u* pBuffer, IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACDuplicate_rmf,(const IppsHMACState_rmf* pSrcCtx, IppsHMACState_rmf* pDstCtx)) + +IPPAPI(IppStatus, ippsHMACUpdate_rmf,(const Ipp8u* pSrc, int len, IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACFinal_rmf,(Ipp8u* pMD, int mdLen, IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACGetTag_rmf,(Ipp8u* pMD, int mdLen, const IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACMessage_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pKey, int keyLen, + Ipp8u* pMD, int mdLen, + const IppsHashMethod* pMethod)) + + +/* +// ========================================================= +// Big Number Integer Arithmetic +// ========================================================= +*/ + +/* Signed BigNum Operations */ +IPPAPI(IppStatus, ippsBigNumGetSize,(int length, int* pSize)) +IPPAPI(IppStatus, ippsBigNumInit,(int length, IppsBigNumState* pBN)) + +IPPAPI(IppStatus, ippsCmpZero_BN,(const IppsBigNumState* pBN, Ipp32u* pResult)) +IPPAPI(IppStatus, ippsCmp_BN,(const IppsBigNumState* pA, const IppsBigNumState* pB, Ipp32u* pResult)) + +IPPAPI(IppStatus, ippsGetSize_BN,(const IppsBigNumState* pBN, int* pSize)) +IPPAPI(IppStatus, ippsSet_BN,(IppsBigNumSGN sgn, + int length, const Ipp32u* pData, + IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsGet_BN,(IppsBigNumSGN* pSgn, + int* pLength, Ipp32u* pData, + const IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsRef_BN,(IppsBigNumSGN* pSgn, int* bitSize, Ipp32u** const ppData, + const IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsExtGet_BN,(IppsBigNumSGN* pSgn, + int* pBitSize, Ipp32u* pData, + const IppsBigNumState* pBN)) + +IPPAPI(IppStatus, ippsAdd_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsSub_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMul_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMAC_BN_I, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsDiv_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pQ, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMod_BN, (IppsBigNumState* pA, IppsBigNumState* pM, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsGcd_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pGCD)) +IPPAPI(IppStatus, ippsModInv_BN,(IppsBigNumState* pA, IppsBigNumState* pM, IppsBigNumState* pInv)) + +IPPAPI(IppStatus, ippsSetOctString_BN,(const Ipp8u* pStr, int strLen, IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsGetOctString_BN,(Ipp8u* pStr, int strLen, const IppsBigNumState* pBN)) + +/* Montgomery Operations */ +IPPAPI(IppStatus, ippsMontGetSize,(IppsExpMethod method, int length, int* pSize)) +IPPAPI(IppStatus, ippsMontInit,(IppsExpMethod method, int length, IppsMontState* pCtx)) + +IPPAPI(IppStatus, ippsMontSet,(const Ipp32u* pModulo, int size, IppsMontState* pCtx)) +IPPAPI(IppStatus, ippsMontGet,(Ipp32u* pModulo, int* pSize, const IppsMontState* pCtx)) + +IPPAPI(IppStatus, ippsMontForm,(const IppsBigNumState* pA, IppsMontState* pCtx, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMontMul, (const IppsBigNumState* pA, const IppsBigNumState* pB, IppsMontState* m, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMontExp, (const IppsBigNumState* pA, const IppsBigNumState* pE, IppsMontState* m, IppsBigNumState* pR)) + +/* Pseudo-Random Number Generation */ +IPPAPI(IppStatus, ippsPRNGGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsPRNGInit, (int seedBits, IppsPRNGState* pCtx)) + +IPPAPI(IppStatus, ippsPRNGSetModulus,(const IppsBigNumState* pMod, IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGSetH0, (const IppsBigNumState* pH0, IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGSetAugment,(const IppsBigNumState* pAug, IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGSetSeed, (const IppsBigNumState* pSeed,IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGGetSeed, (const IppsPRNGState* pCtx,IppsBigNumState* pSeed)) + +IPPAPI(IppStatus, ippsPRNGen, (Ipp32u* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsPRNGen_BN, (IppsBigNumState* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsPRNGenRDRAND, (Ipp32u* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsPRNGenRDRAND_BN,(IppsBigNumState* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsTRNGenRDSEED, (Ipp32u* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsTRNGenRDSEED_BN,(IppsBigNumState* pRand, int nBits, void* pCtx)) + +/* Probable Prime Number Generation */ +IPPAPI(IppStatus, ippsPrimeGetSize,(int nMaxBits, int* pSize)) +IPPAPI(IppStatus, ippsPrimeInit, (int nMaxBits, IppsPrimeState* pCtx)) + +IPPAPI(IppStatus, ippsPrimeGen, (int nBits, int nTrials, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsPrimeTest,(int nTrials, Ipp32u* pResult, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsPrimeGen_BN,(IppsBigNumState* pPrime, int nBits, int nTrials, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsPrimeTest_BN,(const IppsBigNumState* pPrime, int nTrials, Ipp32u* pResult, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) + +IPPAPI(IppStatus, ippsPrimeGet, (Ipp32u* pPrime, int* pLen, const IppsPrimeState* pCtx)) +IPPAPI(IppStatus, ippsPrimeGet_BN,(IppsBigNumState* pPrime, const IppsPrimeState* pCtx)) + +IPPAPI(IppStatus, ippsPrimeSet, (const Ipp32u* pPrime, int nBits, IppsPrimeState* pCtx)) +IPPAPI(IppStatus, ippsPrimeSet_BN,(const IppsBigNumState* pPrime, IppsPrimeState* pCtx)) + + +/* +// ========================================================= +// RSA Cryptography +// ========================================================= +*/ +IPPAPI(IppStatus, ippsRSA_GetSizePublicKey,(int rsaModulusBitSize, int pubicExpBitSize, int* pKeySize)) +IPPAPI(IppStatus, ippsRSA_InitPublicKey,(int rsaModulusBitSize, int publicExpBitSize, + IppsRSAPublicKeyState* pKey, int keyCtxSize)) +IPPAPI(IppStatus, ippsRSA_SetPublicKey,(const IppsBigNumState* pModulus, + const IppsBigNumState* pPublicExp, + IppsRSAPublicKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetPublicKey,(IppsBigNumState* pModulus, + IppsBigNumState* pPublicExp, + const IppsRSAPublicKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_GetSizePrivateKeyType1,(int rsaModulusBitSize, int privateExpBitSize, int* pKeySize)) +IPPAPI(IppStatus, ippsRSA_InitPrivateKeyType1,(int rsaModulusBitSize, int privateExpBitSize, + IppsRSAPrivateKeyState* pKey, int keyCtxSize)) +IPPAPI(IppStatus, ippsRSA_SetPrivateKeyType1,(const IppsBigNumState* pModulus, + const IppsBigNumState* pPrivateExp, + IppsRSAPrivateKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetPrivateKeyType1,(IppsBigNumState* pModulus, + IppsBigNumState* pPrivateExp, + const IppsRSAPrivateKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_GetSizePrivateKeyType2,(int factorPbitSize, int factorQbitSize, int* pKeySize)) +IPPAPI(IppStatus, ippsRSA_InitPrivateKeyType2,(int factorPbitSize, int factorQbitSize, + IppsRSAPrivateKeyState* pKey, int keyCtxSize)) +IPPAPI(IppStatus, ippsRSA_SetPrivateKeyType2,(const IppsBigNumState* pFactorP, + const IppsBigNumState* pFactorQ, + const IppsBigNumState* pCrtExpP, + const IppsBigNumState* pCrtExpQ, + const IppsBigNumState* pInverseQ, + IppsRSAPrivateKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetPrivateKeyType2,(IppsBigNumState* pFactorP, + IppsBigNumState* pFactorQ, + IppsBigNumState* pCrtExpP, + IppsBigNumState* pCrtExpQ, + IppsBigNumState* pInverseQ, + const IppsRSAPrivateKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_GetBufferSizePublicKey,(int* pBufferSize, const IppsRSAPublicKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetBufferSizePrivateKey,(int* pBufferSize, const IppsRSAPrivateKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_Encrypt,(const IppsBigNumState* pPtxt, + IppsBigNumState* pCtxt, + const IppsRSAPublicKeyState* pKey, + Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsRSA_Decrypt,(const IppsBigNumState* pCtxt, + IppsBigNumState* pPtxt, + const IppsRSAPrivateKeyState* pKey, + Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsRSA_GenerateKeys,(const IppsBigNumState* pSrcPublicExp, + IppsBigNumState* pModulus, + IppsBigNumState* pPublicExp, + IppsBigNumState* pPrivateExp, + IppsRSAPrivateKeyState* pPrivateKeyType2, + Ipp8u* pScratchBuffer, + int nTrials, + IppsPrimeState* pPrimeGen, + IppBitSupplier rndFunc, void* pRndParam)) + +IPPAPI(IppStatus, ippsRSA_ValidateKeys,(int* pResult, + const IppsRSAPublicKeyState* pPublicKey, + const IppsRSAPrivateKeyState* pPrivateKeyType2, + const IppsRSAPrivateKeyState* pPrivateKeyType1, + Ipp8u* pScratchBuffer, + int nTrials, + IppsPrimeState* pPrimeGen, + IppBitSupplier rndFunc, void* pRndParam)) + +/* encryption scheme: RSAES-OAEP */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSAEncrypt_OAEP,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pLabel, int labLen, + const Ipp8u* pSeed, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSADecrypt_OAEP,(const Ipp8u* pSrc, + const Ipp8u* pLab, int labLen, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSAEncrypt_OAEP_rmf,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pLabel, int labLen, + const Ipp8u* pSeed, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSADecrypt_OAEP_rmf,(const Ipp8u* pSrc, + const Ipp8u* pLab, int labLen, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +/* encryption scheme: RSAES-PKCS_v1_5 */ + +#define PKCS_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: RSA-OAEP" + +IPP_DEPRECATED(PKCS_DEPRECATED) \ +IPPAPI(IppStatus, ippsRSAEncrypt_PKCSv15,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pRndPS, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(PKCS_DEPRECATED) \ +IPPAPI(IppStatus, ippsRSADecrypt_PKCSv15,(const Ipp8u* pSrc, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + Ipp8u* pBuffer)) + +/* signature scheme : RSA-SSA-PSS */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSASign_PSS,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSalt, int saltLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSAVerify_PSS,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, + int* pIsValid, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSASign_PSS_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSalt, int saltLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSAVerify_PSS_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, + int* pIsValid, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +/* signature scheme : RSA-SSA-PKCS1-v1_5 */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSASign_PKCS1v15,(const Ipp8u* pMsg, int msgLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSAVerify_PKCS1v15,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, int* pIsValid, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSASign_PKCS1v15_rmf,(const Ipp8u* pMsg, int msgLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSAVerify_PKCS1v15_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, int* pIsValid, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +/* +// ========================================================= +// DL Cryptography +// ========================================================= +*/ +IPPAPI( const char*, ippsDLGetResultString, (IppDLResult code)) + +/* Initialization */ +IPPAPI(IppStatus, ippsDLPGetSize,(int bitSizeP, int bitSizeR, int* pSize)) +IPPAPI(IppStatus, ippsDLPInit, (int bitSizeP, int bitSizeR, IppsDLPState* pCtx)) + +IPPAPI(IppStatus, ippsDLPPack,(const IppsDLPState* pCtx, Ipp8u* pBuffer)) +IPPAPI(IppStatus, ippsDLPUnpack,(const Ipp8u* pBuffer, IppsDLPState* pCtx)) + +/* Set Up and Retrieve Domain Parameters */ +IPPAPI(IppStatus, ippsDLPSet,(const IppsBigNumState* pP, + const IppsBigNumState* pR, + const IppsBigNumState* pG, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPGet,(IppsBigNumState* pP, + IppsBigNumState* pR, + IppsBigNumState* pG, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPSetDP,(const IppsBigNumState* pDP, IppDLPKeyTag tag, IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPGetDP,(IppsBigNumState* pDP, IppDLPKeyTag tag, const IppsDLPState* pCtx)) + +/* Key Generation, Validation and Set Up */ +IPPAPI(IppStatus, ippsDLPGenKeyPair,(IppsBigNumState* pPrvKey, IppsBigNumState* pPubKey, + IppsDLPState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsDLPPublicKey, (const IppsBigNumState* pPrvKey, + IppsBigNumState* pPubKey, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPValidateKeyPair,(const IppsBigNumState* pPrvKey, + const IppsBigNumState* pPubKey, + IppDLResult* pResult, + IppsDLPState* pCtx)) + +IPPAPI(IppStatus, ippsDLPSetKeyPair,(const IppsBigNumState* pPrvKey, + const IppsBigNumState* pPubKey, + IppsDLPState* pCtx)) + +/* Signing/Verifying (DSA version) */ +IPPAPI(IppStatus, ippsDLPSignDSA, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPVerifyDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppDLResult* pResult, + IppsDLPState* pCtx)) + +/* Shared Secret Element (DH version) */ +IPPAPI(IppStatus, ippsDLPSharedSecretDH,(const IppsBigNumState* pPrvKeyA, + const IppsBigNumState* pPubKeyB, + IppsBigNumState* pShare, + IppsDLPState* pCtx)) + +/* DSA's parameter Generation and Validation */ +IPPAPI(IppStatus, ippsDLPGenerateDSA,(const IppsBigNumState* pSeedIn, + int nTrials, IppsDLPState* pCtx, + IppsBigNumState* pSeedOut, int* pCounter, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsDLPValidateDSA,(int nTrials, IppDLResult* pResult, IppsDLPState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) + +/* DH parameter's Generation and Validation */ +IPPAPI(IppStatus, ippsDLPGenerateDH,(const IppsBigNumState* pSeedIn, + int nTrials, IppsDLPState* pCtx, + IppsBigNumState* pSeedOut, int* pCounter, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsDLPValidateDH,(int nTrials, IppDLResult* pResult, IppsDLPState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) + + +/* +// ========================================================= +// EC Cryptography +// ========================================================= +*/ +IPPAPI( const char*, ippsECCGetResultString, (IppECResult code)) + +/* +// EC over Prime Fields +*/ +/* general EC initialization */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSize,(int feBitSize, int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd128r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd128r2,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd192r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd224r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd256r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd384r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd521r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStdSM2, (int* pSize)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInit,(int feBitSize, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd128r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd128r2,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd192r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd224r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd256r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd384r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd521r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStdSM2, (IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSet,(const IppsBigNumState* pPrime, + const IppsBigNumState* pA, const IppsBigNumState* pB, + const IppsBigNumState* pGX,const IppsBigNumState* pGY,const IppsBigNumState* pOrder, + int cofactor, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd,(IppECCType flag, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd128r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd128r2,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd192r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd224r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd256r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd384r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd521r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStdSM2, (IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd192r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd224r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd256r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd384r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd521r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStdSM2, (IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGet,(IppsBigNumState* pPrime, + IppsBigNumState* pA, IppsBigNumState* pB, + IppsBigNumState* pGX,IppsBigNumState* pGY,IppsBigNumState* pOrder, + int* cofactor, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetOrderBitSize,(int* pBitSize, IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPValidate,(int nTrials, IppECResult* pResult, IppsECCPState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) + +/* EC Point */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPPointGetSize,(int feBitSize, int* pSize)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPPointInit,(int feBitSize, IppsECCPPointState* pPoint)) + +/* Setup/retrieve point's coordinates */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetPoint,(const IppsBigNumState* pX, const IppsBigNumState* pY, + IppsECCPPointState* pPoint, IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetPointAtInfinity,(IppsECCPPointState* pPoint, IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetPoint,(IppsBigNumState* pX, IppsBigNumState* pY, + const IppsECCPPointState* pPoint, IppsECCPState* pEC)) + +/* EC Point Operations */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPCheckPoint,(const IppsECCPPointState* pP, + IppECResult* pResult, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPComparePoint,(const IppsECCPPointState* pP, const IppsECCPPointState* pQ, + IppECResult* pResult, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPNegativePoint,(const IppsECCPPointState* pP, + IppsECCPPointState* pR, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPAddPoint,(const IppsECCPPointState* pP, const IppsECCPPointState* pQ, + IppsECCPPointState* pR, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPMulPointScalar,(const IppsECCPPointState* pP, const IppsBigNumState* pK, + IppsECCPPointState* pR, IppsECCPState* pEC)) + +/* Key Generation, Setup and Validation */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGenKeyPair,(IppsBigNumState* pPrivate, IppsECCPPointState* pPublic, + IppsECCPState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPPublicKey,(const IppsBigNumState* pPrivate, + IppsECCPPointState* pPublic, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPValidateKeyPair,(const IppsBigNumState* pPrivate, const IppsECCPPointState* pPublic, + IppECResult* pResult, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetKeyPair,(const IppsBigNumState* pPrivate, const IppsECCPPointState* pPublic, + IppBool regular, + IppsECCPState* pEC)) + +/* Shared Secret (DH scheme ) */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSharedSecretDH,(const IppsBigNumState* pPrivateA, + const IppsECCPPointState* pPublicB, + IppsBigNumState* pShare, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSharedSecretDHC,(const IppsBigNumState* pPrivateA, + const IppsECCPPointState* pPublicB, + IppsBigNumState* pShare, + IppsECCPState* pEC)) + +/* Sign/Verify */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSignDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrivate, + IppsBigNumState* pSignX, IppsBigNumState* pSignY, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPVerifyDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignX, const IppsBigNumState* pSignY, + IppECResult* pResult, + IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSignNR,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrivate, + IppsBigNumState* pSignX, IppsBigNumState* pSignY, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPVerifyNR,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignX, const IppsBigNumState* pSignY, + IppECResult* pResult, + IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSignSM2,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPVerifySM2,(const IppsBigNumState* pMsgDigest, + const IppsECCPPointState* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsECCPState* pEC)) + +/* +// GF over prime and its extension +*/ +IPPAPI(IppStatus, ippsGFpGetSize, (int feBitSize, int* pSize)) +IPPAPI(IppStatus, ippsGFpInitArbitrary,(const IppsBigNumState* pPrime, int primeBitSize, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpInitFixed,(int primeBitSize, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpInit, (const IppsBigNumState* pPrime, int primeBitSize, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFp)) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p192r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p224r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p384r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p521r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256sm2,(void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256bn, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_pArb, (void) ) + +IPPAPI(IppStatus, ippsGFpxGetSize,(const IppsGFpState* pGroundGF, int degree, int* pSize)) +IPPAPI(IppStatus, ippsGFpxInit, (const IppsGFpState* pGroundGF, int extDeg, const IppsGFpElement* const ppGroundElm[], int nElm, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFpx)) +IPPAPI(IppStatus, ippsGFpxInitBinomial,(const IppsGFpState* pGroundGF, int extDeg, const IppsGFpElement* pGroundElm, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFpx)) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom2_epid2,(void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom3_epid2,(void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom2, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom3, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_com, (void) ) + +IPPAPI(IppStatus, ippsGFpScratchBufferSize,(int nExponents, int ExpBitSize, const IppsGFpState* pGFp, int* pBufferSize)) + +IPPAPI(IppStatus, ippsGFpElementGetSize,(const IppsGFpState* pGFp, int* pElementSize)) +IPPAPI(IppStatus, ippsGFpElementInit, (const Ipp32u* pA, int lenA, IppsGFpElement* pR, IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpSetElement, (const Ipp32u* pA, int lenA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSetElementRegular,(const IppsBigNumState* pBN, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSetElementOctString,(const Ipp8u* pStr, int strSize, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSetElementRandom,(IppsGFpElement* pR, IppsGFpState* pGFp, IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsGFpSetElementHash,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGFp, IppHashAlgId hashID)) +IPPAPI(IppStatus, ippsGFpSetElementHash_rmf,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGFp, const IppsHashMethod* pMethod)) +IPPAPI(IppStatus, ippsGFpCpyElement,(const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpGetElement,(const IppsGFpElement* pA, Ipp32u* pDataA, int lenA, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpGetElementOctString,(const IppsGFpElement* pA, Ipp8u* pStr, int strSize, IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpCmpElement,(const IppsGFpElement* pA, const IppsGFpElement* pB, int* pResult, const IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpIsZeroElement,(const IppsGFpElement* pA, int* pResult, const IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpIsUnityElement,(const IppsGFpElement* pA, int* pResult, const IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpConj,(const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpNeg, (const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpInv, (const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSqrt,(const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSqr, (const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpAdd, (const IppsGFpElement* pA, const IppsGFpElement* pB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSub, (const IppsGFpElement* pA, const IppsGFpElement* pB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpMul, (const IppsGFpElement* pA, const IppsGFpElement* pB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpExp, (const IppsGFpElement* pA, const IppsBigNumState* pE, IppsGFpElement* pR, IppsGFpState* pGFp, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpMultiExp,(const IppsGFpElement* const ppElmA[], const IppsBigNumState* const ppE[], int nItems, IppsGFpElement* pR, IppsGFpState* pGFp, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpAdd_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSub_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpMul_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, IppsGFpElement* pR, IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpGetInfo, (IppsGFpInfo* pInfo, const IppsGFpState* pGFp)) + +/* ================== */ +IPPAPI(IppStatus, ippsGFpECGetSize,(const IppsGFpState* pGFp, int* pSize)) +IPPAPI(IppStatus, ippsGFpECInit, (const IppsGFpState* pGFp, + const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECSet,(const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetSubgroup,(const IppsGFpElement* pX, const IppsGFpElement* pY, + const IppsBigNumState* pOrder, + const IppsBigNumState* pCofactor, + IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECInitStd128r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd128r2,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd192r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd224r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd256r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd384r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd521r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStdSM2, (const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStdBN256,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd192r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd224r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd256r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd384r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd521r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStdSM2, (IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECGet,(IppsGFpState** const ppGFp, + IppsGFpElement* pA, IppsGFpElement* pB, + const IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECGetSubgroup,(IppsGFpState** const ppGFp, + IppsGFpElement* pX, IppsGFpElement* pY, + IppsBigNumState* pOrder,IppsBigNumState* pCofactor, + const IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECScratchBufferSize,(int nScalars, const IppsGFpECState* pEC, int* pBufferSize)) + +IPPAPI(IppStatus, ippsGFpECVerify,(IppECResult* pResult, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECPointGetSize,(const IppsGFpECState* pEC, int* pSize)) +IPPAPI(IppStatus, ippsGFpECPointInit, (const IppsGFpElement* pX, const IppsGFpElement* pY, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECSetPointAtInfinity,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPoint,(const IppsGFpElement* pX, const IppsGFpElement* pY, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPointRegular,(const IppsBigNumState* pX, const IppsBigNumState* pY, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPointRandom,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC, IppBitSupplier rndFunc, void* pRndParam, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECMakePoint,(const IppsGFpElement* pX, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsGFpECSetPointHash,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, IppHashAlgId hashID, Ipp8u* pScratchBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsGFpECSetPointHashBackCompatible,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, IppHashAlgId hashID, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSetPointHash_rmf,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, const IppsHashMethod* pMethod, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSetPointHashBackCompatible_rmf,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, const IppsHashMethod* pMethod, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECGetPoint,(const IppsGFpECPoint* pPoint, IppsGFpElement* pX, IppsGFpElement* pY, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECGetPointRegular,(const IppsGFpECPoint* pPoint, IppsBigNumState* pX, IppsBigNumState* pY, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPointOctString,(const Ipp8u* pStr, int strLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECGetPointOctString,(const IppsGFpECPoint* pPoint, Ipp8u* pStr, int strLen, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECTstPoint,(const IppsGFpECPoint* pP, IppECResult* pResult, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECTstPointInSubgroup,(const IppsGFpECPoint* pP, IppECResult* pResult, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECCpyPoint,(const IppsGFpECPoint* pA, IppsGFpECPoint* pR, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECCmpPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppECResult* pResult, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECNegPoint,(const IppsGFpECPoint* pP, IppsGFpECPoint* pR, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECAddPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECPoint* pR, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECMulPoint,(const IppsGFpECPoint* pP, const IppsBigNumState* pN, IppsGFpECPoint* pR, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* keys */ +IPPAPI(IppStatus, ippsGFpECPrivateKey,(IppsBigNumState* pPrivate, IppsGFpECState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsGFpECPublicKey,(const IppsBigNumState* pPrivate, IppsGFpECPoint* pPublic, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECTstKeyPair,(const IppsBigNumState* pPrivate, const IppsGFpECPoint* pPublic, IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* DH shared secret */ +IPPAPI(IppStatus, ippsGFpECSharedSecretDH,(const IppsBigNumState* pPrivateA, const IppsGFpECPoint* pPublicB, + IppsBigNumState* pShare, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSharedSecretDHC,(const IppsBigNumState* pPrivateA, + const IppsGFpECPoint* pPublicB, + IppsBigNumState* pShare, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* sign generation/verification of DSA, NR, SM2 */ +IPPAPI(IppStatus, ippsGFpECMessageRepresentationSM2, (IppsBigNumState* pMsgDigest, + const Ipp8u* pMsg, int msgLen, + const Ipp8u* pUserID, int userIDLen, + const IppsGFpECPoint* pRegPublic, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSignDSA, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECVerifyDSA, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECSignNR, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECVerifyNR, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECSignSM2, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECVerifySM2, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* SM2 UserIDHash */ +IPPAPI(IppStatus, ippsGFpECUserIDHashSM2, (Ipp8u* pZaDigest, + const Ipp8u* pUserID, int userIDLen, + const IppsGFpECPoint* pPublicKey, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + + +/* SM2 Key Exchange */ +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_GetSize, (const IppsGFpECState* pEC, int* pSize)) +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_Init, (IppsGFpECKeyExchangeSM2State* pKE, IppsKeyExchangeRoleSM2 role, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_Setup, (const Ipp8u pZSelf[IPP_SM3_DIGEST_BYTESIZE], + const Ipp8u pZPeer[IPP_SM3_DIGEST_BYTESIZE], + const IppsGFpECPoint *pPublicKeySelf, + const IppsGFpECPoint *pPublicKeyPeer, + const IppsGFpECPoint *pEphPublicKeySelf, + const IppsGFpECPoint *pEphPublicKeyPeer, + IppsGFpECKeyExchangeSM2State *pKE)) + +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_SharedKey, (Ipp8u* pSharedKey, int sharedKeySize, + Ipp8u* pSSelf, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pEphPrvKey, + IppsGFpECKeyExchangeSM2State *pKE, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_Confirm, (const Ipp8u pSPeer[IPP_SM3_DIGEST_BYTESIZE], + int* pStatus, + IppsGFpECKeyExchangeSM2State* pKE)) + +/* SM2 Encryption/Decryption */ +IPPAPI(IppStatus, ippsGFpECGetInfo_GF,(IppsGFpInfo* pInfo, const IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECESGetSize_SM2, (const IppsGFpECState* pEC, int* pSize)) +IPPAPI(IppStatus, ippsGFpECESInit_SM2, (IppsGFpECState* pEC, + IppsECESState_SM2* pState, int avaliableCtxSize)) +IPPAPI(IppStatus, ippsGFpECESSetKey_SM2, (const IppsBigNumState* pPrivate, + const IppsGFpECPoint* pPublic, + IppsECESState_SM2* pState, + IppsGFpECState* pEC, + Ipp8u* pEcScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECESStart_SM2, (IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESEncrypt_SM2, (const Ipp8u* pInput, Ipp8u* pOutput, + int dataLen, IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESDecrypt_SM2, (const Ipp8u* pInput, Ipp8u* pOutput, + int dataLen, IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESFinal_SM2, (Ipp8u* pTag, int tagLen, IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESGetBuffersSize_SM2, (int* pPublicKeySize, + int* pMaximumTagSize, const IppsECESState_SM2* pState)) + +/* SM2 Encryption/Decryption Extended API */ +/* Encryption */ +IPPAPI(IppStatus, ippsGFpECEncryptSM2_Ext_EncMsgSize, (const IppsGFpECState *pEC, int ptMsgSize, int *pSize)) + +IPPAPI(IppStatus, ippsGFpECEncryptSM2_Ext, (Ipp8u *pOut, int maxOutLen, + int *pOutSize, + const Ipp8u *pInp, int inpLen, + const IppsGFpECPoint *pPublicKey, + IppsGFpECPoint *pEhpPublicKey, IppsBigNumState *pEphPrvKey, + IppsGFpECState *pEC, Ipp8u *pScratchBuffer)) + +/* Decryption */ +IPPAPI(IppStatus, ippsGFpECDecryptSM2_Ext_DecMsgSize, (const IppsGFpECState *pEC, int ctMsgSize, int *pSize)) + +IPPAPI(IppStatus, ippsGFpECDecryptSM2_Ext, (Ipp8u *pOut, int maxOutLen, + int *pOutSize, + const Ipp8u *pInp, int inpLen, + const IppsBigNumState *pPrvKey, + IppsGFpECState *pEC, Ipp8u *pScratchBuffer)) + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) +#pragma warning(pop) +#endif +#ifdef __cplusplus +} +#endif + + +#endif /* IPPCP_H__ */ diff --git a/plugin/ippcp/library/include/ippcpdefs.h b/plugin/ippcp/library/include/ippcpdefs.h new file mode 100644 index 000000000..50417c698 --- /dev/null +++ b/plugin/ippcp/library/include/ippcpdefs.h @@ -0,0 +1,860 @@ +/******************************************************************************* +* Copyright (C) 2012 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +// Purpose: Basic Types and Macro Definitions +// +*/ + + +#ifndef IPPBASE_H__ +#define IPPBASE_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#if defined (_WIN64) +#define INTEL_PLATFORM "intel64/" +#elif defined (_WIN32) +#define INTEL_PLATFORM "ia32/" +#endif + +#if !defined( IPPAPI ) + + /* Specify explicit calling convention for public functions */ + #if defined( IPP_W32DLL ) && (defined( _WIN32 ) || defined( _WIN64 )) + #if defined( _MSC_VER ) || defined( __ICL ) + #define IPPAPI( type,name,arg ) \ + __declspec(dllimport) type IPP_CALL name arg; + #else + #define IPPAPI( type,name,arg ) type IPP_CALL name arg; + #endif + #else + #define IPPAPI( type,name,arg ) type IPP_CALL name arg; + #endif + +#endif + +/* icc 2021 supports short float data type, icx supports _Float16 data type */ +#define _FLOAT_16 2 +#define _SHORT_FLOAT 1 +#define _NO_FLOAT_16 0 +#if defined(__INTEL_LLVM_COMPILER) && defined(__AVX512FP16__) +# define COMPILER_SUPPORT_SHORT_FLOAT _FLOAT_16 +#else +# if defined(__INTEL_COMPILER) +# if(__INTEL_COMPILER >= 2021) +# define COMPILER_SUPPORT_SHORT_FLOAT _SHORT_FLOAT +# endif +# endif +#endif +#if !(defined(COMPILER_SUPPORT_SHORT_FLOAT)) +# define COMPILER_SUPPORT_SHORT_FLOAT _NO_FLOAT_16 +#endif + +#if !defined(_NO_IPP_DEPRECATED) + #if (defined( __ICL ) || defined( __ECL ) || defined(_MSC_VER)) && !defined( _PCS ) && !defined( _PCS_GENSTUBS ) + #if( __INTEL_COMPILER >= 1100 ) /* icl 11.0 supports additional comment */ + #if( _MSC_VER >= 1400 ) + #define IPP_DEPRECATED( comment ) __declspec( deprecated ( comment )) + #else + #pragma message ("your icl version supports additional comment for deprecated functions but it can't be displayed") + #pragma message ("because internal _MSC_VER macro variable setting requires compatibility with MSVC7.1") + #pragma message ("use -Qvc8 switch for icl command line to see these additional comments") + #define IPP_DEPRECATED( comment ) __declspec( deprecated ) + #endif + #elif( _MSC_FULL_VER >= 140050727 )&&( !defined( __INTEL_COMPILER ))&&( !defined(__INTEL_LLVM_COMPILER)) /* VS2005 supports additional comment */ + #define IPP_DEPRECATED( comment ) __declspec( deprecated ( comment )) + #elif( _MSC_VER <= 1200 )&&( !defined( __INTEL_COMPILER ))&&( !defined(__INTEL_LLVM_COMPILER)) /* VS 6 doesn't support deprecation */ + #define IPP_DEPRECATED( comment ) + #else + #define IPP_DEPRECATED( comment ) __declspec( deprecated ) + #endif + #elif (defined(__ICC) || defined(__ECC) || defined( __GNUC__ )) && !defined( _PCS ) && !defined( _PCS_GENSTUBS ) + #if defined( __GNUC__ ) + #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 + #define IPP_DEPRECATED( message ) __attribute__(( deprecated( message ))) + #else + #define IPP_DEPRECATED( message ) __attribute__(( deprecated )) + #endif + #else + #define IPP_DEPRECATED( comment ) __attribute__(( deprecated )) + #endif + #else + #define IPP_DEPRECATED( comment ) + #endif +#else + #define IPP_DEPRECATED( comment ) +#endif + +#if (defined( __ICL ) || defined( __ECL ) || defined(_MSC_VER)) + #if !defined( IPP_NO_DEFAULT_LIB ) + #if ((defined( _IPP_SEQUENTIAL_DYNAMIC ) && !defined( _IPP_SEQUENTIAL_STATIC )) || \ + (!defined( _IPP_SEQUENTIAL_DYNAMIC ) && defined( _IPP_SEQUENTIAL_STATIC ))) + #elif (!defined( _IPP_SEQUENTIAL_DYNAMIC ) && !defined( _IPP_SEQUENTIAL_STATIC )) + #define IPP_NO_DEFAULT_LIB + #else + #error Illegal combination of _IPP_SEQUENTIAL_DYNAMIC/_IPP_SEQUENTIAL_STATIC, only one definition can be defined + #endif + #endif +#else + #define IPP_NO_DEFAULT_LIB + #if (defined(_IPP_SEQUENTIAL_DYNAMIC) || defined(_IPP_SEQUENTIAL_STATIC)) + #pragma message ("defines _IPP_SEQUENTIAL_DYNAMIC/_IPP_SEQUENTIAL_STATIC do not have any effect in current configuration") + #endif +#endif + + +#if defined (_MSC_VER) + #define IPP_CDECL __cdecl +#elif (defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || defined (__GNUC__ ) || defined (__clang__)) && defined (_ARCH_IA32) + #define IPP_CDECL __attribute((cdecl)) +#else + #define IPP_CDECL +#endif + +#if defined( _WIN32 ) || defined( _WIN64 ) + #define IPP_STDCALL __stdcall + #define IPP_CALL IPP_STDCALL + #define IPP_INT64 __int64 + #define IPP_UINT64 unsigned __int64 +#else + #define IPP_STDCALL + #define IPP_CALL IPP_CDECL + #define IPP_INT64 long long + #define IPP_UINT64 unsigned long long +#endif + +#define IPP_COUNT_OF( obj ) (sizeof(obj)/sizeof(obj[0])) + +#define IPP_PI ( 3.14159265358979323846 ) /* ANSI C does not support M_PI */ +#define IPP_2PI ( 6.28318530717958647692 ) /* 2*pi */ +#define IPP_PI2 ( 1.57079632679489661923 ) /* pi/2 */ +#define IPP_PI4 ( 0.78539816339744830961 ) /* pi/4 */ +#define IPP_PI180 ( 0.01745329251994329577 ) /* pi/180 */ +#define IPP_RPI ( 0.31830988618379067154 ) /* 1/pi */ +#define IPP_SQRT2 ( 1.41421356237309504880 ) /* sqrt(2) */ +#define IPP_SQRT3 ( 1.73205080756887729353 ) /* sqrt(3) */ +#define IPP_LN2 ( 0.69314718055994530942 ) /* ln(2) */ +#define IPP_LN3 ( 1.09861228866810969139 ) /* ln(3) */ +#define IPP_E ( 2.71828182845904523536 ) /* e */ +#define IPP_RE ( 0.36787944117144232159 ) /* 1/e */ +#define IPP_EPS23 ( 1.19209289e-07f ) +#define IPP_EPS52 ( 2.2204460492503131e-016 ) + +#define IPP_MAX_8U ( 0xFF ) +#define IPP_MAX_16U ( 0xFFFF ) +#define IPP_MAX_32U ( 0xFFFFFFFF ) +#define IPP_MIN_8U ( 0 ) +#define IPP_MIN_16U ( 0 ) +#define IPP_MIN_32U ( 0 ) +#define IPP_MIN_8S (-128 ) +#define IPP_MAX_8S ( 127 ) +#define IPP_MIN_16S (-32768 ) +#define IPP_MAX_16S ( 32767 ) +#define IPP_MIN_32S (-2147483647 - 1 ) +#define IPP_MAX_32S ( 2147483647 ) +#define IPP_MIN_64U ( 0 ) + +#if defined( _WIN32 ) || defined ( _WIN64 ) + #define IPP_MAX_64S ( 9223372036854775807i64 ) + #define IPP_MIN_64S (-9223372036854775807i64 - 1 ) + #define IPP_MAX_64U ( 0xffffffffffffffffL ) /* 18446744073709551615 */ +#else + #define IPP_MAX_64S ( 9223372036854775807LL ) + #define IPP_MIN_64S (-9223372036854775807LL - 1 ) + #define IPP_MAX_64U ( 0xffffffffffffffffLL ) /* 18446744073709551615 */ +#endif + +#define IPP_MINABS_32F ( 1.175494351e-38f ) +#define IPP_MAXABS_32F ( 3.402823466e+38f ) +#define IPP_EPS_32F ( 1.192092890e-07f ) +#define IPP_MINABS_64F ( 2.2250738585072014e-308 ) +#define IPP_MAXABS_64F ( 1.7976931348623158e+308 ) +#define IPP_EPS_64F ( 2.2204460492503131e-016 ) + +#define IPP_MAX( a, b ) ( ((a) > (b)) ? (a) : (b) ) +#define IPP_MIN( a, b ) ( ((a) < (b)) ? (a) : (b) ) + +#define IPP_ABS( a ) ( ((a) < 0) ? (-(a)) : (a) ) + +typedef struct { + int major; /* e.g. 1 */ + int minor; /* e.g. 2 */ + int majorBuild; /* e.g. 3 */ + unsigned int revision; /* e.g. 0xf6f5e5bc */ + char targetCpu[4]; /* corresponding to Intel® processor */ + const char* Name; /* e.g. "ippsw7" */ + const char* Version; /* e.g. "v1.2 Beta" */ + const char* BuildDate; /* e.g. "Jul 20 99" */ +} IppLibraryVersion; + +typedef unsigned char Ipp8u; +typedef unsigned short Ipp16u; +typedef unsigned int Ipp32u; +typedef signed char Ipp8s; +typedef signed short Ipp16s; +typedef signed int Ipp32s; +typedef float Ipp32f; +typedef IPP_INT64 Ipp64s; +typedef IPP_UINT64 Ipp64u; +typedef double Ipp64f; + +#if (COMPILER_SUPPORT_SHORT_FLOAT == _FLOAT_16) + typedef _Float16 Ipp16f; +#endif +#if (COMPILER_SUPPORT_SHORT_FLOAT == _SHORT_FLOAT) + typedef short float Ipp16f; +#endif +#if (COMPILER_SUPPORT_SHORT_FLOAT == _NO_FLOAT_16) + typedef Ipp16s Ipp16f; +#endif + +typedef struct { + Ipp8s re; + Ipp8s im; +} Ipp8sc; + +typedef struct { + Ipp16s re; + Ipp16s im; +} Ipp16sc; + +typedef struct { + Ipp16u re; + Ipp16u im; +} Ipp16uc; + +typedef struct { + Ipp32s re; + Ipp32s im; +} Ipp32sc; + +typedef struct { + Ipp32f re; + Ipp32f im; +} Ipp32fc; + +typedef struct { + Ipp64s re; + Ipp64s im; +} Ipp64sc; + +typedef struct { + Ipp64f re; + Ipp64f im; +} Ipp64fc; + +typedef struct { + Ipp16f re; + Ipp16f im; +} Ipp16fc; + +typedef enum { + ippUndef = -1, + ipp1u = 0, + ipp8u = 1, + ipp8uc = 2, + ipp8s = 3, + ipp8sc = 4, + ipp16u = 5, + ipp16uc = 6, + ipp16s = 7, + ipp16sc = 8, + ipp32u = 9, + ipp32uc = 10, + ipp32s = 11, + ipp32sc = 12, + ipp32f = 13, + ipp32fc = 14, + ipp64u = 15, + ipp64uc = 16, + ipp64s = 17, + ipp64sc = 18, + ipp64f = 19, + ipp64fc = 20, + ipp16fc = 21 /* This is necessary for TS */ +} IppDataType; + +typedef enum { + ippFalse = 0, + ippTrue = 1 +} IppBool; + +#ifdef __cplusplus +} +#endif + +#endif /* IPPBASE_H__ */ + +#ifndef IPP_CPU_FEATURES__ +#define IPP_CPU_FEATURES__ + +#define ippCPUID_MMX 0x00000001 /* Intel® architecture with MMX(TM) technology supported */ +#define ippCPUID_SSE 0x00000002 /* Intel® Streaming SIMD Extensions (Intel® SSE) instruction set */ +#define ippCPUID_SSE2 0x00000004 /* Intel® Streaming SIMD Extensions 2 (Intel® SSE2) instruction set */ +#define ippCPUID_SSE3 0x00000008 /* Intel® Streaming SIMD Extensions 3 (Intel® SSE3) instruction set */ +#define ippCPUID_SSSE3 0x00000010 /* Supplemental Streaming SIMD Extensions 3 (SSSE3) instruction set */ +#define ippCPUID_MOVBE 0x00000020 /* Intel® instruction MOVBE */ +#define ippCPUID_SSE41 0x00000040 /* Intel® Streaming SIMD Extensions 4.1 (Intel® SSE4.1) instruction set */ +#define ippCPUID_SSE42 0x00000080 /* Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) instruction set */ +#define ippCPUID_AVX 0x00000100 /* Intel® Advanced Vector Extensions instruction set */ +#define ippAVX_ENABLEDBYOS 0x00000200 /* Intel® Advanced Vector Extensions instruction set is supported by OS */ +#define ippCPUID_AES 0x00000400 /* */ +#define ippCPUID_CLMUL 0x00000800 /* Intel® instruction PCLMULQDQ */ +#define ippCPUID_ABR 0x00001000 /* Reserved */ +#define ippCPUID_RDRAND 0x00002000 /* Intel® instruction RDRAND */ +#define ippCPUID_F16C 0x00004000 /* Intel® instruction F16C */ +#define ippCPUID_AVX2 0x00008000 /* Intel® Advanced Vector Extensions 2 */ +#define ippCPUID_ADCOX 0x00010000 /* Intel® instructions ADOX/ADCX */ +#define ippCPUID_RDSEED 0x00020000 /* Intel® instruction RDSEED */ +#define ippCPUID_PREFETCHW 0x00040000 /* Intel® instruction PREFETCHW */ +#define ippCPUID_SHA 0x00080000 /* Intel® Secure Hash Algorithm Extensions */ +#define ippCPUID_AVX512F 0x00100000 /* Intel® Advanced Vector Extensions 512 Foundation instruction set */ +#define ippCPUID_AVX512CD 0x00200000 /* Intel® Advanced Vector Extensions 512 CD instruction set */ +#define ippCPUID_AVX512ER 0x00400000 /* Intel® Advanced Vector Extensions 512 ER instruction set */ +#define ippCPUID_AVX512PF 0x00800000 /* Intel® Advanced Vector Extensions 512 PF instruction set */ +#define ippCPUID_AVX512BW 0x01000000 /* Intel® Advanced Vector Extensions 512 BW instruction set */ +#define ippCPUID_AVX512DQ 0x02000000 /* Intel® Advanced Vector Extensions 512 DQ instruction set */ +#define ippCPUID_AVX512VL 0x04000000 /* Intel® Advanced Vector Extensions 512 VL instruction set */ +#define ippCPUID_AVX512VBMI 0x08000000 /* Intel® Advanced Vector Extensions 512 Bit Manipulation instructions */ +#define ippCPUID_MPX 0x10000000 /* Intel® Memory Protection Extensions */ +#define ippCPUID_AVX512_4FMADDPS 0x20000000 /* Intel® Advanced Vector Extensions 512 DL floating-point single precision */ +#define ippCPUID_AVX512_4VNNIW 0x40000000 /* Intel® Advanced Vector Extensions 512 DL enhanced word variable precision */ +#define ippCPUID_KNC 0x80000000 /* Intel® Xeon® Phi(TM) Coprocessor */ +#if defined( _WIN32 ) || defined ( _WIN64 ) + #define INT64_SUFFIX(name) name##L +#else + #define INT64_SUFFIX(name) name##LL +#endif + #define ippCPUID_AVX512IFMA INT64_SUFFIX(0x100000000) /* Intel® Advanced Vector Extensions 512 IFMA (PMADD52) instruction set */ + #define ippCPUID_NOCHECK INT64_SUFFIX(0x8000000000000000) /* Force ippSetCpuFeatures to set CPU features without check */ + #define ippCPUID_GETINFO_A INT64_SUFFIX(0x616f666e69746567) /* Force ippGetCpuFeatures to work as cpuid instruction */ + #define ippAVX512_ENABLEDBYOS INT64_SUFFIX(0x200000000) /* Intel® Advanced Vector Extensions 512 is supported by OS */ + + #define ippCPUID_AVX512GFNI INT64_SUFFIX(0x400000000) /* */ + #define ippCPUID_AVX512VAES INT64_SUFFIX(0x800000000) /* */ + #define ippCPUID_AVX512VCLMUL INT64_SUFFIX(0x1000000000) /* */ + #define ippCPUID_AVX512VBMI2 INT64_SUFFIX(0x2000000000) /* Intel® Advanced Vector Extensions 512 Bit Manipulation instructions 2 */ + #define ippCPUID_AVX512_FP16 INT64_SUFFIX(0x1000000000) /* Intel(R) Advanced Vector Extensions 512 16-bit floating point (FP16) instruction set */ + + #define ippCPUID_AVX2VAES INT64_SUFFIX(0x4000000000) /* Intel® Advanced Vector Extensions 256 Bit Vector AES instructions */ + #define ippCPUID_AVX2VCLMUL INT64_SUFFIX(0x8000000000) /* Intel® instruction VPCLMULQDQ */ + +#endif /* IPP_CPU_FEATURES__ */ + +/* Macros are necessary to build custom Intel® IPP Cryptography static 1cpu library (enable specific features at compile-time) */ +#if (!defined(_MERGED_BLD) && defined(IPPCP_CUSTOM_BUILD)) + +#ifndef IPP_CUSTOM_CPU_FEATURES__ +#define IPP_CUSTOM_CPU_FEATURES__ + +#ifndef IPPCP_AES_ON +#define IPPCP_AES_ON (0) +#endif +#ifndef IPPCP_CLMUL_ON +#define IPPCP_CLMUL_ON (0) +#endif +#ifndef IPPCP_VAES_ON +#define IPPCP_VAES_ON (0) +#endif +#ifndef IPPCP_VCLMUL_ON +#define IPPCP_VCLMUL_ON (0) +#endif +#define IPP_CUSTOM_ENABLED_FEATURES (ippCPUID_AES*IPPCP_AES_ON | ippCPUID_CLMUL*IPPCP_CLMUL_ON | ippCPUID_AVX512VAES*IPPCP_VAES_ON | ippCPUID_AVX512VCLMUL*IPPCP_VCLMUL_ON) + +#endif /* IPP_CUSTOM_CPU_FEATURES__ */ +#endif /* !defined(_MERGED_BLD) && defined(IPPCP_CUSTOM_BUILD) */ + +#ifndef IPPSTATUS_H__ +#define IPPSTATUS_H__ + +#ifdef __cplusplus +extern "C" { +#endif +typedef signed int IppStatus; + + /* start of common with ippCrypto part - any changes MUST be done in both repositories - IPP & ippCrypto */ +#define ippStsCpuNotSupportedErr -9999 /* The target CPU is not supported. */ +#define ippStsUnknownStatusCodeErr -216 /* Unknown status code. */ +#define ippStsLoadDynErr -221 /* Error when loading the dynamic library. */ +#define ippStsLengthErr -15 /* Incorrect value for string length. */ +#define ippStsNotSupportedModeErr -14 /* The requested mode is currently not supported. */ +#define ippStsContextMatchErr -13 /* Context parameter does not match the operation. */ +#define ippStsScaleRangeErr -12 /* Scale bounds are out of range. */ +#define ippStsOutOfRangeErr -11 /* Argument is out of range, or point is outside the image. */ +#define ippStsDivByZeroErr -10 /* An attempt to divide by zero. */ +#define ippStsMemAllocErr -9 /* Memory allocated for the operation is not enough. */ +#define ippStsNullPtrErr -8 /* Null pointer error. */ +#define ippStsRangeErr -7 /* Incorrect values for bounds: the lower bound is greater than the upper bound. */ +#define ippStsSizeErr -6 /* Incorrect value for data size. */ +#define ippStsBadArgErr -5 /* Incorrect arg/param of the function. */ +#define ippStsNoMemErr -4 /* Not enough memory for the operation. */ +#define ippStsErr -2 /* Unknown/unspecified error */ + /* no errors */ +#define ippStsNoErr 0 /* No errors. */ + /* warnings */ +#define ippStsNoOperation 1 /* No operation has been executed. */ +#define ippStsDivByZero 2 /* Zero value(s) for the divisor in the Div function. */ +#define ippStsWaterfall 43 /* Cannot load required library, waterfall is used. */ +#define ippStsFeaturesCombination 51 /* Wrong combination of features. */ + /* end of common with ippCrypto part */ + +#ifdef __cplusplus +} +#endif + +#endif /* IPPSTATUS_H__ */ + + /* ippCrypto specific statuses - any changes MUST be done in both repositories - IPP & ippCrypto */ +#define ippStsInvalidPoint -1017 /* ippStsInvalidPoint ECC: Invalid point (out of EC).*/ +#define ippStsQuadraticNonResidueErr -1016 /* SQRT operation on quadratic non-residue value. */ +#define ippStsPointAtInfinity -1015 /* Point at infinity is detected. */ +#define ippStsOFBSizeErr -1014 /* Incorrect value for crypto OFB block size. */ +#define ippStsIncompleteContextErr -1013 /* Crypto: set up of context is not complete. */ +#define ippStsCTRSizeErr -1012 /* Incorrect value for crypto CTR block size. */ +#define ippStsEphemeralKeyErr -1011 /* ECC: Invalid ephemeral key. */ +#define ippStsMessageErr -1010 /* ECC: Invalid message digest. */ +#define ippStsShareKeyErr -1009 /* ECC: Invalid share key. */ +#define ippStsInvalidPrivateKey -1008 /* ECC: Invalid private key. */ +#define ippStsOutOfECErr -1007 /* ECC: Point out of EC. */ +#define ippStsECCInvalidFlagErr -1006 /* ECC: Invalid Flag. */ +#define ippStsUnderRunErr -1005 /* Error in data under run. */ +#define ippStsPaddingErr -1004 /* Detected padding error indicates the possible data corruption. */ +#define ippStsCFBSizeErr -1003 /* Incorrect value for crypto CFB block size. */ +#define ippStsPaddingSchemeErr -1002 /* Invalid padding scheme. */ +#define ippStsBadModulusErr -1001 /* Bad modulus caused a failure in module inversion. */ +#define ippStsInsufficientEntropy 25 /* Generation of the prime/key failed due to insufficient entropy in the random seed and stimulus bit string. */ +#define ippStsNotSupportedCpu 36 /* The CPU is not supported. */ +#define ippStsMbWarning 53 /* Error(s) in statuses array. */ + /* end of ippCrypto specific statuses - any changes MUST be done in both repositories - IPP & ippCrypto */ + +#if (!defined IPPCPDEFS_H__) || defined( _OWN_BLDPCS ) +#define IPPCPDEFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + +#if !defined( _OWN_BLDPCS ) + +typedef Ipp32u IppAlgId; + +/* +// ========================================================= +// Symmetric Ciphers +// ========================================================= +*/ +typedef enum { + ippPaddingNONE = 0, /*NONE = 0,*/ IppsCPPaddingNONE = 0, + ippPaddingPKCS7 = 1, /*PKCS7 = 1,*/ IppsCPPaddingPKCS7 = 1, + ippPaddingZEROS = 2, /*ZEROS = 2,*/ IppsCPPaddingZEROS = 2 +} IppsPadding, IppsCPPadding; + +typedef struct _cpDES IppsDESSpec; +typedef struct _cpRijndael128 IppsAESSpec; +typedef struct _cpRijndael128 IppsRijndael128Spec; +typedef struct _cpSMS4 IppsSMS4Spec; + +/* TDES */ +#define DES_BLOCKSIZE (64) /* cipher blocksize (bits) */ +#define TDES_BLOCKSIZE DES_BLOCKSIZE + +#define DES_KEYSIZE (64) /* cipher keysize (bits) */ +#define TDES_KEYSIZE DES_KEYSIZE + +/* AES */ +#define IPP_AES_BLOCK_BITSIZE (128) /* cipher blocksizes (bits) */ + +/* Rijndael */ +typedef enum { + ippRijndaelKey128 = 128, IppsRijndaelKey128 = 128, /* 128-bit key */ + ippRijndaelKey192 = 192, IppsRijndaelKey192 = 192, /* 192-bit key */ + ippRijndaelKey256 = 256, IppsRijndaelKey256 = 256 /* 256-bit key */ +} IppsRijndaelKeyLength; + +/* AES-CCM (authentication & confidence) */ +typedef struct _cpAES_CCM IppsAES_CCMState; +/* AES-GCM (authentication & confidence) */ +typedef struct _cpAES_GCM IppsAES_GCMState; +/* AES-XTS (confidence) */ +typedef struct _cpAES_XTS IppsAES_XTSSpec; + +/* SMS4-CCM (authentication & confidence) */ +typedef struct _cpSMS4_CCM IppsSMS4_CCMState; + +/* +// ========================================================= +// ARCFOUR Stream Cipher +// ========================================================= +*/ +typedef struct _cpARCfour IppsARCFourState; + +#define IPP_ARCFOUR_KEYMAX_SIZE (256) /* max key length (bytes) */ +#define MAX_ARCFOUR_KEY_LEN IPP_ARCFOUR_KEYMAX_SIZE /* obsolete */ + +/* +// ========================================================= +// One-Way Hash Functions +// ========================================================= +*/ +typedef enum { + ippHashAlg_Unknown, + ippHashAlg_SHA1, + ippHashAlg_SHA256, + ippHashAlg_SHA224, + ippHashAlg_SHA512, + ippHashAlg_SHA384, + ippHashAlg_MD5, + ippHashAlg_SM3, + ippHashAlg_SHA512_224, + ippHashAlg_SHA512_256, + ippHashAlg_MaxNo +} IppHashAlgId; + +#define IPP_ALG_HASH_UNKNOWN (ippHashAlg_Unknown) /* unknown */ +#define IPP_ALG_HASH_SHA1 (ippHashAlg_SHA1) /* SHA1 */ +#define IPP_ALG_HASH_SHA256 (ippHashAlg_SHA256) /* SHA256 */ +#define IPP_ALG_HASH_SHA224 (ippHashAlg_SHA224) /* SHA224 or SHA256/224 */ +#define IPP_ALG_HASH_SHA512 (ippHashAlg_SHA512) /* SHA512 */ +#define IPP_ALG_HASH_SHA384 (ippHashAlg_SHA384) /* SHA384 or SHA512/384 */ +#define IPP_ALG_HASH_MD5 (ippHashAlg_MD5) /* MD5 */ +#define IPP_ALG_HASH_SM3 (ippHashAlg_SM3) /* SM3 */ +#define IPP_ALG_HASH_SHA512_224 (ippHashAlg_SHA512_224) /* SHA512/224 */ +#define IPP_ALG_HASH_SHA512_256 (ippHashAlg_SHA512_256) /* SHA512/256 */ +#define IPP_ALG_HASH_LIMIT (ippHashAlg_MaxNo) /* hash alg limiter*/ + +typedef struct _cpSHA1 IppsSHA1State; +typedef struct _cpSHA256 IppsSHA256State; +typedef struct _cpSHA256 IppsSHA224State; +typedef struct _cpSHA512 IppsSHA512State; +typedef struct _cpSHA512 IppsSHA384State; +typedef struct _cpMD5 IppsMD5State; +typedef struct _cpSM3 IppsSM3State; +typedef struct _cpHashCtx IppsHashState; + +typedef struct _cpHashMethod_rmf IppsHashMethod; +typedef struct _cpHashCtx_rmf IppsHashState_rmf; + +#define IPP_SHA1_DIGEST_BITSIZE 160 /* digest size (bits) */ +#define IPP_SHA256_DIGEST_BITSIZE 256 +#define IPP_SHA224_DIGEST_BITSIZE 224 +#define IPP_SHA384_DIGEST_BITSIZE 384 +#define IPP_SHA512_DIGEST_BITSIZE 512 +#define IPP_MD5_DIGEST_BITSIZE 128 +#define IPP_SM3_DIGEST_BITSIZE 256 +#define IPP_SHA512_224_DIGEST_BITSIZE 224 +#define IPP_SHA512_256_DIGEST_BITSIZE 256 + +/* +// ========================================================= +// Keyed-Hash Message Authentication Codes +// ========================================================= +*/ +typedef struct _cpHMAC IppsHMACState; +typedef struct _cpHMAC IppsHMACSHA1State; +typedef struct _cpHMAC IppsHMACSHA256State; +typedef struct _cpHMAC IppsHMACSHA224State; +typedef struct _cpHMAC IppsHMACSHA384State; +typedef struct _cpHMAC IppsHMACSHA512State; +typedef struct _cpHMAC IppsHMACMD5State; +typedef struct _cpHMAC_rmf IppsHMACState_rmf; + +/* +// ========================================================= +// Data Authentication Codes +// ========================================================= +*/ +typedef struct _cpAES_CMAC IppsAES_CMACState; + +/* +// ========================================================= +// Big Number Integer Arithmetic +// ========================================================= +*/ +#define BN_MAXBITSIZE (16*1024) /* bn max size (bits) */ + + +typedef enum { + ippBigNumNEG = 0, IppsBigNumNEG = 0, + ippBigNumPOS = 1, IppsBigNumPOS = 1 +} IppsBigNumSGN; + +typedef enum { + ippBinaryMethod = 0, IppsBinaryMethod = 0, + ippSlidingWindows = 1, IppsSlidingWindows = 1 +} IppsExpMethod; + +typedef struct _cpBigNum IppsBigNumState; +typedef struct _cpMontgomery IppsMontState; +typedef struct _cpPRNG IppsPRNGState; +typedef struct _cpPrime IppsPrimeState; + +/* External Bit Supplier */ +typedef IppStatus (IPP_CALL *IppBitSupplier)(Ipp32u* pRand, int nBits, void* pEbsParams); + +#define IPP_IS_EQ (0) +#define IPP_IS_GT (1) +#define IPP_IS_LT (2) +#define IPP_IS_NE (3) +#define IPP_IS_NA (4) + +#define IPP_IS_PRIME (5) +#define IPP_IS_COMPOSITE (6) + +#define IPP_IS_VALID (7) +#define IPP_IS_INVALID (8) +#define IPP_IS_INCOMPLETE (9) +#define IPP_IS_ATINFINITY (10) + +#define IS_ZERO IPP_IS_EQ +#define GREATER_THAN_ZERO IPP_IS_GT +#define LESS_THAN_ZERO IPP_IS_LT +#define IS_PRIME IPP_IS_PRIME +#define IS_COMPOSITE IPP_IS_COMPOSITE +#define IS_VALID_KEY IPP_IS_VALID +#define IS_INVALID_KEY IPP_IS_INVALID +#define IS_INCOMPLETED_KEY IPP_IS_INCOMPLETE + +/* +// ========================================================= +// RSA Cryptography +// ========================================================= +*/ +#define MIN_RSA_SIZE (8) +#define MAX_RSA_SIZE (16*1024) + +typedef struct _cpRSA IppsRSAState; + +/* key types */ +typedef enum { + ippRSApublic = 0x20000000, IppRSApublic = 0x20000000, + ippRSAprivate = 0x40000000, IppRSAprivate = 0x40000000 +} IppRSAKeyType; + +/* key component's tag */ +typedef enum { + ippRSAkeyN = 0x01, IppRSAkeyN = 0x01, + ippRSAkeyE = 0x02, IppRSAkeyE = 0x02, + ippRSAkeyD = 0x04, IppRSAkeyD = 0x04, + ippRSAkeyP = 0x08, IppRSAkeyP = 0x08, + ippRSAkeyQ = 0x10, IppRSAkeyQ = 0x10, + ippRSAkeyDp = 0x20, IppRSAkeyDp = 0x20, + ippRSAkeyDq = 0x40, IppRSAkeyDq = 0x40, + ippRSAkeyQinv = 0x80, IppRSAkeyQinv = 0x80 +} IppRSAKeyTag; + +typedef struct _cpRSA_public_key IppsRSAPublicKeyState; +typedef struct _cpRSA_private_key IppsRSAPrivateKeyState; + + +/* +// ========================================================= +// DL Cryptography +// ========================================================= +*/ +#define MIN_DLP_BITSIZE (512) +#define MIN_DLP_BITSIZER (160) + +#define MIN_DLPDH_BITSIZE (512) +#define MIN_DLPDH_BITSIZER (160) +#define DEF_DLPDH_BITSIZER (160) + +#define MIN_DLPDSA_BITSIZE (512) +#define MAX_DLPDSA_BITSIZE (1024) +#define MIN_DLPDSA_BITSIZER (160) +#define DEF_DLPDSA_BITSIZER (160) +#define MAX_DLPDSA_BITSIZER (160) +#define MIN_DLPDSA_SEEDSIZE (160) + +typedef struct _cpDLP IppsDLPState; + +/* domain parameter tags */ +typedef enum { + ippDLPkeyP = 0x01, IppDLPkeyP = 0x01, + ippDLPkeyR = 0x02, IppDLPkeyR = 0x02, + ippDLPkeyG = 0x04, IppDLPkeyG = 0x04 +} IppDLPKeyTag; + +typedef enum { + ippDLValid, /* validation pass successfully */ + + ippDLBaseIsEven, /* !(P is odd) */ + ippDLOrderIsEven, /* !(R is odd) */ + ippDLInvalidBaseRange, /* !(2^(L-1) < P < 2^L) */ + ippDLInvalidOrderRange, /* !(2^(M-1) < R < 2^M) */ + ippDLCompositeBase, + ippDLCompositeOrder, + ippDLInvalidCofactor, /* !( R|(P-1) ) */ + ippDLInvalidGenerator, /* !( G^R == 1 (mod P) ) */ + /* !(1 < G < (P-1)) */ + ippDLInvalidPrivateKey, /* !(1 < private < (R-1)) */ + ippDLInvalidPublicKey, /* !(1 < public <=(P-1)) */ + ippDLInvalidKeyPair, /* !(G^private == public */ + + ippDLInvalidSignature /* invalid signature */ +} IppDLResult; + +/* +// ========================================================= +// EC Cryptography +// ========================================================= +*/ +#define EC_GFP_MAXBITSIZE (1024) + +/* operation result */ +typedef enum { + ippECValid, /* validation pass successfully */ + + ippECCompositeBase, /* field based on composite */ + ippECComplicatedBase, /* number of non-zero terms in the polynomial (> PRIME_ARR_MAX) */ + ippECIsZeroDiscriminant,/* zero discriminant */ + ippECCompositeOrder, /* composite order of base point */ + ippECInvalidOrder, /* invalid base point order */ + ippECIsWeakMOV, /* weak Meneze-Okamoto-Vanstone reduction attack */ + ippECIsWeakSSSA, /* weak Semaev-Smart,Satoh-Araki reduction attack */ + ippECIsSupersingular, /* supersingular curve */ + + ippECInvalidPrivateKey, /* !(0 < Private < order) */ + ippECInvalidPublicKey, /* (order*PublicKey != Infinity) */ + ippECInvalidKeyPair, /* (Private*BasePoint != PublicKey) */ + + ippECPointOutOfGroup, /* out of group (order*P != Infinity) */ + ippECPointIsAtInfinite, /* point (P=(Px,Py)) at Infinity */ + ippECPointIsNotValid, /* point (P=(Px,Py)) out-of EC */ + + ippECPointIsEqual, /* compared points are equal */ + ippECPointIsNotEqual, /* compared points are different */ + + ippECInvalidSignature /* invalid signature */ +} IppECResult; + +/* domain parameter set/get flags */ +typedef enum { + ippECarbitrary =0x00000, IppECCArbitrary = 0x00000, /* arbitrary ECC */ + + ippECPstd = 0x10000, IppECCPStd = 0x10000, /* random (recommended) EC over FG(p): */ + ippECPstd112r1 = ippECPstd, IppECCPStd112r1 = IppECCPStd, /* secp112r1 curve */ + ippECPstd112r2 = ippECPstd+1, IppECCPStd112r2 = IppECCPStd+1, /* secp112r2 curve */ + ippECPstd128r1 = ippECPstd+2, IppECCPStd128r1 = IppECCPStd+2, /* secp128r1 curve */ + ippECPstd128r2 = ippECPstd+3, IppECCPStd128r2 = IppECCPStd+3, /* secp128r2 curve */ + ippECPstd160r1 = ippECPstd+4, IppECCPStd160r1 = IppECCPStd+4, /* secp160r1 curve */ + ippECPstd160r2 = ippECPstd+5, IppECCPStd160r2 = IppECCPStd+5, /* secp160r2 curve */ + ippECPstd192r1 = ippECPstd+6, IppECCPStd192r1 = IppECCPStd+6, /* secp192r1 curve */ + ippECPstd224r1 = ippECPstd+7, IppECCPStd224r1 = IppECCPStd+7, /* secp224r1 curve */ + ippECPstd256r1 = ippECPstd+8, IppECCPStd256r1 = IppECCPStd+8, /* secp256r1 curve */ + ippECPstd384r1 = ippECPstd+9, IppECCPStd384r1 = IppECCPStd+9, /* secp384r1 curve */ + ippECPstd521r1 = ippECPstd+10, IppECCPStd521r1 = IppECCPStd+10, /* secp521r1 curve */ + ippECPstdSM2 = ippECPstd+11, IppECCPStdSM2 = IppECCPStd+11, /* TMP SM2 curve */ + ippEC_TPM_SM2_P256= ippECPstd+11, + ippEC_TPM_BN_P256 = ippECPstd+12, /* TPM BN_P256 curve */ + + /* curves over binary finit fields are not supported in Intel® IPP 9.0 */ + IppECCBStd = 0x20000, /* random (recommended) EC over FG(2^m): */ + IppECCBStd113r1 = IppECCBStd, /* sect113r1 curve */ + IppECCBStd113r2 = IppECCBStd+1, /* sect113r2 curve */ + IppECCBStd131r1 = IppECCBStd+2, /* sect131r1 curve */ + IppECCBStd131r2 = IppECCBStd+3, /* sect131r2 curve */ + IppECCBStd163r1 = IppECCBStd+4, /* sect163r1 curve */ + IppECCBStd163r2 = IppECCBStd+5, /* sect163r2 curve */ + IppECCBStd193r1 = IppECCBStd+6, /* sect193r1 curve */ + IppECCBStd193r2 = IppECCBStd+7, /* sect193r2 curve */ + IppECCBStd233r1 = IppECCBStd+8, /* sect233r1 curve */ + IppECCBStd283r1 = IppECCBStd+9, /* sect283r1 curve */ + IppECCBStd409r1 = IppECCBStd+10, /* sect409r1 curve */ + IppECCBStd571r1 = IppECCBStd+11, /* sect571r1 curve */ + + IppECCKStd = 0x40000, /* Koblitz (recommended) EC over FG(2^m): */ + IppECCBStd163k1 = IppECCKStd, /* Koblitz 163 curve */ + IppECCBStd233k1 = IppECCKStd+1, /* Koblitz 233 curve */ + IppECCBStd239k1 = IppECCKStd+2, /* Koblitz 239 curve */ + IppECCBStd283k1 = IppECCKStd+3, /* Koblitz 283 curve */ + IppECCBStd409k1 = IppECCKStd+4, /* Koblitz 409 curve */ + IppECCBStd571k1 = IppECCKStd+5 /* Koblitz 571 curve */ +} IppsECType, IppECCType; + +/* +// GF over prime and its extension +*/ +#define IPP_MIN_GF_CHAR (3) /* min characteristic of GF */ + +#define IPP_MIN_GF_BITSIZE (2) /* min bitsize of element over prime GF */ +#define IPP_MAX_GF_BITSIZE (1024) /* max bitsize of element over prime GF */ + +#define IPP_MIN_GF_EXTDEG (2) /* min GF extension degree */ +#define IPP_MAX_GF_EXTDEG (8) /* max GF extension degree */ + +#define IPP_MAX_EXPONENT_NUM (6) /* max number of exponents, equals to LOG_CACHE_LINE_SIZE */ + +typedef struct _cpGFpMethod IppsGFpMethod; + +typedef struct _cpGFp IppsGFpState; +typedef struct _cpGFpElement IppsGFpElement; + +typedef struct _cpGFpEC IppsGFpECState; +typedef struct _cpGFpECPoint IppsGFpECPoint; + +typedef struct _cpGFpEC IppsECCPState; +typedef struct _cpGFpECPoint IppsECCPPointState; + +typedef struct { + int hashSize; + int msgBlockSize; +} IppsHashInfo; + +typedef struct { + //const IppsGFpState* pBasicGF; + //const IppsGFpState* pGroundGF; + int parentGFdegree; + int basicGFdegree; + int basicElmBitSize; +} IppsGFpInfo; + +/* SM3 Digest Bytes Size */ +#define IPP_SM3_DIGEST_BYTESIZE ((IPP_SM3_DIGEST_BITSIZE + 7) / 8) + +typedef struct _cpStateECES_SM2 IppsECESState_SM2; + +typedef enum { + ippKESM2Requester = 0xF, /* corresponds to A user/participant */ + ippKESM2Responder /* corresponds to B user/participant */ +} IppsKeyExchangeRoleSM2; + +typedef struct _GFpECKeyExchangeSM2 IppsGFpECKeyExchangeSM2State; + +#endif /* !defined( _OWN_BLDPCS ) */ + +IPPAPI( IppStatus, ippcpGetCpuFeatures, ( Ipp64u* pFeaturesMask )) +IPPAPI( IppStatus, ippcpSetCpuFeatures, ( Ipp64u features )) +IPPAPI( Ipp64u, ippcpGetEnabledCpuFeatures, ( void ) ) +IPPAPI( IppStatus, ippcpSetNumThreads, ( int numThr )) +IPPAPI( IppStatus, ippcpInit,( void )) +IPPAPI( IppStatus, ippcpGetNumThreads, (int* pNumThr) ) +IPPAPI( const char*, ippcpGetStatusString, ( IppStatus StsCode )) +IPPAPI( int, ippcpGetEnabledNumThreads, ( void ) ) +IPPAPI( Ipp64u, ippcpGetCpuClocks, (void) ) + +#ifdef __cplusplus +} +#endif + +#endif /* !defined IPPCPDEFS_H__ || defined( _OWN_BLDPCS ) */ diff --git a/plugin/ippcp/library/include/ippversion.h b/plugin/ippcp/library/include/ippversion.h new file mode 100644 index 000000000..71376145b --- /dev/null +++ b/plugin/ippcp/library/include/ippversion.h @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright (C) 2001 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +// Purpose: Describes the Intel IPP Cryptography version +// +*/ + + +#if !defined( IPPVERSION_H__ ) +#define IPPVERSION_H__ + +#define IPP_VERSION_MAJOR 2021 +#define IPP_VERSION_MINOR 9 +#define IPP_VERSION_UPDATE 0 + +// Major interface version +#define IPP_INTERFACE_VERSION_MAJOR 11 +// Minor interface version +#define IPP_INTERFACE_VERSION_MINOR 9 + +#define IPP_VERSION_STR STR(IPP_VERSION_MAJOR) "." STR(IPP_VERSION_MINOR) "." STR(IPP_VERSION_UPDATE) " (" STR(IPP_INTERFACE_VERSION_MAJOR) "." STR(IPP_INTERFACE_VERSION_MINOR) " )" + +#endif /* IPPVERSION_H__ */ diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_e9.h b/plugin/ippcp/library/include/single_cpu/ippcp_e9.h new file mode 100644 index 000000000..80c52e2b7 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_e9.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion e9_ippcpGetLibVersion +#define ippsDESGetSize e9_ippsDESGetSize +#define ippsDESInit e9_ippsDESInit +#define ippsDESPack e9_ippsDESPack +#define ippsDESUnpack e9_ippsDESUnpack +#define ippsTDESEncryptECB e9_ippsTDESEncryptECB +#define ippsTDESDecryptECB e9_ippsTDESDecryptECB +#define ippsTDESEncryptCBC e9_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC e9_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB e9_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB e9_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB e9_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB e9_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR e9_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR e9_ippsTDESDecryptCTR +#define ippsAESGetSize e9_ippsAESGetSize +#define ippsAESInit e9_ippsAESInit +#define ippsAESSetKey e9_ippsAESSetKey +#define ippsAESPack e9_ippsAESPack +#define ippsAESUnpack e9_ippsAESUnpack +#define ippsAESEncryptECB e9_ippsAESEncryptECB +#define ippsAESDecryptECB e9_ippsAESDecryptECB +#define ippsAESEncryptCBC e9_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 e9_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 e9_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 e9_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC e9_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 e9_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 e9_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 e9_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB e9_ippsAESEncryptCFB +#define ippsAESDecryptCFB e9_ippsAESDecryptCFB +#define ippsAESEncryptOFB e9_ippsAESEncryptOFB +#define ippsAESDecryptOFB e9_ippsAESDecryptOFB +#define ippsAESEncryptCTR e9_ippsAESEncryptCTR +#define ippsAESDecryptCTR e9_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct e9_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct e9_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise e9_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise e9_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise e9_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB e9_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize e9_ippsSMS4GetSize +#define ippsSMS4Init e9_ippsSMS4Init +#define ippsSMS4SetKey e9_ippsSMS4SetKey +#define ippsSMS4EncryptECB e9_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB e9_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC e9_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 e9_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 e9_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 e9_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC e9_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 e9_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 e9_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 e9_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB e9_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB e9_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB e9_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB e9_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR e9_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR e9_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize e9_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit e9_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen e9_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen e9_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart e9_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt e9_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt e9_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag e9_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize e9_ippsAES_CCMGetSize +#define ippsAES_CCMInit e9_ippsAES_CCMInit +#define ippsAES_CCMMessageLen e9_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen e9_ippsAES_CCMTagLen +#define ippsAES_CCMStart e9_ippsAES_CCMStart +#define ippsAES_CCMEncrypt e9_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt e9_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag e9_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize e9_ippsAES_GCMGetSize +#define ippsAES_GCMInit e9_ippsAES_GCMInit +#define ippsAES_GCMReinit e9_ippsAES_GCMReinit +#define ippsAES_GCMReset e9_ippsAES_GCMReset +#define ippsAES_GCMProcessIV e9_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD e9_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart e9_ippsAES_GCMStart +#define ippsAES_GCMEncrypt e9_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt e9_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag e9_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize e9_ippsAES_XTSGetSize +#define ippsAES_XTSInit e9_ippsAES_XTSInit +#define ippsAES_XTSEncrypt e9_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt e9_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC e9_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt e9_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt e9_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize e9_ippsAES_CMACGetSize +#define ippsAES_CMACInit e9_ippsAES_CMACInit +#define ippsAES_CMACUpdate e9_ippsAES_CMACUpdate +#define ippsAES_CMACFinal e9_ippsAES_CMACFinal +#define ippsAES_CMACGetTag e9_ippsAES_CMACGetTag +#define ippsARCFourCheckKey e9_ippsARCFourCheckKey +#define ippsARCFourGetSize e9_ippsARCFourGetSize +#define ippsARCFourInit e9_ippsARCFourInit +#define ippsARCFourReset e9_ippsARCFourReset +#define ippsARCFourPack e9_ippsARCFourPack +#define ippsARCFourUnpack e9_ippsARCFourUnpack +#define ippsARCFourEncrypt e9_ippsARCFourEncrypt +#define ippsARCFourDecrypt e9_ippsARCFourDecrypt +#define ippsSHA1GetSize e9_ippsSHA1GetSize +#define ippsSHA1Init e9_ippsSHA1Init +#define ippsSHA1Duplicate e9_ippsSHA1Duplicate +#define ippsSHA1Pack e9_ippsSHA1Pack +#define ippsSHA1Unpack e9_ippsSHA1Unpack +#define ippsSHA1Update e9_ippsSHA1Update +#define ippsSHA1GetTag e9_ippsSHA1GetTag +#define ippsSHA1Final e9_ippsSHA1Final +#define ippsSHA1MessageDigest e9_ippsSHA1MessageDigest +#define ippsSHA224GetSize e9_ippsSHA224GetSize +#define ippsSHA224Init e9_ippsSHA224Init +#define ippsSHA224Duplicate e9_ippsSHA224Duplicate +#define ippsSHA224Pack e9_ippsSHA224Pack +#define ippsSHA224Unpack e9_ippsSHA224Unpack +#define ippsSHA224Update e9_ippsSHA224Update +#define ippsSHA224GetTag e9_ippsSHA224GetTag +#define ippsSHA224Final e9_ippsSHA224Final +#define ippsSHA224MessageDigest e9_ippsSHA224MessageDigest +#define ippsSHA256GetSize e9_ippsSHA256GetSize +#define ippsSHA256Init e9_ippsSHA256Init +#define ippsSHA256Duplicate e9_ippsSHA256Duplicate +#define ippsSHA256Pack e9_ippsSHA256Pack +#define ippsSHA256Unpack e9_ippsSHA256Unpack +#define ippsSHA256Update e9_ippsSHA256Update +#define ippsSHA256GetTag e9_ippsSHA256GetTag +#define ippsSHA256Final e9_ippsSHA256Final +#define ippsSHA256MessageDigest e9_ippsSHA256MessageDigest +#define ippsSHA384GetSize e9_ippsSHA384GetSize +#define ippsSHA384Init e9_ippsSHA384Init +#define ippsSHA384Duplicate e9_ippsSHA384Duplicate +#define ippsSHA384Pack e9_ippsSHA384Pack +#define ippsSHA384Unpack e9_ippsSHA384Unpack +#define ippsSHA384Update e9_ippsSHA384Update +#define ippsSHA384GetTag e9_ippsSHA384GetTag +#define ippsSHA384Final e9_ippsSHA384Final +#define ippsSHA384MessageDigest e9_ippsSHA384MessageDigest +#define ippsSHA512GetSize e9_ippsSHA512GetSize +#define ippsSHA512Init e9_ippsSHA512Init +#define ippsSHA512Duplicate e9_ippsSHA512Duplicate +#define ippsSHA512Pack e9_ippsSHA512Pack +#define ippsSHA512Unpack e9_ippsSHA512Unpack +#define ippsSHA512Update e9_ippsSHA512Update +#define ippsSHA512GetTag e9_ippsSHA512GetTag +#define ippsSHA512Final e9_ippsSHA512Final +#define ippsSHA512MessageDigest e9_ippsSHA512MessageDigest +#define ippsMD5GetSize e9_ippsMD5GetSize +#define ippsMD5Init e9_ippsMD5Init +#define ippsMD5Duplicate e9_ippsMD5Duplicate +#define ippsMD5Pack e9_ippsMD5Pack +#define ippsMD5Unpack e9_ippsMD5Unpack +#define ippsMD5Update e9_ippsMD5Update +#define ippsMD5GetTag e9_ippsMD5GetTag +#define ippsMD5Final e9_ippsMD5Final +#define ippsMD5MessageDigest e9_ippsMD5MessageDigest +#define ippsSM3GetSize e9_ippsSM3GetSize +#define ippsSM3Init e9_ippsSM3Init +#define ippsSM3Duplicate e9_ippsSM3Duplicate +#define ippsSM3Pack e9_ippsSM3Pack +#define ippsSM3Unpack e9_ippsSM3Unpack +#define ippsSM3Update e9_ippsSM3Update +#define ippsSM3GetTag e9_ippsSM3GetTag +#define ippsSM3Final e9_ippsSM3Final +#define ippsSM3MessageDigest e9_ippsSM3MessageDigest +#define ippsHashGetSize e9_ippsHashGetSize +#define ippsHashInit e9_ippsHashInit +#define ippsHashPack e9_ippsHashPack +#define ippsHashUnpack e9_ippsHashUnpack +#define ippsHashDuplicate e9_ippsHashDuplicate +#define ippsHashUpdate e9_ippsHashUpdate +#define ippsHashGetTag e9_ippsHashGetTag +#define ippsHashFinal e9_ippsHashFinal +#define ippsHashMessage e9_ippsHashMessage +#define ippsHashMethod_MD5 e9_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 e9_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 e9_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI e9_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT e9_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 e9_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI e9_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT e9_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 e9_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI e9_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT e9_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 e9_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 e9_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 e9_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 e9_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize e9_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 e9_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 e9_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 e9_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 e9_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI e9_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT e9_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 e9_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI e9_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT e9_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 e9_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI e9_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT e9_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 e9_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI e9_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT e9_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 e9_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI e9_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT e9_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 e9_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 e9_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 e9_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 e9_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 e9_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 e9_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 e9_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 e9_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf e9_ippsHashGetSize_rmf +#define ippsHashInit_rmf e9_ippsHashInit_rmf +#define ippsHashPack_rmf e9_ippsHashPack_rmf +#define ippsHashUnpack_rmf e9_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf e9_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf e9_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf e9_ippsHashGetTag_rmf +#define ippsHashFinal_rmf e9_ippsHashFinal_rmf +#define ippsHashMessage_rmf e9_ippsHashMessage_rmf +#define ippsHashMethodGetInfo e9_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf e9_ippsHashGetInfo_rmf +#define ippsMGF e9_ippsMGF +#define ippsMGF1_rmf e9_ippsMGF1_rmf +#define ippsMGF2_rmf e9_ippsMGF2_rmf +#define ippsHMAC_GetSize e9_ippsHMAC_GetSize +#define ippsHMAC_Init e9_ippsHMAC_Init +#define ippsHMAC_Pack e9_ippsHMAC_Pack +#define ippsHMAC_Unpack e9_ippsHMAC_Unpack +#define ippsHMAC_Duplicate e9_ippsHMAC_Duplicate +#define ippsHMAC_Update e9_ippsHMAC_Update +#define ippsHMAC_Final e9_ippsHMAC_Final +#define ippsHMAC_GetTag e9_ippsHMAC_GetTag +#define ippsHMAC_Message e9_ippsHMAC_Message +#define ippsHMACGetSize_rmf e9_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf e9_ippsHMACInit_rmf +#define ippsHMACPack_rmf e9_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf e9_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf e9_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf e9_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf e9_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf e9_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf e9_ippsHMACMessage_rmf +#define ippsBigNumGetSize e9_ippsBigNumGetSize +#define ippsBigNumInit e9_ippsBigNumInit +#define ippsCmpZero_BN e9_ippsCmpZero_BN +#define ippsCmp_BN e9_ippsCmp_BN +#define ippsGetSize_BN e9_ippsGetSize_BN +#define ippsSet_BN e9_ippsSet_BN +#define ippsGet_BN e9_ippsGet_BN +#define ippsRef_BN e9_ippsRef_BN +#define ippsExtGet_BN e9_ippsExtGet_BN +#define ippsAdd_BN e9_ippsAdd_BN +#define ippsSub_BN e9_ippsSub_BN +#define ippsMul_BN e9_ippsMul_BN +#define ippsMAC_BN_I e9_ippsMAC_BN_I +#define ippsDiv_BN e9_ippsDiv_BN +#define ippsMod_BN e9_ippsMod_BN +#define ippsGcd_BN e9_ippsGcd_BN +#define ippsModInv_BN e9_ippsModInv_BN +#define ippsSetOctString_BN e9_ippsSetOctString_BN +#define ippsGetOctString_BN e9_ippsGetOctString_BN +#define ippsMontGetSize e9_ippsMontGetSize +#define ippsMontInit e9_ippsMontInit +#define ippsMontSet e9_ippsMontSet +#define ippsMontGet e9_ippsMontGet +#define ippsMontForm e9_ippsMontForm +#define ippsMontMul e9_ippsMontMul +#define ippsMontExp e9_ippsMontExp +#define ippsPRNGGetSize e9_ippsPRNGGetSize +#define ippsPRNGInit e9_ippsPRNGInit +#define ippsPRNGSetModulus e9_ippsPRNGSetModulus +#define ippsPRNGSetH0 e9_ippsPRNGSetH0 +#define ippsPRNGSetAugment e9_ippsPRNGSetAugment +#define ippsPRNGSetSeed e9_ippsPRNGSetSeed +#define ippsPRNGGetSeed e9_ippsPRNGGetSeed +#define ippsPRNGen e9_ippsPRNGen +#define ippsPRNGen_BN e9_ippsPRNGen_BN +#define ippsPRNGenRDRAND e9_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN e9_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED e9_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN e9_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize e9_ippsPrimeGetSize +#define ippsPrimeInit e9_ippsPrimeInit +#define ippsPrimeGen e9_ippsPrimeGen +#define ippsPrimeTest e9_ippsPrimeTest +#define ippsPrimeGen_BN e9_ippsPrimeGen_BN +#define ippsPrimeTest_BN e9_ippsPrimeTest_BN +#define ippsPrimeGet e9_ippsPrimeGet +#define ippsPrimeGet_BN e9_ippsPrimeGet_BN +#define ippsPrimeSet e9_ippsPrimeSet +#define ippsPrimeSet_BN e9_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey e9_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey e9_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey e9_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey e9_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 e9_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 e9_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 e9_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 e9_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 e9_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 e9_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 e9_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 e9_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey e9_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey e9_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt e9_ippsRSA_Encrypt +#define ippsRSA_Decrypt e9_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys e9_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys e9_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP e9_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP e9_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf e9_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf e9_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 e9_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 e9_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS e9_ippsRSASign_PSS +#define ippsRSAVerify_PSS e9_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf e9_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf e9_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 e9_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 e9_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf e9_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf e9_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString e9_ippsDLGetResultString +#define ippsDLPGetSize e9_ippsDLPGetSize +#define ippsDLPInit e9_ippsDLPInit +#define ippsDLPPack e9_ippsDLPPack +#define ippsDLPUnpack e9_ippsDLPUnpack +#define ippsDLPSet e9_ippsDLPSet +#define ippsDLPGet e9_ippsDLPGet +#define ippsDLPSetDP e9_ippsDLPSetDP +#define ippsDLPGetDP e9_ippsDLPGetDP +#define ippsDLPGenKeyPair e9_ippsDLPGenKeyPair +#define ippsDLPPublicKey e9_ippsDLPPublicKey +#define ippsDLPValidateKeyPair e9_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair e9_ippsDLPSetKeyPair +#define ippsDLPSignDSA e9_ippsDLPSignDSA +#define ippsDLPVerifyDSA e9_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH e9_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA e9_ippsDLPGenerateDSA +#define ippsDLPValidateDSA e9_ippsDLPValidateDSA +#define ippsDLPGenerateDH e9_ippsDLPGenerateDH +#define ippsDLPValidateDH e9_ippsDLPValidateDH +#define ippsECCGetResultString e9_ippsECCGetResultString +#define ippsECCPGetSize e9_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 e9_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 e9_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 e9_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 e9_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 e9_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 e9_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 e9_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 e9_ippsECCPGetSizeStdSM2 +#define ippsECCPInit e9_ippsECCPInit +#define ippsECCPInitStd128r1 e9_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 e9_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 e9_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 e9_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 e9_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 e9_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 e9_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 e9_ippsECCPInitStdSM2 +#define ippsECCPSet e9_ippsECCPSet +#define ippsECCPSetStd e9_ippsECCPSetStd +#define ippsECCPSetStd128r1 e9_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 e9_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 e9_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 e9_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 e9_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 e9_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 e9_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 e9_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 e9_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 e9_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 e9_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 e9_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 e9_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 e9_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet e9_ippsECCPGet +#define ippsECCPGetOrderBitSize e9_ippsECCPGetOrderBitSize +#define ippsECCPValidate e9_ippsECCPValidate +#define ippsECCPPointGetSize e9_ippsECCPPointGetSize +#define ippsECCPPointInit e9_ippsECCPPointInit +#define ippsECCPSetPoint e9_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity e9_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint e9_ippsECCPGetPoint +#define ippsECCPCheckPoint e9_ippsECCPCheckPoint +#define ippsECCPComparePoint e9_ippsECCPComparePoint +#define ippsECCPNegativePoint e9_ippsECCPNegativePoint +#define ippsECCPAddPoint e9_ippsECCPAddPoint +#define ippsECCPMulPointScalar e9_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair e9_ippsECCPGenKeyPair +#define ippsECCPPublicKey e9_ippsECCPPublicKey +#define ippsECCPValidateKeyPair e9_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair e9_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH e9_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC e9_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA e9_ippsECCPSignDSA +#define ippsECCPVerifyDSA e9_ippsECCPVerifyDSA +#define ippsECCPSignNR e9_ippsECCPSignNR +#define ippsECCPVerifyNR e9_ippsECCPVerifyNR +#define ippsECCPSignSM2 e9_ippsECCPSignSM2 +#define ippsECCPVerifySM2 e9_ippsECCPVerifySM2 +#define ippsGFpGetSize e9_ippsGFpGetSize +#define ippsGFpInitArbitrary e9_ippsGFpInitArbitrary +#define ippsGFpInitFixed e9_ippsGFpInitFixed +#define ippsGFpInit e9_ippsGFpInit +#define ippsGFpMethod_p192r1 e9_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 e9_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 e9_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 e9_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 e9_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 e9_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn e9_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 e9_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb e9_ippsGFpMethod_pArb +#define ippsGFpxGetSize e9_ippsGFpxGetSize +#define ippsGFpxInit e9_ippsGFpxInit +#define ippsGFpxInitBinomial e9_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 e9_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 e9_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 e9_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 e9_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom e9_ippsGFpxMethod_binom +#define ippsGFpxMethod_com e9_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize e9_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize e9_ippsGFpElementGetSize +#define ippsGFpElementInit e9_ippsGFpElementInit +#define ippsGFpSetElement e9_ippsGFpSetElement +#define ippsGFpSetElementRegular e9_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString e9_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom e9_ippsGFpSetElementRandom +#define ippsGFpSetElementHash e9_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf e9_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement e9_ippsGFpCpyElement +#define ippsGFpGetElement e9_ippsGFpGetElement +#define ippsGFpGetElementOctString e9_ippsGFpGetElementOctString +#define ippsGFpCmpElement e9_ippsGFpCmpElement +#define ippsGFpIsZeroElement e9_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement e9_ippsGFpIsUnityElement +#define ippsGFpConj e9_ippsGFpConj +#define ippsGFpNeg e9_ippsGFpNeg +#define ippsGFpInv e9_ippsGFpInv +#define ippsGFpSqrt e9_ippsGFpSqrt +#define ippsGFpSqr e9_ippsGFpSqr +#define ippsGFpAdd e9_ippsGFpAdd +#define ippsGFpSub e9_ippsGFpSub +#define ippsGFpMul e9_ippsGFpMul +#define ippsGFpExp e9_ippsGFpExp +#define ippsGFpMultiExp e9_ippsGFpMultiExp +#define ippsGFpAdd_PE e9_ippsGFpAdd_PE +#define ippsGFpSub_PE e9_ippsGFpSub_PE +#define ippsGFpMul_PE e9_ippsGFpMul_PE +#define ippsGFpGetInfo e9_ippsGFpGetInfo +#define ippsGFpECGetSize e9_ippsGFpECGetSize +#define ippsGFpECInit e9_ippsGFpECInit +#define ippsGFpECSet e9_ippsGFpECSet +#define ippsGFpECSetSubgroup e9_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 e9_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 e9_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 e9_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 e9_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 e9_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 e9_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 e9_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 e9_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 e9_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 e9_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 e9_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 e9_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 e9_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 e9_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 e9_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet e9_ippsGFpECGet +#define ippsGFpECGetSubgroup e9_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize e9_ippsGFpECScratchBufferSize +#define ippsGFpECVerify e9_ippsGFpECVerify +#define ippsGFpECPointGetSize e9_ippsGFpECPointGetSize +#define ippsGFpECPointInit e9_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity e9_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint e9_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular e9_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom e9_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint e9_ippsGFpECMakePoint +#define ippsGFpECSetPointHash e9_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible e9_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf e9_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf e9_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint e9_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular e9_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString e9_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString e9_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint e9_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup e9_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint e9_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint e9_ippsGFpECCmpPoint +#define ippsGFpECNegPoint e9_ippsGFpECNegPoint +#define ippsGFpECAddPoint e9_ippsGFpECAddPoint +#define ippsGFpECMulPoint e9_ippsGFpECMulPoint +#define ippsGFpECPrivateKey e9_ippsGFpECPrivateKey +#define ippsGFpECPublicKey e9_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair e9_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH e9_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC e9_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 e9_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA e9_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA e9_ippsGFpECVerifyDSA +#define ippsGFpECSignNR e9_ippsGFpECSignNR +#define ippsGFpECVerifyNR e9_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 e9_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 e9_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 e9_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize e9_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init e9_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup e9_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey e9_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm e9_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF e9_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 e9_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 e9_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 e9_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 e9_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 e9_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 e9_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 e9_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 e9_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize e9_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext e9_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize e9_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext e9_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_g9.h b/plugin/ippcp/library/include/single_cpu/ippcp_g9.h new file mode 100644 index 000000000..de27b9484 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_g9.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion g9_ippcpGetLibVersion +#define ippsDESGetSize g9_ippsDESGetSize +#define ippsDESInit g9_ippsDESInit +#define ippsDESPack g9_ippsDESPack +#define ippsDESUnpack g9_ippsDESUnpack +#define ippsTDESEncryptECB g9_ippsTDESEncryptECB +#define ippsTDESDecryptECB g9_ippsTDESDecryptECB +#define ippsTDESEncryptCBC g9_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC g9_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB g9_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB g9_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB g9_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB g9_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR g9_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR g9_ippsTDESDecryptCTR +#define ippsAESGetSize g9_ippsAESGetSize +#define ippsAESInit g9_ippsAESInit +#define ippsAESSetKey g9_ippsAESSetKey +#define ippsAESPack g9_ippsAESPack +#define ippsAESUnpack g9_ippsAESUnpack +#define ippsAESEncryptECB g9_ippsAESEncryptECB +#define ippsAESDecryptECB g9_ippsAESDecryptECB +#define ippsAESEncryptCBC g9_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 g9_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 g9_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 g9_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC g9_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 g9_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 g9_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 g9_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB g9_ippsAESEncryptCFB +#define ippsAESDecryptCFB g9_ippsAESDecryptCFB +#define ippsAESEncryptOFB g9_ippsAESEncryptOFB +#define ippsAESDecryptOFB g9_ippsAESDecryptOFB +#define ippsAESEncryptCTR g9_ippsAESEncryptCTR +#define ippsAESDecryptCTR g9_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct g9_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct g9_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise g9_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise g9_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise g9_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB g9_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize g9_ippsSMS4GetSize +#define ippsSMS4Init g9_ippsSMS4Init +#define ippsSMS4SetKey g9_ippsSMS4SetKey +#define ippsSMS4EncryptECB g9_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB g9_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC g9_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 g9_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 g9_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 g9_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC g9_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 g9_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 g9_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 g9_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB g9_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB g9_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB g9_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB g9_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR g9_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR g9_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize g9_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit g9_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen g9_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen g9_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart g9_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt g9_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt g9_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag g9_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize g9_ippsAES_CCMGetSize +#define ippsAES_CCMInit g9_ippsAES_CCMInit +#define ippsAES_CCMMessageLen g9_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen g9_ippsAES_CCMTagLen +#define ippsAES_CCMStart g9_ippsAES_CCMStart +#define ippsAES_CCMEncrypt g9_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt g9_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag g9_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize g9_ippsAES_GCMGetSize +#define ippsAES_GCMInit g9_ippsAES_GCMInit +#define ippsAES_GCMReinit g9_ippsAES_GCMReinit +#define ippsAES_GCMReset g9_ippsAES_GCMReset +#define ippsAES_GCMProcessIV g9_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD g9_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart g9_ippsAES_GCMStart +#define ippsAES_GCMEncrypt g9_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt g9_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag g9_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize g9_ippsAES_XTSGetSize +#define ippsAES_XTSInit g9_ippsAES_XTSInit +#define ippsAES_XTSEncrypt g9_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt g9_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC g9_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt g9_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt g9_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize g9_ippsAES_CMACGetSize +#define ippsAES_CMACInit g9_ippsAES_CMACInit +#define ippsAES_CMACUpdate g9_ippsAES_CMACUpdate +#define ippsAES_CMACFinal g9_ippsAES_CMACFinal +#define ippsAES_CMACGetTag g9_ippsAES_CMACGetTag +#define ippsARCFourCheckKey g9_ippsARCFourCheckKey +#define ippsARCFourGetSize g9_ippsARCFourGetSize +#define ippsARCFourInit g9_ippsARCFourInit +#define ippsARCFourReset g9_ippsARCFourReset +#define ippsARCFourPack g9_ippsARCFourPack +#define ippsARCFourUnpack g9_ippsARCFourUnpack +#define ippsARCFourEncrypt g9_ippsARCFourEncrypt +#define ippsARCFourDecrypt g9_ippsARCFourDecrypt +#define ippsSHA1GetSize g9_ippsSHA1GetSize +#define ippsSHA1Init g9_ippsSHA1Init +#define ippsSHA1Duplicate g9_ippsSHA1Duplicate +#define ippsSHA1Pack g9_ippsSHA1Pack +#define ippsSHA1Unpack g9_ippsSHA1Unpack +#define ippsSHA1Update g9_ippsSHA1Update +#define ippsSHA1GetTag g9_ippsSHA1GetTag +#define ippsSHA1Final g9_ippsSHA1Final +#define ippsSHA1MessageDigest g9_ippsSHA1MessageDigest +#define ippsSHA224GetSize g9_ippsSHA224GetSize +#define ippsSHA224Init g9_ippsSHA224Init +#define ippsSHA224Duplicate g9_ippsSHA224Duplicate +#define ippsSHA224Pack g9_ippsSHA224Pack +#define ippsSHA224Unpack g9_ippsSHA224Unpack +#define ippsSHA224Update g9_ippsSHA224Update +#define ippsSHA224GetTag g9_ippsSHA224GetTag +#define ippsSHA224Final g9_ippsSHA224Final +#define ippsSHA224MessageDigest g9_ippsSHA224MessageDigest +#define ippsSHA256GetSize g9_ippsSHA256GetSize +#define ippsSHA256Init g9_ippsSHA256Init +#define ippsSHA256Duplicate g9_ippsSHA256Duplicate +#define ippsSHA256Pack g9_ippsSHA256Pack +#define ippsSHA256Unpack g9_ippsSHA256Unpack +#define ippsSHA256Update g9_ippsSHA256Update +#define ippsSHA256GetTag g9_ippsSHA256GetTag +#define ippsSHA256Final g9_ippsSHA256Final +#define ippsSHA256MessageDigest g9_ippsSHA256MessageDigest +#define ippsSHA384GetSize g9_ippsSHA384GetSize +#define ippsSHA384Init g9_ippsSHA384Init +#define ippsSHA384Duplicate g9_ippsSHA384Duplicate +#define ippsSHA384Pack g9_ippsSHA384Pack +#define ippsSHA384Unpack g9_ippsSHA384Unpack +#define ippsSHA384Update g9_ippsSHA384Update +#define ippsSHA384GetTag g9_ippsSHA384GetTag +#define ippsSHA384Final g9_ippsSHA384Final +#define ippsSHA384MessageDigest g9_ippsSHA384MessageDigest +#define ippsSHA512GetSize g9_ippsSHA512GetSize +#define ippsSHA512Init g9_ippsSHA512Init +#define ippsSHA512Duplicate g9_ippsSHA512Duplicate +#define ippsSHA512Pack g9_ippsSHA512Pack +#define ippsSHA512Unpack g9_ippsSHA512Unpack +#define ippsSHA512Update g9_ippsSHA512Update +#define ippsSHA512GetTag g9_ippsSHA512GetTag +#define ippsSHA512Final g9_ippsSHA512Final +#define ippsSHA512MessageDigest g9_ippsSHA512MessageDigest +#define ippsMD5GetSize g9_ippsMD5GetSize +#define ippsMD5Init g9_ippsMD5Init +#define ippsMD5Duplicate g9_ippsMD5Duplicate +#define ippsMD5Pack g9_ippsMD5Pack +#define ippsMD5Unpack g9_ippsMD5Unpack +#define ippsMD5Update g9_ippsMD5Update +#define ippsMD5GetTag g9_ippsMD5GetTag +#define ippsMD5Final g9_ippsMD5Final +#define ippsMD5MessageDigest g9_ippsMD5MessageDigest +#define ippsSM3GetSize g9_ippsSM3GetSize +#define ippsSM3Init g9_ippsSM3Init +#define ippsSM3Duplicate g9_ippsSM3Duplicate +#define ippsSM3Pack g9_ippsSM3Pack +#define ippsSM3Unpack g9_ippsSM3Unpack +#define ippsSM3Update g9_ippsSM3Update +#define ippsSM3GetTag g9_ippsSM3GetTag +#define ippsSM3Final g9_ippsSM3Final +#define ippsSM3MessageDigest g9_ippsSM3MessageDigest +#define ippsHashGetSize g9_ippsHashGetSize +#define ippsHashInit g9_ippsHashInit +#define ippsHashPack g9_ippsHashPack +#define ippsHashUnpack g9_ippsHashUnpack +#define ippsHashDuplicate g9_ippsHashDuplicate +#define ippsHashUpdate g9_ippsHashUpdate +#define ippsHashGetTag g9_ippsHashGetTag +#define ippsHashFinal g9_ippsHashFinal +#define ippsHashMessage g9_ippsHashMessage +#define ippsHashMethod_MD5 g9_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 g9_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 g9_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI g9_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT g9_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 g9_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI g9_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT g9_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 g9_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI g9_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT g9_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 g9_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 g9_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 g9_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 g9_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize g9_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 g9_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 g9_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 g9_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 g9_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI g9_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT g9_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 g9_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI g9_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT g9_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 g9_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI g9_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT g9_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 g9_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI g9_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT g9_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 g9_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI g9_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT g9_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 g9_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 g9_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 g9_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 g9_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 g9_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 g9_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 g9_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 g9_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf g9_ippsHashGetSize_rmf +#define ippsHashInit_rmf g9_ippsHashInit_rmf +#define ippsHashPack_rmf g9_ippsHashPack_rmf +#define ippsHashUnpack_rmf g9_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf g9_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf g9_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf g9_ippsHashGetTag_rmf +#define ippsHashFinal_rmf g9_ippsHashFinal_rmf +#define ippsHashMessage_rmf g9_ippsHashMessage_rmf +#define ippsHashMethodGetInfo g9_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf g9_ippsHashGetInfo_rmf +#define ippsMGF g9_ippsMGF +#define ippsMGF1_rmf g9_ippsMGF1_rmf +#define ippsMGF2_rmf g9_ippsMGF2_rmf +#define ippsHMAC_GetSize g9_ippsHMAC_GetSize +#define ippsHMAC_Init g9_ippsHMAC_Init +#define ippsHMAC_Pack g9_ippsHMAC_Pack +#define ippsHMAC_Unpack g9_ippsHMAC_Unpack +#define ippsHMAC_Duplicate g9_ippsHMAC_Duplicate +#define ippsHMAC_Update g9_ippsHMAC_Update +#define ippsHMAC_Final g9_ippsHMAC_Final +#define ippsHMAC_GetTag g9_ippsHMAC_GetTag +#define ippsHMAC_Message g9_ippsHMAC_Message +#define ippsHMACGetSize_rmf g9_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf g9_ippsHMACInit_rmf +#define ippsHMACPack_rmf g9_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf g9_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf g9_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf g9_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf g9_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf g9_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf g9_ippsHMACMessage_rmf +#define ippsBigNumGetSize g9_ippsBigNumGetSize +#define ippsBigNumInit g9_ippsBigNumInit +#define ippsCmpZero_BN g9_ippsCmpZero_BN +#define ippsCmp_BN g9_ippsCmp_BN +#define ippsGetSize_BN g9_ippsGetSize_BN +#define ippsSet_BN g9_ippsSet_BN +#define ippsGet_BN g9_ippsGet_BN +#define ippsRef_BN g9_ippsRef_BN +#define ippsExtGet_BN g9_ippsExtGet_BN +#define ippsAdd_BN g9_ippsAdd_BN +#define ippsSub_BN g9_ippsSub_BN +#define ippsMul_BN g9_ippsMul_BN +#define ippsMAC_BN_I g9_ippsMAC_BN_I +#define ippsDiv_BN g9_ippsDiv_BN +#define ippsMod_BN g9_ippsMod_BN +#define ippsGcd_BN g9_ippsGcd_BN +#define ippsModInv_BN g9_ippsModInv_BN +#define ippsSetOctString_BN g9_ippsSetOctString_BN +#define ippsGetOctString_BN g9_ippsGetOctString_BN +#define ippsMontGetSize g9_ippsMontGetSize +#define ippsMontInit g9_ippsMontInit +#define ippsMontSet g9_ippsMontSet +#define ippsMontGet g9_ippsMontGet +#define ippsMontForm g9_ippsMontForm +#define ippsMontMul g9_ippsMontMul +#define ippsMontExp g9_ippsMontExp +#define ippsPRNGGetSize g9_ippsPRNGGetSize +#define ippsPRNGInit g9_ippsPRNGInit +#define ippsPRNGSetModulus g9_ippsPRNGSetModulus +#define ippsPRNGSetH0 g9_ippsPRNGSetH0 +#define ippsPRNGSetAugment g9_ippsPRNGSetAugment +#define ippsPRNGSetSeed g9_ippsPRNGSetSeed +#define ippsPRNGGetSeed g9_ippsPRNGGetSeed +#define ippsPRNGen g9_ippsPRNGen +#define ippsPRNGen_BN g9_ippsPRNGen_BN +#define ippsPRNGenRDRAND g9_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN g9_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED g9_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN g9_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize g9_ippsPrimeGetSize +#define ippsPrimeInit g9_ippsPrimeInit +#define ippsPrimeGen g9_ippsPrimeGen +#define ippsPrimeTest g9_ippsPrimeTest +#define ippsPrimeGen_BN g9_ippsPrimeGen_BN +#define ippsPrimeTest_BN g9_ippsPrimeTest_BN +#define ippsPrimeGet g9_ippsPrimeGet +#define ippsPrimeGet_BN g9_ippsPrimeGet_BN +#define ippsPrimeSet g9_ippsPrimeSet +#define ippsPrimeSet_BN g9_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey g9_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey g9_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey g9_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey g9_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 g9_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 g9_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 g9_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 g9_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 g9_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 g9_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 g9_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 g9_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey g9_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey g9_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt g9_ippsRSA_Encrypt +#define ippsRSA_Decrypt g9_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys g9_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys g9_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP g9_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP g9_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf g9_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf g9_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 g9_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 g9_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS g9_ippsRSASign_PSS +#define ippsRSAVerify_PSS g9_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf g9_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf g9_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 g9_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 g9_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf g9_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf g9_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString g9_ippsDLGetResultString +#define ippsDLPGetSize g9_ippsDLPGetSize +#define ippsDLPInit g9_ippsDLPInit +#define ippsDLPPack g9_ippsDLPPack +#define ippsDLPUnpack g9_ippsDLPUnpack +#define ippsDLPSet g9_ippsDLPSet +#define ippsDLPGet g9_ippsDLPGet +#define ippsDLPSetDP g9_ippsDLPSetDP +#define ippsDLPGetDP g9_ippsDLPGetDP +#define ippsDLPGenKeyPair g9_ippsDLPGenKeyPair +#define ippsDLPPublicKey g9_ippsDLPPublicKey +#define ippsDLPValidateKeyPair g9_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair g9_ippsDLPSetKeyPair +#define ippsDLPSignDSA g9_ippsDLPSignDSA +#define ippsDLPVerifyDSA g9_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH g9_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA g9_ippsDLPGenerateDSA +#define ippsDLPValidateDSA g9_ippsDLPValidateDSA +#define ippsDLPGenerateDH g9_ippsDLPGenerateDH +#define ippsDLPValidateDH g9_ippsDLPValidateDH +#define ippsECCGetResultString g9_ippsECCGetResultString +#define ippsECCPGetSize g9_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 g9_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 g9_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 g9_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 g9_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 g9_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 g9_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 g9_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 g9_ippsECCPGetSizeStdSM2 +#define ippsECCPInit g9_ippsECCPInit +#define ippsECCPInitStd128r1 g9_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 g9_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 g9_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 g9_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 g9_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 g9_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 g9_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 g9_ippsECCPInitStdSM2 +#define ippsECCPSet g9_ippsECCPSet +#define ippsECCPSetStd g9_ippsECCPSetStd +#define ippsECCPSetStd128r1 g9_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 g9_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 g9_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 g9_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 g9_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 g9_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 g9_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 g9_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 g9_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 g9_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 g9_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 g9_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 g9_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 g9_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet g9_ippsECCPGet +#define ippsECCPGetOrderBitSize g9_ippsECCPGetOrderBitSize +#define ippsECCPValidate g9_ippsECCPValidate +#define ippsECCPPointGetSize g9_ippsECCPPointGetSize +#define ippsECCPPointInit g9_ippsECCPPointInit +#define ippsECCPSetPoint g9_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity g9_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint g9_ippsECCPGetPoint +#define ippsECCPCheckPoint g9_ippsECCPCheckPoint +#define ippsECCPComparePoint g9_ippsECCPComparePoint +#define ippsECCPNegativePoint g9_ippsECCPNegativePoint +#define ippsECCPAddPoint g9_ippsECCPAddPoint +#define ippsECCPMulPointScalar g9_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair g9_ippsECCPGenKeyPair +#define ippsECCPPublicKey g9_ippsECCPPublicKey +#define ippsECCPValidateKeyPair g9_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair g9_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH g9_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC g9_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA g9_ippsECCPSignDSA +#define ippsECCPVerifyDSA g9_ippsECCPVerifyDSA +#define ippsECCPSignNR g9_ippsECCPSignNR +#define ippsECCPVerifyNR g9_ippsECCPVerifyNR +#define ippsECCPSignSM2 g9_ippsECCPSignSM2 +#define ippsECCPVerifySM2 g9_ippsECCPVerifySM2 +#define ippsGFpGetSize g9_ippsGFpGetSize +#define ippsGFpInitArbitrary g9_ippsGFpInitArbitrary +#define ippsGFpInitFixed g9_ippsGFpInitFixed +#define ippsGFpInit g9_ippsGFpInit +#define ippsGFpMethod_p192r1 g9_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 g9_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 g9_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 g9_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 g9_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 g9_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn g9_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 g9_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb g9_ippsGFpMethod_pArb +#define ippsGFpxGetSize g9_ippsGFpxGetSize +#define ippsGFpxInit g9_ippsGFpxInit +#define ippsGFpxInitBinomial g9_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 g9_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 g9_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 g9_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 g9_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom g9_ippsGFpxMethod_binom +#define ippsGFpxMethod_com g9_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize g9_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize g9_ippsGFpElementGetSize +#define ippsGFpElementInit g9_ippsGFpElementInit +#define ippsGFpSetElement g9_ippsGFpSetElement +#define ippsGFpSetElementRegular g9_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString g9_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom g9_ippsGFpSetElementRandom +#define ippsGFpSetElementHash g9_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf g9_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement g9_ippsGFpCpyElement +#define ippsGFpGetElement g9_ippsGFpGetElement +#define ippsGFpGetElementOctString g9_ippsGFpGetElementOctString +#define ippsGFpCmpElement g9_ippsGFpCmpElement +#define ippsGFpIsZeroElement g9_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement g9_ippsGFpIsUnityElement +#define ippsGFpConj g9_ippsGFpConj +#define ippsGFpNeg g9_ippsGFpNeg +#define ippsGFpInv g9_ippsGFpInv +#define ippsGFpSqrt g9_ippsGFpSqrt +#define ippsGFpSqr g9_ippsGFpSqr +#define ippsGFpAdd g9_ippsGFpAdd +#define ippsGFpSub g9_ippsGFpSub +#define ippsGFpMul g9_ippsGFpMul +#define ippsGFpExp g9_ippsGFpExp +#define ippsGFpMultiExp g9_ippsGFpMultiExp +#define ippsGFpAdd_PE g9_ippsGFpAdd_PE +#define ippsGFpSub_PE g9_ippsGFpSub_PE +#define ippsGFpMul_PE g9_ippsGFpMul_PE +#define ippsGFpGetInfo g9_ippsGFpGetInfo +#define ippsGFpECGetSize g9_ippsGFpECGetSize +#define ippsGFpECInit g9_ippsGFpECInit +#define ippsGFpECSet g9_ippsGFpECSet +#define ippsGFpECSetSubgroup g9_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 g9_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 g9_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 g9_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 g9_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 g9_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 g9_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 g9_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 g9_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 g9_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 g9_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 g9_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 g9_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 g9_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 g9_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 g9_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet g9_ippsGFpECGet +#define ippsGFpECGetSubgroup g9_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize g9_ippsGFpECScratchBufferSize +#define ippsGFpECVerify g9_ippsGFpECVerify +#define ippsGFpECPointGetSize g9_ippsGFpECPointGetSize +#define ippsGFpECPointInit g9_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity g9_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint g9_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular g9_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom g9_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint g9_ippsGFpECMakePoint +#define ippsGFpECSetPointHash g9_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible g9_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf g9_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf g9_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint g9_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular g9_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString g9_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString g9_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint g9_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup g9_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint g9_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint g9_ippsGFpECCmpPoint +#define ippsGFpECNegPoint g9_ippsGFpECNegPoint +#define ippsGFpECAddPoint g9_ippsGFpECAddPoint +#define ippsGFpECMulPoint g9_ippsGFpECMulPoint +#define ippsGFpECPrivateKey g9_ippsGFpECPrivateKey +#define ippsGFpECPublicKey g9_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair g9_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH g9_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC g9_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 g9_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA g9_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA g9_ippsGFpECVerifyDSA +#define ippsGFpECSignNR g9_ippsGFpECSignNR +#define ippsGFpECVerifyNR g9_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 g9_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 g9_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 g9_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize g9_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init g9_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup g9_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey g9_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm g9_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF g9_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 g9_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 g9_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 g9_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 g9_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 g9_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 g9_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 g9_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 g9_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize g9_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext g9_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize g9_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext g9_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_h9.h b/plugin/ippcp/library/include/single_cpu/ippcp_h9.h new file mode 100644 index 000000000..94eae24a9 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_h9.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion h9_ippcpGetLibVersion +#define ippsDESGetSize h9_ippsDESGetSize +#define ippsDESInit h9_ippsDESInit +#define ippsDESPack h9_ippsDESPack +#define ippsDESUnpack h9_ippsDESUnpack +#define ippsTDESEncryptECB h9_ippsTDESEncryptECB +#define ippsTDESDecryptECB h9_ippsTDESDecryptECB +#define ippsTDESEncryptCBC h9_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC h9_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB h9_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB h9_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB h9_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB h9_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR h9_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR h9_ippsTDESDecryptCTR +#define ippsAESGetSize h9_ippsAESGetSize +#define ippsAESInit h9_ippsAESInit +#define ippsAESSetKey h9_ippsAESSetKey +#define ippsAESPack h9_ippsAESPack +#define ippsAESUnpack h9_ippsAESUnpack +#define ippsAESEncryptECB h9_ippsAESEncryptECB +#define ippsAESDecryptECB h9_ippsAESDecryptECB +#define ippsAESEncryptCBC h9_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 h9_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 h9_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 h9_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC h9_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 h9_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 h9_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 h9_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB h9_ippsAESEncryptCFB +#define ippsAESDecryptCFB h9_ippsAESDecryptCFB +#define ippsAESEncryptOFB h9_ippsAESEncryptOFB +#define ippsAESDecryptOFB h9_ippsAESDecryptOFB +#define ippsAESEncryptCTR h9_ippsAESEncryptCTR +#define ippsAESDecryptCTR h9_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct h9_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct h9_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise h9_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise h9_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise h9_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB h9_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize h9_ippsSMS4GetSize +#define ippsSMS4Init h9_ippsSMS4Init +#define ippsSMS4SetKey h9_ippsSMS4SetKey +#define ippsSMS4EncryptECB h9_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB h9_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC h9_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 h9_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 h9_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 h9_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC h9_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 h9_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 h9_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 h9_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB h9_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB h9_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB h9_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB h9_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR h9_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR h9_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize h9_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit h9_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen h9_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen h9_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart h9_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt h9_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt h9_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag h9_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize h9_ippsAES_CCMGetSize +#define ippsAES_CCMInit h9_ippsAES_CCMInit +#define ippsAES_CCMMessageLen h9_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen h9_ippsAES_CCMTagLen +#define ippsAES_CCMStart h9_ippsAES_CCMStart +#define ippsAES_CCMEncrypt h9_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt h9_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag h9_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize h9_ippsAES_GCMGetSize +#define ippsAES_GCMInit h9_ippsAES_GCMInit +#define ippsAES_GCMReinit h9_ippsAES_GCMReinit +#define ippsAES_GCMReset h9_ippsAES_GCMReset +#define ippsAES_GCMProcessIV h9_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD h9_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart h9_ippsAES_GCMStart +#define ippsAES_GCMEncrypt h9_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt h9_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag h9_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize h9_ippsAES_XTSGetSize +#define ippsAES_XTSInit h9_ippsAES_XTSInit +#define ippsAES_XTSEncrypt h9_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt h9_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC h9_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt h9_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt h9_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize h9_ippsAES_CMACGetSize +#define ippsAES_CMACInit h9_ippsAES_CMACInit +#define ippsAES_CMACUpdate h9_ippsAES_CMACUpdate +#define ippsAES_CMACFinal h9_ippsAES_CMACFinal +#define ippsAES_CMACGetTag h9_ippsAES_CMACGetTag +#define ippsARCFourCheckKey h9_ippsARCFourCheckKey +#define ippsARCFourGetSize h9_ippsARCFourGetSize +#define ippsARCFourInit h9_ippsARCFourInit +#define ippsARCFourReset h9_ippsARCFourReset +#define ippsARCFourPack h9_ippsARCFourPack +#define ippsARCFourUnpack h9_ippsARCFourUnpack +#define ippsARCFourEncrypt h9_ippsARCFourEncrypt +#define ippsARCFourDecrypt h9_ippsARCFourDecrypt +#define ippsSHA1GetSize h9_ippsSHA1GetSize +#define ippsSHA1Init h9_ippsSHA1Init +#define ippsSHA1Duplicate h9_ippsSHA1Duplicate +#define ippsSHA1Pack h9_ippsSHA1Pack +#define ippsSHA1Unpack h9_ippsSHA1Unpack +#define ippsSHA1Update h9_ippsSHA1Update +#define ippsSHA1GetTag h9_ippsSHA1GetTag +#define ippsSHA1Final h9_ippsSHA1Final +#define ippsSHA1MessageDigest h9_ippsSHA1MessageDigest +#define ippsSHA224GetSize h9_ippsSHA224GetSize +#define ippsSHA224Init h9_ippsSHA224Init +#define ippsSHA224Duplicate h9_ippsSHA224Duplicate +#define ippsSHA224Pack h9_ippsSHA224Pack +#define ippsSHA224Unpack h9_ippsSHA224Unpack +#define ippsSHA224Update h9_ippsSHA224Update +#define ippsSHA224GetTag h9_ippsSHA224GetTag +#define ippsSHA224Final h9_ippsSHA224Final +#define ippsSHA224MessageDigest h9_ippsSHA224MessageDigest +#define ippsSHA256GetSize h9_ippsSHA256GetSize +#define ippsSHA256Init h9_ippsSHA256Init +#define ippsSHA256Duplicate h9_ippsSHA256Duplicate +#define ippsSHA256Pack h9_ippsSHA256Pack +#define ippsSHA256Unpack h9_ippsSHA256Unpack +#define ippsSHA256Update h9_ippsSHA256Update +#define ippsSHA256GetTag h9_ippsSHA256GetTag +#define ippsSHA256Final h9_ippsSHA256Final +#define ippsSHA256MessageDigest h9_ippsSHA256MessageDigest +#define ippsSHA384GetSize h9_ippsSHA384GetSize +#define ippsSHA384Init h9_ippsSHA384Init +#define ippsSHA384Duplicate h9_ippsSHA384Duplicate +#define ippsSHA384Pack h9_ippsSHA384Pack +#define ippsSHA384Unpack h9_ippsSHA384Unpack +#define ippsSHA384Update h9_ippsSHA384Update +#define ippsSHA384GetTag h9_ippsSHA384GetTag +#define ippsSHA384Final h9_ippsSHA384Final +#define ippsSHA384MessageDigest h9_ippsSHA384MessageDigest +#define ippsSHA512GetSize h9_ippsSHA512GetSize +#define ippsSHA512Init h9_ippsSHA512Init +#define ippsSHA512Duplicate h9_ippsSHA512Duplicate +#define ippsSHA512Pack h9_ippsSHA512Pack +#define ippsSHA512Unpack h9_ippsSHA512Unpack +#define ippsSHA512Update h9_ippsSHA512Update +#define ippsSHA512GetTag h9_ippsSHA512GetTag +#define ippsSHA512Final h9_ippsSHA512Final +#define ippsSHA512MessageDigest h9_ippsSHA512MessageDigest +#define ippsMD5GetSize h9_ippsMD5GetSize +#define ippsMD5Init h9_ippsMD5Init +#define ippsMD5Duplicate h9_ippsMD5Duplicate +#define ippsMD5Pack h9_ippsMD5Pack +#define ippsMD5Unpack h9_ippsMD5Unpack +#define ippsMD5Update h9_ippsMD5Update +#define ippsMD5GetTag h9_ippsMD5GetTag +#define ippsMD5Final h9_ippsMD5Final +#define ippsMD5MessageDigest h9_ippsMD5MessageDigest +#define ippsSM3GetSize h9_ippsSM3GetSize +#define ippsSM3Init h9_ippsSM3Init +#define ippsSM3Duplicate h9_ippsSM3Duplicate +#define ippsSM3Pack h9_ippsSM3Pack +#define ippsSM3Unpack h9_ippsSM3Unpack +#define ippsSM3Update h9_ippsSM3Update +#define ippsSM3GetTag h9_ippsSM3GetTag +#define ippsSM3Final h9_ippsSM3Final +#define ippsSM3MessageDigest h9_ippsSM3MessageDigest +#define ippsHashGetSize h9_ippsHashGetSize +#define ippsHashInit h9_ippsHashInit +#define ippsHashPack h9_ippsHashPack +#define ippsHashUnpack h9_ippsHashUnpack +#define ippsHashDuplicate h9_ippsHashDuplicate +#define ippsHashUpdate h9_ippsHashUpdate +#define ippsHashGetTag h9_ippsHashGetTag +#define ippsHashFinal h9_ippsHashFinal +#define ippsHashMessage h9_ippsHashMessage +#define ippsHashMethod_MD5 h9_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 h9_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 h9_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI h9_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT h9_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 h9_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI h9_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT h9_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 h9_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI h9_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT h9_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 h9_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 h9_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 h9_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 h9_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize h9_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 h9_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 h9_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 h9_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 h9_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI h9_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT h9_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 h9_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI h9_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT h9_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 h9_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI h9_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT h9_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 h9_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI h9_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT h9_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 h9_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI h9_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT h9_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 h9_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 h9_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 h9_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 h9_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 h9_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 h9_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 h9_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 h9_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf h9_ippsHashGetSize_rmf +#define ippsHashInit_rmf h9_ippsHashInit_rmf +#define ippsHashPack_rmf h9_ippsHashPack_rmf +#define ippsHashUnpack_rmf h9_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf h9_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf h9_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf h9_ippsHashGetTag_rmf +#define ippsHashFinal_rmf h9_ippsHashFinal_rmf +#define ippsHashMessage_rmf h9_ippsHashMessage_rmf +#define ippsHashMethodGetInfo h9_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf h9_ippsHashGetInfo_rmf +#define ippsMGF h9_ippsMGF +#define ippsMGF1_rmf h9_ippsMGF1_rmf +#define ippsMGF2_rmf h9_ippsMGF2_rmf +#define ippsHMAC_GetSize h9_ippsHMAC_GetSize +#define ippsHMAC_Init h9_ippsHMAC_Init +#define ippsHMAC_Pack h9_ippsHMAC_Pack +#define ippsHMAC_Unpack h9_ippsHMAC_Unpack +#define ippsHMAC_Duplicate h9_ippsHMAC_Duplicate +#define ippsHMAC_Update h9_ippsHMAC_Update +#define ippsHMAC_Final h9_ippsHMAC_Final +#define ippsHMAC_GetTag h9_ippsHMAC_GetTag +#define ippsHMAC_Message h9_ippsHMAC_Message +#define ippsHMACGetSize_rmf h9_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf h9_ippsHMACInit_rmf +#define ippsHMACPack_rmf h9_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf h9_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf h9_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf h9_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf h9_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf h9_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf h9_ippsHMACMessage_rmf +#define ippsBigNumGetSize h9_ippsBigNumGetSize +#define ippsBigNumInit h9_ippsBigNumInit +#define ippsCmpZero_BN h9_ippsCmpZero_BN +#define ippsCmp_BN h9_ippsCmp_BN +#define ippsGetSize_BN h9_ippsGetSize_BN +#define ippsSet_BN h9_ippsSet_BN +#define ippsGet_BN h9_ippsGet_BN +#define ippsRef_BN h9_ippsRef_BN +#define ippsExtGet_BN h9_ippsExtGet_BN +#define ippsAdd_BN h9_ippsAdd_BN +#define ippsSub_BN h9_ippsSub_BN +#define ippsMul_BN h9_ippsMul_BN +#define ippsMAC_BN_I h9_ippsMAC_BN_I +#define ippsDiv_BN h9_ippsDiv_BN +#define ippsMod_BN h9_ippsMod_BN +#define ippsGcd_BN h9_ippsGcd_BN +#define ippsModInv_BN h9_ippsModInv_BN +#define ippsSetOctString_BN h9_ippsSetOctString_BN +#define ippsGetOctString_BN h9_ippsGetOctString_BN +#define ippsMontGetSize h9_ippsMontGetSize +#define ippsMontInit h9_ippsMontInit +#define ippsMontSet h9_ippsMontSet +#define ippsMontGet h9_ippsMontGet +#define ippsMontForm h9_ippsMontForm +#define ippsMontMul h9_ippsMontMul +#define ippsMontExp h9_ippsMontExp +#define ippsPRNGGetSize h9_ippsPRNGGetSize +#define ippsPRNGInit h9_ippsPRNGInit +#define ippsPRNGSetModulus h9_ippsPRNGSetModulus +#define ippsPRNGSetH0 h9_ippsPRNGSetH0 +#define ippsPRNGSetAugment h9_ippsPRNGSetAugment +#define ippsPRNGSetSeed h9_ippsPRNGSetSeed +#define ippsPRNGGetSeed h9_ippsPRNGGetSeed +#define ippsPRNGen h9_ippsPRNGen +#define ippsPRNGen_BN h9_ippsPRNGen_BN +#define ippsPRNGenRDRAND h9_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN h9_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED h9_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN h9_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize h9_ippsPrimeGetSize +#define ippsPrimeInit h9_ippsPrimeInit +#define ippsPrimeGen h9_ippsPrimeGen +#define ippsPrimeTest h9_ippsPrimeTest +#define ippsPrimeGen_BN h9_ippsPrimeGen_BN +#define ippsPrimeTest_BN h9_ippsPrimeTest_BN +#define ippsPrimeGet h9_ippsPrimeGet +#define ippsPrimeGet_BN h9_ippsPrimeGet_BN +#define ippsPrimeSet h9_ippsPrimeSet +#define ippsPrimeSet_BN h9_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey h9_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey h9_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey h9_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey h9_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 h9_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 h9_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 h9_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 h9_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 h9_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 h9_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 h9_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 h9_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey h9_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey h9_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt h9_ippsRSA_Encrypt +#define ippsRSA_Decrypt h9_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys h9_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys h9_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP h9_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP h9_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf h9_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf h9_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 h9_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 h9_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS h9_ippsRSASign_PSS +#define ippsRSAVerify_PSS h9_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf h9_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf h9_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 h9_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 h9_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf h9_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf h9_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString h9_ippsDLGetResultString +#define ippsDLPGetSize h9_ippsDLPGetSize +#define ippsDLPInit h9_ippsDLPInit +#define ippsDLPPack h9_ippsDLPPack +#define ippsDLPUnpack h9_ippsDLPUnpack +#define ippsDLPSet h9_ippsDLPSet +#define ippsDLPGet h9_ippsDLPGet +#define ippsDLPSetDP h9_ippsDLPSetDP +#define ippsDLPGetDP h9_ippsDLPGetDP +#define ippsDLPGenKeyPair h9_ippsDLPGenKeyPair +#define ippsDLPPublicKey h9_ippsDLPPublicKey +#define ippsDLPValidateKeyPair h9_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair h9_ippsDLPSetKeyPair +#define ippsDLPSignDSA h9_ippsDLPSignDSA +#define ippsDLPVerifyDSA h9_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH h9_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA h9_ippsDLPGenerateDSA +#define ippsDLPValidateDSA h9_ippsDLPValidateDSA +#define ippsDLPGenerateDH h9_ippsDLPGenerateDH +#define ippsDLPValidateDH h9_ippsDLPValidateDH +#define ippsECCGetResultString h9_ippsECCGetResultString +#define ippsECCPGetSize h9_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 h9_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 h9_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 h9_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 h9_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 h9_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 h9_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 h9_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 h9_ippsECCPGetSizeStdSM2 +#define ippsECCPInit h9_ippsECCPInit +#define ippsECCPInitStd128r1 h9_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 h9_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 h9_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 h9_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 h9_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 h9_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 h9_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 h9_ippsECCPInitStdSM2 +#define ippsECCPSet h9_ippsECCPSet +#define ippsECCPSetStd h9_ippsECCPSetStd +#define ippsECCPSetStd128r1 h9_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 h9_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 h9_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 h9_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 h9_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 h9_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 h9_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 h9_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 h9_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 h9_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 h9_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 h9_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 h9_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 h9_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet h9_ippsECCPGet +#define ippsECCPGetOrderBitSize h9_ippsECCPGetOrderBitSize +#define ippsECCPValidate h9_ippsECCPValidate +#define ippsECCPPointGetSize h9_ippsECCPPointGetSize +#define ippsECCPPointInit h9_ippsECCPPointInit +#define ippsECCPSetPoint h9_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity h9_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint h9_ippsECCPGetPoint +#define ippsECCPCheckPoint h9_ippsECCPCheckPoint +#define ippsECCPComparePoint h9_ippsECCPComparePoint +#define ippsECCPNegativePoint h9_ippsECCPNegativePoint +#define ippsECCPAddPoint h9_ippsECCPAddPoint +#define ippsECCPMulPointScalar h9_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair h9_ippsECCPGenKeyPair +#define ippsECCPPublicKey h9_ippsECCPPublicKey +#define ippsECCPValidateKeyPair h9_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair h9_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH h9_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC h9_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA h9_ippsECCPSignDSA +#define ippsECCPVerifyDSA h9_ippsECCPVerifyDSA +#define ippsECCPSignNR h9_ippsECCPSignNR +#define ippsECCPVerifyNR h9_ippsECCPVerifyNR +#define ippsECCPSignSM2 h9_ippsECCPSignSM2 +#define ippsECCPVerifySM2 h9_ippsECCPVerifySM2 +#define ippsGFpGetSize h9_ippsGFpGetSize +#define ippsGFpInitArbitrary h9_ippsGFpInitArbitrary +#define ippsGFpInitFixed h9_ippsGFpInitFixed +#define ippsGFpInit h9_ippsGFpInit +#define ippsGFpMethod_p192r1 h9_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 h9_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 h9_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 h9_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 h9_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 h9_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn h9_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 h9_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb h9_ippsGFpMethod_pArb +#define ippsGFpxGetSize h9_ippsGFpxGetSize +#define ippsGFpxInit h9_ippsGFpxInit +#define ippsGFpxInitBinomial h9_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 h9_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 h9_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 h9_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 h9_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom h9_ippsGFpxMethod_binom +#define ippsGFpxMethod_com h9_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize h9_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize h9_ippsGFpElementGetSize +#define ippsGFpElementInit h9_ippsGFpElementInit +#define ippsGFpSetElement h9_ippsGFpSetElement +#define ippsGFpSetElementRegular h9_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString h9_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom h9_ippsGFpSetElementRandom +#define ippsGFpSetElementHash h9_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf h9_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement h9_ippsGFpCpyElement +#define ippsGFpGetElement h9_ippsGFpGetElement +#define ippsGFpGetElementOctString h9_ippsGFpGetElementOctString +#define ippsGFpCmpElement h9_ippsGFpCmpElement +#define ippsGFpIsZeroElement h9_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement h9_ippsGFpIsUnityElement +#define ippsGFpConj h9_ippsGFpConj +#define ippsGFpNeg h9_ippsGFpNeg +#define ippsGFpInv h9_ippsGFpInv +#define ippsGFpSqrt h9_ippsGFpSqrt +#define ippsGFpSqr h9_ippsGFpSqr +#define ippsGFpAdd h9_ippsGFpAdd +#define ippsGFpSub h9_ippsGFpSub +#define ippsGFpMul h9_ippsGFpMul +#define ippsGFpExp h9_ippsGFpExp +#define ippsGFpMultiExp h9_ippsGFpMultiExp +#define ippsGFpAdd_PE h9_ippsGFpAdd_PE +#define ippsGFpSub_PE h9_ippsGFpSub_PE +#define ippsGFpMul_PE h9_ippsGFpMul_PE +#define ippsGFpGetInfo h9_ippsGFpGetInfo +#define ippsGFpECGetSize h9_ippsGFpECGetSize +#define ippsGFpECInit h9_ippsGFpECInit +#define ippsGFpECSet h9_ippsGFpECSet +#define ippsGFpECSetSubgroup h9_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 h9_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 h9_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 h9_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 h9_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 h9_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 h9_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 h9_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 h9_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 h9_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 h9_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 h9_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 h9_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 h9_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 h9_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 h9_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet h9_ippsGFpECGet +#define ippsGFpECGetSubgroup h9_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize h9_ippsGFpECScratchBufferSize +#define ippsGFpECVerify h9_ippsGFpECVerify +#define ippsGFpECPointGetSize h9_ippsGFpECPointGetSize +#define ippsGFpECPointInit h9_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity h9_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint h9_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular h9_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom h9_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint h9_ippsGFpECMakePoint +#define ippsGFpECSetPointHash h9_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible h9_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf h9_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf h9_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint h9_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular h9_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString h9_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString h9_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint h9_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup h9_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint h9_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint h9_ippsGFpECCmpPoint +#define ippsGFpECNegPoint h9_ippsGFpECNegPoint +#define ippsGFpECAddPoint h9_ippsGFpECAddPoint +#define ippsGFpECMulPoint h9_ippsGFpECMulPoint +#define ippsGFpECPrivateKey h9_ippsGFpECPrivateKey +#define ippsGFpECPublicKey h9_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair h9_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH h9_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC h9_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 h9_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA h9_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA h9_ippsGFpECVerifyDSA +#define ippsGFpECSignNR h9_ippsGFpECSignNR +#define ippsGFpECVerifyNR h9_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 h9_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 h9_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 h9_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize h9_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init h9_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup h9_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey h9_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm h9_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF h9_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 h9_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 h9_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 h9_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 h9_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 h9_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 h9_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 h9_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 h9_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize h9_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext h9_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize h9_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext h9_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_k0.h b/plugin/ippcp/library/include/single_cpu/ippcp_k0.h new file mode 100644 index 000000000..8e1a74029 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_k0.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion k0_ippcpGetLibVersion +#define ippsDESGetSize k0_ippsDESGetSize +#define ippsDESInit k0_ippsDESInit +#define ippsDESPack k0_ippsDESPack +#define ippsDESUnpack k0_ippsDESUnpack +#define ippsTDESEncryptECB k0_ippsTDESEncryptECB +#define ippsTDESDecryptECB k0_ippsTDESDecryptECB +#define ippsTDESEncryptCBC k0_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC k0_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB k0_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB k0_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB k0_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB k0_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR k0_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR k0_ippsTDESDecryptCTR +#define ippsAESGetSize k0_ippsAESGetSize +#define ippsAESInit k0_ippsAESInit +#define ippsAESSetKey k0_ippsAESSetKey +#define ippsAESPack k0_ippsAESPack +#define ippsAESUnpack k0_ippsAESUnpack +#define ippsAESEncryptECB k0_ippsAESEncryptECB +#define ippsAESDecryptECB k0_ippsAESDecryptECB +#define ippsAESEncryptCBC k0_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 k0_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 k0_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 k0_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC k0_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 k0_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 k0_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 k0_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB k0_ippsAESEncryptCFB +#define ippsAESDecryptCFB k0_ippsAESDecryptCFB +#define ippsAESEncryptOFB k0_ippsAESEncryptOFB +#define ippsAESDecryptOFB k0_ippsAESDecryptOFB +#define ippsAESEncryptCTR k0_ippsAESEncryptCTR +#define ippsAESDecryptCTR k0_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct k0_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct k0_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise k0_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise k0_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise k0_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB k0_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize k0_ippsSMS4GetSize +#define ippsSMS4Init k0_ippsSMS4Init +#define ippsSMS4SetKey k0_ippsSMS4SetKey +#define ippsSMS4EncryptECB k0_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB k0_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC k0_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 k0_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 k0_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 k0_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC k0_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 k0_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 k0_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 k0_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB k0_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB k0_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB k0_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB k0_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR k0_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR k0_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize k0_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit k0_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen k0_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen k0_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart k0_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt k0_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt k0_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag k0_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize k0_ippsAES_CCMGetSize +#define ippsAES_CCMInit k0_ippsAES_CCMInit +#define ippsAES_CCMMessageLen k0_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen k0_ippsAES_CCMTagLen +#define ippsAES_CCMStart k0_ippsAES_CCMStart +#define ippsAES_CCMEncrypt k0_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt k0_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag k0_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize k0_ippsAES_GCMGetSize +#define ippsAES_GCMInit k0_ippsAES_GCMInit +#define ippsAES_GCMReinit k0_ippsAES_GCMReinit +#define ippsAES_GCMReset k0_ippsAES_GCMReset +#define ippsAES_GCMProcessIV k0_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD k0_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart k0_ippsAES_GCMStart +#define ippsAES_GCMEncrypt k0_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt k0_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag k0_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize k0_ippsAES_XTSGetSize +#define ippsAES_XTSInit k0_ippsAES_XTSInit +#define ippsAES_XTSEncrypt k0_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt k0_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC k0_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt k0_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt k0_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize k0_ippsAES_CMACGetSize +#define ippsAES_CMACInit k0_ippsAES_CMACInit +#define ippsAES_CMACUpdate k0_ippsAES_CMACUpdate +#define ippsAES_CMACFinal k0_ippsAES_CMACFinal +#define ippsAES_CMACGetTag k0_ippsAES_CMACGetTag +#define ippsARCFourCheckKey k0_ippsARCFourCheckKey +#define ippsARCFourGetSize k0_ippsARCFourGetSize +#define ippsARCFourInit k0_ippsARCFourInit +#define ippsARCFourReset k0_ippsARCFourReset +#define ippsARCFourPack k0_ippsARCFourPack +#define ippsARCFourUnpack k0_ippsARCFourUnpack +#define ippsARCFourEncrypt k0_ippsARCFourEncrypt +#define ippsARCFourDecrypt k0_ippsARCFourDecrypt +#define ippsSHA1GetSize k0_ippsSHA1GetSize +#define ippsSHA1Init k0_ippsSHA1Init +#define ippsSHA1Duplicate k0_ippsSHA1Duplicate +#define ippsSHA1Pack k0_ippsSHA1Pack +#define ippsSHA1Unpack k0_ippsSHA1Unpack +#define ippsSHA1Update k0_ippsSHA1Update +#define ippsSHA1GetTag k0_ippsSHA1GetTag +#define ippsSHA1Final k0_ippsSHA1Final +#define ippsSHA1MessageDigest k0_ippsSHA1MessageDigest +#define ippsSHA224GetSize k0_ippsSHA224GetSize +#define ippsSHA224Init k0_ippsSHA224Init +#define ippsSHA224Duplicate k0_ippsSHA224Duplicate +#define ippsSHA224Pack k0_ippsSHA224Pack +#define ippsSHA224Unpack k0_ippsSHA224Unpack +#define ippsSHA224Update k0_ippsSHA224Update +#define ippsSHA224GetTag k0_ippsSHA224GetTag +#define ippsSHA224Final k0_ippsSHA224Final +#define ippsSHA224MessageDigest k0_ippsSHA224MessageDigest +#define ippsSHA256GetSize k0_ippsSHA256GetSize +#define ippsSHA256Init k0_ippsSHA256Init +#define ippsSHA256Duplicate k0_ippsSHA256Duplicate +#define ippsSHA256Pack k0_ippsSHA256Pack +#define ippsSHA256Unpack k0_ippsSHA256Unpack +#define ippsSHA256Update k0_ippsSHA256Update +#define ippsSHA256GetTag k0_ippsSHA256GetTag +#define ippsSHA256Final k0_ippsSHA256Final +#define ippsSHA256MessageDigest k0_ippsSHA256MessageDigest +#define ippsSHA384GetSize k0_ippsSHA384GetSize +#define ippsSHA384Init k0_ippsSHA384Init +#define ippsSHA384Duplicate k0_ippsSHA384Duplicate +#define ippsSHA384Pack k0_ippsSHA384Pack +#define ippsSHA384Unpack k0_ippsSHA384Unpack +#define ippsSHA384Update k0_ippsSHA384Update +#define ippsSHA384GetTag k0_ippsSHA384GetTag +#define ippsSHA384Final k0_ippsSHA384Final +#define ippsSHA384MessageDigest k0_ippsSHA384MessageDigest +#define ippsSHA512GetSize k0_ippsSHA512GetSize +#define ippsSHA512Init k0_ippsSHA512Init +#define ippsSHA512Duplicate k0_ippsSHA512Duplicate +#define ippsSHA512Pack k0_ippsSHA512Pack +#define ippsSHA512Unpack k0_ippsSHA512Unpack +#define ippsSHA512Update k0_ippsSHA512Update +#define ippsSHA512GetTag k0_ippsSHA512GetTag +#define ippsSHA512Final k0_ippsSHA512Final +#define ippsSHA512MessageDigest k0_ippsSHA512MessageDigest +#define ippsMD5GetSize k0_ippsMD5GetSize +#define ippsMD5Init k0_ippsMD5Init +#define ippsMD5Duplicate k0_ippsMD5Duplicate +#define ippsMD5Pack k0_ippsMD5Pack +#define ippsMD5Unpack k0_ippsMD5Unpack +#define ippsMD5Update k0_ippsMD5Update +#define ippsMD5GetTag k0_ippsMD5GetTag +#define ippsMD5Final k0_ippsMD5Final +#define ippsMD5MessageDigest k0_ippsMD5MessageDigest +#define ippsSM3GetSize k0_ippsSM3GetSize +#define ippsSM3Init k0_ippsSM3Init +#define ippsSM3Duplicate k0_ippsSM3Duplicate +#define ippsSM3Pack k0_ippsSM3Pack +#define ippsSM3Unpack k0_ippsSM3Unpack +#define ippsSM3Update k0_ippsSM3Update +#define ippsSM3GetTag k0_ippsSM3GetTag +#define ippsSM3Final k0_ippsSM3Final +#define ippsSM3MessageDigest k0_ippsSM3MessageDigest +#define ippsHashGetSize k0_ippsHashGetSize +#define ippsHashInit k0_ippsHashInit +#define ippsHashPack k0_ippsHashPack +#define ippsHashUnpack k0_ippsHashUnpack +#define ippsHashDuplicate k0_ippsHashDuplicate +#define ippsHashUpdate k0_ippsHashUpdate +#define ippsHashGetTag k0_ippsHashGetTag +#define ippsHashFinal k0_ippsHashFinal +#define ippsHashMessage k0_ippsHashMessage +#define ippsHashMethod_MD5 k0_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 k0_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 k0_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI k0_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT k0_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 k0_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI k0_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT k0_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 k0_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI k0_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT k0_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 k0_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 k0_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 k0_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 k0_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize k0_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 k0_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 k0_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 k0_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 k0_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI k0_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT k0_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 k0_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI k0_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT k0_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 k0_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI k0_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT k0_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 k0_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI k0_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT k0_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 k0_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI k0_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT k0_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 k0_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 k0_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 k0_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 k0_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 k0_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 k0_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 k0_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 k0_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf k0_ippsHashGetSize_rmf +#define ippsHashInit_rmf k0_ippsHashInit_rmf +#define ippsHashPack_rmf k0_ippsHashPack_rmf +#define ippsHashUnpack_rmf k0_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf k0_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf k0_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf k0_ippsHashGetTag_rmf +#define ippsHashFinal_rmf k0_ippsHashFinal_rmf +#define ippsHashMessage_rmf k0_ippsHashMessage_rmf +#define ippsHashMethodGetInfo k0_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf k0_ippsHashGetInfo_rmf +#define ippsMGF k0_ippsMGF +#define ippsMGF1_rmf k0_ippsMGF1_rmf +#define ippsMGF2_rmf k0_ippsMGF2_rmf +#define ippsHMAC_GetSize k0_ippsHMAC_GetSize +#define ippsHMAC_Init k0_ippsHMAC_Init +#define ippsHMAC_Pack k0_ippsHMAC_Pack +#define ippsHMAC_Unpack k0_ippsHMAC_Unpack +#define ippsHMAC_Duplicate k0_ippsHMAC_Duplicate +#define ippsHMAC_Update k0_ippsHMAC_Update +#define ippsHMAC_Final k0_ippsHMAC_Final +#define ippsHMAC_GetTag k0_ippsHMAC_GetTag +#define ippsHMAC_Message k0_ippsHMAC_Message +#define ippsHMACGetSize_rmf k0_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf k0_ippsHMACInit_rmf +#define ippsHMACPack_rmf k0_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf k0_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf k0_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf k0_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf k0_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf k0_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf k0_ippsHMACMessage_rmf +#define ippsBigNumGetSize k0_ippsBigNumGetSize +#define ippsBigNumInit k0_ippsBigNumInit +#define ippsCmpZero_BN k0_ippsCmpZero_BN +#define ippsCmp_BN k0_ippsCmp_BN +#define ippsGetSize_BN k0_ippsGetSize_BN +#define ippsSet_BN k0_ippsSet_BN +#define ippsGet_BN k0_ippsGet_BN +#define ippsRef_BN k0_ippsRef_BN +#define ippsExtGet_BN k0_ippsExtGet_BN +#define ippsAdd_BN k0_ippsAdd_BN +#define ippsSub_BN k0_ippsSub_BN +#define ippsMul_BN k0_ippsMul_BN +#define ippsMAC_BN_I k0_ippsMAC_BN_I +#define ippsDiv_BN k0_ippsDiv_BN +#define ippsMod_BN k0_ippsMod_BN +#define ippsGcd_BN k0_ippsGcd_BN +#define ippsModInv_BN k0_ippsModInv_BN +#define ippsSetOctString_BN k0_ippsSetOctString_BN +#define ippsGetOctString_BN k0_ippsGetOctString_BN +#define ippsMontGetSize k0_ippsMontGetSize +#define ippsMontInit k0_ippsMontInit +#define ippsMontSet k0_ippsMontSet +#define ippsMontGet k0_ippsMontGet +#define ippsMontForm k0_ippsMontForm +#define ippsMontMul k0_ippsMontMul +#define ippsMontExp k0_ippsMontExp +#define ippsPRNGGetSize k0_ippsPRNGGetSize +#define ippsPRNGInit k0_ippsPRNGInit +#define ippsPRNGSetModulus k0_ippsPRNGSetModulus +#define ippsPRNGSetH0 k0_ippsPRNGSetH0 +#define ippsPRNGSetAugment k0_ippsPRNGSetAugment +#define ippsPRNGSetSeed k0_ippsPRNGSetSeed +#define ippsPRNGGetSeed k0_ippsPRNGGetSeed +#define ippsPRNGen k0_ippsPRNGen +#define ippsPRNGen_BN k0_ippsPRNGen_BN +#define ippsPRNGenRDRAND k0_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN k0_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED k0_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN k0_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize k0_ippsPrimeGetSize +#define ippsPrimeInit k0_ippsPrimeInit +#define ippsPrimeGen k0_ippsPrimeGen +#define ippsPrimeTest k0_ippsPrimeTest +#define ippsPrimeGen_BN k0_ippsPrimeGen_BN +#define ippsPrimeTest_BN k0_ippsPrimeTest_BN +#define ippsPrimeGet k0_ippsPrimeGet +#define ippsPrimeGet_BN k0_ippsPrimeGet_BN +#define ippsPrimeSet k0_ippsPrimeSet +#define ippsPrimeSet_BN k0_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey k0_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey k0_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey k0_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey k0_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 k0_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 k0_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 k0_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 k0_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 k0_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 k0_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 k0_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 k0_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey k0_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey k0_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt k0_ippsRSA_Encrypt +#define ippsRSA_Decrypt k0_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys k0_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys k0_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP k0_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP k0_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf k0_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf k0_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 k0_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 k0_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS k0_ippsRSASign_PSS +#define ippsRSAVerify_PSS k0_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf k0_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf k0_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 k0_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 k0_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf k0_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf k0_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString k0_ippsDLGetResultString +#define ippsDLPGetSize k0_ippsDLPGetSize +#define ippsDLPInit k0_ippsDLPInit +#define ippsDLPPack k0_ippsDLPPack +#define ippsDLPUnpack k0_ippsDLPUnpack +#define ippsDLPSet k0_ippsDLPSet +#define ippsDLPGet k0_ippsDLPGet +#define ippsDLPSetDP k0_ippsDLPSetDP +#define ippsDLPGetDP k0_ippsDLPGetDP +#define ippsDLPGenKeyPair k0_ippsDLPGenKeyPair +#define ippsDLPPublicKey k0_ippsDLPPublicKey +#define ippsDLPValidateKeyPair k0_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair k0_ippsDLPSetKeyPair +#define ippsDLPSignDSA k0_ippsDLPSignDSA +#define ippsDLPVerifyDSA k0_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH k0_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA k0_ippsDLPGenerateDSA +#define ippsDLPValidateDSA k0_ippsDLPValidateDSA +#define ippsDLPGenerateDH k0_ippsDLPGenerateDH +#define ippsDLPValidateDH k0_ippsDLPValidateDH +#define ippsECCGetResultString k0_ippsECCGetResultString +#define ippsECCPGetSize k0_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 k0_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 k0_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 k0_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 k0_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 k0_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 k0_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 k0_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 k0_ippsECCPGetSizeStdSM2 +#define ippsECCPInit k0_ippsECCPInit +#define ippsECCPInitStd128r1 k0_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 k0_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 k0_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 k0_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 k0_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 k0_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 k0_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 k0_ippsECCPInitStdSM2 +#define ippsECCPSet k0_ippsECCPSet +#define ippsECCPSetStd k0_ippsECCPSetStd +#define ippsECCPSetStd128r1 k0_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 k0_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 k0_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 k0_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 k0_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 k0_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 k0_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 k0_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 k0_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 k0_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 k0_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 k0_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 k0_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 k0_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet k0_ippsECCPGet +#define ippsECCPGetOrderBitSize k0_ippsECCPGetOrderBitSize +#define ippsECCPValidate k0_ippsECCPValidate +#define ippsECCPPointGetSize k0_ippsECCPPointGetSize +#define ippsECCPPointInit k0_ippsECCPPointInit +#define ippsECCPSetPoint k0_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity k0_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint k0_ippsECCPGetPoint +#define ippsECCPCheckPoint k0_ippsECCPCheckPoint +#define ippsECCPComparePoint k0_ippsECCPComparePoint +#define ippsECCPNegativePoint k0_ippsECCPNegativePoint +#define ippsECCPAddPoint k0_ippsECCPAddPoint +#define ippsECCPMulPointScalar k0_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair k0_ippsECCPGenKeyPair +#define ippsECCPPublicKey k0_ippsECCPPublicKey +#define ippsECCPValidateKeyPair k0_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair k0_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH k0_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC k0_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA k0_ippsECCPSignDSA +#define ippsECCPVerifyDSA k0_ippsECCPVerifyDSA +#define ippsECCPSignNR k0_ippsECCPSignNR +#define ippsECCPVerifyNR k0_ippsECCPVerifyNR +#define ippsECCPSignSM2 k0_ippsECCPSignSM2 +#define ippsECCPVerifySM2 k0_ippsECCPVerifySM2 +#define ippsGFpGetSize k0_ippsGFpGetSize +#define ippsGFpInitArbitrary k0_ippsGFpInitArbitrary +#define ippsGFpInitFixed k0_ippsGFpInitFixed +#define ippsGFpInit k0_ippsGFpInit +#define ippsGFpMethod_p192r1 k0_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 k0_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 k0_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 k0_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 k0_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 k0_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn k0_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 k0_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb k0_ippsGFpMethod_pArb +#define ippsGFpxGetSize k0_ippsGFpxGetSize +#define ippsGFpxInit k0_ippsGFpxInit +#define ippsGFpxInitBinomial k0_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 k0_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 k0_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 k0_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 k0_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom k0_ippsGFpxMethod_binom +#define ippsGFpxMethod_com k0_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize k0_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize k0_ippsGFpElementGetSize +#define ippsGFpElementInit k0_ippsGFpElementInit +#define ippsGFpSetElement k0_ippsGFpSetElement +#define ippsGFpSetElementRegular k0_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString k0_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom k0_ippsGFpSetElementRandom +#define ippsGFpSetElementHash k0_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf k0_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement k0_ippsGFpCpyElement +#define ippsGFpGetElement k0_ippsGFpGetElement +#define ippsGFpGetElementOctString k0_ippsGFpGetElementOctString +#define ippsGFpCmpElement k0_ippsGFpCmpElement +#define ippsGFpIsZeroElement k0_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement k0_ippsGFpIsUnityElement +#define ippsGFpConj k0_ippsGFpConj +#define ippsGFpNeg k0_ippsGFpNeg +#define ippsGFpInv k0_ippsGFpInv +#define ippsGFpSqrt k0_ippsGFpSqrt +#define ippsGFpSqr k0_ippsGFpSqr +#define ippsGFpAdd k0_ippsGFpAdd +#define ippsGFpSub k0_ippsGFpSub +#define ippsGFpMul k0_ippsGFpMul +#define ippsGFpExp k0_ippsGFpExp +#define ippsGFpMultiExp k0_ippsGFpMultiExp +#define ippsGFpAdd_PE k0_ippsGFpAdd_PE +#define ippsGFpSub_PE k0_ippsGFpSub_PE +#define ippsGFpMul_PE k0_ippsGFpMul_PE +#define ippsGFpGetInfo k0_ippsGFpGetInfo +#define ippsGFpECGetSize k0_ippsGFpECGetSize +#define ippsGFpECInit k0_ippsGFpECInit +#define ippsGFpECSet k0_ippsGFpECSet +#define ippsGFpECSetSubgroup k0_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 k0_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 k0_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 k0_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 k0_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 k0_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 k0_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 k0_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 k0_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 k0_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 k0_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 k0_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 k0_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 k0_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 k0_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 k0_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet k0_ippsGFpECGet +#define ippsGFpECGetSubgroup k0_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize k0_ippsGFpECScratchBufferSize +#define ippsGFpECVerify k0_ippsGFpECVerify +#define ippsGFpECPointGetSize k0_ippsGFpECPointGetSize +#define ippsGFpECPointInit k0_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity k0_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint k0_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular k0_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom k0_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint k0_ippsGFpECMakePoint +#define ippsGFpECSetPointHash k0_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible k0_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf k0_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf k0_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint k0_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular k0_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString k0_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString k0_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint k0_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup k0_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint k0_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint k0_ippsGFpECCmpPoint +#define ippsGFpECNegPoint k0_ippsGFpECNegPoint +#define ippsGFpECAddPoint k0_ippsGFpECAddPoint +#define ippsGFpECMulPoint k0_ippsGFpECMulPoint +#define ippsGFpECPrivateKey k0_ippsGFpECPrivateKey +#define ippsGFpECPublicKey k0_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair k0_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH k0_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC k0_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 k0_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA k0_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA k0_ippsGFpECVerifyDSA +#define ippsGFpECSignNR k0_ippsGFpECSignNR +#define ippsGFpECVerifyNR k0_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 k0_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 k0_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 k0_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize k0_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init k0_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup k0_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey k0_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm k0_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF k0_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 k0_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 k0_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 k0_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 k0_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 k0_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 k0_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 k0_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 k0_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize k0_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext k0_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize k0_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext k0_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_k1.h b/plugin/ippcp/library/include/single_cpu/ippcp_k1.h new file mode 100644 index 000000000..8f5aad300 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_k1.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion k1_ippcpGetLibVersion +#define ippsDESGetSize k1_ippsDESGetSize +#define ippsDESInit k1_ippsDESInit +#define ippsDESPack k1_ippsDESPack +#define ippsDESUnpack k1_ippsDESUnpack +#define ippsTDESEncryptECB k1_ippsTDESEncryptECB +#define ippsTDESDecryptECB k1_ippsTDESDecryptECB +#define ippsTDESEncryptCBC k1_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC k1_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB k1_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB k1_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB k1_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB k1_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR k1_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR k1_ippsTDESDecryptCTR +#define ippsAESGetSize k1_ippsAESGetSize +#define ippsAESInit k1_ippsAESInit +#define ippsAESSetKey k1_ippsAESSetKey +#define ippsAESPack k1_ippsAESPack +#define ippsAESUnpack k1_ippsAESUnpack +#define ippsAESEncryptECB k1_ippsAESEncryptECB +#define ippsAESDecryptECB k1_ippsAESDecryptECB +#define ippsAESEncryptCBC k1_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 k1_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 k1_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 k1_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC k1_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 k1_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 k1_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 k1_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB k1_ippsAESEncryptCFB +#define ippsAESDecryptCFB k1_ippsAESDecryptCFB +#define ippsAESEncryptOFB k1_ippsAESEncryptOFB +#define ippsAESDecryptOFB k1_ippsAESDecryptOFB +#define ippsAESEncryptCTR k1_ippsAESEncryptCTR +#define ippsAESDecryptCTR k1_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct k1_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct k1_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise k1_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise k1_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise k1_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB k1_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize k1_ippsSMS4GetSize +#define ippsSMS4Init k1_ippsSMS4Init +#define ippsSMS4SetKey k1_ippsSMS4SetKey +#define ippsSMS4EncryptECB k1_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB k1_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC k1_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 k1_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 k1_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 k1_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC k1_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 k1_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 k1_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 k1_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB k1_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB k1_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB k1_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB k1_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR k1_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR k1_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize k1_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit k1_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen k1_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen k1_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart k1_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt k1_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt k1_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag k1_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize k1_ippsAES_CCMGetSize +#define ippsAES_CCMInit k1_ippsAES_CCMInit +#define ippsAES_CCMMessageLen k1_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen k1_ippsAES_CCMTagLen +#define ippsAES_CCMStart k1_ippsAES_CCMStart +#define ippsAES_CCMEncrypt k1_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt k1_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag k1_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize k1_ippsAES_GCMGetSize +#define ippsAES_GCMInit k1_ippsAES_GCMInit +#define ippsAES_GCMReinit k1_ippsAES_GCMReinit +#define ippsAES_GCMReset k1_ippsAES_GCMReset +#define ippsAES_GCMProcessIV k1_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD k1_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart k1_ippsAES_GCMStart +#define ippsAES_GCMEncrypt k1_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt k1_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag k1_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize k1_ippsAES_XTSGetSize +#define ippsAES_XTSInit k1_ippsAES_XTSInit +#define ippsAES_XTSEncrypt k1_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt k1_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC k1_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt k1_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt k1_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize k1_ippsAES_CMACGetSize +#define ippsAES_CMACInit k1_ippsAES_CMACInit +#define ippsAES_CMACUpdate k1_ippsAES_CMACUpdate +#define ippsAES_CMACFinal k1_ippsAES_CMACFinal +#define ippsAES_CMACGetTag k1_ippsAES_CMACGetTag +#define ippsARCFourCheckKey k1_ippsARCFourCheckKey +#define ippsARCFourGetSize k1_ippsARCFourGetSize +#define ippsARCFourInit k1_ippsARCFourInit +#define ippsARCFourReset k1_ippsARCFourReset +#define ippsARCFourPack k1_ippsARCFourPack +#define ippsARCFourUnpack k1_ippsARCFourUnpack +#define ippsARCFourEncrypt k1_ippsARCFourEncrypt +#define ippsARCFourDecrypt k1_ippsARCFourDecrypt +#define ippsSHA1GetSize k1_ippsSHA1GetSize +#define ippsSHA1Init k1_ippsSHA1Init +#define ippsSHA1Duplicate k1_ippsSHA1Duplicate +#define ippsSHA1Pack k1_ippsSHA1Pack +#define ippsSHA1Unpack k1_ippsSHA1Unpack +#define ippsSHA1Update k1_ippsSHA1Update +#define ippsSHA1GetTag k1_ippsSHA1GetTag +#define ippsSHA1Final k1_ippsSHA1Final +#define ippsSHA1MessageDigest k1_ippsSHA1MessageDigest +#define ippsSHA224GetSize k1_ippsSHA224GetSize +#define ippsSHA224Init k1_ippsSHA224Init +#define ippsSHA224Duplicate k1_ippsSHA224Duplicate +#define ippsSHA224Pack k1_ippsSHA224Pack +#define ippsSHA224Unpack k1_ippsSHA224Unpack +#define ippsSHA224Update k1_ippsSHA224Update +#define ippsSHA224GetTag k1_ippsSHA224GetTag +#define ippsSHA224Final k1_ippsSHA224Final +#define ippsSHA224MessageDigest k1_ippsSHA224MessageDigest +#define ippsSHA256GetSize k1_ippsSHA256GetSize +#define ippsSHA256Init k1_ippsSHA256Init +#define ippsSHA256Duplicate k1_ippsSHA256Duplicate +#define ippsSHA256Pack k1_ippsSHA256Pack +#define ippsSHA256Unpack k1_ippsSHA256Unpack +#define ippsSHA256Update k1_ippsSHA256Update +#define ippsSHA256GetTag k1_ippsSHA256GetTag +#define ippsSHA256Final k1_ippsSHA256Final +#define ippsSHA256MessageDigest k1_ippsSHA256MessageDigest +#define ippsSHA384GetSize k1_ippsSHA384GetSize +#define ippsSHA384Init k1_ippsSHA384Init +#define ippsSHA384Duplicate k1_ippsSHA384Duplicate +#define ippsSHA384Pack k1_ippsSHA384Pack +#define ippsSHA384Unpack k1_ippsSHA384Unpack +#define ippsSHA384Update k1_ippsSHA384Update +#define ippsSHA384GetTag k1_ippsSHA384GetTag +#define ippsSHA384Final k1_ippsSHA384Final +#define ippsSHA384MessageDigest k1_ippsSHA384MessageDigest +#define ippsSHA512GetSize k1_ippsSHA512GetSize +#define ippsSHA512Init k1_ippsSHA512Init +#define ippsSHA512Duplicate k1_ippsSHA512Duplicate +#define ippsSHA512Pack k1_ippsSHA512Pack +#define ippsSHA512Unpack k1_ippsSHA512Unpack +#define ippsSHA512Update k1_ippsSHA512Update +#define ippsSHA512GetTag k1_ippsSHA512GetTag +#define ippsSHA512Final k1_ippsSHA512Final +#define ippsSHA512MessageDigest k1_ippsSHA512MessageDigest +#define ippsMD5GetSize k1_ippsMD5GetSize +#define ippsMD5Init k1_ippsMD5Init +#define ippsMD5Duplicate k1_ippsMD5Duplicate +#define ippsMD5Pack k1_ippsMD5Pack +#define ippsMD5Unpack k1_ippsMD5Unpack +#define ippsMD5Update k1_ippsMD5Update +#define ippsMD5GetTag k1_ippsMD5GetTag +#define ippsMD5Final k1_ippsMD5Final +#define ippsMD5MessageDigest k1_ippsMD5MessageDigest +#define ippsSM3GetSize k1_ippsSM3GetSize +#define ippsSM3Init k1_ippsSM3Init +#define ippsSM3Duplicate k1_ippsSM3Duplicate +#define ippsSM3Pack k1_ippsSM3Pack +#define ippsSM3Unpack k1_ippsSM3Unpack +#define ippsSM3Update k1_ippsSM3Update +#define ippsSM3GetTag k1_ippsSM3GetTag +#define ippsSM3Final k1_ippsSM3Final +#define ippsSM3MessageDigest k1_ippsSM3MessageDigest +#define ippsHashGetSize k1_ippsHashGetSize +#define ippsHashInit k1_ippsHashInit +#define ippsHashPack k1_ippsHashPack +#define ippsHashUnpack k1_ippsHashUnpack +#define ippsHashDuplicate k1_ippsHashDuplicate +#define ippsHashUpdate k1_ippsHashUpdate +#define ippsHashGetTag k1_ippsHashGetTag +#define ippsHashFinal k1_ippsHashFinal +#define ippsHashMessage k1_ippsHashMessage +#define ippsHashMethod_MD5 k1_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 k1_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 k1_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI k1_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT k1_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 k1_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI k1_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT k1_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 k1_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI k1_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT k1_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 k1_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 k1_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 k1_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 k1_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize k1_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 k1_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 k1_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 k1_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 k1_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI k1_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT k1_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 k1_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI k1_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT k1_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 k1_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI k1_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT k1_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 k1_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI k1_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT k1_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 k1_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI k1_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT k1_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 k1_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 k1_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 k1_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 k1_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 k1_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 k1_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 k1_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 k1_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf k1_ippsHashGetSize_rmf +#define ippsHashInit_rmf k1_ippsHashInit_rmf +#define ippsHashPack_rmf k1_ippsHashPack_rmf +#define ippsHashUnpack_rmf k1_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf k1_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf k1_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf k1_ippsHashGetTag_rmf +#define ippsHashFinal_rmf k1_ippsHashFinal_rmf +#define ippsHashMessage_rmf k1_ippsHashMessage_rmf +#define ippsHashMethodGetInfo k1_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf k1_ippsHashGetInfo_rmf +#define ippsMGF k1_ippsMGF +#define ippsMGF1_rmf k1_ippsMGF1_rmf +#define ippsMGF2_rmf k1_ippsMGF2_rmf +#define ippsHMAC_GetSize k1_ippsHMAC_GetSize +#define ippsHMAC_Init k1_ippsHMAC_Init +#define ippsHMAC_Pack k1_ippsHMAC_Pack +#define ippsHMAC_Unpack k1_ippsHMAC_Unpack +#define ippsHMAC_Duplicate k1_ippsHMAC_Duplicate +#define ippsHMAC_Update k1_ippsHMAC_Update +#define ippsHMAC_Final k1_ippsHMAC_Final +#define ippsHMAC_GetTag k1_ippsHMAC_GetTag +#define ippsHMAC_Message k1_ippsHMAC_Message +#define ippsHMACGetSize_rmf k1_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf k1_ippsHMACInit_rmf +#define ippsHMACPack_rmf k1_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf k1_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf k1_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf k1_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf k1_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf k1_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf k1_ippsHMACMessage_rmf +#define ippsBigNumGetSize k1_ippsBigNumGetSize +#define ippsBigNumInit k1_ippsBigNumInit +#define ippsCmpZero_BN k1_ippsCmpZero_BN +#define ippsCmp_BN k1_ippsCmp_BN +#define ippsGetSize_BN k1_ippsGetSize_BN +#define ippsSet_BN k1_ippsSet_BN +#define ippsGet_BN k1_ippsGet_BN +#define ippsRef_BN k1_ippsRef_BN +#define ippsExtGet_BN k1_ippsExtGet_BN +#define ippsAdd_BN k1_ippsAdd_BN +#define ippsSub_BN k1_ippsSub_BN +#define ippsMul_BN k1_ippsMul_BN +#define ippsMAC_BN_I k1_ippsMAC_BN_I +#define ippsDiv_BN k1_ippsDiv_BN +#define ippsMod_BN k1_ippsMod_BN +#define ippsGcd_BN k1_ippsGcd_BN +#define ippsModInv_BN k1_ippsModInv_BN +#define ippsSetOctString_BN k1_ippsSetOctString_BN +#define ippsGetOctString_BN k1_ippsGetOctString_BN +#define ippsMontGetSize k1_ippsMontGetSize +#define ippsMontInit k1_ippsMontInit +#define ippsMontSet k1_ippsMontSet +#define ippsMontGet k1_ippsMontGet +#define ippsMontForm k1_ippsMontForm +#define ippsMontMul k1_ippsMontMul +#define ippsMontExp k1_ippsMontExp +#define ippsPRNGGetSize k1_ippsPRNGGetSize +#define ippsPRNGInit k1_ippsPRNGInit +#define ippsPRNGSetModulus k1_ippsPRNGSetModulus +#define ippsPRNGSetH0 k1_ippsPRNGSetH0 +#define ippsPRNGSetAugment k1_ippsPRNGSetAugment +#define ippsPRNGSetSeed k1_ippsPRNGSetSeed +#define ippsPRNGGetSeed k1_ippsPRNGGetSeed +#define ippsPRNGen k1_ippsPRNGen +#define ippsPRNGen_BN k1_ippsPRNGen_BN +#define ippsPRNGenRDRAND k1_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN k1_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED k1_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN k1_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize k1_ippsPrimeGetSize +#define ippsPrimeInit k1_ippsPrimeInit +#define ippsPrimeGen k1_ippsPrimeGen +#define ippsPrimeTest k1_ippsPrimeTest +#define ippsPrimeGen_BN k1_ippsPrimeGen_BN +#define ippsPrimeTest_BN k1_ippsPrimeTest_BN +#define ippsPrimeGet k1_ippsPrimeGet +#define ippsPrimeGet_BN k1_ippsPrimeGet_BN +#define ippsPrimeSet k1_ippsPrimeSet +#define ippsPrimeSet_BN k1_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey k1_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey k1_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey k1_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey k1_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 k1_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 k1_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 k1_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 k1_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 k1_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 k1_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 k1_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 k1_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey k1_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey k1_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt k1_ippsRSA_Encrypt +#define ippsRSA_Decrypt k1_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys k1_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys k1_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP k1_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP k1_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf k1_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf k1_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 k1_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 k1_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS k1_ippsRSASign_PSS +#define ippsRSAVerify_PSS k1_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf k1_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf k1_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 k1_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 k1_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf k1_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf k1_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString k1_ippsDLGetResultString +#define ippsDLPGetSize k1_ippsDLPGetSize +#define ippsDLPInit k1_ippsDLPInit +#define ippsDLPPack k1_ippsDLPPack +#define ippsDLPUnpack k1_ippsDLPUnpack +#define ippsDLPSet k1_ippsDLPSet +#define ippsDLPGet k1_ippsDLPGet +#define ippsDLPSetDP k1_ippsDLPSetDP +#define ippsDLPGetDP k1_ippsDLPGetDP +#define ippsDLPGenKeyPair k1_ippsDLPGenKeyPair +#define ippsDLPPublicKey k1_ippsDLPPublicKey +#define ippsDLPValidateKeyPair k1_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair k1_ippsDLPSetKeyPair +#define ippsDLPSignDSA k1_ippsDLPSignDSA +#define ippsDLPVerifyDSA k1_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH k1_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA k1_ippsDLPGenerateDSA +#define ippsDLPValidateDSA k1_ippsDLPValidateDSA +#define ippsDLPGenerateDH k1_ippsDLPGenerateDH +#define ippsDLPValidateDH k1_ippsDLPValidateDH +#define ippsECCGetResultString k1_ippsECCGetResultString +#define ippsECCPGetSize k1_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 k1_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 k1_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 k1_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 k1_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 k1_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 k1_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 k1_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 k1_ippsECCPGetSizeStdSM2 +#define ippsECCPInit k1_ippsECCPInit +#define ippsECCPInitStd128r1 k1_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 k1_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 k1_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 k1_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 k1_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 k1_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 k1_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 k1_ippsECCPInitStdSM2 +#define ippsECCPSet k1_ippsECCPSet +#define ippsECCPSetStd k1_ippsECCPSetStd +#define ippsECCPSetStd128r1 k1_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 k1_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 k1_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 k1_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 k1_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 k1_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 k1_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 k1_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 k1_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 k1_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 k1_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 k1_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 k1_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 k1_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet k1_ippsECCPGet +#define ippsECCPGetOrderBitSize k1_ippsECCPGetOrderBitSize +#define ippsECCPValidate k1_ippsECCPValidate +#define ippsECCPPointGetSize k1_ippsECCPPointGetSize +#define ippsECCPPointInit k1_ippsECCPPointInit +#define ippsECCPSetPoint k1_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity k1_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint k1_ippsECCPGetPoint +#define ippsECCPCheckPoint k1_ippsECCPCheckPoint +#define ippsECCPComparePoint k1_ippsECCPComparePoint +#define ippsECCPNegativePoint k1_ippsECCPNegativePoint +#define ippsECCPAddPoint k1_ippsECCPAddPoint +#define ippsECCPMulPointScalar k1_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair k1_ippsECCPGenKeyPair +#define ippsECCPPublicKey k1_ippsECCPPublicKey +#define ippsECCPValidateKeyPair k1_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair k1_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH k1_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC k1_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA k1_ippsECCPSignDSA +#define ippsECCPVerifyDSA k1_ippsECCPVerifyDSA +#define ippsECCPSignNR k1_ippsECCPSignNR +#define ippsECCPVerifyNR k1_ippsECCPVerifyNR +#define ippsECCPSignSM2 k1_ippsECCPSignSM2 +#define ippsECCPVerifySM2 k1_ippsECCPVerifySM2 +#define ippsGFpGetSize k1_ippsGFpGetSize +#define ippsGFpInitArbitrary k1_ippsGFpInitArbitrary +#define ippsGFpInitFixed k1_ippsGFpInitFixed +#define ippsGFpInit k1_ippsGFpInit +#define ippsGFpMethod_p192r1 k1_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 k1_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 k1_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 k1_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 k1_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 k1_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn k1_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 k1_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb k1_ippsGFpMethod_pArb +#define ippsGFpxGetSize k1_ippsGFpxGetSize +#define ippsGFpxInit k1_ippsGFpxInit +#define ippsGFpxInitBinomial k1_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 k1_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 k1_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 k1_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 k1_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom k1_ippsGFpxMethod_binom +#define ippsGFpxMethod_com k1_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize k1_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize k1_ippsGFpElementGetSize +#define ippsGFpElementInit k1_ippsGFpElementInit +#define ippsGFpSetElement k1_ippsGFpSetElement +#define ippsGFpSetElementRegular k1_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString k1_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom k1_ippsGFpSetElementRandom +#define ippsGFpSetElementHash k1_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf k1_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement k1_ippsGFpCpyElement +#define ippsGFpGetElement k1_ippsGFpGetElement +#define ippsGFpGetElementOctString k1_ippsGFpGetElementOctString +#define ippsGFpCmpElement k1_ippsGFpCmpElement +#define ippsGFpIsZeroElement k1_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement k1_ippsGFpIsUnityElement +#define ippsGFpConj k1_ippsGFpConj +#define ippsGFpNeg k1_ippsGFpNeg +#define ippsGFpInv k1_ippsGFpInv +#define ippsGFpSqrt k1_ippsGFpSqrt +#define ippsGFpSqr k1_ippsGFpSqr +#define ippsGFpAdd k1_ippsGFpAdd +#define ippsGFpSub k1_ippsGFpSub +#define ippsGFpMul k1_ippsGFpMul +#define ippsGFpExp k1_ippsGFpExp +#define ippsGFpMultiExp k1_ippsGFpMultiExp +#define ippsGFpAdd_PE k1_ippsGFpAdd_PE +#define ippsGFpSub_PE k1_ippsGFpSub_PE +#define ippsGFpMul_PE k1_ippsGFpMul_PE +#define ippsGFpGetInfo k1_ippsGFpGetInfo +#define ippsGFpECGetSize k1_ippsGFpECGetSize +#define ippsGFpECInit k1_ippsGFpECInit +#define ippsGFpECSet k1_ippsGFpECSet +#define ippsGFpECSetSubgroup k1_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 k1_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 k1_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 k1_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 k1_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 k1_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 k1_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 k1_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 k1_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 k1_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 k1_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 k1_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 k1_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 k1_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 k1_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 k1_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet k1_ippsGFpECGet +#define ippsGFpECGetSubgroup k1_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize k1_ippsGFpECScratchBufferSize +#define ippsGFpECVerify k1_ippsGFpECVerify +#define ippsGFpECPointGetSize k1_ippsGFpECPointGetSize +#define ippsGFpECPointInit k1_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity k1_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint k1_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular k1_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom k1_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint k1_ippsGFpECMakePoint +#define ippsGFpECSetPointHash k1_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible k1_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf k1_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf k1_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint k1_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular k1_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString k1_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString k1_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint k1_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup k1_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint k1_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint k1_ippsGFpECCmpPoint +#define ippsGFpECNegPoint k1_ippsGFpECNegPoint +#define ippsGFpECAddPoint k1_ippsGFpECAddPoint +#define ippsGFpECMulPoint k1_ippsGFpECMulPoint +#define ippsGFpECPrivateKey k1_ippsGFpECPrivateKey +#define ippsGFpECPublicKey k1_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair k1_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH k1_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC k1_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 k1_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA k1_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA k1_ippsGFpECVerifyDSA +#define ippsGFpECSignNR k1_ippsGFpECSignNR +#define ippsGFpECVerifyNR k1_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 k1_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 k1_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 k1_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize k1_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init k1_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup k1_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey k1_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm k1_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF k1_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 k1_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 k1_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 k1_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 k1_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 k1_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 k1_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 k1_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 k1_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize k1_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext k1_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize k1_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext k1_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_l9.h b/plugin/ippcp/library/include/single_cpu/ippcp_l9.h new file mode 100644 index 000000000..76c5d16b2 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_l9.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion l9_ippcpGetLibVersion +#define ippsDESGetSize l9_ippsDESGetSize +#define ippsDESInit l9_ippsDESInit +#define ippsDESPack l9_ippsDESPack +#define ippsDESUnpack l9_ippsDESUnpack +#define ippsTDESEncryptECB l9_ippsTDESEncryptECB +#define ippsTDESDecryptECB l9_ippsTDESDecryptECB +#define ippsTDESEncryptCBC l9_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC l9_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB l9_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB l9_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB l9_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB l9_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR l9_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR l9_ippsTDESDecryptCTR +#define ippsAESGetSize l9_ippsAESGetSize +#define ippsAESInit l9_ippsAESInit +#define ippsAESSetKey l9_ippsAESSetKey +#define ippsAESPack l9_ippsAESPack +#define ippsAESUnpack l9_ippsAESUnpack +#define ippsAESEncryptECB l9_ippsAESEncryptECB +#define ippsAESDecryptECB l9_ippsAESDecryptECB +#define ippsAESEncryptCBC l9_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 l9_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 l9_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 l9_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC l9_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 l9_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 l9_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 l9_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB l9_ippsAESEncryptCFB +#define ippsAESDecryptCFB l9_ippsAESDecryptCFB +#define ippsAESEncryptOFB l9_ippsAESEncryptOFB +#define ippsAESDecryptOFB l9_ippsAESDecryptOFB +#define ippsAESEncryptCTR l9_ippsAESEncryptCTR +#define ippsAESDecryptCTR l9_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct l9_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct l9_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise l9_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise l9_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise l9_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB l9_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize l9_ippsSMS4GetSize +#define ippsSMS4Init l9_ippsSMS4Init +#define ippsSMS4SetKey l9_ippsSMS4SetKey +#define ippsSMS4EncryptECB l9_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB l9_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC l9_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 l9_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 l9_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 l9_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC l9_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 l9_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 l9_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 l9_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB l9_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB l9_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB l9_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB l9_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR l9_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR l9_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize l9_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit l9_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen l9_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen l9_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart l9_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt l9_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt l9_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag l9_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize l9_ippsAES_CCMGetSize +#define ippsAES_CCMInit l9_ippsAES_CCMInit +#define ippsAES_CCMMessageLen l9_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen l9_ippsAES_CCMTagLen +#define ippsAES_CCMStart l9_ippsAES_CCMStart +#define ippsAES_CCMEncrypt l9_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt l9_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag l9_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize l9_ippsAES_GCMGetSize +#define ippsAES_GCMInit l9_ippsAES_GCMInit +#define ippsAES_GCMReinit l9_ippsAES_GCMReinit +#define ippsAES_GCMReset l9_ippsAES_GCMReset +#define ippsAES_GCMProcessIV l9_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD l9_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart l9_ippsAES_GCMStart +#define ippsAES_GCMEncrypt l9_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt l9_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag l9_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize l9_ippsAES_XTSGetSize +#define ippsAES_XTSInit l9_ippsAES_XTSInit +#define ippsAES_XTSEncrypt l9_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt l9_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC l9_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt l9_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt l9_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize l9_ippsAES_CMACGetSize +#define ippsAES_CMACInit l9_ippsAES_CMACInit +#define ippsAES_CMACUpdate l9_ippsAES_CMACUpdate +#define ippsAES_CMACFinal l9_ippsAES_CMACFinal +#define ippsAES_CMACGetTag l9_ippsAES_CMACGetTag +#define ippsARCFourCheckKey l9_ippsARCFourCheckKey +#define ippsARCFourGetSize l9_ippsARCFourGetSize +#define ippsARCFourInit l9_ippsARCFourInit +#define ippsARCFourReset l9_ippsARCFourReset +#define ippsARCFourPack l9_ippsARCFourPack +#define ippsARCFourUnpack l9_ippsARCFourUnpack +#define ippsARCFourEncrypt l9_ippsARCFourEncrypt +#define ippsARCFourDecrypt l9_ippsARCFourDecrypt +#define ippsSHA1GetSize l9_ippsSHA1GetSize +#define ippsSHA1Init l9_ippsSHA1Init +#define ippsSHA1Duplicate l9_ippsSHA1Duplicate +#define ippsSHA1Pack l9_ippsSHA1Pack +#define ippsSHA1Unpack l9_ippsSHA1Unpack +#define ippsSHA1Update l9_ippsSHA1Update +#define ippsSHA1GetTag l9_ippsSHA1GetTag +#define ippsSHA1Final l9_ippsSHA1Final +#define ippsSHA1MessageDigest l9_ippsSHA1MessageDigest +#define ippsSHA224GetSize l9_ippsSHA224GetSize +#define ippsSHA224Init l9_ippsSHA224Init +#define ippsSHA224Duplicate l9_ippsSHA224Duplicate +#define ippsSHA224Pack l9_ippsSHA224Pack +#define ippsSHA224Unpack l9_ippsSHA224Unpack +#define ippsSHA224Update l9_ippsSHA224Update +#define ippsSHA224GetTag l9_ippsSHA224GetTag +#define ippsSHA224Final l9_ippsSHA224Final +#define ippsSHA224MessageDigest l9_ippsSHA224MessageDigest +#define ippsSHA256GetSize l9_ippsSHA256GetSize +#define ippsSHA256Init l9_ippsSHA256Init +#define ippsSHA256Duplicate l9_ippsSHA256Duplicate +#define ippsSHA256Pack l9_ippsSHA256Pack +#define ippsSHA256Unpack l9_ippsSHA256Unpack +#define ippsSHA256Update l9_ippsSHA256Update +#define ippsSHA256GetTag l9_ippsSHA256GetTag +#define ippsSHA256Final l9_ippsSHA256Final +#define ippsSHA256MessageDigest l9_ippsSHA256MessageDigest +#define ippsSHA384GetSize l9_ippsSHA384GetSize +#define ippsSHA384Init l9_ippsSHA384Init +#define ippsSHA384Duplicate l9_ippsSHA384Duplicate +#define ippsSHA384Pack l9_ippsSHA384Pack +#define ippsSHA384Unpack l9_ippsSHA384Unpack +#define ippsSHA384Update l9_ippsSHA384Update +#define ippsSHA384GetTag l9_ippsSHA384GetTag +#define ippsSHA384Final l9_ippsSHA384Final +#define ippsSHA384MessageDigest l9_ippsSHA384MessageDigest +#define ippsSHA512GetSize l9_ippsSHA512GetSize +#define ippsSHA512Init l9_ippsSHA512Init +#define ippsSHA512Duplicate l9_ippsSHA512Duplicate +#define ippsSHA512Pack l9_ippsSHA512Pack +#define ippsSHA512Unpack l9_ippsSHA512Unpack +#define ippsSHA512Update l9_ippsSHA512Update +#define ippsSHA512GetTag l9_ippsSHA512GetTag +#define ippsSHA512Final l9_ippsSHA512Final +#define ippsSHA512MessageDigest l9_ippsSHA512MessageDigest +#define ippsMD5GetSize l9_ippsMD5GetSize +#define ippsMD5Init l9_ippsMD5Init +#define ippsMD5Duplicate l9_ippsMD5Duplicate +#define ippsMD5Pack l9_ippsMD5Pack +#define ippsMD5Unpack l9_ippsMD5Unpack +#define ippsMD5Update l9_ippsMD5Update +#define ippsMD5GetTag l9_ippsMD5GetTag +#define ippsMD5Final l9_ippsMD5Final +#define ippsMD5MessageDigest l9_ippsMD5MessageDigest +#define ippsSM3GetSize l9_ippsSM3GetSize +#define ippsSM3Init l9_ippsSM3Init +#define ippsSM3Duplicate l9_ippsSM3Duplicate +#define ippsSM3Pack l9_ippsSM3Pack +#define ippsSM3Unpack l9_ippsSM3Unpack +#define ippsSM3Update l9_ippsSM3Update +#define ippsSM3GetTag l9_ippsSM3GetTag +#define ippsSM3Final l9_ippsSM3Final +#define ippsSM3MessageDigest l9_ippsSM3MessageDigest +#define ippsHashGetSize l9_ippsHashGetSize +#define ippsHashInit l9_ippsHashInit +#define ippsHashPack l9_ippsHashPack +#define ippsHashUnpack l9_ippsHashUnpack +#define ippsHashDuplicate l9_ippsHashDuplicate +#define ippsHashUpdate l9_ippsHashUpdate +#define ippsHashGetTag l9_ippsHashGetTag +#define ippsHashFinal l9_ippsHashFinal +#define ippsHashMessage l9_ippsHashMessage +#define ippsHashMethod_MD5 l9_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 l9_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 l9_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI l9_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT l9_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 l9_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI l9_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT l9_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 l9_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI l9_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT l9_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 l9_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 l9_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 l9_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 l9_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize l9_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 l9_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 l9_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 l9_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 l9_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI l9_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT l9_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 l9_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI l9_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT l9_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 l9_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI l9_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT l9_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 l9_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI l9_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT l9_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 l9_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI l9_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT l9_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 l9_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 l9_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 l9_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 l9_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 l9_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 l9_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 l9_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 l9_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf l9_ippsHashGetSize_rmf +#define ippsHashInit_rmf l9_ippsHashInit_rmf +#define ippsHashPack_rmf l9_ippsHashPack_rmf +#define ippsHashUnpack_rmf l9_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf l9_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf l9_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf l9_ippsHashGetTag_rmf +#define ippsHashFinal_rmf l9_ippsHashFinal_rmf +#define ippsHashMessage_rmf l9_ippsHashMessage_rmf +#define ippsHashMethodGetInfo l9_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf l9_ippsHashGetInfo_rmf +#define ippsMGF l9_ippsMGF +#define ippsMGF1_rmf l9_ippsMGF1_rmf +#define ippsMGF2_rmf l9_ippsMGF2_rmf +#define ippsHMAC_GetSize l9_ippsHMAC_GetSize +#define ippsHMAC_Init l9_ippsHMAC_Init +#define ippsHMAC_Pack l9_ippsHMAC_Pack +#define ippsHMAC_Unpack l9_ippsHMAC_Unpack +#define ippsHMAC_Duplicate l9_ippsHMAC_Duplicate +#define ippsHMAC_Update l9_ippsHMAC_Update +#define ippsHMAC_Final l9_ippsHMAC_Final +#define ippsHMAC_GetTag l9_ippsHMAC_GetTag +#define ippsHMAC_Message l9_ippsHMAC_Message +#define ippsHMACGetSize_rmf l9_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf l9_ippsHMACInit_rmf +#define ippsHMACPack_rmf l9_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf l9_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf l9_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf l9_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf l9_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf l9_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf l9_ippsHMACMessage_rmf +#define ippsBigNumGetSize l9_ippsBigNumGetSize +#define ippsBigNumInit l9_ippsBigNumInit +#define ippsCmpZero_BN l9_ippsCmpZero_BN +#define ippsCmp_BN l9_ippsCmp_BN +#define ippsGetSize_BN l9_ippsGetSize_BN +#define ippsSet_BN l9_ippsSet_BN +#define ippsGet_BN l9_ippsGet_BN +#define ippsRef_BN l9_ippsRef_BN +#define ippsExtGet_BN l9_ippsExtGet_BN +#define ippsAdd_BN l9_ippsAdd_BN +#define ippsSub_BN l9_ippsSub_BN +#define ippsMul_BN l9_ippsMul_BN +#define ippsMAC_BN_I l9_ippsMAC_BN_I +#define ippsDiv_BN l9_ippsDiv_BN +#define ippsMod_BN l9_ippsMod_BN +#define ippsGcd_BN l9_ippsGcd_BN +#define ippsModInv_BN l9_ippsModInv_BN +#define ippsSetOctString_BN l9_ippsSetOctString_BN +#define ippsGetOctString_BN l9_ippsGetOctString_BN +#define ippsMontGetSize l9_ippsMontGetSize +#define ippsMontInit l9_ippsMontInit +#define ippsMontSet l9_ippsMontSet +#define ippsMontGet l9_ippsMontGet +#define ippsMontForm l9_ippsMontForm +#define ippsMontMul l9_ippsMontMul +#define ippsMontExp l9_ippsMontExp +#define ippsPRNGGetSize l9_ippsPRNGGetSize +#define ippsPRNGInit l9_ippsPRNGInit +#define ippsPRNGSetModulus l9_ippsPRNGSetModulus +#define ippsPRNGSetH0 l9_ippsPRNGSetH0 +#define ippsPRNGSetAugment l9_ippsPRNGSetAugment +#define ippsPRNGSetSeed l9_ippsPRNGSetSeed +#define ippsPRNGGetSeed l9_ippsPRNGGetSeed +#define ippsPRNGen l9_ippsPRNGen +#define ippsPRNGen_BN l9_ippsPRNGen_BN +#define ippsPRNGenRDRAND l9_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN l9_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED l9_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN l9_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize l9_ippsPrimeGetSize +#define ippsPrimeInit l9_ippsPrimeInit +#define ippsPrimeGen l9_ippsPrimeGen +#define ippsPrimeTest l9_ippsPrimeTest +#define ippsPrimeGen_BN l9_ippsPrimeGen_BN +#define ippsPrimeTest_BN l9_ippsPrimeTest_BN +#define ippsPrimeGet l9_ippsPrimeGet +#define ippsPrimeGet_BN l9_ippsPrimeGet_BN +#define ippsPrimeSet l9_ippsPrimeSet +#define ippsPrimeSet_BN l9_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey l9_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey l9_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey l9_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey l9_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 l9_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 l9_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 l9_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 l9_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 l9_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 l9_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 l9_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 l9_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey l9_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey l9_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt l9_ippsRSA_Encrypt +#define ippsRSA_Decrypt l9_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys l9_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys l9_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP l9_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP l9_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf l9_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf l9_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 l9_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 l9_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS l9_ippsRSASign_PSS +#define ippsRSAVerify_PSS l9_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf l9_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf l9_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 l9_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 l9_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf l9_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf l9_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString l9_ippsDLGetResultString +#define ippsDLPGetSize l9_ippsDLPGetSize +#define ippsDLPInit l9_ippsDLPInit +#define ippsDLPPack l9_ippsDLPPack +#define ippsDLPUnpack l9_ippsDLPUnpack +#define ippsDLPSet l9_ippsDLPSet +#define ippsDLPGet l9_ippsDLPGet +#define ippsDLPSetDP l9_ippsDLPSetDP +#define ippsDLPGetDP l9_ippsDLPGetDP +#define ippsDLPGenKeyPair l9_ippsDLPGenKeyPair +#define ippsDLPPublicKey l9_ippsDLPPublicKey +#define ippsDLPValidateKeyPair l9_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair l9_ippsDLPSetKeyPair +#define ippsDLPSignDSA l9_ippsDLPSignDSA +#define ippsDLPVerifyDSA l9_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH l9_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA l9_ippsDLPGenerateDSA +#define ippsDLPValidateDSA l9_ippsDLPValidateDSA +#define ippsDLPGenerateDH l9_ippsDLPGenerateDH +#define ippsDLPValidateDH l9_ippsDLPValidateDH +#define ippsECCGetResultString l9_ippsECCGetResultString +#define ippsECCPGetSize l9_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 l9_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 l9_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 l9_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 l9_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 l9_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 l9_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 l9_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 l9_ippsECCPGetSizeStdSM2 +#define ippsECCPInit l9_ippsECCPInit +#define ippsECCPInitStd128r1 l9_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 l9_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 l9_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 l9_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 l9_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 l9_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 l9_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 l9_ippsECCPInitStdSM2 +#define ippsECCPSet l9_ippsECCPSet +#define ippsECCPSetStd l9_ippsECCPSetStd +#define ippsECCPSetStd128r1 l9_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 l9_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 l9_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 l9_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 l9_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 l9_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 l9_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 l9_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 l9_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 l9_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 l9_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 l9_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 l9_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 l9_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet l9_ippsECCPGet +#define ippsECCPGetOrderBitSize l9_ippsECCPGetOrderBitSize +#define ippsECCPValidate l9_ippsECCPValidate +#define ippsECCPPointGetSize l9_ippsECCPPointGetSize +#define ippsECCPPointInit l9_ippsECCPPointInit +#define ippsECCPSetPoint l9_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity l9_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint l9_ippsECCPGetPoint +#define ippsECCPCheckPoint l9_ippsECCPCheckPoint +#define ippsECCPComparePoint l9_ippsECCPComparePoint +#define ippsECCPNegativePoint l9_ippsECCPNegativePoint +#define ippsECCPAddPoint l9_ippsECCPAddPoint +#define ippsECCPMulPointScalar l9_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair l9_ippsECCPGenKeyPair +#define ippsECCPPublicKey l9_ippsECCPPublicKey +#define ippsECCPValidateKeyPair l9_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair l9_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH l9_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC l9_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA l9_ippsECCPSignDSA +#define ippsECCPVerifyDSA l9_ippsECCPVerifyDSA +#define ippsECCPSignNR l9_ippsECCPSignNR +#define ippsECCPVerifyNR l9_ippsECCPVerifyNR +#define ippsECCPSignSM2 l9_ippsECCPSignSM2 +#define ippsECCPVerifySM2 l9_ippsECCPVerifySM2 +#define ippsGFpGetSize l9_ippsGFpGetSize +#define ippsGFpInitArbitrary l9_ippsGFpInitArbitrary +#define ippsGFpInitFixed l9_ippsGFpInitFixed +#define ippsGFpInit l9_ippsGFpInit +#define ippsGFpMethod_p192r1 l9_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 l9_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 l9_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 l9_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 l9_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 l9_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn l9_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 l9_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb l9_ippsGFpMethod_pArb +#define ippsGFpxGetSize l9_ippsGFpxGetSize +#define ippsGFpxInit l9_ippsGFpxInit +#define ippsGFpxInitBinomial l9_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 l9_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 l9_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 l9_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 l9_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom l9_ippsGFpxMethod_binom +#define ippsGFpxMethod_com l9_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize l9_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize l9_ippsGFpElementGetSize +#define ippsGFpElementInit l9_ippsGFpElementInit +#define ippsGFpSetElement l9_ippsGFpSetElement +#define ippsGFpSetElementRegular l9_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString l9_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom l9_ippsGFpSetElementRandom +#define ippsGFpSetElementHash l9_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf l9_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement l9_ippsGFpCpyElement +#define ippsGFpGetElement l9_ippsGFpGetElement +#define ippsGFpGetElementOctString l9_ippsGFpGetElementOctString +#define ippsGFpCmpElement l9_ippsGFpCmpElement +#define ippsGFpIsZeroElement l9_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement l9_ippsGFpIsUnityElement +#define ippsGFpConj l9_ippsGFpConj +#define ippsGFpNeg l9_ippsGFpNeg +#define ippsGFpInv l9_ippsGFpInv +#define ippsGFpSqrt l9_ippsGFpSqrt +#define ippsGFpSqr l9_ippsGFpSqr +#define ippsGFpAdd l9_ippsGFpAdd +#define ippsGFpSub l9_ippsGFpSub +#define ippsGFpMul l9_ippsGFpMul +#define ippsGFpExp l9_ippsGFpExp +#define ippsGFpMultiExp l9_ippsGFpMultiExp +#define ippsGFpAdd_PE l9_ippsGFpAdd_PE +#define ippsGFpSub_PE l9_ippsGFpSub_PE +#define ippsGFpMul_PE l9_ippsGFpMul_PE +#define ippsGFpGetInfo l9_ippsGFpGetInfo +#define ippsGFpECGetSize l9_ippsGFpECGetSize +#define ippsGFpECInit l9_ippsGFpECInit +#define ippsGFpECSet l9_ippsGFpECSet +#define ippsGFpECSetSubgroup l9_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 l9_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 l9_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 l9_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 l9_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 l9_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 l9_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 l9_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 l9_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 l9_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 l9_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 l9_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 l9_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 l9_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 l9_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 l9_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet l9_ippsGFpECGet +#define ippsGFpECGetSubgroup l9_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize l9_ippsGFpECScratchBufferSize +#define ippsGFpECVerify l9_ippsGFpECVerify +#define ippsGFpECPointGetSize l9_ippsGFpECPointGetSize +#define ippsGFpECPointInit l9_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity l9_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint l9_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular l9_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom l9_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint l9_ippsGFpECMakePoint +#define ippsGFpECSetPointHash l9_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible l9_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf l9_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf l9_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint l9_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular l9_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString l9_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString l9_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint l9_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup l9_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint l9_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint l9_ippsGFpECCmpPoint +#define ippsGFpECNegPoint l9_ippsGFpECNegPoint +#define ippsGFpECAddPoint l9_ippsGFpECAddPoint +#define ippsGFpECMulPoint l9_ippsGFpECMulPoint +#define ippsGFpECPrivateKey l9_ippsGFpECPrivateKey +#define ippsGFpECPublicKey l9_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair l9_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH l9_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC l9_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 l9_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA l9_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA l9_ippsGFpECVerifyDSA +#define ippsGFpECSignNR l9_ippsGFpECSignNR +#define ippsGFpECVerifyNR l9_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 l9_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 l9_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 l9_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize l9_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init l9_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup l9_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey l9_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm l9_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF l9_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 l9_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 l9_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 l9_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 l9_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 l9_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 l9_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 l9_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 l9_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize l9_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext l9_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize l9_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext l9_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_m7.h b/plugin/ippcp/library/include/single_cpu/ippcp_m7.h new file mode 100644 index 000000000..f9365f82c --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_m7.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion m7_ippcpGetLibVersion +#define ippsDESGetSize m7_ippsDESGetSize +#define ippsDESInit m7_ippsDESInit +#define ippsDESPack m7_ippsDESPack +#define ippsDESUnpack m7_ippsDESUnpack +#define ippsTDESEncryptECB m7_ippsTDESEncryptECB +#define ippsTDESDecryptECB m7_ippsTDESDecryptECB +#define ippsTDESEncryptCBC m7_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC m7_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB m7_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB m7_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB m7_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB m7_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR m7_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR m7_ippsTDESDecryptCTR +#define ippsAESGetSize m7_ippsAESGetSize +#define ippsAESInit m7_ippsAESInit +#define ippsAESSetKey m7_ippsAESSetKey +#define ippsAESPack m7_ippsAESPack +#define ippsAESUnpack m7_ippsAESUnpack +#define ippsAESEncryptECB m7_ippsAESEncryptECB +#define ippsAESDecryptECB m7_ippsAESDecryptECB +#define ippsAESEncryptCBC m7_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 m7_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 m7_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 m7_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC m7_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 m7_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 m7_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 m7_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB m7_ippsAESEncryptCFB +#define ippsAESDecryptCFB m7_ippsAESDecryptCFB +#define ippsAESEncryptOFB m7_ippsAESEncryptOFB +#define ippsAESDecryptOFB m7_ippsAESDecryptOFB +#define ippsAESEncryptCTR m7_ippsAESEncryptCTR +#define ippsAESDecryptCTR m7_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct m7_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct m7_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise m7_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise m7_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise m7_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB m7_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize m7_ippsSMS4GetSize +#define ippsSMS4Init m7_ippsSMS4Init +#define ippsSMS4SetKey m7_ippsSMS4SetKey +#define ippsSMS4EncryptECB m7_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB m7_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC m7_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 m7_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 m7_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 m7_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC m7_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 m7_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 m7_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 m7_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB m7_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB m7_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB m7_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB m7_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR m7_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR m7_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize m7_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit m7_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen m7_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen m7_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart m7_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt m7_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt m7_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag m7_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize m7_ippsAES_CCMGetSize +#define ippsAES_CCMInit m7_ippsAES_CCMInit +#define ippsAES_CCMMessageLen m7_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen m7_ippsAES_CCMTagLen +#define ippsAES_CCMStart m7_ippsAES_CCMStart +#define ippsAES_CCMEncrypt m7_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt m7_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag m7_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize m7_ippsAES_GCMGetSize +#define ippsAES_GCMInit m7_ippsAES_GCMInit +#define ippsAES_GCMReinit m7_ippsAES_GCMReinit +#define ippsAES_GCMReset m7_ippsAES_GCMReset +#define ippsAES_GCMProcessIV m7_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD m7_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart m7_ippsAES_GCMStart +#define ippsAES_GCMEncrypt m7_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt m7_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag m7_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize m7_ippsAES_XTSGetSize +#define ippsAES_XTSInit m7_ippsAES_XTSInit +#define ippsAES_XTSEncrypt m7_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt m7_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC m7_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt m7_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt m7_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize m7_ippsAES_CMACGetSize +#define ippsAES_CMACInit m7_ippsAES_CMACInit +#define ippsAES_CMACUpdate m7_ippsAES_CMACUpdate +#define ippsAES_CMACFinal m7_ippsAES_CMACFinal +#define ippsAES_CMACGetTag m7_ippsAES_CMACGetTag +#define ippsARCFourCheckKey m7_ippsARCFourCheckKey +#define ippsARCFourGetSize m7_ippsARCFourGetSize +#define ippsARCFourInit m7_ippsARCFourInit +#define ippsARCFourReset m7_ippsARCFourReset +#define ippsARCFourPack m7_ippsARCFourPack +#define ippsARCFourUnpack m7_ippsARCFourUnpack +#define ippsARCFourEncrypt m7_ippsARCFourEncrypt +#define ippsARCFourDecrypt m7_ippsARCFourDecrypt +#define ippsSHA1GetSize m7_ippsSHA1GetSize +#define ippsSHA1Init m7_ippsSHA1Init +#define ippsSHA1Duplicate m7_ippsSHA1Duplicate +#define ippsSHA1Pack m7_ippsSHA1Pack +#define ippsSHA1Unpack m7_ippsSHA1Unpack +#define ippsSHA1Update m7_ippsSHA1Update +#define ippsSHA1GetTag m7_ippsSHA1GetTag +#define ippsSHA1Final m7_ippsSHA1Final +#define ippsSHA1MessageDigest m7_ippsSHA1MessageDigest +#define ippsSHA224GetSize m7_ippsSHA224GetSize +#define ippsSHA224Init m7_ippsSHA224Init +#define ippsSHA224Duplicate m7_ippsSHA224Duplicate +#define ippsSHA224Pack m7_ippsSHA224Pack +#define ippsSHA224Unpack m7_ippsSHA224Unpack +#define ippsSHA224Update m7_ippsSHA224Update +#define ippsSHA224GetTag m7_ippsSHA224GetTag +#define ippsSHA224Final m7_ippsSHA224Final +#define ippsSHA224MessageDigest m7_ippsSHA224MessageDigest +#define ippsSHA256GetSize m7_ippsSHA256GetSize +#define ippsSHA256Init m7_ippsSHA256Init +#define ippsSHA256Duplicate m7_ippsSHA256Duplicate +#define ippsSHA256Pack m7_ippsSHA256Pack +#define ippsSHA256Unpack m7_ippsSHA256Unpack +#define ippsSHA256Update m7_ippsSHA256Update +#define ippsSHA256GetTag m7_ippsSHA256GetTag +#define ippsSHA256Final m7_ippsSHA256Final +#define ippsSHA256MessageDigest m7_ippsSHA256MessageDigest +#define ippsSHA384GetSize m7_ippsSHA384GetSize +#define ippsSHA384Init m7_ippsSHA384Init +#define ippsSHA384Duplicate m7_ippsSHA384Duplicate +#define ippsSHA384Pack m7_ippsSHA384Pack +#define ippsSHA384Unpack m7_ippsSHA384Unpack +#define ippsSHA384Update m7_ippsSHA384Update +#define ippsSHA384GetTag m7_ippsSHA384GetTag +#define ippsSHA384Final m7_ippsSHA384Final +#define ippsSHA384MessageDigest m7_ippsSHA384MessageDigest +#define ippsSHA512GetSize m7_ippsSHA512GetSize +#define ippsSHA512Init m7_ippsSHA512Init +#define ippsSHA512Duplicate m7_ippsSHA512Duplicate +#define ippsSHA512Pack m7_ippsSHA512Pack +#define ippsSHA512Unpack m7_ippsSHA512Unpack +#define ippsSHA512Update m7_ippsSHA512Update +#define ippsSHA512GetTag m7_ippsSHA512GetTag +#define ippsSHA512Final m7_ippsSHA512Final +#define ippsSHA512MessageDigest m7_ippsSHA512MessageDigest +#define ippsMD5GetSize m7_ippsMD5GetSize +#define ippsMD5Init m7_ippsMD5Init +#define ippsMD5Duplicate m7_ippsMD5Duplicate +#define ippsMD5Pack m7_ippsMD5Pack +#define ippsMD5Unpack m7_ippsMD5Unpack +#define ippsMD5Update m7_ippsMD5Update +#define ippsMD5GetTag m7_ippsMD5GetTag +#define ippsMD5Final m7_ippsMD5Final +#define ippsMD5MessageDigest m7_ippsMD5MessageDigest +#define ippsSM3GetSize m7_ippsSM3GetSize +#define ippsSM3Init m7_ippsSM3Init +#define ippsSM3Duplicate m7_ippsSM3Duplicate +#define ippsSM3Pack m7_ippsSM3Pack +#define ippsSM3Unpack m7_ippsSM3Unpack +#define ippsSM3Update m7_ippsSM3Update +#define ippsSM3GetTag m7_ippsSM3GetTag +#define ippsSM3Final m7_ippsSM3Final +#define ippsSM3MessageDigest m7_ippsSM3MessageDigest +#define ippsHashGetSize m7_ippsHashGetSize +#define ippsHashInit m7_ippsHashInit +#define ippsHashPack m7_ippsHashPack +#define ippsHashUnpack m7_ippsHashUnpack +#define ippsHashDuplicate m7_ippsHashDuplicate +#define ippsHashUpdate m7_ippsHashUpdate +#define ippsHashGetTag m7_ippsHashGetTag +#define ippsHashFinal m7_ippsHashFinal +#define ippsHashMessage m7_ippsHashMessage +#define ippsHashMethod_MD5 m7_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 m7_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 m7_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI m7_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT m7_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 m7_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI m7_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT m7_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 m7_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI m7_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT m7_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 m7_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 m7_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 m7_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 m7_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize m7_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 m7_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 m7_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 m7_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 m7_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI m7_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT m7_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 m7_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI m7_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT m7_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 m7_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI m7_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT m7_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 m7_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI m7_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT m7_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 m7_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI m7_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT m7_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 m7_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 m7_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 m7_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 m7_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 m7_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 m7_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 m7_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 m7_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf m7_ippsHashGetSize_rmf +#define ippsHashInit_rmf m7_ippsHashInit_rmf +#define ippsHashPack_rmf m7_ippsHashPack_rmf +#define ippsHashUnpack_rmf m7_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf m7_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf m7_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf m7_ippsHashGetTag_rmf +#define ippsHashFinal_rmf m7_ippsHashFinal_rmf +#define ippsHashMessage_rmf m7_ippsHashMessage_rmf +#define ippsHashMethodGetInfo m7_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf m7_ippsHashGetInfo_rmf +#define ippsMGF m7_ippsMGF +#define ippsMGF1_rmf m7_ippsMGF1_rmf +#define ippsMGF2_rmf m7_ippsMGF2_rmf +#define ippsHMAC_GetSize m7_ippsHMAC_GetSize +#define ippsHMAC_Init m7_ippsHMAC_Init +#define ippsHMAC_Pack m7_ippsHMAC_Pack +#define ippsHMAC_Unpack m7_ippsHMAC_Unpack +#define ippsHMAC_Duplicate m7_ippsHMAC_Duplicate +#define ippsHMAC_Update m7_ippsHMAC_Update +#define ippsHMAC_Final m7_ippsHMAC_Final +#define ippsHMAC_GetTag m7_ippsHMAC_GetTag +#define ippsHMAC_Message m7_ippsHMAC_Message +#define ippsHMACGetSize_rmf m7_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf m7_ippsHMACInit_rmf +#define ippsHMACPack_rmf m7_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf m7_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf m7_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf m7_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf m7_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf m7_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf m7_ippsHMACMessage_rmf +#define ippsBigNumGetSize m7_ippsBigNumGetSize +#define ippsBigNumInit m7_ippsBigNumInit +#define ippsCmpZero_BN m7_ippsCmpZero_BN +#define ippsCmp_BN m7_ippsCmp_BN +#define ippsGetSize_BN m7_ippsGetSize_BN +#define ippsSet_BN m7_ippsSet_BN +#define ippsGet_BN m7_ippsGet_BN +#define ippsRef_BN m7_ippsRef_BN +#define ippsExtGet_BN m7_ippsExtGet_BN +#define ippsAdd_BN m7_ippsAdd_BN +#define ippsSub_BN m7_ippsSub_BN +#define ippsMul_BN m7_ippsMul_BN +#define ippsMAC_BN_I m7_ippsMAC_BN_I +#define ippsDiv_BN m7_ippsDiv_BN +#define ippsMod_BN m7_ippsMod_BN +#define ippsGcd_BN m7_ippsGcd_BN +#define ippsModInv_BN m7_ippsModInv_BN +#define ippsSetOctString_BN m7_ippsSetOctString_BN +#define ippsGetOctString_BN m7_ippsGetOctString_BN +#define ippsMontGetSize m7_ippsMontGetSize +#define ippsMontInit m7_ippsMontInit +#define ippsMontSet m7_ippsMontSet +#define ippsMontGet m7_ippsMontGet +#define ippsMontForm m7_ippsMontForm +#define ippsMontMul m7_ippsMontMul +#define ippsMontExp m7_ippsMontExp +#define ippsPRNGGetSize m7_ippsPRNGGetSize +#define ippsPRNGInit m7_ippsPRNGInit +#define ippsPRNGSetModulus m7_ippsPRNGSetModulus +#define ippsPRNGSetH0 m7_ippsPRNGSetH0 +#define ippsPRNGSetAugment m7_ippsPRNGSetAugment +#define ippsPRNGSetSeed m7_ippsPRNGSetSeed +#define ippsPRNGGetSeed m7_ippsPRNGGetSeed +#define ippsPRNGen m7_ippsPRNGen +#define ippsPRNGen_BN m7_ippsPRNGen_BN +#define ippsPRNGenRDRAND m7_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN m7_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED m7_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN m7_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize m7_ippsPrimeGetSize +#define ippsPrimeInit m7_ippsPrimeInit +#define ippsPrimeGen m7_ippsPrimeGen +#define ippsPrimeTest m7_ippsPrimeTest +#define ippsPrimeGen_BN m7_ippsPrimeGen_BN +#define ippsPrimeTest_BN m7_ippsPrimeTest_BN +#define ippsPrimeGet m7_ippsPrimeGet +#define ippsPrimeGet_BN m7_ippsPrimeGet_BN +#define ippsPrimeSet m7_ippsPrimeSet +#define ippsPrimeSet_BN m7_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey m7_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey m7_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey m7_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey m7_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 m7_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 m7_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 m7_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 m7_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 m7_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 m7_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 m7_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 m7_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey m7_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey m7_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt m7_ippsRSA_Encrypt +#define ippsRSA_Decrypt m7_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys m7_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys m7_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP m7_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP m7_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf m7_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf m7_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 m7_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 m7_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS m7_ippsRSASign_PSS +#define ippsRSAVerify_PSS m7_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf m7_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf m7_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 m7_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 m7_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf m7_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf m7_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString m7_ippsDLGetResultString +#define ippsDLPGetSize m7_ippsDLPGetSize +#define ippsDLPInit m7_ippsDLPInit +#define ippsDLPPack m7_ippsDLPPack +#define ippsDLPUnpack m7_ippsDLPUnpack +#define ippsDLPSet m7_ippsDLPSet +#define ippsDLPGet m7_ippsDLPGet +#define ippsDLPSetDP m7_ippsDLPSetDP +#define ippsDLPGetDP m7_ippsDLPGetDP +#define ippsDLPGenKeyPair m7_ippsDLPGenKeyPair +#define ippsDLPPublicKey m7_ippsDLPPublicKey +#define ippsDLPValidateKeyPair m7_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair m7_ippsDLPSetKeyPair +#define ippsDLPSignDSA m7_ippsDLPSignDSA +#define ippsDLPVerifyDSA m7_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH m7_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA m7_ippsDLPGenerateDSA +#define ippsDLPValidateDSA m7_ippsDLPValidateDSA +#define ippsDLPGenerateDH m7_ippsDLPGenerateDH +#define ippsDLPValidateDH m7_ippsDLPValidateDH +#define ippsECCGetResultString m7_ippsECCGetResultString +#define ippsECCPGetSize m7_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 m7_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 m7_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 m7_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 m7_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 m7_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 m7_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 m7_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 m7_ippsECCPGetSizeStdSM2 +#define ippsECCPInit m7_ippsECCPInit +#define ippsECCPInitStd128r1 m7_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 m7_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 m7_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 m7_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 m7_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 m7_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 m7_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 m7_ippsECCPInitStdSM2 +#define ippsECCPSet m7_ippsECCPSet +#define ippsECCPSetStd m7_ippsECCPSetStd +#define ippsECCPSetStd128r1 m7_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 m7_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 m7_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 m7_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 m7_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 m7_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 m7_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 m7_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 m7_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 m7_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 m7_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 m7_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 m7_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 m7_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet m7_ippsECCPGet +#define ippsECCPGetOrderBitSize m7_ippsECCPGetOrderBitSize +#define ippsECCPValidate m7_ippsECCPValidate +#define ippsECCPPointGetSize m7_ippsECCPPointGetSize +#define ippsECCPPointInit m7_ippsECCPPointInit +#define ippsECCPSetPoint m7_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity m7_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint m7_ippsECCPGetPoint +#define ippsECCPCheckPoint m7_ippsECCPCheckPoint +#define ippsECCPComparePoint m7_ippsECCPComparePoint +#define ippsECCPNegativePoint m7_ippsECCPNegativePoint +#define ippsECCPAddPoint m7_ippsECCPAddPoint +#define ippsECCPMulPointScalar m7_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair m7_ippsECCPGenKeyPair +#define ippsECCPPublicKey m7_ippsECCPPublicKey +#define ippsECCPValidateKeyPair m7_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair m7_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH m7_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC m7_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA m7_ippsECCPSignDSA +#define ippsECCPVerifyDSA m7_ippsECCPVerifyDSA +#define ippsECCPSignNR m7_ippsECCPSignNR +#define ippsECCPVerifyNR m7_ippsECCPVerifyNR +#define ippsECCPSignSM2 m7_ippsECCPSignSM2 +#define ippsECCPVerifySM2 m7_ippsECCPVerifySM2 +#define ippsGFpGetSize m7_ippsGFpGetSize +#define ippsGFpInitArbitrary m7_ippsGFpInitArbitrary +#define ippsGFpInitFixed m7_ippsGFpInitFixed +#define ippsGFpInit m7_ippsGFpInit +#define ippsGFpMethod_p192r1 m7_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 m7_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 m7_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 m7_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 m7_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 m7_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn m7_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 m7_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb m7_ippsGFpMethod_pArb +#define ippsGFpxGetSize m7_ippsGFpxGetSize +#define ippsGFpxInit m7_ippsGFpxInit +#define ippsGFpxInitBinomial m7_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 m7_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 m7_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 m7_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 m7_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom m7_ippsGFpxMethod_binom +#define ippsGFpxMethod_com m7_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize m7_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize m7_ippsGFpElementGetSize +#define ippsGFpElementInit m7_ippsGFpElementInit +#define ippsGFpSetElement m7_ippsGFpSetElement +#define ippsGFpSetElementRegular m7_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString m7_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom m7_ippsGFpSetElementRandom +#define ippsGFpSetElementHash m7_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf m7_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement m7_ippsGFpCpyElement +#define ippsGFpGetElement m7_ippsGFpGetElement +#define ippsGFpGetElementOctString m7_ippsGFpGetElementOctString +#define ippsGFpCmpElement m7_ippsGFpCmpElement +#define ippsGFpIsZeroElement m7_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement m7_ippsGFpIsUnityElement +#define ippsGFpConj m7_ippsGFpConj +#define ippsGFpNeg m7_ippsGFpNeg +#define ippsGFpInv m7_ippsGFpInv +#define ippsGFpSqrt m7_ippsGFpSqrt +#define ippsGFpSqr m7_ippsGFpSqr +#define ippsGFpAdd m7_ippsGFpAdd +#define ippsGFpSub m7_ippsGFpSub +#define ippsGFpMul m7_ippsGFpMul +#define ippsGFpExp m7_ippsGFpExp +#define ippsGFpMultiExp m7_ippsGFpMultiExp +#define ippsGFpAdd_PE m7_ippsGFpAdd_PE +#define ippsGFpSub_PE m7_ippsGFpSub_PE +#define ippsGFpMul_PE m7_ippsGFpMul_PE +#define ippsGFpGetInfo m7_ippsGFpGetInfo +#define ippsGFpECGetSize m7_ippsGFpECGetSize +#define ippsGFpECInit m7_ippsGFpECInit +#define ippsGFpECSet m7_ippsGFpECSet +#define ippsGFpECSetSubgroup m7_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 m7_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 m7_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 m7_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 m7_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 m7_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 m7_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 m7_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 m7_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 m7_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 m7_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 m7_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 m7_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 m7_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 m7_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 m7_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet m7_ippsGFpECGet +#define ippsGFpECGetSubgroup m7_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize m7_ippsGFpECScratchBufferSize +#define ippsGFpECVerify m7_ippsGFpECVerify +#define ippsGFpECPointGetSize m7_ippsGFpECPointGetSize +#define ippsGFpECPointInit m7_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity m7_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint m7_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular m7_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom m7_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint m7_ippsGFpECMakePoint +#define ippsGFpECSetPointHash m7_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible m7_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf m7_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf m7_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint m7_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular m7_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString m7_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString m7_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint m7_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup m7_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint m7_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint m7_ippsGFpECCmpPoint +#define ippsGFpECNegPoint m7_ippsGFpECNegPoint +#define ippsGFpECAddPoint m7_ippsGFpECAddPoint +#define ippsGFpECMulPoint m7_ippsGFpECMulPoint +#define ippsGFpECPrivateKey m7_ippsGFpECPrivateKey +#define ippsGFpECPublicKey m7_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair m7_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH m7_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC m7_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 m7_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA m7_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA m7_ippsGFpECVerifyDSA +#define ippsGFpECSignNR m7_ippsGFpECSignNR +#define ippsGFpECVerifyNR m7_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 m7_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 m7_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 m7_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize m7_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init m7_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup m7_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey m7_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm m7_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF m7_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 m7_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 m7_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 m7_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 m7_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 m7_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 m7_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 m7_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 m7_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize m7_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext m7_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize m7_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext m7_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_n0.h b/plugin/ippcp/library/include/single_cpu/ippcp_n0.h new file mode 100644 index 000000000..a3d367b8b --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_n0.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion n0_ippcpGetLibVersion +#define ippsDESGetSize n0_ippsDESGetSize +#define ippsDESInit n0_ippsDESInit +#define ippsDESPack n0_ippsDESPack +#define ippsDESUnpack n0_ippsDESUnpack +#define ippsTDESEncryptECB n0_ippsTDESEncryptECB +#define ippsTDESDecryptECB n0_ippsTDESDecryptECB +#define ippsTDESEncryptCBC n0_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC n0_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB n0_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB n0_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB n0_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB n0_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR n0_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR n0_ippsTDESDecryptCTR +#define ippsAESGetSize n0_ippsAESGetSize +#define ippsAESInit n0_ippsAESInit +#define ippsAESSetKey n0_ippsAESSetKey +#define ippsAESPack n0_ippsAESPack +#define ippsAESUnpack n0_ippsAESUnpack +#define ippsAESEncryptECB n0_ippsAESEncryptECB +#define ippsAESDecryptECB n0_ippsAESDecryptECB +#define ippsAESEncryptCBC n0_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 n0_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 n0_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 n0_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC n0_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 n0_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 n0_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 n0_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB n0_ippsAESEncryptCFB +#define ippsAESDecryptCFB n0_ippsAESDecryptCFB +#define ippsAESEncryptOFB n0_ippsAESEncryptOFB +#define ippsAESDecryptOFB n0_ippsAESDecryptOFB +#define ippsAESEncryptCTR n0_ippsAESEncryptCTR +#define ippsAESDecryptCTR n0_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct n0_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct n0_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise n0_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise n0_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise n0_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB n0_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize n0_ippsSMS4GetSize +#define ippsSMS4Init n0_ippsSMS4Init +#define ippsSMS4SetKey n0_ippsSMS4SetKey +#define ippsSMS4EncryptECB n0_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB n0_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC n0_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 n0_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 n0_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 n0_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC n0_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 n0_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 n0_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 n0_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB n0_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB n0_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB n0_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB n0_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR n0_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR n0_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize n0_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit n0_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen n0_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen n0_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart n0_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt n0_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt n0_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag n0_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize n0_ippsAES_CCMGetSize +#define ippsAES_CCMInit n0_ippsAES_CCMInit +#define ippsAES_CCMMessageLen n0_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen n0_ippsAES_CCMTagLen +#define ippsAES_CCMStart n0_ippsAES_CCMStart +#define ippsAES_CCMEncrypt n0_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt n0_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag n0_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize n0_ippsAES_GCMGetSize +#define ippsAES_GCMInit n0_ippsAES_GCMInit +#define ippsAES_GCMReinit n0_ippsAES_GCMReinit +#define ippsAES_GCMReset n0_ippsAES_GCMReset +#define ippsAES_GCMProcessIV n0_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD n0_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart n0_ippsAES_GCMStart +#define ippsAES_GCMEncrypt n0_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt n0_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag n0_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize n0_ippsAES_XTSGetSize +#define ippsAES_XTSInit n0_ippsAES_XTSInit +#define ippsAES_XTSEncrypt n0_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt n0_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC n0_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt n0_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt n0_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize n0_ippsAES_CMACGetSize +#define ippsAES_CMACInit n0_ippsAES_CMACInit +#define ippsAES_CMACUpdate n0_ippsAES_CMACUpdate +#define ippsAES_CMACFinal n0_ippsAES_CMACFinal +#define ippsAES_CMACGetTag n0_ippsAES_CMACGetTag +#define ippsARCFourCheckKey n0_ippsARCFourCheckKey +#define ippsARCFourGetSize n0_ippsARCFourGetSize +#define ippsARCFourInit n0_ippsARCFourInit +#define ippsARCFourReset n0_ippsARCFourReset +#define ippsARCFourPack n0_ippsARCFourPack +#define ippsARCFourUnpack n0_ippsARCFourUnpack +#define ippsARCFourEncrypt n0_ippsARCFourEncrypt +#define ippsARCFourDecrypt n0_ippsARCFourDecrypt +#define ippsSHA1GetSize n0_ippsSHA1GetSize +#define ippsSHA1Init n0_ippsSHA1Init +#define ippsSHA1Duplicate n0_ippsSHA1Duplicate +#define ippsSHA1Pack n0_ippsSHA1Pack +#define ippsSHA1Unpack n0_ippsSHA1Unpack +#define ippsSHA1Update n0_ippsSHA1Update +#define ippsSHA1GetTag n0_ippsSHA1GetTag +#define ippsSHA1Final n0_ippsSHA1Final +#define ippsSHA1MessageDigest n0_ippsSHA1MessageDigest +#define ippsSHA224GetSize n0_ippsSHA224GetSize +#define ippsSHA224Init n0_ippsSHA224Init +#define ippsSHA224Duplicate n0_ippsSHA224Duplicate +#define ippsSHA224Pack n0_ippsSHA224Pack +#define ippsSHA224Unpack n0_ippsSHA224Unpack +#define ippsSHA224Update n0_ippsSHA224Update +#define ippsSHA224GetTag n0_ippsSHA224GetTag +#define ippsSHA224Final n0_ippsSHA224Final +#define ippsSHA224MessageDigest n0_ippsSHA224MessageDigest +#define ippsSHA256GetSize n0_ippsSHA256GetSize +#define ippsSHA256Init n0_ippsSHA256Init +#define ippsSHA256Duplicate n0_ippsSHA256Duplicate +#define ippsSHA256Pack n0_ippsSHA256Pack +#define ippsSHA256Unpack n0_ippsSHA256Unpack +#define ippsSHA256Update n0_ippsSHA256Update +#define ippsSHA256GetTag n0_ippsSHA256GetTag +#define ippsSHA256Final n0_ippsSHA256Final +#define ippsSHA256MessageDigest n0_ippsSHA256MessageDigest +#define ippsSHA384GetSize n0_ippsSHA384GetSize +#define ippsSHA384Init n0_ippsSHA384Init +#define ippsSHA384Duplicate n0_ippsSHA384Duplicate +#define ippsSHA384Pack n0_ippsSHA384Pack +#define ippsSHA384Unpack n0_ippsSHA384Unpack +#define ippsSHA384Update n0_ippsSHA384Update +#define ippsSHA384GetTag n0_ippsSHA384GetTag +#define ippsSHA384Final n0_ippsSHA384Final +#define ippsSHA384MessageDigest n0_ippsSHA384MessageDigest +#define ippsSHA512GetSize n0_ippsSHA512GetSize +#define ippsSHA512Init n0_ippsSHA512Init +#define ippsSHA512Duplicate n0_ippsSHA512Duplicate +#define ippsSHA512Pack n0_ippsSHA512Pack +#define ippsSHA512Unpack n0_ippsSHA512Unpack +#define ippsSHA512Update n0_ippsSHA512Update +#define ippsSHA512GetTag n0_ippsSHA512GetTag +#define ippsSHA512Final n0_ippsSHA512Final +#define ippsSHA512MessageDigest n0_ippsSHA512MessageDigest +#define ippsMD5GetSize n0_ippsMD5GetSize +#define ippsMD5Init n0_ippsMD5Init +#define ippsMD5Duplicate n0_ippsMD5Duplicate +#define ippsMD5Pack n0_ippsMD5Pack +#define ippsMD5Unpack n0_ippsMD5Unpack +#define ippsMD5Update n0_ippsMD5Update +#define ippsMD5GetTag n0_ippsMD5GetTag +#define ippsMD5Final n0_ippsMD5Final +#define ippsMD5MessageDigest n0_ippsMD5MessageDigest +#define ippsSM3GetSize n0_ippsSM3GetSize +#define ippsSM3Init n0_ippsSM3Init +#define ippsSM3Duplicate n0_ippsSM3Duplicate +#define ippsSM3Pack n0_ippsSM3Pack +#define ippsSM3Unpack n0_ippsSM3Unpack +#define ippsSM3Update n0_ippsSM3Update +#define ippsSM3GetTag n0_ippsSM3GetTag +#define ippsSM3Final n0_ippsSM3Final +#define ippsSM3MessageDigest n0_ippsSM3MessageDigest +#define ippsHashGetSize n0_ippsHashGetSize +#define ippsHashInit n0_ippsHashInit +#define ippsHashPack n0_ippsHashPack +#define ippsHashUnpack n0_ippsHashUnpack +#define ippsHashDuplicate n0_ippsHashDuplicate +#define ippsHashUpdate n0_ippsHashUpdate +#define ippsHashGetTag n0_ippsHashGetTag +#define ippsHashFinal n0_ippsHashFinal +#define ippsHashMessage n0_ippsHashMessage +#define ippsHashMethod_MD5 n0_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 n0_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 n0_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI n0_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT n0_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 n0_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI n0_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT n0_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 n0_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI n0_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT n0_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 n0_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 n0_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 n0_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 n0_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize n0_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 n0_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 n0_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 n0_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 n0_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI n0_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT n0_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 n0_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI n0_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT n0_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 n0_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI n0_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT n0_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 n0_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI n0_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT n0_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 n0_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI n0_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT n0_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 n0_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 n0_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 n0_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 n0_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 n0_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 n0_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 n0_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 n0_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf n0_ippsHashGetSize_rmf +#define ippsHashInit_rmf n0_ippsHashInit_rmf +#define ippsHashPack_rmf n0_ippsHashPack_rmf +#define ippsHashUnpack_rmf n0_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf n0_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf n0_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf n0_ippsHashGetTag_rmf +#define ippsHashFinal_rmf n0_ippsHashFinal_rmf +#define ippsHashMessage_rmf n0_ippsHashMessage_rmf +#define ippsHashMethodGetInfo n0_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf n0_ippsHashGetInfo_rmf +#define ippsMGF n0_ippsMGF +#define ippsMGF1_rmf n0_ippsMGF1_rmf +#define ippsMGF2_rmf n0_ippsMGF2_rmf +#define ippsHMAC_GetSize n0_ippsHMAC_GetSize +#define ippsHMAC_Init n0_ippsHMAC_Init +#define ippsHMAC_Pack n0_ippsHMAC_Pack +#define ippsHMAC_Unpack n0_ippsHMAC_Unpack +#define ippsHMAC_Duplicate n0_ippsHMAC_Duplicate +#define ippsHMAC_Update n0_ippsHMAC_Update +#define ippsHMAC_Final n0_ippsHMAC_Final +#define ippsHMAC_GetTag n0_ippsHMAC_GetTag +#define ippsHMAC_Message n0_ippsHMAC_Message +#define ippsHMACGetSize_rmf n0_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf n0_ippsHMACInit_rmf +#define ippsHMACPack_rmf n0_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf n0_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf n0_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf n0_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf n0_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf n0_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf n0_ippsHMACMessage_rmf +#define ippsBigNumGetSize n0_ippsBigNumGetSize +#define ippsBigNumInit n0_ippsBigNumInit +#define ippsCmpZero_BN n0_ippsCmpZero_BN +#define ippsCmp_BN n0_ippsCmp_BN +#define ippsGetSize_BN n0_ippsGetSize_BN +#define ippsSet_BN n0_ippsSet_BN +#define ippsGet_BN n0_ippsGet_BN +#define ippsRef_BN n0_ippsRef_BN +#define ippsExtGet_BN n0_ippsExtGet_BN +#define ippsAdd_BN n0_ippsAdd_BN +#define ippsSub_BN n0_ippsSub_BN +#define ippsMul_BN n0_ippsMul_BN +#define ippsMAC_BN_I n0_ippsMAC_BN_I +#define ippsDiv_BN n0_ippsDiv_BN +#define ippsMod_BN n0_ippsMod_BN +#define ippsGcd_BN n0_ippsGcd_BN +#define ippsModInv_BN n0_ippsModInv_BN +#define ippsSetOctString_BN n0_ippsSetOctString_BN +#define ippsGetOctString_BN n0_ippsGetOctString_BN +#define ippsMontGetSize n0_ippsMontGetSize +#define ippsMontInit n0_ippsMontInit +#define ippsMontSet n0_ippsMontSet +#define ippsMontGet n0_ippsMontGet +#define ippsMontForm n0_ippsMontForm +#define ippsMontMul n0_ippsMontMul +#define ippsMontExp n0_ippsMontExp +#define ippsPRNGGetSize n0_ippsPRNGGetSize +#define ippsPRNGInit n0_ippsPRNGInit +#define ippsPRNGSetModulus n0_ippsPRNGSetModulus +#define ippsPRNGSetH0 n0_ippsPRNGSetH0 +#define ippsPRNGSetAugment n0_ippsPRNGSetAugment +#define ippsPRNGSetSeed n0_ippsPRNGSetSeed +#define ippsPRNGGetSeed n0_ippsPRNGGetSeed +#define ippsPRNGen n0_ippsPRNGen +#define ippsPRNGen_BN n0_ippsPRNGen_BN +#define ippsPRNGenRDRAND n0_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN n0_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED n0_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN n0_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize n0_ippsPrimeGetSize +#define ippsPrimeInit n0_ippsPrimeInit +#define ippsPrimeGen n0_ippsPrimeGen +#define ippsPrimeTest n0_ippsPrimeTest +#define ippsPrimeGen_BN n0_ippsPrimeGen_BN +#define ippsPrimeTest_BN n0_ippsPrimeTest_BN +#define ippsPrimeGet n0_ippsPrimeGet +#define ippsPrimeGet_BN n0_ippsPrimeGet_BN +#define ippsPrimeSet n0_ippsPrimeSet +#define ippsPrimeSet_BN n0_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey n0_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey n0_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey n0_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey n0_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 n0_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 n0_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 n0_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 n0_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 n0_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 n0_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 n0_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 n0_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey n0_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey n0_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt n0_ippsRSA_Encrypt +#define ippsRSA_Decrypt n0_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys n0_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys n0_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP n0_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP n0_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf n0_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf n0_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 n0_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 n0_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS n0_ippsRSASign_PSS +#define ippsRSAVerify_PSS n0_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf n0_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf n0_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 n0_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 n0_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf n0_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf n0_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString n0_ippsDLGetResultString +#define ippsDLPGetSize n0_ippsDLPGetSize +#define ippsDLPInit n0_ippsDLPInit +#define ippsDLPPack n0_ippsDLPPack +#define ippsDLPUnpack n0_ippsDLPUnpack +#define ippsDLPSet n0_ippsDLPSet +#define ippsDLPGet n0_ippsDLPGet +#define ippsDLPSetDP n0_ippsDLPSetDP +#define ippsDLPGetDP n0_ippsDLPGetDP +#define ippsDLPGenKeyPair n0_ippsDLPGenKeyPair +#define ippsDLPPublicKey n0_ippsDLPPublicKey +#define ippsDLPValidateKeyPair n0_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair n0_ippsDLPSetKeyPair +#define ippsDLPSignDSA n0_ippsDLPSignDSA +#define ippsDLPVerifyDSA n0_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH n0_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA n0_ippsDLPGenerateDSA +#define ippsDLPValidateDSA n0_ippsDLPValidateDSA +#define ippsDLPGenerateDH n0_ippsDLPGenerateDH +#define ippsDLPValidateDH n0_ippsDLPValidateDH +#define ippsECCGetResultString n0_ippsECCGetResultString +#define ippsECCPGetSize n0_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 n0_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 n0_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 n0_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 n0_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 n0_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 n0_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 n0_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 n0_ippsECCPGetSizeStdSM2 +#define ippsECCPInit n0_ippsECCPInit +#define ippsECCPInitStd128r1 n0_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 n0_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 n0_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 n0_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 n0_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 n0_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 n0_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 n0_ippsECCPInitStdSM2 +#define ippsECCPSet n0_ippsECCPSet +#define ippsECCPSetStd n0_ippsECCPSetStd +#define ippsECCPSetStd128r1 n0_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 n0_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 n0_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 n0_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 n0_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 n0_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 n0_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 n0_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 n0_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 n0_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 n0_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 n0_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 n0_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 n0_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet n0_ippsECCPGet +#define ippsECCPGetOrderBitSize n0_ippsECCPGetOrderBitSize +#define ippsECCPValidate n0_ippsECCPValidate +#define ippsECCPPointGetSize n0_ippsECCPPointGetSize +#define ippsECCPPointInit n0_ippsECCPPointInit +#define ippsECCPSetPoint n0_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity n0_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint n0_ippsECCPGetPoint +#define ippsECCPCheckPoint n0_ippsECCPCheckPoint +#define ippsECCPComparePoint n0_ippsECCPComparePoint +#define ippsECCPNegativePoint n0_ippsECCPNegativePoint +#define ippsECCPAddPoint n0_ippsECCPAddPoint +#define ippsECCPMulPointScalar n0_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair n0_ippsECCPGenKeyPair +#define ippsECCPPublicKey n0_ippsECCPPublicKey +#define ippsECCPValidateKeyPair n0_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair n0_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH n0_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC n0_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA n0_ippsECCPSignDSA +#define ippsECCPVerifyDSA n0_ippsECCPVerifyDSA +#define ippsECCPSignNR n0_ippsECCPSignNR +#define ippsECCPVerifyNR n0_ippsECCPVerifyNR +#define ippsECCPSignSM2 n0_ippsECCPSignSM2 +#define ippsECCPVerifySM2 n0_ippsECCPVerifySM2 +#define ippsGFpGetSize n0_ippsGFpGetSize +#define ippsGFpInitArbitrary n0_ippsGFpInitArbitrary +#define ippsGFpInitFixed n0_ippsGFpInitFixed +#define ippsGFpInit n0_ippsGFpInit +#define ippsGFpMethod_p192r1 n0_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 n0_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 n0_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 n0_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 n0_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 n0_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn n0_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 n0_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb n0_ippsGFpMethod_pArb +#define ippsGFpxGetSize n0_ippsGFpxGetSize +#define ippsGFpxInit n0_ippsGFpxInit +#define ippsGFpxInitBinomial n0_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 n0_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 n0_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 n0_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 n0_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom n0_ippsGFpxMethod_binom +#define ippsGFpxMethod_com n0_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize n0_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize n0_ippsGFpElementGetSize +#define ippsGFpElementInit n0_ippsGFpElementInit +#define ippsGFpSetElement n0_ippsGFpSetElement +#define ippsGFpSetElementRegular n0_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString n0_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom n0_ippsGFpSetElementRandom +#define ippsGFpSetElementHash n0_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf n0_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement n0_ippsGFpCpyElement +#define ippsGFpGetElement n0_ippsGFpGetElement +#define ippsGFpGetElementOctString n0_ippsGFpGetElementOctString +#define ippsGFpCmpElement n0_ippsGFpCmpElement +#define ippsGFpIsZeroElement n0_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement n0_ippsGFpIsUnityElement +#define ippsGFpConj n0_ippsGFpConj +#define ippsGFpNeg n0_ippsGFpNeg +#define ippsGFpInv n0_ippsGFpInv +#define ippsGFpSqrt n0_ippsGFpSqrt +#define ippsGFpSqr n0_ippsGFpSqr +#define ippsGFpAdd n0_ippsGFpAdd +#define ippsGFpSub n0_ippsGFpSub +#define ippsGFpMul n0_ippsGFpMul +#define ippsGFpExp n0_ippsGFpExp +#define ippsGFpMultiExp n0_ippsGFpMultiExp +#define ippsGFpAdd_PE n0_ippsGFpAdd_PE +#define ippsGFpSub_PE n0_ippsGFpSub_PE +#define ippsGFpMul_PE n0_ippsGFpMul_PE +#define ippsGFpGetInfo n0_ippsGFpGetInfo +#define ippsGFpECGetSize n0_ippsGFpECGetSize +#define ippsGFpECInit n0_ippsGFpECInit +#define ippsGFpECSet n0_ippsGFpECSet +#define ippsGFpECSetSubgroup n0_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 n0_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 n0_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 n0_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 n0_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 n0_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 n0_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 n0_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 n0_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 n0_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 n0_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 n0_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 n0_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 n0_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 n0_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 n0_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet n0_ippsGFpECGet +#define ippsGFpECGetSubgroup n0_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize n0_ippsGFpECScratchBufferSize +#define ippsGFpECVerify n0_ippsGFpECVerify +#define ippsGFpECPointGetSize n0_ippsGFpECPointGetSize +#define ippsGFpECPointInit n0_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity n0_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint n0_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular n0_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom n0_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint n0_ippsGFpECMakePoint +#define ippsGFpECSetPointHash n0_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible n0_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf n0_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf n0_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint n0_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular n0_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString n0_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString n0_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint n0_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup n0_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint n0_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint n0_ippsGFpECCmpPoint +#define ippsGFpECNegPoint n0_ippsGFpECNegPoint +#define ippsGFpECAddPoint n0_ippsGFpECAddPoint +#define ippsGFpECMulPoint n0_ippsGFpECMulPoint +#define ippsGFpECPrivateKey n0_ippsGFpECPrivateKey +#define ippsGFpECPublicKey n0_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair n0_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH n0_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC n0_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 n0_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA n0_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA n0_ippsGFpECVerifyDSA +#define ippsGFpECSignNR n0_ippsGFpECSignNR +#define ippsGFpECVerifyNR n0_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 n0_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 n0_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 n0_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize n0_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init n0_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup n0_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey n0_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm n0_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF n0_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 n0_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 n0_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 n0_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 n0_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 n0_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 n0_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 n0_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 n0_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize n0_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext n0_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize n0_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext n0_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_n8.h b/plugin/ippcp/library/include/single_cpu/ippcp_n8.h new file mode 100644 index 000000000..b03656083 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_n8.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion n8_ippcpGetLibVersion +#define ippsDESGetSize n8_ippsDESGetSize +#define ippsDESInit n8_ippsDESInit +#define ippsDESPack n8_ippsDESPack +#define ippsDESUnpack n8_ippsDESUnpack +#define ippsTDESEncryptECB n8_ippsTDESEncryptECB +#define ippsTDESDecryptECB n8_ippsTDESDecryptECB +#define ippsTDESEncryptCBC n8_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC n8_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB n8_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB n8_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB n8_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB n8_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR n8_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR n8_ippsTDESDecryptCTR +#define ippsAESGetSize n8_ippsAESGetSize +#define ippsAESInit n8_ippsAESInit +#define ippsAESSetKey n8_ippsAESSetKey +#define ippsAESPack n8_ippsAESPack +#define ippsAESUnpack n8_ippsAESUnpack +#define ippsAESEncryptECB n8_ippsAESEncryptECB +#define ippsAESDecryptECB n8_ippsAESDecryptECB +#define ippsAESEncryptCBC n8_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 n8_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 n8_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 n8_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC n8_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 n8_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 n8_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 n8_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB n8_ippsAESEncryptCFB +#define ippsAESDecryptCFB n8_ippsAESDecryptCFB +#define ippsAESEncryptOFB n8_ippsAESEncryptOFB +#define ippsAESDecryptOFB n8_ippsAESDecryptOFB +#define ippsAESEncryptCTR n8_ippsAESEncryptCTR +#define ippsAESDecryptCTR n8_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct n8_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct n8_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise n8_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise n8_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise n8_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB n8_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize n8_ippsSMS4GetSize +#define ippsSMS4Init n8_ippsSMS4Init +#define ippsSMS4SetKey n8_ippsSMS4SetKey +#define ippsSMS4EncryptECB n8_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB n8_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC n8_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 n8_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 n8_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 n8_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC n8_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 n8_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 n8_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 n8_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB n8_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB n8_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB n8_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB n8_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR n8_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR n8_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize n8_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit n8_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen n8_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen n8_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart n8_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt n8_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt n8_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag n8_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize n8_ippsAES_CCMGetSize +#define ippsAES_CCMInit n8_ippsAES_CCMInit +#define ippsAES_CCMMessageLen n8_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen n8_ippsAES_CCMTagLen +#define ippsAES_CCMStart n8_ippsAES_CCMStart +#define ippsAES_CCMEncrypt n8_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt n8_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag n8_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize n8_ippsAES_GCMGetSize +#define ippsAES_GCMInit n8_ippsAES_GCMInit +#define ippsAES_GCMReinit n8_ippsAES_GCMReinit +#define ippsAES_GCMReset n8_ippsAES_GCMReset +#define ippsAES_GCMProcessIV n8_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD n8_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart n8_ippsAES_GCMStart +#define ippsAES_GCMEncrypt n8_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt n8_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag n8_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize n8_ippsAES_XTSGetSize +#define ippsAES_XTSInit n8_ippsAES_XTSInit +#define ippsAES_XTSEncrypt n8_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt n8_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC n8_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt n8_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt n8_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize n8_ippsAES_CMACGetSize +#define ippsAES_CMACInit n8_ippsAES_CMACInit +#define ippsAES_CMACUpdate n8_ippsAES_CMACUpdate +#define ippsAES_CMACFinal n8_ippsAES_CMACFinal +#define ippsAES_CMACGetTag n8_ippsAES_CMACGetTag +#define ippsARCFourCheckKey n8_ippsARCFourCheckKey +#define ippsARCFourGetSize n8_ippsARCFourGetSize +#define ippsARCFourInit n8_ippsARCFourInit +#define ippsARCFourReset n8_ippsARCFourReset +#define ippsARCFourPack n8_ippsARCFourPack +#define ippsARCFourUnpack n8_ippsARCFourUnpack +#define ippsARCFourEncrypt n8_ippsARCFourEncrypt +#define ippsARCFourDecrypt n8_ippsARCFourDecrypt +#define ippsSHA1GetSize n8_ippsSHA1GetSize +#define ippsSHA1Init n8_ippsSHA1Init +#define ippsSHA1Duplicate n8_ippsSHA1Duplicate +#define ippsSHA1Pack n8_ippsSHA1Pack +#define ippsSHA1Unpack n8_ippsSHA1Unpack +#define ippsSHA1Update n8_ippsSHA1Update +#define ippsSHA1GetTag n8_ippsSHA1GetTag +#define ippsSHA1Final n8_ippsSHA1Final +#define ippsSHA1MessageDigest n8_ippsSHA1MessageDigest +#define ippsSHA224GetSize n8_ippsSHA224GetSize +#define ippsSHA224Init n8_ippsSHA224Init +#define ippsSHA224Duplicate n8_ippsSHA224Duplicate +#define ippsSHA224Pack n8_ippsSHA224Pack +#define ippsSHA224Unpack n8_ippsSHA224Unpack +#define ippsSHA224Update n8_ippsSHA224Update +#define ippsSHA224GetTag n8_ippsSHA224GetTag +#define ippsSHA224Final n8_ippsSHA224Final +#define ippsSHA224MessageDigest n8_ippsSHA224MessageDigest +#define ippsSHA256GetSize n8_ippsSHA256GetSize +#define ippsSHA256Init n8_ippsSHA256Init +#define ippsSHA256Duplicate n8_ippsSHA256Duplicate +#define ippsSHA256Pack n8_ippsSHA256Pack +#define ippsSHA256Unpack n8_ippsSHA256Unpack +#define ippsSHA256Update n8_ippsSHA256Update +#define ippsSHA256GetTag n8_ippsSHA256GetTag +#define ippsSHA256Final n8_ippsSHA256Final +#define ippsSHA256MessageDigest n8_ippsSHA256MessageDigest +#define ippsSHA384GetSize n8_ippsSHA384GetSize +#define ippsSHA384Init n8_ippsSHA384Init +#define ippsSHA384Duplicate n8_ippsSHA384Duplicate +#define ippsSHA384Pack n8_ippsSHA384Pack +#define ippsSHA384Unpack n8_ippsSHA384Unpack +#define ippsSHA384Update n8_ippsSHA384Update +#define ippsSHA384GetTag n8_ippsSHA384GetTag +#define ippsSHA384Final n8_ippsSHA384Final +#define ippsSHA384MessageDigest n8_ippsSHA384MessageDigest +#define ippsSHA512GetSize n8_ippsSHA512GetSize +#define ippsSHA512Init n8_ippsSHA512Init +#define ippsSHA512Duplicate n8_ippsSHA512Duplicate +#define ippsSHA512Pack n8_ippsSHA512Pack +#define ippsSHA512Unpack n8_ippsSHA512Unpack +#define ippsSHA512Update n8_ippsSHA512Update +#define ippsSHA512GetTag n8_ippsSHA512GetTag +#define ippsSHA512Final n8_ippsSHA512Final +#define ippsSHA512MessageDigest n8_ippsSHA512MessageDigest +#define ippsMD5GetSize n8_ippsMD5GetSize +#define ippsMD5Init n8_ippsMD5Init +#define ippsMD5Duplicate n8_ippsMD5Duplicate +#define ippsMD5Pack n8_ippsMD5Pack +#define ippsMD5Unpack n8_ippsMD5Unpack +#define ippsMD5Update n8_ippsMD5Update +#define ippsMD5GetTag n8_ippsMD5GetTag +#define ippsMD5Final n8_ippsMD5Final +#define ippsMD5MessageDigest n8_ippsMD5MessageDigest +#define ippsSM3GetSize n8_ippsSM3GetSize +#define ippsSM3Init n8_ippsSM3Init +#define ippsSM3Duplicate n8_ippsSM3Duplicate +#define ippsSM3Pack n8_ippsSM3Pack +#define ippsSM3Unpack n8_ippsSM3Unpack +#define ippsSM3Update n8_ippsSM3Update +#define ippsSM3GetTag n8_ippsSM3GetTag +#define ippsSM3Final n8_ippsSM3Final +#define ippsSM3MessageDigest n8_ippsSM3MessageDigest +#define ippsHashGetSize n8_ippsHashGetSize +#define ippsHashInit n8_ippsHashInit +#define ippsHashPack n8_ippsHashPack +#define ippsHashUnpack n8_ippsHashUnpack +#define ippsHashDuplicate n8_ippsHashDuplicate +#define ippsHashUpdate n8_ippsHashUpdate +#define ippsHashGetTag n8_ippsHashGetTag +#define ippsHashFinal n8_ippsHashFinal +#define ippsHashMessage n8_ippsHashMessage +#define ippsHashMethod_MD5 n8_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 n8_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 n8_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI n8_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT n8_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 n8_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI n8_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT n8_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 n8_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI n8_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT n8_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 n8_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 n8_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 n8_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 n8_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize n8_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 n8_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 n8_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 n8_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 n8_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI n8_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT n8_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 n8_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI n8_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT n8_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 n8_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI n8_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT n8_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 n8_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI n8_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT n8_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 n8_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI n8_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT n8_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 n8_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 n8_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 n8_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 n8_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 n8_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 n8_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 n8_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 n8_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf n8_ippsHashGetSize_rmf +#define ippsHashInit_rmf n8_ippsHashInit_rmf +#define ippsHashPack_rmf n8_ippsHashPack_rmf +#define ippsHashUnpack_rmf n8_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf n8_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf n8_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf n8_ippsHashGetTag_rmf +#define ippsHashFinal_rmf n8_ippsHashFinal_rmf +#define ippsHashMessage_rmf n8_ippsHashMessage_rmf +#define ippsHashMethodGetInfo n8_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf n8_ippsHashGetInfo_rmf +#define ippsMGF n8_ippsMGF +#define ippsMGF1_rmf n8_ippsMGF1_rmf +#define ippsMGF2_rmf n8_ippsMGF2_rmf +#define ippsHMAC_GetSize n8_ippsHMAC_GetSize +#define ippsHMAC_Init n8_ippsHMAC_Init +#define ippsHMAC_Pack n8_ippsHMAC_Pack +#define ippsHMAC_Unpack n8_ippsHMAC_Unpack +#define ippsHMAC_Duplicate n8_ippsHMAC_Duplicate +#define ippsHMAC_Update n8_ippsHMAC_Update +#define ippsHMAC_Final n8_ippsHMAC_Final +#define ippsHMAC_GetTag n8_ippsHMAC_GetTag +#define ippsHMAC_Message n8_ippsHMAC_Message +#define ippsHMACGetSize_rmf n8_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf n8_ippsHMACInit_rmf +#define ippsHMACPack_rmf n8_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf n8_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf n8_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf n8_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf n8_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf n8_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf n8_ippsHMACMessage_rmf +#define ippsBigNumGetSize n8_ippsBigNumGetSize +#define ippsBigNumInit n8_ippsBigNumInit +#define ippsCmpZero_BN n8_ippsCmpZero_BN +#define ippsCmp_BN n8_ippsCmp_BN +#define ippsGetSize_BN n8_ippsGetSize_BN +#define ippsSet_BN n8_ippsSet_BN +#define ippsGet_BN n8_ippsGet_BN +#define ippsRef_BN n8_ippsRef_BN +#define ippsExtGet_BN n8_ippsExtGet_BN +#define ippsAdd_BN n8_ippsAdd_BN +#define ippsSub_BN n8_ippsSub_BN +#define ippsMul_BN n8_ippsMul_BN +#define ippsMAC_BN_I n8_ippsMAC_BN_I +#define ippsDiv_BN n8_ippsDiv_BN +#define ippsMod_BN n8_ippsMod_BN +#define ippsGcd_BN n8_ippsGcd_BN +#define ippsModInv_BN n8_ippsModInv_BN +#define ippsSetOctString_BN n8_ippsSetOctString_BN +#define ippsGetOctString_BN n8_ippsGetOctString_BN +#define ippsMontGetSize n8_ippsMontGetSize +#define ippsMontInit n8_ippsMontInit +#define ippsMontSet n8_ippsMontSet +#define ippsMontGet n8_ippsMontGet +#define ippsMontForm n8_ippsMontForm +#define ippsMontMul n8_ippsMontMul +#define ippsMontExp n8_ippsMontExp +#define ippsPRNGGetSize n8_ippsPRNGGetSize +#define ippsPRNGInit n8_ippsPRNGInit +#define ippsPRNGSetModulus n8_ippsPRNGSetModulus +#define ippsPRNGSetH0 n8_ippsPRNGSetH0 +#define ippsPRNGSetAugment n8_ippsPRNGSetAugment +#define ippsPRNGSetSeed n8_ippsPRNGSetSeed +#define ippsPRNGGetSeed n8_ippsPRNGGetSeed +#define ippsPRNGen n8_ippsPRNGen +#define ippsPRNGen_BN n8_ippsPRNGen_BN +#define ippsPRNGenRDRAND n8_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN n8_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED n8_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN n8_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize n8_ippsPrimeGetSize +#define ippsPrimeInit n8_ippsPrimeInit +#define ippsPrimeGen n8_ippsPrimeGen +#define ippsPrimeTest n8_ippsPrimeTest +#define ippsPrimeGen_BN n8_ippsPrimeGen_BN +#define ippsPrimeTest_BN n8_ippsPrimeTest_BN +#define ippsPrimeGet n8_ippsPrimeGet +#define ippsPrimeGet_BN n8_ippsPrimeGet_BN +#define ippsPrimeSet n8_ippsPrimeSet +#define ippsPrimeSet_BN n8_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey n8_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey n8_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey n8_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey n8_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 n8_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 n8_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 n8_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 n8_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 n8_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 n8_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 n8_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 n8_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey n8_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey n8_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt n8_ippsRSA_Encrypt +#define ippsRSA_Decrypt n8_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys n8_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys n8_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP n8_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP n8_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf n8_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf n8_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 n8_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 n8_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS n8_ippsRSASign_PSS +#define ippsRSAVerify_PSS n8_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf n8_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf n8_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 n8_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 n8_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf n8_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf n8_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString n8_ippsDLGetResultString +#define ippsDLPGetSize n8_ippsDLPGetSize +#define ippsDLPInit n8_ippsDLPInit +#define ippsDLPPack n8_ippsDLPPack +#define ippsDLPUnpack n8_ippsDLPUnpack +#define ippsDLPSet n8_ippsDLPSet +#define ippsDLPGet n8_ippsDLPGet +#define ippsDLPSetDP n8_ippsDLPSetDP +#define ippsDLPGetDP n8_ippsDLPGetDP +#define ippsDLPGenKeyPair n8_ippsDLPGenKeyPair +#define ippsDLPPublicKey n8_ippsDLPPublicKey +#define ippsDLPValidateKeyPair n8_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair n8_ippsDLPSetKeyPair +#define ippsDLPSignDSA n8_ippsDLPSignDSA +#define ippsDLPVerifyDSA n8_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH n8_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA n8_ippsDLPGenerateDSA +#define ippsDLPValidateDSA n8_ippsDLPValidateDSA +#define ippsDLPGenerateDH n8_ippsDLPGenerateDH +#define ippsDLPValidateDH n8_ippsDLPValidateDH +#define ippsECCGetResultString n8_ippsECCGetResultString +#define ippsECCPGetSize n8_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 n8_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 n8_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 n8_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 n8_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 n8_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 n8_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 n8_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 n8_ippsECCPGetSizeStdSM2 +#define ippsECCPInit n8_ippsECCPInit +#define ippsECCPInitStd128r1 n8_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 n8_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 n8_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 n8_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 n8_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 n8_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 n8_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 n8_ippsECCPInitStdSM2 +#define ippsECCPSet n8_ippsECCPSet +#define ippsECCPSetStd n8_ippsECCPSetStd +#define ippsECCPSetStd128r1 n8_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 n8_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 n8_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 n8_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 n8_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 n8_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 n8_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 n8_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 n8_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 n8_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 n8_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 n8_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 n8_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 n8_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet n8_ippsECCPGet +#define ippsECCPGetOrderBitSize n8_ippsECCPGetOrderBitSize +#define ippsECCPValidate n8_ippsECCPValidate +#define ippsECCPPointGetSize n8_ippsECCPPointGetSize +#define ippsECCPPointInit n8_ippsECCPPointInit +#define ippsECCPSetPoint n8_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity n8_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint n8_ippsECCPGetPoint +#define ippsECCPCheckPoint n8_ippsECCPCheckPoint +#define ippsECCPComparePoint n8_ippsECCPComparePoint +#define ippsECCPNegativePoint n8_ippsECCPNegativePoint +#define ippsECCPAddPoint n8_ippsECCPAddPoint +#define ippsECCPMulPointScalar n8_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair n8_ippsECCPGenKeyPair +#define ippsECCPPublicKey n8_ippsECCPPublicKey +#define ippsECCPValidateKeyPair n8_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair n8_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH n8_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC n8_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA n8_ippsECCPSignDSA +#define ippsECCPVerifyDSA n8_ippsECCPVerifyDSA +#define ippsECCPSignNR n8_ippsECCPSignNR +#define ippsECCPVerifyNR n8_ippsECCPVerifyNR +#define ippsECCPSignSM2 n8_ippsECCPSignSM2 +#define ippsECCPVerifySM2 n8_ippsECCPVerifySM2 +#define ippsGFpGetSize n8_ippsGFpGetSize +#define ippsGFpInitArbitrary n8_ippsGFpInitArbitrary +#define ippsGFpInitFixed n8_ippsGFpInitFixed +#define ippsGFpInit n8_ippsGFpInit +#define ippsGFpMethod_p192r1 n8_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 n8_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 n8_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 n8_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 n8_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 n8_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn n8_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 n8_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb n8_ippsGFpMethod_pArb +#define ippsGFpxGetSize n8_ippsGFpxGetSize +#define ippsGFpxInit n8_ippsGFpxInit +#define ippsGFpxInitBinomial n8_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 n8_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 n8_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 n8_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 n8_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom n8_ippsGFpxMethod_binom +#define ippsGFpxMethod_com n8_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize n8_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize n8_ippsGFpElementGetSize +#define ippsGFpElementInit n8_ippsGFpElementInit +#define ippsGFpSetElement n8_ippsGFpSetElement +#define ippsGFpSetElementRegular n8_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString n8_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom n8_ippsGFpSetElementRandom +#define ippsGFpSetElementHash n8_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf n8_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement n8_ippsGFpCpyElement +#define ippsGFpGetElement n8_ippsGFpGetElement +#define ippsGFpGetElementOctString n8_ippsGFpGetElementOctString +#define ippsGFpCmpElement n8_ippsGFpCmpElement +#define ippsGFpIsZeroElement n8_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement n8_ippsGFpIsUnityElement +#define ippsGFpConj n8_ippsGFpConj +#define ippsGFpNeg n8_ippsGFpNeg +#define ippsGFpInv n8_ippsGFpInv +#define ippsGFpSqrt n8_ippsGFpSqrt +#define ippsGFpSqr n8_ippsGFpSqr +#define ippsGFpAdd n8_ippsGFpAdd +#define ippsGFpSub n8_ippsGFpSub +#define ippsGFpMul n8_ippsGFpMul +#define ippsGFpExp n8_ippsGFpExp +#define ippsGFpMultiExp n8_ippsGFpMultiExp +#define ippsGFpAdd_PE n8_ippsGFpAdd_PE +#define ippsGFpSub_PE n8_ippsGFpSub_PE +#define ippsGFpMul_PE n8_ippsGFpMul_PE +#define ippsGFpGetInfo n8_ippsGFpGetInfo +#define ippsGFpECGetSize n8_ippsGFpECGetSize +#define ippsGFpECInit n8_ippsGFpECInit +#define ippsGFpECSet n8_ippsGFpECSet +#define ippsGFpECSetSubgroup n8_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 n8_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 n8_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 n8_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 n8_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 n8_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 n8_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 n8_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 n8_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 n8_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 n8_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 n8_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 n8_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 n8_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 n8_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 n8_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet n8_ippsGFpECGet +#define ippsGFpECGetSubgroup n8_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize n8_ippsGFpECScratchBufferSize +#define ippsGFpECVerify n8_ippsGFpECVerify +#define ippsGFpECPointGetSize n8_ippsGFpECPointGetSize +#define ippsGFpECPointInit n8_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity n8_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint n8_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular n8_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom n8_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint n8_ippsGFpECMakePoint +#define ippsGFpECSetPointHash n8_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible n8_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf n8_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf n8_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint n8_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular n8_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString n8_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString n8_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint n8_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup n8_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint n8_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint n8_ippsGFpECCmpPoint +#define ippsGFpECNegPoint n8_ippsGFpECNegPoint +#define ippsGFpECAddPoint n8_ippsGFpECAddPoint +#define ippsGFpECMulPoint n8_ippsGFpECMulPoint +#define ippsGFpECPrivateKey n8_ippsGFpECPrivateKey +#define ippsGFpECPublicKey n8_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair n8_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH n8_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC n8_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 n8_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA n8_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA n8_ippsGFpECVerifyDSA +#define ippsGFpECSignNR n8_ippsGFpECSignNR +#define ippsGFpECVerifyNR n8_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 n8_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 n8_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 n8_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize n8_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init n8_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup n8_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey n8_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm n8_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF n8_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 n8_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 n8_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 n8_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 n8_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 n8_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 n8_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 n8_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 n8_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize n8_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext n8_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize n8_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext n8_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_p8.h b/plugin/ippcp/library/include/single_cpu/ippcp_p8.h new file mode 100644 index 000000000..0fac050ce --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_p8.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion p8_ippcpGetLibVersion +#define ippsDESGetSize p8_ippsDESGetSize +#define ippsDESInit p8_ippsDESInit +#define ippsDESPack p8_ippsDESPack +#define ippsDESUnpack p8_ippsDESUnpack +#define ippsTDESEncryptECB p8_ippsTDESEncryptECB +#define ippsTDESDecryptECB p8_ippsTDESDecryptECB +#define ippsTDESEncryptCBC p8_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC p8_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB p8_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB p8_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB p8_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB p8_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR p8_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR p8_ippsTDESDecryptCTR +#define ippsAESGetSize p8_ippsAESGetSize +#define ippsAESInit p8_ippsAESInit +#define ippsAESSetKey p8_ippsAESSetKey +#define ippsAESPack p8_ippsAESPack +#define ippsAESUnpack p8_ippsAESUnpack +#define ippsAESEncryptECB p8_ippsAESEncryptECB +#define ippsAESDecryptECB p8_ippsAESDecryptECB +#define ippsAESEncryptCBC p8_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 p8_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 p8_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 p8_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC p8_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 p8_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 p8_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 p8_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB p8_ippsAESEncryptCFB +#define ippsAESDecryptCFB p8_ippsAESDecryptCFB +#define ippsAESEncryptOFB p8_ippsAESEncryptOFB +#define ippsAESDecryptOFB p8_ippsAESDecryptOFB +#define ippsAESEncryptCTR p8_ippsAESEncryptCTR +#define ippsAESDecryptCTR p8_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct p8_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct p8_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise p8_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise p8_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise p8_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB p8_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize p8_ippsSMS4GetSize +#define ippsSMS4Init p8_ippsSMS4Init +#define ippsSMS4SetKey p8_ippsSMS4SetKey +#define ippsSMS4EncryptECB p8_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB p8_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC p8_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 p8_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 p8_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 p8_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC p8_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 p8_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 p8_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 p8_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB p8_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB p8_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB p8_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB p8_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR p8_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR p8_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize p8_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit p8_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen p8_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen p8_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart p8_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt p8_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt p8_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag p8_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize p8_ippsAES_CCMGetSize +#define ippsAES_CCMInit p8_ippsAES_CCMInit +#define ippsAES_CCMMessageLen p8_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen p8_ippsAES_CCMTagLen +#define ippsAES_CCMStart p8_ippsAES_CCMStart +#define ippsAES_CCMEncrypt p8_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt p8_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag p8_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize p8_ippsAES_GCMGetSize +#define ippsAES_GCMInit p8_ippsAES_GCMInit +#define ippsAES_GCMReinit p8_ippsAES_GCMReinit +#define ippsAES_GCMReset p8_ippsAES_GCMReset +#define ippsAES_GCMProcessIV p8_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD p8_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart p8_ippsAES_GCMStart +#define ippsAES_GCMEncrypt p8_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt p8_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag p8_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize p8_ippsAES_XTSGetSize +#define ippsAES_XTSInit p8_ippsAES_XTSInit +#define ippsAES_XTSEncrypt p8_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt p8_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC p8_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt p8_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt p8_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize p8_ippsAES_CMACGetSize +#define ippsAES_CMACInit p8_ippsAES_CMACInit +#define ippsAES_CMACUpdate p8_ippsAES_CMACUpdate +#define ippsAES_CMACFinal p8_ippsAES_CMACFinal +#define ippsAES_CMACGetTag p8_ippsAES_CMACGetTag +#define ippsARCFourCheckKey p8_ippsARCFourCheckKey +#define ippsARCFourGetSize p8_ippsARCFourGetSize +#define ippsARCFourInit p8_ippsARCFourInit +#define ippsARCFourReset p8_ippsARCFourReset +#define ippsARCFourPack p8_ippsARCFourPack +#define ippsARCFourUnpack p8_ippsARCFourUnpack +#define ippsARCFourEncrypt p8_ippsARCFourEncrypt +#define ippsARCFourDecrypt p8_ippsARCFourDecrypt +#define ippsSHA1GetSize p8_ippsSHA1GetSize +#define ippsSHA1Init p8_ippsSHA1Init +#define ippsSHA1Duplicate p8_ippsSHA1Duplicate +#define ippsSHA1Pack p8_ippsSHA1Pack +#define ippsSHA1Unpack p8_ippsSHA1Unpack +#define ippsSHA1Update p8_ippsSHA1Update +#define ippsSHA1GetTag p8_ippsSHA1GetTag +#define ippsSHA1Final p8_ippsSHA1Final +#define ippsSHA1MessageDigest p8_ippsSHA1MessageDigest +#define ippsSHA224GetSize p8_ippsSHA224GetSize +#define ippsSHA224Init p8_ippsSHA224Init +#define ippsSHA224Duplicate p8_ippsSHA224Duplicate +#define ippsSHA224Pack p8_ippsSHA224Pack +#define ippsSHA224Unpack p8_ippsSHA224Unpack +#define ippsSHA224Update p8_ippsSHA224Update +#define ippsSHA224GetTag p8_ippsSHA224GetTag +#define ippsSHA224Final p8_ippsSHA224Final +#define ippsSHA224MessageDigest p8_ippsSHA224MessageDigest +#define ippsSHA256GetSize p8_ippsSHA256GetSize +#define ippsSHA256Init p8_ippsSHA256Init +#define ippsSHA256Duplicate p8_ippsSHA256Duplicate +#define ippsSHA256Pack p8_ippsSHA256Pack +#define ippsSHA256Unpack p8_ippsSHA256Unpack +#define ippsSHA256Update p8_ippsSHA256Update +#define ippsSHA256GetTag p8_ippsSHA256GetTag +#define ippsSHA256Final p8_ippsSHA256Final +#define ippsSHA256MessageDigest p8_ippsSHA256MessageDigest +#define ippsSHA384GetSize p8_ippsSHA384GetSize +#define ippsSHA384Init p8_ippsSHA384Init +#define ippsSHA384Duplicate p8_ippsSHA384Duplicate +#define ippsSHA384Pack p8_ippsSHA384Pack +#define ippsSHA384Unpack p8_ippsSHA384Unpack +#define ippsSHA384Update p8_ippsSHA384Update +#define ippsSHA384GetTag p8_ippsSHA384GetTag +#define ippsSHA384Final p8_ippsSHA384Final +#define ippsSHA384MessageDigest p8_ippsSHA384MessageDigest +#define ippsSHA512GetSize p8_ippsSHA512GetSize +#define ippsSHA512Init p8_ippsSHA512Init +#define ippsSHA512Duplicate p8_ippsSHA512Duplicate +#define ippsSHA512Pack p8_ippsSHA512Pack +#define ippsSHA512Unpack p8_ippsSHA512Unpack +#define ippsSHA512Update p8_ippsSHA512Update +#define ippsSHA512GetTag p8_ippsSHA512GetTag +#define ippsSHA512Final p8_ippsSHA512Final +#define ippsSHA512MessageDigest p8_ippsSHA512MessageDigest +#define ippsMD5GetSize p8_ippsMD5GetSize +#define ippsMD5Init p8_ippsMD5Init +#define ippsMD5Duplicate p8_ippsMD5Duplicate +#define ippsMD5Pack p8_ippsMD5Pack +#define ippsMD5Unpack p8_ippsMD5Unpack +#define ippsMD5Update p8_ippsMD5Update +#define ippsMD5GetTag p8_ippsMD5GetTag +#define ippsMD5Final p8_ippsMD5Final +#define ippsMD5MessageDigest p8_ippsMD5MessageDigest +#define ippsSM3GetSize p8_ippsSM3GetSize +#define ippsSM3Init p8_ippsSM3Init +#define ippsSM3Duplicate p8_ippsSM3Duplicate +#define ippsSM3Pack p8_ippsSM3Pack +#define ippsSM3Unpack p8_ippsSM3Unpack +#define ippsSM3Update p8_ippsSM3Update +#define ippsSM3GetTag p8_ippsSM3GetTag +#define ippsSM3Final p8_ippsSM3Final +#define ippsSM3MessageDigest p8_ippsSM3MessageDigest +#define ippsHashGetSize p8_ippsHashGetSize +#define ippsHashInit p8_ippsHashInit +#define ippsHashPack p8_ippsHashPack +#define ippsHashUnpack p8_ippsHashUnpack +#define ippsHashDuplicate p8_ippsHashDuplicate +#define ippsHashUpdate p8_ippsHashUpdate +#define ippsHashGetTag p8_ippsHashGetTag +#define ippsHashFinal p8_ippsHashFinal +#define ippsHashMessage p8_ippsHashMessage +#define ippsHashMethod_MD5 p8_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 p8_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 p8_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI p8_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT p8_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 p8_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI p8_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT p8_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 p8_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI p8_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT p8_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 p8_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 p8_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 p8_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 p8_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize p8_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 p8_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 p8_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 p8_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 p8_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI p8_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT p8_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 p8_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI p8_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT p8_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 p8_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI p8_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT p8_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 p8_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI p8_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT p8_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 p8_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI p8_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT p8_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 p8_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 p8_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 p8_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 p8_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 p8_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 p8_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 p8_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 p8_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf p8_ippsHashGetSize_rmf +#define ippsHashInit_rmf p8_ippsHashInit_rmf +#define ippsHashPack_rmf p8_ippsHashPack_rmf +#define ippsHashUnpack_rmf p8_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf p8_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf p8_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf p8_ippsHashGetTag_rmf +#define ippsHashFinal_rmf p8_ippsHashFinal_rmf +#define ippsHashMessage_rmf p8_ippsHashMessage_rmf +#define ippsHashMethodGetInfo p8_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf p8_ippsHashGetInfo_rmf +#define ippsMGF p8_ippsMGF +#define ippsMGF1_rmf p8_ippsMGF1_rmf +#define ippsMGF2_rmf p8_ippsMGF2_rmf +#define ippsHMAC_GetSize p8_ippsHMAC_GetSize +#define ippsHMAC_Init p8_ippsHMAC_Init +#define ippsHMAC_Pack p8_ippsHMAC_Pack +#define ippsHMAC_Unpack p8_ippsHMAC_Unpack +#define ippsHMAC_Duplicate p8_ippsHMAC_Duplicate +#define ippsHMAC_Update p8_ippsHMAC_Update +#define ippsHMAC_Final p8_ippsHMAC_Final +#define ippsHMAC_GetTag p8_ippsHMAC_GetTag +#define ippsHMAC_Message p8_ippsHMAC_Message +#define ippsHMACGetSize_rmf p8_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf p8_ippsHMACInit_rmf +#define ippsHMACPack_rmf p8_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf p8_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf p8_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf p8_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf p8_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf p8_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf p8_ippsHMACMessage_rmf +#define ippsBigNumGetSize p8_ippsBigNumGetSize +#define ippsBigNumInit p8_ippsBigNumInit +#define ippsCmpZero_BN p8_ippsCmpZero_BN +#define ippsCmp_BN p8_ippsCmp_BN +#define ippsGetSize_BN p8_ippsGetSize_BN +#define ippsSet_BN p8_ippsSet_BN +#define ippsGet_BN p8_ippsGet_BN +#define ippsRef_BN p8_ippsRef_BN +#define ippsExtGet_BN p8_ippsExtGet_BN +#define ippsAdd_BN p8_ippsAdd_BN +#define ippsSub_BN p8_ippsSub_BN +#define ippsMul_BN p8_ippsMul_BN +#define ippsMAC_BN_I p8_ippsMAC_BN_I +#define ippsDiv_BN p8_ippsDiv_BN +#define ippsMod_BN p8_ippsMod_BN +#define ippsGcd_BN p8_ippsGcd_BN +#define ippsModInv_BN p8_ippsModInv_BN +#define ippsSetOctString_BN p8_ippsSetOctString_BN +#define ippsGetOctString_BN p8_ippsGetOctString_BN +#define ippsMontGetSize p8_ippsMontGetSize +#define ippsMontInit p8_ippsMontInit +#define ippsMontSet p8_ippsMontSet +#define ippsMontGet p8_ippsMontGet +#define ippsMontForm p8_ippsMontForm +#define ippsMontMul p8_ippsMontMul +#define ippsMontExp p8_ippsMontExp +#define ippsPRNGGetSize p8_ippsPRNGGetSize +#define ippsPRNGInit p8_ippsPRNGInit +#define ippsPRNGSetModulus p8_ippsPRNGSetModulus +#define ippsPRNGSetH0 p8_ippsPRNGSetH0 +#define ippsPRNGSetAugment p8_ippsPRNGSetAugment +#define ippsPRNGSetSeed p8_ippsPRNGSetSeed +#define ippsPRNGGetSeed p8_ippsPRNGGetSeed +#define ippsPRNGen p8_ippsPRNGen +#define ippsPRNGen_BN p8_ippsPRNGen_BN +#define ippsPRNGenRDRAND p8_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN p8_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED p8_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN p8_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize p8_ippsPrimeGetSize +#define ippsPrimeInit p8_ippsPrimeInit +#define ippsPrimeGen p8_ippsPrimeGen +#define ippsPrimeTest p8_ippsPrimeTest +#define ippsPrimeGen_BN p8_ippsPrimeGen_BN +#define ippsPrimeTest_BN p8_ippsPrimeTest_BN +#define ippsPrimeGet p8_ippsPrimeGet +#define ippsPrimeGet_BN p8_ippsPrimeGet_BN +#define ippsPrimeSet p8_ippsPrimeSet +#define ippsPrimeSet_BN p8_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey p8_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey p8_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey p8_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey p8_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 p8_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 p8_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 p8_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 p8_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 p8_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 p8_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 p8_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 p8_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey p8_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey p8_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt p8_ippsRSA_Encrypt +#define ippsRSA_Decrypt p8_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys p8_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys p8_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP p8_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP p8_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf p8_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf p8_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 p8_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 p8_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS p8_ippsRSASign_PSS +#define ippsRSAVerify_PSS p8_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf p8_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf p8_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 p8_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 p8_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf p8_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf p8_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString p8_ippsDLGetResultString +#define ippsDLPGetSize p8_ippsDLPGetSize +#define ippsDLPInit p8_ippsDLPInit +#define ippsDLPPack p8_ippsDLPPack +#define ippsDLPUnpack p8_ippsDLPUnpack +#define ippsDLPSet p8_ippsDLPSet +#define ippsDLPGet p8_ippsDLPGet +#define ippsDLPSetDP p8_ippsDLPSetDP +#define ippsDLPGetDP p8_ippsDLPGetDP +#define ippsDLPGenKeyPair p8_ippsDLPGenKeyPair +#define ippsDLPPublicKey p8_ippsDLPPublicKey +#define ippsDLPValidateKeyPair p8_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair p8_ippsDLPSetKeyPair +#define ippsDLPSignDSA p8_ippsDLPSignDSA +#define ippsDLPVerifyDSA p8_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH p8_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA p8_ippsDLPGenerateDSA +#define ippsDLPValidateDSA p8_ippsDLPValidateDSA +#define ippsDLPGenerateDH p8_ippsDLPGenerateDH +#define ippsDLPValidateDH p8_ippsDLPValidateDH +#define ippsECCGetResultString p8_ippsECCGetResultString +#define ippsECCPGetSize p8_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 p8_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 p8_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 p8_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 p8_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 p8_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 p8_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 p8_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 p8_ippsECCPGetSizeStdSM2 +#define ippsECCPInit p8_ippsECCPInit +#define ippsECCPInitStd128r1 p8_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 p8_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 p8_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 p8_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 p8_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 p8_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 p8_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 p8_ippsECCPInitStdSM2 +#define ippsECCPSet p8_ippsECCPSet +#define ippsECCPSetStd p8_ippsECCPSetStd +#define ippsECCPSetStd128r1 p8_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 p8_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 p8_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 p8_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 p8_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 p8_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 p8_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 p8_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 p8_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 p8_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 p8_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 p8_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 p8_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 p8_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet p8_ippsECCPGet +#define ippsECCPGetOrderBitSize p8_ippsECCPGetOrderBitSize +#define ippsECCPValidate p8_ippsECCPValidate +#define ippsECCPPointGetSize p8_ippsECCPPointGetSize +#define ippsECCPPointInit p8_ippsECCPPointInit +#define ippsECCPSetPoint p8_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity p8_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint p8_ippsECCPGetPoint +#define ippsECCPCheckPoint p8_ippsECCPCheckPoint +#define ippsECCPComparePoint p8_ippsECCPComparePoint +#define ippsECCPNegativePoint p8_ippsECCPNegativePoint +#define ippsECCPAddPoint p8_ippsECCPAddPoint +#define ippsECCPMulPointScalar p8_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair p8_ippsECCPGenKeyPair +#define ippsECCPPublicKey p8_ippsECCPPublicKey +#define ippsECCPValidateKeyPair p8_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair p8_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH p8_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC p8_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA p8_ippsECCPSignDSA +#define ippsECCPVerifyDSA p8_ippsECCPVerifyDSA +#define ippsECCPSignNR p8_ippsECCPSignNR +#define ippsECCPVerifyNR p8_ippsECCPVerifyNR +#define ippsECCPSignSM2 p8_ippsECCPSignSM2 +#define ippsECCPVerifySM2 p8_ippsECCPVerifySM2 +#define ippsGFpGetSize p8_ippsGFpGetSize +#define ippsGFpInitArbitrary p8_ippsGFpInitArbitrary +#define ippsGFpInitFixed p8_ippsGFpInitFixed +#define ippsGFpInit p8_ippsGFpInit +#define ippsGFpMethod_p192r1 p8_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 p8_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 p8_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 p8_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 p8_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 p8_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn p8_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 p8_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb p8_ippsGFpMethod_pArb +#define ippsGFpxGetSize p8_ippsGFpxGetSize +#define ippsGFpxInit p8_ippsGFpxInit +#define ippsGFpxInitBinomial p8_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 p8_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 p8_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 p8_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 p8_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom p8_ippsGFpxMethod_binom +#define ippsGFpxMethod_com p8_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize p8_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize p8_ippsGFpElementGetSize +#define ippsGFpElementInit p8_ippsGFpElementInit +#define ippsGFpSetElement p8_ippsGFpSetElement +#define ippsGFpSetElementRegular p8_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString p8_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom p8_ippsGFpSetElementRandom +#define ippsGFpSetElementHash p8_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf p8_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement p8_ippsGFpCpyElement +#define ippsGFpGetElement p8_ippsGFpGetElement +#define ippsGFpGetElementOctString p8_ippsGFpGetElementOctString +#define ippsGFpCmpElement p8_ippsGFpCmpElement +#define ippsGFpIsZeroElement p8_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement p8_ippsGFpIsUnityElement +#define ippsGFpConj p8_ippsGFpConj +#define ippsGFpNeg p8_ippsGFpNeg +#define ippsGFpInv p8_ippsGFpInv +#define ippsGFpSqrt p8_ippsGFpSqrt +#define ippsGFpSqr p8_ippsGFpSqr +#define ippsGFpAdd p8_ippsGFpAdd +#define ippsGFpSub p8_ippsGFpSub +#define ippsGFpMul p8_ippsGFpMul +#define ippsGFpExp p8_ippsGFpExp +#define ippsGFpMultiExp p8_ippsGFpMultiExp +#define ippsGFpAdd_PE p8_ippsGFpAdd_PE +#define ippsGFpSub_PE p8_ippsGFpSub_PE +#define ippsGFpMul_PE p8_ippsGFpMul_PE +#define ippsGFpGetInfo p8_ippsGFpGetInfo +#define ippsGFpECGetSize p8_ippsGFpECGetSize +#define ippsGFpECInit p8_ippsGFpECInit +#define ippsGFpECSet p8_ippsGFpECSet +#define ippsGFpECSetSubgroup p8_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 p8_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 p8_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 p8_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 p8_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 p8_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 p8_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 p8_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 p8_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 p8_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 p8_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 p8_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 p8_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 p8_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 p8_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 p8_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet p8_ippsGFpECGet +#define ippsGFpECGetSubgroup p8_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize p8_ippsGFpECScratchBufferSize +#define ippsGFpECVerify p8_ippsGFpECVerify +#define ippsGFpECPointGetSize p8_ippsGFpECPointGetSize +#define ippsGFpECPointInit p8_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity p8_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint p8_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular p8_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom p8_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint p8_ippsGFpECMakePoint +#define ippsGFpECSetPointHash p8_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible p8_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf p8_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf p8_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint p8_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular p8_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString p8_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString p8_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint p8_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup p8_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint p8_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint p8_ippsGFpECCmpPoint +#define ippsGFpECNegPoint p8_ippsGFpECNegPoint +#define ippsGFpECAddPoint p8_ippsGFpECAddPoint +#define ippsGFpECMulPoint p8_ippsGFpECMulPoint +#define ippsGFpECPrivateKey p8_ippsGFpECPrivateKey +#define ippsGFpECPublicKey p8_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair p8_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH p8_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC p8_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 p8_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA p8_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA p8_ippsGFpECVerifyDSA +#define ippsGFpECSignNR p8_ippsGFpECSignNR +#define ippsGFpECVerifyNR p8_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 p8_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 p8_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 p8_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize p8_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init p8_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup p8_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey p8_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm p8_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF p8_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 p8_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 p8_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 p8_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 p8_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 p8_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 p8_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 p8_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 p8_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize p8_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext p8_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize p8_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext p8_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_s8.h b/plugin/ippcp/library/include/single_cpu/ippcp_s8.h new file mode 100644 index 000000000..ec0f35a61 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_s8.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion s8_ippcpGetLibVersion +#define ippsDESGetSize s8_ippsDESGetSize +#define ippsDESInit s8_ippsDESInit +#define ippsDESPack s8_ippsDESPack +#define ippsDESUnpack s8_ippsDESUnpack +#define ippsTDESEncryptECB s8_ippsTDESEncryptECB +#define ippsTDESDecryptECB s8_ippsTDESDecryptECB +#define ippsTDESEncryptCBC s8_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC s8_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB s8_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB s8_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB s8_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB s8_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR s8_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR s8_ippsTDESDecryptCTR +#define ippsAESGetSize s8_ippsAESGetSize +#define ippsAESInit s8_ippsAESInit +#define ippsAESSetKey s8_ippsAESSetKey +#define ippsAESPack s8_ippsAESPack +#define ippsAESUnpack s8_ippsAESUnpack +#define ippsAESEncryptECB s8_ippsAESEncryptECB +#define ippsAESDecryptECB s8_ippsAESDecryptECB +#define ippsAESEncryptCBC s8_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 s8_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 s8_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 s8_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC s8_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 s8_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 s8_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 s8_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB s8_ippsAESEncryptCFB +#define ippsAESDecryptCFB s8_ippsAESDecryptCFB +#define ippsAESEncryptOFB s8_ippsAESEncryptOFB +#define ippsAESDecryptOFB s8_ippsAESDecryptOFB +#define ippsAESEncryptCTR s8_ippsAESEncryptCTR +#define ippsAESDecryptCTR s8_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct s8_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct s8_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise s8_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise s8_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise s8_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB s8_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize s8_ippsSMS4GetSize +#define ippsSMS4Init s8_ippsSMS4Init +#define ippsSMS4SetKey s8_ippsSMS4SetKey +#define ippsSMS4EncryptECB s8_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB s8_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC s8_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 s8_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 s8_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 s8_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC s8_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 s8_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 s8_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 s8_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB s8_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB s8_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB s8_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB s8_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR s8_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR s8_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize s8_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit s8_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen s8_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen s8_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart s8_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt s8_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt s8_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag s8_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize s8_ippsAES_CCMGetSize +#define ippsAES_CCMInit s8_ippsAES_CCMInit +#define ippsAES_CCMMessageLen s8_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen s8_ippsAES_CCMTagLen +#define ippsAES_CCMStart s8_ippsAES_CCMStart +#define ippsAES_CCMEncrypt s8_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt s8_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag s8_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize s8_ippsAES_GCMGetSize +#define ippsAES_GCMInit s8_ippsAES_GCMInit +#define ippsAES_GCMReinit s8_ippsAES_GCMReinit +#define ippsAES_GCMReset s8_ippsAES_GCMReset +#define ippsAES_GCMProcessIV s8_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD s8_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart s8_ippsAES_GCMStart +#define ippsAES_GCMEncrypt s8_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt s8_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag s8_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize s8_ippsAES_XTSGetSize +#define ippsAES_XTSInit s8_ippsAES_XTSInit +#define ippsAES_XTSEncrypt s8_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt s8_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC s8_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt s8_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt s8_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize s8_ippsAES_CMACGetSize +#define ippsAES_CMACInit s8_ippsAES_CMACInit +#define ippsAES_CMACUpdate s8_ippsAES_CMACUpdate +#define ippsAES_CMACFinal s8_ippsAES_CMACFinal +#define ippsAES_CMACGetTag s8_ippsAES_CMACGetTag +#define ippsARCFourCheckKey s8_ippsARCFourCheckKey +#define ippsARCFourGetSize s8_ippsARCFourGetSize +#define ippsARCFourInit s8_ippsARCFourInit +#define ippsARCFourReset s8_ippsARCFourReset +#define ippsARCFourPack s8_ippsARCFourPack +#define ippsARCFourUnpack s8_ippsARCFourUnpack +#define ippsARCFourEncrypt s8_ippsARCFourEncrypt +#define ippsARCFourDecrypt s8_ippsARCFourDecrypt +#define ippsSHA1GetSize s8_ippsSHA1GetSize +#define ippsSHA1Init s8_ippsSHA1Init +#define ippsSHA1Duplicate s8_ippsSHA1Duplicate +#define ippsSHA1Pack s8_ippsSHA1Pack +#define ippsSHA1Unpack s8_ippsSHA1Unpack +#define ippsSHA1Update s8_ippsSHA1Update +#define ippsSHA1GetTag s8_ippsSHA1GetTag +#define ippsSHA1Final s8_ippsSHA1Final +#define ippsSHA1MessageDigest s8_ippsSHA1MessageDigest +#define ippsSHA224GetSize s8_ippsSHA224GetSize +#define ippsSHA224Init s8_ippsSHA224Init +#define ippsSHA224Duplicate s8_ippsSHA224Duplicate +#define ippsSHA224Pack s8_ippsSHA224Pack +#define ippsSHA224Unpack s8_ippsSHA224Unpack +#define ippsSHA224Update s8_ippsSHA224Update +#define ippsSHA224GetTag s8_ippsSHA224GetTag +#define ippsSHA224Final s8_ippsSHA224Final +#define ippsSHA224MessageDigest s8_ippsSHA224MessageDigest +#define ippsSHA256GetSize s8_ippsSHA256GetSize +#define ippsSHA256Init s8_ippsSHA256Init +#define ippsSHA256Duplicate s8_ippsSHA256Duplicate +#define ippsSHA256Pack s8_ippsSHA256Pack +#define ippsSHA256Unpack s8_ippsSHA256Unpack +#define ippsSHA256Update s8_ippsSHA256Update +#define ippsSHA256GetTag s8_ippsSHA256GetTag +#define ippsSHA256Final s8_ippsSHA256Final +#define ippsSHA256MessageDigest s8_ippsSHA256MessageDigest +#define ippsSHA384GetSize s8_ippsSHA384GetSize +#define ippsSHA384Init s8_ippsSHA384Init +#define ippsSHA384Duplicate s8_ippsSHA384Duplicate +#define ippsSHA384Pack s8_ippsSHA384Pack +#define ippsSHA384Unpack s8_ippsSHA384Unpack +#define ippsSHA384Update s8_ippsSHA384Update +#define ippsSHA384GetTag s8_ippsSHA384GetTag +#define ippsSHA384Final s8_ippsSHA384Final +#define ippsSHA384MessageDigest s8_ippsSHA384MessageDigest +#define ippsSHA512GetSize s8_ippsSHA512GetSize +#define ippsSHA512Init s8_ippsSHA512Init +#define ippsSHA512Duplicate s8_ippsSHA512Duplicate +#define ippsSHA512Pack s8_ippsSHA512Pack +#define ippsSHA512Unpack s8_ippsSHA512Unpack +#define ippsSHA512Update s8_ippsSHA512Update +#define ippsSHA512GetTag s8_ippsSHA512GetTag +#define ippsSHA512Final s8_ippsSHA512Final +#define ippsSHA512MessageDigest s8_ippsSHA512MessageDigest +#define ippsMD5GetSize s8_ippsMD5GetSize +#define ippsMD5Init s8_ippsMD5Init +#define ippsMD5Duplicate s8_ippsMD5Duplicate +#define ippsMD5Pack s8_ippsMD5Pack +#define ippsMD5Unpack s8_ippsMD5Unpack +#define ippsMD5Update s8_ippsMD5Update +#define ippsMD5GetTag s8_ippsMD5GetTag +#define ippsMD5Final s8_ippsMD5Final +#define ippsMD5MessageDigest s8_ippsMD5MessageDigest +#define ippsSM3GetSize s8_ippsSM3GetSize +#define ippsSM3Init s8_ippsSM3Init +#define ippsSM3Duplicate s8_ippsSM3Duplicate +#define ippsSM3Pack s8_ippsSM3Pack +#define ippsSM3Unpack s8_ippsSM3Unpack +#define ippsSM3Update s8_ippsSM3Update +#define ippsSM3GetTag s8_ippsSM3GetTag +#define ippsSM3Final s8_ippsSM3Final +#define ippsSM3MessageDigest s8_ippsSM3MessageDigest +#define ippsHashGetSize s8_ippsHashGetSize +#define ippsHashInit s8_ippsHashInit +#define ippsHashPack s8_ippsHashPack +#define ippsHashUnpack s8_ippsHashUnpack +#define ippsHashDuplicate s8_ippsHashDuplicate +#define ippsHashUpdate s8_ippsHashUpdate +#define ippsHashGetTag s8_ippsHashGetTag +#define ippsHashFinal s8_ippsHashFinal +#define ippsHashMessage s8_ippsHashMessage +#define ippsHashMethod_MD5 s8_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 s8_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 s8_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI s8_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT s8_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 s8_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI s8_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT s8_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 s8_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI s8_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT s8_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 s8_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 s8_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 s8_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 s8_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize s8_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 s8_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 s8_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 s8_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 s8_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI s8_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT s8_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 s8_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI s8_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT s8_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 s8_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI s8_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT s8_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 s8_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI s8_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT s8_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 s8_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI s8_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT s8_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 s8_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 s8_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 s8_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 s8_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 s8_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 s8_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 s8_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 s8_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf s8_ippsHashGetSize_rmf +#define ippsHashInit_rmf s8_ippsHashInit_rmf +#define ippsHashPack_rmf s8_ippsHashPack_rmf +#define ippsHashUnpack_rmf s8_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf s8_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf s8_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf s8_ippsHashGetTag_rmf +#define ippsHashFinal_rmf s8_ippsHashFinal_rmf +#define ippsHashMessage_rmf s8_ippsHashMessage_rmf +#define ippsHashMethodGetInfo s8_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf s8_ippsHashGetInfo_rmf +#define ippsMGF s8_ippsMGF +#define ippsMGF1_rmf s8_ippsMGF1_rmf +#define ippsMGF2_rmf s8_ippsMGF2_rmf +#define ippsHMAC_GetSize s8_ippsHMAC_GetSize +#define ippsHMAC_Init s8_ippsHMAC_Init +#define ippsHMAC_Pack s8_ippsHMAC_Pack +#define ippsHMAC_Unpack s8_ippsHMAC_Unpack +#define ippsHMAC_Duplicate s8_ippsHMAC_Duplicate +#define ippsHMAC_Update s8_ippsHMAC_Update +#define ippsHMAC_Final s8_ippsHMAC_Final +#define ippsHMAC_GetTag s8_ippsHMAC_GetTag +#define ippsHMAC_Message s8_ippsHMAC_Message +#define ippsHMACGetSize_rmf s8_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf s8_ippsHMACInit_rmf +#define ippsHMACPack_rmf s8_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf s8_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf s8_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf s8_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf s8_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf s8_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf s8_ippsHMACMessage_rmf +#define ippsBigNumGetSize s8_ippsBigNumGetSize +#define ippsBigNumInit s8_ippsBigNumInit +#define ippsCmpZero_BN s8_ippsCmpZero_BN +#define ippsCmp_BN s8_ippsCmp_BN +#define ippsGetSize_BN s8_ippsGetSize_BN +#define ippsSet_BN s8_ippsSet_BN +#define ippsGet_BN s8_ippsGet_BN +#define ippsRef_BN s8_ippsRef_BN +#define ippsExtGet_BN s8_ippsExtGet_BN +#define ippsAdd_BN s8_ippsAdd_BN +#define ippsSub_BN s8_ippsSub_BN +#define ippsMul_BN s8_ippsMul_BN +#define ippsMAC_BN_I s8_ippsMAC_BN_I +#define ippsDiv_BN s8_ippsDiv_BN +#define ippsMod_BN s8_ippsMod_BN +#define ippsGcd_BN s8_ippsGcd_BN +#define ippsModInv_BN s8_ippsModInv_BN +#define ippsSetOctString_BN s8_ippsSetOctString_BN +#define ippsGetOctString_BN s8_ippsGetOctString_BN +#define ippsMontGetSize s8_ippsMontGetSize +#define ippsMontInit s8_ippsMontInit +#define ippsMontSet s8_ippsMontSet +#define ippsMontGet s8_ippsMontGet +#define ippsMontForm s8_ippsMontForm +#define ippsMontMul s8_ippsMontMul +#define ippsMontExp s8_ippsMontExp +#define ippsPRNGGetSize s8_ippsPRNGGetSize +#define ippsPRNGInit s8_ippsPRNGInit +#define ippsPRNGSetModulus s8_ippsPRNGSetModulus +#define ippsPRNGSetH0 s8_ippsPRNGSetH0 +#define ippsPRNGSetAugment s8_ippsPRNGSetAugment +#define ippsPRNGSetSeed s8_ippsPRNGSetSeed +#define ippsPRNGGetSeed s8_ippsPRNGGetSeed +#define ippsPRNGen s8_ippsPRNGen +#define ippsPRNGen_BN s8_ippsPRNGen_BN +#define ippsPRNGenRDRAND s8_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN s8_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED s8_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN s8_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize s8_ippsPrimeGetSize +#define ippsPrimeInit s8_ippsPrimeInit +#define ippsPrimeGen s8_ippsPrimeGen +#define ippsPrimeTest s8_ippsPrimeTest +#define ippsPrimeGen_BN s8_ippsPrimeGen_BN +#define ippsPrimeTest_BN s8_ippsPrimeTest_BN +#define ippsPrimeGet s8_ippsPrimeGet +#define ippsPrimeGet_BN s8_ippsPrimeGet_BN +#define ippsPrimeSet s8_ippsPrimeSet +#define ippsPrimeSet_BN s8_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey s8_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey s8_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey s8_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey s8_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 s8_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 s8_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 s8_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 s8_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 s8_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 s8_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 s8_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 s8_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey s8_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey s8_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt s8_ippsRSA_Encrypt +#define ippsRSA_Decrypt s8_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys s8_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys s8_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP s8_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP s8_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf s8_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf s8_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 s8_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 s8_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS s8_ippsRSASign_PSS +#define ippsRSAVerify_PSS s8_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf s8_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf s8_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 s8_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 s8_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf s8_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf s8_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString s8_ippsDLGetResultString +#define ippsDLPGetSize s8_ippsDLPGetSize +#define ippsDLPInit s8_ippsDLPInit +#define ippsDLPPack s8_ippsDLPPack +#define ippsDLPUnpack s8_ippsDLPUnpack +#define ippsDLPSet s8_ippsDLPSet +#define ippsDLPGet s8_ippsDLPGet +#define ippsDLPSetDP s8_ippsDLPSetDP +#define ippsDLPGetDP s8_ippsDLPGetDP +#define ippsDLPGenKeyPair s8_ippsDLPGenKeyPair +#define ippsDLPPublicKey s8_ippsDLPPublicKey +#define ippsDLPValidateKeyPair s8_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair s8_ippsDLPSetKeyPair +#define ippsDLPSignDSA s8_ippsDLPSignDSA +#define ippsDLPVerifyDSA s8_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH s8_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA s8_ippsDLPGenerateDSA +#define ippsDLPValidateDSA s8_ippsDLPValidateDSA +#define ippsDLPGenerateDH s8_ippsDLPGenerateDH +#define ippsDLPValidateDH s8_ippsDLPValidateDH +#define ippsECCGetResultString s8_ippsECCGetResultString +#define ippsECCPGetSize s8_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 s8_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 s8_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 s8_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 s8_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 s8_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 s8_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 s8_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 s8_ippsECCPGetSizeStdSM2 +#define ippsECCPInit s8_ippsECCPInit +#define ippsECCPInitStd128r1 s8_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 s8_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 s8_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 s8_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 s8_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 s8_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 s8_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 s8_ippsECCPInitStdSM2 +#define ippsECCPSet s8_ippsECCPSet +#define ippsECCPSetStd s8_ippsECCPSetStd +#define ippsECCPSetStd128r1 s8_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 s8_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 s8_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 s8_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 s8_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 s8_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 s8_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 s8_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 s8_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 s8_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 s8_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 s8_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 s8_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 s8_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet s8_ippsECCPGet +#define ippsECCPGetOrderBitSize s8_ippsECCPGetOrderBitSize +#define ippsECCPValidate s8_ippsECCPValidate +#define ippsECCPPointGetSize s8_ippsECCPPointGetSize +#define ippsECCPPointInit s8_ippsECCPPointInit +#define ippsECCPSetPoint s8_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity s8_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint s8_ippsECCPGetPoint +#define ippsECCPCheckPoint s8_ippsECCPCheckPoint +#define ippsECCPComparePoint s8_ippsECCPComparePoint +#define ippsECCPNegativePoint s8_ippsECCPNegativePoint +#define ippsECCPAddPoint s8_ippsECCPAddPoint +#define ippsECCPMulPointScalar s8_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair s8_ippsECCPGenKeyPair +#define ippsECCPPublicKey s8_ippsECCPPublicKey +#define ippsECCPValidateKeyPair s8_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair s8_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH s8_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC s8_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA s8_ippsECCPSignDSA +#define ippsECCPVerifyDSA s8_ippsECCPVerifyDSA +#define ippsECCPSignNR s8_ippsECCPSignNR +#define ippsECCPVerifyNR s8_ippsECCPVerifyNR +#define ippsECCPSignSM2 s8_ippsECCPSignSM2 +#define ippsECCPVerifySM2 s8_ippsECCPVerifySM2 +#define ippsGFpGetSize s8_ippsGFpGetSize +#define ippsGFpInitArbitrary s8_ippsGFpInitArbitrary +#define ippsGFpInitFixed s8_ippsGFpInitFixed +#define ippsGFpInit s8_ippsGFpInit +#define ippsGFpMethod_p192r1 s8_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 s8_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 s8_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 s8_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 s8_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 s8_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn s8_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 s8_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb s8_ippsGFpMethod_pArb +#define ippsGFpxGetSize s8_ippsGFpxGetSize +#define ippsGFpxInit s8_ippsGFpxInit +#define ippsGFpxInitBinomial s8_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 s8_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 s8_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 s8_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 s8_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom s8_ippsGFpxMethod_binom +#define ippsGFpxMethod_com s8_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize s8_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize s8_ippsGFpElementGetSize +#define ippsGFpElementInit s8_ippsGFpElementInit +#define ippsGFpSetElement s8_ippsGFpSetElement +#define ippsGFpSetElementRegular s8_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString s8_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom s8_ippsGFpSetElementRandom +#define ippsGFpSetElementHash s8_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf s8_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement s8_ippsGFpCpyElement +#define ippsGFpGetElement s8_ippsGFpGetElement +#define ippsGFpGetElementOctString s8_ippsGFpGetElementOctString +#define ippsGFpCmpElement s8_ippsGFpCmpElement +#define ippsGFpIsZeroElement s8_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement s8_ippsGFpIsUnityElement +#define ippsGFpConj s8_ippsGFpConj +#define ippsGFpNeg s8_ippsGFpNeg +#define ippsGFpInv s8_ippsGFpInv +#define ippsGFpSqrt s8_ippsGFpSqrt +#define ippsGFpSqr s8_ippsGFpSqr +#define ippsGFpAdd s8_ippsGFpAdd +#define ippsGFpSub s8_ippsGFpSub +#define ippsGFpMul s8_ippsGFpMul +#define ippsGFpExp s8_ippsGFpExp +#define ippsGFpMultiExp s8_ippsGFpMultiExp +#define ippsGFpAdd_PE s8_ippsGFpAdd_PE +#define ippsGFpSub_PE s8_ippsGFpSub_PE +#define ippsGFpMul_PE s8_ippsGFpMul_PE +#define ippsGFpGetInfo s8_ippsGFpGetInfo +#define ippsGFpECGetSize s8_ippsGFpECGetSize +#define ippsGFpECInit s8_ippsGFpECInit +#define ippsGFpECSet s8_ippsGFpECSet +#define ippsGFpECSetSubgroup s8_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 s8_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 s8_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 s8_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 s8_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 s8_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 s8_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 s8_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 s8_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 s8_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 s8_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 s8_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 s8_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 s8_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 s8_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 s8_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet s8_ippsGFpECGet +#define ippsGFpECGetSubgroup s8_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize s8_ippsGFpECScratchBufferSize +#define ippsGFpECVerify s8_ippsGFpECVerify +#define ippsGFpECPointGetSize s8_ippsGFpECPointGetSize +#define ippsGFpECPointInit s8_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity s8_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint s8_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular s8_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom s8_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint s8_ippsGFpECMakePoint +#define ippsGFpECSetPointHash s8_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible s8_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf s8_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf s8_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint s8_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular s8_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString s8_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString s8_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint s8_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup s8_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint s8_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint s8_ippsGFpECCmpPoint +#define ippsGFpECNegPoint s8_ippsGFpECNegPoint +#define ippsGFpECAddPoint s8_ippsGFpECAddPoint +#define ippsGFpECMulPoint s8_ippsGFpECMulPoint +#define ippsGFpECPrivateKey s8_ippsGFpECPrivateKey +#define ippsGFpECPublicKey s8_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair s8_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH s8_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC s8_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 s8_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA s8_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA s8_ippsGFpECVerifyDSA +#define ippsGFpECSignNR s8_ippsGFpECSignNR +#define ippsGFpECVerifyNR s8_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 s8_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 s8_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 s8_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize s8_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init s8_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup s8_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey s8_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm s8_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF s8_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 s8_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 s8_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 s8_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 s8_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 s8_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 s8_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 s8_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 s8_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize s8_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext s8_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize s8_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext s8_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_w7.h b/plugin/ippcp/library/include/single_cpu/ippcp_w7.h new file mode 100644 index 000000000..5ddea08c8 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_w7.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion w7_ippcpGetLibVersion +#define ippsDESGetSize w7_ippsDESGetSize +#define ippsDESInit w7_ippsDESInit +#define ippsDESPack w7_ippsDESPack +#define ippsDESUnpack w7_ippsDESUnpack +#define ippsTDESEncryptECB w7_ippsTDESEncryptECB +#define ippsTDESDecryptECB w7_ippsTDESDecryptECB +#define ippsTDESEncryptCBC w7_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC w7_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB w7_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB w7_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB w7_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB w7_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR w7_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR w7_ippsTDESDecryptCTR +#define ippsAESGetSize w7_ippsAESGetSize +#define ippsAESInit w7_ippsAESInit +#define ippsAESSetKey w7_ippsAESSetKey +#define ippsAESPack w7_ippsAESPack +#define ippsAESUnpack w7_ippsAESUnpack +#define ippsAESEncryptECB w7_ippsAESEncryptECB +#define ippsAESDecryptECB w7_ippsAESDecryptECB +#define ippsAESEncryptCBC w7_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 w7_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 w7_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 w7_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC w7_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 w7_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 w7_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 w7_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB w7_ippsAESEncryptCFB +#define ippsAESDecryptCFB w7_ippsAESDecryptCFB +#define ippsAESEncryptOFB w7_ippsAESEncryptOFB +#define ippsAESDecryptOFB w7_ippsAESDecryptOFB +#define ippsAESEncryptCTR w7_ippsAESEncryptCTR +#define ippsAESDecryptCTR w7_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct w7_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct w7_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise w7_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise w7_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise w7_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB w7_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize w7_ippsSMS4GetSize +#define ippsSMS4Init w7_ippsSMS4Init +#define ippsSMS4SetKey w7_ippsSMS4SetKey +#define ippsSMS4EncryptECB w7_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB w7_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC w7_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 w7_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 w7_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 w7_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC w7_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 w7_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 w7_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 w7_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB w7_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB w7_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB w7_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB w7_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR w7_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR w7_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize w7_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit w7_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen w7_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen w7_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart w7_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt w7_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt w7_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag w7_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize w7_ippsAES_CCMGetSize +#define ippsAES_CCMInit w7_ippsAES_CCMInit +#define ippsAES_CCMMessageLen w7_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen w7_ippsAES_CCMTagLen +#define ippsAES_CCMStart w7_ippsAES_CCMStart +#define ippsAES_CCMEncrypt w7_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt w7_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag w7_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize w7_ippsAES_GCMGetSize +#define ippsAES_GCMInit w7_ippsAES_GCMInit +#define ippsAES_GCMReinit w7_ippsAES_GCMReinit +#define ippsAES_GCMReset w7_ippsAES_GCMReset +#define ippsAES_GCMProcessIV w7_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD w7_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart w7_ippsAES_GCMStart +#define ippsAES_GCMEncrypt w7_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt w7_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag w7_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize w7_ippsAES_XTSGetSize +#define ippsAES_XTSInit w7_ippsAES_XTSInit +#define ippsAES_XTSEncrypt w7_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt w7_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC w7_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt w7_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt w7_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize w7_ippsAES_CMACGetSize +#define ippsAES_CMACInit w7_ippsAES_CMACInit +#define ippsAES_CMACUpdate w7_ippsAES_CMACUpdate +#define ippsAES_CMACFinal w7_ippsAES_CMACFinal +#define ippsAES_CMACGetTag w7_ippsAES_CMACGetTag +#define ippsARCFourCheckKey w7_ippsARCFourCheckKey +#define ippsARCFourGetSize w7_ippsARCFourGetSize +#define ippsARCFourInit w7_ippsARCFourInit +#define ippsARCFourReset w7_ippsARCFourReset +#define ippsARCFourPack w7_ippsARCFourPack +#define ippsARCFourUnpack w7_ippsARCFourUnpack +#define ippsARCFourEncrypt w7_ippsARCFourEncrypt +#define ippsARCFourDecrypt w7_ippsARCFourDecrypt +#define ippsSHA1GetSize w7_ippsSHA1GetSize +#define ippsSHA1Init w7_ippsSHA1Init +#define ippsSHA1Duplicate w7_ippsSHA1Duplicate +#define ippsSHA1Pack w7_ippsSHA1Pack +#define ippsSHA1Unpack w7_ippsSHA1Unpack +#define ippsSHA1Update w7_ippsSHA1Update +#define ippsSHA1GetTag w7_ippsSHA1GetTag +#define ippsSHA1Final w7_ippsSHA1Final +#define ippsSHA1MessageDigest w7_ippsSHA1MessageDigest +#define ippsSHA224GetSize w7_ippsSHA224GetSize +#define ippsSHA224Init w7_ippsSHA224Init +#define ippsSHA224Duplicate w7_ippsSHA224Duplicate +#define ippsSHA224Pack w7_ippsSHA224Pack +#define ippsSHA224Unpack w7_ippsSHA224Unpack +#define ippsSHA224Update w7_ippsSHA224Update +#define ippsSHA224GetTag w7_ippsSHA224GetTag +#define ippsSHA224Final w7_ippsSHA224Final +#define ippsSHA224MessageDigest w7_ippsSHA224MessageDigest +#define ippsSHA256GetSize w7_ippsSHA256GetSize +#define ippsSHA256Init w7_ippsSHA256Init +#define ippsSHA256Duplicate w7_ippsSHA256Duplicate +#define ippsSHA256Pack w7_ippsSHA256Pack +#define ippsSHA256Unpack w7_ippsSHA256Unpack +#define ippsSHA256Update w7_ippsSHA256Update +#define ippsSHA256GetTag w7_ippsSHA256GetTag +#define ippsSHA256Final w7_ippsSHA256Final +#define ippsSHA256MessageDigest w7_ippsSHA256MessageDigest +#define ippsSHA384GetSize w7_ippsSHA384GetSize +#define ippsSHA384Init w7_ippsSHA384Init +#define ippsSHA384Duplicate w7_ippsSHA384Duplicate +#define ippsSHA384Pack w7_ippsSHA384Pack +#define ippsSHA384Unpack w7_ippsSHA384Unpack +#define ippsSHA384Update w7_ippsSHA384Update +#define ippsSHA384GetTag w7_ippsSHA384GetTag +#define ippsSHA384Final w7_ippsSHA384Final +#define ippsSHA384MessageDigest w7_ippsSHA384MessageDigest +#define ippsSHA512GetSize w7_ippsSHA512GetSize +#define ippsSHA512Init w7_ippsSHA512Init +#define ippsSHA512Duplicate w7_ippsSHA512Duplicate +#define ippsSHA512Pack w7_ippsSHA512Pack +#define ippsSHA512Unpack w7_ippsSHA512Unpack +#define ippsSHA512Update w7_ippsSHA512Update +#define ippsSHA512GetTag w7_ippsSHA512GetTag +#define ippsSHA512Final w7_ippsSHA512Final +#define ippsSHA512MessageDigest w7_ippsSHA512MessageDigest +#define ippsMD5GetSize w7_ippsMD5GetSize +#define ippsMD5Init w7_ippsMD5Init +#define ippsMD5Duplicate w7_ippsMD5Duplicate +#define ippsMD5Pack w7_ippsMD5Pack +#define ippsMD5Unpack w7_ippsMD5Unpack +#define ippsMD5Update w7_ippsMD5Update +#define ippsMD5GetTag w7_ippsMD5GetTag +#define ippsMD5Final w7_ippsMD5Final +#define ippsMD5MessageDigest w7_ippsMD5MessageDigest +#define ippsSM3GetSize w7_ippsSM3GetSize +#define ippsSM3Init w7_ippsSM3Init +#define ippsSM3Duplicate w7_ippsSM3Duplicate +#define ippsSM3Pack w7_ippsSM3Pack +#define ippsSM3Unpack w7_ippsSM3Unpack +#define ippsSM3Update w7_ippsSM3Update +#define ippsSM3GetTag w7_ippsSM3GetTag +#define ippsSM3Final w7_ippsSM3Final +#define ippsSM3MessageDigest w7_ippsSM3MessageDigest +#define ippsHashGetSize w7_ippsHashGetSize +#define ippsHashInit w7_ippsHashInit +#define ippsHashPack w7_ippsHashPack +#define ippsHashUnpack w7_ippsHashUnpack +#define ippsHashDuplicate w7_ippsHashDuplicate +#define ippsHashUpdate w7_ippsHashUpdate +#define ippsHashGetTag w7_ippsHashGetTag +#define ippsHashFinal w7_ippsHashFinal +#define ippsHashMessage w7_ippsHashMessage +#define ippsHashMethod_MD5 w7_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 w7_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 w7_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI w7_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT w7_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 w7_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI w7_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT w7_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 w7_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI w7_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT w7_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 w7_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 w7_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 w7_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 w7_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize w7_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 w7_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 w7_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 w7_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 w7_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI w7_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT w7_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 w7_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI w7_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT w7_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 w7_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI w7_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT w7_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 w7_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI w7_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT w7_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 w7_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI w7_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT w7_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 w7_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 w7_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 w7_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 w7_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 w7_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 w7_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 w7_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 w7_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf w7_ippsHashGetSize_rmf +#define ippsHashInit_rmf w7_ippsHashInit_rmf +#define ippsHashPack_rmf w7_ippsHashPack_rmf +#define ippsHashUnpack_rmf w7_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf w7_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf w7_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf w7_ippsHashGetTag_rmf +#define ippsHashFinal_rmf w7_ippsHashFinal_rmf +#define ippsHashMessage_rmf w7_ippsHashMessage_rmf +#define ippsHashMethodGetInfo w7_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf w7_ippsHashGetInfo_rmf +#define ippsMGF w7_ippsMGF +#define ippsMGF1_rmf w7_ippsMGF1_rmf +#define ippsMGF2_rmf w7_ippsMGF2_rmf +#define ippsHMAC_GetSize w7_ippsHMAC_GetSize +#define ippsHMAC_Init w7_ippsHMAC_Init +#define ippsHMAC_Pack w7_ippsHMAC_Pack +#define ippsHMAC_Unpack w7_ippsHMAC_Unpack +#define ippsHMAC_Duplicate w7_ippsHMAC_Duplicate +#define ippsHMAC_Update w7_ippsHMAC_Update +#define ippsHMAC_Final w7_ippsHMAC_Final +#define ippsHMAC_GetTag w7_ippsHMAC_GetTag +#define ippsHMAC_Message w7_ippsHMAC_Message +#define ippsHMACGetSize_rmf w7_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf w7_ippsHMACInit_rmf +#define ippsHMACPack_rmf w7_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf w7_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf w7_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf w7_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf w7_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf w7_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf w7_ippsHMACMessage_rmf +#define ippsBigNumGetSize w7_ippsBigNumGetSize +#define ippsBigNumInit w7_ippsBigNumInit +#define ippsCmpZero_BN w7_ippsCmpZero_BN +#define ippsCmp_BN w7_ippsCmp_BN +#define ippsGetSize_BN w7_ippsGetSize_BN +#define ippsSet_BN w7_ippsSet_BN +#define ippsGet_BN w7_ippsGet_BN +#define ippsRef_BN w7_ippsRef_BN +#define ippsExtGet_BN w7_ippsExtGet_BN +#define ippsAdd_BN w7_ippsAdd_BN +#define ippsSub_BN w7_ippsSub_BN +#define ippsMul_BN w7_ippsMul_BN +#define ippsMAC_BN_I w7_ippsMAC_BN_I +#define ippsDiv_BN w7_ippsDiv_BN +#define ippsMod_BN w7_ippsMod_BN +#define ippsGcd_BN w7_ippsGcd_BN +#define ippsModInv_BN w7_ippsModInv_BN +#define ippsSetOctString_BN w7_ippsSetOctString_BN +#define ippsGetOctString_BN w7_ippsGetOctString_BN +#define ippsMontGetSize w7_ippsMontGetSize +#define ippsMontInit w7_ippsMontInit +#define ippsMontSet w7_ippsMontSet +#define ippsMontGet w7_ippsMontGet +#define ippsMontForm w7_ippsMontForm +#define ippsMontMul w7_ippsMontMul +#define ippsMontExp w7_ippsMontExp +#define ippsPRNGGetSize w7_ippsPRNGGetSize +#define ippsPRNGInit w7_ippsPRNGInit +#define ippsPRNGSetModulus w7_ippsPRNGSetModulus +#define ippsPRNGSetH0 w7_ippsPRNGSetH0 +#define ippsPRNGSetAugment w7_ippsPRNGSetAugment +#define ippsPRNGSetSeed w7_ippsPRNGSetSeed +#define ippsPRNGGetSeed w7_ippsPRNGGetSeed +#define ippsPRNGen w7_ippsPRNGen +#define ippsPRNGen_BN w7_ippsPRNGen_BN +#define ippsPRNGenRDRAND w7_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN w7_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED w7_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN w7_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize w7_ippsPrimeGetSize +#define ippsPrimeInit w7_ippsPrimeInit +#define ippsPrimeGen w7_ippsPrimeGen +#define ippsPrimeTest w7_ippsPrimeTest +#define ippsPrimeGen_BN w7_ippsPrimeGen_BN +#define ippsPrimeTest_BN w7_ippsPrimeTest_BN +#define ippsPrimeGet w7_ippsPrimeGet +#define ippsPrimeGet_BN w7_ippsPrimeGet_BN +#define ippsPrimeSet w7_ippsPrimeSet +#define ippsPrimeSet_BN w7_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey w7_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey w7_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey w7_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey w7_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 w7_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 w7_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 w7_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 w7_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 w7_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 w7_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 w7_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 w7_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey w7_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey w7_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt w7_ippsRSA_Encrypt +#define ippsRSA_Decrypt w7_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys w7_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys w7_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP w7_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP w7_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf w7_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf w7_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 w7_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 w7_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS w7_ippsRSASign_PSS +#define ippsRSAVerify_PSS w7_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf w7_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf w7_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 w7_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 w7_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf w7_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf w7_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString w7_ippsDLGetResultString +#define ippsDLPGetSize w7_ippsDLPGetSize +#define ippsDLPInit w7_ippsDLPInit +#define ippsDLPPack w7_ippsDLPPack +#define ippsDLPUnpack w7_ippsDLPUnpack +#define ippsDLPSet w7_ippsDLPSet +#define ippsDLPGet w7_ippsDLPGet +#define ippsDLPSetDP w7_ippsDLPSetDP +#define ippsDLPGetDP w7_ippsDLPGetDP +#define ippsDLPGenKeyPair w7_ippsDLPGenKeyPair +#define ippsDLPPublicKey w7_ippsDLPPublicKey +#define ippsDLPValidateKeyPair w7_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair w7_ippsDLPSetKeyPair +#define ippsDLPSignDSA w7_ippsDLPSignDSA +#define ippsDLPVerifyDSA w7_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH w7_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA w7_ippsDLPGenerateDSA +#define ippsDLPValidateDSA w7_ippsDLPValidateDSA +#define ippsDLPGenerateDH w7_ippsDLPGenerateDH +#define ippsDLPValidateDH w7_ippsDLPValidateDH +#define ippsECCGetResultString w7_ippsECCGetResultString +#define ippsECCPGetSize w7_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 w7_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 w7_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 w7_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 w7_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 w7_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 w7_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 w7_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 w7_ippsECCPGetSizeStdSM2 +#define ippsECCPInit w7_ippsECCPInit +#define ippsECCPInitStd128r1 w7_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 w7_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 w7_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 w7_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 w7_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 w7_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 w7_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 w7_ippsECCPInitStdSM2 +#define ippsECCPSet w7_ippsECCPSet +#define ippsECCPSetStd w7_ippsECCPSetStd +#define ippsECCPSetStd128r1 w7_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 w7_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 w7_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 w7_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 w7_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 w7_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 w7_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 w7_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 w7_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 w7_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 w7_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 w7_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 w7_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 w7_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet w7_ippsECCPGet +#define ippsECCPGetOrderBitSize w7_ippsECCPGetOrderBitSize +#define ippsECCPValidate w7_ippsECCPValidate +#define ippsECCPPointGetSize w7_ippsECCPPointGetSize +#define ippsECCPPointInit w7_ippsECCPPointInit +#define ippsECCPSetPoint w7_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity w7_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint w7_ippsECCPGetPoint +#define ippsECCPCheckPoint w7_ippsECCPCheckPoint +#define ippsECCPComparePoint w7_ippsECCPComparePoint +#define ippsECCPNegativePoint w7_ippsECCPNegativePoint +#define ippsECCPAddPoint w7_ippsECCPAddPoint +#define ippsECCPMulPointScalar w7_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair w7_ippsECCPGenKeyPair +#define ippsECCPPublicKey w7_ippsECCPPublicKey +#define ippsECCPValidateKeyPair w7_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair w7_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH w7_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC w7_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA w7_ippsECCPSignDSA +#define ippsECCPVerifyDSA w7_ippsECCPVerifyDSA +#define ippsECCPSignNR w7_ippsECCPSignNR +#define ippsECCPVerifyNR w7_ippsECCPVerifyNR +#define ippsECCPSignSM2 w7_ippsECCPSignSM2 +#define ippsECCPVerifySM2 w7_ippsECCPVerifySM2 +#define ippsGFpGetSize w7_ippsGFpGetSize +#define ippsGFpInitArbitrary w7_ippsGFpInitArbitrary +#define ippsGFpInitFixed w7_ippsGFpInitFixed +#define ippsGFpInit w7_ippsGFpInit +#define ippsGFpMethod_p192r1 w7_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 w7_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 w7_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 w7_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 w7_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 w7_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn w7_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 w7_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb w7_ippsGFpMethod_pArb +#define ippsGFpxGetSize w7_ippsGFpxGetSize +#define ippsGFpxInit w7_ippsGFpxInit +#define ippsGFpxInitBinomial w7_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 w7_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 w7_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 w7_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 w7_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom w7_ippsGFpxMethod_binom +#define ippsGFpxMethod_com w7_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize w7_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize w7_ippsGFpElementGetSize +#define ippsGFpElementInit w7_ippsGFpElementInit +#define ippsGFpSetElement w7_ippsGFpSetElement +#define ippsGFpSetElementRegular w7_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString w7_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom w7_ippsGFpSetElementRandom +#define ippsGFpSetElementHash w7_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf w7_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement w7_ippsGFpCpyElement +#define ippsGFpGetElement w7_ippsGFpGetElement +#define ippsGFpGetElementOctString w7_ippsGFpGetElementOctString +#define ippsGFpCmpElement w7_ippsGFpCmpElement +#define ippsGFpIsZeroElement w7_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement w7_ippsGFpIsUnityElement +#define ippsGFpConj w7_ippsGFpConj +#define ippsGFpNeg w7_ippsGFpNeg +#define ippsGFpInv w7_ippsGFpInv +#define ippsGFpSqrt w7_ippsGFpSqrt +#define ippsGFpSqr w7_ippsGFpSqr +#define ippsGFpAdd w7_ippsGFpAdd +#define ippsGFpSub w7_ippsGFpSub +#define ippsGFpMul w7_ippsGFpMul +#define ippsGFpExp w7_ippsGFpExp +#define ippsGFpMultiExp w7_ippsGFpMultiExp +#define ippsGFpAdd_PE w7_ippsGFpAdd_PE +#define ippsGFpSub_PE w7_ippsGFpSub_PE +#define ippsGFpMul_PE w7_ippsGFpMul_PE +#define ippsGFpGetInfo w7_ippsGFpGetInfo +#define ippsGFpECGetSize w7_ippsGFpECGetSize +#define ippsGFpECInit w7_ippsGFpECInit +#define ippsGFpECSet w7_ippsGFpECSet +#define ippsGFpECSetSubgroup w7_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 w7_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 w7_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 w7_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 w7_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 w7_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 w7_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 w7_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 w7_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 w7_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 w7_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 w7_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 w7_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 w7_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 w7_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 w7_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet w7_ippsGFpECGet +#define ippsGFpECGetSubgroup w7_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize w7_ippsGFpECScratchBufferSize +#define ippsGFpECVerify w7_ippsGFpECVerify +#define ippsGFpECPointGetSize w7_ippsGFpECPointGetSize +#define ippsGFpECPointInit w7_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity w7_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint w7_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular w7_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom w7_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint w7_ippsGFpECMakePoint +#define ippsGFpECSetPointHash w7_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible w7_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf w7_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf w7_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint w7_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular w7_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString w7_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString w7_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint w7_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup w7_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint w7_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint w7_ippsGFpECCmpPoint +#define ippsGFpECNegPoint w7_ippsGFpECNegPoint +#define ippsGFpECAddPoint w7_ippsGFpECAddPoint +#define ippsGFpECMulPoint w7_ippsGFpECMulPoint +#define ippsGFpECPrivateKey w7_ippsGFpECPrivateKey +#define ippsGFpECPublicKey w7_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair w7_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH w7_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC w7_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 w7_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA w7_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA w7_ippsGFpECVerifyDSA +#define ippsGFpECSignNR w7_ippsGFpECSignNR +#define ippsGFpECVerifyNR w7_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 w7_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 w7_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 w7_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize w7_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init w7_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup w7_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey w7_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm w7_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF w7_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 w7_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 w7_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 w7_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 w7_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 w7_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 w7_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 w7_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 w7_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize w7_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext w7_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize w7_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext w7_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/include/single_cpu/ippcp_y8.h b/plugin/ippcp/library/include/single_cpu/ippcp_y8.h new file mode 100644 index 000000000..12c727d75 --- /dev/null +++ b/plugin/ippcp/library/include/single_cpu/ippcp_y8.h @@ -0,0 +1,557 @@ +/******************************************************************************* + * Copyright 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + #define ippcpGetLibVersion y8_ippcpGetLibVersion +#define ippsDESGetSize y8_ippsDESGetSize +#define ippsDESInit y8_ippsDESInit +#define ippsDESPack y8_ippsDESPack +#define ippsDESUnpack y8_ippsDESUnpack +#define ippsTDESEncryptECB y8_ippsTDESEncryptECB +#define ippsTDESDecryptECB y8_ippsTDESDecryptECB +#define ippsTDESEncryptCBC y8_ippsTDESEncryptCBC +#define ippsTDESDecryptCBC y8_ippsTDESDecryptCBC +#define ippsTDESEncryptCFB y8_ippsTDESEncryptCFB +#define ippsTDESDecryptCFB y8_ippsTDESDecryptCFB +#define ippsTDESEncryptOFB y8_ippsTDESEncryptOFB +#define ippsTDESDecryptOFB y8_ippsTDESDecryptOFB +#define ippsTDESEncryptCTR y8_ippsTDESEncryptCTR +#define ippsTDESDecryptCTR y8_ippsTDESDecryptCTR +#define ippsAESGetSize y8_ippsAESGetSize +#define ippsAESInit y8_ippsAESInit +#define ippsAESSetKey y8_ippsAESSetKey +#define ippsAESPack y8_ippsAESPack +#define ippsAESUnpack y8_ippsAESUnpack +#define ippsAESEncryptECB y8_ippsAESEncryptECB +#define ippsAESDecryptECB y8_ippsAESDecryptECB +#define ippsAESEncryptCBC y8_ippsAESEncryptCBC +#define ippsAESEncryptCBC_CS1 y8_ippsAESEncryptCBC_CS1 +#define ippsAESEncryptCBC_CS2 y8_ippsAESEncryptCBC_CS2 +#define ippsAESEncryptCBC_CS3 y8_ippsAESEncryptCBC_CS3 +#define ippsAESDecryptCBC y8_ippsAESDecryptCBC +#define ippsAESDecryptCBC_CS1 y8_ippsAESDecryptCBC_CS1 +#define ippsAESDecryptCBC_CS2 y8_ippsAESDecryptCBC_CS2 +#define ippsAESDecryptCBC_CS3 y8_ippsAESDecryptCBC_CS3 +#define ippsAESEncryptCFB y8_ippsAESEncryptCFB +#define ippsAESDecryptCFB y8_ippsAESDecryptCFB +#define ippsAESEncryptOFB y8_ippsAESEncryptOFB +#define ippsAESDecryptOFB y8_ippsAESDecryptOFB +#define ippsAESEncryptCTR y8_ippsAESEncryptCTR +#define ippsAESDecryptCTR y8_ippsAESDecryptCTR +#define ippsAESEncryptXTS_Direct y8_ippsAESEncryptXTS_Direct +#define ippsAESDecryptXTS_Direct y8_ippsAESDecryptXTS_Direct +#define ippsAESSetupNoise y8_ippsAESSetupNoise +#define ippsAES_GCMSetupNoise y8_ippsAES_GCMSetupNoise +#define ippsAES_CMACSetupNoise y8_ippsAES_CMACSetupNoise +#define ippsAES_EncryptCFB16_MB y8_ippsAES_EncryptCFB16_MB +#define ippsSMS4GetSize y8_ippsSMS4GetSize +#define ippsSMS4Init y8_ippsSMS4Init +#define ippsSMS4SetKey y8_ippsSMS4SetKey +#define ippsSMS4EncryptECB y8_ippsSMS4EncryptECB +#define ippsSMS4DecryptECB y8_ippsSMS4DecryptECB +#define ippsSMS4EncryptCBC y8_ippsSMS4EncryptCBC +#define ippsSMS4EncryptCBC_CS1 y8_ippsSMS4EncryptCBC_CS1 +#define ippsSMS4EncryptCBC_CS2 y8_ippsSMS4EncryptCBC_CS2 +#define ippsSMS4EncryptCBC_CS3 y8_ippsSMS4EncryptCBC_CS3 +#define ippsSMS4DecryptCBC y8_ippsSMS4DecryptCBC +#define ippsSMS4DecryptCBC_CS1 y8_ippsSMS4DecryptCBC_CS1 +#define ippsSMS4DecryptCBC_CS2 y8_ippsSMS4DecryptCBC_CS2 +#define ippsSMS4DecryptCBC_CS3 y8_ippsSMS4DecryptCBC_CS3 +#define ippsSMS4EncryptCFB y8_ippsSMS4EncryptCFB +#define ippsSMS4DecryptCFB y8_ippsSMS4DecryptCFB +#define ippsSMS4EncryptOFB y8_ippsSMS4EncryptOFB +#define ippsSMS4DecryptOFB y8_ippsSMS4DecryptOFB +#define ippsSMS4EncryptCTR y8_ippsSMS4EncryptCTR +#define ippsSMS4DecryptCTR y8_ippsSMS4DecryptCTR +#define ippsSMS4_CCMGetSize y8_ippsSMS4_CCMGetSize +#define ippsSMS4_CCMInit y8_ippsSMS4_CCMInit +#define ippsSMS4_CCMMessageLen y8_ippsSMS4_CCMMessageLen +#define ippsSMS4_CCMTagLen y8_ippsSMS4_CCMTagLen +#define ippsSMS4_CCMStart y8_ippsSMS4_CCMStart +#define ippsSMS4_CCMEncrypt y8_ippsSMS4_CCMEncrypt +#define ippsSMS4_CCMDecrypt y8_ippsSMS4_CCMDecrypt +#define ippsSMS4_CCMGetTag y8_ippsSMS4_CCMGetTag +#define ippsAES_CCMGetSize y8_ippsAES_CCMGetSize +#define ippsAES_CCMInit y8_ippsAES_CCMInit +#define ippsAES_CCMMessageLen y8_ippsAES_CCMMessageLen +#define ippsAES_CCMTagLen y8_ippsAES_CCMTagLen +#define ippsAES_CCMStart y8_ippsAES_CCMStart +#define ippsAES_CCMEncrypt y8_ippsAES_CCMEncrypt +#define ippsAES_CCMDecrypt y8_ippsAES_CCMDecrypt +#define ippsAES_CCMGetTag y8_ippsAES_CCMGetTag +#define ippsAES_GCMGetSize y8_ippsAES_GCMGetSize +#define ippsAES_GCMInit y8_ippsAES_GCMInit +#define ippsAES_GCMReinit y8_ippsAES_GCMReinit +#define ippsAES_GCMReset y8_ippsAES_GCMReset +#define ippsAES_GCMProcessIV y8_ippsAES_GCMProcessIV +#define ippsAES_GCMProcessAAD y8_ippsAES_GCMProcessAAD +#define ippsAES_GCMStart y8_ippsAES_GCMStart +#define ippsAES_GCMEncrypt y8_ippsAES_GCMEncrypt +#define ippsAES_GCMDecrypt y8_ippsAES_GCMDecrypt +#define ippsAES_GCMGetTag y8_ippsAES_GCMGetTag +#define ippsAES_XTSGetSize y8_ippsAES_XTSGetSize +#define ippsAES_XTSInit y8_ippsAES_XTSInit +#define ippsAES_XTSEncrypt y8_ippsAES_XTSEncrypt +#define ippsAES_XTSDecrypt y8_ippsAES_XTSDecrypt +#define ippsAES_S2V_CMAC y8_ippsAES_S2V_CMAC +#define ippsAES_SIVEncrypt y8_ippsAES_SIVEncrypt +#define ippsAES_SIVDecrypt y8_ippsAES_SIVDecrypt +#define ippsAES_CMACGetSize y8_ippsAES_CMACGetSize +#define ippsAES_CMACInit y8_ippsAES_CMACInit +#define ippsAES_CMACUpdate y8_ippsAES_CMACUpdate +#define ippsAES_CMACFinal y8_ippsAES_CMACFinal +#define ippsAES_CMACGetTag y8_ippsAES_CMACGetTag +#define ippsARCFourCheckKey y8_ippsARCFourCheckKey +#define ippsARCFourGetSize y8_ippsARCFourGetSize +#define ippsARCFourInit y8_ippsARCFourInit +#define ippsARCFourReset y8_ippsARCFourReset +#define ippsARCFourPack y8_ippsARCFourPack +#define ippsARCFourUnpack y8_ippsARCFourUnpack +#define ippsARCFourEncrypt y8_ippsARCFourEncrypt +#define ippsARCFourDecrypt y8_ippsARCFourDecrypt +#define ippsSHA1GetSize y8_ippsSHA1GetSize +#define ippsSHA1Init y8_ippsSHA1Init +#define ippsSHA1Duplicate y8_ippsSHA1Duplicate +#define ippsSHA1Pack y8_ippsSHA1Pack +#define ippsSHA1Unpack y8_ippsSHA1Unpack +#define ippsSHA1Update y8_ippsSHA1Update +#define ippsSHA1GetTag y8_ippsSHA1GetTag +#define ippsSHA1Final y8_ippsSHA1Final +#define ippsSHA1MessageDigest y8_ippsSHA1MessageDigest +#define ippsSHA224GetSize y8_ippsSHA224GetSize +#define ippsSHA224Init y8_ippsSHA224Init +#define ippsSHA224Duplicate y8_ippsSHA224Duplicate +#define ippsSHA224Pack y8_ippsSHA224Pack +#define ippsSHA224Unpack y8_ippsSHA224Unpack +#define ippsSHA224Update y8_ippsSHA224Update +#define ippsSHA224GetTag y8_ippsSHA224GetTag +#define ippsSHA224Final y8_ippsSHA224Final +#define ippsSHA224MessageDigest y8_ippsSHA224MessageDigest +#define ippsSHA256GetSize y8_ippsSHA256GetSize +#define ippsSHA256Init y8_ippsSHA256Init +#define ippsSHA256Duplicate y8_ippsSHA256Duplicate +#define ippsSHA256Pack y8_ippsSHA256Pack +#define ippsSHA256Unpack y8_ippsSHA256Unpack +#define ippsSHA256Update y8_ippsSHA256Update +#define ippsSHA256GetTag y8_ippsSHA256GetTag +#define ippsSHA256Final y8_ippsSHA256Final +#define ippsSHA256MessageDigest y8_ippsSHA256MessageDigest +#define ippsSHA384GetSize y8_ippsSHA384GetSize +#define ippsSHA384Init y8_ippsSHA384Init +#define ippsSHA384Duplicate y8_ippsSHA384Duplicate +#define ippsSHA384Pack y8_ippsSHA384Pack +#define ippsSHA384Unpack y8_ippsSHA384Unpack +#define ippsSHA384Update y8_ippsSHA384Update +#define ippsSHA384GetTag y8_ippsSHA384GetTag +#define ippsSHA384Final y8_ippsSHA384Final +#define ippsSHA384MessageDigest y8_ippsSHA384MessageDigest +#define ippsSHA512GetSize y8_ippsSHA512GetSize +#define ippsSHA512Init y8_ippsSHA512Init +#define ippsSHA512Duplicate y8_ippsSHA512Duplicate +#define ippsSHA512Pack y8_ippsSHA512Pack +#define ippsSHA512Unpack y8_ippsSHA512Unpack +#define ippsSHA512Update y8_ippsSHA512Update +#define ippsSHA512GetTag y8_ippsSHA512GetTag +#define ippsSHA512Final y8_ippsSHA512Final +#define ippsSHA512MessageDigest y8_ippsSHA512MessageDigest +#define ippsMD5GetSize y8_ippsMD5GetSize +#define ippsMD5Init y8_ippsMD5Init +#define ippsMD5Duplicate y8_ippsMD5Duplicate +#define ippsMD5Pack y8_ippsMD5Pack +#define ippsMD5Unpack y8_ippsMD5Unpack +#define ippsMD5Update y8_ippsMD5Update +#define ippsMD5GetTag y8_ippsMD5GetTag +#define ippsMD5Final y8_ippsMD5Final +#define ippsMD5MessageDigest y8_ippsMD5MessageDigest +#define ippsSM3GetSize y8_ippsSM3GetSize +#define ippsSM3Init y8_ippsSM3Init +#define ippsSM3Duplicate y8_ippsSM3Duplicate +#define ippsSM3Pack y8_ippsSM3Pack +#define ippsSM3Unpack y8_ippsSM3Unpack +#define ippsSM3Update y8_ippsSM3Update +#define ippsSM3GetTag y8_ippsSM3GetTag +#define ippsSM3Final y8_ippsSM3Final +#define ippsSM3MessageDigest y8_ippsSM3MessageDigest +#define ippsHashGetSize y8_ippsHashGetSize +#define ippsHashInit y8_ippsHashInit +#define ippsHashPack y8_ippsHashPack +#define ippsHashUnpack y8_ippsHashUnpack +#define ippsHashDuplicate y8_ippsHashDuplicate +#define ippsHashUpdate y8_ippsHashUpdate +#define ippsHashGetTag y8_ippsHashGetTag +#define ippsHashFinal y8_ippsHashFinal +#define ippsHashMessage y8_ippsHashMessage +#define ippsHashMethod_MD5 y8_ippsHashMethod_MD5 +#define ippsHashMethod_SM3 y8_ippsHashMethod_SM3 +#define ippsHashMethod_SHA1 y8_ippsHashMethod_SHA1 +#define ippsHashMethod_SHA1_NI y8_ippsHashMethod_SHA1_NI +#define ippsHashMethod_SHA1_TT y8_ippsHashMethod_SHA1_TT +#define ippsHashMethod_SHA256 y8_ippsHashMethod_SHA256 +#define ippsHashMethod_SHA256_NI y8_ippsHashMethod_SHA256_NI +#define ippsHashMethod_SHA256_TT y8_ippsHashMethod_SHA256_TT +#define ippsHashMethod_SHA224 y8_ippsHashMethod_SHA224 +#define ippsHashMethod_SHA224_NI y8_ippsHashMethod_SHA224_NI +#define ippsHashMethod_SHA224_TT y8_ippsHashMethod_SHA224_TT +#define ippsHashMethod_SHA512 y8_ippsHashMethod_SHA512 +#define ippsHashMethod_SHA384 y8_ippsHashMethod_SHA384 +#define ippsHashMethod_SHA512_256 y8_ippsHashMethod_SHA512_256 +#define ippsHashMethod_SHA512_224 y8_ippsHashMethod_SHA512_224 +#define ippsHashMethodGetSize y8_ippsHashMethodGetSize +#define ippsHashMethodSet_MD5 y8_ippsHashMethodSet_MD5 +#define ippsHashMethodSet_SM3 y8_ippsHashMethodSet_SM3 +#define ippsHashStateMethodSet_SM3 y8_ippsHashStateMethodSet_SM3 +#define ippsHashMethodSet_SHA1 y8_ippsHashMethodSet_SHA1 +#define ippsHashMethodSet_SHA1_NI y8_ippsHashMethodSet_SHA1_NI +#define ippsHashMethodSet_SHA1_TT y8_ippsHashMethodSet_SHA1_TT +#define ippsHashMethodSet_SHA256 y8_ippsHashMethodSet_SHA256 +#define ippsHashMethodSet_SHA256_NI y8_ippsHashMethodSet_SHA256_NI +#define ippsHashMethodSet_SHA256_TT y8_ippsHashMethodSet_SHA256_TT +#define ippsHashStateMethodSet_SHA256 y8_ippsHashStateMethodSet_SHA256 +#define ippsHashStateMethodSet_SHA256_NI y8_ippsHashStateMethodSet_SHA256_NI +#define ippsHashStateMethodSet_SHA256_TT y8_ippsHashStateMethodSet_SHA256_TT +#define ippsHashMethodSet_SHA224 y8_ippsHashMethodSet_SHA224 +#define ippsHashMethodSet_SHA224_NI y8_ippsHashMethodSet_SHA224_NI +#define ippsHashMethodSet_SHA224_TT y8_ippsHashMethodSet_SHA224_TT +#define ippsHashStateMethodSet_SHA224 y8_ippsHashStateMethodSet_SHA224 +#define ippsHashStateMethodSet_SHA224_NI y8_ippsHashStateMethodSet_SHA224_NI +#define ippsHashStateMethodSet_SHA224_TT y8_ippsHashStateMethodSet_SHA224_TT +#define ippsHashMethodSet_SHA512 y8_ippsHashMethodSet_SHA512 +#define ippsHashMethodSet_SHA384 y8_ippsHashMethodSet_SHA384 +#define ippsHashMethodSet_SHA512_256 y8_ippsHashMethodSet_SHA512_256 +#define ippsHashMethodSet_SHA512_224 y8_ippsHashMethodSet_SHA512_224 +#define ippsHashStateMethodSet_SHA512 y8_ippsHashStateMethodSet_SHA512 +#define ippsHashStateMethodSet_SHA384 y8_ippsHashStateMethodSet_SHA384 +#define ippsHashStateMethodSet_SHA512_256 y8_ippsHashStateMethodSet_SHA512_256 +#define ippsHashStateMethodSet_SHA512_224 y8_ippsHashStateMethodSet_SHA512_224 +#define ippsHashGetSize_rmf y8_ippsHashGetSize_rmf +#define ippsHashInit_rmf y8_ippsHashInit_rmf +#define ippsHashPack_rmf y8_ippsHashPack_rmf +#define ippsHashUnpack_rmf y8_ippsHashUnpack_rmf +#define ippsHashDuplicate_rmf y8_ippsHashDuplicate_rmf +#define ippsHashUpdate_rmf y8_ippsHashUpdate_rmf +#define ippsHashGetTag_rmf y8_ippsHashGetTag_rmf +#define ippsHashFinal_rmf y8_ippsHashFinal_rmf +#define ippsHashMessage_rmf y8_ippsHashMessage_rmf +#define ippsHashMethodGetInfo y8_ippsHashMethodGetInfo +#define ippsHashGetInfo_rmf y8_ippsHashGetInfo_rmf +#define ippsMGF y8_ippsMGF +#define ippsMGF1_rmf y8_ippsMGF1_rmf +#define ippsMGF2_rmf y8_ippsMGF2_rmf +#define ippsHMAC_GetSize y8_ippsHMAC_GetSize +#define ippsHMAC_Init y8_ippsHMAC_Init +#define ippsHMAC_Pack y8_ippsHMAC_Pack +#define ippsHMAC_Unpack y8_ippsHMAC_Unpack +#define ippsHMAC_Duplicate y8_ippsHMAC_Duplicate +#define ippsHMAC_Update y8_ippsHMAC_Update +#define ippsHMAC_Final y8_ippsHMAC_Final +#define ippsHMAC_GetTag y8_ippsHMAC_GetTag +#define ippsHMAC_Message y8_ippsHMAC_Message +#define ippsHMACGetSize_rmf y8_ippsHMACGetSize_rmf +#define ippsHMACInit_rmf y8_ippsHMACInit_rmf +#define ippsHMACPack_rmf y8_ippsHMACPack_rmf +#define ippsHMACUnpack_rmf y8_ippsHMACUnpack_rmf +#define ippsHMACDuplicate_rmf y8_ippsHMACDuplicate_rmf +#define ippsHMACUpdate_rmf y8_ippsHMACUpdate_rmf +#define ippsHMACFinal_rmf y8_ippsHMACFinal_rmf +#define ippsHMACGetTag_rmf y8_ippsHMACGetTag_rmf +#define ippsHMACMessage_rmf y8_ippsHMACMessage_rmf +#define ippsBigNumGetSize y8_ippsBigNumGetSize +#define ippsBigNumInit y8_ippsBigNumInit +#define ippsCmpZero_BN y8_ippsCmpZero_BN +#define ippsCmp_BN y8_ippsCmp_BN +#define ippsGetSize_BN y8_ippsGetSize_BN +#define ippsSet_BN y8_ippsSet_BN +#define ippsGet_BN y8_ippsGet_BN +#define ippsRef_BN y8_ippsRef_BN +#define ippsExtGet_BN y8_ippsExtGet_BN +#define ippsAdd_BN y8_ippsAdd_BN +#define ippsSub_BN y8_ippsSub_BN +#define ippsMul_BN y8_ippsMul_BN +#define ippsMAC_BN_I y8_ippsMAC_BN_I +#define ippsDiv_BN y8_ippsDiv_BN +#define ippsMod_BN y8_ippsMod_BN +#define ippsGcd_BN y8_ippsGcd_BN +#define ippsModInv_BN y8_ippsModInv_BN +#define ippsSetOctString_BN y8_ippsSetOctString_BN +#define ippsGetOctString_BN y8_ippsGetOctString_BN +#define ippsMontGetSize y8_ippsMontGetSize +#define ippsMontInit y8_ippsMontInit +#define ippsMontSet y8_ippsMontSet +#define ippsMontGet y8_ippsMontGet +#define ippsMontForm y8_ippsMontForm +#define ippsMontMul y8_ippsMontMul +#define ippsMontExp y8_ippsMontExp +#define ippsPRNGGetSize y8_ippsPRNGGetSize +#define ippsPRNGInit y8_ippsPRNGInit +#define ippsPRNGSetModulus y8_ippsPRNGSetModulus +#define ippsPRNGSetH0 y8_ippsPRNGSetH0 +#define ippsPRNGSetAugment y8_ippsPRNGSetAugment +#define ippsPRNGSetSeed y8_ippsPRNGSetSeed +#define ippsPRNGGetSeed y8_ippsPRNGGetSeed +#define ippsPRNGen y8_ippsPRNGen +#define ippsPRNGen_BN y8_ippsPRNGen_BN +#define ippsPRNGenRDRAND y8_ippsPRNGenRDRAND +#define ippsPRNGenRDRAND_BN y8_ippsPRNGenRDRAND_BN +#define ippsTRNGenRDSEED y8_ippsTRNGenRDSEED +#define ippsTRNGenRDSEED_BN y8_ippsTRNGenRDSEED_BN +#define ippsPrimeGetSize y8_ippsPrimeGetSize +#define ippsPrimeInit y8_ippsPrimeInit +#define ippsPrimeGen y8_ippsPrimeGen +#define ippsPrimeTest y8_ippsPrimeTest +#define ippsPrimeGen_BN y8_ippsPrimeGen_BN +#define ippsPrimeTest_BN y8_ippsPrimeTest_BN +#define ippsPrimeGet y8_ippsPrimeGet +#define ippsPrimeGet_BN y8_ippsPrimeGet_BN +#define ippsPrimeSet y8_ippsPrimeSet +#define ippsPrimeSet_BN y8_ippsPrimeSet_BN +#define ippsRSA_GetSizePublicKey y8_ippsRSA_GetSizePublicKey +#define ippsRSA_InitPublicKey y8_ippsRSA_InitPublicKey +#define ippsRSA_SetPublicKey y8_ippsRSA_SetPublicKey +#define ippsRSA_GetPublicKey y8_ippsRSA_GetPublicKey +#define ippsRSA_GetSizePrivateKeyType1 y8_ippsRSA_GetSizePrivateKeyType1 +#define ippsRSA_InitPrivateKeyType1 y8_ippsRSA_InitPrivateKeyType1 +#define ippsRSA_SetPrivateKeyType1 y8_ippsRSA_SetPrivateKeyType1 +#define ippsRSA_GetPrivateKeyType1 y8_ippsRSA_GetPrivateKeyType1 +#define ippsRSA_GetSizePrivateKeyType2 y8_ippsRSA_GetSizePrivateKeyType2 +#define ippsRSA_InitPrivateKeyType2 y8_ippsRSA_InitPrivateKeyType2 +#define ippsRSA_SetPrivateKeyType2 y8_ippsRSA_SetPrivateKeyType2 +#define ippsRSA_GetPrivateKeyType2 y8_ippsRSA_GetPrivateKeyType2 +#define ippsRSA_GetBufferSizePublicKey y8_ippsRSA_GetBufferSizePublicKey +#define ippsRSA_GetBufferSizePrivateKey y8_ippsRSA_GetBufferSizePrivateKey +#define ippsRSA_Encrypt y8_ippsRSA_Encrypt +#define ippsRSA_Decrypt y8_ippsRSA_Decrypt +#define ippsRSA_GenerateKeys y8_ippsRSA_GenerateKeys +#define ippsRSA_ValidateKeys y8_ippsRSA_ValidateKeys +#define ippsRSAEncrypt_OAEP y8_ippsRSAEncrypt_OAEP +#define ippsRSADecrypt_OAEP y8_ippsRSADecrypt_OAEP +#define ippsRSAEncrypt_OAEP_rmf y8_ippsRSAEncrypt_OAEP_rmf +#define ippsRSADecrypt_OAEP_rmf y8_ippsRSADecrypt_OAEP_rmf +#define ippsRSAEncrypt_PKCSv15 y8_ippsRSAEncrypt_PKCSv15 +#define ippsRSADecrypt_PKCSv15 y8_ippsRSADecrypt_PKCSv15 +#define ippsRSASign_PSS y8_ippsRSASign_PSS +#define ippsRSAVerify_PSS y8_ippsRSAVerify_PSS +#define ippsRSASign_PSS_rmf y8_ippsRSASign_PSS_rmf +#define ippsRSAVerify_PSS_rmf y8_ippsRSAVerify_PSS_rmf +#define ippsRSASign_PKCS1v15 y8_ippsRSASign_PKCS1v15 +#define ippsRSAVerify_PKCS1v15 y8_ippsRSAVerify_PKCS1v15 +#define ippsRSASign_PKCS1v15_rmf y8_ippsRSASign_PKCS1v15_rmf +#define ippsRSAVerify_PKCS1v15_rmf y8_ippsRSAVerify_PKCS1v15_rmf +#define ippsDLGetResultString y8_ippsDLGetResultString +#define ippsDLPGetSize y8_ippsDLPGetSize +#define ippsDLPInit y8_ippsDLPInit +#define ippsDLPPack y8_ippsDLPPack +#define ippsDLPUnpack y8_ippsDLPUnpack +#define ippsDLPSet y8_ippsDLPSet +#define ippsDLPGet y8_ippsDLPGet +#define ippsDLPSetDP y8_ippsDLPSetDP +#define ippsDLPGetDP y8_ippsDLPGetDP +#define ippsDLPGenKeyPair y8_ippsDLPGenKeyPair +#define ippsDLPPublicKey y8_ippsDLPPublicKey +#define ippsDLPValidateKeyPair y8_ippsDLPValidateKeyPair +#define ippsDLPSetKeyPair y8_ippsDLPSetKeyPair +#define ippsDLPSignDSA y8_ippsDLPSignDSA +#define ippsDLPVerifyDSA y8_ippsDLPVerifyDSA +#define ippsDLPSharedSecretDH y8_ippsDLPSharedSecretDH +#define ippsDLPGenerateDSA y8_ippsDLPGenerateDSA +#define ippsDLPValidateDSA y8_ippsDLPValidateDSA +#define ippsDLPGenerateDH y8_ippsDLPGenerateDH +#define ippsDLPValidateDH y8_ippsDLPValidateDH +#define ippsECCGetResultString y8_ippsECCGetResultString +#define ippsECCPGetSize y8_ippsECCPGetSize +#define ippsECCPGetSizeStd128r1 y8_ippsECCPGetSizeStd128r1 +#define ippsECCPGetSizeStd128r2 y8_ippsECCPGetSizeStd128r2 +#define ippsECCPGetSizeStd192r1 y8_ippsECCPGetSizeStd192r1 +#define ippsECCPGetSizeStd224r1 y8_ippsECCPGetSizeStd224r1 +#define ippsECCPGetSizeStd256r1 y8_ippsECCPGetSizeStd256r1 +#define ippsECCPGetSizeStd384r1 y8_ippsECCPGetSizeStd384r1 +#define ippsECCPGetSizeStd521r1 y8_ippsECCPGetSizeStd521r1 +#define ippsECCPGetSizeStdSM2 y8_ippsECCPGetSizeStdSM2 +#define ippsECCPInit y8_ippsECCPInit +#define ippsECCPInitStd128r1 y8_ippsECCPInitStd128r1 +#define ippsECCPInitStd128r2 y8_ippsECCPInitStd128r2 +#define ippsECCPInitStd192r1 y8_ippsECCPInitStd192r1 +#define ippsECCPInitStd224r1 y8_ippsECCPInitStd224r1 +#define ippsECCPInitStd256r1 y8_ippsECCPInitStd256r1 +#define ippsECCPInitStd384r1 y8_ippsECCPInitStd384r1 +#define ippsECCPInitStd521r1 y8_ippsECCPInitStd521r1 +#define ippsECCPInitStdSM2 y8_ippsECCPInitStdSM2 +#define ippsECCPSet y8_ippsECCPSet +#define ippsECCPSetStd y8_ippsECCPSetStd +#define ippsECCPSetStd128r1 y8_ippsECCPSetStd128r1 +#define ippsECCPSetStd128r2 y8_ippsECCPSetStd128r2 +#define ippsECCPSetStd192r1 y8_ippsECCPSetStd192r1 +#define ippsECCPSetStd224r1 y8_ippsECCPSetStd224r1 +#define ippsECCPSetStd256r1 y8_ippsECCPSetStd256r1 +#define ippsECCPSetStd384r1 y8_ippsECCPSetStd384r1 +#define ippsECCPSetStd521r1 y8_ippsECCPSetStd521r1 +#define ippsECCPSetStdSM2 y8_ippsECCPSetStdSM2 +#define ippsECCPBindGxyTblStd192r1 y8_ippsECCPBindGxyTblStd192r1 +#define ippsECCPBindGxyTblStd224r1 y8_ippsECCPBindGxyTblStd224r1 +#define ippsECCPBindGxyTblStd256r1 y8_ippsECCPBindGxyTblStd256r1 +#define ippsECCPBindGxyTblStd384r1 y8_ippsECCPBindGxyTblStd384r1 +#define ippsECCPBindGxyTblStd521r1 y8_ippsECCPBindGxyTblStd521r1 +#define ippsECCPBindGxyTblStdSM2 y8_ippsECCPBindGxyTblStdSM2 +#define ippsECCPGet y8_ippsECCPGet +#define ippsECCPGetOrderBitSize y8_ippsECCPGetOrderBitSize +#define ippsECCPValidate y8_ippsECCPValidate +#define ippsECCPPointGetSize y8_ippsECCPPointGetSize +#define ippsECCPPointInit y8_ippsECCPPointInit +#define ippsECCPSetPoint y8_ippsECCPSetPoint +#define ippsECCPSetPointAtInfinity y8_ippsECCPSetPointAtInfinity +#define ippsECCPGetPoint y8_ippsECCPGetPoint +#define ippsECCPCheckPoint y8_ippsECCPCheckPoint +#define ippsECCPComparePoint y8_ippsECCPComparePoint +#define ippsECCPNegativePoint y8_ippsECCPNegativePoint +#define ippsECCPAddPoint y8_ippsECCPAddPoint +#define ippsECCPMulPointScalar y8_ippsECCPMulPointScalar +#define ippsECCPGenKeyPair y8_ippsECCPGenKeyPair +#define ippsECCPPublicKey y8_ippsECCPPublicKey +#define ippsECCPValidateKeyPair y8_ippsECCPValidateKeyPair +#define ippsECCPSetKeyPair y8_ippsECCPSetKeyPair +#define ippsECCPSharedSecretDH y8_ippsECCPSharedSecretDH +#define ippsECCPSharedSecretDHC y8_ippsECCPSharedSecretDHC +#define ippsECCPSignDSA y8_ippsECCPSignDSA +#define ippsECCPVerifyDSA y8_ippsECCPVerifyDSA +#define ippsECCPSignNR y8_ippsECCPSignNR +#define ippsECCPVerifyNR y8_ippsECCPVerifyNR +#define ippsECCPSignSM2 y8_ippsECCPSignSM2 +#define ippsECCPVerifySM2 y8_ippsECCPVerifySM2 +#define ippsGFpGetSize y8_ippsGFpGetSize +#define ippsGFpInitArbitrary y8_ippsGFpInitArbitrary +#define ippsGFpInitFixed y8_ippsGFpInitFixed +#define ippsGFpInit y8_ippsGFpInit +#define ippsGFpMethod_p192r1 y8_ippsGFpMethod_p192r1 +#define ippsGFpMethod_p224r1 y8_ippsGFpMethod_p224r1 +#define ippsGFpMethod_p256r1 y8_ippsGFpMethod_p256r1 +#define ippsGFpMethod_p384r1 y8_ippsGFpMethod_p384r1 +#define ippsGFpMethod_p521r1 y8_ippsGFpMethod_p521r1 +#define ippsGFpMethod_p256sm2 y8_ippsGFpMethod_p256sm2 +#define ippsGFpMethod_p256bn y8_ippsGFpMethod_p256bn +#define ippsGFpMethod_p256 y8_ippsGFpMethod_p256 +#define ippsGFpMethod_pArb y8_ippsGFpMethod_pArb +#define ippsGFpxGetSize y8_ippsGFpxGetSize +#define ippsGFpxInit y8_ippsGFpxInit +#define ippsGFpxInitBinomial y8_ippsGFpxInitBinomial +#define ippsGFpxMethod_binom2_epid2 y8_ippsGFpxMethod_binom2_epid2 +#define ippsGFpxMethod_binom3_epid2 y8_ippsGFpxMethod_binom3_epid2 +#define ippsGFpxMethod_binom2 y8_ippsGFpxMethod_binom2 +#define ippsGFpxMethod_binom3 y8_ippsGFpxMethod_binom3 +#define ippsGFpxMethod_binom y8_ippsGFpxMethod_binom +#define ippsGFpxMethod_com y8_ippsGFpxMethod_com +#define ippsGFpScratchBufferSize y8_ippsGFpScratchBufferSize +#define ippsGFpElementGetSize y8_ippsGFpElementGetSize +#define ippsGFpElementInit y8_ippsGFpElementInit +#define ippsGFpSetElement y8_ippsGFpSetElement +#define ippsGFpSetElementRegular y8_ippsGFpSetElementRegular +#define ippsGFpSetElementOctString y8_ippsGFpSetElementOctString +#define ippsGFpSetElementRandom y8_ippsGFpSetElementRandom +#define ippsGFpSetElementHash y8_ippsGFpSetElementHash +#define ippsGFpSetElementHash_rmf y8_ippsGFpSetElementHash_rmf +#define ippsGFpCpyElement y8_ippsGFpCpyElement +#define ippsGFpGetElement y8_ippsGFpGetElement +#define ippsGFpGetElementOctString y8_ippsGFpGetElementOctString +#define ippsGFpCmpElement y8_ippsGFpCmpElement +#define ippsGFpIsZeroElement y8_ippsGFpIsZeroElement +#define ippsGFpIsUnityElement y8_ippsGFpIsUnityElement +#define ippsGFpConj y8_ippsGFpConj +#define ippsGFpNeg y8_ippsGFpNeg +#define ippsGFpInv y8_ippsGFpInv +#define ippsGFpSqrt y8_ippsGFpSqrt +#define ippsGFpSqr y8_ippsGFpSqr +#define ippsGFpAdd y8_ippsGFpAdd +#define ippsGFpSub y8_ippsGFpSub +#define ippsGFpMul y8_ippsGFpMul +#define ippsGFpExp y8_ippsGFpExp +#define ippsGFpMultiExp y8_ippsGFpMultiExp +#define ippsGFpAdd_PE y8_ippsGFpAdd_PE +#define ippsGFpSub_PE y8_ippsGFpSub_PE +#define ippsGFpMul_PE y8_ippsGFpMul_PE +#define ippsGFpGetInfo y8_ippsGFpGetInfo +#define ippsGFpECGetSize y8_ippsGFpECGetSize +#define ippsGFpECInit y8_ippsGFpECInit +#define ippsGFpECSet y8_ippsGFpECSet +#define ippsGFpECSetSubgroup y8_ippsGFpECSetSubgroup +#define ippsGFpECInitStd128r1 y8_ippsGFpECInitStd128r1 +#define ippsGFpECInitStd128r2 y8_ippsGFpECInitStd128r2 +#define ippsGFpECInitStd192r1 y8_ippsGFpECInitStd192r1 +#define ippsGFpECInitStd224r1 y8_ippsGFpECInitStd224r1 +#define ippsGFpECInitStd256r1 y8_ippsGFpECInitStd256r1 +#define ippsGFpECInitStd384r1 y8_ippsGFpECInitStd384r1 +#define ippsGFpECInitStd521r1 y8_ippsGFpECInitStd521r1 +#define ippsGFpECInitStdSM2 y8_ippsGFpECInitStdSM2 +#define ippsGFpECInitStdBN256 y8_ippsGFpECInitStdBN256 +#define ippsGFpECBindGxyTblStd192r1 y8_ippsGFpECBindGxyTblStd192r1 +#define ippsGFpECBindGxyTblStd224r1 y8_ippsGFpECBindGxyTblStd224r1 +#define ippsGFpECBindGxyTblStd256r1 y8_ippsGFpECBindGxyTblStd256r1 +#define ippsGFpECBindGxyTblStd384r1 y8_ippsGFpECBindGxyTblStd384r1 +#define ippsGFpECBindGxyTblStd521r1 y8_ippsGFpECBindGxyTblStd521r1 +#define ippsGFpECBindGxyTblStdSM2 y8_ippsGFpECBindGxyTblStdSM2 +#define ippsGFpECGet y8_ippsGFpECGet +#define ippsGFpECGetSubgroup y8_ippsGFpECGetSubgroup +#define ippsGFpECScratchBufferSize y8_ippsGFpECScratchBufferSize +#define ippsGFpECVerify y8_ippsGFpECVerify +#define ippsGFpECPointGetSize y8_ippsGFpECPointGetSize +#define ippsGFpECPointInit y8_ippsGFpECPointInit +#define ippsGFpECSetPointAtInfinity y8_ippsGFpECSetPointAtInfinity +#define ippsGFpECSetPoint y8_ippsGFpECSetPoint +#define ippsGFpECSetPointRegular y8_ippsGFpECSetPointRegular +#define ippsGFpECSetPointRandom y8_ippsGFpECSetPointRandom +#define ippsGFpECMakePoint y8_ippsGFpECMakePoint +#define ippsGFpECSetPointHash y8_ippsGFpECSetPointHash +#define ippsGFpECSetPointHashBackCompatible y8_ippsGFpECSetPointHashBackCompatible +#define ippsGFpECSetPointHash_rmf y8_ippsGFpECSetPointHash_rmf +#define ippsGFpECSetPointHashBackCompatible_rmf y8_ippsGFpECSetPointHashBackCompatible_rmf +#define ippsGFpECGetPoint y8_ippsGFpECGetPoint +#define ippsGFpECGetPointRegular y8_ippsGFpECGetPointRegular +#define ippsGFpECSetPointOctString y8_ippsGFpECSetPointOctString +#define ippsGFpECGetPointOctString y8_ippsGFpECGetPointOctString +#define ippsGFpECTstPoint y8_ippsGFpECTstPoint +#define ippsGFpECTstPointInSubgroup y8_ippsGFpECTstPointInSubgroup +#define ippsGFpECCpyPoint y8_ippsGFpECCpyPoint +#define ippsGFpECCmpPoint y8_ippsGFpECCmpPoint +#define ippsGFpECNegPoint y8_ippsGFpECNegPoint +#define ippsGFpECAddPoint y8_ippsGFpECAddPoint +#define ippsGFpECMulPoint y8_ippsGFpECMulPoint +#define ippsGFpECPrivateKey y8_ippsGFpECPrivateKey +#define ippsGFpECPublicKey y8_ippsGFpECPublicKey +#define ippsGFpECTstKeyPair y8_ippsGFpECTstKeyPair +#define ippsGFpECSharedSecretDH y8_ippsGFpECSharedSecretDH +#define ippsGFpECSharedSecretDHC y8_ippsGFpECSharedSecretDHC +#define ippsGFpECMessageRepresentationSM2 y8_ippsGFpECMessageRepresentationSM2 +#define ippsGFpECSignDSA y8_ippsGFpECSignDSA +#define ippsGFpECVerifyDSA y8_ippsGFpECVerifyDSA +#define ippsGFpECSignNR y8_ippsGFpECSignNR +#define ippsGFpECVerifyNR y8_ippsGFpECVerifyNR +#define ippsGFpECSignSM2 y8_ippsGFpECSignSM2 +#define ippsGFpECVerifySM2 y8_ippsGFpECVerifySM2 +#define ippsGFpECUserIDHashSM2 y8_ippsGFpECUserIDHashSM2 +#define ippsGFpECKeyExchangeSM2_GetSize y8_ippsGFpECKeyExchangeSM2_GetSize +#define ippsGFpECKeyExchangeSM2_Init y8_ippsGFpECKeyExchangeSM2_Init +#define ippsGFpECKeyExchangeSM2_Setup y8_ippsGFpECKeyExchangeSM2_Setup +#define ippsGFpECKeyExchangeSM2_SharedKey y8_ippsGFpECKeyExchangeSM2_SharedKey +#define ippsGFpECKeyExchangeSM2_Confirm y8_ippsGFpECKeyExchangeSM2_Confirm +#define ippsGFpECGetInfo_GF y8_ippsGFpECGetInfo_GF +#define ippsGFpECESGetSize_SM2 y8_ippsGFpECESGetSize_SM2 +#define ippsGFpECESInit_SM2 y8_ippsGFpECESInit_SM2 +#define ippsGFpECESSetKey_SM2 y8_ippsGFpECESSetKey_SM2 +#define ippsGFpECESStart_SM2 y8_ippsGFpECESStart_SM2 +#define ippsGFpECESEncrypt_SM2 y8_ippsGFpECESEncrypt_SM2 +#define ippsGFpECESDecrypt_SM2 y8_ippsGFpECESDecrypt_SM2 +#define ippsGFpECESFinal_SM2 y8_ippsGFpECESFinal_SM2 +#define ippsGFpECESGetBuffersSize_SM2 y8_ippsGFpECESGetBuffersSize_SM2 +#define ippsGFpECEncryptSM2_Ext_EncMsgSize y8_ippsGFpECEncryptSM2_Ext_EncMsgSize +#define ippsGFpECEncryptSM2_Ext y8_ippsGFpECEncryptSM2_Ext +#define ippsGFpECDecryptSM2_Ext_DecMsgSize y8_ippsGFpECDecryptSM2_Ext_DecMsgSize +#define ippsGFpECDecryptSM2_Ext y8_ippsGFpECDecryptSM2_Ext diff --git a/plugin/ippcp/library/src/.clang-format b/plugin/ippcp/library/src/.clang-format new file mode 100644 index 000000000..ce65d7ef6 --- /dev/null +++ b/plugin/ippcp/library/src/.clang-format @@ -0,0 +1,35 @@ + +#=============================================================================== +# Copyright (C) 2022 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +BasedOnStyle: WebKit + +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: None +ColumnLimit: 150 +ContinuationIndentWidth: 3 +IndentWidth: 3 +MaxEmptyLinesToKeep: 3 +PointerAlignment: Right +SortIncludes: false diff --git a/plugin/ippcp/library/src/.gitattributes b/plugin/ippcp/library/src/.gitattributes new file mode 100644 index 000000000..30e477339 --- /dev/null +++ b/plugin/ippcp/library/src/.gitattributes @@ -0,0 +1,33 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.h text +*.cpp text +*.def text +*.rc text +*.i text +*.sh text +*.csh text +*.mk text +*.java text +*.csv text +*.lst text + +# Declare files that will always have CRLF line endings on checkout. +*.sln text eol=crlf +*.bat text eol=crlf + +# Declare files that will always have LF line endings on checkout. +*.py text eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.lib binary +*.dll binary +*.dylib binary +*.so binary +*.a binary diff --git a/plugin/ippcp/library/src/BUILD.md b/plugin/ippcp/library/src/BUILD.md new file mode 100644 index 000000000..c23d5bdc9 --- /dev/null +++ b/plugin/ippcp/library/src/BUILD.md @@ -0,0 +1,304 @@ +# How to Build Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) + +- [Software Requirements](#software-requirements) + - [Common tools](#common-tools) + - [Linux* OS](#linux-os) + - [Windows* OS](#windows-os) + - [macOS*](#macos) +- [Building Intel IPP Cryptography on Linux\* OS](#building-intel-ipp-cryptography-on-linux-os) +- [Building Intel IPP Cryptography on Windows\* OS](#building-intel-ipp-cryptography-on-windows-os) +- [Building Intel IPP Cryptography on macOS\*](#building-intel-ipp-cryptography-on-macos) +- [CMake Build Options](#cmake-build-options) + - [Common for all operating systems](#common-for-all-operating-systems) + - [Windows\* OS](#windows-os) + - [Linux\* OS](#linux-os) +- [CMake Commands FAQ](#cmake-commands-faq) + - [How to build a 32-bit library?](#how-to-build-a-32-bit-library) + - [How to build a 64-bit generic library without any CPU-specific optimizations?](#how-to-build-a-64-bit-generic-library-without-any-cpu-specific-optimizations) + - [How to build two libraries with optimizations for Intel® Advanced Vector Extensions 2 and Intel® Advanced Vector Extensions 512 instruction sets?](#how-to-build-two-libraries-with-optimizations-for-intel-advanced-vector-extensions-2-and-intel-advanced-vector-extensions-512-instruction-sets) + - [How to build a library to work in a kernel space?](#how-to-build-a-library-to-work-in-a-kernel-space) +- [Incorporating Intel® IPP Cryptography sources into custom build system](#incorporating-intel-ipp-cryptography-sources-into-custom-build-system) + + +## Software Requirements +### Common tools +- [CMake\*](https://cmake.org/download) 3.15 or higher +- Python 3.8.1 +- The Netwide Assembler (NASM) 2.15 +- OpenSSL\* 3.0.8 or higher + +### Linux* OS +- [Common tools](#common-tools) +- Intel® C++ Compiler Classic 2021.9 for Linux\* OS +- GCC 8.3 +- GCC 9.1 +- GCC 10.1 +- GCC 11.1 +- Clang 9.0 +- Clang 12.0 +- GNU binutils 2.32 +### Windows* OS +- [Common tools](#common-tools) +- Intel® C++ Compiler Classic 2021.9 for Windows\* OS +- Microsoft Visual C++ Compiler\* version 19.16 provided by Microsoft Visual Studio\* 2017 version 15.9 +> **NOTE:** Support for this compiler version will be removed from Intel IPP Cryptography starting 2021.4 release. If you use it for building Intel IPP Cryptography library, please plan on migrating to a newer supported version of Microsoft Visual C++ Compiler\*. +- Microsoft Visual C++ Compiler\* version 19.24 provided by Microsoft Visual Studio\* 2019 version 16.4 +- Microsoft Visual C++ Compiler\* version 19.30 provided by Microsoft Visual Studio\* 2022 version 17.0 +> **NOTE:** [CMake\*](https://cmake.org/download) 3.21 or higher is required to build using Microsoft Visual Studio\* 2022. +### macOS* +- [Common tools](#common-tools) +- Intel® C++ Compiler Classic 2021.9 for macOS\* +## Building Intel IPP Cryptography on Linux\* OS + +The software was validated on: + +- Red Hat\* Enterprise Linux\* 8 + +To build the Intel IPP Cryptography library on Linux\* OS, complete the following steps: +1. Clone the source code from GitHub\* as follows: + + ``` bash + git clone --recursive https://github.com/intel/ipp-crypto + ``` + +2. Set the environment for one of the supported C/C++ compilers. + + *Example for Intel® Compiler:* + + ```bash + source /opt/intel/bin/compilervars.sh intel64 + ``` + + For details, refer to the [Intel® C++ Compiler Developer Guide and Reference](https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/current/specifying-the-location-of-compiler-components.html). + +3. Run CMake\* in the command line. + + *Examples*: + + For Intel® C++ Compiler: + + ``` bash + CC=icc CXX=icpc cmake CMakeLists.txt -B_build -DARCH=intel64 + ``` + + For GCC: + + ``` bash + CC=gcc CXX=g++ cmake CMakeLists.txt -B_build -DARCH=intel64 + ``` + + For the complete list of supported CMake options, refer to the [CMake Build Options](#cmake-build-options) section. + +4. Navigate to the build folder specified in the CMake command line and start the build: + + ```bash + cd _build + make all + ``` + + You can find the built libraries in the `/.build//lib` directory. + +## Building Intel IPP Cryptography on Windows\* OS + +The software was validated on: + +- Windows Server\* 2019 + +To build the Intel IPP Cryptography library on Windows* OS, complete the following steps: + +1. Clone the source code from GitHub\* as follows: + + ``` bash + git clone --recursive https://github.com/intel/ipp-crypto + ``` + +2. Set the environment variables for one of the supported C/C++ compilers. + For Intel® Compiler instructions, refer to the [Intel® C++ Compiler Developer Guide and Reference](https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/current/overview.html). + For MSVC* Compiler, refer to [Use the MSVC toolset from the command line](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2017). + +3. Run CMake\* in the command line. + + *Examples*: + + For Intel® C++ Compiler and Visual Studio\* 2019: + + ``` bash + cmake CMakeLists.txt -B_build -G"Visual Studio 16 2019" -T"Intel C++ Compiler 19.2" -Ax64 + ``` + + For MSVC\* Compiler and Visual Studio\* 2019: + + ``` bash + cmake CMakeLists.txt -B_build -G"Visual Studio 16 2019" -Ax64 + ``` + + For the complete list of supported CMake options, please refer to the [CMake Build Options](#cmake-build-options) section. + +4. Navigate to the build folder, specified in the CMake command line and start build either from Visual Studio\* or in the command line. + + *Build from command line:* + + ```bash + cmake --build . --parallel 4 --target ALL_BUILD --config Release + ``` + + *Build from Visual Studio\*:* + Open the Microsoft Visual Studio\* solution `Intel(R) IPP Crypto.sln`, choose project (build target) from the Solution Explorer and run the build. + +## Building Intel IPP Cryptography on macOS\* + +The software was validated on: + +- macOS\* 12.0 + +To build the Intel IPP Cryptography library on macOS*, complete the following steps: + +1. Clone the source code from GitHub\* as follows: + + ``` bash + git clone --recursive https://github.com/intel/ipp-crypto + ``` + +2. Set the environment variables for one of the supported C/C++ compilers. + + *Example for Intel® Compiler:* + + ```bash + source /opt/intel/bin/compilervars.sh intel64 + ``` + + For details, refer to the [Intel® C++ Compiler Developer Guide and Reference](https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/current/specifying-the-location-of-compiler-components.html) + +3. Run CMake\* in the command line. + + *Examples*: + + For Intel® C++ Compiler: + + ``` bash + CC=icc CXX=icpc cmake CMakeLists.txt -B_build -DARCH=intel64 + ``` + + For the complete list of supported CMake options, refer to the [CMake Build Options](#cmake-build-options) section. + +4. Navigate to the build folder specified in the CMake command line and start the build: + + ```bash + cd _build + make all + ``` + + You can find the built libraries in the `/.build//lib` directory. + +## CMake Build Options + +### Common for all operating systems + +- `-B` - defines the build directory. This is the directory where CMake puts the generated Microsoft Visual Studio\* solution or makefiles. + +- `-DARCH=` - on Linux* OS and macOS*, defines the target architecture for the build of the Intel IPP Cryptography library. + > **NOTE:** On Windows* OS, use `-G`/`-A` instead. See the description of these options [below](#windows-os-1). + +- `-DMERGED_BLD:BOOL=` - optional. Defines the configuration of the Intel IPP Cryptography library to build: + + - `-DMERGED_BLD:BOOL=on`: default configuration. It includes the following steps: + - Build of a dispatched static library with all available optimizations + - Build of a dispatched dynamic library with all available optimizations + - Generation of the single-CPU headers (for details, refer to [this](./OVERVIEW.md) section) + + - `-DMERGED_BLD:BOOL=off`: build of one static library per optimization; build of one dynamic library per optimization. + +- `-DPLATFORM_LIST=""` - optional, works only if `-DMERGED_BLD:BOOL=off` is set. Sets target platforms for the code to be compiled. See the supported platforms list [here](./OVERVIEW.md). + + - Example for Linux\* OS and the IA-32 architecture: + `-DPLATFORM_LIST="m7;s8;p8;g9;h9"` + + - Example for Linux\* OS and the Intel® 64 architecture: + `-DPLATFORM_LIST="w7;n8;y8;e9;l9;k0"` +- `-DIPPCP_CUSTOM_BUILD=""` - optional, works only if `-DMERGED_BLD:BOOL=off` is set, i.e. only for 1CPU libraries. Enables the CPU feature dispatching mask at compile-time based on the provided list. + + - Currently supported by the library custom features dispatching: + 1. Intel® Advanced Encryption Standard New Instructions (Intel® AES-NI) code-path enabling: `IPPCP_AES_ON;IPPCP_CLMUL_ON` + 2. Intel® Advanced Vector Extensions 512 (Intel(R) AVX-512) and vector extensions of Intel(R) AES New Instructions (Intel(R) AES-NI) code-path enabling: `IPPCP_VAES_ON;IPPCP_VCLMUL_ON` + - Example: + `-DPLATFORM_LIST="IPPCP_AES_ON;IPPCP_CLMUL_ON"` - this combination enables Intel® AES-NI in all 1CPU libraries, which contains this code path. + - Example of using a combination of CPU features: + `-DPLATFORM_LIST="IPPCP_AES_ON;IPPCP_CLMUL_ON;IPPCP_VAES_ON;IPPCP_VCLMUL_ON"` - in this combination the highest available feature in each 1CPU library will be enabled (e.g. for `"y8"` it’s Intel® AES-NI and for `"k1"` - Intel AVX-512 VAES) + +### Windows\* OS + +- `-G""` - defines the native build system CMake will generate from the input files. + Refer to CMake [documentation](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) for the Visual Studio\* generators options. + +- `-A` - for Visual Studio\* 2019+, defines the target architecture for the build of the Intel IPP Cryptography library. + +- `-T` - defines the compiler for building. + For example, to use Intel® Compiler, specify `-T"Intel C++ Compiler 19.1"`. + +> **NOTE:** Refer to CMake [documentation](https://cmake.org/cmake/help/latest/manual/ccmake.1.html) for more information on these options. + +### Linux\* OS + +- `-DNONPIC_LIB:BOOL=` - optional. Defines whether the built library is position-dependent or not. + + - `-DNONPIC_LIB:BOOL=off:` default. Position-independent code. + + - `-DNONPIC_LIB:BOOL=on:` position-dependent code. + +## CMake Commands FAQ + +### How to build a 32-bit library? + +`cmake CMakeLists.txt -B_build -DARCH=ia32` + +### How to build a 64-bit generic library without any CPU-specific optimizations? + +`cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=off -DPLATFORM_LIST=mx` + +### How to build two libraries with optimizations for Intel® Advanced Vector Extensions 2 and Intel® Advanced Vector Extensions 512 instruction sets? + +`cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=off -DPLATFORM_LIST="l9;k0"` + +### How to build a library to work in a kernel space? + +`cmake CMakeLists.txt -B_build -DARCH=intel64 -DNONPIC_LIB:BOOL=on` + +### How to specify path to OpenSSL\* +`cmake CMakeLists.txt -B_build -DARCH=intel64 -DOPENSSL_INCLUDE_DIR=/path/to/openssl/include -DOPENSSL_LIBRARIES=/path/to/openssl/lib -DOPENSSL_ROOT_DIR=/path/to/openssl` + +## Incorporating Intel® IPP Cryptography sources into custom build system + +You can include Intel IPP Cryptography sources into some arbitrary project's CMake build system and build them with it. + +Here is the minimal working example: + +``` bash +cmake_minimum_required(VERSION 3.14) + +project("test_proj") + +# `crypto` is the repository root folder of Intel IPP Cryptography +add_subdirectory(crypto) +include_directories(crypto/include) + +# 'main.cpp' is some arbitrary project's source file +add_executable("test_proj" main.cpp) +# `ippcp_s` is the target name of static library in the Intel IPP Cryptography build system. +# This static library will be built automatically, when you build your project. +target_link_libraries("test_proj" "ippcp_s") +``` + +Also you can use CMake module to find the Intel IPP Cryptography library installed on the system. The module location is `examples/FindIPPCrypto.cmake` and here is the example of its usage: + +``` bash +find_package(IPPCrypto REQUIRED MODULE) + +if (NOT IPPCRYPTO_FOUND) + message(FATAL_ERROR "No Intel IPP Cryptography library found on the system.") +endif() + +# If Intel IPP Cryptography is found, the following variables will be defined: +# `IPPCRYPTO_LIBRARIES` - static library name +# `IPPCRYPTO_INCLUDE_DIRS` - path to Intel IPP Cryptography headers +# `IPPCRYPTO_ROOT_DIR` - library root dir (a folder with 'include' and 'lib' directories) +``` diff --git a/plugin/ippcp/library/src/CHANGELOG.md b/plugin/ippcp/library/src/CHANGELOG.md new file mode 100644 index 000000000..9c38d14fe --- /dev/null +++ b/plugin/ippcp/library/src/CHANGELOG.md @@ -0,0 +1,128 @@ +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) + +This is a list of notable changes to Intel(R) IPP Cryptography, in reverse chronological order. + +## Intel(R) IPP Cryptography 2021.9 +- Added optimized RSA-2048 code for multi-buffer (8 buffers) Intel® AVX-512 implementation. +- Added Intel® Advanced Vector Extensions 2 (Intel® AVX2) vector extensions of Intel® AES New Instructions (Intel® AES-NI) optimization for AES-GCM algorithm. + +## Intel(R) IPP Cryptography 2021.8 +- Crypto Multi-buffer library was extended with XTS mode of SM4 algorithm. + +## Intel(R) IPP Cryptography 2021.7.1 +- Added re-initialization API for AES-GCM context - ippsAES_GCMReinit. The use-case of this function is very specific, please, refer to the documentation for more details. + +## Intel(R) IPP Cryptography 2021.7 +- Mitigation for Frequency Throttling Side-Channel Attack ([Frequency Throttling Side Channel Software Guidance for Cryptography Implementations](https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/frequency-throttling-side-channel-guidance.html)) was added for ECB, CMAC and GCM modes of AES (for more details refer to ippsAESSetupNoise, ippsAES_GCMSetupNoise and ippsAES_CMACSetupNoise). +- Crypto Multi-buffer library was extended with CCM and GCM modes of SM4 algorithm. +- In Crypto Multi-buffer library in-place mode of executing (when pa_out == pa_inp) was fixed for SM4 CBC and CFB modes. +- New API that updates pointer to IppsHashMethod context inside the IppsHashState_rmf state was added (please, refer to ippsHashStateMethodSet_ API). +- ippsHMAC_Pack(_rmf), ippsHMAC_Unpack(_rmf) APIs were fixed - context id is set up properly now during the packing-unpacking process. + +## Intel(R) IPP Cryptography 2021.6 +- EC cryptography functionality for the NIST curves p256r1, p384r1, p521r1 and SM2 curve was enabled with Intel® Advanced Vector Extensions 512 (Intel® AVX-512) IFMA instructions. +- EC cryptography functionality input parameters checking was improved by adding keys boundaries check. +- AES-GCM input parameters checking was improved by adding input text boundary check. +- An issue in AES-CTR Intel® Advanced Vector Extensions 512 (Intel® AVX-512) code path related to handling of last partial block was fixed. +- The ability to build Intel® IPP Cryptography library and Crypto Multi buffer library with Microsoft Visual C++ Compiler\* version 19.30 provided by Microsoft Visual Studio\* 2022 version 17.0 was added. + +## Intel(R) IPP Cryptography 2021.5 +- AES-GCM small packets processing was optimized for Intel® Advanced Vector Extensions 512 (Intel® AVX-512) code path. +- The ability to build Intel® IPP Cryptography library and Crypto Multi buffer library with GCC\* 10, GCC\* 11, Clang\* 9, Clang\* 12 and Intel® C++ Compiler Classic 2021.3 was added. +- The ability to build Crypto Multi buffer library with OpenSSL\* 3.0 was added. + +## Intel(R) IPP Cryptography 2021.4 +- Crypto Multi buffer library was extended with ECB, CBC, CTR, OFB and CFB modes of SM4 algorithm. +- Crypto Multi buffer library was extended with EC SM2 public key generation, ECDHE and ECDSA (Sign and Verify) algorithms. +- Crypto Multi buffer library extended with ECDSA Ed25519 verify algorithm. +- Crypto Multi buffer library extended with modular exponent algorithm. + +## Intel(R) IPP Cryptography 2021.3 +- Enabled ECDSA Ed25519sign crypto multi buffer API within Intel® IPP Cryptography for 3rd Generation Intel® Xeon® Processor Scalable and 10th Gen Intel® Core™ Processors. +- Enabled RSA single buffer 3k, 4k within Intel® IPP Cryptography for 3rd Generation Intel® Xeon® Processor Scalable and 10th Gen Intel® Core™ Processors. +- Fixed Intel® IPP Cryptography AES-GCM decryption incorrect tag issue while dispatching on processors supported with Intel® Advanced Vector Extensions 512 (Intel® AVX-512). + +## Intel(R) IPP Cryptography 2021.2 +- Crypto Multi buffer library was extended with ECDSA (Sign) and ECDHE for the NIST curves p521r1. +- Added ECDSA verify with new Instruction Set Architecture(ISA) for the NIST curve p384r1, p256r1 and p521r1. +- Added SM3 multi buffer with new Instruction Set Architecture(ISA). +- Added new Intel® IPP Cryptography pre-defined hash algorithm APIs ippsHashMethodGetSize and ippsHashMethodInit. +- RSA-2048 decryption (CRT) was enabled for Intel(R) Microarchitecture Code Named Ice Lake. +- Crypto Multi buffer library was extended with ECDSA (Sign) and ECDHE for the NIST curves p256r1 and p384r1. +- Fixed a build issue that affect build of the Intel(R) IPP Cryptography library with MSVC\* compiler on Windows\* OS. +- Duplicated APIs of HASH, HMAC, MGF, RSA, ECCP functionality were marked as deprecated. For more information see [Deprecation notes](./DEPRECATION_NOTES.md) +- Added examples demonstrating usage of SMS4-CBC encryption and decryption. + +## Intel(R) IPP Cryptography 2020 Update 3 +- Refactoring of Crypto Multi buffer library, added build and installation of crypto_mb dynamic library and CPU features detection. +- Added multi buffer implementation of AES-CFB optimized with Intel(R) AES New Instructions (Intel(R) AES-NI) and vector extensions of Intel(R) AES New Instructions (Intel(R) AES-NI) instruction sets. +- Fixed compatibility issue with x64 ABI (restored non-volatile registers after function call in Intel® Advanced Vector Extensions (Intel® AVX)/Intel® Advanced Vector Extensions 2 (Intel® AVX2) assembly code). +- Updated Intel IPP Custom Library Tool. + +## Intel(R) IPP Cryptography 2020 Update 2 +- AES-GCM algorithm was optimized for Intel(R) Microarchitecture Code Named Cascade Lake with Intel(R) AES New Instructions (Intel(R) AES-NI). +- Crypto Multi buffer library installation instructions update. The Readme file of Crypto Multi buffer Library was updated by information about possible installation fails in specific environment. +- Position Independent Execution (PIE) option was added to Crypto Multi buffer Library build scripts. +- AES-XTS optimization for Intel(R) Microarchitecture Code Named Ice Lake with vector extensions of Intel(R) AES New Instructions (Intel(R) AES-NI) was improved. +- SM4-ECB, SM4-CBC and SM4-CTR were enabled for Intel(R) Microarchitecture Code Named Ice Lake with Intel(R) Advanced Vector Extensions 512 (Intel(R) AVX-512) GFNI instructions. +- Added support of Clang 9.0 for Linux and Clang 11.0 for MacOS compilers. +- Added example of RSA Multi Buffer Encryption/Decryption usage. +- The library was enabled with Intel® Control-Flow Enforcement Technology (Intel® CET) on Linux and Windows. +- Changed API of ippsGFpECSignDSA, ippsGFpECSignNR and ippsGFpECSignSM2 functions: const-ness requirement of private ephemeral keys is removed and now the ephemeral keys are cleaned up after signing. + +## Intel(R) IPP Cryptography 2020 Update 1 +- Added RSA IFMA Muti-buffer Library. +- Added RSA PSS multi buffer signature generation and verification. +- Added RSA PKCS#1 v1.5 multi buffer signature generation and verification. +- Removed Android support. Use Linux libraries instead. +- Fixed all build warnings for supported GCC\* and MSVC\* compilers. +- Assembler sources were migrated to NASM\* assembler. + +## Intel(R) IPP Cryptography 2020 +- Added RSA multi buffer encryption and decryption. +- Added Intel(R) IPP Cryptography library examples: AES-CTR, RSA-OAEP, RSA-PSS. +- Fixed code generation for kernel code model in Linux* Intel(R) 64 non-PIC builds. +- Fixes in Intel IPP Custom Library Tool. +- Added Microsoft\* Visual Studio\* 2019 build support. +- A dynamic dispatcher library and a set of CPU-optimized dynamic libraries were replaced by a single merged dynamic library with an internal dispatcher. +- Removed deprecated multi-threaded version of the library. +- Removed Supplemental Streaming SIMD Extensions 3 (SSSE3) support on macOS. + +## Intel(R) IPP Cryptography 2019 Update 5 +- 1024, 2048, 3072 and 4096 bit RSA were enabled with AVX512 IFMA instructions. +- AES-GCM was enabled with vector extensions of Intel(R) AES New Instructions (Intel(R) AES-NI). +- AES-XTS was enabled with vector extensions of Intel(R) AES New Instructions (Intel(R) AES-NI). +- Fixed GCC\* and MSVC\* builds of IA32 generic CPU code (pure C) with -DMERGED_BLD:BOOL=off option. +- Added single-CPU headers generation. +- Aligned structure of the build output directory across all supported operation systems. +- AES-CFB was enabled with vector extensions of Intel(R) AES New Instructions (Intel(R) AES-NI). +- ippsGFpECGetPointOctString and ippsGFpECSetPointOctString now support elliptic curves over both prime and extended finite fields. +- Added the ability to build the Intel(R) IPP Cryptography library with GCC\* 8.2. + +## Intel(R) IPP Cryptography 2019 Update 4 +- AES-ECB, AES-CBC and AES-CTR were enabled with vector extensions of Intel(R) AES New Instructions (Intel(R) AES-NI). +- Improved optimization of Intel(R) AES-NI based CMAC. +- Added the ippsGFpGetInfo function, which returns information about a finite field. +- Added the ippsHashGetInfo_rmf function, which returns information about a hash algorithm. +- Fixed selection of CPU-specific code in dynamic/shared libraries. + +## Intel(R) IPP Cryptography 2019 Update 3 +- Added the ability to build the Intel(R) IPP Cryptography library with the Intel(R) C++ Compiler 19. +- Added Intel IPP Custom Library Tool based on Python. + +## Intel(R) IPP Cryptography 2019 Update 1 +- Added the ability to build the Intel(R) IPP Cryptography library with the Microsoft\* Visual C++ Compiler 2017. +- Added the new SM2 encryption scheme. +- Changed the range of the message being signed or verified by EC and DLP. +- Deprecated the ARCFour functionality. +- Fixed a potential security problem in the signing functions over elliptic curves. +- Fixed a potential security problem in the key expansion function for AES Encryption. +- Fixed a potential security problem in the AES-CTR cipher functions. +- Fixed a potential security problem in the AES-GCM cipher functions. +- Fixed a potential security problem in the DLP signing and key generation functions. +- Fixed minor issues with DLP functions. +- Fixed some of the compilation warnings observed when building the static dispatcher on Windows\* OS. + +------------------------------------------------------------------------ +Intel is a trademark of Intel Corporation or its subsidiaries in the U.S. and/or other countries. +\* Other names and brands may be claimed as the property of others. diff --git a/plugin/ippcp/library/src/CMakeLists.txt b/plugin/ippcp/library/src/CMakeLists.txt new file mode 100644 index 000000000..552a81225 --- /dev/null +++ b/plugin/ippcp/library/src/CMakeLists.txt @@ -0,0 +1,238 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +# + +cmake_minimum_required(VERSION 3.12) + +include("${CMAKE_CURRENT_SOURCE_DIR}/sources/cmake/ippcp-utils.cmake") +ippcp_getlibversion("${CMAKE_CURRENT_SOURCE_DIR}/include/ippversion.h") +if ((NOT DEFINED IPPCP_VERSION_MAJOR) OR + (NOT DEFINED IPPCP_VERSION_MINOR) OR + (NOT DEFINED IPPCP_VERSION_UPDATE) OR + (NOT DEFINED IPPCP_INTERFACE_VERSION_MAJOR) OR + (NOT DEFINED IPPCP_INTERFACE_VERSION_MINOR)) + message(WARNING "Cannot parse version from ippversion.h file. The project might be corrupted.") +endif() + +set(PROJECT_FULL_NAME "Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography)") +set(PROJECT_NAME "Intel(R) IPP Crypto") +set(PROJECT_VERSION ${IPPCP_VERSION}) + +set(LIB_NAME ippcp) + +set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE) + +cmake_policy(SET CMP0042 NEW) +cmake_policy(SET CMP0054 NEW) +cmake_policy(SET CMP0068 NEW) + +if("${CMAKE_GENERATOR}" STREQUAL "NMake Makefiles") + if(NOT(C_COMPILER STREQUAL "")) + set(CMAKE_C_COMPILER ${C_COMPILER}) + endif() + if(NOT(CXX_COMPILER STREQUAL "")) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER}) + endif() +endif() + +project(${PROJECT_NAME} + VERSION ${PROJECT_VERSION} + LANGUAGES C CXX) + +if("${CMAKE_BUILD_TYPE}" STREQUAL "") + message(STATUS "CMAKE_BUILD_TYPE is unset, defaulting to Release") + set(CMAKE_BUILD_TYPE "Release") +endif() + +find_package(Python REQUIRED) + +if(WIN32 AND (${CMAKE_GENERATOR} MATCHES "Visual Studio")) + if(CMAKE_GENERATOR_PLATFORM) # VS 2019+ -A param + if(${CMAKE_GENERATOR_PLATFORM} MATCHES "x64") + set(ARCH intel64) + else() + set(ARCH ia32) + endif() + else() + if(${CMAKE_GENERATOR} MATCHES "Win64") # old way of platform setting for VS + set(ARCH intel64) + else() + set(ARCH ia32) + endif() + endif() +else() + if (NOT "${ARCH}" STREQUAL "intel64" AND NOT "${ARCH}" STREQUAL "ia32") + message(FATAL_ERROR "Please, set the ARCH parameter to ia32 or intel64") + endif() +endif(WIN32 AND (${CMAKE_GENERATOR} MATCHES "Visual Studio")) + +if ((NOT NONPIC_LIB) AND (NOT CODE_COVERAGE)) + set(DYNAMIC_LIB ON) +else() + set(DYNAMIC_LIB OFF) +endif() + +if("${MERGED_BLD}" STREQUAL "") + set(MERGED_BLD ON) +endif() + +# Set default installation directories +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + if (UNIX) + set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/intel/ippcp_${PROJECT_VERSION}" CACHE PATH "..." FORCE) + else() + set(CMAKE_INSTALL_PREFIX "c:/Program Files (x86)/IntelSWTools/ippcp_${PROJECT_VERSION}" CACHE PATH "..." FORCE) + endif() +endif() + +set(IPP_CRYPTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +set(IPP_CRYPTO_INCLUDE_DIR "${IPP_CRYPTO_DIR}/include") +set(IPP_CRYPTO_SOURCES_INCLUDE_DIR "${IPP_CRYPTO_DIR}/sources/include") +set(IPP_CRYPTO_SOURCES_DIR "${IPP_CRYPTO_DIR}/sources/ippcp") +set(IPP_CRYPTO_DISPATCHER_DIR "${IPP_CRYPTO_DIR}/sources/dispatcher") +set(TOOLS_DIR "${IPP_CRYPTO_DIR}/tools") + +if(NOT CMAKE_OUTPUT_DIR) + set(CMAKE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/.build") +endif() + +message (STATUS "CMAKE_VERSION ......................... " ${CMAKE_VERSION}) + +if(UNIX AND NOT APPLE) + if(NONPIC_LIB) + message (STATUS "NONPIC_LIB ............................ on") + else() + message (STATUS "NONPIC_LIB ............................ off") + endif() +else() + set(${NONPIC_LIB} false) +endif(UNIX AND NOT APPLE) + +set(NONPIC_SUBDIRECTORY "") +if(NONPIC_LIB) + set(NONPIC_SUBDIRECTORY "/nonpic") +endif() + +foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} ) + string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${CMAKE_OUTPUT_DIR}/${OUTPUTCONFIG}/lib${NONPIC_SUBDIRECTORY}") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${CMAKE_OUTPUT_DIR}/${OUTPUTCONFIG}/lib${NONPIC_SUBDIRECTORY}") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${CMAKE_OUTPUT_DIR}/${OUTPUTCONFIG}/lib${NONPIC_SUBDIRECTORY}") +endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) + +if(${CMAKE_BUILD_TYPE} STREQUAL "Release") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE}") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE}") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}") +endif() + +if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG}") + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG}") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}") +endif() + +message (STATUS "PROJECT ............................... " ${PROJECT_FULL_NAME}) +message (STATUS "CMAKE_BINARY_DIR ...................... " ${CMAKE_BINARY_DIR}) +message (STATUS "CMAKE_OUTPUT_DIR ...................... " ${CMAKE_OUTPUT_DIR}) +message (STATUS "CMAKE_SOURCE_DIR ...................... " ${CMAKE_SOURCE_DIR}) +message (STATUS "IPP_CRYPTO_DIR ........................ " ${IPP_CRYPTO_DIR}) +message (STATUS "CMAKE_GENERATOR ....................... " ${CMAKE_GENERATOR}) +message (STATUS "CMAKE_C_COMPILER_ID ................... " ${CMAKE_C_COMPILER_ID}) +message (STATUS "CMAKE_CXX_COMPILER_ID ................. " ${CMAKE_CXX_COMPILER_ID}) +message (STATUS "IPP_CRYPTO_INCLUDE_DIR ................ " ${IPP_CRYPTO_INCLUDE_DIR}) +message (STATUS "IPP_CRYPTO_SOURCES_INCLUDE_DIR ........ " ${IPP_CRYPTO_SOURCES_INCLUDE_DIR}) +message (STATUS "IPP_CRYPTO_SOURCES_DIR ................ " ${IPP_CRYPTO_SOURCES_DIR}) +message (STATUS "ARCH .................................. " ${ARCH}) +message (STATUS "DYNAMIC_LIB ........................... " ${DYNAMIC_LIB}) +message (STATUS "CMAKE_INSTALL_PREFIX .................. " ${CMAKE_INSTALL_PREFIX}) + +if(Python_Interpreter_FOUND) + message (STATUS "PYTHON_VERSION_STRING ................. " ${Python_VERSION}) +else() + message (STATUS "PYTHON_VERSION_STRING ................. Python not found" ) +endif() + +if(MERGED_BLD) + message (STATUS "MERGED_BLD ............................ on") +else() + message (STATUS "MERGED_BLD ............................ off") +endif() + +option(BUILD_EXAMPLES "Build examples" OFF) +if(BUILD_EXAMPLES) + message (STATUS "BUILD_EXAMPLES ........................ on") +else() + message (STATUS "BUILD_EXAMPLES ........................ off") +endif() + +# Build with sanitizers +set(SANITIZERS OFF) +if(BUILD_WITH_SANITIZERS AND UNIX AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER_EQUAL "12.0.0") + set(ASAN OFF) + set(UBSAN OFF) + set(MSAN OFF) + if("${BUILD_WITH_SANITIZERS}" MATCHES "address") + set(ASAN ON) + list(APPEND PRINT_TYPES_OF_SANITIZERS_LIST "address") + endif() + if("${BUILD_WITH_SANITIZERS}" MATCHES "undefined") + set(UBSAN ON) + list(APPEND PRINT_TYPES_OF_SANITIZERS_LIST "undefined") + endif() + if("${BUILD_WITH_SANITIZERS}" MATCHES "memory") + set(MSAN ON) + list(APPEND PRINT_TYPES_OF_SANITIZERS_LIST "memory") + endif() + if((ASAN OR UBSAN) AND MSAN) + message (FATAL_ERROR "Can not use address | undefined sanitizers with memory sanitizer") + endif() + if(ASAN OR UBSAN OR MSAN) + set(SANITIZERS ON) + endif() +endif() +if(SANITIZERS) + list(JOIN PRINT_TYPES_OF_SANITIZERS_LIST "," PRINT_TYPES_OF_SANITIZERS_STRING) + message (STATUS "BUILD_WITH_SANITIZERS ................. on (${PRINT_TYPES_OF_SANITIZERS_STRING})") +else() + message (STATUS "BUILD_WITH_SANITIZERS ................. off - use -DBUILD_WITH_SANITIZERS=[memory,address,undefined] with CLANG compiler to enable this option") +endif(SANITIZERS) + +if((UNIX) AND (NOT APPLE)) + set(LINUX ON) +else() + set(LINUX OFF) +endif() + +add_subdirectory(sources/ippcp) +if(EXISTS "${IPP_CRYPTO_DIR}/tests/") + add_subdirectory(tests) +endif() +if(EXISTS "${IPP_CRYPTO_DIR}/perf_tests/") + add_subdirectory(perf_tests) +endif() + +if(BUILD_EXAMPLES) + # This helps to organize examples projects structure in IDE by folders + set_property(GLOBAL PROPERTY USE_FOLDERS ON) + set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets") + + add_subdirectory(examples) +endif() diff --git a/plugin/ippcp/library/src/CONST_TIME_EXECUTION_TESTING.md b/plugin/ippcp/library/src/CONST_TIME_EXECUTION_TESTING.md new file mode 100644 index 000000000..61868362d --- /dev/null +++ b/plugin/ippcp/library/src/CONST_TIME_EXECUTION_TESTING.md @@ -0,0 +1,162 @@ +# Scope of the Constant-time execution testing of Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) + +- [General information](#general) +- [Scope for ippcp library](#ippcp) +- [Scope for crypto_mb library](#cryptomb) + +## General information
+- Testing is conducted under Linux for 64-bit Intel® IPP Cryptography built with the following compilers: + - Intel® C++ Compiler 19.1 + - Intel® C++ Compiler Classic 2021.9 + - GCC 8.3 + - GCC 9.1 + - GCC 10.1 + - GCC 11.1 + - Clang 9.0 + - Clang 12.0 +- Tested platforms: w7, n8, y8, e9, l9, k0 (see the supported platforms list [here](./OVERVIEW.md#target-optimization-codes-in-function-names)). +- Testing scope described below is guaranteed to pass for **`release`** branches. This is not guaranteed for the **`develop`** branch ([branches description](./OVERVIEW.md#branches-description)) +- Information about Pin-Based Constant Execution Checker can be found [here](https://github.com/intel/pin_based_cec) + +## ippcp library
+| Tested Function | Parameters | +| :----------------------: | :----------------------------------------------------------------------------------------: | +| ippsAESEncryptCBC | Different key length:
128, 192, 256 bits | +| ippsAESDecryptCBC | Different key length:
128, 192, 256 bits | +| ippsAESEncryptCBC_CS1 | Different key length:
128, 192, 256 bits | +| ippsAESDecryptCBC_CS1 | Different key length:
128, 192, 256 bits | +| ippsAESEncryptCBC_CS2 | Different key length:
128, 192, 256 bits | +| ippsAESDecryptCBC_CS2 | Different key length:
128, 192, 256 bits | +| ippsAESEncryptCBC_CS3 | Different key length:
128, 192, 256 bits | +| ippsAESDecryptCBC_CS3 | Different key length:
128, 192, 256 bits | +| ippsAES_CCMEncrypt | Different key length:
128, 192, 256 bits | +| ippsAES_CCMDecrypt | Different key length:
128, 192, 256 bits | +| ippsAESEncryptCFB | Different key length:
128, 192, 256 bits | +| ippsAESDecryptCFB | Different key length:
128, 192, 256 bits | +| ippsAES_CMACUpdate | Different key length:
128, 192, 256 bits | +| ippsAES_CMACFinal | Different key length:
128, 192, 256 bits | +| ippsAESEncryptCTR | Different key length:
128, 192, 256 bits | +| ippsAESDecryptCTR | Different key length:
128, 192, 256 bits | +| ippsAESEncryptECB | Different key length:
128, 192, 256 bits | +| ippsAESDecryptECB | Different key length:
128, 192, 256 bits | +| ippsAES_GCMEncrypt | Different key length:
128, 192, 256 bits | +| ippsAES_GCMDecrypt | Different key length:
128, 192, 256 bits | +| ippsAES_GCMStart | Different key length:
128, 192, 256 bits | +| ippsAESEncryptOFB | Different key length:
128, 192, 256 bits | +| ippsAESDecryptOFB | Different key length:
128, 192, 256 bits | +| ippsAES_S2V_CMAC | Different key length:
128, 192, 256 bits | +| ippsAESSetKey | Different key length:
128, 192, 256 bits | +| ippsAES_SIVEncrypt | Different key length:
128, 192, 256 bits | +| ippsAES_SIVDecrypt | Different key length:
128, 192, 256 bits | +| ippsAES_XTSEncrypt | Different key length:
256, 512 bits | +| ippsAES_XTSDecrypt | Different key length:
256, 512 bits | +| ippsAESEncryptXTS_Direct | Different key length:
256, 512 bits | +| ippsAESDecryptXTS_Direct | Different key length:
256, 512 bits | +| ippsCmp_BN | - | +| ippsDLPPublicKey | - | +| ippsDLPSharedSecretDH | - | +| ippsGFpAdd | - | +| ippsGFpAdd_PE | - | +| ippsGFpConj | - | +| ippsGFpECAddPoint | Different curves:
p256r1, p384r1, p521r1 | +| ippsGFpECMulPoint | Different curves:
p224r1, p256r1, p384r1 | +| ippsGFpECNegPoint | Different curves:
p256r1, p384r1, p521r1 | +| ippsGFpECPublicKey | Different curves:
p256r1, p384r1, p521r1 | +| ippsGFpECSharedSecretDH | Different curves:
p256r1, p384r1, p521r1 | +| ippsGFpECSharedSecretDHC | Different curves:
p256r1, p384r1, p521r1 | +| ippsGFpECSignDSA | Different curves:
p256r1, p384r1 | +| ippsGFpECSignNR | Different curves:
p256r1, p384r1 | +| ippsGFpECSignSM2 | - | +| ippsGFpECESStart_SM2 | - | +| ippsGFpECESEncrypt_SM2 | - | +| ippsGFpECESDecrypt_SM2 | - | +| ippsGFpECESFinal_SM2 | - | +| ippsGFpExp | - | +| ippsGFpInv | - | +| ippsGFpMul | - | +| ippsGFpMul_PE | - | +| ippsGFpMultiExp | - | +| ippsGFpNeg | - | +| ippsGFpSub | - | +| ippsGFpSub_PE | - | +| ippsHMACInit_rmf | Different hashes:
sha1, sha256, sha224, sha384, sha512,
sha512-256, sha512-224, sm3 | +| ippsRSA_Decrypt | Different key types and key length:
key type 1, 512 bits
key type 2, 512 bits | +| ippsRSADecrypt_OAEP | Different key types and key length:
key type 1, 512 bits
key type 2, 512 bits | +| ippsRSADecrypt_OAEP_rmf | Different key types and key length:
key type 1, 512 bits
key type 2, 512 bits | +| ippsRSASign_PKCS1v15 | Different key types and key length:
key type 1, 512 bits
key type 2, 512 bits | +| ippsRSASign_PKCS1v15_rmf | Different key types and key length:
key type 1, 512 bits
key type 2, 512 bits | +| ippsRSASign_PSS | Different key types and key length:
key type 1, 512 bits
key type 2, 512 bits | +| ippsRSASign_PSS_rmf | Different key types and key length:
key type 1, 512 bits
key type 2, 512 bits | +| ippsSMS4EncryptCBC | - | +| ippsSMS4DecryptCBC | - | +| ippsSMS4EncryptCBC_CS1 | - | +| ippsSMS4DecryptCBC_CS1 | - | +| ippsSMS4EncryptCBC_CS2 | - | +| ippsSMS4DecryptCBC_CS2 | - | +| ippsSMS4EncryptCBC_CS3 | - | +| ippsSMS4DecryptCBC_CS3 | - | +| ippsSMS4_CCMEncrypt | - | +| ippsSMS4_CCMDecrypt | - | +| ippsSMS4EncryptCFB | - | +| ippsSMS4DecryptCFB | - | +| ippsSMS4EncryptCTR | - | +| ippsSMS4DecryptCTR | - | +| ippsSMS4EncryptECB | - | +| ippsSMS4DecryptECB | - | +| ippsSMS4EncryptOFB | - | +| ippsSMS4DecryptOFB | - | +| ippsSMS4SetKey | - | + +## crypto_mb library
+| Function | Parameters | +| :--------------------------------------: | :---------------------------------------------------: | +| mbx_nistp256_ecpublic_key_mb8 | projective coordinates
affine coordinates | +| mbx_nistp384_ecpublic_key_mb8 | projective coordinates
affine coordinates | +| mbx_nistp521_ecpublic_key_mb8 | projective coordinates
affine coordinates | +| mbx_sm2_ecpublic_key_mb8 | projective coordinates
affine coordinates | +| mbx_nistp256_ecdh_mb8 | projective coordinates
affine coordinates | +| mbx_nistp384_ecdh_mb8 | projective coordinates
affine coordinates | +| mbx_nistp521_ecdh_mb8 | projective coordinates
affine coordinates | +| mbx_nistp256_ecdsa_sign_mb8 | - | +| mbx_nistp384_ecdsa_sign_mb8 | - | +| mbx_nistp521_ecdsa_sign_mb8 | - | +| mbx_nistp256_ecdsa_sign_setup_mb8 | - | +| mbx_nistp384_ecdsa_sign_setup_mb8 | - | +| mbx_nistp521_ecdsa_sign_setup_mb8 | - | +| mbx_nistp256_ecdsa_sign_complete_mb8 | - | +| mbx_nistp384_ecdsa_sign_complete_mb8 | - | +| mbx_nistp521_ecdsa_sign_complete_mb8 | - | +| mbx_nistp256_ecpublic_key_ssl_mb8 | projective coordinates
affine coordinates | +| mbx_nistp384_ecpublic_key_ssl_mb8 | projective coordinates
affine coordinates | +| mbx_nistp521_ecpublic_key_ssl_mb8 | projective coordinates
affine coordinates | +| mbx_sm2_ecpublic_key_ssl_mb8 | projective coordinates
affine coordinates | +| mbx_nistp256_ecdh_ssl_mb8 | projective coordinates
affine coordinates | +| mbx_nistp384_ecdh_ssl_mb8 | projective coordinates
affine coordinates | +| mbx_nistp521_ecdh_ssl_mb8 | projective coordinates
affine coordinates | +| mbx_nistp256_ecdsa_sign_ssl_mb8 | - | +| mbx_nistp384_ecdsa_sign_ssl_mb8 | - | +| mbx_nistp521_ecdsa_sign_ssl_mb8 | - | +| mbx_nistp256_ecdsa_sign_setup_ssl_mb8 | - | +| mbx_nistp384_ecdsa_sign_setup_ssl_mb8 | - | +| mbx_nistp521_ecdsa_sign_setup_ssl_mb8 | - | +| mbx_nistp256_ecdsa_sign_complete_ssl_mb8 | - | +| mbx_nistp384_ecdsa_sign_complete_ssl_mb8 | - | +| mbx_nistp521_ecdsa_sign_complete_ssl_mb8 | - | +| mbx_ed25519_public_key_mb8 | - | +| mbx_ed25519_sign_mb8 | - | +| mbx_rsa_private_mb8 | Different key length:
1024, 2048, 3072, 4096 bits | +| mbx_rsa_private_crt_mb8 | Different key length:
1024, 2048, 3072, 4096 bits | +| mbx_rsa_private_ssl_mb8 | Different key length:
1024, 2048, 3072, 4096 bits | +| mbx_rsa_private_crt_ssl_mb8 | Different key length:
1024, 2048, 3072, 4096 bits | +| mbx_sm2_ecdsa_sign_mb8 | - | +| mbx_sm2_ecdsa_sign_ssl_mb8 | - | +| mbx_sm4_encrypt_ecb_mb16 | - | +| mbx_sm4_decrypt_ecb_mb16 | - | +| mbx_sm4_encrypt_cbc_mb16 | - | +| mbx_sm4_decrypt_cbc_mb16 | - | +| mbx_sm4_encrypt_ctr128_mb16 | - | +| mbx_sm4_encrypt_ofb_mb16 | - | +| mbx_sm4_encrypt_cfb128_mb16 | - | +| mbx_sm4_decrypt_cfb128_mb16 | - | +| mbx_x25519_public_key_mb8 | - | +| mbx_x25519_mb8 | - | diff --git a/plugin/ippcp/library/src/DEPRECATION_NOTES.md b/plugin/ippcp/library/src/DEPRECATION_NOTES.md new file mode 100644 index 000000000..3ef6475c7 --- /dev/null +++ b/plugin/ippcp/library/src/DEPRECATION_NOTES.md @@ -0,0 +1,86 @@ +# Deprecated API in Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) + +This document describes deprecated API in different Intel IPP Cryptography versions and recommendations for transition. + +The deprecated API means it is obsolete and will be removed in one of future Intel IPP Cryptography releases. If you have any concerns, please use the following link for opening a ticket and providing feedback: + +## 2020 Update1 (branch [ipp-crypto_2020_update1](https://github.com/intel/ipp-crypto/tree/ipp-crypto_2020_update1)) + +### Hash Functionality + +| Deprecated | Recommended replacement | +| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------: | +| ippsSHA1GetSize
ippsSHA224GetSize
ippsSHA256GetSize
ippsSHA384GetSize
ippsSHA512GetSize
ippsSM3GetSize
ippsMD5GetSize | ippsHashGetSize_rmf | +| ippsSHA1Init
ippsSHA224Init
ippsSHA256Init
ippsSHA384Init
ippsSHA512Init
ippsSM3Init
ippsMD5Init | ippsHashInit_rmf \* | +| ippsSHA1Duplicate
ippsSHA224Duplicate
ippsSHA256Duplicate
ippsSHA384Duplicate
ippsSHA512Duplicate
ippsSM3Duplicate
ippsMD5Duplicate | ippsHashDuplicate_rmf | +| ippsSHA1Pack, ippsSHA1Unpack
ippsSHA224Pack, ippsSHA224Unpack
ippsSHA256Pack, ippsSHA256Unpack
ippsSHA384Pack, ippsSHA384Unpack
ippsSHA512Pack, ippsSHA512Unpack
ippsSM3Pack, ippsSM3Unpack
ippsMD5Pack, ippsMD5Unpack | ippsHashPack_rmf,
ippsHashUnpack_rmf | +| ippsSHA1Update, ippsSHA1GetTag, ippsSHA1Final
ippsSHA224Update, ippsSHA224GetTag, ippsSHA224Final
ippsSHA256Update, ippsSHA256GetTag, ippsSHA256Final
ippsSHA384Update, ippsSHA384GetTag, ippsSHA384Final
ippsSHA512Update, ippsSHA512GetTag, ippsSHA512Final
ippsSM3Update, ippsSM3GetTag, ippsSM3Final
ippsMD5Update, ippsMD5GetTag, ippsMD5Final | ippsHashUpdate_rmf,
ippsHashGetTag_rmf,
ippsHashFinal_rmf | +| ippsSHA1MessageDigest
ippsSHA224MessageDigest
ippsSHA256MessageDigest
ippsSHA384MessageDigest
ippsSHA512MessageDigest
ippsSM3MessageDigest
ippsMD5MessageDigest | ippsHashMessage_rmf \* | +| ippsHashGetSize | ippsHashGetSize_rmf | +| ippsHashInit \*\* | ippsHashInit_rmf \* | +| ippsHashDuplicate | ippsHashDuplicate_rmf | +| ippsHashPack, ippsHashUnpack | ippsHashPack_rmf, ippsHashUnpack_rmf | +| ippsHashUpdate, ippsHashGetTag,ippsHashFinal | ippsHashUpdate_rmf,ippsHashGetTag_rmf,ippsHashFinal_rmf | +| ippsHashMessage \*\* | ippsHashMessage_rmf \* | + +>\* To choose hash algorithm, specify [IppsHashMethod parameter](#ippshashalgid-to-ippshashmethod-parameter-map) +>\*\* IppsHashAlgId parameter used in ippsHMAC_Init and in ippsHMAC_Message for choosing hash algorithm is deprecated (see Recommended replacement column for alternative in [IppsHashAlgId to IppsHashMethod Parameter Map](#ippshashalgid-to-ippshashmethod-parameter-map) + +### Keyed HMAC Functionality + +| Deprecated | Recommended replacement | +| :------------------------------------------------ | :------------------------------------------------------------: | +| ippsHMAC_GetSize | ippsHMAC_GetSize_rmf | +| ippsHMAC_Init \*\* | ippsHMAC_Init_rmf \* | +| ippsHMAC_Pack, ippsHMAC_Unack, ippsHMAC_Duplicate | ippsHMAC_Pack_rmf, ippsHMAC_Unpack_rmf, ippsHMAC_Duplicate_rmf | +| ippsHMAC_Update, ippsHMAC_Final, ippsHMAC_GetTag | ippsHMAC_Update_rmf, ippsHMAC_Final_rmf, ippsHMAC_GetTag_rmf | +| ippsHMAC_Message \*\* | ippsHMAC_Message_rmf \* | + +>\* To choose hash algorithm, specify [IppsHashMethod parameter](#ippshashalgid-to-ippshashmethod-parameter-map) +>\*\* IppsHashAlgId parameter used in 'ippsHMAC_Init' and in ippsHMAC_Message for choosing hash algorithm is deprecated (see Recommended replacement column for alternative in [IppsHashAlgId to IppsHashMethod Parameter Map](#ippshashalgid-to-ippshashmethod-parameter-map) + + +### MGF Functionality + +| Deprecated | Recommended replacement | +| :--------------- | :---------------------: | +| ippsHMAC_GetSize | ippsHMAC_GetSize_rmf | + +### RSA Encryption and Signature Schemes + +| Deprecated | Recommended replacement | +| :------------------------------------------- | :--------------------------------------------------: | +| ippsRSAEncrypt_OAEP, ippsRSADecrypt_OAEP | ippsRSAEncrypt_OAEP_rmf, ippsRSADecrypt_OAEP_rmf | +| ippsRSASign_PSS, ippsRSAVerify_PSS | ippsRSASign_PSS_rmf, ippsRSAVerify_PSS_rmf | +| ippsRSASign_PKCS1v15, ippsRSAVerify_PKCS1v15 | ippsRSASign_PKCS1v15_rmf, ippsRSAVerify_PKCS1v15_rmf | + + + +### Elliptic Curve Cryptography (ECC) + +| Deprecated | Recommended replacement | +| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| ippsECCPGetSize
ippsECCPGetSizeStd128r1
ippsECCPGetSizeStd128r2
ippsECCPGetSizeStd192r1
ippsECCPGetSizeStd224r1
ippsECCPGetSizeStd256r1
ippsECCPGetSizeStd384r1
ippsECCPGetSizeStd521r1
ippsECCPGetSizeStdSM2 | ippsGFpECGetSize | +| ippsECCPInit
ippsECCPInitStd128r1
ippsECCPInitStd128r2
ippsECCPInitStd192r1
ippsECCPInitStd224r1
ippsECCPInitStd256r1
ippsECCPInitStd384r1
ippsECCPInitStd521r1
ippsECCPInitStdSM2 | ippsGFpECInitStd \*
* ippsGFpECInitStd functions provides both initialization
and set up standard EC set of parameters | +| ippsECCPSet | ippsGFpECSet | +| ippsECCPSetStd | ippsGFpECInitStd \*
* ippsGFpECInitStd functions provides both initialization
and set up standard EC set of parameters | +| ippsECCPSetStd128r1
ippsECCPSetStd128r2
ippsECCPSetStd192r1
ippsECCPSetStd224r1
ippsECCPSetStd256r1
ippsECCPSetStd384r1
ippsECCPSetStd521r1
ippsECCPSetStdSM2 | ippsGFpECInitStd128r1
ippsGFpECInitStd128r2
ippsGFpECInitStd192r1
ippsGFpECInitStd224r1
ippsGFpECInitStd256r1
ippsGFpECInitStd384r1
ippsGFpECInitStd521r1
ippsGFpECInitStdSM2 | +| ippsECCPBindGxyTblStd192r1
ippsECCPBindGxyTblStd224r1
ippsECCPBindGxyTblStd256r1
ippsECCPBindGxyTblStd384r1
ippsECCPBindGxyTblStd521r1
ippsECCPBindGxyTblStdSM2 | ippsGFpECBindGxyTblStd192r1
ippsGFpECBindGxyTblStd224r1
ippsGFpECBindGxyTblStd256r1
ippsGFpECBindGxyTblStd384r1
ippsGFpECBindGxyTblStd521r1
ippsGFpECBindGxyTblStdSM2 | +| ippsECCPGet
ippsECCPGetOrderBitSize
ippsECCPValidate
ippsECCPPointGetSize, ippsECCPPointInit
ippsECCPSetPointAtInfinity
ippsECCPSetPoint,ippsECCPGetPoint
ippsECCPCheckPoint
ippsECCPComparePoint
ippsECCPNegativePoint
ippsECCPAddPoint
ippsECCPMulPointScalar | ippsGFpECGet
ippsGFpECGetSubgroup
ippsGFpECVerify
ippsGFpECPointGetSize, ippsGFpECPointInit
ippsGFpECSetPointAtInfinity
ippsGFpECSetPointRegular,ippsGFpECGetPointRegular
ippsGFpECTstPoint
ippsGFpECCmpPoint
ippsGFpECNegPoint
ippsGFpECAddPoint
ippsGFpECMulPoint | +| ippsECCPGenKeyPair
ippsECCPPublicKey
ippsECCPValidateKeyPair
ippsECCPSetKeyPair | ippsGFpECPrivateKey
ippsGFpECPublicKey
ippsGFpECTstKeyPair
n/a | +| ippsECCPSharedSecretDH
ippsECCPSharedSecretDHC | ippsGFpECSharedSecretDH
ippsGFpECSharedSecretDHC | +| ippsECCPSignDSA
ippsECCPVerifyDSA
ippsECCPSignNR
ippsECCPVerifyNR
ippsECCPSignSM2
ippsECCPVerifySM2 | ippsGFpECSignDSA
ippsGFpECVerifyDSA
ippsGFpECSignNR
ippsGFpECVerifyNR
ippsGFpECSignSM2
ippsGFpECVerifySM2 | + +### IppsHashAlgId to IppsHashMethod Parameter Map + +| Algorithm | IppsHashAlgId (deprecated) | IppsHashMethod (recommended) | Notes | +| :--------: | :------------------------: | :---------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------: | +| SHA1 | ippsHashAlg_SHA1 | ippsHashMethod_SHA1
ippsHashMethod_SHA1_NI
ippsHashMethod_SHA1_TT | Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) not supported
Intel SHA-NI only supported
Automatic switch on Intel SHA-NI, if possible (tick-tock) | +| SHA224 | ippsHashAlg_SHA224 | ippsHashMethod_SHA224
ippsHashMethod_SHA224_NI
ippsHashMethod_SHA224_TT | Intel SHA-NI not supported
Intel SHA-NI only supported
Automatic switch on Intel SHA-NI, if possible supported | +| SHA256 | ippsHashAlg_SHA256 | ippsHashMethod_SHA256
ippsHashMethod_SHA256_NI
ippsHashMethod_SHA256_TT | Intel SHA-NI not supported
Intel SHA-NI only supported
Automatic switch on Intel SHA-NI, if possible supported | +| SHA384 | ippsHashAlg_SHA384 | ippsHashMethod_SHA384 | - | +| SHA512 | ippsHashAgl_SHA512 | ippsHashMethod_SHA512 | - | +| SM3 | ippsHashAlg_SM3 | ippsHashMethod_SM3 | - | +| MD5 | ippsHashAlg_MD5 | ippsHashMethod_MD5 | - | +| SHA512-224 | ippsHashAlg_SHA512_224 | ippsHashMethod_SHA512_224 | - | +| SHA512-256 | ippsHashAlg_SHA512_256 | ippsHashMethod_SHA512_256 | - | diff --git a/plugin/ippcp/library/src/LICENSE b/plugin/ippcp/library/src/LICENSE new file mode 100644 index 000000000..c7047e16b --- /dev/null +++ b/plugin/ippcp/library/src/LICENSE @@ -0,0 +1,234 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + CMake + ------------------------------ + CMake - Cross Platform Makefile Generator + Copyright 2000-2021 Kitware, Inc. and Contributors + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Kitware, Inc. nor the names of Contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/plugin/ippcp/library/src/MAC.md b/plugin/ippcp/library/src/MAC.md new file mode 100644 index 000000000..1f2d1a120 --- /dev/null +++ b/plugin/ippcp/library/src/MAC.md @@ -0,0 +1,23 @@ +## How to build on macOS + +- download Intel CPP Classic compiler from [here](https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#dpcpp-cpp) +- choose offline installer m_cpp-compiler-classic_p_2023.2.0.48999_offline.dmg +- `wget https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/macosx/nasm-2.16.01-macosx.zip` +- extract zip file +- `wget https://www.openssl.org/source/openssl-3.1.2.tar.gz` +- in `openssl-3.1.2` extracted folder : + +``` +./Configure +make +``` + +- in this `src` folder: (or `git clone https://github.com/intel/ipp-crypto` for newer) + +``` +source /opt/intel/oneapi/compiler/2023.2.0/env/vars.sh intel64 +export ASM_NASM=/[your_path_here]/nasm-2.16.01/nasm +CC=icc CXX=icpc cmake CMakeLists.txt -B_build -DARCH=intel64 -DOPENSSL_INCLUDE_DIR=/[your_path_here]/openssl-3.1.2/include -DOPENSSL_LIBRARIES=/[your_path_here]/openssl-3.1.2 -DOPENSSL_ROOT_DIR=/[your_path_here]/openssl-3.1.2 +cd _build +make ippcp_s +``` diff --git a/plugin/ippcp/library/src/OVERVIEW.md b/plugin/ippcp/library/src/OVERVIEW.md new file mode 100644 index 000000000..63b7059a6 --- /dev/null +++ b/plugin/ippcp/library/src/OVERVIEW.md @@ -0,0 +1,208 @@ +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) Library Overview + +- [Repository Structure](#repository-structure) + - [Branches Description](#branches-description) +- [Dispatcher](#dispatcher) + - [CPU Dispatching](#cpu-dispatching) + - [Target Optimization Codes in Function Names](#target-optimization-codes-in-function-names) + - [CPU Feature Dispatching](#cpu-feature-dispatching) + - [How to Avoid Dispatcher in All CPUs Static Library](#how-to-avoid-dispatcher-in-all-cpus-static-library) +- [Library Configurations](#library-configurations) + - [Linkage Mode](#linkage-mode) + - [Code Position](#code-position) + - [Target Instruction Set Architecture (ISA)](#target-instruction-set-architecture-isa) + - [All CPUs Library](#all-cpus-library) + - [Specific ISA Library](#specific-isa-library) + - [Choosing specific ISA from the All CPUs Static Library](#choosing-specific-isa-from-the-all-cpus-static-library) + - [Functionality](#functionality) + - [Static Library with Custom functionality](#static-library-with-custom-functionality) + - [Dynamic Library with Custom functionality](#dynamic-library-with-custom-functionality) + + +[sha256-dispatching]: ./data/images/README-pictures-0-dispatcher.png "Intel IPP Crypto function dispatching scheme" +[library configurations]: ./data/images/README-pictures-1-library-configurations.png "Library configurations picture" +[build targets]: ./data/images/README-pictures-1a-build-targets.png "Build targets picture" +[merged library]: ./data/images/README-pictures-2-merged-library.png "Merged library scheme" +[CPU-specific libraries]: ./data/images/README-pictures-3-cpu-specific-libraries.png "CPU-specific libraries scheme" +[link-with-merged-library]: ./data/images/README-pictures-4a-1CPU.png "Link with Merged Library picture" +[1cpu-link-with-merged-library]: ./data/images/README-pictures-4b-1CPU.png "1CPU link with Merged Library picture" + + +## Repository Structure + +``` bash +├── CHANGELOG.md +├── CMakeLists.txt < Main CMake file +├── examples < Examples of the library usage +├── include < Public headers +├── LICENSE +├── README.md +├── sources +│   ├── cmake < OS-specific CMake files +│   │   ├── linux +│   │   ├── macosx +│   │   └── windows +│   ├── dispatcher < CPU dispatcher generator +│   ├── gen_cpu_spc_header < Single CPU headers generator +│   ├── include < Internal headers +│   └── ippcp < C-sources +│   ├── asm_ia32 < IA-32 Assembler sources +│   ├── asm_intel64 < Intel® 64 Assembler sources +│   └── ifma_rsa_mb < Sources of RSA IFMA Multi-buffer library +└── tools + └── ipp_custom_library_tool_python < Custom Library Tool +``` + +### Branches Description + +- `develop` - snapshots of the library under active development. +Contains code that may not be fully functional and that Intel may substantially modify in development of a production version. +- `ipp_crypto_` - source code of the official production release ``. + +## Dispatcher + +### CPU Dispatching + +For the best performance, Intel IPP Cryptography uses multiple implementations of each function, optimized for various CPUs, and the [library version targeted for any CPU](#all-cpus-library) contains all of these implementations. + +With the dispatcher, the library detects an available CPU in a runtime and chooses the best for the current hardware version of a function. The process of dispatching is transparent and you can always call a generic function as illustrated at the picture below. + +![Dispatcher picture][sha256-dispatching] + +The prefix before the function name ("m7_", "n8_", etc) is a naming convention for the function implementations that are included in the [library with dispatcher](#all-cpus-library). It refers to the CPU instruction set for which the function is optimized (for all available prefixes see the [table](#target-optimization-codes-in-function-names) below). + +The dispatcher is designed to add no performance overhead when the library is initialized, in other words, when CPU features are detected. You can initialize the library either explicitly in advance by calling the dedicated function [ippcpInit()](https://www.intel.com/content/www/us/en/docs/ipp-crypto/developer-reference/current/init.html) or it will be done implicitly during the first call of any function of the library. + +By default, the dispatcher chooses the most appropriate optimization for the current hardware, but it is possible to apply the user-chosen one using the [ippcpSetCpuFeatures()](https://www.intel.com/content/www/us/en/docs/ipp-crypto/developer-guide-oneapi/current/support-functions.html) function. + +#### Target Optimization Codes in Function Names + +| IA-32 Intel® architecture | Intel® 64 architecture | Meaning | +| ------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------ | +| px | mx | Generic code without hardware specific optimizations suitable for any CPU | +| w7 | - | Optimized for processors with Intel® Streaming SIMD Extensions 2 (Intel® SSE2) | +| - | m7 | Optimized for processors with Intel® SSE3 | +| s8 | n8 | Optimized for processors with Supplemental Streaming SIMD Extensions 3 (SSSE3) | +| p8 | y8 | Optimized for processors with Intel® SSE4.2 | +| g9 | e9 | Optimized for processors with Intel® Advanced Vector Extensions (Intel® AVX) | +| h9 | l9 | Optimized for processors with Intel® Advanced Vector Extensions 2 (Intel® AVX2) | +| - | k0 | Optimized for processors with Intel® Advanced Vector Extensions 512 (Intel® AVX-512) (formerly codenamed SkyLake) | +| - | k1 | Optimized for processors with Intel® Advanced Vector Extensions 512 (Intel® AVX-512) (formerly codenamed IceLake) | + +### CPU Feature Dispatching + +Besides CPU dispatching that lets the library choose the general instruction set targeted implementation (for example, Intel SSE4.2, Intel AVX-512, and others), there is more granular dispatching that allows configuring usage of particular CPU features within a single instruction set. For example, Intel AVX-512 instruction set contains a VAES (AES Vector Extensions) feature subset, but not all CPUs that have Intel AVX-512 on board support VAES, so the library can automatically detect it in a runtime and enable corresponding optimizations if the feature subset is available. + +List of CPU feature subsets that the library has special optimizations for: + +- Intel ADX (ADCX, ADOX) +- Intel® Advanced Encryption Standard New Instructions (Intel® AES-NI) +- Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) +- RDRAND +- RDSEED +- CLMUL +- Intel AVX-512 VAES +- Intel AVX-512 IFMA +- Intel AVX-512 GFNI + + > **NOTE:** For some features there is also an opportunity to force their dispatching inside the 1CPU libraries manually during the compile time. For more information please, refer to [common for all operating systems CMake build options](./BUILD.md/#common-for-all-operating-systems). + +### How to Avoid Dispatcher in All CPUs Static Library + +To leave only specific ISA when linking with an [All CPUs Static Library](#all-cpus-library) and drop dispatcher, please refer to [this section](#choosing-specific-isa-from-the-all-cpus-static-library). + +## Library Configurations + +The Intel IPP Cryptography library supports configurations by: + +1) [*Linkage Mode*](#linkage-mode): to produce a static or dynamic library + +2) [*Code Position*](#code-position): to make position independent code (PIC) or non-PIC library + +3) *Target Instruction Set Architecture (ISA)*: + - [All CPUs Library](#all-cpus-library) + - [Specific Instruction Set (ISA) Targeted Library](#specific-isa-library) + - [Choosing specific ISA from the All CPUs Static Library](#choosing-specific-isa-from-the-all-cpus-static-library) + +4) *Functionality*: + - [Library with All functionality](#functionality) + - [Static Library with Custom functionality](#static-library-with-custom-functionality) + - [Dynamic Library with Custom functionality](#dynamic-library-with-custom-functionality) + +All possible configuration combinations are shown in the picture below. + +![Library configurations picture][library configurations] + +### Linkage Mode + +The build system is designed to create a dynamic library from the static one, so both build targets for dynamic and static libraries are always generated during CMake phase. + +The corresponding build target names for the libraries are shown at the picture below (same target names can be used on Linux* OS in the `make` command as well). + +![Build targets picture][build targets] + +### Code Position + +Be default, the Intel IPP Cryptography library is built with the [Position Independent Code (PIC)](https://en.wikipedia.org/wiki/Position-independent_code) option. + +But on Linux* OS, when the library is supposed to work in kernel space, it is possible to compile the static library in a non-PIC mode. For more information about build options, refer to the [Linux* OS build options](./BUILD.md). + +### Target Instruction Set Architecture (ISA) + +#### All CPUs Library + +Each function of the library is built in several instances with optimizations for each supported instruction set (see example for the `func2` function in green). Those functions instances are all included into a single library along with the [dispatcher](#dispatcher) that lets the library choose right function instance depending on current CPU. Such library build is called a merged library build. + +![Merged library picture][merged library] + +The advantage of this configuration is that the library works on any CPU. + +CMake build option: `-DMERGED_BLD:BOOL=on` + +#### Specific ISA Library + +The build system produces several separate libraries each optimized for its own instruction set. In this case, there is no need in [CPU dispatcher](#cpu-dispatching), so the dispatcher is not included, although [features dispatching](#cpu-feature-dispatching) within a single instruction set is in place. + +To specify for what instruction set targeted libraries must be produced, use the `PLATFORM_LIST` CMake variable. It contains semicolon-delimited list of CPU codes (for the complete list of codes see the table in [this](#target-optimization-codes-in-function-names) section). + +For example, to create two libraries - one with SSE4.2 optimizations and another with Intel AVX-512 optimizations, specify `-DPLATFORM_LIST="y8;k0"`. + +![CPU specific libraries picture][CPU-specific libraries] + +The advantage of this configuration is that libraries that contain function versions optimized for only one instruction set have much smaller footprint size than a big merged library. But the price of this advantage is that such libraries only work on a CPU that supports a corresponding instruction set. + +CMake build options: `-DMERGED_BLD:BOOL=off -DPLATFORM_LIST=""` + +#### Choosing specific ISA from the All CPUs Static Library + +When application is being statically linked with All CPUs Static Library, it receives functions implementations for all instruction sets with corresponding [dispatcher](#dispatcher) routines. This works well when CPU, where an application is going to work, is unknown. + +![Link with Merged Library picture][link-with-merged-library] + +But when target CPU is defined, it is possible to take from the static library only required instruction set implementations and avoid [dispatcher](#dispatcher) inclusion. + +![1CPU link with Merged Library picture][1cpu-link-with-merged-library] + +For this purpose, there are several CPU-specific headers (each targets a specific CPU optimization) generated during the merged library build. They are located in the `/.build//include/autogen` directory. + +To enable linking of CPU-specific versions of the library functions, include the appropriate header from the directory above before the primary library header `ippcp.h`. + +It is important to ensure that both processor and operating system supports full capabilities of the target processor. + +### Functionality + +By default, Intel IPP Cryptography libraries (both static and dynamic) contain all functionality that exists in the product. But when footprint size matters, the library can contain only required functionality and have no unused code. + +#### Static Library with Custom functionality + +With the static linking having only required functionality in the library is not so actual as leaving only those parts of a library that are used by application, is automatically managed by linker. + +Considering Intel IPP Cryptography design that implies minimal internal dependencies, the application linked with the Intel IPP Cryptography static library contains only relevant library functionality, and has minimal footprint size. + +#### Dynamic Library with Custom functionality + +To build your own dynamic library containing only the functionality that is necessary for your application, you can use the Intel® IPP Custom Library Tool - a Python tool that consumes pre-built merged (all CPUs) static library to produce a tiny dynamic library. + +The tool is located in the `tools/ipp_custom_library_tool_python` directory. + +Please refer to the [tool documentation](https://www.intel.com/content/www/us/en/docs/ipp/developer-guide-oneapi/current/ipp-custom-library-tool.html) for more information. diff --git a/plugin/ippcp/library/src/README.md b/plugin/ippcp/library/src/README.md new file mode 100644 index 000000000..5e2e6d54f --- /dev/null +++ b/plugin/ippcp/library/src/README.md @@ -0,0 +1,72 @@ +# Intel® Integrated Performance Primitives Cryptography + +[Build Instructions](./BUILD.md) | [Contributing Guide](#how-to-contribute) | [Documentation](#documentation) | [Get Help](#get-help) | [Intel IPP Product Page](https://www.intel.com/content/www/us/en/developer/tools/oneapi/ipp.html) + +Intel® Integrated Performance Primitives (Intel® IPP) Cryptography is a secure, fast and lightweight library of building blocks for cryptography, highly-optimized for various Intel® CPUs. + +## Key Features +The library provides a comprehensive set of routines commonly used for cryptographic operations, including: + - Symmetric Cryptography Primitive Functions: + - AES (ECB, CBC, CTR, OFB, CFB, XTS, GCM, CCM, SIV) + - SM4 (ECB, CBC, CTR, OFB, CFB, CCM) + - TDES (ECB, CBC, CTR, OFB, CFB) + - RC4 +- One-Way Hash Primitives: + - SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 + - MD5 + - SM3 +- Data Authentication Primitive Functions: + - HMAC + - AES-CMAC +- Public Key Cryptography Functions: + - RSA, RSA-OAEP, RSA-PKCS_v15, RSA-PSS + - DLP, DLP-DSA, DLP-DH + - ECC (NIST curves), ECDSA, ECDH, EC-SM2 +- Multi-buffer RSA, ECDSA, SM3, x25519 +- Finite Field Arithmetic Functions +- Big Number Integer Arithmetic Functions +- PRNG/TRNG and Prime Numbers Generation + +## Reasons to Use Intel IPP Cryptography +- Security (constant-time execution for secret processing functions) +- Designed for the small footprint size +- Optimized for different Intel CPUs and instruction set architectures (including hardware cryptography instructions support): + - Intel® Streaming SIMD Extensions 2 (Intel® SSE2) + - Intel® SSE3 + - Intel® SSE4.2 + - Intel® Advanced Vector Extensions (Intel® AVX) + - Intel® Advanced Vector Extensions 2 (Intel® AVX2) + - Intel® Advanced Vector Extensions 512 (Intel® AVX-512) +- Configurable CPU dispatching for the best performance +- Kernel mode compatibility +- Thread-safe design + +## Installation + +[How to Get and Build the Intel IPP Cryptography Library](./BUILD.md) + +## Documentation + +- [Introduction to Intel IPP Cryptography Library](./OVERVIEW.md) +- [Introduction to Crypto Multi-buffer Library](./sources/ippcp/crypto_mb/Readme.md) +- [Intel IPP Cryptography Build Instructions](./BUILD.md) +- [Intel IPP Release Notes](https://www.intel.com/content/www/us/en/developer/articles/release-notes/release-notes-for-oneapi-integrated-performance-primitives.html) +- [Intel IPP Cryptography Developer Reference](https://www.intel.com/content/www/us/en/docs/ipp-crypto/developer-reference/current/overview.html) +- [Intel IPP Documentation](https://www.intel.com/content/www/us/en/developer/tools/oneapi/ipp-documentation.html) + +## Branches Description + +- `develop` - snapshots of the library under active development. +Contains code that may not be fully functional and that Intel may substantially modify in development of a production version. +- `ipp_crypto_` - source code of the official production release ``. + +## How to Contribute + +We welcome community contributions to Intel IPP Cryptography. If you have an idea how to improve the product, let us know about your proposal via the Intel IPP Forum or GitHub* Issues. + +### License +Intel IPP Cryptography is licensed under Apache License, Version 2.0. By contributing to the project, you agree to the license and copyright terms therein and release your contribution under these terms. + +## Certification + +Intel IPP Cryptography library is not certified for FIPS-140-2 (Security Requirements for Cryptographic Modules) and CMVP (Cryptographic Module Validation Program). diff --git a/plugin/ippcp/library/src/SECURITY.md b/plugin/ippcp/library/src/SECURITY.md new file mode 100644 index 000000000..ca4ec45af --- /dev/null +++ b/plugin/ippcp/library/src/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +## Reporting a Security Vulnerability + +Visit [https://intel.com/security](https://intel.com/security) for information on how to report security vulnerabilities. + +**Do not report any security vulnerability as a regular issue in this repository.** + +Include the following information in your report: + +- Description of the security problem +- Steps to reproduce +- Expected behavior +- Environment where the problem is reproduced: OS, compiler (including version), versions of ippcp / crypto_mb libraries +- Any additional information that may be relevant diff --git a/plugin/ippcp/library/src/THIRD-PARTY-PROGRAMS.txt b/plugin/ippcp/library/src/THIRD-PARTY-PROGRAMS.txt new file mode 100644 index 000000000..ba4c3b565 --- /dev/null +++ b/plugin/ippcp/library/src/THIRD-PARTY-PROGRAMS.txt @@ -0,0 +1,37 @@ +Intel(R) Integrated Performance Primitives Cryptography Third Party Programs File + +This file contains the list of third party software (“third party programs”) contained in the Intel software and their required notices and/or license terms. +This third party software, even if included with the distribution of the Intel software, may be governed by separate license terms, including without limitation, third party license terms, other Intel software license terms, and open source software license terms. +These separate license terms govern your use of the third party programs as set forth in the “third-party-programs.txt” or other similarly-named text file. + +Third party programs and their corresponding required notices and/or license terms are listed +below. + +------------------------------------------------------------- + +1. Intel(R) Multi-Buffer Crypto for IPSec Library + +Copyright (c) 2012-2021, Intel Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/plugin/ippcp/library/src/data/images/README-pictures-0-dispatcher.png b/plugin/ippcp/library/src/data/images/README-pictures-0-dispatcher.png new file mode 100644 index 000000000..2113b319d Binary files /dev/null and b/plugin/ippcp/library/src/data/images/README-pictures-0-dispatcher.png differ diff --git a/plugin/ippcp/library/src/data/images/README-pictures-1-library-configurations.png b/plugin/ippcp/library/src/data/images/README-pictures-1-library-configurations.png new file mode 100644 index 000000000..cabfca56a Binary files /dev/null and b/plugin/ippcp/library/src/data/images/README-pictures-1-library-configurations.png differ diff --git a/plugin/ippcp/library/src/data/images/README-pictures-1a-build-targets.png b/plugin/ippcp/library/src/data/images/README-pictures-1a-build-targets.png new file mode 100644 index 000000000..02df8b1e4 Binary files /dev/null and b/plugin/ippcp/library/src/data/images/README-pictures-1a-build-targets.png differ diff --git a/plugin/ippcp/library/src/data/images/README-pictures-2-merged-library.png b/plugin/ippcp/library/src/data/images/README-pictures-2-merged-library.png new file mode 100644 index 000000000..d844f4f1d Binary files /dev/null and b/plugin/ippcp/library/src/data/images/README-pictures-2-merged-library.png differ diff --git a/plugin/ippcp/library/src/data/images/README-pictures-3-cpu-specific-libraries.png b/plugin/ippcp/library/src/data/images/README-pictures-3-cpu-specific-libraries.png new file mode 100644 index 000000000..623c2c277 Binary files /dev/null and b/plugin/ippcp/library/src/data/images/README-pictures-3-cpu-specific-libraries.png differ diff --git a/plugin/ippcp/library/src/data/images/README-pictures-4a-1CPU.png b/plugin/ippcp/library/src/data/images/README-pictures-4a-1CPU.png new file mode 100644 index 000000000..ffde859ec Binary files /dev/null and b/plugin/ippcp/library/src/data/images/README-pictures-4a-1CPU.png differ diff --git a/plugin/ippcp/library/src/data/images/README-pictures-4b-1CPU.png b/plugin/ippcp/library/src/data/images/README-pictures-4b-1CPU.png new file mode 100644 index 000000000..3dd807bfc Binary files /dev/null and b/plugin/ippcp/library/src/data/images/README-pictures-4b-1CPU.png differ diff --git a/plugin/ippcp/library/src/examples/CMakeLists.txt b/plugin/ippcp/library/src/examples/CMakeLists.txt new file mode 100644 index 000000000..cfb184d49 --- /dev/null +++ b/plugin/ippcp/library/src/examples/CMakeLists.txt @@ -0,0 +1,123 @@ +#=============================================================================== +# Copyright (C) 2019 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) examples +# + +# List of examples for targets generation +set(IPPCP_EXAMPLES + # AES examples + aes/aes-256-ctr-encryption.cpp + aes/aes-256-ctr-decryption.cpp + # DSA + dsa/dsa-dlp-sha-1-verification.cpp + dsa/dsa-dlp-sha-256-verification.cpp + # RSA SSA-PSS examples + rsa/rsa-3k-pss-sha384-type1-signature.cpp + rsa/rsa-1k-pss-sha1-verification.cpp + # RSA OAEP examples + rsa/rsa-1k-oaep-sha1-encryption.cpp + rsa/rsa-1k-oaep-sha1-type2-decryption.cpp + # SMS4 examples + sms4/sms4-128-cbc-encryption.cpp + sms4/sms4-128-cbc-decryption.cpp + ) + +cmake_policy(SET CMP0003 NEW) + +# Custom target to build ALL examples at once +add_custom_target(ippcp_examples_all) +set_target_properties(ippcp_examples_all PROPERTIES FOLDER "examples") + +function(ippcp_define_example out_target source_file category) + # Extract file name without directory or longest extension + get_filename_component(name "${source_file}" NAME_WE) + # Add suffix for nonpic build + if (NONPIC_LIB) + set(suffix "-nonpic") + endif() + set(local_target "example_${name}${suffix}") + # link additional sources if defined in categoryOptions.cmake + set(additional_sources "${category}_CATEGORY_COMMON_SOURCES") + add_executable(${local_target} "${source_file}" + $<$:${${additional_sources}}>) + # Static linking with merged lib is only supported + set(LIBRARY_NAMES_LIST ${IPPCP_LIB_MERGED}) + ippcp_example_set_build_options(${local_target} "${LIBRARY_NAMES_LIST}") + set_target_properties(${local_target} PROPERTIES + PROJECT_LABEL "(example) ${name}" # Set name of the target in IDE + FOLDER "examples/${category}" # Group projects in solution folder + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_OUTPUT_DIR}/$>/examples" # Set output directory for examples in the build folder + RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_OUTPUT_DIR}/$>/examples" + COMPILE_DEFINITIONS _NO_IPP_DEPRECATED) # ignore deprecation warnings + + # Add a single target to build all examples of the same category (e.g. 'make ippcp_examples_aes') + set(parent_target ippcp_examples_${category}) + if(NOT TARGET ${parent_target}) + add_custom_target(${parent_target}) + set_target_properties(${parent_target} PROPERTIES FOLDER "examples") + if(TARGET ippcp_examples_all) + add_dependencies(ippcp_examples_all ${parent_target}) + endif() + endif() + add_dependencies(${parent_target} ${local_target}) + set(${out_target} ${local_target} PARENT_SCOPE) +endfunction() + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_LIST_DIR) +# Build with standalone library + cmake_minimum_required(VERSION 3.1) + + project("Intel IPP Cryptography Examples" CXX) + set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE) + + option(BUILD_EXAMPLES "Build examples" ON) + + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + find_package(IPPCrypto REQUIRED MODULE) + + if (NOT IPPCRYPTO_FOUND) + message(FATAL_ERROR "No Intel IPP Cryptography library found on the system. To build examples with pre-built library, please specify -DIPPCRYPTO_ROOT_DIR= option, where is the path to directory that contains include/ and lib/ folders of Intel IPP Cryptography product.") + endif() + + # Define library to link + list(GET IPPCRYPTO_LIBRARIES 0 IPPCP_LIB_MERGED) + # Define include folder + set(IPP_CRYPTO_INCLUDE_DIR ${IPPCRYPTO_INCLUDE_DIRS}) + # Define output directory + if(NOT CMAKE_OUTPUT_DIR) + set(CMAKE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/.build") + endif() +else() +# Build with library sources + if(NOT BUILD_EXAMPLES OR NOT MERGED_BLD) + message(FATAL_ERROR "Only merged library build is currently supported for Intel IPP Cryptography examples. Use -DMERGED_BLD:BOOL=on options.") + endif() +endif() + +include(examplesBuildOptions.cmake) + +foreach(example_filename ${IPPCP_EXAMPLES}) + # Extract example category from its subdirectory + get_filename_component(category "${example_filename}" DIRECTORY) + + # Source additional options that may exist for category + include(${category}/categoryOptions.cmake OPTIONAL) + + ippcp_define_example(example ${example_filename} ${category}) +endforeach() diff --git a/plugin/ippcp/library/src/examples/README.md b/plugin/ippcp/library/src/examples/README.md new file mode 100644 index 000000000..a26241547 --- /dev/null +++ b/plugin/ippcp/library/src/examples/README.md @@ -0,0 +1,95 @@ +# Building usage examples of Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) library + +## System requirements + +- CMake 3.15 + +## Build with library sources + +Only merged library (cmake option `-DMERGED_BLD:BOOL=ON`) builds are supported for the examples. + +1. Navigate to the library sources root and run cmake to generate a library build procedure with the `-DBUILD_EXAMPLES:BOOL=ON` + option. + + On Linux\*/macOS\*: + + `cmake CMakeLists.txt -B_build -DARCH=intel64 -DMERGED_BLD:BOOL=ON -DBUILD_EXAMPLES:BOOL=ON` + + On Windows\*: + + `cmake CMakeLists.txt -B_build -G [-T"Intel® C++ Compiler "] -DBUILD_EXAMPLES:BOOL=ON` + + For the Visual Studio\* generators options, please refer to the CMake help. + The toolchain switch is optional, specify it if you want to build the library and examples using Intel® C++ Compiler. + + For the list of supported compiler versions or other cmake build options, please refer to the library root README.md file. + +2. On Linux\*/macOS\*, build with `make -j8 `. You can use the following targets: + + - To build an invididual example, use targets started with the *example_* string (like *example_aes-256-ctr-encryption*). + + - To build all examples of a single specific category, use target *ippcp_examples_\* (like *ippcp_examples_aes*). + + - To build all examples, use target *ippcp_examples_all*. + +3. On Windows\* OS open generated Visual Studio\* solution in the IDE, select the appropriate project (individual example, + all examples by category or the whole set of examples) in the *examples* folder of project structure in IDE and run **Build**. + + To run the build from the command line, open "Developer Command Prompt for VS \" console and run the cmake command: + + `cmake --build _build --target --config Release`, + + where '_build' is the path to CMake build directory. + +## Build with pre-built library + +1. Navigate to the *examples* folder and run the cmake command below. + + On Linux\*/macOS\*: + + `cmake CMakeLists.txt -B_build` + + On Windows\* OS it is required to specify a generator (`-G` option) and optionally a toolchain (`-T` option) + to build with Intel® C++ Compiler. Example: + + `cmake CMakeLists.txt -B_build -G [-T"Intel C++ Compiler "]` + + For the Visual Studio\* generators options, please refer to the CMake help. + +2. The build system will scan the system for the Intel IPP Cryptography library. + If it is found, you’ll see the following message: + + ``` + -- Found Intel IPP Cryptography at: /home/user/intel/ippcp + -- Configuring done + ``` + + If the library is not found automatically, you can specify the path to the library root folder + (where the include/ and lib/ directories are located) using the `-DIPPCRYPTO_ROOT_DIR=` option. + +3. Run the build process as described in the [Build with library sources](#build-with-library-sources). + + +# How to add a new example into Intel IPP Cryptography library: + +1. Choose a category (a folder), where to put the example, and a filename. Use + existing folders where applicable. + The file name should be as follows: "\-\-\-\.cpp" + E.g.: "rsa-1k-oaep-sha1-type2-decryption.cpp" for the example of RSA category. + +2. Write an example keeping its source code formatting consistent with other + examples as much as possible. The "aes/aes-256-ctr-encryption.cpp" can be used + as a reference. + +3. Use Doxygen annotations for the file description, global variables and + macros. The *main()* function shall not use doxygen annotations inside + (otherwise they disappear in the source code section of an example page in + the generated documentation). + +4. Add the example to the build: open *examples/CMakeLists.txt* file and add the + new file to the *IPPCP_EXAMPLES* list. + +5. Make sure it can be built using Intel IPP Cryptography examples build procedure, and it + works correctly. + +You are ready to submit a pull request! diff --git a/plugin/ippcp/library/src/examples/aes/aes-256-ctr-decryption.cpp b/plugin/ippcp/library/src/examples/aes/aes-256-ctr-decryption.cpp new file mode 100644 index 000000000..3945c4ad6 --- /dev/null +++ b/plugin/ippcp/library/src/examples/aes/aes-256-ctr-decryption.cpp @@ -0,0 +1,137 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief AES Counter mode of operation (CTR) example + * + * This example demonstrates usage of AES block cipher with 256-bit key + * run with CTR mode of operation. Decryption scheme. + * + * The CTR mode of operation is implemented according to the + * "NIST Special Publication 800-38A: Recommendation for Block Cipher Modes of + * Operation" document: + * + * https://csrc.nist.gov/publications/detail/sp/800-38a/final + * + */ + +#include + +#include "ippcp.h" +#include "examples_common.h" + +/*! AES block size in bytes */ +static const int AES_BLOCK_SIZE = 16; + +/*! Key size in bytes */ +static const int KEY_SIZE = 32; + +/*! Message size in bytes */ +static const int SRC_LEN = 16; + +/*! Plain text */ +static Ipp8u plainText[SRC_LEN] = { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a +}; + +/*! Cipher text */ +static Ipp8u cipherText[SRC_LEN] = { + 0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5, + 0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28 +}; + +/*! 256-bit secret key */ +static Ipp8u key256[KEY_SIZE] = { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 +}; + +/*! Initial counter for CTR mode. + * Size of counter for AES-CTR shall be equal to the size of AES block (16 bytes). + */ +static Ipp8u initialCounter[AES_BLOCK_SIZE] = { + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff +}; + +/*! Main function */ +int main(void) +{ + /* Length of changeable bits in a counter (can be value starting from 1 till block size 128) */ + const Ipp32u counterLen = 128; + + /* Size of AES context structure. It will be set up in ippsAESGetSize(). */ + int ctxSize = 0; + + Ipp8u pOut[SRC_LEN] = {}; + Ipp8u pCounter[AES_BLOCK_SIZE] = {}; + + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Pointer to AES context structure */ + IppsAESSpec* pAES = 0; + + do { + /* 1. Get size needed for AES context structure */ + status = ippsAESGetSize(&ctxSize); + if (!checkStatus("ippsAESGetSize", ippStsNoErr, status)) + return status; + + /* 2. Allocate memory for AES context structure */ + pAES = (IppsAESSpec*)(new Ipp8u[ctxSize]); + if (NULL == pAES) { + printf("ERROR: Cannot allocate memory (%d bytes) for AES context\n", ctxSize); + return -1; + } + + /* 3. Initialize AES context */ + status = ippsAESInit(key256, sizeof(key256), pAES, ctxSize); + if (!checkStatus("ippsAESInit", ippStsNoErr, status)) + break; + + /* Initialize counter before decryption. + * An updated counter value will be stored here after ippsAESDecryptCTR finishes. + */ + memcpy(pCounter, initialCounter, sizeof(initialCounter)); + + /* 4. Decryption */ + status = ippsAESDecryptCTR(cipherText, pOut, sizeof(cipherText), pAES, pCounter, counterLen); + if (!checkStatus("ippsAESDecryptCTR", ippStsNoErr, status)) + break; + + /* Compare decrypted message and original text */ + if (0 != memcmp(pOut, plainText, sizeof(plainText))) { + printf("ERROR: Decrypted and plain text messages do not match\n"); + break; + } + } while (0); + + /* 5. Remove secret and release resources */ + ippsAESInit(0, KEY_SIZE, pAES, ctxSize); + if (pAES) delete [] (Ipp8u*)pAES; + + PRINT_EXAMPLE_STATUS("ippsAESDecryptCTR", "AES-CTR 256 Decryption", !status); + + return status; +} diff --git a/plugin/ippcp/library/src/examples/aes/aes-256-ctr-encryption.cpp b/plugin/ippcp/library/src/examples/aes/aes-256-ctr-encryption.cpp new file mode 100644 index 000000000..a384a163a --- /dev/null +++ b/plugin/ippcp/library/src/examples/aes/aes-256-ctr-encryption.cpp @@ -0,0 +1,137 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief AES Counter mode of operation (CTR) example + * + * This example demonstrates usage of AES block cipher with 256-bit key + * run with CTR mode of operation. Encryption scheme. + * + * The CTR mode of operation is implemented according to the + * "NIST Special Publication 800-38A: Recommendation for Block Cipher Modes of + * Operation" document: + * + * https://csrc.nist.gov/publications/detail/sp/800-38a/final + * + */ + +#include + +#include "ippcp.h" +#include "examples_common.h" + +/*! AES block size in bytes */ +static const int AES_BLOCK_SIZE = 16; + +/*! Key size in bytes */ +static const int KEY_SIZE = 32; + +/*! Message size in bytes */ +static const int SRC_LEN = 16; + +/*! Plain text */ +static Ipp8u plainText[SRC_LEN] = { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a +}; + +/*! Cipher text */ +static Ipp8u cipherText[SRC_LEN] = { + 0x60,0x1e,0xc3,0x13,0x77,0x57,0x89,0xa5, + 0xb7,0xa7,0xf5,0x04,0xbb,0xf3,0xd2,0x28 +}; + +/*! 256-bit secret key */ +static Ipp8u key256[KEY_SIZE] = { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 +}; + +/*! Initial counter for CTR mode. + * Size of counter for AES-CTR shall be equal to the size of AES block (16 bytes). + */ +static Ipp8u initialCounter[AES_BLOCK_SIZE] = { + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff +}; + +/*! Main function */ +int main(void) +{ + /* Length of changeable bits in a counter (can be value starting from 1 till block size 128) */ + const Ipp32u counterLen = 128; + + /* Size of AES context structure. It will be set up in ippsAESGetSize(). */ + int ctxSize = 0; + + Ipp8u pOut[SRC_LEN] = {}; + Ipp8u pCounter[AES_BLOCK_SIZE] = {}; + + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Pointer to AES context structure */ + IppsAESSpec* pAES = 0; + + do { + /* 1. Get size needed for AES context structure */ + status = ippsAESGetSize(&ctxSize); + if (!checkStatus("ippsAESGetSize", ippStsNoErr, status)) + return status; + + /* 2. Allocate memory for AES context structure */ + pAES = (IppsAESSpec*)(new Ipp8u[ctxSize]); + if (NULL == pAES) { + printf("ERROR: Cannot allocate memory (%d bytes) for AES context\n", ctxSize); + return -1; + } + + /* 3. Initialize AES context */ + status = ippsAESInit(key256, sizeof(key256), pAES, ctxSize); + if (!checkStatus("ippsAESInit", ippStsNoErr, status)) + break; + + /* Initialize counter before encryption. + * An updated counter value will be stored here after ippsAESEncryptCTR finishes. + */ + memcpy(pCounter, initialCounter, sizeof(initialCounter)); + + /* 4. Encryption */ + status = ippsAESEncryptCTR(plainText, pOut, sizeof(plainText), pAES, pCounter, counterLen); + if (!checkStatus("ippsAESEncryptCTR", ippStsNoErr, status)) + break; + + /* Compare encrypted message and reference text */ + if (0 != memcmp(pOut, cipherText, sizeof(cipherText))) { + printf("ERROR: Encrypted and reference messages do not match\n"); + break; + } + } while (0); + + /* 5. Remove secret and release resources */ + ippsAESInit(0, KEY_SIZE, pAES, ctxSize); + if (pAES) delete [] (Ipp8u*)pAES; + + PRINT_EXAMPLE_STATUS("ippsAESEncryptCTR", "AES-CTR 256 Encryption", !status) + + return status; +} diff --git a/plugin/ippcp/library/src/examples/dsa/dsa-dlp-sha-1-verification.cpp b/plugin/ippcp/library/src/examples/dsa/dsa-dlp-sha-1-verification.cpp new file mode 100644 index 000000000..ce6f1fa9b --- /dev/null +++ b/plugin/ippcp/library/src/examples/dsa/dsa-dlp-sha-1-verification.cpp @@ -0,0 +1,183 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief DSA-DLP verification scheme example + * + * This example demonstrates message verification according to + * DSA-DLP scheme with (L = 1024, N = 160) DSA parameters and SHA-1 hash function. + * + * The DSA-DLP scheme is implemented according : Digital Signature Standard (DSS) (FIPS PUB 186-4) (July 2013) + * + * available at: + * + * http://dx.doi.org/10.6028/NIST.FIPS.186-4. + * + */ + +#include + +#include "bignum.h" +#include "examples_common.h" +#include "ippcp.h" + +/*! Parameters DSA-DLP scheme */ +static const int L_BIT = 1024; +static const int N_BIT = 160; + +/*! Message size in bytes */ +static const int MSG_LEN_BYTE = 6; + +/*! Message text */ +static Ipp8u MSG[MSG_LEN_BYTE] = {0x31, 0x32, 0x33, + 0x34, 0x30, 0x30}; + +/*! The generator of the multiplicative subgroup */ +static const BigNumber G( + "0x" + "0835AA8C358BBF01A1846D1206323FABE408B0E98789FCC6239DA14D4B3F86C2" + "76A8F48AA85A59507E620AD1BC745F0F1CBF63EC98C229C2610D77C634D1642E" + "404354771655B2D5662F7A45227178CE3430AF0F6B3BB94B52F7F51E97BAD659" + "B1BA0684E208BE624C28D82FB1162F18DD9DCE45216461654CF3374624D15A8D"); + +/*! The modulus p */ +static const BigNumber P( + "0x" + "B34CE9C1E78294D3258473842005D2A48C8C566CFCA8F84C0606F2529B59A6D3" + "8AAE071B53BB2167EAA4FC3B01FE176E787E481B6037AAC62CBC3D089799536A" + "869FA8CDFEA1E8B1FD2D1CD3A30350859A2CD6B3EC2F9BFBB68BB11B4BBE2ADA" + "A18D64A93639543AE5E16293E311C0CF8C8D6E180DF05D08C2FD2D93D570751F"); + +/*! The order of the generator g */ +static const BigNumber Q("0xB90B38BA0A50A43EC6898D3F9B68049777F489B1"); + +/*! The public key value */ +static const BigNumber Y( + "0x" + "173931DDA31EFF32F24B383091BF77EACDC6EFD557624911D8E9B9DEBF0F256D" + "0CFFAC5567B33F6EAAE9D3275BBED7EF9F5F94C4003C959E49A1ED3F58C31B21" + "BACCC0ED8840B46145F121B8906D072129BAE01F071947997E8EF760D2D9EA21" + "D08A5EB7E89390B21A85664713C549E25FEDA6E9E6C31970866BDFBC8FA981F6"); + +/*! R digital signature component */ +static const BigNumber sigR("0xAA6A258FBF7D90E15614676D377DF8B10E38DB4A"); + +/*! S digital signature component */ +static const BigNumber sigS("0x496D5220B5F67D3532D1F991203BC3523B964C3B"); + +int main(void) { + /*! Internal function status */ + IppStatus status = ippStsNoErr; + + /* Pointer to DSA DLP context structure */ + IppsDLPState* pDL = NULL; + + /* Result verification DSA DLP */ + IppDLResult result = ippDLValid; + + /* Size of DSA-DLP context structure. It will be set up in ippsDLPGetSize(). */ + int DLSize = 0; + + /* Digest size */ + const int digestSizeBit = IPP_SHA1_DIGEST_BITSIZE; + const int digestSizeByte = digestSizeBit / 8; + /* Pointer to the SHA-1 hash method */ + const IppsHashMethod* hashMethod = ippsHashMethod_SHA1(); + + /*! Algorithm */ + do { + /* 1. Create a digest by message */ + /*! Buffer create digest */ + Ipp8u md[digestSizeByte] = {}; + + /*! Create digest by message */ + status = ippsHashMessage_rmf(MSG, + MSG_LEN_BYTE, + md, + hashMethod); + /*! Check status create digest */ + if (ippStsNoErr != status) + break; + + /*! + * (!) Allocate BigNumber container for the shrank message digest. + * Note, the DSA algorithm uses only leftmost |minSizeDigestBit| bits of the original message digest + */ + const int minSizeDigestBit = IPP_MIN(N_BIT, digestSizeBit); + BigNumber digest(NULL, bitSizeInWords(minSizeDigestBit)); + + /*! Set digest to BigNumber */ + status = ippsSetOctString_BN(md, + bitSizeInBytes(minSizeDigestBit), + digest); + if (ippStsNoErr != status) + break; + + /* 2. Get size needed for DSA DLP context structure */ + status = ippsDLPGetSize(L_BIT, N_BIT, + &DLSize); + if (ippStsNoErr != status) + break; + + /* 3. Allocate memory for DSA DLP context structure */ + pDL = (IppsDLPState*)(new Ipp8u[DLSize]); + if (NULL == pDL) { + printf("ERROR: Cannot allocate memory (%d bytes) for DSA DLP context\n", DLSize); + return -1; + } + + /* 4. Initialize DSA DLP context */ + status = ippsDLPInit(L_BIT, N_BIT, + pDL); + if (ippStsNoErr != status) + break; + + /* 5. Set DL Domain Parameters */ + status = ippsDLPSet(P, Q, G, pDL); + if (ippStsNoErr != status) + break; + + /* 6. Set up Key Pair into the DL context */ + status = ippsDLPSetKeyPair(NULL, /* optional Private Key Set */ + Y, + pDL); + if (ippStsNoErr != status) + break; + + /* 7. Verify Signature DSA DLP */ + status = ippsDLPVerifyDSA(digest, + sigR, sigS, + &result, + pDL); + if (ippStsNoErr != status) + break; + if (ippDLValid != result) + status = ippStsErr; + + } while (0); /* end Algorithm */ + + /* 8. Remove secret and release resources */ + if (NULL != pDL) + delete[](Ipp8u*) pDL; + + PRINT_EXAMPLE_STATUS("ippsDLPVerifyDSA", "DSA-DLP Verification Hash Method Message SHA-1", ippStsNoErr == status); + + return status; +} diff --git a/plugin/ippcp/library/src/examples/dsa/dsa-dlp-sha-256-verification.cpp b/plugin/ippcp/library/src/examples/dsa/dsa-dlp-sha-256-verification.cpp new file mode 100644 index 000000000..98aa71f9d --- /dev/null +++ b/plugin/ippcp/library/src/examples/dsa/dsa-dlp-sha-256-verification.cpp @@ -0,0 +1,207 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief DSA-DLP verification scheme example + * + * This example demonstrates message verification according to + * DSA-DLP scheme with (L = 3072, N = 256) DSA parameters and SHA-256 hash function. + * + * The DSA-DLP scheme is implemented according : Digital Signature Standard (DSS) (FIPS PUB 186-4) (July 2013) + * + * available at: + * + * http://dx.doi.org/10.6028/NIST.FIPS.186-4. + * + */ + +#include + +#include "bignum.h" +#include "examples_common.h" +#include "ippcp.h" + +/*! Parameters DSA-DLP scheme */ +static const int L_BIT = 3072; +static const int N_BIT = 256; + +/*! Message size in bytes */ +static const int MSG_LEN_BYTE = 6; + +/*! Message text */ +static Ipp8u MSG[MSG_LEN_BYTE] = {0x31, 0x32, 0x33, + 0x34, 0x30, 0x30}; + +/*! The generator of the multiplicative subgroup */ +static const BigNumber G( + "0x" + "6DEA4B8C3FE3AB91E3229FB14C1CFA822915769AF161405F48B7FADFE1EC5D9F" + "EC4EF0CFBB2233FFDDFA5A554CFC68C6BC6A0BA30CEF6F51309294E622B58D4F" + "ACE00AE9669D9172B15696839ED332AFD906E3F427D85A9AF73562B845BE53A3" + "713C0219402A4C208E9B6A6873235E0BC20442E70AB69EDD46E8F3F7D58CB35E" + "A3690C673F54CD37377725739F00EBE2B3B53BDAF89DDAC74012F8486BD3F521" + "7579B4A303F61BCCC98931FABA969C8C2A27ACB04BC21201EDF9A7F6B42E10F7" + "5DD23C3AB073D7290D173EBE6CB1919607BFE2BF0D829A609D8D3CDA7044FF8D" + "FBBD463E68C9403A45834EC547A7D4FD5ABC68C5997CDC397120698F879356E0" + "E74B62FE1A2938A5D1B486B53A5E0CB875E23A2E834EA563A4A9D4BE44045877" + "DF020C30E22E55603F63D74ED2CAFDE18180EC294A7CE263D56EB280562687F6" + "1F898F3C7D2B37D7F00250A43CA989DE16FA1AAB7D83E0DBF6AA66EDC36AD79E" + "ECFE2F91CFAB6285BA10AE713126F69326540C461E44E45BDF076E4ED8D3E924"); + +/*! The modulus p */ +static const BigNumber P( + "0x" + "DCD2F71FBA7AEB46AEEA858AB76F2102FA97A953ABCE9D791AA269F0161733AC" + "3DF25F5C9DB3448F82846E355E23089614046D42B030298D94F5365D942CBB54" + "90E40A1D5E6E577CC646A807F049A1FB42B97A9E64EFA1AA9EF93BB3C7120DDB" + "F9C403E580431F1789127F0A64EA7B036EF12D07F02103655D63DDDA3C44AD32" + "8F727C1D060FC92E3616976CF11BF1FEEFFF033490D98929252B585CD92C081A" + "FCC71DAE6341AE8DD05E62AE297AD2B00560EC94F1F64482816E3AF052FC1DAF" + "F0A9BF52034012594D4246036D040FA5E741E693E36B064BEDB224EA1F7C6C86" + "171CA8FCFAC98C5DB6E34DAD307C5BFDECE4E578F0E18FCAAEE9D5B330ED69A7" + "2D8FDDF878A58A57914247825AE6ED1CB8A6B241EA694B77F843EEE40F1BE90F" + "26B26154813647D1E1AF01254CF21CFDD2E9EBA7E431BD8DB6164D05A3D3AE93" + "71AF5D0D39A3A9B9F07BA61233C77A6BFC273515FB844DB8FAFD69B559CE844C" + "7A3D686EA4991D9FE74CAD560489F3C1DBB4FD171EA8AE7874E302207C02A7B1"); + +/*! The order of the generator g */ +static const BigNumber Q("0xF870D35CA9F84E6ACAD808D6AC35B13EE4073F26EA84FEFE08C4D9A565754037"); + +/*! The public key value */ +static const BigNumber Y( + "0x" + "7E0062E6F32ECAB1EFFA38391B71A523221D6E97A61F55238F0A623CC42980B9" + "87FB22EC6138E8D1C0D36C05D059CA0CA3F1A526A5F67B216341ABCD04105BB8" + "EFC9E479C2532F9DEA6CDDFB4F57DE5B9D6964E3D314EB89693A3D57F82B9FF9" + "3E0E0D11D72FA4F1BD82BB2B20F1B59547AFF7711DB319D7D06E6964BEB294E4" + "4D34C2A21C7AC7CDAC5E91F2F6D183042AFC3644B09837FA2225A074CEB65D49" + "9F73CEE04C705C82BB912F97D765D5F9C8CB442019E7DAC1E1CCCCEE990335EA" + "3B8C837583595CD4F83169D4787FE4675386D604E8E205B977C7AB2369504282" + "54E3B836BD00296257238D22BDA16A722E405DF82029E3384931FB0E4903C3F8" + "771FB15708D4CB3238E7B2A68131BE518A08D6EFD483A01537A432046DCBD1FF" + "A5FF831E0257B292012D5E1A44C6E32019A6B3AE176A67EDAF12EB27E68FA60A" + "05AF4E5448D606C392B4A672B44298B1775A16B9440B131EB0D91CA3FDE1A1E5" + "28B5FFFC31FFDF1449169C2F4ABD96809A75FB6C85AE845940C45D5AF8334057"); + +/*! R digital signature component */ +static const BigNumber sigR("0x8C7F9B7F5D53A4D3877185D2EF69B2B3AB16321D996940C2EFCBEF01C0B598B4"); + +/*! S digital signature component */ +static const BigNumber sigS("0x33708B0FD4109873550D02340918EC93E5383D471C9D0A322AA76C2872783CBA"); + +int main(void) { + /*! Internal function status */ + IppStatus status = ippStsNoErr; + + /* Pointer to DSA DLP context structure */ + IppsDLPState* pDL = NULL; + + /* Result verification DSA DLP */ + IppDLResult result = ippDLValid; + + /* Size of DSA-DLP context structure. It will be set up in ippsDLPGetSize(). */ + int DLSize = 0; + + /* Digest size */ + const int digestSizeBit = IPP_SHA256_DIGEST_BITSIZE; + const int digestSizeByte = digestSizeBit / 8; + /* Pointer to the SHA-256 hash method */ + const IppsHashMethod* hashMethod = ippsHashMethod_SHA256(); + + /*! Algorithm */ + do { + /* 1. Create a digest by message */ + /*! Buffer create digest */ + Ipp8u md[digestSizeByte] = {}; + + /*! Create digest by message */ + status = ippsHashMessage_rmf(MSG, + MSG_LEN_BYTE, + md, + hashMethod); + /*! Check status create digest */ + if (ippStsNoErr != status) + break; + + /*! + * (!) Allocate BigNumber container for the shrank message digest. + * Note, the DSA algorithm uses only leftmost |minSizeDigestBit| bits of the original message digest + */ + const int minSizeDigestBit = IPP_MIN(N_BIT, digestSizeBit); + BigNumber digest(NULL, bitSizeInWords(minSizeDigestBit)); + + /*! Set digest to BigNumber */ + status = ippsSetOctString_BN(md, + bitSizeInBytes(minSizeDigestBit), + digest); + if (ippStsNoErr != status) + break; + + /* 2. Get size needed for DSA DLP context structure */ + status = ippsDLPGetSize(L_BIT, N_BIT, + &DLSize); + if (ippStsNoErr != status) + break; + + /* 3. Allocate memory for DSA DLP context structure */ + pDL = (IppsDLPState*)(new Ipp8u[DLSize]); + if (NULL == pDL) { + printf("ERROR: Cannot allocate memory (%d bytes) for DSA DLP context\n", DLSize); + return -1; + } + + /* 4. Initialize DSA DLP context */ + status = ippsDLPInit(L_BIT, N_BIT, + pDL); + if (ippStsNoErr != status) + break; + + /* 5. Set DL Domain Parameters */ + status = ippsDLPSet(P, Q, G, pDL); + if (ippStsNoErr != status) + break; + + /* 6. Set up Key Pair into the DL context */ + status = ippsDLPSetKeyPair(NULL, /* optional Private Key Set */ + Y, + pDL); + if (ippStsNoErr != status) + break; + + /* 7. Verify Signature DSA DLP */ + status = ippsDLPVerifyDSA(digest, + sigR, sigS, + &result, + pDL); + if (ippStsNoErr != status) + break; + if (ippDLValid != result) + status = ippStsErr; + + } while (0); /* end Algorithm */ + + /* 8. Remove secret and release resources */ + if (NULL != pDL) + delete[](Ipp8u*) pDL; + + PRINT_EXAMPLE_STATUS("ippsDLPVerifyDSA", "DSA-DLP Verification Hash Method Message SHA-256", ippStsNoErr == status); + + return status; +} diff --git a/plugin/ippcp/library/src/examples/rsa/rsa-1k-oaep-sha1-encryption.cpp b/plugin/ippcp/library/src/examples/rsa/rsa-1k-oaep-sha1-encryption.cpp new file mode 100644 index 000000000..3550d1c75 --- /dev/null +++ b/plugin/ippcp/library/src/examples/rsa/rsa-1k-oaep-sha1-encryption.cpp @@ -0,0 +1,131 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief RSA-OAEP encryption scheme usage example. + * + * This example demonstrates message encryption according to + * RSA-OAEP scheme with 1024-bit RSA modulus and SHA-1 hash function. + * It uses Reduced Memory Footprint (_rmf) version of the function. + * + * The RSASSA-OAEP scheme is implemented according to the PKCS#1 v2.1: RSA Cryptography Standard (June 2002), + * available at: + * + * https://tools.ietf.org/html/rfc3447. + * + */ + +#include + +#include "ippcp.h" +#include "examples_common.h" +#include "bignum.h" + +/*! 1024-bit RSA Modulus N = P*Q */ +static BigNumber N("0xBBF82F090682CE9C2338AC2B9DA871F7368D07EED41043A440D6B6F07454F51FB8DFBAAF035C02AB61EA48CEEB6FCD4876ED520D60E1E" + "C4619719D8A5B8B807FAFB8E0A3DFC737723EE6B4B7D93A2584EE6A649D060953748834B2454598394EE0AAB12D7B61A51F527A9A41F6C1" + "687FE2537298CA2A8F5946F8E5FD091DBDCB"); + +/*! Public exponent */ +static BigNumber E("0x11"); + +/*! Plain text source message */ +static Ipp8u sourceMessage[] = + "\xd4\x36\xe9\x95\x69\xfd\x32\xa7" + "\xc8\xa0\x5b\xbc\x90\xd3\x2c\x49"; + +/*! Seed string of hash size */ +static Ipp8u seed[] = "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4" + "\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f"; + +/*! Reference cipher text. Length is equal to RSA modulus size */ +static Ipp8u cipherTextRef[] = + "\x12\x53\xE0\x4D\xC0\xA5\x39\x7B\xB4\x4A\x7A\xB8\x7E\x9B\xF2\xA0" + "\x39\xA3\x3D\x1E\x99\x6F\xC8\x2A\x94\xCC\xD3\x00\x74\xC9\x5D\xF7" + "\x63\x72\x20\x17\x06\x9E\x52\x68\xDA\x5D\x1C\x0B\x4F\x87\x2C\xF6" + "\x53\xC1\x1D\xF8\x23\x14\xA6\x79\x68\xDF\xEA\xE2\x8D\xEF\x04\xBB" + "\x6D\x84\xB1\xC3\x1D\x65\x4A\x19\x70\xE5\x78\x3B\xD6\xEB\x96\xA0" + "\x24\xC2\xCA\x2F\x4A\x90\xFE\x9F\x2E\xF5\xC9\xC1\x40\xE5\xBB\x48" + "\xDA\x95\x36\xAD\x87\x00\xC8\x4F\xC9\x13\x0A\xDE\xA7\x4E\x55\x8D" + "\x51\xA7\x4D\xDF\x85\xD8\xB5\x0D\xE9\x68\x38\xD6\x06\x3E\x09\x55"; + +/*! Main function */ +int main(void) +{ + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Size in bits of RSA modulus */ + const int bitSizeN = N.BitSize(); + /* Size in bits of RSA public exponent */ + const int bitSizeE = E.BitSize(); + + /* Allocate memory for public key. */ + int keySize = 0; + ippsRSA_GetSizePublicKey(bitSizeN, bitSizeE, &keySize); + IppsRSAPublicKeyState* pPubKey = (IppsRSAPublicKeyState*)(new Ipp8u[keySize]); + ippsRSA_InitPublicKey(bitSizeN, bitSizeE, pPubKey, keySize); + + /* Allocate memory for cipher text, not less than RSA modulus size. */ + int cipherTextLen = bitSizeInBytes(bitSizeN); + Ipp8u* pCipherText = new Ipp8u[cipherTextLen]; + + do { + /* Set public key */ + status = ippsRSA_SetPublicKey(N, E, pPubKey); + if (!checkStatus("ippsRSA_SetPublicKey", ippStsNoErr, status)) + break; + + /* Calculate temporary buffer size */ + int pubBufSize = 0; + status = ippsRSA_GetBufferSizePublicKey(&pubBufSize, pPubKey); + if (!checkStatus("ippsRSA_GetBufferSizePublicKey", ippStsNoErr, status)) + break; + + /* Allocate memory for temporary buffer */ + Ipp8u* pScratchBuffer = new Ipp8u[pubBufSize]; + + /* Encrypt message */ + status = ippsRSAEncrypt_OAEP_rmf(sourceMessage, sizeof(sourceMessage)-1, + 0 /* optional label assotiated with the sourceMessage */, + 0, /* label length */ + seed, pCipherText, pPubKey, + ippsHashMethod_SHA1(), + pScratchBuffer); + + if (pScratchBuffer) delete [] pScratchBuffer; + + if (!checkStatus("ippsRSAEncrypt_OAEP_rmf", ippStsNoErr, status)) + break; + + if (0 != memcmp(cipherTextRef, pCipherText, sizeof(cipherTextRef)-1)) { + printf("ERROR: Encrypted and reference messages do not match\n"); + status = ippStsErr; + } + } while (0); + + PRINT_EXAMPLE_STATUS("ippsRSAEncrypt_OAEP_rmf", "RSA-OAEP 1024 (SHA1) Encryption", ippStsNoErr == status); + + if (pCipherText) delete [] pCipherText; + if (pPubKey) delete [] (Ipp8u*)pPubKey; + + return status; +} + diff --git a/plugin/ippcp/library/src/examples/rsa/rsa-1k-oaep-sha1-type2-decryption.cpp b/plugin/ippcp/library/src/examples/rsa/rsa-1k-oaep-sha1-type2-decryption.cpp new file mode 100644 index 000000000..3f43d9eb8 --- /dev/null +++ b/plugin/ippcp/library/src/examples/rsa/rsa-1k-oaep-sha1-type2-decryption.cpp @@ -0,0 +1,146 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief RSA-OAEP decryption scheme usage example. + * + * This example demonstrates message decryption according to + * RSA-OAEP scheme with 1024-bit RSA modulus and SHA-1 hash function. + * The private key of Type2 (to be able to apply Chinese Reminder Theorem) is used in this example. + * It uses Reduced Memory Footprint (_rmf) version of the function. + * + * The RSASSA-OAEP scheme is implemented according to the PKCS#1 v2.1: RSA Cryptography Standard (June 2002), + * available at: + * + * https://tools.ietf.org/html/rfc3447. + * + */ + +#include + +#include "ippcp.h" +#include "examples_common.h" +#include "bignum.h" + +/*! Prime P factor */ +static BigNumber P("0xEECFAE81B1B9B3C908810B10A1B5600199EB9F44AEF4FDA493B81A9E3D84F632" + "124EF0236E5D1E3B7E28FAE7AA040A2D5B252176459D1F397541BA2A58FB6599"); + +/*! Prime Q factor */ +static BigNumber Q("0xC97FB1F027F453F6341233EAAAD1D9353F6C42D08866B1D05A0F2035028B9D86" + "9840B41666B42E92EA0DA3B43204B5CFCE3352524D0416A5A441E700AF461503"); + +/*! D mod (p-1) factor */ +static BigNumber DP("0x54494CA63EBA0337E4E24023FCD69A5AEB07DDDC0183A4D0AC9B54B051F2B13E" + "D9490975EAB77414FF59C1F7692E9A2E202B38FC910A474174ADC93C1F67C981"); + +/*! D mod (q-1) factor */ +static BigNumber DQ("0x471E0290FF0AF0750351B7F878864CA961ADBD3A8A7E991C5C0556A94C3146A7" + "F9803F8F6F8AE342E931FD8AE47A220D1B99A495849807FE39F9245A9836DA3D"); + +/*! Q^-1 mod p factor */ +static BigNumber InvQ("0xB06C4FDABB6301198D265BDBAE9423B380F271F73453885093077FCD39E2119F" + "C98632154F5883B167A967BF402B4E9E2E0F9656E698EA3666EDFB25798039F7"); + +/*! Plain text */ +static Ipp8u sourceMessageRef[] = + "\xd4\x36\xe9\x95\x69\xfd\x32\xa7" + "\xc8\xa0\x5b\xbc\x90\xd3\x2c\x49"; + +/*! Cipher text to decrypt. */ +static Ipp8u cipherText[] = + "\x12\x53\xE0\x4D\xC0\xA5\x39\x7B\xB4\x4A\x7A\xB8\x7E\x9B\xF2\xA0" + "\x39\xA3\x3D\x1E\x99\x6F\xC8\x2A\x94\xCC\xD3\x00\x74\xC9\x5D\xF7" + "\x63\x72\x20\x17\x06\x9E\x52\x68\xDA\x5D\x1C\x0B\x4F\x87\x2C\xF6" + "\x53\xC1\x1D\xF8\x23\x14\xA6\x79\x68\xDF\xEA\xE2\x8D\xEF\x04\xBB" + "\x6D\x84\xB1\xC3\x1D\x65\x4A\x19\x70\xE5\x78\x3B\xD6\xEB\x96\xA0" + "\x24\xC2\xCA\x2F\x4A\x90\xFE\x9F\x2E\xF5\xC9\xC1\x40\xE5\xBB\x48" + "\xDA\x95\x36\xAD\x87\x00\xC8\x4F\xC9\x13\x0A\xDE\xA7\x4E\x55\x8D" + "\x51\xA7\x4D\xDF\x85\xD8\xB5\x0D\xE9\x68\x38\xD6\x06\x3E\x09\x55"; + +/*! Main function */ +int main(void) +{ + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Size in bits of P factor */ + const int bitSizeP = P.BitSize(); + /* Size in bits of Q factor */ + const int bitSizeQ = Q.BitSize(); + + /* Allocate memory for private key. + * There are two types of private keys that are supported: Type1 and Type2. + * You can choose any of them, depending on your private key representation. + * This example uses Type2 key. + * For more information, see https://www.intel.com/content/www/us/en/docs/ipp-crypto/developer-reference/current/crypto-ref-getsize-public-private1-private2.html + */ + int keySize = 0; + ippsRSA_GetSizePrivateKeyType2(bitSizeP, bitSizeQ, &keySize); + IppsRSAPrivateKeyState* pPrvKeyType2 = (IppsRSAPrivateKeyState*)(new Ipp8u [keySize]); + ippsRSA_InitPrivateKeyType2(bitSizeP, bitSizeQ, pPrvKeyType2, keySize); + + /* Allocate memory for decrypted plain text, not less than RSA modulus size. */ + int plainTextLen = bitSizeInBytes(bitSizeP + bitSizeQ); + Ipp8u* pPlainText = new Ipp8u[plainTextLen]; + + do { + /* Set private key */ + status = ippsRSA_SetPrivateKeyType2(P, Q, DP, DQ, InvQ, pPrvKeyType2); + if (!checkStatus("ippsRSA_SetPrivateKeyType2", ippStsNoErr, status)) + break; + + /* Calculate temporary buffer size */ + int bufSize = 0; + status = ippsRSA_GetBufferSizePrivateKey(&bufSize, pPrvKeyType2); + if (!checkStatus("ippsRSA_GetBufferSizePrivateKey", ippStsNoErr, status)) + break; + + /* Allocate memory for temporary buffer */ + Ipp8u* pScratchBuffer = new Ipp8u[bufSize]; + + /* Decrypt message */ + status = ippsRSADecrypt_OAEP_rmf(cipherText, + 0 /* optional label to be assotiated with the message */, + 0, /* label length */ + pPlainText, &plainTextLen, + pPrvKeyType2, + ippsHashMethod_SHA1(), + pScratchBuffer); + + if (pScratchBuffer) delete [] pScratchBuffer; + + if (!checkStatus("ippsRSADecrypt_OAEP_rmf", ippStsNoErr, status)) + break; + + if (0 != memcmp(sourceMessageRef, pPlainText, sizeof(sourceMessageRef)-1)) { + printf("ERROR: Decrypted and plain text messages do not match\n"); + status = ippStsErr; + } + } while (0); + + PRINT_EXAMPLE_STATUS("ippsRSADecrypt_OAEP_rmf", "RSA-OAEP 1024 (SHA1) Type2 decryption", ippStsNoErr == status) + + if (pPlainText) delete [] pPlainText; + if (pPrvKeyType2) delete [] (Ipp8u*)pPrvKeyType2; + + return status; +} + diff --git a/plugin/ippcp/library/src/examples/rsa/rsa-1k-pss-sha1-verification.cpp b/plugin/ippcp/library/src/examples/rsa/rsa-1k-pss-sha1-verification.cpp new file mode 100644 index 000000000..7800c95d7 --- /dev/null +++ b/plugin/ippcp/library/src/examples/rsa/rsa-1k-pss-sha1-verification.cpp @@ -0,0 +1,124 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief RSASSA-PSS verification scheme usage example. + * + * This example demonstrates message verification according to + * RSASSA-PSS scheme with 1024-bit RSA modulus and SHA-1 hash function. + * It uses Reduced Memory Footprint (_rmf) version of the function. + * + * The RSASSA-PSS scheme is implemented according to the PKCS#1 v2.1: RSA Cryptography Standard (June 2002), + * available at: + * + * https://tools.ietf.org/html/rfc3447. + * + */ +#include "ippcp.h" +#include "examples_common.h" +#include "bignum.h" + +/*! 1024-bit RSA Modulus N = P*Q */ +static BigNumber N("0xA2BA40EE07E3B2BD2F02CE227F36A195024486E49C19CB41BBBDFBBA98B22B0E577C2EEAFFA20D883A76E65E394C69D4" + "B3C05A1E8FADDA27EDB2A42BC000FE888B9B32C22D15ADD0CD76B3E7936E19955B220DD17D4EA904B1EC102B2E4DE775" + "1222AA99151024C7CB41CC5EA21D00EEB41F7C800834D2C6E06BCE3BCE7EA9A5"); + +/*! Public exponent */ +static BigNumber E("0x10001"); + +/*! Message to be signed */ +static +Ipp8u sourceMessage[] = "\x85\x9e\xef\x2f\xd7\x8a\xca\x00\x30\x8b\xdc\x47\x11\x93\xbf\x55" + "\xbf\x9d\x78\xdb\x8f\x8a\x67\x2b\x48\x46\x34\xf3\xc9\xc2\x6e\x64" + "\x78\xae\x10\x26\x0f\xe0\xdd\x8c\x08\x2e\x53\xa5\x29\x3a\xf2\x17" + "\x3c\xd5\x0c\x6d\x5d\x35\x4f\xeb\xf7\x8b\x26\x02\x1c\x25\xc0\x27" + "\x12\xe7\x8c\xd4\x69\x4c\x9f\x46\x97\x77\xe4\x51\xe7\xf8\xe9\xe0" + "\x4c\xd3\x73\x9c\x6b\xbf\xed\xae\x48\x7f\xb5\x56\x44\xe9\xca\x74" + "\xff\x77\xa5\x3c\xb7\x29\x80\x2f\x6e\xd4\xa5\xff\xa8\xba\x15\x98" + "\x90\xfc"; + +/*! Signature to verify */ +static +Ipp8u signatureRef[] = "\x8d\xaa\x62\x7d\x3d\xe7\x59\x5d\x63\x05\x6c\x7e\xc6\x59\xe5\x44" + "\x06\xf1\x06\x10\x12\x8b\xaa\xe8\x21\xc8\xb2\xa0\xf3\x93\x6d\x54" + "\xdc\x3b\xdc\xe4\x66\x89\xf6\xb7\x95\x1b\xb1\x8e\x84\x05\x42\x76" + "\x97\x18\xd5\x71\x5d\x21\x0d\x85\xef\xbb\x59\x61\x92\x03\x2c\x42" + "\xbe\x4c\x29\x97\x2c\x85\x62\x75\xeb\x6d\x5a\x45\xf0\x5f\x51\x87" + "\x6f\xc6\x74\x3d\xed\xdd\x28\xca\xec\x9b\xb3\x0e\xa9\x9e\x02\xc3" + "\x48\x82\x69\x60\x4f\xe4\x97\xf7\x4c\xcd\x7c\x7f\xca\x16\x71\x89" + "\x71\x23\xcb\xd3\x0d\xef\x5d\x54\xa2\xb5\x53\x6a\xd9\x0a\x74\x7e"; + +/*! Main function */ +int main(void) +{ + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Size in bits of RSA modulus */ + const int bitSizeN = N.BitSize(); + /* Size in bits of RSA public exponent */ + const int bitSizeE = E.BitSize(); + + /* Allocate memory for public key. */ + int keySize = 0; + ippsRSA_GetSizePublicKey(bitSizeN, bitSizeE, &keySize); + IppsRSAPublicKeyState* pPubKey = (IppsRSAPublicKeyState*)(new Ipp8u[keySize]); + ippsRSA_InitPublicKey(bitSizeN, bitSizeE, pPubKey, keySize); + + if (pPubKey) { + do { + /* Set public key */ + status = ippsRSA_SetPublicKey(N, E, pPubKey); + if (!checkStatus("ippsRSA_SetPublicKey", ippStsNoErr, status)) + break; + + /* Calculate temporary buffer size */ + int pubBufSize = 0; + status = ippsRSA_GetBufferSizePublicKey(&pubBufSize, pPubKey); + if (!checkStatus("ippsRSA_GetBufferSizePublicKey", ippStsNoErr, status)) + break; + + Ipp8u* pScratchBuffer = new Ipp8u[pubBufSize]; + + /* Verify message with use of SHA-1 hash function. The verification result will be placed + * into isValid variable. */ + int isValid = 0; + status = ippsRSAVerify_PSS_rmf(sourceMessage, sizeof(sourceMessage)-1, + signatureRef, &isValid, + pPubKey, + ippsHashMethod_SHA1(), + pScratchBuffer); + + if (pScratchBuffer) delete [] pScratchBuffer; + + if (!checkStatus("ippsRSAVerify_PSS_rmf", ippStsNoErr, status)) + break; + + /* If isValid is zero, then verification fails */ + status = isValid ? ippStsNoErr : ippStsErr; + } while (0); + } + + if (pPubKey) delete [] (Ipp8u*)pPubKey; + + PRINT_EXAMPLE_STATUS("ippsRSAVerify_PSS_rmf", "RSA-PSS 1024 (SHA1) Verification", ippStsNoErr == status); + + return status; +} diff --git a/plugin/ippcp/library/src/examples/rsa/rsa-3k-pss-sha384-type1-signature.cpp b/plugin/ippcp/library/src/examples/rsa/rsa-3k-pss-sha384-type1-signature.cpp new file mode 100644 index 000000000..120f1fb62 --- /dev/null +++ b/plugin/ippcp/library/src/examples/rsa/rsa-3k-pss-sha384-type1-signature.cpp @@ -0,0 +1,166 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief RSASSA-PSS signature generation scheme usage example. + * + * This example demonstrates message signature generation according to + * RSASSA-PSS scheme with 3072-bit RSA modulus and SHA-384 hash function. + * It uses Reduced Memory Footprint (_rmf) version of the function. + * + * The RSASSA-PSS scheme is implemented according to the PKCS#1 v2.1: RSA Cryptography Standard (June 2002), + * available at: + * + * https://tools.ietf.org/html/rfc3447. + * + */ + +#include + +#include "ippcp.h" +#include "examples_common.h" +#include "bignum.h" + +/*! 3072-bit RSA Modulus N = P*Q */ +BigNumber N("0xA7A1882A7FB896786034D07FB1B9F6327C27BDD7CE6FE39C285AE3B6C34259ADC0DC4F7B9C7DEC3CA4A20D3407339EEDD\ +7A12A421DA18F5954673CAC2FF059156ECC73C6861EC761E6A0F2A5A033A6768C6A42D8B459E1B4932349E84EFD92DF59B45935F3D0E3081\ +7C66201AA99D07AE36C5D74F408D69CC08F044151FF4960E531360CB19077833ADF7BCE77ECFAA133C0CCC63C93B856814569E0B9884EE55\ +4061B9A20AB46C38263C094DAE791AA61A17F8D16F0E85B7E5CE3B067ECE89E20BC4E8F1AE814B276D234E04F4E766F501DA74EA7E3817C2\ +4EA35D016676CECE652B823B051625573CA92757FC720D254ECF1DCBBFD21D98307561ECAAB545480C7C52AD7E9FA6B597F5FE550559C2FE\ +923205AC1761A99737CA02D7B19822E008A8969349C87FB874C81620E38F613C8521F0381FE5BA55B74827DAD3E1CF2AA29C6933629F2B28\ +6AD11BE88FA6436E7E3F64A75E3595290DC0D1CD5EEE7AAAC54959CC53BD5A934A365E72DD81A2BD4FB9A67821BFFEDF2EF2BD94913DE8B"); + +/*! Public exponent */ +BigNumber E("0x1415a7"); + +/*! Private exponent */ +BigNumber D("0x073A5FC4CD642F6113DFFC4F84035CEE3A2B8ACC549703751A1D6A5EAA13487229A58EF7D7A522BB9F4F25510F1AA0F74\ +C6A8FC8A5C5BE8B91A674EDE50E92F7E34A90A3C9DA999FFFB1D695E4588F451256C163484C151350CB9C7825A7D910845EE5CF826FECF9A\ +7C0FBBBBA22BB4A531C131D2E7761BA898F002EBEF8AB87218511F81D3266E1EC07A7CA8622514C6DFDC86C67679A2C8F5F031DE9A0C22B5\ +A88060B46EE0C64D3B9AF3C0A379BCD9C6A1B51CF6480456D3FD6DEF94CD2A6C171DD3F010E3C9D662BC857208248C94EBCB9FD997B9FF4A\ +7E5FD95558569906525E741D78344F6F6CFDBD59D4FAA52EE3FA964FB7CCCB2D6BE1935D211FE1498217716273939A946081FD8509913FD4\ +7747C5C2F03EFD4D6FC9C6FCFD8402E9F40A0A5B3DE3CA2B3C0FAC9456938FAA6CF2C20E3912E5981C9876D8CA1FF29B87A15EEAE0CCCE3F\ +8A8F1E405091C083B98BCC5FE0D0DEAAE33C67C0394437F0ECCB385B7EFB17AEEBBA8AFAECCA30A2F63EAC8F0AC8F1EACAD85BBCAF3960B"); + +/*! Reference value of signature */ +static const Ipp8u signatureRef[] = +"\x96\x87\x11\x5b\xe4\x78\xe4\xb6\x42\xcd\x36\x93\x92\xb9\xdd\x0f\x35\x76\xe7\x04\xaf\x72\x18\xb1\xf9\x4d\x7f\x8f\ +\xe7\xf0\x70\x73\xe3\xe8\xe1\x18\x6f\xa7\x68\x97\x7d\x6b\x51\x4e\x51\x34\x59\xf2\x37\x3d\xf6\xec\x52\xe3\xde\x9b\ +\xd8\x3f\xcc\x5c\xc3\xe6\xb9\x7f\x8b\x3f\xb5\x34\x16\x3c\x64\xf5\x26\x76\x20\x70\x0e\x9d\x8c\x52\xb3\xdf\x61\xa7\ +\xc3\x74\x8e\xf1\x59\xd6\xb3\x90\x89\x5a\xfa\x3a\xf5\x91\x09\xa5\x47\x8d\x01\x6d\x96\xc4\x9f\x68\xdf\xc7\x35\xba\ +\x2a\xaf\xd5\x01\x2c\x13\x51\x5e\xd6\x64\x4f\x0d\x41\x09\xc4\x55\x56\xe1\x4a\x38\x21\xe1\xaa\x24\xbe\xb8\xa8\x1a\ +\x48\xda\x27\xf1\x31\xde\x84\xf7\xba\x51\x58\x1d\x81\xb8\xff\x31\xba\x92\xb8\xa1\xfd\xe8\x67\xf0\x7e\x32\xe6\xc2\ +\x70\x92\x53\x44\x81\x74\xdd\x31\x32\x4d\xbc\x32\xb0\x5f\x07\x58\x7f\x76\xa9\x99\x7d\xec\xb8\x0f\x38\xd8\xc1\x3d\ +\x0f\x6e\xb3\xc1\x0e\x3d\x96\xa2\x29\x3f\x74\x64\xf1\xe0\x46\x02\xef\x6e\x84\xc2\xd0\x24\x5d\x7d\xb2\x56\xa6\x7d\ +\x13\x2a\x47\xca\xe9\xab\xe0\x6b\x61\xa8\x96\x8f\x50\xa1\x74\x99\x95\xdc\x15\xef\x0d\xcb\x1d\x5f\x59\x59\xe4\xd4\ +\x54\xc8\x54\x7b\xbb\x4d\x19\x56\x98\xf4\x84\x61\x7b\xfd\x12\x2a\xca\xae\x2d\x0e\x8c\x76\xd2\x8b\x24\x00\x5a\xb0\ +\x3c\xaa\x78\x1e\xa9\x7b\x1c\x4d\x93\x96\xa1\x6f\x79\x98\xee\xe7\xdd\xd9\xde\x4c\xab\xe5\x70\x32\xd9\x43\x8a\x5d\ +\x99\xc6\xb3\x4a\x95\x61\x22\x35\x02\x63\xc7\xe9\x98\xbc\x61\xde\xc9\x13\x81\x01\x2e\x68\x6d\x07\x9e\x39\xe9\x6b\ +\x1e\xa4\xbf\xdb\x7c\xdf\x63\x0d\xdb\x42\x2c\x6b\x58\x0e\x55\x06\xc9\xcc\x3d\x6c\x10\x0f\x20\x41\xd1\x7c\xea\xaa\ +\xa5\x45\x89\x24\x9f\x04\xa1\x37\x0f\xfa\x3b\xf3\xff\x1a\xde\xb8\x90\x68\x86\x98"; + +/*! Message to be signed */ +static const Ipp8u sourceMessage[] = +"\x92\x21\xf0\xfe\x91\x15\x84\x35\x54\xd5\x68\x5d\x9f\xe6\x9d\xc4\x9e\x95\xce\xb5\x79\x39\x86\xe4\x28\xb8\xa1\x0b\ +\x89\x4c\x01\xd6\xaf\x87\x82\xfd\x7d\x95\x2f\xaf\x74\xc2\xb6\x37\xca\x3b\x19\xda\xbc\x19\xa7\xfe\x25\x9b\x2b\x92\ +\x4e\xb3\x63\xa9\x08\xc5\xb3\x68\xf8\xab\x1b\x23\x33\xfc\x67\xc3\x0b\x8e\xa5\x6b\x28\x39\xdc\x5b\xda\xde\xfb\x14\ +\xad\xa8\x10\xbc\x3e\x92\xba\xc5\x4e\x2a\xe1\xca\x15\x94\xa4\xb9\xd8\xd1\x93\x37\xbe\x42\x1f\x40\xe0\x67\x4e\x0e\ +\x9f\xed\xb4\x3d\x3a\xe8\x9e\x2c\xa0\x5d\x90\xa6\x82\x03\xf2\xc2"; + +/*! Salt */ +static const Ipp8u salt[] = +"\x61\xa7\x62\xf8\x96\x8d\x5f\x36\x7e\x2d\xbc\xac\xb4\x02\x16\x53\xdc\x75\x43\x7d\x90\x00\xe3\x16\x9d\x94\x37\x29\ +\x70\x38\x37\xa5\xcb\xf4\xde\x62\xbd\xed\xc9\x5f\xd0\xd1\x00\x4e\x84\x75\x14\x52"; + + +/*! Main function */ +int main(void) +{ + /* RSA Modulus N = P*Q in bits */ + const int RSA_MODULUS = 3072; + + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Size in bits of RSA modulus */ + const int bitSizeN = N.BitSize(); + /* Size in bits of RSA private exponent */ + const int bitSizeD = D.BitSize(); + + /* Allocate memory for signature. + * Size shall be equal to the RSA modulus size. + */ + const int signatureLen = bitSizeInBytes(RSA_MODULUS); + Ipp8u* pSignature = new Ipp8u[signatureLen]; + + /* Allocate memory private key. + * There are two types of private keys that are supported: Type1 and Type2. + * You can choose any of them, depending on your private key representation. + * This example uses Type1 key. + * For more information, see https://www.intel.com/content/www/us/en/docs/ipp-crypto/developer-reference/current/crypto-ref-getsize-public-private1-private2.html + */ + int keySize = 0; + ippsRSA_GetSizePrivateKeyType1(bitSizeN, bitSizeD, &keySize); + IppsRSAPrivateKeyState* pPrvKeyType1 = (IppsRSAPrivateKeyState*)(new Ipp8u[keySize]); + ippsRSA_InitPrivateKeyType1(bitSizeN, bitSizeD, pPrvKeyType1, keySize); + + if (pPrvKeyType1) { + do { + /* Set private key */ + status = ippsRSA_SetPrivateKeyType1(N, D, pPrvKeyType1); + if (!checkStatus("ippsRSA_SetPrivateKeyType1", ippStsNoErr, status)) + break; + + /* Calculate temporary buffer size */ + int bufSize = 0; + status = ippsRSA_GetBufferSizePrivateKey(&bufSize, pPrvKeyType1); + if (!checkStatus("ippsRSA_GetBufferSizePrivateKey", ippStsNoErr, status)) + break; + + Ipp8u* pScratchBuffer = new Ipp8u[bufSize]; + + /* Sign message with use of SHA384 hash function */ + status = ippsRSASign_PSS_rmf(sourceMessage, sizeof(sourceMessage)-1, + salt, sizeof(salt)-1, + pSignature, + pPrvKeyType1, NULL /* public key */, + ippsHashMethod_SHA384(), + pScratchBuffer); + + if (pScratchBuffer) delete [] pScratchBuffer; + + if (!checkStatus("ippsRSASign_PSS_rmf", ippStsNoErr, status)) + break; + + /* Compare signature with expected value */ + if (0 != memcmp(signatureRef, pSignature, signatureLen)) { + printf("ERROR: Signature and reference value do not match\n"); + status = ippStsErr; + } + } while (0); + } + + if (pPrvKeyType1) delete [] (Ipp8u*)pPrvKeyType1; + if (pSignature) delete [] pSignature; + + PRINT_EXAMPLE_STATUS("ippsRSASign_PSS_rmf", "RSA-PSS 3072 (SHA-384) Type1 Signature", ippStsNoErr == status); + + return status; +} diff --git a/plugin/ippcp/library/src/examples/sms4/sms4-128-cbc-decryption.cpp b/plugin/ippcp/library/src/examples/sms4/sms4-128-cbc-decryption.cpp new file mode 100644 index 000000000..c72e6176c --- /dev/null +++ b/plugin/ippcp/library/src/examples/sms4/sms4-128-cbc-decryption.cpp @@ -0,0 +1,126 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief SMS4 Cipher Block Chaining mode of operation (CBC) example + * + * This example demonstrates usage of SMS4 block cipher + * run with CBC mode of operation. Decryption scheme. + * + * The CBC mode of operation is implemented according to the + * "NIST Special Publication 800-38A: Recommendation for Block Cipher Modes of + * Operation" document: + * + * https://csrc.nist.gov/publications/detail/sp/800-38a/final + * + */ + +#include + +#include "ippcp.h" +#include "examples_common.h" + +/*! SMS4 block size in bytes */ +static const int SMS4_BLOCK_SIZE = 16; + +/*! Key size in bytes */ +static const int KEY_SIZE = 16; + +/*! Message size in bytes */ +static const int SRC_LEN = 16; + +/*! Plain text */ +static Ipp8u plainText[SRC_LEN] = { + 0xAA,0xAA,0xAA,0xAA,0xBB,0xBB,0xBB,0xBB, + 0xCC,0xCC,0xCC,0xCC,0xDD,0xDD,0xDD,0xDD +}; + +/*! Cipher text */ +static Ipp8u cipherText[SRC_LEN] = { + 0x78,0xEB,0xB1,0x1C,0xC4,0x0B,0x0A,0x48, + 0x31,0x2A,0xAE,0xB2,0x04,0x02,0x44,0xCB +}; + +/*! 128-bit secret key */ +static Ipp8u key[KEY_SIZE] = { + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 +}; + +/*! Initialization vector for CBC mode. + * Size of initialization vector for SMS4-CBC shall be equal to the size of SMS4 block (16 bytes). + */ +static Ipp8u iv[SMS4_BLOCK_SIZE] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F +}; + +/*! Main function */ +int main(void) +{ + /* Size of SMS4 context structure. It will be set up in ippsSMS4GetSize(). */ + int ctxSize = 0; + + Ipp8u pOut[SRC_LEN] = {}; + + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Pointer to SMS4 context structure */ + IppsSMS4Spec* pSMS4 = 0; + + do { + /* 1. Get size needed for SMS4 context structure */ + status = ippsSMS4GetSize(&ctxSize); + if (!checkStatus("ippsSMS4GetSize", ippStsNoErr, status)) + return status; + + /* 2. Allocate memory for SMS4 context structure */ + pSMS4 = (IppsSMS4Spec*)(new Ipp8u[ctxSize]); + if (NULL == pSMS4) { + printf("ERROR: Cannot allocate memory (%d bytes) for SMS4 context\n", ctxSize); + return -1; + } + + /* 3. Initialize SMS4 context */ + status = ippsSMS4Init(key, sizeof(key), pSMS4, ctxSize); + if (!checkStatus("ippsSMS4Init", ippStsNoErr, status)) + break; + + /* 4. Decryption */ + status = ippsSMS4DecryptCBC(cipherText, pOut, sizeof(cipherText), pSMS4, iv); + if (!checkStatus("ippsSMS4DecryptCBC", ippStsNoErr, status)) + break; + + /* Compare decrypted message and reference text */ + if (0 != memcmp(pOut, plainText, sizeof(plainText))) { + printf("ERROR: Decrypted and reference messages do not match\n"); + break; + } + } while (0); + + /* 5. Remove secret and release resources */ + ippsSMS4Init(0, KEY_SIZE, pSMS4, ctxSize); + if (pSMS4) delete [] (Ipp8u*)pSMS4; + + PRINT_EXAMPLE_STATUS("ippsSMS4DecryptCBC", "SMS4-CBC Decryption", !status) + + return status; +} diff --git a/plugin/ippcp/library/src/examples/sms4/sms4-128-cbc-encryption.cpp b/plugin/ippcp/library/src/examples/sms4/sms4-128-cbc-encryption.cpp new file mode 100644 index 000000000..aa6c43124 --- /dev/null +++ b/plugin/ippcp/library/src/examples/sms4/sms4-128-cbc-encryption.cpp @@ -0,0 +1,126 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * + * \brief SMS4 Cipher Block Chaining mode of operation (CBC) example + * + * This example demonstrates usage of SMS4 block cipher + * run with CBC mode of operation. Encryption scheme. + * + * The CBC mode of operation is implemented according to the + * "NIST Special Publication 800-38A: Recommendation for Block Cipher Modes of + * Operation" document: + * + * https://csrc.nist.gov/publications/detail/sp/800-38a/final + * + */ + +#include + +#include "ippcp.h" +#include "examples_common.h" + +/*! SMS4 block size in bytes */ +static const int SMS4_BLOCK_SIZE = 16; + +/*! Key size in bytes */ +static const int KEY_SIZE = 16; + +/*! Message size in bytes */ +static const int SRC_LEN = 16; + +/*! Plain text */ +static Ipp8u plainText[SRC_LEN] = { + 0xAA,0xAA,0xAA,0xAA,0xBB,0xBB,0xBB,0xBB, + 0xCC,0xCC,0xCC,0xCC,0xDD,0xDD,0xDD,0xDD +}; + +/*! Cipher text */ +static Ipp8u cipherText[SRC_LEN] = { + 0x78,0xEB,0xB1,0x1C,0xC4,0x0B,0x0A,0x48, + 0x31,0x2A,0xAE,0xB2,0x04,0x02,0x44,0xCB +}; + +/*! 128-bit secret key */ +static Ipp8u key[KEY_SIZE] = { + 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF, + 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 +}; + +/*! Initialization vector for CBC mode. + * Size of initialization vector for SMS4-CBC shall be equal to the size of SMS4 block (16 bytes). + */ +static Ipp8u iv[SMS4_BLOCK_SIZE] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F +}; + +/*! Main function */ +int main(void) +{ + /* Size of SMS4 context structure. It will be set up in ippsSMS4GetSize(). */ + int ctxSize = 0; + + Ipp8u pOut[SRC_LEN] = {}; + + /* Internal function status */ + IppStatus status = ippStsNoErr; + + /* Pointer to SMS4 context structure */ + IppsSMS4Spec* pSMS4 = 0; + + do { + /* 1. Get size needed for SMS4 context structure */ + status = ippsSMS4GetSize(&ctxSize); + if (!checkStatus("ippsSMS4GetSize", ippStsNoErr, status)) + return status; + + /* 2. Allocate memory for SMS4 context structure */ + pSMS4 = (IppsSMS4Spec*)(new Ipp8u[ctxSize]); + if (NULL == pSMS4) { + printf("ERROR: Cannot allocate memory (%d bytes) for SMS4 context\n", ctxSize); + return -1; + } + + /* 3. Initialize SMS4 context */ + status = ippsSMS4Init(key, sizeof(key), pSMS4, ctxSize); + if (!checkStatus("ippsSMS4Init", ippStsNoErr, status)) + break; + + /* 4. Encryption */ + status = ippsSMS4EncryptCBC(plainText, pOut, sizeof(plainText), pSMS4, iv); + if (!checkStatus("ippsSMS4EncryptCBC", ippStsNoErr, status)) + break; + + /* Compare encrypted message and reference text */ + if (0 != memcmp(pOut, cipherText, sizeof(cipherText))) { + printf("ERROR: Encrypted and reference messages do not match\n"); + break; + } + } while (0); + + /* 5. Remove secret and release resources */ + ippsSMS4Init(0, KEY_SIZE, pSMS4, ctxSize); + if (pSMS4) delete [] (Ipp8u*)pSMS4; + + PRINT_EXAMPLE_STATUS("ippsSMS4EncryptCBC", "SMS4-CBC Encryption", !status) + + return status; +} diff --git a/plugin/ippcp/library/src/examples/utils/bignum.cpp b/plugin/ippcp/library/src/examples/utils/bignum.cpp new file mode 100644 index 000000000..f9bac9b8e --- /dev/null +++ b/plugin/ippcp/library/src/examples/utils/bignum.cpp @@ -0,0 +1,438 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "bignum.h" +#include +#include +#include "utils.h" + +////////////////////////////////////////////////////////////////////// +// +// BigNumber +// +////////////////////////////////////////////////////////////////////// +BigNumber::~BigNumber() +{ + delete [] (Ipp8u*)m_pBN; +} + +bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + int size; + ippsBigNumGetSize(length, &size); + m_pBN = (IppsBigNumState*)( new Ipp8u[size] ); + if(!m_pBN) + return false; + ippsBigNumInit(length, m_pBN); + if (pData) + ippsSet_BN(sgn, length, pData, m_pBN); + return true; +} + +// +// constructors +// +BigNumber::BigNumber(Ipp32u value) +{ + create(&value, 1, IppsBigNumPOS); +} + +BigNumber::BigNumber(Ipp32s value) +{ + Ipp32s avalue = abs(value); + create((Ipp32u*)&avalue, 1, (value<0)? IppsBigNumNEG : IppsBigNumPOS); +} + +BigNumber::BigNumber(const IppsBigNumState* pBN) +{ + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + create(pData, length, sgn); +} + +static char HexDigitList[] = "0123456789ABCDEF"; + +BigNumber::BigNumber(const char* s) +{ + bool neg = '-' == s[0]; + if(neg) s++; + bool hex = ('0'==s[0]) && (('x'==s[1]) || ('X'==s[1])); + + int dataLen; + Ipp32u base; + if(hex) { + s += 2; + base = 0x10; + dataLen = (int)(strlen_safe(s) + 7)/8; + } + else { + base = 10; + dataLen = (int)(strlen_safe(s) + 9)/10; + } + + create(0, dataLen); + *(this) = Zero(); + while(*s) { + char tmp[2] = {s[0],0}; + Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp); + *this = (*this) * base + BigNumber( digit ); + s++; + } + + if(neg) + (*this) = Zero()- (*this); +} + +BigNumber::BigNumber(const BigNumber& bn) +{ + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); +} + +// +// set value +// +void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn) +{ + ippsSet_BN(sgn, length, pData, BN(*this)); +} + +// +// constants +// +const BigNumber& BigNumber::Zero() +{ + static const BigNumber zero(0); + return zero; +} + +const BigNumber& BigNumber::One() +{ + static const BigNumber one(1); + return one; +} + +const BigNumber& BigNumber::Two() +{ + static const BigNumber two(2); + return two; +} + +// +// arithmetic operators +// +BigNumber& BigNumber::operator =(const BigNumber& bn) +{ + if(this != &bn) { // prevent self copy + IppsBigNumSGN bnSgn; + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn); + + delete [] (Ipp8u*)m_pBN; + create(bnData, BITSIZE_WORD(bnBitLen), bnSgn); + } + return *this; +} + +BigNumber& BigNumber::operator += (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsAdd_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator -= (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = IPP_MAX(aBitLen, bBitLen); + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsSub_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator *= (const BigNumber& bn) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + int bBitLen; + ippsRef_BN(NULL, &bBitLen, NULL, bn); + int rBitLen = aBitLen + bBitLen; + + BigNumber result(0, BITSIZE_WORD(rBitLen)); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator *= (Ipp32u n) +{ + int aBitLen; + ippsRef_BN(NULL, &aBitLen, NULL, *this); + + BigNumber result(0, BITSIZE_WORD(aBitLen+32)); + BigNumber bn(n); + ippsMul_BN(*this, bn, result); + *this = result; + return *this; +} + +BigNumber& BigNumber::operator %= (const BigNumber& bn) +{ + BigNumber remainder(bn); + ippsMod_BN(BN(*this), BN(bn), BN(remainder)); + *this = remainder; + return *this; +} + +BigNumber& BigNumber::operator /= (const BigNumber& bn) +{ + BigNumber quotient(*this); + BigNumber remainder(bn); + ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder)); + *this = quotient; + return *this; +} + +BigNumber operator + (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r += b; +} + +BigNumber operator - (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r -= b; +} + +BigNumber operator * (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(a); + return r *= b; +} + +BigNumber operator * (const BigNumber& a, Ipp32u n) +{ + BigNumber r(a); + return r *= n; +} + +BigNumber operator / (const BigNumber& a, const BigNumber& b ) +{ + BigNumber q(a); + return q /= b; +} + +BigNumber operator % (const BigNumber& a, const BigNumber& b ) +{ + BigNumber r(b); + ippsMod_BN(BN(a), BN(b), BN(r)); + return r; +} + +// +// modulo arithmetic +// +BigNumber BigNumber::Modulo(const BigNumber& a) const +{ + return a % *this; +} + +BigNumber BigNumber::InverseAdd(const BigNumber& a) const +{ + BigNumber t = Modulo(a); + if(t==BigNumber::Zero()) + return t; + else + return *this - t; +} + +BigNumber BigNumber::InverseMul(const BigNumber& a) const +{ + BigNumber r(*this); + ippsModInv_BN(BN(a), BN(*this), BN(r)); + return r; +} + +BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a+b); + return r; +} + +BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a + this->InverseAdd(b)); + return r; +} + +BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const +{ + BigNumber r = this->Modulo(a*b); + return r; +} + +// +// comparison +// +int BigNumber::compare(const BigNumber &bn) const +{ + Ipp32u result; + BigNumber tmp = *this - bn; + ippsCmpZero_BN(BN(tmp), &result); + return (result==IS_ZERO)? 0 : (result==GREATER_THAN_ZERO)? 1 : -1; +} + +bool operator < (const BigNumber &a, const BigNumber &b) { return a.compare(b) < 0; } +bool operator > (const BigNumber &a, const BigNumber &b) { return a.compare(b) > 0; } +bool operator == (const BigNumber &a, const BigNumber &b) { return 0 == a.compare(b);} +bool operator != (const BigNumber &a, const BigNumber &b) { return 0 != a.compare(b);} + +// easy tests +// +bool BigNumber::IsOdd() const +{ + Ipp32u* bnData; + ippsRef_BN(NULL, NULL, &bnData, *this); + return bnData[0]&1; +} + +// +// size of BigNumber +// +int BigNumber::LSB() const +{ + if( *this == BigNumber::Zero() ) + return 0; + + vector v; + num2vec(v); + + int lsb = 0; + vector::iterator i; + for(i=v.begin(); i!=v.end(); i++) { + Ipp32u x = *i; + if(0==x) + lsb += 32; + else { + while(0==(x&1)) { + lsb++; + x >>= 1; + } + break; + } + } + return lsb; +} + +int BigNumber::MSB() const +{ + if( *this == BigNumber::Zero() ) + return 0; + + vector v; + num2vec(v); + + int msb = (int)v.size()*32 -1; + vector::reverse_iterator i; + for(i=v.rbegin(); i!=v.rend(); i++) { + Ipp32u x = *i; + if(0==x) + msb -=32; + else { + while(!(x&0x80000000)) { + msb--; + x <<= 1; + } + break; + } + } + return msb; +} + +int Bit(const vector& v, int n) +{ + return 0 != ( v[n>>5] & (1<<(n&0x1F)) ); +} + +// +// conversions and output +// +void BigNumber::num2vec( vector& v ) const +{ + int bnBitLen; + Ipp32u* bnData; + ippsRef_BN(NULL, &bnBitLen, &bnData, *this); + + int len = BITSIZE_WORD(bnBitLen);; + for(int n=0; n0; n--) { + Ipp32u x = bnData[n-1]; + for(int nd=8; nd>0; nd--) { + char c = HexDigitList[(x>>(nd-1)*4)&0xF]; + s.append(1, c); + } + } +} + +ostream& operator << ( ostream &os, const BigNumber& a) +{ + string s; + a.num2hex(s); + os << s.c_str(); + return os; +} diff --git a/plugin/ippcp/library/src/examples/utils/bignum.h b/plugin/ippcp/library/src/examples/utils/bignum.h new file mode 100644 index 000000000..8af995288 --- /dev/null +++ b/plugin/ippcp/library/src/examples/utils/bignum.h @@ -0,0 +1,107 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined _BIGNUMBER_H_ +#define _BIGNUMBER_H_ + +#include "ippcp.h" + +#include +#include +#include + +using namespace std; + +class BigNumber +{ +public: + BigNumber(Ipp32u value=0); + BigNumber(Ipp32s value); + BigNumber(const IppsBigNumState* pBN); + BigNumber(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); + BigNumber(const BigNumber& bn); + BigNumber(const char *s); + virtual ~BigNumber(); + + // set value + void Set(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS); + // conversion to IppsBigNumState + friend IppsBigNumState* BN(const BigNumber& bn) {return bn.m_pBN;} + operator IppsBigNumState* () const { return m_pBN; } + + // some useful constatns + static const BigNumber& Zero(); + static const BigNumber& One(); + static const BigNumber& Two(); + + // arithmetic operators probably need + BigNumber& operator = (const BigNumber& bn); + BigNumber& operator += (const BigNumber& bn); + BigNumber& operator -= (const BigNumber& bn); + BigNumber& operator *= (Ipp32u n); + BigNumber& operator *= (const BigNumber& bn); + BigNumber& operator /= (const BigNumber& bn); + BigNumber& operator %= (const BigNumber& bn); + friend BigNumber operator + (const BigNumber& a, const BigNumber& b); + friend BigNumber operator - (const BigNumber& a, const BigNumber& b); + friend BigNumber operator * (const BigNumber& a, const BigNumber& b); + friend BigNumber operator * (const BigNumber& a, Ipp32u); + friend BigNumber operator % (const BigNumber& a, const BigNumber& b); + friend BigNumber operator / (const BigNumber& a, const BigNumber& b); + + // modulo arithmetic + BigNumber Modulo(const BigNumber& a) const; + BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const; + BigNumber ModSub(const BigNumber& a, const BigNumber& b) const; + BigNumber ModMul(const BigNumber& a, const BigNumber& b) const; + BigNumber InverseAdd(const BigNumber& a) const; + BigNumber InverseMul(const BigNumber& a) const; + + // comparisons + friend bool operator < (const BigNumber& a, const BigNumber& b); + friend bool operator > (const BigNumber& a, const BigNumber& b); + friend bool operator == (const BigNumber& a, const BigNumber& b); + friend bool operator != (const BigNumber& a, const BigNumber& b); + friend bool operator <= (const BigNumber& a, const BigNumber& b) {return !(a>b);} + friend bool operator >= (const BigNumber& a, const BigNumber& b) {return !(a>5;} + friend int Bit(const vector& v, int n); + + // conversion and output + void num2hex( string& s ) const; // convert to hex string + void num2vec( vector& v ) const; // convert to 32-bit word vector + friend ostream& operator << (ostream& os, const BigNumber& a); + +protected: + bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn=IppsBigNumPOS); + int compare(const BigNumber& ) const; + IppsBigNumState* m_pBN; +}; + +// convert bit size into 32-bit words +#define BITSIZE_WORD(n) ((((n)+31)>>5)) + +#endif // _BIGNUMBER_H_ diff --git a/plugin/ippcp/library/src/examples/utils/examples_common.h b/plugin/ippcp/library/src/examples/utils/examples_common.h new file mode 100644 index 000000000..c9a17faf5 --- /dev/null +++ b/plugin/ippcp/library/src/examples/utils/examples_common.h @@ -0,0 +1,90 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) */ + +/*! + * + * \file + * \brief Common header for Intel IPP Cryptography examples + * + */ + +#ifndef EXAMPLES_COMMON_H_ +#define EXAMPLES_COMMON_H_ + +#include + +/*! Macro that prints status message depending on condition */ +#define PRINT_EXAMPLE_STATUS(function_name, description, success_condition) \ + printf("+--------------------------------------------------------------|\n"); \ + printf(" Function: %s\n", function_name); \ + printf(" Description: %s\n", description); \ + if (success_condition) { \ + printf(" Status: PASSED!\n"); \ + } else { \ + printf(" Status: FAILED!\n"); \ + } \ + printf("+--------------------------------------------------------------|\n"); + +/*! + * Helper function to compare expected and actual function return statuses and display + * an error mesage if those are different. + * + * \param[in] Function name to display + * \param[in] Expected status + * \param[in] Actual status + * + * \return zero if statuses are not equal, otherwise - non-zero value + */ +inline int checkStatus(const char* funcName, IppStatus expectedStatus, IppStatus status) +{ + if (expectedStatus != status) { + printf("%s: unexpected return status\n", funcName); + printf("Expected: %s\n", ippcpGetStatusString(expectedStatus)); + printf("Received: %s\n", ippcpGetStatusString(status)); + return 0; + } + return 1; +} + +/*! + * Helper function to convert bit size into byte size. + * + * \param[in] Size in bits + * + * \return size in bytes + */ +inline int bitSizeInBytes(int nBits) +{ + return (nBits + 7) >> 3; +} + +/*! + * Helper function to convert bit size into word size. + * + * \param[in] Size in bits + * + * \return size in words + */ + +inline int bitSizeInWords(int nBits) +{ + return (nBits + 31) >> 5; +} + +#endif /* #ifndef EXAMPLES_COMMON_H_ */ diff --git a/plugin/ippcp/library/src/examples/utils/requests.cpp b/plugin/ippcp/library/src/examples/utils/requests.cpp new file mode 100644 index 000000000..3bb24143e --- /dev/null +++ b/plugin/ippcp/library/src/examples/utils/requests.cpp @@ -0,0 +1,39 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * \brief The source file contains the implementation of Request class which simulates a queue in the example of using the multi buffer RSA. + * + */ + +#include "bignum.h" +#include "requests.h" +#include "examples_common.h" + +/* Allocated memory for cipher and decipher texts is not less than RSA modulus size and source plain text */ +Request::Request(const BigNumber& pPlainText, const BigNumber& N, const BigNumber& E, const BigNumber& D) + : m_plainText(pPlainText) + , m_N(N) + , m_E(E) + , m_D(D) + , m_cipherText(N) + , m_decipherText(pPlainText) + , m_isCompatible(true) {} + +Request::~Request(){} diff --git a/plugin/ippcp/library/src/examples/utils/requests.h b/plugin/ippcp/library/src/examples/utils/requests.h new file mode 100644 index 000000000..4d7f9b560 --- /dev/null +++ b/plugin/ippcp/library/src/examples/utils/requests.h @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/*! + * + * \file + * \brief The header contains the declaration of Request class which simulates a queue in the example of using the multi buffer RSA. + * + */ + +#if !defined _REQUESTS_H_ +#define _REQUESTS_H_ + +#include "bignum.h" + +class Request { + BigNumber m_plainText; + BigNumber m_cipherText; + BigNumber m_decipherText; + BigNumber m_N; + BigNumber m_E; + BigNumber m_D; + bool m_isCompatible; + + public: + Request(const BigNumber& pPlainText, const BigNumber& N, const BigNumber& E, const BigNumber& D); + ~Request(); + + IppsBigNumState* GetPlainText() const + { + return m_plainText; + } + + IppsBigNumState* GetCipherText() const + { + return m_cipherText; + } + + IppsBigNumState* GetDecipherText() const + { + return m_decipherText; + } + + int GetBitSizeN() const + { + return m_N.BitSize(); + } + + const BigNumber& GetValueN() const + { + return m_N; + } + + int GetBitSizeE() const + { + return m_E.BitSize(); + } + + const BigNumber& GetValueE() const + { + return m_E; + } + + int GetBitSizeD() const + { + return m_D.BitSize(); + } + + const BigNumber& GetValueD() const + { + return m_D; + } + void SetCompatibilityStatus(bool status) + { + m_isCompatible = status; + } + + bool IsCompatible() const + { + return m_isCompatible; + } +}; + +#endif /* #ifndef _REQUESTS_H_ */ diff --git a/plugin/ippcp/library/src/examples/utils/utils.cpp b/plugin/ippcp/library/src/examples/utils/utils.cpp new file mode 100644 index 000000000..c3c721cdf --- /dev/null +++ b/plugin/ippcp/library/src/examples/utils/utils.cpp @@ -0,0 +1,47 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include "utils.h" + +size_t strlen_safe(const char* dest, size_t dmax) { + size_t count; + + /* check null pointer */ + if (NULL == dest) { + return 0UL; + } + + /* check max equal zero */ + if (0UL == dmax) { + return 0UL; + } + + /* check dmax > 4Kb */ + if (dmax > RSIZE_MAX_STR) { + return 0UL; + } + + count = 0UL; + while (*dest && dmax) { + ++count; + --dmax; + ++dest; + } + + return count; +} diff --git a/plugin/ippcp/library/src/examples/utils/utils.h b/plugin/ippcp/library/src/examples/utils/utils.h new file mode 100644 index 000000000..5eebbc968 --- /dev/null +++ b/plugin/ippcp/library/src/examples/utils/utils.h @@ -0,0 +1,35 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include + +#define RSIZE_MAX_STR (4UL << 10) /* 4Kb */ + +/** + * \brief + * The strnlen_s function computes the length of the string pointed to by dest. + * \param[in] dest pointer to string + * \param[in] dmax restricted maximum length. (default 4Kb) + * \return size_t + * The function returns the string length, excluding the terminating + * null character. If dest is NULL, then strnlen_s returns 0. + */ +size_t strlen_safe(const char* dest, size_t dmax = RSIZE_MAX_STR); + +#endif // _UTILS_H_ diff --git a/plugin/ippcp/library/src/include/ippcp.h b/plugin/ippcp/library/src/include/ippcp.h new file mode 100644 index 000000000..9d7e467fb --- /dev/null +++ b/plugin/ippcp/library/src/include/ippcp.h @@ -0,0 +1,1541 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +*/ + +#if !defined( IPPCP_H__ ) || defined( _OWN_BLDPCS ) +#define IPPCP_H__ + + +#ifndef IPPCPDEFS_H__ + #include "ippcpdefs.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined( IPP_NO_DEFAULT_LIB ) + #if defined( _IPP_SEQUENTIAL_DYNAMIC ) + #pragma comment( lib, __FILE__ "/../../lib/" INTEL_PLATFORM "ippcp" ) + #elif defined( _IPP_SEQUENTIAL_STATIC ) + #pragma comment( lib, __FILE__ "/../../lib/" INTEL_PLATFORM "ippcpmt" ) + #endif +#endif + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) +#pragma warning(push) +#pragma warning(disable : 4100) // for MSVC, unreferenced parameter +#endif + +/* ///////////////////////////////////////////////////////////////////////////// +// Name: ippcpGetLibVersion +// Purpose: getting of the library version +// Returns: the structure of information about version of ippCP library +// Parameters: +// +// Notes: not necessary to release the returned structure +*/ +IPPAPI( const IppLibraryVersion*, ippcpGetLibVersion, (void) ) + + +/* +// ========================================================= +// Symmetric Ciphers +// ========================================================= +*/ + +/* TDES */ + +#define TDES_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: AES" + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESGetSize,(int *size)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESInit,(const Ipp8u* pKey, IppsDESSpec* pCtx)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESPack,(const IppsDESSpec* pCtx, Ipp8u* pBuffer)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsDESUnpack,(const Ipp8u* pBuffer, IppsDESSpec* pCtx)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + IppsCPPadding padding)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + IppsCPPadding padding)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsCPPadding padding)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pIV)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pIV)) + +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESEncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pCtrValue, int ctrNumBitSize)) +IPP_DEPRECATED(TDES_DEPRECATED) \ +IPPAPI(IppStatus, ippsTDESDecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pCtrValue, int ctrNumBitSize)) + +/* AES */ +IPPAPI(IppStatus, ippsAESGetSize,(int *pSize)) +IPPAPI(IppStatus, ippsAESInit,(const Ipp8u* pKey, int keyLen, IppsAESSpec* pCtx, int ctxSize)) +IPPAPI(IppStatus, ippsAESSetKey,(const Ipp8u* pKey, int keyLen, IppsAESSpec* pCtx)) + +IPPAPI(IppStatus, ippsAESPack,(const IppsAESSpec* pCtx, Ipp8u* pBuffer, int bufSize)) +IPPAPI(IppStatus, ippsAESUnpack,(const Ipp8u* pBuffer, IppsAESSpec* pCtx, int ctxSize)) + +#define ECB_DEPRECATED "ECB functionality remains in the library, but it is not safe when used as is. \ +It is recommended to use any other mode, for example CBC." + +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsAESEncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx)) +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsAESDecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx)) + +IPPAPI(IppStatus, ippsAESEncryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESEncryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESEncryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESEncryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsAESEncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsAESEncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsAESSpec* pCtx, + Ipp8u* pIV)) +IPPAPI(IppStatus, ippsAESDecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsAESSpec* pCtx, + Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsAESEncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) +IPPAPI(IppStatus, ippsAESDecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) + +IPPAPI(IppStatus, ippsAESEncryptXTS_Direct,(const Ipp8u* pSrc, Ipp8u* pDst, int encBitsize, int aesBlkNo, + const Ipp8u* pTweakPT, + const Ipp8u* pKey, int keyBitsize, + int dataUnitBitsize)) +IPPAPI(IppStatus, ippsAESDecryptXTS_Direct,(const Ipp8u* pSrc, Ipp8u* pDst, int encBitsize, int aesBlkNo, + const Ipp8u* pTweakPT, + const Ipp8u* pKey, int keyBitsize, + int dataUnitBitsize)) + +IPPAPI(IppStatus, ippsAESSetupNoise,(Ipp32u noiseLevel, IppsAESSpec* pCtx)) +IPPAPI(IppStatus, ippsAES_GCMSetupNoise,(Ipp32u noiseLevel, IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_CMACSetupNoise,(Ipp32u noiseLevel, IppsAES_CMACState* pState)) + +/* AES multi-buffer functions */ +IPPAPI(IppStatus, ippsAES_EncryptCFB16_MB, (const Ipp8u* pSrc[], Ipp8u* pDst[], int len[], + const IppsAESSpec* pCtx[], + const Ipp8u* pIV[], + IppStatus status[], + int numBuffers)) + +/* SMS4 */ +IPPAPI(IppStatus, ippsSMS4GetSize,(int *pSize)) +IPPAPI(IppStatus, ippsSMS4Init,(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx, int ctxSize)) +IPPAPI(IppStatus, ippsSMS4SetKey,(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx)) + +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsSMS4EncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx)) +IPP_DEPRECATED(ECB_DEPRECATED) \ +IPPAPI(IppStatus, ippsSMS4DecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx)) + +IPPAPI(IppStatus, ippsSMS4EncryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4EncryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4EncryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4EncryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC_CS1,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC_CS2,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCBC_CS3,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsSMS4EncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsSMS4EncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsSMS4Spec* pCtx, + Ipp8u* pIV)) +IPPAPI(IppStatus, ippsSMS4DecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsSMS4Spec* pCtx, + Ipp8u* pIV)) + +IPPAPI(IppStatus, ippsSMS4EncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) +IPPAPI(IppStatus, ippsSMS4DecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) + +/* SMS4-CCM */ +IPPAPI(IppStatus, ippsSMS4_CCMGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsSMS4_CCMInit,(const Ipp8u* pKey, int keyLen, IppsSMS4_CCMState* pCtx, int ctxSize)) + +IPPAPI(IppStatus, ippsSMS4_CCMMessageLen,(Ipp64u msgLen, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMTagLen,(int tagLen, IppsSMS4_CCMState* pCtx)) + +IPPAPI(IppStatus, ippsSMS4_CCMStart,(const Ipp8u* pIV, int ivLen, const Ipp8u* pAD, int adLen, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsSMS4_CCMState* pCtx)) +IPPAPI(IppStatus, ippsSMS4_CCMGetTag,(Ipp8u* pTag, int tagLen, const IppsSMS4_CCMState* pCtx)) + +/* +// ========================================================= +// AES based authentication & confidence Primitives +// ========================================================= +*/ + +/* AES-CCM */ +IPPAPI(IppStatus, ippsAES_CCMGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsAES_CCMInit,(const Ipp8u* pKey, int keyLen, IppsAES_CCMState* pState, int ctxSize)) + +IPPAPI(IppStatus, ippsAES_CCMMessageLen,(Ipp64u msgLen, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMTagLen,(int tagLen, IppsAES_CCMState* pState)) + +IPPAPI(IppStatus, ippsAES_CCMStart,(const Ipp8u* pIV, int ivLen, const Ipp8u* pAD, int adLen, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_CCMState* pState)) +IPPAPI(IppStatus, ippsAES_CCMGetTag,(Ipp8u* pTag, int tagLen, const IppsAES_CCMState* pState)) + +/* AES-GCM */ +IPPAPI(IppStatus, ippsAES_GCMGetSize,(int * pSize)) +IPPAPI(IppStatus, ippsAES_GCMInit,(const Ipp8u* pKey, int keyLen, IppsAES_GCMState* pState, int ctxSize)) +IPPAPI(IppStatus, ippsAES_GCMReinit,(IppsAES_GCMState* pState)) + +IPPAPI(IppStatus, ippsAES_GCMReset,(IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMProcessIV,(const Ipp8u* pIV, int ivLen, + IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMProcessAAD,(const Ipp8u* pAAD, int aadLen, + IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMStart,(const Ipp8u* pIV, int ivLen, + const Ipp8u* pAAD, int aadLen, + IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_GCMState* pState)) +IPPAPI(IppStatus, ippsAES_GCMGetTag,(Ipp8u* pDstTag, int tagLen, const IppsAES_GCMState* pState)) + +/* AES-XTS */ +IPPAPI(IppStatus, ippsAES_XTSGetSize,(int * pSize)) +IPPAPI(IppStatus, ippsAES_XTSInit,(const Ipp8u* pKey, int keyLen, + int duBitsize, + IppsAES_XTSSpec* pCtx,int ctxSize)) +IPPAPI(IppStatus, ippsAES_XTSEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int bitSizeLen, + const IppsAES_XTSSpec* pCtx, + const Ipp8u* pTweak, + int startCipherBlkNo)) +IPPAPI(IppStatus, ippsAES_XTSDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int bitSizeLen, + const IppsAES_XTSSpec* pCtx, + const Ipp8u* pTweak, + int startCipherBlkNo)) + +/* AES-SIV (RFC 5297) */ +IPPAPI(IppStatus, ippsAES_S2V_CMAC,(const Ipp8u* pKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD, + Ipp8u* pV)) +IPPAPI(IppStatus, ippsAES_SIVEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + Ipp8u* pSIV, + const Ipp8u* pAuthKey, const Ipp8u* pConfKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD)) +IPPAPI(IppStatus, ippsAES_SIVDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + int* pAuthPassed, + const Ipp8u* pAuthKey, const Ipp8u* pConfKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD, + const Ipp8u* pSIV)) + +/* AES-CMAC */ +IPPAPI(IppStatus, ippsAES_CMACGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsAES_CMACInit,(const Ipp8u* pKey, int keyLen, IppsAES_CMACState* pState, int ctxSize)) + +IPPAPI(IppStatus, ippsAES_CMACUpdate,(const Ipp8u* pSrc, int len, IppsAES_CMACState* pState)) +IPPAPI(IppStatus, ippsAES_CMACFinal,(Ipp8u* pMD, int mdLen, IppsAES_CMACState* pState)) +IPPAPI(IppStatus, ippsAES_CMACGetTag,(Ipp8u* pMD, int mdLen, const IppsAES_CMACState* pState)) + + +/* +// ========================================================= +// RC4 Stream Ciphers +// ========================================================= +*/ + +#define RC4_DEPRECATED "is deprecated. This algorithm is considered weak due to known attacks on it. \ +It is obsolete and will be removed in one of the future Intel IPP Cryptography releases." + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourCheckKey, (const Ipp8u *pKey, int keyLen, IppBool* pIsWeak)) + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourGetSize, (int* pSize)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourInit, (const Ipp8u *pKey, int keyLen, IppsARCFourState *pCtx)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourReset, (IppsARCFourState* pCtx)) + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourPack,(const IppsARCFourState* pCtx, Ipp8u* pBuffer)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourUnpack,(const Ipp8u* pBuffer, IppsARCFourState* pCtx)) + +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourEncrypt, (const Ipp8u *pSrc, Ipp8u *pDst, int length, IppsARCFourState *pCtx)) +IPP_DEPRECATED(RC4_DEPRECATED) \ +IPPAPI(IppStatus, ippsARCFourDecrypt, (const Ipp8u *pSrc, Ipp8u *pDst, int length, IppsARCFourState *pCtx)) + + +/* +// ========================================================= +// One-Way Hash Functions +// ========================================================= +*/ + +#define OBSOLETE_API "is deprecated. This API is considered obsolete and will be removed in one of future Intel IPP Cryptography releases. \ +Use the following link for opening a ticket and providing feedback: https://supporttickets.intel.com/ if you have concerns." + +#define SHA1_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: SHA-2" + +/* SHA1 Hash Primitives */ +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1GetSize,(int* pSize)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Init,(IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Duplicate,(const IppsSHA1State* pSrcState, IppsSHA1State* pDstState)) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Pack,(const IppsSHA1State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Unpack,(const Ipp8u* pBuffer, IppsSHA1State* pState)) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Update,(const Ipp8u* pSrc, int len, IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1Final,(Ipp8u* pMD, IppsSHA1State* pState)) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI(IppStatus, ippsSHA1MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA224 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Init,(IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Duplicate,(const IppsSHA224State* pSrcState, IppsSHA224State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Pack,(const IppsSHA224State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Unpack,(const Ipp8u* pBuffer, IppsSHA224State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Update,(const Ipp8u* pSrc, int len, IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224Final,(Ipp8u* pMD, IppsSHA224State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA224MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA256 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Init,(IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Duplicate,(const IppsSHA256State* pSrcState, IppsSHA256State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Pack,(const IppsSHA256State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Unpack,(const Ipp8u* pBuffer, IppsSHA256State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Update,(const Ipp8u* pSrc, int len, IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256Final,(Ipp8u* pMD, IppsSHA256State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA256MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA384 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Init,(IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Duplicate,(const IppsSHA384State* pSrcState, IppsSHA384State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Pack,(const IppsSHA384State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Unpack,(const Ipp8u* pBuffer, IppsSHA384State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Update,(const Ipp8u* pSrc, int len, IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384Final,(Ipp8u* pMD, IppsSHA384State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA384MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SHA512 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Init,(IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Duplicate,(const IppsSHA512State* pSrcState, IppsSHA512State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Pack,(const IppsSHA512State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Unpack,(const Ipp8u* pBuffer, IppsSHA512State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Update,(const Ipp8u* pSrc, int len, IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512Final,(Ipp8u* pMD, IppsSHA512State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSHA512MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* MD5 Hash Primitives */ + +#define MD5_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: SHA-2" + +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5GetSize,(int* pSize)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Init,(IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Duplicate,(const IppsMD5State* pSrcState, IppsMD5State* pDstState)) + +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Pack,(const IppsMD5State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Unpack,(const Ipp8u* pBuffer, IppsMD5State* pState)) + +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Update,(const Ipp8u* pSrc, int len, IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5Final,(Ipp8u* pMD, IppsMD5State* pState)) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI(IppStatus, ippsMD5MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* SM3 Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Init,(IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Duplicate,(const IppsSM3State* pSrcState, IppsSM3State* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Pack,(const IppsSM3State* pState, Ipp8u* pBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Unpack,(const Ipp8u* pBuffer, IppsSM3State* pState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Update,(const Ipp8u* pSrc, int len, IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3Final,(Ipp8u* pMD, IppsSM3State* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsSM3MessageDigest,(const Ipp8u* pMsg, int len, Ipp8u* pMD)) + +/* generalized Hash Primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashGetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashInit,(IppsHashState* pState, IppHashAlgId hashAlg)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashPack,(const IppsHashState* pState, Ipp8u* pBuffer, int bufSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashUnpack,(const Ipp8u* pBuffer, IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashDuplicate,(const IppsHashState* pSrcState, IppsHashState* pDstState)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashUpdate,(const Ipp8u* pSrc, int len, IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashGetTag,(Ipp8u* pTag, int tagLen, const IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashFinal,(Ipp8u* pMD, IppsHashState* pState)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHashMessage,(const Ipp8u* pMsg, int len, Ipp8u* pMD, IppHashAlgId hashAlg)) + +/* method based generalized (reduced memory footprint) Hash Primitives */ +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_MD5, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SM3, (void) ) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA1, (void) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA1_NI, (void) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA1_TT, (void) ) + +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA256, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA256_NI, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA256_TT, (void) ) + +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA224, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA224_NI, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA224_TT, (void) ) + +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA512, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA384, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA512_256, (void) ) +IPPAPI( const IppsHashMethod*, ippsHashMethod_SHA512_224, (void) ) + +IPPAPI( IppStatus, ippsHashMethodGetSize, (int* pSize) ) +IPP_DEPRECATED(MD5_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_MD5, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SM3, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SM3, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_SHA1, (IppsHashMethod* pMethod) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_SHA1_NI, (IppsHashMethod* pMethod) ) +IPP_DEPRECATED(SHA1_DEPRECATED) \ +IPPAPI( IppStatus, ippsHashMethodSet_SHA1_TT, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashMethodSet_SHA256, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA256_NI, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA256_TT, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA256, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA256_NI, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA256_TT, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashMethodSet_SHA224, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA224_NI, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA224_TT, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA224, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA224_NI, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA224_TT, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashMethodSet_SHA512, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA384, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA512_256, (IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashMethodSet_SHA512_224, (IppsHashMethod* pMethod) ) + +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA512, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA384, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA512_256, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +IPPAPI( IppStatus, ippsHashStateMethodSet_SHA512_224, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) + +IPPAPI(IppStatus, ippsHashGetSize_rmf,(int* pSize)) +IPPAPI(IppStatus, ippsHashInit_rmf,(IppsHashState_rmf* pState, const IppsHashMethod* pMethod)) + +IPPAPI(IppStatus, ippsHashPack_rmf,(const IppsHashState_rmf* pState, Ipp8u* pBuffer, int bufSize)) +IPPAPI(IppStatus, ippsHashUnpack_rmf,(const Ipp8u* pBuffer, IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashDuplicate_rmf,(const IppsHashState_rmf* pSrcState, IppsHashState_rmf* pDstState)) + +IPPAPI(IppStatus, ippsHashUpdate_rmf,(const Ipp8u* pSrc, int len, IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashGetTag_rmf,(Ipp8u* pMD, int tagLen, const IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashFinal_rmf,(Ipp8u* pMD, IppsHashState_rmf* pState)) +IPPAPI(IppStatus, ippsHashMessage_rmf,(const Ipp8u* pMsg, int len, Ipp8u* pMD, const IppsHashMethod* pMethod)) + +IPPAPI(IppStatus, ippsHashMethodGetInfo,(IppsHashInfo* pInfo, const IppsHashMethod* pMethod)) +IPPAPI(IppStatus, ippsHashGetInfo_rmf,(IppsHashInfo* pInfo, const IppsHashState_rmf* pState)) + +/* general MGF Primitives*/ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsMGF,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, IppHashAlgId hashAlg)) +IPPAPI(IppStatus, ippsMGF1_rmf,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, const IppsHashMethod* pMethod)) +IPPAPI(IppStatus, ippsMGF2_rmf,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, const IppsHashMethod* pMethod)) + + +/* +// ========================================================= +// Keyed-Hash Message Authentication Codes +// ========================================================= +*/ + +/* generalized Keyed HMAC primitives */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_GetSize,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Init,(const Ipp8u* pKey, int keyLen, IppsHMACState* pCtx, IppHashAlgId hashAlg)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Pack,(const IppsHMACState* pCtx, Ipp8u* pBuffer, int bufSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Unpack,(const Ipp8u* pBuffer, IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Duplicate,(const IppsHMACState* pSrcCtx, IppsHMACState* pDstCtx)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Update,(const Ipp8u* pSrc, int len, IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Final,(Ipp8u* pMD, int mdLen, IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_GetTag,(Ipp8u* pMD, int mdLen, const IppsHMACState* pCtx)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsHMAC_Message,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pKey, int keyLen, + Ipp8u* pMD, int mdLen, + IppHashAlgId hashAlg)) + +/* method based generalized (reduced memory footprint) Keyed HMAC primitives */ +IPPAPI(IppStatus, ippsHMACGetSize_rmf,(int* pSize)) +IPPAPI(IppStatus, ippsHMACInit_rmf,(const Ipp8u* pKey, int keyLen, + IppsHMACState_rmf* pCtx, + const IppsHashMethod* pMethod)) + +IPPAPI(IppStatus, ippsHMACPack_rmf,(const IppsHMACState_rmf* pCtx, Ipp8u* pBuffer, int bufSize)) +IPPAPI(IppStatus, ippsHMACUnpack_rmf,(const Ipp8u* pBuffer, IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACDuplicate_rmf,(const IppsHMACState_rmf* pSrcCtx, IppsHMACState_rmf* pDstCtx)) + +IPPAPI(IppStatus, ippsHMACUpdate_rmf,(const Ipp8u* pSrc, int len, IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACFinal_rmf,(Ipp8u* pMD, int mdLen, IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACGetTag_rmf,(Ipp8u* pMD, int mdLen, const IppsHMACState_rmf* pCtx)) +IPPAPI(IppStatus, ippsHMACMessage_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pKey, int keyLen, + Ipp8u* pMD, int mdLen, + const IppsHashMethod* pMethod)) + + +/* +// ========================================================= +// Big Number Integer Arithmetic +// ========================================================= +*/ + +/* Signed BigNum Operations */ +IPPAPI(IppStatus, ippsBigNumGetSize,(int length, int* pSize)) +IPPAPI(IppStatus, ippsBigNumInit,(int length, IppsBigNumState* pBN)) + +IPPAPI(IppStatus, ippsCmpZero_BN,(const IppsBigNumState* pBN, Ipp32u* pResult)) +IPPAPI(IppStatus, ippsCmp_BN,(const IppsBigNumState* pA, const IppsBigNumState* pB, Ipp32u* pResult)) + +IPPAPI(IppStatus, ippsGetSize_BN,(const IppsBigNumState* pBN, int* pSize)) +IPPAPI(IppStatus, ippsSet_BN,(IppsBigNumSGN sgn, + int length, const Ipp32u* pData, + IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsGet_BN,(IppsBigNumSGN* pSgn, + int* pLength, Ipp32u* pData, + const IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsRef_BN,(IppsBigNumSGN* pSgn, int* bitSize, Ipp32u** const ppData, + const IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsExtGet_BN,(IppsBigNumSGN* pSgn, + int* pBitSize, Ipp32u* pData, + const IppsBigNumState* pBN)) + +IPPAPI(IppStatus, ippsAdd_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsSub_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMul_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMAC_BN_I, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsDiv_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pQ, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMod_BN, (IppsBigNumState* pA, IppsBigNumState* pM, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsGcd_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pGCD)) +IPPAPI(IppStatus, ippsModInv_BN,(IppsBigNumState* pA, IppsBigNumState* pM, IppsBigNumState* pInv)) + +IPPAPI(IppStatus, ippsSetOctString_BN,(const Ipp8u* pStr, int strLen, IppsBigNumState* pBN)) +IPPAPI(IppStatus, ippsGetOctString_BN,(Ipp8u* pStr, int strLen, const IppsBigNumState* pBN)) + +/* Montgomery Operations */ +IPPAPI(IppStatus, ippsMontGetSize,(IppsExpMethod method, int length, int* pSize)) +IPPAPI(IppStatus, ippsMontInit,(IppsExpMethod method, int length, IppsMontState* pCtx)) + +IPPAPI(IppStatus, ippsMontSet,(const Ipp32u* pModulo, int size, IppsMontState* pCtx)) +IPPAPI(IppStatus, ippsMontGet,(Ipp32u* pModulo, int* pSize, const IppsMontState* pCtx)) + +IPPAPI(IppStatus, ippsMontForm,(const IppsBigNumState* pA, IppsMontState* pCtx, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMontMul, (const IppsBigNumState* pA, const IppsBigNumState* pB, IppsMontState* m, IppsBigNumState* pR)) +IPPAPI(IppStatus, ippsMontExp, (const IppsBigNumState* pA, const IppsBigNumState* pE, IppsMontState* m, IppsBigNumState* pR)) + +/* Pseudo-Random Number Generation */ +IPPAPI(IppStatus, ippsPRNGGetSize,(int* pSize)) +IPPAPI(IppStatus, ippsPRNGInit, (int seedBits, IppsPRNGState* pCtx)) + +IPPAPI(IppStatus, ippsPRNGSetModulus,(const IppsBigNumState* pMod, IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGSetH0, (const IppsBigNumState* pH0, IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGSetAugment,(const IppsBigNumState* pAug, IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGSetSeed, (const IppsBigNumState* pSeed,IppsPRNGState* pCtx)) +IPPAPI(IppStatus, ippsPRNGGetSeed, (const IppsPRNGState* pCtx,IppsBigNumState* pSeed)) + +IPPAPI(IppStatus, ippsPRNGen, (Ipp32u* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsPRNGen_BN, (IppsBigNumState* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsPRNGenRDRAND, (Ipp32u* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsPRNGenRDRAND_BN,(IppsBigNumState* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsTRNGenRDSEED, (Ipp32u* pRand, int nBits, void* pCtx)) +IPPAPI(IppStatus, ippsTRNGenRDSEED_BN,(IppsBigNumState* pRand, int nBits, void* pCtx)) + +/* Probable Prime Number Generation */ +IPPAPI(IppStatus, ippsPrimeGetSize,(int nMaxBits, int* pSize)) +IPPAPI(IppStatus, ippsPrimeInit, (int nMaxBits, IppsPrimeState* pCtx)) + +IPPAPI(IppStatus, ippsPrimeGen, (int nBits, int nTrials, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsPrimeTest,(int nTrials, Ipp32u* pResult, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsPrimeGen_BN,(IppsBigNumState* pPrime, int nBits, int nTrials, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsPrimeTest_BN,(const IppsBigNumState* pPrime, int nTrials, Ipp32u* pResult, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) + +IPPAPI(IppStatus, ippsPrimeGet, (Ipp32u* pPrime, int* pLen, const IppsPrimeState* pCtx)) +IPPAPI(IppStatus, ippsPrimeGet_BN,(IppsBigNumState* pPrime, const IppsPrimeState* pCtx)) + +IPPAPI(IppStatus, ippsPrimeSet, (const Ipp32u* pPrime, int nBits, IppsPrimeState* pCtx)) +IPPAPI(IppStatus, ippsPrimeSet_BN,(const IppsBigNumState* pPrime, IppsPrimeState* pCtx)) + + +/* +// ========================================================= +// RSA Cryptography +// ========================================================= +*/ +IPPAPI(IppStatus, ippsRSA_GetSizePublicKey,(int rsaModulusBitSize, int pubicExpBitSize, int* pKeySize)) +IPPAPI(IppStatus, ippsRSA_InitPublicKey,(int rsaModulusBitSize, int publicExpBitSize, + IppsRSAPublicKeyState* pKey, int keyCtxSize)) +IPPAPI(IppStatus, ippsRSA_SetPublicKey,(const IppsBigNumState* pModulus, + const IppsBigNumState* pPublicExp, + IppsRSAPublicKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetPublicKey,(IppsBigNumState* pModulus, + IppsBigNumState* pPublicExp, + const IppsRSAPublicKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_GetSizePrivateKeyType1,(int rsaModulusBitSize, int privateExpBitSize, int* pKeySize)) +IPPAPI(IppStatus, ippsRSA_InitPrivateKeyType1,(int rsaModulusBitSize, int privateExpBitSize, + IppsRSAPrivateKeyState* pKey, int keyCtxSize)) +IPPAPI(IppStatus, ippsRSA_SetPrivateKeyType1,(const IppsBigNumState* pModulus, + const IppsBigNumState* pPrivateExp, + IppsRSAPrivateKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetPrivateKeyType1,(IppsBigNumState* pModulus, + IppsBigNumState* pPrivateExp, + const IppsRSAPrivateKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_GetSizePrivateKeyType2,(int factorPbitSize, int factorQbitSize, int* pKeySize)) +IPPAPI(IppStatus, ippsRSA_InitPrivateKeyType2,(int factorPbitSize, int factorQbitSize, + IppsRSAPrivateKeyState* pKey, int keyCtxSize)) +IPPAPI(IppStatus, ippsRSA_SetPrivateKeyType2,(const IppsBigNumState* pFactorP, + const IppsBigNumState* pFactorQ, + const IppsBigNumState* pCrtExpP, + const IppsBigNumState* pCrtExpQ, + const IppsBigNumState* pInverseQ, + IppsRSAPrivateKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetPrivateKeyType2,(IppsBigNumState* pFactorP, + IppsBigNumState* pFactorQ, + IppsBigNumState* pCrtExpP, + IppsBigNumState* pCrtExpQ, + IppsBigNumState* pInverseQ, + const IppsRSAPrivateKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_GetBufferSizePublicKey,(int* pBufferSize, const IppsRSAPublicKeyState* pKey)) +IPPAPI(IppStatus, ippsRSA_GetBufferSizePrivateKey,(int* pBufferSize, const IppsRSAPrivateKeyState* pKey)) + +IPPAPI(IppStatus, ippsRSA_Encrypt,(const IppsBigNumState* pPtxt, + IppsBigNumState* pCtxt, + const IppsRSAPublicKeyState* pKey, + Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsRSA_Decrypt,(const IppsBigNumState* pCtxt, + IppsBigNumState* pPtxt, + const IppsRSAPrivateKeyState* pKey, + Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsRSA_GenerateKeys,(const IppsBigNumState* pSrcPublicExp, + IppsBigNumState* pModulus, + IppsBigNumState* pPublicExp, + IppsBigNumState* pPrivateExp, + IppsRSAPrivateKeyState* pPrivateKeyType2, + Ipp8u* pScratchBuffer, + int nTrials, + IppsPrimeState* pPrimeGen, + IppBitSupplier rndFunc, void* pRndParam)) + +IPPAPI(IppStatus, ippsRSA_ValidateKeys,(int* pResult, + const IppsRSAPublicKeyState* pPublicKey, + const IppsRSAPrivateKeyState* pPrivateKeyType2, + const IppsRSAPrivateKeyState* pPrivateKeyType1, + Ipp8u* pScratchBuffer, + int nTrials, + IppsPrimeState* pPrimeGen, + IppBitSupplier rndFunc, void* pRndParam)) + +/* encryption scheme: RSAES-OAEP */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSAEncrypt_OAEP,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pLabel, int labLen, + const Ipp8u* pSeed, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSADecrypt_OAEP,(const Ipp8u* pSrc, + const Ipp8u* pLab, int labLen, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSAEncrypt_OAEP_rmf,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pLabel, int labLen, + const Ipp8u* pSeed, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSADecrypt_OAEP_rmf,(const Ipp8u* pSrc, + const Ipp8u* pLab, int labLen, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +/* encryption scheme: RSAES-PKCS_v1_5 */ + +#define PKCS_DEPRECATED "This algorithm is considered weak due to known attacks on it. \ +The functionality remains in the library, but the implementation will no be longer \ +optimized and no security patches will be applied. A more secure alternative is available: RSA-OAEP" + +IPP_DEPRECATED(PKCS_DEPRECATED) \ +IPPAPI(IppStatus, ippsRSAEncrypt_PKCSv15,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pRndPS, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(PKCS_DEPRECATED) \ +IPPAPI(IppStatus, ippsRSADecrypt_PKCSv15,(const Ipp8u* pSrc, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + Ipp8u* pBuffer)) + +/* signature scheme : RSA-SSA-PSS */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSASign_PSS,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSalt, int saltLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSAVerify_PSS,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, + int* pIsValid, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSASign_PSS_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSalt, int saltLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSAVerify_PSS_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, + int* pIsValid, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +/* signature scheme : RSA-SSA-PKCS1-v1_5 */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSASign_PKCS1v15,(const Ipp8u* pMsg, int msgLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsRSAVerify_PKCS1v15,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, int* pIsValid, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSASign_PKCS1v15_rmf,(const Ipp8u* pMsg, int msgLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +IPPAPI(IppStatus, ippsRSAVerify_PKCS1v15_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, int* pIsValid, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pBuffer)) + +/* +// ========================================================= +// DL Cryptography +// ========================================================= +*/ +IPPAPI( const char*, ippsDLGetResultString, (IppDLResult code)) + +/* Initialization */ +IPPAPI(IppStatus, ippsDLPGetSize,(int bitSizeP, int bitSizeR, int* pSize)) +IPPAPI(IppStatus, ippsDLPInit, (int bitSizeP, int bitSizeR, IppsDLPState* pCtx)) + +IPPAPI(IppStatus, ippsDLPPack,(const IppsDLPState* pCtx, Ipp8u* pBuffer)) +IPPAPI(IppStatus, ippsDLPUnpack,(const Ipp8u* pBuffer, IppsDLPState* pCtx)) + +/* Set Up and Retrieve Domain Parameters */ +IPPAPI(IppStatus, ippsDLPSet,(const IppsBigNumState* pP, + const IppsBigNumState* pR, + const IppsBigNumState* pG, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPGet,(IppsBigNumState* pP, + IppsBigNumState* pR, + IppsBigNumState* pG, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPSetDP,(const IppsBigNumState* pDP, IppDLPKeyTag tag, IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPGetDP,(IppsBigNumState* pDP, IppDLPKeyTag tag, const IppsDLPState* pCtx)) + +/* Key Generation, Validation and Set Up */ +IPPAPI(IppStatus, ippsDLPGenKeyPair,(IppsBigNumState* pPrvKey, IppsBigNumState* pPubKey, + IppsDLPState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsDLPPublicKey, (const IppsBigNumState* pPrvKey, + IppsBigNumState* pPubKey, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPValidateKeyPair,(const IppsBigNumState* pPrvKey, + const IppsBigNumState* pPubKey, + IppDLResult* pResult, + IppsDLPState* pCtx)) + +IPPAPI(IppStatus, ippsDLPSetKeyPair,(const IppsBigNumState* pPrvKey, + const IppsBigNumState* pPubKey, + IppsDLPState* pCtx)) + +/* Signing/Verifying (DSA version) */ +IPPAPI(IppStatus, ippsDLPSignDSA, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsDLPState* pCtx)) +IPPAPI(IppStatus, ippsDLPVerifyDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppDLResult* pResult, + IppsDLPState* pCtx)) + +/* Shared Secret Element (DH version) */ +IPPAPI(IppStatus, ippsDLPSharedSecretDH,(const IppsBigNumState* pPrvKeyA, + const IppsBigNumState* pPubKeyB, + IppsBigNumState* pShare, + IppsDLPState* pCtx)) + +/* DSA's parameter Generation and Validation */ +IPPAPI(IppStatus, ippsDLPGenerateDSA,(const IppsBigNumState* pSeedIn, + int nTrials, IppsDLPState* pCtx, + IppsBigNumState* pSeedOut, int* pCounter, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsDLPValidateDSA,(int nTrials, IppDLResult* pResult, IppsDLPState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) + +/* DH parameter's Generation and Validation */ +IPPAPI(IppStatus, ippsDLPGenerateDH,(const IppsBigNumState* pSeedIn, + int nTrials, IppsDLPState* pCtx, + IppsBigNumState* pSeedOut, int* pCounter, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsDLPValidateDH,(int nTrials, IppDLResult* pResult, IppsDLPState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) + + +/* +// ========================================================= +// EC Cryptography +// ========================================================= +*/ +IPPAPI( const char*, ippsECCGetResultString, (IppECResult code)) + +/* +// EC over Prime Fields +*/ +/* general EC initialization */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSize,(int feBitSize, int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd128r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd128r2,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd192r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd224r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd256r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd384r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStd521r1,(int* pSize)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetSizeStdSM2, (int* pSize)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInit,(int feBitSize, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd128r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd128r2,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd192r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd224r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd256r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd384r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStd521r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPInitStdSM2, (IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSet,(const IppsBigNumState* pPrime, + const IppsBigNumState* pA, const IppsBigNumState* pB, + const IppsBigNumState* pGX,const IppsBigNumState* pGY,const IppsBigNumState* pOrder, + int cofactor, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd,(IppECCType flag, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd128r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd128r2,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd192r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd224r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd256r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd384r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStd521r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetStdSM2, (IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd192r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd224r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd256r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd384r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStd521r1,(IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPBindGxyTblStdSM2, (IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGet,(IppsBigNumState* pPrime, + IppsBigNumState* pA, IppsBigNumState* pB, + IppsBigNumState* pGX,IppsBigNumState* pGY,IppsBigNumState* pOrder, + int* cofactor, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetOrderBitSize,(int* pBitSize, IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPValidate,(int nTrials, IppECResult* pResult, IppsECCPState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) + +/* EC Point */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPPointGetSize,(int feBitSize, int* pSize)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPPointInit,(int feBitSize, IppsECCPPointState* pPoint)) + +/* Setup/retrieve point's coordinates */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetPoint,(const IppsBigNumState* pX, const IppsBigNumState* pY, + IppsECCPPointState* pPoint, IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetPointAtInfinity,(IppsECCPPointState* pPoint, IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGetPoint,(IppsBigNumState* pX, IppsBigNumState* pY, + const IppsECCPPointState* pPoint, IppsECCPState* pEC)) + +/* EC Point Operations */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPCheckPoint,(const IppsECCPPointState* pP, + IppECResult* pResult, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPComparePoint,(const IppsECCPPointState* pP, const IppsECCPPointState* pQ, + IppECResult* pResult, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPNegativePoint,(const IppsECCPPointState* pP, + IppsECCPPointState* pR, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPAddPoint,(const IppsECCPPointState* pP, const IppsECCPPointState* pQ, + IppsECCPPointState* pR, IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPMulPointScalar,(const IppsECCPPointState* pP, const IppsBigNumState* pK, + IppsECCPPointState* pR, IppsECCPState* pEC)) + +/* Key Generation, Setup and Validation */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPGenKeyPair,(IppsBigNumState* pPrivate, IppsECCPPointState* pPublic, + IppsECCPState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPPublicKey,(const IppsBigNumState* pPrivate, + IppsECCPPointState* pPublic, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPValidateKeyPair,(const IppsBigNumState* pPrivate, const IppsECCPPointState* pPublic, + IppECResult* pResult, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSetKeyPair,(const IppsBigNumState* pPrivate, const IppsECCPPointState* pPublic, + IppBool regular, + IppsECCPState* pEC)) + +/* Shared Secret (DH scheme ) */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSharedSecretDH,(const IppsBigNumState* pPrivateA, + const IppsECCPPointState* pPublicB, + IppsBigNumState* pShare, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSharedSecretDHC,(const IppsBigNumState* pPrivateA, + const IppsECCPPointState* pPublicB, + IppsBigNumState* pShare, + IppsECCPState* pEC)) + +/* Sign/Verify */ +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSignDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrivate, + IppsBigNumState* pSignX, IppsBigNumState* pSignY, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPVerifyDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignX, const IppsBigNumState* pSignY, + IppECResult* pResult, + IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSignNR,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrivate, + IppsBigNumState* pSignX, IppsBigNumState* pSignY, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPVerifyNR,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignX, const IppsBigNumState* pSignY, + IppECResult* pResult, + IppsECCPState* pEC)) + +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPSignSM2,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsECCPState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsECCPVerifySM2,(const IppsBigNumState* pMsgDigest, + const IppsECCPPointState* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsECCPState* pEC)) + +/* +// GF over prime and its extension +*/ +IPPAPI(IppStatus, ippsGFpGetSize, (int feBitSize, int* pSize)) +IPPAPI(IppStatus, ippsGFpInitArbitrary,(const IppsBigNumState* pPrime, int primeBitSize, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpInitFixed,(int primeBitSize, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpInit, (const IppsBigNumState* pPrime, int primeBitSize, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFp)) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p192r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p224r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p384r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p521r1, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256sm2,(void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256bn, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_p256, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpMethod_pArb, (void) ) + +IPPAPI(IppStatus, ippsGFpxGetSize,(const IppsGFpState* pGroundGF, int degree, int* pSize)) +IPPAPI(IppStatus, ippsGFpxInit, (const IppsGFpState* pGroundGF, int extDeg, const IppsGFpElement* const ppGroundElm[], int nElm, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFpx)) +IPPAPI(IppStatus, ippsGFpxInitBinomial,(const IppsGFpState* pGroundGF, int extDeg, const IppsGFpElement* pGroundElm, const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFpx)) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom2_epid2,(void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom3_epid2,(void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom2, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom3, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_binom, (void) ) +IPPAPI( const IppsGFpMethod*, ippsGFpxMethod_com, (void) ) + +IPPAPI(IppStatus, ippsGFpScratchBufferSize,(int nExponents, int ExpBitSize, const IppsGFpState* pGFp, int* pBufferSize)) + +IPPAPI(IppStatus, ippsGFpElementGetSize,(const IppsGFpState* pGFp, int* pElementSize)) +IPPAPI(IppStatus, ippsGFpElementInit, (const Ipp32u* pA, int lenA, IppsGFpElement* pR, IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpSetElement, (const Ipp32u* pA, int lenA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSetElementRegular,(const IppsBigNumState* pBN, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSetElementOctString,(const Ipp8u* pStr, int strSize, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSetElementRandom,(IppsGFpElement* pR, IppsGFpState* pGFp, IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsGFpSetElementHash,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGFp, IppHashAlgId hashID)) +IPPAPI(IppStatus, ippsGFpSetElementHash_rmf,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGFp, const IppsHashMethod* pMethod)) +IPPAPI(IppStatus, ippsGFpCpyElement,(const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpGetElement,(const IppsGFpElement* pA, Ipp32u* pDataA, int lenA, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpGetElementOctString,(const IppsGFpElement* pA, Ipp8u* pStr, int strSize, IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpCmpElement,(const IppsGFpElement* pA, const IppsGFpElement* pB, int* pResult, const IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpIsZeroElement,(const IppsGFpElement* pA, int* pResult, const IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpIsUnityElement,(const IppsGFpElement* pA, int* pResult, const IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpConj,(const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpNeg, (const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpInv, (const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSqrt,(const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSqr, (const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpAdd, (const IppsGFpElement* pA, const IppsGFpElement* pB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSub, (const IppsGFpElement* pA, const IppsGFpElement* pB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpMul, (const IppsGFpElement* pA, const IppsGFpElement* pB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpExp, (const IppsGFpElement* pA, const IppsBigNumState* pE, IppsGFpElement* pR, IppsGFpState* pGFp, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpMultiExp,(const IppsGFpElement* const ppElmA[], const IppsBigNumState* const ppE[], int nItems, IppsGFpElement* pR, IppsGFpState* pGFp, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpAdd_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpSub_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, IppsGFpElement* pR, IppsGFpState* pGFp)) +IPPAPI(IppStatus, ippsGFpMul_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, IppsGFpElement* pR, IppsGFpState* pGFp)) + +IPPAPI(IppStatus, ippsGFpGetInfo, (IppsGFpInfo* pInfo, const IppsGFpState* pGFp)) + +/* ================== */ +IPPAPI(IppStatus, ippsGFpECGetSize,(const IppsGFpState* pGFp, int* pSize)) +IPPAPI(IppStatus, ippsGFpECInit, (const IppsGFpState* pGFp, + const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECSet,(const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetSubgroup,(const IppsGFpElement* pX, const IppsGFpElement* pY, + const IppsBigNumState* pOrder, + const IppsBigNumState* pCofactor, + IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECInitStd128r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd128r2,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd192r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd224r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd256r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd384r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStd521r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStdSM2, (const IppsGFpState* pGFp, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECInitStdBN256,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd192r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd224r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd256r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd384r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStd521r1,(IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECBindGxyTblStdSM2, (IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECGet,(IppsGFpState** const ppGFp, + IppsGFpElement* pA, IppsGFpElement* pB, + const IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECGetSubgroup,(IppsGFpState** const ppGFp, + IppsGFpElement* pX, IppsGFpElement* pY, + IppsBigNumState* pOrder,IppsBigNumState* pCofactor, + const IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECScratchBufferSize,(int nScalars, const IppsGFpECState* pEC, int* pBufferSize)) + +IPPAPI(IppStatus, ippsGFpECVerify,(IppECResult* pResult, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECPointGetSize,(const IppsGFpECState* pEC, int* pSize)) +IPPAPI(IppStatus, ippsGFpECPointInit, (const IppsGFpElement* pX, const IppsGFpElement* pY, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECSetPointAtInfinity,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPoint,(const IppsGFpElement* pX, const IppsGFpElement* pY, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPointRegular,(const IppsBigNumState* pX, const IppsBigNumState* pY, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPointRandom,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC, IppBitSupplier rndFunc, void* pRndParam, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECMakePoint,(const IppsGFpElement* pX, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsGFpECSetPointHash,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, IppHashAlgId hashID, Ipp8u* pScratchBuffer)) +IPP_DEPRECATED(OBSOLETE_API) \ +IPPAPI(IppStatus, ippsGFpECSetPointHashBackCompatible,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, IppHashAlgId hashID, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSetPointHash_rmf,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, const IppsHashMethod* pMethod, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSetPointHashBackCompatible_rmf,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC, const IppsHashMethod* pMethod, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECGetPoint,(const IppsGFpECPoint* pPoint, IppsGFpElement* pX, IppsGFpElement* pY, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECGetPointRegular,(const IppsGFpECPoint* pPoint, IppsBigNumState* pX, IppsBigNumState* pY, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECSetPointOctString,(const Ipp8u* pStr, int strLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECGetPointOctString,(const IppsGFpECPoint* pPoint, Ipp8u* pStr, int strLen, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECTstPoint,(const IppsGFpECPoint* pP, IppECResult* pResult, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECTstPointInSubgroup,(const IppsGFpECPoint* pP, IppECResult* pResult, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECCpyPoint,(const IppsGFpECPoint* pA, IppsGFpECPoint* pR, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECCmpPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppECResult* pResult, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECNegPoint,(const IppsGFpECPoint* pP, IppsGFpECPoint* pR, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECAddPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECPoint* pR, IppsGFpECState* pEC)) +IPPAPI(IppStatus, ippsGFpECMulPoint,(const IppsGFpECPoint* pP, const IppsBigNumState* pN, IppsGFpECPoint* pR, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* keys */ +IPPAPI(IppStatus, ippsGFpECPrivateKey,(IppsBigNumState* pPrivate, IppsGFpECState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) +IPPAPI(IppStatus, ippsGFpECPublicKey,(const IppsBigNumState* pPrivate, IppsGFpECPoint* pPublic, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECTstKeyPair,(const IppsBigNumState* pPrivate, const IppsGFpECPoint* pPublic, IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* DH shared secret */ +IPPAPI(IppStatus, ippsGFpECSharedSecretDH,(const IppsBigNumState* pPrivateA, const IppsGFpECPoint* pPublicB, + IppsBigNumState* pShare, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSharedSecretDHC,(const IppsBigNumState* pPrivateA, + const IppsGFpECPoint* pPublicB, + IppsBigNumState* pShare, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* sign generation/verification of DSA, NR, SM2 */ +IPPAPI(IppStatus, ippsGFpECMessageRepresentationSM2, (IppsBigNumState* pMsgDigest, + const Ipp8u* pMsg, int msgLen, + const Ipp8u* pUserID, int userIDLen, + const IppsGFpECPoint* pRegPublic, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECSignDSA, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECVerifyDSA, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECSignNR, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECVerifyNR, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECSignSM2, (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECVerifySM2, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +/* SM2 UserIDHash */ +IPPAPI(IppStatus, ippsGFpECUserIDHashSM2, (Ipp8u* pZaDigest, + const Ipp8u* pUserID, int userIDLen, + const IppsGFpECPoint* pPublicKey, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + + +/* SM2 Key Exchange */ +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_GetSize, (const IppsGFpECState* pEC, int* pSize)) +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_Init, (IppsGFpECKeyExchangeSM2State* pKE, IppsKeyExchangeRoleSM2 role, IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_Setup, (const Ipp8u pZSelf[IPP_SM3_DIGEST_BYTESIZE], + const Ipp8u pZPeer[IPP_SM3_DIGEST_BYTESIZE], + const IppsGFpECPoint *pPublicKeySelf, + const IppsGFpECPoint *pPublicKeyPeer, + const IppsGFpECPoint *pEphPublicKeySelf, + const IppsGFpECPoint *pEphPublicKeyPeer, + IppsGFpECKeyExchangeSM2State *pKE)) + +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_SharedKey, (Ipp8u* pSharedKey, int sharedKeySize, + Ipp8u* pSSelf, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pEphPrvKey, + IppsGFpECKeyExchangeSM2State *pKE, Ipp8u* pScratchBuffer)) + +IPPAPI(IppStatus, ippsGFpECKeyExchangeSM2_Confirm, (const Ipp8u pSPeer[IPP_SM3_DIGEST_BYTESIZE], + int* pStatus, + IppsGFpECKeyExchangeSM2State* pKE)) + +/* SM2 Encryption/Decryption */ +IPPAPI(IppStatus, ippsGFpECGetInfo_GF,(IppsGFpInfo* pInfo, const IppsGFpECState* pEC)) + +IPPAPI(IppStatus, ippsGFpECESGetSize_SM2, (const IppsGFpECState* pEC, int* pSize)) +IPPAPI(IppStatus, ippsGFpECESInit_SM2, (IppsGFpECState* pEC, + IppsECESState_SM2* pState, int avaliableCtxSize)) +IPPAPI(IppStatus, ippsGFpECESSetKey_SM2, (const IppsBigNumState* pPrivate, + const IppsGFpECPoint* pPublic, + IppsECESState_SM2* pState, + IppsGFpECState* pEC, + Ipp8u* pEcScratchBuffer)) +IPPAPI(IppStatus, ippsGFpECESStart_SM2, (IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESEncrypt_SM2, (const Ipp8u* pInput, Ipp8u* pOutput, + int dataLen, IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESDecrypt_SM2, (const Ipp8u* pInput, Ipp8u* pOutput, + int dataLen, IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESFinal_SM2, (Ipp8u* pTag, int tagLen, IppsECESState_SM2* pState)) +IPPAPI(IppStatus, ippsGFpECESGetBuffersSize_SM2, (int* pPublicKeySize, + int* pMaximumTagSize, const IppsECESState_SM2* pState)) + +/* SM2 Encryption/Decryption Extended API */ +/* Encryption */ +IPPAPI(IppStatus, ippsGFpECEncryptSM2_Ext_EncMsgSize, (const IppsGFpECState *pEC, int ptMsgSize, int *pSize)) + +IPPAPI(IppStatus, ippsGFpECEncryptSM2_Ext, (Ipp8u *pOut, int maxOutLen, + int *pOutSize, + const Ipp8u *pInp, int inpLen, + const IppsGFpECPoint *pPublicKey, + IppsGFpECPoint *pEhpPublicKey, IppsBigNumState *pEphPrvKey, + IppsGFpECState *pEC, Ipp8u *pScratchBuffer)) + +/* Decryption */ +IPPAPI(IppStatus, ippsGFpECDecryptSM2_Ext_DecMsgSize, (const IppsGFpECState *pEC, int ctMsgSize, int *pSize)) + +IPPAPI(IppStatus, ippsGFpECDecryptSM2_Ext, (Ipp8u *pOut, int maxOutLen, + int *pOutSize, + const Ipp8u *pInp, int inpLen, + const IppsBigNumState *pPrvKey, + IppsGFpECState *pEC, Ipp8u *pScratchBuffer)) + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) +#pragma warning(pop) +#endif +#ifdef __cplusplus +} +#endif + + +#endif /* IPPCP_H__ */ diff --git a/plugin/ippcp/library/src/include/ippcpdefs.h b/plugin/ippcp/library/src/include/ippcpdefs.h new file mode 100644 index 000000000..50417c698 --- /dev/null +++ b/plugin/ippcp/library/src/include/ippcpdefs.h @@ -0,0 +1,860 @@ +/******************************************************************************* +* Copyright (C) 2012 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +// Purpose: Basic Types and Macro Definitions +// +*/ + + +#ifndef IPPBASE_H__ +#define IPPBASE_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#if defined (_WIN64) +#define INTEL_PLATFORM "intel64/" +#elif defined (_WIN32) +#define INTEL_PLATFORM "ia32/" +#endif + +#if !defined( IPPAPI ) + + /* Specify explicit calling convention for public functions */ + #if defined( IPP_W32DLL ) && (defined( _WIN32 ) || defined( _WIN64 )) + #if defined( _MSC_VER ) || defined( __ICL ) + #define IPPAPI( type,name,arg ) \ + __declspec(dllimport) type IPP_CALL name arg; + #else + #define IPPAPI( type,name,arg ) type IPP_CALL name arg; + #endif + #else + #define IPPAPI( type,name,arg ) type IPP_CALL name arg; + #endif + +#endif + +/* icc 2021 supports short float data type, icx supports _Float16 data type */ +#define _FLOAT_16 2 +#define _SHORT_FLOAT 1 +#define _NO_FLOAT_16 0 +#if defined(__INTEL_LLVM_COMPILER) && defined(__AVX512FP16__) +# define COMPILER_SUPPORT_SHORT_FLOAT _FLOAT_16 +#else +# if defined(__INTEL_COMPILER) +# if(__INTEL_COMPILER >= 2021) +# define COMPILER_SUPPORT_SHORT_FLOAT _SHORT_FLOAT +# endif +# endif +#endif +#if !(defined(COMPILER_SUPPORT_SHORT_FLOAT)) +# define COMPILER_SUPPORT_SHORT_FLOAT _NO_FLOAT_16 +#endif + +#if !defined(_NO_IPP_DEPRECATED) + #if (defined( __ICL ) || defined( __ECL ) || defined(_MSC_VER)) && !defined( _PCS ) && !defined( _PCS_GENSTUBS ) + #if( __INTEL_COMPILER >= 1100 ) /* icl 11.0 supports additional comment */ + #if( _MSC_VER >= 1400 ) + #define IPP_DEPRECATED( comment ) __declspec( deprecated ( comment )) + #else + #pragma message ("your icl version supports additional comment for deprecated functions but it can't be displayed") + #pragma message ("because internal _MSC_VER macro variable setting requires compatibility with MSVC7.1") + #pragma message ("use -Qvc8 switch for icl command line to see these additional comments") + #define IPP_DEPRECATED( comment ) __declspec( deprecated ) + #endif + #elif( _MSC_FULL_VER >= 140050727 )&&( !defined( __INTEL_COMPILER ))&&( !defined(__INTEL_LLVM_COMPILER)) /* VS2005 supports additional comment */ + #define IPP_DEPRECATED( comment ) __declspec( deprecated ( comment )) + #elif( _MSC_VER <= 1200 )&&( !defined( __INTEL_COMPILER ))&&( !defined(__INTEL_LLVM_COMPILER)) /* VS 6 doesn't support deprecation */ + #define IPP_DEPRECATED( comment ) + #else + #define IPP_DEPRECATED( comment ) __declspec( deprecated ) + #endif + #elif (defined(__ICC) || defined(__ECC) || defined( __GNUC__ )) && !defined( _PCS ) && !defined( _PCS_GENSTUBS ) + #if defined( __GNUC__ ) + #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 + #define IPP_DEPRECATED( message ) __attribute__(( deprecated( message ))) + #else + #define IPP_DEPRECATED( message ) __attribute__(( deprecated )) + #endif + #else + #define IPP_DEPRECATED( comment ) __attribute__(( deprecated )) + #endif + #else + #define IPP_DEPRECATED( comment ) + #endif +#else + #define IPP_DEPRECATED( comment ) +#endif + +#if (defined( __ICL ) || defined( __ECL ) || defined(_MSC_VER)) + #if !defined( IPP_NO_DEFAULT_LIB ) + #if ((defined( _IPP_SEQUENTIAL_DYNAMIC ) && !defined( _IPP_SEQUENTIAL_STATIC )) || \ + (!defined( _IPP_SEQUENTIAL_DYNAMIC ) && defined( _IPP_SEQUENTIAL_STATIC ))) + #elif (!defined( _IPP_SEQUENTIAL_DYNAMIC ) && !defined( _IPP_SEQUENTIAL_STATIC )) + #define IPP_NO_DEFAULT_LIB + #else + #error Illegal combination of _IPP_SEQUENTIAL_DYNAMIC/_IPP_SEQUENTIAL_STATIC, only one definition can be defined + #endif + #endif +#else + #define IPP_NO_DEFAULT_LIB + #if (defined(_IPP_SEQUENTIAL_DYNAMIC) || defined(_IPP_SEQUENTIAL_STATIC)) + #pragma message ("defines _IPP_SEQUENTIAL_DYNAMIC/_IPP_SEQUENTIAL_STATIC do not have any effect in current configuration") + #endif +#endif + + +#if defined (_MSC_VER) + #define IPP_CDECL __cdecl +#elif (defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || defined (__GNUC__ ) || defined (__clang__)) && defined (_ARCH_IA32) + #define IPP_CDECL __attribute((cdecl)) +#else + #define IPP_CDECL +#endif + +#if defined( _WIN32 ) || defined( _WIN64 ) + #define IPP_STDCALL __stdcall + #define IPP_CALL IPP_STDCALL + #define IPP_INT64 __int64 + #define IPP_UINT64 unsigned __int64 +#else + #define IPP_STDCALL + #define IPP_CALL IPP_CDECL + #define IPP_INT64 long long + #define IPP_UINT64 unsigned long long +#endif + +#define IPP_COUNT_OF( obj ) (sizeof(obj)/sizeof(obj[0])) + +#define IPP_PI ( 3.14159265358979323846 ) /* ANSI C does not support M_PI */ +#define IPP_2PI ( 6.28318530717958647692 ) /* 2*pi */ +#define IPP_PI2 ( 1.57079632679489661923 ) /* pi/2 */ +#define IPP_PI4 ( 0.78539816339744830961 ) /* pi/4 */ +#define IPP_PI180 ( 0.01745329251994329577 ) /* pi/180 */ +#define IPP_RPI ( 0.31830988618379067154 ) /* 1/pi */ +#define IPP_SQRT2 ( 1.41421356237309504880 ) /* sqrt(2) */ +#define IPP_SQRT3 ( 1.73205080756887729353 ) /* sqrt(3) */ +#define IPP_LN2 ( 0.69314718055994530942 ) /* ln(2) */ +#define IPP_LN3 ( 1.09861228866810969139 ) /* ln(3) */ +#define IPP_E ( 2.71828182845904523536 ) /* e */ +#define IPP_RE ( 0.36787944117144232159 ) /* 1/e */ +#define IPP_EPS23 ( 1.19209289e-07f ) +#define IPP_EPS52 ( 2.2204460492503131e-016 ) + +#define IPP_MAX_8U ( 0xFF ) +#define IPP_MAX_16U ( 0xFFFF ) +#define IPP_MAX_32U ( 0xFFFFFFFF ) +#define IPP_MIN_8U ( 0 ) +#define IPP_MIN_16U ( 0 ) +#define IPP_MIN_32U ( 0 ) +#define IPP_MIN_8S (-128 ) +#define IPP_MAX_8S ( 127 ) +#define IPP_MIN_16S (-32768 ) +#define IPP_MAX_16S ( 32767 ) +#define IPP_MIN_32S (-2147483647 - 1 ) +#define IPP_MAX_32S ( 2147483647 ) +#define IPP_MIN_64U ( 0 ) + +#if defined( _WIN32 ) || defined ( _WIN64 ) + #define IPP_MAX_64S ( 9223372036854775807i64 ) + #define IPP_MIN_64S (-9223372036854775807i64 - 1 ) + #define IPP_MAX_64U ( 0xffffffffffffffffL ) /* 18446744073709551615 */ +#else + #define IPP_MAX_64S ( 9223372036854775807LL ) + #define IPP_MIN_64S (-9223372036854775807LL - 1 ) + #define IPP_MAX_64U ( 0xffffffffffffffffLL ) /* 18446744073709551615 */ +#endif + +#define IPP_MINABS_32F ( 1.175494351e-38f ) +#define IPP_MAXABS_32F ( 3.402823466e+38f ) +#define IPP_EPS_32F ( 1.192092890e-07f ) +#define IPP_MINABS_64F ( 2.2250738585072014e-308 ) +#define IPP_MAXABS_64F ( 1.7976931348623158e+308 ) +#define IPP_EPS_64F ( 2.2204460492503131e-016 ) + +#define IPP_MAX( a, b ) ( ((a) > (b)) ? (a) : (b) ) +#define IPP_MIN( a, b ) ( ((a) < (b)) ? (a) : (b) ) + +#define IPP_ABS( a ) ( ((a) < 0) ? (-(a)) : (a) ) + +typedef struct { + int major; /* e.g. 1 */ + int minor; /* e.g. 2 */ + int majorBuild; /* e.g. 3 */ + unsigned int revision; /* e.g. 0xf6f5e5bc */ + char targetCpu[4]; /* corresponding to Intel® processor */ + const char* Name; /* e.g. "ippsw7" */ + const char* Version; /* e.g. "v1.2 Beta" */ + const char* BuildDate; /* e.g. "Jul 20 99" */ +} IppLibraryVersion; + +typedef unsigned char Ipp8u; +typedef unsigned short Ipp16u; +typedef unsigned int Ipp32u; +typedef signed char Ipp8s; +typedef signed short Ipp16s; +typedef signed int Ipp32s; +typedef float Ipp32f; +typedef IPP_INT64 Ipp64s; +typedef IPP_UINT64 Ipp64u; +typedef double Ipp64f; + +#if (COMPILER_SUPPORT_SHORT_FLOAT == _FLOAT_16) + typedef _Float16 Ipp16f; +#endif +#if (COMPILER_SUPPORT_SHORT_FLOAT == _SHORT_FLOAT) + typedef short float Ipp16f; +#endif +#if (COMPILER_SUPPORT_SHORT_FLOAT == _NO_FLOAT_16) + typedef Ipp16s Ipp16f; +#endif + +typedef struct { + Ipp8s re; + Ipp8s im; +} Ipp8sc; + +typedef struct { + Ipp16s re; + Ipp16s im; +} Ipp16sc; + +typedef struct { + Ipp16u re; + Ipp16u im; +} Ipp16uc; + +typedef struct { + Ipp32s re; + Ipp32s im; +} Ipp32sc; + +typedef struct { + Ipp32f re; + Ipp32f im; +} Ipp32fc; + +typedef struct { + Ipp64s re; + Ipp64s im; +} Ipp64sc; + +typedef struct { + Ipp64f re; + Ipp64f im; +} Ipp64fc; + +typedef struct { + Ipp16f re; + Ipp16f im; +} Ipp16fc; + +typedef enum { + ippUndef = -1, + ipp1u = 0, + ipp8u = 1, + ipp8uc = 2, + ipp8s = 3, + ipp8sc = 4, + ipp16u = 5, + ipp16uc = 6, + ipp16s = 7, + ipp16sc = 8, + ipp32u = 9, + ipp32uc = 10, + ipp32s = 11, + ipp32sc = 12, + ipp32f = 13, + ipp32fc = 14, + ipp64u = 15, + ipp64uc = 16, + ipp64s = 17, + ipp64sc = 18, + ipp64f = 19, + ipp64fc = 20, + ipp16fc = 21 /* This is necessary for TS */ +} IppDataType; + +typedef enum { + ippFalse = 0, + ippTrue = 1 +} IppBool; + +#ifdef __cplusplus +} +#endif + +#endif /* IPPBASE_H__ */ + +#ifndef IPP_CPU_FEATURES__ +#define IPP_CPU_FEATURES__ + +#define ippCPUID_MMX 0x00000001 /* Intel® architecture with MMX(TM) technology supported */ +#define ippCPUID_SSE 0x00000002 /* Intel® Streaming SIMD Extensions (Intel® SSE) instruction set */ +#define ippCPUID_SSE2 0x00000004 /* Intel® Streaming SIMD Extensions 2 (Intel® SSE2) instruction set */ +#define ippCPUID_SSE3 0x00000008 /* Intel® Streaming SIMD Extensions 3 (Intel® SSE3) instruction set */ +#define ippCPUID_SSSE3 0x00000010 /* Supplemental Streaming SIMD Extensions 3 (SSSE3) instruction set */ +#define ippCPUID_MOVBE 0x00000020 /* Intel® instruction MOVBE */ +#define ippCPUID_SSE41 0x00000040 /* Intel® Streaming SIMD Extensions 4.1 (Intel® SSE4.1) instruction set */ +#define ippCPUID_SSE42 0x00000080 /* Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) instruction set */ +#define ippCPUID_AVX 0x00000100 /* Intel® Advanced Vector Extensions instruction set */ +#define ippAVX_ENABLEDBYOS 0x00000200 /* Intel® Advanced Vector Extensions instruction set is supported by OS */ +#define ippCPUID_AES 0x00000400 /* */ +#define ippCPUID_CLMUL 0x00000800 /* Intel® instruction PCLMULQDQ */ +#define ippCPUID_ABR 0x00001000 /* Reserved */ +#define ippCPUID_RDRAND 0x00002000 /* Intel® instruction RDRAND */ +#define ippCPUID_F16C 0x00004000 /* Intel® instruction F16C */ +#define ippCPUID_AVX2 0x00008000 /* Intel® Advanced Vector Extensions 2 */ +#define ippCPUID_ADCOX 0x00010000 /* Intel® instructions ADOX/ADCX */ +#define ippCPUID_RDSEED 0x00020000 /* Intel® instruction RDSEED */ +#define ippCPUID_PREFETCHW 0x00040000 /* Intel® instruction PREFETCHW */ +#define ippCPUID_SHA 0x00080000 /* Intel® Secure Hash Algorithm Extensions */ +#define ippCPUID_AVX512F 0x00100000 /* Intel® Advanced Vector Extensions 512 Foundation instruction set */ +#define ippCPUID_AVX512CD 0x00200000 /* Intel® Advanced Vector Extensions 512 CD instruction set */ +#define ippCPUID_AVX512ER 0x00400000 /* Intel® Advanced Vector Extensions 512 ER instruction set */ +#define ippCPUID_AVX512PF 0x00800000 /* Intel® Advanced Vector Extensions 512 PF instruction set */ +#define ippCPUID_AVX512BW 0x01000000 /* Intel® Advanced Vector Extensions 512 BW instruction set */ +#define ippCPUID_AVX512DQ 0x02000000 /* Intel® Advanced Vector Extensions 512 DQ instruction set */ +#define ippCPUID_AVX512VL 0x04000000 /* Intel® Advanced Vector Extensions 512 VL instruction set */ +#define ippCPUID_AVX512VBMI 0x08000000 /* Intel® Advanced Vector Extensions 512 Bit Manipulation instructions */ +#define ippCPUID_MPX 0x10000000 /* Intel® Memory Protection Extensions */ +#define ippCPUID_AVX512_4FMADDPS 0x20000000 /* Intel® Advanced Vector Extensions 512 DL floating-point single precision */ +#define ippCPUID_AVX512_4VNNIW 0x40000000 /* Intel® Advanced Vector Extensions 512 DL enhanced word variable precision */ +#define ippCPUID_KNC 0x80000000 /* Intel® Xeon® Phi(TM) Coprocessor */ +#if defined( _WIN32 ) || defined ( _WIN64 ) + #define INT64_SUFFIX(name) name##L +#else + #define INT64_SUFFIX(name) name##LL +#endif + #define ippCPUID_AVX512IFMA INT64_SUFFIX(0x100000000) /* Intel® Advanced Vector Extensions 512 IFMA (PMADD52) instruction set */ + #define ippCPUID_NOCHECK INT64_SUFFIX(0x8000000000000000) /* Force ippSetCpuFeatures to set CPU features without check */ + #define ippCPUID_GETINFO_A INT64_SUFFIX(0x616f666e69746567) /* Force ippGetCpuFeatures to work as cpuid instruction */ + #define ippAVX512_ENABLEDBYOS INT64_SUFFIX(0x200000000) /* Intel® Advanced Vector Extensions 512 is supported by OS */ + + #define ippCPUID_AVX512GFNI INT64_SUFFIX(0x400000000) /* */ + #define ippCPUID_AVX512VAES INT64_SUFFIX(0x800000000) /* */ + #define ippCPUID_AVX512VCLMUL INT64_SUFFIX(0x1000000000) /* */ + #define ippCPUID_AVX512VBMI2 INT64_SUFFIX(0x2000000000) /* Intel® Advanced Vector Extensions 512 Bit Manipulation instructions 2 */ + #define ippCPUID_AVX512_FP16 INT64_SUFFIX(0x1000000000) /* Intel(R) Advanced Vector Extensions 512 16-bit floating point (FP16) instruction set */ + + #define ippCPUID_AVX2VAES INT64_SUFFIX(0x4000000000) /* Intel® Advanced Vector Extensions 256 Bit Vector AES instructions */ + #define ippCPUID_AVX2VCLMUL INT64_SUFFIX(0x8000000000) /* Intel® instruction VPCLMULQDQ */ + +#endif /* IPP_CPU_FEATURES__ */ + +/* Macros are necessary to build custom Intel® IPP Cryptography static 1cpu library (enable specific features at compile-time) */ +#if (!defined(_MERGED_BLD) && defined(IPPCP_CUSTOM_BUILD)) + +#ifndef IPP_CUSTOM_CPU_FEATURES__ +#define IPP_CUSTOM_CPU_FEATURES__ + +#ifndef IPPCP_AES_ON +#define IPPCP_AES_ON (0) +#endif +#ifndef IPPCP_CLMUL_ON +#define IPPCP_CLMUL_ON (0) +#endif +#ifndef IPPCP_VAES_ON +#define IPPCP_VAES_ON (0) +#endif +#ifndef IPPCP_VCLMUL_ON +#define IPPCP_VCLMUL_ON (0) +#endif +#define IPP_CUSTOM_ENABLED_FEATURES (ippCPUID_AES*IPPCP_AES_ON | ippCPUID_CLMUL*IPPCP_CLMUL_ON | ippCPUID_AVX512VAES*IPPCP_VAES_ON | ippCPUID_AVX512VCLMUL*IPPCP_VCLMUL_ON) + +#endif /* IPP_CUSTOM_CPU_FEATURES__ */ +#endif /* !defined(_MERGED_BLD) && defined(IPPCP_CUSTOM_BUILD) */ + +#ifndef IPPSTATUS_H__ +#define IPPSTATUS_H__ + +#ifdef __cplusplus +extern "C" { +#endif +typedef signed int IppStatus; + + /* start of common with ippCrypto part - any changes MUST be done in both repositories - IPP & ippCrypto */ +#define ippStsCpuNotSupportedErr -9999 /* The target CPU is not supported. */ +#define ippStsUnknownStatusCodeErr -216 /* Unknown status code. */ +#define ippStsLoadDynErr -221 /* Error when loading the dynamic library. */ +#define ippStsLengthErr -15 /* Incorrect value for string length. */ +#define ippStsNotSupportedModeErr -14 /* The requested mode is currently not supported. */ +#define ippStsContextMatchErr -13 /* Context parameter does not match the operation. */ +#define ippStsScaleRangeErr -12 /* Scale bounds are out of range. */ +#define ippStsOutOfRangeErr -11 /* Argument is out of range, or point is outside the image. */ +#define ippStsDivByZeroErr -10 /* An attempt to divide by zero. */ +#define ippStsMemAllocErr -9 /* Memory allocated for the operation is not enough. */ +#define ippStsNullPtrErr -8 /* Null pointer error. */ +#define ippStsRangeErr -7 /* Incorrect values for bounds: the lower bound is greater than the upper bound. */ +#define ippStsSizeErr -6 /* Incorrect value for data size. */ +#define ippStsBadArgErr -5 /* Incorrect arg/param of the function. */ +#define ippStsNoMemErr -4 /* Not enough memory for the operation. */ +#define ippStsErr -2 /* Unknown/unspecified error */ + /* no errors */ +#define ippStsNoErr 0 /* No errors. */ + /* warnings */ +#define ippStsNoOperation 1 /* No operation has been executed. */ +#define ippStsDivByZero 2 /* Zero value(s) for the divisor in the Div function. */ +#define ippStsWaterfall 43 /* Cannot load required library, waterfall is used. */ +#define ippStsFeaturesCombination 51 /* Wrong combination of features. */ + /* end of common with ippCrypto part */ + +#ifdef __cplusplus +} +#endif + +#endif /* IPPSTATUS_H__ */ + + /* ippCrypto specific statuses - any changes MUST be done in both repositories - IPP & ippCrypto */ +#define ippStsInvalidPoint -1017 /* ippStsInvalidPoint ECC: Invalid point (out of EC).*/ +#define ippStsQuadraticNonResidueErr -1016 /* SQRT operation on quadratic non-residue value. */ +#define ippStsPointAtInfinity -1015 /* Point at infinity is detected. */ +#define ippStsOFBSizeErr -1014 /* Incorrect value for crypto OFB block size. */ +#define ippStsIncompleteContextErr -1013 /* Crypto: set up of context is not complete. */ +#define ippStsCTRSizeErr -1012 /* Incorrect value for crypto CTR block size. */ +#define ippStsEphemeralKeyErr -1011 /* ECC: Invalid ephemeral key. */ +#define ippStsMessageErr -1010 /* ECC: Invalid message digest. */ +#define ippStsShareKeyErr -1009 /* ECC: Invalid share key. */ +#define ippStsInvalidPrivateKey -1008 /* ECC: Invalid private key. */ +#define ippStsOutOfECErr -1007 /* ECC: Point out of EC. */ +#define ippStsECCInvalidFlagErr -1006 /* ECC: Invalid Flag. */ +#define ippStsUnderRunErr -1005 /* Error in data under run. */ +#define ippStsPaddingErr -1004 /* Detected padding error indicates the possible data corruption. */ +#define ippStsCFBSizeErr -1003 /* Incorrect value for crypto CFB block size. */ +#define ippStsPaddingSchemeErr -1002 /* Invalid padding scheme. */ +#define ippStsBadModulusErr -1001 /* Bad modulus caused a failure in module inversion. */ +#define ippStsInsufficientEntropy 25 /* Generation of the prime/key failed due to insufficient entropy in the random seed and stimulus bit string. */ +#define ippStsNotSupportedCpu 36 /* The CPU is not supported. */ +#define ippStsMbWarning 53 /* Error(s) in statuses array. */ + /* end of ippCrypto specific statuses - any changes MUST be done in both repositories - IPP & ippCrypto */ + +#if (!defined IPPCPDEFS_H__) || defined( _OWN_BLDPCS ) +#define IPPCPDEFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + +#if !defined( _OWN_BLDPCS ) + +typedef Ipp32u IppAlgId; + +/* +// ========================================================= +// Symmetric Ciphers +// ========================================================= +*/ +typedef enum { + ippPaddingNONE = 0, /*NONE = 0,*/ IppsCPPaddingNONE = 0, + ippPaddingPKCS7 = 1, /*PKCS7 = 1,*/ IppsCPPaddingPKCS7 = 1, + ippPaddingZEROS = 2, /*ZEROS = 2,*/ IppsCPPaddingZEROS = 2 +} IppsPadding, IppsCPPadding; + +typedef struct _cpDES IppsDESSpec; +typedef struct _cpRijndael128 IppsAESSpec; +typedef struct _cpRijndael128 IppsRijndael128Spec; +typedef struct _cpSMS4 IppsSMS4Spec; + +/* TDES */ +#define DES_BLOCKSIZE (64) /* cipher blocksize (bits) */ +#define TDES_BLOCKSIZE DES_BLOCKSIZE + +#define DES_KEYSIZE (64) /* cipher keysize (bits) */ +#define TDES_KEYSIZE DES_KEYSIZE + +/* AES */ +#define IPP_AES_BLOCK_BITSIZE (128) /* cipher blocksizes (bits) */ + +/* Rijndael */ +typedef enum { + ippRijndaelKey128 = 128, IppsRijndaelKey128 = 128, /* 128-bit key */ + ippRijndaelKey192 = 192, IppsRijndaelKey192 = 192, /* 192-bit key */ + ippRijndaelKey256 = 256, IppsRijndaelKey256 = 256 /* 256-bit key */ +} IppsRijndaelKeyLength; + +/* AES-CCM (authentication & confidence) */ +typedef struct _cpAES_CCM IppsAES_CCMState; +/* AES-GCM (authentication & confidence) */ +typedef struct _cpAES_GCM IppsAES_GCMState; +/* AES-XTS (confidence) */ +typedef struct _cpAES_XTS IppsAES_XTSSpec; + +/* SMS4-CCM (authentication & confidence) */ +typedef struct _cpSMS4_CCM IppsSMS4_CCMState; + +/* +// ========================================================= +// ARCFOUR Stream Cipher +// ========================================================= +*/ +typedef struct _cpARCfour IppsARCFourState; + +#define IPP_ARCFOUR_KEYMAX_SIZE (256) /* max key length (bytes) */ +#define MAX_ARCFOUR_KEY_LEN IPP_ARCFOUR_KEYMAX_SIZE /* obsolete */ + +/* +// ========================================================= +// One-Way Hash Functions +// ========================================================= +*/ +typedef enum { + ippHashAlg_Unknown, + ippHashAlg_SHA1, + ippHashAlg_SHA256, + ippHashAlg_SHA224, + ippHashAlg_SHA512, + ippHashAlg_SHA384, + ippHashAlg_MD5, + ippHashAlg_SM3, + ippHashAlg_SHA512_224, + ippHashAlg_SHA512_256, + ippHashAlg_MaxNo +} IppHashAlgId; + +#define IPP_ALG_HASH_UNKNOWN (ippHashAlg_Unknown) /* unknown */ +#define IPP_ALG_HASH_SHA1 (ippHashAlg_SHA1) /* SHA1 */ +#define IPP_ALG_HASH_SHA256 (ippHashAlg_SHA256) /* SHA256 */ +#define IPP_ALG_HASH_SHA224 (ippHashAlg_SHA224) /* SHA224 or SHA256/224 */ +#define IPP_ALG_HASH_SHA512 (ippHashAlg_SHA512) /* SHA512 */ +#define IPP_ALG_HASH_SHA384 (ippHashAlg_SHA384) /* SHA384 or SHA512/384 */ +#define IPP_ALG_HASH_MD5 (ippHashAlg_MD5) /* MD5 */ +#define IPP_ALG_HASH_SM3 (ippHashAlg_SM3) /* SM3 */ +#define IPP_ALG_HASH_SHA512_224 (ippHashAlg_SHA512_224) /* SHA512/224 */ +#define IPP_ALG_HASH_SHA512_256 (ippHashAlg_SHA512_256) /* SHA512/256 */ +#define IPP_ALG_HASH_LIMIT (ippHashAlg_MaxNo) /* hash alg limiter*/ + +typedef struct _cpSHA1 IppsSHA1State; +typedef struct _cpSHA256 IppsSHA256State; +typedef struct _cpSHA256 IppsSHA224State; +typedef struct _cpSHA512 IppsSHA512State; +typedef struct _cpSHA512 IppsSHA384State; +typedef struct _cpMD5 IppsMD5State; +typedef struct _cpSM3 IppsSM3State; +typedef struct _cpHashCtx IppsHashState; + +typedef struct _cpHashMethod_rmf IppsHashMethod; +typedef struct _cpHashCtx_rmf IppsHashState_rmf; + +#define IPP_SHA1_DIGEST_BITSIZE 160 /* digest size (bits) */ +#define IPP_SHA256_DIGEST_BITSIZE 256 +#define IPP_SHA224_DIGEST_BITSIZE 224 +#define IPP_SHA384_DIGEST_BITSIZE 384 +#define IPP_SHA512_DIGEST_BITSIZE 512 +#define IPP_MD5_DIGEST_BITSIZE 128 +#define IPP_SM3_DIGEST_BITSIZE 256 +#define IPP_SHA512_224_DIGEST_BITSIZE 224 +#define IPP_SHA512_256_DIGEST_BITSIZE 256 + +/* +// ========================================================= +// Keyed-Hash Message Authentication Codes +// ========================================================= +*/ +typedef struct _cpHMAC IppsHMACState; +typedef struct _cpHMAC IppsHMACSHA1State; +typedef struct _cpHMAC IppsHMACSHA256State; +typedef struct _cpHMAC IppsHMACSHA224State; +typedef struct _cpHMAC IppsHMACSHA384State; +typedef struct _cpHMAC IppsHMACSHA512State; +typedef struct _cpHMAC IppsHMACMD5State; +typedef struct _cpHMAC_rmf IppsHMACState_rmf; + +/* +// ========================================================= +// Data Authentication Codes +// ========================================================= +*/ +typedef struct _cpAES_CMAC IppsAES_CMACState; + +/* +// ========================================================= +// Big Number Integer Arithmetic +// ========================================================= +*/ +#define BN_MAXBITSIZE (16*1024) /* bn max size (bits) */ + + +typedef enum { + ippBigNumNEG = 0, IppsBigNumNEG = 0, + ippBigNumPOS = 1, IppsBigNumPOS = 1 +} IppsBigNumSGN; + +typedef enum { + ippBinaryMethod = 0, IppsBinaryMethod = 0, + ippSlidingWindows = 1, IppsSlidingWindows = 1 +} IppsExpMethod; + +typedef struct _cpBigNum IppsBigNumState; +typedef struct _cpMontgomery IppsMontState; +typedef struct _cpPRNG IppsPRNGState; +typedef struct _cpPrime IppsPrimeState; + +/* External Bit Supplier */ +typedef IppStatus (IPP_CALL *IppBitSupplier)(Ipp32u* pRand, int nBits, void* pEbsParams); + +#define IPP_IS_EQ (0) +#define IPP_IS_GT (1) +#define IPP_IS_LT (2) +#define IPP_IS_NE (3) +#define IPP_IS_NA (4) + +#define IPP_IS_PRIME (5) +#define IPP_IS_COMPOSITE (6) + +#define IPP_IS_VALID (7) +#define IPP_IS_INVALID (8) +#define IPP_IS_INCOMPLETE (9) +#define IPP_IS_ATINFINITY (10) + +#define IS_ZERO IPP_IS_EQ +#define GREATER_THAN_ZERO IPP_IS_GT +#define LESS_THAN_ZERO IPP_IS_LT +#define IS_PRIME IPP_IS_PRIME +#define IS_COMPOSITE IPP_IS_COMPOSITE +#define IS_VALID_KEY IPP_IS_VALID +#define IS_INVALID_KEY IPP_IS_INVALID +#define IS_INCOMPLETED_KEY IPP_IS_INCOMPLETE + +/* +// ========================================================= +// RSA Cryptography +// ========================================================= +*/ +#define MIN_RSA_SIZE (8) +#define MAX_RSA_SIZE (16*1024) + +typedef struct _cpRSA IppsRSAState; + +/* key types */ +typedef enum { + ippRSApublic = 0x20000000, IppRSApublic = 0x20000000, + ippRSAprivate = 0x40000000, IppRSAprivate = 0x40000000 +} IppRSAKeyType; + +/* key component's tag */ +typedef enum { + ippRSAkeyN = 0x01, IppRSAkeyN = 0x01, + ippRSAkeyE = 0x02, IppRSAkeyE = 0x02, + ippRSAkeyD = 0x04, IppRSAkeyD = 0x04, + ippRSAkeyP = 0x08, IppRSAkeyP = 0x08, + ippRSAkeyQ = 0x10, IppRSAkeyQ = 0x10, + ippRSAkeyDp = 0x20, IppRSAkeyDp = 0x20, + ippRSAkeyDq = 0x40, IppRSAkeyDq = 0x40, + ippRSAkeyQinv = 0x80, IppRSAkeyQinv = 0x80 +} IppRSAKeyTag; + +typedef struct _cpRSA_public_key IppsRSAPublicKeyState; +typedef struct _cpRSA_private_key IppsRSAPrivateKeyState; + + +/* +// ========================================================= +// DL Cryptography +// ========================================================= +*/ +#define MIN_DLP_BITSIZE (512) +#define MIN_DLP_BITSIZER (160) + +#define MIN_DLPDH_BITSIZE (512) +#define MIN_DLPDH_BITSIZER (160) +#define DEF_DLPDH_BITSIZER (160) + +#define MIN_DLPDSA_BITSIZE (512) +#define MAX_DLPDSA_BITSIZE (1024) +#define MIN_DLPDSA_BITSIZER (160) +#define DEF_DLPDSA_BITSIZER (160) +#define MAX_DLPDSA_BITSIZER (160) +#define MIN_DLPDSA_SEEDSIZE (160) + +typedef struct _cpDLP IppsDLPState; + +/* domain parameter tags */ +typedef enum { + ippDLPkeyP = 0x01, IppDLPkeyP = 0x01, + ippDLPkeyR = 0x02, IppDLPkeyR = 0x02, + ippDLPkeyG = 0x04, IppDLPkeyG = 0x04 +} IppDLPKeyTag; + +typedef enum { + ippDLValid, /* validation pass successfully */ + + ippDLBaseIsEven, /* !(P is odd) */ + ippDLOrderIsEven, /* !(R is odd) */ + ippDLInvalidBaseRange, /* !(2^(L-1) < P < 2^L) */ + ippDLInvalidOrderRange, /* !(2^(M-1) < R < 2^M) */ + ippDLCompositeBase, + ippDLCompositeOrder, + ippDLInvalidCofactor, /* !( R|(P-1) ) */ + ippDLInvalidGenerator, /* !( G^R == 1 (mod P) ) */ + /* !(1 < G < (P-1)) */ + ippDLInvalidPrivateKey, /* !(1 < private < (R-1)) */ + ippDLInvalidPublicKey, /* !(1 < public <=(P-1)) */ + ippDLInvalidKeyPair, /* !(G^private == public */ + + ippDLInvalidSignature /* invalid signature */ +} IppDLResult; + +/* +// ========================================================= +// EC Cryptography +// ========================================================= +*/ +#define EC_GFP_MAXBITSIZE (1024) + +/* operation result */ +typedef enum { + ippECValid, /* validation pass successfully */ + + ippECCompositeBase, /* field based on composite */ + ippECComplicatedBase, /* number of non-zero terms in the polynomial (> PRIME_ARR_MAX) */ + ippECIsZeroDiscriminant,/* zero discriminant */ + ippECCompositeOrder, /* composite order of base point */ + ippECInvalidOrder, /* invalid base point order */ + ippECIsWeakMOV, /* weak Meneze-Okamoto-Vanstone reduction attack */ + ippECIsWeakSSSA, /* weak Semaev-Smart,Satoh-Araki reduction attack */ + ippECIsSupersingular, /* supersingular curve */ + + ippECInvalidPrivateKey, /* !(0 < Private < order) */ + ippECInvalidPublicKey, /* (order*PublicKey != Infinity) */ + ippECInvalidKeyPair, /* (Private*BasePoint != PublicKey) */ + + ippECPointOutOfGroup, /* out of group (order*P != Infinity) */ + ippECPointIsAtInfinite, /* point (P=(Px,Py)) at Infinity */ + ippECPointIsNotValid, /* point (P=(Px,Py)) out-of EC */ + + ippECPointIsEqual, /* compared points are equal */ + ippECPointIsNotEqual, /* compared points are different */ + + ippECInvalidSignature /* invalid signature */ +} IppECResult; + +/* domain parameter set/get flags */ +typedef enum { + ippECarbitrary =0x00000, IppECCArbitrary = 0x00000, /* arbitrary ECC */ + + ippECPstd = 0x10000, IppECCPStd = 0x10000, /* random (recommended) EC over FG(p): */ + ippECPstd112r1 = ippECPstd, IppECCPStd112r1 = IppECCPStd, /* secp112r1 curve */ + ippECPstd112r2 = ippECPstd+1, IppECCPStd112r2 = IppECCPStd+1, /* secp112r2 curve */ + ippECPstd128r1 = ippECPstd+2, IppECCPStd128r1 = IppECCPStd+2, /* secp128r1 curve */ + ippECPstd128r2 = ippECPstd+3, IppECCPStd128r2 = IppECCPStd+3, /* secp128r2 curve */ + ippECPstd160r1 = ippECPstd+4, IppECCPStd160r1 = IppECCPStd+4, /* secp160r1 curve */ + ippECPstd160r2 = ippECPstd+5, IppECCPStd160r2 = IppECCPStd+5, /* secp160r2 curve */ + ippECPstd192r1 = ippECPstd+6, IppECCPStd192r1 = IppECCPStd+6, /* secp192r1 curve */ + ippECPstd224r1 = ippECPstd+7, IppECCPStd224r1 = IppECCPStd+7, /* secp224r1 curve */ + ippECPstd256r1 = ippECPstd+8, IppECCPStd256r1 = IppECCPStd+8, /* secp256r1 curve */ + ippECPstd384r1 = ippECPstd+9, IppECCPStd384r1 = IppECCPStd+9, /* secp384r1 curve */ + ippECPstd521r1 = ippECPstd+10, IppECCPStd521r1 = IppECCPStd+10, /* secp521r1 curve */ + ippECPstdSM2 = ippECPstd+11, IppECCPStdSM2 = IppECCPStd+11, /* TMP SM2 curve */ + ippEC_TPM_SM2_P256= ippECPstd+11, + ippEC_TPM_BN_P256 = ippECPstd+12, /* TPM BN_P256 curve */ + + /* curves over binary finit fields are not supported in Intel® IPP 9.0 */ + IppECCBStd = 0x20000, /* random (recommended) EC over FG(2^m): */ + IppECCBStd113r1 = IppECCBStd, /* sect113r1 curve */ + IppECCBStd113r2 = IppECCBStd+1, /* sect113r2 curve */ + IppECCBStd131r1 = IppECCBStd+2, /* sect131r1 curve */ + IppECCBStd131r2 = IppECCBStd+3, /* sect131r2 curve */ + IppECCBStd163r1 = IppECCBStd+4, /* sect163r1 curve */ + IppECCBStd163r2 = IppECCBStd+5, /* sect163r2 curve */ + IppECCBStd193r1 = IppECCBStd+6, /* sect193r1 curve */ + IppECCBStd193r2 = IppECCBStd+7, /* sect193r2 curve */ + IppECCBStd233r1 = IppECCBStd+8, /* sect233r1 curve */ + IppECCBStd283r1 = IppECCBStd+9, /* sect283r1 curve */ + IppECCBStd409r1 = IppECCBStd+10, /* sect409r1 curve */ + IppECCBStd571r1 = IppECCBStd+11, /* sect571r1 curve */ + + IppECCKStd = 0x40000, /* Koblitz (recommended) EC over FG(2^m): */ + IppECCBStd163k1 = IppECCKStd, /* Koblitz 163 curve */ + IppECCBStd233k1 = IppECCKStd+1, /* Koblitz 233 curve */ + IppECCBStd239k1 = IppECCKStd+2, /* Koblitz 239 curve */ + IppECCBStd283k1 = IppECCKStd+3, /* Koblitz 283 curve */ + IppECCBStd409k1 = IppECCKStd+4, /* Koblitz 409 curve */ + IppECCBStd571k1 = IppECCKStd+5 /* Koblitz 571 curve */ +} IppsECType, IppECCType; + +/* +// GF over prime and its extension +*/ +#define IPP_MIN_GF_CHAR (3) /* min characteristic of GF */ + +#define IPP_MIN_GF_BITSIZE (2) /* min bitsize of element over prime GF */ +#define IPP_MAX_GF_BITSIZE (1024) /* max bitsize of element over prime GF */ + +#define IPP_MIN_GF_EXTDEG (2) /* min GF extension degree */ +#define IPP_MAX_GF_EXTDEG (8) /* max GF extension degree */ + +#define IPP_MAX_EXPONENT_NUM (6) /* max number of exponents, equals to LOG_CACHE_LINE_SIZE */ + +typedef struct _cpGFpMethod IppsGFpMethod; + +typedef struct _cpGFp IppsGFpState; +typedef struct _cpGFpElement IppsGFpElement; + +typedef struct _cpGFpEC IppsGFpECState; +typedef struct _cpGFpECPoint IppsGFpECPoint; + +typedef struct _cpGFpEC IppsECCPState; +typedef struct _cpGFpECPoint IppsECCPPointState; + +typedef struct { + int hashSize; + int msgBlockSize; +} IppsHashInfo; + +typedef struct { + //const IppsGFpState* pBasicGF; + //const IppsGFpState* pGroundGF; + int parentGFdegree; + int basicGFdegree; + int basicElmBitSize; +} IppsGFpInfo; + +/* SM3 Digest Bytes Size */ +#define IPP_SM3_DIGEST_BYTESIZE ((IPP_SM3_DIGEST_BITSIZE + 7) / 8) + +typedef struct _cpStateECES_SM2 IppsECESState_SM2; + +typedef enum { + ippKESM2Requester = 0xF, /* corresponds to A user/participant */ + ippKESM2Responder /* corresponds to B user/participant */ +} IppsKeyExchangeRoleSM2; + +typedef struct _GFpECKeyExchangeSM2 IppsGFpECKeyExchangeSM2State; + +#endif /* !defined( _OWN_BLDPCS ) */ + +IPPAPI( IppStatus, ippcpGetCpuFeatures, ( Ipp64u* pFeaturesMask )) +IPPAPI( IppStatus, ippcpSetCpuFeatures, ( Ipp64u features )) +IPPAPI( Ipp64u, ippcpGetEnabledCpuFeatures, ( void ) ) +IPPAPI( IppStatus, ippcpSetNumThreads, ( int numThr )) +IPPAPI( IppStatus, ippcpInit,( void )) +IPPAPI( IppStatus, ippcpGetNumThreads, (int* pNumThr) ) +IPPAPI( const char*, ippcpGetStatusString, ( IppStatus StsCode )) +IPPAPI( int, ippcpGetEnabledNumThreads, ( void ) ) +IPPAPI( Ipp64u, ippcpGetCpuClocks, (void) ) + +#ifdef __cplusplus +} +#endif + +#endif /* !defined IPPCPDEFS_H__ || defined( _OWN_BLDPCS ) */ diff --git a/plugin/ippcp/library/src/include/ippversion.h b/plugin/ippcp/library/src/include/ippversion.h new file mode 100644 index 000000000..71376145b --- /dev/null +++ b/plugin/ippcp/library/src/include/ippversion.h @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright (C) 2001 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +// Purpose: Describes the Intel IPP Cryptography version +// +*/ + + +#if !defined( IPPVERSION_H__ ) +#define IPPVERSION_H__ + +#define IPP_VERSION_MAJOR 2021 +#define IPP_VERSION_MINOR 9 +#define IPP_VERSION_UPDATE 0 + +// Major interface version +#define IPP_INTERFACE_VERSION_MAJOR 11 +// Minor interface version +#define IPP_INTERFACE_VERSION_MINOR 9 + +#define IPP_VERSION_STR STR(IPP_VERSION_MAJOR) "." STR(IPP_VERSION_MINOR) "." STR(IPP_VERSION_UPDATE) " (" STR(IPP_INTERFACE_VERSION_MAJOR) "." STR(IPP_INTERFACE_VERSION_MINOR) " )" + +#endif /* IPPVERSION_H__ */ diff --git a/plugin/ippcp/library/src/sources/cmake/CMakeASM_NASMOptions.txt b/plugin/ippcp/library/src/sources/cmake/CMakeASM_NASMOptions.txt new file mode 100644 index 000000000..8204215c8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/CMakeASM_NASMOptions.txt @@ -0,0 +1,43 @@ +#=============================================================================== +# Copyright (C) 2019 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +# + +if (UNIX) + set(CMAKE_ASM_NASM_DEBUG_OPTIONS -g) + if (APPLE) + set(CMAKE_ASM_NASM_OBJECT_FORMAT macho64) + else() + if (${ARCH} MATCHES "ia32") + set(CMAKE_ASM_NASM_OBJECT_FORMAT elf32) + else() + set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64) + endif() + endif() +else() # Windows + if (${ARCH} MATCHES "ia32") + set(CMAKE_ASM_NASM_OBJECT_FORMAT win32) # MS extended COFF for Win32 + else() + set(CMAKE_ASM_NASM_OBJECT_FORMAT win64) + endif() +endif() + + +set(CMAKE_ASM_NASM_COMPILE_OBJECT " -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o ") +set(CMAKE_ASM_NASM_FLAGS_INIT "${LIBRARY_DEFINES}") diff --git a/plugin/ippcp/library/src/sources/cmake/ippcp-config-version.cmake.in b/plugin/ippcp/library/src/sources/cmake/ippcp-config-version.cmake.in new file mode 100644 index 000000000..87bf1e3b0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/ippcp-config-version.cmake.in @@ -0,0 +1,36 @@ +#=============================================================================== +# Copyright (C) 2019 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +# library detection routine (version compatibility rules). +# + +set(PACKAGE_VERSION @IPPCP_INTERFACE_VERSION@) + +set(PACKAGE_VERSION_EXACT False) +set(PACKAGE_VERSION_COMPATIBLE False) + +if(PACKAGE_FIND_VERSION VERSION_EQUAL PACKAGE_VERSION) + set(PACKAGE_VERSION_EXACT True) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() + +if(PACKAGE_FIND_VERSION_MAJOR EQUAL @IPPCP_INTERFACE_VERSION_MAJOR@ + AND PACKAGE_FIND_VERSION VERSION_LESS PACKAGE_VERSION) + set(PACKAGE_VERSION_COMPATIBLE True) +endif() diff --git a/plugin/ippcp/library/src/sources/cmake/ippcp-config.cmake.in b/plugin/ippcp/library/src/sources/cmake/ippcp-config.cmake.in new file mode 100644 index 000000000..a1e94fb6b --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/ippcp-config.cmake.in @@ -0,0 +1,149 @@ +#=============================================================================== +# Copyright (C) 2019 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +# library detection routine. +# +# To use it, add the lines below to your CMakeLists.txt: +# find_package(IPPCP REQUIRED) +# target_link_libraries(mytarget ${IPPCP_LIBRARIES}) +# +# List of the variables defined in this file: +# IPPCP_FOUND +# IPPCP_LIBRARIES - list of all imported targets +# +# Configuration variables available: +# IPPCP_SHARED - set this to True before find_package() to search for shared library. +# IPPCP_ARCH - set this to 'ia32' or 'intel64' before find_package() to use library of particular arch +# (this variable can be auto-defined) +# + +# Initialize to default values +if (NOT IPPCP_LIBRARIES) + set(IPPCP_LIBRARIES "") +endif() + +# Determine ARCH if not defined outside +if (NOT DEFINED IPPCP_ARCH) + set(IPPCP_ARCH "ia32") + if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) + set(IPPCP_ARCH "intel64") + endif() + if(CMAKE_SIZEOF_VOID_P) + set(IPPCP_ARCH "intel64") + endif() +endif() + +if (NOT IPPCP_FIND_COMPONENTS) + set(IPPCP_FIND_COMPONENTS "ippcp") + + # crypto_mb library is only for intel64 + if(${IPPCP_ARCH} MATCHES "intel64") + set(IPPCP_BIN_REL_PATH @IPPCP_BIN64_REL_PATH@) + set(IPPCP_LIB_REL_PATH @IPPCP_LIB64_REL_PATH@) + + set(IPPCP_FIND_COMPONENTS "${IPPCP_FIND_COMPONENTS}" "crypto_mb") + else() + set(IPPCP_BIN_REL_PATH @IPPCP_BIN32_REL_PATH@) + set(IPPCP_LIB_REL_PATH @IPPCP_LIB32_REL_PATH@) + endif() + + foreach (_component ${IPPCP_FIND_COMPONENTS}) + set(IPPCP_FIND_REQUIRED_${_component} 1) + endforeach() +endif() + +if (WIN32) + set(_ippcp_library_prefix "") + set(_ippcp_static_library_suffix "mt.lib") + set(_ippcp_shared_library_suffix ".dll") + set(_ippcp_import_library_suffix ".lib") +else() + set(_ippcp_library_prefix "lib") + set(_ippcp_static_library_suffix ".a") + if (APPLE) + set(_ippcp_shared_library_suffix ".dylib") + else() + set(_ippcp_shared_library_suffix ".so") + endif() + set(_ippcp_import_library_suffix "") +endif() + +get_filename_component(_ippcrypto_root "${CMAKE_CURRENT_LIST_DIR}" REALPATH) +set(_ippcrypto_root "${_ippcrypto_root}/../../..") + +macro(add_imported_library_target PATH_TO_LIBRARY PATH_TO_IMPORT_LIB LINKAGE_TYPE) + if (EXISTS "${PATH_TO_LIBRARY}") + if (NOT TARGET IPPCP::${_component}) + add_library(IPPCP::${_component} ${LINKAGE_TYPE} IMPORTED) + get_filename_component(_include_dir "${_ippcrypto_root}/@IPPCP_INC_REL_PATH@" REALPATH) + if (EXISTS "${_include_dir}") + set_target_properties(IPPCP::${_component} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_include_dir}" + IMPORTED_LOCATION "${PATH_TO_LIBRARY}") + if (WIN32) + set_target_properties(IPPCP::${_component} PROPERTIES IMPORTED_IMPLIB "${PATH_TO_IMPORT_LIB}") + endif() + else() + message(WARNING "IPPCP: Include directory does not exist: '${_include_dir}'. Intel IPP Cryptography installation might be broken.") + endif() + unset(_include_dir) + endif() + list(APPEND IPPCP_LIBRARIES IPPCP::${_component}) + set(IPPCP_${_component}_FOUND 1) + elseif (IPPCP_FIND_REQUIRED AND IPPCP_FIND_REQUIRED_${_component}) + message(STATUS "Missed required Intel IPP Cryptography component: ${_component}") + message(STATUS " library not found:\n ${PATH_TO_LIBRARY}") + if (${LINKAGE_TYPE} MATCHES "SHARED") + message(STATUS "You may try to search for static library by unsetting IPPCP_SHARED variable.") + endif() + set(IPPCP_FOUND FALSE) + endif() +endmacro(add_imported_library_target) + +foreach (_component ${IPPCP_FIND_COMPONENTS}) + set(IPPCP_${_component}_FOUND 0) + + if (IPPCP_SHARED) + set(_ippcp_library_suffix "${_ippcp_shared_library_suffix}") + set(_linkage_type "SHARED") + else() + set(_ippcp_library_suffix "${_ippcp_static_library_suffix}") + set(_linkage_type "STATIC") + endif() + + if (WIN32 AND ${_linkage_type} MATCHES "SHARED") + get_filename_component(_lib "${_ippcrypto_root}/${IPPCP_BIN_REL_PATH}/${_ippcp_library_prefix}${_component}${_ippcp_library_suffix}" REALPATH) + get_filename_component(_imp_lib "${_ippcrypto_root}/${PPCP_LIB_REL_PATH}/${_ippcp_library_prefix}${_component}${_ippcp_import_library_suffix}" REALPATH) + else() + get_filename_component(_lib "${_ippcrypto_root}/${IPPCP_LIB_REL_PATH}/${_ippcp_library_prefix}${_component}${_ippcp_library_suffix}" REALPATH) + set(_imp_lib "") + endif() + + add_imported_library_target("${_lib}" "${_imp_lib}" "${_linkage_type}") +endforeach() + +list(REMOVE_DUPLICATES IPPCP_LIBRARIES) +unset(_ippcp_library_prefix) +unset(_ippcp_static_library_suffix) +unset(_ippcp_shared_library_suffix) +unset(_ippcp_import_library_suffix) +unset(_ippcp_library_suffix) +unset(_linkage_type) +unset(_lib) +unset(_imp_lib) diff --git a/plugin/ippcp/library/src/sources/cmake/linux/sanitizers_ignorelist.txt b/plugin/ippcp/library/src/sources/cmake/linux/sanitizers_ignorelist.txt new file mode 100644 index 000000000..7dd77caa9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/linux/sanitizers_ignorelist.txt @@ -0,0 +1,22 @@ +#=============================================================================== +# Copyright 2022 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#=============================================================================== + +[memory] +fun:*cpGetFeatures* +fun:*IntelCpu* +fun:*ppSetIppEnvironment* +src:tests/testlib/* +src:perf_tests/perflib/* \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/cmake/pkg-config/crypto_mb-dynamic.pc.in b/plugin/ippcp/library/src/sources/cmake/pkg-config/crypto_mb-dynamic.pc.in new file mode 100644 index 000000000..98ae0f97c --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/pkg-config/crypto_mb-dynamic.pc.in @@ -0,0 +1,27 @@ +#=============================================================================== +# Copyright (C) 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +prefix=@PREFIX_FOR_PC_FILE@ +libdir=@LIBDIR_FOR_PC_FILE@ +includedir=@INCDIR_FOR_PC_FILE@ + +Name: Intel® Integrated Performance Primitives (Intel® IPP) Cryptography Crypto Multi-Buffer Library +Description: This library consists of highly-optimized kernels taking advantage of Intel’s multi-buffer processing and Intel® AVX-512 instruction set. +URL: https://github.com/intel/ipp-crypto +Version: @IPPCP_VERSION@ +Libs: -L${libdir} -l@CRYPTO_MB_PC_LIB_NAME@ +Cflags: -I${includedir} diff --git a/plugin/ippcp/library/src/sources/cmake/pkg-config/crypto_mb-static.pc.in b/plugin/ippcp/library/src/sources/cmake/pkg-config/crypto_mb-static.pc.in new file mode 100644 index 000000000..4a1df4413 --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/pkg-config/crypto_mb-static.pc.in @@ -0,0 +1,27 @@ +#=============================================================================== +# Copyright (C) 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +prefix=@PREFIX_FOR_PC_FILE@ +libdir=@LIBDIR_FOR_PC_FILE@ +includedir=@INCDIR_FOR_PC_FILE@ + +Name: Intel® Integrated Performance Primitives (Intel® IPP) Cryptography Crypto Multi-Buffer Library +Description: This library consists of highly-optimized kernels taking advantage of Intel’s multi-buffer processing and Intel® AVX-512 instruction set. +URL: https://github.com/intel/ipp-crypto +Version: @IPPCP_VERSION@ +Libs: ${libdir}/@STATIC_LIBRARY_PREFIX@@CRYPTO_MB_PC_LIB_NAME@@STATIC_LIBRARY_SUFFIX@ +Cflags: -I${includedir} diff --git a/plugin/ippcp/library/src/sources/cmake/pkg-config/ippcp-dynamic.pc.in b/plugin/ippcp/library/src/sources/cmake/pkg-config/ippcp-dynamic.pc.in new file mode 100644 index 000000000..94d2773a5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/pkg-config/ippcp-dynamic.pc.in @@ -0,0 +1,27 @@ +#=============================================================================== +# Copyright (C) 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +prefix=@PREFIX_FOR_PC_FILE@ +libdir=@LIBDIR_FOR_PC_FILE@ +includedir=@INCDIR_FOR_PC_FILE@ + +Name: Intel® Integrated Performance Primitives (Intel® IPP) Cryptography Library +Description: Secure, fast and lightweight library of building blocks for cryptography, highly-optimized for various Intel® CPUs. +URL: https://github.com/intel/ipp-crypto +Version: @IPPCP_VERSION@ +Libs: -L${libdir} -l@IPPCP_PC_LIB_NAME@ +Cflags: -I${includedir} diff --git a/plugin/ippcp/library/src/sources/cmake/pkg-config/ippcp-static.pc.in b/plugin/ippcp/library/src/sources/cmake/pkg-config/ippcp-static.pc.in new file mode 100644 index 000000000..7732e58ca --- /dev/null +++ b/plugin/ippcp/library/src/sources/cmake/pkg-config/ippcp-static.pc.in @@ -0,0 +1,27 @@ +#=============================================================================== +# Copyright (C) 2021 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +prefix=@PREFIX_FOR_PC_FILE@ +libdir=@LIBDIR_FOR_PC_FILE@ +includedir=@INCDIR_FOR_PC_FILE@ + +Name: Intel® Integrated Performance Primitives (Intel® IPP) Cryptography Library +Description: Secure, fast and lightweight library of building blocks for cryptography, highly-optimized for various Intel® CPUs. +URL: https://github.com/intel/ipp-crypto +Version: @IPPCP_VERSION@ +Libs: ${libdir}/@STATIC_LIBRARY_PREFIX@@IPPCP_PC_LIB_NAME@@STATIC_LIBRARY_SUFFIX@ +Cflags: -I${includedir} diff --git a/plugin/ippcp/library/src/sources/dispatcher/__pycache__/gen_disp_common.cpython-39.pyc b/plugin/ippcp/library/src/sources/dispatcher/__pycache__/gen_disp_common.cpython-39.pyc new file mode 100644 index 000000000..9b537579f Binary files /dev/null and b/plugin/ippcp/library/src/sources/dispatcher/__pycache__/gen_disp_common.cpython-39.pyc differ diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_common.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_common.py new file mode 100644 index 000000000..fce76b738 --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_common.py @@ -0,0 +1,67 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import re +import sys +import os +import hashlib + +def readNextFunction(header, curLine, headerID): ## read next function with arguments + ## find header ID macros + FunName = '' + FunArg = '' + FunType = '' + success = False + while (curLine < len(header) and success == False): + if not headerID and re.match( '\s*#\s*if\s*!\s*defined\s*\(\s*__IPP', header[curLine]): + headerID= re.sub( '.*__IPP', '__IPP', header[curLine] ) + headerID= re.sub( "\)", '', headerID) + headerID= re.sub( '[\n\s]', '', headerID ) + + if re.match( '^\s*IPPAPI\s*\(.*', header[curLine] ) : + FunStr= header[curLine]; + FunStr= re.sub('\n','',FunStr) ## remove EOL symbols + + while not re.match('.*\)\s*\)\s*$', FunStr): ## concatinate strinng if string is not completed + curLine= curLine+1 + FunStr= FunStr+header[curLine] + FunStr= re.sub('\n','',FunStr) ## remove EOL symbols + + FunStr= re.sub('\s+', ' ', FunStr) + + s= FunStr.split(',') + + ## Extract funtion name + FunName= s[1] + FunName= re.sub('\s', '', FunName) + + ## Extract function type + FunType= re.sub( '.*\(', '', s[0] ) + #FunType= re.sub(' ', '', FunType ) + + ## Extract function arguments + FunArg= re.sub('.*\(.*,.+,\s*\(', '(', FunStr) + FunArg= re.sub('\)\s*\)', ')', FunArg) + success = True + + curLine = curLine + 1 + + return {'curLine':curLine, 'FunType':FunType, 'FunName':FunName, 'FunArg':FunArg, 'success':success } \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin32.nonpic.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin32.nonpic.py new file mode 100644 index 000000000..b2155c475 --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin32.nonpic.py @@ -0,0 +1,175 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import re +import sys +import os +import hashlib +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-i', '--header', action='store', required=True, help='Intel IPP Cryptography dispatcher will be generated for fucntions in Header') +parser.add_argument('-o', '--out-directory', action='store', required=True, help='Output folder for generated files') +parser.add_argument('-l', '--cpu-list', action='store', required=True, help='Actual CPU list: semicolon separated string') +parser.add_argument('-c', '--compiler', action='store', required=True, help='Compiler') +args = parser.parse_args() +Header = args.header +OutDir = args.out_directory +cpulist = args.cpu_list.split(';') +compiler = args.compiler + +headerID= False ## Header ID define to avoid multiple include like: #if !defined( __IPPCP_H__ ) + +from gen_disp_common import readNextFunction + +HDR= open( Header, 'r' ) +h= HDR.readlines() +HDR.close() + + +## keep filename only +(incdir, Header)= os.path.split(Header) + +## original header name to declare external functions as internal for dispatcher +OrgH= Header + +isFunctionFound = True +curLine = 0 +FunName = "" +FunArg = "" + +if(compiler == "GNU" or compiler == "Clang" or compiler == "IntelLLVM"): + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files ASM + ################################################## + ASMDISP= open( os.sep.join([OutDir, "jmp_" + FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] +".asm"]), 'w' ) + + # Symbol type setting for extern functions initially appeared in version 2.15 + ASMDISP.write("%if ((__NASM_MAJOR__ > 2) || ((__NASM_MAJOR__ == 2) && (__NASM_MINOR__ > 14)))\n"); + ASMDISP.write(" %xdefine elf_symbol_type :function\n"); + ASMDISP.write("%else\n"); + ASMDISP.write(" %xdefine elf_symbol_type\n"); + ASMDISP.write("%endif\n"); + for cpu in cpulist: + ASMDISP.write("extern "+cpu+"_"+FunName+"%+elf_symbol_type\n") + + ASMDISP.write("extern ippcpJumpIndexForMergedLibs\n") + ASMDISP.write("extern ippcpInit%+elf_symbol_type\n\n") + ASMDISP.write(""" +segment .data +align 4 + +dd in_{FunName} +arraddr_{FunName}: + +""".format(FunName=FunName)) + size = 4 + for cpu in cpulist: + size = size + 4 + ASMDISP.write(" dd "+cpu+"_"+FunName+"\n") + + ASMDISP.write(""" + +segment .text +global {FunName}:function ({FunName}.LEnd{FunName} - {FunName}) +in_{FunName}: + {endbr32} + call ippcpInit + align 16 +{FunName}: + {endbr32} + mov eax, dword [ippcpJumpIndexForMergedLibs] + jmp dword [rel arraddr_{FunName} + eax*4] +.LEnd{FunName}: +""".format(FunName=FunName, size=size, endbr32='db 0xf3, 0x0f, 0x1e, 0xfb')) + ASMDISP.close() +else: + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files: C file with inline asm + ################################################## + DISP= open( os.sep.join([OutDir, "jmp_"+FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] + ".c"]), 'w' ) + + DISP.write("""#include "ippcpdefs.h"\n\n""") + + DISP.write("typedef void (*IPP_PROC)(void);\n\n") + DISP.write("extern int ippcpJumpIndexForMergedLibs;\n") + DISP.write("extern IPP_CALL ippcpInit();\n\n") + + DISP.write("extern IppStatus in_"+FunName+FunArg+";\n") + + for cpu in cpulist: + DISP.write("extern IppStatus "+cpu+"_"+FunName+FunArg+";\n") + + DISP.write(""" +__asm( " .data"); +__asm( " .align 4"); +__asm( "arraddr:"); +__asm( " .long in_{FunName}");""".format(FunName=FunName)) + size = 4 + for cpu in cpulist: + size = size + 4 + DISP.write("""\n__asm( " .long {cpu}_{FunName}");""".format(FunName=FunName, cpu=cpu)) + + DISP.write(""" +__asm( " .type arraddr,@object"); +__asm( " .size arraddr,{size}"); +__asm( " .data");\n""".format(size=size)) + + DISP.write(""" +#undef IPPAPI +#define IPPAPI(type,name,arg) __declspec(naked) void name arg +IPPAPI(IppStatus, {FunName},{FunArg}) +{{ + __asm( ".L0: mov ippcpJumpIndexForMergedLibs, %eax"); + __asm( "mov (arraddr+4)(,%eax,4), %eax" ); + __asm( "jmp *%eax" ); + __asm( ".global in_{FunName}" ); + __asm( "in_{FunName}:" ); + {endbr32} + __asm( "call ippcpInit" ); + __asm( "jmp .L0" ); +}}; +""".format(FunName=FunName, FunArg=FunArg, endbr32='__asm( ".byte 0xf3, 0x0f, 0x1e, 0xfb" );')) + + DISP.close() + diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin32.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin32.py new file mode 100644 index 000000000..7dda598f7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin32.py @@ -0,0 +1,191 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import re +import sys +import os +import hashlib +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-i', '--header', action='store', required=True, help='Intel IPP Cryptography dispatcher will be generated for fucntions in Header') +parser.add_argument('-o', '--out-directory', action='store', required=True, help='Output folder for generated files') +parser.add_argument('-l', '--cpu-list', action='store', required=True, help='Actual CPU list: semicolon separated string') +parser.add_argument('-c', '--compiler', action='store', required=True, help='Compiler') +args = parser.parse_args() +Header = args.header +OutDir = args.out_directory +cpulist = args.cpu_list.split(';') +compiler = args.compiler + +headerID= False ## Header ID define to avoid multiple include like: #if !defined( __IPPCP_H__ ) + +from gen_disp_common import readNextFunction + +HDR= open( Header, 'r' ) +h= HDR.readlines() +HDR.close() + + +## keep filename only +(incdir, Header)= os.path.split(Header) + +## original header name to declare external functions as internal for dispatcher +OrgH= Header + +isFunctionFound = True +curLine = 0 +FunName = "" +FunArg = "" + +if(compiler == "GNU" or compiler == "Clang" or compiler == "IntelLLVM"): + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files ASM + ################################################## + ASMDISP= open( os.sep.join([OutDir, "jmp_" + FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] +".asm"]), 'w' ) + + # Symbol type setting for extern functions initially appeared in version 2.15 + ASMDISP.write("%if ((__NASM_MAJOR__ > 2) || ((__NASM_MAJOR__ == 2) && (__NASM_MINOR__ > 14)))\n"); + ASMDISP.write(" %xdefine elf_symbol_type :function\n"); + ASMDISP.write("%else\n"); + ASMDISP.write(" %xdefine elf_symbol_type\n"); + ASMDISP.write("%endif\n"); + for cpu in cpulist: + ASMDISP.write("extern "+cpu+"_"+FunName+"%+elf_symbol_type\n") + + ASMDISP.write("extern ippcpJumpIndexForMergedLibs\n") + ASMDISP.write("extern ippcpInit%+elf_symbol_type\n\n") + + ASMDISP.write(""" +segment .data +align 4 +dd .Lin_{FunName} +.Larraddr_{FunName}: +""".format(FunName=FunName)) + + for cpu in cpulist: + ASMDISP.write(" dd "+cpu+"_"+FunName+"\n") + + ASMDISP.write(""" + +segment .text +extern _GLOBAL_OFFSET_TABLE_ +global {FunName}:function ({FunName}.LEnd{FunName} - {FunName}) +.Lin_{FunName}: + {endbr32} + push ebx + mov ebx, eax + call ippcpInit wrt ..plt + pop ebx + align 16 +{FunName}: + {endbr32} + call .L1 +.L1: + pop eax + add eax, _GLOBAL_OFFSET_TABLE_ + $$ - .L1 wrt ..gotpc + mov edx, [eax + ippcpJumpIndexForMergedLibs wrt ..got] + mov edx, [edx] + jmp dword [eax + edx*4 + .Larraddr_{FunName} wrt ..gotoff] +.LEnd{FunName}: +""".format(FunName=FunName, endbr32='db 0xf3, 0x0f, 0x1e, 0xfb')) + ASMDISP.close() +else: + + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files: C file with inline asm + ################################################## + DISP= open( os.sep.join([OutDir, "jmp_"+FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] + ".c"]), 'w' ) + + DISP.write("""#include "ippcpdefs.h"\n\n""") + + DISP.write("typedef void (*IPP_PROC)(void);\n\n") + DISP.write("extern int ippcpJumpIndexForMergedLibs;\n") + DISP.write("extern IPP_CALL ippcpInit();\n\n") + + DISP.write("extern IppStatus IPP_CALL in_"+FunName+FunArg+";\n") + + for cpu in cpulist: + DISP.write("extern IppStatus IPP_CALL "+cpu+"_"+FunName+FunArg+";\n") + + DISP.write(""" +__asm( " .data"); +__asm( " .align 4"); +__asm( "arraddr:"); +__asm( " .long in_{FunName}");""".format(FunName=FunName)) + size = 4 + for cpu in cpulist: + size = size + 4 + DISP.write("""\n__asm( " .long {cpu}_{FunName}");""".format(FunName=FunName, cpu=cpu)) + + DISP.write(""" +__asm( " .type arraddr,@object"); +__asm( " .size arraddr,{size}"); +__asm( " .data");\n""".format(size=size)) + + DISP.write(""" +#undef IPPAPI +#define IPPAPI(type,name,arg) __declspec(naked) void IPP_CALL name arg +__declspec(naked) IPP_PROC {FunName}{FunArg} +{{ + __asm( ".L0: call .L1"); + __asm( ".L1: pop %eax"); + __asm( "add $_GLOBAL_OFFSET_TABLE_ - .L1, %eax" ); + __asm( "movd ippcpJumpIndexForMergedLibs@GOT(%eax), %xmm0" ); + __asm( "movd %xmm0, %edx" ); + __asm( "mov (%edx), %edx" ); + __asm( "mov (arraddr@GOTOFF+4)(%eax,%edx,4), %edx" ); + __asm( "jmp *%edx" ); + __asm( ".global in_{FunName}" ); + __asm( "in_{FunName}:" ); + {endbr32} + __asm( "push %ebx" ); + __asm( "mov %eax, %ebx" ); + __asm( "call ippcpInit@PLT" ); + __asm( "pop %ebx" ); + __asm( "jmp .L0" ); +}}; +""".format(FunName=FunName, FunArg=FunArg, endbr32='__asm( ".byte 0xf3, 0x0f, 0x1e, 0xfb" );')) + + DISP.close() + diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin64.nonpic.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin64.nonpic.py new file mode 100644 index 000000000..8439ef17e --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin64.nonpic.py @@ -0,0 +1,175 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import re +import sys +import os +import hashlib +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-i', '--header', action='store', required=True, help='Intel IPP Cryptography dispatcher will be generated for fucntions in Header') +parser.add_argument('-o', '--out-directory', action='store', required=True, help='Output folder for generated files') +parser.add_argument('-l', '--cpu-list', action='store', required=True, help='Actual CPU list: semicolon separated string') +parser.add_argument('-c', '--compiler', action='store', required=True, help='Compiler') +args = parser.parse_args() +Header = args.header +OutDir = args.out_directory +cpulist = args.cpu_list.split(';') +compiler = args.compiler + +headerID= False ## Header ID define to avoid multiple include like: #if !defined( __IPPCP_H__ ) + +from gen_disp_common import readNextFunction + +HDR= open( Header, 'r' ) +h= HDR.readlines() +HDR.close() + + +## keep filename only +(incdir, Header)= os.path.split(Header) + +## original header name to declare external functions as internal for dispatcher +OrgH= Header + +isFunctionFound = True +curLine = 0 +FunType = "" +FunName = "" +FunArg = "" + +if(compiler == "GNU" or compiler == "Clang" or compiler == "IntelLLVM"): + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunType = result['FunType'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files ASM + ################################################## + ASMDISP= open( os.sep.join([OutDir, "jmp_" + FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] +".asm"]), 'w' ) + + # Symbol type setting for extern functions initially appeared in version 2.15 + ASMDISP.write("%if ((__NASM_MAJOR__ > 2) || ((__NASM_MAJOR__ == 2) && (__NASM_MINOR__ > 14)))\n"); + ASMDISP.write(" %xdefine elf_symbol_type :function\n"); + ASMDISP.write("%else\n"); + ASMDISP.write(" %xdefine elf_symbol_type\n"); + ASMDISP.write("%endif\n"); + for cpu in cpulist: + ASMDISP.write("extern "+cpu+"_"+FunName+"%+elf_symbol_type\n") + + ASMDISP.write("extern ippcpJumpIndexForMergedLibs\n") + ASMDISP.write("extern ippcpSafeInit%+elf_symbol_type\n\n") + ASMDISP.write(""" +segment .data +align 8 +dq .Lin_{FunName} +.Larraddr_{FunName}: +""".format(FunName=FunName)) + + for cpu in cpulist: + ASMDISP.write(" dq "+cpu+"_"+FunName+"\n") + + ASMDISP.write(""" +segment .text +global {FunName}:function ({FunName}.LEnd{FunName} - {FunName}) +.Lin_{FunName}: + {endbr64} + call ippcpSafeInit + align 16 + +{FunName}: + {endbr64} + movsxd rax, dword [ippcpJumpIndexForMergedLibs] + lea r11, [rel .Larraddr_{FunName}] + mov r11, qword [r11 + rax*8] + jmp r11 +.LEnd{FunName}: +""".format(FunName=FunName, endbr64='db 0xf3, 0x0f, 0x1e, 0xfa')) + ASMDISP.close() +else: + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunType = result['FunType'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files: C file with inline asm + ################################################## + DISP= open( os.sep.join([OutDir, "jmp_"+FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] + ".c"]), 'w' ) + + DISP.write("""#include "ippcp.h"\n\n#pragma warning(disable : 1478 1786) // deprecated\n\n""") + + DISP.write("typedef "+FunType+" (*IPP_PROC)"+FunArg+";\n\n") + DISP.write("extern int ippcpJumpIndexForMergedLibs;\n") + DISP.write("extern IppStatus ippcpSafeInit( void );\n\n") + + DISP.write("extern "+FunType+" in_"+FunName+FunArg+";\n") + + for cpu in cpulist: + DISP.write("extern "+FunType+" "+cpu+"_"+FunName+FunArg+";\n") + + DISP.write("static IPP_PROC arraddr[] =\n{{\n (IPP_PROC)in_{}".format(FunName)) + + for cpu in cpulist: + DISP.write(",\n (IPP_PROC)"+cpu+"_"+FunName+"") + + DISP.write("\n};") + + DISP.write(""" +#undef IPPAPI +#define IPPAPI(type,name,arg) __declspec(naked) type name arg + +IPPAPI({FunType}, {FunName},{FunArg}) +{{ + __asm{{ + movsxd rax, dword ptr ippcpJumpIndexForMergedLibs + mov rax, qword ptr [8*rax+8+arraddr] + jmp rax + }} +}} + +IPPAPI({FunType}, in_{FunName},{FunArg}) +{{ + __asm{{ + call ippcpSafeInit + lea rax, {FunName} + jmp rax + }} +}}; +""".format(FunType=FunType, FunName=FunName, FunArg=FunArg)) + + DISP.close() diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin64.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin64.py new file mode 100644 index 000000000..d5645d547 --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_lin64.py @@ -0,0 +1,174 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import re +import sys +import os +import hashlib +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-i', '--header', action='store', required=True, help='Intel IPP Cryptography dispatcher will be generated for fucntions in Header') +parser.add_argument('-o', '--out-directory', action='store', required=True, help='Output folder for generated files') +parser.add_argument('-l', '--cpu-list', action='store', required=True, help='Actual CPU list: semicolon separated string') +parser.add_argument('-c', '--compiler', action='store', required=True, help='Compiler') +args = parser.parse_args() +Header = args.header +OutDir = args.out_directory +cpulist = args.cpu_list.split(';') +compiler = args.compiler + +headerID= False ## Header ID define to avoid multiple include like: #if !defined( __IPPCP_H__ ) + +from gen_disp_common import readNextFunction + +HDR= open( Header, 'r' ) +h= HDR.readlines() +HDR.close() + + +## keep filename only +(incdir, Header)= os.path.split(Header) + +## original header name to declare external functions as internal for dispatcher +OrgH= Header + +isFunctionFound = True +curLine = 0 +FunType = "" +FunName = "" +FunArg = "" + +if(compiler == "GNU" or compiler == "Clang" or compiler == "IntelLLVM"): + + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunType = result['FunType'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files ASM + ################################################## + ASMDISP= open( os.sep.join([OutDir, "jmp_" + FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] +".asm"]), 'w' ) + + # Symbol type setting for extern functions initially appeared in version 2.15 + ASMDISP.write("%if ((__NASM_MAJOR__ > 2) || ((__NASM_MAJOR__ == 2) && (__NASM_MINOR__ > 14)))\n"); + ASMDISP.write(" %xdefine elf_symbol_type :function\n"); + ASMDISP.write("%else\n"); + ASMDISP.write(" %xdefine elf_symbol_type\n"); + ASMDISP.write("%endif\n"); + for cpu in cpulist: + ASMDISP.write("extern "+cpu+"_"+FunName+"%+elf_symbol_type\n") + + ASMDISP.write("extern ippcpJumpIndexForMergedLibs\n") + ASMDISP.write("extern ippcpSafeInit%+elf_symbol_type\n\n") + ASMDISP.write(""" +segment .data +align 8 +dq .Lin_{FunName} +.Larraddr_{FunName}: +""".format(FunName=FunName)) + + for cpu in cpulist: + ASMDISP.write(" dq "+cpu+"_"+FunName+"\n") + + ASMDISP.write(""" +segment .text +global {FunName}:function ({FunName}.LEnd{FunName} - {FunName}) +.Lin_{FunName}: + {endbr64} + call ippcpSafeInit wrt ..plt + align 16 + +{FunName}: + {endbr64} + mov rax, qword [rel ippcpJumpIndexForMergedLibs wrt ..gotpc] + movsxd rax, dword [rax] + lea r11, [rel .Larraddr_{FunName}] + mov r11, qword [r11+rax*8] + jmp r11 +.LEnd{FunName}: +""".format(FunName=FunName, endbr64='db 0xf3, 0x0f, 0x1e, 0xfa')) + ASMDISP.close() + +else: + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunType = result['FunType'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files: C file with inline asm + ################################################## + DISP= open( os.sep.join([OutDir, "jmp_"+FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] + ".c"]), 'w' ) + + DISP.write("""#include "ippcp.h"\n\n#pragma warning(disable : 1478 1786) // deprecated\n\n""") + + DISP.write("typedef "+FunType+" (*IPP_PROC)"+FunArg+";\n\n") + DISP.write("extern int ippcpJumpIndexForMergedLibs;\n") + DISP.write("extern IppStatus ippcpSafeInit( void );\n\n") + + DISP.write("extern "+FunType+" in_"+FunName+FunArg+";\n") + + for cpu in cpulist: + DISP.write("extern "+FunType+" "+cpu+"_"+FunName+FunArg+";\n") + + DISP.write("static IPP_PROC arraddr[] =\n{{\n (IPP_PROC)in_{}".format(FunName)) + + for cpu in cpulist: + DISP.write(",\n (IPP_PROC)"+cpu+"_"+FunName+"") + + DISP.write("\n};") + + DISP.write(""" +#undef IPPAPI +#define IPPAPI(type,name,arg) __declspec(naked) type name arg +IPPAPI({FunType}, {FunName},{FunArg}) +{{ + register unsigned long long i __asm__("rax"); + i = (unsigned long long)arraddr[ippcpJumpIndexForMergedLibs+1]; + _asm{{ jmp rax }} +}}; +IPPAPI({FunType}, in_{FunName},{FunArg}) +{{ + __asm{{ + call ippcpSafeInit + mov rax, qword ptr [{FunName}] + jmp rax + }} +}}; +""".format(FunType=FunType, FunName=FunName, FunArg=FunArg)) + + DISP.close() diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_mac64.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_mac64.py new file mode 100644 index 000000000..badc127e1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_mac64.py @@ -0,0 +1,168 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import re +import sys +import os +import hashlib +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-i', '--header', action='store', required=True, help='Intel IPP Cryptography dispatcher will be generated for fucntions in Header') +parser.add_argument('-o', '--out-directory', action='store', required=True, help='Output folder for generated files') +parser.add_argument('-l', '--cpu-list', action='store', required=True, help='Actual CPU list: semicolon separated string') +parser.add_argument('-c', '--compiler', action='store', help='Compiler') # is not used +args = parser.parse_args() +Header = args.header +OutDir = args.out_directory +cpulist = args.cpu_list.split(';') +compiler = args.compiler + +headerID= False ## Header ID define to avoid multiple include like: #if !defined( __IPPCP_H__ ) + +from gen_disp_common import readNextFunction + +HDR= open( Header, 'r' ) +h= HDR.readlines() +HDR.close() + + +## keep filename only +(incdir, Header)= os.path.split(Header) + +## original header name to declare external functions as internal for dispatcher +OrgH= Header + +isFunctionFound = True +curLine = 0 +FunType = "" +FunName = "" +FunArg = "" + +if(compiler == "AppleClang"): + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunType = result['FunType'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files ASM + ################################################## + ASMDISP= open( os.sep.join([OutDir, "jmp_" + FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] +".asm"]), 'w' ) + + for cpu in cpulist: + ASMDISP.write("extern "+"_"+cpu+"_"+FunName+"\n") + + ASMDISP.write("extern _ippcpJumpIndexForMergedLibs\n") + ASMDISP.write("extern _ippcpSafeInit\n\n") + ASMDISP.write(""" + segment .data + align 8 + dq .Lin_{FunName} + .Larraddr_{FunName}: + """.format(FunName=FunName)) + + for cpu in cpulist: + ASMDISP.write(" dq "+"_"+cpu+"_"+FunName+"\n") + + ASMDISP.write(""" + segment .text + global _{FunName} + .Lin_{FunName}: + {endbr64} + call _ippcpSafeInit + align 16 + + _{FunName}: + {endbr64} + mov rax, qword [rel _ippcpJumpIndexForMergedLibs wrt ..gotpcrel] + movsxd rax, dword [rax] + lea r11, [rel .Larraddr_{FunName}] + mov r11, qword [r11+rax*8] + jmp r11 + .LEnd{FunName}: + """.format(FunName=FunName, endbr64='db 0xf3, 0x0f, 0x1e, 0xfa')) + ASMDISP.close() +else: + while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunType = result['FunType'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files: C file with inline asm + ################################################## + DISP= open( os.sep.join([OutDir, "jmp_"+FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] + ".c"]), 'w' ) + + DISP.write("""#include "ippcp.h"\n\n#pragma warning(disable : 1478 1786) // deprecated\n\n""") + + DISP.write("typedef "+FunType+" (*IPP_PROC)"+FunArg+";\n\n") + DISP.write("extern int ippcpJumpIndexForMergedLibs;\n") + DISP.write("extern IppStatus ippcpSafeInit( void );\n\n") + + DISP.write("extern "+FunType+" in_"+FunName+FunArg+";\n") + + for cpu in cpulist: + DISP.write("extern "+FunType+" "+cpu+"_"+FunName+FunArg+";\n") + + DISP.write("static IPP_PROC arraddr[] =\n{{\n (IPP_PROC)in_{}".format(FunName)) + + for cpu in cpulist: + DISP.write(",\n (IPP_PROC)"+cpu+"_"+FunName+"") + + DISP.write("\n};") + + DISP.write(""" + #undef IPPAPI + #define IPPAPI(type,name,arg) __declspec(naked) type name arg + + IPPAPI({FunType}, {FunName},{FunArg}) + {{ + register unsigned long long i __asm__("rax"); + i = (unsigned long long)arraddr[ippcpJumpIndexForMergedLibs+1]; + __asm{{ jmp rax }} + }}; + + IPPAPI({FunType}, in_{FunName},{FunArg}) + {{ + __asm{{ + call ippcpSafeInit + mov rax, qword ptr [{FunName}] + jmp rax + }} + }}; + """.format(FunType=FunType, FunName=FunName, FunArg=FunArg)) + + DISP.close() diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_win32.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_win32.py new file mode 100644 index 000000000..4534b70db --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_win32.py @@ -0,0 +1,117 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import re +import sys +import os +import hashlib +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-i', '--header', action='store', required=True, help='Intel IPP Cryptography dispatcher will be generated for fucntions in Header') +parser.add_argument('-o', '--out-directory', action='store', required=True, help='Output folder for generated files') +parser.add_argument('-l', '--cpu-list', action='store', required=True, help='Actual CPU list: semicolon separated string') +parser.add_argument('-c', '--compiler', action='store', help='Compiler') # is not used +args = parser.parse_args() +Header = args.header +OutDir = args.out_directory +cpulist = args.cpu_list.split(';') + +headerID= False ## Header ID define to avoid multiple include like: #if !defined( __IPPCP_H__ ) + +from gen_disp_common import readNextFunction + +HDR= open( Header, 'r' ) +h= HDR.readlines() +HDR.close() + + +## keep filename only +(incdir, Header)= os.path.split(Header) + +## original header name to declare external functions as internal for dispatcher +OrgH= Header + +isFunctionFound = True +curLine = 0 +FunName = "" +FunType = "" +FunArg = "" + +while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunType = result['FunType'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + + ################################################## + ## create dispatcher files: C file with inline asm + ################################################## + DISP= open( os.sep.join([OutDir, "jmp_"+FunName+"_" + hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8] + ".c"]), 'w' ) + + DISP.write("""#include "ippcpdefs.h" """) + + DISP.write("\n\ntypedef " + FunType + "(*IPP_PROC)(void);\n\n") + DISP.write("extern int ippcpJumpIndexForMergedLibs;\n") + DISP.write("extern IppStatus IPP_CALL ippcpInit();\n\n") + + DISP.write("extern " + FunType + " IPP_CALL in_"+FunName+FunArg+";\n") + + for cpu in cpulist: + DISP.write("extern " + FunType + " IPP_CALL "+cpu+"_"+FunName+FunArg+";\n") + + DISP.write("static IPP_PROC arraddr[] =\n{{\n (IPP_PROC)in_{}".format(FunName)) + + for cpu in cpulist: + DISP.write(",\n (IPP_PROC)"+cpu+"_"+FunName+"") + + DISP.write("\n};") + + DISP.write(""" +#ifdef _MSC_VER +#pragma warning(disable: 4100) // for MSVC, unreferenced param +#endif +#undef IPPAPI +#define IPPAPI(type,name,arg) __declspec(naked) type __stdcall name arg +IPPAPI({FunType}, {FunName},{FunArg}) +{{ + __asm {{mov eax, dword ptr ippcpJumpIndexForMergedLibs}} + __asm {{mov eax, arraddr[eax*4+4]}} + __asm {{jmp eax}} +}}; + +IPPAPI({FunType}, in_{FunName},{FunArg}) +{{ + __asm {{call ippcpInit}} + __asm {{mov eax, dword ptr ippcpJumpIndexForMergedLibs }} + __asm {{mov eax, arraddr[eax*4+4]}} + __asm {{jmp eax}} +}}; +""".format(FunType=FunType, FunName=FunName, FunArg=FunArg)) + + DISP.close() + diff --git a/plugin/ippcp/library/src/sources/dispatcher/gen_disp_win64.py b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_win64.py new file mode 100644 index 000000000..9c52b29b7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/dispatcher/gen_disp_win64.py @@ -0,0 +1,107 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +# + +import re +import sys +import os +import hashlib +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-i', '--header', action='store', required=True, help='Intel IPP Cryptography dispatcher will be generated for fucntions in Header') +parser.add_argument('-o', '--out-directory', action='store', required=True, help='Output folder for generated files') +parser.add_argument('-l', '--cpu-list', action='store', required=True, help='Actual CPU list: semicolon separated string') +parser.add_argument('-c', '--compiler', action='store', help='Compiler') # is not used +args = parser.parse_args() +Header = args.header +OutDir = args.out_directory +cpulist = args.cpu_list.split(';') + +headerID= False ## Header ID define to avoid multiple include like: #if !defined( __IPPCP_H__ ) + +from gen_disp_common import readNextFunction + +HDR= open( Header, 'r' ) +h= HDR.readlines() +HDR.close() + +## keep filename only +(incdir, Header)= os.path.split(Header) + +## original header name to declare external functions as internal for dispatcher +OrgH= Header + +isFunctionFound = True +curLine = 0 +FunName = "" +FunArg = "" + +while (isFunctionFound == True): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunName = result['FunName'] + FunArg = result['FunArg'] + isFunctionFound = result['success'] + + if (isFunctionFound == True): + ################################################## + ## create dispatcher files: C file with inline asm + ################################################## + filename = "jmp_{}_{}".format(FunName, hashlib.sha512(FunName.encode('utf-8')).hexdigest()[:8]) + + DISP= open( os.sep.join([OutDir, filename + ".asm"]), 'w' ) + + for cpu in cpulist: + DISP.write("extern "+cpu+"_"+FunName+"\n") + + DISP.write("extern ippcpJumpIndexForMergedLibs\n") + DISP.write("extern ippcpSafeInit\n\n") + + DISP.write("segment data\n\n") + + DISP.write(" DQ in_"+FunName+"\n") + DISP.write(FunName+"_arraddr:\n") + + for cpu in cpulist: + DISP.write(" DQ "+cpu+"_"+FunName+"\n") + + DISP.write(""" + +segment text + +global {FunName} + +in_{FunName}: + {endbr64} + call ippcpSafeInit + align 16 +{FunName}: + {endbr64} + movsxd rax, dword [rel ippcpJumpIndexForMergedLibs] + lea r10, [rel {FunName}_arraddr] + mov r10, qword [r10+rax*8] + jmp r10 + +""".format(FunName=FunName, endbr64='db 0xf3, 0x0f, 0x1e, 0xfa')) + + DISP.close() diff --git a/plugin/ippcp/library/src/sources/gen_cpu_spc_header/gen_cpu_spc_1cpu_header.py b/plugin/ippcp/library/src/sources/gen_cpu_spc_header/gen_cpu_spc_1cpu_header.py new file mode 100644 index 000000000..c04402055 --- /dev/null +++ b/plugin/ippcp/library/src/sources/gen_cpu_spc_header/gen_cpu_spc_1cpu_header.py @@ -0,0 +1,86 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import sys +import os +import datetime + +sys.path.append(os.path.join(sys.path[0], '../dispatcher')) + +from gen_disp_common import readNextFunction + +Header = sys.argv[1] +OutDir = sys.argv[2] + +Header = os.path.abspath(Header) +Filename = "" + +HDR= open(Header, 'r') +h= HDR.readlines() +HDR.close() + +headerID= False +FunName = "" + + +if not os.path.exists(OutDir): + os.makedirs(OutDir) + + +Filename="ippcp" +Filenames=["h9", "p8", "s8", "w7", "e9", "k0", "k1", "l9", "m7", "n0", "n8", "y8", "g9"] + +for name in Filenames: + OutFile = os.sep.join([OutDir, Filename + "_"+ name + ".h"]) + + OUT= open( OutFile, 'w' ) + OUT.write("""/******************************************************************************* + * Copyright {year} Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + + """.format(year=datetime.datetime.today().year)) + + curLine = 0 + isFunctionFound = True + + while (isFunctionFound): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunName = result['FunName'] + isFunctionFound = result['success'] + + if (isFunctionFound): + OUT.write("#define " + FunName + " " + name +"_" + FunName + "\n") + OUT.close() diff --git a/plugin/ippcp/library/src/sources/gen_cpu_spc_header/gen_cpu_spc_header.py b/plugin/ippcp/library/src/sources/gen_cpu_spc_header/gen_cpu_spc_header.py new file mode 100644 index 000000000..0bf8f2610 --- /dev/null +++ b/plugin/ippcp/library/src/sources/gen_cpu_spc_header/gen_cpu_spc_header.py @@ -0,0 +1,81 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel(R) Integrated Performance Primitives Cryptography (Intel(R) IPP Cryptography) +# + +import sys +import os +import datetime + +sys.path.append(os.path.join(sys.path[0], '../dispatcher')) + +from gen_disp_common import readNextFunction + +Header = sys.argv[1] +OutDir = sys.argv[2] + +Header = os.path.abspath(Header) +Filename = "" + +HDR= open(Header, 'r') +h= HDR.readlines() +HDR.close() + +headerID= False +FunName = "" + +if not os.path.exists(OutDir): + os.makedirs(OutDir) + +Filename = "ippcp_cpuspc" +OutFile = os.sep.join([OutDir, Filename + ".h"]) + +OUT= open( OutFile, 'w' ) +OUT.write("""/******************************************************************************* +* Copyright {year} Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +""".format(year=datetime.datetime.today().year)) + +curLine = 0 +isFunctionFound = True + +while (isFunctionFound): + + result = readNextFunction(h, curLine, headerID) + + curLine = result['curLine'] + FunName = result['FunName'] + isFunctionFound = result['success'] + + if (isFunctionFound): + OUT.write("#define " + FunName + " " + "OWNAPI(" + FunName + ")\n") +OUT.close() diff --git a/plugin/ippcp/library/src/sources/include/asmdefs.inc b/plugin/ippcp/library/src/sources/include/asmdefs.inc new file mode 100644 index 000000000..a7a3daaaa --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/asmdefs.inc @@ -0,0 +1,175 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef __ASMDEFS_INC__ +%define __ASMDEFS_INC__ 1 + +%assign _IPP_PX 0 ; pure C-code ia32 +%assign _IPP_M5 1 ; Intel(R) Quark(TM) processor - ia32 +%assign _IPP_W7 8 ; Intel(R) Streaming SIMD Extensions 2 - ia32 +%assign _IPP_T7 16 ; Intel(R) Streaming SIMD Extensions 3 - ia32 +%assign _IPP_V8 32 ; Supplemental Streaming SIMD Extensions 3 (SSSE3) +%assign _IPP_S8 33 ; SSSE3 + MOVBE instruction - ia32 +%assign _IPP_P8 64 ; Intel(R) Streaming SIMD Extensions 4.2 - ia32 +%assign _IPP_G9 128 ; Intel(R) Advanced Vector Extensions - ia32 +%assign _IPP_H9 256 ; Intel(R) Advanced Vector Extensions 2 - ia32 +%assign _IPP_I0 512 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon Phi(TM) processor (formerly Knight Landing) - ia32 +%assign _IPP_S0 1024 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon(R) processor (formerly Skylake) - ia32 + +%assign _IPP32E_PX _IPP_PX ; pure C-code x64 +%assign _IPP32E_M7 32 ; Intel(R) Streaming SIMD Extensions 3 - intel64 +%assign _IPP32E_U8 64 ; Supplemental Streaming SIMD Extensions 3 (SSSE3) - intel64 +%assign _IPP32E_N8 65 ; SSSE3 + MOVBE instruction - intel64 +%assign _IPP32E_Y8 128 ; Intel(R) Streaming SIMD Extensions 4.2 - intel64 +%assign _IPP32E_E9 256 ; Intel(R) Advanced Vector Extensions - intel64 +%assign _IPP32E_L9 512 ; Intel(R) Advanced Vector Extensions 2 - intel64 +%assign _IPP32E_N0 1024 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon Phi(TM) processor (formerly Knight Landing) - intel64 +%assign _IPP32E_K0 2048 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon(R) processor (formerly Skylake) - intel64 +%assign _IPP32E_K1 4096 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon(R) processor (formerly Icelake) - intel64 + +%assign _IPP _IPP_PX +%assign _IPP32E _IPP32E_PX + +%ifdef _M5 ; Intel(R) Quark(TM) processor - ia32 + %assign _IPP _IPP_M5 +%elifdef _W7 ; Intel(R) Streaming SIMD Extensions 2 - ia32 + %assign _IPP _IPP_W7 +%elifdef _T7 ; Intel(R) Streaming SIMD Extensions 3 - ia32 + %assign _IPP _IPP_T7 +%elifdef _V8 ; Supplemental Streaming SIMD Extensions 3 (SSSE3) + %assign _IPP _IPP_V8 +%elifdef _S8 ; SSSE3 + MOVBE instruction - ia32 + %assign _IPP _IPP_S8 +%elifdef _P8 ; Intel(R) Streaming SIMD Extensions 4.2 - ia32 + %assign _IPP _IPP_P8 +%elifdef _G9 ; Intel(R) Advanced Vector Extensions - ia32 + %assign IPP_ALIGN_FACTOR 32 + %assign _IPP _IPP_G9 +%elifdef _H9 ; Intel(R) Advanced Vector Extensions 2 - ia32 + %assign IPP_ALIGN_FACTOR 32 + %assign _IPP _IPP_H9 +%elifdef _S0 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon(R) processor (formerly Skylake) - ia32 + %assign IPP_ALIGN_FACTOR 64 + %assign _IPP _IPP_S0 +%elifdef _M7 ; Intel(R) Streaming SIMD Extensions 3 - intel64 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_M7 +%elifdef _U8 ; Supplemental Streaming SIMD Extensions 3 (SSSE3) - intel64 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_U8 +%elifdef _N8 ; SSSE3 + MOVBE instruction - intel64 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_N8 +%elifdef _Y8 ; Intel(R) Streaming SIMD Extensions 4.2 - intel64 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_Y8 +%elifdef _E9 ; Intel(R) Advanced Vector Extensions - intel64 + %assign IPP_ALIGN_FACTOR 32 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_E9 +%elifdef _L9 ; Intel(R) Advanced Vector Extensions 2 - intel64 + %assign IPP_ALIGN_FACTOR 32 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_L9 +%elifdef _N0 ; Intel(R) Advanced Vector Extensions 512 (formerly Knights Landing) - intel64 + %assign IPP_ALIGN_FACTOR 64 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_N0 +%elifdef _K0 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon(R) processor (formerly Skylake) - intel64 + %assign IPP_ALIGN_FACTOR 64 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_K0 +%elifdef _K1 ; Intel(R) Advanced Vector Extensions 512 - Intel(R) Xeon(R) processor (formerly Icelake) - intel64 + %assign IPP_ALIGN_FACTOR 64 + %assign _IPP _IPP_PX + %assign _IPP32E _IPP32E_K1 +%else + %assign _IPP _IPP_PX ; pure C-code +%endif + +%if (_IPP > _IPP_H9) || (_IPP32E > _IPP32E_L9) + %assign IPP_ALIGN_FACTOR 64 +%elif (_IPP > _IPP_P8) || (_IPP32E > _IPP32E_Y8) + %assign IPP_ALIGN_FACTOR 32 +%else + %assign IPP_ALIGN_FACTOR 16 +%endif + +; noexec stack +%ifdef LINUX32 + %ifndef OSX32 +section .note.GNU-stack noalloc noexec nowrite progbits + %endif +%endif + +; noexec stack +%ifdef LINUX32E + %ifndef OSXEM64T + %ifndef _ARCH_KNC +section .note.GNU-stack noalloc noexec nowrite progbits + %endif + %endif +%endif + + +%ifidn __OUTPUT_FORMAT__, elf32 + %assign IPP_BINARY_FORMAT 0 +%elifidn __OUTPUT_FORMAT__, elf64 + %assign IPP_BINARY_FORMAT 1 +%elifidn __OUTPUT_FORMAT__, macho64 + %assign IPP_BINARY_FORMAT 2 +%elifidn __OUTPUT_FORMAT__, win32 + %assign IPP_BINARY_FORMAT 3 +%elifidn __OUTPUT_FORMAT__, win64 + %assign IPP_BINARY_FORMAT 4 +%else + %fatal Unsupported output format: __OUTPUT_FORMAT__. Shall be: elf32, elf64, win32, win64, macho64 +%endif + +%ifdef _MERGED_BLD + %assign _OWN_MERGED_BLD 1 +%endif ; _MERGED_BLD + +; data compilation definitions: merged builds shall compile data only as +; part of one single object build to avoid multiple definition warnings at link time +%ifndef _MERGED_BLD + %assign _IPP_DATA 1 +%else + %if (_IPP == _IPP_G9) || (_IPP32E == _IPP32E_E9) + %assign _IPP_DATA 1 + %endif +%endif ; _MERGED_BLD + +; Definitions of sizeof(type) +%iassign ZWORD_size 64 ; zmm-word +%iassign YWORD_size 32 ; ymm-word +%iassign OWORD_size 16 ; octo-word +%iassign TWORD_size 10 ; ten-bytes word +%iassign QWORD_size 8 ; quad-word +%iassign DWORD_size 4 ; double-word +%iassign WORD_size 2 +%iassign BYTE_size 1 + +%idefine YMMWORD YWORD +%idefine XMMWORD OWORD +%iassign YMMWORD_size YWORD_size +%iassign XMMWORD_size OWORD_size + +%idefine sizeof(_x_) _x_%+_size + +%endif +;;;;;;;;;;;;;;;;;;;;;;;;;; End of file "asmdefs.inc" ;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/plugin/ippcp/library/src/sources/include/dispatcher.h b/plugin/ippcp/library/src/sources/include/dispatcher.h new file mode 100644 index 000000000..8290df60d --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/dispatcher.h @@ -0,0 +1,293 @@ +/******************************************************************************* +* Copyright (C) 2009 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// + +#ifndef __DISPATCHER_H__ +#define __DISPATCHER_H__ + +#if defined( __cplusplus ) +extern "C" { +#endif + +/* + Intel IPP Cryptography libraries and CPU features mask fitness. Implemented only for IA32 and Intel64 (emt) +*/ + +#if defined( _ARCH_IA32 ) +#define M5_FM ( 0 ) +#ifdef _IPP_QUARK +#define PX_FM ( 0 ) +#else +#define PX_FM ( ippCPUID_MMX | ippCPUID_SSE ) +#endif +#define W7_FM ( PX_FM | ippCPUID_SSE2 ) +#define V8_FM ( W7_FM | ippCPUID_SSE3 | ippCPUID_SSSE3 ) +#define S8_FM ( V8_FM | ippCPUID_MOVBE ) +#define P8_FM ( V8_FM | ippCPUID_SSE41 | ippCPUID_SSE42 | ippCPUID_AES | ippCPUID_CLMUL | ippCPUID_SHA ) +#define G9_FM ( P8_FM | ippCPUID_AVX | ippAVX_ENABLEDBYOS | ippCPUID_RDRAND | ippCPUID_F16C ) +#define H9_FM ( G9_FM | ippCPUID_MOVBE | ippCPUID_AVX2 | ippCPUID_ADCOX | ippCPUID_RDSEED | ippCPUID_PREFETCHW ) +#define I0_FM ( H9_FM | ippCPUID_AVX512F | ippCPUID_AVX512CD | ippCPUID_AVX512PF | ippCPUID_AVX512ER | ippAVX512_ENABLEDBYOS ) +#define S0_FM ( H9_FM | ippCPUID_AVX512F | ippCPUID_AVX512CD | ippCPUID_AVX512VL | ippCPUID_AVX512BW | ippCPUID_AVX512DQ | ippAVX512_ENABLEDBYOS ) + +#elif defined (_ARCH_EM64T) + +#define PX_FM ( ippCPUID_MMX | ippCPUID_SSE | ippCPUID_SSE2 ) +#define M7_FM ( PX_FM | ippCPUID_SSE3 ) +#define U8_FM ( M7_FM | ippCPUID_SSSE3 ) +#define N8_FM ( U8_FM | ippCPUID_MOVBE ) +#define Y8_FM ( U8_FM | ippCPUID_SSE41 | ippCPUID_SSE42 | ippCPUID_AES | ippCPUID_CLMUL | ippCPUID_SHA ) +#define E9_FM ( Y8_FM | ippCPUID_AVX | ippAVX_ENABLEDBYOS | ippCPUID_RDRAND | ippCPUID_F16C ) +#define L9_FM ( E9_FM | ippCPUID_MOVBE | ippCPUID_AVX2 | ippCPUID_ADCOX | ippCPUID_RDSEED | ippCPUID_PREFETCHW ) +#define N0_FM ( L9_FM | ippCPUID_AVX512F | ippCPUID_AVX512CD | ippCPUID_AVX512PF | ippCPUID_AVX512ER | ippAVX512_ENABLEDBYOS ) +#define K0_FM ( L9_FM | ippCPUID_AVX512F | ippCPUID_AVX512CD | ippCPUID_AVX512VL | ippCPUID_AVX512BW | ippCPUID_AVX512DQ | ippAVX512_ENABLEDBYOS ) + +#elif defined (_ARCH_LRB2) + #define PX_FM ( ippCPUID_KNC ) +#else + #error undefined architecture +#endif + +#define PX_MSK ( 0 ) +#define MMX_MSK ( ippCPUID_MMX ) +#define SSE_MSK ( MMX_MSK | ippCPUID_SSE ) +#define SSE2_MSK ( SSE_MSK | ippCPUID_SSE2 ) +#define SSE3_MSK ( SSE2_MSK | ippCPUID_SSE3 ) +#define SSSE3_MSK ( SSE3_MSK | ippCPUID_SSSE3 ) +#define ATOM_MSK ( SSE3_MSK | ippCPUID_SSSE3 | ippCPUID_MOVBE ) +#define SSE41_MSK ( SSSE3_MSK | ippCPUID_SSE41 ) +#define SSE42_MSK ( SSE41_MSK | ippCPUID_SSE42 ) +#define AVX_MSK ( SSE42_MSK | ippCPUID_AVX ) +#define AVX2_MSK ( AVX_MSK | ippCPUID_AVX2 ) +#define AVX3X_MSK ( AVX2_MSK | ippCPUID_AVX512F | ippCPUID_AVX512CD | ippCPUID_AVX512VL | ippCPUID_AVX512BW | ippCPUID_AVX512DQ ) +#define AVX3M_MSK ( AVX2_MSK | ippCPUID_AVX512F | ippCPUID_AVX512CD | ippCPUID_AVX512PF | ippCPUID_AVX512ER ) +#define AVX3I_MSK ( AVX3X_MSK | ippCPUID_SHA | ippCPUID_AVX512VBMI | ippCPUID_AVX512VBMI2 | ippCPUID_AVX512IFMA | ippCPUID_AVX512GFNI | ippCPUID_AVX512VAES | ippCPUID_AVX512VCLMUL ) + +#if defined( _ARCH_IA32 ) && !defined( OSX32 ) + enum lib_enum { + LIB_W7=0, LIB_S8=1, LIB_P8=2, LIB_G9=3, LIB_H9=4, LIB_NOMORE + }; + #define LIB_PX LIB_W7 +#elif defined( OSX32 ) + enum lib_enum { + LIB_S8=0, LIB_P8=1, LIB_G9=2, LIB_H9=3, LIB_NOMORE + }; + #define LIB_PX LIB_S8 + #define LIB_W7 LIB_S8 +#elif defined( _ARCH_EM64T ) && !defined( OSXEM64T ) && !defined( WIN32E ) /* Linux* OS Intel64 supports N0 */ + enum lib_enum { + LIB_M7=0, LIB_N8=1, LIB_Y8=2, LIB_E9=3, LIB_L9=4, LIB_N0=5, LIB_K0=6, LIB_K1=7,LIB_NOMORE + }; + #define LIB_PX LIB_M7 +#elif defined( _ARCH_EM64T ) && !defined( OSXEM64T ) /* Windows* OS Intel64 doesn't support N0 */ + enum lib_enum { + LIB_M7=0, LIB_N8=1, LIB_Y8=2, LIB_E9=3, LIB_L9=4, LIB_K0=5, LIB_K1=6, LIB_NOMORE + }; + #define LIB_PX LIB_M7 + #define LIB_N0 LIB_L9 +#elif defined( OSXEM64T ) + enum lib_enum { + LIB_Y8=0, LIB_E9=1, LIB_L9=2, LIB_K0=3, LIB_K1=4, LIB_NOMORE + }; + #define LIB_PX LIB_Y8 + #define LIB_M7 LIB_Y8 + #define LIB_N8 LIB_Y8 + #define LIB_N0 LIB_L9 +#elif defined( _ARCH_LRB2 ) + enum lib_enum { + LIB_PX=0, LIB_B2=1, LIB_NOMORE + }; + #define LIB_MIC LIB_B2 +#else + #error "lib_enum isn't defined!" +#endif + +#if defined( _ARCH_IA32 ) + #if defined( OSX32 ) /* OSX supports starting with Intel® architecture formerly codenamed Penryn only */ + #define LIB_MMX LIB_S8 + #define LIB_SSE LIB_S8 + #define LIB_SSE2 LIB_S8 + #define LIB_SSE3 LIB_S8 + #define LIB_ATOM LIB_S8 + #define LIB_SSSE3 LIB_S8 + #define LIB_SSE41 LIB_S8 + #define LIB_SSE42 LIB_P8 + #define LIB_AVX LIB_G9 + #define LIB_AVX2 LIB_H9 + #define LIB_AVX3M LIB_H9 /* no ia32 library for Intel® Xeon® Phi(TM) processor (formerly Knight Landing) */ + #define LIB_AVX3X LIB_H9 /* no ia32 library for Intel® Xeon® processor (formerly Skylake) */ + #define LIB_AVX3I LIB_H9 /* no ia32 library for Intel® Xeon® processor (formerly Icelake) */ +#else + #define LIB_MMX LIB_W7 + #define LIB_SSE LIB_W7 + #define LIB_SSE2 LIB_W7 + #define LIB_SSE3 LIB_W7 + #define LIB_ATOM LIB_S8 + #define LIB_SSSE3 LIB_S8 + #define LIB_SSE41 LIB_S8 /* P8 is oriented for new Intel Atom® processor (formerly Silvermont) */ + #define LIB_SSE42 LIB_P8 + #define LIB_AVX LIB_G9 + #define LIB_AVX2 LIB_H9 + #define LIB_AVX3M LIB_H9 /* no ia32 library for Intel® Xeon® Phi(TM) processor (formerly Knight Landing) */ + #define LIB_AVX3X LIB_H9 /* no ia32 library for Intel® Xeon® processor (formerly Skylake) */ + #define LIB_AVX3I LIB_H9 /* no ia32 library for Intel® Xeon® processor (formerly Icelake) */ +#endif +#elif defined (_ARCH_EM64T) + #if defined( OSXEM64T ) /* OSX supports starting PNR only */ + #define LIB_MMX LIB_N8 + #define LIB_SSE LIB_N8 + #define LIB_SSE2 LIB_N8 + #define LIB_SSE3 LIB_N8 + #define LIB_ATOM LIB_N8 + #define LIB_SSSE3 LIB_N8 + #define LIB_SSE41 LIB_N8 + #define LIB_SSE42 LIB_Y8 + #define LIB_AVX LIB_E9 + #define LIB_AVX2 LIB_L9 + #define LIB_AVX3M LIB_L9 + #define LIB_AVX3X LIB_K0 + #define LIB_AVX3I LIB_K1 +#else + #define LIB_MMX LIB_M7 + #define LIB_SSE LIB_M7 + #define LIB_SSE2 LIB_M7 + #define LIB_SSE3 LIB_M7 + #define LIB_ATOM LIB_N8 + #define LIB_SSSE3 LIB_N8 + #define LIB_SSE41 LIB_N8 /* Y8 is oriented for new Intel Atom® processor (formerly Silvermont) */ + #define LIB_SSE42 LIB_Y8 + #define LIB_AVX LIB_E9 + #define LIB_AVX2 LIB_L9 + #define LIB_AVX3M LIB_N0 + #define LIB_AVX3X LIB_K0 + #define LIB_AVX3I LIB_K1 +#endif +#elif defined (_ARCH_LRB2) + #define LIB_MIC LIB_B2 +#endif + +//gres: #if defined( _IPP_DYNAMIC ) +#if defined( _PCS ) +#if defined( _ARCH_IA32 ) + +/* Describe Intel CPUs and libraries */ +typedef enum{CPU_W7=0, CPU_S8, CPU_P8, CPU_G9, CPU_H9, CPU_NOMORE} cpu_enum; +typedef enum{DLL_W7=0, DLL_S8, DLL_P8, DLL_G9, DLL_H9, DLL_NOMORE} dll_enum; + +/* New cpu can use some libraries for old cpu */ +static const dll_enum dllUsage[][DLL_NOMORE+1] = { + /* DLL_H9, DLL_G9, DLL_P8, DLL_S8, DLL_W7, DLL_NOMORE */ +/*CPU_W7*/ { DLL_W7, DLL_NOMORE }, +/*CPU_S8*/ { DLL_S8, DLL_W7, DLL_NOMORE }, +/*CPU_P8*/ { DLL_P8, DLL_S8, DLL_W7, DLL_NOMORE }, +/*CPU_G9*/ { DLL_G9, DLL_P8, DLL_S8, DLL_W7, DLL_NOMORE }, +/*CPU_H9*/ { DLL_H9, DLL_G9, DLL_P8, DLL_S8, DLL_W7, DLL_NOMORE } +}; + +#elif defined (_ARCH_EM64T) +/* Describe Intel CPUs and libraries */ +typedef enum{CPU_M7=0, CPU_N8, CPU_Y8, CPU_E9, CPU_L9, CPU_N0, CPU_K0, CPU_K1, CPU_NOMORE} cpu_enum; +typedef enum{DLL_M7=0, DLL_N8, DLL_Y8, DLL_E9, DLL_L9, DLL_N0, DLL_K0, DLL_K1, DLL_NOMORE} dll_enum; + +/* New cpu can use some libraries for old cpu */ +static const dll_enum dllUsage[][DLL_NOMORE+1] = { + /* DLL_K1, DLL_K0, DLL_N0, DLL_L9, DLL_E9, DLL_Y8, DLL_N8, DLL_M7, DLL_NOMORE */ +/*CPU_M7*/ { DLL_M7, DLL_NOMORE }, +/*CPU_N8*/ { DLL_N8, DLL_M7, DLL_NOMORE }, +/*CPU_Y8*/ { DLL_Y8, DLL_N8, DLL_M7, DLL_NOMORE }, +/*CPU_E9*/ { DLL_E9, DLL_Y8, DLL_N8, DLL_M7, DLL_NOMORE }, +/*CPU_L9*/ { DLL_L9, DLL_E9, DLL_Y8, DLL_N8, DLL_M7, DLL_NOMORE }, +/*CPU_N0*/ { DLL_N0, DLL_L9, DLL_E9, DLL_Y8, DLL_N8, DLL_M7, DLL_NOMORE }, +/*CPU_K0*/ { DLL_K0, DLL_N0, DLL_L9, DLL_E9, DLL_Y8, DLL_N8, DLL_M7, DLL_NOMORE } +/*CPU_K1*/ { DLL_K1, DLL_K0, DLL_N0, DLL_L9, DLL_E9, DLL_Y8, DLL_N8, DLL_M7, DLL_NOMORE } +}; + +#endif + +#if defined( _PCS ) + +/* Names of the Intel libraries which can be loaded */ +#if defined ( WIN32 ) +static const _TCHAR* dllNames[DLL_NOMORE] = { + _T(IPP_LIB_PREFIX()) _T("w7") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("s8") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("p8") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("g9") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("h9") _T(".dll") +}; +#elif defined(LINUX32) +static const _TCHAR* dllNames[DLL_NOMORE] = { + _T("lib") _T(IPP_LIB_PREFIX()) _T("w7.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("s8.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("p8.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("g9.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("h9.so") +}; +#elif defined( OSX32 ) +static const _TCHAR* dllNames[DLL_NOMORE] = { + _T("lib") _T(IPP_LIB_PREFIX()) _T("s8") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("p8") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("g9") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("h9") _T(".dylib") +}; +#elif defined( WIN32E ) +static const _TCHAR* dllNames[DLL_NOMORE] = { + _T(IPP_LIB_PREFIX()) _T("m7") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("n8") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("y8") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("e9") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("l9") _T(".dll"), /* no support for N0 on win */ + _T(IPP_LIB_PREFIX()) _T("k0") _T(".dll"), + _T(IPP_LIB_PREFIX()) _T("k1") _T(".dll") +}; +#elif defined( OSXEM64T ) +static const _TCHAR* dllNames[DLL_NOMORE] = { + _T("lib") _T(IPP_LIB_PREFIX()) _T("n8") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("y8") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("e9") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("l9") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("k0") _T(".dylib"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("k1") _T(".dylib") +}; +#elif defined( LINUX32E ) +static const _TCHAR* dllNames[DLL_NOMORE] = { + _T("lib") _T(IPP_LIB_PREFIX()) _T("m7.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("n8.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("y8.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("e9.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("l9.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("n0.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("k0.so"), + _T("lib") _T(IPP_LIB_PREFIX()) _T("k1.so") +}; +#endif + +#endif /* _PCS */ + +#else /*_IPP_DYNAMIC */ + + +#endif + + +#if defined( __cplusplus ) +} +#endif + +#endif /* __DISPATCHER_H__ */ diff --git a/plugin/ippcp/library/src/sources/include/ia_32e.inc b/plugin/ippcp/library/src/sources/include/ia_32e.inc new file mode 100644 index 000000000..fecfe44f6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/ia_32e.inc @@ -0,0 +1,532 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + + +%include "asmdefs.inc" +%include "ia_common.inc" +%include "utils.inc" + +%ifndef __IA_32E_INC__ +%define __IA_32E_INC__ 1 + +%ifndef LINUX32E + %ifndef WIN32E + %fatal \ + LINUX32E or WIN32E - Linux ABI (parameter passing in rdi, rsi, rdx, rcx, r8, r9...) + %endif +%endif + +; Force RIP-relative addressing +; default rel + +%ifdef LINUX32E + %ifdef STACK_ABI + %assign IPP_ABI 2 + %else + %assign IPP_ABI 3 + %endif +%endif + +%ifdef WIN32E + %ifdef STACK_ABI + %assign IPP_ABI 1 + %else + %assign IPP_ABI 0 + %endif +%endif + +; Decorates function name with appropriate CPU prefix (for the merged library). +; The macro is context-dependent and returns decorated name in the %$decorated_func_name +; context variable along with the decoration length in the %$decoration_length context variable. +%macro CPU_PREFIX_DECORATE 1.nolist + %ifnctx _CPU_PREFIX_DECORATE_CTX_ + %fatal "Not in the context: _CPU_PREFIX_DECORATE_CTX_" + %endif + + ; Add CPU-specific suffix for the dispatched library + %ifdef _OWN_MERGED_BLD + %if (_IPP32E == _IPP32E_PX) + %xdefine %%func_name mx_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_M7) + %xdefine %%func_name m7_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_U8) + %xdefine %%func_name u8_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_N8) + %xdefine %%func_name n8_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_Y8) + %xdefine %%func_name y8_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_E9) + %xdefine %%func_name e9_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_L9) + %xdefine %%func_name l9_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_N0) + %xdefine %%func_name n0_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_K0) + %xdefine %%func_name k0_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP32E == _IPP32E_K1) + %xdefine %%func_name k1_%1 + %assign %%decoration_length 3 + %endif + %else + %xdefine %%func_name %1 + %assign %%decoration_length 0 + %endif + + %ifndef %%func_name + %fatal "CPU_PREFIX_DECORATE: unknown decoration for : _IPP32E = " _IPP32E + %endif + %xdefine %$decorated_func_name %[%%func_name] + %assign %$decoration_length %%decoration_length +%endmacro + +; Lists of non-volatile registers that needs to be preserved in a function call +%define NONVOLATILE_REGS_LIN64_GPR rbx,rbp,r12,r13,r14,r15 +%define NONVOLATILE_REGS_WIN64_GPR rbx,rbp,r12,r13,r14,r15,rsi,rdi +%define NONVOLATILE_REGS_WIN64_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 +%define NONVOLATILE_REGS_WIN64_YMM ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13,ymm14,ymm15 + +; Saves non-volatile GPR registers on stack. +; Input - list of used registers. +%macro USES_GPR 1+.nolist + %assign GPR_FRAME 0 + %define GPR_CUR + + %if (IPP_ABI < 2) ; Win64 + %define %%nonvolatile_regs_list %[NONVOLATILE_REGS_WIN64_GPR] + %else ; Lin64 + %define %%nonvolatile_regs_list %[NONVOLATILE_REGS_LIN64_GPR] + %endif + BEGIN_INTERSECT + INTERSECT {%1},{%%nonvolatile_regs_list} + ; List of non-volatile GPR registers in the order they will be pushed on stack + %xdefine GPR_CUR %[%$intersection] + %assign GPR_FRAME %$cardinality * 8 + END_INTERSECT + + ; Push non-volatile GPRs on stack + FOREACH GPR_CUR,{push} +%endmacro + +; Restore preliminary saved by USES_GPR non-volatile GPR registers from the stack. +; The macro shall be called after function processing. +%macro REST_GPR 0.nolist + %ifndef GPR_CUR + %fatal "REST_GPR: no GPR_CUR defined" + %endif + + ; Pop saved registers from the stack + RFOREACH GPR_CUR,{pop} +%endmacro + +; Saves XMM register on stack (SSE version). +; An offset from RSP, where the register will be saved, shall be provided in the calling context. +%macro PUSH_XMM_REG 1.nolist + movdqa [rsp + %$rsp_offset], %1 + %assign %$rsp_offset %$rsp_offset + 16 +%endmacro + +; Saves non-volatile XMM registers on stack and allocates stack size for +; local variables if needed. +; Input - list of used registers (can be empty). +%macro USES_XMM 0-*.nolist + ; LOCAL_FRAME - stack size required for all local variables of the procedure. Shall be defined before USES_XMM macro call if + ; local variables are used in the procedure. + %ifndef LOCAL_FRAME + %assign LOCAL_FRAME 0 + %endif + ; to align size for local variables size on 16-bytes + %assign LOCAL_FRAME (LOCAL_FRAME + 15) & (-16) + %assign S_FRAME 0 + %define XMM_CUR + + ; Convert parameters to the list variable if there are arguments + %if (%0 > 0) + %xdefine %%param_list %1 + %rotate 1 + %rep %0-1 + %xdefine %%param_list %[%%param_list],%1 + %rotate 1 + %endrep + %endif + + %if (IPP_ABI < 2) ; Win64 + %assign %%T_FRAME 0 + BEGIN_INTERSECT + INTERSECT {%%param_list},{%[NONVOLATILE_REGS_WIN64_XMM]} + %define XMM_CUR %[%$intersection] + %assign %%T_FRAME %$cardinality * 16 + END_INTERSECT + + ; Adjust offset depending on function frame + %if ((%%T_FRAME > 0) || (LOCAL_FRAME > 0)) + %assign S_FRAME %%T_FRAME + LOCAL_FRAME + %if (((S_FRAME + GPR_FRAME ) & 8) == 0) + %assign S_FRAME S_FRAME + 8 + %endif + %endif + + ; Allocate space on stack and push XMM registers + %if (S_FRAME > 0) + sub rsp, S_FRAME + %push %?? + %assign %$rsp_offset LOCAL_FRAME + FOREACH %[XMM_CUR],{PUSH_XMM_REG} + %pop %?? + %endif + %else + ; Linux x86_64 ABI does not count MM registers as non-volatile, so they do not need to be + ; preserved, so just allocate stack space for local variables and duplicated register parameters if needed. + %if (IPP_ABI == 2) ; LINUX32S + %assign S_FRAME LOCAL_FRAME + 48 ; 48 = 6 * 8 - stack frame for 6 register inputs + %if (((S_FRAME + GPR_FRAME) & 8 ) == 0) + %assign S_FRAME S_FRAME + 8 + %endif + %assign INP_FRAME S_FRAME - 48 ; for Linux32s-key stack-frame for 6 registers inputs + %else ; LINUX32E + %if (LOCAL_FRAME > 0) + %assign S_FRAME LOCAL_FRAME + %if (((S_FRAME + GPR_FRAME) & 8 ) == 0) + %assign S_FRAME S_FRAME + 8 + %endif + %endif + %endif + %if (S_FRAME > 0) + sub rsp, S_FRAME + %endif + %endif +%endmacro + +; Pop input list of XMM registers from the stack. +; The offset from RSP, where the registers will be taken from, shall be provided in the calling context. +%macro POP_XMM_REG 1.nolist + movdqa %1, [rsp + %$rsp_offset] + %assign %$rsp_offset %$rsp_offset + 16 +%endmacro + +; Restore preliminary saved by USES_XMM non-volatile XMM registers from the stack. +; The macro shall be called after function processing. +%macro REST_XMM 0.nolist + %if (IPP_ABI < 2) + %if (S_FRAME > 0) + %push %?? + %assign %$rsp_offset LOCAL_FRAME + FOREACH %[XMM_CUR],{POP_XMM_REG} + %pop %?? + %endif + %endif + %if (S_FRAME > 0) + add rsp, S_FRAME + %endif + %if (_IPP32E >= _IPP32E_E9) + %if (_IPP32E != _IPP32E_N0) + vzeroupper + %endif + %endif +%endmacro + +; Saves XMM or YMM register on stack (AVX version). +; An offset from RSP, where the registers will be saved, shall be provided in the calling context. +%macro PUSH_XMM_AVX_REG 1.nolist + ; Process registers depending on type + %defstr %%reg_str %1 ; convert register token to the string + %substr %%reg_type %%reg_str 1, 3 ; take first 3 elems of the string + %ifidni %%reg_type, 'xmm' + vmovdqa oword [rsp + %$rsp_offset], %1 + %assign %$rsp_offset %$rsp_offset + 16 + %elifidni %%reg_type, 'ymm' + vmovdqu ymmword [rsp + %$rsp_offset], %1 + %assign %$rsp_offset %$rsp_offset + 32 + %else + %fatal PUSH_XMM_AVX_REG: inconsistent usage - only XMM/YMM registers supported, found: %%reg_type + %endif +%endmacro + +; Saves non-volatile XMM/YMM registers on stack and allocates stack size for +; local variables if needed (AVX version). +; Input - list of used registers (can be empty). +%macro USES_XMM_AVX 0-*.nolist + ; LOCAL_FRAME - stack size required for all local variables of the procedure. Shall be defined before USES_XMM macro call if + ; local variables are used in the procedure. + %ifndef LOCAL_FRAME + %assign LOCAL_FRAME 0 + %endif + ; to align size for local variables size on 16-bytes + %assign LOCAL_FRAME (LOCAL_FRAME + 15) & (-16) + %assign S_FRAME 0 + %define XMM_CUR + %define YMM_CUR + + ; Convert parameters to the list variable if there are arguments + %if (%0 > 0) + %xdefine %%param_list %1 + %rotate 1 + %rep %0-1 + %xdefine %%param_list %[%%param_list],%1 + %rotate 1 + %endrep + %endif + + %if (IPP_ABI < 2) ; Win64 + %assign %%T_FRAME 0 + ; Process XMM registers + BEGIN_INTERSECT + INTERSECT {%%param_list},{%[NONVOLATILE_REGS_WIN64_XMM]} + %define XMM_CUR %[%$intersection] + %assign %%T_FRAME %$cardinality * 16 + END_INTERSECT + + ; Process YMM registers + BEGIN_INTERSECT + INTERSECT {%%param_list},{%[NONVOLATILE_REGS_WIN64_YMM]} + %define YMM_CUR %[%$intersection] + %assign %%T_FRAME %%T_FRAME + %$cardinality * 32 + END_INTERSECT + + ; Adjust offset depending on function frame + %if ((%%T_FRAME > 0) || (LOCAL_FRAME > 0)) + %assign S_FRAME %%T_FRAME + LOCAL_FRAME + %if (((S_FRAME + GPR_FRAME ) & 8) == 0) + %assign S_FRAME S_FRAME + 8 + %endif + %endif + + ; Allocate space on stack and push registers + %if (S_FRAME > 0) + sub rsp, S_FRAME + CONCATENATE {%[XMM_CUR]},{%[YMM_CUR]},%%XMM_YMM_CUR + %push %?? + %assign %$rsp_offset LOCAL_FRAME + FOREACH %[%%XMM_YMM_CUR],{PUSH_XMM_AVX_REG} + %pop %?? + %endif + %else + ; Linux x86_64 ABI does not count MM registers as non-volatile, so they do not need to be + ; preserved, so just allocate stack space for local variables and duplicated register parameters if needed. + %if (IPP_ABI == 2) ; LINUX32S + %assign S_FRAME LOCAL_FRAME + 48 ; 48 = 6 * 8 - stack frame for 6 register inputs + %if (((S_FRAME + GPR_FRAME) & 8 ) == 0) + %assign S_FRAME S_FRAME + 8 + %endif + %assign INP_FRAME S_FRAME - 48 ; for Linux32s-key stack-frame for 6 registers inputs + %else ; LINUX32E + %if (LOCAL_FRAME > 0) + %assign S_FRAME LOCAL_FRAME + %if (((S_FRAME + GPR_FRAME) & 8 ) == 0) + %assign S_FRAME S_FRAME + 8 + %endif + %endif + %endif + %if (S_FRAME > 0) + sub rsp, S_FRAME + %endif + %endif +%endmacro + +; Pop XMM or YMM register from the stack. +; The offset from RSP, where the registers will be taken from, shall be provided in the calling context. +%macro POP_XMM_AVX_REG 1.nolist + ; Process registers depending on type + %defstr %%reg_str %1 ; convert register token to the string + %substr %%reg_type %%reg_str 1, 3 ; take first 3 elems of the string + %ifidni %%reg_type, 'xmm' + vmovdqa %1, oword [rsp + %$rsp_offset] + %assign %$rsp_offset %$rsp_offset + 16 + %elifidni %%reg_type, 'ymm' + vmovdqu %1, ymmword [rsp + %$rsp_offset] + %assign %$rsp_offset %$rsp_offset + 32 + %else + %fatal POP_XMM_AVX_REG: inconsistent usage - only XMM/YMM registers supported, found: %%reg_type + %endif +%endmacro + +; Restore preliminary saved by USES_XMM_AVX non-volatile XMM/YMM registers from the stack. +; The macro shall be called after function processing. +%macro REST_XMM_AVX 0.nolist + %if (IPP_ABI < 2) + %if (S_FRAME > 0) + CONCATENATE {%[XMM_CUR]},{%[YMM_CUR]},%%XMM_YMM_CUR + %push %?? + %assign %$rsp_offset LOCAL_FRAME + FOREACH %[%%XMM_YMM_CUR],{POP_XMM_AVX_REG} + %pop %?? + %endif + %endif + %if (S_FRAME > 0) + add rsp, S_FRAME + %endif + %if (_IPP32E != _IPP32E_N0) + vzeroupper + %endif +%endmacro + +; Helper macro to align different ABIs parameters for uniform usage +%macro COMP_ABI 1.nolist + %if (IPP_ABI == 0) ;; if defined WIN32E + %if (%1 > 0) + mov rdi, rcx ;; ARG_1 + %endif + %if (%1 > 1) + mov rsi, rdx ;; ARG_2 + %endif + %if (%1 > 2) + mov rdx, r8 ;; ARG_3 + %endif + %if (%1 > 3) + mov rcx, r9 ;; ARG_4 + %endif + %if (%1 > 4) + mov r8, [rsp + S_FRAME + GPR_FRAME + 40] ;; ARG_5 + %endif + %if (%1 > 5) + mov r9, [rsp + S_FRAME + GPR_FRAME + 48] ;; ARG_6 + %endif + %if (%1 > 6) + %assign FIRST_P S_FRAME + GPR_FRAME + 56 ;; ARG_7 + %assign ARG_7 S_FRAME + GPR_FRAME + 56 + %endif + %endif + %if (IPP_ABI == 1) ;; if defined WIN32S + %assign FIRST_P S_FRAME + GPR_FRAME + 8 + %if (%1 > 0) + mov [rsp + FIRST_P],rcx + %assign ARG_1 FIRST_P + %endif + %if (%1 > 1) + mov [rsp + FIRST_P + 8],rdx + %assign ARG_2 ARG_1 + 8 + %endif + %if (%1 > 2) + mov [rsp + FIRST_P + 16],r8 + %assign ARG_3 ARG_2 + 8 + %endif + %if (%1 > 3) + mov [rsp + FIRST_P + 24],r9 + %assign ARG_4 ARG_3 + 8 + %endif + %if (%1 > 4) + %assign ARG_5 ARG_4 + 8 + %endif + %if (%1 > 5) + %assign ARG_6 ARG_5 + 8 + %endif + %if (%1 > 6) + %assign ARG_7 ARG_6 + 8 ;; ARG_7 + %endif + %endif + %if (IPP_ABI == 2) ;; if defined LINUX32S + %assign FIRST_P INP_FRAME + %if (%1 > 0) + mov [rsp + FIRST_P],rdi + %assign ARG_1 FIRST_P + %endif + %if (%1 > 1) + mov [rsp + FIRST_P + 8],rsi + %assign ARG_2 ARG_1 + 8 + %endif + %if (%1 > 2) + mov [rsp + FIRST_P + 16],rdx + %assign ARG_3 ARG_2 + 8 + %endif + %if (%1 > 3) + mov [rsp + FIRST_P + 24],rcx + %assign ARG_4 ARG_3 + 8 + %endif + %if (%1 > 4) + mov [rsp + FIRST_P + 32],r8 + %assign ARG_5 ARG_4 + 8 + %endif + %if (%1 > 5) + mov [rsp + FIRST_P + 40],r9 + %assign ARG_6 ARG_5 + 8 + %endif + %if (%1 > 6) + %assign ARG_7 S_FRAME+GPR_FRAME+8 + %endif + %endif + %if (IPP_ABI == 3) + %if (%1 > 6) ;; ARG_1 = rdi ARG_2 = rsi ARG_3 = rdx ARG_4 = rcx ARG_5 = r8 ARG_6 = r9 + %assign FIRST_P S_FRAME + GPR_FRAME + 8 ;; ARG_7 + %assign ARG_7 S_FRAME + GPR_FRAME + 8 + %endif + %endif + %if (%1 > 7) + %assign ARG_8 ARG_7 + 8 ;; ARG_8 + %endif + %if (%1 > 8) + %assign ARG_9 ARG_8 + 8 ;; ARG_9 + %endif + %if (%1 > 9) + %assign ARG_10 ARG_9 + 8 ;; ARG_10 + %endif + %if (%1 > 10) + %assign ARG_11 ARG_10 + 8 ;; ARG_11 + %endif + %if (%1 > 11) + %assign ARG_12 ARG_11 + 8 ;; ARG_12 + %endif + %if (%1 > 12) + %assign ARG_13 ARG_12 + 8 ;; ARG_13 + %endif + %if (%1 > 13) + %assign ARG_14 ARG_13 + 8 ;; ARG_14 + %endif + %if (%1 > 14) + %assign ARG_15 ARG_14 + 8 ;; ARG_15 + %endif + %if (%1 > 15) + %assign ARG_16 ARG_15 + 8 ;; ARG_16 + %endif + %if (%1 > 16) + %assign ARG_17 ARG_16 + 8 ;; ARG_17 + %endif + %if (%1 > 17) + %assign ARG_18 ARG_17 + 8 ;; ARG_18 + %endif +%endmacro + +%macro LD_ADDR 2.nolist + %xdefine %%reg %1 + %xdefine %%addr %2 + +%ifdef xxIPP_PIC + call %%LABEL +%%LABEL: pop %%reg + sub %%reg, %%LABEL-%%addr +%else + lea %%reg, [%%addr] +%endif +%endmacro + +%endif diff --git a/plugin/ippcp/library/src/sources/include/ia_common.inc b/plugin/ippcp/library/src/sources/include/ia_common.inc new file mode 100644 index 000000000..059805626 --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/ia_common.inc @@ -0,0 +1,186 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef __IA_COMMON_INC__ +%define __IA_COMMON_INC__ 1 + +; use multi-byte nop's sequences to align loops and jmp's when threshold is reached +%use smartalign +ALIGNMODE p6,16 + +; Declares function, sets visibility and binding and adds __cdecl decoration when needed. +%macro DECLARE_FUNC 2-3.nolist + %xdefine %%func_name %1 + %xdefine %%visibility %2 + %xdefine %%binding %3 + + %ifctx _DECLARE_FUNC_CTX_ + %fatal "DECLARE_FUNC: already in the context, need to call ENDFUNC" + %endif + + ; Accepted visibility values are PUBLIC and PRIVATE + %ifnidni %%visibility, PUBLIC + %ifnidni %%visibility, PRIVATE + %fatal Function %%func_name visibility is not properly defined. Shall be: PRIVATE or PUBLIC. + %endif + %endif + + ; Accepted binding values are WEAK or STRONG (default) + %ifnempty %%binding + %ifnidni %%binding, WEAK + %ifnidni %%binding, STRONG + %%fatal Function %%func_name binding is not properly defined. Shall be: WEAK or STRONG. + %endif + %endif + %endif + + ; Function decoration length + %assign %%decoration_length 0 + + ; The __cdecl calling convention name decoration (to have interoperability with C). + ; Only public functions are decorated + %ifidni %%visibility, PUBLIC + %if ((IPP_BINARY_FORMAT == 2) || (IPP_BINARY_FORMAT == 3)) ; WIN32 or OSXEM64T + %xdefine %%func_name _%[%%func_name] + %assign %%decoration_length %%decoration_length+1 + %endif + %endif + + ; If current macro is called from IPPASM macro, then function might be decorated by CPU-prefix + %ifctx _IPPASM_CTX_ + %assign %%decoration_length %%decoration_length + %$decoration_length ; %$decoration_length belongs to _IPPASM_CTX_ + %endif + + %push _DECLARE_FUNC_CTX_ + ; setup context variables to use in ENDFUNC + %xdefine %$func_name_ctx %%func_name + %assign %$decoration_length %%decoration_length ; %$decoration_length belongs to _DECLARE_FUNC_CTX_ + + %ifidn %%visibility, PUBLIC + %if (IPP_BINARY_FORMAT < 2) ; LINUX32 or LINUX32E + %ifnempty %%binding + global %%func_name:function %%binding (%%func_name%+.LEnd_%+%%func_name - %%func_name) + %else + global %%func_name:function (%%func_name%+.LEnd_%+%%func_name - %%func_name) + %endif + %else + global %%func_name + %endif + %endif + %%func_name: + + ; CET enabling (macOS not supported) + %if ((IPP_BINARY_FORMAT == 0) || (IPP_BINARY_FORMAT == 3)) ; elf32/win32 + db 0F3h, 00Fh, 01Eh, 0FBh ; endbr32 + %elif ((IPP_BINARY_FORMAT == 1) || (IPP_BINARY_FORMAT == 4)) ; elf64/win64 + db 0F3h, 00Fh, 01Eh, 0FAh ; endbr64 + %endif +%endmacro + +; Calls assembler function declared by DECLARE_FUNC +; Default visibility is PRIVATE (affects decoration) +%macro CALL_FUNC 1-2.nolist PRIVATE + %xdefine %%func_name %1 + %xdefine %%visibility %2 + + ; Accepted visibility values are PUBLIC and PRIVATE + %ifnidni %%visibility, PUBLIC + %ifnidni %%visibility, PRIVATE + %fatal Function %%func_name visibility is not properly defined. Shall be: PRIVATE or PUBLIC. + %endif + %endif + + ; __cdecl on WIN32/OSXEM64T obligates to have undersore prefix decoration. + ; Only PUBLIC functions are decorated. + %ifidni %%visibility, PUBLIC + %if ((IPP_BINARY_FORMAT == 2) || (IPP_BINARY_FORMAT == 3)) ; WIN32 or OSXEM64T + %xdefine %%func_name _%1 + %endif + %endif + + call %%func_name +%endmacro + +; Declares function decorated by appropriate CPU prefix (for the merged library) +; Default visibility (if not defined) is PUBLIC. +%macro IPPASM 1-2.nolist PUBLIC + %xdefine %%func_name %1 + %xdefine %%visibility %2 + + %ifctx _IPPASM_CTX_ + %fatal "IPPASM: already in the context, need to call ENDFUNC" + %endif + %push _IPPASM_CTX_ + + %push _CPU_PREFIX_DECORATE_CTX_ + CPU_PREFIX_DECORATE %%func_name + %xdefine %%func_name %$decorated_func_name + %assign %$$decoration_length %$decoration_length + %pop _CPU_PREFIX_DECORATE_CTX_ + + DECLARE_FUNC %%func_name, %%visibility +%endmacro + +; Calls assembler function declared by IPPASM +; Default visibility is PRIVATE (affects decoration) +%macro CALL_IPPASM 1-2.nolist PRIVATE + %xdefine %%func_name %1 + %xdefine %%visibility %2 + + ; Accepted visibility values are PUBLIC and PRIVATE + %ifnidni %%visibility, PUBLIC + %ifnidni %%visibility, PRIVATE + %fatal Function %%func_name visibility is not properly defined. Shall be: PRIVATE or PUBLIC. + %endif + %endif + + %push _CPU_PREFIX_DECORATE_CTX_ + CPU_PREFIX_DECORATE %%func_name + %xdefine %%func_name %$decorated_func_name + %pop _CPU_PREFIX_DECORATE_CTX_ + + CALL_FUNC %%func_name,%%visibility +%endmacro + +; End function macro - required to be called after IPPASM or DECLARE_FUNC macro invokation. +%macro ENDFUNC 1.nolist + %xdefine %%func_name %1 + %ifnctx _DECLARE_FUNC_CTX_ + %fatal "Not in the context: _DECLARE_FUNC_CTX_" + %endif + + ; Cross-check of context variable with macro parameter + %defstr %%func_name_str %%func_name + %defstr %%func_name_ctx_str %$func_name_ctx + %substr %%func_name_ctx_str_not_decorated %%func_name_ctx_str %[%$decoration_length+1],-1 ; remove decoration (first X symbols) + %ifnidn %%func_name_str,%%func_name_ctx_str + %ifnidn %%func_name_str,%%func_name_ctx_str_not_decorated + %fatal ENDFUNC: function name [%%func_name] does match context: [%$func_name_ctx] + %endif + %endif + + ; Add local label to be able calculate function size + ; Take function name from the context (real declaration name) +.LEnd_%+%$func_name_ctx: + %pop _DECLARE_FUNC_CTX_ + + %ifctx _IPPASM_CTX_ + %pop _IPPASM_CTX_ + %endif +%endmacro + +%endif diff --git a/plugin/ippcp/library/src/sources/include/ia_emm.inc b/plugin/ippcp/library/src/sources/include/ia_emm.inc new file mode 100644 index 000000000..1136c920b --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/ia_emm.inc @@ -0,0 +1,116 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_common.inc" +%include "utils.inc" + +; Decorates function name with appropriate CPU prefix (for the merged library). +; The macro is context-dependent and returns decorated name in the %$decorated_func_name +; context variable. +%macro CPU_PREFIX_DECORATE 1.nolist + %ifnctx _CPU_PREFIX_DECORATE_CTX_ + %fatal "Not in the context: _CPU_PREFIX_DECORATE_CTX_" + %endif + + ; Add CPU-specific suffix for the dispatched library + %ifdef _OWN_MERGED_BLD + %if (_IPP == _IPP_PX) + %xdefine %%func_name px_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP == _IPP_W7) + %xdefine %%func_name w7_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP == _IPP_V8) + %xdefine %%func_name v8_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP == _IPP_S8) + %xdefine %%func_name s8_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP == _IPP_P8) + %xdefine %%func_name p8_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP == _IPP_G9) + %xdefine %%func_name g9_%1 + %assign %%decoration_length 3 + %endif + %if (_IPP == _IPP_H9) + %xdefine %%func_name h9_%1 + %assign %%decoration_length 3 + %endif + %else + %xdefine %%func_name %1 + %assign %%decoration_length 0 + %endif + + %ifndef %%func_name + %fatal "CPU_PREFIX_DECORATE: unknown decoration for: _IPP = " _IPP + %endif + %xdefine %$decorated_func_name %[%%func_name] + %assign %$decoration_length %%decoration_length +%endmacro + +%define NONVOLATILE_REGS_32_GPR ebp,ebx,esi,edi + +; Saves non-volatile GPR registers on stack. +; Input - list of used registers. +%macro USES_GPR 1+.nolist + %assign LOCAL_FRAME 0 + %assign GPR_FRAME 0 + %define GPR_CUR + + BEGIN_INTERSECT + INTERSECT {%1},{%[NONVOLATILE_REGS_32_GPR]} + ; List of non-volatile GPR registers in the order they will be pushed on stack + %xdefine GPR_CUR %$intersection + %assign GPR_FRAME %$cardinality * 4 + END_INTERSECT + + ; Push non-volatile GPRs on stack + FOREACH GPR_CUR,{push} + + ; Set up offset of arguments from ESP + %assign ARG_1 %[GPR_FRAME + 4] +%endmacro + +; Restore preliminary saved by USES_GPR non-volatile GPR registers from the stack. +; The macro shall be called after function processing. +%macro REST_GPR 0.nolist + %ifndef GPR_CUR + %fatal "REST_GPR: no GPR_CUR defined" + %endif + ; Pop saved GPRs from the stack + RFOREACH GPR_CUR,{pop} +%endmacro + +%macro LD_ADDR 2.nolist + %xdefine %%reg %1 + %xdefine %%addr %2 + +%ifdef IPP_PIC + call %%LABEL +%%LABEL: pop %%reg + sub %%reg, %%LABEL-%%addr +%else + lea %%reg, [%%addr] +%endif +%endmacro diff --git a/plugin/ippcp/library/src/sources/include/ippres.gen b/plugin/ippcp/library/src/sources/include/ippres.gen new file mode 100644 index 000000000..4e827e5dc --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/ippres.gen @@ -0,0 +1,159 @@ +/******************************************************************************* +* Copyright (C) 1999 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include "winres.h" + +#define STR2(x) #x +#define STR(x) STR2(x) + +#ifndef _IPP_VERSION +#define _IPP_VERSION "" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION() + PRODUCTVERSION VERSION() + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Intel Corporation.\0" + VALUE "FileVersion", STR( VERSION() ) "\0" + VALUE "ProductName", IPP_LIB_SHORTNAME() ". Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ".\0" + VALUE "ProductVersion", STR_VERSION() "\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2021, Intel Corporation. All rights reserved.\0" + + #if defined(_MERGED_BLD) + #if defined (WIN32) && !defined (_WIN64) && !defined (WIN32E) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ".\0" + VALUE "FileDescription", IPP_LIB_PREFIX() _IPP_VERSION ".dll is the ia32 " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() _IPP_VERSION ".dll\0" + #endif + + #if defined(WIN32E) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ".\0" + VALUE "FileDescription", IPP_LIB_PREFIX() _IPP_VERSION ".dll is the intel64 " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() _IPP_VERSION ".dll\0" + #endif + + #else + #if defined (_PX) && defined (WIN32) && !defined (_WIN64) && !defined (WIN32E) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". For Intel(R) Pentium(R) processors\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "px" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "px" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "px" _IPP_VERSION ".dll\0" + #endif + #if defined(_PX) && defined(WIN32E) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". For Intel(R) 64 Instruction Set Architecture (ISA) processors\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "mx" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "mx" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "mx" _IPP_VERSION ".dll\0" + #endif + #if defined(_W7) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with Streaming SIMD Extensions 2 (SSE2)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "w7" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "w7" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "w7" _IPP_VERSION ".dll\0" + #endif + #if defined(_P8) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with Streaming SIMD Extensions 4.2 (SSE4.2)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "p8" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "p8" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "p8" _IPP_VERSION ".dll\0" + #endif + #if defined(_G9) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with Advanced Vector Extensions (AVX)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "g9" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "g9" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "g9" _IPP_VERSION ".dll\0" + #endif + #if defined(_H9) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with Advanced Vector Extensions 2 (AVX2)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "h9" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "h9" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "h9" _IPP_VERSION ".dll\0" + #endif + #if defined(_M7) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for Intel(R) 64 Instruction Set Architecture (ISA)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "m7" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "m7" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "m7" _IPP_VERSION ".dll\0" + #endif + #if defined(_Y8) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with Streaming SIMD Extensions 4.2 (SSE4.2)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "y8" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "y8" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "y8" _IPP_VERSION ".dll\0" + #endif + #if defined(_E9) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with Advanced Vector Extensions (AVX)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "e9" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "e9" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "e9" _IPP_VERSION ".dll\0" + #endif + #if defined(_L9) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with Advanced Vector Extensions 2 (AVX2)\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "l9" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "l9" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "l9" _IPP_VERSION ".dll\0" + #endif + #if defined(_K0) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with AVX512F/CD/BW/DQ/VL support\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "k0" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "k0" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "k0" _IPP_VERSION ".dll\0" + #endif + #if defined(_N0) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for processors with AVX512F/CD/ER/PF support\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "n0" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "n0" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "n0" _IPP_VERSION ".dll\0" + #endif + #if defined(_S8) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for Intel(R) Atom(TM) processor\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "s8" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "s8" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "s8" _IPP_VERSION ".dll\0" + #endif + #if defined(_N8) + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " IPP_LIB_LONGNAME() ". Optimized for Intel(R) Atom(TM) processor\0" + VALUE "FileDescription", IPP_LIB_PREFIX() "n8" _IPP_VERSION ".dll is an " IPP_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", IPP_LIB_PREFIX() "n8" _IPP_VERSION ".dll\0" + VALUE "OriginalFilename", IPP_LIB_PREFIX() "n8" _IPP_VERSION ".dll\0" + #endif + #endif + + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/plugin/ippcp/library/src/sources/include/ippver.h b/plugin/ippcp/library/src/sources/include/ippver.h new file mode 100644 index 000000000..fe9ec9be6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/ippver.h @@ -0,0 +1,43 @@ +/******************************************************************************* +* Copyright (C) 2001 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +// Purpose: Describes the base Intel IPP Cryptography version +// +*/ + + +#include "ippversion.h" +#ifndef BASE_VERSION +#define BASE_VERSION() IPP_VERSION_MAJOR,IPP_VERSION_MINOR,IPP_VERSION_UPDATE +#endif + +#define STR2(x) #x +#define STR(x) STR2(x) + +#ifndef STR_VERSION + #ifdef IPP_REVISION + #define STR_VERSION() IPP_VERSION_STR " (r" STR( IPP_REVISION ) ")" + #else + #define STR_VERSION() IPP_VERSION_STR " (-)" + #endif +#endif + + +/* ////////////////////////////// End of file /////////////////////////////// */ diff --git a/plugin/ippcp/library/src/sources/include/owndefs.h b/plugin/ippcp/library/src/sources/include/owndefs.h new file mode 100644 index 000000000..dcc1ede25 --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/owndefs.h @@ -0,0 +1,658 @@ +/******************************************************************************* +* Copyright (C) 1999 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +// Purpose: +// Internal definitions +// +// + +#ifndef __OWNDEFS_H__ +#define __OWNDEFS_H__ + +#if defined( _VXWORKS ) + #include + #undef NONE +#endif + +#ifndef IPPCPDEFS_H__ + #include "ippcpdefs.h" +#endif + +#if !defined(__INLINE) +#if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) || defined(_MSC_VER) + #define __INLINE static __inline +#elif defined( __GNUC__ ) + #define __INLINE static __inline__ +#else + #define __INLINE static +#endif +#endif /*__INLINE*/ + +/* TODO: to check ICX compiler */ +#if !defined(__NOINLINE) +#if defined(__INTEL_COMPILER) || defined(_MSC_VER) + #define __NOINLINE __declspec(noinline) +#elif defined( __GNUC__ ) + #define __NOINLINE __attribute__((noinline)) +#else + #define __NOINLINE +#endif +#endif /*__NOINLINE*/ + +#if !defined(__FORCEINLINE) +#if defined(_MSC_VER) + #define __FORCEINLINE __forceinline +#elif defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) || defined( __GNUC__ ) + #define __FORCEINLINE __INLINE __attribute__((always_inline)) +#else + #define __FORCEINLINE +#endif +#endif /*__FORCEINLINE*/ + +#if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) + #define __RESTRICT restrict +#elif !defined( __RESTRICT ) + #define __RESTRICT +#endif + +#if defined( IPP_W32DLL ) + #if defined( _MSC_VER ) || defined( __INTEL_COMPILER ) || defined(__INTEL_LLVM_COMPILER) + #define IPPDEF(type) __declspec(dllexport) type + #else + #define IPPDEF(type) type + #endif +#else + #define IPPDEF(type) type +#endif + +/* ia32 */ +#define _IPP_PX 0 /* pure C-code */ +#define _IPP_M5 1 /* Intel® Quark(TM) processor */ +#define _IPP_W7 8 /* Intel® Streaming SIMD Extensions 2 (Intel® SSE2) */ +#define _IPP_T7 16 /* Intel® Streaming SIMD Extensions 3 (Intel® SSE3) */ +#define _IPP_V8 32 /* Supplemental Streaming SIMD Extensions 3 (SSSE3) */ +#define _IPP_S8 33 /* Supplemental Streaming SIMD Extensions 3 (SSSE3) + MOVBE instruction */ +#define _IPP_P8 64 /* Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) */ +#define _IPP_G9 128 /* Intel® Advanced Vector Extensions (Intel® AVX) */ +#define _IPP_H9 256 /* Intel® Advanced Vector Extensions 2 (Intel® AVX2) */ +#define _IPP_I0 512 /* Intel® Advanced Vector Extensions 512 (Intel® AVX512) - Intel® Xeon® Phi(TM) Processor (formerly Knights Landing) */ +#define _IPP_S0 1024 /* Intel® Advanced Vector Extensions 512 (Intel® AVX512) - Intel® Xeon® Processor (formerly codenamed Skylake) */ + +/* intel64 */ +#define _IPP32E_PX _IPP_PX /* pure C-code */ +#define _IPP32E_M7 32 /* Intel® Streaming SIMD Extensions 3 (Intel® SSE3) */ +#define _IPP32E_U8 64 /* Supplemental Streaming SIMD Extensions 3 (SSSE3) */ +#define _IPP32E_N8 65 /* Supplemental Streaming SIMD Extensions 3 (SSSE3) + MOVBE instruction */ +#define _IPP32E_Y8 128 /* Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) */ +#define _IPP32E_E9 256 /* Intel® Advanced Vector Extensions (Intel® AVX) */ +#define _IPP32E_L9 512 /* Intel® Advanced Vector Extensions 2 (Intel® AVX2) */ +#define _IPP32E_N0 1024 /* Intel® Advanced Vector Extensions 512 (Intel® AVX512) - Intel® Xeon® Phi(TM) Processor (formerly Knights Landing) */ +#define _IPP32E_K0 2048 /* Intel® Advanced Vector Extensions 512 (Intel® AVX512) - Intel® Xeon® Processor (formerly codenamed Skylake) */ +#define _IPP32E_K1 4096 /* Intel® Advanced Vector Extensions 512 (Intel® AVX512) - Intel® Xeon® Processor (formerly codenamed Icelake) */ + + +#if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) || (_MSC_VER >= 1300) + #define __ALIGN8 __declspec (align(8)) + #define __ALIGN16 __declspec (align(16)) + #define __ALIGN32 __declspec (align(32)) + #if !defined(__ALIGN64) + #define __ALIGN64 __declspec (align(64)) + #endif/*__ALIGN64*/ +#elif defined(__GNUC__) || defined(__CLANG__) + #define __ALIGN8 __attribute__((aligned(8))) + #define __ALIGN16 __attribute__((aligned(16))) + #define __ALIGN32 __attribute__((aligned(32))) + #if !defined(__ALIGN64) + #define __ALIGN64 __attribute__((aligned(64))) + #endif/*__ALIGN64*/ +#else + #error Intel, MS or GNU C compiler required +#endif + +/* ia32 */ +#if defined ( _M5 ) /* Intel® Quark(TM) processor */ + #define _IPP _IPP_M5 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) m5_##name + +#elif defined( _W7 ) /* Intel® SSE2 */ + #define _IPP _IPP_W7 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) w7_##name + +#elif defined( _T7 ) /* Intel® SSE3 */ + #define _IPP _IPP_T7 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) t7_##name + +#elif defined( _V8 ) /* SSSE3 */ + #define _IPP _IPP_V8 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) v8_##name + +#elif defined( _S8 ) /* SSSE3 + MOVBE instruction */ + #define _IPP _IPP_S8 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) s8_##name + +#elif defined( _P8 ) /* Intel® SSE4.2 */ + #define _IPP _IPP_P8 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) p8_##name + +#elif defined( _G9 ) /* Intel® AVX */ + #define _IPP _IPP_G9 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) g9_##name + +#elif defined( _H9 ) /* Intel® AVX2 */ + #define _IPP _IPP_H9 + #define _IPP32E _IPP32E_PX + #define OWNAPI(name) h9_##name + +/* intel64 */ +#elif defined( _M7 ) /* Intel® SSE3 */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_M7 + #define OWNAPI(name) m7_##name + +#elif defined( _U8 ) /* SSSE3 */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_U8 + #define OWNAPI(name) u8_##name + +#elif defined( _N8 ) /* SSSE3 + MOVBE instruction */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_N8 + #define OWNAPI(name) n8_##name + +#elif defined( _Y8 ) /* Intel® SSE4.2 */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_Y8 + #define OWNAPI(name) y8_##name + +#elif defined( _E9 ) /* Intel® AVX */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_E9 + #define OWNAPI(name) e9_##name + +#elif defined( _L9 ) /* Intel® AVX2 */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_L9 + #define OWNAPI(name) l9_##name + +#elif defined( _N0 ) /* Intel® AVX512 - formerly Knights Landing */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_N0 + #define OWNAPI(name) n0_##name + +#elif defined( _K0 ) /* Intel® AVX512 - formerly codenamed Skylake */ + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_K0 + #define OWNAPI(name) k0_##name + +#elif defined( _K1 ) /* Intel® AVX512 - formerly codenamed Icelake */ +#define _IPP _IPP_PX +#define _IPP32E _IPP32E_K1 +#define OWNAPI(name) k1_##name + +#else + #define _IPP _IPP_PX + #define _IPP32E _IPP32E_PX + #if defined (_M_AMD64) || defined (__x86_64__) || defined ( _ARCH_EM64T ) + #define OWNAPI(name) mx_##name + #else + #define OWNAPI(name) px_##name + #endif +#endif + +#if defined(_MERGED_BLD) +#define _OWN_MERGED_BLD +#endif + +#ifndef _OWN_MERGED_BLD + #undef OWNAPI + #define OWNAPI(name) name +#endif + +/* Force __cdecl calling convention for internal functions declarations */ +#define IPP_OWN_DECL(type,name,param) type IPP_CDECL name param ; +#define IPP_OWN_DEFN(type,name,param) type IPP_CDECL name param +#define IPP_OWN_FUNPTR(type,name,param) typedef type (IPP_CDECL *name) param ; + +#if defined( IPP_W32DLL ) + #if defined( _MSC_VER ) || defined( __INTEL_COMPILER ) || defined(__INTEL_LLVM_COMPILER) + #define IPPFUN(type,name,arg) __declspec(dllexport) type IPP_CALL name arg + #else + #define IPPFUN(type,name,arg) extern type IPP_CALL name arg + #endif +#else + #if defined(LINUX32E) && !defined(IPP_PIC) + #define IPPFUN(type,name,arg) __attribute__((force_align_arg_pointer)) extern type IPP_CALL name arg + #else + #define IPPFUN(type,name,arg) extern type IPP_CALL name arg + #endif +#endif + +#define _IPP_ARCH_IA32 1 +#define _IPP_ARCH_EM64T 4 +#define _IPP_ARCH_LRB 16 +#define _IPP_ARCH_LRB2 128 +#define _IPP_ARCH_LP64 0 + +#if defined ( _ARCH_IA32 ) + #define _IPP_ARCH _IPP_ARCH_IA32 + +#elif defined( _ARCH_EM64T ) + #define _IPP_ARCH _IPP_ARCH_EM64T + +#else + #if defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) + #define _IPP_ARCH _IPP_ARCH_EM64T + + #else + #define _IPP_ARCH _IPP_ARCH_IA32 + + #endif +#endif + +#if ((_IPP_ARCH == _IPP_ARCH_IA32)) +__INLINE Ipp32s IPP_INT_PTR ( const void* ptr ) +{ + union { + void* Ptr; + Ipp32s Int; + } dd; + dd.Ptr = (void*)ptr; + return dd.Int; +} + +__INLINE Ipp32u IPP_UINT_PTR( const void* ptr ) +{ + union { + void* Ptr; + Ipp32u Int; + } dd; + dd.Ptr = (void*)ptr; + return dd.Int; +} +#elif ((_IPP_ARCH == _IPP_ARCH_EM64T) || (_IPP_ARCH == _IPP_ARCH_LRB2)) +__INLINE Ipp64s IPP_INT_PTR( const void* ptr ) +{ + union { + void* Ptr; + Ipp64s Int; + } dd; + dd.Ptr = (void*)ptr; + return dd.Int; +} + +__INLINE Ipp64u IPP_UINT_PTR( const void* ptr ) +{ + union { + void* Ptr; + Ipp64u Int; + } dd; + dd.Ptr = (void*)ptr; + return dd.Int; +} +#else + #define IPP_INT_PTR( ptr ) ( (long)(ptr) ) + #define IPP_UINT_PTR( ptr ) ( (unsigned long)(ptr) ) +#endif + +#define IPP_ALIGN_TYPE(type, align) ((align)/sizeof(type)-1) +#define IPP_BYTES_TO_ALIGN(ptr, align) ((~(IPP_INT_PTR(ptr)&((align)-1))+1)&((align)-1)) +#define IPP_ALIGNED_PTR(ptr, align) (void*)( (unsigned char*)(ptr) + (IPP_BYTES_TO_ALIGN( ptr, align )) ) + +#define IPP_ALIGNED_SIZE(size, align) (((size)+(align)-1)&~((align)-1)) + +#define IPP_MALLOC_ALIGNED_BYTES 64 +#define IPP_MALLOC_ALIGNED_8BYTES 8 +#define IPP_MALLOC_ALIGNED_16BYTES 16 +#define IPP_MALLOC_ALIGNED_32BYTES 32 + +#define IPP_ALIGNED_ARRAY(align,arrtype,arrname,arrlength)\ + char arrname##AlignedArrBuff[sizeof(arrtype)*(arrlength)+IPP_ALIGN_TYPE(char, align)];\ + arrtype *arrname = (arrtype*)IPP_ALIGNED_PTR(arrname##AlignedArrBuff,align) + +#if defined( __cplusplus ) +extern "C" { +#endif + +/* ///////////////////////////////////////////////////////////////////////////// + + Intel IPP Cryptography Context Identification + + /////////////////////////////////////////////////////////////////////////// */ + +#define IPP_CONTEXT( a, b, c, d) \ + (int)(((unsigned)(a) << 24) | ((unsigned)(b) << 16) | \ + ((unsigned)(c) << 8) | (unsigned)(d)) + +typedef enum { + idCtxUnknown = 0, + idCtxDES = IPP_CONTEXT( ' ', 'D', 'E', 'S'), + idCtxRijndael = IPP_CONTEXT( ' ', 'R', 'I', 'J'), + idCtxSMS4 = IPP_CONTEXT( 'S', 'M', 'S', '4'), + idCtxARCFOUR = IPP_CONTEXT( ' ', 'R', 'C', '4'), + idCtxSHA1 = IPP_CONTEXT( 'S', 'H', 'S', '1'), + idCtxSHA224 = IPP_CONTEXT( 'S', 'H', 'S', '3'), + idCtxSHA256 = IPP_CONTEXT( 'S', 'H', 'S', '2'), + idCtxSHA384 = IPP_CONTEXT( 'S', 'H', 'S', '4'), + idCtxSHA512 = IPP_CONTEXT( 'S', 'H', 'S', '5'), + idCtxMD5 = IPP_CONTEXT( ' ', 'M', 'D', '5'), + idCtxHMAC = IPP_CONTEXT( 'H', 'M', 'A', 'C'), + idCtxBigNum = IPP_CONTEXT( 'B', 'I', 'G', 'N'), + idCtxMontgomery = IPP_CONTEXT( 'M', 'O', 'N', 'T'), + idCtxPrimeNumber = IPP_CONTEXT( 'P', 'R', 'I', 'M'), + idCtxPRNG = IPP_CONTEXT( 'P', 'R', 'N', 'G'), + idCtxRSA = IPP_CONTEXT( ' ', 'R', 'S', 'A'), + idCtxRSA_PubKey = IPP_CONTEXT( 'R', 'S', 'A', '0'), + idCtxRSA_PrvKey1 = IPP_CONTEXT( 'R', 'S', 'A', '1'), + idCtxRSA_PrvKey2 = IPP_CONTEXT( 'R', 'S', 'A', '2'), + idCtxDSA = IPP_CONTEXT( ' ', 'D', 'S', 'A'), + idCtxECCP = IPP_CONTEXT( ' ', 'E', 'C', 'P'), + idCtxECCB = IPP_CONTEXT( ' ', 'E', 'C', 'B'), + idCtxECCPPoint = IPP_CONTEXT( 'P', 'E', 'C', 'P'), + idCtxECCBPoint = IPP_CONTEXT( 'P', 'E', 'C', 'B'), + idCtxDH = IPP_CONTEXT( ' ', ' ', 'D', 'H'), + idCtxDLP = IPP_CONTEXT( ' ', 'D', 'L', 'P'), + idCtxCMAC = IPP_CONTEXT( 'C', 'M', 'A', 'C'), + idCtxAESXCBC, + idCtxAESCCM, + idCtxAESGCM, + idCtxGFP, + idCtxGFPE, + idCtxGFPX, + idCtxGFPXE, + idCtxGFPXQX, + idCtxGFPXQXE, + idCtxGFPEC, + idCtxGFPPoint, + idCtxGFPXEC, + idCtxGFPXECPoint, + idCtxHash, + idCtxSM3, + idCtxAESXTS, + idxCtxECES_SM2, + idCtxGFPECKE +} IppCtxId; + + + + +/* ///////////////////////////////////////////////////////////////////////////// + Helpers + /////////////////////////////////////////////////////////////////////////// */ + +#define IPP_NOERROR_RET() return ippStsNoErr +#define IPP_ERROR_RET( ErrCode ) return (ErrCode) + +#define IPP_BADARG_RET( expr, ErrCode )\ + {if (expr) { IPP_ERROR_RET( ErrCode ); }} + +#define IPP_BAD_SIZE_RET( n )\ + IPP_BADARG_RET( (n)<=0, ippStsSizeErr ) + +#define IPP_BAD_STEP_RET( n )\ + IPP_BADARG_RET( (n)<=0, ippStsStepErr ) + +#define IPP_BAD_PTR1_RET( ptr )\ + IPP_BADARG_RET( NULL==(ptr), ippStsNullPtrErr ) + +#define IPP_BAD_PTR2_RET( ptr1, ptr2 )\ + {IPP_BAD_PTR1_RET( ptr1 ); IPP_BAD_PTR1_RET( ptr2 )} + +#define IPP_BAD_PTR3_RET( ptr1, ptr2, ptr3 )\ + {IPP_BAD_PTR2_RET( ptr1, ptr2 ); IPP_BAD_PTR1_RET( ptr3 )} + +#define IPP_BAD_PTR4_RET( ptr1, ptr2, ptr3, ptr4 )\ + {IPP_BAD_PTR2_RET( ptr1, ptr2 ); IPP_BAD_PTR2_RET( ptr3, ptr4 )} + +#define IPP_BAD_ISIZE_RET(roi) \ + IPP_BADARG_RET( ((roi).width<=0 || (roi).height<=0), ippStsSizeErr) + +/* ////////////////////////////////////////////////////////////////////////// */ +/* internal messages */ + +#define MSG_LOAD_DLL_ERR (-9700) /* Error at loading of %s library */ +#define MSG_NO_DLL (-9701) /* No DLLs were found in the Waterfall procedure */ +#define MSG_NO_SHARED (-9702) /* No shared libraries were found in the Waterfall procedure */ + +/* ////////////////////////////////////////////////////////////////////////// */ + + +typedef union { /* double precision */ + Ipp64s hex; + Ipp64f fp; +} IppFP_64f; + +typedef union { /* single precision */ + Ipp32s hex; + Ipp32f fp; +} IppFP_32f; + + +/* ////////////////////////////////////////////////////////////////////////// */ + +/* Define NULL pointer value */ +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +#define IPP_UNREFERENCED_PARAMETER(p) (void)(p) + +#if defined( _IPP_MARK_LIBRARY ) +static char G[] = {73, 80, 80, 71, 101, 110, 117, 105, 110, 101, 243, 193, 210, 207, 215}; +#endif + + +/* +// endian definition +*/ +#define IPP_LITTLE_ENDIAN (0) +#define IPP_BIG_ENDIAN (1) + +#if defined( _IPP_LE ) + #define IPP_ENDIAN IPP_LITTLE_ENDIAN + +#elif defined( _IPP_BE ) + #define IPP_ENDIAN IPP_BIG_ENDIAN + +#else + #if defined( __ARMEB__ ) + #define IPP_ENDIAN IPP_BIG_ENDIAN + + #else + #define IPP_ENDIAN IPP_LITTLE_ENDIAN + + #endif +#endif + + +/* ////////////////////////////////////////////////////////////////////////// */ + +/* intrinsics */ +#if (_IPP >= _IPP_W7) || (_IPP32E >= _IPP32E_M7) + #if defined(__INTEL_COMPILER) || (_MSC_VER >= 1300) + #if (_IPP == _IPP_W7) + #if defined(__INTEL_COMPILER) + #include "emmintrin.h" + #else + #undef _W7 + #include "emmintrin.h" + #define _W7 + #endif + #define _mm_loadu _mm_loadu_si128 + #elif (_IPP32E == _IPP32E_M7) + #if defined(__INTEL_COMPILER) + #include "pmmintrin.h" + #define _mm_loadu _mm_lddqu_si128 + #elif (_MSC_FULL_VER >= 140050110) + #include "intrin.h" + #define _mm_loadu _mm_lddqu_si128 + #elif (_MSC_FULL_VER < 140050110) + #include "emmintrin.h" + #define _mm_loadu _mm_loadu_si128 + #endif + #elif ((_IPP == _IPP_V8) || (_IPP32E == _IPP32E_U8) || (_IPP == _IPP_S8) || (_IPP32E == _IPP32E_N8)) + #if defined(__INTEL_COMPILER) + #include "tmmintrin.h" + #define _mm_loadu _mm_lddqu_si128 + #elif (_MSC_FULL_VER >= 140050110) + #include "intrin.h" + #define _mm_loadu _mm_lddqu_si128 + #elif (_MSC_FULL_VER < 140050110) + #include "emmintrin.h" + #define _mm_loadu _mm_loadu_si128 + #endif + #elif (_IPP == _IPP_P8) || (_IPP32E == _IPP32E_Y8) + #if defined(__INTEL_COMPILER) + #include "smmintrin.h" + #define _mm_loadu _mm_lddqu_si128 + #elif (_MSC_FULL_VER >= 140050110) + #include "intrin.h" + #define _mm_loadu _mm_lddqu_si128 + #elif (_MSC_FULL_VER < 140050110) + #include "emmintrin.h" + #define _mm_loadu _mm_loadu_si128 + #endif + #elif (_IPP >= _IPP_G9) || (_IPP32E >= _IPP32E_E9) + #if defined(__INTEL_COMPILER) + #include "immintrin.h" + #define _mm_loadu _mm_lddqu_si128 + #elif (_MSC_FULL_VER >= 160021003) + #include "immintrin.h" + #define _mm_loadu _mm_lddqu_si128 + #endif + #endif + #endif + #if defined(__GNUC__) && !defined(__INTEL_COMPILER) + #include "x86intrin.h" + #endif +#endif + +// **** intrinsics for bit casting **** +#if defined(__INTEL_COMPILER) +extern unsigned int __intel_castf32_u32(float val); +extern float __intel_castu32_f32(unsigned int val); +extern unsigned __int64 __intel_castf64_u64(double val); +extern double __intel_castu64_f64(unsigned __int64 val); + #define __CAST_32f32u(val) __intel_castf32_u32((Ipp32f)val) + #define __CAST_32u32f(val) __intel_castu32_f32((Ipp32u)val) + #define __CAST_64f64u(val) __intel_castf64_u64((Ipp64f)val) + #define __CAST_64u64f(val) __intel_castu64_f64((Ipp64u)val) +#else + #define __CAST_32f32u(val) ( *((Ipp32u*)&val) ) + #define __CAST_32u32f(val) ( *((Ipp32f*)&val) ) + #define __CAST_64f64u(val) ( *((Ipp64u*)&val) ) + #define __CAST_64u64f(val) ( *((Ipp64f*)&val) ) +#endif + + +// short names for vector registers casting +#define _pd2ps _mm_castpd_ps +#define _ps2pd _mm_castps_pd +#define _pd2pi _mm_castpd_si128 +#define _pi2pd _mm_castsi128_pd +#define _ps2pi _mm_castps_si128 +#define _pi2ps _mm_castsi128_ps + +#define _ypd2ypi _mm256_castpd_si256 +#define _ypi2ypd _mm256_castsi256_pd +#define _yps2ypi _mm256_castps_si256 +#define _ypi2yps _mm256_castsi256_ps +#define _ypd2yps _mm256_castpd_ps +#define _yps2ypd _mm256_castps_pd + +#define _yps2ps _mm256_castps256_ps128 +#define _ypi2pi _mm256_castsi256_si128 +#define _ypd2pd _mm256_castpd256_pd128 +#define _ps2yps _mm256_castps128_ps256 +#define _pi2ypi _mm256_castsi128_si256 +#define _pd2ypd _mm256_castpd128_pd256 + +#define _zpd2zpi _mm512_castpd_si512 +#define _zpi2zpd _mm512_castsi512_pd +#define _zps2zpi _mm512_castps_si512 +#define _zpi2zps _mm512_castsi512_ps +#define _zpd2zps _mm512_castpd_ps +#define _zps2zpd _mm512_castps_pd + +#define _zps2ps _mm512_castps512_ps128 +#define _zpi2pi _mm512_castsi512_si128 +#define _zpd2pd _mm512_castpd512_pd128 +#define _ps2zps _mm512_castps128_ps512 +#define _pi2zpi _mm512_castsi128_si512 +#define _pd2zpd _mm512_castpd128_pd512 + +#define _zps2yps _mm512_castps512_ps256 +#define _zpi2ypi _mm512_castsi512_si256 +#define _zpd2ypd _mm512_castpd512_pd256 +#define _yps2zps _mm512_castps256_ps512 +#define _ypi2zpi _mm512_castsi256_si512 +#define _ypd2zpd _mm512_castpd256_pd512 + + +#if defined(__INTEL_COMPILER) +#define __IVDEP ivdep +#else +#define __IVDEP message("message :: 'ivdep' is not defined") +#endif + +#if defined( _MERGED_BLD ) + #if !defined( _IPP_DYNAMIC ) + /* WIN-32, WIN-64 */ + #if defined(WIN32) || defined(WIN32E) + #if ( defined(_W7) || defined(_M7) ) + #define _IPP_DATA 1 + #endif + + #elif defined(linux) + /* LIN-32, LIN-64 */ + #if ( defined(_W7) || defined(_M7) ) + #define _IPP_DATA 1 + #endif + + + /* OSX-32, OSX-64 */ + #elif defined(OSX32) || defined(OSXEM64T) + #if ( defined(_Y8) ) + #define _IPP_DATA 1 + #endif + #endif + #endif +#else + /* compile data unconditionally */ + #define _IPP_DATA 1 +#endif + + +#if defined( __cplusplus ) +} +#endif + +#endif /* __OWNDEFS_H__ */ + diff --git a/plugin/ippcp/library/src/sources/include/utils.inc b/plugin/ippcp/library/src/sources/include/utils.inc new file mode 100644 index 000000000..d4abb92ed --- /dev/null +++ b/plugin/ippcp/library/src/sources/include/utils.inc @@ -0,0 +1,132 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef __UTILS_INC__ +%define __UTILS_INC__ 1 + +; Apply a functor provided as a last parameter to each element of the list, provided as sequence of first parameters. +; A list is processed in direct order. Note: an input list can be empty. +%macro FOREACH 2-*.nolist + %rotate -1 + %xdefine %%functor %1 + %rep %0-1 + %rotate 1 + %ifnempty %1 + %%functor %1 + %endif + %endrep +%endmacro + +; Apply a functor provided as a last parameter to each element of the list, provided as sequence of first parameters. +; A list is processed in reverse order. Note: an input list can be empty. +%macro RFOREACH 2-*.nolist + %rotate -1 + %xdefine %%functor %1 + %rep %0-1 + %rotate -1 + %ifnempty %1 + %%functor %1 + %endif + %endrep +%endmacro + +; Shall be called before INTERSECT macro to open corresponding context. +%macro BEGIN_INTERSECT 0.nolist + %push _INTERSECT_CTX_ + %xdefine %$intersection + %assign %$cardinality 0 +%endmacro + +; Shall be called after INTERSECT macro to close corresponding context. +%macro END_INTERSECT 0.nolist + %pop _INTERSECT_CTX_ +%endmacro + +; The macro searches intersection between two lists. +; Input: two comma-separated lists, enclosed in curly braces. +; Output: +; - Intersection will be located in the %$instersection context macro (can be empty). +; - Count of intersection elements list will be stored in the %$cardinality context variable. +%macro INTERSECT 2.nolist + %ifnctx _INTERSECT_CTX_ + %fatal "Not in the context: _INTERSECT_CTX_" + %endif + + %xdefine %%list1 %1 + %xdefine %%list2 %2 + + FOREACH %%list1,{?INTERSECT_BODY {%%list2},} +%endmacro + +; Helper macro to concatenate two lists. +; The result will be stored in the 3rd parameter that must be a macro identifier. +%macro CONCATENATE 3.nolist + %ifnid %3 + %fatal "CONCATENATE: 3rd parameter must be a macro identifier." + %endif + %define %3 %[%1] + %ifnempty %3 + %ifnempty %2 + %define %3 %[%3],%[%2] + %endif + %else + %define %3 %[%2] + %endif +%endmacro + +; Helper macro that searches the specified element in the input list. +; Input: +; - Last parameter - target element +; - First parameters refer to the list where the search is processed. +; Output: +; - The macro is context dependent and upon the element is found, the context macro %$elem_exists will be defined. +%macro ?FIND 2-*.nolist + %ifnctx _FIND_CTX_ + %fatal "Not in the context: _FIND_CTX_" + %endif + %rotate -1 + %xdefine %%elem_to_check %1 + %undef %$elem_exists + + %rep %0-1 + %rotate -1 + %ifidni %%elem_to_check, %1 + %define %$elem_exists %1 + %exitrep + %endif + %endrep +%endmacro + +; Macro that finds and collects intersection elements. To be used as INTERSECT macro functor. +%macro ?INTERSECT_BODY 2.nolist + %xdefine %%list %1 + %xdefine %%elem %2 + + %push _FIND_CTX_ + ?FIND %%list,%%elem + %ifdef %$elem_exists + %ifempty %$$intersection + %define %$$intersection %2 + %else + %define %$$intersection %[%$$intersection],%%elem + %endif + %assign %$$cardinality %$$cardinality + 1 + %endif + %pop _FIND_CTX_ +%endmacro + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/CMakeLists.txt b/plugin/ippcp/library/src/sources/ippcp/CMakeLists.txt new file mode 100644 index 000000000..a7f38aa5f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/CMakeLists.txt @@ -0,0 +1,595 @@ +#=============================================================================== +# Copyright (C) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# +# Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +# + +include (GenerateExportHeader) + +set(TARGET_NAME ${LIB_NAME}) + +#Set platform list +if (NOT MERGED_BLD) + if(${ARCH} MATCHES "ia32") + set(BASE_PLATFORM_LIST px) + else() + set(BASE_PLATFORM_LIST mx) + endif() +endif() +if(WIN32) + if(${ARCH} MATCHES "ia32") + set(BASE_PLATFORM_LIST ${BASE_PLATFORM_LIST} w7 s8 p8 g9 h9) + else() + set(BASE_PLATFORM_LIST ${BASE_PLATFORM_LIST} m7 n8 y8 e9 l9 k0 k1) + endif() +endif(WIN32) +if(UNIX) + if(APPLE) + set(BASE_PLATFORM_LIST ${BASE_PLATFORM_LIST} y8 e9 l9 k0 k1) + else() + if (${ARCH} MATCHES "ia32") + set(BASE_PLATFORM_LIST ${BASE_PLATFORM_LIST} w7 s8 p8 g9 h9) + else() + set(BASE_PLATFORM_LIST ${BASE_PLATFORM_LIST} m7 n8 y8 e9 l9 n0 k0 k1) + endif(${ARCH} MATCHES "ia32") + endif(APPLE) +endif(UNIX) + +if(PLATFORM_LIST) + if (NOT MERGED_BLD) + foreach(opt ${PLATFORM_LIST}) + set(FOUND_PLATFORM false) + foreach(base_opt ${BASE_PLATFORM_LIST}) + string(STRIP "${opt}" opt_strip) + if(opt_strip STREQUAL base_opt) + set(FOUND_PLATFORM true) + endif() + endforeach(base_opt ${BASE_PLATFORM_LIST}) + if(NOT FOUND_PLATFORM) + message (FATAL_ERROR "Incorrect platform: " ${opt}) + endif() + endforeach(opt ${PLATFORM_LIST}) + if (PLATFORM_LIST STREQUAL "") + message (FATAL_ERROR "PLATFORM_LIST cannot be empty") + endif(PLATFORM_LIST STREQUAL "") + message (STATUS "Platform list ......................... " ${PLATFORM_LIST}) + else() + message (FATAL_ERROR "PLATFORM_LIST cannot be set, when MERGED_BLD is on") + endif(NOT MERGED_BLD) +endif() + +# Platform-specific definitions +set(px_def "_PX") +set(w7_def "_W7") +set(s8_def "_S8") +set(p8_def "_P8") +set(g9_def "_G9") +set(h9_def "_H9") +set(mx_def "_PX") +set(m7_def "_M7") +set(n8_def "_N8") +set(y8_def "_Y8") +set(e9_def "_E9") +set(l9_def "_L9") +set(n0_def "_N0") +set(k0_def "_K0") +set(k1_def "_K1") + +if(NOT PLATFORM_LIST) + set(PLATFORM_LIST ${BASE_PLATFORM_LIST}) +endif() + +if (NOT MERGED_BLD) + set(PLATFORM_LIST ${PLATFORM_LIST} PARENT_SCOPE) +endif(NOT MERGED_BLD) + +# define defaults for every supported compiler +set(DEFAULT_Intel_COMPILER_VER 19.0.0) +set(DEFAULT_MSVC_COMPILER_VER 19.14) +set(DEFAULT_GNU_COMPILER_VER 8.2.0) +set(DEFAULT_APPLE_CLANG_COMPILER_VER 12.0.0) +set(DEFAULT_Clang_COMPILER_VER 9.0.0) + +set(DEFAULT_Intel18_COMPILER_VER 18.0.0) +set(DEFAULT_Intel19_COMPILER_VER 19.0.0) +set(DEFAULT_MSVC19_COMPILER_VER 19.14) +set(DEFAULT_IntelLLVM2023_COMPILER_VER 2023.1.0) + +string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+).*$" "\\1.\\2.\\3" CMAKE_C_COMPILER_VERSION_SHORT ${CMAKE_C_COMPILER_VERSION}) +string(REGEX REPLACE "^([0-9]+)\\..*$" "\\1" CMAKE_C_COMPILER_VERSION_MAJOR ${CMAKE_C_COMPILER_VERSION}) + +if(UNIX) + if(APPLE) + set(OS_STRING "macosx") + else() + set(OS_STRING "linux") + endif() +else() + set(OS_STRING "windows") +endif() + +# common build options and ${OS_DEFAULT_COMPILER} +include("${IPP_CRYPTO_DIR}/sources/cmake/${OS_STRING}/common.cmake") +include("${IPP_CRYPTO_DIR}/sources/cmake/os_common.cmake") + +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") AND (CMAKE_C_COMPILER_VERSION VERSION_LESS DEFAULT_MSVC_COMPILER_VER)) + message(FATAL_ERROR "Microsoft Visual C++ Compiler version must be 19.14 or higher (MSVC 19.14 or higher)") +endif() + +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") AND (CMAKE_C_COMPILER_VERSION VERSION_LESS DEFAULT_GNU_COMPILER_VER)) + message(FATAL_ERROR "GNU C Compiler version must be 8.2 or higher") +endif() + +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") AND (CMAKE_C_COMPILER_VERSION VERSION_LESS DEFAULT_APPLE_CLANG_COMPILER_VER)) + message(FATAL_ERROR "Apple Clang C Compiler version must be 12.0 or higher") +endif() + +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") AND (CMAKE_C_COMPILER_VERSION VERSION_LESS DEFAULT_CLANG_COMPILER_VER)) + message(FATAL_ERROR "Clang C Compiler version must be 9.0 or higher") +endif() + +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")) + set(CLANG_COMPILER ON) + set(CLANG_COMPILER ${CLANG_COMPILER} PARENT_SCOPE) +endif() + +# Compiler options file +set(COMPILER_OPTIONS_FILE "${IPP_CRYPTO_DIR}/sources/cmake/${OS_STRING}") +if (EXISTS "${COMPILER_OPTIONS_FILE}/${CMAKE_C_COMPILER_ID}${CMAKE_C_COMPILER_VERSION_SHORT}.cmake") + set(COMPILER_OPTIONS_FILE "${COMPILER_OPTIONS_FILE}/${CMAKE_C_COMPILER_ID}${CMAKE_C_COMPILER_VERSION_SHORT}.cmake") +else() + if ("${DEFAULT_${CMAKE_C_COMPILER_ID}${CMAKE_C_COMPILER_VERSION_MAJOR}_COMPILER_VER}" STREQUAL "") + if ("${DEFAULT_${CMAKE_C_COMPILER_ID}_COMPILER_VER}" STREQUAL "") + set(COMPILER_OPTIONS_FILE "${COMPILER_OPTIONS_FILE}/${OS_DEFAULT_COMPILER}.cmake") + message(WARNING "Unknown compiler, using options from the OS default one: ${OS_DEFAULT_COMPILER}") + else() + set(COMPILER_OPTIONS_FILE "${COMPILER_OPTIONS_FILE}/${CMAKE_C_COMPILER_ID}${DEFAULT_${CMAKE_C_COMPILER_ID}_COMPILER_VER}.cmake") + if(CMAKE_C_COMPILER_VERSION VERSION_LESS ${DEFAULT_${CMAKE_C_COMPILER_ID}_COMPILER_VER}) + message(WARNING "Version of the compiler is lower than default, using options from: ${DEFAULT_${CMAKE_C_COMPILER_ID}_COMPILER_VER}") + endif() + endif() + else() + set(COMPILER_OPTIONS_FILE "${COMPILER_OPTIONS_FILE}/${CMAKE_C_COMPILER_ID}${DEFAULT_${CMAKE_C_COMPILER_ID}${CMAKE_C_COMPILER_VERSION_MAJOR}_COMPILER_VER}.cmake") + endif() +endif() +message (STATUS "Using compiler options from ........... " ${COMPILER_OPTIONS_FILE}) + +# Assembler options +# Note: do not move this initialization after LIBRARY_DEFINES extension +set(CMAKE_USER_MAKE_RULES_OVERRIDE_ASM "${IPP_CRYPTO_DIR}/sources/cmake/CMakeASM_NASMOptions.txt") +enable_language(ASM_NASM) +if(NOT CMAKE_ASM_NASM_COMPILER_LOADED) + message(FATAL_ERROR "Can't find assembler") +endif() +message(STATUS "ASM compiler version .................. " ${CMAKE_ASM_NASM_COMPILER}) +message(STATUS "ASM object format ..................... " ${CMAKE_ASM_NASM_OBJECT_FORMAT}) + +# set Intel IPP Cryptography revision, if required +if(IPP_REVISION) + # IPP_REVISION - release revision id, added into LibraryVersion + set(LIBRARY_DEFINES "${LIBRARY_DEFINES} -DIPP_REVISION=${IPP_REVISION}") +endif() + +set(LIBRARY_DEFINES "${LIBRARY_DEFINES} -D_NO_IPP_DEPRECATED") # do not warn about ippcp deprecated functions +# set BN_OPENSSL_DISABLE for Intel IPP Cryptography +# set(LIBRARY_DEFINES "${LIBRARY_DEFINES} -DBN_OPENSSL_DISABLE") + +include(${COMPILER_OPTIONS_FILE}) # uses ${CMAKE_C_FLAGS} ${LIBRARY_DEFINES} ${opt} from the scope + +if(UNIX) + set(CMAKE_C_CREATE_SHARED_LIBRARY " ${LIB_EXPORT_FILE} -o ") + set(CMAKE_CXX_CREATE_SHARED_LIBRARY " ${LIB_EXPORT_FILE} -o ") + if("${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") + string(REPLACE "" " " CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_LIBRARY}) + string(REPLACE "" " " CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY}) + endif() +endif(UNIX) + +if(NOT MERGED_BLD) + set(IPPCP_LIB_STATIC "") + set(IPPCP_LIB_DYNAMIC "") +endif(NOT MERGED_BLD) + +file(GLOB IPPCP_PUBLIC_HEADERS + ${IPP_CRYPTO_INCLUDE_DIR}/*.h) + +file(GLOB LIBRARY_HEADERS + ${IPP_CRYPTO_SOURCES_DIR}/*.h + ${IPP_CRYPTO_SOURCES_DIR}/ecnist/*.h + ${IPP_CRYPTO_SOURCES_DIR}/sm2/*.h + ${IPP_CRYPTO_SOURCES_INCLUDE_DIR}/*.h + ${IPP_CRYPTO_INCLUDE_DIR}/ippcp*.h + # RSA_SB (ifma) uses crypto_mb headers + ${IPP_CRYPTO_SOURCES_DIR}/crypto_mb/include/crypto_mb/*.h + ${IPP_CRYPTO_SOURCES_DIR}/crypto_mb/include/internal/*.h + ) + +file(GLOB LIBRARY_C_SOURCES_ORIGINAL + ${IPP_CRYPTO_SOURCES_DIR}/*.c + ${IPP_CRYPTO_SOURCES_DIR}/ecnist/*.c + ${IPP_CRYPTO_SOURCES_DIR}/sm2/*.c + ) + +file(GLOB LIBRARY_ASM_SOURCES_ORIGINAL + ${IPP_CRYPTO_SOURCES_DIR}/asm_${ARCH}/*.asm + ) + +set(INTERNAL_INCLUDE_DIR ${CMAKE_BINARY_DIR}/include/autogen) + +set (C_INCLUDE_DIRECTORIES + ${IPP_CRYPTO_SOURCES_DIR} + ${IPP_CRYPTO_SOURCES_DIR}/ecnist + ${IPP_CRYPTO_SOURCES_DIR}/sm2 + ${IPP_CRYPTO_SOURCES_INCLUDE_DIR} + ${IPP_CRYPTO_INCLUDE_DIR} + ${INTERNAL_INCLUDE_DIR} + # RSA_SB (ifma) uses crypto_mb headers + ${IPP_CRYPTO_SOURCES_DIR}/crypto_mb/include + $<$:$ENV{ROOT}/compiler/include $ENV{ROOT}/compiler/include/icc> + $<$>:${CMAKE_SYSTEM_INCLUDE_PATH}> + $<$,$>:$ENV{INCLUDE}> + ) + +set (ASM_INCLUDE_DIRECTORIES + ${IPP_CRYPTO_SOURCES_INCLUDE_DIR} + ${IPP_CRYPTO_SOURCES_DIR}/asm_${ARCH} + ) + +# Because of CMake bug (https://gitlab.kitware.com/cmake/cmake/issues/19178) it is impossible to add +# target specific NASM compiler options/definitions when using VS generator, but it is possible to specify +# them based on source files. So, here is the workaround - we spawn same assembler sources across different +# platform-specific directories and assign different definitions for each directory using set_source_files_properties(). +# +# The same trick is used for C sources, but it aims a different purpose: to rename object files in the library archive, +# so that they do not intersect in a 'merged' library. +foreach(opt ${PLATFORM_LIST}) + # Popullate ASM source files in to corresponding folders per library 'letter' + set(asm_cache_dir "${CMAKE_BINARY_DIR}/asm_sources/${opt}/asm_${ARCH}") + file(MAKE_DIRECTORY ${asm_cache_dir}) + # Prefer configure_file() over simple file(COPY) as it creates dependencies, so that cmake project + # will be regenerated each time when any original file is changed. This is needed to keep all copied files up-to-date. + foreach (file ${LIBRARY_ASM_SOURCES_ORIGINAL}) + get_filename_component(basename ${file} NAME) + configure_file(${file} ${asm_cache_dir}/${opt}_${basename} COPYONLY) + endforeach() + file (GLOB LIBRARY_ASM_SOURCES_${opt} + ${asm_cache_dir}/*.asm + ) + set_source_files_properties(${LIBRARY_ASM_SOURCES_${opt}} PROPERTIES COMPILE_DEFINITIONS "$<$:_MERGED_BLD>;${${opt}_def}" + COMPILE_OPTIONS "$<$:${CMAKE_ASM_NASM_DEBUG_OPTIONS}>" + INCLUDE_DIRECTORIES "${ASM_INCLUDE_DIRECTORIES}") + + ######################################################################################### + # Popullate C source files in to corresponding folders per library 'letter' + if (NOT CODE_COVERAGE) + set(c_cache_dir "${CMAKE_BINARY_DIR}/c_sources/${opt}/c_${ARCH}") + file(MAKE_DIRECTORY ${c_cache_dir}) + # Add a prefix to the source files, so that corresponding object files in the merged library are unique named + foreach (file ${LIBRARY_C_SOURCES_ORIGINAL}) + get_filename_component(basename ${file} NAME) + configure_file(${file} ${c_cache_dir}/${opt}_${basename} COPYONLY) + endforeach() + file (GLOB LIBRARY_C_SOURCES_${opt} + ${c_cache_dir}/*.c + ) + else() + # Code coverage data gathering is a bit easier, when sources for ISA-specific builds point to the same location on a filesystem + set(LIBRARY_C_SOURCES_${opt} "${LIBRARY_C_SOURCES_ORIGINAL}") + endif() + set_source_files_properties(${LIBRARY_C_SOURCES_${opt}} pcpver.rc PROPERTIES INCLUDE_DIRECTORIES "${C_INCLUDE_DIRECTORIES}") + # Set optimization flag for cpinit.c to -O1 + # Fix for problem related with MSVC compiler -O2 optimization + if((${ARCH} STREQUAL "intel64") AND ("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")) + set_source_files_properties("${c_cache_dir}/${opt}_cpinit.c" PROPERTIES COMPILE_FLAGS " /O1") + endif() +endforeach() + +# Generate single-CPU headers +if(MERGED_BLD) + set(ONE_CPU_FOLDER ${INTERNAL_INCLUDE_DIR}/single_cpu) + set(ONE_CPU_GENERATOR ${IPP_CRYPTO_DIR}/sources/gen_cpu_spc_header/gen_cpu_spc_1cpu_header.py) + execute_process(COMMAND ${Python_EXECUTABLE} ${ONE_CPU_GENERATOR} ${IPP_CRYPTO_INCLUDE_DIR}/ippcp.h ${ONE_CPU_FOLDER}) + file(GLOB ONE_CPU_HEADERS "${ONE_CPU_FOLDER}/*.h") + + set(INTERNAL_GENERATOR ${IPP_CRYPTO_DIR}/sources/gen_cpu_spc_header/gen_cpu_spc_header.py) + execute_process(COMMAND ${Python_EXECUTABLE} ${INTERNAL_GENERATOR} ${IPP_CRYPTO_INCLUDE_DIR}/ippcp.h ${INTERNAL_INCLUDE_DIR}) + set(HEADERS ${LIBRARY_HEADERS} ${INTERNAL_INCLUDE_DIR}/ippcp_cpuspc.h) +endif(MERGED_BLD) + +# Copy headers to the output directory +foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) + string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) + file(COPY ${IPP_CRYPTO_INCLUDE_DIR}/ippcp.h + ${IPP_CRYPTO_INCLUDE_DIR}/ippcpdefs.h + ${IPP_CRYPTO_INCLUDE_DIR}/ippversion.h + ${ONE_CPU_FOLDER} + DESTINATION "${CMAKE_OUTPUT_DIR}/${OUTPUTCONFIG}/include") +endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) + +foreach(opt ${PLATFORM_LIST}) + set(OPT_FLAGS_${opt} ${${opt}_opt}) + + if(DYNAMIC_LIB AND NOT MERGED_BLD) + set(IPPCP_DYN_ITER ${TARGET_NAME}_dyn_${opt}) + set(IPPCP_DYN_ITER_ASMOBJS ${TARGET_NAME}_dyn_${opt}-asmobjs) + if(WIN32) + add_library(${IPPCP_DYN_ITER_ASMOBJS} OBJECT ${LIBRARY_ASM_SOURCES_${opt}}) + add_library(${IPPCP_DYN_ITER} SHARED ippcp.def + pcpver.rc + ${LIBRARY_HEADERS} + ${LIBRARY_C_SOURCES_${opt}} + $) + + set_target_properties(${IPPCP_DYN_ITER} PROPERTIES LINK_FLAGS ${LINK_FLAG_DYNAMIC_WINDOWS}) + foreach(link ${LINK_LIB_STATIC_DEBUG}) + target_link_libraries(${IPPCP_DYN_ITER} debug ${link}) + endforeach() + foreach(link ${LINK_LIB_STATIC_RELEASE}) + target_link_libraries(${IPPCP_DYN_ITER} optimized ${link}) + endforeach() + else() + add_library(${IPPCP_DYN_ITER_ASMOBJS} OBJECT ${LIBRARY_ASM_SOURCES_${opt}}) + add_library(${IPPCP_DYN_ITER} SHARED ${LIBRARY_HEADERS} + ${LIBRARY_C_SOURCES_${opt}} + $) + if(APPLE) + ## gres: copy LINK_FLAG_DYNAMIC_LINUX + set(LINK_FLAGS ${LINK_FLAG_DYNAMIC_MACOSX}) + ## add export file + set(LINK_FLAGS "${LINK_FLAGS} -exported_symbols_list ${IPP_CRYPTO_SOURCES_DIR}/exports.macosx.lib-export") + set_target_properties(${IPPCP_DYN_ITER} PROPERTIES LINK_FLAGS "${LINK_FLAGS}") + add_custom_command(TARGET ${IPPCP_DYN_ITER} POST_BUILD COMMAND + ${CMAKE_INSTALL_NAME_TOOL} -id @rpath/lib${TARGET_NAME}${opt}.dylib $) + else() + ## gres: copy LINK_FLAG_DYNAMIC_LINUX + set(LINK_FLAGS ${LINK_FLAG_DYNAMIC_LINUX}) + ## add export file + set(LINK_FLAGS "${LINK_FLAGS} ${IPP_CRYPTO_SOURCES_DIR}/exports.linux.lib-export") + set_target_properties(${IPPCP_DYN_ITER} PROPERTIES LINK_FLAGS ${LINK_FLAGS}) + endif() + if(NOT APPLE) + if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + target_link_libraries(${IPPCP_DYN_ITER} gcc) # gcc is because of -nostdlib + target_link_libraries(${IPPCP_DYN_ITER} c) # for printf - debug purpose only, not used + endif() + endif() + endif() + set_target_properties(${IPPCP_DYN_ITER} PROPERTIES OUTPUT_NAME "${TARGET_NAME}${opt}" + COMPILE_FLAGS "${OPT_FLAGS_${opt}}" + COMPILE_DEFINITIONS "_IPP_DYNAMIC;${${opt}_def}" + PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}" + ) + if(UNIX) + set_target_properties(${IPPCP_DYN_ITER} PROPERTIES VERSION ${IPPCP_INTERFACE_VERSION} + SOVERSION ${IPPCP_INTERFACE_VERSION_MAJOR}) + endif() + + install(TARGETS ${IPPCP_DYN_ITER} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" + PUBLIC_HEADER DESTINATION "include") + list(APPEND IPPCP_LIB_DYNAMIC ${IPPCP_DYN_ITER}) + endif(DYNAMIC_LIB AND NOT MERGED_BLD) + + set(IPPCP_ST_ITER ${TARGET_NAME}_s_${opt}) + set(IPPCP_ST_ITER_ASMOBJS ${TARGET_NAME}_s_${opt}-asmobjs) + if(MERGED_BLD) + add_library(${IPPCP_ST_ITER} OBJECT ${LIBRARY_HEADERS} ${LIBRARY_C_SOURCES_${opt}}) + add_library(${IPPCP_ST_ITER_ASMOBJS} OBJECT ${LIBRARY_ASM_SOURCES_${opt}}) + set(merged_dependency ${merged_dependency} $ + $) + else() + add_library(${IPPCP_ST_ITER_ASMOBJS} OBJECT ${LIBRARY_ASM_SOURCES_${opt}}) + add_library(${IPPCP_ST_ITER} STATIC ${LIBRARY_HEADERS} + ${LIBRARY_C_SOURCES_${opt}} + $) + endif() + + if(WIN32) + set_target_properties(${IPPCP_ST_ITER} ${IPPCP_ST_ITER_ASMOBJS} PROPERTIES STATIC_LIBRARY_FLAGS ${LINK_FLAG_STATIC_WINDOWS}) + endif() + + set_target_properties(${IPPCP_ST_ITER} PROPERTIES COMPILE_FLAGS "${OPT_FLAGS_${opt}}" + COMPILE_DEFINITIONS "$<$:_MERGED_BLD>;${${opt}_def}") + # Merged build install is handled in another target + if (NOT MERGED_BLD) + set_target_properties(${IPPCP_ST_ITER} PROPERTIES PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}") + install(TARGETS ${IPPCP_ST_ITER} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" + PUBLIC_HEADER DESTINATION "include") + endif() + + list(APPEND IPPCP_LIB_STATIC ${IPPCP_ST_ITER}) +endforeach() + +if(NOT MERGED_BLD) + set(IPPCP_LIB_STATIC ${IPPCP_LIB_STATIC} PARENT_SCOPE) + set(IPPCP_LIB_DYNAMIC ${IPPCP_LIB_DYNAMIC} PARENT_SCOPE) +endif() + +if(MERGED_BLD) + set(DISPATCHER ${CMAKE_BINARY_DIR}/dispatcher) + set(IPPCP_API ${IPP_CRYPTO_INCLUDE_DIR}/ippcp.h) + file(MAKE_DIRECTORY ${DISPATCHER}) + + if(WIN32) + if(${ARCH} MATCHES "ia32") + set(DISPATCHER_GENERATOR ${IPP_CRYPTO_DISPATCHER_DIR}/gen_disp_win32.py) + else() + set(DISPATCHER_GENERATOR ${IPP_CRYPTO_DISPATCHER_DIR}/gen_disp_win64.py) + endif() + elseif(UNIX) + if(APPLE) + set(DISPATCHER_GENERATOR ${IPP_CRYPTO_DISPATCHER_DIR}/gen_disp_mac64.py) + else() + if(NOT NONPIC_LIB) + if(${ARCH} MATCHES "ia32") + set(DISPATCHER_GENERATOR ${IPP_CRYPTO_DISPATCHER_DIR}/gen_disp_lin32.py) + else() + set(DISPATCHER_GENERATOR ${IPP_CRYPTO_DISPATCHER_DIR}/gen_disp_lin64.py) + endif() + else() + if(${ARCH} MATCHES "ia32") + set(DISPATCHER_GENERATOR ${IPP_CRYPTO_DISPATCHER_DIR}/gen_disp_lin32.nonpic.py) + else() + set(DISPATCHER_GENERATOR ${IPP_CRYPTO_DISPATCHER_DIR}/gen_disp_lin64.nonpic.py) + endif() + endif() + endif() + endif(WIN32) + + execute_process(COMMAND ${Python_EXECUTABLE} ${DISPATCHER_GENERATOR} -i ${IPPCP_API} -o ${DISPATCHER} -l "${PLATFORM_LIST}" -c ${CMAKE_C_COMPILER_ID} + RESULT_VARIABLE result + ) + + file(GLOB DISPATCHER_HEADERS + ${CMAKE_BINARY_DIR}/dispatcher/*.h + ) + + file(GLOB DISPATCHER_C_SOURCES + ${CMAKE_BINARY_DIR}/dispatcher/*.c + ) + + file(GLOB DISPATCHER_ASM_SOURCES + ${CMAKE_BINARY_DIR}/dispatcher/*.asm + ) + + set(IPPCP_LIB_MERGED ${TARGET_NAME}_s) + add_library(${IPPCP_LIB_MERGED} STATIC ${DISPATCHER_HEADERS} ${DISPATCHER_C_SOURCES} ${DISPATCHER_ASM_SOURCES} ${merged_dependency}) + + set(IPPCP_LIB_MERGED ${IPPCP_LIB_MERGED} PARENT_SCOPE) + + if(WIN32) + set_target_properties(${IPPCP_LIB_MERGED} PROPERTIES OUTPUT_NAME "${TARGET_NAME}mt") + set_target_properties(${IPPCP_LIB_MERGED} PROPERTIES STATIC_LIBRARY_FLAGS ${LINK_FLAG_STATIC_WINDOWS}) + else() + set_target_properties(${IPPCP_LIB_MERGED} PROPERTIES OUTPUT_NAME "${TARGET_NAME}") + endif(WIN32) + + set_target_properties(${IPPCP_LIB_MERGED} PROPERTIES PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}" + PRIVATE_HEADER "${ONE_CPU_HEADERS}") + + install(TARGETS ${IPPCP_LIB_MERGED} + ARCHIVE DESTINATION "lib/${ARCH}/$<$:nonpic>" + PUBLIC_HEADER DESTINATION "include" + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + set_source_files_properties(${DISPATCHER_C_SOURCES} pcpver.rc PROPERTIES INCLUDE_DIRECTORIES "${C_INCLUDE_DIRECTORIES}") + # protection (_FORTIFY_SOURCE) and optimization flags for dispatcher + if(UNIX) + if(${ARCH} MATCHES "ia32") + set_source_files_properties(${DISPATCHER_C_SOURCES} PROPERTIES COMPILE_FLAGS "${CC_FLAGS_INLINE_ASM_UNIX_IA32} -D_GNU_SOURCE -D_FORTIFY_SOURCE=2 -O2") + else() + set_source_files_properties(${DISPATCHER_C_SOURCES} PROPERTIES COMPILE_FLAGS "${CC_FLAGS_INLINE_ASM_UNIX_INTEL64} -D_GNU_SOURCE -D_FORTIFY_SOURCE=2 -O2") + endif() + endif() + + # Single merged dynamic lib + if(DYNAMIC_LIB) + set(IPPCP_LIB_PCS ${TARGET_NAME}_dyn) + set(IPPCP_LIB_PCS ${IPPCP_LIB_PCS} PARENT_SCOPE) + + if(WIN32) + add_library(${IPPCP_LIB_PCS} SHARED ippcp.def emptyfile.c pcpver.rc) # emptyfile.c - Visual Studio does not produce a .dll without source files + else() + add_library(${IPPCP_LIB_PCS} SHARED emptyfile.c) # emptyfile.c to suppress the cmake warning + endif() + + set_target_properties(${IPPCP_LIB_PCS} PROPERTIES LINKER_LANGUAGE C + COMPILE_DEFINITIONS "_MERGED_BLD" + PUBLIC_HEADER "${IPPCP_PUBLIC_HEADERS}" + PRIVATE_HEADER "${ONE_CPU_HEADERS}") + if(UNIX) + set_target_properties(${IPPCP_LIB_PCS} PROPERTIES VERSION ${IPPCP_INTERFACE_VERSION} + SOVERSION ${IPPCP_INTERFACE_VERSION_MAJOR}) + endif() + + target_link_libraries(${IPPCP_LIB_PCS} ${IPPCP_LIB_MERGED}) # link to the static merged + set_target_properties(${IPPCP_LIB_PCS} PROPERTIES OUTPUT_NAME "${TARGET_NAME}") + + install(TARGETS ${IPPCP_LIB_PCS} + LIBRARY DESTINATION "lib/${ARCH}/$<$:nonpic>" + RUNTIME DESTINATION "lib/${ARCH}/$<$:nonpic>" + PUBLIC_HEADER DESTINATION "include" + PRIVATE_HEADER DESTINATION "tools/${ARCH}/staticlib") + + if(WIN32) + set_target_properties(${IPPCP_LIB_PCS} PROPERTIES LINK_FLAGS ${LINK_FLAG_DYNAMIC_WINDOWS}) + foreach(link ${LINK_LIB_STATIC_DEBUG}) + target_link_libraries(${IPPCP_LIB_PCS} debug ${link}) + endforeach() + foreach(link ${LINK_LIB_STATIC_RELEASE}) + target_link_libraries(${IPPCP_LIB_PCS} optimized ${link}) + endforeach() + else() + if(APPLE) + set(LINK_FLAGS ${LINK_FLAG_PCS_MACOSX}) + ## add export file + set(LINK_FLAGS "${LINK_FLAGS} -exported_symbols_list ${IPP_CRYPTO_SOURCES_DIR}/exports.macosx.lib-export") + set_target_properties(${IPPCP_LIB_PCS} PROPERTIES LINK_FLAGS "${LINK_FLAGS}") + add_custom_command(TARGET ${IPPCP_LIB_PCS} POST_BUILD COMMAND + ${CMAKE_INSTALL_NAME_TOOL} -id @rpath/lib${TARGET_NAME}.dylib $) + else() + set(LINK_FLAGS ${LINK_FLAG_PCS_LINUX}) + ## add export file + set(LINK_FLAGS "${LINK_FLAGS} ${IPP_CRYPTO_SOURCES_DIR}/exports.linux.lib-export") + set_target_properties(${IPPCP_LIB_PCS} PROPERTIES LINK_FLAGS ${LINK_FLAGS}) + if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + target_link_libraries(${IPPCP_LIB_PCS} gcc) # gcc is because of -nostdlib + target_link_libraries(${IPPCP_LIB_PCS} c) # for stack check on gcc + endif() + endif() + endif(WIN32) + + endif(DYNAMIC_LIB) +endif() + +# Generate CMake configs to let external projects find ippcp and crypto_mb libraries easily +include("${IPP_CRYPTO_DIR}/sources/cmake/ippcp-gen-config.cmake") + +# Install Custom Library tool +install(DIRECTORY "${TOOLS_DIR}/ipp_custom_library_tool_python/" + DESTINATION "tools/custom_library_tool_python") + +# Crypto multi-buffer library +if ((NOT NO_CRYPTO_MB) AND ("${ARCH}" STREQUAL "intel64")) + # MB_STANDALONE adjusts some build settings in crypto_mb + # (e.g. output directories, make some crypto_mb build variables visible in parent scope, etc) + set(MB_STANDALONE false) + add_subdirectory(crypto_mb) + + # Throw these variables further up, so that tests can grab them and link to crypto_mb libraries + set(MB_DYN_LIB_TARGET "${MB_DYN_LIB_TARGET}" PARENT_SCOPE) + set(MB_STATIC_LIB_TARGET "${MB_STATIC_LIB_TARGET}" PARENT_SCOPE) + + # Copy crypto_mb public headers to the output directory + foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) + string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG ) + foreach(HEADER ${MB_PUBLIC_HEADERS}) + file(COPY "${HEADER}" DESTINATION "${CMAKE_OUTPUT_DIR}/${OUTPUTCONFIG}/include/crypto_mb") + endforeach(HEADER ${MB_PUBLIC_HEADERS}) + endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES ) + + # Interface versions (a.k.a. shared library versions) of ippcp and crypto_mb shall be equal, + # as they share single cmake-config routine with same "package name" IPPCP (in terms of find_package()). + # The intention behind this is ippcp and crypto_mb are part of the same product, and should + # share single find_package() call that can accept just one version common for all package components. + if(NOT "${IPPCP_INTERFACE_VERSION}" MATCHES "${MBX_INTERFACE_VERSION}") + message(SEND_ERROR "IPPCP_INTERFACE_VERSION and MBX_INTERFACE_VERSION don't match") + endif() +endif() diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_cfb_aesni_mb.h b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_aesni_mb.h new file mode 100644 index 000000000..991f96a3b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_aesni_mb.h @@ -0,0 +1,31 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_AES_CFB_AESNI_MB) +#define _AES_CFB_AESNI_MB + +#include "owndefs.h" +#include "owncp.h" + +#if (_IPP32E>=_IPP32E_Y8) + +#define aes_cfb16_enc_aesni_mb4 OWNAPI(aes_cfb16_enc_aesni_mb4) + IPP_OWN_DECL (void, aes_cfb16_enc_aesni_mb4, (const Ipp8u* const source_pa[4], Ipp8u* const dst_pa[4], const int len[4], const int num_of_rounds, const Ipp32u* enc_keys[4], const Ipp8u* pIV[4])) + +#endif + +#endif /* _AES_CFB_AESNI_MB */ diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_cfb_aesni_mb4.c b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_aesni_mb4.c new file mode 100644 index 000000000..be702b1b9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_aesni_mb4.c @@ -0,0 +1,102 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "aes_cfb_aesni_mb.h" + +#if (_IPP32E>=_IPP32E_Y8) + +static inline void aes_encrypt4_aesni_mb4(__m128i blocks[4], __m128i enc_keys[4][15], int cipherRounds) +{ + + blocks[0] = _mm_xor_si128(blocks[0], enc_keys[0][0]); + blocks[1] = _mm_xor_si128(blocks[1], enc_keys[1][0]); + blocks[2] = _mm_xor_si128(blocks[2], enc_keys[2][0]); + blocks[3] = _mm_xor_si128(blocks[3], enc_keys[3][0]); + + int nr; + + for (nr = 1; nr < cipherRounds; nr += 1) { + + blocks[0] = _mm_aesenc_si128(blocks[0], enc_keys[0][nr]); + blocks[1] = _mm_aesenc_si128(blocks[1], enc_keys[1][nr]); + blocks[2] = _mm_aesenc_si128(blocks[2], enc_keys[2][nr]); + blocks[3] = _mm_aesenc_si128(blocks[3], enc_keys[3][nr]); + + } + + blocks[0] = _mm_aesenclast_si128(blocks[0], enc_keys[0][nr]); + blocks[1] = _mm_aesenclast_si128(blocks[1], enc_keys[1][nr]); + blocks[2] = _mm_aesenclast_si128(blocks[2], enc_keys[2][nr]); + blocks[3] = _mm_aesenclast_si128(blocks[3], enc_keys[3][nr]); +} + + +IPP_OWN_DEFN (void, aes_cfb16_enc_aesni_mb4, (const Ipp8u* const source_pa[4], Ipp8u* const dst_pa[4], const int len[4], const int cipherRounds, const Ipp32u* enc_keys[4], const Ipp8u* pIV[4])) +{ + __m128i* pSrc[4]; + __m128i* pDst[4]; + + __m128i blocks[4]; + __m128i plainBlocks[4]; + + int nBlocks[4]; + + int maxBlocks = 0; + + __m128i keySchedule[4][15]; + + for (int i = 0; i < 4; i++) { + pSrc[i] = (__m128i*)source_pa[i]; + pDst[i] = (__m128i*)dst_pa[i]; + + nBlocks[i] = len[i] / CFB16_BLOCK_SIZE; + + if(nBlocks[i] > 0) { + blocks[i] = _mm_loadu_si128((__m128i const*)(pIV[i])); + + for (int j = 0; j <= cipherRounds; j++) { + keySchedule[i][j] = _mm_loadu_si128((__m128i const*)enc_keys[i] + j); + } + } + + if (nBlocks[i] > maxBlocks) { + maxBlocks = nBlocks[i]; + } + } + + for (int block = 0; block < maxBlocks; block++) { + aes_encrypt4_aesni_mb4(blocks, keySchedule, cipherRounds); + + for (int i = 0; i < 4; i++) { + if (nBlocks[i] > 0) { + plainBlocks[i] = _mm_loadu_si128(pSrc[i]); + blocks[i] = _mm_xor_si128(blocks[i], plainBlocks[i]); + _mm_storeu_si128(pDst[i], blocks[i]); + + pSrc[i]+= 1; + pDst[i]+= 1; + nBlocks[i] -= 1; + } + } + } +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb.h b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb.h new file mode 100644 index 000000000..7894c56f7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb.h @@ -0,0 +1,54 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_AES_CFB_VAES_MB) +#define _AES_CFB_VAES_MB + +#include "owndefs.h" +#include "owncp.h" + +#if (_IPP32E>=_IPP32E_K1) + +#define TRANSPOSE_4x4_I128(X0_, X1_ ,X2_ ,X3_) {\ + __m512i T0_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, X0_, X1_, 0b01000100); \ + __m512i T1_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, X2_, X3_, 0b01000100); \ + __m512i T2_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, X0_, X1_, 0b11101110); \ + __m512i T3_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, X2_, X3_, 0b11101110); \ + \ + X0_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, T0_, T1_, 0b10001000); \ + X1_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, T0_, T1_, 0b11011101); \ + X2_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, T2_, T3_, 0b10001000); \ + X3_ = _mm512_maskz_shuffle_i64x2((__mmask8)0xFF, T2_, T3_, 0b11011101); \ +} + +#define UPDATE_MASK(len64, mask) {\ + if (len64 < 2 * 4 && len64 >= 0) \ + mask = (__mmask8)(((1 << len64) - 1) & 0xFF); \ + else if (len64 < 0) \ + mask = 0; \ +} + +#define aes_cfb16_enc_vaes_mb4 OWNAPI(aes_cfb16_enc_vaes_mb4) + IPP_OWN_DECL (void, aes_cfb16_enc_vaes_mb4, (const Ipp8u* const source_pa[4], Ipp8u* const dst_pa[4], const int len[4], const int num_of_rounds, const Ipp32u* enc_keys[4], const Ipp8u* pIV[4])) +#define aes_cfb16_enc_vaes_mb8 OWNAPI(aes_cfb16_enc_vaes_mb8) + IPP_OWN_DECL (void, aes_cfb16_enc_vaes_mb8, (const Ipp8u* const source_pa[8], Ipp8u* const dst_pa[8], const int len[8], const int num_of_rounds, const Ipp32u* enc_keys[8], const Ipp8u* pIV[8])) +#define aes_cfb16_enc_vaes_mb16 OWNAPI(aes_cfb16_enc_vaes_mb16) + IPP_OWN_DECL (void, aes_cfb16_enc_vaes_mb16, (const Ipp8u* const source_pa[16], Ipp8u* const dst_pa[16], const int len[16], const int num_of_rounds, const Ipp32u* enc_keys[16], const Ipp8u* pIV[16])) + +#endif + +#endif /* _AES_CFB_VAES_MB */ diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb16.c b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb16.c new file mode 100644 index 000000000..889f132ca --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb16.c @@ -0,0 +1,257 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "aes_cfb_vaes_mb.h" + +#if(_IPP32E>=_IPP32E_K1) + +#define AES_ENCRYPT_VAES_MB16(b0, b1, b2, b3, pRkey, num_rounds) { \ + __m512i (*tkeys)[4] = &pRkey[num_rounds-9]; \ + b0 = _mm512_xor_si512(b0, pRkey[0][0]); \ + b1 = _mm512_xor_si512(b1, pRkey[0][1]); \ + b2 = _mm512_xor_si512(b2, pRkey[0][2]); \ + b3 = _mm512_xor_si512(b3, pRkey[0][3]); \ + switch(num_rounds) { \ + case 14: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-4][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-4][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[-4][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[-4][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-3][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-3][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[-3][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[-3][3]); \ + case 12: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-2][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-2][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[-2][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[-2][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-1][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-1][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[-1][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[-1][3]); \ + default: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[0][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[0][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[0][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[0][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[1][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[1][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[1][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[1][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[2][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[2][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[2][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[2][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[3][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[3][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[3][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[3][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[4][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[4][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[4][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[4][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[5][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[5][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[5][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[5][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[6][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[6][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[6][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[6][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[7][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[7][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[7][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[7][3]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[8][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[8][1]); \ + b2 = _mm512_aesenc_epi128(b2, tkeys[8][2]); \ + b3 = _mm512_aesenc_epi128(b3, tkeys[8][3]); \ + \ + b0 = _mm512_aesenclast_epi128(b0, tkeys[9][0]); \ + b1 = _mm512_aesenclast_epi128(b1, tkeys[9][1]); \ + b2 = _mm512_aesenclast_epi128(b2, tkeys[9][2]); \ + b3 = _mm512_aesenclast_epi128(b3, tkeys[9][3]); \ + } \ +} + +// Disable optimization for MSVC +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma optimize( "", off ) +#endif + +IPP_OWN_DEFN(void, aes_cfb16_enc_vaes_mb16, (const Ipp8u* const source_pa[16], Ipp8u* const dst_pa[16], const int arr_len[16], const int num_rounds, const Ipp32u* enc_keys[16], const Ipp8u* iv_pa[16])) +{ + int i, j, k; + int maxLen = 0; + int loc_len64[16]; + Ipp8u* loc_src[16]; + Ipp8u* loc_dst[16]; + __m512i iv512[4]; + + __mmask8 mbMask128[16] = { 0x03, 0x0C, 0x30, 0xC0, 0x03, 0x0C, 0x30, 0xC0, 0x03, 0x0C, 0x30, 0xC0, 0x03, 0x0C, 0x30, 0xC0 }; + __mmask8 mbMask[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + // - Local copy of length, source and target pointers, maxLen calculation + for (i = 0; i < 16; i++) { + // The case of the empty input buffer + if (arr_len[i] == 0) + { + mbMask128[i] = 0; + mbMask[i] = 0; + loc_len64[i] = 0; + continue; + } + + loc_src[i] = (Ipp8u*)source_pa[i]; + loc_dst[i] = (Ipp8u*)dst_pa[i]; + int len64 = arr_len[i] / (Ipp32s)sizeof(Ipp64u); // length in 64-bit chunks + loc_len64[i] = len64; + + if (len64 < 8) + mbMask[i] = (__mmask8)(((1 << len64) - 1) & 0xFF); + if (len64 > maxLen) + maxLen = len64; + } + + // Load the necessary number of 128-bit IV + j = 0; + for (i = 0; i < 16; i += 4) { + iv512[j] = _mm512_setzero_si512(); + + iv512[j] = _mm512_mask_expandloadu_epi64(iv512[j], mbMask128[i], iv_pa[i]); + iv512[j] = _mm512_mask_expandloadu_epi64(iv512[j], mbMask128[i + 1], iv_pa[i + 1]); + iv512[j] = _mm512_mask_expandloadu_epi64(iv512[j], mbMask128[i + 2], iv_pa[i + 2]); + iv512[j] = _mm512_mask_expandloadu_epi64(iv512[j], mbMask128[i + 3], iv_pa[i + 3]); + j += 1; + } + + // Temporary block to left IV unchanged to use it on the next round + __m512i chip0 = iv512[0]; + __m512i chip1 = iv512[1]; + __m512i chip2 = iv512[2]; + __m512i chip3 = iv512[3]; + + // Prepare array with key schedule + __m512i keySchedule[15][4]; + __m512i tmpKeyMb = _mm512_setzero_si512(); + for (i = 0; i <= num_rounds; i++) + { + k = 0; + for (j = 0; j < 16; j += 4) { + tmpKeyMb = _mm512_setzero_si512(); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[j], (const void *)(enc_keys[j] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[j + 1], (const void *)(enc_keys[j + 1] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[j + 2], (const void *)(enc_keys[j + 2] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[j + 3], (const void *)(enc_keys[j + 3] + (Ipp32u)i * sizeof(Ipp32u))); + + keySchedule[i][k] = _mm512_loadu_si512(&tmpKeyMb); + k += 1; + } + } + + for (; maxLen >= 0; maxLen -= 8) + { + __m512i b0 = _mm512_maskz_loadu_epi64(mbMask[0], loc_src[0]); loc_src[0] += CFB16_BLOCK_SIZE * 4; + __m512i b1 = _mm512_maskz_loadu_epi64(mbMask[1], loc_src[1]); loc_src[1] += CFB16_BLOCK_SIZE * 4; + __m512i b2 = _mm512_maskz_loadu_epi64(mbMask[2], loc_src[2]); loc_src[2] += CFB16_BLOCK_SIZE * 4; + __m512i b3 = _mm512_maskz_loadu_epi64(mbMask[3], loc_src[3]); loc_src[3] += CFB16_BLOCK_SIZE * 4; + __m512i b4 = _mm512_maskz_loadu_epi64(mbMask[4], loc_src[4]); loc_src[4] += CFB16_BLOCK_SIZE * 4; + __m512i b5 = _mm512_maskz_loadu_epi64(mbMask[5], loc_src[5]); loc_src[5] += CFB16_BLOCK_SIZE * 4; + __m512i b6 = _mm512_maskz_loadu_epi64(mbMask[6], loc_src[6]); loc_src[6] += CFB16_BLOCK_SIZE * 4; + __m512i b7 = _mm512_maskz_loadu_epi64(mbMask[7], loc_src[7]); loc_src[7] += CFB16_BLOCK_SIZE * 4; + __m512i b8 = _mm512_maskz_loadu_epi64(mbMask[8], loc_src[8]); loc_src[8] += CFB16_BLOCK_SIZE * 4; + __m512i b9 = _mm512_maskz_loadu_epi64(mbMask[9], loc_src[9]); loc_src[9] += CFB16_BLOCK_SIZE * 4; + __m512i b10 = _mm512_maskz_loadu_epi64(mbMask[10], loc_src[10]); loc_src[10] += CFB16_BLOCK_SIZE * 4; + __m512i b11 = _mm512_maskz_loadu_epi64(mbMask[11], loc_src[11]); loc_src[11] += CFB16_BLOCK_SIZE * 4; + __m512i b12 = _mm512_maskz_loadu_epi64(mbMask[12], loc_src[12]); loc_src[12] += CFB16_BLOCK_SIZE * 4; + __m512i b13 = _mm512_maskz_loadu_epi64(mbMask[13], loc_src[13]); loc_src[13] += CFB16_BLOCK_SIZE * 4; + __m512i b14 = _mm512_maskz_loadu_epi64(mbMask[14], loc_src[14]); loc_src[14] += CFB16_BLOCK_SIZE * 4; + __m512i b15 = _mm512_maskz_loadu_epi64(mbMask[15], loc_src[15]); loc_src[15] += CFB16_BLOCK_SIZE * 4; + + TRANSPOSE_4x4_I128(b0, b1, b2, b3); // {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} + TRANSPOSE_4x4_I128(b4, b5, b6, b7); // {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} + TRANSPOSE_4x4_I128(b8, b9, b10, b11); // {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} + TRANSPOSE_4x4_I128(b12, b13, b14, b15); // {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} + + AES_ENCRYPT_VAES_MB16(chip0, chip1, chip2, chip3, keySchedule, num_rounds); + chip0 = b0 = _mm512_xor_si512(b0, chip0); + chip1 = b4 = _mm512_xor_si512(b4, chip1); + chip2 = b8 = _mm512_xor_si512(b8, chip2); + chip3 = b12 = _mm512_xor_si512(b12, chip3); + + AES_ENCRYPT_VAES_MB16(chip0, chip1, chip2, chip3, keySchedule, num_rounds); + chip0 = b1 = _mm512_xor_si512(b1, chip0); + chip1 = b5 = _mm512_xor_si512(b5, chip1); + chip2 = b9 = _mm512_xor_si512(b9, chip2); + chip3 = b13 = _mm512_xor_si512(b13, chip3); + + AES_ENCRYPT_VAES_MB16(chip0, chip1, chip2, chip3, keySchedule, num_rounds); + chip0 = b2 = _mm512_xor_si512(b2, chip0); + chip1 = b6 = _mm512_xor_si512(b6, chip1); + chip2 = b10 = _mm512_xor_si512(b10, chip2); + chip3 = b14 = _mm512_xor_si512(b14, chip3); + + AES_ENCRYPT_VAES_MB16(chip0, chip1, chip2, chip3, keySchedule, num_rounds); + chip0 = b3 = _mm512_xor_si512(b3, chip0); + chip1 = b7 = _mm512_xor_si512(b7, chip1); + chip2 = b11 = _mm512_xor_si512(b11, chip2); + chip3 = b15 = _mm512_xor_si512(b15, chip3); + + TRANSPOSE_4x4_I128(b0, b1, b2, b3); + TRANSPOSE_4x4_I128(b4, b5, b6, b7); + TRANSPOSE_4x4_I128(b8, b9, b10, b11); + TRANSPOSE_4x4_I128(b12, b13, b14, b15); + + _mm512_mask_storeu_epi64(loc_dst[0], mbMask[0], b0); loc_dst[0] += CFB16_BLOCK_SIZE * 4; loc_len64[0] -= 2 * 4; UPDATE_MASK(loc_len64[0], mbMask[0]); + _mm512_mask_storeu_epi64(loc_dst[1], mbMask[1], b1); loc_dst[1] += CFB16_BLOCK_SIZE * 4; loc_len64[1] -= 2 * 4; UPDATE_MASK(loc_len64[1], mbMask[1]); + _mm512_mask_storeu_epi64(loc_dst[2], mbMask[2], b2); loc_dst[2] += CFB16_BLOCK_SIZE * 4; loc_len64[2] -= 2 * 4; UPDATE_MASK(loc_len64[2], mbMask[2]); + _mm512_mask_storeu_epi64(loc_dst[3], mbMask[3], b3); loc_dst[3] += CFB16_BLOCK_SIZE * 4; loc_len64[3] -= 2 * 4; UPDATE_MASK(loc_len64[3], mbMask[3]); + _mm512_mask_storeu_epi64(loc_dst[4], mbMask[4], b4); loc_dst[4] += CFB16_BLOCK_SIZE * 4; loc_len64[4] -= 2 * 4; UPDATE_MASK(loc_len64[4], mbMask[4]); + _mm512_mask_storeu_epi64(loc_dst[5], mbMask[5], b5); loc_dst[5] += CFB16_BLOCK_SIZE * 4; loc_len64[5] -= 2 * 4; UPDATE_MASK(loc_len64[5], mbMask[5]); + _mm512_mask_storeu_epi64(loc_dst[6], mbMask[6], b6); loc_dst[6] += CFB16_BLOCK_SIZE * 4; loc_len64[6] -= 2 * 4; UPDATE_MASK(loc_len64[6], mbMask[6]); + _mm512_mask_storeu_epi64(loc_dst[7], mbMask[7], b7); loc_dst[7] += CFB16_BLOCK_SIZE * 4; loc_len64[7] -= 2 * 4; UPDATE_MASK(loc_len64[7], mbMask[7]); + _mm512_mask_storeu_epi64(loc_dst[8], mbMask[8], b8); loc_dst[8] += CFB16_BLOCK_SIZE * 4; loc_len64[8] -= 2 * 4; UPDATE_MASK(loc_len64[8], mbMask[8]); + _mm512_mask_storeu_epi64(loc_dst[9], mbMask[9], b9); loc_dst[9] += CFB16_BLOCK_SIZE * 4; loc_len64[9] -= 2 * 4; UPDATE_MASK(loc_len64[9], mbMask[9]); + _mm512_mask_storeu_epi64(loc_dst[10], mbMask[10], b10); loc_dst[10] += CFB16_BLOCK_SIZE * 4; loc_len64[10] -= 2 * 4; UPDATE_MASK(loc_len64[10], mbMask[10]); + _mm512_mask_storeu_epi64(loc_dst[11], mbMask[11], b11); loc_dst[11] += CFB16_BLOCK_SIZE * 4; loc_len64[11] -= 2 * 4; UPDATE_MASK(loc_len64[11], mbMask[11]); + _mm512_mask_storeu_epi64(loc_dst[12], mbMask[12], b12); loc_dst[12] += CFB16_BLOCK_SIZE * 4; loc_len64[12] -= 2 * 4; UPDATE_MASK(loc_len64[12], mbMask[12]); + _mm512_mask_storeu_epi64(loc_dst[13], mbMask[13], b13); loc_dst[13] += CFB16_BLOCK_SIZE * 4; loc_len64[13] -= 2 * 4; UPDATE_MASK(loc_len64[13], mbMask[13]); + _mm512_mask_storeu_epi64(loc_dst[14], mbMask[14], b14); loc_dst[14] += CFB16_BLOCK_SIZE * 4; loc_len64[14] -= 2 * 4; UPDATE_MASK(loc_len64[14], mbMask[14]); + _mm512_mask_storeu_epi64(loc_dst[15], mbMask[15], b15); loc_dst[15] += CFB16_BLOCK_SIZE * 4; loc_len64[15] -= 2 * 4; UPDATE_MASK(loc_len64[15], mbMask[15]); + } +} + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma optimize( "", on ) +#endif + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb4.c b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb4.c new file mode 100644 index 000000000..5bfb65180 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb4.c @@ -0,0 +1,146 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "aes_cfb_vaes_mb.h" + +#if(_IPP32E>=_IPP32E_K1) + +#define AES_ENCRYPT_VAES_MB16(b0, pRkey, num_rounds) { \ + __m512i (*tkeys) = &pRkey[num_rounds-9]; \ + b0 = _mm512_xor_si512(b0, pRkey[0]); \ + switch(num_rounds) { \ + case 14: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-4]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-3]); \ + case 12: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-2]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-1]); \ + default: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[0]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[1]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[2]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[3]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[4]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[5]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[6]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[7]); \ + b0 = _mm512_aesenc_epi128(b0, tkeys[8]); \ + b0 = _mm512_aesenclast_epi128(b0, tkeys[9]); \ + } \ +} + +// Disable optimization for MSVC +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma optimize( "", off ) +#endif + +IPP_OWN_DEFN (void, aes_cfb16_enc_vaes_mb4, (const Ipp8u* const source_pa[4], Ipp8u* const dst_pa[4], const int arr_len[4], const int num_rounds, const Ipp32u* enc_keys[4], const Ipp8u* iv_pa[4])) +{ + int i; + int maxLen = 0; + int loc_len64[4]; + Ipp8u* loc_src[4]; + Ipp8u* loc_dst[4]; + + __mmask8 mbMask128[4] = { 0x03, 0x0C, 0x30, 0xC0 }; + __mmask8 mbMask[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + + for (i = 0; i < 4; i++) { + // The case of the empty input buffer + if (arr_len[i] == 0) + { + mbMask128[i] = 0; + mbMask[i] = 0; + loc_len64[i] = 0; + loc_src[i] = NULL; + loc_dst[i] = NULL; + continue; + } + loc_src[i] = (Ipp8u*)source_pa[i]; + loc_dst[i] = (Ipp8u*)dst_pa[i]; + int len64 = arr_len[i] / (Ipp32s)sizeof(Ipp64u); // length in 64-bit chunks + loc_len64[i] = len64; + + if (len64 < 8) + mbMask[i] = (__mmask8)(((1 << len64) - 1) & 0xFF); + if (len64 > maxLen) + maxLen = len64; + } + + // Load the necessary number of 128-bit IV + __m512i iv512 = _mm512_setzero_si512(); + iv512 = _mm512_mask_expandloadu_epi64(iv512, mbMask128[0], iv_pa[0]); // 0 0 0 IV1 + iv512 = _mm512_mask_expandloadu_epi64(iv512, mbMask128[1], iv_pa[1]); // 0 0 IV2 0 + iv512 = _mm512_mask_expandloadu_epi64(iv512, mbMask128[2], iv_pa[2]); // 0 IV3 0 0 + iv512 = _mm512_mask_expandloadu_epi64(iv512, mbMask128[3], iv_pa[3]); // IV4 0 0 0 + + // Temporary block to left IV unchanged to use it on the next round + __m512i chip0 = iv512; + + // Prepare array with key schedule + __m512i keySchedule[15]; + __m512i tmpKeyMb = _mm512_setzero_si512(); + for (i = 0; i <= num_rounds; i++) + { + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[0], (const void *)(enc_keys[0] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[1], (const void *)(enc_keys[1] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[2], (const void *)(enc_keys[2] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[3], (const void *)(enc_keys[3] + (Ipp32u)i * sizeof(Ipp32u))); + + keySchedule[i] = _mm512_loadu_si512(&tmpKeyMb); + } + + for (; maxLen >= 0; maxLen -= 8) + { + // Load plain text from the different buffers + __m512i b0 = _mm512_maskz_loadu_epi64(mbMask[0], loc_src[0]); loc_src[0] += CFB16_BLOCK_SIZE * 4; + __m512i b1 = _mm512_maskz_loadu_epi64(mbMask[1], loc_src[1]); loc_src[1] += CFB16_BLOCK_SIZE * 4; + __m512i b2 = _mm512_maskz_loadu_epi64(mbMask[2], loc_src[2]); loc_src[2] += CFB16_BLOCK_SIZE * 4; + __m512i b3 = _mm512_maskz_loadu_epi64(mbMask[3], loc_src[3]); loc_src[3] += CFB16_BLOCK_SIZE * 4; + + TRANSPOSE_4x4_I128(b0, b1, b2, b3); // {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} + + AES_ENCRYPT_VAES_MB16(chip0, keySchedule, num_rounds); + chip0 = b0 = _mm512_xor_si512(b0, chip0); + + AES_ENCRYPT_VAES_MB16(chip0, keySchedule, num_rounds); + chip0 = b1 = _mm512_xor_si512(b1, chip0); + + AES_ENCRYPT_VAES_MB16(chip0, keySchedule, num_rounds); + chip0 = b2 = _mm512_xor_si512(b2, chip0); + + AES_ENCRYPT_VAES_MB16(chip0, keySchedule, num_rounds); + chip0 = b3 = _mm512_xor_si512(b3, chip0); + + TRANSPOSE_4x4_I128(b0, b1, b2, b3); + + _mm512_mask_storeu_epi64(loc_dst[0], mbMask[0], b0); loc_dst[0] += CFB16_BLOCK_SIZE * 4; loc_len64[0] -= 2 * 4; UPDATE_MASK(loc_len64[0], mbMask[0]); + _mm512_mask_storeu_epi64(loc_dst[1], mbMask[1], b1); loc_dst[1] += CFB16_BLOCK_SIZE * 4; loc_len64[1] -= 2 * 4; UPDATE_MASK(loc_len64[1], mbMask[1]); + _mm512_mask_storeu_epi64(loc_dst[2], mbMask[2], b2); loc_dst[2] += CFB16_BLOCK_SIZE * 4; loc_len64[2] -= 2 * 4; UPDATE_MASK(loc_len64[2], mbMask[2]); + _mm512_mask_storeu_epi64(loc_dst[3], mbMask[3], b3); loc_dst[3] += CFB16_BLOCK_SIZE * 4; loc_len64[3] -= 2 * 4; UPDATE_MASK(loc_len64[3], mbMask[3]); + } +} + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma optimize( "", on ) +#endif + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb8.c b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb8.c new file mode 100644 index 000000000..68957e6bf --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_cfb_vaes_mb8.c @@ -0,0 +1,204 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "aes_cfb_vaes_mb.h" + +#if(_IPP32E>=_IPP32E_K1) + +#define AES_ENCRYPT_VAES_MB16(b0, b1, pRkey, num_rounds) { \ + __m512i (*tkeys)[2] = &pRkey[num_rounds-9]; \ + b0 = _mm512_xor_si512(b0, pRkey[0][0]); \ + b1 = _mm512_xor_si512(b1, pRkey[0][1]); \ + switch(num_rounds) { \ + case 14: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-4][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-4][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-3][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-3][1]); \ + case 12: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-2][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-2][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[-1][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[-1][1]); \ + default: \ + b0 = _mm512_aesenc_epi128(b0, tkeys[0][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[0][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[1][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[1][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[2][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[2][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[3][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[3][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[4][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[4][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[5][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[5][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[6][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[6][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[7][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[7][1]); \ + \ + b0 = _mm512_aesenc_epi128(b0, tkeys[8][0]); \ + b1 = _mm512_aesenc_epi128(b1, tkeys[8][1]); \ + \ + b0 = _mm512_aesenclast_epi128(b0, tkeys[9][0]); \ + b1 = _mm512_aesenclast_epi128(b1, tkeys[9][1]); \ + } \ +} + +// Disable optimization for MSVC +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma optimize( "", off ) +#endif + +IPP_OWN_DEFN (void, aes_cfb16_enc_vaes_mb8, (const Ipp8u* const source_pa[8], Ipp8u* const dst_pa[8], const int arr_len[8], const int num_rounds, const Ipp32u* enc_keys[8], const Ipp8u* iv_pa[8])) +{ + int i; + int maxLen = 0; + int loc_len64[8]; + Ipp8u* loc_src[8]; + Ipp8u* loc_dst[8]; + __m512i iv512[2]; + + __mmask8 mbMask128[8] = { 0x03, 0x0C, 0x30, 0xC0, 0x03, 0x0C, 0x30, 0xC0 }; + __mmask8 mbMask[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + + for (i = 0; i < 8; i++) { + // The case of the empty input buffer + if (arr_len[i] == 0) + { + mbMask128[i] = 0; + mbMask[i] = 0; + loc_len64[i] = 0; + loc_src[i] = NULL; + loc_dst[i] = NULL; + continue; + } + + loc_src[i] = (Ipp8u*)source_pa[i]; + loc_dst[i] = (Ipp8u*)dst_pa[i]; + int len64 = arr_len[i] / (Ipp32s)sizeof(Ipp64u); // length in 64-bit chunks + loc_len64[i] = len64; + + if (len64 < 8) + mbMask[i] = (__mmask8)(((1 << len64) - 1) & 0xFF); + if (len64 > maxLen) + maxLen = len64; + } + + // Load the necessary number of 128-bit IV + iv512[0] = _mm512_setzero_si512(); + iv512[0] = _mm512_mask_expandloadu_epi64(iv512[0], mbMask128[0], iv_pa[0]); + iv512[0] = _mm512_mask_expandloadu_epi64(iv512[0], mbMask128[1], iv_pa[1]); + iv512[0] = _mm512_mask_expandloadu_epi64(iv512[0], mbMask128[2], iv_pa[2]); + iv512[0] = _mm512_mask_expandloadu_epi64(iv512[0], mbMask128[3], iv_pa[3]); + + iv512[1] = _mm512_setzero_si512(); + iv512[1] = _mm512_mask_expandloadu_epi64(iv512[1], mbMask128[4], iv_pa[4]); + iv512[1] = _mm512_mask_expandloadu_epi64(iv512[1], mbMask128[5], iv_pa[5]); + iv512[1] = _mm512_mask_expandloadu_epi64(iv512[1], mbMask128[6], iv_pa[6]); + iv512[1] = _mm512_mask_expandloadu_epi64(iv512[1], mbMask128[7], iv_pa[7]); + + + // Temporary block to left IV unchanged to use it on the next round + __m512i chip0 = iv512[0]; + __m512i chip1 = iv512[1]; + + // Prepare array with key schedule + __m512i keySchedule[15][2]; + __m512i tmpKeyMb = _mm512_setzero_si512(); + + for (i = 0; i <= num_rounds; i++) + { + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[0], (const void *)(enc_keys[0] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[1], (const void *)(enc_keys[1] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[2], (const void *)(enc_keys[2] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[3], (const void *)(enc_keys[3] + (Ipp32u)i * sizeof(Ipp32u))); + + keySchedule[i][0] = _mm512_loadu_si512(&tmpKeyMb); + + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[4], (const void *)(enc_keys[4] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[5], (const void *)(enc_keys[5] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[6], (const void *)(enc_keys[6] + (Ipp32u)i * sizeof(Ipp32u))); + tmpKeyMb = _mm512_mask_expandloadu_epi64(tmpKeyMb, mbMask128[7], (const void *)(enc_keys[7] + (Ipp32u)i * sizeof(Ipp32u))); + + keySchedule[i][1] = _mm512_loadu_si512(&tmpKeyMb); + } + + for (; maxLen >= 0; maxLen -= 8) + { + // Load plain text from the different buffers + __m512i b0 = _mm512_maskz_loadu_epi64(mbMask[0], loc_src[0]); loc_src[0] += CFB16_BLOCK_SIZE * 4; + __m512i b1 = _mm512_maskz_loadu_epi64(mbMask[1], loc_src[1]); loc_src[1] += CFB16_BLOCK_SIZE * 4; + __m512i b2 = _mm512_maskz_loadu_epi64(mbMask[2], loc_src[2]); loc_src[2] += CFB16_BLOCK_SIZE * 4; + __m512i b3 = _mm512_maskz_loadu_epi64(mbMask[3], loc_src[3]); loc_src[3] += CFB16_BLOCK_SIZE * 4; + __m512i b4 = _mm512_maskz_loadu_epi64(mbMask[4], loc_src[4]); loc_src[4] += CFB16_BLOCK_SIZE * 4; + __m512i b5 = _mm512_maskz_loadu_epi64(mbMask[5], loc_src[5]); loc_src[5] += CFB16_BLOCK_SIZE * 4; + __m512i b6 = _mm512_maskz_loadu_epi64(mbMask[6], loc_src[6]); loc_src[6] += CFB16_BLOCK_SIZE * 4; + __m512i b7 = _mm512_maskz_loadu_epi64(mbMask[7], loc_src[7]); loc_src[7] += CFB16_BLOCK_SIZE * 4; + + TRANSPOSE_4x4_I128(b0, b1, b2, b3); // {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} + TRANSPOSE_4x4_I128(b4, b5, b6, b7); // {0,0,0,0}, {1,1,1,1}, {2,2,2,2}, {3,3,3,3} + + AES_ENCRYPT_VAES_MB16(chip0, chip1, keySchedule, num_rounds); + chip0 = b0 = _mm512_xor_si512(b0, chip0); + chip1 = b4 = _mm512_xor_si512(b4, chip1); + + AES_ENCRYPT_VAES_MB16(chip0, chip1, keySchedule, num_rounds); + chip0 = b1 = _mm512_xor_si512(b1, chip0); + chip1 = b5 = _mm512_xor_si512(b5, chip1); + + AES_ENCRYPT_VAES_MB16(chip0, chip1, keySchedule, num_rounds); + chip0 = b2 = _mm512_xor_si512(b2, chip0); + chip1 = b6 = _mm512_xor_si512(b6, chip1); + + AES_ENCRYPT_VAES_MB16(chip0, chip1, keySchedule, num_rounds); + chip0 = b3 = _mm512_xor_si512(b3, chip0); + chip1 = b7 = _mm512_xor_si512(b7, chip1); + + TRANSPOSE_4x4_I128(b0, b1, b2, b3); + TRANSPOSE_4x4_I128(b4, b5, b6, b7); + + _mm512_mask_storeu_epi64(loc_dst[0], mbMask[0], b0); loc_dst[0] += CFB16_BLOCK_SIZE * 4; loc_len64[0] -= 2 * 4; UPDATE_MASK(loc_len64[0], mbMask[0]); + _mm512_mask_storeu_epi64(loc_dst[1], mbMask[1], b1); loc_dst[1] += CFB16_BLOCK_SIZE * 4; loc_len64[1] -= 2 * 4; UPDATE_MASK(loc_len64[1], mbMask[1]); + _mm512_mask_storeu_epi64(loc_dst[2], mbMask[2], b2); loc_dst[2] += CFB16_BLOCK_SIZE * 4; loc_len64[2] -= 2 * 4; UPDATE_MASK(loc_len64[2], mbMask[2]); + _mm512_mask_storeu_epi64(loc_dst[3], mbMask[3], b3); loc_dst[3] += CFB16_BLOCK_SIZE * 4; loc_len64[3] -= 2 * 4; UPDATE_MASK(loc_len64[3], mbMask[3]); + _mm512_mask_storeu_epi64(loc_dst[4], mbMask[4], b4); loc_dst[4] += CFB16_BLOCK_SIZE * 4; loc_len64[4] -= 2 * 4; UPDATE_MASK(loc_len64[4], mbMask[4]); + _mm512_mask_storeu_epi64(loc_dst[5], mbMask[5], b5); loc_dst[5] += CFB16_BLOCK_SIZE * 4; loc_len64[5] -= 2 * 4; UPDATE_MASK(loc_len64[5], mbMask[5]); + _mm512_mask_storeu_epi64(loc_dst[6], mbMask[6], b6); loc_dst[6] += CFB16_BLOCK_SIZE * 4; loc_len64[6] -= 2 * 4; UPDATE_MASK(loc_len64[6], mbMask[6]); + _mm512_mask_storeu_epi64(loc_dst[7], mbMask[7], b7); loc_dst[7] += CFB16_BLOCK_SIZE * 4; loc_len64[7] -= 2 * 4; UPDATE_MASK(loc_len64[7], mbMask[7]); + } +} + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) + #pragma optimize( "", on ) +#endif + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_gcm_avx512.h b/plugin/ippcp/library/src/sources/ippcp/aes_gcm_avx512.h new file mode 100644 index 000000000..8c89bc413 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_gcm_avx512.h @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES GCM AVX512 +// Internal Functions Prototypes +// +*/ + +#ifndef __AES_GCM_AVX512_H_ +#define __AES_GCM_AVX512_H_ + +#include "owndefs.h" +#include "owncp.h" + +#include "aes_gcm_avx512_structures.h" + +#if(_IPP32E>=_IPP32E_K0) + +#define aes_gcm_enc_128_update_avx512 OWNAPI(aes_gcm_enc_128_update_avx512) + IPP_OWN_DECL (void, aes_gcm_enc_128_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_enc_192_update_avx512 OWNAPI(aes_gcm_enc_192_update_avx512) + IPP_OWN_DECL (void, aes_gcm_enc_192_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_enc_256_update_avx512 OWNAPI(aes_gcm_enc_256_update_avx512) + IPP_OWN_DECL (void, aes_gcm_enc_256_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) + +#define aes_gcm_dec_128_update_avx512 OWNAPI(aes_gcm_dec_128_update_avx512) + IPP_OWN_DECL (void, aes_gcm_dec_128_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_dec_192_update_avx512 OWNAPI(aes_gcm_dec_192_update_avx512) + IPP_OWN_DECL (void, aes_gcm_dec_192_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_dec_256_update_avx512 OWNAPI(aes_gcm_dec_256_update_avx512) + IPP_OWN_DECL (void, aes_gcm_dec_256_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) + +#define aes_gcm_gettag_128_avx512 OWNAPI(aes_gcm_gettag_128_avx512) + IPP_OWN_DECL (void, aes_gcm_gettag_128_avx512, (const struct gcm_key_data *key_data, const struct gcm_context_data *context_data, Ipp8u *auth_tag, Ipp64u auth_tag_len)) +#define aes_gcm_gettag_192_avx512 OWNAPI(aes_gcm_gettag_192_avx512) + IPP_OWN_DECL (void, aes_gcm_gettag_192_avx512, (const struct gcm_key_data *key_data, const struct gcm_context_data *context_data, Ipp8u *auth_tag, Ipp64u auth_tag_len)) +#define aes_gcm_gettag_256_avx512 OWNAPI(aes_gcm_gettag_256_avx512) + IPP_OWN_DECL (void, aes_gcm_gettag_256_avx512, (const struct gcm_key_data *key_data, const struct gcm_context_data *context_data, Ipp8u *auth_tag, Ipp64u auth_tag_len)) + +#define aes_gcm_precomp_128_avx512 OWNAPI(aes_gcm_precomp_128_avx512) + IPP_OWN_DECL (void, aes_gcm_precomp_128_avx512, (struct gcm_key_data *key_data)) +#define aes_gcm_precomp_192_avx512 OWNAPI(aes_gcm_precomp_192_avx512) + IPP_OWN_DECL (void, aes_gcm_precomp_192_avx512, (struct gcm_key_data *key_data)) +#define aes_gcm_precomp_256_avx512 OWNAPI(aes_gcm_precomp_256_avx512) + IPP_OWN_DECL (void, aes_gcm_precomp_256_avx512, (struct gcm_key_data *key_data)) + +#define aes_gcm_aad_hash_update_avx512 OWNAPI(aes_gcm_aad_hash_update_avx512) + IPP_OWN_DECL (void, aes_gcm_aad_hash_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *aad, const Ipp64u aad_len)) + +#define aes_gcm_iv_hash_update_avx512 OWNAPI(aes_gcm_iv_hash_update_avx512) + IPP_OWN_DECL (void, aes_gcm_iv_hash_update_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *iv, const Ipp64u iv_len)) +#define aes_gcm_iv_hash_finalize_avx512 OWNAPI(aes_gcm_iv_hash_finalize_avx512) + IPP_OWN_DECL (void, aes_gcm_iv_hash_finalize_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *iv, const Ipp64u iv_len, const Ipp64u iv_general_len)) + +#define aes_gcm_gmult_avx512 OWNAPI(aes_gcm_gmult_avx512) + IPP_OWN_DECL (void, aes_gcm_gmult_avx512, (const struct gcm_key_data *key_data, Ipp8u *ghash)) + +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_gcm_avx512_structures.h b/plugin/ippcp/library/src/sources/ippcp/aes_gcm_avx512_structures.h new file mode 100644 index 000000000..b604c5a11 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_gcm_avx512_structures.h @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES GCM otimized for AVX512 and AVX512-VAES features +// Internal Definitions +// +// +*/ + +#ifndef __AES_GCM_AVX512_STRUCTURES_H_ +#define __AES_GCM_AVX512_STRUCTURES_H_ + +#include "owndefs.h" +#include "owncp.h" + +// declaration of internal structures used for AVX512 AES GCM optimization + +/* GCM data structures */ +#define GCM_BLOCK_LEN 16 + +/** + * \brief holds GCM operation context + */ +struct gcm_context_data { + /* init, update and finalize context data */ + Ipp8u aad_hash[GCM_BLOCK_LEN]; + Ipp64u aad_length; + Ipp64u in_length; + Ipp8u partial_block_enc_key[GCM_BLOCK_LEN]; + Ipp8u orig_IV[GCM_BLOCK_LEN]; + Ipp8u current_counter[GCM_BLOCK_LEN]; + Ipp64u partial_block_length; +}; + +/* #define GCM_BLOCK_LEN 16 */ +#define GCM_ENC_KEY_LEN 16 +#define GCM_KEY_SETS (15) /*exp key + 14 exp round keys*/ + +/** + * \brief holds intermediate key data needed to improve performance + * + * gcm_key_data hold internal key information used by gcm128, gcm192 and gcm256. + */ +struct gcm_key_data { + Ipp8u expanded_keys[GCM_ENC_KEY_LEN * GCM_KEY_SETS]; + /* + * (HashKey<<1 mod poly), (HashKey^2<<1 mod poly), ..., + * (Hashkey^48<<1 mod poly) + */ + Ipp8u shifted_hkey[GCM_ENC_KEY_LEN * 48]; +} +#ifdef LINUX +__attribute__((aligned(64))); +#else +; +#endif + +#endif // __AES_GCM_AVX512_STRUCTURES_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_gcm_vaes.h b/plugin/ippcp/library/src/sources/ippcp/aes_gcm_vaes.h new file mode 100644 index 000000000..fa706d798 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_gcm_vaes.h @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES GCM AVX512-VAES +// Internal Functions Prototypes +// +*/ + +#ifndef __AES_GCM_VAES_H_ +#define __AES_GCM_VAES_H_ + +#include "owndefs.h" +#include "owncp.h" + +#include "aes_gcm_avx512_structures.h" + +#if(_IPP32E>=_IPP32E_K0) + +#define aes_gcm_enc_128_update_vaes_avx512 OWNAPI(aes_gcm_enc_128_update_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_enc_128_update_vaes_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_enc_192_update_vaes_avx512 OWNAPI(aes_gcm_enc_192_update_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_enc_192_update_vaes_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_enc_256_update_vaes_avx512 OWNAPI(aes_gcm_enc_256_update_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_enc_256_update_vaes_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) + +#define aes_gcm_dec_128_update_vaes_avx512 OWNAPI(aes_gcm_dec_128_update_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_dec_128_update_vaes_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_dec_192_update_vaes_avx512 OWNAPI(aes_gcm_dec_192_update_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_dec_192_update_vaes_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) +#define aes_gcm_dec_256_update_vaes_avx512 OWNAPI(aes_gcm_dec_256_update_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_dec_256_update_vaes_avx512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) + +#define aes_gcm_gettag_128_vaes_avx512 OWNAPI(aes_gcm_gettag_128_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_gettag_128_vaes_avx512, (const struct gcm_key_data *key_data, const struct gcm_context_data *context_data, Ipp8u *auth_tag, Ipp64u auth_tag_len)) +#define aes_gcm_gettag_192_vaes_avx512 OWNAPI(aes_gcm_gettag_192_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_gettag_192_vaes_avx512, (const struct gcm_key_data *key_data, const struct gcm_context_data *context_data, Ipp8u *auth_tag, Ipp64u auth_tag_len)) +#define aes_gcm_gettag_256_vaes_avx512 OWNAPI(aes_gcm_gettag_256_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_gettag_256_vaes_avx512, (const struct gcm_key_data *key_data, const struct gcm_context_data *context_data, Ipp8u *auth_tag, Ipp64u auth_tag_len)) + +#define aes_gcm_precomp_128_vaes_avx512 OWNAPI(aes_gcm_precomp_128_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_precomp_128_vaes_avx512, (struct gcm_key_data *key_data)) +#define aes_gcm_precomp_192_vaes_avx512 OWNAPI(aes_gcm_precomp_192_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_precomp_192_vaes_avx512, (struct gcm_key_data *key_data)) +#define aes_gcm_precomp_256_vaes_avx512 OWNAPI(aes_gcm_precomp_256_vaes_avx512) + IPP_OWN_DECL (void, aes_gcm_precomp_256_vaes_avx512, (struct gcm_key_data *key_data)) + +#define aes_gcm_aad_hash_update_vaes512 OWNAPI(aes_gcm_aad_hash_update_vaes512) + IPP_OWN_DECL (void, aes_gcm_aad_hash_update_vaes512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *aad, const Ipp64u aad_len)) + +#define aes_gcm_iv_hash_update_vaes512 OWNAPI(aes_gcm_iv_hash_update_vaes512) + IPP_OWN_DECL (void, aes_gcm_iv_hash_update_vaes512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *iv, const Ipp64u iv_len)) +#define aes_gcm_iv_hash_finalize_vaes512 OWNAPI(aes_gcm_iv_hash_finalize_vaes512) + IPP_OWN_DECL (void, aes_gcm_iv_hash_finalize_vaes512, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *iv, const Ipp64u iv_len, const Ipp64u iv_general_len)) + +#define aes_gcm_gmult_vaes512 OWNAPI(aes_gcm_gmult_vaes512) + IPP_OWN_DECL (void, aes_gcm_gmult_vaes512, (const struct gcm_key_data *key_data, Ipp8u *ghash)) + +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/aes_keyexp.h b/plugin/ippcp/library/src/sources/ippcp/aes_keyexp.h new file mode 100644 index 000000000..81e5d3f9c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/aes_keyexp.h @@ -0,0 +1,48 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES Key Expansion +// Internal Definitions +// +*/ + +#ifndef __AES_KEYEXP_H_ +#define __AES_KEYEXP_H_ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpaesauthgcm_avx512.h" + +// These functions for key expansion are used only with AVX512 and AVX512-VAES optimizations for AES GCM +// TODO: replase AVX2 keyexp with AVX512 keyexp +#if(_IPP32E>=_IPP32E_K0) + +#define aes_keyexp_128_enc OWNAPI(aes_keyexp_128_enc) + IPP_OWN_DECL (void, aes_keyexp_128_enc, (const Ipp8u* key, struct gcm_key_data *key_data)) +#define aes_keyexp_192_enc OWNAPI(aes_keyexp_192_enc) + IPP_OWN_DECL (void, aes_keyexp_192_enc, (const Ipp8u* key, struct gcm_key_data *key_data)) +#define aes_keyexp_256_enc OWNAPI(aes_keyexp_256_enc) + IPP_OWN_DECL (void, aes_keyexp_256_enc, (const Ipp8u* key, struct gcm_key_data *key_data)) + +#endif // (_IPP32E>=_IPP32E_K0) + +#endif // __AES_KEYEXP_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/cpinitas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/cpinitas.asm new file mode 100644 index 000000000..7209f0c53 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/cpinitas.asm @@ -0,0 +1,733 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%assign LOCAL_ALIGN_FACTOR 32 + +segment .text align=LOCAL_ALIGN_FACTOR + +%ifdef _IPP_DATA + +;#################################################################### +;# void ownGetReg( int* buf, int valueEAX, int valueECX ); # +;#################################################################### + +%define buf [esp+12] +%define valueEAX [esp+16] +%define valueECX [esp+20] + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpGetReg,PUBLIC + + push ebx + push esi + mov eax, valueEAX + mov ecx, valueECX + xor ebx, ebx + xor edx, edx + mov esi, buf + cpuid + mov [esi], eax + mov [esi + 4], ebx + mov [esi + 8], ecx + mov [esi + 12], edx + pop esi + pop ebx + ret +ENDFUNC cpGetReg + +;################################################### + +; Feature information after XGETBV(ECX=0), EAX, bits 2,1 ( XMM state and YMM state are enabled by OS ) +%assign XGETBV_MASK 06h +; OSXSAVE support, feature information after cpuid(1), ECX, bit 27 ( XGETBV is enabled by OS ) +%assign XSAVEXGETBV_FLAG 8000000h +%assign XGETBV_AVX512_MASK 0E0h + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cp_is_avx_extension,PUBLIC + USES_GPR ebx,edx,ecx + mov eax, 1 + cpuid + xor eax, eax + and ecx, 018000000h + cmp ecx, 018000000h + jne .not_avx + xor ecx, ecx + db 00fh,001h,0d0h ; xgetbv + mov ecx, eax + xor eax, eax + and ecx, XGETBV_MASK + cmp ecx, XGETBV_MASK + jne .not_avx + mov eax, 1 +.not_avx: + REST_GPR + ret +ENDFUNC cp_is_avx_extension + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cp_is_avx512_extension,PUBLIC + USES_GPR ebx,edx,ecx + mov eax, 1 + cpuid + xor eax, eax + and ecx, XSAVEXGETBV_FLAG + cmp ecx, XSAVEXGETBV_FLAG + jne .not_avx512 + xor ecx, ecx + db 00fh,001h,0d0h ; xgetbv + mov ecx, eax + xor eax, eax + and ecx, XGETBV_AVX512_MASK + cmp ecx, XGETBV_AVX512_MASK + jne .not_avx512 + mov eax, 1 +.not_avx512: + REST_GPR + ret +ENDFUNC cp_is_avx512_extension + +%ifdef LINUX32 + %ifndef OSX32 + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC __ashldi3,PUBLIC,WEAK + mov eax, [esp+4] + mov edx, [esp+8] + mov ecx, [esp+12] + test cl, 20H + je .less + mov edx, eax + xor eax, eax + shl edx, cl + ret +.less: + shld edx, eax, cl + shl eax, cl + ret +ENDFUNC __ashldi3 + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC __ashrdi3,PUBLIC,WEAK + mov eax, [esp+4] + mov edx, [esp+8] + mov ecx, [esp+12] + test cl, 20H + je .less + mov eax, edx + sar edx, 1FH + sar eax, cl + ret +.less: + shrd eax, edx, cl + sar edx, cl + ret +ENDFUNC __ashrdi3 + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC __divdi3,PUBLIC,WEAK + xor ecx, ecx + mov eax, dword [8+esp] + or eax, eax + jge .Apositive + mov ecx, 1 + mov edx, dword [4+esp] + neg eax + neg edx + sbb eax, 0 + mov dword [4+esp], edx + mov dword [8+esp], eax +.Apositive: + mov eax, dword [16+esp] + or eax,eax + jge .ABpositive + sub ecx, 1 + mov edx, dword [12+esp] + neg eax + neg edx + sbb eax, 0 + mov dword [12+esp], edx + mov dword [16+esp], eax +.ABpositive: + mov eax, dword [16+esp] + xor edx, edx + push ecx + test eax, eax + jne .non_zero_hi + mov eax, dword [12+esp] + div dword [16+esp] + mov ecx, eax + mov eax, dword [8+esp] + div dword [16+esp] + mov edx, ecx + jmp .return +.non_zero_hi: + mov ecx, dword [12+esp] + cmp eax, ecx + jb .divisor_greater + jne .return_zero + mov ecx, dword [16+esp] + mov eax, dword [8+esp] + cmp ecx, eax + ja .return_zero +.return_one: + mov eax, 1 + jmp .return +.return_zero: + add esp, 4 + xor eax, eax + ret +.divisor_greater: + test eax, 80000000h + jne .return_one +.find_hi_bit: + bsr ecx, eax + add ecx, 1 +.hi_bit_found: + mov edx, dword [16+esp] + push ebx + shrd edx, eax, cl + mov ebx, edx + mov eax, dword [12+esp] + mov edx, dword [16+esp] + shrd eax, edx, cl + shr edx, cl +.make_div: + div ebx + mov ebx, eax + mul dword [24+esp] + mov ecx, eax + mov eax, dword [20+esp] + mul ebx + add edx, ecx + jb .need_dec + cmp dword [16+esp], edx + jb .need_dec + ja .after_dec + cmp dword [12+esp], eax + jae .after_dec +.need_dec: + sub ebx, 1 +.after_dec: + xor edx, edx + mov eax, ebx + pop ebx +.return: + pop ecx + test ecx, ecx + jne .ch_sign + ret +.ch_sign: + neg edx + neg eax + sbb edx, 0 + ret +ENDFUNC __divdi3 + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC __udivdi3,PUBLIC,WEAK + xor ecx,ecx +.ABpositive: + mov eax, dword [16+esp] + xor edx, edx + push ecx + test eax, eax + jne .non_zero_hi + mov eax, dword [12+esp] + div dword [16+esp] + mov ecx, eax + mov eax, dword [8+esp] + div dword [16+esp] + mov edx, ecx + jmp .return +.non_zero_hi: + mov ecx, dword [12+esp] + cmp eax, ecx + jb .divisor_greater + jne .return_zero + mov ecx, dword [16+esp] + mov eax, dword [8+esp] + cmp ecx, eax + ja .return_zero +.return_one: + mov eax, 1 + jmp .return +.return_zero: + add esp, 4 + xor eax, eax + ret +.divisor_greater: + test eax, 80000000h + jne .return_one +.find_hi_bit: + bsr ecx, eax + add ecx, 1 +.hi_bit_found: + mov edx, dword [16+esp] + push ebx + shrd edx, eax, cl + mov ebx, edx + mov eax, dword [12+esp] + mov edx, dword [16+esp] + shrd eax, edx, cl + shr edx, cl +.make_div: + div ebx + mov ebx, eax + mul dword [24+esp] + mov ecx, eax + mov eax, dword [20+esp] + mul ebx + add edx, ecx + jb .need_dec + cmp dword [16+esp], edx + jb .need_dec + ja .after_dec + cmp dword [12+esp], eax + jae .after_dec +.need_dec: + sub ebx, 1 +.after_dec: + xor edx, edx + mov eax, ebx + pop ebx +.return: + pop ecx + test ecx, ecx + jne .ch_sign + ret +.ch_sign: + neg edx + neg eax + sbb edx, 0 + ret +ENDFUNC __udivdi3 + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC __moddi3,PUBLIC,WEAK + sub esp, 8 + mov dword [esp], 0 + mov eax, dword [esp+16] + or eax, eax + jge .Apositive + inc dword [esp] + mov edx, dword [esp+12] + neg eax + neg edx + sbb eax, 0 + mov dword [esp+16], eax + mov dword [esp+12], edx + +.Apositive: + mov eax, dword [esp+24] + or eax, eax + jge .ABpositive + mov edx, dword [esp+20] + neg eax + neg edx + sbb eax, 0 + mov dword [esp+24], eax + mov dword [esp+20], edx + jmp .ABpositive + lea esi, [esi] + lea edi, [edi] + + sub esp, 8 + mov dword [esp], 0 + +.ABpositive: + mov eax, dword [esp+24] + test eax, eax + jne .non_zero_hi + mov eax, dword [esp+16] + mov edx, 0 + div dword [esp+20] + mov ecx, eax + mov eax, dword [12+esp] + div dword [20+esp] + mov eax, edx + xor edx, edx + jmp .return + +.non_zero_hi: + mov ecx, dword [16+esp] + cmp eax, ecx + jb .divisor_greater + jne .return_devisor + mov ecx, dword [20+esp] + cmp ecx, dword [12+esp] + ja .return_devisor + +.return_dif: + mov eax, dword [12+esp] + mov edx, dword [16+esp] + sub eax, dword [20+esp] + sbb edx, dword [24+esp] + jmp .return + +.return_devisor: + mov eax, dword [12+esp] + mov edx, dword [16+esp] + jmp .return + +.divisor_greater: + test eax, 80000000h + jne .return_dif + +.find_hi_bit: + bsr ecx, eax + add ecx, 1 + +.hi_bit_found: + push ebx + mov edx, dword [24+esp] + shrd edx, eax, cl + mov ebx, edx + mov eax, dword [16+esp] + mov edx, dword [20+esp] + shrd eax, edx, cl + shr edx, cl + div ebx + mov ebx, eax + +.multiple: + mul dword [28+esp] + mov ecx, eax + mov eax, dword [24+esp] + mul ebx + add edx, ecx + jb .need_dec + cmp dword [20+esp], edx + jb .need_dec + ja .after_dec + cmp dword [16+esp], eax + jb .need_dec + +.after_dec: + mov ebx, eax + mov eax, dword [16+esp] + sub eax, ebx + mov ebx, edx + mov edx, dword [20+esp] + sbb edx, ebx + pop ebx + +.return: + mov dword [4+esp], eax + mov eax, dword [esp] + test eax, eax + jne .ch_sign + mov eax, dword [4+esp] + add esp, 8 + ret + +.ch_sign: + mov eax, dword [4+esp] + neg edx + neg eax + sbb edx, 0 + add esp, 8 + ret + +.need_dec: + dec ebx + mov eax, ebx + jmp .multiple +ENDFUNC __moddi3 + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC __umoddi3,PUBLIC,WEAK + sub esp, 8 + mov dword [esp], 0 + +.ABpositive: + mov eax, dword [esp+24] + test eax, eax + jne .non_zero_hi + mov eax, dword [esp+16] + mov edx, 0 + div dword [esp+20] + mov ecx, eax + mov eax, dword [12+esp] + div dword [20+esp] + mov eax, edx + xor edx, edx + jmp .return + +.non_zero_hi: + mov ecx, dword [16+esp] + cmp eax, ecx + jb .divisor_greater + jne .return_devisor + mov ecx, dword [20+esp] + cmp ecx, dword [12+esp] + ja .return_devisor + +.return_dif: + mov eax, dword [12+esp] + mov edx, dword [16+esp] + sub eax, dword [20+esp] + sbb edx, dword [24+esp] + jmp .return + +.return_devisor: + mov eax, dword [12+esp] + mov edx, dword [16+esp] + jmp .return + +.divisor_greater: + test eax, 80000000h + jne .return_dif + +.find_hi_bit: + bsr ecx, eax + add ecx, 1 + +.hi_bit_found: + push ebx + mov edx, dword [24+esp] + shrd edx, eax, cl + mov ebx, edx + mov eax, dword [16+esp] + mov edx, dword [20+esp] + shrd eax, edx, cl + shr edx, cl + div ebx + mov ebx, eax + +.multiple: + mul dword [28+esp] + mov ecx, eax + mov eax, dword [24+esp] + mul ebx + add edx, ecx + jb .need_dec + cmp dword [20+esp], edx + jb .need_dec + ja .after_dec + cmp dword [16+esp], eax + jb .need_dec + +.after_dec: + mov ebx, eax + mov eax, dword [16+esp] + sub eax, ebx + mov ebx, edx + mov edx, dword [20+esp] + sbb edx, ebx + pop ebx + +.return: + mov dword [4+esp], eax + mov eax, dword [esp] + test eax, eax + jne .ch_sign + mov eax, dword [4+esp] + add esp, 8 + ret + +.ch_sign: + mov eax, dword [4+esp] + neg edx + neg eax + sbb edx, 0 + add esp, 8 + ret + +.need_dec: + dec ebx + mov eax, ebx + jmp .multiple +ENDFUNC __umoddi3 + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC __muldi3,PUBLIC,WEAK + mov eax, dword [esp+8] + mul dword [esp+12] + mov ecx, eax + mov eax, dword [esp+4] + mul dword [esp+16] + add ecx, eax + mov eax, dword [esp+4] + mul dword [esp+12] + add edx, ecx + ret +ENDFUNC __muldi3 + + %endif; IFNDEF OSX32 +%endif; IFDEF LINUX32 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cp_get_pentium_counter,PUBLIC + rdtsc + ret +ENDFUNC cp_get_pentium_counter + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStartTscp,PUBLIC + push ebx + xor eax, eax + cpuid + pop ebx + rdtscp + ret +ENDFUNC cpStartTscp + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStopTscp,PUBLIC + rdtscp + push eax + push edx + push ebx + xor eax, eax + cpuid + pop ebx + pop edx + pop eax + ret +ENDFUNC cpStopTscp + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStartTsc,PUBLIC + push ebx + xor eax, eax + cpuid + pop ebx + rdtsc + ret +ENDFUNC cpStartTsc + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStopTsc,PUBLIC + rdtsc + push eax + push edx + push ebx + xor eax, eax + cpuid + pop ebx + pop edx + pop eax + ret +ENDFUNC cpStopTsc + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;***************************************** +; int cpGetCacheSize( int* tableCache ); +align LOCAL_ALIGN_FACTOR +%define table [36+esp] +DECLARE_FUNC cpGetCacheSize,PUBLIC + push edi + push esi + push ebx + push ebp + sub esp, 16 + + mov edi, table + mov ebp, esp + xor esi, esi + + mov eax, 2 + cpuid + + cmp al, 1 + jne .GetCacheSize_11 + + test eax, 080000000h + jz .GetCacheSize_00 + xor eax, eax +.GetCacheSize_00: + test ebx, 080000000h + jz .GetCacheSize_01 + xor ebx, ebx +.GetCacheSize_01: + test ecx, 080000000h + jz .GetCacheSize_02 + xor ecx, ecx +.GetCacheSize_02: + test edx, 080000000h + jz .GetCacheSize_03 + xor edx, edx + +.GetCacheSize_03: + test eax, eax + jz .GetCacheSize_04 + mov [ebp], eax + add ebp, 4 + add esi, 3 +.GetCacheSize_04: + test ebx, ebx + jz .GetCacheSize_05 + mov [ebp], ebx + add ebp, 4 + add esi, 4 +.GetCacheSize_05: + test ecx, ecx + jz .GetCacheSize_06 + mov [ebp], ecx + add ebp, 4 + add esi, 4 +.GetCacheSize_06: + test edx, edx + jz .GetCacheSize_07 + mov [ebp], edx + add esi, 4 + +.GetCacheSize_07: + test esi, esi + jz .GetCacheSize_11 + mov eax, -1 +.GetCacheSize_08: + xor edx, edx + add edx, [edi] + jz .ExitGetCacheSize00 + add edi, 8 + mov ecx, esi +.GetCacheSize_09: + cmp dl, BYTE [esp + ecx] + je .GetCacheSize_10 + dec ecx + jnz .GetCacheSize_09 + jmp .GetCacheSize_08 + +.GetCacheSize_10: + mov eax, [edi - 4] + +.ExitGetCacheSize00: + add esp, 16 + pop ebp + pop ebx + pop esi + pop edi + ret + +.GetCacheSize_11: + mov eax, -1 + jmp .ExitGetCacheSize00 +ENDFUNC cpGetCacheSize + +; ***************************************** + +%endif ; IPP_DATA diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/emulator.inc b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/emulator.inc new file mode 100644 index 000000000..667b3f9a2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/emulator.inc @@ -0,0 +1,441 @@ +;=============================================================================== +; Copyright (C) 2009 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: x86 Cryptography Primitive. +; +; +; + +%macro my_pclmulqdq 3.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + %define %%xxOp %3 + +%if (my_emulator == 0) + pclmulqdq %%xxDst, %%xxSrc, %%xxOp +%else +;;;; esp => &p1 +;; +4 => &p2 +;; +8 => p3 +;; +12 => p2 (16 bytes) +;; +28 => p1 (16 bytes) +;; +44 => eax + + %assign %%stackSize (4+4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+44], eax ;; save eax + mov dword [esp+48], ebx ;; save ebx + mov dword [esp+52], ecx ;; save ecx + mov dword [esp+56], edx ;; save edx + mov dword [esp+60], esi ;; save esi + mov dword [esp+64], edi ;; save edi + + movdqu oword [esp+28], %%xxDst ;; store mmDst + movdqu oword [esp+12], %%xxSrc ;; store mmSrc + mov dword [esp+8], %%xxOp ;; put p3 (mmOp) into the stack + lea eax, [esp+28] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+12] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_pclmulqdq + movdqu %%xxDst, oword [esp+28] ;; load result + + mov eax, dword [esp+44] ;; restore eax + mov ebx, dword [esp+48] ;; restore ebx + mov ecx, dword [esp+52] ;; restore ecx + mov edx, dword [esp+56] ;; restore edx + mov esi, dword [esp+60] ;; restore esi + mov edi, dword [esp+64] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + +%macro my_palignr 3.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + %define %%xxOp %3 + +%if (my_emulator == 0) + palignr %%xxDst, %%xxSrc, %%xxOp +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p3 +;; +12 => p2 (16 bytes) +;; +28 => p1 (16 bytes) +;; +44 => eax + + %assign %%stackSize (4+4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+44], eax ;; save eax + mov dword [esp+48], ebx ;; save ebx + mov dword [esp+52], ecx ;; save ecx + mov dword [esp+56], edx ;; save edx + mov dword [esp+60], esi ;; save esi + mov dword [esp+64], edi ;; save edi + + movdqu oword [esp+28], %%xxDst ;; store mmDst + movdqu oword [esp+12], %%xxSrc ;; store mmSrc + mov dword [esp+8], %%xxOp ;; put p3 (mmOp) into the stack + lea eax, [esp+28] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+12] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_palignr + movdqu %%xxDst, oword [esp+28] ;; load result + + mov eax, dword [esp+44] ;; restore eax + mov ebx, dword [esp+48] ;; restore ebx + mov ecx, dword [esp+52] ;; restore ecx + mov edx, dword [esp+56] ;; restore edx + mov esi, dword [esp+60] ;; restore esi + mov edi, dword [esp+64] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + +%macro my_pshufd 3.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + %define %%xxOp %3 + +%if (my_emulator == 0) + pshufd %%xxDst, %%xxSrc, %%xxOp +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p3 +;; +12 => p2 (16 bytes) +;; +28 => p1 (16 bytes) +;; +44 => eax + + %assign %%stackSize (4+4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+44], eax ;; save eax + mov dword [esp+48], ebx ;; save ebx + mov dword [esp+52], ecx ;; save ecx + mov dword [esp+56], edx ;; save edx + mov dword [esp+60], esi ;; save esi + mov dword [esp+64], edi ;; save edi + + movdqu oword [esp+28], %%xxDst ;; store mmDst + movdqu oword [esp+12], %%xxSrc ;; store mmSrc + mov dword [esp+8], %%xxOp ;; put p3 (mmOp) into the stack + lea eax, [esp+28] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+12] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_pshufd + movdqu %%xxDst, oword [esp+28] ;; load result + + mov eax, dword [esp+44] ;; restore eax + mov ebx, dword [esp+48] ;; restore ebx + mov ecx, dword [esp+52] ;; restore ecx + mov edx, dword [esp+56] ;; restore edx + mov esi, dword [esp+60] ;; restore esi + mov edi, dword [esp+64] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + + +%macro my_pshufb 2.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + +%if (my_emulator == 0) + pshufb %%xxDst, %%xxSrc +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p2 (16 bytes) +;; +24 => p1 (16 bytes) +;; +40 => eax + + %assign %%stackSize (4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+40], eax ;; save eax + mov dword [esp+44], ebx ;; save ebx + mov dword [esp+48], ecx ;; save ecx + mov dword [esp+52], edx ;; save edx + mov dword [esp+56], esi ;; save esi + mov dword [esp+60], edi ;; save edi + + movdqu oword [esp+24], %%xxDst ;; store mmDst + movdqu oword [esp+8], %%xxSrc ;; store mmSrc + lea eax, [esp+24] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+8] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_pshufb + movdqu %%xxDst, oword [esp+24] ;; load result + + mov eax, dword [esp+40] ;; restore eax + mov ebx, dword [esp+44] ;; restore ebx + mov ecx, dword [esp+48] ;; restore ecx + mov edx, dword [esp+52] ;; restore edx + mov esi, dword [esp+56] ;; restore esi + mov edi, dword [esp+60] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + +%macro my_pshufbM 2.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + +%if (my_emulator == 0) + pshufb %%xxDst, %%xxSrc +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p2 (16 bytes) +;; +24 => p1 (16 bytes) +;; +40 => eax + + %assign %%stackSize (4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+40], eax ;; save eax + mov dword [esp+44], ebx ;; save ebx + mov dword [esp+48], ecx ;; save ecx + mov dword [esp+52], edx ;; save edx + mov dword [esp+56], esi ;; save esi + mov dword [esp+60], edi ;; save edi + + movdqu oword [esp+24], %%xxDst ;; store mmDst + movdqu %%xxDst, %%xxSrc + movdqu oword [esp+8], %%xxDst ;; store mmSrc + lea eax, [esp+24] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+8] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_pshufb + movdqu %%xxDst, oword [esp+24] ;; load result + + mov eax, dword [esp+40] ;; restore eax + mov ebx, dword [esp+44] ;; restore ebx + mov ecx, dword [esp+48] ;; restore ecx + mov edx, dword [esp+52] ;; restore edx + mov esi, dword [esp+56] ;; restore esi + mov edi, dword [esp+60] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + +%macro my_aesenc 2.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + +%if (my_emulator == 0) + aesenc %%xxDst, %%xxSrc +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p1 (16 bytes) +;; +24 => p2 (16 bytes) +;; +40 => eax + + %assign %%stackSize (4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+40], eax ;; save eax + mov dword [esp+44], ebx ;; save ebx + mov dword [esp+48], ecx ;; save ecx + mov dword [esp+52], edx ;; save edx + mov dword [esp+56], esi ;; save esi + mov dword [esp+60], edi ;; save edi + + movdqu oword [esp+8], %%xxDst ;; store mmDst + movdqu oword [esp+24], %%xxSrc ;; store mmSrc + lea eax, [esp+8] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+24] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_aesenc + movdqu %%xxDst, oword [esp+8] ;; load result + + mov eax, dword [esp+40] ;; restore eax + mov ebx, dword [esp+44] ;; restore ebx + mov ecx, dword [esp+48] ;; restore ecx + mov edx, dword [esp+52] ;; restore edx + mov esi, dword [esp+56] ;; restore esi + mov edi, dword [esp+60] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + +%macro my_aesenclast 2.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + +%if (my_emulator == 0) + aesenclast %%xxDst, %%xxSrc +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p1 (16 bytes) +;; +24 => p2 (16 bytes) +;; +40 => eax + + %assign %%stackSize (4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+40], eax ;; save eax + mov dword [esp+44], ebx ;; save ebx + mov dword [esp+48], ecx ;; save ecx + mov dword [esp+52], edx ;; save edx + mov dword [esp+56], esi ;; save esi + mov dword [esp+60], edi ;; save edi + + movdqu oword [esp+8], %%xxDst ;; store mmDst + movdqu oword [esp+24], %%xxSrc ;; store mmSrc + lea eax, [esp+8] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+24] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_aesenclast + movdqu %%xxDst, oword [esp+8] ;; load result + + mov eax, dword [esp+40] ;; restore eax + mov ebx, dword [esp+44] ;; restore ebx + mov ecx, dword [esp+48] ;; restore ecx + mov edx, dword [esp+52] ;; restore edx + mov esi, dword [esp+56] ;; restore esi + mov edi, dword [esp+60] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + + +%macro my_aesdec 2.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + +%if (my_emulator == 0) + aesdec %%xxDst, %%xxSrc +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p1 (16 bytes) +;; +24 => p2 (16 bytes) +;; +40 => eax + + %assign %%stackSize (4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+40], eax ;; save eax + mov dword [esp+44], ebx ;; save ebx + mov dword [esp+48], ecx ;; save ecx + mov dword [esp+52], edx ;; save edx + mov dword [esp+56], esi ;; save esi + mov dword [esp+60], edi ;; save edi + + movdqu oword [esp+8], %%xxDst ;; store mmDst + movdqu oword [esp+24], %%xxSrc ;; store mmSrc + lea eax, [esp+8] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+24] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_aesdec + movdqu %%xxDst, oword [esp+8] ;; load result + + mov eax, dword [esp+40] ;; restore eax + mov ebx, dword [esp+44] ;; restore ebx + mov ecx, dword [esp+48] ;; restore ecx + mov edx, dword [esp+52] ;; restore edx + mov esi, dword [esp+56] ;; restore esi + mov edi, dword [esp+60] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + +%macro my_aesdeclast 2.nolist + %define %%xxDst %1 + %define %%xxSrc %2 + +%if (my_emulator == 0) + aesdeclast %%xxDst, %%xxSrc +%else +;; +;; esp => &p1 +;; +4 => &p2 +;; +8 => p1 (16 bytes) +;; +24 => p2 (16 bytes) +;; +40 => eax + + %assign %%stackSize (4+4)+(16+16)+(4+4+4+4+4+4) + sub esp,%%stackSize + + mov dword [esp+40], eax ;; save eax + mov dword [esp+44], ebx ;; save ebx + mov dword [esp+48], ecx ;; save ecx + mov dword [esp+52], edx ;; save edx + mov dword [esp+56], esi ;; save esi + mov dword [esp+60], edi ;; save edi + + movdqu oword [esp+8], %%xxDst ;; store mmDst + movdqu oword [esp+24], %%xxSrc ;; store mmSrc + lea eax, [esp+8] ;; &p1 (&mmSrc) + mov dword [esp], eax ;; put &p1 into the stack + lea eax, [esp+24] ;; &p2 + mov dword [esp+4], eax ;; put &p2 into the stack + + call emu_aesdeclast + movdqu %%xxDst, oword [esp+8] ;; load result + + mov eax, dword [esp+40] ;; restore eax + mov ebx, dword [esp+44] ;; restore ebx + mov ecx, dword [esp+48] ;; restore ecx + mov edx, dword [esp+52] ;; restore edx + mov esi, dword [esp+56] ;; restore esi + mov edi, dword [esp+60] ;; restore edi + add esp, %%stackSize +%endif +%endmacro + +%if (my_emulator != 0) + extern emu_pclmulqdq + extern emu_palignr + extern emu_pshufd + extern emu_pshufb + extern emu_aesenc + extern emu_aesenclast + extern emu_aesdec + extern emu_aesdeclast +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpaesgcmg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpaesgcmg9as.asm new file mode 100644 index 000000000..6f19e77a8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpaesgcmg9as.asm @@ -0,0 +1,875 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; AES-GCM function +; +; Content: +; AesGcmPrecompute_avx() +; AesGcmMulGcm_avx() +; AesGcmAuth_avx() +; AesGcmEnc_avx() +; AesGcmDec_avx() +; +; +; + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%assign my_emulator 0; set 1 for emulation +%include "emulator.inc" + +;; +;; a = a*b mod g(x), g(x) = x^128 + x^7 + x^2 +x +1 +;; +%macro sse_clmul_gcm 5.nolist + %xdefine %%GH %1 + %xdefine %%HK %2 + %xdefine %%tmpX0 %3 + %xdefine %%tmpX1 %4 + %xdefine %%tmpX2 %5 + + ;; GH, HK hold the values for the two operands which are carry-less multiplied + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Karatsuba Method + ;; + ;; GH = [GH1:GH0] + ;; HK = [HK1:HK0] + ;; + pshufd %%tmpX2, %%GH, 01001110b ;; xmm2 = {GH0:GH1} + pshufd %%tmpX0, %%HK, 01001110b ;; xmm0 = {HK0:HK1} + pxor %%tmpX2, %%GH ;; xmm2 = {GH0+GH1:GH1+GH0} + pxor %%tmpX0, %%HK ;; xmm0 = {HK0+HK1:HK1+HK0} + +my_pclmulqdq %%tmpX2, %%tmpX0,00h ;; tmpX2 = (a1+a0)*(b1+b0) xmm2 = (GH1+GH0)*(HK1+HK0) + movdqa %%tmpX1, %%GH +my_pclmulqdq %%GH, %%HK, 00h ;; GH = a0*b0 GH = GH0*HK0 + pxor %%tmpX0, %%tmpX0 +my_pclmulqdq %%tmpX1, %%HK, 11h ;; tmpX1 = a1*b1 xmm1 = GH1*HK1 + pxor %%tmpX2, %%GH ;; xmm2 = (GH1+GH0)*(HK1+HK0) + GH0*HK0 + pxor %%tmpX2, %%tmpX1 ;; tmpX2 = a0*b1+a1*b0 xmm2 = (GH1+GH0)*(HK1+HK0) + GH0*HK0 + GH1*HK1 = GH0*HK1+GH1*HK0 + + palignr %%tmpX0, %%tmpX2, 8 ;; tmpX0 = {Zeros : HI(a0*b1+a1*b0)} + pslldq %%tmpX2, 8 ;; tmpX2 = {LO(HI(a0*b1+a1*b0)) : Zeros} + pxor %%tmpX1, %%tmpX0 ;; holds the result of the carry-less multiplication of GH by HK + pxor %%GH, %%tmpX2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction: + ; Most( (product_H * g1), 128)) product_H = GH + ; g1 = 2^256/g = g = 1+x+x^2+x^7+x^128 + ; + movdqa %%tmpX0, %%GH + psllq %%tmpX0, 1 ; GH<<1 + pxor %%tmpX0, %%GH + psllq %%tmpX0, 5 ; ((GH<<1) ^ GH)<<5 + pxor %%tmpX0, %%GH + psllq %%tmpX0, 57 ; (((GH<<1) ^ GH)<<5) ^ GH)<<57 <==> GH<<63 ^ GH<<62 ^ GH<<57 + + movdqa %%tmpX2, %%tmpX0 + pslldq %%tmpX2, 8 ; shift-L tmpX2 2 DWs + psrldq %%tmpX0, 8 ; shift-R xmm2 2 DWs + + pxor %%GH, %%tmpX2 ; first phase of the reduction complete + pxor %%tmpX1, %%tmpX0 ; save the lost MS 1-2-7 bits from first phase + + ;second phase of the reduction + movdqa %%tmpX2, %%GH ; move GH into xmm15 + psrlq %%tmpX2, 5 ; packed right shifting >> 5 + pxor %%tmpX2, %%GH ; xor shifted versions + psrlq %%tmpX2, 1 ; packed right shifting >> 1 + pxor %%tmpX2, %%GH ; xor shifted versions + psrlq %%tmpX2, 1 ; packed right shifting >> 1 + + pxor %%GH, %%tmpX2 ; second phase of the reduction complete + pxor %%GH, %%tmpX1 ; the result is in GH +%endmacro + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +CONST_TABLE: +_poly DQ 00000000000000001h,0C200000000000000h ;; 0xC2000000000000000000000000000001 +_twoone DQ 00000000000000001h,00000000100000000h ;; 0x00000001000000000000000000000001 +_u128_str DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +_mask1 DQ 0ffffffffffffffffh,00000000000000000h ;; 0x0000000000000000ffffffffffffffff +_mask2 DQ 00000000000000000h,0ffffffffffffffffh ;; 0xffffffffffffffff0000000000000000 +_inc1 DQ 1,0 + +%xdefine POLY [esi+(_poly - CONST_TABLE)] +%xdefine TWOONE [esi+(_twoone - CONST_TABLE)] +%xdefine u128_str [esi+(_u128_str - CONST_TABLE)] +%xdefine MASK1 [esi+(_mask1 - CONST_TABLE)] +%xdefine MASK2 [esi+(_mask2 - CONST_TABLE)] +%xdefine inc1 [esi+(_inc1 - CONST_TABLE)] + +%assign sizeof_oword_ (16) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; void GCMpipePrecomute(const Ipp8u* pRefHkey, Ipp8u* pMultipliers); +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmPrecompute_avx,PUBLIC + USES_GPR esi + +%xdefine pHkey [esp + ARG_1 + 0*sizeof(dword)] ; pointer to the reflected hkey +%xdefine pMultipliers [esp + ARG_1 + 1*sizeof(dword)] ; output to the precomputed multipliers + + LD_ADDR esi, CONST_TABLE + + mov eax, pHkey + movdqu xmm0, oword [eax] ; xmm0 holds HashKey + pshufb xmm0, u128_str + + ; precompute HashKey<<1 mod poly from the HashKey + movdqa xmm4, xmm0 + psllq xmm0, 1 + psrlq xmm4, 63 + movdqa xmm3, xmm4 + pslldq xmm4, 8 + psrldq xmm3, 8 + por xmm0, xmm4 + ;reduction + pshufd xmm4, xmm3, 00100100b + pcmpeqd xmm4, oword TWOONE ; TWOONE = 0x00000001000000000000000000000001 + pand xmm4, oword POLY + pxor xmm0, xmm4 ; xmm0 holds the HashKey<<1 mod poly + + movdqa xmm1, xmm0 + sse_clmul_gcm xmm1, xmm0, xmm3, xmm4, xmm5 ; xmm1 holds (HashKey^2)<<1 mod poly + + movdqa xmm2, xmm1 + sse_clmul_gcm xmm2, xmm1, xmm3, xmm4, xmm5 ; xmm2 holds (HashKey^4)<<1 mod poly + + mov eax, pMultipliers + movdqu oword [eax+sizeof_oword_*0], xmm0 + movdqu oword [eax+sizeof_oword_*1], xmm1 + movdqu oword [eax+sizeof_oword_*2], xmm2 + + REST_GPR + ret +ENDFUNC AesGcmPrecompute_avx + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; void AesGcmMulGcm_avx(Ipp8u* pHash, const Ipp8u* pHKey) +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmMulGcm_avx,PUBLIC + USES_GPR esi,edi + +%xdefine pHash [esp + ARG_1 + 0*sizeof(dword)] +%xdefine pHKey [esp + ARG_1 + 1*sizeof(dword)] + + LD_ADDR esi, CONST_TABLE + + mov edi, pHash ; (edi) pointer to the Hash value + mov eax, pHKey ; (eax) pointer to the (hkey<<1) value + + movdqa xmm0, oword [edi] + pshufb xmm0, u128_str + movdqa xmm1, oword [eax] + + sse_clmul_gcm xmm0, xmm1, xmm2, xmm3, xmm4 ; xmm0 holds Hash*HKey mod poly + + pshufb xmm0, u128_str + movdqa oword [edi], xmm0 + + REST_GPR + ret +ENDFUNC AesGcmMulGcm_avx + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; void AesGcmAuth_avx(Ipp8u* pHash, const Ipp8u* pSrc, int len, const Ipp8u* pHKey +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmAuth_avx,PUBLIC + USES_GPR esi,edi + +%xdefine pHash [esp + ARG_1 + 0*sizeof(dword)] +%xdefine pSrc [esp + ARG_1 + 1*sizeof(dword)] +%xdefine len [esp + ARG_1 + 2*sizeof(dword)] +%xdefine pHKey [esp + ARG_1 + 3*sizeof(dword)] + +%assign BYTES_PER_BLK (16) + + LD_ADDR esi, CONST_TABLE + + mov edi, pHash + movdqa xmm0, oword [edi] + pshufb xmm0, u128_str + mov eax, pHKey + movdqa xmm1, oword [eax] + + mov ecx, pSrc + mov edx, len + +align IPP_ALIGN_FACTOR +.auth_loop: + movdqu xmm2, oword [ecx] ; src[] + pshufb xmm2, u128_str + add ecx, BYTES_PER_BLK + pxor xmm0, xmm2 ; hash ^= src[] + + sse_clmul_gcm xmm0, xmm1, xmm2, xmm3, xmm4 ; xmm0 holds Hash*HKey mod poly + + sub edx, BYTES_PER_BLK + jnz .auth_loop + + pshufb xmm0, u128_str + movdqa oword [edi], xmm0 + + REST_GPR + ret +ENDFUNC AesGcmAuth_avx + + +;*************************************************************** +;* Purpose: pipelined AES-GCM encryption +;* +;* void AesGcmEnc_avx(Ipp8u* pDst, +;* const Ipp8u* pSrc, +;* int length, +;* RijnCipher cipher, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp8u* pGhash, +;* Ipp8u* pCtrValue, +;* Ipp8u* pEncCtrValue, +;* const Ipp8u* pPrecomData) +;*************************************************************** + +;; +;; Lib = P8, G9 +;; +;; Caller = ippsRijndael128GCMEncrypt +;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmEnc_avx,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pDst [ebp + ARG_1 + 0*sizeof(dword)] ; output block address +%xdefine pSrc [ebp + ARG_1 + 1*sizeof(dword)] ; input block address +%xdefine len [ebp + ARG_1 + 2*sizeof(dword)] ; length(byte) +%xdefine cipher [ebp + ARG_1 + 3*sizeof(dword)] +%xdefine nr [ebp + ARG_1 + 4*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 5*sizeof(dword)] ; key material address +%xdefine pGhash [ebp + ARG_1 + 6*sizeof(dword)] ; hash +%xdefine pCounter [ebp + ARG_1 + 7*sizeof(dword)] ; counter +%xdefine pEcounter [ebp + ARG_1 + 8*sizeof(dword)] ; enc. counter +%xdefine pPrecomData [ebp + ARG_1 + 9*sizeof(dword)] ; const multipliers + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + +;; +;; stack structure: +%assign CNT (0) +%assign ECNT (CNT+sizeof_oword_) +%assign GHASH (ECNT+sizeof_oword_) + +%assign GHASH0 (GHASH) +%assign GHASH1 (GHASH0+sizeof_oword_) +%assign GHASH2 (GHASH1+sizeof_oword_) +%assign GHASH3 (GHASH2+sizeof_oword_) + +%assign SHUF_CONST (GHASH3+sizeof_oword_) +%assign INC_1 (SHUF_CONST+sizeof_oword_) + +%assign BLKS4 (INC_1+sizeof_oword_) +%assign BLKS (BLKS4+sizeof(dword)) +%assign STACK_SIZE (BLKS+sizeof(dword)+sizeof_oword_) + + sub esp, STACK_SIZE ; alocate stack + lea ebx, [esp+sizeof_oword_] ; align stack + and ebx, -sizeof_oword_ + mov eax, cipher ; due to bug in ml12 - dummy instruction + LD_ADDR esi, CONST_TABLE + movdqa xmm4, oword u128_str + movdqa xmm5, oword inc1 + + mov eax, pCounter ; address of the counter + mov ecx, pEcounter ; address of the encrypted counter + mov edx, pGhash ; address of hash value + + movdqu xmm0, oword [eax] ; counter value + movdqu xmm1, oword [ecx] ; encrypted counter value + movdqu xmm2, oword [edx] ; hash value + +my_pshufb xmm0, xmm4 ; convert counter and + movdqa oword [ebx+CNT], xmm0 ; and store into the stack + movdqa oword [ebx+ECNT], xmm1 ; store encrypted counter into the stack + +my_pshufb xmm2, xmm4 ; convert hash value + pxor xmm1, xmm1 + movdqa oword [ebx+GHASH0], xmm2 ; store hash into the stack + movdqa oword [ebx+GHASH1], xmm1 ; + movdqa oword [ebx+GHASH2], xmm1 ; + movdqa oword [ebx+GHASH3], xmm1 ; + + movdqa oword [ebx+SHUF_CONST], xmm4 ; store constants into the stack + movdqa oword [ebx+INC_1], xmm5 + + mov ecx, pKey ; key marerial + mov esi, pSrc ; src/dst pointers + mov edi, pDst + + mov eax, len + mov edx, BYTES_PER_LOOP-1 + and edx, eax + and eax,-BYTES_PER_LOOP + mov dword [ebx+BLKS4], eax ; 4-blks counter + mov dword [ebx+BLKS], edx ; rest counter + jz .single_block_proc + +;; +;; pipelined processing +;; +align IPP_ALIGN_FACTOR +.blks4_loop: + ;; + ;; ctr encryption + ;; + movdqa xmm5, oword [ebx+INC_1] + + movdqa xmm1, xmm0 ; counter+1 + paddd xmm1, xmm5 + movdqa xmm2, xmm1 ; counter+2 + paddd xmm2, xmm5 + movdqa xmm3, xmm2 ; counter+3 + paddd xmm3, xmm5 + movdqa xmm4, xmm3 ; counter+4 + paddd xmm4, xmm5 + movdqa oword [ebx+CNT], xmm4 + + movdqa xmm5,oword [ebx+SHUF_CONST] + + movdqa xmm0, oword [ecx] ; pre-load whitening keys + lea eax, [ecx+16] ; pointer to the round's key material + +my_pshufb xmm1, xmm5 ; counter, counter+1, counter+2, counter+3 +my_pshufb xmm2, xmm5 ; ready to be encrypted +my_pshufb xmm3, xmm5 +my_pshufb xmm4, xmm5 + + pxor xmm1, xmm0 ; whitening + pxor xmm2, xmm0 + pxor xmm3, xmm0 + pxor xmm4, xmm0 + + movdqa xmm0, oword [eax] ; pre load round keys + add eax, 16 + + mov edx, nr ; counter depending on key length + sub edx, 1 + +align IPP_ALIGN_FACTOR +.cipher4_loop: +my_aesenc xmm1, xmm0 ; regular round +my_aesenc xmm2, xmm0 +my_aesenc xmm3, xmm0 +my_aesenc xmm4, xmm0 + movdqa xmm0, oword [eax] + add eax, 16 + dec edx + jnz .cipher4_loop +my_aesenclast xmm1, xmm0 +my_aesenclast xmm2, xmm0 +my_aesenclast xmm3, xmm0 +my_aesenclast xmm4, xmm0 + + movdqa xmm0, oword [ebx+ECNT] ; load pre-calculated encrypted counter + movdqa oword [ebx+ECNT], xmm4 ; save encrypted counter+4 + + movdqu xmm4, oword [esi+0*BYTES_PER_BLK] ; ctr encryption of 4 input blocks + movdqu xmm5, oword [esi+1*BYTES_PER_BLK] + movdqu xmm6, oword [esi+2*BYTES_PER_BLK] + movdqu xmm7, oword [esi+3*BYTES_PER_BLK] + add esi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; ctr encryption + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 ; store result +my_pshufbM xmm0, [ebx+SHUF_CONST] ; convert for multiplication and + pxor xmm0, oword [ebx+GHASH0] + + pxor xmm1, xmm5 + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 +my_pshufbM xmm1, [ebx+SHUF_CONST] + pxor xmm1, oword [ebx+GHASH1] + + pxor xmm2, xmm6 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 +my_pshufbM xmm2, [ebx+SHUF_CONST] + pxor xmm2, oword [ebx+GHASH2] + + pxor xmm3, xmm7 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 +my_pshufbM xmm3, [ebx+SHUF_CONST] + pxor xmm3, oword [ebx+GHASH3] + + add edi, BYTES_PER_LOOP + + mov eax, pPrecomData ; pointer to the {hk<<1,hk^2<<1,kh^4<<1} multipliers + movdqa xmm7,oword [eax+sizeof_oword_*2] + + cmp dword [ebx+BLKS4], BYTES_PER_LOOP + je .combine_hash + + ;; + ;; update hash value + ;; + sse_clmul_gcm xmm0, xmm7, xmm4, xmm5, xmm6 ; gHash0 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm1, xmm7, xmm4, xmm5, xmm6 ; gHash1 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm2, xmm7, xmm4, xmm5, xmm6 ; gHash2 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm3, xmm7, xmm4, xmm5, xmm6 ; gHash3 = gHash0 * (HashKey^4)<<1 mod poly + + movdqa oword [ebx+GHASH0], xmm0 + movdqa oword [ebx+GHASH1], xmm1 + movdqa oword [ebx+GHASH2], xmm2 + movdqa oword [ebx+GHASH3], xmm3 + + movdqa xmm0, oword [ebx+CNT] ; next counter value + sub dword [ebx+BLKS4], BYTES_PER_LOOP + jge .blks4_loop + +.combine_hash: + sse_clmul_gcm xmm0, xmm7, xmm4, xmm5, xmm6 ; gHash0 = gHash0 * (HashKey^4)<<1 mod poly + movdqa xmm7,oword [eax+sizeof_oword_*1] + sse_clmul_gcm xmm1, xmm7, xmm4, xmm5, xmm6 ; gHash1 = gHash1 * (HashKey^2)<<1 mod poly + movdqa xmm7,oword [eax+sizeof_oword_*0] + sse_clmul_gcm xmm2, xmm7, xmm4, xmm5, xmm6 ; gHash2 = gHash2 * (HashKey^1)<<1 mod poly + + pxor xmm3, xmm1 + pxor xmm3, xmm2 + sse_clmul_gcm xmm3, xmm7, xmm4, xmm5, xmm6 ; gHash3 = gHash3 * (HashKey)<<1 mod poly + + pxor xmm3, xmm0 + movdqa oword [ebx+GHASH0], xmm3 ; store ghash + +;; +;; rest of input processing (1-3 blocks) +;; +.single_block_proc: + cmp dword [ebx+BLKS],0 + jz .quit + +align IPP_ALIGN_FACTOR +.blk_loop: + movdqa xmm0, oword [ebx+CNT] ; advance counter value + movdqa xmm1, xmm0 + paddd xmm1, oword [ebx+INC_1] + movdqa oword [ebx+CNT], xmm1 + + movdqa xmm0, oword [ecx] ; pre-load whitening keys + lea eax, [ecx+16] + +my_pshufb xmm1, [ebx+SHUF_CONST] ; counter is ready to be encrypted + + pxor xmm1, xmm0 ; whitening + + movdqa xmm0, oword [eax] + add eax, 16 + + mov edx, nr ; counter depending on key length + sub edx, 1 + +align IPP_ALIGN_FACTOR +.cipher_loop: +my_aesenc xmm1, xmm0 ; regular round + movdqa xmm0, oword [eax] + add eax, 16 + dec edx + jnz .cipher_loop +my_aesenclast xmm1, xmm0 + + movdqa xmm0, oword [ebx+ECNT] ; load pre-calculated encrypted counter + movdqa oword [ebx+ECNT], xmm1 ; save encrypted counter + + movdqu xmm1, oword [esi] ; input block + add esi, BYTES_PER_BLK + pxor xmm0, xmm1 ; ctr encryption + movdqu oword [edi], xmm0 + add edi, BYTES_PER_BLK + + mov eax, pPrecomData + + pshufb xmm0, [ebx+SHUF_CONST] + pxor xmm0, oword [ebx+GHASH0] + movdqa xmm1, oword [eax] + sse_clmul_gcm xmm0, xmm1, xmm2, xmm3, xmm4 ; update hash value + movdqa oword [ebx+GHASH0], xmm0 + + sub dword [ebx+BLKS], BYTES_PER_BLK + jg .blk_loop + +;; +;; exit +;; +.quit: + movdqa xmm4, oword [ebx+SHUF_CONST] + + movdqa xmm0, oword [ebx+CNT] ; counter + movdqa xmm1, oword [ebx+ECNT] ; encrypted counter + movdqa xmm2, oword [ebx+GHASH0] ; hash + + mov eax, pCounter ; address of the counter + mov ecx, pEcounter ; address of the encrypted counter + mov edx, pGhash ; address of hash value + +my_pshufb xmm0, xmm4 ; convert counter back and + movdqu oword [eax], xmm0 ; and store + + movdqu oword [ecx], xmm1 ; store encrypted counter into the context + +my_pshufb xmm2, xmm4 ; convert hash value back + movdqu oword [edx], xmm2 ; store hash into the context + + add esp, STACK_SIZE ; free stack + REST_GPR + ret +ENDFUNC AesGcmEnc_avx + + +;*************************************************************** +;* Purpose: pipelined AES-GCM decryption +;* +;* void AesGcmEnc_avx(Ipp8u* pDst, +;* const Ipp8u* pSrc, +;* int length, +;* RijnCipher cipher, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp8u* pGhash, +;* Ipp8u* pCtrValue, +;* Ipp8u* pEncCtrValue, +;* const Ipp8u* pPrecomData) +;*************************************************************** + +;; +;; Lib = P8, G9 +;; +;; Caller = ippsRijndael128GCMDecrypt +;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmDec_avx,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pDst [ebp + ARG_1 + 0*sizeof(dword)] ; output block address +%xdefine pSrc [ebp + ARG_1 + 1*sizeof(dword)] ; input block address +%xdefine len [ebp + ARG_1 + 2*sizeof(dword)] ; length(byte) +%xdefine cipher [ebp + ARG_1 + 3*sizeof(dword)] +%xdefine nr [ebp + ARG_1 + 4*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 5*sizeof(dword)] ; key material address +%xdefine pGhash [ebp + ARG_1 + 6*sizeof(dword)] ; hash +%xdefine pCounter [ebp + ARG_1 + 7*sizeof(dword)] ; counter +%xdefine pEcounter [ebp + ARG_1 + 8*sizeof(dword)] ; enc. counter +%xdefine pPrecomData [ebp + ARG_1 + 9*sizeof(dword)] ; const multipliers + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + +;; +;; stack structure: +%assign CNT (0) +%assign ECNT (CNT+sizeof_oword_) +%assign GHASH (ECNT+sizeof_oword_) + +%assign GHASH0 (GHASH) +%assign GHASH1 (GHASH0+sizeof_oword_) +%assign GHASH2 (GHASH1+sizeof_oword_) +%assign GHASH3 (GHASH2+sizeof_oword_) + +%assign SHUF_CONST (GHASH3+sizeof_oword_) +%assign INC_1 (SHUF_CONST+sizeof_oword_) + +%assign BLKS4 (INC_1+sizeof_oword_) +%assign BLKS (BLKS4+sizeof(dword)) +%assign STACK_SIZE (BLKS+sizeof(dword)+sizeof_oword_) + + sub esp, STACK_SIZE ; alocate stack + lea ebx, [esp+sizeof_oword_] ; align stack + and ebx, -sizeof_oword_ + mov eax, cipher ; due to bug in ml12 - dummy instruction + + LD_ADDR esi, CONST_TABLE + movdqa xmm4, oword u128_str + movdqa xmm5, oword inc1 + + mov eax, pCounter ; address of the counter + mov ecx, pEcounter ; address of the encrypted counter + mov edx, pGhash ; address of hash value + + movdqu xmm0, oword [eax] ; counter value + movdqu xmm1, oword [ecx] ; encrypted counter value + movdqu xmm2, oword [edx] ; hash value + +my_pshufb xmm0, xmm4 ; convert counter and + movdqa oword [ebx+CNT], xmm0 ; and store into the stack + movdqa oword [ebx+ECNT], xmm1 ; store encrypted counter into the stack + +my_pshufb xmm2, xmm4 ; convert hash value + pxor xmm1, xmm1 + movdqa oword [ebx+GHASH0], xmm2 ; store hash into the stack + movdqa oword [ebx+GHASH1], xmm1 ; + movdqa oword [ebx+GHASH2], xmm1 ; + movdqa oword [ebx+GHASH3], xmm1 ; + + movdqa oword [ebx+SHUF_CONST], xmm4 ; store constants into the stack + movdqa oword [ebx+INC_1], xmm5 + + mov ecx, pKey ; key marerial + mov esi, pSrc ; src/dst pointers + mov edi, pDst + + mov eax, len + mov edx, BYTES_PER_LOOP-1 + and edx, eax + and eax,-BYTES_PER_LOOP + mov dword [ebx+BLKS4], eax ; 4-blks counter + mov dword [ebx+BLKS], edx ; rest counter + jz .single_block_proc + +;; +;; pipelined processing +;; +align IPP_ALIGN_FACTOR +.blks4_loop: + ;; + ;; ctr encryption + ;; + movdqa xmm5, oword [ebx+INC_1] + + movdqa xmm1, xmm0 ; counter+1 + paddd xmm1, xmm5 + movdqa xmm2, xmm1 ; counter+2 + paddd xmm2, xmm5 + movdqa xmm3, xmm2 ; counter+3 + paddd xmm3, xmm5 + movdqa xmm4, xmm3 ; counter+4 + paddd xmm4, xmm5 + movdqa oword [ebx+CNT], xmm4 + + movdqa xmm5,oword [ebx+SHUF_CONST] + + movdqa xmm0, oword [ecx] ; pre-load whitening keys + lea eax, [ecx+16] ; pointer to the round's key material + +my_pshufb xmm1, xmm5 ; counter, counter+1, counter+2, counter+3 +my_pshufb xmm2, xmm5 ; ready to be encrypted +my_pshufb xmm3, xmm5 +my_pshufb xmm4, xmm5 + + pxor xmm1, xmm0 ; whitening + pxor xmm2, xmm0 + pxor xmm3, xmm0 + pxor xmm4, xmm0 + + movdqa xmm0, oword [eax] ; pre load round keys + add eax, 16 + + mov edx, nr ; counter depending on key length + sub edx, 1 + +align IPP_ALIGN_FACTOR +.cipher4_loop: +my_aesenc xmm1, xmm0 ; regular round +my_aesenc xmm2, xmm0 +my_aesenc xmm3, xmm0 +my_aesenc xmm4, xmm0 + movdqa xmm0, oword [eax] + add eax, 16 + dec edx + jnz .cipher4_loop +my_aesenclast xmm1, xmm0 +my_aesenclast xmm2, xmm0 +my_aesenclast xmm3, xmm0 +my_aesenclast xmm4, xmm0 + + movdqa xmm0, oword [ebx+ECNT] ; load pre-calculated encrypted counter + movdqa oword [ebx+ECNT], xmm4 ; save encrypted counter+4 + + movdqu xmm4, oword [esi+0*BYTES_PER_BLK] ; ctr encryption of 4 input blocks + movdqu xmm5, oword [esi+1*BYTES_PER_BLK] + movdqu xmm6, oword [esi+2*BYTES_PER_BLK] + movdqu xmm7, oword [esi+3*BYTES_PER_BLK] + add esi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; ctr encryption + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 ; store result +my_pshufbM xmm4, [ebx+SHUF_CONST] ; convert for multiplication and + pxor xmm4, oword [ebx+GHASH0] + + pxor xmm1, xmm5 + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 +my_pshufbM xmm5, [ebx+SHUF_CONST] + pxor xmm5, oword [ebx+GHASH1] + + pxor xmm2, xmm6 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 + ;pshufb xmm6, [ebx+SHUF_CONST] +my_pshufbM xmm6, [ebx+SHUF_CONST] + pxor xmm6, oword [ebx+GHASH2] + + pxor xmm3, xmm7 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 +my_pshufbM xmm7, [ebx+SHUF_CONST] + pxor xmm7, oword [ebx+GHASH3] + + add edi, BYTES_PER_LOOP + + mov eax, pPrecomData ; pointer to the const multipliers (c^1, c^2, c^4) + movdqa xmm0,oword [eax+sizeof_oword_*2] + + cmp dword [ebx+BLKS4], BYTES_PER_LOOP + je .combine_hash + + ;; + ;; update hash value + ;; + sse_clmul_gcm xmm4, xmm0, xmm1, xmm2, xmm3 ; gHash0 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm5, xmm0, xmm1, xmm2, xmm3 ; gHash1 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm6, xmm0, xmm1, xmm2, xmm3 ; gHash2 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm7, xmm0, xmm1, xmm2, xmm3 ; gHash3 = gHash0 * (HashKey^4)<<1 mod poly + + movdqa oword [ebx+GHASH0], xmm4 + movdqa oword [ebx+GHASH1], xmm5 + movdqa oword [ebx+GHASH2], xmm6 + movdqa oword [ebx+GHASH3], xmm7 + + movdqa xmm0, oword [ebx+CNT] ; next counter value + sub dword [ebx+BLKS4], BYTES_PER_LOOP + jge .blks4_loop + +.combine_hash: + sse_clmul_gcm xmm4, xmm0, xmm1, xmm2, xmm3 ; gHash0 = gHash0 * (HashKey^4)<<1 mod poly + movdqa xmm0, oword [eax+sizeof_oword_*1] + sse_clmul_gcm xmm5, xmm0, xmm1, xmm2, xmm3 ; gHash1 = gHash1 * (HashKey^2)<<1 mod poly + movdqa xmm0, oword [eax+sizeof_oword_*0] + sse_clmul_gcm xmm6, xmm0, xmm1, xmm2, xmm3 ; gHash2 = gHash2 * (HashKey^1)<<1 mod poly + + pxor xmm7, xmm5 + pxor xmm7, xmm6 + sse_clmul_gcm xmm7, xmm0, xmm1, xmm2, xmm3 ; gHash3 = gHash3 * (HashKey)<<1 mod poly + + pxor xmm7, xmm4 + movdqa oword [ebx+GHASH0], xmm7 ; store ghash + +;; +;; rest of input processing (1-3 blocks) +;; +.single_block_proc: + cmp dword [ebx+BLKS],0 + jz .quit + +align IPP_ALIGN_FACTOR +.blk_loop: + movdqa xmm0, oword [ebx+CNT] ; advance counter value + movdqa xmm1, xmm0 + paddd xmm1, oword [ebx+INC_1] + movdqa oword [ebx+CNT], xmm1 + + movdqa xmm0, oword [ecx] ; pre-load whitening keys + lea eax, [ecx+16] + +my_pshufb xmm1, [ebx+SHUF_CONST] ; counter is ready to be encrypted + + pxor xmm1, xmm0 ; whitening + + movdqa xmm0, oword [eax] + add eax, 16 + + mov edx, nr ; counter depending on key length + sub edx, 1 + +align IPP_ALIGN_FACTOR +.cipher_loop: +my_aesenc xmm1, xmm0 ; regular round + movdqa xmm0, oword [eax] + add eax, 16 + dec edx + jnz .cipher_loop +my_aesenclast xmm1, xmm0 + + movdqa xmm0, oword [ebx+ECNT] ; load pre-calculated encrypted counter + movdqa oword [ebx+ECNT], xmm1 ; save encrypted counter + + movdqu xmm1, oword [esi] ; input block + add esi, BYTES_PER_BLK + pxor xmm0, xmm1 ; ctr encryption + movdqu oword [edi], xmm0 + add edi, BYTES_PER_BLK + + mov eax, pPrecomData + + pshufb xmm1, [ebx+SHUF_CONST] + pxor xmm1, oword [ebx+GHASH0] + movdqa xmm0, oword [eax] + sse_clmul_gcm xmm1, xmm0, xmm2, xmm3, xmm4 ; update hash value + movdqa oword [ebx+GHASH0], xmm1 + + sub dword [ebx+BLKS], BYTES_PER_BLK + jg .blk_loop + +;; +;; exit +;; +.quit: + movdqa xmm4, oword [ebx+SHUF_CONST] + + movdqa xmm0, oword [ebx+CNT] ; counter + movdqa xmm1, oword [ebx+ECNT] ; encrypted counter + movdqa xmm2, oword [ebx+GHASH0] ; hash + + mov eax, pCounter ; address of the counter + mov ecx, pEcounter ; address of the encrypted counter + mov edx, pGhash ; address of hash value + +my_pshufb xmm0, xmm4 ; convert counter back and + movdqu oword [eax], xmm0 ; and store + + movdqu oword [ecx], xmm1 ; store encrypted counter into the context + +my_pshufb xmm2, xmm4 ; convert hash value back + movdqu oword [edx], xmm2 ; store hash into the context + + add esp, STACK_SIZE ; free stack + REST_GPR + ret +ENDFUNC AesGcmDec_avx + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpaesgcmtable2kv8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpaesgcmtable2kv8as.asm new file mode 100644 index 000000000..9deb3ece0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpaesgcmtable2kv8as.asm @@ -0,0 +1,449 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Encrypt/Decrypt byte data stream according to Rijndael128 (GCM mode) +; +; Content: +; AesGcmMulGcm_table2K() +; AesGcmAuth_table2K() +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_V8) + +segment .text align=IPP_ALIGN_FACTOR + +; +; getAesGcmConst_table_ct provides c-e-t access to pre-computed Ipp16u AesGcmConst_table[256] +; +; input: +; edx: address of the AesGcmConst_table +; ecx: index in the table +; +; output: +; eax +; +; register ecx destoyed +; registers mmx2, mmx3, mmx6, and mmx7 destoyed +; +align IPP_ALIGN_FACTOR +_CONST_DATA: +_INIT_IDX DW 000h,001h,002h,003h,004h,005h,006h,007h ;; initial search inx = {0:1:2:3:4:5:6:7} +_INCR_IDX DW 008h,008h,008h,008h,008h,008h,008h,008h ;; index increment = {8:8:8:8:8:8:8:8} + +%xdefine INIT_IDX [ebx+(_INIT_IDX - _CONST_DATA)] +%xdefine INCR_IDX [ebx+(_INCR_IDX - _CONST_DATA)] + +align IPP_ALIGN_FACTOR +IPPASM getAesGcmConst_table_ct,PRIVATE + push ebx + LD_ADDR ebx, _CONST_DATA + + pxor xmm2, xmm2 ;; accumulator xmm2 = 0 + + mov eax, ecx ;; broadcast inx into dword + shl ecx, 16 + or ecx, eax + movd xmm3, ecx + pshufd xmm3, xmm3, 00b ;; search index xmm3 = broadcast(idx) + + movdqa xmm6, xmmword INIT_IDX ;; current indexes + + xor eax, eax +align IPP_ALIGN_FACTOR +.search_loop: + movdqa xmm7, xmm6 ;; copy current indexes + paddw xmm6, xmmword INCR_IDX ;; advance current indexes + + pcmpeqw xmm7, xmm3 ;; selection mask + pand xmm7, xmmword [edx+eax*sizeof(word)];; mask data + + add eax, 8 + cmp eax, 256 + + por xmm2, xmm7 ;; and accumulate + jl .search_loop + + movdqa xmm3, xmm2 ;; pack result in qword + psrldq xmm2, sizeof(xmmword)/2 + por xmm2, xmm3 + movdqa xmm3, xmm2 ;; pack result in dword + psrldq xmm2, sizeof(xmmword)/4 + por xmm2, xmm3 + movd eax, xmm2 + + pop ebx + + and ecx, 3 ;; select tbl[idx] value + shl ecx, 4 ;; rcx *=16 = sizeof(word)*8 + shr eax, cl + ret +ENDFUNC getAesGcmConst_table_ct + + +; +; void AesGcmMulGcm_table2K(Ipp8u* pHash, const Ipp8u* pPrecomputedData, , const void* pParam)) +; +align IPP_ALIGN_FACTOR +IPPASM AesGcmMulGcm_table2K,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pHash [esp + ARG_1 + 0*sizeof(dword)] +%xdefine pMulTbl [esp + ARG_1 + 1*sizeof(dword)] +%xdefine pParam [esp + ARG_1 + 2*sizeof(dword)] + + mov edi, pHash + movdqu xmm0, [edi] ; hash value + + mov esi, pMulTbl + mov edx, pParam ; pointer to the fixed table + + movd ebx, xmm0 ; ebx = hash.0 + mov eax, 0f0f0f0f0h + and eax, ebx ; eax = 4 x 4_bits + shl ebx, 4 + and ebx, 0f0f0f0f0h ; ebx = 4 x 4_bits (another) + movzx ecx, ah + movdqa xmm5, oword [esi+1024+ecx] + movzx ecx, al + movdqa xmm4, oword [esi+1024+ecx] + shr eax, 16 + movzx ecx, ah + movdqa xmm3, oword [esi+1024+ecx] + movzx ecx, al + movdqa xmm2, oword [esi+1024+ecx] + + psrldq xmm0, 4 ; shift xmm0 + movd eax, xmm0 ; eax = hash[1] + and eax, 0f0f0f0f0h ; eax = 4 x 4_bits + + movzx ecx, bh + pxor xmm5, oword [esi+ 0*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 0*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 0*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 0*256 + ecx] + + movd ebx, xmm0 ; ebx = hash[1] + shl ebx, 4 ; another 4 x 4_bits + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [esi+1024+ 1*256 + ecx] + movzx ecx, al + pxor xmm4, oword [esi+1024+ 1*256 + ecx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [esi+1024+ 1*256 + ecx] + movzx ecx, al + pxor xmm2, oword [esi+1024+ 1*256 + ecx] + psrldq xmm0, 4 + + movd eax, xmm0 ; eax = hash.2 + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [esi+ 1*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 1*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 1*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 1*256 + ecx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [esi+1024+ 2*256 + ecx] + movzx ecx, al + pxor xmm4, oword [esi+1024+ 2*256 + ecx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [esi+1024+ 2*256 + ecx] + movzx ecx, al + pxor xmm2, oword [esi+1024+ 2*256 + ecx] + + psrldq xmm0, 4 + movd eax, xmm0 ; eax = hash.3 + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [esi+ 2*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 2*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 2*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 2*256 + ecx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [esi+1024+ 3*256 + ecx] + movzx ecx, al + pxor xmm4, oword [esi+1024+ 3*256 + ecx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [esi+1024+ 3*256 + ecx] + movzx ecx, al + pxor xmm2, oword [esi+1024+ 3*256 + ecx] + + movzx ecx, bh + pxor xmm5, oword [esi+ 3*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 3*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 3*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 3*256 + ecx] + + movdqa xmm0, xmm3 + pslldq xmm3, 1 + pxor xmm2, xmm3 + movdqa xmm1, xmm2 + pslldq xmm2, 1 + pxor xmm5, xmm2 + + psrldq xmm0, 15 + movd ecx, xmm0 + CALL_IPPASM getAesGcmConst_table_ct ;;movzx eax, word [edx + ecx*sizeof(word)] + shl eax, 8 + + movdqa xmm0, xmm5 + pslldq xmm5, 1 + pxor xmm4, xmm5 + + psrldq xmm1, 15 + movd ecx, xmm1 + mov ebx, eax ;;xor ax, word [edx + ecx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor eax, ebx ;; + shl eax, 8 + + psrldq xmm0, 15 + movd ecx, xmm0 + mov ebx, eax ;;xor ax, word [edx + ecx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor eax, ebx ;; + + movd xmm0, eax + pxor xmm0, xmm4 + + movdqu oword [edi], xmm0 ; store hash value + + REST_GPR + ret +ENDFUNC AesGcmMulGcm_table2K + +; +; void AesGcmAuth_table2K(Ipp8u* pHash, const Ipp8u* pSrc, int len, const Ipp8u* pPrecomputedData, const void* pParam) +; +align IPP_ALIGN_FACTOR +IPPASM AesGcmAuth_table2K,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pHash [esp + ARG_1 + 0*sizeof(dword)] +%xdefine pSrc [esp + ARG_1 + 1*sizeof(dword)] +%xdefine len [esp + ARG_1 + 2*sizeof(dword)] +%xdefine pMulTbl [esp + ARG_1 + 3*sizeof(dword)] +%xdefine pParam [esp + ARG_1 + 4*sizeof(dword)] + + mov edi, pHash + movdqu xmm0, [edi] ; hash value + + mov esi, pMulTbl + mov edi, pSrc + + mov edx, pParam ; pointer to the fixed table + +align IPP_ALIGN_FACTOR +.auth_loop: + movdqu xmm4, [edi] ; get src[] + pxor xmm0, xmm4 ; hash ^= src[] + + movd ebx, xmm0 ; ebx = hash.0 + mov eax, 0f0f0f0f0h + and eax, ebx ; eax = 4 x 4_bits + shl ebx, 4 + and ebx, 0f0f0f0f0h ; ebx = 4 x 4_bits (another) + movzx ecx, ah + movdqa xmm5, oword [esi+1024+ecx] + movzx ecx, al + movdqa xmm4, oword [esi+1024+ecx] + shr eax, 16 + movzx ecx, ah + movdqa xmm3, oword [esi+1024+ecx] + movzx ecx, al + movdqa xmm2, oword [esi+1024+ecx] + + psrldq xmm0, 4 ; shift xmm0 + movd eax, xmm0 ; eax = hash[1] + and eax, 0f0f0f0f0h ; eax = 4 x 4_bits + + movzx ecx, bh + pxor xmm5, oword [esi+ 0*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 0*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 0*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 0*256 + ecx] + + movd ebx, xmm0 ; ebx = hash[1] + shl ebx, 4 ; another 4 x 4_bits + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [esi+1024+ 1*256 + ecx] + movzx ecx, al + pxor xmm4, oword [esi+1024+ 1*256 + ecx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [esi+1024+ 1*256 + ecx] + movzx ecx, al + pxor xmm2, oword [esi+1024+ 1*256 + ecx] + + psrldq xmm0, 4 + movd eax, xmm0 ; eax = hash[2] + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [esi+ 1*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 1*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 1*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 1*256 + ecx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [esi+1024+ 2*256 + ecx] + movzx ecx, al + pxor xmm4, oword [esi+1024+ 2*256 + ecx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [esi+1024+ 2*256 + ecx] + movzx ecx, al + pxor xmm2, oword [esi+1024+ 2*256 + ecx] + + psrldq xmm0, 4 + movd eax, xmm0 ; eax = hash[3] + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [esi+ 2*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 2*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 2*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 2*256 + ecx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [esi+1024+ 3*256 + ecx] + movzx ecx, al + pxor xmm4, oword [esi+1024+ 3*256 + ecx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [esi+1024+ 3*256 + ecx] + movzx ecx, al + pxor xmm2, oword [esi+1024+ 3*256 + ecx] + + movzx ecx, bh + pxor xmm5, oword [esi+ 3*256 + ecx] + movzx ecx, bl + pxor xmm4, oword [esi+ 3*256 + ecx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [esi+ 3*256 + ecx] + movzx ecx, bl + pxor xmm2, oword [esi+ 3*256 + ecx] + + movdqa xmm0, xmm3 + pslldq xmm3, 1 + pxor xmm2, xmm3 + movdqa xmm1, xmm2 + pslldq xmm2, 1 + pxor xmm5, xmm2 + psrldq xmm0, 15 + + movd ecx, xmm0 + CALL_IPPASM getAesGcmConst_table_ct ;;movzx eax, word [edx + ecx*sizeof(word)] + shl eax, 8 + + movdqa xmm0, xmm5 + pslldq xmm5, 1 + pxor xmm4, xmm5 + + psrldq xmm1, 15 + movd ecx, xmm1 + mov ebx, eax ;;xor ax, word [edx + ecx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor eax, ebx ;; + shl eax, 8 + + psrldq xmm0, 15 + movd ecx, xmm0 + mov ebx, eax ;;xor ax, word [edx + ecx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor eax, ebx ;; + + movd xmm0, eax + pxor xmm0, xmm4 + + add edi, sizeof(oword) ; advance src address + sub dword len, sizeof(oword) ; decrease counter + jnz .auth_loop ; process next block + + mov edi, pHash + movdqu oword [edi], xmm0 ; store hash value + + REST_GPR + ret +ENDFUNC AesGcmAuth_table2K + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnu.inc b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnu.inc new file mode 100644 index 000000000..87f72ad20 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnu.inc @@ -0,0 +1,377 @@ +;=============================================================================== +; Copyright (C) 2006 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number macros +; +; Content: +; COPY_BNU +; CMP_BNU +; FIX_BNU +; +; SUB_FIX_BNU +; ADD_FIX_BNU +; + +;; +;; CMP_BNU comare arbitrary BNUs +;; +;; input +;; rSrc1 points BNU1 +;; rSrc2 points BNU2 +;; rLen size of BNUs +;; +;; output +;; flags +;; +%macro CMP_BNU 4.nolist + %xdefine %%rSrc1 %1 + %xdefine %%rSrc2 %2 + %xdefine %%rLen %3 + %xdefine %%tmp %4 + +%%cmp_loop: + mov %%tmp,[%%rSrc1+%%rLen*4-4] + cmp %%tmp,[%%rSrc2+%%rLen*4-4] + jne %%cmp_quit + sub %%rLen,1 + jg %%cmp_loop +%%cmp_quit: +%endmacro + + +;; +;; SUB_FIX_BNU subtract fixed size BNUs +;; +;; input +;; rVal points src/dst BNU +;; rSrc points source BNU +;; immLen BNU size +;; +%macro SUB_FIX_BNU 3.nolist + %xdefine %%rVal %1 + %xdefine %%rSrc %2 + %xdefine %%immLen %3 + + pxor mm0,mm0 + %assign %%i 0 + %rep %%immLen + movd mm1,DWORD [%%rVal+%%i*4] + movd mm2,DWORD [%%rSrc+%%i*4] + %if %%i != 0 + paddq mm1,mm0 + %endif + psubq mm1,mm2 + movd DWORD [%%rVal+%%i*4],mm1 + %if %%i < (%%immLen-1) + pshufw mm0,mm1,11111110b + %endif + %assign %%i %%i+1 + %endrep +%endmacro + + +;; +;; ADD_FIX_BNU add fixed size BNUs +;; +;; input +;; rVal points src/dst BNU +;; rSrc points source BNU +;; immLen BNU size +;; +%macro ADD_FIX_BNU 3.nolist + %xdefine %%rVal %1 + %xdefine %%rSrc %2 + %xdefine %%immLen %3 + + pxor mm0,mm0 + %assign %%i 0 + %rep %%immLen + movd mm1,DWORD [%%rVal+%%i*4] + movd mm2,DWORD [%%rSrc+%%i*4] + %if %%i != 0 + paddq mm1,mm0 + %endif + paddq mm1,mm2 + movd DWORD [%%rVal+%%i*4],mm1 + %if %%i < (%%immLen-1) + pshufw mm0,mm1,11111110b + %endif + %assign %%i %%i+1 + %endrep +%endmacro + + +;; +;; COPY_BNU copy arbitrary BNU +;; +%macro COPY_BNU 5.nolist + %xdefine %%rSrc %1 + %xdefine %%rDst %2 + %xdefine %%rLen %3 + %xdefine %%rIdx %4 + %xdefine %%rTmp %5 + + xor %%rIdx,%%rIdx +%%copy_bnu: + mov %%rTmp,[%%rSrc+%%rIdx*4] + mov [%%rDst+%%rIdx*4],%%rTmp + add %%rIdx,1 + cmp %%rIdx,%%rLen + jl %%copy_bnu +%endmacro + + +;; +;; FIX_BNU returns actual length of BNU +;; +;; input +;; rSrc points BNU +;; rLen initial BNU size +;; +;; output +;; rLen actual BNU size +;; +%macro FIX_BNU 3.nolist + %xdefine %%rSrc %1 + %xdefine %%rLen %2 + %xdefine %%tmp %3 + +%%fix_bnu_loop: + mov %%tmp,[%%rSrc+%%rLen*4-4] ;; value + test %%tmp,%%tmp ;; test BNU component + jnz %%fix_bnu_quit + sub %%rLen,1 + jg %%fix_bnu_loop + add %%rLen,1 +%%fix_bnu_quit: +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro MULADD_START 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd mm1,DWORD [eax + 4*%%j] + movd mm3,DWORD [eax + 4*%%j] + pmuludq mm1,mm0 + paddq mm7,mm1 + movd DWORD [edx + 4*(%%i+%%j)],mm7 + pand mm3,mm6 + psrlq mm7,32 + paddq mm7,mm3 +%endmacro + + +%macro MULADD 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd mm1,DWORD [eax + 4*%%j] + movd mm3,DWORD [eax + 4*%%j] + movd mm2,DWORD [edx + 4*(%%i+%%j)] + pmuludq mm1,mm0 + pand mm3,mm6 + paddq mm1,mm2 + paddq mm7,mm1 + movd DWORD [edx + 4*(%%i+%%j)],mm7 + psrlq mm7,32 + paddq mm7,mm3 +%endmacro + + +%macro SQR_DECOMPOSE 1.nolist + %xdefine %%i %1 + + movd mm7,DWORD [eax + 4*%%i] + movd mm0,DWORD [eax + 4*%%i] + movd mm6,DWORD [eax + 4*%%i] + %if %%i != 0 + movd mm1,DWORD [edx + 4*(2*%%i)] + %endif + pslld mm0,1 + pmuludq mm7,mm7 + psrad mm6,32 + %if %%i != 0 + paddq mm7,mm1 + %endif + movd DWORD [edx + 4*(2*%%i)],mm7 + psrlq mm7,32 +%endmacro + + +%macro STORE_CARRY 2.nolist + %xdefine %%i %1 + %xdefine %%s %2 + + movq DWORD [edx + 4*(%%i + %%s)],mm7 +%endmacro + + +%macro STORE_CARRY_NEXT 2.nolist + %xdefine %%i %1 + %xdefine %%s %2 + + movd mm4,DWORD [edx + 4*(%%i + %%s)] + paddq mm4,mm7 + movd DWORD [edx + 4*(%%i + %%s)],mm4 + psrlq mm7,32 + movd DWORD [edx + 4*(%%i + %%s + 1)],mm7 +%endmacro + + +%macro LAST_STEP 1.nolist + %xdefine %%s %1 + + movd mm7,DWORD [eax + 4*(%%s - 1)] + movd mm2,DWORD [edx + 4*(2*%%s - 2)] + pmuludq mm7,mm7 + paddq mm7,mm2 + movd mm4,DWORD [edx + 4*(2*%%s - 1)] + movd DWORD [edx + 4*(2*%%s - 2)],mm7 + psrlq mm7,32 + paddq mm4,mm7 + movd DWORD [edx + 4*(2*%%s - 1)],mm4 +%endmacro + + +%macro INNER_LOOP 2.nolist + %xdefine %%i %1 + %xdefine %%nsize %2 + + %assign %%j %%i + 1 + %assign %%s %%nsize - %%i - 1 + + SQR_DECOMPOSE %%i + + %rep %%s + %if %%i == 0 + MULADD_START %%i,%%j + el%%se + MULADD %%i,%%j + %endif + %assign %%j %%j + 1 + %endrep + + %if %%i == 0 + STORE_CARRY %%i,%%nsize + el%%se + STORE_CARRY_NEXT %%i,%%nsize + %endif +%endmacro + + +%macro OUTER_LOOP 1.nolist + %xdefine %%nsize %1 + + %assign %%i 0 + %rep ns%%ize - 1 + INNER_LOOP %%i,%%nsize + %assign %%i %%i + 1 + %endrep + + LAST_STEP %%nsize +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro MULADD_START_wt_carry 1.nolist + %xdefine %%i %1 + + movd mm7,DWORD [eax] + movd mm2,DWORD [edx + 4*(%%i)] + pmuludq mm7,mm0 + paddq mm7,mm2 + movd DWORD [edx + 4*(%%i)],mm7 + psrlq mm7,32 +%endmacro + + +%macro MULADD_START1 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd mm1,DWORD [eax + 4*%%j] + pmuludq mm1,mm0 + paddq mm7,mm1 + movd DWORD [edx + 4*(%%i+%%j)],mm7 + psrlq mm7,32 +%endmacro + + +%macro MULADD_START_wt_carry1 0.nolist + movd mm7,DWORD [eax] + pmuludq mm7,mm0 + movd DWORD [edx],mm7 + psrlq mm7,32 +%endmacro + + +%macro MULADD1 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd mm1,DWORD [eax + 4*%%j] + movd mm2,DWORD [edx + 4*(%%i+%%j)] + pmuludq mm1,mm0 + paddq mm1,mm2 + paddq mm7,mm1 + movd DWORD [edx + 4*(%%i+%%j)],mm7 + psrlq mm7,32 +%endmacro + + +%macro INNER_LOOP1 2.nolist + %xdefine %%i %1 + %xdefine %%nsize %2 + + %assign %%j 0 + movd mm0,DWORD [ebx + 4*%%i] + + %rep %%nsize +%if %%i == 0 + %if %%j == 0 + MULADD_START_wt_carry1 + %else + MULADD_START1 %%i,%%j + %endif +%else + %if %%j == 0 + MULADD_START_wt_carry %%i + %else + MULADD1 %%i,%%j + %endif +%endif + %assign %%j %%j + 1 + %endrep + movd DWORD [edx + 4*(%%i + %%nsize)],mm7 +%endmacro + + +%macro OUTER_LOOP1 1.nolist + %xdefine %%nsize %1 + + %assign %%i 0 + %rep %%nsize + INNER_LOOP1 %%i,%%nsize + %assign %%i %%i + 1 + %endrep +%endmacro + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnuaddw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnuaddw7as.asm new file mode 100644 index 000000000..51542ca04 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnuaddw7as.asm @@ -0,0 +1,80 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Purpose: Cryptography Primitive. +; Big Number Arithmetic +; +; Content: +; cpAddMul_BNU() +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_W7) +%include "pcpvariant.inc" + +segment .text align=IPP_ALIGN_FACTOR + +%if (_USE_C_cpAdd_BNU_ == 0) +align IPP_ALIGN_FACTOR + +IPPASM cpAdd_BNU,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pDst [esp + ARG_1 + 0*sizeof(dword)] ; target address +%xdefine pSrc1 [esp + ARG_1 + 1*sizeof(dword)] ; source address +%xdefine pSrc2 [esp + ARG_1 + 2*sizeof(dword)] ; source address +%xdefine len [esp + ARG_1 + 3*sizeof(dword)] ; length of BNU + + mov eax,pSrc1 ; src1 + mov ebx,pSrc2 ; src2 + mov edx,pDst ; dst + mov edi,len ; length + shl edi,2 + + xor ecx,ecx + pandn mm0,mm0 + +align IPP_ALIGN_FACTOR +.main_loop: + movd mm1,DWORD [eax + ecx] + movd mm2,DWORD [ebx + ecx] + + paddq mm0,mm1 + paddq mm0,mm2 + movd DWORD [edx + ecx],mm0 + pshufw mm0,mm0,11111110b + + add ecx,4 + cmp ecx,edi + jl .main_loop + + movd eax,mm0 + emms + REST_GPR + ret +ENDFUNC cpAdd_BNU +%endif + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnuincw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnuincw7as.asm new file mode 100644 index 000000000..4603e00cc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnuincw7as.asm @@ -0,0 +1,77 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Purpose: Cryptography Primitive. +; +; Content: +; cpInc_BNU() +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_W7) +%include "pcpvariant.inc" + +%if (_USE_C_cpInc_BNU_ == 0) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM cpInc_BNU,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pDst [esp + ARG_1 + 0*sizeof(dword)] ; target address +%xdefine pSrc [esp + ARG_1 + 1*sizeof(dword)] ; source address +%xdefine len [esp + ARG_1 + 2*sizeof(dword)] ; length of BNU +%xdefine value [esp + ARG_1 + 3*sizeof(dword)] ; increment val + + mov edi, pDst ; dst + mov esi, pSrc ; src + mov eax, value ; value + movd mm0, value + mov edx,len ; length + shl edx,2 + + xor ecx,ecx + +align IPP_ALIGN_FACTOR +.main_loop: + movd mm1,DWORD [esi + ecx] + paddq mm1,mm0 + movd DWORD [edi + ecx],mm1 + pshufw mm0,mm1,11111110b + movd eax, mm0 + + add ecx,4 + cmp ecx,edx + jl .main_loop + +.exit_loop: + emms + REST_GPR + ret +ENDFUNC cpInc_BNU +%endif + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnumuldgtw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnumuldgtw7as.asm new file mode 100644 index 000000000..d340abf8f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnumuldgtw7as.asm @@ -0,0 +1,82 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Purpose: Cryptography Primitive. +; Big Number Arithmetic +; +; Content: +; cpMulDgt_BNU() +; cpAddMulDgt_BNU() +; cpSubMulDgtBNU() +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_W7) +%include "pcpvariant.inc" + +segment .text align=IPP_ALIGN_FACTOR + +%if (_USE_C_cpAddMulDgt_BNU_ == 0) +;; +;; Ipp32u cpAddMulDgt_BNU(Ipp32u* pDst, const Ipp32u* pSrc, cpSize len, Ipp32u dgt) +;; +IPPASM cpAddMulDgt_BNU,PUBLIC + USES_GPR edi + +%xdefine pDst [esp + ARG_1 + 0*sizeof(dword)] ; target address +%xdefine pSrc [esp + ARG_1 + 1*sizeof(dword)] ; source address +%xdefine len [esp + ARG_1 + 2*sizeof(dword)] ; BNU length +%xdefine dgt [esp + ARG_1 + 3*sizeof(dword)] ; 32-bit multiplier + + mov eax,pSrc ; src + mov edx,pDst ; dst + mov edi,len ; length + + xor ecx,ecx + shl edi,2 + movd mm0,dgt + pandn mm7,mm7 ;c + +.main_loop: + movd mm1,DWORD [eax + ecx] + movd mm2,DWORD [edx + ecx] + pmuludq mm1,mm0 + paddq mm7,mm1 + paddq mm7,mm2 + movd DWORD [edx + ecx],mm7 + psrlq mm7,32 + add ecx,4 + cmp ecx,edi + jl .main_loop + + movd eax,mm7 + + emms + REST_GPR + ret +ENDFUNC cpAddMulDgt_BNU +%endif + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnumulschoolv8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnumulschoolv8as.asm new file mode 100644 index 000000000..29e679745 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnumulschoolv8as.asm @@ -0,0 +1,1217 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Arithmetic +; +; Content: +; cpMulAdc_BNU_school() +; +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_V8) +%include "pcpvariant.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; +;; Short-Length Squaring +;; +%macro INIT 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + movd xmm0,DWORD [%%a] ;; a[0] + pxor xmm7,xmm7 ;; clear carry + movd DWORD [%%r],xmm7 ;; r[0] = 0 + + %assign %%i 1 + movd xmm1,DWORD [%%a+%%i*4] ;; a[i] + pmuludq xmm1,xmm0 ;; t0 = a[i]*a[0] + movd xmm2,DWORD [%%a+%%i*4+4] ;; a[i+1] + pmuludq xmm2,xmm0 ;; t1 = a[i+1]*a[0] + + %rep (%%n-1)/2 + paddq xmm7,xmm1 ;; t0 += carry + %if %%n-(%%i+2) > 0 + movd xmm1,DWORD [%%a+(%%i+2)*4] ;; read in advance a[i+2] + pmuludq xmm1,xmm0 ;; multiply in advance a[i+2]*a[0] + %endif + movd DWORD [%%r+%%i*4],xmm7 ;; r[i] = LO(t0) + psrlq xmm7,32 ;; carry = HI(t0) + + paddq xmm7,xmm2 ;; t1 += carry + %if %%n-(%%i+3) > 0 + movd xmm2,DWORD [%%a+(%%i+2)*4+4] ;; read in advance a[i+3] + pmuludq xmm2,xmm0 ;; multiply in advance a[i+3]*a[0] + %endif + movd DWORD [%%r+%%i*4+4],xmm7 ;; r[i+1] = LO(t1) + psrlq xmm7,32 ;; carry = HI(t1) + + %assign %%i %%i+2 + %endrep + + %if (((%%n-1) & 1) != 0) + paddq xmm7,xmm1 ;; t0 += carry + movd DWORD [%%r+%%i*4],xmm7 ;; r[i] = LO(t0) + psrlq xmm7,32 ;; carry = HI(t0) + %endif + + movd DWORD [%%r+%%n*4],xmm7 ;; r[n] = extension +%endmacro + + +%macro UPDATE_MUL 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + %assign %%i 1 + %rep (%%n-2) + movd xmm0,DWORD [%%a+%%i*4] ;; a[i] + pxor xmm7,xmm7 ;; clear carry + + %assign %%j %%i+1 + movd xmm1,DWORD [%%a+%%j*4] ;; a[j] + pmuludq xmm1,xmm0 ;; t0 = a[j]*a[i] + movd xmm3,DWORD [%%r+(%%i+%%j)*4] ;; r[i+j] + %if (%%j+1) < %%n + movd xmm2,DWORD [%%a+%%j*4+4] ;; a[j+1] + pmuludq xmm2,xmm0 ;; t1 = a[j+1]*a[i] + movd xmm4,DWORD [%%r+(%%i+%%j)*4+4];; r[i+j+1] + %endif + + %assign %%tn %%n-%%j + %rep %%tn/2 + paddq xmm7,xmm1 ;; t0 += carry+r[i+j] + %if %%n-(%%j+2) > 0 + movd xmm1,DWORD [%%a+(%%j+2)*4] ;; read in advance a[j+2] + pmuludq xmm1,xmm0 ;; multiply in advance a[j+2]*a[i] + %endif + paddq xmm7,xmm3 + %if %%n-(%%j+2) > 0 + movd xmm3,DWORD [%%r+(%%i+2+%%j)*4];; read in advance r[i+j+2] + %endif + movd DWORD [%%r+(%%i+%%j)*4],xmm7 ;; r[i+j] = LO(t0) + psrlq xmm7,32 ;; carry = HI(t0) + + paddq xmm7,xmm2 ;; t1 += carry+r[i+j] + %if %%n-(%%j+3) > 0 + movd xmm2,DWORD [%%a+(%%j+2)*4+4];; read in advance a[j+3] + pmuludq xmm2,xmm0 ;; multiply in advance a[j+3]*a[i] + %endif + paddq xmm7,xmm4 + %if %%n-(%%j+3) > 0 + movd xmm4,DWORD [%%r+(%%i+2+%%j)*4+4];; read in advance r[i+j+3] + %endif + movd DWORD [%%r+(%%i+%%j)*4+4],xmm7 ;; r[i+j+1] = LO(t1) + psrlq xmm7,32 ;; carry = HI(t1) + + %assign %%j %%j+2 + %endrep + + %if ((%%tn & 1) != 0) + paddq xmm7,xmm1 + paddq xmm7,xmm3 + movd DWORD [%%r+(%%i+%%j)*4],xmm7 + psrlq xmm7,32 ;; carry = HI(t1) + %endif + + movd DWORD [%%r+(%%n+%%i)*4],xmm7 ;; r[i+j] = extension + + %assign %%i %%i+1 + %endrep + + pandn xmm7,xmm7 ;; clear carry + movd DWORD [%%r+(2*%%n-1)*4],xmm7 ;; r[2*n-1] = zero extension +%endmacro + + + +%macro FINALIZE 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + %assign %%i 0 + movd xmm0,DWORD [%%a+%%i*4] ;; a[i] + pmuludq xmm0,xmm0 ;; p = a[i]*a[i] + + movd xmm2,DWORD [%%r+(2*%%i)*4] ;; r[2*i] + paddq xmm2,xmm2 + movd xmm3,DWORD [%%r+(2*%%i+1)*4] ;; r[2*i+1] + paddq xmm3,xmm3 + + pcmpeqd xmm6,xmm6 ;; mm6 = low 32 bit mask + psrlq xmm6,32 + + pandn xmm7,xmm7 ;; clear carry + + %rep %%n + movq xmm1,xmm0 + pand xmm0,xmm6 ;; mm0 = LO(p) + psrlq xmm1,32 ;; mm1 = HI(p) + + paddq xmm7,xmm0 ;; q = carry + 2*r[2*i] + LO(p) + %if %%n-(%%i+1) > 0 + movd xmm0,DWORD [%%a+(%%i+1)*4] ;; a[i] + pmuludq xmm0,xmm0 ;; p = a[i]*a[i] + %endif + paddq xmm7,xmm2 + %if %%n-(%%i+1) > 0 + movd xmm2,DWORD [%%r+(2*%%i+2)*4] ;; r[2*(i+1)] + paddq xmm2,xmm2 + %endif + movd DWORD [%%r+(2*%%i)*4],xmm7 ;; r[2*i] = LO(q) + psrlq xmm7,32 ;; carry = HI(q) + + paddq xmm7,xmm1 ;; q = carry + 2*r[2*i+1] + HI(p) + paddq xmm7,xmm3 + %if %%n-(%%i+1) > 0 + movd xmm3,DWORD [%%r+(2*%%i+2)*4+4];; r[2*(i+1)+1] + paddq xmm3,xmm3 + %endif + movd DWORD [%%r+(2*%%i+1)*4],xmm7 ;; r[2*i+1] = LO(q) + psrlq xmm7,32 ;; carry = HI(q) + + %assign %%i %%i+1 + %endrep +%endmacro + + +%macro SQR_SHORT 3 + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + INIT %%r,%%a,%%n + UPDATE_MUL %%r,%%a,%%n + FINALIZE %%r,%%a,%%n +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; Middle-Length Squaring +;; +%macro SQR_DECOMPOSE 1.nolist + %xdefine %%i %1 + + movd xmm7,DWORD [eax + 4*%%i] + movd xmm0,DWORD [eax + 4*%%i] + movd xmm6,DWORD [eax + 4*%%i] + + %if %%i != 0 + movd xmm1,DWORD [edx + 4*(2*%%i)] + %endif + + psllq xmm0,1 + pmuludq xmm7,xmm7 + psrad xmm6,32 + + %if %%i != 0 + paddq xmm7,xmm1 + %endif + + movd DWORD [edx + 4*(2*%%i)],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro MULADD_START 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd xmm1,DWORD [eax + 4*%%j] + movd xmm3,DWORD [eax + 4*%%j] + pmuludq xmm1,xmm0 + paddq xmm7,xmm1 + movd DWORD [edx + 4*(%%i+%%j)],xmm7 + pand xmm3,xmm6 + psrlq xmm7,32 + paddq xmm7,xmm3 +%endmacro + + +%macro MULADD 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd xmm1,DWORD [eax + 4*%%j] + movd xmm3,DWORD [eax + 4*%%j] + movd xmm2,DWORD [edx + 4*(%%i+%%j)] + pmuludq xmm1,xmm0 + pand xmm3,xmm6 + paddq xmm1,xmm2 + paddq xmm7,xmm1 + movd DWORD [edx + 4*(%%i+%%j)],xmm7 + psrlq xmm7,32 + paddq xmm7,xmm3 +%endmacro + + +%macro STORE_CARRY 2.nolist + %xdefine %%i %1 + %xdefine %%nsize %2 + + movq QWORD [edx + 4*(%%i + %%nsize)],xmm7 +%endmacro + + +%macro STORE_CARRY_NEXT 2.nolist + %xdefine %%i %1 + %xdefine %%nsize %2 + + movd xmm4,DWORD [edx + 4*(%%i + %%nsize)] + paddq xmm4,xmm7 + movd DWORD [edx + 4*(%%i + %%nsize)],xmm4 + psrlq xmm7,32 + movd DWORD [edx + 4*(%%i + %%nsize + 1)],xmm7 +%endmacro + + +%macro INNER_LOOP 2.nolist + %xdefine %%i %1 + %xdefine %%nsize %2 + + %assign %%j %%i + 1 + %assign %%s %%nsize - %%i - 1 + + SQR_DECOMPOSE %%i + + %rep %%s + %if %%i == 0 + MULADD_START %%i,%%j + el%%se + MULADD %%i,%%j + %endif + + %assign %%j %%j + 1 + %endrep + + %if %%i == 0 + STORE_CARRY %%i,%%nsize + el%%se + STORE_CARRY_NEXT %%i,%%nsize + %endif +%endmacro + + +%macro LAST_STEP 1.nolist + %xdefine %%nsize %1 + + movd xmm7,DWORD [eax + 4*(%%nsize - 1)] + pmuludq xmm7,xmm7 + movd xmm2,DWORD [edx + 4*(2*%%nsize - 2)] + paddq xmm7,xmm2 + movd xmm4,DWORD [edx + 4*(2*%%nsize - 1)] + movd DWORD [edx + 4*(2*%%nsize - 2)],xmm7 + psrlq xmm7,32 + paddq xmm7,xmm4 + movd DWORD [edx + 4*(2*%%nsize - 1)],xmm7 +%endmacro + + +%macro SQR_MIDDL 1.nolist + %xdefine %%nsize %1 + + %assign %%i 0 + %rep %%nsize - 1 + INNER_LOOP %%i,%%nsize + %assign %%i %%i + 1 + %endrep + LAST_STEP %%nsize +%endmacro + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%macro UNROLL16_MULADD 0.nolist + movd xmm1,DWORD [eax + ecx] + movd xmm2,DWORD [edx + ecx] + movd xmm3,DWORD [eax + ecx + 4] + movd xmm4,DWORD [edx + ecx + 4] + movd xmm5,DWORD [eax + ecx + 8] + movd xmm6,DWORD [edx + ecx + 8] + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax + ecx + 12] + movd xmm2,DWORD [edx + ecx + 12] + movd DWORD [edx + ecx],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax + ecx + 16] + movd xmm4,DWORD [edx + ecx + 16] + movd DWORD [edx + ecx + 4],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax + ecx + 20] + movd xmm6,DWORD [edx + ecx + 20] + movd DWORD [edx + ecx + 8],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax + ecx + 24] + movd xmm2,DWORD [edx + ecx + 24] + movd DWORD [edx + ecx + 12],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax + ecx + 28] + movd xmm4,DWORD [edx + ecx + 28] + movd DWORD [edx + ecx + 16],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax + ecx + 32] + movd xmm6,DWORD [edx + ecx + 32] + movd DWORD [edx + ecx + 20],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax + ecx + 36] + movd xmm2,DWORD [edx + ecx + 36] + movd DWORD [edx + ecx + 24],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax + ecx + 40] + movd xmm4,DWORD [edx + ecx + 40] + movd DWORD [edx + ecx + 28],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax + ecx + 44] + movd xmm6,DWORD [edx + ecx + 44] + movd DWORD [edx + ecx + 32],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax + ecx + 48] + movd xmm2,DWORD [edx + ecx + 48] + movd DWORD [edx + ecx + 36],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax + ecx + 52] + movd xmm4,DWORD [edx + ecx + 52] + movd DWORD [edx + ecx + 40],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax + ecx + 56] + movd xmm6,DWORD [edx + ecx + 56] + movd DWORD [edx + ecx + 44],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax + ecx + 60] + movd xmm2,DWORD [edx + ecx + 60] + movd DWORD [edx + ecx + 48],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd DWORD [edx + ecx + 52],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm5 + movd DWORD [edx + ecx + 56],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm1 + movd DWORD [edx + ecx + 60],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro UNROLL8_MULADD 0.nolist + movd xmm1,DWORD [eax + ecx] + movd xmm2,DWORD [edx + ecx] + movd xmm3,DWORD [eax + ecx + 4] + movd xmm4,DWORD [edx + ecx + 4] + movd xmm5,DWORD [eax + ecx + 8] + movd xmm6,DWORD [edx + ecx + 8] + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax + ecx + 12] + movd xmm2,DWORD [edx + ecx + 12] + movd DWORD [edx + ecx],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax + ecx + 16] + movd xmm4,DWORD [edx + ecx + 16] + movd DWORD [edx + ecx + 4],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax + ecx + 20] + movd xmm6,DWORD [edx + ecx + 20] + movd DWORD [edx + ecx + 8],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax + ecx + 24] + movd xmm2,DWORD [edx + ecx + 24] + movd DWORD [edx + ecx + 12],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax + ecx + 28] + movd xmm4,DWORD [edx + ecx + 28] + movd DWORD [edx + ecx + 16],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd DWORD [edx + ecx + 20],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm1 + movd DWORD [edx + ecx + 24],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm3 + movd DWORD [edx + ecx + 28],xmm7 + psrlq xmm7,32 +%endmacro + + + +%macro MUL_MAC0_START 0.nolist + movd xmm7,DWORD [eax] + pmuludq xmm7,xmm0 + movd DWORD [edx],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro MUL_MAC0_START2 0.nolist + movd xmm1,DWORD [eax] + pmuludq xmm1,xmm0 + movd DWORD [edx],xmm1 + psrlq xmm1,32 + + movd xmm7,DWORD [eax+4] + pmuludq xmm7,xmm0 + paddq xmm7,xmm1 + movd DWORD [edx+4],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro MUL_MAC0 1.nolist + %xdefine %%j %1 + + movd xmm1,DWORD [eax + 4*%%j] + pmuludq xmm1,xmm0 + paddq xmm1,xmm7 + movd DWORD [edx + 4*%%j],xmm1 + psrlq xmm1,32 + + movd xmm7,DWORD [eax + 4*(%%j+1)] + pmuludq xmm7,xmm0 + paddq xmm7,xmm1 + movd DWORD [edx + 4*(%%j+1)],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro MUL_MAC_START 1.nolist + %xdefine %%i %1 + + movd xmm7,DWORD [eax] + pmuludq xmm7,xmm0 + movd xmm2,DWORD [edx + 4*(%%i)] + paddq xmm7,xmm2 + movd DWORD [edx + 4*(%%i)],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro MUL_MAC_START2 1.nolist + %xdefine %%i %1 + + movd xmm1,DWORD [eax] + pmuludq xmm1,xmm0 + movd xmm2,DWORD [edx + 4*%%i] + paddq xmm1,xmm2 + movd DWORD [edx + 4*%%i],xmm1 + psrlq xmm1,32 + + movd xmm7,DWORD [eax+4] + pmuludq xmm7,xmm0 + movd xmm2,DWORD [edx + 4*(%%i+1)] + paddq xmm7,xmm2 + paddq xmm7,xmm1 + movd DWORD [edx + 4*(%%i+1)],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro MUL_MAC 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd xmm1,DWORD [eax + 4*%%j] + pmuludq xmm1,xmm0 + movd xmm2,DWORD [edx + 4*(%%i+%%j)] + paddq xmm1,xmm2 + paddq xmm1,xmm7 + movd DWORD [edx + 4*(%%i+%%j)],xmm1 + psrlq xmm1,32 + + movd xmm7,DWORD [eax + 4*(%%j+1)] + pmuludq xmm7,xmm0 + movd xmm2,DWORD [edx + 4*(%%i+%%j+1)] + paddq xmm7,xmm2 + paddq xmm7,xmm1 + movd DWORD [edx + 4*(%%i+%%j+1)],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro INNER_LOOP1 2.nolist + %xdefine %%i %1 + %xdefine %%nsize %2 + + %assign %%j 0 + movd xmm0,DWORD [ebx + 4*%%i] + + %if %%i == 0 + %if %%nsize & 1 + MUL_MAC0_START + %assign %%j %%j + 1 + %else + MUL_MAC0_START2 + %assign %%j %%j + 2 + %endif + %else + %if %%nsize & 1 + MUL_MAC_START %%i + %assign %%j %%j + 1 + %else + MUL_MAC_START2 %%i + %assign %%j %%j + 2 + %endif + %endif + + %rep ((%%nsize-%%j)/2) + %if %%i == 0 + MUL_MAC0 %%j + %else + MUL_MAC %%i,%%j + %endif + %assign %%j %%j + 2 + %endrep + movd DWORD [edx + 4*(%%i + %%nsize)],xmm7 +%endmacro + + +%macro OUTER_LOOP1 1.nolist + %xdefine %%nsize %1 + + %assign %%i 0 + %rep %%nsize + INNER_LOOP1 %%i,%%nsize + %assign %%i %%i+1 + %endrep +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + +%if (_USE_C_cpMulAdc_BNU_school_ == 0) +;************************************************************* +;* +;* void cpMulAdc_BNU_school(Ipp32u* pR, +;* const Ipp32u* pA, int aSize, +;* const Ipp32u* pB, int bSize) +;* +;************************************************************* + +;; +;; Lib = V8 +;; +;; Caller = ippsMontMul +;; Caller = ippsMontExp +;; Caller = ippsModInv_BN +;; +;; Caller = ippsECCPGetPoint +;; Caller = ippsECCPCheckPoint +;; Caller = ippsECCPAddPoint +;; Caller = ippsECCPMulPointScalar +;; Caller = ippsECCPGenKeyPair +;; Caller = ippsECCPPublicKey +;; Caller = ippsECCPValidateKey +;; Caller = ippsECCPShareSecretKeyDH +;; Caller = ippsECCPShareSecretKeyDHC +;; Caller = ippsECCPSignDSA +;; Caller = ippsECCPSignNR +;; Caller = ippsECCPVerifyDSA +;; Caller = ippsECCPVerifyNR +;; +IPPASM cpMulAdc_BNU_school,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; target address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source address +%xdefine aSize [esp + ARG_1 + 2*sizeof(dword)] ; BNU length +%xdefine pB [esp + ARG_1 + 3*sizeof(dword)] ; source address +%xdefine bSize [esp + ARG_1 + 4*sizeof(dword)] ; BNU length + + mov eax,pA ; pA + mov edi,aSize ; aSzie_len + mov ebx,pB ; pB + mov esi,bSize ; bSize + mov edx,pR ; pR + + cmp eax,ebx + jne .multiplication + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; squaring +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp edi,1 + jg .sqr2 +.sqr1: + movd xmm0,DWORD [eax] + pmuludq xmm0,xmm0 + movq QWORD [edx],xmm0 + jmp .finish + +.sqr2: + cmp edi,2 + jg .sqr3 + movd xmm0,DWORD [eax] + movd xmm1,DWORD [eax+4] + + movq xmm2,xmm0 + pmuludq xmm0,xmm0 ; a[0]*a[0] + pmuludq xmm2,xmm1 ; a[0]*a[1] + pmuludq xmm1,xmm1 ; a[1]*a[1] + + pcmpeqd xmm7,xmm7 ; mm7 = low 32 bit mask + psrlq xmm7,32 + + pand xmm7,xmm2 ; mm7 = LO(a[0]*a[1]) + paddq xmm7,xmm7 + psrlq xmm2,32 ; mm2 = HI(a[0]*a[1]) + paddq xmm2,xmm2 + + movd DWORD [edx],xmm0 + psrlq xmm0,32 + + paddq xmm0,xmm7 + movd DWORD [edx+4],xmm0 + psrlq xmm0,32 + + paddq xmm2,xmm1 + paddq xmm2,xmm0 + movq QWORD [edx+8],xmm2 + jmp .finish + +.sqr3: + cmp edi,3 + jg .sqr4 + SQR_SHORT edx,eax,3 + jmp .finish + +.sqr4: + cmp edi,4 + jg .sqr5 + SQR_SHORT edx,eax,4 + jmp .finish + +.sqr5: + cmp edi,5 + jg .sqr6 + SQR_SHORT edx,eax,5 + jmp .finish + +.sqr6: + cmp edi,6 + jg .sqr7 + SQR_SHORT edx,eax,6 + jmp .finish + +.sqr7: + cmp edi,7 + jg .sqr8 + SQR_SHORT edx,eax,7 + jmp .finish + +.sqr8: + cmp edi,8 + jg .sqr9 + ;SQR_MIDDL 8 + SQR_SHORT edx,eax,8 + jmp .finish + +.sqr9: + cmp edi,9 + jg .sqr10 + ;SQR_MIDDL 9 + SQR_SHORT edx,eax,9 + jmp .finish + +.sqr10: + cmp edi,10 + jg .sqr11 + ;SQR_MIDDL 10 + SQR_SHORT edx,eax,10 + jmp .finish + +.sqr11: + cmp edi,11 + jg .sqr12 + ;SQR_MIDDL 11 + SQR_SHORT edx,eax,11 + jmp .finish + +.sqr12: + cmp edi,12 + jg .sqr13 + ;SQR_MIDDL 12 + SQR_SHORT edx,eax,12 + jmp .finish + +.sqr13: + cmp edi,13 + jg .sqr14 + ;SQR_MIDDL 13 + SQR_SHORT edx,eax,13 + jmp .finish + +.sqr14: + cmp edi,14 + jg .sqr15 + ;SQR_MIDDL 14 + SQR_SHORT edx,eax,14 + jmp .finish + +.sqr15: + cmp edi,15 + jg .sqr16 + ;SQR_MIDDL 15 + SQR_SHORT edx,eax,15 + jmp .finish + +.sqr16: + cmp edi,16 + jg .sqr17 + ;SQR_MIDDL 16 + SQR_SHORT edx,eax,16 + jmp .finish + +.sqr17: + cmp edi,17 + jg .common_case_sqr + ;SQR_MIDDL 17 + SQR_SHORT edx,eax,17 + jmp .finish + +;; +;; General case Squaring (aSize > 17) +;; +.common_case_sqr: + mov ebx,edx ; copy pR + mov ecx,edi ; copy aSize +;; +;; init result: +;; r = (a[1],a[2],..a[N-1]) * a[0] +;; + mov edx,1 ; i=1 + movd xmm0,DWORD [eax] ; a[0] + movd xmm1,DWORD [eax+edx*4] ; a[i] + pmuludq xmm1,xmm0 ; p = a[i]*a[0] + pandn xmm7,xmm7 ; clear carry + movd DWORD [ebx],xmm7 ; r[0] = 0 +.sqr_init_loop: + movd xmm2,DWORD [eax+edx*4+4] ; read in advance a[i+1] + pmuludq xmm2,xmm0 ; q = a[i+1]*a[0] + + paddq xmm7,xmm1 ; p+= carry + movd DWORD [ebx+edx*4],xmm7 ; r[i] = LO(p) + psrlq xmm7,32 ; carry = HI(p) + + add edx,2 + cmp edx,ecx + jg .sqr_break_init_loop + + movd xmm1,DWORD [eax+edx*4] ; next a[i] + pmuludq xmm1,xmm0 ; p = a[i]*a[0] + + paddq xmm7,xmm2 ; q += carry + movd DWORD [ebx+edx*4-4],xmm7 ; r[i+1] = LO(q) + psrlq xmm7,32 ; carry = HI(q) + + jl .sqr_init_loop + +.sqr_break_init_loop: + movd DWORD [ebx+ecx*4],xmm7 ; r[aSize] = carry + +;; +;; add other a[i]*a[j], i=1,..,N-1, j=i+1,..,N-1 +;; + mov edx,1 ; i=1 + +.sqr_update_mul_loop: + mov esi,edx ; j=i+1 + add esi,1 + mov edi,edx ; i+j + add edi,esi + + movd xmm0,DWORD [eax+edx*4] ; a[i] + movd xmm1,DWORD [eax+esi*4] ; a[j] + pmuludq xmm1,xmm0 ; p = a[j]*a[i] + movd xmm3,DWORD [ebx+edi*4] ; r[i+j] + pandn xmm7,xmm7 ; clear carry + +.sqr_update_mul_inner_loop: + paddq xmm7,xmm1 ; p += carry+r[i+j] + paddq xmm7,xmm3 + movd DWORD [ebx+edi*4],xmm7 ; r[i+j] = LO(p) + psrlq xmm7,32 ; carry = HI(p) + + movd xmm1,DWORD [eax+esi*4+4] ; read in advance a[i+1] + pmuludq xmm1,xmm0 ; p = a[j+1]*a[i] + movd xmm3,DWORD [ebx+edi*4+4] ; read in advance r[i+j+1] + + add edi,1 + add esi,1 + cmp esi,ecx + jl .sqr_update_mul_inner_loop + + movd DWORD [ebx+edi*4],xmm7 ; r[i+j] = carry + add edx,1 + sub esi,1 + cmp edx,esi + jl .sqr_update_mul_loop + pandn xmm7,xmm7 ; clear carry + movd DWORD [ebx+edi*4+4],xmm7 ; r[i+j+1] = 0 + +;; +;; double a[i]*a[j] and add a[i]^2 +;; + pcmpeqd xmm6,xmm6 ; xmm6 = low 32 bit mask + psrlq xmm6,32 + + movd xmm0,DWORD [eax] ; a[i] + pmuludq xmm0,xmm0 ; p = a[i]*a[i] + mov edx,0 ; i=0 + movd xmm2,DWORD [ebx] ; r[2*i] + movd xmm3,DWORD [ebx+4] ; r[2*i+1] + pandn xmm7,xmm7 ; clear carry +.sqr_loop: + paddq xmm2,xmm2 ; 2*r[2*i] + paddq xmm3,xmm3 ; 2*r[2*i+1] + + movq xmm1,xmm0 + pand xmm0,xmm6 ; xmm0 = LO(p) + psrlq xmm1,32 ; xmm1 = HI(p) + + paddq xmm7,xmm2 ; q = carry + 2*r[2*i] + LO(p) + paddq xmm7,xmm0 + movd DWORD [ebx+edx*8],xmm7 ; r[2*i] = LO(q) + psrlq xmm7,32 ; carry = HI(q) + + movd xmm0,DWORD [eax+edx*4+4] ; read in advance a[i+1] + pmuludq xmm0,xmm0 ; p = a[i+1]*a[i+1] + + paddq xmm7,xmm3 ; q = carry + 2*r[2*i+1] + HI(p) + paddq xmm7,xmm1 + movd DWORD [ebx+edx*8+4],xmm7 ; r[2*i+1] = LO(q) + psrlq xmm7,32 ; carry = HI(q) + + add edx,1 + movd xmm2,DWORD [ebx+edx*8] ; r[2*(i+1)] + movd xmm3,DWORD [ebx+edx*8+4] ; r[2*(i+1)+1] + cmp edx,ecx + jl .sqr_loop + + jmp .finish + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; multiplication +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.multiplication: + cmp edi,esi + jne .common_case_mul + +.mul4: + cmp edi,4 + jne .mul5 + OUTER_LOOP1 4 + jmp .finish + +.mul5: + cmp edi,5 + jne .mul6 + OUTER_LOOP1 5 + jmp .finish + +.mul6: + cmp edi,6 + jne .mul7 + OUTER_LOOP1 6 + jmp .finish + +.mul7: + cmp edi,7 + jne .mul8 + OUTER_LOOP1 7 + jmp .finish + +.mul8: + cmp edi,8 + jne .mul9 + OUTER_LOOP1 8 + jmp .finish + +.mul9: + cmp edi,9 + jne .mul10 + OUTER_LOOP1 9 + jmp .finish + +.mul10: + cmp edi,10 + jne .mul11 + OUTER_LOOP1 10 + jmp .finish + +.mul11: + cmp edi,11 + jne .mul12 + OUTER_LOOP1 11 + jmp .finish + +.mul12: + cmp edi,12 + jne .mul13 + OUTER_LOOP1 12 + jmp .finish + +.mul13: + cmp edi,13 + jne .mul14 + OUTER_LOOP1 13 + jmp .finish + +.mul14: + cmp edi,14 + jne .mul15 + OUTER_LOOP1 14 + jmp .finish + +.mul15: + cmp edi,15 + jne .mul16 + OUTER_LOOP1 15 + jmp .finish + +.mul16: + cmp edi,16 + jne .mul17 + OUTER_LOOP1 16 + jmp .finish + +.mul17: + cmp edi,17 + jne .common_case_mul + OUTER_LOOP1 17 + jmp .finish + +;; +;; General case Multiplication +;; +.common_case_mul: + cmp esi,edi ; bSize ~ aSize + jae .ini_result + + xor edi,esi ; swap(aSize,bSize) + xor esi,edi + xor edi,esi + mov edi,aSize + mov esi,bSize + + xor eax,ebx ; swap(pA,pB) + xor ebx,eax + xor eax,ebx + mov eax,pA + mov ebx,pB + +.ini_result: + add esi,edi + xor ecx,ecx +.mul_init_loop: + mov [edx],ecx + add edx,4 + sub esi,1 + jne .mul_init_loop + + mov esi,edi ; restore aSize + mov edx,pR ; restore pR + + shl edi,2 ; aSize*4 +; +; multiplication loop +; +.macLoop: + movd xmm0,DWORD [ebx] ; pB[] + pxor xmm7,xmm7 + mov esi,edi ; number of loops (==aSize*4) + xor ecx,ecx ; init loop counter + + and esi,7*4 + jz .testSize_8 +.tiny_loop: + movd xmm1,DWORD [eax+ecx] + movd xmm2,DWORD [edx+ecx] + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + paddq xmm7,xmm1 + movd DWORD [edx+ecx],xmm7 + psrlq xmm7,32 + + add ecx,4 + cmp ecx,esi + jl .tiny_loop + +.testSize_8: + mov esi,edi ; restore aSize*4 + and esi,8*4 + jz .testSize_16 + + UNROLL8_MULADD + add ecx,8*4 + +.testSize_16: + mov esi,edi ; restore aSize*4 + and esi,0FFFFFFC0h + jz .next_term + +.huge_loop: + UNROLL16_MULADD + add ecx,16*4 + cmp ecx,esi + jl .huge_loop + +.next_term: + movd DWORD [edx + ecx],xmm7 + + add ebx,4 ; move to the next B[] + add edx,4 ; move pR + sub dword bSize,1 ; decrease bSize + jne .macLoop + +.finish: + REST_GPR + ret +ENDFUNC cpMulAdc_BNU_school +%endif + +%endif ;; _IPP_V8 diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnusqrw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnusqrw7as.asm new file mode 100644 index 000000000..4f77f911a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnusqrw7as.asm @@ -0,0 +1,706 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Purpose: Cryptography Primitive. +; Big Number Arithmetic +; +; Content: +; cpSqrAdc_BNU_school() +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_W7) +%include "pcpvariant.inc" + +;; +;; Short-Length Squaring +;; +%macro INIT 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + movd mm0,DWORD [%%a] ;; a[0] + pandn mm7,mm7 ;; clear carry + movd DWORD [%%r],mm7 ;; r[0] = 0 + + %assign %%i 1 + movd mm1,DWORD [%%a+%%i*4] ;; a[i] + pmuludq mm1,mm0 ;; t0 = a[i]*a[0] + movd mm2,DWORD [%%a+%%i*4+4] ;; a[i+1] + pmuludq mm2,mm0 ;; t1 = a[i+1]*a[0] + + %rep (%%n-1)/2 + paddq mm7,mm1 ;; t0 += carry + %if %%n-(%%i+2) > 0 + movd mm1,DWORD [%%a+(%%i+2)*4] ;; read in advance a[i+2] + pmuludq mm1,mm0 ;; multiply in advance a[i+2]*a[0] + %endif + movd DWORD [%%r+%%i*4],mm7 ;; r[i] = LO(t0) + psrlq mm7,32 ;; carry = HI(t0) + + paddq mm7,mm2 ;; t1 += carry + %if %%n-(%%i+3) > 0 + movd mm2,DWORD [%%a+(%%i+2)*4+4] ;; read in advance a[i+3] + pmuludq mm2,mm0 ;; multiply in advance a[i+3]*a[0] + %endif + movd DWORD [%%r+%%i*4+4],mm7 ;; r[i+1] = LO(t1) + psrlq mm7,32 ;; carry = HI(t1) + + %assign %%i %%i+2 + %endrep + + %if (((%%n-1) & 1) != 0) + paddq mm7,mm1 ;; t0 += carry + movd DWORD [%%r+%%i*4],mm7 ;; r[i] = LO(t0) + psrlq mm7,32 ;; carry = HI(t0) + %endif + + movd DWORD [%%r+%%n*4],mm7 ;; r[n] = extension +%endmacro + + +%macro UPDATE_MUL 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + %assign %%i 1 + %rep (%%n-2) + movd mm0,DWORD [%%a+%%i*4] ;; a[i] + pandn mm7,mm7 ;; clear carry + + %assign %%j %%i+1 + movd mm1,DWORD [%%a+%%j*4] ;; a[j] + pmuludq mm1,mm0 ;; t0 = a[j]*a[i] + movd mm3,DWORD [%%r+(%%i+%%j)*4] ;; r[i+j] + %if (%%j+1) < %%n + movd mm2,DWORD [%%a+%%j*4+4] ;; a[j+1] + pmuludq mm2,mm0 ;; t1 = a[j+1]*a[i] + movd mm4,DWORD [%%r+(%%i+%%j)*4+4] ;; r[i+j+1] + %endif + + %assign %%tn %%n-%%j + %rep %%tn/2 + paddq mm7,mm1 ;; t0 += carry+r[i+j] + %if %%n-(%%j+2) > 0 + movd mm1,DWORD [%%a+(%%j+2)*4] ;; read in advance a[j+2] + pmuludq mm1,mm0 ;; multiply in advance a[j+2]*a[i] + %endif + paddq mm7,mm3 + %if %%n-(%%j+2) > 0 + movd mm3,DWORD [%%r+(%%i+2+%%j)*4] ;; read in advance r[i+j+2] + %endif + movd DWORD [%%r+(%%i+%%j)*4],mm7 ;; r[i+j] = LO(t0) + psrlq mm7,32 ;; carry = HI(t0) + + paddq mm7,mm2 ;; t1 += carry+r[i+j] + %if %%n-(%%j+3) > 0 + movd mm2,DWORD [%%a+(%%j+2)*4+4] ;; read in advance a[j+3] + pmuludq mm2,mm0 ;; multiply in advance a[j+3]*a[i] + %endif + paddq mm7,mm4 + %if %%n-(%%j+3) > 0 + movd mm4,DWORD [%%r+(%%i+2+%%j)*4+4];; read in advance r[i+j+3] + %endif + movd DWORD [%%r+(%%i+%%j)*4+4],mm7 ;; r[i+j+1] = LO(t1) + psrlq mm7,32 ;; carry = HI(t1) + + %assign %%j %%j+2 + %endrep + + %if ((%%tn & 1) != 0) + paddq mm7,mm1 + paddq mm7,mm3 + movd DWORD [%%r+(%%i+%%j)*4],mm7 + psrlq mm7,32 ;; carry = HI(t1) + %endif + + movd DWORD [%%r+(%%n+%%i)*4],mm7 ;; r[i+j] = extension + + %assign %%i %%i+1 + %endrep + + pandn mm7,mm7 ;; clear carry + movd DWORD [%%r+(2*%%n-1)*4],mm7 ;; r[2*n-1] = zero extension +%endmacro + + + +%macro FINALIZE 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + %assign %%i 0 + movd mm0,DWORD [%%a+%%i*4] ;; a[i] + pmuludq mm0,mm0 ;; p = a[i]*a[i] + + movd mm2,DWORD [%%r+(2*%%i)*4] ;; r[2*i] + paddq mm2,mm2 + movd mm3,DWORD [%%r+(2*%%i+1)*4];; r[2*i+1] + paddq mm3,mm3 + + pcmpeqd mm6,mm6 ;; mm6 = low 32 bit mask + psrlq mm6,32 + + pandn mm7,mm7 ;; clear carry + + %rep %%n + movq mm1,mm0 + pand mm0,mm6 ;; mm0 = LO(p) + psrlq mm1,32 ;; mm1 = HI(p) + + paddq mm7,mm0 ;; q = carry + 2*r[2*i] + LO(p) + %if %%n-(%%i+1) > 0 + movd mm0,DWORD [%%a+(%%i+1)*4] ;; a[i] + pmuludq mm0,mm0 ;; p = a[i]*a[i] + %endif + paddq mm7,mm2 + %if %%n-(%%i+1) > 0 + movd mm2,DWORD [%%r+(2*%%i+2)*4] ;; r[2*(i+1)] + paddq mm2,mm2 + %endif + movd DWORD [%%r+(2*%%i)*4],mm7 ;; r[2*i] = LO(q) + psrlq mm7,32 ;; carry = HI(q) + + paddq mm7,mm1 ;; q = carry + 2*r[2*i+1] + HI(p) + paddq mm7,mm3 + %if %%n-(%%i+1) > 0 + movd mm3,DWORD [%%r+(2*%%i+2)*4+4] ;; r[2*(i+1)+1] + paddq mm3,mm3 + %endif + movd DWORD [%%r+(2*%%i+1)*4],mm7 ;; r[2*i+1] = LO(q) + psrlq mm7,32 ;; carry = HI(q) + + %assign %%i %%i+1 + %endrep +%endmacro + + +%macro INIT1 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + movd mm0,DWORD [%%a] ;; a[0] + pandn mm7,mm7 ;; clear carry + movd DWORD [%%r],mm7 ;; r[0] = 0 + + %assign %%i 1 + %rep (%%n-1) + movd mm1,DWORD [%%a+%%i*4] ;; a[i] + pmuludq mm1,mm0 ;; t0 = a[i]*a[0] + paddq mm7,mm1 ;; t0 += carry + movd DWORD [%%r+%%i*4],mm7 ;; r[i] = LO(t0) + psrlq mm7,32 ;; carry = HI(t0) + %assign %%i %%i+1 + %endrep + movd DWORD [%%r+%%n*4],mm7 ;; r[n] = extension +%endmacro + + +%macro UPDATE_MUL1 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + %assign %%i 1 + %rep (%%n-2) + movd mm0,DWORD [%%a+%%i*4] ;; a[i] + pandn mm7,mm7 ;; clear carry + + %assign %%j %%i+1 + %rep (%%n-%%j) + movd mm1,DWORD [%%a+%%j*4] ;; a[j]) + pmuludq mm1,mm0 ;; t0 = a[j]*a[i] + movd mm3,DWORD [%%r+(%%i+%%j)*4] ;; r[i+j] + paddq mm7,mm1 ;; t0 += carry+r[i+j] + paddq mm7,mm3 + movd DWORD [%%r+(%%i+%%j)*4],mm7 ;; r[i+j] = LO(t0) + psrlq mm7,32 ;; carry = HI(t0) + %assign %%j %%j+1 + %endrep + + movd DWORD [%%r+(%%n+%%i)*4],mm7 ;; r[i+j] = extension + %assign %%i %%i+1 + %endrep + + pandn mm7,mm7 ;; clear carry + movd DWORD [%%r+(2*%%n-1)*4],mm7 ;; r[2*n-1] = zero extension +%endmacro + + +%macro SQUARE_SHORT 3.nolist + %xdefine %%r %1 + %xdefine %%a %2 + %xdefine %%n %3 + + INIT %%r,%%a,%%n + UPDATE_MUL %%r,%%a,%%n + FINALIZE %%r,%%a,%%n + emms +%endmacro + + + +;; +;; Middle-Length Squaring +;; +%macro SQR_DECOMPOSE 1.nolist + %xdefine %%i %1 + + movd mm7,DWORD [eax + 4*%%i] + movd mm0,DWORD [eax + 4*%%i] + movd mm6,DWORD [eax + 4*%%i] + %if %%i != 0 + movd mm1,DWORD [ebx + 4*(2*%%i)] + %endif + pslld mm0,1 + pmuludq mm7,mm7 + psrad mm6,32 + %if %%i != 0 + paddq mm7,mm1 + %endif + movd DWORD [ebx + 4*(2*%%i)],mm7 + psrlq mm7,32 +%endmacro + + + +%macro MULADD_START 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd mm1,DWORD [eax + 4*%%j] + movd mm3,DWORD [eax + 4*%%j] + pmuludq mm1,mm0 + paddq mm7,mm1 + movd DWORD [ebx + 4*(%%i+%%j)],mm7 + pand mm3,mm6 + psrlq mm7,32 + paddq mm7,mm3 +%endmacro + + +%macro MULADD 2.nolist + %xdefine %%i %1 + %xdefine %%j %2 + + movd mm1,DWORD [eax + 4*%%j] + movd mm3,DWORD [eax + 4*%%j] + movd mm2,DWORD [ebx + 4*(%%i+%%j)] + pmuludq mm1,mm0 + pand mm3,mm6 + paddq mm1,mm2 + paddq mm7,mm1 + movd DWORD [ebx + 4*(%%i+%%j)],mm7 + psrlq mm7,32 + paddq mm7,mm3 +%endmacro + + +%macro STORE_CARRY 2.nolist + %xdefine %%i %1 + %xdefine %%s %2 + + movq [ebx + 4*(%%i + %%s)],mm7 +%endmacro + + +%macro STORE_CARRY_NEXT 2.nolist + %xdefine %%i %1 + %xdefine %%s %2 + + movd mm4,DWORD [ebx + 4*(%%i + %%s)] + paddq mm4,mm7 + movd DWORD [ebx + 4*(%%i + %%s)],mm4 + psrlq mm7,32 + movd DWORD [ebx + 4*(%%i + %%s + 1)],mm7 +%endmacro + + +%macro INNER_LOOP 2.nolist + %xdefine %%i %1 + %xdefine %%nsize %2 + + %assign %%j %%i + 1 + %assign %%s %%nsize - %%i - 1 + + SQR_DECOMPOSE %%i + + %rep %%s + %if %%i == 0 + MULADD_START %%i,%%j + el%%se + MULADD %%i,%%j + %endif + %assign %%j %%j + 1 + %endrep + + %if %%i == 0 + STORE_CARRY %%i,%%nsize + %else + STORE_CARRY_NEXT %%i,%%nsize + %endif +%endmacro + + +%macro LAST_STEP 1.nolist + %xdefine %%s %1 + + movd mm7,DWORD [eax + 4*(%%s - 1)] + movd mm2,DWORD [ebx + 4*(2*%%s - 2)] + pmuludq mm7,mm7 + paddq mm7,mm2 + movd mm4,DWORD [ebx + 4*(2*%%s - 1)] + movd DWORD [ebx + 4*(2*%%s - 2)],mm7 + psrlq mm7,32 + paddq mm4,mm7 + movd DWORD [ebx + 4*(2*%%s - 1)],mm4 +%endmacro + + +%macro SQUARE_MIDL 1.nolist + %xdefine %%nsize %1 + + %assign %%i 0 + %rep %%nsize - 1 + INNER_LOOP %%i,%%nsize + %assign %%i %%i + 1 + %endrep + LAST_STEP %%nsize + emms +%endmacro + + +%if (_USE_C_cpSqrAdc_BNU_school_ == 0) + +segment .text align=IPP_ALIGN_FACTOR + +;************************************************************* +;* void cpSqrAdc_BNU_school(Ipp32u* pR, const Ipp32u* pA, int aSize) +;* +;************************************************************* + +;; +;; Lib = W7 +;; +;; Caller = ippsMontMul +;; Caller = ippsMontExp +;; +;; Caller = ippsECCPGetPoint +;; Caller = ippsECCPCheckPoint +;; Caller = ippsECCPAddPoint +;; Caller = ippsECCPMulPointScalar +;; Caller = ippsECCPGenKeyPair +;; Caller = ippsECCPPublicKey +;; Caller = ippsECCPValidateKey +;; Caller = ippsECCPShareSecretKeyDH +;; Caller = ippsECCPShareSecretKeyDHC +;; Caller = ippsECCPSignDSA +;; Caller = ippsECCPSignNR +;; Caller = ippsECCPVerifyDSA +;; Caller = ippsECCPVerifyNR +;; +IPPASM cpSqrAdc_BNU_school,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; target address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source address +%xdefine aSize [esp + ARG_1 + 2*sizeof(dword)] ; BNU length + + mov eax,pA ; src + mov ebx,pR ; dst + mov ecx,aSize ; length + +;; +;; switch +;; +.len1: + cmp ecx,1 + jg .len2 + + movd mm0,DWORD [eax] + pmuludq mm0,mm0 + movq QWORD [ebx],mm0 + jmp .finish + +.len2: + cmp ecx,2 + jg .len3 + + movd mm0,DWORD [eax] + movd mm1,DWORD [eax+4] + + movq mm2,mm0 + pmuludq mm0,mm0 ; a[0]*a[0] + pmuludq mm2,mm1 ; a[0]*a[1] + pmuludq mm1,mm1 ; a[1]*a[1] + + pcmpeqd mm7,mm7 ; mm7 = low 32 bit mask + psrlq mm7,32 + + pand mm7,mm2 ; mm7 = LO(a[0]*a[1]) + paddq mm7,mm7 + psrlq mm2,32 ; mm2 = HI(a[0]*a[1]) + paddq mm2,mm2 + + movd DWORD [ebx],mm0 + psrlq mm0,32 + + paddq mm0,mm7 + movd DWORD [ebx+4],mm0 + psrlq mm0,32 + + paddq mm2,mm1 + paddq mm2,mm0 + movq QWORD [ebx+8],mm2 + + jmp .finish + +.len3: + cmp ecx,3 + jg .len4 + SQUARE_SHORT ebx,eax,3 + jmp .finish + +.len4: + cmp ecx,4 + jg .len5 + SQUARE_SHORT ebx,eax,4 + jmp .finish + +.len5: + cmp ecx,5 + jg .len6 + SQUARE_SHORT ebx,eax,5 + jmp .finish + +.len6: + cmp ecx,6 + jg .len7 + SQUARE_SHORT ebx,eax,6 + jmp .finish + +.len7: + cmp ecx,7 + jg .len8 + SQUARE_SHORT ebx,eax,7 + jmp .finish + +.len8: + cmp ecx,8 + jg .len9 + ;SQUARE_MIDL 8 + SQUARE_SHORT ebx,eax,8 + jmp .finish + +.len9: + cmp ecx,9 + jg .len10 + ;SQUARE_MIDL 9 + SQUARE_SHORT ebx,eax,9 + jmp .finish + +.len10: + cmp ecx,10 + jg .len11 + ;SQUARE_MIDL 10 + SQUARE_SHORT ebx,eax,10 + jmp .finish + +.len11: + cmp ecx,11 + jg .len12 + ;SQUARE_MIDL 11 + SQUARE_SHORT ebx,eax,11 + jmp .finish + +.len12: + cmp ecx,12 + jg .len13 + ;SQUARE_MIDL 12 + SQUARE_SHORT ebx,eax,12 + jmp .finish + +.len13: + cmp ecx,13 + jg .len14 + ;SQUARE_MIDL 13 + SQUARE_SHORT ebx,eax,13 + jmp .finish + +.len14: + cmp ecx,14 + jg .len15 + ;SQUARE_MIDL 14 + SQUARE_SHORT ebx,eax,14 + jmp .finish + +.len15: + cmp ecx,15 + jg .len16 + ;SQUARE_MIDL 15 + SQUARE_SHORT ebx,eax,15 + jmp .finish + +.len16: + cmp ecx,16 + jg .len17 + ;SQUARE_MIDL 16 + SQUARE_SHORT ebx,eax,16 + jmp .finish + +.len17: + cmp ecx,17 + jg .common_case + ;SQUARE_MIDL 17 + SQUARE_SHORT ebx,eax,17 + jmp .finish + +;; +;; Ceneral case (aSize > 17) +;; +.common_case: +;; +;; init result: +;; r = (a[1],a[2],..a[N-1]) * a[0] +;; + mov edx,1 ; i=1 + movd mm0,DWORD [eax] ; a[0] + movd mm1,DWORD [eax+edx*4] ; a[i] + pmuludq mm1,mm0 ; p = a[i]*a[0] + pandn mm7,mm7 ; clear carry + movd DWORD [ebx],mm7 ; r[0] = 0 +.init_loop: + movd mm2,DWORD [eax+edx*4+4] ; read in advance a[i+1] + pmuludq mm2,mm0 ; q = a[i+1]*a[0] + + paddq mm7,mm1 ; p+= carry + movd DWORD [ebx+edx*4],mm7 ; r[i] = LO(p) + psrlq mm7,32 ; carry = HI(p) + + add edx,2 + cmp edx,ecx + jg .break_init_loop + + movd mm1,DWORD [eax+edx*4] ; next a[i] + pmuludq mm1,mm0 ; p = a[i]*a[0] + + paddq mm7,mm2 ; q += carry + movd DWORD [ebx+edx*4-4],mm7 ; r[i+1] = LO(q) + psrlq mm7,32 ; carry = HI(q) + + jl .init_loop + +.break_init_loop: + movd DWORD [ebx+ecx*4],mm7 ; r[aSize] = carry + +;; +;; add other a[i]*a[j], i=1,..,N-1, j=i+1,..,N-1 +;; + mov edx,1 ; i=1 + +.update_mul_loop: + mov esi,edx ; j=i+1 + add esi,1 + mov edi,edx ; i+j + add edi,esi + + movd mm0,DWORD [eax+edx*4] ; a[i] + movd mm1,DWORD [eax+esi*4] ; a[j] + pmuludq mm1,mm0 ; p = a[j]*a[i] + movd mm3,DWORD [ebx+edi*4] ; r[i+j] + pandn mm7,mm7 ; clear carry + +.update_mul_inner_loop: + paddq mm7,mm1 ; p += carry+r[i+j] + paddq mm7,mm3 + movd DWORD [ebx+edi*4],mm7 ; r[i+j] = LO(p) + psrlq mm7,32 ; carry = HI(p) + + movd mm1,DWORD [eax+esi*4+4] ; read in advance a[i+1] + pmuludq mm1,mm0 ; p = a[j+1]*a[i] + movd mm3,DWORD [ebx+edi*4+4] ; read in advance r[i+j+1] + + add edi,1 + add esi,1 + cmp esi,ecx + jl .update_mul_inner_loop + + movd DWORD [ebx+edi*4],mm7 ; r[i+j] = carry + add edx,1 + sub esi,1 + cmp edx,esi + jl .update_mul_loop + pandn mm7,mm7 ; clear carry + movd DWORD [ebx+edi*4+4],mm7 ; r[i+j+1] = 0 + +;; +;; double a[i]*a[j] and add a[i]^2 +;; + pcmpeqd mm6,mm6 ; mm6 = low 32 bit mask + psrlq mm6,32 + + movd mm0,DWORD [eax] ; a[i] + pmuludq mm0,mm0 ; p = a[i]*a[i] + mov edx,0 ; i=0 + movd mm2,DWORD [ebx] ; r[2*i] + movd mm3,DWORD [ebx+4] ; r[2*i+1] + pandn mm7,mm7 ; clear carry +.sqr_loop: + paddq mm2,mm2 ; 2*r[2*i] + paddq mm3,mm3 ; 2*r[2*i+1] + + movq mm1,mm0 + pand mm0,mm6 ; mm0 = LO(p) + psrlq mm1,32 ; mm1 = HI(p) + + paddq mm7,mm2 ; q = carry + 2*r[2*i] + LO(p) + paddq mm7,mm0 + movd DWORD [ebx+edx*8],mm7 ; r[2*i] = LO(q) + psrlq mm7,32 ; carry = HI(q) + + movd mm0,DWORD [eax+edx*4+4] ; read in advance a[i+1] + pmuludq mm0,mm0 ; p = a[i+1]*a[i+1] + + paddq mm7,mm3 ; q = carry + 2*r[2*i+1] + HI(p) + paddq mm7,mm1 + movd DWORD [ebx+edx*8+4],mm7 ; r[2*i+1] = LO(q) + psrlq mm7,32 ; carry = HI(q) + + add edx,1 + movd mm2,DWORD [ebx+edx*8] ; r[2*(i+1)] + movd mm3,DWORD [ebx+edx*8+4] ; r[2*(i+1)+1] + cmp edx,ecx + jl .sqr_loop + +.finish: + emms + REST_GPR + ret +ENDFUNC cpSqrAdc_BNU_school + +%endif +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnusubw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnusubw7as.asm new file mode 100644 index 000000000..85b59ee12 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpbnusubw7as.asm @@ -0,0 +1,82 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Purpose: Cryptography Primitive. +; Big Number Arithmetic +; +; Content: +; cpSubMul_BNU() +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_W7) +%include "pcpvariant.inc" + +segment .text align=IPP_ALIGN_FACTOR + +%if (_USE_C_cpSub_BNU_ == 0) + +align IPP_ALIGN_FACTOR +IPPASM cpSub_BNU,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pDst [esp + ARG_1 + 0*sizeof(dword)] ; target address +%xdefine pSrc1 [esp + ARG_1 + 1*sizeof(dword)] ; source address +%xdefine pSrc2 [esp + ARG_1 + 2*sizeof(dword)] ; source address +%xdefine len [esp + ARG_1 + 3*sizeof(dword)] ; length of BNU + + mov eax,pSrc1 ; src1 + mov ebx,pSrc2 ; src2 + mov edx,pDst ; dst + mov edi,len ; length + shl edi,2 + + xor ecx,ecx + pandn mm0,mm0 + +align IPP_ALIGN_FACTOR +.main_loop: + movd mm1,DWORD [eax + ecx] + movd mm2,DWORD [ebx + ecx] + + paddq mm0,mm1 + psubq mm0,mm2 + movd DWORD [edx + ecx],mm0 + pshufw mm0,mm0,11111110b + + add ecx,4 + cmp ecx,edi + jl .main_loop + + movd eax,mm0 + neg eax + + emms + REST_GPR + ret +ENDFUNC cpSub_BNU +%endif + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpdelay.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpdelay.asm new file mode 100644 index 000000000..e7a18790c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpdelay.asm @@ -0,0 +1,51 @@ +;=============================================================================== +; Copyright 2022 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +;=============================================================================== + +; +; +; Purpose: Delay function, ia32 version +; +; Content: +; _ippcpDelay() +; + +%include "asmdefs.inc" +%include "ia_emm.inc" + +segment .text align=IPP_ALIGN_FACTOR + +;*************************************************************** +;* Purpose: delay +;* +;* void _ippcpDelay(Ipp32u value) +;* +;* Caller = cpAESRandomNoise +;*************************************************************** +align IPP_ALIGN_FACTOR +IPPASM _ippcpDelay,PUBLIC + +%xdefine delayVal [esp + 4] ; indent through the return address + + mov ecx,delayVal + +.Loop: + mov eax,ecx + dec ecx + test eax,eax + jnz .Loop + + ret +ENDFUNC _ippcpDelay diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmd5w7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmd5w7as.asm new file mode 100644 index 000000000..bad43e742 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmd5w7as.asm @@ -0,0 +1,315 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to MD5 +; (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +; +; Content: +; UpdateMD5 +; +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_MD5_) +%if (_IPP >= _IPP_M5) + +;; +;; Magic functions defined in RFC 1321 +;; +%macro MAGIC_F 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F,%%Z + xor %%F,%%Y + and %%F,%%X + xor %%F,%%Z +%endmacro + + +%macro MAGIC_G 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + MAGIC_F %%F,%%Z,%%X,%%Y +%endmacro + + +%macro MAGIC_H 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F,%%Z + xor %%F,%%Y + xor %%F,%%X +%endmacro + + +%macro MAGIC_I 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F,%%Z + not %%F + or %%F,%%X + xor %%F,%%Y +%endmacro + + + +;; +;; single MD5 step +;; +;; A = B +ROL32((A +MAGIC(B,C,D) +data +const), nrot) +;; +%macro MD5_STEP 9.nolist + %xdefine %%MAGIC_FUN %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%FUN %6 + %xdefine %%data %7 + %xdefine %%MD5const %8 + %xdefine %%nrot %9 + + add %%A,%%MD5const + add %%A,[%%data] + MAGIC_FUN %%FUN, %%B,%%C,%%D + add %%A,%%FUN + rol %%A,%%nrot + add %%A,%%B +%endmacro + + +%macro MD5_RND 9.nolist + %xdefine %%MAGIC_FUN %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%FUN %6 + %xdefine %%MD5const %7 + %xdefine %%nrot %8 + %xdefine %%nextdata %9 + + %%MAGIC_FUN %%FUN, %%B,%%C,%%D + lea %%A,[%%A+ebp+%%MD5const] + %ifnempty %%nextdata + mov ebp,[%%nextdata] + %endif +; MAGIC_FUN FUN, B,C,D + add %%A,%%FUN + rol %%A,%%nrot + add %%A,%%B +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateMD5(DigestMD5digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +;; +;; MD5 left rotations (number of bits) +;; +%assign rot11 7 +%assign rot12 12 +%assign rot13 17 +%assign rot14 22 +%assign rot21 5 +%assign rot22 9 +%assign rot23 14 +%assign rot24 20 +%assign rot31 4 +%assign rot32 11 +%assign rot33 16 +%assign rot34 23 +%assign rot41 6 +%assign rot42 10 +%assign rot43 15 +%assign rot44 21 + +;; +;; Lib = W7 +;; +;; Caller = ippsSHA1Update +;; Caller = ippsSHA1Final +;; Caller = ippsSHA1MessageDigest +;; +;; Caller = ippsHMACSHA1Update +;; Caller = ippsHMACSHA1Final +;; Caller = ippsHMACSHA1MessageDigest +;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateMD5,PUBLIC + USES_GPR esi,edi,ebx,ebp + +%xdefine digest [esp + ARG_1 + 0*sizeof(dword)] ; digest address +%xdefine mblk [esp + ARG_1 + 1*sizeof(dword)] ; buffer address +%xdefine mlen [esp + ARG_1 + 2*sizeof(dword)] ; buffer length +%xdefine pParam [esp + ARG_1 + 3*sizeof(dword)] ; dummy parameter + +%xdefine MBS_MD5 (64) + mov eax, pParam ; due to bug in ml12 - dummy instruction + + mov edi,digest ; digest address + mov esi,mblk ; source data address + mov eax,mlen ; data length + + sub esp,2*sizeof(dword) + mov [esp+0*sizeof(dword)],edi ; save digest address + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.md5_block_loop: + mov [esp+1*sizeof(dword)],eax ; save data length + + mov ebp,[esi+ 0*4] ; preload data + +;; +;; init A, B, C, D by the internal digest +;; + mov eax,[edi+0*4] ; eax = digest[0] (A) + mov ebx,[edi+1*4] ; ebx = digest[1] (B) + mov ecx,[edi+2*4] ; ecx = digest[2] (C) + mov edx,[edi+3*4] ; edx = digest[3] (D) + +;; +;; perform 0-63 steps +;; +;; MAGIC A, B, C, D, FUN, cnt, nrot, pNextData (ebp) +;; ------------------------------------------------------------ + MD5_RND MAGIC_F, eax,ebx,ecx,edx, edi, 0d76aa478h, rot11, {esi+ 1*4} + MD5_RND MAGIC_F, edx,eax,ebx,ecx, edi, 0e8c7b756h, rot12, {esi+ 2*4} + MD5_RND MAGIC_F, ecx,edx,eax,ebx, edi, 0242070dbh, rot13, {esi+ 3*4} + MD5_RND MAGIC_F, ebx,ecx,edx,eax, edi, 0c1bdceeeh, rot14, {esi+ 4*4} + MD5_RND MAGIC_F, eax,ebx,ecx,edx, edi, 0f57c0fafh, rot11, {esi+ 5*4} + MD5_RND MAGIC_F, edx,eax,ebx,ecx, edi, 04787c62ah, rot12, {esi+ 6*4} + MD5_RND MAGIC_F, ecx,edx,eax,ebx, edi, 0a8304613h, rot13, {esi+ 7*4} + MD5_RND MAGIC_F, ebx,ecx,edx,eax, edi, 0fd469501h, rot14, {esi+ 8*4} + MD5_RND MAGIC_F, eax,ebx,ecx,edx, edi, 0698098d8h, rot11, {esi+ 9*4} + MD5_RND MAGIC_F, edx,eax,ebx,ecx, edi, 08b44f7afh, rot12, {esi+10*4} + MD5_RND MAGIC_F, ecx,edx,eax,ebx, edi, 0ffff5bb1h, rot13, {esi+11*4} + MD5_RND MAGIC_F, ebx,ecx,edx,eax, edi, 0895cd7beh, rot14, {esi+12*4} + MD5_RND MAGIC_F, eax,ebx,ecx,edx, edi, 06b901122h, rot11, {esi+13*4} + MD5_RND MAGIC_F, edx,eax,ebx,ecx, edi, 0fd987193h, rot12, {esi+14*4} + MD5_RND MAGIC_F, ecx,edx,eax,ebx, edi, 0a679438eh, rot13, {esi+15*4} + MD5_RND MAGIC_F, ebx,ecx,edx,eax, edi, 049b40821h, rot14, {esi+ 1*4} + + MD5_RND MAGIC_G, eax,ebx,ecx,edx, edi, 0f61e2562h, rot21, {esi+ 6*4} + MD5_RND MAGIC_G, edx,eax,ebx,ecx, edi, 0c040b340h, rot22, {esi+11*4} + MD5_RND MAGIC_G, ecx,edx,eax,ebx, edi, 0265e5a51h, rot23, {esi+ 0*4} + MD5_RND MAGIC_G, ebx,ecx,edx,eax, edi, 0e9b6c7aah, rot24, {esi+ 5*4} + MD5_RND MAGIC_G, eax,ebx,ecx,edx, edi, 0d62f105dh, rot21, {esi+10*4} + MD5_RND MAGIC_G, edx,eax,ebx,ecx, edi, 002441453h, rot22, {esi+15*4} + MD5_RND MAGIC_G, ecx,edx,eax,ebx, edi, 0d8a1e681h, rot23, {esi+ 4*4} + MD5_RND MAGIC_G, ebx,ecx,edx,eax, edi, 0e7d3fbc8h, rot24, {esi+ 9*4} + MD5_RND MAGIC_G, eax,ebx,ecx,edx, edi, 021e1cde6h, rot21, {esi+14*4} + MD5_RND MAGIC_G, edx,eax,ebx,ecx, edi, 0c33707d6h, rot22, {esi+ 3*4} + MD5_RND MAGIC_G, ecx,edx,eax,ebx, edi, 0f4d50d87h, rot23, {esi+ 8*4} + MD5_RND MAGIC_G, ebx,ecx,edx,eax, edi, 0455a14edh, rot24, {esi+13*4} + MD5_RND MAGIC_G, eax,ebx,ecx,edx, edi, 0a9e3e905h, rot21, {esi+ 2*4} + MD5_RND MAGIC_G, edx,eax,ebx,ecx, edi, 0fcefa3f8h, rot22, {esi+ 7*4} + MD5_RND MAGIC_G, ecx,edx,eax,ebx, edi, 0676f02d9h, rot23, {esi+12*4} + MD5_RND MAGIC_G, ebx,ecx,edx,eax, edi, 08d2a4c8ah, rot24, {esi+ 5*4} + + MD5_RND MAGIC_H, eax,ebx,ecx,edx, edi, 0fffa3942h, rot31, {esi+ 8*4} + MD5_RND MAGIC_H, edx,eax,ebx,ecx, edi, 08771f681h, rot32, {esi+11*4} + MD5_RND MAGIC_H, ecx,edx,eax,ebx, edi, 06d9d6122h, rot33, {esi+14*4} + MD5_RND MAGIC_H, ebx,ecx,edx,eax, edi, 0fde5380ch, rot34, {esi+ 1*4} + MD5_RND MAGIC_H, eax,ebx,ecx,edx, edi, 0a4beea44h, rot31, {esi+ 4*4} + MD5_RND MAGIC_H, edx,eax,ebx,ecx, edi, 04bdecfa9h, rot32, {esi+ 7*4} + MD5_RND MAGIC_H, ecx,edx,eax,ebx, edi, 0f6bb4b60h, rot33, {esi+10*4} + MD5_RND MAGIC_H, ebx,ecx,edx,eax, edi, 0bebfbc70h, rot34, {esi+13*4} + MD5_RND MAGIC_H, eax,ebx,ecx,edx, edi, 0289b7ec6h, rot31, {esi+ 0*4} + MD5_RND MAGIC_H, edx,eax,ebx,ecx, edi, 0eaa127fah, rot32, {esi+ 3*4} + MD5_RND MAGIC_H, ecx,edx,eax,ebx, edi, 0d4ef3085h, rot33, {esi+ 6*4} + MD5_RND MAGIC_H, ebx,ecx,edx,eax, edi, 004881d05h, rot34, {esi+ 9*4} + MD5_RND MAGIC_H, eax,ebx,ecx,edx, edi, 0d9d4d039h, rot31, {esi+12*4} + MD5_RND MAGIC_H, edx,eax,ebx,ecx, edi, 0e6db99e5h, rot32, {esi+15*4} + MD5_RND MAGIC_H, ecx,edx,eax,ebx, edi, 01fa27cf8h, rot33, {esi+ 2*4} + MD5_RND MAGIC_H, ebx,ecx,edx,eax, edi, 0c4ac5665h, rot34, {esi+ 0*4} + + MD5_RND MAGIC_I, eax,ebx,ecx,edx, edi, 0f4292244h, rot41, {esi+ 7*4} + MD5_RND MAGIC_I, edx,eax,ebx,ecx, edi, 0432aff97h, rot42, {esi+14*4} + MD5_RND MAGIC_I, ecx,edx,eax,ebx, edi, 0ab9423a7h, rot43, {esi+ 5*4} + MD5_RND MAGIC_I, ebx,ecx,edx,eax, edi, 0fc93a039h, rot44, {esi+12*4} + MD5_RND MAGIC_I, eax,ebx,ecx,edx, edi, 0655b59c3h, rot41, {esi+ 3*4} + MD5_RND MAGIC_I, edx,eax,ebx,ecx, edi, 08f0ccc92h, rot42, {esi+10*4} + MD5_RND MAGIC_I, ecx,edx,eax,ebx, edi, 0ffeff47dh, rot43, {esi+ 1*4} + MD5_RND MAGIC_I, ebx,ecx,edx,eax, edi, 085845dd1h, rot44, {esi+ 8*4} + MD5_RND MAGIC_I, eax,ebx,ecx,edx, edi, 06fa87e4fh, rot41, {esi+15*4} + MD5_RND MAGIC_I, edx,eax,ebx,ecx, edi, 0fe2ce6e0h, rot42, {esi+ 6*4} + MD5_RND MAGIC_I, ecx,edx,eax,ebx, edi, 0a3014314h, rot43, {esi+13*4} + MD5_RND MAGIC_I, ebx,ecx,edx,eax, edi, 04e0811a1h, rot44, {esi+ 4*4} + MD5_RND MAGIC_I, eax,ebx,ecx,edx, edi, 0f7537e82h, rot41, {esi+11*4} + MD5_RND MAGIC_I, edx,eax,ebx,ecx, edi, 0bd3af235h, rot42, {esi+ 2*4} + MD5_RND MAGIC_I, ecx,edx,eax,ebx, edi, 02ad7d2bbh, rot43, {esi+ 9*4} + MD5_RND MAGIC_I, ebx,ecx,edx,eax, edi, 0eb86d391h, rot44, {esp} + +;; +;; update digest +;; + add [ebp+0*4],eax ; advance digest + mov eax, dword [esp+1*sizeof(dword)] + add [ebp+1*4],ebx + add [ebp+2*4],ecx + add [ebp+3*4],edx + + mov edi, ebp ; restore hash address + add esi, MBS_MD5 + sub eax, MBS_MD5 + jg .md5_block_loop + + add esp,2*sizeof(dword) + REST_GPR + ret +ENDFUNC UpdateMD5 + +%endif +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmontreductionv8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmontreductionv8as.asm new file mode 100644 index 000000000..f13135d85 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmontreductionv8as.asm @@ -0,0 +1,603 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Purpose: Cryptography Primitive. +; Big Number Arithmetic (Montgomery Reduction) +; +; Content: +; cpMontRedAdc_BNU() +; +; History: +; This implementation used instead of previous one +; (see pcpmontredictw7as.asm) +; +; Extra reduction (R=A-M) has been added to perform MontReduction safe +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_V8) +%include "pcpvariant.inc" +%include "pcpbnu.inc" + +%if _USE_NN_MONTMUL_ == _NUSE + + +%macro MULADD_wt_carry 1.nolist + %xdefine %%i %1 + + movd xmm7,DWORD [eax] ;; pM[0] + pmuludq xmm7,xmm0 ;; t = pM[0] * u + movd xmm2,DWORD [edx+4*(%%i)] ;; pBuffer[i] + paddq xmm7,xmm2 ;; t += pBuffer[i] + movd DWORD [edx+4*(%%i)],xmm7 ;; pBuffer[i] = LO(t) + psrlq xmm7,32 ;; carryLcl = HI(t) +%endmacro + + +%macro MULADD1 3.nolist + %xdefine %%i %1 + %xdefine %%j %2 + %xdefine %%nsize %3 + + movd xmm1,DWORD [eax+4*%%j] ;; pM[j] + pmuludq xmm1,xmm0 ;; t = pM[j] * u + movd xmm2,DWORD [edx+4*(%%i+%%j)] ;; pBuffer[i+j] + paddq xmm1,xmm2 ;; t +=pBuffer[i+j] + paddq xmm7,xmm1 ;; +carryLcl + movd DWORD [edx+4*(%%i+%%j)],xmm7 ;; pBuffer[i+j] = LO(t) + psrlq xmm7,32 ;; carryLcl = HI(t) +%endmacro + + +; INNER_LOOP1 is defined in pcpbnu.inc as well +%ifmacro INNER_LOOP1 2 +%unmacro INNER_LOOP1 2 +%endif +%macro INNER_LOOP1 2.nolist + %xdefine %%i %1 + %xdefine %%size %2 + + %assign %%j 0 + movd xmm0,DWORD [edx+4*%%i] ;; pBuffer[i] + + pmuludq xmm0,xmm5 ;; u = (Ipp32u)( m0*pBuffer[i] ) + movd xmm4,DWORD [edx+4*(%%i+%%size)] ;; w = pBuffer[i+mSize] + paddq xmm4,xmm6 ;; +carryGbl + + %rep %%size + %if %%j == 0 + MULADD_wt_carry %%i + %else + MULADD1 %%i,%%j,%%size + %endif + %assign %%j %%j + 1 + %endrep + + paddq xmm7,xmm4 ;; w+= carryLcl + + movd DWORD [edx+4*(%%i+%%size)],xmm7 ;; pBuffer[i+mSize] = LO(w) +; pshufw xmm6,xmm7,11111110b ;; carryGbl = HI(w) + pshuflw xmm6,xmm7,11111110b ;; carryGbl = HI(w) +%endmacro + + +; OUTER_LOOP1 is defined in pcpbnu.inc as well +%ifmacro OUTER_LOOP1 1 +%unmacro OUTER_LOOP1 1 +%endif +%macro OUTER_LOOP1 1.nolist + %xdefine %%nsize %1 + + movd xmm5,DWORD m0 ; m0 + pandn xmm6,xmm6 ; init carryGbl = 0 + + %assign %%i 0 + %rep %%nsize + INNER_LOOP1 %%i,%%nsize + %assign %%i %%i + 1 + %endrep + + psrlq xmm7,32 +%endmacro + + + +%macro UNROLL8 0.nolist + movd xmm1,DWORD [eax+ecx] + movd xmm2,DWORD [edx+ecx] + movd xmm3,DWORD [eax+ecx+4] + movd xmm4,DWORD [edx+ecx+4] + movd xmm5,DWORD [eax+ecx+8] + movd xmm6,DWORD [edx+ecx+8] + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax+ecx+12] + movd xmm2,DWORD [edx+ecx+12] + movd DWORD [edx+ecx],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax+ecx+16] + movd xmm4,DWORD [edx+ecx+16] + movd DWORD [edx+ecx+4],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax+ecx+20] + movd xmm6,DWORD [edx+ecx+20] + movd DWORD [edx+ecx+8],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax+ecx+24] + movd xmm2,DWORD [edx+ecx+24] + movd DWORD [edx+ecx+12],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax+ecx+28] + movd xmm4,DWORD [edx+ecx+28] + movd DWORD [edx+ecx+16],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd DWORD [edx+ecx+20],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm1 + movd DWORD [edx+ecx+24],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm3 + movd DWORD [edx+ecx+28],xmm7 + psrlq xmm7,32 +%endmacro + + +%macro UNROLL16 0.nolist + movd xmm1,DWORD [eax+ecx] + movd xmm2,DWORD [edx+ecx] + movd xmm3,DWORD [eax+ecx+4] + movd xmm4,DWORD [edx+ecx+4] + movd xmm5,DWORD [eax+ecx+8] + movd xmm6,DWORD [edx+ecx+8] + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax+ecx+12] + movd xmm2,DWORD [edx+ecx+12] + movd DWORD [edx+ecx],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax+ecx+16] + movd xmm4,DWORD [edx+ecx+16] + movd DWORD [edx+ecx+4],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax+ecx+20] + movd xmm6,DWORD [edx+ecx+20] + movd DWORD [edx+ecx+8],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax+ecx+24] + movd xmm2,DWORD [edx+ecx+24] + movd DWORD [edx+ecx+12],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax+ecx+28] + movd xmm4,DWORD [edx+ecx+28] + movd DWORD [edx+ecx+16],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax+ecx+32] + movd xmm6,DWORD [edx+ecx+32] + movd DWORD [edx+ecx+20],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax+ecx+36] + movd xmm2,DWORD [edx+ecx+36] + movd DWORD [edx+ecx+24],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax+ecx+40] + movd xmm4,DWORD [edx+ecx+40] + movd DWORD [edx+ecx+28],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax+ecx+44] + movd xmm6,DWORD [edx+ecx+44] + movd DWORD [edx+ecx+32],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax+ecx+48] + movd xmm2,DWORD [edx+ecx+48] + movd DWORD [edx+ecx+36],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd xmm3,DWORD [eax+ecx+52] + movd xmm4,DWORD [edx+ecx+52] + movd DWORD [edx+ecx+40],xmm7 + psrlq xmm7,32 + + pmuludq xmm3,xmm0 + paddq xmm3,xmm4 + + paddq xmm7,xmm5 + movd xmm5,DWORD [eax+ecx+56] + movd xmm6,DWORD [edx+ecx+56] + movd DWORD [edx+ecx+44],xmm7 + psrlq xmm7,32 + + pmuludq xmm5,xmm0 + paddq xmm5,xmm6 + + paddq xmm7,xmm1 + movd xmm1,DWORD [eax+ecx+60] + movd xmm2,DWORD [edx+ecx+60] + movd DWORD [edx+ecx+48],xmm7 + psrlq xmm7,32 + + pmuludq xmm1,xmm0 + paddq xmm1,xmm2 + + paddq xmm7,xmm3 + movd DWORD [edx+ecx+52],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm5 + movd DWORD [edx+ecx+56],xmm7 + psrlq xmm7,32 + + paddq xmm7,xmm1 + movd DWORD [edx+ecx+60],xmm7 + psrlq xmm7,32 +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + +%if (_USE_C_cpMontRedAdc_BNU_ == 0) +;************************************************************* +;* void cpMontRedAdc_BNU(Ipp32u* pR, +;* Ipp32u* pBuffer, +;* const Ipp32u* pModulo, int mSize, Ipp32u m0) +;* +;************************************************************* + +;; +;; Lib = V8 +;; +;; Caller = ippsMontMul +;; +IPPASM cpMontRedAdc_BNU,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to the reduction +%xdefine pBuffer [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to the product +%xdefine pModulo [ebp + ARG_1 + 2*sizeof(dword)] ; pointer to the modulo +%xdefine mSize [ebp + ARG_1 + 3*sizeof(dword)] ; modulo size +%xdefine m0 [ebp + ARG_1 + 4*sizeof(dword)] ; helper + + mov eax,pModulo ; modulo address + mov edi,mSize ; modulo size + mov edx,pBuffer ; temp product address + +; +; spesial cases +; +.tst_reduct4: + cmp edi,4 ; special case + jne .tst_reduct5 + OUTER_LOOP1 4 + add edx,4*4 + jmp .finish + +.tst_reduct5: + cmp edi,5 ; special case + jne .tst_reduct6 + OUTER_LOOP1 5 + add edx,4*5 + jmp .finish + +.tst_reduct6: + cmp edi,6 ; special case + jne .tst_reduct7 + OUTER_LOOP1 6 + add edx,4*6 + jmp .finish + +.tst_reduct7: + cmp edi,7 ; special case + jne .tst_reduct8 + OUTER_LOOP1 7 + add edx,4*7 + jmp .finish + +.tst_reduct8: + cmp edi,8 ; special case + jne .tst_reduct9 + OUTER_LOOP1 8 + add edx,4*8 + jmp .finish + +.tst_reduct9: + cmp edi,9 ; special case + jne .tst_reduct10 + OUTER_LOOP1 9 + add edx,4*9 + jmp .finish + +.tst_reduct10: + cmp edi,10 ; special case + jne .tst_reduct11 + OUTER_LOOP1 10 + add edx,4*10 + jmp .finish + +.tst_reduct11: + cmp edi,11 ; special case + jne .tst_reduct12 + OUTER_LOOP1 11 + add edx,4*11 + jmp .finish + +.tst_reduct12: + cmp edi,12 ; special case + jne .tst_reduct13 + OUTER_LOOP1 12 + add edx,4*12 + jmp .finish + +.tst_reduct13: + cmp edi,13 ; special case + jne .tst_reduct14 + OUTER_LOOP1 13 + add edx,4*13 + jmp .finish + +.tst_reduct14: + cmp edi,14 ; special case + jne .tst_reduct15 + OUTER_LOOP1 14 + add edx,4*14 + jmp .finish + +.tst_reduct15: + cmp edi,15 ; special case + jne .tst_reduct16 + OUTER_LOOP1 15 + add edx,4*15 + jmp .finish + +.tst_reduct16: + cmp edi,16 ; special case + jne .reduct_general + OUTER_LOOP1 16 + add edx,4*16 + jmp .finish + +; +; general case +; +.reduct_general: + sub esp,4 ; allocate slot for carryGbl + + pandn xmm6,xmm6 ; init carryGbl = 0 + + mov ebx,edi + shl ebx,2 ; modulo size in bytes (outer counter) + shl edi,2 + +.mainLoop: + movd xmm0,DWORD m0 ; m0 helper + movd xmm1,DWORD [edx] ; pBuffer[i] + movd DWORD [esp],xmm6 ; save carryGbl + + pmuludq xmm0,xmm1 ; u = (Ipp32u)( m0*pBuffer[i] ) + + xor ecx,ecx ; inner index + pandn xmm7,xmm7 ; int carryLcl = 0 + +; +; case: 0 != mSize%8 +; + mov esi,edi ; copy modulo size copy + and esi,7*4 ; and test (inner counter) + jz .testSize_8 + +.small_loop: + movd xmm1,DWORD [eax+ecx] ; pModulo[] + pmuludq xmm1,xmm0 ; t = pModulo[]*u + movd xmm2,DWORD [edx+ecx] ; pBuffer[] + paddq xmm1,xmm2 ; t +=pBuffer[] + paddq xmm7,xmm1 ; +carryLcl + movd DWORD [edx+ecx],xmm7 ; pBuffer[] = LO(t) + psrlq xmm7,32 ; carryLcl = HI(t) + + add ecx,4 + cmp ecx,esi + jl .small_loop + +; +; case: mSize==8 +; +.testSize_8: + mov esi,edi ; copy modulo size copy + and esi,8*4 ; and test + jz .testSize_16 + + UNROLL8 + add ecx,8*4 + +; +; case: mSize==16*n +; +.testSize_16: + mov esi,edi ; copy modulo size copy + and esi,0FFFFFFC0h ; and test + jz .next_term + +.unroll16_loop: + UNROLL16 + add ecx,16*4 + cmp ecx,esi + jl .unroll16_loop + +.next_term: + movd xmm1,DWORD [edx+ecx] ; pBuffer[] + paddq xmm7,xmm1 ; t = pBuffer[]+carryLcl + movd xmm6,DWORD [esp] ; carryGbl + paddq xmm6,xmm7 ; t +=carryGbl + movd DWORD [edx+ecx],xmm6 ; pBuffer[] = LO(t) + psrlq xmm6,32 ; carryGbl = HI(t) + + add edx,4 ; advance pBuffer + sub ebx,4 ; decrease outer counter + jg .mainLoop + + add esp,4 ; release slot for carryGbl + shr edi,2 ; restore mSize + + +;; +;; finish +;; +.finish: + pxor xmm7,xmm7 ; converr carryGbl into the mask + psubd xmm7,xmm6 + + mov esi,pR ; pointer to the result + pandn xmm0,xmm0 ; borrow=0 + xor ecx,ecx ; index =0 + ; perform pR[] = pBuffer[] - pModulus[] +.subtract_loop: + movd xmm1,DWORD [edx+ecx*4]; pBuffer[] + paddq xmm0,xmm1 + movd xmm2,DWORD [eax+ecx*4]; pModulus[] + psubq xmm0,xmm2 + movd DWORD [esi+ecx*4],xmm0 + pshuflw xmm0,xmm0,11111110b + + add ecx,1 + cmp ecx,edi + jl .subtract_loop + + pcmpeqd xmm6,xmm6 ; convert borrow into the mask + pxor xmm0,xmm6 + por xmm0,xmm7 ; common (carryGbl and borrow) mask + + pcmpeqd xmm7,xmm7 ; mask and + pxor xmm7,xmm0 ; ~mask + + xor ecx,ecx ; index =0 + ; masked copy: pR[] = (mask & pR[]) | (~mask & pBuffer[]) +.masked_copy_loop: + movd xmm1,DWORD [esi+ecx*4]; pR[] + pand xmm1,xmm0 + movd xmm2,DWORD [edx+ecx*4]; pBuffer[] + pand xmm2,xmm7 + por xmm1,xmm2 + movd DWORD [esi+ecx*4],xmm1; pR[] + + add ecx,1 + cmp ecx,edi + jl .masked_copy_loop + REST_GPR + ret +ENDFUNC cpMontRedAdc_BNU +%endif + +%endif ;; _IPP_V8 +%endif ;; _USE_NN_MONTMUL_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmontreductionw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmontreductionw7as.asm new file mode 100644 index 000000000..e94fce9c8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpmontreductionw7as.asm @@ -0,0 +1,618 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Arithmetic (Montgomery Reduction) +; +; Content: +; cpMontRedAdc_BNU() +; +; History: +; This implementation used instead of previous one +; (see pcpmontredictw7as.asm) +; +; Extra reduction (R=A-M) has been added to perform MontReduction safe +; +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP == _IPP_W7) || (_IPP == _IPP_T7) +%include "pcpvariant.inc" +%include "pcpbnu.inc" + +%if _USE_NN_MONTMUL_ == _NUSE + + +%macro MULADD_wt_carry 1.nolist + %xdefine %%i %1 + + movd mm7,DWORD [eax] ;; pM[0] + movd mm2,DWORD [edx+4*(%%i)] ;; pBuffer[i] + pmuludq mm7,mm0 ;; t = pM[0] * u + paddq mm7,mm2 ;; +pBuffer[i] + movd DWORD [edx+4*(%%i)],mm7 ;; pBuffer[i] = LO(t) + psrlq mm7,32 ;; carryLcl = HI(t) +%endmacro + + +%macro MULADD1 3.nolist + %xdefine %%i %1 + %xdefine %%j %2 + %xdefine %%nsize %3 + + movd mm1,DWORD [eax+4*%%j] ;; pM[j] + movd mm2,DWORD [edx+4*(%%i+%%j)] ;; pBuffer[i+j] + pmuludq mm1,mm0 ;; t = pM[j] * u + paddq mm1,mm2 ;; +pBuffer[i+j] + paddq mm7,mm1 ;; +carryLcl + movd DWORD [edx+4*(%%i+%%j)],mm7 ;; pBuffer[i+j] = LO(t) + psrlq mm7,32 ;; carryLcl = HI(t) +%endmacro + +; INNER_LOOP1 is defined in pcpbnu.inc as well +%ifmacro INNER_LOOP1 2 +%unmacro INNER_LOOP1 2 +%endif +%macro INNER_LOOP1 2.nolist + %xdefine %%i %1 + %xdefine %%size %2 + + %assign %%j 0 + movd mm0,DWORD [edx+4*%%i] ;; pBuffer[i] + + pmuludq mm0,mm5 ;; u = (Ipp32u)( m0*pBuffer[i] ) + movd mm4,DWORD [edx+4*(%%i+%%size)] ;; w = pBuffer[i+mSize] + paddq mm4,mm6 ;; +carryGbl + + %rep %%size + %if %%j == 0 + MULADD_wt_carry %%i + %else + MULADD1 %%i,%%j,%%size + %endif + %assign %%j %%j + 1 + %endrep + + paddq mm7,mm4 ;; w+= carryLcl + + movd DWORD [edx+4*(%%i+%%size)],mm7 ;; pBuffer[i+mSize] = LO(w) + pshufw mm6,mm7,11111110b ;; carryGbl = HI(w) +%endmacro + + +; OUTER_LOOP1 is defined in pcpbnu.inc as well +%ifmacro OUTER_LOOP1 1 +%unmacro OUTER_LOOP1 1 +%endif +%macro OUTER_LOOP1 1.nolist + %xdefine %%nsize %1 + + movd mm5,DWORD m0 ; m0 + pandn mm6,mm6 ; init carryGbl = 0 + + %assign %%i 0 + %rep %%nsize + INNER_LOOP1 %%i,%%nsize + %assign %%i %%i + 1 + %endrep + + psrlq mm7,32 +%endmacro + + + +%macro UNROLL8 0.nolist + movd mm1,DWORD [eax+ecx] + movd mm2,DWORD [edx+ecx] + movd mm3,DWORD [eax+ecx+4] + movd mm4,DWORD [edx+ecx+4] + movd mm5,DWORD [eax+ecx+8] + movd mm6,DWORD [edx+ecx+8] + + pmuludq mm1,mm0 + paddq mm1,mm2 + pmuludq mm3,mm0 + paddq mm3,mm4 + pmuludq mm5,mm0 + paddq mm5,mm6 + + movd mm2,DWORD [edx+ecx+12] + paddq mm7,mm1 + movd mm1,DWORD [eax+ecx+12] + + pmuludq mm1,mm0 + paddq mm1,mm2 + movd mm2,DWORD [edx+ecx+24] + movd DWORD [edx+ecx],mm7 + + psrlq mm7,32 + paddq mm7,mm3 + + movd mm3,DWORD [eax+ecx+16] + movd mm4,DWORD [edx+ecx+16] + + pmuludq mm3,mm0 + + movd DWORD [edx+ecx+4],mm7 + + psrlq mm7,32 + paddq mm3,mm4 + movd mm4,DWORD [edx+ecx+28] + paddq mm7,mm5 + movd mm5,DWORD [eax+ecx+20] + movd mm6,DWORD [edx+ecx+20] + + pmuludq mm5,mm0 + movd DWORD [edx+ecx+8],mm7 + psrlq mm7,32 + + paddq mm5,mm6 + paddq mm7,mm1 + + movd mm1,DWORD [eax+ecx+24] + + pmuludq mm1,mm0 + + movd DWORD [edx+ecx+12],mm7 + psrlq mm7,32 + + paddq mm1,mm2 + paddq mm7,mm3 + + movd mm3,DWORD [eax+ecx+28] + pmuludq mm3,mm0 + + movd DWORD [edx+ecx+16],mm7 + psrlq mm7,32 + paddq mm3,mm4 + paddq mm7,mm5 + + movd DWORD [edx+ecx+20],mm7 + psrlq mm7,32 + + paddq mm7,mm1 + movd DWORD [edx+ecx+24],mm7 + psrlq mm7,32 + + paddq mm7,mm3 + + movd DWORD [edx+ecx+28],mm7 + psrlq mm7,32 +%endmacro + + +%macro UNROLL16 0.nolist + movd mm1,DWORD [eax+ecx] + movd mm2,DWORD [edx+ecx] + movd mm3,DWORD [eax+ecx+4] + movd mm4,DWORD [edx+ecx+4] + movd mm5,DWORD [eax+ecx+8] + movd mm6,DWORD [edx+ecx+8] + + pmuludq mm1,mm0 + paddq mm1,mm2 + pmuludq mm3,mm0 + paddq mm3,mm4 + pmuludq mm5,mm0 + paddq mm5,mm6 + + movd mm2,DWORD [edx+ecx+12] + paddq mm7,mm1 + movd mm1,DWORD [eax+ecx+12] + + pmuludq mm1,mm0 + paddq mm1,mm2 + movd mm2,DWORD [edx+ecx+24] + movd DWORD [edx+ecx],mm7 + + psrlq mm7,32 + paddq mm7,mm3 + + movd mm3,DWORD [eax+ecx+16] + movd mm4,DWORD [edx+ecx+16] + + pmuludq mm3,mm0 + + movd DWORD [edx+ecx+4],mm7 + + psrlq mm7,32 + paddq mm3,mm4 + movd mm4,DWORD [edx+ecx+28] + paddq mm7,mm5 + movd mm5,DWORD [eax+ecx+20] + movd mm6,DWORD [edx+ecx+20] + + pmuludq mm5,mm0 + movd DWORD [edx+ecx+8],mm7 + psrlq mm7,32 + + paddq mm5,mm6 + movd mm6,DWORD [edx+ecx+32] + paddq mm7,mm1 + + movd mm1,DWORD [eax+ecx+24] + + pmuludq mm1,mm0 + + movd DWORD [edx+ecx+12],mm7 + psrlq mm7,32 + + paddq mm1,mm2 + movd mm2,DWORD [edx+ecx+36] + paddq mm7,mm3 + + movd mm3,DWORD [eax+ecx+28] + pmuludq mm3,mm0 + + movd DWORD [edx+ecx+16],mm7 + psrlq mm7,32 + paddq mm3,mm4 + movd mm4,DWORD [edx+ecx+40] + paddq mm7,mm5 + + movd mm5,DWORD [eax+ecx+32] + pmuludq mm5,mm0 + + movd DWORD [edx+ecx+20],mm7 + psrlq mm7,32 + + paddq mm5,mm6 + movd mm6,DWORD [edx+ecx+44] + paddq mm7,mm1 + movd mm1,DWORD [eax+ecx+36] + pmuludq mm1,mm0 + movd DWORD [edx+ecx+24],mm7 + psrlq mm7,32 + + paddq mm1,mm2 + movd mm2,DWORD [edx+ecx+48] + paddq mm7,mm3 + movd mm3,DWORD [eax+ecx+40] + pmuludq mm3,mm0 + + movd DWORD [edx+ecx+28],mm7 + psrlq mm7,32 + paddq mm3,mm4 + movd mm4,DWORD [edx+ecx+52] + paddq mm7,mm5 + + movd mm5,DWORD [eax+ecx+44] + pmuludq mm5,mm0 + + movd DWORD [edx+ecx+32],mm7 + psrlq mm7,32 + paddq mm5,mm6 + movd mm6,DWORD [edx+ecx+56] + paddq mm7,mm1 + + movd mm1,DWORD [eax+ecx+48] + pmuludq mm1,mm0 + + movd DWORD [edx+ecx+36],mm7 + psrlq mm7,32 + + paddq mm1,mm2 + movd mm2,DWORD [edx+ecx+60] + paddq mm7,mm3 + + movd mm3,DWORD [eax+ecx+52] + pmuludq mm3,mm0 + + movd DWORD [edx+ecx+40],mm7 + psrlq mm7,32 + paddq mm3,mm4 + paddq mm7,mm5 + + movd mm5,DWORD [eax+ecx+56] + + pmuludq mm5,mm0 + movd DWORD [edx+ecx+44],mm7 + psrlq mm7,32 + paddq mm5,mm6 + paddq mm7,mm1 + + movd mm1,DWORD [eax+ecx+60] + + pmuludq mm1,mm0 + movd DWORD [edx+ecx+48],mm7 + psrlq mm7,32 + + paddq mm7,mm3 + movd DWORD [edx+ecx+52],mm7 + psrlq mm7,32 + paddq mm1,mm2 + paddq mm7,mm5 + movd DWORD [edx+ecx+56],mm7 + psrlq mm7,32 + + paddq mm7,mm1 + movd DWORD [edx+ecx+60],mm7 + psrlq mm7,32 +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + +;************************************************************* +;* void cpMontRedAdc_BNU(Ipp32u* pR, +;* Ipp32u* pBuffer, +;* const Ipp32u* pModulo, int mSize, Ipp32u m0) +;* +;************************************************************* + +;; +;; Lib = W7 +;; +;; Caller = ippsMontMul +;; +IPPASM cpMontRedAdc_BNU,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to the reduction +%xdefine pBuffer [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to the product +%xdefine pModulo [ebp + ARG_1 + 2*sizeof(dword)] ; pointer to the modulo +%xdefine mSize [ebp + ARG_1 + 3*sizeof(dword)] ; modulo size +%xdefine m0 [ebp + ARG_1 + 4*sizeof(dword)] ; helper + + mov eax,pModulo ; modulo address + mov edi,mSize ; modulo size + mov edx,pBuffer ; temp product address + +; +; spesial cases +; +.tst_reduct4: + cmp edi,4 ; special case + jne .tst_reduct5 + OUTER_LOOP1 4 + add edx,4*4 + jmp .finish + +.tst_reduct5: + cmp edi,5 ; special case + jne .tst_reduct6 + OUTER_LOOP1 5 + add edx,4*5 + jmp .finish + +.tst_reduct6: + cmp edi,6 ; special case + jne .tst_reduct7 + OUTER_LOOP1 6 + add edx,4*6 + jmp .finish + +.tst_reduct7: + cmp edi,7 ; special case + jne .tst_reduct8 + OUTER_LOOP1 7 + add edx,4*7 + jmp .finish + +.tst_reduct8: + cmp edi,8 ; special case + jne .tst_reduct9 + OUTER_LOOP1 8 + add edx,4*8 + jmp .finish + +.tst_reduct9: + cmp edi,9 ; special case + jne .tst_reduct10 + OUTER_LOOP1 9 + add edx,4*9 + jmp .finish + +.tst_reduct10: + cmp edi,10 ; special case + jne .tst_reduct11 + OUTER_LOOP1 10 + add edx,4*10 + jmp .finish + +.tst_reduct11: + cmp edi,11 ; special case + jne .tst_reduct12 + OUTER_LOOP1 11 + add edx,4*11 + jmp .finish + +.tst_reduct12: + cmp edi,12 ; special case + jne .tst_reduct13 + OUTER_LOOP1 12 + add edx,4*12 + jmp .finish + +.tst_reduct13: + cmp edi,13 ; special case + jne .tst_reduct14 + OUTER_LOOP1 13 + add edx,4*13 + jmp .finish + +.tst_reduct14: + cmp edi,14 ; special case + jne .tst_reduct15 + OUTER_LOOP1 14 + add edx,4*14 + jmp .finish + +.tst_reduct15: + cmp edi,15 ; special case + jne .tst_reduct16 + OUTER_LOOP1 15 + add edx,4*15 + jmp .finish + +.tst_reduct16: + cmp edi,16 ; special case + jne .reduct_general + OUTER_LOOP1 16 + add edx,4*16 + jmp .finish + +; +; general case +; +.reduct_general: + sub esp,4 ; allocate slot for carryGbl + + pandn mm6,mm6 ; init carryGbl = 0 + + mov ebx,edi + shl ebx,2 ; modulo size in bytes (outer counter) + shl edi,2 + +.mainLoop: + movd mm0,DWORD m0 ; m0 helper + movd mm1,DWORD [edx] ; pBuffer[i] + movd DWORD [esp],mm6 ; save carryGbl + + pmuludq mm0,mm1 ; u = (Ipp32u)( m0*pBuffer[i] ) + + xor ecx,ecx ; inner index + pandn mm7,mm7 ; int carryLcl = 0 + +; +; case: 0 != mSize%8 +; + mov esi,edi ; copy modulo size copy + and esi,7*4 ; and test (inner counter) + jz .testSize_8 + +.small_loop: + movd mm1,DWORD [eax+ecx] ; pModulo[] + movd mm2,DWORD [edx+ecx] ; pBuffer[] + + pmuludq mm1,mm0 ; t = pModulo[]*u + paddq mm2,mm1 ; +pBuffer[] + paddq mm7,mm2 ; +carryLcl + movd DWORD [edx+ecx],mm7 ; pBuffer[] = LO(t) + psrlq mm7,32 ; carryLcl = HI(t) + + add ecx,4 + cmp ecx,esi + jl .small_loop + +; +; case: mSize==8 +; +.testSize_8: + mov esi,edi ; copy modulo size copy + and esi,8*4 ; and test + jz .testSize_16 + + UNROLL8 + add ecx,8*4 + +; +; case: mSize==16*n +; +.testSize_16: + mov esi,edi ; copy modulo size copy + and esi,0FFFFFFC0h ; and test + jz .next_term + +.unroll16_loop: + UNROLL16 + add ecx,16*4 + cmp ecx,esi + jl .unroll16_loop + +.next_term: + movd mm1,DWORD [edx+ecx] ; pBuffer[] + movd mm6,DWORD [esp] ; carryGbl + paddq mm7,mm1 ; t = pBuffer[]+carryLcl + paddq mm6,mm7 ; +carryGbl + movd DWORD [edx+ecx],mm6 ; pBuffer[] = LO(t) + psrlq mm6,32 ; carryGbl = HI(t) + + add edx,4 ; advance pBuffer + sub ebx,4 ; decrease outer counter + jg .mainLoop + + add esp,4 ; release slot for carryGbl + shr edi,2 ; restore mSize + + +;; +;; finish +;; +.finish: + pxor mm7,mm7 ; converr carryGbl into the mask + psubd mm7,mm6 + + mov esi,pR ; pointer to the result + mov ebx,edi ; restore mSize + pandn mm0,mm0 ; borrow=0 + xor ecx,ecx ; index =0 + ; perform pR[] = pBuffer[] - pModulus[] +.subtract_loop: + movd mm1,DWORD [edx+ecx*4]; pBuffer[] + movd mm2,DWORD [eax+ecx*4]; pModulus[] + + psubq mm1,mm2 + paddq mm1,mm0 + movd DWORD [esi+ecx*4],mm1 + pshufw mm0,mm1,11111110b + + add ecx,1 + cmp ecx,edi + jl .subtract_loop + + pcmpeqd mm6,mm6 ; convert borrow into the mask + pxor mm0,mm6 + por mm0,mm7 ; common (carryGbl and borrow) mask + + pcmpeqd mm7,mm7 ; mask and + pxor mm7,mm0 ; ~mask + + xor ecx,ecx ; index =0 + ; masked copy: pR[] = (mask & pR[]) | (~mask & pBuffer[]) +.masked_copy_loop: + movd mm1,DWORD [esi+ecx*4]; pR[] + pand mm1,mm0 + movd mm2,DWORD [edx+ecx*4]; pBuffer[] + pand mm2,mm7 + por mm1,mm2 + movd DWORD [esi+ecx*4],mm1; pR[] + + add ecx,1 + cmp ecx,edi + jl .masked_copy_loop + + emms + REST_GPR + ret +ENDFUNC cpMontRedAdc_BNU + +%endif ;; _IPP_W7 || _IPP_T7 +%endif ;; _USE_NN_MONTMUL_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp192r1arith_mont_slm.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp192r1arith_mont_slm.asm new file mode 100644 index 000000000..31a43e67b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp192r1arith_mont_slm.asm @@ -0,0 +1,810 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; P192r1 basic arithmetic function +; +; Content: +; p192r1_add +; p192r1_sub +; p192r1_neg +; p192r1_div_by_2 +; p192r1_mul_mont_slm +; p192r1_sqr_mont_slm +; p192r1_mred +; p192r1_select_ap_w7 +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +;; +;; some p384r1 constants +;; +p192r1_data: +_prime192r1 DD 0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFEh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh + +%assign LEN192 (192/32) ; dword's length of operands + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Ipp32u add_192(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = carry = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM add_192,PRIVATE + ; r = a+b + mov eax, dword [esi] + add eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + adc eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + adc eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + adc eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + adc eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + adc eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC add_192 + +;; +;; Ipp32u sub_192(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = borrow = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM sub_192,PRIVATE + ; r = a-b + mov eax, dword [esi] + sub eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + sbb eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + sbb eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + sbb eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + sbb eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + sbb eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC sub_192 + +;; +;; Ipp32u shl_192(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shl_192,PRIVATE + mov eax, dword [esi+(LEN192-1)*sizeof(dword)] + ; r = a<<1 + movq xmm2, qword [esi+sizeof(oword)] + movdqu xmm1, oword [esi] + + movdqa xmm3, xmm2 + palignr xmm3, xmm1, sizeof(qword) + psllq xmm2, 1 + psrlq xmm3, 63 + por xmm2, xmm3 + movq qword [edi+sizeof(oword)], xmm2 + + movdqa xmm3, xmm1 + pslldq xmm3, sizeof(qword) + psllq xmm1, 1 + psrlq xmm3, 63 + por xmm1, xmm3 + movdqu oword [edi], xmm1 + + shr eax, 31 + ret +ENDFUNC shl_192 + +;; +;; void shr_192(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; eax = ext +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shr_192,PRIVATE + ; r = a>>1 + movdqu xmm2, oword [esi] + movq xmm1, qword [esi+sizeof(oword)] + + movdqa xmm3, xmm1 + palignr xmm3, xmm2, sizeof(qword) + psrlq xmm2, 1 + psllq xmm3, 63 + por xmm2, xmm3 + movdqu oword [edi], xmm2 + + movdqa xmm3, xmm0 + psrlq xmm1, 1 + psllq xmm3, 63 + por xmm1, xmm3 + movq qword [edi+sizeof(oword)], xmm1 + + ret +ENDFUNC shr_192 + +;; +;; void cpy_192(Ipp32u* r, const Ipp32u* a) +;; +%macro cpy_192 2.nolist + %xdefine %%pdst %1 + %xdefine %%psrc %2 + + movdqu xmm0, oword [%%psrc] + movq xmm1, qword [%%psrc+sizeof(oword)] + movdqu oword [%%pdst], xmm0 + movq qword [%%pdst+sizeof(oword)], xmm1 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_add(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_add,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN192] +%assign _sp_ _buf_+(LEN192)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM add_192 ; R = A+B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p192r1_data ; modulus + lea ebx, [ebx+(_prime192r1-p192r1_data)] + CALL_IPPASM sub_192 ; T = R-modulus + + lea esi,[esp+_buf_] + mov edi, pR + sub edx, eax ; R = T<0? R : T + cmovnz esi, edi + cpy_192 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p192r1_add + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_sub(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_sub,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN192] +%assign _sp_ _buf_+(LEN192)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM sub_192 ; R = A-B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p192r1_data ; modulus + lea ebx, [ebx+(_prime192r1-p192r1_data)] + CALL_IPPASM add_192 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_192 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p192r1_sub + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_neg(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_neg,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN192] +%assign _sp_ _buf_+(LEN192)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; outpur pR + mov esi, pA ; input pA + + ; r = 0-a + mov eax, 0 + sub eax, dword [esi] + mov dword [edi], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + sbb edx,edx + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p192r1_data ; modulus + lea ebx, [ebx+(_prime192r1-p192r1_data)] + CALL_IPPASM add_192 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_192 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p192r1_neg + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_mul_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_mul_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN192] +%assign _sp_ _buf_+(LEN192)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; pA + CALL_IPPASM shl_192 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + mov edi, pR ; R + LD_ADDR ebx, p192r1_data ; modulus + lea ebx, [ebx+(_prime192r1-p192r1_data)] + CALL_IPPASM sub_192 ; R = T-modulus + + sub edx, eax ; R = R<0? T : R + cmovz esi, edi + cpy_192 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p192r1_mul_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_mul_by_3(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_mul_by_3,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _bufT_ 0 ; T buffer[LEN192] +%assign _bufU_ _bufT_+(LEN192)*sizeof(dword) ; U buffer[LEN192] +%assign _mod_ _bufU_+(LEN192)*sizeof(dword) ; modulus address [1] +%assign _sp_ _mod_+sizeof(dword) ; esp [1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + LD_ADDR eax, p192r1_data ; srore modulus address + lea eax, [eax+(_prime192r1-p192r1_data)] + mov dword [esp+_mod_], eax + + lea edi, [esp+_bufT_] ; T + mov esi, pA ; A + CALL_IPPASM shl_192 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + lea edi, [esp+_bufU_] ; U + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_192 ; U = T-modulus + + sub edx, eax ; T = U<0? T : U + cmovz esi, edi + cpy_192 edi, esi + + mov esi, edi + mov ebx, pA + CALL_IPPASM add_192 ; T +=A + mov edx, eax + + mov edi, pR ; R + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_192 ; R = T-modulus + + sub edx, eax ; R = T<0? R : T + cmovz esi, edi + cpy_192 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p192r1_mul_by_3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_div_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_div_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN192] +%assign _sp_ _buf_+(LEN192)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; A + LD_ADDR ebx, p192r1_data ; modulus + lea ebx, [ebx+(_prime192r1-p192r1_data)] + CALL_IPPASM add_192 ; R = A+modulus + mov edx, 0 + + mov ecx, dword [esi] ; shifted_data = (a[0]&1)? T : A + and ecx, 1 + cmovnz esi, edi + cmovz eax, edx + movd xmm0, eax + mov edi, pR + CALL_IPPASM shr_192 + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p192r1_div_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_mul_mont_slm(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_mul_mont_slm,PUBLIC + USES_GPR ebp,ebx,esi,edi + +%xdefine pR [eax + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [eax + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [eax + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 +%assign _rp_ _buf_+(LEN192+1)*sizeof(dword) ; pR +%assign _ap_ _rp_+sizeof(dword) ; pA +%assign _bp_ _ap_+sizeof(dword) ; pB +%assign _sp_ _bp_+sizeof(dword) ; esp storage +%assign _ssize_ _sp_+sizeof(dword) ; size allocated stack + + mov eax, esp ; save esp + sub esp, _ssize_ ; allocate stack + and esp, -16 ; provide 16-byte stack alignment + mov dword [esp+_sp_], eax ; store original esp + + ; clear buffer + pxor mm0, mm0 + movq [esp+_buf_], mm0 + movq [esp+_buf_+sizeof(qword)], mm0 + movq [esp+_buf_+sizeof(qword)*2], mm0 + movq [esp+_buf_+sizeof(qword)*3], mm0 + + ; store parameters into the stack + ; note: eax here stores an original esp, so it can be used to reach function parameters + mov edi, pR + mov esi, pA + mov ebp, pB + mov dword [esp+_rp_], edi + mov dword [esp+_ap_], esi + mov dword [esp+_bp_], ebp + + mov edi, LEN192 + + movd mm1, dword [esi+sizeof(dword)] ; pre load a[1], a[2] + movd mm2, dword [esi+sizeof(dword)*2] + + +align IPP_ALIGN_FACTOR +.mmul_loop: +; +; i-st pass +; modulus = 2^192 -2^64 -1 +; [6] [2] [0] +; m0 = 1 +; + movd mm7, edi ; save pass counter + + mov edx, dword [ebp] ; b = b[i] + mov eax, dword [esi] ; a[0] + movd mm0, edx + add ebp, sizeof(dword) + mov dword [esp+_bp_], ebp + + pmuludq mm1, mm0 ; a[1]*b[i] + + mul edx ; (E:u) = (edx:eax) = a[0]*b[i]+buf[0] + add eax, dword [esp+_buf_] + adc edx, 0 + + pmuludq mm2, mm0 ; a[2]*b[i] + +; multiplication round 1 - round 2 + movd ecx, mm1 ; p = a[1]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*1] + movd mm1, dword [esi+sizeof(dword)*3] + adc edx, 0 + + movd ebx, mm2 ; p = a[2]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*2] + movd mm2, dword [esi+sizeof(dword)*4] + movd mm3, dword [esi+sizeof(dword)*5] + adc edx, 0 + + pmuludq mm1, mm0 ; a[3]*b[i] + pmuludq mm2, mm0 ; a[4]*b[i] + pmuludq mm3, mm0 ; a[5]*b[i] + +;;; and reduction ;;; + mov dword [esp+_buf_+sizeof(dword)*0], ecx ; +0 + sub ebx, eax ; -u0 + mov edi, 0 + mov dword [esp+_buf_+sizeof(dword)*1], ebx + adc edi, 0 ; ssave bf + +; multiplication round 3 - round 5 + movd ecx, mm1 ; p = a[3]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*3] + adc edx, 0 + + movd ebx, mm2 ; p = a[4]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*4] + adc edx, 0 + + movd ebp, mm3 ; p = a[5]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*5] + adc edx, 0 + +;;; and reduction ;;; + sub ecx, edi ; -cb + mov dword [esp+_buf_+sizeof(dword)*2], ecx + sbb ebx, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*3], ebx + sbb ebp, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*4], ebp + +;;; last multiplication round 6 + movd edi, mm7 ; restore pass counter + + sbb eax, 0 ; u0 -bf + mov ebx, 0 + add edx, dword [esp+_buf_+sizeof(dword)*6] + adc ebx, 0 + add edx, eax + adc ebx, 0 + mov dword [esp+_buf_+sizeof(dword)*5], edx + mov dword [esp+_buf_+sizeof(dword)*6], ebx + + sub edi, 1 + movd mm1, dword [esi+sizeof(dword)] ; speculative load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + jz .exit_mmul_loop + + mov ebp, dword [esp+_bp_] ; restore pB + jmp .mmul_loop + +.exit_mmul_loop: + emms + +; final reduction + mov edi, [esp+_rp_] ; result + lea esi, [esp+_buf_] ; buffer + LD_ADDR ebx, p192r1_data ; modulus + lea ebx, [ebx+(_prime192r1-p192r1_data)] + CALL_IPPASM sub_192 + mov edx, dword [esp+_buf_+sizeof(dword)*LEN192] + sub edx, eax + +; copy + cmovz esi, edi + cpy_192 edi, esi + + mov esp, [esp+_sp_] ; release stack + REST_GPR + ret +ENDFUNC p192r1_mul_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_sqr_mont_slm(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_sqr_mont_slm,PUBLIC + USES_GPR esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source A address + + ;; use p192r1_mul_mont_slm to compute sqr + mov esi, pA + mov edi, pR + push esi + push esi + push edi + CALL_IPPASM p192r1_mul_mont_slm,PUBLIC + add esp, sizeof(dword)*3 + REST_GPR + ret +ENDFUNC p192r1_sqr_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p192r1_mred(Ipp32u* r, Ipp32u* prod) +;; +; modulus = 2^192 -2^64 -1 +; [6] [2] [0] +; m0 = 1 +; +align IPP_ALIGN_FACTOR +IPPASM p192r1_mred,PUBLIC + USES_GPR ebx,esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; reduction address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source product address + + ; get parameters: + mov esi, pA + + mov ecx, LEN192 + xor edx, edx +align IPP_ALIGN_FACTOR +.mred_loop: + mov eax, dword [esi] + + mov ebx, 0 + mov dword [esi], ebx + + mov ebx, dword [esi+sizeof(dword)] + mov dword [esi+sizeof(dword)], ebx + + mov ebx, dword [esi+sizeof(dword)*2] + sub ebx, eax + mov dword [esi+sizeof(dword)*2], ebx + + mov ebx, dword [esi+sizeof(dword)*3] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*3], ebx + + mov ebx, dword [esi+sizeof(dword)*4] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*4], ebx + + mov ebx, dword [esi+sizeof(dword)*5] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*5], ebx + + mov ebx, dword [esi+sizeof(dword)*6] + sbb eax, 0 + add eax, edx + mov edx, 0 + adc edx, 0 + add ebx, eax + mov dword [esi+sizeof(dword)*6], ebx + adc edx, 0 + + lea esi, [esi+sizeof(dword)] + sub ecx, 1 + jnz .mred_loop + + ; final reduction + mov edi, pR ; result + LD_ADDR ebx, p192r1_data ; addres of the modulus + lea ebx, [ebx+(_prime192r1-p192r1_data)] + CALL_IPPASM sub_192 + + sub edx, eax + cmovz esi, edi + cpy_192 edi, esi + + REST_GPR + ret +ENDFUNC p192r1_mred + +%endif ;; _IPP >= _IPP_P8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp224r1arith_mont_slm.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp224r1arith_mont_slm.asm new file mode 100644 index 000000000..24879e66d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp224r1arith_mont_slm.asm @@ -0,0 +1,867 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; P224r1 basic arithmetic function +; +; Content: +; p224r1_add +; p224r1_sub +; p224r1_neg +; p224r1_div_by_2 +; p224r1_mul_mont_slm +; p224r1_sqr_mont_slm +; p224r1_mred +; p224r1_mont_back +; p224r1_select_ap_w7 +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +;; +;; some p224r1 constants +;; +p224r1_data: +_prime224r1 DD 000000001h,000000000h,000000000h,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh + +%assign LEN224 (224/32) ; dword's length of operands + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Ipp32u add_224(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = carry = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM add_224,PRIVATE + ; r = a+b + mov eax, dword [esi] + add eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + adc eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + adc eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + adc eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + adc eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + adc eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + adc eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC add_224 + +;; +;; Ipp32u sub_224(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = borrow = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM sub_224,PRIVATE + ; r = a-b + mov eax, dword [esi] + sub eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + sbb eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + sbb eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + sbb eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + sbb eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + sbb eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + sbb eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC sub_224 + +;; +;; Ipp32u shl_224(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shl_224,PRIVATE + ; r = a<<1 + movdqu xmm0, oword [esi] + movdqu xmm1, oword [esi+LEN224*sizeof(dword)-sizeof(oword)] + mov eax, dword [esi+(LEN224-1)*sizeof(dword)] + psrldq xmm1, sizeof(dword) + + movdqa xmm2, xmm0 + psllq xmm0, 1 + psrlq xmm2, 63 + movdqa xmm3, xmm1 + psllq xmm1, 1 + psrlq xmm3, 63 + + palignr xmm3, xmm2, sizeof(qword) + pslldq xmm2, sizeof(qword) + + por xmm1, xmm3 + por xmm0, xmm2 + movdqu oword [edi], xmm0 + movq qword [edi+sizeof(oword)], xmm1 + psrldq xmm1, sizeof(qword) + movd dword [edi+sizeof(oword)+sizeof(qword)], xmm1 + + shr eax, 31 + ret +ENDFUNC shl_224 + +;; +;; void shr_224(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; eax = ext +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shr_224,PRIVATE + ; r = a>>1 + movdqu xmm0, oword [esi] + movdqu xmm2, oword [esi+LEN224*sizeof(dword)-sizeof(oword)] + movd xmm1, eax + palignr xmm1, xmm2, sizeof(dword) + + movdqa xmm2, xmm0 + psrlq xmm0, 1 + psllq xmm2, 63 + movdqa xmm3, xmm1 + psrlq xmm1, 1 + psllq xmm3, 63 + + movdqa xmm4, xmm3 + palignr xmm3, xmm2, sizeof(qword) + psrldq xmm4, sizeof(qword) + + por xmm0, xmm3 + por xmm1, xmm4 + movdqu oword [edi], xmm0 + movq qword [edi+sizeof(oword)], xmm1 + psrldq xmm1, sizeof(qword) + movd dword [edi+sizeof(oword)+sizeof(qword)], xmm1 + + ret +ENDFUNC shr_224 + +;; +;; void cpy_224(Ipp32u* r, const Ipp32u* a) +;; +%macro cpy_224 2.nolist + %xdefine %%pdst %1 + %xdefine %%psrc %2 + + movdqu xmm0, oword [%%psrc] + movq xmm1, qword [%%psrc+sizeof(oword)] + movd xmm2, dword [%%psrc+sizeof(oword)+sizeof(qword)] + movdqu oword [%%pdst], xmm0 + movq qword [%%pdst+sizeof(oword)], xmm1 + movd dword [%%pdst+sizeof(oword)+sizeof(qword)], xmm2 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_add(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_add,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN224] +%assign _sp_ _buf_+(LEN224)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM add_224 ; R = A+B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p224r1_data ; modulus + lea ebx, [ebx+(_prime224r1-p224r1_data)] + CALL_IPPASM sub_224 ; T = R-modulus + + lea esi,[esp+_buf_] + mov edi, pR + sub edx, eax ; R = T<0? R : T + cmovnz esi, edi + cpy_224 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p224r1_add + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_sub(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_sub,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN224] +%assign _sp_ _buf_+(LEN224)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM sub_224 ; R = A-B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p224r1_data ; modulus + lea ebx, [ebx+(_prime224r1-p224r1_data)] + CALL_IPPASM add_224 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_224 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p224r1_sub + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_neg(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_neg,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN224] +%assign _sp_ _buf_+(LEN224)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; outpur pR + mov esi, pA ; input pA + + ; r = 0-a + mov eax, 0 + sub eax, dword [esi] + mov dword [edi], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + sbb edx,edx + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p224r1_data ; modulus + lea ebx, [ebx+(_prime224r1-p224r1_data)] + CALL_IPPASM add_224 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_224 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p224r1_neg + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_mul_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_mul_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN224] +%assign _sp_ _buf_+(LEN224)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; pA + CALL_IPPASM shl_224 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + mov edi, pR ; R + LD_ADDR ebx, p224r1_data ; modulus + lea ebx, [ebx+(_prime224r1-p224r1_data)] + CALL_IPPASM sub_224 ; R = T-modulus + + sub edx, eax ; R = R<0? T : R + cmovz esi, edi + cpy_224 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p224r1_mul_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_mul_by_3(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_mul_by_3,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _bufT_ 0 ; T buffer[LEN224] +%assign _bufU_ _bufT_+(LEN224)*sizeof(dword) ; U buffer[LEN224] +%assign _mod_ _bufU_+(LEN224)*sizeof(dword) ; modulus address [1] +%assign _sp_ _mod_+sizeof(dword) ; esp [1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + LD_ADDR eax, p224r1_data ; srore modulus address + lea eax, [eax+(_prime224r1-p224r1_data)] + mov dword [esp+_mod_], eax + + lea edi, [esp+_bufT_] ; T + mov esi, pA ; A + CALL_IPPASM shl_224 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + lea edi, [esp+_bufU_] ; U + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_224 ; U = T-modulus + + sub edx, eax ; T = U<0? T : U + cmovz esi, edi + cpy_224 edi, esi + + mov esi, edi + mov ebx, pA + CALL_IPPASM add_224 ; T +=A + mov edx, eax + + mov edi, pR ; R + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_224 ; R = T-modulus + + sub edx, eax ; R = T<0? R : T + cmovz esi, edi + cpy_224 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p224r1_mul_by_3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_div_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_div_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN224] +%assign _sp_ _buf_+(LEN224)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; A + LD_ADDR ebx, p224r1_data ; modulus + lea ebx, [ebx+(_prime224r1-p224r1_data)] + CALL_IPPASM add_224 ; R = A+modulus + mov edx, 0 + + mov ecx, dword [esi] ; shifted_data = (a[0]&1)? T : A + and ecx, 1 + cmovnz esi, edi + cmovz eax, edx + mov edi, pR + CALL_IPPASM shr_224 + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p224r1_div_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_mul_mont_slm(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_mul_mont_slm,PUBLIC + USES_GPR ebp,ebx,esi,edi + +%xdefine pR [eax + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [eax + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [eax + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 +%assign _rp_ _buf_+(LEN224+1)*sizeof(dword) ; pR +%assign _ap_ _rp_ +sizeof(dword) ; pA +%assign _bp_ _ap_+sizeof(dword) ; pB +%assign _sp_ _bp_+sizeof(dword) ; esp storage +%assign _ssize_ _sp_+sizeof(dword) ; size allocated stack + + mov eax, esp ; save esp + sub esp, _ssize_ ; allocate stack + and esp, -16 ; provide 16-byte stack alignment + mov dword [esp+_sp_], eax ; store original esp + + ; clear buffer + pxor mm0, mm0 + movq [esp+_buf_], mm0 + movq [esp+_buf_+sizeof(qword)], mm0 + movq [esp+_buf_+sizeof(qword)*2], mm0 + movq [esp+_buf_+sizeof(qword)*3], mm0 + + ; store parameters into the stack + ; note: eax here stores an original esp, so it can be used to reach function parameters + mov edi, pR + mov esi, pA + mov ebp, pB + mov dword [esp+_rp_], edi + mov dword [esp+_ap_], esi + mov dword [esp+_bp_], ebp + + mov edi, LEN224 + + movd mm1, dword [esi+sizeof(dword)] ; pre load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + +align IPP_ALIGN_FACTOR +.mmul_loop: +; +; i-st pass +; modulus = 2^224 -2^96 +1 +; [7] [3] [0] +; m0 = 1 +; + movd mm7, edi ; save pass counter + + mov edx, dword [ebp] ; b = b[i] + mov eax, dword [esi] ; a[0] + movd mm0, edx + add ebp, sizeof(dword) + mov dword [esp+_bp_], ebp + + pmuludq mm1, mm0 ; a[1]*b[i] + pmuludq mm2, mm0 ; a[2]*b[i] + + mul edx ; (E:u) = (edx:eax) = a[0]*b[i]+buf[0] + add eax, dword [esp+_buf_] + adc edx, 0 + + pmuludq mm3, mm0 ; a[3]*b[i] + pmuludq mm4, mm0 ; a[4]*b[i] + +; multiplication round 1 - round 4 + movd ecx, mm1 ; p = a[1]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*1] + movd mm1, dword [esi+sizeof(dword)*5] + adc edx, 0 + + movd ebx, mm2 ; p = a[2]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*2] + movd mm2, dword [esi+sizeof(dword)*6] + adc edx, 0 + + pmuludq mm1, mm0 ; a[5]*b[i] + pmuludq mm2, mm0 ; a[6]*b[i] + + movd ebp, mm3 ; p = a[3]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*3] + adc edx, 0 + + movd edi, mm4 ; p = a[4]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*4] + adc edx, 0 + +;;; and reduction ;;; + neg eax ; u0 + + adc ecx, 0 ; +cf + mov dword [esp+_buf_+sizeof(dword)*0], ecx + adc ebx, 0 ; +cf + mov dword [esp+_buf_+sizeof(dword)*1], ebx + + mov ecx, eax ; save u0 + + sbb eax, 0 ; u0-cf + sub ebp, eax ; -u0+cf + mov dword [esp+_buf_+sizeof(dword)*2], ebp + + mov eax, ecx ; restore u0 + mov ebp, 0 + + sbb edi, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*3], edi + adc ebp, 0 ; save bf + +; multiplication round 5 - round 6 + movd ecx, mm1 ; p = a[5]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*5] + adc edx, 0 + + movd ebx, mm2 ; p = a[6]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*6] + adc edx, 0 + +;;; and reduction ;;; + sub ecx, ebp ; -bf + mov dword [esp+_buf_+sizeof(dword)*4], ecx + sbb ebx, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*5], ebx + +; last multiplication round 7 + movd edi, mm7 ; restore pass counter + + sbb eax, 0 ; u-bf + mov ebx, 0 + + add edx, dword [esp+_buf_+sizeof(dword)*7] + adc ebx, 0 + add edx, eax + mov dword [esp+_buf_+sizeof(dword)*6], edx + adc ebx, 0 + mov dword [esp+_buf_+sizeof(dword)*7], ebx + + sub edi, 1 + movd mm1, dword [esi+sizeof(dword)] ; speculative load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + jz .exit_mmul_loop + + mov ebp, dword [esp+_bp_] ; restore pB + jmp .mmul_loop + +.exit_mmul_loop: + emms + +; final reduction + mov edi, [esp+_rp_] ; result + lea esi, [esp+_buf_] ; buffer + LD_ADDR ebx, p224r1_data ; modulus + lea ebx, [ebx+(_prime224r1-p224r1_data)] + CALL_IPPASM sub_224 + mov edx, dword [esp+_buf_+LEN224*sizeof(dword)] + sub edx, eax + +; copy + cmovz esi, edi + cpy_224 edi, esi + + mov esp, [esp+_sp_] ; release stack + REST_GPR + ret +ENDFUNC p224r1_mul_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_sqr_mont_slm(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_sqr_mont_slm,PUBLIC + USES_GPR esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source A address + + ;; use p224r1_mul_mont_slm to compute sqr + mov esi, pA + mov edi, pR + push esi + push esi + push edi + CALL_IPPASM p224r1_mul_mont_slm,PUBLIC + add esp, sizeof(dword)*3 + REST_GPR + ret +ENDFUNC p224r1_sqr_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p224r1_mred(Ipp32u* r, Ipp32u* prod) +;; +; modulus = 2^224 -2^96 +1 +; [7] [3] [0] +; m0 = -1 +; +align IPP_ALIGN_FACTOR +IPPASM p224r1_mred,PUBLIC + USES_GPR ebx,esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; reduction address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source product address + + ; get parameters: + mov esi, pA + + mov ecx, LEN224 + xor edx, edx +align IPP_ALIGN_FACTOR +.mred_loop: + mov eax, dword [esi] + neg eax + + mov ebx, 0 + mov dword [esi], ebx + + mov ebx, dword [esi+sizeof(dword)] + adc ebx, 0 + mov dword [esi+sizeof(dword)], ebx + + mov ebx, dword [esi+sizeof(dword)*2] + adc ebx, 0 + mov dword [esi+sizeof(dword)*2], ebx + + push eax + mov ebx, dword [esi+sizeof(dword)*3] + sbb eax, 0 + sub ebx, eax + mov dword [esi+sizeof(dword)*3], ebx + pop eax + + mov ebx, dword [esi+sizeof(dword)*4] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*4], ebx + + mov ebx, dword [esi+sizeof(dword)*5] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*5], ebx + + mov ebx, dword [esi+sizeof(dword)*6] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*6], ebx + + mov ebx, dword [esi+sizeof(dword)*7] + sbb eax, 0 + add eax, edx + mov edx, 0 + adc edx, 0 + add ebx, eax + mov dword [esi+sizeof(dword)*7], ebx + adc edx, 0 + + lea esi, [esi+sizeof(dword)] + sub ecx, 1 + jnz .mred_loop + + ; final reduction + mov edi, pR ; result + LD_ADDR ebx, p224r1_data ; addres of the modulus + lea ebx, [ebx+(_prime224r1-p224r1_data)] + CALL_IPPASM sub_224 + + sub edx, eax + cmovz esi, edi + cpy_224 edi, esi + + REST_GPR + ret +ENDFUNC p224r1_mred + +%endif ;; _IPP >= _IPP_P8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp256r1arith_mont_slm.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp256r1arith_mont_slm.asm new file mode 100644 index 000000000..b21452b56 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp256r1arith_mont_slm.asm @@ -0,0 +1,874 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; P256r1 basic arithmetic function +; +; Content: +; p256r1_add +; p256r1_sub +; p256r1_neg +; p256r1_div_by_2 +; p256r1_mul_mont_slm +; p256r1_sqr_mont_slm +; p256r1_mred +; p256r1_mont_back +; p256r1_select_ap_w7 +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +;; +;; some p256r1 constants +;; +p256r1_data: +_prime256r1 DD 0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,000000000h,000000000h,000000000h,000000001h, 0FFFFFFFFh + +%assign LEN256 (256/32) ; dword's length of operands + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Ipp32u add_256(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = carry = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM add_256,PRIVATE + ; r = a+b + mov eax, dword [esi] + add eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + adc eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + adc eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + adc eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + adc eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + adc eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + adc eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + adc eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC add_256 + +;; +;; Ipp32u sub_256(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = borrow = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM sub_256,PRIVATE + ; r = a-b + mov eax, dword [esi] + sub eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + sbb eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + sbb eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + sbb eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + sbb eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + sbb eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + sbb eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + sbb eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC sub_256 + +;; +;; Ipp32u shl_256(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shl_256,PRIVATE + ; r = a<<1 + movdqu xmm0, oword [esi] + movdqu xmm1, oword [esi+sizeof(oword)] + mov eax, dword [esi+(LEN256-1)*sizeof(dword)] + + movdqa xmm2, xmm0 + psllq xmm0, 1 + psrlq xmm2, 63 + movdqa xmm3, xmm1 + psllq xmm1, 1 + psrlq xmm3, 63 + + palignr xmm3, xmm2, sizeof(qword) + pslldq xmm2, sizeof(qword) + + por xmm1, xmm3 + por xmm0, xmm2 + movdqu oword [edi], xmm0 + movdqu oword [edi+sizeof(oword)], xmm1 + + shr eax, 31 + ret +ENDFUNC shl_256 + +;; +;; void shr_256(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; eax = ext +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shr_256,PRIVATE + ; r = a>>1 + movd xmm4, eax + movdqu xmm0, oword [esi] + movdqu xmm1, oword [esi+sizeof(oword)] + + psllq xmm4, 63 + movdqa xmm2, xmm0 + psrlq xmm0, 1 + psllq xmm2, 63 + movdqa xmm3, xmm1 + psrlq xmm1, 1 + psllq xmm3, 63 + + palignr xmm4, xmm3, sizeof(qword) + palignr xmm3, xmm2, sizeof(qword) + + por xmm1, xmm4 + por xmm0, xmm3 + movdqu oword [edi], xmm0 + movdqu oword [edi+sizeof(oword)], xmm1 + + ret +ENDFUNC shr_256 + +;; +;; void cpy_256(Ipp32u* r, const Ipp32u* a) +;; +%macro cpy_256 2.nolist + %xdefine %%pdst %1 + %xdefine %%psrc %2 + + movdqu xmm0, oword [%%psrc] + movdqu xmm1, oword [%%psrc+sizeof(oword)] + movdqu oword [%%pdst], xmm0 + movdqu oword [%%pdst+sizeof(oword)], xmm1 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_add(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_add,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN256] +%assign _sp_ _buf_+(LEN256)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM add_256 ; R = A+B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p256r1_data ; modulus + lea ebx, [ebx+(_prime256r1-p256r1_data)] + CALL_IPPASM sub_256 ; T = R-modulus + + lea esi,[esp+_buf_] + mov edi, pR + sub edx, eax ; R = T<0? R : T + cmovnz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p256r1_add + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_sub(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_sub,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN256] +%assign _sp_ _buf_+(LEN256)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM sub_256 ; R = A-B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p256r1_data ; modulus + lea ebx, [ebx+(_prime256r1-p256r1_data)] + CALL_IPPASM add_256 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p256r1_sub + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_neg(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_neg,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN256] +%assign _sp_ _buf_+(LEN256)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; outpur pR + mov esi, pA ; input pA + + ; r = 0-a + mov eax, 0 + sub eax, dword [esi] + mov dword [edi], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + sbb edx,edx + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p256r1_data ; modulus + lea ebx, [ebx+(_prime256r1-p256r1_data)] + CALL_IPPASM add_256 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p256r1_neg + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_mul_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_mul_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN256] +%assign _sp_ _buf_+(LEN256)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; pA + CALL_IPPASM shl_256 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + mov edi, pR ; R + LD_ADDR ebx, p256r1_data ; modulus + lea ebx, [ebx+(_prime256r1-p256r1_data)] + CALL_IPPASM sub_256 ; R = T-modulus + + sub edx, eax ; R = R<0? T : R + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p256r1_mul_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_mul_by_3(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_mul_by_3,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _bufT_ 0 ; T buffer[LEN256] +%assign _bufU_ _bufT_+(LEN256)*sizeof(dword) ; U buffer[LEN256] +%assign _mod_ _bufU_+(LEN256)*sizeof(dword) ; modulus address [1] +%assign _sp_ _mod_+sizeof(dword) ; esp [1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + LD_ADDR eax, p256r1_data ; srore modulus address + lea eax, [eax+(_prime256r1-p256r1_data)] + mov dword [esp+_mod_], eax + + lea edi, [esp+_bufT_] ; T + mov esi, pA ; A + CALL_IPPASM shl_256 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + lea edi, [esp+_bufU_] ; U + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_256 ; U = T-modulus + + sub edx, eax ; T = U<0? T : U + cmovz esi, edi + cpy_256 edi, esi + + mov esi, edi + mov ebx, pA + CALL_IPPASM add_256 ; T +=A + mov edx, eax + + mov edi, pR ; R + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_256 ; R = T-modulus + + sub edx, eax ; R = T<0? R : T + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p256r1_mul_by_3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_div_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_div_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN256] +%assign _sp_ _buf_+(LEN256)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; A + LD_ADDR ebx, p256r1_data ; modulus + lea ebx, [ebx+(_prime256r1-p256r1_data)] + CALL_IPPASM add_256 ; R = A+modulus + mov edx, 0 + + mov ecx, dword [esi] ; shifted_data = (a[0]&1)? T : A + and ecx, 1 + cmovnz esi, edi + cmovz eax, edx + mov edi, pR + CALL_IPPASM shr_256 + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p256r1_div_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_mul_mont_slm(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_mul_mont_slm,PUBLIC + USES_GPR ebp,ebx,esi,edi + +%xdefine pR [eax + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [eax + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [eax + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 +%assign _rp_ _buf_+(LEN256+1)*sizeof(dword) ; pR +%assign _ap_ _rp_ +sizeof(dword) ; pA +%assign _bp_ _ap_+sizeof(dword) ; pB +%assign _sp_ _bp_+sizeof(dword) ; esp storage +%assign _ssize_ _sp_+sizeof(dword) ; size allocated stack + + mov eax, esp ; save esp + sub esp, _ssize_ ; allocate stack + and esp, -16 ; provide 16-byte stack alignment + mov dword [esp+_sp_], eax ; store original esp + + ; clear buffer + pxor mm0, mm0 + movq qword [esp+_buf_], mm0 + movq qword [esp+_buf_+sizeof(qword)], mm0 + movq qword [esp+_buf_+sizeof(qword)*2], mm0 + movq qword [esp+_buf_+sizeof(qword)*3], mm0 + movd dword [esp+_buf_+sizeof(qword)*4], mm0 + + ; store parameters into the stack + ; note: eax here stores an original esp, so it can be used to reach function parameters + mov edi, pR + mov esi, pA + mov ebp, pB + mov dword [esp+_rp_], edi + mov dword [esp+_ap_], esi + mov dword [esp+_bp_], ebp + + mov edi, LEN256 + + movd mm1, dword [esi+sizeof(dword)] ; pre load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + +align IPP_ALIGN_FACTOR +.mmul_loop: +; +; i-st pass +; modulus = 2^256 -2^224 +2^192 +2^96 -1 +; [8] [7] [6] [3] [0] +; m0 = 1 +; + movd mm7, edi ; save pass counter + + mov edx, dword [ebp] ; b = b[i] + mov eax, dword [esi] ; a[0] + movd mm0, edx + add ebp, sizeof(dword) + mov dword [esp+_bp_], ebp + + pmuludq mm1, mm0 ; a[1]*b[i] + pmuludq mm2, mm0 ; a[2]*b[i] + + mul edx ; (E:u) = (edx:eax) = a[0]*b[i]+buf[0] + add eax, dword [esp+_buf_] + adc edx, 0 + + pmuludq mm3, mm0 ; a[3]*b[i] + pmuludq mm4, mm0 ; a[4]*b[i] + +; multiplication round 1 - round 4 + movd ecx, mm1 ; p = a[1]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*1] + movd mm1, dword [esi+sizeof(dword)*5] + adc edx, 0 + + movd ebx, mm2 ; p = a[2]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*2] + movd mm2, dword [esi+sizeof(dword)*6] + adc edx, 0 + + pmuludq mm1, mm0 ; a[5]*b[i] + pmuludq mm2, mm0 ; a[6]*b[i] + + movd ebp, mm3 ; p = a[3]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*3] + movd mm3, dword [esi+sizeof(dword)*7] + adc edx, 0 + + movd edi, mm4 ; p = a[4]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*4] + adc edx, 0 + + pmuludq mm3, mm0 ; a[7]*b[i] + +;;; and reduction ;;; + ; eax =u0 + + mov dword [esp+_buf_+sizeof(dword)*0], ecx ; copy + mov dword [esp+_buf_+sizeof(dword)*1], ebx ; copy + + add ebp, eax ; +u0 + mov dword [esp+_buf_+sizeof(dword)*2], ebp + + adc edi, 0 ; +cf + mov dword [esp+_buf_+sizeof(dword)*3], edi + mov edi, 0 ; save edi = cf + adc edi, 0 + +; multiplication round 5 - round 7 + movd ecx, mm1 ; p = a[5]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*5] + adc edx, 0 + + movd ebx, mm2 ; p = a[6]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*6] + adc edx, 0 + + movd ebp, mm3 ; p = a[7]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*7] + adc edx, 0 + +;;; and reduction ;;; + add ecx, edi ; +cf + mov dword [esp+_buf_+sizeof(dword)*4], ecx + adc ebx, eax ; +u0+cf + mov dword [esp+_buf_+sizeof(dword)*5], ebx + mov ecx, eax + sbb eax, 0 + sub ebp, eax ; -u0+cf + mov dword [esp+_buf_+sizeof(dword)*6], ebp + +; last multiplication round 8 + movd edi, mm7 ; restore pass counter + + sbb ecx, 0 ; u-bf + mov ebx, 0 + + add edx, dword [esp+_buf_+sizeof(dword)*8] + adc ebx, 0 + add edx, ecx + mov dword [esp+_buf_+sizeof(dword)*7], edx + adc ebx, 0 + mov dword [esp+_buf_+sizeof(dword)*8], ebx + + sub edi, 1 + movd mm1, dword [esi+sizeof(dword)] ; speculative load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + jz .exit_mmul_loop + + mov ebp, dword [esp+_bp_] ; restore pB + jmp .mmul_loop + +.exit_mmul_loop: + emms + +; final reduction + mov edi, [esp+_rp_] ; result + lea esi, [esp+_buf_] ; buffer + LD_ADDR ebx, p256r1_data ; modulus + lea ebx, [ebx+(_prime256r1-p256r1_data)] + CALL_IPPASM sub_256 + mov edx, dword [esp+_buf_+LEN256*sizeof(dword)] + sub edx, eax + +; copy + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] ; release stack + REST_GPR + ret +ENDFUNC p256r1_mul_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_sqr_mont_slm(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_sqr_mont_slm,PUBLIC + USES_GPR esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source A address + + ;; use p256r1_mul_mont_slm to compute sqr + mov esi, pA + mov edi, pR + push esi + push esi + push edi + CALL_IPPASM p256r1_mul_mont_slm,PUBLIC + add esp, sizeof(dword)*3 + REST_GPR + ret +ENDFUNC p256r1_sqr_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p256r1_mred(Ipp32u* r, Ipp32u* prod) +;; +; modulus = 2^256 -2^224 +2^192 +2^96 -1 +; [8] [7] [6] [3] [0] +; m0 = 1 +; +align IPP_ALIGN_FACTOR +IPPASM p256r1_mred,PUBLIC + USES_GPR ebx,esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; reduction address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source product address + + ; get parameters: + mov esi, pA + + mov ecx, LEN256 + xor edx, edx +align IPP_ALIGN_FACTOR +.mred_loop: + mov eax, dword [esi] + + mov ebx, 0 + mov dword [esi], ebx + + mov ebx, dword [esi+sizeof(dword)*3] + add ebx, eax + mov dword [esi+sizeof(dword)*3], ebx + + mov ebx, dword [esi+sizeof(dword)*4] + adc ebx, 0 + mov dword [esi+sizeof(dword)*4], ebx + + mov ebx, dword [esi+sizeof(dword)*5] + adc ebx, 0 + mov dword [esi+sizeof(dword)*5], ebx + + mov ebx, dword [esi+sizeof(dword)*6] + adc ebx, eax + mov dword [esi+sizeof(dword)*6], ebx + + mov ebx, dword [esi+sizeof(dword)*7] + push eax + sbb eax, 0 + sub ebx, eax + mov dword [esi+sizeof(dword)*7], ebx + pop eax + + mov ebx, dword [esi+sizeof(dword)*8] + sbb eax, 0 + add eax, edx + mov edx, 0 + adc edx, 0 + add ebx, eax + mov dword [esi+sizeof(dword)*8], ebx + adc edx, 0 + + lea esi, [esi+sizeof(dword)] + sub ecx, 1 + jnz .mred_loop + + ; final reduction + mov edi, pR ; result + LD_ADDR ebx, p256r1_data ; addres of the modulus + lea ebx, [ebx+(_prime256r1-p256r1_data)] + CALL_IPPASM sub_256 + + sub edx, eax + cmovz esi, edi + cpy_256 edi, esi + + REST_GPR + ret +ENDFUNC p256r1_mred + +%endif ;; _IPP >= _IPP_P8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp384r1arith_mont_slm.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp384r1arith_mont_slm.asm new file mode 100644 index 000000000..fe2228d8f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp384r1arith_mont_slm.asm @@ -0,0 +1,1030 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; P384r1 basic arithmetic function +; +; Content: +; p384r1_add +; p384r1_sub +; p384r1_neg +; p384r1_div_by_2 +; p384r1_mul_mont_slm +; p384r1_sqr_mont_slm +; p384r1_mred +; p384r1_select_ap_w5 +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +;; +;; some p384r1 constants +;; +p384r1_data: +_prime384r1 DD 0FFFFFFFFh,000000000h,000000000h,0FFFFFFFFh,0FFFFFFFEh,0FFFFFFFFh + DD 0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh + +%assign LEN384 (384/32) ; dword's length of operands + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Ipp32u add_384(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = carry = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM add_384,PRIVATE + ; r = a+b + mov eax, dword [esi] + add eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + adc eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + adc eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + adc eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + adc eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + adc eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + adc eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + adc eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, dword [esi+sizeof(dword)*8] + adc eax, dword [ebx+sizeof(dword)*8] + mov dword [edi+sizeof(dword)*8], eax + + mov eax, dword [esi+sizeof(dword)*9] + adc eax, dword [ebx+sizeof(dword)*9] + mov dword [edi+sizeof(dword)*9], eax + + mov eax, dword [esi+sizeof(dword)*10] + adc eax, dword [ebx+sizeof(dword)*10] + mov dword [edi+sizeof(dword)*10], eax + + mov eax, dword [esi+sizeof(dword)*11] + adc eax, dword [ebx+sizeof(dword)*11] + mov dword [edi+sizeof(dword)*11], eax + mov eax, 0 + adc eax, 0 + ret +ENDFUNC add_384 + +;; +;; Ipp32u sub_384(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = borrow = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM sub_384,PRIVATE + ; r = a-b + mov eax, dword [esi] + sub eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + sbb eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + sbb eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + sbb eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + sbb eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + sbb eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + sbb eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + sbb eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, dword [esi+sizeof(dword)*8] + sbb eax, dword [ebx+sizeof(dword)*8] + mov dword [edi+sizeof(dword)*8], eax + + mov eax, dword [esi+sizeof(dword)*9] + sbb eax, dword [ebx+sizeof(dword)*9] + mov dword [edi+sizeof(dword)*9], eax + + mov eax, dword [esi+sizeof(dword)*10] + sbb eax, dword [ebx+sizeof(dword)*10] + mov dword [edi+sizeof(dword)*10], eax + + mov eax, dword [esi+sizeof(dword)*11] + sbb eax, dword [ebx+sizeof(dword)*11] + mov dword [edi+sizeof(dword)*11], eax + mov eax, 0 + adc eax, 0 + ret +ENDFUNC sub_384 + +;; +;; Ipp32u shl_384(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shl_384,PRIVATE + mov eax, dword [esi+(LEN384-1)*sizeof(dword)] + ; r = a<<1 + movdqu xmm3, oword [esi+sizeof(oword)*2] + movdqu xmm2, oword [esi+sizeof(oword)] + movdqu xmm1, oword [esi] + + movdqa xmm4, xmm3 + palignr xmm4, xmm2, sizeof(qword) + psllq xmm3, 1 + psrlq xmm4, 63 + por xmm3, xmm4 + movdqu oword [edi+sizeof(oword)*2], xmm3 + + movdqa xmm4, xmm2 + palignr xmm4, xmm1, sizeof(qword) + psllq xmm2, 1 + psrlq xmm4, 63 + por xmm2, xmm4 + movdqu oword [edi+sizeof(oword)], xmm2 + + movdqa xmm4, xmm1 + pslldq xmm4, sizeof(qword) + psllq xmm1, 1 + psrlq xmm4, 63 + por xmm1, xmm4 + movdqu oword [edi], xmm1 + + shr eax, 31 + ret +ENDFUNC shl_384 + +;; +;; void shr_384(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; eax = ext +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shr_384,PRIVATE + ; r = a>>1 + movdqu xmm3, oword [esi] + movdqu xmm2, oword [esi+sizeof(oword)] + movdqu xmm1, oword [esi+sizeof(oword)*2] + + movdqa xmm4, xmm2 + palignr xmm4, xmm3, sizeof(qword) + psrlq xmm3, 1 + psllq xmm4, 63 + por xmm3, xmm4 + movdqu oword [edi], xmm3 + + movdqa xmm4, xmm1 + palignr xmm4, xmm2, sizeof(qword) + psrlq xmm2, 1 + psllq xmm4, 63 + por xmm2, xmm4 + movdqu oword [edi+sizeof(oword)], xmm2 + + movdqa xmm4, xmm0 + palignr xmm4, xmm1, sizeof(qword) + psrlq xmm1, 1 + psllq xmm4, 63 + por xmm1, xmm4 + movdqu oword [edi+sizeof(oword)*2], xmm1 + + ret +ENDFUNC shr_384 + +;; +;; void cpy_384(Ipp32u* r, const Ipp32u* a) +;; +%macro cpy_384 2.nolist + %xdefine %%pdst %1 + %xdefine %%psrc %2 + + movdqu xmm0, oword [%%psrc] + movdqu xmm1, oword [%%psrc+sizeof(oword)] + movdqu xmm2, oword [%%psrc+sizeof(oword)*2] + movdqu oword [%%pdst], xmm0 + movdqu oword [%%pdst+sizeof(oword)], xmm1 + movdqu oword [%%pdst+sizeof(oword)*2], xmm2 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_add(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_add,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN384] +%assign _sp_ _buf_+(LEN384)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM add_384 ; R = A+B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p384r1_data ; modulus + lea ebx, [ebx+(_prime384r1-p384r1_data)] + CALL_IPPASM sub_384 ; T = R-modulus + + lea esi,[esp+_buf_] + mov edi, pR + sub edx, eax ; R = T<0? R : T + cmovnz esi, edi + cpy_384 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p384r1_add + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_sub(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_sub,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN384] +%assign _sp_ _buf_+(LEN384)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM sub_384 ; R = A-B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p384r1_data ; modulus + lea ebx, [ebx+(_prime384r1-p384r1_data)] + CALL_IPPASM add_384 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_384 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p384r1_sub + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_neg(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_neg,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN384] +%assign _sp_ _buf_+(LEN384)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; outpur pR + mov esi, pA ; input pA + + ; r = 0-a + mov eax, 0 + sub eax, dword [esi] + mov dword [edi], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*8] + mov dword [edi+sizeof(dword)*8], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*9] + mov dword [edi+sizeof(dword)*9], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*10] + mov dword [edi+sizeof(dword)*10], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*11] + mov dword [edi+sizeof(dword)*11], eax + sbb edx,edx + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p384r1_data ; modulus + lea ebx, [ebx+(_prime384r1-p384r1_data)] + CALL_IPPASM add_384 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_384 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p384r1_neg + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_mul_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_mul_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN384] +%assign _sp_ _buf_+(LEN384)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; pA + CALL_IPPASM shl_384 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + mov edi, pR ; R + LD_ADDR ebx, p384r1_data ; modulus + lea ebx, [ebx+(_prime384r1-p384r1_data)] + CALL_IPPASM sub_384 ; R = T-modulus + + sub edx, eax ; R = R<0? T : R + cmovz esi, edi + cpy_384 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p384r1_mul_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_mul_by_3(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_mul_by_3,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _bufT_ 0 ; T buffer[LEN384] +%assign _bufU_ _bufT_+(LEN384)*sizeof(dword) ; U buffer[LEN384] +%assign _mod_ _bufU_+(LEN384)*sizeof(dword) ; modulus address [1] +%assign _sp_ _mod_+sizeof(dword) ; esp [1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + LD_ADDR eax, p384r1_data ; srore modulus address + lea eax, [eax+(_prime384r1-p384r1_data)] + mov dword [esp+_mod_], eax + + lea edi, [esp+_bufT_] ; T + mov esi, pA ; A + CALL_IPPASM shl_384 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + lea edi, [esp+_bufU_] ; U + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_384 ; U = T-modulus + + sub edx, eax ; T = U<0? T : U + cmovz esi, edi + cpy_384 edi, esi + + mov esi, edi + mov ebx, pA + CALL_IPPASM add_384 ; T +=A + mov edx, eax + + mov edi, pR ; R + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_384 ; R = T-modulus + + sub edx, eax ; R = T<0? R : T + cmovz esi, edi + cpy_384 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p384r1_mul_by_3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_div_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_div_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN384] +%assign _sp_ _buf_+(LEN384)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; A + LD_ADDR ebx, p384r1_data ; modulus + lea ebx, [ebx+(_prime384r1-p384r1_data)] + CALL_IPPASM add_384 ; R = A+modulus + mov edx, 0 + + mov ecx, dword [esi] ; shifted_data = (a[0]&1)? T : A + and ecx, 1 + cmovnz esi, edi + cmovz eax, edx + movd xmm0, eax + mov edi, pR + CALL_IPPASM shr_384 + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p384r1_div_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_mul_mont_slm(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_mul_mont_slm,PUBLIC + USES_GPR ebp,ebx,esi,edi + +%xdefine pR [eax + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [eax + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [eax + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 +%assign _rp_ _buf_+(LEN384+1)*sizeof(dword) ; pR +%assign _ap_ _rp_ +sizeof(dword) ; pA +%assign _bp_ _ap_+sizeof(dword) ; pB +%assign _sp_ _bp_+sizeof(dword) ; esp storage +%assign _ssize_ _sp_+sizeof(dword) ; size allocated stack + + mov eax, esp ; save esp + sub esp, _ssize_ ; allocate stack + and esp, -16 ; provide 16-byte stack alignment + mov dword [esp+_sp_], eax ; store original esp + + ; clear buffer + pxor mm0, mm0 + movq [esp+_buf_], mm0 + movq [esp+_buf_+sizeof(qword)], mm0 + movq [esp+_buf_+sizeof(qword)*2], mm0 + movq [esp+_buf_+sizeof(qword)*3], mm0 + movq [esp+_buf_+sizeof(qword)*4], mm0 + movq [esp+_buf_+sizeof(qword)*5], mm0 + movq [esp+_buf_+sizeof(qword)*6], mm0 + + ; store parameters into the stack + ; note: eax here stores an original esp, so it can be used to reach function parameters + mov edi, pR + mov esi, pA + mov ebp, pB + mov dword [esp+_rp_], edi + mov dword [esp+_ap_], esi + mov dword [esp+_bp_], ebp + + mov eax, LEN384 + + movd mm1, dword [esi+sizeof(dword)] ; pre load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + + +align IPP_ALIGN_FACTOR +.mmul_loop: +; +; i-st pass +; modulus = 2^384 -2^128 -2^96 +2^32 -1 +; [12] [4] [3] [1] [0] +; m0 = 1 +; +; T0 = a[ 0]*b[i] + p[0] +; e0 = HI(T0), u = LO(T0) +; +; T1 = a[ 1]*b[i] +e0 +p[ 1], (cf=0), e1 = HI( T1), p1 =LO( T1), (cf1 ,p1 ) = p1 +u, p[ 0] = p1, cf1 +; T2 = a[ 2]*b[i] +e1 +p[ 2], (cf=0), e2 = HI( T2), p2 =LO( T2), (cf2 ,p2 ) = p2 +cf1, p[ 1] = p2, cf2 +; T3 = a[ 3]*b[i] +e2 +p[ 3], (cf=0), e3 = HI( T3), p3 =LO( T3), (bf3 ,p3 ) = p3 +cf2 -u, p[ 2] = p3, bf3 +; T4 = a[ 4]*b[i] +e3 +p[ 4], (cf=0), e4 = HI( T4), p4 =LO( T4), (bf4 ,p4 ) = p4 -bf3 -u, p[ 3] = p4, bf4 +; T5 = a[ 5]*b[i] +e4 +p[ 5], (cf=0), e5 = HI( T5), p5 =LO( T5), (bf5 ,p5 ) = p5 -bf4, p[ 4] = p5, bf5 +; T6 = a[ 6]*b[i] +e5 +p[ 6], (cf=0), e6 = HI( T6), p6 =LO( T6), (bf6 ,p6 ) = p6 -bf5, p[ 5] = p6, bf6 +; T7 = a[ 7]*b[i] +e6 +p[ 7], (cf=0), e7 = HI( T7), p7 =LO( T7), (bf7 ,p7 ) = p7 -bf6, p[ 6] = p7, bf7 +; T8 = a[ 8]*b[i] +e7 +p[ 8], (cf=0), e8 = HI( T8), p8 =LO( T8), (bf8 ,p8 ) = p8 -bf7, p[ 7] = p8, bf8 +; T9 = a[ 9]*b[i] +e8 +p[ 9], (cf=0), e9 = HI( T9), p9 =LO( T9), (bf9 ,p9 ) = p9 -bf8, p[ 8] = p9, bf9 +; T10 = a[10]*b[i] +e9 +p[10], (cf=0), e10= HI(T10), p10=LO(T10), (bf10,p10) = p10-bf9, p[ 9] = p10, bf9 +; T11 = a[11]*b[i] +e10 +p[11], (cf=0), e11= HI(T11), p11=LO(T11), (bf11,p11) = p11-bf10, p[10] = p11, bf10 +; (cf12,p12) = e11-bf11+u p[11] = p12, cf12 +; p[13] = cf12 + movd mm7, eax ; save pass counter + + mov edx, dword [ebp] ; b = b[i] + mov eax, dword [esi] ; a[0] + movd mm0, edx + add ebp, sizeof(dword) + mov dword [esp+_bp_], ebp + + pmuludq mm1, mm0 ; a[1]*b[i] + pmuludq mm2, mm0 ; a[2]*b[i] + + mul edx ; (E:u) = (edx:eax) = a[0]*b[i]+buf[0] + add eax, dword [esp+_buf_] + adc edx, 0 + + pmuludq mm3, mm0 ; a[3]*b[i] + pmuludq mm4, mm0 ; a[4]*b[i] + +; multiplication round 1 - round 4 + movd ecx, mm1 ; p = a[1]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*1] + movd mm1, dword [esi+sizeof(dword)*5] + adc edx, 0 + ;pmuludq mm1, mm0 + + movd ebx, mm2 ; p = a[2]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*2] + movd mm2, dword [esi+sizeof(dword)*6] + adc edx, 0 + pmuludq mm1, mm0 + pmuludq mm2, mm0 + + movd ebp, mm3 ; p = a[3]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*3] + movd mm3, dword [esi+sizeof(dword)*7] + adc edx, 0 + ;pmuludq mm3, mm0 + + movd edi, mm4 ; p = a[4]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*4] + movd mm4, dword [esi+sizeof(dword)*8] + adc edx, 0 + pmuludq mm3, mm0 + pmuludq mm4, mm0 + +;;; and reduction ;;; + add ecx, eax ; +u0 + mov dword [esp+_buf_+sizeof(dword)*0], ecx + mov ecx, eax ; save u0 + adc ebx, 0 ; +cf + mov dword [esp+_buf_+sizeof(dword)*1], ebx + sbb eax, 0 ; eax = u0-cf + sub ebp, eax ; ebp-eax = ebp+cf-u0 + mov dword [esp+_buf_+sizeof(dword)*2], ebp + sbb edi, ecx ; edi-u0-bf + mov eax, 0 + mov dword [esp+_buf_+sizeof(dword)*3], edi + movd mm6, ecx + ;sbb eax, eax ; save bf signu: eax = bf? 0xffffffff: 0x00000000 + adc eax, 0 + +; multiplication round 5 - round 8 + movd ecx, mm1 ; p = a[5]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*5] + movd mm1, dword [esi+sizeof(dword)*9] + adc edx, 0 + ;pmuludq mm1, mm0 + + movd ebx, mm2 ; p = a[6]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*6] + movd mm2, dword [esi+sizeof(dword)*10] + adc edx, 0 + pmuludq mm1, mm0 + pmuludq mm2, mm0 + + movd ebp, mm3 ; p = a[7]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*7] + movd mm3, dword [esi+sizeof(dword)*11] + adc edx, 0 + pmuludq mm3, mm0 + + movd edi, mm4 ; p = a[8]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*8] + adc edx, 0 + +;;; and reduction ;;; + ;add eax, eax ; restore bf + ;sbb ecx, 0 ; -bf + sub ecx, eax + movd eax, mm6 + mov dword [esp+_buf_+sizeof(dword)*4], ecx + sbb ebx, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*5], ebx + sbb ebp, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*6], ebp + sbb edi, 0 ; -bf + mov eax, 0 + mov dword [esp+_buf_+sizeof(dword)*7], edi + ;sbb eax, eax + adc eax, 0 + +; multiplication round 9 - round 11 + movd ecx, mm1 ; p = a[9]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*9] + adc edx, 0 + + movd ebx, mm2 ; p = a[10]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*10] + adc edx, 0 + + movd ebp, mm3 ; p = a[11]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*11] + adc edx, 0 + +;;; and reduction ;;; + ;add eax, eax ; restore bf + ;sbb ecx, 0 ; u0-bf + sub ecx, eax + mov dword [esp+_buf_+sizeof(dword)*8], ecx + movd ecx, mm6 + sbb ebx, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*9], ebx + sbb ebp, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*10], ebp + sbb ecx, 0 ; u0-bf + mov ebx, 0 + +; last multiplication round 12 + movd eax, mm7 ; restore pass counter + + add edx, dword [esp+_buf_+sizeof(dword)*12] + adc ebx, 0 + add edx, ecx + adc ebx, 0 + mov dword [esp+_buf_+sizeof(dword)*11], edx + mov dword [esp+_buf_+sizeof(dword)*12], ebx + + sub eax, 1 + movd mm1, dword [esi+sizeof(dword)] ; speculative load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + jz .exit_mmul_loop + + mov ebp, dword [esp+_bp_] ; restore pB + jmp .mmul_loop + +.exit_mmul_loop: + emms + +; final reduction + mov edi, [esp+_rp_] ; result + lea esi, [esp+_buf_] ; buffer + LD_ADDR ebx, p384r1_data ; modulus + lea ebx, [ebx+(_prime384r1-p384r1_data)] + CALL_IPPASM sub_384 + mov edx, dword [esp+_buf_+sizeof(dword)*12] + sub edx, eax + +; copy + cmovz esi, edi + cpy_384 edi, esi + + mov esp, [esp+_sp_] ; release stack + REST_GPR + ret +ENDFUNC p384r1_mul_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_sqr_mont_slm(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_sqr_mont_slm,PUBLIC + USES_GPR esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source A address + + ;; use p384r1_mul_mont_slm to compute sqr + mov esi, pA + mov edi, pR + push esi + push esi + push edi + CALL_IPPASM p384r1_mul_mont_slm,PUBLIC + add esp, sizeof(dword)*3 + REST_GPR + ret +ENDFUNC p384r1_sqr_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p384r1_mred(Ipp32u* r, Ipp32u* prod) +;; +; modulus = 2^384 -2^128 -2^96 +2^32 -1 +; [12] [4] [3] [1] [0] +; m0 = 1 +; +align IPP_ALIGN_FACTOR +IPPASM p384r1_mred,PUBLIC + USES_GPR ebx,esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; reduction address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source product address + + ; get parameters: + mov esi, pA + + mov ecx, LEN384 + xor edx, edx +align IPP_ALIGN_FACTOR +.mred_loop: + mov eax, dword [esi] + + mov ebx, dword [esi+sizeof(dword)] + add ebx, eax + mov dword [esi+sizeof(dword)], ebx + + mov ebx, dword [esi+sizeof(dword)*2] + adc ebx, 0 + mov dword [esi+sizeof(dword)*2], ebx + + mov ebx, dword [esi+sizeof(dword)*3] + sbb eax, 0 + sub ebx, eax + mov eax, dword [esi] + mov dword [esi+sizeof(dword)*3], ebx + + mov ebx, dword [esi+sizeof(dword)*4] + sbb ebx, eax + mov dword [esi+sizeof(dword)*4], ebx + + mov ebx, dword [esi+sizeof(dword)*5] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*5], ebx + + mov ebx, dword [esi+sizeof(dword)*6] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*6], ebx + + mov ebx, dword [esi+sizeof(dword)*7] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*7], ebx + + mov ebx, dword [esi+sizeof(dword)*8] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*8], ebx + + mov ebx, dword [esi+sizeof(dword)*9] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*9], ebx + + mov ebx, dword [esi+sizeof(dword)*10] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*10], ebx + + mov ebx, dword [esi+sizeof(dword)*11] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*11], ebx + + mov ebx, dword [esi+sizeof(dword)*12] + sbb eax, 0 + add eax, edx + mov edx, 0 + adc edx, 0 + add ebx, eax + mov dword [esi+sizeof(dword)*12], ebx + adc edx, 0 + + lea esi, [esi+sizeof(dword)] + sub ecx, 1 + jnz .mred_loop + + ; final reduction + mov edi, pR ; result + LD_ADDR ebx, p384r1_data ; addres of the modulus + lea ebx, [ebx+(_prime384r1-p384r1_data)] + CALL_IPPASM sub_384 + + sub edx, eax + cmovz esi, edi + cpy_384 edi, esi + + REST_GPR + ret +ENDFUNC p384r1_mred + +%endif ;; _IPP >= _IPP_P8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp521r1arith_mont_slm.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp521r1arith_mont_slm.asm new file mode 100644 index 000000000..cbafa02da --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpp521r1arith_mont_slm.asm @@ -0,0 +1,1069 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; P521r1 basic arithmetic function +; +; Content: +; p521r1_add +; p521r1_sub +; p521r1_neg +; p521r1_div_by_2 +; p521r1_mul_mont_slm +; p521r1_sqr_mont_slm +; p521r1_mred +; p521r1_mont_back +; p521r1_select_ap_w7 +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +;; +;; some p256r1 constants +;; +p521r1_data: +_prime521r1 DD 0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh, 0FFFFFFFFh + DD 0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh, 0FFFFFFFFh + DD 0000001FFh + +%assign LEN521 ((521+32-1)/32) ; dword's length of operands + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Ipp32u add_521(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = carry = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM add_521,PRIVATE + ; r = a+b + mov eax, dword [esi] + add eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + adc eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + adc eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + adc eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + adc eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + adc eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + adc eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + adc eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, dword [esi+sizeof(dword)*8] + adc eax, dword [ebx+sizeof(dword)*8] + mov dword [edi+sizeof(dword)*8], eax + + mov eax, dword [esi+sizeof(dword)*9] + adc eax, dword [ebx+sizeof(dword)*9] + mov dword [edi+sizeof(dword)*9], eax + + mov eax, dword [esi+sizeof(dword)*10] + adc eax, dword [ebx+sizeof(dword)*10] + mov dword [edi+sizeof(dword)*10], eax + + mov eax, dword [esi+sizeof(dword)*11] + adc eax, dword [ebx+sizeof(dword)*11] + mov dword [edi+sizeof(dword)*11], eax + + mov eax, dword [esi+sizeof(dword)*12] + adc eax, dword [ebx+sizeof(dword)*12] + mov dword [edi+sizeof(dword)*12], eax + + mov eax, dword [esi+sizeof(dword)*13] + adc eax, dword [ebx+sizeof(dword)*13] + mov dword [edi+sizeof(dword)*13], eax + + mov eax, dword [esi+sizeof(dword)*14] + adc eax, dword [ebx+sizeof(dword)*14] + mov dword [edi+sizeof(dword)*14], eax + + mov eax, dword [esi+sizeof(dword)*15] + adc eax, dword [ebx+sizeof(dword)*15] + mov dword [edi+sizeof(dword)*15], eax + + mov eax, dword [esi+sizeof(dword)*16] + adc eax, dword [ebx+sizeof(dword)*16] + mov dword [edi+sizeof(dword)*16], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC add_521 + +;; +;; Ipp32u sub_521(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = borrow = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM sub_521,PRIVATE + ; r = a-b + mov eax, dword [esi] + sub eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + sbb eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + sbb eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + sbb eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + sbb eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + sbb eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + sbb eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + sbb eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, dword [esi+sizeof(dword)*8] + sbb eax, dword [ebx+sizeof(dword)*8] + mov dword [edi+sizeof(dword)*8], eax + + mov eax, dword [esi+sizeof(dword)*9] + sbb eax, dword [ebx+sizeof(dword)*9] + mov dword [edi+sizeof(dword)*9], eax + + mov eax, dword [esi+sizeof(dword)*10] + sbb eax, dword [ebx+sizeof(dword)*10] + mov dword [edi+sizeof(dword)*10], eax + + mov eax, dword [esi+sizeof(dword)*11] + sbb eax, dword [ebx+sizeof(dword)*11] + mov dword [edi+sizeof(dword)*11], eax + + mov eax, dword [esi+sizeof(dword)*12] + sbb eax, dword [ebx+sizeof(dword)*12] + mov dword [edi+sizeof(dword)*12], eax + + mov eax, dword [esi+sizeof(dword)*13] + sbb eax, dword [ebx+sizeof(dword)*13] + mov dword [edi+sizeof(dword)*13], eax + + mov eax, dword [esi+sizeof(dword)*14] + sbb eax, dword [ebx+sizeof(dword)*14] + mov dword [edi+sizeof(dword)*14], eax + + mov eax, dword [esi+sizeof(dword)*15] + sbb eax, dword [ebx+sizeof(dword)*15] + mov dword [edi+sizeof(dword)*15], eax + + mov eax, dword [esi+sizeof(dword)*16] + sbb eax, dword [ebx+sizeof(dword)*16] + mov dword [edi+sizeof(dword)*16], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC sub_521 + +;; +;; Ipp32u shl_521(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shl_521,PRIVATE + ; r = a<<1 + push ecx + mov ecx, LEN521-4 + + pxor xmm1, xmm1 +.shl_loop: + movdqu xmm0, oword [esi] + movdqa xmm2, xmm0 + add esi, sizeof(oword) + palignr xmm2, xmm1, sizeof(qword) + movdqa xmm1, xmm0 + + psllq xmm0, 1 + psrlq xmm2, 63 + por xmm0, xmm2 + movdqu oword [edi], xmm0 + add edi, sizeof(oword) + sub ecx, 4 + jg .shl_loop + + movd xmm0, dword [esi] + palignr xmm0, xmm1, sizeof(dword)*3 + psllq xmm0, 1 + psrldq xmm0, sizeof(dword) + movd dword [edi], xmm0 + + sub esi, sizeof(oword)*4 + sub edi, sizeof(oword)*4 + pop ecx + + xor eax, eax + ret +ENDFUNC shl_521 + +;; +;; void shr_521(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; eax = ext +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM shr_521,PRIVATE + ; r = a>>1 + mov eax, dword [esi+(LEN521-1)*sizeof(dword)] + + push ecx + mov ecx, LEN521-(4*2) +.shr_loop: + movdqu xmm0, oword [esi] + movdqu xmm1, oword [esi+sizeof(oword)] + palignr xmm1, xmm0, sizeof(qword) + add esi, sizeof(oword) + + psrlq xmm0, 1 + psllq xmm1, 63 + por xmm0, xmm1 + movdqu oword [edi], xmm0 + add edi, sizeof(oword) + + sub ecx, 4 + jg .shr_loop + pop ecx + + movdqu xmm0, oword [esi] + movd xmm1, eax + palignr xmm1, xmm0, sizeof(qword) + + psrlq xmm0, 1 + psllq xmm1, 63 + por xmm0, xmm1 + movdqu oword [edi], xmm0 + shr eax, 1 + mov dword [edi+sizeof(oword)], eax + + sub esi, sizeof(qword)*3 + sub esi, sizeof(qword)*3 + ret +ENDFUNC shr_521 +;; +;; void cpy_521(Ipp32u* r, const Ipp32u* a) +;; +%macro cpy_521 2.nolist + %xdefine %%pdst %1 + %xdefine %%psrc %2 + + movdqu xmm0, oword [%%psrc] + movdqu xmm1, oword [%%psrc+sizeof(oword)] + movdqu xmm2, oword [%%psrc+sizeof(oword)*2] + movdqu xmm3, oword [%%psrc+sizeof(oword)*3] + mov eax, dword [%%psrc+sizeof(oword)*4] + movdqu oword [%%pdst], xmm0 + movdqu oword [%%pdst+sizeof(oword)], xmm1 + movdqu oword [%%pdst+sizeof(oword)*2], xmm2 + movdqu oword [%%pdst+sizeof(oword)*3], xmm3 + mov dword [%%pdst+sizeof(oword)*4], eax +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_add(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_add,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN521] +%assign _sp_ _buf_+(LEN521)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM add_521 ; R = A+B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p521r1_data ; modulus + lea ebx, [ebx+(_prime521r1-p521r1_data)] + CALL_IPPASM sub_521 ; T = R-modulus + + lea esi,[esp+_buf_] + mov edi, pR + sub edx, eax ; R = T<0? R : T + cmovnz esi, edi + cpy_521 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p521r1_add + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_sub(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_sub,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN521] +%assign _sp_ _buf_+(LEN521)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM sub_521 ; R = A-B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p521r1_data ; modulus + lea ebx, [ebx+(_prime521r1-p521r1_data)] + CALL_IPPASM add_521 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_521 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p521r1_sub + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_neg(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_neg,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN521] +%assign _sp_ _buf_+(LEN521)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; outpur pR + mov esi, pA ; input pA + + ; r = 0-a + mov eax, 0 + sub eax, dword [esi] + mov dword [edi], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*8] + mov dword [edi+sizeof(dword)*8], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*9] + mov dword [edi+sizeof(dword)*9], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*10] + mov dword [edi+sizeof(dword)*10], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*11] + mov dword [edi+sizeof(dword)*11], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*12] + mov dword [edi+sizeof(dword)*12], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*13] + mov dword [edi+sizeof(dword)*13], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*14] + mov dword [edi+sizeof(dword)*14], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*15] + mov dword [edi+sizeof(dword)*15], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*16] + mov dword [edi+sizeof(dword)*16], eax + + sbb edx,edx + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, p521r1_data ; modulus + lea ebx, [ebx+(_prime521r1-p521r1_data)] + CALL_IPPASM add_521 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_521 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p521r1_neg + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_mul_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_mul_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN521] +%assign _sp_ _buf_+(LEN521)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; pA + CALL_IPPASM shl_521 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + mov edi, pR ; R + LD_ADDR ebx, p521r1_data ; modulus + lea ebx, [ebx+(_prime521r1-p521r1_data)] + CALL_IPPASM sub_521 ; R = T-modulus + + sub edx, eax ; R = R<0? T : R + cmovz esi, edi + cpy_521 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p521r1_mul_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_mul_by_3(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_mul_by_3,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _bufT_ 0 ; T buffer[LEN521] +%assign _bufU_ _bufT_+(LEN521)*sizeof(dword) ; U buffer[LEN521] +%assign _mod_ _bufU_+(LEN521)*sizeof(dword) ; modulus address [1] +%assign _sp_ _mod_+sizeof(dword) ; esp [1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + LD_ADDR eax, p521r1_data ; srore modulus address + lea eax, [eax+(_prime521r1-p521r1_data)] + mov dword [esp+_mod_], eax + + lea edi, [esp+_bufT_] ; T + mov esi, pA ; A + CALL_IPPASM shl_521 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + lea edi, [esp+_bufU_] ; U + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_521 ; U = T-modulus + + sub edx, eax ; T = U<0? T : U + cmovz esi, edi + cpy_521 edi, esi + + mov esi, edi + mov ebx, pA + CALL_IPPASM add_521 ; T +=A + mov edx, eax + + mov edi, pR ; R + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM sub_521 ; R = T-modulus + + sub edx, eax ; R = T<0? R : T + cmovz esi, edi + cpy_521 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p521r1_mul_by_3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_div_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_div_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LEN521] +%assign _sp_ _buf_+(LEN521)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_ +sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; A + LD_ADDR ebx, p521r1_data ; modulus + lea ebx, [ebx+(_prime521r1-p521r1_data)] + CALL_IPPASM add_521 ; R = A+modulus + mov edx, 0 + + mov ecx, dword [esi] ; shifted_data = (a[0]&1)? T : A + and ecx, 1 + cmovnz esi, edi + cmovz eax, edx + mov edi, pR + CALL_IPPASM shr_521 + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC p521r1_div_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_mul_mont_slm(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_mul_mont_slm,PUBLIC + USES_GPR ebp,ebx,esi,edi + +%xdefine pR [eax + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [eax + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [eax + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 +%assign _rp_ _buf_+(LEN521+1)*sizeof(dword) ; pR +%assign _ap_ _rp_ +sizeof(dword) ; pA +%assign _bp_ _ap_ +sizeof(dword) ; pB +%assign _sp_ _bp_ +sizeof(dword) ; esp storage +%assign _ssize_ _sp_ +sizeof(dword) ; size allocated stack + + mov eax, esp ; save esp + sub esp, _ssize_ ; allocate stack + and esp, -16 ; provide 16-byte stack alignment + mov dword [esp+_sp_], eax ; store original esp + + ; clear buffer + pxor xmm0, xmm0 + movdqa oword [esp+_buf_], xmm0 + movdqa oword [esp+_buf_+sizeof(oword)], xmm0 + movdqa oword [esp+_buf_+sizeof(oword)*2], xmm0 + movdqa oword [esp+_buf_+sizeof(oword)*3], xmm0 + movq qword [esp+_buf_+sizeof(oword)*4], xmm0 + + ; store parameters into the stack + ; note: eax here stores an original esp, so it can be used to reach function parameters + mov edi, pR + mov esi, pA + mov ebp, pB + mov dword [esp+_rp_], edi + mov dword [esp+_ap_], esi + mov dword [esp+_bp_], ebp + + mov ebx, LEN521 + + movd mm1, dword [esi+sizeof(dword)] ; pre load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + +align IPP_ALIGN_FACTOR +.mmul_loop: +; +; i-st pass +; modulus = 2^521 -1 +; [17] [0] +; m0 = 1 +; + movd mm7, ebx ; save pass counter + + mov edx, dword [ebp] ; b = b[i] + mov eax, dword [esi] ; a[0] + movd mm0, edx + add ebp, sizeof(dword) + mov dword [esp+_bp_], ebp + + pmuludq mm1, mm0 ; a[1]*b[i] + pmuludq mm2, mm0 ; a[2]*b[i] + + mul edx ; (E:u) = (edx:eax) = a[0]*b[i]+buf[0] + add eax, dword [esp+_buf_] + adc edx, 0 + + pmuludq mm3, mm0 ; a[3]*b[i] + pmuludq mm4, mm0 ; a[4]*b[i] + +; multiplication round 1 - round 4 + movd ecx, mm1 ; p = a[1]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*1] + movd mm1, dword [esi+sizeof(dword)*5] + mov dword [esp+_buf_+sizeof(dword)*0], ecx + adc edx, 0 + + movd ebx, mm2 ; p = a[2]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*2] + movd mm2, dword [esi+sizeof(dword)*6] + mov dword [esp+_buf_+sizeof(dword)*1], ebx + adc edx, 0 + + pmuludq mm1, mm0 ; a[5]*b[i] + pmuludq mm2, mm0 ; a[6]*b[i] + + movd ebp, mm3 ; p = a[3]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*3] + movd mm3, dword [esi+sizeof(dword)*7] + mov dword [esp+_buf_+sizeof(dword)*2], ebp + adc edx, 0 + + movd edi, mm4 ; p = a[4]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*4] + movd mm4, dword [esi+sizeof(dword)*8] + mov dword [esp+_buf_+sizeof(dword)*3], edi + adc edx, 0 + + pmuludq mm3, mm0 ; a[7]*b[i] + pmuludq mm4, mm0 ; a[8]*b[i] + +; multiplication round 5 - round 8 + movd ecx, mm1 ; p = a[5]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*5] + movd mm1, dword [esi+sizeof(dword)*9] + mov dword [esp+_buf_+sizeof(dword)*4], ecx + adc edx, 0 + + movd ebx, mm2 ; p = a[6]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*6] + movd mm2, dword [esi+sizeof(dword)*10] + mov dword [esp+_buf_+sizeof(dword)*5], ebx + adc edx, 0 + + pmuludq mm1, mm0 ; a[9]*b[i] + pmuludq mm2, mm0 ; a[10]*b[i] + + movd ebp, mm3 ; p = a[7]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*7] + movd mm3, dword [esi+sizeof(dword)*11] + mov dword [esp+_buf_+sizeof(dword)*6], ebp + adc edx, 0 + + movd edi, mm4 ; p = a[8]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*8] + movd mm4, dword [esi+sizeof(dword)*12] + mov dword [esp+_buf_+sizeof(dword)*7], edi + adc edx, 0 + + pmuludq mm3, mm0 ; a[11]*b[i] + pmuludq mm4, mm0 ; a[12]*b[i] + +; multiplication round 9 - round 12 + movd ecx, mm1 ; p = a[9]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*9] + movd mm1, dword [esi+sizeof(dword)*13] + mov dword [esp+_buf_+sizeof(dword)*8], ecx + adc edx, 0 + + movd ebx, mm2 ; p = a[10]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*10] + movd mm2, dword [esi+sizeof(dword)*14] + mov dword [esp+_buf_+sizeof(dword)*9], ebx + adc edx, 0 + + pmuludq mm1, mm0 ; a[13]*b[i] + pmuludq mm2, mm0 ; a[14]*b[i] + + movd ebp, mm3 ; p = a[11]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*11] + movd mm3, dword [esi+sizeof(dword)*15] + mov dword [esp+_buf_+sizeof(dword)*10], ebp + adc edx, 0 + + movd edi, mm4 ; p = a[12]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*12] + movd mm4, dword [esi+sizeof(dword)*16] + mov dword [esp+_buf_+sizeof(dword)*11], edi + adc edx, 0 + + pmuludq mm3, mm0 ; a[15]*b[i] + pmuludq mm4, mm0 ; a[16]*b[i] + +; multiplication round 13 - round 16 + movd ecx, mm1 ; p = a[13]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*13] + mov dword [esp+_buf_+sizeof(dword)*12], ecx + adc edx, 0 + + movd ebx, mm2 ; p = a[14]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*14] + mov dword [esp+_buf_+sizeof(dword)*13], ebx + adc edx, 0 + + movd ebp, mm3 ; p = a[15]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*15] + mov dword [esp+_buf_+sizeof(dword)*14], ebp + adc edx, 0 + + movd edi, mm4 ; p = a[16]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*16] + adc edx, 0 + +;;; and reduction and last multiplication round 17 + movd ebx, mm7 ; restore pass counter + + mov ecx, eax ; u0 <<= 9 + shl eax, (521-512) + shr ecx, (32-(521-512)) + + add edi, eax + mov dword [esp+_buf_+sizeof(dword)*15], edi + adc edx, ecx + mov dword [esp+_buf_+sizeof(dword)*16], edx + + sub ebx, 1 + movd mm1, dword [esi+sizeof(dword)] ; speculative load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + jz .exit_mmul_loop + + mov ebp, dword [esp+_bp_] ; restore pB + jmp .mmul_loop + +.exit_mmul_loop: + emms + +; final reduction + mov edi, [esp+_rp_] ; result + lea esi, [esp+_buf_] ; buffer + LD_ADDR ebx, p521r1_data ; modulus + lea ebx, [ebx+(_prime521r1-p521r1_data)] + CALL_IPPASM sub_521 + mov edx, dword [esp+_buf_+LEN521*sizeof(dword)] + +; copy + cmovz esi, edi + cpy_521 edi, esi + + mov esp, [esp+_sp_] ; release stack + REST_GPR + ret +ENDFUNC p521r1_mul_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_sqr_mont_slm(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_sqr_mont_slm,PUBLIC + USES_GPR esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source A address + + ;; use p521r1_mul_mont_slm to compute sqr + mov esi, pA + mov edi, pR + push esi + push esi + push edi + CALL_IPPASM p521r1_mul_mont_slm,PUBLIC + add esp, sizeof(dword)*3 + REST_GPR + ret +ENDFUNC p521r1_sqr_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void p521r1_mred(Ipp32u* r, Ipp32u* prod) +;; +; modulus = 2^521 -1 +; [17] [0] +; m0 = 1 +; +align IPP_ALIGN_FACTOR +IPPASM p521r1_mred,PUBLIC + USES_GPR ebx,esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; reduction address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source product address + + ; get parameters: + mov esi, pA + + mov ecx, LEN521 + xor edx, edx +align IPP_ALIGN_FACTOR +.mred_loop: + mov ebx, dword [esi] ; [ebx:eax] = u0<<9 + mov eax, dword [esi] + shr ebx,(32-(521-512)) + shl eax,(521-512) + add ebx, edx + + ;; [esi+i*sizeof(dword)] = [esi+i*sizeof(dword)], i=1,..,16 + + add eax, dword [esi+sizeof(dword)*16] + mov edx, dword [esi+sizeof(dword)*17] + adc ebx, edx + mov edx, 0 + + mov dword [esi+sizeof(dword)*16], eax + mov dword [esi+sizeof(dword)*17], ebx + adc edx, 0 + + lea esi, [esi+sizeof(dword)] + sub ecx, 1 + jnz .mred_loop + + ; final reduction + mov edi, pR ; result + LD_ADDR ebx, p521r1_data ; addres of the modulus + lea ebx, [ebx+(_prime521r1-p521r1_data)] + CALL_IPPASM sub_521 + + sub edx, eax + cmovz esi, edi + cpy_521 edi, esi + + REST_GPR + ret +ENDFUNC p521r1_mred + +%endif ;; _IPP >= _IPP_P8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcppurgeblkw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcppurgeblkw7as.asm new file mode 100644 index 000000000..be2737164 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcppurgeblkw7as.asm @@ -0,0 +1,80 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Purge block +; +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_W7) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: Clear memory block +;* +;* void PurgeBlock(Ipp8u *pDst, int len) +;* +;*************************************************************** + +;; +;; Lib = W7 +;; +align IPP_ALIGN_FACTOR +IPPASM PurgeBlock,PUBLIC + USES_GPR edi + +%xdefine pDst [esp + ARG_1 + 0*sizeof(dword)] ; target address +%xdefine len [esp + ARG_1 + 1*sizeof(dword)] ; length + + mov edi, pDst ; mem address + mov ecx, len ; length + xor eax, eax + sub ecx, sizeof(dword) + jl .test_purge +.purge4: + mov dword [edi], eax ; clear + add edi, sizeof(dword) + sub ecx, sizeof(dword) + jge .purge4 + +.test_purge: + add ecx, sizeof(dword) + jz .quit +.purge1: + mov byte [edi], al + add edi, sizeof(byte) + sub ecx, sizeof(byte) + jg .purge1 + +.quit: + REST_GPR + ret +ENDFUNC PurgeBlock + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprc4v8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprc4v8as.asm new file mode 100644 index 000000000..666b08b65 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprc4v8as.asm @@ -0,0 +1,123 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; ARCFour +; +; Content: +; ARCFourKernel() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_V8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: RC4 kernel +;* +;* void ARCFourProcessData(const Ipp8u *pSrc, Ipp8u *pDst, int len, +;* IppsARCFourState* pCtx) +;* +;*************************************************************** + +;; +;; Lib = V8 +;; +;; Caller = ippsARCFourEncrypt +;; Caller = ippsARCFourDecrypt +;; +align IPP_ALIGN_FACTOR +IPPASM ARCFourProcessData,PUBLIC + USES_GPR esi,edi,ebx,ebp + +%xdefine pSrc [esp + ARG_1 + 0*sizeof(dword)] +%xdefine pDst [esp + ARG_1 + 1*sizeof(dword)] +%xdefine len [esp + ARG_1 + 2*sizeof(dword)] +%xdefine pCtx [esp + ARG_1 + 3*sizeof(dword)] + + mov edx, len ; data length + mov esi, pSrc ; source data + mov edi, pDst ; target data + mov ebp, pCtx ; context + + test edx, edx ; test length + jz .quit + + mov eax, dword [ebp+4] ; extract x + mov ebx, dword [ebp+8] ; extract y + + lea ebp, [ebp+12] ; sbox + + add eax,1 ; x = (x+1)&0xFF + and eax, 0FFh + mov ecx, dword [ebp+eax*4] ; tx = S[x] + + lea edx, [esi+edx] ; store stop data address + push edx + +;; +;; main code +;; +align IPP_ALIGN_FACTOR +.main_loop: + add ebx, ecx ; y = (x+tx)&0xFF + movzx ebx, bl + mov edx, dword [ebp+ebx*4] ; ty = S[y] + + mov dword [ebp+ebx*4],ecx ; S[y] = tx + add ecx, edx ; tmp_idx = (tx+ty)&0xFF + movzx ecx, cl + mov dword [ebp+eax*4],edx ; S[x] = ty + + add eax, 1 ; next x = (x+1)&0xFF + mov dl, byte [ebp+ecx*4] ; byte of gamma + + movzx eax, al + + xor dl,byte [esi] ; gamma ^= src + add esi, 1 + mov ecx, dword [ebp+eax*4] ; next tx = S[x] + mov byte [edi],dl ; store result + add edi, 1 + cmp esi, dword [esp] + jb .main_loop + + lea ebp, [ebp-12] ; pointer to context + pop edx ; remove local variable + + dec eax ; actual new x counter + and eax, 0FFh + mov dword [ebp+4], eax ; update x conter + mov dword [ebp+8], ebx ; updtae y counter + +.quit: + REST_GPR + ret +ENDFUNC ARCFourProcessData + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprc4w7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprc4w7as.asm new file mode 100644 index 000000000..71ac114ad --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprc4w7as.asm @@ -0,0 +1,118 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; ARCFour +; +; Content: +; ARCFourKernel() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_M5) && (_IPP < _IPP_V8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: RC4 kernel +;* +;* void ARCFourProcessData(const Ipp8u *pSrc, Ipp8u *pDst, int len, +;* IppsARCFourState* pCtx) +;* +;*************************************************************** + +;; +;; Lib = W7 +;; +;; Caller = ippsARCFourEncrypt +;; Caller = ippsARCFourDecrypt +;; +IPPASM ARCFourProcessData,PUBLIC + USES_GPR esi,edi,ebx,ebp + +%xdefine pSrc [esp + ARG_1 + 0*sizeof(dword)] +%xdefine pDst [esp + ARG_1 + 1*sizeof(dword)] +%xdefine len [esp + ARG_1 + 2*sizeof(dword)] +%xdefine pCtx [esp + ARG_1 + 3*sizeof(dword)] + + mov edx, len ; data length + mov esi, pSrc ; source data + mov edi, pDst ; target data + mov ebp, pCtx ; context + + test edx, edx ; test length + jz .quit + + xor eax, eax + movzx eax, byte [ebp+4] ; extract x + xor ebx, ebx + movzx ebx, byte [ebp+8] ; extract y + + lea ebp, [ebp+12] ; sbox + + inc al ; x = (x+1)&0xFF + movzx ecx, byte [ebp+eax] ; tx = S[x] + + lea edx, [esi+edx] ; store stop data address + push edx + +;; +;; main code +;; +align IPP_ALIGN_FACTOR +.main_loop: + add bl,cl ; y = (x+tx)&0xFF + movzx edx,byte [ebx+ebp] ; ty = S[y] + + mov byte [ebx+ebp],cl ; S[y] = tx + mov byte [eax+ebp],dl ; S[x] = ty + add dl, cl ; tmp_idx = (tx+ty)&0xFF + + movzx edx,byte [edx+ebp] ; byte of gamma + + add al,1 ; next x = (x+1)&0xFF + xor dl,byte [esi] ; gamma ^= src + lea esi,[esi+1] + movzx ecx,byte [eax+ebp] ; next tx = S[x] + cmp esi, dword [esp] + mov byte [edi],dl ; store result + lea edi,[edi+1] + jb .main_loop + + lea ebp, [ebp-12] ; pointer to context + pop edx ; remove local variable + + dec eax ; actual new x counter + mov byte [ebp+4], al ; update x conter + mov byte [ebp+8], bl ; updtae y counter + +.quit: + REST_GPR + ret +ENDFUNC ARCFourProcessData + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128ccmg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128ccmg9as.asm new file mode 100644 index 000000000..c788dab32 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128ccmg9as.asm @@ -0,0 +1,298 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; AuthEncrypt_RIJ128_AES_NI() +; DecryptAuth_RIJ128_AES_NI() +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +ENCODE_DATA: +u128_str DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +increment DQ 1,0 + +;*************************************************************** +;* Purpose: Authenticate and Encrypt +;* +;* void AuthEncrypt_RIJ128_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp32u len, +;* Ipp8u* pLocalState) +;* inp localCtx: +;* MAC +;* CTRi +;* CTRi mask +;* +;* out localCtx: +;* new MAC +;* S = enc(CTRi) +;*************************************************************** + +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128CCMEncrypt +;; Caller = ippsRijndael128CCMEncryptMessage +;; +align IPP_ALIGN_FACTOR +IPPASM AuthEncrypt_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input blocks address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output blocks address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [esp + ARG_1 + 4*sizeof(dword)] ; length (bytes) +%xdefine pLocCtx [esp + ARG_1 + 5*sizeof(dword)] ; pointer to the localState + +%assign BYTES_PER_BLK (16) + + mov eax, pLocCtx + movdqa xmm0, oword [eax] ; MAC + movdqa xmm2, oword [eax+sizeof(oword)] ; CTRi block + movdqa xmm1, oword [eax+sizeof(oword)*2] ; CTR mask + + LD_ADDR eax, ENCODE_DATA + + movdqa xmm7, oword [eax+(u128_str-ENCODE_DATA)] + + pshufb xmm2, xmm7 ; CTRi block (LE) + pshufb xmm1, xmm7 ; CTR mask + + movdqa xmm3, xmm1 + pandn xmm3, xmm2 ; CTR block template + pand xmm2, xmm1 ; CTR value + + mov edx, nr ; number of rounds + mov ecx, pKey ; and keys + + lea edx, [edx*4] ; nrCounter = -nr*16 + lea edx, [edx*4] ; pKey += nr*16 + lea ecx, [ecx+edx] + neg edx + mov ebx, edx + + mov esi, pInpBlk + mov edi, pOutBlk + +align IPP_ALIGN_FACTOR +;; +;; block-by-block processing +;; +.blk_loop: + movdqu xmm4, oword [esi] ; input block src[i] + pxor xmm0, xmm4 ; MAC ^= src[i] + + movdqa xmm5, xmm3 + paddq xmm2, oword [eax+(increment-ENCODE_DATA)] ; advance counter bits + pand xmm2, xmm1 ; and mask them + por xmm5, xmm2 + pshufb xmm5, xmm7 ; CTRi (BE) + + movdqa xmm6, oword [ecx+edx] ; keys for whitening + add edx, 16 + + pxor xmm5, xmm6 ; whitening (CTRi) + pxor xmm0, xmm6 ; whitening (MAC) + + movdqa xmm6, oword [ecx+edx] ; pre load operation's keys + +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm5, xmm6 ; regular round (CTRi) + aesenc xmm0, xmm6 ; regular round (MAC) + movdqa xmm6, oword [ecx+edx+16] + add edx, 16 + jnz .cipher_loop + aesenclast xmm5, xmm6 ; irregular round (CTRi) + aesenclast xmm0, xmm6 ; irregular round (MAC) + + pxor xmm4, xmm5 ; dst[i] = src[i] ^ ENC(CTRi) + movdqu oword [edi], xmm4 + + mov edx, ebx + add esi, BYTES_PER_BLK + add edi, BYTES_PER_BLK + sub dword len, BYTES_PER_BLK + jnz .blk_loop + + mov eax, pLocCtx + movdqu oword [eax], xmm0 ; update MAC value + movdqu oword [eax+sizeof(oword)], xmm5 ; update ENC(Ctri) + + REST_GPR + ret +ENDFUNC AuthEncrypt_RIJ128_AES_NI + + +;*************************************************************** +;* Purpose: Decrypt and Authenticate +;* +;* void DecryptAuth_RIJ128_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp32u len, +;* Ipp8u* pLocalState) +;* inp localCtx: +;* MAC +;* CTRi +;* CTRi mask +;* +;* out localCtx: +;* new MAC +;* S = enc(CTRi) +;*************************************************************** + +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128CCMDecrypt +;; Caller = ippsRijndael128CCMDecryptMessage +;; +align IPP_ALIGN_FACTOR +IPPASM DecryptAuth_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input blocks address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output blocks address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [esp + ARG_1 + 4*sizeof(dword)] ; length (bytes) +%xdefine pLocCtx [esp + ARG_1 + 5*sizeof(dword)] ; pointer to the localState + +%assign BYTES_PER_BLK (16) + + mov eax, pLocCtx + movdqa xmm0, oword [eax] ; MAC + movdqa xmm2, oword [eax+sizeof(oword)] ; CTRi block + movdqa xmm1, oword [eax+sizeof(oword)*2] ; CTR mask + + LD_ADDR eax, ENCODE_DATA + + movdqa xmm7, oword [eax+(u128_str-ENCODE_DATA)] + + pshufb xmm2, xmm7 ; CTRi block (LE) + pshufb xmm1, xmm7 ; CTR mask + + movdqa xmm3, xmm1 + pandn xmm3, xmm2 ; CTR block template + pand xmm2, xmm1 ; CTR value + + mov edx, nr ; number of rounds + mov ecx, pKey ; and keys + + lea edx, [edx*4] ; nrCounter = -nr*16 + lea edx, [edx*4] ; pKey += nr*16 + lea ecx, [ecx+edx] + neg edx + mov ebx, edx + + mov esi, pInpBlk + mov edi, pOutBlk + +align IPP_ALIGN_FACTOR +;; +;; block-by-block processing +;; +.blk_loop: + + ;;;;;;;;;;;;;;;;; + ;; decryption + ;;;;;;;;;;;;;;;;; + movdqu xmm4, oword [esi] ; input block src[i] + + movdqa xmm5, xmm3 + paddq xmm2, oword [eax+(increment-ENCODE_DATA)] ; advance counter bits + pand xmm2, xmm1 ; and mask them + por xmm5, xmm2 + pshufb xmm5, xmm7 ; CTRi (BE) + + movdqa xmm6, oword [ecx+edx] ; keys for whitening + add edx, 16 + + pxor xmm5, xmm6 ; whitening (CTRi) + movdqa xmm6, oword [ecx+edx] ; pre load operation's keys + +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm5, xmm6 ; regular round (CTRi) + movdqa xmm6, oword [ecx+edx+16] + add edx, 16 + jnz .cipher_loop + aesenclast xmm5, xmm6 ; irregular round (CTRi) + + pxor xmm4, xmm5 ; dst[i] = src[i] ^ ENC(CTRi) + movdqu oword [edi], xmm4 + + ;;;;;;;;;;;;;;;;; + ;; update MAC + ;;;;;;;;;;;;;;;;; + mov edx, ebx + + movdqa xmm6, oword [ecx+edx] ; keys for whitening + add edx, 16 + + pxor xmm0, xmm4 ; MAC ^= dst[i] + pxor xmm0, xmm6 ; whitening (MAC) + + movdqa xmm6, oword [ecx+edx] ; pre load operation's keys + +align IPP_ALIGN_FACTOR +.auth_loop: + aesenc xmm0, xmm6 ; regular round (MAC) + movdqa xmm6, oword [ecx+edx+16] + add edx, 16 + jnz .auth_loop + aesenclast xmm0, xmm6 ; irregular round (MAC) + + + mov edx, ebx + add esi, BYTES_PER_BLK + add edi, BYTES_PER_BLK + sub dword len, BYTES_PER_BLK + jnz .blk_loop + + mov eax, pLocCtx + movdqu oword [eax], xmm0 ; update MAC value + movdqu oword [eax+sizeof(oword)], xmm6 ; update ENC(Ctri) + + REST_GPR + ret +ENDFUNC DecryptAuth_RIJ128_AES_NI + +%endif + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128cmacg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128cmacg9as.asm new file mode 100644 index 000000000..f9cdfc8c2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128cmacg9as.asm @@ -0,0 +1,117 @@ +;=============================================================================== +; Copyright (C) 2018 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; cpAESCMAC_Update_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + +;*************************************************************** +;* Purpose: AES-CMAC update +;* +;* void cpAESCMAC_Update_AES_NI(Ipp8u* digest, +;* const Ipp8u* input, +;* int inpLen, +;* int nr, +;* const Ipp32u* pRKey) +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsAES_CMACUpdate +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM cpAESCMAC_Update_AES_NI,PUBLIC + USES_GPR esi,edi + +%xdefine pDigest [esp + ARG_1 + 0*sizeof(dword)] ; input/output digest +%xdefine pInpBlk [esp + ARG_1 + 1*sizeof(dword)] ; input blocks +%xdefine len [esp + ARG_1 + 2*sizeof(dword)] ; length (bytes) +%xdefine nr [esp + ARG_1 + 3*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 4*sizeof(dword)] ; key material address + +%xdefine SC (4) +%assign BYTES_PER_BLK (16) + + mov edi, pDigest ; pointer to digest + mov esi,pInpBlk ; input data address + mov ecx,pKey ; key material address + mov eax,nr ; number of rounds + + movdqu xmm0, oword [edi] ; digest + + mov edx, len ; length of stream + +align IPP_ALIGN_FACTOR +;; +;; block-by-block processing +;; +.blks_loop: + movdqu xmm1, oword [esi] ; input block + + movdqa xmm4, oword [ecx] ; preload key material + + pxor xmm0, xmm1 ; digest ^ src[] + + pxor xmm0, xmm4 ; whitening + + movdqa xmm4, oword [ecx+16] ; preload key material + add ecx, 16 + + sub eax, 1 ; counter depending on key length +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + movdqa xmm4, oword [ecx+16] + add ecx, 16 + sub eax, 1 + jnz .cipher_loop + aesenclast xmm0, xmm4 ; irregular round + + mov ecx, pKey ; restore key pointer + mov eax, nr ; resrore number of rounds + + add esi, BYTES_PER_BLK ; advance pointers + sub edx, BYTES_PER_BLK ; decrease counter + jnz .blks_loop + + pxor xmm4, xmm4 + movdqu oword [edi], xmm0 ; store output block + + REST_GPR + ret +ENDFUNC cpAESCMAC_Update_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptcbcpipeg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptcbcpipeg9as.asm new file mode 100644 index 000000000..cbf5b8038 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptcbcpipeg9as.asm @@ -0,0 +1,208 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; DecryptCBC_RIJ128pipe_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + +;*************************************************************** +;* Purpose: pipelined RIJ128 CBC decryption +;* +;* void DecryptCBC_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len, +;* const Ipp8u* pIV) +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = G9 +;; +;; Caller = ippsRijndael128DecryptCBC +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM DecryptCBC_RIJ128pipe_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [ebp + ARG_1 + 4*sizeof(dword)] ; length(byte) +%xdefine pIV [ebp + ARG_1 + 5*sizeof(dword)] ; IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + mov ecx,pKey ; key material address + mov eax,nr ; number of rounds + + sub esp, 16*(1+4+1) ; allocate stack + lea edx, [esp+16] + and edx, -16 + + mov ebx, pIV + movdqu xmm4, oword [ebx] ; save IV + movdqa oword [edx+0*16], xmm4 ; into the stack + + sub dword len, BYTES_PER_LOOP + jl .short_input + + lea ebx,[eax*SC] ; keys offset + lea ecx,[ecx+ebx*4] +;; +;; pipelined processing +;; +.blks_loop: + movdqa xmm4, oword [ecx] ; keys for whitening + lea ebx, [ecx-16] ; set pointer to the round's key material + + movdqu xmm0, oword [esi+0*BYTES_PER_BLK] ; get input blocks + movdqu xmm1, oword [esi+1*BYTES_PER_BLK] + movdqu xmm2, oword [esi+2*BYTES_PER_BLK] + movdqu xmm3, oword [esi+3*BYTES_PER_BLK] + movdqa oword [edx+1*16], xmm0 ; and save as IVx + movdqa oword [edx+2*16], xmm1 ; for next operations + movdqa oword [edx+3*16], xmm2 ; into the stack + movdqa oword [edx+4*16], xmm3 + + pxor xmm0, xmm4 ;whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [ebx] ; pre load operation's keys + sub ebx, 16 + + mov eax, nr ; counter depending on key length + sub eax, 1 +.cipher_loop: + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + movdqa xmm4, oword [ebx] ; pre load operation's keys + sub ebx, 16 + dec eax + jnz .cipher_loop + + aesdeclast xmm0, xmm4 ; irregular round and IV + pxor xmm0, oword [edx+0*16] ; xor with IV + movdqu oword [edi+0*16], xmm0 ; and store output blocls + + aesdeclast xmm1, xmm4 + pxor xmm1, oword [edx+1*16] + movdqu oword [edi+1*16], xmm1 + + aesdeclast xmm2, xmm4 + pxor xmm2, oword [edx+2*16] + movdqu oword [edi+2*16], xmm2 + + aesdeclast xmm3, xmm4 + pxor xmm3, oword [edx+3*16] + movdqu oword [edi+3*16], xmm3 + + movdqa xmm4, oword [edx+4*16] ; update IV + movdqa oword [edx+0*16], xmm4 + + add esi, BYTES_PER_LOOP + add edi, BYTES_PER_LOOP + sub dword len, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add dword len, BYTES_PER_LOOP + jz .quit + + mov eax, nr + mov ecx, pKey + lea ebx,[eax*SC] ; set pointer to the key material + lea ebx,[ecx+ebx*4] + +.single_blk_loop: + movdqu xmm0, oword [esi] ; get input block + movdqa oword [edx+16], xmm0 ; and save as IV for future + pxor xmm0, oword [ebx] ; whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesdec xmm0, oword [ecx+9*SC*4+4*SC*4] + aesdec xmm0, oword [ecx+9*SC*4+3*SC*4] +.key_192_s: + aesdec xmm0, oword [ecx+9*SC*4+2*SC*4] + aesdec xmm0, oword [ecx+9*SC*4+1*SC*4] +.key_128_s: + aesdec xmm0, oword [ecx+9*SC*4-0*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-1*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-2*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-3*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-4*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-5*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-6*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-7*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-8*SC*4] + aesdeclast xmm0, oword [ecx+9*SC*4-9*SC*4] + + pxor xmm0, oword [edx+0*16] ; add IV + movdqu oword [edi], xmm0 ; and save output blocl + + movdqa xmm4, oword [edx+1*16] ; update IV + movdqa oword [edx+0*16], xmm4 + + add esi, BYTES_PER_BLK + add edi, BYTES_PER_BLK + sub dword len, BYTES_PER_BLK + jnz .single_blk_loop + +.quit: + add esp, 16*(1+4+1) ; free stack + REST_GPR + ret +ENDFUNC DecryptCBC_RIJ128pipe_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptcfbpipeg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptcfbpipeg9as.asm new file mode 100644 index 000000000..f7f1110e9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptcfbpipeg9as.asm @@ -0,0 +1,581 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Decrypt_RIJ128_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + +%macro COPY_8U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor ecx, ecx +%%next_byte: + mov %%tmp, byte [%%src+ecx] + mov byte [%%dst+ecx], %%tmp + add ecx, 1 + cmp ecx, %%limit + jl %%next_byte +%endmacro + + +%macro COPY_32U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor ecx, ecx +%%next_dword: + mov %%tmp, dword [%%src+ecx] + mov dword [%%dst+ecx], %%tmp + add ecx, 4 + cmp ecx, %%limit + jl %%next_dword +%endmacro + + +%macro COPY_128U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor ecx, ecx +%%next_oword: + movdqu %%tmp, oword [%%src+ecx] + movdqu oword [%%dst+ecx], %%tmp + add ecx, 16 + cmp ecx, %%limit + jl %%next_oword +%endmacro + + +;*************************************************************** +;* Purpose: pipelined RIJ128 CFB decryption +;* +;* void DecryptCFB_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int cfbBlks, +;* int cfbSize, +;* const Ipp8u* pIV) +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128DecryptCFB +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM DecryptCFB_RIJ128pipe_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine cfbBlks [ebp + ARG_1 + 4*sizeof(dword)] ; length of stream in cfbSize +%xdefine cfbSize [ebp + ARG_1 + 5*sizeof(dword)] ; cfb blk size +%xdefine pIV [ebp + ARG_1 + 6*sizeof(dword)] ; IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + sub esp,16*(1+4+4) ; allocate stask: + ; +0*16 IV + ; +1*16 inp0, inp1, inp2, inp3 + ; +5*16 out0, out1, out2, out3 + + mov eax, pIV ; IV address + movdqu xmm4, oword [eax] ; get IV + movdqu oword [esp+0*16], xmm4 ; into the stack + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + mov edx,cfbSize ; size of block + + sub dword cfbBlks, BLKS_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +.blks_loop: + lea eax, [edx*BLKS_PER_LOOP] + COPY_32U {esp+16}, esi, eax, ebx ; move 4 input blocks to stack + + mov ecx, pKey + movdqa xmm4, oword [ecx] ; keys for whitening + + lea ebx, [edx+edx*2] + movdqu xmm0, oword [esp] ; get encoded blocks + movdqu xmm1, oword [esp+edx] + movdqu xmm2, oword [esp+edx*2] + movdqu xmm3, oword [esp+ebx] + + lea ebx, [ecx+16] ; pointer to the round's key material + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [ebx] ; pre load operation's keys + add ebx, 16 + + mov eax, nr ; counter depending on key length + sub eax, 1 +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [ebx] ; pre load operation's keys + add ebx, 16 + dec eax + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round and IV + aesenclast xmm1, xmm4 + aesenclast xmm2, xmm4 + aesenclast xmm3, xmm4 + + lea ebx, [edx+edx*2] ; get src blocks from the stack + movdqu xmm4, oword [esp+16] + movdqu xmm5, oword [esp+16+edx] + movdqu xmm6, oword [esp+16+edx*2] + movdqu xmm7, oword [esp+16+ebx] + + pxor xmm0, xmm4 ; xor src + movdqu oword [esp+5*16],xmm0;and store into the stack + pxor xmm1, xmm5 + movdqu oword [esp+5*16+edx], xmm1 + pxor xmm2, xmm6 + movdqu oword [esp+5*16+edx*2], xmm2 + pxor xmm3, xmm7 + movdqu oword [esp+5*16+ebx], xmm3 + + lea eax, [edx*BLKS_PER_LOOP] + COPY_32U edi, {esp+5*16}, eax, ebx ; move 4 blocks to output + + movdqu xmm0, oword [esp+eax] ; update IV + movdqu oword [esp], xmm0 + + + add esi, eax + add edi, eax + sub dword cfbBlks, BLKS_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add dword cfbBlks, BLKS_PER_LOOP + jz .quit + + lea ebx, [edx*2] + lea ecx, [edx+edx*2] + cmp dword cfbBlks, 2 + cmovl ebx, edx + cmovg ebx, ecx + COPY_8U {esp+16}, esi, ebx, al ; move recent input blocks to stack + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov ecx, pKey + mov eax, nr + lea esi,[eax*4] + lea esi, [ecx+esi*4-9*(SC)*4] ; AES-128 round keys + + xor eax, eax ; index +.single_blk_loop: + movdqu xmm0, oword [esp+eax] ; get encoded block + + pxor xmm0, oword [ecx] ; whitening + + cmp dword nr, 12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0, oword [esi-4*4*SC] + aesenc xmm0, oword [esi-3*4*SC] +.key_192_s: + aesenc xmm0, oword [esi-2*4*SC] + aesenc xmm0, oword [esi-1*4*SC] +.key_128_s: + aesenc xmm0, oword [esi+0*4*SC] + aesenc xmm0, oword [esi+1*4*SC] + aesenc xmm0, oword [esi+2*4*SC] + aesenc xmm0, oword [esi+3*4*SC] + aesenc xmm0, oword [esi+4*4*SC] + aesenc xmm0, oword [esi+5*4*SC] + aesenc xmm0, oword [esi+6*4*SC] + aesenc xmm0, oword [esi+7*4*SC] + aesenc xmm0, oword [esi+8*4*SC] + aesenclast xmm0, oword [esi+9*4*SC] + + movdqu xmm1, oword [esp+eax+16] ; get input block from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [esp+5*16+eax], xmm0 ; and save output + + add eax, edx + dec dword cfbBlks + jnz .single_blk_loop + + COPY_8U edi, {esp+5*16}, ebx, al ; copy rest output from the stack + +.quit: + add esp, 16*(1+4+4) ; free stack + REST_GPR + ret +ENDFUNC DecryptCFB_RIJ128pipe_AES_NI + +align IPP_ALIGN_FACTOR +IPPASM DecryptCFB32_RIJ128pipe_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine cfbBlks [ebp + ARG_1 + 4*sizeof(dword)] ; length of stream in cfbSize +%xdefine cfbSize [ebp + ARG_1 + 5*sizeof(dword)] ; cfb blk size (4 bytes multible) +%xdefine pIV [ebp + ARG_1 + 6*sizeof(dword)] ; IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + sub esp,16*(1+4+4) ; allocate stask: + ; +0*16 IV + ; +1*16 inp0, inp1, inp2, inp3 + ; +5*16 out0, out1, out2, out3 + + mov eax, pIV ; IV address + movdqu xmm4, oword [eax] ; get IV + movdqu oword [esp+0*16], xmm4 ; into the stack + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + mov edx,cfbSize ; size of block + + sub dword cfbBlks, BLKS_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +.blks_loop: + lea eax, [edx*BLKS_PER_LOOP] + COPY_128U {esp+16}, esi, eax, xmm0 ; move 4 input blocks to stack + + mov ecx, pKey + movdqa xmm4, oword [ecx] ; keys for whitening + + lea ebx, [edx+edx*2] + movdqu xmm0, oword [esp] ; get encoded blocks + movdqu xmm1, oword [esp+edx] + movdqu xmm2, oword [esp+edx*2] + movdqu xmm3, oword [esp+ebx] + + lea ebx, [ecx+16] ; pointer to the round's key material + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [ebx] ; pre load operation's keys + add ebx, 16 + + mov eax, nr ; counter depending on key length + sub eax, 1 +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [ebx] ; pre load operation's keys + add ebx, 16 + dec eax + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round and IV + aesenclast xmm1, xmm4 + aesenclast xmm2, xmm4 + aesenclast xmm3, xmm4 + + lea ebx, [edx+edx*2] ; get src blocks from the stack + movdqu xmm4, oword [esp+16] + movdqu xmm5, oword [esp+16+edx] + movdqu xmm6, oword [esp+16+edx*2] + movdqu xmm7, oword [esp+16+ebx] + + pxor xmm0, xmm4 ; xor src + movdqu oword [esp+5*16],xmm0;and store into the stack + pxor xmm1, xmm5 + movdqu oword [esp+5*16+edx], xmm1 + pxor xmm2, xmm6 + movdqu oword [esp+5*16+edx*2], xmm2 + pxor xmm3, xmm7 + movdqu oword [esp+5*16+ebx], xmm3 + + lea eax, [edx*BLKS_PER_LOOP] + COPY_128U edi, {esp+5*16}, eax, xmm0 ; move 4 blocks to output + + movdqu xmm0, oword [esp+eax] ; update IV + movdqu oword [esp], xmm0 + + + add esi, eax + add edi, eax + sub dword cfbBlks, BLKS_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add dword cfbBlks, BLKS_PER_LOOP + jz .quit + + lea ebx, [edx*2] + lea ecx, [edx+edx*2] + cmp dword cfbBlks, 2 + cmovl ebx, edx + cmovg ebx, ecx + COPY_32U {esp+16}, esi, ebx, eax ; move recent input blocks to stack + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov ecx, pKey + mov eax, nr + lea esi,[eax*4] + lea esi, [ecx+esi*4-9*(SC)*4] ; AES-128 round keys + + xor eax, eax ; index +.single_blk_loop: + movdqu xmm0, oword [esp+eax] ; get encoded block + + pxor xmm0, oword [ecx] ; whitening + + cmp dword nr, 12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0, oword [esi-4*4*SC] + aesenc xmm0, oword [esi-3*4*SC] +.key_192_s: + aesenc xmm0, oword [esi-2*4*SC] + aesenc xmm0, oword [esi-1*4*SC] +.key_128_s: + aesenc xmm0, oword [esi+0*4*SC] + aesenc xmm0, oword [esi+1*4*SC] + aesenc xmm0, oword [esi+2*4*SC] + aesenc xmm0, oword [esi+3*4*SC] + aesenc xmm0, oword [esi+4*4*SC] + aesenc xmm0, oword [esi+5*4*SC] + aesenc xmm0, oword [esi+6*4*SC] + aesenc xmm0, oword [esi+7*4*SC] + aesenc xmm0, oword [esi+8*4*SC] + aesenclast xmm0, oword [esi+9*4*SC] + + movdqu xmm1, oword [esp+eax+16] ; get input block from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [esp+5*16+eax], xmm0 ; and save output + + add eax, edx + dec dword cfbBlks + jnz .single_blk_loop + + COPY_32U edi, {esp+5*16}, ebx, eax ; copy rest output from the stack + +.quit: + add esp, 16*(1+4+4) ; free stack + REST_GPR + ret +ENDFUNC DecryptCFB32_RIJ128pipe_AES_NI + +;; +;; Lib = G9 +;; +;; Caller = ippsRijndael128DecryptCFB +;; +align IPP_ALIGN_FACTOR +IPPASM DecryptCFB128_RIJ128pipe_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [ebp + ARG_1 + 4*sizeof(dword)] ; length of stream in bytes +%xdefine pIV [ebp + ARG_1 + 5*sizeof(dword)] ; IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + mov ecx,pKey ; keys + mov edx, len + + mov eax, pIV + movdqu xmm0, oword [eax] ; get IV + + sub edx, BYTES_PER_LOOP ; test length of the stream + jl .short_input + +;; +;; pipelined processing +;; +.blks_loop: + movdqa xmm7, oword [ecx] ; keys for whitening + lea ebx, [ecx+16] ; pointer to the round's key material + + movdqu xmm1, oword [esi+0*BYTES_PER_BLK] ; get another encoded cblocks + movdqu xmm2, oword [esi+1*BYTES_PER_BLK] + movdqu xmm3, oword [esi+2*BYTES_PER_BLK] + + pxor xmm0, xmm7 ; whitening + pxor xmm1, xmm7 + pxor xmm2, xmm7 + pxor xmm3, xmm7 + + movdqa xmm7, oword [ebx] ; pre load operation's keys + add ebx, 16 + + mov eax, nr ; counter depending on key length + sub eax, 1 +.cipher_loop: + aesenc xmm0, xmm7 ; regular round + aesenc xmm1, xmm7 + aesenc xmm2, xmm7 + aesenc xmm3, xmm7 + movdqa xmm7, oword [ebx] ; pre load operation's keys + add ebx, 16 + dec eax + jnz .cipher_loop + + aesenclast xmm0, xmm7 ; irregular round and IV for 4 input blocks + movdqu xmm4, oword [esi+0*BYTES_PER_BLK] + aesenclast xmm1, xmm7 + movdqu xmm5, oword [esi+1*BYTES_PER_BLK] + aesenclast xmm2, xmm7 + movdqu xmm6, oword [esi+2*BYTES_PER_BLK] + aesenclast xmm3, xmm7 + movdqu xmm7, oword [esi+3*BYTES_PER_BLK] + add esi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; 4 output blocks + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 + pxor xmm1, xmm5 + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 + pxor xmm2, xmm6 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 + pxor xmm3, xmm7 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 + add edi, BYTES_PER_LOOP + + movdqa xmm0, xmm7 ; update IV + sub edx, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add edx, BYTES_PER_LOOP + jz .quit + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov eax, nr + lea ebx,[eax*4] + lea ebx, [ecx+ebx*4-9*(SC)*4] ; AES-128 round keys + +.single_blk_loop: + pxor xmm0, oword [ecx] ; whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0, oword [ebx-4*4*SC] + aesenc xmm0, oword [ebx-3*4*SC] +.key_192_s: + aesenc xmm0, oword [ebx-2*4*SC] + aesenc xmm0, oword [ebx-1*4*SC] +.key_128_s: + aesenc xmm0, oword [ebx+0*4*SC] + aesenc xmm0, oword [ebx+1*4*SC] + aesenc xmm0, oword [ebx+2*4*SC] + aesenc xmm0, oword [ebx+3*4*SC] + aesenc xmm0, oword [ebx+4*4*SC] + aesenc xmm0, oword [ebx+5*4*SC] + aesenc xmm0, oword [ebx+6*4*SC] + aesenc xmm0, oword [ebx+7*4*SC] + aesenc xmm0, oword [ebx+8*4*SC] + aesenclast xmm0, oword [ebx+9*4*SC] + + movdqu xmm1, oword [esi] ; input block from the stream + add esi, BYTES_PER_BLK + + pxor xmm0, xmm1 ; xor src + movdqu oword [edi], xmm0 ; and save output + add edi, BYTES_PER_BLK + + movdqa xmm0, xmm1 ; update IV + sub edx, BYTES_PER_BLK + jnz .single_blk_loop + +.quit: + REST_GPR + ret +ENDFUNC DecryptCFB128_RIJ128pipe_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptecbpipeg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptecbpipeg9as.asm new file mode 100644 index 000000000..431a84468 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptecbpipeg9as.asm @@ -0,0 +1,176 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; DecryptECB_RIJ128pipe_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +;*************************************************************** +;* Purpose: pipelined RIJ128 ECB decryption +;* +;* void DecryptECB_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len) +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128DecryptECB +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM DecryptECB_RIJ128pipe_AES_NI,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [esp + ARG_1 + 4*sizeof(dword)] ; length(byte) + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + mov ecx,pKey ; key material address + mov edx,len ; length + mov eax,nr ; number of rounds + + sub edx, BYTES_PER_LOOP + jl .short_input + + lea ebx,[eax*SC] ; keys offset + lea ecx,[ecx+ebx*4] +;; +;; pipelined processing +;; +.blks_loop: + movdqa xmm4, oword [ecx] ; keys for whitening + lea ebx, [ecx-16] ; set pointer to the round's key material + + movdqu xmm0, oword [esi+0*BYTES_PER_BLK] ; get input blocks + movdqu xmm1, oword [esi+1*BYTES_PER_BLK] + movdqu xmm2, oword [esi+2*BYTES_PER_BLK] + movdqu xmm3, oword [esi+3*BYTES_PER_BLK] + add esi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [ebx] ; pre load round keys + sub ebx, 16 + + mov eax, nr ; counter depending on key length + sub eax, 1 +.cipher_loop: + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + movdqa xmm4, oword [ebx] ; pre load operation's keys + sub ebx, 16 + dec eax + jnz .cipher_loop + + aesdeclast xmm0, xmm4 ; irregular round + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 ; store output blocks + aesdeclast xmm1, xmm4 + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 + aesdeclast xmm2, xmm4 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 + aesdeclast xmm3, xmm4 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 + + add edi, BYTES_PER_LOOP + sub edx, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add edx, BYTES_PER_LOOP + jz .quit + + mov eax, nr + mov ecx, pKey + lea ebx,[eax*SC] ; set pointer to the key material + lea ebx,[ecx+ebx*4] + +.single_blk_loop: + movdqu xmm0, oword [esi] ; get input block + add esi, BYTES_PER_BLK + pxor xmm0, oword [ebx] ; whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesdec xmm0, oword [ecx+9*SC*4+4*SC*4] + aesdec xmm0, oword [ecx+9*SC*4+3*SC*4] +.key_192_s: + aesdec xmm0, oword [ecx+9*SC*4+2*SC*4] + aesdec xmm0, oword [ecx+9*SC*4+1*SC*4] +.key_128_s: + aesdec xmm0, oword [ecx+9*SC*4-0*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-1*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-2*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-3*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-4*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-5*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-6*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-7*SC*4] + aesdec xmm0, oword [ecx+9*SC*4-8*SC*4] + aesdeclast xmm0, oword [ecx+9*SC*4-9*SC*4] + + movdqu oword [edi], xmm0 ; save output block + add edi, BYTES_PER_BLK + + sub edx, BYTES_PER_BLK + jnz .single_blk_loop + +.quit: + REST_GPR + ret +ENDFUNC DecryptECB_RIJ128pipe_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptg9as.asm new file mode 100644 index 000000000..29512c9de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptg9as.asm @@ -0,0 +1,114 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Decrypt_RIJ128_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + +;*************************************************************** +;* Purpose: single block RIJ128 Inverse Cipher +;* +;* void Encrypt_RIJ128(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* const Ipp32u Tables[][256]) +;* +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128DecryptECB +;; Caller = ippsRijndael128DecryptCBC +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM Decrypt_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address + +%xdefine SC (4) + + + mov esi,pInpBlk ; input data address + mov ecx,pKey ; key material address + mov eax,nr ; number of rounds + mov edi,pOutBlk ; output data address + + lea edx,[eax*4] + + movdqu xmm0, oword [esi] ; input block + + ;;whitening + pxor xmm0, oword [ecx+edx*4] ; whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128 + jz .key_192 + + ;; + ;; regular rounds + ;; +.key_256: + aesdec xmm0,oword [ecx+9*SC*4+4*4*SC] + aesdec xmm0,oword [ecx+9*SC*4+3*4*SC] +.key_192: + aesdec xmm0,oword [ecx+9*SC*4+2*4*SC] + aesdec xmm0,oword [ecx+9*SC*4+1*4*SC] +.key_128: + aesdec xmm0,oword [ecx+9*SC*4-0*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-1*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-2*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-3*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-4*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-5*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-6*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-7*4*SC] + aesdec xmm0,oword [ecx+9*SC*4-8*4*SC] + ;; + ;; last rounds + ;; + aesdeclast xmm0,oword [ecx+9*SC*4-9*4*SC] + + movdqu oword [edi], xmm0 ; output block + REST_GPR + ret +ENDFUNC Decrypt_RIJ128_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptxtsg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptxtsg9as.asm new file mode 100644 index 000000000..2d2294dc2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128decryptxtsg9as.asm @@ -0,0 +1,265 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; AES function +; +; Content: +; cpAESDecryptXTS_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%macro MUL_X 4.nolist + %xdefine %%y %1 + %xdefine %%x %2 + %xdefine %%t %3 + %xdefine %%cnt %4 + + pxor %%t, %%t + movdqa %%y, %%x + pcmpgtq %%t, %%x + paddq %%y, %%y + palignr %%t, %%t, sizeof(qword) + pand %%t, %%cnt + pxor %%y, %%t +%endmacro + + +;*************************************************************** +;* Purpose: AES-XTS decryption +;* +;* void cpAESDecryptXTS_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int length, +;* const Ipp8u* pRKey, +;* int nr, +;* const Ipp8u* pTweak) +;*************************************************************** + +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsAESDecryptXTS +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM cpAESDecryptXTS_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pOutBlk [ebp + ARG_1 + 0*sizeof(dword)] ; output block address +%xdefine pInpBlk [ebp + ARG_1 + 1*sizeof(dword)] ; input block address +%xdefine blks [ebp + ARG_1 + 2*sizeof(dword)] ; length(blocks) +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine nr [ebp + ARG_1 + 4*sizeof(dword)] ; number of rounds +%xdefine pTweak [ebp + ARG_1 + 5*sizeof(dword)] ; tweaks + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + +; +; stack layout: +; +%assign _tweakCnt 0 ; constant +%assign _tweak0 _tweakCnt+sizeof(oword) ; * alpha +%assign _tweak1 _tweak0+sizeof(oword) ; * alpha^2 +%assign _tweak2 _tweak1+sizeof(oword) ; * alpha^3 +%assign _tweak3 _tweak2+sizeof(oword) ; * alpha^4 +%assign _tkey _tweak3+sizeof(oword) ; decryption keys (top) +%assign _bkey _tkey+sizeof(dword) ; decryption keys (bottom) +%assign _nr _bkey+sizeof(dword) ; # rounds +%assign _sp _nr+sizeof(dword) ; esp +%assign stackSize _sp+sizeof(dword) ; stack size + + mov eax, esp + sub esp, stackSize ; aligned stack + and esp, (-16) + mov dword [esp+_sp], eax ; store esp + + mov eax, pTweak + movdqu xmm4, oword [eax] ; initial tweak + movdqa xmm7, xmm4 + + mov eax, 087h ; create tweakCnt = {0x01:0x87} + mov ecx, 1 + movd xmm0, eax + movd xmm1, ecx + punpcklqdq xmm0, xmm1 + + mov ecx,pKey ; key material address + mov eax,nr ; num of rounds + mov edx,blks ; num of blocks + + ; move parameters to local stack frame + movdqa oword [esp+_tweakCnt], xmm0 + mov dword [esp+_tkey], ecx + lea ebx, [eax*SC] + lea ecx, [ecx+ebx*sizeof(dword)] + mov dword [esp+_bkey], ecx + mov dword [esp+_nr], eax + + sub edx, BLKS_PER_LOOP + jl .short_input + jmp .blks_loop_ep + +;; +;; pipelined processing +;; +.blks_loop: + MUL_X xmm4, xmm7, xmm1, xmm0 +.blks_loop_ep: + movdqa oword [esp+_tweak0], xmm4 + MUL_X xmm5, xmm4, xmm1, xmm0 + movdqa oword [esp+_tweak1], xmm5 + MUL_X xmm6, xmm5, xmm1, xmm0 + movdqa oword [esp+_tweak2], xmm6 + MUL_X xmm7, xmm6, xmm1, xmm0 + movdqa oword [esp+_tweak3], xmm7 + + movdqu xmm0, oword [esi+0*BYTES_PER_BLK] ; get input blocks + movdqu xmm1, oword [esi+1*BYTES_PER_BLK] + movdqu xmm2, oword [esi+2*BYTES_PER_BLK] + movdqu xmm3, oword [esi+3*BYTES_PER_BLK] + add esi, BYTES_PER_BLK*BLKS_PER_LOOP + + pxor xmm0, xmm4 ; tweak pre-whitening + pxor xmm1, xmm5 + pxor xmm2, xmm6 + pxor xmm3, xmm7 + + movdqa xmm4, oword [ecx] ; keys for whitening + lea ebx, [ecx-BYTES_PER_BLK]; pointer to the round's key material + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [ebx] ; pre load round keys + sub ebx, BYTES_PER_BLK + sub eax, 1 +.cipher_loop: + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + movdqa xmm4, oword [ebx] + sub ebx, BYTES_PER_BLK + dec eax + jnz .cipher_loop + + aesdeclast xmm0, xmm4 ; irregular round + aesdeclast xmm1, xmm4 + aesdeclast xmm2, xmm4 + aesdeclast xmm3, xmm4 + + movdqa xmm4, oword [esp+_tweak0] ; tweak post-whitening + movdqa xmm5, oword [esp+_tweak1] + movdqa xmm6, oword [esp+_tweak2] + movdqa xmm7, oword [esp+_tweak3] + pxor xmm0, xmm4 + pxor xmm1, xmm5 + pxor xmm2, xmm6 + pxor xmm3, xmm7 + + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 ; store output blocks + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 + add edi, BYTES_PER_BLK*BLKS_PER_LOOP + + movdqa xmm0, oword [esp+_tweakCnt] ; restore tweak const + mov eax, dword [esp+_nr] ; number of rounds + sub edx, BLKS_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add edx, BLKS_PER_LOOP + jz .quit + + mov ecx, dword [esp+_tkey] + mov ebx, dword [esp+_bkey] + mov eax, dword [esp+_nr] + jmp .single_blk_loop_ep + +.single_blk_loop: + MUL_X xmm7, xmm7, xmm1, xmm0 + +.single_blk_loop_ep: + movdqu xmm1, oword [esi] ; input block + add esi, BYTES_PER_BLK + pxor xmm1, xmm7 ; tweak pre-whitening + pxor xmm1, oword [ebx] ; AES whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128_s + +.key_256_s: + aesdec xmm1,oword [ecx+9*SC*4+4*SC*4] + aesdec xmm1,oword [ecx+9*SC*4+3*SC*4] + aesdec xmm1,oword [ecx+9*SC*4+2*SC*4] + aesdec xmm1,oword [ecx+9*SC*4+1*SC*4] +.key_128_s: + aesdec xmm1,oword [ecx+9*SC*4-0*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-1*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-2*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-3*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-4*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-5*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-6*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-7*SC*4] + aesdec xmm1,oword [ecx+9*SC*4-8*SC*4] + aesdeclast xmm1,oword [ecx+9*SC*4-9*SC*4] + + pxor xmm1, xmm7 ; tweak post-whitening + movdqu oword [edi], xmm1 ; output block + add edi, BYTES_PER_BLK + + sub edx, 1 + jnz .single_blk_loop + +.quit: + mov eax, pTweak ; save tweak + movdqu oword [eax], xmm7 + + mov esp, [esp+_sp] + REST_GPR + ret +ENDFUNC cpAESDecryptXTS_AES_NI +%endif + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptcbcg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptcbcg9as.asm new file mode 100644 index 000000000..4728b851b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptcbcg9as.asm @@ -0,0 +1,119 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; EncryptCBC_RIJ128pipe_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +;*************************************************************** +;* Purpose: RIJ128 CBC encryption +;* +;* void EncryptCBC_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len, +;* const Ipp8u* pIV) +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128EncryptCBC +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM EncryptCBC_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [esp + ARG_1 + 4*sizeof(dword)] ; length (bytes) +%xdefine pIV [esp + ARG_1 + 5*sizeof(dword)] ; IV + +%xdefine SC (4) +%assign BYTES_PER_BLK (16) + + mov edx, pIV ; IV address + mov esi,pInpBlk ; input data address + mov ecx,pKey ; key material address + mov eax,nr ; number of rounds + mov edi,pOutBlk ; output data address + + movdqu xmm0, oword [edx] ; IV + + mov edx, len ; length of stream + +align IPP_ALIGN_FACTOR +;; +;; block-by-block processing +;; +.blks_loop: + movdqu xmm1, oword [esi] ; input block + + movdqa xmm4, oword [ecx] ; preload key material + + pxor xmm0, xmm1 ; src[] ^ iv + + pxor xmm0, xmm4 ; whitening + + movdqa xmm4, oword [ecx+16] ; preload key material + add ecx, 16 + + sub eax, 1 ; counter depending on key length +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + movdqa xmm4, oword [ecx+16] + add ecx, 16 + sub eax, 1 + jnz .cipher_loop + aesenclast xmm0, xmm4 ; irregular round + + movdqu oword [edi], xmm0 ; store output block + + mov ecx, pKey ; restore key pointer + mov eax, nr ; resrore number of rounds + + add esi, BYTES_PER_BLK ; advance pointers + add edi, BYTES_PER_BLK + sub edx, BYTES_PER_BLK ; decrease counter + jnz .blks_loop + + REST_GPR + ret +ENDFUNC EncryptCBC_RIJ128_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptcfbg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptcfbg9as.asm new file mode 100644 index 000000000..0ef62a1d6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptcfbg9as.asm @@ -0,0 +1,376 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Encrypt_RIJ128_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + +%macro COPY_8U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor ecx, ecx +%%next_byte: + mov %%tmp, byte [%%src+ecx] + mov byte [%%dst+ecx], %%tmp + add ecx, 1 + cmp ecx, %%limit + jl %%next_byte +%endmacro + + +%macro COPY_32U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor ecx, ecx +%%next_dword: + mov %%tmp, dword [%%src+ecx] + mov dword [%%dst+ecx], %%tmp + add ecx, 4 + cmp ecx, %%limit + jl %%next_dword +%endmacro + + +%macro COPY_128U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor ecx, ecx +%%next_oword: + movdqu %%tmp, oword [%%src+ecx] + movdqu oword [%%dst+ecx], %%tmp + add ecx, 16 + cmp ecx, %%limit + jl %%next_oword +%endmacro + + +;*************************************************************** +;* Purpose: RIJ128 CFB encryption +;* +;* void EncryptCFB_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len, +;* int cfbSize, +;* const Ipp8u* pIV) +;*************************************************************** + +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128EncryptCFB +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM EncryptCFB_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input blocks address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output blocks address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [ebp + ARG_1 + 4*sizeof(dword)] ; length of stream in bytes +%xdefine cfbSize [ebp + ARG_1 + 5*sizeof(dword)] ; cfb blk size +%xdefine pIV [ebp + ARG_1 + 6*sizeof(dword)] ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + sub esp,16*(1+4+4) ; allocate stask: + ; +0*16 IV + ; +1*16 inp0, inp1, inp2, inp3 + ; +5*16 out0, out1, out2, out3 + + mov eax, pIV ; IV address + movdqu xmm4, oword [eax] ; get IV + movdqu oword [esp+0*16], xmm4 ; into the stack + +;; +;; processing +;; +.blks_loop: + mov esi,pInpBlk ; input data address + + mov edx,cfbSize ; size of block + lea ebx, [edx*BLKS_PER_LOOP] ; 4 cfb block + mov edx, len + cmp edx, ebx + cmovl ebx, edx + COPY_8U {esp+5*16}, esi, ebx, dl ; move 1-4 input blocks to stack + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov ecx, pKey + mov edx, nr + lea eax,[edx*4] + lea eax, [ecx+eax*4-9*(SC)*4] ; AES-128 round keys + + xor esi, esi ; index + mov edi, ebx +.single_blk: + movdqu xmm0, oword [esp+esi] ; get processing blocks + + pxor xmm0, oword [ecx] ; whitening + + cmp edx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [eax-4*4*SC] + aesenc xmm0, oword [eax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [eax-2*4*SC] + aesenc xmm0, oword [eax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [eax+0*4*SC] + aesenc xmm0, oword [eax+1*4*SC] + aesenc xmm0, oword [eax+2*4*SC] + aesenc xmm0, oword [eax+3*4*SC] + aesenc xmm0, oword [eax+4*4*SC] + aesenc xmm0, oword [eax+5*4*SC] + aesenc xmm0, oword [eax+6*4*SC] + aesenc xmm0, oword [eax+7*4*SC] + aesenc xmm0, oword [eax+8*4*SC] + aesenclast xmm0, oword [eax+9*4*SC] + + movdqu xmm1, oword [esp+5*16+esi] ; get src blocks from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [esp+1*16+esi],xmm0 ;and store into the stack + + add esi, cfbSize ; advance index + sub edi, cfbSize ; decrease length + jg .single_blk + + mov edi,pOutBlk ; output data address + COPY_8U edi, {esp+1*16}, ebx, dl ; move 1-4 blocks to output + + movdqu xmm0, oword [esp+ebx]; update IV + movdqu oword [esp], xmm0 + + add pInpBlk, ebx + add pOutBlk, ebx + sub len, ebx + jg .blks_loop + + add esp, 16*(1+4+4) + REST_GPR + ret +ENDFUNC EncryptCFB_RIJ128_AES_NI + +align IPP_ALIGN_FACTOR +IPPASM EncryptCFB32_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input blocks address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output blocks address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [ebp + ARG_1 + 4*sizeof(dword)] ; length of stream in bytes +%xdefine cfbSize [ebp + ARG_1 + 5*sizeof(dword)] ; cfb blk size +%xdefine pIV [ebp + ARG_1 + 6*sizeof(dword)] ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + sub esp,16*(1+4+4) ; allocate stask: + ; +0*16 IV + ; +1*16 inp0, inp1, inp2, inp3 + ; +5*16 out0, out1, out2, out3 + + mov eax, pIV ; IV address + movdqu xmm4, oword [eax] ; get IV + movdqu oword [esp+0*16], xmm4 ; into the stack + +;; +;; processing +;; +.blks_loop: + mov esi,pInpBlk ; input data address + + mov edx,cfbSize ; size of block + lea ebx, [edx*BLKS_PER_LOOP] ; 4 cfb block + mov edx, len + cmp edx, ebx + cmovl ebx, edx + COPY_32U {esp+5*16}, esi, ebx, edx ; move 1-4 input blocks to stack + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov ecx, pKey + mov edx, nr + lea eax,[edx*4] + lea eax, [ecx+eax*4-9*(SC)*4] ; AES-128 round keys + + xor esi, esi ; index + mov edi, ebx +.single_blk: + movdqu xmm0, oword [esp+esi] ; get processing blocks + + pxor xmm0, oword [ecx] ; whitening + + cmp edx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [eax-4*4*SC] + aesenc xmm0, oword [eax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [eax-2*4*SC] + aesenc xmm0, oword [eax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [eax+0*4*SC] + aesenc xmm0, oword [eax+1*4*SC] + aesenc xmm0, oword [eax+2*4*SC] + aesenc xmm0, oword [eax+3*4*SC] + aesenc xmm0, oword [eax+4*4*SC] + aesenc xmm0, oword [eax+5*4*SC] + aesenc xmm0, oword [eax+6*4*SC] + aesenc xmm0, oword [eax+7*4*SC] + aesenc xmm0, oword [eax+8*4*SC] + aesenclast xmm0, oword [eax+9*4*SC] + + movdqu xmm1, oword [esp+5*16+esi] ; get src blocks from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [esp+1*16+esi],xmm0 ;and store into the stack + + add esi, cfbSize ; advance index + sub edi, cfbSize ; decrease length + jg .single_blk + + mov edi,pOutBlk ; output data address + COPY_32U edi, {esp+1*16}, ebx, edx ; move 1-4 blocks to output + + movdqu xmm0, oword [esp+ebx] ; update IV + movdqu oword [esp], xmm0 + + add pInpBlk, ebx + add pOutBlk, ebx + sub len, ebx + jg .blks_loop + + add esp, 16*(1+4+4) + REST_GPR + ret +ENDFUNC EncryptCFB32_RIJ128_AES_NI + + +align IPP_ALIGN_FACTOR +IPPASM EncryptCFB128_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input blocks address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output blocks address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [ebp + ARG_1 + 4*sizeof(dword)] ; length of stream in bytes +%xdefine pIV [ebp + ARG_1 + 5*sizeof(dword)] ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + mov eax, pIV ; IV address + movdqu xmm0, oword [eax] ; get IV + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + mov ebx, len + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov ecx, pKey + mov edx, nr + lea eax,[edx*4] + lea eax, [ecx+eax*4-9*(SC)*4] ; AES-128 round keys + + +;; +;; processing +;; +.blks_loop: + pxor xmm0, oword [ecx] ; whitening + + movdqu xmm1, oword [esi] ; input blocks + + + cmp edx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [eax-4*4*SC] + aesenc xmm0, oword [eax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [eax-2*4*SC] + aesenc xmm0, oword [eax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [eax+0*4*SC] + aesenc xmm0, oword [eax+1*4*SC] + aesenc xmm0, oword [eax+2*4*SC] + aesenc xmm0, oword [eax+3*4*SC] + aesenc xmm0, oword [eax+4*4*SC] + aesenc xmm0, oword [eax+5*4*SC] + aesenc xmm0, oword [eax+6*4*SC] + aesenc xmm0, oword [eax+7*4*SC] + aesenc xmm0, oword [eax+8*4*SC] + aesenclast xmm0, oword [eax+9*4*SC] + + pxor xmm0, xmm1 ; xor src + movdqu oword [edi],xmm0 ;and store into the dst + + add esi, 16 + add edi, 16 + sub ebx, 16 + jg .blks_loop + + REST_GPR + ret +ENDFUNC EncryptCFB128_RIJ128_AES_NI + +%endif + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptctrpipeg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptctrpipeg9as.asm new file mode 100644 index 000000000..49e12bcfe --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptctrpipeg9as.asm @@ -0,0 +1,318 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; EncryptCTR_RIJ128pipe_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + + + +;*************************************************************** +;* Purpose: pipelined RIJ128 CTR encryption/decryption +;* +;* void EncryptCTR_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int length, +;* Ipp8u* pCtrValue, +;* Ipp8u* pCtrBitMask) +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128EncryptCTR +;; + +segment .text align=IPP_ALIGN_FACTOR +align IPP_ALIGN_FACTOR +CONST_TABLE: +u128_str DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +align IPP_ALIGN_FACTOR +IPPASM EncryptCTR_RIJ128pipe_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [ebp + ARG_1 + 4*sizeof(dword)] ; number of blocks being processed +%xdefine pCtrValue [ebp + ARG_1 + 5*sizeof(dword)] ; pointer to the Counter +%xdefine pCtrBitMask [ebp + ARG_1 + 6*sizeof(dword)] ; pointer to the Counter Bit Mask + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov esi, pCtrBitMask + mov edi, pCtrValue + movdqu xmm6, oword [esi] ; counter bit mask + movdqu xmm1, oword [edi] ; initial counter + movdqu xmm5, xmm6 ; counter bit mask + pandn xmm6, xmm1 ; counter template + + sub esp, (4*4) ; allocate stack + + LD_ADDR eax, CONST_TABLE ; load bswap conversion tbl + movdqa xmm4, oword [eax+(u128_str - CONST_TABLE)] + + ;; + ;; init counter + ;; + mov edx, dword [edi] + mov ecx, dword [edi+4] + mov ebx, dword [edi+8] + mov eax, dword [edi+12] + bswap edx + bswap ecx + bswap ebx + bswap eax + + mov dword [esp], eax ; store counter + mov dword [esp+4], ebx + mov dword [esp+8], ecx + mov dword [esp+12], edx + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + + sub dword len, BYTES_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +.blks_loop: + mov eax, dword [esp] ; get coutnter value + mov ebx, dword [esp+4] + mov ecx, dword [esp+8] + mov edx, dword [esp+12] + + pinsrd xmm0, eax, 0 ; set counter value + pinsrd xmm0, ebx, 1 + pinsrd xmm0, ecx, 2 + pinsrd xmm0, edx, 3 + pshufb xmm0, xmm4 ; convert int the octet string + pand xmm0, xmm5 ; select counter bits + por xmm0, xmm6 ; add unchanged bits + + add eax, 1 ; increment counter + adc ebx, 0 + adc ecx, 0 + adc edx, 0 + pinsrd xmm1, eax, 0 ; set counter value + pinsrd xmm1, ebx, 1 + pinsrd xmm1, ecx, 2 + pinsrd xmm1, edx, 3 + pshufb xmm1, xmm4 ; convert int the octet string + pand xmm1, xmm5 ; select counter bits + por xmm1, xmm6 ; add unchanged bits + + add eax, 1 ; increment counter + adc ebx, 0 + adc ecx, 0 + adc edx, 0 + pinsrd xmm2, eax, 0 ; set counter value + pinsrd xmm2, ebx, 1 + pinsrd xmm2, ecx, 2 + pinsrd xmm2, edx, 3 + pshufb xmm2, xmm4 ; convert int the octet string + pand xmm2, xmm5 ; select counter bits + por xmm2, xmm6 ; add unchanged bits + + add eax, 1 ; increment counter + adc ebx, 0 + adc ecx, 0 + adc edx, 0 + pinsrd xmm3, eax, 0 ; set counter value + pinsrd xmm3, ebx, 1 + pinsrd xmm3, ecx, 2 + pinsrd xmm3, edx, 3 + pshufb xmm3, xmm4 ; convert int the octet string + pand xmm3, xmm5 ; select counter bits + por xmm3, xmm6 ; add unchanged bits + + add eax, 1 ; increment counter + adc ebx, 0 + adc ecx, 0 + adc edx, 0 + mov dword [esp], eax ; and store for next itteration + mov dword [esp+4], ebx + mov dword [esp+8], ecx + mov dword [esp+12], edx + + mov ecx, pKey ; get key material address + movdqa xmm7, oword [ecx] + lea ebx, [ecx+16] ; pointer to the round's key material + + pxor xmm0, xmm7 ; whitening + pxor xmm1, xmm7 + pxor xmm2, xmm7 + pxor xmm3, xmm7 + + movdqa xmm7, oword [ebx] ; pre load round keys + add ebx, 16 + + mov eax, nr ; counter depending on key length + sub eax, 1 +.cipher_loop: + aesenc xmm0, xmm7 ; regular round + aesenc xmm1, xmm7 + aesenc xmm2, xmm7 + aesenc xmm3, xmm7 + movdqa xmm7, oword [ebx] + add ebx, 16 + dec eax + jnz .cipher_loop + + aesenclast xmm0, xmm7 ; irregular round + aesenclast xmm1, xmm7 + aesenclast xmm2, xmm7 + aesenclast xmm3, xmm7 + + movdqu xmm7, oword [esi+0*BYTES_PER_BLK] ; xor input blocks + pxor xmm0, xmm7 + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 + + movdqu xmm7, oword [esi+1*BYTES_PER_BLK] + pxor xmm1, xmm7 + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 + + movdqu xmm7, oword [esi+2*BYTES_PER_BLK] + pxor xmm2, xmm7 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 + + movdqu xmm7, oword [esi+3*BYTES_PER_BLK] + pxor xmm3, xmm7 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 + + add esi, BYTES_PER_LOOP + add edi, BYTES_PER_LOOP + + sub dword len, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add dword len, BYTES_PER_LOOP + jz .quit + + mov ecx,pKey ; key material address + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov eax, nr + lea ebx,[eax*4] + lea ebx,[ecx+ebx*4-9*(SC)*4] ; AES-128 round keys + +.single_blk_loop: + movdqu xmm0, oword [esp] ; get counter value + pshufb xmm0, xmm4 ; convert int the octet string + pand xmm0, xmm5 ; select counter bits + por xmm0, xmm6 ; add unchanged bits + + pxor xmm0, oword [ecx] ; whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0,oword [ebx-4*4*SC] + aesenc xmm0,oword [ebx-3*4*SC] +.key_192_s: + aesenc xmm0,oword [ebx-2*4*SC] + aesenc xmm0,oword [ebx-1*4*SC] +.key_128_s: + aesenc xmm0,oword [ebx+0*4*SC] + aesenc xmm0,oword [ebx+1*4*SC] + aesenc xmm0,oword [ebx+2*4*SC] + aesenc xmm0,oword [ebx+3*4*SC] + aesenc xmm0,oword [ebx+4*4*SC] + aesenc xmm0,oword [ebx+5*4*SC] + aesenc xmm0,oword [ebx+6*4*SC] + aesenc xmm0,oword [ebx+7*4*SC] + aesenc xmm0,oword [ebx+8*4*SC] + aesenclast xmm0,oword [ebx+9*4*SC] + + add dword [esp], 1 ; advance counter value + adc dword [esp+4], 0 + adc dword [esp+8], 0 + adc dword [esp+12], 0 + + sub dword len, BYTES_PER_BLK + jl .partial_block + + movdqu xmm1, oword [esi] ; input block + add esi, BYTES_PER_BLK + pxor xmm0, xmm1 ; output block + movdqu oword [edi], xmm0 ; save output block + add edi, BYTES_PER_BLK + + cmp dword len, 0 + jz .quit + jmp .single_blk_loop + +.partial_block: + add dword len, BYTES_PER_BLK + +.partial_block_loop: + pextrb eax, xmm0, 0 + psrldq xmm0, 1 + movzx ebx, byte [esi] + xor eax, ebx + mov byte [edi], al + inc esi + inc edi + dec dword len + jnz .partial_block_loop + +.quit: + mov eax, pCtrValue + movdqu xmm0, oword [esp] ; get counter value + pshufb xmm0, xmm4 ; convert int the octet string + pand xmm0, xmm5 ; select counter bits + por xmm0, xmm6 ; add unchanged bits + movdqu oword [eax], xmm0 ; return updated counter + + add esp, (4*4) ; free stack + REST_GPR + ret +ENDFUNC EncryptCTR_RIJ128pipe_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptecbpipeg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptecbpipeg9as.asm new file mode 100644 index 000000000..2d9939152 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptecbpipeg9as.asm @@ -0,0 +1,173 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; EncryptECB_RIJ128pipe_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +;*************************************************************** +;* Purpose: pipelined RIJ128 ECB encryption +;* +;* void EncryptECB_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len) +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128EncryptECB +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM EncryptECB_RIJ128pipe_AES_NI,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [esp + ARG_1 + 4*sizeof(dword)] ; length(byte) + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + mov ecx,pKey ; key material address + mov edx,len ; length + + sub edx, BYTES_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +.blks_loop: + movdqa xmm4, oword [ecx] ; keys for whitening + lea ebx, [ecx+16] ; pointer to the round's key material + + movdqu xmm0, oword [esi+0*BYTES_PER_BLK] ; get input blocks + movdqu xmm1, oword [esi+1*BYTES_PER_BLK] + movdqu xmm2, oword [esi+2*BYTES_PER_BLK] + movdqu xmm3, oword [esi+3*BYTES_PER_BLK] + add esi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [ebx] ; pre load round keys + add ebx, 16 + + mov eax,nr ; number of rounds depending on key length + sub eax, 1 +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [ebx] + add ebx, 16 + dec eax + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 ; store output blocks + aesenclast xmm1, xmm4 + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 + aesenclast xmm2, xmm4 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 + aesenclast xmm3, xmm4 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 + + add edi, BYTES_PER_LOOP + sub edx, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add edx, BYTES_PER_LOOP + jz .quit + + ; get actual address of key material: pRKeys += (nr-9) * SC + mov eax, nr + lea ebx,[eax*4] + lea ebx,[ecx+ebx*4-9*(SC)*4] ; AES-128 round keys + +.single_blk_loop: + movdqu xmm0, oword [esi] ; get input block + add esi, BYTES_PER_BLK + pxor xmm0, oword [ecx] ; whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0,oword [ebx-4*4*SC] + aesenc xmm0,oword [ebx-3*4*SC] +.key_192_s: + aesenc xmm0,oword [ebx-2*4*SC] + aesenc xmm0,oword [ebx-1*4*SC] +.key_128_s: + aesenc xmm0,oword [ebx+0*4*SC] + aesenc xmm0,oword [ebx+1*4*SC] + aesenc xmm0,oword [ebx+2*4*SC] + aesenc xmm0,oword [ebx+3*4*SC] + aesenc xmm0,oword [ebx+4*4*SC] + aesenc xmm0,oword [ebx+5*4*SC] + aesenc xmm0,oword [ebx+6*4*SC] + aesenc xmm0,oword [ebx+7*4*SC] + aesenc xmm0,oword [ebx+8*4*SC] + aesenclast xmm0,oword [ebx+9*4*SC] + + movdqu oword [edi], xmm0 ; save output block + add edi, BYTES_PER_BLK + + sub edx, BYTES_PER_BLK + jnz .single_blk_loop + +.quit: + REST_GPR + ret +ENDFUNC EncryptECB_RIJ128pipe_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptg9as.asm new file mode 100644 index 000000000..5ec0205be --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptg9as.asm @@ -0,0 +1,119 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; Encrypt_RIJ128_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +;*************************************************************** +;* Purpose: single block RIJ128 Cipher +;* +;* void Encrypt_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* const Ipp32u Tables[][256]) +;* +;*************************************************************** + +;%if (_IPP >= _IPP_P8) && (_IPP < _IPP_G9) +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128EncryptECB +;; Caller = ippsRijndael128EncryptCBC +;; Caller = ippsRijndael128EncryptCFB +;; Caller = ippsRijndael128DecryptCFB +;; +;; Caller = ippsDAARijndael128Update +;; Caller = ippsDAARijndael128Final +;; Caller = ippsDAARijndael128MessageDigest +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM Encrypt_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address + +%xdefine SC (4) + + mov esi,pInpBlk ; input data address + mov ecx,pKey ; key material address + mov eax,nr ; number of rounds + mov edi,pOutBlk ; output data address + + movdqu xmm0, oword [esi] ; input block + pxor xmm0, oword [ecx] ; whitening + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea edx,[eax*4] + lea ecx,[ecx+edx*4-9*(SC)*4]; AES-128-keys + + cmp eax,12 ; switch according to number of rounds + jl .key_128 + jz .key_192 + + ;; + ;; regular rounds + ;; +.key_256: + aesenc xmm0,oword [ecx-4*4*SC] + aesenc xmm0,oword [ecx-3*4*SC] +.key_192: + aesenc xmm0,oword [ecx-2*4*SC] + aesenc xmm0,oword [ecx-1*4*SC] +.key_128: + aesenc xmm0,oword [ecx+0*4*SC] + aesenc xmm0,oword [ecx+1*4*SC] + aesenc xmm0,oword [ecx+2*4*SC] + aesenc xmm0,oword [ecx+3*4*SC] + aesenc xmm0,oword [ecx+4*4*SC] + aesenc xmm0,oword [ecx+5*4*SC] + aesenc xmm0,oword [ecx+6*4*SC] + aesenc xmm0,oword [ecx+7*4*SC] + aesenc xmm0,oword [ecx+8*4*SC] + ;; + ;; last rounds + ;; + aesenclast xmm0,oword [ecx+9*4*SC] + + movdqu oword [edi], xmm0 ; output block + + REST_GPR + ret +ENDFUNC Encrypt_RIJ128_AES_NI +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptofbg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptofbg9as.asm new file mode 100644 index 000000000..46af14f88 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptofbg9as.asm @@ -0,0 +1,251 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Encrypt_RIJ128_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + + +%macro COPY_8U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor ecx, ecx +%%next_byte: + mov %%tmp, byte [%%src+ecx] + mov byte [%%dst+ecx], %%tmp + add ecx, 1 + cmp ecx, %%limit + jl %%next_byte +%endmacro + + +;*************************************************************** +;* Purpose: RIJ128 OFB encryption +;* +;* void EncryptOFB_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int length, +;* int ofbBlks, +;* const Ipp8u* pIV) +;*************************************************************** + +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsRijndael128DecryptOFB +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM EncryptOFB_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInpBlk [ebp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [ebp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [ebp + ARG_1 + 4*sizeof(dword)] ; length of stream in bytes +%xdefine ofbSize [ebp + ARG_1 + 5*sizeof(dword)] ; ofb blk size +%xdefine pIV [ebp + ARG_1 + 6*sizeof(dword)] ; IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + +%xdefine tmpInp esp +%xdefine tmpOut tmpInp+sizeof(oword) +%xdefine locDst tmpOut+sizeof(oword) +%xdefine locSrc locDst+sizeof(oword)*4 +%xdefine locLen locSrc+sizeof(oword)*4 +%xdefine stackLen sizeof(oword)+sizeof(oword)+sizeof(oword)*4+sizeof(oword)*4+sizeof(dword) + + sub esp,stackLen ; allocate stack + + mov eax, pIV ; get IV + movdqu xmm0, oword [eax] ; + movdqu oword [tmpInp], xmm0 ; and save into the stack + + mov eax, nr ; number of rounds + mov ecx, pKey ; key material address + lea eax, [eax*4] ; nr*16 offset (bytes) to end of key material + lea eax, [eax*4] + lea ecx, [ecx+eax] + neg eax ; save -nr*16 + mov nr, eax + mov pKey, ecx ; save key material address + + mov esi, pInpBlk ; input stream + mov edi, pOutBlk ; output stream + mov ebx, ofbSize ; cfb blk size + +align IPP_ALIGN_FACTOR +;; +;; processing +;; +.blks_loop: + lea ebx, [ebx*BLKS_PER_LOOP] ; 4 cfb block + + cmp len, ebx + cmovl ebx, len + COPY_8U {locSrc}, esi, ebx, dl ; move 1-4 input blocks to stack + + mov ecx, pKey + mov eax, nr + + mov dword [locLen], ebx + xor edx, edx ; index + +align IPP_ALIGN_FACTOR +.single_blk: + movdqa xmm3, oword [ecx+eax] ; preload key material + add eax, 16 + + movdqa xmm4, oword [ecx+eax] ; preload next key material + pxor xmm0, xmm3 ; whitening + +align IPP_ALIGN_FACTOR +.cipher_loop: + add eax, 16 + aesenc xmm0, xmm4 ; regular round + movdqa xmm4, oword [ecx+eax] + jnz .cipher_loop + aesenclast xmm0, xmm4 ; irregular round + movdqu oword [tmpOut], xmm0 ; save chipher output + + mov eax, ofbSize ; cfb blk size + + movdqu xmm1, oword [locSrc+edx] ; get src blocks from the stack + pxor xmm1, xmm0 ; xor src + movdqu oword [locDst+edx],xmm1 ;and store into the stack + + movdqu xmm0, oword [tmpInp+eax] ; update chiper input (IV) + movdqu oword [tmpInp], xmm0 + + add edx, eax ; advance index + mov eax, nr + cmp edx, ebx + jl .single_blk + + COPY_8U edi, {locDst}, edx, bl ; move 1-4 blocks to output + + mov ebx, ofbSize ; restore cfb blk size + add esi, edx ; advance pointers + add edi, edx + sub len, edx ; decrease stream counter + jg .blks_loop + + mov eax, pIV ; IV address + movdqu xmm0, oword [tmpInp] ; update IV before return + movdqu oword [eax], xmm0 + + add esp,stackLen ; remove local variables + REST_GPR + ret +ENDFUNC EncryptOFB_RIJ128_AES_NI + + +align IPP_ALIGN_FACTOR +IPPASM EncryptOFB128_RIJ128_AES_NI,PUBLIC + USES_GPR esi,edi + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine len [esp + ARG_1 + 4*sizeof(dword)] ; length of stream in bytes +%xdefine pIV [esp + ARG_1 + 5*sizeof(dword)] ; IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + mov eax, pIV ; get IV + movdqu xmm0, oword [eax] ; + + mov eax, nr ; number of rounds + mov ecx, pKey ; key material address + lea eax, [eax*4] ; nr*16 offset (bytes) to end of key material + lea eax, [eax*4] + lea ecx, [ecx+eax] + neg eax ; save -nr*16 + mov nr, eax + + mov esi, pInpBlk ; input stream + mov edi, pOutBlk ; output stream + mov edx, len ; length of stream + +align IPP_ALIGN_FACTOR +;; +;; processing +;; +.blks_loop: + movdqa xmm3, oword [ecx+eax] ; preload key material + add eax, 16 + +align IPP_ALIGN_FACTOR +.single_blk: + movdqa xmm4, oword [ecx+eax] ; preload next key material + pxor xmm0, xmm3 ; whitening + + movdqu xmm1, oword [esi] ; input block + +align IPP_ALIGN_FACTOR +.cipher_loop: + add eax, 16 + aesenc xmm0, xmm4 ; regular round + movdqa xmm4, oword [ecx+eax] + jnz .cipher_loop + aesenclast xmm0, xmm4 ; irregular round + + pxor xmm1, xmm0 ; xor src + movdqu oword [edi],xmm1 ; and store into the dst + + mov eax, nr ; restore key material counter + add esi, 16 ; advance pointers + add edi, 16 + sub edx, 16 ; decrease stream counter + jg .blks_loop + + mov eax, pIV ; get IV address + movdqu oword [eax], xmm0 ; update IV before return + + REST_GPR + ret +ENDFUNC EncryptOFB128_RIJ128_AES_NI + +%endif + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptxtsg9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptxtsg9as.asm new file mode 100644 index 000000000..0b14658bb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128encryptxtsg9as.asm @@ -0,0 +1,259 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; AES function +; +; Content: +; cpAESEncryptXTS_AES_NI() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%macro MUL_X 4.nolist + %xdefine %%y %1 + %xdefine %%x %2 + %xdefine %%t %3 + %xdefine %%cnt %4 + + pxor %%t, %%t + movdqa %%y, %%x + pcmpgtq %%t, %%x + paddq %%y, %%y + palignr %%t, %%t, sizeof(qword) + pand %%t, %%cnt + pxor %%y, %%t +%endmacro + + +;*************************************************************** +;* Purpose: AES-XTS encryption +;* +;* void cpAESEncryptXTS_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int length, +;* const Ipp8u* pRKey, +;* int nr, +;* const Ipp8u* pTweak) +;*************************************************************** + +%if (_IPP >= _IPP_P8) +;; +;; Lib = P8 +;; +;; Caller = ippsAESEncryptXTS +;; + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +IPPASM cpAESEncryptXTS_AES_NI,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pOutBlk [ebp + ARG_1 + 0*sizeof(dword)] ; output block address +%xdefine pInpBlk [ebp + ARG_1 + 1*sizeof(dword)] ; input block address +%xdefine blks [ebp + ARG_1 + 2*sizeof(dword)] ; length(blocks) +%xdefine pKey [ebp + ARG_1 + 3*sizeof(dword)] ; key material address +%xdefine nr [ebp + ARG_1 + 4*sizeof(dword)] ; number of rounds +%xdefine pTweak [ebp + ARG_1 + 5*sizeof(dword)] ; tweaks + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + +; +; stack layout: +; +%assign _tweakCnt 0 ; constant +%assign _tweak0 _tweakCnt+sizeof(oword) ; * alpha +%assign _tweak1 _tweak0+sizeof(oword) ; * alpha^2 +%assign _tweak2 _tweak1+sizeof(oword) ; * alpha^3 +%assign _tweak3 _tweak2+sizeof(oword) ; * alpha^4 +%assign _nr _tweak3+sizeof(oword) ; # rounds +%assign _sp _nr+sizeof(dword) ; esp +%assign stackSize _sp+sizeof(dword) ; stack size + + mov eax, esp + sub esp, stackSize ; aligned stack + and esp, (-16) + mov dword [esp+_sp], eax ; store esp + + mov eax, pTweak + movdqu xmm4, oword [eax] ; initial tweak + movdqa xmm7, xmm4 + + mov eax, 087h ; create tweakCnt = {0x01:0x87} + mov ecx, 1 + movd xmm0, eax + movd xmm1, ecx + punpcklqdq xmm0, xmm1 + + mov ecx,pKey ; key material address + mov edx,blks ; num of blocks + + ; move parameters to local stack frame + mov eax,nr ; num of rounds + movdqa oword [esp+_tweakCnt], xmm0 + mov dword [esp+_nr], eax + + sub edx, BLKS_PER_LOOP + jl .short_input + jmp .blks_loop_ep + +;; +;; pipelined processing +;; +.blks_loop: + MUL_X xmm4, xmm7, xmm1, xmm0 +.blks_loop_ep: + movdqa oword [esp+_tweak0], xmm4 + MUL_X xmm5, xmm4, xmm1, xmm0 + movdqa oword [esp+_tweak1], xmm5 + MUL_X xmm6, xmm5, xmm1, xmm0 + movdqa oword [esp+_tweak2], xmm6 + MUL_X xmm7, xmm6, xmm1, xmm0 + movdqa oword [esp+_tweak3], xmm7 + + movdqu xmm0, oword [esi+0*BYTES_PER_BLK] ; get input blocks + movdqu xmm1, oword [esi+1*BYTES_PER_BLK] + movdqu xmm2, oword [esi+2*BYTES_PER_BLK] + movdqu xmm3, oword [esi+3*BYTES_PER_BLK] + add esi, BYTES_PER_BLK*BLKS_PER_LOOP + + pxor xmm0, xmm4 ; tweak pre-whitening + pxor xmm1, xmm5 + pxor xmm2, xmm6 + pxor xmm3, xmm7 + + movdqa xmm4, oword [ecx] ; keys for whitening + lea ebx, [ecx+BYTES_PER_BLK]; pointer to the round's key material + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [ebx] ; pre load round keys + add ebx, BYTES_PER_BLK + sub eax, 1 +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [ebx] + add ebx, BYTES_PER_BLK + dec eax + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round + aesenclast xmm1, xmm4 + aesenclast xmm2, xmm4 + aesenclast xmm3, xmm4 + + movdqa xmm4, oword [esp+_tweak0] ; tweak post-whitening + movdqa xmm5, oword [esp+_tweak1] + movdqa xmm6, oword [esp+_tweak2] + movdqa xmm7, oword [esp+_tweak3] + pxor xmm0, xmm4 + pxor xmm1, xmm5 + pxor xmm2, xmm6 + pxor xmm3, xmm7 + + movdqu oword [edi+0*BYTES_PER_BLK], xmm0 ; store output blocks + movdqu oword [edi+1*BYTES_PER_BLK], xmm1 + movdqu oword [edi+2*BYTES_PER_BLK], xmm2 + movdqu oword [edi+3*BYTES_PER_BLK], xmm3 + add edi, BYTES_PER_BLK*BLKS_PER_LOOP + + movdqa xmm0, oword [esp+_tweakCnt] ; restore tweak const + mov eax, dword [esp+_nr] ; number of rounds + sub edx, BLKS_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add edx, BLKS_PER_LOOP + jz .quit + + mov eax, dword [esp+_nr] ; bottom of the keys + lea ebx,[eax*sizeof(dword)] + lea ebx,[ecx+ebx*4-9*(SC)*4] ; AES-128 keys + jmp .single_blk_loop_ep + +.single_blk_loop: + MUL_X xmm7, xmm7, xmm1, xmm0 + +.single_blk_loop_ep: + movdqu xmm1, oword [esi] ; input block + add esi, BYTES_PER_BLK + pxor xmm1, xmm7 ; tweak pre-whitening + pxor xmm1, oword [ecx] ; AES whitening + + cmp eax,12 ; switch according to number of rounds + jl .key_128_s + +.key_256_s: + aesenc xmm1,oword [ebx-4*4*SC] + aesenc xmm1,oword [ebx-3*4*SC] + aesenc xmm1,oword [ebx-2*4*SC] + aesenc xmm1,oword [ebx-1*4*SC] +.key_128_s: + aesenc xmm1,oword [ebx+0*4*SC] + aesenc xmm1,oword [ebx+1*4*SC] + aesenc xmm1,oword [ebx+2*4*SC] + aesenc xmm1,oword [ebx+3*4*SC] + aesenc xmm1,oword [ebx+4*4*SC] + aesenc xmm1,oword [ebx+5*4*SC] + aesenc xmm1,oword [ebx+6*4*SC] + aesenc xmm1,oword [ebx+7*4*SC] + aesenc xmm1,oword [ebx+8*4*SC] + aesenclast xmm1,oword [ebx+9*4*SC] + + pxor xmm1, xmm7 ; tweak post-whitening + movdqu oword [edi], xmm1 ; output block + add edi, BYTES_PER_BLK + + sub edx, 1 + jnz .single_blk_loop + +.quit: + mov eax, pTweak ; save tweak + movdqu oword [eax], xmm7 + + mov esp, [esp+_sp] + REST_GPR + ret +ENDFUNC cpAESEncryptXTS_AES_NI +%endif + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safedecm5as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safedecm5as.asm new file mode 100644 index 000000000..c0c7d987b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safedecm5as.asm @@ -0,0 +1,448 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael-128 (AES) inverse cipher functions. +; (It's the special free from Sbox/tables implementation) +; +; Content: +; SafeDecrypt_RIJ128() +; +; History: +; +; Notes. +; The implementation is based on compact S-box usage. +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP == _IPP_M5) + +;; +;; transpose 16x16 martix to [dst] +;; eax,ebx,ecx,edx constins matrix rows +;; +%macro TRANSPOSE 1.nolist + %xdefine %%dst %1 + + mov byte [%%dst+0 ], al + shr eax, 8 + mov byte [%%dst+1 ], bl + shr ebx, 8 + mov byte [%%dst+2 ], cl + shr ecx, 8 + mov byte [%%dst+3 ], dl + shr edx, 8 + + mov byte [%%dst+4 ], al + shr eax, 8 + mov byte [%%dst+5 ], bl + shr ebx, 8 + mov byte [%%dst+6 ], cl + shr ecx, 8 + mov byte [%%dst+7 ], dl + shr edx, 8 + + mov byte [%%dst+8 ], al + shr eax, 8 + mov byte [%%dst+9 ], bl + shr ebx, 8 + mov byte [%%dst+10], cl + shr ecx, 8 + mov byte [%%dst+11], dl + shr edx, 8 + + mov byte [%%dst+12], al + shr eax, 8 + mov byte [%%dst+13], bl + shr ebx, 8 + mov byte [%%dst+14], cl + shr ecx, 8 + mov byte [%%dst+15], dl + shr edx, 8 +%endmacro + + +;; +;; SubBute +;; +%macro SBOX_ZERO 1.nolist + %xdefine %%inpb %1 + + mov al, byte [esi+%%inpb] +%endmacro + + +%macro SBOX_QUAD 1.nolist + %xdefine %%inpb %1 + + mov eax, 03Fh + and eax, %%inpb ; x%64 + shr %%inpb, 6 ; x/64 + add esi, eax ; &Sbox[x%64] + + mov al, byte [esi+64*0] + mov bl, byte [esi+64*1] + mov cl, byte [esi+64*2] + mov dl, byte [esi+64*3] + mov byte [esp+oBuffer+1*0], al + mov byte [esp+oBuffer+1*1], bl + mov byte [esp+oBuffer+1*2], cl + mov byte [esp+oBuffer+1*3], dl + + mov al, byte [esp+oBuffer+%%inpb] +%endmacro + + +%macro SBOX_FULL 1.nolist + %xdefine %%inpb %1 + + mov eax, 0Fh + and eax, %%inpb ; x%16 + shr %%inpb, 4 ; x/16 + add esi, eax ; &Sbox[x%16] + + movzx eax, byte [esi+16*15] + movzx ebx, byte [esi+16*14] + movzx ecx, byte [esi+16*13] + movzx edx, byte [esi+16*12] + push eax + push ebx + push ecx + push edx + + movzx eax, byte [esi+16*11] + movzx ebx, byte [esi+16*10] + movzx ecx, byte [esi+16*9] + movzx edx, byte [esi+16*8] + push eax + push ebx + push ecx + push edx + + movzx eax, byte [esi+16*7] + movzx ebx, byte [esi+16*6] + movzx ecx, byte [esi+16*5] + movzx edx, byte [esi+16*4] + push eax + push ebx + push ecx + push edx + + movzx eax, byte [esi+16*3] + movzx ebx, byte [esi+16*2] + movzx ecx, byte [esi+16*1] + movzx edx, byte [esi+16*0] + push eax + push ebx + push ecx + push edx + + mov eax, dword [esp+%%inpb*sizeof(dword)] + add esp, 16*sizeof(dword) +%endmacro + + +;; +;; AddRoundKey +;; +%macro ADD_ROUND_KEY 5.nolist + %xdefine %%x0 %1 + %xdefine %%x1 %2 + %xdefine %%x2 %3 + %xdefine %%x3 %4 + %xdefine %%key %5 + + xor %%x0, dword [%%key+sizeof(dword)*0] + xor %%x1, dword [%%key+sizeof(dword)*1] + xor %%x2, dword [%%key+sizeof(dword)*2] + xor %%x3, dword [%%key+sizeof(dword)*3] +%endmacro + + +;; +;; GFMULx x, t0,t1 +;; +;; mask = x & 0x80808080 +;; mask = (mask<<1) - (mask>>7) +;; +;; x = (x<<=1) & 0xFEFEFEFE +;; x ^= msk & 0x1B1B1B1B +;; +%macro GFMULx 3.nolist + %xdefine %%x %1 + %xdefine %%msk %2 + %xdefine %%t %3 + + mov %%t, %%x + add %%x, %%x ;; mul: x = (x<<=1) & 0xFEFEFEFE + and %%t, 080808080h ;; mask: t = x & 0x80808080 + and %%x, 0FEFEFEFEh ;; + lea %%msk, [%%t+%%t] ;; mask: msk = (t<<1) - (t>>7) + shr %%t, 7 ;; mask: + sub %%msk, %%t ;; mask: + and %%msk, 01B1B1B1Bh ;; mul: x ^= msk & 0x1B1B1B1B + xor %%x, %%msk +%endmacro + + +;; +;; MixColumn +;; +%macro MIX_COLUMNS 6.nolist + %xdefine %%x0 %1 + %xdefine %%x1 %2 + %xdefine %%x2 %3 + %xdefine %%x3 %4 + %xdefine %%t0 %5 + %xdefine %%t1 %6 + + ;; Ipp32u y0 = state[1] ^ state[2] ^ state[3]; + ;; Ipp32u y1 = state[0] ^ state[2] ^ state[3]; + ;; Ipp32u y2 = state[0] ^ state[1] ^ state[3]; + ;; Ipp32u y3 = state[0] ^ state[1] ^ state[2]; + mov %%t0, %%x1 + xor %%t0, %%x2 + xor %%t0, %%x3 + mov %%t1, %%x0 + xor %%t1, %%x2 + xor %%t1, %%x3 + mov dword [esp+oBuffer+sizeof(dword)*0], %%t0 + mov dword [esp+oBuffer+sizeof(dword)*1], %%t1 + mov %%t0, %%x0 + xor %%t0, %%x1 + xor %%t0, %%x3 + mov %%t1, %%x0 + xor %%t1, %%x1 + xor %%t1, %%x2 + mov dword [esp+oBuffer+sizeof(dword)*2], %%t0 + mov dword [esp+oBuffer+sizeof(dword)*3], %%t1 + + ;; state[0] = xtime4(state[0]); + ;; state[1] = xtime4(state[1]); + ;; state[2] = xtime4(state[2]); + ;; state[3] = xtime4(state[3]); + GFMULx %%x0, %%t0,%%t1 + GFMULx %%x1, %%t0,%%t1 + GFMULx %%x2, %%t0,%%t1 + GFMULx %%x3, %%t0,%%t1 + + ;; y0 ^= state[0] ^ state[1]; + ;; y1 ^= state[1] ^ state[2]; + ;; y2 ^= state[2] ^ state[3]; + ;; y3 ^= state[3] ^ state[0]; + mov %%t0, dword [esp+oBuffer+sizeof(dword)*0] + mov %%t1, dword [esp+oBuffer+sizeof(dword)*1] + xor %%t0, %%x0 + xor %%t1, %%x1 + xor %%t0, %%x1 + xor %%t1, %%x2 + mov dword [esp+oBuffer+sizeof(dword)*0], %%t0 + mov dword [esp+oBuffer+sizeof(dword)*1], %%t1 + + mov %%t0, dword [esp+oBuffer+sizeof(dword)*2] + mov %%t1, dword [esp+oBuffer+sizeof(dword)*3] + xor %%t0, %%x2 + xor %%t1, %%x3 + xor %%t0, %%x3 + xor %%t1, %%x0 + mov dword [esp+oBuffer+sizeof(dword)*2], %%t0 + mov dword [esp+oBuffer+sizeof(dword)*3], %%t1 + + ;; t02 = state[0] ^ state[2]; + ;; t13 = state[1] ^ state[3]; + ;; t02 = xtime4(t02); + ;; t13 = xtime4(t13); + mov %%t0, %%x0 + mov %%t1, %%x1 + xor %%t0, %%x2 + xor %%t1, %%x3 + GFMULx %%t0, %%x0,%%x1 ;; t02 + GFMULx %%t1, %%x0,%%x1 ;; t13 + + ;; t0123 = t02^t13; + ;; t0123 = xtime4(t0123); + mov %%x0, %%t0 + xor %%x0, %%t1 + GFMULx %%x0, %%x1,%%x2 + + ;; state[0] = y0 ^t02 ^t0123; + ;; state[1] = y1 ^t13 ^t0123; + ;; state[2] = y2 ^t02 ^t0123; + ;; state[3] = y3 ^t13 ^t0123; + xor %%t0, %%x0 ;; t02^t0123 + xor %%t1, %%x0 ;; t13^t0123 + mov %%x0, dword [esp+oBuffer+sizeof(dword)*0] + mov %%x1, dword [esp+oBuffer+sizeof(dword)*1] + mov %%x2, dword [esp+oBuffer+sizeof(dword)*2] + mov %%x3, dword [esp+oBuffer+sizeof(dword)*3] + xor %%x0, %%t0 + xor %%x1, %%t1 + xor %%x2, %%t0 + xor %%x3, %%t1 +%endmacro + + +segment .text align=IPP_ALIGN_FACTOR + +IPPASM Safe2Decrypt_RIJ128,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pInp [ebp + ARG_1 + 0*sizeof(dword)] ; input buffer +%xdefine pOut [ebp + ARG_1 + 1*sizeof(dword)] ; outpu buffer +%xdefine nrounds [ebp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pRK [ebp + ARG_1 + 3*sizeof(dword)] ; round keys +%xdefine pSbox [ebp + ARG_1 + 4*sizeof(dword)] ; S-box + +;; stack +%assign oState 0 ; 4*dword state +%assign oBuffer oState+sizeof(dword)*4 ; 4*dword buffer +%assign oSbox oBuffer+sizeof(dword)*4 ; S-box address +%assign oSaveEBP oSbox+sizeof(dword) ; save EBP slot + +%assign stackSize oSaveEBP+sizeof(dword) ; stack size + + sub esp, stackSize ; state on the stack + + mov edi, nrounds + + ; read input block and transpose one + mov esi, pInp + mov eax, dword [esi+sizeof(dword)*0] + mov ebx, dword [esi+sizeof(dword)*1] + mov ecx, dword [esi+sizeof(dword)*2] + mov edx, dword [esi+sizeof(dword)*3] + TRANSPOSE {esp+oState} + + shl edi, 4 ; nrounds*16 + mov esi, pRK + add esi, edi + + ; read input block + mov eax, dword [esp+oState+sizeof(dword)*0] + mov ebx, dword [esp+oState+sizeof(dword)*1] + mov ecx, dword [esp+oState+sizeof(dword)*2] + mov edx, dword [esp+oState+sizeof(dword)*3] + + ; add round key + ADD_ROUND_KEY eax,ebx,ecx,edx, esi ; add round key + sub esi, sizeof(byte)*16 + mov pRK, esi + mov dword [esp+oState+sizeof(dword)*0], eax + mov dword [esp+oState+sizeof(dword)*1], ebx + mov dword [esp+oState+sizeof(dword)*2], ecx + mov dword [esp+oState+sizeof(dword)*3], edx + + dec nrounds + mov esi, pSbox + mov dword [esp+oSbox], esi + mov dword [esp+oSaveEBP], ebp + + ;; regular rounds +.next_aes_round: + + ;; shift rows + ror ebx, 24 + ror ecx, 16 + ror edx, 8 + mov dword [esp+oState+sizeof(dword)*0], eax + mov dword [esp+oState+sizeof(dword)*1], ebx + mov dword [esp+oState+sizeof(dword)*2], ecx + mov dword [esp+oState+sizeof(dword)*3], edx + + ;; sub bytes + xor ebp, ebp +.sub_byte_loop: + mov esi, dword [esp+oSbox] ; Sbox address + movzx edi, byte [esp+oState+ebp] ; x input byte + add ebp, 1 + SBOX_FULL edi + ;;SBOX_QUAD edi + ;;SBOX_ZERO edi + mov byte [esp+oState+ebp-1], al + cmp ebp, 16 + jl .sub_byte_loop + + ;; add round key + mov ebp, dword [esp+oSaveEBP] + mov esi, pRK + + mov eax, dword [esp+oState+sizeof(dword)*0] + mov ebx, dword [esp+oState+sizeof(dword)*1] + mov ecx, dword [esp+oState+sizeof(dword)*2] + mov edx, dword [esp+oState+sizeof(dword)*3] + ADD_ROUND_KEY eax,ebx,ecx,edx, esi ; add round key + sub esi, sizeof(byte)*16 + mov pRK, esi + + ;; mix columns + MIX_COLUMNS eax,ebx,ecx,edx, esi, edi ; mix columns + + sub nrounds, 1 + jne .next_aes_round + + ;; irregular round: shift rows + ror ebx, 24 + ror ecx, 16 + ror edx, 8 + mov dword [esp+oState+sizeof(dword)*0], eax + mov dword [esp+oState+sizeof(dword)*1], ebx + mov dword [esp+oState+sizeof(dword)*2], ecx + mov dword [esp+oState+sizeof(dword)*3], edx + + ;; irregular round: sub bytes + xor ebp, ebp +.sub_byte_irr_loop: + mov esi, dword [esp+oSbox] + movzx edi, byte [esp+oState+ebp] ; x input byte + add ebp, 1 + SBOX_FULL edi + ;;SBOX_QUAD edi + ;;SBOX_ZERO edi + mov byte [esp+oState+ebp-1], al + cmp ebp, 16 + jl .sub_byte_irr_loop + + ;; irregular round: add round key + mov ebp, dword [esp+oSaveEBP] + mov esi, pRK + + mov eax, dword [esp+oState+sizeof(dword)*0] + mov ebx, dword [esp+oState+sizeof(dword)*1] + mov ecx, dword [esp+oState+sizeof(dword)*2] + mov edx, dword [esp+oState+sizeof(dword)*3] + ADD_ROUND_KEY eax,ebx,ecx,edx, esi ; add round key + + mov edi, pOut + TRANSPOSE edi + + add esp, stackSize ; remove state + REST_GPR + ret +ENDFUNC Safe2Decrypt_RIJ128 + + +%endif ; _IPP == _IPP_M5 diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safedecv8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safedecv8as.asm new file mode 100644 index 000000000..fdbfe894c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safedecv8as.asm @@ -0,0 +1,442 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael-128 (AES) cipher functions. +; (It's the special free from Sbox/tables implementation) +; +; Content: +; SafeDecrypt_RIJ128() +; +; History: +; +; Notes. +; The implementation is based on +; isomorphism between native GF(2^8) and composite GF((2^4)^2). +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_V8) + +%macro PTRANSFORM 6.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%memTransLO %3 + %xdefine %%memTransHI %4 + %xdefine %%tmp %5 + %xdefine %%srcLO %6 + + movdqa %%dst, oword [%%memTransLO] ;; LO transformation + movdqa %%tmp, oword [%%memTransHI] ;; HI transformation + + movdqa %%srcLO, %%src ;; split src: + psrlw %%src, 4 ;; + pand %%srcLO, xmm7 ;; low 4 bits -> srcLO + pand %%src, xmm7 ;; upper 4 bits -> src + + pshufb %%dst, %%srcLO ;; transformation + pshufb %%tmp, %%src + pxor %%dst, %%tmp +%endmacro + + +%macro PLOOKUP_MEM 3.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%Table %3 + + movdqa %%dst, OWORD %%Table + pshufb %%dst,%%src +%endmacro + + +%macro PREDUCE_MOD15 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + movdqa %%dst, %%src + pcmpgtb %%src, xmm7 + psubb %%dst, %%src +%endmacro + + +%macro PINVERSE_GF16_INV 6.nolist + %xdefine %%xmmB %1 + %xdefine %%xmmC %2 + %xdefine %%xmmP %3 + %xdefine %%xmmQ %4 + %xdefine %%xmmD %5 + %xdefine %%xmmT %6 + + PLOOKUP_MEM %%xmmT, %%xmmC, [eax+(GF16_logTbl-DECODE_DATA)] ;; xmmT = index_of(c) + pxor %%xmmC, %%xmmB + PLOOKUP_MEM %%xmmQ, %%xmmC, [eax+(GF16_logTbl-DECODE_DATA)] ;; xmmQ = index_of(b xor c) + + PLOOKUP_MEM %%xmmD, %%xmmB, [eax+(GF16_sqr1-DECODE_DATA)] ;; xmmD = sqr(b)*beta^14 + PLOOKUP_MEM %%xmmP, %%xmmB, [eax+(GF16_logTbl-DECODE_DATA)] ;; xmmP = index_of(b) + + paddb %%xmmT, %%xmmQ ;; xmmT = index_of(c) + index_of(b xor c) + PREDUCE_MOD15 %%xmmC, %%xmmT ;; + PLOOKUP_MEM %%xmmT, %%xmmC, [eax+(GF16_expTbl-DECODE_DATA)] ;; c*(b xor c) + + pxor %%xmmD, %%xmmT ;; xmmD = delta = (c*(b xor c)) xor (sqr(b)*beta^14) + PLOOKUP_MEM %%xmmT, %%xmmD, [eax+(GF16_invLog-DECODE_DATA)] ;; xmmT = index_of( inv(delta) ) + + paddb %%xmmQ, %%xmmT ;; xmmQ = index_of((b xor c) * inv(delta)) + paddb %%xmmP, %%xmmT ;; xmmP = index_of(b * inv(delta)) + PREDUCE_MOD15 %%xmmT, %%xmmQ + PLOOKUP_MEM %%xmmC, %%xmmT, [eax+(GF16_expTbl-DECODE_DATA)] + PREDUCE_MOD15 %%xmmT, %%xmmP + PLOOKUP_MEM %%xmmB, %%xmmT, [eax+(GF16_expTbl-DECODE_DATA)] +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +DECODE_DATA: + +;; (forward) native GF(2^8) to composite GF((2^4)^2) transformation : {0x01,0x2E,0x49,0x43,0x35,0xD0,0x3D,0xE9} +TransFwdLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 02Eh ;; 02Eh ;; 2 + DB 02Fh ;; 02Eh XOR 001h ;; 3 + DB 049h ;; 049h ;; 4 + DB 048h ;; 049h XOR 001h ;; 5 + DB 067h ;; 049h XOR 02Eh ;; 6 + DB 066h ;; 049h XOR 02Eh XOR 001h ;; 7 + DB 043h ;; 043h ;; 8 + DB 042h ;; 043h XOR 001h ;; 9 + DB 06Dh ;; 043h XOR 02Eh ;; a + DB 06Ch ;; 043h XOR 02Eh XOR 001h ;; b + DB 00Ah ;; 043h XOR 049h ;; c + DB 00Bh ;; 043h XOR 049h XOR 001h ;; d + DB 024h ;; 043h XOR 049h XOR 02Eh ;; e + DB 025h ;; 043h XOR 049h XOR 02Eh XOR 001h ;; f +TransFwdHI \ + DB 000h ;; 000h ;; 0 + DB 035h ;; 035h ;; 1 + DB 0D0h ;; 0D0h ;; 2 + DB 0E5h ;; 0D0h XOR 035h ;; 3 + DB 03Dh ;; 03Dh ;; 4 + DB 008h ;; 03Dh XOR 035h ;; 5 + DB 0EDh ;; 03Dh XOR 0D0h ;; 6 + DB 0D8h ;; 03Dh XOR 0D0h XOR 035h ;; 7 + DB 0E9h ;; 0E9h ;; 8 + DB 0DCh ;; 0E9h XOR 035h ;; 9 + DB 039h ;; 0E9h XOR 0D0h ;; a + DB 00Ch ;; 0E9h XOR 0D0h XOR 035h ;; b + DB 0D4h ;; 0E9h XOR 03Dh ;; c + DB 0E1h ;; 0E9h XOR 03Dh XOR 035h ;; d + DB 004h ;; 0E9h XOR 03Dh XOR 0D0h ;; e + DB 031h ;; 0E9h XOR 03Dh XOR 0D0h XOR 035h ;; f + +;; (inverse) composite GF((2^4)^2) to native GF(2^8) transformation : {0x01,0x5C,0xE0,0x50,0x1F,0xEE,0x55,0x6A} +TransInvLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 05Ch ;; 05Ch ;; 2 + DB 05Dh ;; 05Ch XOR 001h ;; 3 + DB 0E0h ;; 0E0h ;; 4 + DB 0E1h ;; 0E0h XOR 001h ;; 5 + DB 0BCh ;; 0E0h XOR 05Ch ;; 6 + DB 0BDh ;; 0E0h XOR 05Ch XOR 001h ;; 7 + DB 050h ;; 050h ;; 8 + DB 051h ;; 050h XOR 001h ;; 9 + DB 00Ch ;; 050h XOR 05Ch ;; a + DB 00Dh ;; 050h XOR 05Ch XOR 001h ;; b + DB 0B0h ;; 050h XOR 0E0h ;; c + DB 0B1h ;; 050h XOR 0E0h XOR 001h ;; d + DB 0ECh ;; 050h XOR 0E0h XOR 05Ch ;; e + DB 0EDh ;; 050h XOR 0E0h XOR 05Ch XOR 001h ;; f +TransInvHI \ + DB 000h ;; 000h ;; 0 + DB 01Fh ;; 01Fh ;; 1 + DB 0EEh ;; 0EEh ;; 2 + DB 0F1h ;; 0EEh XOR 01Fh ;; 3 + DB 055h ;; 055h ;; 4 + DB 04Ah ;; 055h XOR 01Fh ;; 5 + DB 0BBh ;; 055h XOR 0EEh ;; 6 + DB 0A4h ;; 055h XOR 0EEh XOR 01Fh ;; 7 + DB 06Ah ;; 06Ah ;; 8 + DB 075h ;; 06Ah XOR 01Fh ;; 9 + DB 084h ;; 06Ah XOR 0EEh ;; a + DB 09Bh ;; 06Ah XOR 0EEh XOR 01Fh ;; b + DB 03Fh ;; 06Ah XOR 055h ;; c + DB 020h ;; 06Ah XOR 055h XOR 01Fh ;; d + DB 0D1h ;; 06Ah XOR 055h XOR 0EEh ;; e + DB 0CEh ;; 06Ah XOR 055h XOR 0EEh XOR 01Fh ;; f + + +GF16_csize DB 00Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh + +;; GF16 elements: +;; 0 1 2 3 4 5 6 7 8 9 A B C D E F +GF16_logTbl \ + DB 0C0h,00h,01h,04h,02h,08h,05h,0Ah,03h,0Eh,09h,07h,06h,0Dh,0Bh,0Ch +GF16_expTbl \ + DB 001h,02h,04h,08h,03h,06h,0Ch,0Bh,05h,0Ah,07h,0Eh,0Fh,0Dh,09h,01h +GF16_sqr1 \ + DB 000h,09h,02h,0Bh,08h,01h,0Ah,03h,06h,0Fh,04h,0Dh,0Eh,07h,0Ch,05h ;; sqr(GF16_element) * beta^14 +GF16_invLog \ + DB 0C0h,00h,0Eh,0Bh,0Dh,07h,0Ah,05h,0Ch,01h,06h,08h,09h,02h,04h,03h + +;; affine transformation matrix (inverse cipher) : {0x50,0x36,0x15,0x82,0x01,0x34,0x40,0x3E} +InvAffineLO \ + DB 000h ;; 000h ;; 0 + DB 050h ;; 050h ;; 1 + DB 036h ;; 036h ;; 2 + DB 066h ;; 036h XOR 050h ;; 3 + DB 015h ;; 015h ;; 4 + DB 045h ;; 015h XOR 050h ;; 5 + DB 023h ;; 015h XOR 036h ;; 6 + DB 073h ;; 015h XOR 036h XOR 050h ;; 7 + DB 082h ;; 082h ;; 8 + DB 0D2h ;; 082h XOR 050h ;; 9 + DB 0B4h ;; 082h XOR 036h ;; a + DB 0E4h ;; 082h XOR 036h XOR 050h ;; b + DB 097h ;; 082h XOR 015h ;; c + DB 0C7h ;; 082h XOR 015h XOR 050h ;; d + DB 0A1h ;; 082h XOR 015h XOR 036h ;; e + DB 0F1h ;; 082h XOR 015h XOR 036h XOR 050h ;; f +InvAffineHI \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 034h ;; 034h ;; 2 + DB 035h ;; 034h XOR 001h ;; 3 + DB 040h ;; 040h ;; 4 + DB 041h ;; 040h XOR 001h ;; 5 + DB 074h ;; 040h XOR 034h ;; 6 + DB 075h ;; 040h XOR 034h XOR 001h ;; 7 + DB 03Eh ;; 03Eh ;; 8 + DB 03Fh ;; 03Eh XOR 001h ;; 9 + DB 00Ah ;; 03Eh XOR 034h ;; a + DB 00Bh ;; 03Eh XOR 034h XOR 001h ;; b + DB 07Eh ;; 03Eh XOR 040h ;; c + DB 07Fh ;; 03Eh XOR 040h XOR 001h ;; d + DB 04Ah ;; 03Eh XOR 040h XOR 034h ;; e + DB 04Bh ;; 03Eh XOR 040h XOR 034h XOR 001h ;; f + +;; affine transformation constant (inverse cipher) +InvAffineCnt \ + DQ 04848484848484848h,04848484848484848h + +;; shift rows transformation (inverse cipher) +InvShiftRows \ + DB 0,13,10,7,4,1,14,11,8,5,2,15,12,9,6,3 + +;; mix columns transformation (inverse cipher) +GF16mul_4_2x \ + DB 000h,024h,048h,06Ch,083h,0A7h,0CBh,0EFh,036h,012h,07Eh,05Ah,0B5h,091h,0FDh,0D9h ;; *(4+2x) +GF16mul_1_6x \ + DB 000h,061h,0C2h,0A3h,0B4h,0D5h,076h,017h,058h,039h,09Ah,0FBh,0ECh,08Dh,02Eh,04Fh ;; *(1+6x) + +GF16mul_C_6x \ + DB 000h,06Ch,0CBh,0A7h,0B5h,0D9h,07Eh,012h,05Ah,036h,091h,0FDh,0EFh,083h,024h,048h ;; *(C+6x) +GF16mul_3_Ax \ + DB 000h,0A3h,076h,0D5h,0ECh,04Fh,09Ah,039h,0FBh,058h,08Dh,02Eh,017h,0B4h,061h,0C2h ;; *(3+Ax) + +GF16mul_B_0x \ + DB 000h,00Bh,005h,00Eh,00Ah,001h,00Fh,004h,007h,00Ch,002h,009h,00Dh,006h,008h,003h ;; *(B+0x) +GF16mul_0_Bx \ + DB 000h,0B0h,050h,0E0h,0A0h,010h,0F0h,040h,070h,0C0h,020h,090h,0D0h,060h,080h,030h ;; *(0+Bx) + +GF16mul_2_4x \ + DB 000h,042h,084h,0C6h,038h,07Ah,0BCh,0FEh,063h,021h,0E7h,0A5h,05Bh,019h,0DFh,09Dh ;; *(2+4x) +GF16mul_2_6x \ + DB 000h,062h,0C4h,0A6h,0B8h,0DAh,07Ch,01Eh,053h,031h,097h,0F5h,0EBh,089h,02Fh,04Dh ;; *(2+6x) + +ColumnROR \ + DB 1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12 + + +;************************************************************* +; convert GF(2^128) -> GF((2^4)^2) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM TransformNative2Composite,PUBLIC + USES_GPR esi,edi + +%xdefine pOutBlk [esp + ARG_1 + 0*sizeof(dword)] ; output block address +%xdefine pInpBlk [esp + ARG_1 + 1*sizeof(dword)] ; input block address + + LD_ADDR eax, DECODE_DATA + mov edi,pOutBlk ; output data address + mov esi,pInpBlk ; input data address + movdqa xmm7, oword [eax+(GF16_csize-DECODE_DATA)] + + ;; convert input into the composite GF((2^4)^2) + movdqu xmm0, oword [esi] ; input block + PTRANSFORM xmm1, xmm0, {eax+(TransFwdLO-DECODE_DATA)},{eax+(TransFwdHI-DECODE_DATA)}, xmm2, xmm3 + + movdqu oword [edi], xmm1 ; output block + REST_GPR + ret +ENDFUNC TransformNative2Composite + +align IPP_ALIGN_FACTOR +;************************************************************* +;* void SafeDecrypt_RIJ128( +;* const Ipp32u* pInpBlk, +;* Ipp32u* pOutBlk, +;* int nr, +;* const Ipp32u* pKeys, +;* const void* Tables) +;************************************************************* + +;; +;; Lib = V8 +;; +IPPASM SafeDecrypt_RIJ128,PUBLIC + USES_GPR esi,edi + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address + +%assign RSIZE sizeof(dword) ; size of row +%assign SC 4 ; columns in STATE +%assign SSIZE RSIZE*SC ; size of state + + mov edx, pKey + mov ecx, nr + mov esi,pInpBlk ; input data address + mov edi,pOutBlk ; output data address + + lea eax,[ecx*4] + lea edx,[edx+eax*4] ; AES-128-keys + + LD_ADDR eax, DECODE_DATA + + movdqu xmm0, oword [esi] ; input block + + movdqa xmm7, oword [eax+(GF16_csize-DECODE_DATA)] + + + ;; convert input into the composite GF((2^4)^2) + PTRANSFORM xmm2,xmm0, {eax+(TransFwdLO-DECODE_DATA)},{eax+(TransFwdHI-DECODE_DATA)}, xmm1,xmm3 + + ;; initial whitening + pxor xmm2, oword [edx] + sub edx, SSIZE + + ;; (nr-1) regular rounds + sub ecx,1 + +.decode_round: + ;; InvSubByte() Transformation: + + ;; affine transformation + PTRANSFORM xmm0,xmm2, {eax+(InvAffineLO-DECODE_DATA)},{eax+(InvAffineHI-DECODE_DATA)}, xmm1,xmm3 + pxor xmm0, oword [eax+(InvAffineCnt-DECODE_DATA)] ; H(c), c=0x05 + + ;; split input by low and upper parts + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; upper parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; low parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_INV xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; InvShiftRows() Transformation: + pshufb xmm0, [eax+(InvShiftRows-DECODE_DATA)] + pshufb xmm1, [eax+(InvShiftRows-DECODE_DATA)] + + ;; InvMixColumn() Transformation: + PLOOKUP_MEM xmm2, xmm0, [eax+(GF16mul_4_2x-DECODE_DATA)] ; mul H(0xE) = 0x24 + pshufb xmm0, [eax+(ColumnROR-DECODE_DATA)] + PLOOKUP_MEM xmm3, xmm1, [eax+(GF16mul_1_6x-DECODE_DATA)] + pshufb xmm1, [eax+(ColumnROR-DECODE_DATA)] + pxor xmm2, xmm3 + + PLOOKUP_MEM xmm3, xmm0, [eax+(GF16mul_C_6x-DECODE_DATA)] ; mul H(0xB) = 0x6C + pshufb xmm0, [eax+(ColumnROR-DECODE_DATA)] + pxor xmm2, xmm3 + PLOOKUP_MEM xmm3, xmm1, [eax+(GF16mul_3_Ax-DECODE_DATA)] + pshufb xmm1, [eax+(ColumnROR-DECODE_DATA)] + pxor xmm2, xmm3 + + PLOOKUP_MEM xmm3, xmm0, [eax+(GF16mul_B_0x-DECODE_DATA)] ; mul H(0xD) = 0x0B + pshufb xmm0, [eax+(ColumnROR-DECODE_DATA)] + pxor xmm2, xmm3 + PLOOKUP_MEM xmm3, xmm1, [eax+(GF16mul_0_Bx-DECODE_DATA)] + pshufb xmm1, [eax+(ColumnROR-DECODE_DATA)] + pxor xmm2, xmm3 + + PLOOKUP_MEM xmm3, xmm0, [eax+(GF16mul_2_4x-DECODE_DATA)] ; mul H(0x9) = 0x42 + pxor xmm2, xmm3 + PLOOKUP_MEM xmm3, xmm1, [eax+(GF16mul_2_6x-DECODE_DATA)] + pxor xmm2, xmm3 + + ;; AddRoundKey() Transformation: + pxor xmm2, oword [edx] + sub edx, SSIZE + + sub ecx,1 + jg .decode_round + + + ;; + ;; the last one is irregular + ;; + + ;; InvSubByte() Transformation: + + ;; affine transformation + PTRANSFORM xmm0,xmm2, {eax+(InvAffineLO-DECODE_DATA)},{eax+(InvAffineHI-DECODE_DATA)}, xmm1,xmm3 + pxor xmm0, oword [eax+(InvAffineCnt-DECODE_DATA)] ; H(c), c=0x05 + + ;; split input by low and upper parts + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; low parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; upper parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_INV xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; InvShiftRows() Transformation: + psllw xmm1, 4 + por xmm1, xmm0 + pshufb xmm1, [eax+(InvShiftRows-DECODE_DATA)] + + ;; AddRoundKey() Transformation: + pxor xmm1, oword [edx] + sub edx, SSIZE + + ;; convert output into the native GF(2^8) + PTRANSFORM xmm0,xmm1, {eax+(TransInvLO-DECODE_DATA)},{eax+(TransInvHI-DECODE_DATA)}, xmm2, xmm3 + + movdqu oword [edi], xmm0 + REST_GPR + ret +ENDFUNC SafeDecrypt_RIJ128 + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safeencv8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safeencv8as.asm new file mode 100644 index 000000000..13f1ab0d2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprij128safeencv8as.asm @@ -0,0 +1,413 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael-128 (AES) cipher functions. +; (It's the special free from Sbox/tables implementation) +; +; Content: +; SafeEncrypt_RIJ128() +; +; History: +; +; Notes. +; The implementation is based on +; isomorphism between native GF(2^8) and composite GF((2^4)^2). +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_V8) + +%macro PTRANSFORM 6.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%memTransLO %3 + %xdefine %%memTransHI %4 + %xdefine %%tmp %5 + %xdefine %%srcLO %6 + + movdqa %%dst, oword [%%memTransLO] ;; LO transformation + movdqa %%tmp, oword [%%memTransHI] ;; HI transformation + + movdqa %%srcLO, %%src ;; split src: + psrlw %%src, 4 ;; + pand %%srcLO, xmm7 ;; low 4 bits -> srcLO + pand %%src, xmm7 ;; upper 4 bits -> src + + pshufb %%dst, %%srcLO ;; transformation + pshufb %%tmp, %%src + pxor %%dst, %%tmp +%endmacro + + +%macro PLOOKUP_MEM 3.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%Table %3 + + movdqa %%dst, OWORD %%Table + pshufb %%dst,%%src +%endmacro + + +%macro PREDUCE_MOD15 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + movdqa %%dst, %%src + pcmpgtb %%src, xmm7 + psubb %%dst, %%src +%endmacro + + + +%macro PINVERSE_GF16_FWD 6.nolist + %xdefine %%xmmB %1 + %xdefine %%xmmC %2 + %xdefine %%xmmP %3 + %xdefine %%xmmQ %4 + %xdefine %%xmmD %5 + %xdefine %%xmmT %6 + + PLOOKUP_MEM %%xmmT, %%xmmC, [eax+(GF16_logTbl-ENCODE_DATA)] ;; xmmT = index_of(c) + pxor %%xmmC, %%xmmB + PLOOKUP_MEM %%xmmQ, %%xmmC, [eax+(GF16_logTbl-ENCODE_DATA)] ;; xmmQ = index_of(b xor c) + + PLOOKUP_MEM %%xmmD, %%xmmB, [eax+(GF16_sqr1-ENCODE_DATA)] ;; xmmD = sqr(b)*beta^14 + PLOOKUP_MEM %%xmmP, %%xmmB, [eax+(GF16_logTbl-ENCODE_DATA)] ;; xmmP = index_of(b) + + paddb %%xmmT, %%xmmQ ;; xmmT = index_of(c) + index_of(b xor c) + PREDUCE_MOD15 %%xmmC, %%xmmT ;; + PLOOKUP_MEM %%xmmT, %%xmmC, [eax+(GF16_expTbl-ENCODE_DATA)] ;; c*(b xor c) + + pxor %%xmmD, %%xmmT ;; xmmD = delta = (c*(b xor c)) xor (sqr(b)*beta^14) + PLOOKUP_MEM %%xmmT, %%xmmD, [eax+(GF16_invLog-ENCODE_DATA)] ;; xmmT = index_of( inv(delta) ) + + paddb %%xmmQ, %%xmmT ;; xmmQ = index_of((b xor c) * inv(delta)) + paddb %%xmmP, %%xmmT ;; xmmP = index_of(b * inv(delta)) + PREDUCE_MOD15 %%xmmT, %%xmmQ + PLOOKUP_MEM %%xmmC, %%xmmT, [eax+(GF16_expTbl-ENCODE_DATA)] + PREDUCE_MOD15 %%xmmT, %%xmmP + PLOOKUP_MEM %%xmmB, %%xmmT, [eax+(GF16_expTbl-ENCODE_DATA)] +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +ENCODE_DATA: + +;; (forward) native GF(2^8) to composite GF((2^4)^2) transformation : {0x01,0x2E,0x49,0x43,0x35,0xD0,0x3D,0xE9} +TransFwdLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 02Eh ;; 02Eh ;; 2 + DB 02Fh ;; 02Eh XOR 001h ;; 3 + DB 049h ;; 049h ;; 4 + DB 048h ;; 049h XOR 001h ;; 5 + DB 067h ;; 049h XOR 02Eh ;; 6 + DB 066h ;; 049h XOR 02Eh XOR 001h ;; 7 + DB 043h ;; 043h ;; 8 + DB 042h ;; 043h XOR 001h ;; 9 + DB 06Dh ;; 043h XOR 02Eh ;; a + DB 06Ch ;; 043h XOR 02Eh XOR 001h ;; b + DB 00Ah ;; 043h XOR 049h ;; c + DB 00Bh ;; 043h XOR 049h XOR 001h ;; d + DB 024h ;; 043h XOR 049h XOR 02Eh ;; e + DB 025h ;; 043h XOR 049h XOR 02Eh XOR 001h ;; f +TransFwdHI \ + DB 000h ;; 000h ;; 0 + DB 035h ;; 035h ;; 1 + DB 0D0h ;; 0D0h ;; 2 + DB 0E5h ;; 0D0h XOR 035h ;; 3 + DB 03Dh ;; 03Dh ;; 4 + DB 008h ;; 03Dh XOR 035h ;; 5 + DB 0EDh ;; 03Dh XOR 0D0h ;; 6 + DB 0D8h ;; 03Dh XOR 0D0h XOR 035h ;; 7 + DB 0E9h ;; 0E9h ;; 8 + DB 0DCh ;; 0E9h XOR 035h ;; 9 + DB 039h ;; 0E9h XOR 0D0h ;; a + DB 00Ch ;; 0E9h XOR 0D0h XOR 035h ;; b + DB 0D4h ;; 0E9h XOR 03Dh ;; c + DB 0E1h ;; 0E9h XOR 03Dh XOR 035h ;; d + DB 004h ;; 0E9h XOR 03Dh XOR 0D0h ;; e + DB 031h ;; 0E9h XOR 03Dh XOR 0D0h XOR 035h ;; f + +;; (inverse) composite GF((2^4)^2) to native GF(2^8) transformation : {0x01,0x5C,0xE0,0x50,0x1F,0xEE,0x55,0x6A} +TransInvLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 05Ch ;; 05Ch ;; 2 + DB 05Dh ;; 05Ch XOR 001h ;; 3 + DB 0E0h ;; 0E0h ;; 4 + DB 0E1h ;; 0E0h XOR 001h ;; 5 + DB 0BCh ;; 0E0h XOR 05Ch ;; 6 + DB 0BDh ;; 0E0h XOR 05Ch XOR 001h ;; 7 + DB 050h ;; 050h ;; 8 + DB 051h ;; 050h XOR 001h ;; 9 + DB 00Ch ;; 050h XOR 05Ch ;; a + DB 00Dh ;; 050h XOR 05Ch XOR 001h ;; b + DB 0B0h ;; 050h XOR 0E0h ;; c + DB 0B1h ;; 050h XOR 0E0h XOR 001h ;; d + DB 0ECh ;; 050h XOR 0E0h XOR 05Ch ;; e + DB 0EDh ;; 050h XOR 0E0h XOR 05Ch XOR 001h ;; f +TransInvHI \ + DB 000h ;; 000h ;; 0 + DB 01Fh ;; 01Fh ;; 1 + DB 0EEh ;; 0EEh ;; 2 + DB 0F1h ;; 0EEh XOR 01Fh ;; 3 + DB 055h ;; 055h ;; 4 + DB 04Ah ;; 055h XOR 01Fh ;; 5 + DB 0BBh ;; 055h XOR 0EEh ;; 6 + DB 0A4h ;; 055h XOR 0EEh XOR 01Fh ;; 7 + DB 06Ah ;; 06Ah ;; 8 + DB 075h ;; 06Ah XOR 01Fh ;; 9 + DB 084h ;; 06Ah XOR 0EEh ;; a + DB 09Bh ;; 06Ah XOR 0EEh XOR 01Fh ;; b + DB 03Fh ;; 06Ah XOR 055h ;; c + DB 020h ;; 06Ah XOR 055h XOR 01Fh ;; d + DB 0D1h ;; 06Ah XOR 055h XOR 0EEh ;; e + DB 0CEh ;; 06Ah XOR 055h XOR 0EEh XOR 01Fh ;; f + + +GF16_csize DB 00Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh + +;; GF16 elements: +;; 0 1 2 3 4 5 6 7 8 9 A B C D E F +GF16_logTbl \ + DB 0C0h,00h,01h,04h,02h,08h,05h,0Ah,03h,0Eh,09h,07h,06h,0Dh,0Bh,0Ch +GF16_expTbl \ + DB 001h,02h,04h,08h,03h,06h,0Ch,0Bh,05h,0Ah,07h,0Eh,0Fh,0Dh,09h,01h +GF16_sqr1 \ + DB 000h,09h,02h,0Bh,08h,01h,0Ah,03h,06h,0Fh,04h,0Dh,0Eh,07h,0Ch,05h ;; sqr(GF16_element) * beta^14 +GF16_invLog \ + DB 0C0h,00h,0Eh,0Bh,0Dh,07h,0Ah,05h,0Ch,01h,06h,08h,09h,02h,04h,03h +GF16_expTbl_shift \ + DB 010h,020h,040h,080h,030h,060h,0C0h,0B0h,050h,0A0h,070h,0E0h,0F0h,0D0h,090h,010h + +;; affine transformation matrix (forward cipher) : {0x10,0x22,0x55,0x82,0x41,0x34,0x40,0x2A} +FwdAffineLO \ + DB 000h ;; 000h ;; 0 + DB 010h ;; 010h ;; 1 + DB 022h ;; 022h ;; 2 + DB 032h ;; 022h XOR 010h ;; 3 + DB 055h ;; 055h ;; 4 + DB 045h ;; 055h XOR 010h ;; 5 + DB 077h ;; 055h XOR 022h ;; 6 + DB 067h ;; 055h XOR 022h XOR 010h ;; 7 + DB 082h ;; 082h ;; 8 + DB 092h ;; 082h XOR 010h ;; 9 + DB 0A0h ;; 082h XOR 022h ;; a + DB 0B0h ;; 082h XOR 022h XOR 010h ;; b + DB 0D7h ;; 082h XOR 055h ;; c + DB 0C7h ;; 082h XOR 055h XOR 010h ;; d + DB 0F5h ;; 082h XOR 055h XOR 022h ;; e + DB 0E5h ;; 082h XOR 055h XOR 022h XOR 010h ;; f +FwdAffineHI \ + DB 000h ;; 000h ;; 0 + DB 041h ;; 041h ;; 1 + DB 034h ;; 034h ;; 2 + DB 075h ;; 034h XOR 041h ;; 3 + DB 040h ;; 040h ;; 4 + DB 001h ;; 040h XOR 041h ;; 5 + DB 074h ;; 040h XOR 034h ;; 6 + DB 035h ;; 040h XOR 034h XOR 041h ;; 7 + DB 02Ah ;; 02Ah ;; 8 + DB 06Bh ;; 02Ah XOR 041h ;; 9 + DB 01Eh ;; 02Ah XOR 034h ;; a + DB 05Fh ;; 02Ah XOR 034h XOR 041h ;; b + DB 06Ah ;; 02Ah XOR 040h ;; c + DB 02Bh ;; 02Ah XOR 040h XOR 041h ;; d + DB 05Eh ;; 02Ah XOR 040h XOR 034h ;; e + DB 01Fh ;; 02Ah XOR 040h XOR 034hXOR 041h ;; f + +;; affine transformation constant (forward cipher) +FwdAffineCnt \ + DQ 0C2C2C2C2C2C2C2C2h,0C2C2C2C2C2C2C2C2h + +;; shift rows transformation (forward cipher) +FwdShiftRows \ + DB 0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11 + +;; mix columns transformation (forward cipher) +GF16mul_E_2x \ + DB 000h,02Eh,04Fh,061h,08Dh,0A3h,0C2h,0ECh,039h,017h,076h,058h,0B4h,09Ah,0FBh,0D5h +GF16mul_1_Cx \ + DB 000h,0C1h,0B2h,073h,054h,095h,0E6h,027h,0A8h,069h,01Ah,0DBh,0FCh,03Dh,04Eh,08Fh + +ColumnROR \ + DB 1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12 + + + +align IPP_ALIGN_FACTOR +;************************************************************* +;* void SafeEncrypt_RIJ128( +;* const Ipp32u* pInpBlk, +;* Ipp32u* pOutBlk, +;* int nr, +;* const Ipp32u* pKeys, +;* const void* Tables); +;* +;************************************************************* + +;; +;; Lib = V8 +;; +IPPASM SafeEncrypt_RIJ128,PUBLIC + USES_GPR esi,edi + +%xdefine pInpBlk [esp + ARG_1 + 0*sizeof(dword)] ; input block address +%xdefine pOutBlk [esp + ARG_1 + 1*sizeof(dword)] ; output block address +%xdefine nr [esp + ARG_1 + 2*sizeof(dword)] ; number of rounds +%xdefine pKey [esp + ARG_1 + 3*sizeof(dword)] ; key material address + +%assign RSIZE sizeof(dword) ; size of row +%assign SC 4 ; columns in STATE +%assign SSIZE RSIZE*SC ; size of state + + mov esi, pInpBlk + mov edi, pOutBlk + mov edx, pKey + mov ecx, nr + + LD_ADDR eax, ENCODE_DATA + + movdqu xmm1, oword [esi] ; input block + + movdqa xmm7, oword [eax+(GF16_csize-ENCODE_DATA)] + + ;; convert input into the composite GF((2^4)^2) + PTRANSFORM xmm0,xmm1, {eax+(TransFwdLO-ENCODE_DATA)},{eax+(TransFwdHI-ENCODE_DATA)}, xmm2,xmm3 + + ;; initial whitening + pxor xmm0, oword [edx] + add edx, SSIZE + + ;; (nr-1) regular rounds + sub ecx,1 + +.encode_round: + ;; SubByte() Transformation: + + ;; split input by low and upper parts + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; low parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; upper parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_FWD xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; affine transformation + movdqa xmm3, oword [eax+(FwdAffineLO-ENCODE_DATA)] + movdqa xmm2, oword [eax+(FwdAffineHI-ENCODE_DATA)] + movdqa xmm4, oword [eax+(FwdAffineCnt-ENCODE_DATA)] ; H(c), c=0x63 + pshufb xmm3, xmm0 + pshufb xmm2, xmm1 + pxor xmm3, xmm4 + pxor xmm3, xmm2 + + ;; ShiftRows() Transformation: + pshufb xmm3, [eax+(FwdShiftRows-ENCODE_DATA)] + + ;; MixColumn() Transformation: + movdqa xmm1, xmm3 + movdqa xmm2, xmm3 + pxor xmm4, xmm4 + psrlw xmm2, 4 + + pand xmm1, xmm7 ;; a0*(0xE + 0x2*t) + PLOOKUP_MEM xmm0, xmm1, [eax+(GF16mul_E_2x-ENCODE_DATA)] + + pand xmm2, xmm7 ;; a1*(0x2*0x9 + (0x2+0xE)*t) + PLOOKUP_MEM xmm1, xmm2, [eax+(GF16mul_1_Cx-ENCODE_DATA)] + + pxor xmm0, xmm1 + + pshufb xmm3, [eax+(ColumnROR-ENCODE_DATA)] + pxor xmm4, xmm3 + + pshufb xmm3, [eax+(ColumnROR-ENCODE_DATA)] + pxor xmm4, xmm3 + + movdqa xmm2, xmm0 + pshufb xmm2, [eax+(ColumnROR-ENCODE_DATA)] + pxor xmm0, xmm2 + + pshufb xmm3, [eax+(ColumnROR-ENCODE_DATA)] + pxor xmm4, xmm3 + + pxor xmm0, xmm4 + + ;; AddRoundKey() Transformation: + pxor xmm0, oword [edx] + add edx, SSIZE + + sub ecx,1 + jg .encode_round + + + ;; + ;; the last one is irregular + ;; + + ;; SubByte() Transformation: + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; low parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; upper parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_FWD xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; affine transformation + movdqa xmm3, oword [eax+(FwdAffineLO-ENCODE_DATA)] + movdqa xmm2, oword [eax+(FwdAffineHI-ENCODE_DATA)] + movdqa xmm4, oword [eax+(FwdAffineCnt-ENCODE_DATA)] ; H(c), c=0x63 + pshufb xmm3, xmm0 + pshufb xmm2, xmm1 + pxor xmm3, xmm4 + pxor xmm3, xmm2 + + ;; ShiftRows() Transformation: + pshufb xmm3, [eax+(FwdShiftRows-ENCODE_DATA)] + + ;; AddRoundKey() Transformation: + pxor xmm3, oword [edx] + add edx, SSIZE + + ;; convert output into the native GF(2^8) + PTRANSFORM xmm0,xmm3, {eax+(TransInvLO-ENCODE_DATA)},{eax+(TransInvHI-ENCODE_DATA)}, xmm2, xmm1 + + movdqu oword [edi], xmm0 + REST_GPR + ret +ENDFUNC SafeEncrypt_RIJ128 + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprijnkeyw7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprijnkeyw7as.asm new file mode 100644 index 000000000..06c924432 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcprijnkeyw7as.asm @@ -0,0 +1,95 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Key Expansion Support +; +; Content: +; SubsDword_8uT() +; +; + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_W7) + +segment .text align=IPP_ALIGN_FACTOR + + +%xdefine CACHE_LINE_SIZE (64) + +;*************************************************************** +;* Purpose: Mitigation of the Key Expansion procedure +;* +;* Ipp32u Touch_SubsDword_8uT(Ipp32u inp, +;* const Ipp8u* pTbl, +;* int tblBytes) +;*************************************************************** +align IPP_ALIGN_FACTOR +IPPASM Touch_SubsDword_8uT,PUBLIC + USES_GPR esi,edi,ebx + +%xdefine inp [esp + ARG_1 + 0*sizeof(dword)] ; input dword +%xdefine pTbl [esp + ARG_1 + 1*sizeof(dword)] ; Rijndael's S-box +%xdefine tblLen [esp + ARG_1 + 2*sizeof(dword)] ; length of table (bytes) + + mov esi, pTbl ; tbl address and + mov edx, tblLen ; length + xor ecx, ecx +.touch_tbl: + mov eax, [esi+ecx] + add ecx, CACHE_LINE_SIZE + cmp ecx, edx + jl .touch_tbl + + mov edx, inp + + mov eax, edx + and eax, 0FFh ; b[0] + movzx eax, BYTE [esi+eax] + + shr edx, 8 + mov ebx, edx + and ebx, 0FFh ; b[1] + movzx ebx, BYTE [esi+ebx] + shl ebx, 8 + + shr edx, 8 + mov ecx, edx + and ecx, 0FFh ; b[2] + movzx ecx, BYTE [esi+ecx] + shl ecx, 16 + + shr edx, 8 + movzx edx, BYTE [esi+edx] + shl edx, 24 + + or eax, ebx + or eax, ecx + or eax, edx + REST_GPR + ret +ENDFUNC Touch_SubsDword_8uT + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha1nias.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha1nias.asm new file mode 100644 index 000000000..6ef5fbbda --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha1nias.asm @@ -0,0 +1,581 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA-1 +; +; Content: +; UpdateSHA1ni +; +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA1_) +%if (_SHA_NI_ENABLING_ == _FEATURE_ON_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +CODE_DATA: +UPPER_DWORD_MASK \ + DQ 00000000000000000h, 0ffffffff00000000h +PSHUFFLE_BYTE_FLIP_MASK \ + DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +align IPP_ALIGN_FACTOR +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA1ni(DigestSHA1 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +%ifndef _VXWORKS + +IPPASM UpdateSHA1ni,PUBLIC + USES_GPR esi,edi,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pDigest [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to the in/out digest +%xdefine pMsg [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to the inp message +%xdefine msgLen [ebp + ARG_1 + 2*sizeof(dword)] ; message length + +%xdefine MBS_SHA1 (64) ; SHA-1 message block length (bytes) + +%xdefine HASH_PTR edi ; 1st arg +%xdefine MSG_PTR esi ; 2nd arg +%xdefine MSG_LEN edx ; 3rd arg + +%xdefine ABCD xmm0 +%xdefine E0 xmm1 ; Need two E's b/c they ping pong +%xdefine E1 xmm2 +%xdefine MSG0 xmm3 +%xdefine MSG1 xmm4 +%xdefine MSG2 xmm5 +%xdefine MSG3 xmm6 +%xdefine SHUF_MASK xmm7 + +; +; stack frame +; +%xdefine abcd_save eax +%xdefine e_save eax+sizeof(oword) +%xdefine frame_size sizeof(oword)+sizeof(oword) + + sub esp, (frame_size+16) + lea eax, [esp+16] + and eax, -16 + + mov MSG_LEN, msgLen ; message length + test MSG_LEN, MSG_LEN + jz .quit + + mov HASH_PTR, pDigest ; digest + mov MSG_PTR, pMsg ; and message pointers + + LD_ADDR ecx, CODE_DATA + +;; load initial hash values + movdqu ABCD, oword [HASH_PTR] + pinsrd E0, dword [HASH_PTR+16], 3 + ;pand E0, oword [UPPER_DWORD_MASK] + pand E0, oword [ecx+(UPPER_DWORD_MASK-CODE_DATA)] + pshufd ABCD, ABCD, 01Bh + + ;movdqa SHUF_MASK, oword [PSHUFFLE_BYTE_FLIP_MASK] + movdqa SHUF_MASK, oword [ecx+(PSHUFFLE_BYTE_FLIP_MASK-CODE_DATA)] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + movdqa oword [abcd_save], ABCD + movdqa oword [e_save], E0 + + ;; rounds 0-3 + movdqu MSG0, oword [MSG_PTR +0*16] + pshufb MSG0, SHUF_MASK + paddd E0, MSG0 + movdqa E1, ABCD + sha1rnds4 ABCD, E0, 0 + ;movdqu oword [rcx+16*0], ABCD + + ;; rounds 4-7 + movdqu MSG1, oword [MSG_PTR +1*16] + pshufb MSG1, SHUF_MASK + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1rnds4 ABCD, E1, 0 + sha1msg1 MSG0, MSG1 + ;movdqu oword [rcx+16*1], ABCD + + ;; rounds 8-11 + movdqu MSG2, oword [MSG_PTR +2*16] + pshufb MSG2, SHUF_MASK + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1rnds4 ABCD, E0, 0 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*2], ABCD + + ;; rounds 12-15 + movdqu MSG3, oword [MSG_PTR +3*16] + pshufb MSG3, SHUF_MASK + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 0 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*3], ABCD + + ;; rounds 16-19 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 0 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*4], ABCD + + ;; rounds 20-23 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 1 + sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*5], ABCD + + ;; rounds 24-27 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 1 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*6], ABCD + + ;; rounds 28-31 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 1 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*7], ABCD + + ;; rounds 32-35 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 1 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*8], ABCD + + ;; rounds 36-39 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 1 + sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*9], ABCD + + ;; rounds 40-43 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 2 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*10], ABCD + + ;; rounds 44-47 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 2 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*11], ABCD + + ;; rounds 48-51 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 2 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*12], ABCD + + ;; rounds 52-55 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 2 + sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*13], ABCD + + ;; rounds 56-59 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 2 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*14], ABCD + + ;; rounds 60-63 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 3 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*15], ABCD + + ;; rounds 64-67 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 3 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*16], ABCD + + ;; rounds 68-71 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 3 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*17], ABCD + + ;; rounds 72-75 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 3 + ;movdqu oword [rcx+16*18], ABCD + + ;; rounds 76-79 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1rnds4 ABCD, E1, 3 + ;movdqu oword [rcx+16*19], ABCD + + ;; add current hash values with previously saved + sha1nexte E0, oword [e_save] + paddd ABCD, oword [abcd_save] + + add MSG_PTR, MBS_SHA1 + sub MSG_LEN, MBS_SHA1 + jg .sha1_block_loop + + ;; write hash values back in the correct order + pshufd ABCD, ABCD, 01Bh + movdqu oword [HASH_PTR], ABCD + pextrd dword [HASH_PTR+16], E0, 3 + +.quit: + add esp, (frame_size+16) + REST_GPR + ret +ENDFUNC UpdateSHA1ni + +%else ;; no sha ni support in VxWorks - therefore we temporary use db +IPPASM UpdateSHA1ni,PUBLIC + USES_GPR esi,edi,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pDigest [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to the in/out digest +%xdefine pMsg [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to the inp message +%xdefine msgLen [ebp + ARG_1 + 2*sizeof(dword)] ; message length + +%xdefine MBS_SHA1 (64) ; SHA-1 message block length (bytes) + +%xdefine HASH_PTR edi ; 1st arg +%xdefine MSG_PTR esi ; 2nd arg +%xdefine MSG_LEN edx ; 3rd arg + +%xdefine ABCD xmm0 +%xdefine E0 xmm1 ; Need two E's b/c they ping pong +%xdefine E1 xmm2 +%xdefine MSG0 xmm3 +%xdefine MSG1 xmm4 +%xdefine MSG2 xmm5 +%xdefine MSG3 xmm6 +%xdefine SHUF_MASK xmm7 + +; +; stack frame +; +%xdefine abcd_save eax +%xdefine e_save eax+sizeof(oword) +%xdefine frame_size sizeof(oword)+sizeof(oword) + + sub esp, (frame_size+16) + lea eax, [esp+16] + and eax, -16 + + mov MSG_LEN, msgLen ; message length + test MSG_LEN, MSG_LEN + jz .quit + + mov HASH_PTR, pDigest ; digest + mov MSG_PTR, pMsg ; and message pointers + + LD_ADDR ecx, CODE_DATA + +;; load initial hash values + movdqu ABCD, oword [HASH_PTR] + pinsrd E0, dword [HASH_PTR+16], 3 + ;pand E0, oword [UPPER_DWORD_MASK] + pand E0, oword [ecx+(UPPER_DWORD_MASK-CODE_DATA)] + pshufd ABCD, ABCD, 01Bh + + ;movdqa SHUF_MASK, oword [PSHUFFLE_BYTE_FLIP_MASK] + movdqa SHUF_MASK, oword [ecx+(PSHUFFLE_BYTE_FLIP_MASK-CODE_DATA)] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + movdqa oword [abcd_save], ABCD + movdqa oword [e_save], E0 + + ;; rounds 0-3 + movdqu MSG0, oword [MSG_PTR +0*16] + pshufb MSG0, SHUF_MASK + paddd E0, MSG0 + movdqa E1, ABCD + db 0FH,03AH,0CCH,0C1H,00H ;; sha1rnds4 ABCD, E0, 0 + ;movdqu oword [rcx+16*0], ABCD + + ;; rounds 4-7 + movdqu MSG1, oword [MSG_PTR +1*16] + pshufb MSG1, SHUF_MASK + db 0FH,038H,0C8H,0D4H ;; sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,03AH,0CCH,0C2H,00H ;; sha1rnds4 ABCD, E1, 0 + db 0FH,038H,0C9H,0DCH ;; sha1msg1 MSG0, MSG1 + ;movdqu oword [rcx+16*1], ABCD + + ;; rounds 8-11 + movdqu MSG2, oword [MSG_PTR +2*16] + pshufb MSG2, SHUF_MASK + db 0FH,038H,0C8H,0CDH ;; sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0FH,03AH,0CCH,0C1H,00H ;; sha1rnds4 ABCD, E0, 0 + db 0FH,038H,0C9H,0E5H ;; sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*2], ABCD + + ;; rounds 12-15 + movdqu MSG3, oword [MSG_PTR +3*16] + pshufb MSG3, SHUF_MASK + db 0FH,038H,0C8H,0D6H ;; sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0FH,038H,0CAH,0DEH ;; sha1msg2 MSG0, MSG3 + db 0FH,03AH,0CCH,0C2H,00H ;; sha1rnds4 ABCD, E1, 0 + db 0FH,038H,0C9H,0EEH ;; sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*3], ABCD + + ;; rounds 16-19 + db 0FH,038H,0C8H,0CBH ;; sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0FH,038H,0CAH,0E3H ;; sha1msg2 MSG1, MSG0 + db 0FH,03AH,0CCH,0C1H,00H ;; sha1rnds4 ABCD, E0, 0 + db 0FH,038H,0C9H,0F3H ;; sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*4], ABCD + + ;; rounds 20-23 + db 0FH,038H,0C8H,0D4H ;; sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,038H,0CAH,0ECH ;; sha1msg2 MSG2, MSG1 + db 0FH,03AH,0CCH,0C2H,01H ;; sha1rnds4 ABCD, E1, 1 + db 0FH,038H,0C9H,0DCH ;; sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*5], ABCD + + ;; rounds 24-27 + db 0FH,038H,0C8H,0CDH ;; sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0FH,038H,0CAH,0F5H ;; sha1msg2 MSG3, MSG2 + db 0FH,03AH,0CCH,0C1H,01H ;; sha1rnds4 ABCD, E0, 1 + db 0FH,038H,0C9H,0E5H ;; sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*6], ABCD + + ;; rounds 28-31 + db 0FH,038H,0C8H,0D6H ;; sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0FH,038H,0CAH,0DEH ;; sha1msg2 MSG0, MSG3 + db 0FH,03AH,0CCH,0C2H,01H ;; sha1rnds4 ABCD, E1, 1 + db 0FH,038H,0C9H,0EEH ;; sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*7], ABCD + + ;; rounds 32-35 + db 0FH,038H,0C8H,0CBH ;; sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0FH,038H,0CAH,0E3H ;; sha1msg2 MSG1, MSG0 + db 0FH,03AH,0CCH,0C1H,01H ;; sha1rnds4 ABCD, E0, 1 + db 0FH,038H,0C9H,0F3H ;; sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*8], ABCD + + ;; rounds 36-39 + db 0FH,038H,0C8H,0D4H ;; sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,038H,0CAH,0ECH ;; sha1msg2 MSG2, MSG1 + db 0FH,03AH,0CCH,0C2H,01H ;; sha1rnds4 ABCD, E1, 1 + db 0FH,038H,0C9H,0DCH ;; sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*9], ABCD + + ;; rounds 40-43 + db 0FH,038H,0C8H,0CDH ;; sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0FH,038H,0CAH,0F5H ;; sha1msg2 MSG3, MSG2 + db 0FH,03AH,0CCH,0C1H,02H ;; sha1rnds4 ABCD, E0, 2 + db 0FH,038H,0C9H,0E5H ;; sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*10], ABCD + + ;; rounds 44-47 + db 0FH,038H,0C8H,0D6H ;; sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0FH,038H,0CAH,0DEH ;; sha1msg2 MSG0, MSG3 + db 0FH,03AH,0CCH,0C2H,02H ;; sha1rnds4 ABCD, E1, 2 + db 0FH,038H,0C9H,0EEH ;; sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*11], ABCD + + ;; rounds 48-51 + db 0FH,038H,0C8H,0CBH ;; sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0FH,038H,0CAH,0E3H ;; sha1msg2 MSG1, MSG0 + db 0FH,03AH,0CCH,0C1H,02H ;; sha1rnds4 ABCD, E0, 2 + db 0FH,038H,0C9H,0F3H ;; sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*12], ABCD + + ;; rounds 52-55 + db 0FH,038H,0C8H,0D4H ;; sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,038H,0CAH,0ECH ;; sha1msg2 MSG2, MSG1 + db 0FH,03AH,0CCH,0C2H,02H ;; sha1rnds4 ABCD, E1, 2 + db 0FH,038H,0C9H,0DCH ;; sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*13], ABCD + + ;; rounds 56-59 + db 0FH,038H,0C8H,0CDH ;; sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0FH,038H,0CAH,0F5H ;; sha1msg2 MSG3, MSG2 + db 0FH,03AH,0CCH,0C1H,02H ;; sha1rnds4 ABCD, E0, 2 + db 0FH,038H,0C9H,0E5H ;; sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*14], ABCD + + ;; rounds 60-63 + db 0FH,038H,0C8H,0D6H ;; sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0FH,038H,0CAH,0DEH ;; sha1msg2 MSG0, MSG3 + db 0FH,03AH,0CCH,0C2H,03H ;; sha1rnds4 ABCD, E1, 3 + db 0FH,038H,0C9H,0EEH ;; sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*15], ABCD + + ;; rounds 64-67 + db 0FH,038H,0C8H,0CBH ;; sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0FH,038H,0CAH,0E3H ;; sha1msg2 MSG1, MSG0 + db 0FH,03AH,0CCH,0C1H,03H ;; sha1rnds4 ABCD, E0, 3 + db 0FH,038H,0C9H,0F3H ;; sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*16], ABCD + + ;; rounds 68-71 + db 0FH,038H,0C8H,0D4H ;; sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,038H,0CAH,0ECH ;; sha1msg2 MSG2, MSG1 + db 0FH,03AH,0CCH,0C2H,03H ;; sha1rnds4 ABCD, E1, 3 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*17], ABCD + + ;; rounds 72-75 + db 0FH,038H,0C8H,0CDH ;; sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0FH,038H,0CAH,0F5H ;; sha1msg2 MSG3, MSG2 + db 0FH,03AH,0CCH,0C1H,03H ;; sha1rnds4 ABCD, E0, 3 + ;movdqu oword [rcx+16*18], ABCD + + ;; rounds 76-79 + db 0FH,038H,0C8H,0D6H ;; sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0FH,03AH,0CCH,0C2H,03H ;; sha1rnds4 ABCD, E1, 3 + ;movdqu oword [rcx+16*19], ABCD + + ;; add current hash values with previously saved + db 0FH,038H,0C8H,048H,10h ;; sha1nexte E0, oword [e_save] + paddd ABCD, oword [abcd_save] + + add MSG_PTR, MBS_SHA1 + sub MSG_LEN, MBS_SHA1 + jg .sha1_block_loop + + ;; write hash values back in the correct order + pshufd ABCD, ABCD, 01Bh + movdqu oword [HASH_PTR], ABCD + pextrd dword [HASH_PTR+16], E0, 3 + +.quit: + add esp, (frame_size+16) + REST_GPR + ret +ENDFUNC UpdateSHA1ni + +%endif ;; VxWorks + +%endif ;; _FEATURE_ON_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA1_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha1w7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha1w7as.asm new file mode 100644 index 000000000..9d37c75de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha1w7as.asm @@ -0,0 +1,524 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA1 +; +; Content: +; UpdateSHA1 +; +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA1_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP >= _IPP_M5) + +;; +;; Magic functions defined in FIPS 180-1 +;; +%macro MAGIC_F0 4.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + + mov %%regF,%%regC + xor %%regF,%%regD + and %%regF,%%regB + xor %%regF,%%regD +%endmacro + + +%macro MAGIC_F1 4.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + + mov %%regF,%%regD + xor %%regF,%%regC + xor %%regF,%%regB +%endmacro + + +%macro MAGIC_F2 5.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regT %5 + + mov %%regF,%%regB + mov %%regT,%%regB + or %%regF,%%regC + and %%regT,%%regC + and %%regF,%%regD + or %%regF,%%regT +%endmacro + + +%macro MAGIC_F3 4.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + + MAGIC_F1 %%regF,%%regB,%%regC,%%regD +%endmacro + + +;; +;; single SHA1 step +;; +;; Ipp32u tmp = ROL(A,5) + MAGIC_Fi(B,C,D) + E + W[t] + CNT[i]; +;; E = D; +;; D = C; +;; C = ROL(B,30); +;; B = A; +;; A = tmp; +;; +%macro SHA1_STEP 10.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%memW %8 + %xdefine %%immCNT %9 + %xdefine %%MAGIC %10 + + add %%regE,%%immCNT + add %%regE,[%%memW] + mov %%regT,%%regA + rol %%regT,5 + add %%regE,%%regT + %%MAGIC %%regF,%%regB,%%regC,%%regD,%%regT ;; FUN = MAGIC_Fi(B,C,D) + rol %%regB,30 + add %%regE,%%regF +%endmacro + + +;; +;; ENDIANNESS +;; +%macro ENDIANNESS 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + %ifnidn %%dst,%%src + mov %%dst,%%src + %endif + bswap %%dst +%endmacro + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Following Macros are especially for new implementation of SHA1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%macro UPDATE 2-3.nolist + %xdefine %%nr %1 + %xdefine %%regU %2 + %xdefine %%regT %3 + + %ifempty %%regT + mov %%regU,[esp+((%%nr-16)&0Fh)*4] + xor %%regU,[esp+((%%nr-14)&0Fh)*4] + xor %%regU,[esp+((%%nr-8) &0Fh)*4] + xor %%regU,[esp+((%%nr-3) &0Fh)*4] + %else + mov %%regU,[esp+((%%nr-16)&0Fh)*4] + mov %%regT,[esp+((%%nr-14)&0Fh)*4] + xor %%regU,%%regT + mov %%regT,[esp+((%%nr-8) &0Fh)*4] + xor %%regU,%%regT + mov %%regT,[esp+((%%nr-3) &0Fh)*4] + xor %%regU,%%regT + %endif + rol %%regU,1 + mov [esp+(%%nr&0Fh)*4],%%regU +%endmacro + + +;; +;; single SHA1 step +;; +;; Ipp32u tmp = ROL(A,5) + MAGIC_Fi(B,C,D) + E + W[t] + CNT[i]; +;; E = D; +;; D = C; +;; C = ROL(B,30); +;; B = A; +;; A = tmp; +;; +%macro SHA1_RND0 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %assign %%immCNT 05A827999h + + MAGIC_F0 %%regF,%%regB,%%regC,%%regD ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[esp+(((%%nr) & 0Fh)*4)] + lea %%regE,[%%regE+%%regF+%%immCNT] + add %%regE,%%regT +%endmacro + + +%macro SHA1_RND1 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %assign %%immCNT 06ED9EBA1h + + MAGIC_F1 %%regF,%%regB,%%regC,%%regD ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[esp+(((%%nr)&0Fh)*4)] + lea %%regE,[%%regE+%%regF+%%immCNT] + add %%regE,%%regT +%endmacro + + +%macro SHA1_RND2 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %assign %%immCNT 08F1BBCDCh + + MAGIC_F2 %%regF,%%regB,%%regC,%%regD,%%regT ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[esp+(((%%nr)&0Fh)*4)] + lea %%regE,[%%regE+%%regF+%%immCNT] + add %%regE,%%regT +%endmacro + + +%macro SHA1_RND3 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %assign %%immCNT 0CA62C1D6h + + MAGIC_F3 %%regF,%%regB,%%regC,%%regD ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[esp+(((%%nr)&0Fh)*4)] + lea %%regE,[%%regE+%%regF+%%immCNT] + add %%regE,%%regT +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA1(DigestSHA1 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +;; +;; Lib = W7,V8 +;; +;; Caller = ippsSHA1Update +;; Caller = ippsSHA1Final +;; Caller = ippsSHA1MessageDigest +;; +;; Caller = ippsHMACSHA1Update +;; Caller = ippsHMACSHA1Final +;; Caller = ippsHMACSHA1MessageDigest +;; +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA1,PUBLIC + USES_GPR esi,edi,ebx,ebp + +%xdefine digest [esp + ARG_1 + 0*sizeof(dword)] ; hash address +%xdefine mblk [esp + ARG_1 + 1*sizeof(dword)] ; buffer address +%xdefine mlen [esp + ARG_1 + 2*sizeof(dword)] ; buffer length +%xdefine pTable [esp + ARG_1 + 3*sizeof(dword)] ; pointer to SHA1 const (dummy) + +%xdefine MBS_SHA1 (64) + +%assign stackSize (16+3) ; stack size + mov eax, pTable ; dummy + mov esi,mblk ; source data address + mov eax,mlen ; data length + mov edi,digest ; hash address + + sub esp,stackSize*4 ; allocate local buffer + mov [esp+stackSize*4-3*4],edi ; save hash address + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + mov [esp+stackSize*4-2*4],esi ; save data address + mov [esp+stackSize*4-1*4],eax ; save data length + +;; +;; initialize the first 16 words in the array W (remember about endian) +;; + xor ecx,ecx +.loop1: + mov eax,[esi+ecx*4+0*4] + mov edx,[esi+ecx*4+1*4] + ENDIANNESS eax,eax + ENDIANNESS edx,edx + mov [esp+ecx*4+0*4],eax + mov [esp+ecx*4+1*4],edx + add ecx,2 + cmp ecx,16 + jl .loop1 + +;; +;; init A, B, C, D, E by the internal digest +;; + mov eax,[edi+0*4] ; r2 = digest[0] (A) + mov ebx,[edi+1*4] ; r3 = digest[1] (B) + mov ecx,[edi+2*4] ; r4 = digest[2] (C) + mov edx,[edi+3*4] ; r5 = digest[3] (D) + mov ebp,[edi+4*4] ; r6 = digest[4] (E) + +;; +;; perform 0-79 steps +;; +;; A, B, C, D, E, TMP,FUN, round +;; ----------------------------------- + SHA1_RND0 eax,ebx,ecx,edx,ebp, esi,edi, 0 + UPDATE 16, esi + SHA1_RND0 ebp,eax,ebx,ecx,edx, esi,edi, 1 + UPDATE 17, esi + SHA1_RND0 edx,ebp,eax,ebx,ecx, esi,edi, 2 + UPDATE 18, esi + SHA1_RND0 ecx,edx,ebp,eax,ebx, esi,edi, 3 + UPDATE 19, esi + SHA1_RND0 ebx,ecx,edx,ebp,eax, esi,edi, 4 + UPDATE 20, esi + SHA1_RND0 eax,ebx,ecx,edx,ebp, esi,edi, 5 + UPDATE 21, esi + SHA1_RND0 ebp,eax,ebx,ecx,edx, esi,edi, 6 + UPDATE 22, esi + SHA1_RND0 edx,ebp,eax,ebx,ecx, esi,edi, 7 + UPDATE 23, esi + SHA1_RND0 ecx,edx,ebp,eax,ebx, esi,edi, 8 + UPDATE 24, esi + SHA1_RND0 ebx,ecx,edx,ebp,eax, esi,edi, 9 + UPDATE 25, esi + SHA1_RND0 eax,ebx,ecx,edx,ebp, esi,edi, 10 + UPDATE 26, esi + SHA1_RND0 ebp,eax,ebx,ecx,edx, esi,edi, 11 + UPDATE 27, esi + SHA1_RND0 edx,ebp,eax,ebx,ecx, esi,edi, 12 + UPDATE 28, esi + SHA1_RND0 ecx,edx,ebp,eax,ebx, esi,edi, 13 + UPDATE 29, esi + SHA1_RND0 ebx,ecx,edx,ebp,eax, esi,edi, 14 + UPDATE 30, esi + SHA1_RND0 eax,ebx,ecx,edx,ebp, esi,edi, 15 + UPDATE 31, esi + SHA1_RND0 ebp,eax,ebx,ecx,edx, esi,edi, 16 + UPDATE 32, esi + SHA1_RND0 edx,ebp,eax,ebx,ecx, esi,edi, 17 + UPDATE 33, esi + SHA1_RND0 ecx,edx,ebp,eax,ebx, esi,edi, 18 + UPDATE 34, esi + SHA1_RND0 ebx,ecx,edx,ebp,eax, esi,edi, 19 + UPDATE 35, esi + + SHA1_RND1 eax,ebx,ecx,edx,ebp, esi,edi, 20 + UPDATE 36, esi + SHA1_RND1 ebp,eax,ebx,ecx,edx, esi,edi, 21 + UPDATE 37, esi + SHA1_RND1 edx,ebp,eax,ebx,ecx, esi,edi, 22 + UPDATE 38, esi + SHA1_RND1 ecx,edx,ebp,eax,ebx, esi,edi, 23 + UPDATE 39, esi + SHA1_RND1 ebx,ecx,edx,ebp,eax, esi,edi, 24 + UPDATE 40, esi + SHA1_RND1 eax,ebx,ecx,edx,ebp, esi,edi, 25 + UPDATE 41, esi + SHA1_RND1 ebp,eax,ebx,ecx,edx, esi,edi, 26 + UPDATE 42, esi + SHA1_RND1 edx,ebp,eax,ebx,ecx, esi,edi, 27 + UPDATE 43, esi + SHA1_RND1 ecx,edx,ebp,eax,ebx, esi,edi, 28 + UPDATE 44, esi + SHA1_RND1 ebx,ecx,edx,ebp,eax, esi,edi, 29 + UPDATE 45, esi + SHA1_RND1 eax,ebx,ecx,edx,ebp, esi,edi, 30 + UPDATE 46, esi + SHA1_RND1 ebp,eax,ebx,ecx,edx, esi,edi, 31 + UPDATE 47, esi + SHA1_RND1 edx,ebp,eax,ebx,ecx, esi,edi, 32 + UPDATE 48, esi + SHA1_RND1 ecx,edx,ebp,eax,ebx, esi,edi, 33 + UPDATE 49, esi + SHA1_RND1 ebx,ecx,edx,ebp,eax, esi,edi, 34 + UPDATE 50, esi + SHA1_RND1 eax,ebx,ecx,edx,ebp, esi,edi, 35 + UPDATE 51, esi + SHA1_RND1 ebp,eax,ebx,ecx,edx, esi,edi, 36 + UPDATE 52, esi + SHA1_RND1 edx,ebp,eax,ebx,ecx, esi,edi, 37 + UPDATE 53, esi + SHA1_RND1 ecx,edx,ebp,eax,ebx, esi,edi, 38 + UPDATE 54, esi + SHA1_RND1 ebx,ecx,edx,ebp,eax, esi,edi, 39 + UPDATE 55, esi + + SHA1_RND2 eax,ebx,ecx,edx,ebp, esi,edi, 40 + UPDATE 56, esi + SHA1_RND2 ebp,eax,ebx,ecx,edx, esi,edi, 41 + UPDATE 57, esi + SHA1_RND2 edx,ebp,eax,ebx,ecx, esi,edi, 42 + UPDATE 58, esi + SHA1_RND2 ecx,edx,ebp,eax,ebx, esi,edi, 43 + UPDATE 59, esi + SHA1_RND2 ebx,ecx,edx,ebp,eax, esi,edi, 44 + UPDATE 60, esi + SHA1_RND2 eax,ebx,ecx,edx,ebp, esi,edi, 45 + UPDATE 61, esi + SHA1_RND2 ebp,eax,ebx,ecx,edx, esi,edi, 46 + UPDATE 62, esi + SHA1_RND2 edx,ebp,eax,ebx,ecx, esi,edi, 47 + UPDATE 63, esi + SHA1_RND2 ecx,edx,ebp,eax,ebx, esi,edi, 48 + UPDATE 64, esi + SHA1_RND2 ebx,ecx,edx,ebp,eax, esi,edi, 49 + UPDATE 65, esi + SHA1_RND2 eax,ebx,ecx,edx,ebp, esi,edi, 50 + UPDATE 66, esi + SHA1_RND2 ebp,eax,ebx,ecx,edx, esi,edi, 51 + UPDATE 67, esi + SHA1_RND2 edx,ebp,eax,ebx,ecx, esi,edi, 52 + UPDATE 68, esi + SHA1_RND2 ecx,edx,ebp,eax,ebx, esi,edi, 53 + UPDATE 69, esi + SHA1_RND2 ebx,ecx,edx,ebp,eax, esi,edi, 54 + UPDATE 70, esi + SHA1_RND2 eax,ebx,ecx,edx,ebp, esi,edi, 55 + UPDATE 71, esi + SHA1_RND2 ebp,eax,ebx,ecx,edx, esi,edi, 56 + UPDATE 72, esi + SHA1_RND2 edx,ebp,eax,ebx,ecx, esi,edi, 57 + UPDATE 73, esi + SHA1_RND2 ecx,edx,ebp,eax,ebx, esi,edi, 58 + UPDATE 74, esi + SHA1_RND2 ebx,ecx,edx,ebp,eax, esi,edi, 59 + UPDATE 75, esi + + SHA1_RND3 eax,ebx,ecx,edx,ebp, esi,edi, 60 + UPDATE 76, esi + SHA1_RND3 ebp,eax,ebx,ecx,edx, esi,edi, 61 + UPDATE 77, esi + SHA1_RND3 edx,ebp,eax,ebx,ecx, esi,edi, 62 + UPDATE 78, esi + SHA1_RND3 ecx,edx,ebp,eax,ebx, esi,edi, 63 + UPDATE 79, esi + SHA1_RND3 ebx,ecx,edx,ebp,eax, esi,edi, 64 + SHA1_RND3 eax,ebx,ecx,edx,ebp, esi,edi, 65 + SHA1_RND3 ebp,eax,ebx,ecx,edx, esi,edi, 66 + SHA1_RND3 edx,ebp,eax,ebx,ecx, esi,edi, 67 + SHA1_RND3 ecx,edx,ebp,eax,ebx, esi,edi, 68 + SHA1_RND3 ebx,ecx,edx,ebp,eax, esi,edi, 69 + SHA1_RND3 eax,ebx,ecx,edx,ebp, esi,edi, 70 + SHA1_RND3 ebp,eax,ebx,ecx,edx, esi,edi, 71 + SHA1_RND3 edx,ebp,eax,ebx,ecx, esi,edi, 72 + SHA1_RND3 ecx,edx,ebp,eax,ebx, esi,edi, 73 + SHA1_RND3 ebx,ecx,edx,ebp,eax, esi,edi, 74 + SHA1_RND3 eax,ebx,ecx,edx,ebp, esi,edi, 75 + SHA1_RND3 ebp,eax,ebx,ecx,edx, esi,edi, 76 + SHA1_RND3 edx,ebp,eax,ebx,ecx, esi,edi, 77 + SHA1_RND3 ecx,edx,ebp,eax,ebx, esi,edi, 78 + SHA1_RND3 ebx,ecx,edx,ebp,eax, esi,edi, 79 + +;; +;; update digest +;; + mov edi,[esp+stackSize*4-3*4] ; restore hash address + mov esi,[esp+stackSize*4-2*4] ; restore data address + + add [edi+0*4],eax ; advance digest + mov eax,[esp+stackSize*4-1*4] ; restore data length + add [edi+1*4],ebx + add [edi+2*4],ecx + add [edi+3*4],edx + add [edi+4*4],ebp + + add esi, MBS_SHA1 + sub eax, MBS_SHA1 + jg .sha1_block_loop + + add esp,stackSize*4 ; remove local buffer + REST_GPR + ret +ENDFUNC UpdateSHA1 + +%endif ;; _IPP >= _IPP_M5 +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA1_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256g9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256g9as.asm new file mode 100644 index 000000000..9a585dc1f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256g9as.asm @@ -0,0 +1,444 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA256 +; +; Content: +; UpdateSHA256 +; +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP >= _IPP_G9) + +%xdefine XMM_SHUFB_BSWAP xmm6 +%xdefine W0 xmm0 +%xdefine W4 xmm1 +%xdefine W8 xmm2 +%xdefine W12 xmm3 +%xdefine SIG1 xmm4 +%xdefine SIG0 xmm5 +%xdefine X xmm6 +%xdefine W xmm7 + +%xdefine regTbl ebx + + +;; we are considering x, y, z are polynomials over GF(2) +;; & - multiplication +;; ^ - additive +;; operations + +;; +;; Chj(x,y,z) = (x&y) ^ (~x & z) +;; = (x&y) ^ ((1^x) &z) +;; = (x&y) ^ (z ^ x&z) +;; = x&y ^ z ^ x&z +;; = x&(y^z) ^z +;; +%macro Chj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%Y + xor %%F, %%Z + and %%F, %%X + xor %%F, %%Z +%endmacro + + +;; +;; Maj(x,y,z) = (x&y) ^ (x&z) ^ (y&z) +;; = (x&y) ^ (x&z) ^ (y&z) ^ (z&z) ^z // note: ((z&z) ^z) = 0 +;; = x&(y^z) ^ z&(y^z) ^z +;; = (x^z)&(y^z) ^z +;; +%macro Maj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%X + xor %%F, %%Z + xor %%Z, %%Y + and %%F, %%Z + xor %%Z, %%Y + xor %%F, %%Z +%endmacro + + +%macro ROTR 2.nolist + %xdefine %%X %1 + %xdefine %%n %2 + + shrd %%X,%%X, %%n + ;;ror X, n +%endmacro + + +;; +;; Summ0(x) = ROR(x,2) ^ ROR(x,13) ^ ROR(x,22) +;; +%macro Summ0 3.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%T %3 + + mov %%F, %%X + ROTR %%F, 2 + mov %%T, %%X + ROTR %%T, 13 + xor %%F, %%T + ROTR %%T, (22-13) + xor %%F, %%T +%endmacro + + +;; +;; Summ1(x) = ROR(x,6) ^ ROR(x,11) ^ ROR(x,25) +;; +%macro Summ1 3.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%T %3 + + mov %%F, %%X + ROTR %%F, 6 + mov %%T, %%X + ROTR %%T, 11 + xor %%F, %%T + ROTR %%T, (25-11) + xor %%F, %%T +%endmacro + + +;; +;; regular round (i): +;; +;; T1 = h + Sigma1(e) + Ch(e,f,g) + K[i] + W[i] +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h = g +;; g = f +;; f = e +;; e = d + T1 +;; d = c +;; c = b +;; b = a +;; a = T1+T2 +;; +;; or +;; +;; h += Sigma1(e) + Ch(e,f,g) + K[i] + W[i] (==T1) +;; d += h +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h += T2 +;; and following textual shift {a,b,c,d,e,f,g,h} => {h,a,b,c,d,e,f,g} +;; +%macro ROUND 6.nolist + %xdefine %%nr %1 + %xdefine %%hashBuff %2 + %xdefine %%wBuff %3 + %xdefine %%F1 %4 + %xdefine %%F2 %5 + %xdefine %%T1 %6 + ; %xdefine T2 %7 + + Summ1 %%F1, eax, %%T1 + Chj %%F2, eax,{[%%hashBuff+((vF-%%nr)&7)*sizeof(dword)]},{[%%hashBuff+((vG-%%nr)&7)*sizeof(dword)]} + mov eax, [%%hashBuff+((vH-%%nr)&7)*sizeof(dword)] + add eax, %%F1 + add eax, %%F2 + add eax, dword [%%wBuff+(%%nr&3)*sizeof(dword)] + + mov %%F1, dword [%%hashBuff+((vB-%%nr)&7)*sizeof(dword)] + mov %%T1, dword [%%hashBuff+((vC-%%nr)&7)*sizeof(dword)] + Maj %%F2, edx,%%F1, %%T1 + Summ0 %%F1, edx, %%T1 + lea edx, [%%F1+%%F2] + + add edx,eax ; T2+T1 + add eax,[%%hashBuff+((vD-%%nr)&7)*sizeof(dword)] ; T1+d + + mov [%%hashBuff+((vH-%%nr)&7)*sizeof(dword)],edx + mov [%%hashBuff+((vD-%%nr)&7)*sizeof(dword)],eax +%endmacro + + +;; +;; W[i] = Sigma1(W[i-2]) + W[i-7] + Sigma0(W[i-15]) + W[i-16], i=16,..,63 +;; +;;for next rounds 16,17,18 and 19: +;; W[0] <= W[16] = Sigma1(W[14]) + W[ 9] + Sigma0(W[1]) + W[0] +;; W[1] <= W[17] = Sigma1(W[15]) + W[10] + Sigma0(W[2]) + W[1] +;; W[2] <= W[18] = Sigma1(W[ 0]) + W[11] + Sigma0(W[3]) + W[1] +;; W[3] <= W[19] = Sigma1(W[ 1]) + W[12] + Sigma0(W[4]) + W[2] +;; +;; the process is repeated exactly because texual round of W[] +;; +;; Sigma1() and Sigma0() functions are defined as following: +;; Sigma1(X) = ROR(X,17)^ROR(X,19)^SHR(X,10) +;; Sigma0(X) = ROR(X, 7)^ROR(X,18)^SHR(X, 3) +;; +%macro UPDATE_W 8.nolist + %xdefine %%xS %1 + %xdefine %%xS0 %2 + %xdefine %%xS4 %3 + %xdefine %%xS8 %4 + %xdefine %%xS12 %5 + %xdefine %%SIGMA1 %6 + %xdefine %%SIGMA0 %7 + %xdefine %%X %8 + + vpshufd %%X, %%xS12, 11111010b ;; SIGMA1 = {W[15],W[15],W[14],W[14]} + vpsrld %%SIGMA1, %%X, 10 + vpsrlq %%X, %%X, 17 + vpxor %%SIGMA1, %%SIGMA1, %%X + vpsrlq %%X, %%X, (19-17) + vpxor %%SIGMA1, %%SIGMA1, %%X + + vpshufd %%X, %%xS0, 10100101b ;; SIGMA0 = {W[2],W[2],W[1],W[1]} + vpsrld %%SIGMA0, %%X, 3 + vpsrlq %%X, %%X, 7 + vpxor %%SIGMA0, %%SIGMA0, %%X + vpsrlq %%X, %%X, (18-7) + vpxor %%SIGMA0, %%SIGMA0, %%X + + vpshufd %%xS, %%xS0, 01010000b ;; {W[ 1],W[ 1],W[ 0],W[ 0]} + vpaddd %%SIGMA1, %%SIGMA1, %%SIGMA0 + vpshufd %%X, %%xS8, 10100101b ;; {W[10],W[10],W[ 9],W[ 9]} + vpaddd %%xS, %%xS, %%SIGMA1 + vpaddd %%xS, %%xS, %%X + + + vpshufd %%X, %%xS, 10100000b ;; SIGMA1 = {W[1],W[1],W[0],W[0]} + vpsrld %%SIGMA1, %%X, 10 + vpsrlq %%X, %%X, 17 + vpxor %%SIGMA1, %%SIGMA1, %%X + vpsrlq %%X, %%X, (19-17) + vpxor %%SIGMA1, %%SIGMA1, %%X + + vpalignr %%X, %%xS4, %%xS0, (3*sizeof(dword)) ;; SIGMA0 = {W[4],W[4],W[3],W[3]} + vpshufd %%X, %%X, 01010000b + vpsrld %%SIGMA0, %%X, 3 + vpsrlq %%X, %%X, 7 + vpxor %%SIGMA0, %%SIGMA0, %%X + vpsrlq %%X, %%X, (18-7) + vpxor %%SIGMA0, %%SIGMA0, %%X + + vpalignr %%X, %%xS12, %%xS8, (3*sizeof(dword)) ;; {W[14],W[13],W[12],W[11]} + vpshufd %%xS0, %%xS0, 11111010b ;; {W[ 3],W[ 3],W[ 2],W[ 2]} + vpaddd %%SIGMA1, %%SIGMA1, %%SIGMA0 + vpshufd %%X, %%X, 01010000b ;; {W[12],W[12],W[11],W[11]} + vpaddd %%xS0, %%xS0, %%SIGMA1 + vpaddd %%xS0, %%xS0, %%X + + vpshufd %%xS, %%xS, 10001000b ;; {W[1],W[0],W[1],W[0]} + vpshufd %%xS0, %%xS0, 10001000b ;; {W[3],W[2],W[3],W[2]} + vpalignr %%xS0, %%xS0, %%xS, (2*sizeof(dword)) ;; {W[3],W[2],W[1],W[0]} +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR +SWP_BYTE: +pByteSwp DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; UpdateSHA256(Ipp32u digest[], Ipp8u dataBlock[], int datalen, Ipp32u K_256[]) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA256,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pHash [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to hash +%xdefine pData [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to data block +%xdefine dataLen [ebp + ARG_1 + 2*sizeof(dword)] ; data length +%xdefine pTbl [ebp + ARG_1 + 3*sizeof(dword)] ; pointer to the SHA256 const table + +%xdefine MBS_SHA256 (64) + +%assign hSize sizeof(dword)*8 ; size of hash +%assign wSize sizeof(oword) ; W values queue (dwords) +%assign cntSize sizeof(dword) ; local counter + +%assign hashOff 0 ; hash address +%assign wOff hashOff+hSize ; W values offset +%assign cntOff wOff+wSize + +%assign stackSize (hSize+wSize+cntSize) ; stack size + sub esp, stackSize + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + + mov eax, pHash ; pointer to the hash + vmovdqu W0, oword [eax] ; load initial hash value + vmovdqu W4, oword [eax+sizeof(oword)] + vmovdqu oword [esp+hashOff], W0 + vmovdqu oword [esp+hashOff+sizeof(oword)*1], W4 + + mov eax, pData ; pointer to the data block + mov regTbl, pTbl ; pointer to SHA256 table (points K_256[] constants) + ;vmovdqa XMM_SHUFB_BSWAP, oword pByteSwp ; load shuffle mask + LD_ADDR ecx, SWP_BYTE + movdqa XMM_SHUFB_BSWAP, oword [ecx+(pByteSwp-SWP_BYTE)] + + vmovdqu W0, oword [eax] ; load buffer content + vmovdqu W4, oword [eax+sizeof(oword)] + vmovdqu W8, oword [eax+sizeof(oword)*2] + vmovdqu W12,oword [eax+sizeof(oword)*3] + +%assign vA 0 +%assign vB 1 +%assign vC 2 +%assign vD 3 +%assign vE 4 +%assign vF 5 +%assign vG 6 +%assign vH 7 + + mov eax, [esp+hashOff+vE*sizeof(dword)] + mov edx, [esp+hashOff+vA*sizeof(dword)] + + ;; perform 0-3 regular rounds + vpshufb W0, W0, XMM_SHUFB_BSWAP ; swap input + vpaddd W, W0, oword [regTbl+sizeof(oword)*0] ; T += K_SHA256[0-3] + vmovdqu oword [esp+wOff], W + ROUND 0, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 1, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 2, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 3, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + ;; perform next 4-7 regular rounds + vpshufb W4, W4, XMM_SHUFB_BSWAP ; swap input + vpaddd W, W4, oword [regTbl+sizeof(oword)*1] ; T += K_SHA256[4-7] + vmovdqu oword [esp+wOff], W + ROUND 4, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 5, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 6, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 7, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + ;; perform next 8-11 regular rounds + vpshufb W8, W8, XMM_SHUFB_BSWAP ; swap input + vpaddd W, W8, oword [regTbl+sizeof(oword)*2] ; T += K_SHA256[8-11] + vmovdqu oword [esp+wOff], W + ROUND 8, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 9, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 10, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 11, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + ;; perform next 12-15 regular rounds + vpshufb W12, W12, XMM_SHUFB_BSWAP ; swap input + vpaddd W, W12, oword [regTbl+sizeof(oword)*3] ; T += K_SHA256[12-15] + vmovdqu oword [esp+wOff], W + ROUND 12, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 13, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 14, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 15, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + mov dword [esp+cntOff], (64-16) ; init counter +.loop_16_63: + add regTbl, sizeof(oword)*4 ; update SHA_256 pointer + + UPDATE_W W, W0, W4, W8, W12, SIG1,SIG0,X ; round: 16*i - 16*i+3 + vpaddd W, W0, oword [regTbl+sizeof(oword)*0] ; T += K_SHA256[16-19] + vmovdqu oword [esp+wOff], W + ROUND 16, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 17, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 18, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 19, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + UPDATE_W W, W4, W8, W12,W0, SIG1,SIG0,X ; round: 20*i 20*i+3 + vpaddd W, W4, oword [regTbl+sizeof(oword)*1] ; T += K_SHA256[20-23] + vmovdqu oword [esp+wOff], W + ROUND 20, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 21, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 22, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 23, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + UPDATE_W W, W8, W12,W0, W4, SIG1,SIG0,X ; round: 24*i - 24*i+3 + vpaddd W, W8, oword [regTbl+sizeof(oword)*2] ; T += K_SHA256[24-27] + vmovdqu oword [esp+wOff], W + ROUND 24, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 25, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 26, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 27, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + UPDATE_W W, W12,W0, W4, W8, SIG1,SIG0,X ; round: 28*i - 28*i+3 + vpaddd W, W12, oword [regTbl+sizeof(oword)*3]; T += K_SHA256[28-31] + vmovdqu oword [esp+wOff], W + ROUND 28, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 29, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 30, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 31, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + sub dword [esp+cntOff], 16 + jg .loop_16_63 + + mov eax, pHash ; pointer to the hash + vmovdqu W0, oword [esp+hashOff] + vmovdqu W4, oword [esp+hashOff+sizeof(oword)*1] + + ; update hash + vmovdqu W, oword [eax] + vpaddd W, W, W0 + vmovdqu oword [eax], W + vmovdqu W, oword [eax+sizeof(oword)] + vpaddd W, W, W4 + vmovdqu oword [eax+sizeof(oword)], W + + add dword pData, MBS_SHA256 + sub dword dataLen, MBS_SHA256 + jg .sha256_block_loop + + add esp, stackSize + REST_GPR + ret +ENDFUNC UpdateSHA256 + +%endif ;; _IPP32E_G9 and above +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256nias.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256nias.asm new file mode 100644 index 000000000..fd6e3e70d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256nias.asm @@ -0,0 +1,617 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA-256 +; +; Content: +; UpdateSHA256ni +; +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_ON_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) + + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +CODE_DATA: +PSHUFFLE_BYTE_FLIP_MASK \ + DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 + +align IPP_ALIGN_FACTOR +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA256ni(DigestSHA256 digest, const Ipp8u* msg, int mlen, const Ipp32u K_256[]) +;* +;***************************************************************************************** + +%ifndef _VXWORKS + +IPPASM UpdateSHA256ni,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pDigest [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to the in/out digest +%xdefine pMsg [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to the inp message +%xdefine msgLen [ebp + ARG_1 + 2*sizeof(dword)] ; message length +%xdefine pTbl [ebp + ARG_1 + 3*sizeof(dword)] ; pointer to SHA256 table of constants + +%xdefine MBS_SHA256 (64) ; SHA-1 message block length (bytes) + +%xdefine HASH_PTR edi ; 1st arg +%xdefine MSG_PTR esi ; 2nd arg +%xdefine MSG_LEN edx ; 3rd arg +%xdefine K256_PTR ebx ; 4rd arg + +%xdefine MSG xmm0 +%xdefine STATE0 xmm1 +%xdefine STATE1 xmm2 +%xdefine MSGTMP0 xmm3 +%xdefine MSGTMP1 xmm4 +%xdefine MSGTMP2 xmm5 +%xdefine MSGTMP3 xmm6 +%xdefine MSGTMP4 xmm7 + +; +; stack frame +; +%xdefine mask_save eax +%xdefine abef_save eax+sizeof(oword) +%xdefine cdgh_save eax+sizeof(oword)*2 +%xdefine frame_size sizeof(oword)+sizeof(oword)+sizeof(oword) + + sub esp, (frame_size+16) + lea eax, [esp+16] + and eax, -16 + + mov MSG_LEN, msgLen ; message length + test MSG_LEN, MSG_LEN + jz .quit + + mov HASH_PTR, pDigest + mov MSG_PTR, pMsg + mov K256_PTR, pTbl + + ;; load input hash value, reorder these appropriately + movdqu STATE0, oword [HASH_PTR+0*sizeof(oword)] + movdqu STATE1, oword [HASH_PTR+1*sizeof(oword)] + + pshufd STATE0, STATE0, 0B1h ; CDAB + pshufd STATE1, STATE1, 01Bh ; EFGH + movdqa MSGTMP4, STATE0 + palignr STATE0, STATE1, 8 ; ABEF + pblendw STATE1, MSGTMP4, 0F0h ; CDGH + + ;; copy byte_flip_mask to stack + mov ecx, 000010203h ;; DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 + mov dword [mask_save], ecx + mov ecx, 004050607h + mov dword [mask_save+1*sizeof(dword)], ecx + mov ecx, 008090a0bh + mov dword [mask_save+2*sizeof(dword)], ecx + mov ecx, 00c0d0e0fh + mov dword [mask_save+3*sizeof(dword)], ecx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + movdqa oword [abef_save], STATE0 ; save for addition after rounds + movdqa oword [cdgh_save], STATE1 + + ;; rounds 0-3 + movdqu MSG, oword [MSG_PTR + 0*sizeof(oword)] + pshufb MSG, [mask_save] + movdqa MSGTMP0, MSG + paddd MSG, oword [K256_PTR + 0*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + ;; rounds 4-7 + movdqu MSG, oword [MSG_PTR + 1*sizeof(oword)] + pshufb MSG, [mask_save] + movdqa MSGTMP1, MSG + paddd MSG, oword [K256_PTR + 1*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 8-11 + movdqu MSG, oword [MSG_PTR + 2*sizeof(oword)] + pshufb MSG, [mask_save] + movdqa MSGTMP2, MSG + paddd MSG, oword [K256_PTR + 2*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 12-15 + movdqu MSG, oword [MSG_PTR + 3*sizeof(oword)] + pshufb MSG, [mask_save] + movdqa MSGTMP3, MSG + paddd MSG, oword [K256_PTR + 3*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP2, MSGTMP3 + ;; rounds 16-19 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 4*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 20-23 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 5*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 24-27 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 6*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 28-31 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 7*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 32-35 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 8*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 36-39 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 9*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 40-43 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 10*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 44-47 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 11*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 48-51 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 12*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 52-55 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 13*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + ;; rounds 56-59 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 14*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + ;; rounds 60-63 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 15*sizeof(oword)] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + paddd STATE0, oword [abef_save] ; update previously saved hash + paddd STATE1, oword [cdgh_save] + + add MSG_PTR, MBS_SHA256 + sub MSG_LEN, MBS_SHA256 + jg .sha256_block_loop + + ; reorder hash + pshufd STATE0, STATE0, 01Bh ; FEBA + pshufd STATE1, STATE1, 0B1h ; DCHG + movdqa MSGTMP4, STATE0 + pblendw STATE0, STATE1, 0F0h ; DCBA + palignr STATE1, MSGTMP4, 8 ; HGFE + + ; and store it back + movdqu oword [HASH_PTR + 0*sizeof(oword)], STATE0 + movdqu oword [HASH_PTR + 1*sizeof(oword)], STATE1 + +.quit: + add esp, (frame_size+16) + REST_GPR + ret +ENDFUNC UpdateSHA256ni + +%else ;; no sha ni support in VxWorks - therefore we temporary use db + +IPPASM UpdateSHA256ni,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pDigest [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to the in/out digest +%xdefine pMsg [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to the inp message +%xdefine msgLen [ebp + ARG_1 + 2*sizeof(dword)] ; message length +%xdefine pTbl [ebp + ARG_1 + 3*sizeof(dword)] ; pointer to SHA256 table of constants + +%xdefine MBS_SHA256 (64) ; SHA-1 message block length (bytes) + +%xdefine HASH_PTR edi ; 1st arg +%xdefine MSG_PTR esi ; 2nd arg +%xdefine MSG_LEN edx ; 3rd arg +%xdefine K256_PTR ebx ; 4rd arg + +%xdefine MSG xmm0 +%xdefine STATE0 xmm1 +%xdefine STATE1 xmm2 +%xdefine MSGTMP0 xmm3 +%xdefine MSGTMP1 xmm4 +%xdefine MSGTMP2 xmm5 +%xdefine MSGTMP3 xmm6 +%xdefine MSGTMP4 xmm7 + +; +; stack frame +; +%xdefine mask_save eax +%xdefine abef_save eax+sizeof(oword) +%xdefine cdgh_save eax+sizeof(oword)*2 +%xdefine frame_size sizeof(oword)+sizeof(oword)+sizeof(oword) + + sub esp, (frame_size+16) + lea eax, [esp+16] + and eax, -16 + + mov MSG_LEN, msgLen ; message length + test MSG_LEN, MSG_LEN + jz .quit + + mov HASH_PTR, pDigest + mov MSG_PTR, pMsg + mov K256_PTR, pTbl + + ;; load input hash value, reorder these appropriately + movdqu STATE0, oword [HASH_PTR+0*sizeof(oword)] + movdqu STATE1, oword [HASH_PTR+1*sizeof(oword)] + + pshufd STATE0, STATE0, 0B1h ; CDAB + pshufd STATE1, STATE1, 01Bh ; EFGH + movdqa MSGTMP4, STATE0 + palignr STATE0, STATE1, 8 ; ABEF + pblendw STATE1, MSGTMP4, 0F0h ; CDGH + + ;; copy byte_flip_mask to stack + ;movdqa MSGTMP4, oword [PSHUFFLE_BYTE_FLIP_MASK] + LD_ADDR ecx, CODE_DATA + movdqa MSGTMP4, oword [ecx+(PSHUFFLE_BYTE_FLIP_MASK-CODE_DATA)] + movdqa oword [mask_save], MSGTMP4 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + movdqa oword [abef_save], STATE0 ; save for addition after rounds + movdqa oword [cdgh_save], STATE1 + + ;; rounds 0-3 + movdqu MSG, oword [MSG_PTR + 0*sizeof(oword)] + pshufb MSG, oword [mask_save] + movdqa MSGTMP0, MSG + paddd MSG, oword [K256_PTR + 0*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + ;; rounds 4-7 + movdqu MSG, oword [MSG_PTR + 1*sizeof(oword)] + pshufb MSG, oword [mask_save] + movdqa MSGTMP1, MSG + paddd MSG, oword [K256_PTR + 1*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0DCH ;; sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 8-11 + movdqu MSG, oword [MSG_PTR + 2*sizeof(oword)] + pshufb MSG, oword [mask_save] + movdqa MSGTMP2, MSG + paddd MSG, oword [K256_PTR + 2*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0E5H ;; sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 12-15 + movdqu MSG, oword [MSG_PTR + 3*sizeof(oword)] + pshufb MSG, oword [mask_save] + movdqa MSGTMP3, MSG + paddd MSG, oword [K256_PTR + 3*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + db 0FH,038H,0CDH,0DEH ;; sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0EEH ;; sha256msg1 MSGTMP2, MSGTMP3 + ;; rounds 16-19 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 4*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + db 0FH,038H,0CDH,0E3H ;; sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0F3H ;; sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 20-23 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 5*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + db 0FH,038H,0CDH,0ECH ;; sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0DCH ;; sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 24-27 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 6*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + db 0FH,038H,0CDH,0F5H ;; sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0E5H ;; sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 28-31 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 7*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + db 0FH,038H,0CDH,0DEH ;; sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0EEH ;; sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 32-35 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 8*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + db 0FH,038H,0CDH,0E3H ;; sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0F3H ;; sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 36-39 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 9*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + db 0FH,038H,0CDH,0ECH ;; sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0DCH ;; sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 40-43 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 10*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + db 0FH,038H,0CDH,0F5H ;; sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0E5H ;; sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 44-47 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 11*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + db 0FH,038H,0CDH,0DEH ;; sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0EEH ;; sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 48-51 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 12*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + db 0FH,038H,0CDH,0E3H ;; sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,038H,0CCH,0F3H ;; sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 52-55 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 13*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + db 0FH,038H,0CDH,0ECH ;; sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + ;; rounds 56-59 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 14*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + db 0FH,038H,0CDH,0F5H ;; sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + ;; rounds 60-63 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 15*sizeof(oword)] + db 0FH,038H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,038H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + paddd STATE0, oword [abef_save] ; update previously saved hash + paddd STATE1, oword [cdgh_save] + + add MSG_PTR, MBS_SHA256 + sub MSG_LEN, MBS_SHA256 + jg .sha256_block_loop + + ; reorder hash + pshufd STATE0, STATE0, 01Bh ; FEBA + pshufd STATE1, STATE1, 0B1h ; DCHG + movdqa MSGTMP4, STATE0 + pblendw STATE0, STATE1, 0F0h ; DCBA + palignr STATE1, MSGTMP4, 8 ; HGFE + + ; and store it back + movdqu oword [HASH_PTR + 0*sizeof(oword)], STATE0 + movdqu oword [HASH_PTR + 1*sizeof(oword)], STATE1 + +.quit: + add esp, (frame_size+16) + REST_GPR + ret +ENDFUNC UpdateSHA256ni + +%endif ;; VxWorks + +%endif ;; _FEATURE_ON_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256v8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256v8as.asm new file mode 100644 index 000000000..cef896546 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256v8as.asm @@ -0,0 +1,455 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA256 +; +; Content: +; UpdateSHA256 +; +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP >= _IPP_V8) && (_IPP < _IPP_G9) + +%xdefine XMM_SHUFB_BSWAP xmm6 +%xdefine W0 xmm0 +%xdefine W4 xmm1 +%xdefine W8 xmm2 +%xdefine W12 xmm3 +%xdefine SIG1 xmm4 +%xdefine SIG0 xmm5 +%xdefine X xmm6 +%xdefine W xmm7 + +%xdefine regTbl ebx + + +;; we are considering x, y, z are polynomials over GF(2) +;; & - multiplication +;; ^ - additive +;; operations + +;; +;; Chj(x,y,z) = (x&y) ^ (~x & z) +;; = (x&y) ^ ((1^x) &z) +;; = (x&y) ^ (z ^ x&z) +;; = x&y ^ z ^ x&z +;; = x&(y^z) ^z +;; +%macro Chj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%Y + xor %%F, %%Z + and %%F, %%X + xor %%F, %%Z +%endmacro + + +;; +;; Maj(x,y,z) = (x&y) ^ (x&z) ^ (y&z) +;; = (x&y) ^ (x&z) ^ (y&z) ^ (z&z) ^z // note: ((z&z) ^z) = 0 +;; = x&(y^z) ^ z&(y^z) ^z +;; = (x^z)&(y^z) ^z +;; +%macro Maj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%X + xor %%F, %%Z + xor %%Z, %%Y + and %%F, %%Z + xor %%Z, %%Y + xor %%F, %%Z +%endmacro + + +%macro ROTR 2.nolist + %xdefine %%X %1 + %xdefine %%n %2 + + ;;shrd X,X, n + ror %%X, %%n +%endmacro + + +;; +;; Summ0(x) = ROR(x,2) ^ ROR(x,13) ^ ROR(x,22) +;; +%macro Summ0 3.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%T %3 + + mov %%F, %%X + ROTR %%F, 2 + mov %%T, %%X + ROTR %%T, 13 + xor %%F, %%T + ROTR %%T, (22-13) + xor %%F, %%T +%endmacro + + +;; +;; Summ1(x) = ROR(x,6) ^ ROR(x,11) ^ ROR(x,25) +;; +%macro Summ1 3.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%T %3 + + mov %%F, %%X + ROTR %%F, 6 + mov %%T, %%X + ROTR %%T, 11 + xor %%F, %%T + ROTR %%T, (25-11) + xor %%F, %%T +%endmacro + + +;; +;; regular round (i): +;; +;; T1 = h + Sigma1(e) + Ch(e,f,g) + K[i] + W[i] +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h = g +;; g = f +;; f = e +;; e = d + T1 +;; d = c +;; c = b +;; b = a +;; a = T1+T2 +;; +;; or +;; +;; h += Sigma1(e) + Ch(e,f,g) + K[i] + W[i] (==T1) +;; d += h +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h += T2 +;; and following textual shift {a,b,c,d,e,f,g,h} => {h,a,b,c,d,e,f,g} +;; +%macro ROUND 6.nolist + %xdefine %%nr %1 + %xdefine %%hashBuff %2 + %xdefine %%wBuff %3 + %xdefine %%F1 %4 + %xdefine %%F2 %5 + %xdefine %%T1 %6 + ; %xdefine T2 %7 + + Summ1 %%F1, eax, %%T1 + Chj %%F2, eax,{[%%hashBuff+((vF-%%nr)&7)*sizeof(dword)]},{[%%hashBuff+((vG-%%nr)&7)*sizeof(dword)]} + mov eax, [%%hashBuff+((vH-%%nr)&7)*sizeof(dword)] + add eax, %%F1 + add eax, %%F2 + add eax, dword [%%wBuff+(%%nr&3)*sizeof(dword)] + + mov %%F1, dword [%%hashBuff+((vB-%%nr)&7)*sizeof(dword)] + mov %%T1, dword [%%hashBuff+((vC-%%nr)&7)*sizeof(dword)] + Maj %%F2, edx,%%F1, %%T1 + Summ0 %%F1, edx, %%T1 + lea edx, [%%F1+%%F2] + + add edx,eax ; T2+T1 + add eax,[%%hashBuff+((vD-%%nr)&7)*sizeof(dword)] ; T1+d + + mov [%%hashBuff+((vH-%%nr)&7)*sizeof(dword)],edx + mov [%%hashBuff+((vD-%%nr)&7)*sizeof(dword)],eax +%endmacro + + +;; +;; W[i] = Sigma1(W[i-2]) + W[i-7] + Sigma0(W[i-15]) + W[i-16], i=16,..,63 +;; +;;for next rounds 16,17,18 and 19: +;; W[0] <= W[16] = Sigma1(W[14]) + W[ 9] + Sigma0(W[1]) + W[0] +;; W[1] <= W[17] = Sigma1(W[15]) + W[10] + Sigma0(W[2]) + W[1] +;; W[2] <= W[18] = Sigma1(W[ 0]) + W[11] + Sigma0(W[3]) + W[1] +;; W[3] <= W[19] = Sigma1(W[ 1]) + W[12] + Sigma0(W[4]) + W[2] +;; +;; the process is repeated exactly because texual round of W[] +;; +;; Sigma1() and Sigma0() functions are defined as following: +;; Sigma1(X) = ROR(X,17)^ROR(X,19)^SHR(X,10) +;; Sigma0(X) = ROR(X, 7)^ROR(X,18)^SHR(X, 3) +;; +%macro UPDATE_W 8.nolist + %xdefine %%xS %1 + %xdefine %%xS0 %2 + %xdefine %%xS4 %3 + %xdefine %%xS8 %4 + %xdefine %%xS12 %5 + %xdefine %%SIGMA1 %6 + %xdefine %%SIGMA0 %7 + %xdefine %%X %8 + + pshufd %%SIGMA1, %%xS12, 11111010b ;; SIGMA1 = {W[15],W[15],W[14],W[14]} + movdqa %%X, %%SIGMA1 + psrld %%SIGMA1, 10 + psrlq %%X, 17 + pxor %%SIGMA1, %%X + psrlq %%X, (19-17) + pxor %%SIGMA1, %%X + + pshufd %%SIGMA0, %%xS0, 10100101b ;; SIGMA0 = {W[2],W[2],W[1],W[1]} + movdqa %%X, %%SIGMA0 + psrld %%SIGMA0, 3 + psrlq %%X, 7 + pxor %%SIGMA0, %%X + psrlq %%X, (18-7) + pxor %%SIGMA0, %%X + + pshufd %%xS, %%xS0, 01010000b ;; {W[ 1],W[ 1],W[ 0],W[ 0]} + pshufd %%X, %%xS8, 10100101b ;; {W[10],W[10],W[ 9],W[ 9]} + paddd %%xS, %%SIGMA1 + paddd %%xS, %%SIGMA0 + paddd %%xS, %%X + + + pshufd %%SIGMA1, %%xS, 10100000b ;; SIGMA1 = {W[1],W[1],W[0],W[0]} + movdqa %%X, %%SIGMA1 + psrld %%SIGMA1, 10 + psrlq %%X, 17 + pxor %%SIGMA1, %%X + psrlq %%X, (19-17) + pxor %%SIGMA1, %%X + + movdqa %%SIGMA0, %%xS4 ;; SIGMA0 = {W[4],W[4],W[3],W[3]} + palignr %%SIGMA0, %%xS0, (3*sizeof(dword)) + pshufd %%SIGMA0, %%SIGMA0, 01010000b + movdqa %%X, %%SIGMA0 + psrld %%SIGMA0, 3 + psrlq %%X, 7 + pxor %%SIGMA0, %%X + psrlq %%X, (18-7) + pxor %%SIGMA0, %%X + + movdqa %%X, %%xS12 + palignr %%X, %%xS8, (3*sizeof(dword)) ;; {W[14],W[13],W[12],W[11]} + pshufd %%xS0, %%xS0, 11111010b ;; {W[ 3],W[ 3],W[ 2],W[ 2]} + pshufd %%X, %%X, 01010000b ;; {W[12],W[12],W[11],W[11]} + paddd %%xS0, %%SIGMA1 + paddd %%xS0, %%SIGMA0 + paddd %%xS0, %%X + + pshufd %%xS, %%xS, 10001000b ;; {W[1],W[0],W[1],W[0]} + pshufd %%xS0, %%xS0, 10001000b ;; {W[3],W[2],W[3],W[2]} + palignr %%xS0, %%xS, (2*sizeof(dword)) ;; {W[3],W[2],W[1],W[0]} + movdqa %%xS, %%xS0 +%endmacro + + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR +SWP_BYTE: +pByteSwp DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; SHA256(Ipp32u digest[], Ipp8u dataBlock[], int dataLen, Ipp32u K_256[]) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA256,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pHash [ebp + ARG_1 + 0*sizeof(dword)] ; pointer to hash +%xdefine pData [ebp + ARG_1 + 1*sizeof(dword)] ; pointer to data block +%xdefine dataLen [ebp + ARG_1 + 2*sizeof(dword)] ; data length +%xdefine pTbl [ebp + ARG_1 + 3*sizeof(dword)] ; pointer to the SHA256 const table + +%xdefine MBS_SHA256 (64) + +%assign hSize sizeof(dword)*8 ; size of hash +%assign wSize sizeof(oword) ; W values queue (dwords) +%assign cntSize sizeof(dword) ; local counter + +%assign hashOff 0 ; hash address +%assign wOff hashOff+hSize ; W values offset +%assign cntOff wOff+wSize + +%assign stackSize (hSize+wSize+cntSize) ; stack size + + sub esp, stackSize + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + + mov eax, pHash ; pointer to the hash + movdqu W0, oword [eax] ; load initial hash value + movdqu W4, oword [eax+sizeof(oword)] + movdqu oword [esp+hashOff], W0 + movdqu oword [esp+hashOff+sizeof(oword)*1], W4 + + ;movdqa XMM_SHUFB_BSWAP, oword pByteSwp ; load shuffle mask + LD_ADDR eax, SWP_BYTE + movdqa XMM_SHUFB_BSWAP, oword [eax+(pByteSwp-SWP_BYTE)] + mov eax, pData ; pointer to the data block + mov regTbl, pTbl ; pointer to SHA256 table (points K_256[] constants) + + movdqu W0, oword [eax] ; load buffer content + movdqu W4, oword [eax+sizeof(oword)] + movdqu W8, oword [eax+sizeof(oword)*2] + movdqu W12,oword [eax+sizeof(oword)*3] + +%assign vA 0 +%assign vB 1 +%assign vC 2 +%assign vD 3 +%assign vE 4 +%assign vF 5 +%assign vG 6 +%assign vH 7 + + mov eax, [esp+hashOff+vE*sizeof(dword)] + mov edx, [esp+hashOff+vA*sizeof(dword)] + + ;; perform 0-3 regular rounds + pshufb W0, XMM_SHUFB_BSWAP ; swap input + movdqa W, W0 ; T = W[0-3] + paddd W, oword [regTbl+sizeof(oword)*0] ; T += K_SHA256[0-3] + movdqu oword [esp+wOff], W + ROUND 0, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 1, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 2, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 3, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + ;; perform next 4-7 regular rounds + pshufb W4, XMM_SHUFB_BSWAP ; swap input + movdqa W, W4 ; T = W[4-7] + paddd W, oword [regTbl+sizeof(oword)*1] ; T += K_SHA256[4-7] + movdqu oword [esp+wOff], W + ROUND 4, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 5, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 6, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 7, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + ;; perform next 8-11 regular rounds + pshufb W8, XMM_SHUFB_BSWAP ; swap input + movdqa W, W8 ; T = W[8-11] + paddd W, oword [regTbl+sizeof(oword)*2] ; T += K_SHA256[8-11] + movdqu oword [esp+wOff], W + ROUND 8, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 9, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 10, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 11, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + ;; perform next 12-15 regular rounds + pshufb W12, XMM_SHUFB_BSWAP ; swap input + movdqa W, W12 ; T = W[12-15] + paddd W, oword [regTbl+sizeof(oword)*3] ; T += K_SHA256[12-15] + movdqu oword [esp+wOff], W + ROUND 12, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 13, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 14, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 15, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + mov dword [esp+cntOff], (64-16) ; init counter +.loop_16_63: + add regTbl, sizeof(oword)*4 ; update SHA_256 pointer + + UPDATE_W W, W0, W4, W8, W12, SIG1,SIG0,X ; round: 16*i - 16*i+3 + paddd W, oword [regTbl+sizeof(oword)*0] ; T += K_SHA256[16-19] + movdqu oword [esp+wOff], W + ROUND 16, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 17, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 18, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 19, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + UPDATE_W W, W4, W8, W12,W0, SIG1,SIG0,X ; round: 20*i 20*i+3 + paddd W, oword [regTbl+sizeof(oword)*1] ; T += K_SHA256[20-23] + movdqu oword [esp+wOff], W + ROUND 20, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 21, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 22, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 23, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + UPDATE_W W, W8, W12,W0, W4, SIG1,SIG0,X ; round: 24*i - 24*i+3 + paddd W, oword [regTbl+sizeof(oword)*2] ; T += K_SHA256[24-27] + movdqu oword [esp+wOff], W + ROUND 24, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 25, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 26, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 27, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + UPDATE_W W, W12,W0, W4, W8, SIG1,SIG0,X ; round: 28*i - 28*i+3 + paddd W, oword [regTbl+sizeof(oword)*3] ; T += K_SHA256[28-31] + movdqu oword [esp+wOff], W + ROUND 28, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 29, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 30, {esp+hashOff},{esp+wOff}, esi,edi,ecx + ROUND 31, {esp+hashOff},{esp+wOff}, esi,edi,ecx + + sub dword [esp+cntOff], 16 + jg .loop_16_63 + + mov eax, pHash ; pointer to the hash + movdqu W0, oword [esp+hashOff] + movdqu W4, oword [esp+hashOff+sizeof(oword)*1] + + ; update hash + movdqu W, oword [eax] + paddd W, W0 + movdqu oword [eax], W + movdqu W, oword [eax+sizeof(oword)] + paddd W, W4 + movdqu oword [eax+sizeof(oword)], W + + add dword pData, MBS_SHA256 + sub dword dataLen, MBS_SHA256 + jg .sha256_block_loop + + add esp, stackSize + REST_GPR + ret +ENDFUNC UpdateSHA256 + +%endif ;; (_IPP >= _IPP_V8) && (_IPP < _IPP_G9) +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256w7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256w7as.asm new file mode 100644 index 000000000..b8c76a7d8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha256w7as.asm @@ -0,0 +1,419 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA256 +; +; Content: +; UpdateSHA256 +; +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP >= _IPP_M5) && (_IPP < _IPP_V8) + +;; +;; SIG0(x) = ROR32(x, 7) ^ ROR32(x,18) ^ LSR(x, 3) +;; SIG1(x) = ROR32(x,17) ^ ROR32(x,19) ^ LSR(x,10) +;; W[i] = SIG1(W[i-2]) + W[i-7] + SIG0(W[i-15]) + W[i-16], i=16,..,63 +;; +%macro UPDATE 2.nolist + %xdefine %%nr %1 + %xdefine %%wBuff %2 + + mov ebx,[%%wBuff+((%%nr-2) &0Fh)*sizeof(dword)] ; W[i- 2] + ror ebx, 10 + mov ecx,[%%wBuff+((%%nr-15)&0Fh)*sizeof(dword)] ; W[i-15] + ror ecx, 3 + mov esi,[%%wBuff+((%%nr-7) &0Fh)*sizeof(dword)] ; +W[i- 7] + add esi,[%%wBuff+((%%nr-16)&0Fh)*sizeof(dword)] ; +W[i-16] + + mov edi,003FFFFFh ; SIG1() + and edi,ebx + ror ebx,(17-10) + xor edi,ebx + ror ebx,(19-17) + xor edi,ebx + + add edi, esi ; SIG0() +W[i-7] +W[i-16] + + mov esi,1FFFFFFFh ; SIG0() + and esi,ecx + ror ecx,(7-3) + xor esi,ecx + ror ecx,(18-7) + xor esi,ecx + + add edi,esi ; SIG0() +W[i-7] +W[i-16] + SIG1() + mov [%%wBuff+(%%nr&0Fh)*sizeof(dword)],edi +%endmacro + + +; +; SUM1(x) = ROR32(x, 6) ^ ROR32(x,11) ^ ROR32(x,25) +; SUM0(x) = ROR32(x, 2) ^ ROR32(x,13) ^ ROR32(x,22) +; +; CH(x,y,x) = (x & y) ^ (~x & z) +; MAJ(x,y,z) = (x & y) ^ (x & z) ^ (y & z) = (x&y)^((x^y)&z) +; +; T1 = SUM1(E) +CH(E,F,G) +K[i] +W[i] + H +; T2 = SUM0(A) +MAJ(A,B,C) +; +; D += T1 +; H = T1+T2 +; +; eax = E +; edx = A +; +%macro SHA256_STEP 4.nolist + %xdefine %%nr %1 + %xdefine %%hashBuff %2 + %xdefine %%wBuff %3 + %xdefine %%immCnt %4 + + mov esi,[%%hashBuff+((vF-%%nr)&7)*sizeof(dword)] ; init CH() + mov ecx,eax + mov edi,[%%hashBuff+((vG-%%nr)&7)*sizeof(dword)] ; init CH() + mov ebx,eax ; SUM1() + ror eax,6 ; SUM1() + not ecx ; CH() + and esi,ebx ; CH() + ror ebx,11 ; SUM1() + and edi,ecx ; CH() + xor eax,ebx ; SUM1() + ror ebx,(25-11) ; SUM1() + xor esi,edi ; CH() + xor eax,ebx ; SUM1() + add eax,esi ; T1 = SUM1() +CH() + add eax,[%%hashBuff+((vH-%%nr)&7)*sizeof(dword)] ; T1 += h +;; add eax,[wBuff+(nr&0Fh)*sizeof(dword)] ; T1 += w[] + add eax,[%%wBuff] ; T1 += w[] + add eax, %%immCnt ; T1 += K[] + + mov esi,[%%hashBuff+((vB-%%nr)&7)*sizeof(dword)] ; init MAJ() + mov ecx,edx + mov edi,[%%hashBuff+((vC-%%nr)&7)*sizeof(dword)] ; init MAJ() + mov ebx,edx ; SUM0() + and ecx,esi ; MAJ() + ror edx,2 ; SUM0() + xor esi,ebx ; MAJ() + ror ebx,13 ; SUM0() + and esi,edi ; MAJ() + xor edx,ebx ; SUM0() + xor esi,ecx ; MAJ() + ror ebx,(22-13) ; SUM0() + xor edx,ebx ; SUM0() + add edx,esi ; T2 = SUM0()+MAJ() + + add edx,eax ; T2+T1 + add eax,[%%hashBuff+((vD-%%nr)&7)*sizeof(dword)] ; T1+d + + mov [%%hashBuff+((vH-%%nr)&7)*sizeof(dword)],edx + mov [%%hashBuff+((vD-%%nr)&7)*sizeof(dword)],eax +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA256(DigestSHA256 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +;; +;; Lib = W7 +;; +;; Caller = ippsSHA256Update +;; Caller = ippsSHA256Final +;; Caller = ippsSHA256MessageDigest +;; +;; Caller = ippsSHA224Update +;; Caller = ippsSHA224Final +;; Caller = ippsSHA224MessageDigest +;; +;; Caller = ippsHMACSHA256Update +;; Caller = ippsHMACSHA256Final +;; Caller = ippsHMACSHA256MessageDigest +;; +;; Caller = ippsHMACSHA224Update +;; Caller = ippsHMACSHA224Final +;; Caller = ippsHMACSHA224MessageDigest +;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA256,PUBLIC + USES_GPR esi,edi,ebx,ebp + +%xdefine pHash [esp + ARG_1 + 0*sizeof(dword)] ; pointer to the input/output hash +%xdefine pSrc [esp + ARG_1 + 1*sizeof(dword)] ; input message +%xdefine srcL [esp + ARG_1 + 2*sizeof(dword)] ; message length +%xdefine pParm [esp + ARG_1 + 3*sizeof(dword)] ; dummy parameter + +%xdefine MBS_SHA256 (64) ; SHA256 block data size + +%assign dSize 8 ; size of digest (dwords) +%assign wSize 16 ; W values queue (dwords) + +%assign hashOffset 0 ; hash address +%assign msgOffset hashOffset+sizeof(dword) ; message address offset +%assign lenOffset msgOffset+sizeof(dword) ; message length offset +%assign dOffset lenOffset+sizeof(dword) ; hash buffer offset +%assign wOffset dOffset+dSize*sizeof(dword) ; W values offset + +%assign stackSize 3*sizeof(dword) + (dSize+wSize)*sizeof(dword) + +%assign vA 0 +%assign vB 1 +%assign vC 2 +%assign vD 3 +%assign vE 4 +%assign vF 5 +%assign vG 6 +%assign vH 7 + mov eax, pParm ; dummy + mov edi, pHash ; hash address + mov esi, pSrc ; source data address + mov eax, srcL ; source data length + + sub esp, stackSize ; allocate local buffers + mov [esp+hashOffset], edi; save hash address + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + mov [esp+msgOffset], esi ; save message address + mov [esp+lenOffset], eax ; save message length + +;; +;; copy input digest +;; + mov eax, [edi+0*sizeof(dword)] + mov ebx, [edi+1*sizeof(dword)] + mov ecx, [edi+2*sizeof(dword)] + mov edx, [edi+3*sizeof(dword)] + mov [esp+dOffset+vA*sizeof(dword)], eax + mov [esp+dOffset+vB*sizeof(dword)], ebx + mov [esp+dOffset+vC*sizeof(dword)], ecx + mov [esp+dOffset+vD*sizeof(dword)], edx + mov eax, [edi+4*sizeof(dword)] + mov ebx, [edi+5*sizeof(dword)] + mov ecx, [edi+6*sizeof(dword)] + mov edx, [edi+7*sizeof(dword)] + mov [esp+dOffset+vE*sizeof(dword)], eax + mov [esp+dOffset+vF*sizeof(dword)], ebx + mov [esp+dOffset+vG*sizeof(dword)], ecx + mov [esp+dOffset+vH*sizeof(dword)], edx + +;; +;; initialize the first 16 qwords of W array +;; - remember about endian +;; + xor ecx, ecx +.loop1: + mov eax, [esi+ecx*sizeof(dword)] + bswap eax + mov ebx, [esi+ecx*sizeof(dword)+sizeof(dword)] + bswap ebx + + mov [esp+wOffset+ecx*sizeof(dword)], eax + mov [esp+wOffset+ecx*sizeof(dword)+sizeof(dword)], ebx + + add ecx, 2 + cmp ecx, 16 + jl .loop1 + +;; +;; perform 0-64 steps +;; + mov eax, [esp+dOffset+vE*sizeof(dword)] + mov edx, [esp+dOffset+vA*sizeof(dword)] + + + SHA256_STEP 0, {esp+dOffset}, {esp+wOffset+ 0*sizeof(dword)}, 0428A2F98h + UPDATE 16, {esp+wOffset} + SHA256_STEP 1, {esp+dOffset}, {esp+wOffset+ 1*sizeof(dword)}, 071374491h + UPDATE 17, {esp+wOffset} + SHA256_STEP 2, {esp+dOffset}, {esp+wOffset+ 2*sizeof(dword)}, 0B5C0FBCFh + UPDATE 18, {esp+wOffset} + SHA256_STEP 3, {esp+dOffset}, {esp+wOffset+ 3*sizeof(dword)}, 0E9B5DBA5h + UPDATE 19, {esp+wOffset} + SHA256_STEP 4, {esp+dOffset}, {esp+wOffset+ 4*sizeof(dword)}, 03956C25Bh + UPDATE 20, {esp+wOffset} + SHA256_STEP 5, {esp+dOffset}, {esp+wOffset+ 5*sizeof(dword)}, 059F111F1h + UPDATE 21, {esp+wOffset} + SHA256_STEP 6, {esp+dOffset}, {esp+wOffset+ 6*sizeof(dword)}, 0923F82A4h + UPDATE 22, {esp+wOffset} + SHA256_STEP 7, {esp+dOffset}, {esp+wOffset+ 7*sizeof(dword)}, 0AB1C5ED5h + UPDATE 23, {esp+wOffset} + SHA256_STEP 8, {esp+dOffset}, {esp+wOffset+ 8*sizeof(dword)}, 0D807AA98h + UPDATE 24, {esp+wOffset} + SHA256_STEP 9, {esp+dOffset}, {esp+wOffset+ 9*sizeof(dword)}, 012835B01h + UPDATE 25, {esp+wOffset} + SHA256_STEP 10,{esp+dOffset}, {esp+wOffset+10*sizeof(dword)}, 0243185BEh + UPDATE 26, {esp+wOffset} + SHA256_STEP 11, {esp+dOffset}, {esp+wOffset+11*sizeof(dword)}, 0550C7DC3h + UPDATE 27, {esp+wOffset} + SHA256_STEP 12, {esp+dOffset}, {esp+wOffset+12*sizeof(dword)}, 072BE5D74h + UPDATE 28, {esp+wOffset} + SHA256_STEP 13, {esp+dOffset}, {esp+wOffset+13*sizeof(dword)}, 080DEB1FEh + UPDATE 29, {esp+wOffset} + SHA256_STEP 14, {esp+dOffset}, {esp+wOffset+14*sizeof(dword)}, 09BDC06A7h + UPDATE 30, {esp+wOffset} + SHA256_STEP 15, {esp+dOffset}, {esp+wOffset+15*sizeof(dword)}, 0C19BF174h + UPDATE 31, {esp+wOffset} + + SHA256_STEP 16, {esp+dOffset}, {esp+wOffset+ 0*sizeof(dword)}, 0E49B69C1h + UPDATE 32, {esp+wOffset} + SHA256_STEP 17, {esp+dOffset}, {esp+wOffset+ 1*sizeof(dword)}, 0EFBE4786h + UPDATE 33, {esp+wOffset} + SHA256_STEP 18, {esp+dOffset}, {esp+wOffset+ 2*sizeof(dword)}, 00FC19DC6h + UPDATE 34, {esp+wOffset} + SHA256_STEP 19, {esp+dOffset}, {esp+wOffset+ 3*sizeof(dword)}, 0240CA1CCh + UPDATE 35, {esp+wOffset} + SHA256_STEP 20, {esp+dOffset}, {esp+wOffset+ 4*sizeof(dword)}, 02DE92C6Fh + UPDATE 36, {esp+wOffset} + SHA256_STEP 21, {esp+dOffset}, {esp+wOffset+ 5*sizeof(dword)}, 04A7484AAh + UPDATE 37, {esp+wOffset} + SHA256_STEP 22, {esp+dOffset}, {esp+wOffset+ 6*sizeof(dword)}, 05CB0A9DCh + UPDATE 38, {esp+wOffset} + SHA256_STEP 23, {esp+dOffset}, {esp+wOffset+ 7*sizeof(dword)}, 076F988DAh + UPDATE 39, {esp+wOffset} + SHA256_STEP 24, {esp+dOffset}, {esp+wOffset+ 8*sizeof(dword)}, 0983E5152h + UPDATE 40, {esp+wOffset} + SHA256_STEP 25, {esp+dOffset}, {esp+wOffset+ 9*sizeof(dword)}, 0A831C66Dh + UPDATE 41, {esp+wOffset} + SHA256_STEP 26, {esp+dOffset}, {esp+wOffset+10*sizeof(dword)}, 0B00327C8h + UPDATE 42, {esp+wOffset} + SHA256_STEP 27, {esp+dOffset}, {esp+wOffset+11*sizeof(dword)}, 0BF597FC7h + UPDATE 43, {esp+wOffset} + SHA256_STEP 28, {esp+dOffset}, {esp+wOffset+12*sizeof(dword)}, 0C6E00BF3h + UPDATE 44, {esp+wOffset} + SHA256_STEP 29, {esp+dOffset}, {esp+wOffset+13*sizeof(dword)}, 0D5A79147h + UPDATE 45, {esp+wOffset} + SHA256_STEP 30, {esp+dOffset}, {esp+wOffset+14*sizeof(dword)}, 006CA6351h + UPDATE 46, {esp+wOffset} + SHA256_STEP 31, {esp+dOffset}, {esp+wOffset+15*sizeof(dword)}, 014292967h + UPDATE 47, {esp+wOffset} + + SHA256_STEP 32, {esp+dOffset}, {esp+wOffset+ 0*sizeof(dword)}, 027B70A85h + UPDATE 48, {esp+wOffset} + SHA256_STEP 33, {esp+dOffset}, {esp+wOffset+ 1*sizeof(dword)}, 02E1B2138h + UPDATE 49, {esp+wOffset} + SHA256_STEP 34, {esp+dOffset}, {esp+wOffset+ 2*sizeof(dword)}, 04D2C6DFCh + UPDATE 50, {esp+wOffset} + SHA256_STEP 35, {esp+dOffset}, {esp+wOffset+ 3*sizeof(dword)}, 053380D13h + UPDATE 51, {esp+wOffset} + SHA256_STEP 36, {esp+dOffset}, {esp+wOffset+ 4*sizeof(dword)}, 0650A7354h + UPDATE 52, {esp+wOffset} + SHA256_STEP 37, {esp+dOffset}, {esp+wOffset+ 5*sizeof(dword)}, 0766A0ABBh + UPDATE 53, {esp+wOffset} + SHA256_STEP 38, {esp+dOffset}, {esp+wOffset+ 6*sizeof(dword)}, 081C2C92Eh + UPDATE 54, {esp+wOffset} + SHA256_STEP 39, {esp+dOffset}, {esp+wOffset+ 7*sizeof(dword)}, 092722C85h + UPDATE 55, {esp+wOffset} + SHA256_STEP 40, {esp+dOffset}, {esp+wOffset+ 8*sizeof(dword)}, 0A2BFE8A1h + UPDATE 56, {esp+wOffset} + SHA256_STEP 41, {esp+dOffset}, {esp+wOffset+ 9*sizeof(dword)}, 0A81A664Bh + UPDATE 57, {esp+wOffset} + SHA256_STEP 42, {esp+dOffset}, {esp+wOffset+10*sizeof(dword)}, 0C24B8B70h + UPDATE 58, {esp+wOffset} + SHA256_STEP 43, {esp+dOffset}, {esp+wOffset+11*sizeof(dword)}, 0C76C51A3h + UPDATE 59, {esp+wOffset} + SHA256_STEP 44, {esp+dOffset}, {esp+wOffset+12*sizeof(dword)}, 0D192E819h + UPDATE 60, {esp+wOffset} + SHA256_STEP 45, {esp+dOffset}, {esp+wOffset+13*sizeof(dword)}, 0D6990624h + UPDATE 61, {esp+wOffset} + SHA256_STEP 46, {esp+dOffset}, {esp+wOffset+14*sizeof(dword)}, 0F40E3585h + UPDATE 62, {esp+wOffset} + SHA256_STEP 47, {esp+dOffset}, {esp+wOffset+15*sizeof(dword)}, 0106AA070h + UPDATE 63, {esp+wOffset} + + SHA256_STEP 48, {esp+dOffset}, {esp+wOffset+ 0*sizeof(dword)}, 019A4C116h + SHA256_STEP 49, {esp+dOffset}, {esp+wOffset+ 1*sizeof(dword)}, 01E376C08h + SHA256_STEP 50, {esp+dOffset}, {esp+wOffset+ 2*sizeof(dword)}, 02748774Ch + SHA256_STEP 51, {esp+dOffset}, {esp+wOffset+ 3*sizeof(dword)}, 034B0BCB5h + SHA256_STEP 52, {esp+dOffset}, {esp+wOffset+ 4*sizeof(dword)}, 0391C0CB3h + SHA256_STEP 53, {esp+dOffset}, {esp+wOffset+ 5*sizeof(dword)}, 04ED8AA4Ah + SHA256_STEP 54, {esp+dOffset}, {esp+wOffset+ 6*sizeof(dword)}, 05B9CCA4Fh + SHA256_STEP 55, {esp+dOffset}, {esp+wOffset+ 7*sizeof(dword)}, 0682E6FF3h + SHA256_STEP 56, {esp+dOffset}, {esp+wOffset+ 8*sizeof(dword)}, 0748F82EEh + SHA256_STEP 57, {esp+dOffset}, {esp+wOffset+ 9*sizeof(dword)}, 078A5636Fh + SHA256_STEP 58, {esp+dOffset}, {esp+wOffset+10*sizeof(dword)}, 084C87814h + SHA256_STEP 59, {esp+dOffset}, {esp+wOffset+11*sizeof(dword)}, 08CC70208h + SHA256_STEP 60, {esp+dOffset}, {esp+wOffset+12*sizeof(dword)}, 090BEFFFAh + SHA256_STEP 61, {esp+dOffset}, {esp+wOffset+13*sizeof(dword)}, 0A4506CEBh + SHA256_STEP 62, {esp+dOffset}, {esp+wOffset+14*sizeof(dword)}, 0BEF9A3F7h + SHA256_STEP 63, {esp+dOffset}, {esp+wOffset+15*sizeof(dword)}, 0C67178F2h + +; +; update digest +; + mov edi,[esp+hashOffset] + mov esi,[esp+msgOffset] + + mov eax,[esp+dOffset+vA*sizeof(dword)] + mov ebx,[esp+dOffset+vB*sizeof(dword)] + mov ecx,[esp+dOffset+vC*sizeof(dword)] + mov edx,[esp+dOffset+vD*sizeof(dword)] + add [edi+0*sizeof(dword)],eax + add [edi+1*sizeof(dword)],ebx + add [edi+2*sizeof(dword)],ecx + add [edi+3*sizeof(dword)],edx + mov eax,[esp+dOffset+vE*sizeof(dword)] + mov ebx,[esp+dOffset+vF*sizeof(dword)] + mov ecx,[esp+dOffset+vG*sizeof(dword)] + mov edx,[esp+dOffset+vH*sizeof(dword)] + add [edi+4*sizeof(dword)],eax + add [edi+5*sizeof(dword)],ebx + add [edi+6*sizeof(dword)],ecx + add [edi+7*sizeof(dword)],edx + + mov eax,[esp+lenOffset] + add esi, MBS_SHA256 + sub eax, MBS_SHA256 + jg .sha256_block_loop + + add esp,stackSize ; remove local buffers + REST_GPR + ret +ENDFUNC UpdateSHA256 + +%endif ;; (_IPP >= _IPP_M5) && (_IPP < _IPP_V8) +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha512g9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha512g9as.asm new file mode 100644 index 000000000..96ee3d900 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha512g9as.asm @@ -0,0 +1,441 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA512 +; +; Content: +; UpdateSHA512 +; +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA512_) +%if (_IPP >= _IPP_G9) + +;; +;; ENDIANNESS +;; +%macro ENDIANNESS 2.nolist + %xdefine %%xmm %1 + %xdefine %%masks %2 + + vpshufb %%xmm, %%xmm, %%masks +%endmacro + + +;; +;; Rotate Right +;; +%macro PRORQ 3.nolist + %xdefine %%mm %1 + %xdefine %%nbits %2 + %xdefine %%tmp %3 + + vpsllq %%tmp, %%mm, (64-%%nbits) + vpsrlq %%mm, %%mm, %%nbits + vpor %%mm, %%mm,%%tmp +%endmacro + + + +;; +;; Init and Update W: +;; +;; j = 0-15 +;; W[j] = ENDIANNESS(src) +;; +;; j = 16-79 +;; W[j] = SIGMA1(W[j- 2]) + W[j- 7] +;; +SIGMA0(W[j-15]) + W[j-16] +;; +;; SIGMA0(x) = ROR64(x,1) ^ROR64(x,8) ^LSR64(x,7) +;; SIGMA1(x) = ROR64(x,19)^ROR64(x,61)^LSR64(x,6) +;; +%macro SIGMA0 4.nolist + %xdefine %%sigma %1 + %xdefine %%x %2 + %xdefine %%t1 %3 + %xdefine %%t2 %4 + + vpsrlq %%sigma, %%x, 7 + vmovdqa %%t1, %%x + PRORQ %%x, 1, %%t2 + vpxor %%sigma, %%sigma, %%x + PRORQ %%t1,8, %%t2 + vpxor %%sigma, %%sigma, %%t1 +%endmacro + + +%macro SIGMA1 4.nolist + %xdefine %%sigma %1 + %xdefine %%x %2 + %xdefine %%t1 %3 + %xdefine %%t2 %4 + + vpsrlq %%sigma, %%x, 6 + vmovdqa %%t1, %%x + PRORQ %%x, 19, %%t2 + vpxor %%sigma, %%sigma, %%x + PRORQ %%t1,61, %%t2 + vpxor %%sigma, %%sigma, %%t1 +%endmacro + + + +;; +;; SHA512 step +;; +;; Ipp64u T1 = H + SUM1(E) + CHJ(E,F,G) + K_SHA512[t] + W[t]; +;; Ipp64u T2 = SUM0(A) + MAJ(A,B,C); +;; D+= T1; +;; H = T1 + T2; +;; +;; where +;; SUM1(x) = ROR64(x,14) ^ ROR64(x,18) ^ ROR64(x,41) +;; SUM0(x) = ROR64(x,28) ^ ROR64(x,34) ^ ROR64(x,39) +;; +;; CHJ(x,y,z) = (x & y) ^ (~x & z) => x&(y^z) ^z +;; MAJ(x,y,z) = (x & y) ^ (x & z) ^ (y & z) = (x&y)^((x^y)&z) +;; +;; Input: +;; A,B,C,D,E,F,G,H - 8 digest's values +;; pW - pointer to the W array +;; pK512 - pointer to the constants +;; pBuffer - temporary buffer +;; Output: +;; A,B,C,D*,E,F,G,H* - 8 digest's values (D and H updated) +;; pW - pointer to the W array +;; pK512 - pointer to the constants +;; pBuffer - temporary buffer (changed) +;; +%macro CHJ 5.nolist + %xdefine %%R %1 + %xdefine %%E %2 + %xdefine %%F %3 + %xdefine %%G %4 + %xdefine %%T %5 + + vpxor %%R, %%F,%%G ; R=(f^g) + vpand %%R, %%R,%%E ; R=e & (f^g) + vpxor %%R, %%R,%%G ; R=e & (f^g) ^g +%endmacro + + +%macro MAJ 5.nolist + %xdefine %%R %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%T %5 + + vpxor %%T, %%A,%%B ; T=a^b + vpand %%R, %%A,%%B ; R=a&b + vpand %%T, %%T,%%C ; T=(a^b)&c + vpxor %%R, %%R,%%T ; R=(a&b)^((a^b)&c) +%endmacro + + +%macro SUM0 3.nolist + %xdefine %%R %1 + %xdefine %%X %2 + %xdefine %%tmp %3 + + vmovdqa %%R,%%X + PRORQ %%R,28,%%tmp ; R=ROR(X,28) + PRORQ %%X,34,%%tmp ; X=ROR(X,34) + vpxor %%R, %%R,%%X + PRORQ %%X,(39-34),%%tmp ; X=ROR(x,39) + vpxor %%R, %%R,%%X +%endmacro + + +%macro SUM1 3.nolist + %xdefine %%R %1 + %xdefine %%X %2 + %xdefine %%tmp %3 + + vmovdqa %%R,%%X + PRORQ %%R,14,%%tmp ; R=ROR(X,14) + PRORQ %%X,18,%%tmp ; X=ROR(X,18) + vpxor %%R, %%R,%%X + PRORQ %%X,(41-18),%%tmp ; X=ROR(x,41) + vpxor %%R, %%R,%%X +%endmacro + + +%macro SHA512_STEP 11.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%F %6 + %xdefine %%G %7 + %xdefine %%H %8 + %xdefine %%pW %9 + %xdefine %%pK512 %10 + %xdefine %%pBuffer %11 + + vmovdqa oword [%%pBuffer+0*sizeof(oword)],%%E ; save E + vmovdqa oword [%%pBuffer+1*sizeof(oword)],%%A ; save A + + vmovdqa oword [%%pBuffer+2*sizeof(oword)],%%D ; save D + vmovdqa oword [%%pBuffer+3*sizeof(oword)],%%H ; save H + + CHJ %%D,%%E,%%F,%%G, %%H ; t1 = h+CHJ(e,f,g)+pW[]+pK512[] + vmovq %%H, qword [%%pW] + vpaddq %%D, %%D,%%H ; +[pW] + vmovq %%H, qword [%%pK512] + vpaddq %%D, %%D,%%H ; +[pK512] + vpaddq %%D, %%D,oword [%%pBuffer+3*sizeof(oword)] + vmovdqa oword [%%pBuffer+3*sizeof(oword)],%%D ; save t1 + + MAJ %%H,%%A,%%B,%%C, %%D ; t2 = MAJ(a,b,c) + vmovdqa oword [%%pBuffer+4*sizeof(oword)],%%H ; save t2 + + SUM1 %%D,%%E,%%H ; D = SUM1(e) + vpaddq %%D, %%D,oword [%%pBuffer+3*sizeof(oword)]; t1 = h+CHJ(e,f,g)+pW[]+pK512[] + SUM1(e) + + SUM0 %%H,%%A,%%E ; H = SUM0(a) + vpaddq %%H, %%H,oword [%%pBuffer+4*sizeof(oword)]; t2 = MAJ(a,b,c)+SUM0(a) + + vpaddq %%H, %%H,%%D ; h = t1+t2 + vpaddq %%D, %%D,oword [%%pBuffer+2*sizeof(oword)]; d+= t1 + + vmovdqa %%E,oword [%%pBuffer+0*sizeof(oword)] ; restore E + vmovdqa %%A,oword [%%pBuffer+1*sizeof(oword)] ; restore A +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + +%if (_IPP >= _IPP_V8) +align IPP_ALIGN_FACTOR +SWP_BYTE: +pByteSwp DB 7,6,5,4,3,2,1,0, 15,14,13,12,11,10,9,8 +%endif + +;******************************************************************************************* +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA512(DigestSHA512 digest, const Ipp64u* mblk, int mlen, const void* pParam) +;* +;******************************************************************************************* + +;; +;; Lib = W7, V8, P8 +;; +;; Caller = ippsSHA512Update +;; Caller = ippsSHA512Final +;; Caller = ippsSHA512MessageDigest +;; +;; Caller = ippsSHA384Update +;; Caller = ippsSHA384Final +;; Caller = ippsSHA384MessageDigest +;; +;; Caller = ippsHMACSHA512Update +;; Caller = ippsHMACSHA512Final +;; Caller = ippsHMACSHA512MessageDigest +;; +;; Caller = ippsHMACSHA384Update +;; Caller = ippsHMACSHA384Final +;; Caller = ippsHMACSHA384MessageDigest +;; +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA512,PUBLIC + USES_GPR esi,edi,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine digest [ebp + ARG_1 + 0*sizeof(dword)] ; digest address +%xdefine mblk [ebp + ARG_1 + 1*sizeof(dword)] ; buffer address +%xdefine mlen [ebp + ARG_1 + 2*sizeof(dword)] ; buffer length +%xdefine pSHA512 [ebp + ARG_1 + 3*sizeof(dword)] ; address of SHA constants + +%xdefine MBS_SHA512 (128) ; SHA512 block data size + +%assign sSize 5 ; size of save area (oword) +%assign dSize 8 ; size of digest (oword) +%assign wSize 80 ; W values queue (qword) +%assign stackSize (sSize*sizeof(oword)+dSize*sizeof(oword)+wSize*sizeof(qword)+sizeof(dword)) ; stack size (bytes) + +%assign sOffset 0 ; save area +%assign dOffset sOffset+sSize*sizeof(oword) ; digest offset +%assign wOffset dOffset+dSize*sizeof(oword) ; W values offset +%assign acualOffset wOffset+wSize*sizeof(qword) ; actual stack size offset + + mov edi,digest ; digest address + mov esi,mblk ; source data address + mov eax,mlen ; source data length + + mov edx, pSHA512 ; table constant address + + sub esp,stackSize ; allocate local buffer (probably unaligned) + mov ecx,esp + and esp,-16 ; 16-byte aligned stack + sub ecx,esp + add ecx,stackSize ; acual stack size (bytes) + mov [esp+acualOffset],ecx + + vmovq xmm0,qword [edi+sizeof(qword)*0] ; A = digest[0] + vmovq xmm1,qword [edi+sizeof(qword)*1] ; B = digest[1] + vmovq xmm2,qword [edi+sizeof(qword)*2] ; C = digest[2] + vmovq xmm3,qword [edi+sizeof(qword)*3] ; D = digest[3] + vmovq xmm4,qword [edi+sizeof(qword)*4] ; E = digest[4] + vmovq xmm5,qword [edi+sizeof(qword)*5] ; F = digest[5] + vmovq xmm6,qword [edi+sizeof(qword)*6] ; G = digest[6] + vmovq xmm7,qword [edi+sizeof(qword)*7] ; H = digest[7] + vmovdqa oword [esp+dOffset+sizeof(oword)*0], xmm0 + vmovdqa oword [esp+dOffset+sizeof(oword)*1], xmm1 + vmovdqa oword [esp+dOffset+sizeof(oword)*2], xmm2 + vmovdqa oword [esp+dOffset+sizeof(oword)*3], xmm3 + vmovdqa oword [esp+dOffset+sizeof(oword)*4], xmm4 + vmovdqa oword [esp+dOffset+sizeof(oword)*5], xmm5 + vmovdqa oword [esp+dOffset+sizeof(oword)*6], xmm6 + vmovdqa oword [esp+dOffset+sizeof(oword)*7], xmm7 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.sha512_block_loop: + +;; +;; initialize the first 16 qwords in the array W (remember about endian) +;; + ;vmovdqa xmm1, oword pByteSwp ; load shuffle mask + LD_ADDR ecx, SWP_BYTE + movdqa xmm1, oword [ecx+(pByteSwp-SWP_BYTE)] + mov ecx,0 +align IPP_ALIGN_FACTOR +.loop1: + vmovdqu xmm0, oword [esi+ecx*sizeof(qword)] ; swap input + ENDIANNESS xmm0, xmm1 + vmovdqa oword [esp+wOffset+ecx*sizeof(qword)],xmm0 + add ecx,sizeof(oword)/sizeof(qword) + cmp ecx,16 + jl .loop1 + +;; +;; initialize another 80-16 qwords in the array W +;; +align IPP_ALIGN_FACTOR +.loop2: + vmovdqa xmm1,oword [esp+ecx*sizeof(qword)+wOffset- 2*sizeof(qword)] ; xmm1 = W[j-2] + SIGMA1 xmm0,xmm1,xmm2,xmm3 + + vmovdqu xmm5,oword [esp+ecx*sizeof(qword)+wOffset-15*sizeof(qword)] ; xmm5 = W[j-15] + SIGMA0 xmm4,xmm5,xmm6,xmm3 + + vmovdqu xmm7,oword [esp+ecx*sizeof(qword)+wOffset- 7*sizeof(qword)] ; W[j-7] + vpaddq xmm0, xmm0,xmm4 + vpaddq xmm7, xmm7,oword [esp+ecx*sizeof(qword)+wOffset-16*sizeof(qword)] ; W[j-16] + vpaddq xmm0, xmm0,xmm7 + vmovdqa oword [esp+ecx*sizeof(qword)+wOffset],xmm0 + + add ecx,sizeof(oword)/sizeof(qword) + cmp ecx,80 + jl .loop2 + +;; +;; init A,B,C,D,E,F,G,H by the internal digest +;; + vmovdqa xmm0,oword [esp+dOffset+sizeof(oword)*0] ; A = digest[0] + vmovdqa xmm1,oword [esp+dOffset+sizeof(oword)*1] ; B = digest[1] + vmovdqa xmm2,oword [esp+dOffset+sizeof(oword)*2] ; C = digest[2] + vmovdqa xmm3,oword [esp+dOffset+sizeof(oword)*3] ; D = digest[3] + vmovdqa xmm4,oword [esp+dOffset+sizeof(oword)*4] ; E = digest[4] + vmovdqa xmm5,oword [esp+dOffset+sizeof(oword)*5] ; F = digest[5] + vmovdqa xmm6,oword [esp+dOffset+sizeof(oword)*6] ; G = digest[6] + vmovdqa xmm7,oword [esp+dOffset+sizeof(oword)*7] ; H = digest[7] + +;; +;; perform 0-79 steps +;; + xor ecx,ecx +align IPP_ALIGN_FACTOR +.loop3: +;; A, B, C, D, E, F, G, H W[], K[], buffer +;; -------------------------------------------------------------------------------------------------------------------------------------- + SHA512_STEP xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*0},{edx+ecx*sizeof(qword)+sizeof(qword)*0}, {esp} + SHA512_STEP xmm7,xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*1},{edx+ecx*sizeof(qword)+sizeof(qword)*1}, {esp} + SHA512_STEP xmm6,xmm7,xmm0,xmm1,xmm2,xmm3,xmm4,xmm5, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*2},{edx+ecx*sizeof(qword)+sizeof(qword)*2}, {esp} + SHA512_STEP xmm5,xmm6,xmm7,xmm0,xmm1,xmm2,xmm3,xmm4, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*3},{edx+ecx*sizeof(qword)+sizeof(qword)*3}, {esp} + SHA512_STEP xmm4,xmm5,xmm6,xmm7,xmm0,xmm1,xmm2,xmm3, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*4},{edx+ecx*sizeof(qword)+sizeof(qword)*4}, {esp} + SHA512_STEP xmm3,xmm4,xmm5,xmm6,xmm7,xmm0,xmm1,xmm2, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*5},{edx+ecx*sizeof(qword)+sizeof(qword)*5}, {esp} + SHA512_STEP xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm0,xmm1, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*6},{edx+ecx*sizeof(qword)+sizeof(qword)*6}, {esp} + SHA512_STEP xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm0, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*7},{edx+ecx*sizeof(qword)+sizeof(qword)*7}, {esp} + + add ecx,8 + cmp ecx,80 + jl .loop3 + +;; +;; update digest +;; + vpaddq xmm0, xmm0,oword [esp+dOffset+sizeof(oword)*0] ; A += digest[0] + vpaddq xmm1, xmm1,oword [esp+dOffset+sizeof(oword)*1] ; B += digest[1] + vpaddq xmm2, xmm2,oword [esp+dOffset+sizeof(oword)*2] ; C += digest[2] + vpaddq xmm3, xmm3,oword [esp+dOffset+sizeof(oword)*3] ; D += digest[3] + vpaddq xmm4, xmm4,oword [esp+dOffset+sizeof(oword)*4] ; E += digest[4] + vpaddq xmm5, xmm5,oword [esp+dOffset+sizeof(oword)*5] ; F += digest[5] + vpaddq xmm6, xmm6,oword [esp+dOffset+sizeof(oword)*6] ; G += digest[6] + vpaddq xmm7, xmm7,oword [esp+dOffset+sizeof(oword)*7] ; H += digest[7] + + vmovdqa oword [esp+dOffset+sizeof(oword)*0],xmm0 ; digest[0] = A + vmovdqa oword [esp+dOffset+sizeof(oword)*1],xmm1 ; digest[1] = B + vmovdqa oword [esp+dOffset+sizeof(oword)*2],xmm2 ; digest[2] = C + vmovdqa oword [esp+dOffset+sizeof(oword)*3],xmm3 ; digest[3] = D + vmovdqa oword [esp+dOffset+sizeof(oword)*4],xmm4 ; digest[4] = E + vmovdqa oword [esp+dOffset+sizeof(oword)*5],xmm5 ; digest[5] = F + vmovdqa oword [esp+dOffset+sizeof(oword)*6],xmm6 ; digest[6] = G + vmovdqa oword [esp+dOffset+sizeof(oword)*7],xmm7 ; digest[7] = H + + add esi, MBS_SHA512 + sub eax, MBS_SHA512 + jg .sha512_block_loop + + vmovq qword [edi+sizeof(qword)*0], xmm0 ; A = digest[0] + vmovq qword [edi+sizeof(qword)*1], xmm1 ; B = digest[1] + vmovq qword [edi+sizeof(qword)*2], xmm2 ; C = digest[2] + vmovq qword [edi+sizeof(qword)*3], xmm3 ; D = digest[3] + vmovq qword [edi+sizeof(qword)*4], xmm4 ; E = digest[4] + vmovq qword [edi+sizeof(qword)*5], xmm5 ; F = digest[5] + vmovq qword [edi+sizeof(qword)*6], xmm6 ; G = digest[6] + vmovq qword [edi+sizeof(qword)*7], xmm7 ; H = digest[7] + + add esp,[esp+acualOffset] + REST_GPR + ret +ENDFUNC UpdateSHA512 + +%endif ;; (_IPP >= _IPP_G9) +%endif ;; _ENABLE_ALG_SHA512_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha512w7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha512w7as.asm new file mode 100644 index 000000000..395e06e11 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsha512w7as.asm @@ -0,0 +1,463 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA512 +; +; Content: +; UpdateSHA512 +; +; + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA512_) +%if (_IPP >= _IPP_W7) && (_IPP < _IPP_G9) + +;; +;; ENDIANNESS +;; +%if (_IPP >= _IPP_V8) +%macro ENDIANNESS 2.nolist + %xdefine %%xmm %1 + %xdefine %%masks %2 + + pshufb %%xmm, %%masks +%endmacro + + +%else +%macro ENDIANNESS 2.nolist + %xdefine %%xmm %1 + %xdefine %%tmp %2 + + pshuflw %%xmm,%%xmm, 00011011b + pshufhw %%xmm,%%xmm, 00011011b + movdqa %%tmp,%%xmm + psrlw %%tmp,8 + psllw %%xmm,8 + por %%xmm,%%tmp +%endmacro + +%endif + +;; +;; Rotate Right +;; +%macro PRORQ 3.nolist + %xdefine %%mm %1 + %xdefine %%nbits %2 + %xdefine %%tmp %3 + + movdqa %%tmp,%%mm + psrlq %%mm,%%nbits + psllq %%tmp,(64-%%nbits) + por %%mm,%%tmp +%endmacro + + + +;; +;; Init and Update W: +;; +;; j = 0-15 +;; W[j] = ENDIANNESS(src) +;; +;; j = 16-79 +;; W[j] = SIGMA1(W[j- 2]) + W[j- 7] +;; +SIGMA0(W[j-15]) + W[j-16] +;; +;; SIGMA0(x) = ROR64(x,1) ^ROR64(x,8) ^LSR64(x,7) +;; SIGMA1(x) = ROR64(x,19)^ROR64(x,61)^LSR64(x,6) +;; +%macro SIGMA0 4.nolist + %xdefine %%sigma %1 + %xdefine %%x %2 + %xdefine %%t1 %3 + %xdefine %%t2 %4 + + movdqa %%sigma, %%x + psrlq %%x, 7 + movdqa %%t1,%%sigma + PRORQ %%sigma, 1, %%t2 + pxor %%sigma, %%x + PRORQ %%t1,8, %%t2 + pxor %%sigma, %%t1 +%endmacro + + +%macro SIGMA1 4.nolist + %xdefine %%sigma %1 + %xdefine %%x %2 + %xdefine %%t1 %3 + %xdefine %%t2 %4 + + movdqa %%sigma, %%x + psrlq %%x, 6 + movdqa %%t1,%%sigma + PRORQ %%sigma, 19, %%t2 + pxor %%sigma, %%x + PRORQ %%t1,61, %%t2 + pxor %%sigma, %%t1 +%endmacro + + + +;; +;; SHA512 step +;; +;; Ipp64u T1 = H + SUM1(E) + CHJ(E,F,G) + K_SHA512[t] + W[t]; +;; Ipp64u T2 = SUM0(A) + MAJ(A,B,C); +;; D+= T1; +;; H = T1 + T2; +;; +;; where +;; SUM1(x) = ROR64(x,14) ^ ROR64(x,18) ^ ROR64(x,41) +;; SUM0(x) = ROR64(x,28) ^ ROR64(x,34) ^ ROR64(x,39) +;; +;; CHJ(x,y,z) = (x & y) ^ (~x & z) => x&(y^z) ^z +;; MAJ(x,y,z) = (x & y) ^ (x & z) ^ (y & z) = (x&y)^((x^y)&z) +;; +;; Input: +;; A,B,C,D,E,F,G,H - 8 digest's values +;; pW - pointer to the W array +;; pK512 - pointer to the constants +;; pBuffer - temporary buffer +;; Output: +;; A,B,C,D*,E,F,G,H* - 8 digest's values (D and H updated) +;; pW - pointer to the W array +;; pK512 - pointer to the constants +;; pBuffer - temporary buffer (changed) +;; +%macro CHJ 5.nolist + %xdefine %%R %1 + %xdefine %%E %2 + %xdefine %%F %3 + %xdefine %%G %4 + %xdefine %%T %5 + + movdqa %%R,%%F ; R=f + pxor %%R,%%G ; R=(f^g) + pand %%R,%%E ; R=e & (f^g) + pxor %%R,%%G ; R=e & (f^g) ^g +%endmacro + + +%macro MAJ 5.nolist + %xdefine %%R %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%T %5 + + movdqa %%T,%%B ; T=b + movdqa %%R,%%A ; R=a + pxor %%T,%%A ; T=a^b + pand %%R,%%B ; R=a&b + pand %%T,%%C ; T=(a^b)&c + pxor %%R,%%T ; R=(a&b)^((a^b)&c) +%endmacro + + +%macro SUM0 3.nolist + %xdefine %%R %1 + %xdefine %%X %2 + %xdefine %%tmp %3 + + movdqa %%R,%%X + PRORQ %%R,28,%%tmp ; R=ROR(X,28) + PRORQ %%X,34,%%tmp ; X=ROR(X,34) + pxor %%R,%%X + PRORQ %%X,(39-34),%%tmp ; X=ROR(x,39) + pxor %%R,%%X +%endmacro + + +%macro SUM1 3.nolist + %xdefine %%R %1 + %xdefine %%X %2 + %xdefine %%tmp %3 + + movdqa %%R,%%X + PRORQ %%R,14,%%tmp ; R=ROR(X,14) + PRORQ %%X,18,%%tmp ; X=ROR(X,18) + pxor %%R,%%X + PRORQ %%X,(41-18),%%tmp ; X=ROR(x,41) + pxor %%R,%%X +%endmacro + + +%macro SHA512_STEP 11.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%F %6 + %xdefine %%G %7 + %xdefine %%H %8 + %xdefine %%pW %9 + %xdefine %%pK512 %10 + %xdefine %%pBuffer %11 + + movdqa oword [%%pBuffer+0*sizeof(oword)],%%E ; save E + movdqa oword [%%pBuffer+1*sizeof(oword)],%%A ; save A + + movdqa oword [%%pBuffer+2*sizeof(oword)],%%D ; save D + movdqa oword [%%pBuffer+3*sizeof(oword)],%%H ; save H + + CHJ %%D,%%E,%%F,%%G, %%H ; t1 = h+CHJ(e,f,g)+pW[]+pK512[] + movq %%H, qword [%%pW] + paddq %%D, %%H ; +[pW] + movq %%H, qword [%%pK512] + paddq %%D, %%H ; +[pK512] + paddq %%D,oword [%%pBuffer+3*sizeof(oword)] + movdqa oword [%%pBuffer+3*sizeof(oword)],%%D ; save t1 + + MAJ %%H,%%A,%%B,%%C, %%D ; t2 = MAJ(a,b,c) + movdqa oword [%%pBuffer+4*sizeof(oword)],%%H ; save t2 + + SUM1 %%D,%%E,%%H ; D = SUM1(e) + paddq %%D,oword [%%pBuffer+3*sizeof(oword)] ; t1 = h+CHJ(e,f,g)+pW[]+pK512[] + SUM1(e) + + SUM0 %%H,%%A,%%E ; H = SUM0(a) + paddq %%H,oword [%%pBuffer+4*sizeof(oword)] ; t2 = MAJ(a,b,c)+SUM0(a) + + paddq %%H,%%D ; h = t1+t2 + paddq %%D,oword [%%pBuffer+2*sizeof(oword)] ; d+= t1 + + movdqa %%E,oword [%%pBuffer+0*sizeof(oword)] ; restore E + movdqa %%A,oword [%%pBuffer+1*sizeof(oword)] ; restore A +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + +%if (_IPP >= _IPP_V8) +align IPP_ALIGN_FACTOR +SWP_BYTE: +pByteSwp DB 7,6,5,4,3,2,1,0, 15,14,13,12,11,10,9,8 +%endif + +;******************************************************************************************* +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA512(DigestSHA512 digest, const Ipp64u* mblk, int mlen, const void* pParam) +;* +;******************************************************************************************* + +;; +;; Lib = W7, V8, P8 +;; +;; Caller = ippsSHA512Update +;; Caller = ippsSHA512Final +;; Caller = ippsSHA512MessageDigest +;; +;; Caller = ippsSHA384Update +;; Caller = ippsSHA384Final +;; Caller = ippsSHA384MessageDigest +;; +;; Caller = ippsHMACSHA512Update +;; Caller = ippsHMACSHA512Final +;; Caller = ippsHMACSHA512MessageDigest +;; +;; Caller = ippsHMACSHA384Update +;; Caller = ippsHMACSHA384Final +;; Caller = ippsHMACSHA384MessageDigest +;; +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA512,PUBLIC + USES_GPR esi,edi + +%xdefine digest [esp + ARG_1 + 0*sizeof(dword)] ; digest address +%xdefine mblk [esp + ARG_1 + 1*sizeof(dword)] ; buffer address +%xdefine mlen [esp + ARG_1 + 2*sizeof(dword)] ; buffer length +%xdefine pSHA512 [esp + ARG_1 + 3*sizeof(dword)] ; address of SHA constants + +%xdefine MBS_SHA512 (128) ; SHA512 block data size + +%assign sSize 5 ; size of save area (oword) +%assign dSize 8 ; size of digest (oword) +%assign wSize 80 ; W values queue (qword) +%assign stackSize (sSize*sizeof(oword)+dSize*sizeof(oword)+wSize*sizeof(qword)+sizeof(dword)) ; stack size (bytes) + +%assign sOffset 0 ; save area +%assign dOffset sOffset+sSize*sizeof(oword) ; digest offset +%assign wOffset dOffset+dSize*sizeof(oword) ; W values offset +%assign acualOffset wOffset+wSize*sizeof(qword) ; actual stack size offset + + mov edi,digest ; digest address + mov esi,mblk ; source data address + mov eax,mlen ; source data length + + mov edx, pSHA512 ; table constant address + + sub esp,stackSize ; allocate local buffer (probably unaligned) + mov ecx,esp + and esp,-16 ; 16-byte aligned stack + sub ecx,esp + add ecx,stackSize ; acual stack size (bytes) + mov [esp+acualOffset],ecx + + movq xmm0,qword [edi+sizeof(qword)*0] ; A = digest[0] + movq xmm1,qword [edi+sizeof(qword)*1] ; B = digest[1] + movq xmm2,qword [edi+sizeof(qword)*2] ; C = digest[2] + movq xmm3,qword [edi+sizeof(qword)*3] ; D = digest[3] + movq xmm4,qword [edi+sizeof(qword)*4] ; E = digest[4] + movq xmm5,qword [edi+sizeof(qword)*5] ; F = digest[5] + movq xmm6,qword [edi+sizeof(qword)*6] ; G = digest[6] + movq xmm7,qword [edi+sizeof(qword)*7] ; H = digest[7] + movdqa oword [esp+dOffset+sizeof(oword)*0], xmm0 + movdqa oword [esp+dOffset+sizeof(oword)*1], xmm1 + movdqa oword [esp+dOffset+sizeof(oword)*2], xmm2 + movdqa oword [esp+dOffset+sizeof(oword)*3], xmm3 + movdqa oword [esp+dOffset+sizeof(oword)*4], xmm4 + movdqa oword [esp+dOffset+sizeof(oword)*5], xmm5 + movdqa oword [esp+dOffset+sizeof(oword)*6], xmm6 + movdqa oword [esp+dOffset+sizeof(oword)*7], xmm7 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.sha512_block_loop: + +;; +;; initialize the first 16 qwords in the array W (remember about endian) +;; +%if (_IPP >= _IPP_V8) + ;movdqa xmm1, oword pByteSwp ; load shuffle mask + LD_ADDR ecx, SWP_BYTE + movdqa xmm1, oword [ecx+(pByteSwp-SWP_BYTE)] +%endif + mov ecx,0 +align IPP_ALIGN_FACTOR +.loop1: + movdqu xmm0, oword [esi+ecx*sizeof(qword)] ; swap input + ENDIANNESS xmm0, xmm1 + movdqa oword [esp+wOffset+ecx*sizeof(qword)],xmm0 + add ecx,sizeof(oword)/sizeof(qword) + cmp ecx,16 + jl .loop1 + +;; +;; initialize another 80-16 qwords in the array W +;; +align IPP_ALIGN_FACTOR +.loop2: + movdqa xmm1,oword [esp+ecx*sizeof(qword)+wOffset- 2*sizeof(qword)] ; xmm1 = W[j-2] + SIGMA1 xmm0,xmm1,xmm2,xmm3 + + movdqu xmm5,oword [esp+ecx*sizeof(qword)+wOffset-15*sizeof(qword)] ; xmm5 = W[j-15] + SIGMA0 xmm4,xmm5,xmm6,xmm3 + + movdqu xmm7,oword [esp+ecx*sizeof(qword)+wOffset- 7*sizeof(qword)] ; W[j-7] + paddq xmm0,xmm4 + paddq xmm7,oword [esp+ecx*sizeof(qword)+wOffset-16*sizeof(qword)] ; W[j-16] + paddq xmm0,xmm7 + movdqa oword [esp+ecx*sizeof(qword)+wOffset],xmm0 + + add ecx,sizeof(oword)/sizeof(qword) + cmp ecx,80 + jl .loop2 + +;; +;; init A,B,C,D,E,F,G,H by the internal digest +;; + movdqa xmm0,oword [esp+dOffset+sizeof(oword)*0] ; A = digest[0] + movdqa xmm1,oword [esp+dOffset+sizeof(oword)*1] ; B = digest[1] + movdqa xmm2,oword [esp+dOffset+sizeof(oword)*2] ; C = digest[2] + movdqa xmm3,oword [esp+dOffset+sizeof(oword)*3] ; D = digest[3] + movdqa xmm4,oword [esp+dOffset+sizeof(oword)*4] ; E = digest[4] + movdqa xmm5,oword [esp+dOffset+sizeof(oword)*5] ; F = digest[5] + movdqa xmm6,oword [esp+dOffset+sizeof(oword)*6] ; G = digest[6] + movdqa xmm7,oword [esp+dOffset+sizeof(oword)*7] ; H = digest[7] + +;; +;; perform 0-79 steps +;; + xor ecx,ecx +align IPP_ALIGN_FACTOR +.loop3: +;; A, B, C, D, E, F, G, H W[], K[], buffer +;; -------------------------------------------------------------------------------------------------------------------------------------- + SHA512_STEP xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*0},{edx+ecx*sizeof(qword)+sizeof(qword)*0}, {esp} + SHA512_STEP xmm7,xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*1},{edx+ecx*sizeof(qword)+sizeof(qword)*1}, {esp} + SHA512_STEP xmm6,xmm7,xmm0,xmm1,xmm2,xmm3,xmm4,xmm5, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*2},{edx+ecx*sizeof(qword)+sizeof(qword)*2}, {esp} + SHA512_STEP xmm5,xmm6,xmm7,xmm0,xmm1,xmm2,xmm3,xmm4, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*3},{edx+ecx*sizeof(qword)+sizeof(qword)*3}, {esp} + SHA512_STEP xmm4,xmm5,xmm6,xmm7,xmm0,xmm1,xmm2,xmm3, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*4},{edx+ecx*sizeof(qword)+sizeof(qword)*4}, {esp} + SHA512_STEP xmm3,xmm4,xmm5,xmm6,xmm7,xmm0,xmm1,xmm2, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*5},{edx+ecx*sizeof(qword)+sizeof(qword)*5}, {esp} + SHA512_STEP xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm0,xmm1, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*6},{edx+ecx*sizeof(qword)+sizeof(qword)*6}, {esp} + SHA512_STEP xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7,xmm0, {esp+ecx*sizeof(qword)+wOffset+sizeof(qword)*7},{edx+ecx*sizeof(qword)+sizeof(qword)*7}, {esp} + + add ecx,8 + cmp ecx,80 + jl .loop3 + +;; +;; update digest +;; + paddq xmm0,oword [esp+dOffset+sizeof(oword)*0] ; A += digest[0] + paddq xmm1,oword [esp+dOffset+sizeof(oword)*1] ; B += digest[1] + paddq xmm2,oword [esp+dOffset+sizeof(oword)*2] ; C += digest[2] + paddq xmm3,oword [esp+dOffset+sizeof(oword)*3] ; D += digest[3] + paddq xmm4,oword [esp+dOffset+sizeof(oword)*4] ; E += digest[4] + paddq xmm5,oword [esp+dOffset+sizeof(oword)*5] ; F += digest[5] + paddq xmm6,oword [esp+dOffset+sizeof(oword)*6] ; G += digest[6] + paddq xmm7,oword [esp+dOffset+sizeof(oword)*7] ; H += digest[7] + + movdqa oword [esp+dOffset+sizeof(oword)*0],xmm0 ; digest[0] = A + movdqa oword [esp+dOffset+sizeof(oword)*1],xmm1 ; digest[1] = B + movdqa oword [esp+dOffset+sizeof(oword)*2],xmm2 ; digest[2] = C + movdqa oword [esp+dOffset+sizeof(oword)*3],xmm3 ; digest[3] = D + movdqa oword [esp+dOffset+sizeof(oword)*4],xmm4 ; digest[4] = E + movdqa oword [esp+dOffset+sizeof(oword)*5],xmm5 ; digest[5] = F + movdqa oword [esp+dOffset+sizeof(oword)*6],xmm6 ; digest[6] = G + movdqa oword [esp+dOffset+sizeof(oword)*7],xmm7 ; digest[7] = H + + add esi, MBS_SHA512 + sub eax, MBS_SHA512 + jg .sha512_block_loop + + movq qword [edi+sizeof(qword)*0], xmm0 ; A = digest[0] + movq qword [edi+sizeof(qword)*1], xmm1 ; B = digest[1] + movq qword [edi+sizeof(qword)*2], xmm2 ; C = digest[2] + movq qword [edi+sizeof(qword)*3], xmm3 ; D = digest[3] + movq qword [edi+sizeof(qword)*4], xmm4 ; E = digest[4] + movq qword [edi+sizeof(qword)*5], xmm5 ; F = digest[5] + movq qword [edi+sizeof(qword)*6], xmm6 ; G = digest[6] + movq qword [edi+sizeof(qword)*7], xmm7 ; H = digest[7] + + add esp,[esp+acualOffset] + REST_GPR + ret +ENDFUNC UpdateSHA512 + +%endif ;; (_IPP >= _IPP_W7) && (_IPP < _IPP_G9) +%endif ;; _ENABLE_ALG_SHA512_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsm2arith_mont_slm.asm b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsm2arith_mont_slm.asm new file mode 100644 index 000000000..d3b5b6474 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpsm2arith_mont_slm.asm @@ -0,0 +1,880 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; P256r1 basic arithmetic function +; +; Content: +; sm2_add +; sm2_sub +; sm2_neg +; sm2_div_by_2 +; sm2_mul_mont_slm +; sm2_sqr_mont_slm +; sm2_mred +; sm2_mont_back +; + + + + + + +%include "asmdefs.inc" +%include "ia_emm.inc" + +%if (_IPP >= _IPP_P8) + +segment .text align=IPP_ALIGN_FACTOR + +;; +;; some SM2 constants +;; +sm2_data: +_prime_sm2 DD 0FFFFFFFFh,0FFFFFFFFh,000000000h,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh,0FFFFFFFFh, 0FFFFFFFEh + +%assign LENSM2 (256/32) ; dword's length of operands + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Ipp32u _add_256(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = carry = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM _add_256,PRIVATE + ; r = a+b + mov eax, dword [esi] + add eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + adc eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + adc eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + adc eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + adc eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + adc eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + adc eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + adc eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC _add_256 + +;; +;; Ipp32u _sub_256(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +;; input: edi = r +;; esi = a +;; ebx = b +;; +;; output: eax = borrow = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM _sub_256,PRIVATE + ; r = a-b + mov eax, dword [esi] + sub eax, dword [ebx] + mov dword [edi], eax + + mov eax, dword [esi+sizeof(dword)] + sbb eax, dword [ebx+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + + mov eax, dword [esi+sizeof(dword)*2] + sbb eax, dword [ebx+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + + mov eax, dword [esi+sizeof(dword)*3] + sbb eax, dword [ebx+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + + mov eax, dword [esi+sizeof(dword)*4] + sbb eax, dword [ebx+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + + mov eax, dword [esi+sizeof(dword)*5] + sbb eax, dword [ebx+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + + mov eax, dword [esi+sizeof(dword)*6] + sbb eax, dword [ebx+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + + mov eax, dword [esi+sizeof(dword)*7] + sbb eax, dword [ebx+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + + mov eax, 0 + adc eax, 0 + ret +ENDFUNC _sub_256 + +;; +;; Ipp32u _shl_256(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM _shl_256,PRIVATE + ; r = a<<1 + movdqu xmm0, oword [esi] + movdqu xmm1, oword [esi+sizeof(oword)] + mov eax, dword [esi+(LENSM2-1)*sizeof(dword)] + + movdqa xmm2, xmm0 + psllq xmm0, 1 + psrlq xmm2, 63 + movdqa xmm3, xmm1 + psllq xmm1, 1 + psrlq xmm3, 63 + + palignr xmm3, xmm2, sizeof(qword) + pslldq xmm2, sizeof(qword) + + por xmm1, xmm3 + por xmm0, xmm2 + movdqu oword [edi], xmm0 + movdqu oword [edi+sizeof(oword)], xmm1 + + shr eax, 31 + ret +ENDFUNC _shl_256 + +;; +;; void _shr_256(Ipp32u* r, const Ipp32u* a) +;; +;; input: edi = r +;; esi = a +;; eax = ext +;; output: eax = extension = 0/1 +;; +align IPP_ALIGN_FACTOR +IPPASM _shr_256,PRIVATE + ; r = a>>1 + movd xmm4, eax + movdqu xmm0, oword [esi] + movdqu xmm1, oword [esi+sizeof(oword)] + + psllq xmm4, 63 + movdqa xmm2, xmm0 + psrlq xmm0, 1 + psllq xmm2, 63 + movdqa xmm3, xmm1 + psrlq xmm1, 1 + psllq xmm3, 63 + + palignr xmm4, xmm3, sizeof(qword) + palignr xmm3, xmm2, sizeof(qword) + + por xmm1, xmm4 + por xmm0, xmm3 + movdqu oword [edi], xmm0 + movdqu oword [edi+sizeof(oword)], xmm1 + + ret +ENDFUNC _shr_256 + +;; +;; void cpy_256(Ipp32u* r, const Ipp32u* a) +;; +%macro cpy_256 2.nolist + %xdefine %%pdst %1 + %xdefine %%psrc %2 + + movdqu xmm0, oword [%%psrc] + movdqu xmm1, oword [%%psrc+sizeof(oword)] + movdqu oword [%%pdst], xmm0 + movdqu oword [%%pdst+sizeof(oword)], xmm1 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_add(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_add,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LENSM2] +%assign _sp_ _buf_+(LENSM2)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM _add_256 ; R = A+B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, sm2_data ; modulus + lea ebx, [ebx+(_prime_sm2-sm2_data)] + CALL_IPPASM _sub_256 ; T = R-modulus + + lea esi,[esp+_buf_] + mov edi, pR + sub edx, eax ; R = T<0? R : T + cmovnz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC sm2_add + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_sub(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_sub,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [ebp + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LENSM2] +%assign _sp_ _buf_+(LENSM2)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; pR + mov esi, pA ; pA + mov ebx, pB ; pB + CALL_IPPASM _sub_256 ; R = A-B + mov edx, eax + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, sm2_data ; modulus + lea ebx, [ebx+(_prime_sm2-sm2_data)] + CALL_IPPASM _add_256 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC sm2_sub + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_neg(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_neg,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LENSM2] +%assign _sp_ _buf_+(LENSM2)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + mov edi, pR ; outpur pR + mov esi, pA ; input pA + + ; r = 0-a + mov eax, 0 + sub eax, dword [esi] + mov dword [edi], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)] + mov dword [edi+sizeof(dword)], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*2] + mov dword [edi+sizeof(dword)*2], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*3] + mov dword [edi+sizeof(dword)*3], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*4] + mov dword [edi+sizeof(dword)*4], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*5] + mov dword [edi+sizeof(dword)*5], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*6] + mov dword [edi+sizeof(dword)*6], eax + mov eax, 0 + sbb eax, dword [esi+sizeof(dword)*7] + mov dword [edi+sizeof(dword)*7], eax + sbb edx,edx + + lea edi, [esp+_buf_] ; T + mov esi, pR ; R + LD_ADDR ebx, sm2_data ; modulus + lea ebx, [ebx+(_prime_sm2-sm2_data)] + CALL_IPPASM _add_256 ; T = R+modulus + + lea esi,[esp+_buf_] + mov edi, pR + test edx, edx ; R = T<0? R : T + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC sm2_neg + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_mul_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_mul_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LENSM2] +%assign _sp_ _buf_+(LENSM2)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; pA + CALL_IPPASM _shl_256 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + mov edi, pR ; R + LD_ADDR ebx, sm2_data ; modulus + lea ebx, [ebx+(_prime_sm2-sm2_data)] + CALL_IPPASM _sub_256 ; R = T-modulus + + sub edx, eax ; R = R<0? T : R + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC sm2_mul_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_mul_by_3(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_mul_by_3,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _bufT_ 0 ; T buffer[LENSM2] +%assign _bufU_ _bufT_+(LENSM2)*sizeof(dword) ; U buffer[LENSM2] +%assign _mod_ _bufU_+(LENSM2)*sizeof(dword) ; modulus address [1] +%assign _sp_ _mod_+sizeof(dword) ; esp [1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + LD_ADDR eax, sm2_data ; srore modulus address + lea eax, [eax+(_prime_sm2-sm2_data)] + mov dword [esp+_mod_], eax + + lea edi, [esp+_bufT_] ; T + mov esi, pA ; A + CALL_IPPASM _shl_256 ; T = A<<1 + mov edx, eax + + mov esi, edi ; T + lea edi, [esp+_bufU_] ; U + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM _sub_256 ; U = T-modulus + + sub edx, eax ; T = U<0? T : U + cmovz esi, edi + cpy_256 edi, esi + + mov esi, edi + mov ebx, pA + CALL_IPPASM _add_256 ; T +=A + mov edx, eax + + mov edi, pR ; R + mov ebx, [esp+_mod_] ; modulus + CALL_IPPASM _sub_256 ; R = T-modulus + + sub edx, eax ; R = T<0? R : T + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC sm2_mul_by_3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_div_by_2(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_div_by_2,PUBLIC + USES_GPR esi,edi,ebx,ebp + + mov ebp, esp ; save original esp to use it to reach parameters + +%xdefine pR [ebp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [ebp + ARG_1 + 1*sizeof(dword)] ; source A address +; +; stack layout: +; +%assign _buf_ 0 ; buffer[LENSM2] +%assign _sp_ _buf_+(LENSM2)*sizeof(dword) ; esp[1] +%assign _frame_ _sp_+sizeof(dword) ; +16 bytes for alignment + + mov eax, esp ; save esp + sub esp, _frame_ ; allocate frame + and esp, -16 ; provide 16-byte alignment + mov dword [esp+_sp_], eax ; store esp + + lea edi, [esp+_buf_] ; T + mov esi, pA ; A + LD_ADDR ebx, sm2_data ; modulus + lea ebx, [ebx+(_prime_sm2-sm2_data)] + CALL_IPPASM _add_256 ; R = A+modulus + mov edx, 0 + + mov ecx, dword [esi] ; shifted_data = (a[0]&1)? T : A + and ecx, 1 + cmovnz esi, edi + cmovz eax, edx + mov edi, pR + CALL_IPPASM _shr_256 + + mov esp, [esp+_sp_] + REST_GPR + ret +ENDFUNC sm2_div_by_2 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_mul_mont_slm(Ipp32u* r, const Ipp32u* a, const Ipp32u* b) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_mul_mont_slm,PUBLIC + USES_GPR ebp,ebx,esi,edi + +%xdefine pR [eax + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [eax + ARG_1 + 1*sizeof(dword)] ; source A address +%xdefine pB [eax + ARG_1 + 2*sizeof(dword)] ; source B address +; +; stack layout: +; +%assign _buf_ 0 +%assign _rp_ _buf_+(LENSM2+1)*sizeof(dword) ; pR +%assign _ap_ _rp_ +sizeof(dword) ; pA +%assign _bp_ _ap_+sizeof(dword) ; pB +%assign _sp_ _bp_+sizeof(dword) ; esp storage +%assign _ssize_ _sp_+sizeof(dword) ; size allocated stack + + mov eax, esp ; save esp + sub esp, _ssize_ ; allocate stack + and esp, -16 ; provide 16-byte stack alignment + mov dword [esp+_sp_], eax ; store original esp + + ; clear buffer + pxor mm0, mm0 + movq qword [esp+_buf_], mm0 + movq qword [esp+_buf_+sizeof(qword)], mm0 + movq qword [esp+_buf_+sizeof(qword)*2], mm0 + movq qword [esp+_buf_+sizeof(qword)*3], mm0 + movd dword [esp+_buf_+sizeof(qword)*4], mm0 + + ; store parameters into the stack + ; note: eax here stores an original esp, so it can be used to reach function parameters + mov edi, pR + mov esi, pA + mov ebp, pB + mov dword [esp+_rp_], edi + mov dword [esp+_ap_], esi + mov dword [esp+_bp_], ebp + + mov edi, LENSM2 + + movd mm1, dword [esi+sizeof(dword)] ; pre load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + +align IPP_ALIGN_FACTOR +.mmul_loop: +; +; i-st pass +; modulus = 2^256 -2^224 +2^192 +2^96 -1 +; [8] [7] [6] [3] [0] +; m0 = 1 +; + movd mm7, edi ; save pass counter + + mov edx, dword [ebp] ; b = b[i] + mov eax, dword [esi] ; a[0] + movd mm0, edx + add ebp, sizeof(dword) + mov dword [esp+_bp_], ebp + + pmuludq mm1, mm0 ; a[1]*b[i] + pmuludq mm2, mm0 ; a[2]*b[i] + + mul edx ; (E:u) = (edx:eax) = a[0]*b[i]+buf[0] + add eax, dword [esp+_buf_] + adc edx, 0 + + pmuludq mm3, mm0 ; a[3]*b[i] + pmuludq mm4, mm0 ; a[4]*b[i] + +; multiplication round 1 - round 4 + movd ecx, mm1 ; p = a[1]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*1] + movd mm1, dword [esi+sizeof(dword)*5] + adc edx, 0 + + movd ebx, mm2 ; p = a[2]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*2] + movd mm2, dword [esi+sizeof(dword)*6] + adc edx, 0 + + pmuludq mm1, mm0 ; a[5]*b[i] + pmuludq mm2, mm0 ; a[6]*b[i] + + movd ebp, mm3 ; p = a[3]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*3] + movd mm3, dword [esi+sizeof(dword)*7] + adc edx, 0 + + movd edi, mm4 ; p = a[4]*b[i] + E + psrlq mm4, 32 + add edi, edx + movd edx, mm4 + adc edx, 0 + add edi, dword [esp+_buf_+sizeof(dword)*4] + adc edx, 0 + + pmuludq mm3, mm0 ; a[7]*b[i] + +;;; and reduction ;;; + ; eax =u0 + + mov dword [esp+_buf_+sizeof(dword)*0], ecx ; copy + + add ebx, eax ; +u0 + mov dword [esp+_buf_+sizeof(dword)*1], ebx + + mov ecx, eax + sbb eax, 0 + sub ebp, eax ; -u0 +cf + mov dword [esp+_buf_+sizeof(dword)*2], ebp + + sbb edi, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*3], edi + mov edi, 0 ; save edi = bf + adc edi, 0 + mov eax, ecx + +; multiplication round 5 - round 7 + movd ecx, mm1 ; p = a[5]*b[i] + E + psrlq mm1, 32 + add ecx, edx + movd edx, mm1 + adc edx, 0 + add ecx, dword [esp+_buf_+sizeof(dword)*5] + adc edx, 0 + + movd ebx, mm2 ; p = a[6]*b[i] + E + psrlq mm2, 32 + add ebx, edx + movd edx, mm2 + adc edx, 0 + add ebx, dword [esp+_buf_+sizeof(dword)*6] + adc edx, 0 + + movd ebp, mm3 ; p = a[7]*b[i] + E + psrlq mm3, 32 + add ebp, edx + movd edx, mm3 + adc edx, 0 + add ebp, dword [esp+_buf_+sizeof(dword)*7] + adc edx, 0 + +;;; and reduction ;;; + sub ecx, edi ; -bf + mov dword [esp+_buf_+sizeof(dword)*4], ecx + sbb ebx, 0 ; -bf + mov dword [esp+_buf_+sizeof(dword)*5], ebx + sbb ebp, eax ; -u0+bf + mov dword [esp+_buf_+sizeof(dword)*6], ebp + +; last multiplication round 8 + movd edi, mm7 ; restore pass counter + + sbb eax, 0 ; u0-bf + mov ebx, 0 + + add edx, dword [esp+_buf_+sizeof(dword)*8] + adc ebx, 0 + add edx, eax + mov dword [esp+_buf_+sizeof(dword)*7], edx + adc ebx, 0 + mov dword [esp+_buf_+sizeof(dword)*8], ebx + + sub edi, 1 + movd mm1, dword [esi+sizeof(dword)] ; speculative load a[1], a[2], a[3], a[4] + movd mm2, dword [esi+sizeof(dword)*2] + movd mm3, dword [esi+sizeof(dword)*3] + movd mm4, dword [esi+sizeof(dword)*4] + jz .exit_mmul_loop + + mov ebp, dword [esp+_bp_] ; restore pB + jmp .mmul_loop + +.exit_mmul_loop: + emms + +; final reduction + mov edi, [esp+_rp_] ; result + lea esi, [esp+_buf_] ; buffer + LD_ADDR ebx, sm2_data ; modulus + lea ebx, [ebx+(_prime_sm2-sm2_data)] + CALL_IPPASM _sub_256 + mov edx, dword [esp+_buf_+LENSM2*sizeof(dword)] + sub edx, eax + +; copy + cmovz esi, edi + cpy_256 edi, esi + + mov esp, [esp+_sp_] ; release stack + REST_GPR + ret +ENDFUNC sm2_mul_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_sqr_mont_slm(Ipp32u* r, const Ipp32u* a) +;; +align IPP_ALIGN_FACTOR +IPPASM sm2_sqr_mont_slm,PUBLIC + USES_GPR esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; product address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source A address + + ;; use sm2_mul_mont_slm to compute sqr + mov esi, pA + mov edi, pR + push esi + push esi + push edi + CALL_IPPASM sm2_mul_mont_slm,PUBLIC + add esp, sizeof(dword)*3 + REST_GPR + ret +ENDFUNC sm2_sqr_mont_slm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; void sm2_mred(Ipp32u* r, Ipp32u* prod) +;; +; modulus = 2^256 -2^224 +2^192 +2^96 -1 +; [8] [7] [6] [3] [0] +; m0 = 1 +; +align IPP_ALIGN_FACTOR +IPPASM sm2_mred,PUBLIC + USES_GPR ebx,esi,edi + +%xdefine pR [esp + ARG_1 + 0*sizeof(dword)] ; reduction address +%xdefine pA [esp + ARG_1 + 1*sizeof(dword)] ; source product address + + ; get parameters: + mov esi, pA + + mov ecx, LENSM2 + xor edx, edx +align IPP_ALIGN_FACTOR +.mred_loop: + mov eax, dword [esi] + + mov ebx, 0 + mov dword [esi], ebx + + mov ebx, dword [esi+sizeof(dword)*2] + add ebx, eax + mov dword [esi+sizeof(dword)*2], ebx + + mov ebx, dword [esi+sizeof(dword)*3] + push eax + sbb eax, 0 + sub ebx, eax + mov dword [esi+sizeof(dword)*3], ebx + pop eax + + mov ebx, dword [esi+sizeof(dword)*4] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*4], ebx + + mov ebx, dword [esi+sizeof(dword)*5] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*5], ebx + + mov ebx, dword [esi+sizeof(dword)*6] + sbb ebx, 0 + mov dword [esi+sizeof(dword)*6], ebx + + mov ebx, dword [esi+sizeof(dword)*7] + sbb ebx, eax + mov dword [esi+sizeof(dword)*7], ebx + + mov ebx, dword [esi+sizeof(dword)*8] + sbb eax, 0 + add eax, edx + mov edx, 0 + adc edx, 0 + add ebx, eax + mov dword [esi+sizeof(dword)*8], ebx + adc edx, 0 + + lea esi, [esi+sizeof(dword)] + sub ecx, 1 + jnz .mred_loop + + ; final reduction + mov edi, pR ; result + LD_ADDR ebx, sm2_data ; addres of the modulus + lea ebx, [ebx+(_prime_sm2-sm2_data)] + CALL_IPPASM _sub_256 + + sub edx, eax + cmovz esi, edi + cpy_256 edi, esi + + REST_GPR + ret +ENDFUNC sm2_mred + +%endif ;; _IPP >= _IPP_P8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant.inc b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant.inc new file mode 100644 index 000000000..61f4b8fa5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant.inc @@ -0,0 +1,133 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Intel(R) Integrated Performance Primitives +; Cryptographic Primitives (ippcp) +; +; Purpose: +; Define ippCP variant +; +; do not change definitions below! +; + +;; +;; modes of the feature +;; +%assign _FEATURE_OFF_ 0 ;; feature is OFF +%assign _FEATURE_ON_ 1 ;; feature is ON +%assign _FEATURE_TICKTOCK_ 2 ;; dectect is feature OFF/ON + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;_XMM7560_ = 1 +%ifdef _XMM7560_ + %include "pcpvariant_xmm7560.inc" +%endif + +;;_TXT_ACM_ = 1 +%ifdef _TXT_ACM_ + %include "pcpvariant_txt_acm.inc" +%endif +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; it possible to force use of C-version of some implementtaions +;; instead of ASM one +;; +%ifndef _USE_C_cpAdd_BNU_ + %assign _USE_C_cpAdd_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpSub_BNU_ + %assign _USE_C_cpSub_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpInc_BNU_ + %assign _USE_C_cpInc_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpAddMulDgt_BNU_ + %assign _USE_C_cpAddMulDgt_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpMulAdc_BNU_school_ + %assign _USE_C_cpMulAdc_BNU_school_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpSqrAdc_BNU_school_ + %assign _USE_C_cpSqrAdc_BNU_school_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpMontRedAdc_BNU_ + %assign _USE_C_cpMontRedAdc_BNU_ _FEATURE_OFF_ +%endif + +;; +;; if there is no outside assignment +;; set _SHA_NI_ENABLING_ based on CPU specification +;; +%ifndef _SHA_NI_ENABLING_ + %if (_IPP >= _IPP_P8 ) + %assign _SHA_NI_ENABLING_ _FEATURE_TICKTOCK_ + %else + %assign _SHA_NI_ENABLING_ _FEATURE_OFF_ + %endif +%endif + +;; +;; select Hash algorithm +;; +%ifndef _DISABLE_ALG_SHA1_ + %assign _ENABLE_ALG_SHA1_ _FEATURE_ON_ ;; SHA1 on +%else + %assign _ENABLE_ALG_SHA1_ _FEATURE_OFF_ ;; SHA1 on +%endif + +%ifndef _DISABLE_ALG_SHA256_ + %assign _ENABLE_ALG_SHA256_ _FEATURE_ON_ ;; SHA256 on +%else + %assign _ENABLE_ALG_SHA256_ _FEATURE_OFF_ ;; SHA256 off +%endif + +%ifndef _DISABLE_ALG_SHA521_ + %assign _ENABLE_ALG_SHA512_ _FEATURE_ON_ ;; SHA512 on +%else + %assign _ENABLE_ALG_SHA512_ _FEATURE_OFF_ ;; SHA512 off +%endif + +%ifndef _DISABLE_ALG_MD5_ + %assign _ENABLE_ALG_MD5_ _FEATURE_ON_ ;; MD5 on +%else + %assign _ENABLE_ALG_MD5_ _FEATURE_OFF_ ;; MD5 off +%endif + +%ifndef _DISABLE_ALG_SM3_ + %assign _ENABLE_ALG_SM3_ _FEATURE_ON_ ;; SM3 on +%else + %assign _ENABLE_ALG_SM3_ _FEATURE_OFF_ ;; SM3 off +%endif + + +%assign _ENABLE_KARATSUBA_ 0 ;; not use Karatsuba method for multiplication + +%assign _NUSE 0 ;; do not use use +%assign _USE 1 ;; do use + +;; ~ 5.0 +%assign _USE_NN_MUL_BNU_FS_ _NUSE ;; use/not use NN version of full-size multiplication +%assign _USE_NN_MONTMUL_ _NUSE ;; use/not use NN version of Montgomery multiplication + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant_txt_acm.inc b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant_txt_acm.inc new file mode 100644 index 000000000..ae0fff46e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant_txt_acm.inc @@ -0,0 +1,39 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; Intel(R) Integrated Performance Primitives +; Cryptographic Primitives (ippcp) +; +; Purpose: +; Update standard ippCP variant +; +; do not change definitions below! +; + +%ifdef _TXT_ACM_ + +;; +;; HASH algs outside settings +;; +%assign _SHA_NI_ENABLING_ _FEATURE_TICKTOCK_ + +;; +;; select Hash algorithm +;; +%assign _ENABLE_ALG_MD5_ _FEATURE_OFF_ + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant_xmm7560.inc b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant_xmm7560.inc new file mode 100644 index 000000000..0c3a010f3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_ia32/pcpvariant_xmm7560.inc @@ -0,0 +1,45 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; Intel(R) Integrated Performance Primitives +; Cryptographic Primitives (ippcp) +; +; Purpose: +; Update standard ippCP variant +; for code size optimization +; + +%ifdef _XMM7560_ +%if (_IPP >= _IPP_P8) + +%assign OFF 0 +%assign ON 1 + +;%assign _USE_C_cpAdd_BNU_ ON +;%assign _USE_C_cpSub_BNU_ ON +;%assign _USE_C_cpInc_BNU_ ON +;%assign _USE_C_cpAddMulDgt_BNU_ ON +;%assign _USE_C_cpSubMulDgt_BNU_ ON +%assign _USE_C_cpMulAdc_BNU_school_ ON +%assign _USE_C_cpSqrAdc_BNU_school_ ON +%assign _USE_C_cpMontRedAdc_BNU_ ON + +%assign _DISABLE_ECP_256R1_HARDCODED_BP_TBL_ OFF +%assign _DISABLE_ECP_384R1_HARDCODED_BP_TBL_ OFF + +%endif +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_common.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_common.inc new file mode 100644 index 000000000..f2f793acf --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_common.inc @@ -0,0 +1,365 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef _AES_COMMON_ASM_ +%define _AES_COMMON_ASM_ + +%include "reg_sizes.inc" + +;; ============================================================================= +;; Generic macro to produce code that executes %%OPCODE instruction +;; on selected number of AES blocks (16 bytes long ) between 0 and 16. +;; All three operands of the instruction come from registers. +;; Note: if 3 blocks are left at the end instruction is produced to operate all +;; 4 blocks (full width of ZMM) + +%macro ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 14 +%define %%NUM_BLOCKS %1 ; [in] numerical value, number of AES blocks (0 to 16) +%define %%OPCODE %2 ; [in] instruction name +%define %%DST0 %3 ; [out] destination ZMM register +%define %%DST1 %4 ; [out] destination ZMM register +%define %%DST2 %5 ; [out] destination ZMM register +%define %%DST3 %6 ; [out] destination ZMM register +%define %%SRC1_0 %7 ; [in] source 1 ZMM register +%define %%SRC1_1 %8 ; [in] source 1 ZMM register +%define %%SRC1_2 %9 ; [in] source 1 ZMM register +%define %%SRC1_3 %10 ; [in] source 1 ZMM register +%define %%SRC2_0 %11 ; [in] source 2 ZMM register +%define %%SRC2_1 %12 ; [in] source 2 ZMM register +%define %%SRC2_2 %13 ; [in] source 2 ZMM register +%define %%SRC2_3 %14 ; [in] source 2 ZMM register + +%assign reg_idx 0 +%assign blocks_left %%NUM_BLOCKS + +%rep (%%NUM_BLOCKS / 4) +%xdefine %%DSTREG %%DST %+ reg_idx +%xdefine %%SRC1REG %%SRC1_ %+ reg_idx +%xdefine %%SRC2REG %%SRC2_ %+ reg_idx + %%OPCODE %%DSTREG, %%SRC1REG, %%SRC2REG +%undef %%DSTREG +%undef %%SRC1REG +%undef %%SRC2REG +%assign reg_idx (reg_idx + 1) +%assign blocks_left (blocks_left - 4) +%endrep + +%xdefine %%DSTREG %%DST %+ reg_idx +%xdefine %%SRC1REG %%SRC1_ %+ reg_idx +%xdefine %%SRC2REG %%SRC2_ %+ reg_idx + +%if blocks_left == 1 + %%OPCODE XWORD(%%DSTREG), XWORD(%%SRC1REG), XWORD(%%SRC2REG) +%elif blocks_left == 2 + %%OPCODE YWORD(%%DSTREG), YWORD(%%SRC1REG), YWORD(%%SRC2REG) +%elif blocks_left == 3 + %%OPCODE %%DSTREG, %%SRC1REG, %%SRC2REG +%endif + +%endmacro + +;; ============================================================================= +;; Loads specified number of AES blocks into ZMM registers +;; %%FLAGS are optional and only affect behavior when 3 trailing blocks are left +;; - if %%FlAGS not provided then exactly 3 blocks are loaded (move and insert) +;; - if "load_4_instead_of_3" option is passed then 4 blocks are loaded +%macro ZMM_LOAD_BLOCKS_0_16 7-8 +%define %%NUM_BLOCKS %1 ; [in] numerical value, number of AES blocks (0 to 16) +%define %%INP %2 ; [in] input data pointer to read from +%define %%DATA_OFFSET %3 ; [in] offset to the output pointer (GP or numerical) +%define %%DST0 %4 ; [out] ZMM register with loaded data +%define %%DST1 %5 ; [out] ZMM register with loaded data +%define %%DST2 %6 ; [out] ZMM register with loaded data +%define %%DST3 %7 ; [out] ZMM register with loaded data +%define %%FLAGS %8 ; [in] optional "load_4_instead_of_3" + +%assign src_offset 0 +%assign dst_idx 0 + +%rep (%%NUM_BLOCKS / 4) +%xdefine %%DSTREG %%DST %+ dst_idx + vmovdqu8 %%DSTREG, [%%INP + %%DATA_OFFSET + src_offset] +%undef %%DSTREG +%assign src_offset (src_offset + 64) +%assign dst_idx (dst_idx + 1) +%endrep + +%assign blocks_left (%%NUM_BLOCKS % 4) +%xdefine %%DSTREG %%DST %+ dst_idx + +%if blocks_left == 1 + vmovdqu8 XWORD(%%DSTREG), [%%INP + %%DATA_OFFSET + src_offset] +%elif blocks_left == 2 + vmovdqu8 YWORD(%%DSTREG), [%%INP + %%DATA_OFFSET + src_offset] +%elif blocks_left == 3 +%ifidn %%FLAGS, load_4_instead_of_3 + vmovdqu8 %%DSTREG, [%%INP + %%DATA_OFFSET + src_offset] +%else + vmovdqu8 YWORD(%%DSTREG), [%%INP + %%DATA_OFFSET + src_offset] + vinserti64x2 %%DSTREG, [%%INP + %%DATA_OFFSET + src_offset + 32], 2 +%endif +%endif + +%endmacro + +;; ============================================================================= +;; Loads specified number of AES blocks into ZMM registers using mask register +;; for the last loaded register (xmm, ymm or zmm). +;; Loads take place at 1 byte granularity. +%macro ZMM_LOAD_MASKED_BLOCKS_0_16 8 +%define %%NUM_BLOCKS %1 ; [in] numerical value, number of AES blocks (0 to 16) +%define %%INP %2 ; [in] input data pointer to read from +%define %%DATA_OFFSET %3 ; [in] offset to the output pointer (GP or numerical) +%define %%DST0 %4 ; [out] ZMM register with loaded data +%define %%DST1 %5 ; [out] ZMM register with loaded data +%define %%DST2 %6 ; [out] ZMM register with loaded data +%define %%DST3 %7 ; [out] ZMM register with loaded data +%define %%MASK %8 ; [in] mask register + +%assign src_offset 0 +%assign dst_idx 0 +%assign blocks_left %%NUM_BLOCKS + +%if %%NUM_BLOCKS > 0 +%rep (((%%NUM_BLOCKS + 3) / 4) - 1) +%xdefine %%DSTREG %%DST %+ dst_idx + vmovdqu8 %%DSTREG, [%%INP + %%DATA_OFFSET + src_offset] +%undef %%DSTREG +%assign src_offset (src_offset + 64) +%assign dst_idx (dst_idx + 1) +%assign blocks_left (blocks_left - 4) +%endrep +%endif ; %if %%NUM_BLOCKS > 0 + +%xdefine %%DSTREG %%DST %+ dst_idx + +%if blocks_left == 1 + vmovdqu8 XWORD(%%DSTREG){%%MASK}{z}, [%%INP + %%DATA_OFFSET + src_offset] +%elif blocks_left == 2 + vmovdqu8 YWORD(%%DSTREG){%%MASK}{z}, [%%INP + %%DATA_OFFSET + src_offset] +%elif (blocks_left == 3 || blocks_left == 4) + vmovdqu8 %%DSTREG{%%MASK}{z}, [%%INP + %%DATA_OFFSET + src_offset] +%endif + +%endmacro + +;; ============================================================================= +;; Stores specified number of AES blocks from ZMM registers +%macro ZMM_STORE_BLOCKS_0_16 7 +%define %%NUM_BLOCKS %1 ; [in] numerical value, number of AES blocks (0 to 16) +%define %%OUTP %2 ; [in] output data pointer to write to +%define %%DATA_OFFSET %3 ; [in] offset to the output pointer (GP or numerical) +%define %%SRC0 %4 ; [in] ZMM register with data to store +%define %%SRC1 %5 ; [in] ZMM register with data to store +%define %%SRC2 %6 ; [in] ZMM register with data to store +%define %%SRC3 %7 ; [in] ZMM register with data to store + +%assign dst_offset 0 +%assign src_idx 0 + +%rep (%%NUM_BLOCKS / 4) +%xdefine %%SRCREG %%SRC %+ src_idx + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset], %%SRCREG +%undef %%SRCREG +%assign dst_offset (dst_offset + 64) +%assign src_idx (src_idx + 1) +%endrep + +%assign blocks_left (%%NUM_BLOCKS % 4) +%xdefine %%SRCREG %%SRC %+ src_idx + +%if blocks_left == 1 + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset], XWORD(%%SRCREG) +%elif blocks_left == 2 + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset], YWORD(%%SRCREG) +%elif blocks_left == 3 + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset], YWORD(%%SRCREG) + vextracti32x4 [%%OUTP + %%DATA_OFFSET + dst_offset + 32], %%SRCREG, 2 +%endif + +%endmacro + +;; ============================================================================= +;; Stores specified number of AES blocks from ZMM registers with mask register +;; for the last loaded register (xmm, ymm or zmm). +;; Stores take place at 1 byte granularity. +%macro ZMM_STORE_MASKED_BLOCKS_0_16 8 +%define %%NUM_BLOCKS %1 ; [in] numerical value, number of AES blocks (0 to 16) +%define %%OUTP %2 ; [in] output data pointer to write to +%define %%DATA_OFFSET %3 ; [in] offset to the output pointer (GP or numerical) +%define %%SRC0 %4 ; [in] ZMM register with data to store +%define %%SRC1 %5 ; [in] ZMM register with data to store +%define %%SRC2 %6 ; [in] ZMM register with data to store +%define %%SRC3 %7 ; [in] ZMM register with data to store +%define %%MASK %8 ; [in] mask register + +%assign dst_offset 0 +%assign src_idx 0 +%assign blocks_left %%NUM_BLOCKS + +%if %%NUM_BLOCKS > 0 +%rep (((%%NUM_BLOCKS + 3) / 4) - 1) +%xdefine %%SRCREG %%SRC %+ src_idx + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset], %%SRCREG +%undef %%SRCREG +%assign dst_offset (dst_offset + 64) +%assign src_idx (src_idx + 1) +%assign blocks_left (blocks_left - 4) +%endrep +%endif ; %if %%NUM_BLOCKS > 0 + +%xdefine %%SRCREG %%SRC %+ src_idx + +%if blocks_left == 1 + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset]{%%MASK}, XWORD(%%SRCREG) +%elif blocks_left == 2 + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset]{%%MASK}, YWORD(%%SRCREG) +%elif (blocks_left == 3 || blocks_left == 4) + vmovdqu8 [%%OUTP + %%DATA_OFFSET + dst_offset]{%%MASK}, %%SRCREG +%endif + +%endmacro + +;;; =========================================================================== +;;; Handles AES encryption rounds +;;; It handles special cases: the last and first rounds +;;; Optionally, it performs XOR with data after the last AES round. +;;; Uses NROUNDS parameterto check what needs to be done for the current round. +;;; If 3 blocks are trailing then operation on whole ZMM is performed (4 blocks). +%macro ZMM_AESENC_ROUND_BLOCKS_0_16 12 +%define %%L0B0_3 %1 ; [in/out] zmm; blocks 0 to 3 +%define %%L0B4_7 %2 ; [in/out] zmm; blocks 4 to 7 +%define %%L0B8_11 %3 ; [in/out] zmm; blocks 8 to 11 +%define %%L0B12_15 %4 ; [in/out] zmm; blocks 12 to 15 +%define %%KEY %5 ; [in] zmm containing round key +%define %%ROUND %6 ; [in] round number +%define %%D0_3 %7 ; [in] zmm or no_data; plain/cipher text blocks 0-3 +%define %%D4_7 %8 ; [in] zmm or no_data; plain/cipher text blocks 4-7 +%define %%D8_11 %9 ; [in] zmm or no_data; plain/cipher text blocks 8-11 +%define %%D12_15 %10 ; [in] zmm or no_data; plain/cipher text blocks 12-15 +%define %%NUMBL %11 ; [in] number of blocks; numerical value +%define %%NROUNDS %12 ; [in] number of rounds; numerical value + +;;; === first AES round +%if (%%ROUND < 1) + ;; round 0 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vpxorq, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%KEY, %%KEY, %%KEY, %%KEY +%endif ; ROUND 0 + +;;; === middle AES rounds +%if (%%ROUND >= 1 && %%ROUND <= %%NROUNDS) + ;; rounds 1 to 9/11/13 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vaesenc, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%KEY, %%KEY, %%KEY, %%KEY +%endif ; rounds 1 to 9/11/13 + +;;; === last AES round +%if (%%ROUND > %%NROUNDS) + ;; the last round - mix enclast with text xor's + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vaesenclast, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%KEY, %%KEY, %%KEY, %%KEY + +;;; === XOR with data +%ifnidn %%D0_3, no_data +%ifnidn %%D4_7, no_data +%ifnidn %%D8_11, no_data +%ifnidn %%D12_15, no_data + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vpxorq, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%D0_3, %%D4_7, %%D8_11, %%D12_15 +%endif ; !no_data +%endif ; !no_data +%endif ; !no_data +%endif ; !no_data + +%endif ; The last round + +%endmacro + +;;; =========================================================================== +;;; Handles AES decryption rounds +;;; It handles special cases: the last and first rounds +;;; Optionally, it performs XOR with data after the last AES round. +;;; Uses NROUNDS parameter to check what needs to be done for the current round. +;;; If 3 blocks are trailing then operation on whole ZMM is performed (4 blocks). +%macro ZMM_AESDEC_ROUND_BLOCKS_0_16 12 +%define %%L0B0_3 %1 ; [in/out] zmm; blocks 0 to 3 +%define %%L0B4_7 %2 ; [in/out] zmm; blocks 4 to 7 +%define %%L0B8_11 %3 ; [in/out] zmm; blocks 8 to 11 +%define %%L0B12_15 %4 ; [in/out] zmm; blocks 12 to 15 +%define %%KEY %5 ; [in] zmm containing round key +%define %%ROUND %6 ; [in] round number +%define %%D0_3 %7 ; [in] zmm or no_data; cipher text blocks 0-3 +%define %%D4_7 %8 ; [in] zmm or no_data; cipher text blocks 4-7 +%define %%D8_11 %9 ; [in] zmm or no_data; cipher text blocks 8-11 +%define %%D12_15 %10 ; [in] zmm or no_data; cipher text blocks 12-15 +%define %%NUMBL %11 ; [in] number of blocks; numerical value +%define %%NROUNDS %12 ; [in] number of rounds; numerical value + +;;; === first AES round +%if (%%ROUND < 1) + ;; round 0 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vpxorq, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%KEY, %%KEY, %%KEY, %%KEY +%endif ; ROUND 0 + +;;; === middle AES rounds +%if (%%ROUND >= 1 && %%ROUND <= %%NROUNDS) + ;; rounds 1 to 9/11/13 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vaesdec, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%KEY, %%KEY, %%KEY, %%KEY +%endif ; rounds 1 to 9/11/13 + +;;; === last AES round +%if (%%ROUND > %%NROUNDS) + ;; the last round - mix enclast with text xor's + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vaesdeclast, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%KEY, %%KEY, %%KEY, %%KEY + +;;; === XOR with data +%ifnidn %%D0_3, no_data +%ifnidn %%D4_7, no_data +%ifnidn %%D8_11, no_data +%ifnidn %%D12_15, no_data + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUMBL, vpxorq, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%L0B0_3, %%L0B4_7, %%L0B8_11, %%L0B12_15, \ + %%D0_3, %%D4_7, %%D8_11, %%D12_15 +%endif ; !no_data +%endif ; !no_data +%endif ; !no_data +%endif ; !no_data + +%endif ; The last round + +%endmacro + +%endif ;; _AES_COMMON_ASM diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_128.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_128.asm new file mode 100644 index 000000000..f0a5d1962 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_128.asm @@ -0,0 +1,103 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; Routine to do AES key expansion +%include "os.inc" +%define NO_AESNI_RENAME +%include "clear_regs.inc" + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%macro key_expansion_128_avx 0 + ;; Assumes the xmm3 includes all zeros at this point. + vpshufd xmm2, xmm2, 11111111b + vshufps xmm3, xmm3, xmm1, 00010000b + vpxor xmm1, xmm1, xmm3 + vshufps xmm3, xmm3, xmm1, 10001100b + vpxor xmm1, xmm1, xmm3 + vpxor xmm1, xmm1, xmm2 +%endmacro + +%ifdef LINUX +%define KEY rdi +%define EXP_ENC_KEYS rsi +%define EXP_DEC_KEYS rdx +%else +%define KEY rcx +%define EXP_ENC_KEYS rdx +%define EXP_DEC_KEYS r8 +%endif + +section .text + +IPPASM aes_keyexp_128_enc, PUBLIC + + vmovdqu xmm1, [KEY] ; loading the AES key + vmovdqa [EXP_ENC_KEYS + 16*0], xmm1 + vpxor xmm3, xmm3, xmm3 + + vaeskeygenassist xmm2, xmm1, 0x1 ; Generating round key 1 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*1], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x2 ; Generating round key 2 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*2], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x4 ; Generating round key 3 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*3], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x8 ; Generating round key 4 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*4], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x10 ; Generating round key 5 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*5], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x20 ; Generating round key 6 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*6], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x40 ; Generating round key 7 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*7], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x80 ; Generating round key 8 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*8], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x1b ; Generating round key 9 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*9], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x36 ; Generating round key 10 + key_expansion_128_avx + vmovdqa [EXP_ENC_KEYS + 16*10], xmm1 + + clear_scratch_gps_asm + clear_scratch_xmms_avx_asm + + ret + +ENDFUNC aes_keyexp_128_enc + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_192.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_192.asm new file mode 100644 index 000000000..b013f5425 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_192.asm @@ -0,0 +1,128 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; Routine to do AES key expansion +%include "os.inc" +%define NO_AESNI_RENAME +%include "clear_regs.inc" + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%ifdef LINUX +%define KEY rdi +%define EXP_ENC_KEYS rsi +%define EXP_DEC_KEYS rdx +%else +%define KEY rcx +%define EXP_ENC_KEYS rdx +%define EXP_DEC_KEYS r8 +%endif + +%macro key_expansion_1_192_avx 1 + ;; Assumes the xmm3 includes all zeros at this point. + vpshufd xmm2, xmm2, 11111111b + vshufps xmm3, xmm3, xmm1, 00010000b + vpxor xmm1, xmm1, xmm3 + vshufps xmm3, xmm3, xmm1, 10001100b + vpxor xmm1, xmm1, xmm3 + vpxor xmm1, xmm1, xmm2 + vmovdqu [EXP_ENC_KEYS + %1], xmm1 +%endmacro + +; Calculate w10 and w11 using calculated w9 and known w4-w5 +%macro key_expansion_2_192_avx 1 + vmovdqa xmm5, xmm4 + vpslldq xmm5, xmm5, 4 + vshufps xmm6, xmm6, xmm1, 11110000b + vpxor xmm6, xmm6, xmm5 + vpxor xmm4, xmm4, xmm6 + vpshufd xmm7, xmm4, 00001110b + vmovdqu [EXP_ENC_KEYS + %1], xmm7 +%endmacro + +%macro key_dec_192_avx 1 + vmovdqa xmm0, [EXP_ENC_KEYS + 16 * %1] + vaesimc xmm1, xmm0 + vmovdqa [EXP_DEC_KEYS + 16 * (12 - %1)], xmm1 +%endmacro + +section .text +IPPASM aes_keyexp_192_enc, PUBLIC + +%ifndef LINUX + sub rsp, 16*2 + 8 + vmovdqa [rsp + 0*16], xmm6 + vmovdqa [rsp + 1*16], xmm7 +%endif + + vmovq xmm7, [KEY + 16] ; loading the AES key, 64 bits + vmovq [EXP_ENC_KEYS + 16], xmm7 ; Storing key in memory where all key expansion + vpshufd xmm4, xmm7, 01001111b + vmovdqu xmm1, [KEY] ; loading the AES key, 128 bits + vmovdqu [EXP_ENC_KEYS], xmm1 ; Storing key in memory where all key expansion + + vpxor xmm3, xmm3, xmm3 + vpxor xmm6, xmm6, xmm6 + + vaeskeygenassist xmm2, xmm4, 0x1 ; Complete round key 1 and generate round key 2 + key_expansion_1_192_avx 24 + key_expansion_2_192_avx 40 + + vaeskeygenassist xmm2, xmm4, 0x2 ; Generate round key 3 and part of round key 4 + key_expansion_1_192_avx 48 + key_expansion_2_192_avx 64 + + vaeskeygenassist xmm2, xmm4, 0x4 ; Complete round key 4 and generate round key 5 + key_expansion_1_192_avx 72 + key_expansion_2_192_avx 88 + + vaeskeygenassist xmm2, xmm4, 0x8 ; Generate round key 6 and part of round key 7 + key_expansion_1_192_avx 96 + key_expansion_2_192_avx 112 + + vaeskeygenassist xmm2, xmm4, 0x10 ; Complete round key 7 and generate round key 8 + key_expansion_1_192_avx 120 + key_expansion_2_192_avx 136 + + vaeskeygenassist xmm2, xmm4, 0x20 ; Generate round key 9 and part of round key 10 + key_expansion_1_192_avx 144 + key_expansion_2_192_avx 160 + + vaeskeygenassist xmm2, xmm4, 0x40 ; Complete round key 10 and generate round key 11 + key_expansion_1_192_avx 168 + key_expansion_2_192_avx 184 + + vaeskeygenassist xmm2, xmm4, 0x80 ; Generate round key 12 + key_expansion_1_192_avx 192 + + clear_scratch_gps_asm + clear_scratch_xmms_avx_asm + +%ifndef LINUX + vmovdqa xmm6, [rsp + 0*16] + vmovdqa xmm7, [rsp + 1*16] + add rsp, 16*2 + 8 +%endif + + ret + +ENDFUNC aes_keyexp_192_enc + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_256.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_256.asm new file mode 100644 index 000000000..b66340a8b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/aes_keyexp_256.asm @@ -0,0 +1,131 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; Routine to do AES key expansion +%include "os.inc" +%define NO_AESNI_RENAME +%include "clear_regs.inc" + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +; Uses the f() function of the aeskeygenassist result +%macro key_expansion_256_avx 0 + ;; Assumes the xmm3 includes all zeros at this point. + vpshufd xmm2, xmm2, 11111111b + vshufps xmm3, xmm3, xmm1, 00010000b + vpxor xmm1, xmm1, xmm3 + vshufps xmm3, xmm3, xmm1, 10001100b + vpxor xmm1, xmm1, xmm3 + vpxor xmm1, xmm1, xmm2 +%endmacro + +; Uses the SubWord function of the aeskeygenassist result +%macro key_expansion_256_avx_2 0 + ;; Assumes the xmm3 includes all zeros at this point. + vpshufd xmm2, xmm2, 10101010b + vshufps xmm3, xmm3, xmm4, 00010000b + vpxor xmm4, xmm4, xmm3 + vshufps xmm3, xmm3, xmm4, 10001100b + vpxor xmm4, xmm4, xmm3 + vpxor xmm4, xmm4, xmm2 +%endmacro + +%ifdef LINUX +%define KEY rdi +%define EXP_ENC_KEYS rsi +%define EXP_DEC_KEYS rdx +%else +%define KEY rcx +%define EXP_ENC_KEYS rdx +%define EXP_DEC_KEYS r8 +%endif + +section .text + +IPPASM aes_keyexp_256_enc, PUBLIC + + vmovdqu xmm1, [KEY] ; loading the AES key + vmovdqa [EXP_ENC_KEYS + 16*0], xmm1 + + vmovdqu xmm4, [KEY+16] ; loading the AES key + vmovdqa [EXP_ENC_KEYS + 16*1], xmm4 + + vpxor xmm3, xmm3, xmm3 ; Required for the key_expansion. + + vaeskeygenassist xmm2, xmm4, 0x1 ; Generating round key 2 + key_expansion_256_avx + vmovdqa [EXP_ENC_KEYS + 16*2], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x1 ; Generating round key 3 + key_expansion_256_avx_2 + vmovdqa [EXP_ENC_KEYS + 16*3], xmm4 + + vaeskeygenassist xmm2, xmm4, 0x2 ; Generating round key 4 + key_expansion_256_avx + vmovdqa [EXP_ENC_KEYS + 16*4], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x2 ; Generating round key 5 + key_expansion_256_avx_2 + vmovdqa [EXP_ENC_KEYS + 16*5], xmm4 + + vaeskeygenassist xmm2, xmm4, 0x4 ; Generating round key 6 + key_expansion_256_avx + vmovdqa [EXP_ENC_KEYS + 16*6], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x4 ; Generating round key 7 + key_expansion_256_avx_2 + vmovdqa [EXP_ENC_KEYS + 16*7], xmm4 + + vaeskeygenassist xmm2, xmm4, 0x8 ; Generating round key 8 + key_expansion_256_avx + vmovdqa [EXP_ENC_KEYS + 16*8], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x8 ; Generating round key 9 + key_expansion_256_avx_2 + vmovdqa [EXP_ENC_KEYS + 16*9], xmm4 + + vaeskeygenassist xmm2, xmm4, 0x10 ; Generating round key 10 + key_expansion_256_avx + vmovdqa [EXP_ENC_KEYS + 16*10], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x10 ; Generating round key 11 + key_expansion_256_avx_2 + vmovdqa [EXP_ENC_KEYS + 16*11], xmm4 + + vaeskeygenassist xmm2, xmm4, 0x20 ; Generating round key 12 + key_expansion_256_avx + vmovdqa [EXP_ENC_KEYS + 16*12], xmm1 + + vaeskeygenassist xmm2, xmm1, 0x20 ; Generating round key 13 + key_expansion_256_avx_2 + vmovdqa [EXP_ENC_KEYS + 16*13], xmm4 + + vaeskeygenassist xmm2, xmm4, 0x40 ; Generating round key 14 + key_expansion_256_avx + vmovdqa [EXP_ENC_KEYS + 16*14], xmm1 + + clear_scratch_gps_asm + clear_scratch_xmms_avx_asm + + ret + +ENDFUNC aes_keyexp_256_enc + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/clear_regs.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/clear_regs.inc new file mode 100644 index 000000000..99dffc2ef --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/clear_regs.inc @@ -0,0 +1,186 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef _CLEAR_REGS_ASM_ +%define _CLEAR_REGS_ASM_ + +%include "os.inc" + +; +; This macro clears any GP registers passed +; +%macro clear_gps 1-16 +%define %%NUM_REGS %0 +%rep %%NUM_REGS + xor %1, %1 +%rotate 1 +%endrep +%endmacro + +; +; This macro clears any XMM registers passed on SSE +; +%macro clear_xmms_sse 1-16 +%define %%NUM_REGS %0 +%rep %%NUM_REGS + pxor %1, %1 +%rotate 1 +%endrep +%endmacro + +; +; This macro clears any XMM registers passed on AVX +; +%macro clear_xmms_avx 1-16 +%define %%NUM_REGS %0 +%rep %%NUM_REGS + vpxor %1, %1 +%rotate 1 +%endrep +%endmacro + +; +; This macro clears any YMM registers passed +; +%macro clear_ymms 1-16 +%define %%NUM_REGS %0 +%rep %%NUM_REGS + vpxor %1, %1 +%rotate 1 +%endrep +%endmacro + +; +; This macro clears any ZMM registers passed +; +%macro clear_zmms 1-32 +%define %%NUM_REGS %0 +%rep %%NUM_REGS + vpxorq %1, %1 +%rotate 1 +%endrep +%endmacro + +; +; This macro clears all scratch GP registers +; for Windows or Linux +; +%macro clear_scratch_gps_asm 0 + clear_gps rax, rcx, rdx, r8, r9, r10, r11 +%ifdef LINUX + clear_gps rdi, rsi +%endif +%endmacro + +; +; This macro clears all scratch XMM registers on SSE +; +%macro clear_scratch_xmms_sse_asm 0 +%ifdef LINUX +%assign i 0 +%rep 16 + pxor xmm %+ i, xmm %+ i +%assign i (i+1) +%endrep +; On Windows, XMM0-XMM5 registers are scratch registers +%else +%assign i 0 +%rep 6 + pxor xmm %+ i, xmm %+ i +%assign i (i+1) +%endrep +%endif ; LINUX +%endmacro + +; +; This macro clears all scratch XMM registers on AVX +; +%macro clear_scratch_xmms_avx_asm 0 +%ifdef LINUX + vzeroall +; On Windows, XMM0-XMM5 registers are scratch registers +%else +%assign i 0 +%rep 6 + vpxor xmm %+ i, xmm %+ i +%assign i (i+1) +%endrep +%endif ; LINUX +%endmacro + +; +; This macro clears all scratch YMM registers +; +; It should be called before restoring the XMM registers +; for Windows (XMM6-XMM15) +; +%macro clear_scratch_ymms_asm 0 +; On Linux, all YMM registers are scratch registers +%ifdef LINUX + vzeroall +; On Windows, YMM0-YMM5 registers are scratch registers. +; YMM6-YMM15 upper 128 bits are scratch registers too, but +; the lower 128 bits are to be restored after calling these function +; which clears the upper bits too. +%else +%assign i 0 +%rep 6 + vpxor ymm %+ i, ymm %+ i +%assign i (i+1) +%endrep +%endif ; LINUX +%endmacro + +; +; This macro clears all scratch ZMM registers +; +; It should be called before restoring the XMM registers +; for Windows (XMM6-XMM15). YMM registers are used +; on purpose, since XOR'ing YMM registers is faster +; than XOR'ing ZMM registers, and the operation clears +; also the upper 256 bits +; +%macro clear_scratch_zmms_asm 0 +; On Linux, all ZMM registers are scratch registers +%ifdef LINUX + vzeroall + ;; vzeroall only clears the first 16 ZMM registers +%assign i 16 +%rep 16 + vpxorq ymm %+ i, ymm %+ i +%assign i (i+1) +%endrep +; On Windows, ZMM0-ZMM5 and ZMM16-ZMM31 registers are scratch registers. +; ZMM6-ZMM15 upper 384 bits are scratch registers too, but +; the lower 128 bits are to be restored after calling these function +; which clears the upper bits too. +%else +%assign i 0 +%rep 6 + vpxorq ymm %+ i, ymm %+ i +%assign i (i+1) +%endrep + +%assign i 16 +%rep 16 + vpxorq ymm %+ i, ymm %+ i +%assign i (i+1) +%endrep +%endif ; LINUX +%endmacro + +%endif ;; _CLEAR_REGS_ASM diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/cpinitas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/cpinitas.asm new file mode 100644 index 000000000..33ea99628 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/cpinitas.asm @@ -0,0 +1,320 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%assign LOCAL_ALIGN_FACTOR 32 + +%ifdef _IPP_DATA + +segment .text align=LOCAL_ALIGN_FACTOR + +;#################################################################### +;# void cpGetReg( int* buf, int valueEAX, int valueECX ); # +;#################################################################### + +%ifdef WIN32E + %define buf rcx + %define valueEAX edx + %define valueECX r8d +%else + %define buf rdi + %define valueEAX esi + %define valueECX edx +%endif + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpGetReg,PUBLIC + push rbx + movsxd r9, valueEAX + movsxd r10, valueECX + mov r11, buf + + mov rax, r9 + mov rcx, r10 + xor ebx, ebx + xor edx, edx + cpuid + mov [r11], eax + mov [r11 + 4], ebx + mov [r11 + 8], ecx + mov [r11 + 12], edx + pop rbx + ret +ENDFUNC cpGetReg + +;################################################### + +; OSXSAVE support, feature information after cpuid(1), ECX, bit 27 ( XGETBV is enabled by OS ) +%assign XSAVEXGETBV_FLAG 8000000h + +; Feature information after XGETBV(ECX=0), EAX, bits 2,1 ( XMM state and YMM state are enabled by OS ) +%assign XGETBV_MASK 06h + +%assign XGETBV_AVX512_MASK 0E0h + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cp_is_avx_extension,PUBLIC + push rbx + mov eax, 1 + cpuid + xor eax, eax + and ecx, 018000000h + cmp ecx, 018000000h + jne .not_avx + xor ecx, ecx + db 00fh,001h,0d0h ; xgetbv + mov ecx, eax + xor eax, eax + and ecx, XGETBV_MASK + cmp ecx, XGETBV_MASK + jne .not_avx + mov eax, 1 +.not_avx: + pop rbx + ret +ENDFUNC cp_is_avx_extension + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cp_is_avx512_extension,PUBLIC + push rbx + mov eax, 1 + cpuid + xor eax, eax + and ecx, XSAVEXGETBV_FLAG + cmp ecx, XSAVEXGETBV_FLAG + jne .not_avx512 + xor ecx, ecx + db 00fh,001h,0d0h ; xgetbv + mov ecx, eax + xor eax, eax + and ecx, XGETBV_AVX512_MASK + cmp ecx, XGETBV_AVX512_MASK + jne .not_avx512 + mov eax, 1 +.not_avx512: + pop rbx + ret +ENDFUNC cp_is_avx512_extension + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cp_issue_avx512_instruction,PUBLIC + db 062h,0f1h,07dh,048h,0efh,0c0h ; vpxord zmm0, zmm0, zmm0 + xor eax, eax + ret +ENDFUNC cp_issue_avx512_instruction + +%ifdef OSXEM64T + extern _ippcpInit +%else + extern ippcpInit +%endif + +;#################################################################### +;# void ippSafeInit( ); # +;#################################################################### + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC ippcpSafeInit,PUBLIC + push rcx + push rdx +%ifdef LINUX32E + push rdi + push rsi +%endif + push r8 + push r9 +%ifdef LINUX32E + %ifdef OSXEM64T + call _ippcpInit + %else + %ifdef IPP_PIC + call ippcpInit wrt ..plt + %else + call ippcpInit + %endif + %endif +%else + call ippcpInit +%endif + pop r9 + pop r8 +%ifdef LINUX32E + pop rsi + pop rdi +%endif + pop rdx + pop rcx + ret +ENDFUNC ippcpSafeInit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cp_get_pentium_counter,PUBLIC + rdtsc + sal rdx,32 + or rax,rdx + ret +ENDFUNC cp_get_pentium_counter + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStartTscp,PUBLIC + push rbx + xor rax, rax + cpuid + pop rbx + rdtscp + sal rdx,32 + or rax,rdx + ret +ENDFUNC cpStartTscp + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStopTscp,PUBLIC + rdtscp + sal rdx,32 + or rax,rdx + push rax + push rbx + xor rax, rax + cpuid + pop rbx + pop rax + ret +ENDFUNC cpStopTscp + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStartTsc,PUBLIC + push rbx + xor rax, rax + cpuid + pop rbx + rdtsc + sal rdx,32 + or rax,rdx + ret +ENDFUNC cpStartTsc + +align LOCAL_ALIGN_FACTOR +DECLARE_FUNC cpStopTsc,PUBLIC + rdtsc + sal rdx,32 + or rax,rdx + push rax + push rbx + xor rax, rax + cpuid + pop rbx + pop rax + ret +ENDFUNC cpStopTsc + + +;***************************************** +; int cpGetCacheSize( int* tableCache ); +align LOCAL_ALIGN_FACTOR +%define table rdi +DECLARE_FUNC cpGetCacheSize,PUBLIC +%assign LOCAL_FRAME 16 + USES_GPR rsi, rdi, rbx, rbp + USES_XMM + COMP_ABI 1 + + mov rbp, rsp + xor esi, esi + + mov eax, 2 + cpuid + + cmp al, 1 + jne .GetCacheSize_11 + + test eax, 080000000h + jz .GetCacheSize_00 + xor eax, eax +.GetCacheSize_00: + test ebx, 080000000h + jz .GetCacheSize_01 + xor ebx, ebx +.GetCacheSize_01: + test ecx, 080000000h + jz .GetCacheSize_02 + xor ecx, ecx +.GetCacheSize_02: + test edx, 080000000h + jz .GetCacheSize_03 + xor edx, edx + +.GetCacheSize_03: + test eax, eax + jz .GetCacheSize_04 + mov [rbp], eax + add rbp, 4 + add esi, 3 +.GetCacheSize_04: + test ebx, ebx + jz .GetCacheSize_05 + mov [rbp], ebx + add rbp, 4 + add esi, 4 +.GetCacheSize_05: + test ecx, ecx + jz .GetCacheSize_06 + mov [rbp], ecx + add rbp, 4 + add esi, 4 +.GetCacheSize_06: + test edx, edx + jz .GetCacheSize_07 + mov [rbp], edx + add esi, 4 + +.GetCacheSize_07: + test esi, esi + jz .GetCacheSize_11 + mov eax, -1 +.GetCacheSize_08: + xor edx, edx + add edx, [table] + jz .ExitGetCacheSize00 + add table, 8 + mov ecx, esi +.GetCacheSize_09: + cmp dl, BYTE [rsp + rcx] + je .GetCacheSize_10 + dec ecx + jnz .GetCacheSize_09 + jmp .GetCacheSize_08 + +.GetCacheSize_10: + mov eax, [table - 4] + +.ExitGetCacheSize00: + REST_XMM + REST_GPR + ret + +.GetCacheSize_11: + mov eax, -1 + jmp .ExitGetCacheSize00 +ENDFUNC cpGetCacheSize + +;**************************** + +%endif ; _IPP_DATA diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/emulator.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/emulator.inc new file mode 100644 index 000000000..e0eeebf8f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/emulator.inc @@ -0,0 +1,340 @@ +;=============================================================================== +; Copyright (C) 2009 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: EM64T Cryptography Primitive. +; +; +; + +%ifndef _EMULATOR_INC_ +%define _EMULATOR_INC_ + +%macro my_pclmulqdq 3.nolist + %xdefine %%xxDst %1 + %xdefine %%xxSrc %2 + %xdefine %%xxOp %3 + + %if (my_emulator == 0) + pclmulqdq %%xxDst, %%xxSrc, %%xxOp + %else +;; +;; rsp +;; registers +;; +00 => xxDst +;; +16 => xxSrc + + pushf + push rax + push rbx + push rcx + push rdx + push rdi + push rsi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + %assign %%stackSize (sizeof(oword)*2) + sub rsp,%%stackSize + + movdqu oword [rsp+00], %%xxDst ;; save Dst + movdqu oword [rsp+16], %%xxSrc ;; save Src + + lea rcx, [rsp+00] + lea rdx, [rsp+16] + mov r8, %%xxOp + + sub rsp, (sizeof(qword)*3) + call emu_pclmulqdq + add rsp, (sizeof(qword)*3) + + movdqu %%xxDst, oword [rsp+00] ;; return Dst + ;movdqu xxSrc, oword [rsp+16] ;; return Src + add esp, %%stackSize + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rsi + pop rdi + pop rdx + pop rcx + pop rbx + pop rax + popf + %endif +%endmacro + +%macro my_aesenc 2.nolist + %xdefine %%xxDst %1 + %xdefine %%xxSrc %2 + + %if (my_emulator == 0) + aesenc %%xxDst, %%xxSrc + %else + pushf + push rax + push rbx + push rcx + push rdx + push rdi + push rsi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + %assign %%stackSize (sizeof(oword)*2) + sub rsp,%%stackSize + + movdqu oword [rsp+00], %%xxDst ;; save Dst + movdqu oword [rsp+16], %%xxSrc ;; save Src + + lea rcx, [rsp+00] + lea rdx, [rsp+16] + + sub rsp, (sizeof(qword)*2) + call emu_aesenc + add rsp, (sizeof(qword)*2) + + movdqu %%xxDst, oword [rsp+00] ;; return Dst + add esp, %%stackSize + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rsi + pop rdi + pop rdx + pop rcx + pop rbx + pop rax + popf + %endif +%endmacro + +%macro my_aesenclast 2.nolist + %xdefine %%xxDst %1 + %xdefine %%xxSrc %2 + + %if (my_emulator == 0) + aesenclast %%xxDst, %%xxSrc + %else + pushf + push rax + push rbx + push rcx + push rdx + push rdi + push rsi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + %assign %%stackSize (sizeof(oword)*2) + sub rsp,%%stackSize + + movdqu oword [rsp+00], %%xxDst ;; save Dst + movdqu oword [rsp+16], %%xxSrc ;; save Src + + lea rcx, [rsp+00] + lea rdx, [rsp+16] + + sub rsp, (sizeof(qword)*2) + call emu_aesenclast + add rsp, (sizeof(qword)*2) + + movdqu %%xxDst, oword [rsp+00] ;; return Dst + add esp, %%stackSize + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rsi + pop rdi + pop rdx + pop rcx + pop rbx + pop rax + popf + %endif +%endmacro + +%macro my_aesdec 2.nolist + %xdefine %%xxDst %1 + %xdefine %%xxSrc %2 + + %if (my_emulator == 0) + aesdec %%xxDst, %%xxSrc + %else + pushf + push rax + push rbx + push rcx + push rdx + push rdi + push rsi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + %assign %%stackSize (sizeof(oword)*2) + sub rsp,%%stackSize + + movdqu oword [rsp+00], %%xxDst ;; save Dst + movdqu oword [rsp+16], %%xxSrc ;; save Src + + lea rcx, [rsp+00] + lea rdx, [rsp+16] + + sub rsp, (sizeof(qword)*2) + call emu_aesdec + add rsp, (sizeof(qword)*2) + + movdqu %%xxDst, oword [rsp+00] ;; return Dst + add esp, %%stackSize + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rsi + pop rdi + pop rdx + pop rcx + pop rbx + pop rax + popf + %endif +%endmacro + +%macro my_aesdeclast 2.nolist + %xdefine %%xxDst %1 + %xdefine %%xxSrc %2 + + %if (my_emulator == 0) + aesenclast %%xxDst, %%xxSrc + %else + pushf + push rax + push rbx + push rcx + push rdx + push rdi + push rsi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + %assign %%stackSize (sizeof(oword)*2) + sub rsp,%%stackSize + + movdqu oword [rsp+00], %%xxDst ;; save Dst + movdqu oword [rsp+16], %%xxSrc ;; save Src + + lea rcx, [rsp+00] + lea rdx, [rsp+16] + + sub rsp, (sizeof(qword)*2) + call emu_aesdeclast + add rsp, (sizeof(qword)*2) + + movdqu %%xxDst, oword [rsp+00] ;; return Dst + add esp, %%stackSize + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rsi + pop rdi + pop rdx + pop rcx + pop rbx + pop rax + popf + %endif +%endmacro + +%if (my_emulator != 0) + extern emu_pclmulqdq + extern emu_aesenc + extern emu_aesenclast + extern emu_aesdec + extern emu_aesdeclast +%endif + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm128_api_vaes_avx512.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm128_api_vaes_avx512.asm new file mode 100644 index 000000000..031cc5a66 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm128_api_vaes_avx512.asm @@ -0,0 +1,27 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%define GCM128_MODE 1 +%include "gcm_api_vaes_avx512.inc" +%include "gcm_ippcp_api_vaes_avx512.inc" + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm128_avx512.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm128_avx512.asm new file mode 100644 index 000000000..1a5f4fbc5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm128_avx512.asm @@ -0,0 +1,26 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%define GCM128_MODE 1 +%include "gcm_avx512.inc" + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm192_api_vaes_avx512.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm192_api_vaes_avx512.asm new file mode 100644 index 000000000..4ba4841d3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm192_api_vaes_avx512.asm @@ -0,0 +1,27 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%define GCM192_MODE 1 +;; single buffer implementation +%include "gcm_api_vaes_avx512.inc" + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm192_avx512.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm192_avx512.asm new file mode 100644 index 000000000..82c645ff0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm192_avx512.asm @@ -0,0 +1,26 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%define GCM192_MODE 1 +%include "gcm_avx512.inc" + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm256_api_vaes_avx512.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm256_api_vaes_avx512.asm new file mode 100644 index 000000000..5f23906b9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm256_api_vaes_avx512.asm @@ -0,0 +1,27 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%define GCM256_MODE 1 +;; single buffer implementation +%include "gcm_api_vaes_avx512.inc" + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm256_avx512.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm256_avx512.asm new file mode 100644 index 000000000..8abcd5530 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm256_avx512.asm @@ -0,0 +1,26 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_K0) + +%define GCM256_MODE 1 +%include "gcm_avx512.inc" + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_api_vaes_avx512.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_api_vaes_avx512.inc new file mode 100644 index 000000000..b943ea38e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_api_vaes_avx512.inc @@ -0,0 +1,203 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef _GCM_API_VAES_AVX512_INC_ +%define _GCM_API_VAES_AVX512_INC_ + +%include "gcm_vaes_avx512.inc" + +section .text +default rel + +;; Safe param check is disabled as parameters checking is done outside. +%ifdef SAFE_PARAM +%undef SAFE_PARAM +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_precomp_128_vaes_avx512 / +; aes_gcm_precomp_192_vaes_avx512 / +; aes_gcm_precomp_256_vaes_avx512 +; (struct gcm_key_data *key_data) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(precomp,_), PUBLIC +;; Parameter is passed through register +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz .exit_precomp +%endif + + FUNC_SAVE + + vpxor xmm6, xmm6 + ENCRYPT_SINGLE_BLOCK arg1, xmm6 ; xmm6 = HashKey + + vpshufb xmm6, [rel SHUF_MASK] + ;;;;;;;;;;;;;;; PRECOMPUTATION of HashKey<<1 mod poly from the HashKey;;;;;;;;;;;;;;; + vmovdqa xmm2, xmm6 + vpsllq xmm6, xmm6, 1 + vpsrlq xmm2, xmm2, 63 + vmovdqa xmm1, xmm2 + vpslldq xmm2, xmm2, 8 + vpsrldq xmm1, xmm1, 8 + vpor xmm6, xmm6, xmm2 + ;reduction + vpshufd xmm2, xmm1, 00100100b + vpcmpeqd xmm2, [rel TWOONE] + vpand xmm2, xmm2, [rel POLY] + vpxor xmm6, xmm6, xmm2 ; xmm6 holds the HashKey<<1 mod poly + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vmovdqu [arg1 + HashKey], xmm6 ; store HashKey<<1 mod poly + + + PRECOMPUTE arg1, xmm6, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm7, xmm8 + + FUNC_RESTORE +.exit_precomp: + + ret + +ENDFUNC FN_NAME(precomp,_) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_enc_128_update_vaes_avx512 / aes_gcm_enc_192_update_vaes_avx512 / +; aes_gcm_enc_256_update_vaes_avx512 +; (const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; u8 *out, +; const u8 *in, +; u64 plaintext_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(enc,_update_), PUBLIC + + FUNC_SAVE + +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz .exit_update_enc + + ;; Check context_data != NULL + cmp arg2, 0 + jz .exit_update_enc + + ;; Check if plaintext_len == 0 + cmp arg5, 0 + jz .exit_update_enc + + ;; Check out != NULL (plaintext_len != 0) + cmp arg3, 0 + jz .exit_update_enc + + ;; Check in != NULL (plaintext_len != 0) + cmp arg4, 0 + jz .exit_update_enc +%endif + GCM_ENC_DEC arg1, arg2, arg3, arg4, arg5, ENC, multi_call + +.exit_update_enc: + FUNC_RESTORE + ret + +ENDFUNC FN_NAME(enc,_update_) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_dec_128_update_vaes_avx512 / aes_gcm_dec_192_update_vaes_avx512 / +; aes_gcm_dec_256_update_vaes_avx512 +; (const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; u8 *out, +; const u8 *in, +; u64 plaintext_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(dec,_update_), PUBLIC + FUNC_SAVE + +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz .exit_update_dec + + ;; Check context_data != NULL + cmp arg2, 0 + jz .exit_update_dec + + ;; Check if plaintext_len == 0 + cmp arg5, 0 + jz .exit_update_dec + + ;; Check out != NULL (plaintext_len != 0) + cmp arg3, 0 + jz .exit_update_dec + + ;; Check in != NULL (plaintext_len != 0) + cmp arg4, 0 + jz .exit_update_dec +%endif + + GCM_ENC_DEC arg1, arg2, arg3, arg4, arg5, DEC, multi_call + +.exit_update_dec: + FUNC_RESTORE + ret + +ENDFUNC FN_NAME(dec,_update_) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_gettag_128_vaes_avx512 / aes_gcm_gettag_192_vaes_avx512 / +; aes_gcm_gettag_256_vaes_avx512 +; (const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; u8 *auth_tag, +; u64 auth_tag_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(gettag,_), PUBLIC + +;; All parameters are passed through registers +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz .exit_enc_fin + + ;; Check context_data != NULL + cmp arg2, 0 + jz .exit_enc_fin + + ;; Check auth_tag != NULL + cmp arg3, 0 + jz .exit_enc_fin + + ;; Check auth_tag_len == 0 or > 16 + cmp arg4, 0 + jz .exit_enc_fin + + cmp arg4, 16 + ja .exit_enc_fin +%endif + + FUNC_SAVE + GCM_COMPLETE arg1, arg2, arg3, arg4, multi_call, k1, r10, r11, r12 + + FUNC_RESTORE + +.exit_enc_fin: + ret + +ENDFUNC FN_NAME(gettag,_) + +%endif ; _GCM_API_VAES_AVX512_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_avx512.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_avx512.inc new file mode 100644 index 000000000..b49cc66d3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_avx512.inc @@ -0,0 +1,3591 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Authors: +; Erdinc Ozturk +; Vinodh Gopal +; James Guilford +; Tomasz Kantecki +; +; +; References: +; This code was derived and highly optimized from the code described in paper: +; Vinodh Gopal et. al. Optimized Galois-Counter-Mode Implementation on Intel Architecture Processors. August, 2010 +; The details of the implementation is explained in: +; Erdinc Ozturk et. al. Enabling High-Performance Galois-Counter-Mode on Intel Architecture Processors. October, 2012. +; +; +; +; +; Assumptions: +; +; +; +; iv: +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Salt (From the SA) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Initialization Vector | +; | (This is the sequence number from IPSec header) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 0x1 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; +; +; +; AAD: +; AAD will be padded with 0 to the next 16byte multiple +; for example, assume AAD is a u32 vector +; +; if AAD is 8 bytes: +; AAD[3] = {A0, A1}; +; padded AAD in xmm register = {A1 A0 0 0} +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | SPI (A1) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 32-bit Sequence Number (A0) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 0x0 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; +; AAD Format with 32-bit Sequence Number +; +; if AAD is 12 bytes: +; AAD[3] = {A0, A1, A2}; +; padded AAD in xmm register = {A2 A1 A0 0} +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | SPI (A2) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 64-bit Extended Sequence Number {A1,A0} | +; | | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 0x0 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; +; AAD Format with 64-bit Extended Sequence Number +; +; +; aadLen: +; Must be a multiple of 4 bytes and from the definition of the spec. +; The code additionally supports any aadLen length. +; +; TLen: +; from the definition of the spec, TLen can only be 8, 12 or 16 bytes. +; +; poly = x^128 + x^127 + x^126 + x^121 + 1 +; throughout the code, one tab and two tab indentations are used. one tab is for GHASH part, two tabs is for AES part. +; + +%ifndef _GCM_AVX512_INC_ +%define _GCM_AVX512_INC_ + +%include "os.inc" +%include "reg_sizes.inc" +%include "clear_regs.inc" +%include "gcm_defines.inc" +%include "gcm_keys_avx512.inc" +%include "memcpy.inc" +%include "aes_common.inc" + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%ifndef GCM128_MODE +%ifndef GCM192_MODE +%ifndef GCM256_MODE +%error "No GCM mode selected for gcm_avx512.asm!" +%endif +%endif +%endif + +;; Decide on AES-GCM key size to compile for +%ifdef GCM128_MODE +%define NROUNDS 9 +%define FN_NAME(x,y) aes_gcm_ %+ x %+ _128 %+ y %+ avx512 +%endif + +%ifdef GCM192_MODE +%define NROUNDS 11 +%define FN_NAME(x,y) aes_gcm_ %+ x %+ _192 %+ y %+ avx512 +%endif + +%ifdef GCM256_MODE +%define NROUNDS 13 +%define FN_NAME(x,y) aes_gcm_ %+ x %+ _256 %+ y %+ avx512 +%endif + +section .text +default rel + +; need to push 4 registers into stack to maintain +%define STACK_OFFSET 8*4 + +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_STORAGE 16*10 +%else + %define XMM_STORAGE 0 +%endif + +%define TMP2 16*0 ; Temporary storage for AES State 2 (State 1 is stored in an XMM register) +%define TMP3 16*1 ; Temporary storage for AES State 3 +%define TMP4 16*2 ; Temporary storage for AES State 4 +%define TMP5 16*3 ; Temporary storage for AES State 5 +%define TMP6 16*4 ; Temporary storage for AES State 6 +%define TMP7 16*5 ; Temporary storage for AES State 7 +%define TMP8 16*6 ; Temporary storage for AES State 8 +%define LOCAL_STORAGE 16*7 +%define VARIABLE_OFFSET LOCAL_STORAGE + XMM_STORAGE + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Utility Macros +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) +; Input: A and B (128-bits each, bit-reflected) +; Output: C = A*B*x mod poly, (i.e. >>1 ) +; To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input +; GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GHASH_MUL 7 +%define %%GH %1 ; 16 Bytes +%define %%HK %2 ; 16 Bytes +%define %%T1 %3 +%define %%T2 %4 +%define %%T3 %5 +%define %%T4 %6 +%define %%T5 %7 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + vpclmulqdq %%T1, %%GH, %%HK, 0x11 ; %%T1 = a1*b1 + vpclmulqdq %%T2, %%GH, %%HK, 0x00 ; %%T2 = a0*b0 + vpclmulqdq %%T3, %%GH, %%HK, 0x01 ; %%T3 = a1*b0 + vpclmulqdq %%GH, %%GH, %%HK, 0x10 ; %%GH = a0*b1 + vpxor %%GH, %%GH, %%T3 + + + vpsrldq %%T3, %%GH, 8 ; shift-R %%GH 2 DWs + vpslldq %%GH, %%GH, 8 ; shift-L %%GH 2 DWs + + vpxor %%T1, %%T1, %%T3 + vpxor %%GH, %%GH, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqu %%T3, [rel POLY2] + + vpclmulqdq %%T2, %%T3, %%GH, 0x01 + vpslldq %%T2, %%T2, 8 ; shift-L %%T2 2 DWs + + vpxor %%GH, %%GH, %%T2 ; first phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;second phase of the reduction + vpclmulqdq %%T2, %%T3, %%GH, 0x00 + vpsrldq %%T2, %%T2, 4 ; shift-R %%T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%GH, %%T3, %%GH, 0x10 + vpslldq %%GH, %%GH, 4 ; shift-L %%GH 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%GH, %%GH, %%T2 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%GH, %%GH, %%T1 ; the result is in %%GH +%endmacro + + +; In PRECOMPUTE, the commands filling Hashkey_i_k are not required for avx512 +; functions, but are kept to allow users to switch cpu architectures between calls +; of pre, init, update, and finalize. +%macro PRECOMPUTE 8 +%define %%GDATA %1 +%define %%HK %2 +%define %%T1 %3 +%define %%T2 %4 +%define %%T3 %5 +%define %%T4 %6 +%define %%T5 %7 +%define %%T6 %8 + + ; Haskey_i_k holds XORed values of the low and high parts of the Haskey_i + vmovdqa %%T5, %%HK + + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 ; %%T5 = HashKey^2<<1 mod poly + vmovdqu [%%GDATA + HashKey_2], %%T5 ; [HashKey_2] = HashKey^2<<1 mod poly + + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 ; %%T5 = HashKey^3<<1 mod poly + vmovdqu [%%GDATA + HashKey_3], %%T5 + + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 ; %%T5 = HashKey^4<<1 mod poly + vmovdqu [%%GDATA + HashKey_4], %%T5 + + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 ; %%T5 = HashKey^5<<1 mod poly + vmovdqu [%%GDATA + HashKey_5], %%T5 + + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 ; %%T5 = HashKey^6<<1 mod poly + vmovdqu [%%GDATA + HashKey_6], %%T5 + + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 ; %%T5 = HashKey^7<<1 mod poly + vmovdqu [%%GDATA + HashKey_7], %%T5 + + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 ; %%T5 = HashKey^8<<1 mod poly + vmovdqu [%%GDATA + HashKey_8], %%T5 +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; READ_SMALL_DATA_INPUT: Packs xmm register with data when data input is less than 16 bytes. +; Returns 0 if data has length 0. +; Input: The input data (INPUT), that data's length (LENGTH). +; Output: The packed xmm register (OUTPUT). +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro READ_SMALL_DATA_INPUT 4 +%define %%OUTPUT %1 ; %%OUTPUT is an xmm register +%define %%INPUT %2 +%define %%LENGTH %3 +%define %%TMP1 %4 + + lea %%TMP1, [rel byte_len_to_mask_table] +%ifidn __OUTPUT_FORMAT__, win64 + add %%TMP1, %%LENGTH + add %%TMP1, %%LENGTH + kmovw k1, [%%TMP1] +%else + kmovw k1, [%%TMP1 + %%LENGTH*2] +%endif + vmovdqu8 XWORD(%%OUTPUT){k1}{z}, [%%INPUT] + +%endmacro ; READ_SMALL_DATA_INPUT + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CALC_AAD_HASH: Calculates the hash of the data which will not be encrypted. +; Input: The input data (A_IN), that data's length (A_LEN), and the hash key (HASH_KEY). +; Output: The hash of the data (AAD_HASH). +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro CALC_AAD_HASH 13 +%define %%A_IN %1 +%define %%A_LEN %2 +%define %%AAD_HASH %3 +%define %%GDATA_KEY %4 +%define %%XTMP0 %5 ; xmm temp reg 5 +%define %%XTMP1 %6 ; xmm temp reg 5 +%define %%XTMP2 %7 +%define %%XTMP3 %8 +%define %%XTMP4 %9 +%define %%XTMP5 %10 ; xmm temp reg 5 +%define %%T1 %11 ; temp reg 1 +%define %%T2 %12 +%define %%T3 %13 + + + mov %%T1, %%A_IN ; T1 = AAD + mov %%T2, %%A_LEN ; T2 = aadLen + vpxor %%AAD_HASH, %%AAD_HASH + +%%_get_AAD_loop128: + cmp %%T2, 128 + jl %%_exit_AAD_loop128 + + vmovdqu %%XTMP0, [%%T1 + 16*0] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vpxor %%XTMP0, %%AAD_HASH + + vmovdqu %%XTMP5, [%%GDATA_KEY + HashKey_8] + vpclmulqdq %%XTMP1, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = a1*b1 + vpclmulqdq %%XTMP2, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = a0*b0 + vpclmulqdq %%XTMP3, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = a1*b0 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 ; %%T4 = a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 ; %%T3 = a1*b0 + a0*b1 + +%assign i 1 +%assign j 7 +%rep 7 + vmovdqu %%XTMP0, [%%T1 + 16*i] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vmovdqu %%XTMP5, [%%GDATA_KEY + HashKey_ %+ j] + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = T1 + a1*b1 + vpxor %%XTMP1, %%XTMP1, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = T2 + a0*b0 + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = T3 + a1*b0 + a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 +%assign i (i + 1) +%assign j (j - 1) +%endrep + + vpslldq %%XTMP4, %%XTMP3, 8 ; shift-L 2 DWs + vpsrldq %%XTMP3, %%XTMP3, 8 ; shift-R 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + vpxor %%XTMP1, %%XTMP1, %%XTMP3 ; accumulate the results in %%T1(M):%%T2(L) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqa %%XTMP5, [rel POLY2] + vpclmulqdq %%XTMP0, %%XTMP5, %%XTMP2, 0x01 + vpslldq %%XTMP0, %%XTMP0, 8 ; shift-L xmm2 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP0 ; first phase of the reduction complete + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;second phase of the reduction + vpclmulqdq %%XTMP3, %%XTMP5, %%XTMP2, 0x00 + vpsrldq %%XTMP3, %%XTMP3, 4 ; shift-R 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%XTMP4, %%XTMP5, %%XTMP2, 0x10 + vpslldq %%XTMP4, %%XTMP4, 4 ; shift-L 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%XTMP4, %%XTMP4, %%XTMP3 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%AAD_HASH, %%XTMP1, %%XTMP4 ; the result is in %%T1 + + sub %%T2, 128 + je %%_CALC_AAD_done + + add %%T1, 128 + jmp %%_get_AAD_loop128 + +%%_exit_AAD_loop128: + cmp %%T2, 16 + jl %%_get_small_AAD_block + + ;; calculate hash_key position to start with + mov %%T3, %%T2 + and %%T3, -16 ; 1 to 7 blocks possible here + neg %%T3 + add %%T3, HashKey_1 + 16 + lea %%T3, [%%GDATA_KEY + %%T3] + + vmovdqu %%XTMP0, [%%T1] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vpxor %%XTMP0, %%AAD_HASH + + vmovdqu %%XTMP5, [%%T3] + vpclmulqdq %%XTMP1, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = a1*b1 + vpclmulqdq %%XTMP2, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = a0*b0 + vpclmulqdq %%XTMP3, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = a1*b0 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 ; %%T4 = a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 ; %%T3 = a1*b0 + a0*b1 + + add %%T3, 16 ; move to next hashkey + add %%T1, 16 ; move to next data block + sub %%T2, 16 + cmp %%T2, 16 + jl %%_AAD_reduce + +%%_AAD_blocks: + vmovdqu %%XTMP0, [%%T1] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vmovdqu %%XTMP5, [%%T3] + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = T1 + a1*b1 + vpxor %%XTMP1, %%XTMP1, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = T2 + a0*b0 + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = T3 + a1*b0 + a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 + + add %%T3, 16 ; move to next hashkey + add %%T1, 16 + sub %%T2, 16 + cmp %%T2, 16 + jl %%_AAD_reduce + jmp %%_AAD_blocks + +%%_AAD_reduce: + vpslldq %%XTMP4, %%XTMP3, 8 ; shift-L 2 DWs + vpsrldq %%XTMP3, %%XTMP3, 8 ; shift-R 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + vpxor %%XTMP1, %%XTMP1, %%XTMP3 ; accumulate the results in %%T1(M):%%T2(L) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqa %%XTMP5, [rel POLY2] + vpclmulqdq %%XTMP0, %%XTMP5, %%XTMP2, 0x01 + vpslldq %%XTMP0, %%XTMP0, 8 ; shift-L xmm2 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP0 ; first phase of the reduction complete + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;second phase of the reduction + vpclmulqdq %%XTMP3, %%XTMP5, %%XTMP2, 0x00 + vpsrldq %%XTMP3, %%XTMP3, 4 ; shift-R 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%XTMP4, %%XTMP5, %%XTMP2, 0x10 + vpslldq %%XTMP4, %%XTMP4, 4 ; shift-L 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%XTMP4, %%XTMP4, %%XTMP3 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%AAD_HASH, %%XTMP1, %%XTMP4 ; the result is in %%T1 + + or %%T2, %%T2 + je %%_CALC_AAD_done + +%%_get_small_AAD_block: + vmovdqu %%XTMP0, [%%GDATA_KEY + HashKey] + READ_SMALL_DATA_INPUT %%XTMP1, %%T1, %%T2, %%T3 + ;byte-reflect the AAD data + vpshufb %%XTMP1, [rel SHUF_MASK] + vpxor %%AAD_HASH, %%XTMP1 + GHASH_MUL %%AAD_HASH, %%XTMP0, %%XTMP1, %%XTMP2, %%XTMP3, %%XTMP4, %%XTMP5 + +%%_CALC_AAD_done: + +%endmacro ; CALC_AAD_HASH + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; PARTIAL_BLOCK: Handles encryption/decryption and the tag partial blocks between update calls. +; Requires the input data be at least 1 byte long. +; Input: gcm_key_data * (GDATA_KEY), gcm_context_data *(GDATA_CTX), input text (PLAIN_CYPH_IN), +; input text length (PLAIN_CYPH_LEN), the current data offset (DATA_OFFSET), +; and whether encoding or decoding (ENC_DEC) +; Output: A cypher of the first partial block (CYPH_PLAIN_OUT), and updated GDATA_CTX +; Clobbers rax, r10, r12, r13, r15, xmm0, xmm1, xmm2, xmm3, xmm5, xmm6, xmm9, xmm10, xmm11, xmm13 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro PARTIAL_BLOCK 8 +%define %%GDATA_KEY %1 +%define %%GDATA_CTX %2 +%define %%CYPH_PLAIN_OUT %3 +%define %%PLAIN_CYPH_IN %4 +%define %%PLAIN_CYPH_LEN %5 +%define %%DATA_OFFSET %6 +%define %%AAD_HASH %7 +%define %%ENC_DEC %8 + + mov r13, [%%GDATA_CTX + PBlockLen] + cmp r13, 0 + je %%_partial_block_done ;Leave Macro if no partial blocks + + cmp %%PLAIN_CYPH_LEN, 16 ;Read in input data without over reading + jl %%_fewer_than_16_bytes + VXLDR xmm1, [%%PLAIN_CYPH_IN] ;If more than 16 bytes of data, just fill the xmm register + jmp %%_data_read + +%%_fewer_than_16_bytes: + lea r10, [%%PLAIN_CYPH_IN] + READ_SMALL_DATA_INPUT xmm1, r10, %%PLAIN_CYPH_LEN, rax + +%%_data_read: ;Finished reading in data + + vmovdqu xmm9, [%%GDATA_CTX + PBlockEncKey] ;xmm9 = my_ctx_data.partial_block_enc_key + vmovdqu xmm13, [%%GDATA_KEY + HashKey] + + lea r12, [rel SHIFT_MASK] + + add r12, r13 ; adjust the shuffle mask pointer to be able to shift r13 bytes (16-r13 is the number of bytes in plaintext mod 16) + vmovdqu xmm2, [r12] ; get the appropriate shuffle mask + vpshufb xmm9, xmm2 ;shift right r13 bytes + +%ifidn %%ENC_DEC, DEC + vmovdqa xmm3, xmm1 +%endif + vpxor xmm9, xmm1 ; Cyphertext XOR E(K, Yn) + + mov r15, %%PLAIN_CYPH_LEN + add r15, r13 + sub r15, 16 ;Set r15 to be the amount of data left in CYPH_PLAIN_IN after filling the block + jge %%_no_extra_mask ;Determine if if partial block is not being filled and shift mask accordingly + sub r12, r15 +%%_no_extra_mask: + + vmovdqu xmm1, [r12 + ALL_F - SHIFT_MASK]; get the appropriate mask to mask out bottom r13 bytes of xmm9 + vpand xmm9, xmm1 ; mask out bottom r13 bytes of xmm9 + +%ifidn %%ENC_DEC, DEC + vpand xmm3, xmm1 + vpshufb xmm3, [rel SHUF_MASK] + vpshufb xmm3, xmm2 + vpxor %%AAD_HASH, xmm3 +%else + vpshufb xmm9, [rel SHUF_MASK] + vpshufb xmm9, xmm2 + vpxor %%AAD_HASH, xmm9 +%endif + cmp r15,0 + jl %%_partial_incomplete + + GHASH_MUL %%AAD_HASH, xmm13, xmm0, xmm10, xmm11, xmm5, xmm6 ;GHASH computation for the last <16 Byte block + xor rax,rax + mov [%%GDATA_CTX + PBlockLen], rax + jmp %%_enc_dec_done +%%_partial_incomplete: +%ifidn __OUTPUT_FORMAT__, win64 + mov rax, %%PLAIN_CYPH_LEN + add [%%GDATA_CTX + PBlockLen], rax +%else + add [%%GDATA_CTX + PBlockLen], %%PLAIN_CYPH_LEN +%endif +%%_enc_dec_done: + vmovdqu [%%GDATA_CTX + AadHash], %%AAD_HASH + +%ifidn %%ENC_DEC, ENC + vpshufb xmm9, [rel SHUF_MASK] ; shuffle xmm9 back to output as ciphertext + vpshufb xmm9, xmm2 +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; output encrypted Bytes + cmp r15,0 + jl %%_partial_fill + mov r12, r13 + mov r13, 16 + sub r13, r12 ; Set r13 to be the number of bytes to write out + jmp %%_count_set +%%_partial_fill: + mov r13, %%PLAIN_CYPH_LEN +%%_count_set: + lea rax, [rel byte_len_to_mask_table] + kmovw k1, [rax + r13*2] + vmovdqu8 [%%CYPH_PLAIN_OUT + %%DATA_OFFSET]{k1}, xmm9 + add %%DATA_OFFSET, r13 +%%_partial_block_done: +%endmacro ; PARTIAL_BLOCK + + +%macro GHASH_SINGLE_MUL 9 +%define %%GDATA %1 +%define %%HASHKEY %2 +%define %%CIPHER %3 +%define %%STATE_11 %4 +%define %%STATE_00 %5 +%define %%STATE_MID %6 +%define %%T1 %7 +%define %%T2 %8 +%define %%FIRST %9 + + vmovdqu %%T1, [%%GDATA + %%HASHKEY] +%ifidn %%FIRST, first + vpclmulqdq %%STATE_11, %%CIPHER, %%T1, 0x11 ; %%T4 = a1*b1 + vpclmulqdq %%STATE_00, %%CIPHER, %%T1, 0x00 ; %%T4_2 = a0*b0 + vpclmulqdq %%STATE_MID, %%CIPHER, %%T1, 0x01 ; %%T6 = a1*b0 + vpclmulqdq %%T2, %%CIPHER, %%T1, 0x10 ; %%T5 = a0*b1 + vpxor %%STATE_MID, %%STATE_MID, %%T2 +%else + vpclmulqdq %%T2, %%CIPHER, %%T1, 0x11 + vpxor %%STATE_11, %%STATE_11, %%T2 + + vpclmulqdq %%T2, %%CIPHER, %%T1, 0x00 + vpxor %%STATE_00, %%STATE_00, %%T2 + + vpclmulqdq %%T2, %%CIPHER, %%T1, 0x01 + vpxor %%STATE_MID, %%STATE_MID, %%T2 + + vpclmulqdq %%T2, %%CIPHER, %%T1, 0x10 + vpxor %%STATE_MID, %%STATE_MID, %%T2 +%endif + +%endmacro + +; if a = number of total plaintext bytes +; b = floor(a/16) +; %%num_initial_blocks = b mod 8; +; encrypt the initial %%num_initial_blocks blocks and apply ghash on the ciphertext +; %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r14 are used as a pointer only, not modified. +; Updated AAD_HASH is returned in %%T3 + +%macro INITIAL_BLOCKS 23 +%define %%GDATA_KEY %1 +%define %%CYPH_PLAIN_OUT %2 +%define %%PLAIN_CYPH_IN %3 +%define %%LENGTH %4 +%define %%DATA_OFFSET %5 +%define %%num_initial_blocks %6 ; can be 0, 1, 2, 3, 4, 5, 6 or 7 +%define %%T1 %7 +%define %%T2 %8 +%define %%T3 %9 +%define %%T4 %10 +%define %%T5 %11 +%define %%CTR %12 +%define %%XMM1 %13 +%define %%XMM2 %14 +%define %%XMM3 %15 +%define %%XMM4 %16 +%define %%XMM5 %17 +%define %%XMM6 %18 +%define %%XMM7 %19 +%define %%XMM8 %20 +%define %%T6 %21 +%define %%T_key %22 +%define %%ENC_DEC %23 + +%assign i (8-%%num_initial_blocks) + ;; Move AAD_HASH to temp reg + vmovdqu %%T2, %%XMM8 + ;; Start AES for %%num_initial_blocks blocks + ;; vmovdqu %%CTR, [%%GDATA_CTX + CurCount] ; %%CTR = Y0 + +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + vpaddd %%CTR, %%CTR, [rel ONE] ; INCR Y0 + vmovdqa reg(i), %%CTR + vpshufb reg(i), [rel SHUF_MASK] ; perform a 16Byte swap +%assign i (i+1) +%endrep + +%if(%%num_initial_blocks>0) +vmovdqu %%T_key, [%%GDATA_KEY+16*0] +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + vpxor reg(i),reg(i),%%T_key +%assign i (i+1) +%endrep + +%assign j 1 +%rep NROUNDS +vmovdqu %%T_key, [%%GDATA_KEY+16*j] +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + vaesenc reg(i),%%T_key +%assign i (i+1) +%endrep + +%assign j (j+1) +%endrep + + +vmovdqu %%T_key, [%%GDATA_KEY+16*j] +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + vaesenclast reg(i),%%T_key +%assign i (i+1) +%endrep + +%endif ; %if(%%num_initial_blocks>0) + + + +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET] + vpxor reg(i), reg(i), %%T1 + ;; Write back ciphertext for %%num_initial_blocks blocks + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET], reg(i) + add %%DATA_OFFSET, 16 + %ifidn %%ENC_DEC, DEC + vmovdqa reg(i), %%T1 + %endif + ;; Prepare ciphertext for GHASH computations + vpshufb reg(i), [rel SHUF_MASK] +%assign i (i+1) +%endrep + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%assign i (9-%%num_initial_blocks) +%if(%%num_initial_blocks>0) + vmovdqa %%T3, reg(i) +%assign i (i+1) +%endif +%if %%num_initial_blocks>1 +%rep %%num_initial_blocks-1 + vmovdqu [rsp + TMP %+ i], reg(i) +%assign i (i+1) +%endrep +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Prepare 8 counter blocks and perform rounds of AES cipher on + ;; them, load plain/cipher text and store cipher/plain text. + ;; Stitch GHASH computation in between AES rounds. + vpaddd %%XMM1, %%CTR, [rel ONE] ; INCR Y0 + vpaddd %%XMM2, %%CTR, [rel TWO] ; INCR Y0 + vpaddd %%XMM3, %%XMM1, [rel TWO] ; INCR Y0 + vpaddd %%XMM4, %%XMM2, [rel TWO] ; INCR Y0 + vpaddd %%XMM5, %%XMM3, [rel TWO] ; INCR Y0 + vpaddd %%XMM6, %%XMM4, [rel TWO] ; INCR Y0 + vpaddd %%XMM7, %%XMM5, [rel TWO] ; INCR Y0 + vpaddd %%XMM8, %%XMM6, [rel TWO] ; INCR Y0 + vmovdqa %%CTR, %%XMM8 + + vpshufb %%XMM1, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM2, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM3, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM4, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM5, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM6, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM7, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM8, [rel SHUF_MASK] ; perform a 16Byte swap + + vmovdqu %%T_key, [%%GDATA_KEY+16*0] + vpxor %%XMM1, %%XMM1, %%T_key + vpxor %%XMM2, %%XMM2, %%T_key + vpxor %%XMM3, %%XMM3, %%T_key + vpxor %%XMM4, %%XMM4, %%T_key + vpxor %%XMM5, %%XMM5, %%T_key + vpxor %%XMM6, %%XMM6, %%T_key + vpxor %%XMM7, %%XMM7, %%T_key + vpxor %%XMM8, %%XMM8, %%T_key + +%assign i (8-%%num_initial_blocks) +%assign j (9-%%num_initial_blocks) +%assign k (%%num_initial_blocks) + +%define %%T4_2 %%T4 +%if(%%num_initial_blocks>0) + ;; Hash in AES state + ;; T2 - incoming AAD hash + vpxor %%T2, %%T3 + + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, first +%endif + + vmovdqu %%T_key, [%%GDATA_KEY+16*1] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + + vmovdqu %%T_key, [%%GDATA_KEY+16*2] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%if(%%num_initial_blocks>1) + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + vmovdqu %%T2, [rsp + TMP %+ j] + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, not_first +%endif + + vmovdqu %%T_key, [%%GDATA_KEY+16*3] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + + vmovdqu %%T_key, [%%GDATA_KEY+16*4] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%if(%%num_initial_blocks>2) + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + vmovdqu %%T2, [rsp + TMP %+ j] + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, not_first +%endif + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%if(%%num_initial_blocks>3) + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + vmovdqu %%T2, [rsp + TMP %+ j] + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, not_first +%endif + + vmovdqu %%T_key, [%%GDATA_KEY+16*5] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + + vmovdqu %%T_key, [%%GDATA_KEY+16*6] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%if(%%num_initial_blocks>4) + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + vmovdqu %%T2, [rsp + TMP %+ j] + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, not_first +%endif + + vmovdqu %%T_key, [%%GDATA_KEY+16*7] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + + vmovdqu %%T_key, [%%GDATA_KEY+16*8] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%if(%%num_initial_blocks>5) + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + vmovdqu %%T2, [rsp + TMP %+ j] + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, not_first +%endif + + vmovdqu %%T_key, [%%GDATA_KEY+16*9] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + +%ifndef GCM128_MODE + vmovdqu %%T_key, [%%GDATA_KEY+16*10] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key +%endif + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%if(%%num_initial_blocks>6) + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + vmovdqu %%T2, [rsp + TMP %+ j] + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, not_first +%endif + +%ifdef GCM128_MODE + vmovdqu %%T_key, [%%GDATA_KEY+16*10] + vaesenclast %%XMM1, %%T_key + vaesenclast %%XMM2, %%T_key + vaesenclast %%XMM3, %%T_key + vaesenclast %%XMM4, %%T_key + vaesenclast %%XMM5, %%T_key + vaesenclast %%XMM6, %%T_key + vaesenclast %%XMM7, %%T_key + vaesenclast %%XMM8, %%T_key +%endif + +%ifdef GCM192_MODE + vmovdqu %%T_key, [%%GDATA_KEY+16*11] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + + vmovdqu %%T_key, [%%GDATA_KEY+16*12] + vaesenclast %%XMM1, %%T_key + vaesenclast %%XMM2, %%T_key + vaesenclast %%XMM3, %%T_key + vaesenclast %%XMM4, %%T_key + vaesenclast %%XMM5, %%T_key + vaesenclast %%XMM6, %%T_key + vaesenclast %%XMM7, %%T_key + vaesenclast %%XMM8, %%T_key +%endif +%ifdef GCM256_MODE + vmovdqu %%T_key, [%%GDATA_KEY+16*11] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + + vmovdqu %%T_key, [%%GDATA_KEY+16*12] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key +%endif + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%if(%%num_initial_blocks>7) + ;; GDATA, HASHKEY, CIPHER, + ;; STATE_11, STATE_00, STATE_MID, T1, T2 + vmovdqu %%T2, [rsp + TMP %+ j] + GHASH_SINGLE_MUL %%GDATA_KEY, HashKey_ %+ k, %%T2, \ + %%T1, %%T4, %%T6, %%T5, %%T3, not_first +%endif + +%ifdef GCM256_MODE ; GCM256 + vmovdqu %%T_key, [%%GDATA_KEY+16*13] + vaesenc %%XMM1, %%T_key + vaesenc %%XMM2, %%T_key + vaesenc %%XMM3, %%T_key + vaesenc %%XMM4, %%T_key + vaesenc %%XMM5, %%T_key + vaesenc %%XMM6, %%T_key + vaesenc %%XMM7, %%T_key + vaesenc %%XMM8, %%T_key + + vmovdqu %%T_key, [%%GDATA_KEY+16*14] + vaesenclast %%XMM1, %%T_key + vaesenclast %%XMM2, %%T_key + vaesenclast %%XMM3, %%T_key + vaesenclast %%XMM4, %%T_key + vaesenclast %%XMM5, %%T_key + vaesenclast %%XMM6, %%T_key + vaesenclast %%XMM7, %%T_key + vaesenclast %%XMM8, %%T_key +%endif ; GCM256 mode + +%if(%%num_initial_blocks>0) + vpsrldq %%T3, %%T6, 8 ; shift-R %%T2 2 DWs + vpslldq %%T6, %%T6, 8 ; shift-L %%T3 2 DWs + vpxor %%T1, %%T1, %%T3 ; accumulate the results in %%T1:%%T4 + vpxor %%T4, %%T6, %%T4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; First phase of the reduction + vmovdqu %%T3, [rel POLY2] + + vpclmulqdq %%T2, %%T3, %%T4, 0x01 + vpslldq %%T2, %%T2, 8 ; shift-L xmm2 2 DWs + + ;; First phase of the reduction complete + vpxor %%T4, %%T4, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; Second phase of the reduction + vpclmulqdq %%T2, %%T3, %%T4, 0x00 + ;; Shift-R xmm2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + vpsrldq %%T2, %%T2, 4 + + vpclmulqdq %%T4, %%T3, %%T4, 0x10 + ;; Shift-L xmm0 1 DW (Shift-L 1-DW to obtain result with no shifts) + vpslldq %%T4, %%T4, 4 + ;; Second phase of the reduction complete + vpxor %%T4, %%T4, %%T2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; The result is in %%T3 + vpxor %%T3, %%T1, %%T4 +%else + ;; The hash should end up in T3 + vmovdqa %%T3, %%T2 +%endif + + ;; Final hash is now in T3 +%if %%num_initial_blocks > 0 + ;; NOTE: obsolete in case %%num_initial_blocks = 0 + sub %%LENGTH, 16*%%num_initial_blocks +%endif + + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*0] + vpxor %%XMM1, %%XMM1, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*0], %%XMM1 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM1, %%T1 + %endif + + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*1] + vpxor %%XMM2, %%XMM2, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*1], %%XMM2 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM2, %%T1 + %endif + + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*2] + vpxor %%XMM3, %%XMM3, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*2], %%XMM3 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM3, %%T1 + %endif + + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*3] + vpxor %%XMM4, %%XMM4, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*3], %%XMM4 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM4, %%T1 + %endif + + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*4] + vpxor %%XMM5, %%XMM5, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*4], %%XMM5 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM5, %%T1 + %endif + + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*5] + vpxor %%XMM6, %%XMM6, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*5], %%XMM6 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM6, %%T1 + %endif + + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*6] + vpxor %%XMM7, %%XMM7, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*6], %%XMM7 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM7, %%T1 + %endif + +%if %%num_initial_blocks > 0 + ;; NOTE: 'jl' is never taken for %%num_initial_blocks = 0 + ;; This macro is executed for lenght 128 and up, + ;; zero length is checked in GCM_ENC_DEC. + ;; If the last block is partial then the xor will be done later + ;; in ENCRYPT_FINAL_PARTIAL_BLOCK. + ;; We know it's partial if LENGTH - 16*num_initial_blocks < 128 + cmp %%LENGTH, 128 + jl %%_initial_skip_last_word_write +%endif + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET + 16*7] + vpxor %%XMM8, %%XMM8, %%T1 + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET + 16*7], %%XMM8 + %ifidn %%ENC_DEC, DEC + vmovdqa %%XMM8, %%T1 + %endif + + ;; Update %%LENGTH with the number of blocks processed + sub %%LENGTH, 16 + add %%DATA_OFFSET, 16 +%%_initial_skip_last_word_write: + sub %%LENGTH, 128-16 + add %%DATA_OFFSET, 128-16 + + vpshufb %%XMM1, [rel SHUF_MASK] ; perform a 16Byte swap + ;; Combine GHASHed value with the corresponding ciphertext + vpxor %%XMM1, %%XMM1, %%T3 + vpshufb %%XMM2, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM3, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM4, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM5, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM6, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM7, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM8, [rel SHUF_MASK] ; perform a 16Byte swap + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%%_initial_blocks_done: + + +%endmacro + +;;; INITIAL_BLOCKS macro with support for a partial final block. +;;; num_initial_blocks is expected to include the partial final block +;;; in the count. +%macro INITIAL_BLOCKS_PARTIAL 25 +%define %%GDATA_KEY %1 +%define %%GDATA_CTX %2 +%define %%CYPH_PLAIN_OUT %3 +%define %%PLAIN_CYPH_IN %4 +%define %%LENGTH %5 +%define %%DATA_OFFSET %6 +%define %%num_initial_blocks %7 ; can be 1, 2, 3, 4, 5, 6 or 7 (not 0) +%define %%T1 %8 +%define %%T2 %9 +%define %%T3 %10 ; [out] hash value +%define %%T4 %11 +%define %%T5 %12 +%define %%CTR %13 +%define %%XMM1 %14 +%define %%XMM2 %15 +%define %%XMM3 %16 +%define %%XMM4 %17 +%define %%XMM5 %18 +%define %%XMM6 %19 +%define %%XMM7 %20 +%define %%XMM8 %21 ; [in] hash value +%define %%T6 %22 +%define %%T_key %23 +%define %%ENC_DEC %24 +%define %%INSTANCE_TYPE %25 + + ;; Move AAD_HASH to temp reg + vmovdqu %%T2, %%XMM8 + +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + ;; Compute AES counters + vpaddd %%CTR, %%CTR, [rel ONE] ; INCR Y0 + vmovdqa reg(i), %%CTR + vpshufb reg(i), [rel SHUF_MASK] ; perform a 16Byte swap +%assign i (i+1) +%endrep + +vmovdqu %%T_key, [%%GDATA_KEY+16*0] +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + ; Start AES for %%num_initial_blocks blocks + vpxor reg(i),reg(i),%%T_key +%assign i (i+1) +%endrep + +%assign j 1 +%rep NROUNDS +vmovdqu %%T_key, [%%GDATA_KEY+16*j] +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + vaesenc reg(i),%%T_key +%assign i (i+1) +%endrep + +%assign j (j+1) +%endrep + + +vmovdqu %%T_key, [%%GDATA_KEY+16*j] +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks + vaesenclast reg(i),%%T_key +%assign i (i+1) +%endrep + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Hash all but the last block of data +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%assign i (9-%%num_initial_blocks) +%rep %%num_initial_blocks-1 + ;; Encrypt the message for all but the last block + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET] + vpxor reg(i), reg(i), %%T1 + ;; write back ciphertext for %%num_initial_blocks blocks + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET], reg(i) + add %%DATA_OFFSET, 16 +%ifidn %%ENC_DEC, DEC + vmovdqa reg(i), %%T1 +%endif + ;; Prepare ciphertext for GHASH computations + vpshufb reg(i), [rel SHUF_MASK] +%assign i (i+1) +%endrep + +%if %%num_initial_blocks > 1 + ;; The final block of data may be <16B + sub %%LENGTH, 16*(%%num_initial_blocks-1) +%endif + +%if %%num_initial_blocks < 8 + ;; NOTE: the 'jl' is always taken for num_initial_blocks = 8. + ;; This is run in the context of GCM_ENC_DEC_SMALL for length < 128. + cmp %%LENGTH, 16 + jl %%_small_initial_partial_block + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Handle a full length final block - encrypt and hash all blocks +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + sub %%LENGTH, 16 + mov [%%GDATA_CTX + PBlockLen], %%LENGTH + + ;; Encrypt the message + VXLDR %%T1, [%%PLAIN_CYPH_IN + %%DATA_OFFSET] + vpxor reg(i), reg(i), %%T1 + ;; write back ciphertext for %%num_initial_blocks blocks + VXSTR [%%CYPH_PLAIN_OUT + %%DATA_OFFSET], reg(i) + add %%DATA_OFFSET, 16 +%ifidn %%ENC_DEC, DEC + vmovdqa reg(i), %%T1 +%endif + ;; Prepare ciphertext for GHASH computations + vpshufb reg(i), [rel SHUF_MASK] + + ;; Hash all of the data +%assign i (8-%%num_initial_blocks) +%assign j (9-%%num_initial_blocks) +%assign k (%%num_initial_blocks) +%assign last_block_to_hash 0 + +%if(%%num_initial_blocks>last_block_to_hash) + ;; Hash in AES state + vpxor %%T2, reg(j) + + ;; T2 - incoming AAD hash + ;; reg(i) holds ciphertext + ;; T5 - hash key + ;; T6 - updated xor + ;; reg(1)/xmm1 should now be available for tmp use + vmovdqu %%T5, [%%GDATA_KEY + HashKey_ %+ k] + vpclmulqdq %%T1, %%T2, %%T5, 0x11 ; %%T4 = a1*b1 + vpclmulqdq %%T4, %%T2, %%T5, 0x00 ; %%T4 = a0*b0 + vpclmulqdq %%T6, %%T2, %%T5, 0x01 ; %%T6 = a1*b0 + vpclmulqdq %%T5, %%T2, %%T5, 0x10 ; %%T5 = a0*b1 + vpxor %%T6, %%T6, %%T5 +%endif + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%assign rep_count (%%num_initial_blocks-1) +%rep rep_count + + vmovdqu %%T5, [%%GDATA_KEY + HashKey_ %+ k] + vpclmulqdq %%T3, reg(j), %%T5, 0x11 + vpxor %%T1, %%T1, %%T3 + + vpclmulqdq %%T3, reg(j), %%T5, 0x00 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, reg(j), %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, reg(j), %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%endrep + + ;; Record that a reduction is needed + mov r12, 1 + + jmp %%_small_initial_compute_hash + + +%endif ; %if %%num_initial_blocks < 8 + +%%_small_initial_partial_block: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Handle ghash for a <16B final block +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; In this case if it's a single call to encrypt we can + ;; hash all of the data but if it's an init / update / finalize + ;; series of call we need to leave the last block if it's + ;; less than a full block of data. + + mov [%%GDATA_CTX + PBlockLen], %%LENGTH + vmovdqu [%%GDATA_CTX + PBlockEncKey], reg(i) + ;; Handle a partial final block + ;; GDATA, KEY, T1, T2 + ;; r13 - length + ;; LT16 - indicates type of read and that the buffer is less than 16 bytes long + ;; NOTE: could be replaced with %%LENGTH but at this point + ;; %%LENGTH is always less than 16. + ;; No PLAIN_CYPH_LEN argument available in this macro. + ENCRYPT_FINAL_PARTIAL_BLOCK reg(i), %%T1, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, LT16, %%ENC_DEC, %%DATA_OFFSET + vpshufb reg(i), [rel SHUF_MASK] + +%ifidn %%INSTANCE_TYPE, multi_call +%assign i (8-%%num_initial_blocks) +%assign j (9-%%num_initial_blocks) +%assign k (%%num_initial_blocks-1) +%assign last_block_to_hash 1 +%else +%assign i (8-%%num_initial_blocks) +%assign j (9-%%num_initial_blocks) +%assign k (%%num_initial_blocks) +%assign last_block_to_hash 0 +%endif + +%if(%%num_initial_blocks>last_block_to_hash) + ;; Record that a reduction is needed + mov r12, 1 + ;; Hash in AES state + vpxor %%T2, reg(j) + + ;; T2 - incoming AAD hash + ;; reg(i) holds ciphertext + ;; T5 - hash key + ;; T6 - updated xor + ;; reg(1)/xmm1 should now be available for tmp use + vmovdqu %%T5, [%%GDATA_KEY + HashKey_ %+ k] + vpclmulqdq %%T1, %%T2, %%T5, 0x11 ; %%T4 = a1*b1 + vpclmulqdq %%T4, %%T2, %%T5, 0x00 ; %%T4 = a0*b0 + vpclmulqdq %%T6, %%T2, %%T5, 0x01 ; %%T6 = a1*b0 + vpclmulqdq %%T5, %%T2, %%T5, 0x10 ; %%T5 = a0*b1 + vpxor %%T6, %%T6, %%T5 +%else + ;; Record that a reduction is not needed - + ;; In this case no hashes are computed because there + ;; is only one initial block and it is < 16B in length. + xor r12, r12 +%endif + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%ifidn %%INSTANCE_TYPE, multi_call +%assign rep_count (%%num_initial_blocks-2) +%%_multi_call_hash: +%else +%assign rep_count (%%num_initial_blocks-1) +%endif + +%if rep_count < 0 + ;; fix for negative rep_count +%assign rep_count 0 +%endif + +%rep rep_count + + vmovdqu %%T5, [%%GDATA_KEY + HashKey_ %+ k] + vpclmulqdq %%T3, reg(j), %%T5, 0x11 + vpxor %%T1, %%T1, %%T3 + + vpclmulqdq %%T3, reg(j), %%T5, 0x00 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, reg(j), %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, reg(j), %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + +%assign i (i+1) +%assign j (j+1) +%assign k (k-1) +%endrep + +%%_small_initial_compute_hash: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Ghash reduction +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%if(%%num_initial_blocks=1) +%ifidn %%INSTANCE_TYPE, multi_call + ;; We only need to check if a reduction is needed if + ;; initial_blocks == 1 and init/update/final is being used. + ;; In this case we may just have a partial block, and that + ;; gets hashed in finalize. + ;; cmp r12, 0 + or r12, r12 + je %%_no_reduction_needed +%endif +%endif + + vpsrldq %%T3, %%T6, 8 ; shift-R %%T2 2 DWs + vpslldq %%T6, %%T6, 8 ; shift-L %%T3 2 DWs + vpxor %%T1, %%T1, %%T3 ; accumulate the results in %%T1:%%T4 + vpxor %%T4, %%T6, %%T4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; First phase of the reduction + vmovdqu %%T3, [rel POLY2] + + vpclmulqdq %%T2, %%T3, %%T4, 0x01 + ;; shift-L xmm2 2 DWs + vpslldq %%T2, %%T2, 8 + vpxor %%T4, %%T4, %%T2 + + ;; First phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Second phase of the reduction + + vpclmulqdq %%T2, %%T3, %%T4, 0x00 + ;; Shift-R xmm2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + vpsrldq %%T2, %%T2, 4 + + vpclmulqdq %%T4, %%T3, %%T4, 0x10 + ;; Shift-L xmm0 1 DW (Shift-L 1-DW to obtain result with no shifts) + vpslldq %%T4, %%T4, 4 + + vpxor %%T4, %%T4, %%T2 + ;; Second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%T3, %%T1, %%T4 + +%ifidn %%INSTANCE_TYPE, multi_call + ;; If using init/update/finalize, we need to xor any partial block data + ;; into the hash. +%if %%num_initial_blocks > 1 + ;; NOTE: for %%num_initial_blocks = 0 the xor never takes place +%if %%num_initial_blocks != 8 + ;; NOTE: for %%num_initial_blocks = 8, %%LENGTH, stored in [PBlockLen] is never zero + cmp qword [%%GDATA_CTX + PBlockLen], 0 + je %%_no_partial_block_xor +%endif ; %%num_initial_blocks != 8 + vpxor %%T3, %%T3, reg(8) +%%_no_partial_block_xor: +%endif ; %%num_initial_blocks > 1 +%endif ; %%INSTANCE_TYPE, multi_call + +%if(%%num_initial_blocks=1) +%ifidn %%INSTANCE_TYPE, multi_call + ;; NOTE: %%_no_reduction_needed case only valid for + ;; multi_call with initial_blocks = 1. + ;; Look for comment above around '_no_reduction_needed' + ;; The jmp below is obsolete as the code will fall through. + + ;; The result is in %%T3 + jmp %%_after_reduction + +%%_no_reduction_needed: + ;; The hash should end up in T3. The only way we should get here is if + ;; there is a partial block of data, so xor that into the hash. + vpxor %%T3, %%T2, reg(8) +%endif ; %%INSTANCE_TYPE = multi_call +%endif ; %%num_initial_blocks=1 + +%%_after_reduction: + ;; Final hash is now in T3 + +%endmacro ; INITIAL_BLOCKS_PARTIAL + + + +; encrypt 8 blocks at a time +; ghash the 8 previously encrypted ciphertext blocks +; %%GDATA (KEY), %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN are used as pointers only, not modified +; %%DATA_OFFSET is the data offset value +%macro GHASH_8_ENCRYPT_8_PARALLEL 23 +%define %%GDATA %1 +%define %%CYPH_PLAIN_OUT %2 +%define %%PLAIN_CYPH_IN %3 +%define %%DATA_OFFSET %4 +%define %%T1 %5 +%define %%T2 %6 +%define %%T3 %7 +%define %%T4 %8 +%define %%T5 %9 +%define %%T6 %10 +%define %%CTR %11 +%define %%XMM1 %12 +%define %%XMM2 %13 +%define %%XMM3 %14 +%define %%XMM4 %15 +%define %%XMM5 %16 +%define %%XMM6 %17 +%define %%XMM7 %18 +%define %%XMM8 %19 +%define %%T7 %20 +%define %%loop_idx %21 +%define %%ENC_DEC %22 +%define %%FULL_PARTIAL %23 + + vmovdqa %%T2, %%XMM1 + vmovdqu [rsp + TMP2], %%XMM2 + vmovdqu [rsp + TMP3], %%XMM3 + vmovdqu [rsp + TMP4], %%XMM4 + vmovdqu [rsp + TMP5], %%XMM5 + vmovdqu [rsp + TMP6], %%XMM6 + vmovdqu [rsp + TMP7], %%XMM7 + vmovdqu [rsp + TMP8], %%XMM8 + +%ifidn %%loop_idx, in_order + vpaddd %%XMM1, %%CTR, [rel ONE] ; INCR CNT + vmovdqu %%T5, [rel TWO] + vpaddd %%XMM2, %%CTR, %%T5 + vpaddd %%XMM3, %%XMM1, %%T5 + vpaddd %%XMM4, %%XMM2, %%T5 + vpaddd %%XMM5, %%XMM3, %%T5 + vpaddd %%XMM6, %%XMM4, %%T5 + vpaddd %%XMM7, %%XMM5, %%T5 + vpaddd %%XMM8, %%XMM6, %%T5 + vmovdqa %%CTR, %%XMM8 + + vmovdqu %%T5, [rel SHUF_MASK] + vpshufb %%XMM1, %%T5 ; perform a 16Byte swap + vpshufb %%XMM2, %%T5 ; perform a 16Byte swap + vpshufb %%XMM3, %%T5 ; perform a 16Byte swap + vpshufb %%XMM4, %%T5 ; perform a 16Byte swap + vpshufb %%XMM5, %%T5 ; perform a 16Byte swap + vpshufb %%XMM6, %%T5 ; perform a 16Byte swap + vpshufb %%XMM7, %%T5 ; perform a 16Byte swap + vpshufb %%XMM8, %%T5 ; perform a 16Byte swap +%else + vpaddd %%XMM1, %%CTR, [rel ONEf] ; INCR CNT + vmovdqu %%T5, [rel TWOf] + vpaddd %%XMM2, %%CTR, %%T5 + vpaddd %%XMM3, %%XMM1, %%T5 + vpaddd %%XMM4, %%XMM2, %%T5 + vpaddd %%XMM5, %%XMM3, %%T5 + vpaddd %%XMM6, %%XMM4, %%T5 + vpaddd %%XMM7, %%XMM5, %%T5 + vpaddd %%XMM8, %%XMM6, %%T5 + vmovdqa %%CTR, %%XMM8 +%endif + + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T1, [%%GDATA + 16*0] + vpxor %%XMM1, %%XMM1, %%T1 + vpxor %%XMM2, %%XMM2, %%T1 + vpxor %%XMM3, %%XMM3, %%T1 + vpxor %%XMM4, %%XMM4, %%T1 + vpxor %%XMM5, %%XMM5, %%T1 + vpxor %%XMM6, %%XMM6, %%T1 + vpxor %%XMM7, %%XMM7, %%T1 + vpxor %%XMM8, %%XMM8, %%T1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T1, [%%GDATA + 16*1] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + + vmovdqu %%T1, [%%GDATA + 16*2] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_8] + vpclmulqdq %%T4, %%T2, %%T5, 0x11 ; %%T4 = a1*b1 + vpclmulqdq %%T7, %%T2, %%T5, 0x00 ; %%T7 = a0*b0 + vpclmulqdq %%T6, %%T2, %%T5, 0x01 ; %%T6 = a1*b0 + vpclmulqdq %%T5, %%T2, %%T5, 0x10 ; %%T5 = a0*b1 + vpxor %%T6, %%T6, %%T5 + + vmovdqu %%T1, [%%GDATA + 16*3] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + vmovdqu %%T1, [rsp + TMP2] + vmovdqu %%T5, [%%GDATA + HashKey_7] + vpclmulqdq %%T3, %%T1, %%T5, 0x11 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x00 + vpxor %%T7, %%T7, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + + vmovdqu %%T1, [%%GDATA + 16*4] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vmovdqu %%T1, [rsp + TMP3] + vmovdqu %%T5, [%%GDATA + HashKey_6] + vpclmulqdq %%T3, %%T1, %%T5, 0x11 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x00 + vpxor %%T7, %%T7, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + + vmovdqu %%T1, [%%GDATA + 16*5] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + + vmovdqu %%T1, [rsp + TMP4] + vmovdqu %%T5, [%%GDATA + HashKey_5] + vpclmulqdq %%T3, %%T1, %%T5, 0x11 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x00 + vpxor %%T7, %%T7, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + + vmovdqu %%T1, [%%GDATA + 16*6] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + vmovdqu %%T1, [rsp + TMP5] + vmovdqu %%T5, [%%GDATA + HashKey_4] + vpclmulqdq %%T3, %%T1, %%T5, 0x11 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x00 + vpxor %%T7, %%T7, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + + vmovdqu %%T1, [%%GDATA + 16*7] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + vmovdqu %%T1, [rsp + TMP6] + vmovdqu %%T5, [%%GDATA + HashKey_3] + vpclmulqdq %%T3, %%T1, %%T5, 0x11 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x00 + vpxor %%T7, %%T7, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + + vmovdqu %%T1, [%%GDATA + 16*8] + vaesenc %%XMM1, %%T1 + vaesenc %%XMM2, %%T1 + vaesenc %%XMM3, %%T1 + vaesenc %%XMM4, %%T1 + vaesenc %%XMM5, %%T1 + vaesenc %%XMM6, %%T1 + vaesenc %%XMM7, %%T1 + vaesenc %%XMM8, %%T1 + + vmovdqu %%T1, [rsp + TMP7] + vmovdqu %%T5, [%%GDATA + HashKey_2] + vpclmulqdq %%T3, %%T1, %%T5, 0x11 + vpxor %%T4, %%T4, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x00 + vpxor %%T7, %%T7, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + 16*9] + vaesenc %%XMM1, %%T5 + vaesenc %%XMM2, %%T5 + vaesenc %%XMM3, %%T5 + vaesenc %%XMM4, %%T5 + vaesenc %%XMM5, %%T5 + vaesenc %%XMM6, %%T5 + vaesenc %%XMM7, %%T5 + vaesenc %%XMM8, %%T5 + + vmovdqu %%T1, [rsp + TMP8] + vmovdqu %%T5, [%%GDATA + HashKey] + + + vpclmulqdq %%T3, %%T1, %%T5, 0x00 + vpxor %%T7, %%T7, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x01 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x10 + vpxor %%T6, %%T6, %%T3 + + vpclmulqdq %%T3, %%T1, %%T5, 0x11 + vpxor %%T1, %%T4, %%T3 + + + vmovdqu %%T5, [%%GDATA + 16*10] + %ifndef GCM128_MODE ; GCM192 or GCM256 + vaesenc %%XMM1, %%T5 + vaesenc %%XMM2, %%T5 + vaesenc %%XMM3, %%T5 + vaesenc %%XMM4, %%T5 + vaesenc %%XMM5, %%T5 + vaesenc %%XMM6, %%T5 + vaesenc %%XMM7, %%T5 + vaesenc %%XMM8, %%T5 + + vmovdqu %%T5, [%%GDATA + 16*11] + vaesenc %%XMM1, %%T5 + vaesenc %%XMM2, %%T5 + vaesenc %%XMM3, %%T5 + vaesenc %%XMM4, %%T5 + vaesenc %%XMM5, %%T5 + vaesenc %%XMM6, %%T5 + vaesenc %%XMM7, %%T5 + vaesenc %%XMM8, %%T5 + + vmovdqu %%T5, [%%GDATA + 16*12] +%endif +%ifdef GCM256_MODE + vaesenc %%XMM1, %%T5 + vaesenc %%XMM2, %%T5 + vaesenc %%XMM3, %%T5 + vaesenc %%XMM4, %%T5 + vaesenc %%XMM5, %%T5 + vaesenc %%XMM6, %%T5 + vaesenc %%XMM7, %%T5 + vaesenc %%XMM8, %%T5 + + vmovdqu %%T5, [%%GDATA + 16*13] + vaesenc %%XMM1, %%T5 + vaesenc %%XMM2, %%T5 + vaesenc %%XMM3, %%T5 + vaesenc %%XMM4, %%T5 + vaesenc %%XMM5, %%T5 + vaesenc %%XMM6, %%T5 + vaesenc %%XMM7, %%T5 + vaesenc %%XMM8, %%T5 + + vmovdqu %%T5, [%%GDATA + 16*14] +%endif ; GCM256 + +%assign i 0 +%assign j 1 +%rep 8 + + ;; SNP TBD: This is pretty ugly - consider whether just XORing the + ;; data in after vaesenclast is simpler and performant. Would + ;; also have to ripple it through partial block and ghash_mul_8. +%ifidn %%FULL_PARTIAL, full + %ifdef NT_LD + VXLDR %%T2, [%%PLAIN_CYPH_IN+%%DATA_OFFSET+16*i] + vpxor %%T2, %%T2, %%T5 + %else + vpxor %%T2, %%T5, [%%PLAIN_CYPH_IN+%%DATA_OFFSET+16*i] + %endif + + %ifidn %%ENC_DEC, ENC + vaesenclast reg(j), reg(j), %%T2 + %else + vaesenclast %%T3, reg(j), %%T2 + vpxor reg(j), %%T2, %%T5 + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*i], %%T3 + %endif + +%else + ; Don't read the final data during partial block processing + %ifdef NT_LD + %if (i<7) + VXLDR %%T2, [%%PLAIN_CYPH_IN+%%DATA_OFFSET+16*i] + vpxor %%T2, %%T2, %%T5 + %else + ;; Stage the key directly in T2 rather than hash it with plaintext + vmovdqu %%T2, %%T5 + %endif + %else + %if (i<7) + vpxor %%T2, %%T5, [%%PLAIN_CYPH_IN+%%DATA_OFFSET+16*i] + %else + ;; Stage the key directly in T2 rather than hash it with plaintext + vmovdqu %%T2, %%T5 + %endif + %endif + + %ifidn %%ENC_DEC, ENC + vaesenclast reg(j), reg(j), %%T2 + %else + %if (i<7) + vaesenclast %%T3, reg(j), %%T2 + vpxor reg(j), %%T2, %%T5 + ;; Do not read the data since it could fault + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*i], %%T3 + %else + vaesenclast reg(j), reg(j), %%T2 + %endif + %endif +%endif + +%assign i (i+1) +%assign j (j+1) +%endrep + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + vpslldq %%T3, %%T6, 8 ; shift-L %%T3 2 DWs + vpsrldq %%T6, %%T6, 8 ; shift-R %%T2 2 DWs + vpxor %%T7, %%T7, %%T3 + vpxor %%T1, %%T1, %%T6 ; accumulate the results in %%T1:%%T7 + + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqu %%T3, [rel POLY2] + + vpclmulqdq %%T2, %%T3, %%T7, 0x01 + vpslldq %%T2, %%T2, 8 ; shift-L xmm2 2 DWs + + vpxor %%T7, %%T7, %%T2 ; first phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + %ifidn %%ENC_DEC, ENC + ; Write to the Ciphertext buffer + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*0], %%XMM1 + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*1], %%XMM2 + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*2], %%XMM3 + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*3], %%XMM4 + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*4], %%XMM5 + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*5], %%XMM6 + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*6], %%XMM7 + %ifidn %%FULL_PARTIAL, full + ;; Avoid writing past the buffer if handling a partial block + VXSTR [%%CYPH_PLAIN_OUT+%%DATA_OFFSET+16*7], %%XMM8 + %endif + %endif + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;second phase of the reduction + vpclmulqdq %%T2, %%T3, %%T7, 0x00 + vpsrldq %%T2, %%T2, 4 ; shift-R xmm2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%T4, %%T3, %%T7, 0x10 + vpslldq %%T4, %%T4, 4 ; shift-L xmm0 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%T4, %%T4, %%T2 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%T1, %%T1, %%T4 ; the result is in %%T1 + + vpshufb %%XMM1, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM2, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM3, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM4, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM5, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM6, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM7, [rel SHUF_MASK] ; perform a 16Byte swap + vpshufb %%XMM8, [rel SHUF_MASK] ; perform a 16Byte swap + + + vpxor %%XMM1, %%T1 + + +%endmacro ; GHASH_8_ENCRYPT_8_PARALLEL + + +; GHASH the last 4 ciphertext blocks. +%macro GHASH_LAST_8 16 +%define %%GDATA %1 +%define %%T1 %2 +%define %%T2 %3 +%define %%T3 %4 +%define %%T4 %5 +%define %%T5 %6 +%define %%T6 %7 +%define %%T7 %8 +%define %%XMM1 %9 +%define %%XMM2 %10 +%define %%XMM3 %11 +%define %%XMM4 %12 +%define %%XMM5 %13 +%define %%XMM6 %14 +%define %%XMM7 %15 +%define %%XMM8 %16 + + ;; Karatsuba Method + + vmovdqu %%T5, [%%GDATA + HashKey_8] + + vpshufd %%T2, %%XMM1, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM1 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T6, %%XMM1, %%T5, 0x11 + vpclmulqdq %%T7, %%XMM1, %%T5, 0x00 + + vpclmulqdq %%XMM1, %%T2, %%T3, 0x00 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_7] + vpshufd %%T2, %%XMM2, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM2 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM2, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM2, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_6] + vpshufd %%T2, %%XMM3, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM3 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM3, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM3, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_5] + vpshufd %%T2, %%XMM4, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM4 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM4, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM4, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_4] + vpshufd %%T2, %%XMM5, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM5 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM5, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM5, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_3] + vpshufd %%T2, %%XMM6, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM6 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM6, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM6, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_2] + vpshufd %%T2, %%XMM7, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM7 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM7, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM7, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey] + vpshufd %%T2, %%XMM8, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM8 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM8, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM8, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + vpxor %%XMM1, %%XMM1, %%T6 + vpxor %%T2, %%XMM1, %%T7 + + + + + vpslldq %%T4, %%T2, 8 + vpsrldq %%T2, %%T2, 8 + + vpxor %%T7, %%T7, %%T4 + vpxor %%T6, %%T6, %%T2 ; <%%T6:%%T7> holds the result of the accumulated carry-less multiplications + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqu %%T3, [rel POLY2] + + vpclmulqdq %%T2, %%T3, %%T7, 0x01 + vpslldq %%T2, %%T2, 8 ; shift-L xmm2 2 DWs + + vpxor %%T7, %%T7, %%T2 ; first phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + ;second phase of the reduction + vpclmulqdq %%T2, %%T3, %%T7, 0x00 + vpsrldq %%T2, %%T2, 4 ; shift-R %%T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%T4, %%T3, %%T7, 0x10 + vpslldq %%T4, %%T4, 4 ; shift-L %%T4 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%T4, %%T4, %%T2 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%T6, %%T6, %%T4 ; the result is in %%T6 +%endmacro + + +; GHASH the last 4 ciphertext blocks. +%macro GHASH_LAST_7 15 +%define %%GDATA %1 +%define %%T1 %2 +%define %%T2 %3 +%define %%T3 %4 +%define %%T4 %5 +%define %%T5 %6 +%define %%T6 %7 +%define %%T7 %8 +%define %%XMM1 %9 +%define %%XMM2 %10 +%define %%XMM3 %11 +%define %%XMM4 %12 +%define %%XMM5 %13 +%define %%XMM6 %14 +%define %%XMM7 %15 + + ;; Karatsuba Method + + vmovdqu %%T5, [%%GDATA + HashKey_7] + + vpshufd %%T2, %%XMM1, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM1 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T6, %%XMM1, %%T5, 0x11 + vpclmulqdq %%T7, %%XMM1, %%T5, 0x00 + + vpclmulqdq %%XMM1, %%T2, %%T3, 0x00 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_6] + vpshufd %%T2, %%XMM2, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM2 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM2, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM2, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_5] + vpshufd %%T2, %%XMM3, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM3 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM3, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM3, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_4] + vpshufd %%T2, %%XMM4, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM4 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM4, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM4, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_3] + vpshufd %%T2, %%XMM5, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM5 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM5, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM5, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_2] + vpshufd %%T2, %%XMM6, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM6 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM6, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM6, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vmovdqu %%T5, [%%GDATA + HashKey_1] + vpshufd %%T2, %%XMM7, 01001110b + vpshufd %%T3, %%T5, 01001110b + vpxor %%T2, %%T2, %%XMM7 + vpxor %%T3, %%T3, %%T5 + + vpclmulqdq %%T4, %%XMM7, %%T5, 0x11 + vpxor %%T6, %%T6, %%T4 + + vpclmulqdq %%T4, %%XMM7, %%T5, 0x00 + vpxor %%T7, %%T7, %%T4 + + vpclmulqdq %%T2, %%T2, %%T3, 0x00 + + vpxor %%XMM1, %%XMM1, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;; + + vpxor %%XMM1, %%XMM1, %%T6 + vpxor %%T2, %%XMM1, %%T7 + + + + + vpslldq %%T4, %%T2, 8 + vpsrldq %%T2, %%T2, 8 + + vpxor %%T7, %%T7, %%T4 + vpxor %%T6, %%T6, %%T2 ; <%%T6:%%T7> holds the result of the accumulated carry-less multiplications + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqu %%T3, [rel POLY2] + + vpclmulqdq %%T2, %%T3, %%T7, 0x01 + vpslldq %%T2, %%T2, 8 ; shift-L xmm2 2 DWs + + vpxor %%T7, %%T7, %%T2 ; first phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + ;second phase of the reduction + vpclmulqdq %%T2, %%T3, %%T7, 0x00 + vpsrldq %%T2, %%T2, 4 ; shift-R %%T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%T4, %%T3, %%T7, 0x10 + vpslldq %%T4, %%T4, 4 ; shift-L %%T4 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%T4, %%T4, %%T2 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%T6, %%T6, %%T4 ; the result is in %%T6 +%endmacro + + + +;;; Handle encryption of the final partial block +;;; IN: +;;; r13 - Number of bytes to read +;;; MODIFIES: +;;; KEY - Key for encrypting the partial block +;;; SMASHES: +;;; rax, T1 +;;; Note: +;;; PLAIN_CYPH_LEN is unused at this stage. Previously: +;;; it was used to determine if buffer is big enough to do +;;; a 16 byte read & shift. +;;; 'LT16' is passed here only if buffer is known to be smaller +;;; than 16 bytes. +;;; Any other value passed here will result in 16 byte read +;;; code path. +%macro ENCRYPT_FINAL_PARTIAL_BLOCK 7 +%define %%KEY %1 +%define %%T1 %2 +%define %%CYPH_PLAIN_OUT %3 +%define %%PLAIN_CYPH_IN %4 +%define %%PLAIN_CYPH_LEN %5 +%define %%ENC_DEC %6 +%define %%DATA_OFFSET %7 + + ;; %%PLAIN_CYPH_IN + %%DATA_OFFSET + ;; - input data address + ;; r13 - input data length + ;; rax - temp registers + ;; out: + ;; T1 - packed output + ;; k1 - valid byte mask + READ_SMALL_DATA_INPUT %%T1, %%PLAIN_CYPH_IN+%%DATA_OFFSET, r13, rax + + ;; At this point T1 contains the partial block data + ;; Plaintext XOR E(K, Yn) + vpxorq %%KEY, %%KEY, %%T1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Output r13 Bytes + vmovdqu8 [%%CYPH_PLAIN_OUT + %%DATA_OFFSET]{k1}, %%KEY + +%ifidn %%ENC_DEC, DEC + ;; If decrypt, restore the ciphertext into %%KEY + vmovdqa64 %%KEY, %%T1 +%else + vmovdqu8 %%KEY{k1}{z}, %%KEY +%endif +%endmacro ; ENCRYPT_FINAL_PARTIAL_BLOCK + + + +; Encryption of a single block +%macro ENCRYPT_SINGLE_BLOCK 2 +%define %%GDATA %1 +%define %%XMM0 %2 + + vpxor %%XMM0, %%XMM0, [%%GDATA+16*0] +%assign i 1 +%rep NROUNDS + vaesenc %%XMM0, [%%GDATA+16*i] +%assign i (i+1) +%endrep + vaesenclast %%XMM0, [%%GDATA+16*i] +%endmacro + + +;; Start of Stack Setup + +%macro FUNC_SAVE 0 + ;; Required for Update/GMC_ENC + ;the number of pushes must equal STACK_OFFSET + push r12 + push r13 + push r14 + push r15 + mov r14, rsp + + sub rsp, VARIABLE_OFFSET + and rsp, ~63 + +%ifidn __OUTPUT_FORMAT__, win64 + ; xmm6:xmm15 need to be maintained for Windows + vmovdqu [rsp + LOCAL_STORAGE + 0*16],xmm6 + vmovdqu [rsp + LOCAL_STORAGE + 1*16],xmm7 + vmovdqu [rsp + LOCAL_STORAGE + 2*16],xmm8 + vmovdqu [rsp + LOCAL_STORAGE + 3*16],xmm9 + vmovdqu [rsp + LOCAL_STORAGE + 4*16],xmm10 + vmovdqu [rsp + LOCAL_STORAGE + 5*16],xmm11 + vmovdqu [rsp + LOCAL_STORAGE + 6*16],xmm12 + vmovdqu [rsp + LOCAL_STORAGE + 7*16],xmm13 + vmovdqu [rsp + LOCAL_STORAGE + 8*16],xmm14 + vmovdqu [rsp + LOCAL_STORAGE + 9*16],xmm15 +%endif +%endmacro + + +%macro FUNC_RESTORE 0 + +%ifdef SAFE_DATA + clear_scratch_gps_asm + clear_scratch_zmms_asm +%endif +%ifidn __OUTPUT_FORMAT__, win64 + vmovdqu xmm15, [rsp + LOCAL_STORAGE + 9*16] + vmovdqu xmm14, [rsp + LOCAL_STORAGE + 8*16] + vmovdqu xmm13, [rsp + LOCAL_STORAGE + 7*16] + vmovdqu xmm12, [rsp + LOCAL_STORAGE + 6*16] + vmovdqu xmm11, [rsp + LOCAL_STORAGE + 5*16] + vmovdqu xmm10, [rsp + LOCAL_STORAGE + 4*16] + vmovdqu xmm9, [rsp + LOCAL_STORAGE + 3*16] + vmovdqu xmm8, [rsp + LOCAL_STORAGE + 2*16] + vmovdqu xmm7, [rsp + LOCAL_STORAGE + 1*16] + vmovdqu xmm6, [rsp + LOCAL_STORAGE + 0*16] +%endif +;; Required for Update/GMC_ENC + mov rsp, r14 + pop r15 + pop r14 + pop r13 + pop r12 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; UPDATE_HASH: Calculates the hash of the data which will not be encrypted. +; Input: The input data (A_IN), that data's length (A_LEN), and the hash key (HASH_KEY). +; Output: The hash of the data (AAD_HASH). +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro UPDATE_HASH 13 +%define %%A_IN %1 +%define %%A_LEN %2 +%define %%AAD_HASH %3 +%define %%GDATA_KEY %4 +%define %%XTMP0 %5 ; xmm temp reg 5 +%define %%XTMP1 %6 ; xmm temp reg 5 +%define %%XTMP2 %7 +%define %%XTMP3 %8 +%define %%XTMP4 %9 +%define %%XTMP5 %10 ; xmm temp reg 5 +%define %%T1 %11 ; temp reg 1 +%define %%T2 %12 +%define %%T3 %13 + + + mov %%T1, %%A_IN ; T1 = AAD + mov %%T2, %%A_LEN ; T2 = aadLen + + or %%T2, %%T2 + jz %%_CALC_AAD_done + +%%_get_AAD_loop128: + cmp %%T2, 128 + jl %%_exit_AAD_loop128 + + vmovdqu %%XTMP0, [%%T1 + 16*0] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vpxor %%XTMP0, %%AAD_HASH + + vmovdqu %%XTMP5, [%%GDATA_KEY + HashKey_8] + vpclmulqdq %%XTMP1, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = a1*b1 + vpclmulqdq %%XTMP2, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = a0*b0 + vpclmulqdq %%XTMP3, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = a1*b0 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 ; %%T4 = a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 ; %%T3 = a1*b0 + a0*b1 + +%assign i 1 +%assign j 7 +%rep 7 + vmovdqu %%XTMP0, [%%T1 + 16*i] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vmovdqu %%XTMP5, [%%GDATA_KEY + HashKey_ %+ j] + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = T1 + a1*b1 + vpxor %%XTMP1, %%XTMP1, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = T2 + a0*b0 + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = T3 + a1*b0 + a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 +%assign i (i + 1) +%assign j (j - 1) +%endrep + + vpslldq %%XTMP4, %%XTMP3, 8 ; shift-L 2 DWs + vpsrldq %%XTMP3, %%XTMP3, 8 ; shift-R 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + vpxor %%XTMP1, %%XTMP1, %%XTMP3 ; accumulate the results in %%T1(M):%%T2(L) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqa %%XTMP5, [rel POLY2] + vpclmulqdq %%XTMP0, %%XTMP5, %%XTMP2, 0x01 + vpslldq %%XTMP0, %%XTMP0, 8 ; shift-L xmm2 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP0 ; first phase of the reduction complete + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;second phase of the reduction + vpclmulqdq %%XTMP3, %%XTMP5, %%XTMP2, 0x00 + vpsrldq %%XTMP3, %%XTMP3, 4 ; shift-R 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%XTMP4, %%XTMP5, %%XTMP2, 0x10 + vpslldq %%XTMP4, %%XTMP4, 4 ; shift-L 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%XTMP4, %%XTMP4, %%XTMP3 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%AAD_HASH, %%XTMP1, %%XTMP4 ; the result is in %%T1 + + sub %%T2, 128 + je %%_CALC_AAD_done + + add %%T1, 128 + jmp %%_get_AAD_loop128 + +%%_exit_AAD_loop128: + cmp %%T2, 16 + jl %%_get_small_AAD_block + + ;; calculate hash_key position to start with + mov %%T3, %%T2 + and %%T3, -16 ; 1 to 7 blocks possible here + neg %%T3 + add %%T3, HashKey_1 + 16 + lea %%T3, [%%GDATA_KEY + %%T3] + + vmovdqu %%XTMP0, [%%T1] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vpxor %%XTMP0, %%AAD_HASH + + vmovdqu %%XTMP5, [%%T3] + vpclmulqdq %%XTMP1, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = a1*b1 + vpclmulqdq %%XTMP2, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = a0*b0 + vpclmulqdq %%XTMP3, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = a1*b0 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 ; %%T4 = a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 ; %%T3 = a1*b0 + a0*b1 + + add %%T3, 16 ; move to next hashkey + add %%T1, 16 ; move to next data block + sub %%T2, 16 + cmp %%T2, 16 + jl %%_AAD_reduce + +%%_AAD_blocks: + vmovdqu %%XTMP0, [%%T1] + vpshufb %%XTMP0, [rel SHUF_MASK] + + vmovdqu %%XTMP5, [%%T3] + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x11 ; %%T1 = T1 + a1*b1 + vpxor %%XTMP1, %%XTMP1, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x00 ; %%T2 = T2 + a0*b0 + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x01 ; %%T3 = T3 + a1*b0 + a0*b1 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 + vpclmulqdq %%XTMP4, %%XTMP0, %%XTMP5, 0x10 + vpxor %%XTMP3, %%XTMP3, %%XTMP4 + + add %%T3, 16 ; move to next hashkey + add %%T1, 16 + sub %%T2, 16 + cmp %%T2, 16 + jl %%_AAD_reduce + jmp %%_AAD_blocks + +%%_AAD_reduce: + vpslldq %%XTMP4, %%XTMP3, 8 ; shift-L 2 DWs + vpsrldq %%XTMP3, %%XTMP3, 8 ; shift-R 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP4 + vpxor %%XTMP1, %%XTMP1, %%XTMP3 ; accumulate the results in %%T1(M):%%T2(L) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqa %%XTMP5, [rel POLY2] + vpclmulqdq %%XTMP0, %%XTMP5, %%XTMP2, 0x01 + vpslldq %%XTMP0, %%XTMP0, 8 ; shift-L xmm2 2 DWs + vpxor %%XTMP2, %%XTMP2, %%XTMP0 ; first phase of the reduction complete + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;second phase of the reduction + vpclmulqdq %%XTMP3, %%XTMP5, %%XTMP2, 0x00 + vpsrldq %%XTMP3, %%XTMP3, 4 ; shift-R 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R) + + vpclmulqdq %%XTMP4, %%XTMP5, %%XTMP2, 0x10 + vpslldq %%XTMP4, %%XTMP4, 4 ; shift-L 1 DW (Shift-L 1-DW to obtain result with no shifts) + + vpxor %%XTMP4, %%XTMP4, %%XTMP3 ; second phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vpxor %%AAD_HASH, %%XTMP1, %%XTMP4 ; the result is in %%T1 + + or %%T2, %%T2 + je %%_CALC_AAD_done + +%%_get_small_AAD_block: + vmovdqu %%XTMP0, [%%GDATA_KEY + HashKey] + READ_SMALL_DATA_INPUT %%XTMP1, %%T1, %%T2, %%T3 + ;byte-reflect the AAD data + vpshufb %%XTMP1, [rel SHUF_MASK] + vpxor %%AAD_HASH, %%XTMP1 + GHASH_MUL %%AAD_HASH, %%XTMP0, %%XTMP1, %%XTMP2, %%XTMP3, %%XTMP4, %%XTMP5 + +%%_CALC_AAD_done: + +%endmacro ; UPDATE_HASH + +%macro CALC_J0 14 +%define %%KEY %1 ;; [in] Pointer to GCM KEY structure +%define %%IV %2 ;; [in] Pointer to IV +%define %%IV_LEN %3 ;; [in] IV length +%define %%J0 %4 ;; [out] XMM reg to contain J0 +%define %%TMP0 %5 ;; [clobbered] Temporary GP reg +%define %%TMP1 %6 ;; [clobbered] Temporary GP reg +%define %%TMP2 %7 ;; [clobbered] Temporary GP reg +%define %%XTMP0 %8 ;; [clobbered] Temporary XMM reg +%define %%XTMP1 %9 ;; [clobbered] Temporary XMM reg +%define %%XTMP2 %10 ;; [clobbered] Temporary XMM reg +%define %%XTMP3 %11 ;; [clobbered] Temporary XMM reg +%define %%XTMP4 %12 ;; [clobbered] Temporary XMM reg +%define %%XTMP5 %13 ;; [clobbered] Temporary XMM reg +%define %%IV_GEN_LEN %14 ;; [in] IV general length + + ;; J0 = GHASH(IV || 0s+64 || len(IV)64) + ;; s = 16 * RoundUp(len(IV)/16) - len(IV) */ + + ;; Calculate GHASH of (IV || 0s) + UPDATE_HASH %%IV, %%IV_LEN, %%J0, %%KEY, %%XTMP0, %%XTMP1, %%XTMP2, \ + %%XTMP3, %%XTMP4, %%XTMP5, %%TMP0, %%TMP1, %%TMP2 + + ;; Calculate GHASH of last 16-byte block (0 || len(IV)64) + vmovdqu %%XTMP0, [%%KEY + HashKey] + mov %%TMP2, %%IV_GEN_LEN + shl %%TMP2, 3 ;; IV length in bits + vmovq %%XTMP1, %%TMP2 + vpxor %%J0, %%XTMP1 + GHASH_MUL %%J0, %%XTMP0, %%XTMP1, %%XTMP2, %%XTMP3, %%XTMP4, %%XTMP5 + + vpshufb %%J0, [rel SHUF_MASK] ; perform a 16Byte swap +%endmacro + +%macro GCM_ENC_DEC_SMALL 12 +%define %%GDATA_KEY %1 +%define %%GDATA_CTX %2 +%define %%CYPH_PLAIN_OUT %3 +%define %%PLAIN_CYPH_IN %4 +%define %%PLAIN_CYPH_LEN %5 +%define %%ENC_DEC %6 +%define %%DATA_OFFSET %7 +%define %%LENGTH %8 ; assumed r13 +%define %%NUM_BLOCKS %9 +%define %%CTR %10 ; assumed xmm9 +%define %%HASH_OUT %11 ; assumed xmm14 +%define %%INSTANCE_TYPE %12 + + ;; NOTE: the check below is obsolete in current implementation. The check is already done in GCM_ENC_DEC. + ;; cmp %%NUM_BLOCKS, 0 + ;; je %%_small_initial_blocks_encrypted + cmp %%NUM_BLOCKS, 8 + je %%_small_initial_num_blocks_is_8 + cmp %%NUM_BLOCKS, 7 + je %%_small_initial_num_blocks_is_7 + cmp %%NUM_BLOCKS, 6 + je %%_small_initial_num_blocks_is_6 + cmp %%NUM_BLOCKS, 5 + je %%_small_initial_num_blocks_is_5 + cmp %%NUM_BLOCKS, 4 + je %%_small_initial_num_blocks_is_4 + cmp %%NUM_BLOCKS, 3 + je %%_small_initial_num_blocks_is_3 + cmp %%NUM_BLOCKS, 2 + je %%_small_initial_num_blocks_is_2 + + jmp %%_small_initial_num_blocks_is_1 + + +%%_small_initial_num_blocks_is_8: + ;; r13 - %%LENGTH + ;; xmm12 - T1 + ;; xmm13 - T2 + ;; xmm14 - T3 - AAD HASH OUT when not producing 8 AES keys + ;; xmm15 - T4 + ;; xmm11 - T5 + ;; xmm9 - CTR + ;; xmm1 - XMM1 - Cipher + Hash when producing 8 AES keys + ;; xmm2 - XMM2 + ;; xmm3 - XMM3 + ;; xmm4 - XMM4 + ;; xmm5 - XMM5 + ;; xmm6 - XMM6 + ;; xmm7 - XMM7 + ;; xmm8 - XMM8 - AAD HASH IN + ;; xmm10 - T6 + ;; xmm0 - T_key + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 8, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE + jmp %%_small_initial_blocks_encrypted + +%%_small_initial_num_blocks_is_7: + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 7, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE + jmp %%_small_initial_blocks_encrypted + +%%_small_initial_num_blocks_is_6: + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 6, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE + jmp %%_small_initial_blocks_encrypted + +%%_small_initial_num_blocks_is_5: + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 5, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE + jmp %%_small_initial_blocks_encrypted + +%%_small_initial_num_blocks_is_4: + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 4, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE + jmp %%_small_initial_blocks_encrypted + +%%_small_initial_num_blocks_is_3: + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 3, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE + jmp %%_small_initial_blocks_encrypted + +%%_small_initial_num_blocks_is_2: + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 2, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE + jmp %%_small_initial_blocks_encrypted + +%%_small_initial_num_blocks_is_1: + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, \ + %%PLAIN_CYPH_IN, %%LENGTH, %%DATA_OFFSET, 1, \ + xmm12, xmm13, %%HASH_OUT, xmm15, xmm11, %%CTR, \ + xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, \ + xmm10, xmm0, %%ENC_DEC, %%INSTANCE_TYPE +%%_small_initial_blocks_encrypted: + +%endmacro ; GCM_ENC_DEC_SMALL + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; GCM_ENC_DEC Encodes/Decodes given data. Assumes that the passed gcm_context_data struct +; has been initialized by GCM_INIT +; Requires the input data be at least 1 byte long because of READ_SMALL_INPUT_DATA. +; Input: gcm_key_data struct* (GDATA_KEY), gcm_context_data *(GDATA_CTX), input text (PLAIN_CYPH_IN), +; input text length (PLAIN_CYPH_LEN) and whether encoding or decoding (ENC_DEC). +; Output: A cypher of the given plain text (CYPH_PLAIN_OUT), and updated GDATA_CTX +; Clobbers rax, r10-r15, and xmm0-xmm15 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GCM_ENC_DEC 7 +%define %%GDATA_KEY %1 +%define %%GDATA_CTX %2 +%define %%CYPH_PLAIN_OUT %3 +%define %%PLAIN_CYPH_IN %4 +%define %%PLAIN_CYPH_LEN %5 +%define %%ENC_DEC %6 +%define %%INSTANCE_TYPE %7 +%define %%DATA_OFFSET r11 + +; Macro flow: +; calculate the number of 16byte blocks in the message +; process (number of 16byte blocks) mod 8 '%%_initial_num_blocks_is_# .. %%_initial_blocks_encrypted' +; process 8 16 byte blocks at a time until all are done '%%_encrypt_by_8_new .. %%_eight_cipher_left' +; if there is a block of less tahn 16 bytes process it '%%_zero_cipher_left .. %%_multiple_of_16_bytes' + +%ifidn __OUTPUT_FORMAT__, win64 + cmp %%PLAIN_CYPH_LEN, 0 +%else + or %%PLAIN_CYPH_LEN, %%PLAIN_CYPH_LEN +%endif + je %%_enc_dec_done + + xor %%DATA_OFFSET, %%DATA_OFFSET + ;; Update length of data processed +%ifidn __OUTPUT_FORMAT__, win64 + mov rax, %%PLAIN_CYPH_LEN + add [%%GDATA_CTX + InLen], rax +%else + add [%%GDATA_CTX + InLen], %%PLAIN_CYPH_LEN +%endif + vmovdqu xmm13, [%%GDATA_KEY + HashKey] + vmovdqu xmm8, [%%GDATA_CTX + AadHash] + +%ifidn %%INSTANCE_TYPE, multi_call + ;; NOTE: partial block processing makes only sense for multi_call here. + ;; Used for the update flow - if there was a previous partial + ;; block fill the remaining bytes here. + PARTIAL_BLOCK %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, %%PLAIN_CYPH_LEN, %%DATA_OFFSET, xmm8, %%ENC_DEC +%endif + + ;; lift CTR set from initial_blocks to here +%ifidn %%INSTANCE_TYPE, single_call + vmovdqu xmm9, xmm2 +%else + vmovdqu xmm9, [%%GDATA_CTX + CurCount] +%endif + + ;; Save the amount of data left to process in r10 + mov r13, %%PLAIN_CYPH_LEN +%ifidn %%INSTANCE_TYPE, multi_call + ;; NOTE: %%DATA_OFFSET is zero in single_call case. + ;; Consequently PLAIN_CYPH_LEN will never be zero after + ;; %%DATA_OFFSET subtraction below. + sub r13, %%DATA_OFFSET + + ;; There may be no more data if it was consumed in the partial block. + cmp r13, 0 + je %%_enc_dec_done +%endif ; %%INSTANCE_TYPE, multi_call + mov r10, r13 + + ;; Determine how many blocks to process in INITIAL + mov r12, r13 + shr r12, 4 + and r12, 7 + + ;; Process one additional block in INITIAL if there is a partial block + and r10, 0xf + blsmsk r10, r10 ; Set CF if zero + cmc ; Flip CF + adc r12, 0x0 ; Process an additional INITIAL block if CF set + + ;; Less than 127B will be handled by the small message code, which + ;; can process up to 7 16B blocks. + cmp r13, 128 + jge %%_large_message_path + + GCM_ENC_DEC_SMALL %%GDATA_KEY, %%GDATA_CTX, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, %%PLAIN_CYPH_LEN, %%ENC_DEC, %%DATA_OFFSET, r13, r12, xmm9, xmm14, %%INSTANCE_TYPE + jmp %%_ghash_done + +%%_large_message_path: + and r12, 0x7 ; Still, don't allow 8 INITIAL blocks since this will + ; can be handled by the x8 partial loop. + + cmp r12, 0 + je %%_initial_num_blocks_is_0 + cmp r12, 7 + je %%_initial_num_blocks_is_7 + cmp r12, 6 + je %%_initial_num_blocks_is_6 + cmp r12, 5 + je %%_initial_num_blocks_is_5 + cmp r12, 4 + je %%_initial_num_blocks_is_4 + cmp r12, 3 + je %%_initial_num_blocks_is_3 + cmp r12, 2 + je %%_initial_num_blocks_is_2 + + jmp %%_initial_num_blocks_is_1 + +%%_initial_num_blocks_is_7: + ;; r13 - %%LENGTH + ;; xmm12 - T1 + ;; xmm13 - T2 + ;; xmm14 - T3 - AAD HASH OUT when not producing 8 AES keys + ;; xmm15 - T4 + ;; xmm11 - T5 + ;; xmm9 - CTR + ;; xmm1 - XMM1 - Cipher + Hash when producing 8 AES keys + ;; xmm2 - XMM2 + ;; xmm3 - XMM3 + ;; xmm4 - XMM4 + ;; xmm5 - XMM5 + ;; xmm6 - XMM6 + ;; xmm7 - XMM7 + ;; xmm8 - XMM8 - AAD HASH IN + ;; xmm10 - T6 + ;; xmm0 - T_key + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 7, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + jmp %%_initial_blocks_encrypted + +%%_initial_num_blocks_is_6: + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 6, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + jmp %%_initial_blocks_encrypted + +%%_initial_num_blocks_is_5: + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 5, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + jmp %%_initial_blocks_encrypted + +%%_initial_num_blocks_is_4: + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 4, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + jmp %%_initial_blocks_encrypted + +%%_initial_num_blocks_is_3: + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 3, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + jmp %%_initial_blocks_encrypted + +%%_initial_num_blocks_is_2: + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 2, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + jmp %%_initial_blocks_encrypted + +%%_initial_num_blocks_is_1: + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 1, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + jmp %%_initial_blocks_encrypted + +%%_initial_num_blocks_is_0: + INITIAL_BLOCKS %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, r13, %%DATA_OFFSET, 0, xmm12, xmm13, xmm14, xmm15, xmm11, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm10, xmm0, %%ENC_DEC + + +%%_initial_blocks_encrypted: + ;; The entire message was encrypted processed in initial and now need to be hashed + cmp r13, 0 + je %%_encrypt_done + + ;; Encrypt the final <16 byte (partial) block, then hash + cmp r13, 16 + jl %%_encrypt_final_partial + + ;; Process 7 full blocks plus a partial block + cmp r13, 128 + jl %%_encrypt_by_8_partial + + +%%_encrypt_by_8_parallel: + ;; in_order vs. out_order is an optimization to increment the counter without shuffling + ;; it back into little endian. r15d keeps track of when we need to increent in order so + ;; that the carry is handled correctly. + vmovd r15d, xmm9 + and r15d, 255 + vpshufb xmm9, [rel SHUF_MASK] + + +%%_encrypt_by_8_new: + cmp r15d, 255-8 + jg %%_encrypt_by_8 + + + + ;; xmm0 - T1 + ;; xmm10 - T2 + ;; xmm11 - T3 + ;; xmm12 - T4 + ;; xmm13 - T5 + ;; xmm14 - T6 + ;; xmm9 - CTR + ;; xmm1 - XMM1 + ;; xmm2 - XMM2 + ;; xmm3 - XMM3 + ;; xmm4 - XMM4 + ;; xmm5 - XMM5 + ;; xmm6 - XMM6 + ;; xmm7 - XMM7 + ;; xmm8 - XMM8 + ;; xmm15 - T7 + add r15b, 8 + GHASH_8_ENCRYPT_8_PARALLEL %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, %%DATA_OFFSET, xmm0, xmm10, xmm11, xmm12, xmm13, xmm14, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm15, out_order, %%ENC_DEC, full + add %%DATA_OFFSET, 128 + sub r13, 128 + cmp r13, 128 + jge %%_encrypt_by_8_new + + vpshufb xmm9, [rel SHUF_MASK] + jmp %%_encrypt_by_8_parallel_done + +%%_encrypt_by_8: + vpshufb xmm9, [rel SHUF_MASK] + add r15b, 8 + GHASH_8_ENCRYPT_8_PARALLEL %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, %%DATA_OFFSET, xmm0, xmm10, xmm11, xmm12, xmm13, xmm14, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm15, in_order, %%ENC_DEC, full + vpshufb xmm9, [rel SHUF_MASK] + add %%DATA_OFFSET, 128 + sub r13, 128 + cmp r13, 128 + jge %%_encrypt_by_8_new + vpshufb xmm9, [rel SHUF_MASK] + + +%%_encrypt_by_8_parallel_done: + ;; Test to see if we need a by 8 with partial block. At this point + ;; bytes remaining should be either zero or between 113-127. + cmp r13, 0 + je %%_encrypt_done + +%%_encrypt_by_8_partial: + ;; Shuffle needed to align key for partial block xor. out_order + ;; is a little faster because it avoids extra shuffles. + ;; TBD: Might need to account for when we don't have room to increment the counter. + + + ;; Process parallel buffers with a final partial block. + GHASH_8_ENCRYPT_8_PARALLEL %%GDATA_KEY, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, %%DATA_OFFSET, xmm0, xmm10, xmm11, xmm12, xmm13, xmm14, xmm9, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm15, in_order, %%ENC_DEC, partial + + + add %%DATA_OFFSET, 128-16 + sub r13, 128-16 + +%%_encrypt_final_partial: + + vpshufb xmm8, [rel SHUF_MASK] + mov [%%GDATA_CTX + PBlockLen], r13 + vmovdqu [%%GDATA_CTX + PBlockEncKey], xmm8 + + ;; xmm8 - Final encrypted counter - need to hash with partial or full block ciphertext + ;; GDATA, KEY, T1, T2 + ENCRYPT_FINAL_PARTIAL_BLOCK xmm8, xmm0, %%CYPH_PLAIN_OUT, %%PLAIN_CYPH_IN, %%PLAIN_CYPH_LEN, %%ENC_DEC, %%DATA_OFFSET + + vpshufb xmm8, [rel SHUF_MASK] + + +%%_encrypt_done: + + ;; Mapping to macro parameters + ;; IN: + ;; xmm9 contains the counter + ;; xmm1-xmm8 contain the xor'd ciphertext + ;; OUT: + ;; xmm14 contains the final hash + ;; GDATA, T1, T2, T3, T4, T5, T6, T7, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8 +%ifidn %%INSTANCE_TYPE, multi_call + mov r13, [%%GDATA_CTX + PBlockLen] + cmp r13, 0 + jz %%_hash_last_8 + GHASH_LAST_7 %%GDATA_KEY, xmm0, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + ;; XOR the partial word into the hash + vpxor xmm14, xmm14, xmm8 + jmp %%_ghash_done +%endif +%%_hash_last_8: + GHASH_LAST_8 %%GDATA_KEY, xmm0, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8 + +%%_ghash_done: + vmovdqu [%%GDATA_CTX + CurCount], xmm9 ; my_ctx_data.current_counter = xmm9 + vmovdqu [%%GDATA_CTX + AadHash], xmm14 ; my_ctx_data.aad hash = xmm14 + +%%_enc_dec_done: + + +%endmacro ; GCM_ENC_DEC + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; GCM_COMPLETE Finishes Encryption/Decryption of last partial block after GCM_UPDATE finishes. +; Input: A gcm_key_data * (GDATA_KEY), gcm_context_data (GDATA_CTX) and whether encoding or decoding (ENC_DEC). +; Output: Authorization Tag (AUTH_TAG) and Authorization Tag length (AUTH_TAG_LEN) +; Clobbers rax, r10-r12, and xmm0-xmm2, xmm5-xmm6, xmm9-xmm11, xmm13-xmm15 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GCM_COMPLETE 6 +%define %%GDATA_KEY %1 +%define %%GDATA_CTX %2 +%define %%AUTH_TAG %3 +%define %%AUTH_TAG_LEN %4 +%define %%ENC_DEC %5 +%define %%INSTANCE_TYPE %6 +%define %%PLAIN_CYPH_LEN rax + + vmovdqu xmm13, [%%GDATA_KEY + HashKey] + ;; Start AES as early as possible + vmovdqu xmm9, [%%GDATA_CTX + OrigIV] ; xmm9 = Y0 + ENCRYPT_SINGLE_BLOCK %%GDATA_KEY, xmm9 ; E(K, Y0) + +%ifidn %%INSTANCE_TYPE, multi_call + ;; If the GCM function is called as a single function call rather + ;; than invoking the individual parts (init, update, finalize) we + ;; can remove a write to read dependency on AadHash. + vmovdqu xmm14, [%%GDATA_CTX + AadHash] + + ;; Encrypt the final partial block. If we did this as a single call then + ;; the partial block was handled in the main GCM_ENC_DEC macro. + mov r12, [%%GDATA_CTX + PBlockLen] + cmp r12, 0 + + je %%_partial_done + + GHASH_MUL xmm14, xmm13, xmm0, xmm10, xmm11, xmm5, xmm6 ;GHASH computation for the last <16 Byte block + vmovdqu [%%GDATA_CTX + AadHash], xmm14 + +%%_partial_done: + +%endif + + mov r12, [%%GDATA_CTX + AadLen] ; r12 = aadLen (number of bytes) + mov %%PLAIN_CYPH_LEN, [%%GDATA_CTX + InLen] + + shl r12, 3 ; convert into number of bits + vmovd xmm15, r12d ; len(A) in xmm15 + + shl %%PLAIN_CYPH_LEN, 3 ; len(C) in bits (*128) + vmovq xmm1, %%PLAIN_CYPH_LEN + vpslldq xmm15, xmm15, 8 ; xmm15 = len(A)|| 0x0000000000000000 + vpxor xmm15, xmm15, xmm1 ; xmm15 = len(A)||len(C) + + vpxor xmm14, xmm15 + GHASH_MUL xmm14, xmm13, xmm0, xmm10, xmm11, xmm5, xmm6 + vpshufb xmm14, [rel SHUF_MASK] ; perform a 16Byte swap + + vpxor xmm9, xmm9, xmm14 + + +%%_return_T: + mov r10, %%AUTH_TAG ; r10 = authTag + mov r11, %%AUTH_TAG_LEN ; r11 = auth_tag_len + + cmp r11, 16 + je %%_T_16 + + cmp r11, 12 + je %%_T_12 + + cmp r11, 8 + je %%_T_8 + + simd_store_avx r10, xmm9, r11, r12, rax + jmp %%_return_T_done +%%_T_8: + vmovq rax, xmm9 + mov [r10], rax + jmp %%_return_T_done +%%_T_12: + vmovq rax, xmm9 + mov [r10], rax + vpsrldq xmm9, xmm9, 8 + vmovd eax, xmm9 + mov [r10 + 8], eax + jmp %%_return_T_done +%%_T_16: + vmovdqu [r10], xmm9 + +%%_return_T_done: + +;; IPPCP: disabled clearing of context fields, as in IPPCP case GetTag may be called +;; several times and it should not stop GCM processing. Context zeroing is done by user. +;; https://www.intel.com/content/www/us/en/docs/ipp-crypto/developer-reference/current/aes-gcm-functions.html +;; %ifdef SAFE_DATA +;; ;; Clear sensitive data from context structure +;; vpxor xmm0, xmm0 +;; vmovdqu [%%GDATA_CTX + AadHash], xmm0 +;; vmovdqu [%%GDATA_CTX + PBlockEncKey], xmm0 +;; %endif +%endmacro ; GCM_COMPLETE + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; GCM_UPDATE_AAD_HASH update AadHash value in gcm_context_data struct to prepare for encoding/decoding. +;;; Input: gcm_key_data * (GDATA_KEY), gcm_context_data *(GDATA_CTX), +;;; Additional Authentication data (A_IN), Additional Data length (A_LEN). +;;; Output: Updated GDATA_CTX with the hash of A_IN (AadHash). +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GCM_UPDATE_AAD_HASH 7 +%define %%GDATA_KEY %1 ; [in] GCM expanded keys pointer +%define %%GDATA_CTX %2 ; [in] GCM context pointer +%define %%A_IN %3 ; [in] AAD pointer +%define %%A_LEN %4 ; [in] AAD length in bytes +%define %%GPR1 %5 ; temp GPR +%define %%GPR2 %6 ; temp GPR +%define %%GPR3 %7 ; temp GPR + +%define %%AAD_HASH xmm14 + + vmovdqu64 %%AAD_HASH, [%%GDATA_CTX + AadHash] ; load current hash + + UPDATE_HASH %%A_IN, %%A_LEN, %%AAD_HASH, %%GDATA_KEY, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, %%GPR1, %%GPR2, %%GPR3 + + vmovdqu64 [%%GDATA_CTX + AadHash], %%AAD_HASH ; store updated hash + +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; GCM_UPDATE_IV_HASH update orig_IV value in gcm_context_data struct to prepare for encoding/decoding. +;;; Input: gcm_key_data * (GDATA_KEY), gcm_context_data *(GDATA_CTX), +;;; Initialization Vector (IV), Initialization Vector length (IV_LEN). +;;; Output: Updated GDATA_CTX with the hash of A_IN (orig_IV). +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GCM_UPDATE_IV_HASH 7 +%define %%GDATA_KEY %1 ; [in] GCM expanded keys pointer +%define %%GDATA_CTX %2 ; [in] GCM context pointer +%define %%IV %3 ; [in] AAD pointer +%define %%IV_LEN %4 ; [in] AAD length in bytes +%define %%GPR1 %5 ; temp GPR +%define %%GPR2 %6 ; temp GPR +%define %%GPR3 %7 ; temp GPR + +%define %%IV_HASH xmm14 + + vmovdqu64 %%IV_HASH, [%%GDATA_CTX + OrigIV] ; load current hash + + UPDATE_HASH %%IV, %%IV_LEN, %%IV_HASH, %%GDATA_KEY, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, %%GPR1, %%GPR2, %%GPR3 + + vmovdqu64 [%%GDATA_CTX + OrigIV], %%IV_HASH ; store updated hash + +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; GCM_FINALIZE_IV_HASH finalize updating of AadHash value in gcm_context_data struct +;;; to prepare for encoding/decoding. +;;; Input: gcm_key_data * (GDATA_KEY), gcm_context_data *(GDATA_CTX), +;;; Initialization Vector (IV), Initialization Vector length (IV_LEN). +;;; Output: Updated GDATA_CTX with the hash of A_IN (orig_IV). and initialized other parts of GDATA_CTX. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GCM_FINALIZE_IV_HASH 7-8 +%define %%GDATA_KEY %1 ; [in] GCM expanded keys pointer +%define %%GDATA_CTX %2 ; [in] GCM context pointer +%define %%IV %3 ; [in] IV pointer +%define %%IV_LEN %4 ; [in] IV length in bytes +%define %%GPR1 %5 ; temp GPR +%define %%GPR2 %6 ; temp GPR +%define %%GPR3 %7 ; temp GPR +%define %%IV_GEN_LEN %8 ; [in] IV general length in bytes + + +%if %0 == 7 ;; IV is 12 bytes + + ;; read 12 IV bytes and pad with 0x00000001 + mov %%GPR2, %%IV + vmovd xmm3, [%%GPR2 + 8] + vpslldq xmm3, 8 + vmovq xmm2, [%%GPR2] + vmovdqa xmm4, [rel ONEf] + vpternlogq xmm2, xmm3, xmm4, 0xfe ; xmm2 = xmm2 or xmm3 or xmm4 + +%else ;; IV is not 12 bytes + + vmovdqu xmm2, [%%GDATA_CTX + OrigIV] + + CALC_J0 %%GDATA_KEY, %%IV, %%IV_LEN, xmm2, r10, r11, r12, xmm0, xmm1, \ + xmm3, xmm4, xmm5, xmm6, %%IV_GEN_LEN + +%endif + vmovdqu [%%GDATA_CTX + OrigIV], xmm2 ; ctx_data.orig_IV = iv + + ;; store IV as counter in LE format + vpshufb xmm2, [rel SHUF_MASK] + vmovdqu [%%GDATA_CTX + CurCount], xmm2 ; ctx_data.current_counter = iv + + +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_precomp_128_avx512 / +; aes_gcm_precomp_192_avx512 / +; aes_gcm_precomp_256_avx512 +; (struct gcm_key_data *key_data) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(precomp,_), PUBLIC +;; Parameter is passed through register +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz exit_precomp +%endif + + push r12 + push r13 + push r14 + push r15 + + mov r14, rsp + + + + sub rsp, VARIABLE_OFFSET + and rsp, ~63 ; align rsp to 64 bytes + +%ifidn __OUTPUT_FORMAT__, win64 + ; only xmm6 needs to be maintained + vmovdqu [rsp + LOCAL_STORAGE + 0*16],xmm6 +%endif + + vpxor xmm6, xmm6 + ENCRYPT_SINGLE_BLOCK arg1, xmm6 ; xmm6 = HashKey + + vpshufb xmm6, [rel SHUF_MASK] + ;;;;;;;;;;;;;;; PRECOMPUTATION of HashKey<<1 mod poly from the HashKey;;;;;;;;;;;;;;; + vmovdqa xmm2, xmm6 + vpsllq xmm6, xmm6, 1 + vpsrlq xmm2, xmm2, 63 + vmovdqa xmm1, xmm2 + vpslldq xmm2, xmm2, 8 + vpsrldq xmm1, xmm1, 8 + vpor xmm6, xmm6, xmm2 + ;reduction + vpshufd xmm2, xmm1, 00100100b + vpcmpeqd xmm2, [rel TWOONE] + vpand xmm2, xmm2, [rel POLY] + vpxor xmm6, xmm6, xmm2 ; xmm6 holds the HashKey<<1 mod poly + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + vmovdqu [arg1 + HashKey], xmm6 ; store HashKey<<1 mod poly + + + PRECOMPUTE arg1, xmm6, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5 + +%ifdef SAFE_DATA + clear_scratch_gps_asm + clear_scratch_zmms_asm +%endif +%ifidn __OUTPUT_FORMAT__, win64 + vmovdqu xmm6, [rsp + LOCAL_STORAGE + 0*16] +%endif + mov rsp, r14 + + pop r15 + pop r14 + pop r13 + pop r12 + +.exit_precomp: + ret + +ENDFUNC FN_NAME(precomp,_) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_enc_128_update_avx512 / aes_gcm_enc_192_update_avx512 / +; aes_gcm_enc_256_update_avx512 +; (const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; u8 *out, +; const u8 *in, +; u64 plaintext_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(enc,_update_), PUBLIC + + FUNC_SAVE + +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz exit_update_enc + + ;; Check context_data != NULL + cmp arg2, 0 + jz exit_update_enc + + ;; Check if plaintext_len == 0 + cmp arg5, 0 + jz skip_in_out_check_update_enc + + ;; Check out != NULL (plaintext_len != 0) + cmp arg3, 0 + jz exit_update_enc + + ;; Check in != NULL (plaintext_len != 0) + cmp arg4, 0 + jz exit_update_enc + +.skip_in_out_check_update_enc: +%endif + GCM_ENC_DEC arg1, arg2, arg3, arg4, arg5, ENC, multi_call + +.exit_update_enc: + FUNC_RESTORE + + ret + +ENDFUNC FN_NAME(enc,_update_) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_dec_128_update_avx512 / aes_gcm_dec_192_update_avx512 / +; aes_gcm_dec_256_update_avx512 +; (const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; u8 *out, +; const u8 *in, +; u64 plaintext_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(dec,_update_), PUBLIC + + FUNC_SAVE + +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz exit_update_dec + + ;; Check context_data != NULL + cmp arg2, 0 + jz exit_update_dec + + ;; Check if plaintext_len == 0 + cmp arg5, 0 + jz skip_in_out_check_update_dec + + ;; Check out != NULL (plaintext_len != 0) + cmp arg3, 0 + jz exit_update_dec + + ;; Check in != NULL (plaintext_len != 0) + cmp arg4, 0 + jz exit_update_dec + +skip_in_out_check_update_dec: +%endif + + GCM_ENC_DEC arg1, arg2, arg3, arg4, arg5, DEC, multi_call + +.exit_update_dec: + FUNC_RESTORE + ret + +ENDFUNC FN_NAME(dec,_update_) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_gettag_128_avx512 / aes_gcm_gettag_192_avx512 / +; aes_gcm_gettag_256_avx512 +; (const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; u8 *auth_tag, +; u64 auth_tag_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM FN_NAME(gettag,_), PUBLIC + + FUNC_SAVE + +;; All parameters are passed through registers +%ifdef SAFE_PARAM + ;; Check key_data != NULL + cmp arg1, 0 + jz exit_enc_fin + + ;; Check context_data != NULL + cmp arg2, 0 + jz exit_enc_fin + + ;; Check auth_tag != NULL + cmp arg3, 0 + jz exit_enc_fin + + ;; Check auth_tag_len == 0 or > 16 + cmp arg4, 0 + jz exit_enc_fin + + cmp arg4, 16 + ja exit_enc_fin +%endif + + GCM_COMPLETE arg1, arg2, arg3, arg4, ENC, multi_call + +.exit_enc_fin: + FUNC_RESTORE + ret + +ENDFUNC FN_NAME(gettag,_) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; IV and AAD in disconnected buffers processing +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%ifdef GCM128_MODE + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_aad_hash_update_avx512( +; const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; const u8 *aad, +; const u64 aad_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_aad_hash_update_avx512, PUBLIC + + FUNC_SAVE + + GCM_UPDATE_AAD_HASH arg1, arg2, arg3, arg4, r10, r11, r12 + + FUNC_RESTORE + + ret +ENDFUNC aes_gcm_aad_hash_update_avx512 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_iv_hash_update_avx512( +; const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; const u8 *iv, +; const u64 iv_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_iv_hash_update_avx512, PUBLIC + + FUNC_SAVE + + GCM_UPDATE_IV_HASH arg1, arg2, arg3, arg4, r10, r11, r12 + + FUNC_RESTORE + + ret +ENDFUNC aes_gcm_iv_hash_update_avx512 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_iv_hash_finalize_avx512( +; const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; const u8 *iv, +; const u64 iv_len, +; const u64 iv_general_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_iv_hash_finalize_avx512, PUBLIC + + FUNC_SAVE + + cmp arg5, 12 + je .iv_eq_12 + + GCM_FINALIZE_IV_HASH arg1, arg2, arg3, arg4, r10, r11, r12, arg5 + jmp .skip_iv_eq_12 + +.iv_eq_12: + + GCM_FINALIZE_IV_HASH arg1, arg2, arg3, arg4, r10, r11, r12 +.skip_iv_eq_12: + + FUNC_RESTORE + + ret +ENDFUNC aes_gcm_iv_hash_finalize_avx512 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_gmult_avx512( +; const struct gcm_key_data *key_data, +; u8 *ghash) +; +; Function updates |ghash| value by multiplying it on H^1 key. +; Leaf function. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_gmult_avx512, PUBLIC + + vmovdqu64 xmm1, [arg2] + vmovdqu64 xmm2, [arg1 + HashKey_1] + + GHASH_MUL xmm1, xmm2, xmm3, xmm4, xmm5, xmm16, xmm17 + + vmovdqu64 [arg2], xmm1 + + ret +ENDFUNC aes_gcm_gmult_avx512 + + +%endif + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_defines.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_defines.inc new file mode 100644 index 000000000..63392711a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_defines.inc @@ -0,0 +1,264 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef GCM_DEFINES_ASM_INCLUDED +%define GCM_DEFINES_ASM_INCLUDED + +; +; Authors: +; Erdinc Ozturk +; Vinodh Gopal +; James Guilford + +section .data +default rel + +align 16 +POLY: dq 0x0000000000000001, 0xC200000000000000 + +align 64 +POLY2: + dq 0x00000001C2000000, 0xC200000000000000 + dq 0x00000001C2000000, 0xC200000000000000 + dq 0x00000001C2000000, 0xC200000000000000 + dq 0x00000001C2000000, 0xC200000000000000 + +align 16 +TWOONE: dq 0x0000000000000001, 0x0000000100000000 + +;;; @note Order of these constants should not change. +;;; More specifically, ALL_F should follow SHIFT_MASK, and ZERO should follow ALL_F +align 64 +SHUF_MASK: + dq 0x08090A0B0C0D0E0F, 0x0001020304050607 + dq 0x08090A0B0C0D0E0F, 0x0001020304050607 + dq 0x08090A0B0C0D0E0F, 0x0001020304050607 + dq 0x08090A0B0C0D0E0F, 0x0001020304050607 + +align 16 +SHIFT_MASK: + dq 0x0706050403020100, 0x0f0e0d0c0b0a0908 + +ALL_F: + dq 0xffffffffffffffff, 0xffffffffffffffff + +ZERO: + dq 0x0000000000000000, 0x0000000000000000 + +align 16 +ONE: + dq 0x0000000000000001, 0x0000000000000000 + +align 16 +TWO: + dq 0x0000000000000002, 0x0000000000000000 + +align 16 +ONEf: + dq 0x0000000000000000, 0x0100000000000000 + +align 16 +TWOf: + dq 0x0000000000000000, 0x0200000000000000 + +align 64 +ddq_add_1234: + dq 0x0000000000000001, 0x0000000000000000 + dq 0x0000000000000002, 0x0000000000000000 + dq 0x0000000000000003, 0x0000000000000000 + dq 0x0000000000000004, 0x0000000000000000 + +align 64 +ddq_add_5678: + dq 0x0000000000000005, 0x0000000000000000 + dq 0x0000000000000006, 0x0000000000000000 + dq 0x0000000000000007, 0x0000000000000000 + dq 0x0000000000000008, 0x0000000000000000 + +align 64 +ddq_add_4444: + dq 0x0000000000000004, 0x0000000000000000 + dq 0x0000000000000004, 0x0000000000000000 + dq 0x0000000000000004, 0x0000000000000000 + dq 0x0000000000000004, 0x0000000000000000 + +align 64 +ddq_add_8888: + dq 0x0000000000000008, 0x0000000000000000 + dq 0x0000000000000008, 0x0000000000000000 + dq 0x0000000000000008, 0x0000000000000000 + dq 0x0000000000000008, 0x0000000000000000 + +align 64 +ddq_addbe_1234: + dq 0x0000000000000000, 0x0100000000000000 + dq 0x0000000000000000, 0x0200000000000000 + dq 0x0000000000000000, 0x0300000000000000 + dq 0x0000000000000000, 0x0400000000000000 + +align 64 +ddq_addbe_5678: + dq 0x0000000000000000, 0x0500000000000000 + dq 0x0000000000000000, 0x0600000000000000 + dq 0x0000000000000000, 0x0700000000000000 + dq 0x0000000000000000, 0x0800000000000000 + +align 64 +ddq_addbe_4444: + dq 0x0000000000000000, 0x0400000000000000 + dq 0x0000000000000000, 0x0400000000000000 + dq 0x0000000000000000, 0x0400000000000000 + dq 0x0000000000000000, 0x0400000000000000 + +align 64 +ddq_addbe_8888: + dq 0x0000000000000000, 0x0800000000000000 + dq 0x0000000000000000, 0x0800000000000000 + dq 0x0000000000000000, 0x0800000000000000 + dq 0x0000000000000000, 0x0800000000000000 + +align 64 +byte_len_to_mask_table: + dw 0x0000, 0x0001, 0x0003, 0x0007, + dw 0x000f, 0x001f, 0x003f, 0x007f, + dw 0x00ff, 0x01ff, 0x03ff, 0x07ff, + dw 0x0fff, 0x1fff, 0x3fff, 0x7fff, + dw 0xffff + +align 64 +byte64_len_to_mask_table: + dq 0x0000000000000000, 0x0000000000000001 + dq 0x0000000000000003, 0x0000000000000007 + dq 0x000000000000000f, 0x000000000000001f + dq 0x000000000000003f, 0x000000000000007f + dq 0x00000000000000ff, 0x00000000000001ff + dq 0x00000000000003ff, 0x00000000000007ff + dq 0x0000000000000fff, 0x0000000000001fff + dq 0x0000000000003fff, 0x0000000000007fff + dq 0x000000000000ffff, 0x000000000001ffff + dq 0x000000000003ffff, 0x000000000007ffff + dq 0x00000000000fffff, 0x00000000001fffff + dq 0x00000000003fffff, 0x00000000007fffff + dq 0x0000000000ffffff, 0x0000000001ffffff + dq 0x0000000003ffffff, 0x0000000007ffffff + dq 0x000000000fffffff, 0x000000001fffffff + dq 0x000000003fffffff, 0x000000007fffffff + dq 0x00000000ffffffff, 0x00000001ffffffff + dq 0x00000003ffffffff, 0x00000007ffffffff + dq 0x0000000fffffffff, 0x0000001fffffffff + dq 0x0000003fffffffff, 0x0000007fffffffff + dq 0x000000ffffffffff, 0x000001ffffffffff + dq 0x000003ffffffffff, 0x000007ffffffffff + dq 0x00000fffffffffff, 0x00001fffffffffff + dq 0x00003fffffffffff, 0x00007fffffffffff + dq 0x0000ffffffffffff, 0x0001ffffffffffff + dq 0x0003ffffffffffff, 0x0007ffffffffffff + dq 0x000fffffffffffff, 0x001fffffffffffff + dq 0x003fffffffffffff, 0x007fffffffffffff + dq 0x00ffffffffffffff, 0x01ffffffffffffff + dq 0x03ffffffffffffff, 0x07ffffffffffffff + dq 0x0fffffffffffffff, 0x1fffffffffffffff + dq 0x3fffffffffffffff, 0x7fffffffffffffff + dq 0xffffffffffffffff + +align 64 +mask_out_top_block: + dq 0xffffffffffffffff, 0xffffffffffffffff + dq 0xffffffffffffffff, 0xffffffffffffffff + dq 0xffffffffffffffff, 0xffffffffffffffff + dq 0x0000000000000000, 0x0000000000000000 + +section .text + +;;define the fields of gcm_context_data struct +;; struct gcm_context_data { +;; // init, update and finalize context data +;; uint8_t aad_hash[GCM_BLOCK_LEN]; +;; uint64_t aad_length; +;; uint64_t in_length; +;; uint8_t partial_block_enc_key[GCM_BLOCK_LEN]; +;; uint8_t orig_IV[GCM_BLOCK_LEN]; +;; uint8_t current_counter[GCM_BLOCK_LEN]; +;; uint64_t partial_block_length; +;; }; + +%define AadHash (16*0) ; store current Hash of data which has been input +%define AadLen (16*1) ; store length of input data which will not be encrypted or decrypted +%define InLen ((16*1)+8); store length of input data which will be encrypted or decrypted +%define PBlockEncKey (16*2) ; encryption key for the partial block at the end of the previous update +%define OrigIV (16*3) ; input IV +%define CurCount (16*4) ; Current counter for generation of encryption key +%define PBlockLen (16*5) ; length of partial block at the end of the previous update + +%define reg(q) xmm %+ q +%define regy(q) ymm %+ q +%define regz(q) zmm %+ q + +%ifdef WIN_ABI + %xdefine arg1 rcx + %xdefine arg2 rdx + %xdefine arg3 r8 + %xdefine arg4 r9 + %xdefine arg5 qword [r14 + STACK_OFFSET + 8*5] + %xdefine arg6 qword [r14 + STACK_OFFSET + 8*6] + %xdefine arg7 qword [r14 + STACK_OFFSET + 8*7] + %xdefine arg8 qword [r14 + STACK_OFFSET + 8*8] + %xdefine arg9 qword [r14 + STACK_OFFSET + 8*9] + %xdefine arg10 qword [r14 + STACK_OFFSET + 8*10] +%else + %xdefine arg1 rdi + %xdefine arg2 rsi + %xdefine arg3 rdx + %xdefine arg4 rcx + %xdefine arg5 r8 + %xdefine arg6 r9 + %xdefine arg7 qword [r14 + STACK_OFFSET + 8*1] + %xdefine arg8 qword [r14 + STACK_OFFSET + 8*2] + %xdefine arg9 qword [r14 + STACK_OFFSET + 8*3] + %xdefine arg10 qword [r14 + STACK_OFFSET + 8*4] +%endif + +%ifdef NT_LDST + %define NT_LD + %define NT_ST +%endif + +;;; Use Non-temporal load/stor +%ifdef NT_LD + %define XLDR movntdqa + %define VXLDR vmovntdqa + %define VX512LDR vmovntdqa +%else + %define XLDR movdqu + %define VXLDR vmovdqu + %define VX512LDR vmovdqu8 +%endif + +;;; Use Non-temporal load/stor +%ifdef NT_ST + %define XSTR movntdq + %define VXSTR vmovntdq + %define VX512STR vmovntdq +%else + %define XSTR movdqu + %define VXSTR vmovdqu + %define VX512STR vmovdqu8 +%endif + +%define SAFE_DATA 1 + +%endif ; GCM_DEFINES_ASM_INCLUDED diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_ippcp_api_vaes_avx512.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_ippcp_api_vaes_avx512.inc new file mode 100644 index 000000000..cd84ac05c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_ippcp_api_vaes_avx512.inc @@ -0,0 +1,144 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef _GCM_IPPCP_API_VAES_AVX512_INC_ +%define _GCM_IPPCP_API_VAES_AVX512_INC_ + +%include "gcm_vaes_avx512.inc" + +section .text +default rel + +%ifdef GCM128_MODE + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_iv_hash_update_vaes512( +; const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; const u8 *iv, +; const u64 iv_len); +; +; NB: |iv_len| shall be multiple of 16 bytes (block size). This restriction is handled outside. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_iv_hash_update_vaes512, PUBLIC + FUNC_SAVE + + vmovdqu64 xmm8, [arg2 + OrigIV] ; load current hash + + ;; Calculate GHASH of this segment + CALC_AAD_HASH arg3, arg4, xmm8, arg1, zmm1, zmm2, zmm3, zmm4, zmm5, \ + zmm6, zmm7, zmm9, zmm10, zmm11, zmm12, zmm13, zmm15, \ + zmm16, zmm17, zmm18, zmm19, zmm20, r10, r11, r12, k1 + + vmovdqu64 [arg2 + OrigIV], xmm8 ; store updated hash + + FUNC_RESTORE + + ret +ENDFUNC aes_gcm_iv_hash_update_vaes512 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_iv_hash_finalize_vaes512( +; const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; const u8 *iv, +; const u64 iv_len, +; const u64 iv_general_len); +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_iv_hash_finalize_vaes512, PUBLIC + FUNC_SAVE + + cmp arg5, 12 + jnz .Liv_is_not_12_bytes + + ;; read 12 IV bytes and pad with 0x00000001 + vmovdqa64 xmm2, [rel ONEf] + mov r11, arg3 + mov DWORD(r10), 0x0000_0fff + kmovd k1, DWORD(r10) + vmovdqu8 xmm2{k1}, [r11] ; ctr = IV | 0x1 + + jmp .Liv_compute_done + +.Liv_is_not_12_bytes: + vmovdqu xmm2, [arg2 + OrigIV] + + ;; prepare IV + CALC_J0 arg1, arg3, arg4, xmm2, \ + zmm1, zmm11, zmm3, zmm4, zmm5, zmm6, zmm7, zmm8, zmm9, zmm10, \ + zmm12, zmm13, zmm15, zmm16, zmm17, zmm18, zmm19, zmm20, \ + r10, r11, r12, k1, arg5 + +.Liv_compute_done: + vmovdqu64 [arg2 + OrigIV], xmm2 ; ctx.orig_IV = iv + vpshufb xmm2, [rel SHUF_MASK] + vmovdqu64 [arg2 + CurCount], xmm2 ; ctx.current_counter = iv (LE format) + + FUNC_RESTORE + + ret +ENDFUNC aes_gcm_iv_hash_finalize_vaes512 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_aad_hash_update_vaes512( +; const struct gcm_key_data *key_data, +; struct gcm_context_data *context_data, +; const u8 *aad, +; const u64 aad_len); +; +; NB: This function is always called with |aad_len| that is multiple of 16 bytes (block size). +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_aad_hash_update_vaes512, PUBLIC + FUNC_SAVE + + vmovdqu64 xmm14, [arg2 + AadHash] ; load current hash + + ;; Calculate GHASH of this segment + CALC_AAD_HASH arg3, arg4, xmm14, arg1, zmm1, zmm2, zmm3, zmm4, zmm5, \ + zmm6, zmm7, zmm9, zmm10, zmm11, zmm12, zmm13, zmm15, \ + zmm16, zmm17, zmm18, zmm19, zmm20, r10, r11, r12, k1 + + vmovdqu64 [arg2 + AadHash], xmm14 ; store updated hash + + FUNC_RESTORE + + ret +ENDFUNC aes_gcm_aad_hash_update_vaes512 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;void aes_gcm_gmult_vaes512( +; struct gcm_context_data *context_data, +; u8 *ghash) +; +; Function updates |ghash| value by multiplying it on H^1 key. +; Leaf function. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +IPPASM aes_gcm_gmult_vaes512, PUBLIC + + vmovdqu64 xmm1, [arg2] + vmovdqu64 xmm2, [arg1 + HashKey_1] + + GHASH_MUL xmm1, xmm2, xmm3, xmm4, xmm5, xmm16, xmm17 + + vmovdqu64 [arg2], xmm1 + + ret +ENDFUNC aes_gcm_gmult_vaes512 + +%endif ; GCM128_MODE + +%endif ; _GCM_IPPCP_API_VAES_AVX512_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_keys_avx512.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_keys_avx512.inc new file mode 100644 index 000000000..62dcc86f8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_keys_avx512.inc @@ -0,0 +1,42 @@ +;=============================================================================== +; Copyright (C) 2019 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef GCM_KEYS_AVX512_INCLUDED +%define GCM_KEYS_AVX512_INCLUDED + +;; Define the fields of gcm_key_data struct: +;; uint8_t expanded_keys[GCM_ENC_KEY_LEN * GCM_KEY_SETS]; +;; uint8_t shifted_hkey_8[GCM_ENC_KEY_LEN]; // HashKey^8 <<1 mod poly +;; uint8_t shifted_hkey_7[GCM_ENC_KEY_LEN]; // HashKey^7 <<1 mod poly +;; uint8_t shifted_hkey_6[GCM_ENC_KEY_LEN]; // HashKey^6 <<1 mod poly +;; uint8_t shifted_hkey_5[GCM_ENC_KEY_LEN]; // HashKey^5 <<1 mod poly +;; uint8_t shifted_hkey_4[GCM_ENC_KEY_LEN]; // HashKey^4 <<1 mod poly +;; uint8_t shifted_hkey_3[GCM_ENC_KEY_LEN]; // HashKey^3 <<1 mod poly +;; uint8_t shifted_hkey_2[GCM_ENC_KEY_LEN]; // HashKey^2 <<1 mod poly +;; uint8_t shifted_hkey_1[GCM_ENC_KEY_LEN]; // HashKey <<1 mod poly + +%define HashKey_8 (16*15) ; HashKey^8 <<1 mod poly +%define HashKey_7 (16*16) ; HashKey^7 <<1 mod poly +%define HashKey_6 (16*17) ; HashKey^6 <<1 mod poly +%define HashKey_5 (16*18) ; HashKey^5 <<1 mod poly +%define HashKey_4 (16*19) ; HashKey^4 <<1 mod poly +%define HashKey_3 (16*20) ; HashKey^3 <<1 mod poly +%define HashKey_2 (16*21) ; HashKey^2 <<1 mod poly +%define HashKey_1 (16*22) ; HashKey <<1 mod poly +%define HashKey (16*22) ; HashKey <<1 mod poly + +%endif ; GCM_KEYS_AVX512_INCLUDED diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_keys_vaes_avx512.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_keys_vaes_avx512.inc new file mode 100644 index 000000000..e23712f73 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_keys_vaes_avx512.inc @@ -0,0 +1,221 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef GCM_KEYS_VAES_AVX512_INCLUDED +%define GCM_KEYS_VAES_AVX512_INCLUDED + +;; Define the fields of gcm_key_data struct: +;; uint8_t expanded_keys[GCM_ENC_KEY_LEN * GCM_KEY_SETS]; +;; uint8_t shifted_hkey_9_128[GCM_ENC_KEY_LEN * (128 - 8)]; +;; uint8_t shifted_hkey_8[GCM_ENC_KEY_LEN]; // HashKey^8 <<1 mod poly +;; uint8_t shifted_hkey_7[GCM_ENC_KEY_LEN]; // HashKey^7 <<1 mod poly +;; uint8_t shifted_hkey_6[GCM_ENC_KEY_LEN]; // HashKey^6 <<1 mod poly +;; uint8_t shifted_hkey_5[GCM_ENC_KEY_LEN]; // HashKey^5 <<1 mod poly +;; uint8_t shifted_hkey_4[GCM_ENC_KEY_LEN]; // HashKey^4 <<1 mod poly +;; uint8_t shifted_hkey_3[GCM_ENC_KEY_LEN]; // HashKey^3 <<1 mod poly +;; uint8_t shifted_hkey_2[GCM_ENC_KEY_LEN]; // HashKey^2 <<1 mod poly +;; uint8_t shifted_hkey_1[GCM_ENC_KEY_LEN]; // HashKey <<1 mod poly + +%ifdef GCM_BIG_DATA +;; +;; Key structure holds up to 128 ghash keys +;; +%define HashKey_128 (16*15) ; HashKey^128 <<1 mod poly +%define HashKey_127 (16*16) ; HashKey^127 <<1 mod poly +%define HashKey_126 (16*17) ; HashKey^126 <<1 mod poly +%define HashKey_125 (16*18) ; HashKey^125 <<1 mod poly +%define HashKey_124 (16*19) ; HashKey^124 <<1 mod poly +%define HashKey_123 (16*20) ; HashKey^123 <<1 mod poly +%define HashKey_122 (16*21) ; HashKey^122 <<1 mod poly +%define HashKey_121 (16*22) ; HashKey^121 <<1 mod poly +%define HashKey_120 (16*23) ; HashKey^120 <<1 mod poly +%define HashKey_119 (16*24) ; HashKey^119 <<1 mod poly +%define HashKey_118 (16*25) ; HashKey^118 <<1 mod poly +%define HashKey_117 (16*26) ; HashKey^117 <<1 mod poly +%define HashKey_116 (16*27) ; HashKey^116 <<1 mod poly +%define HashKey_115 (16*28) ; HashKey^115 <<1 mod poly +%define HashKey_114 (16*29) ; HashKey^114 <<1 mod poly +%define HashKey_113 (16*30) ; HashKey^113 <<1 mod poly +%define HashKey_112 (16*31) ; HashKey^112 <<1 mod poly +%define HashKey_111 (16*32) ; HashKey^111 <<1 mod poly +%define HashKey_110 (16*33) ; HashKey^110 <<1 mod poly +%define HashKey_109 (16*34) ; HashKey^109 <<1 mod poly +%define HashKey_108 (16*35) ; HashKey^108 <<1 mod poly +%define HashKey_107 (16*36) ; HashKey^107 <<1 mod poly +%define HashKey_106 (16*37) ; HashKey^106 <<1 mod poly +%define HashKey_105 (16*38) ; HashKey^105 <<1 mod poly +%define HashKey_104 (16*39) ; HashKey^104 <<1 mod poly +%define HashKey_103 (16*40) ; HashKey^103 <<1 mod poly +%define HashKey_102 (16*41) ; HashKey^102 <<1 mod poly +%define HashKey_101 (16*42) ; HashKey^101 <<1 mod poly +%define HashKey_100 (16*43) ; HashKey^100 <<1 mod poly +%define HashKey_99 (16*44) ; HashKey^99 <<1 mod poly +%define HashKey_98 (16*45) ; HashKey^98 <<1 mod poly +%define HashKey_97 (16*46) ; HashKey^97 <<1 mod poly +%define HashKey_96 (16*47) ; HashKey^96 <<1 mod poly +%define HashKey_95 (16*48) ; HashKey^95 <<1 mod poly +%define HashKey_94 (16*49) ; HashKey^94 <<1 mod poly +%define HashKey_93 (16*50) ; HashKey^93 <<1 mod poly +%define HashKey_92 (16*51) ; HashKey^92 <<1 mod poly +%define HashKey_91 (16*52) ; HashKey^91 <<1 mod poly +%define HashKey_90 (16*53) ; HashKey^90 <<1 mod poly +%define HashKey_89 (16*54) ; HashKey^89 <<1 mod poly +%define HashKey_88 (16*55) ; HashKey^88 <<1 mod poly +%define HashKey_87 (16*56) ; HashKey^87 <<1 mod poly +%define HashKey_86 (16*57) ; HashKey^86 <<1 mod poly +%define HashKey_85 (16*58) ; HashKey^85 <<1 mod poly +%define HashKey_84 (16*59) ; HashKey^84 <<1 mod poly +%define HashKey_83 (16*60) ; HashKey^83 <<1 mod poly +%define HashKey_82 (16*61) ; HashKey^82 <<1 mod poly +%define HashKey_81 (16*62) ; HashKey^81 <<1 mod poly +%define HashKey_80 (16*63) ; HashKey^80 <<1 mod poly +%define HashKey_79 (16*64) ; HashKey^79 <<1 mod poly +%define HashKey_78 (16*65) ; HashKey^78 <<1 mod poly +%define HashKey_77 (16*66) ; HashKey^77 <<1 mod poly +%define HashKey_76 (16*67) ; HashKey^76 <<1 mod poly +%define HashKey_75 (16*68) ; HashKey^75 <<1 mod poly +%define HashKey_74 (16*69) ; HashKey^74 <<1 mod poly +%define HashKey_73 (16*70) ; HashKey^73 <<1 mod poly +%define HashKey_72 (16*71) ; HashKey^72 <<1 mod poly +%define HashKey_71 (16*72) ; HashKey^71 <<1 mod poly +%define HashKey_70 (16*73) ; HashKey^70 <<1 mod poly +%define HashKey_69 (16*74) ; HashKey^69 <<1 mod poly +%define HashKey_68 (16*75) ; HashKey^68 <<1 mod poly +%define HashKey_67 (16*76) ; HashKey^67 <<1 mod poly +%define HashKey_66 (16*77) ; HashKey^66 <<1 mod poly +%define HashKey_65 (16*78) ; HashKey^65 <<1 mod poly +%define HashKey_64 (16*79) ; HashKey^64 <<1 mod poly +%define HashKey_63 (16*80) ; HashKey^63 <<1 mod poly +%define HashKey_62 (16*81) ; HashKey^62 <<1 mod poly +%define HashKey_61 (16*82) ; HashKey^61 <<1 mod poly +%define HashKey_60 (16*83) ; HashKey^60 <<1 mod poly +%define HashKey_59 (16*84) ; HashKey^59 <<1 mod poly +%define HashKey_58 (16*85) ; HashKey^58 <<1 mod poly +%define HashKey_57 (16*86) ; HashKey^57 <<1 mod poly +%define HashKey_56 (16*87) ; HashKey^56 <<1 mod poly +%define HashKey_55 (16*88) ; HashKey^55 <<1 mod poly +%define HashKey_54 (16*89) ; HashKey^54 <<1 mod poly +%define HashKey_53 (16*90) ; HashKey^53 <<1 mod poly +%define HashKey_52 (16*91) ; HashKey^52 <<1 mod poly +%define HashKey_51 (16*92) ; HashKey^51 <<1 mod poly +%define HashKey_50 (16*93) ; HashKey^50 <<1 mod poly +%define HashKey_49 (16*94) ; HashKey^49 <<1 mod poly +%define HashKey_48 (16*95) ; HashKey^48 <<1 mod poly +%define HashKey_47 (16*96) ; HashKey^47 <<1 mod poly +%define HashKey_46 (16*97) ; HashKey^46 <<1 mod poly +%define HashKey_45 (16*98) ; HashKey^45 <<1 mod poly +%define HashKey_44 (16*99) ; HashKey^44 <<1 mod poly +%define HashKey_43 (16*100) ; HashKey^43 <<1 mod poly +%define HashKey_42 (16*101) ; HashKey^42 <<1 mod poly +%define HashKey_41 (16*102) ; HashKey^41 <<1 mod poly +%define HashKey_40 (16*103) ; HashKey^40 <<1 mod poly +%define HashKey_39 (16*104) ; HashKey^39 <<1 mod poly +%define HashKey_38 (16*105) ; HashKey^38 <<1 mod poly +%define HashKey_37 (16*106) ; HashKey^37 <<1 mod poly +%define HashKey_36 (16*107) ; HashKey^36 <<1 mod poly +%define HashKey_35 (16*108) ; HashKey^35 <<1 mod poly +%define HashKey_34 (16*109) ; HashKey^34 <<1 mod poly +%define HashKey_33 (16*110) ; HashKey^33 <<1 mod poly +%define HashKey_32 (16*111) ; HashKey^32 <<1 mod poly +%define HashKey_31 (16*112) ; HashKey^31 <<1 mod poly +%define HashKey_30 (16*113) ; HashKey^30 <<1 mod poly +%define HashKey_29 (16*114) ; HashKey^29 <<1 mod poly +%define HashKey_28 (16*115) ; HashKey^28 <<1 mod poly +%define HashKey_27 (16*116) ; HashKey^27 <<1 mod poly +%define HashKey_26 (16*117) ; HashKey^26 <<1 mod poly +%define HashKey_25 (16*118) ; HashKey^25 <<1 mod poly +%define HashKey_24 (16*119) ; HashKey^24 <<1 mod poly +%define HashKey_23 (16*120) ; HashKey^23 <<1 mod poly +%define HashKey_22 (16*121) ; HashKey^22 <<1 mod poly +%define HashKey_21 (16*122) ; HashKey^21 <<1 mod poly +%define HashKey_20 (16*123) ; HashKey^20 <<1 mod poly +%define HashKey_19 (16*124) ; HashKey^19 <<1 mod poly +%define HashKey_18 (16*125) ; HashKey^18 <<1 mod poly +%define HashKey_17 (16*126) ; HashKey^17 <<1 mod poly +%define HashKey_16 (16*127) ; HashKey^16 <<1 mod poly +%define HashKey_15 (16*128) ; HashKey^15 <<1 mod poly +%define HashKey_14 (16*129) ; HashKey^14 <<1 mod poly +%define HashKey_13 (16*130) ; HashKey^13 <<1 mod poly +%define HashKey_12 (16*131) ; HashKey^12 <<1 mod poly +%define HashKey_11 (16*132) ; HashKey^11 <<1 mod poly +%define HashKey_10 (16*133) ; HashKey^10 <<1 mod poly +%define HashKey_9 (16*134) ; HashKey^9 <<1 mod poly +%define HashKey_8 (16*135) ; HashKey^8 <<1 mod poly +%define HashKey_7 (16*136) ; HashKey^7 <<1 mod poly +%define HashKey_6 (16*137) ; HashKey^6 <<1 mod poly +%define HashKey_5 (16*138) ; HashKey^5 <<1 mod poly +%define HashKey_4 (16*139) ; HashKey^4 <<1 mod poly +%define HashKey_3 (16*140) ; HashKey^3 <<1 mod poly +%define HashKey_2 (16*141) ; HashKey^2 <<1 mod poly +%define HashKey_1 (16*142) ; HashKey <<1 mod poly +%define HashKey (16*142) ; HashKey <<1 mod poly +%else +;; +;; Key structure holds up to 48 ghash keys +;; +%define HashKey_48 (16*15) ; HashKey^48 <<1 mod poly +%define HashKey_47 (16*16) ; HashKey^47 <<1 mod poly +%define HashKey_46 (16*17) ; HashKey^46 <<1 mod poly +%define HashKey_45 (16*18) ; HashKey^45 <<1 mod poly +%define HashKey_44 (16*19) ; HashKey^44 <<1 mod poly +%define HashKey_43 (16*20) ; HashKey^43 <<1 mod poly +%define HashKey_42 (16*21) ; HashKey^42 <<1 mod poly +%define HashKey_41 (16*22) ; HashKey^41 <<1 mod poly +%define HashKey_40 (16*23) ; HashKey^40 <<1 mod poly +%define HashKey_39 (16*24) ; HashKey^39 <<1 mod poly +%define HashKey_38 (16*25) ; HashKey^38 <<1 mod poly +%define HashKey_37 (16*26) ; HashKey^37 <<1 mod poly +%define HashKey_36 (16*27) ; HashKey^36 <<1 mod poly +%define HashKey_35 (16*28) ; HashKey^35 <<1 mod poly +%define HashKey_34 (16*29) ; HashKey^34 <<1 mod poly +%define HashKey_33 (16*30) ; HashKey^33 <<1 mod poly +%define HashKey_32 (16*31) ; HashKey^32 <<1 mod poly +%define HashKey_31 (16*32) ; HashKey^31 <<1 mod poly +%define HashKey_30 (16*33) ; HashKey^30 <<1 mod poly +%define HashKey_29 (16*34) ; HashKey^29 <<1 mod poly +%define HashKey_28 (16*35) ; HashKey^28 <<1 mod poly +%define HashKey_27 (16*36) ; HashKey^27 <<1 mod poly +%define HashKey_26 (16*37) ; HashKey^26 <<1 mod poly +%define HashKey_25 (16*38) ; HashKey^25 <<1 mod poly +%define HashKey_24 (16*39) ; HashKey^24 <<1 mod poly +%define HashKey_23 (16*40) ; HashKey^23 <<1 mod poly +%define HashKey_22 (16*41) ; HashKey^22 <<1 mod poly +%define HashKey_21 (16*42) ; HashKey^21 <<1 mod poly +%define HashKey_20 (16*43) ; HashKey^20 <<1 mod poly +%define HashKey_19 (16*44) ; HashKey^19 <<1 mod poly +%define HashKey_18 (16*45) ; HashKey^18 <<1 mod poly +%define HashKey_17 (16*46) ; HashKey^17 <<1 mod poly +%define HashKey_16 (16*47) ; HashKey^16 <<1 mod poly +%define HashKey_15 (16*48) ; HashKey^15 <<1 mod poly +%define HashKey_14 (16*49) ; HashKey^14 <<1 mod poly +%define HashKey_13 (16*50) ; HashKey^13 <<1 mod poly +%define HashKey_12 (16*51) ; HashKey^12 <<1 mod poly +%define HashKey_11 (16*52) ; HashKey^11 <<1 mod poly +%define HashKey_10 (16*53) ; HashKey^10 <<1 mod poly +%define HashKey_9 (16*54) ; HashKey^9 <<1 mod poly +%define HashKey_8 (16*55) ; HashKey^8 <<1 mod poly +%define HashKey_7 (16*56) ; HashKey^7 <<1 mod poly +%define HashKey_6 (16*57) ; HashKey^6 <<1 mod poly +%define HashKey_5 (16*58) ; HashKey^5 <<1 mod poly +%define HashKey_4 (16*59) ; HashKey^4 <<1 mod poly +%define HashKey_3 (16*60) ; HashKey^3 <<1 mod poly +%define HashKey_2 (16*61) ; HashKey^2 <<1 mod poly +%define HashKey_1 (16*62) ; HashKey <<1 mod poly +%define HashKey (16*62) ; HashKey <<1 mod poly +%endif ; !GCM_BIG_DATA + +%endif ; GCM_KEYS_VAES_AVX512_INCLUDED diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_vaes_avx512.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_vaes_avx512.inc new file mode 100644 index 000000000..6aca9ca6a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/gcm_vaes_avx512.inc @@ -0,0 +1,3559 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Authors: +; Erdinc Ozturk +; Vinodh Gopal +; James Guilford +; Tomasz Kantecki +; +; +; References: +; This code was derived and highly optimized from the code described in paper: +; Vinodh Gopal et. al. Optimized Galois-Counter-Mode Implementation on Intel Architecture Processors. August, 2010 +; The details of the implementation is explained in: +; Erdinc Ozturk et. al. Enabling High-Performance Galois-Counter-Mode on Intel Architecture Processors. October, 2012. +; +; +; +; +; Assumptions: +; +; +; +; iv: +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Salt (From the SA) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Initialization Vector | +; | (This is the sequence number from IPSec header) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 0x1 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; +; +; +; AAD: +; AAD will be padded with 0 to the next 16byte multiple +; for example, assume AAD is a u32 vector +; +; if AAD is 8 bytes: +; AAD[3] = {A0, A1}; +; padded AAD in xmm register = {A1 A0 0 0} +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | SPI (A1) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 32-bit Sequence Number (A0) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 0x0 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; +; AAD Format with 32-bit Sequence Number +; +; if AAD is 12 bytes: +; AAD[3] = {A0, A1, A2}; +; padded AAD in xmm register = {A2 A1 A0 0} +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | SPI (A2) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 64-bit Extended Sequence Number {A1,A0} | +; | | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | 0x0 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; +; AAD Format with 64-bit Extended Sequence Number +; +; +; aadLen: +; Must be a multiple of 4 bytes and from the definition of the spec. +; The code additionally supports any aadLen length. +; +; TLen: +; from the definition of the spec, TLen can only be 8, 12 or 16 bytes. +; +; poly = x^128 + x^127 + x^126 + x^121 + 1 +; throughout the code, one tab and two tab indentations are used. one tab is for GHASH part, two tabs is for AES part. +; + +%ifndef _GCM_VAES_AVX512_INC_ +%define _GCM_VAES_AVX512_INC_ + +%include "os.inc" +%include "reg_sizes.inc" +%include "clear_regs.inc" +%include "gcm_defines.inc" +%include "gcm_keys_vaes_avx512.inc" +%include "memcpy.inc" +%include "aes_common.inc" + +%ifndef GCM128_MODE +%ifndef GCM192_MODE +%ifndef GCM256_MODE +%error "No GCM mode selected for gcm_avx512.asm!" +%endif +%endif +%endif + +;; Decide on AES-GCM key size to compile for +%ifdef GCM128_MODE +%define NROUNDS 9 +%define FN_NAME(x,y) aes_gcm_ %+ x %+ _128 %+ y %+ vaes_avx512 +%endif + +%ifdef GCM192_MODE +%define NROUNDS 11 +%define FN_NAME(x,y) aes_gcm_ %+ x %+ _192 %+ y %+ vaes_avx512 +%endif + +%ifdef GCM256_MODE +%define NROUNDS 13 +%define FN_NAME(x,y) aes_gcm_ %+ x %+ _256 %+ y %+ vaes_avx512 +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Stack frame definition +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%ifidn __OUTPUT_FORMAT__, win64 + %define XMM_STORAGE (10*16) ; space for 10 XMM registers + %define GP_STORAGE ((9*8) + 24) ; space for 9 GP registers + 24 bytes for 64 byte alignment +%else + %define XMM_STORAGE 0 + %define GP_STORAGE (8*8) ; space for 7 GP registers + 1 for alignment +%endif +%define LOCAL_STORAGE (48*16) ; space for up to 48 AES blocks + +;;; sequence is (bottom-up): GP, XMM, local +%define STACK_GP_OFFSET 0 +%define STACK_XMM_OFFSET (STACK_GP_OFFSET + GP_STORAGE) +%define STACK_LOCAL_OFFSET (STACK_XMM_OFFSET + XMM_STORAGE) +%define STACK_FRAME_SIZE (STACK_LOCAL_OFFSET + LOCAL_STORAGE) + +;; for compatibility with stack argument definitions in gcm_defines.asm +%define STACK_OFFSET 0 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Utility Macros +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; =========================================================================== +;;; =========================================================================== +;;; Horizontal XOR - 4 x 128bits xored together +%macro VHPXORI4x128 2 +%define %%REG %1 ; [in/out] ZMM with 4x128bits to xor; 128bit output +%define %%TMP %2 ; [clobbered] ZMM temporary register + vextracti64x4 YWORD(%%TMP), %%REG, 1 + vpxorq YWORD(%%REG), YWORD(%%REG), YWORD(%%TMP) + vextracti32x4 XWORD(%%TMP), YWORD(%%REG), 1 + vpxorq XWORD(%%REG), XWORD(%%REG), XWORD(%%TMP) +%endmacro ; VHPXORI4x128 + +;;; =========================================================================== +;;; =========================================================================== +;;; AVX512 reduction macro +%macro VCLMUL_REDUCE 6 +%define %%OUT %1 ; [out] zmm/ymm/xmm: result (must not be %%TMP1 or %%HI128) +%define %%POLY %2 ; [in] zmm/ymm/xmm: polynomial +%define %%HI128 %3 ; [in] zmm/ymm/xmm: high 128b of hash to reduce +%define %%LO128 %4 ; [in] zmm/ymm/xmm: low 128b of hash to reduce +%define %%TMP0 %5 ; [in] zmm/ymm/xmm: temporary register +%define %%TMP1 %6 ; [in] zmm/ymm/xmm: temporary register + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; first phase of the reduction + vpclmulqdq %%TMP0, %%POLY, %%LO128, 0x01 + vpslldq %%TMP0, %%TMP0, 8 ; shift-L 2 DWs + vpxorq %%TMP0, %%LO128, %%TMP0 ; first phase of the reduction complete + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; second phase of the reduction + vpclmulqdq %%TMP1, %%POLY, %%TMP0, 0x00 + vpsrldq %%TMP1, %%TMP1, 4 ; shift-R only 1-DW to obtain 2-DWs shift-R + + vpclmulqdq %%OUT, %%POLY, %%TMP0, 0x10 + vpslldq %%OUT, %%OUT, 4 ; shift-L 1-DW to obtain result with no shifts + + vpternlogq %%OUT, %%TMP1, %%HI128, 0x96 ; OUT/GHASH = OUT xor TMP1 xor HI128 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%endmacro + +;;; =========================================================================== +;;; =========================================================================== +;;; schoolbook multiply of 16 blocks (8 x 16 bytes) +;;; - it is assumed that data read from %%INPTR is already shuffled and +;;; %%INPTR address is 64 byte aligned +;;; - there is an option to pass ready blocks through ZMM registers too. +;;; 4 extra parameters need to passed in such case and 21st argument can be empty +%macro GHASH_16 21-25 +%define %%TYPE %1 ; [in] ghash type: start (xor hash), mid, end (same as mid; no reduction), + ; end_reduce (end with reduction), start_reduce +%define %%GH %2 ; [in/out] ZMM ghash sum: high 128-bits +%define %%GM %3 ; [in/out] ZMM ghash sum: middle 128-bits +%define %%GL %4 ; [in/out] ZMM ghash sum: low 128-bits +%define %%INPTR %5 ; [in] data input pointer +%define %%INOFF %6 ; [in] data input offset +%define %%INDIS %7 ; [in] data input displacement +%define %%HKPTR %8 ; [in] hash key pointer +%define %%HKOFF %9 ; [in] hash key offset +%define %%HKDIS %10 ; [in] hash key displacement +%define %%HASH %11 ; [in/out] ZMM hash value in/out +%define %%ZTMP0 %12 ; [clobbered] temporary ZMM +%define %%ZTMP1 %13 ; [clobbered] temporary ZMM +%define %%ZTMP2 %14 ; [clobbered] temporary ZMM +%define %%ZTMP3 %15 ; [clobbered] temporary ZMM +%define %%ZTMP4 %16 ; [clobbered] temporary ZMM +%define %%ZTMP5 %17 ; [clobbered] temporary ZMM +%define %%ZTMP6 %18 ; [clobbered] temporary ZMM +%define %%ZTMP7 %19 ; [clobbered] temporary ZMM +%define %%ZTMP8 %20 ; [clobbered] temporary ZMM +%define %%ZTMP9 %21 ; [clobbered] temporary ZMM +%define %%DAT0 %22 ; [in] ZMM with 4 blocks of input data (INPTR, INOFF, INDIS unused) +%define %%DAT1 %23 ; [in] ZMM with 4 blocks of input data (INPTR, INOFF, INDIS unused) +%define %%DAT2 %24 ; [in] ZMM with 4 blocks of input data (INPTR, INOFF, INDIS unused) +%define %%DAT3 %25 ; [in] ZMM with 4 blocks of input data (INPTR, INOFF, INDIS unused) + +%assign start_ghash 0 +%assign do_reduction 0 + +%ifidn %%TYPE, start +%assign start_ghash 1 +%endif + +%ifidn %%TYPE, start_reduce +%assign start_ghash 1 +%assign do_reduction 1 +%endif + +%ifidn %%TYPE, end_reduce +%assign do_reduction 1 +%endif + + ;; ghash blocks 0-3 +%if %0 == 21 + vmovdqa64 %%ZTMP9, [%%INPTR + %%INOFF + %%INDIS] +%else +%xdefine %%ZTMP9 %%DAT0 +%endif + +%if start_ghash != 0 + vpxorq %%ZTMP9, %%HASH +%endif + vmovdqu64 %%ZTMP8, [%%HKPTR + %%HKOFF + %%HKDIS] + vpclmulqdq %%ZTMP0, %%ZTMP9, %%ZTMP8, 0x11 ; T0H = a1*b1 + vpclmulqdq %%ZTMP1, %%ZTMP9, %%ZTMP8, 0x00 ; T0L = a0*b0 + vpclmulqdq %%ZTMP2, %%ZTMP9, %%ZTMP8, 0x01 ; T0M1 = a1*b0 + vpclmulqdq %%ZTMP3, %%ZTMP9, %%ZTMP8, 0x10 ; T0M2 = a0*b1 + ;; ghash blocks 4-7 +%if %0 == 21 + vmovdqa64 %%ZTMP9, [%%INPTR + %%INOFF + %%INDIS + 64] +%else +%xdefine %%ZTMP9 %%DAT1 +%endif + vmovdqu64 %%ZTMP8, [%%HKPTR + %%HKOFF + %%HKDIS + 64] + vpclmulqdq %%ZTMP4, %%ZTMP9, %%ZTMP8, 0x11 ; T1H = a1*b1 + vpclmulqdq %%ZTMP5, %%ZTMP9, %%ZTMP8, 0x00 ; T1L = a0*b0 + vpclmulqdq %%ZTMP6, %%ZTMP9, %%ZTMP8, 0x01 ; T1M1 = a1*b0 + vpclmulqdq %%ZTMP7, %%ZTMP9, %%ZTMP8, 0x10 ; T1M2 = a0*b1 + ;; update sums +%if start_ghash != 0 + vpxorq %%GM, %%ZTMP2, %%ZTMP6 ; GM = T0M1 + T1M1 + vpxorq %%GH, %%ZTMP0, %%ZTMP4 ; GH = T0H + T1H + vpxorq %%GL, %%ZTMP1, %%ZTMP5 ; GL = T0L + T1L + vpternlogq %%GM, %%ZTMP3, %%ZTMP7, 0x96 ; GM = T0M2 + T1M1 +%else ;; mid, end, end_reduce + vpternlogq %%GM, %%ZTMP2, %%ZTMP6, 0x96 ; GM += T0M1 + T1M1 + vpternlogq %%GH, %%ZTMP0, %%ZTMP4, 0x96 ; GH += T0H + T1H + vpternlogq %%GL, %%ZTMP1, %%ZTMP5, 0x96 ; GL += T0L + T1L + vpternlogq %%GM, %%ZTMP3, %%ZTMP7, 0x96 ; GM += T0M2 + T1M1 +%endif + ;; ghash blocks 8-11 +%if %0 == 21 + vmovdqa64 %%ZTMP9, [%%INPTR + %%INOFF + %%INDIS + 128] +%else +%xdefine %%ZTMP9 %%DAT2 +%endif + vmovdqu64 %%ZTMP8, [%%HKPTR + %%HKOFF + %%HKDIS + 128] + vpclmulqdq %%ZTMP0, %%ZTMP9, %%ZTMP8, 0x11 ; T0H = a1*b1 + vpclmulqdq %%ZTMP1, %%ZTMP9, %%ZTMP8, 0x00 ; T0L = a0*b0 + vpclmulqdq %%ZTMP2, %%ZTMP9, %%ZTMP8, 0x01 ; T0M1 = a1*b0 + vpclmulqdq %%ZTMP3, %%ZTMP9, %%ZTMP8, 0x10 ; T0M2 = a0*b1 + ;; ghash blocks 12-15 +%if %0 == 21 + vmovdqa64 %%ZTMP9, [%%INPTR + %%INOFF + %%INDIS + 192] +%else +%xdefine %%ZTMP9 %%DAT3 +%endif + vmovdqu64 %%ZTMP8, [%%HKPTR + %%HKOFF + %%HKDIS + 192] + vpclmulqdq %%ZTMP4, %%ZTMP9, %%ZTMP8, 0x11 ; T1H = a1*b1 + vpclmulqdq %%ZTMP5, %%ZTMP9, %%ZTMP8, 0x00 ; T1L = a0*b0 + vpclmulqdq %%ZTMP6, %%ZTMP9, %%ZTMP8, 0x01 ; T1M1 = a1*b0 + vpclmulqdq %%ZTMP7, %%ZTMP9, %%ZTMP8, 0x10 ; T1M2 = a0*b1 + ;; update sums + vpternlogq %%GM, %%ZTMP2, %%ZTMP6, 0x96 ; GM += T0M1 + T1M1 + vpternlogq %%GH, %%ZTMP0, %%ZTMP4, 0x96 ; GH += T0H + T1H + vpternlogq %%GL, %%ZTMP1, %%ZTMP5, 0x96 ; GL += T0L + T1L + vpternlogq %%GM, %%ZTMP3, %%ZTMP7, 0x96 ; GM += T0M2 + T1M1 + +%if do_reduction != 0 + ;; integrate GM into GH and GL + vpsrldq %%ZTMP0, %%GM, 8 + vpslldq %%ZTMP1, %%GM, 8 + vpxorq %%GH, %%GH, %%ZTMP0 + vpxorq %%GL, %%GL, %%ZTMP1 + + ;; add GH and GL 128-bit words horizontally + VHPXORI4x128 %%GH, %%ZTMP0 + VHPXORI4x128 %%GL, %%ZTMP1 + + ;; reduction + vmovdqa64 XWORD(%%ZTMP2), [rel POLY2] + VCLMUL_REDUCE XWORD(%%HASH), XWORD(%%ZTMP2), \ + XWORD(%%GH), XWORD(%%GL), XWORD(%%ZTMP0), XWORD(%%ZTMP1) +%endif +%endmacro + +;;; =========================================================================== +;;; =========================================================================== +;;; GHASH 1 to 16 blocks of cipher text +;;; - performs reduction at the end +;;; - it doesn't load the data and it assumed it is already loaded and +;;; shuffled +;;; - single_call scenario only +%macro GHASH_1_TO_16 17-20 +%define %%KP %1 ; [in] pointer to expanded keys +%define %%GHASH %2 ; [out] ghash output +%define %%T0H %3 ; [clobbered] temporary ZMM +%define %%T0L %4 ; [clobbered] temporary ZMM +%define %%T0M1 %5 ; [clobbered] temporary ZMM +%define %%T0M2 %6 ; [clobbered] temporary ZMM +%define %%T1H %7 ; [clobbered] temporary ZMM +%define %%T1L %8 ; [clobbered] temporary ZMM +%define %%T1M1 %9 ; [clobbered] temporary ZMM +%define %%T1M2 %10 ; [clobbered] temporary ZMM +%define %%HK %11 ; [clobbered] temporary ZMM +%define %%AAD_HASH_IN %12 ; [in] input hash value +%define %%CIPHER_IN0 %13 ; [in] ZMM with cipher text blocks 0-3 +%define %%CIPHER_IN1 %14 ; [in] ZMM with cipher text blocks 4-7 +%define %%CIPHER_IN2 %15 ; [in] ZMM with cipher text blocks 8-11 +%define %%CIPHER_IN3 %16 ; [in] ZMM with cipher text blocks 12-15 +%define %%NUM_BLOCKS %17 ; [in] numerical value, number of blocks +%define %%GH %18 ; [in] ZMM with hi product part +%define %%GM %19 ; [in] ZMM with mid product part +%define %%GL %20 ; [in] ZMM with lo product part + +%assign hashk HashKey_ %+ %%NUM_BLOCKS + +%if %0 == 17 + vpxorq %%CIPHER_IN0, %%CIPHER_IN0, %%AAD_HASH_IN +%endif + +%if %%NUM_BLOCKS == 16 + + vmovdqu64 %%HK, [%%KP + hashk] + vpclmulqdq %%T0H, %%CIPHER_IN0, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T0L, %%CIPHER_IN0, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T0M1, %%CIPHER_IN0, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T0M2, %%CIPHER_IN0, %%HK, 0x10 ; M2 = a0*b1 + vmovdqu64 %%HK, [%%KP + hashk + (1*64)] + vpclmulqdq %%T1H, %%CIPHER_IN1, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T1L, %%CIPHER_IN1, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T1M1, %%CIPHER_IN1, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T1M2, %%CIPHER_IN1, %%HK, 0x10 ; M2 = a0*b1 + vmovdqu64 %%HK, [%%KP + hashk + (2*64)] + vpclmulqdq %%CIPHER_IN0, %%CIPHER_IN2, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%CIPHER_IN1, %%CIPHER_IN2, %%HK, 0x00 ; L = a0*b0 + vpternlogq %%T0H, %%CIPHER_IN0, %%T1H, 0x96 + vpternlogq %%T0L, %%CIPHER_IN1, %%T1L, 0x96 + vpclmulqdq %%CIPHER_IN0, %%CIPHER_IN2, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%CIPHER_IN1, %%CIPHER_IN2, %%HK, 0x10 ; M2 = a0*b1 + vpternlogq %%T0M1, %%CIPHER_IN0, %%T1M1, 0x96 + vpternlogq %%T0M2, %%CIPHER_IN1, %%T1M2, 0x96 + vmovdqu64 %%HK, [%%KP + hashk + (3*64)] + vpclmulqdq %%T1H, %%CIPHER_IN3, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T1L, %%CIPHER_IN3, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T1M1, %%CIPHER_IN3, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T1M2, %%CIPHER_IN3, %%HK, 0x10 ; M2 = a0*b1 + vpxorq %%T1H, %%T0H, %%T1H + vpxorq %%T1L, %%T0L, %%T1L + vpxorq %%T1M1, %%T0M1, %%T1M1 + vpxorq %%T1M2, %%T0M2, %%T1M2 + +%elif %%NUM_BLOCKS >= 12 + + vmovdqu64 %%HK, [%%KP + hashk] + vpclmulqdq %%T0H, %%CIPHER_IN0, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T0L, %%CIPHER_IN0, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T0M1, %%CIPHER_IN0, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T0M2, %%CIPHER_IN0, %%HK, 0x10 ; M2 = a0*b1 + vmovdqu64 %%HK, [%%KP + hashk + (1*64)] + vpclmulqdq %%T1H, %%CIPHER_IN1, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T1L, %%CIPHER_IN1, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T1M1, %%CIPHER_IN1, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T1M2, %%CIPHER_IN1, %%HK, 0x10 ; M2 = a0*b1 + vmovdqu64 %%HK, [%%KP + hashk + (2*64)] + vpclmulqdq %%CIPHER_IN0, %%CIPHER_IN2, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%CIPHER_IN1, %%CIPHER_IN2, %%HK, 0x00 ; L = a0*b0 + vpternlogq %%T1H, %%CIPHER_IN0, %%T0H, 0x96 + vpternlogq %%T1L, %%CIPHER_IN1, %%T0L, 0x96 + vpclmulqdq %%CIPHER_IN0, %%CIPHER_IN2, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%CIPHER_IN1, %%CIPHER_IN2, %%HK, 0x10 ; M2 = a0*b1 + vpternlogq %%T1M1, %%CIPHER_IN0, %%T0M1, 0x96 + vpternlogq %%T1M2, %%CIPHER_IN1, %%T0M2, 0x96 + +%elif %%NUM_BLOCKS >= 8 + + vmovdqu64 %%HK, [%%KP + hashk] + vpclmulqdq %%T0H, %%CIPHER_IN0, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T0L, %%CIPHER_IN0, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T0M1, %%CIPHER_IN0, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T0M2, %%CIPHER_IN0, %%HK, 0x10 ; M2 = a0*b1 + vmovdqu64 %%HK, [%%KP + hashk + (1*64)] + vpclmulqdq %%T1H, %%CIPHER_IN1, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T1L, %%CIPHER_IN1, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T1M1, %%CIPHER_IN1, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T1M2, %%CIPHER_IN1, %%HK, 0x10 ; M2 = a0*b1 + vpxorq %%T1H, %%T0H, %%T1H + vpxorq %%T1L, %%T0L, %%T1L + vpxorq %%T1M1, %%T0M1, %%T1M1 + vpxorq %%T1M2, %%T0M2, %%T1M2 + +%elif %%NUM_BLOCKS >= 4 + + vmovdqu64 %%HK, [%%KP + hashk] + vpclmulqdq %%T1H, %%CIPHER_IN0, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T1L, %%CIPHER_IN0, %%HK, 0x00 ; L = a0*b0 + vpclmulqdq %%T1M1, %%CIPHER_IN0, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T1M2, %%CIPHER_IN0, %%HK, 0x10 ; M2 = a0*b1 + +%endif + + ;; T1H/L/M1/M2 - hold current product sums (provided %%NUM_BLOCKS >= 4) +%assign blocks_left (%%NUM_BLOCKS % 4) + +%if blocks_left > 0 + ;; ===================================================== + ;; There are 1, 2 or 3 blocks left to process. + ;; It may also be that they are the only blocks to process. + +;; Set hash key and register index position for the remaining 1 to 3 blocks +%assign hashk HashKey_ %+ blocks_left +%assign reg_idx (%%NUM_BLOCKS / 4) + +%xdefine %%REG_IN %%CIPHER_IN %+ reg_idx + +%if blocks_left == 1 + vmovdqu64 XWORD(%%HK), [%%KP + hashk] + vpclmulqdq XWORD(%%T0M1), XWORD(%%REG_IN), XWORD(%%HK), 0x01 ; M1 = a1*b0 + vpclmulqdq XWORD(%%T0M2), XWORD(%%REG_IN), XWORD(%%HK), 0x10 ; M2 = a0*b1 + vpclmulqdq XWORD(%%T0H), XWORD(%%REG_IN), XWORD(%%HK), 0x11 ; H = a1*b1 + vpclmulqdq XWORD(%%T0L), XWORD(%%REG_IN), XWORD(%%HK), 0x00 ; L = a0*b0 +%elif blocks_left == 2 + vmovdqu64 YWORD(%%HK), [%%KP + hashk] + vpclmulqdq YWORD(%%T0M1), YWORD(%%REG_IN), YWORD(%%HK), 0x01 ; M1 = a1*b0 + vpclmulqdq YWORD(%%T0M2), YWORD(%%REG_IN), YWORD(%%HK), 0x10 ; M2 = a0*b1 + vpclmulqdq YWORD(%%T0H), YWORD(%%REG_IN), YWORD(%%HK), 0x11 ; H = a1*b1 + vpclmulqdq YWORD(%%T0L), YWORD(%%REG_IN), YWORD(%%HK), 0x00 ; L = a0*b0 +%else ; blocks_left == 3 + vmovdqu64 YWORD(%%HK), [%%KP + hashk] + vinserti64x2 %%HK, [%%KP + hashk + 32], 2 + vpclmulqdq %%T0M1, %%REG_IN, %%HK, 0x01 ; M1 = a1*b0 + vpclmulqdq %%T0M2, %%REG_IN, %%HK, 0x10 ; M2 = a0*b1 + vpclmulqdq %%T0H, %%REG_IN, %%HK, 0x11 ; H = a1*b1 + vpclmulqdq %%T0L, %%REG_IN, %%HK, 0x00 ; L = a0*b0 +%endif ; blocks_left + +%undef %%REG_IN + +%if %0 == 20 + ;; *** GH/GM/GL passed as arguments +%if %%NUM_BLOCKS >= 4 + ;; add ghash product sums from the first 4, 8 or 12 blocks + vpxorq %%T0M1, %%T0M1, %%T1M1 + vpternlogq %%T0M2, %%GM, %%T1M2, 0x96 + vpternlogq %%T0H, %%GH, %%T1H, 0x96 + vpternlogq %%T0L, %%GL, %%T1L, 0x96 +%else + vpxorq %%T0M1, %%T0M1, %%GM + vpxorq %%T0H, %%T0H, %%GH + vpxorq %%T0L, %%T0L, %%GL +%endif ;; %%NUM_BLOCKS >= 4 +%else + ;; *** GH/GM/GL NOT passed as arguments +%if %%NUM_BLOCKS >= 4 + ;; add ghash product sums from the first 4, 8 or 12 blocks + vpxorq %%T0M1, %%T0M1, %%T1M1 + vpxorq %%T0M2, %%T0M2, %%T1M2 + vpxorq %%T0H, %%T0H, %%T1H + vpxorq %%T0L, %%T0L, %%T1L +%endif ;; %%NUM_BLOCKS >= 4 +%endif ;; %0 == 20 + + ;; integrate TM into TH and TL + vpxorq %%T0M1, %%T0M1, %%T0M2 + vpsrldq %%T1M1, %%T0M1, 8 + vpslldq %%T1M2, %%T0M1, 8 + vpxorq %%T0H, %%T0H, %%T1M1 + vpxorq %%T0L, %%T0L, %%T1M2 +%else + ;; ===================================================== + ;; number of blocks is 4, 8, 12 or 16 + ;; T1H/L/M1/M2 include product sums not T0H/L/M1/M2 +%if %0 == 20 + ;; *** GH/GM/GL passed as arguments + vpxorq %%T1M1, %%T1M1, %%GM + vpxorq %%T1H, %%T1H, %%GH + vpxorq %%T1L, %%T1L, %%GL +%endif + ;; integrate TM into TH and TL + vpxorq %%T1M1, %%T1M1, %%T1M2 + vpsrldq %%T0M1, %%T1M1, 8 + vpslldq %%T0M2, %%T1M1, 8 + vpxorq %%T0H, %%T1H, %%T0M1 + vpxorq %%T0L, %%T1L, %%T0M2 +%endif ; blocks_left > 0 + + ;; add TH and TL 128-bit words horizontally + VHPXORI4x128 %%T0H, %%T1M1 + VHPXORI4x128 %%T0L, %%T1M2 + + ;; reduction + vmovdqa64 XWORD(%%HK), [rel POLY2] + VCLMUL_REDUCE XWORD(%%GHASH), XWORD(%%HK), \ + XWORD(%%T0H), XWORD(%%T0L), XWORD(%%T0M1), XWORD(%%T0M2) +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) +;;; Input: A and B (128-bits each, bit-reflected) +;;; Output: C = A*B*x mod poly, (i.e. >>1 ) +;;; To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input +;;; GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GHASH_MUL 7 +%define %%GH %1 ;; [in/out] xmm/ymm/zmm with multiply operand(s) (128-bits) +%define %%HK %2 ;; [in] xmm/ymm/zmm with hash key value(s) (128-bits) +%define %%T1 %3 ;; [clobbered] xmm/ymm/zmm +%define %%T2 %4 ;; [clobbered] xmm/ymm/zmm +%define %%T3 %5 ;; [clobbered] xmm/ymm/zmm +%define %%T4 %6 ;; [clobbered] xmm/ymm/zmm +%define %%T5 %7 ;; [clobbered] xmm/ymm/zmm + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + vpclmulqdq %%T1, %%GH, %%HK, 0x11 ; %%T1 = a1*b1 + vpclmulqdq %%T2, %%GH, %%HK, 0x00 ; %%T2 = a0*b0 + vpclmulqdq %%T3, %%GH, %%HK, 0x01 ; %%T3 = a1*b0 + vpclmulqdq %%GH, %%GH, %%HK, 0x10 ; %%GH = a0*b1 + vpxorq %%GH, %%GH, %%T3 + + + vpsrldq %%T3, %%GH, 8 ; shift-R %%GH 2 DWs + vpslldq %%GH, %%GH, 8 ; shift-L %%GH 2 DWs + + vpxorq %%T1, %%T1, %%T3 + vpxorq %%GH, %%GH, %%T2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction + vmovdqu64 %%T3, [rel POLY2] + + vpclmulqdq %%T2, %%T3, %%GH, 0x01 + vpslldq %%T2, %%T2, 8 ; shift-L %%T2 2 DWs + + vpxorq %%GH, %%GH, %%T2 ; first phase of the reduction complete + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;second phase of the reduction + vpclmulqdq %%T2, %%T3, %%GH, 0x00 + vpsrldq %%T2, %%T2, 4 ; shift-R only 1-DW to obtain 2-DWs shift-R + + vpclmulqdq %%GH, %%T3, %%GH, 0x10 + vpslldq %%GH, %%GH, 4 ; Shift-L 1-DW to obtain result with no shifts + + ; second phase of the reduction complete, the result is in %%GH + vpternlogq %%GH, %%T1, %%T2, 0x96 ; GH = GH xor T1 xor T2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; In PRECOMPUTE, the commands filling Hashkey_i_k are not required for avx512 +;;; functions, but are kept to allow users to switch cpu architectures between calls +;;; of pre, init, update, and finalize. +%macro PRECOMPUTE 10 +%define %%GDATA %1 ;; [in/out] GPR, pointer to GCM key data structure, content updated +%define %%HK %2 ;; [in] xmm, hash key +%define %%T1 %3 ;; [clobbered] xmm +%define %%T2 %4 ;; [clobbered] xmm +%define %%T3 %5 ;; [clobbered] xmm +%define %%T4 %6 ;; [clobbered] xmm +%define %%T5 %7 ;; [clobbered] xmm +%define %%T6 %8 ;; [clobbered] xmm +%define %%T7 %9 ;; [clobbered] xmm +%define %%T8 %10 ;; [clobbered] xmm + +%xdefine %%ZT1 ZWORD(%%T1) +%xdefine %%ZT2 ZWORD(%%T2) +%xdefine %%ZT3 ZWORD(%%T3) +%xdefine %%ZT4 ZWORD(%%T4) +%xdefine %%ZT5 ZWORD(%%T5) +%xdefine %%ZT6 ZWORD(%%T6) +%xdefine %%ZT7 ZWORD(%%T7) +%xdefine %%ZT8 ZWORD(%%T8) + + vmovdqa64 %%T5, %%HK + vinserti64x2 %%ZT7, %%HK, 3 + + ;; calculate HashKey^2<<1 mod poly + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 + vmovdqu64 [%%GDATA + HashKey_2], %%T5 + vinserti64x2 %%ZT7, %%T5, 2 + + ;; calculate HashKey^3<<1 mod poly + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 + vmovdqu64 [%%GDATA + HashKey_3], %%T5 + vinserti64x2 %%ZT7, %%T5, 1 + + ;; calculate HashKey^4<<1 mod poly + GHASH_MUL %%T5, %%HK, %%T1, %%T3, %%T4, %%T6, %%T2 + vmovdqu64 [%%GDATA + HashKey_4], %%T5 + vinserti64x2 %%ZT7, %%T5, 0 + + ;; switch to 4x128-bit computations now + vshufi64x2 %%ZT5, %%ZT5, %%ZT5, 0x00 ;; broadcast HashKey^4 across all ZT5 + vmovdqa64 %%ZT8, %%ZT7 ;; save HashKey^4 to HashKey^1 in ZT8 + + ;; calculate HashKey^5<<1 mod poly, HashKey^6<<1 mod poly, ... HashKey^8<<1 mod poly + GHASH_MUL %%ZT7, %%ZT5, %%ZT1, %%ZT3, %%ZT4, %%ZT6, %%ZT2 + vmovdqu64 [%%GDATA + HashKey_8], %%ZT7 ;; HashKey^8 to HashKey^5 in ZT7 now + vshufi64x2 %%ZT5, %%ZT7, %%ZT7, 0x00 ;; broadcast HashKey^8 across all ZT5 + + ;; calculate HashKey^9<<1 mod poly, HashKey^10<<1 mod poly, ... HashKey^48<<1 mod poly + ;; use HashKey^8 as multiplier against ZT8 and ZT7 - this allows deeper ooo execution +%assign i 12 +%rep ((48 - 8) / 8) + ;; compute HashKey^(4 + n), HashKey^(3 + n), ... HashKey^(1 + n) + GHASH_MUL %%ZT8, %%ZT5, %%ZT1, %%ZT3, %%ZT4, %%ZT6, %%ZT2 + vmovdqu64 [%%GDATA + HashKey_ %+ i], %%ZT8 +%assign i (i + 4) + + ;; compute HashKey^(8 + n), HashKey^(7 + n), ... HashKey^(5 + n) + GHASH_MUL %%ZT7, %%ZT5, %%ZT1, %%ZT3, %%ZT4, %%ZT6, %%ZT2 + vmovdqu64 [%%GDATA + HashKey_ %+ i], %%ZT7 +%assign i (i + 4) +%endrep +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; READ_SMALL_DATA_INPUT +;;; Packs xmm register with data when data input is less or equal to 16 bytes +;;; Returns 0 if data has length 0 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro READ_SMALL_DATA_INPUT 6 +%define %%OUTPUT %1 ; [out] xmm register +%define %%INPUT %2 ; [in] buffer pointer to read from +%define %%LENGTH %3 ; [in] number of bytes to read +%define %%TMP1 %4 ; [clobbered] +%define %%TMP2 %5 ; [clobbered] +%define %%MASK %6 ; [out] k1 to k7 register to store the partial block mask + + mov DWORD(%%TMP2), 16 + lea %%TMP1, [rel byte_len_to_mask_table] + cmp %%LENGTH, %%TMP2 + cmovb %%TMP2, %%LENGTH +%ifidn __OUTPUT_FORMAT__, win64 + add %%TMP1, %%TMP2 + add %%TMP1, %%TMP2 + kmovw %%MASK, [%%TMP1] +%else + kmovw %%MASK, [%%TMP1 + %%TMP2*2] +%endif + vmovdqu8 %%OUTPUT{%%MASK}{z}, [%%INPUT] +%endmacro ; READ_SMALL_DATA_INPUT + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CALC_AAD_HASH: Calculates the hash of the data which will not be encrypted. +; Input: The input data (A_IN), that data's length (A_LEN), and the hash key (HASH_KEY). +; Output: The hash of the data (AAD_HASH). +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro CALC_AAD_HASH 26 +%define %%A_IN %1 ; [in] AAD text pointer +%define %%A_LEN %2 ; [in] AAD length +%define %%AAD_HASH %3 ; [in/out] xmm ghash value +%define %%GDATA_KEY %4 ; [in] pointer to keys +%define %%ZT0 %5 ; [clobbered] ZMM register +%define %%ZT1 %6 ; [clobbered] ZMM register +%define %%ZT2 %7 ; [clobbered] ZMM register +%define %%ZT3 %8 ; [clobbered] ZMM register +%define %%ZT4 %9 ; [clobbered] ZMM register +%define %%ZT5 %10 ; [clobbered] ZMM register +%define %%ZT6 %11 ; [clobbered] ZMM register +%define %%ZT7 %12 ; [clobbered] ZMM register +%define %%ZT8 %13 ; [clobbered] ZMM register +%define %%ZT9 %14 ; [clobbered] ZMM register +%define %%ZT10 %15 ; [clobbered] ZMM register +%define %%ZT11 %16 ; [clobbered] ZMM register +%define %%ZT12 %17 ; [clobbered] ZMM register +%define %%ZT13 %18 ; [clobbered] ZMM register +%define %%ZT14 %19 ; [clobbered] ZMM register +%define %%ZT15 %20 ; [clobbered] ZMM register +%define %%ZT16 %21 ; [clobbered] ZMM register +%define %%ZT17 %22 ; [clobbered] ZMM register +%define %%T1 %23 ; [clobbered] GP register +%define %%T2 %24 ; [clobbered] GP register +%define %%T3 %25 ; [clobbered] GP register +%define %%MASKREG %26 ; [clobbered] mask register + +%define %%SHFMSK %%ZT13 + + mov %%T1, %%A_IN ; T1 = AAD + mov %%T2, %%A_LEN ; T2 = aadLen + + or %%T2, %%T2 + jz %%_CALC_AAD_done + + vmovdqa64 %%SHFMSK, [rel SHUF_MASK] + +%%_get_AAD_loop48x16: + cmp %%T2, (48*16) + jl %%_exit_AAD_loop48x16 + + vmovdqu64 %%ZT1, [%%T1 + 64*0] ; Blocks 0-3 + vmovdqu64 %%ZT2, [%%T1 + 64*1] ; Blocks 4-7 + vmovdqu64 %%ZT3, [%%T1 + 64*2] ; Blocks 8-11 + vmovdqu64 %%ZT4, [%%T1 + 64*3] ; Blocks 12-15 + vpshufb %%ZT1, %%SHFMSK + vpshufb %%ZT2, %%SHFMSK + vpshufb %%ZT3, %%SHFMSK + vpshufb %%ZT4, %%SHFMSK + + GHASH_16 start, %%ZT5, %%ZT6, %%ZT7, \ + NO_INPUT_PTR, NO_INPUT_PTR, NO_INPUT_PTR, \ + %%GDATA_KEY, HashKey_48, 0, ZWORD(%%AAD_HASH), \ + %%ZT0, %%ZT8, %%ZT9, %%ZT10, %%ZT11, %%ZT12, \ + %%ZT14, %%ZT15, %%ZT16, NO_ZMM, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4 + + vmovdqu64 %%ZT1, [%%T1 + 16*16 + 64*0] ; Blocks 16-19 + vmovdqu64 %%ZT2, [%%T1 + 16*16 + 64*1] ; Blocks 20-23 + vmovdqu64 %%ZT3, [%%T1 + 16*16 + 64*2] ; Blocks 24-27 + vmovdqu64 %%ZT4, [%%T1 + 16*16 + 64*3] ; Blocks 28-31 + vpshufb %%ZT1, %%SHFMSK + vpshufb %%ZT2, %%SHFMSK + vpshufb %%ZT3, %%SHFMSK + vpshufb %%ZT4, %%SHFMSK + + GHASH_16 mid, %%ZT5, %%ZT6, %%ZT7, \ + NO_INPUT_PTR, NO_INPUT_PTR, NO_INPUT_PTR, \ + %%GDATA_KEY, HashKey_32, 0, NO_HASH_IN_OUT, \ + %%ZT0, %%ZT8, %%ZT9, %%ZT10, %%ZT11, %%ZT12, \ + %%ZT14, %%ZT15, %%ZT16, NO_ZMM, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4 + + vmovdqu64 %%ZT1, [%%T1 + 32*16 + 64*0] ; Blocks 32-35 + vmovdqu64 %%ZT2, [%%T1 + 32*16 + 64*1] ; Blocks 36-39 + vmovdqu64 %%ZT3, [%%T1 + 32*16 + 64*2] ; Blocks 40-43 + vmovdqu64 %%ZT4, [%%T1 + 32*16 + 64*3] ; Blocks 44-47 + vpshufb %%ZT1, %%SHFMSK + vpshufb %%ZT2, %%SHFMSK + vpshufb %%ZT3, %%SHFMSK + vpshufb %%ZT4, %%SHFMSK + + GHASH_16 end_reduce, %%ZT5, %%ZT6, %%ZT7, \ + NO_INPUT_PTR, NO_INPUT_PTR, NO_INPUT_PTR, \ + %%GDATA_KEY, HashKey_16, 0, ZWORD(%%AAD_HASH), \ + %%ZT0, %%ZT8, %%ZT9, %%ZT10, %%ZT11, %%ZT12, \ + %%ZT14, %%ZT15, %%ZT16, NO_ZMM, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4 + + sub %%T2, (48*16) + je %%_CALC_AAD_done + + add %%T1, (48*16) + jmp %%_get_AAD_loop48x16 + +%%_exit_AAD_loop48x16: + ; Less than 48x16 bytes remaining + cmp %%T2, (32*16) + jl %%_less_than_32x16 + + ; Get next 16 blocks + vmovdqu64 %%ZT1, [%%T1 + 64*0] + vmovdqu64 %%ZT2, [%%T1 + 64*1] + vmovdqu64 %%ZT3, [%%T1 + 64*2] + vmovdqu64 %%ZT4, [%%T1 + 64*3] + vpshufb %%ZT1, %%SHFMSK + vpshufb %%ZT2, %%SHFMSK + vpshufb %%ZT3, %%SHFMSK + vpshufb %%ZT4, %%SHFMSK + + GHASH_16 start, %%ZT5, %%ZT6, %%ZT7, \ + NO_INPUT_PTR, NO_INPUT_PTR, NO_INPUT_PTR, \ + %%GDATA_KEY, HashKey_32, 0, ZWORD(%%AAD_HASH), \ + %%ZT0, %%ZT8, %%ZT9, %%ZT10, %%ZT11, %%ZT12, \ + %%ZT14, %%ZT15, %%ZT16, NO_ZMM, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4 + + vmovdqu64 %%ZT1, [%%T1 + 16*16 + 64*0] + vmovdqu64 %%ZT2, [%%T1 + 16*16 + 64*1] + vmovdqu64 %%ZT3, [%%T1 + 16*16 + 64*2] + vmovdqu64 %%ZT4, [%%T1 + 16*16 + 64*3] + vpshufb %%ZT1, %%SHFMSK + vpshufb %%ZT2, %%SHFMSK + vpshufb %%ZT3, %%SHFMSK + vpshufb %%ZT4, %%SHFMSK + + GHASH_16 end_reduce, %%ZT5, %%ZT6, %%ZT7, \ + NO_INPUT_PTR, NO_INPUT_PTR, NO_INPUT_PTR, \ + %%GDATA_KEY, HashKey_16, 0, ZWORD(%%AAD_HASH), \ + %%ZT0, %%ZT8, %%ZT9, %%ZT10, %%ZT11, %%ZT12, \ + %%ZT14, %%ZT15, %%ZT16, NO_ZMM, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4 + + sub %%T2, (32*16) + je %%_CALC_AAD_done + + add %%T1, (32*16) + jmp %%_less_than_16x16 + +%%_less_than_32x16: + cmp %%T2, (16*16) + jl %%_less_than_16x16 + ; Get next 16 blocks + vmovdqu64 %%ZT1, [%%T1 + 64*0] + vmovdqu64 %%ZT2, [%%T1 + 64*1] + vmovdqu64 %%ZT3, [%%T1 + 64*2] + vmovdqu64 %%ZT4, [%%T1 + 64*3] + vpshufb %%ZT1, %%SHFMSK + vpshufb %%ZT2, %%SHFMSK + vpshufb %%ZT3, %%SHFMSK + vpshufb %%ZT4, %%SHFMSK + + GHASH_16 start_reduce, %%ZT5, %%ZT6, %%ZT7, \ + NO_INPUT_PTR, NO_INPUT_PTR, NO_INPUT_PTR, \ + %%GDATA_KEY, HashKey_16, 0, ZWORD(%%AAD_HASH), \ + %%ZT0, %%ZT8, %%ZT9, %%ZT10, %%ZT11, %%ZT12, \ + %%ZT14, %%ZT15, %%ZT16, NO_ZMM, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4 + + sub %%T2, (16*16) + je %%_CALC_AAD_done + + add %%T1, (16*16) + + ; Less than 16x16 bytes remaining +%%_less_than_16x16: + ;; prep mask source address + lea %%T3, [rel byte64_len_to_mask_table] + lea %%T3, [%%T3 + %%T2*8] + + ;; calculate number of blocks to ghash (including partial bytes) + add DWORD(%%T2), 15 + shr DWORD(%%T2), 4 + cmp DWORD(%%T2), 2 + jb %%_AAD_blocks_1 + je %%_AAD_blocks_2 + cmp DWORD(%%T2), 4 + jb %%_AAD_blocks_3 + je %%_AAD_blocks_4 + cmp DWORD(%%T2), 6 + jb %%_AAD_blocks_5 + je %%_AAD_blocks_6 + cmp DWORD(%%T2), 8 + jb %%_AAD_blocks_7 + je %%_AAD_blocks_8 + cmp DWORD(%%T2), 10 + jb %%_AAD_blocks_9 + je %%_AAD_blocks_10 + cmp DWORD(%%T2), 12 + jb %%_AAD_blocks_11 + je %%_AAD_blocks_12 + cmp DWORD(%%T2), 14 + jb %%_AAD_blocks_13 + je %%_AAD_blocks_14 + cmp DWORD(%%T2), 15 + je %%_AAD_blocks_15 + ;; fall through for 16 blocks + + ;; The flow of each of these cases is identical: + ;; - load blocks plain text + ;; - shuffle loaded blocks + ;; - xor in current hash value into block 0 + ;; - perform up multiplications with ghash keys + ;; - jump to reduction code + +%assign I 16 + ;; generate all 16 cases using preprocessor +%rep 16 + +%%_AAD_blocks_ %+ I: +%if I > 12 + sub %%T3, 12 * 16 * 8 +%elif I > 8 + sub %%T3, 8 * 16 * 8 +%elif I > 4 + sub %%T3, 4 * 16 * 8 +%endif + kmovq %%MASKREG, [%%T3] + + ZMM_LOAD_MASKED_BLOCKS_0_16 \ + I, %%T1, 0, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4, %%MASKREG + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 \ + I, vpshufb, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%SHFMSK, %%SHFMSK, %%SHFMSK, %%SHFMSK + + GHASH_1_TO_16 %%GDATA_KEY, ZWORD(%%AAD_HASH), \ + %%ZT0, %%ZT5, %%ZT6, %%ZT7, %%ZT8, \ + %%ZT9, %%ZT10, %%ZT11, %%ZT12, \ + ZWORD(%%AAD_HASH), %%ZT1, %%ZT2, %%ZT3, %%ZT4, I +%if I > 1 + ;; fall through to CALC_AAD_done in 1 block case + jmp %%_CALC_AAD_done +%endif + +%assign I (I - 1) +%endrep + +%%_CALC_AAD_done: + ;; result in AAD_HASH + +%endmacro ; CALC_AAD_HASH + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; PARTIAL_BLOCK +;;; Handles encryption/decryption and the tag partial blocks between +;;; update calls. +;;; Requires the input data be at least 1 byte long. +;;; Output: +;;; A cipher/plain of the first partial block (CIPH_PLAIN_OUT), +;;; AAD_HASH and updated GDATA_CTX +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro PARTIAL_BLOCK 22 +%define %%GDATA_KEY %1 ; [in] key pointer +%define %%GDATA_CTX %2 ; [in] context pointer +%define %%CIPH_PLAIN_OUT %3 ; [in] output buffer +%define %%PLAIN_CIPH_IN %4 ; [in] input buffer +%define %%PLAIN_CIPH_LEN %5 ; [in] buffer length +%define %%DATA_OFFSET %6 ; [out] data offset (gets set) +%define %%AAD_HASH %7 ; [out] updated GHASH value +%define %%ENC_DEC %8 ; [in] cipher direction +%define %%GPTMP0 %9 ; [clobbered] GP temporary register +%define %%GPTMP1 %10 ; [clobbered] GP temporary register +%define %%GPTMP2 %11 ; [clobbered] GP temporary register +%define %%ZTMP0 %12 ; [clobbered] ZMM temporary register +%define %%ZTMP1 %13 ; [clobbered] ZMM temporary register +%define %%ZTMP2 %14 ; [clobbered] ZMM temporary register +%define %%ZTMP3 %15 ; [clobbered] ZMM temporary register +%define %%ZTMP4 %16 ; [clobbered] ZMM temporary register +%define %%ZTMP5 %17 ; [clobbered] ZMM temporary register +%define %%ZTMP6 %18 ; [clobbered] ZMM temporary register +%define %%ZTMP7 %19 ; [clobbered] ZMM temporary register +%define %%ZTMP8 %20 ; [clobbered] ZMM temporary register +%define %%ZTMP9 %21 ; [clobbered] ZMM temporary register +%define %%MASKREG %22 ; [clobbered] mask temporary register + +%define %%XTMP0 XWORD(%%ZTMP0) +%define %%XTMP1 XWORD(%%ZTMP1) +%define %%XTMP2 XWORD(%%ZTMP2) +%define %%XTMP3 XWORD(%%ZTMP3) +%define %%XTMP4 XWORD(%%ZTMP4) +%define %%XTMP5 XWORD(%%ZTMP5) +%define %%XTMP6 XWORD(%%ZTMP6) +%define %%XTMP7 XWORD(%%ZTMP7) +%define %%XTMP8 XWORD(%%ZTMP8) +%define %%XTMP9 XWORD(%%ZTMP9) + +%define %%LENGTH %%DATA_OFFSET +%define %%IA0 %%GPTMP1 +%define %%IA1 %%GPTMP2 +%define %%IA2 %%GPTMP0 + + ;; if no partial block present then LENGTH/DATA_OFFSET will be set to zero + mov %%LENGTH, [%%GDATA_CTX + PBlockLen] + or %%LENGTH, %%LENGTH + je %%_partial_block_done ;Leave Macro if no partial blocks + + READ_SMALL_DATA_INPUT %%XTMP0, %%PLAIN_CIPH_IN, %%PLAIN_CIPH_LEN, %%IA0, %%IA2, %%MASKREG + + ;; XTMP1 = my_ctx_data.partial_block_enc_key + vmovdqu64 %%XTMP1, [%%GDATA_CTX + PBlockEncKey] + vmovdqu64 %%XTMP2, [%%GDATA_KEY + HashKey] + + ;; adjust the shuffle mask pointer to be able to shift right %%LENGTH bytes + ;; (16 - %%LENGTH) is the number of bytes in plaintext mod 16) + lea %%IA0, [rel SHIFT_MASK] + add %%IA0, %%LENGTH + vmovdqu64 %%XTMP3, [%%IA0] ; shift right shuffle mask + vpshufb %%XTMP1, %%XTMP3 + +%ifidn %%ENC_DEC, DEC + ;; keep copy of cipher text in %%XTMP4 + vmovdqa64 %%XTMP4, %%XTMP0 +%endif + vpxorq %%XTMP1, %%XTMP0 ; Ciphertext XOR E(K, Yn) + + ;; Set %%IA1 to be the amount of data left in CIPH_PLAIN_IN after filling the block + ;; Determine if partial block is not being filled and shift mask accordingly +%ifidn __OUTPUT_FORMAT__, win64 + mov %%IA1, %%PLAIN_CIPH_LEN + add %%IA1, %%LENGTH +%else + lea %%IA1, [%%PLAIN_CIPH_LEN + %%LENGTH] +%endif + sub %%IA1, 16 + jge %%_no_extra_mask + sub %%IA0, %%IA1 +%%_no_extra_mask: + ;; get the appropriate mask to mask out bottom %%LENGTH bytes of %%XTMP1 + ;; - mask out bottom %%LENGTH bytes of %%XTMP1 + vmovdqu64 %%XTMP0, [%%IA0 + ALL_F - SHIFT_MASK] + vpand %%XTMP1, %%XTMP0 + +%ifidn %%ENC_DEC, DEC + vpand %%XTMP4, %%XTMP0 + vpshufb %%XTMP4, [rel SHUF_MASK] + vpshufb %%XTMP4, %%XTMP3 + vpxorq %%AAD_HASH, %%XTMP4 +%else + vpshufb %%XTMP1, [rel SHUF_MASK] + vpshufb %%XTMP1, %%XTMP3 + vpxorq %%AAD_HASH, %%XTMP1 +%endif + cmp %%IA1, 0 + jl %%_partial_incomplete + + ;; GHASH computation for the last <16 Byte block + GHASH_MUL %%AAD_HASH, %%XTMP2, %%XTMP5, %%XTMP6, %%XTMP7, %%XTMP8, %%XTMP9 + + mov qword [%%GDATA_CTX + PBlockLen], 0 + + ;; Set %%LENGTH to be the number of bytes to write out + mov %%IA0, %%LENGTH + mov %%LENGTH, 16 + sub %%LENGTH, %%IA0 + jmp %%_enc_dec_done + +%%_partial_incomplete: +%ifidn __OUTPUT_FORMAT__, win64 + mov %%IA0, %%PLAIN_CIPH_LEN + add [%%GDATA_CTX + PBlockLen], %%IA0 +%else + add [%%GDATA_CTX + PBlockLen], %%PLAIN_CIPH_LEN +%endif + mov %%LENGTH, %%PLAIN_CIPH_LEN + +%%_enc_dec_done: + ;; output encrypted Bytes + + lea %%IA0, [rel byte_len_to_mask_table] + kmovw %%MASKREG, [%%IA0 + %%LENGTH*2] + vmovdqu64 [%%GDATA_CTX + AadHash], %%AAD_HASH + +%ifidn %%ENC_DEC, ENC + ;; shuffle XTMP1 back to output as ciphertext + vpshufb %%XTMP1, [rel SHUF_MASK] + vpshufb %%XTMP1, %%XTMP3 +%endif + vmovdqu8 [%%CIPH_PLAIN_OUT]{%%MASKREG}, %%XTMP1 +%%_partial_block_done: +%endmacro ; PARTIAL_BLOCK + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Ciphers 1 to 16 blocks and prepares them for later GHASH compute operation +%macro INITIAL_BLOCKS_PARTIAL_CIPHER 25 +%define %%GDATA_KEY %1 ; [in] key pointer +%define %%GDATA_CTX %2 ; [in] context pointer +%define %%CIPH_PLAIN_OUT %3 ; [in] text output pointer +%define %%PLAIN_CIPH_IN %4 ; [in] text input pointer +%define %%LENGTH %5 ; [in/clobbered] length in bytes +%define %%DATA_OFFSET %6 ; [in/out] current data offset (updated) +%define %%NUM_BLOCKS %7 ; [in] can only be 1, 2, 3, 4, 5, ..., 15 or 16 (not 0) +%define %%CTR %8 ; [in/out] current counter value +%define %%ENC_DEC %9 ; [in] cipher direction (ENC/DEC) +%define %%INSTANCE_TYPE %10 ; [in] multi_call or single_call +%define %%DAT0 %11 ; [out] ZMM with cipher text shuffled for GHASH +%define %%DAT1 %12 ; [out] ZMM with cipher text shuffled for GHASH +%define %%DAT2 %13 ; [out] ZMM with cipher text shuffled for GHASH +%define %%DAT3 %14 ; [out] ZMM with cipher text shuffled for GHASH +%define %%LAST_CIPHER_BLK %15 ; [out] XMM to put ciphered counter block partially xor'ed with text +%define %%LAST_GHASH_BLK %16 ; [out] XMM to put last cipher text block shuffled for GHASH +%define %%CTR0 %17 ; [clobbered] ZMM temporary +%define %%CTR1 %18 ; [clobbered] ZMM temporary +%define %%CTR2 %19 ; [clobbered] ZMM temporary +%define %%CTR3 %20 ; [clobbered] ZMM temporary +%define %%ZT1 %21 ; [clobbered] ZMM temporary +%define %%IA0 %22 ; [clobbered] GP temporary +%define %%IA1 %23 ; [clobbered] GP temporary +%define %%MASKREG %24 ; [clobbered] mask register +%define %%SHUFMASK %25 ; [out] ZMM loaded with BE/LE shuffle mask + +%if %%NUM_BLOCKS == 1 + vmovdqa64 XWORD(%%SHUFMASK), [rel SHUF_MASK] +%elif %%NUM_BLOCKS == 2 + vmovdqa64 YWORD(%%SHUFMASK), [rel SHUF_MASK] +%else + vmovdqa64 %%SHUFMASK, [rel SHUF_MASK] +%endif + ;; prepare AES counter blocks +%if %%NUM_BLOCKS == 1 + vpaddd XWORD(%%CTR0), %%CTR, [rel ONE] +%elif %%NUM_BLOCKS == 2 + vshufi64x2 YWORD(%%CTR0), YWORD(%%CTR), YWORD(%%CTR), 0 + vpaddd YWORD(%%CTR0), YWORD(%%CTR0), [rel ddq_add_1234] +%else + vshufi64x2 ZWORD(%%CTR), ZWORD(%%CTR), ZWORD(%%CTR), 0 + vpaddd %%CTR0, ZWORD(%%CTR), [rel ddq_add_1234] +%if %%NUM_BLOCKS > 4 + vpaddd %%CTR1, ZWORD(%%CTR), [rel ddq_add_5678] +%endif +%if %%NUM_BLOCKS > 8 + vpaddd %%CTR2, %%CTR0, [rel ddq_add_8888] +%endif +%if %%NUM_BLOCKS > 12 + vpaddd %%CTR3, %%CTR1, [rel ddq_add_8888] +%endif +%endif + + ;; get load/store mask + lea %%IA0, [rel byte64_len_to_mask_table] + mov %%IA1, %%LENGTH +%if %%NUM_BLOCKS > 12 + sub %%IA1, 3 * 64 +%elif %%NUM_BLOCKS > 8 + sub %%IA1, 2 * 64 +%elif %%NUM_BLOCKS > 4 + sub %%IA1, 64 +%endif + kmovq %%MASKREG, [%%IA0 + %%IA1*8] + + ;; extract new counter value + ;; shuffle the counters for AES rounds +%ifidn %%INSTANCE_TYPE, multi_call +%if %%NUM_BLOCKS <= 4 + vextracti32x4 %%CTR, %%CTR0, (%%NUM_BLOCKS - 1) +%elif %%NUM_BLOCKS <= 8 + vextracti32x4 %%CTR, %%CTR1, (%%NUM_BLOCKS - 5) +%elif %%NUM_BLOCKS <= 12 + vextracti32x4 %%CTR, %%CTR2, (%%NUM_BLOCKS - 9) +%else + vextracti32x4 %%CTR, %%CTR3, (%%NUM_BLOCKS - 13) +%endif +%endif + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpshufb, \ + %%CTR0, %%CTR1, %%CTR2, %%CTR3, \ + %%CTR0, %%CTR1, %%CTR2, %%CTR3, \ + %%SHUFMASK, %%SHUFMASK, %%SHUFMASK, %%SHUFMASK + + ;; load plain/cipher text + ZMM_LOAD_MASKED_BLOCKS_0_16 %%NUM_BLOCKS, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, %%MASKREG + + ;; AES rounds and XOR with plain/cipher text +%assign j 0 +%rep (NROUNDS + 2) + vbroadcastf64x2 %%ZT1, [%%GDATA_KEY + (j * 16)] + ZMM_AESENC_ROUND_BLOCKS_0_16 %%CTR0, %%CTR1, %%CTR2, %%CTR3, \ + %%ZT1, j, \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, \ + %%NUM_BLOCKS, NROUNDS +%assign j (j + 1) +%endrep + +%ifidn %%INSTANCE_TYPE, multi_call + ;; retrieve the last cipher counter block (partially XOR'ed with text) + ;; - this is needed for partial block cases +%if %%NUM_BLOCKS <= 4 + vextracti32x4 %%LAST_CIPHER_BLK, %%CTR0, (%%NUM_BLOCKS - 1) +%elif %%NUM_BLOCKS <= 8 + vextracti32x4 %%LAST_CIPHER_BLK, %%CTR1, (%%NUM_BLOCKS - 5) +%elif %%NUM_BLOCKS <= 12 + vextracti32x4 %%LAST_CIPHER_BLK, %%CTR2, (%%NUM_BLOCKS - 9) +%else + vextracti32x4 %%LAST_CIPHER_BLK, %%CTR3, (%%NUM_BLOCKS - 13) +%endif +%endif + ;; write cipher/plain text back to output and + ZMM_STORE_MASKED_BLOCKS_0_16 %%NUM_BLOCKS, %%CIPH_PLAIN_OUT, %%DATA_OFFSET, \ + %%CTR0, %%CTR1, %%CTR2, %%CTR3, %%MASKREG + + ;; zero bytes outside the mask before hashing +%if %%NUM_BLOCKS <= 4 + vmovdqu8 %%CTR0{%%MASKREG}{z}, %%CTR0 +%elif %%NUM_BLOCKS <= 8 + vmovdqu8 %%CTR1{%%MASKREG}{z}, %%CTR1 +%elif %%NUM_BLOCKS <= 12 + vmovdqu8 %%CTR2{%%MASKREG}{z}, %%CTR2 +%else + vmovdqu8 %%CTR3{%%MASKREG}{z}, %%CTR3 +%endif + + ;; Shuffle the cipher text blocks for hashing part + ;; ZT5 and ZT6 are expected outputs with blocks for hashing +%ifidn %%ENC_DEC, DEC + ;; Decrypt case + ;; - cipher blocks are in ZT5 & ZT6 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpshufb, \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, \ + %%SHUFMASK, %%SHUFMASK, %%SHUFMASK, %%SHUFMASK +%else + ;; Encrypt case + ;; - cipher blocks are in CTR0-CTR3 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpshufb, \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, \ + %%CTR0, %%CTR1, %%CTR2, %%CTR3, \ + %%SHUFMASK, %%SHUFMASK, %%SHUFMASK, %%SHUFMASK +%endif ; Encrypt + +%ifidn %%INSTANCE_TYPE, multi_call + ;; Extract the last block for partials and multi_call cases +%if %%NUM_BLOCKS <= 4 + vextracti32x4 %%LAST_GHASH_BLK, %%DAT0, %%NUM_BLOCKS - 1 +%elif %%NUM_BLOCKS <= 8 + vextracti32x4 %%LAST_GHASH_BLK, %%DAT1, %%NUM_BLOCKS - 5 +%elif %%NUM_BLOCKS <= 12 + vextracti32x4 %%LAST_GHASH_BLK, %%DAT2, %%NUM_BLOCKS - 9 +%else + vextracti32x4 %%LAST_GHASH_BLK, %%DAT3, %%NUM_BLOCKS - 13 +%endif +%endif + +%endmacro ; INITIAL_BLOCKS_PARTIAL_CIPHER + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Computes GHASH on 1 to 16 blocks +%macro INITIAL_BLOCKS_PARTIAL_GHASH 22-25 +%define %%GDATA_KEY %1 ; [in] key pointer +%define %%GDATA_CTX %2 ; [in] context pointer +%define %%LENGTH %3 ; [in/clobbered] length in bytes +%define %%NUM_BLOCKS %4 ; [in] can only be 1, 2, 3, 4, 5, ..., 15 or 16 (not 0) +%define %%HASH_IN_OUT %5 ; [in/out] XMM ghash in/out value +%define %%ENC_DEC %6 ; [in] cipher direction (ENC/DEC) +%define %%INSTANCE_TYPE %7 ; [in] multi_call or single_call +%define %%DAT0 %8 ; [in] ZMM with cipher text shuffled for GHASH +%define %%DAT1 %9 ; [in] ZMM with cipher text shuffled for GHASH +%define %%DAT2 %10 ; [in] ZMM with cipher text shuffled for GHASH +%define %%DAT3 %11 ; [in] ZMM with cipher text shuffled for GHASH +%define %%LAST_CIPHER_BLK %12 ; [in] XMM with ciphered counter block partially xor'ed with text +%define %%LAST_GHASH_BLK %13 ; [in] XMM with last cipher text block shuffled for GHASH +%define %%ZT0 %14 ; [clobbered] ZMM temporary +%define %%ZT1 %15 ; [clobbered] ZMM temporary +%define %%ZT2 %16 ; [clobbered] ZMM temporary +%define %%ZT3 %17 ; [clobbered] ZMM temporary +%define %%ZT4 %18 ; [clobbered] ZMM temporary +%define %%ZT5 %19 ; [clobbered] ZMM temporary +%define %%ZT6 %20 ; [clobbered] ZMM temporary +%define %%ZT7 %21 ; [clobbered] ZMM temporary +%define %%ZT8 %22 ; [clobbered] ZMM temporary +%define %%GH %23 ; [in] ZMM with hi product part +%define %%GM %24 ; [in] ZMM with mid prodcut part +%define %%GL %25 ; [in] ZMM with lo product part + + +%ifidn %%INSTANCE_TYPE, single_call + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;; SINGLE CALL case + ;;; - hash all data including partial block + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%if %0 == 22 + ;; start GHASH compute + GHASH_1_TO_16 %%GDATA_KEY, %%HASH_IN_OUT, \ + %%ZT0, %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%ZT5, %%ZT6, %%ZT7, %%ZT8, ZWORD(%%HASH_IN_OUT), \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, %%NUM_BLOCKS +%elif %0 == 25 + ;; continue GHASH compute + GHASH_1_TO_16 %%GDATA_KEY, %%HASH_IN_OUT, \ + %%ZT0, %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%ZT5, %%ZT6, %%ZT7, %%ZT8, ZWORD(%%HASH_IN_OUT), \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, %%NUM_BLOCKS, %%GH, %%GM, %%GL +%endif + +%else + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;; MULTI CALL (SGL) case + ;;; - hash all but the last partial block of data + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; update data offset +%if %%NUM_BLOCKS > 1 + ;; The final block of data may be <16B + sub %%LENGTH, 16 * (%%NUM_BLOCKS - 1) +%endif + +%if %%NUM_BLOCKS < 16 + ;; NOTE: the 'jl' is always taken for num_initial_blocks = 16. + ;; This is run in the context of GCM_ENC_DEC_SMALL for length < 256. + cmp %%LENGTH, 16 + jl %%_small_initial_partial_block + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;; Handle a full length final block - encrypt and hash all blocks + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + sub %%LENGTH, 16 + mov qword [%%GDATA_CTX + PBlockLen], 0 + + ;; Hash all of the data +%if %0 == 22 + ;; start GHASH compute + GHASH_1_TO_16 %%GDATA_KEY, %%HASH_IN_OUT, \ + %%ZT0, %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%ZT5, %%ZT6, %%ZT7, %%ZT8, ZWORD(%%HASH_IN_OUT), \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, %%NUM_BLOCKS +%elif %0 == 25 + ;; continue GHASH compute + GHASH_1_TO_16 %%GDATA_KEY, %%HASH_IN_OUT, \ + %%ZT0, %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%ZT5, %%ZT6, %%ZT7, %%ZT8, ZWORD(%%HASH_IN_OUT), \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, %%NUM_BLOCKS, %%GH, %%GM, %%GL +%endif + jmp %%_small_initial_compute_done +%endif ; %if %%NUM_BLOCKS < 16 + +%%_small_initial_partial_block: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;; Handle ghash for a <16B final block + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;; In this case if it's a single call to encrypt we can + ;; hash all of the data but if it's an init / update / finalize + ;; series of call we need to leave the last block if it's + ;; less than a full block of data. + + mov [%%GDATA_CTX + PBlockLen], %%LENGTH + vmovdqu64 [%%GDATA_CTX + PBlockEncKey], %%LAST_CIPHER_BLK + +%assign k (%%NUM_BLOCKS - 1) +%assign last_block_to_hash 1 + +%if (%%NUM_BLOCKS > last_block_to_hash) + + ;; ZT12-ZT20 - temporary registers +%if %0 == 22 + ;; start GHASH compute + GHASH_1_TO_16 %%GDATA_KEY, %%HASH_IN_OUT, \ + %%ZT0, %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%ZT5, %%ZT6, %%ZT7, %%ZT8, ZWORD(%%HASH_IN_OUT), \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, k +%elif %0 == 25 + ;; continue GHASH compute + GHASH_1_TO_16 %%GDATA_KEY, %%HASH_IN_OUT, \ + %%ZT0, %%ZT1, %%ZT2, %%ZT3, %%ZT4, \ + %%ZT5, %%ZT6, %%ZT7, %%ZT8, ZWORD(%%HASH_IN_OUT), \ + %%DAT0, %%DAT1, %%DAT2, %%DAT3, k, %%GH, %%GM, %%GL +%endif + ;; just fall through no jmp needed +%else + +%if %0 == 25 + ;; Reduction is required in this case. + ;; Integrate GM into GH and GL. + vpsrldq %%ZT0, %%GM, 8 + vpslldq %%ZT1, %%GM, 8 + vpxorq %%GH, %%GH, %%ZT0 + vpxorq %%GL, %%GL, %%ZT1 + + ;; Add GH and GL 128-bit words horizontally + VHPXORI4x128 %%GH, %%ZT0 + VHPXORI4x128 %%GL, %%ZT1 + + ;; 256-bit to 128-bit reduction + vmovdqa64 XWORD(%%ZT0), [rel POLY2] + VCLMUL_REDUCE XWORD(%%HASH_IN_OUT), XWORD(%%ZT0), \ + XWORD(%%GH), XWORD(%%GL), XWORD(%%ZT1), XWORD(%%ZT2) +%endif + ;; Record that a reduction is not needed - + ;; In this case no hashes are computed because there + ;; is only one initial block and it is < 16B in length. + ;; We only need to check if a reduction is needed if + ;; initial_blocks == 1 and init/update/final is being used. + ;; In this case we may just have a partial block, and that + ;; gets hashed in finalize. + + ;; The hash should end up in HASH_IN_OUT. + ;; The only way we should get here is if there is + ;; a partial block of data, so xor that into the hash. + vpxorq %%HASH_IN_OUT, %%HASH_IN_OUT, %%LAST_GHASH_BLK + ;; The result is in %%HASH_IN_OUT + jmp %%_after_reduction +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; After GHASH reduction +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%%_small_initial_compute_done: + ;; If using init/update/finalize, we need to xor any partial block data + ;; into the hash. +%if %%NUM_BLOCKS > 1 + ;; NOTE: for %%NUM_BLOCKS = 0 the xor never takes place +%if %%NUM_BLOCKS != 16 + ;; NOTE: for %%NUM_BLOCKS = 16, %%LENGTH, stored in [PBlockLen] is never zero + or %%LENGTH, %%LENGTH + je %%_after_reduction +%endif ; %%NUM_BLOCKS != 16 + vpxorq %%HASH_IN_OUT, %%HASH_IN_OUT, %%LAST_GHASH_BLK +%endif ; %%NUM_BLOCKS > 1 + +%%_after_reduction: + +%endif ; %%INSTANCE_TYPE, multi_call + + ;; Final hash is now in HASH_IN_OUT + +%endmacro ; INITIAL_BLOCKS_PARTIAL_GHASH + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; INITIAL_BLOCKS_PARTIAL macro with support for a partial final block. +;;; It may look similar to INITIAL_BLOCKS but its usage is different: +;;; - first encrypts/decrypts required number of blocks and then +;;; ghashes these blocks +;;; - Small packets or left over data chunks (<256 bytes) +;;; - single or multi call +;;; - Remaining data chunks below 256 bytes (multi buffer code) +;;; +;;; num_initial_blocks is expected to include the partial final block +;;; in the count. +%macro INITIAL_BLOCKS_PARTIAL 30 +%define %%GDATA_KEY %1 ; [in] key pointer +%define %%GDATA_CTX %2 ; [in] context pointer +%define %%CIPH_PLAIN_OUT %3 ; [in] text output pointer +%define %%PLAIN_CIPH_IN %4 ; [in] text input pointer +%define %%LENGTH %5 ; [in/clobbered] length in bytes +%define %%DATA_OFFSET %6 ; [in/out] current data offset (updated) +%define %%NUM_BLOCKS %7 ; [in] can only be 1, 2, 3, 4, 5, ..., 15 or 16 (not 0) +%define %%CTR %8 ; [in/out] current counter value +%define %%HASH_IN_OUT %9 ; [in/out] XMM ghash in/out value +%define %%ENC_DEC %10 ; [in] cipher direction (ENC/DEC) +%define %%INSTANCE_TYPE %11 ; [in] multi_call or single_call +%define %%CTR0 %12 ; [clobbered] ZMM temporary +%define %%CTR1 %13 ; [clobbered] ZMM temporary +%define %%CTR2 %14 ; [clobbered] ZMM temporary +%define %%CTR3 %15 ; [clobbered] ZMM temporary +%define %%DAT0 %16 ; [clobbered] ZMM temporary +%define %%DAT1 %17 ; [clobbered] ZMM temporary +%define %%DAT2 %18 ; [clobbered] ZMM temporary +%define %%DAT3 %19 ; [clobbered] ZMM temporary +%define %%LAST_CIPHER_BLK %20 ; [clobbered] ZMM temporary +%define %%LAST_GHASH_BLK %21 ; [clobbered] ZMM temporary +%define %%ZT0 %22 ; [clobbered] ZMM temporary +%define %%ZT1 %23 ; [clobbered] ZMM temporary +%define %%ZT2 %24 ; [clobbered] ZMM temporary +%define %%ZT3 %25 ; [clobbered] ZMM temporary +%define %%ZT4 %26 ; [clobbered] ZMM temporary +%define %%IA0 %27 ; [clobbered] GP temporary +%define %%IA1 %28 ; [clobbered] GP temporary +%define %%MASKREG %29 ; [clobbered] mask register +%define %%SHUFMASK %30 ; [clobbered] ZMM for BE/LE shuffle mask + + INITIAL_BLOCKS_PARTIAL_CIPHER \ + %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%LENGTH, %%DATA_OFFSET, %%NUM_BLOCKS, %%CTR, \ + %%ENC_DEC, %%INSTANCE_TYPE, %%DAT0, %%DAT1, %%DAT2, %%DAT3, \ + XWORD(%%LAST_CIPHER_BLK), XWORD(%%LAST_GHASH_BLK), \ + %%CTR0, %%CTR1, %%CTR2, %%CTR3, %%ZT0, \ + %%IA0, %%IA1, %%MASKREG, %%SHUFMASK + + INITIAL_BLOCKS_PARTIAL_GHASH \ + %%GDATA_KEY, %%GDATA_CTX, %%LENGTH, \ + %%NUM_BLOCKS, %%HASH_IN_OUT, %%ENC_DEC, \ + %%INSTANCE_TYPE, %%DAT0, %%DAT1, %%DAT2, %%DAT3, \ + XWORD(%%LAST_CIPHER_BLK), XWORD(%%LAST_GHASH_BLK), \ + %%CTR0, %%CTR1, %%CTR2, %%CTR3, %%ZT0, %%ZT1, \ + %%ZT2, %%ZT3, %%ZT4 + +%endmacro ; INITIAL_BLOCKS_PARTIAL + +;;; =========================================================================== +;;; =========================================================================== +;;; Stitched GHASH of 16 blocks (with reduction) with encryption of N blocks +;;; followed with GHASH of the N blocks. +%macro GHASH_16_ENCRYPT_N_GHASH_N 47 +%define %%GDATA %1 ; [in] key pointer +%define %%GCTX %2 ; [in] context pointer +%define %%CIPH_PLAIN_OUT %3 ; [in] pointer to output buffer +%define %%PLAIN_CIPH_IN %4 ; [in] pointer to input buffer +%define %%DATA_OFFSET %5 ; [in] data offset +%define %%LENGTH %6 ; [in] data length +%define %%CTR_BE %7 ; [in/out] ZMM counter blocks (last 4) in big-endian +%define %%CTR_CHECK %8 ; [in/out] GP with 8-bit counter for overflow check +%define %%HASHKEY_OFFSET %9 ; [in] numerical offset for the highest hash key +%define %%GHASHIN_BLK_OFFSET %10 ; [in] numerical offset for GHASH blocks in +%define %%SHFMSK %11 ; [in] ZMM with byte swap mask for pshufb +%define %%B00_03 %12 ; [clobbered] temporary ZMM +%define %%B04_07 %13 ; [clobbered] temporary ZMM +%define %%B08_11 %14 ; [clobbered] temporary ZMM +%define %%B12_15 %15 ; [clobbered] temporary ZMM +%define %%GH1H_UNUSED %16 ; [clobbered] temporary ZMM +%define %%GH1L %17 ; [clobbered] temporary ZMM +%define %%GH1M %18 ; [clobbered] temporary ZMM +%define %%GH1T %19 ; [clobbered] temporary ZMM +%define %%GH2H %20 ; [clobbered] temporary ZMM +%define %%GH2L %21 ; [clobbered] temporary ZMM +%define %%GH2M %22 ; [clobbered] temporary ZMM +%define %%GH2T %23 ; [clobbered] temporary ZMM +%define %%GH3H %24 ; [clobbered] temporary ZMM +%define %%GH3L %25 ; [clobbered] temporary ZMM +%define %%GH3M %26 ; [clobbered] temporary ZMM +%define %%GH3T %27 ; [clobbered] temporary ZMM +%define %%AESKEY1 %28 ; [clobbered] temporary ZMM +%define %%AESKEY2 %29 ; [clobbered] temporary ZMM +%define %%GHKEY1 %30 ; [clobbered] temporary ZMM +%define %%GHKEY2 %31 ; [clobbered] temporary ZMM +%define %%GHDAT1 %32 ; [clobbered] temporary ZMM +%define %%GHDAT2 %33 ; [clobbered] temporary ZMM +%define %%ZT01 %34 ; [clobbered] temporary ZMM +%define %%ADDBE_4x4 %35 ; [in] ZMM with 4x128bits 4 in big-endian +%define %%ADDBE_1234 %36 ; [in] ZMM with 4x128bits 1, 2, 3 and 4 in big-endian +%define %%GHASH_TYPE %37 ; [in] "start", "start_reduce", "mid", "end_reduce" +%define %%TO_REDUCE_L %38 ; [in] ZMM for low 4x128-bit GHASH sum +%define %%TO_REDUCE_H %39 ; [in] ZMM for hi 4x128-bit GHASH sum +%define %%TO_REDUCE_M %40 ; [in] ZMM for medium 4x128-bit GHASH sum +%define %%ENC_DEC %41 ; [in] cipher direction +%define %%HASH_IN_OUT %42 ; [in/out] XMM ghash in/out value +%define %%IA0 %43 ; [clobbered] GP temporary +%define %%IA1 %44 ; [clobbered] GP temporary +%define %%MASKREG %45 ; [clobbered] mask register +%define %%NUM_BLOCKS %46 ; [in] numerical value with number of blocks to be encrypted/ghashed (1 to 16) +%define %%INSTANCE_TYPE %47 ; [in] multi_call or single_call + +%xdefine %%GH1H %%HASH_IN_OUT ; this is to avoid additional move in do_reduction case + +%define %%LAST_GHASH_BLK %%GH1L +%define %%LAST_CIPHER_BLK %%GH1T + +%define %%RED_POLY %%GH2T +%define %%RED_P1 %%GH2L +%define %%RED_T1 %%GH2H +%define %%RED_T2 %%GH2M + +%define %%DATA1 %%GH3H +%define %%DATA2 %%GH3L +%define %%DATA3 %%GH3M +%define %%DATA4 %%GH3T + +;; do reduction after the 16 blocks ? +%assign do_reduction 0 + +;; is 16 block chunk a start? +%assign is_start 0 + +%ifidn %%GHASH_TYPE, start_reduce +%assign is_start 1 +%assign do_reduction 1 +%endif + +%ifidn %%GHASH_TYPE, start +%assign is_start 1 +%endif + +%ifidn %%GHASH_TYPE, end_reduce +%assign do_reduction 1 +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; - get load/store mask + ;; - load plain/cipher text + ;; get load/store mask + lea %%IA0, [rel byte64_len_to_mask_table] + mov %%IA1, %%LENGTH +%if %%NUM_BLOCKS > 12 + sub %%IA1, 3 * 64 +%elif %%NUM_BLOCKS > 8 + sub %%IA1, 2 * 64 +%elif %%NUM_BLOCKS > 4 + sub %%IA1, 64 +%endif + kmovq %%MASKREG, [%%IA0 + %%IA1*8] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; prepare counter blocks + + cmp DWORD(%%CTR_CHECK), (256 - %%NUM_BLOCKS) + jae %%_16_blocks_overflow + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpaddd, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%CTR_BE, %%B00_03, %%B04_07, %%B08_11, \ + %%ADDBE_1234, %%ADDBE_4x4, %%ADDBE_4x4, %%ADDBE_4x4 + jmp %%_16_blocks_ok + +%%_16_blocks_overflow: + vpshufb %%CTR_BE, %%CTR_BE, %%SHFMSK + vpaddd %%B00_03, %%CTR_BE, [rel ddq_add_1234] +%if %%NUM_BLOCKS > 4 + vmovdqa64 %%B12_15, [rel ddq_add_4444] + vpaddd %%B04_07, %%B00_03, %%B12_15 +%endif +%if %%NUM_BLOCKS > 8 + vpaddd %%B08_11, %%B04_07, %%B12_15 +%endif +%if %%NUM_BLOCKS > 12 + vpaddd %%B12_15, %%B08_11, %%B12_15 +%endif + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpshufb, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%SHFMSK, %%SHFMSK, %%SHFMSK, %%SHFMSK +%%_16_blocks_ok: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; - pre-load constants + ;; - add current hash into the 1st block + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 0)] +%if is_start != 0 + vpxorq %%GHDAT1, %%HASH_IN_OUT, [rsp + %%GHASHIN_BLK_OFFSET + (0*64)] +%else + vmovdqa64 %%GHDAT1, [rsp + %%GHASHIN_BLK_OFFSET + (0*64)] +%endif + vmovdqu64 %%GHKEY1, [%%GDATA + %%HASHKEY_OFFSET + (0*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; save counter for the next round + ;; increment counter overflow check register +%ifidn %%INSTANCE_TYPE, multi_call +%if %%NUM_BLOCKS <= 4 + vextracti32x4 XWORD(%%CTR_BE), %%B00_03, (%%NUM_BLOCKS - 1) +%elif %%NUM_BLOCKS <= 8 + vextracti32x4 XWORD(%%CTR_BE), %%B04_07, (%%NUM_BLOCKS - 5) +%elif %%NUM_BLOCKS <= 12 + vextracti32x4 XWORD(%%CTR_BE), %%B08_11, (%%NUM_BLOCKS - 9) +%else + vextracti32x4 XWORD(%%CTR_BE), %%B12_15, (%%NUM_BLOCKS - 13) +%endif + vshufi64x2 %%CTR_BE, %%CTR_BE, %%CTR_BE, 0000_0000b +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; pre-load constants + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 1)] + vmovdqu64 %%GHKEY2, [%%GDATA + %%HASHKEY_OFFSET + (1*64)] + vmovdqa64 %%GHDAT2, [rsp + %%GHASHIN_BLK_OFFSET + (1*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; stitch AES rounds with GHASH + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 0 - ARK + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpxorq, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 2)] + + ;;================================================== + ;; GHASH 4 blocks (15 to 12) + vpclmulqdq %%GH1H, %%GHDAT1, %%GHKEY1, 0x11 ; a1*b1 + vpclmulqdq %%GH1L, %%GHDAT1, %%GHKEY1, 0x00 ; a0*b0 + vpclmulqdq %%GH1M, %%GHDAT1, %%GHKEY1, 0x01 ; a1*b0 + vpclmulqdq %%GH1T, %%GHDAT1, %%GHKEY1, 0x10 ; a0*b1 + + vmovdqu64 %%GHKEY1, [%%GDATA + %%HASHKEY_OFFSET + (2*64)] + vmovdqa64 %%GHDAT1, [rsp + %%GHASHIN_BLK_OFFSET + (2*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 1 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY2, %%AESKEY2, %%AESKEY2, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 3)] + + ;; ================================================= + ;; GHASH 4 blocks (11 to 8) + vpclmulqdq %%GH2M, %%GHDAT2, %%GHKEY2, 0x10 ; a0*b1 + vpclmulqdq %%GH2T, %%GHDAT2, %%GHKEY2, 0x01 ; a1*b0 + vpclmulqdq %%GH2H, %%GHDAT2, %%GHKEY2, 0x11 ; a1*b1 + vpclmulqdq %%GH2L, %%GHDAT2, %%GHKEY2, 0x00 ; a0*b0 + + vmovdqu64 %%GHKEY2, [%%GDATA + %%HASHKEY_OFFSET + (3*64)] + vmovdqa64 %%GHDAT2, [rsp + %%GHASHIN_BLK_OFFSET + (3*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 2 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 4)] + + ;; ================================================= + ;; GHASH 4 blocks (7 to 4) + vpclmulqdq %%GH3M, %%GHDAT1, %%GHKEY1, 0x10 ; a0*b1 + vpclmulqdq %%GH3T, %%GHDAT1, %%GHKEY1, 0x01 ; a1*b0 + vpclmulqdq %%GH3H, %%GHDAT1, %%GHKEY1, 0x11 ; a1*b1 + vpclmulqdq %%GH3L, %%GHDAT1, %%GHKEY1, 0x00 ; a0*b0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds 3 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY2, %%AESKEY2, %%AESKEY2, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 5)] + + ;; ================================================= + ;; Gather (XOR) GHASH for 12 blocks + vpternlogq %%GH1H, %%GH2H, %%GH3H, 0x96 + vpternlogq %%GH1L, %%GH2L, %%GH3L, 0x96 + vpternlogq %%GH1T, %%GH2T, %%GH3T, 0x96 + vpternlogq %%GH1M, %%GH2M, %%GH3M, 0x96 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds 4 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 6)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; load plain/cipher text + ZMM_LOAD_MASKED_BLOCKS_0_16 %%NUM_BLOCKS, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%DATA1, %%DATA2, %%DATA3, %%DATA4, %%MASKREG + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds 5 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY2, %%AESKEY2, %%AESKEY2, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 7)] + + ;; ================================================= + ;; GHASH 4 blocks (3 to 0) + vpclmulqdq %%GH2M, %%GHDAT2, %%GHKEY2, 0x10 ; a0*b1 + vpclmulqdq %%GH2T, %%GHDAT2, %%GHKEY2, 0x01 ; a1*b0 + vpclmulqdq %%GH2H, %%GHDAT2, %%GHKEY2, 0x11 ; a1*b1 + vpclmulqdq %%GH2L, %%GHDAT2, %%GHKEY2, 0x00 ; a0*b0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 6 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 8)] + + ;; ================================================= + ;; gather GHASH in GH1L (low), GH1H (high), GH1M (mid) + ;; - add GH2[MTLH] to GH1[MTLH] + vpternlogq %%GH1M, %%GH1T, %%GH2T, 0x96 +%if do_reduction != 0 + +%if is_start != 0 + vpxorq %%GH1M, %%GH1M, %%GH2M +%else + vpternlogq %%GH1H, %%TO_REDUCE_H, %%GH2H, 0x96 + vpternlogq %%GH1L, %%TO_REDUCE_L, %%GH2L, 0x96 + vpternlogq %%GH1M, %%TO_REDUCE_M, %%GH2M, 0x96 +%endif + +%else + ;; Update H/M/L hash sums if not carrying reduction +%if is_start != 0 + vpxorq %%TO_REDUCE_H, %%GH1H, %%GH2H + vpxorq %%TO_REDUCE_L, %%GH1L, %%GH2L + vpxorq %%TO_REDUCE_M, %%GH1M, %%GH2M +%else + vpternlogq %%TO_REDUCE_H, %%GH1H, %%GH2H, 0x96 + vpternlogq %%TO_REDUCE_L, %%GH1L, %%GH2L, 0x96 + vpternlogq %%TO_REDUCE_M, %%GH1M, %%GH2M, 0x96 +%endif + +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 7 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY2, %%AESKEY2, %%AESKEY2, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 9)] + + ;; ================================================= + ;; prepare mid sum for adding to high & low + ;; load polynomial constant for reduction +%if do_reduction != 0 + vpsrldq %%GH2M, %%GH1M, 8 + vpslldq %%GH1M, %%GH1M, 8 + + vmovdqa64 XWORD(%%RED_POLY), [rel POLY2] +%endif + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 8 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 10)] + + ;; ================================================= + ;; Add mid product to high and low +%if do_reduction != 0 +%if is_start != 0 + vpternlogq %%GH1H, %%GH2H, %%GH2M, 0x96 ; TH = TH1 + TH2 + TM>>64 + vpternlogq %%GH1L, %%GH2L, %%GH1M, 0x96 ; TL = TL1 + TL2 + TM<<64 +%else + vpxorq %%GH1H, %%GH1H, %%GH2M ; TH = TH1 + TM>>64 + vpxorq %%GH1L, %%GH1L, %%GH1M ; TL = TL1 + TM<<64 +%endif +%endif + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 9 + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY2, %%AESKEY2, %%AESKEY2, %%AESKEY2 + + ;; ================================================= + ;; horizontal xor of low and high 4x128 +%if do_reduction != 0 + VHPXORI4x128 %%GH1H, %%GH2H + VHPXORI4x128 %%GH1L, %%GH2L +%endif + +%if (NROUNDS >= 11) + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 11)] +%endif + ;; ================================================= + ;; first phase of reduction +%if do_reduction != 0 + vpclmulqdq XWORD(%%RED_P1), XWORD(%%RED_POLY), XWORD(%%GH1L), 0x01 + vpslldq XWORD(%%RED_P1), XWORD(%%RED_P1), 8 ; shift-L 2 DWs + vpxorq XWORD(%%RED_P1), XWORD(%%GH1L), XWORD(%%RED_P1) ; first phase of the reduct +%endif + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds up to 11 (AES192) or 13 (AES256) + ;; AES128 is done +%if (NROUNDS >= 11) + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 12)] + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY2, %%AESKEY2, %%AESKEY2, %%AESKEY2 +%if (NROUNDS == 13) + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 13)] + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 14)] + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenc, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY2, %%AESKEY2, %%AESKEY2, %%AESKEY2 +%endif ; GCM256 / NROUNDS = 13 (15 including the first and the last) +%endif ; GCM192 / NROUNDS = 11 (13 including the first and the last) + + ;; ================================================= + ;; second phase of the reduction +%if do_reduction != 0 + vpclmulqdq XWORD(%%RED_T1), XWORD(%%RED_POLY), XWORD(%%RED_P1), 0x00 + vpsrldq XWORD(%%RED_T1), XWORD(%%RED_T1), 4 ; shift-R 1-DW to obtain 2-DWs shift-R + + vpclmulqdq XWORD(%%RED_T2), XWORD(%%RED_POLY), XWORD(%%RED_P1), 0x10 + vpslldq XWORD(%%RED_T2), XWORD(%%RED_T2), 4 ; shift-L 1-DW for result without shifts + ;; GH1H = GH1H + RED_T1 + RED_T2 + vpternlogq XWORD(%%GH1H), XWORD(%%RED_T2), XWORD(%%RED_T1), 0x96 +%endif + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; the last AES round + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vaesenclast, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%AESKEY1, %%AESKEY1, %%AESKEY1, %%AESKEY1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; XOR against plain/cipher text + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpxorq, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%DATA1, %%DATA2, %%DATA3, %%DATA4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; retrieve the last cipher counter block (partially XOR'ed with text) + ;; - this is needed for partial block cases +%ifidn %%INSTANCE_TYPE, multi_call +%if %%NUM_BLOCKS <= 4 + vextracti32x4 XWORD(%%LAST_CIPHER_BLK), %%B00_03, (%%NUM_BLOCKS - 1) +%elif %%NUM_BLOCKS <= 8 + vextracti32x4 XWORD(%%LAST_CIPHER_BLK), %%B04_07, (%%NUM_BLOCKS - 5) +%elif %%NUM_BLOCKS <= 12 + vextracti32x4 XWORD(%%LAST_CIPHER_BLK), %%B08_11, (%%NUM_BLOCKS - 9) +%else + vextracti32x4 XWORD(%%LAST_CIPHER_BLK), %%B12_15, (%%NUM_BLOCKS - 13) +%endif +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; store cipher/plain text + ZMM_STORE_MASKED_BLOCKS_0_16 %%NUM_BLOCKS, %%CIPH_PLAIN_OUT, %%DATA_OFFSET, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, %%MASKREG + + ;; ================================================= + ;; shuffle cipher text blocks for GHASH computation +%ifidn %%ENC_DEC, ENC + ;; zero bytes outside the mask before hashing +%if %%NUM_BLOCKS <= 4 + vmovdqu8 %%B00_03{%%MASKREG}{z}, %%B00_03 +%elif %%NUM_BLOCKS <= 8 + vmovdqu8 %%B04_07{%%MASKREG}{z}, %%B04_07 +%elif %%NUM_BLOCKS <= 12 + vmovdqu8 %%B08_11{%%MASKREG}{z}, %%B08_11 +%else + vmovdqu8 %%B12_15{%%MASKREG}{z}, %%B12_15 +%endif + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpshufb, \ + %%DATA1, %%DATA2, %%DATA3, %%DATA4, \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, \ + %%SHFMSK, %%SHFMSK, %%SHFMSK, %%SHFMSK +%else + ;; zero bytes outside the mask before hashing +%if %%NUM_BLOCKS <= 4 + vmovdqu8 %%DATA1{%%MASKREG}{z}, %%DATA1 +%elif %%NUM_BLOCKS <= 8 + vmovdqu8 %%DATA2{%%MASKREG}{z}, %%DATA2 +%elif %%NUM_BLOCKS <= 12 + vmovdqu8 %%DATA3{%%MASKREG}{z}, %%DATA3 +%else + vmovdqu8 %%DATA4{%%MASKREG}{z}, %%DATA4 +%endif + + ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16 %%NUM_BLOCKS, vpshufb, \ + %%DATA1, %%DATA2, %%DATA3, %%DATA4, \ + %%DATA1, %%DATA2, %%DATA3, %%DATA4, \ + %%SHFMSK, %%SHFMSK, %%SHFMSK, %%SHFMSK +%endif + + ;; ================================================= + ;; Extract the last block for partial / multi_call cases +%ifidn %%INSTANCE_TYPE, multi_call +%if %%NUM_BLOCKS <= 4 + vextracti32x4 XWORD(%%LAST_GHASH_BLK), %%DATA1, %%NUM_BLOCKS - 1 +%elif %%NUM_BLOCKS <= 8 + vextracti32x4 XWORD(%%LAST_GHASH_BLK), %%DATA2, %%NUM_BLOCKS - 5 +%elif %%NUM_BLOCKS <= 12 + vextracti32x4 XWORD(%%LAST_GHASH_BLK), %%DATA3, %%NUM_BLOCKS - 9 +%else + vextracti32x4 XWORD(%%LAST_GHASH_BLK), %%DATA4, %%NUM_BLOCKS - 13 +%endif +%endif + +%if do_reduction != 0 + ;; GH1H holds reduced hash value + ;; - normally do "vmovdqa64 XWORD(%%HASH_IN_OUT), XWORD(%%GH1H)" + ;; - register rename trick obsoletes the above move +%endif + + ;; ================================================= + ;; GHASH last N blocks + ;; - current hash value in HASH_IN_OUT or + ;; product parts in TO_REDUCE_H/M/L + ;; - DATA1-DATA4 include blocks for GHASH + +%if do_reduction == 0 + INITIAL_BLOCKS_PARTIAL_GHASH \ + %%GDATA, %%GCTX, %%LENGTH, \ + %%NUM_BLOCKS, XWORD(%%HASH_IN_OUT), %%ENC_DEC, \ + %%INSTANCE_TYPE, %%DATA1, %%DATA2, %%DATA3, %%DATA4, \ + XWORD(%%LAST_CIPHER_BLK), XWORD(%%LAST_GHASH_BLK), \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, %%GHDAT1, %%GHDAT2, \ + %%AESKEY1, %%AESKEY2, %%GHKEY1, \ + %%TO_REDUCE_H, %%TO_REDUCE_M, %%TO_REDUCE_L +%else + INITIAL_BLOCKS_PARTIAL_GHASH \ + %%GDATA, %%GCTX, %%LENGTH, \ + %%NUM_BLOCKS, XWORD(%%HASH_IN_OUT), %%ENC_DEC, \ + %%INSTANCE_TYPE, %%DATA1, %%DATA2, %%DATA3, %%DATA4, \ + XWORD(%%LAST_CIPHER_BLK), XWORD(%%LAST_GHASH_BLK), \ + %%B00_03, %%B04_07, %%B08_11, %%B12_15, %%GHDAT1, %%GHDAT2, \ + %%AESKEY1, %%AESKEY2, %%GHKEY1 +%endif +%endmacro + +;;; =========================================================================== +;;; =========================================================================== +;;; Stitched GHASH of 16 blocks (with reduction) with encryption of N blocks +;;; followed with GHASH of the N blocks. +%macro GCM_ENC_DEC_LAST 46 +%define %%GDATA %1 ; [in] key pointer +%define %%GCTX %2 ; [in] context pointer +%define %%CIPH_PLAIN_OUT %3 ; [in] pointer to output buffer +%define %%PLAIN_CIPH_IN %4 ; [in] pointer to input buffer +%define %%DATA_OFFSET %5 ; [in] data offset +%define %%LENGTH %6 ; [in/clobbered] data length +%define %%CTR_BE %7 ; [in/out] ZMM counter blocks (last 4) in big-endian +%define %%CTR_CHECK %8 ; [in/out] GP with 8-bit counter for overflow check +%define %%HASHKEY_OFFSET %9 ; [in] numerical offset for the highest hash key +%define %%GHASHIN_BLK_OFFSET %10 ; [in] numerical offset for GHASH blocks in +%define %%SHFMSK %11 ; [in] ZMM with byte swap mask for pshufb +%define %%ZT00 %12 ; [clobbered] temporary ZMM +%define %%ZT01 %13 ; [clobbered] temporary ZMM +%define %%ZT02 %14 ; [clobbered] temporary ZMM +%define %%ZT03 %15 ; [clobbered] temporary ZMM +%define %%ZT04 %16 ; [clobbered] temporary ZMM +%define %%ZT05 %17 ; [clobbered] temporary ZMM +%define %%ZT06 %18 ; [clobbered] temporary ZMM +%define %%ZT07 %19 ; [clobbered] temporary ZMM +%define %%ZT08 %20 ; [clobbered] temporary ZMM +%define %%ZT09 %21 ; [clobbered] temporary ZMM +%define %%ZT10 %22 ; [clobbered] temporary ZMM +%define %%ZT11 %23 ; [clobbered] temporary ZMM +%define %%ZT12 %24 ; [clobbered] temporary ZMM +%define %%ZT13 %25 ; [clobbered] temporary ZMM +%define %%ZT14 %26 ; [clobbered] temporary ZMM +%define %%ZT15 %27 ; [clobbered] temporary ZMM +%define %%ZT16 %28 ; [clobbered] temporary ZMM +%define %%ZT17 %29 ; [clobbered] temporary ZMM +%define %%ZT18 %30 ; [clobbered] temporary ZMM +%define %%ZT19 %31 ; [clobbered] temporary ZMM +%define %%ZT20 %32 ; [clobbered] temporary ZMM +%define %%ZT21 %33 ; [clobbered] temporary ZMM +%define %%ZT22 %34 ; [clobbered] temporary ZMM +%define %%ADDBE_4x4 %35 ; [in] ZMM with 4x128bits 4 in big-endian +%define %%ADDBE_1234 %36 ; [in] ZMM with 4x128bits 1, 2, 3 and 4 in big-endian +%define %%GHASH_TYPE %37 ; [in] "start", "start_reduce", "mid", "end_reduce" +%define %%TO_REDUCE_L %38 ; [in] ZMM for low 4x128-bit GHASH sum +%define %%TO_REDUCE_H %39 ; [in] ZMM for hi 4x128-bit GHASH sum +%define %%TO_REDUCE_M %40 ; [in] ZMM for medium 4x128-bit GHASH sum +%define %%ENC_DEC %41 ; [in] cipher direction +%define %%HASH_IN_OUT %42 ; [in/out] XMM ghash in/out value +%define %%IA0 %43 ; [clobbered] GP temporary +%define %%IA1 %44 ; [clobbered] GP temporary +%define %%MASKREG %45 ; [clobbered] mask register +%define %%INSTANCE_TYPE %46 ; [in] multi_call or single_call + + mov DWORD(%%IA0), DWORD(%%LENGTH) + add DWORD(%%IA0), 15 + shr DWORD(%%IA0), 4 + je %%_last_num_blocks_is_0 + + cmp DWORD(%%IA0), 8 + je %%_last_num_blocks_is_8 + jb %%_last_num_blocks_is_7_1 + + + cmp DWORD(%%IA0), 12 + je %%_last_num_blocks_is_12 + jb %%_last_num_blocks_is_11_9 + + ;; 16, 15, 14 or 13 + cmp DWORD(%%IA0), 15 + je %%_last_num_blocks_is_15 + ja %%_last_num_blocks_is_16 + cmp DWORD(%%IA0), 14 + je %%_last_num_blocks_is_14 + jmp %%_last_num_blocks_is_13 + +%%_last_num_blocks_is_11_9: + ;; 11, 10 or 9 + cmp DWORD(%%IA0), 10 + je %%_last_num_blocks_is_10 + ja %%_last_num_blocks_is_11 + jmp %%_last_num_blocks_is_9 + +%%_last_num_blocks_is_7_1: + cmp DWORD(%%IA0), 4 + je %%_last_num_blocks_is_4 + jb %%_last_num_blocks_is_3_1 + ;; 7, 6 or 5 + cmp DWORD(%%IA0), 6 + ja %%_last_num_blocks_is_7 + je %%_last_num_blocks_is_6 + jmp %%_last_num_blocks_is_5 + +%%_last_num_blocks_is_3_1: + ;; 3, 2 or 1 + cmp DWORD(%%IA0), 2 + ja %%_last_num_blocks_is_3 + je %%_last_num_blocks_is_2 + ;; fall through for `jmp %%_last_num_blocks_is_1` + + ;; Use rep to generate different block size variants + ;; - one block size has to be the first one +%assign num_blocks 1 +%rep 16 +%%_last_num_blocks_is_ %+ num_blocks : + GHASH_16_ENCRYPT_N_GHASH_N \ + %%GDATA, %%GCTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%DATA_OFFSET, %%LENGTH, %%CTR_BE, %%CTR_CHECK, \ + %%HASHKEY_OFFSET, %%GHASHIN_BLK_OFFSET, %%SHFMSK, \ + %%ZT00, %%ZT01, %%ZT02, %%ZT03, %%ZT04, %%ZT05, %%ZT06, %%ZT07, \ + %%ZT08, %%ZT09, %%ZT10, %%ZT11, %%ZT12, %%ZT13, %%ZT14, %%ZT15, \ + %%ZT16, %%ZT17, %%ZT18, %%ZT19, %%ZT20, %%ZT21, %%ZT22, \ + %%ADDBE_4x4, %%ADDBE_1234, %%GHASH_TYPE, \ + %%TO_REDUCE_L, %%TO_REDUCE_H, %%TO_REDUCE_M, \ + %%ENC_DEC, %%HASH_IN_OUT, %%IA0, %%IA1, %%MASKREG, \ + num_blocks, %%INSTANCE_TYPE + + jmp %%_last_blocks_done +%assign num_blocks (num_blocks + 1) +%endrep + +%%_last_num_blocks_is_0: +;; if there is 0 blocks to cipher then there are only 16 blocks for ghash and reduction +;; - convert mid into end_reduce +;; - convert start into start_reduce +%ifidn %%GHASH_TYPE, mid +%xdefine %%GHASH_TYPE end_reduce +%endif +%ifidn %%GHASH_TYPE, start +%xdefine %%GHASH_TYPE start_reduce +%endif + + GHASH_16 %%GHASH_TYPE, %%TO_REDUCE_H, %%TO_REDUCE_M, %%TO_REDUCE_L, \ + rsp, %%GHASHIN_BLK_OFFSET, 0, %%GDATA, %%HASHKEY_OFFSET, 0, %%HASH_IN_OUT, \ + %%ZT00, %%ZT01, %%ZT02, %%ZT03, %%ZT04, %%ZT05, %%ZT06, %%ZT07, %%ZT08, %%ZT09 + +%%_last_blocks_done: + +%endmacro + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Main GCM macro stitching cipher with GHASH +;;; - operates on single stream +;;; - encrypts 16 blocks at a time +;;; - ghash the 16 previously encrypted ciphertext blocks +;;; - no partial block or multi_call handling here +%macro GHASH_16_ENCRYPT_16_PARALLEL 42 +%define %%GDATA %1 ; [in] key pointer +%define %%CIPH_PLAIN_OUT %2 ; [in] pointer to output buffer +%define %%PLAIN_CIPH_IN %3 ; [in] pointer to input buffer +%define %%DATA_OFFSET %4 ; [in] data offset +%define %%CTR_BE %5 ; [in/out] ZMM counter blocks (last 4) in big-endian +%define %%CTR_CHECK %6 ; [in/out] GP with 8-bit counter for overflow check +%define %%HASHKEY_OFFSET %7 ; [in] numerical offset for the highest hash key +%define %%AESOUT_BLK_OFFSET %8 ; [in] numerical offset for AES-CTR out +%define %%GHASHIN_BLK_OFFSET %9 ; [in] numerical offset for GHASH blocks in +%define %%SHFMSK %10 ; [in] ZMM with byte swap mask for pshufb +%define %%ZT1 %11 ; [clobbered] temporary ZMM (cipher) +%define %%ZT2 %12 ; [clobbered] temporary ZMM (cipher) +%define %%ZT3 %13 ; [clobbered] temporary ZMM (cipher) +%define %%ZT4 %14 ; [clobbered] temporary ZMM (cipher) +%define %%ZT5 %15 ; [clobbered/out] temporary ZMM or GHASH OUT (final_reduction) +%define %%ZT6 %16 ; [clobbered] temporary ZMM (cipher) +%define %%ZT7 %17 ; [clobbered] temporary ZMM (cipher) +%define %%ZT8 %18 ; [clobbered] temporary ZMM (cipher) +%define %%ZT9 %19 ; [clobbered] temporary ZMM (cipher) +%define %%ZT10 %20 ; [clobbered] temporary ZMM (ghash) +%define %%ZT11 %21 ; [clobbered] temporary ZMM (ghash) +%define %%ZT12 %22 ; [clobbered] temporary ZMM (ghash) +%define %%ZT13 %23 ; [clobbered] temporary ZMM (ghash) +%define %%ZT14 %24 ; [clobbered] temporary ZMM (ghash) +%define %%ZT15 %25 ; [clobbered] temporary ZMM (ghash) +%define %%ZT16 %26 ; [clobbered] temporary ZMM (ghash) +%define %%ZT17 %27 ; [clobbered] temporary ZMM (ghash) +%define %%ZT18 %28 ; [clobbered] temporary ZMM (ghash) +%define %%ZT19 %29 ; [clobbered] temporary ZMM +%define %%ZT20 %30 ; [clobbered] temporary ZMM +%define %%ZT21 %31 ; [clobbered] temporary ZMM +%define %%ZT22 %32 ; [clobbered] temporary ZMM +%define %%ZT23 %33 ; [clobbered] temporary ZMM +%define %%ADDBE_4x4 %34 ; [in] ZMM with 4x128bits 4 in big-endian +%define %%ADDBE_1234 %35 ; [in] ZMM with 4x128bits 1, 2, 3 and 4 in big-endian +%define %%TO_REDUCE_L %36 ; [in/out] ZMM for low 4x128-bit GHASH sum +%define %%TO_REDUCE_H %37 ; [in/out] ZMM for hi 4x128-bit GHASH sum +%define %%TO_REDUCE_M %38 ; [in/out] ZMM for medium 4x128-bit GHASH sum +%define %%DO_REDUCTION %39 ; [in] "no_reduction", "final_reduction", "first_time" +%define %%ENC_DEC %40 ; [in] cipher direction +%define %%DATA_DISPL %41 ; [in] fixed numerical data displacement/offset +%define %%GHASH_IN %42 ; [in] current GHASH value or "no_ghash_in" + +%define %%B00_03 %%ZT1 +%define %%B04_07 %%ZT2 +%define %%B08_11 %%ZT3 +%define %%B12_15 %%ZT4 + +%define %%GH1H %%ZT5 ; @note: do not change this mapping +%define %%GH1L %%ZT6 +%define %%GH1M %%ZT7 +%define %%GH1T %%ZT8 + +%define %%GH2H %%ZT9 +%define %%GH2L %%ZT10 +%define %%GH2M %%ZT11 +%define %%GH2T %%ZT12 + +%define %%RED_POLY %%GH2T +%define %%RED_P1 %%GH2L +%define %%RED_T1 %%GH2H +%define %%RED_T2 %%GH2M + +%define %%GH3H %%ZT13 +%define %%GH3L %%ZT14 +%define %%GH3M %%ZT15 +%define %%GH3T %%ZT16 + +%define %%DATA1 %%ZT13 +%define %%DATA2 %%ZT14 +%define %%DATA3 %%ZT15 +%define %%DATA4 %%ZT16 + +%define %%AESKEY1 %%ZT17 +%define %%AESKEY2 %%ZT18 + +%define %%GHKEY1 %%ZT19 +%define %%GHKEY2 %%ZT20 +%define %%GHDAT1 %%ZT21 +%define %%GHDAT2 %%ZT22 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; prepare counter blocks + + cmp BYTE(%%CTR_CHECK), (256 - 16) + jae %%_16_blocks_overflow + vpaddd %%B00_03, %%CTR_BE, %%ADDBE_1234 + vpaddd %%B04_07, %%B00_03, %%ADDBE_4x4 + vpaddd %%B08_11, %%B04_07, %%ADDBE_4x4 + vpaddd %%B12_15, %%B08_11, %%ADDBE_4x4 + jmp %%_16_blocks_ok +%%_16_blocks_overflow: + vpshufb %%CTR_BE, %%CTR_BE, %%SHFMSK + vmovdqa64 %%B12_15, [rel ddq_add_4444] + vpaddd %%B00_03, %%CTR_BE, [rel ddq_add_1234] + vpaddd %%B04_07, %%B00_03, %%B12_15 + vpaddd %%B08_11, %%B04_07, %%B12_15 + vpaddd %%B12_15, %%B08_11, %%B12_15 + vpshufb %%B00_03, %%SHFMSK + vpshufb %%B04_07, %%SHFMSK + vpshufb %%B08_11, %%SHFMSK + vpshufb %%B12_15, %%SHFMSK +%%_16_blocks_ok: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; pre-load constants + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 0)] +%ifnidn %%GHASH_IN, no_ghash_in + vpxorq %%GHDAT1, %%GHASH_IN, [rsp + %%GHASHIN_BLK_OFFSET + (0*64)] +%else + vmovdqa64 %%GHDAT1, [rsp + %%GHASHIN_BLK_OFFSET + (0*64)] +%endif + vmovdqu64 %%GHKEY1, [%%GDATA + %%HASHKEY_OFFSET + (0*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; save counter for the next round + ;; increment counter overflow check register + vshufi64x2 %%CTR_BE, %%B12_15, %%B12_15, 1111_1111b + add BYTE(%%CTR_CHECK), 16 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; pre-load constants + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 1)] + vmovdqu64 %%GHKEY2, [%%GDATA + %%HASHKEY_OFFSET + (1*64)] + vmovdqa64 %%GHDAT2, [rsp + %%GHASHIN_BLK_OFFSET + (1*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; stitch AES rounds with GHASH + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 0 - ARK + + vpxorq %%B00_03, %%AESKEY1 + vpxorq %%B04_07, %%AESKEY1 + vpxorq %%B08_11, %%AESKEY1 + vpxorq %%B12_15, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 2)] + + ;;================================================== + ;; GHASH 4 blocks (15 to 12) + vpclmulqdq %%GH1H, %%GHDAT1, %%GHKEY1, 0x11 ; a1*b1 + vpclmulqdq %%GH1L, %%GHDAT1, %%GHKEY1, 0x00 ; a0*b0 + vpclmulqdq %%GH1M, %%GHDAT1, %%GHKEY1, 0x01 ; a1*b0 + vpclmulqdq %%GH1T, %%GHDAT1, %%GHKEY1, 0x10 ; a0*b1 + + vmovdqu64 %%GHKEY1, [%%GDATA + %%HASHKEY_OFFSET + (2*64)] + vmovdqa64 %%GHDAT1, [rsp + %%GHASHIN_BLK_OFFSET + (2*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 1 + vaesenc %%B00_03, %%B00_03, %%AESKEY2 + vaesenc %%B04_07, %%B04_07, %%AESKEY2 + vaesenc %%B08_11, %%B08_11, %%AESKEY2 + vaesenc %%B12_15, %%B12_15, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 3)] + + ;; ================================================= + ;; GHASH 4 blocks (11 to 8) + vpclmulqdq %%GH2M, %%GHDAT2, %%GHKEY2, 0x10 ; a0*b1 + vpclmulqdq %%GH2T, %%GHDAT2, %%GHKEY2, 0x01 ; a1*b0 + vpclmulqdq %%GH2H, %%GHDAT2, %%GHKEY2, 0x11 ; a1*b1 + vpclmulqdq %%GH2L, %%GHDAT2, %%GHKEY2, 0x00 ; a0*b0 + + vmovdqu64 %%GHKEY2, [%%GDATA + %%HASHKEY_OFFSET + (3*64)] + vmovdqa64 %%GHDAT2, [rsp + %%GHASHIN_BLK_OFFSET + (3*64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 2 + vaesenc %%B00_03, %%B00_03, %%AESKEY1 + vaesenc %%B04_07, %%B04_07, %%AESKEY1 + vaesenc %%B08_11, %%B08_11, %%AESKEY1 + vaesenc %%B12_15, %%B12_15, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 4)] + + ;; ================================================= + ;; GHASH 4 blocks (7 to 4) + vpclmulqdq %%GH3M, %%GHDAT1, %%GHKEY1, 0x10 ; a0*b1 + vpclmulqdq %%GH3T, %%GHDAT1, %%GHKEY1, 0x01 ; a1*b0 + vpclmulqdq %%GH3H, %%GHDAT1, %%GHKEY1, 0x11 ; a1*b1 + vpclmulqdq %%GH3L, %%GHDAT1, %%GHKEY1, 0x00 ; a0*b0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds 3 + vaesenc %%B00_03, %%B00_03, %%AESKEY2 + vaesenc %%B04_07, %%B04_07, %%AESKEY2 + vaesenc %%B08_11, %%B08_11, %%AESKEY2 + vaesenc %%B12_15, %%B12_15, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 5)] + + ;; ================================================= + ;; Gather (XOR) GHASH for 12 blocks + vpternlogq %%GH1H, %%GH2H, %%GH3H, 0x96 + vpternlogq %%GH1L, %%GH2L, %%GH3L, 0x96 + vpternlogq %%GH1T, %%GH2T, %%GH3T, 0x96 + vpternlogq %%GH1M, %%GH2M, %%GH3M, 0x96 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds 4 + vaesenc %%B00_03, %%B00_03, %%AESKEY1 + vaesenc %%B04_07, %%B04_07, %%AESKEY1 + vaesenc %%B08_11, %%B08_11, %%AESKEY1 + vaesenc %%B12_15, %%B12_15, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 6)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; load plain/cipher text (recycle GH3xx registers) + VX512LDR %%DATA1, [%%PLAIN_CIPH_IN + %%DATA_OFFSET + %%DATA_DISPL + (0 * 64)] + VX512LDR %%DATA2, [%%PLAIN_CIPH_IN + %%DATA_OFFSET + %%DATA_DISPL + (1 * 64)] + VX512LDR %%DATA3, [%%PLAIN_CIPH_IN + %%DATA_OFFSET + %%DATA_DISPL + (2 * 64)] + VX512LDR %%DATA4, [%%PLAIN_CIPH_IN + %%DATA_OFFSET + %%DATA_DISPL + (3 * 64)] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds 5 + vaesenc %%B00_03, %%B00_03, %%AESKEY2 + vaesenc %%B04_07, %%B04_07, %%AESKEY2 + vaesenc %%B08_11, %%B08_11, %%AESKEY2 + vaesenc %%B12_15, %%B12_15, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 7)] + + ;; ================================================= + ;; GHASH 4 blocks (3 to 0) + vpclmulqdq %%GH2M, %%GHDAT2, %%GHKEY2, 0x10 ; a0*b1 + vpclmulqdq %%GH2T, %%GHDAT2, %%GHKEY2, 0x01 ; a1*b0 + vpclmulqdq %%GH2H, %%GHDAT2, %%GHKEY2, 0x11 ; a1*b1 + vpclmulqdq %%GH2L, %%GHDAT2, %%GHKEY2, 0x00 ; a0*b0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 6 + vaesenc %%B00_03, %%B00_03, %%AESKEY1 + vaesenc %%B04_07, %%B04_07, %%AESKEY1 + vaesenc %%B08_11, %%B08_11, %%AESKEY1 + vaesenc %%B12_15, %%B12_15, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 8)] + + ;; ================================================= + ;; gather GHASH in GH1L (low) and GH1H (high) +%ifidn %%DO_REDUCTION, first_time + vpternlogq %%GH1M, %%GH1T, %%GH2T, 0x96 ; TM + vpxorq %%TO_REDUCE_M, %%GH1M, %%GH2M ; TM + vpxorq %%TO_REDUCE_H, %%GH1H, %%GH2H ; TH + vpxorq %%TO_REDUCE_L, %%GH1L, %%GH2L ; TL +%endif +%ifidn %%DO_REDUCTION, no_reduction + vpternlogq %%GH1M, %%GH1T, %%GH2T, 0x96 ; TM + vpternlogq %%TO_REDUCE_M, %%GH1M, %%GH2M, 0x96 ; TM + vpternlogq %%TO_REDUCE_H, %%GH1H, %%GH2H, 0x96 ; TH + vpternlogq %%TO_REDUCE_L, %%GH1L, %%GH2L, 0x96 ; TL +%endif +%ifidn %%DO_REDUCTION, final_reduction + ;; phase 1: add mid products together + ;; also load polynomial constant for reduction + vpternlogq %%GH1M, %%GH1T, %%GH2T, 0x96 ; TM + vpternlogq %%GH1M, %%TO_REDUCE_M, %%GH2M, 0x96 + + vpsrldq %%GH2M, %%GH1M, 8 + vpslldq %%GH1M, %%GH1M, 8 + + vmovdqa64 XWORD(%%RED_POLY), [rel POLY2] +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 7 + vaesenc %%B00_03, %%B00_03, %%AESKEY2 + vaesenc %%B04_07, %%B04_07, %%AESKEY2 + vaesenc %%B08_11, %%B08_11, %%AESKEY2 + vaesenc %%B12_15, %%B12_15, %%AESKEY2 + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 9)] + + ;; ================================================= + ;; Add mid product to high and low +%ifidn %%DO_REDUCTION, final_reduction + vpternlogq %%GH1H, %%GH2H, %%GH2M, 0x96 ; TH = TH1 + TH2 + TM>>64 + vpxorq %%GH1H, %%TO_REDUCE_H + vpternlogq %%GH1L, %%GH2L, %%GH1M, 0x96 ; TL = TL1 + TL2 + TM<<64 + vpxorq %%GH1L, %%TO_REDUCE_L +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 8 + vaesenc %%B00_03, %%B00_03, %%AESKEY1 + vaesenc %%B04_07, %%B04_07, %%AESKEY1 + vaesenc %%B08_11, %%B08_11, %%AESKEY1 + vaesenc %%B12_15, %%B12_15, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 10)] + + ;; ================================================= + ;; horizontal xor of low and high 4x128 +%ifidn %%DO_REDUCTION, final_reduction + VHPXORI4x128 %%GH1H, %%GH2H + VHPXORI4x128 %%GH1L, %%GH2L +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES round 9 + vaesenc %%B00_03, %%B00_03, %%AESKEY2 + vaesenc %%B04_07, %%B04_07, %%AESKEY2 + vaesenc %%B08_11, %%B08_11, %%AESKEY2 + vaesenc %%B12_15, %%B12_15, %%AESKEY2 +%if (NROUNDS >= 11) + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 11)] +%endif + ;; ================================================= + ;; first phase of reduction +%ifidn %%DO_REDUCTION, final_reduction + vpclmulqdq XWORD(%%RED_P1), XWORD(%%RED_POLY), XWORD(%%GH1L), 0x01 + vpslldq XWORD(%%RED_P1), XWORD(%%RED_P1), 8 ; shift-L 2 DWs + vpxorq XWORD(%%RED_P1), XWORD(%%GH1L), XWORD(%%RED_P1) ; first phase of the reduct +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; AES rounds up to 11 (AES192) or 13 (AES256) + ;; AES128 is done +%if (NROUNDS >= 11) + vaesenc %%B00_03, %%B00_03, %%AESKEY1 + vaesenc %%B04_07, %%B04_07, %%AESKEY1 + vaesenc %%B08_11, %%B08_11, %%AESKEY1 + vaesenc %%B12_15, %%B12_15, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 12)] + + vaesenc %%B00_03, %%B00_03, %%AESKEY2 + vaesenc %%B04_07, %%B04_07, %%AESKEY2 + vaesenc %%B08_11, %%B08_11, %%AESKEY2 + vaesenc %%B12_15, %%B12_15, %%AESKEY2 +%if (NROUNDS == 13) + vbroadcastf64x2 %%AESKEY2, [%%GDATA + (16 * 13)] + + vaesenc %%B00_03, %%B00_03, %%AESKEY1 + vaesenc %%B04_07, %%B04_07, %%AESKEY1 + vaesenc %%B08_11, %%B08_11, %%AESKEY1 + vaesenc %%B12_15, %%B12_15, %%AESKEY1 + vbroadcastf64x2 %%AESKEY1, [%%GDATA + (16 * 14)] + + vaesenc %%B00_03, %%B00_03, %%AESKEY2 + vaesenc %%B04_07, %%B04_07, %%AESKEY2 + vaesenc %%B08_11, %%B08_11, %%AESKEY2 + vaesenc %%B12_15, %%B12_15, %%AESKEY2 +%endif ; GCM256 / NROUNDS = 13 (15 including the first and the last) +%endif ; GCM192 / NROUNDS = 11 (13 including the first and the last) + + ;; ================================================= + ;; second phase of the reduction +%ifidn %%DO_REDUCTION, final_reduction + vpclmulqdq XWORD(%%RED_T1), XWORD(%%RED_POLY), XWORD(%%RED_P1), 0x00 + vpsrldq XWORD(%%RED_T1), XWORD(%%RED_T1), 4 ; shift-R 1-DW to obtain 2-DWs shift-R + + vpclmulqdq XWORD(%%RED_T2), XWORD(%%RED_POLY), XWORD(%%RED_P1), 0x10 + vpslldq XWORD(%%RED_T2), XWORD(%%RED_T2), 4 ; shift-L 1-DW for result without shifts + ;; GH1H = GH1H x RED_T1 x RED_T2 + vpternlogq XWORD(%%GH1H), XWORD(%%RED_T2), XWORD(%%RED_T1), 0x96 +%endif + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; the last AES round + vaesenclast %%B00_03, %%B00_03, %%AESKEY1 + vaesenclast %%B04_07, %%B04_07, %%AESKEY1 + vaesenclast %%B08_11, %%B08_11, %%AESKEY1 + vaesenclast %%B12_15, %%B12_15, %%AESKEY1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; XOR against plain/cipher text + vpxorq %%B00_03, %%B00_03, %%DATA1 + vpxorq %%B04_07, %%B04_07, %%DATA2 + vpxorq %%B08_11, %%B08_11, %%DATA3 + vpxorq %%B12_15, %%B12_15, %%DATA4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; store cipher/plain text + VX512STR [%%CIPH_PLAIN_OUT + %%DATA_OFFSET + %%DATA_DISPL + (0 * 64)], %%B00_03 + VX512STR [%%CIPH_PLAIN_OUT + %%DATA_OFFSET + %%DATA_DISPL + (1 * 64)], %%B04_07 + VX512STR [%%CIPH_PLAIN_OUT + %%DATA_OFFSET + %%DATA_DISPL + (2 * 64)], %%B08_11 + VX512STR [%%CIPH_PLAIN_OUT + %%DATA_OFFSET + %%DATA_DISPL + (3 * 64)], %%B12_15 + + ;; ================================================= + ;; shuffle cipher text blocks for GHASH computation +%ifidn %%ENC_DEC, ENC + vpshufb %%B00_03, %%B00_03, %%SHFMSK + vpshufb %%B04_07, %%B04_07, %%SHFMSK + vpshufb %%B08_11, %%B08_11, %%SHFMSK + vpshufb %%B12_15, %%B12_15, %%SHFMSK +%else + vpshufb %%B00_03, %%DATA1, %%SHFMSK + vpshufb %%B04_07, %%DATA2, %%SHFMSK + vpshufb %%B08_11, %%DATA3, %%SHFMSK + vpshufb %%B12_15, %%DATA4, %%SHFMSK +%endif + + ;; ================================================= + ;; store shuffled cipher text for ghashing + vmovdqa64 [rsp + %%AESOUT_BLK_OFFSET + (0*64)], %%B00_03 + vmovdqa64 [rsp + %%AESOUT_BLK_OFFSET + (1*64)], %%B04_07 + vmovdqa64 [rsp + %%AESOUT_BLK_OFFSET + (2*64)], %%B08_11 + vmovdqa64 [rsp + %%AESOUT_BLK_OFFSET + (3*64)], %%B12_15 + +%ifidn %%DO_REDUCTION, final_reduction + ;; ================================================= + ;; Return GHASH value through %%GH1H +%endif + +%endmacro ; GHASH_16_ENCRYPT_16_PARALLEL + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Encryption of a single block +%macro ENCRYPT_SINGLE_BLOCK 2 +%define %%GDATA %1 +%define %%XMM0 %2 + + vpxorq %%XMM0, %%XMM0, [%%GDATA+16*0] +%assign i 1 +%rep NROUNDS + vaesenc %%XMM0, [%%GDATA+16*i] +%assign i (i+1) +%endrep + vaesenclast %%XMM0, [%%GDATA+16*i] +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Save register content for the caller +%macro FUNC_SAVE 0 + ;; Required for Update/GMC_ENC + ;the number of pushes must equal STACK_OFFSET + mov rax, rsp + + sub rsp, STACK_FRAME_SIZE + and rsp, ~63 + + mov [rsp + STACK_GP_OFFSET + 0*8], r12 + mov [rsp + STACK_GP_OFFSET + 1*8], r13 + mov [rsp + STACK_GP_OFFSET + 2*8], r14 + mov [rsp + STACK_GP_OFFSET + 3*8], r15 + mov [rsp + STACK_GP_OFFSET + 4*8], rax ; stack + mov r14, rax ; r14 is used to retrieve stack args + mov [rsp + STACK_GP_OFFSET + 5*8], rbp + mov [rsp + STACK_GP_OFFSET + 6*8], rbx +%ifidn __OUTPUT_FORMAT__, win64 + mov [rsp + STACK_GP_OFFSET + 7*8], rdi + mov [rsp + STACK_GP_OFFSET + 8*8], rsi +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + ; xmm6:xmm15 need to be maintained for Windows + vmovdqu [rsp + STACK_XMM_OFFSET + 0*16], xmm6 + vmovdqu [rsp + STACK_XMM_OFFSET + 1*16], xmm7 + vmovdqu [rsp + STACK_XMM_OFFSET + 2*16], xmm8 + vmovdqu [rsp + STACK_XMM_OFFSET + 3*16], xmm9 + vmovdqu [rsp + STACK_XMM_OFFSET + 4*16], xmm10 + vmovdqu [rsp + STACK_XMM_OFFSET + 5*16], xmm11 + vmovdqu [rsp + STACK_XMM_OFFSET + 6*16], xmm12 + vmovdqu [rsp + STACK_XMM_OFFSET + 7*16], xmm13 + vmovdqu [rsp + STACK_XMM_OFFSET + 8*16], xmm14 + vmovdqu [rsp + STACK_XMM_OFFSET + 9*16], xmm15 +%endif +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Restore register content for the caller +%macro FUNC_RESTORE 0 + +%ifdef SAFE_DATA + clear_scratch_gps_asm + clear_scratch_zmms_asm +%else + vzeroupper +%endif + +%ifidn __OUTPUT_FORMAT__, win64 + vmovdqu xmm15, [rsp + STACK_XMM_OFFSET + 9*16] + vmovdqu xmm14, [rsp + STACK_XMM_OFFSET + 8*16] + vmovdqu xmm13, [rsp + STACK_XMM_OFFSET + 7*16] + vmovdqu xmm12, [rsp + STACK_XMM_OFFSET + 6*16] + vmovdqu xmm11, [rsp + STACK_XMM_OFFSET + 5*16] + vmovdqu xmm10, [rsp + STACK_XMM_OFFSET + 4*16] + vmovdqu xmm9, [rsp + STACK_XMM_OFFSET + 3*16] + vmovdqu xmm8, [rsp + STACK_XMM_OFFSET + 2*16] + vmovdqu xmm7, [rsp + STACK_XMM_OFFSET + 1*16] + vmovdqu xmm6, [rsp + STACK_XMM_OFFSET + 0*16] +%endif + + ;; Required for Update/GMC_ENC + mov rbp, [rsp + STACK_GP_OFFSET + 5*8] + mov rbx, [rsp + STACK_GP_OFFSET + 6*8] +%ifidn __OUTPUT_FORMAT__, win64 + mov rdi, [rsp + STACK_GP_OFFSET + 7*8] + mov rsi, [rsp + STACK_GP_OFFSET + 8*8] +%endif + mov r12, [rsp + STACK_GP_OFFSET + 0*8] + mov r13, [rsp + STACK_GP_OFFSET + 1*8] + mov r14, [rsp + STACK_GP_OFFSET + 2*8] + mov r15, [rsp + STACK_GP_OFFSET + 3*8] + mov rsp, [rsp + STACK_GP_OFFSET + 4*8] ; stack +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Calculate J0 for cases when IV length is different than 12 bytes +%macro CALC_J0 27 +%define %%KEY %1 ;; [in] Pointer to GCM KEY structure +%define %%IV %2 ;; [in] Pointer to IV +%define %%IV_LEN %3 ;; [in] IV length +%define %%J0 %4 ;; [out] XMM reg to contain J0 +%define %%ZT0 %5 ;; [clobbered] ZMM register +%define %%ZT1 %6 ;; [clobbered] ZMM register +%define %%ZT2 %7 ;; [clobbered] ZMM register +%define %%ZT3 %8 ;; [clobbered] ZMM register +%define %%ZT4 %9 ;; [clobbered] ZMM register +%define %%ZT5 %10 ;; [clobbered] ZMM register +%define %%ZT6 %11 ;; [clobbered] ZMM register +%define %%ZT7 %12 ;; [clobbered] ZMM register +%define %%ZT8 %13 ;; [clobbered] ZMM register +%define %%ZT9 %14 ;; [clobbered] ZMM register +%define %%ZT10 %15 ;; [clobbered] ZMM register +%define %%ZT11 %16 ;; [clobbered] ZMM register +%define %%ZT12 %17 ;; [clobbered] ZMM register +%define %%ZT13 %18 ;; [clobbered] ZMM register +%define %%ZT14 %19 ;; [clobbered] ZMM register +%define %%ZT15 %20 ;; [clobbered] ZMM register +%define %%ZT16 %21 ;; [clobbered] ZMM register +%define %%ZT17 %22 ;; [clobbered] ZMM register +%define %%T1 %23 ;; [clobbered] GP register +%define %%T2 %24 ;; [clobbered] GP register +%define %%T3 %25 ;; [clobbered] GP register +%define %%MASKREG %26 ;; [clobbered] mask register +;; IPPCP: unlike IPsec-MB this macro is called in iv_finalize only that can follow +;; several iv_update calls, so iv_total_len should be an additional external parameter +;; here. +%define %%IV_TOTAL_LEN %27 ;; [in] total len of IV + + ;; J0 = GHASH(IV || 0s+64 || len(IV)64) + ;; s = 16 * RoundUp(len(IV)/16) - len(IV) */ + + ;; Calculate GHASH of (IV || 0s) + ;; vpxor %%J0, %%J0 ;; IPPCP: xor disabled (zeroing is done outside) + CALC_AAD_HASH %%IV, %%IV_LEN, %%J0, %%KEY, %%ZT0, %%ZT1, %%ZT2, %%ZT3, \ + %%ZT4, %%ZT5, %%ZT6, %%ZT7, %%ZT8, %%ZT9, %%ZT10, %%ZT11, \ + %%ZT12, %%ZT13, %%ZT14, %%ZT15, %%ZT16, %%ZT17, \ + %%T1, %%T2, %%T3, %%MASKREG + + ;; Calculate GHASH of last 16-byte block (0 || len(IV)64) + ;; mov %%T1, %%IV_LEN ;; IPPCP: iv total len is external parameter + mov %%T1, %%IV_TOTAL_LEN + shl %%T1, 3 ;; IV length in bits + vmovq XWORD(%%ZT2), %%T1 + + ;; Might need shuffle of ZT2 + vpxorq %%J0, XWORD(%%ZT2), %%J0 + + vmovdqu64 XWORD(%%ZT0), [%%KEY + HashKey_1] + GHASH_MUL %%J0, XWORD(%%ZT0), XWORD(%%ZT1), XWORD(%%ZT2), XWORD(%%ZT3), XWORD(%%ZT4), XWORD(%%ZT5) + + vpshufb %%J0, [rel SHUF_MASK] ; perform a 16Byte swap +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Cipher and ghash of payloads shorter than 256 bytes +;;; - number of blocks in the message comes as argument +;;; - depending on the number of blocks an optimized variant of +;;; INITIAL_BLOCKS_PARTIAL is invoked +%macro GCM_ENC_DEC_SMALL 39 +%define %%GDATA_KEY %1 ; [in] key pointer +%define %%GDATA_CTX %2 ; [in] context pointer +%define %%CIPH_PLAIN_OUT %3 ; [in] output buffer +%define %%PLAIN_CIPH_IN %4 ; [in] input buffer +%define %%PLAIN_CIPH_LEN %5 ; [in] buffer length +%define %%ENC_DEC %6 ; [in] cipher direction +%define %%DATA_OFFSET %7 ; [in] data offset +%define %%LENGTH %8 ; [in] GP data length +%define %%NUM_BLOCKS %9 ; [in] GP number of blocks to process 1 to 16 +%define %%CTR %10 ; [in/out] XMM counter block +%define %%HASH_IN_OUT %11 ; [in/out] XMM GHASH value +%define %%INSTANCE_TYPE %12 ; [in] single or multi call +%define %%ZTMP0 %13 ; [clobbered] ZMM register +%define %%ZTMP1 %14 ; [clobbered] ZMM register +%define %%ZTMP2 %15 ; [clobbered] ZMM register +%define %%ZTMP3 %16 ; [clobbered] ZMM register +%define %%ZTMP4 %17 ; [clobbered] ZMM register +%define %%ZTMP5 %18 ; [clobbered] ZMM register +%define %%ZTMP6 %19 ; [clobbered] ZMM register +%define %%ZTMP7 %20 ; [clobbered] ZMM register +%define %%ZTMP8 %21 ; [clobbered] ZMM register +%define %%ZTMP9 %22 ; [clobbered] ZMM register +%define %%ZTMP10 %23 ; [clobbered] ZMM register +%define %%ZTMP11 %24 ; [clobbered] ZMM register +%define %%ZTMP12 %25 ; [clobbered] ZMM register +%define %%ZTMP13 %26 ; [clobbered] ZMM register +%define %%ZTMP14 %27 ; [clobbered] ZMM register +%define %%ZTMP15 %28 ; [clobbered] ZMM register +%define %%ZTMP16 %29 ; [clobbered] ZMM register +%define %%ZTMP17 %30 ; [clobbered] ZMM register +%define %%ZTMP18 %31 ; [clobbered] ZMM register +%define %%ZTMP19 %32 ; [clobbered] ZMM register +%define %%ZTMP20 %33 ; [clobbered] ZMM register +%define %%ZTMP21 %34 ; [clobbered] ZMM register +%define %%ZTMP22 %35 ; [clobbered] ZMM register +%define %%IA0 %36 ; [clobbered] GP register +%define %%IA1 %37 ; [clobbered] GP register +%define %%MASKREG %38 ; [clobbered] mask register +%define %%SHUFMASK %39 ; [clobbered] ZMM to be used for BE/LE shuffle mask + + cmp DWORD(%%NUM_BLOCKS), 8 + je %%_small_initial_num_blocks_is_8 + jb %%_small_initial_num_blocks_is_7_1 + + cmp DWORD(%%NUM_BLOCKS), 12 + je %%_small_initial_num_blocks_is_12 + jb %%_small_initial_num_blocks_is_11_9 + + ;; 16, 15, 14 or 13 + cmp DWORD(%%NUM_BLOCKS), 15 + ja %%_small_initial_num_blocks_is_16 + je %%_small_initial_num_blocks_is_15 + cmp DWORD(%%NUM_BLOCKS), 14 + je %%_small_initial_num_blocks_is_14 + jmp %%_small_initial_num_blocks_is_13 + +%%_small_initial_num_blocks_is_11_9: + ;; 11, 10 or 9 + cmp DWORD(%%NUM_BLOCKS), 10 + ja %%_small_initial_num_blocks_is_11 + je %%_small_initial_num_blocks_is_10 + jmp %%_small_initial_num_blocks_is_9 + +%%_small_initial_num_blocks_is_7_1: + cmp DWORD(%%NUM_BLOCKS), 4 + je %%_small_initial_num_blocks_is_4 + jb %%_small_initial_num_blocks_is_3_1 + ;; 7, 6 or 5 + cmp DWORD(%%NUM_BLOCKS), 6 + ja %%_small_initial_num_blocks_is_7 + je %%_small_initial_num_blocks_is_6 + jmp %%_small_initial_num_blocks_is_5 + +%%_small_initial_num_blocks_is_3_1: + ;; 3, 2 or 1 + cmp DWORD(%%NUM_BLOCKS), 2 + ja %%_small_initial_num_blocks_is_3 + je %%_small_initial_num_blocks_is_2 + + ;; for %%NUM_BLOCKS == 1, just fall through and no 'jmp' needed + + ;; Use rep to generate different block size variants + ;; - one block size has to be the first one + ;; - ZTMP15 - ZTMP22 are free +%assign num_blocks 1 +%rep 16 +%%_small_initial_num_blocks_is_ %+ num_blocks : + INITIAL_BLOCKS_PARTIAL %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, \ + %%PLAIN_CIPH_IN, %%LENGTH, %%DATA_OFFSET, num_blocks, \ + %%CTR, %%HASH_IN_OUT, %%ENC_DEC, %%INSTANCE_TYPE, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, \ + %%ZTMP5, %%ZTMP6, %%ZTMP7, %%ZTMP8, %%ZTMP9, \ + %%ZTMP10, %%ZTMP11, %%ZTMP12, %%ZTMP13, %%ZTMP14, \ + %%IA0, %%IA1, %%MASKREG, %%SHUFMASK +%if num_blocks != 16 + jmp %%_small_initial_blocks_encrypted +%endif +%assign num_blocks (num_blocks + 1) +%endrep + +%%_small_initial_blocks_encrypted: + +%endmacro ; GCM_ENC_DEC_SMALL + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; GCM_ENC_DEC Encodes/Decodes given data. Assumes that the passed gcm_context_data struct +; has been initialized by GCM_INIT +; Requires the input data be at least 1 byte long because of READ_SMALL_INPUT_DATA. +; Input: gcm_key_data struct* (GDATA_KEY), gcm_context_data *(GDATA_CTX), input text (PLAIN_CIPH_IN), +; input text length (PLAIN_CIPH_LEN) and whether encoding or decoding (ENC_DEC). +; Output: A cipher of the given plain text (CIPH_PLAIN_OUT), and updated GDATA_CTX +; Clobbers rax, r10-r15, and zmm0-zmm31, k1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GCM_ENC_DEC 7 +%define %%GDATA_KEY %1 ; [in] key pointer +%define %%GDATA_CTX %2 ; [in] context pointer +%define %%CIPH_PLAIN_OUT %3 ; [in] output buffer pointer +%define %%PLAIN_CIPH_IN %4 ; [in] input buffer pointer +%define %%PLAIN_CIPH_LEN %5 ; [in] buffer length +%define %%ENC_DEC %6 ; [in] cipher direction +%define %%INSTANCE_TYPE %7 ; [in] 'single_call' or 'multi_call' selection + +%define %%IA0 r10 +%define %%IA1 r12 +%define %%IA2 r13 +%define %%IA3 r15 +%define %%IA4 r11 +%define %%IA5 rax +%define %%IA6 rbx + +%ifidn __OUTPUT_FORMAT__, win64 +%define %%LENGTH %%IA2 +%endif +%define %%CTR_CHECK %%IA3 +%define %%DATA_OFFSET %%IA4 +%define %%HASHK_PTR %%IA6 + +%define %%CTR_BLOCKz zmm2 +%define %%CTR_BLOCKx xmm2 ; hardcoded in GCM_INIT + +%define %%AAD_HASHz zmm14 +%define %%AAD_HASHx xmm14 ; hardcoded in GCM_COMPLETE + +%define %%ZTMP0 zmm0 +%define %%ZTMP1 zmm3 +%define %%ZTMP2 zmm4 +%define %%ZTMP3 zmm5 +%define %%ZTMP4 zmm6 +%define %%ZTMP5 zmm7 +%define %%ZTMP6 zmm10 +%define %%ZTMP7 zmm11 +%define %%ZTMP8 zmm12 +%define %%ZTMP9 zmm13 +%define %%ZTMP10 zmm15 +%define %%ZTMP11 zmm16 +%define %%ZTMP12 zmm17 + +%define %%ZTMP13 zmm19 +%define %%ZTMP14 zmm20 +%define %%ZTMP15 zmm21 +%define %%ZTMP16 zmm30 +%define %%ZTMP17 zmm31 +%define %%ZTMP18 zmm1 +%define %%ZTMP19 zmm18 +%define %%ZTMP20 zmm8 +%define %%ZTMP21 zmm22 +%define %%ZTMP22 zmm23 + +%define %%GH zmm24 +%define %%GL zmm25 +%define %%GM zmm26 +%define %%SHUF_MASK zmm29 + +;;; Unused in the small packet path +%define %%ADDBE_4x4 zmm27 +%define %%ADDBE_1234 zmm28 + +%define %%MASKREG k1 + +;; reduction every 48 blocks, depth 32 blocks +;; @note 48 blocks is the maximum capacity of the stack frame +%assign big_loop_nblocks 48 +%assign big_loop_depth 32 + +;;; Macro flow depending on packet size +;;; - LENGTH <= 16 blocks +;;; - cipher followed by hashing (reduction) +;;; - 16 blocks < LENGTH < 32 blocks +;;; - cipher 16 blocks +;;; - cipher N blocks & hash 16 blocks, hash N blocks (reduction) +;;; - 32 blocks < LENGTH < 48 blocks +;;; - cipher 2 x 16 blocks +;;; - hash 16 blocks +;;; - cipher N blocks & hash 16 blocks, hash N blocks (reduction) +;;; - LENGTH >= 48 blocks +;;; - cipher 2 x 16 blocks +;;; - while (data_to_cipher >= 48 blocks): +;;; - cipher 16 blocks & hash 16 blocks +;;; - cipher 16 blocks & hash 16 blocks +;;; - cipher 16 blocks & hash 16 blocks (reduction) +;;; - if (data_to_cipher >= 32 blocks): +;;; - cipher 16 blocks & hash 16 blocks +;;; - cipher 16 blocks & hash 16 blocks +;;; - hash 16 blocks (reduction) +;;; - cipher N blocks & hash 16 blocks, hash N blocks (reduction) +;;; - elif (data_to_cipher >= 16 blocks): +;;; - cipher 16 blocks & hash 16 blocks +;;; - hash 16 blocks +;;; - cipher N blocks & hash 16 blocks, hash N blocks (reduction) +;;; - else: +;;; - hash 16 blocks +;;; - cipher N blocks & hash 16 blocks, hash N blocks (reduction) + +%ifidn __OUTPUT_FORMAT__, win64 + cmp %%PLAIN_CIPH_LEN, 0 +%else + or %%PLAIN_CIPH_LEN, %%PLAIN_CIPH_LEN +%endif + je %%_enc_dec_done + + ;; Update length of data processed +%ifidn __OUTPUT_FORMAT__, win64 + mov %%IA0, %%PLAIN_CIPH_LEN + add [%%GDATA_CTX + InLen], %%IA0 +%else + add [%%GDATA_CTX + InLen], %%PLAIN_CIPH_LEN +%endif + vmovdqu64 %%AAD_HASHx, [%%GDATA_CTX + AadHash] + +%ifidn %%INSTANCE_TYPE, multi_call + ;; NOTE: partial block processing makes only sense for multi_call here. + ;; Used for the update flow - if there was a previous partial + ;; block fill the remaining bytes here. + PARTIAL_BLOCK %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%PLAIN_CIPH_LEN, %%DATA_OFFSET, %%AAD_HASHx, %%ENC_DEC, \ + %%IA0, %%IA1, %%IA2, %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, \ + %%ZTMP5, %%ZTMP6, %%ZTMP7, %%ZTMP8, %%ZTMP9, %%MASKREG +%else + xor %%DATA_OFFSET, %%DATA_OFFSET +%endif + +%ifidn %%INSTANCE_TYPE, single_call + ;; use counter block from GCM_INIT +%else + vmovdqu64 %%CTR_BLOCKx, [%%GDATA_CTX + CurCount] +%endif + + ;; Save the amount of data left to process in %%LENGTH +%ifidn __OUTPUT_FORMAT__, win64 + mov %%LENGTH, %%PLAIN_CIPH_LEN +%else +%define %%LENGTH %%PLAIN_CIPH_LEN ;; PLAIN_CIPH_LEN is a register on linux +%endif + +%ifidn %%INSTANCE_TYPE, multi_call + ;; NOTE: %%DATA_OFFSET is zero in single_call case. + ;; Consequently PLAIN_CIPH_LEN will never be zero after + ;; %%DATA_OFFSET subtraction below. + ;; There may be no more data if it was consumed in the partial block. + sub %%LENGTH, %%DATA_OFFSET + je %%_enc_dec_done +%endif ; %%INSTANCE_TYPE, multi_call + + cmp %%LENGTH, (16 * 16) + jbe %%_message_below_equal_16_blocks + + vmovdqa64 %%SHUF_MASK, [rel SHUF_MASK] + vmovdqa64 %%ADDBE_4x4, [rel ddq_addbe_4444] + vmovdqa64 %%ADDBE_1234, [rel ddq_addbe_1234] + + ;; start the pipeline + ;; - 32 blocks aes-ctr + ;; - 16 blocks ghash + aes-ctr + + ;; set up CTR_CHECK + vmovd DWORD(%%CTR_CHECK), %%CTR_BLOCKx + and DWORD(%%CTR_CHECK), 255 + + ;; in LE format after init, convert to BE + vshufi64x2 %%CTR_BLOCKz, %%CTR_BLOCKz, %%CTR_BLOCKz, 0 + vpshufb %%CTR_BLOCKz, %%CTR_BLOCKz, %%SHUF_MASK + + ;; ==== AES-CTR - first 16 blocks +%assign aesout_offset (STACK_LOCAL_OFFSET + (0 * 16)) +%assign data_in_out_offset 0 + + INITIAL_BLOCKS_16 %%PLAIN_CIPH_IN, %%CIPH_PLAIN_OUT, %%GDATA_KEY, %%DATA_OFFSET, \ + no_ghash, %%CTR_BLOCKz, %%CTR_CHECK, %%ADDBE_4x4, %%ADDBE_1234, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, \ + %%ZTMP5, %%ZTMP6, %%ZTMP7, %%ZTMP8, \ + %%SHUF_MASK, %%ENC_DEC, aesout_offset, data_in_out_offset + + cmp %%LENGTH, (32 * 16) + jb %%_message_below_32_blocks + + ;; ==== AES-CTR - next 16 blocks +%assign aesout_offset (STACK_LOCAL_OFFSET + (16 * 16)) +%assign data_in_out_offset (16 * 16) + + INITIAL_BLOCKS_16 %%PLAIN_CIPH_IN, %%CIPH_PLAIN_OUT, %%GDATA_KEY, %%DATA_OFFSET, \ + no_ghash, %%CTR_BLOCKz, %%CTR_CHECK, %%ADDBE_4x4, %%ADDBE_1234, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, \ + %%ZTMP5, %%ZTMP6, %%ZTMP7, %%ZTMP8, \ + %%SHUF_MASK, %%ENC_DEC, aesout_offset, data_in_out_offset + + add %%DATA_OFFSET, (32 * 16) + sub %%LENGTH, (32 * 16) + + cmp %%LENGTH, (big_loop_nblocks * 16) + jb %%_no_more_big_nblocks + + ;; ==== + ;; ==== AES-CTR + GHASH - 48 blocks loop + ;; ==== +%%_encrypt_big_nblocks: + ;; ==== AES-CTR + GHASH - 16 blocks, start +%assign aesout_offset (STACK_LOCAL_OFFSET + (32 * 16)) +%assign data_in_out_offset (0 * 16) +%assign ghashin_offset (STACK_LOCAL_OFFSET + (0 * 16)) + + GHASH_16_ENCRYPT_16_PARALLEL %%GDATA_KEY, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%CTR_BLOCKz, %%CTR_CHECK, \ + HashKey_48, aesout_offset, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, \ + %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, \ + %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11,\ + %%ZTMP12, %%ZTMP13, %%ZTMP14, %%ZTMP15,\ + %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, \ + %%ZTMP20, %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, \ + %%GL, %%GH, %%GM, \ + first_time, %%ENC_DEC, data_in_out_offset, %%AAD_HASHz + + ;; ==== AES-CTR + GHASH - 16 blocks, no reduction +%assign aesout_offset (STACK_LOCAL_OFFSET + (0 * 16)) +%assign data_in_out_offset (16 * 16) +%assign ghashin_offset (STACK_LOCAL_OFFSET + (16 * 16)) + + GHASH_16_ENCRYPT_16_PARALLEL %%GDATA_KEY, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%CTR_BLOCKz, %%CTR_CHECK, \ + HashKey_32, aesout_offset, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, \ + %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, \ + %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11,\ + %%ZTMP12, %%ZTMP13, %%ZTMP14, %%ZTMP15,\ + %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, \ + %%ZTMP20, %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, \ + %%GL, %%GH, %%GM, \ + no_reduction, %%ENC_DEC, data_in_out_offset, no_ghash_in + + ;; ==== AES-CTR + GHASH - 16 blocks, reduction +%assign aesout_offset (STACK_LOCAL_OFFSET + (16 * 16)) +%assign data_in_out_offset (32 * 16) +%assign ghashin_offset (STACK_LOCAL_OFFSET + (32 * 16)) + + GHASH_16_ENCRYPT_16_PARALLEL %%GDATA_KEY, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%CTR_BLOCKz, %%CTR_CHECK, \ + HashKey_16, aesout_offset, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, \ + %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, \ + %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11,\ + %%ZTMP12, %%ZTMP13, %%ZTMP14, %%ZTMP15,\ + %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, \ + %%ZTMP20, %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, \ + %%GL, %%GH, %%GM, \ + final_reduction, %%ENC_DEC, data_in_out_offset, no_ghash_in + + ;; === xor cipher block 0 with GHASH (ZT4) + vmovdqa64 %%AAD_HASHz, %%ZTMP4 + + add %%DATA_OFFSET, (big_loop_nblocks * 16) + sub %%LENGTH, (big_loop_nblocks * 16) + cmp %%LENGTH, (big_loop_nblocks * 16) + jae %%_encrypt_big_nblocks + +%%_no_more_big_nblocks: + + cmp %%LENGTH, (32 * 16) + jae %%_encrypt_32_blocks + + cmp %%LENGTH, (16 * 16) + jae %%_encrypt_16_blocks + + ;; ===================================================== + ;; ===================================================== + ;; ==== GHASH 1 x 16 blocks + ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks + ;; ==== then GHASH N blocks +%%_encrypt_0_blocks_ghash_32: + ;; calculate offset to the right hash key +%ifidn %%INSTANCE_TYPE, multi_call + mov DWORD(%%IA0), DWORD(%%LENGTH) +%else + lea DWORD(%%IA0), [DWORD(%%LENGTH) + 15] +%endif + and DWORD(%%IA0), ~15 + mov DWORD(%%HASHK_PTR), HashKey_32 + sub DWORD(%%HASHK_PTR), DWORD(%%IA0) + + ;; ==== GHASH 32 blocks and follow with reduction + GHASH_16 start, %%GH, %%GM, %%GL, rsp, STACK_LOCAL_OFFSET, (0 * 16), %%GDATA_KEY, %%HASHK_PTR, 0, %%AAD_HASHz, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, %%ZTMP8, %%ZTMP9 + + ;; ==== GHASH 1 x 16 blocks with reduction + cipher and ghash on the reminder +%assign ghashin_offset (STACK_LOCAL_OFFSET + (16 * 16)) + add DWORD(%%HASHK_PTR), (16 * 16) + + GCM_ENC_DEC_LAST \ + %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%DATA_OFFSET, %%LENGTH, %%CTR_BLOCKz, %%CTR_CHECK, \ + %%HASHK_PTR, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, %%ZTMP5, %%ZTMP6, \ + %%ZTMP7, %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11, %%ZTMP12, %%ZTMP13, \ + %%ZTMP14, %%ZTMP15, %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, %%ZTMP20, \ + %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, mid, %%GL, %%GH, %%GM, \ + %%ENC_DEC, %%AAD_HASHz, %%IA0, %%IA5, %%MASKREG, %%INSTANCE_TYPE + +%ifidn %%INSTANCE_TYPE, multi_call + vpshufb %%CTR_BLOCKx, %%CTR_BLOCKx, XWORD(%%SHUF_MASK) +%endif + jmp %%_ghash_done + + ;; ===================================================== + ;; ===================================================== + ;; ==== GHASH & encrypt 1 x 16 blocks + ;; ==== GHASH & encrypt 1 x 16 blocks + ;; ==== GHASH 1 x 16 blocks (reduction) + ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks + ;; ==== then GHASH N blocks +%%_encrypt_32_blocks: + ;; ==== AES-CTR + GHASH - 16 blocks, start +%assign aesout_offset (STACK_LOCAL_OFFSET + (32 * 16)) +%assign ghashin_offset (STACK_LOCAL_OFFSET + (0 * 16)) +%assign data_in_out_offset (0 * 16) + + GHASH_16_ENCRYPT_16_PARALLEL %%GDATA_KEY, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%CTR_BLOCKz, %%CTR_CHECK, \ + HashKey_48, aesout_offset, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, \ + %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, \ + %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11,\ + %%ZTMP12, %%ZTMP13, %%ZTMP14, %%ZTMP15,\ + %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, \ + %%ZTMP20, %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, \ + %%GL, %%GH, %%GM, \ + first_time, %%ENC_DEC, data_in_out_offset, %%AAD_HASHz + + ;; ==== AES-CTR + GHASH - 16 blocks, no reduction +%assign aesout_offset (STACK_LOCAL_OFFSET + (0 * 16)) +%assign ghashin_offset (STACK_LOCAL_OFFSET + (16 * 16)) +%assign data_in_out_offset (16 * 16) + + GHASH_16_ENCRYPT_16_PARALLEL %%GDATA_KEY, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%CTR_BLOCKz, %%CTR_CHECK, \ + HashKey_32, aesout_offset, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, \ + %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, \ + %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11,\ + %%ZTMP12, %%ZTMP13, %%ZTMP14, %%ZTMP15,\ + %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, \ + %%ZTMP20, %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, \ + %%GL, %%GH, %%GM, \ + no_reduction, %%ENC_DEC, data_in_out_offset, no_ghash_in + + ;; ==== GHASH 16 blocks with reduction + GHASH_16 end_reduce, %%GH, %%GM, %%GL, rsp, STACK_LOCAL_OFFSET, (32 * 16), %%GDATA_KEY, HashKey_16, 0, %%AAD_HASHz, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, %%ZTMP8, %%ZTMP9 + + ;; ==== GHASH 1 x 16 blocks with reduction + cipher and ghash on the reminder +%assign ghashin_offset (STACK_LOCAL_OFFSET + (0 * 16)) + + sub %%LENGTH, (32 * 16) + add %%DATA_OFFSET, (32 * 16) + + ;; calculate offset to the right hash key +%ifidn %%INSTANCE_TYPE, multi_call + mov DWORD(%%IA0), DWORD(%%LENGTH) +%else + lea DWORD(%%IA0), [DWORD(%%LENGTH) + 15] +%endif + and DWORD(%%IA0), ~15 + mov DWORD(%%HASHK_PTR), HashKey_16 + sub DWORD(%%HASHK_PTR), DWORD(%%IA0) + + GCM_ENC_DEC_LAST \ + %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%DATA_OFFSET, %%LENGTH, %%CTR_BLOCKz, %%CTR_CHECK, \ + %%HASHK_PTR, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, %%ZTMP5, %%ZTMP6, \ + %%ZTMP7, %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11, %%ZTMP12, %%ZTMP13, \ + %%ZTMP14, %%ZTMP15, %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, %%ZTMP20, \ + %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, start, %%GL, %%GH, %%GM, \ + %%ENC_DEC, %%AAD_HASHz, %%IA0, %%IA5, %%MASKREG, %%INSTANCE_TYPE + +%ifidn %%INSTANCE_TYPE, multi_call + vpshufb %%CTR_BLOCKx, %%CTR_BLOCKx, XWORD(%%SHUF_MASK) +%endif + jmp %%_ghash_done + + ;; ===================================================== + ;; ===================================================== + ;; ==== GHASH & encrypt 16 blocks (done before) + ;; ==== GHASH 1 x 16 blocks + ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks + ;; ==== then GHASH N blocks +%%_encrypt_16_blocks: + ;; ==== AES-CTR + GHASH - 16 blocks, start +%assign aesout_offset (STACK_LOCAL_OFFSET + (32 * 16)) +%assign ghashin_offset (STACK_LOCAL_OFFSET + (0 * 16)) +%assign data_in_out_offset (0 * 16) + + GHASH_16_ENCRYPT_16_PARALLEL %%GDATA_KEY, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, %%DATA_OFFSET, \ + %%CTR_BLOCKz, %%CTR_CHECK, \ + HashKey_48, aesout_offset, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, \ + %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, \ + %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11,\ + %%ZTMP12, %%ZTMP13, %%ZTMP14, %%ZTMP15,\ + %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, \ + %%ZTMP20, %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, \ + %%GL, %%GH, %%GM, \ + first_time, %%ENC_DEC, data_in_out_offset, %%AAD_HASHz + + ;; ==== GHASH 1 x 16 blocks + GHASH_16 mid, %%GH, %%GM, %%GL, rsp, STACK_LOCAL_OFFSET, (16 * 16), %%GDATA_KEY, HashKey_32, 0, no_hash_input, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, %%ZTMP8, %%ZTMP9 + + ;; ==== GHASH 1 x 16 blocks with reduction + cipher and ghash on the reminder +%assign ghashin_offset (STACK_LOCAL_OFFSET + (32 * 16)) + + sub %%LENGTH, (16 * 16) + add %%DATA_OFFSET, (16 * 16) + + GCM_ENC_DEC_LAST \ + %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%DATA_OFFSET, %%LENGTH, %%CTR_BLOCKz, %%CTR_CHECK, \ + HashKey_16, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, %%ZTMP5, %%ZTMP6, \ + %%ZTMP7, %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11, %%ZTMP12, %%ZTMP13, \ + %%ZTMP14, %%ZTMP15, %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, %%ZTMP20, \ + %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, end_reduce, %%GL, %%GH, %%GM, \ + %%ENC_DEC, %%AAD_HASHz, %%IA0, %%IA5, %%MASKREG, %%INSTANCE_TYPE + +%ifidn %%INSTANCE_TYPE, multi_call + vpshufb %%CTR_BLOCKx, %%CTR_BLOCKx, XWORD(%%SHUF_MASK) +%endif + jmp %%_ghash_done + +%%_message_below_32_blocks: + ;; 32 > number of blocks > 16 + + sub %%LENGTH, (16 * 16) + add %%DATA_OFFSET, (16 * 16) + +%assign ghashin_offset (STACK_LOCAL_OFFSET + (0 * 16)) + + ;; calculate offset to the right hash key +%ifidn %%INSTANCE_TYPE, multi_call + mov DWORD(%%IA0), DWORD(%%LENGTH) +%else + lea DWORD(%%IA0), [DWORD(%%LENGTH) + 15] +%endif + and DWORD(%%IA0), ~15 + mov DWORD(%%HASHK_PTR), HashKey_16 + sub DWORD(%%HASHK_PTR), DWORD(%%IA0) + + GCM_ENC_DEC_LAST \ + %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%DATA_OFFSET, %%LENGTH, %%CTR_BLOCKz, %%CTR_CHECK, \ + %%HASHK_PTR, ghashin_offset, %%SHUF_MASK, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, %%ZTMP4, %%ZTMP5, %%ZTMP6, \ + %%ZTMP7, %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11, %%ZTMP12, %%ZTMP13, \ + %%ZTMP14, %%ZTMP15, %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, %%ZTMP20, \ + %%ZTMP21, %%ZTMP22, \ + %%ADDBE_4x4, %%ADDBE_1234, start, %%GL, %%GH, %%GM, \ + %%ENC_DEC, %%AAD_HASHz, %%IA0, %%IA5, %%MASKREG, %%INSTANCE_TYPE + +%ifidn %%INSTANCE_TYPE, multi_call + vpshufb %%CTR_BLOCKx, %%CTR_BLOCKx, XWORD(%%SHUF_MASK) +%endif + jmp %%_ghash_done + +%%_message_below_equal_16_blocks: + ;; Determine how many blocks to process + ;; - process one additional block if there is a partial block + mov DWORD(%%IA1), DWORD(%%LENGTH) + add DWORD(%%IA1), 15 + shr DWORD(%%IA1), 4 + ;; %%IA1 can be in the range from 0 to 16 + + GCM_ENC_DEC_SMALL \ + %%GDATA_KEY, %%GDATA_CTX, %%CIPH_PLAIN_OUT, %%PLAIN_CIPH_IN, \ + %%PLAIN_CIPH_LEN, %%ENC_DEC, %%DATA_OFFSET, \ + %%LENGTH, %%IA1, %%CTR_BLOCKx, %%AAD_HASHx, %%INSTANCE_TYPE, \ + %%ZTMP0, %%ZTMP1, %%ZTMP2, %%ZTMP3, \ + %%ZTMP4, %%ZTMP5, %%ZTMP6, %%ZTMP7, \ + %%ZTMP8, %%ZTMP9, %%ZTMP10, %%ZTMP11, \ + %%ZTMP12, %%ZTMP13, %%ZTMP14, %%ZTMP15, \ + %%ZTMP16, %%ZTMP17, %%ZTMP18, %%ZTMP19, \ + %%ZTMP20, %%ZTMP21, %%ZTMP22, \ + %%IA0, %%IA3, %%MASKREG, %%SHUF_MASK + + ;; fall through to exit + +%%_ghash_done: +%ifidn %%INSTANCE_TYPE, multi_call + ;; save the last counter block + vmovdqu64 [%%GDATA_CTX + CurCount], %%CTR_BLOCKx +%endif + vmovdqu64 [%%GDATA_CTX + AadHash], %%AAD_HASHx +%%_enc_dec_done: + +%endmacro ; GCM_ENC_DEC + +;;; =========================================================================== +;;; =========================================================================== +;;; Encrypt/decrypt the initial 16 blocks +%macro INITIAL_BLOCKS_16 22 +%define %%IN %1 ; [in] input buffer +%define %%OUT %2 ; [in] output buffer +%define %%KP %3 ; [in] pointer to expanded keys +%define %%DATA_OFFSET %4 ; [in] data offset +%define %%GHASH %5 ; [in] ZMM with AAD (low 128 bits) +%define %%CTR %6 ; [in] ZMM with CTR BE blocks 4x128 bits +%define %%CTR_CHECK %7 ; [in/out] GPR with counter overflow check +%define %%ADDBE_4x4 %8 ; [in] ZMM 4x128bits with value 4 (big endian) +%define %%ADDBE_1234 %9 ; [in] ZMM 4x128bits with values 1, 2, 3 & 4 (big endian) +%define %%T0 %10 ; [clobered] temporary ZMM register +%define %%T1 %11 ; [clobered] temporary ZMM register +%define %%T2 %12 ; [clobered] temporary ZMM register +%define %%T3 %13 ; [clobered] temporary ZMM register +%define %%T4 %14 ; [clobered] temporary ZMM register +%define %%T5 %15 ; [clobered] temporary ZMM register +%define %%T6 %16 ; [clobered] temporary ZMM register +%define %%T7 %17 ; [clobered] temporary ZMM register +%define %%T8 %18 ; [clobered] temporary ZMM register +%define %%SHUF_MASK %19 ; [in] ZMM with BE/LE shuffle mask +%define %%ENC_DEC %20 ; [in] ENC (encrypt) or DEC (decrypt) selector +%define %%BLK_OFFSET %21 ; [in] stack frame offset to ciphered blocks +%define %%DATA_DISPL %22 ; [in] fixed numerical data displacement/offset + +%define %%B00_03 %%T5 +%define %%B04_07 %%T6 +%define %%B08_11 %%T7 +%define %%B12_15 %%T8 + +%assign stack_offset (%%BLK_OFFSET) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; prepare counter blocks + + cmp BYTE(%%CTR_CHECK), (256 - 16) + jae %%_next_16_overflow + vpaddd %%B00_03, %%CTR, %%ADDBE_1234 + vpaddd %%B04_07, %%B00_03, %%ADDBE_4x4 + vpaddd %%B08_11, %%B04_07, %%ADDBE_4x4 + vpaddd %%B12_15, %%B08_11, %%ADDBE_4x4 + jmp %%_next_16_ok +%%_next_16_overflow: + vpshufb %%CTR, %%CTR, %%SHUF_MASK + vmovdqa64 %%B12_15, [rel ddq_add_4444] + vpaddd %%B00_03, %%CTR, [rel ddq_add_1234] + vpaddd %%B04_07, %%B00_03, %%B12_15 + vpaddd %%B08_11, %%B04_07, %%B12_15 + vpaddd %%B12_15, %%B08_11, %%B12_15 + vpshufb %%B00_03, %%SHUF_MASK + vpshufb %%B04_07, %%SHUF_MASK + vpshufb %%B08_11, %%SHUF_MASK + vpshufb %%B12_15, %%SHUF_MASK +%%_next_16_ok: + vshufi64x2 %%CTR, %%B12_15, %%B12_15, 1111_1111b + add BYTE(%%CTR_CHECK), 16 + + ;; === load 16 blocks of data + VX512LDR %%T0, [%%IN + %%DATA_OFFSET + %%DATA_DISPL + (64*0)] + VX512LDR %%T1, [%%IN + %%DATA_OFFSET + %%DATA_DISPL + (64*1)] + VX512LDR %%T2, [%%IN + %%DATA_OFFSET + %%DATA_DISPL + (64*2)] + VX512LDR %%T3, [%%IN + %%DATA_OFFSET + %%DATA_DISPL + (64*3)] + + ;; move to AES encryption rounds +%assign i 0 + vbroadcastf64x2 %%T4, [%%KP + (16*i)] + vpxorq %%B00_03, %%B00_03, %%T4 + vpxorq %%B04_07, %%B04_07, %%T4 + vpxorq %%B08_11, %%B08_11, %%T4 + vpxorq %%B12_15, %%B12_15, %%T4 +%assign i (i + 1) + +%rep NROUNDS + vbroadcastf64x2 %%T4, [%%KP + (16*i)] + vaesenc %%B00_03, %%B00_03, %%T4 + vaesenc %%B04_07, %%B04_07, %%T4 + vaesenc %%B08_11, %%B08_11, %%T4 + vaesenc %%B12_15, %%B12_15, %%T4 +%assign i (i + 1) +%endrep + + vbroadcastf64x2 %%T4, [%%KP + (16*i)] + vaesenclast %%B00_03, %%B00_03, %%T4 + vaesenclast %%B04_07, %%B04_07, %%T4 + vaesenclast %%B08_11, %%B08_11, %%T4 + vaesenclast %%B12_15, %%B12_15, %%T4 + + ;; xor against text + vpxorq %%B00_03, %%B00_03, %%T0 + vpxorq %%B04_07, %%B04_07, %%T1 + vpxorq %%B08_11, %%B08_11, %%T2 + vpxorq %%B12_15, %%B12_15, %%T3 + + ;; store + VX512STR [%%OUT + %%DATA_OFFSET + %%DATA_DISPL + (64*0)], %%B00_03 + VX512STR [%%OUT + %%DATA_OFFSET + %%DATA_DISPL + (64*1)], %%B04_07 + VX512STR [%%OUT + %%DATA_OFFSET + %%DATA_DISPL + (64*2)], %%B08_11 + VX512STR [%%OUT + %%DATA_OFFSET + %%DATA_DISPL + (64*3)], %%B12_15 + +%ifidn %%ENC_DEC, DEC + ;; decryption - cipher text needs to go to GHASH phase + vpshufb %%B00_03, %%T0, %%SHUF_MASK + vpshufb %%B04_07, %%T1, %%SHUF_MASK + vpshufb %%B08_11, %%T2, %%SHUF_MASK + vpshufb %%B12_15, %%T3, %%SHUF_MASK +%else + ;; encryption + vpshufb %%B00_03, %%B00_03, %%SHUF_MASK + vpshufb %%B04_07, %%B04_07, %%SHUF_MASK + vpshufb %%B08_11, %%B08_11, %%SHUF_MASK + vpshufb %%B12_15, %%B12_15, %%SHUF_MASK +%endif + +%ifnidn %%GHASH, no_ghash + ;; === xor cipher block 0 with GHASH for the next GHASH round + vpxorq %%B00_03, %%B00_03, %%GHASH +%endif + + vmovdqa64 [rsp + stack_offset + (0 * 64)], %%B00_03 + vmovdqa64 [rsp + stack_offset + (1 * 64)], %%B04_07 + vmovdqa64 [rsp + stack_offset + (2 * 64)], %%B08_11 + vmovdqa64 [rsp + stack_offset + (3 * 64)], %%B12_15 +%endmacro ;INITIAL_BLOCKS_16 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; GCM_COMPLETE Finishes Encryption/Decryption of last partial block after GCM_UPDATE finishes. +; Input: A gcm_key_data * (GDATA_KEY), gcm_context_data (GDATA_CTX). +; Output: Authorization Tag (AUTH_TAG) and Authorization Tag length (AUTH_TAG_LEN) +; Clobbers xmm0-xmm2, xmm5-xmm6, xmm9-xmm11, xmm13-xmm15 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro GCM_COMPLETE 9 +%define %%GDATA_KEY %1 ; [in] GP with pointer to key structure +%define %%GDATA_CTX %2 ; [in] GP with pointer to context structure +%define %%AUTH_TAG %3 ; [in] pointer to store auth tag into (GP or mem) +%define %%AUTH_TAG_LEN %4 ; [in] length in bytes of auth tag (GP or mem) +%define %%INSTANCE_TYPE %5 ; [in] instance type "single_call" vs "multi_call" +%define %%MASKREG %6 ; [clobbered] temporary K register +%define %%IA0 %7 ; [clobbered] temporary GP +%define %%IA1 %8 ; [clobbered] temporary GP +%define %%IA2 %9 ; [clobbered] temporary GP + + ;; @note: xmm14 is hardcoded for hash input in singe_call case + + vmovdqu xmm13, [%%GDATA_KEY + HashKey] + ;; Start AES as early as possible + vmovdqu xmm9, [%%GDATA_CTX + OrigIV] ; xmm9 = Y0 + ENCRYPT_SINGLE_BLOCK %%GDATA_KEY, xmm9 ; E(K, Y0) + +%ifidn %%INSTANCE_TYPE, multi_call + ;; If the GCM function is called as a single function call rather + ;; than invoking the individual parts (init, update, finalize) we + ;; can remove a write to read dependency on AadHash. + vmovdqu xmm14, [%%GDATA_CTX + AadHash] + + ;; Encrypt of the final partial block was already done in the main GCM_ENC_DEC macro. + ;; It may be required to GHASH it now + cmp qword [%%GDATA_CTX + PBlockLen], 0 + je %%_partial_done + + ;; GHASH computation for the last <16 Byte block + GHASH_MUL xmm14, xmm13, xmm0, xmm10, xmm11, xmm5, xmm6 + +%%_partial_done: +%endif + vmovq xmm15, [%%GDATA_CTX + InLen] + vpinsrq xmm15, [%%GDATA_CTX + AadLen], 1 ; xmm15 = len(A)||len(C) + vpsllq xmm15, xmm15, 3 ; convert bytes into bits + + vpxor xmm14, xmm15 + GHASH_MUL xmm14, xmm13, xmm0, xmm10, xmm11, xmm5, xmm6 + vpshufb xmm14, [rel SHUF_MASK] ; perform a 16Byte swap + + vpxor xmm9, xmm9, xmm14 + + ;; xmm9 includes the final TAG + mov %%IA0, %%AUTH_TAG ; r10 = authTag + mov %%IA1, %%AUTH_TAG_LEN ; r11 = auth_tag_len + + cmp %%IA1, 16 + je %%_T_16 + + cmp %%IA1, 12 + je %%_T_12 + + cmp %%IA1, 8 + je %%_T_8 + + lea %%IA2, [rel byte64_len_to_mask_table] + kmovq %%MASKREG, [%%IA2 + %%IA1*8] + vmovdqu8 [%%IA0]{%%MASKREG}, xmm9 + jmp %%_return_T_done +%%_T_8: + vmovq [%%IA0], xmm9 + jmp %%_return_T_done +%%_T_12: + vmovq [%%IA0], xmm9 + vpextrd [%%IA0 + 8], xmm9, 2 + jmp %%_return_T_done +%%_T_16: + vmovdqu [%%IA0], xmm9 + +%%_return_T_done: + +;; IPPCP: disabled clearing of context fields, as in IPPCP case GetTag may be called +;; several times and it should not stop GCM processing. Context zeroing is done by user. +;; https://www.intel.com/content/www/us/en/docs/ipp-crypto/developer-reference/current/aes-gcm-functions.html +;; %ifdef SAFE_DATA +;; ;; Clear sensitive data from context structure +;; vpxor xmm0, xmm0 +;; vmovdqu [%%GDATA_CTX + AadHash], xmm0 +;; %ifidn %%INSTANCE_TYPE, multi_call +;; vmovdqu [%%GDATA_CTX + PBlockEncKey], xmm0 +;; %endif +;; %endif +%endmacro ; GCM_COMPLETE + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/ia_32e_regs.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/ia_32e_regs.inc new file mode 100644 index 000000000..ee3f4a434 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/ia_32e_regs.inc @@ -0,0 +1,125 @@ +;=============================================================================== +; Copyright (C) 2012 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: EM64T Cryptography Primitive. +; +; +; + +;; +;; Just for unify GPRs usage +;; + +%ifndef _IA_32_REGS_INC_ +%define _IA_32_REGS_INC_ + +%define r0 rax ;; 64-bits GPRs +%define r1 rbx +%define r2 rcx +%define r3 rdx +%define r4 rdi +%define r5 rsi +%define r6 rbp +%define r7 rsp + +%define r0d eax ;; 32-bits GPRs +%define r1d ebx +%define r2d ecx +%define r3d edx +%define r4d edi +%define r5d esi +%define r6d ebp +%define r7d esp + +%define raxd eax +%define rbxd ebx +%define rcxd ecx +%define rdxd edx +%define rdid edi +%define rsid esi +%define rbpd ebp + +%define r0w ax ;; 16-bits GPRs +%define r1w bx +%define r2w cx +%define r3w dx +%define r4w di +%define r5w si +%define r6w bp +%define r7w sp + +%define raxw ax +%define rbxw bx +%define rcxw cx +%define rdxw dx +%define rdiw di +%define rsiw si +%define rbpw bp + +%define r0b al ;; 8-bits GPRs +%define r1b bl +%define r2b cl +%define r3b dl +%define r4b dil +%define r5b sil +%define r6b bpl +%define r7b spl + +%define raxb al +%define rbxb bl +%define rcxb cl +%define rdxb dl +%define rdib dil +%define rsib sil +%define rbpb bpl + +%define raxbl al +%define rbxbl bl +%define rcxbl cl +%define rdxbl dl +%define raxbh ah +%define rbxbh bh +%define rcxbh ch +%define rdxbh dh + +;; +;; Register Parameters (depend on used OS) +;; +%ifdef WIN32E + %define rpar1 rcx + %define rpar2 rdx + %define rpar3 r8 + %define rpar4 r9 + %define rpar5 [rsp + ARG_5] + %define rpar6 [rsp + ARG_6] +%endif + +%ifdef LINUX32E + %define rpar1 rdi + %define rpar2 rsi + %define rpar3 rdx + %define rpar4 rcx + %define rpar5 r8 + %define rpar6 r9 +%endif + +;; use GPR implementation everywhere possible +%assign GPR_version 1 + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/memcpy.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/memcpy.inc new file mode 100644 index 000000000..482e4fac9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/memcpy.inc @@ -0,0 +1,603 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef __MEMCPY_ASM__ +%define __MEMCPY_ASM__ + +%include "reg_sizes.inc" + + +; This section defines a series of macros to copy small to medium amounts +; of data from memory to memory, where the size is variable but limited. +; +; The macros are all called as: +; memcpy DST, SRC, SIZE, TMP0, TMP1, XTMP0, XTMP1, XTMP2, XTMP3 +; with the parameters defined as: +; DST : register: pointer to dst (not modified) +; SRC : register: pointer to src (not modified) +; SIZE : register: length in bytes (not modified) +; TMP0 : 64-bit temp GPR (clobbered) +; TMP1 : 64-bit temp GPR (clobbered) +; XTMP0 : temp XMM (clobbered) +; XTMP1 : temp XMM (clobbered) +; XTMP2 : temp XMM (clobbered) +; XTMP3 : temp XMM (clobbered) +; +; The name indicates the options. The name is of the form: +; memcpy__ +; where: +; is either "sse" or "avx" or "avx2" +; is either "64" or "128" and defines largest value of SIZE +; is blank or "_1". If "_1" then the min SIZE is 1 (otherwise 0) +; is blank or "_ret". If blank, the code falls through. If "ret" +; it does a "ret" at the end +; +; For the avx2 versions, the temp XMM registers need to be YMM registers +; If the SZ is 64, then only two YMM temps are needed, i.e. it is called as: +; memcpy_avx2_64 DST, SRC, SIZE, TMP0, TMP1, YTMP0, YTMP1 +; memcpy_avx2_128 DST, SRC, SIZE, TMP0, TMP1, YTMP0, YTMP1, YTMP2, YTMP3 +; +; For example: +; memcpy_sse_64 : SSE, 0 <= size < 64, falls through +; memcpy_avx_64_1 : AVX1, 1 <= size < 64, falls through +; memcpy_sse_128_ret : SSE, 0 <= size < 128, ends with ret +; mempcy_avx_128_1_ret : AVX1, 1 <= size < 128, ends with ret +; + +%macro memcpy_sse_64 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 64, 0, 0 +%endm + +%macro memcpy_sse_64_1 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 64, 0, 0 +%endm + +%macro memcpy_sse_128 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 128, 0, 0 +%endm + +%macro memcpy_sse_128_1 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 128, 0, 0 +%endm + +%macro memcpy_sse_64_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 64, 1, 0 +%endm + +%macro memcpy_sse_64_1_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 64, 1, 0 +%endm + +%macro memcpy_sse_128_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 128, 1, 0 +%endm + +%macro memcpy_sse_128_1_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 128, 1, 0 +%endm + + +%macro memcpy_sse_16 5 + __memcpy_int %1,%2,%3,%4,%5,,,,, 0, 16, 0, 0 +%endm + +%macro memcpy_sse_16_1 5 + __memcpy_int %1,%2,%3,%4,%5,,,,, 1, 16, 0, 0 +%endm + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%macro memcpy_avx_64 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 64, 0, 1 +%endm + +%macro memcpy_avx_64_1 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 64, 0, 1 +%endm + +%macro memcpy_avx_128 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 128, 0, 1 +%endm + +%macro memcpy_avx_128_1 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 128, 0, 1 +%endm + +%macro memcpy_avx_64_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 64, 1, 1 +%endm + +%macro memcpy_avx_64_1_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 64, 1, 1 +%endm + +%macro memcpy_avx_128_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 128, 1, 1 +%endm + +%macro memcpy_avx_128_1_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 128, 1, 1 +%endm + + +%macro memcpy_avx_16 5 + __memcpy_int %1,%2,%3,%4,%5,,,,, 0, 16, 0, 1 +%endm + +%macro memcpy_avx_16_1 5 + __memcpy_int %1,%2,%3,%4,%5,,,,, 1, 16, 0, 1 +%endm + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%macro memcpy_avx2_64 7 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,--,--, 0, 64, 0, 2 +%endm + +%macro memcpy_avx2_64_1 7 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,--,--, 1, 64, 0, 2 +%endm + +%macro memcpy_avx2_128 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7, %8, %9, 0, 128, 0, 2 +%endm + +%macro memcpy_avx2_128_1 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7, %8, %9, 1, 128, 0, 2 +%endm + +%macro memcpy_avx2_64_ret 7 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,--,--, 0, 64, 1, 2 +%endm + +%macro memcpy_avx2_64_1_ret 7 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,--,--, 1, 64, 1, 2 +%endm + +%macro memcpy_avx2_128_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 0, 128, 1, 2 +%endm + +%macro memcpy_avx2_128_1_ret 9 + __memcpy_int %1,%2,%3,%4,%5,%6,%7,%8,%9, 1, 128, 1, 2 +%endm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +%macro __memcpy_int 13 +%define %%DST %1 ; register: pointer to dst (not modified) +%define %%SRC %2 ; register: pointer to src (not modified) +%define %%SIZE %3 ; register: length in bytes (not modified) +%define %%TMP0 %4 ; 64-bit temp GPR (clobbered) +%define %%TMP1 %5 ; 64-bit temp GPR (clobbered) +%define %%XTMP0 %6 ; temp XMM (clobbered) +%define %%XTMP1 %7 ; temp XMM (clobbered) +%define %%XTMP2 %8 ; temp XMM (clobbered) +%define %%XTMP3 %9 ; temp XMM (clobbered) +%define %%NOT0 %10 ; if not 0, then assume size cannot be zero +%define %%MAXSIZE %11 ; 128, 64, etc +%define %%USERET %12 ; if not 0, use "ret" at end +%define %%USEAVX %13 ; 0 = SSE, 1 = AVX1, 2 = AVX2 + +%if (%%USERET != 0) + %define %%DONE ret +%else + %define %%DONE jmp %%end +%endif + +%if (%%USEAVX != 0) + %define %%MOVDQU vmovdqu +%else + %define %%MOVDQU movdqu +%endif + +%if (%%MAXSIZE >= 128) + test %%SIZE, 64 + jz %%lt64 + %if (%%USEAVX >= 2) + %%MOVDQU %%XTMP0, [%%SRC + 0*32] + %%MOVDQU %%XTMP1, [%%SRC + 1*32] + %%MOVDQU %%XTMP2, [%%SRC + %%SIZE - 2*32] + %%MOVDQU %%XTMP3, [%%SRC + %%SIZE - 1*32] + + %%MOVDQU [%%DST + 0*32], %%XTMP0 + %%MOVDQU [%%DST + 1*32], %%XTMP1 + %%MOVDQU [%%DST + %%SIZE - 2*32], %%XTMP2 + %%MOVDQU [%%DST + %%SIZE - 1*32], %%XTMP3 + %else + %%MOVDQU %%XTMP0, [%%SRC + 0*16] + %%MOVDQU %%XTMP1, [%%SRC + 1*16] + %%MOVDQU %%XTMP2, [%%SRC + 2*16] + %%MOVDQU %%XTMP3, [%%SRC + 3*16] + %%MOVDQU [%%DST + 0*16], %%XTMP0 + %%MOVDQU [%%DST + 1*16], %%XTMP1 + %%MOVDQU [%%DST + 2*16], %%XTMP2 + %%MOVDQU [%%DST + 3*16], %%XTMP3 + + %%MOVDQU %%XTMP0, [%%SRC + %%SIZE - 4*16] + %%MOVDQU %%XTMP1, [%%SRC + %%SIZE - 3*16] + %%MOVDQU %%XTMP2, [%%SRC + %%SIZE - 2*16] + %%MOVDQU %%XTMP3, [%%SRC + %%SIZE - 1*16] + %%MOVDQU [%%DST + %%SIZE - 4*16], %%XTMP0 + %%MOVDQU [%%DST + %%SIZE - 3*16], %%XTMP1 + %%MOVDQU [%%DST + %%SIZE - 2*16], %%XTMP2 + %%MOVDQU [%%DST + %%SIZE - 1*16], %%XTMP3 + %endif + %%DONE +%endif + +%if (%%MAXSIZE >= 64) +%%lt64: + test %%SIZE, 32 + jz %%lt32 + %if (%%USEAVX >= 2) + %%MOVDQU %%XTMP0, [%%SRC + 0*32] + %%MOVDQU %%XTMP1, [%%SRC + %%SIZE - 1*32] + %%MOVDQU [%%DST + 0*32], %%XTMP0 + %%MOVDQU [%%DST + %%SIZE - 1*32], %%XTMP1 + %else + %%MOVDQU %%XTMP0, [%%SRC + 0*16] + %%MOVDQU %%XTMP1, [%%SRC + 1*16] + %%MOVDQU %%XTMP2, [%%SRC + %%SIZE - 2*16] + %%MOVDQU %%XTMP3, [%%SRC + %%SIZE - 1*16] + %%MOVDQU [%%DST + 0*16], %%XTMP0 + %%MOVDQU [%%DST + 1*16], %%XTMP1 + %%MOVDQU [%%DST + %%SIZE - 2*16], %%XTMP2 + %%MOVDQU [%%DST + %%SIZE - 1*16], %%XTMP3 + %endif + %%DONE +%endif + +%if (%%MAXSIZE >= 32) +%%lt32: + test %%SIZE, 16 + jz %%lt16 + %if (%%USEAVX >= 2) + %%MOVDQU XWORD(%%XTMP0), [%%SRC + 0*16] + %%MOVDQU XWORD(%%XTMP1), [%%SRC + %%SIZE - 1*16] + %%MOVDQU [%%DST + 0*16], XWORD(%%XTMP0) + %%MOVDQU [%%DST + %%SIZE - 1*16], XWORD(%%XTMP1) + %else + %%MOVDQU %%XTMP0, [%%SRC + 0*16] + %%MOVDQU %%XTMP1, [%%SRC + %%SIZE - 1*16] + %%MOVDQU [%%DST + 0*16], %%XTMP0 + %%MOVDQU [%%DST + %%SIZE - 1*16], %%XTMP1 + %endif + %%DONE +%endif + +%if (%%MAXSIZE >= 16) +%%lt16: + test %%SIZE, 8 + jz %%lt8 + mov %%TMP0, [%%SRC] + mov %%TMP1, [%%SRC + %%SIZE - 8] + mov [%%DST], %%TMP0 + mov [%%DST + %%SIZE - 8], %%TMP1 + %%DONE +%endif + +%if (%%MAXSIZE >= 8) +%%lt8: + test %%SIZE, 4 + jz %%lt4 + mov DWORD(%%TMP0), [%%SRC] + mov DWORD(%%TMP1), [%%SRC + %%SIZE - 4] + mov [%%DST], DWORD(%%TMP0) + mov [%%DST + %%SIZE - 4], DWORD(%%TMP1) + %%DONE +%endif + +%if (%%MAXSIZE >= 4) +%%lt4: + test %%SIZE, 2 + jz %%lt2 + movzx DWORD(%%TMP0), word [%%SRC] + movzx DWORD(%%TMP1), byte [%%SRC + %%SIZE - 1] + mov [%%DST], WORD(%%TMP0) + mov [%%DST + %%SIZE - 1], BYTE(%%TMP1) + %%DONE +%endif + +%%lt2: +%if (%%NOT0 == 0) + test %%SIZE, 1 + jz %%end +%endif + movzx DWORD(%%TMP0), byte [%%SRC] + mov [%%DST], BYTE(%%TMP0) +%%end: +%if (%%USERET != 0) + ret +%endif +%endm + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Utility macro to assist with SIMD shifting +%macro _PSRLDQ 3 +%define %%VEC %1 +%define %%REG %2 +%define %%IMM %3 + +%ifidn %%VEC, SSE + psrldq %%REG, %%IMM +%else + vpsrldq %%REG, %%REG, %%IMM +%endif +%endm + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; This section defines a series of macros to store small to medium amounts +; of data from SIMD registers to memory, where the size is variable but limited. +; +; The macros are all called as: +; memcpy DST, SRC, SIZE, TMP, IDX +; with the parameters defined as: +; DST : register: pointer to dst (not modified) +; SRC : register: src data (clobbered) +; SIZE : register: length in bytes (not modified) +; TMP : 64-bit temp GPR (clobbered) +; IDX : 64-bit GPR to store dst index/offset (clobbered) +; +; The name indicates the options. The name is of the form: +; simd_store_ +; where is the SIMD instruction type e.g. "sse" or "avx" + + +%macro simd_store_sse 5 + __simd_store %1,%2,%3,%4,%5,SSE +%endm + +%macro simd_store_avx 5 + __simd_store %1,%2,%3,%4,%5,AVX +%endm + +%macro simd_store_sse_15 5 + __simd_store %1,%2,%3,%4,%5,SSE,15 +%endm + +%macro simd_store_avx_15 5 + __simd_store %1,%2,%3,%4,%5,AVX,15 +%endm + +%macro __simd_store 6-7 +%define %%DST %1 ; register: pointer to dst (not modified) +%define %%SRC %2 ; register: src data (clobbered) +%define %%SIZE %3 ; register: length in bytes (not modified) +%define %%TMP %4 ; 64-bit temp GPR (clobbered) +%define %%IDX %5 ; 64-bit temp GPR to store dst idx (clobbered) +%define %%SIMDTYPE %6 ; "SSE" or "AVX" +%define %%MAX_LEN %7 ; [optional] maximum length to be stored, default 16 + +%define %%PSRLDQ _PSRLDQ %%SIMDTYPE, + +%ifidn %%SIMDTYPE, SSE + %define %%MOVDQU movdqu + %define %%MOVQ movq +%else + %define %%MOVDQU vmovdqu + %define %%MOVQ vmovq +%endif + +;; determine max byte size for store operation +%if %0 > 6 +%assign max_length_to_store %%MAX_LEN +%else +%assign max_length_to_store 16 +%endif + +%if max_length_to_store > 16 +%error "__simd_store macro invoked with MAX_LEN bigger than 16!" +%endif + + xor %%IDX, %%IDX ; zero idx + +%if max_length_to_store == 16 + test %%SIZE, 16 + jz %%lt16 + %%MOVDQU [%%DST], %%SRC + jmp %%end +%%lt16: +%endif + +%if max_length_to_store >= 8 + test %%SIZE, 8 + jz %%lt8 + %%MOVQ [%%DST + %%IDX], %%SRC + %%PSRLDQ %%SRC, 8 + add %%IDX, 8 +%%lt8: +%endif + + %%MOVQ %%TMP, %%SRC ; use GPR from now on + +%if max_length_to_store >= 4 + test %%SIZE, 4 + jz %%lt4 + mov [%%DST + %%IDX], DWORD(%%TMP) + shr %%TMP, 32 + add %%IDX, 4 +%%lt4: +%endif + + test %%SIZE, 2 + jz %%lt2 + mov [%%DST + %%IDX], WORD(%%TMP) + shr %%TMP, 16 + add %%IDX, 2 +%%lt2: + test %%SIZE, 1 + jz %%end + mov [%%DST + %%IDX], BYTE(%%TMP) +%%end: +%endm + +; This section defines a series of macros to load small to medium amounts +; (from 0 to 16 bytes) of data from memory to SIMD registers, +; where the size is variable but limited. +; +; The macros are all called as: +; simd_load DST, SRC, SIZE +; with the parameters defined as: +; DST : register: destination XMM register +; SRC : register: pointer to src data (not modified) +; SIZE : register: length in bytes (not modified) +; +; The name indicates the options. The name is of the form: +; simd_load__ +; where: +; is either "sse" or "avx" +; is either "15" or "16" and defines largest value of SIZE +; is blank or "_1". If "_1" then the min SIZE is 1 (otherwise 0) +; +; For example: +; simd_load_sse_16 : SSE, 0 <= size <= 16 +; simd_load_avx_15_1 : AVX, 1 <= size <= 15 + +%macro simd_load_sse_15_1 3 + __simd_load %1,%2,%3,0,0,SSE +%endm +%macro simd_load_sse_15 3 + __simd_load %1,%2,%3,1,0,SSE +%endm +%macro simd_load_sse_16_1 3 + __simd_load %1,%2,%3,0,1,SSE +%endm +%macro simd_load_sse_16 3 + __simd_load %1,%2,%3,1,1,SSE +%endm + +%macro simd_load_avx_15_1 3 + __simd_load %1,%2,%3,0,0,AVX +%endm +%macro simd_load_avx_15 3 + __simd_load %1,%2,%3,1,0,AVX +%endm +%macro simd_load_avx_16_1 3 + __simd_load %1,%2,%3,0,1,AVX +%endm +%macro simd_load_avx_16 3 + __simd_load %1,%2,%3,1,1,AVX +%endm + +%macro __simd_load 6 +%define %%DST %1 ; [out] destination XMM register +%define %%SRC %2 ; [in] pointer to src data +%define %%SIZE %3 ; [in] length in bytes (0-16 bytes) +%define %%ACCEPT_0 %4 ; 0 = min length = 1, 1 = min length = 0 +%define %%ACCEPT_16 %5 ; 0 = max length = 15 , 1 = max length = 16 +%define %%SIMDTYPE %6 ; "SSE" or "AVX" + +%ifidn %%SIMDTYPE, SSE + %define %%MOVDQU movdqu + %define %%PINSRB pinsrb + %define %%PINSRQ pinsrq + %define %%PXOR pxor +%else + %define %%MOVDQU vmovdqu + %define %%PINSRB vpinsrb + %define %%PINSRQ vpinsrq + %define %%PXOR vpxor +%endif + +%if (%%ACCEPT_16 != 0) + test %%SIZE, 16 + jz %%_skip_16 + %%MOVDQU %%DST, [%%SRC] + jmp %%end_load + +%%_skip_16: +%endif + %%PXOR %%DST, %%DST ; clear XMM register +%if (%%ACCEPT_0 != 0) + or %%SIZE, %%SIZE + je %%end_load +%endif + cmp %%SIZE, 1 + je %%_size_1 + cmp %%SIZE, 2 + je %%_size_2 + cmp %%SIZE, 3 + je %%_size_3 + cmp %%SIZE, 4 + je %%_size_4 + cmp %%SIZE, 5 + je %%_size_5 + cmp %%SIZE, 6 + je %%_size_6 + cmp %%SIZE, 7 + je %%_size_7 + cmp %%SIZE, 8 + je %%_size_8 + cmp %%SIZE, 9 + je %%_size_9 + cmp %%SIZE, 10 + je %%_size_10 + cmp %%SIZE, 11 + je %%_size_11 + cmp %%SIZE, 12 + je %%_size_12 + cmp %%SIZE, 13 + je %%_size_13 + cmp %%SIZE, 14 + je %%_size_14 + +%%_size_15: + %%PINSRB %%DST, [%%SRC + 14], 14 +%%_size_14: + %%PINSRB %%DST, [%%SRC + 13], 13 +%%_size_13: + %%PINSRB %%DST, [%%SRC + 12], 12 +%%_size_12: + %%PINSRB %%DST, [%%SRC + 11], 11 +%%_size_11: + %%PINSRB %%DST, [%%SRC + 10], 10 +%%_size_10: + %%PINSRB %%DST, [%%SRC + 9], 9 +%%_size_9: + %%PINSRB %%DST, [%%SRC + 8], 8 +%%_size_8: + %%PINSRQ %%DST, [%%SRC], 0 + jmp %%end_load +%%_size_7: + %%PINSRB %%DST, [%%SRC + 6], 6 +%%_size_6: + %%PINSRB %%DST, [%%SRC + 5], 5 +%%_size_5: + %%PINSRB %%DST, [%%SRC + 4], 4 +%%_size_4: + %%PINSRB %%DST, [%%SRC + 3], 3 +%%_size_3: + %%PINSRB %%DST, [%%SRC + 2], 2 +%%_size_2: + %%PINSRB %%DST, [%%SRC + 1], 1 +%%_size_1: + %%PINSRB %%DST, [%%SRC + 0], 0 +%%end_load: +%endm +%endif ; ifndef __MEMCPY_ASM__ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/os.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/os.inc new file mode 100644 index 000000000..38c65866e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/os.inc @@ -0,0 +1,40 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +%ifndef OS_ASM_FILE +%define OS_ASM_FILE + +%ifndef WIN_ABI +%ifidn __OUTPUT_FORMAT__, win64 +%define WIN_ABI +%endif +%endif + +%ifndef LINUX +%ifidn __OUTPUT_FORMAT__, elf64 +%define LINUX +%endif +%endif + +;; code is the same for linux and macos +%ifndef LINUX +%ifidn __OUTPUT_FORMAT__, macho64 +%define LINUX +%endif +%endif + +%endif ; OS_ASM_FILE diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpaesgcme9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpaesgcme9as.asm new file mode 100644 index 000000000..5cf631dec --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpaesgcme9as.asm @@ -0,0 +1,931 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; AES-GCM function +; +; Content: +; AesGcmPrecompute_avx() +; AesGcmMulGcm_avx() +; AesGcmAuth_avx() +; AesGcmEnc_avx() +; AesGcmDec_avx() +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%assign my_emulator 0; set 1 for emulation +%include "emulator.inc" + + +; sse_clmul_gcm MACRO to implement: Data*HashKey mod (128,127,126,121,0) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%assign REFLECTED_IN_OUT 1 ; GCM input and output are represented in reflected form naturaly +;USE_BYTE_REFLECTED = 0 ; set to 1 %if input data is byte-reflected + + +%macro sse_clmul_gcm_2way 11.nolist + %xdefine %%HK %1 + %xdefine %%HKforKaratsuba %2 + %xdefine %%GH_1 %3 + %xdefine %%tmpX0_1 %4 + %xdefine %%tmpX1_1 %5 + %xdefine %%tmpX2_1 %6 + %xdefine %%GH_2 %7 + %xdefine %%tmpX0_2 %8 + %xdefine %%tmpX1_2 %9 + %xdefine %%tmpX2_2 %10 + %xdefine %%tmpX3_2 %11 + +pshufd %%tmpX2_1, %%GH_1, 01001110b + + ;; Karatsuba Method + movdqa %%tmpX1_1, %%GH_1 + pxor %%tmpX2_1, %%GH_1 +my_pclmulqdq %%GH_1, %%HK, 00h + + pshufd %%tmpX2_2, %%GH_2, 01001110b + + ;; Karatsuba Method + movdqa %%tmpX1_2, %%GH_2 + pxor %%tmpX2_2, %%GH_2 +my_pclmulqdq %%tmpX1_1, %%HK, 11h +my_pclmulqdq %%tmpX2_1, %%HKforKaratsuba, 00h + pxor %%tmpX2_1, %%GH_1 + pxor %%tmpX2_1, %%tmpX1_1 + + pshufd %%tmpX0_1, %%tmpX2_1, 78 + movdqa %%tmpX2_1, %%tmpX0_1 + pand %%tmpX0_1, oword [rel MASK2] + pand %%tmpX2_1, xmm14 + pxor %%GH_1, %%tmpX0_1 + pxor %%tmpX1_1, %%tmpX2_1 + + ;first phase of the reduction + movdqa %%tmpX0_1, %%GH_1 + + psllq %%GH_1, 1 + +my_pclmulqdq %%GH_2, %%HK, 00h + pxor %%GH_1, %%tmpX0_1 + psllq %%GH_1, 5 + pxor %%GH_1, %%tmpX0_1 + psllq %%GH_1, 57 + + pshufd %%tmpX2_1, %%GH_1, 78 + movdqa %%GH_1, %%tmpX2_1 + +my_pclmulqdq %%tmpX1_2, %%HK, 11h + pand %%tmpX2_1, xmm14 + pand %%GH_1, oword [rel MASK2] + pxor %%GH_1, %%tmpX0_1 + pxor %%tmpX1_1, %%tmpX2_1 + + ;second phase of the reduction + movdqa %%tmpX2_1, %%GH_1 + psrlq %%GH_1, 5 + +my_pclmulqdq %%tmpX2_2, %%HKforKaratsuba, 00h + pxor %%GH_1, %%tmpX2_1 + psrlq %%GH_1, 1 + pxor %%GH_1, %%tmpX2_1 + psrlq %%GH_1, 1 + + pxor %%GH_1, %%tmpX2_1 + pxor %%GH_1, %%tmpX1_1 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + pxor %%tmpX2_2, %%GH_2 + pxor %%tmpX2_2, %%tmpX1_2 + + pshufd %%tmpX0_2, %%tmpX2_2, 78 + movdqa %%tmpX2_2, %%tmpX0_2 + pand %%tmpX0_2, oword [rel MASK2] + pand %%tmpX2_2, xmm14 + pxor %%GH_2, %%tmpX0_2 + pxor %%tmpX1_2, %%tmpX2_2 + + ;first phase of the reduction + movdqa %%tmpX0_2, %%GH_2 + movdqa %%tmpX2_2, %%GH_2 + movdqa %%tmpX3_2, %%GH_2 ; move GH_2 into tmpX0_2, tmpX2_2, tmpX3_2 + + psllq %%tmpX0_2, 63 ; packed left shifting << 63 + psllq %%tmpX2_2, 62 ; packed left shifting shift << 62 + psllq %%tmpX3_2, 57 ; packed left shifting shift << 57 + pxor %%tmpX0_2, %%tmpX2_2 ; xor the shifted versions + pxor %%tmpX0_2, %%tmpX3_2 + + movdqa %%tmpX2_2, %%tmpX0_2 + pslldq %%tmpX2_2, 8 ; shift-L tmpX2_2 2 DWs + psrldq %%tmpX0_2, 8 ; shift-R xmm2 2 DWs + + pxor %%GH_2, %%tmpX2_2 ; first phase of the reduction complete + pxor %%tmpX1_2, %%tmpX0_2 ; save the lost MS 1-2-7 bits from first phase + + ;second phase of the reduction + movdqa %%tmpX2_2, %%GH_2 ; move GH_2 into tmpX3_2 + psrlq %%tmpX2_2, 5 ; packed right shifting >> 5 + pxor %%tmpX2_2, %%GH_2 ; xor shifted versions + psrlq %%tmpX2_2, 1 ; packed right shifting >> 1 + pxor %%tmpX2_2, %%GH_2 ; xor shifted versions + psrlq %%tmpX2_2, 1 ; packed right shifting >> 1 + + pxor %%GH_2, %%tmpX2_2 ; second phase of the reduction complete + pxor %%GH_2, %%tmpX1_2 ; the result is in GH_2 +%endmacro + +%macro sse_clmul_gcm 5.nolist + %xdefine %%GH %1 + %xdefine %%HK %2 + %xdefine %%tmpX0 %3 + %xdefine %%tmpX1 %4 + %xdefine %%tmpX2 %5 + +;; GH, HK hold the values for the two operands which are carry-less multiplied + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Karatsuba Method + ;; + ;; GH = [GH1:GH0] + ;; HK = [HK1:HK0] + ;; + pshufd %%tmpX2, %%GH, 01001110b ;; xmm2 = {GH0:GH1} + pshufd %%tmpX0, %%HK, 01001110b ;; xmm0 = {HK0:HK1} + pxor %%tmpX2, %%GH ;; xmm2 = {GH0+GH1:GH1+GH0} + pxor %%tmpX0, %%HK ;; xmm0 = {HK0+HK1:HK1+HK0} + +my_pclmulqdq %%tmpX2, %%tmpX0,00h ;; tmpX2 = (a1+a0)*(b1+b0) xmm2 = (GH1+GH0)*(HK1+HK0) + movdqa %%tmpX1, %%GH +my_pclmulqdq %%GH, %%HK, 00h ;; GH = a0*b0 GH = GH0*HK0 + pxor %%tmpX0, %%tmpX0 +my_pclmulqdq %%tmpX1, %%HK, 11h ;; tmpX1 = a1*b1 xmm1 = GH1*HK1 + pxor %%tmpX2, %%GH ;; xmm2 = (GH1+GH0)*(HK1+HK0) + GH0*HK0 + pxor %%tmpX2, %%tmpX1 ;; tmpX2 = a0*b1+a1*b0 xmm2 = (GH1+GH0)*(HK1+HK0) + GH0*HK0 + GH1*HK1 = GH0*HK1+GH1*HK0 + + palignr %%tmpX0, %%tmpX2, 8 ;; tmpX0 = {Zeros : HI(a0*b1+a1*b0)} + pslldq %%tmpX2, 8 ;; tmpX2 = {LO(HI(a0*b1+a1*b0)) : Zeros} + pxor %%tmpX1, %%tmpX0 ;; holds the result of the carry-less multiplication of GH by HK + pxor %%GH, %%tmpX2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;first phase of the reduction: + ; Most( (product_H * g1), 128)) product_H = GH + ; g1 = 2^256/g = g = 1+x+x^2+x^7+x^128 + ; + movdqa %%tmpX0, %%GH ;; copy GH into tmpX0, tmpX2, xmm15 + movdqa %%tmpX2, %%GH + movdqa xmm15, %%GH + + psllq %%tmpX0, 63 ; packed left shifting << 63 + psllq %%tmpX2, 62 ; packed left shifting shift << 62 + psllq xmm15, 57 ; packed left shifting shift << 57 + pxor %%tmpX0, %%tmpX2 ; xor the shifted versions + pxor %%tmpX0, xmm15 + + movdqa %%tmpX2, %%tmpX0 + pslldq %%tmpX2, 8 ; shift-L tmpX2 2 DWs + psrldq %%tmpX0, 8 ; shift-R xmm2 2 DWs + + pxor %%GH, %%tmpX2 ; first phase of the reduction complete + pxor %%tmpX1, %%tmpX0 ; save the lost MS 1-2-7 bits from first phase + + ;second phase of the reduction + movdqa %%tmpX2, %%GH ; move GH into xmm15 + psrlq %%tmpX2, 5 ; packed right shifting >> 5 + pxor %%tmpX2, %%GH ; xor shifted versions + psrlq %%tmpX2, 1 ; packed right shifting >> 1 + pxor %%tmpX2, %%GH ; xor shifted versions + psrlq %%tmpX2, 1 ; packed right shifting >> 1 + + pxor %%GH, %%tmpX2 ; second phase of the reduction complete + pxor %%GH, %%tmpX1 ; the result is in GH +%endmacro + +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +POLY DQ 00000000000000001h,0C200000000000000h ;; 0xC2000000000000000000000000000001 +TWOONE DQ 00000000000000001h,00000000100000000h ;; 0x00000001000000000000000000000001 +SHUF_CONST DQ 008090a0b0c0d0e0fh,00001020304050607h ;; 0x000102030405060708090a0b0c0d0e0f +MASK1 DQ 0ffffffffffffffffh,00000000000000000h ;; 0x0000000000000000ffffffffffffffff +MASK2 DQ 00000000000000000h,0ffffffffffffffffh ;; 0xffffffffffffffff0000000000000000 +INC_1 DQ 1,0 + +%assign sizeof_oword_ (16) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; void AesGcmPrecomute_avx(Ipp8u* pPrecomutedData, const Ipp8u* pHKey) +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmPrecompute_avx,PUBLIC + USES_GPR rdi,rsi + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 + COMP_ABI 2 + +%xdefine pPrecomData rdi ; (rdi) pointer to the reflected multipliers reflect(hkey),(hkey<<1), (hkey^2)<<1, (hkey^4)<<1, +%xdefine pHKey rsi ; (rsi) pointer to the Hkey value + + movdqu xmm0, oword [rel pHKey] ; xmm0 holds HashKey + pshufb xmm0, [rel SHUF_CONST] + ;movdqu oword [pPrecomData+sizeof_oword_*0], xmm0 + + ; precompute HashKey<<1 mod poly from the HashKey + movdqa xmm4, xmm0 + psllq xmm0, 1 + psrlq xmm4, 63 + movdqa xmm3, xmm4 + pslldq xmm4, 8 + psrldq xmm3, 8 + por xmm0, xmm4 + ;reduction + pshufd xmm4, xmm3, 00100100b + pcmpeqd xmm4, oword [rel TWOONE] ; [TWOONE] = 0x00000001000000000000000000000001 + pand xmm4, oword [rel POLY] + pxor xmm0, xmm4 ; xmm0 holds the HashKey<<1 mod poly + + movdqa xmm1, xmm0 + sse_clmul_gcm xmm1, xmm0, xmm3, xmm4, xmm5 ; xmm1 holds (HashKey^2)<<1 mod poly + + movdqa xmm2, xmm1 + sse_clmul_gcm xmm2, xmm1, xmm3, xmm4, xmm5 ; xmm2 holds (HashKey^4)<<1 mod poly + + movdqu oword [pPrecomData+sizeof_oword_*0], xmm0 + movdqu oword [pPrecomData+sizeof_oword_*1], xmm1 + movdqu oword [pPrecomData+sizeof_oword_*2], xmm2 + + REST_XMM + REST_GPR + ret +ENDFUNC AesGcmPrecompute_avx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; void AesGcmMulGcm_avx(Ipp8u* pHash, const Ipp8u* pHKey) +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmMulGcm_avx,PUBLIC + USES_GPR rsi,rdi + USES_XMM xmm15 + COMP_ABI 2 + +%xdefine pHash rdi ; (rdi) pointer to the Hash value +%xdefine pHKey rsi ; (rsi) pointer to the (hkey<<1) value + + movdqa xmm0, oword [rel pHash] + pshufb xmm0, [rel SHUF_CONST] + movdqa xmm1, oword [rel pHKey] + + sse_clmul_gcm xmm0, xmm1, xmm2, xmm3, xmm4 ; xmm0 holds Hash*HKey mod poly + + pshufb xmm0, [rel SHUF_CONST] + movdqa oword [rel pHash], xmm0 + + REST_XMM + REST_GPR + ret +ENDFUNC AesGcmMulGcm_avx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; void AesGcmAuth_avx(Ipp8u* pHash, const Ipp8u* pSrc, int len, const Ipp8u* pHKey, const void* pParam +;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM AesGcmAuth_avx,PUBLIC + USES_GPR rsi,rdi + USES_XMM xmm15 + COMP_ABI 5 + +%xdefine pHash rdi ; (rdi) pointer to the Hash value +%xdefine pSrc rsi ; (rsi) pointer to the input data +%xdefine len rdx ; (rdx) length of data (multiplr by AES_DATA_BLOCK) +%xdefine pHKey rcx ; (rcx) pointer to the (hkey<<1) value + +%assign BYTES_PER_BLK (16) + + movdqa xmm0, oword [rel pHash] + pshufb xmm0, [rel SHUF_CONST] + movdqa xmm1, oword [rel pHKey] + + movsxd rdx, edx + +align IPP_ALIGN_FACTOR +.auth_loop: + movdqu xmm2, oword [rel pSrc] ; src[] + pshufb xmm2, [rel SHUF_CONST] + add pSrc, BYTES_PER_BLK + pxor xmm0, xmm2 ; hash ^= src[] + + sse_clmul_gcm xmm0, xmm1, xmm2, xmm3, xmm4 ; xmm0 holds Hash*HKey mod poly + + sub len, BYTES_PER_BLK + jnz .auth_loop + + pshufb xmm0, [rel SHUF_CONST] + movdqa oword [pHash], xmm0 + + REST_XMM + REST_GPR + ret +ENDFUNC AesGcmAuth_avx + +;*************************************************************** +;* Purpose: pipelined AES-GCM encryption +;* +;* void AesGcmEnc_avx(Ipp8u* pDst, +;* const Ipp8u* pSrc, +;* int length, +;* RijnCipher cipher, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp8u* pGhash, +;* Ipp8u* pCtrValue, +;* Ipp8u* pEncCtrValue, +;* const Ipp8u* pPrecomData) +;*************************************************************** +align IPP_ALIGN_FACTOR +;; +;; Lib = Y8, E9 +;; +;; Caller = ippsRijndael128GCMEncrypt +;; +IPPASM AesGcmEnc_avx,PUBLIC +%assign LOCAL_FRAME (8*16) + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 + COMP_ABI 10 + +%xdefine pDst rdi ; pointer to the encrypted data +%xdefine pSrc rsi ; pointer to the plane data +%xdefine len rdx ; data length in bytes (multiple by BYTES_PER_BLK) +%xdefine cipher rcx ; ciper function (don't need in fact) +%xdefine nr r8d ; number of cipher's rounds +%xdefine pRKey r9 ; pointer to the cipher's round keys +%xdefine pGhash [rsp+ARG_7] ; pointer to the Hash value +%xdefine pCtrValue [rsp+ARG_8] ; pointer to the counter value +%xdefine pEncCtrValue [rsp+ARG_9] ; pointer to the encrypted counter +%xdefine pPrecomData [rsp+ARG_10]; pointer to the precomputed data + +%assign SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + +;; +;; stack structure: +%assign CNT (0) +%assign ECNT (CNT+sizeof_oword_) +%assign GHASH (ECNT+sizeof_oword_) + +%assign GHASH0 (GHASH) +%assign GHASH1 (GHASH0+sizeof_oword_) +%assign GHASH2 (GHASH1+sizeof_oword_) +%assign GHASH3 (GHASH2+sizeof_oword_) +%assign HKeyKaratsuba (GHASH3+sizeof_oword_) + + mov rax, pCtrValue ; address of the counter + mov rbx, pEncCtrValue ; address of the encrypted counter + mov rcx, pGhash ; address of hash value + movdqa xmm4,oword [rel SHUF_CONST] + + movdqu xmm0, oword [rax] ; counter value + movdqu xmm1, oword [rbx] ; encrypted counter value + movdqu xmm2, oword [rcx] ; hash value + + pshufb xmm0, xmm4 ; convert counter and + movdqa oword [rsp+CNT], xmm0 ; store into the stack + movdqa oword [rsp+ECNT], xmm1 ; store encrypted counter into the stack + + pshufb xmm2, xmm4 ; convert hash value + pxor xmm1, xmm1 + movdqa oword [rsp+GHASH0], xmm2 ; store hash into the stack + movdqa oword [rsp+GHASH1], xmm1 ; + movdqa oword [rsp+GHASH2], xmm1 ; + movdqa oword [rsp+GHASH3], xmm1 ; + + mov rbx, [rsp+ARG_10] ; pointer to the {hk<<1,hk^2<<1,kh^4<<1} multipliers + movdqa xmm10,oword [rbx+sizeof_oword_*2] + pshufd xmm9, xmm10, 01001110b ; xmm9 holds qword-swapped version of (HashKey^4)<<1 mod poly for Karatsuba + pxor xmm9, xmm10 + movdqa oword [rsp+HKeyKaratsuba], xmm9 + + movsxd len, edx ; data length + mov rcx, pRKey ; rcx point to the chipher's round keys + + mov rax, len + and rax, BYTES_PER_LOOP-1 + and len, -BYTES_PER_LOOP + jz .single_block_proc + +;; +;; pipelined processing (4 blocks) +;; +align IPP_ALIGN_FACTOR +.blks4_loop: + ;; + ;; ctr encryption + ;; + movdqa xmm6,oword [rel INC_1] + movdqa xmm5,oword [rel SHUF_CONST] + + movdqa xmm1, xmm0 ; counter+1 + paddd xmm1, xmm6 + movdqa xmm2, xmm1 ; counter+2 + paddd xmm2, xmm6 + movdqa xmm3, xmm2 ; counter+3 + paddd xmm3, xmm6 + movdqa xmm4, xmm3 ; counter+4 + paddd xmm4, xmm6 + movdqa oword [rsp+CNT], xmm4 + + movdqa xmm0, oword [rcx] ; pre-load whitening keys + mov r10, rcx + + pshufb xmm1, xmm5 ; counter, counter+1, counter+2, counter+3 + pshufb xmm2, xmm5 ; ready to be encrypted + pshufb xmm3, xmm5 + pshufb xmm4, xmm5 + + pxor xmm1, xmm0 ; whitening + pxor xmm2, xmm0 + pxor xmm3, xmm0 + pxor xmm4, xmm0 + + movdqa xmm0, oword [r10+16] + add r10, 16 + + mov r11d, nr ; counter depending on key length + sub r11, 1 + +align IPP_ALIGN_FACTOR +.cipher4_loop: +my_aesenc xmm1, xmm0 ; regular round +my_aesenc xmm2, xmm0 +my_aesenc xmm3, xmm0 +my_aesenc xmm4, xmm0 + movdqa xmm0, oword [r10+16] + add r10, 16 + dec r11 + jnz .cipher4_loop +my_aesenclast xmm1, xmm0 +my_aesenclast xmm2, xmm0 +my_aesenclast xmm3, xmm0 +my_aesenclast xmm4, xmm0 + + movdqa xmm0, oword [rsp+ECNT] ; load pre-calculated encrypted counter + movdqa oword [rsp+ECNT], xmm4 ; save encrypted counter+4 + + movdqu xmm4, oword [pSrc+0*BYTES_PER_BLK] ; 4 input blocks + movdqu xmm5, oword [pSrc+1*BYTES_PER_BLK] + movdqu xmm6, oword [pSrc+2*BYTES_PER_BLK] + movdqu xmm7, oword [pSrc+3*BYTES_PER_BLK] + add pSrc, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; ctr encryption + movdqu oword [pDst+0*BYTES_PER_BLK], xmm0 ; store result + pshufb xmm0, [rel SHUF_CONST] ; convert for multiplication and + pxor xmm0, oword [rsp+GHASH0] + + pxor xmm1, xmm5 + movdqu oword [pDst+1*BYTES_PER_BLK], xmm1 + pshufb xmm1, [rel SHUF_CONST] + pxor xmm1, oword [rsp+GHASH1] + + pxor xmm2, xmm6 + movdqu oword [pDst+2*BYTES_PER_BLK], xmm2 + pshufb xmm2, [rel SHUF_CONST] + pxor xmm2, oword [rsp+GHASH2] + + pxor xmm3, xmm7 + movdqu oword [pDst+3*BYTES_PER_BLK], xmm3 + pshufb xmm3, [rel SHUF_CONST] + pxor xmm3, oword [rsp+GHASH3] + + add pDst, BYTES_PER_LOOP + + cmp len, BYTES_PER_LOOP + je .combine_hash + + ;; + ;; update hash value + ;; + movdqa xmm14, oword [rel MASK1] + sse_clmul_gcm_2way xmm10, xmm9, xmm0, xmm4, xmm5, xmm6, xmm1, xmm11, xmm12, xmm13, xmm15 + sse_clmul_gcm_2way xmm10, xmm9, xmm2, xmm4, xmm5, xmm6, xmm3, xmm11, xmm12, xmm13, xmm15 + + movdqa oword [rsp+GHASH0], xmm0 + movdqa oword [rsp+GHASH1], xmm1 + movdqa oword [rsp+GHASH2], xmm2 + movdqa oword [rsp+GHASH3], xmm3 + + sub len, BYTES_PER_LOOP + movdqa xmm0, oword [rsp+CNT] ; next counter value + cmp len, BYTES_PER_LOOP + jge .blks4_loop + +.combine_hash: + movdqa xmm8,oword [rbx] ; hk<<1 + movdqa xmm9,oword [rbx+sizeof_oword_] ; (hk^2)<<1 + + sse_clmul_gcm xmm0, xmm10, xmm6, xmm4, xmm5 ; gHash0 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm1, xmm9, xmm6, xmm4, xmm5 ; gHash1 = gHash1 * (HashKey^2)<<1 mod poly + sse_clmul_gcm xmm2, xmm8, xmm6, xmm4, xmm5 ; gHash2 = gHash2 * (HashKey^1)<<1 mod poly + + pxor xmm3, xmm1 + pxor xmm3, xmm2 + sse_clmul_gcm xmm3, xmm8, xmm6, xmm4, xmm5 ; gHash3 = gHash3 * (HashKey)<<1 mod poly + pxor xmm3, xmm0 + movdqa oword [rsp+GHASH0], xmm3 ; store gHash + +;; +;; rest of input processing (1-3 blocks) +;; +.single_block_proc: + test rax, rax + jz .quit + +align IPP_ALIGN_FACTOR +.blk_loop: + movdqa xmm0, oword [rsp+CNT] ; advance counter value + movdqa xmm1, xmm0 + paddd xmm1, oword [rel INC_1] + movdqa oword [rsp+CNT], xmm1 + + movdqa xmm0, oword [rcx] ; pre-load whitening keys + mov r10, rcx + + pshufb xmm1, [rel SHUF_CONST] ; counter is ready to be encrypted + + pxor xmm1, xmm0 ; whitening + + movdqa xmm0, oword [r10+16] + add r10, 16 + + mov r11d, nr ; counter depending on key length + sub r11, 1 + +align IPP_ALIGN_FACTOR +.cipher_loop: +my_aesenc xmm1, xmm0 ; regular round + movdqa xmm0, oword [r10+16] + add r10, 16 + dec r11 + jnz .cipher_loop +my_aesenclast xmm1, xmm0 + + movdqa xmm0, oword [rsp+ECNT] ; load pre-calculated encrypted counter + movdqa oword [rsp+ECNT], xmm1 ; save encrypted counter + + movdqu xmm1, oword [pSrc] ; input block + add pSrc, BYTES_PER_BLK + pxor xmm0, xmm1 ; ctr encryption + movdqu oword [pDst], xmm0 + add pDst, BYTES_PER_BLK + + pshufb xmm0, [rel SHUF_CONST] + pxor xmm0, oword [rsp+GHASH0] + movdqa xmm1, oword [rbx] + sse_clmul_gcm xmm0, xmm1, xmm2, xmm3, xmm4 ; update hash value + movdqa oword [rsp+GHASH0], xmm0 + + sub rax, BYTES_PER_BLK + jg .blk_loop + +;; +;; exit +;; +.quit: + movdqa xmm0, oword [rsp+CNT] ; counter + movdqa xmm1, oword [rsp+ECNT] ; encrypted counter + movdqa xmm2, oword [rsp+GHASH0] ; hash + + mov rax, pCtrValue ; address of the counter + mov rbx, pEncCtrValue ; address of the encrypted counter + mov rcx, pGhash ; address of hash value + + pshufb xmm0, [rel SHUF_CONST] ; convert counter back and + movdqu oword [rax], xmm0 ; store counter into the context + + movdqu oword [rbx], xmm1 ; store encrypted counter into the context + + pshufb xmm2, [rel SHUF_CONST] ; convert hach value back + movdqu oword [rcx], xmm2 ; store hash into the context + + REST_XMM + REST_GPR + ret +ENDFUNC AesGcmEnc_avx + +;*************************************************************** +;* Purpose: pipelined AES-GCM decryption +;* +;* void AesGcmDec_avx(Ipp8u* pDst, +;* const Ipp8u* pSrc,, +;* int length, +;* RijnCipher cipher, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp8u* pGhash, +;* Ipp8u* pCtrValue, +;* Ipp8u* pEncCtrValue, +;* const Ipp8u* pPrecomData) +;*************************************************************** +align IPP_ALIGN_FACTOR +;; +;; Lib = Y8, E9 +;; +;; Caller = ippsRijndael128GCMDecrypt +;; +IPPASM AesGcmDec_avx,PUBLIC +%assign LOCAL_FRAME (8*16) + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 + COMP_ABI 10 + +%xdefine pDst rdi ; pointer to the encrypted data +%xdefine pSrc rsi ; pointer to the plane data +%xdefine len rdx ; data length in bytes (multiple by BYTES_PER_BLK) +%xdefine cipher rcx ; ciper function (don't need in fact) +%xdefine nr r8d ; number of cipher's rounds +%xdefine pRKey r9 ; pointer to the cipher's round keys +%xdefine pGhash [rsp+ARG_7] ; pointer to the Hash value +%xdefine pCtrValue [rsp+ARG_8] ; pointer to the counter value +%xdefine pEncCtrValue [rsp+ARG_9] ; pointer to the encrypted counter +%xdefine pPrecomData [rsp+ARG_10]; pointer to the precomputed data + +%assign SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + +;; +;; stack structure: +%assign CNT (0) +%assign ECNT (CNT+sizeof_oword_) +%assign GHASH (ECNT+sizeof_oword_) + +%assign GHASH0 (GHASH) +%assign GHASH1 (GHASH0+sizeof_oword_) +%assign GHASH2 (GHASH1+sizeof_oword_) +%assign GHASH3 (GHASH2+sizeof_oword_) +%assign HKeyKaratsuba (GHASH3+sizeof_oword_) + + mov rax, pCtrValue ; address of the counter + mov rbx, pEncCtrValue ; address of the encrypted counter + mov rcx, pGhash ; address of hash value + movdqa xmm4,oword [rel SHUF_CONST] + + movdqu xmm0, oword [rax] ; counter value + movdqu xmm1, oword [rbx] ; encrypted counter value + movdqu xmm2, oword [rcx] ; hash value + + pshufb xmm0, xmm4 ; convert counter and + movdqa oword [rsp+CNT], xmm0 ; store into the stack + movdqa oword [rsp+ECNT], xmm1 ; store encrypted counter into the stack + + pshufb xmm2, xmm4 ; convert hash value + pxor xmm1, xmm1 + movdqa oword [rsp+GHASH0], xmm2 ; store hash into the stack + movdqa oword [rsp+GHASH1], xmm1 ; + movdqa oword [rsp+GHASH2], xmm1 ; + movdqa oword [rsp+GHASH3], xmm1 ; + + mov rbx, [rsp+ARG_10] ; pointer to the {hk<<1,hk^2<<1,kh^4<<1} multipliers + movdqa xmm10,oword [rbx+sizeof_oword_*2] + pshufd xmm9, xmm10, 01001110b ; xmm0 holds qword-swapped version of (HashKey^4)<<1 mod poly for Karatsuba + pxor xmm9, xmm10 + movdqa oword [rsp+HKeyKaratsuba], xmm9 + + movsxd len, edx ; data length + mov rcx, pRKey ; rcx point to the chipher's round keys + + mov rax, len + and rax, BYTES_PER_LOOP-1 + and len, -BYTES_PER_LOOP + jz .single_block_proc + +;; +;; pipelined processing (4 blocks) +;; +align IPP_ALIGN_FACTOR +.blks4_loop: + ;; + ;; ctr encryption + ;; + movdqa xmm6,oword [rel INC_1] + movdqa xmm5,oword [rel SHUF_CONST] + + movdqa xmm1, xmm0 ; counter+1 + paddd xmm1, oword [rel INC_1] + movdqa xmm2, xmm1 ; counter+2 + paddd xmm2, oword [rel INC_1] + movdqa xmm3, xmm2 ; counter+3 + paddd xmm3, oword [rel INC_1] + movdqa xmm4, xmm3 ; counter+4 + paddd xmm4, oword [rel INC_1] + movdqa oword [rsp+CNT], xmm4 + + movdqa xmm0, oword [rcx] ; pre-load whitening keys + mov r10, rcx + + pshufb xmm1, xmm5 ; counter, counter+1, counter+2, counter+3 + pshufb xmm2, xmm5 ; ready to be encrypted + pshufb xmm3, xmm5 + pshufb xmm4, xmm5 + + pxor xmm1, xmm0 ; whitening + pxor xmm2, xmm0 + pxor xmm3, xmm0 + pxor xmm4, xmm0 + + movdqa xmm0, oword [r10+16] + add r10, 16 + + mov r11d, nr ; counter depending on key length + sub r11, 1 + +align IPP_ALIGN_FACTOR +.cipher4_loop: +my_aesenc xmm1, xmm0 ; regular round +my_aesenc xmm2, xmm0 +my_aesenc xmm3, xmm0 +my_aesenc xmm4, xmm0 + movdqa xmm0, oword [r10+16] + add r10, 16 + dec r11 + jnz .cipher4_loop +my_aesenclast xmm1, xmm0 +my_aesenclast xmm2, xmm0 +my_aesenclast xmm3, xmm0 +my_aesenclast xmm4, xmm0 + + movdqa xmm0, oword [rsp+ECNT] ; load pre-calculated encrypted counter + movdqa oword [rsp+ECNT], xmm4 ; save encrypted counter+4 + + movdqu xmm4, oword [pSrc+0*BYTES_PER_BLK] ; 4 input blocks + movdqu xmm5, oword [pSrc+1*BYTES_PER_BLK] + movdqu xmm6, oword [pSrc+2*BYTES_PER_BLK] + movdqu xmm7, oword [pSrc+3*BYTES_PER_BLK] + add pSrc, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; ctr encryption + movdqu oword [pDst+0*BYTES_PER_BLK], xmm0 ; store result + pshufb xmm4, [rel SHUF_CONST] ; convert for multiplication and + pxor xmm4, oword [rsp+GHASH0] + + pxor xmm1, xmm5 + movdqu oword [pDst+1*BYTES_PER_BLK], xmm1 + pshufb xmm5, [rel SHUF_CONST] + pxor xmm5, oword [rsp+GHASH1] + + pxor xmm2, xmm6 + movdqu oword [pDst+2*BYTES_PER_BLK], xmm2 + pshufb xmm6, [rel SHUF_CONST] + pxor xmm6, oword [rsp+GHASH2] + + pxor xmm3, xmm7 + movdqu oword [pDst+3*BYTES_PER_BLK], xmm3 + pshufb xmm7, [rel SHUF_CONST] + pxor xmm7, oword [rsp+GHASH3] + + add pDst, BYTES_PER_LOOP + + cmp len, BYTES_PER_LOOP + je .combine_hash + + ;; + ;; update hash value + ;; + movdqa xmm14, oword [rel MASK1] + sse_clmul_gcm_2way xmm10, xmm9, xmm4, xmm0, xmm1, xmm2, xmm5, xmm11, xmm12, xmm13, xmm15 + sse_clmul_gcm_2way xmm10, xmm9, xmm6, xmm0, xmm1, xmm2, xmm7, xmm11, xmm12, xmm13, xmm15 + + movdqa oword [rsp+GHASH0], xmm4 + movdqa oword [rsp+GHASH1], xmm5 + movdqa oword [rsp+GHASH2], xmm6 + movdqa oword [rsp+GHASH3], xmm7 + + sub len, BYTES_PER_LOOP + movdqa xmm0, oword [rsp+CNT] ; next counter value + cmp len, BYTES_PER_LOOP + jge .blks4_loop + +.combine_hash: + movdqa xmm8,oword [rbx] ; hk<<1 + movdqa xmm9,oword [rbx+sizeof_oword_] ; (hk^2)<<1 + + sse_clmul_gcm xmm4, xmm10, xmm0, xmm1, xmm2 ; gHash0 = gHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm xmm5, xmm9, xmm0, xmm1, xmm2 ; gHash1 = gHash1 * (HashKey^2)<<1 mod poly + sse_clmul_gcm xmm6, xmm8, xmm0, xmm1, xmm2 ; gHash2 = gHash2 * (HashKey^1)<<1 mod poly + + pxor xmm7, xmm5 + pxor xmm7, xmm6 + sse_clmul_gcm xmm7, xmm8, xmm0, xmm1, xmm2 ; gHash3 = gHash3 * (HashKey)<<1 mod poly + pxor xmm7, xmm4 + movdqa oword [rsp+GHASH0], xmm7 ; store gHash + +;; +;; rest of input processing (1-3 blocks) +;; +.single_block_proc: + test rax, rax + jz .quit + +align IPP_ALIGN_FACTOR +.blk_loop: + movdqa xmm0, oword [rsp+CNT] ; advance counter value + movdqa xmm1, xmm0 + paddd xmm1, oword [rel INC_1] + movdqa oword [rsp+CNT], xmm1 + + movdqa xmm0, oword [rcx] ; pre-load whitening keys + mov r10, rcx + + pshufb xmm1, [rel SHUF_CONST] ; counter is ready to be encrypted + + pxor xmm1, xmm0 ; whitening + + movdqa xmm0, oword [r10+16] + add r10, 16 + + mov r11d, nr ; counter depending on key length + sub r11, 1 + +align IPP_ALIGN_FACTOR +.cipher_loop: +my_aesenc xmm1, xmm0 ; regular round + movdqa xmm0, oword [r10+16] + add r10, 16 + dec r11 + jnz .cipher_loop +my_aesenclast xmm1, xmm0 + + movdqa xmm0, oword [rsp+ECNT] ; load pre-calculated encrypted counter + movdqa oword [rsp+ECNT], xmm1 ; save encrypted counter + + movdqu xmm1, oword [pSrc] ; input block + add pSrc, BYTES_PER_BLK + pxor xmm0, xmm1 ; ctr encryption + movdqu oword [pDst], xmm0 + add pDst, BYTES_PER_BLK + + pshufb xmm1, [rel SHUF_CONST] + pxor xmm1, oword [rsp+GHASH0] + movdqa xmm0, oword [rbx] + sse_clmul_gcm xmm1, xmm0, xmm2, xmm3, xmm4 ; update hash value + movdqa oword [rsp+GHASH0], xmm1 + + sub rax, BYTES_PER_BLK + jg .blk_loop + +;; +;; exit +;; +.quit: + movdqa xmm0, oword [rsp+CNT] ; counter + movdqa xmm1, oword [rsp+ECNT] ; encrypted counter + movdqa xmm2, oword [rsp+GHASH0] ; hash + + mov rax, pCtrValue ; address of the counter + mov rbx, pEncCtrValue ; address of the encrypted counter + mov rcx, pGhash ; address of hash value + + pshufb xmm0, [rel SHUF_CONST] ; convert counter back and + movdqu oword [rax], xmm0 ; store counter into the context + + movdqu oword [rbx], xmm1 ; store encrypted counter into the context + + pshufb xmm2, [rel SHUF_CONST] ; convert hach value back + movdqu oword [rcx], xmm2 ; store hash into the context + + REST_XMM + REST_GPR + ret +ENDFUNC AesGcmDec_avx + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpaesgcmtable2ku8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpaesgcmtable2ku8as.asm new file mode 100644 index 000000000..283ae0a0b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpaesgcmtable2ku8as.asm @@ -0,0 +1,418 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Encrypt/Decrypt byte data stream according to Rijndael128 (GCM mode) +; +; Content: +; AesGcmMulGcm_table2K() +; AesGcmAuth_table2K() +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + + +%if (_IPP32E >= _IPP32E_U8) + +segment .text align=IPP_ALIGN_FACTOR + +; +; getAesGcmConst_table_ct provides c-e-t access to pre-computed Ipp16u AesGcmConst_table[256] +; +; input: +; r9: address of the AesGcmConst_table +; rcx: index in the table +; +; output: +; rax +; +; register rcx destoyed +; registers mmx2, mmx3, mmx6, and mmx7 destoyed +; +align IPP_ALIGN_FACTOR +INIT_IDX dw 000h,001h,002h,003h,004h,005h,006h,007h ;; initial search inx = {0:1:2:3:4:5:6:7} +INCR_IDX dw 008h,008h,008h,008h,008h,008h,008h,008h ;; index increment = {8:8:8:8:8:8:8:8} + +align IPP_ALIGN_FACTOR +IPPASM getAesGcmConst_table_ct,PRIVATE + pxor xmm2, xmm2 ;; accumulator xmm2 = 0 + + mov rax, rcx ;; broadcast inx into dword + shl rcx, 16 + or rcx, rax + movq xmm3, rcx + pshufd xmm3, xmm3, 00b ;; search index xmm3 = broadcast(idx) + + movdqa xmm6, xmmword [rel INIT_IDX] ;; current indexes + + xor rax, rax +align IPP_ALIGN_FACTOR +.search_loop: + movdqa xmm7, xmm6 ;; copy current indexes + paddw xmm6, xmmword [rel INCR_IDX] ;; advance current indexes + + pcmpeqw xmm7, xmm3 ;; selection mask + pand xmm7, xmmword [r9+rax*sizeof(word)] ;; mask data + + add rax, 8 + cmp rax, 256 + + por xmm2, xmm7 ;; and accumulate + jl .search_loop + + movdqa xmm3, xmm2 ;; pack result in qword + psrldq xmm2, sizeof(xmmword)/2 + por xmm2, xmm3 + movq rax, xmm2 + + and rcx, 3 ;; select tbl[idx] value + shl rcx, 4 ;; rcx *=16 = sizeof(word)*8 + shr rax, cl + ret +ENDFUNC getAesGcmConst_table_ct + +; +; void AesGcmMulGcm_table2K(Ipp8u* pHash, const Ipp8u* pPrecomputedData, const void* pParam) +; +align IPP_ALIGN_FACTOR +IPPASM AesGcmMulGcm_table2K,PUBLIC + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7 + COMP_ABI 3 + + movdqu xmm0, [rdi] ; hash value + mov r8, rsi ; precomputed data pointer + + mov r9, rdx ; pointer to the fixed table (AesGcmConst_table) + + movd ebx, xmm0 ; ebx = hash.0 + mov eax, 0f0f0f0f0h + and eax, ebx ; eax = 4 x 4_bits + shl ebx, 4 + and ebx, 0f0f0f0f0h ; ebx = 4 x 4_bits (another) + movzx ecx, ah + movdqa xmm5, oword [r8+1024+rcx] + movzx ecx, al + movdqa xmm4, oword [r8+1024+rcx] + shr eax, 16 + movzx ecx, ah + movdqa xmm3, oword [r8+1024+rcx] + movzx ecx, al + movdqa xmm2, oword [r8+1024+rcx] + + psrldq xmm0, 4 ; shift xmm0 + movd eax, xmm0 ; eax = hash[1] + and eax, 0f0f0f0f0h ; eax = 4 x 4_bits + + movzx ecx, bh + pxor xmm5, oword [r8+ (1-1)*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ (1-1)*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ (1-1)*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ (1-1)*256 + rcx] + + movd ebx, xmm0 ; ebx = hash[1] + shl ebx, 4 ; another 4 x 4_bits + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [r8+1024+ 1*256 + rcx] + movzx ecx, al + pxor xmm4, oword [r8+1024+ 1*256 + rcx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [r8+1024+ 1*256 + rcx] + movzx ecx, al + pxor xmm2, oword [r8+1024+ 1*256 + rcx] + psrldq xmm0, 4 + + movd eax, xmm0 ; eax = hash.2 + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [r8+ (2-1)*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ (2-1)*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ (2-1)*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ (2-1)*256 + rcx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [r8+1024+ 2*256 + rcx] + movzx ecx, al + pxor xmm4, oword [r8+1024+ 2*256 + rcx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [r8+1024+ 2*256 + rcx] + movzx ecx, al + pxor xmm2, oword [r8+1024+ 2*256 + rcx] + + psrldq xmm0, 4 + movd eax, xmm0 ; eax = hash.3 + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [r8+ (3-1)*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ (3-1)*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ (3-1)*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ (3-1)*256 + rcx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [r8+1024+ 3*256 + rcx] + movzx ecx, al + pxor xmm4, oword [r8+1024+ 3*256 + rcx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [r8+1024+ 3*256 + rcx] + movzx ecx, al + pxor xmm2, oword [r8+1024+ 3*256 + rcx] + + movzx ecx, bh + pxor xmm5, oword [r8+ 3*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ 3*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ 3*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ 3*256 + rcx] + + movdqa xmm0, xmm3 + pslldq xmm3, 1 + pxor xmm2, xmm3 + movdqa xmm1, xmm2 + pslldq xmm2, 1 + pxor xmm5, xmm2 + psrldq xmm0, 15 + + movd ecx, xmm0 + CALL_IPPASM getAesGcmConst_table_ct ;;movzx eax, word [r9 + rcx*sizeof(word)] + shl eax, 8 + movdqa xmm0, xmm5 + pslldq xmm5, 1 + pxor xmm4, xmm5 + psrldq xmm1, 15 + movd ecx, xmm1 + mov rbx, rax ;;xor ax, word [r9 + rcx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor rax, rbx ;; + shl eax, 8 + psrldq xmm0, 15 + movd ecx, xmm0 + mov rbx, rax ;;xor ax, word [r9 + rcx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor rax, rbx ;; + movd xmm0, eax + pxor xmm0, xmm4 + + movdqu oword [rdi], xmm0 ; store hash value + + REST_XMM + REST_GPR + ret +ENDFUNC AesGcmMulGcm_table2K + + +; +; void AesGcmAuth_table2K(Ipp8u* pHash, const Ipp8u* pSrc, int len, const Ipp8u* pPrecomputedData, const void* pParam) +; +align IPP_ALIGN_FACTOR +IPPASM AesGcmAuth_table2K,PUBLIC + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7 + COMP_ABI 5 + + mov r9, r8 ; pointer to the fixed table (pParam) + + movdqu xmm0, [rdi] ; hash value + mov r8, rcx ; precomputed data pointer + +align IPP_ALIGN_FACTOR +.auth_loop: + movdqu xmm4, [rsi] ; get src[] + pxor xmm0, xmm4 ; hash ^= src[] + + movd ebx, xmm0 ; ebx = hash.0 + mov eax, 0f0f0f0f0h + and eax, ebx ; eax = 4 x 4_bits + shl ebx, 4 + and ebx, 0f0f0f0f0h ; ebx = 4 x 4_bits (another) + movzx ecx, ah + movdqa xmm5, oword [r8+1024+rcx] + movzx ecx, al + movdqa xmm4, oword [r8+1024+rcx] + shr eax, 16 + movzx ecx, ah + movdqa xmm3, oword [r8+1024+rcx] + movzx ecx, al + movdqa xmm2, oword [r8+1024+rcx] + + psrldq xmm0, 4 ; shift xmm0 + movd eax, xmm0 ; eax = hash[1] + and eax, 0f0f0f0f0h ; eax = 4 x 4_bits + + movzx ecx, bh + pxor xmm5, oword [r8+ (1-1)*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ (1-1)*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ (1-1)*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ (1-1)*256 + rcx] + + movd ebx, xmm0 ; ebx = hash[1] + shl ebx, 4 ; another 4 x 4_bits + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [r8+1024+ 1*256 + rcx] + movzx ecx, al + pxor xmm4, oword [r8+1024+ 1*256 + rcx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [r8+1024+ 1*256 + rcx] + movzx ecx, al + pxor xmm2, oword [r8+1024+ 1*256 + rcx] + + psrldq xmm0, 4 + movd eax, xmm0 ; eax = hash[2] + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [r8+ (2-1)*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ (2-1)*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ (2-1)*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ (2-1)*256 + rcx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [r8+1024+ 2*256 + rcx] + movzx ecx, al + pxor xmm4, oword [r8+1024+ 2*256 + rcx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [r8+1024+ 2*256 + rcx] + movzx ecx, al + pxor xmm2, oword [r8+1024+ 2*256 + rcx] + + psrldq xmm0, 4 + movd eax, xmm0 ; eax = hash[3] + and eax, 0f0f0f0f0h + + movzx ecx, bh + pxor xmm5, oword [r8+ (3-1)*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ (3-1)*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ (3-1)*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ (3-1)*256 + rcx] + + movd ebx, xmm0 + shl ebx, 4 + and ebx, 0f0f0f0f0h + + movzx ecx, ah + pxor xmm5, oword [r8+1024+ 3*256 + rcx] + movzx ecx, al + pxor xmm4, oword [r8+1024+ 3*256 + rcx] + shr eax, 16 + movzx ecx, ah + pxor xmm3, oword [r8+1024+ 3*256 + rcx] + movzx ecx, al + pxor xmm2, oword [r8+1024+ 3*256 + rcx] + + movzx ecx, bh + pxor xmm5, oword [r8+ 3*256 + rcx] + movzx ecx, bl + pxor xmm4, oword [r8+ 3*256 + rcx] + shr ebx, 16 + movzx ecx, bh + pxor xmm3, oword [r8+ 3*256 + rcx] + movzx ecx, bl + pxor xmm2, oword [r8+ 3*256 + rcx] + + movdqa xmm0, xmm3 + pslldq xmm3, 1 + pxor xmm2, xmm3 + movdqa xmm1, xmm2 + pslldq xmm2, 1 + pxor xmm5, xmm2 + psrldq xmm0, 15 + + movd ecx, xmm0 + CALL_IPPASM getAesGcmConst_table_ct ;;movzx eax, word [r9 + rcx*sizeof(word)] + shl eax, 8 + movdqa xmm0, xmm5 + pslldq xmm5, 1 + pxor xmm4, xmm5 + psrldq xmm1, 15 + movd ecx, xmm1 + mov rbx, rax ;;xor ax, word [r9 + rcx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor rax, rbx ;; + shl eax, 8 + psrldq xmm0, 15 + movd ecx, xmm0 + mov rbx, rax ;;xor ax, word [r9 + rcx*sizeof(word)] + CALL_IPPASM getAesGcmConst_table_ct ;; + xor rax, rbx ;; + movd xmm0, eax + pxor xmm0, xmm4 + + add rsi, sizeof(oword) ; advance src address + sub rdx, sizeof(oword) ; decrease counter + jnz .auth_loop ; process next block + + movdqu oword [rdi], xmm0 ; store hash value + + REST_XMM + REST_GPR + ret +ENDFUNC AesGcmAuth_table2K + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnuaddm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnuaddm7as.asm new file mode 100644 index 000000000..1a2672c04 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnuaddm7as.asm @@ -0,0 +1,327 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpAdd_BNU() +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + +;************************************************************* +;* Ipp64u cpAdd_BNU(Ipp64u* pDst, +;* const Ipp64u* pSrc1, +;* const Ipp64u* pSrc2, +;* int len) +;* returns carry +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpAdd_BNU,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 4 + +; rdi = pDst +; rsi = pSrcA +; rdx = pSrcB +; rcx = len + + movsxd rcx, ecx ; unsigned length + xor rax, rax + + cmp rcx, 2 + jge .ADD_GE2 + +;********** lenSrcA == 1 ************************************* + add rax, rax + mov r8, qword [rsi] ; rsi = a + adc r8, qword [rdx] ; r8 = a+b = s + mov qword [rdi], r8 ; save s + sbb rax, rax ; + jmp .FINAL + +;********** lenSrcA == 1 END ******************************** + +.ADD_GE2: + jg .ADD_GT2 + +;********** lenSrcA == 2 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r9, qword [rdx+8] ; r9 = a1+b1 = s1 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + sbb rax, rax ; rax = carry + jmp .FINAL + +;********** lenSrcA == 2 END ********************************* + +.ADD_GT2: + cmp rcx, 4 + jge .ADD_GE4 + +;********** lenSrcA == 3 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r9, qword [rdx+8] ; r9 = a1+b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + adc r10, qword [rdx+16] ; r10 = a2+b2 = s2 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + sbb rax, rax ; rax = carry + jmp .FINAL + +;********** lenSrcA == 3 END ********************************* + +.ADD_GE4: + jg .ADD_GT4 + +;********** lenSrcA == 4 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r9, qword [rdx+8] ; r9 = a1+b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + adc r10, qword [rdx+16] ; r10 = a2+b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + adc r11, qword [rdx+24] ; r11 = a3+b3 = s3 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s2 + sbb rax, rax ; rax = carry + jmp .FINAL + +;********** lenSrcA == 4 END ********************************* + +.ADD_GT4: + cmp rcx, 6 + jge .ADD_GE6 + +;********** lenSrcA == 5 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r9, qword [rdx+8] ; r9 = a1+b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + adc r10, qword [rdx+16] ; r10 = a2+b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + adc r11, qword [rdx+24] ; r11 = a3+b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + adc rcx, qword [rdx+32] ; rcx = a4+b4 = s4 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + sbb rax, rax ; rax = carry + jmp .FINAL + +;********** lenSrcA == 5 END ********************************* + +.ADD_GE6: + jg .ADD_GT6 + +;********** lenSrcA == 6 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r9, qword [rdx+8] ; r9 = a1+b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + adc r10, qword [rdx+16] ; r10 = a2+b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + adc r11, qword [rdx+24] ; r11 = a3+b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + adc rcx, qword [rdx+32] ; rcx = a4+b4 = s4 + mov rsi, qword [rsi+40] ; rsi = a5 + adc rsi, qword [rdx+40] ; rsi = a5+b5 = s5 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + mov qword [rdi+40], rsi ; save s5 + sbb rax, rax ; rax = carry + jmp .FINAL + +;********** lenSrcA == 6 END ********************************* + +.ADD_GT6: + cmp rcx, 8 + jge .ADD_GE8 + +.ADD_EQ7: +;********** lenSrcA == 7 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r9, qword [rdx+8] ; r9 = a1+b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + adc r10, qword [rdx+16] ; r10 = a2+b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + adc r11, qword [rdx+24] ; r11 = a3+b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + adc rcx, qword [rdx+32] ; rcx = a4+b4 = s4 + mov qword [rdi], r8 ; save s0 + mov r8, qword [rsi+40] ; r8 = a5 + adc r8, qword [rdx+40] ; r8 = a5+b5 = s5 + mov rsi, qword [rsi+48] ; rsi = a6 + adc rsi, qword [rdx+48] ; rsi = a6+b6 = s6 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + mov qword [rdi+40], r8 ; save s5 + mov qword [rdi+48], rsi ; save s6 + sbb rax, rax ; rax = carry + jmp .FINAL + +;********** lenSrcA == 7 END ********************************* + + +.ADD_GE8: + jg .ADD_GT8 + +;********** lenSrcA == 8 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r9, qword [rdx+8] ; r9 = a1+b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + adc r10, qword [rdx+16] ; r10 = a2+b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + adc r11, qword [rdx+24] ; r11 = a3+b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + adc rcx, qword [rdx+32] ; rcx = a4+b4 = s4 + mov qword [rdi], r8 ; save s0 + mov r8, qword [rsi+40] ; r8 = a5 + adc r8, qword [rdx+40] ; r8 = a5+b5 = s5 + mov qword [rdi+8], r9 ; save s1 + mov r9, qword [rsi+48] ; r9 = a7 + adc r9, qword [rdx+48] ; r9 = a7+b7 = s7 + mov rsi, qword [rsi+56] ; rsi = a6 + adc rsi, qword [rdx+56] ; rsi = a6+b6 = s6 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + mov qword [rdi+40], r8 ; save s5 + mov qword [rdi+48], r9 ; save s6 + mov qword [rdi+56], rsi ; save s7 + sbb rax, rax ; rax = carry + jmp .FINAL + +;********** lenSrcA == 8 END ********************************* + + +;********** lenSrcA > 8 ************************************* + +.ADD_GT8: + mov r8, rax + mov rax, rcx ; rax = len + and rcx, 3 ; + xor rcx, rax ; + lea rsi, [rsi+8*rcx] ; + lea rdx, [rdx+8*rcx] ; + lea rdi, [rdi+8*rcx] ; + neg rcx + add r8, r8 + jmp .ADD_GLOOP + +align IPP_ALIGN_FACTOR +.ADD_GLOOP: + mov r8, qword [rsi+8*rcx] ; r8 = a0 + mov r9, qword [rsi+8*rcx+8] ; r9 = a1 + mov r10, qword [rsi+8*rcx+16] ; r10 = a2 + mov r11, qword [rsi+8*rcx+24] ; r11 = a3 + adc r8, qword [rdx+8*rcx] ; r8 = a0+b0 = r0 + adc r9, qword [rdx+8*rcx+8] ; r9 = a1+b1 = r1 + adc r10, qword [rdx+8*rcx+16] ; r10 = a2+b2 = r2 + adc r11, qword [rdx+8*rcx+24] ; r11 = a3+b3 = r3 + mov qword [rdi+8*rcx], r8 ; + mov qword [rdi+8*rcx+8], r9 ; + mov qword [rdi+8*rcx+16], r10 ; + mov qword [rdi+8*rcx+24], r11 ; + lea rcx, [rcx+4] + jrcxz .ADD_LLAST0 + jmp .ADD_GLOOP + +.ADD_LLAST0: + sbb rcx, rcx + and rax, 3 + jz .FIN0 + +.ADD_LLOOP: + test rax, 2 + jz .ADD_LLAST1 + + add rcx, rcx + mov r8, qword [rsi] ; r8 = a0 + mov r9, qword [rsi+8] ; r9 = a1 + adc r8, qword [rdx] ; r8 = a0+b0 = r0 + adc r9, qword [rdx+8] ; r9 = a1+b1 = r1 + mov qword [rdi], r8 ; + mov qword [rdi+8], r9 ; + sbb rcx, rcx + test rax, 1 + jz .FIN0 + + add rsi, 16 + add rdx, 16 + add rdi, 16 + +.ADD_LLAST1: + add rcx, rcx + mov r8, qword [rsi] ; r8 = a0 + adc r8, qword [rdx] ; r8 = a0+b0 = r0 + mov qword [rdi], r8 ; + sbb rcx, rcx + +.FIN0: + mov rax, rcx + +;******************* .FINAL *********************************************************** + +.FINAL: + neg rax + REST_XMM + REST_GPR + ret +ENDFUNC cpAdd_BNU + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnudivm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnudivm7as.asm new file mode 100644 index 000000000..5afe15668 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnudivm7as.asm @@ -0,0 +1,476 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpDiv_BNU32() +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" + +%if (_IPP32E >= _IPP32E_M7) + +;; +;; FIX_BNU returns actual length of BNU +;; +;; input +;; rSrc points BNU +;; rLen initial BNU size +;; +;; output +;; rSrc points BNU +;; rLen actual BNU size +;; +%macro FIX_BNU 3.nolist + %xdefine %%rSrc %1 + %xdefine %%rLen %2 + %xdefine %%tmp %3 + +%%fix_bnu_loop: + mov %%tmp%+d,[%%rSrc+%%rLen*4-4] ;; value + test %%tmp%+d,%%tmp%+d ;; test BNU component + jnz %%fix_bnu_quit + sub %%rLen,1 + jg %%fix_bnu_loop + add %%rLen,1 +%%fix_bnu_quit: +%endmacro + + +;; +;; Number of Leaging Zeros in32-bit value +;; +%macro NLZ32u 2.nolist + %xdefine %%rNlz %1 + %xdefine %%rVal %2 + + mov %%rNlz, 32 + test %%rVal,%%rVal + jz %%nlz_quit + + xor %%rNlz,%%rNlz +%%nlz16: + test %%rVal,0FFFF0000h + jnz %%nlz8 + shl %%rVal,16 + add %%rNlz,16 +%%nlz8: + test %%rVal,0FF000000h + jnz %%nlz4 + shl %%rVal,8 + add %%rNlz,8 +%%nlz4: + test %%rVal,0F0000000h + jnz %%nlz2 + shl %%rVal,4 + add %%rNlz,4 +%%nlz2: + test %%rVal,0C0000000h + jnz %%nlz1 + shl %%rVal,2 + add %%rNlz,2 +%%nlz1: + test %%rVal,080000000h + jnz %%nlz_quit + add %%rNlz,1 +%%nlz_quit: +%endmacro + + +;; +;; (Logical) Shift BNU Left and Right +;; +;; Input: +;; rDst source/destination address +;; rLen length (dwords) of BNU +;; CL left shift +;; rTmpH scratch +;; rTmpL scratch +;; Note +;; rDst don't changes +;; rLen changes +;; +%macro SHL_BNU_I 4.nolist + %xdefine %%rDst %1 + %xdefine %%rLen %2 + %xdefine %%rTmpH %3 + %xdefine %%rTmpL %4 + + mov %%rTmpH%+d,[%%rDst+%%rLen*4-4] + sub %%rLen,1 + jz %%shl_bnu_quit +%%shl_bnu_loop: + mov %%rTmpL%+d,[%%rDst+%%rLen*4-4] + shld %%rTmpH%+d,%%rTmpL%+d, CL + mov [%%rDst+%%rLen*4],%%rTmpH%+d + mov %%rTmpH%+d,%%rTmpL%+d + sub %%rLen,1 + jg %%shl_bnu_loop +%%shl_bnu_quit: + shl %%rTmpH%+d,CL + mov [%%rDst],%%rTmpH%+d +%endmacro + + +%macro SHR_BNU_I 4.nolist + %xdefine %%rDst %1 + %xdefine %%rLen %2 + %xdefine %%rTmpH %3 + %xdefine %%rTmpL %4 + + push %%rDst + mov %%rTmpL%+d,[%%rDst] + sub %%rLen,1 + jz %%shr_bnu_quit +%%shr_bnu_loop: + mov %%rTmpH%+d,[%%rDst+4] + shrd %%rTmpL%+d,%%rTmpH%+d, CL + mov [%%rDst],%%rTmpL%+d + add %%rDst,4 + mov %%rTmpL%+d,%%rTmpH%+d + sub %%rLen,1 + jg %%shr_bnu_loop +%%shr_bnu_quit: + shr %%rTmpL%+d,CL + mov [%%rDst],%%rTmpL%+d + pop %%rDst +%endmacro + + +;; +;; Multuply BNU by 32-bit digit and Subtract +;; +;; input +;; rSrc points source BNU +;; rDgt 32-bit digit value +;; rDst points accumulator (resultant) BNU +;; rLen BNU size +;; rIdx (scratch) source/target index +;; rExp (scratch) expansion +;; +;; output +;; rDgt 32-bit expansion +;; +;; Note +;; rdx and rax used in mul instruction, +;; this mean any macro argument may be neither rax nor rdx +;; +%macro xMDC_BNU_D32 6.nolist + %xdefine %%rSrc %1 + %xdefine %%rDgt %2 + %xdefine %%rDst %3 + %xdefine %%rLen %4 + %xdefine %%rIdx %5 + %xdefine %%rExp %6 + + xor %%rIdx,%%rIdx ;; index = 0 + xor %%rExp,%%rExp ;; carry = 0 + + sub %%rLen,2 ;; test length + jl %%mdc_short + +%%mdc_loop: + mov rax, [%%rSrc+%%rIdx] ;; a = src[i] + mul %%rDgt ;; x = a*w + + add rax, %%rExp ;; x += borrow + adc rdx,0 + + xor %%rExp,%%rExp ;; zero extension of r + sub [%%rDst+%%rIdx],rax ;; dst[] -= x + sbb %%rExp,rdx + + neg %%rExp ;; update borrow + + add %%rIdx,2*4 ;; advance index + sub %%rLen,2 ;; decrease counter + jge %%mdc_loop ;; continue + + add %%rLen,2 + jz %%mdc_quit + +%%mdc_short: + mov eax, [%%rSrc+%%rIdx] ;; a = src[i] + mul %%rDgt%+d ;; x = a*w + + add eax, %%rExp%+d ;; x += borrow + adc edx,0 + + xor %%rExp%+d, %%rExp%+d ;; zero extension of r + sub [%%rDst+%%rIdx],eax ;; dst[] -= x + sbb %%rExp%+d,edx + + neg %%rExp%+d ;; update borrow + +%%mdc_quit: + mov %%rDgt,%%rExp ;; return borrow +%endmacro + + +;; +;; xADD_BNU add BNUs +;; +;; input +;; rDst points resultant BNU +;; rSrc1 points source BNU +;; rSrc2 points source BNU +;; rLen BNU size +;; rIdx source, resultant index +;; +;; output +;; rCarry carry value (byte) +;; +%macro xADD_BNU 8.nolist + %xdefine %%rDst %1 + %xdefine %%rCarry %2 + %xdefine %%rSrc1 %3 + %xdefine %%rSrc2 %4 + %xdefine %%rLen %5 + %xdefine %%rIdx %6 + %xdefine %%tmp1 %7 + %xdefine %%tmp2 %8 + + xor %%rCarry,%%rCarry ;; carry=0 + xor %%rIdx,%%rIdx ;; index=0 + + sub %%rLen,2 ;; test BNU size + jl %%short_bnu + + clc ;; CF=0 +%%add_bnu_loop: + mov %%tmp1,[%%rSrc1+%%rIdx*8] ;; src1[] + mov %%tmp2,[%%rSrc2+%%rIdx*8] ;; src2[] + adc %%tmp1,%%tmp2 ;; x = src1[]+src[2]+CF + mov [%%rDst+%%rIdx*8],%%tmp1 ;; dst[] = x + + inc %%rIdx ;; advance index + dec %%rLen ;; decrease length + dec %%rLen + jge %%add_bnu_loop ;; continue + setc %%rCarry%+b ;; save CF + + add %%rIdx,%%rIdx ;; restore ordinal index + add %%rLen,2 ;; restore length + jz %%add_bnu_exit + +%%short_bnu: + shr %%rCarry%+d,1 ;; restore CF + mov %%tmp1%+d,[%%rSrc1+%%rIdx*4] ;; src1[] + mov %%tmp2%+d,[%%rSrc2+%%rIdx*4] ;; src2[] + adc %%tmp1%+d,%%tmp2%+d ;; x = src1[]-src[2]-CF + mov [%%rDst+%%rIdx*4],%%tmp1%+d ;; dst[] = x + setc %%rCarry%+b ;; save CF + add %%rIdx,1 ;; advance index +%%add_bnu_exit: +%endmacro + + + +segment .text align=IPP_ALIGN_FACTOR + + +;************************************************************* +;* Ipp32u cpDiv_BNU32(Ipp32u* pQ, int* sizeQ, +;* Ipp32u* pX, int sizeX, +;* Ipp32u* pY, int sizeY) +;* +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpDiv_BNU32,PUBLIC +%assign LOCAL_FRAME 4*8 + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14,r15 + USES_XMM + COMP_ABI 6 + +; rdi = pQ ; address of quotient +; rsi = sizeQ ; address of quotient length +; rdx = pX ; address of denominator (remaider) +; rcx = sizeX ; length (dwords) of denominator +; r8 = pY ; address of divired +; r9 = sizeY ; length (dwords) of length + + movsxd rcx, ecx ; length + movsxd r9, r9d + +; make sure denominator and divider are fixed + FIX_BNU rdx,rcx, rax + FIX_BNU r8, r9, rax + + mov r10, rdx ; save pX + mov r11, rcx ; save sizeX + +; +; special case: sizeX < sizeY +; +.spec_case1: + cmp rcx, r9 + jae .spec_case2 + + test rdi, rdi ; %if quotient was requested + jz .spec_case1_quit + mov DWORD [rdi], 0 ; pQ[0] = 0 + mov DWORD [rsi], 1 ; sizeQ = 1 +.spec_case1_quit: + mov rax, rcx ; remainder length address + REST_XMM + REST_GPR + ret + +; +; special case: 1 == sizeY +; +.spec_case2: + cmp r9, 1 + jnz .common_case + + mov ebx, [r8] ; divider = pY[0] + xor edx,edx ; init remaider + +.spec_case2_loop: + mov eax,[r10+r11*4-4] + div ebx ; (edx,eax)/pY[0] + + test rdi, rdi ; store %if quotient requested + je .spec_case2_cont + mov [rdi+r11*4-4],eax + +.spec_case2_cont: + sub r11,1 + jg .spec_case2_loop + + test rdi, rdi ; %if quotient was requested + je .spec_case2_quit + FIX_BNU rdi,rcx, rax ; fix quotient + mov DWORD [rsi], ecx ; store quotient length +.spec_case2_quit: + mov DWORD [r10],edx ; pX[0] = remainder value + mov rax, dword 1 + REST_XMM + REST_GPR + ret + +; +; common case +; +.common_case: + xor eax,eax ; expand denominator + mov [r10+r11*4], eax ; by zero + + mov eax,[r8+r9*4-4] ; get divider's + NLZ32u ecx,eax ; factor + + test ecx,ecx ; test normalization factor + jz .division ; and + mov r15,r9 ; normalize + SHL_BNU_I r8,r15, r12,r13 ; divider + lea r15,[r11+1] ; and + SHL_BNU_I r10,r15, r12,r13 ; denominator + +; compute quotation digit-by-digit +.division: + mov ebx,[r8+r9*4-4] ; yHi - the most significant divider digit pY[ySize-1] + + mov [rsp], r10 ; save pX + mov [rsp+8], r11 ; save sizeX + + sub r11, r9 ; estimate length of quotient = (sizeX-sizeY+1) + mov [rsp+16], r11 ; (will use for loop counter) + + lea r10, [r10+r11*4] ; points current denominator position + +.division_loop: + mov rax,[r10+r9*4-4] ; tmp = (pX[xSize],pX[xSize-1]) + xor rdx,rdx ; estimate quotation digit: + div rbx ; (rax) q = tmp/yHi + ; (rdx) r = tmp%yHi + mov r12,rax + mov r13,rdx + + mov ebp,[r8+r9*4-8] ; next significant divider digit pY[ySize-2] +.tune_loop: + mov r15,0FFFFFFFF00000000h + and r15,rax ; %if q >= base .tune q value + jne .tune + mul rbp ; (rax) A = q*pY[ySize-2] + mov r14,r13 + shl r14,32 ; (rdx) B = QWORD(r,pX[xSize-2]) + mov edx,[r10+r9*4-8] + or rdx,r14 + cmp rax,rdx ; %if A>B .tune q value + jbe .mul_and_sub +.tune: + sub r12,1 ; q -= 1 + add r13d,ebx ; r += yHi + mov rax,r12 + jnc .tune_loop + +.mul_and_sub: + mov r15,r9 ; multiplay and subtract + mov ebp,r12d + xMDC_BNU_D32 r8, rbp, r10,r15, r13,r14 + sub [r10+r9*4],ebp ; extend = (pX[i+sizeY] -= extend); + + jnc .store_duotation + sub r12d,1 + mov r15,r9 + xADD_BNU r10,rax, r10,r8,r15, r13,r14,rdx + add [r10+r9*4],eax ; pX[i+sizeY] += extend; + +.store_duotation: + test rdi, rdi + jz .cont_division_loop + mov DWORD [rdi+r11*4],r12d + +.cont_division_loop: + sub r10,4 + sub r11,1 + jge .division_loop + + mov r10,[rsp] ; restore pX + mov r11,[rsp+8] ; restore sizeX + + test ecx,ecx ; test normalization factor + jz .store_results ; and + mov r15,r9 ; de-normalize + SHR_BNU_I r8,r15, r12,r13 ; divider + mov r15,r11 ; and + SHR_BNU_I r10,r15, r12,r13 ; remainder + +.store_results: + test rdi, rdi + jz .quit + mov rcx,[rsp+16] ; restore quotient length + add rcx,1 + FIX_BNU rdi, rcx, rax ; fix quotient + mov DWORD [rsi], ecx + +.quit: + FIX_BNU r10,r11, rax ; fix remainder + mov rax, r11 + REST_XMM + REST_GPR + ret +ENDFUNC cpDiv_BNU32 + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnuincm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnuincm7as.asm new file mode 100644 index 000000000..704793d14 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnuincm7as.asm @@ -0,0 +1,168 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpInc_BNU() +; cpDec_BNU() +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + + +;************************************************************* +;* Ipp64u cpInc_BNU(Ipp64u* pDst, +;* const Ipp64u* pSrc, int len, +;* Ipp64u increment) +;* returns carry +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpInc_BNU,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 4 + +; rdi = pDst +; rsi = pSrc +; rdx = len +; rcx = increment + + movsxd rdx, edx ; length + + mov r8, qword [rsi] ; r[0] = r[0]+increment + add r8, rcx + mov qword [rdi], r8 + + lea rsi, [rsi+rdx*sizeof(qword)] + lea rdi, [rdi+rdx*sizeof(qword)] + lea rcx, [rdx*sizeof(qword)] + + sbb rax, rax ; save cf + neg rcx ; rcx = negative length (bytes) + add rcx, sizeof(qword) + jrcxz .exit + add rax, rax ; restore cf + jnc .copy + +align IPP_ALIGN_FACTOR +.inc_loop: + mov r8, qword [rsi+rcx] + adc r8, 0 + mov qword [rdi+rcx], r8 + lea rcx, [rcx+sizeof(qword)] + jrcxz .exit_loop + jnc .exit_loop + jmp .inc_loop +.exit_loop: + sbb rax, rax ; save cf + +.copy: + cmp rsi, rdi + jz .exit + jrcxz .exit +.copy_loop: + mov r8, qword [rsi+rcx] + mov qword [rdi+rcx], r8 + add rcx, sizeof(qword) + jnz .copy_loop + +.exit: + neg rax + REST_XMM + REST_GPR + ret +ENDFUNC cpInc_BNU + + + +;************************************************************* +;* Ipp64u cpDec_BNU(Ipp64u* pDst, +;* const Ipp64u* pSrc, int len, +;* Ipp64u increment) +;* returns borrow +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpDec_BNU,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 4 + +; rdi = pDst +; rsi = pSrc +; rdx = len +; rcx = increment + + movsxd rdx, edx ; length + + mov r8, qword [rsi] ; r[0] = r[0]+increment + sub r8, rcx + mov qword [rdi], r8 + + lea rsi, [rsi+rdx*sizeof(qword)] + lea rdi, [rdi+rdx*sizeof(qword)] + lea rcx, [rdx*sizeof(qword)] + + sbb rax, rax ; save cf + neg rcx ; rcx = negative length (bytes) + add rcx, sizeof(qword) + jrcxz .exit + add rax, rax ; restore cf + jnc .copy + +align IPP_ALIGN_FACTOR +.inc_loop: + mov r8, qword [rsi+rcx] + sbb r8, 0 + mov qword [rdi+rcx], r8 + lea rcx, [rcx+sizeof(qword)] + jrcxz .exit_loop + jnc .exit_loop + jmp .inc_loop +.exit_loop: + sbb rax, rax ; save cf + +.copy: + cmp rsi, rdi + jz .exit + jrcxz .exit +.copy_loop: + mov r8, qword [rsi+rcx] + mov qword [rdi+rcx], r8 + add rcx, sizeof(qword) + jnz .copy_loop + +.exit: + neg rax + REST_XMM + REST_GPR + ret +ENDFUNC cpDec_BNU + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnum7.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnum7.inc new file mode 100644 index 000000000..3b25b77c0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnum7.inc @@ -0,0 +1,691 @@ +;=============================================================================== +; Copyright (C) 2013 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number macros +; +; Content: +; SWAP +; EXPAND_BNU +; +; COPY_BNU +; FIX_BNU CMP_BNU +; +; ADD_BNU SUB_BNU +; ECARRY EBORROW +; +; MUL_BNU_D32 MAC_BNU_D32 +; MUL_BNU_D64 MAC_BNU_D64 +; +; MAC MAC2 +; +; ADD_FIX_BNU SUB_FIX_BNU +; + +;; +;; Swap values or addresses +;; +%macro SWAP 4.nolist + %xdefine %%cc %1 + %xdefine %%dst %2 + %xdefine %%src %3 + %xdefine %%tmp %4 + + cmov&%%cc %%tmp,%%src + cmov&%%cc %%src,%%dst + cmov&%%cc %%dst,%%tmp +%endmacro + +;; +;; EXPAND_BNU expands BNU by zero %if one has odd size +;; +%macro EXPAND_BNU 2.nolist + %xdefine %%rBNU %1 + %xdefine %%rLen %2 + + test %%rLen,1 + jz %%expand_quit + mov DWORD [%%rBNU+%%rLen*4],0 + add %%rLen,1 +%%expand_quit: +%endmacro + +;; +;; COPY_BNU +;; +%macro COPY_BNU 5.nolist + %xdefine %%rSrc %1 + %xdefine %%rDst %2 + %xdefine %%rLen %3 + %xdefine %%rIdx %4 + %xdefine %%rTmp %5 + + xor %%rIdx,%%rIdx +%%copy_bnu: + mov %%rTmp&d,[%%rSrc+%%rIdx*4] + mov [%%rDst+%%rIdx*4],%%rTmp&d + add %%rIdx,1 + cmp %%rIdx,%%rLen + jl %%copy_bnu +%endmacro + +;; +;; FIX_BNU returns actual length of BNU +;; +;; input +;; rSrc points BNU +;; rLen initial BNU size +;; +;; output +;; rSrc points BNU +;; rLen actual BNU size +;; +%macro FIX_BNU 3.nolist + %xdefine %%rSrc %1 + %xdefine %%rLen %2 + %xdefine %%tmp %3 + +%%fix_bnu_loop: + mov %%tmp&d,[%%rSrc+%%rLen*4-4] ;; value + test %%tmp&d,%%tmp&d ;; test BNU component + jnz %%fix_bnu_quit + sub %%rLen,1 + jg %%fix_bnu_loop + add %%rLen,1 +%%fix_bnu_quit: +%endmacro + +;; +;; CMP_BNU comare BNUs +;; +;; input +;; rSrc1 points BNU1 +;; rSrc2 points BNU2 +;; rLen size of BNUs +;; +;; output +;; rCode -1/0/1 +;; +%macro CMP_BNU 4.nolist + %xdefine %%rCode %1 + %xdefine %%rSrc1 %2 + %xdefine %%rSrc2 %3 + %xdefine %%rLen %4 + +%%cmp_bnu_loop: + mov %%rCode&d,[%%rSrc1+%%rLen*4-4] ;; src1[] + cmp %%rCode&d,[%%rSrc2+%%rLen*4-4] ;; src1[] ~ src2[] + jnz %%cmp_bnu_quit ;; src1[] != src2[] + sub %%rLen,1 + jg %%cmp_bnu_loop +%%cmp_bnu_quit: + seta %%rCode&b ;; rCode = (src1[]>src2[])? 1:0 + setb %%rLen&b ;; rLen = (src1[]= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + + +;************************************************************* +; Ipp64u cpAddMulDgt_BNU(Ipp64u* pDst, +; const Ipp64u* pSrcA, +; int len, +; Ipp64u B ) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpAddMulDgt_BNU,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r11,r12 + USES_XMM + COMP_ABI 4 + +; rdi = pDst +; rsi = pSrc +; rdx = len +; rcx = B + +%xdefine B0 rcx ; b + +%xdefine T0 r8 ; temporary +%xdefine T1 r9 +%xdefine T2 r10 +%xdefine T3 r11 + +%xdefine idx rbx ; index +%xdefine rDst rdi +%xdefine rSrc rsi + + mov edx, edx ; unsigned length + + mov rax, qword [rsi] + cmp rdx, 1 + jnz .general_case + + mul rcx + add qword [rdi], rax + adc rdx, 0 + mov rax, rdx + REST_XMM + REST_GPR + ret + +.general_case: + lea rSrc, [rSrc+rdx*sizeof(qword)-sizeof(qword)*5] + lea rDst, [rDst+rdx*sizeof(qword)-sizeof(qword)*5] + mov idx, dword 5 + sub idx, rdx ; negative counter -(len-5) + + mul rcx ; {T1:T0} = a[0]*B + mov T0, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)] + mov T1, rdx + + cmp idx, 0 + jge .skip_muladd_loop4 + +align IPP_ALIGN_FACTOR +.muladd_loop4: + mul rcx ; a[4*i+1]*B + xor T2, T2 + add qword [rDst+idx*sizeof(qword)], T0 + adc T1, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*2] + adc T2, rdx + + mul rcx ; a[4*i+2]*B + xor T3, T3 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)], T1 + adc T2, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*3] + adc T3, rdx + + mul rcx ; a[4*i+3]*B + xor T0, T0 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*2], T2 + adc T3, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*4] + adc T0, rdx + + mul rcx ; a[4*i+4]*B + xor T1, T1 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*3], T3 + adc T0, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*5] + adc T1, rdx + + add idx, 4 + jnc .muladd_loop4 + +.skip_muladd_loop4: + mul rcx + xor T2, T2 + add qword [rDst+idx*sizeof(qword)], T0 + adc T1, rax + adc T2, rdx + + cmp idx, 2 + ja .fin_mul1x4n_2 ; idx=3 + jz .fin_mul1x4n_3 ; idx=2 + jp .fin_mul1x4n_4 ; idx=1 + ; .fin_mul1x4n_1 ; idx=0 + +.fin_mul1x4n_1: + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*2] + mul rcx + xor T3, T3 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)], T1 + adc T2, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*3] + adc T3, rdx + + mul rcx + xor T0, T0 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*2], T2 + adc T3, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*4] + adc T0, rdx + + mul rcx + xor T1, T1 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*3], T3 + adc T0, rax + adc rdx, 0 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*4], T0 + adc rdx, 0 + mov rax, rdx + jmp .exit + +.fin_mul1x4n_4: + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*2] + mul rcx + xor T3, T3 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)], T1 + adc T2, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*3] + adc T3, rdx + + mul rcx + xor T0, T0 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*2], T2 + adc T3, rax + adc rdx, 0 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*3], T3 + adc rdx, 0 + mov rax, rdx + jmp .exit + +.fin_mul1x4n_3: + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)*2] + mul rcx + xor T3, T3 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)], T1 + adc T2, rax + adc rdx, 0 + add qword [rDst+idx*sizeof(qword)+sizeof(qword)*2], T2 + adc rdx, 0 + mov rax, rdx + jmp .exit + +.fin_mul1x4n_2: + add qword [rDst+idx*sizeof(qword)+sizeof(qword)], T1 + adc T2, 0 + mov rax, T2 + +.exit: + REST_XMM + REST_GPR + ret +ENDFUNC cpAddMulDgt_BNU + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul.inc new file mode 100644 index 000000000..481702ff7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul.inc @@ -0,0 +1,666 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number multiplication Support +; +; + +%ifndef _PCPBNUMUL_INC_ +%assign _PCPBNUMUL_INC_ 1 + +%include "pcpbnumul_basic.inc" + +%macro CLEAR 2.nolist + %xdefine %%rPtr %1 + %xdefine %%rLen %2 + +%%L_1: + mov qword [%%rPtr], rax + add %%rPtr, sizeof(qword) + sub %%rLen, 1 + jnz %%L_1 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; (8*n)x(8*m) multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_8Nx8M,PRIVATE + push rbx ;; nsB + push rdi ;; pR + push rsi ;; pA + push rdx ;; nsA + +;;; +;;; init +;;; +.mul_loopA: + push rdx ;; nsA + call mla_8x8 + add rdi, sizeof(qword)*8 ; adv pR + add rsi, sizeof(qword)*8 ; adv pA + pop rdx ; nsA-- + sub rdx, 8 + jnz .mul_loopA + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + + jmp .mla_entry + +.mla_loopB: + push rbx ;; nsB + + push rdi ;; pR + push rsi ;; pA + push rdx ;; nsA + + xor rax, rax ; c-flag + push rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + +.loopA: + push rdx ; nsA + call mla_8x8 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + pop rdx ; nsA-- + sub rdx, 8 + jz .exit_loopA + + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15,qword [rdi+sizeof(qword)*7], rax + sbb rax, rax ; save c-flag + push rax + jmp .loopA + +.exit_loopA: + pop rax ; restore c-flag + neg rax + adc r8, 0 + mov qword [rdi+sizeof(qword)*0], r8 + adc r9, 0 + mov qword [rdi+sizeof(qword)*1], r9 + adc r10,0 + mov qword [rdi+sizeof(qword)*2],r10 + adc r11,0 + mov qword [rdi+sizeof(qword)*3],r11 + adc r12,0 + mov qword [rdi+sizeof(qword)*4],r12 + adc r13,0 + mov qword [rdi+sizeof(qword)*5],r13 + adc r14,0 + mov qword [rdi+sizeof(qword)*6],r14 + adc r15,0 + mov qword [rdi+sizeof(qword)*7],r15 + +.mla_entry: + pop rdx ; restore nsA + pop rsi ; restore pA + pop rdi + add rdi, sizeof(qword)*8 + + add rcx, sizeof(qword)*8 + pop rbx ;; nsB-- + sub rbx, 8 + jnz .mla_loopB + ret +ENDFUNC mul_8Nx8M + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; simplest general case N x M multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_simple,PRIVATE + xor rax, rax ; carry = 0 + + mov r11, rdx + cmp r11, rbx + jge .ms_mla_entry + SWAP r11, rbx + SWAP rsi, rcx + jmp .ms_mla_entry + +.ms_loopB: + push rbx ;; nsB + push rdi ;; pR + push rsi ;; pA + push r11 ;; nsA + push rax ;; save previous pass carry + + mov rdx, qword [rcx] ; pB[] + xor r10, r10 ; extension +.ms_loopA: + gsmulx r9, r8, qword [rsi] + add rdi, sizeof(qword) + add rsi, sizeof(qword) + add r8, r10 + adc r9, 0 + add r8, qword [rdi-sizeof(qword)] + adc r9, 0 + mov qword [rdi-sizeof(qword)], r8 + mov r10, r9 + sub r11, 1 + jnz .ms_loopA + + pop rax ; restore carry + shr rax, 1 + + adc r10, qword [rdi] + mov qword [rdi], r10 + adc rax, 0 ; save carry + + pop r11 ; restore nsA + pop rsi ; restore pA + pop rdi ; restore pR + pop rbx ; nsB + + add rdi, sizeof(qword) + add rcx, sizeof(qword) + +.ms_mla_entry: + sub rbx, 1 + jnc .ms_loopB + ret +ENDFUNC mla_simple + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case N x M multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_NxM,PRIVATE +; +; stack struct +; +%assign nsB_cnt 0 ; rest of B operand +%assign ptrR nsB_cnt+sizeof(qword) ; current product pointer +%assign ptrA ptrR+sizeof(qword) ; ponter to A operand (pA) +%assign nsA ptrA+sizeof(qword) ; length of A operand (nsA) +%assign nsA_cnt nsA+sizeof(qword) ; rest of A operand +%assign carry nsA_cnt+sizeof(qword) ; carry +%assign tailproc carry+sizeof(qword) ; mla_8xn procedure +%assign stack_mem tailproc+sizeof(qword) ; size of stack allocation + + sub rsp, stack_mem ; allocate stack + + cmp rbx, 8 + jge .regular_entry + cmp rdx, 8 + jge .irregular_entry + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; degradated case +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; clear product + mov r8, rdx + add r8, rbx + mov rbp, rdi + xor rax, rax + CLEAR rbp, r8 + + call mla_simple + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; irregular init +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.irregular_entry: + mov [rsp+nsB_cnt], rbx + mov [rsp+nsA], rdx + mov [rsp+nsA_cnt], rdx + + GET_EP rax, mla_8xl_tail, rbx, rbp ; tail procedure (mla_8xn) address + mov [rsp+tailproc], rax + + jmp .irr_init_entry + +.irr_init_loop: + mov [rsp+nsA_cnt], rdx ; save A counter + call rax + + mov rbx, [rsp+nsB_cnt] + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0], r8 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1], r9 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2], r10 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3], r11 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4], r12 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5], r13 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6], r14 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*7], r15 + + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + + xor r8, r8 + xor r9, r9 + xor r10,r10 + xor r11,r11 + xor r12,r12 + xor r13,r13 + xor r14,r14 + xor r15,r15 + + ; load data depending on nsB length + mov r8, qword [rdi] + cmp rbx, 1 + jz .continue + mov r9, qword [rdi+sizeof(qword)] + cmp rbx, 2 + jz .continue + mov r10, qword [rdi+sizeof(qword)*2] + cmp rbx, 3 + jz .continue + mov r11, qword [rdi+sizeof(qword)*3] + cmp rbx, 4 + jz .continue + mov r12, qword [rdi+sizeof(qword)*4] + cmp rbx, 5 + jz .continue + mov r13, qword [rdi+sizeof(qword)*5] + cmp rbx, 6 + jz .continue + mov r14, qword [rdi+sizeof(qword)*6] +.continue: + mov rdx, [rsp+nsA_cnt] ; nsA + +.irr_init_entry: + sub rdx, 8 + mov rax, [rsp+tailproc] + jnc .irr_init_loop + + add rdx, 8 + jz .quit + + ; clear uninitialized rest of product + lea rbp, [rdi+rbx*sizeof(qword)] + xor rax, rax + CLEAR rbp, rdx + + mov rdx, [rsp+nsA_cnt] + call mla_simple + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; regular ep +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.regular_entry: + sub rbx, 8 + xor rax, rax + mov [rsp+nsB_cnt], rbx + mov [rsp+ptrR], rdi + mov [rsp+ptrA], rsi + mov [rsp+nsA], rdx + mov [rsp+nsA_cnt], rdx + mov [rsp+carry], rax + + mov rbp, rdx ; n = nsA %8 + and rbp, 7 + GET_EP rax, mla_8xl_tail, rbp ; tail procedure (mla_8xn) address + mov [rsp+tailproc], rax + +;; +;; regular init +;; + sub rdx, 8 ;; nsA counter +.init_loopA: + mov [rsp+nsA_cnt], rdx ; nsA + call mla_8x8 + mov rdx, [rsp+nsA_cnt] + add rdi, sizeof(qword)*8 ; adv ptrR + add rsi, sizeof(qword)*8 ; adv ptrA + sub rdx, 8 ; nsA -= 8 + jnc .init_loopA + + add rdx, 8 + jz .init_complete + + mov [rsp+nsA_cnt], rdx + + mov rax, [rsp+tailproc] + SWAP rcx, rsi + call rax + SWAP rcx, rsi + + mov rdx, [rsp+nsA_cnt] + lea rdi, [rdi+rdx*sizeof(qword)] + +.init_complete: + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + + jmp .mla_entry + +;; +;; regular mla passes +;; +.mla_loopB: + mov [rsp+nsB_cnt], rbx ; update B conter + mov [rsp+ptrR], rdi ; update current product pointer + + xor rax, rax ; init carry + mov [rsp+carry], rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + sub rdx, 8 +.loopA: + mov [rsp+nsA_cnt], rdx ; save A counter + call mla_8x8 + mov rdx, [rsp+nsA_cnt] ; A counter + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + sub rdx, 8 ; nsA -= 8 + jc .exit_loopA + + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rbx + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rbx + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*2], rbx + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*3], rbx + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*4], rbx + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*5], rbx + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*6], rbx + op_reg_mem adc, r15,qword [rdi+sizeof(qword)*7], rbx + adc rax, 0 ; save carry + mov [rsp+carry], rax + jmp .loopA + +.exit_loopA: + add rdx, 8 + jz .complete_reg_loopB + + mov [rsp+nsA_cnt], rdx + + ; put zeros + xor rax, rax +.put_zero: + mov qword [rdi+rdx*sizeof(qword)], rax + add rdx,1 + cmp rdx, 8 + jl .put_zero + + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*4], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*5], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*6], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*7], rbx + adc rax, 0 ; save carry + mov [rsp+carry], rax + + mov rax, [rsp+tailproc] + SWAP rcx, rsi + call rax + SWAP rcx, rsi + + mov rdx, [rsp+nsA_cnt] ; restore nsA + lea rdi, [rdi+rdx*sizeof(qword)] + + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + + dec rdx + jz .mt_1 + dec rdx + jz .mt_2 + dec rdx + jz .mt_3 + dec rdx + jz .mt_4 + dec rdx + jz .mt_5 + dec rdx + jz .mt_6 +.mt_7: adc r9, 0 +.mt_6: adc r10,0 +.mt_5: adc r11,0 +.mt_4: adc r12,0 +.mt_3: adc r13,0 +.mt_2: adc r14,0 +.mt_1: adc r15,0 + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + jmp .mla_entry + +.complete_reg_loopB: + mov rax, [rsp+carry] ; restore carry + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + adc r15,0 + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + +.mla_entry: + ; restore: + mov rbx, [rsp+nsB_cnt] ; - B counter + mov rdi, [rsp+ptrR] ; - ptrR + mov rdx, [rsp+nsA] ; - nsA + mov rsi, [rsp+ptrA] ; - pA + + add rcx, sizeof(qword)*8 ; adv pB + add rdi, sizeof(qword)*8 ; adv ptrR + sub rbx, 8 ; nsB -= 8 + jnc .mla_loopB + + add rbx, 8 + jz .quit + +;; +;; final mla pass +;; + mov [rsp+nsB_cnt], rbx + + GET_EP rax, mla_8xl_tail, rbx, rbp ; tail procedure (mla_8xn) address + mov [rsp+tailproc], rax + + ; clear uninitialized rest of product + lea rbp, [rdi+rdx*sizeof(qword)] + xor rax, rax + CLEAR rbp, rbx + + xor rax, rax ; init carry + mov [rsp+carry], rax + + sub rdx, 8 +.tail_loopA: + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov [rsp+nsA_cnt], rdx ; save A counter + mov rax, [rsp+tailproc] + call rax + +.entry_tail_loopA: + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + adc r8, 0 + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + adc rax, 0 + + mov rbx, [rsp+nsB_cnt] ; nsB + mov rbp, rbx + dec rbp + jz .tt_1 + dec rbp + jz .tt_2 + dec rbp + jz .tt_3 + dec rbp + jz .tt_4 + dec rbp + jz .tt_5 + dec rbp + jz .tt_6 +.tt_7: op_reg_mem adc, r9, [rdi+rbx*sizeof(qword)+sizeof(qword)*1], rbp +.tt_6: op_reg_mem adc, r10,[rdi+rbx*sizeof(qword)+sizeof(qword)*2], rbp +.tt_5: op_reg_mem adc, r11,[rdi+rbx*sizeof(qword)+sizeof(qword)*3], rbp +.tt_4: op_reg_mem adc, r12,[rdi+rbx*sizeof(qword)+sizeof(qword)*4], rbp +.tt_3: op_reg_mem adc, r13,[rdi+rbx*sizeof(qword)+sizeof(qword)*5], rbp +.tt_2: op_reg_mem adc, r14,[rdi+rbx*sizeof(qword)+sizeof(qword)*6], rbp +.tt_1: op_reg_mem adc, r15,[rdi+rbx*sizeof(qword)+sizeof(qword)*7], rbp + adc rax, 0 + mov [rsp+carry], rax ; update carry + + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0], r8 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1], r9 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2], r10 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3], r11 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4], r12 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5], r13 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6], r14 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*7], r15 + + mov rdx, [rsp+nsA_cnt] ; A counter + add rsi, sizeof(qword)*8 ; adv pA + add rdi, sizeof(qword)*8 ; adv pR + sub rdx, 8 ; nsA -= 8 + jnc .tail_loopA + + add rdx, 8 + jz .quit + + ; carry propagation + mov rax, [rsp+carry] + mov rbp, rbx + + dec rbp + mov r8, qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0] + add r8, rax + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0], r8 + jz .simple + dec rbp + mov r9, qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1] + adc r9, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1], r9 + jz .simple + dec rbp + mov r10,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2] + adc r10, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2], r10 + jz .simple + dec rbp + mov r11,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3] + adc r11, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3], r11 + jz .simple + dec rbp + mov r12,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4] + adc r12, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4], r12 + jz .simple + dec rbp + mov r13,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5] + adc r13, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5], r13 + jz .simple + dec rbp + mov r14,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6] + adc r14, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6], r14 + +.simple: + call mla_simple + + +.quit: + add rsp, stack_mem ; release stack + ret +ENDFUNC mul_NxM + + +%endif ;; _PCPBNUMUL_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul_basic.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul_basic.inc new file mode 100644 index 000000000..71f9b4179 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul_basic.inc @@ -0,0 +1,947 @@ +;=============================================================================== +; Copyright (C) 2013 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number multiplication Support +; +; + +%ifndef _PCPBNUMUL_BASIC_INC_ +%assign _PCPBNUMUL_BASIC_INC_ 1 + +%include "pcpmulx.inc" +%include "pcpbnumul_fix.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; short size (1-8 qwords) operand mla and mul operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; 1x1 multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_1x1,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 1, rdi, rsi, rbx,rbp, r8 + ret +ENDFUNC mla_1x1 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_1x1,PRIVATE + mov rdx,qword [rcx] + gsmulx rdx, rax, qword [rsi] + mov qword [rdi], rax + mov qword [rdi+sizeof(qword)], rdx + ret +ENDFUNC mul_1x1 + + +;; +;; 2x2 multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_2x2,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 2, rdi, rsi, rbx,rbp, r8,r9 + mov rdx, qword [rcx+sizeof(qword)] + MLA_FIX 2, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9 + ret +ENDFUNC mla_2x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_2x2,PRIVATE + call mla_2x2 + mov qword [rdi+sizeof(qword)*2], r8 + mov qword [rdi+sizeof(qword)*3], r9 + ret +ENDFUNC mul_2x2 + + + +;; +;; 3x3 multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_3x3,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 3, rdi, rsi, rbx,rbp, r8,r9,r10 + mov rdx, qword [rcx+sizeof(qword)] + MLA_FIX 3, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10 + mov rdx, qword [rcx+sizeof(qword)*2] + MLA_FIX 3, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10 + ret +ENDFUNC mla_3x3 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_3x3,PRIVATE + call mla_3x3 + mov qword [rdi+sizeof(qword)*3], r8 + mov qword [rdi+sizeof(qword)*4], r9 + mov qword [rdi+sizeof(qword)*5], r10 + ret +ENDFUNC mul_3x3 + + + +;; +;; 4x{2,4} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_4x2,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 4, rdi, rsi, rbx,rbp, r8,r9,r10,r11 + mov rdx, qword [rcx+sizeof(qword)] + MLA_FIX 4, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10,r11 + ret +ENDFUNC mla_4x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_4x4,PRIVATE + call mla_4x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_4x2 + sub rdi, sizeof(qword)*2 + sub rcx, sizeof(qword)*2 + ret +ENDFUNC mla_4x4 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_4x4,PRIVATE + call mla_4x4 + mov qword [rdi+sizeof(qword)*4], r8 + mov qword [rdi+sizeof(qword)*5], r9 + mov qword [rdi+sizeof(qword)*6], r10 + mov qword [rdi+sizeof(qword)*7], r11 + ret +ENDFUNC mul_4x4 + + + +;; +;; 5x{2,5} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_5x2,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 5, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 5, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10,r11,r12 + ret +ENDFUNC mla_5x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_5x5,PRIVATE + mov rdx, [rcx] + MLA_FIX 5, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12 + + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_5x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_5x2 + + sub rdi, sizeof(qword)*3 + sub rcx, sizeof(qword)*3 + ret +ENDFUNC mla_5x5 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_5x5,PRIVATE + call mla_5x5 + mov qword [rdi+sizeof(qword)*5], r8 + mov qword [rdi+sizeof(qword)*6], r9 + mov qword [rdi+sizeof(qword)*7], r10 + mov qword [rdi+sizeof(qword)*8], r11 + mov qword [rdi+sizeof(qword)*9], r12 + ret +ENDFUNC mul_5x5 + + + +;; +;; 6x{2,6} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_6x2,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 6, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 6, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + ret +ENDFUNC mla_6x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_6x6,PRIVATE + call mla_6x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_6x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_6x2 + + sub rdi, sizeof(qword)*4 + sub rcx, sizeof(qword)*4 + ret +ENDFUNC mla_6x6 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_6x6,PRIVATE + call mla_6x6 + mov qword [rdi+sizeof(qword)*6], r8 + mov qword [rdi+sizeof(qword)*7], r9 + mov qword [rdi+sizeof(qword)*8], r10 + mov qword [rdi+sizeof(qword)*9], r11 + mov qword [rdi+sizeof(qword)*10],r12 + mov qword [rdi+sizeof(qword)*11],r13 + ret +ENDFUNC mul_6x6 + + + +;; +;; 7x{2,7} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_7x2,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 7, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 7, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + ret +ENDFUNC mla_7x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_7x7,PRIVATE + mov rdx, [rcx] + MLA_FIX 7, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_7x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_7x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_7x2 + + sub rdi, sizeof(qword)*5 + sub rcx, sizeof(qword)*5 + ret +ENDFUNC mla_7x7 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_7x7,PRIVATE + call mla_7x7 + mov qword [rdi+sizeof(qword)*7], r8 + mov qword [rdi+sizeof(qword)*8], r9 + mov qword [rdi+sizeof(qword)*9], r10 + mov qword [rdi+sizeof(qword)*10],r11 + mov qword [rdi+sizeof(qword)*11],r12 + mov qword [rdi+sizeof(qword)*12],r13 + mov qword [rdi+sizeof(qword)*13],r14 + ret +ENDFUNC mul_7x7 + + + +;; +;; 8x{1,2,3,4,5,6,7,8} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x1,PRIVATE + mov rdx, [rcx] + MLA_FIX 8, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x1 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x2,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x3,PRIVATE + call mla_8x1 + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_8x2 + sub rdi, sizeof(qword) + sub rcx, sizeof(qword) + ret +ENDFUNC mla_8x3 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x4,PRIVATE + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*2 + sub rcx, sizeof(qword)*2 + ret +ENDFUNC mla_8x4 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x5,PRIVATE + call mla_8x1 + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_8x4 + sub rdi, sizeof(qword) + sub rcx, sizeof(qword) + ret +ENDFUNC mla_8x5 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x6,PRIVATE + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x4 + sub rdi, sizeof(qword)*2 + sub rcx, sizeof(qword)*2 + ret +ENDFUNC mla_8x6 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x7,PRIVATE + call mla_8x1 + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_8x6 + sub rdi, sizeof(qword) + sub rcx, sizeof(qword) + ret +ENDFUNC mla_8x7 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x8,PRIVATE + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + sub rdi, sizeof(qword)*6 + sub rcx, sizeof(qword)*6 + ret +ENDFUNC mla_8x8 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_8x8,PRIVATE + call mla_8x8 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],r15 + ret +ENDFUNC mul_8x8 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; middle size (9-16 qwords) operand mla and mul operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_9x9,PRIVATE + call mla_8x8 + + mov rdx, [rcx+sizeof(qword)*8] + MLA_FIX 8, {rdi+sizeof(qword)*8}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + push r15 + + mov rdx, [rsi+sizeof(qword)*8] + mov r15, [rdi+sizeof(qword)*8] + MLA_FIX 8, {rdi+sizeof(qword)*8}, rcx, rbx,rbp, r15,r8,r9,r10,r11,r12,r13,r14 + mov qword [rdi+sizeof(qword)*9], r15 + + gsmulx r15, rbp, [rcx+sizeof(qword)*8] + pop rax + add r14, rax + adc r15,0 + add r14, rbp + adc r15, 0 + + mov qword [rdi+sizeof(qword)*10],r8 + mov qword [rdi+sizeof(qword)*11],r9 + mov qword [rdi+sizeof(qword)*12],r10 + mov qword [rdi+sizeof(qword)*13],r11 + mov qword [rdi+sizeof(qword)*14],r12 + mov qword [rdi+sizeof(qword)*15],r13 + mov qword [rdi+sizeof(qword)*16],r14 + mov qword [rdi+sizeof(qword)*17],r15 + ret +ENDFUNC mul_9x9 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_10x10,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x2 + push r15 + push r14 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r13 + mov r14, r12 + mov r13, r11 + mov r12, r10 + mov r11, r9 + mov r10, r8 + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x2 + + mov qword [rdi+sizeof(qword)*2],r8 + mov qword [rdi+sizeof(qword)*3],r9 + mov qword [rdi+sizeof(qword)*4],r10 + mov qword [rdi+sizeof(qword)*5],r11 + mov qword [rdi+sizeof(qword)*6],r12 + mov qword [rdi+sizeof(qword)*7],r13 + add rdi, sizeof(qword)*8 + + xor r10, r10 + pop r8 + pop r9 + add r8, r14 + adc r9, r15 + adc r10,0 + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_2x2 + add rdi, sizeof(qword)*2 + + add r8, r10 + adc r9, 0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + ret +ENDFUNC mul_10x10 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_11x11,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x3 + push r15 + push r14 + push r13 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r12 + mov r14, r11 + mov r13, r10 + mov r12, r9 + mov r11, r8 + mov r10,qword [rdi+sizeof(qword)*2] + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x3 + + mov qword [rdi+sizeof(qword)*3],r8 + mov qword [rdi+sizeof(qword)*4],r9 + mov qword [rdi+sizeof(qword)*5],r10 + mov qword [rdi+sizeof(qword)*6],r11 + mov qword [rdi+sizeof(qword)*7],r12 + add rdi, sizeof(qword)*8 + + xor r11, r11 + pop r8 + pop r9 + pop r10 + add r8, r13 + adc r9, r14 + adc r10,r15 + adc r11,0 + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_3x3 + add rdi, sizeof(qword)*3 + + add r8, r11 + adc r9, 0 + adc r10,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + ret +ENDFUNC mul_11x11 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_12x12,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x4 + push r15 + push r14 + push r13 + push r12 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r11 + mov r14, r10 + mov r13, r9 + mov r12, r8 + mov r11,qword [rdi+sizeof(qword)*3] + mov r10,qword [rdi+sizeof(qword)*2] + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x4 + + mov qword [rdi+sizeof(qword)*4],r8 + mov qword [rdi+sizeof(qword)*5],r9 + mov qword [rdi+sizeof(qword)*6],r10 + mov qword [rdi+sizeof(qword)*7],r11 + add rdi, sizeof(qword)*8 + + xor rax, rax + pop r8 + pop r9 + pop r10 + pop r11 + add r8, r12 + adc r9, r13 + adc r10,r14 + adc r11,r15 + adc rax,0 + push rax + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_4x4 + add rdi, sizeof(qword)*4 + + pop rax + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + ret +ENDFUNC mul_12x12 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_13x13,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x5 + push r15 + push r14 + push r13 + push r12 + push r11 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r10 + mov r14, r9 + mov r13, r8 + mov r12,qword [rdi+sizeof(qword)*4] + mov r11,qword [rdi+sizeof(qword)*3] + mov r10,qword [rdi+sizeof(qword)*2] + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x5 + + mov qword [rdi+sizeof(qword)*5], r8 + mov qword [rdi+sizeof(qword)*6], r9 + mov qword [rdi+sizeof(qword)*7], r10 + add rdi, sizeof(qword)*8 + + xor rax, rax + pop r8 + pop r9 + pop r10 + pop rbx + pop rbp + add r8, r11 + adc r9, r12 + adc r10,r13 + adc rbx,r14 + adc rbp,r15 + adc rax,0 + push rax + + mov r11, rbx + mov r12, rbp + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_5x5 + add rdi, sizeof(qword)*5 + + pop rax + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + ret +ENDFUNC mul_13x13 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_14x14,PRIVATE + call mla_7x7 + + add rdi, sizeof(qword)*7 + add rsi, sizeof(qword)*7 + call mla_7x7 + mov qword [rdi+sizeof(qword)*7], r8 + mov qword [rdi+sizeof(qword)*8], r9 + mov qword [rdi+sizeof(qword)*9], r10 + mov qword [rdi+sizeof(qword)*10],r11 + mov qword [rdi+sizeof(qword)*11],r12 + mov qword [rdi+sizeof(qword)*12],r13 + mov qword [rdi+sizeof(qword)*13],r14 + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + + add rcx, sizeof(qword)*7 + sub rsi, sizeof(qword)*7 + call mla_7x7 + + xor rdx, rdx + op_reg_mem add, r8, qword [rdi+sizeof(qword)*7], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*8], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*9], rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*10],rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*11],rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*12],rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*13],rax + adc rdx, 0 + push rdx + + add rdi, sizeof(qword)*7 + add rsi, sizeof(qword)*7 + call mla_7x7 + + sub rdi, sizeof(qword)*14 + sub rsi, sizeof(qword)*7 + sub rcx, sizeof(qword)*7 + + pop rdx + add r8, rdx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + + mov qword [rdi+sizeof(qword)*21],r8 + mov qword [rdi+sizeof(qword)*22],r9 + mov qword [rdi+sizeof(qword)*23],r10 + mov qword [rdi+sizeof(qword)*24],r11 + mov qword [rdi+sizeof(qword)*25],r12 + mov qword [rdi+sizeof(qword)*26],r13 + mov qword [rdi+sizeof(qword)*27],r14 + ret +ENDFUNC mul_14x14 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_15x15,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x7 + mov qword [rdi+sizeof(qword)*7], r8 + mov qword [rdi+sizeof(qword)*8], r9 + mov qword [rdi+sizeof(qword)*9], r10 + mov qword [rdi+sizeof(qword)*10],r11 + mov qword [rdi+sizeof(qword)*11],r12 + mov qword [rdi+sizeof(qword)*12],r13 + mov qword [rdi+sizeof(qword)*13],r14 + mov qword [rdi+sizeof(qword)*14],r15 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + call mla_8x7 + + mov qword [rdi+sizeof(qword)*7], r8 + add rdi, sizeof(qword)*8 + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + + mov r8, r9 + mov r9, r10 + mov r10,r11 + mov r11,r12 + mov r12,r13 + mov r13,r14 + mov r14,r15 + xor rdx, rdx + op_reg_mem add, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*6], rax + adc rdx, 0 + push rdx + + call mla_7x7 + add rdi, sizeof(qword)*7 + + pop rax + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + ret +ENDFUNC mul_15x15 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_16x16,PRIVATE + call mla_8x8 + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + call mla_8x8 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],r15 + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + add rcx, sizeof(qword)*8 + sub rsi, sizeof(qword)*8 + call mla_8x8 + + xor rdx, rdx + op_reg_mem add, r8, qword [rdi+sizeof(qword)*8], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*9], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*10],rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*11],rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*12],rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*13],rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*14],rax + op_reg_mem adc, r15,qword [rdi+sizeof(qword)*15],rax + adc rdx, 0 + push rdx + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + call mla_8x8 + + sub rdi, sizeof(qword)*16 + sub rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + + pop rdx + add r8, rdx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + + mov qword [rdi+sizeof(qword)*24],r8 + mov qword [rdi+sizeof(qword)*25],r9 + mov qword [rdi+sizeof(qword)*26],r10 + mov qword [rdi+sizeof(qword)*27],r11 + mov qword [rdi+sizeof(qword)*28],r12 + mov qword [rdi+sizeof(qword)*29],r13 + mov qword [rdi+sizeof(qword)*30],r14 + mov qword [rdi+sizeof(qword)*31],r15 + ret +ENDFUNC mul_16x16 + + +mul_lxl_basic DQ mul_1x1 - mul_lxl_basic + DQ mul_2x2 - mul_lxl_basic + DQ mul_3x3 - mul_lxl_basic + DQ mul_4x4 - mul_lxl_basic + DQ mul_5x5 - mul_lxl_basic + DQ mul_6x6 - mul_lxl_basic + DQ mul_7x7 - mul_lxl_basic + DQ mul_8x8 - mul_lxl_basic + DQ mul_9x9 - mul_lxl_basic + DQ mul_10x10-mul_lxl_basic + DQ mul_11x11-mul_lxl_basic + DQ mul_12x12-mul_lxl_basic + DQ mul_13x13-mul_lxl_basic + DQ mul_14x14-mul_lxl_basic + DQ mul_15x15-mul_lxl_basic + DQ mul_16x16-mul_lxl_basic + +mla_lxl_short DQ mla_1x1 - mla_lxl_short + DQ mla_2x2 - mla_lxl_short + DQ mla_3x3 - mla_lxl_short + DQ mla_4x4 - mla_lxl_short + DQ mla_5x5 - mla_lxl_short + DQ mla_6x6 - mla_lxl_short + DQ mla_7x7 - mla_lxl_short + +mla_8xl_tail DQ mla_8x1 - mla_8xl_tail + DQ mla_8x2 - mla_8xl_tail + DQ mla_8x3 - mla_8xl_tail + DQ mla_8x4 - mla_8xl_tail + DQ mla_8x5 - mla_8xl_tail + DQ mla_8x6 - mla_8xl_tail + DQ mla_8x7 - mla_8xl_tail + +%endif ;; _PCPBNUMUL_BASIC_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul_fix.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul_fix.inc new file mode 100644 index 000000000..3093f2ee7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumul_fix.inc @@ -0,0 +1,406 @@ +;=============================================================================== +; Copyright (C) 2013 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number multiplication Support +; +; + +%ifndef _PCPBNUMUL_FIX_ADCX_INC_ +%assign _PCPBNUMUL_FIX_ADCX_INC_ 1 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; macro used to replace op reg, mem instructions +%macro SWAP 2.nolist + %xdefine %%r1 %1 + %xdefine %%r2 %2 + + xor %%r1, %%r2 + xor %%r2, %%r1 + xor %%r1, %%r2 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; macro used extract proc ep from the table +%macro GET_EP 3-4.nolist + %xdefine %%regEp %1 + %xdefine %%Table %2 + %xdefine %%regIdx %3 + %xdefine %%tmp %4 + + lea %%regEp, [rel %%Table] + %ifnempty %%tmp + mov %%tmp, [%%regEp+%%regIdx*sizeof(qword)-sizeof(qword)] + add %%regEp, %%tmp + %else + mov %%regIdx, [%%regEp+%%regIdx*sizeof(qword)-sizeof(qword)] + add %%regEp, %%regIdx + %endif +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; op DST, mem_src +%macro op_reg_mem 4.nolist + %xdefine %%opCode %1 + %xdefine %%dst %2 + %xdefine %%mem_src %3 + %xdefine %%tmp %4 + + mov %%tmp, %%mem_src + %%opCode %%dst, %%tmp +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEM_DST = (op src1, mem_src2) +%macro op_mem_reg_mem 5.nolist + %xdefine %%opCode %1 + %xdefine %%mem_dst %2 + %xdefine %%src1 %3 + %xdefine %%mem_src2 %4 + %xdefine %%tmp %5 + + op_reg_mem %%opCode, %%src1, %%mem_src2, %%tmp + mov %%mem_dst, %%src1 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEM_DST = op mem_src1, mem_src2 +%macro op_mem_mem 5.nolist + %xdefine %%opCode %1 + %xdefine %%mem_dst %2 + %xdefine %%mem_src1 %3 + %xdefine %%mem_src2 %4 + %xdefine %%tmp %5 + + mov %%tmp, %%mem_src1 + %%opCode %%tmp, %%mem_src2 + mov %%mem_dst, %%tmp +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Inputs: pDst: Destination (upto 1024 bits, 16 qwords) +;;; pA: Multiplicand (upto 512 bits, 8 qwords) +;;; +;;; +;;; Uses registers: +;;; rdx - implicit multiplicand +;;; (HIP:LOP)- 64x64-bit product (mulx) +;;; X7,,X0 - high result +;;; +%macro MUL_FIX 12-13.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pA %3 + %xdefine %%HIP %4 + %xdefine %%LOP %5 + %xdefine %%X0 %6 + %xdefine %%X1 %7 + %xdefine %%X2 %8 + %xdefine %%X3 %9 + %xdefine %%X4 %10 + %xdefine %%X5 %11 + %xdefine %%X6 %12 + %xdefine %%X7 %13 + + gsmulx %%X0, %%LOP, [%%pA] ; (X0:LO) = a[0]*b + %ifnempty %%pDst + mov [%%pDst], %%LOP + %endif + + %if %%N > 1 + gsmulx %%X1, %%HIP, [%%pA+sizeof(qword)] ; (X1:LO) = a[1]*b + add %%X0, %%HIP + %if %%N == 2 + adc %%X1, 0 + %endif + + %if %%N > 2 + gsmulx %%X2, %%LOP, [%%pA+sizeof(qword)*2] ; (X2:LO) = a[2]*b + adc %%X1, %%LOP + %if %%N == 3 + adc %%X2, 0 + %endif + + %if %%N > 3 + gsmulx %%X3, %%HIP, [%%pA+sizeof(qword)*3] ; (X3:LO) = a[3]*b + adc %%X2, %%HIP + %if %%N == 4 + adc %%X3, 0 + %endif + + %if %%N > 4 + gsmulx %%X4, %%LOP, [%%pA+sizeof(qword)*4] ; (X4:LO) = a[4]*b + adc %%X3, %%LOP + %if %%N == 5 + adc %%X4, 0 + %endif + + %if %%N > 5 + gsmulx %%X5, %%HIP, [%%pA+sizeof(qword)*5] ; (X5:LO) = a[5]*b + adc %%X4, %%HIP + %if %%N == 6 + adc %%X5, 0 + %endif + + %if %%N > 6 + gsmulx %%X6, %%LOP, [%%pA+sizeof(qword)*6] ; (X6:LO) = a[6]*b + adc %%X5, %%LOP + %if %%N == 7 + adc %%X6, 0 + %endif + + %if %%N > 7 + gsmulx %%X7, %%HIP, [%%pA+sizeof(qword)*7] ; (X7:LO) = a[7]*b + adc %%X6, %%HIP + adc %%X7, 0 + %endif + %endif + %endif + %endif + %endif + %endif + %endif +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; {x7,x6,x5,x4,x3,x2,x1,x0},DCT[0] = {x7,x6,x5,x4,x3,x2,x1,x0} + A[7:0]*B[i] +;; +;; uses rax, rdx +;; rdx - implicit multiplicand B[i] (should to be preloaded) +;; rax - temporary product +;; (HIP:LOP)- 64x64-bit product (mulx) +;; X7,,X0 - high result +;; +%macro MLA_FIX 6-13.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pA %3 + %xdefine %%HIP %4 + %xdefine %%LOP %5 + %xdefine %%X0 %6 + %xdefine %%X1 %7 + %xdefine %%X2 %8 + %xdefine %%X3 %9 + %xdefine %%X4 %10 + %xdefine %%X5 %11 + %xdefine %%X6 %12 + %xdefine %%X7 %13 + + gsmulx %%HIP, rax, [%%pA] ; (HI:rax) = a[0]*b[i] + add rax, %%X0 + adc %%HIP, 0 + %ifnempty %%pDst + mov [%%pDst], rax + %endif + %if %%N == 1 + mov %%X0, %%HIP + %endif + + %if %%N > 1 + gsmulx %%LOP,%%X0, [%%pA+sizeof(qword)] ; (LO:X0) = a[1]*b[i] + add %%X0, %%X1 + adc %%LOP, 0 + add %%X0, %%HIP + adc %%LOP, 0 + %if %%N == 2 + mov %%X1, %%LOP + %endif + + %if %%N > 2 + gsmulx %%HIP,%%X1, [%%pA+sizeof(qword)*2] ; (HI:X1) = a[2]*b[i] + add %%X1, %%X2 + adc %%HIP, 0 + add %%X1, %%LOP + adc %%HIP, 0 + %if %%N == 3 + mov %%X2, %%HIP + %endif + + %if %%N > 3 + gsmulx %%LOP,%%X2, [%%pA+sizeof(qword)*3] ; (LO,X2) = a[3]*b[i] + add %%X2, %%X3 + adc %%LOP, 0 + add %%X2, %%HIP + adc %%LOP, 0 + %if %%N == 4 + mov %%X3, %%LOP + %endif + + %if %%N > 4 + gsmulx %%HIP,%%X3, [%%pA+sizeof(qword)*4] ; (HI:X3) = a[4]*b[i] + add %%X3, %%X4 + adc %%HIP, 0 + add %%X3, %%LOP + adc %%HIP, 0 + %if %%N == 5 + mov %%X4, %%HIP + %endif + + %if %%N > 5 + gsmulx %%LOP,%%X4, [%%pA+sizeof(qword)*5] ; (LO:X4) = a[5]*b[i] + add %%X4, %%X5 + adc %%LOP, 0 + add %%X4, %%HIP + adc %%LOP, 0 + %if %%N == 6 + mov %%X5, %%LOP + %endif + + %if %%N > 6 + gsmulx %%HIP,%%X5, [%%pA+sizeof(qword)*6] ; (HI:X5) = a[6]*b[i] + add %%X5, %%X6 + adc %%HIP, 0 + add %%X5, %%LOP + adc %%HIP, 0 + %if %%N == 7 + mov %%X6, %%HIP + %endif + + %if %%N > 7 + gsmulx %%LOP, %%X6, [%%pA+sizeof(qword)*7] ; (LO:X6) = a[7]*b[i] + add %%X6, %%X7 + adc %%LOP, 0 + add %%X6, %%HIP + adc %%LOP, 0 + mov %%X7, %%LOP + %endif + %endif + %endif + %endif + %endif + %endif + %endif +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Inputs: pDst: Destination (upto 1024 bits, 16 qwords) +;;; pA: Multiplicand (upto 512 bits, 8 qwords) +;;; pB: Multiplicand (upto 512 bits, 8 qwords) +;;; +;;; +;;; Uses registers: +;;; rdx - implicit multiplicand +;;; (HIP:LOP)- 64x64-bit product (mulx) +;;; X0,,X7 - high result +;;; +%macro MUL_NxN 7-14.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pA %3 + %xdefine %%pB %4 + %xdefine %%HIP %5 + %xdefine %%LOP %6 + %xdefine %%X0 %7 + %xdefine %%X1 %8 + %xdefine %%X2 %9 + %xdefine %%X3 %10 + %xdefine %%X4 %11 + %xdefine %%X5 %12 + %xdefine %%X6 %13 + %xdefine %%X7 %14 + + mov rdx, [%%pB] + MUL_FIX {%%N},%%pDst,{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + + %if %%N > 1 + mov rdx, [%%pB+sizeof(qword)*1] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*1},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 2 + mov rdx, [%%pB+sizeof(qword)*2] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*2},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 3 + mov rdx, [%%pB+sizeof(qword)*3] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*3},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 4 + mov rdx, [%%pB+sizeof(qword)*4] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*4},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 5 + mov rdx, [%%pB+sizeof(qword)*5] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*5},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 6 + mov rdx, [%%pB+sizeof(qword)*6] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*6},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 7 + mov rdx, [%%pB+sizeof(qword)*7] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*7},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 7 + mov qword [%%pDst+sizeof(qword)*8], %%X0 + mov qword [%%pDst+sizeof(qword)*9], %%X1 + mov qword [%%pDst+sizeof(qword)*10], %%X2 + mov qword [%%pDst+sizeof(qword)*11], %%X3 + mov qword [%%pDst+sizeof(qword)*12], %%X4 + mov qword [%%pDst+sizeof(qword)*13], %%X5 + mov qword [%%pDst+sizeof(qword)*14], %%X6 + mov qword [%%pDst+sizeof(qword)*15], %%X7 + %elif %%N > 6 + mov qword [%%pDst+sizeof(qword)*7], %%X0 + mov qword [%%pDst+sizeof(qword)*8], %%X1 + mov qword [%%pDst+sizeof(qword)*9], %%X2 + mov qword [%%pDst+sizeof(qword)*10], %%X3 + mov qword [%%pDst+sizeof(qword)*11], %%X4 + mov qword [%%pDst+sizeof(qword)*12], %%X5 + mov qword [%%pDst+sizeof(qword)*13], %%X6 + %elif %%N > 5 + mov qword [%%pDst+sizeof(qword)*6], %%X0 + mov qword [%%pDst+sizeof(qword)*7], %%X1 + mov qword [%%pDst+sizeof(qword)*8], %%X2 + mov qword [%%pDst+sizeof(qword)*9], %%X3 + mov qword [%%pDst+sizeof(qword)*10], %%X4 + mov qword [%%pDst+sizeof(qword)*11], %%X5 + %elif %%N > 4 + mov qword [%%pDst+sizeof(qword)*5], %%X0 + mov qword [%%pDst+sizeof(qword)*6], %%X1 + mov qword [%%pDst+sizeof(qword)*7], %%X2 + mov qword [%%pDst+sizeof(qword)*8], %%X3 + mov qword [%%pDst+sizeof(qword)*9], %%X4 + %elif %%N > 3 + mov qword [%%pDst+sizeof(qword)*4], %%X0 + mov qword [%%pDst+sizeof(qword)*5], %%X1 + mov qword [%%pDst+sizeof(qword)*6], %%X2 + mov qword [%%pDst+sizeof(qword)*7], %%X3 + %elif %%N > 2 + mov qword [%%pDst+sizeof(qword)*3], %%X0 + mov qword [%%pDst+sizeof(qword)*4], %%X1 + mov qword [%%pDst+sizeof(qword)*5], %%X2 + %elif %%N > 1 + mov qword [%%pDst+sizeof(qword)*2], %%X0 + mov qword [%%pDst+sizeof(qword)*3], %%X1 + %else + mov qword [%%pDst+sizeof(qword)*1], %%X0 + %endif ;; N==2 + +%endmacro + +%endif ;; _PCPBNUMUL_FIX_ADCX_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp.inc new file mode 100644 index 000000000..5e53d372e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp.inc @@ -0,0 +1,666 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number multiplication Support +; +; + +%ifndef _PCPBNUMUL_INC_ +%assign _PCPBNUMUL_INC_ 1 + +%include "pcpbnumulpp_basic.inc" + +%macro CLEAR 2.nolist + %xdefine %%rPtr %1 + %xdefine %%rLen %2 + +%%L_1: + mov qword [%%rPtr], rax + add %%rPtr, sizeof(qword) + sub %%rLen, 1 + jnz %%L_1 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; (8*n)x(8*m) multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_8Nx8M_adcox,PRIVATE + push rbx ;; nsB + push rdi ;; pR + push rsi ;; pA + push rdx ;; nsA + +;;; +;;; init +;;; +.mul_loopA: + push rdx ;; nsA + call mla_8x8 + add rdi, sizeof(qword)*8 ; adv pR + add rsi, sizeof(qword)*8 ; adv pA + pop rdx ; nsA-- + sub rdx, 8 + jnz .mul_loopA + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + + jmp .mla_entry + +.mla_loopB: + push rbx ;; nsB + + push rdi ;; pR + push rsi ;; pA + push rdx ;; nsA + + xor rax, rax ; c-flag + push rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + +.loopA: + push rdx ; nsA + call mla_8x8 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + pop rdx ; nsA-- + sub rdx, 8 + jz .exit_loopA + + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15,qword [rdi+sizeof(qword)*7], rax + sbb rax, rax ; save c-flag + push rax + jmp .loopA + +.exit_loopA: + pop rax ; restore c-flag + neg rax + adc r8, 0 + mov qword [rdi+sizeof(qword)*0], r8 + adc r9, 0 + mov qword [rdi+sizeof(qword)*1], r9 + adc r10,0 + mov qword [rdi+sizeof(qword)*2],r10 + adc r11,0 + mov qword [rdi+sizeof(qword)*3],r11 + adc r12,0 + mov qword [rdi+sizeof(qword)*4],r12 + adc r13,0 + mov qword [rdi+sizeof(qword)*5],r13 + adc r14,0 + mov qword [rdi+sizeof(qword)*6],r14 + adc r15,0 + mov qword [rdi+sizeof(qword)*7],r15 + +.mla_entry: + pop rdx ; restore nsA + pop rsi ; restore pA + pop rdi + add rdi, sizeof(qword)*8 + + add rcx, sizeof(qword)*8 + pop rbx ;; nsB-- + sub rbx, 8 + jnz .mla_loopB + ret +ENDFUNC mul_8Nx8M_adcox + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; simplest general case N x M multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_simple,PRIVATE + xor rax, rax ; carry = 0 + + mov r11, rdx + cmp r11, rbx + jge .ms_mla_entry + SWAP r11, rbx + SWAP rsi, rcx + jmp .ms_mla_entry + +.ms_loopB: + push rbx ;; nsB + push rdi ;; pR + push rsi ;; pA + push r11 ;; nsA + push rax ;; save previous pass carry + + mov rdx, qword [rcx] ; pB[] + xor r10, r10 ; extension +.ms_loopA: + gsmulx r9, r8, qword [rsi] + add rdi, sizeof(qword) + add rsi, sizeof(qword) + add r8, r10 + adc r9, 0 + add r8, qword [rdi-sizeof(qword)] + adc r9, 0 + mov qword [rdi-sizeof(qword)], r8 + mov r10, r9 + sub r11, 1 + jnz .ms_loopA + + pop rax ; restore carry + shr rax, 1 + + adc r10, qword [rdi] + mov qword [rdi], r10 + adc rax, 0 ; save carry + + pop r11 ; restore nsA + pop rsi ; restore pA + pop rdi ; restore pR + pop rbx ; nsB + + add rdi, sizeof(qword) + add rcx, sizeof(qword) + +.ms_mla_entry: + sub rbx, 1 + jnc .ms_loopB + ret +ENDFUNC mla_simple + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case N x M multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_NxM_adcox,PRIVATE +; +; stack struct +; +%assign nsB_cnt 0 ; rest of B operand +%assign ptrR nsB_cnt+sizeof(qword) ; current product pointer +%assign ptrA ptrR+sizeof(qword) ; ponter to A operand (pA) +%assign nsA ptrA+sizeof(qword) ; length of A operand (nsA) +%assign nsA_cnt nsA+sizeof(qword) ; rest of A operand +%assign carry nsA_cnt+sizeof(qword) ; carry +%assign tailproc carry+sizeof(qword) ; mla_8xn procedure +%assign stack_mem tailproc+sizeof(qword) ; size of stack allocation + + sub rsp, stack_mem ; allocate stack + + cmp rbx, 8 + jge .regular_entry + cmp rdx, 8 + jge .irregular_entry + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; degradated case +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; clear product + mov r8, rdx + add r8, rbx + mov rbp, rdi + xor rax, rax + CLEAR rbp, r8 + + call mla_simple + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; irregular init +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.irregular_entry: + mov [rsp+nsB_cnt], rbx + mov [rsp+nsA], rdx + mov [rsp+nsA_cnt], rdx + + GET_EP rax, mla_8xl_tail, rbx, rbp ; tail procedure (mla_8xn) address + mov [rsp+tailproc], rax + + jmp .irr_init_entry + +.irr_init_loop: + mov [rsp+nsA_cnt], rdx ; save A counter + call rax + + mov rbx, [rsp+nsB_cnt] + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0], r8 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1], r9 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2], r10 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3], r11 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4], r12 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5], r13 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6], r14 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*7], r15 + + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + + xor r8, r8 + xor r9, r9 + xor r10,r10 + xor r11,r11 + xor r12,r12 + xor r13,r13 + xor r14,r14 + xor r15,r15 + + ; load data depending on nsB length + mov r8, qword [rdi] + cmp rbx, 1 + jz .continue + mov r9, qword [rdi+sizeof(qword)] + cmp rbx, 2 + jz .continue + mov r10, qword [rdi+sizeof(qword)*2] + cmp rbx, 3 + jz .continue + mov r11, qword [rdi+sizeof(qword)*3] + cmp rbx, 4 + jz .continue + mov r12, qword [rdi+sizeof(qword)*4] + cmp rbx, 5 + jz .continue + mov r13, qword [rdi+sizeof(qword)*5] + cmp rbx, 6 + jz .continue + mov r14, qword [rdi+sizeof(qword)*6] +.continue: + mov rdx, [rsp+nsA_cnt] ; nsA + +.irr_init_entry: + sub rdx, 8 + mov rax, [rsp+tailproc] + jnc .irr_init_loop + + add rdx, 8 + jz .quit + + ; clear uninitialized rest of product + lea rbp, [rdi+rbx*sizeof(qword)] + xor rax, rax + CLEAR rbp, rdx + + mov rdx, [rsp+nsA_cnt] + call mla_simple + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; regular ep +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.regular_entry: + sub rbx, 8 + xor rax, rax + mov [rsp+nsB_cnt], rbx + mov [rsp+ptrR], rdi + mov [rsp+ptrA], rsi + mov [rsp+nsA], rdx + mov [rsp+nsA_cnt], rdx + mov [rsp+carry], rax + + mov rbp, rdx ; n = nsA %8 + and rbp, 7 + GET_EP rax, mla_8xl_tail, rbp ; tail procedure (mla_8xn) address + mov [rsp+tailproc], rax + +;; +;; regular init +;; + sub rdx, 8 ;; nsA counter +.init_loopA: + mov [rsp+nsA_cnt], rdx ; nsA + call mla_8x8 + mov rdx, [rsp+nsA_cnt] + add rdi, sizeof(qword)*8 ; adv ptrR + add rsi, sizeof(qword)*8 ; adv ptrA + sub rdx, 8 ; nsA -= 8 + jnc .init_loopA + + add rdx, 8 + jz .init_complete + + mov [rsp+nsA_cnt], rdx + + mov rax, [rsp+tailproc] + SWAP rcx, rsi + call rax + SWAP rcx, rsi + + mov rdx, [rsp+nsA_cnt] + lea rdi, [rdi+rdx*sizeof(qword)] + +.init_complete: + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + + jmp .mla_entry + +;; +;; regular mla passes +;; +.mla_loopB: + mov [rsp+nsB_cnt], rbx ; update B conter + mov [rsp+ptrR], rdi ; update current product pointer + + xor rax, rax ; init carry + mov [rsp+carry], rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + sub rdx, 8 +.loopA: + mov [rsp+nsA_cnt], rdx ; save A counter + call mla_8x8 + mov rdx, [rsp+nsA_cnt] ; A counter + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + sub rdx, 8 ; nsA -= 8 + jc .exit_loopA + + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rbx + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rbx + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*2], rbx + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*3], rbx + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*4], rbx + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*5], rbx + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*6], rbx + op_reg_mem adc, r15,qword [rdi+sizeof(qword)*7], rbx + adc rax, 0 ; save carry + mov [rsp+carry], rax + jmp .loopA + +.exit_loopA: + add rdx, 8 + jz .complete_reg_loopB + + mov [rsp+nsA_cnt], rdx + + ; put zeros + xor rax, rax +.put_zero: + mov qword [rdi+rdx*sizeof(qword)], rax + add rdx,1 + cmp rdx, 8 + jl .put_zero + + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*4], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*5], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*6], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*7], rbx + adc rax, 0 ; save carry + mov [rsp+carry], rax + + mov rax, [rsp+tailproc] + SWAP rcx, rsi + call rax + SWAP rcx, rsi + + mov rdx, [rsp+nsA_cnt] ; restore nsA + lea rdi, [rdi+rdx*sizeof(qword)] + + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + + dec rdx + jz .mt_1 + dec rdx + jz .mt_2 + dec rdx + jz .mt_3 + dec rdx + jz .mt_4 + dec rdx + jz .mt_5 + dec rdx + jz .mt_6 +.mt_7: adc r9, 0 +.mt_6: adc r10,0 +.mt_5: adc r11,0 +.mt_4: adc r12,0 +.mt_3: adc r13,0 +.mt_2: adc r14,0 +.mt_1: adc r15,0 + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + jmp .mla_entry + +.complete_reg_loopB: + mov rax, [rsp+carry] ; restore carry + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + adc r15,0 + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + +.mla_entry: + ; restore: + mov rbx, [rsp+nsB_cnt] ; - B counter + mov rdi, [rsp+ptrR] ; - ptrR + mov rdx, [rsp+nsA] ; - nsA + mov rsi, [rsp+ptrA] ; - pA + + add rcx, sizeof(qword)*8 ; adv pB + add rdi, sizeof(qword)*8 ; adv ptrR + sub rbx, 8 ; nsB -= 8 + jnc .mla_loopB + + add rbx, 8 + jz .quit + +;; +;; final mla pass +;; + mov [rsp+nsB_cnt], rbx + + GET_EP rax, mla_8xl_tail, rbx, rbp ; tail procedure (mla_8xn) address + mov [rsp+tailproc], rax + + ; clear uninitialized rest of product + lea rbp, [rdi+rdx*sizeof(qword)] + xor rax, rax + CLEAR rbp, rbx + + xor rax, rax ; init carry + mov [rsp+carry], rax + + sub rdx, 8 +.tail_loopA: + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov [rsp+nsA_cnt], rdx ; save A counter + mov rax, [rsp+tailproc] + call rax + +.entry_tail_loopA: + mov rax, [rsp+carry] ; restore carry + shr rax, 1 + adc r8, 0 + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + adc rax, 0 + + mov rbx, [rsp+nsB_cnt] ; nsB + mov rbp, rbx + dec rbp + jz .tt_1 + dec rbp + jz .tt_2 + dec rbp + jz .tt_3 + dec rbp + jz .tt_4 + dec rbp + jz .tt_5 + dec rbp + jz .tt_6 +.tt_7: op_reg_mem adc, r9, [rdi+rbx*sizeof(qword)+sizeof(qword)*1], rbp +.tt_6: op_reg_mem adc, r10,[rdi+rbx*sizeof(qword)+sizeof(qword)*2], rbp +.tt_5: op_reg_mem adc, r11,[rdi+rbx*sizeof(qword)+sizeof(qword)*3], rbp +.tt_4: op_reg_mem adc, r12,[rdi+rbx*sizeof(qword)+sizeof(qword)*4], rbp +.tt_3: op_reg_mem adc, r13,[rdi+rbx*sizeof(qword)+sizeof(qword)*5], rbp +.tt_2: op_reg_mem adc, r14,[rdi+rbx*sizeof(qword)+sizeof(qword)*6], rbp +.tt_1: op_reg_mem adc, r15,[rdi+rbx*sizeof(qword)+sizeof(qword)*7], rbp + adc rax, 0 + mov [rsp+carry], rax ; update carry + + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0], r8 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1], r9 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2], r10 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3], r11 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4], r12 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5], r13 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6], r14 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*7], r15 + + mov rdx, [rsp+nsA_cnt] ; A counter + add rsi, sizeof(qword)*8 ; adv pA + add rdi, sizeof(qword)*8 ; adv pR + sub rdx, 8 ; nsA -= 8 + jnc .tail_loopA + + add rdx, 8 + jz .quit + + ; carry propagation + mov rax, [rsp+carry] + mov rbp, rbx + + dec rbp + mov r8, qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0] + add r8, rax + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0], r8 + jz .simple + dec rbp + mov r9, qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1] + adc r9, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1], r9 + jz .simple + dec rbp + mov r10,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2] + adc r10, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2], r10 + jz .simple + dec rbp + mov r11,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3] + adc r11, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3], r11 + jz .simple + dec rbp + mov r12,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4] + adc r12, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4], r12 + jz .simple + dec rbp + mov r13,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5] + adc r13, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5], r13 + jz .simple + dec rbp + mov r14,qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6] + adc r14, 0 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6], r14 + +.simple: + call mla_simple + + +.quit: + add rsp, stack_mem ; release stack + ret +ENDFUNC mul_NxM_adcox + + +%endif ;; _PCPBNUMUL_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp_basic.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp_basic.inc new file mode 100644 index 000000000..d89375fa0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp_basic.inc @@ -0,0 +1,924 @@ +;=============================================================================== +; Copyright (C) 2013 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number multiplication Support +; +; + +%ifndef _PCPBNUMUL_BASIC_INC_ +%assign _PCPBNUMUL_BASIC_INC_ 1 + +%include "pcpmulx.inc" +%include "pcpbnumulpp_fix.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; short size (1-8 qwords) operand mla and mul operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; 1x1 multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_1x1,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 1, rdi, rsi, rbx,rbp, r8 + ret +ENDFUNC mla_1x1 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_1x1,PRIVATE + mov rdx,qword [rcx] + gsmulx rdx, rax, qword [rsi] + mov qword [rdi], rax + mov qword [rdi+sizeof(qword)], rdx + ret +ENDFUNC mul_1x1 + + + +;; +;; 2x2 multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_2x2,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 2, rdi, rsi, rbx,rbp, r8,r9 + mov rdx, qword [rcx+sizeof(qword)] + MLA_FIX 2, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9 + ret +ENDFUNC mla_2x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_2x2,PRIVATE + call mla_2x2 + mov qword [rdi+sizeof(qword)*2], r8 + mov qword [rdi+sizeof(qword)*3], r9 + ret +ENDFUNC mul_2x2 + + + +;; +;; 3x3 multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_3x3,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 3, rdi, rsi, rbx,rbp, r8,r9,r10 + mov rdx, qword [rcx+sizeof(qword)] + MLA_FIX 3, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10 + mov rdx, qword [rcx+sizeof(qword)*2] + MLA_FIX 3, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10 + ret +ENDFUNC mla_3x3 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_3x3,PRIVATE + call mla_3x3 + mov qword [rdi+sizeof(qword)*3], r8 + mov qword [rdi+sizeof(qword)*4], r9 + mov qword [rdi+sizeof(qword)*5], r10 + ret +ENDFUNC mul_3x3 + + + +;; +;; 4x{2,4} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_4x4,PRIVATE + mov rdx, qword [rcx] + MLA_FIX 4, rdi, rsi, rbx,rbp, r8,r9,r10,r11 + mov rdx, qword [rcx+sizeof(qword)] + MLA_FIX 4, {rdi+sizeof(qword)}, rsi, rbx,rbp, r8,r9,r10,r11 + mov rdx, qword [rcx+sizeof(qword)*2] + MLA_FIX 4, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11 + mov rdx, qword [rcx+sizeof(qword)*3] + MLA_FIX 4, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11 + ret +ENDFUNC mla_4x4 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_4x4,PRIVATE + call mla_4x4 + mov qword [rdi+sizeof(qword)*4], r8 + mov qword [rdi+sizeof(qword)*5], r9 + mov qword [rdi+sizeof(qword)*6], r10 + mov qword [rdi+sizeof(qword)*7], r11 + ret +ENDFUNC mul_4x4 + + + +;; +;; 5x{2,5} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_5x5,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 5, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 5, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 5, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 5, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12 + mov rdx, [rcx+sizeof(qword)*4] + MLA_FIX 5, {rdi+sizeof(qword)*4}, rsi, rbx,rbp, r8,r9,r10,r11,r12 + ret +ENDFUNC mla_5x5 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_5x5,PRIVATE + call mla_5x5 + mov qword [rdi+sizeof(qword)*5], r8 + mov qword [rdi+sizeof(qword)*6], r9 + mov qword [rdi+sizeof(qword)*7], r10 + mov qword [rdi+sizeof(qword)*8], r11 + mov qword [rdi+sizeof(qword)*9], r12 + ret +ENDFUNC mul_5x5 + + + +;; +;; 6x{2,6} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_6x6,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 6, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 6, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 6, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 6, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + mov rdx, [rcx+sizeof(qword)*4] + MLA_FIX 6, {rdi+sizeof(qword)*4}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + mov rdx, [rcx+sizeof(qword)*5] + MLA_FIX 6, {rdi+sizeof(qword)*5}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + ret +ENDFUNC mla_6x6 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_6x6,PRIVATE + call mla_6x6 + mov qword [rdi+sizeof(qword)*6], r8 + mov qword [rdi+sizeof(qword)*7], r9 + mov qword [rdi+sizeof(qword)*8], r10 + mov qword [rdi+sizeof(qword)*9], r11 + mov qword [rdi+sizeof(qword)*10],r12 + mov qword [rdi+sizeof(qword)*11],r13 + ret +ENDFUNC mul_6x6 + + + +;; +;; 7x{2,7} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_7x7,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 7, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 7, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 7, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 7, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + mov rdx, [rcx+sizeof(qword)*4] + MLA_FIX 7, {rdi+sizeof(qword)*4}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + mov rdx, [rcx+sizeof(qword)*5] + MLA_FIX 7, {rdi+sizeof(qword)*5}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + mov rdx, [rcx+sizeof(qword)*6] + MLA_FIX 7, {rdi+sizeof(qword)*6}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + ret +ENDFUNC mla_7x7 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_7x7,PRIVATE + call mla_7x7 + mov qword [rdi+sizeof(qword)*7], r8 + mov qword [rdi+sizeof(qword)*8], r9 + mov qword [rdi+sizeof(qword)*9], r10 + mov qword [rdi+sizeof(qword)*10],r11 + mov qword [rdi+sizeof(qword)*11],r12 + mov qword [rdi+sizeof(qword)*12],r13 + mov qword [rdi+sizeof(qword)*13],r14 + ret +ENDFUNC mul_7x7 + + + +;; +;; 8x{1,2,3,4,5,6,7,8} multiplication +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x1,PRIVATE + mov rdx, [rcx] + MLA_FIX 8, rdi, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x1 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x2,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x2 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x3,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 8, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x3 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x4,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 8, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 8, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x4 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x5,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 8, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 8, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*4] + MLA_FIX 8, {rdi+sizeof(qword)*4}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x5 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x6,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 8, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 8, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*4] + MLA_FIX 8, {rdi+sizeof(qword)*4}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*5] + MLA_FIX 8, {rdi+sizeof(qword)*5}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x6 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x7,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 8, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 8, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*4] + MLA_FIX 8, {rdi+sizeof(qword)*4}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*5] + MLA_FIX 8, {rdi+sizeof(qword)*5}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*6] + MLA_FIX 8, {rdi+sizeof(qword)*6}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x7 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mla_8x8,PRIVATE + mov rdx, [rcx+sizeof(qword)*0] + MLA_FIX 8, {rdi+sizeof(qword)*0}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*1] + MLA_FIX 8, {rdi+sizeof(qword)*1}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*2] + MLA_FIX 8, {rdi+sizeof(qword)*2}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*3] + MLA_FIX 8, {rdi+sizeof(qword)*3}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*4] + MLA_FIX 8, {rdi+sizeof(qword)*4}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*5] + MLA_FIX 8, {rdi+sizeof(qword)*5}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*6] + MLA_FIX 8, {rdi+sizeof(qword)*6}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + mov rdx, [rcx+sizeof(qword)*7] + MLA_FIX 8, {rdi+sizeof(qword)*7}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mla_8x8 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_8x8,PRIVATE + call mla_8x8 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],r15 + ret +ENDFUNC mul_8x8 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; middle size (9-16 qwords) operand mla and mul operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_9x9,PRIVATE + call mla_8x8 + + mov rdx, [rcx+sizeof(qword)*8] + MLA_FIX 8, {rdi+sizeof(qword)*8}, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + push r15 + + mov rdx, [rsi+sizeof(qword)*8] + mov r15, [rdi+sizeof(qword)*8] + MLA_FIX 8, {rdi+sizeof(qword)*8}, rcx, rbx,rbp, r15,r8,r9,r10,r11,r12,r13,r14 + mov qword [rdi+sizeof(qword)*9], r15 + + gsmulx r15, rbp, [rcx+sizeof(qword)*8] + pop rax + add r14, rax + adc r15,0 + add r14, rbp + adc r15, 0 + + mov qword [rdi+sizeof(qword)*10],r8 + mov qword [rdi+sizeof(qword)*11],r9 + mov qword [rdi+sizeof(qword)*12],r10 + mov qword [rdi+sizeof(qword)*13],r11 + mov qword [rdi+sizeof(qword)*14],r12 + mov qword [rdi+sizeof(qword)*15],r13 + mov qword [rdi+sizeof(qword)*16],r14 + mov qword [rdi+sizeof(qword)*17],r15 + ret +ENDFUNC mul_9x9 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_10x10,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x2 + push r15 + push r14 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r13 + mov r14, r12 + mov r13, r11 + mov r12, r10 + mov r11, r9 + mov r10, r8 + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x2 + + mov qword [rdi+sizeof(qword)*2],r8 + mov qword [rdi+sizeof(qword)*3],r9 + mov qword [rdi+sizeof(qword)*4],r10 + mov qword [rdi+sizeof(qword)*5],r11 + mov qword [rdi+sizeof(qword)*6],r12 + mov qword [rdi+sizeof(qword)*7],r13 + add rdi, sizeof(qword)*8 + + xor r10, r10 + pop r8 + pop r9 + add r8, r14 + adc r9, r15 + adc r10,0 + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_2x2 + add rdi, sizeof(qword)*2 + + add r8, r10 + adc r9, 0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + ret +ENDFUNC mul_10x10 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_11x11,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x3 + push r15 + push r14 + push r13 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r12 + mov r14, r11 + mov r13, r10 + mov r12, r9 + mov r11, r8 + mov r10,qword [rdi+sizeof(qword)*2] + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x3 + + mov qword [rdi+sizeof(qword)*3],r8 + mov qword [rdi+sizeof(qword)*4],r9 + mov qword [rdi+sizeof(qword)*5],r10 + mov qword [rdi+sizeof(qword)*6],r11 + mov qword [rdi+sizeof(qword)*7],r12 + add rdi, sizeof(qword)*8 + + xor r11, r11 + pop r8 + pop r9 + pop r10 + add r8, r13 + adc r9, r14 + adc r10,r15 + adc r11,0 + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_3x3 + add rdi, sizeof(qword)*3 + + add r8, r11 + adc r9, 0 + adc r10,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + ret +ENDFUNC mul_11x11 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_12x12,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x4 + push r15 + push r14 + push r13 + push r12 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r11 + mov r14, r10 + mov r13, r9 + mov r12, r8 + mov r11,qword [rdi+sizeof(qword)*3] + mov r10,qword [rdi+sizeof(qword)*2] + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x4 + + mov qword [rdi+sizeof(qword)*4],r8 + mov qword [rdi+sizeof(qword)*5],r9 + mov qword [rdi+sizeof(qword)*6],r10 + mov qword [rdi+sizeof(qword)*7],r11 + add rdi, sizeof(qword)*8 + + xor rax, rax + pop r8 + pop r9 + pop r10 + pop r11 + add r8, r12 + adc r9, r13 + adc r10,r14 + adc r11,r15 + adc rax,0 + push rax + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_4x4 + add rdi, sizeof(qword)*4 + + pop rax + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + ret +ENDFUNC mul_12x12 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_13x13,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x5 + push r15 + push r14 + push r13 + push r12 + push r11 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r15, r10 + mov r14, r9 + mov r13, r8 + mov r12,qword [rdi+sizeof(qword)*4] + mov r11,qword [rdi+sizeof(qword)*3] + mov r10,qword [rdi+sizeof(qword)*2] + mov r9, qword [rdi+sizeof(qword)*1] + mov r8, qword [rdi+sizeof(qword)*0] + call mla_8x5 + + mov qword [rdi+sizeof(qword)*5], r8 + mov qword [rdi+sizeof(qword)*6], r9 + mov qword [rdi+sizeof(qword)*7], r10 + add rdi, sizeof(qword)*8 + + xor rax, rax + pop r8 + pop r9 + pop r10 + pop rbx + pop rbp + add r8, r11 + adc r9, r12 + adc r10,r13 + adc rbx,r14 + adc rbp,r15 + adc rax,0 + push rax + + mov r11, rbx + mov r12, rbp + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + call mla_5x5 + add rdi, sizeof(qword)*5 + + pop rax + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + ret +ENDFUNC mul_13x13 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_14x14,PRIVATE + call mla_7x7 + + add rdi, sizeof(qword)*7 + add rsi, sizeof(qword)*7 + call mla_7x7 + mov qword [rdi+sizeof(qword)*7], r8 + mov qword [rdi+sizeof(qword)*8], r9 + mov qword [rdi+sizeof(qword)*9], r10 + mov qword [rdi+sizeof(qword)*10],r11 + mov qword [rdi+sizeof(qword)*11],r12 + mov qword [rdi+sizeof(qword)*12],r13 + mov qword [rdi+sizeof(qword)*13],r14 + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + + add rcx, sizeof(qword)*7 + sub rsi, sizeof(qword)*7 + call mla_7x7 + + xor rdx, rdx + op_reg_mem add, r8, qword [rdi+sizeof(qword)*7], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*8], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*9], rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*10],rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*11],rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*12],rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*13],rax + adc rdx, 0 + push rdx + + add rdi, sizeof(qword)*7 + add rsi, sizeof(qword)*7 + call mla_7x7 + + sub rdi, sizeof(qword)*14 + sub rsi, sizeof(qword)*7 + sub rcx, sizeof(qword)*7 + + pop rdx + add r8, rdx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + + mov qword [rdi+sizeof(qword)*21],r8 + mov qword [rdi+sizeof(qword)*22],r9 + mov qword [rdi+sizeof(qword)*23],r10 + mov qword [rdi+sizeof(qword)*24],r11 + mov qword [rdi+sizeof(qword)*25],r12 + mov qword [rdi+sizeof(qword)*26],r13 + mov qword [rdi+sizeof(qword)*27],r14 + ret +ENDFUNC mul_14x14 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_15x15,PRIVATE +; A0*B0 + call mla_8x8 + add rdi, sizeof(qword)*8 + +; + A0*B1 + add rcx, sizeof(qword)*8 + call mla_8x7 + mov qword [rdi+sizeof(qword)*7], r8 + mov qword [rdi+sizeof(qword)*8], r9 + mov qword [rdi+sizeof(qword)*9], r10 + mov qword [rdi+sizeof(qword)*10],r11 + mov qword [rdi+sizeof(qword)*11],r12 + mov qword [rdi+sizeof(qword)*12],r13 + mov qword [rdi+sizeof(qword)*13],r14 + mov qword [rdi+sizeof(qword)*14],r15 + +; + A1*B0 + add rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + SWAP rcx, rsi + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + call mla_8x7 + + mov qword [rdi+sizeof(qword)*7], r8 + add rdi, sizeof(qword)*8 + +; + A1*B1 + SWAP rcx, rsi + add rcx, sizeof(qword)*8 + + mov r8, r9 + mov r9, r10 + mov r10,r11 + mov r11,r12 + mov r12,r13 + mov r13,r14 + mov r14,r15 + xor rdx, rdx + op_reg_mem add, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*6], rax + adc rdx, 0 + push rdx + + call mla_7x7 + add rdi, sizeof(qword)*7 + + pop rax + add r8, rax + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + mov qword [rdi+sizeof(qword)*0],r8 + mov qword [rdi+sizeof(qword)*1],r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + ret +ENDFUNC mul_15x15 + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mul_16x16,PRIVATE + call mla_8x8 + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + call mla_8x8 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],r15 + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + add rcx, sizeof(qword)*8 + sub rsi, sizeof(qword)*8 + call mla_8x8 + + xor rdx, rdx + op_reg_mem add, r8, qword [rdi+sizeof(qword)*8], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*9], rax + op_reg_mem adc, r10,qword [rdi+sizeof(qword)*10],rax + op_reg_mem adc, r11,qword [rdi+sizeof(qword)*11],rax + op_reg_mem adc, r12,qword [rdi+sizeof(qword)*12],rax + op_reg_mem adc, r13,qword [rdi+sizeof(qword)*13],rax + op_reg_mem adc, r14,qword [rdi+sizeof(qword)*14],rax + op_reg_mem adc, r15,qword [rdi+sizeof(qword)*15],rax + adc rdx, 0 + push rdx + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + call mla_8x8 + + sub rdi, sizeof(qword)*16 + sub rsi, sizeof(qword)*8 + sub rcx, sizeof(qword)*8 + + pop rdx + add r8, rdx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + + mov qword [rdi+sizeof(qword)*24],r8 + mov qword [rdi+sizeof(qword)*25],r9 + mov qword [rdi+sizeof(qword)*26],r10 + mov qword [rdi+sizeof(qword)*27],r11 + mov qword [rdi+sizeof(qword)*28],r12 + mov qword [rdi+sizeof(qword)*29],r13 + mov qword [rdi+sizeof(qword)*30],r14 + mov qword [rdi+sizeof(qword)*31],r15 + ret +ENDFUNC mul_16x16 + + +mul_lxl_basic DQ mul_1x1 - mul_lxl_basic + DQ mul_2x2 - mul_lxl_basic + DQ mul_3x3 - mul_lxl_basic + DQ mul_4x4 - mul_lxl_basic + DQ mul_5x5 - mul_lxl_basic + DQ mul_6x6 - mul_lxl_basic + DQ mul_7x7 - mul_lxl_basic + DQ mul_8x8 - mul_lxl_basic + DQ mul_9x9 - mul_lxl_basic + DQ mul_10x10-mul_lxl_basic + DQ mul_11x11-mul_lxl_basic + DQ mul_12x12-mul_lxl_basic + DQ mul_13x13-mul_lxl_basic + DQ mul_14x14-mul_lxl_basic + DQ mul_15x15-mul_lxl_basic + DQ mul_16x16-mul_lxl_basic + +mla_lxl_short DQ mla_1x1 - mla_lxl_short + DQ mla_2x2 - mla_lxl_short + DQ mla_3x3 - mla_lxl_short + DQ mla_4x4 - mla_lxl_short + DQ mla_5x5 - mla_lxl_short + DQ mla_6x6 - mla_lxl_short + DQ mla_7x7 - mla_lxl_short + +mla_8xl_tail DQ mla_8x1 - mla_8xl_tail + DQ mla_8x2 - mla_8xl_tail + DQ mla_8x3 - mla_8xl_tail + DQ mla_8x4 - mla_8xl_tail + DQ mla_8x5 - mla_8xl_tail + DQ mla_8x6 - mla_8xl_tail + DQ mla_8x7 - mla_8xl_tail + +%endif ;; _PCPBNUMUL_BASIC_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp_fix.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp_fix.inc new file mode 100644 index 000000000..62f35d89b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulpp_fix.inc @@ -0,0 +1,427 @@ +;=============================================================================== +; Copyright (C) 2013 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number multiplication Support +; +; + +%ifndef _PCPBNUMUL_FIX_ADCX_INC_ +%assign _PCPBNUMUL_FIX_ADCX_INC_ 1 + +%ifdef _ADCX_ADOX_ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; macro used to replace op reg, mem instructions +%macro SWAP 2.nolist + %xdefine %%r1 %1 + %xdefine %%r2 %2 + + xor %%r1, %%r2 + xor %%r2, %%r1 + xor %%r1, %%r2 +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; macro used extract proc ep from the table +%macro GET_EP 3-4.nolist + %xdefine %%regEp %1 + %xdefine %%Table %2 + %xdefine %%regIdx %3 + %xdefine %%tmp %4 + + lea %%regEp, [rel %%Table] + %ifnempty %%tmp + mov %%tmp, [%%regEp+%%regIdx*sizeof(qword)-sizeof(qword)] + add %%regEp, %%tmp + %else + mov %%regIdx, [%%regEp+%%regIdx*sizeof(qword)-sizeof(qword)] + add %%regEp, %%regIdx + %endif +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; op DST, mem_src +%macro op_reg_mem 4.nolist + %xdefine %%opCode %1 + %xdefine %%dst %2 + %xdefine %%mem_src %3 + %xdefine %%tmp %4 + + mov %%tmp, %%mem_src + %%opCode %%dst, %%tmp +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEM_DST = (op src1, mem_src2) +%macro op_mem_reg_mem 5.nolist + %xdefine %%opCode %1 + %xdefine %%mem_dst %2 + %xdefine %%src1 %3 + %xdefine %%mem_src2 %4 + %xdefine %%tmp %5 + + op_reg_mem %%opCode, %%src1, %%mem_src2, %%tmp + mov %%mem_dst, %%src1 +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEM_DST = op mem_src1, mem_src2 +%macro op_mem_mem 5.nolist + %xdefine %%opCode %1 + %xdefine %%mem_dst %2 + %xdefine %%mem_src1 %3 + %xdefine %%mem_src2 %4 + %xdefine %%tmp %5 + + mov %%tmp, %%mem_src1 + %%opCode %%tmp, %%mem_src2 + mov %%mem_dst, %%tmp +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Inputs: pDst: Destination (upto 1024 bits, 16 qwords) +;;; pA: Multiplicand (upto 512 bits, 8 qwords) +;;; +;;; +;;; Uses registers: +;;; rdx - implicit multiplicand +;;; (HIP:LOP)- 64x64-bit product (mulx) +;;; X7,,X0 - high result +;;; +%macro MUL_FIX 12-13.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pA %3 + %xdefine %%HIP %4 + %xdefine %%LOP %5 + %xdefine %%X0 %6 + %xdefine %%X1 %7 + %xdefine %%X2 %8 + %xdefine %%X3 %9 + %xdefine %%X4 %10 + %xdefine %%X5 %11 + %xdefine %%X6 %12 + %xdefine %%X7 %13 + + gsmulx %%X0, %%LOP, [%%pA] ; (X0:LO) = a[0]*b + %ifnempty %%pDst + mov [%%pDst], %%LOP + %endif + + %if %%N > 1 + gsmulx %%X1, %%HIP, [%%pA+sizeof(qword)] ; (X1:LO) = a[1]*b + add %%X0, %%HIP + %if %%N == 2 + adc %%X1, 0 + %endif + %endif + + %if %%N > 2 + gsmulx %%X2, %%LOP, [%%pA+sizeof(qword)*2] ; (X2:LO) = a[2]*b + adc %%X1, %%LOP + %if %%N == 3 + adc %%X2, 0 + %endif + %endif + + %if %%N > 3 + gsmulx %%X3, %%HIP, [%%pA+sizeof(qword)*3] ; (X3:LO) = a[3]*b + adc %%X2, %%HIP + %if %%N == 4 + adc %%X3, 0 + %endif + %endif + + %if %%N > 4 + gsmulx %%X4, %%LOP, [%%pA+sizeof(qword)*4] ; (X4:LO) = a[4]*b + adc %%X3, %%LOP + %if %%N == 5 + adc %%X4, 0 + %endif + %endif + + %if %%N > 5 + gsmulx %%X5, %%HIP, [%%pA+sizeof(qword)*5] ; (X5:LO) = a[5]*b + adc %%X4, %%HIP + %if %%N == 6 + adc %%X5, 0 + %endif + %endif + + %if %%N > 6 + gsmulx %%X6, %%LOP, [%%pA+sizeof(qword)*6] ; (X6:LO) = a[6]*b + adc %%X5, %%LOP + %if %%N == 7 + adc %%X6, 0 + %endif + %endif + + %if %%N > 7 + gsmulx %%X7, %%HIP, [%%pA+sizeof(qword)*7] ; (X7:LO) = a[7]*b + adc %%X6, %%HIP + adc %%X7, 0 + %endif +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; {x7,x6,x5,x4,x3,x2,x1,x0},DCT[0] = {x7,x6,x5,x4,x3,x2,x1,x0} + A[7:0]*B[i] +;; +;; uses rax, rdx +;; rdx - implicit multiplicand B[i] (should to be preloaded) +;; rax - temporary product +;; (HIP:LOP)- 64x64-bit product (mulx) +;; X7,,X0 - high result +;; +%macro MLA_FIX 6-13.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pA %3 + %xdefine %%HIP %4 + %xdefine %%LOP %5 + %xdefine %%X0 %6 + %xdefine %%X1 %7 + %xdefine %%X2 %8 + %xdefine %%X3 %9 + %xdefine %%X4 %10 + %xdefine %%X5 %11 + %xdefine %%X6 %12 + %xdefine %%X7 %13 + + xor rax, rax + + gsmulx %%HIP, %%LOP, [%%pA] ; (HI:LO) = a[0]*b[i] + gsadox %%X0, %%LOP + %ifnempty %%pDst + mov [%%pDst], %%X0 + %endif + + %if %%N == 1 + gsadox %%HIP, rax + mov %%X0, %%HIP + %else + + gsadcx %%X1, %%HIP + + gsmulx %%LOP,%%X0, [%%pA+sizeof(qword)] ; (LO:X0) = a[1]*b[i] + gsadox %%X0, %%X1 + + %if %%N == 2 + gsadcx %%LOP, rax + gsadox %%LOP, rax + mov %%X1, %%LOP + %else + + gsadcx %%X2, %%LOP + + gsmulx %%HIP,%%X1, [%%pA+sizeof(qword)*2] ; (HI:X1) = a[2]*b[i] + gsadox %%X1, %%X2 + + %if %%N == 3 + gsadcx %%HIP, rax + gsadox %%HIP, rax + mov %%X2, %%HIP + %else + + gsadcx %%X3, %%HIP + + gsmulx %%LOP,%%X2, [%%pA+sizeof(qword)*3] ; (LO,X2) = a[3]*b[i] + gsadox %%X2, %%X3 + + %if %%N == 4 + gsadcx %%LOP, rax + gsadox %%LOP, rax + mov %%X3, %%LOP + %else + + gsadcx %%X4, %%LOP + + gsmulx %%HIP,%%X3, [%%pA+sizeof(qword)*4] ; (HI:X3) = a[4]*b[i] + gsadox %%X3, %%X4 + + %if %%N == 5 + gsadcx %%HIP, rax + gsadox %%HIP, rax + mov %%X4, %%HIP + %else + + gsadcx %%X5, %%HIP + + gsmulx %%LOP,%%X4, [%%pA+sizeof(qword)*5] ; (LO:X4) = a[5]*b[i] + gsadox %%X4, %%X5 + + %if %%N == 6 + gsadcx %%LOP, rax + gsadox %%LOP, rax + mov %%X5, %%LOP + %else + + gsadcx %%X6, %%LOP + + gsmulx %%HIP,%%X5, [%%pA+sizeof(qword)*6] ; (HI:X5) = a[6]*b[i] + gsadox %%X5, %%X6 + + %if %%N == 7 + gsadcx %%HIP, rax + gsadox %%HIP, rax + mov %%X6, %%HIP + %else + + gsadcx %%HIP,%%X7 + + gsmulx %%X7, %%X6, [%%pA+sizeof(qword)*7] ; (LO:X6) = a[7]*b[i] + gsadox %%X6, %%HIP + gsadcx %%X7, rax + gsadox %%X7, rax + + %endif + %endif + %endif + %endif + %endif + %endif + %endif +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Inputs: pDst: Destination (upto 1024 bits, 16 qwords) +;;; pA: Multiplicand (upto 512 bits, 8 qwords) +;;; pB: Multiplicand (upto 512 bits, 8 qwords) +;;; +;;; +;;; Uses registers: +;;; rdx - implicit multiplicand +;;; (HIP:LOP)- 64x64-bit product (mulx) +;;; X0,,X7 - high result +;;; +%macro MUL_NxN 7-14.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pA %3 + %xdefine %%pB %4 + %xdefine %%HIP %5 + %xdefine %%LOP %6 + %xdefine %%X0 %7 + %xdefine %%X1 %8 + %xdefine %%X2 %9 + %xdefine %%X3 %10 + %xdefine %%X4 %11 + %xdefine %%X5 %12 + %xdefine %%X6 %13 + %xdefine %%X7 %14 + + mov rdx, [%%pB] + MUL_FIX {%%N},{%%pDst},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + + %if %%N > 1 + mov rdx, [%%pB+sizeof(qword)*1] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*1},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 2 + mov rdx,[%%pB+sizeof(qword)*2] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*2},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 3 + mov rdx,[%%pB+sizeof(qword)*3] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*3},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 4 + mov rdx,[%%pB+sizeof(qword)*4] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*4},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 5 + mov rdx,[%%pB+sizeof(qword)*5] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*5},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 6 + mov rdx,[%%pB+sizeof(qword)*6] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*6},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 7 + mov rdx,[%%pB+sizeof(qword)*7] + MLA_FIX {%%N},{%%pDst+sizeof(qword)*7},{%%pA},{%%HIP},{%%LOP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} + %endif + + %if %%N > 7 + mov qword [%%pDst+sizeof(qword)*8], %%X0 + mov qword [%%pDst+sizeof(qword)*9], %%X1 + mov qword [%%pDst+sizeof(qword)*10], %%X2 + mov qword [%%pDst+sizeof(qword)*11], %%X3 + mov qword [%%pDst+sizeof(qword)*12], %%X4 + mov qword [%%pDst+sizeof(qword)*13], %%X5 + mov qword [%%pDst+sizeof(qword)*14], %%X6 + mov qword [%%pDst+sizeof(qword)*15], %%X7 + %elif %%N > 6 + mov qword [%%pDst+sizeof(qword)*7], %%X0 + mov qword [%%pDst+sizeof(qword)*8], %%X1 + mov qword [%%pDst+sizeof(qword)*9], %%X2 + mov qword [%%pDst+sizeof(qword)*10], %%X3 + mov qword [%%pDst+sizeof(qword)*11], %%X4 + mov qword [%%pDst+sizeof(qword)*12], %%X5 + mov qword [%%pDst+sizeof(qword)*13], %%X6 + %elif %%N > 5 + mov qword [%%pDst+sizeof(qword)*6], %%X0 + mov qword [%%pDst+sizeof(qword)*7], %%X1 + mov qword [%%pDst+sizeof(qword)*8], %%X2 + mov qword [%%pDst+sizeof(qword)*9], %%X3 + mov qword [%%pDst+sizeof(qword)*10], %%X4 + mov qword [%%pDst+sizeof(qword)*11], %%X5 + %elif %%N > 4 + mov qword [%%pDst+sizeof(qword)*5], %%X0 + mov qword [%%pDst+sizeof(qword)*6], %%X1 + mov qword [%%pDst+sizeof(qword)*7], %%X2 + mov qword [%%pDst+sizeof(qword)*8], %%X3 + mov qword [%%pDst+sizeof(qword)*9], %%X4 + %elif %%N > 3 + mov qword [%%pDst+sizeof(qword)*4], %%X0 + mov qword [%%pDst+sizeof(qword)*5], %%X1 + mov qword [%%pDst+sizeof(qword)*6], %%X2 + mov qword [%%pDst+sizeof(qword)*7], %%X3 + %elif %%N > 2 + mov qword [%%pDst+sizeof(qword)*3], %%X0 + mov qword [%%pDst+sizeof(qword)*4], %%X1 + mov qword [%%pDst+sizeof(qword)*5], %%X2 + %elif %%N > 1 + mov qword [%%pDst+sizeof(qword)*2], %%X0 + mov qword [%%pDst+sizeof(qword)*3], %%X1 + %else + mov qword [%%pDst+sizeof(qword)*1], %%X0 + %endif ;; N==2 + +%endmacro + + +%endif ;; _ADCX_ADOX_ + +%endif ;; _PCPBNUMUL_FIX_ADCX_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschool.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschool.inc new file mode 100644 index 000000000..b461d9576 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschool.inc @@ -0,0 +1,1327 @@ +;=============================================================================== +; Copyright (C) 2010 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; BNU multiplication support +; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; fixed multiplier macros +;; + +;; +;; {x0,x7,x6,x5,x4,x3,x2,x1},DCT[0] = OP*SRC2[] + {x7,x6,x5,x4,x3,x2,x1,x0} +;; +;; uses rax, rdx +;; OP=SRC1[i] should to be preloaded +;; TMP is destoyed +;; +%macro MLA_FIX 6-13.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%SRC2 %3 + %xdefine %%OP %4 + %xdefine %%TMP %5 + %xdefine %%X7 %6 + %xdefine %%X6 %7 + %xdefine %%X5 %8 + %xdefine %%X4 %9 + %xdefine %%X3 %10 + %xdefine %%X2 %11 + %xdefine %%X1 %12 + %xdefine %%X0 %13 + + mov rax, [%%SRC2+8*0] + mul %%OP ; rdx:rax = OP * [] + add %%X0, rax + adc rdx, 0 + mov %%pDst, %%X0 + mov %%TMP, rdx + + %if %%N > 1 + mov rax, [%%SRC2+8*1] + mul %%OP ; rdx:rax = OP * [] + add %%X1, rax + adc rdx, 0 + add %%X1, %%TMP + adc rdx, 0 + %if %%N == 2 + mov %%X2, rdx + %else + mov %%TMP, rdx + %endif + + %if %%N > 2 + mov rax, [%%SRC2+8*2] + mul %%OP ; rdx:rax = OP * [] + add %%X2, rax + adc rdx, 0 + add %%X2, %%TMP + adc rdx, 0 + %if %%N == 3 + mov %%X3, rdx + %else + mov %%TMP, rdx + %endif + + %if %%N > 3 + mov rax, [%%SRC2+8*3] + mul %%OP ; rdx:rax = OP * [] + add %%X3, rax + adc rdx, 0 + add %%X3, %%TMP + adc rdx, 0 + %if %%N == 4 + mov %%X4, rdx + %else + mov %%TMP, rdx + %endif + + %if %%N > 4 + mov rax, [%%SRC2+8*4] + mul %%OP ; rdx:rax = OP * [] + add %%X4, rax + adc rdx, 0 + add %%X4, %%TMP + adc rdx, 0 + %if %%N == 5 + mov %%X5, rdx + %else + mov %%TMP, rdx + %endif + + %if %%N > 5 + mov rax, [%%SRC2+8*5] + mul %%OP ; rdx:rax = OP * [] + add %%X5, rax + adc rdx, 0 + add %%X5, %%TMP + adc rdx, 0 + %if %%N == 6 + mov %%X6, rdx + %else + mov %%TMP, rdx + %endif + + %if %%N > 6 + mov rax, [%%SRC2+8*6] + mul %%OP ; rdx:rax = OP * [] + add %%X6, rax + adc rdx, 0 + add %%X6, %%TMP + adc rdx, 0 + %if %%N == 7 + mov %%X7, rdx + %else + mov %%TMP, rdx + %endif + + %if %%N > 7 + mov rax, [%%SRC2+8*7] + mul %%OP ; rdx:rax = OP * [] + add %%X7, rax + adc rdx, 0 + add %%X7, %%TMP + adc rdx, 0 + mov %%X0, rdx + %endif + %endif + %endif + %endif + %endif + %endif + %endif +%endmacro + + +;;; Inputs: pDst: Destination (1024 bits, 16 qwords) +;;; pA: Multiplicand (512 bits, 8 qwords) +;;; pB: Multiplicand (512 bits, 8 qwords) +;;; +;;; +;;; Uses registers rax, rdx, args and rbp, rbx +;;; B operand in [pB] and also in x7...x0 +%macro MUL_NxN 7-14.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pA %3 + %xdefine %%pB %4 + %xdefine %%OP %5 + %xdefine %%TMP %6 + %xdefine %%X7 %7 + %xdefine %%X6 %8 + %xdefine %%X5 %9 + %xdefine %%X4 %10 + %xdefine %%X3 %11 + %xdefine %%X2 %12 + %xdefine %%X1 %13 + %xdefine %%X0 %14 + +mov %%OP, [%%pA+8*0] + + mov rax, %%X0 + mul %%OP ; rdx:rax = OP * [] + mov [%%pDst+8*0], rax + mov %%X0, rdx + + %if %%N > 1 + mov rax, %%X1 + mul %%OP ; rdx:rax = OP * [] + add %%X0, rax + adc rdx, 0 + mov %%X1, rdx + %endif + + %if %%N > 2 + mov rax, %%X2 + mul %%OP ; rdx:rax = OP * [] + add %%X1, rax + adc rdx, 0 + mov %%X2, rdx + %endif + + %if %%N > 3 + mov rax, %%X3 + mul %%OP ; rdx:rax = OP * [] + add %%X2, rax + adc rdx, 0 + mov %%X3, rdx + %endif + + %if %%N > 4 + mov rax, %%X4 + mul %%OP ; rdx:rax = OP * [] + add %%X3, rax + adc rdx, 0 + mov %%X4, rdx + %endif + + %if %%N > 5 + mov rax, %%X5 + mul %%OP ; rdx:rax = OP * [] + add %%X4, rax + adc rdx, 0 + mov %%X5, rdx + %endif + + %if %%N > 6 + mov rax, %%X6 + mul %%OP ; rdx:rax = OP * [] + add %%X5, rax + adc rdx, 0 + mov %%X6, rdx + %endif + + %if %%N > 7 + mov rax, %%X7 + mul %%OP ; rdx:rax = OP * [] + add %%X6, rax + adc rdx, 0 + mov %%X7, rdx + %endif + + %if %%N > 1 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; {X0,X7,X6,X5,X4,X3,X2,X1},pDst[1] = pA[1]*pB[] + {X7,X6,X5,X4,X3,X2,X1,X0} + mov %%OP, [%%pA+sizeof(qword)*1] + MLA_FIX {%%N},[%%pDst+sizeof(qword)*1],{%%pB},{%%OP},{%%TMP},{%%X7},{%%X6},{%%X5},{%%X4},{%%X3},{%%X2},{%%X1},{%%X0} + %endif + + %if %%N > 2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; {X1,X0,X7,X6,X5,X4,X3,X2},pDst[2] = pA[2]*pB[] + {X0,X7,X6,X5,X4,X3,X2,X1} + mov %%OP, [%%pA+sizeof(qword)*2] + MLA_FIX {%%N},[%%pDst+sizeof(qword)*2],{%%pB},{%%OP},{%%TMP},{%%X0},{%%X7},{%%X6},{%%X5},{%%X4},{%%X3},{%%X2},{%%X1} + %endif + + %if %%N > 3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; {X2,X1,X0,X7,X6,X5,X4,X3},pDst[3] = pA[3]*pB[] + {X1,X0,X7,X6,X5,X4,X3,X2} + mov %%OP, [%%pA+sizeof(qword)*3] + MLA_FIX {%%N},[%%pDst+sizeof(qword)*3],{%%pB},{%%OP},{%%TMP},{%%X1},{%%X0},{%%X7},{%%X6},{%%X5},{%%X4},{%%X3},{%%X2} + %endif + + %if %%N > 4 + ; {X3,X2,X1,X0,X7,X6,X5,X4},pDst[4] = pA[4]*pB[] + {X2,X1,X0,X7,X6,X5,X4,X3} + mov %%OP, [%%pA+sizeof(qword)*4] + MLA_FIX {%%N},[%%pDst+sizeof(qword)*4],{%%pB},{%%OP},{%%TMP},{%%X2},{%%X1},{%%X0},{%%X7},{%%X6},{%%X5},{%%X4},{%%X3} + %endif + + %if %%N > 5 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; {X4,X3,X2,X1,X0,X7,X6,X5},pDst[5] = pA[5]*pB[] + {X3,X2,X1,X0,X7,X6,X5,X4} + mov %%OP, [%%pA+sizeof(qword)*5] + MLA_FIX {%%N},[%%pDst+sizeof(qword)*5],{%%pB},{%%OP},{%%TMP},{%%X3},{%%X2},{%%X1},{%%X0},{%%X7},{%%X6},{%%X5},{%%X4} + %endif + + %if %%N > 6 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; {X5,X4,X3,X2,X1,X0,X7,X6},pDst[6] = pA[6]*pB[] + {X4,X3,X2,X1,X0,X7,X6,X5} + mov %%OP, [%%pA+sizeof(qword)*6] + MLA_FIX {%%N},[%%pDst+sizeof(qword)*6],{%%pB},{%%OP},{%%TMP},{%%X4},{%%X3},{%%X2},{%%X1},{%%X0},{%%X7},{%%X6},{%%X5} + %endif + + %if %%N > 7 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; {X6,X5,X4,X3,X2,X1,X0,X7},pDst[7] = pA[7]*pB[] + {X5,X4,X3,X2,X1,X0,X7,X6} + mov %%OP, [%%pA+sizeof(qword)*7] + MLA_FIX {%%N},[%%pDst+sizeof(qword)*7],{%%pB},{%%OP},{%%TMP},{%%X5},{%%X4},{%%X3},{%%X2},{%%X1},{%%X0},{%%X7},{%%X6} + %endif + + %if %%N > 7 + mov qword [%%pDst+sizeof(qword)*8], %%X7 + mov qword [%%pDst+sizeof(qword)*9], %%X0 + mov qword [%%pDst+sizeof(qword)*10], %%X1 + mov qword [%%pDst+sizeof(qword)*11], %%X2 + mov qword [%%pDst+sizeof(qword)*12], %%X3 + mov qword [%%pDst+sizeof(qword)*13], %%X4 + mov qword [%%pDst+sizeof(qword)*14], %%X5 + mov qword [%%pDst+sizeof(qword)*15], %%X6 + %elif %%N > 6 + mov qword [%%pDst+sizeof(qword)*7], %%X6 + mov qword [%%pDst+sizeof(qword)*8], %%X7 + mov qword [%%pDst+sizeof(qword)*9], %%X0 + mov qword [%%pDst+sizeof(qword)*10], %%X1 + mov qword [%%pDst+sizeof(qword)*11], %%X2 + mov qword [%%pDst+sizeof(qword)*12], %%X3 + mov qword [%%pDst+sizeof(qword)*13], %%X4 + %elif %%N > 5 + mov qword [%%pDst+sizeof(qword)*6], %%X5 + mov qword [%%pDst+sizeof(qword)*7], %%X6 + mov qword [%%pDst+sizeof(qword)*8], %%X7 + mov qword [%%pDst+sizeof(qword)*9], %%X0 + mov qword [%%pDst+sizeof(qword)*10], %%X1 + mov qword [%%pDst+sizeof(qword)*11], %%X2 + %elif %%N > 4 + mov qword [%%pDst+sizeof(qword)*5], %%X4 + mov qword [%%pDst+sizeof(qword)*6], %%X5 + mov qword [%%pDst+sizeof(qword)*7], %%X6 + mov qword [%%pDst+sizeof(qword)*8], %%X7 + mov qword [%%pDst+sizeof(qword)*9], %%X0 + %elif %%N > 3 + mov qword [%%pDst+sizeof(qword)*4], %%X3 + mov qword [%%pDst+sizeof(qword)*5], %%X4 + mov qword [%%pDst+sizeof(qword)*6], %%X5 + mov qword [%%pDst+sizeof(qword)*7], %%X6 + %elif %%N > 2 + mov qword [%%pDst+sizeof(qword)*3], %%X2 + mov qword [%%pDst+sizeof(qword)*4], %%X3 + mov qword [%%pDst+sizeof(qword)*5], %%X4 + %elif %%N > 1 + mov qword [%%pDst+sizeof(qword)*2], %%X1 + mov qword [%%pDst+sizeof(qword)*3], %%X2 + %else + mov qword [%%pDst+sizeof(qword)*1], %%X0 + %endif ;; N==2 + +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MULx1 genaral-case multiplier macros +;; + +;; dst = src * B (body) +%macro MULx1 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%B %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + align 16 +%%L_1: + mul %%B + xor %%T1, %%T1 + add %%T0, rax + mov qword [%%rDst+%%idx*sizeof(qword)], %%T0 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] + adc %%T1, rdx + + mul %%B + xor %%T2, %%T2 + add %%T1, rax + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T1 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] + adc %%T2, rdx + + mul %%B + xor %%T3, %%T3 + add %%T2, rax + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T2 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] + adc %%T3, rdx + + mul %%B + xor %%T0, %%T0 + add %%T3, rax + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3], %%T3 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] + adc %%T0, rdx + + add %%idx, 4 + jnc %%L_1 +%endmacro + + +;; dst = src * B epilogue (srcLen=4*n+4) +%macro MULx1_4N_4_ELOG 7.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B %3 + %xdefine %%T0 %4 + %xdefine %%T1 %5 + %xdefine %%T2 %6 + %xdefine %%T3 %7 + + mul %%B + xor %%T1, %%T1 + add %%T0, rax + mov qword [%%rDst], %%T0 + mov rax, qword [%%rSrc+sizeof(qword)] + adc %%T1, rdx + + mul %%B + xor %%T2, %%T2 + add %%T1, rax + mov qword [%%rDst+sizeof(qword)], %%T1 + mov rax, qword [%%rSrc+sizeof(qword)*2] + adc %%T2, rdx + + mul %%B + xor %%T3, %%T3 + add %%T2, rax + mov qword [%%rDst+sizeof(qword)*2], %%T2 + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T3, rdx + + mul %%B + mov idx, qword [rsp+counterA] + add %%T3, rax + mov qword [%%rDst+sizeof(qword)*3], %%T3 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, 0 + ;mov rbp, rax + + mov qword [%%rDst+sizeof(qword)*4], rdx + add %%rDst, sizeof(qword) +%endmacro + + +;; dst = src * B epilogue (srcLen=4*n+3) +%macro MULx1_4N_3_ELOG 7.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B %3 + %xdefine %%T0 %4 + %xdefine %%T1 %5 + %xdefine %%T2 %6 + %xdefine %%T3 %7 + + mul %%B + xor %%T1, %%T1 + add %%T0, rax + mov qword [%%rDst+sizeof(qword)], %%T0 + mov rax, qword [%%rSrc+sizeof(qword)*2] + adc %%T1, rdx + + mul %%B + xor %%T2, %%T2 + add %%T1, rax + mov qword [%%rDst+sizeof(qword)*2], %%T1 + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T2, rdx + + mul %%B + mov idx, qword [rsp+counterA] + add %%T2, rax + mov qword [%%rDst+sizeof(qword)*3], %%T2 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, 0 + ;mov rbp, rax + + mov qword [%%rDst+sizeof(qword)*4], rdx + add %%rDst, sizeof(qword) +%endmacro + + +;; dst = src * B epilogue (srcLen=4*n+2) +%macro MULx1_4N_2_ELOG 7.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B %3 + %xdefine %%T0 %4 + %xdefine %%T1 %5 + %xdefine %%T2 %6 + %xdefine %%T3 %7 + + mul %%B + xor %%T1, %%T1 + add %%T0, rax + mov qword [%%rDst+sizeof(qword)*2], %%T0 + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T1, rdx + + mul %%B + mov idx, qword [rsp+counterA] + add %%T1, rax + mov qword [%%rDst+sizeof(qword)*3], %%T1 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, 0 + ;mov rbp, rax + + mov qword [%%rDst+sizeof(qword)*4], rdx + add %%rDst, sizeof(qword) +%endmacro + + +;; dst = src * B epilogue (srcLen=4*n+1) +%macro MULx1_4N_1_ELOG 7.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B %3 + %xdefine %%T0 %4 + %xdefine %%T1 %5 + %xdefine %%T2 %6 + %xdefine %%T3 %7 + + mul %%B + mov idx, qword [rsp+counterA] + add %%T0, rax + mov qword [%%rDst+sizeof(qword)*3], %%T0 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, 0 + ;mov rbp, rax + + mov qword [%%rDst+sizeof(qword)*4], rdx + add %%rDst, sizeof(qword) +%endmacro + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MULx2 genaral-case multiplier macros +;; + +; dst = src*{B1:B0} +%macro MULx2 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%B0 %4 + %xdefine %%B1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + align IPP_ALIGN_FACTOR +%%L_1: + mul %%B1 ; {T2:T1} += a[i]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] ; a[i+1] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[i+1]*B0 + mov qword [%%rDst+%%idx*sizeof(qword)], %%T0 + add %%T1, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] ; a[i+1] + adc %%T2, rdx + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[i+1]*B1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] ; a[i+2] + adc %%T3, rdx + + mul %%B0 ; {T0:T3:T2} += a[i+2]*B0 + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T1 + add %%T2, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] ; a[i+2] + adc %%T3, rdx + adc %%T0, 0 + + mul %%B1 ; {T0:T3} += a[i+2]*B1 + xor %%T1, %%T1 + add %%T3, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] ; a[i+3] + adc %%T0, rdx + + mul %%B0 ; {T1:T0:T3} += a[i+3]*B0 + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T2 + add %%T3, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] ; a[i+3] + adc %%T0, rdx + adc %%T1, 0 + + mul %%B1 ; {T1:T0} += a[i+3]*B1 + xor %%T2, %%T2 + add %%T0, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] ; a[i+4] + adc %%T1, rdx + + mul %%B0 ; {T2:T1:T0} += a[i+4]*B0 + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3], %%T3 + add %%T0, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] ; a[i+4] + adc %%T1, rdx + adc %%T2, 0 + + add %%idx, 4 + jnc %%L_1 +%endmacro + + +;; dst = src * {B1:B0} epilogue (srcLen=4*n+1) +%macro MULx2_4N_1_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-1]*B1 + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T0 + add %%T1, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T2 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T1 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = src * {B1:B0} epilogue (srcLen=4*n+2) +%macro MULx2_4N_2_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-2]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[LenA-1]*B0 + mov qword [%%rDst+sizeof(qword)*2], %%T0 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T2, rdx + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[lenA-1]*B1 + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T1 + add %%T2, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T3 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T2 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = src * {B1:B0} epilogue (srcLen=4*n+3) +%macro MULx2_4N_3_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-3]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[LenA-2]*B0 + mov qword [%%rDst+sizeof(qword)], %%T0 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[lenA-2]*B1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T3, rdx + + mul %%B0 ; {T0:T3:T2} += a[lenA-1]*B0 + mov qword [%%rDst+sizeof(qword)*2], %%T1 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T3, rdx + adc %%T0, 0 + + mul %%B1 ; {T0:T3} += a[lenA-1]*B1 + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T2 + add %%T3, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T0 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T3 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = src * {B1:B0} epilogue (srcLen=4*n+4) +%macro MULx2_4N_4_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-4]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[lenA-3]*B0 + mov qword [%%rDst], %%T0 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + adc %%T2, rdx + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[lenA-3]*B1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + adc %%T3, rdx + + mul %%B0 ; {T0:T3:T2} += a[aLen-2]*B0 + mov qword [%%rDst+sizeof(qword)], %%T1 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + adc %%T3, rdx + adc %%T0, 0 + + mul %%B1 ; {T0:T3} += a[lenA-2]*B1 + xor %%T1, %%T1 + add %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T0, rdx + + mul %%B0 ; {T1:T0:T3} += a[lenA-1]*B0 + mov qword [%%rDst+sizeof(qword)*2], %%T2 + add %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T0, rdx + adc %%T1, 0 + + mul %%B1 ; {T1:T0} += a[lenA-1]*B1 + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T3 + add %%T0, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T1 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T0 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MLAx2 genaral-case multiplier macros +;; + +%macro MLAx2_PLOG 7.nolist + %xdefine %%B0 %1 + %xdefine %%B1 %2 + %xdefine %%dataB %3 + %xdefine %%T0 %4 + %xdefine %%T1 %5 + %xdefine %%T2 %6 + %xdefine %%T3 %7 + + mov %%B0, qword [%%dataB] + mul %%B0 ; {T2:T1:T0} = a[0]*b[i] + mov %%B1, qword [%%dataB+sizeof(qword)] + xor %%T2, %%T2 + mov %%T0, rax + mov rax, qword [rSrc+idx*sizeof(qword)] ; a[i] + mov %%T1, rdx +%endmacro + + + +%if (_IPP32E <= _IPP32E_Y8) +;; +;; Pre- Sandy Bridge specific code +;; + +%macro MLAx2 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%B0 %4 + %xdefine %%B1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + +align IPP_ALIGN_FACTOR +%%L_1: + mul %%B1 ; {T2:T1} += a[i]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] ; a[i+1] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[i+1]*B0 + r[i] + add %%T0, qword [%%rDst+%%idx*sizeof(qword)] + adc %%T1, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] ; a[i+1] + adc %%T2, rdx + mov qword [%%rDst+%%idx*sizeof(qword)], %%T0 + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[i+1]*B1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] ; a[i+2] + adc %%T3, rdx + + mul %%B0 ; {T0:T3:T2} += a[i+2]*B0 + r[i+1] + add %%T1, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)] + adc %%T2, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] ; a[i+2] + adc %%T3, rdx + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T1 + adc %%T0, 0 + + mul %%B1 ; {T0:T3} += a[i+2]*B1 + xor %%T1, %%T1 + add %%T3, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] ; a[i+3] + adc %%T0, rdx + + mul %%B0 ; {T1:T0:T3} += a[i+3]*B0 + r[i+2] + add %%T2, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2] + adc %%T3, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] ; a[i+3] + adc %%T0, rdx + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T2 + adc %%T1, 0 + + mul %%B1 ; {T1:T0} += a[i+3]*B1 + xor %%T2, %%T2 + add %%T0, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] ; a[i+4] + adc %%T1, rdx + + mul %%B0 ; {T2:T1:T0} += a[i+4]*B0 + r[i+3] + add %%T3, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3] + adc %%T0, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] ; a[i+4] + adc %%T1, rdx + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3], %%T3 + adc %%T2, 0 + + add %%idx, 4 + jnc %%L_1 +%endmacro + + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+1) +%macro MLAx2_4N_1_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T0, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T0 + adc %%T1, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T2 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T1 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = dst + src * {B1:B0} epilogue (srcLen=4*n+2) +%macro MLAx2_4N_2_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-2]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[lenA-1]*B0 + r[lenA-2] + add %%T0, qword [%%rDst+sizeof(qword)*2] + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T2, rdx + mov qword [%%rDst+sizeof(qword)*2], %%T0 + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T1, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T1 + adc %%T2, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T3 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T2 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+3) +%macro MLAx2_4N_3_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-3]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[LenA-2]*B0 + r[len-3] + add %%T0, qword [%%rDst+sizeof(qword)] + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + mov qword [%%rDst+sizeof(qword)], %%T0 + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[lenA-2]*B1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T3, rdx + + mul %%B0 ; {T0:T3:T2} += a[lenA-1]*B0 + r[lenA-2] + add %%T1, qword [%%rDst+sizeof(qword)*2] + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T3, rdx + mov qword [%%rDst+sizeof(qword)*2], %%T1 + adc %%T0, 0 + + mul %%B1 ; {T0:T3} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T2, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T2 + adc %%T3, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T0 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T3 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+4) +%macro MLAx2_4N_4_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-4]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[lenA-3]*B0 + r[lenA-4] + add %%T0, qword [%%rDst] + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + adc %%T2, rdx + mov qword [%%rDst], %%T0 + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[lenA-3]*B1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + adc %%T3, rdx + + mul %%B0 ; {T0:T3:T2} += a[aLen-2]*B0 + r[lenA-3] + add %%T1, qword [%%rDst+sizeof(qword)] + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + adc %%T3, rdx + mov qword [%%rDst+sizeof(qword)], %%T1 + adc %%T0, 0 + + mul %%B1 ; {T0:T3} += a[lenA-2]*B1 + xor %%T1, %%T1 + add %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T0, rdx + + mul %%B0 ; {T1:T0:T3} += a[lenA-1]*B0 + r[lenA-2] + add %%T2, qword [%%rDst+sizeof(qword)*2] + adc %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T0, rdx + mov qword [%%rDst+sizeof(qword)*2], %%T2 + adc %%T1, 0 + + mul %%B1 ; {T1:T0} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T3, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T3 + adc %%T0, rax + mov rax, qword [%%rSrc+idx*sizeof(qword)] + adc rdx, %%T1 + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T0 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + +%endif + +%if (_IPP32E >= _IPP32E_E9) +;; +;; Sandy Bridge specific code +;; +%macro MLAx2 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%B0 %4 + %xdefine %%B1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + +align IPP_ALIGN_FACTOR +%%L_1: + mul %%B1 ; {T2:T1} += a[i]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] ; a[i+1] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[i+1]*B0 + r[i] + add %%T0, qword [%%rDst+%%idx*sizeof(qword)] + mov qword [%%rDst+%%idx*sizeof(qword)], %%T0 + adc %%T1, rax + adc %%T2, rdx + adc %%T3, 0 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] ; a[i+1] + + mul %%B1 ; {T3:T2} += a[i+1]*B1 + xor %%T0, %%T0 + add %%T2, rax + adc %%T3, rdx + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] ; a[i+2] + + mul %%B0 ; {T0:T3:T2} += a[i+2]*B0 + r[i+1] + add %%T1, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T1 + adc %%T2, rax + adc %%T3, rdx + adc %%T0, 0 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] ; a[i+2] + + mul %%B1 ; {T0:T3} += a[i+2]*B1 + xor %%T1, %%T1 + add %%T3, rax + adc %%T0, rdx + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] ; a[i+3] + + mul %%B0 ; {T1:T0:T3} += a[i+3]*B0 + r[i+2] + add %%T2, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T2 + adc %%T3, rax + adc %%T0, rdx + adc %%T1, 0 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] ; a[i+3] + + mul %%B1 ; {T1:T0} += a[i+3]*B1 + xor %%T2, %%T2 + add %%T0, rax + adc %%T1, rdx + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] ; a[i+4] + + mul %%B0 ; {T2:T1:T0} += a[i+4]*B0 + r[i+3] + add %%T3, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3], %%T3 + adc %%T0, rax + adc %%T1, rdx + adc %%T2, 0 + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] ; a[i+4] + + add %%idx, 4 + jnc %%L_1 +%endmacro + + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+1) +%macro MLAx2_4N_1_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T0, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T0 + adc %%T1, rax + adc rdx, %%T2 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T1 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = dst + src * {B1:B0} epilogue (srcLen=4*n+2) +%macro MLAx2_4N_2_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-2]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[lenA-1]*B0 + r[lenA-2] + add %%T0, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T0 + adc %%T1, rax + adc %%T2, rdx + adc %%T3, 0 + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + + mul %%B1 ; {T3:T2} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T1, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T1 + adc %%T2, rax + adc rdx, %%T3 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T2 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+3) +%macro MLAx2_4N_3_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-3]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[LenA-2]*B0 + r[len-3] + add %%T0, qword [%%rDst+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T0 + adc %%T1, rax + adc %%T2, rdx + adc %%T3, 0 + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + + mul %%B1 ; {T3:T2} += a[lenA-2]*B1 + xor %%T0, %%T0 + add %%T2, rax + adc %%T3, rdx + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + + mul %%B0 ; {T0:T3:T2} += a[lenA-1]*B0 + r[lenA-2] + add %%T1, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T1 + adc %%T2, rax + adc %%T3, rdx + adc %%T0, 0 + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + + mul %%B1 ; {T0:T3} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T2, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T2 + adc %%T3, rax + adc rdx, %%T0 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T3 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+4) +%macro MLAx2_4N_4_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B1 ; {T2:T1} += a[lenA-4]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[lenA-3]*B0 + r[lenA-4] + add %%T0, qword [%%rDst] + mov qword [%%rDst], %%T0 + adc %%T1, rax + adc %%T2, rdx + adc %%T3, 0 + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + + mul %%B1 ; {T3:T2} += a[lenA-3]*B1 + xor %%T0, %%T0 + add %%T2, rax + adc %%T3, rdx + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + + mul %%B0 ; {T0:T3:T2} += a[aLen-2]*B0 + r[lenA-3] + add %%T1, qword [%%rDst+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T1 + adc %%T2, rax + adc %%T3, rdx + adc %%T0, 0 + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + + mul %%B1 ; {T0:T3} += a[lenA-2]*B1 + xor %%T1, %%T1 + add %%T3, rax + adc %%T0, rdx + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + + mul %%B0 ; {T1:T0:T3} += a[lenA-1]*B0 + r[lenA-2] + add %%T2, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T2 + adc %%T3, rax + adc %%T0, rdx + adc %%T1, 0 + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + + mul %%B1 ; {T1:T0} += a[lenA-1]*B1 + r[lenA-1] + add %%rDst, sizeof(qword)*2 + mov idx, [rsp+counterA] + add %%T3, qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*3-sizeof(qword)*2], %%T3 + adc %%T0, rax + adc rdx, %%T1 + mov rax, qword [%%rSrc+idx*sizeof(qword)] + + mov qword [%%rDst+sizeof(qword)*4-sizeof(qword)*2], %%T0 + mov qword [%%rDst+sizeof(qword)*5-sizeof(qword)*2], rdx +%endmacro + +%endif +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolm7as.asm new file mode 100644 index 000000000..f6f6a2c47 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolm7as.asm @@ -0,0 +1,379 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpMulAdc_BNU_school() +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpbnumulschool.inc" +%include "pcpvariant.inc" + +%if (_ADCOX_NI_ENABLING_ == _FEATURE_OFF_) || (_ADCOX_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_M7) && (_IPP32E < _IPP32E_L9) + + +segment .text align=IPP_ALIGN_FACTOR + + +;************************************************************* +;* Ipp64u cpMulAdc_BNU_school(Ipp64u* pR; +;* const Ipp64u* pA, int aSize, +;* const Ipp64u* pB, int bSize) +;* returns pR[aSize+bSize] +;* +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMulAdc_BNU_school,PUBLIC +%assign LOCAL_FRAME (1*sizeof(qword)) + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 5 + +; rdi = pDst +; rsi = pSrcA +; edx = lenA +; rcx = pSrcB +; r8d = lenB + +;; +;; stack structure: +;;counterB = (0) +;;counterA = (counterB+sizeof(qword)) +%assign counterA (0) + + + cmp edx, r8d + jl .general_case_mul_entry + jg .general_case_mul +%if (_IPP32E < _IPP32E_E9) + cmp edx, 4 +%else + cmp edx, 8 +%endif + jg .general_case_mul + +%if (_IPP32E >= _IPP32E_E9) + cmp edx, 4 + jg .more_then_4 +%endif + + cmp edx, 3 + ja .mul_4x4 + jz .mul_3x3 + jp .mul_2x2 + ; mul_1x1 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; fixed-size multipliers (1-4) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +.mul_1x1: + mov rax, qword [rsi] + mul qword [rcx] + mov qword [rdi], rax + mov qword [rdi+sizeof(qword)], rdx + mov rax, qword [rdi+sizeof(qword)*1] + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.mul_2x2: + mov r8, [rcx] + mov r9, [rcx+sizeof(qword)*1] + MUL_NxN 2, rdi, rsi, rcx, rbx, rbp, r15, r14, r13, r12, r11, r10, r9, r8 + mov rax, qword [rdi+sizeof(qword)*3] + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.mul_3x3: + mov r8, [rcx] + mov r9, [rcx+sizeof(qword)*1] + mov r10,[rcx+sizeof(qword)*2] + MUL_NxN 3, rdi, rsi, rcx, rbx, rbp, r15, r14, r13, r12, r11, r10, r9, r8 + mov rax, qword [rdi+sizeof(qword)*5] + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.mul_4x4: + mov r8, [rcx] + mov r9, [rcx+sizeof(qword)*1] + mov r10,[rcx+sizeof(qword)*2] + mov r11,[rcx+sizeof(qword)*3] + MUL_NxN 4, rdi, rsi, rcx, rbx, rbp, r15, r14, r13, r12, r11, r10, r9, r8 + mov rax, qword [rdi+sizeof(qword)*7] + REST_XMM + REST_GPR + ret + +%if (_IPP32E >= _IPP32E_E9) +.more_then_4: + cmp edx, 7 + ja .mul_8x8 + jz .mul_7x7 + jp .mul_6x6 + ; mul_5x5 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; fixed-size multipliers (5-8) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +.mul_5x5: + mov r8, [rcx] + mov r9, [rcx+sizeof(qword)*1] + mov r10,[rcx+sizeof(qword)*2] + mov r11,[rcx+sizeof(qword)*3] + mov r12,[rcx+sizeof(qword)*4] + MUL_NxN 5, rdi, rsi, rcx, rbx, rbp, r15, r14, r13, r12, r11, r10, r9, r8 + mov rax, qword [rdi+sizeof(qword)*9] + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.mul_6x6: + mov r8, [rcx] + mov r9, [rcx+sizeof(qword)*1] + mov r10,[rcx+sizeof(qword)*2] + mov r11,[rcx+sizeof(qword)*3] + mov r12,[rcx+sizeof(qword)*4] + mov r13,[rcx+sizeof(qword)*5] + MUL_NxN 6, rdi, rsi, rcx, rbx, rbp, r15, r14, r13, r12, r11, r10, r9, r8 + mov rax, qword [rdi+sizeof(qword)*11] + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.mul_7x7: + mov r8, [rcx] + mov r9, [rcx+sizeof(qword)*1] + mov r10,[rcx+sizeof(qword)*2] + mov r11,[rcx+sizeof(qword)*3] + mov r12,[rcx+sizeof(qword)*4] + mov r13,[rcx+sizeof(qword)*5] + mov r14,[rcx+sizeof(qword)*6] + MUL_NxN 7, rdi, rsi, rcx, rbx, rbp, r15, r14, r13, r12, r11, r10, r9, r8 + mov rax, qword [rdi+sizeof(qword)*13] + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.mul_8x8: + mov r8, [rcx] + mov r9, [rcx+sizeof(qword)*1] + mov r10,[rcx+sizeof(qword)*2] + mov r11,[rcx+sizeof(qword)*3] + mov r12,[rcx+sizeof(qword)*4] + mov r13,[rcx+sizeof(qword)*5] + mov r14,[rcx+sizeof(qword)*6] + mov r15,[rcx+sizeof(qword)*7] + MUL_NxN 8, rdi, rsi, rcx, rbx, rbp, r15, r14, r13, r12, r11, r10, r9, r8 + mov rax, qword [rdi+sizeof(qword)*15] + REST_XMM + REST_GPR + ret +%endif + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; general case multiplier +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +.general_case_mul_entry: + ; swap operands %if lenA < lenB then exchange operands + xor rsi, rcx + xor edx, r8d + xor rcx, rsi + xor r8d, edx + xor rsi, rcx + xor edx, r8d + +%xdefine B0 r10 ; b[i], b[i+1] +%xdefine B1 r11 + +%xdefine T0 r12 ; temporary +%xdefine T1 r13 +%xdefine T2 r14 +%xdefine T3 r15 + +%xdefine idx rbx ; index +%xdefine rDst rdi +%xdefine rSrc rsi + +align IPP_ALIGN_FACTOR +.general_case_mul: + movsxd rdx, edx ; expand length + movsxd r8, r8d + + lea rdi, [rdi+rdx*sizeof(qword)-sizeof(qword)*4] ; rdi = &R[lenA-4] + lea rsi, [rsi+rdx*sizeof(qword)-sizeof(qword)*4] ; rsi = &A[lenA-4] + + mov idx, dword 4 ; negative + sub idx, rdx ; A-counter + mov qword [rsp+counterA], idx + + mov rax, qword [rsi+idx*sizeof(qword)] ; a[0] + mov B0, qword [rcx] ; b[0] + test r8, 1 + jz .init_even_B + +;********** lenSrcB = 2*n+ 1 (multiply only) ********************* +.init_odd_B: + xor T0, T0 + cmp idx, 0 + jge .skip_mul1 + + MULx1 rdi, rsi, idx, B0, T0, T1, T2, T3 + +.skip_mul1: + cmp idx, 2 + ja .fin_mul1x4n_1 ; idx=3 + jz .fin_mul1x4n_2 ; idx=2 + jp .fin_mul1x4n_3 ; idx=1 + ; fin_mul1x4n_4 ; idx=0 + +.fin_mul1x4n_4: + MULx1_4N_4_ELOG rdi, rsi, B0, T0,T1,T2,T3 + add rcx, sizeof(qword) + add r8, 1 + jmp .mla2x4n_4 +.fin_mul1x4n_3: + MULx1_4N_3_ELOG rdi, rsi, B0, T0,T1,T2,T3 + add rcx, sizeof(qword) + add r8, 1 + jmp .mla2x4n_3 +.fin_mul1x4n_2: + MULx1_4N_2_ELOG rdi, rsi, B0, T0,T1,T2,T3 + add rcx, sizeof(qword) + add r8, 1 + jmp .mla2x4n_2 +.fin_mul1x4n_1: + MULx1_4N_1_ELOG rdi, rsi, B0, T0,T1,T2,T3 + add rcx, sizeof(qword) + add r8, 1 + jmp .mla2x4n_1 + + +;********** lenSrcB = 2*n (multiply only) ************************ +.init_even_B: + mov rbp, rax + mul B0 ; {T2:T1:T0} = a[0]*B0 + mov B1, qword [rcx+sizeof(qword)] + xor T2, T2 + mov T0, rax + mov rax, rbp ; restore a[0] + mov T1, rdx + + cmp idx, 0 + jge .skip_mul_nx2 + + MULx2 rdi, rsi, idx, B0,B1, T0,T1,T2,T3 + +.skip_mul_nx2: + cmp idx, 2 + ja .fin_mul2x4n_1 ; idx=3 + jz .fin_mul2x4n_2 ; idx=2 + jp .fin_mul2x4n_3 ; idx=1 + ; fin_mul2x4n_4 ; idx=0 + +.fin_mul2x4n_4: + MULx2_4N_4_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 +align IPP_ALIGN_FACTOR +.mla2x4n_4: + sub r8, 2 + jz .quit + MLAx2_PLOG B0,B1, rcx, T0,T1,T2,T3 + cmp idx, 0 + jz .skip_mla_x2 + MLAx2 rdi, rsi, idx, B0,B1, T0,T1,T2,T3 +.skip_mla_x2: + MLAx2_4N_4_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 + jmp .mla2x4n_4 + +.fin_mul2x4n_3: + MULx2_4N_3_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 +align IPP_ALIGN_FACTOR +.mla2x4n_3: + sub r8, 2 + jz .quit + MLAx2_PLOG B0,B1, rcx, T0,T1,T2,T3 + MLAx2 rdi, rsi, idx, B0,B1, T0,T1,T2,T3 + MLAx2_4N_3_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 + jmp .mla2x4n_3 + +.fin_mul2x4n_2: + MULx2_4N_2_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 +align IPP_ALIGN_FACTOR +.mla2x4n_2: + sub r8, 2 + jz .quit + MLAx2_PLOG B0,B1, rcx, T0,T1,T2,T3 + MLAx2 rdi, rsi, idx, B0,B1, T0,T1,T2,T3 + MLAx2_4N_2_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 + jmp .mla2x4n_2 + +.fin_mul2x4n_1: + MULx2_4N_1_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 +align IPP_ALIGN_FACTOR +.mla2x4n_1: + sub r8, 2 + jz .quit + MLAx2_PLOG B0,B1, rcx, T0,T1,T2,T3 + MLAx2 rdi, rsi, idx, B0,B1, T0,T1,T2,T3 + MLAx2_4N_1_ELOG rdi, rsi, B0,B1, T0,T1,T2,T3 + add rcx, sizeof(qword)*2 + jmp .mla2x4n_1 + +.quit: + mov rax, rdx + + REST_XMM + REST_GPR + ret +ENDFUNC cpMulAdc_BNU_school + +%endif + +%endif ;; _ADCOX_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolsrvl9.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolsrvl9.asm new file mode 100644 index 000000000..5c495bfb6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolsrvl9.asm @@ -0,0 +1,308 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Multiplicative Operations +; +; Content: +; cpMulAdc_BNU_school() +; cpSqrAdc_BNU_school() +; cpMontRedAdc_BNU() +; +; Implementation is using mulx and adcx/adox instruvtions +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ADCOX_NI_ENABLING_ == _FEATURE_ON_) || (_ADCOX_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_L9) + +%assign _xEMULATION_ 1 + +segment .text align=IPP_ALIGN_FACTOR + + +%include "pcpbnumul.inc" +%include "pcpbnusqr.inc" +%include "pcpmred.inc" + +;************************************************************* +;* Ipp64u cpMulAdc_BNU_school(Ipp64u* pR; +;* const Ipp64u* pA, int aSize, +;* const Ipp64u* pB, int bSize) +;* +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMulAdc_BNU_school,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 5 + +; rdi = pR +; rsi = pA +; edx = nsA +; rcx = pB +; r8d = nsB + + movsxd rdx, edx ; expand length + movsxd rbx, r8d + + xor r8, r8 ; clear scratch + xor r9, r9 + xor r10, r10 + xor r11, r11 + xor r12, r12 + xor r13, r13 + xor r14, r14 + xor r15, r15 + + cmp rdx, rbx + jl .swap_operans ; nsA < nsB + jg .test_8N_case ; test %if nsA=8*N and nsB=8*M + + cmp rdx, 16 + jg .test_8N_case + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short nsA==nsB (1,..,16) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp rdx, 4 + jg .more_then_4 + + cmp edx, 3 + ja .mul_4_4 + jz .mul_3_3 + jp .mul_2_2 + ; mul_1_1 + +.mul_1_1: + MUL_NxN 1, rdi, rsi, rcx, rbx,rbp, r8 + jmp .quit +.mul_2_2: + MUL_NxN 2, rdi, rsi, rcx, rbx,rbp, r8,r9 + jmp .quit +.mul_3_3: + MUL_NxN 3, rdi, rsi, rcx, rbx,rbp, r8,r9,r10 + jmp .quit +.mul_4_4: + MUL_NxN 4, rdi, rsi, rcx, rbx,rbp, r8,r9,r10,r11 + jmp .quit + +.more_then_4: + GET_EP rax, mul_lxl_basic, rdx, rbp + call rax + jmp .quit + +.swap_operans: + SWAP rsi, rcx ; swap operands + SWAP rdx, rbx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 8*N x 8*M case multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.test_8N_case: + mov rax, rdx + or rax, rbx + and rax, 7 + jnz .general_mul + + CALL_FUNC mul_8Nx8M + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.general_mul: + CALL_FUNC mul_NxM + jmp .quit + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC cpMulAdc_BNU_school + +;************************************************************* +;* +;* Ipp64u cpSqrAdc_BNU_school(Ipp64u* pR; +;* const Ipp64u* pA, int aSize) +;* +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpSqrAdc_BNU_school,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + + movsxd rdx, edx ; expand length + + xor r8, r8 ; clear scratch + xor r9, r9 + xor r10, r10 + xor r11, r11 + xor r12, r12 + xor r13, r13 + xor r14, r14 + xor r15, r15 + + cmp rdx, 16 + jg .test_8N_case + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short nsA (1,..,16) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + GET_EP rax, sqr_l_basic, rdx, rbp + call rax + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 8N case squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.test_8N_case: + test rdx, 7 + jnz .general_sqr + + CALL_FUNC sqr_8N + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.general_sqr: + CALL_FUNC sqr_N + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC cpSqrAdc_BNU_school + +;************************************************************* +;* +;* Ipp64u cpMontRedAdc_BNU(Ipp64u* pR; +;* Ipp64u* pProduct, +;* const Ipp64u* pModulus, int mSize, +;* Ipp64u m) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMontRedAdc_BNU,PUBLIC +%assign LOCAL_FRAME (0) + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 5 +;pR (rdi) address of the reduction +;pProduct (rsi) address of the temporary product +;pModulus (rdx) address of the modulus +;mSize (rcx) size of the modulus +;m0 (r8) montgomery helper (m') + + mov r15, rdi ; store reduction address + + ; reload parameters for future convinience: + mov rdi, rsi ; rdi = temporary product buffer + mov rsi, rdx ; rsi = modulus + movsxd rdx, ecx ; rdx = length of modulus + + cmp rdx, 16 + ja .test_8N_case ; length of modulus >16 + + cmp rdx, 4 + ja .above4 ; length of modulus 4,..,16 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short modulus (1,..,4) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp rdx, 3 + ja .red_4 + jz .red_3 + jp .red_2 + ; red_1 + +.red_1: + mov r9, qword [rdi+sizeof(qword)*0] + MRED_FIX 1, r15, rdi, rsi, r8, rbp,rbx, r9 + jmp .quit + +.red_2: + mov r9, qword [rdi+sizeof(qword)*0] + mov r10, qword [rdi+sizeof(qword)*1] + MRED_FIX 2, r15, rdi, rsi, r8, rbp,rbx, r9,r10 + jmp .quit + +.red_3: + mov r9, qword [rdi+sizeof(qword)*0] + mov r10, qword [rdi+sizeof(qword)*1] + mov r11, qword [rdi+sizeof(qword)*2] + MRED_FIX 3, r15, rdi, rsi, r8, rbp,rbx, r9,r10,r11 + jmp .quit + +.red_4: + mov r9, qword [rdi+sizeof(qword)*0] + mov r10, qword [rdi+sizeof(qword)*1] + mov r11, qword [rdi+sizeof(qword)*2] + mov r12, qword [rdi+sizeof(qword)*3] + MRED_FIX 4, r15, rdi, rsi, r8, rbp,rbx, r9,r10,r11,r12 + jmp .quit + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short modulus (5,..,16) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.above4: + mov rbp, rdx + sub rbp, 4 + GET_EP rax, mred_short, rbp ; mred procedure + + call rax + jmp .quit + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 8N case squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.test_8N_case: + test rdx, 7 + jnz .general_case + + CALL_FUNC mred_8N + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; general case modulus +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.general_case: + CALL_FUNC mred_N + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC cpMontRedAdc_BNU + +%endif + +%endif ;; _ADCOX_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolsrvl9pp.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolsrvl9pp.asm new file mode 100644 index 000000000..00f47c983 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnumulschoolsrvl9pp.asm @@ -0,0 +1,307 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Multiplicative Operations +; +; Content: +; cpMulAdx_BNU_school() +; cpSqrAdx_BNU_school() +; cpMontRedAdx_BNU() +; +; Implementation is using mulx and adcx/adox instruvtions +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ADCOX_NI_ENABLING_ == _FEATURE_ON_) || (_ADCOX_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_L9) + +%assign _xEMULATION_ 1 +%assign _ADCX_ADOX_ 1 + +segment .text align=IPP_ALIGN_FACTOR + +%include "pcpbnumulpp.inc" +%include "pcpbnusqrpp.inc" +%include "pcpmredpp.inc" + +;************************************************************* +;* Ipp64u cpMulAdx_BNU_school(Ipp64u* pR; +;* const Ipp64u* pA, int aSize, +;* const Ipp64u* pB, int bSize) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMulAdx_BNU_school,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 5 + +; rdi = pR +; rsi = pA +; edx = nsA +; rcx = pB +; r8d = nsB + + movsxd rdx, edx ; expand length + movsxd rbx, r8d + + xor r8, r8 ; clear scratch + xor r9, r9 + xor r10, r10 + xor r11, r11 + xor r12, r12 + xor r13, r13 + xor r14, r14 + xor r15, r15 + + cmp rdx, rbx + jl .swap_operans ; nsA < nsB + jg .test_8N_case ; test %if nsA=8*N and nsB=8*M + + cmp rdx, 16 + jg .test_8N_case + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short nsA==nsB (1,..,16) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp rdx, 4 + jg .more_then_4 + + cmp edx, 3 + ja .mul_4_4 + jz .mul_3_3 + jp .mul_2_2 + ; mul_1_1 + +.mul_1_1: + MUL_NxN 1, rdi, rsi, rcx, rbx, rbp, r8 + jmp .quit +.mul_2_2: + MUL_NxN 2, rdi, rsi, rcx, rbx, rbp, r8, r9 + jmp .quit +.mul_3_3: + MUL_NxN 3, rdi, rsi, rcx, rbx, rbp, r8, r9, r10 + jmp .quit +.mul_4_4: + MUL_NxN 4, rdi, rsi, rcx, rbx, rbp, r8, r9, r10, r11 + jmp .quit + +.more_then_4: + GET_EP rax, mul_lxl_basic, rdx, rbp + call rax + jmp .quit + +.swap_operans: + SWAP rsi, rcx ; swap operands + SWAP rdx, rbx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 8*N x 8*M case multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.test_8N_case: + mov rax, rdx + or rax, rbx + and rax, 7 + jnz .general_mul + + CALL_FUNC mul_8Nx8M_adcox + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case multiplier +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.general_mul: + CALL_FUNC mul_NxM_adcox + jmp .quit + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC cpMulAdx_BNU_school + +;************************************************************* +;* +;* Ipp64u cpSqrAdx_BNU_school(Ipp64u* pR; +;* const Ipp64u* pA, int aSize) +;* +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpSqrAdx_BNU_school,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + + movsxd rdx, edx ; expand length + + xor r8, r8 ; clear scratch + xor r9, r9 + xor r10, r10 + xor r11, r11 + xor r12, r12 + xor r13, r13 + xor r14, r14 + xor r15, r15 + + cmp rdx, 16 + jg .test_8N_case + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short nsA (1,..,16) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + GET_EP rax, sqr_l_basic, rdx, rbp + call rax + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 8N case squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.test_8N_case: + test rdx, 7 + jnz .general_sqr + + CALL_FUNC sqr_8N_adcox + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.general_sqr: + CALL_FUNC sqr_N_adcox + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC cpSqrAdx_BNU_school + +;************************************************************* +;* +;* Ipp64u cpMontRedAdx_BNU(Ipp64u* pR; +;* Ipp64u* pProduct, +;* const Ipp64u* pModulus, int mSize, +;* Ipp64u m) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMontRedAdx_BNU,PUBLIC +%assign LOCAL_FRAME (0) + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 5 +;pR (rdi) address of the reduction +;pProduct (rsi) address of the temporary product +;pModulus (rdx) address of the modulus +;mSize (rcx) size of the modulus +;m0 (r8) montgomery helper (m') + + mov r15, rdi ; store reduction address + + ; reload parameters for future convinience: + mov rdi, rsi ; rdi = temporary product buffer + mov rsi, rdx ; rsi = modulus + movsxd rdx, ecx ; rdx = length of modulus + + cmp rdx, 16 + ja .test_8N_case ; length of modulus >16 + + cmp rdx, 4 + ja .above4 ; length of modulus 4,..,16 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short modulus (1,..,4) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp rdx, 3 + ja .red_4 + jz .red_3 + jp .red_2 + ; red_1 + +.red_1: + mov r9, qword [rdi+sizeof(qword)*0] + MRED_FIX 1, r15, rdi, rsi, r8, rbp,rbx, r9 + jmp .quit + +.red_2: + mov r9, qword [rdi+sizeof(qword)*0] + mov r10, qword [rdi+sizeof(qword)*1] + MRED_FIX 2, r15, rdi, rsi, r8, rbp,rbx, r9,r10 + jmp .quit + +.red_3: + mov r9, qword [rdi+sizeof(qword)*0] + mov r10, qword [rdi+sizeof(qword)*1] + mov r11, qword [rdi+sizeof(qword)*2] + MRED_FIX 3, r15, rdi, rsi, r8, rbp,rbx, r9,r10,r11 + jmp .quit + +.red_4: + mov r9, qword [rdi+sizeof(qword)*0] + mov r10, qword [rdi+sizeof(qword)*1] + mov r11, qword [rdi+sizeof(qword)*2] + mov r12, qword [rdi+sizeof(qword)*3] + MRED_FIX 4, r15, rdi, rsi, r8, rbp,rbx, r9,r10,r11,r12 + jmp .quit + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; short modulus (5,..,16) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.above4: + mov rbp, rdx + sub rbp, 4 + GET_EP rax, mred_short, rbp ; mred procedure + + call rax + jmp .quit + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 8N case squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.test_8N_case: + test rdx, 7 + jnz .general_case + + CALL_FUNC mred_8N_adcox + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; general case modulus +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.general_case: + CALL_FUNC mred_N_adcox + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC cpMontRedAdx_BNU + +%endif + +%endif ;; _ADCOX_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqr.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqr.inc new file mode 100644 index 000000000..45f4a9ed9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqr.inc @@ -0,0 +1,474 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number squaring Support +; +; + +%ifndef _PCPBNUSQR_INC_ +%assign _PCPBNUSQR_INC_ 1 + +%include "pcpmulx.inc" +%include "pcpbnusqr_basic.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; (8*n) squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_8N,PRIVATE + push rdi ; save diagonal loop parameters + push rsi + push rdx + + push rdi ; save initial triangle product parameters + push rsi + push rdx +; +; init upper triangle product +; + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + add rdi, sizeof(qword)*8 + + sub rdx, 8 + + mov rcx, rsi + add rsi, sizeof(qword)*8 +.initLoop: + push rdx + call mla_8x8 + pop rdx + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnz .initLoop + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + jmp .update_Triangle + +; +; update upper triangle product +; +.outerLoop: + push rdi ; update triangle product parameters + push rsi + push rdx + + xor rax, rax ; c-flag + push rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10, qword [rdi+sizeof(qword)*2] + mov r11, qword [rdi+sizeof(qword)*3] + mov r12, qword [rdi+sizeof(qword)*4] + mov r13, qword [rdi+sizeof(qword)*5] + mov r14, qword [rdi+sizeof(qword)*6] + mov r15, qword [rdi+sizeof(qword)*7] + +.innerLoop_entry: + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + add rdi, sizeof(qword)*8 + + sub rdx, 8 + jz .skipInnerLoop + + mov rcx, rsi + add rsi, sizeof(qword)*8 +.innerLoop: + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10, qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11, qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12, qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13, qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14, qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15, qword [rdi+sizeof(qword)*7], rax + sbb rax, rax ; save c-flag + push rax + + push rdx + call mla_8x8 + pop rdx + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnz .innerLoop + +.skipInnerLoop: + pop rax ; restore c-flag + neg rax + adc r8, 0 + mov qword [rdi+sizeof(qword)*0], r8 + adc r9, 0 + mov qword [rdi+sizeof(qword)*1], r9 + adc r10,0 + mov qword [rdi+sizeof(qword)*2],r10 + adc r11,0 + mov qword [rdi+sizeof(qword)*3],r11 + adc r12,0 + mov qword [rdi+sizeof(qword)*4],r12 + adc r13,0 + mov qword [rdi+sizeof(qword)*5],r13 + adc r14,0 + mov qword [rdi+sizeof(qword)*6],r14 + adc r15,0 + mov qword [rdi+sizeof(qword)*7],r15 + +.update_Triangle: + pop rdx + pop rsi + pop rdi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*(8*2) + sub rdx, 8 + jnz .outerLoop + +; +; add diagonal terms +; + pop rcx + pop rsi + pop rdi + xor rbx, rbx +.update_loop: + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + sub rcx, 4 + jnz .update_loop + ret +ENDFUNC sqr_8N + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case N>16 squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_N,PRIVATE + push rdi ; save diagonal loop parameters + push rsi + push rdx + + push rdi ; save initial triangle product parameters + push rsi + push rdx + + mov rbp, rdx + and rbp, 7 + GET_EP rax, mla_8xl_tail, rbp ; get tail procedure + push rax + +; +; init upper triangle product +; + sub rdx, 8 + + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + add rdi, sizeof(qword)*8 + xor r15, r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + sub rdx, 8 + +.initLoop: + push rdx + call mla_8x8 + pop rdx + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnc .initLoop + + add rdx, 8 +; +; tail +; + SWAP rsi, rcx + mov rax, [rsp] ; procedure + push rdx + call rax + pop rdx + lea rdi, [rdi+rdx*sizeof(qword)] + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + jmp .update_Triangle + +; +; update upper triangle product +; +.outerLoop: + push rdi ; update triangle product parameters + push rsi + push rdx + push rax ; tail procedure + + xor rax, rax ; c-flag + push rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10, qword [rdi+sizeof(qword)*2] + mov r11, qword [rdi+sizeof(qword)*3] + mov r12, qword [rdi+sizeof(qword)*4] + mov r13, qword [rdi+sizeof(qword)*5] + mov r14, qword [rdi+sizeof(qword)*6] + mov r15, qword [rdi+sizeof(qword)*7] + + sub rdx, 8 + + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + add rdi, sizeof(qword)*8 + xor r15, r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + sub rdx, 8 + +.innerLoop: + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10, qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11, qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12, qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13, qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14, qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15, qword [rdi+sizeof(qword)*7], rax + sbb rax, rax ; save c-flag + push rax + + push rdx + call mla_8x8 + pop rdx + + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnc .innerLoop + + add rdx, 8 +; +; tail +; + ; clear in advance + pxor xmm0, xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)], xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)+sizeof(qword)*2], xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)+sizeof(qword)*4], xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)+sizeof(qword)*6], xmm0 + + ; updates registers before mla operation + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10, qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11, qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12, qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13, qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14, qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15, qword [rdi+sizeof(qword)*7], rax + + ; store carry for future + sbb rax, rax + neg rax + mov qword [rdi+sizeof(qword)*8], rax + + ; mla_8xn operation + SWAP rsi, rcx + mov rax, [rsp] ; procedure + push rdx + call rax + pop rdx + lea rdi, [rdi+rdx*sizeof(qword)] + + ; updates registers before store + xor rax, rax + mov rax, qword [rdi+sizeof(qword)*0] + add r8, rax + mov qword [rdi+sizeof(qword)*0], r8 + mov rax, qword [rdi+sizeof(qword)*1] + adc r9, rax + mov qword [rdi+sizeof(qword)*1], r9 + mov rax, qword [rdi+sizeof(qword)*2] + adc r10, rax + mov qword [rdi+sizeof(qword)*2], r10 + mov rax, qword [rdi+sizeof(qword)*3] + adc r11, rax + mov qword [rdi+sizeof(qword)*3], r11 + mov rax, qword [rdi+sizeof(qword)*4] + adc r12, rax + mov qword [rdi+sizeof(qword)*4], r12 + mov rax, qword [rdi+sizeof(qword)*5] + adc r13, rax + mov qword [rdi+sizeof(qword)*5], r13 + mov rax, qword [rdi+sizeof(qword)*6] + adc r14, rax + mov qword [rdi+sizeof(qword)*6], r14 + mov rax, qword [rdi+sizeof(qword)*7] + adc r15, rax + mov qword [rdi+sizeof(qword)*7], r15 + +.update_Triangle: + pop rax ; tail procedure + pop rdx + pop rsi + pop rdi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*(8*2) + sub rdx, 8 + cmp rdx, 16 + jg .outerLoop + +; +; tail +; + mov rbp, rdx + sub rbp, 8 + GET_EP rax, sqrN_triangle, rbp ; get triangle proc + + sub rsp, sizeof(qword)*32 + push rdi + push rdx + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + lea rdi, [rsp+sizeof(qword)*2] + call rax + + mov rsi, rdi + pop rdx + pop rdi + + ; copy 8 terms + movdqu xmm0, xmmword [rsi] + movdqu xmm1, xmmword [rsi+sizeof(qword)*2] + movdqu xmm2, xmmword [rsi+sizeof(qword)*4] + movdqu xmm3, xmmword [rsi+sizeof(qword)*6] + add rsi, sizeof(qword)*8 + movdqu xmmword [rdi], xmm0 + movdqu xmmword [rdi+sizeof(qword)*2], xmm1 + movdqu xmmword [rdi+sizeof(qword)*4], xmm2 + movdqu xmmword [rdi+sizeof(qword)*6], xmm3 + add rdi, sizeof(qword)*8 + + ; update rdx-8 terms + lea rax, [rdx-8] + xor rbx, rbx +.update1: + mov r8, qword [rsi] + mov r9, qword [rdi] + add rsi, sizeof(qword) + neg rbx + adc r8, r9 + sbb rbx, rbx + mov qword [rdi], r8 + add rdi, sizeof(qword) + sub rax, 1 + jg .update1 + + ; update rdx terms +.update2: + mov r8, qword [rsi] + add rsi, sizeof(qword) + neg rbx + adc r8, 0 + sbb rbx, rbx + mov qword [rdi], r8 + add rdi, sizeof(qword) + sub rdx, 1 + jg .update2 + + add rsp, sizeof(qword)*32 + +; +; add diagonal terms +; +.add_diagonals: + pop rcx + pop rsi + pop rdi + sub rcx, 4 + xor rbx, rbx +.add_diagonal_loop: + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + sub rcx, 4 + jnc .add_diagonal_loop + + add rcx, 4 + jz .quit +.add_diagonal_rest: + ADD_DIAG 1, rdi, rsi + add rdi, sizeof(qword)*2 + add rsi, sizeof(qword) + sub rcx, 1 + jnz .add_diagonal_rest + +.quit: + ret +ENDFUNC sqr_N + + +%endif ;; _PCPBNUSQR_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqr_basic.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqr_basic.inc new file mode 100644 index 000000000..1474f720f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqr_basic.inc @@ -0,0 +1,2003 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number squaring Support +; +; + +%ifndef _PCPBNSQR_BASIC_ADCX_INC_ +%assign _PCPBNSQR_BASIC_ADCX_INC_ 1 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Fixed-size (1-8 qwords) square operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; acc:a1 = src * mem + a1 +%macro MULADD1x 4.nolist + %xdefine %%acc %1 + %xdefine %%a1 %2 + %xdefine %%src %3 + %xdefine %%mem %4 + +%ifnidni %%src,rdx + mov rdx, %%src +%endif +gsmulx %%acc, rax, %%mem + add %%a1, rax + adc %%acc, 0 +%endmacro + +; acc:a1 = src * mem + a1 + acc +%macro MULADDx 5.nolist + %xdefine %%acc %1 + %xdefine %%a1 %2 + %xdefine %%src %3 + %xdefine %%mem %4 + %xdefine %%H %5 + +%ifnidni %%src,rdx + mov rdx, %%src +%endif + +gsmulx %%H,rax, %%mem + add %%a1, rax + adc %%H, 0 + add %%a1, %%acc + adc %%H, 0 + mov %%acc, %%H +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; assignment +;; +%xdefine pDst rdi +%xdefine pSrc rsi +%xdefine pA rsi + +%xdefine A rcx +%xdefine x0 r8 +%xdefine x1 r9 +%xdefine x2 r10 +%xdefine x3 r11 +%xdefine x4 r12 +%xdefine x5 r13 +%xdefine x6 r14 +%xdefine x7 r15 +%xdefine x8 rbx +%xdefine t0 rbp + + +;; +;; 1*qword squarer +;; +%macro SQR_64 2.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + + mov rdx, qword [%%pA] +gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + mov qword [%%pDst+sizeof(qword)], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_1,PRIVATE + SQR_64 pDst, pA + ret +ENDFUNC sqr_1 + + + +;; +;; 2*qword squarer +;; +%macro SQR_128 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov rdx, qword [%%pA] +gsmulx %%x1,%%x0,qword [rsi+sizeof(qword)*1] ; a[0]*a[1] + +gsmulx %%x3,%%x2,rdx ; a[0]^2 + mov rdx, qword [%%pA+sizeof(qword)] ; a[1] +gsmulx rdx,rax,rdx ; a[1]^2 + + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%A, 0 + + mov qword [%%pDst+sizeof(qword)*0], %%x2 + add %%x3, %%x0 + mov qword [%%pDst+sizeof(qword)*1], %%x3 + adc rax, %%x1 + mov qword [%%pDst+sizeof(qword)*2], rax + adc rdx, %%A + mov qword [%%pDst+sizeof(qword)*3], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_2,PRIVATE + SQR_128 pDst, pA, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + ret +ENDFUNC sqr_2 + + + +;; +;; 3*qword squarer +;; +%macro SQR_192 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov rdx, [%%pA] +gsmulx %%x1,%%x0, [%%pA+sizeof(qword)*1] + MULADD1x %%x2, %%x1, rdx, [%%pA+sizeof(qword)*2] + + mov rdx, qword [%%pA+sizeof(qword)*1] +gsmulx %%x3, rax, qword [%%pA+sizeof(qword)*2] + add %%x2, rax + adc %%x3, 0 + + mov rdx, qword [%%pA+ sizeof(qword)*0] + + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%A, %%A + + ;; add sqr(a[0]),...,sqr(a[2]) +gsmulx rax, rdx, rdx ; a[0]^2 + mov [%%pDst+sizeof(qword)*0], rdx + mov rdx, [%%pA+sizeof(qword)*1] + add %%x0, rax + mov [%%pDst+sizeof(qword)*1], %%x0 + +gsmulx rax, rdx, rdx ; a[1]^2 + adc %%x1, rdx + mov [%%pDst+sizeof(qword)*2], %%x1 + mov rdx, [%%pA+sizeof(qword)*2] + adc %%x2, rax + mov [%%pDst+sizeof(qword)*3], %%x2 + +gsmulx rax, rdx, rdx ; a[2]^2 + adc %%x3, rdx + mov [%%pDst+sizeof(qword)*4], %%x3 + adc %%A, rax + mov [%%pDst+sizeof(qword)*5], %%A +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_3,PRIVATE + SQR_192 pDst, pA, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + ret +ENDFUNC sqr_3 + + + +;; +;; 4*qword squarer +;; +%macro SQR_256 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov rdx, [%%pA] +gsmulx %%x1,%%x0, [%%pA+sizeof(qword)*1] + MULADD1x %%x2, %%x1, rdx, [%%pA+sizeof(qword)*2] + MULADD1x %%x3, %%x2, rdx, [%%pA+sizeof(qword)*3] + + mov rdx, qword [%%pA+sizeof(qword)*1] +gsmulx %%A, rax, qword [%%pA+sizeof(qword)*2] + xor %%x4, %%x4 + add %%x2, rax + adc %%x3, %%A + adc %%x4, 0 +gsmulx %%A, rax, qword [%%pA+sizeof(qword)*3] + add %%x3, rax + adc %%x4, %%A + + mov rdx, qword [%%pA+sizeof(qword)*2] +gsmulx %%x5, rax, qword [%%pA+sizeof(qword)*3] + add %%x4, rax + adc %%x5, 0 + + mov rdx, [%%pA+sizeof(qword)*0] + + ;; --- double x0...x5 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%A, 0 + + ;; add sqr(a[0]),...,sqr(a[3]) +gsmulx rax, rdx, rdx ; a[0]^2 + mov [%%pDst+sizeof(qword)*0], rdx + mov rdx, [%%pA+sizeof(qword)*1] + add %%x0, rax + mov [%%pDst+sizeof(qword)*1], %%x0 + +gsmulx rax, rdx, rdx ; a[1]^2 + adc %%x1, rdx + mov [%%pDst+sizeof(qword)*2], %%x1 + mov rdx, [%%pA+sizeof(qword)*2] + adc %%x2, rax + mov [%%pDst+sizeof(qword)*3], %%x2 + +gsmulx rax, rdx, rdx ; a[2]^2 + adc %%x3, rdx + mov [%%pDst+sizeof(qword)*4], %%x3 + mov rdx, [%%pA+sizeof(qword)*3] + adc %%x4, rax + mov [%%pDst+sizeof(qword)*5], %%x4 + +gsmulx rax, rdx, rdx ; a[3]^2 + adc %%x5, rdx + mov [%%pDst+sizeof(qword)*6], %%x5 + adc %%A, rax + mov [%%pDst+sizeof(qword)*7], %%A +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_4,PRIVATE + SQR_256 pDst, pA, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + ret +ENDFUNC sqr_4 + + + +;; +;; 5*qword squarer +;; +%macro SQR_320 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + +mov rdx, [%%pA] +gsmulx %%x1,%%x0, [%%pA+sizeof(qword)*1] + MULADD1x %%x2, %%x1, rdx, [%%pA+sizeof(qword)*2] + MULADD1x %%x3, %%x2, rdx, [%%pA+sizeof(qword)*3] + MULADD1x %%x4, %%x3, rdx, [%%pA+sizeof(qword)*4] + + mov rdx, [%%pA + sizeof(qword)*1] +gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + add %%x2, rax + adc %%t0, 0 + MULADDx %%t0, %%x3, rdx, [%%pA+sizeof(qword)*3], %%A + MULADDx %%t0, %%x4, rdx, [%%pA+sizeof(qword)*4], %%A + mov %%x5, %%t0 + + mov rdx, qword [%%pA+sizeof(qword)*2] +gsmulx %%A, rax, qword [%%pA+sizeof(qword)*3] + xor %%x6, %%x6 + add %%x4, rax + adc %%x5, %%A + adc %%x6, 0 +gsmulx %%A, rax, qword [%%pA+sizeof(qword)*4] + add %%x5, rax + adc %%x6, %%A + + mov rdx, qword [%%pA+sizeof(qword)*3] +gsmulx %%x7, rax, qword [%%pA+sizeof(qword)*4] + add %%x6, rax + adc %%x7, 0 + + mov rdx, [%%pA+sizeof(qword)*0] + + ;; --- double x0...x5 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%x7, %%x7 + adc %%A, 0 + + ;; add sqr(a[0]),...,sqr(a[4]) +gsmulx rax, rdx, rdx ; a[0]^2 + mov [%%pDst+sizeof(qword)*0], rdx + mov rdx, [%%pA+sizeof(qword)*1] + add %%x0, rax + mov [%%pDst+sizeof(qword)*1], %%x0 + +gsmulx rax, rdx, rdx ; a[1]^2 + adc %%x1, rdx + mov [%%pDst+sizeof(qword)*2], %%x1 + mov rdx, [%%pA+sizeof(qword)*2] + adc %%x2, rax + mov [%%pDst+sizeof(qword)*3], %%x2 + +gsmulx rax, rdx, rdx ; a[2]^2 + adc %%x3, rdx + mov [%%pDst+sizeof(qword)*4], %%x3 + mov rdx, [%%pA+sizeof(qword)*3] + adc %%x4, rax + mov [%%pDst+sizeof(qword)*5], %%x4 + +gsmulx rax, rdx, rdx ; a[3]^2 + adc %%x5, rdx + mov [%%pDst+sizeof(qword)*6], %%x5 + mov rdx, [%%pA+sizeof(qword)*4] + adc %%x6, rax + mov [%%pDst+sizeof(qword)*7], %%x6 + +gsmulx rax, rdx, rdx ; a[4]^2 + adc %%x7, rdx + mov [%%pDst+sizeof(qword)*8], %%x7 + mov rdx, [%%pA+sizeof(qword)*5] + adc %%A, rax + mov [%%pDst+sizeof(qword)*9], %%A +%endmacro + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_5,PRIVATE + SQR_320 pDst, pA, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + ret +ENDFUNC sqr_5 + + + +;; +;; 6*qword squarer +;; +%macro SQR_384 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + +mov rdx, [%%pA] +gsmulx %%x1,%%x0, [%%pA+sizeof(qword)*1] + MULADD1x %%x2, %%x1, rdx, [%%pA+sizeof(qword)*2] + MULADD1x %%x3, %%x2, rdx, [%%pA+sizeof(qword)*3] + MULADD1x %%x4, %%x3, rdx, [%%pA+sizeof(qword)*4] + MULADD1x %%x5, %%x4, rdx, [%%pA+sizeof(qword)*5] + + mov rdx, [%%pA + sizeof(qword)*1] +gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + add %%x2, rax + adc %%t0, 0 + MULADDx %%t0, %%x3, rdx, [%%pA+sizeof(qword)*3], %%A + MULADDx %%t0, %%x4, rdx, [%%pA+sizeof(qword)*4], %%A + MULADDx %%t0, %%x5, rdx, [%%pA+sizeof(qword)*5], %%A + mov %%x6, %%t0 + + mov rdx, [%%pA+sizeof(qword)*2] +gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + add %%x4, rax + adc %%t0, 0 + MULADDx %%t0, %%x5, rdx, [%%pA+sizeof(qword)*4], %%A + MULADDx %%t0, %%x6, rdx, [%%pA+sizeof(qword)*5], %%A + mov %%x7, %%t0 + + mov rdx, qword [%%pA+sizeof(qword)*3] +gsmulx %%A, rax, qword [%%pA+sizeof(qword)*4] + xor %%x8, %%x8 + add %%x6, rax + adc %%x7, %%A + adc %%x8, 0 +gsmulx %%A, rax, qword [%%pA+sizeof(qword)*5] + add %%x7, rax + adc %%x8, %%A + + mov rdx, qword [%%pA+sizeof(qword)*4] +gsmulx %%t0, rax, qword [%%pA+sizeof(qword)*5] + add %%x8, rax + adc %%t0, 0 + + mov rdx, [%%pA+sizeof(qword)*0] + + ;; --- double x0...x7,x8,t0 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%x7, %%x7 + adc %%x8, %%x8 + adc %%t0, %%t0 + adc %%A, 0 + + ;; add sqr(a[0]),...,sqr(a[5]) +gsmulx rax, rdx, rdx ; a[0]^2 + mov [%%pDst+sizeof(qword)*0], rdx + mov rdx, [%%pA+sizeof(qword)*1] + add %%x0, rax + mov [%%pDst+sizeof(qword)*1], %%x0 + +gsmulx rax, rdx, rdx ; a[1]^2 + adc %%x1, rdx + mov [%%pDst+sizeof(qword)*2], %%x1 + mov rdx, [%%pA+sizeof(qword)*2] + adc %%x2, rax + mov [%%pDst+sizeof(qword)*3], %%x2 + +gsmulx rax, rdx, rdx ; a[2]^2 + adc %%x3, rdx + mov [%%pDst+sizeof(qword)*4], %%x3 + mov rdx, [%%pA+sizeof(qword)*3] + adc %%x4, rax + mov [%%pDst+sizeof(qword)*5], %%x4 + +gsmulx rax, rdx, rdx ; a[3]^2 + adc %%x5, rdx + mov [%%pDst+sizeof(qword)*6], %%x5 + mov rdx, [%%pA+sizeof(qword)*4] + adc %%x6, rax + mov [%%pDst+sizeof(qword)*7], %%x6 + +gsmulx rax, rdx, rdx ; a[4]^2 + adc %%x7, rdx + mov [%%pDst+sizeof(qword)*8], %%x7 + mov rdx, [%%pA+sizeof(qword)*5] + adc %%x8, rax + mov [%%pDst+sizeof(qword)*9], %%x8 + +gsmulx rax, rdx, rdx ; a[5]^2 + adc %%t0, rdx + mov [%%pDst+sizeof(qword)*10], %%t0 + adc %%A, rax + mov [%%pDst+sizeof(qword)*11], %%A +%endmacro + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_6,PRIVATE + SQR_384 pDst, pA, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + ret +ENDFUNC sqr_6 + + + +;; +;; 7*qword squarer +;; +%macro SQR_448 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; ------------------ + ;; first pass 01...06 + ;; ------------------ + mov rdx, [%%pA] +gsmulx %%x1,%%x0, [%%pA+sizeof(qword)*1] + MULADD1x %%x2, %%x1, rdx, [%%pA+sizeof(qword)*2] + MULADD1x %%x3, %%x2, rdx, [%%pA+sizeof(qword)*3] + MULADD1x %%x4, %%x3, rdx, [%%pA+sizeof(qword)*4] + MULADD1x %%x5, %%x4, rdx, [%%pA+sizeof(qword)*5] + MULADD1x %%x6, %%x5, rdx, [%%pA+sizeof(qword)*6] + + ;; ------------------ + ;; second pass 12...16 + ;; ------------------ + mov rdx, [%%pA + sizeof(qword)*1] +gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + add %%x2, rax + adc %%t0, 0 + + MULADDx %%t0, %%x3, rdx, [%%pA+sizeof(qword)*3], %%A + MULADDx %%t0, %%x4, rdx, [%%pA+sizeof(qword)*4], %%A + MULADDx %%t0, %%x5, rdx, [%%pA+sizeof(qword)*5], %%A + MULADDx %%t0, %%x6, rdx, [%%pA+sizeof(qword)*6], %%A + mov %%x7, %%t0 + + ;; ------------------ + ;; third pass 23...25 + ;; ------------------ + mov rdx, [%%pA+sizeof(qword)*2] +gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + add %%x4, rax + adc %%t0, 0 + + xor %%x8, %%x8 + MULADDx %%t0, %%x5, rdx, [%%pA+sizeof(qword)*4], %%A + MULADDx %%t0, %%x6, rdx, [%%pA+sizeof(qword)*5], %%A + add %%x7, %%t0 + adc %%x8, 0 + + ;; ------------------ + ;; fourth pass 34 + ;; ------------------ + mov rax, [%%pA+sizeof(qword)*3] + mul qword [%%pA+sizeof(qword)*4] + add %%x6, rax + adc rdx, 0 + add %%x7, rdx + adc %%x8, 0 + + mov rdx, [%%pA+sizeof(qword)*0] + + ;; --- double x0...x6 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%A, 0 + + ;; add sqr(a[0]),...,sqr(a[3]) +gsmulx rax, rdx, rdx ; a[0]^2 + mov [%%pDst+sizeof(qword)*0], rdx + mov rdx, [%%pA+sizeof(qword)*1] + add %%x0, rax + mov [%%pDst+sizeof(qword)*1], %%x0 + +gsmulx rax, rdx, rdx ; a[1]^2 + adc %%x1, rdx + mov [%%pDst+sizeof(qword)*2], %%x1 + mov rdx, [%%pA+sizeof(qword)*2] + adc %%x2, rax + mov [%%pDst+sizeof(qword)*3], %%x2 + +gsmulx rax, rdx, rdx ; a[2]^2 + adc %%x3, rdx + mov [%%pDst+sizeof(qword)*4], %%x3 + mov rdx, [%%pA+sizeof(qword)*3] + adc %%x4, rax + mov [%%pDst+sizeof(qword)*5], %%x4 + +gsmulx rax, rdx, rdx ; a[3]^2 + adc %%x5, rdx + mov [%%pDst+sizeof(qword)*6], %%x5 + adc %%x6, rax + mov [%%pDst+sizeof(qword)*7], %%x6 + adc %%A, 0 + + ;; ------------------ + ;; third pass complete 26 + ;; ------------------ + mov rax, [%%pA+sizeof(qword)*2] + xor %%x0, %%x0 + + mul qword [%%pA+sizeof(qword)*6] + add %%x7, rax + adc rdx, 0 + add %%x8, rdx + adc %%x0, 0 + + ;; ------------------ + ;; forth pass complete 35...36 + ;; ------------------ + mov rdx, [%%pA+sizeof(qword)*3] +gsmulx %%x6, rax, [%%pA+sizeof(qword)*5] + add %%x7, rax + adc %%x8, %%x6 + adc %%x0, 0 +gsmulx %%x6, rax, [%%pA+sizeof(qword)*6] + add %%x8, rax + adc %%x0, %%x6 + + ;; ------------------ + ;; fifth pass 45...46 + ;; ------------------ + mov rdx, [%%pA+sizeof(qword)*4] +gsmulx %%x6, rax, [%%pA+sizeof(qword)*5] + xor %%x1, %%x1 + add %%x8, rax + adc %%x0, %%x6 + adc %%x1, 0 +gsmulx %%x6, rax, [%%pA+sizeof(qword)*6] + add %%x0, rax + adc %%x1, %%x6 + + ;; ------------------ + ;; six pass 56 + ;; ------------------ + mov rax, [%%pA+sizeof(qword)*5] + xor %%x2, %%x2 + mul qword [%%pA + sizeof(qword)*6] + add %%x1, rax + adc %%x2, rdx + + mov rdx, [%%pA+sizeof(qword)*4] + + ;; --- double x7, x8, x0, x1, x2 + xor %%x3, %%x3 + add %%x7, %%x7 + adc %%x8, %%x8 + adc %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, 0 + +gsmulx rax, rdx, rdx ; a[4]^2 + add rdx, %%A + adc rax, 0 + add %%x7, rdx + mov rdx, [%%pA+sizeof(qword)*5] + mov [%%pDst+sizeof(qword)*8], %%x7 + adc %%x8, rax + mov [%%pDst+sizeof(qword)*9], %%x8 + +gsmulx rax, rdx, rdx ; a[5]^2 + adc %%x0, rdx + mov [%%pDst+sizeof(qword)*10], %%x0 + mov rdx, [%%pA+sizeof(qword)*6] + adc %%x1, rax + mov [%%pDst+sizeof(qword)*11], %%x1 + +gsmulx rax, rdx, rdx ; a[6]^2 + adc %%x2, rdx + mov [%%pDst+sizeof(qword)*12], %%x2 + adc %%x3, rax + mov [%%pDst+sizeof(qword)*13], %%x3 +%endmacro + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_7,PRIVATE + SQR_448 pDst, pA, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + ret +ENDFUNC sqr_7 + + + +;; +;; 8*qword squarer +;; +%macro SQR_512 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + +;; ---------------------------------- + ;; first pass a[0]*a[1],...,a[0]*a[7] + ;; ---------------------------------- + mov rdx, [%%pA] +gsmulx %%x1,%%x0, [%%pA+sizeof(qword)*1] + MULADD1x %%x2, %%x1, rdx, [%%pA+sizeof(qword)*2] + MULADD1x %%x3, %%x2, rdx, [%%pA+sizeof(qword)*3] + MULADD1x %%x4, %%x3, rdx, [%%pA+sizeof(qword)*4] + MULADD1x %%x5, %%x4, rdx, [%%pA+sizeof(qword)*5] + MULADD1x %%x6, %%x5, rdx, [%%pA+sizeof(qword)*6] + MULADD1x %%x7, %%x6, rdx, [%%pA+sizeof(qword)*7] + + ;; ----------------------------------- + ;; second pass a[1]*a[2],...,a[1]*a[6] + ;; ----------------------------------- + mov rdx, [%%pA + sizeof(qword)*1] +gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + add %%x2, rax + adc %%t0, 0 + xor %%x8, %%x8 + + MULADDx %%t0, %%x3, rdx, [%%pA+sizeof(qword)*3], %%A + MULADDx %%t0, %%x4, rdx, [%%pA+sizeof(qword)*4], %%A + MULADDx %%t0, %%x5, rdx, [%%pA+sizeof(qword)*5], %%A + MULADDx %%t0, %%x6, rdx, [%%pA+sizeof(qword)*6], %%A + add %%x7, %%t0 + adc %%x8, 0 + + ;; ---------------------------------- + ;; third pass a[2]*a[3],...,a[2]*a[5] + ;; ---------------------------------- + mov rdx, [%%pA+sizeof(qword)*2] +gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + add %%x4, rax + adc %%t0, 0 + + MULADDx %%t0, %%x5, rdx, [%%pA+sizeof(qword)*4], %%A + MULADDx %%t0, %%x6, rdx, [%%pA+sizeof(qword)*5], %%A + add %%x7, %%t0 + adc %%x8, 0 + + ;; --------------------- + ;; fourth pass a[3]*a[4] + ;; --------------------- + mov rax, [%%pA+sizeof(qword)*3] + mul qword [%%pA+sizeof(qword)*4] + add %%x6, rax + adc rdx, 0 + add %%x7, rdx + adc %%x8, 0 + + mov rdx, [%%pA+sizeof(qword)*0] + + ;; double x0,...,x6 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%A, 0 + + ;; add sqr(a[0]),...,sqr(a[3]) +gsmulx rax, rdx, rdx ; a[0]^2 + mov [%%pDst+sizeof(qword)*0], rdx + mov rdx, [%%pA+sizeof(qword)*1] + add %%x0, rax + mov [%%pDst+sizeof(qword)*1], %%x0 + +gsmulx rax, rdx, rdx ; a[1]^2 + adc %%x1, rdx + mov [%%pDst+sizeof(qword)*2], %%x1 + mov rdx, [%%pA+sizeof(qword)*2] + adc %%x2, rax + mov [%%pDst+sizeof(qword)*3], %%x2 + +gsmulx rax, rdx, rdx ; a[2]^2 + adc %%x3, rdx + mov [%%pDst+sizeof(qword)*4], %%x3 + mov rdx, [%%pA+sizeof(qword)*3] + adc %%x4, rax + mov [%%pDst+sizeof(qword)*5], %%x4 + +gsmulx rax, rdx, rdx ; a[3]^2 + adc %%x5, rdx + mov [%%pDst+sizeof(qword)*6], %%x5 + adc %%x6, rax + mov [%%pDst+sizeof(qword)*7], %%x6 + adc %%A, 0 + + ;; ---------------------------- + ;; second pass (cont) a[1]*a[7] + ;; ---------------------------- + mov rax, [%%pA+sizeof(qword)*1] + xor %%x0, %%x0 + mul qword [%%pA+sizeof(qword)*7] + add %%x7, rax + adc rdx, 0 + add %%x8, rdx + adc %%x0, 0 + + ;; ----------------------------------------- + ;; third pass (cont) a[2]*a[6],...,a[2]*a[7] + ;; ----------------------------------------- + mov rdx, [%%pA+sizeof(qword)*2] +gsmulx %%x6, rax, [%%pA+sizeof(qword)*6] + add %%x7, rax + adc %%x8, %%x6 + adc %%x0, 0 +gsmulx %%x6, rax, [%%pA+sizeof(qword)*7] + xor %%x1, %%x1 + add %%x8, rax + adc %%x0, %%x6 + adc %%x1, 0 + + ;; ----------------------------------- + ;; fourth pass a[3]*a[5],...,a[3]*a[7] + ;; ----------------------------------- + mov rdx, [%%pA+sizeof(qword)*3] +gsmulx %%x6, rax, [%%pA+sizeof(qword)*5] + add %%x7, rax + adc %%x6, 0 + add %%x8, %%x6 + adc %%x0, 0 + adc %%x1, 0 +gsmulx %%x6, rax, [%%pA+sizeof(qword)*6] + add %%x8, rax + adc %%x6, 0 + add %%x0, %%x6 + adc %%x1, 0 +gsmulx %%x6, rax, [%%pA+sizeof(qword)*7] + add %%x0, rax + adc %%x6, 0 + add %%x1, %%x6 + ;; carry out should be 0 + + ;; ----------------------------------- + ;; fifth pass a[4]*a[5],...,a[4]*a[7] + ;; ----------------------------------- + mov rdx, [%%pA+sizeof(qword)*4] + +gsmulx %%x2, rax, [%%pA+sizeof(qword)*5] + add %%x8, rax + adc %%x2, 0 + + MULADDx %%x2, %%x0, rdx, [%%pA+sizeof(qword)*6], %%x6 + MULADDx %%x2, %%x1, rdx, [%%pA+sizeof(qword)*7], %%x6 + + ;; ----------------------------------------------------------- + ;; sixth pass a[5]*a[6],...,a[5]*a[7] & seventh pass a[6]*a[7] + ;; ----------------------------------------------------------- + mov rdx, [%%pA+sizeof(qword)*5] + +gsmulx %%x3, rax, [%%pA+sizeof(qword)*6] + add %%x1, rax + adc %%x3, 0 + + MULADDx %%x3, %%x2, rdx, [%%pA+sizeof(qword)*7], %%x6 + + mov rax, [%%pA+sizeof(qword)*6] + mul qword [%%pA+sizeof(qword)*7] + add %%x3, rax + adc rdx, 0 + mov %%x4, rdx + + mov rdx, [%%pA+sizeof(qword)*4] + + ;; --- double x7, x8, x0, ..., x4 + xor %%x5, %%x5 + add %%x7, %%x7 + adc %%x8, %%x8 + adc %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, 0 + + ;; add sqr(a[4]),...,sqr(a[7]) +gsmulx rax, rdx, rdx ; a[4]^2 + add rdx, %%A + adc rax, 0 + add %%x7, rdx + mov rdx, [%%pA+sizeof(qword)*5] + mov [%%pDst+sizeof(qword)*8], %%x7 + adc %%x8, rax + mov [%%pDst+sizeof(qword)*9], %%x8 + +gsmulx rax, rdx, rdx ; a[5]^2 + adc %%x0, rdx + mov [%%pDst+sizeof(qword)*10], %%x0 + mov rdx, [%%pA+sizeof(qword)*6] + adc %%x1, rax + mov [%%pDst+sizeof(qword)*11], %%x1 + +gsmulx rax, rdx, rdx ; a[6]^2 + adc %%x2, rdx + mov [%%pDst+sizeof(qword)*12], %%x2 + mov rdx, [%%pA+sizeof(qword)*7] + adc %%x3, rax + mov [%%pDst+sizeof(qword)*13], %%x3 + +gsmulx rax, rdx, rdx ; a[7]^2 + adc %%x4, rdx + mov [%%pDst+sizeof(qword)*14], %%x4 + adc %%x5, rax + mov [%%pDst+sizeof(qword)*15], %%x5 +%endmacro + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_8,PRIVATE + SQR_512 pDst, pA, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + ret +ENDFUNC sqr_8 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; SQR_512_TRIANGLE_STEP +; executes single line of upper tpiangle +; +; Inp:partial sum: x7 x6 x5 x4 x3 x2 x1 x0 +; rdx * pA[] p p p p p p p p p +; Out: x0 x7 x6 x5 x4 x3 x2 x1 +; [dst] + +%macro SQR_512_TRIANGLE_STEP 14.nolist + %xdefine %%HEAD_X %1 + %xdefine %%X7 %2 + %xdefine %%X6 %3 + %xdefine %%X5 %4 + %xdefine %%X4 %5 + %xdefine %%X3 %6 + %xdefine %%X2 %7 + %xdefine %%X1 %8 + %xdefine %%X0 %9 + %xdefine %%TAIL_X %10 + %xdefine %%pDst %11 + %xdefine %%pA %12 + %xdefine %%TMP1 %13 + %xdefine %%TMP2 %14 + +%ifnempty %%X0 +gsmulx %%TMP1, rax, [%%pA+sizeof(qword)*0] ; TMP1:rax = rdx * pA[0] + add %%X0, rax + adc %%TMP1, 0 +%endif + +%ifnempty %%TAIL_X + mov %%pDst, %%TAIL_X +%endif + +%ifnempty %%X1 +gsmulx %%TMP2, rax, [%%pA+sizeof(qword)*1] ; TMP2:rax = rdx * pA[1] + add %%X1, rax + adc %%TMP2, 0 +%ifnempty %%X0 + add %%X1, %%TMP1 + adc %%TMP2, 0 +%endif +%endif + +%ifnempty %%X2 +gsmulx %%TMP1, rax, [%%pA+sizeof(qword)*2] ; TMP1:rax = rdx * pA[2] + add %%X2, rax + adc %%TMP1, 0 +%ifnempty %%X1 + add %%X2, %%TMP2 + adc %%TMP1, 0 +%endif +%endif + +%ifnempty %%X3 +gsmulx %%TMP2, rax, [%%pA+sizeof(qword)*3] ; TMP2:rax = rdx * pA[3] + add %%X3, rax + adc %%TMP2, 0 +%ifnempty %%X2 + add %%X3, %%TMP1 + adc %%TMP2, 0 +%endif +%endif + +%ifnempty %%X4 +gsmulx %%TMP1, rax, [%%pA+sizeof(qword)*4] ; TMP1:rax = rdx * pA[4] + add %%X4, rax + adc %%TMP1, 0 +%ifnempty %%X3 + add %%X4, %%TMP2 + adc %%TMP1, 0 +%endif +%endif + +%ifnempty %%X5 +gsmulx %%TMP2, rax, [%%pA+sizeof(qword)*5] ; TMP2:rax = rdx * pA[5] + add %%X5, rax + adc %%TMP2, 0 +%ifnempty %%X4 + add %%X5, %%TMP1 + adc %%TMP2, 0 +%endif +%endif + +%ifnempty %%X6 +gsmulx %%TMP1, rax, [%%pA+sizeof(qword)*6] ; TMP1:rax = rdx * pA[6] + add %%X6, rax + adc %%TMP1, 0 +%ifnempty %%X5 + add %%X6, %%TMP2 + adc %%TMP1, 0 +%endif +%endif + +%ifnempty %%X7 +gsmulx %%HEAD_X, rax, [%%pA+sizeof(qword)*7] ; X0:rax = rdx * pA[7] + add %%X7, rax + adc %%HEAD_X, 0 +%ifnempty %%X6 + add %%X7, %%TMP1 + adc %%HEAD_X, 0 +%endif +%endif +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; square and add diagonal terms + +%macro ADD_DIAG 3.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pSrc %3 + +mov r8, qword [%%pDst+sizeof(qword)*0] + mov r9, qword [%%pDst+sizeof(qword)*1] +%if %%N > 1 + mov r10,qword [%%pDst+sizeof(qword)*2] + mov r11,qword [%%pDst+sizeof(qword)*3] +%if %%N > 2 + mov r12,qword [%%pDst+sizeof(qword)*4] + mov r13,qword [%%pDst+sizeof(qword)*5] +%if %%N > 3 + mov r14,qword [%%pDst+sizeof(qword)*6] + mov r15,qword [%%pDst+sizeof(qword)*7] +%endif +%endif +%endif + + xor rbp, rbp + add r8, r8 + adc r9, r9 +%if %%N > 1 + adc r10,r10 + adc r11,r11 +%if %%N > 2 + adc r12,r12 + adc r13,r13 +%if %%N > 3 + adc r14,r14 + adc r15,r15 +%endif +%endif +%endif + adc rbp, 0 + + mov rdx, [%%pSrc+sizeof(qword)*0] +gsmulx rdx, rax, rdx + add rax, rbx + adc rdx, 0 + add r8, rax + mov rbx, rbp + adc r9, rdx + +%if %%N > 1 + mov rdx, [%%pSrc+sizeof(qword)*1] +gsmulx rdx, rax, rdx + adc r10,rax + adc r11,rdx + +%if %%N > 2 + mov rdx, [%%pSrc+sizeof(qword)*2] +gsmulx rdx, rax, rdx + adc r12,rax + adc r13,rdx + +%if %%N > 3 + mov rdx, [%%pSrc+sizeof(qword)*3] +gsmulx rdx, rax, rdx + adc r14,rax + adc r15,rdx +%endif +%endif +%endif + + adc rbx, 0 + mov qword [%%pDst+sizeof(qword)*0], r8 + mov qword [%%pDst+sizeof(qword)*1], r9 +%if %%N > 1 + mov qword [%%pDst+sizeof(qword)*2], r10 + mov qword [%%pDst+sizeof(qword)*3], r11 +%if %%N > 2 + mov qword [%%pDst+sizeof(qword)*4], r12 + mov qword [%%pDst+sizeof(qword)*5], r13 +%if %%N > 3 + mov qword [%%pDst+sizeof(qword)*6], r14 + mov qword [%%pDst+sizeof(qword)*7], r15 +%endif +%endif +%endif +%endmacro + + + +;; rbp = local carry +;; rbx = global carry +align IPP_ALIGN_FACTOR +DECLARE_FUNC add_diag_4,PRIVATE + ADD_DIAG 4, rdi, rsi + ret +ENDFUNC add_diag_4 + + + +;; +;; 8*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr8_triangle,PRIVATE + ;; A[0]*A[1..7] + mov rdx, [rsi+sizeof(qword)*0] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11,r10, r9, , r8, [rdi+sizeof(qword)*0],rsi, rbx,rbp + + ;; A[1]*A[2..7] + mov rdx, [rsi+sizeof(qword)*1] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13,r12,r11, , , r9, [rdi+sizeof(qword)*1],rsi, rbx,rbp + + ;; A[2]*A[3..7] + mov rdx, [rsi+sizeof(qword)*2] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15,r14,r13, , , , r10, [rdi+sizeof(qword)*2],rsi, rbx,rbp + + ;; A[3]*A[4..7] + mov rdx, [rsi+sizeof(qword)*3] + SQR_512_TRIANGLE_STEP r11, r10, r9, r8,r15, , , , , r11, [rdi+sizeof(qword)*3],rsi, rbx,rbp + + ;; A[4]*A[5..7] + mov rdx, [rsi+sizeof(qword)*4] + SQR_512_TRIANGLE_STEP r12, r11,r10, r9, , , , , , r12, [rdi+sizeof(qword)*4],rsi, rbx,rbp + + ;; A[5]*A[6..7] + mov rdx, [rsi+sizeof(qword)*5] + SQR_512_TRIANGLE_STEP r13, r12,r11, , , , , , , r13, [rdi+sizeof(qword)*5],rsi, rbx,rbp + + ;; A[6]*A[7] + mov rdx, [rsi+sizeof(qword)*6] + SQR_512_TRIANGLE_STEP r14, r13, , , , , , , , r14, [rdi+sizeof(qword)*6],rsi, rbx,rbp + ret +ENDFUNC sqr8_triangle + + + +;; +;; 9*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_9,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + + mov qword [rdi+sizeof(qword)*(1+0)], r8 + mov qword [rdi+sizeof(qword)*(1+1)], r9 + mov qword [rdi+sizeof(qword)*(1+2)], r10 + mov qword [rdi+sizeof(qword)*(1+3)], r11 + mov qword [rdi+sizeof(qword)*(1+4)], r12 + mov qword [rdi+sizeof(qword)*(1+5)], r13 + mov qword [rdi+sizeof(qword)*(1+6)], r14 + mov qword [rdi+sizeof(qword)*(1+7)], r15 + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(1+8)], rbx + + sub rdi, sizeof(qword)*8 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + ADD_DIAG 1, rdi, rsi + + sub rsi, sizeof(qword)*8 + sub rdi, sizeof(qword)*16 + ret +ENDFUNC sqr_9 + + + +;; +;; 10*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_10,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + + mov qword [rdi+sizeof(qword)*(2+0)], r8 + mov qword [rdi+sizeof(qword)*(2+1)], r9 + mov qword [rdi+sizeof(qword)*(2+2)], r10 + mov qword [rdi+sizeof(qword)*(2+3)], r11 + mov qword [rdi+sizeof(qword)*(2+4)], r12 + mov qword [rdi+sizeof(qword)*(2+5)], r13 + mov qword [rdi+sizeof(qword)*(2+6)], r14 + + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15, , , , , , , , , , {rsi+sizeof(qword)*2}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(2+7)], r15 + mov qword [rdi+sizeof(qword)*(2+8)], r8 + mov qword [rdi+sizeof(qword)*(2+9)], rbx + + sub rdi, sizeof(qword)*8 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + ADD_DIAG 2, rdi, rsi + + sub rsi, sizeof(qword)*8 + sub rdi, sizeof(qword)*16 + ret +ENDFUNC sqr_10 + + +;; +;; 10*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_11,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + add rdi, sizeof(qword)*1 + add rcx, sizeof(qword)*1 + call mla_8x2 + sub rdi, sizeof(qword)*1 + sub rcx, sizeof(qword)*1 + + mov qword [rdi+sizeof(qword)*(3+0)], r8 + mov qword [rdi+sizeof(qword)*(3+1)], r9 + mov qword [rdi+sizeof(qword)*(3+2)], r10 + mov qword [rdi+sizeof(qword)*(3+3)], r11 + mov qword [rdi+sizeof(qword)*(3+4)], r12 + + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14, , , , , , , r13,[rdi+sizeof(qword)*(3+5)],{rsi+sizeof(qword)*3}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8, , , , , , , , r14,[rdi+sizeof(qword)*(3+6)],{rsi+sizeof(qword)*3}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(3+7)], r15 + mov qword [rdi+sizeof(qword)*(3+8)], r8 + mov qword [rdi+sizeof(qword)*(3+9)], r9 + mov qword [rdi+sizeof(qword)*(3+10)],rbx + + sub rdi, sizeof(qword)*8 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + ADD_DIAG 3, rdi, rsi + + sub rsi, sizeof(qword)*(4*2) + sub rdi, sizeof(qword)*(8*2) + ret +ENDFUNC sqr_11 + + +;; +;; 12*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_12,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*2 + sub rcx, sizeof(qword)*2 + + mov qword [rdi+sizeof(qword)*(4+0)], r8 + mov qword [rdi+sizeof(qword)*(4+1)], r9 + mov qword [rdi+sizeof(qword)*(4+2)], r10 + mov qword [rdi+sizeof(qword)*(4+3)], r11 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13, , , , , , r12,[rdi+sizeof(qword)*(4+4)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15, , , , , , , r13,[rdi+sizeof(qword)*(4+5)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, , , , , , , , r14,[rdi+sizeof(qword)*(4+6)],{rsi+sizeof(qword)*4}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(4+7)], r15 + mov qword [rdi+sizeof(qword)*(4+8)], r8 + mov qword [rdi+sizeof(qword)*(4+9)], r9 + mov qword [rdi+sizeof(qword)*(4+10)],r10 + mov qword [rdi+sizeof(qword)*(4+11)],rbx + + sub rdi, sizeof(qword)*8 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + + sub rsi, sizeof(qword)*(4*2) + sub rdi, sizeof(qword)*(8*2) + ret +ENDFUNC sqr_12 + + +;; +;; 13*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_13,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*3 + sub rcx, sizeof(qword)*3 + + mov qword [rdi+sizeof(qword)*(5+0)], r8 + mov qword [rdi+sizeof(qword)*(5+1)], r9 + mov qword [rdi+sizeof(qword)*(5+2)], r10 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12, , , , , r11,[rdi+sizeof(qword)*(5+3)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14, , , , , , r12,[rdi+sizeof(qword)*(5+4)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8, , , , , , , r13,[rdi+sizeof(qword)*(5+5)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, , , , , , , , r14,[rdi+sizeof(qword)*(5+6)],{rsi+sizeof(qword)*5}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(5+7)], r15 + mov qword [rdi+sizeof(qword)*(5+8)], r8 + mov qword [rdi+sizeof(qword)*(5+9)], r9 + mov qword [rdi+sizeof(qword)*(5+10)],r10 + mov qword [rdi+sizeof(qword)*(5+11)],r11 + mov qword [rdi+sizeof(qword)*(5+12)],rbx + + sub rdi, sizeof(qword)*8 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + ADD_DIAG 1, rdi, rsi + + sub rsi, sizeof(qword)*(4*3) + sub rdi, sizeof(qword)*(8*3) + ret +ENDFUNC sqr_13 + + +;; +;; 14*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_14,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*4 + sub rcx, sizeof(qword)*4 + + mov qword [rdi+sizeof(qword)*(6+0)], r8 + mov qword [rdi+sizeof(qword)*(6+1)], r9 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11, , , , r10,[rdi+sizeof(qword)*(6+2)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13, , , , , r11,[rdi+sizeof(qword)*(6+3)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15, , , , , , r12,[rdi+sizeof(qword)*(6+4)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, , , , , , , r13,[rdi+sizeof(qword)*(6+5)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11, , , , , , , , r14,[rdi+sizeof(qword)*(6+6)],{rsi+sizeof(qword)*6}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(6+7)], r15 + mov qword [rdi+sizeof(qword)*(6+8)], r8 + mov qword [rdi+sizeof(qword)*(6+9)], r9 + mov qword [rdi+sizeof(qword)*(6+10)],r10 + mov qword [rdi+sizeof(qword)*(6+11)],r11 + mov qword [rdi+sizeof(qword)*(6+12)],r12 + mov qword [rdi+sizeof(qword)*(6+13)],rbx + + sub rdi, sizeof(qword)*8 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + ADD_DIAG 2, rdi, rsi + + sub rsi, sizeof(qword)*(4*3) + sub rdi, sizeof(qword)*(8*3) + ret +ENDFUNC sqr_14 + + +;; +;; 15*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_15,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*5 + sub rcx, sizeof(qword)*5 + + mov qword [rdi+sizeof(qword)*(7+0)], r8 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11,r10, , , r9, [rdi+sizeof(qword)*(7+1)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13,r12, , , , r10,[rdi+sizeof(qword)*(7+2)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15,r14, , , , , r11,[rdi+sizeof(qword)*(7+3)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, r8, , , , , , r12,[rdi+sizeof(qword)*(7+4)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11,r10, , , , , , , r13,[rdi+sizeof(qword)*(7+5)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*13] + SQR_512_TRIANGLE_STEP r13, r12, , , , , , , , r14,[rdi+sizeof(qword)*(7+6)],{rsi+sizeof(qword)*7}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(7+7)], r15 + mov qword [rdi+sizeof(qword)*(7+8)], r8 + mov qword [rdi+sizeof(qword)*(7+9)], r9 + mov qword [rdi+sizeof(qword)*(7+10)],r10 + mov qword [rdi+sizeof(qword)*(7+11)],r11 + mov qword [rdi+sizeof(qword)*(7+12)],r12 + mov qword [rdi+sizeof(qword)*(7+13)],r13 + mov qword [rdi+sizeof(qword)*(7+14)],rbx + + sub rdi, sizeof(qword)*8 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + ADD_DIAG 3, rdi, rsi + + sub rsi, sizeof(qword)*(4*3) + sub rdi, sizeof(qword)*(8*3) + ret +ENDFUNC sqr_15 + + +;; +;; 16*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_16,PRIVATE + call sqr8_triangle + + mov qword [rdi+sizeof(qword)*7], r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + sub rdi, sizeof(qword)*6 + sub rcx, sizeof(qword)*6 + + add rdi, sizeof(qword)*8 + call sqr8_triangle + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*7], r15 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],rbx + + sub rsi, sizeof(qword)*8 + sub rdi, sizeof(qword)*16 + + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*4 + call add_diag_4 + + sub rsi, sizeof(qword)*12 + sub rdi, sizeof(qword)*24 + ret +ENDFUNC sqr_16 + + + +;; +;; 9*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr9_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x1 + + xor rax, rax + mov qword [rdi+sizeof(qword)*(1+0)], r8 + mov qword [rdi+sizeof(qword)*(1+1)], r9 + mov qword [rdi+sizeof(qword)*(1+2)], r10 + mov qword [rdi+sizeof(qword)*(1+3)], r11 + mov qword [rdi+sizeof(qword)*(1+4)], r12 + mov qword [rdi+sizeof(qword)*(1+5)], r13 + mov qword [rdi+sizeof(qword)*(1+6)], r14 + mov qword [rdi+sizeof(qword)*(1+7)], r15 + mov qword [rdi+sizeof(qword)*(1+8)], rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr9_triangle + + +;; +;; 10*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr10_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x2 + + mov qword [rdi+sizeof(qword)*(2+0)], r8 + mov qword [rdi+sizeof(qword)*(2+1)], r9 + mov qword [rdi+sizeof(qword)*(2+2)], r10 + mov qword [rdi+sizeof(qword)*(2+3)], r11 + mov qword [rdi+sizeof(qword)*(2+4)], r12 + mov qword [rdi+sizeof(qword)*(2+5)], r13 + mov qword [rdi+sizeof(qword)*(2+6)], r14 + + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15, , , , , , , , , , {rsi+sizeof(qword)*2}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(2+7)], r15 + mov qword [rdi+sizeof(qword)*(2+8)], r8 + mov qword [rdi+sizeof(qword)*(2+9)], rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr10_triangle + + +;; +;; 11*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr11_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x3 + + mov qword [rdi+sizeof(qword)*(3+0)], r8 + mov qword [rdi+sizeof(qword)*(3+1)], r9 + mov qword [rdi+sizeof(qword)*(3+2)], r10 + mov qword [rdi+sizeof(qword)*(3+3)], r11 + mov qword [rdi+sizeof(qword)*(3+4)], r12 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14, , , , , , , r13,[rdi+sizeof(qword)*(3+5)],{rsi+sizeof(qword)*3}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8, , , , , , , , r14,[rdi+sizeof(qword)*(3+6)],{rsi+sizeof(qword)*3}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(3+7)], r15 + mov qword [rdi+sizeof(qword)*(3+8)], r8 + mov qword [rdi+sizeof(qword)*(3+9)], r9 + mov qword [rdi+sizeof(qword)*(3+10)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr11_triangle + + +;; +;; 12*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr12_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x4 + + mov qword [rdi+sizeof(qword)*(4+0)], r8 + mov qword [rdi+sizeof(qword)*(4+1)], r9 + mov qword [rdi+sizeof(qword)*(4+2)], r10 + mov qword [rdi+sizeof(qword)*(4+3)], r11 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13, , , , , , r12,[rdi+sizeof(qword)*(4+4)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15, , , , , , , r13,[rdi+sizeof(qword)*(4+5)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, , , , , , , , r14,[rdi+sizeof(qword)*(4+6)],{rsi+sizeof(qword)*4}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(4+7)], r15 + mov qword [rdi+sizeof(qword)*(4+8)], r8 + mov qword [rdi+sizeof(qword)*(4+9)], r9 + mov qword [rdi+sizeof(qword)*(4+10)],r10 + mov qword [rdi+sizeof(qword)*(4+11)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr12_triangle + + +;; +;; 13*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr13_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x5 + + mov qword [rdi+sizeof(qword)*(5+0)], r8 + mov qword [rdi+sizeof(qword)*(5+1)], r9 + mov qword [rdi+sizeof(qword)*(5+2)], r10 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12, , , , , r11,[rdi+sizeof(qword)*(5+3)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14, , , , , , r12,[rdi+sizeof(qword)*(5+4)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8, , , , , , , r13,[rdi+sizeof(qword)*(5+5)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, , , , , , , , r14,[rdi+sizeof(qword)*(5+6)],{rsi+sizeof(qword)*5}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(5+7)], r15 + mov qword [rdi+sizeof(qword)*(5+8)], r8 + mov qword [rdi+sizeof(qword)*(5+9)], r9 + mov qword [rdi+sizeof(qword)*(5+10)],r10 + mov qword [rdi+sizeof(qword)*(5+11)],r11 + mov qword [rdi+sizeof(qword)*(5+12)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr13_triangle + + +;; +;; 14*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr14_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x6 + + mov qword [rdi+sizeof(qword)*(6+0)], r8 + mov qword [rdi+sizeof(qword)*(6+1)], r9 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11, , , , r10,[rdi+sizeof(qword)*(6+2)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13, , , , , r11,[rdi+sizeof(qword)*(6+3)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15, , , , , , r12,[rdi+sizeof(qword)*(6+4)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, , , , , , , r13,[rdi+sizeof(qword)*(6+5)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11, , , , , , , , r14,[rdi+sizeof(qword)*(6+6)],{rsi+sizeof(qword)*6}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(6+7)], r15 + mov qword [rdi+sizeof(qword)*(6+8)], r8 + mov qword [rdi+sizeof(qword)*(6+9)], r9 + mov qword [rdi+sizeof(qword)*(6+10)],r10 + mov qword [rdi+sizeof(qword)*(6+11)],r11 + mov qword [rdi+sizeof(qword)*(6+12)],r12 + mov qword [rdi+sizeof(qword)*(6+13)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr14_triangle + + +;; +;; 15*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr15_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x7 + + mov qword [rdi+sizeof(qword)*(7+0)], r8 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11,r10, , , r9, [rdi+sizeof(qword)*(7+1)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13,r12, , , , r10,[rdi+sizeof(qword)*(7+2)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15,r14, , , , , r11,[rdi+sizeof(qword)*(7+3)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, r8, , , , , , r12,[rdi+sizeof(qword)*(7+4)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11,r10, , , , , , , r13,[rdi+sizeof(qword)*(7+5)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*13] + SQR_512_TRIANGLE_STEP r13, r12, , , , , , , , r14,[rdi+sizeof(qword)*(7+6)],{rsi+sizeof(qword)*7}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(7+7)], r15 + mov qword [rdi+sizeof(qword)*(7+8)], r8 + mov qword [rdi+sizeof(qword)*(7+9)], r9 + mov qword [rdi+sizeof(qword)*(7+10)],r10 + mov qword [rdi+sizeof(qword)*(7+11)],r11 + mov qword [rdi+sizeof(qword)*(7+12)],r12 + mov qword [rdi+sizeof(qword)*(7+13)],r13 + mov qword [rdi+sizeof(qword)*(7+14)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr15_triangle + + +;; +;; 16*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr16_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + call mla_8x8 + + add rdi, sizeof(qword)*8 + call sqr8_triangle + + xor rax, rax + mov qword [rdi+sizeof(qword)*7], r15 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],rax + + sub rsi, sizeof(qword)*8 + sub rdi, sizeof(qword)*16 + ret +ENDFUNC sqr16_triangle + + +sqr_l_basic dq sqr_1 - sqr_l_basic + dq sqr_2 - sqr_l_basic + dq sqr_3 - sqr_l_basic + dq sqr_4 - sqr_l_basic + dq sqr_5 - sqr_l_basic + dq sqr_6 - sqr_l_basic + dq sqr_7 - sqr_l_basic + dq sqr_8 - sqr_l_basic + dq sqr_9 - sqr_l_basic + dq sqr_10- sqr_l_basic + dq sqr_11- sqr_l_basic + dq sqr_12- sqr_l_basic + dq sqr_13- sqr_l_basic + dq sqr_14- sqr_l_basic + dq sqr_15- sqr_l_basic + dq sqr_16- sqr_l_basic + +sqrN_triangle dq sqr9_triangle - sqrN_triangle + dq sqr10_triangle - sqrN_triangle + dq sqr11_triangle - sqrN_triangle + dq sqr12_triangle - sqrN_triangle + dq sqr13_triangle - sqrN_triangle + dq sqr14_triangle - sqrN_triangle + dq sqr15_triangle - sqrN_triangle + dq sqr16_triangle - sqrN_triangle + +%endif ;; _PCPBNSQR_BASIC_ADCX_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrpp.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrpp.inc new file mode 100644 index 000000000..ef73b5b3f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrpp.inc @@ -0,0 +1,452 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number squaring Support +; +; + +%ifndef _PCPBNUSQR_INC_ +%assign _PCPBNUSQR_INC_ 1 + +%include "pcpmulx.inc" +%include "pcpbnusqrpp_basic.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; (8*n) squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_8N_adcox,PRIVATE + push rdi ; save diagonal loop parameters + push rsi + push rdx + + push rdi ; save initial triangle product parameters + push rsi + push rdx +; +; init upper triangle product +; + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + add rdi, sizeof(qword)*8 + + sub rdx, 8 + + mov rcx, rsi + add rsi, sizeof(qword)*8 +.initLoop: + push rdx + call mla_8x8 + pop rdx + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnz .initLoop + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + jmp .update_Triangle + +; +; update upper triangle product +; +.outerLoop: + push rdi ; update triangle product parameters + push rsi + push rdx + + xor rax, rax ; c-flag + push rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10, qword [rdi+sizeof(qword)*2] + mov r11, qword [rdi+sizeof(qword)*3] + mov r12, qword [rdi+sizeof(qword)*4] + mov r13, qword [rdi+sizeof(qword)*5] + mov r14, qword [rdi+sizeof(qword)*6] + mov r15, qword [rdi+sizeof(qword)*7] + +.innerLoop_entry: + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + add rdi, sizeof(qword)*8 + + sub rdx, 8 + jz .skipInnerLoop + + mov rcx, rsi + add rsi, sizeof(qword)*8 +.innerLoop: + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10, qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11, qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12, qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13, qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14, qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15, qword [rdi+sizeof(qword)*7], rax + sbb rax, rax ; save c-flag + push rax + + push rdx + call mla_8x8 + pop rdx + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnz .innerLoop + +.skipInnerLoop: + pop rax ; restore c-flag + neg rax + adc r8, 0 + mov qword [rdi+sizeof(qword)*0], r8 + adc r9, 0 + mov qword [rdi+sizeof(qword)*1], r9 + adc r10,0 + mov qword [rdi+sizeof(qword)*2],r10 + adc r11,0 + mov qword [rdi+sizeof(qword)*3],r11 + adc r12,0 + mov qword [rdi+sizeof(qword)*4],r12 + adc r13,0 + mov qword [rdi+sizeof(qword)*5],r13 + adc r14,0 + mov qword [rdi+sizeof(qword)*6],r14 + adc r15,0 + mov qword [rdi+sizeof(qword)*7],r15 + +.update_Triangle: + pop rdx + pop rsi + pop rdi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*(8*2) + sub rdx, 8 + jnz .outerLoop + +; +; add diagonal terms +; + pop rcx + pop rsi + pop rdi + call finalize + ret +ENDFUNC sqr_8N_adcox + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; general case N>16 squarer +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_N_adcox,PRIVATE + push rdi ; save diagonal loop parameters + push rsi + push rdx + + push rdi ; save initial triangle product parameters + push rsi + push rdx + + mov rbp, rdx + and rbp, 7 + GET_EP rax, mla_8xl_tail, rbp ; get tail procedure + push rax + +; +; init upper triangle product +; + sub rdx, 8 + + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + add rdi, sizeof(qword)*8 + xor r15, r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + sub rdx, 8 + +.initLoop: + push rdx + call mla_8x8 + pop rdx + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnc .initLoop + + add rdx, 8 +; +; tail +; + SWAP rsi, rcx + mov rax, [rsp] ; procedure + push rdx + call rax + pop rdx + lea rdi, [rdi+rdx*sizeof(qword)] + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2],r10 + mov qword [rdi+sizeof(qword)*3],r11 + mov qword [rdi+sizeof(qword)*4],r12 + mov qword [rdi+sizeof(qword)*5],r13 + mov qword [rdi+sizeof(qword)*6],r14 + mov qword [rdi+sizeof(qword)*7],r15 + jmp .update_Triangle + +; +; update upper triangle product +; +.outerLoop: + push rdi ; update triangle product parameters + push rsi + push rdx + push rax ; tail procedure + + xor rax, rax ; c-flag + push rax + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10, qword [rdi+sizeof(qword)*2] + mov r11, qword [rdi+sizeof(qword)*3] + mov r12, qword [rdi+sizeof(qword)*4] + mov r13, qword [rdi+sizeof(qword)*5] + mov r14, qword [rdi+sizeof(qword)*6] + mov r15, qword [rdi+sizeof(qword)*7] + + sub rdx, 8 + + push rdx + call sqr8_triangle + pop rdx + + mov qword [rdi+sizeof(qword)*7], r15 + add rdi, sizeof(qword)*8 + xor r15, r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + sub rdx, 8 + +.innerLoop: + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10, qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11, qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12, qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13, qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14, qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15, qword [rdi+sizeof(qword)*7], rax + sbb rax, rax ; save c-flag + push rax + + push rdx + call mla_8x8 + pop rdx + + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnc .innerLoop + + add rdx, 8 +; +; tail +; + ; clear in advance + pxor xmm0, xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)], xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)+sizeof(qword)*2], xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)+sizeof(qword)*4], xmm0 + movdqu xmmword [rdi+rdx*sizeof(qword)+sizeof(qword)*6], xmm0 + + ; updates registers before mla operation + pop rax ; restore c-flag + neg rax + op_reg_mem adc, r8, qword [rdi+sizeof(qword)*0], rax + op_reg_mem adc, r9, qword [rdi+sizeof(qword)*1], rax + op_reg_mem adc, r10, qword [rdi+sizeof(qword)*2], rax + op_reg_mem adc, r11, qword [rdi+sizeof(qword)*3], rax + op_reg_mem adc, r12, qword [rdi+sizeof(qword)*4], rax + op_reg_mem adc, r13, qword [rdi+sizeof(qword)*5], rax + op_reg_mem adc, r14, qword [rdi+sizeof(qword)*6], rax + op_reg_mem adc, r15, qword [rdi+sizeof(qword)*7], rax + + ; store carry for future + sbb rax, rax + neg rax + mov qword [rdi+sizeof(qword)*8], rax + + ; mla_8xn operation + SWAP rsi, rcx + mov rax, [rsp] ; procedure + push rdx + call rax + pop rdx + lea rdi, [rdi+rdx*sizeof(qword)] + + ; updates registers before store + xor rax, rax + mov rax, qword [rdi+sizeof(qword)*0] + add r8, rax + mov qword [rdi+sizeof(qword)*0], r8 + mov rax, qword [rdi+sizeof(qword)*1] + adc r9, rax + mov qword [rdi+sizeof(qword)*1], r9 + mov rax, qword [rdi+sizeof(qword)*2] + adc r10, rax + mov qword [rdi+sizeof(qword)*2], r10 + mov rax, qword [rdi+sizeof(qword)*3] + adc r11, rax + mov qword [rdi+sizeof(qword)*3], r11 + mov rax, qword [rdi+sizeof(qword)*4] + adc r12, rax + mov qword [rdi+sizeof(qword)*4], r12 + mov rax, qword [rdi+sizeof(qword)*5] + adc r13, rax + mov qword [rdi+sizeof(qword)*5], r13 + mov rax, qword [rdi+sizeof(qword)*6] + adc r14, rax + mov qword [rdi+sizeof(qword)*6], r14 + mov rax, qword [rdi+sizeof(qword)*7] + adc r15, rax + mov qword [rdi+sizeof(qword)*7], r15 + +.update_Triangle: + pop rax ; tail procedure + pop rdx + pop rsi + pop rdi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*(8*2) + sub rdx, 8 + cmp rdx, 16 + jg .outerLoop + +; +; tail +; + mov rbp, rdx + sub rbp, 8 + GET_EP rax, sqrN_triangle, rbp ; get triangle proc + + sub rsp, sizeof(qword)*32 + push rdi + push rdx + + mov r8, qword [rdi+sizeof(qword)*0] + mov r9, qword [rdi+sizeof(qword)*1] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + lea rdi, [rsp+sizeof(qword)*2] + call rax + + mov rsi, rdi + pop rdx + pop rdi + + ; copy 8 terms + movdqu xmm0, xmmword [rsi] + movdqu xmm1, xmmword [rsi+sizeof(qword)*2] + movdqu xmm2, xmmword [rsi+sizeof(qword)*4] + movdqu xmm3, xmmword [rsi+sizeof(qword)*6] + add rsi, sizeof(qword)*8 + movdqu xmmword [rdi], xmm0 + movdqu xmmword [rdi+sizeof(qword)*2], xmm1 + movdqu xmmword [rdi+sizeof(qword)*4], xmm2 + movdqu xmmword [rdi+sizeof(qword)*6], xmm3 + add rdi, sizeof(qword)*8 + + ; update rdx-8 terms + lea rax, [rdx-8] + xor rbx, rbx +.update1: + mov r8, qword [rsi] + mov r9, qword [rdi] + add rsi, sizeof(qword) + neg rbx + adc r8, r9 + sbb rbx, rbx + mov qword [rdi], r8 + add rdi, sizeof(qword) + sub rax, 1 + jg .update1 + + ; update rdx terms +.update2: + mov r8, qword [rsi] + add rsi, sizeof(qword) + neg rbx + adc r8, 0 + sbb rbx, rbx + mov qword [rdi], r8 + add rdi, sizeof(qword) + sub rdx, 1 + jg .update2 + + add rsp, sizeof(qword)*32 + +; +; add diagonal terms +; +.add_diagonals: + pop rcx + pop rsi + pop rdi + call finalize + +.quit: + ret +ENDFUNC sqr_N_adcox + + +%endif ;; _PCPBNUSQR_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrpp_basic.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrpp_basic.inc new file mode 100644 index 000000000..c1764c725 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrpp_basic.inc @@ -0,0 +1,1800 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number squaring Support +; +; + +%ifndef _PCPBNSQR_BASIC_ADCX_INC_ +%assign _PCPBNSQR_BASIC_ADCX_INC_ 1 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Fixed-size (1-8 qwords) square operations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; 1*qword squarer +;; +%macro SQR_64 2.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + + mov rdx, qword [%%pA] +gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + mov qword [%%pDst+sizeof(qword)], rdx +%endmacro + +align IPP_ALIGN_FACTOR +sqr_1: + SQR_64 rdi, rsi + ret + + +;; +;; 2*qword squarer +;; +%macro SQR_128 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov rdx, qword [%%pA+sizeof(qword)] + gsmulx rax, %%x1, qword [%%pA] ; (rax:x1) = a[0]*a[1] + gsmulx %%x3, %%x2, rdx ; (x3 :x2) = a[1]^2 + mov rdx, qword [%%pA] ; a[0] + gsmulx rdx, %%x0, rdx ; (rdx:x0) = a[0]^2 + + add %%x1, %%x1 ; (rax:x1) = a[0]*a[1]*2 + adc rax,rax + adc %%x3, 0 + + mov qword [%%pDst+sizeof(qword)*0], %%x0 + add %%x1, rdx + mov qword [%%pDst+sizeof(qword)*1], %%x1 + adc %%x2, rax + mov qword [%%pDst+sizeof(qword)*2], %%x2 + adc %%x3, 0 + mov qword [%%pDst+sizeof(qword)*3], %%x3 +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_2,PRIVATE + SQR_128 rdi, rsi, r15,r14,r13,r12,r11,r10,r9,r8, rcx, rbx, rbp + ret +ENDFUNC sqr_2 + + + +;; +;; 3*qword squarer +;; +%macro SQR_192 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov rdx, [%%pA] ;; a[0]*{a[1],a[2]} + gsmulx %%x1, %%x0, [%%pA+sizeof(qword)*1] + gsmulx %%x2, rax,[%%pA+sizeof(qword)*2] + add %%x1, rax + adc %%x2, 0 + mov rdx, [%%pA+sizeof(qword)*1] ;; a[1]*a[2] + gsmulx %%x3, rax, [%%pA+sizeof(qword)*2] + add %%x2, rax + adc %%x3, 0 + + xor %%A, %%A + ;; square a[0],a[1],a[2] and add double x0,x1,x2,x3 + mov rdx, [%%pA+sizeof(qword)*0] + gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + gsadcx rdx, %%x0 + gsadox rdx, %%x0 + mov qword [%%pDst+sizeof(qword)], rdx + + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx rdx, rax, rdx + gsadcx rax, %%x1 + gsadox rax, %%x1 + mov qword [%%pDst+sizeof(qword)*2], rax + gsadcx rdx, %%x2 + gsadox rdx, %%x2 + mov qword [%%pDst+sizeof(qword)*3], rdx + + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx rdx, rax, rdx + gsadcx rax, %%x3 + gsadox rax, %%x3 + mov qword [%%pDst+sizeof(qword)*4], rax + gsadcx rdx, %%A + gsadox rdx, %%A + mov qword [%%pDst+sizeof(qword)*5], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_3,PRIVATE + SQR_192 rdi,rsi, r15,r14,r13,r12,r11,r10,r9,r8, rcx,rbx,rbp + ret +ENDFUNC sqr_3 + + + +;; +;; 4*qword squarer +;; +%macro SQR_256 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; 1-st pass a[0]*{a[1],a[2],a[3]} + mov rdx, [%%pA] + gsmulx %%x1, %%x0, [%%pA+sizeof(qword)*1] + xor %%A, %%A + gsmulx %%x2, rax,[%%pA+sizeof(qword)*2] + add %%x1, rax + gsmulx %%x3, rax,[%%pA+sizeof(qword)*3] + adc %%x2, rax + adc %%x3, 0 + + ;; 2-nd pass a[1]*{a[2],a[3]} + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + gsadcx %%x2, rax + gsadox %%x3, %%t0 + gsmulx %%x4, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x3, rax + gsadox %%x4, %%A + adc %%x4, 0 + + ;; 3-rd pass a[2]*a[3] + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx %%x5, rax, [%%pA+sizeof(qword)*3] + add %%x4, rax + adc %%x5, 0 + + ;; square a[0],...,a[3] and add double x0,...,,x5 + mov rdx, [%%pA+sizeof(qword)*0] + gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + gsadcx rdx, %%x0 + gsadox rdx, %%x0 + mov qword [%%pDst+sizeof(qword)], rdx + + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx rdx, rax, rdx + gsadcx rax, %%x1 + gsadox rax, %%x1 + mov qword [%%pDst+sizeof(qword)*2], rax + gsadcx rdx, %%x2 + gsadox rdx, %%x2 + mov qword [%%pDst+sizeof(qword)*3], rdx + + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx rdx, rax, rdx + gsadcx rax, %%x3 + gsadox rax, %%x3 + mov qword [%%pDst+sizeof(qword)*4], rax + gsadcx rdx, %%x4 + gsadox rdx, %%x4 + mov qword [%%pDst+sizeof(qword)*5], rdx + + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx rdx, rax, rdx + gsadcx rax, %%x5 + gsadox rax, %%x5 + mov qword [%%pDst+sizeof(qword)*6], rax + gsadcx rdx, %%A + gsadox rdx, %%A + mov qword [%%pDst+sizeof(qword)*7], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_4,PRIVATE + SQR_256 rdi,rsi, r15,r14,r13,r12,r11,r10,r9,r8, rcx,rbx,rbp + ret +ENDFUNC sqr_4 + + + +;; +;; 5*qword squarer +;; +%macro SQR_320 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; 1-st pass a[0]*{a[1],...,a[4]} + mov rdx, [%%pA] + gsmulx %%x1, %%x0, [%%pA+sizeof(qword)*1] + xor %%A, %%A + gsmulx %%x2, rax,[%%pA+sizeof(qword)*2] + add %%x1, rax + gsmulx %%x3, rax,[%%pA+sizeof(qword)*3] + adc %%x2, rax + gsmulx %%x4, rax,[%%pA+sizeof(qword)*4] + adc %%x3, rax + adc %%x4, 0 + + ;; 2-nd pass a[1]*{a[2],...,a[4]} + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + gsadcx %%x2, rax + gsadox %%x3, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x3, rax + gsadox %%x4, %%t0 + gsmulx %%x5, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x4, rax + gsadox %%x5, %%A + adc %%x5, 0 + + ;; 3-rd pass a[2]*{a[3],a[4]} + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x4, rax + gsadox %%x5, %%t0 + gsmulx %%x6, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x5, rax + gsadox %%x6, %%A + adc %%x6, 0 + + ;; 4-th pass a[3]*a[4] + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx %%x7, rax, [%%pA+sizeof(qword)*4] + add %%x6, rax + adc %%x7, 0 + + ;; square a[0],...,a[4] and add double x0,...,,x7 + mov rdx, [%%pA+sizeof(qword)*0] + gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + gsadcx rdx, %%x0 + gsadox rdx, %%x0 + mov qword [%%pDst+sizeof(qword)], rdx + + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx rdx, rax, rdx + gsadcx rax, %%x1 + gsadox rax, %%x1 + mov qword [%%pDst+sizeof(qword)*2], rax + gsadcx rdx, %%x2 + gsadox rdx, %%x2 + mov qword [%%pDst+sizeof(qword)*3], rdx + + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx rdx, rax, rdx + gsadcx rax, %%x3 + gsadox rax, %%x3 + mov qword [%%pDst+sizeof(qword)*4], rax + gsadcx rdx, %%x4 + gsadox rdx, %%x4 + mov qword [%%pDst+sizeof(qword)*5], rdx + + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx rdx, rax, rdx + gsadcx rax, %%x5 + gsadox rax, %%x5 + mov qword [%%pDst+sizeof(qword)*6], rax + gsadcx rdx, %%x6 + gsadox rdx, %%x6 + mov qword [%%pDst+sizeof(qword)*7], rdx + + mov rdx, [%%pA+sizeof(qword)*4] + gsmulx rdx, rax, rdx + gsadcx rax, %%x7 + gsadox rax, %%x7 + mov qword [%%pDst+sizeof(qword)*8], rax + gsadcx rdx, %%A + gsadox rdx, %%A + mov qword [%%pDst+sizeof(qword)*9], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_5,PRIVATE + SQR_320 rdi,rsi, r15,r14,r13,r12,r11,r10,r9,r8, rcx,rbx,rbp + ret +ENDFUNC sqr_5 + + + +;; +;; 6*qword squarer +;; +%macro SQR_384 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; 1-st pass a[0]*{a[1],...,a[5]} + mov rdx, [%%pA] + gsmulx %%x1, %%x0, [%%pA+sizeof(qword)*1] + xor %%A, %%A + gsmulx %%x2, rax,[%%pA+sizeof(qword)*2] + add %%x1, rax + gsmulx %%x3, rax,[%%pA+sizeof(qword)*3] + adc %%x2, rax + gsmulx %%x4, rax,[%%pA+sizeof(qword)*4] + adc %%x3, rax + gsmulx %%x5, rax,[%%pA+sizeof(qword)*5] + adc %%x4, rax + adc %%x5, 0 + + ;; 2-nd pass a[1]*{a[2],...,a[5]} + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + gsadcx %%x2, rax + gsadox %%x3, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x3, rax + gsadox %%x4, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x4, rax + gsadox %%x5, %%t0 + gsmulx %%x6, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x5, rax + gsadox %%x6, %%A + adc %%x6, 0 + + ;; 3-rd pass a[2]*{a[3],a[4],a[5]} + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x4, rax + gsadox %%x5, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x5, rax + gsadox %%x6, %%t0 + gsmulx %%x7, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x6, rax + gsadox %%x7, %%A + adc %%x7, 0 + + ;; 4-th pass a[3]*{a[4],a[5]} + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x6, rax + gsadox %%x7, %%t0 + gsmulx %%x8, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x7, rax + gsadox %%x8, %%A + adc %%x8, 0 + + ;; 5-th pass a[4]*a[5] + mov rdx, [%%pA+sizeof(qword)*4] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + add %%x8, rax + adc %%t0, 0 + + ;; square a[0],...,a[5] and add double x0,...,x7,x8,t0 + mov rdx, [%%pA+sizeof(qword)*0] + gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + gsadcx rdx, %%x0 + gsadox rdx, %%x0 + mov qword [%%pDst+sizeof(qword)], rdx + + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx rdx, rax, rdx + gsadcx rax, %%x1 + gsadox rax, %%x1 + mov qword [%%pDst+sizeof(qword)*2], rax + gsadcx rdx, %%x2 + gsadox rdx, %%x2 + mov qword [%%pDst+sizeof(qword)*3], rdx + + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx rdx, rax, rdx + gsadcx rax, %%x3 + gsadox rax, %%x3 + mov qword [%%pDst+sizeof(qword)*4], rax + gsadcx rdx, %%x4 + gsadox rdx, %%x4 + mov qword [%%pDst+sizeof(qword)*5], rdx + + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx rdx, rax, rdx + gsadcx rax, %%x5 + gsadox rax, %%x5 + mov qword [%%pDst+sizeof(qword)*6], rax + gsadcx rdx, %%x6 + gsadox rdx, %%x6 + mov qword [%%pDst+sizeof(qword)*7], rdx + + mov rdx, [%%pA+sizeof(qword)*4] + gsmulx rdx, rax, rdx + gsadcx rax, %%x7 + gsadox rax, %%x7 + mov qword [%%pDst+sizeof(qword)*8], rax + gsadcx rdx, %%x8 + gsadox rdx, %%x8 + mov qword [%%pDst+sizeof(qword)*9], rdx + + mov rdx, [%%pA+sizeof(qword)*5] + gsmulx rdx, rax, rdx + gsadcx rax, %%t0 + gsadox rax, %%t0 + mov qword [%%pDst+sizeof(qword)*10], rax + gsadcx rdx, %%A + gsadox rdx, %%A + mov qword [%%pDst+sizeof(qword)*11], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_6,PRIVATE + SQR_384 rdi,rsi, r15,r14,r13,r12,r11,r10,r9,r8, rcx,rbx,rbp + ret +ENDFUNC sqr_6 + + + +;; +;; 7*qword squarer +;; +%macro SQR_448 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; 1-st pass a[0]*{a[1],...,a[6]} + mov rdx, [%%pA] + gsmulx %%x1, %%x0, [%%pA+sizeof(qword)*1] + xor %%A, %%A + gsmulx %%x2, rax,[%%pA+sizeof(qword)*2] + add %%x1, rax + gsmulx %%x3, rax,[%%pA+sizeof(qword)*3] + adc %%x2, rax + gsmulx %%x4, rax,[%%pA+sizeof(qword)*4] + adc %%x3, rax + gsmulx %%x5, rax,[%%pA+sizeof(qword)*5] + adc %%x4, rax + gsmulx %%x6, rax,[%%pA+sizeof(qword)*6] + adc %%x5, rax + adc %%x6, 0 + + mov [%%pDst+sizeof(qword)*1], %%x0 + mov [%%pDst+sizeof(qword)*2], %%x1 + + ;; 2-nd pass a[1]*{a[2],...,a[6]} + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + gsadcx %%x2, rax + gsadox %%x3, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x3, rax + gsadox %%x4, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x4, rax + gsadox %%x5, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x5, rax + gsadox %%x6, %%t0 + gsmulx %%x7, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x6, rax + gsadox %%x7, %%A + adc %%x7, 0 + + mov [%%pDst+sizeof(qword)*3], %%x2 + + ;; 3-rd pass a[2]*{a[3],...,a[6]} + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x4, rax + gsadox %%x5, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x5, rax + gsadox %%x6, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x6, rax + gsadox %%x7, %%t0 + gsmulx %%x8, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x7, rax + gsadox %%x8, %%A + adc %%x8, 0 + + ;; 4-rd pass a[3]*{a[4],...,a[6]} + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x6, rax + gsadox %%x7, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x7, rax + gsadox %%x8, %%t0 + gsmulx %%x0, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x8, rax + gsadox %%x0, %%A + adc %%x0, 0 + + ;; 5-rd pass a[4]*{a[5],a[6]} + mov rdx, [%%pA+sizeof(qword)*4] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x8, rax + gsadox %%x0, %%t0 + gsmulx %%x1, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x0, rax + gsadox %%x1, %%A + adc %%x1, 0 + + ;; 6-rd pass a[5]*a[6] + mov rdx, [%%pA+sizeof(qword)*5] + gsmulx %%x2, rax, [%%pA+sizeof(qword)*6] + add %%x1, rax + adc %%x2, 0 + + ;; square a[0],...,a[5] and add double + mov rdx, [%%pA+sizeof(qword)*0] + gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + gsadcx rdx, qword [%%pDst+sizeof(qword)] + gsadox rdx, qword [%%pDst+sizeof(qword)] + mov qword [%%pDst+sizeof(qword)], rdx + + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx rdx, rax, rdx + gsadcx rax, qword [%%pDst+sizeof(qword)*2] + gsadox rax, qword [%%pDst+sizeof(qword)*2] + mov qword [%%pDst+sizeof(qword)*2], rax + gsadcx rdx, qword [%%pDst+sizeof(qword)*3] + gsadox rdx, qword [%%pDst+sizeof(qword)*3] + mov qword [%%pDst+sizeof(qword)*3], rdx + + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx rdx, rax, rdx + gsadcx rax, %%x3 + gsadox rax, %%x3 + mov qword [%%pDst+sizeof(qword)*4], rax + gsadcx rdx, %%x4 + gsadox rdx, %%x4 + mov qword [%%pDst+sizeof(qword)*5], rdx + + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx rdx, rax, rdx + gsadcx rax, %%x5 + gsadox rax, %%x5 + mov qword [%%pDst+sizeof(qword)*6], rax + gsadcx rdx, %%x6 + gsadox rdx, %%x6 + mov qword [%%pDst+sizeof(qword)*7], rdx + + mov rdx, [%%pA+sizeof(qword)*4] + gsmulx rdx, rax, rdx + gsadcx rax, %%x7 + gsadox rax, %%x7 + mov qword [%%pDst+sizeof(qword)*8], rax + gsadcx rdx, %%x8 + gsadox rdx, %%x8 + mov qword [%%pDst+sizeof(qword)*9], rdx + + mov rdx, [%%pA+sizeof(qword)*5] + gsmulx rdx, rax, rdx + gsadcx rax, %%x0 + gsadox rax, %%x0 + mov qword [%%pDst+sizeof(qword)*10], rax + gsadcx rdx, %%x1 + gsadox rdx, %%x1 + mov qword [%%pDst+sizeof(qword)*11], rdx + + mov rdx, [%%pA+sizeof(qword)*6] + gsmulx rdx, rax, rdx + gsadcx rax, %%x2 + gsadox rax, %%x2 + mov qword [%%pDst+sizeof(qword)*12], rax + gsadcx rdx, %%A + gsadox rdx, %%A + mov qword [%%pDst+sizeof(qword)*13], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_7,PRIVATE + SQR_448 rdi,rsi, r15,r14,r13,r12,r11,r10,r9,r8, rcx,rbx,rbp + ret +ENDFUNC sqr_7 + + + +;; +;; 8*qword squarer +;; +%macro SQR_512 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; 1-st pass a[0]*{a[1],...,a[7]} + mov rdx, [%%pA] + gsmulx %%x1, %%x0, [%%pA+sizeof(qword)*1] + xor %%A, %%A + gsmulx %%x2, rax,[%%pA+sizeof(qword)*2] + add %%x1, rax + gsmulx %%x3, rax,[%%pA+sizeof(qword)*3] + adc %%x2, rax + gsmulx %%x4, rax,[%%pA+sizeof(qword)*4] + adc %%x3, rax + gsmulx %%x5, rax,[%%pA+sizeof(qword)*5] + adc %%x4, rax + gsmulx %%x6, rax,[%%pA+sizeof(qword)*6] + adc %%x5, rax + gsmulx %%x7, rax,[%%pA+sizeof(qword)*7] + adc %%x6, rax + adc %%x7, 0 + + mov [%%pDst+sizeof(qword)*1], %%x0 + mov [%%pDst+sizeof(qword)*2], %%x1 + + ;; 2-nd pass a[1]*{a[2],...,a[7]} + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*2] + gsadcx %%x2, rax + gsadox %%x3, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x3, rax + gsadox %%x4, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x4, rax + gsadox %%x5, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x5, rax + gsadox %%x6, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x6, rax + gsadox %%x7, %%t0 + gsmulx %%x8, rax, [%%pA+sizeof(qword)*7] + gsadcx %%x7, rax + gsadox %%x8, %%A + adc %%x8, 0 + + mov [%%pDst+sizeof(qword)*3], %%x2 + mov [%%pDst+sizeof(qword)*4], %%x3 + + ;; 3-rd pass a[2]*{a[3],...,a[7]} + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*3] + gsadcx %%x4, rax + gsadox %%x5, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x5, rax + gsadox %%x6, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x6, rax + gsadox %%x7, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x7, rax + gsadox %%x8, %%t0 + gsmulx %%x0, rax, [%%pA+sizeof(qword)*7] + gsadcx %%x8, rax + gsadox %%x0, %%A + adc %%x0, 0 + + ;; 4-rd pass a[3]*{a[4],...,a[7]} + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*4] + gsadcx %%x6, rax + gsadox %%x7, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x7, rax + gsadox %%x8, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x8, rax + gsadox %%x0, %%t0 + gsmulx %%x1, rax, [%%pA+sizeof(qword)*7] + gsadcx %%x0, rax + gsadox %%x1, %%A + adc %%x1, 0 + + ;; 5-rd pass a[4]*{a[5],...,a[7]} + mov rdx, [%%pA+sizeof(qword)*4] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*5] + gsadcx %%x8, rax + gsadox %%x0, %%t0 + gsmulx %%t0, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x0, rax + gsadox %%x1, %%t0 + gsmulx %%x2, rax, [%%pA+sizeof(qword)*7] + gsadcx %%x1, rax + gsadox %%x2, %%A + adc %%x2, 0 + + ;; 6-rd pass a[5]*{a[6],a[7]} + mov rdx, [%%pA+sizeof(qword)*5] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*6] + gsadcx %%x1, rax + gsadox %%x2, %%t0 + gsmulx %%x3, rax, [%%pA+sizeof(qword)*7] + gsadcx %%x2, rax + gsadox %%x3, %%A + adc %%x3, 0 + + ;; 7-rd pass a[6]*a[7] + mov rdx, [%%pA+sizeof(qword)*6] + gsmulx %%t0, rax, [%%pA+sizeof(qword)*7] + add %%x3, rax + adc %%t0, 0 + + ;; square a[0],...,a[7] and add double + mov rdx, [%%pA+sizeof(qword)*0] + gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + gsadcx rdx, qword [%%pDst+sizeof(qword)] + gsadox rdx, qword [%%pDst+sizeof(qword)] + mov qword [%%pDst+sizeof(qword)], rdx + + mov rdx, [%%pA+sizeof(qword)*1] + gsmulx rdx, rax, rdx + gsadcx rax, qword [%%pDst+sizeof(qword)*2] + gsadox rax, qword [%%pDst+sizeof(qword)*2] + mov qword [%%pDst+sizeof(qword)*2], rax + gsadcx rdx, qword [%%pDst+sizeof(qword)*3] + gsadox rdx, qword [%%pDst+sizeof(qword)*3] + mov qword [%%pDst+sizeof(qword)*3], rdx + + mov rdx, [%%pA+sizeof(qword)*2] + gsmulx rdx, rax, rdx + gsadcx rax, qword [%%pDst+sizeof(qword)*4] + gsadox rax, qword [%%pDst+sizeof(qword)*4] + mov qword [%%pDst+sizeof(qword)*4], rax + gsadcx rdx, %%x4 + gsadox rdx, %%x4 + mov qword [%%pDst+sizeof(qword)*5], rdx + + mov rdx, [%%pA+sizeof(qword)*3] + gsmulx rdx, rax, rdx + gsadcx rax, %%x5 + gsadox rax, %%x5 + mov qword [%%pDst+sizeof(qword)*6], rax + gsadcx rdx, %%x6 + gsadox rdx, %%x6 + mov qword [%%pDst+sizeof(qword)*7], rdx + + mov rdx, [%%pA+sizeof(qword)*4] + gsmulx rdx, rax, rdx + gsadcx rax, %%x7 + gsadox rax, %%x7 + mov qword [%%pDst+sizeof(qword)*8], rax + gsadcx rdx, %%x8 + gsadox rdx, %%x8 + mov qword [%%pDst+sizeof(qword)*9], rdx + + mov rdx, [%%pA+sizeof(qword)*5] + gsmulx rdx, rax, rdx + gsadcx rax, %%x0 + gsadox rax, %%x0 + mov qword [%%pDst+sizeof(qword)*10], rax + gsadcx rdx, %%x1 + gsadox rdx, %%x1 + mov qword [%%pDst+sizeof(qword)*11], rdx + + mov rdx, [%%pA+sizeof(qword)*6] + gsmulx rdx, rax, rdx + gsadcx rax, %%x2 + gsadox rax, %%x2 + mov qword [%%pDst+sizeof(qword)*12], rax + gsadcx rdx, %%x3 + gsadox rdx, %%x3 + mov qword [%%pDst+sizeof(qword)*13], rdx + + mov rdx, [%%pA+sizeof(qword)*7] + gsmulx rdx, rax, rdx + gsadcx rax, %%t0 + gsadox rax, %%t0 + mov qword [%%pDst+sizeof(qword)*14], rax + gsadcx rdx, %%A + gsadox rdx, %%A + mov qword [%%pDst+sizeof(qword)*15], rdx +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_8,PRIVATE + SQR_512 rdi, rsi, r15,r14,r13,r12,r11,r10,r9,r8, rcx, rbx, rbp + ret +ENDFUNC sqr_8 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; SQR_512_TRIANGLE_STEP +; executes single line of upper triangle +; +; Inp:partial sum: x7 x6 x5 x4 x3 x2 x1 x0 +; rdx * pA[] p p p p p p p p p +; Out: x0 x7 x6 x5 x4 x3 x2 x1 +; [dst] + +%macro SQR_512_TRIANGLE_STEP 14.nolist + %xdefine %%HEAD_X %1 + %xdefine %%X7 %2 + %xdefine %%X6 %3 + %xdefine %%X5 %4 + %xdefine %%X4 %5 + %xdefine %%X3 %6 + %xdefine %%X2 %7 + %xdefine %%X1 %8 + %xdefine %%X0 %9 + %xdefine %%TAIL_X %10 + %xdefine %%pDst %11 + %xdefine %%pA %12 + %xdefine %%TMP1 %13 + %xdefine %%TMP2 %14 + + xor rax, rax + +%ifnempty %%X0 +gsmulx %%TMP2,%%TMP1, [%%pA+sizeof(qword)*0] ; TMP2:TMP1 = rdx * pA[0] +gsadcx %%X0, %%TMP1 +gsadox %%X1, %%TMP2 +%endif + +%ifnempty %%TAIL_X + mov %%pDst, %%TAIL_X +%endif + +%ifnempty %%X1 +gsmulx %%TMP2,%%TMP1, [%%pA+sizeof(qword)*1] ; TMP2:TMP1 = rdx * pA[1] +gsadcx %%X1, %%TMP1 +gsadox %%X2, %%TMP2 +%endif + +%ifnempty %%X2 +gsmulx %%TMP2,%%TMP1, [%%pA+sizeof(qword)*2] ; TMP2:TMP1 = rdx * pA[2] +gsadcx %%X2, %%TMP1 +gsadox %%X3, %%TMP2 +%endif + +%ifnempty %%X3 +gsmulx %%TMP2,%%TMP1, [%%pA+sizeof(qword)*3] ; TMP2:TMP1 = rdx * pA[3] +gsadcx %%X3, %%TMP1 +gsadox %%X4, %%TMP2 +%endif + +%ifnempty %%X4 +gsmulx %%TMP2,%%TMP1, [%%pA+sizeof(qword)*4] ; TMP2:TMP1 = rdx * pA[4] +gsadcx %%X4, %%TMP1 +gsadox %%X5, %%TMP2 +%endif + +%ifnempty %%X5 +gsmulx %%TMP2,%%TMP1, [%%pA+sizeof(qword)*5] ; TMP2:TMP1 = rdx * pA[5] +gsadcx %%X5, %%TMP1 +gsadox %%X6, %%TMP2 +%endif + +%ifnempty %%X6 +gsmulx %%TMP2,%%TMP1, [%%pA+sizeof(qword)*6] ; TMP2:TMP1 = rdx * pA[6] +gsadcx %%X6, %%TMP1 +gsadox %%X7, %%TMP2 +%endif + +%ifnempty %%X7 +gsmulx %%HEAD_X,%%TMP1, [%%pA+sizeof(qword)*7] ; X0:TMP1 = rdx * pA[7] +gsadcx %%X7, %%TMP1 +gsadox %%HEAD_X, rax + adc %%HEAD_X, 0 +%endif +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; square and add diagonal terms +; + +;; rdi = dst +;; rsi = src +;; rcx = src lengh +%macro FINALIZE_FIX 3.nolist + %xdefine %%N %1 + %xdefine %%pDst %2 + %xdefine %%pSrc %3 + + xor rax, rax + mov rdx, qword [%%pSrc] + gsmulx rdx, rax, rdx + mov qword [%%pDst], rax + gsadcx rdx, qword [%%pDst+sizeof(qword)] + gsadox rdx, qword [%%pDst+sizeof(qword)] + mov qword [rdi+sizeof(qword)], rdx + + %assign %%i 1 + %rep (%%N-2) + mov rdx, qword [%%pSrc+%%i*sizeof(qword)] + gsmulx rdx, rax, rdx + gsadcx rax, qword [%%pDst+(2*%%i)*sizeof(qword)] + gsadox rax, qword [%%pDst+(2*%%i)*sizeof(qword)] + mov qword [%%pDst+(2*%%i)*sizeof(qword)], rax + gsadcx rdx, qword [%%pDst+(2*%%i+1)*sizeof(qword)] + gsadox rdx, qword [%%pDst+(2*%%i+1)*sizeof(qword)] + mov qword [rdi+(2*%%i+1)*sizeof(qword)], rdx + %assign %%i %%i+1 + %endrep + + mov rdx, qword [%%pSrc+(%%N-1)*sizeof(qword)] + gsmulx rdx, rax, rdx + gsadcx rax, qword [%%pDst+(2*%%N-2)*sizeof(qword)] + gsadox rax, qword [%%pDst+(2*%%N-2)*sizeof(qword)] + mov qword [%%pDst+(2*%%N-2)*sizeof(qword)], rax + mov rax, dword 0 + gsadcx rdx, rax + gsadox rdx, rax + mov qword [rdi+(2*%%N-1)*sizeof(qword)], rdx +%endmacro + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC finalize,PRIVATE + push rcx + xor rax, rax + + mov rdx, qword [rsi] + gsmulx rdx, rax, rdx + lea rsi, [rsi+sizeof(qword)] + mov qword [rdi], rax + gsadcx rdx, qword [rdi+sizeof(qword)] + gsadox rdx, qword [rdi+sizeof(qword)] + mov qword [rdi+sizeof(qword)], rdx + lea rdi, [rdi+sizeof(qword)*2] + lea rcx, [rcx-2] + +.next_sqr: + mov rdx, qword [rsi] + gsmulx rdx, rax, rdx + lea rsi, [rsi+sizeof(qword)] + gsadcx rax, qword [rdi] + gsadox rax, qword [rdi] + mov qword [rdi], rax + gsadcx rdx, qword [rdi+sizeof(qword)] + gsadox rdx, qword [rdi+sizeof(qword)] + mov qword [rdi+sizeof(qword)], rdx + lea rdi, [rdi+sizeof(qword)*2] + lea rcx, [rcx-1] + jrcxz .last_sqr + jmp .next_sqr + +.last_sqr: + mov rdx, qword [rsi] + gsmulx rdx, rax, rdx + gsadcx rax, qword [rdi] + gsadox rax, qword [rdi] + mov qword [rdi], rax + mov rax, dword 0 + gsadcx rdx, rax + gsadox rdx, rax + mov qword [rdi+sizeof(qword)], rdx + + pop rcx + lea rax, [rcx*sizeof(qword)-sizeof(qword)] + sub rsi, rax + sub rdi, rax + sub rdi, rax + ret +ENDFUNC finalize + + +;; +;; 8*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr8_triangle,PRIVATE + ;; A[0]*A[1..7] + mov rdx, [rsi+sizeof(qword)*0] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11,r10, r9, , r8, [rdi+sizeof(qword)*0],rsi, rbx,rbp + + ;; A[1]*A[2..7] + mov rdx, [rsi+sizeof(qword)*1] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13,r12,r11, , , r9, [rdi+sizeof(qword)*1],rsi, rbx,rbp + + ;; A[2]*A[3..7] + mov rdx, [rsi+sizeof(qword)*2] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15,r14,r13, , , , r10, [rdi+sizeof(qword)*2],rsi, rbx,rbp + + ;; A[3]*A[4..7] + mov rdx, [rsi+sizeof(qword)*3] + SQR_512_TRIANGLE_STEP r11, r10, r9, r8,r15, , , , , r11, [rdi+sizeof(qword)*3],rsi, rbx,rbp + + ;; A[4]*A[5..7] + mov rdx, [rsi+sizeof(qword)*4] + SQR_512_TRIANGLE_STEP r12, r11,r10, r9, , , , , , r12, [rdi+sizeof(qword)*4],rsi, rbx,rbp + + ;; A[5]*A[6..7] + mov rdx, [rsi+sizeof(qword)*5] + SQR_512_TRIANGLE_STEP r13, r12,r11, , , , , , , r13, [rdi+sizeof(qword)*5],rsi, rbx,rbp + + ;; A[6]*A[7] + mov rdx, [rsi+sizeof(qword)*6] + SQR_512_TRIANGLE_STEP r14, r13, , , , , , , , r14, [rdi+sizeof(qword)*6],rsi, rbx,rbp + ret +ENDFUNC sqr8_triangle + + + +;; +;; 9*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_9,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + + mov qword [rdi+sizeof(qword)*(1+0)], r8 + mov qword [rdi+sizeof(qword)*(1+1)], r9 + mov qword [rdi+sizeof(qword)*(1+2)], r10 + mov qword [rdi+sizeof(qword)*(1+3)], r11 + mov qword [rdi+sizeof(qword)*(1+4)], r12 + mov qword [rdi+sizeof(qword)*(1+5)], r13 + mov qword [rdi+sizeof(qword)*(1+6)], r14 + mov qword [rdi+sizeof(qword)*(1+7)], r15 + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(1+8)], rbx + + sub rdi, sizeof(qword)*8 + + FINALIZE_FIX 9, rdi, rsi + ret +ENDFUNC sqr_9 + + +;; +;; 10*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_10,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + + mov qword [rdi+sizeof(qword)*(2+0)], r8 + mov qword [rdi+sizeof(qword)*(2+1)], r9 + mov qword [rdi+sizeof(qword)*(2+2)], r10 + mov qword [rdi+sizeof(qword)*(2+3)], r11 + mov qword [rdi+sizeof(qword)*(2+4)], r12 + mov qword [rdi+sizeof(qword)*(2+5)], r13 + mov qword [rdi+sizeof(qword)*(2+6)], r14 + + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15, , , , , , , , , , {rsi+sizeof(qword)*2}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(2+7)], r15 + mov qword [rdi+sizeof(qword)*(2+8)], r8 + mov qword [rdi+sizeof(qword)*(2+9)], rbx + + sub rdi, sizeof(qword)*8 + + FINALIZE_FIX 10, rdi, rsi + ret +ENDFUNC sqr_10 + + +;; +;; 10*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_11,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + add rdi, sizeof(qword)*1 + add rcx, sizeof(qword)*1 + call mla_8x2 + sub rdi, sizeof(qword)*1 + sub rcx, sizeof(qword)*1 + + mov qword [rdi+sizeof(qword)*(3+0)], r8 + mov qword [rdi+sizeof(qword)*(3+1)], r9 + mov qword [rdi+sizeof(qword)*(3+2)], r10 + mov qword [rdi+sizeof(qword)*(3+3)], r11 + mov qword [rdi+sizeof(qword)*(3+4)], r12 + + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14, , , , , , , r13,[rdi+sizeof(qword)*(3+5)],{rsi+sizeof(qword)*3}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8, , , , , , , , r14,[rdi+sizeof(qword)*(3+6)],{rsi+sizeof(qword)*3}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(3+7)], r15 + mov qword [rdi+sizeof(qword)*(3+8)], r8 + mov qword [rdi+sizeof(qword)*(3+9)], r9 + mov qword [rdi+sizeof(qword)*(3+10)],rbx + + sub rdi, sizeof(qword)*8 + + FINALIZE_FIX 11, rdi, rsi + ret +ENDFUNC sqr_11 + + +;; +;; 12*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_12,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*2 + sub rcx, sizeof(qword)*2 + + mov qword [rdi+sizeof(qword)*(4+0)], r8 + mov qword [rdi+sizeof(qword)*(4+1)], r9 + mov qword [rdi+sizeof(qword)*(4+2)], r10 + mov qword [rdi+sizeof(qword)*(4+3)], r11 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13, , , , , , r12,[rdi+sizeof(qword)*(4+4)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15, , , , , , , r13,[rdi+sizeof(qword)*(4+5)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, , , , , , , , r14,[rdi+sizeof(qword)*(4+6)],{rsi+sizeof(qword)*4}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(4+7)], r15 + mov qword [rdi+sizeof(qword)*(4+8)], r8 + mov qword [rdi+sizeof(qword)*(4+9)], r9 + mov qword [rdi+sizeof(qword)*(4+10)],r10 + mov qword [rdi+sizeof(qword)*(4+11)],rbx + + sub rdi, sizeof(qword)*8 + + FINALIZE_FIX 12, rdi, rsi + ret +ENDFUNC sqr_12 + + +;; +;; 13*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_13,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*3 + sub rcx, sizeof(qword)*3 + + mov qword [rdi+sizeof(qword)*(5+0)], r8 + mov qword [rdi+sizeof(qword)*(5+1)], r9 + mov qword [rdi+sizeof(qword)*(5+2)], r10 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12, , , , , r11,[rdi+sizeof(qword)*(5+3)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14, , , , , , r12,[rdi+sizeof(qword)*(5+4)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8, , , , , , , r13,[rdi+sizeof(qword)*(5+5)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, , , , , , , , r14,[rdi+sizeof(qword)*(5+6)],{rsi+sizeof(qword)*5}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(5+7)], r15 + mov qword [rdi+sizeof(qword)*(5+8)], r8 + mov qword [rdi+sizeof(qword)*(5+9)], r9 + mov qword [rdi+sizeof(qword)*(5+10)],r10 + mov qword [rdi+sizeof(qword)*(5+11)],r11 + mov qword [rdi+sizeof(qword)*(5+12)],rbx + + sub rdi, sizeof(qword)*8 + + FINALIZE_FIX 13, rdi, rsi + ret +ENDFUNC sqr_13 + + +;; +;; 14*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_14,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*4 + sub rcx, sizeof(qword)*4 + + mov qword [rdi+sizeof(qword)*(6+0)], r8 + mov qword [rdi+sizeof(qword)*(6+1)], r9 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11, , , , r10,[rdi+sizeof(qword)*(6+2)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13, , , , , r11,[rdi+sizeof(qword)*(6+3)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15, , , , , , r12,[rdi+sizeof(qword)*(6+4)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, , , , , , , r13,[rdi+sizeof(qword)*(6+5)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11, , , , , , , , r14,[rdi+sizeof(qword)*(6+6)],{rsi+sizeof(qword)*6}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(6+7)], r15 + mov qword [rdi+sizeof(qword)*(6+8)], r8 + mov qword [rdi+sizeof(qword)*(6+9)], r9 + mov qword [rdi+sizeof(qword)*(6+10)],r10 + mov qword [rdi+sizeof(qword)*(6+11)],r11 + mov qword [rdi+sizeof(qword)*(6+12)],r12 + mov qword [rdi+sizeof(qword)*(6+13)],rbx + + sub rdi, sizeof(qword)*8 + + FINALIZE_FIX 14, rdi, rsi + ret +ENDFUNC sqr_14 + + +;; +;; 15*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_15,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x1 + add rdi, sizeof(qword) + add rcx, sizeof(qword) + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + sub rdi, sizeof(qword)*5 + sub rcx, sizeof(qword)*5 + + mov qword [rdi+sizeof(qword)*(7+0)], r8 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11,r10, , , r9, [rdi+sizeof(qword)*(7+1)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13,r12, , , , r10,[rdi+sizeof(qword)*(7+2)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15,r14, , , , , r11,[rdi+sizeof(qword)*(7+3)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, r8, , , , , , r12,[rdi+sizeof(qword)*(7+4)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11,r10, , , , , , , r13,[rdi+sizeof(qword)*(7+5)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*13] + SQR_512_TRIANGLE_STEP r13, r12, , , , , , , , r14,[rdi+sizeof(qword)*(7+6)],{rsi+sizeof(qword)*7}, rbx,rbp + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*(7+7)], r15 + mov qword [rdi+sizeof(qword)*(7+8)], r8 + mov qword [rdi+sizeof(qword)*(7+9)], r9 + mov qword [rdi+sizeof(qword)*(7+10)],r10 + mov qword [rdi+sizeof(qword)*(7+11)],r11 + mov qword [rdi+sizeof(qword)*(7+12)],r12 + mov qword [rdi+sizeof(qword)*(7+13)],r13 + mov qword [rdi+sizeof(qword)*(7+14)],rbx + + sub rdi, sizeof(qword)*8 + + FINALIZE_FIX 15, rdi, rsi + ret +ENDFUNC sqr_15 + + +;; +;; 16*qword squarer +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr_16,PRIVATE + call sqr8_triangle + + mov qword [rdi+sizeof(qword)*7], r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + xor r15, r15 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + add rdi, sizeof(qword)*2 + add rcx, sizeof(qword)*2 + call mla_8x2 + + sub rdi, sizeof(qword)*6 + sub rcx, sizeof(qword)*6 + + add rdi, sizeof(qword)*8 + call sqr8_triangle + + xor rbx, rbx + mov qword [rdi+sizeof(qword)*7], r15 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],rbx + + sub rsi, sizeof(qword)*8 + sub rdi, sizeof(qword)*16 + + FINALIZE_FIX 16, rdi, rsi + ret +ENDFUNC sqr_16 + + + +;; +;; 9*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr9_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x1 + + xor rax, rax + mov qword [rdi+sizeof(qword)*(1+0)], r8 + mov qword [rdi+sizeof(qword)*(1+1)], r9 + mov qword [rdi+sizeof(qword)*(1+2)], r10 + mov qword [rdi+sizeof(qword)*(1+3)], r11 + mov qword [rdi+sizeof(qword)*(1+4)], r12 + mov qword [rdi+sizeof(qword)*(1+5)], r13 + mov qword [rdi+sizeof(qword)*(1+6)], r14 + mov qword [rdi+sizeof(qword)*(1+7)], r15 + mov qword [rdi+sizeof(qword)*(1+8)], rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr9_triangle + + +;; +;; 10*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr10_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x2 + + mov qword [rdi+sizeof(qword)*(2+0)], r8 + mov qword [rdi+sizeof(qword)*(2+1)], r9 + mov qword [rdi+sizeof(qword)*(2+2)], r10 + mov qword [rdi+sizeof(qword)*(2+3)], r11 + mov qword [rdi+sizeof(qword)*(2+4)], r12 + mov qword [rdi+sizeof(qword)*(2+5)], r13 + mov qword [rdi+sizeof(qword)*(2+6)], r14 + + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15, , , , , , , , , , {rsi+sizeof(qword)*2}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(2+7)], r15 + mov qword [rdi+sizeof(qword)*(2+8)], r8 + mov qword [rdi+sizeof(qword)*(2+9)], rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr10_triangle + + +;; +;; 11*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr11_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x3 + + mov qword [rdi+sizeof(qword)*(3+0)], r8 + mov qword [rdi+sizeof(qword)*(3+1)], r9 + mov qword [rdi+sizeof(qword)*(3+2)], r10 + mov qword [rdi+sizeof(qword)*(3+3)], r11 + mov qword [rdi+sizeof(qword)*(3+4)], r12 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14, , , , , , , r13,[rdi+sizeof(qword)*(3+5)],{rsi+sizeof(qword)*3}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8, , , , , , , , r14,[rdi+sizeof(qword)*(3+6)],{rsi+sizeof(qword)*3}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(3+7)], r15 + mov qword [rdi+sizeof(qword)*(3+8)], r8 + mov qword [rdi+sizeof(qword)*(3+9)], r9 + mov qword [rdi+sizeof(qword)*(3+10)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr11_triangle + + +;; +;; 12*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr12_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x4 + + mov qword [rdi+sizeof(qword)*(4+0)], r8 + mov qword [rdi+sizeof(qword)*(4+1)], r9 + mov qword [rdi+sizeof(qword)*(4+2)], r10 + mov qword [rdi+sizeof(qword)*(4+3)], r11 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13, , , , , , r12,[rdi+sizeof(qword)*(4+4)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15, , , , , , , r13,[rdi+sizeof(qword)*(4+5)],{rsi+sizeof(qword)*4}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, , , , , , , , r14,[rdi+sizeof(qword)*(4+6)],{rsi+sizeof(qword)*4}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(4+7)], r15 + mov qword [rdi+sizeof(qword)*(4+8)], r8 + mov qword [rdi+sizeof(qword)*(4+9)], r9 + mov qword [rdi+sizeof(qword)*(4+10)],r10 + mov qword [rdi+sizeof(qword)*(4+11)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr12_triangle + + +;; +;; 13*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr13_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x5 + + mov qword [rdi+sizeof(qword)*(5+0)], r8 + mov qword [rdi+sizeof(qword)*(5+1)], r9 + mov qword [rdi+sizeof(qword)*(5+2)], r10 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12, , , , , r11,[rdi+sizeof(qword)*(5+3)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14, , , , , , r12,[rdi+sizeof(qword)*(5+4)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8, , , , , , , r13,[rdi+sizeof(qword)*(5+5)],{rsi+sizeof(qword)*5}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, , , , , , , , r14,[rdi+sizeof(qword)*(5+6)],{rsi+sizeof(qword)*5}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(5+7)], r15 + mov qword [rdi+sizeof(qword)*(5+8)], r8 + mov qword [rdi+sizeof(qword)*(5+9)], r9 + mov qword [rdi+sizeof(qword)*(5+10)],r10 + mov qword [rdi+sizeof(qword)*(5+11)],r11 + mov qword [rdi+sizeof(qword)*(5+12)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr13_triangle + + +;; +;; 14*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr14_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x6 + + mov qword [rdi+sizeof(qword)*(6+0)], r8 + mov qword [rdi+sizeof(qword)*(6+1)], r9 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11, , , , r10,[rdi+sizeof(qword)*(6+2)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13, , , , , r11,[rdi+sizeof(qword)*(6+3)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15, , , , , , r12,[rdi+sizeof(qword)*(6+4)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, , , , , , , r13,[rdi+sizeof(qword)*(6+5)],{rsi+sizeof(qword)*6}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11, , , , , , , , r14,[rdi+sizeof(qword)*(6+6)],{rsi+sizeof(qword)*6}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(6+7)], r15 + mov qword [rdi+sizeof(qword)*(6+8)], r8 + mov qword [rdi+sizeof(qword)*(6+9)], r9 + mov qword [rdi+sizeof(qword)*(6+10)],r10 + mov qword [rdi+sizeof(qword)*(6+11)],r11 + mov qword [rdi+sizeof(qword)*(6+12)],r12 + mov qword [rdi+sizeof(qword)*(6+13)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr14_triangle + + +;; +;; 15*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr15_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + lea rcx, [rsi+sizeof(qword)*8] + add rdi, sizeof(qword)*8 + call mla_8x7 + + mov qword [rdi+sizeof(qword)*(7+0)], r8 + +; SQR_512_TRIANGLE_STEP H, p7, p6, p5, p4, p3, p2, p1, p0, T, ,, rbx,rbp +; ------------------------------ + mov rdx, qword [rsi+sizeof(qword)*8] + SQR_512_TRIANGLE_STEP r8, r15,r14,r13,r12,r11,r10, , , r9, [rdi+sizeof(qword)*(7+1)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*9] + SQR_512_TRIANGLE_STEP r9, r8,r15,r14,r13,r12, , , , r10,[rdi+sizeof(qword)*(7+2)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*10] + SQR_512_TRIANGLE_STEP r10, r9, r8,r15,r14, , , , , r11,[rdi+sizeof(qword)*(7+3)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*11] + SQR_512_TRIANGLE_STEP r11, r10, r9, r8, , , , , , r12,[rdi+sizeof(qword)*(7+4)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*12] + SQR_512_TRIANGLE_STEP r12, r11,r10, , , , , , , r13,[rdi+sizeof(qword)*(7+5)],{rsi+sizeof(qword)*7}, rbx,rbp + mov rdx, qword [rsi+sizeof(qword)*13] + SQR_512_TRIANGLE_STEP r13, r12, , , , , , , , r14,[rdi+sizeof(qword)*(7+6)],{rsi+sizeof(qword)*7}, rbx,rbp + + xor rax, rax + mov qword [rdi+sizeof(qword)*(7+7)], r15 + mov qword [rdi+sizeof(qword)*(7+8)], r8 + mov qword [rdi+sizeof(qword)*(7+9)], r9 + mov qword [rdi+sizeof(qword)*(7+10)],r10 + mov qword [rdi+sizeof(qword)*(7+11)],r11 + mov qword [rdi+sizeof(qword)*(7+12)],r12 + mov qword [rdi+sizeof(qword)*(7+13)],r13 + mov qword [rdi+sizeof(qword)*(7+14)],rax + + sub rdi, sizeof(qword)*8 + ret +ENDFUNC sqr15_triangle + + +;; +;; 16*qword triangle +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC sqr16_triangle,PRIVATE + call sqr8_triangle + mov qword [rdi+sizeof(qword)*7], r15 + xor r15, r15 + + mov rcx, rsi + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + call mla_8x8 + + add rdi, sizeof(qword)*8 + call sqr8_triangle + + xor rax, rax + mov qword [rdi+sizeof(qword)*7], r15 + mov qword [rdi+sizeof(qword)*8], r8 + mov qword [rdi+sizeof(qword)*9], r9 + mov qword [rdi+sizeof(qword)*10],r10 + mov qword [rdi+sizeof(qword)*11],r11 + mov qword [rdi+sizeof(qword)*12],r12 + mov qword [rdi+sizeof(qword)*13],r13 + mov qword [rdi+sizeof(qword)*14],r14 + mov qword [rdi+sizeof(qword)*15],rax + + sub rsi, sizeof(qword)*8 + sub rdi, sizeof(qword)*16 + ret +ENDFUNC sqr16_triangle + + + +sqr_l_basic DQ sqr_1 - sqr_l_basic + DQ sqr_2 - sqr_l_basic + DQ sqr_3 - sqr_l_basic + DQ sqr_4 - sqr_l_basic + DQ sqr_5 - sqr_l_basic + DQ sqr_6 - sqr_l_basic + DQ sqr_7 - sqr_l_basic + DQ sqr_8 - sqr_l_basic + DQ sqr_9 - sqr_l_basic + DQ sqr_10- sqr_l_basic + DQ sqr_11- sqr_l_basic + DQ sqr_12- sqr_l_basic + DQ sqr_13- sqr_l_basic + DQ sqr_14- sqr_l_basic + DQ sqr_15- sqr_l_basic + DQ sqr_16- sqr_l_basic + +sqrN_triangle DQ sqr9_triangle - sqrN_triangle + DQ sqr10_triangle - sqrN_triangle + DQ sqr11_triangle - sqrN_triangle + DQ sqr12_triangle - sqrN_triangle + DQ sqr13_triangle - sqrN_triangle + DQ sqr14_triangle - sqrN_triangle + DQ sqr15_triangle - sqrN_triangle + DQ sqr16_triangle - sqrN_triangle + +%endif ;; _PCPBNSQR_BASIC_ADCX_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrschool.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrschool.inc new file mode 100644 index 000000000..cb45b4469 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrschool.inc @@ -0,0 +1,283 @@ +;=============================================================================== +; Copyright (C) 2010 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; BNU squaring support +; +; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MULx1 genaral-case squarer macros +;; + +;; dst = src * B epilogue (srcLen=4*n+3) +%macro sMULx1_4N_3_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%update_idx %3 + %xdefine %%B %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B + xor %%T1, %%T1 + add %%T0, rax + mov qword [%%rDst+sizeof(qword)], %%T0 + mov rax, qword [%%rSrc+sizeof(qword)*2] + adc %%T1, rdx + + mul %%B + xor %%T2, %%T2 + add %%T1, rax + mov qword [%%rDst+sizeof(qword)*2], %%T1 + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T2, rdx + + mul %%B + %%update_idx + add %%T2, rax + mov qword [%%rDst+sizeof(qword)*3], %%T2 + ;mov rax, qword [rSrc+idx*sizeof(qword)] + adc rdx, 0 + + mov qword [%%rDst+sizeof(qword)*4], rdx + add %%rDst, sizeof(qword) +%endmacro + +;; dst = src * B epilogue (srcLen=4*n+1) +%macro sMULx1_4N_1_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%update_idx %3 + %xdefine %%B %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mul %%B + %%update_idx + add %%T0, rax + mov qword [%%rDst+sizeof(qword)*3], %%T0 + ;mov rax, qword [rSrc+idx*sizeof(qword)] + adc rdx, 0 + + mov qword [%%rDst+sizeof(qword)*4], rdx + add %%rDst, sizeof(qword) +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MULx2 genaral-case multiplier macros +;; + +;; dst = src * {B1:B0} epilogue (srcLen=4*n+1) +%macro sMULx2_4N_1_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%update_idx %3 + %xdefine %%B0 %4 + %xdefine %%B1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%B1 ; {T2:T1} += a[lenA-1]*B1 + ;add rDst, sizeof(qword)*2 + %%update_idx + mov qword [%%rDst+sizeof(qword)*3], %%T0 + add %%T1, rax + ;mov rax, qword [rSrc+idx*sizeof(qword)] + adc rdx, %%T2 + + mov qword [%%rDst+sizeof(qword)*4], %%T1 + mov qword [%%rDst+sizeof(qword)*5], rdx +%endmacro + +;; dst = src * {B1:B0} epilogue (srcLen=4*n+3) +%macro sMULx2_4N_3_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%update_idx %3 + %xdefine %%B0 %4 + %xdefine %%B1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%B1 ; {T2:T1} += a[lenA-3]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[LenA-2]*B0 + mov qword [%%rDst+sizeof(qword)], %%T0 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + adc %%T3, 0 + + mul %%B1 ; {T3:T2} += a[lenA-2]*B1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T3, rdx + + mul %%B0 ; {T0:T3:T2} += a[lenA-1]*B0 + mov qword [%%rDst+sizeof(qword)*2], %%T1 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + adc %%T3, rdx + adc %%T0, 0 + + mul %%B1 ; {T0:T3} += a[lenA-1]*B1 + ;add rDst, sizeof(qword)*2 + %%update_idx + mov qword [%%rDst+sizeof(qword)*3], %%T2 + add %%T3, rax + ;mov rax, qword [rSrc+idx*sizeof(qword)] + adc rdx, %%T0 + + mov qword [%%rDst+sizeof(qword)*4], %%T3 + mov qword [%%rDst+sizeof(qword)*5], rdx +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; MLAx2 genaral-case multiplier macros +;; + +;; +;; B0 = rSrc[-2] +;; B1 = rSrc[-1] +;; inp_vector = rSrc +;; out_vector = rDst +%macro sMLAx2_PLOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%B0 %3 + %xdefine %%B1 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov %%B0, qword [%%rSrc-2*sizeof(qword)] ; preload a[-2] + mov %%B1, qword [%%rSrc-sizeof(qword)] ; and a[i-1] + + mov rax, %%B1 + mul %%B0 ; a[-2]*a[i-1] + xor %%T0, %%T0 + + add qword [%%rDst-sizeof(qword)], rax + mov rax, qword [%%rSrc] ; a[i] + adc %%T0, rdx + + mul %%B0 ; B0*a[i] + xor %%T1, %%T1 + xor %%T2, %%T2 + add %%T0, rax + mov rax, qword [%%rSrc] ; a[i] + adc %%T1, rdx +%endmacro + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+1) +%macro sMLAx2_4N_1_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%update_idx %3 + %xdefine %%B0 %4 + %xdefine %%B1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%B1 ; {T2:T1} += a[lenA-1]*B1 + r[lenA-1] + ;add rDst, sizeof(qword)*2 + %%update_idx + add %%T0, qword [%%rDst+sizeof(qword)*3] + mov qword [%%rDst+sizeof(qword)*3], %%T0 + adc %%T1, rax + adc rdx, %%T2 + ;mov rax, qword [rSrc+idx*sizeof(qword)] + + mov qword [%%rDst+sizeof(qword)*4], %%T1 + mov qword [%%rDst+sizeof(qword)*5], rdx +%endmacro + +;; dst = + src * {B1:B0} epilogue (srcLen=4*n+3) +%macro sMLAx2_4N_3_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%update_idx %3 + %xdefine %%B0 %4 + %xdefine %%B1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%B1 ; {T2:T1} += a[lenA-3]*B1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + adc %%T2, rdx + + mul %%B0 ; {T3:T2:T1} += a[LenA-2]*B0 + r[len-3] + add %%T0, qword [%%rDst+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T0 + adc %%T1, rax + adc %%T2, rdx + adc %%T3, 0 + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[lenA-2] + + mul %%B1 ; {T3:T2} += a[lenA-2]*B1 + xor %%T0, %%T0 + add %%T2, rax + adc %%T3, rdx + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + + mul %%B0 ; {T0:T3:T2} += a[lenA-1]*B0 + r[lenA-2] + add %%T1, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T1 + adc %%T2, rax + adc %%T3, rdx + adc %%T0, 0 + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[lenA-1] + + mul %%B1 ; {T0:T3} += a[lenA-1]*B1 + r[lenA-1] + ;add rDst, sizeof(qword)*2 + %%update_idx + add %%T2, qword [%%rDst+sizeof(qword)*3] + mov qword [%%rDst+sizeof(qword)*3], %%T2 + adc %%T3, rax + adc rdx, %%T0 + ;mov rax, qword [rSrc+idx*sizeof(qword)] + + mov qword [%%rDst+sizeof(qword)*4], %%T3 + mov qword [%%rDst+sizeof(qword)*5], rdx +%endmacro + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrschoolm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrschoolm7as.asm new file mode 100644 index 000000000..aeb8acbd8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusqrschoolm7as.asm @@ -0,0 +1,1343 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpSqrAdc_BNU_school() +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpbnumulschool.inc" +%include "pcpbnusqrschool.inc" +%include "pcpvariant.inc" + +%if (_ADCOX_NI_ENABLING_ == _FEATURE_OFF_) || (_ADCOX_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_M7) && (_IPP32E < _IPP32E_L9) + +; acc:a1 = src * mem + a1 +; clobbers rax, rdx +%macro MULADD0 4.nolist + %xdefine %%acc %1 + %xdefine %%a1 %2 + %xdefine %%src %3 + %xdefine %%mem %4 + + mov rax, %%mem + mul %%src + xor %%acc, %%acc + add %%a1, rax + adc %%acc, rdx +%endmacro + + +; acc:a1 = src * mem + a1 + acc +; clobbers rax, rdx +%macro MULADD 4.nolist + %xdefine %%acc %1 + %xdefine %%a1 %2 + %xdefine %%src %3 + %xdefine %%mem %4 + + mov rax, %%mem + mul %%src + add %%a1, rax + adc rdx, 0 + add %%a1, %%acc + adc rdx, 0 + mov %%acc, rdx +%endmacro + + +; acc:a1 = src * mem + a1 +; clobbers rax, rdx +%macro MULADD1 4.nolist + %xdefine %%acc %1 + %xdefine %%a1 %2 + %xdefine %%src %3 + %xdefine %%mem %4 + + mov rax, %%mem + mul %%src + add %%a1, rax + adc rdx, 0 + mov %%acc, rdx +%endmacro + + +; Macro to allow us to do an adc as an adc_0/add pair +%macro adc2 2.nolist + %xdefine %%a1 %1 + %xdefine %%a2 %2 + +%if 1 + adc %%a1, %%a2 +%else + adc %%a2, 0 + add %%a1, %%a2 +%endif +%endmacro + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; This version does the first half of the off-diagonal terms, then adds +; in the first half of the diagonal terms, then does the second half. +; This is to avoid the writing and reading of the off-diagonal terms to mem. +; Due to extra overhead in the arithmetic, this may or may not be faster +; than the simple version (which follows) +; +; Input in memory [pA] and also in x7...x0 +; Uses all argument registers plus rax and rdx +; +%macro SQR_512 13.nolist + %xdefine %%pDst %1 + %xdefine %%pA %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; ------------------ + ;; first pass 01...07 + ;; ------------------ + mov %%A, %%x0 + + mov rax, %%x1 + mul %%A + mov %%x0, rax + mov %%x1, rdx + + MULADD1 %%x2, %%x1, %%A, %%x2 + MULADD1 %%x3, %%x2, %%A, %%x3 + MULADD1 %%x4, %%x3, %%A, %%x4 + MULADD1 %%x5, %%x4, %%A, %%x5 + MULADD1 %%x6, %%x5, %%A, %%x6 + MULADD1 %%x7, %%x6, %%A, %%x7 + + ;; ------------------ + ;; second pass 12...16 + ;; ------------------ + mov %%A, [%%pA + 8*1] + xor %%x8, %%x8 + + mov rax, [%%pA + 8*2] + mul %%A + add %%x2, rax + adc rdx, 0 + mov %%t0, rdx + + MULADD %%t0, %%x3, %%A, [%%pA + 8*3] + MULADD %%t0, %%x4, %%A, [%%pA + 8*4] + MULADD %%t0, %%x5, %%A, [%%pA + 8*5] + MULADD %%t0, %%x6, %%A, [%%pA + 8*6] + add %%x7, %%t0 + adc %%x8, 0 + + ;; ------------------ + ;; third pass 23...25 + ;; ------------------ + mov %%A, [%%pA + 8*2] + + mov rax, [%%pA + 8*3] + mul %%A + add %%x4, rax + adc rdx, 0 + mov %%t0, rdx + + MULADD %%t0, %%x5, %%A, [%%pA + 8*4] + MULADD %%t0, %%x6, %%A, [%%pA + 8*5] + add %%x7, %%t0 + adc %%x8, 0 + + ;; ------------------ + ;; fourth pass 34 + ;; ------------------ + mov rax, [%%pA + 8*3] + mul qword [%%pA + 8*4] + add %%x6, rax + adc rdx, 0 + add %%x7, rdx + adc %%x8, 0 + + ;; --- double x0...x6 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%A, 0 + + mov rax, [%%pA + 8*0] + mul rax + mov [%%pDst + 8*0], rax + mov %%t0, rdx + + mov rax, [%%pA + 8*1] + mul rax + add %%x0, %%t0 + adc %%x1, rax + mov [%%pDst + 8*1], %%x0 + adc rdx, 0 + mov [%%pDst + 8*2], %%x1 + mov %%t0, rdx + mov rax, [%%pA + 8*2] + mul rax + mov %%x0, rax + mov %%x1, rdx + mov rax, [%%pA + 8*3] + mul rax + add %%x2, %%t0 + adc %%x3, %%x0 + mov [%%pDst + 8*3], %%x2 + adc2 %%x4, %%x1 + mov [%%pDst + 8*4], %%x3 + adc %%x5, rax + mov [%%pDst + 8*5], %%x4 + adc2 %%x6, rdx + mov [%%pDst + 8*6], %%x5 + adc %%A, 0 + mov [%%pDst + 8*7], %%x6 + + ;; ------------------ + ;; second pass 17 + ;; ------------------ + mov rax, [%%pA + 8*1] + xor %%x0, %%x0 + + mul qword [%%pA + 8*7] + add %%x7, rax + adc rdx, 0 + add %%x8, rdx + adc %%x0, 0 + + ;; ------------------ + ;; third pass 26...27 + ;; ------------------ + mov %%x6, [%%pA + 8*2] + + mov rax, [%%pA + 8*6] + mul %%x6 + add %%x7, rax + adc rdx, 0 + add %%x8, rdx + adc %%x0, 0 + + mov rax, [%%pA + 8*7] + xor %%x1, %%x1 + mul %%x6 + add %%x8, rax + adc rdx, 0 + add %%x0, rdx + adc %%x1, 0 + + ;; ------------------ + ;; fourth pass 35...37 + ;; ------------------ + mov %%x6, [%%pA + 8*3] + + mov rax, [%%pA + 8*5] + mul %%x6 + add %%x7, rax + adc rdx, 0 + add %%x8, rdx + adc %%x0, 0 + adc %%x1, 0 + + mov rax, [%%pA + 8*6] + mul %%x6 + add %%x8, rax + adc rdx, 0 + add %%x0, rdx + adc %%x1, 0 + + mov rax, [%%pA + 8*7] + mul %%x6 + add %%x0, rax + adc rdx, 0 + add %%x1, rdx + ;; carry out should be 0 + + ;; ------------------ + ;; f%ifth pass 45...47 + ;; ------------------ + mov %%x6, [%%pA + 8*4] + + mov rax, [%%pA + 8*5] + mul %%x6 + add %%x8, rax + adc rdx, 0 + mov %%x2, rdx + + MULADD %%x2, %%x0, %%x6, [%%pA + 8*6] + MULADD %%x2, %%x1, %%x6, [%%pA + 8*7] + + ;; ------------------ + ;; sixth pass 56...57 & seventh pass 67 + ;; ------------------ + mov %%x6, [%%pA + 8*5] + + mov rax, [%%pA + 8*6] + mul %%x6 + add %%x1, rax + adc rdx, 0 + mov %%x3, rdx + + MULADD %%x3, %%x2, %%x6, [%%pA + 8*7] + + mov rax, [%%pA + 8*6] + mul qword [%%pA + 8*7] + add %%x3, rax + adc rdx, 0 + mov %%x4, rdx + + ;; --- double x7, x8, x0, ..., x4 + xor %%x5, %%x5 + add %%x7, %%x7 + adc %%x8, %%x8 + adc %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, 0 + + mov rax, [%%pA + 8*4] + mul rax + add rax, %%A + adc rdx, 0 + add rax, %%x7 + adc rdx, 0 + mov [%%pDst + 8*8], rax + mov %%A, rdx + mov rax, [%%pA + 8*5] + mul rax + add %%x8, %%A + adc %%x0, rax + mov [%%pDst + 8*9], %%x8 + adc rdx, 0 + mov [%%pDst + 8*10], %%x0 + mov %%A, rdx + mov rax, [%%pA + 8*6] + mul rax + mov %%x7, rax + mov %%x8, rdx + mov rax, [%%pA + 8*7] + mul rax + add %%x1, %%A + adc %%x2, %%x7 + mov [%%pDst + 8*11], %%x1 + adc2 %%x3, %%x8 + mov [%%pDst + 8*12], %%x2 + adc %%x4, rax + mov [%%pDst + 8*13], %%x3 + adc2 %%x5, rdx + mov [%%pDst + 8*14], %%x4 + mov [%%pDst + 8*15], %%x5 +%endmacro + + +%macro SQR_448 13.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; ------------------ + ;; first pass 01...06 + ;; ------------------ + mov %%A, %%x0 + + mov rax, %%x1 + mul %%A + mov %%x0, rax + mov %%x1, rdx + + MULADD1 %%x2, %%x1, %%A, %%x2 + MULADD1 %%x3, %%x2, %%A, %%x3 + MULADD1 %%x4, %%x3, %%A, %%x4 + MULADD1 %%x5, %%x4, %%A, %%x5 + MULADD1 %%x6, %%x5, %%A, %%x6 + + ;; ------------------ + ;; second pass 12...16 + ;; ------------------ + mov %%A, [%%rSrc + sizeof(qword)*1] + mov rax, [%%rSrc+ sizeof(qword)*2] + mul %%A + add %%x2, rax + adc rdx, 0 + mov %%t0, rdx + MULADD %%t0, %%x3, %%A, [%%rSrc + sizeof(qword)*3] + MULADD %%t0, %%x4, %%A, [%%rSrc + sizeof(qword)*4] + MULADD %%t0, %%x5, %%A, [%%rSrc + sizeof(qword)*5] + MULADD %%t0, %%x6, %%A, [%%rSrc + sizeof(qword)*6] + mov %%x7, %%t0 + + ;; ------------------ + ;; third pass 23...25 + ;; ------------------ + mov %%A, [%%rSrc + sizeof(qword)*2] + xor %%x8, %%x8 + mov rax, [%%rSrc + sizeof(qword)*3] + mul %%A + add %%x4, rax + adc rdx, 0 + mov %%t0, rdx + MULADD %%t0, %%x5, %%A, [%%rSrc+ sizeof(qword)*4] + MULADD %%t0, %%x6, %%A, [%%rSrc+ sizeof(qword)*5] + add %%x7, %%t0 + adc %%x8, 0 + + ;; ------------------ + ;; fourth pass 34 + ;; ------------------ + mov rax, [%%rSrc + sizeof(qword)*3] + mul qword [%%rSrc + sizeof(qword)*4] + add %%x6, rax + adc rdx, 0 + add %%x7, rdx + adc %%x8, 0 + + + mov rax, [%%rSrc + sizeof(qword)*0] + + ;; --- double x0...x6 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%A, 0 + + mul rax ; a[0]^2 + mov [%%rDst + sizeof(qword)*0], rax + mov rax, [%%rSrc + sizeof(qword)*1] + mov %%t0, rdx + + mul rax ; a[1]^2 + add %%x0, %%t0 + adc %%x1, rax + mov rax, [%%rSrc + sizeof(qword)*2] + mov [%%rDst + sizeof(qword)*1], %%x0 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*2], %%x1 + mov %%t0, rdx + + mul rax ; a[2]^2 + add %%x2, %%t0 + adc %%x3, rax + mov rax, [%%rSrc + sizeof(qword)*3] + mov [%%rDst + sizeof(qword)*3], %%x2 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*4], %%x3 + mov %%t0, rdx + + mul rax ; a[3]^2 + add %%x4, %%t0 + adc %%x5, rax + mov [%%rDst + sizeof(qword)*5], %%x4 + adc %%x6, rdx + mov [%%rDst + sizeof(qword)*6], %%x5 + adc %%A, 0 + mov [%%rDst + sizeof(qword)*7], %%x6 + + ;; ------------------ + ;; third pass complete 26 + ;; ------------------ + mov rax, [%%rSrc + sizeof(qword)*2] + xor %%x0, %%x0 + + mul qword [%%rSrc + sizeof(qword)*6] + add %%x7, rax + adc rdx, 0 + add %%x8, rdx + adc %%x0, 0 + + ;; ------------------ + ;; forth pass complete 35...36 + ;; ------------------ + mov %%x6, [%%rSrc + sizeof(qword)*3] + mov rax, [%%rSrc+ sizeof(qword)*5] + mul %%x6 + add %%x7, rax + mov rax, [%%rSrc + sizeof(qword)*6] + adc %%x8, rdx + adc %%x0, 0 + mul %%x6 + add %%x8, rax + adc %%x0, rdx + + ;; ------------------ + ;; f%ifth pass 45...46 + ;; ------------------ + mov %%x6, [%%rSrc + sizeof(qword)*4] + xor %%x1, %%x1 + mov rax, [%%rSrc + sizeof(qword)*5] + mul %%x6 + add %%x8, rax + mov rax, [%%rSrc + sizeof(qword)*6] + adc %%x0, rdx + adc %%x1, 0 + mul %%x6 + add %%x0, rax + adc %%x1, rdx + + ;; ------------------ + ;; six pass 56 + ;; ------------------ + mov %%x6, [%%rSrc + sizeof(qword)*5] + xor %%x2, %%x2 + mov rax, [%%rSrc + sizeof(qword)*6] + mul %%x6 + add %%x1, rax + adc %%x2, rdx + + mov rax, [%%rSrc + sizeof(qword)*4] + + ;; --- double x7, x8, x0, x1, x2 + xor %%x3, %%x3 + add %%x7, %%x7 + adc %%x8, %%x8 + adc %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, 0 + + mul rax ; a[4]^2 + add %%x7, %%A + adc rdx, 0 + xor %%A, %%A + add %%x7, rax + mov rax, [%%rSrc + sizeof(qword)*5] + adc %%x8, rdx + mov [%%rDst+ sizeof(qword)*8], %%x7 + adc %%A, 0 + mov [%%rDst + sizeof(qword)*9], %%x8 + + mul rax ; a[5]^2 + add %%x0, %%A + adc rdx, 0 + xor %%A, %%A + add %%x0, rax + mov rax, [%%rSrc + sizeof(qword)*6] + adc %%x1, rdx + mov [%%rDst + sizeof(qword)*10], %%x0 + adc %%A, 0 + mov [%%rDst + sizeof(qword)*11], %%x1 + + mul rax ; a[6]^2 + add %%x2, %%A + adc rdx, 0 + add %%x2, rax + adc rdx, %%x3 + mov [%%rDst + sizeof(qword)*12], %%x2 + mov [%%rDst + sizeof(qword)*13], rdx +%endmacro + + +%macro SQR_384 13.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov %%A, %%x0 + mov rax, %%x1 + mul %%A + mov %%x0, rax + mov %%x1, rdx + MULADD1 %%x2, %%x1, %%A, %%x2 + MULADD1 %%x3, %%x2, %%A, %%x3 + MULADD1 %%x4, %%x3, %%A, %%x4 + MULADD1 %%x5, %%x4, %%A, %%x5 + + mov %%A, qword [%%rSrc+ sizeof(qword)*1] + mov rax, qword [%%rSrc+ sizeof(qword)*2] + mul %%A + add %%x2, rax + adc rdx, 0 + mov %%t0, rdx + MULADD %%t0, %%x3, %%A, [%%rSrc + sizeof(qword)*3] + MULADD %%t0, %%x4, %%A, [%%rSrc + sizeof(qword)*4] + MULADD %%t0, %%x5, %%A, [%%rSrc + sizeof(qword)*5] + mov %%x6, %%t0 + + mov %%A, qword [%%rSrc+ sizeof(qword)*2] + mov rax, qword [%%rSrc+ sizeof(qword)*3] + mul %%A + add %%x4, rax + adc rdx, 0 + mov %%t0, rdx + MULADD %%t0, %%x5, %%A, [%%rSrc + sizeof(qword)*4] + MULADD %%t0, %%x6, %%A, [%%rSrc + sizeof(qword)*5] + mov %%x7, %%t0 + + mov %%A, qword [%%rSrc+ sizeof(qword)*3] + mov rax, qword [%%rSrc+ sizeof(qword)*4] + mul %%A + xor %%x8, %%x8 + add %%x6, rax + mov rax, qword [%%rSrc+ sizeof(qword)*5] + adc %%x7, rdx + adc %%x8, 0 + mul %%A + mov %%A, qword [%%rSrc+ sizeof(qword)*4] + add %%x7, rax + mov rax, qword [%%rSrc+ sizeof(qword)*5] + adc %%x8, rdx + + mul %%A + xor %%t0, %%t0 + add %%x8, rax + adc %%t0, rdx + + mov rax, [%%rSrc + sizeof(qword)*0] + + ;; --- double x0...x7,x8,t0 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%x7, %%x7 + adc %%x8, %%x8 + adc %%t0, %%t0 + adc %%A, 0 + mov qword [rsp], %%A + + mul rax + mov [%%rDst + sizeof(qword)*0], rax + mov rax, [%%rSrc + sizeof(qword)*1] ; a[1] + mov %%A, rdx + + mul rax + add %%x0, %%A + adc %%x1, rax + mov rax, [%%rSrc + sizeof(qword)*2] ; a[2] + mov [%%rDst + sizeof(qword)*1], %%x0 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*2], %%x1 + mov %%A, rdx + + mul rax + add %%x2, %%A + adc %%x3, rax + mov rax, [%%rSrc + sizeof(qword)*3] ; a[3] + mov [%%rDst + sizeof(qword)*3], %%x2 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*4], %%x3 + mov %%A, rdx + + mul rax + add %%x4, %%A + adc %%x5, rax + mov rax, [%%rSrc + sizeof(qword)*4] ; a[4] + mov [%%rDst + sizeof(qword)*5], %%x4 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*6], %%x5 + mov %%A, rdx + + mul rax + add %%x6, %%A + adc %%x7, rax + mov rax, [%%rSrc + sizeof(qword)*5] ; a[5] + mov [%%rDst + sizeof(qword)*7], %%x6 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*8], %%x7 + mov %%A, rdx + + mul rax + add %%x8, %%A + adc %%t0, rax + mov [%%rDst + sizeof(qword)*9], %%x8 + adc rdx, qword [rsp] + mov [%%rDst + sizeof(qword)*10], %%t0 + mov [%%rDst + sizeof(qword)*11], rdx +%endmacro + + +%macro SQR_320 13.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov %%A, %%x0 + mov rax, %%x1 + mul %%A + mov %%x0, rax + mov %%x1, rdx + MULADD1 %%x2, %%x1, %%A, %%x2 + MULADD1 %%x3, %%x2, %%A, %%x3 + MULADD1 %%x4, %%x3, %%A, %%x4 + + mov %%A, qword [%%rSrc+ sizeof(qword)*1] + mov rax, qword [%%rSrc+ sizeof(qword)*2] + mul %%A + add %%x2, rax + adc rdx, 0 + mov %%t0, rdx + MULADD %%t0, %%x3, %%A, [%%rSrc + sizeof(qword)*3] + MULADD %%t0, %%x4, %%A, [%%rSrc + sizeof(qword)*4] + mov %%x5, %%t0 + + mov %%A, qword [%%rSrc+ sizeof(qword)*2] + mov rax, qword [%%rSrc+ sizeof(qword)*3] + mul %%A + xor %%x6, %%x6 + add %%x4, rax + mov rax, qword [%%rSrc+ sizeof(qword)*4] + adc %%x5, rdx + adc %%x6, 0 + mul %%A + mov %%A, qword [%%rSrc+ sizeof(qword)*3] + add %%x5, rax + mov rax, qword [%%rSrc+ sizeof(qword)*4] + adc %%x6, rdx + + mul %%A + xor %%x7, %%x7 + add %%x6, rax + adc %%x7, rdx + + mov rax, [%%rSrc + sizeof(qword)*0] + + ;; --- double x0...x5 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%x6, %%x6 + adc %%x7, %%x7 + adc %%A, 0 + + mul rax + mov [%%rDst + sizeof(qword)*0], rax + mov rax, [%%rSrc + sizeof(qword)*1] + mov %%t0, rdx + + mul rax + add %%x0, %%t0 + adc %%x1, rax + mov rax, [%%rSrc + sizeof(qword)*2] + mov [%%rDst + sizeof(qword)*1], %%x0 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*2], %%x1 + mov %%t0, rdx + + mul rax + add %%x2, %%t0 + adc %%x3, rax + mov rax, [%%rSrc + sizeof(qword)*3] + mov [%%rDst + sizeof(qword)*3], %%x2 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*4], %%x3 + mov %%t0, rdx + + mul rax + add %%x4, %%t0 + adc %%x5, rax + mov rax, [%%rSrc + sizeof(qword)*4] + mov [%%rDst + sizeof(qword)*5], %%x4 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*6], %%x5 + mov %%t0, rdx + + mul rax + add %%x6, %%t0 + adc %%x7, rax + mov [%%rDst + sizeof(qword)*7], %%x6 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*8], %%x7 + add rdx, %%A + mov [%%rDst + sizeof(qword)*9], rdx +%endmacro + + +%macro SQR_256 13.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + ;; ------------------ + ;; first pass 01...03 + ;; ------------------ + mov %%A, %%x0 + mov rax, %%x1 + mul %%A + mov %%x0, rax + mov %%x1, rdx + MULADD1 %%x2, %%x1, %%A, %%x2 + MULADD1 %%x3, %%x2, %%A, %%x3 + + ;; ------------------ + ;; second pass 12, 13 + ;; ------------------ + mov %%A, qword [%%rSrc+ sizeof(qword)*1] + mov rax, qword [%%rSrc+ sizeof(qword)*2] + mul %%A + xor %%x4, %%x4 + add %%x2, rax + mov rax, qword [%%rSrc+ sizeof(qword)*3] + adc %%x3, rdx + adc %%x4, 0 + + mul %%A + mov %%A, qword [%%rSrc+ sizeof(qword)*2] + add %%x3, rax + mov rax, qword [%%rSrc+ sizeof(qword)*3] + adc %%x4, rdx + + ;; ------------------ + ;; third pass 23 + ;; ------------------ + mul %%A + xor %%x5, %%x5 + add %%x4, rax + adc %%x5, rdx + + mov rax, [%%rSrc + sizeof(qword)*0] + + ;; --- double x0...x5 + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%x4, %%x4 + adc %%x5, %%x5 + adc %%A, 0 + + mul rax + mov [%%rDst + sizeof(qword)*0], rax + mov rax, [%%rSrc + sizeof(qword)*1] + mov %%t0, rdx + + mul rax + add %%x0, %%t0 + adc %%x1, rax + mov rax, [%%rSrc + sizeof(qword)*2] + mov [%%rDst + sizeof(qword)*1], %%x0 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*2], %%x1 + mov %%t0, rdx + + mul rax + add %%x2, %%t0 + adc %%x3, rax + mov rax, [%%rSrc + sizeof(qword)*3] + mov [%%rDst + sizeof(qword)*3], %%x2 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*4], %%x3 + mov %%t0, rdx + + mul rax + add %%x4, %%t0 + adc %%x5, rax + mov [%%rDst + sizeof(qword)*5], %%x4 + adc rdx, 0 + mov [%%rDst + sizeof(qword)*6], %%x5 + add rdx, %%A + mov [%%rDst + sizeof(qword)*7], rdx +%endmacro + + +%macro SQR_192 13.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%x7 %3 + %xdefine %%x6 %4 + %xdefine %%x5 %5 + %xdefine %%x4 %6 + %xdefine %%x3 %7 + %xdefine %%x2 %8 + %xdefine %%x1 %9 + %xdefine %%x0 %10 + %xdefine %%A %11 + %xdefine %%x8 %12 + %xdefine %%t0 %13 + + mov %%A, %%x0 + + mov rax, %%x1 + mul %%A + mov %%x0, rax + mov %%x1, rdx + + MULADD1 %%x2, %%x1, %%A, %%x2 + + mov rax, qword [%%rSrc+ sizeof(qword)*1] + mul qword [%%rSrc+ sizeof(qword)*2] + xor %%x3, %%x3 + add %%x2, rax + adc %%x3, rdx + + xor %%A, %%A + add %%x0, %%x0 + adc %%x1, %%x1 + adc %%x2, %%x2 + adc %%x3, %%x3 + adc %%A, %%A + + mov rax, qword [%%rSrc+ sizeof(qword)*0] + mul rax + mov %%x4, rax + mov %%x5, rdx + + mov rax, qword [%%rSrc+ sizeof(qword)*1] + mul rax + mov %%x6, rax + mov %%x7, rdx + + mov rax, qword [%%rSrc+ sizeof(qword)*2] + mul rax + + mov qword [%%rDst+sizeof(qword)*0], %%x4 + add %%x5, %%x0 + mov qword [%%rDst+sizeof(qword)*1], %%x5 + adc %%x6, %%x1 + mov qword [%%rDst+sizeof(qword)*2], %%x6 + adc %%x7, %%x2 + mov qword [%%rDst+sizeof(qword)*3], %%x7 + adc rax, %%x3 + mov qword [%%rDst+sizeof(qword)*4], rax + adc rdx, %%A + mov qword [%%rDst+sizeof(qword)*5], rdx +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + +;************************************************************* +;* Ipp64u cpSqrAdc_BNU_school(Ipp64u* pR; +;* const Ipp64u* pA, int aSize) +;* returns pR[aSize+aSize-1] +;* +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpSqrAdc_BNU_school,PUBLIC +%assign LOCAL_FRAME (3*sizeof(qword)) + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +;; +;; assignment +%xdefine rDst rdi +%xdefine rSrc rsi +%xdefine srcL rdx + +%xdefine A rcx +%xdefine x0 r8 +%xdefine x1 r9 +%xdefine x2 r10 +%xdefine x3 r11 +%xdefine x4 r12 +%xdefine x5 r13 +%xdefine x6 r14 +%xdefine x7 r15 +%xdefine x8 rbx +%xdefine t0 rbp + + cmp edx, 4 + jg .more_then_4 + + cmp edx, 3 + jg .SQR4 + je .SQR3 + jp .SQR2 + +align IPP_ALIGN_FACTOR +.SQR1: ;; len=1 + mov rax, qword [rsi] ; eax = a + mul rax ; eax = rL edx = rH + mov qword [rdi], rax ; + mov rax, rdx ; + mov qword [rdi+8], rdx ; + mov rax, rdx + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.SQR2: ;; len=2 + mov rax, qword [rsi] ; a[0] + mul qword [rsi+sizeof(qword)*1] ; a[0]*a[1] + xor A, A + mov x2, rax + mov x3, rdx + + mov rax, qword [rsi] ; a[0] + mul rax ; (x1:x0) = a[1]^2 + + add x2, x2 ; (A:x3:x2) = 2*a[0]*a[1] + adc x3, x3 + adc A, 0 + + mov x0, rax + mov x1, rdx + + mov rax, qword [rsi+sizeof(qword)*1]; a[1] + mul rax ; (rdx:rax) = a[1]^2 + + mov qword [rdi+sizeof(qword)*0], x0 + add x1, x2 + mov qword [rdi+sizeof(qword)*1], x1 + adc rax, x3 + mov qword [rdi+sizeof(qword)*2], rax + adc rdx, A + mov qword [rdi+sizeof(qword)*3], rdx + mov rax, rdx + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.SQR3: ;; len=3 + mov x0, [rSrc+ sizeof(qword)*0] + mov x1, [rSrc+ sizeof(qword)*1] + mov x2, [rSrc+ sizeof(qword)*2] + SQR_192 rDst, rSrc, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + mov rax, rdx + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.SQR4: ;; len=4 + mov x0, [rSrc+ sizeof(qword)*0] + mov x1, [rSrc+ sizeof(qword)*1] + mov x2, [rSrc+ sizeof(qword)*2] + mov x3, [rSrc+ sizeof(qword)*3] + SQR_256 rDst, rSrc, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + mov rax, rdx + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.more_then_4: + cmp edx, 8 + jg .general_case + + cmp edx, 7 + jg .SQR8 + je .SQR7 + jp .SQR6 + +align IPP_ALIGN_FACTOR +.SQR5: ;; len=5 + mov x0, [rSrc+ sizeof(qword)*0] + mov x1, [rSrc+ sizeof(qword)*1] + mov x2, [rSrc+ sizeof(qword)*2] + mov x3, [rSrc+ sizeof(qword)*3] + mov x4, [rSrc+ sizeof(qword)*4] + SQR_320 rDst, rSrc, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + mov rax, rdx + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.SQR6: ;; len=6 + mov x0, [rSrc+ sizeof(qword)*0] + mov x1, [rSrc+ sizeof(qword)*1] + mov x2, [rSrc+ sizeof(qword)*2] + mov x3, [rSrc+ sizeof(qword)*3] + mov x4, [rSrc+ sizeof(qword)*4] + mov x5, [rSrc+ sizeof(qword)*5] + SQR_384 rDst, rSrc, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + mov rax, rdx + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.SQR7: ;; len=7 + mov x0, [rSrc+ sizeof(qword)*0] + mov x1, [rSrc+ sizeof(qword)*1] + mov x2, [rSrc+ sizeof(qword)*2] + mov x3, [rSrc+ sizeof(qword)*3] + mov x4, [rSrc+ sizeof(qword)*4] + mov x5, [rSrc+ sizeof(qword)*5] + mov x6, [rSrc+ sizeof(qword)*6] + SQR_448 rDst, rSrc, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + mov rax, rdx + REST_XMM + REST_GPR + ret + +align IPP_ALIGN_FACTOR +.SQR8: ;; len=8 + mov x0, [rSrc+ sizeof(qword)*0] + mov x1, [rSrc+ sizeof(qword)*1] + mov x2, [rSrc+ sizeof(qword)*2] + mov x3, [rSrc+ sizeof(qword)*3] + mov x4, [rSrc+ sizeof(qword)*4] + mov x5, [rSrc+ sizeof(qword)*5] + mov x6, [rSrc+ sizeof(qword)*6] + mov x7, [rSrc+ sizeof(qword)*7] + SQR_512 rDst, rSrc, x7, x6, x5, x4, x3, x2, x1, x0, A, x8, t0 + mov rax, rdx + REST_XMM + REST_GPR + ret + + + +;********** lenSrcA > 8 ************************************** +align IPP_ALIGN_FACTOR +.general_case: + +;; +;; stack structure: +%assign pDst 0 +%assign pSrc pDst+sizeof(qword) +%assign len pSrc+sizeof(qword) + +;; +;; assignment +%xdefine B0 r10 ; a[i], a[i+1] +%xdefine B1 r11 + +%xdefine T0 r12 ; temporary +%xdefine T1 r13 +%xdefine T2 r14 +%xdefine T3 r15 + +%xdefine idx rcx ; indexs +%xdefine idxt rbx + +%xdefine rSrc rsi +%xdefine rDst rdi + + movsxd rdx, edx ; expand length + mov [rsp+pDst], rdi ; save parameters + mov [rsp+pSrc], rsi + mov [rsp+len], rdx + + mov r8, rdx + mov rax, dword 2 + mov rbx, dword 1 + test r8, 1 + cmove rax, rbx ; delta = len&1? 2:1 + + sub rdx, rax ; len -= delta + lea rsi, [rsi+rax*sizeof(qword)] ; A' = A+delta + lea rdi, [rdi+rax*sizeof(qword)] ; R' = R+delta + lea rsi, [rsi+rdx*sizeof(qword)-4*sizeof(qword)] ; rsi = &A'[len-4] + lea rdi, [rdi+rdx*sizeof(qword)-4*sizeof(qword)] ; rdi = &R'[len-4] + + mov idx, dword 4 ; init + sub idx, rdx ; negative index + + test r8, 1 + jnz .init_odd_len_operation + +;********** odd number of passes (multiply only) ********************* +.init_even_len_operation: + mov B0, qword [rsi+idx*sizeof(qword)-sizeof(qword)] ; B0 = a[0] + mov rax, qword [rsi+idx*sizeof(qword)] ; a[1] + xor T0, T0 + cmp idx, 0 + jge .skip_mul1 + + mov idxt, idx + MULx1 rdi, rsi, idxt, B0, T0, T1, T2, T3 + +.skip_mul1: + cmp idxt, 1 + jne .fin_mulx1_3 ; idx=3 (effective len=4n+1) + ; .fin_mulx1_1 ; idx=1 (effective len=4n+3) + +.fin_mulx1_1: + sMULx1_4N_3_ELOG rdi, rsi, {add idx,2}, B0, T0,T1,T2,T3 + jmp .odd_pass_pairs +.fin_mulx1_3: + sMULx1_4N_1_ELOG rdi, rsi, {add idx,2}, B0, T0,T1,T2,T3 + jmp .even_pass_pairs + + +;********** even number of passes (multiply only) ********************* +.init_odd_len_operation: + mov B0, qword [rsi+idx*sizeof(qword)-2*sizeof(qword)] ; a[0] and a[1] + mov B1, qword [rsi+idx*sizeof(qword)-sizeof(qword)] + + mov rax, B1 ; a[0]*a[1] + mul B0 + + mov qword [rdi+idx*sizeof(qword)-sizeof(qword)], rax + mov rax, qword [rsi+idx*sizeof(qword)] ; a[2] + mov T0, rdx + + mul B0 ; a[0]*a[2] + xor T1, T1 + xor T2, T2 + add T0, rax + mov rax, qword [rsi+idx*sizeof(qword)] ; a[2] + adc T1, rdx + + cmp idx, 0 + jge .skip_mul_nx2 + + mov idxt, idx + MULx2 rdi, rsi, idxt, B0,B1, T0,T1,T2,T3 + +.skip_mul_nx2: + cmp idxt, 1 + jnz .fin_mul2x_3 ; idx=3 (effective len=4n+3) + ; .fin_mul2x_1 ; idx=1 (effective len=4n+1) + +.fin_mul2x_1: + sMULx2_4N_3_ELOG rdi, rsi, {add idx,2}, B0,B1, T0,T1,T2,T3 + add rdi, 2*sizeof(qword) + jmp .odd_pass_pairs +.fin_mul2x_3: + sMULx2_4N_1_ELOG rdi, rsi, {add idx,2}, B0,B1, T0,T1,T2,T3 + add rdi, 2*sizeof(qword) + +align IPP_ALIGN_FACTOR +.even_pass_pairs: + sMLAx2_PLOG {rdi+idx*sizeof(qword)}, {rsi+idx*sizeof(qword)}, B0,B1, T0,T1,T2,T3 + cmp idx, 0 + jge .skip1 + mov idxt, idx + MLAx2 rdi, rsi, idxt, B0,B1, T0,T1,T2,T3 +.skip1: + sMLAx2_4N_3_ELOG rdi, rsi, {add idx,2}, B0,B1, T0,T1,T2,T3 + add rdi, 2*sizeof(qword) + +.odd_pass_pairs: + sMLAx2_PLOG {rdi+idx*sizeof(qword)}, {rsi+idx*sizeof(qword)}, B0,B1, T0,T1,T2,T3 + cmp idx, 0 + jge .skip2 + mov idxt, idx + MLAx2 rdi, rsi, idxt, B0,B1, T0,T1,T2,T3 +.skip2: + sMLAx2_4N_1_ELOG rdi, rsi, {add idx,2}, B0,B1, T0,T1,T2,T3 + add rdi, 2*sizeof(qword) + + cmp idx, 4 + jl .even_pass_pairs + + +.add_diag: + mov rdi, [rsp+pDst] ; restore parameters + mov rsi, [rsp+pSrc] + mov rcx, [rsp+len] + + xor idxt, idxt + xor T0, T0 + xor T1, T1 + lea rax, [rdi+rcx*sizeof(qword)] + lea rsi, [rsi+rcx*sizeof(qword)] + mov qword [rdi], T0 ; r[0] = 0 + mov qword [rax+rcx*sizeof(qword)-sizeof(qword)], T0 ; r[2*len-1] = 0 + neg rcx + +align IPP_ALIGN_FACTOR +.add_diag_loop: + mov rax, qword [rsi+rcx*sizeof(qword)] ; a[i] + mul rax + mov T2, qword [rdi] ; r[2*i] + mov T3, qword [rdi+sizeof(qword)] ; r[2*i+1] + add T0, 1 + adc T2, T2 + adc T3, T3 + sbb T0, T0 + add T1, 1 + adc T2, rax + adc T3, rdx + sbb T1, T1 + mov qword [rdi], T2 + mov qword [rdi+sizeof(qword)], T3 + add rdi, sizeof(qword)*2 + add rcx, 1 + jnz .add_diag_loop + + mov rax, T3 ; r[2*len-1] + REST_XMM + REST_GPR + ret +ENDFUNC cpSqrAdc_BNU_school + + +%endif + +%endif ;; _ADCOX_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusubm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusubm7as.asm new file mode 100644 index 000000000..7c19b1ee7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpbnusubm7as.asm @@ -0,0 +1,330 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpSub_BNU() +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + + +;************************************************************* +;* Ipp64u cpSub_BNU(Ipp64u* pDst, +;* const Ipp64u* pSrc1, +;* const Ipp64u* pSrc2, +;* int len) +;* +;* returns borrow >= 0 +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpSub_BNU,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 4 + +; rdi = pDst +; rsi = pSrcA +; rdx = pSrcB +; rcx = len + + movsxd rcx, ecx ; unsigned length + xor rax, rax + + cmp rcx, 2 + jge .SUB_GE2 + +;********** lenSrcA == 1 ************************************* + add rax, rax + mov r8, qword [rsi] ; rsi = a + sbb r8, qword [rdx] ; r8 = a-b = s + mov qword [rdi], r8 ; save s + sbb rax, rax ; + jmp .FINAL + +;********** lenSrcA == 1 END ******************************** + +.SUB_GE2: + jg .SUB_GT2 + +;********** lenSrcA == 2 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0-b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r9, qword [rdx+8] ; r9 = a1-b1 = s1 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + sbb rax, rax ; rax = borrow + jmp .FINAL + +;********** lenSrcA == 2 END ********************************* + +.SUB_GT2: + cmp rcx, 4 + jge .SUB_GE4 + +;********** lenSrcA == 3 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0-b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r9, qword [rdx+8] ; r9 = a1-b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + sbb r10, qword [rdx+16] ; r10 = a2-b2 = s2 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + sbb rax, rax ; rax = borrow + jmp .FINAL + +;********** lenSrcA == 3 END ********************************* + +.SUB_GE4: + jg .SUB_GT4 + +;********** lenSrcA == 4 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0-b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r9, qword [rdx+8] ; r9 = a1-b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + sbb r10, qword [rdx+16] ; r10 = a2-b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + sbb r11, qword [rdx+24] ; r11 = a3-b3 = s3 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s2 + sbb rax, rax ; rax = borrow + jmp .FINAL + +;********** lenSrcA == 4 END ********************************* + +.SUB_GT4: + cmp rcx, 6 + jge .SUB_GE6 + +;********** lenSrcA == 5 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0-b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r9, qword [rdx+8] ; r9 = a1-b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + sbb r10, qword [rdx+16] ; r10 = a2-b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + sbb r11, qword [rdx+24] ; r11 = a3-b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + sbb rcx, qword [rdx+32] ; rcx = a4-b4 = s4 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + sbb rax, rax ; rax = borrow + jmp .FINAL + +;********** lenSrcA == 5 END ********************************* + +.SUB_GE6: + jg .SUB_GT6 + +;********** lenSrcA == 6 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0-b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r9, qword [rdx+8] ; r9 = a1-b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + sbb r10, qword [rdx+16] ; r10 = a2-b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + sbb r11, qword [rdx+24] ; r11 = a3-b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + sbb rcx, qword [rdx+32] ; rcx = a4-b4 = s4 + mov rsi, qword [rsi+40] ; rsi = a5 + sbb rsi, qword [rdx+40] ; rsi = a5-b5 = s5 + mov qword [rdi], r8 ; save s0 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + mov qword [rdi+40], rsi ; save s5 + sbb rax, rax ; rax = borrow + jmp .FINAL + +;********** lenSrcA == 6 END ********************************* + +.SUB_GT6: + cmp rcx, 8 + jge .SUB_GE8 + +.SUB_EQ7: +;********** lenSrcA == 7 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0-b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r9, qword [rdx+8] ; r9 = a1-b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + sbb r10, qword [rdx+16] ; r10 = a2-b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + sbb r11, qword [rdx+24] ; r11 = a3-b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + sbb rcx, qword [rdx+32] ; rcx = a4-b4 = s4 + mov qword [rdi], r8 ; save s0 + mov r8, qword [rsi+40] ; r8 = a5 + sbb r8, qword [rdx+40] ; r8 = a5-b5 = s5 + mov rsi, qword [rsi+48] ; rsi = a6 + sbb rsi, qword [rdx+48] ; rsi = a6-b6 = s6 + mov qword [rdi+8], r9 ; save s1 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + mov qword [rdi+40], r8 ; save s5 + mov qword [rdi+48], rsi ; save s6 + sbb rax, rax ; rax = borrow + jmp .FINAL + +;********** lenSrcA == 7 END ********************************* + + +.SUB_GE8: + jg .SUB_GT8 + +;********** lenSrcA == 8 ************************************* + add rax, rax + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0-b0 = s0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r9, qword [rdx+8] ; r9 = a1-b1 = s1 + mov r10, qword [rsi+16] ; r10 = a2 + sbb r10, qword [rdx+16] ; r10 = a2-b2 = s2 + mov r11, qword [rsi+24] ; r11 = a3 + sbb r11, qword [rdx+24] ; r11 = a3-b3 = s3 + mov rcx, qword [rsi+32] ; rcx = a4 + sbb rcx, qword [rdx+32] ; rcx = a4-b4 = s4 + mov qword [rdi], r8 ; save s0 + mov r8, qword [rsi+40] ; r8 = a5 + sbb r8, qword [rdx+40] ; r8 = a5-b5 = s5 + mov qword [rdi+8], r9 ; save s1 + mov r9, qword [rsi+48] ; r9 = a7 + sbb r9, qword [rdx+48] ; r9 = a7-b7 = s7 + mov rsi, qword [rsi+56] ; rsi = a6 + sbb rsi, qword [rdx+56] ; rsi = a6-b6 = s6 + mov qword [rdi+16], r10 ; save s2 + mov qword [rdi+24], r11 ; save s3 + mov qword [rdi+32], rcx ; save s4 + mov qword [rdi+40], r8 ; save s5 + mov qword [rdi+48], r9 ; save s6 + mov qword [rdi+56], rsi ; save s7 + sbb rax, rax ; rax = borrow + jmp .FINAL + +;********** lenSrcA == 8 END ********************************* + + +;********** lenSrcA > 8 ************************************* + +.SUB_GT8: + mov r8, rax + mov rax, rcx ; rax = len + and rcx, 3 ; + xor rcx, rax ; + lea rsi, [rsi+8*rcx] ; + lea rdx, [rdx+8*rcx] ; + lea rdi, [rdi+8*rcx] ; + neg rcx + add r8, r8 + jmp .SUB_GLOOP + +align IPP_ALIGN_FACTOR +.SUB_GLOOP: + mov r8, qword [rsi+8*rcx] ; r8 = a0 + mov r9, qword [rsi+8*rcx+8] ; r9 = a1 + mov r10, qword [rsi+8*rcx+16] ; r10 = a2 + mov r11, qword [rsi+8*rcx+24] ; r11 = a3 + sbb r8, qword [rdx+8*rcx] ; r8 = a0+b0 = r0 + sbb r9, qword [rdx+8*rcx+8] ; r9 = a1+b1 = r1 + sbb r10, qword [rdx+8*rcx+16] ; r10 = a2+b2 = r2 + sbb r11, qword [rdx+8*rcx+24] ; r11 = a3+b3 = r3 + mov qword [rdi+8*rcx], r8 ; + mov qword [rdi+8*rcx+8], r9 ; + mov qword [rdi+8*rcx+16], r10 ; + mov qword [rdi+8*rcx+24], r11 ; + lea rcx, [rcx+4] + jrcxz .SUB_LLAST0 + jmp .SUB_GLOOP + +.SUB_LLAST0: + sbb rcx, rcx + and rax, 3 + jz .FIN0 + +.SUB_LLOOP: + test rax, 2 + jz .SUB_LLAST1 + + add rcx, rcx + mov r8, qword [rsi] ; r8 = a0 + mov r9, qword [rsi+8] ; r9 = a1 + sbb r8, qword [rdx] ; r8 = a0+b0 = r0 + sbb r9, qword [rdx+8] ; r9 = a1+b1 = r1 + mov qword [rdi], r8 ; + mov qword [rdi+8], r9 ; + sbb rcx, rcx + test rax, 1 + jz .FIN0 + + add rsi, 16 + add rdx, 16 + add rdi, 16 + +.SUB_LLAST1: + add rcx, rcx + mov r8, qword [rsi] ; r8 = a0 + sbb r8, qword [rdx] ; r8 = a0+b0 = r0 + mov qword [rdi], r8 ; + sbb rcx, rcx + +.FIN0: + mov rax, rcx + +;******************* .FINAL *********************************************************** + +.FINAL: + neg rax + REST_XMM + REST_GPR + ret +ENDFUNC cpSub_BNU + + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpdelay.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpdelay.asm new file mode 100644 index 000000000..db1d31b53 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpdelay.asm @@ -0,0 +1,52 @@ +;=============================================================================== +; Copyright 2022 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +;=============================================================================== + +; +; +; Purpose: Delay function, intel64 version +; +; Content: +; _ippcpDelay() +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +segment .text align=IPP_ALIGN_FACTOR + +;*************************************************************** +;* Purpose: delay +;* +;* void _ippcpDelay(Ipp32u value) +;* +;* Caller = cpAESRandomNoise +;*************************************************************** +align IPP_ALIGN_FACTOR +IPPASM _ippcpDelay,PUBLIC + COMP_ABI 1 + +;; edi - delay value + + mov ecx,edi + +.Loop: + mov eax,ecx + dec ecx + test eax,eax + jnz .Loop + + ret +ENDFUNC _ippcpDelay diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmd5m7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmd5m7as.asm new file mode 100644 index 000000000..dcaa1946b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmd5m7as.asm @@ -0,0 +1,320 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to MD5 +; (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +; +; Content: +; UpdateMD5 +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_MD5_) +%if (_IPP32E >= _IPP32E_M7) + + +;; +;; Magic functions defined in RFC 1321 +;; +%macro MAGIC_F 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F,%%Z + xor %%F,%%Y + and %%F,%%X + xor %%F,%%Z +%endmacro + + +%macro MAGIC_G 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + MAGIC_F %%F,%%Z,%%X,%%Y +%endmacro + + +%macro MAGIC_H 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F,%%Z + xor %%F,%%Y + xor %%F,%%X +%endmacro + + +%macro MAGIC_I 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F,%%Z + not %%F + or %%F,%%X + xor %%F,%%Y +%endmacro + + +%macro ROT_L 2.nolist + %xdefine %%r %1 + %xdefine %%nbits %2 + + %if (_IPP32E >= _IPP32E_L9) + rorx %%r,%%r,(32-%%nbits) + %elif (_IPP32E >= _IPP32E_Y8) + shld %%r,%%r,%%nbits + %else + rol %%r,%%nbits + %endif +%endmacro + + +;; +;; single MD5 step +;; +;; A = B +ROL32((A +MAGIC(B,C,D) +data +const), nrot) +;; +%macro xMD5_STEP 10.nolist + %xdefine %%MAGIC_FUN %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%FUN %6 + %xdefine %%TMP %7 + %xdefine %%data %8 + %xdefine %%MD5const %9 + %xdefine %%nrot %10 + + mov %%TMP,[%%data] +; lea A,[TMP+A+MD5const] + add %%A, %%MD5const + add %%A, %%TMP + %%MAGIC_FUN %%FUN, %%B,%%C,%%D + add %%A,%%FUN + rol %%A,%%nrot + add %%A,%%B +%endmacro + + +%macro MD5_STEP 10.nolist + %xdefine %%MAGIC_FUN %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%FUN %6 + %xdefine %%TMP %7 + %xdefine %%data %8 + %xdefine %%MD5const %9 + %xdefine %%nrot %10 + + mov %%TMP,[%%data] + add %%A, %%MD5const + add %%A, %%TMP + %%MAGIC_FUN %%FUN, %%B,%%C,%%D + add %%A,%%FUN + ROT_L %%A,%%nrot + add %%A,%%B +%endmacro + + +segment .text align=IPP_ALIGN_FACTOR + + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateMD5(DigestMD5digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +;; +;; MD5 left rotations (number of bits) +;; +%assign rot11 7 +%assign rot12 12 +%assign rot13 17 +%assign rot14 22 +%assign rot21 5 +%assign rot22 9 +%assign rot23 14 +%assign rot24 20 +%assign rot31 4 +%assign rot32 11 +%assign rot33 16 +%assign rot34 23 +%assign rot41 6 +%assign rot42 10 +%assign rot43 15 +%assign rot44 21 + +align IPP_ALIGN_FACTOR + +;; +;; Lib = M7 +;; +;; Caller = ippsMD5Update +;; Caller = ippsMD5Final +;; Caller = ippsMD5MessageDigest +;; +;; Caller = ippsHMACMD5Update +;; Caller = ippsHMACMD5Final +;; Caller = ippsHMACMD5MessageDigest +;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateMD5,PUBLIC + USES_GPR rbx,rsi,rdi,r12 + USES_XMM + COMP_ABI 4 + +;; rdi = hash +;; rsi = data buffer +;; rdx = buffer length +;; rcx = address of MD5 constants + +%assign MBS_MD5 64 + + movsxd r12, edx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.md5_block_loop: +; prefetcht0 [rsi+64] + +;; +;; init A, B, C, D by the internal digest +;; + mov r8d, [rdi+0*4] ; r8d = digest[0] (A) + mov r9d, [rdi+1*4] ; r9d = digest[1] (B) + mov r10d,[rdi+2*4] ; r10d = digest[2] (C) + mov r11d,[rdi+3*4] ; r11d = digest[3] (D) + +;; +;; perform 0-63 steps +;; +;; MAGIC A, B, C, D, FUN,TMP, pData, cnt, nrot +;; ------------------------------------------------------------------- + MD5_STEP MAGIC_F, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 0*4}, 0d76aa478h, rot11 + MD5_STEP MAGIC_F, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 1*4}, 0e8c7b756h, rot12 + MD5_STEP MAGIC_F, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 2*4}, 0242070dbh, rot13 + MD5_STEP MAGIC_F, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 3*4}, 0c1bdceeeh, rot14 + MD5_STEP MAGIC_F, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 4*4}, 0f57c0fafh, rot11 + MD5_STEP MAGIC_F, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 5*4}, 04787c62ah, rot12 + MD5_STEP MAGIC_F, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 6*4}, 0a8304613h, rot13 + MD5_STEP MAGIC_F, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 7*4}, 0fd469501h, rot14 + MD5_STEP MAGIC_F, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 8*4}, 0698098d8h, rot11 + MD5_STEP MAGIC_F, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 9*4}, 08b44f7afh, rot12 + MD5_STEP MAGIC_F, r10d,r11d,r8d, r9d, edx,ecx, {rsi+10*4}, 0ffff5bb1h, rot13 + MD5_STEP MAGIC_F, r9d, r10d,r11d,r8d, edx,ecx, {rsi+11*4}, 0895cd7beh, rot14 + MD5_STEP MAGIC_F, r8d, r9d, r10d,r11d, edx,ecx, {rsi+12*4}, 06b901122h, rot11 + MD5_STEP MAGIC_F, r11d,r8d, r9d, r10d, edx,ecx, {rsi+13*4}, 0fd987193h, rot12 + MD5_STEP MAGIC_F, r10d,r11d,r8d, r9d, edx,ecx, {rsi+14*4}, 0a679438eh, rot13 + MD5_STEP MAGIC_F, r9d, r10d,r11d,r8d, edx,ecx, {rsi+15*4}, 049b40821h, rot14 + + MD5_STEP MAGIC_G, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 1*4}, 0f61e2562h, rot21 + MD5_STEP MAGIC_G, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 6*4}, 0c040b340h, rot22 + MD5_STEP MAGIC_G, r10d,r11d,r8d, r9d, edx,ecx, {rsi+11*4}, 0265e5a51h, rot23 + MD5_STEP MAGIC_G, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 0*4}, 0e9b6c7aah, rot24 + MD5_STEP MAGIC_G, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 5*4}, 0d62f105dh, rot21 + MD5_STEP MAGIC_G, r11d,r8d, r9d, r10d, edx,ecx, {rsi+10*4}, 002441453h, rot22 + MD5_STEP MAGIC_G, r10d,r11d,r8d, r9d, edx,ecx, {rsi+15*4}, 0d8a1e681h, rot23 + MD5_STEP MAGIC_G, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 4*4}, 0e7d3fbc8h, rot24 + MD5_STEP MAGIC_G, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 9*4}, 021e1cde6h, rot21 + MD5_STEP MAGIC_G, r11d,r8d, r9d, r10d, edx,ecx, {rsi+14*4}, 0c33707d6h, rot22 + MD5_STEP MAGIC_G, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 3*4}, 0f4d50d87h, rot23 + MD5_STEP MAGIC_G, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 8*4}, 0455a14edh, rot24 + MD5_STEP MAGIC_G, r8d, r9d, r10d,r11d, edx,ecx, {rsi+13*4}, 0a9e3e905h, rot21 + MD5_STEP MAGIC_G, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 2*4}, 0fcefa3f8h, rot22 + MD5_STEP MAGIC_G, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 7*4}, 0676f02d9h, rot23 + MD5_STEP MAGIC_G, r9d, r10d,r11d,r8d, edx,ecx, {rsi+12*4}, 08d2a4c8ah, rot24 + + MD5_STEP MAGIC_H, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 5*4}, 0fffa3942h, rot31 + MD5_STEP MAGIC_H, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 8*4}, 08771f681h, rot32 + MD5_STEP MAGIC_H, r10d,r11d,r8d, r9d, edx,ecx, {rsi+11*4}, 06d9d6122h, rot33 + MD5_STEP MAGIC_H, r9d, r10d,r11d,r8d, edx,ecx, {rsi+14*4}, 0fde5380ch, rot34 + MD5_STEP MAGIC_H, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 1*4}, 0a4beea44h, rot31 + MD5_STEP MAGIC_H, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 4*4}, 04bdecfa9h, rot32 + MD5_STEP MAGIC_H, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 7*4}, 0f6bb4b60h, rot33 + MD5_STEP MAGIC_H, r9d, r10d,r11d,r8d, edx,ecx, {rsi+10*4}, 0bebfbc70h, rot34 + MD5_STEP MAGIC_H, r8d, r9d, r10d,r11d, edx,ecx, {rsi+13*4}, 0289b7ec6h, rot31 + MD5_STEP MAGIC_H, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 0*4}, 0eaa127fah, rot32 + MD5_STEP MAGIC_H, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 3*4}, 0d4ef3085h, rot33 + MD5_STEP MAGIC_H, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 6*4}, 004881d05h, rot34 + MD5_STEP MAGIC_H, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 9*4}, 0d9d4d039h, rot31 + MD5_STEP MAGIC_H, r11d,r8d, r9d, r10d, edx,ecx, {rsi+12*4}, 0e6db99e5h, rot32 + MD5_STEP MAGIC_H, r10d,r11d,r8d, r9d, edx,ecx, {rsi+15*4}, 01fa27cf8h, rot33 + MD5_STEP MAGIC_H, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 2*4}, 0c4ac5665h, rot34 + + MD5_STEP MAGIC_I, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 0*4}, 0f4292244h, rot41 + MD5_STEP MAGIC_I, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 7*4}, 0432aff97h, rot42 + MD5_STEP MAGIC_I, r10d,r11d,r8d, r9d, edx,ecx, {rsi+14*4}, 0ab9423a7h, rot43 + MD5_STEP MAGIC_I, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 5*4}, 0fc93a039h, rot44 + MD5_STEP MAGIC_I, r8d, r9d, r10d,r11d, edx,ecx, {rsi+12*4}, 0655b59c3h, rot41 + MD5_STEP MAGIC_I, r11d,r8d, r9d, r10d, edx,ecx, {rsi+ 3*4}, 08f0ccc92h, rot42 + MD5_STEP MAGIC_I, r10d,r11d,r8d, r9d, edx,ecx, {rsi+10*4}, 0ffeff47dh, rot43 + MD5_STEP MAGIC_I, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 1*4}, 085845dd1h, rot44 + MD5_STEP MAGIC_I, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 8*4}, 06fa87e4fh, rot41 + MD5_STEP MAGIC_I, r11d,r8d, r9d, r10d, edx,ecx, {rsi+15*4}, 0fe2ce6e0h, rot42 + MD5_STEP MAGIC_I, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 6*4}, 0a3014314h, rot43 + MD5_STEP MAGIC_I, r9d, r10d,r11d,r8d, edx,ecx, {rsi+13*4}, 04e0811a1h, rot44 + MD5_STEP MAGIC_I, r8d, r9d, r10d,r11d, edx,ecx, {rsi+ 4*4}, 0f7537e82h, rot41 + MD5_STEP MAGIC_I, r11d,r8d, r9d, r10d, edx,ecx, {rsi+11*4}, 0bd3af235h, rot42 + MD5_STEP MAGIC_I, r10d,r11d,r8d, r9d, edx,ecx, {rsi+ 2*4}, 02ad7d2bbh, rot43 + MD5_STEP MAGIC_I, r9d, r10d,r11d,r8d, edx,ecx, {rsi+ 9*4}, 0eb86d391h, rot44 + +;; +;; update digest +;; + add [rdi+0*4],r8d ; advance digest + add [rdi+1*4],r9d + add [rdi+2*4],r10d + add [rdi+3*4],r11d + + add rsi, MBS_MD5 + sub r12, MBS_MD5 + jg .md5_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateMD5 + + +%endif ;; _IPP32E >= _IPP32E_M7 +%endif ;; _ENABLE_ALG_MD5_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontmul1024_avx2as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontmul1024_avx2as.asm new file mode 100644 index 000000000..9752c18c5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontmul1024_avx2as.asm @@ -0,0 +1,378 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpMontMul1024_avx2() +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +;include pcpbnumulschool.inc +;include pcpvariant.inc + +%if (_IPP32E >= _IPP32E_L9) + +segment .text align=IPP_ALIGN_FACTOR + +%assign DIGIT_BITS 27 +%assign DIGIT_MASK (1 << DIGIT_BITS) -1 + +;************************************************************* +;* void cpMontMul1024_avx2(Ipp64u* pR, +;* const Ipp64u* pA, +;* const Ipp64u* pB, +;* const Ipp64u* pModulo, int mSize, +;* Ipp64u m0) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMontMul1024_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(ymmword) + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14 + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13,ymm14 + COMP_ABI 6 + + mov rbp,rdx ; pointer to B operand + movsxd r8, r8d ; redLen value counter + +;; clear results and buffers + vzeroall + +;; expands A and M operands + vmovdqu ymmword [rsi+r8*sizeof(qword)], ymm0 + vmovdqu ymmword [rcx+r8*sizeof(qword)], ymm0 + + xor r10, r10 ; ac0 = 0 + + vmovdqu ymmword [rsp], ymm0 ; {r3:r2:r1;R0} = 0 + +align IPP_ALIGN_FACTOR +;; +;; process b[] by quadruples (b[j], b[j+1], b[j+2] and b[j+3]) per pass +;; +.loop4_B: + mov rbx, qword [rbp] ; rbx = b[j] + vpbroadcastq ymm0, qword [rbp] + + mov r10, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul r10, qword [rsi] + add r10, qword [rsp] + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov r11, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul r11, qword [rsi+sizeof(qword)] + add r11, qword [rsp+sizeof(qword)] + mov r12, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul r12, qword [rsi+sizeof(qword)*2] + add r12, qword [rsp+sizeof(qword)*2] + mov r13, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul r13, qword [rsi+sizeof(qword)*3] + add r13, qword [rsp+sizeof(qword)*3] + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*4] + vpaddq ymm4, ymm4, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*5] + vpaddq ymm5, ymm5, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*6] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*7] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*8] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*9] + vpaddq ymm9, ymm9, ymm14 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*4] + vpaddq ymm4, ymm4, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*5] + vpaddq ymm5, ymm5, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*6] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*7] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*8] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*9] + vpaddq ymm9, ymm9, ymm14 +;; ------------------------------------------------------------ + + mov rbx, qword [rbp+sizeof(qword)] ; rbx = b[j+1] + vpbroadcastq ymm0, qword [rbp+sizeof(qword)] + mov rax, rbx ; ac1 += pa[0]*b[j+1] + imul rax, qword [rsi] + add r11, rax + mov rdx, r11 ; y1 = (ac1*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[1]*b[j+1] + imul rax, qword [rsi+sizeof(qword)] + add r12, rax + mov rax, rbx ; ac3 += pa[2]*b[j+1] + imul rax, qword [rsi+sizeof(qword)*2] + add r13, rax + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)-sizeof(qword)] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*2-sizeof(qword)] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*3-sizeof(qword)] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*4-sizeof(qword)] + vpaddq ymm4, ymm4, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*5-sizeof(qword)] + vpaddq ymm5, ymm5, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*6-sizeof(qword)] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*7-sizeof(qword)] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*8-sizeof(qword)] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*9-sizeof(qword)] + vpaddq ymm9, ymm9, ymm14 + + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + add r11, rax + shr r11, DIGIT_BITS + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + add r12, rax + add r12, r11 + mov rax, rdx ; ac3 += pn[2]*y1 + imul rax, qword [rcx+sizeof(qword)*2] + add r13, rax + + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)-sizeof(qword)] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*2-sizeof(qword)] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*3-sizeof(qword)] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*4-sizeof(qword)] + vpaddq ymm4, ymm4, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*5-sizeof(qword)] + vpaddq ymm5, ymm5, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*6-sizeof(qword)] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*7-sizeof(qword)] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*8-sizeof(qword)] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*9-sizeof(qword)] + vpaddq ymm9, ymm9, ymm14 + sub r8, 2 + jz .exit_loop_B +;; ------------------------------------------------------------ + + mov rbx, qword [rbp+sizeof(qword)*2] ; rbx = b[j+2] + vpbroadcastq ymm0, qword [rbp+sizeof(qword)*2] + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi] + add r12, rax + mov rdx, r12 ; y2 = (ac2*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi+sizeof(qword)] + add r13, rax + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)-sizeof(qword)*2] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*2-sizeof(qword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*3-sizeof(qword)*2] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*4-sizeof(qword)*2] + vpaddq ymm4, ymm4, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*5-sizeof(qword)*2] + vpaddq ymm5, ymm5, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*6-sizeof(qword)*2] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*7-sizeof(qword)*2] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*8-sizeof(qword)*2] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*9-sizeof(qword)*2] + vpaddq ymm9, ymm9, ymm14 + + mov rax, rdx ; ac2 += pn[0]*y2 + imul rax, qword [rcx] + add r12, rax + shr r12, DIGIT_BITS + mov rax, rdx ; ac3 += pn[1]*y2 + imul rax, qword [rcx+sizeof(qword)] + add r13, rax + add r13, r12 + + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)-sizeof(qword)*2] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*2-sizeof(qword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*3-sizeof(qword)*2] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*4-sizeof(qword)*2] + vpaddq ymm4, ymm4, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*5-sizeof(qword)*2] + vpaddq ymm5, ymm5, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*6-sizeof(qword)*2] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*7-sizeof(qword)*2] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*8-sizeof(qword)*2] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*9-sizeof(qword)*2] + vpaddq ymm9, ymm9, ymm14 +;; ------------------------------------------------------------ + + mov rbx, qword [rbp+sizeof(qword)*3] ; rbx = b[j+3] + vpbroadcastq ymm0, qword [rbp+sizeof(qword)*3] + imul rbx, qword [rsi] ; ac3 += pa[0]*b[j+3] + add r13, rbx + mov rdx, r13 ; y3 = (ac3*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)-sizeof(qword)*3] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*2-sizeof(qword)*3] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*3-sizeof(qword)*3] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*4-sizeof(qword)*3] + vpaddq ymm4, ymm4, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*5-sizeof(qword)*3] + vpaddq ymm5, ymm5, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*6-sizeof(qword)*3] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm12, ymm0, ymmword [rsi+sizeof(ymmword)*7-sizeof(qword)*3] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm0, ymmword [rsi+sizeof(ymmword)*8-sizeof(qword)*3] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm14, ymm0, ymmword [rsi+sizeof(ymmword)*9-sizeof(qword)*3] + vpaddq ymm9, ymm9, ymm14 + vpmuludq ymm10, ymm0, ymmword [rsi+sizeof(ymmword)*10-sizeof(qword)*3] + + imul rdx, qword [rcx] ; ac3 += pn[0]*y3 + add r13, rdx + shr r13, DIGIT_BITS + vmovq xmm14, r13 + + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)-sizeof(qword)*3] + vpaddq ymm1, ymm1, ymm12 + vpaddq ymm1, ymm1, ymm14 + vmovdqu ymmword [rsp], ymm1 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*2-sizeof(qword)*3] + vpaddq ymm1, ymm2, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*3-sizeof(qword)*3] + vpaddq ymm2, ymm3, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*4-sizeof(qword)*3] + vpaddq ymm3, ymm4, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*5-sizeof(qword)*3] + vpaddq ymm4, ymm5, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*6-sizeof(qword)*3] + vpaddq ymm5, ymm6, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*7-sizeof(qword)*3] + vpaddq ymm6, ymm7, ymm12 + vpmuludq ymm13, ymm11, ymmword [rcx+sizeof(ymmword)*8-sizeof(qword)*3] + vpaddq ymm7, ymm8, ymm13 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*9-sizeof(qword)*3] + vpaddq ymm8, ymm9, ymm14 + vpmuludq ymm12, ymm11, ymmword [rcx+sizeof(ymmword)*10-sizeof(qword)*3] + vpaddq ymm9, ymm10, ymm12 +;; ------------------------------------------------------------ + + add rbp, sizeof(qword)*4 + sub r8, 2 + jnz .loop4_B + +.exit_loop_B: + mov qword [rdi], r12 + mov qword [rdi+sizeof(qword)], r13 + vmovdqu ymmword [rdi+sizeof(qword)*2], ymm1 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)], ymm2 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)*2], ymm3 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)*3], ymm4 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)*4], ymm5 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)*5], ymm6 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)*6], ymm7 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)*7], ymm8 + vmovdqu ymmword [rdi+sizeof(qword)*2+sizeof(ymmword)*8], ymm9 + + ;; + ;; normalize + ;; + mov r8, dword 38 + xor rax, rax +.norm_loop: + add rax, qword [rdi] + add rdi, sizeof(qword) + mov rdx, dword DIGIT_MASK + and rdx, rax + shr rax, DIGIT_BITS + mov qword [rdi-sizeof(qword)], rdx + sub r8, 1 + jg .norm_loop + mov qword [rdi], rax + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC cpMontMul1024_avx2 + + +%endif ; _IPP32E_L9 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontmul_avx2as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontmul_avx2as.asm new file mode 100644 index 000000000..c1040770d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontmul_avx2as.asm @@ -0,0 +1,1834 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpMontMul4n_avx2() +; cpMontMul4n1_avx2() +; cpMontMul4n2_avx2() +; cpMontMul4n3_avx2() +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_L9) + +segment .text align=IPP_ALIGN_FACTOR + + +%assign DIGIT_BITS 27 +%assign DIGIT_MASK (1 << DIGIT_BITS) -1 + +;************************************************************* +;* void cpMontMul4n_avx2(Ipp64u* pR, +;* const Ipp64u* pA, +;* const Ipp64u* pB, +;* const Ipp64u* pModulo, int mSize, +;* Ipp64u m0, +;* Ipp64u* pBuffer) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMontMul4n_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*5 + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14 + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13 + COMP_ABI 7 + + mov rbp,rdx ; pointer to B operand + movsxd r8, r8d ; redLen value counter + +; +; stack struct +; +%assign pR 0 ; pointer to result +%assign pResult pR+sizeof(qword) ; pointer to buffer +%assign pA pResult+sizeof(qword) ; pointer to A operand +%assign pM pA+sizeof(qword) ; pointer to modulus +%assign redLen pM+sizeof(qword) ; length + + mov qword [rsp+pR], rdi ; save pointer to destination + mov qword [rsp+pA], rsi ; A operand + mov qword [rsp+pM], rcx ; modulus + mov qword [rsp+redLen], r8 ; modulus length + + mov rdi, qword [rsp+ARG_7] ; buffer + mov [rsp+pResult], rdi + + vpxor ymm0, ymm0, ymm0 + xor rax, rax + +;; expands A and M operands + vmovdqu ymmword [rsi+r8*sizeof(qword)], ymm0 + vmovdqu ymmword [rcx+r8*sizeof(qword)], ymm0 + +;; clear result buffer of (redLen+4) qword length + mov r14, r8 +align IPP_ALIGN_FACTOR +.clearLoop: + vmovdqu ymmword [rdi], ymm0 + add rdi, sizeof(ymmword) + sub r14, sizeof(ymmword)/sizeof(qword) + jg .clearLoop + vmovdqu ymmword [rdi], ymm0 + + lea r14, [r8+sizeof(ymmword)/sizeof(qword)-1] ; a_counter = (redLen+3) & (-4) + and r14,-(sizeof(ymmword)/sizeof(qword)) + +align IPP_ALIGN_FACTOR +;; +;; process b[] by quadruples (b[j], b[j+1], b[j+2] and b[j+3]) per pass +;; +.loop4_B: + sub r8, sizeof(ymmword)/sizeof(qword) + jl .exit_loop4_B + + mov rbx, qword [rbp] ; rbx = b[j] + vpbroadcastq ymm4, qword [rbp] + + mov rdi, qword [rsp+pResult] ; restore pointer to destination + mov rsi, qword [rsp+pA] ; A operand + mov rcx, qword [rsp+pM] ; modulus + + mov r10, qword [rdi] + mov r11, qword [rdi+sizeof(qword)] + mov r12, qword [rdi+sizeof(qword)*2] + mov r13, qword [rdi+sizeof(qword)*3] + + mov rax, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul rax, qword [rsi] + add r10, rax + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul rax, qword [rsi+sizeof(qword)] + add r11, rax + mov rax, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul rax, qword [rsi+sizeof(qword)*2] + add r12, rax + mov rax, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul rax, qword [rsi+sizeof(qword)*3] + add r13, rax + vmovd xmm8, edx + vpbroadcastq ymm8, xmm8 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)] ; rbx = b[j+1] + vpbroadcastq ymm5, qword [rbp+sizeof(qword)] + mov rax, rbx ; ac1 += pa[0]*b[j+1] + imul rax, qword [rsi] + add r11, rax + mov rdx, r11 ; y1 = (ac1*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[1]*b[j+1] + imul rax, qword [rsi+sizeof(qword)] + add r12, rax + mov rax, rbx ; ac3 += pa[2]*b[j+1] + imul rax, qword [rsi+sizeof(qword)*2] + add r13, rax + vmovd xmm9, edx + vpbroadcastq ymm9, xmm9 + + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + add r11, rax + shr r11, DIGIT_BITS + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + add r12, rax + add r12, r11 + mov rax, rdx ; ac3 += pn[2]*y1 + imul rax, qword [rcx+sizeof(qword)*2] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)*2] ; rbx = b[j+2] + vpbroadcastq ymm6, qword [rbp+sizeof(qword)*2] + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi] + add r12, rax + mov rdx, r12 ; y2 = (ac2*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi+sizeof(qword)] + add r13, rax + vmovd xmm10, edx + vpbroadcastq ymm10, xmm10 + + mov rax, rdx ; ac2 += pn[0]*y2 + imul rax, qword [rcx] + add r12, rax + shr r12, DIGIT_BITS + mov rax, rdx ; ac3 += pn[1]*y2 + imul rax, qword [rcx+sizeof(qword)] + add r13, rax + add r13, r12 + + mov rbx, qword [rbp+sizeof(qword)*3] ; rbx = b[j+3] + vpbroadcastq ymm7, qword [rbp+sizeof(qword)*3] + imul rbx, qword [rsi] ; ac3 += pa[0]*b[j+3] + add r13, rbx + mov rdx, r13 ; y3 = (ac3*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + imul rdx, qword [rcx] ; ac3 += pn[0]*y3 + add r13, rdx + shr r13, DIGIT_BITS + vmovq xmm0, r13 + + vpaddq ymm0, ymm0, ymmword [rdi+sizeof(ymmword)] + vmovdqu ymmword [rdi+sizeof(ymmword)], ymm0 + + add rbp, sizeof(qword)*4 + add rsi, sizeof(qword)*4 + add rcx, sizeof(qword)*4 + add rdi, sizeof(ymmword) + + mov r11, r14 ; init a_counter + + ;; (vb0) ymm4 = {b0:b0:b0:b0} + ;; (vb1) ymm5 = {b1:b1:b1:b1} + ;; (vb2) ymm6 = {b2:b2:b2:b2} + ;; (vb3) ymm7 = {b3:b3:b3:b3} + + ;; (vy0) ymm8 = {y0:y0:y0:y0} + ;; (vy1) ymm9 = {y1:y1:y1:y1} + ;; (vy2) ymm10= {y2:y2:y2:y2} + ;; (vy3) ymm11= {y3:y3:y3:y3} + + sub r11, sizeof(ymmword)/sizeof(qword) + +align IPP_ALIGN_FACTOR +.loop16_A: + sub r11, 4*sizeof(ymmword)/sizeof(qword) + jl .exit_loop16_A + + vmovdqu ymm0, ymmword [rdi] ; r0 + vmovdqu ymm1, ymmword [rdi+sizeof(ymmword)] ; r1 + vmovdqu ymm2, ymmword [rdi+sizeof(ymmword)*2] ; r2 + vmovdqu ymm3, ymmword [rdi+sizeof(ymmword)*3] ; r3 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)] ; r1 += vb0 * (__m256i*)(pa)[j+1] + vy0 * (__m256i*)(pn)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*2] ; r2 += vb0 * (__m256i*)(pa)[j+2] + vy0 * (__m256i*)(pn)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*3] ; r3 += vb0 * (__m256i*)(pa)[j+3] + vy0 * (__m256i*)(pn)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)] ; r1 += vb1 * (__m256i*)(pa-1)[j+1] + vy1 * (__m256i*)(pn-1)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*2] ; r2 += vb1 * (__m256i*)(pa-1)[j+2] + vy1 * (__m256i*)(pn-1)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*3] ; r3 += vb1 * (__m256i*)(pa-1)[j+3] + vy1 * (__m256i*)(pn-1)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)] ; r1 += vb2 * (__m256i*)(pa-2)[j+1] + vy2 * (__m256i*)(pn-2)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*2] ; r2 += vb2 * (__m256i*)(pa-2)[j+2] + vy2 * (__m256i*)(pn-2)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*3] ; r3 += vb2 * (__m256i*)(pa-2)[j+3] + vy2 * (__m256i*)(pn-2)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)] ; r1 += vb3 * (__m256i*)(pa-3)[j+1] + vy3 * (__m256i*)(pn-3)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*2] ; r2 += vb3 * (__m256i*)(pa-3)[j+2] + vy3 * (__m256i*)(pn-3)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*3] ; r3 += vb3 * (__m256i*)(pa-3)[j+3] + vy3 * (__m256i*)(pn-3)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)], ymm1 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*2], ymm2 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*3], ymm3 + + add rdi, sizeof(ymmword)*4 + add rsi, sizeof(ymmword)*4 + add rcx, sizeof(ymmword)*4 + jmp .loop16_A + +.exit_loop16_A: + add r11, 4*(sizeof(ymmword)/sizeof(qword)) + jz .exitA + +.loop4_A: + sub r11, sizeof(ymmword)/sizeof(qword) + jl .exitA + + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm2 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm2 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + + add rdi, sizeof(ymmword) + add rsi, sizeof(ymmword) + add rcx, sizeof(ymmword) + jmp .loop4_A + +.exitA: + vpmuludq ymm1, ymm5, ymmword [rsi-sizeof(qword)] ; r1 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm1, ymm1, ymm13 + + vpmuludq ymm2, ymm6, ymmword [rsi-sizeof(qword)*2] ; r2 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm2, ymm2, ymm13 + + vpmuludq ymm3, ymm7, ymmword [rsi-sizeof(qword)*3] ; r3 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpaddq ymm1, ymm1, ymm2 + vpaddq ymm1, ymm1, ymm3 + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm1 + + jmp .loop4_B + +.exit_loop4_B: + ;; + ;; normalize + ;; + mov rdi, qword [rsp+pR] + mov rsi, qword [rsp+pResult] + mov r8, qword [rsp+redLen] + xor rax, rax +.norm_loop: + add rax, qword [rsi] + add rsi, sizeof(qword) + mov rdx, dword DIGIT_MASK + and rdx, rax + shr rax, DIGIT_BITS + mov qword [rdi], rdx + add rdi, sizeof(qword) + sub r8, 1 + jg .norm_loop + mov qword [rdi], rax + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC cpMontMul4n_avx2 + + +;************************************************************* +;* void cpMontMul4n1_avx2(Ipp64u* pR, +;* const Ipp64u* pA, +;* const Ipp64u* pB, +;* const Ipp64u* pModulo, int mSize, +;* Ipp64u m0, +;* Ipp64u* pBuffer) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMontMul4n1_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*5 + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14 + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13 + COMP_ABI 7 + + mov rbp,rdx ; pointer to B operand + movsxd r8, r8d ; redLen value counter + +; +; stack struct +; +%xdefine pR 0 ; pointer to result +%xdefine pResult pR+sizeof(qword) ; pointer to buffer +%xdefine pA pResult+sizeof(qword) ; pointer to A operand +%xdefine pM pA+sizeof(qword) ; pointer to modulus +%xdefine redLen pM+sizeof(qword) ; length + + mov qword [rsp+pR], rdi ; save pointer to destination + mov qword [rsp+pA], rsi ; A operand + mov qword [rsp+pM], rcx ; modulus + mov qword [rsp+redLen], r8 ; modulus length + + mov rdi, qword [rsp+ARG_7] ; buffer + mov [rsp+pResult], rdi + + vpxor ymm0, ymm0, ymm0 + xor rax, rax + +;; expands A and M operands + vmovdqu ymmword [rsi+r8*sizeof(qword)], ymm0 + vmovdqu ymmword [rcx+r8*sizeof(qword)], ymm0 + +;; clear result buffer of (redLen+4) qword length + mov r14, r8 +align IPP_ALIGN_FACTOR +.clearLoop: + vmovdqu ymmword [rdi], ymm0 + add rdi, sizeof(ymmword) + sub r14, sizeof(ymmword)/sizeof(qword) + jg .clearLoop + mov qword [rdi], rax + + lea r14, [r8+sizeof(ymmword)/sizeof(qword)-1] ; a_counter = (redLen+3) & (-4) + and r14,-(sizeof(ymmword)/sizeof(qword)) + +align IPP_ALIGN_FACTOR +;; +;; process b[] by quadruples (b[j], b[j+1], b[j+2] and b[j+3]) per pass +;; +.loop4_B: + sub r8, sizeof(ymmword)/sizeof(qword) + jl .exit_loop4_B + + mov rbx, qword [rbp] ; rbx = b[j] + vpbroadcastq ymm4, qword [rbp] + + mov rdi, qword [rsp+pResult] ; restore pointer to destination + mov rsi, qword [rsp+pA] ; A operand + mov rcx, qword [rsp+pM] ; modulus + + mov r10, qword [rdi] + mov r11, qword [rdi+sizeof(qword)] + mov r12, qword [rdi+sizeof(qword)*2] + mov r13, qword [rdi+sizeof(qword)*3] + + mov rax, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul rax, qword [rsi] + add r10, rax + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul rax, qword [rsi+sizeof(qword)] + add r11, rax + mov rax, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul rax, qword [rsi+sizeof(qword)*2] + add r12, rax + mov rax, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul rax, qword [rsi+sizeof(qword)*3] + add r13, rax + vmovd xmm8, edx + vpbroadcastq ymm8, xmm8 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)] ; rbx = b[j+1] + vpbroadcastq ymm5, qword [rbp+sizeof(qword)] + mov rax, rbx ; ac1 += pa[0]*b[j+1] + imul rax, qword [rsi] + add r11, rax + mov rdx, r11 ; y1 = (ac1*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[1]*b[j+1] + imul rax, qword [rsi+sizeof(qword)] + add r12, rax + mov rax, rbx ; ac3 += pa[2]*b[j+1] + imul rax, qword [rsi+sizeof(qword)*2] + add r13, rax + vmovd xmm9, edx + vpbroadcastq ymm9, xmm9 + + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + add r11, rax + shr r11, DIGIT_BITS + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + add r12, rax + add r12, r11 + mov rax, rdx ; ac3 += pn[2]*y1 + imul rax, qword [rcx+sizeof(qword)*2] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)*2] ; rbx = b[j+2] + vpbroadcastq ymm6, qword [rbp+sizeof(qword)*2] + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi] + add r12, rax + mov rdx, r12 ; y2 = (ac2*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi+sizeof(qword)] + add r13, rax + vmovd xmm10, edx + vpbroadcastq ymm10, xmm10 + + mov rax, rdx ; ac2 += pn[0]*y2 + imul rax, qword [rcx] + add r12, rax + shr r12, DIGIT_BITS + mov rax, rdx ; ac3 += pn[1]*y2 + imul rax, qword [rcx+sizeof(qword)] + add r13, rax + add r13, r12 + + mov rbx, qword [rbp+sizeof(qword)*3] ; rbx = b[j+3] + vpbroadcastq ymm7, qword [rbp+sizeof(qword)*3] + imul rbx, qword [rsi] ; ac3 += pa[0]*b[j+3] + add r13, rbx + mov rdx, r13 ; y3 = (ac3*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + imul rdx, qword [rcx] ; ac3 += pn[0]*y3 + add r13, rdx + shr r13, DIGIT_BITS + vmovq xmm0, r13 + + vpaddq ymm0, ymm0, ymmword [rdi+sizeof(ymmword)] + vmovdqu ymmword [rdi+sizeof(ymmword)], ymm0 + + add rbp, sizeof(qword)*4 + add rsi, sizeof(qword)*4 + add rcx, sizeof(qword)*4 + add rdi, sizeof(ymmword) + + mov r11, r14 ; init a_counter + + ;; (vb0) ymm4 = {b0:b0:b0:b0} + ;; (vb1) ymm5 = {b1:b1:b1:b1} + ;; (vb2) ymm6 = {b2:b2:b2:b2} + ;; (vb3) ymm7 = {b3:b3:b3:b3} + + ;; (vy0) ymm8 = {y0:y0:y0:y0} + ;; (vy1) ymm9 = {y1:y1:y1:y1} + ;; (vy2) ymm10= {y2:y2:y2:y2} + ;; (vy3) ymm11= {y3:y3:y3:y3} + + sub r11, sizeof(ymmword)/sizeof(qword) + +align IPP_ALIGN_FACTOR +.loop16_A: + sub r11, 4*sizeof(ymmword)/sizeof(qword) + jl .exit_loop16_A + + vmovdqu ymm0, ymmword [rdi] ; r0 + vmovdqu ymm1, ymmword [rdi+sizeof(ymmword)] ; r1 + vmovdqu ymm2, ymmword [rdi+sizeof(ymmword)*2] ; r2 + vmovdqu ymm3, ymmword [rdi+sizeof(ymmword)*3] ; r3 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)] ; r1 += vb0 * (__m256i*)(pa)[j+1] + vy0 * (__m256i*)(pn)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*2] ; r2 += vb0 * (__m256i*)(pa)[j+2] + vy0 * (__m256i*)(pn)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*3] ; r3 += vb0 * (__m256i*)(pa)[j+3] + vy0 * (__m256i*)(pn)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)] ; r1 += vb1 * (__m256i*)(pa-1)[j+1] + vy1 * (__m256i*)(pn-1)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*2] ; r2 += vb1 * (__m256i*)(pa-1)[j+2] + vy1 * (__m256i*)(pn-1)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*3] ; r3 += vb1 * (__m256i*)(pa-1)[j+3] + vy1 * (__m256i*)(pn-1)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)] ; r1 += vb2 * (__m256i*)(pa-2)[j+1] + vy2 * (__m256i*)(pn-2)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*2] ; r2 += vb2 * (__m256i*)(pa-2)[j+2] + vy2 * (__m256i*)(pn-2)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*3] ; r3 += vb2 * (__m256i*)(pa-2)[j+3] + vy2 * (__m256i*)(pn-2)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)] ; r1 += vb3 * (__m256i*)(pa-3)[j+1] + vy3 * (__m256i*)(pn-3)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*2] ; r2 += vb3 * (__m256i*)(pa-3)[j+2] + vy3 * (__m256i*)(pn-3)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*3] ; r3 += vb3 * (__m256i*)(pa-3)[j+3] + vy3 * (__m256i*)(pn-3)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)], ymm1 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*2], ymm2 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*3], ymm3 + + add rdi, sizeof(ymmword)*4 + add rsi, sizeof(ymmword)*4 + add rcx, sizeof(ymmword)*4 + jmp .loop16_A + +.exit_loop16_A: + add r11, 4*(sizeof(ymmword)/sizeof(qword)) + jz .exitA + +.loop4_A: + sub r11, sizeof(ymmword)/sizeof(qword) + jl .exitA + + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm2 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm2 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + + add rdi, sizeof(ymmword) + add rsi, sizeof(ymmword) + add rcx, sizeof(ymmword) + jmp .loop4_A + +.exitA: + jmp .loop4_B + +;; +;; process latest b[redLen-1] +;; +.exit_loop4_B: + mov rbx, qword [rbp] ; rbx = b[redLen-1] + vpbroadcastq ymm4, qword [rbp] + + mov rdi, qword [rsp+pResult] ; restore pointer to destination + mov rsi, qword [rsp+pA] ; A operand + mov rcx, qword [rsp+pM] ; modulus + + mov r10, qword [rdi] + mov r11, qword [rdi+sizeof(qword)] + mov r12, qword [rdi+sizeof(qword)*2] + mov r13, qword [rdi+sizeof(qword)*3] + + mov rax, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul rax, qword [rsi] + add r10, rax + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul rax, qword [rsi+sizeof(qword)] + add r11, rax + mov rax, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul rax, qword [rsi+sizeof(qword)*2] + add r12, rax + mov rax, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul rax, qword [rsi+sizeof(qword)*3] + add r13, rax + vmovd xmm8, edx + vpbroadcastq ymm8, xmm8 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + mov qword [rdi], r11 ; pr[0] = ac1 + mov qword [rdi+sizeof(qword)], r12 ; pr[1] = ac2 + mov qword [rdi+sizeof(qword)*2], r13 ; pr[2] = ac3 + + add rbp, sizeof(qword)*4 + add rsi, sizeof(qword)*4 + add rcx, sizeof(qword)*4 + add rdi, sizeof(ymmword) + + mov r11, r14 ; init a_counter + sub r11, sizeof(ymmword)/sizeof(qword) + +align IPP_ALIGN_FACTOR +.rem_loop4_A: + sub r11, sizeof(ymmword)/sizeof(qword) + jl .exit_rem_loop4_A + + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + + vmovdqu ymmword [rdi+3*sizeof(qword)-sizeof(ymmword)], ymm0 + + add rdi, sizeof(ymmword) + add rsi, sizeof(ymmword) + add rcx, sizeof(ymmword) + jmp .rem_loop4_A + +.exit_rem_loop4_A: + + ;; + ;; normalize + ;; + mov rdi, qword [rsp+pR] + mov rsi, qword [rsp+pResult] + mov r8, qword [rsp+redLen] + xor rax, rax +.norm_loop: + add rax, qword [rsi] + add rsi, sizeof(qword) + mov rdx, dword DIGIT_MASK + and rdx, rax + shr rax, DIGIT_BITS + mov qword [rdi], rdx + add rdi, sizeof(qword) + sub r8, 1 + jg .norm_loop + mov qword [rdi], rax + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC cpMontMul4n1_avx2 + + +;************************************************************* +;* void cpMontMul4n2_avx2(Ipp64u* pR, +;* const Ipp64u* pA, +;* const Ipp64u* pB, +;* const Ipp64u* pModulo, int mSize, +;* Ipp64u m0, +;* Ipp64u* pBuffer) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMontMul4n2_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*5 + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14 + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13 + COMP_ABI 7 + + mov rbp,rdx ; pointer to B operand + movsxd r8, r8d ; redLen value counter + +; +; stack struct +; +%xdefine pR 0 ; pointer to result +%xdefine pResult pR+sizeof(qword) ; pointer to buffer +%xdefine pA pResult+sizeof(qword) ; pointer to A operand +%xdefine pM pA+sizeof(qword) ; pointer to modulus +%xdefine redLen pM+sizeof(qword) ; length + + mov qword [rsp+pR], rdi ; save pointer to destination + mov qword [rsp+pA], rsi ; A operand + mov qword [rsp+pM], rcx ; modulus + mov qword [rsp+redLen], r8 ; modulus length + + mov rdi, qword [rsp+ARG_7] ; buffer + mov [rsp+pResult], rdi + + vpxor ymm0, ymm0, ymm0 + xor rax, rax + +;; expands A and M operands + vmovdqu ymmword [rsi+r8*sizeof(qword)], ymm0 + vmovdqu ymmword [rcx+r8*sizeof(qword)], ymm0 + +;; clear result buffer of (redLen+4) qword length + mov r14, r8 +align IPP_ALIGN_FACTOR +.clearLoop: + vmovdqu ymmword [rdi], ymm0 + add rdi, sizeof(ymmword) + sub r14, sizeof(ymmword)/sizeof(qword) + jg .clearLoop + vmovdqu xmmword [rdi], xmm0 + + lea r14, [r8+sizeof(ymmword)/sizeof(qword)-1] ; a_counter = (redLen+3) & (-4) + and r14,-(sizeof(ymmword)/sizeof(qword)) + +align IPP_ALIGN_FACTOR +;; +;; process b[] by quadruples (b[j], b[j+1], b[j+2] and b[j+3]) per pass +;; +.loop4_B: + sub r8, sizeof(ymmword)/sizeof(qword) + jl .exit_loop4_B + + mov rbx, qword [rbp] ; rbx = b[j] + vpbroadcastq ymm4, qword [rbp] + + mov rdi, qword [rsp+pResult] ; restore pointer to destination + mov rsi, qword [rsp+pA] ; A operand + mov rcx, qword [rsp+pM] ; modulus + + mov r10, qword [rdi] + mov r11, qword [rdi+sizeof(qword)] + mov r12, qword [rdi+sizeof(qword)*2] + mov r13, qword [rdi+sizeof(qword)*3] + + mov rax, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul rax, qword [rsi] + add r10, rax + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul rax, qword [rsi+sizeof(qword)] + add r11, rax + mov rax, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul rax, qword [rsi+sizeof(qword)*2] + add r12, rax + mov rax, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul rax, qword [rsi+sizeof(qword)*3] + add r13, rax + vmovd xmm8, edx + vpbroadcastq ymm8, xmm8 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)] ; rbx = b[j+1] + vpbroadcastq ymm5, qword [rbp+sizeof(qword)] + mov rax, rbx ; ac1 += pa[0]*b[j+1] + imul rax, qword [rsi] + add r11, rax + mov rdx, r11 ; y1 = (ac1*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[1]*b[j+1] + imul rax, qword [rsi+sizeof(qword)] + add r12, rax + mov rax, rbx ; ac3 += pa[2]*b[j+1] + imul rax, qword [rsi+sizeof(qword)*2] + add r13, rax + vmovd xmm9, edx + vpbroadcastq ymm9, xmm9 + + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + add r11, rax + shr r11, DIGIT_BITS + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + add r12, rax + add r12, r11 + mov rax, rdx ; ac3 += pn[2]*y1 + imul rax, qword [rcx+sizeof(qword)*2] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)*2] ; rbx = b[j+2] + vpbroadcastq ymm6, qword [rbp+sizeof(qword)*2] + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi] + add r12, rax + mov rdx, r12 ; y2 = (ac2*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi+sizeof(qword)] + add r13, rax + vmovd xmm10, edx + vpbroadcastq ymm10, xmm10 + + mov rax, rdx ; ac2 += pn[0]*y2 + imul rax, qword [rcx] + add r12, rax + shr r12, DIGIT_BITS + mov rax, rdx ; ac3 += pn[1]*y2 + imul rax, qword [rcx+sizeof(qword)] + add r13, rax + add r13, r12 + + mov rbx, qword [rbp+sizeof(qword)*3] ; rbx = b[j+3] + vpbroadcastq ymm7, qword [rbp+sizeof(qword)*3] + imul rbx, qword [rsi] ; ac3 += pa[0]*b[j+3] + add r13, rbx + mov rdx, r13 ; y3 = (ac3*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + imul rdx, qword [rcx] ; ac3 += pn[0]*y3 + add r13, rdx + shr r13, DIGIT_BITS + vmovq xmm0, r13 + + vpaddq ymm0, ymm0, ymmword [rdi+sizeof(ymmword)] + vmovdqu ymmword [rdi+sizeof(ymmword)], ymm0 + + add rbp, sizeof(qword)*4 + add rsi, sizeof(qword)*4 + add rcx, sizeof(qword)*4 + add rdi, sizeof(ymmword) + + mov r11, r14 ; init a_counter + + ;; (vb0) ymm4 = {b0:b0:b0:b0} + ;; (vb1) ymm5 = {b1:b1:b1:b1} + ;; (vb2) ymm6 = {b2:b2:b2:b2} + ;; (vb3) ymm7 = {b3:b3:b3:b3} + + ;; (vy0) ymm8 = {y0:y0:y0:y0} + ;; (vy1) ymm9 = {y1:y1:y1:y1} + ;; (vy2) ymm10= {y2:y2:y2:y2} + ;; (vy3) ymm11= {y3:y3:y3:y3} + + sub r11, sizeof(ymmword)/sizeof(qword) + +align IPP_ALIGN_FACTOR +.loop16_A: + sub r11, 4*sizeof(ymmword)/sizeof(qword) + jl .exit_loop16_A + + vmovdqu ymm0, ymmword [rdi] ; r0 + vmovdqu ymm1, ymmword [rdi+sizeof(ymmword)] ; r1 + vmovdqu ymm2, ymmword [rdi+sizeof(ymmword)*2] ; r2 + vmovdqu ymm3, ymmword [rdi+sizeof(ymmword)*3] ; r3 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)] ; r1 += vb0 * (__m256i*)(pa)[j+1] + vy0 * (__m256i*)(pn)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*2] ; r2 += vb0 * (__m256i*)(pa)[j+2] + vy0 * (__m256i*)(pn)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*3] ; r3 += vb0 * (__m256i*)(pa)[j+3] + vy0 * (__m256i*)(pn)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)] ; r1 += vb1 * (__m256i*)(pa-1)[j+1] + vy1 * (__m256i*)(pn-1)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*2] ; r2 += vb1 * (__m256i*)(pa-1)[j+2] + vy1 * (__m256i*)(pn-1)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*3] ; r3 += vb1 * (__m256i*)(pa-1)[j+3] + vy1 * (__m256i*)(pn-1)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)] ; r1 += vb2 * (__m256i*)(pa-2)[j+1] + vy2 * (__m256i*)(pn-2)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*2] ; r2 += vb2 * (__m256i*)(pa-2)[j+2] + vy2 * (__m256i*)(pn-2)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*3] ; r3 += vb2 * (__m256i*)(pa-2)[j+3] + vy2 * (__m256i*)(pn-2)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)] ; r1 += vb3 * (__m256i*)(pa-3)[j+1] + vy3 * (__m256i*)(pn-3)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*2] ; r2 += vb3 * (__m256i*)(pa-3)[j+2] + vy3 * (__m256i*)(pn-3)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*3] ; r3 += vb3 * (__m256i*)(pa-3)[j+3] + vy3 * (__m256i*)(pn-3)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)], ymm1 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*2], ymm2 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*3], ymm3 + + add rdi, sizeof(ymmword)*4 + add rsi, sizeof(ymmword)*4 + add rcx, sizeof(ymmword)*4 + jmp .loop16_A + +.exit_loop16_A: + add r11, 4*(sizeof(ymmword)/sizeof(qword)) + jz .exitA + +.loop4_A: + sub r11, sizeof(ymmword)/sizeof(qword) + jl .exitA + + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm2 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm2 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + + add rdi, sizeof(ymmword) + add rsi, sizeof(ymmword) + add rcx, sizeof(ymmword) + jmp .loop4_A + +.exitA: + vpmuludq ymm0, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpmuludq ymm1, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm1 + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + + jmp .loop4_B + +;; +;; process latest b[redLen-2] and b[redLen-1] +;; +.exit_loop4_B: + mov rbx, qword [rbp] ; rbx = b[redLen-2] + vpbroadcastq ymm4, qword [rbp] + + mov rdi, qword [rsp+pResult] ; restore pointer to destination + mov rsi, qword [rsp+pA] ; A operand + mov rcx, qword [rsp+pM] ; modulus + + mov r10, qword [rdi] + mov r11, qword [rdi+sizeof(qword)] + mov r12, qword [rdi+sizeof(qword)*2] + mov r13, qword [rdi+sizeof(qword)*3] + + mov rax, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul rax, qword [rsi] + add r10, rax + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul rax, qword [rsi+sizeof(qword)] + add r11, rax + mov rax, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul rax, qword [rsi+sizeof(qword)*2] + add r12, rax + mov rax, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul rax, qword [rsi+sizeof(qword)*3] + add r13, rax + vmovd xmm8, edx + vpbroadcastq ymm8, xmm8 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)] ; rbx = b[j+1] + vpbroadcastq ymm5, qword [rbp+sizeof(qword)] + mov rax, rbx ; ac1 += pa[0]*b[j+1] + imul rax, qword [rsi] + add r11, rax + mov rdx, r11 ; y1 = (ac1*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[1]*b[j+1] + imul rax, qword [rsi+sizeof(qword)] + add r12, rax + mov rax, rbx ; ac3 += pa[2]*b[j+1] + imul rax, qword [rsi+sizeof(qword)*2] + add r13, rax + vmovd xmm9, edx + vpbroadcastq ymm9, xmm9 + + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + add r11, rax + shr r11, DIGIT_BITS + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + add r12, rax + add r12, r11 + mov rax, rdx ; ac3 += pn[2]*y1 + imul rax, qword [rcx+sizeof(qword)*2] + add r13, rax + + mov qword [rdi], r12 ; pr[0] = ac2 + mov qword [rdi+sizeof(qword)], r13 ; pr[1] = ac3 + + add rbp, sizeof(qword)*4 + add rsi, sizeof(qword)*4 + add rcx, sizeof(qword)*4 + add rdi, sizeof(ymmword) + + mov r11, r14 ; init a_counter + sub r11, sizeof(ymmword)/sizeof(qword) + +align IPP_ALIGN_FACTOR +.rem_loop4_A: + sub r11, sizeof(ymmword)/sizeof(qword) + jl .exit_rem_loop4_A + + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm13 + + vmovdqu ymmword [rdi+sizeof(qword)*2-sizeof(ymmword)], ymm0 + + add rdi, sizeof(ymmword) + add rsi, sizeof(ymmword) + add rcx, sizeof(ymmword) + jmp .rem_loop4_A + +.exit_rem_loop4_A: + + ;; + ;; normalize + ;; + mov rdi, qword [rsp+pR] + mov rsi, qword [rsp+pResult] + mov r8, qword [rsp+redLen] + xor rax, rax +.norm_loop: + add rax, qword [rsi] + add rsi, sizeof(qword) + mov rdx, dword DIGIT_MASK + and rdx, rax + shr rax, DIGIT_BITS + mov qword [rdi], rdx + add rdi, sizeof(qword) + sub r8, 1 + jg .norm_loop + mov qword [rdi], rax + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC cpMontMul4n2_avx2 + + +;************************************************************* +;* void cpMontMul4n3_avx2(Ipp64u* pR, +;* const Ipp64u* pA, +;* const Ipp64u* pB, +;* const Ipp64u* pModulo, int mSize, +;* Ipp64u m0, +;* Ipp64u* pBuffer) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpMontMul4n3_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*5 + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14 + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13 + COMP_ABI 7 + + mov rbp,rdx ; pointer to B operand + movsxd r8, r8d ; redLen value counter + +; +; stack struct +; +%xdefine pR 0 ; pointer to result +%xdefine pResult pR+sizeof(qword) ; pointer to buffer +%xdefine pA pResult+sizeof(qword) ; pointer to A operand +%xdefine pM pA+sizeof(qword) ; pointer to modulus +%xdefine redLen pM+sizeof(qword) ; length + + mov qword [rsp+pR], rdi ; save pointer to destination + mov qword [rsp+pA], rsi ; A operand + mov qword [rsp+pM], rcx ; modulus + mov qword [rsp+redLen], r8 ; modulus length + + mov rdi, qword [rsp+ARG_7] ; buffer + mov [rsp+pResult], rdi + + vpxor ymm0, ymm0, ymm0 + xor rax, rax + +;; expands A and M operands + vmovdqu ymmword [rsi+r8*sizeof(qword)], ymm0 + vmovdqu ymmword [rcx+r8*sizeof(qword)], ymm0 + +;; clear result buffer of (redLen+4) qword length + mov r14, r8 +align IPP_ALIGN_FACTOR +.clearLoop: + vmovdqu ymmword [rdi], ymm0 + add rdi, sizeof(ymmword) + sub r14, sizeof(ymmword)/sizeof(qword) + jg .clearLoop + vmovdqu xmmword [rdi], xmm0 + mov qword [rdi+sizeof(xmmword)], rax + + lea r14, [r8+sizeof(ymmword)/sizeof(qword)-1] ; a_counter = (redLen+3) & (-4) + and r14,-(sizeof(ymmword)/sizeof(qword)) + +align IPP_ALIGN_FACTOR +;; +;; process b[] by quadruples (b[j], b[j+1], b[j+2] and b[j+3]) per pass +;; +.loop4_B: + sub r8, sizeof(ymmword)/sizeof(qword) + jl .exit_loop4_B + + mov rbx, qword [rbp] ; rbx = b[j] + vpbroadcastq ymm4, qword [rbp] + + mov rdi, qword [rsp+pResult] ; restore pointer to destination + mov rsi, qword [rsp+pA] ; A operand + mov rcx, qword [rsp+pM] ; modulus + + mov r10, qword [rdi] + mov r11, qword [rdi+sizeof(qword)] + mov r12, qword [rdi+sizeof(qword)*2] + mov r13, qword [rdi+sizeof(qword)*3] + + mov rax, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul rax, qword [rsi] + add r10, rax + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul rax, qword [rsi+sizeof(qword)] + add r11, rax + mov rax, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul rax, qword [rsi+sizeof(qword)*2] + add r12, rax + mov rax, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul rax, qword [rsi+sizeof(qword)*3] + add r13, rax + vmovd xmm8, edx + vpbroadcastq ymm8, xmm8 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)] ; rbx = b[j+1] + vpbroadcastq ymm5, qword [rbp+sizeof(qword)] + mov rax, rbx ; ac1 += pa[0]*b[j+1] + imul rax, qword [rsi] + add r11, rax + mov rdx, r11 ; y1 = (ac1*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[1]*b[j+1] + imul rax, qword [rsi+sizeof(qword)] + add r12, rax + mov rax, rbx ; ac3 += pa[2]*b[j+1] + imul rax, qword [rsi+sizeof(qword)*2] + add r13, rax + vmovd xmm9, edx + vpbroadcastq ymm9, xmm9 + + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + add r11, rax + shr r11, DIGIT_BITS + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + add r12, rax + add r12, r11 + mov rax, rdx ; ac3 += pn[2]*y1 + imul rax, qword [rcx+sizeof(qword)*2] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)*2] ; rbx = b[j+2] + vpbroadcastq ymm6, qword [rbp+sizeof(qword)*2] + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi] + add r12, rax + mov rdx, r12 ; y2 = (ac2*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi+sizeof(qword)] + add r13, rax + vmovd xmm10, edx + vpbroadcastq ymm10, xmm10 + + mov rax, rdx ; ac2 += pn[0]*y2 + imul rax, qword [rcx] + add r12, rax + shr r12, DIGIT_BITS + mov rax, rdx ; ac3 += pn[1]*y2 + imul rax, qword [rcx+sizeof(qword)] + add r13, rax + add r13, r12 + + mov rbx, qword [rbp+sizeof(qword)*3] ; rbx = b[j+3] + vpbroadcastq ymm7, qword [rbp+sizeof(qword)*3] + imul rbx, qword [rsi] ; ac3 += pa[0]*b[j+3] + add r13, rbx + mov rdx, r13 ; y3 = (ac3*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + imul rdx, qword [rcx] ; ac3 += pn[0]*y3 + add r13, rdx + shr r13, DIGIT_BITS + vmovq xmm0, r13 + + vpaddq ymm0, ymm0, ymmword [rdi+sizeof(ymmword)] + vmovdqu ymmword [rdi+sizeof(ymmword)], ymm0 + + add rbp, sizeof(qword)*4 + add rsi, sizeof(qword)*4 + add rcx, sizeof(qword)*4 + add rdi, sizeof(ymmword) + + mov r11, r14 ; init a_counter + + ;; (vb0) ymm4 = {b0:b0:b0:b0} + ;; (vb1) ymm5 = {b1:b1:b1:b1} + ;; (vb2) ymm6 = {b2:b2:b2:b2} + ;; (vb3) ymm7 = {b3:b3:b3:b3} + + ;; (vy0) ymm8 = {y0:y0:y0:y0} + ;; (vy1) ymm9 = {y1:y1:y1:y1} + ;; (vy2) ymm10= {y2:y2:y2:y2} + ;; (vy3) ymm11= {y3:y3:y3:y3} + + sub r11, sizeof(ymmword)/sizeof(qword) + +align IPP_ALIGN_FACTOR +.loop16_A: + sub r11, 4*sizeof(ymmword)/sizeof(qword) + jl .exit_loop16_A + + vmovdqu ymm0, ymmword [rdi] ; r0 + vmovdqu ymm1, ymmword [rdi+sizeof(ymmword)] ; r1 + vmovdqu ymm2, ymmword [rdi+sizeof(ymmword)*2] ; r2 + vmovdqu ymm3, ymmword [rdi+sizeof(ymmword)*3] ; r3 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)] ; r1 += vb0 * (__m256i*)(pa)[j+1] + vy0 * (__m256i*)(pn)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*2] ; r2 += vb0 * (__m256i*)(pa)[j+2] + vy0 * (__m256i*)(pn)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm4, ymmword [rsi+sizeof(ymmword)*3] ; r3 += vb0 * (__m256i*)(pa)[j+3] + vy0 * (__m256i*)(pn)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)] ; r1 += vb1 * (__m256i*)(pa-1)[j+1] + vy1 * (__m256i*)(pn-1)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*2] ; r2 += vb1 * (__m256i*)(pa-1)[j+2] + vy1 * (__m256i*)(pn-1)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)+sizeof(ymmword)*3] ; r3 += vb1 * (__m256i*)(pa-1)[j+3] + vy1 * (__m256i*)(pn-1)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)] ; r1 += vb2 * (__m256i*)(pa-2)[j+1] + vy2 * (__m256i*)(pn-2)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*2] ; r2 += vb2 * (__m256i*)(pa-2)[j+2] + vy2 * (__m256i*)(pn-2)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2+sizeof(ymmword)*3] ; r3 += vb2 * (__m256i*)(pa-2)[j+3] + vy2 * (__m256i*)(pn-2)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)] ; r1 += vb3 * (__m256i*)(pa-3)[j+1] + vy3 * (__m256i*)(pn-3)[j+1] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*2] ; r2 += vb3 * (__m256i*)(pa-3)[j+2] + vy3 * (__m256i*)(pn-3)[j+2] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm12, ymm7, ymmword [rsi-sizeof(qword)*3+sizeof(ymmword)*3] ; r3 += vb3 * (__m256i*)(pa-3)[j+3] + vy3 * (__m256i*)(pn-3)[j+3] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm13 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)], ymm1 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*2], ymm2 + vmovdqu ymmword [rdi-sizeof(ymmword)+sizeof(ymmword)*3], ymm3 + + add rdi, sizeof(ymmword)*4 + add rsi, sizeof(ymmword)*4 + add rcx, sizeof(ymmword)*4 + jmp .loop16_A + +.exit_loop16_A: + add r11, 4*(sizeof(ymmword)/sizeof(qword)) + jz .exitA + +.loop4_A: + sub r11, sizeof(ymmword)/sizeof(qword) + jl .exitA + + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm2 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2] ; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm1, ymm7, ymmword [rsi-sizeof(qword)*3] ; r0 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpaddq ymm0, ymm0, ymm1 + vpmuludq ymm2, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm0, ymm0, ymm2 + + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm0 + + add rdi, sizeof(ymmword) + add rsi, sizeof(ymmword) + add rcx, sizeof(ymmword) + jmp .loop4_A + +.exitA: + vpmuludq ymm2, ymm6, ymmword [rsi-sizeof(qword)*2] ; r2 += vb3 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpmuludq ymm12, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm2, ymm2, ymm12 + + vpmuludq ymm3, ymm7, ymmword [rsi-sizeof(qword)*3] ; r3 += vb3 * (__m256i*)(pa-3)[j] + vy3 * (__m256i*)(pn-3)[j] + vpmuludq ymm13, ymm11,ymmword [rcx-sizeof(qword)*3] + vpaddq ymm3, ymm3, ymm13 + + vpaddq ymm2, ymm2, ymm3 + vmovdqu ymmword [rdi-sizeof(ymmword)], ymm2 + + jmp .loop4_B + +;; +;; process latest b[redLen-3], b[redLen-2] and b[redLen-1] +;; +.exit_loop4_B: + mov rbx, qword [rbp] ; rbx = b[redLen-3] + vpbroadcastq ymm4, qword [rbp] + + mov rdi, qword [rsp+pResult] ; restore pointer to destination + mov rsi, qword [rsp+pA] ; A operand + mov rcx, qword [rsp+pM] ; modulus + + mov r10, qword [rdi] + mov r11, qword [rdi+sizeof(qword)] + mov r12, qword [rdi+sizeof(qword)*2] + mov r13, qword [rdi+sizeof(qword)*3] + + mov rax, rbx ; ac0 = pa[0]*b[j]+pr[0] + imul rax, qword [rsi] + add r10, rax + mov rdx, r10 ; y0 = (ac0*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac1 = pa[1]*b[j]+pr[1] + imul rax, qword [rsi+sizeof(qword)] + add r11, rax + mov rax, rbx ; ac2 = pa[2]*b[j]+pr[2] + imul rax, qword [rsi+sizeof(qword)*2] + add r12, rax + mov rax, rbx ; ac3 = pa[3]*b[j]+pr[3] + imul rax, qword [rsi+sizeof(qword)*3] + add r13, rax + vmovd xmm8, edx + vpbroadcastq ymm8, xmm8 + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + shr r10, DIGIT_BITS + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + add r11, r10 + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + mov rax, rdx ; ac3 += pn[3]*y0 + imul rax, qword [rcx+sizeof(qword)*3] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)] ; rbx = b[redLen-2] + vpbroadcastq ymm5, qword [rbp+sizeof(qword)] + mov rax, rbx ; ac1 += pa[0]*b[j+1] + imul rax, qword [rsi] + add r11, rax + mov rdx, r11 ; y1 = (ac1*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[1]*b[j+1] + imul rax, qword [rsi+sizeof(qword)] + add r12, rax + mov rax, rbx ; ac3 += pa[2]*b[j+1] + imul rax, qword [rsi+sizeof(qword)*2] + add r13, rax + vmovd xmm9, edx + vpbroadcastq ymm9, xmm9 + + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + add r11, rax + shr r11, DIGIT_BITS + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + add r12, rax + add r12, r11 + mov rax, rdx ; ac3 += pn[2]*y1 + imul rax, qword [rcx+sizeof(qword)*2] + add r13, rax + + + mov rbx, qword [rbp+sizeof(qword)*2] ; rbx = b[redLen-1] + vpbroadcastq ymm6, qword [rbp+sizeof(qword)*2] + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi] + add r12, rax + mov rdx, r12 ; y2 = (ac2*m0) & DIGIT_MASK + imul edx, r9d + and edx, DIGIT_MASK + mov rax, rbx ; ac2 += pa[0]*b[j+2] + imul rax, qword [rsi+sizeof(qword)] + add r13, rax + vmovd xmm10, edx + vpbroadcastq ymm10, xmm10 + + mov rax, rdx ; ac2 += pn[0]*y2 + imul rax, qword [rcx] + add r12, rax + shr r12, DIGIT_BITS + mov rax, rdx ; ac3 += pn[1]*y2 + imul rax, qword [rcx+sizeof(qword)] + add r13, rax + add r13, r12 + + mov qword [rdi], r13 ; pr[0] = ac3 + + add rbp, sizeof(qword)*4 + add rsi, sizeof(qword)*4 + add rcx, sizeof(qword)*4 + add rdi, sizeof(ymmword) + + mov r11, r14 ; init a_counter + sub r11, sizeof(ymmword)/sizeof(qword) + +align IPP_ALIGN_FACTOR +.rem_loop4_A: + sub r11, sizeof(ymmword)/sizeof(qword) + jl .exit_rem_loop4_A + + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm4, ymmword [rsi] ; r0 += vb0 * (__m256i*)(pa)[j] + vy0 * (__m256i*)(pn)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm8, ymmword [rcx] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm12, ymm5, ymmword [rsi-sizeof(qword)] ; r0 += vb1 * (__m256i*)(pa-1)[j] + vy1 * (__m256i*)(pn-1)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm9, ymmword [rcx-sizeof(qword)] + vpaddq ymm0, ymm0, ymm13 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2]; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + + vmovdqu ymmword [rdi+sizeof(qword)-sizeof(ymmword)], ymm0 + + add rdi, sizeof(ymmword) + add rsi, sizeof(ymmword) + add rcx, sizeof(ymmword) + jmp .rem_loop4_A + +.exit_rem_loop4_A: + vmovdqu ymm0, ymmword [rdi] ; r0 + + vpmuludq ymm12, ymm6, ymmword [rsi-sizeof(qword)*2]; r0 += vb2 * (__m256i*)(pa-2)[j] + vy2 * (__m256i*)(pn-2)[j] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm10,ymmword [rcx-sizeof(qword)*2] + vpaddq ymm0, ymm0, ymm13 + + vmovdqu ymmword [rdi+sizeof(qword)-sizeof(ymmword)], ymm0 + + ;; + ;; normalize + ;; + mov rdi, qword [rsp+pR] + mov rsi, qword [rsp+pResult] + mov r8, qword [rsp+redLen] + xor rax, rax +.norm_loop: + add rax, qword [rsi] + add rsi, sizeof(qword) + mov rdx, dword DIGIT_MASK + and rdx, rax + shr rax, DIGIT_BITS + mov qword [rdi], rdx + add rdi, sizeof(qword) + sub r8, 1 + jg .norm_loop + mov qword [rdi], rax + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC cpMontMul4n3_avx2 + + +%endif ; _IPP32E_L9 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontreductionm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontreductionm7as.asm new file mode 100644 index 000000000..9e361fd89 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontreductionm7as.asm @@ -0,0 +1,1549 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpMontRedAdc_BNU() +; +; +; History: +; Extra reduction (R=A-M) has been added to perform MontReduction safe +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpbnumulschool.inc" +%include "pcpvariant.inc" + +%if (_ADCOX_NI_ENABLING_ == _FEATURE_OFF_) || (_ADCOX_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_M7) && (_IPP32E < _IPP32E_L9) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; fixed size reduction +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%macro MREDUCE_FIX_STEP 12.nolist + %xdefine %%mSize %1 + %xdefine %%X7 %2 + %xdefine %%X6 %3 + %xdefine %%X5 %4 + %xdefine %%X4 %5 + %xdefine %%X3 %6 + %xdefine %%X2 %7 + %xdefine %%X1 %8 + %xdefine %%X0 %9 + %xdefine %%rSrc %10 + %xdefine %%U %11 + %xdefine %%rCarry %12 + +%if %%mSize > 0 + mul %%U + xor %%rCarry, %%rCarry + add %%X0, rax + +%if %%mSize > 1 + mov rax, qword [%%rSrc+sizeof(qword)] + adc %%rCarry, rdx + mul %%U + add %%X1, %%rCarry + adc rdx, 0 + xor %%rCarry, %%rCarry + add %%X1, rax + +%if %%mSize > 2 + mov rax, qword [%%rSrc+sizeof(qword)*2] + adc %%rCarry, rdx + mul %%U + add %%X2, %%rCarry + adc rdx, 0 + xor %%rCarry, %%rCarry + add %%X2, rax + +%if %%mSize > 3 + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%rCarry, rdx + mul %%U + add %%X3, %%rCarry + adc rdx, 0 + xor %%rCarry, %%rCarry + add %%X3, rax +%if %%mSize == 4 + adc %%X4, rdx + adc %%rCarry, 0 + add %%X4, qword [rsp+carry] +%endif +%endif ;; mSize==4 + +%if %%mSize == 3 + adc %%X3, rdx + adc %%rCarry, 0 + add %%X3, qword [rsp+carry] +%endif +%endif ;; mSize==3 + +%if %%mSize == 2 + adc %%X2, rdx + adc %%rCarry, 0 + add %%X2, qword [rsp+carry] +%endif +%endif ;; mSize==2 + +%if %%mSize == 1 + adc %%X1, rdx + adc %%rCarry, 0 + add %%X1, qword [rsp+carry] +%endif +%endif ;; mSize==1 + + adc %%rCarry, 0 + mov qword [rsp+carry], %%rCarry +%endmacro + +%macro MREDUCE_FIX 14.nolist + %xdefine %%mSize %1 + %xdefine %%rDst %2 + %xdefine %%rSrc %3 + %xdefine %%M0 %4 + %xdefine %%X7 %5 + %xdefine %%X6 %6 + %xdefine %%X5 %7 + %xdefine %%X4 %8 + %xdefine %%X3 %9 + %xdefine %%X2 %10 + %xdefine %%X1 %11 + %xdefine %%X0 %12 + %xdefine %%U %13 + %xdefine %%rCarry %14 + +%if %%mSize > 0 + mov %%U, %%X0 + imul %%U, %%M0 + mov rax, qword [%%rSrc] + MREDUCE_FIX_STEP %%mSize, %%X7,%%X6,%%X5,%%X4,%%X3,%%X2,%%X1,%%X0, %%rSrc, %%U, %%rCarry + +%if %%mSize > 1 + mov %%U, %%X1 + imul %%U, %%M0 + mov rax, qword [%%rSrc] + MREDUCE_FIX_STEP %%mSize, %%X0,%%X7,%%X6,%%X5,%%X4,%%X3,%%X2,%%X1, %%rSrc, %%U, %%rCarry + +%if %%mSize > 2 + mov %%U, %%X2 + imul %%U, %%M0 + mov rax, qword [%%rSrc] + MREDUCE_FIX_STEP %%mSize, %%X1,%%X0,%%X7,%%X6,%%X5,%%X4,%%X3,%%X2, %%rSrc, %%U, %%rCarry + +%if %%mSize > 3 ; mSize == 4 + mov %%U, %%X3 + imul %%U, %%M0 + mov rax, qword [%%rSrc] + MREDUCE_FIX_STEP %%mSize, %%X2,%%X1,%%X0,%%X7,%%X6,%%X5,%%X4,%%X3, %%rSrc, %%U, %%rCarry + + mov %%X0, %%X4 ; {X3:X2:X1:X0} = {X7:X6:X5:X4} + sub %%X4, qword [%%rSrc] ; {X7:X6:X5:X4}-= modulus + mov %%X1, %%X5 + sbb %%X5, qword [%%rSrc+sizeof(qword)] + mov %%X2, %%X6 + sbb %%X6, qword [%%rSrc+sizeof(qword)*2] + mov %%X3, %%X7 + sbb %%X7, qword [%%rSrc+sizeof(qword)*3] + sbb %%rCarry, 0 + + cmovc %%X4, %%X0 ; dst = borrow? {X3:X2:X1:X0} : {X7:X6:X5:X4} + mov qword [%%rDst], %%X4 + cmovc %%X5, %%X1 + mov qword [%%rDst+sizeof(qword)], %%X5 + cmovc %%X6, %%X2 + mov qword [%%rDst+sizeof(qword)*2], %%X6 + cmovc %%X7, %%X3 + mov qword [%%rDst+sizeof(qword)*3], %%X7 +%endif +%endif +%endif +%endif + +%if %%mSize == 3 + mov %%X0, %%X3 ; {X2:X1:X0} = {X5:X4:X3} + sub %%X3, qword [%%rSrc] ; {X5:X4:X3}-= modulus + mov %%X1, %%X4 + sbb %%X4, qword [%%rSrc+sizeof(qword)] + mov %%X2, %%X5 + sbb %%X5, qword [%%rSrc+sizeof(qword)*2] + sbb %%rCarry, 0 + + cmovc %%X3, %%X0 ; dst = borrow? {X2:X1:X0} : {X5:X4:X3} + mov qword [%%rDst], %%X3 + cmovc %%X4, %%X1 + mov qword [%%rDst+sizeof(qword)], %%X4 + cmovc %%X5, %%X2 + mov qword [%%rDst+sizeof(qword)*2], %%X5 +%endif ; mSize==3 + +%if %%mSize == 2 + mov %%X0, %%X2 ; {X1:X0} = {X3:X2} + sub %%X2, qword [%%rSrc] ; {X3:X2}-= modulus + mov %%X1, %%X3 + sbb %%X3, qword [%%rSrc+sizeof(qword)] + sbb %%rCarry, 0 + + cmovc %%X2, %%X0 ; dst = borrow? {X1:X0} : {X3:X2} + mov qword [%%rDst], %%X2 + cmovc %%X3, %%X1 + mov qword [%%rDst+sizeof(qword)], %%X3 +%endif ; mSize==2 + +%if %%mSize == 1 + mov %%X0, %%X1 ; X1 = X0 + sub %%X1, qword [%%rSrc] ; X1 -= modulus + sbb %%rCarry, 0 + + cmovc %%X1, %%X0 ; dst = borrow? X0 : X1 + mov qword [%%rDst], %%X1 +%endif ; mSize==1 +%endmacro + +%if (_IPP32E <= _IPP32E_Y8) +;; +;; Pre- Sandy Brige specific code +;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; product = + modulus * U0 + +;; main body: product = + modulus * U0 +%macro MLAx1 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + ALIGN IPP_ALIGN_FACTOR +%%L_1: + mul %%U0 + xor %%T2, %%T2 + add %%T0, qword [%%rDst+%%idx*sizeof(qword)-sizeof(qword)] + adc %%T1, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] + adc %%T2, rdx + mov qword [%%rDst+%%idx*sizeof(qword)-sizeof(qword)], %%T0 + + mul %%U0 + xor %%T3, %%T3 + add %%T1, qword [%%rDst+%%idx*sizeof(qword)] + adc %%T2, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] + adc %%T3, rdx + mov qword [%%rDst+%%idx*sizeof(qword)], %%T1 + + mul %%U0 + xor %%T0, %%T0 + add %%T2, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)] + adc %%T3, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] + adc %%T0, rdx + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T2 + + mul %%U0 + xor %%T1, %%T1 + add %%T3, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2] + adc %%T0, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] + adc %%T1, rdx + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T3 + + add %%idx, 4 + jnc %%L_1 +%endmacro + +;; elipogue: product = modulus * U0, (srcLen=4*n+1) +%macro MM_MLAx1_4N_1_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov rax, qword [%%rSrc+sizeof(qword)] + mov %%idx, qword [rsp+counter] + + mul %%U0 + xor %%T3, %%T3 + add %%T1, qword [%%rDst] + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] + adc %%T3, rdx + mov qword [%%rDst], %%T1 + + mul %%U0 + xor %%T0, %%T0 + add %%T2, qword [%%rDst+sizeof(qword)] + adc %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T0, rdx + mov qword [%%rDst+sizeof(qword)], %%T2 + + mul %%U0 + add %%T3, qword [%%rDst+sizeof(qword)*2] + adc %%T0, rax + adc rdx, 0 + xor rax, rax + mov qword [%%rDst+sizeof(qword)*2], %%T3 + + add %%T0, qword [%%rDst+sizeof(qword)*3] + adc rdx, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T0 + mov qword [%%rDst+sizeof(qword)*4], rdx + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +;; elipogue: product = modulus * U0, (srcLen=4*n+4) +%macro MM_MLAx1_4N_4_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov rax, qword [%%rSrc+sizeof(qword)*2] + mov %%idx, qword [rsp+counter] + + mul %%U0 + xor %%T3, %%T0 + add %%T1, qword [%%rDst+sizeof(qword)] + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T3, rdx + mov qword [%%rDst+sizeof(qword)], %%T1 + + mul %%U0 + add %%T2, qword [%%rDst+sizeof(qword)*2] + adc %%T3, rax + adc rdx, 0 + xor rax, rax + mov qword [%%rDst+sizeof(qword)*2], %%T2 + + add %%T3, qword [%%rDst+sizeof(qword)*3] + adc rdx, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T3 + mov qword [%%rDst+sizeof(qword)*4], rdx + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +;; elipogue: product = modulus * U0, (srcLen=4*n+3) +%macro MM_MLAx1_4N_3_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov rax, qword [%%rSrc+sizeof(qword)*3] + mov %%idx, qword [rsp+counter] + + mul %%U0 + add %%T1, qword [%%rDst+sizeof(qword)*2] + adc %%T2, rax + adc rdx, 0 + xor rax, rax + mov qword [%%rDst+sizeof(qword)*2], %%T1 + + add %%T2, qword [%%rDst+sizeof(qword)*3] + adc rdx, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T2 + mov qword [%%rDst+sizeof(qword)*4], rdx + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +;; elipogue: product = modulus * U0, (srcLen=4*n+2) +%macro MM_MLAx1_4N_2_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov %%idx, qword [rsp+counter] + xor rax, rax + + add %%T1, qword [%%rDst+sizeof(qword)*3] + adc %%T2, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T1 + mov qword [%%rDst+sizeof(qword)*4], %%T2 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +%endif + + +%if (_IPP32E >= _IPP32E_E9) +;; +;; Sandy Brige specific code +;; +%macro MLAx1 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + ALIGN IPP_ALIGN_FACTOR +%%L_1: + mul %%U0 + xor %%T2, %%T2 + add %%T0, qword [%%rDst+%%idx*sizeof(qword)-sizeof(qword)] + mov qword [%%rDst+%%idx*sizeof(qword)-sizeof(qword)], %%T0 + adc %%T1, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] + adc %%T2, rdx + + mul %%U0 + xor %%T3, %%T3 + add %%T1, qword [%%rDst+%%idx*sizeof(qword)] + mov qword [%%rDst+%%idx*sizeof(qword)], %%T1 + adc %%T2, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*2] + adc %%T3, rdx + + mul %%U0 + xor %%T0, %%T0 + add %%T2, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T2 + adc %%T3, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*3] + adc %%T0, rdx + + mul %%U0 + xor %%T1, %%T1 + add %%T3, qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T3 + adc %%T0, rax + mov rax, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)*4] + adc %%T1, rdx + + add %%idx, 4 + jnc %%L_1 +%endmacro + +%macro MM_MLAx1_4N_1_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov rax, qword [%%rSrc+sizeof(qword)] + mov %%idx, qword [rsp+counter] + + mul %%U0 + xor %%T3, %%T3 + add %%T1, qword [%%rDst] + mov qword [%%rDst], %%T1 + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] + adc %%T3, rdx + + mul %%U0 + xor %%T0, %%T0 + add %%T2, qword [%%rDst+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T2 + adc %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T0, rdx + + mul %%U0 + add %%T3, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T3 + adc %%T0, rax + adc rdx, 0 + xor rax, rax + + add %%T0, qword [%%rDst+sizeof(qword)*3] + adc rdx, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T0 + mov qword [%%rDst+sizeof(qword)*4], rdx + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +%macro MM_MLAx1_4N_4_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov rax, qword [%%rSrc+sizeof(qword)*2] + mov %%idx, qword [rsp+counter] + + mul %%U0 + xor %%T3, %%T0 + add %%T1, qword [%%rDst+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T1 + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] + adc %%T3, rdx + + mul %%U0 + add %%T2, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T2 + adc %%T3, rax + adc rdx, 0 + xor rax, rax + + add %%T3, qword [%%rDst+sizeof(qword)*3] + adc rdx, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T3 + mov qword [%%rDst+sizeof(qword)*4], rdx + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +%macro MM_MLAx1_4N_3_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov rax, qword [%%rSrc+sizeof(qword)*3] + mov %%idx, qword [rsp+counter] + + mul %%U0 + add %%T1, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T1 + adc %%T2, rax + adc rdx, 0 + xor rax, rax + + add %%T2, qword [%%rDst+sizeof(qword)*3] + adc rdx, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T2 + mov qword [%%rDst+sizeof(qword)*4], rdx + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +%macro MM_MLAx1_4N_2_ELOG 8.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + + mov %%idx, qword [rsp+counter] + xor rax, rax + + add %%T1, qword [%%rDst+sizeof(qword)*3] + adc %%T2, qword [%%rDst+sizeof(qword)*4] + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*3], %%T1 + mov qword [%%rDst+sizeof(qword)*4], %%T2 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword) +%endmacro + +%endif + +; +; prologue: +; pre-compute: +; - u0 = product[0]*m0 +; - u1 = (product[1] + LO(modulo[1]*u0) + HI(modulo[0]*u0) carry(product[0]+LO(modulo[0]*u0)))*m0 +; +%macro MMx2_PLOG 10.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%m0 %4 + %xdefine %%U0 %5 + %xdefine %%U1 %6 + %xdefine %%T0 %7 + %xdefine %%T1 %8 + %xdefine %%T2 %9 + %xdefine %%T3 %10 + + mov %%U0, qword [%%rDst+%%idx*sizeof(qword)] ; product[0] + imul %%U0, %%m0 ; u0 = product[0]*m0 + + mov rax, qword [%%rSrc+%%idx*sizeof(qword)] ; modulo[0]*u0 + mul %%U0 + + mov %%U1, qword [%%rSrc+%%idx*sizeof(qword)+sizeof(qword)] ; modulo[1]*u0 + imul %%U1, %%U0 + + mov %%T0, rax ; save modulo[0]*u0 + mov %%T1, rdx + + add rax, qword [rdi+%%idx*sizeof(qword)] ; a[1] = product[1] + LO(modulo[1]*u0) + adc rdx, qword [rdi+%%idx*sizeof(qword)+sizeof(qword)] ; + HI(modulo[0]*u0) + add %%U1, rdx ; + carry(product[0]+LO(modulo[0]*u0)) + imul %%U1, %%m0 ; u1 = a[1]*m0 + + mov rax, qword [%%rSrc+%%idx*sizeof(qword)] + xor %%T2, %%T2 +%endmacro + +%if (_IPP32E <= _IPP32E_Y8) +;; +;; Pre- Sandy Brige specific code +;; +%macro MM_MLAx2_4N_1_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += modulus[mSize-1]*U1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T0, qword [%%rDst+sizeof(qword)*3] + adc %%T1, rax + mov qword [%%rDst+sizeof(qword)*3], %%T0 + adc %%T2, rdx + xor rax, rax + + add %%T1, qword [%%rDst+sizeof(qword)*4] + adc %%T2, qword [%%rDst+sizeof(qword)*5] + adc rax, 0 + add %%T1, qword [rsp+carry] + adc %%T2, 0 + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*4], %%T1 + mov qword [%%rDst+sizeof(qword)*5], %%T2 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%macro MM_MLAx2_4N_2_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += a[mSize-2]*U1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T2, rdx + + mul %%U0 ; {T3:T2:T1} += a[mSize-1]*U0 + r[mSize-2] + add %%T0, qword [%%rDst+sizeof(qword)*2] + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T2, rdx + mov qword [%%rDst+sizeof(qword)*2], %%T0 + adc %%T3, 0 + + mul %%U1 ; {T3:T2} += a[mSize-1]*B1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T1, qword [%%rDst+sizeof(qword)*3] + adc %%T2, rax + mov qword [%%rDst+sizeof(qword)*3], %%T1 + adc %%T3, rdx + xor rax, rax + + add %%T2, qword [%%rDst+sizeof(qword)*4] + adc %%T3, qword [%%rDst+sizeof(qword)*5] + adc rax, 0 + add %%T2, qword [rsp+carry] + adc %%T3, 0 + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*4], %%T2 + mov qword [%%rDst+sizeof(qword)*5], %%T3 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%macro MM_MLAx2_4N_3_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += a[mSize-3]*U1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[mSize-2] + adc %%T2, rdx + + mul %%U0 ; {T3:T2:T1} += a[mSize-2]*U0 + r[mSize-3] + add %%T0, qword [%%rDst+sizeof(qword)] + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[mSize-2] + adc %%T2, rdx + mov qword [%%rDst+sizeof(qword)], %%T0 + adc %%T3, 0 + + mul %%U1 ; {T3:T2} += a[mSize-2]*U1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T3, rdx + + mul %%U0 ; {T0:T3:T2} += a[mSize-1]*U0 + r[mSize-2] + add %%T1, qword [rdi+sizeof(qword)*2] + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T3, rdx + mov qword [rdi+sizeof(qword)*2], %%T1 + adc %%T0, 0 + + mul %%U1 ; {T0:T3} += a[mSize-1]*U1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T2, qword [rdi+sizeof(qword)*3] + adc %%T3, rax + mov qword [rdi+sizeof(qword)*3], %%T2 + adc %%T0, rdx + xor rax, rax + + add %%T3, qword [rdi+sizeof(qword)*4] + adc %%T0, qword [rdi+sizeof(qword)*5] + adc rax, 0 + add %%T3, qword [rsp+carry] + adc %%T0, 0 + adc rax, 0 + mov qword [rdi+sizeof(qword)*4], %%T3 + mov qword [rdi+sizeof(qword)*5], %%T0 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%macro MM_MLAx2_4N_4_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += a[mSize-4]*U1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + adc %%T2, rdx + + mul %%U0 ; {T3:T2:T1} += a[mSize-3]*U0 + r[mSize-4] + add %%T0, qword [%%rDst] + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[mSize-3] + adc %%T2, rdx + mov qword [%%rDst], %%T0 + adc %%T3, 0 + + mul %%U1 ; {T3:T2} += a[mSize-3]*U1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[mSize-2] + adc %%T3, rdx + + mul %%U0 ; {T0:T3:T2} += a[mSize-2]*U0 + r[mSize-3] + add %%T1, qword [%%rDst+sizeof(qword)] + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + adc %%T3, rdx + mov qword [%%rDst+sizeof(qword)], %%T1 + adc %%T0, 0 + + mul %%U1 ; {T0:T3} += a[mSize-2]*U1 + xor %%T1, %%T1 + add %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T0, rdx + + mul %%U0 ; {T1:T0:T3} += a[mSize-1]*U0 + r[mSize-2] + add %%T2, qword [%%rDst+sizeof(qword)*2] + adc %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T0, rdx + mov qword [%%rDst+sizeof(qword)*2], %%T2 + adc %%T1, 0 + + mul %%U1 ; {T1:T0} += a[mSize-1]*U1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T3, qword [%%rDst+sizeof(qword)*3] + adc %%T0, rax + mov qword [%%rDst+sizeof(qword)*3], %%T3 + adc %%T1, rdx + xor rax, rax + + add %%T0, qword [%%rDst+sizeof(qword)*4] + adc %%T1, qword [%%rDst+sizeof(qword)*5] + adc rax, 0 + add %%T0, qword [rsp+carry] + adc %%T1, 0 + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*4], %%T0 + mov qword [%%rDst+sizeof(qword)*5], %%T1 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%endif + +%if (_IPP32E >= _IPP32E_E9) +;; +;; Sandy Brige specific code +;; +%macro MM_MLAx2_4N_1_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += modulus[mSize-1]*U1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T0, qword [%%rDst+sizeof(qword)*3] + mov qword [%%rDst+sizeof(qword)*3], %%T0 + adc %%T1, rax + adc %%T2, rdx + xor rax, rax + + add %%T1, qword [%%rDst+sizeof(qword)*4] + adc %%T2, qword [%%rDst+sizeof(qword)*5] + adc rax, 0 + add %%T1, qword [rsp+carry] + adc %%T2, 0 + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*4], %%T1 + mov qword [%%rDst+sizeof(qword)*5], %%T2 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%macro MM_MLAx2_4N_2_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += a[mSize-2]*U1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T2, rdx + + mul %%U0 ; {T3:T2:T1} += a[mSize-1]*U0 + r[mSize-2] + add %%T0, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T0 + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T2, rdx + adc %%T3, 0 + + mul %%U1 ; {T3:T2} += a[mSize-1]*B1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T1, qword [%%rDst+sizeof(qword)*3] + mov qword [%%rDst+sizeof(qword)*3], %%T1 + adc %%T2, rax + adc %%T3, rdx + xor rax, rax + + add %%T2, qword [%%rDst+sizeof(qword)*4] + adc %%T3, qword [%%rDst+sizeof(qword)*5] + adc rax, 0 + add %%T2, qword [rsp+carry] + adc %%T3, 0 + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*4], %%T2 + mov qword [%%rDst+sizeof(qword)*5], %%T3 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%macro MM_MLAx2_4N_3_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += a[mSize-3]*U1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[mSize-2] + adc %%T2, rdx + + mul %%U0 ; {T3:T2:T1} += a[mSize-2]*U0 + r[mSize-3] + add %%T0, qword [%%rDst+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T0 + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[mSize-2] + adc %%T2, rdx + adc %%T3, 0 + + mul %%U1 ; {T3:T2} += a[mSize-2]*U1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T3, rdx + + mul %%U0 ; {T0:T3:T2} += a[mSize-1]*U0 + r[mSize-2] + add %%T1, qword [rdi+sizeof(qword)*2] + mov qword [rdi+sizeof(qword)*2], %%T1 + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T3, rdx + adc %%T0, 0 + + mul %%U1 ; {T0:T3} += a[mSize-1]*U1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T2, qword [rdi+sizeof(qword)*3] + mov qword [rdi+sizeof(qword)*3], %%T2 + adc %%T3, rax + adc %%T0, rdx + xor rax, rax + + add %%T3, qword [rdi+sizeof(qword)*4] + adc %%T0, qword [rdi+sizeof(qword)*5] + adc rax, 0 + add %%T3, qword [rsp+carry] + adc %%T0, 0 + adc rax, 0 + mov qword [rdi+sizeof(qword)*4], %%T3 + mov qword [rdi+sizeof(qword)*5], %%T0 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%macro MM_MLAx2_4N_4_ELOG 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc %2 + %xdefine %%idx %3 + %xdefine %%U0 %4 + %xdefine %%U1 %5 + %xdefine %%T0 %6 + %xdefine %%T1 %7 + %xdefine %%T2 %8 + %xdefine %%T3 %9 + + mul %%U1 ; {T2:T1} += a[mSize-4]*U1 + xor %%T3, %%T3 + add %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[lenA-3] + adc %%T2, rdx + + mul %%U0 ; {T3:T2:T1} += a[mSize-3]*U0 + r[mSize-4] + add %%T0, qword [%%rDst] + mov qword [%%rDst], %%T0 + adc %%T1, rax + mov rax, qword [%%rSrc+sizeof(qword)] ; a[mSize-3] + adc %%T2, rdx + adc %%T3, 0 + + mul %%U1 ; {T3:T2} += a[mSize-3]*U1 + xor %%T0, %%T0 + add %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a[mSize-2] + adc %%T3, rdx + + mul %%U0 ; {T0:T3:T2} += a[mSize-2]*U0 + r[mSize-3] + add %%T1, qword [%%rDst+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T1 + adc %%T2, rax + mov rax, qword [%%rSrc+sizeof(qword)*2] ; a{lenA-2] + adc %%T3, rdx + adc %%T0, 0 + + mul %%U1 ; {T0:T3} += a[mSize-2]*U1 + xor %%T1, %%T1 + add %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T0, rdx + + mul %%U0 ; {T1:T0:T3} += a[mSize-1]*U0 + r[mSize-2] + add %%T2, qword [%%rDst+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T2 + adc %%T3, rax + mov rax, qword [%%rSrc+sizeof(qword)*3] ; a[mSize-1] + adc %%T0, rdx + adc %%T1, 0 + + mul %%U1 ; {T1:T0} += a[mSize-1]*U1 + r[mSize-1] + mov %%idx, qword [rsp+counter] + add %%T3, qword [%%rDst+sizeof(qword)*3] + mov qword [%%rDst+sizeof(qword)*3], %%T3 + adc %%T0, rax + adc %%T1, rdx + xor rax, rax + + add %%T0, qword [%%rDst+sizeof(qword)*4] + adc %%T1, qword [%%rDst+sizeof(qword)*5] + adc rax, 0 + add %%T0, qword [rsp+carry] + adc %%T1, 0 + adc rax, 0 + mov qword [%%rDst+sizeof(qword)*4], %%T0 + mov qword [%%rDst+sizeof(qword)*5], %%T1 + mov qword [rsp+carry], rax + + add %%rDst, sizeof(qword)*2 +%endmacro + +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro SBB_x4 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc1 %2 + %xdefine %%rSrc2 %3 + %xdefine %%idx %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + %xdefine %%rcf %9 + + ALIGN IPP_ALIGN_FACTOR +%%L_1: + add %%rcf, %%rcf ; restore cf + + mov %%T0, qword [%%rSrc1+%%idx*sizeof(qword)] + sbb %%T0, qword [%%rSrc2+%%idx*sizeof(qword)] + mov qword [%%rDst+%%idx*sizeof(qword)], %%T0 + + mov %%T1, qword [%%rSrc1+%%idx*sizeof(qword)+sizeof(qword)] + sbb %%T1, qword [%%rSrc2+%%idx*sizeof(qword)+sizeof(qword)] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T1 + + mov %%T2, qword [%%rSrc1+%%idx*sizeof(qword)+sizeof(qword)*2] + sbb %%T2, qword [%%rSrc2+%%idx*sizeof(qword)+sizeof(qword)*2] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T2 + + mov %%T3, qword [%%rSrc1+%%idx*sizeof(qword)+sizeof(qword)*3] + sbb %%T3, qword [%%rSrc2+%%idx*sizeof(qword)+sizeof(qword)*3] + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3], %%T3 + + sbb %%rcf, %%rcf ; save cf + add %%idx, 4 + jnc %%L_1 +%endmacro + +%macro SBB_TAIL 9.nolist + %xdefine %%N %1 + %xdefine %%rDst %2 + %xdefine %%rSrc1 %3 + %xdefine %%rSrc2 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + %xdefine %%rcf %9 + + add %%rcf, %%rcf ; restore cf + mov idx, qword [rsp+counter] ; restore counter + +%if %%N > 3 + mov %%T0, qword [%%rSrc1] + sbb %%T0, qword [%%rSrc2] + mov qword [%%rDst], %%T0 +%endif + +%if %%N > 2 + mov %%T1, qword [%%rSrc1+sizeof(qword)] + sbb %%T1, qword [%%rSrc2+sizeof(qword)] + mov qword [%%rDst+sizeof(qword)], %%T1 +%endif + +%if %%N > 1 + mov %%T2, qword [%%rSrc1+sizeof(qword)*2] + sbb %%T2, qword [%%rSrc2+sizeof(qword)*2] + mov qword [%%rDst+sizeof(qword)*2], %%T2 +%endif + +%if %%N > 0 + mov %%T3, qword [%%rSrc1+sizeof(qword)*3] + sbb %%T3, qword [%%rSrc2+sizeof(qword)*3] + mov qword [%%rDst+sizeof(qword)*3], %%T3 +%endif + + sbb rax, 0 + sbb %%rcf, %%rcf ; set cf +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; dst[] = cf? src1[] : src2[] +%macro CMOV_x4 9.nolist + %xdefine %%rDst %1 + %xdefine %%rSrc1 %2 + %xdefine %%rSrc2 %3 + %xdefine %%idx %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + %xdefine %%rcf %9 + + mov %%T3, %%rcf ; copy cf + ALIGN IPP_ALIGN_FACTOR +%%L_1: + add %%T3, %%T3 ; restore cf + + mov %%T0, qword [%%rSrc2+%%idx*sizeof(qword)] + mov %%T1, qword [%%rSrc1+%%idx*sizeof(qword)] + mov %%T2, qword [%%rSrc2+%%idx*sizeof(qword)+sizeof(qword)] + mov %%T3, qword [%%rSrc1+%%idx*sizeof(qword)+sizeof(qword)] + cmovc %%T0, %%T1 + mov qword [%%rDst+%%idx*sizeof(qword)], %%T0 + cmovc %%T2, %%T3 + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)], %%T2 + + mov %%T0, qword [%%rSrc2+%%idx*sizeof(qword)+sizeof(qword)*2] + mov %%T1, qword [%%rSrc1+%%idx*sizeof(qword)+sizeof(qword)*2] + mov %%T2, qword [%%rSrc2+%%idx*sizeof(qword)+sizeof(qword)*3] + mov %%T3, qword [%%rSrc1+%%idx*sizeof(qword)+sizeof(qword)*3] + cmovc %%T0, %%T1 + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*2], %%T0 + cmovc %%T2, %%T3 + mov qword [%%rDst+%%idx*sizeof(qword)+sizeof(qword)*3], %%T2 + + mov %%T3, %%rcf ; copy cf + add %%idx, 4 + jnc %%L_1 +%endmacro + +%macro CMOV_TAIL 9.nolist + %xdefine %%N %1 + %xdefine %%rDst %2 + %xdefine %%rSrc1 %3 + %xdefine %%rSrc2 %4 + %xdefine %%T0 %5 + %xdefine %%T1 %6 + %xdefine %%T2 %7 + %xdefine %%T3 %8 + %xdefine %%rcf %9 + + add %%rcf, %%rcf ; restore cf + mov idx, qword [rsp+counter] ; restore counter + +%if %%N > 3 + mov %%T0, qword [%%rSrc2] + mov %%T1, qword [%%rSrc1] + cmovc %%T0, %%T1 + mov qword [%%rDst], %%T0 +%endif + +%if %%N > 2 + mov %%T2, qword [%%rSrc2+sizeof(qword)] + mov %%T3, qword [%%rSrc1+sizeof(qword)] + cmovc %%T2, %%T3 + mov qword [%%rDst+sizeof(qword)], %%T2 +%endif + +%if %%N > 1 + mov %%T0, qword [%%rSrc2+sizeof(qword)*2] + mov %%T1, qword [%%rSrc1+sizeof(qword)*2] + cmovc %%T0, %%T1 + mov qword [%%rDst+sizeof(qword)*2], %%T0 +%endif + +%if %%N > 0 + mov %%T2, qword [%%rSrc2+sizeof(qword)*3] + mov %%T3, qword [%%rSrc1+sizeof(qword)*3] + cmovc %%T2, %%T3 + mov qword [%%rDst+sizeof(qword)*3], %%T2 +%endif +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +;************************************************************* +;* void cpMontRedAdc_BNU(Ipp64u* pR, +;* Ipp64u* pBuffer, +;* const Ipp64u* pModulo, int mSize, Ipp64u m0) +;* +;************************************************************* + +;; +;; Lib = M7 +;; +;; Caller = ippsMontMul +;; +align IPP_ALIGN_FACTOR +IPPASM cpMontRedAdc_BNU,PUBLIC +%assign LOCAL_FRAME (1+1+1+1)*sizeof(qword) + USES_GPR rbx,rbp,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 5 + +;pR (rdi) address of the reduction +;pBuffer (rsi) address of the temporary product +;pModulo (rdx) address of the modulus +;mSize (rcx) size of the modulus +;m0 (r8) helper + +;; +;; stack structure: +%assign pR (0) ; reduction address +%assign mSize (pR+sizeof(qword)) ; modulus length (qwords) +%assign carry (mSize+sizeof(qword)) ; carry from previous MLAx1 or MLAx2 operation +%assign counter (carry+sizeof(qword)) ; counter = 4-mSize + + mov qword [rsp+carry], 0 ; clear carry + movsxd rcx, ecx ; expand modulus length + mov r15, r8 ; helper m0 + + cmp rcx, 5 + jge .general_case + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; reducer of the fixed sizes +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp rcx, 3 + ja .mSize_4 ; rcx=4 + jz .mSize_3 ; rcx=3 + jp .mSize_2 ; rcx=2 + ; mSize_1 ; rcx=1 + +%xdefine X0 r8 +%xdefine X1 r9 +%xdefine X2 r10 +%xdefine X3 r11 +%xdefine X4 r12 +%xdefine X5 r13 +%xdefine X6 r14 +%xdefine X7 rcx + +align IPP_ALIGN_FACTOR +.mSize_1: + mov X0, qword [rsi] + mov X1, qword [rsi+sizeof(qword)] + mov rsi, rdx + ; rDst,rSrc, U, M0, T0 + MREDUCE_FIX 1, rdi, rsi, r15, X7, X6, X5, X4, X3, X2, X1,X0, rbp,rbx + jmp .quit + +align IPP_ALIGN_FACTOR +.mSize_2: + mov X0, qword [rsi] + mov X1, qword [rsi+sizeof(qword)] + mov X2, qword [rsi+sizeof(qword)*2] + mov X3, qword [rsi+sizeof(qword)*3] + mov rsi, rdx + MREDUCE_FIX 2, rdi, rsi, r15, X7, X6, X5, X4, X3, X2, X1,X0, rbp,rbx + jmp .quit + +align IPP_ALIGN_FACTOR +.mSize_3: + mov X0, qword [rsi] + mov X1, qword [rsi+sizeof(qword)] + mov X2, qword [rsi+sizeof(qword)*2] + mov X3, qword [rsi+sizeof(qword)*3] + mov X4, qword [rsi+sizeof(qword)*4] + mov X5, qword [rsi+sizeof(qword)*5] + mov rsi, rdx + MREDUCE_FIX 3, rdi, rsi, r15, X7, X6, X5, X4, X3, X2, X1,X0, rbp,rbx + jmp .quit + +align IPP_ALIGN_FACTOR +.mSize_4: + mov X0, qword [rsi] + mov X1, qword [rsi+sizeof(qword)] + mov X2, qword [rsi+sizeof(qword)*2] + mov X3, qword [rsi+sizeof(qword)*3] + mov X4, qword [rsi+sizeof(qword)*4] + mov X5, qword [rsi+sizeof(qword)*5] + mov X6, qword [rsi+sizeof(qword)*6] + mov X7, qword [rsi+sizeof(qword)*7] + mov rsi, rdx + MREDUCE_FIX 4, rdi, rsi, r15, X7, X6, X5, X4, X3, X2, X1,X0, rbp,rbx + jmp .quit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; general case reducer +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%xdefine U0 r9 ; u0, u1 +%xdefine U1 r10 + +%xdefine T0 r11 ; temporary +%xdefine T1 r12 +%xdefine T2 r13 +%xdefine T3 r14 + +%xdefine idx rbx ; index +%xdefine rDst rdi +%xdefine rSrc rsi + +align IPP_ALIGN_FACTOR +.general_case: + lea rdi, [rdi+rcx*sizeof(qword)-sizeof(qword)*4] ; save pR+mSzie-4 + mov qword [rsp+pR], rdi ; save pR + ;mov qword [rsp+mSize], rcx ; save length of modulus + + mov rdi, rsi ; rdi = pBuffer + mov rsi, rdx ; rsi = pModulo + + lea rdi, [rdi+rcx*sizeof(qword)-sizeof(qword)*4] ; rdi = pBuffer + lea rsi, [rsi+rcx*sizeof(qword)-sizeof(qword)*4] ; rsi = pModulus + + mov idx, dword 4 ; init negative counter + sub idx, rcx + mov qword [rsp+counter], idx + mov rdx, dword 3 + and rdx, rcx + + test rcx,1 + jz .even_len_Modulus + +; +; modulus of odd length +; +.odd_len_Modulus: + mov U0, qword [rDst+idx*sizeof(qword)] ; pBuffer[0] + imul U0, r15 ; u0 = pBuffer[0]*m0 + + mov rax, qword [rSrc+idx*sizeof(qword)] ; pModulo[0] + + mul U0 ; prologue + mov T0, rax + mov rax, qword [rSrc+idx*sizeof(qword)+sizeof(qword)] + mov T1, rdx + + add idx, 1 + jz .skip_mlax1 + + MLAx1 rdi, rsi, idx, U0, T0,T1,T2,T3 ; pBuffer[] += pModulo[]*u + +.skip_mlax1: + mul U0 + xor T2, T2 + add qword [rDst+idx*sizeof(qword)-sizeof(qword)], T0 + adc T1, rax + adc T2, rdx + + cmp idx, 2 + ja .fin_mla1x4n_2 ; idx=3 + jz .fin_mla1x4n_3 ; idx=2 + jp .fin_mla1x4n_4 ; idx=1 + ; fin_mla1x4n_1 ; idx=0 + +.fin_mla1x4n_1: + MM_MLAx1_4N_1_ELOG rdi, rsi, idx, U0, T0,T1,T2,T3 ; [rsp+carry] = rax = cf = pBuffer[]+pModulo[]*u + sub rcx, 1 + jmp .mla2x4n_1 + +.fin_mla1x4n_4: + MM_MLAx1_4N_4_ELOG rdi, rsi, idx, U0, T0,T1,T2,T3 ; [rsp+carry] = rax = cf = pBuffer[]+pModulo[]*u + sub rcx, 1 + jmp .mla2x4n_4 + +.fin_mla1x4n_3: + MM_MLAx1_4N_3_ELOG rdi, rsi, idx, U0, T0,T1,T2,T3 ; [rsp+carry] = rax = cf = pBuffer[]+pModulo[]*u + sub rcx, 1 + jmp .mla2x4n_3 + +.fin_mla1x4n_2: + MM_MLAx1_4N_2_ELOG rdi, rsi, idx, U0, T0,T1,T2,T3 ; [rsp+carry] = rax = cf = pBuffer[]+pModulo[]*u + sub rcx, 1 + jmp .mla2x4n_2 + +align IPP_ALIGN_FACTOR +; +; modulus of even length +; +.even_len_Modulus: + xor rax, rax ; clear carry + cmp rdx, 2 + ja .mla2x4n_1 ; rdx=1 + jz .mla2x4n_2 ; rdx=2 + jp .mla2x4n_3 ; rdx=3 + ; mla2x4n_4 ; rdx=0 + +align IPP_ALIGN_FACTOR +.mla2x4n_4: + MMx2_PLOG rdi, rsi, idx, r15, U0,U1,T0,T1,T2,T3 ; pre-compute u0 and u1 + MLAx2 rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; rax = cf = product[]+modulo[]*{u1:u0} + MM_MLAx2_4N_4_ELOG rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; [rsp+carry] = rax = cf + sub rcx, 2 + jnz .mla2x4n_4 + + ; (borrow, pR) = (carry,product) - modulo + mov rdx, qword [rsp+pR] + xor rcx, rcx + SBB_x4 rdx, rdi, rsi, idx, T0,T1,T2,T3, rcx + SBB_TAIL 4, rdx, rdi, rsi, T0,T1,T2,T3, rcx + + ; pR = borrow? product : pR + CMOV_x4 rdx, rdi, rdx, idx, T0,T1,T2,T3, rcx + CMOV_TAIL 4, rdx, rdi, rdx, T0,T1,T2,T3, rcx + jmp .quit + +align IPP_ALIGN_FACTOR +.mla2x4n_3: + MMx2_PLOG rdi, rsi, idx, r15, U0,U1,T0,T1,T2,T3 ; pre-compute u0 and u1 + MLAx2 rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; rax = cf = product[]+modulo[]*{u1:u0} + MM_MLAx2_4N_3_ELOG rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; [rsp+carry] = rax = cf + sub rcx, 2 + jnz .mla2x4n_3 + + ; (borrow, pR) = (carry,product) - modulo + mov rdx, qword [rsp+pR] + xor rcx, rcx + SBB_x4 rdx, rdi, rsi, idx, T0,T1,T2,T3, rcx + SBB_TAIL 3, rdx, rdi, rsi, T0,T1,T2,T3, rcx + + ; pR = borrow? product : pR + CMOV_x4 rdx, rdi, rdx, idx, T0,T1,T2,T3, rcx + CMOV_TAIL 3, rdx, rdi, rdx, T0,T1,T2,T3, rcx + jmp .quit + +align IPP_ALIGN_FACTOR +.mla2x4n_2: + MMx2_PLOG rdi, rsi, idx, r15, U0,U1,T0,T1,T2,T3 ; pre-compute u0 and u1 + MLAx2 rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; rax = cf = product[]+modulo[]*{u1:u0} + MM_MLAx2_4N_2_ELOG rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; [rsp+carry] = rax = cf + sub rcx, 2 + jnz .mla2x4n_2 + + ; (borrow, pR) = (carry,product) - modulo + mov rdx, qword [rsp+pR] + xor rcx, rcx + SBB_x4 rdx, rdi, rsi, idx, T0,T1,T2,T3, rcx + SBB_TAIL 2, rdx, rdi, rsi, T0,T1,T2,T3, rcx + + ; pR = borrow? product : pR + CMOV_x4 rdx, rdi, rdx, idx, T0,T1,T2,T3, rcx + CMOV_TAIL 2, rdx, rdi, rdx, T0,T1,T2,T3, rcx + jmp .quit + + +align IPP_ALIGN_FACTOR +.mla2x4n_1: + MMx2_PLOG rdi, rsi, idx, r15, U0,U1,T0,T1,T2,T3 ; pre-compute u0 and u1 + MLAx2 rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; rax = cf = product[]+modulo[]*{u1:u0} + MM_MLAx2_4N_1_ELOG rdi, rsi, idx, U0,U1, T0,T1,T2,T3 ; [rsp+carry] = rax = cf + sub rcx, 2 + jnz .mla2x4n_1 + + ; (borrow, pR) = (carry,product) - modulo + mov rdx, qword [rsp+pR] + xor rcx, rcx + SBB_x4 rdx, rdi, rsi, idx, T0,T1,T2,T3, rcx + SBB_TAIL 1, rdx, rdi, rsi, T0,T1,T2,T3, rcx + + ; pR = borrow? product : pR + CMOV_x4 rdx, rdi, rdx, idx, T0,T1,T2,T3, rcx + CMOV_TAIL 1, rdx, rdi, rdx, T0,T1,T2,T3, rcx + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC cpMontRedAdc_BNU + +%endif + +%endif ;; _ADCOX_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontsqr1024_avx2as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontsqr1024_avx2as.asm new file mode 100644 index 000000000..cf5f2f6f8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontsqr1024_avx2as.asm @@ -0,0 +1,895 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpMontSqr1024_avx2() +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_L9) + +segment .text align=IPP_ALIGN_FACTOR + + +%assign DIGIT_BITS 27 +%assign DIGIT_MASK (1 << DIGIT_BITS) -1 + +;************************************************************* +;* void cpMontSqr1024_avx2(Ipp64u* pR, +;* const Ipp64u* pA, +;* const Ipp64u* pModulus, int mSize, +;* Ipp64u k0, +;* Ipp64u* pBuffer) +;************************************************************* + +align IPP_ALIGN_FACTOR +IPPASM cpMontSqr1024_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*7 + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14 + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13,ymm14 + COMP_ABI 6 + + movsxd rcx, ecx ; redLen value counter + vpxor ymm11, ymm11, ymm11 + +;; expands A and M operands + vmovdqu ymmword [rsi+rcx*sizeof(qword)], ymm11 + vmovdqu ymmword [rdx+rcx*sizeof(qword)], ymm11 + +; +; stack struct +; +%assign pResult 0 ; pointer to result +%assign pA pResult+sizeof(qword) ; pointer to A operand +%assign pM pA+sizeof(qword) ; pointer to modulus +%assign redLen pM+sizeof(qword) ; length +%assign m0 redLen+sizeof(qword) ; m0 value +%assign pA2 m0+sizeof(qword) ; pointer to buffer (contains doubled input (A*2) and temporary result (A^2) ) +%assign pAxA pA2+sizeof(qword) ; pointer to temporary result (A^2) + + mov qword [rsp+pResult], rdi ; store pointer to result + mov qword [rsp+pA], rsi ; store pointer to input A + mov qword [rsp+pM], rdx ; store pointer to modulus + mov qword [rsp+redLen], rcx ; store redLen + mov qword [rsp+m0], r8 ; store m0 value + + mov rcx, dword 40 + + mov rdi, r9 + mov qword [rsp+pAxA], rdi ; pointer to temporary result (low A^2) + lea rbx, [rdi+rcx*sizeof(qword)] ; pointer to temporary result (high A^2) + lea r9, [rbx+rcx*sizeof(qword)] ; pointer to doubled input (A*2) + mov qword [rsp+pA2], r9 + + mov rax, rsi + mov rcx, dword sizeof(ymmword)/sizeof(qword) + +;; doubling input + vmovdqu ymm0, ymmword [rsi] + vmovdqu ymm1, ymmword [rsi+sizeof(ymmword)] + vmovdqu ymm2, ymmword [rsi+sizeof(ymmword)*2] + vmovdqu ymm3, ymmword [rsi+sizeof(ymmword)*3] + vmovdqu ymm4, ymmword [rsi+sizeof(ymmword)*4] + vmovdqu ymm5, ymmword [rsi+sizeof(ymmword)*5] + vmovdqu ymm6, ymmword [rsi+sizeof(ymmword)*6] + vmovdqu ymm7, ymmword [rsi+sizeof(ymmword)*7] + vmovdqu ymm8, ymmword [rsi+sizeof(ymmword)*8] + vmovdqu ymm9, ymmword [rsi+sizeof(ymmword)*9] + + vmovdqu ymmword [r9], ymm0 + vpbroadcastq ymm10, qword [rax] ; ymm10 = {a0:a0:a0:a0} + vpaddq ymm1, ymm1, ymm1 + vmovdqu ymmword [r9+sizeof(ymmword)], ymm1 + vpaddq ymm2, ymm2, ymm2 + vmovdqu ymmword [r9+sizeof(ymmword)*2], ymm2 + vpaddq ymm3, ymm3, ymm3 + vmovdqu ymmword [r9+sizeof(ymmword)*3], ymm3 + vpaddq ymm4, ymm4, ymm4 + vmovdqu ymmword [r9+sizeof(ymmword)*4], ymm4 + vpaddq ymm5, ymm5, ymm5 + vmovdqu ymmword [r9+sizeof(ymmword)*5], ymm5 + vpaddq ymm6, ymm6, ymm6 + vmovdqu ymmword [r9+sizeof(ymmword)*6], ymm6 + vpaddq ymm7, ymm7, ymm7 + vmovdqu ymmword [r9+sizeof(ymmword)*7], ymm7 + vpaddq ymm8, ymm8, ymm8 + vmovdqu ymmword [r9+sizeof(ymmword)*8], ymm8 + vpaddq ymm9, ymm9, ymm9 + vmovdqu ymmword [r9+sizeof(ymmword)*9], ymm9 + +;; +;; squaring +;; + vpmuludq ymm0, ymm10, ymmword [rsi] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*4] ; ymm14 = {a4:a4:a4:a4} + vmovdqu ymmword [rbx], ymm11 + vpmuludq ymm1, ymm10, ymmword [r9+sizeof(ymmword)] + vmovdqu ymmword [rbx+sizeof(ymmword)], ymm11 + vpmuludq ymm2, ymm10, ymmword [r9+sizeof(ymmword)*2] + vmovdqu ymmword [rbx+sizeof(ymmword)*2], ymm11 + vpmuludq ymm3, ymm10, ymmword [r9+sizeof(ymmword)*3] + vmovdqu ymmword [rbx+sizeof(ymmword)*3], ymm11 + vpmuludq ymm4, ymm10, ymmword [r9+sizeof(ymmword)*4] + vmovdqu ymmword [rbx+sizeof(ymmword)*4], ymm11 + vpmuludq ymm5, ymm10, ymmword [r9+sizeof(ymmword)*5] + vmovdqu ymmword [rbx+sizeof(ymmword)*5], ymm11 + vpmuludq ymm6, ymm10, ymmword [r9+sizeof(ymmword)*6] + vmovdqu ymmword [rbx+sizeof(ymmword)*6], ymm11 + vpmuludq ymm7, ymm10, ymmword [r9+sizeof(ymmword)*7] + vmovdqu ymmword [rbx+sizeof(ymmword)*7], ymm11 + vpmuludq ymm8, ymm10, ymmword [r9+sizeof(ymmword)*8] + vmovdqu ymmword [rbx+sizeof(ymmword)*8], ymm11 + vpmuludq ymm9, ymm10, ymmword [r9+sizeof(ymmword)*9] + vmovdqu ymmword [rbx+sizeof(ymmword)*9], ymm11 + + jmp .sqr1024_ep + +align IPP_ALIGN_FACTOR +.sqr1024_loop4: + vpmuludq ymm0, ymm10, ymmword [rsi] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*4] ; ymm14 = {a4:a4:a4:a4} + vpaddq ymm0, ymm0, ymmword [rdi] + + vpmuludq ymm1, ymm10, ymmword [r9+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymmword [rdi+sizeof(ymmword)] + + vpmuludq ymm2, ymm10, ymmword [r9+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymmword [rdi+sizeof(ymmword)*2] + + vpmuludq ymm3, ymm10, ymmword [r9+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymmword [rdi+sizeof(ymmword)*3] + + vpmuludq ymm4, ymm10, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm4, ymm4, ymmword [rdi+sizeof(ymmword)*4] + + vpmuludq ymm5, ymm10, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm5, ymm5, ymmword [rdi+sizeof(ymmword)*5] + + vpmuludq ymm6, ymm10, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm6, ymm6, ymmword [rdi+sizeof(ymmword)*6] + + vpmuludq ymm7, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm7, ymm7, ymmword [rdi+sizeof(ymmword)*7] + + vpmuludq ymm8, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm8, ymm8, ymmword [rdi+sizeof(ymmword)*8] + + vpmuludq ymm9, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm9, ymm9, ymmword [rdi+sizeof(ymmword)*9] + +.sqr1024_ep: + vmovdqu ymmword [rdi], ymm0 + vmovdqu ymmword [rdi+sizeof(ymmword)], ymm1 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*8] ; ymm10 = {a8:a8:a8:a8} + vpaddq ymm2, ymm2, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*2] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*3] + vpaddq ymm4, ymm4, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm5, ymm5, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm6, ymm6, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm7, ymm7, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm8, ymm8, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm9, ymm9, ymm12 + vpmuludq ymm0, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm0, ymm0, ymmword [rbx] + + vmovdqu ymmword [rdi+sizeof(ymmword)*2], ymm2 + vmovdqu ymmword [rdi+sizeof(ymmword)*3], ymm3 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*2] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*12] ; ymm14 = {a12:a12:a12:a12} + vpaddq ymm4, ymm4, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*3] + vpaddq ymm5, ymm5, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm6, ymm6, ymm13 + vpmuludq ymm11, ymm10, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm7, ymm7, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm8, ymm8, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm9, ymm9, ymm13 + vpmuludq ymm11, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm0, ymm0, ymm11 + vpmuludq ymm1, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm1, ymm1, ymmword [rbx+sizeof(ymmword)] + + vmovdqu ymmword [rdi+sizeof(ymmword)*4], ymm4 + vmovdqu ymmword [rdi+sizeof(ymmword)*5], ymm5 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)*3] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*16] ; ymm10 = {a16:a16:a16:a16} + vpaddq ymm6, ymm6, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm9, ymm9, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm2, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm2, ymm2, ymmword [rbx+sizeof(ymmword)*2] + + vmovdqu ymmword [rdi+sizeof(ymmword)*6], ymm6 + vmovdqu ymmword [rdi+sizeof(ymmword)*7], ymm7 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*4] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*20] ; ymm14 = {a20:a20:a20:a20} + vpaddq ymm8, ymm8, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm9, ymm9, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm11, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm1, ymm1, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm3, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm3, ymm3, ymmword [rbx+sizeof(ymmword)*3] + + vmovdqu ymmword [rdi+sizeof(ymmword)*8], ymm8 + vmovdqu ymmword [rdi+sizeof(ymmword)*9], ymm9 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)*5] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*24] ; ymm10 = {a24:a24:a24:a24} + vpaddq ymm0, ymm0, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm3, ymm3, ymm11 + vpmuludq ymm4, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm4, ymm4, ymmword [rbx+sizeof(ymmword)*4] + + vmovdqu ymmword [rdi+sizeof(ymmword)*10], ymm0 + vmovdqu ymmword [rdi+sizeof(ymmword)*11], ymm1 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*6] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*28] ; ymm14 = {a28:a28:a28:a28} + vpaddq ymm2, ymm2, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm4, ymm4, ymm13 + vpmuludq ymm5, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm5, ymm5, ymmword [rbx+sizeof(ymmword)*5] + + vmovdqu ymmword [rdi+sizeof(ymmword)*12], ymm2 + vmovdqu ymmword [rdi+sizeof(ymmword)*13], ymm3 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)*7] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*32] ; ymm10 = {a32:a32:a32:a32} + vpaddq ymm4, ymm4, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm5, ymm5, ymm12 + vpmuludq ymm6, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm6, ymm6, ymmword [rbx+sizeof(ymmword)*6] + + vmovdqu ymmword [rdi+sizeof(ymmword)*14], ymm4 + vmovdqu ymmword [rdi+sizeof(ymmword)*15], ymm5 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*8] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*36] ; ymm14 = {a36:a36:a36:a36} + vpaddq ymm6, ymm6, ymm11 + vpmuludq ymm7, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm7, ymm7, ymmword [rbx+sizeof(ymmword)*7] + + vpmuludq ymm8, ymm14, ymmword [rsi+sizeof(ymmword)*9] + vpbroadcastq ymm10, qword [rax+sizeof(qword)] ; ymm10 = {a[1/2/3]:a[1/2/3]:a[1/2/3]:a[1/2/3]} + vpaddq ymm8, ymm8, ymmword [rbx+sizeof(ymmword)*8] + + vmovdqu ymmword [rdi+sizeof(ymmword)*16], ymm6 + vmovdqu ymmword [rdi+sizeof(ymmword)*17], ymm7 + vmovdqu ymmword [rdi+sizeof(ymmword)*18], ymm8 + + add rdi, sizeof(qword) + add rbx, sizeof(qword) + add rax, sizeof(qword) + sub rcx, 1 + jnz .sqr1024_loop4 + +;; +;; reduction +;; + mov rdi, qword [rsp+pAxA] ; restore pointer to temporary result (low A^2) + mov rcx, qword [rsp+pM] ; restore pointer to modulus + mov r8, qword [rsp+m0] ; restore m0 value + mov r9, dword 38 ; modulus length + + mov r10, qword [rdi] ; load low part of temporary result + mov r11, qword [rdi+sizeof(qword)] ; + mov r12, qword [rdi+sizeof(qword)*2] ; + mov r13, qword [rdi+sizeof(qword)*3] ; + + mov rdx, r10 ; y0 = (ac0*k0) & DIGIT_MASK + imul edx, r8d + and edx, DIGIT_MASK + vmovd xmm10, edx + + vmovdqu ymm1, ymmword [rdi+sizeof(ymmword)*1] ; load other data + vmovdqu ymm2, ymmword [rdi+sizeof(ymmword)*2] ; + vmovdqu ymm3, ymmword [rdi+sizeof(ymmword)*3] ; + vmovdqu ymm4, ymmword [rdi+sizeof(ymmword)*4] ; + vmovdqu ymm5, ymmword [rdi+sizeof(ymmword)*5] ; + vmovdqu ymm6, ymmword [rdi+sizeof(ymmword)*6] ; + + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + add r10, rax + + vpbroadcastq ymm10, xmm10 + + vmovdqu ymm7, ymmword [rdi+sizeof(ymmword)*7] ; load other data + vmovdqu ymm8, ymmword [rdi+sizeof(ymmword)*8] ; + vmovdqu ymm9, ymmword [rdi+sizeof(ymmword)*9] ; + + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + add r11, rax + + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + add r12, rax + + shr r10, DIGIT_BITS ; updtae ac1 + + imul rdx, qword [rcx+sizeof(qword)*3] ; ac3 += pn[3]*y0 + add r13, rdx + add r11, r10 ; updtae ac1 + + mov rdx, r11 ; y1 = (ac1*k0) & DIGIT_MASK + imul edx, r8d + and rdx, DIGIT_MASK + +align IPP_ALIGN_FACTOR +.reduction_loop: + vmovd xmm11, edx + vpbroadcastq ymm11, xmm11 + + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)] + mov rax, rdx ; ac1 += pn[0]*y1 + imul rax, qword [rcx] + vpaddq ymm1, ymm1, ymm14 + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymm14 + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymm14 + + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*4] + add r11, rax + shr r11, DIGIT_BITS ; update ac2 + vpaddq ymm4, ymm4, ymm14 + + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*5] + mov rax, rdx ; ac2 += pn[1]*y1 + imul rax, qword [rcx+sizeof(qword)] + vpaddq ymm5, ymm5, ymm14 + add r12, rax + + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*6] + imul rdx, qword [rcx+sizeof(qword)*2] ; ac3 += pn[2]*y1 + add r12, r11 + vpaddq ymm6, ymm6, ymm14 + add r13, rdx + + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*7] + mov rdx, r12 ; y2 = (ac2*m0) & DIGIT_MASK + imul edx, r8d + vpaddq ymm7, ymm7, ymm14 + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*8] + vpaddq ymm8, ymm8, ymm14 + and rdx, DIGIT_MASK + + vpmuludq ymm14, ymm10, ymmword [rcx+sizeof(ymmword)*9] + vpaddq ymm9, ymm9, ymm14 +;; ------------------------------------------------------------ + + vmovd xmm12, edx + vpbroadcastq ymm12, xmm12 + + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)-sizeof(qword)] + mov rax, rdx ; ac2 += pn[0]*y2 + imul rax, qword [rcx] + vpaddq ymm1, ymm1, ymm14 + + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*2-sizeof(qword)] + vpaddq ymm2, ymm2, ymm14 + + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*3-sizeof(qword)] + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*4-sizeof(qword)] + vpaddq ymm4, ymm4, ymm14 + add rax, r12 + shr rax, DIGIT_BITS ; update ac3 + + + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*5-sizeof(qword)] + imul rdx, qword [rcx+sizeof(qword)] ; ac3 += pn[1]*y2 + vpaddq ymm5, ymm5, ymm14 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*6-sizeof(qword)] + vpaddq ymm6, ymm6, ymm14 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*7-sizeof(qword)] + vpaddq ymm7, ymm7, ymm14 + add rdx, r13 + add rdx, rax ; update ac3 + + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*8-sizeof(qword)] + vpaddq ymm8, ymm8, ymm14 + vpmuludq ymm14, ymm11, ymmword [rcx+sizeof(ymmword)*9-sizeof(qword)] + vpaddq ymm9, ymm9, ymm14 + + sub r9, 2 + jz .exit_reduction_loop +;; ------------------------------------------------------------ + + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)-sizeof(qword)*2] + mov r13, rdx ; y3 = (ac3*m0) & DIGIT_MASK + imul edx, r8d + vpaddq ymm1, ymm1, ymm14 + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*2-sizeof(qword)*2] + vpaddq ymm2, ymm2, ymm14 + and rdx, DIGIT_MASK + + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*3-sizeof(qword)*2] + vmovd xmm13, edx + vpaddq ymm3, ymm3, ymm14 + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*4-sizeof(qword)*2] + vpbroadcastq ymm13, xmm13 + vpaddq ymm4, ymm4, ymm14 + + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*5-sizeof(qword)*2] + imul rdx, qword [rcx] ; ac3 += pn[0]*y3 + vpaddq ymm5, ymm5, ymm14 + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*6-sizeof(qword)*2] + vpaddq ymm6, ymm6, ymm14 + add r13, rdx + + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*7-sizeof(qword)*2] + vpaddq ymm7, ymm7, ymm14 + shr r13, DIGIT_BITS + vmovq xmm0, r13 + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)-sizeof(qword)*3] + vpaddq ymm1, ymm1, ymm0 + vpaddq ymm1, ymm1, ymm14 + vmovdqu ymmword [rdi], ymm1 + + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*8-sizeof(qword)*2] + vpaddq ymm8, ymm8, ymm14 + + vpmuludq ymm14, ymm12, ymmword [rcx+sizeof(ymmword)*9-sizeof(qword)*2] + vpaddq ymm9, ymm9, ymm14 +;; ------------------------------------------------------------ + + vmovq rdx, xmm1 ; y0 = (ac0*k0) & DIGIT_MASK + imul edx, r8d + and edx, DIGIT_MASK + + vmovq r10, xmm1 ; update lowest part of temporary result + mov r11, qword [rdi+sizeof(qword)] ; + mov r12, qword [rdi+sizeof(qword)*2] ; + mov r13, qword [rdi+sizeof(qword)*3] ; + + vmovd xmm10, edx + vpbroadcastq ymm10, xmm10 + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*2-sizeof(qword)*3] + mov rax, rdx ; ac0 += pn[0]*y0 + imul rax, qword [rcx] + vpaddq ymm1, ymm2, ymm14 + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*3-sizeof(qword)*3] + add r10, rax + vpaddq ymm2, ymm3, ymm14 + shr r10, DIGIT_BITS ; updtae ac1 + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*4-sizeof(qword)*3] + mov rax, rdx ; ac1 += pn[1]*y0 + imul rax, qword [rcx+sizeof(qword)] + vpaddq ymm3, ymm4, ymm14 + add r11, rax + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*5-sizeof(qword)*3] + mov rax, rdx ; ac2 += pn[2]*y0 + imul rax, qword [rcx+sizeof(qword)*2] + vpaddq ymm4, ymm5, ymm14 + add r12, rax + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*6-sizeof(qword)*3] + imul rdx, qword [rcx+sizeof(qword)*3] ; ac3 += pn[3]*y0 + vpaddq ymm5, ymm6, ymm14 + add r13, rdx + add r11, r10 + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*7-sizeof(qword)*3] + mov rdx, r11 ; y1 = (ac1*k0) & DIGIT_MASK + imul edx, r8d + vpaddq ymm6, ymm7, ymm14 + and rdx, DIGIT_MASK + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*8-sizeof(qword)*3] + vpaddq ymm7, ymm8, ymm14 + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*9-sizeof(qword)*3] + vpaddq ymm8, ymm9, ymm14 + + vpmuludq ymm14, ymm13, ymmword [rcx+sizeof(ymmword)*10-sizeof(qword)*3] + vpaddq ymm9, ymm14, ymmword [rdi+sizeof(ymmword)*10] + + add rdi, sizeof(qword)*4 + sub r9, 2 + jnz .reduction_loop + +.exit_reduction_loop: + mov rdi, qword [rsp+pResult] ; restore pointer to result + mov qword [rdi], r12 + mov qword [rdi+sizeof(qword)], r13 + vmovdqu ymmword [rdi+sizeof(ymmword)-sizeof(qword)*2], ymm1 + vmovdqu ymmword [rdi+sizeof(ymmword)*2-sizeof(qword)*2], ymm2 + vmovdqu ymmword [rdi+sizeof(ymmword)*3-sizeof(qword)*2], ymm3 + vmovdqu ymmword [rdi+sizeof(ymmword)*4-sizeof(qword)*2], ymm4 + vmovdqu ymmword [rdi+sizeof(ymmword)*5-sizeof(qword)*2], ymm5 + vmovdqu ymmword [rdi+sizeof(ymmword)*6-sizeof(qword)*2], ymm6 + vmovdqu ymmword [rdi+sizeof(ymmword)*7-sizeof(qword)*2], ymm7 + vmovdqu ymmword [rdi+sizeof(ymmword)*8-sizeof(qword)*2], ymm8 + vmovdqu ymmword [rdi+sizeof(ymmword)*9-sizeof(qword)*2], ymm9 + +;; +;; normalization +;; + mov r9, dword 38 + xor rax, rax +.norm_loop: + add rax, qword [rdi] + add rdi, sizeof(qword) + mov rdx, dword DIGIT_MASK + and rdx, rax + shr rax, DIGIT_BITS + mov qword [rdi-sizeof(qword)], rdx + sub r9, 1 + jg .norm_loop + mov qword [rdi], rax + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC cpMontSqr1024_avx2 + +;************************************************************* +;* void cpSqr1024_avx2(Ipp64u* pR, +;* const Ipp64u* pA, int nsA, +;* Ipp64u* pBuffer) +;************************************************************* + +align IPP_ALIGN_FACTOR +IPPASM cpSqr1024_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*5 + USES_GPR rsi,rdi,rbx + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13,ymm14 + COMP_ABI 4 + + movsxd rdx, edx ; redLen value counter + vpxor ymm11, ymm11, ymm11 + +;; expands A operand + vmovdqu ymmword [rsi+rdx*sizeof(qword)], ymm11 + +; +; stack struct +; +%assign pResult 0 ; pointer to result +%assign pA pResult+sizeof(qword) ; pointer to A operand +%assign redLen pA+sizeof(qword) ; length +%assign pA2 redLen+sizeof(qword) ; pointer to buffer (contains doubled input (A*2) and temporary result (A^2) ) +%assign pAxA pA2+sizeof(qword) ; pointer to temporary result (A^2) + + mov qword [rsp+pResult], rdi ; store pointer to result + mov qword [rsp+pA], rsi ; store pointer to input A + mov qword [rsp+redLen], rdx ; store redLen + + mov rdx, dword 40 + + mov rdi, rcx ; pointer to buffer + mov qword [rsp+pAxA], rdi ; pointer to temporary result (low A^2) + lea rbx, [rdi+rdx*sizeof(qword)] ; pointer to temporary result (high A^2) + lea r9, [rbx+rdx*sizeof(qword)] ; pointer to doubled input (A*2) + mov qword [rsp+pA2], r9 + + mov rax, rsi + mov rcx, dword sizeof(ymmword)/sizeof(qword) + +;; doubling input + vmovdqu ymm0, ymmword [rsi] + vmovdqu ymm1, ymmword [rsi+sizeof(ymmword)] + vmovdqu ymm2, ymmword [rsi+sizeof(ymmword)*2] + vmovdqu ymm3, ymmword [rsi+sizeof(ymmword)*3] + vmovdqu ymm4, ymmword [rsi+sizeof(ymmword)*4] + vmovdqu ymm5, ymmword [rsi+sizeof(ymmword)*5] + vmovdqu ymm6, ymmword [rsi+sizeof(ymmword)*6] + vmovdqu ymm7, ymmword [rsi+sizeof(ymmword)*7] + vmovdqu ymm8, ymmword [rsi+sizeof(ymmword)*8] + vmovdqu ymm9, ymmword [rsi+sizeof(ymmword)*9] + + vmovdqu ymmword [r9], ymm0 + vpbroadcastq ymm10, qword [rax] ; ymm10 = {a0:a0:a0:a0} + vpaddq ymm1, ymm1, ymm1 + vmovdqu ymmword [r9+sizeof(ymmword)], ymm1 + vpaddq ymm2, ymm2, ymm2 + vmovdqu ymmword [r9+sizeof(ymmword)*2], ymm2 + vpaddq ymm3, ymm3, ymm3 + vmovdqu ymmword [r9+sizeof(ymmword)*3], ymm3 + vpaddq ymm4, ymm4, ymm4 + vmovdqu ymmword [r9+sizeof(ymmword)*4], ymm4 + vpaddq ymm5, ymm5, ymm5 + vmovdqu ymmword [r9+sizeof(ymmword)*5], ymm5 + vpaddq ymm6, ymm6, ymm6 + vmovdqu ymmword [r9+sizeof(ymmword)*6], ymm6 + vpaddq ymm7, ymm7, ymm7 + vmovdqu ymmword [r9+sizeof(ymmword)*7], ymm7 + vpaddq ymm8, ymm8, ymm8 + vmovdqu ymmword [r9+sizeof(ymmword)*8], ymm8 + vpaddq ymm9, ymm9, ymm9 + vmovdqu ymmword [r9+sizeof(ymmword)*9], ymm9 + +;; +;; squaring +;; + vpmuludq ymm0, ymm10, ymmword [rsi] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*4] ; ymm14 = {a4:a4:a4:a4} + vmovdqu ymmword [rbx], ymm11 + vpmuludq ymm1, ymm10, ymmword [r9+sizeof(ymmword)] + vmovdqu ymmword [rbx+sizeof(ymmword)], ymm11 + vpmuludq ymm2, ymm10, ymmword [r9+sizeof(ymmword)*2] + vmovdqu ymmword [rbx+sizeof(ymmword)*2], ymm11 + vpmuludq ymm3, ymm10, ymmword [r9+sizeof(ymmword)*3] + vmovdqu ymmword [rbx+sizeof(ymmword)*3], ymm11 + vpmuludq ymm4, ymm10, ymmword [r9+sizeof(ymmword)*4] + vmovdqu ymmword [rbx+sizeof(ymmword)*4], ymm11 + vpmuludq ymm5, ymm10, ymmword [r9+sizeof(ymmword)*5] + vmovdqu ymmword [rbx+sizeof(ymmword)*5], ymm11 + vpmuludq ymm6, ymm10, ymmword [r9+sizeof(ymmword)*6] + vmovdqu ymmword [rbx+sizeof(ymmword)*6], ymm11 + vpmuludq ymm7, ymm10, ymmword [r9+sizeof(ymmword)*7] + vmovdqu ymmword [rbx+sizeof(ymmword)*7], ymm11 + vpmuludq ymm8, ymm10, ymmword [r9+sizeof(ymmword)*8] + vmovdqu ymmword [rbx+sizeof(ymmword)*8], ymm11 + vpmuludq ymm9, ymm10, ymmword [r9+sizeof(ymmword)*9] + vmovdqu ymmword [rbx+sizeof(ymmword)*9], ymm11 + + jmp .sqr1024_ep + +align IPP_ALIGN_FACTOR +.sqr1024_loop4: + vpmuludq ymm0, ymm10, ymmword [rsi] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*4] ; ymm14 = {a4:a4:a4:a4} + vpaddq ymm0, ymm0, ymmword [rdi] + + vpmuludq ymm1, ymm10, ymmword [r9+sizeof(ymmword)] + vpaddq ymm1, ymm1, ymmword [rdi+sizeof(ymmword)] + + vpmuludq ymm2, ymm10, ymmword [r9+sizeof(ymmword)*2] + vpaddq ymm2, ymm2, ymmword [rdi+sizeof(ymmword)*2] + + vpmuludq ymm3, ymm10, ymmword [r9+sizeof(ymmword)*3] + vpaddq ymm3, ymm3, ymmword [rdi+sizeof(ymmword)*3] + + vpmuludq ymm4, ymm10, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm4, ymm4, ymmword [rdi+sizeof(ymmword)*4] + + vpmuludq ymm5, ymm10, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm5, ymm5, ymmword [rdi+sizeof(ymmword)*5] + + vpmuludq ymm6, ymm10, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm6, ymm6, ymmword [rdi+sizeof(ymmword)*6] + + vpmuludq ymm7, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm7, ymm7, ymmword [rdi+sizeof(ymmword)*7] + + vpmuludq ymm8, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm8, ymm8, ymmword [rdi+sizeof(ymmword)*8] + + vpmuludq ymm9, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm9, ymm9, ymmword [rdi+sizeof(ymmword)*9] + +.sqr1024_ep: + vmovdqu ymmword [rdi], ymm0 + vmovdqu ymmword [rdi+sizeof(ymmword)], ymm1 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*8] ; ymm10 = {a8:a8:a8:a8} + vpaddq ymm2, ymm2, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*2] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*3] + vpaddq ymm4, ymm4, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm5, ymm5, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm6, ymm6, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm7, ymm7, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm8, ymm8, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm9, ymm9, ymm12 + vpmuludq ymm0, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm0, ymm0, ymmword [rbx] + + vmovdqu ymmword [rdi+sizeof(ymmword)*2], ymm2 + vmovdqu ymmword [rdi+sizeof(ymmword)*3], ymm3 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*2] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*12] ; ymm14 = {a12:a12:a12:a12} + vpaddq ymm4, ymm4, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*3] + vpaddq ymm5, ymm5, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm6, ymm6, ymm13 + vpmuludq ymm11, ymm10, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm7, ymm7, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm8, ymm8, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm9, ymm9, ymm13 + vpmuludq ymm11, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm0, ymm0, ymm11 + vpmuludq ymm1, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm1, ymm1, ymmword [rbx+sizeof(ymmword)] + + vmovdqu ymmword [rdi+sizeof(ymmword)*4], ymm4 + vmovdqu ymmword [rdi+sizeof(ymmword)*5], ymm5 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)*3] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*16] ; ymm10 = {a16:a16:a16:a16} + vpaddq ymm6, ymm6, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*4] + vpaddq ymm7, ymm7, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm8, ymm8, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm9, ymm9, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm0, ymm0, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm1, ymm1, ymm13 + vpmuludq ymm2, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm2, ymm2, ymmword [rbx+sizeof(ymmword)*2] + + vmovdqu ymmword [rdi+sizeof(ymmword)*6], ymm6 + vmovdqu ymmword [rdi+sizeof(ymmword)*7], ymm7 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*4] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*20] ; ymm14 = {a20:a20:a20:a20} + vpaddq ymm8, ymm8, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*5] + vpaddq ymm9, ymm9, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm0, ymm0, ymm13 + vpmuludq ymm11, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm1, ymm1, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm2, ymm2, ymm12 + vpmuludq ymm3, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm3, ymm3, ymmword [rbx+sizeof(ymmword)*3] + + vmovdqu ymmword [rdi+sizeof(ymmword)*8], ymm8 + vmovdqu ymmword [rdi+sizeof(ymmword)*9], ymm9 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)*5] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*24] ; ymm10 = {a24:a24:a24:a24} + vpaddq ymm0, ymm0, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*6] + vpaddq ymm1, ymm1, ymm12 + vpmuludq ymm13, ymm14, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm2, ymm2, ymm13 + vpmuludq ymm11, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm3, ymm3, ymm11 + vpmuludq ymm4, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm4, ymm4, ymmword [rbx+sizeof(ymmword)*4] + + vmovdqu ymmword [rdi+sizeof(ymmword)*10], ymm0 + vmovdqu ymmword [rdi+sizeof(ymmword)*11], ymm1 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*6] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*28] ; ymm14 = {a28:a28:a28:a28} + vpaddq ymm2, ymm2, ymm11 + vpmuludq ymm12, ymm10, ymmword [r9+sizeof(ymmword)*7] + vpaddq ymm3, ymm3, ymm12 + vpmuludq ymm13, ymm10, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm4, ymm4, ymm13 + vpmuludq ymm5, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm5, ymm5, ymmword [rbx+sizeof(ymmword)*5] + + vmovdqu ymmword [rdi+sizeof(ymmword)*12], ymm2 + vmovdqu ymmword [rdi+sizeof(ymmword)*13], ymm3 + + vpmuludq ymm11, ymm14, ymmword [rsi+sizeof(ymmword)*7] + vpbroadcastq ymm10, qword [rax+sizeof(qword)*32] ; ymm10 = {a32:a32:a32:a32} + vpaddq ymm4, ymm4, ymm11 + vpmuludq ymm12, ymm14, ymmword [r9+sizeof(ymmword)*8] + vpaddq ymm5, ymm5, ymm12 + vpmuludq ymm6, ymm14, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm6, ymm6, ymmword [rbx+sizeof(ymmword)*6] + + vmovdqu ymmword [rdi+sizeof(ymmword)*14], ymm4 + vmovdqu ymmword [rdi+sizeof(ymmword)*15], ymm5 + + vpmuludq ymm11, ymm10, ymmword [rsi+sizeof(ymmword)*8] + vpbroadcastq ymm14, qword [rax+sizeof(qword)*36] ; ymm14 = {a36:a36:a36:a36} + vpaddq ymm6, ymm6, ymm11 + vpmuludq ymm7, ymm10, ymmword [r9+sizeof(ymmword)*9] + vpaddq ymm7, ymm7, ymmword [rbx+sizeof(ymmword)*7] + + vpmuludq ymm8, ymm14, ymmword [rsi+sizeof(ymmword)*9] + vpbroadcastq ymm10, qword [rax+sizeof(qword)] ; ymm10 = {a[1/2/3]:a[1/2/3]:a[1/2/3]:a[1/2/3]} + vpaddq ymm8, ymm8, ymmword [rbx+sizeof(ymmword)*8] + + vmovdqu ymmword [rdi+sizeof(ymmword)*16], ymm6 + vmovdqu ymmword [rdi+sizeof(ymmword)*17], ymm7 + vmovdqu ymmword [rdi+sizeof(ymmword)*18], ymm8 + + add rdi, sizeof(qword) + add rbx, sizeof(qword) + add rax, sizeof(qword) + sub rcx, 1 + jnz .sqr1024_loop4 + + +;; +;; normalization +;; + mov rsi, qword [rsp+pAxA] + mov rdi, qword [rsp+pResult] + mov r9, dword 38*2 + xor rax, rax +.norm_loop: + add rax, qword [rsi] + add rsi, sizeof(qword) + mov rdx, dword DIGIT_MASK + and rdx, rax + shr rax, DIGIT_BITS + mov qword [rdi], rdx + add rdi, sizeof(qword) + sub r9, 1 + jg .norm_loop + mov qword [rdi], rax + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC cpSqr1024_avx2 + +%endif ; _IPP32E_L9 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontsqr_avx2as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontsqr_avx2as.asm new file mode 100644 index 000000000..d825b60da --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmontsqr_avx2as.asm @@ -0,0 +1,802 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Big Number Operations +; +; Content: +; cpSqr_avx2() +; cpMontRed_avx2() +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_L9) + +segment .text align=IPP_ALIGN_FACTOR + + +%assign DIGIT_BITS 27 +%assign DIGIT_MASK (1 << DIGIT_BITS) -1 + +;************************************************************* +;* void cpSqr_avx2(Ipp64u* pR, +;* const Ipp64u* pA, int aSize, +;* Ipp64u* pBuffer) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM cpSqr_avx2,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*6 + USES_GPR rsi,rdi,rbx,rbp,r12,r13 + USES_XMM_AVX ymm6,ymm7,ymm8,ymm9,ymm10,ymm11,ymm12,ymm13,ymm14 + COMP_ABI 4 + + movsxd rdx, edx ; redLen value counter + vpxor ymm11, ymm11, ymm11 + +;; expands A + vmovdqu ymmword [rsi+rdx*sizeof(qword)], ymm11 ; size of buffer = redLen+4 + +; +; stack struct +; +%assign pResult 0 ; pointer to result +%assign pA pResult+sizeof(qword) ; pointer to A operand +%assign redLen pA+sizeof(qword) ; length +%assign len4 redLen+sizeof(qword) ; x4 length +%assign pA2 len4+sizeof(qword) ; pointer to buffer (contains doubled input (A*2) and temporary result (A^2) ) +%assign pAxA pA2+sizeof(qword) ; pointer to temporary result (A^2) + + lea rax, [rdx+3] ; len4 = ((redLen+3) &(-4))/4 + and rax, -4 ; multiple 4 length of operand (in ymmwords) + shr rax, 2 + + mov qword [rsp+pResult], rdi ; store pointer to result + mov qword [rsp+pA], rsi ; store pointer to input A + mov qword [rsp+redLen], rdx ; store redLen + mov qword [rsp+len4], rax ; store len4 + + mov rdi, rcx ; pointer to word buffer + shl rax, 2 + mov qword [rsp+pAxA], rdi ; pointer to temporary result (low A^2) + lea rbx, [rdi+rax*sizeof(qword)] ; pointer to temporary result (high A^2) + lea r9, [rbx+rax*sizeof(qword)] ; pointer to doubled input (A*2) + mov qword [rsp+pA2], r9 + +;; clear temporary result and double input +.clr_dbl_loop: + vmovdqu ymm0, ymmword [rsi] + vpaddq ymm0, ymm0, ymm0 + vmovdqu ymmword [rdi], ymm11 + vmovdqu ymmword [rbx], ymm11 + vmovdqu ymmword [r9], ymm0 + add rsi, sizeof(ymmword) + add rdi, sizeof(ymmword) + add rbx, sizeof(ymmword) + add r9, sizeof(ymmword) + sub rax, sizeof(ymmword)/sizeof(qword) + jg .clr_dbl_loop + +;; +;; squaring +;; + mov rsi, qword [rsp+pA] ; restore A + mov rdi, qword [rsp+pAxA] ; restore temp result buffer + mov r9, qword [rsp+pA2] ; restore temp double buffer + + mov rax, rsi ; tsrc = src + sizeof(qword)*n, n=0,1,2,3 + mov rcx, dword 4 +align IPP_ALIGN_FACTOR +.sqr_offset_loop: ; for(n=0; n<4; n++) + + mov r10, qword [rsp+len4] + mov r12, dword 3 + and r12, r10 ; init vflg = len4%4 + lea r11, [r10-(4*2-1)] ; init inner_loop counter (hcnt = len4 -7) + shr r10, 2 ; init outer_loop counter (vcnt = len4/4 -1) + sub r10, 1 ; + + push r9 ; (optr_d256) + push rsi ; (optr_s256) + push rdi ; (optr_r256) + push rax ; (optr_a256) + +align IPP_ALIGN_FACTOR +.sqr_outer_loop: ; for(i=0; i 1 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif +%if %%mSize > 2 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif +%if %%mSize > 3 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif +%if %%mSize > 4 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif +%if %%mSize > 5 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif +%if %%mSize > 6 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif +%if %%mSize > 7 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif + + xor %%TMP, %%TMP + add %%X0, qword [%%rProduct+sizeof(qword)*(%%mSize+0)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+0)], %%X0 +%if %%mSize > 1 + adc %%X1, qword [%%rProduct+sizeof(qword)*(%%mSize+1)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+1)], %%X1 +%endif +%if %%mSize > 2 + adc %%X2, qword [%%rProduct+sizeof(qword)*(%%mSize+2)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+2)], %%X2 +%endif +%if %%mSize > 3 + adc %%X3, qword [%%rProduct+sizeof(qword)*(%%mSize+3)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+3)], %%X3 +%endif +%if %%mSize > 4 + adc %%X4, qword [%%rProduct+sizeof(qword)*(%%mSize+4)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+4)], %%X4 +%endif +%if %%mSize > 5 + adc %%X5, qword [%%rProduct+sizeof(qword)*(%%mSize+5)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+5)], %%X5 +%endif +%if %%mSize > 6 + adc %%X6, qword [%%rProduct+sizeof(qword)*(%%mSize+6)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+6)], %%X6 +%endif +%if %%mSize > 7 + adc %%X7, qword [%%rProduct+sizeof(qword)*(%%mSize+7)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+7)], %%X7 +%endif + adc %%TMP, 0 + + sub %%X0, qword [%%rModulus+sizeof(qword)*0] +%if %%mSize > 1 + sbb %%X1, qword [%%rModulus+sizeof(qword)*1] +%endif +%if %%mSize > 2 + sbb %%X2, qword [%%rModulus+sizeof(qword)*2] +%endif +%if %%mSize > 3 + sbb %%X3, qword [%%rModulus+sizeof(qword)*3] +%endif +%if %%mSize > 4 + sbb %%X4, qword [%%rModulus+sizeof(qword)*4] +%endif +%if %%mSize > 5 + sbb %%X5, qword [%%rModulus+sizeof(qword)*5] +%endif +%if %%mSize > 6 + sbb %%X6, qword [%%rModulus+sizeof(qword)*6] +%endif +%if %%mSize > 7 + sbb %%X7, qword [%%rModulus+sizeof(qword)*7] +%endif + sbb %%TMP, 0 + + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+0)] + cmovae rax, %%X0 + mov qword [%%rRed+sizeof(qword)*0], rax +%if %%mSize > 1 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+1)] + cmovae rax, %%X1 + mov qword [%%rRed+sizeof(qword)*1], rax +%endif +%if %%mSize > 2 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+2)] + cmovae rax, %%X2 + mov qword [%%rRed+sizeof(qword)*2], rax +%endif +%if %%mSize > 3 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+3)] + cmovae rax, %%X3 + mov qword [%%rRed+sizeof(qword)*3], rax +%endif +%if %%mSize > 4 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+4)] + cmovae rax, %%X4 + mov qword [%%rRed+sizeof(qword)*4], rax +%endif +%if %%mSize > 5 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+5)] + cmovae rax, %%X5 + mov qword [%%rRed+sizeof(qword)*5], rax +%endif +%if %%mSize > 6 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+6)] + cmovae rax, %%X6 + mov qword [%%rRed+sizeof(qword)*6], rax +%endif +%if %%mSize > 7 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+7)] + cmovae rax, %%X7 + mov qword [%%rRed+sizeof(qword)*7], rax +%endif + +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sub_N,PRIVATE + xor rax, rax ; cf = 0 +.sub_next: + lea rdi, [rdi+sizeof(qword)] + mov r8, qword [rsi] + mov r9, qword [rcx] + lea rsi, [rsi+sizeof(qword)] + lea rcx, [rcx+sizeof(qword)] + sbb r8, r9 + mov qword [rdi-sizeof(qword)], r8 + dec rdx + jnz .sub_next + adc rax, 0 + ret +ENDFUNC sub_N + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC copy_ae_N,PRIVATE + lea rdi, [rdi+sizeof(qword)] + mov r8, qword [rsi] ; src1[] + mov r9, qword [rcx] ; src2[] + lea rsi, [rsi+sizeof(qword)] + lea rcx, [rcx+sizeof(qword)] + cmovae r8, r9 + mov qword [rdi-sizeof(qword)], r8 + dec rdx + jnz copy_ae_N + ret +ENDFUNC copy_ae_N + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; mredN_start procedures +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred1_start,PRIVATE + MLA_FIX 1,, rsi, rbx,rbp, r8 + ret +ENDFUNC mred1_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred2_start,PRIVATE + MLA_FIX 2,, rsi, rbx,rbp, r8,r9 + ret +ENDFUNC mred2_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred3_start,PRIVATE + MLA_FIX 3,, rsi, rbx,rbp, r8,r9,r10 + ret +ENDFUNC mred3_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred4_start,PRIVATE + MLA_FIX 4,, rsi, rbx,rbp, r8,r9,r10,r11 + ret +ENDFUNC mred4_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred5_start,PRIVATE + MLA_FIX 5,, rsi, rbx,rbp, r8,r9,r10,r11,r12 + ret +ENDFUNC mred5_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred6_start,PRIVATE + MLA_FIX 6,, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + ret +ENDFUNC mred6_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred7_start,PRIVATE + MLA_FIX 7,, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + ret +ENDFUNC mred7_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8_start,PRIVATE + MLA_FIX 8,, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mred8_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x1_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x1_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x2_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x2_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x3_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x3_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x4_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x4_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x5_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x5_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x6_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*5], rdx + call mred8_start + mov [rdi+sizeof(qword)*5], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x6_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x7_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*5], rdx + call mred8_start + mov [rdi+sizeof(qword)*5], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*6], rdx + call mred8_start + mov [rdi+sizeof(qword)*6], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x7_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x8_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*5], rdx + call mred8_start + mov [rdi+sizeof(qword)*5], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*6], rdx + call mred8_start + mov [rdi+sizeof(qword)*6], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*7], rdx + call mred8_start + mov [rdi+sizeof(qword)*7], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x8_start + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; rdi - temporary product buffer/temporary reduction +;; rsi - modulus +;; r8 - m' +;; r15 - target reduction address +;; + +;; +;; 1*qword modulus length +;; + +;; +;; 2*qword modulus length +;; + +;; +;; 3*qword modulus length +;; + +;; +;; 4*qword modulus length +;; + +;; +;; 5*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_5,PRIVATE +%assign MSIZE 5 + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + sbb rax, 0 + + ; copy under cf [r15] = cf? [r15] : {r8-r12} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + mov rbp, qword [rdi+sizeof(qword)*(MSIZE+4)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + cmovae rbp, r12 + mov qword [r15+sizeof(qword)*0], rax + mov qword [r15+sizeof(qword)*1], rbx + mov qword [r15+sizeof(qword)*2], rcx + mov qword [r15+sizeof(qword)*3], rdx + mov qword [r15+sizeof(qword)*4], rbp + ret +ENDFUNC mred_5 + + +;; +;; 6*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_6,PRIVATE +%assign MSIZE 6 + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE+5)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+5)], r13 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + op_reg_mem sbb, r13,[rsi+sizeof(qword)*5], rbx + sbb rax, 0 + + ; copy under cf [r15] = cf? [r15] : {r8-r13} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + mov rbp, qword [rdi+sizeof(qword)*(MSIZE+4)] + mov rsi, qword [rdi+sizeof(qword)*(MSIZE+5)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + cmovae rbp, r12 + cmovae rsi, r13 + mov qword [r15+sizeof(qword)*0], rax + mov qword [r15+sizeof(qword)*1], rbx + mov qword [r15+sizeof(qword)*2], rcx + mov qword [r15+sizeof(qword)*3], rdx + mov qword [r15+sizeof(qword)*4], rbp + mov qword [r15+sizeof(qword)*5], rsi + ret +ENDFUNC mred_6 + + +;; +;; 7*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_7,PRIVATE +%assign MSIZE 7 + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE+5)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+5)], r13 + op_reg_mem adc, r14,[rdi+sizeof(qword)*(MSIZE+6)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+6)], r14 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + op_reg_mem sbb, r13,[rsi+sizeof(qword)*5], rbx + op_reg_mem sbb, r14,[rsi+sizeof(qword)*6], rbx + sbb rax, 0 + + ; copy under cf [r15] = cf? [r15] : {r8-r14} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + mov rbp, qword [rdi+sizeof(qword)*(MSIZE+4)] + mov rsi, qword [rdi+sizeof(qword)*(MSIZE+5)] + mov rdi, qword [rdi+sizeof(qword)*(MSIZE+6)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + cmovae rbp, r12 + cmovae rsi, r13 + cmovae rdi, r14 + mov qword [r15+sizeof(qword)*0], rax + mov qword [r15+sizeof(qword)*1], rbx + mov qword [r15+sizeof(qword)*2], rcx + mov qword [r15+sizeof(qword)*3], rdx + mov qword [r15+sizeof(qword)*4], rbp + mov qword [r15+sizeof(qword)*5], rsi + mov qword [r15+sizeof(qword)*6], rdi + ret +ENDFUNC mred_7 + + +;; +;; 8*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_8,PRIVATE +%assign MSIZE 8 + push r15 ; save reduction address + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE+5)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+5)], r13 + op_reg_mem adc, r14,[rdi+sizeof(qword)*(MSIZE+6)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+6)], r14 + op_reg_mem adc, r15,[rdi+sizeof(qword)*(MSIZE+7)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+7)], r15 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + op_reg_mem sbb, r13,[rsi+sizeof(qword)*5], rbx + op_reg_mem sbb, r14,[rsi+sizeof(qword)*6], rbx + op_reg_mem sbb, r15,[rsi+sizeof(qword)*7], rbx + sbb rax, 0 + + pop rsi ; address of reduction + ; copy under cf [rsi] = cf? [rdi] : {r8-r15} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + mov qword [rsi+sizeof(qword)*0], rax + mov qword [rsi+sizeof(qword)*1], rbx + mov qword [rsi+sizeof(qword)*2], rcx + mov qword [rsi+sizeof(qword)*3], rdx + + mov rax, qword [rdi+sizeof(qword)*(MSIZE+4)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+5)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+6)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+7)] + cmovae rax, r12 + cmovae rbx, r13 + cmovae rcx, r14 + cmovae rdx, r15 + mov qword [rsi+sizeof(qword)*4], rax + mov qword [rsi+sizeof(qword)*5], rbx + mov qword [rsi+sizeof(qword)*6], rcx + mov qword [rsi+sizeof(qword)*7], rdx + ret +ENDFUNC mred_8 + + +;; +;; 9*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_9,PRIVATE +%assign MSIZE 9 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x1 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x1_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14 + mov r8, r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_1x1 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_9 + + +;; +;; 10*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_10,PRIVATE +%assign MSIZE 10 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x2 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x2_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov r8, r14 + mov r9, r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_2x2 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_10 + + +;; +;; 11*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_11,PRIVATE +%assign MSIZE 11 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x3 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x3_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov r8, r13 + mov r9, r14 + mov r10,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_3x3 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_11 + + +;; +;; 12*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_12,PRIVATE +%assign MSIZE 12 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x4 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x4_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov r8, r12 + mov r9, r13 + mov r10,r14 + mov r11,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_4x4 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_12 + + +;; +;; 13*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_13,PRIVATE +%assign MSIZE 13 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x5 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x5_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov r8, r11 + mov r9, r12 + mov r10,r13 + mov r11,r14 + mov r12,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r12,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_5x5 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_13 + + +;; +;; 14*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_14,PRIVATE +%assign MSIZE 14 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x6 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x6_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov r8, r10 + mov r9, r11 + mov r10,r12 + mov r11,r13 + mov r12,r14 + mov r13,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r12,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r13,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_6x6 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_14 + + +;; +;; 15*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_15,PRIVATE +%assign MSIZE 15 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x7 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x7_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov r8, r9 + mov r9, r10 + mov r10,r11 + mov r11,r12 + mov r12,r13 + mov r13,r14 + mov r14,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r12,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r13,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r14,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_7x7 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_15 + + +;; +;; 16*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_16,PRIVATE +%assign MSIZE 16 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + mov rdx, r8 ; copy m' + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + + push rdx + call mla_8x8 + pop rdx + + pop rax + shr rax, 1 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+0)], r8, [rdi+sizeof(qword)*(8+0)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+1)], r9, [rdi+sizeof(qword)*(8+1)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+2)], r10,[rdi+sizeof(qword)*(8+2)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+3)], r11,[rdi+sizeof(qword)*(8+3)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+4)], r12,[rdi+sizeof(qword)*(8+4)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+5)], r13,[rdi+sizeof(qword)*(8+5)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+6)], r14,[rdi+sizeof(qword)*(8+6)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+7)], r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_8x8 + + sub rsi, sizeof(qword)*8 + + pop rax + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10, [rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11, [rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12, [rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13, [rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14, [rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15, [rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + + pop rbx + add r8, rbx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + adc rax, 0 + + mov qword [rdi+sizeof(qword)*(8+0)], r8 + mov qword [rdi+sizeof(qword)*(8+1)], r9 + mov qword [rdi+sizeof(qword)*(8+2)], r10 + mov qword [rdi+sizeof(qword)*(8+3)], r11 + mov qword [rdi+sizeof(qword)*(8+4)], r12 + mov qword [rdi+sizeof(qword)*(8+5)], r13 + mov qword [rdi+sizeof(qword)*(8+6)], r14 + mov qword [rdi+sizeof(qword)*(8+7)], r15 + + add rsp, sizeof(qword)*8 ; release U space + + pop rbp + + ; reduction -= modulus + op_mem_mem sub, [rbp+sizeof(qword)*0 ], [rdi+sizeof(qword)*0 ], [rsi+sizeof(qword)*0 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*1 ], [rdi+sizeof(qword)*1 ], [rsi+sizeof(qword)*1 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*2 ], [rdi+sizeof(qword)*2 ], [rsi+sizeof(qword)*2 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*3 ], [rdi+sizeof(qword)*3 ], [rsi+sizeof(qword)*3 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*4 ], [rdi+sizeof(qword)*4 ], [rsi+sizeof(qword)*4 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*5 ], [rdi+sizeof(qword)*5 ], [rsi+sizeof(qword)*5 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*6 ], [rdi+sizeof(qword)*6 ], [rsi+sizeof(qword)*6 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*7 ], [rdi+sizeof(qword)*7 ], [rsi+sizeof(qword)*7 ], rbx + op_reg_mem sbb, r8, [rsi+sizeof(qword)*8 ], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*9 ], rbx + op_reg_mem sbb, r10, [rsi+sizeof(qword)*10], rbx + op_reg_mem sbb, r11, [rsi+sizeof(qword)*11], rbx + op_reg_mem sbb, r12, [rsi+sizeof(qword)*12], rbx + op_reg_mem sbb, r13, [rsi+sizeof(qword)*13], rbx + op_reg_mem sbb, r14, [rsi+sizeof(qword)*14], rbx + op_reg_mem sbb, r15, [rsi+sizeof(qword)*15], rbx + sbb rax, 0 + + ; copy under cf [rbp] = cf? [rdi] : [rbp] + mov rax, qword [rdi+sizeof(qword)*8 ] + mov rbx, qword [rdi+sizeof(qword)*9 ] + mov rcx, qword [rdi+sizeof(qword)*10] + mov rdx, qword [rdi+sizeof(qword)*11] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + mov qword [rbp+sizeof(qword)*8 ], rax + mov qword [rbp+sizeof(qword)*9 ], rbx + mov qword [rbp+sizeof(qword)*10], rcx + mov qword [rbp+sizeof(qword)*11], rdx + + mov rax, qword [rdi+sizeof(qword)*12] + mov rbx, qword [rdi+sizeof(qword)*13] + mov rcx, qword [rdi+sizeof(qword)*14] + mov rdx, qword [rdi+sizeof(qword)*15] + cmovae rax, r12 + cmovae rbx, r13 + cmovae rcx, r14 + cmovae rdx, r15 + mov qword [rbp+sizeof(qword)*12], rax + mov qword [rbp+sizeof(qword)*13], rbx + mov qword [rbp+sizeof(qword)*14], rcx + mov qword [rbp+sizeof(qword)*15], rdx + + mov r8, qword [rbp+sizeof(qword)*0] + mov r9, qword [rbp+sizeof(qword)*1] + mov r10, qword [rbp+sizeof(qword)*2] + mov r11, qword [rbp+sizeof(qword)*3] + mov r12, qword [rbp+sizeof(qword)*4] + mov r13, qword [rbp+sizeof(qword)*5] + mov r14, qword [rbp+sizeof(qword)*6] + mov r15, qword [rbp+sizeof(qword)*7] + + mov rax, qword [rdi+sizeof(qword)*0] + mov rbx, qword [rdi+sizeof(qword)*1] + mov rcx, qword [rdi+sizeof(qword)*2] + mov rdx, qword [rdi+sizeof(qword)*3] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + mov qword [rbp+sizeof(qword)*0], rax + mov qword [rbp+sizeof(qword)*1], rbx + mov qword [rbp+sizeof(qword)*2], rcx + mov qword [rbp+sizeof(qword)*3], rdx + + mov rax, qword [rdi+sizeof(qword)*4] + mov rbx, qword [rdi+sizeof(qword)*5] + mov rcx, qword [rdi+sizeof(qword)*6] + mov rdx, qword [rdi+sizeof(qword)*7] + cmovae rax, r12 + cmovae rbx, r13 + cmovae rcx, r14 + cmovae rdx, r15 + mov qword [rbp+sizeof(qword)*4], rax + mov qword [rbp+sizeof(qword)*5], rbx + mov qword [rbp+sizeof(qword)*6], rcx + mov qword [rbp+sizeof(qword)*7], rdx + + ret +ENDFUNC mred_16 + + + +mred_short DQ mred_5 - mred_short + DQ mred_6 - mred_short + DQ mred_7 - mred_short + DQ mred_8 - mred_short + DQ mred_9 - mred_short + DQ mred_10 - mred_short + DQ mred_11 - mred_short + DQ mred_12 - mred_short + DQ mred_13 - mred_short + DQ mred_14 - mred_short + DQ mred_15 - mred_short + DQ mred_16 - mred_short + +mred8x_start DQ mred8x1_start - mred8x_start + DQ mred8x2_start - mred8x_start + DQ mred8x3_start - mred8x_start + DQ mred8x4_start - mred8x_start + DQ mred8x5_start - mred8x_start + DQ mred8x6_start - mred8x_start + DQ mred8x7_start - mred8x_start diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmredpp.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmredpp.inc new file mode 100644 index 000000000..4a2bf7b7c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmredpp.inc @@ -0,0 +1,571 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number reduction Support +; +; + +%ifndef _PCPMRED_INC_ +%assign _PCPMRED_INC_ 1 + +%include "pcpmredpp_basic.inc" + +; +; r15 - reduction +; rdi - buffer +; rsi - modulus +; rdx - modulus legth +; r8 - m' +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_8N_adcox,PRIVATE + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + mov rbx, rdx ; number of passes == modulus length + + xor rax, rax ; init global carry + +.passLoop: + ; save: + push rdi ; - buffer address + push rsi ; - modulus address + push rdx ; - modulus length + push r8 ; - m' + push rbx ; - rest of passes + push rax ; - global carry + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; + ; signgle pass + ; + push rdx ; init modulus counter + mov rdx, r8 ; copy m' + + ; load low part of the product into r8,r9,r10,r11,r12,r13,r14,r15 + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + pop rdx ; restore modulus counter + + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + + jmp .entryInnerLoop + +.innerLoop: + push rdx ; save modulus counter + call mla_8x8 + pop rdx ; restore modulus counter + + pop rax + shr rax, 1 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+0)], r8, [rdi+sizeof(qword)*(8+0)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+1)], r9, [rdi+sizeof(qword)*(8+1)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+2)], r10,[rdi+sizeof(qword)*(8+2)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+3)], r11,[rdi+sizeof(qword)*(8+3)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+4)], r12,[rdi+sizeof(qword)*(8+4)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+5)], r13,[rdi+sizeof(qword)*(8+5)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+6)], r14,[rdi+sizeof(qword)*(8+6)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+7)], r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + +.entryInnerLoop: + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + sub rdx, 8 + jg .innerLoop + + ; single pass completion + pop rax ; new global carry + + pop rbx ; prev global carry + add r8, rbx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + adc rax, 0 ; update global carry + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*6], r14 + mov qword [rdi+sizeof(qword)*7], r15 + ; + ; end of single pass + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ; restore: + pop rbx ; - rest of passes + pop r8 ; - m' + pop rdx ; - modulus length + pop rsi ; - modulus address + pop rdi ; - buffer address + add rdi, sizeof(qword)*8 + sub rbx, 8 + jg .passLoop + + add rsp, sizeof(qword)*8 ; release U space + + mov r14, rdx ; save modulus length + lea r15, [rdx*sizeof(qword)]; save modulus length (bytes) + + mov rbx, rax ; global carry + mov rcx, rsi ; modulus + mov rsi, rdi ; buffer + pop rdi ; reduction address + + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + mov rdx, r14 ; length + sub rdi, r15 ; reduction + sub rsi, r15 ; buffer (src1) + mov rcx, rdi ; reduction (src2) + shr rbx,1 ; restore cf + + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_8N_adcox + + +; +; r15 - reduction +; rdi - buffer +; rsi - modulus +; rdx - modulus legth +; r8 - m' +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_N_adcox,PRIVATE + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + mov rbx, rdx ; number of passes counter == (modulus_length -8) + sub rbx, 8 + + xor rax, rax ; init carryGBL + + mov r15, dword 7 ; n = modulus_len%8 + and r15, rdx + GET_EP rbp, mla_8xl_tail, r15 ; tail procedure (mla_8xn) address + +.passLoop: + ; save: + push rdi ; - buffer address + push rsi ; - modulus address + push rdx ; - modulus length + push r8 ; - m' + push rbx ; - rest of passes + push rax ; - carryGBL + push rbp ; - mla_8xn procedure + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; regular pass +;; + sub rdx, 8 ; init modulus counter + push rdx + mov rdx, r8 ; copy m' + + ; load low part of the product into r8,r9,r10,r11,r12,r13,r14,r15 + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + pop rdx ; restore modulus counter + + xor rax, rax ; init carryLCL + push rax + + jmp .entryInnerLoop + +.innerLoop: + push rdx ; save modulus counter + call mla_8x8 + pop rdx ; restore modulus counter + +.entryInnerLoop: + pop rax ; restore carryLCL + shr rax, 1 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+0)], r8, [rdi+sizeof(qword)*(8+0)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+1)], r9, [rdi+sizeof(qword)*(8+1)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+2)], r10,[rdi+sizeof(qword)*(8+2)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+3)], r11,[rdi+sizeof(qword)*(8+3)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+4)], r12,[rdi+sizeof(qword)*(8+4)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+5)], r13,[rdi+sizeof(qword)*(8+5)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+6)], r14,[rdi+sizeof(qword)*(8+6)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+7)], r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; update store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + sub rdx, 8 + jnc .innerLoop + + add rdx, 8 + jz .complete_regular_pass + + ; tail of single pass + mov rax, [rsp+sizeof(qword)] ; procedure address + + SWAP rcx, rsi + push rdx + call rax + pop rdx + SWAP rcx, rsi + + lea rdi, [rdi+rdx*sizeof(qword)] + pop rax ; restore carryLCL + shr rax, 1 + mov rbx, rdx + + dec rbx + jz .mt_1 + dec rbx + jz .mt_2 + dec rbx + jz .mt_3 + dec rbx + jz .mt_4 + dec rbx + jz .mt_5 + dec rbx + jz .mt_6 +.mt_7: op_reg_mem adc, r9, [rdi+sizeof(qword)*1], rbx +.mt_6: op_reg_mem adc, r10,[rdi+sizeof(qword)*2], rbx +.mt_5: op_reg_mem adc, r11,[rdi+sizeof(qword)*3], rbx +.mt_4: op_reg_mem adc, r12,[rdi+sizeof(qword)*4], rbx +.mt_3: op_reg_mem adc, r13,[rdi+sizeof(qword)*5], rbx +.mt_2: op_reg_mem adc, r14,[rdi+sizeof(qword)*6], rbx +.mt_1: op_reg_mem adc, r15,[rdi+sizeof(qword)*7], rbx + + adc rax, 0 ; update carryLCL + push rax + + ; single pass completion +.complete_regular_pass: + pop rax ; carryLCL + pop rbp ; mla_8xn procedure + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + adc rax, 0 ; update carryGBL + + mov qword [rdi+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*6], r14 + mov qword [rdi+sizeof(qword)*7], r15 +;; +;; end of regular pass +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ; restore: + pop rbx ; - rest of passes + pop r8 ; - m' + pop rdx ; - modulus length + pop rsi ; - modulus address + pop rdi ; - buffer address + add rdi, sizeof(qword)*8 + sub rbx, 8 + jnc .passLoop + + add rbx, 8 + jz .complete_reduction + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; tail pass of reduction +;; + ; save: + push rdi ; - buffer address + push rsi ; - modulus address + push rdx ; - modulus length + push r8 ; - m' + push rbx ; - rest of passes + push rax ; - carry + push rbp ; - mla_8xn procedure + + sub rdx, 8 ; init modulus counter + push rdx + mov rdx, r8 ; copy m' + + ; load low part of the product into r8,r9,r10,r11,r12,r13,r14,r15 + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + GET_EP rax, mred8x_start, rbx, rbp ; procedure mred8xn_start address + + call rax + pop rdx ; restore modulus counter + + xor rax, rax ; init carryCLC + push rax + + jmp .entryTailLoop + +.tailLoop: + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rax, [rsp+sizeof(qword)] ; procedure address + push rdx ; save modulus counter + call rax + pop rdx ; restore modulus counter + +.entryTailLoop: + pop rax ; restore carryLCL + shr rax, 1 + adc r8, 0 + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + adc rax, 0 ; update carryGBL + + mov rbx, [rsp+sizeof(qword)*2] ; modulus_len%7 + cmp rbx, 1 + jz .tt_1 + cmp rbx, 2 + jz .tt_2 + cmp rbx, 3 + jz .tt_3 + cmp rbx, 4 + jz .tt_4 + cmp rbx, 5 + jz .tt_5 + cmp rbx, 6 + jz .tt_6 +.tt_7: op_reg_mem adc, r9, [rdi+rbx*sizeof(qword)+sizeof(qword)*1], rbp +.tt_6: op_reg_mem adc, r10,[rdi+rbx*sizeof(qword)+sizeof(qword)*2], rbp +.tt_5: op_reg_mem adc, r11,[rdi+rbx*sizeof(qword)+sizeof(qword)*3], rbp +.tt_4: op_reg_mem adc, r12,[rdi+rbx*sizeof(qword)+sizeof(qword)*4], rbp +.tt_3: op_reg_mem adc, r13,[rdi+rbx*sizeof(qword)+sizeof(qword)*5], rbp +.tt_2: op_reg_mem adc, r14,[rdi+rbx*sizeof(qword)+sizeof(qword)*6], rbp +.tt_1: op_reg_mem adc, r15,[rdi+rbx*sizeof(qword)+sizeof(qword)*7], rbp + + adc rax, 0 + push rax ; update store carryLCL + + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*0], r8 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*1], r9 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*2], r10 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*3], r11 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*4], r12 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*5], r13 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*6], r14 + mov qword [rdi+rbx*sizeof(qword)+sizeof(qword)*7], r15 + + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + sub rdx, 8 + jnc .tailLoop + + add rdx, 8 + + ; load data depending on length of tail + mov rbx, rdx + + mov r8, qword [rdi] + dec rbx + jz .get_tail_proc + mov r9, qword [rdi+sizeof(qword)] + dec rbx + jz .get_tail_proc + mov r10, qword [rdi+sizeof(qword)*2] + dec rbx + jz .get_tail_proc + mov r11, qword [rdi+sizeof(qword)*3] + dec rbx + jz .get_tail_proc + mov r12, qword [rdi+sizeof(qword)*4] + dec rbx + jz .get_tail_proc + mov r13, qword [rdi+sizeof(qword)*5] + dec rbx + jz .get_tail_proc + mov r14, qword [rdi+sizeof(qword)*6] + +.get_tail_proc: + ; multiply +; GET_EP rax, mla_8xl_tail, rdx, rbp ; tail procedure mla_8xn address + GET_EP rax, mla_lxl_short, rdx, rbp ; tail procedure mla_lxl address + + push rdx + call rax ; mla_nxn + pop rdx + + lea rdi, [rdi+rdx*sizeof(qword)] + + ; accumulate carryLCL and update hight product above + pop rax + shr rax, 1 + mov rbx, rdx + op_reg_mem adc, r8, [rdi+sizeof(qword)*0], rbp + dec rbx + jz .add_carry1 + op_reg_mem adc, r9, [rdi+sizeof(qword)*1], rbp + dec rbx + jz .add_carry1 + op_reg_mem adc, r10,[rdi+sizeof(qword)*2], rbp + dec rbx + jz .add_carry1 + op_reg_mem adc, r11,[rdi+sizeof(qword)*3], rbp + dec rbx + jz .add_carry1 + op_reg_mem adc, r12,[rdi+sizeof(qword)*4], rbp + dec rbx + jz .add_carry1 + op_reg_mem adc, r13,[rdi+sizeof(qword)*5], rbp + dec rbx + jz .add_carry1 + op_reg_mem adc, r14,[rdi+sizeof(qword)*6], rbp +.add_carry1: + adc rax, 0 + + pop rbp ; mul_8xn procedure + + ; accumulate carryGBL and store hight product above + pop rbx ; carryGBL + add r8, rbx + mov qword [rdi+sizeof(qword)*0], r8 + dec rdx + jz .add_carry2 + adc r9, 0 + mov qword [rdi+sizeof(qword)*1], r9 + dec rdx + jz .add_carry2 + adc r10, 0 + mov qword [rdi+sizeof(qword)*2], r10 + dec rdx + jz .add_carry2 + adc r11, 0 + mov qword [rdi+sizeof(qword)*3], r11 + dec rdx + jz .add_carry2 + adc r12, 0 + mov qword [rdi+sizeof(qword)*4], r12 + dec rdx + jz .add_carry2 + adc r13, 0 + mov qword [rdi+sizeof(qword)*5], r13 + dec rdx + jz .add_carry2 + adc r14, 0 + mov qword [rdi+sizeof(qword)*6], r14 +.add_carry2: + adc rax, 0 ; update carryGBL + + + ; release stack + pop rbx ; - passes counter + pop r8 ; - m' + pop rdx ; - modulus length + pop rsi ; - modulus + pop rdi ; - buffer + lea rdi, [rdi+rbx*sizeof(qword)] + +.complete_reduction: + add rsp, sizeof(qword)*8 ; release U space + + mov r14, rdx ; save modulus length + lea r15, [rdx*sizeof(qword)]; save modulus length (bytes) + + mov rbx, rax ; carry + mov rcx, rsi ; modulus + mov rsi, rdi ; buffer + pop rdi ; reduction address + + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + mov rdx, r14 ; length + sub rdi, r15 ; reduction + sub rsi, r15 ; buffer (src1) + mov rcx, rdi ; reduction (src2) + shr rbx,1 ; restore cf + + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_N_adcox + + +%endif ;; _PCPMRED_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmredpp_basic.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmredpp_basic.inc new file mode 100644 index 000000000..8e8b16378 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmredpp_basic.inc @@ -0,0 +1,2193 @@ +;=============================================================================== +; Copyright (C) 2013 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Low level Big Number reduction Support +; +; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Fixed-size Montgomery reduction +;; + +; +; X7,X6,X5,X4,X3,X2,X1,X0 contains already preloaded (low) product +; +%macro MRED_FIX 8-15.nolist + %xdefine %%mSize %1 + %xdefine %%rRed %2 + %xdefine %%rProduct %3 + %xdefine %%rModulus %4 + %xdefine %%M0 %5 + %xdefine %%TMPH %6 + %xdefine %%TMP %7 + %xdefine %%X0 %8 + %xdefine %%X1 %9 + %xdefine %%X2 %10 + %xdefine %%X3 %11 + %xdefine %%X4 %12 + %xdefine %%X5 %13 + %xdefine %%X6 %14 + %xdefine %%X7 %15 + + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%if %%mSize > 1 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{}, {%%rModulus}, {%%TMPH},{%%TMP}, {%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%if %%mSize > 2 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%if %%mSize > 3 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{}, {%%rModulus}, {%%TMPH},{%%TMP}, {%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%if %%mSize > 4 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%if %%mSize > 5 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{}, {%%rModulus}, {%%TMPH},{%%TMP}, {%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%if %%mSize > 6 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%if %%mSize > 7 + mov rdx, %%M0 + imul rdx, %%X0 + MLA_FIX {%%mSize},{},{%%rModulus},{%%TMPH},{%%TMP},{%%X0},{%%X1},{%%X2},{%%X3},{%%X4},{%%X5},{%%X6},{%%X7} +%endif +%endif +%endif +%endif +%endif +%endif +%endif + + xor %%TMP, %%TMP + add %%X0, qword [%%rProduct+sizeof(qword)*(%%mSize+0)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+0)], %%X0 +%if %%mSize > 1 + adc %%X1, qword [%%rProduct+sizeof(qword)*(%%mSize+1)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+1)], %%X1 +%if %%mSize > 2 + adc %%X2, qword [%%rProduct+sizeof(qword)*(%%mSize+2)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+2)], %%X2 +%if %%mSize > 3 + adc %%X3, qword [%%rProduct+sizeof(qword)*(%%mSize+3)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+3)], %%X3 +%if %%mSize > 4 + adc %%X4, qword [%%rProduct+sizeof(qword)*(%%mSize+4)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+4)], %%X4 +%if %%mSize > 5 + adc %%X5, qword [%%rProduct+sizeof(qword)*(%%mSize+5)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+5)], %%X5 +%if %%mSize > 6 + adc %%X6, qword [%%rProduct+sizeof(qword)*(%%mSize+6)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+6)], %%X6 +%if %%mSize > 7 + adc %%X7, qword [%%rProduct+sizeof(qword)*(%%mSize+7)] + mov qword [%%rProduct+sizeof(qword)*(%%mSize+7)], %%X7 +%endif +%endif +%endif +%endif +%endif +%endif +%endif + adc %%TMP, 0 + + sub %%X0, qword [%%rModulus+sizeof(qword)*0] +%if %%mSize > 1 + sbb %%X1, qword [%%rModulus+sizeof(qword)*1] +%if %%mSize > 2 + sbb %%X2, qword [%%rModulus+sizeof(qword)*2] +%if %%mSize > 3 + sbb %%X3, qword [%%rModulus+sizeof(qword)*3] +%if %%mSize > 4 + sbb %%X4, qword [%%rModulus+sizeof(qword)*4] +%if %%mSize > 5 + sbb %%X5, qword [%%rModulus+sizeof(qword)*5] +%if %%mSize > 6 + sbb %%X6, qword [%%rModulus+sizeof(qword)*6] +%if %%mSize > 7 + sbb %%X7, qword [%%rModulus+sizeof(qword)*7] +%endif +%endif +%endif +%endif +%endif +%endif +%endif + sbb %%TMP, 0 + + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+0)] + cmovae rax, %%X0 + mov qword [%%rRed+sizeof(qword)*0], rax +%if %%mSize > 1 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+1)] + cmovae rax, %%X1 + mov qword [%%rRed+sizeof(qword)*1], rax +%if %%mSize > 2 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+2)] + cmovae rax, %%X2 + mov qword [%%rRed+sizeof(qword)*2], rax +%if %%mSize > 3 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+3)] + cmovae rax, %%X3 + mov qword [%%rRed+sizeof(qword)*3], rax +%if %%mSize > 4 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+4)] + cmovae rax, %%X4 + mov qword [%%rRed+sizeof(qword)*4], rax +%if %%mSize > 5 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+5)] + cmovae rax, %%X5 + mov qword [%%rRed+sizeof(qword)*5], rax +%if %%mSize > 6 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+6)] + cmovae rax, %%X6 + mov qword [%%rRed+sizeof(qword)*6], rax +%if %%mSize > 7 + mov rax, qword [%%rProduct+sizeof(qword)*(%%mSize+7)] + cmovae rax, %%X7 + mov qword [%%rRed+sizeof(qword)*7], rax +%endif +%endif +%endif +%endif +%endif +%endif +%endif +%endmacro + +align IPP_ALIGN_FACTOR +DECLARE_FUNC sub_N,PRIVATE + xor rax, rax ; cf = 0 +.sub_next: + lea rdi, [rdi+sizeof(qword)] + mov r8, qword [rsi] + mov r9, qword [rcx] + lea rsi, [rsi+sizeof(qword)] + lea rcx, [rcx+sizeof(qword)] + sbb r8, r9 + mov qword [rdi-sizeof(qword)], r8 + dec rdx + jnz .sub_next + adc rax, 0 + ret +ENDFUNC sub_N + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC copy_ae_N,PRIVATE + lea rdi, [rdi+sizeof(qword)] + mov r8, qword [rsi] ; src1[] + mov r9, qword [rcx] ; src2[] + lea rsi, [rsi+sizeof(qword)] + lea rcx, [rcx+sizeof(qword)] + cmovae r8, r9 + mov qword [rdi-sizeof(qword)], r8 + dec rdx + jnz copy_ae_N + ret +ENDFUNC copy_ae_N + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; mredN_start procedures +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred1_start,PRIVATE + MLA_FIX 1,, rsi, rbx,rbp, r8 + ret +ENDFUNC mred1_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred2_start,PRIVATE + MLA_FIX 2,, rsi, rbx,rbp, r8,r9 + ret +ENDFUNC mred2_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred3_start,PRIVATE + MLA_FIX 3,, rsi, rbx,rbp, r8,r9,r10 + ret +ENDFUNC mred3_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred4_start,PRIVATE + MLA_FIX 4,, rsi, rbx,rbp, r8,r9,r10,r11 + ret +ENDFUNC mred4_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred5_start,PRIVATE + MLA_FIX 5,, rsi, rbx,rbp, r8,r9,r10,r11,r12 + ret +ENDFUNC mred5_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred6_start,PRIVATE + MLA_FIX 6,, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13 + ret +ENDFUNC mred6_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred7_start,PRIVATE + MLA_FIX 7,, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14 + ret +ENDFUNC mred7_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8_start,PRIVATE + MLA_FIX 8,, rsi, rbx,rbp, r8,r9,r10,r11,r12,r13,r14,r15 + ret +ENDFUNC mred8_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x1_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x1_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x2_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x2_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x3_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x3_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x4_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x4_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x5_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x5_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x6_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*5], rdx + call mred8_start + mov [rdi+sizeof(qword)*5], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x6_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x7_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*5], rdx + call mred8_start + mov [rdi+sizeof(qword)*5], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*6], rdx + call mred8_start + mov [rdi+sizeof(qword)*6], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x7_start + + +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred8x8_start,PRIVATE + push rdx ; save m' + + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*0], rdx + call mred8_start + mov [rdi], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*1], rdx + call mred8_start + mov [rdi+sizeof(qword)*1], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*2], rdx + call mred8_start + mov [rdi+sizeof(qword)*2], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*3], rdx + call mred8_start + mov [rdi+sizeof(qword)*3], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*4], rdx + call mred8_start + mov [rdi+sizeof(qword)*4], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*5], rdx + call mred8_start + mov [rdi+sizeof(qword)*5], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*6], rdx + call mred8_start + mov [rdi+sizeof(qword)*6], rax + + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + mov qword [rcx+sizeof(qword)*7], rdx + call mred8_start + mov [rdi+sizeof(qword)*7], rax + + pop rdx ; resrore m' + ret +ENDFUNC mred8x8_start + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; rdi - temporary product buffer/temporary reduction +;; rsi - modulus +;; r8 - m' +;; r15 - target reduction address +;; + +;; +;; 1*qword modulus length +;; + +;; +;; 2*qword modulus length +;; + +;; +;; 3*qword modulus length +;; + +;; +;; 4*qword modulus length +;; + +;; +;; 5*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_5,PRIVATE +%assign MSIZE 5 + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred5_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + sbb rax, 0 + + ; copy under cf [r15] = cf? [r15] : {r8-r12} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + mov rbp, qword [rdi+sizeof(qword)*(MSIZE+4)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + cmovae rbp, r12 + mov qword [r15+sizeof(qword)*0], rax + mov qword [r15+sizeof(qword)*1], rbx + mov qword [r15+sizeof(qword)*2], rcx + mov qword [r15+sizeof(qword)*3], rdx + mov qword [r15+sizeof(qword)*4], rbp + ret +ENDFUNC mred_5 + + +;; +;; 6*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_6,PRIVATE +%assign MSIZE 6 + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred6_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE+5)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+5)], r13 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + op_reg_mem sbb, r13,[rsi+sizeof(qword)*5], rbx + sbb rax, 0 + + ; copy under cf [r15] = cf? [r15] : {r8-r13} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + mov rbp, qword [rdi+sizeof(qword)*(MSIZE+4)] + mov rsi, qword [rdi+sizeof(qword)*(MSIZE+5)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + cmovae rbp, r12 + cmovae rsi, r13 + mov qword [r15+sizeof(qword)*0], rax + mov qword [r15+sizeof(qword)*1], rbx + mov qword [r15+sizeof(qword)*2], rcx + mov qword [r15+sizeof(qword)*3], rdx + mov qword [r15+sizeof(qword)*4], rbp + mov qword [r15+sizeof(qword)*5], rsi + ret +ENDFUNC mred_6 + + +;; +;; 7*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_7,PRIVATE +%assign MSIZE 7 + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred7_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE+5)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+5)], r13 + op_reg_mem adc, r14,[rdi+sizeof(qword)*(MSIZE+6)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+6)], r14 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + op_reg_mem sbb, r13,[rsi+sizeof(qword)*5], rbx + op_reg_mem sbb, r14,[rsi+sizeof(qword)*6], rbx + sbb rax, 0 + + ; copy under cf [r15] = cf? [r15] : {r8-r14} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + mov rbp, qword [rdi+sizeof(qword)*(MSIZE+4)] + mov rsi, qword [rdi+sizeof(qword)*(MSIZE+5)] + mov rdi, qword [rdi+sizeof(qword)*(MSIZE+6)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + cmovae rbp, r12 + cmovae rsi, r13 + cmovae rdi, r14 + mov qword [r15+sizeof(qword)*0], rax + mov qword [r15+sizeof(qword)*1], rbx + mov qword [r15+sizeof(qword)*2], rcx + mov qword [r15+sizeof(qword)*3], rdx + mov qword [r15+sizeof(qword)*4], rbp + mov qword [r15+sizeof(qword)*5], rsi + mov qword [r15+sizeof(qword)*6], rdi + ret +ENDFUNC mred_7 + + +;; +;; 8*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_8,PRIVATE +%assign MSIZE 8 + push r15 ; save reduction address + push r8 ; m' + + ; load low half of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + ; ui = x[i]*m' + ; reduction += ui*modulus + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + mov rdx, [rsp] + gsmulx rbx, rdx, r8 + call mred8_start + + pop rax ; remove m' + + ; finalize cf, reduction += U0*modulus operation + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(MSIZE+0)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+0)], r8 + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE+1)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+1)], r9 + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE+2)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+2)], r10 + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE+3)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+3)], r11 + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE+4)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+4)], r12 + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE+5)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+5)], r13 + op_reg_mem adc, r14,[rdi+sizeof(qword)*(MSIZE+6)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+6)], r14 + op_reg_mem adc, r15,[rdi+sizeof(qword)*(MSIZE+7)], rbx + mov qword [rdi+sizeof(qword)*(MSIZE+7)], r15 + adc rax, 0 + + ; reduction -= modulus + op_reg_mem sub, r8, [rsi+sizeof(qword)*0], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*1], rbx + op_reg_mem sbb, r10,[rsi+sizeof(qword)*2], rbx + op_reg_mem sbb, r11,[rsi+sizeof(qword)*3], rbx + op_reg_mem sbb, r12,[rsi+sizeof(qword)*4], rbx + op_reg_mem sbb, r13,[rsi+sizeof(qword)*5], rbx + op_reg_mem sbb, r14,[rsi+sizeof(qword)*6], rbx + op_reg_mem sbb, r15,[rsi+sizeof(qword)*7], rbx + sbb rax, 0 + + pop rsi ; address of reduction + ; copy under cf [rsi] = cf? [rdi] : {r8-r15} + mov rax, qword [rdi+sizeof(qword)*(MSIZE+0)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+1)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+2)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+3)] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + mov qword [rsi+sizeof(qword)*0], rax + mov qword [rsi+sizeof(qword)*1], rbx + mov qword [rsi+sizeof(qword)*2], rcx + mov qword [rsi+sizeof(qword)*3], rdx + + mov rax, qword [rdi+sizeof(qword)*(MSIZE+4)] + mov rbx, qword [rdi+sizeof(qword)*(MSIZE+5)] + mov rcx, qword [rdi+sizeof(qword)*(MSIZE+6)] + mov rdx, qword [rdi+sizeof(qword)*(MSIZE+7)] + cmovae rax, r12 + cmovae rbx, r13 + cmovae rcx, r14 + cmovae rdx, r15 + mov qword [rsi+sizeof(qword)*4], rax + mov qword [rsi+sizeof(qword)*5], rbx + mov qword [rsi+sizeof(qword)*6], rcx + mov qword [rsi+sizeof(qword)*7], rdx + ret +ENDFUNC mred_8 + + +;; +;; 9*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_9,PRIVATE +%assign MSIZE 9 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x1 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x1_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14 + mov r8, r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_1x1 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_9 + + +;; +;; 10*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_10,PRIVATE +%assign MSIZE 10 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x2 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x2_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov r8, r14 + mov r9, r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_2x2 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_10 + + +;; +;; 11*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_11,PRIVATE +%assign MSIZE 11 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x3 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x3_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov r8, r13 + mov r9, r14 + mov r10,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_3x3 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_11 + + +;; +;; 12*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_12,PRIVATE +%assign MSIZE 12 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x4 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x4_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov r8, r12 + mov r9, r13 + mov r10,r14 + mov r11,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_4x4 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_12 + + +;; +;; 13*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_13,PRIVATE +%assign MSIZE 13 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x5 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x5_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov r8, r11 + mov r9, r12 + mov r10,r13 + mov r11,r14 + mov r12,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r12,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_5x5 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_13 + + +;; +;; 14*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_14,PRIVATE +%assign MSIZE 14 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x6 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x6_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov r8, r10 + mov r9, r11 + mov r10,r12 + mov r11,r13 + mov r12,r14 + mov r13,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r12,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r13,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_6x6 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_14 + + +;; +;; 15*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_15,PRIVATE +%assign MSIZE 15 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + push r8 ; save m' + mov rdx, r8 + +;; +;; init pass +;; + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax ; init carryLCL + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + SWAP rcx, rsi + call mla_8x7 + SWAP rcx, rsi + + pop rax + shr rax, 1 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], r15, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7], rbx + adc rax, 0 + push rax ; store carryGBL + +;; +;; last pass +;; + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + mov rdx, [rsp+sizeof(qword)] + call mred8x7_start + + xor rax, rax ; init carryLCL + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov r8, r9 + mov r9, r10 + mov r10,r11 + mov r11,r12 + mov r12,r13 + mov r13,r14 + mov r14,r15 + add r8, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1] + adc r9, qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2] + adc r10,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3] + adc r11,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4] + adc r12,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5] + adc r13,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6] + adc r14,qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*7] + adc rax, 0 + push rax ; store carryLCL + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_7x7 + + pop rax ; restore carryLCL + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], rbx + adc rax, 0 + + pop rbx ; carryGBL + add r8, rbx + adc r9, 0 + adc r10,0 + adc r11,0 + adc r12,0 + adc r13,0 + adc r14,0 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*0], r8 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*1], r9 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*2], r10 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*3], r11 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*4], r12 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*5], r13 + mov qword [rdi+sizeof(qword)*(MSIZE-8)+sizeof(qword)*6], r14 + adc rax, 0 ; update carryGBL + + + pop rcx ; remove m' + add rsp, sizeof(qword)*8 ; release U space + + lea rcx, [rsi-sizeof(qword)*8] ; restore modulus + lea rsi, [rdi+sizeof(qword)*(MSIZE-8)-sizeof(qword)*8] ; restore buffer + pop rdi ; restore reduction + + mov rbx, rax ; save carryGBL + + mov rdx, dword MSIZE + call sub_N ; reduction = buffer - modulus + sub rbx, rax ; rbx = borrow + + sub rdi, sizeof(qword)*MSIZE ; reduction + sub rsi, sizeof(qword)*MSIZE ; buffer (src1) + mov rcx, rdi ; reduction (src2) + mov rdx, dword MSIZE + shr rbx,1 ; restore cf + call copy_ae_N ; copy under cf, reduction = cf? buffer : reduction + + ret +ENDFUNC mred_15 + + +;; +;; 16*qword modulus length +;; +align IPP_ALIGN_FACTOR +DECLARE_FUNC mred_16,PRIVATE +%assign MSIZE 16 + push r15 ; save reduction address + + sub rsp, sizeof(qword)*8 ; allocate U space + mov rcx, rsp + + mov rdx, r8 ; copy m' + + ; load low part of the product + mov r8, qword [rdi] ; x0,x1,x2,x3,x4,x5,x6,x7 + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + + add rsi, sizeof(qword)*8 + add rdi, sizeof(qword)*8 + + push rdx + call mla_8x8 + pop rdx + + pop rax + shr rax, 1 + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+0)], r8, [rdi+sizeof(qword)*(8+0)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+1)], r9, [rdi+sizeof(qword)*(8+1)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+2)], r10,[rdi+sizeof(qword)*(8+2)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+3)], r11,[rdi+sizeof(qword)*(8+3)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+4)], r12,[rdi+sizeof(qword)*(8+4)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+5)], r13,[rdi+sizeof(qword)*(8+5)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+6)], r14,[rdi+sizeof(qword)*(8+6)], rbx + op_mem_reg_mem adc, [rdi+sizeof(qword)*(8+7)], r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + + sub rsi, sizeof(qword)*8 + + mov r8, qword [rdi] + mov r9, qword [rdi+sizeof(qword)] + mov r10,qword [rdi+sizeof(qword)*2] + mov r11,qword [rdi+sizeof(qword)*3] + mov r12,qword [rdi+sizeof(qword)*4] + mov r13,qword [rdi+sizeof(qword)*5] + mov r14,qword [rdi+sizeof(qword)*6] + mov r15,qword [rdi+sizeof(qword)*7] + + call mred8x8_start + + xor rax, rax + op_reg_mem add, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10,[rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11,[rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12,[rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13,[rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14,[rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15,[rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + push rax + + add rdi, sizeof(qword)*8 + add rsi, sizeof(qword)*8 + + call mla_8x8 + + sub rsi, sizeof(qword)*8 + + pop rax + shr rax, 1 + op_reg_mem adc, r8, [rdi+sizeof(qword)*(8+0)], rbx + op_reg_mem adc, r9, [rdi+sizeof(qword)*(8+1)], rbx + op_reg_mem adc, r10, [rdi+sizeof(qword)*(8+2)], rbx + op_reg_mem adc, r11, [rdi+sizeof(qword)*(8+3)], rbx + op_reg_mem adc, r12, [rdi+sizeof(qword)*(8+4)], rbx + op_reg_mem adc, r13, [rdi+sizeof(qword)*(8+5)], rbx + op_reg_mem adc, r14, [rdi+sizeof(qword)*(8+6)], rbx + op_reg_mem adc, r15, [rdi+sizeof(qword)*(8+7)], rbx + adc rax, 0 + + pop rbx + add r8, rbx + adc r9, 0 + adc r10, 0 + adc r11, 0 + adc r12, 0 + adc r13, 0 + adc r14, 0 + adc r15, 0 + adc rax, 0 + + mov qword [rdi+sizeof(qword)*(8+0)], r8 + mov qword [rdi+sizeof(qword)*(8+1)], r9 + mov qword [rdi+sizeof(qword)*(8+2)], r10 + mov qword [rdi+sizeof(qword)*(8+3)], r11 + mov qword [rdi+sizeof(qword)*(8+4)], r12 + mov qword [rdi+sizeof(qword)*(8+5)], r13 + mov qword [rdi+sizeof(qword)*(8+6)], r14 + mov qword [rdi+sizeof(qword)*(8+7)], r15 + + add rsp, sizeof(qword)*8 ; release U space + + pop rbp + + ; reduction -= modulus + op_mem_mem sub, [rbp+sizeof(qword)*0 ], [rdi+sizeof(qword)*0 ], [rsi+sizeof(qword)*0 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*1 ], [rdi+sizeof(qword)*1 ], [rsi+sizeof(qword)*1 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*2 ], [rdi+sizeof(qword)*2 ], [rsi+sizeof(qword)*2 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*3 ], [rdi+sizeof(qword)*3 ], [rsi+sizeof(qword)*3 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*4 ], [rdi+sizeof(qword)*4 ], [rsi+sizeof(qword)*4 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*5 ], [rdi+sizeof(qword)*5 ], [rsi+sizeof(qword)*5 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*6 ], [rdi+sizeof(qword)*6 ], [rsi+sizeof(qword)*6 ], rbx + op_mem_mem sbb, [rbp+sizeof(qword)*7 ], [rdi+sizeof(qword)*7 ], [rsi+sizeof(qword)*7 ], rbx + op_reg_mem sbb, r8, [rsi+sizeof(qword)*8 ], rbx + op_reg_mem sbb, r9, [rsi+sizeof(qword)*9 ], rbx + op_reg_mem sbb, r10, [rsi+sizeof(qword)*10], rbx + op_reg_mem sbb, r11, [rsi+sizeof(qword)*11], rbx + op_reg_mem sbb, r12, [rsi+sizeof(qword)*12], rbx + op_reg_mem sbb, r13, [rsi+sizeof(qword)*13], rbx + op_reg_mem sbb, r14, [rsi+sizeof(qword)*14], rbx + op_reg_mem sbb, r15, [rsi+sizeof(qword)*15], rbx + sbb rax, 0 + + ; copy under cf [rbp] = cf? [rdi] : [rbp] + mov rax, qword [rdi+sizeof(qword)*8 ] + mov rbx, qword [rdi+sizeof(qword)*9 ] + mov rcx, qword [rdi+sizeof(qword)*10] + mov rdx, qword [rdi+sizeof(qword)*11] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + mov qword [rbp+sizeof(qword)*8 ], rax + mov qword [rbp+sizeof(qword)*9 ], rbx + mov qword [rbp+sizeof(qword)*10], rcx + mov qword [rbp+sizeof(qword)*11], rdx + + mov rax, qword [rdi+sizeof(qword)*12] + mov rbx, qword [rdi+sizeof(qword)*13] + mov rcx, qword [rdi+sizeof(qword)*14] + mov rdx, qword [rdi+sizeof(qword)*15] + cmovae rax, r12 + cmovae rbx, r13 + cmovae rcx, r14 + cmovae rdx, r15 + mov qword [rbp+sizeof(qword)*12], rax + mov qword [rbp+sizeof(qword)*13], rbx + mov qword [rbp+sizeof(qword)*14], rcx + mov qword [rbp+sizeof(qword)*15], rdx + + mov r8, qword [rbp+sizeof(qword)*0] + mov r9, qword [rbp+sizeof(qword)*1] + mov r10, qword [rbp+sizeof(qword)*2] + mov r11, qword [rbp+sizeof(qword)*3] + mov r12, qword [rbp+sizeof(qword)*4] + mov r13, qword [rbp+sizeof(qword)*5] + mov r14, qword [rbp+sizeof(qword)*6] + mov r15, qword [rbp+sizeof(qword)*7] + + mov rax, qword [rdi+sizeof(qword)*0] + mov rbx, qword [rdi+sizeof(qword)*1] + mov rcx, qword [rdi+sizeof(qword)*2] + mov rdx, qword [rdi+sizeof(qword)*3] + cmovae rax, r8 + cmovae rbx, r9 + cmovae rcx, r10 + cmovae rdx, r11 + mov qword [rbp+sizeof(qword)*0], rax + mov qword [rbp+sizeof(qword)*1], rbx + mov qword [rbp+sizeof(qword)*2], rcx + mov qword [rbp+sizeof(qword)*3], rdx + + mov rax, qword [rdi+sizeof(qword)*4] + mov rbx, qword [rdi+sizeof(qword)*5] + mov rcx, qword [rdi+sizeof(qword)*6] + mov rdx, qword [rdi+sizeof(qword)*7] + cmovae rax, r12 + cmovae rbx, r13 + cmovae rcx, r14 + cmovae rdx, r15 + mov qword [rbp+sizeof(qword)*4], rax + mov qword [rbp+sizeof(qword)*5], rbx + mov qword [rbp+sizeof(qword)*6], rcx + mov qword [rbp+sizeof(qword)*7], rdx + + ret +ENDFUNC mred_16 + + + +mred_short DQ mred_5 - mred_short + DQ mred_6 - mred_short + DQ mred_7 - mred_short + DQ mred_8 - mred_short + DQ mred_9 - mred_short + DQ mred_10 - mred_short + DQ mred_11 - mred_short + DQ mred_12 - mred_short + DQ mred_13 - mred_short + DQ mred_14 - mred_short + DQ mred_15 - mred_short + DQ mred_16 - mred_short + +mred8x_start DQ mred8x1_start - mred8x_start + DQ mred8x2_start - mred8x_start + DQ mred8x3_start - mred8x_start + DQ mred8x4_start - mred8x_start + DQ mred8x5_start - mred8x_start + DQ mred8x6_start - mred8x_start + DQ mred8x7_start - mred8x_start diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmulx.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmulx.inc new file mode 100644 index 000000000..f3689a639 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpmulx.inc @@ -0,0 +1,154 @@ +;=============================================================================== +; Copyright (C) 2013 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: EM64T Cryptography Primitive. +; Emulation of Intel(R) instructions MULX, ADCX, ADOX (for debug only) +; +; +%ifndef _PCPMULX_INC_ +%assign _PCPMULX_INC_ 1 + +%ifndef _EMULATION_ +%macro gsmulx 3.nolist + %xdefine %%resH %1 + %xdefine %%resL %2 + %xdefine %%src %3 + + mulx %%resH,%%resL,%%src +%endmacro + +%endif + +%ifdef _EMULATION_ +%macro gsmulx 3.nolist + %xdefine %%resH %1 + %xdefine %%resL %2 + %xdefine %%src %3 + + pushf ;; store flags + + sub rsp, sizeof(qword)*4 + mov [rsp-sizeof(qword)*3], rax ;; store RAX + mov [rsp-sizeof(qword)*2], rdx ;; store RDX + mov rax,rdx + mov rdx, %%src + + mul rdx + + mov [rsp-sizeof(qword)*1], rax ;; store Low product + mov [rsp-sizeof(qword)*0], rdx ;; store Hig product + + mov rax, [rsp-sizeof(qword)*3] ;; re-store RAX + mov rdx, [rsp-sizeof(qword)*2] ;; re-store RDX + mov %%resL, [rsp-sizeof(qword)*1];; load Low product + mov %%resH, [rsp-sizeof(qword)*0];; load Hig product + add rsp, sizeof(qword)*4 + + popf ;; re-store flags +%endmacro + +%endif + +%ifndef _EMULATION_ +%macro gsadcx 2.nolist + %xdefine %%rdst %1 + %xdefine %%rsrc %2 + + adcx %%rdst, %%rsrc +%endmacro + +%endif + +%ifdef _EMULATION_ +%macro gsadcx 2.nolist + %xdefine %%rdst %1 + %xdefine %%src %2 + + push %%rdst ;; slot for result + push rax ;; save rax + pushfq ;; flags before adc + + adc %%rdst, %%src + mov [rsp+2*sizeof(qword)], %%rdst + + pushfq ;; rsrc = flags after operation + pop rax + and rax, 1 ;; cf after operation + and qword [rsp], (-2) ;; clear cf before operation + or [rsp], rax ;; new psw + popfq + + pop rax + pop %%rdst +%endmacro + +%endif + +%ifndef _EMULATION_ +%macro gsadox 2.nolist + %xdefine %%rdst %1 + %xdefine %%rsrc %2 + + adox %%rdst, %%rsrc +%endmacro + +%endif + +%ifdef _EMULATION_ +%macro gsadox 2.nolist + %xdefine %%rdst %1 + %xdefine %%src %2 + + push %%rdst + push rax ;; save rax + + pushfq ;; rax = flags before adc + mov rax, [rsp] + and rax, 800h ;; of + xor [rsp], rax ;; clear of + + shr rax, 11 ;; mov of to cf position + push rax ;; new psw + popfq + +%ifidni %%src,rax + mov rax, [rsp+sizeof(qword)] +%endif +%ifidni %%rdst,rax + mov %%rdst, [rsp+2*sizeof(qword)] +%endif + + adc %%rdst, %%src + mov [rsp+2*sizeof(qword)], %%rdst + + pushfq ;; rsrc = flags after operation + pop rax + and rax, 1 ;; cf after operation + + shl rax, 11 ;; mov cf into of position + or [rsp], rax ;; new psw + popfq + + pop rax + pop %%rdst +%endmacro + +%endif + +%endif ;; _PCPMULX_INC_ diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp192r1funcs_montas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp192r1funcs_montas.asm new file mode 100644 index 000000000..a47deb3d7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp192r1funcs_montas.asm @@ -0,0 +1,1030 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; secp p192r1 specific implementation +; + + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if _IPP32E >= _IPP32E_M7 + +%assign _xEMULATION_ 1 +%assign _ADCX_ADOX_ 1 + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +;; The p192r1 polynomial +Lpoly DQ 0FFFFFFFFFFFFFFFFh,0FFFFFFFFFFFFFFFEh,0FFFFFFFFFFFFFFFFh + +;; 2^(192*2) mod P precomputed for p192r1 polynomial +LRR DQ 00000000000000001h,00000000000000002h,00000000000000001h + +LOne DD 1,1,1,1,1,1,1,1 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_mul_by_2(uint64_t res[3], uint64_t a[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_mul_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 + + xor t3, t3 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + + shld t3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_mul_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_div_by_2(uint64_t res[3], uint64_t a[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_div_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + + xor t3, t3 + xor r13, r13 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, 0 + test a0, 1 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz r13,t3 + + shrd a0, a1, 1 + shrd a1, a2, 1 + shrd a2, r13,1 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_div_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_mul_by_3(uint64_t res[3], uint64_t a[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_mul_by_3,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 + + xor t3, t3 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + + shld t3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + + xor t3, t3 + add a0, qword [rsi+sizeof(qword)*0] + adc a1, qword [rsi+sizeof(qword)*1] + adc a2, qword [rsi+sizeof(qword)*2] + adc t3, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_mul_by_3 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_add(uint64_t res[3], uint64_t a[3], uint64_t b[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_add,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 + + xor t3, t3 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + + add a0, qword [rdx+sizeof(qword)*0] + adc a1, qword [rdx+sizeof(qword)*1] + adc a2, qword [rdx+sizeof(qword)*2] + adc t3, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_add + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_sub(uint64_t res[3], uint64_t a[3], uint64_t b[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_sub,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 + + xor t3, t3 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + + sub a0, qword [rdx+sizeof(qword)*0] + sbb a1, qword [rdx+sizeof(qword)*1] + sbb a2, qword [rdx+sizeof(qword)*2] + sbb t3, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + test t3, t3 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_sub + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_neg(uint64_t res[3], uint64_t a[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_neg,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 + + xor t3, t3 + + xor a0, a0 + xor a1, a1 + xor a2, a2 + + sub a0, qword [rsi+sizeof(qword)*0] + sbb a1, qword [rsi+sizeof(qword)*1] + sbb a2, qword [rsi+sizeof(qword)*2] + sbb t3, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + test t3, t3 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_neg + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_mul_montl(uint64_t res[3], uint64_t a[3], uint64_t b[3]); +; void p192r1_mul_montx(uint64_t res[3], uint64_t a[3], uint64_t b[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; product = {p3,p2,p1,p0}, p4=0 +; product += 2^192*p0 -2^64*p0 -p0 +; +; on entry p4=0 +; on exit p0=0 +; +%macro p192r1_mul_redstep 5.nolist + %xdefine %%p4 %1 + %xdefine %%p3 %2 + %xdefine %%p2 %3 + %xdefine %%p1 %4 + %xdefine %%p0 %5 + + sub %%p1, %%p0 + sbb %%p2, 0 + sbb %%p0, 0 + add %%p3, %%p0 + adc %%p4, 0 + xor %%p0, %%p0 +%endmacro + +align IPP_ALIGN_FACTOR +p192r1_mmull: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc4, acc4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*0] + mov acc0, rax + mov acc1, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*1] + add acc1, rax + adc rdx, 0 + mov acc2, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*2] + add acc2, rax + adc rdx, 0 + mov acc3, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 0 + p192r1_mul_redstep acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*0] + add acc1, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*1] + add acc2, rcx + adc rdx, 0 + add acc2, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*2] + add acc3, rcx + adc rdx, 0 + add acc3, rax + adc acc4, rdx + adc acc0, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 1 + p192r1_mul_redstep acc0,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*0] + add acc2, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*1] + add acc3, rcx + adc rdx, 0 + add acc3, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*2] + add acc4, rcx + adc rdx, 0 + add acc4, rax + adc acc0, rdx + adc acc1, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 2 (final) + p192r1_mul_redstep acc1,acc0,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t0, acc3 ;; copy reducted result + mov t1, acc4 + mov t2, acc0 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] ;; test %if it exceeds prime value + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb acc1, 0 + + cmovnc acc3, t0 + cmovnc acc4, t1 + cmovnc acc0, t2 + + mov qword [rdi+sizeof(qword)*0], acc3 + mov qword [rdi+sizeof(qword)*1], acc4 + mov qword [rdi+sizeof(qword)*2], acc0 + + ret + +%if (_IPP32E >= _IPP32E_L9) +align IPP_ALIGN_FACTOR +p192r1_mmulx: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc4, acc4 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + xor rdx, rdx + mov rdx, qword [bPtr+sizeof(qword)*0] + mulx acc1,acc0, qword [aPtr+sizeof(qword)*0] + mulx acc2,t2, qword [aPtr+sizeof(qword)*1] + add acc1,t2 + mulx acc3,t2, qword [aPtr+sizeof(qword)*2] + adc acc2,t2 + adc acc3,0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 0 + p192r1_mul_redstep acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rdx, qword [bPtr+sizeof(qword)*1] + + mulx t0, t2, qword [aPtr+sizeof(qword)*0] + adcx acc1, t2 + adox acc2, t0 + + mulx t0, t2, qword [aPtr+sizeof(qword)*1] + adcx acc2, t2 + adox acc3, t0 + + mulx t0, t2, qword [aPtr+sizeof(qword)*2] + adcx acc3, t2 + adox acc4, t0 + + adcx acc4, acc0 + adox acc0, acc0 + adc acc0, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 1 + p192r1_mul_redstep acc0,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rdx, qword [bPtr+sizeof(qword)*2] + + mulx t0, t2, qword [aPtr+sizeof(qword)*0] + adcx acc2, t2 + adox acc3, t0 + + mulx t0, t2, qword [aPtr+sizeof(qword)*1] + adcx acc3, t2 + adox acc4, t0 + + mulx t0, t2, qword [aPtr+sizeof(qword)*2] + adcx acc4, t2 + adox acc0, t0 + + adcx acc0, acc1 + adox acc1, acc1 + adc acc1, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 2 (final) + p192r1_mul_redstep acc1,acc0,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t0, acc3 ;; copy reducted result + mov t1, acc4 + mov t2, acc0 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] ;; test %if it exceeds prime value + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb acc1, 0 + + cmovnc acc3, t0 + cmovnc acc4, t1 + cmovnc acc0, t2 + + mov qword [rdi+sizeof(qword)*0], acc3 + mov qword [rdi+sizeof(qword)*1], acc4 + mov qword [rdi+sizeof(qword)*2], acc0 + + ret +%endif + +align IPP_ALIGN_FACTOR +IPPASM p192r1_mul_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call p192r1_mmull + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_mul_montl + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +IPPASM p192r1_mul_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call p192r1_mmulx + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_mul_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_to_mont(uint64_t res[3], uint64_t a[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_to_mont,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + + lea rbx, [rel LRR] + call p192r1_mmull + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_to_mont + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_sqr_montl(uint64_t res[3], uint64_t a[3]); +; void p192r1_sqr_montx(uint64_t res[3], uint64_t a[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; on entry e = expasion (previous step) +; on exit p0= expasion (next step) +; +%macro p192r1_prod_redstep 5.nolist + %xdefine %%e %1 + %xdefine %%p3 %2 + %xdefine %%p2 %3 + %xdefine %%p1 %4 + %xdefine %%p0 %5 + + sub %%p1, %%p0 + sbb %%p2, 0 + sbb %%p0, 0 + add %%p3, %%p0 + mov %%p0, dword 0 + adc %%p0, 0 + + %ifnempty %%e + add %%p3, %%e + adc %%p0, 0 + %endif +%endmacro + +align IPP_ALIGN_FACTOR +IPPASM p192r1_sqr_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*0] + mov rax,qword [aPtr+sizeof(qword)*1] + mul t2 + mov acc1, rax + mov acc2, rdx + mov rax,qword [aPtr+sizeof(qword)*2] + mul t2 + add acc2, rax + adc rdx, 0 + mov acc3, rdx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*1] + mov rax,qword [aPtr+sizeof(qword)*2] + mul t2 + add acc3, rax + adc rdx, 0 + mov acc4, rdx + + xor acc5, acc5 + shld acc5, acc4, 1 + shld acc4, acc3, 1 + shld acc3, acc2, 1 + shld acc2, acc1, 1 + shl acc1, 1 + + mov rax,qword [aPtr+sizeof(qword)*0] + mul rax + mov acc0, rax + add acc1, rdx + adc acc2, 0 + mov rax,qword [aPtr+sizeof(qword)*1] + mul rax + add acc2, rax + adc acc3, rdx + adc acc4, 0 + mov rax,qword [aPtr+sizeof(qword)*2] + mul rax + add acc4, rax + adc acc5, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + p192r1_prod_redstep ,acc3,acc2,acc1,acc0 + p192r1_prod_redstep acc0,acc4,acc3,acc2,acc1 + p192r1_prod_redstep acc1,acc5,acc4,acc3,acc2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, acc3 + mov t1, acc4 + mov t2, acc5 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb acc2, 0 + + cmovnc acc3, t0 + cmovnc acc4, t1 + cmovnc acc5, t2 + + mov qword [rdi+sizeof(qword)*0], acc3 + mov qword [rdi+sizeof(qword)*1], acc4 + mov qword [rdi+sizeof(qword)*2], acc5 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_sqr_montl + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +IPPASM p192r1_sqr_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 + +%xdefine t0 rcx +%xdefine t1 rax +%xdefine t2 rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*0] + mulx acc2, acc1, qword [aPtr+sizeof(qword)*1] + mulx acc3, t0, qword [aPtr+sizeof(qword)*2] + add acc2, t0 + adc acc3, 0 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*1] + mulx acc4, t0, qword [aPtr+sizeof(qword)*2] + add acc3, t0 + adc acc4, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor acc5, acc5 + shld acc5, acc4, 1 + shld acc4, acc3, 1 + shld acc3, acc2, 1 + shld acc2, acc1, 1 + shl acc1, 1 + + xor acc0, acc0 + mov rdx, qword [aPtr+sizeof(qword)*0] + mulx t1, acc0, rdx + adcx acc1, t1 + mov rdx, qword [aPtr+sizeof(qword)*1] + mulx t1, t0, rdx + adcx acc2, t0 + adcx acc3, t1 + mov rdx, qword [aPtr+sizeof(qword)*2] + mulx t1, t0, rdx + adcx acc4, t0 + adcx acc5, t1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + p192r1_prod_redstep ,acc3,acc2,acc1,acc0 + p192r1_prod_redstep acc0,acc4,acc3,acc2,acc1 + p192r1_prod_redstep acc1,acc5,acc4,acc3,acc2 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, acc3 + mov t1, acc4 + mov t2, acc5 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb acc2, 0 + + cmovnc acc3, t0 + cmovnc acc4, t1 + cmovnc acc5, t2 + + mov qword [rdi+sizeof(qword)*0], acc3 + mov qword [rdi+sizeof(qword)*1], acc4 + mov qword [rdi+sizeof(qword)*2], acc5 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_sqr_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_mont_back(uint64_t res[3], uint64_t a[3]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_mont_back,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 rsi + + mov acc2, qword [rsi+sizeof(qword)*0] + mov acc3, qword [rsi+sizeof(qword)*1] + mov acc4, qword [rsi+sizeof(qword)*2] + xor acc0, acc0 + xor acc1, acc1 + + p192r1_mul_redstep acc1,acc0,acc4,acc3,acc2 + p192r1_mul_redstep acc2,acc1,acc0,acc4,acc3 + p192r1_mul_redstep acc3,acc2,acc1,acc0,acc4 + + mov t0, acc0 + mov t1, acc1 + mov t2, acc2 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb acc4, 0 + + cmovnc acc0, t0 + cmovnc acc1, t1 + cmovnc acc2, t2 + + mov qword [rdi+sizeof(qword)*0], acc0 + mov qword [rdi+sizeof(qword)*1], acc1 + mov qword [rdi+sizeof(qword)*2], acc2 + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_mont_back + + +%ifndef _DISABLE_ECP_192R1_HARDCODED_BP_TBL_ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p192r1_select_ap_w7(AF_POINT *val, const AF_POINT *in_t, int index); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p192r1_select_ap_w7,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7,xmm8,xmm9 + COMP_ABI 3 + +%xdefine val rdi +%xdefine in_t rsi +%xdefine idx edx + +%xdefine ONE xmm0 +%xdefine INDEX xmm1 + +%xdefine Ra xmm2 +%xdefine Rb xmm3 +%xdefine Rc xmm4 + +%xdefine T0a xmm5 +%xdefine T0b xmm6 +%xdefine T0c xmm7 + +%xdefine M0 xmm8 +%xdefine TMP0 xmm9 + + movdqa ONE, oword [rel LOne] + + pxor Ra, Ra + pxor Rb, Rb + pxor Rc, Rc + + movdqa M0, ONE + + movd INDEX, idx + pshufd INDEX, INDEX, 0 + + ; Skip index = 0, is implicictly infty -> load with offset -1 + mov rcx, dword 64 +.select_loop_sse_w7: + movdqa TMP0, M0 + pcmpeqd TMP0, INDEX + paddd M0, ONE + + movdqa T0a, oword [in_t+sizeof(oword)*0] + movdqa T0b, oword [in_t+sizeof(oword)*1] + movdqa T0c, oword [in_t+sizeof(oword)*2] + add in_t, sizeof(oword)*3 + + pand T0a, TMP0 + pand T0b, TMP0 + pand T0c, TMP0 + + por Ra, T0a + por Rb, T0b + por Rc, T0c + dec rcx + jnz .select_loop_sse_w7 + + movdqu oword [val+sizeof(oword)*0], Ra + movdqu oword [val+sizeof(oword)*1], Rb + movdqu oword [val+sizeof(oword)*2], Rc + + REST_XMM + REST_GPR + ret +ENDFUNC p192r1_select_ap_w7 + +%endif + +%endif ;; _IPP32E_M7 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp224r1funcs_montas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp224r1funcs_montas.asm new file mode 100644 index 000000000..ac2dba640 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp224r1funcs_montas.asm @@ -0,0 +1,1066 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; secp p224r1 specific implementation +; + + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +%assign _xEMULATION_ 1 +%assign _ADCX_ADOX_ 1 + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +;; The p224r1 polynomial +Lpoly DQ 00000000000000001h,0ffffffff00000000h,0ffffffffffffffffh,000000000ffffffffh + +;; mont(1) +;; ffffffff00000000 ffffffffffffffff 0000000000000000 0000000000000000 + +;; 2^(2*224) mod P precomputed for p224r1 polynomial +LRR DQ 0ffffffff00000001h,0ffffffff00000000h,0fffffffe00000000h,000000000ffffffffh + +LOne DD 1,1,1,1,1,1,1,1 +LTwo DD 2,2,2,2,2,2,2,2 +LThree DD 3,3,3,3,3,3,3,3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_mul_by_2(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_mul_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + shld t4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_mul_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_div_by_2(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_div_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + xor t4, t4 + xor r14, r14 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + adc t4, 0 + test a0, 1 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + cmovnz r14,t4 + + shrd a0, a1, 1 + shrd a1, a2, 1 + shrd a2, a3, 1 + shrd a3, r14,1 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_div_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_mul_by_3(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_mul_by_3,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + shld t4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + xor t4, t4 + add a0, qword [rsi+sizeof(qword)*0] + adc a1, qword [rsi+sizeof(qword)*1] + adc a2, qword [rsi+sizeof(qword)*2] + adc a3, qword [rsi+sizeof(qword)*3] + adc t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_mul_by_3 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_add,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + add a0, qword [rdx+sizeof(qword)*0] + adc a1, qword [rdx+sizeof(qword)*1] + adc a2, qword [rdx+sizeof(qword)*2] + adc a3, qword [rdx+sizeof(qword)*3] + adc t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_add + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_sub,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + sub a0, qword [rdx+sizeof(qword)*0] + sbb a1, qword [rdx+sizeof(qword)*1] + sbb a2, qword [rdx+sizeof(qword)*2] + sbb a3, qword [rdx+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_sub + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_neg(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_neg,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + xor a0, a0 + xor a1, a1 + xor a2, a2 + xor a3, a3 + + sub a0, qword [rsi+sizeof(qword)*0] + sbb a1, qword [rsi+sizeof(qword)*1] + sbb a2, qword [rsi+sizeof(qword)*2] + sbb a3, qword [rsi+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_neg + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_mul_montl(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; void p224r1_mul_montx(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; was working on GFp functionality the problem (in reduction spep) has been found +;; 1) "sqr" impementation has been changed by "mul" +;; 2) fortunately "mont_back" stay as is because of operand zero extensioned + +; on entry p5=0 +; on exit p0=0 +; +%macro p224r1_prod_redstep 5.nolist + %xdefine %%p4 %1 + %xdefine %%p3 %2 + %xdefine %%p2 %3 + %xdefine %%p1 %4 + %xdefine %%p0 %5 + + neg %%p0 + mov t2, %%p0 + mov t3, %%p0 + xor t0, t0 + xor t1, t1 + shr t3, 32 + shl t2, 32 + sub t0, t2 + sbb t1, t3 + sbb t2, 0 + sbb t3, 0 + + neg %%p0 + adc %%p1, t0 + adc %%p2, t1 + adc %%p3, t2 + adc %%p4, t3 +%endmacro + +align IPP_ALIGN_FACTOR +p224r1_mmull: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 rbp +%xdefine t4 rbx + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc5, acc5 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*0] + mov acc0, rax + mov acc1, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*1] + add acc1, rax + adc rdx, 0 + mov acc2, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*2] + add acc2, rax + adc rdx, 0 + mov acc3, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*3] + add acc3, rax + adc rdx, 0 + mov acc4, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 0 + p224r1_prod_redstep acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*0] + add acc1, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*1] + add acc2, rcx + adc rdx, 0 + add acc2, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*2] + add acc3, rcx + adc rdx, 0 + add acc3, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*3] + add acc4, rcx + adc rdx, 0 + add acc4, rax + adc rdx, 0 + mov acc5, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 1 + p224r1_prod_redstep acc5,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*0] + add acc2, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*1] + add acc3, rcx + adc rdx, 0 + add acc3, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*2] + add acc4, rcx + adc rdx, 0 + add acc4, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*3] + add acc5, rcx + adc rdx, 0 + add acc5, rax + adc rdx, 0 + mov acc6, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 2 + p224r1_prod_redstep acc6,acc5,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[3] + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*0] + add acc3, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*1] + add acc4, rcx + adc rdx, 0 + add acc4, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*2] + add acc5, rcx + adc rdx, 0 + add acc5, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*3] + add acc6, rcx + adc rdx, 0 + add acc6, rax + adc rdx, 0 + mov acc7, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 3 (final) + p224r1_prod_redstep acc7,acc6,acc5,acc4,acc3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov acc0, acc4 ;; copy reducted result + mov acc1, acc5 + mov acc2, acc6 + mov acc3, acc7 + + sub acc4, t0 ;; test %if it exceeds prime value + sbb acc5, t1 + sbb acc6, t2 + sbb acc7, t3 + + cmovc acc4, acc0 + cmovc acc5, acc1 + cmovc acc6, acc2 + cmovc acc7, acc3 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc6 + mov qword [rdi+sizeof(qword)*3], acc7 + + ret + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +p224r1_mmulx: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 rbp +%xdefine t4 rbx + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc5, acc5 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + mov rdx, qword [bPtr+sizeof(qword)*0] + mulx acc1,acc0, qword [aPtr+sizeof(qword)*0] + mulx acc2,t2, qword [aPtr+sizeof(qword)*1] + add acc1,t2 + mulx acc3,t2, qword [aPtr+sizeof(qword)*2] + adc acc2,t2 + mulx acc4,t2, qword [aPtr+sizeof(qword)*3] + adc acc3,t2 + adc acc4,0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 0 + p224r1_prod_redstep acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rdx, qword [bPtr+sizeof(qword)*1] + xor t0, t0 + + mulx t3, t2, qword [aPtr+sizeof(qword)*0] + adcx acc1, t2 + adox acc2, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*1] + adcx acc2, t2 + adox acc3, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*2] + adcx acc3, t2 + adox acc4, t3 + + mulx acc5, t2, qword [aPtr+sizeof(qword)*3] + adcx acc4, t2 + adox acc5, t0 + adc acc5, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 1 + p224r1_prod_redstep acc5,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rdx, qword [bPtr+sizeof(qword)*2] + xor t0, t0 + + mulx t3, t2, qword [aPtr+sizeof(qword)*0] + adcx acc2, t2 + adox acc3, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*1] + adcx acc3, t2 + adox acc4, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*2] + adcx acc4, t2 + adox acc5, t3 + + mulx acc6, t2, qword [aPtr+sizeof(qword)*3] + adcx acc5, t2 + adox acc6, t0 + adc acc6, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 2 + p224r1_prod_redstep acc6,acc5,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[3] + mov rdx, qword [bPtr+sizeof(qword)*3] + xor t0, t0 + + mulx t3, t2, qword [aPtr+sizeof(qword)*0] + adcx acc3, t2 + adox acc4, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*1] + adcx acc4, t2 + adox acc5, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*2] + adcx acc5, t2 + adox acc6, t3 + + mulx acc7, t2, qword [aPtr+sizeof(qword)*3] + adcx acc6, t2 + adox acc7, t0 + adc acc7, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 3 (final) + p224r1_prod_redstep acc7,acc6,acc5,acc4,acc3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov acc0, acc4 ;; copy reducted result + mov acc1, acc5 + mov acc2, acc6 + mov acc3, acc7 + + sub acc4, t0 ;; test %if it exceeds prime value + sbb acc5, t1 + sbb acc6, t2 + sbb acc7, t3 + + cmovc acc4, acc0 + cmovc acc5, acc1 + cmovc acc6, acc2 + cmovc acc7, acc3 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc6 + mov qword [rdi+sizeof(qword)*3], acc7 + + ret +%endif + +IPPASM p224r1_mul_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call p224r1_mmull + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_mul_montl + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +IPPASM p224r1_mul_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call p224r1_mmulx + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_mul_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_to_mont(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_to_mont,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + + lea rbx, [rel LRR] + call p224r1_mmull + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_to_mont + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_sqr_montl(uint64_t res[4], uint64_t a[4]); +; void p224r1_sqr_montx(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_sqr_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + + mov rbx, rsi + call p224r1_mmull + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_sqr_montl + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +IPPASM p224r1_sqr_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + + mov rbx, rsi + call p224r1_mmulx + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_sqr_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_mont_back(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_mont_back,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 rsi + + mov acc0, qword [rsi+sizeof(qword)*0] + mov acc1, qword [rsi+sizeof(qword)*1] + mov acc2, qword [rsi+sizeof(qword)*2] + mov acc3, qword [rsi+sizeof(qword)*3] + xor acc4, acc4 + xor acc5, acc5 + xor acc6, acc6 + xor acc7, acc7 + + p224r1_prod_redstep acc4,acc3,acc2,acc1,acc0 + p224r1_prod_redstep acc5,acc4,acc3,acc2,acc1 + p224r1_prod_redstep acc6,acc5,acc4,acc3,acc2 + p224r1_prod_redstep acc7,acc6,acc5,acc4,acc3 + + mov acc0, acc4 + mov acc1, acc5 + mov acc2, acc6 + mov acc3, acc7 + + sub acc4, qword [rel Lpoly+sizeof(qword)*0] + sbb acc5, qword [rel Lpoly+sizeof(qword)*1] + sbb acc6, qword [rel Lpoly+sizeof(qword)*2] + sbb acc7, qword [rel Lpoly+sizeof(qword)*3] + + cmovc acc4, acc0 + cmovc acc5, acc1 + cmovc acc6, acc2 + cmovc acc7, acc3 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc6 + mov qword [rdi+sizeof(qword)*3], acc7 + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_mont_back + +%ifndef _DISABLE_ECP_224R1_HARDCODED_BP_TBL_ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p224r1_select_ap_w7(AF_POINT *val, const AF_POINT *in_t, int index); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p224r1_select_ap_w7,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 + COMP_ABI 3 + +%xdefine val rdi +%xdefine in_t rsi +%xdefine idx edx + +%xdefine ONE xmm0 +%xdefine INDEX xmm1 + +%xdefine Ra xmm2 +%xdefine Rb xmm3 +%xdefine Rc xmm4 +%xdefine Rd xmm5 + +%xdefine M0 xmm8 +%xdefine T0a xmm9 +%xdefine T0b xmm10 +%xdefine T0c xmm11 +%xdefine T0d xmm12 +%xdefine TMP0 xmm15 + + movdqa ONE, oword [rel LOne] + + pxor Ra, Ra + pxor Rb, Rb + pxor Rc, Rc + pxor Rd, Rd + + movdqa M0, ONE + + movd INDEX, idx + pshufd INDEX, INDEX, 0 + + ; Skip index = 0, is implicictly infty -> load with offset -1 + mov rcx, dword 64 +.select_loop_sse_w7: + movdqa TMP0, M0 + pcmpeqd TMP0, INDEX + paddd M0, ONE + + movdqa T0a, oword [in_t+sizeof(oword)*0] + movdqa T0b, oword [in_t+sizeof(oword)*1] + movdqa T0c, oword [in_t+sizeof(oword)*2] + movdqa T0d, oword [in_t+sizeof(oword)*3] + add in_t, sizeof(oword)*4 + + pand T0a, TMP0 + pand T0b, TMP0 + pand T0c, TMP0 + pand T0d, TMP0 + + por Ra, T0a + por Rb, T0b + por Rc, T0c + por Rd, T0d + dec rcx + jnz .select_loop_sse_w7 + + movdqu oword [val+sizeof(oword)*0], Ra + movdqu oword [val+sizeof(oword)*1], Rb + movdqu oword [val+sizeof(oword)*2], Rc + movdqu oword [val+sizeof(oword)*3], Rd + + REST_XMM + REST_GPR + ret +ENDFUNC p224r1_select_ap_w7 + +%endif + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp256funcs_montas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp256funcs_montas.asm new file mode 100644 index 000000000..40675b79f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp256funcs_montas.asm @@ -0,0 +1,677 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; 256-bit modular arithmetic +; + +; +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Ipp64u* gf256_add(Ipp64u res[4], Ipp64u a[4], Ipp64u b[4], Ipp64u poly[4]) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM gf256_add,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14 + USES_XMM + COMP_ABI 4 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 r12 +%xdefine t3 r13 +%xdefine t4 r14 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] ; a[] = A + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + add a0, qword [rdx+sizeof(qword)*0] ; a[] = a[]+b[] + adc a1, qword [rdx+sizeof(qword)*1] + adc a2, qword [rdx+sizeof(qword)*2] + adc a3, qword [rdx+sizeof(qword)*3] + adc t4, 0 + + mov t0, a0 ; save result t[] = a[] + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rcx+sizeof(qword)*0] ; t[] = a[]+b[] -poly[] + sbb t1, qword [rcx+sizeof(qword)*1] + sbb t2, qword [rcx+sizeof(qword)*2] + sbb t3, qword [rcx+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 ; A = a:t + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + mov rax, rdi ; return pointer to result + + REST_XMM + REST_GPR + ret +ENDFUNC gf256_add + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Ipp64u* gf256_sub(Ipp64u res[4], Ipp64u a[4], Ipp64u b[4], Ipp64u poly[4]) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM gf256_sub,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14 + USES_XMM + COMP_ABI 4 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 r12 +%xdefine t3 r13 +%xdefine t4 r14 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] ; a[] = A + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + sub a0, qword [rdx+sizeof(qword)*0] ; a[] = a[]-b[] + sbb a1, qword [rdx+sizeof(qword)*1] + sbb a2, qword [rdx+sizeof(qword)*2] + sbb a3, qword [rdx+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 ; save result t[] = a[] + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rcx+sizeof(qword)*0] ; t[] = a[]-b[] +poly[] + adc t1, qword [rcx+sizeof(qword)*1] + adc t2, qword [rcx+sizeof(qword)*2] + adc t3, qword [rcx+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 ; A = a:t + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + mov rax, rdi ; return pointer to result + + REST_XMM + REST_GPR + ret +ENDFUNC gf256_sub + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Ipp64u* gf256_neg(Ipp64u res[4], Ipp64u a[4], Ipp64u poly[4]) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM gf256_neg,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rcx +%xdefine t2 r12 +%xdefine t3 r13 +%xdefine t4 r14 + + xor t4, t4 + + xor a0, a0 ; a[] = 0; + xor a1, a1 + xor a2, a2 + xor a3, a3 + + sub a0, qword [rsi+sizeof(qword)*0] ; a[] = -a[] + sbb a1, qword [rsi+sizeof(qword)*1] + sbb a2, qword [rsi+sizeof(qword)*2] + sbb a3, qword [rsi+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 ; t[] = a[] + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rdx+sizeof(qword)*0] ; t[] = -a[] +poly[] + adc t1, qword [rdx+sizeof(qword)*1] + adc t2, qword [rdx+sizeof(qword)*2] + adc t3, qword [rdx+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 ; A = a:t + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + mov rax, rdi ; return pointer to result + + REST_XMM + REST_GPR + ret +ENDFUNC gf256_neg + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Ipp64u* gf256_div2(Ipp64u res[4], Ipp64u a[4], Ipp64u poly[4]) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM gf256_div2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rcx +%xdefine t2 r12 +%xdefine t3 r13 +%xdefine t4 r14 + + mov a0, qword [rsi+sizeof(qword)*0] ; a[] = A + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + xor t4, t4 + xor rsi, rsi + + mov t0, a0 ; t[] = A + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rdx+sizeof(qword)*0] ; t[] += poly[] + adc t1, qword [rdx+sizeof(qword)*1] + adc t2, qword [rdx+sizeof(qword)*2] + adc t3, qword [rdx+sizeof(qword)*3] + adc t4, 0 + + test a0, 1 ; %if (A[0] & 1) + cmovnz a0, t0 ; a[] = t[] + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + cmovnz rsi,t4 + + shrd a0, a1, 1 ; a[] /= 2 + shrd a1, a2, 1 + shrd a2, a3, 1 + shrd a3, rsi,1 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + mov rax, rdi ; return pointer to result + + REST_XMM + REST_GPR + ret +ENDFUNC gf256_div2 + +;; +;; GF256 multiplicative operations +;; +%macro MUL_4x1 8.nolist + %xdefine %%dm %1 + %xdefine %%ACC4 %2 + %xdefine %%ACC3 %3 + %xdefine %%ACC2 %4 + %xdefine %%ACC1 %5 + %xdefine %%ACC0 %6 + %xdefine %%aPtr %7 + %xdefine %%B %8 + + mov rax, qword [%%aPtr+sizeof(qword)*0] + mul %%B + mov %%ACC0,rax + mov %%ACC1,rdx + imul %%dm, %%ACC0 + + mov rax, qword [%%aPtr+sizeof(qword)*1] + mul %%B + add %%ACC1,rax + adc rdx, 0 + mov %%ACC2,rdx + + mov rax, qword [%%aPtr+sizeof(qword)*2] + mul %%B + add %%ACC2,rax + adc rdx, 0 + mov %%ACC3,rdx + + mov rax, qword [%%aPtr+sizeof(qword)*3] + mul %%B + add %%ACC3,rax + adc rdx, 0 + mov %%ACC4,rdx +%endmacro + +%macro MLA_4x1 10.nolist + %xdefine %%dm %1 + %xdefine %%ACC5 %2 + %xdefine %%ACC4 %3 + %xdefine %%ACC3 %4 + %xdefine %%ACC2 %5 + %xdefine %%ACC1 %6 + %xdefine %%ACC0 %7 + %xdefine %%aPtr %8 + %xdefine %%B %9 + %xdefine %%TMP %10 + + mov rax, qword [%%aPtr+sizeof(qword)*0] + mul %%B + add %%ACC0,rax + adc rdx, 0 + mov %%TMP, rdx + imul %%dm, %%ACC0 + + mov rax, qword [%%aPtr+sizeof(qword)*1] + mul %%B + add %%ACC1,%%TMP + adc rdx, 0 + add %%ACC1,rax + adc rdx, 0 + mov %%TMP, rdx + + mov rax, qword [%%aPtr+sizeof(qword)*2] + mul %%B + add %%ACC2,%%TMP + adc rdx, 0 + add %%ACC2,rax + adc rdx, 0 + mov %%TMP, rdx + + mov rax, qword [%%aPtr+sizeof(qword)*3] + mul %%B + add %%ACC3,%%TMP + adc rdx, 0 + add %%ACC3,rax + adc %%ACC4,rdx + adc %%ACC5,0 +%endmacro + +%macro MRED_4x1 8.nolist + %xdefine %%ACC5 %1 + %xdefine %%ACC4 %2 + %xdefine %%ACC3 %3 + %xdefine %%ACC2 %4 + %xdefine %%ACC1 %5 + %xdefine %%ACC0 %6 + %xdefine %%mPtr %7 + %xdefine %%dm %8 + + mov rax, qword [%%mPtr+sizeof(qword)*0] + mul %%dm + add %%ACC0,rax + adc rdx, 0 + mov %%ACC0,rdx + + mov rax, qword [%%mPtr+sizeof(qword)*1] + mul %%dm + add %%ACC1,%%ACC0 + adc rdx, 0 + add %%ACC1,rax + adc rdx, 0 + mov %%ACC0,rdx + + mov rax, qword [%%mPtr+sizeof(qword)*2] + mul %%dm + add %%ACC2,%%ACC0 + adc rdx, 0 + add %%ACC2,rax + adc rdx, 0 + mov %%ACC0,rdx + + mov rax, qword [%%mPtr+sizeof(qword)*3] + mul %%dm + add %%ACC3,%%ACC0 + adc rdx, 0 + add %%ACC3,rax + adc rdx, 0 + add %%ACC4,rdx + + adc %%ACC5,0 + xor %%ACC0,%%ACC0 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Ipp64u* gf256_mulm(Ipp64u res[4], Ipp64u a[4], Ipp64u b[4], Ipp64u poly[4], Ipp64u m0) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM gf256_mulm,PUBLIC +%assign LOCAL_FRAME 2*sizeof(qword) + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14,r15 + USES_XMM + COMP_ABI 5 + +;; stack structure: +%assign res 0 +%assign m0 res+sizeof(qword) + + mov qword [rsp+res], rdi ; save result + mov rbx, rdx ; rbx = bPtr + mov rdi, rcx ; rcx = mPtr + mov qword [rsp+m0], r8 ; save m0 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; P = A[] * b[0] + mov r14, qword [rbx+sizeof(qword)*0] + mov r15, qword [rsp+m0] + MUL_4x1 r15, acc4,acc3,acc2,acc1,acc0, rsi, r14 + + xor acc5,acc5 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step + MRED_4x1 acc5,acc4,acc3,acc2,acc1,acc0, rdi, r15 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; P+= A[] * b[1] + mov r14, qword [rbx+sizeof(qword)*1] + mov r15, qword [rsp+m0] + MLA_4x1 r15, acc0,acc5,acc4,acc3,acc2,acc1, rsi, r14, rcx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step + MRED_4x1 acc0,acc5,acc4,acc3,acc2,acc1, rdi, r15 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; P+= A[] * b[2] + mov r14, qword [rbx+sizeof(qword)*2] + mov r15, qword [rsp+m0] + MLA_4x1 r15, acc1,acc0,acc5,acc4,acc3,acc2, rsi, r14, rcx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step + MRED_4x1 acc1,acc0,acc5,acc4,acc3,acc2, rdi, r15 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; P+= A[] * b[3] + mov r14, qword [rbx+sizeof(qword)*3] + mov r15, qword [rsp+m0] + MLA_4x1 r15, acc2,acc1,acc0,acc5,acc4,acc3, rsi, r14, rcx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step + MRED_4x1 acc2,acc1,acc0,acc5,acc4,acc3, rdi, r15 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; final reduction + mov rsi, qword [rsp+res] ;; restore result address + + mov rax, acc4 ;; copy temporary result + mov rbx, acc5 + mov rcx, acc0 + mov rdx, acc1 + + sub rax, qword [rdi+sizeof(qword)*0] ;; subtract modulus + sbb rbx, qword [rdi+sizeof(qword)*1] + sbb rcx, qword [rdi+sizeof(qword)*2] + sbb rdx, qword [rdi+sizeof(qword)*3] + sbb acc2, 0 + + cmovnc acc4, rax + cmovnc acc5, rbx + cmovnc acc0, rcx + cmovnc acc1, rdx + + mov qword [rsi+sizeof(qword)*0], acc4 + mov qword [rsi+sizeof(qword)*1], acc5 + mov qword [rsi+sizeof(qword)*2], acc0 + mov qword [rsi+sizeof(qword)*3], acc1 + + mov rax, rsi ; return pointer to result + + REST_XMM + REST_GPR + ret +ENDFUNC gf256_mulm + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Ipp64u* gf256_sqrm(Ipp64u res[4], Ipp64u a[4], Ipp64u poly[4], Ipp64u m0) +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM gf256_sqrm,PUBLIC +%assign LOCAL_FRAME 2*sizeof(qword) + USES_GPR rsi,rdi,rbx,rbp,r12,r13,r14,r15 + USES_XMM + COMP_ABI 4 + +;; stack structure: +%assign res 0 +%assign m0 res+sizeof(qword) + + mov qword [rsp+res], rdi ; save result + mov rdi, rdx ; rdi = mPtr + mov qword [rsp+m0], rcx ; save m0 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rcx +%xdefine t1 rbp +%xdefine t2 rbx +%xdefine t3 rdx +%xdefine t4 rax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; diagonal + mov t2, qword [rsi+sizeof(qword)*0] + mov rax,qword [rsi+sizeof(qword)*1] + mul t2 + mov acc1, rax + mov acc2, rdx + mov rax,qword [rsi+sizeof(qword)*2] + mul t2 + add acc2, rax + adc rdx, 0 + mov acc3, rdx + mov rax,qword [rsi+sizeof(qword)*3] + mul t2 + add acc3, rax + adc rdx, 0 + mov acc4, rdx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [rsi+sizeof(qword)*1] + mov rax,qword [rsi+sizeof(qword)*2] + mul t2 + add acc3, rax + adc rdx, 0 + mov t1, rdx + mov rax,qword [rsi+sizeof(qword)*3] + mul t2 + add acc4, rax + adc rdx, 0 + add acc4, t1 + adc rdx, 0 + mov acc5, rdx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [rsi+sizeof(qword)*2] + mov rax,qword [rsi+sizeof(qword)*3] + mul t2 + add acc5, rax + adc rdx, 0 + mov acc6, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; doubling + xor acc7, acc7 + shld acc7, acc6, 1 + shld acc6, acc5, 1 + shld acc5, acc4, 1 + shld acc4, acc3, 1 + shld acc3, acc2, 1 + shld acc2, acc1, 1 + shl acc1, 1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; add sruares + mov rax,qword [rsi+sizeof(qword)*0] + mul rax + mov acc0, rax + add acc1, rdx + adc acc2, 0 + mov rax,qword [rsi+sizeof(qword)*1] + mul rax + add acc2, rax + adc acc3, rdx + adc acc4, 0 + mov rax,qword [rsi+sizeof(qword)*2] + mul rax + add acc4, rax + adc acc5, rdx + adc acc6, 0 + mov rax,qword [rsi+sizeof(qword)*3] + mul rax + add acc6, rax + adc acc7, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction + mov rcx, qword [rsp+m0] ; restore m0 + imul rcx, acc0 + MRED_4x1 acc5,acc4,acc3,acc2,acc1,acc0, rdi, rcx + + mov rcx, qword [rsp+m0] ; restore m0 + imul rcx, acc1 + MRED_4x1 acc6,acc5,acc4,acc3,acc2,acc1, rdi, rcx + + mov rcx, qword [rsp+m0] ; restore m0 + imul rcx, acc2 + MRED_4x1 acc7,acc6,acc5,acc4,acc3,acc2, rdi, rcx + + mov rcx, qword [rsp+m0] ; restore m0 + imul rcx, acc3 + MRED_4x1 acc0,acc7,acc6,acc5,acc4,acc3, rdi, rcx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; final reduction + mov rsi, qword [rsp+res] ;; restore result address + + mov rax, acc4 ;; copy temporary result + mov rbx, acc5 + mov rcx, acc6 + mov rdx, acc7 + + sub rax, qword [rdi+sizeof(qword)*0] ;; subtract modulus + sbb rbx, qword [rdi+sizeof(qword)*1] + sbb rcx, qword [rdi+sizeof(qword)*2] + sbb rdx, qword [rdi+sizeof(qword)*3] + sbb acc0, 0 + + cmovnc acc4, rax + cmovnc acc5, rbx + cmovnc acc6, rcx + cmovnc acc7, rdx + + mov qword [rsi+sizeof(qword)*0], acc4 + mov qword [rsi+sizeof(qword)*1], acc5 + mov qword [rsi+sizeof(qword)*2], acc6 + mov qword [rsi+sizeof(qword)*3], acc7 + + mov rax, rsi ; return pointer to result + + REST_XMM + REST_GPR + ret +ENDFUNC gf256_sqrm + +%endif ;; _IPP32E_M7 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp256r1funcs_montas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp256r1funcs_montas.asm new file mode 100644 index 000000000..5d01202a0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp256r1funcs_montas.asm @@ -0,0 +1,1316 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; secp p256r1 specific implementation +; + + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +%assign _xEMULATION_ 1 +%assign _ADCX_ADOX_ 1 + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +;; The p256r1 polynomial +Lpoly DQ 0FFFFFFFFFFFFFFFFh,000000000FFFFFFFFh,00000000000000000h,0FFFFFFFF00000001h + +;; 2^512 mod P precomputed for p256r1 polynomial +LRR DQ 00000000000000003h,0fffffffbffffffffh,0fffffffffffffffeh,000000004fffffffdh + +LOne DD 1,1,1,1,1,1,1,1 +LTwo DD 2,2,2,2,2,2,2,2 +LThree DD 3,3,3,3,3,3,3,3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_mul_by_2(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_mul_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + shld t4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_mul_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_div_by_2(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_div_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + xor t4, t4 + xor r14, r14 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + adc t4, 0 + test a0, 1 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + cmovnz r14,t4 + + shrd a0, a1, 1 + shrd a1, a2, 1 + shrd a2, a3, 1 + shrd a3, r14,1 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_div_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_mul_by_3(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_mul_by_3,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + shld t4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + xor t4, t4 + add a0, qword [rsi+sizeof(qword)*0] + adc a1, qword [rsi+sizeof(qword)*1] + adc a2, qword [rsi+sizeof(qword)*2] + adc a3, qword [rsi+sizeof(qword)*3] + adc t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_mul_by_3 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_add,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + add a0, qword [rdx+sizeof(qword)*0] + adc a1, qword [rdx+sizeof(qword)*1] + adc a2, qword [rdx+sizeof(qword)*2] + adc a3, qword [rdx+sizeof(qword)*3] + adc t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_add + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_sub,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + sub a0, qword [rdx+sizeof(qword)*0] + sbb a1, qword [rdx+sizeof(qword)*1] + sbb a2, qword [rdx+sizeof(qword)*2] + sbb a3, qword [rdx+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_sub + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_neg(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_neg,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + xor a0, a0 + xor a1, a1 + xor a2, a2 + xor a3, a3 + + sub a0, qword [rsi+sizeof(qword)*0] + sbb a1, qword [rsi+sizeof(qword)*1] + sbb a2, qword [rsi+sizeof(qword)*2] + sbb a3, qword [rsi+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_neg + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_mul_montl(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; on entry p5=0 +; on exit p0=0 +; +%macro p256r1_mul_redstep 6.nolist + %xdefine %%p5 %1 + %xdefine %%p4 %2 + %xdefine %%p3 %3 + %xdefine %%p2 %4 + %xdefine %%p1 %5 + %xdefine %%p0 %6 + + mov t0, %%p0 + shl t0, 32 + mov t1, %%p0 + shr t1, 32 ;; (t1:t0) = p0*2^32 + + mov t2, %%p0 + mov t3, %%p0 + xor %%p0, %%p0 + sub t2, t0 + sbb t3, t1 ;; (t3:t2) = (p0*2^64+p0) - p0*2^32 + + add %%p1, t0 ;; (p2:p1) += (t1:t0) + adc %%p2, t1 + adc %%p3, t2 ;; (p4:p3) += (t3:t2) + adc %%p4, t3 + adc %%p5, 0 ;; extension = {0/1} +%endmacro + +align IPP_ALIGN_FACTOR +p256r1_mmull: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 rbp +%xdefine t4 rbx + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc5, acc5 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*0] + mov acc0, rax + mov acc1, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*1] + add acc1, rax + adc rdx, 0 + mov acc2, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*2] + add acc2, rax + adc rdx, 0 + mov acc3, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*3] + add acc3, rax + adc rdx, 0 + mov acc4, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 0 + p256r1_mul_redstep acc5,acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*0] + add acc1, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*1] + add acc2, rcx + adc rdx, 0 + add acc2, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*2] + add acc3, rcx + adc rdx, 0 + add acc3, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*3] + add acc4, rcx + adc rdx, 0 + add acc4, rax + adc acc5, rdx + adc acc0, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 1 + p256r1_mul_redstep acc0,acc5,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*0] + add acc2, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*1] + add acc3, rcx + adc rdx, 0 + add acc3, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*2] + add acc4, rcx + adc rdx, 0 + add acc4, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*3] + add acc5, rcx + adc rdx, 0 + add acc5, rax + adc acc0, rdx + adc acc1, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 2 + p256r1_mul_redstep acc1,acc0,acc5,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[3] + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*0] + add acc3, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*1] + add acc4, rcx + adc rdx, 0 + add acc4, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*2] + add acc5, rcx + adc rdx, 0 + add acc5, rax + adc rdx, 0 + mov rcx, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*3] + add acc0, rcx + adc rdx, 0 + add acc0, rax + adc acc1, rdx + adc acc2, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 3 (final) + p256r1_mul_redstep acc2,acc1,acc0,acc5,acc4,acc3 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 ;; copy reducted result + mov acc3, acc5 + mov acc6, acc0 + mov acc7, acc1 + + sub t4, t0 ;; test %if it exceeds prime value + sbb acc3, t1 + sbb acc6, t2 + sbb acc7, t3 + sbb acc2, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc3 + cmovnc acc0, acc6 + cmovnc acc1, acc7 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc0 + mov qword [rdi+sizeof(qword)*3], acc1 + + ret + +align IPP_ALIGN_FACTOR +IPPASM p256r1_mul_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call p256r1_mmull + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_mul_montl + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_to_mont(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_to_mont,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + + lea rbx, [rel LRR] + call p256r1_mmull + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_to_mont + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_mul_montx(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +p256r1_mmulx: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 rbp +%xdefine t4 rbx + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc5, acc5 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + xor rdx, rdx + mov rdx, qword [bPtr+sizeof(qword)*0] + mulx acc1,acc0, qword [aPtr+sizeof(qword)*0] + mulx acc2,t2, qword [aPtr+sizeof(qword)*1] + add acc1,t2 + mulx acc3,t2, qword [aPtr+sizeof(qword)*2] + adc acc2,t2 + mulx acc4,t2, qword [aPtr+sizeof(qword)*3] + adc acc3,t2 + adc acc4,0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 0 + p256r1_mul_redstep acc5,acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rdx, qword [bPtr+sizeof(qword)*1] + + mulx t3, t2, qword [aPtr+sizeof(qword)*0] + adcx acc1, t2 + adox acc2, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*1] + adcx acc2, t2 + adox acc3, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*2] + adcx acc3, t2 + adox acc4, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*3] + adcx acc4, t2 + adox acc5, t3 + + adcx acc5, acc0 + adox acc0, acc0 + adc acc0, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 1 + p256r1_mul_redstep acc0,acc5,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rdx, qword [bPtr+sizeof(qword)*2] + + mulx t3, t2, qword [aPtr+sizeof(qword)*0] + adcx acc2, t2 + adox acc3, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*1] + adcx acc3, t2 + adox acc4, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*2] + adcx acc4, t2 + adox acc5, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*3] + adcx acc5, t2 + adox acc0, t3 + + adcx acc0, acc1 + adox acc1, acc1 + + adc acc1, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 2 + p256r1_mul_redstep acc1,acc0,acc5,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[3] + mov rdx, qword [bPtr+sizeof(qword)*3] + + mulx t3, t2, qword [aPtr+sizeof(qword)*0] + adcx acc3, t2 + adox acc4, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*1] + adcx acc4, t2 + adox acc5, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*2] + adcx acc5, t2 + adox acc0, t3 + + mulx t3, t2, qword [aPtr+sizeof(qword)*3] + adcx acc0, t2 + adox acc1, t3 + + adcx acc1, acc2 + adox acc2, acc2 + adc acc2, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 3 (final) + p256r1_mul_redstep acc2,acc1,acc0,acc5,acc4,acc3 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 ;; copy reducted result + mov acc3, acc5 + mov acc6, acc0 + mov acc7, acc1 + + sub t4, t0 ;; test %if it exceeds prime value + sbb acc3, t1 + sbb acc6, t2 + sbb acc7, t3 + sbb acc2, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc3 + cmovnc acc0, acc6 + cmovnc acc1, acc7 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc0 + mov qword [rdi+sizeof(qword)*3], acc1 + + ret +%endif + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +IPPASM p256r1_mul_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call p256r1_mmulx + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_mul_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_sqr_montl(uint64_t res[4], uint64_t a[4]); +; void p256r1_sqr_montx(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; on entry e = expasion (previous step) +; on exit p0= expasion (next step) +; +%macro p256r1_prod_redstep 6.nolist + %xdefine %%e %1 + %xdefine %%p4 %2 + %xdefine %%p3 %3 + %xdefine %%p2 %4 + %xdefine %%p1 %5 + %xdefine %%p0 %6 + + mov t0, %%p0 + shl t0, 32 + mov t1, %%p0 + shr t1, 32 ;; (t1:t0) = p0*2^32 + + mov t2, %%p0 + mov t3, %%p0 + xor %%p0, %%p0 + sub t2, t0 + sbb t3, t1 ;; (t3:t2) = (p0*2^64+p0) - p0*2^32 + + add %%p1, t0 ;; (p2:p1) += (t1:t0) + adc %%p2, t1 + adc %%p3, t2 ;; (p4:p3) += (t3:t2) + adc %%p4, t3 + adc %%p0, 0 ;; extension = {0/1} + + %ifnempty %%e + add %%p4, %%e + adc %%p0, 0 + %endif + +%endmacro + +align IPP_ALIGN_FACTOR +IPPASM p256r1_sqr_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rcx +%xdefine t1 rbp +%xdefine t2 rbx +%xdefine t3 rdx +%xdefine t4 rax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*0] + mov rax,qword [aPtr+sizeof(qword)*1] + mul t2 + mov acc1, rax + mov acc2, rdx + mov rax,qword [aPtr+sizeof(qword)*2] + mul t2 + add acc2, rax + adc rdx, 0 + mov acc3, rdx + mov rax,qword [aPtr+sizeof(qword)*3] + mul t2 + add acc3, rax + adc rdx, 0 + mov acc4, rdx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*1] + mov rax,qword [aPtr+sizeof(qword)*2] + mul t2 + add acc3, rax + adc rdx, 0 + mov t1, rdx + mov rax,qword [aPtr+sizeof(qword)*3] + mul t2 + add acc4, rax + adc rdx, 0 + add acc4, t1 + adc rdx, 0 + mov acc5, rdx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*2] + mov rax,qword [aPtr+sizeof(qword)*3] + mul t2 + add acc5, rax + adc rdx, 0 + mov acc6, rdx + + xor acc7, acc7 + shld acc7, acc6, 1 + shld acc6, acc5, 1 + shld acc5, acc4, 1 + shld acc4, acc3, 1 + shld acc3, acc2, 1 + shld acc2, acc1, 1 + shl acc1, 1 + + mov rax,qword [aPtr+sizeof(qword)*0] + mul rax + mov acc0, rax + add acc1, rdx + adc acc2, 0 + mov rax,qword [aPtr+sizeof(qword)*1] + mul rax + add acc2, rax + adc acc3, rdx + adc acc4, 0 + mov rax,qword [aPtr+sizeof(qword)*2] + mul rax + add acc4, rax + adc acc5, rdx + adc acc6, 0 + mov rax,qword [aPtr+sizeof(qword)*3] + mul rax + add acc6, rax + adc acc7, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + p256r1_prod_redstep ,acc4,acc3,acc2,acc1,acc0 + p256r1_prod_redstep acc0,acc5,acc4,acc3,acc2,acc1 + p256r1_prod_redstep acc1,acc6,acc5,acc4,acc3,acc2 + p256r1_prod_redstep acc2,acc7,acc6,acc5,acc4,acc3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 + mov acc0, acc5 + mov acc1, acc6 + mov acc2, acc7 + + sub t4, t0 + sbb acc0, t1 + sbb acc1, t2 + sbb acc2, t3 + sbb acc3, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc0 + cmovnc acc6, acc1 + cmovnc acc7, acc2 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc6 + mov qword [rdi+sizeof(qword)*3], acc7 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_sqr_montl + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +IPPASM p256r1_sqr_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rcx +%xdefine t1 rbp +%xdefine t2 rbx +%xdefine t3 rdx +%xdefine t4 rax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*0] + mulx acc2, acc1, qword [aPtr+sizeof(qword)*1] + mulx acc3, t0, qword [aPtr+sizeof(qword)*2] + add acc2, t0 + mulx acc4, t0, qword [aPtr+sizeof(qword)*3] + adc acc3, t0 + adc acc4, 0 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*1] + xor acc5, acc5 + mulx t1, t0, qword [aPtr+sizeof(qword)*2] + adcx acc3, t0 + adox acc4, t1 + mulx t1, t0, qword [aPtr+sizeof(qword)*3] + adcx acc4, t0 + adox acc5, t1 + adc acc5, 0 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*2] + mulx acc6, t0, qword [aPtr+sizeof(qword)*3] + add acc5, t0 + adc acc6, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor acc7, acc7 + shld acc7, acc6, 1 + shld acc6, acc5, 1 + shld acc5, acc4, 1 + shld acc4, acc3, 1 + shld acc3, acc2, 1 + shld acc2, acc1, 1 + shl acc1, 1 + + xor acc0, acc0 + mov rdx, qword [aPtr+sizeof(qword)*0] + mulx t1, acc0, rdx + adcx acc1, t1 + mov rdx, qword [aPtr+sizeof(qword)*1] + mulx t1, t0, rdx + adcx acc2, t0 + adcx acc3, t1 + mov rdx, qword [aPtr+sizeof(qword)*2] + mulx t1, t0, rdx + adcx acc4, t0 + adcx acc5, t1 + mov rdx, qword [aPtr+sizeof(qword)*3] + mulx t1, t0, rdx + adcx acc6, t0 + adcx acc7, t1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + p256r1_prod_redstep ,acc4,acc3,acc2,acc1,acc0 + p256r1_prod_redstep acc0,acc5,acc4,acc3,acc2,acc1 + p256r1_prod_redstep acc1,acc6,acc5,acc4,acc3,acc2 + p256r1_prod_redstep acc2,acc7,acc6,acc5,acc4,acc3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 + mov acc0, acc5 + mov acc1, acc6 + mov acc2, acc7 + + sub t4, t0 + sbb acc0, t1 + sbb acc1, t2 + sbb acc2, t3 + sbb acc3, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc0 + cmovnc acc6, acc1 + cmovnc acc7, acc2 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc6 + mov qword [rdi+sizeof(qword)*3], acc7 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_sqr_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_mont_back(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_mont_back,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 rsi + + mov acc2, qword [rsi+sizeof(qword)*0] + mov acc3, qword [rsi+sizeof(qword)*1] + mov acc4, qword [rsi+sizeof(qword)*2] + mov acc5, qword [rsi+sizeof(qword)*3] + xor acc0, acc0 + xor acc1, acc1 + + p256r1_mul_redstep acc1,acc0,acc5,acc4,acc3,acc2 + p256r1_mul_redstep acc2,acc1,acc0,acc5,acc4,acc3 + p256r1_mul_redstep acc3,acc2,acc1,acc0,acc5,acc4 + p256r1_mul_redstep acc4,acc3,acc2,acc1,acc0,acc5 + + mov t0, acc0 + mov t1, acc1 + mov t2, acc2 + mov t3, acc3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb acc4, 0 + + cmovnc acc0, t0 + cmovnc acc1, t1 + cmovnc acc2, t2 + cmovnc acc3, t3 + + mov qword [rdi+sizeof(qword)*0], acc0 + mov qword [rdi+sizeof(qword)*1], acc1 + mov qword [rdi+sizeof(qword)*2], acc2 + mov qword [rdi+sizeof(qword)*3], acc3 + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_mont_back + +;;%if _IPP32E < _IPP32E_L9 +%ifndef _DISABLE_ECP_256R1_HARDCODED_BP_TBL_ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p256r1_select_ap_w7(AF_POINT *val, const AF_POINT *in_t, int index); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p256r1_select_ap_w7,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 + COMP_ABI 3 + +%xdefine val rdi +%xdefine in_t rsi +%xdefine idx edx + +%xdefine ONE xmm0 +%xdefine INDEX xmm1 + +%xdefine Ra xmm2 +%xdefine Rb xmm3 +%xdefine Rc xmm4 +%xdefine Rd xmm5 + +%xdefine M0 xmm8 +%xdefine T0a xmm9 +%xdefine T0b xmm10 +%xdefine T0c xmm11 +%xdefine T0d xmm12 +%xdefine TMP0 xmm15 + + movdqa ONE, oword [rel LOne] + + pxor Ra, Ra + pxor Rb, Rb + pxor Rc, Rc + pxor Rd, Rd + + movdqa M0, ONE + + movd INDEX, idx + pshufd INDEX, INDEX, 0 + + ; Skip index = 0, is implicictly infty -> load with offset -1 + mov rcx, dword 64 +.select_loop_sse_w7: + movdqa TMP0, M0 + pcmpeqd TMP0, INDEX + paddd M0, ONE + + movdqa T0a, oword [in_t+sizeof(oword)*0] + movdqa T0b, oword [in_t+sizeof(oword)*1] + movdqa T0c, oword [in_t+sizeof(oword)*2] + movdqa T0d, oword [in_t+sizeof(oword)*3] + add in_t, sizeof(oword)*4 + + pand T0a, TMP0 + pand T0b, TMP0 + pand T0c, TMP0 + pand T0d, TMP0 + + por Ra, T0a + por Rb, T0b + por Rc, T0c + por Rd, T0d + dec rcx + jnz .select_loop_sse_w7 + + movdqu oword [val+sizeof(oword)*0], Ra + movdqu oword [val+sizeof(oword)*1], Rb + movdqu oword [val+sizeof(oword)*2], Rc + movdqu oword [val+sizeof(oword)*3], Rd + + REST_XMM + REST_GPR + ret +ENDFUNC p256r1_select_ap_w7 + +%endif +;;%endif ;; _IPP32E < _IPP32E_L9 + +%endif ;; _IPP32E_M7 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp384r1funcs_montas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp384r1funcs_montas.asm new file mode 100644 index 000000000..f31278211 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp384r1funcs_montas.asm @@ -0,0 +1,843 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; secp p384r1 specific implementation +; + + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +%assign _xEMULATION_ 1 +%assign _ADCX_ADOX_ 1 + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +;; The p384r1 polynomial +Lpoly DQ 000000000ffffffffh,0ffffffff00000000h,0fffffffffffffffeh + DQ 0ffffffffffffffffh,0ffffffffffffffffh,0ffffffffffffffffh + +;; 2^(2*384) mod P precomputed for p384r1 polynomial +;LRR DQ 0fffffffe00000001h,00000000200000000h,0fffffffe00000000h +; DQ 00000000200000000h,00000000000000001h,00000000000000000h + +LOne DD 1,1,1,1,1,1,1,1 +LTwo DD 2,2,2,2,2,2,2,2 +LThree DD 3,3,3,3,3,3,3,3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p384r1_mul_by_2(uint64_t res[6], uint64_t a[6]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_mul_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + +%xdefine a0 rax +%xdefine a1 rcx +%xdefine a2 rdx +%xdefine a3 r8 +%xdefine a4 r9 +%xdefine a5 r10 +%xdefine ex r11 + +%xdefine t r12 + + xor ex, ex + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + + shld ex, a5, 1 + shld a5, a4, 1 + mov qword [rdi+sizeof(qword)*5], a5 + shld a4, a3, 1 + mov qword [rdi+sizeof(qword)*4], a4 + shld a3, a2, 1 + mov qword [rdi+sizeof(qword)*3], a3 + shld a2, a1, 1 + mov qword [rdi+sizeof(qword)*2], a2 + shld a1, a0, 1 + mov qword [rdi+sizeof(qword)*1], a1 + shl a0, 1 + mov qword [rdi+sizeof(qword)*0], a0 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb ex, 0 + + mov t, qword [rdi+sizeof(qword)*0] + cmovnz a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovnz a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovnz a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovnz a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovnz a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovnz a5, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_mul_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p384r1_div_by_2(uint64_t res[6], uint64_t a[6]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_div_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + +%xdefine a0 rax +%xdefine a1 rcx +%xdefine a2 rdx +%xdefine a3 r8 +%xdefine a4 r9 +%xdefine a5 r10 +%xdefine ex r11 + +%xdefine t r12 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + + xor t, t + xor ex, ex + add a0, qword [rel Lpoly+sizeof(qword)*0] + adc a1, qword [rel Lpoly+sizeof(qword)*1] + adc a2, qword [rel Lpoly+sizeof(qword)*2] + adc a3, qword [rel Lpoly+sizeof(qword)*3] + adc a4, qword [rel Lpoly+sizeof(qword)*4] + adc a5, qword [rel Lpoly+sizeof(qword)*5] + adc ex, 0 + + test a0, 1 + cmovnz ex, t + mov t, qword [rsi+sizeof(qword)*0] + cmovnz a0, t + mov t, qword [rsi+sizeof(qword)*1] + cmovnz a1, t + mov t, qword [rsi+sizeof(qword)*2] + cmovnz a2, t + mov t, qword [rsi+sizeof(qword)*3] + cmovnz a3, t + mov t, qword [rsi+sizeof(qword)*4] + cmovnz a4, t + mov t, qword [rsi+sizeof(qword)*5] + cmovnz a5, t + + shrd a0, a1, 1 + shrd a1, a2, 1 + shrd a2, a3, 1 + shrd a3, a4, 1 + shrd a4, a5, 1 + shrd a5, ex, 1 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_div_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p384r1_mul_by_3(uint64_t res[6], uint64_t a[6]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_mul_by_3,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*6 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 rax +%xdefine a1 rcx +%xdefine a2 rdx +%xdefine a3 r8 +%xdefine a4 r9 +%xdefine a5 r10 +%xdefine ex r11 + +%xdefine t r12 + + xor ex, ex + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + + shld ex, a5, 1 + shld a5, a4, 1 + mov qword [rsp+sizeof(qword)*5], a5 + shld a4, a3, 1 + mov qword [rsp+sizeof(qword)*4], a4 + shld a3, a2, 1 + mov qword [rsp+sizeof(qword)*3], a3 + shld a2, a1, 1 + mov qword [rsp+sizeof(qword)*2], a2 + shld a1, a0, 1 + mov qword [rsp+sizeof(qword)*1], a1 + shl a0, 1 + mov qword [rsp+sizeof(qword)*0], a0 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb ex, 0 + + mov t, qword [rsp+0*sizeof(qword)] + cmovb a0, t + mov t, qword [rsp+1*sizeof(qword)] + cmovb a1, t + mov t, qword [rsp+2*sizeof(qword)] + cmovb a2, t + mov t, qword [rsp+3*sizeof(qword)] + cmovb a3, t + mov t, qword [rsp+4*sizeof(qword)] + cmovb a4, t + mov t, qword [rsp+5*sizeof(qword)] + cmovb a5, t + + xor ex, ex + add a0, qword [rsi+sizeof(qword)*0] + mov qword [rsp+sizeof(qword)*0], a0 + adc a1, qword [rsi+sizeof(qword)*1] + mov qword [rsp+sizeof(qword)*1], a1 + adc a2, qword [rsi+sizeof(qword)*2] + mov qword [rsp+sizeof(qword)*2], a2 + adc a3, qword [rsi+sizeof(qword)*3] + mov qword [rsp+sizeof(qword)*3], a3 + adc a4, qword [rsi+sizeof(qword)*4] + mov qword [rsp+sizeof(qword)*4], a4 + adc a5, qword [rsi+sizeof(qword)*5] + mov qword [rsp+sizeof(qword)*5], a5 + adc ex, 0 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb ex, 0 + + mov t, qword [rsp+sizeof(qword)*0] + cmovb a0, t + mov t, qword [rsp+sizeof(qword)*1] + cmovb a1, t + mov t, qword [rsp+sizeof(qword)*2] + cmovb a2, t + mov t, qword [rsp+sizeof(qword)*3] + cmovb a3, t + mov t, qword [rsp+sizeof(qword)*4] + cmovb a4, t + mov t, qword [rsp+sizeof(qword)*5] + cmovb a5, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_mul_by_3 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p384r1_add(uint64_t res[6], uint64_t a[6], uint64_t b[6]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_add,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12 + USES_XMM + COMP_ABI 3 + +%xdefine a0 rax +%xdefine a1 rcx +%xdefine a2 rbx +%xdefine a3 r8 +%xdefine a4 r9 +%xdefine a5 r10 +%xdefine ex r11 + +%xdefine t r12 + + xor ex, ex + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + + add a0, qword [rdx+sizeof(qword)*0] + adc a1, qword [rdx+sizeof(qword)*1] + adc a2, qword [rdx+sizeof(qword)*2] + adc a3, qword [rdx+sizeof(qword)*3] + adc a4, qword [rdx+sizeof(qword)*4] + adc a5, qword [rdx+sizeof(qword)*5] + adc ex, 0 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb ex, 0 + + mov t, qword [rdi+sizeof(qword)*0] + cmovb a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovb a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovb a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovb a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovb a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovb a5, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_add + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p384r1_sub(uint64_t res[6], uint64_t a[6], uint64_t b[6]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_sub,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12 + USES_XMM + COMP_ABI 3 + +%xdefine a0 rax +%xdefine a1 rcx +%xdefine a2 rbx +%xdefine a3 r8 +%xdefine a4 r9 +%xdefine a5 r10 +%xdefine ex r11 + +%xdefine t r12 + + xor ex, ex + + mov a0, qword [rsi+sizeof(qword)*0] ; a + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + + sub a0, qword [rdx+sizeof(qword)*0] ; a-b + sbb a1, qword [rdx+sizeof(qword)*1] + sbb a2, qword [rdx+sizeof(qword)*2] + sbb a3, qword [rdx+sizeof(qword)*3] + sbb a4, qword [rdx+sizeof(qword)*4] + sbb a5, qword [rdx+sizeof(qword)*5] + + sbb ex, 0 ; ex = a>=b? 0 : -1 + + mov qword [rdi+sizeof(qword)*0], a0 ; store (a-b) + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + add a0, qword [rel Lpoly+sizeof(qword)*0] ; (a-b) +poly + adc a1, qword [rel Lpoly+sizeof(qword)*1] + adc a2, qword [rel Lpoly+sizeof(qword)*2] + adc a3, qword [rel Lpoly+sizeof(qword)*3] + adc a4, qword [rel Lpoly+sizeof(qword)*4] + adc a5, qword [rel Lpoly+sizeof(qword)*5] + + test ex, ex ; r = (ex)? ((a-b)+poly) : (a-b) + + mov t, qword [rdi+sizeof(qword)*0] + cmovz a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovz a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovz a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovz a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovz a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovz a5, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_sub + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p384r1_neg(uint64_t res[6], uint64_t a[6]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_neg,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12 + USES_XMM + COMP_ABI 2 + +%xdefine a0 rax +%xdefine a1 rcx +%xdefine a2 rdx +%xdefine a3 r8 +%xdefine a4 r9 +%xdefine a5 r10 +%xdefine ex r11 + +%xdefine t r12 + + xor ex, ex + + xor a0, a0 + xor a1, a1 + xor a2, a2 + xor a3, a3 + xor a4, a4 + xor a5, a5 + + sub a0, qword [rsi+sizeof(qword)*0] + sbb a1, qword [rsi+sizeof(qword)*1] + sbb a2, qword [rsi+sizeof(qword)*2] + sbb a3, qword [rsi+sizeof(qword)*3] + sbb a4, qword [rsi+sizeof(qword)*4] + sbb a5, qword [rsi+sizeof(qword)*5] + sbb ex, 0 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + add a0, qword [rel Lpoly+sizeof(qword)*0] + adc a1, qword [rel Lpoly+sizeof(qword)*1] + adc a2, qword [rel Lpoly+sizeof(qword)*2] + adc a3, qword [rel Lpoly+sizeof(qword)*3] + adc a4, qword [rel Lpoly+sizeof(qword)*4] + adc a5, qword [rel Lpoly+sizeof(qword)*5] + test ex, ex + + mov t, qword [rdi+sizeof(qword)*0] + cmovz a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovz a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovz a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovz a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovz a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovz a5, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_neg + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; projective point selector +; +; void p384r1_mred(Ipp464u* res, Ipp64u product); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; mred_step does single Montgomery reduction step -- computes {a0:a1:a2:a3:a4:a5:a6} += u*M[] +; where u = a0*m0 = a0*(2^32+1) and +; M[] = (2^32-1) + (2^64-2^32)*2^64 + (2^64-2)*2^64*2 + (2^64-1)*2^64*3 + (2^64-1)*2^64*4 + (2^64-1)*2^64*5 +; +; u*M[] = u*(2^32-1) + u*(2^64-2^32)*2^64 + u*(2^64-2)*2^64*2 + u*(2^64-1)*2^64*3 + u*(2^64-1)*2^64*4 + u*(2^64-1)*2^64*5 +; = u*2^32 -u +; +u*2^128 -u*2^32*2^64 +; +u*2^192 -u*2^128 -u*2^128 +; +u*2^256 -u*2^192 +; +u*2^320 -u*2^256 +; +u*2^384 -u*2^320 +; +; = (u*2^32 -u) + u*2^384 +; -u*2^32*2^64 -u*2^128 +; +; = (u*2^32 -u) + u*B^5 +; -(u*2^32 +u*B)*B, where B=2^64 is the target radix +; +; so update of {a0:a1:a2:a3:a4:a5:a6} consisns of 2 steps: +; {a0:a1:a2:a3:a4:a5:a6} += {(u*2^32 -u):0:0:0:0:0:u} and +; {a0:a1:a2:a3:a4:a5:a6} -= {0:(u*2^32 +u*B):0:0:0:0:0} +; +%macro mred_step 9.nolist + %xdefine %%a6 %1 + %xdefine %%a5 %2 + %xdefine %%a4 %3 + %xdefine %%a3 %4 + %xdefine %%a2 %5 + %xdefine %%a1 %6 + %xdefine %%a0 %7 + %xdefine %%t2 %8 + %xdefine %%t1 %9 + + mov rax, %%a0 ;; u = (m0*a0) mod 2^64= ((2^32+1)*a0) mod 2^64 + shl rax, 32 + add rax, %%a0 + + mov %%t2, rax ;; (t2:t1) = u*2^32, store + shr %%t2, (64-32) + push %%t2 + mov %%t1, rax + shl %%t1, 32 + push %%t1 + + sub %%t1, rax ;; {t2:t1} = (2^32 -1)*u + sbb %%t2, 0 + + ;; {a0:a1:a2:a3:a4:a5:a6} += (u*2^32 -u) + u*2^64*6 + add %%a0, %%t1 ;; {a0:a1} += (u*2^32 -u) + mov %%t1, rdx ;; t1 = carry_inp + mov rdx, 0 + adc %%a1, %%t2 + adc %%a2, 0 + adc %%a3, 0 + adc %%a4, 0 + adc %%a5, 0 + adc %%a6, rax ;; a6 += u + cf + adc rdx, 0 ;; rdx = carry_out + + add %%a6, %%t1 ;; add input carry + adc rdx, 0 ;; rdx = carry_out + + pop %%t1 ;; restore {t2:t1} = u*2^32 + pop %%t2 + + add %%t2, rax ;; {t1:t2} = u*2^32 +u*2^64 + mov rax,0 + adc rax,0 + + ;; {a1:a2:a3:a4:a5:a6} -= (u*2^32 + u) + sub %%a1, %%t1 + sbb %%a2, %%t2 + sbb %%a3, rax + sbb %%a4, 0 + sbb %%a5, 0 + sbb %%a6, 0 + + sbb rdx, 0 ;; update carry_out +%endmacro + +align IPP_ALIGN_FACTOR +IPPASM p384r1_mred,PUBLIC + + USES_GPR rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +;; rdi = result +;; rsi = product buffer + + xor rdx, rdx + mov r8, qword [rsi] + mov r9, qword [rsi+sizeof(qword)] + mov r10, qword [rsi+sizeof(qword)*2] + mov r11, qword [rsi+sizeof(qword)*3] + mov r12, qword [rsi+sizeof(qword)*4] + mov r13, qword [rsi+sizeof(qword)*5] + mov r14, qword [rsi+sizeof(qword)*6] + mred_step r14,r13,r12,r11,r10,r9,r8, r15,rcx + ;mov qword [rdi+sizeof(qword)*0], r9 + ;mov qword [rdi+sizeof(qword)*1], r10 + ;mov qword [rdi+sizeof(qword)*2], r11 + ;mov qword [rdi+sizeof(qword)*3], r12 + ;mov qword [rdi+sizeof(qword)*4], r13 + ;mov qword [rdi+sizeof(qword)*5], r14 + + mov r8, qword [rsi+sizeof(qword)*7] + mred_step r8,r14,r13,r12,r11,r10,r9, r15,rcx + ;mov qword [rdi+sizeof(qword)*0], r10 + ;mov qword [rdi+sizeof(qword)*1], r11 + ;mov qword [rdi+sizeof(qword)*2], r12 + ;mov qword [rdi+sizeof(qword)*3], r13 + ;mov qword [rdi+sizeof(qword)*4], r14 + ;mov qword [rdi+sizeof(qword)*5], r8 + + mov r9, qword [rsi+sizeof(qword)*8] + mred_step r9,r8,r14,r13,r12,r11,r10, r15,rcx + ;mov qword [rdi+sizeof(qword)*0], r11 + ;mov qword [rdi+sizeof(qword)*1], r12 + ;mov qword [rdi+sizeof(qword)*2], r13 + ;mov qword [rdi+sizeof(qword)*3], r14 + ;mov qword [rdi+sizeof(qword)*4], r8 + ;mov qword [rdi+sizeof(qword)*5], r9 + + mov r10, qword [rsi+sizeof(qword)*9] + mred_step r10,r9,r8,r14,r13,r12,r11, r15,rcx + ;mov qword [rdi+sizeof(qword)*0], r12 + ;mov qword [rdi+sizeof(qword)*1], r13 + ;mov qword [rdi+sizeof(qword)*2], r14 + ;mov qword [rdi+sizeof(qword)*3], r8 + ;mov qword [rdi+sizeof(qword)*4], r9 + ;mov qword [rdi+sizeof(qword)*5], r10 + + mov r11, qword [rsi+sizeof(qword)*10] + mred_step r11,r10,r9,r8,r14,r13,r12, r15,rcx + ;mov qword [rdi+sizeof(qword)*0], r13 + ;mov qword [rdi+sizeof(qword)*1], r14 + ;mov qword [rdi+sizeof(qword)*2], r8 + ;mov qword [rdi+sizeof(qword)*3], r9 + ;mov qword [rdi+sizeof(qword)*4], r10 + ;mov qword [rdi+sizeof(qword)*5], r11 + + mov r12, qword [rsi+sizeof(qword)*11] + mred_step r12,r11,r10,r9,r8,r14,r13, r15,rcx ; {r12,r11,r10,r9,r8,r14} - result + mov qword [rdi+sizeof(qword)*0], r14 + mov qword [rdi+sizeof(qword)*1], r8 + mov qword [rdi+sizeof(qword)*2], r9 + mov qword [rdi+sizeof(qword)*3], r10 + mov qword [rdi+sizeof(qword)*4], r11 + mov qword [rdi+sizeof(qword)*5], r12 + + sub r14, qword [rel Lpoly+sizeof(qword)*0] + sbb r8, qword [rel Lpoly+sizeof(qword)*1] + sbb r9, qword [rel Lpoly+sizeof(qword)*2] + sbb r10, qword [rel Lpoly+sizeof(qword)*3] + sbb r11, qword [rel Lpoly+sizeof(qword)*4] + sbb r12, qword [rel Lpoly+sizeof(qword)*5] + sbb rdx, 0 + + mov rax, qword [rdi+sizeof(qword)*0] + cmovnz r14, rax + mov rax, qword [rdi+sizeof(qword)*1] + cmovnz r8, rax + mov rax, qword [rdi+sizeof(qword)*2] + cmovnz r9, rax + mov rax, qword [rdi+sizeof(qword)*3] + cmovnz r10, rax + mov rax, qword [rdi+sizeof(qword)*4] + cmovnz r11, rax + mov rax, qword [rdi+sizeof(qword)*5] + cmovnz r12, rax + + mov qword [rdi+sizeof(qword)*0], r14 + mov qword [rdi+sizeof(qword)*1], r8 + mov qword [rdi+sizeof(qword)*2], r9 + mov qword [rdi+sizeof(qword)*3], r10 + mov qword [rdi+sizeof(qword)*4], r11 + mov qword [rdi+sizeof(qword)*5], r12 + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_mred + +%ifndef _DISABLE_ECP_384R1_HARDCODED_BP_TBL_ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; affine point selector +; +; void p384r1_select_ap_w5(AF_POINT *val, const AF_POINT *tbl, int idx); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p384r1_select_ap_w5,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14 + COMP_ABI 3 + +%xdefine val rdi +%xdefine in_t rsi +%xdefine idx edx + +%xdefine Xa xmm0 +%xdefine Xb xmm1 +%xdefine Xc xmm2 +%xdefine Ya xmm3 +%xdefine Yb xmm4 +%xdefine Yc xmm5 + +%xdefine TXa xmm6 +%xdefine TXb xmm7 +%xdefine TXc xmm8 +%xdefine TYa xmm9 +%xdefine TYb xmm10 +%xdefine TYc xmm11 + +%xdefine REQ_IDX xmm12 +%xdefine CUR_IDX xmm13 +%xdefine MASKDATA xmm14 + + movdqa CUR_IDX, oword [rel LOne] + + movd REQ_IDX, idx + pshufd REQ_IDX, REQ_IDX, 0 + + pxor Xa, Xa + pxor Xb, Xb + pxor Xc, Xc + pxor Ya, Ya + pxor Yb, Yb + pxor Yc, Yc + + ; Skip index = 0, is implicictly infty -> load with offset -1 + mov rcx, dword 16 +.select_loop: + movdqa MASKDATA, CUR_IDX ; MASK = CUR_IDX==REQ_IDX? 0xFF : 0x00 + pcmpeqd MASKDATA, REQ_IDX ; + paddd CUR_IDX, oword [rel LOne] + + movdqa TXa, oword [in_t+sizeof(oword)*0] + movdqa TXb, oword [in_t+sizeof(oword)*1] + movdqa TXc, oword [in_t+sizeof(oword)*2] + movdqa TYa, oword [in_t+sizeof(oword)*3] + movdqa TYb, oword [in_t+sizeof(oword)*4] + movdqa TYc, oword [in_t+sizeof(oword)*5] + add in_t, sizeof(oword)*6 + + pand TXa, MASKDATA + pand TXb, MASKDATA + pand TXc, MASKDATA + pand TYa, MASKDATA + pand TYb, MASKDATA + pand TYc, MASKDATA + + por Xa, TXa + por Xb, TXb + por Xc, TXc + por Ya, TYa + por Yb, TYb + por Yc, TYc + + dec rcx + jnz .select_loop + + movdqu oword [val+sizeof(oword)*0], Xa + movdqu oword [val+sizeof(oword)*1], Xb + movdqu oword [val+sizeof(oword)*2], Xc + movdqu oword [val+sizeof(oword)*3], Ya + movdqu oword [val+sizeof(oword)*4], Yb + movdqu oword [val+sizeof(oword)*5], Yc + + REST_XMM + REST_GPR + ret +ENDFUNC p384r1_select_ap_w5 + +%endif + +%endif ;; _IPP32E_M7 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp521r1funcs_montas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp521r1funcs_montas.asm new file mode 100644 index 000000000..1aba2bd5f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpp521r1funcs_montas.asm @@ -0,0 +1,963 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; secp p521r1 specific implementation +; + + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +%assign _xEMULATION_ 1 +%assign _ADCX_ADOX_ 1 + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +LOne DD 1,1,1,1,1,1,1,1 +LTwo DD 2,2,2,2,2,2,2,2 +LThree DD 3,3,3,3,3,3,3,3 + +;; The p521r1 polynomial +Lpoly DQ 0ffffffffffffffffh,0ffffffffffffffffh,0ffffffffffffffffh + DQ 0ffffffffffffffffh,0ffffffffffffffffh,0ffffffffffffffffh + DQ 0ffffffffffffffffh,0ffffffffffffffffh,000000000000001ffh + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p521r1_mul_by_2(uint64_t res[9], uint64_t a[9]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_mul_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 +%xdefine a4 r12 +%xdefine a5 r13 +%xdefine a6 r14 +%xdefine a7 r15 +%xdefine a8 rax +%xdefine ex rcx + +%xdefine t rdx + + xor ex, ex + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + mov a6, qword [rsi+sizeof(qword)*6] + mov a7, qword [rsi+sizeof(qword)*7] + mov a8, qword [rsi+sizeof(qword)*8] + + shld ex, a8, 1 + shld a8, a7, 1 + shld a7, a6, 1 + shld a6, a5, 1 + shld a5, a4, 1 + shld a4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov qword [rdi+sizeof(qword)*8], a8 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*0], a0 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb a6, qword [rel Lpoly+sizeof(qword)*6] + sbb a7, qword [rel Lpoly+sizeof(qword)*7] + sbb a8, qword [rel Lpoly+sizeof(qword)*8] + sbb ex, 0 + + mov t, qword [rdi+sizeof(qword)*0] + cmovnz a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovnz a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovnz a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovnz a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovnz a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovnz a5, t + mov t, qword [rdi+sizeof(qword)*6] + cmovnz a6, t + mov t, qword [rdi+sizeof(qword)*7] + cmovnz a7, t + mov t, qword [rdi+sizeof(qword)*8] + cmovnz a8, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_mul_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p521r1_div_by_2(uint64_t res[9], uint64_t a[9]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_div_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 +%xdefine a4 r12 +%xdefine a5 r13 +%xdefine a6 r14 +%xdefine a7 r15 +%xdefine a8 rax +%xdefine ex rcx + +%xdefine t rdx + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + mov a6, qword [rsi+sizeof(qword)*6] + mov a7, qword [rsi+sizeof(qword)*7] + mov a8, qword [rsi+sizeof(qword)*8] + + xor t, t + xor ex, ex + add a0, qword [rel Lpoly+sizeof(qword)*0] + adc a1, qword [rel Lpoly+sizeof(qword)*1] + adc a2, qword [rel Lpoly+sizeof(qword)*2] + adc a3, qword [rel Lpoly+sizeof(qword)*3] + adc a4, qword [rel Lpoly+sizeof(qword)*4] + adc a5, qword [rel Lpoly+sizeof(qword)*5] + adc a6, qword [rel Lpoly+sizeof(qword)*6] + adc a7, qword [rel Lpoly+sizeof(qword)*7] + adc a8, qword [rel Lpoly+sizeof(qword)*8] + adc ex, 0 + + test a0, 1 + cmovnz ex, t + mov t, qword [rsi+sizeof(qword)*0] + cmovnz a0, t + mov t, qword [rsi+sizeof(qword)*1] + cmovnz a1, t + mov t, qword [rsi+sizeof(qword)*2] + cmovnz a2, t + mov t, qword [rsi+sizeof(qword)*3] + cmovnz a3, t + mov t, qword [rsi+sizeof(qword)*4] + cmovnz a4, t + mov t, qword [rsi+sizeof(qword)*5] + cmovnz a5, t + mov t, qword [rsi+sizeof(qword)*6] + cmovnz a6, t + mov t, qword [rsi+sizeof(qword)*7] + cmovnz a7, t + mov t, qword [rsi+sizeof(qword)*8] + cmovnz a8, t + + shrd a0, a1, 1 + shrd a1, a2, 1 + shrd a2, a3, 1 + shrd a3, a4, 1 + shrd a4, a5, 1 + shrd a5, a6, 1 + shrd a6, a7, 1 + shrd a7, a8, 1 + shrd a8, ex, 1 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_div_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p521r1_mul_by_3(uint64_t res[9], uint64_t a[9]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_mul_by_3,PUBLIC +%assign LOCAL_FRAME sizeof(qword)*9 + USES_GPR rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 +%xdefine a4 r12 +%xdefine a5 r13 +%xdefine a6 r14 +%xdefine a7 r15 +%xdefine a8 rax +%xdefine ex rcx + +%xdefine t rdx + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + mov a6, qword [rsi+sizeof(qword)*6] + mov a7, qword [rsi+sizeof(qword)*7] + mov a8, qword [rsi+sizeof(qword)*8] + + xor ex, ex + shld ex, a8, 1 + shld a8, a7, 1 + shld a7, a6, 1 + shld a6, a5, 1 + shld a5, a4, 1 + shld a4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov qword [rsp+sizeof(qword)*8], a8 + mov qword [rsp+sizeof(qword)*7], a7 + mov qword [rsp+sizeof(qword)*6], a6 + mov qword [rsp+sizeof(qword)*5], a5 + mov qword [rsp+sizeof(qword)*4], a4 + mov qword [rsp+sizeof(qword)*3], a3 + mov qword [rsp+sizeof(qword)*2], a2 + mov qword [rsp+sizeof(qword)*1], a1 + mov qword [rsp+sizeof(qword)*0], a0 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb a6, qword [rel Lpoly+sizeof(qword)*6] + sbb a7, qword [rel Lpoly+sizeof(qword)*7] + sbb a8, qword [rel Lpoly+sizeof(qword)*8] + sbb ex, 0 + + mov t, qword [rsp+sizeof(qword)*0] + cmovb a0, t + mov t, qword [rsp+sizeof(qword)*1] + cmovb a1, t + mov t, qword [rsp+sizeof(qword)*2] + cmovb a2, t + mov t, qword [rsp+sizeof(qword)*3] + cmovb a3, t + mov t, qword [rsp+sizeof(qword)*4] + cmovb a4, t + mov t, qword [rsp+sizeof(qword)*5] + cmovb a5, t + mov t, qword [rsp+sizeof(qword)*6] + cmovb a6, t + mov t, qword [rsp+sizeof(qword)*7] + cmovb a7, t + mov t, qword [rsp+sizeof(qword)*8] + cmovb a8, t + + xor ex, ex + add a0, qword [rsi+sizeof(qword)*0] + adc a1, qword [rsi+sizeof(qword)*1] + adc a2, qword [rsi+sizeof(qword)*2] + adc a3, qword [rsi+sizeof(qword)*3] + adc a4, qword [rsi+sizeof(qword)*4] + adc a5, qword [rsi+sizeof(qword)*5] + adc a6, qword [rsi+sizeof(qword)*6] + adc a7, qword [rsi+sizeof(qword)*7] + adc a8, qword [rsi+sizeof(qword)*8] + adc ex, 0 + + mov qword [rsp+sizeof(qword)*0], a0 + mov qword [rsp+sizeof(qword)*1], a1 + mov qword [rsp+sizeof(qword)*2], a2 + mov qword [rsp+sizeof(qword)*3], a3 + mov qword [rsp+sizeof(qword)*4], a4 + mov qword [rsp+sizeof(qword)*5], a5 + mov qword [rsp+sizeof(qword)*6], a6 + mov qword [rsp+sizeof(qword)*7], a7 + mov qword [rsp+sizeof(qword)*8], a8 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb a6, qword [rel Lpoly+sizeof(qword)*6] + sbb a7, qword [rel Lpoly+sizeof(qword)*7] + sbb a8, qword [rel Lpoly+sizeof(qword)*8] + sbb ex, 0 + + mov t, qword [rsp+sizeof(qword)*0] + cmovb a0, t + mov t, qword [rsp+sizeof(qword)*1] + cmovb a1, t + mov t, qword [rsp+sizeof(qword)*2] + cmovb a2, t + mov t, qword [rsp+sizeof(qword)*3] + cmovb a3, t + mov t, qword [rsp+sizeof(qword)*4] + cmovb a4, t + mov t, qword [rsp+sizeof(qword)*5] + cmovb a5, t + mov t, qword [rsp+sizeof(qword)*6] + cmovb a6, t + mov t, qword [rsp+sizeof(qword)*7] + cmovb a7, t + mov t, qword [rsp+sizeof(qword)*8] + cmovb a8, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_mul_by_3 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p521r1_add(uint64_t res[9], uint64_t a[9], uint64_t b[9]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_add,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 +%xdefine a4 r12 +%xdefine a5 r13 +%xdefine a6 r14 +%xdefine a7 r15 +%xdefine a8 rax +%xdefine ex rcx + +%xdefine t rdx + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + mov a6, qword [rsi+sizeof(qword)*6] + mov a7, qword [rsi+sizeof(qword)*7] + mov a8, qword [rsi+sizeof(qword)*8] + + xor ex, ex + add a0, qword [rdx+sizeof(qword)*0] + adc a1, qword [rdx+sizeof(qword)*1] + adc a2, qword [rdx+sizeof(qword)*2] + adc a3, qword [rdx+sizeof(qword)*3] + adc a4, qword [rdx+sizeof(qword)*4] + adc a5, qword [rdx+sizeof(qword)*5] + adc a6, qword [rdx+sizeof(qword)*6] + adc a7, qword [rdx+sizeof(qword)*7] + adc a8, qword [rdx+sizeof(qword)*8] + adc ex, 0 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + sub a0, qword [rel Lpoly+sizeof(qword)*0] + sbb a1, qword [rel Lpoly+sizeof(qword)*1] + sbb a2, qword [rel Lpoly+sizeof(qword)*2] + sbb a3, qword [rel Lpoly+sizeof(qword)*3] + sbb a4, qword [rel Lpoly+sizeof(qword)*4] + sbb a5, qword [rel Lpoly+sizeof(qword)*5] + sbb a6, qword [rel Lpoly+sizeof(qword)*6] + sbb a7, qword [rel Lpoly+sizeof(qword)*7] + sbb a8, qword [rel Lpoly+sizeof(qword)*8] + sbb ex, 0 + + mov t, qword [rdi+sizeof(qword)*0] + cmovb a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovb a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovb a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovb a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovb a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovb a5, t + mov t, qword [rdi+sizeof(qword)*6] + cmovb a6, t + mov t, qword [rdi+sizeof(qword)*7] + cmovb a7, t + mov t, qword [rdi+sizeof(qword)*8] + cmovb a8, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_add + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p521r1_sub(uint64_t res[9], uint64_t a[9], uint64_t b[9]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_sub,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 +%xdefine a4 r12 +%xdefine a5 r13 +%xdefine a6 r14 +%xdefine a7 r15 +%xdefine a8 rax +%xdefine ex rcx + +%xdefine t rdx + + mov a0, qword [rsi+sizeof(qword)*0] ; a + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + mov a6, qword [rsi+sizeof(qword)*6] + mov a7, qword [rsi+sizeof(qword)*7] + mov a8, qword [rsi+sizeof(qword)*8] + + xor ex, ex + sub a0, qword [rdx+sizeof(qword)*0] ; a-b + sbb a1, qword [rdx+sizeof(qword)*1] + sbb a2, qword [rdx+sizeof(qword)*2] + sbb a3, qword [rdx+sizeof(qword)*3] + sbb a4, qword [rdx+sizeof(qword)*4] + sbb a5, qword [rdx+sizeof(qword)*5] + sbb a6, qword [rdx+sizeof(qword)*6] + sbb a7, qword [rdx+sizeof(qword)*7] + sbb a8, qword [rdx+sizeof(qword)*8] + sbb ex, 0 ; ex = a>=b? 0 : -1 + + mov qword [rdi+sizeof(qword)*0], a0 ; store (a-b) + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + add a0, qword [rel Lpoly+sizeof(qword)*0] ; (a-b) +poly + adc a1, qword [rel Lpoly+sizeof(qword)*1] + adc a2, qword [rel Lpoly+sizeof(qword)*2] + adc a3, qword [rel Lpoly+sizeof(qword)*3] + adc a4, qword [rel Lpoly+sizeof(qword)*4] + adc a5, qword [rel Lpoly+sizeof(qword)*5] + adc a6, qword [rel Lpoly+sizeof(qword)*6] + adc a7, qword [rel Lpoly+sizeof(qword)*7] + adc a8, qword [rel Lpoly+sizeof(qword)*8] + + test ex, ex ; r = (ex)? ((a-b)+poly) : (a-b) + + mov t, qword [rdi+sizeof(qword)*0] + cmovz a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovz a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovz a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovz a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovz a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovz a5, t + mov t, qword [rdi+sizeof(qword)*6] + cmovz a6, t + mov t, qword [rdi+sizeof(qword)*7] + cmovz a7, t + mov t, qword [rdi+sizeof(qword)*8] + cmovz a8, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_sub + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void p521r1_neg(uint64_t res[9], uint64_t a[9]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_neg,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 +%xdefine a4 r12 +%xdefine a5 r13 +%xdefine a6 r14 +%xdefine a7 r15 +%xdefine a8 rax +%xdefine ex rcx + +%xdefine t rdx + + xor a0, a0 + xor a1, a1 + xor a2, a2 + xor a3, a3 + xor a4, a4 + xor a5, a5 + xor a6, a6 + xor a7, a7 + xor a8, a8 + + xor ex, ex + sub a0, qword [rsi+sizeof(qword)*0] + sbb a1, qword [rsi+sizeof(qword)*1] + sbb a2, qword [rsi+sizeof(qword)*2] + sbb a3, qword [rsi+sizeof(qword)*3] + sbb a4, qword [rsi+sizeof(qword)*4] + sbb a5, qword [rsi+sizeof(qword)*5] + sbb a6, qword [rsi+sizeof(qword)*6] + sbb a7, qword [rsi+sizeof(qword)*7] + sbb a8, qword [rsi+sizeof(qword)*8] + sbb ex, 0 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + add a0, qword [rel Lpoly+sizeof(qword)*0] + adc a1, qword [rel Lpoly+sizeof(qword)*1] + adc a2, qword [rel Lpoly+sizeof(qword)*2] + adc a3, qword [rel Lpoly+sizeof(qword)*3] + adc a4, qword [rel Lpoly+sizeof(qword)*4] + adc a5, qword [rel Lpoly+sizeof(qword)*5] + adc a6, qword [rel Lpoly+sizeof(qword)*6] + adc a7, qword [rel Lpoly+sizeof(qword)*7] + adc a8, qword [rel Lpoly+sizeof(qword)*8] + test ex, ex + + mov t, qword [rdi+sizeof(qword)*0] + cmovz a0, t + mov t, qword [rdi+sizeof(qword)*1] + cmovz a1, t + mov t, qword [rdi+sizeof(qword)*2] + cmovz a2, t + mov t, qword [rdi+sizeof(qword)*3] + cmovz a3, t + mov t, qword [rdi+sizeof(qword)*4] + cmovz a4, t + mov t, qword [rdi+sizeof(qword)*5] + cmovz a5, t + mov t, qword [rdi+sizeof(qword)*6] + cmovz a6, t + mov t, qword [rdi+sizeof(qword)*7] + cmovz a7, t + mov t, qword [rdi+sizeof(qword)*8] + cmovz a8, t + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + mov qword [rdi+sizeof(qword)*4], a4 + mov qword [rdi+sizeof(qword)*5], a5 + mov qword [rdi+sizeof(qword)*6], a6 + mov qword [rdi+sizeof(qword)*7], a7 + mov qword [rdi+sizeof(qword)*8], a8 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_neg + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; p521r1_mred(uint64_t res[9], const uint64_t product[9*2]); +; +; modulus = 2^521 -1 +; [17] [0] +; m0 = 1 +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%macro mred_step 12.nolist + %xdefine %%EX %1 + %xdefine %%X8 %2 + %xdefine %%X7 %3 + %xdefine %%X6 %4 + %xdefine %%X5 %5 + %xdefine %%X4 %6 + %xdefine %%X3 %7 + %xdefine %%X2 %8 + %xdefine %%X1 %9 + %xdefine %%X0 %10 + %xdefine %%T %11 + %xdefine %%CF %12 + + mov %%T, %%X0 ;; u0 = X0 + shr %%T, (64-(521-512)) ;; (T:X0) = u0<<9 + shl %%X0, (521-512) + add %%T, %%CF + + add %%X8, %%X0 + adc %%EX, %%T + mov %%CF, dword 0 + adc %%CF, 0 +%endmacro + +align IPP_ALIGN_FACTOR +IPPASM p521r1_mred,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 +%xdefine a4 r12 +%xdefine a5 r13 +%xdefine a6 r14 +%xdefine a7 r15 +%xdefine a8 rax +%xdefine ex rcx + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + mov a4, qword [rsi+sizeof(qword)*4] + mov a5, qword [rsi+sizeof(qword)*5] + mov a6, qword [rsi+sizeof(qword)*6] + mov a7, qword [rsi+sizeof(qword)*7] + mov a8, qword [rsi+sizeof(qword)*8] + mov ex, qword [rsi+sizeof(qword)*9] + +%xdefine t rbx +%xdefine carry rdx + + xor carry, carry + mred_step ex,a8,a7,a6,a5,a4,a3,a2,a1,a0, t,carry ;; step 0 {rcx,rax,r15,r14,r13,r12,r11,r10,r9,r8} -> {rcx,rax,r15,r14,r13,r12,r11,r10,r9,--} + + mov a0, qword [rsi+sizeof(qword)*10] + mred_step a0,ex,a8,a7,a6,a5,a4,a3,a2,a1, t,carry ;; step 1 {r8,rcx,rax,r15,r14,r13,r12,r11,r10,r9} -> {r8,rcx,rax,r15,r14,r13,r12,r11,r10,--} + + mov a1, qword [rsi+sizeof(qword)*11] + mred_step a1,a0,ex,a8,a7,a6,a5,a4,a3,a2, t,carry ;; step 2 {r9,r8,rcx,rax,r15,r14,r13,r12,r11,r10} -> {r9,r8,rcx,rax,r15,r14,r13,r12,r11, --} + + mov a2, qword [rsi+sizeof(qword)*12] + mred_step a2,a1,a0,ex,a8,a7,a6,a5,a4,a3, t,carry ;; step 3 {r10,r9,r8,rcx,rax,r15,r14,r13,r12,r11} -> {r10,r9,r8,rcx,rax,r15,r14,r13,r12, --} + + mov a3, qword [rsi+sizeof(qword)*13] + mred_step a3,a2,a1,a0,ex,a8,a7,a6,a5,a4, t,carry ;; step 4 {r11,r10,r9,r8,rcx,rax,r15,r14,r13,r12} -> {r11,r10,r9,r8,rcx,rax,r15,r14,r13, --} + + mov a4, qword [rsi+sizeof(qword)*14] + mred_step a4,a3,a2,a1,a0,ex,a8,a7,a6,a5, t,carry ;; step 5 {r12,r11,r10,r9,r8,rcx,rax,r15,r14,r13} -> {r12,r11,r10,r9,r8,rcx,rax,r15,r14, --} + + mov a5, qword [rsi+sizeof(qword)*15] + mred_step a5,a4,a3,a2,a1,a0,ex,a8,a7,a6, t,carry ;; step 6 {r13,r12,r11,r10,r9,r8,rcx,rax,r15,r14} -> {r13,r12,r11,r10,r9,r8,rcx,rax,r15, --} + + mov a6, qword [rsi+sizeof(qword)*16] + mred_step a6,a5,a4,a3,a2,a1,a0,ex,a8,a7, t,carry ;; step 7 {r14,r13,r12,r11,r10,r9,r8,rcx,rax,r15} -> {r14,r13,r12,r11,r10,r9,r8,rcx,rax, --} + + mov a7, qword [rsi+sizeof(qword)*17] + mred_step a7,a6,a5,a4,a3,a2,a1,a0,ex,a8, t,carry ;; step 8 {r15,r14,r13,r12,r11,r10,r9,r8,rcx,rax} -> {r15,r14,r13,r12,r11,r10,r9,r8,rcx, --} + + ;; temporary result: a8,a7,a6,a5,a4,a3,a2,a1,a0,ex + mov qword [rdi+sizeof(qword)*0], ex + mov qword [rdi+sizeof(qword)*1], a0 + mov qword [rdi+sizeof(qword)*2], a1 + mov qword [rdi+sizeof(qword)*3], a2 + mov qword [rdi+sizeof(qword)*4], a3 + mov qword [rdi+sizeof(qword)*5], a4 + mov qword [rdi+sizeof(qword)*6], a5 + mov qword [rdi+sizeof(qword)*7], a6 + mov qword [rdi+sizeof(qword)*8], a7 + + ;; sub modulus + sub ex, qword [rel Lpoly+sizeof(qword)*0] + sbb a0, qword [rel Lpoly+sizeof(qword)*1] + sbb a1, qword [rel Lpoly+sizeof(qword)*2] + sbb a2, qword [rel Lpoly+sizeof(qword)*3] + sbb a3, qword [rel Lpoly+sizeof(qword)*4] + sbb a4, qword [rel Lpoly+sizeof(qword)*5] + sbb a5, qword [rel Lpoly+sizeof(qword)*6] + sbb a6, qword [rel Lpoly+sizeof(qword)*7] + sbb a7, qword [rel Lpoly+sizeof(qword)*8] + + ;; masked copy + mov t, qword [rdi+sizeof(qword)*0] + cmovb ex, t + mov t, qword [rdi+sizeof(qword)*1] + cmovb a0, t + mov t, qword [rdi+sizeof(qword)*2] + cmovb a1, t + mov t, qword [rdi+sizeof(qword)*3] + cmovb a2, t + mov t, qword [rdi+sizeof(qword)*4] + cmovb a3, t + mov t, qword [rdi+sizeof(qword)*5] + cmovb a4, t + mov t, qword [rdi+sizeof(qword)*6] + cmovb a5, t + mov t, qword [rdi+sizeof(qword)*7] + cmovb a6, t + mov t, qword [rdi+sizeof(qword)*8] + cmovb a7, t + + ;; store result: a7,a6,a5,a4,a3,a2,a1,a0,ex + mov qword [rdi+sizeof(qword)*0], ex + mov qword [rdi+sizeof(qword)*1], a0 + mov qword [rdi+sizeof(qword)*2], a1 + mov qword [rdi+sizeof(qword)*3], a2 + mov qword [rdi+sizeof(qword)*4], a3 + mov qword [rdi+sizeof(qword)*5], a4 + mov qword [rdi+sizeof(qword)*6], a5 + mov qword [rdi+sizeof(qword)*7], a6 + mov qword [rdi+sizeof(qword)*8], a7 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_mred + +%ifndef _DISABLE_ECP_521R1_HARDCODED_BP_TBL_ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; affine point selector +; +; void p521r1_select_ap_w5(AF_POINT *val, const AF_POINT *tbl, int idx); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM p521r1_select_ap_w5,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm14 + COMP_ABI 3 + +%xdefine val rdi +%xdefine in_t rsi +%xdefine idx edx + +%xdefine xyz0 xmm0 +%xdefine xyz1 xmm1 +%xdefine xyz2 xmm2 +%xdefine xyz3 xmm3 +%xdefine xyz4 xmm4 +%xdefine xyz5 xmm5 +%xdefine xyz6 xmm6 +%xdefine xyz7 xmm7 +%xdefine xyz8 xmm8 + +%xdefine REQ_IDX xmm9 +%xdefine CUR_IDX xmm10 +%xdefine MASKDATA xmm11 +%xdefine TMP xmm12 + + movdqa CUR_IDX, oword [rel LOne] + + movd REQ_IDX, idx + pshufd REQ_IDX, REQ_IDX, 0 + + pxor xyz0, xyz0 + pxor xyz1, xyz1 + pxor xyz2, xyz2 + pxor xyz3, xyz3 + pxor xyz4, xyz4 + pxor xyz5, xyz5 + pxor xyz6, xyz6 + pxor xyz7, xyz7 + pxor xyz8, xyz8 + + ; Skip index = 0, is implicictly infty -> load with offset -1 + mov rcx, dword 16 +.select_loop: + movdqa MASKDATA, CUR_IDX ; MASK = CUR_IDX==REQ_IDX? 0xFF : 0x00 + pcmpeqd MASKDATA, REQ_IDX ; + paddd CUR_IDX, oword [rel LOne] + + movdqa TMP, oword [in_t+sizeof(oword)*0] + pand TMP, MASKDATA + por xyz0, TMP + movdqa TMP, oword [in_t+sizeof(oword)*1] + pand TMP, MASKDATA + por xyz1, TMP + movdqa TMP, oword [in_t+sizeof(oword)*2] + pand TMP, MASKDATA + por xyz2, TMP + movdqa TMP, oword [in_t+sizeof(oword)*3] + pand TMP, MASKDATA + por xyz3, TMP + movdqa TMP, oword [in_t+sizeof(oword)*4] + pand TMP, MASKDATA + por xyz4, TMP + movdqa TMP, oword [in_t+sizeof(oword)*5] + pand TMP, MASKDATA + por xyz5, TMP + movdqa TMP, oword [in_t+sizeof(oword)*6] + pand TMP, MASKDATA + por xyz6, TMP + movdqa TMP, oword [in_t+sizeof(oword)*7] + pand TMP, MASKDATA + por xyz7, TMP + movdqa TMP, oword [in_t+sizeof(oword)*8] + pand TMP, MASKDATA + por xyz8, TMP + + add in_t, sizeof(qword)*(9*2) + dec rcx + jnz .select_loop + + movdqu oword [val+sizeof(oword)*0], xyz0 + movdqu oword [val+sizeof(oword)*1], xyz1 + movdqu oword [val+sizeof(oword)*2], xyz2 + movdqu oword [val+sizeof(oword)*3], xyz3 + movdqu oword [val+sizeof(oword)*4], xyz4 + movdqu oword [val+sizeof(oword)*5], xyz5 + movdqu oword [val+sizeof(oword)*6], xyz6 + movdqu oword [val+sizeof(oword)*7], xyz7 + movdqu oword [val+sizeof(oword)*8], xyz8 + + REST_XMM + REST_GPR + ret +ENDFUNC p521r1_select_ap_w5 + +%endif + +%endif ;; _IPP32E_M7 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcppurgeblkm7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcppurgeblkm7as.asm new file mode 100644 index 000000000..b02619a2e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcppurgeblkm7as.asm @@ -0,0 +1,78 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Purge block +; +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: Clear memory block +;* +;* void PurgeBlock(Ipp8u *pDst, int len) +;* +;*************************************************************** + +;; +;; Lib = M7 +;; +align IPP_ALIGN_FACTOR +IPPASM PurgeBlock,PUBLIC + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 2 +;; rdi: pDst: BYTE, ; mem being clear +;; rsi: len: DWORD ; length + + movsxd rcx, esi ; store stream length + xor rax, rax + sub rcx, sizeof(qword) + jl .test_purge +.purge8: + mov qword [rdi], rax ; clear + add rdi, sizeof(qword) + sub rcx, sizeof(qword) + jge .purge8 + +.test_purge: + add rcx, sizeof(qword) + jz .quit +.purge1: + mov byte [rdi], al + add rdi, sizeof(byte) + sub rcx, sizeof(byte) + jg .purge1 + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC PurgeBlock + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprc4m7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprc4m7as.asm new file mode 100644 index 000000000..4991757e6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprc4m7as.asm @@ -0,0 +1,114 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; ARCFour +; +; Content: +; ARCFourKernel() +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: RC4 kernel +;* +;* void ARCFourProcessData(const Ipp8u *pSrc, Ipp8u *pDst, int len, +;* IppsARCFourState* pCtx) +;* +;*************************************************************** + +;; +;; Lib = M7 +;; +;; Caller = ippsARCFourEncrypt +;; Caller = ippsARCFourDecrypt +;; +align IPP_ALIGN_FACTOR +IPPASM ARCFourProcessData,PUBLIC + USES_GPR rsi,rdi,rbx,rbp + USES_XMM + COMP_ABI 4 +;; rdi: pSrc: BYTE, ; input stream +;; rsi: pDst: BYTE, ; output stream +;; rdx: len: DWORD, ; stream length +;; rcx: pCtx: BYTE ; context + + movsxd r8, edx + test r8, r8 ; test length + mov rbp, rcx ; copy pointer context + jz .quit + + movzx rax, byte [rbp+4] ; extract x + movzx rbx, byte [rbp+8] ; extract y + + lea rbp, [rbp+12] ; sbox + + add rax,1 ; x = (x+1)&0xFF + movzx rax, al + movzx rcx, byte [rbp+rax*4] ; tx = S[x] + +;; +;; main code +;; +align IPP_ALIGN_FACTOR +.main_loop: + add rbx, rcx ; y = (x+tx)&0xFF + movzx rbx, bl + add rdi, 1 + add rsi, 1 + movzx rdx, byte [rbp+rbx*4] ; ty = S[y] + + mov dword [rbp+rbx*4],ecx ; S[y] = tx + add rcx, rdx ; tmp_idx = (tx+ty)&0xFF + movzx rcx, cl + mov dword [rbp+rax*4],edx ; S[x] = ty + + mov dl, byte [rbp+rcx*4] ; byte of gamma + add rax, 1 ; next x = (x+1)&0xFF + movzx rax, al + + xor dl,byte [rdi-1] ; gamma ^= src + sub r8, 1 + movzx rcx, byte [rbp+rax*4] ; next tx = S[x] + mov byte [rsi-1],dl ; store result + jne .main_loop + + lea rbp, [rbp-12] ; pointer to context + + sub rax, 1 ; actual new x counter + movzx rax, al + mov dword [rbp+4], eax ; update x conter + mov dword [rbp+8], ebx ; updtae y counter + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC ARCFourProcessData + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128ccme9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128ccme9as.asm new file mode 100644 index 000000000..66ff4b520 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128ccme9as.asm @@ -0,0 +1,289 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; AuthEncrypt_RIJ128_AES_NI() +; DecryptAuth_RIJ128_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +u128_str DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +increment DQ 1,0 + +;*************************************************************** +;* Purpose: Authenticate and Encrypt +;* +;* void AuthEncrypt_RIJ128_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp32u len, +;* Ipp8u* pLocalState) +;* inp localCtx: +;* MAC +;* CTRi +;* CTRi mask +;* +;* out localCtx: +;* new MAC +;* S = enc(CTRi) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAES_CCMEncrypt +;; +align IPP_ALIGN_FACTOR +IPPASM AuthEncrypt_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7 + COMP_ABI 6 +;; rdi: pInpBlk: BYTE, ; input blocks address +;; rsi: pOutBlk: BYTE, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: BYTE, ; key material address +;; r8d length: DWORD, ; length (bytes) +;; r9 pLocCtx: BYTE ; pointer to the localState + +%assign BYTES_PER_BLK (16) + + movdqa xmm0, oword [r9] ; MAC + movdqa xmm2, oword [r9+sizeof(oword)] ; CTRi block + movdqa xmm1, oword [r9+sizeof(oword)*2] ; CTR mask + + movdqa xmm7, oword [rel u128_str] + + pshufb xmm2, xmm7 ; CTRi block (LE) + pshufb xmm1, xmm7 ; CTR mask + + movdqa xmm3, xmm1 + pandn xmm3, xmm2 ; CTR block template + pand xmm2, xmm1 ; CTR value + + mov r8d, r8d ; expand length + movsxd rdx, edx ; expand number of rounds + + lea rdx, [rdx*4] ; nrCounter = -nr*16 + lea rdx, [rdx*4] ; pKey += nr*16 + lea rcx, [rcx+rdx] + neg rdx + mov rbx, rdx + +align IPP_ALIGN_FACTOR +;; +;; block-by-block processing +;; +.blk_loop: + movdqu xmm4, oword [rdi] ; input block src[i] + pxor xmm0, xmm4 ; MAC ^= src[i] + + movdqa xmm5, xmm3 + paddq xmm2, oword [rel increment] ; advance counter bits + pand xmm2, xmm1 ; and mask them + por xmm5, xmm2 + pshufb xmm5, xmm7 ; CTRi (BE) + + movdqa xmm6, oword [rcx+rdx] ; keys for whitening + add rdx, 16 + + pxor xmm5, xmm6 ; whitening (CTRi) + pxor xmm0, xmm6 ; whitening (MAC) + + movdqa xmm6, oword [rcx+rdx] ; pre load operation's keys + +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm5, xmm6 ; regular round (CTRi) + aesenc xmm0, xmm6 ; regular round (MAC) + movdqa xmm6, oword [rcx+rdx+16] + add rdx, 16 + jnz .cipher_loop + aesenclast xmm5, xmm6 ; irregular round (CTRi) + aesenclast xmm0, xmm6 ; irregular round (MAC) + + pxor xmm4, xmm5 ; dst[i] = src[i] ^ ENC(CTRi) + movdqu oword [rsi], xmm4 + + mov rdx, rbx + add rsi, BYTES_PER_BLK + add rdi, BYTES_PER_BLK + sub r8, BYTES_PER_BLK + jnz .blk_loop + + movdqu oword [r9], xmm0 ; update MAC value + movdqu oword [r9+sizeof(oword)], xmm5 ; update ENC(Ctri) + + pxor xmm6, xmm6 + + REST_XMM + REST_GPR + ret +ENDFUNC AuthEncrypt_RIJ128_AES_NI + +;*************************************************************** +;* Purpose: Decrypt and Authenticate +;* +;* void DecryptAuth_RIJ128_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int nr, +;* const Ipp8u* pRKey, +;* Ipp32u len, +;* Ipp8u* pLocalState) +;* inp localCtx: +;* MAC +;* CTRi +;* CTRi mask +;* +;* out localCtx: +;* new MAC +;* S = enc(CTRi) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAES_CCMDecrypt +;; +align IPP_ALIGN_FACTOR +IPPASM DecryptAuth_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME sizeof(qword) + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7 + COMP_ABI 6 +;; rdi: pInpBlk: BYTE, ; input blocks address +;; rsi: pOutBlk: BYTE, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: BYTE, ; key material address +;; r8d length: DWORD, ; length (bytes) +;; r9 pLocCtx: BYTE ; pointer to the localState + +%assign BYTES_PER_BLK (16) + + movdqa xmm0, oword [r9] ; MAC + movdqa xmm2, oword [r9+sizeof(oword)] ; CTRi block + movdqa xmm1, oword [r9+sizeof(oword)*2] ; CTR mask + + movdqa xmm7, oword [rel u128_str] + + pshufb xmm2, xmm7 ; CTRi block (LE) + pshufb xmm1, xmm7 ; CTR mask + + movdqa xmm3, xmm1 + pandn xmm3, xmm2 ; CTR block template + pand xmm2, xmm1 ; CTR value + + mov r8d, r8d ; expand length + movsxd rdx, edx ; expand number of rounds + + lea rdx, [rdx*4] ; nrCounter = -nr*16 + lea rdx, [rdx*4] ; pKey += nr*16 + lea rcx, [rcx+rdx] + neg rdx + mov rbx, rdx + +align IPP_ALIGN_FACTOR +;; +;; block-by-block processing +;; +.blk_loop: + + ;;;;;;;;;;;;;;;;; + ;; decryption + ;;;;;;;;;;;;;;;;; + movdqu xmm4, oword [rdi] ; input block src[i] + + movdqa xmm5, xmm3 + paddq xmm2, oword [rel increment] ; advance counter bits + pand xmm2, xmm1 ; and mask them + por xmm5, xmm2 + pshufb xmm5, xmm7 ; CTRi (BE) + + movdqa xmm6, oword [rcx+rdx] ; keys for whitening + add rdx, 16 + + pxor xmm5, xmm6 ; whitening (CTRi) + movdqa xmm6, oword [rcx+rdx] ; pre load operation's keys + +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm5, xmm6 ; regular round (CTRi) + movdqa xmm6, oword [rcx+rdx+16] + add rdx, 16 + jnz .cipher_loop + aesenclast xmm5, xmm6 ; irregular round (CTRi) + + pxor xmm4, xmm5 ; dst[i] = src[i] ^ ENC(CTRi) + movdqu oword [rsi], xmm4 + + ;;;;;;;;;;;;;;;;; + ;; update MAC + ;;;;;;;;;;;;;;;;; + mov rdx, rbx + + movdqa xmm6, oword [rcx+rdx] ; keys for whitening + add rdx, 16 + + pxor xmm0, xmm4 ; MAC ^= dst[i] + pxor xmm0, xmm6 ; whitening (MAC) + + movdqa xmm6, oword [rcx+rdx] ; pre load operation's keys + +align IPP_ALIGN_FACTOR +.auth_loop: + aesenc xmm0, xmm6 ; regular round (MAC) + movdqa xmm6, oword [rcx+rdx+16] + add rdx, 16 + jnz .auth_loop + aesenclast xmm0, xmm6 ; irregular round (MAC) + + + mov rdx, rbx + add rsi, BYTES_PER_BLK + add rdi, BYTES_PER_BLK + sub r8, BYTES_PER_BLK + jnz .blk_loop + + movdqu oword [r9], xmm0 ; update MAC value + movdqu oword [r9+sizeof(oword)], xmm6 ; update ENC(Ctri) + + pxor xmm6, xmm6 + + REST_XMM + REST_GPR + ret +ENDFUNC DecryptAuth_RIJ128_AES_NI + +%endif +%endif ;; _AES_NI_ENABLING_ + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128cmace9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128cmace9as.asm new file mode 100644 index 000000000..97a55f2ff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128cmace9as.asm @@ -0,0 +1,114 @@ +;=============================================================================== +; Copyright (C) 2018 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; cpAESCMAC_Update_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: AES-CMAC update +;* +;* void cpAESCMAC_Update_AES_NI(Ipp8u* digest, +;* const Ipp8u* input, +;* int inpLen, +;* int nr, +;* const Ipp32u* pRKey) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAES_CMACUpdate +;; +align IPP_ALIGN_FACTOR +IPPASM cpAESCMAC_Update_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 5 +;; rdi: pDigest: DWORD, ; input blocks address +;; rsi: pInput: DWORD, ; output blocks address +;; rdx: length: DWORD, ; lenght in bytes (multiple 16) +;; rcx: nr: DWORD ; number of rounds +;; r8: pRKey: DWORD ; pointer to keys + +%xdefine SC (4) +%assign BYTES_PER_BLK (16) + + movsxd rdx, edx ; input length + movdqu xmm0, oword [rdi] ; digest + +align IPP_ALIGN_FACTOR +;; +;; pseudo-pipelined processing +;; +.blks_loop: + movdqu xmm1, oword [rsi] ; input block + + movdqa xmm4, oword [r8] + mov r9, r8 ; save pointer to the key material + + pxor xmm0, xmm1 ; digest ^ src[] + + pxor xmm0, xmm4 ; whitening + + movdqa xmm4, oword [r9+16] + add r9, 16 + + mov r10, rcx ; counter depending on key length + sub r10, 1 +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + movdqa xmm4, oword [r9+16] + add r9, 16 + dec r10 + jnz .cipher_loop + aesenclast xmm0, xmm4 ; irregular round + + add rsi, BYTES_PER_BLK ; advance pointers + sub rdx, BYTES_PER_BLK ; decrease counter + jnz .blks_loop + + pxor xmm4, xmm4 + movdqu oword [rdi], xmm0 ; store updated digest digest + + REST_XMM + REST_GPR + ret +ENDFUNC cpAESCMAC_Update_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptcbcpipee9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptcbcpipee9as.asm new file mode 100644 index 000000000..332719760 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptcbcpipee9as.asm @@ -0,0 +1,342 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; DecryptCBC_RIJ128pipe_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: pipelined RIJ128 CBC decryption +;* +;* void DecryptCBC_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len, +;* const Ipp8u* pIV) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAESDecryptCBC +;; + +%assign AES_BLOCK (16) + +align IPP_ALIGN_FACTOR +IPPASM DecryptCBC_RIJ128pipe_AES_NI,PUBLIC +%assign LOCAL_FRAME ((1+8)*AES_BLOCK) + USES_GPR rsi,rdi,rbx + USES_XMM xmm15 + COMP_ABI 6 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d length: DWORD ; length (bytes) +;; r9 pIV BYTE ; pointer to the IV + +%xdefine SC (4) + + movdqu xmm15, oword [r9] ; IV + movsxd r8, r8d ; processed length + + lea rax,[rdx*SC] ; keys offset + + cmp r8, (4*AES_BLOCK) + jl .short123_input + cmp r8, (16*AES_BLOCK) + jle .block4x + +;; +;; 8-blocks processing +;; + mov rbx, rsp ; rbx points on cipher's data in stack + + sub rsp, sizeof(oword)*4 ; allocate stack and xmm registers + movdqa oword [rsp+0*sizeof(oword)], xmm6 + movdqa oword [rsp+1*sizeof(oword)], xmm7 + movdqa oword [rsp+2*sizeof(oword)], xmm8 + movdqa oword [rsp+3*sizeof(oword)], xmm9 + + sub r8, (8*AES_BLOCK) + +align IPP_ALIGN_FACTOR +.blk8_loop: + lea r9,[rcx+rax*sizeof(dword)-AES_BLOCK]; pointer to the key material + + movdqu xmm0, oword [rdi+0*AES_BLOCK] ; get input blocks + movdqu xmm1, oword [rdi+1*AES_BLOCK] + movdqu xmm2, oword [rdi+2*AES_BLOCK] + movdqu xmm3, oword [rdi+3*AES_BLOCK] + movdqu xmm6, oword [rdi+4*AES_BLOCK] + movdqu xmm7, oword [rdi+5*AES_BLOCK] + movdqu xmm8, oword [rdi+6*AES_BLOCK] + movdqu xmm9, oword [rdi+7*AES_BLOCK] + + movdqa xmm5, oword [r9+AES_BLOCK] ; whitening keys + movdqa xmm4, oword [r9] ; pre load operation's keys + + movdqa oword [rbx+1*AES_BLOCK], xmm0 ; save input into the stack + pxor xmm0, xmm5 ; and do whitening + movdqa oword [rbx+2*AES_BLOCK], xmm1 + pxor xmm1, xmm5 + movdqa oword [rbx+3*AES_BLOCK], xmm2 + pxor xmm2, xmm5 + movdqa oword [rbx+4*AES_BLOCK], xmm3 + pxor xmm3, xmm5 + movdqa oword [rbx+5*AES_BLOCK], xmm6 + pxor xmm6, xmm5 + movdqa oword [rbx+6*AES_BLOCK], xmm7 + pxor xmm7, xmm5 + movdqa oword [rbx+7*AES_BLOCK], xmm8 + pxor xmm8, xmm5 + movdqa oword [rbx+8*AES_BLOCK], xmm9 + pxor xmm9, xmm5 + + movdqa xmm5, oword [r9-AES_BLOCK] ; pre load operation's keys + sub r9, (2*AES_BLOCK) + + lea r10, [rdx-2] ; counter = nrounds-2 +align IPP_ALIGN_FACTOR +.cipher_loop8: + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + aesdec xmm6, xmm4 + aesdec xmm7, xmm4 + aesdec xmm8, xmm4 + aesdec xmm9, xmm4 + movdqa xmm4, oword [r9] ; pre load operation's keys + + aesdec xmm0, xmm5 ; regular round + aesdec xmm1, xmm5 + aesdec xmm2, xmm5 + aesdec xmm3, xmm5 + aesdec xmm6, xmm5 + aesdec xmm7, xmm5 + aesdec xmm8, xmm5 + aesdec xmm9, xmm5 + movdqa xmm5, oword [r9-AES_BLOCK] ; pre load operation's keys + sub r9, (2*AES_BLOCK) + + sub r10, 2 + jnz .cipher_loop8 + + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + aesdec xmm6, xmm4 + aesdec xmm7, xmm4 + aesdec xmm8, xmm4 + aesdec xmm9, xmm4 + + aesdeclast xmm0, xmm5 ; irregular round, ^IV, and store result + pxor xmm0, xmm15 + movdqu oword [rsi+0*AES_BLOCK], xmm0 + aesdeclast xmm1, xmm5 + pxor xmm1, oword [rbx+1*AES_BLOCK] + movdqu oword [rsi+1*AES_BLOCK], xmm1 + aesdeclast xmm2, xmm5 + pxor xmm2, oword [rbx+2*AES_BLOCK] + movdqu oword [rsi+2*AES_BLOCK], xmm2 + aesdeclast xmm3, xmm5 + pxor xmm3, oword [rbx+3*AES_BLOCK] + movdqu oword [rsi+3*AES_BLOCK], xmm3 + aesdeclast xmm6, xmm5 + pxor xmm6, oword [rbx+4*AES_BLOCK] + movdqu oword [rsi+4*AES_BLOCK], xmm6 + aesdeclast xmm7, xmm5 + pxor xmm7, oword [rbx+5*AES_BLOCK] + movdqu oword [rsi+5*AES_BLOCK], xmm7 + aesdeclast xmm8, xmm5 + pxor xmm8, oword [rbx+6*AES_BLOCK] + movdqu oword [rsi+6*AES_BLOCK], xmm8 + aesdeclast xmm9, xmm5 + pxor xmm9, oword [rbx+7*AES_BLOCK] + movdqu oword [rsi+7*AES_BLOCK], xmm9 + + movdqa xmm15,oword [rbx+8*AES_BLOCK] ; update IV + + add rsi, (8*AES_BLOCK) + add rdi, (8*AES_BLOCK) + sub r8, (8*AES_BLOCK) + jge .blk8_loop + + movdqa xmm6, oword [rsp+0*sizeof(oword)] ; restore xmm registers + movdqa xmm7, oword [rsp+1*sizeof(oword)] + movdqa xmm8, oword [rsp+2*sizeof(oword)] + movdqa xmm9, oword [rsp+3*sizeof(oword)] + add rsp, sizeof(oword)*4 ; and release stack + + add r8, (8*AES_BLOCK) + jz .quit + +;; +;; test %if 4-blocks processing alaivalbe +;; +.block4x: + cmp r8, (4*AES_BLOCK) + jl .short123_input + sub r8, (4*AES_BLOCK) + +align IPP_ALIGN_FACTOR +.blk4_loop: + lea r9,[rcx+rax*sizeof(dword)-AES_BLOCK]; pointer to the key material + + movdqu xmm0, oword [rdi+0*AES_BLOCK] ; get input blocks + movdqu xmm1, oword [rdi+1*AES_BLOCK] + movdqu xmm2, oword [rdi+2*AES_BLOCK] + movdqu xmm3, oword [rdi+3*AES_BLOCK] + + movdqa xmm5, oword [r9+AES_BLOCK] ; whitening keys + movdqa xmm4, oword [r9] ; pre load operation's keys + + movdqa oword [rsp+1*AES_BLOCK], xmm0 ; save input into the stack + pxor xmm0, xmm5 ; and do whitening + movdqa oword [rsp+2*AES_BLOCK], xmm1 + pxor xmm1, xmm5 + movdqa oword [rsp+3*AES_BLOCK], xmm2 + pxor xmm2, xmm5 + movdqa oword [rsp+4*AES_BLOCK], xmm3 + pxor xmm3, xmm5 + + movdqa xmm5, oword [r9-AES_BLOCK] ; pre load operation's keys + sub r9, (2*AES_BLOCK) + + lea r10, [rdx-2] ; counter = nrounds-2 +align IPP_ALIGN_FACTOR +.cipher_loop4: + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + movdqa xmm4, oword [r9] ; pre load operation's keys + + aesdec xmm0, xmm5 ; regular round + aesdec xmm1, xmm5 + aesdec xmm2, xmm5 + aesdec xmm3, xmm5 + movdqa xmm5, oword [r9-AES_BLOCK] ; pre load operation's keys + sub r9, (2*AES_BLOCK) + + sub r10, 2 + jnz .cipher_loop4 + + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + + aesdeclast xmm0, xmm5 ; irregular round, ^IV, and store result + pxor xmm0, xmm15 + movdqu oword [rsi+0*AES_BLOCK], xmm0 + aesdeclast xmm1, xmm5 + pxor xmm1, oword [rsp+1*AES_BLOCK] + movdqu oword [rsi+1*AES_BLOCK], xmm1 + aesdeclast xmm2, xmm5 + pxor xmm2, oword [rsp+2*AES_BLOCK] + movdqu oword [rsi+2*AES_BLOCK], xmm2 + aesdeclast xmm3, xmm5 + pxor xmm3, oword [rsp+3*AES_BLOCK] + movdqu oword [rsi+3*AES_BLOCK], xmm3 + + movdqa xmm15,oword [rsp+4*AES_BLOCK] ; update IV + + add rsi, (4*AES_BLOCK) + add rdi, (4*AES_BLOCK) + sub r8, (4*AES_BLOCK) + jge .blk4_loop + + add r8, (4*AES_BLOCK) + jz .quit + +;; +;; block-by-block processing +;; +.short123_input: + lea r9,[rcx+rax*sizeof(dword)] ; pointer to the key material (whitening) + +align IPP_ALIGN_FACTOR +.single_blk_loop: + movdqu xmm0, oword [rdi] ; get input block + add rdi, AES_BLOCK + movdqa xmm1, xmm0 ; and save as IV for future + + pxor xmm0, oword [r9] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesdec xmm0, oword [rcx+9*SC*4+4*SC*4] + aesdec xmm0, oword [rcx+9*SC*4+3*SC*4] +.key_192_s: + aesdec xmm0, oword [rcx+9*SC*4+2*SC*4] + aesdec xmm0, oword [rcx+9*SC*4+1*SC*4] +.key_128_s: + aesdec xmm0, oword [rcx+9*SC*4-0*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-1*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-2*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-3*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-4*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-5*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-6*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-7*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-8*SC*4] + aesdeclast xmm0, oword [rcx+9*SC*4-9*SC*4] + + pxor xmm0, xmm15 ; add IV + movdqu oword [rsi], xmm0 ; and save output blocl + add rsi, AES_BLOCK + + sub r8, AES_BLOCK + movdqa xmm15, xmm1 ; update IV + + jnz .single_blk_loop + +.quit: + pxor xmm4, xmm4 + pxor xmm5, xmm5 + + REST_XMM + REST_GPR + ret +ENDFUNC DecryptCBC_RIJ128pipe_AES_NI + +%endif ;; _IPP32E >= _IPP32E_Y8 +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptcfbpipee9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptcfbpipee9as.asm new file mode 100644 index 000000000..4a7461f7b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptcfbpipee9as.asm @@ -0,0 +1,562 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Decrypt_RIJ128_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + + +%macro COPY_8U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor rcx, rcx +%%next_byte: + mov %%tmp, byte [%%src+rcx] + mov byte [%%dst+rcx], %%tmp + add rcx, 1 + cmp rcx, %%limit + jl %%next_byte +%endmacro + +%macro COPY_32U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor rcx, rcx +%%next_dword: + mov %%tmp, dword [%%src+rcx] + mov dword [%%dst+rcx], %%tmp + add rcx, 4 + cmp rcx, %%limit + jl %%next_dword +%endmacro + +%macro COPY_128U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor rcx, rcx +%%next_oword: + movdqu %%tmp, oword [%%src+rcx] + movdqu oword [%%dst+rcx], %%tmp + add rcx, 16 + cmp rcx, %%limit + jl %%next_oword +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: pipelined RIJ128 CFB decryption +;* +;* void DecryptCFB_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int cfbBlks, +;* int cfbSize, +;* const Ipp8u* pIV) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsRijndael128DecryptCFB +;; +align IPP_ALIGN_FACTOR +IPPASM DecryptCFB_RIJ128pipe_AES_NI,PUBLIC +%assign LOCAL_FRAME (1+4+4)*16 + USES_GPR rsi,rdi,r13,r14,r15 + USES_XMM xmm6,xmm7 + COMP_ABI 7 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d cfbBlks: DWORD ; length of stream in cfbSize +;; r9d cfbSize: DWORD ; cfb blk size +;; [rsp+ARG_7] pIV BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + mov rax, [rsp+ARG_7] ; IV address + movdqu xmm4, oword [rax] ; get IV + movdqa oword [rsp+0*16], xmm4 ; into the stack + + mov r13, rdi + mov r14, rsi + mov r15, rcx + + movsxd r8, r8d ; length of stream + movsxd r9, r9d ; cfb blk size + + sub r8, BLKS_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; + lea r10, [r9*BLKS_PER_LOOP] +.blks_loop: + COPY_32U {rsp+16}, r13, r10, r11d ; move 4 input blocks to stack + + movdqa xmm4, oword [r15] + + lea r10, [r9+r9*2] + movdqa xmm0, oword [rsp] ; get encoded blocks + movdqu xmm1, oword [rsp+r9] + movdqu xmm2, oword [rsp+r9*2] + movdqu xmm3, oword [rsp+r10] + + mov r10, r15 ; set pointer to the key material + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [r10+16] ; pre load operation's keys + add r10, 16 + + mov r11, rdx ; counter depending on key length + sub r11, 1 +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [r10+16]; pre load operation's keys + add r10, 16 + dec r11 + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round and IV + aesenclast xmm1, xmm4 + aesenclast xmm2, xmm4 + aesenclast xmm3, xmm4 + + lea r10, [r9+r9*2] ; get src blocks from the stack + movdqa xmm4, oword [rsp+16] + movdqu xmm5, oword [rsp+16+r9] + movdqu xmm6, oword [rsp+16+r9*2] + movdqu xmm7, oword [rsp+16+r10] + + pxor xmm0, xmm4 ; xor src + movdqa oword [rsp+5*16],xmm0;and store into the stack + pxor xmm1, xmm5 + movdqu oword [rsp+5*16+r9], xmm1 + pxor xmm2, xmm6 + movdqu oword [rsp+5*16+r9*2], xmm2 + pxor xmm3, xmm7 + movdqu oword [rsp+5*16+r10], xmm3 + + lea r10, [r9*BLKS_PER_LOOP] + ;COPY_8U r14, {rsp+5*16}, r10 ; move 4 blocks to output + COPY_32U r14, {rsp+5*16}, r10, r11d ; move 4 blocks to output + + movdqu xmm0, oword [rsp+r10]; update IV + movdqu oword [rsp], xmm0 + + add r13, r10 + add r14, r10 + sub r8, BLKS_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add r8, BLKS_PER_LOOP + jz .quit + + lea r10, [r9*2] + lea r11, [r9+r9*2] + cmp r8, 2 + cmovl r10, r9 + cmovg r10, r11 + COPY_8U {rsp+16}, r13, r10, al ; move recent input blocks to stack + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rax, [r15+rax*4-9*(SC)*4] ; AES-128 round keys + + xor r11, r11 ; index +.single_blk_loop: + movdqu xmm0, oword [rsp+r11] ; get encoded block + + pxor xmm0, oword [r15] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + + movdqu xmm1, oword [rsp+r11+16] ; get input block from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [rsp+5*16+r11], xmm0 ; and save output + + add r11, r9 + dec r8 + jnz .single_blk_loop + + COPY_8U r14, {rsp+5*16}, r10, al ; copy rest output from the stack + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC DecryptCFB_RIJ128pipe_AES_NI + +align IPP_ALIGN_FACTOR +IPPASM DecryptCFB32_RIJ128pipe_AES_NI,PUBLIC +%assign LOCAL_FRAME (1+4+4)*16 + USES_GPR rsi,rdi,r13,r14,r15 + USES_XMM xmm6,xmm7 + COMP_ABI 7 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d cfbBlks: DWORD ; length of stream in cfbSize +;; r9d cfbSize: DWORD ; cfb blk size (4 bytes multible) +;; [rsp+ARG_7] pIV BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + mov rax, [rsp+ARG_7] ; IV address + movdqu xmm4, oword [rax] ; get IV + movdqa oword [rsp+0*16], xmm4 ; into the stack + + mov r13, rdi + mov r14, rsi + mov r15, rcx + + movsxd r8, r8d ; length of stream + movsxd r9, r9d ; cfb blk size + + sub r8, BLKS_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; + lea r10, [r9*BLKS_PER_LOOP] +.blks_loop: + COPY_128U {rsp+16}, r13, r10, xmm0 ; move 4 input blocks to stack + + movdqa xmm4, oword [r15] + + lea r10, [r9+r9*2] + movdqa xmm0, oword [rsp] ; get encoded blocks + movdqu xmm1, oword [rsp+r9] + movdqu xmm2, oword [rsp+r9*2] + movdqu xmm3, oword [rsp+r10] + + mov r10, r15 ; set pointer to the key material + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [r10+16] ; pre load operation's keys + add r10, 16 + + mov r11, rdx ; counter depending on key length + sub r11, 1 +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [r10+16]; pre load operation's keys + add r10, 16 + dec r11 + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round and IV + aesenclast xmm1, xmm4 + aesenclast xmm2, xmm4 + aesenclast xmm3, xmm4 + + lea r10, [r9+r9*2] ; get src blocks from the stack + movdqa xmm4, oword [rsp+16] + movdqu xmm5, oword [rsp+16+r9] + movdqu xmm6, oword [rsp+16+r9*2] + movdqu xmm7, oword [rsp+16+r10] + + pxor xmm0, xmm4 ; xor src + movdqa oword [rsp+5*16],xmm0;and store into the stack + pxor xmm1, xmm5 + movdqu oword [rsp+5*16+r9], xmm1 + pxor xmm2, xmm6 + movdqu oword [rsp+5*16+r9*2], xmm2 + pxor xmm3, xmm7 + movdqu oword [rsp+5*16+r10], xmm3 + + lea r10, [r9*BLKS_PER_LOOP] + COPY_128U r14, {rsp+5*16}, r10, xmm0 ; move 4 blocks to output + + movdqu xmm0, oword [rsp+r10] ; update IV + movdqu oword [rsp], xmm0 + + add r13, r10 + add r14, r10 + sub r8, BLKS_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add r8, BLKS_PER_LOOP + jz .quit + + lea r10, [r9*2] + lea r11, [r9+r9*2] + cmp r8, 2 + cmovl r10, r9 + cmovg r10, r11 + COPY_32U {rsp+16}, r13, r10, eax ; move recent input blocks to stack + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rax, [r15+rax*4-9*(SC)*4] ; AES-128 round keys + + xor r11, r11 ; index +.single_blk_loop: + movdqu xmm0, oword [rsp+r11] ; get encoded block + + pxor xmm0, oword [r15] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + + movdqu xmm1, oword [rsp+r11+16] ; get input block from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [rsp+5*16+r11], xmm0 ; and save output + + add r11, r9 + dec r8 + jnz .single_blk_loop + + COPY_32U r14, {rsp+5*16}, r10, eax ; copy rest output from the stack + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC DecryptCFB32_RIJ128pipe_AES_NI + +;; +;; Lib = Y8 +;; +;; Caller = ippsRijndael128DecryptCFB +;; +align IPP_ALIGN_FACTOR +IPPASM DecryptCFB128_RIJ128pipe_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7 + COMP_ABI 6 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d lenBytes: DWORD ; length of stream in bytes +;; r9 pIV BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + movdqu xmm0, oword [r9] ; get IV + + movsxd r8, r8d ; length of the stream + sub r8, BYTES_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +.blks_loop: + movdqa xmm7, oword [rcx] ; get initial key material + mov r10, rcx ; set pointer to the key material + + movdqu xmm1, oword [rdi+0*BYTES_PER_BLK] ; get another encoded cblocks + movdqu xmm2, oword [rdi+1*BYTES_PER_BLK] + movdqu xmm3, oword [rdi+2*BYTES_PER_BLK] + + pxor xmm0, xmm7 ; whitening + pxor xmm1, xmm7 + pxor xmm2, xmm7 + pxor xmm3, xmm7 + + movdqa xmm7, oword [r10+16] ; pre load operation's keys + add r10, 16 + + mov r11, rdx ; counter depending on key length + sub r11, 1 +.cipher_loop: + aesenc xmm0, xmm7 ; regular round + aesenc xmm1, xmm7 + aesenc xmm2, xmm7 + aesenc xmm3, xmm7 + movdqa xmm7, oword [r10+16] ; pre load operation's keys + add r10, 16 + dec r11 + jnz .cipher_loop + + aesenclast xmm0, xmm7 ; irregular round and IV + movdqu xmm4, oword [rdi+0*BYTES_PER_BLK] ; 4 input blocks + aesenclast xmm1, xmm7 + movdqu xmm5, oword [rdi+1*BYTES_PER_BLK] + aesenclast xmm2, xmm7 + movdqu xmm6, oword [rdi+2*BYTES_PER_BLK] + aesenclast xmm3, xmm7 + movdqu xmm7, oword [rdi+3*BYTES_PER_BLK] + add rdi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; 4 output blocks + movdqu oword [rsi+0*16], xmm0 + pxor xmm1, xmm5 + movdqu oword [rsi+1*16], xmm1 + pxor xmm2, xmm6 + movdqu oword [rsi+2*16], xmm2 + pxor xmm3, xmm7 + movdqu oword [rsi+3*16], xmm3 + add rsi, BYTES_PER_LOOP + + movdqa xmm0, xmm7 ; update IV + sub r8, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add r8, BYTES_PER_LOOP + jz .quit + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax, [rdx*4] + lea rax, [rcx+rax*4-9*(SC)*4] ; AES-128 round keys + +.single_blk_loop: + pxor xmm0, oword [rcx] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + + movdqu xmm1, oword [rdi] ; input block from the stream + add rdi, BYTES_PER_BLK + pxor xmm0, xmm1 ; xor src + movdqu oword [rsi], xmm0 ; and save output + add rsi, BYTES_PER_BLK + + movdqa xmm0, xmm1 ; update IV + sub r8, BYTES_PER_BLK + jnz .single_blk_loop + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC DecryptCFB128_RIJ128pipe_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decrypte9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decrypte9as.asm new file mode 100644 index 000000000..8e3a94cf8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decrypte9as.asm @@ -0,0 +1,115 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Decrypt_RIJ128_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + + +segment .text align=IPP_ALIGN_FACTOR + + + +;*************************************************************** +;* Purpose: single block RIJ128 Inverse Cipher +;* +;* void Decrypt_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* const Ipp32u Tables[][256]) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsRijndael128DecryptECB +;; Caller = ippsRijndael128DecryptCBC +;; +align IPP_ALIGN_FACTOR +IPPASM Decrypt_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 4 +;; rdi: pInpBlk: DWORD, ; input block address +;; rsi: pOutBlk: DWORD, ; output block address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address + +%xdefine SC (4) + + + lea rax,[rdx*SC] + lea rax,[rax*4] + + movdqu xmm0, oword [rdi] ; input block + + ;;whitening + pxor xmm0, oword [rcx+rax] + + cmp rdx,12 ; switch according to number of rounds + jl .key_128 + jz .key_192 + + ;; + ;; regular rounds + ;; +.key_256: + aesdec xmm0,oword [rcx+9*SC*4+4*SC*4] + aesdec xmm0,oword [rcx+9*SC*4+3*SC*4] +.key_192: + aesdec xmm0,oword [rcx+9*SC*4+2*SC*4] + aesdec xmm0,oword [rcx+9*SC*4+1*SC*4] +.key_128: + aesdec xmm0,oword [rcx+9*SC*4-0*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-1*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-2*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-3*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-4*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-5*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-6*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-7*SC*4] + aesdec xmm0,oword [rcx+9*SC*4-8*SC*4] + ;; + ;; last rounds + ;; + aesdeclast xmm0,oword [rcx+9*SC*4-9*SC*4] + + movdqu oword [rsi], xmm0 ; output block + + REST_XMM + REST_GPR + ret +ENDFUNC Decrypt_RIJ128_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptecbpipee9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptecbpipee9as.asm new file mode 100644 index 000000000..9ac77b56f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptecbpipee9as.asm @@ -0,0 +1,180 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; DecryptECB_RIJ128pipe_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + + +segment .text align=IPP_ALIGN_FACTOR + +;*************************************************************** +;* Purpose: pipelined RIJ128 ECB decryption +;* +;* void DecryptECB_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAESDecryptECB +;; +align IPP_ALIGN_FACTOR +IPPASM DecryptECB_RIJ128pipe_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 5 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d length: DWORD ; length (bytes) + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + lea rax,[rdx*SC] ; keys offset + + movsxd r8, r8d + sub r8, BYTES_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +;ALIGN IPP_ALIGN_FACTOR +.blks_loop: + lea r9,[rcx+rax*4] ; set pointer to the key material + movdqa xmm4, oword [r9] ; keys for whitening + sub r9, 16 + + movdqu xmm0, oword [rdi+0*BYTES_PER_BLK] ; get input blocks + movdqu xmm1, oword [rdi+1*BYTES_PER_BLK] + movdqu xmm2, oword [rdi+2*BYTES_PER_BLK] + movdqu xmm3, oword [rdi+3*BYTES_PER_BLK] + add rdi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [r9] ; pre load operation's keys + sub r9, 16 + + mov r10, rdx ; counter depending on key length + sub r10, 1 +;ALIGN IPP_ALIGN_FACTOR +.cipher_loop: + aesdec xmm0, xmm4 ; regular round + aesdec xmm1, xmm4 + aesdec xmm2, xmm4 + aesdec xmm3, xmm4 + movdqa xmm4, oword [r9] ; pre load operation's keys + sub r9, 16 + dec r10 + jnz .cipher_loop + + aesdeclast xmm0, xmm4 ; irregular round + movdqu oword [rsi+0*BYTES_PER_BLK], xmm0 ; store output blocks + + aesdeclast xmm1, xmm4 + movdqu oword [rsi+1*BYTES_PER_BLK], xmm1 + + aesdeclast xmm2, xmm4 + movdqu oword [rsi+2*BYTES_PER_BLK], xmm2 + + aesdeclast xmm3, xmm4 + movdqu oword [rsi+3*BYTES_PER_BLK], xmm3 + + add rsi, BYTES_PER_LOOP + sub r8, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add r8, BYTES_PER_LOOP + jz .quit + + lea r9,[rcx+rax*4] ; set pointer to the key material +align IPP_ALIGN_FACTOR +.single_blk_loop: + movdqu xmm0, oword [rdi] ; get input block + add rdi, BYTES_PER_BLK + pxor xmm0, oword [r9] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesdec xmm0, oword [rcx+9*SC*4+4*SC*4] + aesdec xmm0, oword [rcx+9*SC*4+3*SC*4] +.key_192_s: + aesdec xmm0, oword [rcx+9*SC*4+2*SC*4] + aesdec xmm0, oword [rcx+9*SC*4+1*SC*4] +.key_128_s: + aesdec xmm0, oword [rcx+9*SC*4-0*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-1*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-2*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-3*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-4*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-5*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-6*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-7*SC*4] + aesdec xmm0, oword [rcx+9*SC*4-8*SC*4] + aesdeclast xmm0, oword [rcx+9*SC*4-9*SC*4] + + movdqu oword [rsi], xmm0 ; save output block + add rsi, BYTES_PER_BLK + + sub r8, BYTES_PER_BLK + jnz .single_blk_loop + +.quit: + pxor xmm4, xmm4 + + REST_XMM + REST_GPR + ret +ENDFUNC DecryptECB_RIJ128pipe_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptxtse9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptxtse9as.asm new file mode 100644 index 000000000..372eef85d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128decryptxtse9as.asm @@ -0,0 +1,377 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; AES functions +; +; Content: +; cpAESEncryptXTS_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +ALPHA_MUL_CNT dq 00000000000000087h, 00000000000000001h + + +;*************************************************************** +;* Purpose: AES-XTS encryption +;* +;* void cpAESDecryptXTS_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int length, +;* const Ipp8u* pRKey, +;* int nr, +;* Ipp8u* pTweak) +;*************************************************************** + +;; +;; key = ks[0] +;; mul_cnt = {0x0000000000000001:0x0000000000000087} +;; returns: +;; ktwk = twk^key +;; twk = twk*alpha +;; twk2= twk2 *2 - auxillary +;; +%macro OUTER_MUL_X 6.nolist + %xdefine %%ktwk %1 + %xdefine %%twk %2 + %xdefine %%key %3 + %xdefine %%mul_cnt %4 + %xdefine %%twk2 %5 + %xdefine %%mask %6 + + movdqa %%mask, %%twk2 + paddd %%twk2, %%twk2 + movdqa %%ktwk, %%twk + psrad %%mask, 31 + paddq %%twk, %%twk + pand %%mask, %%mul_cnt + pxor %%ktwk, %%key + pxor %%twk, %%mask +%endmacro + +%macro LAST_OUTER_MUL_X 5.nolist + %xdefine %%ktwk %1 + %xdefine %%twk %2 + %xdefine %%key %3 + %xdefine %%mul_cnt %4 + %xdefine %%twk2 %5 + + movdqa %%ktwk, %%twk + psrad %%twk2, 31 + paddq %%twk, %%twk + pand %%twk2, %%mul_cnt + pxor %%ktwk, %%key + pxor %%twk, %%twk2 +%endmacro + +%macro INNER_MUL_X 6.nolist + %xdefine %%ktwk %1 + %xdefine %%twk %2 + %xdefine %%key %3 + %xdefine %%mul_cnt %4 + %xdefine %%twk2 %5 + %xdefine %%mask %6 + + movdqa %%mask, %%twk2 + paddd %%twk2, %%twk2 + psrad %%mask, 31 + paddq %%twk, %%twk + pand %%mask, %%mul_cnt + pxor %%twk, %%mask +%ifnidn %%key,%%ktwk + movdqa %%key, %%ktwk +%endif + pxor %%ktwk, %%twk +%endmacro + +%macro LAST_INNER_MUL_X 3.nolist + %xdefine %%twk %1 + %xdefine %%mul_cnt %2 + %xdefine %%twk2 %3 + + psrad %%twk2, 31 + paddq %%twk, %%twk + pand %%twk2, %%mul_cnt + pxor %%twk, %%twk2 +%endmacro + +align IPP_ALIGN_FACTOR +IPPASM cpAESDecryptXTS_AES_NI,PUBLIC +%assign LOCAL_FRAME sizeof(oword)*6 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 + COMP_ABI 6 +;; rdi: pOutBlk: BYTE ; pointer to the output bloak +;; rsi: pInpBlk: BYTE ; pointer to the input block +;; edx: nBlocks DWORD ; number of blocks +;; rcx: pKey: BYTE ; key material address +;; r8d: nr: DWORD ; number of rounds +;; r9 pTweak: BYTE ; pointer to the input/outpout (ciphertext) tweak + +%assign AES_BLOCK (16) + + movsxd r8, r8d ; number of cipher rounds + + movdqu xmm15, xmmword [r9] ; input tweak value + + shl r8, 4 ; key schedule length (bytes) + + movdqa xmm0, xmmword [rcx+r8] ; key[0] + movdqa xmm8, xmmword [rel ALPHA_MUL_CNT] ; mul constant + + pshufd xmm9, xmm15, 5Fh ; {twk[1]:twk[1]:twk[3]:twk[3]} - auxillary value + + movsxd rdx, edx ; number of blocks being processing + + ;; compute: + ;; - ktwk[i] = twk[i]^key[0] + ;; - twk[i+1] = twk[i]*alpha^(i+1), i=0..5 + OUTER_MUL_X xmm10, xmm15, xmm0, xmm8, xmm9, xmm14 + OUTER_MUL_X xmm11, xmm15, xmm0, xmm8, xmm9, xmm14 + OUTER_MUL_X xmm12, xmm15, xmm0, xmm8, xmm9, xmm14 + OUTER_MUL_X xmm13, xmm15, xmm0, xmm8, xmm9, xmm14 + LAST_OUTER_MUL_X xmm14, xmm15, xmm0, xmm8, xmm9 + + movdqa xmm8, xmm15 ; save tweak for next iteration + pxor xmm15, xmm0 ; add key[0] + + sub rdx, 6 ; test input length + jc .short_input + +;; +;; blocks processing +;; +align IPP_ALIGN_FACTOR +.blks_loop: + pxor xmm0, xmmword [rcx] ; key[0]^key[last] + + lea rax, [r8-6*AES_BLOCK] ; cipher_loop counter + lea r10, [rcx+6*AES_BLOCK] ; mov key pointer down + + movdqu xmm2, xmmword [rsi] ; src[0] - src[7] + movdqu xmm3, xmmword [rsi+AES_BLOCK] + movdqu xmm4, xmmword [rsi+2*AES_BLOCK] + movdqu xmm5, xmmword [rsi+3*AES_BLOCK] + movdqu xmm6, xmmword [rsi+4*AES_BLOCK] + movdqu xmm7, xmmword [rsi+5*AES_BLOCK] + + movdqa xmm1, xmmword [rcx+r8-1*AES_BLOCK] ; key[1] + + pxor xmm2, xmm10 ; src[] ^twk[] ^ key[0] + pxor xmm3, xmm11 + pxor xmm4, xmm12 + pxor xmm5, xmm13 + pxor xmm6, xmm14 + pxor xmm7, xmm15 + + pxor xmm10, xmm0 ; store twk[] ^ key[last] + pxor xmm11, xmm0 + pxor xmm12, xmm0 + pxor xmm13, xmm0 + pxor xmm14, xmm0 + pxor xmm15, xmm0 + movdqa xmm0, xmmword [rcx+r8-2*AES_BLOCK] ; key[2] + + movdqa xmmword [rsp+0*AES_BLOCK], xmm10 + movdqa xmmword [rsp+1*AES_BLOCK], xmm11 + movdqa xmmword [rsp+2*AES_BLOCK], xmm12 + movdqa xmmword [rsp+3*AES_BLOCK], xmm13 + movdqa xmmword [rsp+4*AES_BLOCK], xmm14 + movdqa xmmword [rsp+5*AES_BLOCK], xmm15 + add rsi, 6*AES_BLOCK + +align IPP_ALIGN_FACTOR +.cipher_loop: + sub rax, 2*AES_BLOCK ; dec loop counter + aesdec xmm2, xmm1 ; regular rounds 3 - (last-2) + aesdec xmm3, xmm1 + aesdec xmm4, xmm1 + aesdec xmm5, xmm1 + aesdec xmm6, xmm1 + aesdec xmm7, xmm1 + movdqa xmm1, xmmword [r10+rax-1*AES_BLOCK] + aesdec xmm2, xmm0 + aesdec xmm3, xmm0 + aesdec xmm4, xmm0 + aesdec xmm5, xmm0 + aesdec xmm6, xmm0 + aesdec xmm7, xmm0 + movdqa xmm0, xmmword [r10+rax-2*AES_BLOCK] + jnz .cipher_loop + + movdqa xmm10, xmmword [rcx+r8] ; key[0] + + movdqa xmm15, xmm8 ; restore tweak value + pshufd xmm9, xmm8, 5Fh ; {twk[1]:twk[1]:twk[3]:twk[3]} - auxillary value + movdqa xmm8, xmmword [rel ALPHA_MUL_CNT] ; mul constant + + ; + ; last 6 rounds (5 regular rounds + irregular) + ; merged together with next tweaks computation + ; + aesdec xmm2, xmm1 + aesdec xmm3, xmm1 + aesdec xmm4, xmm1 + aesdec xmm5, xmm1 + aesdec xmm6, xmm1 + aesdec xmm7, xmm1 + movdqa xmm1, xmmword [rcx+3*AES_BLOCK] + + INNER_MUL_X xmm10, xmm15, xmm11, xmm8, xmm9, xmm14 + + aesdec xmm2, xmm0 + aesdec xmm3, xmm0 + aesdec xmm4, xmm0 + aesdec xmm5, xmm0 + aesdec xmm6, xmm0 + aesdec xmm7, xmm0 + movdqa xmm0, xmmword [rcx+2*AES_BLOCK] + + INNER_MUL_X xmm11, xmm15, xmm12, xmm8, xmm9, xmm14 + + aesdec xmm2, xmm1 + aesdec xmm3, xmm1 + aesdec xmm4, xmm1 + aesdec xmm5, xmm1 + aesdec xmm6, xmm1 + aesdec xmm7, xmm1 + movdqa xmm1, xmmword [rcx+1*AES_BLOCK] + + INNER_MUL_X xmm12, xmm15, xmm13, xmm8, xmm9, xmm14 + + aesdec xmm2, xmm0 + aesdec xmm3, xmm0 + aesdec xmm4, xmm0 + aesdec xmm5, xmm0 + aesdec xmm6, xmm0 + aesdec xmm7, xmm0 + + INNER_MUL_X xmm13, xmm15, xmm14, xmm8, xmm9, xmm14 + + aesdec xmm2, xmm1 + aesdec xmm3, xmm1 + aesdec xmm4, xmm1 + aesdec xmm5, xmm1 + aesdec xmm6, xmm1 + aesdec xmm7, xmm1 + + INNER_MUL_X xmm14, xmm15, xmm0, xmm8, xmm9, xmm0 + + aesdeclast xmm2, xmmword [rsp] ; final irregular round + aesdeclast xmm3, xmmword [rsp+1*AES_BLOCK] + aesdeclast xmm4, xmmword [rsp+2*AES_BLOCK] + aesdeclast xmm5, xmmword [rsp+3*AES_BLOCK] + aesdeclast xmm6, xmmword [rsp+4*AES_BLOCK] + aesdeclast xmm7, xmmword [rsp+5*AES_BLOCK] + + LAST_INNER_MUL_X xmm15, xmm8, xmm9 + movdqa xmm8, xmm15 ; save tweak for next iteration + pxor xmm15, xmm0 ; add key[0] + + movdqu xmmword [rdi+0*AES_BLOCK], xmm2 ; store output blocks + movdqu xmmword [rdi+1*AES_BLOCK], xmm3 + movdqu xmmword [rdi+2*AES_BLOCK], xmm4 + movdqu xmmword [rdi+3*AES_BLOCK], xmm5 + movdqu xmmword [rdi+4*AES_BLOCK], xmm6 + movdqu xmmword [rdi+5*AES_BLOCK], xmm7 + add rdi, 6*AES_BLOCK + + sub rdx, 6 + jnc .blks_loop + +.short_input: + add rdx, 6 + jz .quit + + movdqa xmmword [rsp+0*AES_BLOCK], xmm10 ; save pre-computed twae + movdqa xmmword [rsp+1*AES_BLOCK], xmm11 + movdqa xmmword [rsp+2*AES_BLOCK], xmm12 + movdqa xmmword [rsp+3*AES_BLOCK], xmm13 + movdqa xmmword [rsp+4*AES_BLOCK], xmm14 + movdqa xmmword [rsp+5*AES_BLOCK], xmm15 + +;; +;; block-by-block processing +;; + movdqa xmm0, xmmword [rcx+r8] ; key[0] + pxor xmm0, xmmword [rcx] ; key[0] ^ key[last] + + xor rax, rax + +.single_blk_loop: + movdqu xmm2, xmmword [rsi] ; input block + movdqa xmm1, xmmword [rsp+rax] ; tweak ^ key[0] + add rsi, AES_BLOCK + + pxor xmm2, xmm1 ; src[] ^tweak ^ key[0] + pxor xmm1, xmm0 ; tweak ^ key[lasl] + cmp r8, 12*16 ; switch according to number of rounds + jl .key_128_s + +.key_256_s: + aesdec xmm2, xmmword [rcx+9*AES_BLOCK+4*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK+3*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK+2*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK+1*AES_BLOCK] +.key_128_s: + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-0*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-1*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-2*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-3*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-4*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-5*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-6*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-7*AES_BLOCK] + aesdec xmm2, xmmword [rcx+9*AES_BLOCK-8*AES_BLOCK] + aesdeclast xmm2, xmm1 + + movdqu xmmword [rdi], xmm2 ; output block + add rdi, AES_BLOCK + add rax, AES_BLOCK + sub rdx, 1 + jnz .single_blk_loop + + movdqa xmm10, xmmword [rsp+rax] ; tweak ^ key[0] + +.quit: + pxor xmm10, xmmword [rcx+r8] ; remove key[0] + movdqu xmmword [r9], xmm10 ; and save tweak value + + pxor xmm0, xmm0 + pxor xmm1, xmm1 + + REST_XMM + REST_GPR + ret +ENDFUNC cpAESDecryptXTS_AES_NI + +%endif ;; _AES_NI_ENABLING_ +%endif ;;_IPP32E_Y8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptcbce9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptcbce9as.asm new file mode 100644 index 000000000..a41f3c277 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptcbce9as.asm @@ -0,0 +1,118 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; EncryptCBC_RIJ128_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: RIJ128 CBC encryption +;* +;* void EncryptCBC_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len, +;* const Ipp8u* pIV) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAESEncryptCBC +;; +align IPP_ALIGN_FACTOR +IPPASM EncryptCBC_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 6 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d length: DWORD ; length (bytes) +;; r9 pIV: DWORD ; IV address + +%xdefine SC (4) +%assign BYTES_PER_BLK (16) + + movsxd r8, r8d ; input length + movdqu xmm0, oword [r9] ; IV + +align IPP_ALIGN_FACTOR +;; +;; pseudo-pipelined processing +;; +.blks_loop: + movdqu xmm1, oword [rdi] ; input block + + movdqa xmm4, oword [rcx] + mov r9, rcx ; set pointer to the key material + + pxor xmm0, xmm1 ; src[] ^ iv + + pxor xmm0, xmm4 ; whitening + + movdqa xmm4, oword [r9+16] + add r9, 16 + + mov r10, rdx ; counter depending on key length + sub r10, 1 +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + movdqa xmm4, oword [r9+16] + add r9, 16 + dec r10 + jnz .cipher_loop + aesenclast xmm0, xmm4 ; irregular round + + movdqu oword [rsi], xmm0 ; store output block + + add rdi, BYTES_PER_BLK ; advance pointers + add rsi, BYTES_PER_BLK + sub r8, BYTES_PER_BLK ; decrease counter + jnz .blks_loop + + pxor xmm4, xmm4 + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptCBC_RIJ128_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptcfbe9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptcfbe9as.asm new file mode 100644 index 000000000..429778e0b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptcfbe9as.asm @@ -0,0 +1,354 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Encrypt_RIJ128_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + + +%macro COPY_8U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor rcx, rcx +%%next_byte: + mov %%tmp, byte [%%src+rcx] + mov byte [%%dst+rcx], %%tmp + add rcx, 1 + cmp rcx, %%limit + jl %%next_byte +%endmacro + +%macro COPY_32U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor rcx, rcx +%%next_dword: + mov %%tmp, dword [%%src+rcx] + mov dword [%%dst+rcx], %%tmp + add rcx, 4 + cmp rcx, %%limit + jl %%next_dword +%endmacro + +%macro COPY_128U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor rcx, rcx +%%next_oword: + movdqu %%tmp, oword [%%src+rcx] + movdqu oword [%%dst+rcx], %%tmp + add rcx, 16 + cmp rcx, %%limit + jl %%next_oword +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: RIJ128 CFB encryption +;* +;* void EncryptCFB_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int cfbBlks, +;* int cfbSize, +;* const Ipp8u* pIV) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAESEncryptCFB +;; +align IPP_ALIGN_FACTOR +IPPASM EncryptCFB_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME (1+4+4)*16 + USES_GPR rsi,rdi,r12,r15 + USES_XMM + COMP_ABI 7 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d cfbBlks: DWORD ; length of stream in bytes +;; r9d cfbSize: DWORD ; cfb blk size +;; [rsp+ARG_7] pIV BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + mov rax, [rsp+ARG_7] ; IV address + movdqu xmm4, oword [rax] ; get IV + movdqa oword [rsp+0*16], xmm4 ; into the stack + + movsxd r8, r8d ; length of stream + movsxd r9, r9d ; cfb blk size + + mov r15, rcx ; save key material address + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rax, [r15+rax*4-9*(SC)*4] ; AES-128 round keys + +;; +;; processing +;; + lea r10, [r9*BLKS_PER_LOOP] ; 4 cfb block +.blks_loop: + cmp r8, r10 + cmovl r10, r8 + COPY_8U {rsp+5*16}, rdi, r10, r11b ; move 1-4 input blocks to stack + + mov r12, r10 ; copy length to be processed + xor r11, r11 ; index +.single_blk: + movdqu xmm0, oword [rsp+r11] ; get processing blocks + + pxor xmm0, oword [r15] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + + movdqu xmm1, oword [rsp+5*16+r11] ; get src blocks from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [rsp+1*16+r11],xmm0 ;and store into the stack + + add r11, r9 ; advance index + sub r12, r9 ; decrease length + jg .single_blk + + COPY_8U rsi, {rsp+1*16}, r10, r11b ; move 1-4 blocks to output + + movdqu xmm0, oword [rsp+r10]; update IV + movdqa oword [rsp], xmm0 + + add rdi, r10 + add rsi, r10 + sub r8, r10 + jg .blks_loop + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptCFB_RIJ128_AES_NI + +align IPP_ALIGN_FACTOR +IPPASM EncryptCFB32_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME (1+4+4)*16 + USES_GPR rsi,rdi,r12,r15 + USES_XMM + COMP_ABI 7 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d cfbBlks: DWORD ; length of stream in bytes +;; r9d cfbSize: DWORD ; cfb blk size +;; [rsp+ARG_7] pIV BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + mov rax, [rsp+ARG_7] ; IV address + movdqu xmm4, oword [rax] ; get IV + movdqa oword [rsp+0*16], xmm4 ; into the stack + + movsxd r8, r8d ; length of stream + movsxd r9, r9d ; cfb blk size + + mov r15, rcx ; save key material address + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rax, [r15+rax*4-9*(SC)*4] ; AES-128 round keys + +;; +;; processing +;; + lea r10, [r9*BLKS_PER_LOOP] ; 4 cfb block +.blks_loop: + cmp r8, r10 + cmovl r10, r8 + COPY_32U {rsp+5*16}, rdi, r10, r11d ; move 1-4 input blocks to stack + + mov r12, r10 ; copy length to be processed + xor r11, r11 ; index +.single_blk: + movdqu xmm0, oword [rsp+r11] ; get processing blocks + + pxor xmm0, oword [r15] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + + movdqu xmm1, oword [rsp+5*16+r11] ; get src blocks from the stack + pxor xmm0, xmm1 ; xor src + movdqu oword [rsp+1*16+r11],xmm0 ;and store into the stack + + add r11, r9 ; advance index + sub r12, r9 ; decrease length + jg .single_blk + + COPY_32U rsi, {rsp+1*16}, r10, r11d ; move 1-4 blocks to output + + movdqu xmm0, oword [rsp+r10]; update IV + movdqa oword [rsp], xmm0 + + add rdi, r10 + add rsi, r10 + sub r8, r10 + jg .blks_loop + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptCFB32_RIJ128_AES_NI + +align IPP_ALIGN_FACTOR +IPPASM EncryptCFB128_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 6 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d cfbBlks: DWORD ; length of stream in bytes +;; r9d pIV: BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + movdqu xmm0, oword [r9] ; get IV + + movsxd r8, r8d ; length of stream + movsxd r9, r9d ; cfb blk size + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rax, [rcx+rax*4-9*(SC)*4] ; AES-128 round keys + +;; +;; processing +;; +.blks_loop: + pxor xmm0, oword [rcx] ; whitening + + movdqu xmm1, oword [rdi] ; input blocks + + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + + pxor xmm0, xmm1 ; xor src + movdqu oword [rsi],xmm0 ;and store into the dst + + add rdi, 16 + add rsi, 16 + sub r8, 16 + jg .blks_loop + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptCFB128_RIJ128_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptctr128pipee9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptctr128pipee9as.asm new file mode 100644 index 000000000..c8f9a9579 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptctr128pipee9as.asm @@ -0,0 +1,457 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; EncryptCTR_RIJ128pipe_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: pipelined RIJ128 CTR128 encryption/decryption +;* +;* +;* void EncryptStreamCTR32_AES_NI(const Ipp8u* inpBlk, +;* Ipp8u* outBlk, +;* int nr, +;* const Ipp8u* pRKey, +;* int length, +;* Ipp8u* pIV) +;*************************************************************** +%assign AES_BLOCK (16) + +align IPP_ALIGN_FACTOR +IPPASM EncryptStreamCTR32_AES_NI,PUBLIC +%assign LOCAL_FRAME sizeof(oword)*8 + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7,xmm8,xmm9 + COMP_ABI 6 +;; rdi: pInpBlk: BYTE ; pointer to the input +;; rsi: pOutBlk: BYTE ; pointer to the output +;; rdx: nr: DWORD ; number of rounds +;; rcx pKey: BYTE ; key material address +;; r8d length: DWORD ; length of the input +;; r9 pIV : BYTE ; pointer to the iv (BE string counter representation) + +%xdefine SC (4) + + movdqu xmm0, oword [r9] ; input IV + movsxd r8, r8d ; length + + lea r11, [r8+AES_BLOCK-1] ; r11 = blocks = ceil(len/AES_BLOCK) + shr r11, 4 + + mov rax, qword [r9+sizeof(qword)] ; input IV + mov rbx, qword [r9] + bswap rax + bswap rbx + mov r10d, eax ; save ctr32 + add rax, r11 ; +blocks + adc rbx, 0 + bswap rax + bswap rbx + mov qword [r9+sizeof(qword)], rax ; update IV + mov qword [r9], rbx + + mov r11d, dword [rcx+AES_BLOCK-sizeof(dword)] ; get whitening keys corresponding to ctr32 + + pxor xmm0, oword [rcx] ; apply whitening keys + add rcx, AES_BLOCK ; mov pointer to the round keys + movdqa oword [rsp+0*AES_BLOCK], xmm0 ; store unchanged part of ctr128 + movdqa oword [rsp+1*AES_BLOCK], xmm0 + movdqa oword [rsp+2*AES_BLOCK], xmm0 + movdqa oword [rsp+3*AES_BLOCK], xmm0 + movdqa oword [rsp+4*AES_BLOCK], xmm0 + movdqa oword [rsp+5*AES_BLOCK], xmm0 + movdqa oword [rsp+6*AES_BLOCK], xmm0 + movdqa oword [rsp+7*AES_BLOCK], xmm0 + + mov r9, rsp + cmp r8, AES_BLOCK ; test %if single block processed + jle .short123_input + + movdqa xmm1, xmm0 + movdqa xmm2, xmm0 + movdqa xmm3, xmm0 + lea ebx, [r10d+1] ; init ctr32+1 + lea eax, [r10d+2] ; init ctr32+2 + lea r9d, [r10d+3] ; init ctr32+3 + bswap ebx + bswap eax + bswap r9d + xor ebx, r11d + pinsrd xmm1, ebx, 3 + xor eax, r11d + pinsrd xmm2, eax, 3 + xor r9d, r11d + pinsrd xmm3, r9d, 3 + + movdqa oword [rsp+1*AES_BLOCK], xmm1 + movdqa oword [rsp+2*AES_BLOCK], xmm2 + movdqa oword [rsp+3*AES_BLOCK], xmm3 + + mov r9, rsp + + movdqa xmm4, oword [rcx+0*AES_BLOCK] ; pre load operation's keys + movdqa xmm5, oword [rcx+1*AES_BLOCK] + + cmp r8, (4*AES_BLOCK) ; test %if 1-2-3 blocks processed + jl .short123_input + jz .short_input + + lea eax, [r10d+4] ; init ctr32+4 + lea ebx, [r10d+5] ; init ctr32+5 + bswap eax + bswap ebx + xor ebx, r11d + xor eax, r11d + mov dword [rsp+4*AES_BLOCK+AES_BLOCK-sizeof(dword)], eax + mov dword [rsp+5*AES_BLOCK+AES_BLOCK-sizeof(dword)], ebx + + lea eax, [r10d+6] ; init ctr32+6 + lea ebx, [r10d+7] ; init ctr32+7 + bswap eax + bswap ebx + xor eax, r11d + xor ebx, r11d + mov dword [rsp+6*AES_BLOCK+AES_BLOCK-sizeof(dword)], eax + mov dword [rsp+7*AES_BLOCK+AES_BLOCK-sizeof(dword)], ebx + + cmp r8, (8*AES_BLOCK) + jl .short_input + +;; +;; 8-blocks processing alaivalbe +;; + sub rsp, sizeof(oword)*4 ; save xmm registers + movdqa oword [rsp+0*sizeof(oword)], xmm10 + movdqa oword [rsp+1*sizeof(oword)], xmm11 + movdqa oword [rsp+2*sizeof(oword)], xmm12 + movdqa oword [rsp+3*sizeof(oword)], xmm13 + + push rcx ; store pointer to the key material + push rdx ; store number of rounds + sub r8, (8*AES_BLOCK) + +align IPP_ALIGN_FACTOR +.blk8_loop: +; movdqa xmm4, oword [rcx+0*AES_BLOCK] ; pre load operation's keys +; movdqa xmm5, oword [rcx+1*AES_BLOCK] + add rcx, (2*AES_BLOCK) + + add r10d, 8 ; next counter value + sub rdx, 4 ; rounds -= 4 + + movdqa xmm6, oword [r9+4*AES_BLOCK] ; load current ctr32 + movdqa xmm7, oword [r9+5*AES_BLOCK] + movdqa xmm8, oword [r9+6*AES_BLOCK] + movdqa xmm9, oword [r9+7*AES_BLOCK] + + mov eax, r10d ; improve next 2 ctr32 values in advance + aesenc xmm0, xmm4 + lea ebx, [r10d+1] + aesenc xmm1, xmm4 + bswap eax + aesenc xmm2, xmm4 + bswap ebx + aesenc xmm3, xmm4 + xor eax, r11d + aesenc xmm6, xmm4 + xor ebx, r11d + aesenc xmm7, xmm4 + mov dword [r9+0*AES_BLOCK+AES_BLOCK-sizeof(dword)], eax + aesenc xmm8, xmm4 + mov dword [r9+1*AES_BLOCK+AES_BLOCK-sizeof(dword)], ebx + aesenc xmm9, xmm4 + movdqa xmm4, oword [rcx] ; pre load operation's keys + + lea eax, [r10d+2] ; improve next 2 ctr32 values in advance + aesenc xmm0, xmm5 + lea ebx, [r10d+3] + aesenc xmm1, xmm5 + bswap eax + aesenc xmm2, xmm5 + bswap ebx + aesenc xmm3, xmm5 + xor eax, r11d + aesenc xmm6, xmm5 + xor ebx, r11d + aesenc xmm7, xmm5 + mov dword [r9+2*AES_BLOCK+AES_BLOCK-sizeof(dword)], eax + aesenc xmm8, xmm5 + mov dword [r9+3*AES_BLOCK+AES_BLOCK-sizeof(dword)], ebx + aesenc xmm9, xmm5 + movdqa xmm5, oword [rcx+AES_BLOCK] ; pre load operation's keys + +align IPP_ALIGN_FACTOR +.cipher_loop: + add rcx, (2*AES_BLOCK) + sub rdx, 2 + + aesenc xmm0, xmm4 + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + aesenc xmm6, xmm4 + aesenc xmm7, xmm4 + aesenc xmm8, xmm4 + aesenc xmm9, xmm4 + movdqa xmm4, oword [rcx] ; pre load operation's keys + + aesenc xmm0, xmm5 + aesenc xmm1, xmm5 + aesenc xmm2, xmm5 + aesenc xmm3, xmm5 + aesenc xmm6, xmm5 + aesenc xmm7, xmm5 + aesenc xmm8, xmm5 + aesenc xmm9, xmm5 + movdqa xmm5, oword [rcx+AES_BLOCK] ; pre load operation's keys + jnz .cipher_loop + + lea eax, [r10d+4] ; improve next 2 ctr32 values in advance + aesenc xmm0, xmm4 + lea ebx, [r10d+5] + aesenc xmm1, xmm4 + bswap eax + aesenc xmm2, xmm4 + bswap ebx + aesenc xmm3, xmm4 + xor eax, r11d + aesenc xmm6, xmm4 + xor ebx, r11d + aesenc xmm7, xmm4 + mov dword [r9+4*AES_BLOCK+AES_BLOCK-sizeof(dword)], eax + aesenc xmm8, xmm4 + mov dword [r9+5*AES_BLOCK+AES_BLOCK-sizeof(dword)], ebx + aesenc xmm9, xmm4 + + lea eax, [r10d+6] ; improve next 2 ctr32 values in advance + aesenclast xmm0, xmm5 + lea ebx, [r10d+7] + aesenclast xmm1, xmm5 + bswap eax + aesenclast xmm2, xmm5 + bswap ebx + aesenclast xmm3, xmm5 + xor eax, r11d + aesenclast xmm6, xmm5 + xor ebx, r11d + aesenclast xmm7, xmm5 + mov dword [r9+6*AES_BLOCK+AES_BLOCK-sizeof(dword)], eax + aesenclast xmm8, xmm5 + mov dword [r9+7*AES_BLOCK+AES_BLOCK-sizeof(dword)], ebx + aesenclast xmm9, xmm5 + + movdqu xmm10, oword [rdi+0*AES_BLOCK] + movdqu xmm11, oword [rdi+1*AES_BLOCK] + movdqu xmm12, oword [rdi+2*AES_BLOCK] + movdqu xmm13, oword [rdi+3*AES_BLOCK] + pxor xmm0, xmm10 + pxor xmm1, xmm11 + pxor xmm2, xmm12 + pxor xmm3, xmm13 + movdqu oword [rsi+0*AES_BLOCK], xmm0 + movdqu oword [rsi+1*AES_BLOCK], xmm1 + movdqu oword [rsi+2*AES_BLOCK], xmm2 + movdqu oword [rsi+3*AES_BLOCK], xmm3 + movdqu xmm10, oword [rdi+4*AES_BLOCK] + movdqu xmm11, oword [rdi+5*AES_BLOCK] + movdqu xmm12, oword [rdi+6*AES_BLOCK] + movdqu xmm13, oword [rdi+7*AES_BLOCK] + pxor xmm6, xmm10 + pxor xmm7, xmm11 + pxor xmm8, xmm12 + pxor xmm9, xmm13 + movdqu oword [rsi+4*AES_BLOCK], xmm6 + movdqu oword [rsi+5*AES_BLOCK], xmm7 + movdqu oword [rsi+6*AES_BLOCK], xmm8 + movdqu oword [rsi+7*AES_BLOCK], xmm9 + + mov rcx, qword [rsp+sizeof(qword)] ; restore pointer to the key material + mov rdx, qword [rsp] ; restore number of rounds + + movdqa xmm0, oword [r9+0*AES_BLOCK] ; load next current ctr32 + movdqa xmm1, oword [r9+1*AES_BLOCK] + movdqa xmm2, oword [r9+2*AES_BLOCK] + movdqa xmm3, oword [r9+3*AES_BLOCK] + + movdqa xmm4, oword [rcx+0*AES_BLOCK] ; pre load operation's keys + movdqa xmm5, oword [rcx+1*AES_BLOCK] ; pre load operation's keys + + add rdi, 8*AES_BLOCK + add rsi, 8*AES_BLOCK + sub r8, 8*AES_BLOCK + jge .blk8_loop + + pop rdx + pop rcx + + movdqa xmm10,oword [rsp+0*sizeof(oword)] ; resrore xmm registers + movdqa xmm11,oword [rsp+1*sizeof(oword)] + movdqa xmm12,oword [rsp+2*sizeof(oword)] + movdqa xmm13,oword [rsp+3*sizeof(oword)] + add rsp, sizeof(oword)*4 ; release stack + + add r8, 8*AES_BLOCK + jz .quit + +align IPP_ALIGN_FACTOR +.short_input: +;; +;; test %if 4-blocks processing alaivalbe +;; + cmp r8, (4*AES_BLOCK) + jl .short123_input + + mov rbx, rcx ; pointer to the key material + lea r10, [rdx-2] ; rounds -= 2 + +align IPP_ALIGN_FACTOR +.cipher_loop4: + add rbx, (2*AES_BLOCK) + sub r10, 2 + + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [rbx] ; pre load operation's keys + + aesenc xmm0, xmm5 + aesenc xmm1, xmm5 + aesenc xmm2, xmm5 + aesenc xmm3, xmm5 + movdqa xmm5, oword [rbx+AES_BLOCK] ; pre load operation's keys + jnz .cipher_loop4 + + movdqu xmm6, oword [rdi+0*AES_BLOCK] + movdqu xmm7, oword [rdi+1*AES_BLOCK] + movdqu xmm8, oword [rdi+2*AES_BLOCK] + movdqu xmm9, oword [rdi+3*AES_BLOCK] + add rdi, (4*AES_BLOCK) + + aesenc xmm0, xmm4 + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + + aesenclast xmm0, xmm5 + aesenclast xmm1, xmm5 + aesenclast xmm2, xmm5 + aesenclast xmm3, xmm5 + + pxor xmm0, xmm6 + movdqu oword [rsi+0*AES_BLOCK], xmm0 + pxor xmm1, xmm7 + movdqu oword [rsi+1*AES_BLOCK], xmm1 + pxor xmm2, xmm8 + movdqu oword [rsi+2*AES_BLOCK], xmm2 + pxor xmm3, xmm9 + movdqu oword [rsi+3*AES_BLOCK], xmm3 + add rsi, (4*AES_BLOCK) + + add r9, (4*AES_BLOCK) + + sub r8, (4*AES_BLOCK) + jz .quit + +;; +;; block-by-block processing +;; +.short123_input: + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rbx,[rdx*4] + lea rbx, [rcx+rbx*4-10*(SC)*4] ; AES-128 round keys + +.single_blk: + movdqa xmm0, oword [r9] ; counter from the stack + add r9, AES_BLOCK + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0,oword [rbx-4*4*SC] + aesenc xmm0,oword [rbx-3*4*SC] +.key_192_s: + aesenc xmm0,oword [rbx-2*4*SC] + aesenc xmm0,oword [rbx-1*4*SC] +.key_128_s: + aesenc xmm0,oword [rbx+0*4*SC] + aesenc xmm0,oword [rbx+1*4*SC] + aesenc xmm0,oword [rbx+2*4*SC] + aesenc xmm0,oword [rbx+3*4*SC] + aesenc xmm0,oword [rbx+4*4*SC] + aesenc xmm0,oword [rbx+5*4*SC] + aesenc xmm0,oword [rbx+6*4*SC] + aesenc xmm0,oword [rbx+7*4*SC] + aesenc xmm0,oword [rbx+8*4*SC] + aesenclast xmm0,oword [rbx+9*4*SC] + + cmp r8, AES_BLOCK ; test %if partial bloak + jl .partial_block + + movdqu xmm1, oword [rdi] ; input data block + add rdi, AES_BLOCK + pxor xmm0, xmm1 ; output block + movdqu oword [rsi], xmm0 ; save output block + add rsi, AES_BLOCK + + sub r8, AES_BLOCK + jz .quit + jmp .single_blk + +.partial_block: + pextrb eax, xmm0, 0 + psrldq xmm0, 1 + movzx edx, byte [rdi] + inc rdi + xor rax, rdx + mov byte [rsi], al + inc rsi + dec r8 + jnz .partial_block + +.quit: + pxor xmm4, xmm4 + pxor xmm5, xmm5 + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptStreamCTR32_AES_NI + +%endif ;; _IPP32E_Y8 +%endif ;; _AES_NI_ENABLING_ + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptctrpipee9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptctrpipee9as.asm new file mode 100644 index 000000000..a9128f708 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptctrpipee9as.asm @@ -0,0 +1,271 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; EncryptCTR_RIJ128pipe_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR +u128_str DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +;*************************************************************** +;* Purpose: pipelined RIJ128 CTR encryption/decryption +;* +;* void EncryptCTR_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int length, +;* Ipp8u* pCtrValue, +;* Ipp8u* pCtrBitMask) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAESEncryptCTR +;; +align IPP_ALIGN_FACTOR +IPPASM EncryptCTR_RIJ128pipe_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,rbx + USES_XMM xmm6,xmm7,xmm8,xmm9 + COMP_ABI 7 +;; rdi: pInpBlk: DWORD, ; pointer to the input +;; rsi: pOutBlk: DWORD, ; pointer to the output +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d length: DWORD ; length of the input +;; r9 pCtrValue: BYTED ; pointer to the Counter +;; [rsp+ARG_7] pCtrBitMask: BYTE ; pointer to the Counter Bit Mask + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + mov rax, [rsp+ARG_7] + movdqu xmm8, oword [rax] ; counter bit mask + + movdqu xmm0, oword [r9] ; initial counter + movdqa xmm9, xmm8 + pandn xmm9, xmm0 ; counter template + + ;; + ;; init counter + ;; + mov rbx, qword [r9] ; initial counter (BE) + mov rax, qword [r9+8] + bswap rbx + bswap rax + + movsxd r8, r8d + sub r8, BYTES_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +.blks_loop: + movdqa xmm4,oword [rel u128_str] + + pinsrq xmm0, rax, 0 ; get counter value + pinsrq xmm0, rbx, 1 + pshufb xmm0, xmm4 ; convert int the octet string + pand xmm0, xmm8 ; select counter bits + por xmm0, xmm9 ; add unchanged bits + + add rax, 1 + adc rbx, 0 + pinsrq xmm1, rax, 0 + pinsrq xmm1, rbx, 1 + pshufb xmm1, xmm4 + pand xmm1, xmm8 + por xmm1, xmm9 + + add rax, 1 + adc rbx, 0 + pinsrq xmm2, rax, 0 + pinsrq xmm2, rbx, 1 + pshufb xmm2, xmm4 + pand xmm2, xmm8 + por xmm2, xmm9 + + add rax, 1 + adc rbx, 0 + pinsrq xmm3, rax, 0 + pinsrq xmm3, rbx, 1 + pshufb xmm3, xmm4 + pand xmm3, xmm8 + por xmm3, xmm9 + + movdqa xmm4, oword [rcx] + mov r10, rcx ; set pointer to the key material + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [r10+16] + add r10, 16 + + mov r11, rdx ; counter depending on key length + sub r11, 1 +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [r10+16] + add r10, 16 + dec r11 + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round + aesenclast xmm1, xmm4 + aesenclast xmm2, xmm4 + aesenclast xmm3, xmm4 + + movdqu xmm4, oword [rdi+0*BYTES_PER_BLK] ; 4 input blocks + movdqu xmm5, oword [rdi+1*BYTES_PER_BLK] + movdqu xmm6, oword [rdi+2*BYTES_PER_BLK] + movdqu xmm7, oword [rdi+3*BYTES_PER_BLK] + add rdi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; 4 output blocks + movdqu oword [rsi+0*BYTES_PER_BLK], xmm0 + pxor xmm1, xmm5 + movdqu oword [rsi+1*BYTES_PER_BLK], xmm1 + pxor xmm2, xmm6 + movdqu oword [rsi+2*BYTES_PER_BLK], xmm2 + pxor xmm3, xmm7 + movdqu oword [rsi+3*BYTES_PER_BLK], xmm3 + + add rax, 1 ; advance counter + adc rbx, 0 + + add rsi, BYTES_PER_LOOP + + sub r8, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add r8, BYTES_PER_LOOP + jz .quit + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea r10,[rdx*4] + lea r10, [rcx+r10*4-9*(SC)*4] ; AES-128 round keys + +.single_blk_loop: + pinsrq xmm0, rax, 0 ; get counter value + pinsrq xmm0, rbx, 1 + pshufb xmm0, [rel u128_str] ; convert int the octet string + pand xmm0, xmm8 ; select counter bits + por xmm0, xmm9 ; add unchanged bits + + pxor xmm0, oword [rcx] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0,oword [r10-4*4*SC] + aesenc xmm0,oword [r10-3*4*SC] +.key_192_s: + aesenc xmm0,oword [r10-2*4*SC] + aesenc xmm0,oword [r10-1*4*SC] +.key_128_s: + aesenc xmm0,oword [r10+0*4*SC] + aesenc xmm0,oword [r10+1*4*SC] + aesenc xmm0,oword [r10+2*4*SC] + aesenc xmm0,oword [r10+3*4*SC] + aesenc xmm0,oword [r10+4*4*SC] + aesenc xmm0,oword [r10+5*4*SC] + aesenc xmm0,oword [r10+6*4*SC] + aesenc xmm0,oword [r10+7*4*SC] + aesenc xmm0,oword [r10+8*4*SC] + aesenclast xmm0,oword [r10+9*4*SC] + + add rax, 1 ; update counter + adc rbx, 0 + + sub r8, BYTES_PER_BLK + jl .partial_block + + movdqu xmm4, oword [rdi] ; input block + pxor xmm0, xmm4 ; output block + movdqu oword [rsi], xmm0 ; save output block + + add rdi, BYTES_PER_BLK + add rsi, BYTES_PER_BLK + cmp r8, 0 + jz .quit + jmp .single_blk_loop + +.partial_block: + add r8, BYTES_PER_BLK + +.partial_block_loop: + pextrb r10d, xmm0, 0 + psrldq xmm0, 1 + movzx r11d, byte [rdi] + xor r10, r11 + mov byte [rsi], r10b + inc rdi + inc rsi + dec r8 + jnz .partial_block_loop + +.quit: + pinsrq xmm0, rax, 0 ; get counter value + pinsrq xmm0, rbx, 1 + pshufb xmm0, [rel u128_str] ; convert int the octet string + pand xmm0, xmm8 ; select counter bits + por xmm0, xmm9 ; add unchanged bits + movdqu oword [r9], xmm0 ; return updated counter + REST_XMM + REST_GPR + ret +ENDFUNC EncryptCTR_RIJ128pipe_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encrypte9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encrypte9as.asm new file mode 100644 index 000000000..229f43ed6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encrypte9as.asm @@ -0,0 +1,122 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; Encrypt_RIJ128_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: single block RIJ128 Cipher +;* +;* void Encrypt_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* const Ipp32u Tables[][256]) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsRijndael128EncryptECB +;; Caller = ippsRijndael128EncryptCBC +;; Caller = ippsRijndael128EncryptCFB +;; Caller = ippsRijndael128DecryptCFB +;; +;; Caller = ippsDAARijndael128Update +;; Caller = ippsDAARijndael128Final +;; Caller = ippsDAARijndael128MessageDigest +;; +align IPP_ALIGN_FACTOR +IPPASM Encrypt_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 4 + +;; rdi: pInpBlk: DWORD, ; input block address +;; rsi: pOutBlk: DWORD, ; output block address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address + +%xdefine SC (4) + + + movdqu xmm0, oword [rdi] ; input block + + ;;whitening + pxor xmm0, oword [rcx] + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rcx,[rcx+rax*4-9*(SC)*4] ; AES-128-keys + + cmp rdx,12 ; switch according to number of rounds + jl .key_128 + jz .key_192 + + ;; + ;; regular rounds + ;; +.key_256: + aesenc xmm0,oword [rcx-4*4*SC] + aesenc xmm0,oword [rcx-3*4*SC] +.key_192: + aesenc xmm0,oword [rcx-2*4*SC] + aesenc xmm0,oword [rcx-1*4*SC] +.key_128: + aesenc xmm0,oword [rcx+0*4*SC] + aesenc xmm0,oword [rcx+1*4*SC] + aesenc xmm0,oword [rcx+2*4*SC] + aesenc xmm0,oword [rcx+3*4*SC] + aesenc xmm0,oword [rcx+4*4*SC] + aesenc xmm0,oword [rcx+5*4*SC] + aesenc xmm0,oword [rcx+6*4*SC] + aesenc xmm0,oword [rcx+7*4*SC] + aesenc xmm0,oword [rcx+8*4*SC] + ;; + ;; last rounds + ;; + aesenclast xmm0,oword [rcx+9*4*SC] + + movdqu oword [rsi], xmm0 ; output block + + REST_XMM + REST_GPR + ret +ENDFUNC Encrypt_RIJ128_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptecbpipee9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptecbpipee9as.asm new file mode 100644 index 000000000..00426197c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptecbpipee9as.asm @@ -0,0 +1,179 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Cipher function +; +; Content: +; EncryptECB_RIJ128pipe_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: pipelined RIJ128 ECB encryption +;* +;* void EncryptECB_RIJ128pipe_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int len) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsAESEncryptECB +;; +align IPP_ALIGN_FACTOR +IPPASM EncryptECB_RIJ128pipe_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 5 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d length: DWORD ; length (bytes) + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) +%assign BYTES_PER_BLK (16) +%assign BYTES_PER_LOOP (BYTES_PER_BLK*BLKS_PER_LOOP) + + movsxd r8, r8d + sub r8, BYTES_PER_LOOP + jl .short_input + +;; +;; pipelined processing +;; +align IPP_ALIGN_FACTOR +.blks_loop: + movdqa xmm4, oword [rcx] + mov r9, rcx ; set pointer to the key material + + movdqu xmm0, oword [rdi+0*16] ; get input blocks + movdqu xmm1, oword [rdi+1*16] + movdqu xmm2, oword [rdi+2*16] + movdqu xmm3, oword [rdi+3*16] + add rdi, BYTES_PER_LOOP + + pxor xmm0, xmm4 ; whitening + pxor xmm1, xmm4 + pxor xmm2, xmm4 + pxor xmm3, xmm4 + + movdqa xmm4, oword [r9+16] + add r9, 16 + + mov r10, rdx ; counter depending on key length + sub r10, 1 +align IPP_ALIGN_FACTOR +.cipher_loop: + aesenc xmm0, xmm4 ; regular round + aesenc xmm1, xmm4 + aesenc xmm2, xmm4 + aesenc xmm3, xmm4 + movdqa xmm4, oword [r9+16] + add r9, 16 + dec r10 + jnz .cipher_loop + + aesenclast xmm0, xmm4 ; irregular round + movdqu oword [rsi+0*16], xmm0 ; store output blocks + aesenclast xmm1, xmm4 + movdqu oword [rsi+1*16], xmm1 + aesenclast xmm2, xmm4 + movdqu oword [rsi+2*16], xmm2 + aesenclast xmm3, xmm4 + movdqu oword [rsi+3*16], xmm3 + add rsi, BYTES_PER_LOOP + + sub r8, BYTES_PER_LOOP + jge .blks_loop + +;; +;; block-by-block processing +;; +.short_input: + add r8, BYTES_PER_LOOP + jz .quit + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea r9, [rcx+rax*4-9*(SC)*4] ; AES-128 round keys + +align IPP_ALIGN_FACTOR +.single_blk_loop: + movdqu xmm0, oword [rdi] ; get input block + add rdi, BYTES_PER_BLK + pxor xmm0, oword [rcx] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + +.key_256_s: + aesenc xmm0,oword [r9-4*4*SC] + aesenc xmm0,oword [r9-3*4*SC] +.key_192_s: + aesenc xmm0,oword [r9-2*4*SC] + aesenc xmm0,oword [r9-1*4*SC] +.key_128_s: + aesenc xmm0,oword [r9+0*4*SC] + aesenc xmm0,oword [r9+1*4*SC] + aesenc xmm0,oword [r9+2*4*SC] + aesenc xmm0,oword [r9+3*4*SC] + aesenc xmm0,oword [r9+4*4*SC] + aesenc xmm0,oword [r9+5*4*SC] + aesenc xmm0,oword [r9+6*4*SC] + aesenc xmm0,oword [r9+7*4*SC] + aesenc xmm0,oword [r9+8*4*SC] + aesenclast xmm0,oword [r9+9*4*SC] + + movdqu oword [rsi], xmm0 ; save output block + add rsi, BYTES_PER_BLK + + sub r8, BYTES_PER_BLK + jnz .single_blk_loop + +.quit: + pxor xmm4, xmm4 + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptECB_RIJ128pipe_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptofbe9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptofbe9as.asm new file mode 100644 index 000000000..b2680070b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptofbe9as.asm @@ -0,0 +1,247 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Inverse Cipher function +; +; Content: +; Encrypt_RIJ128_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + + +%macro COPY_8U 4.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%limit %3 + %xdefine %%tmp %4 + + xor rcx, rcx +%%next_byte: + mov %%tmp, byte [%%src+rcx] + mov byte [%%dst+rcx], %%tmp + add rcx, 1 + cmp rcx, %%limit + jl %%next_byte +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +;*************************************************************** +;* Purpose: RIJ128 OFB encryption +;* +;* void EncryptOFB_RIJ128_AES_NI(const Ipp32u* inpBlk, +;* Ipp32u* outBlk, +;* int nr, +;* const Ipp32u* pRKey, +;* int length, +;* int ofbBlks, +;* const Ipp8u* pIV) +;*************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsRijndael128DecryptCFB +;; +align IPP_ALIGN_FACTOR +IPPASM EncryptOFB_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME (1+1+4+4)*16 + USES_GPR rsi,rdi,r12,r15 + USES_XMM + COMP_ABI 7 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d cfbBlks: DWORD ; length of stream in bytes +;; r9d cfbSize: DWORD ; cfb blk size +;; [rsp+ARG_7] pIV BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + +%xdefine tmpInp [rsp] +%xdefine tmpOut [rsp+16*1] +%xdefine locDst [rsp+16*2] +%xdefine locSrc [rsp+16*6] + + mov rax, [rsp+ARG_7] ; IV address + movdqu xmm0, oword [rax] ; get IV + movdqa oword [rsp+0*16], xmm0 ; into the stack + + movsxd r8, r8d ; length of stream + movsxd r9, r9d ; cfb blk size + + mov r15, rcx ; save key material address + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rax, [r15+rax*4-9*(SC)*4] ; AES-128 round keys + +;; +;; processing +;; + lea r10, [r9*BLKS_PER_LOOP] ; 4 cfb block + +align IPP_ALIGN_FACTOR +.blks_loop: + cmp r8, r10 + cmovl r10, r8 + COPY_8U {rsp+6*16}, rdi, r10, r11b ; move 1-4 input blocks to stack + + mov r12, r10 ; copy length to be processed + xor r11, r11 ; index + +align IPP_ALIGN_FACTOR +.single_blk: + pxor xmm0, oword [r15] ; whitening + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + movdqa oword [rsp+1*16], xmm0 ; save chipher output + + movdqu xmm1, oword [rsp+6*16+r11] ; get src blocks from the stack + pxor xmm1, xmm0 ; xor src + movdqu oword [rsp+2*16+r11],xmm1 ;and store into the stack + + movdqu xmm0, oword [rsp+r9] ; update chiper input (IV) + movdqa oword [rsp], xmm0 + + add r11, r9 ; advance index + sub r12, r9 ; decrease length + jg .single_blk + + COPY_8U rsi, {rsp+2*16}, r10, r11b ; move 1-4 blocks to output + + add rdi, r10 + add rsi, r10 + sub r8, r10 + jg .blks_loop + + mov rax, [rsp+ARG_7] ; IV address + movdqa xmm0, oword [rsp] ; update IV before return + movdqu oword [rax], xmm0 + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptOFB_RIJ128_AES_NI + +align IPP_ALIGN_FACTOR +IPPASM EncryptOFB128_RIJ128_AES_NI,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 6 +;; rdi: pInpBlk: DWORD, ; input blocks address +;; rsi: pOutBlk: DWORD, ; output blocks address +;; rdx: nr: DWORD, ; number of rounds +;; rcx pKey: DWORD ; key material address +;; r8d cfbBlks: DWORD ; length of stream in bytes +;; r9 pIV: BYTE ; pointer to the IV + +%xdefine SC (4) +%assign BLKS_PER_LOOP (4) + + movdqu xmm0, oword [r9] ; get IV + + movsxd r8, r8d ; length of stream + + ; get actual address of key material: pRKeys += (nr-9) * SC + lea rax,[rdx*4] + lea rax, [rcx+rax*4-9*(SC)*4] ; AES-128 round keys + +;; +;; processing +;; +.blks_loop: + pxor xmm0, oword [rcx] ; whitening + + movdqu xmm1, oword [rdi] ; input blocks + + + cmp rdx,12 ; switch according to number of rounds + jl .key_128_s + jz .key_192_s + ; do encryption +.key_256_s: + aesenc xmm0, oword [rax-4*4*SC] + aesenc xmm0, oword [rax-3*4*SC] +.key_192_s: + aesenc xmm0, oword [rax-2*4*SC] + aesenc xmm0, oword [rax-1*4*SC] +.key_128_s: + aesenc xmm0, oword [rax+0*4*SC] + aesenc xmm0, oword [rax+1*4*SC] + aesenc xmm0, oword [rax+2*4*SC] + aesenc xmm0, oword [rax+3*4*SC] + aesenc xmm0, oword [rax+4*4*SC] + aesenc xmm0, oword [rax+5*4*SC] + aesenc xmm0, oword [rax+6*4*SC] + aesenc xmm0, oword [rax+7*4*SC] + aesenc xmm0, oword [rax+8*4*SC] + aesenclast xmm0, oword [rax+9*4*SC] + + pxor xmm1, xmm0 ; xor src + movdqu oword [rsi],xmm1 ;and store into the dst + + add rdi, 16 + add rsi, 16 + sub r8, 16 + jg .blks_loop + + movdqu oword [r9], xmm0 ; update IV before return + + REST_XMM + REST_GPR + ret +ENDFUNC EncryptOFB128_RIJ128_AES_NI + +%endif + +%endif ;; _AES_NI_ENABLING_ + + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptxtse9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptxtse9as.asm new file mode 100644 index 000000000..6032ff8b1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128encryptxtse9as.asm @@ -0,0 +1,377 @@ +;=============================================================================== +; Copyright (C) 2016 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; AES functions +; +; Content: +; cpAESEncryptXTS_AES_NI() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_ON_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_Y8) + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +ALPHA_MUL_CNT dq 00000000000000087h, 00000000000000001h + + +;*************************************************************** +;* Purpose: AES-XTS encryption +;* +;* void cpAESEncryptXTS_AES_NI(Ipp8u* outBlk, +;* const Ipp8u* inpBlk, +;* int length, +;* const Ipp8u* pRKey, +;* int nr, +;* Ipp8u* pTweak) +;*************************************************************** + +;; +;; key = ks[0] +;; mul_cnt = {0x0000000000000001:0x0000000000000087} +;; returns: +;; ktwk = twk^key +;; twk = twk*alpha +;; twk2= twk2 *2 - auxillary +;; +%macro OUTER_MUL_X 6.nolist + %xdefine %%ktwk %1 + %xdefine %%twk %2 + %xdefine %%key %3 + %xdefine %%mul_cnt %4 + %xdefine %%twk2 %5 + %xdefine %%mask %6 + + movdqa %%mask, %%twk2 + paddd %%twk2, %%twk2 + movdqa %%ktwk, %%twk + psrad %%mask, 31 + paddq %%twk, %%twk + pand %%mask, %%mul_cnt + pxor %%ktwk, %%key + pxor %%twk, %%mask +%endmacro + +%macro LAST_OUTER_MUL_X 5.nolist + %xdefine %%ktwk %1 + %xdefine %%twk %2 + %xdefine %%key %3 + %xdefine %%mul_cnt %4 + %xdefine %%twk2 %5 + + movdqa %%ktwk, %%twk + psrad %%twk2, 31 + paddq %%twk, %%twk + pand %%twk2, %%mul_cnt + pxor %%ktwk, %%key + pxor %%twk, %%twk2 +%endmacro + +%macro INNER_MUL_X 6.nolist + %xdefine %%ktwk %1 + %xdefine %%twk %2 + %xdefine %%key %3 + %xdefine %%mul_cnt %4 + %xdefine %%twk2 %5 + %xdefine %%mask %6 + + movdqa %%mask, %%twk2 + paddd %%twk2, %%twk2 + psrad %%mask, 31 + paddq %%twk, %%twk + pand %%mask, %%mul_cnt + pxor %%twk, %%mask +%ifnidn %%key,%%ktwk + movdqa %%key, %%ktwk +%endif + pxor %%ktwk, %%twk +%endmacro + +%macro LAST_INNER_MUL_X 3.nolist + %xdefine %%twk %1 + %xdefine %%mul_cnt %2 + %xdefine %%twk2 %3 + + psrad %%twk2, 31 + paddq %%twk, %%twk + pand %%twk2, %%mul_cnt + pxor %%twk, %%twk2 +%endmacro + +align IPP_ALIGN_FACTOR +IPPASM cpAESEncryptXTS_AES_NI,PUBLIC +%assign LOCAL_FRAME sizeof(oword)*6 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15 + COMP_ABI 6 +;; rdi: pOutBlk: BYTE ; pointer to the output bloak +;; rsi: pInpBlk: BYTE ; pointer to the input block +;; edx: nBlocks DWORD ; number of blocks +;; rcx: pKey: BYTE ; key material address +;; r8d: nr: DWORD ; number of rounds +;; r9 pTweak: BYTE ; pointer to the input/outpout (ciphertext) tweak + +%assign AES_BLOCK (16) + + movsxd r8, r8d ; number of cipher rounds + + movdqu xmm15, xmmword [r9] ; input tweak value + + shl r8, 4 ; key schedule length (bytes) + + movdqa xmm0, xmmword [rcx] ; key[0] + movdqa xmm8, xmmword [rel ALPHA_MUL_CNT] ; mul constant + + pshufd xmm9, xmm15, 5Fh ; {twk[1]:twk[1]:twk[3]:twk[3]} - auxillary value + + movsxd rdx, edx ; number of blocks being processing + + ;; compute: + ;; - ktwk[i] = twk[i]^key[0] + ;; - twk[i+1] = twk[i]*alpha^(i+1), i=0..5 + OUTER_MUL_X xmm10, xmm15, xmm0, xmm8, xmm9, xmm14 + OUTER_MUL_X xmm11, xmm15, xmm0, xmm8, xmm9, xmm14 + OUTER_MUL_X xmm12, xmm15, xmm0, xmm8, xmm9, xmm14 + OUTER_MUL_X xmm13, xmm15, xmm0, xmm8, xmm9, xmm14 + LAST_OUTER_MUL_X xmm14, xmm15, xmm0, xmm8, xmm9 + + movdqa xmm8, xmm15 ; save tweak for next iteration + pxor xmm15, xmm0 ; add key[0] + + sub rdx, 6 ; test input length + jc .short_input + +;; +;; blocks processing +;; +align IPP_ALIGN_FACTOR +.blks_loop: + pxor xmm0, xmmword [rcx+r8] ; key[0]^key[last] + + lea rax, [r8-6*AES_BLOCK] ; cipher_loop counter + lea r10, [rcx+rax+AES_BLOCK] ; mov key pointer down + neg rax + + movdqu xmm2, xmmword [rsi] ; src[0] - src[7] + movdqu xmm3, xmmword [rsi+AES_BLOCK] + movdqu xmm4, xmmword [rsi+2*AES_BLOCK] + movdqu xmm5, xmmword [rsi+3*AES_BLOCK] + movdqu xmm6, xmmword [rsi+4*AES_BLOCK] + movdqu xmm7, xmmword [rsi+5*AES_BLOCK] + + movdqa xmm1, xmmword [rcx+1*AES_BLOCK] ; key[1] + + pxor xmm2, xmm10 ; src[] ^twk[] ^ key[0] + pxor xmm3, xmm11 + pxor xmm4, xmm12 + pxor xmm5, xmm13 + pxor xmm6, xmm14 + pxor xmm7, xmm15 + + pxor xmm10, xmm0 ; store twk[] ^ key[last] + pxor xmm11, xmm0 + pxor xmm12, xmm0 + pxor xmm13, xmm0 + pxor xmm14, xmm0 + pxor xmm15, xmm0 + movdqa xmm0, xmmword [rcx+2*AES_BLOCK] ; key[2] + + movdqa xmmword [rsp+0*AES_BLOCK], xmm10 + movdqa xmmword [rsp+1*AES_BLOCK], xmm11 + movdqa xmmword [rsp+2*AES_BLOCK], xmm12 + movdqa xmmword [rsp+3*AES_BLOCK], xmm13 + movdqa xmmword [rsp+4*AES_BLOCK], xmm14 + movdqa xmmword [rsp+5*AES_BLOCK], xmm15 + add rsi, 6*AES_BLOCK + +align IPP_ALIGN_FACTOR +.cipher_loop: + add rax, 2*AES_BLOCK ; inc loop counter + aesenc xmm2, xmm1 ; regular rounds 3 - (last-2) + aesenc xmm3, xmm1 + aesenc xmm4, xmm1 + aesenc xmm5, xmm1 + aesenc xmm6, xmm1 + aesenc xmm7, xmm1 + movdqa xmm1, xmmword [r10+rax] + aesenc xmm2, xmm0 + aesenc xmm3, xmm0 + aesenc xmm4, xmm0 + aesenc xmm5, xmm0 + aesenc xmm6, xmm0 + aesenc xmm7, xmm0 + movdqa xmm0, xmmword [r10+rax+AES_BLOCK] + jnz .cipher_loop + + movdqa xmm10, xmmword [rcx] ; key[0] + + movdqa xmm15, xmm8 ; restore tweak value + pshufd xmm9, xmm8, 5Fh ; {twk[1]:twk[1]:twk[3]:twk[3]} - auxillary value + movdqa xmm8, xmmword [rel ALPHA_MUL_CNT] ; mul constant + + ; + ; last 6 rounds (5 regular rounds + irregular) + ; merged together with next tweaks computation + ; + aesenc xmm2, xmm1 + aesenc xmm3, xmm1 + aesenc xmm4, xmm1 + aesenc xmm5, xmm1 + aesenc xmm6, xmm1 + aesenc xmm7, xmm1 + movdqa xmm1, xmmword [rcx+r8-3*AES_BLOCK] + + INNER_MUL_X xmm10, xmm15, xmm11, xmm8, xmm9, xmm14 + + aesenc xmm2, xmm0 + aesenc xmm3, xmm0 + aesenc xmm4, xmm0 + aesenc xmm5, xmm0 + aesenc xmm6, xmm0 + aesenc xmm7, xmm0 + movdqa xmm0, xmmword [rcx+r8-2*AES_BLOCK] + + INNER_MUL_X xmm11, xmm15, xmm12, xmm8, xmm9, xmm14 + + aesenc xmm2, xmm1 + aesenc xmm3, xmm1 + aesenc xmm4, xmm1 + aesenc xmm5, xmm1 + aesenc xmm6, xmm1 + aesenc xmm7, xmm1 + movdqa xmm1, xmmword [rcx+r8-1*AES_BLOCK] + + INNER_MUL_X xmm12, xmm15, xmm13, xmm8, xmm9, xmm14 + + aesenc xmm2, xmm0 + aesenc xmm3, xmm0 + aesenc xmm4, xmm0 + aesenc xmm5, xmm0 + aesenc xmm6, xmm0 + aesenc xmm7, xmm0 + + INNER_MUL_X xmm13, xmm15, xmm14, xmm8, xmm9, xmm14 + + aesenc xmm2, xmm1 + aesenc xmm3, xmm1 + aesenc xmm4, xmm1 + aesenc xmm5, xmm1 + aesenc xmm6, xmm1 + aesenc xmm7, xmm1 + + INNER_MUL_X xmm14, xmm15, xmm0, xmm8, xmm9, xmm0 + + aesenclast xmm2, xmmword [rsp] ; final irregular round + aesenclast xmm3, xmmword [rsp+1*AES_BLOCK] + aesenclast xmm4, xmmword [rsp+2*AES_BLOCK] + aesenclast xmm5, xmmword [rsp+3*AES_BLOCK] + aesenclast xmm6, xmmword [rsp+4*AES_BLOCK] + aesenclast xmm7, xmmword [rsp+5*AES_BLOCK] + + LAST_INNER_MUL_X xmm15, xmm8, xmm9 + movdqa xmm8, xmm15 ; save tweak for next iteration + pxor xmm15, xmm0 ; add key[0] + + movdqu xmmword [rdi+0*AES_BLOCK], xmm2 ; store output blocks + movdqu xmmword [rdi+1*AES_BLOCK], xmm3 + movdqu xmmword [rdi+2*AES_BLOCK], xmm4 + movdqu xmmword [rdi+3*AES_BLOCK], xmm5 + movdqu xmmword [rdi+4*AES_BLOCK], xmm6 + movdqu xmmword [rdi+5*AES_BLOCK], xmm7 + add rdi, 6*AES_BLOCK + + sub rdx, 6 + jnc .blks_loop + +.short_input: + add rdx, 6 + jz .quit + + movdqa xmmword [rsp+0*AES_BLOCK], xmm10 ; save pre-computed twae + movdqa xmmword [rsp+1*AES_BLOCK], xmm11 + movdqa xmmword [rsp+2*AES_BLOCK], xmm12 + movdqa xmmword [rsp+3*AES_BLOCK], xmm13 + movdqa xmmword [rsp+4*AES_BLOCK], xmm14 + movdqa xmmword [rsp+5*AES_BLOCK], xmm15 + +;; +;; block-by-block processing +;; + movdqa xmm0, xmmword [rcx] ; key[0] + pxor xmm0, xmmword [rcx+r8] ; key[0] ^ key[last] + + lea r10, [rcx+r8-9*AES_BLOCK] ; r10 = &key[nr-9] + xor rax, rax + +.single_blk_loop: + movdqu xmm2, xmmword [rsi] ; input block + movdqa xmm1, xmmword [rsp+rax] ; tweak ^ key[0] + add rsi, AES_BLOCK + + pxor xmm2, xmm1 ; src[] ^tweak ^ key[0] + pxor xmm1, xmm0 ; tweak ^ key[lasl] + cmp r8, 12*16 ; switch according to number of rounds + jl .key_128_s + +.key_256_s: + aesenc xmm2, xmmword [r10-4*AES_BLOCK] + aesenc xmm2, xmmword [r10-3*AES_BLOCK] + aesenc xmm2, xmmword [r10-2*AES_BLOCK] + aesenc xmm2, xmmword [r10-1*AES_BLOCK] +.key_128_s: + aesenc xmm2, xmmword [r10+0*AES_BLOCK] + aesenc xmm2, xmmword [r10+1*AES_BLOCK] + aesenc xmm2, xmmword [r10+2*AES_BLOCK] + aesenc xmm2, xmmword [r10+3*AES_BLOCK] + aesenc xmm2, xmmword [r10+4*AES_BLOCK] + aesenc xmm2, xmmword [r10+5*AES_BLOCK] + aesenc xmm2, xmmword [r10+6*AES_BLOCK] + aesenc xmm2, xmmword [r10+7*AES_BLOCK] + aesenc xmm2, xmmword [r10+8*AES_BLOCK] + aesenclast xmm2, xmm1 + + movdqu xmmword [rdi], xmm2 ; output block + add rdi, AES_BLOCK + add rax, AES_BLOCK + sub rdx, 1 + jnz .single_blk_loop + + movdqa xmm10, xmmword [rsp+rax] ; tweak ^ key[0] + +.quit: + pxor xmm10, xmmword [rcx] ; remove key[0] + movdqu xmmword [r9], xmm10 ; and save tweak value + + pxor xmm1, xmm1 + + REST_XMM + REST_GPR + ret +ENDFUNC cpAESEncryptXTS_AES_NI + +%endif ;; _AES_NI_ENABLING_ +%endif ;;_IPP32E_Y8 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128safedecu8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128safedecu8as.asm new file mode 100644 index 000000000..3864a5f32 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128safedecu8as.asm @@ -0,0 +1,410 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael-128 (AES) cipher functions. +; (It's the special free from Sbox/tables implementation) +; +; Content: +; SafeDecrypt_RIJ128() +; +; History: +; +; Notes. +; The implementation is based on +; isomorphism between native GF(2^8) and composite GF((2^4)^2). +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_OFF_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_U8) + +%macro PTRANSFORM 6.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%memTransLO %3 + %xdefine %%memTransHI %4 + %xdefine %%tmp %5 + %xdefine %%srcLO %6 + + movdqa %%dst, oword [rel %%memTransLO] ;; LO transformation + movdqa %%tmp, oword [rel %%memTransHI] ;; HI transformation + + movdqa %%srcLO, %%src ;; split src: + psrlw %%src, 4 ;; + pand %%srcLO, xmm7 ;; low 4 bits -> srcLO + pand %%src, xmm7 ;; upper 4 bits -> src + + pshufb %%dst, %%srcLO ;; transformation + pshufb %%tmp, %%src + pxor %%dst, %%tmp +%endmacro + +%macro PLOOKUP_MEM 3.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%Table %3 + + movdqa %%dst, OWORD [rel %%Table] + pshufb %%dst,%%src +%endmacro + +%macro PREDUCE_MOD15 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + movdqa %%dst, %%src + pcmpgtb %%src, xmm7 + psubb %%dst, %%src +%endmacro + +%macro PINVERSE_GF16_INV 6.nolist + %xdefine %%xmmB %1 + %xdefine %%xmmC %2 + %xdefine %%xmmP %3 + %xdefine %%xmmQ %4 + %xdefine %%xmmD %5 + %xdefine %%xmmT %6 + + PLOOKUP_MEM %%xmmT, %%xmmC, GF16_logTbl ;; xmmT = index_of(c) + pxor %%xmmC, %%xmmB + PLOOKUP_MEM %%xmmQ, %%xmmC, GF16_logTbl ;; xmmQ = index_of(b xor c) + + PLOOKUP_MEM %%xmmD, %%xmmB, GF16_sqr1 ;; xmmD = sqr(b)*beta^14 + PLOOKUP_MEM %%xmmP, %%xmmB, GF16_logTbl ;; xmmP = index_of(b) + + paddb %%xmmT, %%xmmQ ;; xmmT = index_of(c) + index_of(b xor c) + PREDUCE_MOD15 %%xmmC, %%xmmT ;; + PLOOKUP_MEM %%xmmT, %%xmmC, GF16_expTbl ;; c*(b xor c) + + pxor %%xmmD, %%xmmT ;; xmmD = delta = (c*(b xor c)) xor (sqr(b)*beta^14) + PLOOKUP_MEM %%xmmT, %%xmmD, GF16_invLog ;; xmmT = index_of( inv(delta) ) + + paddb %%xmmQ, %%xmmT ;; xmmQ = index_of((b xor c) * inv(delta)) + paddb %%xmmP, %%xmmT ;; xmmP = index_of(b * inv(delta)) + PREDUCE_MOD15 %%xmmT, %%xmmQ + PLOOKUP_MEM %%xmmC, %%xmmT, GF16_expTbl + PREDUCE_MOD15 %%xmmT, %%xmmP + PLOOKUP_MEM %%xmmB, %%xmmT, GF16_expTbl +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +DECODE_DATA: + +;; (forward) native GF(2^8) to composite GF((2^4)^2) transformation : {0x01,0x2E,0x49,0x43,0x35,0xD0,0x3D,0xE9} +TransFwdLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 02Eh ;; 02Eh ;; 2 + DB 02Fh ;; 02Eh XOR 001h ;; 3 + DB 049h ;; 049h ;; 4 + DB 048h ;; 049h XOR 001h ;; 5 + DB 067h ;; 049h XOR 02Eh ;; 6 + DB 066h ;; 049h XOR 02Eh XOR 001h ;; 7 + DB 043h ;; 043h ;; 8 + DB 042h ;; 043h XOR 001h ;; 9 + DB 06Dh ;; 043h XOR 02Eh ;; a + DB 06Ch ;; 043h XOR 02Eh XOR 001h ;; b + DB 00Ah ;; 043h XOR 049h ;; c + DB 00Bh ;; 043h XOR 049h XOR 001h ;; d + DB 024h ;; 043h XOR 049h XOR 02Eh ;; e + DB 025h ;; 043h XOR 049h XOR 02Eh XOR 001h ;; f +TransFwdHI \ + DB 000h ;; 000h ;; 0 + DB 035h ;; 035h ;; 1 + DB 0D0h ;; 0D0h ;; 2 + DB 0E5h ;; 0D0h XOR 035h ;; 3 + DB 03Dh ;; 03Dh ;; 4 + DB 008h ;; 03Dh XOR 035h ;; 5 + DB 0EDh ;; 03Dh XOR 0D0h ;; 6 + DB 0D8h ;; 03Dh XOR 0D0h XOR 035h ;; 7 + DB 0E9h ;; 0E9h ;; 8 + DB 0DCh ;; 0E9h XOR 035h ;; 9 + DB 039h ;; 0E9h XOR 0D0h ;; a + DB 00Ch ;; 0E9h XOR 0D0h XOR 035h ;; b + DB 0D4h ;; 0E9h XOR 03Dh ;; c + DB 0E1h ;; 0E9h XOR 03Dh XOR 035h ;; d + DB 004h ;; 0E9h XOR 03Dh XOR 0D0h ;; e + DB 031h ;; 0E9h XOR 03Dh XOR 0D0h XOR 035h ;; f + +;; (inverse) composite GF((2^4)^2) to native GF(2^8) transformation : {0x01,0x5C,0xE0,0x50,0x1F,0xEE,0x55,0x6A} +TransInvLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 05Ch ;; 05Ch ;; 2 + DB 05Dh ;; 05Ch XOR 001h ;; 3 + DB 0E0h ;; 0E0h ;; 4 + DB 0E1h ;; 0E0h XOR 001h ;; 5 + DB 0BCh ;; 0E0h XOR 05Ch ;; 6 + DB 0BDh ;; 0E0h XOR 05Ch XOR 001h ;; 7 + DB 050h ;; 050h ;; 8 + DB 051h ;; 050h XOR 001h ;; 9 + DB 00Ch ;; 050h XOR 05Ch ;; a + DB 00Dh ;; 050h XOR 05Ch XOR 001h ;; b + DB 0B0h ;; 050h XOR 0E0h ;; c + DB 0B1h ;; 050h XOR 0E0h XOR 001h ;; d + DB 0ECh ;; 050h XOR 0E0h XOR 05Ch ;; e + DB 0EDh ;; 050h XOR 0E0h XOR 05Ch XOR 001h ;; f +TransInvHI \ + DB 000h ;; 000h ;; 0 + DB 01Fh ;; 01Fh ;; 1 + DB 0EEh ;; 0EEh ;; 2 + DB 0F1h ;; 0EEh XOR 01Fh ;; 3 + DB 055h ;; 055h ;; 4 + DB 04Ah ;; 055h XOR 01Fh ;; 5 + DB 0BBh ;; 055h XOR 0EEh ;; 6 + DB 0A4h ;; 055h XOR 0EEh XOR 01Fh ;; 7 + DB 06Ah ;; 06Ah ;; 8 + DB 075h ;; 06Ah XOR 01Fh ;; 9 + DB 084h ;; 06Ah XOR 0EEh ;; a + DB 09Bh ;; 06Ah XOR 0EEh XOR 01Fh ;; b + DB 03Fh ;; 06Ah XOR 055h ;; c + DB 020h ;; 06Ah XOR 055h XOR 01Fh ;; d + DB 0D1h ;; 06Ah XOR 055h XOR 0EEh ;; e + DB 0CEh ;; 06Ah XOR 055h XOR 0EEh XOR 01Fh ;; f + + +GF16_csize DB 00Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh + +;; GF16 elements: +;; 0 1 2 3 4 5 6 7 8 9 A B C D E F +GF16_logTbl \ + DB 0C0h,00h,01h,04h,02h,08h,05h,0Ah,03h,0Eh,09h,07h,06h,0Dh,0Bh,0Ch +GF16_expTbl \ + DB 001h,02h,04h,08h,03h,06h,0Ch,0Bh,05h,0Ah,07h,0Eh,0Fh,0Dh,09h,01h +GF16_sqr1 \ + DB 000h,09h,02h,0Bh,08h,01h,0Ah,03h,06h,0Fh,04h,0Dh,0Eh,07h,0Ch,05h ;; sqr(GF16_element) * beta^14 +GF16_invLog \ + DB 0C0h,00h,0Eh,0Bh,0Dh,07h,0Ah,05h,0Ch,01h,06h,08h,09h,02h,04h,03h + +;; affine transformation matrix (inverse cipher) : {0x50,0x36,0x15,0x82,0x01,0x34,0x40,0x3E} +InvAffineLO \ + DB 000h ;; 000h ;; 0 + DB 050h ;; 050h ;; 1 + DB 036h ;; 036h ;; 2 + DB 066h ;; 036h XOR 050h ;; 3 + DB 015h ;; 015h ;; 4 + DB 045h ;; 015h XOR 050h ;; 5 + DB 023h ;; 015h XOR 036h ;; 6 + DB 073h ;; 015h XOR 036h XOR 050h ;; 7 + DB 082h ;; 082h ;; 8 + DB 0D2h ;; 082h XOR 050h ;; 9 + DB 0B4h ;; 082h XOR 036h ;; a + DB 0E4h ;; 082h XOR 036h XOR 050h ;; b + DB 097h ;; 082h XOR 015h ;; c + DB 0C7h ;; 082h XOR 015h XOR 050h ;; d + DB 0A1h ;; 082h XOR 015h XOR 036h ;; e + DB 0F1h ;; 082h XOR 015h XOR 036h XOR 050h ;; f +InvAffineHI \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 034h ;; 034h ;; 2 + DB 035h ;; 034h XOR 001h ;; 3 + DB 040h ;; 040h ;; 4 + DB 041h ;; 040h XOR 001h ;; 5 + DB 074h ;; 040h XOR 034h ;; 6 + DB 075h ;; 040h XOR 034h XOR 001h ;; 7 + DB 03Eh ;; 03Eh ;; 8 + DB 03Fh ;; 03Eh XOR 001h ;; 9 + DB 00Ah ;; 03Eh XOR 034h ;; a + DB 00Bh ;; 03Eh XOR 034h XOR 001h ;; b + DB 07Eh ;; 03Eh XOR 040h ;; c + DB 07Fh ;; 03Eh XOR 040h XOR 001h ;; d + DB 04Ah ;; 03Eh XOR 040h XOR 034h ;; e + DB 04Bh ;; 03Eh XOR 040h XOR 034h XOR 001h ;; f + +;; affine transformation constant (inverse cipher) +InvAffineCnt \ + DQ 04848484848484848h,04848484848484848h + +;; shift rows transformation (inverse cipher) +InvShiftRows \ + DB 0,13,10,7,4,1,14,11,8,5,2,15,12,9,6,3 + +;; mix columns transformation (inverse cipher) +GF16mul_4_2x \ + DB 000h,024h,048h,06Ch,083h,0A7h,0CBh,0EFh,036h,012h,07Eh,05Ah,0B5h,091h,0FDh,0D9h ;; *(4+2x) +GF16mul_1_6x \ + DB 000h,061h,0C2h,0A3h,0B4h,0D5h,076h,017h,058h,039h,09Ah,0FBh,0ECh,08Dh,02Eh,04Fh ;; *(1+6x) + +GF16mul_C_6x \ + DB 000h,06Ch,0CBh,0A7h,0B5h,0D9h,07Eh,012h,05Ah,036h,091h,0FDh,0EFh,083h,024h,048h ;; *(C+6x) +GF16mul_3_Ax \ + DB 000h,0A3h,076h,0D5h,0ECh,04Fh,09Ah,039h,0FBh,058h,08Dh,02Eh,017h,0B4h,061h,0C2h ;; *(3+Ax) + +GF16mul_B_0x \ + DB 000h,00Bh,005h,00Eh,00Ah,001h,00Fh,004h,007h,00Ch,002h,009h,00Dh,006h,008h,003h ;; *(B+0x) +GF16mul_0_Bx \ + DB 000h,0B0h,050h,0E0h,0A0h,010h,0F0h,040h,070h,0C0h,020h,090h,0D0h,060h,080h,030h ;; *(0+Bx) + +GF16mul_2_4x \ + DB 000h,042h,084h,0C6h,038h,07Ah,0BCh,0FEh,063h,021h,0E7h,0A5h,05Bh,019h,0DFh,09Dh ;; *(2+4x) +GF16mul_2_6x \ + DB 000h,062h,0C4h,0A6h,0B8h,0DAh,07Ch,01Eh,053h,031h,097h,0F5h,0EBh,089h,02Fh,04Dh ;; *(2+6x) + +ColumnROR \ + DB 1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12 + + +align IPP_ALIGN_FACTOR +;************************************************************* +;* void SafeDecrypt_RIJ128(const Ipp8u* pInpBlk, +;* Ipp8u* pOutBlk, +;* int nr, +;* const Ipp8u* pKeys, +;* const void* Tables) +;************************************************************* + +;; +;; Lib = U8 +;; +IPPASM SafeDecrypt_RIJ128,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7 + COMP_ABI 5 +;; rdi: pInpBlk: DWORD, ; input block address +;; rsi: pOutBlk: DWORD, ; output block address +;; rdx: nr: DWORD, ; number of rounds +;; rcx: pKey: DWORD ; key material address + +%assign RSIZE sizeof(dword) ; size of row +%assign SC 4 ; columns in STATE +%assign SSIZE RSIZE*SC ; size of state + + lea rax,[rdx*4] + lea rcx,[rcx+rax*4] ; AES-128-keys + + movdqu xmm0, oword [rdi] ; input block + + movdqa xmm7, oword [rel GF16_csize] + + ;; convert input into the composite GF((2^4)^2) + PTRANSFORM xmm2, xmm0, TransFwdLO,TransFwdHI, xmm1, xmm3 + + ;; initial whitening + pxor xmm2, oword [rcx] + sub rcx, SSIZE + + ;; (nr-1) regular rounds + sub rdx,1 + +.decode_round: + ;; InvSubByte() Transformation: + + ;; affine transformation + PTRANSFORM xmm0, xmm2, InvAffineLO,InvAffineHI, xmm1, xmm3 + pxor xmm0, oword [rel InvAffineCnt] ; H(c), c=0x05 + + ;; split input by low and upper parts + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; low parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; upper parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_INV xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; InvShiftRows() Transformation: + pshufb xmm0, [rel InvShiftRows] + pshufb xmm1, [rel InvShiftRows] + + ;; InvMixColumn() Transformation: + PLOOKUP_MEM xmm2, xmm0, GF16mul_4_2x ; mul H(0xE) = 0x24 + pshufb xmm0, [rel ColumnROR] + PLOOKUP_MEM xmm3, xmm1, GF16mul_1_6x + pshufb xmm1, [rel ColumnROR] + pxor xmm2, xmm3 + + PLOOKUP_MEM xmm3, xmm0, GF16mul_C_6x ; mul H(0xB) = 0x6C + pshufb xmm0, [rel ColumnROR] + pxor xmm2, xmm3 + PLOOKUP_MEM xmm3, xmm1, GF16mul_3_Ax + pshufb xmm1, [rel ColumnROR] + pxor xmm2, xmm3 + + PLOOKUP_MEM xmm3, xmm0, GF16mul_B_0x ; mul H(0xD) = 0x0B + pshufb xmm0, [rel ColumnROR] + pxor xmm2, xmm3 + PLOOKUP_MEM xmm3, xmm1, GF16mul_0_Bx + pshufb xmm1, [rel ColumnROR] + pxor xmm2, xmm3 + + PLOOKUP_MEM xmm3, xmm0, GF16mul_2_4x ; mul H(0x9) = 0x42 + pxor xmm2, xmm3 + PLOOKUP_MEM xmm3, xmm1, GF16mul_2_6x + pxor xmm2, xmm3 + + ;; AddRoundKey() Transformation: + pxor xmm2, oword [rcx] + sub rcx, SSIZE + + sub rdx,1 + jg .decode_round + + + ;; + ;; the last one is irregular + ;; + + ;; InvSubByte() Transformation + + ;; affine transformation + PTRANSFORM xmm0, xmm2, InvAffineLO,InvAffineHI, xmm1, xmm3 + pxor xmm0, oword [rel InvAffineCnt] ; H(c), c=0x05 + + ;; split input by low and upper parts + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; low parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; upper parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_INV xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; InvShiftRows() Transformation: + psllw xmm1, 4 + por xmm1, xmm0 + pshufb xmm1, [rel InvShiftRows] + + ;; AddRoundKey() Transformation: + pxor xmm1, oword [rcx] + + ;; convert output into the native GF(2^8) + PTRANSFORM xmm0,xmm1, TransInvLO,TransInvHI, xmm2, xmm3 + + movdqu oword [rsi], xmm0 + + REST_XMM + REST_GPR + ret +ENDFUNC SafeDecrypt_RIJ128 + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128safeencu8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128safeencu8as.asm new file mode 100644 index 000000000..0de859765 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprij128safeencu8as.asm @@ -0,0 +1,426 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael-128 (AES) cipher functions. +; (It's the special free from Sbox/tables implementation) +; +; Content: +; SafeEncrypt_RIJ128() +; +; History: +; +; Notes. +; The implementation is based on +; isomorphism between native GF(2^8) and composite GF((2^4)^2). +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_AES_NI_ENABLING_ == _FEATURE_OFF_) || (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_U8) + +%macro PTRANSFORM 6.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%memTransLO %3 + %xdefine %%memTransHI %4 + %xdefine %%tmp %5 + %xdefine %%srcLO %6 + + movdqa %%dst, oword [rel %%memTransLO] ;; LO transformation + movdqa %%tmp, oword [rel %%memTransHI] ;; HI transformation + + movdqa %%srcLO, %%src ;; split src: + psrlw %%src, 4 ;; + pand %%srcLO, xmm7 ;; low 4 bits -> srcLO + pand %%src, xmm7 ;; upper 4 bits -> src + + pshufb %%dst, %%srcLO ;; transformation + pshufb %%tmp, %%src + pxor %%dst, %%tmp +%endmacro + +%macro PLOOKUP_MEM 3.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + %xdefine %%Table %3 + + movdqa %%dst, OWORD [rel %%Table] + pshufb %%dst,%%src +%endmacro + +%macro PREDUCE_MOD15 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + movdqa %%dst, %%src + pcmpgtb %%src, xmm7 + psubb %%dst, %%src +%endmacro + +%macro PINVERSE_GF16_FWD 6.nolist + %xdefine %%xmmB %1 + %xdefine %%xmmC %2 + %xdefine %%xmmP %3 + %xdefine %%xmmQ %4 + %xdefine %%xmmD %5 + %xdefine %%xmmT %6 + + PLOOKUP_MEM %%xmmT, %%xmmC, GF16_logTbl ;; xmmT = index_of(c) + pxor %%xmmC, %%xmmB + PLOOKUP_MEM %%xmmQ, %%xmmC, GF16_logTbl ;; xmmQ = index_of(b xor c) + + PLOOKUP_MEM %%xmmD, %%xmmB, GF16_sqr1 ;; xmmD = sqr(b)*beta^14 + PLOOKUP_MEM %%xmmP, %%xmmB, GF16_logTbl ;; xmmP = index_of(b) + + paddb %%xmmT, %%xmmQ ;; xmmT = index_of(c) + index_of(b xor c) + PREDUCE_MOD15 %%xmmC, %%xmmT ;; + PLOOKUP_MEM %%xmmT, %%xmmC, GF16_expTbl ;; c*(b xor c) + + pxor %%xmmD, %%xmmT ;; xmmD = delta = (c*(b xor c)) xor (sqr(b)*beta^14) + PLOOKUP_MEM %%xmmT, %%xmmD, GF16_invLog ;; xmmT = index_of( inv(delta) ) + + paddb %%xmmQ, %%xmmT ;; xmmQ = index_of((b xor c) * inv(delta)) + paddb %%xmmP, %%xmmT ;; xmmP = index_of(b * inv(delta)) + PREDUCE_MOD15 %%xmmT, %%xmmQ + PLOOKUP_MEM %%xmmC, %%xmmT, GF16_expTbl + PREDUCE_MOD15 %%xmmT, %%xmmP + PLOOKUP_MEM %%xmmB, %%xmmT, GF16_expTbl +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +ENCODE_DATA: + +;; (forward) native GF(2^8) to composite GF((2^4)^2) transformation : {0x01,0x2E,0x49,0x43,0x35,0xD0,0x3D,0xE9} +TransFwdLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 02Eh ;; 02Eh ;; 2 + DB 02Fh ;; 02Eh XOR 001h ;; 3 + DB 049h ;; 049h ;; 4 + DB 048h ;; 049h XOR 001h ;; 5 + DB 067h ;; 049h XOR 02Eh ;; 6 + DB 066h ;; 049h XOR 02Eh XOR 001h ;; 7 + DB 043h ;; 043h ;; 8 + DB 042h ;; 043h XOR 001h ;; 9 + DB 06Dh ;; 043h XOR 02Eh ;; a + DB 06Ch ;; 043h XOR 02Eh XOR 001h ;; b + DB 00Ah ;; 043h XOR 049h ;; c + DB 00Bh ;; 043h XOR 049h XOR 001h ;; d + DB 024h ;; 043h XOR 049h XOR 02Eh ;; e + DB 025h ;; 043h XOR 049h XOR 02Eh XOR 001h ;; f +TransFwdHI \ + DB 000h ;; 000h ;; 0 + DB 035h ;; 035h ;; 1 + DB 0D0h ;; 0D0h ;; 2 + DB 0E5h ;; 0D0h XOR 035h ;; 3 + DB 03Dh ;; 03Dh ;; 4 + DB 008h ;; 03Dh XOR 035h ;; 5 + DB 0EDh ;; 03Dh XOR 0D0h ;; 6 + DB 0D8h ;; 03Dh XOR 0D0h XOR 035h ;; 7 + DB 0E9h ;; 0E9h ;; 8 + DB 0DCh ;; 0E9h XOR 035h ;; 9 + DB 039h ;; 0E9h XOR 0D0h ;; a + DB 00Ch ;; 0E9h XOR 0D0h XOR 035h ;; b + DB 0D4h ;; 0E9h XOR 03Dh ;; c + DB 0E1h ;; 0E9h XOR 03Dh XOR 035h ;; d + DB 004h ;; 0E9h XOR 03Dh XOR 0D0h ;; e + DB 031h ;; 0E9h XOR 03Dh XOR 0D0h XOR 035h ;; f + +;; (inverse) composite GF((2^4)^2) to native GF(2^8) transformation : {0x01,0x5C,0xE0,0x50,0x1F,0xEE,0x55,0x6A} +TransInvLO \ + DB 000h ;; 000h ;; 0 + DB 001h ;; 001h ;; 1 + DB 05Ch ;; 05Ch ;; 2 + DB 05Dh ;; 05Ch XOR 001h ;; 3 + DB 0E0h ;; 0E0h ;; 4 + DB 0E1h ;; 0E0h XOR 001h ;; 5 + DB 0BCh ;; 0E0h XOR 05Ch ;; 6 + DB 0BDh ;; 0E0h XOR 05Ch XOR 001h ;; 7 + DB 050h ;; 050h ;; 8 + DB 051h ;; 050h XOR 001h ;; 9 + DB 00Ch ;; 050h XOR 05Ch ;; a + DB 00Dh ;; 050h XOR 05Ch XOR 001h ;; b + DB 0B0h ;; 050h XOR 0E0h ;; c + DB 0B1h ;; 050h XOR 0E0h XOR 001h ;; d + DB 0ECh ;; 050h XOR 0E0h XOR 05Ch ;; e + DB 0EDh ;; 050h XOR 0E0h XOR 05Ch XOR 001h ;; f +TransInvHI \ + DB 000h ;; 000h ;; 0 + DB 01Fh ;; 01Fh ;; 1 + DB 0EEh ;; 0EEh ;; 2 + DB 0F1h ;; 0EEh XOR 01Fh ;; 3 + DB 055h ;; 055h ;; 4 + DB 04Ah ;; 055h XOR 01Fh ;; 5 + DB 0BBh ;; 055h XOR 0EEh ;; 6 + DB 0A4h ;; 055h XOR 0EEh XOR 01Fh ;; 7 + DB 06Ah ;; 06Ah ;; 8 + DB 075h ;; 06Ah XOR 01Fh ;; 9 + DB 084h ;; 06Ah XOR 0EEh ;; a + DB 09Bh ;; 06Ah XOR 0EEh XOR 01Fh ;; b + DB 03Fh ;; 06Ah XOR 055h ;; c + DB 020h ;; 06Ah XOR 055h XOR 01Fh ;; d + DB 0D1h ;; 06Ah XOR 055h XOR 0EEh ;; e + DB 0CEh ;; 06Ah XOR 055h XOR 0EEh XOR 01Fh ;; f + + +GF16_csize DB 00Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh,0Fh + +;; GF16 elements: +;; 0 1 2 3 4 5 6 7 8 9 A B C D E F +GF16_logTbl \ + DB 0C0h,00h,01h,04h,02h,08h,05h,0Ah,03h,0Eh,09h,07h,06h,0Dh,0Bh,0Ch +GF16_expTbl \ + DB 001h,02h,04h,08h,03h,06h,0Ch,0Bh,05h,0Ah,07h,0Eh,0Fh,0Dh,09h,01h +GF16_sqr1 \ + DB 000h,09h,02h,0Bh,08h,01h,0Ah,03h,06h,0Fh,04h,0Dh,0Eh,07h,0Ch,05h ;; sqr(GF16_element) * beta^14 +GF16_invLog \ + DB 0C0h,00h,0Eh,0Bh,0Dh,07h,0Ah,05h,0Ch,01h,06h,08h,09h,02h,04h,03h +GF16_expTbl_shift \ + DB 010h,020h,040h,080h,030h,060h,0C0h,0B0h,050h,0A0h,070h,0E0h,0F0h,0D0h,090h,010h + +;; affine transformation matrix (forward cipher) : {0x10,0x22,0x55,0x82,0x41,0x34,0x40,0x2A} +FwdAffineLO \ + DB 000h ;; 000h ;; 0 + DB 010h ;; 010h ;; 1 + DB 022h ;; 022h ;; 2 + DB 032h ;; 022h XOR 010h ;; 3 + DB 055h ;; 055h ;; 4 + DB 045h ;; 055h XOR 010h ;; 5 + DB 077h ;; 055h XOR 022h ;; 6 + DB 067h ;; 055h XOR 022h XOR 010h ;; 7 + DB 082h ;; 082h ;; 8 + DB 092h ;; 082h XOR 010h ;; 9 + DB 0A0h ;; 082h XOR 022h ;; a + DB 0B0h ;; 082h XOR 022h XOR 010h ;; b + DB 0D7h ;; 082h XOR 055h ;; c + DB 0C7h ;; 082h XOR 055h XOR 010h ;; d + DB 0F5h ;; 082h XOR 055h XOR 022h ;; e + DB 0E5h ;; 082h XOR 055h XOR 022h XOR 010h ;; f +FwdAffineHI \ + DB 000h ;; 000h ;; 0 + DB 041h ;; 041h ;; 1 + DB 034h ;; 034h ;; 2 + DB 075h ;; 034h XOR 041h ;; 3 + DB 040h ;; 040h ;; 4 + DB 001h ;; 040h XOR 041h ;; 5 + DB 074h ;; 040h XOR 034h ;; 6 + DB 035h ;; 040h XOR 034h XOR 041h ;; 7 + DB 02Ah ;; 02Ah ;; 8 + DB 06Bh ;; 02Ah XOR 041h ;; 9 + DB 01Eh ;; 02Ah XOR 034h ;; a + DB 05Fh ;; 02Ah XOR 034h XOR 041h ;; b + DB 06Ah ;; 02Ah XOR 040h ;; c + DB 02Bh ;; 02Ah XOR 040h XOR 041h ;; d + DB 05Eh ;; 02Ah XOR 040h XOR 034h ;; e + DB 01Fh ;; 02Ah XOR 040h XOR 034h XOR 041h ;; f + +;; affine transformation constant (forward cipher) +FwdAffineCnt \ + DQ 0C2C2C2C2C2C2C2C2h,0C2C2C2C2C2C2C2C2h + +;; shift rows transformation (forward cipher) +FwdShiftRows \ + DB 0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11 + +;; mix columns transformation (forward cipher) +GF16mul_E_2x \ + DB 000h,02Eh,04Fh,061h,08Dh,0A3h,0C2h,0ECh,039h,017h,076h,058h,0B4h,09Ah,0FBh,0D5h +GF16mul_1_Cx \ + DB 000h,0C1h,0B2h,073h,054h,095h,0E6h,027h,0A8h,069h,01Ah,0DBh,0FCh,03Dh,04Eh,08Fh + +ColumnROR \ + DB 1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12 + + +;************************************************************* +; convert GF(2^128) -> GF((2^4)^2) +;************************************************************* +align IPP_ALIGN_FACTOR +IPPASM TransformNative2Composite,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM xmm7 + COMP_ABI 2 +;; rdi: pOutBlk: DWORD, ; output block address +;; rsi: pInpBlk: DWORD, ; input block address + + movdqu xmm0, oword [rsi] ; input block + movdqa xmm7, oword [rel GF16_csize] + + ;; convert input into the composite GF((2^4)^2) + PTRANSFORM xmm1, xmm0, TransFwdLO,TransFwdHI, xmm2, xmm3 + + movdqu oword [rdi], xmm1 ; output block + + REST_XMM + REST_GPR + ret +ENDFUNC TransformNative2Composite + +;************************************************************* +;* void SafeEncrypt_RIJ128(const Ipp8u* pInpBlk, +;* Ipp8u* pOutBlk, +;* int nr, +;* const Ipp8u* pKeys, +;* const void* Tables) +;************************************************************* +align IPP_ALIGN_FACTOR +;; +;; Lib = U8 +;; +IPPASM SafeEncrypt_RIJ128,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7 + COMP_ABI 5 +;; rdi: pInpBlk: DWORD, ; input block address +;; rsi: pOutBlk: DWORD, ; output block address +;; rdx: nr: DWORD, ; number of rounds +;; rcx: pKey: DWORD ; key material address + +%assign RSIZE sizeof(dword) ; size of row +%assign SC 4 ; columns in STATE +%assign SSIZE RSIZE*SC ; size of state + + movdqu xmm1, oword [rdi] ; input block + + movdqa xmm7, oword [rel GF16_csize] + + ;; convert input into the composite GF((2^4)^2) + PTRANSFORM xmm0, xmm1, TransFwdLO,TransFwdHI, xmm2, xmm3 + + ;; initial whitening + pxor xmm0, oword [rcx] + add rcx, SSIZE + + ;; (nr-1) regular rounds + sub rdx,1 + +.encode_round: + ;; SubByte() Transformation: + + ;; split input by low and upper parts + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; low parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; upper parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_FWD xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; affine transformation + movdqa xmm3, oword [rel FwdAffineLO] + movdqa xmm2, oword [rel FwdAffineHI] + movdqa xmm4, oword [rel FwdAffineCnt] ; H(c), c=0x63 + pshufb xmm3, xmm0 + pshufb xmm2, xmm1 + pxor xmm3, xmm4 + pxor xmm3, xmm2 + + ;; ShiftRows() Transformation: + pshufb xmm3, [rel FwdShiftRows] + + ;; MixColumn() Transformation: + movdqa xmm1, xmm3 + movdqa xmm2, xmm3 + pxor xmm4, xmm4 + psrlw xmm2, 4 + + pand xmm1, xmm7 ;; a0*(0xE + 0x2*t) + PLOOKUP_MEM xmm0, xmm1, GF16mul_E_2x + + pand xmm2, xmm7 ;; a1*(0x2*0x9 + (0x2+0xE)*t) + PLOOKUP_MEM xmm1, xmm2, GF16mul_1_Cx + + pxor xmm0, xmm1 + + pshufb xmm3, [rel ColumnROR] + pxor xmm4, xmm3 + + pshufb xmm3, [rel ColumnROR] + pxor xmm4, xmm3 + + movdqa xmm2, xmm0 + pshufb xmm2, [rel ColumnROR] + pxor xmm0, xmm2 + + pshufb xmm3, [rel ColumnROR] + pxor xmm4, xmm3 + + pxor xmm0, xmm4 + + ;; AddRoundKey() Transformation: + pxor xmm0, oword [rcx] + add rcx, SSIZE + + sub rdx,1 + jg .encode_round + + + ;; + ;; the last one is irregular + ;; + + ;; SubByte() Transformation: + movdqa xmm1, xmm0 + pand xmm0, xmm7 ; low parts (4 bits) + psrlw xmm1, 4 + pand xmm1, xmm7 ; upper parts (4 bits) + + ;; compute multiplicative inverse + PINVERSE_GF16_FWD xmm1,xmm0, xmm3,xmm2,xmm4,xmm5 + + ;; affine transformation + movdqa xmm3, oword [rel FwdAffineLO] + movdqa xmm2, oword [rel FwdAffineHI] + movdqa xmm4, oword [rel FwdAffineCnt] ; H(c), c=0x63 + pshufb xmm3, xmm0 + pshufb xmm2, xmm1 + pxor xmm3, xmm4 + pxor xmm3, xmm2 + + ;; ShiftRows() Transformation: + pshufb xmm3, [rel FwdShiftRows] + + ;; AddRoundKey() Transformation: + pxor xmm3, oword [rcx] + + ;; convert output into the native GF(2^8) + PTRANSFORM xmm0,xmm3, TransInvLO,TransInvHI, xmm2,xmm1 + + movdqu oword [rsi], xmm0 + + REST_XMM + REST_GPR + ret +ENDFUNC SafeEncrypt_RIJ128 + +%endif + +%endif ;; _AES_NI_ENABLING_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprijnkeym7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprijnkeym7as.asm new file mode 100644 index 000000000..d37a86f42 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcprijnkeym7as.asm @@ -0,0 +1,91 @@ +;=============================================================================== +; Copyright (C) 2014 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Rijndael Key Expansion Support +; +; Content: +; SubsDword_8uT() +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +segment .text align=IPP_ALIGN_FACTOR + +%xdefine CACHE_LINE_SIZE (64) + +;*************************************************************** +;* Purpose: Mitigation of the Key Expansion procedure +;* +;* Ipp32u Touch_SubsDword_8uT(Ipp32u inp, +;* const Ipp8u* pTbl, +;* int tblBytes) +;*************************************************************** +align IPP_ALIGN_FACTOR +IPPASM Touch_SubsDword_8uT,PUBLIC + USES_GPR rsi,rdi + USES_XMM + COMP_ABI 3 +;; rdi: inp: DWORD, ; input dword +;; rsi: pTbl: BYTE, ; Rijndael's S-box +;; edx tblLen: DWORD ; length of table (bytes) + + movsxd r8, edx ; length + xor rcx, rcx +.touch_tbl: + mov rax, [rsi+rcx] + add rcx, CACHE_LINE_SIZE + cmp rcx, r8 + jl .touch_tbl + + mov rax, rdi + and rax, 0FFh ; b[0] + movzx rax, BYTE [rsi+rax] + + shr rdi, 8 + mov r9, rdi + and r9, 0FFh ; b[1] + movzx r9, BYTE [rsi+r9] + shl r9, 8 + + shr rdi, 8 + mov rcx, rdi + and rcx, 0FFh ; b[2] + movzx rcx, BYTE [rsi+rcx] + shl rcx, 16 + + shr rdi, 8 + mov rdx, rdi + and rdx, 0FFh ; b[3] + movzx rdx, BYTE [rsi+rdx] + shl rdx, 24 + + or rax, r9 + or rax, rcx + or rax, rdx + REST_XMM + REST_GPR + ret +ENDFUNC Touch_SubsDword_8uT + +%endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1e9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1e9as.asm new file mode 100644 index 000000000..ca71d33ba --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1e9as.asm @@ -0,0 +1,510 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA1 +; +; Content: +; UpdateSHA1 +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA1_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +;;%if (_IPP32E >= _IPP32E_E9 ) +%if (_IPP32E == _IPP32E_E9 ) + +;; +;; SHA1 constants K[i] +%xdefine SHA1_K1 (05a827999h) +%xdefine SHA1_K2 (06ed9eba1h) +%xdefine SHA1_K3 (08f1bbcdch) +%xdefine SHA1_K4 (0ca62c1d6h) + +;; +;; Magic functions defined in FIPS 180-1 +;; +;; F1, F2, F3 and F4 assumes, that +;; - T1 returns function value +;; - T2 is the temporary +;; + +%macro F1 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + mov T1,%%C + xor T1,%%D + and T1,%%B + xor T1,%%D +%endmacro + +%macro F2 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + mov T1,%%D + xor T1,%%C + xor T1,%%B +%endmacro + +%macro F3 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + mov T1,%%C + mov T2,%%B + or T1,%%B + and T2,%%C + and T1,%%D + or T1,T2 +%endmacro + +%macro F4 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + F2 %%B,%%C,%%D +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; rotations +;; + +%macro ROL_5 1.nolist + %xdefine %%x %1 + + shld %%x,%%x, 5 +%endmacro + +%macro ROL_30 1.nolist + %xdefine %%x %1 + + shld %%x,%%x, 30 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; textual rotation of W array +;; +%macro ROTATE_W 0.nolist + %xdefine W_minus_32 W_minus_28 + %xdefine W_minus_28 W_minus_24 + %xdefine W_minus_24 W_minus_20 + %xdefine W_minus_20 W_minus_16 + %xdefine W_minus_16 W_minus_12 + %xdefine W_minus_12 W_minus_08 + %xdefine W_minus_08 W_minus_04 + %xdefine W_minus_04 W + %xdefine W W_minus_32 +%endmacro + +;; +;; SHA1 update round: +;; - F1 magic is used (and imbedded into the macros directly) +;; - 16 bytes of input are swapped +;; +%macro SHA1_UPDATE_RND_F1_BSWAP 7.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%nr %6 + %xdefine %%Wchunk %7 + + vpshufb W, %%Wchunk, XMM_SHUFB_BSWAP + vpaddd %%Wchunk, W, oword [K_XMM] + vmovdqa oword [rsp + (%%nr & 15)*4], %%Wchunk + mov T1,%%C ; F1 + mov T2,%%A + xor T1,%%D ; F1 + and T1,%%B ; F1 + ROL_5 T2 + xor T1,%%D ; F1 + add %%E, T2 + ROL_30 %%B + add T1, dword [rsp + (%%nr & 15)*4] + add %%E,T1 + + ROTATE_W +%endmacro + +;; +;; SHA1 update round: +;; - F1 magic is used (and imbedded into the macros directly) +;; +%macro SHA1_UPDATE_RND_F1 6.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%nr %6 + + mov T1,%%C ; F1 + mov T2,%%A + xor T1,%%D ; F1 + ROL_5 T2 + and T1,%%B ; F1 + xor T1,%%D ; F1 + add %%E, T2 + ROL_30 %%B + add T1, dword [rsp + (%%nr & 15)*4] + add %%E,T1 +%endmacro + +;; +;; update W +;; +%macro W_CALC 1.nolist + %xdefine %%nr %1 + + %assign %%W_CALC_ahead 8 + + %assign %%i (%%nr + %%W_CALC_ahead) + + %if (%%i < 20) + %xdefine K_XMM K_BASE + %elif (%%i < 40) + %xdefine K_XMM K_BASE+16 + %elif (%%i < 60) + %xdefine K_XMM K_BASE+32 + %else + %xdefine K_XMM K_BASE+48 + %endif + + %if (%%i < 32) + %if ((%%i & 3) == 0) ;; just scheduling to interleave with ALUs + vpalignr W, W_minus_12, W_minus_16, 8 ; w[i-14] + vpsrldq W_TMP, W_minus_04, 4 ; w[i-3] + vpxor W, W, W_minus_08 + %elif ((%%i & 3) == 1) + vpxor W_TMP, W_TMP, W_minus_16 + vpxor W, W, W_TMP + vpslldq W_TMP2, W, 12 + %elif ((%%i & 3) == 2) + vpslld W_TMP, W, 1 + vpsrld W, W, 31 + vpor W_TMP, W_TMP, W + vpslld W, W_TMP2, 2 + vpsrld W_TMP2, W_TMP2, 30 + %elif ((%%i & 3) == 3) + vpxor W_TMP, W_TMP, W + vpxor W, W_TMP, W_TMP2 + vpaddd W_TMP, W, oword [K_XMM] + vmovdqa oword [rsp + ((%%i & (~3)) & 15)*4],W_TMP + + ROTATE_W + %endif + +;; %elif (i < 83) + %elif (%%i < 80) + %if ((%%i & 3) == 0) ;; scheduling to interleave with ALUs + vpalignr W_TMP, W_minus_04, W_minus_08, 8 + vpxor W, W, W_minus_28 ;; W == W_minus_32 + %elif ((%%i & 3) == 1) + vpxor W_TMP, W_TMP, W_minus_16 + vpxor W, W, W_TMP + %elif ((%%i & 3) == 2) + vpslld W_TMP, W, 2 + vpsrld W, W, 30 + vpor W, W_TMP, W + %elif ((%%i & 3) == 3) + vpaddd W_TMP, W, oword [K_XMM] + vmovdqa oword [rsp + ((%%i & (~3)) & 15)*4],W_TMP + + ROTATE_W + %endif + + %endif +%endmacro + +;; +;; Regular hash update +;; +%macro SHA1_UPDATE_REGULAR 7.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%nr %6 + %xdefine %%MagiF %7 + + W_CALC %%nr + + add %%E, dword [rsp + (%%nr & 15)*4] + %%MagiF %%B,%%C,%%D + add %%D, dword [rsp +((%%nr+1) & 15)*4] + ROL_30 %%B + mov T3,%%A + add %%E, T1 + ROL_5 T3 + add T3, %%E + mov %%E, T3 + + W_CALC %%nr+1 + + ROL_5 T3 + add %%D,T3 + %%MagiF %%A,%%B,%%C + add %%D, T1 + ROL_30 %%A + +; write: %1, %2 +; rotate: %1<=%4, %2<=%5, %3<=%1, %4<=%2, %5<=%3 +%endmacro + +;; update hash macro +%macro UPDATE_HASH 2.nolist + %xdefine %%hash0 %1 + %xdefine %%hashAdd %2 + + add %%hashAdd, %%hash0 + mov %%hash0, %%hashAdd +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +K_XMM_AR dd SHA1_K1, SHA1_K1, SHA1_K1, SHA1_K1 + dd SHA1_K2, SHA1_K2, SHA1_K2, SHA1_K2 + dd SHA1_K3, SHA1_K3, SHA1_K3, SHA1_K3 + dd SHA1_K4, SHA1_K4, SHA1_K4, SHA1_K4 + +shuffle_mask DD 00010203h + DD 04050607h + DD 08090a0bh + DD 0c0d0e0fh + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA1(DigestSHA1 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +;; +;; Lib = Y8 +;; +;; Caller = ippsSHA1Update +;; Caller = ippsSHA1Final +;; Caller = ippsSHA1MessageDigest +;; +;; Caller = ippsHMACSHA1Update +;; Caller = ippsHMACSHA1Final +;; Caller = ippsHMACSHA1MessageDigest +;; + +;; assign hash values to GPU registers +%xdefine A ecx +%xdefine B eax +%xdefine C edx +%xdefine D r8d +%xdefine E r9d + +;; temporary +%xdefine T1 r10d +%xdefine T2 r11d +%xdefine T3 r13d +%xdefine T4 r13d + +%xdefine W_TMP xmm0 +%xdefine W_TMP2 xmm1 + +%xdefine W0 xmm2 +%xdefine W4 xmm3 +%xdefine W8 xmm4 +%xdefine W12 xmm5 +%xdefine W16 xmm6 +%xdefine W20 xmm7 +%xdefine W24 xmm8 +%xdefine W28 xmm9 + +;; endianness swap constant +%xdefine XMM_SHUFB_BSWAP xmm10 + +;; K_BASE contains [K_XMM_AR] address +%xdefine K_BASE r12 + + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA1,PUBLIC +%assign LOCAL_FRAME (16*4) + USES_GPR rdi,rsi,r12,r13,r14 + USES_XMM_AVX xmm6,xmm7,xmm8,xmm9,xmm10 + COMP_ABI 4 + +;; +;; rdi = digest ptr +;; rsi = data block ptr +;; rdx = data length +;; rcx = dummy + +%xdefine MBS_SHA1 (64) + + movsxd r14, edx + + movdqa XMM_SHUFB_BSWAP, oword [rel shuffle_mask] ; load shuffle mask + lea K_BASE, [rel K_XMM_AR] ; SHA1 const array address + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + mov A, dword [rdi] ; load initial hash value + mov B, dword [rdi+4] + mov C, dword [rdi+8] + mov D, dword [rdi+12] + mov E, dword [rdi+16] + + movdqu W28, oword [rsi] ; load buffer content + movdqu W24, oword [rsi+16] + movdqu W20, oword [rsi+32] + movdqu W16, oword [rsi+48] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;SHA1_MAIN_BODY + +%xdefine W W0 +%xdefine W_minus_04 W4 +%xdefine W_minus_08 W8 +%xdefine W_minus_12 W12 +%xdefine W_minus_16 W16 +%xdefine W_minus_20 W20 +%xdefine W_minus_24 W24 +%xdefine W_minus_28 W28 +%xdefine W_minus_32 W + + ;; assignment +%xdefine K_XMM K_BASE + +;;F textequ + SHA1_UPDATE_RND_F1_BSWAP A,B,C,D,E, 0, W28 + SHA1_UPDATE_RND_F1 E,A,B,C,D, 1 + SHA1_UPDATE_RND_F1 D,E,A,B,C, 2 + SHA1_UPDATE_RND_F1 C,D,E,A,B, 3 + + SHA1_UPDATE_RND_F1_BSWAP B,C,D,E,A, 4, W24 + SHA1_UPDATE_RND_F1 A,B,C,D,E, 5 + SHA1_UPDATE_RND_F1 E,A,B,C,D, 6 + SHA1_UPDATE_RND_F1 D,E,A,B,C, 7 + + SHA1_UPDATE_RND_F1_BSWAP C,D,E,A,B, 8, W20 + SHA1_UPDATE_RND_F1 B,C,D,E,A, 9 + SHA1_UPDATE_RND_F1 A,B,C,D,E, 10 + SHA1_UPDATE_RND_F1 E,A,B,C,D, 11 + + SHA1_UPDATE_RND_F1_BSWAP D,E,A,B,C, 12, W16 + + W_CALC 8 + W_CALC 9 + W_CALC 10 + + SHA1_UPDATE_RND_F1 C,D,E,A,B, 13 + + W_CALC 11 + W_CALC 12 + + SHA1_UPDATE_RND_F1 B,C,D,E,A, 14 + + W_CALC 13 + W_CALC 14 + W_CALC 15 + + SHA1_UPDATE_RND_F1 A,B,C,D,E, 15 + + SHA1_UPDATE_REGULAR E,A,B,C,D,16, F1 + SHA1_UPDATE_REGULAR C,D,E,A,B,18, F1 + +;;F textequ + SHA1_UPDATE_REGULAR A,B,C,D,E,20, F2 + SHA1_UPDATE_REGULAR D,E,A,B,C,22, F2 + SHA1_UPDATE_REGULAR B,C,D,E,A,24, F2 + SHA1_UPDATE_REGULAR E,A,B,C,D,26, F2 + SHA1_UPDATE_REGULAR C,D,E,A,B,28, F2 + + SHA1_UPDATE_REGULAR A,B,C,D,E,30, F2 + SHA1_UPDATE_REGULAR D,E,A,B,C,32, F2 + SHA1_UPDATE_REGULAR B,C,D,E,A,34, F2 + SHA1_UPDATE_REGULAR E,A,B,C,D,36, F2 + SHA1_UPDATE_REGULAR C,D,E,A,B,38, F2 + +;;F textequ + SHA1_UPDATE_REGULAR A,B,C,D,E,40, F3 + SHA1_UPDATE_REGULAR D,E,A,B,C,42, F3 + SHA1_UPDATE_REGULAR B,C,D,E,A,44, F3 + SHA1_UPDATE_REGULAR E,A,B,C,D,46, F3 + SHA1_UPDATE_REGULAR C,D,E,A,B,48, F3 + + SHA1_UPDATE_REGULAR A,B,C,D,E,50, F3 + SHA1_UPDATE_REGULAR D,E,A,B,C,52, F3 + SHA1_UPDATE_REGULAR B,C,D,E,A,54, F3 + SHA1_UPDATE_REGULAR E,A,B,C,D,56, F3 + SHA1_UPDATE_REGULAR C,D,E,A,B,58, F3 + +;;F textequ + SHA1_UPDATE_REGULAR A,B,C,D,E,60, F4 + SHA1_UPDATE_REGULAR D,E,A,B,C,62, F4 + SHA1_UPDATE_REGULAR B,C,D,E,A,64, F4 + SHA1_UPDATE_REGULAR E,A,B,C,D,66, F4 + SHA1_UPDATE_REGULAR C,D,E,A,B,68, F4 + + SHA1_UPDATE_REGULAR A,B,C,D,E,70, F4 + SHA1_UPDATE_REGULAR D,E,A,B,C,72, F4 + SHA1_UPDATE_REGULAR B,C,D,E,A,74, F4 + SHA1_UPDATE_REGULAR E,A,B,C,D,76, F4 + SHA1_UPDATE_REGULAR C,D,E,A,B,78, F4 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + UPDATE_HASH dword [rdi], A + UPDATE_HASH dword [rdi+4], B + UPDATE_HASH dword [rdi+8], C + UPDATE_HASH dword [rdi+12],D + UPDATE_HASH dword [rdi+16],E + + add rsi, MBS_SHA1 + sub r14, MBS_SHA1 + jg .sha1_block_loop + + REST_XMM_AVX + REST_GPR + ret +ENDFUNC UpdateSHA1 + +%endif ;; _IPP32E >= _IPP32E_E9 +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA1_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1l9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1l9as.asm new file mode 100644 index 000000000..94dd60f9e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1l9as.asm @@ -0,0 +1,788 @@ +;=============================================================================== +; Copyright (C) 2017 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA1 +; +; Content: +; UpdateSHA1 +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA1_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_L9 ) + + +;; +;; assignments +;; +%xdefine hA eax ;; hash values into GPU registers +%xdefine F ebp +%xdefine hB ebx +%xdefine hC ecx +%xdefine hD edx +%xdefine hE r8d + +%xdefine T1 r10d ;; SHA1 round computation (temporary) +%xdefine T2 r11d + +%xdefine W00 ymm2 ;; W values into YMM registers +%xdefine W04 ymm3 +%xdefine W08 ymm4 +%xdefine W12 ymm5 +%xdefine W16 ymm6 +%xdefine W20 ymm7 +%xdefine W24 ymm8 +%xdefine W28 ymm9 + +%xdefine W16L xmm6 +%xdefine W20L xmm7 +%xdefine W24L xmm8 +%xdefine W28L xmm9 + +%xdefine WTMP1 ymm0 ;; msg schedulling computation (temporary) +%xdefine WTMP2 ymm1 +%xdefine WTMP3 ymm10 + +%xdefine YMM_SHUFB ymm11 ;; byte swap constant +%xdefine YMM_K ymm12 ;; sha1 round constant value + +%xdefine F_PTR r13 ;; frame ptr/data block ptr +;;W_PTR textequ r12 ;; frame ptr/data block ptr + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; textual rotation of W array +;; +%macro ROTATE_W 0.nolist + %xdefine W_minus_32 W_minus_28 + %xdefine W_minus_28 W_minus_24 + %xdefine W_minus_24 W_minus_20 + %xdefine W_minus_20 W_minus_16 + %xdefine W_minus_16 W_minus_12 + %xdefine W_minus_12 W_minus_08 + %xdefine W_minus_08 W_minus_04 + %xdefine W_minus_04 W + %xdefine W W_minus_32 +%endmacro + +;; +;; msg schedulling for initial 00-15 sha1 rounds: +;; - byte swap input +;; - add sha1 round constant +%macro W_CALC_00_15 2.nolist + %xdefine %%nr %1 + %xdefine %%Wchunk %2 + + vpshufb W, %%Wchunk, YMM_SHUFB + vpaddd %%Wchunk, W, YMM_K + vmovdqa ymmword [F_PTR + (%%nr)*sizeof(dword)*2], %%Wchunk + + ROTATE_W +%endmacro + +;; +;; msg schedulling for other 16-79 sha1 rounds: +;; +%macro W_CALC 1.nolist + %xdefine %%rndw %1 + + %if (%%rndw < 32) + %if ((%%rndw & 3) == 0) ;; scheduling to interleave with ALUs + vpalignr W, W_minus_12, W_minus_16, 8 ;; w[t-14] + vpsrldq WTMP1, W_minus_04, 4 ;; w[t-3] + vpxor W, W, W_minus_16 + vpxor WTMP1, WTMP1, W_minus_08 + %elif ((%%rndw & 3) == 1) + vpxor W, W, WTMP1 + vpsrld WTMP1, W, 31 + vpslldq WTMP2, W, 12 + vpaddd W, W, W + %elif ((%%rndw & 3) == 2) + vpsrld WTMP3, WTMP2, 30 + vpxor W, W, WTMP1 + vpslld WTMP2, WTMP2, 2 + vpxor W, W, WTMP3 + %elif ((%%rndw & 3) == 3) + vpxor W, W, WTMP2 + ;;vpaddd WTMP1, W, ymmword [K_SHA1_PTR] + vpaddd WTMP1, W, YMM_K + vmovdqa ymmword [F_PTR+4*sizeof(ymmword)+((%%rndw & 15)/4)*sizeof(ymmword)],WTMP1 + ROTATE_W + %endif + + %elif (%%rndw < 80) + %if ((%%rndw & 3) == 0) ;; scheduling to interleave with ALUs + vpalignr WTMP1, W_minus_04, W_minus_08, 8 + vpxor W, W, W_minus_28 ;; W == W_minus_32 + %elif ((%%rndw & 3) == 1) + vpxor W, W, W_minus_16 + vpxor W, W, WTMP1 + %elif ((%%rndw & 3) == 2) + vpslld WTMP1, W, 2 + vpsrld W, W, 30 + %elif ((%%rndw & 3) == 3) + vpxor W, WTMP1, W + ;;vpaddd WTMP1, W, ymmword [K_SHA1_PTR] + vpaddd WTMP1, W, YMM_K + vmovdqa ymmword [F_PTR+4*sizeof(ymmword)+((%%rndw & 15)/4)*sizeof(ymmword)],WTMP1 + ROTATE_W + %endif + + %endif +%endmacro + +;; +;; update hash macro +;; +%macro UPDATE_HASH 2.nolist + %xdefine %%hashMem %1 + %xdefine %%hash %2 + + add %%hash, %%hashMem + mov %%hashMem, %%hash +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; textual rotation of HASH arguments +;; +%macro ROTATE_H 0.nolist + %xdefine %%_X hE + %xdefine hE hD + %xdefine hD hC + %xdefine hC hB + %xdefine hB F + %xdefine F hA + %xdefine hA %%_X +%endmacro + +;; +;; SHA1 rounds 0 - 19 +;; on entry: +;; - a, f(), b', c, d, e values +;; where: f() = F(b,c,d) = (b&c) & (~b&d) already pre-computed for this round +;; b' = rotl(b,30) already pre-computed for the next round +;; note: +;; %if nr==19 the f(b,c,d)=b^c^d precomputed +;; +%macro SHA1_ROUND_00_19 1.nolist + %xdefine %%nr %1 + + ;; hE+=W[nr]+K + add hE, dword [F_PTR+((%%nr & 15)/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + +%if (((%%nr+1) & 15) == 0) + add F_PTR, (16/4)*sizeof(ymmword) +%endif + +%if (%%nr < 19) + andn T1,hA,hC ;; ~hB&hC (next round) +%endif + add hE, F ;; hE += F() + rorx T2,hA, 27 ;; hA<<<5 + rorx F, hA, 2 ;; hB<<<30 (next round) +%if (%%nr < 19) + and hA, hB ;; hB&hC (next round) +%endif + add hE, T2 ;; hE += (hA<<<5) +%if (%%nr < 19) + xor hA, T1 ;; F() = (hB&hC)^(~hB&hC) (next round) +%else + xor hA, hB ;; F() = hB^hC^hD next round + xor hA, hC +%endif + + ROTATE_H +%endmacro + +;; +;; SHA1 rounds 20 - 39 +;; on entry: +;; - a, f(), b', c, d, e values +;; where: f() = F(b,c,d) = b^c^d already pre-computed for this round +;; b' = rotl(b,30) already pre-computed for the next round +;; +;; note: +;; %if nr==39 the f(b,c,d)=(b^c)&(c^d) precomputed +;; +%macro SHA1_ROUND_20_39 1.nolist + %xdefine %%nr %1 + + ;; hE+=W[nr]+K + add hE, dword [F_PTR+((%%nr & 15)/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + +%if (((%%nr+1) & 15) == 0) + add F_PTR, (16/4)*sizeof(ymmword) +%endif + + add hE, F ;; hE += F() + rorx T2,hA, 27 ;; hA<<<5 + rorx F, hA, 2 ;; hB<<<30 (next round) + xor hA, hB ;; hB^hC (next round) + add hE, T2 ;; hE += (hA<<<5) +%if (%%nr < 39) + xor hA, hC ;; F() = hB^hC^hD (next round) +%else + mov T1, hB ;; hC^hD (next round) + xor T1, hC ;; + and hA, T1 ;; (hB^hC)&(hC^hD) +%endif + + ROTATE_H +%endmacro + +;; +;; SHA1 rounds 40 - 59 +;; on entry: +;; - a, f(), b', c, d, e values +;; where: f() = (b&c)^(c&d) already pre-computed (part of F()) for this round +;; b' = rotl(b,30) already pre-computed for the next round +;; +;; F(b,c,d) = (b&c)^(b&d)^(c&d) +;; +;; note, using GF(2): arithmetic +;; F(b,c,d) = (b&c)^(b&d)^(c&d) ~ bc+bd+cd +;; =(b+c)(c+d) +c^2 = (b+c)(c+d) +c +;; ~ ((b^c)&(c^d)) ^c +;; direct substitution: +;; (b+c)(c+d) = bc + bd + c^2 + cd, but c^2 = c +;; +%macro SHA1_ROUND_40_59 1.nolist + %xdefine %%nr %1 + + ;; hE+=W[nr]+K + add hE, dword [F_PTR+((%%nr & 15)/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + +%if (((%%nr+1) & 15) == 0) + add F_PTR, (16/4)*sizeof(ymmword) +%endif + + xor F, hC ;; F() = ((b^c)&(c^d)) ^c +%if(%%nr < 59) + mov T1, hB ;; hC^hD (next round) + xor T1, hC ;; +%endif + add hE, F ;; hE += F() + rorx T2,hA, 27 ;; hA<<<5 + rorx F, hA, 2 ;; hB<<<30 (next round) + xor hA, hB ;; hB^hC (next round) + add hE, T2 ;; hE += (hA<<<5) +%if(%%nr < 59) + and hA, T1 ;; (hB^hC)&(hC^hD) (next round) +%else + xor hA, hC ;; (hB^hC^hD) (next round) +%endif + + ROTATE_H +%endmacro + +;; +;; SHA1 rounds 60 - 79 +;; on entry: +;; - a, f(), b', c, d, e values +;; where: f() = F(b,c,d) = b^c^d already pre-computed for this round +;; b' = rotl(b,30) already pre-computed for the next round +;; +%macro SHA1_ROUND_60_79 1.nolist + %xdefine %%nr %1 + + ;; hE+=W[nr]+K + add hE, dword [F_PTR+((%%nr & 15)/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + +%if (((%%nr+1) & 15) == 0) + add F_PTR, (16/4)*sizeof(ymmword) +%endif + + add hE, F ;; hE += F() + rorx T2,hA, 27 ;; hA<<<5 +%if (%%nr < 79) + rorx F, hA, 2 ;; hB<<<30 (next round) + xor hA, hB ;; hB^hC (next round) +%endif + add hE, T2 ;; hE += (hA<<<5) +%if (%%nr < 79) + xor hA, hC ;; F() = hB^hC^hD (next round) +%endif + + ROTATE_H +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +SHA1_YMM_K dd 05a827999h, 05a827999h, 05a827999h, 05a827999h, 05a827999h, 05a827999h, 05a827999h, 05a827999h + dd 06ed9eba1h, 06ed9eba1h, 06ed9eba1h, 06ed9eba1h, 06ed9eba1h, 06ed9eba1h, 06ed9eba1h, 06ed9eba1h + dd 08f1bbcdch, 08f1bbcdch, 08f1bbcdch, 08f1bbcdch, 08f1bbcdch, 08f1bbcdch, 08f1bbcdch, 08f1bbcdch + dd 0ca62c1d6h, 0ca62c1d6h, 0ca62c1d6h, 0ca62c1d6h, 0ca62c1d6h, 0ca62c1d6h, 0ca62c1d6h, 0ca62c1d6h + +SHA1_YMM_BF dd 00010203h,04050607h,08090a0bh,0c0d0e0fh + dd 00010203h,04050607h,08090a0bh,0c0d0e0fh + + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA1(DigestSHA1 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA1,PUBLIC +%assign LOCAL_FRAME (sizeof(dword)*80*2) + USES_GPR rdi,rsi,rbp,rbx,r12,r13,r14,r15 + USES_XMM_AVX xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12 + COMP_ABI 4 + +;; rdi = hash ptr +;; rsi = data block ptr +;; rdx = data length in bytes +;; rcx = dummy + +%xdefine MBS_SHA1 (64) + + mov r15, rsp ; store orifinal rsp + and rsp, -IPP_ALIGN_FACTOR ; 32-byte aligned stack + + movsxd r14, edx ; input length in bytes + + vmovdqa YMM_SHUFB, [rel SHA1_YMM_BF] ; load byte shuffler + + mov hA, dword [rdi] ; load initial hash value + mov F, dword [rdi+sizeof(dword)] + mov hC, dword [rdi+2*sizeof(dword)] + mov hD, dword [rdi+3*sizeof(dword)] + mov hE, dword [rdi+4*sizeof(dword)] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data 2 block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; assignment: +;; - W00,...,W28 are fixed +;; - W_minus_04,...,W_minus_32 are rorarted +;; - W corresponds to W[t] +;; +%xdefine W W00 +%xdefine W_minus_04 W04 +%xdefine W_minus_08 W08 +%xdefine W_minus_12 W12 +%xdefine W_minus_16 W16 +%xdefine W_minus_20 W20 +%xdefine W_minus_24 W24 +%xdefine W_minus_28 W28 +%xdefine W_minus_32 W + +align IPP_ALIGN_FACTOR +.sha1_block2_loop: + lea F_PTR, [rsi+MBS_SHA1] ; next block + + cmp r14, MBS_SHA1 ; %if single block processed + cmovbe F_PTR, rsi ; use the same data block address + + ;; + ;; load data block and merge next data block + ;; + vmovdqa YMM_K, [rel SHA1_YMM_K] ; pre-load sha1 constant + + vmovdqu W28L, xmmword [rsi] ; load data block + vmovdqu W24L, xmmword [rsi+1*sizeof(xmmword)] + vmovdqu W20L, xmmword [rsi+2*sizeof(xmmword)] + vmovdqu W16L, xmmword [rsi+3*sizeof(xmmword)] + + vinserti128 W28, W28, xmmword [F_PTR], 1 ; merge next data block + vinserti128 W24, W24, xmmword [F_PTR+1*sizeof(xmmword)], 1 + vinserti128 W20, W20, xmmword [F_PTR+2*sizeof(xmmword)], 1 + vinserti128 W16, W16, xmmword [F_PTR+3*sizeof(xmmword)], 1 + + mov F_PTR, rsp ;; set local data pointer + + W_CALC_00_15 0, W28 ;; msg scheduling for rounds 00 .. 15 + W_CALC_00_15 4, W24 ;; + W_CALC_00_15 8, W20 ;; msg scheduling for rounds 08 .. 15 + W_CALC_00_15 12, W16 ;; + + rorx hB, F, 2 ;; pre-compute (b<<<30) next round + andn T1,F, hD ;; pre-compute F1(F,hC,hD) = hB&hC ^(~hB&hD) + and F, hC + xor F, T1 + + W_CALC 16 ;; msg schedilling ahead 16 rounds + SHA1_ROUND_00_19 0 ;; sha1 round + + W_CALC 17 + SHA1_ROUND_00_19 1 + + W_CALC 18 + SHA1_ROUND_00_19 2 + + W_CALC 19 + SHA1_ROUND_00_19 3 + + ; pre-load sha1 constant + vmovdqa YMM_K, [rel SHA1_YMM_K+sizeof(ymmword)] + W_CALC 20 + SHA1_ROUND_00_19 4 + + W_CALC 21 + SHA1_ROUND_00_19 5 + + W_CALC 22 + SHA1_ROUND_00_19 6 + + W_CALC 23 + SHA1_ROUND_00_19 7 + + W_CALC 24 + SHA1_ROUND_00_19 8 + + W_CALC 25 + SHA1_ROUND_00_19 9 + + W_CALC 26 + SHA1_ROUND_00_19 10 + + W_CALC 27 + SHA1_ROUND_00_19 11 + + W_CALC 28 + SHA1_ROUND_00_19 12 + + W_CALC 29 + SHA1_ROUND_00_19 13 + + W_CALC 30 + SHA1_ROUND_00_19 14 + + W_CALC 31 + SHA1_ROUND_00_19 15 + + W_CALC 32 + SHA1_ROUND_00_19 16 + + W_CALC 33 + SHA1_ROUND_00_19 17 + + W_CALC 34 + SHA1_ROUND_00_19 18 + + W_CALC 35 + SHA1_ROUND_00_19 19 + + W_CALC 36 + SHA1_ROUND_20_39 20 + + W_CALC 37 + SHA1_ROUND_20_39 21 + + W_CALC 38 + SHA1_ROUND_20_39 22 + + W_CALC 39 + SHA1_ROUND_20_39 23 + + ; pre-load sha1 constant + vmovdqa YMM_K, [rel SHA1_YMM_K+2*sizeof(ymmword)] + W_CALC 40 + SHA1_ROUND_20_39 24 + + W_CALC 41 + SHA1_ROUND_20_39 25 + + W_CALC 42 + SHA1_ROUND_20_39 26 + + W_CALC 43 + SHA1_ROUND_20_39 27 + + W_CALC 44 + SHA1_ROUND_20_39 28 + + W_CALC 45 + SHA1_ROUND_20_39 29 + + W_CALC 46 + SHA1_ROUND_20_39 30 + + W_CALC 47 + SHA1_ROUND_20_39 31 + + W_CALC 48 + SHA1_ROUND_20_39 32 + + W_CALC 49 + SHA1_ROUND_20_39 33 + + W_CALC 50 + SHA1_ROUND_20_39 34 + + W_CALC 51 + SHA1_ROUND_20_39 35 + + W_CALC 52 + SHA1_ROUND_20_39 36 + + W_CALC 53 + SHA1_ROUND_20_39 37 + + W_CALC 54 + SHA1_ROUND_20_39 38 + + W_CALC 55 + SHA1_ROUND_20_39 39 + + W_CALC 56 + SHA1_ROUND_40_59 40 + + W_CALC 57 + SHA1_ROUND_40_59 41 + + W_CALC 58 + SHA1_ROUND_40_59 42 + + W_CALC 59 + SHA1_ROUND_40_59 43 + + ; pre-load sha1 constant + vmovdqa YMM_K, [rel SHA1_YMM_K+3*sizeof(ymmword)] + W_CALC 60 + SHA1_ROUND_40_59 44 + + W_CALC 61 + SHA1_ROUND_40_59 45 + + W_CALC 62 + SHA1_ROUND_40_59 46 + + W_CALC 63 + SHA1_ROUND_40_59 47 + + W_CALC 64 + SHA1_ROUND_40_59 48 + + W_CALC 65 + SHA1_ROUND_40_59 49 + + W_CALC 66 + SHA1_ROUND_40_59 50 + + W_CALC 67 + SHA1_ROUND_40_59 51 + + W_CALC 68 + SHA1_ROUND_40_59 52 + + W_CALC 69 + SHA1_ROUND_40_59 53 + + W_CALC 70 + SHA1_ROUND_40_59 54 + + W_CALC 71 + SHA1_ROUND_40_59 55 + + W_CALC 72 + SHA1_ROUND_40_59 56 + + W_CALC 73 + SHA1_ROUND_40_59 57 + + W_CALC 74 + SHA1_ROUND_40_59 58 + + W_CALC 75 + SHA1_ROUND_40_59 59 + + W_CALC 76 + SHA1_ROUND_60_79 60 + + W_CALC 77 + SHA1_ROUND_60_79 61 + + W_CALC 78 + SHA1_ROUND_60_79 62 + + W_CALC 79 + SHA1_ROUND_60_79 63 + + SHA1_ROUND_60_79 64 + SHA1_ROUND_60_79 65 + SHA1_ROUND_60_79 66 + SHA1_ROUND_60_79 67 + SHA1_ROUND_60_79 68 + SHA1_ROUND_60_79 69 + SHA1_ROUND_60_79 70 + SHA1_ROUND_60_79 71 + SHA1_ROUND_60_79 72 + SHA1_ROUND_60_79 73 + SHA1_ROUND_60_79 74 + SHA1_ROUND_60_79 75 + SHA1_ROUND_60_79 76 + SHA1_ROUND_60_79 77 + SHA1_ROUND_60_79 78 + SHA1_ROUND_60_79 79 + + lea F_PTR, [rsp+sizeof(xmmword)] ;; set local data pointer + + ;; update hash values by 1-st data block + UPDATE_HASH dword [rdi], hA + UPDATE_HASH dword [rdi+4], F + UPDATE_HASH dword [rdi+8], hC + UPDATE_HASH dword [rdi+12],hD + UPDATE_HASH dword [rdi+16],hE + + cmp r14, MBS_SHA1*2 + jl .done + + rorx hB, F, 2 ;; pre-compute (b<<<30) next round + andn T1,F, hD ;; pre-compute F1(F,hC,hD) = hB&hC ^(~hB&hD) + and F, hC + xor F, T1 + + SHA1_ROUND_00_19 0 + SHA1_ROUND_00_19 1 + SHA1_ROUND_00_19 2 + SHA1_ROUND_00_19 3 + SHA1_ROUND_00_19 4 + SHA1_ROUND_00_19 5 + SHA1_ROUND_00_19 6 + SHA1_ROUND_00_19 7 + SHA1_ROUND_00_19 8 + SHA1_ROUND_00_19 9 + SHA1_ROUND_00_19 10 + SHA1_ROUND_00_19 11 + SHA1_ROUND_00_19 12 + SHA1_ROUND_00_19 13 + SHA1_ROUND_00_19 14 + SHA1_ROUND_00_19 15 + SHA1_ROUND_00_19 16 + SHA1_ROUND_00_19 17 + SHA1_ROUND_00_19 18 + SHA1_ROUND_00_19 19 + + SHA1_ROUND_20_39 20 + SHA1_ROUND_20_39 21 + SHA1_ROUND_20_39 22 + SHA1_ROUND_20_39 23 + SHA1_ROUND_20_39 24 + SHA1_ROUND_20_39 25 + SHA1_ROUND_20_39 26 + SHA1_ROUND_20_39 27 + SHA1_ROUND_20_39 28 + SHA1_ROUND_20_39 29 + SHA1_ROUND_20_39 30 + SHA1_ROUND_20_39 31 + SHA1_ROUND_20_39 32 + SHA1_ROUND_20_39 33 + SHA1_ROUND_20_39 34 + SHA1_ROUND_20_39 35 + SHA1_ROUND_20_39 36 + SHA1_ROUND_20_39 37 + SHA1_ROUND_20_39 38 + SHA1_ROUND_20_39 39 + + SHA1_ROUND_40_59 40 + SHA1_ROUND_40_59 41 + SHA1_ROUND_40_59 42 + SHA1_ROUND_40_59 43 + SHA1_ROUND_40_59 44 + SHA1_ROUND_40_59 45 + SHA1_ROUND_40_59 46 + SHA1_ROUND_40_59 47 + SHA1_ROUND_40_59 48 + SHA1_ROUND_40_59 49 + SHA1_ROUND_40_59 50 + SHA1_ROUND_40_59 51 + SHA1_ROUND_40_59 52 + SHA1_ROUND_40_59 53 + SHA1_ROUND_40_59 54 + SHA1_ROUND_40_59 55 + SHA1_ROUND_40_59 56 + SHA1_ROUND_40_59 57 + SHA1_ROUND_40_59 58 + SHA1_ROUND_40_59 59 + + SHA1_ROUND_60_79 60 + SHA1_ROUND_60_79 61 + SHA1_ROUND_60_79 62 + SHA1_ROUND_60_79 63 + SHA1_ROUND_60_79 64 + SHA1_ROUND_60_79 65 + SHA1_ROUND_60_79 66 + SHA1_ROUND_60_79 67 + SHA1_ROUND_60_79 68 + SHA1_ROUND_60_79 69 + SHA1_ROUND_60_79 70 + SHA1_ROUND_60_79 71 + SHA1_ROUND_60_79 72 + SHA1_ROUND_60_79 73 + SHA1_ROUND_60_79 74 + SHA1_ROUND_60_79 75 + SHA1_ROUND_60_79 76 + SHA1_ROUND_60_79 77 + SHA1_ROUND_60_79 78 + SHA1_ROUND_60_79 79 + + ;; update hash values by 2-nd data block + UPDATE_HASH dword [rdi], hA + UPDATE_HASH dword [rdi+4], F + UPDATE_HASH dword [rdi+8], hC + UPDATE_HASH dword [rdi+12],hD + UPDATE_HASH dword [rdi+16],hE + + ;; unfortunately 2*80%6 != 0 + ;; and so need to re-order hA,F,hB,hC,hD,hE values + ;; to match the code generated for 1-st block processing + mov hB, hD ; re-order data physically + mov hD, hA + mov T1, hE + mov hE, F + mov F, hC + mov hC, T1 + + ROTATE_H ; re-order data logically + ROTATE_H ; twice, because 6 -(2*80%6) = 2 + + add rsi, MBS_SHA1*2 + sub r14, MBS_SHA1*2 + jg .sha1_block2_loop + +.done: + mov rsp, r15 + REST_XMM_AVX + REST_GPR + ret +ENDFUNC UpdateSHA1 + +%endif ;; _IPP32E >= _IPP32E_L9 +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA1_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1m7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1m7as.asm new file mode 100644 index 000000000..2a003e990 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1m7as.asm @@ -0,0 +1,503 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA1 +; +; Content: +; UpdateSHA1 +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA1_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_M7) && (_IPP32E < _IPP32E_U8 ) + + +;; +;; Magic functions defined in FIPS 180-1 +;; +%macro MAGIC_F0 4-5.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regT %5 + + mov %%regF,%%regC + xor %%regF,%%regD + and %%regF,%%regB + xor %%regF,%%regD +%endmacro + +%macro MAGIC_F1 4-5.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regT %5 + + mov %%regF,%%regD + xor %%regF,%%regC + xor %%regF,%%regB +%endmacro + +%macro MAGIC_F2 5.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regT %5 + + mov %%regF,%%regB + mov %%regT,%%regB + or %%regF,%%regC + and %%regT,%%regC + and %%regF,%%regD + or %%regF,%%regT +%endmacro + +%macro MAGIC_F3 4-5.nolist + %xdefine %%regF %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regT %5 + + MAGIC_F1 {%%regF},{%%regB},{%%regC},{%%regD},{%%regT} +%endmacro + +;; +;; single SHA1 step +;; +;; Ipp32u tmp = ROL(A,5) + MAGIC_Fi(B,C,D) + E + W[t] + CNT[i]; +;; E = D; +;; D = C; +;; C = ROL(B,30); +;; B = A; +;; A = tmp; +;; +%macro SHA1_STEP 10.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%memW %8 + %xdefine %%immCNT %9 + %xdefine %%MAGIC %10 + + add %%regE,%%immCNT + add %%regE,[%%memW] + mov %%regT,%%regA + rol %%regT,5 + add %%regE,%%regT + %%MAGIC %%regF,%%regB,%%regC,%%regD,%%regT ;; FUN = MAGIC_Fi(B,C,D) + rol %%regB,30 + add %%regE,%%regF +%endmacro + +%macro SHA1_RND0 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %assign %%immCNT 05A827999h + mov r13d,%%immCNT + MAGIC_F0 %%regF,%%regB,%%regC,%%regD ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[rsp+(((%%nr) & 0Fh)*4)] +; lea regE,[regE+regF+immCNT] ; substituted with 2 adds because of gnu as bug + add r13d, %%regF + add %%regE, r13d + add %%regE,%%regT +%endmacro + +%macro SHA1_RND1 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %assign %%immCNT 06ED9EBA1h + mov r13d,%%immCNT + MAGIC_F1 {%%regF},{%%regB},{%%regC},{%%regD} ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[rsp+(((%%nr) & 0Fh)*4)] +; lea regE,[regE+regF+immCNT] ; substituted with 2 adds because of gnu as bug + add r13d, %%regF + add %%regE, r13d + add %%regE,%%regT +%endmacro + +%macro SHA1_RND2 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %ifndef _VXWORKS + %assign %%immCNT 08F1BBCDCh + %else + %assign %%immCNT -1894007588 + %endif + mov r13d,%%immCNT + MAGIC_F2 %%regF,%%regB,%%regC,%%regD,%%regT ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[rsp+(((%%nr) & 0Fh)*4)] +; lea regE,[regE+regF+immCNT] ; substituted with 2 adds because of gnu as bug + add r13d, %%regF + add %%regE, r13d + add %%regE,%%regT +%endmacro + +%macro SHA1_RND3 8.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regT %6 + %xdefine %%regF %7 + %xdefine %%nr %8 + + %ifndef _VXWORKS + %assign %%immCNT 0CA62C1D6h + %else + %assign %%immCNT -899497514 + %endif + mov r13d,%%immCNT + MAGIC_F3 {%%regF},{%%regB},{%%regC},{%%regD} ;; FUN = MAGIC_Fi(B,C,D) + ror %%regB,(32-30) + mov %%regT,%%regA + rol %%regT,5 + add %%regE,[rsp+(((%%nr) & 0Fh)*4)] +; lea regE,[regE+regF+immCNT] ; substituted with 2 adds because of gnu as bug + add r13d, %%regF + add %%regE, r13d + add %%regE,%%regT +%endmacro + +;; +;; ENDIANNESS +;; +%macro ENDIANNESS 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + %ifnidn %%dst,%%src + mov %%dst,%%src + %endif + bswap %%dst +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Following Macros are especially for new implementation of SHA1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%macro UPDATE 2-3.nolist + %xdefine %%nr %1 + %xdefine %%regU %2 + %xdefine %%regT %3 + + %ifempty %%regT + mov %%regU,[rsp+((%%nr-16) & 0Fh)*4] + xor %%regU,[rsp+((%%nr-14) & 0Fh)*4] + xor %%regU,[rsp+((%%nr-8) & 0Fh)*4] + xor %%regU,[rsp+((%%nr-3) & 0Fh)*4] + %else + mov %%regU,[rsp+((%%nr-16) & 0Fh)*4] + mov %%regT,[rsp+((%%nr-14) & 0Fh)*4] + xor %%regU,%%regT + mov %%regT,[rsp+((%%nr-8) & 0Fh)*4] + xor %%regU,%%regT + mov %%regT,[rsp+((%%nr-3) & 0Fh)*4] + xor %%regU,%%regT + %endif + rol %%regU,1 + mov [rsp+(%%nr & 0Fh)*4],%%regU +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA1(DigestSHA1 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +;; +;; Lib = M7 +;; +;; Caller = ippsSHA1Update +;; Caller = ippsSHA1Final +;; Caller = ippsSHA1MessageDigest +;; +;; Caller = ippsHMACSHA1Update +;; Caller = ippsHMACSHA1Final +;; Caller = ippsHMACSHA1MessageDigest +;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA1,PUBLIC +%assign LOCAL_FRAME 16*4 + USES_GPR rbx,rsi,rdi,r8,r9,r10,r11,r12,r13 + USES_XMM + COMP_ABI 4 + +%xdefine MBS_SHA1 (64) + + movsxd rdx, edx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + +;; +;; init A, B, C, D, E by the internal digest +;; + mov r8d, [rdi+0*4] ; r8d = digest[0] (A) + mov r9d, [rdi+1*4] ; r9d = digest[1] (B) + mov r10d,[rdi+2*4] ; r10d= digest[2] (C) + mov r11d,[rdi+3*4] ; r11d= digest[3] (D) + mov r12d,[rdi+4*4] ; r12d= digest[4] (E) + +;; +;; initialize the first 16 words in the array W (remember about endian) +;; + xor rcx,rcx +.loop1: + mov eax,[rsi+rcx*4+0*4] + ENDIANNESS eax,eax + mov [rsp+rcx*4+0*4],eax + + mov ebx,[rsi+rcx*4+1*4] + ENDIANNESS ebx,ebx + mov [rsp+rcx*4+1*4],ebx + + add rcx,2 + cmp rcx,16 + jl .loop1 + +;; +;; perform 0-79 steps +;; +;; A, B, C, D, E, TMP,FUN, round +;; ----------------------------------- + SHA1_RND0 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 0 + UPDATE 16, eax + SHA1_RND0 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 1 + UPDATE 17, eax + SHA1_RND0 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 2 + UPDATE 18, eax + SHA1_RND0 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 3 + UPDATE 19, eax + SHA1_RND0 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 4 + UPDATE 20, eax + SHA1_RND0 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 5 + UPDATE 21, eax + SHA1_RND0 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 6 + UPDATE 22, eax + SHA1_RND0 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 7 + UPDATE 23, eax + SHA1_RND0 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 8 + UPDATE 24, eax + SHA1_RND0 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 9 + UPDATE 25, eax + SHA1_RND0 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 10 + UPDATE 26, eax + SHA1_RND0 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 11 + UPDATE 27, eax + SHA1_RND0 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 12 + UPDATE 28, eax + SHA1_RND0 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 13 + UPDATE 29, eax + SHA1_RND0 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 14 + UPDATE 30, eax + SHA1_RND0 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 15 + UPDATE 31, eax + SHA1_RND0 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 16 + UPDATE 32, eax + SHA1_RND0 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 17 + UPDATE 33, eax + SHA1_RND0 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 18 + UPDATE 34, eax + SHA1_RND0 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 19 + UPDATE 35, eax + + SHA1_RND1 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 20 + UPDATE 36, eax + SHA1_RND1 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 21 + UPDATE 37, eax + SHA1_RND1 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 22 + UPDATE 38, eax + SHA1_RND1 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 23 + UPDATE 39, eax + SHA1_RND1 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 24 + UPDATE 40, eax + SHA1_RND1 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 25 + UPDATE 41, eax + SHA1_RND1 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 26 + UPDATE 42, eax + SHA1_RND1 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 27 + UPDATE 43, eax + SHA1_RND1 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 28 + UPDATE 44, eax + SHA1_RND1 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 29 + UPDATE 45, eax + SHA1_RND1 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 30 + UPDATE 46, eax + SHA1_RND1 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 31 + UPDATE 47, eax + SHA1_RND1 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 32 + UPDATE 48, eax + SHA1_RND1 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 33 + UPDATE 49, eax + SHA1_RND1 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 34 + UPDATE 50, eax + SHA1_RND1 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 35 + UPDATE 51, eax + SHA1_RND1 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 36 + UPDATE 52, eax + SHA1_RND1 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 37 + UPDATE 53, eax + SHA1_RND1 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 38 + UPDATE 54, eax + SHA1_RND1 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 39 + UPDATE 55, eax + + SHA1_RND2 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 40 + UPDATE 56, eax + SHA1_RND2 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 41 + UPDATE 57, eax + SHA1_RND2 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 42 + UPDATE 58, eax + SHA1_RND2 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 43 + UPDATE 59, eax + SHA1_RND2 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 44 + UPDATE 60, eax + SHA1_RND2 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 45 + UPDATE 61, eax + SHA1_RND2 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 46 + UPDATE 62, eax + SHA1_RND2 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 47 + UPDATE 63, eax + SHA1_RND2 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 48 + UPDATE 64, eax + SHA1_RND2 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 49 + UPDATE 65, eax + SHA1_RND2 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 50 + UPDATE 66, eax + SHA1_RND2 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 51 + UPDATE 67, eax + SHA1_RND2 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 52 + UPDATE 68, eax + SHA1_RND2 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 53 + UPDATE 69, eax + SHA1_RND2 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 54 + UPDATE 70, eax + SHA1_RND2 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 55 + UPDATE 71, eax + SHA1_RND2 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 56 + UPDATE 72, eax + SHA1_RND2 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 57 + UPDATE 73, eax + SHA1_RND2 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 58 + UPDATE 74, eax + SHA1_RND2 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 59 + UPDATE 75, eax + + SHA1_RND3 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 60 + UPDATE 76, eax + SHA1_RND3 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 61 + UPDATE 77, eax + SHA1_RND3 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 62 + UPDATE 78, eax + SHA1_RND3 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 63 + UPDATE 79, eax + SHA1_RND3 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 64 + SHA1_RND3 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 65 + SHA1_RND3 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 66 + SHA1_RND3 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 67 + SHA1_RND3 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 68 + SHA1_RND3 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 69 + SHA1_RND3 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 70 + SHA1_RND3 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 71 + SHA1_RND3 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 72 + SHA1_RND3 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 73 + SHA1_RND3 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 74 + SHA1_RND3 r8d,r9d,r10d,r11d,r12d, ecx,ebx, 75 + SHA1_RND3 r12d,r8d,r9d,r10d,r11d, ecx,ebx, 76 + SHA1_RND3 r11d,r12d,r8d,r9d,r10d, ecx,ebx, 77 + SHA1_RND3 r10d,r11d,r12d,r8d,r9d, ecx,ebx, 78 + SHA1_RND3 r9d,r10d,r11d,r12d,r8d, ecx,ebx, 79 + +;; +;; update digest +;; + add [rdi+0*4],r8d ; advance digest + add [rdi+1*4],r9d + add [rdi+2*4],r10d + add [rdi+3*4],r11d + add [rdi+4*4],r12d + + add rsi, MBS_SHA1 + sub rdx, MBS_SHA1 + jg .sha1_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA1 + +%endif ;; (_IPP32E >= _IPP32E_M7) AND (_IPP32E < _IPP32E_U8 ) +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA1_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1nias.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1nias.asm new file mode 100644 index 000000000..8ed02fa3c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1nias.asm @@ -0,0 +1,549 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA-1 +; +; Content: +; UpdateSHA1ni +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA1_) +%if (_SHA_NI_ENABLING_ == _FEATURE_ON_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +;;%if (_IPP32E >= _IPP32E_Y8 ) + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +UPPER_DWORD_MASK \ + DQ 00000000000000000h, 0ffffffff00000000h +PSHUFFLE_BYTE_FLIP_MASK \ + DB 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +align IPP_ALIGN_FACTOR +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA1ni(DigestSHA1 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +%ifndef _VXWORKS + +IPPASM UpdateSHA1ni,PUBLIC +%assign LOCAL_FRAME 16*2 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7 + COMP_ABI 4 + +%xdefine MBS_SHA1 (64) ; SHA-1 message block length (bytes) + +%xdefine HASH_PTR rdi ; 1st arg +%xdefine MSG_PTR rsi ; 2nd arg +%xdefine MSG_LEN rdx ; 3rd arg + +%xdefine ABCD xmm0 +%xdefine E0 xmm1 ; Need two E's b/c they ping pong +%xdefine E1 xmm2 +%xdefine MSG0 xmm3 +%xdefine MSG1 xmm4 +%xdefine MSG2 xmm5 +%xdefine MSG3 xmm6 +%xdefine SHUF_MASK xmm7 + +; +; stack frame +; +%xdefine abcd_save rsp +%xdefine e_save rsp+16 + + movsxd MSG_LEN, edx ; expand mLen + test MSG_LEN, MSG_LEN + jz .quit + +;; load initial hash values + movdqu ABCD, oword [HASH_PTR] + pinsrd E0, dword [HASH_PTR+16], 3 + pand E0, oword [rel UPPER_DWORD_MASK] + pshufd ABCD, ABCD, 01Bh + + movdqa SHUF_MASK, oword [rel PSHUFFLE_BYTE_FLIP_MASK] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + movdqa oword [abcd_save], ABCD + movdqa oword [e_save], E0 + + ;; rounds 0-3 + movdqu MSG0, oword [MSG_PTR +0*16] + pshufb MSG0, SHUF_MASK + paddd E0, MSG0 + movdqa E1, ABCD + sha1rnds4 ABCD, E0, 0 + ;movdqu oword [rcx+16*0], ABCD + + ;; rounds 4-7 + movdqu MSG1, oword [MSG_PTR +1*16] + pshufb MSG1, SHUF_MASK + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1rnds4 ABCD, E1, 0 + sha1msg1 MSG0, MSG1 + ;movdqu oword [rcx+16*1], ABCD + + ;; rounds 8-11 + movdqu MSG2, oword [MSG_PTR +2*16] + pshufb MSG2, SHUF_MASK + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1rnds4 ABCD, E0, 0 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*2], ABCD + + ;; rounds 12-15 + movdqu MSG3, oword [MSG_PTR +3*16] + pshufb MSG3, SHUF_MASK + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 0 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*3], ABCD + + ;; rounds 16-19 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 0 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*4], ABCD + + ;; rounds 20-23 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 1 + sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*5], ABCD + + ;; rounds 24-27 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 1 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*6], ABCD + + ;; rounds 28-31 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 1 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*7], ABCD + + ;; rounds 32-35 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 1 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*8], ABCD + + ;; rounds 36-39 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 1 + sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*9], ABCD + + ;; rounds 40-43 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 2 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*10], ABCD + + ;; rounds 44-47 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 2 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*11], ABCD + + ;; rounds 48-51 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 2 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*12], ABCD + + ;; rounds 52-55 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 2 + sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*13], ABCD + + ;; rounds 56-59 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 2 + sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*14], ABCD + + ;; rounds 60-63 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1msg2 MSG0, MSG3 + sha1rnds4 ABCD, E1, 3 + sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*15], ABCD + + ;; rounds 64-67 + sha1nexte E0, MSG0 + movdqa E1, ABCD + sha1msg2 MSG1, MSG0 + sha1rnds4 ABCD, E0, 3 + sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*16], ABCD + + ;; rounds 68-71 + sha1nexte E1, MSG1 + movdqa E0, ABCD + sha1msg2 MSG2, MSG1 + sha1rnds4 ABCD, E1, 3 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*17], ABCD + + ;; rounds 72-75 + sha1nexte E0, MSG2 + movdqa E1, ABCD + sha1msg2 MSG3, MSG2 + sha1rnds4 ABCD, E0, 3 + ;movdqu oword [rcx+16*18], ABCD + + ;; rounds 76-79 + sha1nexte E1, MSG3 + movdqa E0, ABCD + sha1rnds4 ABCD, E1, 3 + ;movdqu oword [rcx+16*19], ABCD + + ;; add current hash values with previously saved + sha1nexte E0, oword [e_save] + paddd ABCD, oword [abcd_save] + + add MSG_PTR, MBS_SHA1 + sub MSG_LEN, MBS_SHA1 + jg .sha1_block_loop + + ;; write hash values back in the correct order + pshufd ABCD, ABCD, 01Bh + movdqu oword [HASH_PTR], ABCD + pextrd dword [HASH_PTR+16], E0, 3 + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA1ni + +%else ;; no sha ni support in VxWorks - therefore we temporary use db +IPPASM UpdateSHA1ni,PUBLIC +%assign LOCAL_FRAME 16*2 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7 + COMP_ABI 4 + +%xdefine MBS_SHA1 (64) ; SHA-1 message block length (bytes) + +%xdefine HASH_PTR rdi ; 1st arg +%xdefine MSG_PTR rsi ; 2nd arg +%xdefine MSG_LEN rdx ; 3rd arg + +%xdefine ABCD xmm0 +%xdefine E0 xmm1 ; Need two E's b/c they ping pong +%xdefine E1 xmm2 +%xdefine MSG0 xmm3 +%xdefine MSG1 xmm4 +%xdefine MSG2 xmm5 +%xdefine MSG3 xmm6 +%xdefine SHUF_MASK xmm7 + +; +; stack frame +; +%xdefine abcd_save rsp +%xdefine e_save rsp+16 + + movsxd MSG_LEN, edx ; expand mLen + test MSG_LEN, MSG_LEN + jz .quit + +;; load initial hash values + movdqu ABCD, oword [HASH_PTR] + pinsrd E0, dword [HASH_PTR+16], 3 + pand E0, oword [rel UPPER_DWORD_MASK] + pshufd ABCD, ABCD, 01Bh + + movdqa SHUF_MASK, oword [rel PSHUFFLE_BYTE_FLIP_MASK] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + movdqa oword [abcd_save], ABCD + movdqa oword [e_save], E0 + + ;; rounds 0-3 + movdqu MSG0, oword [MSG_PTR +0*16] + pshufb MSG0, SHUF_MASK + paddd E0, MSG0 + movdqa E1, ABCD + db 0FH,3AH,0CCH,0C1H,00H ;;sha1rnds4 ABCD, E0, 0 + ;movdqu oword [rcx+16*0], ABCD + + ;; rounds 4-7 + movdqu MSG1, oword [MSG_PTR +1*16] + pshufb MSG1, SHUF_MASK + db 0FH,38H,0C8H,0D4H ;;sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,3AH,0CCH,0C2H,00H ;;sha1rnds4 ABCD, E1, 0 + db 0FH,38H,0C9H,0DCH ;;sha1msg1 MSG0, MSG1 + ;movdqu oword [rcx+16*1], ABCD + + ;; rounds 8-11 + movdqu MSG2, oword [MSG_PTR +2*16] + pshufb MSG2, SHUF_MASK + db 0FH,38H,0C8H,0CDH ;;sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0Fh,3Ah,0CCh,0C1h,00h ;;sha1rnds4 ABCD, E0, 0 + db 0Fh,38h,0C9h,0E5h ;;sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*2], ABCD + + ;; rounds 12-15 + movdqu MSG3, oword [MSG_PTR +3*16] + pshufb MSG3, SHUF_MASK + db 0Fh,38H,0C8h,0D6h ;;sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0Fh,38H,0CAh,0DEh ;;sha1msg2 MSG0, MSG3 + db 0Fh,3AH,0CCh,0C2h,00h ;;sha1rnds4 ABCD, E1, 0 + db 0Fh,38H,0C9h,0EEh ;;sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*3], ABCD + + ;; rounds 16-19 + db 0Fh,38H,0C8h,0CBh ;;sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0Fh,38H,0CAh,0E3h ;;sha1msg2 MSG1, MSG0 + db 0Fh,3AH,0CCh,0C1h,00h ;;sha1rnds4 ABCD, E0, 0 + db 0Fh,38H,0C9h,0F3h ;;sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*4], ABCD + + ;; rounds 20-23 + db 0FH,38H,0C8h,0D4h ;;sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,38H,0CAh,0ECH ;;sha1msg2 MSG2, MSG1 + db 0FH,3AH,0CCH,0C2H,01H ;;sha1rnds4 ABCD, E1, 1 + db 0FH,38H,0C9h,0DCh ;;sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*5], ABCD + + ;; rounds 24-27 + db 0FH,38H,0C8h,0CDh ;;sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0FH,38H,0CAh,0F5h ;;sha1msg2 MSG3, MSG2 + db 0FH,3AH,0CCh,0C1h,01h ;;sha1rnds4 ABCD, E0, 1 + db 0FH,38H,0C9h,0E5h ;;sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*6], ABCD + + ;; rounds 28-31 + db 0FH,38H,0C8H,0D6h ;;sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0FH,38H,0CAH,0DEh ;;sha1msg2 MSG0, MSG3 + db 0FH,3AH,0CCH,0C2H,01h ;;sha1rnds4 ABCD, E1, 1 + db 0FH,38H,0C9H,0EEh ;;sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*7], ABCD + + ;; rounds 32-35 + db 0FH,38H,0C8H,0CBh ;;sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0FH,38H,0CAH,0E3h ;;sha1msg2 MSG1, MSG0 + db 0FH,3AH,0CCH,0C1H,01h ;;sha1rnds4 ABCD, E0, 1 + db 0FH,38H,0C9H,0F3h ;;sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*8], ABCD + + ;; rounds 36-39 + db 0FH,38H,0C8H,0D4h ;;sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0FH,38H,0CAH,0ECh ;;sha1msg2 MSG2, MSG1 + db 0FH,3AH,0CCH,0C2H,01h ;;sha1rnds4 ABCD, E1, 1 + db 0FH,38H,0C9H,0DCh ;;sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*9], ABCD + + ;; rounds 40-43 + db 0FH,38H,0C8H,0CDh ;;sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0FH,38H,0CAH,0F5h ;;sha1msg2 MSG3, MSG2 + db 0FH,3AH,0CCH,0C1H,02h ;;sha1rnds4 ABCD, E0, 2 + db 0FH,38H,0C9H,0E5h ;;sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*10], ABCD + + ;; rounds 44-47 + db 0FH,38H,0C8H,0D6h ;;sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0FH,38H,0CAH,0DEh ;;sha1msg2 MSG0, MSG3 + db 0FH,3AH,0CCH,0C2h,02h ;;sha1rnds4 ABCD, E1, 2 + db 0FH,38H,0C9H,0EEh ;;sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*11], ABCD + + ;; rounds 48-51 + db 0Fh,38H,0C8h,0CBh ;;sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0Fh,38H,0CAH,0E3h ;;sha1msg2 MSG1, MSG0 + db 0Fh,3AH,0CCH,0C1H,02h ;;sha1rnds4 ABCD, E0, 2 + db 0Fh,38H,0C9H,0F3h ;;sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*12], ABCD + + ;; rounds 52-55 + db 0Fh,38H,0C8h,0D4h ;;sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0Fh,38H,0CAH,0ECh ;;sha1msg2 MSG2, MSG1 + db 0Fh,3AH,0CCH,0C2H,02h ;;sha1rnds4 ABCD, E1, 2 + db 0Fh,38H,0C9H,0DCh ;;sha1msg1 MSG0, MSG1 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*13], ABCD + + ;; rounds 56-59 + db 0Fh,38H,0C8H,0CDh ;;sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0Fh,38H,0CAH,0F5h ;;sha1msg2 MSG3, MSG2 + db 0Fh,3AH,0CCH,0C1H,02h ;;sha1rnds4 ABCD, E0, 2 + db 0Fh,38H,0C9H,0E5h ;;sha1msg1 MSG1, MSG2 + pxor MSG0, MSG2 + ;movdqu oword [rcx+16*14], ABCD + + ;; rounds 60-63 + db 0Fh,38H,0C8H,0D6h ;;sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0Fh,38H,0CAH,0DEh ;;sha1msg2 MSG0, MSG3 + db 0Fh,3AH,0CCH,0C2H,03h ;;sha1rnds4 ABCD, E1, 3 + db 0Fh,38H,0C9H,0EEh ;;sha1msg1 MSG2, MSG3 + pxor MSG1, MSG3 + ;movdqu oword [rcx+16*15], ABCD + + ;; rounds 64-67 + db 0Fh,38H,0C8H,0CBh ;;sha1nexte E0, MSG0 + movdqa E1, ABCD + db 0Fh,38H,0CAH,0E3h ;;sha1msg2 MSG1, MSG0 + db 0Fh,3AH,0CCH,0C1H,03h ;;sha1rnds4 ABCD, E0, 3 + db 0Fh,38H,0C9H,0F3h ;;sha1msg1 MSG3, MSG0 + pxor MSG2, MSG0 + ;movdqu oword [rcx+16*16], ABCD + + ;; rounds 68-71 + db 0Fh,38H,0C8h,0D4h ;;sha1nexte E1, MSG1 + movdqa E0, ABCD + db 0Fh,38H,0CAh,0ECh ;;sha1msg2 MSG2, MSG1 + db 0Fh,3AH,0CCh,0C2h,03h ;;sha1rnds4 ABCD, E1, 3 + pxor MSG3, MSG1 + ;movdqu oword [rcx+16*17], ABCD + + ;; rounds 72-75 + db 0Fh,38H,0C8h,0CDh ;;sha1nexte E0, MSG2 + movdqa E1, ABCD + db 0Fh,38H,0CAh,0F5h ;;sha1msg2 MSG3, MSG2 + db 0Fh,3AH,0CCh,0C1h,03h ;;sha1rnds4 ABCD, E0, 3 + ;movdqu oword [rcx+16*18], ABCD + + ;; rounds 76-79 + db 0Fh,38H,0C8h,0D6h ;;sha1nexte E1, MSG3 + movdqa E0, ABCD + db 0Fh,3AH,0CCh,0C2h,03h ;;sha1rnds4 ABCD, E1, 3 + ;movdqu oword [rcx+16*19], ABCD + + ;; add current hash values with previously saved + db 0Fh,38H,0C8h,4Ch,24h,10h ;;sha1nexte E0, oword [e_save] + paddd ABCD, oword [abcd_save] + + add MSG_PTR, MBS_SHA1 + sub MSG_LEN, MBS_SHA1 + jg .sha1_block_loop + + ;; write hash values back in the correct order + pshufd ABCD, ABCD, 01Bh + movdqu oword [HASH_PTR], ABCD + pextrd dword [HASH_PTR+16], E0, 3 + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA1ni + +%endif ;; VxWorks + +;;%endif ;; (_IPP32E >= _IPP32E_Y8) +%endif ;; _FEATURE_ON_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA1_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1u8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1u8as.asm new file mode 100644 index 000000000..014f14563 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha1u8as.asm @@ -0,0 +1,518 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA1 +; +; Content: +; UpdateSHA1 +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA1_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if ((_IPP32E >= _IPP32E_U8 ) && (_IPP32E < _IPP32E_E9 )) || (_IPP32E == _IPP32E_N8 ) + +;; +;; SHA1 constants K[i] +%xdefine SHA1_K1 (05a827999h) +%xdefine SHA1_K2 (06ed9eba1h) +%xdefine SHA1_K3 (08f1bbcdch) +%xdefine SHA1_K4 (0ca62c1d6h) + +;; +;; Magic functions defined in FIPS 180-1 +;; +;; F1, F2, F3 and F4 assumes, that +;; - T1 returns function value +;; - T2 is the temporary +;; + +%macro F1 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + mov T1,%%C + xor T1,%%D + and T1,%%B + xor T1,%%D +%endmacro + +%macro F2 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + mov T1,%%D + xor T1,%%C + xor T1,%%B +%endmacro + +%macro F3 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + mov T1,%%C + mov T2,%%B + or T1,%%B + and T2,%%C + and T1,%%D + or T1,T2 +%endmacro + +%macro F4 3.nolist + %xdefine %%B %1 + %xdefine %%C %2 + %xdefine %%D %3 + + F2 %%B,%%C,%%D +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; rotations +;; + +%macro ROL_5 1.nolist + %xdefine %%x %1 + + rol %%x, 5 +%endmacro + +%macro ROL_30 1.nolist + %xdefine %%x %1 + + rol %%x, 30 +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; textual rotation of W array +;; +%macro ROTATE_W 0.nolist + %xdefine W_minus_32 W_minus_28 + %xdefine W_minus_28 W_minus_24 + %xdefine W_minus_24 W_minus_20 + %xdefine W_minus_20 W_minus_16 + %xdefine W_minus_16 W_minus_12 + %xdefine W_minus_12 W_minus_08 + %xdefine W_minus_08 W_minus_04 + %xdefine W_minus_04 W + %xdefine W W_minus_32 +%endmacro + +;; +;; SHA1 update round: +;; - F1 magic is used (and imbedded into the macros directly) +;; - 16 bytes of input are swapped +;; +%macro SHA1_UPDATE_RND_F1_BSWAP 7.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%nr %6 + %xdefine %%Wchunk %7 + + pshufb %%Wchunk, XMM_SHUFB_BSWAP + movdqa W, %%Wchunk + paddd %%Wchunk, oword [K_XMM] + movdqa oword [rsp + (%%nr & 15)*4], %%Wchunk + mov T1,%%C ; F1 + mov T2,%%A + xor T1,%%D ; F1 + and T1,%%B ; F1 + ROL_5 T2 + xor T1,%%D ; F1 + add %%E, T2 + ROL_30 %%B + add T1, dword [rsp + (%%nr & 15)*4] + add %%E,T1 + + ROTATE_W +%endmacro + +;; +;; SHA1 update round: +;; - F1 magic is used (and imbedded into the macros directly) +;; +%macro SHA1_UPDATE_RND_F1 6.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%nr %6 + + mov T1,%%C ; F1 + mov T2,%%A + xor T1,%%D ; F1 + ROL_5 T2 + and T1,%%B ; F1 + xor T1,%%D ; F1 + add %%E, T2 + ROL_30 %%B + add T1, dword [rsp + (%%nr & 15)*4] + add %%E,T1 +%endmacro + +;; +;; update W +;; +%macro W_CALC 1.nolist + %xdefine %%nr %1 + + %assign %%W_CALC_ahead 8 + + %assign %%i (%%nr + %%W_CALC_ahead) + + %if (%%i < 20) + %xdefine K_XMM K_BASE + %elif (%%i < 40) + %xdefine K_XMM K_BASE+16 + %elif (%%i < 60) + %xdefine K_XMM K_BASE+32 + %else + %xdefine K_XMM K_BASE+48 + %endif + + %if (%%i < 32) + %if ((%%i & 3) == 0) ;; just scheduling to interleave with ALUs + movdqa W, W_minus_12 + palignr W, W_minus_16, 8 ; w[i-14] + + movdqa W_TMP, W_minus_04 + psrldq W_TMP, 4 ; w[i-3] + + pxor W, W_minus_08 + %elif ((%%i & 3) == 1) + pxor W_TMP, W_minus_16 + pxor W, W_TMP + + movdqa W_TMP2, W + movdqa W_TMP, W + pslldq W_TMP2, 12 + %elif ((%%i & 3) == 2) + psrld W, 31 + pslld W_TMP, 1 + por W_TMP, W + + movdqa W, W_TMP2 + psrld W_TMP2, 30 + pslld W, 2 + %elif ((%%i & 3) == 3) + pxor W_TMP, W + pxor W_TMP, W_TMP2 + movdqa W, W_TMP + + paddd W_TMP, oword [K_XMM] + movdqa oword [rsp + ((%%i & (~3)) & 15)*4],W_TMP + + ROTATE_W + %endif + + %elif (%%i < 83) + %if ((%%i & 3) == 0) ;; scheduling to interleave with ALUs + movdqa W_TMP, W_minus_04 + pxor W, W_minus_28 ;; W == W_minus_32 + palignr W_TMP, W_minus_08, 8 + %elif ((%%i & 3) == 1) + pxor W, W_minus_16 + pxor W, W_TMP + movdqa W_TMP, W + %elif ((%%i & 3) == 2) + psrld W, 30 + pslld W_TMP, 2 + por W_TMP, W + %elif ((%%i & 3) == 3) + movdqa W, W_TMP + paddd W_TMP, oword [K_XMM] + movdqa oword [rsp + ((%%i & (~3)) & 15)*4],W_TMP + + ROTATE_W + %endif + + %endif +%endmacro + +;; +;; Regular hash update +;; +%macro SHA1_UPDATE_REGULAR 7.nolist + %xdefine %%A %1 + %xdefine %%B %2 + %xdefine %%C %3 + %xdefine %%D %4 + %xdefine %%E %5 + %xdefine %%nr %6 + %xdefine %%MagiF %7 + + W_CALC %%nr + + add %%E, dword [rsp + (%%nr & 15)*4] + %%MagiF %%B,%%C,%%D + add %%D, dword [rsp +((%%nr+1) & 15)*4] + ROL_30 %%B + mov T3,%%A + add %%E, T1 + ROL_5 T3 + add T3, %%E + mov %%E, T3 + + W_CALC %%nr+1 + + ROL_5 T3 + add %%D,T3 + %%MagiF %%A,%%B,%%C + add %%D, T1 + ROL_30 %%A + +; write: %1, %2 +; rotate: %1<=%4, %2<=%5, %3<=%1, %4<=%2, %5<=%3 +%endmacro + +;; update hash macro +%macro UPDATE_HASH 2.nolist + %xdefine %%hash0 %1 + %xdefine %%hashAdd %2 + + add %%hashAdd, %%hash0 + mov %%hash0, %%hashAdd +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +K_XMM_AR dd SHA1_K1, SHA1_K1, SHA1_K1, SHA1_K1 + dd SHA1_K2, SHA1_K2, SHA1_K2, SHA1_K2 + dd SHA1_K3, SHA1_K3, SHA1_K3, SHA1_K3 + dd SHA1_K4, SHA1_K4, SHA1_K4, SHA1_K4 + +shuffle_mask DD 00010203h + DD 04050607h + DD 08090a0bh + DD 0c0d0e0fh + + +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA1(DigestSHA1 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;***************************************************************************************** + +;; +;; Lib = U8, N8 +;; +;; Caller = ippsSHA1Update +;; Caller = ippsSHA1Final +;; Caller = ippsSHA1MessageDigest +;; +;; Caller = ippsHMACSHA1Update +;; Caller = ippsHMACSHA1Final +;; Caller = ippsHMACSHA1MessageDigest +;; + +;; assign hash values to GPU registers +%xdefine A ecx +%xdefine B eax +%xdefine C edx +%xdefine D r8d +%xdefine E r9d + +;; temporary +%xdefine T1 r10d +%xdefine T2 r11d +%xdefine T3 r13d +%xdefine T4 r13d + +%xdefine W_TMP xmm0 +%xdefine W_TMP2 xmm1 + +%xdefine W0 xmm2 +%xdefine W4 xmm3 +%xdefine W8 xmm4 +%xdefine W12 xmm5 +%xdefine W16 xmm6 +%xdefine W20 xmm7 +%xdefine W24 xmm8 +%xdefine W28 xmm9 + +;; endianness swap constant +%xdefine XMM_SHUFB_BSWAP xmm10 + +;; K_BASE contains K_XMM_AR address +%xdefine K_BASE r12 + + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA1,PUBLIC +%assign LOCAL_FRAME (16*4) + USES_GPR rdi,rsi,r12,r13,r14 + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10 + COMP_ABI 4 + +%xdefine MBS_SHA1 (64) + + movsxd r14, edx + + movdqa XMM_SHUFB_BSWAP, oword [rel shuffle_mask] ; load shuffle mask + lea K_BASE, [rel K_XMM_AR] ; SHA1 const array address + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha1_block_loop: + mov A, dword [rdi] ; load initial hash value + mov B, dword [rdi+4] + mov C, dword [rdi+8] + mov D, dword [rdi+12] + mov E, dword [rdi+16] + + movdqu W28, oword [rsi] ; load buffer content + movdqu W24, oword [rsi+16] + movdqu W20, oword [rsi+32] + movdqu W16, oword [rsi+48] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;SHA1_MAIN_BODY + +%xdefine W W0 +%xdefine W_minus_04 W4 +%xdefine W_minus_08 W8 +%xdefine W_minus_12 W12 +%xdefine W_minus_16 W16 +%xdefine W_minus_20 W20 +%xdefine W_minus_24 W24 +%xdefine W_minus_28 W28 +%xdefine W_minus_32 W + + ;; assignment +%xdefine K_XMM K_BASE + +;;F textequ + SHA1_UPDATE_RND_F1_BSWAP A,B,C,D,E, 0, W28 + SHA1_UPDATE_RND_F1 E,A,B,C,D, 1 + SHA1_UPDATE_RND_F1 D,E,A,B,C, 2 + SHA1_UPDATE_RND_F1 C,D,E,A,B, 3 + + SHA1_UPDATE_RND_F1_BSWAP B,C,D,E,A, 4, W24 + SHA1_UPDATE_RND_F1 A,B,C,D,E, 5 + SHA1_UPDATE_RND_F1 E,A,B,C,D, 6 + SHA1_UPDATE_RND_F1 D,E,A,B,C, 7 + + SHA1_UPDATE_RND_F1_BSWAP C,D,E,A,B, 8, W20 + SHA1_UPDATE_RND_F1 B,C,D,E,A, 9 + SHA1_UPDATE_RND_F1 A,B,C,D,E, 10 + SHA1_UPDATE_RND_F1 E,A,B,C,D, 11 + + SHA1_UPDATE_RND_F1_BSWAP D,E,A,B,C, 12, W16 + + W_CALC 8 + W_CALC 9 + W_CALC 10 + + SHA1_UPDATE_RND_F1 C,D,E,A,B, 13 + + W_CALC 11 + W_CALC 12 + + SHA1_UPDATE_RND_F1 B,C,D,E,A, 14 + + W_CALC 13 + W_CALC 14 + W_CALC 15 + + SHA1_UPDATE_RND_F1 A,B,C,D,E, 15 + + SHA1_UPDATE_REGULAR E,A,B,C,D,16, F1 + SHA1_UPDATE_REGULAR C,D,E,A,B,18, F1 + +;;F textequ + SHA1_UPDATE_REGULAR A,B,C,D,E,20, F2 + SHA1_UPDATE_REGULAR D,E,A,B,C,22, F2 + SHA1_UPDATE_REGULAR B,C,D,E,A,24, F2 + SHA1_UPDATE_REGULAR E,A,B,C,D,26, F2 + SHA1_UPDATE_REGULAR C,D,E,A,B,28, F2 + + SHA1_UPDATE_REGULAR A,B,C,D,E,30, F2 + SHA1_UPDATE_REGULAR D,E,A,B,C,32, F2 + SHA1_UPDATE_REGULAR B,C,D,E,A,34, F2 + SHA1_UPDATE_REGULAR E,A,B,C,D,36, F2 + SHA1_UPDATE_REGULAR C,D,E,A,B,38, F2 + +;;F textequ + SHA1_UPDATE_REGULAR A,B,C,D,E,40, F3 + SHA1_UPDATE_REGULAR D,E,A,B,C,42, F3 + SHA1_UPDATE_REGULAR B,C,D,E,A,44, F3 + SHA1_UPDATE_REGULAR E,A,B,C,D,46, F3 + SHA1_UPDATE_REGULAR C,D,E,A,B,48, F3 + + SHA1_UPDATE_REGULAR A,B,C,D,E,50, F3 + SHA1_UPDATE_REGULAR D,E,A,B,C,52, F3 + SHA1_UPDATE_REGULAR B,C,D,E,A,54, F3 + SHA1_UPDATE_REGULAR E,A,B,C,D,56, F3 + SHA1_UPDATE_REGULAR C,D,E,A,B,58, F3 + +;;F textequ + SHA1_UPDATE_REGULAR A,B,C,D,E,60, F4 + SHA1_UPDATE_REGULAR D,E,A,B,C,62, F4 + SHA1_UPDATE_REGULAR B,C,D,E,A,64, F4 + SHA1_UPDATE_REGULAR E,A,B,C,D,66, F4 + SHA1_UPDATE_REGULAR C,D,E,A,B,68, F4 + + SHA1_UPDATE_REGULAR A,B,C,D,E,70, F4 + SHA1_UPDATE_REGULAR D,E,A,B,C,72, F4 + SHA1_UPDATE_REGULAR B,C,D,E,A,74, F4 + SHA1_UPDATE_REGULAR E,A,B,C,D,76, F4 + SHA1_UPDATE_REGULAR C,D,E,A,B,78, F4 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + UPDATE_HASH dword [rdi], A + UPDATE_HASH dword [rdi+4], B + UPDATE_HASH dword [rdi+8], C + UPDATE_HASH dword [rdi+12],D + UPDATE_HASH dword [rdi+16],E + + add rsi, MBS_SHA1 + sub r14, MBS_SHA1 + jg .sha1_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA1 + +%endif ;; ((_IPP32E >= _IPP32E_U8 ) AND (_IPP32E < _IPP32E_E9 )) OR (_IPP32E == _IPP32E_N8 ) +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA1_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256e9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256e9as.asm new file mode 100644 index 000000000..cb99c5927 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256e9as.asm @@ -0,0 +1,541 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA256 +; +; Content: +; UpdateSHA256 +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E == _IPP32E_E9 ) + +%xdefine W0 xmm0 +%xdefine W4 xmm1 +%xdefine W8 xmm2 +%xdefine W12 xmm3 +%xdefine SIG1 xmm4 +%xdefine SIG0 xmm5 +%xdefine X xmm6 +%xdefine W xmm7 +%xdefine XMM_SHUFB_BSWAP xmm6 + +;; assign hash values to GPU registers +%xdefine A eax +%xdefine B ebx +%xdefine C ecx +%xdefine D edx +%xdefine E r8d +%xdefine F r9d +%xdefine G r10d +%xdefine H r11d +%xdefine T1 r12d +%xdefine T2 r13d +%xdefine T3 r14d +%xdefine T4 r15d + +;; we are considering x, y, z are polynomials over GF(2) +;; & - multiplication +;; ^ - additive +;; operations + +;; +;; Chj(x,y,z) = (x&y) ^ (~x & z) +;; = (x&y) ^ ((1^x) &z) +;; = (x&y) ^ (z ^ x&z) +;; = x&y ^ z ^ x&z +;; = x&(y^z) ^z +;; +%macro Chj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%Y + xor %%F, %%Z + and %%F, %%X + xor %%F, %%Z +%endmacro + +;; +;; Maj(x,y,z) = (x&y) ^ (x&z) ^ (y&z) +;; = (x&y) ^ (x&z) ^ (y&z) ^ (z&z) ^z // note: ((z&z) ^z) = 0 +;; = x&(y^z) ^ z&(y^z) ^z +;; = (x^z)&(y^z) ^z +;; +%macro Maj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%X + xor %%F, %%Z + xor %%Y, %%Z + and %%F, %%Y + xor %%Y, %%Z + xor %%F, %%Z +%endmacro + +%macro ROTR 2.nolist + %xdefine %%X %1 + %xdefine %%n %2 + + shrd %%X,%%X, %%n +%endmacro + +;; +;; Summ0(x) = ROR(x,2) ^ ROR(x,13) ^ ROR(x,22) +;; +%macro Summ0 2.nolist + %xdefine %%F %1 + %xdefine %%X %2 + + mov %%F, %%X + ROTR %%F, (22-13) + xor %%F, %%X + ROTR %%F, (13-2) + xor %%F, %%X + ROTR %%F, 2 +%endmacro + +;; +;; Summ1(x) = ROR(x,6) ^ ROR(x,11) ^ ROR(x,25) +;; +%macro Summ1 2.nolist + %xdefine %%F %1 + %xdefine %%X %2 + + mov %%F, %%X + ROTR %%F, (25-11) + xor %%F, %%X + ROTR %%F, (11-6) + xor %%F, %%X + ROTR %%F, 6 +%endmacro + +;; +;; regular round (i): +;; +;; T1 = h + Sigma1(e) + Ch(e,f,g) + K[i] + W[i] +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h = g +;; g = f +;; f = e +;; e = d + T1 +;; d = c +;; c = b +;; b = a +;; a = T1+T2 +;; +;; or +;; +;; h += Sigma1(e) + Ch(e,f,g) + K[i] + W[i] (==T1) +;; d += h +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h += T2 +;; and following textual shift {a,b,c,d,e,f,g,h} => {h,a,b,c,d,e,f,g} +;; +%macro ROUND 11.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + %xdefine %%T1 %10 + %xdefine %%T2 %11 + + add %%H, dword [rsp+(%%nr & 3)*sizeof(dword)] + Summ1 %%T1, %%E + Chj %%T2, %%E,%%F,%%G + add %%H, %%T1 + add %%H, %%T2 + + add %%D, %%H + + Summ0 %%T1, %%A + Maj %%T2, %%A,%%B,%%C + add %%H, %%T1 + add %%H, %%T2 +%endmacro + +%macro ROUND_v1 12.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + %xdefine %%T1 %10 + %xdefine %%T2 %11 + %xdefine %%T3 %12 + + Summ1 %%T1, %%E ;; S1 + Chj %%T2, %%E,%%F,%%G ;; CH + add %%H, dword [rsp+(%%nr & 3)*sizeof(dword)] + add %%H, %%T1 + add %%H, %%T2 + + Maj %%T1, %%A,%%B,%%C ;; MAJ + Summ0 %%T2, %%A ;; S0 + + add %%D, %%H + + add %%H, %%T1 + add %%H, %%T2 +%endmacro + +;; W[i] = Sigma1(W[i-2]) + W[i-7] + Sigma0(W[i-15]) + W[i-16], i=16,..,63 +;; +;;for next rounds 16,17,18 and 19: +;; W[0] <= W[16] = Sigma1(W[14]) + W[ 9] + Sigma0(W[1]) + W[0] +;; W[1] <= W[17] = Sigma1(W[15]) + W[10] + Sigma0(W[2]) + W[1] +;; W[2] <= W[18] = Sigma1(W[ 0]) + W[11] + Sigma0(W[3]) + W[2] +;; W[3] <= W[19] = Sigma1(W[ 1]) + W[12] + Sigma0(W[4]) + W[3] +;; +;; the process is repeated exactly because texual round of W[] +;; +;; Sigma1() and Sigma0() functions are defined as following: +;; Sigma1(X) = ROR(X,17)^ROR(X,19)^SHR(X,10) +;; Sigma0(X) = ROR(X, 7)^ROR(X,18)^SHR(X, 3) +;; +%macro UPDATE_W 8.nolist + %xdefine %%xS0 %1 + %xdefine %%xS4 %2 + %xdefine %%xS8 %3 + %xdefine %%xS12 %4 + %xdefine %%SIGMA %5 + %xdefine %%xS %6 + %xdefine %%xT %7 + %xdefine %%phase %8 + +%if %%phase == 0 + ;; SIGMA0 + vpalignr %%xS, %%xS4, %%xS0, 4 ;; xS = {W04,W03,W02,W01} + vpsrld %%SIGMA, %%xS, 3 ;; SIGMA0 = SHR({W04,W03,W02,W01},3) + vpsrld %%xT, %%xS, 7 ;; SIGMA0 ^= SHR({W04,W03,W02,W01},7) + vpxor %%SIGMA, %%SIGMA, %%xT + vpsrld %%xT, %%xS, 18 ;; SIGMA0 ^= SHR({W04,W03,W02,W01},18) + vpxor %%SIGMA, %%SIGMA, %%xT + vpslld %%xT, %%xS, (32-18) ;; SIGMA0 ^= SHL({W04,W03,W02,W01},32-18) + vpxor %%SIGMA, %%SIGMA, %%xT + vpslld %%xT, %%xS, (32-7) ;; SIGMA0 ^= SHL({W04,W03,W02,W01},32-7) + vpxor %%SIGMA, %%SIGMA, %%xT +%endif +%if %%phase == 1 + vpalignr %%xS, %%xS12,%%xS8, 4 ;; xS = {W12,W11,W10,W09} + vpaddd %%xS0, %%xS0, %%xS ;; xS0 = xS0 + {W12,W11,W10,W09} + SIGMA0 + vpaddd %%xS0, %%xS0, %%SIGMA +%endif +%if %%phase == 2 + ;; SIGMA1 (low) + vpshufd %%xS, %%xS12, 11111010b ;; xS = {W[15],W[15],W[14],W[14]} + vpsrld %%SIGMA, %%xS, 10 ;; SIGMA1 = SHR({W[15],W[15],W[14],W[14]},10) + vpsrlq %%xT, %%xS, 17 ;; xT = SHR({W[15],W[15],W[14],W[14]},17) + vpsrlq %%xS, %%xS, 19 ;; xS = SHR({W[15],W[15],W[14],W[14]},19) + vpxor %%SIGMA, %%SIGMA, %%xT + vpxor %%SIGMA, %%SIGMA, %%xS ;; SIGMA1 ^= xT ^ xS + vpshufb %%SIGMA, %%SIGMA, [rel SHUFD_ZZ10] ;; SIGMA1 = {zzz,zzz,SIGMA1.1,SIGMA1.0} + + vpaddd %%xS0, %%xS0, %%SIGMA ;; {???,???,new W01,new W00} = {??,??,W17,W16} +%endif +%if %%phase == 3 + ;; SIGMA1 (hight) + vpshufd %%xS, %%xS0, 01010000b ;; xS = {W17,W17,W16,W16} + vpsrld %%SIGMA, %%xS, 10 ;; SIGMA1 = SHR({W[17],W[17],W[16],W[16]},10) + vpsrlq %%xT, %%xS, 17 ;; xT = ROTR({W[17],W[17],W[16],W[16]},17)- low 32 rotation in fact + vpsrlq %%xS, %%xS, 19 ;; xS = RORR({W[17],W[17],W[16],W[16]},19) - low 32 rotation in fact + vpxor %%SIGMA, %%SIGMA, %%xT + vpxor %%SIGMA, %%SIGMA, %%xS ;; SIGMA1 ^= xT ^ xS + vpshufb %%SIGMA, %%SIGMA, [rel SHUFD_32ZZ] ;; SIGMA1 = {SIGMA1.3,SIGMA1.2,zzz,zzz} + + vpaddd %%xS0, %%xS0, %%SIGMA ;; {new W03, new W02,new W01,new W00} = {W19,W18,W17,W16} +%endif +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR +SHUFB_BSWAP DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 +SHUFD_ZZ10 DB 0,1,2,3, 8,9,10,11, 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh +SHUFD_32ZZ DB 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh, 0,1,2,3, 8,9,10,11 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; UpdateSHA256(Ipp32u digest[], Ipp8u dataBlock[], int datalen, Ipp32u K_256[]) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA256,PUBLIC +%assign LOCAL_FRAME sizeof(oword)+sizeof(qword) + USES_GPR rbx,rsi,rdi,rbp,r12,r13,r14,r15 + USES_XMM xmm6,xmm7 + COMP_ABI 4 +;; +;; rdi = pointer to the updated hash +;; rsi = pointer to the data block +;; rdx = data block length +;; rcx = pointer to the SHA_256 constant +;; + +%xdefine MBS_SHA256 (64) + + movsxd rdx, edx + mov qword [rsp+sizeof(oword)], rdx ; save length of buffer + + mov rbp, rcx ; rbp points K_256[] constants + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +.sha256_block_loop: + vmovdqu W0, oword [rsi] ; load buffer content and swap + vpshufb W0, W0, [rel SHUFB_BSWAP] + vmovdqu W4, oword [rsi+sizeof(oword)] + vpshufb W4, W4, [rel SHUFB_BSWAP] + vmovdqu W8, oword [rsi+sizeof(oword)*2] + vpshufb W8, W8, [rel SHUFB_BSWAP] + vmovdqu W12,oword [rsi+sizeof(oword)*3] + vpshufb W12,W12, [rel SHUFB_BSWAP] + + mov A, dword [rdi] ; load initial hash value + mov B, dword [rdi+sizeof(dword)] + mov C, dword [rdi+sizeof(dword)*2] + mov D, dword [rdi+sizeof(dword)*3] + mov E, dword [rdi+sizeof(dword)*4] + mov F, dword [rdi+sizeof(dword)*5] + mov G, dword [rdi+sizeof(dword)*6] + mov H, dword [rdi+sizeof(dword)*7] + + ;; perform 0-3 regular rounds + vpaddd W, W0, oword [rbp+sizeof(oword)*0] ; T += K_SHA256[0-3] + vmovdqa oword [rsp], W + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 0 ; update for round: 16-19 + ROUND 0, A,B,C,D,E,F,G,H, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 1 + ROUND 1, H,A,B,C,D,E,F,G, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 2 + ROUND 2, G,H,A,B,C,D,E,F, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 3 + ROUND 3, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 4-7 regular rounds + vpaddd W, W4, oword [rbp+sizeof(oword)*1] ; T += K_SHA256[4-7] + vmovdqa oword [rsp], W + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 0 ; update for round: 20-23 + ROUND 4, E,F,G,H,A,B,C,D, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 1 + ROUND 5, D,E,F,G,H,A,B,C, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 2 + ROUND 6, C,D,E,F,G,H,A,B, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 3 + ROUND 7, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 8-11 regular rounds + vpaddd W, W8, oword [rbp+sizeof(oword)*2] ; T += K_SHA256[8-11] + vmovdqa oword [rsp], W + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 0 ; update for round: 24-27 + ROUND 8, A,B,C,D,E,F,G,H, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 1 + ROUND 9, H,A,B,C,D,E,F,G, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 2 + ROUND 10, G,H,A,B,C,D,E,F, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 3 + ROUND 11, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 12-15 regular rounds + vpaddd W, W12, oword [rbp+sizeof(oword)*3] ; T += K_SHA256[12-15] + vmovdqa oword [rsp], W + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 0 ; update for round: 28-31 + ROUND 12, E,F,G,H,A,B,C,D, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 1 + ROUND 13, D,E,F,G,H,A,B,C, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 2 + ROUND 14, C,D,E,F,G,H,A,B, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 3 + ROUND 15, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 16-19 regular rounds + vpaddd W, W0, oword [rbp+sizeof(oword)*4] ; T += K_SHA256[16-19] + vmovdqa oword [rsp], W + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 0 ; update for round: 32-35 + ROUND 16, A,B,C,D,E,F,G,H, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 1 + ROUND 17, H,A,B,C,D,E,F,G, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 2 + ROUND 18, G,H,A,B,C,D,E,F, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 3 + ROUND 19, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 20-23 regular rounds + vpaddd W, W4, oword [rbp+sizeof(oword)*5] ; T += K_SHA256[20-23] + vmovdqa oword [rsp], W + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 0 ; update for round: 36-39 + ROUND 20, E,F,G,H,A,B,C,D, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 1 + ROUND 21, D,E,F,G,H,A,B,C, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 2 + ROUND 22, C,D,E,F,G,H,A,B, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 3 + ROUND 23, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 24-27 regular rounds + vpaddd W, W8, oword [rbp+sizeof(oword)*6] ; T += K_SHA256[24-27] + vmovdqa oword [rsp], W + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 0 ; update for round: 40-43 + ROUND 24, A,B,C,D,E,F,G,H, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 1 + ROUND 25, H,A,B,C,D,E,F,G, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 2 + ROUND 26, G,H,A,B,C,D,E,F, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 3 + ROUND 27, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 28-31 regular rounds + vpaddd W, W12, oword [rbp+sizeof(oword)*7] ; T += K_SHA256[28-31] + vmovdqa oword [rsp], W + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 0 ; update for round: 44-47 + ROUND 28, E,F,G,H,A,B,C,D, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 1 + ROUND 29, D,E,F,G,H,A,B,C, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 2 + ROUND 30, C,D,E,F,G,H,A,B, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 3 + ROUND 31, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 32-35 regular rounds + vpaddd W, W0, oword [rbp+sizeof(oword)*8] ; T += K_SHA256[32-35] + vmovdqa oword [rsp], W + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 0 ; update for round: 48-51 + ROUND 32, A,B,C,D,E,F,G,H, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 1 + ROUND 33, H,A,B,C,D,E,F,G, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 2 + ROUND 34, G,H,A,B,C,D,E,F, T1,T2 + UPDATE_W W0,W4,W8,W12, SIG1,W,X, 3 + ROUND 35, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 36-39 regular rounds + vpaddd W, W4, oword [rbp+sizeof(oword)*9] ; T += K_SHA256[36-39] + vmovdqa oword [rsp], W + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 0 ; update for round: 52-55 + ROUND 36, E,F,G,H,A,B,C,D, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 1 + ROUND 37, D,E,F,G,H,A,B,C, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 2 + ROUND 38, C,D,E,F,G,H,A,B, T1,T2 + UPDATE_W W4,W8,W12,W0, SIG1,W,X, 3 + ROUND 39, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 40-43 regular rounds + vpaddd W, W8, oword [rbp+sizeof(oword)*10] ; T += K_SHA256[40-43] + vmovdqa oword [rsp], W + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 0 ; update for round: 56-59 + ROUND 40, A,B,C,D,E,F,G,H, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 1 + ROUND 41, H,A,B,C,D,E,F,G, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 2 + ROUND 42, G,H,A,B,C,D,E,F, T1,T2 + UPDATE_W W8,W12,W0,W4, SIG1,W,X, 3 + ROUND 43, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 44-47 regular rounds + vpaddd W, W12, oword [rbp+sizeof(oword)*11] ; T += K_SHA256[44-47] + vmovdqa oword [rsp], W + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 0 ; update for round: 60-63 + ROUND 44, E,F,G,H,A,B,C,D, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 1 + ROUND 45, D,E,F,G,H,A,B,C, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 2 + ROUND 46, C,D,E,F,G,H,A,B, T1,T2 + UPDATE_W W12,W0,W4,W8, SIG1,W,X, 3 + ROUND 47, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 48-51 regular rounds + vpaddd W, W0, oword [rbp+sizeof(oword)*12] ; T += K_SHA256[48-51] + vmovdqa oword [rsp], W + ROUND 48, A,B,C,D,E,F,G,H, T1,T2 + ROUND 49, H,A,B,C,D,E,F,G, T1,T2 + ROUND 50, G,H,A,B,C,D,E,F, T1,T2 + ROUND 51, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 52-55 regular rounds + vpaddd W, W4, oword [rbp+sizeof(oword)*13] ; T += K_SHA256[52-55] + vmovdqa oword [rsp], W + ROUND 52, E,F,G,H,A,B,C,D, T1,T2 + ROUND 53, D,E,F,G,H,A,B,C, T1,T2 + ROUND 54, C,D,E,F,G,H,A,B, T1,T2 + ROUND 55, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 56-59 regular rounds + vpaddd W, W8, oword [rbp+sizeof(oword)*14] ; T += K_SHA256[56-59] + vmovdqa oword [rsp], W + ROUND 56, A,B,C,D,E,F,G,H, T1,T2 + ROUND 57, H,A,B,C,D,E,F,G, T1,T2 + ROUND 58, G,H,A,B,C,D,E,F, T1,T2 + ROUND 59, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 60-63 regular rounds + vpaddd W, W12, oword [rbp+sizeof(oword)*15] ; T += K_SHA256[60-63] + vmovdqa oword [rsp], W + ROUND 60, E,F,G,H,A,B,C,D, T1,T2 + ROUND 61, D,E,F,G,H,A,B,C, T1,T2 + ROUND 62, C,D,E,F,G,H,A,B, T1,T2 + ROUND 63, B,C,D,E,F,G,H,A, T1,T2 + + add dword [rdi], A ; update shash + add dword [rdi+sizeof(dword)*1], B + add dword [rdi+sizeof(dword)*2], C + add dword [rdi+sizeof(dword)*3], D + add dword [rdi+sizeof(dword)*4], E + add dword [rdi+sizeof(dword)*5], F + add dword [rdi+sizeof(dword)*6], G + add dword [rdi+sizeof(dword)*7], H + + add rsi, MBS_SHA256 + sub qword [rsp+sizeof(oword)], MBS_SHA256 + jg .sha256_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA256 + +%endif ;; _IPP32E_E9 and above +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256l9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256l9as.asm new file mode 100644 index 000000000..7f2ade9aa --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256l9as.asm @@ -0,0 +1,629 @@ +;=============================================================================== +; Copyright (C) 2017 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA256 +; +; Content: +; UpdateSHA256 +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_L9 ) + +;; +;; assignments +;; +%xdefine hA eax ;; hash values into GPU registers +%xdefine hB ebx +%xdefine hC ecx +%xdefine hD edx +%xdefine hE r8d +%xdefine hF r9d +%xdefine hG r10d +%xdefine hH r11d + +%xdefine T1 r12d ;; scratch +%xdefine T2 r13d +%xdefine T3 r14d +%xdefine T4 r15d +%xdefine T5 edi + +%xdefine W0 ymm0 ;; W values into YMM registers +%xdefine W1 ymm1 +%xdefine W2 ymm2 +%xdefine W3 ymm3 + +%xdefine yT1 ymm4 ;; scratch +%xdefine yT2 ymm5 +%xdefine yT3 ymm6 +%xdefine yT4 ymm7 + +%xdefine W0L xmm0 +%xdefine W1L xmm1 +%xdefine W2L xmm2 +%xdefine W3L xmm3 + +%xdefine YMM_zzBA ymm8 ;; byte swap constant +%xdefine YMM_DCzz ymm9 ;; byte swap constant +%xdefine YMM_SHUFB_BSWAP ymm10 ;; byte swap constant + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; textual rotation of W args +;; +%macro ROTATE_W 0.nolist + %xdefine %%_X W0 + %xdefine W0 W1 + %xdefine W1 W2 + %xdefine W2 W3 + %xdefine W3 %%_X +%endmacro + +;; +;; textual rotation of HASH arguments +;; +%macro ROTATE_H 0.nolist + %xdefine %%_X hH + %xdefine hH hG + %xdefine hG hF + %xdefine hF hE + %xdefine hE hD + %xdefine hD hC + %xdefine hC hB + %xdefine hB hA + %xdefine hA %%_X +%endmacro + +%macro ROTATE_T4_T5 0.nolist + %xdefine %%T T4 + %xdefine T4 T5 + %xdefine T5 %%T +%endmacro + +;; +;; compute next 4 W[t], W[t+1], W[t+2] and W[t+3], t=16,...63 +;; (see pcpsha256e9as.asm for details) +%macro UPDATE_W 5.nolist + %xdefine %%nr %1 + %xdefine %%W0 %2 + %xdefine %%W1 %3 + %xdefine %%W2 %4 + %xdefine %%W3 %5 + + %assign %%W_AHEAD 16 + + vpalignr yT3,%%W1,%%W0,4 + vpalignr yT2,%%W3,%%W2,4 + vpsrld yT1,yT3,7 + vpaddd %%W0,%%W0,yT2 + vpsrld yT2,yT3,3 + vpslld yT4,yT3,14 + vpxor yT3,yT2,yT1 + vpshufd yT2,%%W3,250 + vpsrld yT1,yT1,11 + vpxor yT3,yT3,yT4 + vpslld yT4,yT4,11 + vpxor yT3,yT3,yT1 + vpsrld yT1,yT2,10 + vpxor yT3,yT3,yT4 + vpsrlq yT2,yT2,17 + vpaddd %%W0,%%W0,yT3 + vpxor yT1,yT1,yT2 + vpsrlq yT2,yT2,2 + vpxor yT1,yT1,yT2 + vpshufb yT1,yT1,YMM_zzBA + vpaddd %%W0,%%W0,yT1 + vpshufd yT2,%%W0,80 + vpsrld yT1,yT2,10 + vpsrlq yT2,yT2,17 + vpxor yT1,yT1,yT2 + vpsrlq yT2,yT2,2 + vpxor yT1,yT1,yT2 + vpshufb yT1,yT1,YMM_DCzz + vpaddd %%W0,%%W0,yT1 + vpaddd yT1,%%W0,YMMWORD [rbp+(%%nr/4)*sizeof(ymmword)] + vmovdqa YMMWORD [rsi+(%%W_AHEAD/4)*sizeof(ymmword)+(%%nr/4)*sizeof(ymmword)],yT1 +%endmacro + +;; +;; regular round (i): +;; +;; T1 = h + Sum1(e) + Ch(e,f,g) + K[i] + W[i] +;; T2 = Sum0(a) + Maj(a,b,c) +;; h = g +;; g = f +;; f = e +;; e = d + T1 +;; d = c +;; c = b +;; b = a +;; a = T1+T2 +;; +;; sum1(e) = (e>>>25)^(e>>>11)^(e>>>6) +;; sum0(a) = (a>>>13)^(a>>>22)^(a>>>2) +;; ch(e,f,g) = (e&f)^(~e^g) +;; maj(a,b,m)= (a&b)^(a&c)^(b&c) +;; +;; note: +;; 1) U + ch(e,f,g) = U + (e&f) & (~e&g) +;; 2) maj(a,b,c)= (a&b)^(a&c)^(b&c) = (a^b)&(b^c) ^b +;; to make sure both are correct - use GF(2) arith instead of logic +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; or +;; X = sum0(a[i-1]) computed on prev round +;; a[i] += X +;; h[i] += (K[i]+W[i]) + sum1(e[i]) + ch(e[i],f[i],g[i]) or +;; h[i] += (K[i]+W[i]) + sum1(e[i]) + (e[i]&f[i]) + (~e[i]&g[i]) -- helps break dependencies +;; d[i] += h[i] +;; h[i] += maj(a[i],b[i],c[i]) +;; and following textual shift +;; {a[i+1],b[i+1],c[i+1],d[i+1],e[i+1],f[i+1],g[i+1],h[i+1]} <= {h[i],a[i],b[i],c[i],d[i],e[i],f[i],g[i]} +;; +;; on entry: +;; - T1 = f +;; - T3 = sum0{a[i-1]) +;; - T5 = b&c +%macro SHA256_ROUND 9.nolist + %xdefine %%nr %1 + %xdefine %%hA %2 + %xdefine %%hB %3 + %xdefine %%hC %4 + %xdefine %%hD %5 + %xdefine %%hE %6 + %xdefine %%hF %7 + %xdefine %%hG %8 + %xdefine %%hH %9 + + add %%hH, dword [rsi+(%%nr/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] ;; h += (k[t]+w[t]) + and T1, %%hE ;; ch(e,f,g): (f&e) + rorx T2, %%hE, 25 ;; sum1(e): e>>>25 + rorx T4, %%hE, 11 ;; sum1(e): e>>>11 + add %%hA, T3 ;; complete computation a += sum0(a[t-1]) + add %%hH, T1 ;; h += (k[t]+w[t]) + (f&e) + andn T1, %%hE, %%hG ;; ch(e,f,g): (~e&g) + xor T2, T4 ;; sum1(e): (e>>>25)^(e>>>11) + rorx T3, %%hE, 6 ;; sum1(e): e>>>6 + add %%hH, T1 ;; h += (k[t]+w[t]) + (f&e) + (~e&g) + xor T2, T3 ;; sum1(e) = (e>>>25)^(e>>>11)^(e>>>6) + mov T4, %%hA ;; maj(a,b,c): a + rorx T1, %%hA, 22 ;; sum0(a): a>>>22 + add %%hH, T2 ;; h += (k[t]+w[t]) +(f&e) +(~e&g) +sig1(e) + xor T4, %%hB ;; maj(a,b,c): (a^b) + rorx T3, %%hA, 13 ;; sum0(a): a>>>13 + rorx T2, %%hA, 2 ;; sum0(a): a>>>2 + add %%hD, %%hH ;; d += h + and T5, T4 ;; maj(a,b,c): (b^c)&(a^b) + xor T3, T1 ;; sum0(a): (a>>>13)^(a>>>22) + xor T5, %%hB ;; maj(a,b,c) = (b^c)&(a^b)^b = (a&b)^(a&c)^(b&c) + xor T3, T2 ;; sum0(a): = (a>>>13)^(a>>>22)^(a>>>2) + add %%hH, T5 ;; h += (k[t]+w[t]) +(f&e) +(~e&g) +sig1(e) +maj(a,b,c) + mov T1, %%hE ;; T1 = f (next round) + ROTATE_T4_T5 ;; T5 = (b^c) (next round) +%endmacro + +;; +;; does 4 regular rounds and computes next 4 W values +;; (just 4 instances of SHA256_ROUND merged together woth UPDATE_W) +;; +%macro SHA256_4ROUND_SHED 1.nolist + %xdefine %%round %1 + + %assign %%W_AHEAD 16 +vpalignr yT3,W1,W0,4 + %assign %%nr %%round + add hH, dword [rsi+(%%nr/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + and T1, hE + rorx T2, hE, 25 +vpalignr yT2,W3,W2,4 + rorx T4, hE, 11 + add hA, T3 + add hH, T1 +vpsrld yT1,yT3,7 + andn T1, hE, hG + xor T2, T4 + rorx T3, hE, 6 +vpaddd W0,W0,yT2 + add hH, T1 + xor T2, T3 + mov T4, hA +vpsrld yT2,yT3,3 + rorx T1, hA, 22 + add hH, T2 + xor T4, hB +vpslld yT4,yT3,14 + rorx T3, hA, 13 + rorx T2, hA, 2 + add hD, hH +vpxor yT3,yT2,yT1 + and T5, T4 + xor T3, T1 + xor T5, hB +vpshufd yT2,W3,250 + xor T3, T2 + add hH, T5 + mov T1, hE + ROTATE_T4_T5 + ROTATE_H + +vpsrld yT1,yT1,11 + %assign %%nr %%nr+1 + add hH, dword [rsi+(%%nr/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + and T1, hE + rorx T2, hE, 25 +vpxor yT3,yT3,yT4 + rorx T4, hE, 11 + add hA, T3 + add hH, T1 +vpslld yT4,yT4,11 + andn T1, hE, hG + xor T2, T4 + rorx T3, hE, 6 +vpxor yT3,yT3,yT1 + add hH, T1 + xor T2, T3 + mov T4, hA +vpsrld yT1,yT2,10 + rorx T1, hA, 22 + add hH, T2 + xor T4, hB +vpxor yT3,yT3,yT4 + rorx T3, hA, 13 + rorx T2, hA, 2 + add hD, hH +vpsrlq yT2,yT2,17 + and T5, T4 + xor T3, T1 + xor T5, hB +vpaddd W0,W0,yT3 + xor T3, T2 + add hH, T5 + mov T1, hE + ROTATE_T4_T5 + ROTATE_H + +vpxor yT1,yT1,yT2 + %assign %%nr %%nr+1 + add hH, dword [rsi+(%%nr/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + and T1, hE + rorx T2, hE, 25 +vpsrlq yT2,yT2,2 + rorx T4, hE, 11 + add hA, T3 + add hH, T1 +vpxor yT1,yT1,yT2 + andn T1, hE, hG + xor T2, T4 + rorx T3, hE, 6 +vpshufb yT1,yT1,YMM_zzBA + add hH, T1 + xor T2, T3 + mov T4, hA +vpaddd W0,W0,yT1 + rorx T1, hA, 22 + add hH, T2 + xor T4, hB +vpshufd yT2,W0,80 + rorx T3, hA, 13 + rorx T2, hA, 2 + add hD, hH +vpsrld yT1,yT2,10 + and T5, T4 + xor T3, T1 + xor T5, hB +vpsrlq yT2,yT2,17 + xor T3, T2 + add hH, T5 + mov T1, hE + ROTATE_T4_T5 + ROTATE_H + +vpxor yT1,yT1,yT2 + %assign %%nr %%nr+1 + add hH, dword [rsi+(%%nr/4)*sizeof(ymmword)+(%%nr & 3)*sizeof(dword)] + and T1, hE + rorx T2, hE, 25 +vpsrlq yT2,yT2,2 + rorx T4, hE, 11 + add hA, T3 + add hH, T1 +vpxor yT1,yT1,yT2 + andn T1, hE, hG + xor T2, T4 + rorx T3, hE, 6 +vpshufb yT1,yT1,YMM_DCzz + add hH, T1 + xor T2, T3 + mov T4, hA +vpaddd W0,W0,yT1 + rorx T1, hA, 22 + add hH, T2 + xor T4, hB +vpaddd yT1,W0,YMMWORD [rbp+(%%nr/4)*sizeof(ymmword)] + rorx T3, hA, 13 + rorx T2, hA, 2 + add hD, hH + and T5, T4 + xor T3, T1 + xor T5, hB +vmovdqa YMMWORD [rsi+(%%W_AHEAD/4)*sizeof(ymmword)+(%%round/4)*sizeof(ymmword)],yT1 + xor T3, T2 + add hH, T5 + mov T1, hE + ROTATE_T4_T5 + ROTATE_H + + ROTATE_W +%endmacro + +;; +;; update hash +;; +%macro UPDATE_HASH 2.nolist + %xdefine %%hashMem %1 + %xdefine %%hash %2 + + add %%hash, %%hashMem + mov %%hashMem, %%hash +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +SHA256_YMM_K dd 0428a2f98h, 071374491h, 0b5c0fbcfh, 0e9b5dba5h, 0428a2f98h, 071374491h, 0b5c0fbcfh, 0e9b5dba5h + dd 03956c25bh, 059f111f1h, 0923f82a4h, 0ab1c5ed5h, 03956c25bh, 059f111f1h, 0923f82a4h, 0ab1c5ed5h + dd 0d807aa98h, 012835b01h, 0243185beh, 0550c7dc3h, 0d807aa98h, 012835b01h, 0243185beh, 0550c7dc3h + dd 072be5d74h, 080deb1feh, 09bdc06a7h, 0c19bf174h, 072be5d74h, 080deb1feh, 09bdc06a7h, 0c19bf174h + dd 0e49b69c1h, 0efbe4786h, 00fc19dc6h, 0240ca1cch, 0e49b69c1h, 0efbe4786h, 00fc19dc6h, 0240ca1cch + dd 02de92c6fh, 04a7484aah, 05cb0a9dch, 076f988dah, 02de92c6fh, 04a7484aah, 05cb0a9dch, 076f988dah + dd 0983e5152h, 0a831c66dh, 0b00327c8h, 0bf597fc7h, 0983e5152h, 0a831c66dh, 0b00327c8h, 0bf597fc7h + dd 0c6e00bf3h, 0d5a79147h, 006ca6351h, 014292967h, 0c6e00bf3h, 0d5a79147h, 006ca6351h, 014292967h + dd 027b70a85h, 02e1b2138h, 04d2c6dfch, 053380d13h, 027b70a85h, 02e1b2138h, 04d2c6dfch, 053380d13h + dd 0650a7354h, 0766a0abbh, 081c2c92eh, 092722c85h, 0650a7354h, 0766a0abbh, 081c2c92eh, 092722c85h + dd 0a2bfe8a1h, 0a81a664bh, 0c24b8b70h, 0c76c51a3h, 0a2bfe8a1h, 0a81a664bh, 0c24b8b70h, 0c76c51a3h + dd 0d192e819h, 0d6990624h, 0f40e3585h, 0106aa070h, 0d192e819h, 0d6990624h, 0f40e3585h, 0106aa070h + dd 019a4c116h, 01e376c08h, 02748774ch, 034b0bcb5h, 019a4c116h, 01e376c08h, 02748774ch, 034b0bcb5h + dd 0391c0cb3h, 04ed8aa4ah, 05b9cca4fh, 0682e6ff3h, 0391c0cb3h, 04ed8aa4ah, 05b9cca4fh, 0682e6ff3h + dd 0748f82eeh, 078a5636fh, 084c87814h, 08cc70208h, 0748f82eeh, 078a5636fh, 084c87814h, 08cc70208h + dd 090befffah, 0a4506cebh, 0bef9a3f7h, 0c67178f2h, 090befffah, 0a4506cebh, 0bef9a3f7h, 0c67178f2h + +SHA256_YMM_BF dd 000010203h, 004050607h, 008090a0bh, 00c0d0e0fh, 000010203h, 004050607h, 008090a0bh, 00c0d0e0fh + +SHA256_DCzz db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh, 0,1,2,3, 8,9,10,11 + db 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh, 0,1,2,3, 8,9,10,11 +SHA256_zzBA db 0,1,2,3, 8,9,10,11, 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh + db 0,1,2,3, 8,9,10,11, 0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0ffh + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; UpdateSHA256(Ipp32u digest[], Ipp8u dataBlock[], int datalen, Ipp32u K_256[]) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA256,PUBLIC +%assign LOCAL_FRAME (sizeof(qword)*4 + sizeof(dword)*64*2) + USES_GPR rbx,rsi,rdi,rbp,rbx,r12,r13,r14,r15 + USES_XMM_AVX xmm6,xmm7,xmm8,xmm9,xmm10 + COMP_ABI 4 +;; +;; rdi = pointer to the updated hash +;; rsi = pointer to the data block +;; rdx = data block length +;; rcx = pointer to the SHA_256 constant (ignored) +;; + +%xdefine MBS_SHA256 (64) + +;; +;; stack structure: +;; +%assign _block 0 ;; block address +%assign _hash _block+sizeof(qword) ;; hash address +%assign _len _hash+sizeof(qword) ;; rest of processed data +%assign _frame _len+sizeof(qword) ;; rsp before alignment +%assign _dataW _frame+sizeof(qword) ;; W[t] values + + + mov r15, rsp ; store orifinal rsp + and rsp, -IPP_ALIGN_FACTOR ; 32-byte aligned stack + + movsxd r14, edx ; input length in bytes + + mov qword [rsp+_hash], rdi ; store hash address + mov qword [rsp+_len], r14 ; store length + mov qword [rsp+_frame], r15 ; store rsp + + mov hA, dword [rdi] ; load initial hash value + mov hB, dword [rdi+1*sizeof(dword)] + mov hC, dword [rdi+2*sizeof(dword)] + mov hD, dword [rdi+3*sizeof(dword)] + mov hE, dword [rdi+4*sizeof(dword)] + mov hF, dword [rdi+5*sizeof(dword)] + mov hG, dword [rdi+6*sizeof(dword)] + mov hH, dword [rdi+7*sizeof(dword)] + + vmovdqa YMM_SHUFB_BSWAP, ymmword [rel SHA256_YMM_BF] ; load byte shuffler + + vmovdqa YMM_zzBA, ymmword [rel SHA256_zzBA] ; load byte shuffler (zzBA) + vmovdqa YMM_DCzz, ymmword [rel SHA256_DCzz] ; load byte shuffler (DCzz) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data 2 block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +.sha256_block2_loop: + lea r12, [rsi+MBS_SHA256] ; next block + + cmp r14, MBS_SHA256 ; %if single block processed + cmovbe r12, rsi ; use the same data block address + lea rbp, [rel SHA256_YMM_K] ; to SHA256 consts + + vmovdqu W0L, xmmword [rsi] ; load data block + vmovdqu W1L, xmmword [rsi+1*sizeof(xmmword)] + vmovdqu W2L, xmmword [rsi+2*sizeof(xmmword)] + vmovdqu W3L, xmmword [rsi+3*sizeof(xmmword)] + + vinserti128 W0, W0, xmmword [r12], 1 ; merge next data block + vinserti128 W1, W1, xmmword [r12+1*sizeof(xmmword)], 1 + vinserti128 W2, W2, xmmword [r12+2*sizeof(xmmword)], 1 + vinserti128 W3, W3, xmmword [r12+3*sizeof(xmmword)], 1 + + vpshufb W0, W0, YMM_SHUFB_BSWAP + vpshufb W1, W1, YMM_SHUFB_BSWAP + vpshufb W2, W2, YMM_SHUFB_BSWAP + vpshufb W3, W3, YMM_SHUFB_BSWAP + vpaddd yT1, W0, ymmword [rbp] + vpaddd yT2, W1, ymmword [rbp+1*sizeof(ymmword)] + vpaddd yT3, W2, ymmword [rbp+2*sizeof(ymmword)] + vpaddd yT4, W3, ymmword [rbp+3*sizeof(ymmword)] + add rbp, 4*sizeof(ymmword) + vmovdqa ymmword [rsp+_dataW], yT1 + vmovdqa ymmword [rsp+_dataW+1*sizeof(ymmword)], yT2 + vmovdqa ymmword [rsp+_dataW+2*sizeof(ymmword)], yT3 + vmovdqa ymmword [rsp+_dataW+3*sizeof(ymmword)], yT4 + + mov T5, hB ; T5 = b^c + xor T3, T3 ; T3 = 0 + mov T1, hF ; T1 = f + xor T5, hC + + mov qword [rsp+_block], rsi ; store block addres + lea rsi, [rsp+_dataW] ; use rsi as stack pointer + +align IPP_ALIGN_FACTOR +.block1_shed_proc: + SHA256_4ROUND_SHED 0 + SHA256_4ROUND_SHED 4 + SHA256_4ROUND_SHED 8 + SHA256_4ROUND_SHED 12 + + add rsi, 4*sizeof(ymmword) + add rbp, 4*sizeof(ymmword) + + ;; and repeat + cmp dword [rbp-sizeof(dword)],0c67178f2h + jne .block1_shed_proc + + ;; the rest 16 rounds + SHA256_ROUND 0, hA,hB,hC,hD,hE,hF,hG,hH + SHA256_ROUND 1, hH,hA,hB,hC,hD,hE,hF,hG + SHA256_ROUND 2, hG,hH,hA,hB,hC,hD,hE,hF + SHA256_ROUND 3, hF,hG,hH,hA,hB,hC,hD,hE + SHA256_ROUND 4, hE,hF,hG,hH,hA,hB,hC,hD + SHA256_ROUND 5, hD,hE,hF,hG,hH,hA,hB,hC + SHA256_ROUND 6, hC,hD,hE,hF,hG,hH,hA,hB + SHA256_ROUND 7, hB,hC,hD,hE,hF,hG,hH,hA + SHA256_ROUND 8, hA,hB,hC,hD,hE,hF,hG,hH + SHA256_ROUND 9, hH,hA,hB,hC,hD,hE,hF,hG + SHA256_ROUND 10, hG,hH,hA,hB,hC,hD,hE,hF + SHA256_ROUND 11, hF,hG,hH,hA,hB,hC,hD,hE + SHA256_ROUND 12, hE,hF,hG,hH,hA,hB,hC,hD + SHA256_ROUND 13, hD,hE,hF,hG,hH,hA,hB,hC + SHA256_ROUND 14, hC,hD,hE,hF,hG,hH,hA,hB + SHA256_ROUND 15, hB,hC,hD,hE,hF,hG,hH,hA + add hA, T3 + + sub rsi, (16-4)*sizeof(ymmword) ; restore stack to W + + mov rdi, qword [rsp+_hash] ; restore hash pointer + mov r14, qword [rsp+_len] ; restore data length + + ;; update hash values by 1-st data block + UPDATE_HASH dword [rdi], hA + UPDATE_HASH dword [rdi+1*sizeof(dword)], hB + UPDATE_HASH dword [rdi+2*sizeof(dword)], hC + UPDATE_HASH dword [rdi+3*sizeof(dword)], hD + UPDATE_HASH dword [rdi+4*sizeof(dword)], hE + UPDATE_HASH dword [rdi+5*sizeof(dword)], hF + UPDATE_HASH dword [rdi+6*sizeof(dword)], hG + UPDATE_HASH dword [rdi+7*sizeof(dword)], hH + + cmp r14, MBS_SHA256*2 + jl .done + + ;; do 64 rounds for the next block + add rsi, 4*sizeof(dword) ; restore stack to next block W + lea rbp, [rsi+16*sizeof(ymmword)] ; use rbp for loop limiter + + mov T5, hB ; T5 = b^c + xor T3, T3 ; T3 = 0 + mov T1, hF ; T1 = f + xor T5, hC + +align IPP_ALIGN_FACTOR +.block2_proc: + SHA256_ROUND 0, hA,hB,hC,hD,hE,hF,hG,hH + SHA256_ROUND 1, hH,hA,hB,hC,hD,hE,hF,hG + SHA256_ROUND 2, hG,hH,hA,hB,hC,hD,hE,hF + SHA256_ROUND 3, hF,hG,hH,hA,hB,hC,hD,hE + SHA256_ROUND 4, hE,hF,hG,hH,hA,hB,hC,hD + SHA256_ROUND 5, hD,hE,hF,hG,hH,hA,hB,hC + SHA256_ROUND 6, hC,hD,hE,hF,hG,hH,hA,hB + SHA256_ROUND 7, hB,hC,hD,hE,hF,hG,hH,hA + add rsi, 2*sizeof(ymmword) + cmp rsi, rbp + jb .block2_proc + add hA, T3 + + mov rdi, qword [rsp+_hash] ; restore hash pointer + mov r14, qword [rsp+_len] ; restore data length + + ;; update hash values by 2-nd data block + UPDATE_HASH dword [rdi], hA + UPDATE_HASH dword [rdi+1*sizeof(dword)], hB + UPDATE_HASH dword [rdi+2*sizeof(dword)], hC + UPDATE_HASH dword [rdi+3*sizeof(dword)], hD + UPDATE_HASH dword [rdi+4*sizeof(dword)], hE + UPDATE_HASH dword [rdi+5*sizeof(dword)], hF + UPDATE_HASH dword [rdi+6*sizeof(dword)], hG + UPDATE_HASH dword [rdi+7*sizeof(dword)], hH + + mov rsi, qword [rsp+_block] ; restore block addres + add rsi, MBS_SHA256*2 ; move data pointer + sub r14, MBS_SHA256*2 ; update data length + mov qword [rsp+_len], r14 + jg .sha256_block2_loop + +.done: + mov rsp, qword [rsp+_frame] + REST_XMM_AVX + REST_GPR + ret +ENDFUNC UpdateSHA256 + +%endif ;; _IPP32E_L9 and above +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256m7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256m7as.asm new file mode 100644 index 000000000..36287e3d6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256m7as.asm @@ -0,0 +1,416 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA256 +; +; Content: +; UpdateSHA256 +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_M7) && (_IPP32E < _IPP32E_U8 ) + + +;; +;; ENDIANNESS +;; +%macro ENDIANNESS 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + %ifnidn %%dst,%%src + mov %%dst,%%src + %endif + bswap %%dst +%endmacro + +;; +;; single SHA256 step +;; +;; Ipp32u T1 = H + SUM1(E) + CH(E,F,G) + K_SHA256[t] + W[t]; +;; Ipp32u T2 = SUM0(A) + MAJ(A,B,C); +;; D+= T1; +;; H = T1 + T2; +;; +;; where +;; SUM1(x) = ROR(x,6) ^ ROR(x,11) ^ ROR(x,25) +;; SUM0(x) = ROR(x,2) ^ ROR(x,13) ^ ROR(x,22) +;; +;; CH(x,y,z) = (x & y) ^ (~x & z) +;; MAJ(x,y,z) = (x & y) ^ (x & z) ^ (y & z) = (x&y)^((x^y)&z) +;; +%macro SHA256_STEP_2 13.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regF %6 + %xdefine %%regG %7 + %xdefine %%regH %8 + %xdefine %%regT %9 + %xdefine %%regF1 %10 + %xdefine %%regF2 %11 + %xdefine %%memW %12 + %xdefine %%immCNT %13 + + ;; update H (start) + add %%regH%+d,%%immCNT ;; H += W[t]+K_SHA256[t] + add %%regH%+d,[%%memW] + + ;; compute T = SUM1(E) + CH(E,F,G) + mov %%regF1%+d,%%regE%+d ;; SUM1() = E + mov %%regF2%+d,%%regE%+d ;; CH() = E + ror %%regF1%+d,6 ;; ROR(E,6) + mov %%regT%+d, %%regE%+d + push %%regE + not %%regF2%+d ;; ~E + ror %%regE%+d, 11 ;; ROR(E,11) + and %%regT%+d, %%regF%+d ;; E&F + and %%regF2%+d,%%regG%+d ;;~E&G + xor %%regF1%+d,%%regE%+d ;; ROR(E,6)^ROR(E,11) + ror %%regE%+d, 14 ;; ROR(E,25) + xor %%regF2%+d,%%regT%+d ;; CH() = (E&F)&(~E&G) + xor %%regF1%+d,%%regE%+d ;; SUM1() = ROR(E,6)^ROR(E,11)^ROR(E,25) + pop %%regE ;; repair E + lea %%regT, [%%regF1+%%regF2] + + ;; update H (continue) + add %%regH%+d, %%regT%+d + + ;; update D + add %%regD%+d, %%regH%+d + + ;; compute T = SUM0(A) + MAJ(A,B,C) + mov %%regF1%+d,%%regA%+d ;; SUM0() = A + mov %%regF2%+d,%%regA%+d ;; MAJ() = A + ror %%regF1%+d,2 ;; ROR(A,2) + mov %%regT%+d, %%regA%+d + push %%regA + xor %%regF2%+d,%%regB%+d ;; A^B + ror %%regA%+d, 13 ;; ROR(A,13) + and %%regT%+d, %%regB%+d ;; A&B + and %%regF2%+d,%%regC%+d ;; (A^B)&C + xor %%regF1%+d,%%regA%+d ;; ROR(A,2)^ROR(A,13) + ror %%regA%+d, 9 ;; ROR(A,22) + xor %%regF2%+d,%%regT%+d ;; MAJ() = (A^B)^((A^B)&C) + xor %%regF1%+d,%%regA%+d ;; SUM0() = ROR(A,2)^ROR(A,13)^ROR(A,22) + pop %%regA ;; repair A + lea %%regT, [%%regF1+%%regF2] + + ;; update H (finish) + add %%regH%+d, %%regT%+d +%endmacro + +;; +;; update W[] +;; +;; W[j] = SIG1(W[j- 2]) + W[j- 7] +;; +SIG0(W[j-15]) + W[j-16] +;; +;; SIG0(x) = ROR(x,7) ^ROR(x,18) ^LSR(x,3) +;; SIG1(x) = ROR(x,17)^ROR(x,19) ^LSR(x,10) +;; +%macro UPDATE_2 5.nolist + %xdefine %%nr %1 + %xdefine %%sig0 %2 + %xdefine %%sig1 %3 + %xdefine %%W15 %4 + %xdefine %%W2 %5 + + mov %%sig0, [rsp+((%%nr-15) & 0Fh)*4] ;; W[j-15] + mov %%sig1, [rsp+((%%nr-2) & 0Fh)*4] ;; W[j-2] + shr %%sig0, 3 + shr %%sig1, 10 + mov %%W15, [rsp+((%%nr-15) & 0Fh)*4] ;; W[j-15] + mov %%W2, [rsp+((%%nr-2) & 0Fh)*4] ;; W[j-2] + ror %%W15, 7 + ror %%W2, 17 + xor %%sig0, %%W15 ;; SIG0 = LSR(W[j-15], 3) + xor %%sig1, %%W2 ;; SIG1 = LSR(W[j-2], 10) + ror %%W15, 11 ;; ROR(W[j-15], 18) + ror %%W2, 2 ;; ROR(W[j-2, 19) + xor %%sig0, %%W15 + xor %%sig1, %%W2 + + add %%sig0, [rsp+((%%nr-16) & 0Fh)*4] ;;SIG0 += W[j-16] + add %%sig1, [rsp+((%%nr-7) & 0Fh)*4] ;;SIG1 += W[j-7] + add %%sig0, %%sig1 + mov [rsp+((%%nr-16) & 0Fh)*4], %%sig0 +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +;****************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA256(DigestSHA256 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;****************************************************************************************** + +;; +;; Lib = M7 +;; +;; Caller = ippsSHA256Update +;; Caller = ippsSHA256Final +;; Caller = ippsSHA256MessageDigest +;; +;; Caller = ippsSHA224Update +;; Caller = ippsSHA224Final +;; Caller = ippsSHA224MessageDigest +;; +;; Caller = ippsHMACSHA256Update +;; Caller = ippsHMACSHA256Final +;; Caller = ippsHMACSHA256MessageDigest +;; +;; Caller = ippsHMACSHA224Update +;; Caller = ippsHMACSHA224Final +;; Caller = ippsHMACSHA224MessageDigest +;; + + +%if (_IPP32E >= _IPP32E_U8) +align IPP_ALIGN_FACTOR +pByteSwp DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 +%endif + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA256,PUBLIC +%assign LOCAL_FRAME (16*sizeof(dword) + sizeof(qword)) + USES_GPR rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 4 + +;; rdi = digest +;; rsi = data buffer +;; rdx = buffer len +;; rcx = dummy parameter + +%xdefine MBS_SHA256 (64) + + movsxd rdx, edx + mov qword [rsp+16*sizeof(dword)], rdx ; save length of buffer + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + +;; +;; initialize the first 16 words in the array W (remember about endian) +;; +%if (_IPP32E >= _IPP32E_U8) + movdqa xmm4, oword [rel pByteSwp] + movdqu xmm0, oword [rsi+0*16] + pshufb xmm0, xmm4 + movdqa oword [rsp+0*16], xmm0 + movdqu xmm1, oword [rsi+1*16] + pshufb xmm1, xmm4 + movdqa oword [rsp+1*16], xmm1 + movdqu xmm2, oword [rsi+2*16] + pshufb xmm2, xmm4 + movdqa oword [rsp+2*16], xmm2 + movdqu xmm3, oword [rsi+3*16] + pshufb xmm3, xmm4 + movdqa oword [rsp+3*16], xmm3 +%else + xor rcx,rcx +.loop1: + mov r8d,[rsi+rcx*4+0*4] + ENDIANNESS r8d,r8d + mov [rsp+rcx*4+0*4],r8d + + mov r9d,[rsi+rcx*4+1*4] + ENDIANNESS r9d,r9d + mov [rsp+rcx*4+1*4],r9d + + add rcx,2 + cmp rcx,16 + jl .loop1 +%endif + +;; +;; init A, B, C, D, E, F, G, H by the internal digest +;; + mov r8d, [rdi+0*4] ; r8d = digest[0] (A) + mov r9d, [rdi+1*4] ; r9d = digest[1] (B) + mov r10d,[rdi+2*4] ; r10d= digest[2] (C) + mov r11d,[rdi+3*4] ; r11d= digest[3] (D) + mov r12d,[rdi+4*4] ; r12d= digest[4] (E) + mov r13d,[rdi+5*4] ; r13d= digest[5] (F) + mov r14d,[rdi+6*4] ; r14d= digest[6] (G) + mov r15d,[rdi+7*4] ; r15d= digest[7] (H) + +;; +;; perform 0-64 steps +;; +;; A, B, C, D, E, F, G, H T, F1, F2, W[], K256 +;; ---------------------------------------------------------------------------- + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*4}, 0428A2F98h + UPDATE_2 16, eax,ebx, ecx,edx + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*4}, 071374491h + UPDATE_2 17, eax,ebx, ecx,edx + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*4}, 0B5C0FBCFh + UPDATE_2 18, eax,ebx, ecx,edx + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*4}, 0E9B5DBA5h + UPDATE_2 19, eax,ebx, ecx,edx + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*4}, 03956C25Bh + UPDATE_2 20, eax,ebx, ecx,edx + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*4}, 059F111F1h + UPDATE_2 21, eax,ebx, ecx,edx + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*4}, 0923F82A4h + UPDATE_2 22, eax,ebx, ecx,edx + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*4}, 0AB1C5ED5h + UPDATE_2 23, eax,ebx, ecx,edx + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*4}, 0D807AA98h + UPDATE_2 24, eax,ebx, ecx,edx + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*4}, 012835B01h + UPDATE_2 25, eax,ebx, ecx,edx + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*4}, 0243185BEh + UPDATE_2 26, eax,ebx, ecx,edx + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*4}, 0550C7DC3h + UPDATE_2 27, eax,ebx, ecx,edx + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*4}, 072BE5D74h + UPDATE_2 28, eax,ebx, ecx,edx + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*4}, 080DEB1FEh + UPDATE_2 29, eax,ebx, ecx,edx + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*4}, 09BDC06A7h + UPDATE_2 30, eax,ebx, ecx,edx + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*4}, 0C19BF174h + UPDATE_2 31, eax,ebx, ecx,edx + + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*4}, 0E49B69C1h + UPDATE_2 32, eax,ebx, ecx,edx + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*4}, 0EFBE4786h + UPDATE_2 33, eax,ebx, ecx,edx + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*4}, 00FC19DC6h + UPDATE_2 34, eax,ebx, ecx,edx + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*4}, 0240CA1CCh + UPDATE_2 35, eax,ebx, ecx,edx + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*4}, 02DE92C6Fh + UPDATE_2 36, eax,ebx, ecx,edx + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*4}, 04A7484AAh + UPDATE_2 37, eax,ebx, ecx,edx + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*4}, 05CB0A9DCh + UPDATE_2 38, eax,ebx, ecx,edx + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*4}, 076F988DAh + UPDATE_2 39, eax,ebx, ecx,edx + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*4}, 0983E5152h + UPDATE_2 40, eax,ebx, ecx,edx + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*4}, 0A831C66Dh + UPDATE_2 41, eax,ebx, ecx,edx + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*4}, 0B00327C8h + UPDATE_2 42, eax,ebx, ecx,edx + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*4}, 0BF597FC7h + UPDATE_2 43, eax,ebx, ecx,edx + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*4}, 0C6E00BF3h + UPDATE_2 44, eax,ebx, ecx,edx + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*4}, 0D5A79147h + UPDATE_2 45, eax,ebx, ecx,edx + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*4}, 006CA6351h + UPDATE_2 46, eax,ebx, ecx,edx + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*4}, 014292967h + UPDATE_2 47, eax,ebx, ecx,edx + + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*4}, 027B70A85h + UPDATE_2 48, eax,ebx, ecx,edx + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*4}, 02E1B2138h + UPDATE_2 49, eax,ebx, ecx,edx + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*4}, 04D2C6DFCh + UPDATE_2 50, eax,ebx, ecx,edx + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*4}, 053380D13h + UPDATE_2 51, eax,ebx, ecx,edx + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*4}, 0650A7354h + UPDATE_2 52, eax,ebx, ecx,edx + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*4}, 0766A0ABBh + UPDATE_2 53, eax,ebx, ecx,edx + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*4}, 081C2C92Eh + UPDATE_2 54, eax,ebx, ecx,edx + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*4}, 092722C85h + UPDATE_2 55, eax,ebx, ecx,edx + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*4}, 0A2BFE8A1h + UPDATE_2 56, eax,ebx, ecx,edx + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*4}, 0A81A664Bh + UPDATE_2 57, eax,ebx, ecx,edx + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*4}, 0C24B8B70h + UPDATE_2 58, eax,ebx, ecx,edx + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*4}, 0C76C51A3h + UPDATE_2 59, eax,ebx, ecx,edx + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*4}, 0D192E819h + UPDATE_2 60, eax,ebx, ecx,edx + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*4}, 0D6990624h + UPDATE_2 61, eax,ebx, ecx,edx + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*4}, 0F40E3585h + UPDATE_2 62, eax,ebx, ecx,edx + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*4}, 0106AA070h + UPDATE_2 63, eax,ebx, ecx,edx + + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*4}, 019A4C116h + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*4}, 01E376C08h + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*4}, 02748774Ch + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*4}, 034B0BCB5h + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*4}, 0391C0CB3h + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*4}, 04ED8AA4Ah + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*4}, 05B9CCA4Fh + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*4}, 0682E6FF3h + SHA256_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*4}, 0748F82EEh + SHA256_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*4}, 078A5636Fh + SHA256_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*4}, 084C87814h + SHA256_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*4}, 08CC70208h + SHA256_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*4}, 090BEFFFAh + SHA256_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*4}, 0A4506CEBh + SHA256_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*4}, 0BEF9A3F7h + SHA256_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*4}, 0C67178F2h + +;; +;; update digest +;; + add [rdi+0*4],r8d + add [rdi+1*4],r9d + add [rdi+2*4],r10d + add [rdi+3*4],r11d + add [rdi+4*4],r12d + add [rdi+5*4],r13d + add [rdi+6*4],r14d + add [rdi+7*4],r15d + + add rsi, MBS_SHA256 + sub qword [rsp+16*sizeof(dword)], MBS_SHA256 + jg .sha256_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA256 + +%endif ;; (_IPP32E >= _IPP32E_M7) AND (_IPP32E < _IPP32E_U8 ) +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256nias.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256nias.asm new file mode 100644 index 000000000..3c8928c8f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256nias.asm @@ -0,0 +1,569 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA-256 +; +; Content: +; UpdateSHA256ni +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_ON_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +;;%if (_IPP32E >= _IPP32E_Y8 ) + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR +PSHUFFLE_BYTE_FLIP_MASK \ + DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 + +align IPP_ALIGN_FACTOR +;***************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA256ni(DigestSHA256 digest, const Ipp8u* msg, int mlen, const void* pParam) +;* +;***************************************************************************************** +%ifndef _VXWORKS + +IPPASM UpdateSHA256ni,PUBLIC +%assign LOCAL_FRAME 16*2 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10 + COMP_ABI 4 + +%xdefine MBS_SHA256 (64) ; SHA-256 message block length (bytes) + +%xdefine HASH_PTR rdi ; 1st arg +%xdefine MSG_PTR rsi ; 2nd arg +%xdefine MSG_LEN rdx ; 3rd arg +%xdefine K256_PTR rcx ; 4th arg + +%xdefine MSG xmm0 +%xdefine STATE0 xmm1 +%xdefine STATE1 xmm2 +%xdefine MSGTMP0 xmm3 +%xdefine MSGTMP1 xmm4 +%xdefine MSGTMP2 xmm5 +%xdefine MSGTMP3 xmm6 +%xdefine MSGTMP4 xmm7 + +%xdefine SHUF_MASK xmm8 + +%xdefine ABEF_SAVE xmm9 +%xdefine CDGH_SAVE xmm10 + + movsxd MSG_LEN, edx ; expand mLen + test MSG_LEN, MSG_LEN + jz .quit + + ;; load input hash value, reorder these appropriately + movdqu STATE0, oword [HASH_PTR+0*16] + movdqu STATE1, oword [HASH_PTR+1*16] + + pshufd STATE0, STATE0, 0B1h ; CDAB + pshufd STATE1, STATE1, 01Bh ; EFGH + movdqa MSGTMP4, STATE0 + palignr STATE0, STATE1, 8 ; ABEF + pblendw STATE1, MSGTMP4, 0F0h ; CDGH + + movdqa SHUF_MASK, oword [rel PSHUFFLE_BYTE_FLIP_MASK] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + movdqa ABEF_SAVE, STATE0 ; save for addition after rounds + movdqa CDGH_SAVE, STATE1 + + ;; rounds 0-3 + movdqu MSG, oword [MSG_PTR + 0*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP0, MSG + paddd MSG, oword [K256_PTR + 0*16] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + ;; rounds 4-7 + movdqu MSG, oword [MSG_PTR + 1*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP1, MSG + paddd MSG, oword [K256_PTR + 1*16] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 8-11 + movdqu MSG, oword [MSG_PTR + 2*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP2, MSG + paddd MSG, oword [K256_PTR + 2*16] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 12-15 + movdqu MSG, oword [MSG_PTR + 3*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP3, MSG + paddd MSG, oword [K256_PTR + 3*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP2, MSGTMP3 + ;; rounds 16-19 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 4*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 20-23 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 5*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 24-27 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 6*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 28-31 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 7*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 32-35 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 8*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 36-39 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 9*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 40-43 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 10*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 44-47 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 11*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 48-51 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 12*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 52-55 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 13*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + ;; rounds 56-59 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 14*16] + sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + ;; rounds 60-63 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 15*16] + sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + sha256rnds2 STATE0, STATE1 + + paddd STATE0, ABEF_SAVE ; update previously saved hash + paddd STATE1, CDGH_SAVE + + add MSG_PTR, MBS_SHA256 + sub MSG_LEN, MBS_SHA256 + jg .sha256_block_loop + + ; reorder hash + pshufd STATE0, STATE0, 01Bh ; FEBA + pshufd STATE1, STATE1, 0B1h ; DCHG + movdqa MSGTMP4, STATE0 + pblendw STATE0, STATE1, 0F0h ; DCBA + palignr STATE1, MSGTMP4, 8 ; HGFE + + ; and store it back + movdqu oword [HASH_PTR + 0*16], STATE0 + movdqu oword [HASH_PTR + 1*16], STATE1 + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA256ni + +%else ;; no sha ni support in VxWorks - therefore we temporary use db +IPPASM UpdateSHA256ni,PUBLIC +%assign LOCAL_FRAME 16*2 + USES_GPR rsi,rdi + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10 + COMP_ABI 4 + +%xdefine MBS_SHA256 (64) ; SHA-256 message block length (bytes) + +%xdefine HASH_PTR rdi ; 1st arg +%xdefine MSG_PTR rsi ; 2nd arg +%xdefine MSG_LEN rdx ; 3rd arg +%xdefine K256_PTR rcx ; 4th arg + +%xdefine MSG xmm0 +%xdefine STATE0 xmm1 +%xdefine STATE1 xmm2 +%xdefine MSGTMP0 xmm3 +%xdefine MSGTMP1 xmm4 +%xdefine MSGTMP2 xmm5 +%xdefine MSGTMP3 xmm6 +%xdefine MSGTMP4 xmm7 + +%xdefine SHUF_MASK xmm8 + +%xdefine ABEF_SAVE xmm9 +%xdefine CDGH_SAVE xmm10 + + movsxd MSG_LEN, edx ; expand mLen + test MSG_LEN, MSG_LEN + jz .quit + + ;; load input hash value, reorder these appropriately + movdqu STATE0, oword [HASH_PTR+0*16] + movdqu STATE1, oword [HASH_PTR+1*16] + + pshufd STATE0, STATE0, 0B1h ; CDAB + pshufd STATE1, STATE1, 01Bh ; EFGH + movdqa MSGTMP4, STATE0 + palignr STATE0, STATE1, 8 ; ABEF + pblendw STATE1, MSGTMP4, 0F0h ; CDGH + + movdqa SHUF_MASK, oword [rel PSHUFFLE_BYTE_FLIP_MASK] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + movdqa ABEF_SAVE, STATE0 ; save for addition after rounds + movdqa CDGH_SAVE, STATE1 + + ;; rounds 0-3 + movdqu MSG, oword [MSG_PTR + 0*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP0, MSG + paddd MSG, oword [K256_PTR + 0*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + ;; rounds 4-7 + movdqu MSG, oword [MSG_PTR + 1*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP1, MSG + paddd MSG, oword [K256_PTR + 1*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0DCH ;; sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 8-11 + movdqu MSG, oword [MSG_PTR + 2*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP2, MSG + paddd MSG, oword [K256_PTR + 2*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0E5H ;; sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 12-15 + movdqu MSG, oword [MSG_PTR + 3*16] + pshufb MSG, SHUF_MASK + movdqa MSGTMP3, MSG + paddd MSG, oword [K256_PTR + 3*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + db 0FH,38H,0CDH,0DEH ;; sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0EEH ;; sha256msg1 MSGTMP2, MSGTMP3 + ;; rounds 16-19 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 4*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + db 0FH,38H,0CDH,0E3H ;; sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0F3H ;; sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 20-23 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 5*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + db 0FH,38H,0CDH,0ECH ;; sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0DCH ;; sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 24-27 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 6*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + db 0FH,38H,0CDH,0F5H ;; sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0E5H ;; sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 28-31 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 7*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + db 0FH,38H,0CDH,0DEH ;; sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0EEH ;; sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 32-35 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 8*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + db 0FH,38H,0CDH,0E3H ;; sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0F3H ;; sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 36-39 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 9*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + db 0FH,38H,0CDH,0ECH ;; sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0DCH ;; sha256msg1 MSGTMP0, MSGTMP1 + + ;; rounds 40-43 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 10*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + db 0FH,38H,0CDH,0F5H ;; sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0E5H ;; sha256msg1 MSGTMP1, MSGTMP2 + + ;; rounds 44-47 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 11*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP3 + palignr MSGTMP4, MSGTMP2, 4 + paddd MSGTMP0, MSGTMP4 + db 0FH,38H,0CDH,0DEH ;; sha256msg2 MSGTMP0, MSGTMP3 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0EEH ;; sha256msg1 MSGTMP2, MSGTMP3 + + ;; rounds 48-51 + movdqa MSG, MSGTMP0 + paddd MSG, oword [K256_PTR + 12*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP0 + palignr MSGTMP4, MSGTMP3, 4 + paddd MSGTMP1, MSGTMP4 + db 0FH,38H,0CDH,0E3H ;; sha256msg2 MSGTMP1, MSGTMP0 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + db 0FH,38H,0CCH,0F3H ;; sha256msg1 MSGTMP3, MSGTMP0 + + ;; rounds 52-55 + movdqa MSG, MSGTMP1 + paddd MSG, oword [K256_PTR + 13*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP1 + palignr MSGTMP4, MSGTMP0, 4 + paddd MSGTMP2, MSGTMP4 + db 0FH,38H,0CDH,0ECH ;; sha256msg2 MSGTMP2, MSGTMP1 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + ;; rounds 56-59 + movdqa MSG, MSGTMP2 + paddd MSG, oword [K256_PTR + 14*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + movdqa MSGTMP4, MSGTMP2 + palignr MSGTMP4, MSGTMP1, 4 + paddd MSGTMP3, MSGTMP4 + db 0FH,38H,0CDH,0F5H ;; sha256msg2 MSGTMP3, MSGTMP2 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + ;; rounds 60-63 + movdqa MSG, MSGTMP3 + paddd MSG, oword [K256_PTR + 15*16] + db 0FH,38H,0CBH,0D1H ;; sha256rnds2 STATE1, STATE0 + pshufd MSG, MSG, 0Eh + db 0FH,38H,0CBH,0CAH ;; sha256rnds2 STATE0, STATE1 + + paddd STATE0, ABEF_SAVE ; update previously saved hash + paddd STATE1, CDGH_SAVE + + add MSG_PTR, MBS_SHA256 + sub MSG_LEN, MBS_SHA256 + jg .sha256_block_loop + + ; reorder hash + pshufd STATE0, STATE0, 01Bh ; FEBA + pshufd STATE1, STATE1, 0B1h ; DCHG + movdqa MSGTMP4, STATE0 + pblendw STATE0, STATE1, 0F0h ; DCBA + palignr STATE1, MSGTMP4, 8 ; HGFE + + ; and store it back + movdqu oword [HASH_PTR + 0*16], STATE0 + movdqu oword [HASH_PTR + 1*16], STATE1 + +.quit: + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA256ni + +%endif ;; VxWorks + +;;%endif ;; (_IPP32E >= _IPP32E_Y8) +%endif ;; _FEATURE_ON_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256u8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256u8as.asm new file mode 100644 index 000000000..3880b5b3a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha256u8as.asm @@ -0,0 +1,488 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA256 +; +; Content: +; UpdateSHA256 +; +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA256_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if ((_IPP32E >= _IPP32E_U8 ) && (_IPP32E < _IPP32E_E9 )) || (_IPP32E == _IPP32E_N8 ) + + +%xdefine XMM_SHUFB_BSWAP xmm6 +%xdefine W0 xmm0 +%xdefine W4 xmm1 +%xdefine W8 xmm2 +%xdefine W12 xmm3 +%xdefine SIG1 xmm4 +%xdefine SIG0 xmm5 +%xdefine X xmm6 +%xdefine W xmm7 + +;; assign hash values to GPU registers +%xdefine A eax +%xdefine B ebx +%xdefine C edx +%xdefine D r8d +%xdefine E r9d +%xdefine F r10d +%xdefine G r11d +%xdefine H r12d +%xdefine T1 r13d +%xdefine T2 r14d +%xdefine T3 r15d + +;; we are considering x, y, z are polynomials over GF(2) +;; & - multiplication +;; ^ - additive +;; operations + +;; +;; Chj(x,y,z) = (x&y) ^ (~x & z) +;; = (x&y) ^ ((1^x) &z) +;; = (x&y) ^ (z ^ x&z) +;; = x&y ^ z ^ x&z +;; = x&(y^z) ^z +;; +%macro Chj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%Y + xor %%F, %%Z + and %%F, %%X + xor %%F, %%Z +%endmacro + +;; +;; Maj(x,y,z) = (x&y) ^ (x&z) ^ (y&z) +;; = (x&y) ^ (x&z) ^ (y&z) ^ (z&z) ^z // note: ((z&z) ^z) = 0 +;; = x&(y^z) ^ z&(y^z) ^z +;; = (x^z)&(y^z) ^z +;; +%macro Maj 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%X + xor %%F, %%Z + xor %%Z, %%Y + and %%F, %%Z + xor %%Z, %%Y + xor %%F, %%Z +%endmacro + +%macro ROTR 2.nolist + %xdefine %%X %1 + %xdefine %%n %2 + + ;;shrd X,X, n + ror %%X, %%n +%endmacro + +;; +;; Summ0(x) = ROR(x,2) ^ ROR(x,13) ^ ROR(x,22) +;; +%macro Summ0 3.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%T %3 + + mov %%F, %%X + ROTR %%F, 2 + mov %%T, %%X + ROTR %%T, 13 + xor %%F, %%T + ROTR %%T, (22-13) + xor %%F, %%T +%endmacro + +;; +;; Summ1(x) = ROR(x,6) ^ ROR(x,11) ^ ROR(x,25) +;; +%macro Summ1 3.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%T %3 + + mov %%F, %%X + ROTR %%F, 6 + mov %%T, %%X + ROTR %%T, 11 + xor %%F, %%T + ROTR %%T, (25-11) + xor %%F, %%T +%endmacro + +;; +;; regular round (i): +;; +;; T1 = h + Sigma1(e) + Ch(e,f,g) + K[i] + W[i] +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h = g +;; g = f +;; f = e +;; e = d + T1 +;; d = c +;; c = b +;; b = a +;; a = T1+T2 +;; +;; or +;; +;; h += Sigma1(e) + Ch(e,f,g) + K[i] + W[i] (==T1) +;; d += h +;; T2 = Sigma0(a) + Maj(a,b,c) +;; h += T2 +;; and following textual shift {a,b,c,d,e,f,g,h} => {h,a,b,c,d,e,f,g} +;; +%macro ROUND 11.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + %xdefine %%T1 %10 + %xdefine %%T2 %11 + + add %%H, dword [rsp+(%%nr & 3)*sizeof(dword)] + Summ1 %%T1, %%E, %%T2 + Chj %%T2, %%E,%%F,%%G + add %%H, %%T1 + add %%H, %%T2 + + add %%D, %%H + + Summ0 %%T1, %%A, %%T2 + Maj %%T2, %%A,%%B,%%C + add %%H, %%T1 + add %%H, %%T2 +%endmacro + +;; W[i] = Sigma1(W[i-2]) + W[i-7] + Sigma0(W[i-15]) + W[i-16], i=16,..,63 +;; +;;for next rounds 16,17,18 and 19: +;; W[0] <= W[16] = Sigma1(W[14]) + W[ 9] + Sigma0(W[1]) + W[0] +;; W[1] <= W[17] = Sigma1(W[15]) + W[10] + Sigma0(W[2]) + W[1] +;; W[2] <= W[18] = Sigma1(W[ 0]) + W[11] + Sigma0(W[3]) + W[1] +;; W[3] <= W[19] = Sigma1(W[ 1]) + W[12] + Sigma0(W[4]) + W[2] +;; +;; the process is repeated exactly because texual round of W[] +;; +;; Sigma1() and Sigma0() functions are defined as following: +;; Sigma1(X) = ROR(X,17)^ROR(X,19)^SHR(X,10) +;; Sigma0(X) = ROR(X, 7)^ROR(X,18)^SHR(X, 3) +;; +%macro UPDATE_W 8.nolist + %xdefine %%xS %1 + %xdefine %%xS0 %2 + %xdefine %%xS4 %3 + %xdefine %%xS8 %4 + %xdefine %%xS12 %5 + %xdefine %%SIGMA1 %6 + %xdefine %%SIGMA0 %7 + %xdefine %%X %8 + + pshufd %%SIGMA1, %%xS12, 11111010b ;; SIGMA1 = {W[15],W[15],W[14],W[14]} + movdqa %%X, %%SIGMA1 + psrld %%SIGMA1, 10 + psrlq %%X, 17 + pxor %%SIGMA1, %%X + psrlq %%X, (19-17) + pxor %%SIGMA1, %%X + + pshufd %%SIGMA0, %%xS0, 10100101b ;; SIGMA0 = {W[2],W[2],W[1],W[1]} + movdqa %%X, %%SIGMA0 + psrld %%SIGMA0, 3 + psrlq %%X, 7 + pxor %%SIGMA0, %%X + psrlq %%X, (18-7) + pxor %%SIGMA0, %%X + + pshufd %%xS, %%xS0, 01010000b ;; {W[ 1],W[ 1],W[ 0],W[ 0]} + pshufd %%X, %%xS8, 10100101b ;; {W[10],W[10],W[ 9],W[ 9]} + paddd %%xS, %%SIGMA1 + paddd %%xS, %%SIGMA0 + paddd %%xS, %%X + + + pshufd %%SIGMA1, %%xS, 10100000b ;; SIGMA1 = {W[1],W[1],W[0],W[0]} + movdqa %%X, %%SIGMA1 + psrld %%SIGMA1, 10 + psrlq %%X, 17 + pxor %%SIGMA1, %%X + psrlq %%X, (19-17) + pxor %%SIGMA1, %%X + + movdqa %%SIGMA0, %%xS4 ;; SIGMA0 = {W[4],W[4],W[3],W[3]} + palignr %%SIGMA0, %%xS0, (3*sizeof(dword)) + pshufd %%SIGMA0, %%SIGMA0, 01010000b + movdqa %%X, %%SIGMA0 + psrld %%SIGMA0, 3 + psrlq %%X, 7 + pxor %%SIGMA0, %%X + psrlq %%X, (18-7) + pxor %%SIGMA0, %%X + + movdqa %%X, %%xS12 + palignr %%X, %%xS8, (3*sizeof(dword)) ;; {W[14],W[13],W[12],W[11]} + pshufd %%xS0, %%xS0, 11111010b ;; {W[ 3],W[ 3],W[ 2],W[ 2]} + pshufd %%X, %%X, 01010000b ;; {W[12],W[12],W[11],W[11]} + paddd %%xS0, %%SIGMA1 + paddd %%xS0, %%SIGMA0 + paddd %%xS0, %%X + + pshufd %%xS, %%xS, 10001000b ;; {W[1],W[0],W[1],W[0]} + pshufd %%xS0, %%xS0, 10001000b ;; {W[3],W[2],W[3],W[2]} + palignr %%xS0, %%xS, (2*sizeof(dword)) ;; {W[3],W[2],W[1],W[0]} + movdqa %%xS, %%xS0 +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR +pByteSwp DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; UpdateSHA256(Ipp32u digest[], Ipp8u dataBlock[], int datalen, Ipp32u K_256[]) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA256,PUBLIC +%assign LOCAL_FRAME sizeof(oword)+sizeof(qword) + USES_GPR rbx,rsi,rdi,rbp,r12,r13,r14,r15 + USES_XMM xmm6,xmm7 + COMP_ABI 4 +;; +;; rdi = pointer to the updated hash +;; rsi = pointer to the data block +;; rdx = data block length +;; rcx = pointer to the SHA_256 constant +;; + +%xdefine MBS_SHA256 (64) + + movsxd rdx, edx + mov qword [rsp+sizeof(oword)], rdx ; save length of buffer + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.sha256_block_loop: + + movdqu W0, oword [rsi] ; load buffer content + movdqu W4, oword [rsi+sizeof(oword)] + movdqu W8, oword [rsi+sizeof(oword)*2] + movdqu W12,oword [rsi+sizeof(oword)*3] + + mov A, dword [rdi] ; load initial hash value + mov B, dword [rdi+sizeof(dword)] + mov C, dword [rdi+sizeof(dword)*2] + mov D, dword [rdi+sizeof(dword)*3] + mov E, dword [rdi+sizeof(dword)*4] + mov F, dword [rdi+sizeof(dword)*5] + mov G, dword [rdi+sizeof(dword)*6] + mov H, dword [rdi+sizeof(dword)*7] + + movdqa XMM_SHUFB_BSWAP, oword [rel pByteSwp] ; load shuffle mask + + ; rcx points K_256[] constants + + ;; perform 0-3 regular rounds + pshufb W0, XMM_SHUFB_BSWAP ; swap input + movdqa W, W0 ; T = W[0-3] + paddd W, oword [rcx+sizeof(oword)*0] ; T += K_SHA256[0-3] + movdqa oword [rsp], W + ROUND 0, A,B,C,D,E,F,G,H, T1,T2 + ROUND 1, H,A,B,C,D,E,F,G, T1,T2 + ROUND 2, G,H,A,B,C,D,E,F, T1,T2 + ROUND 3, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 4-7 regular rounds + pshufb W4, XMM_SHUFB_BSWAP ; swap input + movdqa W, W4 ; T = W[4-7] + paddd W, oword [rcx+sizeof(oword)*1] ; T += K_SHA256[4-7] + movdqa oword [rsp], W + ROUND 4, E,F,G,H,A,B,C,D, T1,T2 + ROUND 5, D,E,F,G,H,A,B,C, T1,T2 + ROUND 6, C,D,E,F,G,H,A,B, T1,T2 + ROUND 7, B,C,D,E,F,G,H,A, T1,T2 + + ;; perform next 8-11 regular rounds + pshufb W8, XMM_SHUFB_BSWAP ; swap input + movdqa W, W8 ; T = W[8-11] + paddd W, oword [rcx+sizeof(oword)*2] ; T += K_SHA256[8-11] + movdqa oword [rsp], W + ROUND 8, A,B,C,D,E,F,G,H, T1,T2 + ROUND 9, H,A,B,C,D,E,F,G, T1,T2 + ROUND 10, G,H,A,B,C,D,E,F, T1,T2 + ROUND 11, F,G,H,A,B,C,D,E, T1,T2 + + ;; perform next 12-15 regular rounds + pshufb W12, XMM_SHUFB_BSWAP ; swap input + movdqa W, W12 ; T = W[12-15] + paddd W, oword [rcx+sizeof(oword)*3] ; T += K_SHA256[12-15] + movdqa oword [rsp], W + ROUND 12, E,F,G,H,A,B,C,D, T1,T2 + ROUND 13, D,E,F,G,H,A,B,C, T1,T2 + ROUND 14, C,D,E,F,G,H,A,B, T1,T2 + ROUND 15, B,C,D,E,F,G,H,A, T1,T2 + + UPDATE_W W, W0, W4, W8, W12, SIG1,SIG0,X ; round: 16-19 + paddd W, oword [rcx+sizeof(oword)*4] ; T += K_SHA256[16-19] + movdqa oword [rsp], W + ROUND 16, A,B,C,D,E,F,G,H, T1,T2 + ROUND 17, H,A,B,C,D,E,F,G, T1,T2 + ROUND 18, G,H,A,B,C,D,E,F, T1,T2 + ROUND 19, F,G,H,A,B,C,D,E, T1,T2 + + UPDATE_W W, W4, W8, W12,W0, SIG1,SIG0,X ; round: 20-23 + paddd W, oword [rcx+sizeof(oword)*5] ; T += K_SHA256[20-23] + movdqa oword [rsp], W + ROUND 20, E,F,G,H,A,B,C,D, T1,T2 + ROUND 21, D,E,F,G,H,A,B,C, T1,T2 + ROUND 22, C,D,E,F,G,H,A,B, T1,T2 + ROUND 23, B,C,D,E,F,G,H,A, T1,T2 + + UPDATE_W W, W8, W12,W0, W4, SIG1,SIG0,X ; round: 24-27 + paddd W, oword [rcx+sizeof(oword)*6] ; T += K_SHA256[24-27] + movdqa oword [rsp], W + ROUND 24, A,B,C,D,E,F,G,H, T1,T2 + ROUND 25, H,A,B,C,D,E,F,G, T1,T2 + ROUND 26, G,H,A,B,C,D,E,F, T1,T2 + ROUND 27, F,G,H,A,B,C,D,E, T1,T2 + + UPDATE_W W, W12,W0, W4, W8, SIG1,SIG0,X ; round: 28-31 + paddd W, oword [rcx+sizeof(oword)*7] ; T += K_SHA256[28-31] + movdqa oword [rsp], W + ROUND 28, E,F,G,H,A,B,C,D, T1,T2 + ROUND 29, D,E,F,G,H,A,B,C, T1,T2 + ROUND 30, C,D,E,F,G,H,A,B, T1,T2 + ROUND 31, B,C,D,E,F,G,H,A, T1,T2 + + UPDATE_W W, W0, W4, W8, W12, SIG1,SIG0,X ; round: 32-35 + paddd W, oword [rcx+sizeof(oword)*8] ; T += K_SHA256[32-35] + movdqa oword [rsp], W + ROUND 32, A,B,C,D,E,F,G,H, T1,T2 + ROUND 33, H,A,B,C,D,E,F,G, T1,T2 + ROUND 34, G,H,A,B,C,D,E,F, T1,T2 + ROUND 35, F,G,H,A,B,C,D,E, T1,T2 + + UPDATE_W W, W4, W8, W12,W0, SIG1,SIG0,X ; round: 36-39 + paddd W, oword [rcx+sizeof(oword)*9] ; T += K_SHA256[36-39] + movdqa oword [rsp], W + ROUND 36, E,F,G,H,A,B,C,D, T1,T2 + ROUND 37, D,E,F,G,H,A,B,C, T1,T2 + ROUND 38, C,D,E,F,G,H,A,B, T1,T2 + ROUND 39, B,C,D,E,F,G,H,A, T1,T2 + + UPDATE_W W, W8, W12,W0, W4, SIG1,SIG0,X ; round: 40-43 + paddd W, oword [rcx+sizeof(oword)*10] ; T += K_SHA256[40-43] + movdqa oword [rsp], W + ROUND 40, A,B,C,D,E,F,G,H, T1,T2 + ROUND 41, H,A,B,C,D,E,F,G, T1,T2 + ROUND 42, G,H,A,B,C,D,E,F, T1,T2 + ROUND 43, F,G,H,A,B,C,D,E, T1,T2 + + UPDATE_W W, W12,W0, W4, W8, SIG1,SIG0,X ; round: 44-47 + paddd W, oword [rcx+sizeof(oword)*11] ; T += K_SHA256[44-47] + movdqa oword [rsp], W + ROUND 44, E,F,G,H,A,B,C,D, T1,T2 + ROUND 45, D,E,F,G,H,A,B,C, T1,T2 + ROUND 46, C,D,E,F,G,H,A,B, T1,T2 + ROUND 47, B,C,D,E,F,G,H,A, T1,T2 + + UPDATE_W W, W0, W4, W8, W12, SIG1,SIG0,X ; round: 48-51 + paddd W, oword [rcx+sizeof(oword)*12] ; T += K_SHA256[48-51] + movdqa oword [rsp], W + ROUND 48, A,B,C,D,E,F,G,H, T1,T2 + ROUND 49, H,A,B,C,D,E,F,G, T1,T2 + ROUND 50, G,H,A,B,C,D,E,F, T1,T2 + ROUND 51, F,G,H,A,B,C,D,E, T1,T2 + + UPDATE_W W, W4, W8, W12,W0, SIG1,SIG0,X ; round: 52-55 + paddd W, oword [rcx+sizeof(oword)*13] ; T += K_SHA256[52-55] + movdqa oword [rsp], W + ROUND 52, E,F,G,H,A,B,C,D, T1,T2 + ROUND 53, D,E,F,G,H,A,B,C, T1,T2 + ROUND 54, C,D,E,F,G,H,A,B, T1,T2 + ROUND 55, B,C,D,E,F,G,H,A, T1,T2 + + UPDATE_W W, W8, W12,W0, W4, SIG1,SIG0,X ; round: 56-59 + paddd W, oword [rcx+sizeof(oword)*14] ; T += K_SHA256[56-59] + movdqa oword [rsp], W + ROUND 56, A,B,C,D,E,F,G,H, T1,T2 + ROUND 57, H,A,B,C,D,E,F,G, T1,T2 + ROUND 58, G,H,A,B,C,D,E,F, T1,T2 + ROUND 59, F,G,H,A,B,C,D,E, T1,T2 + + UPDATE_W W, W12,W0, W4, W8, SIG1,SIG0,X ; round: 60-63 + paddd W, oword [rcx+sizeof(oword)*15] ; T += K_SHA256[60-63] + movdqa oword [rsp], W + ROUND 60, E,F,G,H,A,B,C,D, T1,T2 + ROUND 61, D,E,F,G,H,A,B,C, T1,T2 + ROUND 62, C,D,E,F,G,H,A,B, T1,T2 + ROUND 63, B,C,D,E,F,G,H,A, T1,T2 + + add dword [rdi], A ; update hash + add dword [rdi+sizeof(dword)*1], B + add dword [rdi+sizeof(dword)*2], C + add dword [rdi+sizeof(dword)*3], D + add dword [rdi+sizeof(dword)*4], E + add dword [rdi+sizeof(dword)*5], F + add dword [rdi+sizeof(dword)*6], G + add dword [rdi+sizeof(dword)*7], H + + add rsi, MBS_SHA256 + sub qword [rsp+sizeof(oword)], MBS_SHA256 + jg .sha256_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA256 + +%endif ;; ((_IPP32E >= _IPP32E_U8 ) AND (_IPP32E < _IPP32E_E9 )) OR (_IPP32E == _IPP32E_N8 ) +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA256_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512e9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512e9as.asm new file mode 100644 index 000000000..8c9d5fdbe --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512e9as.asm @@ -0,0 +1,732 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA512 +; +; Content: +; UpdateSHA256 +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA512_) +;;%if (_IPP32E >= _IPP32E_E9) +%if (_IPP32E == _IPP32E_E9 ) + +%xdefine W0 xmm0 +%xdefine W1 xmm1 +%xdefine W2 xmm2 +%xdefine W3 xmm3 +%xdefine W4 xmm4 +%xdefine W5 xmm5 +%xdefine W6 xmm6 +%xdefine W7 xmm7 +%xdefine xT0 xmm8 +%xdefine xT1 xmm9 +%xdefine xT2 xmm10 +%xdefine SIGMA xmm11 + +;; assign hash values to GPU registers +%xdefine A r8 +%xdefine B r9 +%xdefine C r10 +%xdefine D r11 +%xdefine E r12 +%xdefine F r13 +%xdefine G r14 +%xdefine H r15 +%xdefine T1 rax +%xdefine T2 rbx +%xdefine T0 rbp +%xdefine KK_SHA512 rcx + +%macro ROTATE_H 0.nolist + %xdefine %%_TMP H + %xdefine H G + %xdefine G F + %xdefine F E + %xdefine E D + %xdefine D C + %xdefine C B + %xdefine B A + %xdefine A %%_TMP +%endmacro + +%macro ROTATE_W 0.nolist + %xdefine %%DUMMY W0 + %xdefine W0 W1 + %xdefine W1 W2 + %xdefine W2 W3 + %xdefine W3 W4 + %xdefine W4 W5 + %xdefine W5 W6 + %xdefine W6 W7 + %xdefine W7 %%DUMMY +%endmacro + +%macro ROR64 2.nolist + %xdefine %%r %1 + %xdefine %%nbits %2 + + %if _IPP32E >= _IPP32E_L9 + rorx %%r,%%r,%%nbits + %elif _IPP32E >= _IPP32E_Y8 + shld %%r,%%r,(64-%%nbits) + %else + ror %%r,%%nbits + %endif +%endmacro + +;; +;; CHJ(x,y,z) = (x & y) ^ (~x & z) +;; +;; CHJ(x,y,z) = (x & y) ^ (~x & z) +;; = (x&y) ^ ((1^x) &z) +;; = (x&y) ^ (z ^ x&z) +;; = x&y ^ z ^ x&z +;; = x&(y^z) ^z +;; +;; => CHJ(E,F,G) = ((F^G) & E) ^G +;; +%macro CHJ 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%Y + xor %%F, %%Z + and %%F, %%X + xor %%F, %%Z +%endmacro + +;; +;; MAJ(x,y,z) = (x & y) ^ (x & z) ^ (y & z) +;; +;; MAJ(x,y,z) = (x&y) ^ (x&z) ^ (y&z) +;; = (x&y) ^ (x&z) ^ (y&z) ^ (z&z) ^z // note: ((z&z) ^z) = 0 +;; = x&(y^z) ^ z&(y^z) ^z +;; = (x^z)&(y^z) ^z +;; +;; => MAJ(A,B,C) = ((A^C) & B) ^ (A&C) +;; +%macro MAJ 4.nolist + %xdefine %%F %1 + %xdefine %%X %2 + %xdefine %%Y %3 + %xdefine %%Z %4 + + mov %%F, %%X + xor %%F, %%Z ;; maj = x^z + xor %%Y, %%Z ;; y ^= z + and %%F, %%Y ;; maj = (x^z)&(y^z) + xor %%F, %%Z ;; maj = (x^z)&(y^z) ^z + xor %%Y, %%Z ;; restore y +%endmacro + +;; +;; SUM1(x) = ROR64(x,14) ^ ROR64(x,18) ^ ROR64(x,41) +;; +;;=> SUM1(x) = ROR((ROR((ROR(x, 23) ^x), 4) ^x), 14) +;; +%macro SUM1 2.nolist + %xdefine %%F %1 + %xdefine %%X %2 + + mov %%F, %%X + ROR64 %%F, 23 + xor %%F, %%X + ROR64 %%F, 4 + xor %%F, %%X + ROR64 %%F, 14 +%endmacro + +;; +;; SUM0(x) = ROR64(x,28) ^ ROR64(x,34) ^ ROR64(x,39) +;; +;; => SUM0(x) = ROR((ROR((ROR(x, 5) ^x), 6) ^x), 28) +;; +%macro SUM0 2.nolist + %xdefine %%F %1 + %xdefine %%X %2 + + mov %%F, %%X + ROR64 %%F, 5 + xor %%F, %%X + ROR64 %%F, 6 + xor %%F, %%X + ROR64 %%F, 28 +%endmacro + +;; regular SHA512 step +;; +;; Ipp64u T1 = H + SUM1(E) + CHJ(E,F,G) + K_SHA512[t] + W[t]; +;; Ipp64u T2 = SUM0(A) + MAJ(A,B,C); +;; D+= T1; +;; H = T1 + T2; +;; +;; where +;; SUM1(x) = ROR64(x,14) ^ ROR64(x,18) ^ ROR64(x,41) +;; SUM0(x) = ROR64(x,28) ^ ROR64(x,34) ^ ROR64(x,39) +;; +;; CHJ(x,y,z) = (x & y) ^ (~x & z) +;; MAJ(x,y,z) = (x & y) ^ (x & z) ^ (y & z) = (x&y)^((x^y)&z) +;; +%macro SHA512_STEP_v0 1.nolist + %xdefine %%nr %1 + + add H, qword [rsp+(%%nr & 1)*sizeof(qword)] + SUM1 T0, E + CHJ T1, E,F,G + add H, T1 + add H, T0 + + add D, H + + SUM0 T0, A + MAJ T1, A,B,C + add H, T1 + add H, T0 + + ROTATE_H +%endmacro + +%macro SHA512_2step 9.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + + mov T0, %%E ;; T0: SUM1(E) + ROR64 T0, 23 ;; T0: SUM1(E) + add %%H, qword [rsp+(%%nr & 1)*sizeof(qword)] + mov T1, %%F ;; T1: CHJ(E,F,G) + xor T0, %%E ;; T0: SUM1(E) + ROR64 T0, 4 ;; T0: SUM1(E) + xor T1, %%G ;; T1: CHJ(E,G,G) + and T1, %%E ;; T1: CHJ(E,G,G) + xor T0, %%E ;; T0: SUM1(E) + ROR64 T0,14 ;; T0: SUM1(E) + xor T1, %%G ;; T1: CHJ(E,G,G) + add %%H, T1 + add %%H, T0 ;; H += SUM1(E) + CHJ(E,F,G) + K_SHA512[t] + W[t] + + add %%D, %%H + + mov T0, %%A ;; T0: SUM0(A) + ROR64 T0, 5 ;; T0: SUM0(A) + mov T1, %%A ;; T1: MAJ(A,B,C) + xor T1, %%C ;; T1: MAJ(A,B,C) + xor T0, %%A ;; T0: SUM0(A) + ROR64 T0, 6 ;; T0: SUM0(A) + xor %%B, %%C ;; T1: MAJ(A,B,C) + and T1, %%B ;; T1: MAJ(A,B,C) + xor T0, %%A ;; T0: SUM0(A) + ROR64 T0,28 ;; T0: SUM0(A) + xor %%B, %%C ;; T1: MAJ(A,B,C) + xor T1, %%C ;; T1: MAJ(A,B,C) + + add %%H, T0 + add %%H, T1 + + ;ROTATE_H + + mov T0, %%D ;; T0: SUM1(E) + ROR64 T0, 23 ;; T0: SUM1(E) + add %%G, qword [rsp+((%%nr+1) & 1)*sizeof(qword)] + mov T1, %%E ;; T1: CHJ(E,F,G) + xor T0, %%D ;; T0: SUM1(E) + ROR64 T0, 4 ;; T0: SUM1(E) + xor T1, %%F ;; T1: CHJ(E,G,G) + and T1, %%D ;; T1: CHJ(E,G,G) + xor T0, %%D ;; T0: SUM1(E) + ROR64 T0,14 ;; T0: SUM1(E) + xor T1, %%F ;; T1: CHJ(E,G,G) + add %%G, T1 + add %%G, T0 ;; H += SUM1(E) + CHJ(E,F,G) + K_SHA512[t] + W[t] + + add %%C, %%G + + mov T0, %%H ;; T0: SUM0(A) + ROR64 T0, 5 ;; T0: SUM0(A) + mov T1, %%H ;; T1: MAJ(A,B,C) + xor T1, %%B ;; T1: MAJ(A,B,C) + xor T0, %%H ;; T0: SUM0(A) + ROR64 T0, 6 ;; T0: SUM0(A) + xor %%A, %%B ;; T1: MAJ(A,B,C) + and T1, %%A ;; T1: MAJ(A,B,C) + xor T0, %%H ;; T0: SUM0(A) + ROR64 T0,28 ;; T0: SUM0(A) + xor %%A, %%B ;; T1: MAJ(A,B,C) + xor T1, %%B ;; T1: MAJ(A,B,C) + + add %%G, T0 + add %%G, T1 + + ;ROTATE_H +%endmacro + +;; +;; update W[] +;; +;; W[j] = SIG1(W[j- 2]) + W[j- 7] +;; +SIG0(W[j-15]) + W[j-16] +;; +;; SIG0(x) = ROR(x,1) ^ROR(x,8) ^LSR(x,7) +;; SIG1(x) = ROR(x,19)^ROR(x,61) ^LSR(x,6) +;; +%macro SHA512_2Wupdate 0.nolist + vpalignr xT1, W5, W4, 8 ;; xT1 = W[t-7] + vpalignr xT0, W1, W0, 8 ;; xT0 = W[t-15] + vpaddq W0, W0, xT1 ;; W0 = W0 + W[t-7] + + vpsrlq SIGMA, W7, 6 ;; SIG1: W[t-2]>>6 + vpsrlq xT1, W7,61 ;; SIG1: W[t-2]>>61 + vpsllq xT2, W7,(64-61) ;; SIG1: W[t-2]<<(64-61) + vpxor SIGMA, SIGMA, xT1 + vpxor SIGMA, SIGMA, xT2 + vpsrlq xT1, W7,19 ;; SIG1: W[t-2]>>19 + vpsllq xT2, W7,(64-19) ;; SIG1: W[t-2]<<(64-19) + vpxor SIGMA, SIGMA, xT1 + vpxor SIGMA, SIGMA, xT2 + vpaddq W0, W0, SIGMA ;; W0 = W0 + W[t-7] + SIG1(W[t-2]) + + vpsrlq SIGMA, xT0, 7 ;; SIG0: W[t-15]>>7 + vpsrlq xT1, xT0, 1 ;; SIG0: W[t-15]>>1 + vpsllq xT2, xT0,(64-1) ;; SIG0: W[t-15]<<(64-1) + vpxor SIGMA, SIGMA, xT1 + vpxor SIGMA, SIGMA, xT2 + vpsrlq xT1, xT0, 8 ;; SIG0: W[t-15]>>8 + vpsllq xT2, xT0,(64-8) ;; SIG0: W[t-15]<<(64-8) + vpxor SIGMA, SIGMA, xT1 + vpxor SIGMA, SIGMA, xT2 + vpaddq W0, W0, SIGMA ;; W0 = W0 + W[t-7] + SIG1(W[t-2]) +SIG0(W[t-15]) + + ROTATE_W +%endmacro + +%macro SHA512_2step_2Wupdate 9.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + + add %%H, qword [rsp+(%%nr & 1)*sizeof(qword)] + + vpalignr xT1, W5, W4, 8 ;; xT1 = W[t-7] + + mov T0, %%E ;; T0: SUM1(E) + ROR64 T0, 23 ;; T0: SUM1(E) + + vpalignr xT0, W1, W0, 8 ;; xT0 = W[t-15] + + mov T1, %%F ;; T1: CHJ(E,F,G) + xor T0, %%E ;; T0: SUM1(E) + + vpaddq W0, W0, xT1 ;; W0 = W0 + W[t-7] + + ROR64 T0, 4 ;; T0: SUM1(E) + xor T1, %%G ;; T1: CHJ(E,G,G) + + vpsrlq SIGMA, W7, 6 ;; SIG1: W[t-2]>>6 + + and T1, %%E ;; T1: CHJ(E,G,G) + xor T0, %%E ;; T0: SUM1(E) + ROR64 T0,14 ;; T0: SUM1(E) + + vpsrlq xT1, W7,61 ;; SIG1: W[t-2]>>61 + + xor T1, %%G ;; T1: CHJ(E,G,G) + add %%H, T1 + add %%H, T0 ;; H += SUM1(E) + CHJ(E,F,G) + K_SHA512[t] + W[t] + + vpsllq xT2, W7,(64-61) ;; SIG1: W[t-2]<<(64-61) + + add %%D, %%H + mov T0, %%A ;; T0: SUM0(A) + ROR64 T0, 5 ;; T0: SUM0(A) + + vpxor SIGMA, SIGMA, xT1 + + mov T1, %%A ;; T1: MAJ(A,B,C) + xor T1, %%C ;; T1: MAJ(A,B,C) + + vpxor SIGMA, SIGMA, xT2 + + xor T0, %%A ;; T0: SUM0(A) + ROR64 T0, 6 ;; T0: SUM0(A) + + vpsrlq xT1, W7,19 ;; SIG1: W[t-2]>>19 + + xor %%B, %%C ;; T1: MAJ(A,B,C) + and T1, %%B ;; T1: MAJ(A,B,C) + xor T0, %%A ;; T0: SUM0(A) + + vpsllq xT2, W7,(64-19) ;; SIG1: W[t-2]<<(64-19) + + ROR64 T0,28 ;; T0: SUM0(A) + xor %%B, %%C ;; T1: MAJ(A,B,C) + xor T1, %%C ;; T1: MAJ(A,B,C) + + vpxor SIGMA, SIGMA, xT1 + add %%H, T0 + add %%H, T1 + ;ROTATE_H + + vpxor SIGMA, SIGMA, xT2 + + mov T0, %%D ;; T0: SUM1(E) + ROR64 T0, 23 ;; T0: SUM1(E) + + vpaddq W0, W0, SIGMA ;; W0 = W0 + W[t-7] + SIG1(W[t-2]) + + add %%G, qword [rsp+((%%nr+1) & 1)*sizeof(qword)] + mov T1, %%E ;; T1: CHJ(E,F,G) + + vpsrlq SIGMA, xT0, 7 ;; SIG0: W[t-15]>>7 + + xor T0, %%D ;; T0: SUM1(E) + ROR64 T0, 4 ;; T0: SUM1(E) + xor T1, %%F ;; T1: CHJ(E,G,G) + + vpsrlq xT1, xT0, 1 ;; SIG0: W[t-15]>>1 + + and T1, %%D ;; T1: CHJ(E,G,G) + xor T0, %%D ;; T0: SUM1(E) + ROR64 T0,14 ;; T0: SUM1(E) + + vpsllq xT2, xT0,(64-1) ;; SIG0: W[t-15]<<(64-1) + + xor T1, %%F ;; T1: CHJ(E,G,G) + add %%G, T1 + add %%G, T0 ;; H += SUM1(E) + CHJ(E,F,G) + K_SHA512[t] + W[t] + + vpxor SIGMA, SIGMA, xT1 + + add %%C, %%G + mov T0, %%H ;; T0: SUM0(A) + + vpxor SIGMA, SIGMA, xT2 + + ROR64 T0, 5 ;; T0: SUM0(A) + mov T1, %%H ;; T1: MAJ(A,B,C) + + vpsrlq xT1, xT0, 8 ;; SIG0: W[t-15]>>8 + + xor T1, %%B ;; T1: MAJ(A,B,C) + xor T0, %%H ;; T0: SUM0(A) + ROR64 T0, 6 ;; T0: SUM0(A) + + vpsllq xT2, xT0,(64-8) ;; SIG0: W[t-15]<<(64-8) + + xor %%A, %%B ;; T1: MAJ(A,B,C) + and T1, %%A ;; T1: MAJ(A,B,C) + xor T0, %%H ;; T0: SUM0(A) + + vpxor SIGMA, SIGMA, xT1 + + ROR64 T0,28 ;; T0: SUM0(A) + xor %%A, %%B ;; T1: MAJ(A,B,C) + + vpxor SIGMA, SIGMA, xT2 + xor T1, %%B ;; T1: MAJ(A,B,C) + add %%G, T0 + + vpaddq W0, W0, SIGMA ;; W0 = W0 + W[t-7] + SIG1(W[t-2]) +SIG0(W[t-15]) + add %%G, T1 + + ;ROTATE_H + ROTATE_W +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR +SHUFB_BSWAP DB 7,6,5,4,3,2,1,0, 15,14,13,12,11,10,9,8 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; UpdateSHA512(Ipp64u digest[], Ipp8u dataBlock[], int datalen, Ipp64u K_512[]) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA512,PUBLIC +%assign LOCAL_FRAME sizeof(oword)+sizeof(qword) + USES_GPR rbx,rsi,rdi,rbp,r12,r13,r14,r15 + USES_XMM xmm6,xmm7,xmm8,xmm9,xmm10,xmm11 + COMP_ABI 4 +;; +;; rdi = pointer to the updated hash +;; rsi = pointer to the data block +;; rdx = data block length +;; rcx = pointer to the SHA_512 constant +;; + +%xdefine MBS_SHA512 (128) + + vmovdqa xT1, oword [rel SHUFB_BSWAP] + movsxd rdx, edx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +.sha512_block_loop: +;; +;; initialize the first 16 qwords in the array W (remember about endian) +;; + vmovdqu W0, oword [rsi] ; load buffer content and swap + vpshufb W0, W0, xT1 + vmovdqu W1, oword [rsi+sizeof(oword)*1]; + vpshufb W1, W1, xT1 + vmovdqu W2, oword [rsi+sizeof(oword)*2]; + vpshufb W2, W2, xT1 + vmovdqu W3, oword [rsi+sizeof(oword)*3]; + vpshufb W3, W3, xT1 + vmovdqu W4, oword [rsi+sizeof(oword)*4]; + vpshufb W4, W4, xT1 + vmovdqu W5, oword [rsi+sizeof(oword)*5]; + vpshufb W5, W5, xT1 + vmovdqu W6, oword [rsi+sizeof(oword)*6]; + vpshufb W6, W6, xT1 + vmovdqu W7, oword [rsi+sizeof(oword)*7]; + vpshufb W7, W7, xT1 + + mov A, qword [rdi] ; load initial hash value + mov B, qword [rdi+sizeof(qword)] + mov C, qword [rdi+sizeof(qword)*2] + mov D, qword [rdi+sizeof(qword)*3] + mov E, qword [rdi+sizeof(qword)*4] + mov F, qword [rdi+sizeof(qword)*5] + mov G, qword [rdi+sizeof(qword)*6] + mov H, qword [rdi+sizeof(qword)*7] + + ;; perform 0- 9 rounds + vpaddq xT1, W0, oword [KK_SHA512+ 0*sizeof(qword)] ; T += K_SHA512[0-1] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 0, A,B,C,D,E,F,G,H + + vpaddq xT1, W0, oword [KK_SHA512+ 2*sizeof(qword)] ; T += K_SHA512[2-3] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 2, G,H,A,B,C,D,E,F + + vpaddq xT1, W0, oword [KK_SHA512+ 4*sizeof(qword)] ; T += K_SHA512[4-5] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 4, E,F,G,H,A,B,C,D + + vpaddq xT1, W0, oword [KK_SHA512+ 6*sizeof(qword)] ; T += K_SHA512[6-7] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 6, C,D,E,F,G,H,A,B + + vpaddq xT1, W0, oword [KK_SHA512+ 8*sizeof(qword)] ; T += K_SHA512[8-9] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 8, A,B,C,D,E,F,G,H + + ;; perform 10-19 rounds + vpaddq xT1, W0, oword [KK_SHA512+10*sizeof(qword)] ; T += K_SHA512[10-11] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 10, G,H,A,B,C,D,E,F + + vpaddq xT1, W0, oword [KK_SHA512+12*sizeof(qword)] ; T += K_SHA512[12-13] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 12, E,F,G,H,A,B,C,D + + vpaddq xT1, W0, oword [KK_SHA512+14*sizeof(qword)] ; T += K_SHA512[14-15] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 14, C,D,E,F,G,H,A,B + + vpaddq xT1, W0, oword [KK_SHA512+16*sizeof(qword)] ; T += K_SHA512[16-17] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 16, A,B,C,D,E,F,G,H + + vpaddq xT1, W0, oword [KK_SHA512+18*sizeof(qword)] ; T += K_SHA512[18-19] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 18, G,H,A,B,C,D,E,F + + ;; perform 20-29 rounds + vpaddq xT1, W0, oword [KK_SHA512+20*sizeof(qword)] ; T += K_SHA512[20-21] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 20, E,F,G,H,A,B,C,D + + vpaddq xT1, W0, oword [KK_SHA512+22*sizeof(qword)] ; T += K_SHA512[22-23] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 22, C,D,E,F,G,H,A,B + + vpaddq xT1, W0, oword [KK_SHA512+24*sizeof(qword)] ; T += K_SHA512[24-25] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 24, A,B,C,D,E,F,G,H + + vpaddq xT1, W0, oword [KK_SHA512+26*sizeof(qword)] ; T += K_SHA512[26-27] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 26, G,H,A,B,C,D,E,F + + vpaddq xT1, W0, oword [KK_SHA512+28*sizeof(qword)] ; T += K_SHA512[28-29] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 28, E,F,G,H,A,B,C,D + + ;; perform 30-39 rounds + vpaddq xT1, W0, oword [KK_SHA512+30*sizeof(qword)] ; T += K_SHA512[30-31] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 30, C,D,E,F,G,H,A,B + + vpaddq xT1, W0, oword [KK_SHA512+32*sizeof(qword)] ; T += K_SHA512[32-33] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 32, A,B,C,D,E,F,G,H + + vpaddq xT1, W0, oword [KK_SHA512+34*sizeof(qword)] ; T += K_SHA512[34-35] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 34, G,H,A,B,C,D,E,F + + vpaddq xT1, W0, oword [KK_SHA512+36*sizeof(qword)] ; T += K_SHA512[36-37] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 36, E,F,G,H,A,B,C,D + + vpaddq xT1, W0, oword [KK_SHA512+38*sizeof(qword)] ; T += K_SHA512[38-39] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 38, C,D,E,F,G,H,A,B + + ;; perform 40-49 rounds + vpaddq xT1, W0, oword [KK_SHA512+40*sizeof(qword)] ; T += K_SHA512[40-41] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 40, A,B,C,D,E,F,G,H + + vpaddq xT1, W0, oword [KK_SHA512+42*sizeof(qword)] ; T += K_SHA512[42-43] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 42, G,H,A,B,C,D,E,F + + vpaddq xT1, W0, oword [KK_SHA512+44*sizeof(qword)] ; T += K_SHA512[44-45] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 44, E,F,G,H,A,B,C,D + + vpaddq xT1, W0, oword [KK_SHA512+46*sizeof(qword)] ; T += K_SHA512[46-47] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 46, C,D,E,F,G,H,A,B + + vpaddq xT1, W0, oword [KK_SHA512+48*sizeof(qword)] ; T += K_SHA512[48-49] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 48, A,B,C,D,E,F,G,H + + ;; perform 50-59 rounds + vpaddq xT1, W0, oword [KK_SHA512+50*sizeof(qword)] ; T += K_SHA512[50-51] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 50, G,H,A,B,C,D,E,F + + vpaddq xT1, W0, oword [KK_SHA512+52*sizeof(qword)] ; T += K_SHA512[52-53] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 52, E,F,G,H,A,B,C,D + + vpaddq xT1, W0, oword [KK_SHA512+54*sizeof(qword)] ; T += K_SHA512[54-55] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 54, C,D,E,F,G,H,A,B + + vpaddq xT1, W0, oword [KK_SHA512+56*sizeof(qword)] ; T += K_SHA512[56-57] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 56, A,B,C,D,E,F,G,H + + vpaddq xT1, W0, oword [KK_SHA512+58*sizeof(qword)] ; T += K_SHA512[58-59] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 58, G,H,A,B,C,D,E,F + + ;; perform 60-69 rounds + vpaddq xT1, W0, oword [KK_SHA512+60*sizeof(qword)] ; T += K_SHA512[60-61] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 60, E,F,G,H,A,B,C,D + + vpaddq xT1, W0, oword [KK_SHA512+62*sizeof(qword)] ; T += K_SHA512[62-63] + vmovdqa oword [rsp], xT1 + SHA512_2step_2Wupdate 62, C,D,E,F,G,H,A,B + + vpaddq xT1, W0, oword [KK_SHA512+64*sizeof(qword)] ; T += K_SHA512[64-65] + vmovdqa oword [rsp], xT1 + SHA512_2step 64, A,B,C,D,E,F,G,H + ROTATE_W + + vpaddq xT1, W0, oword [KK_SHA512+66*sizeof(qword)] ; T += K_SHA512[66-67] + vmovdqa oword [rsp], xT1 + SHA512_2step 66, G,H,A,B,C,D,E,F + ROTATE_W + + vpaddq xT1, W0, oword [KK_SHA512+68*sizeof(qword)] ; T += K_SHA512[68-69] + vmovdqa oword [rsp], xT1 + SHA512_2step 68, E,F,G,H,A,B,C,D + ROTATE_W + + ;; perform 70-79 rounds + vpaddq xT1, W0, oword [KK_SHA512+70*sizeof(qword)] ; T += K_SHA512[70-71] + vmovdqa oword [rsp], xT1 + SHA512_2step 70, C,D,E,F,G,H,A,B + ROTATE_W + + vpaddq xT1, W0, oword [KK_SHA512+72*sizeof(qword)] ; T += K_SHA512[72-73] + vmovdqa oword [rsp], xT1 + SHA512_2step 72, A,B,C,D,E,F,G,H + ROTATE_W + + vpaddq xT1, W0, oword [KK_SHA512+74*sizeof(qword)] ; T += K_SHA512[74-75] + vmovdqa oword [rsp], xT1 + SHA512_2step 74, G,H,A,B,C,D,E,F + ROTATE_W + + vpaddq xT1, W0, oword [KK_SHA512+76*sizeof(qword)] ; T += K_SHA512[76-77] + vmovdqa oword [rsp], xT1 + SHA512_2step 76, E,F,G,H,A,B,C,D + ROTATE_W + + vpaddq xT1, W0, oword [KK_SHA512+78*sizeof(qword)] ; T += K_SHA512[78-79] + vmovdqa oword [rsp], xT1 + SHA512_2step 78, C,D,E,F,G,H,A,B + ROTATE_W + + add qword [rdi], A ; update shash + add qword [rdi+sizeof(qword)*1], B + add qword [rdi+sizeof(qword)*2], C + add qword [rdi+sizeof(qword)*3], D + add qword [rdi+sizeof(qword)*4], E + add qword [rdi+sizeof(qword)*5], F + add qword [rdi+sizeof(qword)*6], G + add qword [rdi+sizeof(qword)*7], H + + vmovdqa xT1, oword [rel SHUFB_BSWAP] + add rsi, MBS_SHA512 + sub rdx, MBS_SHA512 + jg .sha512_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA512 + +%endif ;; (_IPP32E >= _IPP32E_E9 ) +%endif ;; _ENABLE_ALG_SHA512_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512l9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512l9as.asm new file mode 100644 index 000000000..5cde357a4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512l9as.asm @@ -0,0 +1,635 @@ +;=============================================================================== +; Copyright (C) 2017 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA512 +; +; Content: +; UpdateSHA512 +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "ia_32e_regs.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA512_) +%if (_SHA_NI_ENABLING_ == _FEATURE_OFF_) || (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) +%if (_IPP32E >= _IPP32E_L9 ) + +;; +;; assignments +;; +%xdefine hA rax ;; hash values into GPU registers +%xdefine hB rbx +%xdefine hC rcx +%xdefine hD rdx +%xdefine hE r8 +%xdefine hF r9 +%xdefine hG r10 +%xdefine hH r11 + +%xdefine T1 r12 ;; scratch +%xdefine T2 r13 +%xdefine T3 r14 +%xdefine T4 r15 +%xdefine T5 rdi + +%xdefine W0 ymm0 ;; W values into YMM registers +%xdefine W1 ymm1 +%xdefine W2 ymm2 +%xdefine W3 ymm3 +%xdefine W4 ymm4 +%xdefine W5 ymm5 +%xdefine W6 ymm6 +%xdefine W7 ymm7 + +%xdefine yT1 ymm8 ;; scratch +%xdefine yT2 ymm9 +%xdefine yT3 ymm10 +%xdefine yT4 ymm11 + +%xdefine W0L xmm0 +%xdefine W1L xmm1 +%xdefine W2L xmm2 +%xdefine W3L xmm3 +%xdefine W4L xmm4 +%xdefine W5L xmm5 +%xdefine W6L xmm6 +%xdefine W7L xmm7 + +%xdefine YMM_SHUFB_BSWAP ymm12 ;; byte swap constant + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; textual rotation of W args +;; +%macro ROTATE_W 0.nolist + %xdefine %%_X W0 + %xdefine W0 W1 + %xdefine W1 W2 + %xdefine W2 W3 + %xdefine W3 W4 + %xdefine W4 W5 + %xdefine W5 W6 + %xdefine W6 W7 + %xdefine W7 %%_X +%endmacro + +;; +;; textual rotation of HASH arguments +;; +%macro ROTATE_H 0.nolist + %xdefine %%_X hH + %xdefine hH hG + %xdefine hG hF + %xdefine hF hE + %xdefine hE hD + %xdefine hD hC + %xdefine hC hB + %xdefine hB hA + %xdefine hA %%_X + %endmacro + +%macro ROTATE_T4_T5 0.nolist + %xdefine %%T T4 + %xdefine T4 T5 + %xdefine T5 %%T +%endmacro + +;; +;; update next 2 W[t] and W[t+1], t=16,...79 +;; +;; W[j] = sig1(W[t- 2]) + W[t- 7] +;; +sig0(W[t-15]) + W[t-16] +;; +;; sig0(x) = ROR(x,1) ^ROR(x,8) ^SHR(x,7) +;; = SHR(x,7) +;; ^SHR(x,1) ^SHL(x,63) +;; ^SHR(x,8) ^SHL(x,56) +;; sig1(x) = ROR(x,19)^ROR(x,61) ^SHR(x,6) +;; = SHR(x,6) +;; ^SHR(x,19) ^SHL(x,45) +;; ^SHR(x,61) ^SHL(x,3) +;; +%macro UPDATE_W 9.nolist + %xdefine %%nr %1 + %xdefine %%W0 %2 + %xdefine %%W1 %3 + %xdefine %%W2 %4 + %xdefine %%W3 %5 + %xdefine %%W4 %6 + %xdefine %%W5 %7 + %xdefine %%W6 %8 + %xdefine %%W7 %9 + + %assign %%W_AHEAD 16 + + vpalignr yT1,%%W1,%%W0,sizeof(qword) ;; T1 = {w2:w1} args sig0() + vpalignr yT4,%%W5,%%W4,sizeof(qword) ;; T4 = {w10:w9} additive + vpsrlq yT3,yT1,1 ;; sig0(): T3 = {w2:w1}>>1 + vpaddq %%W0,%%W0,yT4 ;; W0 += {w10:w9} + vpsrlq yT4,yT1,7 ;; sig0(): {w2:w1}>>7 + vpsllq yT2,yT1,56 ;; sig0(): {w2:w1}<<(64-8) + vpxor yT1,yT4,yT3 ;; sig0(): {w2:w1}>>7 ^ {w2:w1}>>1 + vpsrlq yT3,yT3, 7 ;; sig0(): {w2:w1}>>1>>7 = {w2:w1}>>8 + vpxor yT1,yT1,yT2 ;; sig0(): {w2:w1}>>7 ^ {w2:w1}>>1 ^ {w2:w1}<<(64-8) + vpsllq yT2,yT2, 7 ;; sig0(): {w2:w1}<<(64-8)<<7 = {w2:w1}<<63 + vpxor yT1,yT1,yT3 ;; sig0(): {w2:w1}>>7 ^ {w2:w1}>>1 ^ {w2:w1}<<(64-8) ^ {w2:w1}>>8 + vpsrlq yT4,%%W7, 6 ;; sig1(): {w15:w14}>>6 + vpxor yT1,yT1,yT2 ;; sig0()= {w2:w1}>>7 + ;; ^{w2:w1}>>1 ^ {w2:w1}<<63 + ;; ^{w2:w1}<<(64-8) ^ {w2:w1}>>8 + vpsllq yT3,%%W7, 3 ;; sig1(): {w15:w14}<<3 + vpaddq %%W0,%%W0,yT1 ;; W0 += sig0() + vpsrlq yT2,%%W7, 19 ;; sig1(): {w15:w14}>>19 + vpxor yT4,yT4,yT3 ;; sig1(): {w15:w14}>>6 ^ {w15:w14}<<3 + vpsllq yT3,yT3, 42 ;; sig1(): {w15:w14}<<3<<42 = {w15:w14}<<45 + vpxor yT4,yT4,yT2 ;; sig1(): {w15:w14}>>6 ^ {w15:w14}<<3 ^ {w15:w14}>>19 + vpsrlq yT2,yT2,42 ;; sig1(): {w15:w14}>>19>>42= {w15:w14}>>61 + vpxor yT4,yT4,yT3 ;; sig1(): {w15:w14}>>6 ^ {w15:w14}<<3 ^ {w15:w14}>>19 ^ {w15:w14}<<45 + vpxor yT4,yT4,yT2 ;; sig1()= {w15:w14}>>6 + ;; ^{w15:w14}<<3 ^ {w15:w14}>>61 + ;; ^{w15:w14}>>19 ^ {w15:w14}<<45 + vpaddq %%W0,%%W0,yT4 ;; W0 += sig1() + vpaddq yT3,%%W0,YMMWORD [rbp+(%%nr/2)*sizeof(ymmword)] + vmovdqa YMMWORD [rsi+(%%W_AHEAD/2)*sizeof(ymmword)+(%%nr/2)*sizeof(ymmword)],yT3 + ROTATE_W +%endmacro + +;; +;; regular round (i): +;; +;; T1 = h + Sum1(e) + Ch(e,f,g) + K[i] + W[i] +;; T2 = Sum0(a) + Maj(a,b,c) +;; h = g +;; g = f +;; f = e +;; e = d + T1 +;; d = c +;; c = b +;; b = a +;; a = T1+T2 +;; +;; sum1(e) = (e>>>14)^(e>>>18)^(e>>>41) +;; sum0(a) = (a>>>28)^(a>>>34)^(a>>>39) +;; ch(e,f,g) = (e&f)^(~e^g) +;; maj(a,b,m)= (a&b)^(a&c)^(b&c) +;; +;; note: +;; 1) U + ch(e,f,g) = U + (e&f) & (~e&g) +;; 2) maj(a,b,c)= (a&b)^(a&c)^(b&c) = (a^b)&(b^c) ^b +;; to make sure both are correct - use GF(2) arith instead of logic +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; or +;; X = sum0(a[i-1]) computed on prev round +;; a[i] += X +;; h[i] += (K[i]+W[i]) + sum1(e[i]) + ch(e[i],f[i],g[i]) or +;; h[i] += (K[i]+W[i]) + sum1(e[i]) + (e[i]&f[i]) + (~e[i]&g[i]) -- helps break dependencies +;; d[i] += h[i] +;; h[i] += maj(a[i],b[i],c[i]) +;; and following textual shift +;; {a[i+1],b[i+1],c[i+1],d[i+1],e[i+1],f[i+1],g[i+1],h[i+1]} <= {h[i],a[i],b[i],c[i],d[i],e[i],f[i],g[i]} +;; +;; on entry: +;; - T1 = f +;; - T3 = sum0{a[i-1]) +;; - T5 = b&c +%macro SHA512_ROUND 9.nolist + %xdefine %%nr %1 + %xdefine %%hA %2 + %xdefine %%hB %3 + %xdefine %%hC %4 + %xdefine %%hD %5 + %xdefine %%hE %6 + %xdefine %%hF %7 + %xdefine %%hG %8 + %xdefine %%hH %9 + + add %%hH, qword [rsi+(%%nr/2)*sizeof(ymmword)+(%%nr & 1)*sizeof(qword)] ;; h += (k[t]+w[t]) + and T1, %%hE ;; ch(e,f,g): (f&e) + rorx T2, %%hE, 41 ;; sum1(e): e>>>41 + rorx T4, %%hE, 18 ;; sum1(e): e>>>18 + add %%hA, T3 ;; complete computation a += sum0(a[t-1]) + add %%hH, T1 ;; h += (k[t]+w[t]) + (f&e) + andn T1, %%hE, %%hG ;; ch(e,f,g): (~e&g) + xor T2, T4 ;; sum1(e): (e>>>41)^(e>>>18) + rorx T3, %%hE, 14 ;; sum1(e): e>>>14 + add %%hH, T1 ;; h += (k[t]+w[t]) + (f&e) + (~e&g) + xor T2, T3 ;; sum1(e) = (e>>>41)^(e>>>18)^(e>>>14) + mov T4, %%hA ;; maj(a,b,c): a + rorx T1, %%hA, 39 ;; sum0(a): a>>>39 + add %%hH, T2 ;; h += (k[t]+w[t]) +(f&e) +(~e&g) +sig1(e) + xor T4, %%hB ;; maj(a,b,c): (a^b) + rorx T3, %%hA, 34 ;; sum0(a): a>>>34 + rorx T2, %%hA, 28 ;; sum0(a): a>>>28 + add %%hD, %%hH ;; d += h + and T5, T4 ;; maj(a,b,c): (b^c)&(a^b) + xor T3, T1 ;; sum0(a): (a>>>13)^(a>>>22) + xor T5, %%hB ;; maj(a,b,c) = (b^c)&(a^b)^b = (a&b)^(a&c)^(b&c) + xor T3, T2 ;; sum0(a): = (a>>>13)^(a>>>22)^(a>>>2) + add %%hH, T5 ;; h += (k[t]+w[t]) +(f&e) +(~e&g) +sig1(e) +maj(a,b,c) + mov T1, %%hE ;; T1 = f (next round) + ROTATE_T4_T5 ;; T5 = (b^c) (next round) +%endmacro + +;; +;; does 2 regular rounds and computes next 2 W values +;; (just 2 instances of SHA512_ROUND merged together woth UPDATE_W) +;; +%macro SHA512_2ROUND_SHED 1.nolist + %xdefine %%round %1 + + %assign %%W_AHEAD 16 + %assign %%nr %%round + +vpalignr yT1,W1,W0,sizeof(qword) + add hH, qword [rsi+(%%nr/2)*sizeof(ymmword)+(%%nr & 1)*sizeof(qword)] + and T1, hE +vpalignr yT4,W5,W4,sizeof(qword) + rorx T2, hE, 41 + rorx T4, hE, 18 +vpsrlq yT3,yT1,1 + add hA, T3 + add hH, T1 +vpaddq W0,W0,yT4 + andn T1, hE, hG + xor T2, T4 +vpsrlq yT4,yT1,7 + rorx T3, hE, 14 + add hH, T1 +vpsllq yT2,yT1,56 + xor T2, T3 + mov T4, hA +vpxor yT1,yT4,yT3 + rorx T1, hA, 39 + add hH, T2 +vpsrlq yT3,yT3, 7 + xor T4, hB + rorx T3, hA, 34 +vpxor yT1,yT1,yT2 + rorx T2, hA, 28 + add hD, hH +vpsllq yT2,yT2, 7 + and T5, T4 + xor T3, T1 +vpxor yT1,yT1,yT3 + xor T5, hB + xor T3, T2 +vpsrlq yT4,W7, 6 + add hH, T5 + mov T1, hE +vpxor yT1,yT1,yT2 + ROTATE_T4_T5 + ROTATE_H + + %assign %%nr %%nr+1 + add hH, qword [rsi+(%%nr/2)*sizeof(ymmword)+(%%nr & 1)*sizeof(qword)] + and T1, hE +vpsllq yT3,W7, 3 + rorx T2, hE, 41 + rorx T4, hE, 18 +vpaddq W0,W0,yT1 + add hA, T3 + add hH, T1 +vpsrlq yT2,W7, 19 + andn T1, hE, hG + xor T2, T4 +vpxor yT4,yT4,yT3 + rorx T3, hE, 14 + add hH, T1 +vpsllq yT3,yT3, 42 + xor T2, T3 + mov T4, hA +vpxor yT4,yT4,yT2 + rorx T1, hA, 39 + add hH, T2 +vpsrlq yT2,yT2,42 + xor T4, hB + rorx T3, hA, 34 +vpxor yT4,yT4,yT3 + rorx T2, hA, 28 + add hD, hH +vpxor yT4,yT4,yT2 + and T5, T4 + xor T3, T1 +vpaddq W0,W0,yT4 + xor T5, hB + xor T3, T2 +vpaddq yT3,W0,YMMWORD [rbp+(%%nr/2)*sizeof(ymmword)] + add hH, T5 + mov T1, hE +vmovdqa YMMWORD [rsi+(%%W_AHEAD/2)*sizeof(ymmword)+(%%nr/2)*sizeof(ymmword)],yT3 + ROTATE_T4_T5 + ROTATE_H + ROTATE_W +%endmacro + +;; +;; update hash +;; +%macro UPDATE_HASH 2.nolist + %xdefine %%hashMem %1 + %xdefine %%hash %2 + + add %%hash, %%hashMem + mov %%hashMem, %%hash +%endmacro + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +SHA512_YMM_K dq 0428a2f98d728ae22h, 07137449123ef65cdh, 0428a2f98d728ae22h, 07137449123ef65cdh + dq 0b5c0fbcfec4d3b2fh, 0e9b5dba58189dbbch, 0b5c0fbcfec4d3b2fh, 0e9b5dba58189dbbch + dq 03956c25bf348b538h, 059f111f1b605d019h, 03956c25bf348b538h, 059f111f1b605d019h + dq 0923f82a4af194f9bh, 0ab1c5ed5da6d8118h, 0923f82a4af194f9bh, 0ab1c5ed5da6d8118h + dq 0d807aa98a3030242h, 012835b0145706fbeh, 0d807aa98a3030242h, 012835b0145706fbeh + dq 0243185be4ee4b28ch, 0550c7dc3d5ffb4e2h, 0243185be4ee4b28ch, 0550c7dc3d5ffb4e2h + dq 072be5d74f27b896fh, 080deb1fe3b1696b1h, 072be5d74f27b896fh, 080deb1fe3b1696b1h + dq 09bdc06a725c71235h, 0c19bf174cf692694h, 09bdc06a725c71235h, 0c19bf174cf692694h + dq 0e49b69c19ef14ad2h, 0efbe4786384f25e3h, 0e49b69c19ef14ad2h, 0efbe4786384f25e3h + dq 00fc19dc68b8cd5b5h, 0240ca1cc77ac9c65h, 00fc19dc68b8cd5b5h, 0240ca1cc77ac9c65h + dq 02de92c6f592b0275h, 04a7484aa6ea6e483h, 02de92c6f592b0275h, 04a7484aa6ea6e483h + dq 05cb0a9dcbd41fbd4h, 076f988da831153b5h, 05cb0a9dcbd41fbd4h, 076f988da831153b5h + dq 0983e5152ee66dfabh, 0a831c66d2db43210h, 0983e5152ee66dfabh, 0a831c66d2db43210h + dq 0b00327c898fb213fh, 0bf597fc7beef0ee4h, 0b00327c898fb213fh, 0bf597fc7beef0ee4h + dq 0c6e00bf33da88fc2h, 0d5a79147930aa725h, 0c6e00bf33da88fc2h, 0d5a79147930aa725h + dq 006ca6351e003826fh, 0142929670a0e6e70h, 006ca6351e003826fh, 0142929670a0e6e70h + dq 027b70a8546d22ffch, 02e1b21385c26c926h, 027b70a8546d22ffch, 02e1b21385c26c926h + dq 04d2c6dfc5ac42aedh, 053380d139d95b3dfh, 04d2c6dfc5ac42aedh, 053380d139d95b3dfh + dq 0650a73548baf63deh, 0766a0abb3c77b2a8h, 0650a73548baf63deh, 0766a0abb3c77b2a8h + dq 081c2c92e47edaee6h, 092722c851482353bh, 081c2c92e47edaee6h, 092722c851482353bh + dq 0a2bfe8a14cf10364h, 0a81a664bbc423001h, 0a2bfe8a14cf10364h, 0a81a664bbc423001h + dq 0c24b8b70d0f89791h, 0c76c51a30654be30h, 0c24b8b70d0f89791h, 0c76c51a30654be30h + dq 0d192e819d6ef5218h, 0d69906245565a910h, 0d192e819d6ef5218h, 0d69906245565a910h + dq 0f40e35855771202ah, 0106aa07032bbd1b8h, 0f40e35855771202ah, 0106aa07032bbd1b8h + dq 019a4c116b8d2d0c8h, 01e376c085141ab53h, 019a4c116b8d2d0c8h, 01e376c085141ab53h + dq 02748774cdf8eeb99h, 034b0bcb5e19b48a8h, 02748774cdf8eeb99h, 034b0bcb5e19b48a8h + dq 0391c0cb3c5c95a63h, 04ed8aa4ae3418acbh, 0391c0cb3c5c95a63h, 04ed8aa4ae3418acbh + dq 05b9cca4f7763e373h, 0682e6ff3d6b2b8a3h, 05b9cca4f7763e373h, 0682e6ff3d6b2b8a3h + dq 0748f82ee5defb2fch, 078a5636f43172f60h, 0748f82ee5defb2fch, 078a5636f43172f60h + dq 084c87814a1f0ab72h, 08cc702081a6439ech, 084c87814a1f0ab72h, 08cc702081a6439ech + dq 090befffa23631e28h, 0a4506cebde82bde9h, 090befffa23631e28h, 0a4506cebde82bde9h + dq 0bef9a3f7b2c67915h, 0c67178f2e372532bh, 0bef9a3f7b2c67915h, 0c67178f2e372532bh + dq 0ca273eceea26619ch, 0d186b8c721c0c207h, 0ca273eceea26619ch, 0d186b8c721c0c207h + dq 0eada7dd6cde0eb1eh, 0f57d4f7fee6ed178h, 0eada7dd6cde0eb1eh, 0f57d4f7fee6ed178h + dq 006f067aa72176fbah, 00a637dc5a2c898a6h, 006f067aa72176fbah, 00a637dc5a2c898a6h + dq 0113f9804bef90daeh, 01b710b35131c471bh, 0113f9804bef90daeh, 01b710b35131c471bh + dq 028db77f523047d84h, 032caab7b40c72493h, 028db77f523047d84h, 032caab7b40c72493h + dq 03c9ebe0a15c9bebch, 0431d67c49c100d4ch, 03c9ebe0a15c9bebch, 0431d67c49c100d4ch + dq 04cc5d4becb3e42b6h, 0597f299cfc657e2ah, 04cc5d4becb3e42b6h, 0597f299cfc657e2ah + dq 05fcb6fab3ad6faech, 06c44198c4a475817h, 05fcb6fab3ad6faech, 06c44198c4a475817h + +SHA512_YMM_BF dq 00001020304050607h, 008090a0b0c0d0e0fh, 00001020304050607h, 008090a0b0c0d0e0fh + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; UpdateSHA512(Ipp64u digest[], Ipp8u dataBlock[], int datalen, Ipp64u K_512[]) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA512,PUBLIC +%assign LOCAL_FRAME (sizeof(qword)*4 + sizeof(qword)*80*2) + USES_GPR rbx,rsi,rdi,rbp,rbx,r12,r13,r14,r15 + USES_XMM_AVX xmm6,xmm7,xmm8,xmm9,xmm10,xmm11,xmm12 + COMP_ABI 4 +;; +;; rdi = pointer to the updated hash +;; rsi = pointer to the data block +;; rdx = data block length +;; rcx = pointer to the SHA_512 constant (ignored) +;; + +%xdefine MBS_SHA512 (128) + +;; +;; stack structure: +;; +%assign _block 0 ;; block address +%assign _hash _block+sizeof(qword) ;; hash address +%assign _len _hash+sizeof(qword) ;; rest of processed data +%assign _frame _len+sizeof(qword) ;; rsp before alignment +%assign _dataW _frame+sizeof(qword) ;; W[t] values + + mov r15, rsp ; store orifinal rsp + and rsp, -IPP_ALIGN_FACTOR ; 32-byte aligned stack + + movsxd r14, edx ; input length in bytes + + mov qword [rsp+_hash], rdi ; store hash address + mov qword [rsp+_len], r14 ; store length + mov qword [rsp+_frame], r15 ; store rsp + + vmovdqa YMM_SHUFB_BSWAP, ymmword [rel SHA512_YMM_BF] ; load byte shuffler + + mov hA, qword [rdi] ; load initial hash value + mov hB, qword [rdi+1*sizeof(qword)] + mov hC, qword [rdi+2*sizeof(qword)] + mov hD, qword [rdi+3*sizeof(qword)] + mov hE, qword [rdi+4*sizeof(qword)] + mov hF, qword [rdi+5*sizeof(qword)] + mov hG, qword [rdi+6*sizeof(qword)] + mov hH, qword [rdi+7*sizeof(qword)] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data 2 block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +.sha512_block2_loop: + lea r12, [rsi+MBS_SHA512] ; next block + + cmp r14, MBS_SHA512 ; %if single block processed + cmovbe r12, rsi ; use the same data block address + + lea rbp, [rel SHA512_YMM_K] ; to SHA512 consts + + vmovdqu W0L, xmmword [rsi] ; load data block + vmovdqu W1L, xmmword [rsi+1*sizeof(xmmword)] + vmovdqu W2L, xmmword [rsi+2*sizeof(xmmword)] + vmovdqu W3L, xmmword [rsi+3*sizeof(xmmword)] + vmovdqu W4L, xmmword [rsi+4*sizeof(xmmword)] + vmovdqu W5L, xmmword [rsi+5*sizeof(xmmword)] + vmovdqu W6L, xmmword [rsi+6*sizeof(xmmword)] + vmovdqu W7L, xmmword [rsi+7*sizeof(xmmword)] + + vinserti128 W0, W0, xmmword [r12], 1 ; merge next data block + vinserti128 W1, W1, xmmword [r12+1*sizeof(xmmword)], 1 + vinserti128 W2, W2, xmmword [r12+2*sizeof(xmmword)], 1 + vinserti128 W3, W3, xmmword [r12+3*sizeof(xmmword)], 1 + vinserti128 W4, W4, xmmword [r12+4*sizeof(xmmword)], 1 + vinserti128 W5, W5, xmmword [r12+5*sizeof(xmmword)], 1 + vinserti128 W6, W6, xmmword [r12+6*sizeof(xmmword)], 1 + vinserti128 W7, W7, xmmword [r12+7*sizeof(xmmword)], 1 + + vpshufb W0, W0, YMM_SHUFB_BSWAP + vpshufb W1, W1, YMM_SHUFB_BSWAP + vpshufb W2, W2, YMM_SHUFB_BSWAP + vpshufb W3, W3, YMM_SHUFB_BSWAP + vpshufb W4, W4, YMM_SHUFB_BSWAP + vpshufb W5, W5, YMM_SHUFB_BSWAP + vpshufb W6, W6, YMM_SHUFB_BSWAP + vpshufb W7, W7, YMM_SHUFB_BSWAP + + vpaddq yT1, W0, ymmword [rbp] + vmovdqa ymmword [rsp+_dataW], yT1 + vpaddq yT2, W1, ymmword [rbp+1*sizeof(ymmword)] + vmovdqa ymmword [rsp+_dataW+1*sizeof(ymmword)], yT2 + vpaddq yT3, W2, ymmword [rbp+2*sizeof(ymmword)] + vmovdqa ymmword [rsp+_dataW+2*sizeof(ymmword)], yT3 + vpaddq yT4, W3, ymmword [rbp+3*sizeof(ymmword)] + vmovdqa ymmword [rsp+_dataW+3*sizeof(ymmword)], yT4 + + vpaddq yT1, W4, ymmword [rbp+4*sizeof(ymmword)] + vmovdqa ymmword [rsp+_dataW+4*sizeof(ymmword)], yT1 + vpaddq yT2, W5, ymmword [rbp+5*sizeof(ymmword)] + vmovdqa ymmword [rsp+_dataW+5*sizeof(ymmword)], yT2 + vpaddq yT3, W6, ymmword [rbp+6*sizeof(ymmword)] + vmovdqa ymmword [rsp+_dataW+6*sizeof(ymmword)], yT3 + vpaddq yT4, W7, ymmword [rbp+7*sizeof(ymmword)] + vmovdqa ymmword [rsp+_dataW+7*sizeof(ymmword)], yT4 + + add rbp, 8*sizeof(ymmword) + + mov T5, hB ; T5 = b^c + xor T3, T3 ; T3 = 0 + mov T1, hF ; T1 = f + xor T5, hC + + mov qword [rsp+_block], rsi ; store block addres + lea rsi, [rsp+_dataW] ; use rsi as stack pointer + +align IPP_ALIGN_FACTOR +.block1_shed_proc: + SHA512_2ROUND_SHED 0 + SHA512_2ROUND_SHED 2 + SHA512_2ROUND_SHED 4 + SHA512_2ROUND_SHED 6 + SHA512_2ROUND_SHED 8 + SHA512_2ROUND_SHED 10 + SHA512_2ROUND_SHED 12 + SHA512_2ROUND_SHED 14 + + add rsi, 8*sizeof(ymmword) + add rbp, 8*sizeof(ymmword) + + ;; and repeat + cmp dword [rbp-sizeof(qword)],04a475817h + jne .block1_shed_proc + + ;; the rest 16 rounds + SHA512_ROUND 0, hA,hB,hC,hD,hE,hF,hG,hH + SHA512_ROUND 1, hH,hA,hB,hC,hD,hE,hF,hG + SHA512_ROUND 2, hG,hH,hA,hB,hC,hD,hE,hF + SHA512_ROUND 3, hF,hG,hH,hA,hB,hC,hD,hE + SHA512_ROUND 4, hE,hF,hG,hH,hA,hB,hC,hD + SHA512_ROUND 5, hD,hE,hF,hG,hH,hA,hB,hC + SHA512_ROUND 6, hC,hD,hE,hF,hG,hH,hA,hB + SHA512_ROUND 7, hB,hC,hD,hE,hF,hG,hH,hA + SHA512_ROUND 8, hA,hB,hC,hD,hE,hF,hG,hH + SHA512_ROUND 9, hH,hA,hB,hC,hD,hE,hF,hG + SHA512_ROUND 10, hG,hH,hA,hB,hC,hD,hE,hF + SHA512_ROUND 11, hF,hG,hH,hA,hB,hC,hD,hE + SHA512_ROUND 12, hE,hF,hG,hH,hA,hB,hC,hD + SHA512_ROUND 13, hD,hE,hF,hG,hH,hA,hB,hC + SHA512_ROUND 14, hC,hD,hE,hF,hG,hH,hA,hB + SHA512_ROUND 15, hB,hC,hD,hE,hF,hG,hH,hA + add hA, T3 + + sub rsi, ((80-16)/2)*sizeof(ymmword) ; restore stack to W + + mov rdi, qword [rsi+_hash-_dataW] ; restore hash pointer + mov r14, qword [rsi+_len-_dataW] ; restore data length + + ;; update hash values by 1-st data block + UPDATE_HASH qword [rdi], hA + UPDATE_HASH qword [rdi+1*sizeof(qword)], hB + UPDATE_HASH qword [rdi+2*sizeof(qword)], hC + UPDATE_HASH qword [rdi+3*sizeof(qword)], hD + UPDATE_HASH qword [rdi+4*sizeof(qword)], hE + UPDATE_HASH qword [rdi+5*sizeof(qword)], hF + UPDATE_HASH qword [rdi+6*sizeof(qword)], hG + UPDATE_HASH qword [rdi+7*sizeof(qword)], hH + + cmp r14, MBS_SHA512*2 + jl .done + + ;; do 80 rounds for the next block + add rsi, 2*sizeof(qword) ; restore stack to next block W + lea rbp, [rsi+40*sizeof(ymmword)] ; use rbp for loop limiter + + mov T5, hB ; T5 = b^c + xor T3, T3 ; T3 = 0 + mov T1, hF ; T1 = f + xor T5, hC + +align IPP_ALIGN_FACTOR +.block2_proc: + SHA512_ROUND 0, hA,hB,hC,hD,hE,hF,hG,hH + SHA512_ROUND 1, hH,hA,hB,hC,hD,hE,hF,hG + SHA512_ROUND 2, hG,hH,hA,hB,hC,hD,hE,hF + SHA512_ROUND 3, hF,hG,hH,hA,hB,hC,hD,hE + SHA512_ROUND 4, hE,hF,hG,hH,hA,hB,hC,hD + SHA512_ROUND 5, hD,hE,hF,hG,hH,hA,hB,hC + SHA512_ROUND 6, hC,hD,hE,hF,hG,hH,hA,hB + SHA512_ROUND 7, hB,hC,hD,hE,hF,hG,hH,hA + add rsi, 4*sizeof(ymmword) + cmp rsi, rbp + jb .block2_proc + add hA, T3 + + mov rdi, qword [rsp+_hash] ; restore hash pointer + mov r14, qword [rsp+_len] ; restore data length + + ;; update hash values by 1-st data block + UPDATE_HASH qword [rdi], hA + UPDATE_HASH qword [rdi+1*sizeof(qword)], hB + UPDATE_HASH qword [rdi+2*sizeof(qword)], hC + UPDATE_HASH qword [rdi+3*sizeof(qword)], hD + UPDATE_HASH qword [rdi+4*sizeof(qword)], hE + UPDATE_HASH qword [rdi+5*sizeof(qword)], hF + UPDATE_HASH qword [rdi+6*sizeof(qword)], hG + UPDATE_HASH qword [rdi+7*sizeof(qword)], hH + + mov rsi, qword [rsp+_block] ; restore block addres + add rsi, MBS_SHA512*2 ; move data pointer + sub r14, MBS_SHA512*2 ; update data length + mov qword [rsp+_len], r14 + jg .sha512_block2_loop + +.done: + mov rsp, qword [rsp+_frame] + REST_XMM_AVX + REST_GPR + ret +ENDFUNC UpdateSHA512 + +%endif ;; _IPP32E_L9 and above +%endif ;; _FEATURE_OFF_ / _FEATURE_TICKTOCK_ +%endif ;; _ENABLE_ALG_SHA512_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512m7as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512m7as.asm new file mode 100644 index 000000000..c38c38a62 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsha512m7as.asm @@ -0,0 +1,490 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SHA512 +; +; Content: +; UpdateSHA512 +; +; +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SHA512_) +%if (_IPP32E >= _IPP32E_M7) && (_IPP32E < _IPP32E_E9 ) + + +;; +;; ENDIANNESS +;; +%macro ENDIANNESS 2.nolist + %xdefine %%dst %1 + %xdefine %%src %2 + + %ifnidn %%dst,%%src + mov %%dst,%%src + %endif + bswap %%dst +%endmacro + +%macro ROT_R 2.nolist + %xdefine %%r %1 + %xdefine %%nbits %2 + + %if _IPP32E >= _IPP32E_L9 + rorx %%r,%%r,%%nbits + ;; %elif _IPP32E >= _IPP32E_Y8 + ;; shrd %%r,%%r,%%nbits + %else + ror %%r,%%nbits + %endif +%endmacro + +;; +;; SHA512 step +;; +;; Ipp64u T1 = H + SUM1(E) + CH(E,F,G) + K_SHA512[t] + W[t]; +;; Ipp64u T2 = SUM0(A) + MAJ(A,B,C); +;; D+= T1; +;; H = T1 + T2; +;; +;; where +;; SUM1(x) = ROR64(x,14) ^ ROR64(x,18) ^ ROR64(x,41) +;; SUM0(x) = ROR64(x,28) ^ ROR64(x,34) ^ ROR64(x,39) +;; +;; CHJ(x,y,z) = (x & y) ^ (~x & z) +;; MAJ(x,y,z) = (x & y) ^ (x & z) ^ (y & z) = (x&y)^((x^y)&z) +;; +%macro SHA512_STEP_2 13.nolist + %xdefine %%regA %1 + %xdefine %%regB %2 + %xdefine %%regC %3 + %xdefine %%regD %4 + %xdefine %%regE %5 + %xdefine %%regF %6 + %xdefine %%regG %7 + %xdefine %%regH %8 + %xdefine %%regT %9 + %xdefine %%regF1 %10 + %xdefine %%regF2 %11 + %xdefine %%memW %12 + %xdefine %%memCNT %13 + + ;; update H (start) + add %%regH,[%%memCNT] ;; H += W[t]+K_SHA512[t] + add %%regH,[%%memW] + + ;; compute T = SUM1(E) + CH(E,F,G) + mov %%regF1,%%regE ;; SUM1() = E + mov %%regF2,%%regE ;; CH() = E + ROT_R %%regF1,14 ;; ROR(E,14) + mov %%regT, %%regE + push %%regE + not %%regF2 ;; ~E + ROT_R %%regE, 18 ;; ROR(E,18) + and %%regT, %%regF ;; E&F + and %%regF2,%%regG ;;~E&G + xor %%regF1,%%regE ;; ROR(E,14)^ROR(E,18) + ROT_R %%regE, 23 ;; ROR(E,41) + xor %%regF2,%%regT ;; CH() = (E&F)&(~E&G) + xor %%regF1,%%regE ;; SUM1() = ROR(E,14)^ROR(E,18)^ROR(E,41) + pop %%regE ;; repair E + lea %%regT, [%%regF1+%%regF2] + + ;; update H (continue) + add %%regH, %%regT + + ;; update D + add %%regD, %%regH + + ;; compute T = SUM0(A) + MAJ(A,B,C) + mov %%regF1,%%regA ;; SUM0() = A + mov %%regF2,%%regA ;; MAJ() = A + ROT_R %%regF1,28 ;; ROR(A,28) + mov %%regT, %%regA + push %%regA + xor %%regF2,%%regB ;; A^B + ROT_R %%regA, 34 ;; ROR(A,34) + and %%regT, %%regB ;; A&B + and %%regF2,%%regC ;; (A^B)&C + xor %%regF1,%%regA ;; ROR(A,2)^ROR(A,13) + ROT_R %%regA, 5 ;; ROR(A,39) + xor %%regF2,%%regT ;; MAJ() = (A^B)^((A^B)&C) + xor %%regF1,%%regA ;; SUM0() = ROR(A,28)^ROR(A,34)^ROR(A,39) + pop %%regA ;; repair A + lea %%regT, [%%regF1+%%regF2] + + ;; update H (finish) + add %%regH, %%regT +%endmacro + +;; +;; update W[] +;; +;; W[j] = SIG1(W[j- 2]) + W[j- 7] +;; +SIG0(W[j-15]) + W[j-16] +;; +;; SIG0(x) = ROR(x,1) ^ROR(x,8) ^LSR(x,7) +;; SIG1(x) = ROR(x,19)^ROR(x,61) ^LSR(x,6) +;; +%macro UPDATE_2 5.nolist + %xdefine %%nr %1 + %xdefine %%sig0 %2 + %xdefine %%sig1 %3 + %xdefine %%W15 %4 + %xdefine %%W2 %5 + + mov %%sig0, [rsp+((%%nr-15) & 0Fh)*8] ;; W[j-15] + mov %%sig1, [rsp+((%%nr-2) & 0Fh)*8] ;; W[j-2] + shr %%sig0, 7 ;; LSR(W[j-15], 7) + shr %%sig1, 6 ;; LSR(W[j-2], 6) + + mov %%W15, [rsp+((%%nr-15) & 0Fh)*8] ;; W[j-15] + mov %%W2, [rsp+((%%nr-2) & 0Fh)*8] ;; W[j-2] + ROT_R %%W15, 1 ;; ROR(W[j-15], 1) + ROT_R %%W2, 19 ;; ROR(W[j-2], 19) + xor %%sig0, %%W15 ;; SIG0 ^= ROR(W[j-15], 1) + xor %%sig1, %%W2 ;; SIG1 ^= ROR(W[j-2], 19) + + ROT_R %%W15, 7 ;; ROR(W[j-15], 8) + ROT_R %%W2, 42 ;; ROR(W[j-2], 61) + xor %%sig0, %%W15 ;; SIG0 ^= ROR(W[j-15], 8) + xor %%sig1, %%W2 ;; SIG1 ^= ROR(W[j-2], 61) + + add %%sig0, [rsp+((%%nr-16) & 0Fh)*8] ;; SIG0 += W[j-16] + add %%sig1, [rsp+((%%nr-7) & 0Fh)*8] ;; SIG1 += W[j-7] + add %%sig0, %%sig1 + mov [rsp+((%%nr-16) & 0Fh)*8], %%sig0 +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + + +;****************************************************************************************** +;* Purpose: Update internal digest according to message block +;* +;* void UpdateSHA512(DigestSHA512 digest, const Ipp32u* mblk, int mlen, const void* pParam) +;* +;****************************************************************************************** + +;; +;; Lib = M7 +;; +;; Caller = ippsSHA512Update +;; Caller = ippsSHA512Final +;; Caller = ippsSHA512MessageDigest +;; +;; Caller = ippsSHA384Update +;; Caller = ippsSHA384Final +;; Caller = ippsSHA384MessageDigest +;; +;; Caller = ippsHMACSHA512Update +;; Caller = ippsHMACSHA512Final +;; Caller = ippsHMACSHA512MessageDigest +;; +;; Caller = ippsHMACSHA384Update +;; Caller = ippsHMACSHA384Final +;; Caller = ippsHMACSHA384MessageDigest +;; + +%xdefine KK_SHA512 rbp + +%if _IPP32E >= _IPP32E_U8 +align IPP_ALIGN_FACTOR +pByteSwp DB 7,6,5,4,3,2,1,0, 15,14,13,12,11,10,9,8 +%endif + +align IPP_ALIGN_FACTOR +IPPASM UpdateSHA512,PUBLIC +%assign LOCAL_FRAME (16*sizeof(qword)+sizeof(qword)) + USES_GPR rbx,rsi,rdi,r12,r13,r14,r15,rbp + USES_XMM + COMP_ABI 4 + +;; rdi = hash +;; rsi = data buffer +;; rdx = buffer length +;; rcx = address of SHA512 constants + +%xdefine MBS_SHA512 (128) + + movsxd rdx, edx + mov qword [rsp+16*sizeof(qword)], rdx ; save length of buffer + + mov KK_SHA512, rcx + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process next data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align IPP_ALIGN_FACTOR +.sha512_block_loop: + +;; +;; initialize the first 16 qwords in the array W (remember about endian) +;; +%if (_IPP32E >= _IPP32E_U8) + movdqu xmm4, oword [rel pByteSwp] + + movdqu xmm0, oword [rsi+0*16] + pshufb xmm0, xmm4 + movdqa oword [rsp+0*16], xmm0 + movdqu xmm1, oword [rsi+1*16] + pshufb xmm1, xmm4 + movdqa oword [rsp+1*16], xmm1 + movdqu xmm2, oword [rsi+2*16] + pshufb xmm2, xmm4 + movdqa oword [rsp+2*16], xmm2 + movdqu xmm3, oword [rsi+3*16] + pshufb xmm3, xmm4 + movdqa oword [rsp+3*16], xmm3 + + movdqu xmm0, oword [rsi+4*16] + pshufb xmm0, xmm4 + movdqa oword [rsp+4*16], xmm0 + movdqu xmm1, oword [rsi+5*16] + pshufb xmm1, xmm4 + movdqa oword [rsp+5*16], xmm1 + movdqu xmm2, oword [rsi+6*16] + pshufb xmm2, xmm4 + movdqa oword [rsp+6*16], xmm2 + movdqu xmm3, oword [rsi+7*16] + pshufb xmm3, xmm4 + movdqa oword [rsp+7*16], xmm3 +%else + xor rcx,rcx + +align IPP_ALIGN_FACTOR +.loop1: + mov r8,[rsi+rcx*8+0*8] + ENDIANNESS r8,r8 + mov [rsp+rcx*8+0*8],r8 + + mov r9,[rsi+rcx*8+1*8] + ENDIANNESS r9,r9 + mov [rsp+rcx*8+1*8],r9 + + add rcx,2 + cmp rcx,16 + jl .loop1 +%endif + +;; +;; init A,B,C,D,E,F,G,H by the internal digest +;; +;; +;; init A, B, C, D, E, F, G, H by the internal digest +;; + mov r8, [rdi+0*8] ; r8 = digest[0] (A) + mov r9, [rdi+1*8] ; r9 = digest[1] (B) + mov r10,[rdi+2*8] ; r10= digest[2] (C) + mov r11,[rdi+3*8] ; r11= digest[3] (D) + mov r12,[rdi+4*8] ; r12= digest[4] (E) + mov r13,[rdi+5*8] ; r13= digest[5] (F) + mov r14,[rdi+6*8] ; r14= digest[6] (G) + mov r15,[rdi+7*8] ; r15= digest[7] (H) + +;; +;; perform 0-79 steps +;; +;; A, B, C, D, E, F, G, H W[], K[] +;; ------------------------------------------------------------------------- + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*8}, {KK_SHA512+ 0*8} + UPDATE_2 16, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*8}, {KK_SHA512+ 1*8} + UPDATE_2 17, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*8}, {KK_SHA512+ 2*8} + UPDATE_2 18, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*8}, {KK_SHA512+ 3*8} + UPDATE_2 19, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*8}, {KK_SHA512+ 4*8} + UPDATE_2 20, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*8}, {KK_SHA512+ 5*8} + UPDATE_2 21, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*8}, {KK_SHA512+ 6*8} + UPDATE_2 22, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*8}, {KK_SHA512+ 7*8} + UPDATE_2 23, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*8}, {KK_SHA512+ 8*8} + UPDATE_2 24, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*8}, {KK_SHA512+ 9*8} + UPDATE_2 25, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*8}, {KK_SHA512+10*8} + UPDATE_2 26, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*8}, {KK_SHA512+11*8} + UPDATE_2 27, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*8}, {KK_SHA512+12*8} + UPDATE_2 28, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*8}, {KK_SHA512+13*8} + UPDATE_2 29, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*8}, {KK_SHA512+14*8} + UPDATE_2 30, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*8}, {KK_SHA512+15*8} + UPDATE_2 31, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*8}, {KK_SHA512+16*8} + UPDATE_2 32, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*8}, {KK_SHA512+17*8} + UPDATE_2 33, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*8}, {KK_SHA512+18*8} + UPDATE_2 34, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*8}, {KK_SHA512+19*8} + UPDATE_2 35, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*8}, {KK_SHA512+20*8} + UPDATE_2 36, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*8}, {KK_SHA512+21*8} + UPDATE_2 37, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*8}, {KK_SHA512+22*8} + UPDATE_2 38, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*8}, {KK_SHA512+23*8} + UPDATE_2 39, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*8}, {KK_SHA512+24*8} + UPDATE_2 40, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*8}, {KK_SHA512+25*8} + UPDATE_2 41, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*8}, {KK_SHA512+26*8} + UPDATE_2 42, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*8}, {KK_SHA512+27*8} + UPDATE_2 43, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*8}, {KK_SHA512+28*8} + UPDATE_2 44, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*8}, {KK_SHA512+29*8} + UPDATE_2 45, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*8}, {KK_SHA512+30*8} + UPDATE_2 46, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*8}, {KK_SHA512+31*8} + UPDATE_2 47, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*8}, {KK_SHA512+32*8} + UPDATE_2 48, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*8}, {KK_SHA512+33*8} + UPDATE_2 49, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*8}, {KK_SHA512+34*8} + UPDATE_2 50, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*8}, {KK_SHA512+35*8} + UPDATE_2 51, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*8}, {KK_SHA512+36*8} + UPDATE_2 52, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*8}, {KK_SHA512+37*8} + UPDATE_2 53, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*8}, {KK_SHA512+38*8} + UPDATE_2 54, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*8}, {KK_SHA512+39*8} + UPDATE_2 55, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*8}, {KK_SHA512+40*8} + UPDATE_2 56, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*8}, {KK_SHA512+41*8} + UPDATE_2 57, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*8}, {KK_SHA512+42*8} + UPDATE_2 58, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*8}, {KK_SHA512+43*8} + UPDATE_2 59, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*8}, {KK_SHA512+44*8} + UPDATE_2 60, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*8}, {KK_SHA512+45*8} + UPDATE_2 61, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*8}, {KK_SHA512+46*8} + UPDATE_2 62, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*8}, {KK_SHA512+47*8} + UPDATE_2 63, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*8}, {KK_SHA512+48*8} + UPDATE_2 64, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*8}, {KK_SHA512+49*8} + UPDATE_2 65, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*8}, {KK_SHA512+50*8} + UPDATE_2 66, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*8}, {KK_SHA512+51*8} + UPDATE_2 67, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*8}, {KK_SHA512+52*8} + UPDATE_2 68, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*8}, {KK_SHA512+53*8} + UPDATE_2 69, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*8}, {KK_SHA512+54*8} + UPDATE_2 70, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*8}, {KK_SHA512+55*8} + UPDATE_2 71, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*8}, {KK_SHA512+56*8} + UPDATE_2 72, rax,rbx, rcx,rdx + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*8}, {KK_SHA512+57*8} + UPDATE_2 73, rax,rbx, rcx,rdx + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*8}, {KK_SHA512+58*8} + UPDATE_2 74, rax,rbx, rcx,rdx + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*8}, {KK_SHA512+59*8} + UPDATE_2 75, rax,rbx, rcx,rdx + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*8}, {KK_SHA512+60*8} + UPDATE_2 76, rax,rbx, rcx,rdx + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*8}, {KK_SHA512+61*8} + UPDATE_2 77, rax,rbx, rcx,rdx + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*8}, {KK_SHA512+62*8} + UPDATE_2 78, rax,rbx, rcx,rdx + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*8}, {KK_SHA512+63*8} + UPDATE_2 79, rax,rbx, rcx,rdx + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 0*8}, {KK_SHA512+64*8} + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 1*8}, {KK_SHA512+65*8} + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+ 2*8}, {KK_SHA512+66*8} + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+ 3*8}, {KK_SHA512+67*8} + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+ 4*8}, {KK_SHA512+68*8} + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+ 5*8}, {KK_SHA512+69*8} + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+ 6*8}, {KK_SHA512+70*8} + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+ 7*8}, {KK_SHA512+71*8} + + SHA512_STEP_2 r8, r9, r10,r11,r12,r13,r14,r15, rbx,rcx,rdx, {rsp+ 8*8}, {KK_SHA512+72*8} + SHA512_STEP_2 r15,r8, r9, r10,r11,r12,r13,r14, rbx,rcx,rdx, {rsp+ 9*8}, {KK_SHA512+73*8} + SHA512_STEP_2 r14,r15,r8, r9, r10,r11,r12,r13, rbx,rcx,rdx, {rsp+10*8}, {KK_SHA512+74*8} + SHA512_STEP_2 r13,r14,r15,r8, r9, r10,r11,r12, rbx,rcx,rdx, {rsp+11*8}, {KK_SHA512+75*8} + SHA512_STEP_2 r12,r13,r14,r15,r8, r9, r10,r11, rbx,rcx,rdx, {rsp+12*8}, {KK_SHA512+76*8} + SHA512_STEP_2 r11,r12,r13,r14,r15,r8, r9, r10, rbx,rcx,rdx, {rsp+13*8}, {KK_SHA512+77*8} + SHA512_STEP_2 r10,r11,r12,r13,r14,r15,r8, r9, rbx,rcx,rdx, {rsp+14*8}, {KK_SHA512+78*8} + SHA512_STEP_2 r9, r10,r11,r12,r13,r14,r15,r8, rbx,rcx,rdx, {rsp+15*8}, {KK_SHA512+79*8} + +;; +;; update digest +;; + add [rdi+0*8],r8 + add [rdi+1*8],r9 + add [rdi+2*8],r10 + add [rdi+3*8],r11 + add [rdi+4*8],r12 + add [rdi+5*8],r13 + add [rdi+6*8],r14 + add [rdi+7*8],r15 + + add rsi, MBS_SHA512 + sub qword [rsp+16*sizeof(qword)], MBS_SHA512 + jg .sha512_block_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSHA512 + +%endif ;; (_IPP32E >= _IPP32E_M7) AND (_IPP32E < _IPP32E_E9 ) +%endif ;; _ENABLE_ALG_SHA512_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm2pfuncs_montas.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm2pfuncs_montas.asm new file mode 100644 index 000000000..329138a2f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm2pfuncs_montas.asm @@ -0,0 +1,1241 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; SM2 specific implementation +; + +%include "asmdefs.inc" +%include "ia_32e.inc" + +%if (_IPP32E >= _IPP32E_M7) + +%assign _xEMULATION_ 1 +%assign _ADCX_ADOX_ 1 + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +;; The SM2 polynomial +Lpoly DQ 0FFFFFFFFFFFFFFFFh,0FFFFFFFF00000000h,0FFFFFFFFFFFFFFFFh,0FFFFFFFEFFFFFFFFh + +;; 2^512 mod P precomputed for SM2 polynomial +LRR DQ 00000000200000003h,000000002ffffffffh,00000000100000001h,00000000400000002h + +LOne DD 1,1,1,1,1,1,1,1 +LTwo DD 2,2,2,2,2,2,2,2 +LThree DD 3,3,3,3,3,3,3,3 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_mul_by_2(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_mul_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + shld t4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_mul_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_div_by_2(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_div_by_2,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13,r14 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + xor t4, t4 + xor r14, r14 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + adc t4, 0 + test a0, 1 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + cmovnz r14,t4 + + shrd a0, a1, 1 + shrd a1, a2, 1 + shrd a2, a3, 1 + shrd a3, r14,1 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_div_by_2 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_mul_by_3(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_mul_by_3,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + shld t4, a3, 1 + shld a3, a2, 1 + shld a2, a1, 1 + shld a1, a0, 1 + shl a0, 1 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + xor t4, t4 + add a0, qword [rsi+sizeof(qword)*0] + adc a1, qword [rsi+sizeof(qword)*1] + adc a2, qword [rsi+sizeof(qword)*2] + adc a3, qword [rsi+sizeof(qword)*3] + adc t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_mul_by_3 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_add,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + add a0, qword [rdx+sizeof(qword)*0] + adc a1, qword [rdx+sizeof(qword)*1] + adc a2, qword [rdx+sizeof(qword)*2] + adc a3, qword [rdx+sizeof(qword)*3] + adc t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb t4, 0 + + cmovz a0, t0 + cmovz a1, t1 + cmovz a2, t2 + cmovz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_add + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_sub,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 3 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + mov a0, qword [rsi+sizeof(qword)*0] + mov a1, qword [rsi+sizeof(qword)*1] + mov a2, qword [rsi+sizeof(qword)*2] + mov a3, qword [rsi+sizeof(qword)*3] + + sub a0, qword [rdx+sizeof(qword)*0] + sbb a1, qword [rdx+sizeof(qword)*1] + sbb a2, qword [rdx+sizeof(qword)*2] + sbb a3, qword [rdx+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_sub + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_neg(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_neg,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rsi,rdi,r12,r13 + USES_XMM + COMP_ABI 2 + +%xdefine a0 r8 +%xdefine a1 r9 +%xdefine a2 r10 +%xdefine a3 r11 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t2 rcx +%xdefine t3 r12 +%xdefine t4 r13 + + xor t4, t4 + + xor a0, a0 + xor a1, a1 + xor a2, a2 + xor a3, a3 + + sub a0, qword [rsi+sizeof(qword)*0] + sbb a1, qword [rsi+sizeof(qword)*1] + sbb a2, qword [rsi+sizeof(qword)*2] + sbb a3, qword [rsi+sizeof(qword)*3] + sbb t4, 0 + + mov t0, a0 + mov t1, a1 + mov t2, a2 + mov t3, a3 + + add t0, qword [rel Lpoly+sizeof(qword)*0] + adc t1, qword [rel Lpoly+sizeof(qword)*1] + adc t2, qword [rel Lpoly+sizeof(qword)*2] + adc t3, qword [rel Lpoly+sizeof(qword)*3] + test t4, t4 + + cmovnz a0, t0 + cmovnz a1, t1 + cmovnz a2, t2 + cmovnz a3, t3 + + mov qword [rdi+sizeof(qword)*0], a0 + mov qword [rdi+sizeof(qword)*1], a1 + mov qword [rdi+sizeof(qword)*2], a2 + mov qword [rdi+sizeof(qword)*3], a3 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_neg + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_mul_montl(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; on entry p5=0 +; on exit p0=0, p5=0/1 +; +%macro sm2_mul_redstep 6.nolist + %xdefine %%p5 %1 + %xdefine %%p4 %2 + %xdefine %%p3 %3 + %xdefine %%p2 %4 + %xdefine %%p1 %5 + %xdefine %%p0 %6 + + mov acc6, %%p0 ;; (u1:u0) = p0*2^32 + shl acc6, 32 + mov acc7, %%p0 + shr acc7, 32 + + mov t0, %%p0 + mov t4, %%p0 + xor t1, t1 + xor t3, t3 + + sub t0, acc6 ;; (t3:t2:t1:t0) = p0*2^256 -p0*2^224 +p0*2^64 -p0*2^96 + sbb t1, acc7 + sbb t3, acc6 + sbb t4, acc7 + + add %%p1, t0 ;; (p5:p4:p3:p2:p1) -= (t3:t2:t1:t0) + adc %%p2, t1 + adc %%p3, t3 + adc %%p4, t4 + adc %%p5, 0 ;; p5 extension + xor %%p0, %%p0 ;; p0 = 0; +%endmacro + +align IPP_ALIGN_FACTOR +sm2_mmull: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rcx +%xdefine t1 rbp +%xdefine t2 rbx +%xdefine t3 rdx +%xdefine t4 rax +%xdefine t5 r14 + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc5, acc5 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*0] + mov acc0, rax + mov acc1, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*1] + add acc1, rax + adc rdx, 0 + mov acc2, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*2] + add acc2, rax + adc rdx, 0 + mov acc3, rdx + + mov rax, qword [bPtr+sizeof(qword)*0] + mul qword [aPtr+sizeof(qword)*3] + add acc3, rax + adc rdx, 0 + mov acc4, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; 1-st reduction step + sm2_mul_redstep acc5,acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*0] + add acc1, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*1] + add acc2, t0 + adc rdx, 0 + add acc2, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*2] + add acc3, t0 + adc rdx, 0 + add acc3, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*1] + mul qword [aPtr+sizeof(qword)*3] + add acc4, t0 + adc rdx, 0 + add acc4, rax + adc acc5, rdx + adc acc0, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; 2-ndt reduction step + sm2_mul_redstep acc0,acc5,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*0] + add acc2, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*1] + add acc3, t0 + adc rdx, 0 + add acc3, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*2] + add acc4, t0 + adc rdx, 0 + add acc4, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*2] + mul qword [aPtr+sizeof(qword)*3] + add acc5, t0 + adc rdx, 0 + add acc5, rax + adc acc0, rdx + adc acc1, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; 3-rd reduction step + sm2_mul_redstep acc1,acc0,acc5,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[3] + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*0] + add acc3, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*1] + add acc4, t0 + adc rdx, 0 + add acc4, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*2] + add acc5, t0 + adc rdx, 0 + add acc5, rax + adc rdx, 0 + mov t0, rdx + + mov rax, qword [bPtr+sizeof(qword)*3] + mul qword [aPtr+sizeof(qword)*3] + add acc0, t0 + adc rdx, 0 + add acc0, rax + adc acc1, rdx + adc acc2, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; final reduction step + sm2_mul_redstep acc2,acc1,acc0,acc5,acc4,acc3 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 + mov acc3, acc5 + mov acc6, acc0 + mov acc7, acc1 + + sub t4, t0 ;; test %if it exceeds prime value + sbb acc3, t1 + sbb acc6, t2 + sbb acc7, t3 + sbb acc2, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc3 + cmovnc acc0, acc6 + cmovnc acc1, acc7 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc0 + mov qword [rdi+sizeof(qword)*3], acc1 + + ret + +align IPP_ALIGN_FACTOR +IPPASM sm2_mul_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call sm2_mmull + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_mul_montl + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_to_mont(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_to_mont,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + + lea rbx, [rel LRR] + call sm2_mmull + REST_XMM + REST_GPR + ret +ENDFUNC sm2_to_mont + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_mul_montx(uint64_t res[4], uint64_t a[4], uint64_t b[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%if (_IPP32E >= _IPP32E_L9) +align IPP_ALIGN_FACTOR +sm2_mmulx: + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rax +%xdefine t1 rdx +%xdefine t3 rcx +%xdefine t4 rbp +%xdefine t2 rbx + +; rdi assumed as result +%xdefine aPtr rsi +%xdefine bPtr rbx + + xor acc5, acc5 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[0] + xor rdx, rdx + mov rdx, qword [bPtr+sizeof(qword)*0] + mulx acc1,acc0, qword [aPtr+sizeof(qword)*0] + mulx acc2,t3, qword [aPtr+sizeof(qword)*1] + add acc1,t3 + mulx acc3,t3, qword [aPtr+sizeof(qword)*2] + adc acc2,t3 + mulx acc4,t3, qword [aPtr+sizeof(qword)*3] + adc acc3,t3 + adc acc4,0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 0 + sm2_mul_redstep acc5,acc4,acc3,acc2,acc1,acc0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[1] + mov rdx, qword [bPtr+sizeof(qword)*1] + + mulx t4, t3, qword [aPtr+sizeof(qword)*0] + adcx acc1, t3 + adox acc2, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*1] + adcx acc2, t3 + adox acc3, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*2] + adcx acc3, t3 + adox acc4, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*3] + adcx acc4, t3 + adox acc5, t4 + + adcx acc5, acc0 + adox acc0, acc0 + adc acc0, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 1 + sm2_mul_redstep acc0,acc5,acc4,acc3,acc2,acc1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[2] + mov rdx, qword [bPtr+sizeof(qword)*2] + + mulx t4, t3, qword [aPtr+sizeof(qword)*0] + adcx acc2, t3 + adox acc3, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*1] + adcx acc3, t3 + adox acc4, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*2] + adcx acc4, t3 + adox acc5, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*3] + adcx acc5, t3 + adox acc0, t4 + + adcx acc0, acc1 + adox acc1, acc1 + + adc acc1, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 2 + sm2_mul_redstep acc1,acc0,acc5,acc4,acc3,acc2 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; * b[3] + mov rdx, qword [bPtr+sizeof(qword)*3] + + mulx t4, t3, qword [aPtr+sizeof(qword)*0] + adcx acc3, t3 + adox acc4, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*1] + adcx acc4, t3 + adox acc5, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*2] + adcx acc5, t3 + adox acc0, t4 + + mulx t4, t3, qword [aPtr+sizeof(qword)*3] + adcx acc0, t3 + adox acc1, t4 + + adcx acc1, acc2 + adox acc2, acc2 + adc acc2, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; reduction step 3 (final) + sm2_mul_redstep acc2,acc1,acc0,acc5,acc4,acc3 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 ;; copy reducted result + mov acc3, acc5 + mov acc6, acc0 + mov acc7, acc1 + + sub t4, t0 ;; test %if it exceeds prime value + sbb acc3, t1 + sbb acc6, t2 + sbb acc7, t3 + sbb acc2, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc3 + cmovnc acc0, acc6 + cmovnc acc1, acc7 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc0 + mov qword [rdi+sizeof(qword)*3], acc1 + + ret +%endif + +%if _IPP32E >= _IPP32E_L9 +align IPP_ALIGN_FACTOR +IPPASM sm2_mul_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 3 + +%xdefine bPtr rbx + + mov bPtr, rdx + call sm2_mmulx + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_mul_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_sqr_montl(uint64_t res[4], uint64_t a[4]); +; void sm2_sqr_montx(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +%macro sm2_prod_redstep 6.nolist + %xdefine %%e %1 + %xdefine %%p4 %2 + %xdefine %%p3 %3 + %xdefine %%p2 %4 + %xdefine %%p1 %5 + %xdefine %%p0 %6 + + mov t4, %%p0 + mov t0, %%p0 + mov t3, %%p0 + xor t1, t1 + xor t2, t2 + shl %%p0, 32 + shr t4, 32 ;; (t4:p0) = p0*2^32 + + sub t0, %%p0 ;; (t3:t2:t1:t0) = p0*2^256 -p0*2^224 +p0*2^64 -p0*2^96 + sbb t1, t4 + sbb t2, %%p0 + sbb t3, t4 + + xor %%p0, %%p0 + add %%p1, t0 ;; (p5:p4:p3:p2:p1) -= (t3:t2:t1:t0) + adc %%p2, t1 + adc %%p3, t2 + adc %%p4, t3 + adc %%p0, 0 + + %ifnempty %%e + add %%p4, %%e + adc %%p0, 0 + %endif + +%endmacro + +align IPP_ALIGN_FACTOR +IPPASM sm2_sqr_montl,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rcx +%xdefine t1 rbp +%xdefine t2 rbx +%xdefine t3 rdx +%xdefine t4 rax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*0] + mov rax,qword [aPtr+sizeof(qword)*1] + mul t2 + mov acc1, rax + mov acc2, rdx + mov rax,qword [aPtr+sizeof(qword)*2] + mul t2 + add acc2, rax + adc rdx, 0 + mov acc3, rdx + mov rax,qword [aPtr+sizeof(qword)*3] + mul t2 + add acc3, rax + adc rdx, 0 + mov acc4, rdx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*1] + mov rax,qword [aPtr+sizeof(qword)*2] + mul t2 + add acc3, rax + adc rdx, 0 + mov t1, rdx + mov rax,qword [aPtr+sizeof(qword)*3] + mul t2 + add acc4, rax + adc rdx, 0 + add acc4, t1 + adc rdx, 0 + mov acc5, rdx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov t2, qword [aPtr+sizeof(qword)*2] + mov rax,qword [aPtr+sizeof(qword)*3] + mul t2 + add acc5, rax + adc rdx, 0 + mov acc6, rdx + + xor acc7, acc7 + shld acc7, acc6, 1 + shld acc6, acc5, 1 + shld acc5, acc4, 1 + shld acc4, acc3, 1 + shld acc3, acc2, 1 + shld acc2, acc1, 1 + shl acc1, 1 + + mov rax,qword [aPtr+sizeof(qword)*0] + mul rax + mov acc0, rax + add acc1, rdx + adc acc2, 0 + mov rax,qword [aPtr+sizeof(qword)*1] + mul rax + add acc2, rax + adc acc3, rdx + adc acc4, 0 + mov rax,qword [aPtr+sizeof(qword)*2] + mul rax + add acc4, rax + adc acc5, rdx + adc acc6, 0 + mov rax,qword [aPtr+sizeof(qword)*3] + mul rax + add acc6, rax + adc acc7, rdx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + sm2_prod_redstep ,acc4,acc3,acc2,acc1,acc0 + sm2_prod_redstep acc0,acc5,acc4,acc3,acc2,acc1 + sm2_prod_redstep acc1,acc6,acc5,acc4,acc3,acc2 + sm2_prod_redstep acc2,acc7,acc6,acc5,acc4,acc3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 + mov acc0, acc5 + mov acc1, acc6 + mov acc2, acc7 + + sub t4, t0 + sbb acc0, t1 + sbb acc1, t2 + sbb acc2, t3 + sbb acc3, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc0 + cmovnc acc6, acc1 + cmovnc acc7, acc2 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc6 + mov qword [rdi+sizeof(qword)*3], acc7 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_sqr_montl + +%if (_IPP32E >= _IPP32E_L9) +align IPP_ALIGN_FACTOR +IPPASM sm2_sqr_montx,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rcx +%xdefine t1 rbp +%xdefine t2 rbx +%xdefine t3 rdx +%xdefine t4 rax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*0] + mulx acc2, acc1, qword [aPtr+sizeof(qword)*1] + mulx acc3, t0, qword [aPtr+sizeof(qword)*2] + add acc2, t0 + mulx acc4, t0, qword [aPtr+sizeof(qword)*3] + adc acc3, t0 + adc acc4, 0 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*1] + xor acc5, acc5 + mulx t1, t0, qword [aPtr+sizeof(qword)*2] + adcx acc3, t0 + adox acc4, t1 + mulx t1, t0, qword [aPtr+sizeof(qword)*3] + adcx acc4, t0 + adox acc5, t1 + adc acc5, 0 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov rdx, qword [aPtr+sizeof(qword)*2] + mulx acc6, t0, qword [aPtr+sizeof(qword)*3] + add acc5, t0 + adc acc6, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor acc7, acc7 + shld acc7, acc6, 1 + shld acc6, acc5, 1 + shld acc5, acc4, 1 + shld acc4, acc3, 1 + shld acc3, acc2, 1 + shld acc2, acc1, 1 + shl acc1, 1 + + xor acc0, acc0 + mov rdx, qword [aPtr+sizeof(qword)*0] + mulx t1, acc0, rdx + adcx acc1, t1 + mov rdx, qword [aPtr+sizeof(qword)*1] + mulx t1, t0, rdx + adcx acc2, t0 + adcx acc3, t1 + mov rdx, qword [aPtr+sizeof(qword)*2] + mulx t1, t0, rdx + adcx acc4, t0 + adcx acc5, t1 + mov rdx, qword [aPtr+sizeof(qword)*3] + mulx t1, t0, rdx + adcx acc6, t0 + adcx acc7, t1 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + sm2_prod_redstep ,acc4,acc3,acc2,acc1,acc0 + sm2_prod_redstep acc0,acc5,acc4,acc3,acc2,acc1 + sm2_prod_redstep acc1,acc6,acc5,acc4,acc3,acc2 + sm2_prod_redstep acc2,acc7,acc6,acc5,acc4,acc3 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + mov t0, qword [rel Lpoly+sizeof(qword)*0] + mov t1, qword [rel Lpoly+sizeof(qword)*1] + mov t2, qword [rel Lpoly+sizeof(qword)*2] + mov t3, qword [rel Lpoly+sizeof(qword)*3] + + mov t4, acc4 + mov acc0, acc5 + mov acc1, acc6 + mov acc2, acc7 + + sub t4, t0 + sbb acc0, t1 + sbb acc1, t2 + sbb acc2, t3 + sbb acc3, 0 + + cmovnc acc4, t4 + cmovnc acc5, acc0 + cmovnc acc6, acc1 + cmovnc acc7, acc2 + + mov qword [rdi+sizeof(qword)*0], acc4 + mov qword [rdi+sizeof(qword)*1], acc5 + mov qword [rdi+sizeof(qword)*2], acc6 + mov qword [rdi+sizeof(qword)*3], acc7 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_sqr_montx + +%endif ;; _IPP32E_L9 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; void sm2_mont_back(uint64_t res[4], uint64_t a[4]); +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +IPPASM sm2_mont_back,PUBLIC +%assign LOCAL_FRAME 0 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 2 + +%xdefine acc0 r8 +%xdefine acc1 r9 +%xdefine acc2 r10 +%xdefine acc3 r11 +%xdefine acc4 r12 +%xdefine acc5 r13 +%xdefine acc6 r14 +%xdefine acc7 r15 + +%xdefine t0 rcx +%xdefine t1 rbp +%xdefine t2 rbx +%xdefine t3 rdx +%xdefine t4 rax + + mov acc2, qword [rsi+sizeof(qword)*0] + mov acc3, qword [rsi+sizeof(qword)*1] + mov acc4, qword [rsi+sizeof(qword)*2] + mov acc5, qword [rsi+sizeof(qword)*3] + xor acc0, acc0 + xor acc1, acc1 + + sm2_mul_redstep acc1,acc0,acc5,acc4,acc3,acc2 + sm2_mul_redstep acc2,acc1,acc0,acc5,acc4,acc3 + sm2_mul_redstep acc3,acc2,acc1,acc0,acc5,acc4 + sm2_mul_redstep acc4,acc3,acc2,acc1,acc0,acc5 + + mov t0, acc0 + mov t1, acc1 + mov t2, acc2 + mov t3, acc3 + + sub t0, qword [rel Lpoly+sizeof(qword)*0] + sbb t1, qword [rel Lpoly+sizeof(qword)*1] + sbb t2, qword [rel Lpoly+sizeof(qword)*2] + sbb t3, qword [rel Lpoly+sizeof(qword)*3] + sbb acc4, 0 + + cmovnc acc0, t0 + cmovnc acc1, t1 + cmovnc acc2, t2 + cmovnc acc3, t3 + + mov qword [rdi+sizeof(qword)*0], acc0 + mov qword [rdi+sizeof(qword)*1], acc1 + mov qword [rdi+sizeof(qword)*2], acc2 + mov qword [rdi+sizeof(qword)*3], acc3 + + REST_XMM + REST_GPR + ret +ENDFUNC sm2_mont_back + +%endif ;; _IPP32E>=_IPP32E_M7 + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm3e9as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm3e9as.asm new file mode 100644 index 000000000..30924add0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm3e9as.asm @@ -0,0 +1,874 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SM3 +; +; Content: +; UpdateSM3 +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SM3_) +%if (_IPP32E >= _IPP32E_E9) + +%xdefine A r8d +%xdefine B r9d +%xdefine C r10d +%xdefine D r11d +%xdefine E r12d +%xdefine F r13d +%xdefine G r14d +%xdefine H r15d + +%xdefine hPtr rdi +%xdefine mPtr rsi +%xdefine kPtr rcx + +%xdefine t0 eax +%xdefine t1 ebx +%xdefine t2 ebp +%xdefine t3 edx + +%xdefine W0 xmm0 +%xdefine W1 xmm1 +%xdefine W2 xmm2 +%xdefine W3 xmm3 + +%xdefine xT0 xmm4 +%xdefine xT1 xmm5 +%xdefine xTr xmm6 +%xdefine xWZZZ xmm7 +%xdefine xBCAST xmm8 +%xdefine xROL8 xmm9 + + +%macro ROTATE_H 0.nolist + %xdefine %%DUMMY H + %xdefine H G + %xdefine G F + %xdefine F E + %xdefine E D + %xdefine D C + %xdefine C B + %xdefine B A + %xdefine A %%DUMMY +%endmacro + +%macro ROUND_00_15 1.nolist + %xdefine %%nr %1 + + mov t0, A + mov t1, [kPtr+%%nr*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, E + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + add t1, H ; t1: TT2 = SS1 + h + add t0, D ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%nr & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%nr & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + mov t2, B + mov t3, F + + xor t2, C + xor t3, G + + xor t2, A ; t2 = FF(a,b,c) = a^b^c + xor t3, E ; t3 = GG(e,f,g) = e^f^g + + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + + shld B, B, 9 + shld F, F, 19 + + mov H, t0 + + mov D, t1 + shld D, D, 8 + xor D, t1 + shld D, D, 9 + xor D, t1 + + ROTATE_H +%endmacro + +%macro ROUND_16_63 9.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + + mov t0, %%A + mov t1, [kPtr+%%nr*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%E + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + add t1, %%H ; t1: TT2 = SS1 + h + add t0, %%D ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%nr & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%nr & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + mov t3, %%B + mov t2, %%B + and t3, %%C + xor t2, %%C + and t2, %%A + add t2, t3 + + mov t3, %%F + xor t3, %%G + and t3, %%E + xor t3, %%G + + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + + shld %%B, %%B, 9 + shld %%F, %%F, 19 + + mov %%H, t0 + + mov %%D, t1 + shld %%D, %%D, 8 + xor %%D, t1 + shld %%D, %%D, 9 + xor %%D, t1 + + ;ROTATE_H +%endmacro + +;; +;; Y = ROL32(X,nbits) +%macro xmmROL32 3.nolist + %xdefine %%Y %1 + %xdefine %%X %2 + %xdefine %%nbits %3 + +%if %%nbits != 8 + vpslld xTr,%%X, %%nbits + vpsrld %%Y, %%X, (32-%%nbits) + vpxor %%Y, %%Y, xTr +%else + ;;vpshufb Y, X, oword [rel rol_32_8] + vpshufb %%Y, %%X, xROL8 +%endif +%endmacro + +%macro xmmBCAST 2.nolist + %xdefine %%Y %1 + %xdefine %%X %2 + + ;;vpshufb Y, X, oword [rel bcast] + vpshufb %%Y, %%X, xBCAST +%endmacro + +;; +;; w[j] = P1(w[t-16]^w[t-9]^ROL32(w[t-3],15)) ^ ROL32(w[t-13],7) ^ w[t-6] +;; +%macro ROTATE_W 0.nolist + %xdefine %%DUMMY W0 + %xdefine W0 W1 + %xdefine W1 W2 + %xdefine W2 W3 + %xdefine W3 %%DUMMY +%endmacro + +%macro QSCHED 0.nolist + vpalignr xT0, W1, W0, sizeof(dword)*3 ;; T0 = {w6,w5,w4,w3} + xmmROL32 xT0, xT0, 7 ;; T0 = ROL32({w6,w5,w4,w3}, 7) + + ;; compute P1() argument + vpsrldq xT1, W3, sizeof(dword) ;; T1 = {Z,w15,w14,w13} + xmmROL32 xT1, xT1, 15 ;; T1 = ROL32({Z,w15,w14,w13}, 15) + vpxor W0, W0, xT1 ;; W0 = {w3,w2,w1,w0} ^ ROL32({Z,w15,w14,w13}, 15) + vpalignr xT1, W2, W1, sizeof(dword)*3 ;; T1 = {w10,w9,w8,w7} + vpxor W0, W0, xT1 ;; W0 = {w3,w2,w1,w0} ^ ROL32({Z,w15,w14,w13}, 15) ^ {w10,w9,w8,w7} + + ;; compute W0 = P1(W0), P1(x) = x ^ rol32(x,15) ^ rol(x,23) + xmmROL32 xT1, W0, 8 + vpxor xT1, xT1, W0 + xmmROL32 xT1, xT1, 15 + vpxor W0, W0, xT1 + + vpalignr xT1, W3, W2, sizeof(dword)*2 ;; T1 = {w13,w12,w11,w10} + + vpxor W0, W0, xT0 + vpxor W0, W0, xT1 + + ;; compute P1(rol(w16,15)) + xmmBCAST xT0, W0 ;; T0 = {w16,w16,w16,rw16} + vpsrlq xT0, xT0, (32-15) ;; T0 = {??,rol(w16,15),??,rol(w16,15)} + xmmBCAST xT0, xT0 ;; T0 = {rol(w16,15),rol(w16,15),rol(w16,15),rol(w16,15)} + vpsllq xT1, xT0, 15 + vpxor xT0, xT0, xT1 + vpsllq xT1, xT1, (23-15) + vpxor xT0, xT0, xT1 + ;;vpshufb xT0, xT0, [rel wzzz] ;; T0 = {P1(rol(w16,15)),zz,zz,zz} + vpshufb xT0, xT0, xWZZZ ;; T0 = {P1(rol(w16,15)),zz,zz,zz} + + vpxor W0, W0, xT0 + ROTATE_W +%endmacro + +%macro QSCHED_W_QROUND_00_15 9.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + + vpalignr xT0, W1, W0, sizeof(dword)*3 ;; T0 = {w6,w5,w4,w3} + xmmROL32 xT0, xT0, 7 ;; T0 = ROL32({w6,w5,w4,w3}, 7) + + %assign %%t %%nr + ;ROUND_00_15 t + mov t0, %%A + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%E + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + add t1, %%H ; t1: TT2 = SS1 + h + add t0, %%D ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + vpsrldq xT1, W3, sizeof(dword) ;; T1 = {Z,w15,w14,w13} + xmmROL32 xT1, xT1, 15 ;; T1 = ROL32({Z,w15,w14,w13}, 15) + + mov t2, %%B + mov t3, %%F + + xor t2, %%C + xor t3, %%G + + xor t2, %%A ; t2 = FF(a,b,c) = a^b^c + xor t3, %%E ; t3 = GG(e,f,g) = e^f^g + + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + + shld %%B, %%B, 9 + shld %%F, %%F, 19 + + mov %%H, t0 + + vpxor W0, W0, xT1 ;; W0 = {w3,w2,w1,w0} ^ ROL32({Z,w15,w14,w13}, 15) + vpalignr xT1, W2, W1, sizeof(dword)*3 ;; T1 = {w10,w9,w8,w7} + vpxor W0, W0, xT1 ;; W0 = {w3,w2,w1,w0} ^ ROL32({Z,w15,w14,w13}, 15) ^ {w10,w9,w8,w7} + + mov %%D, t1 + shld %%D, %%D, 8 + xor %%D, t1 + shld %%D, %%D, 9 + xor %%D, t1 + + ;ROTATE_H + ;;;;;;;;;;;;;;; + + %assign %%t %%t+1 + ;ROUND_00_15 t + mov t0, %%H + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%D + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + xmmROL32 xT1, W0, 8 + vpxor xT1, xT1, W0 + + add t1, %%G ; t1: TT2 = SS1 + h + add t0, %%C ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + xmmROL32 xT1, xT1, 15 + vpxor W0, W0, xT1 + + mov t2, %%A + mov t3, %%E + + xor t2, %%B + xor t3, %%F + + xor t2, %%H ; t2 = FF(a,b,c) = a^b^c + xor t3, %%D ; t3 = GG(e,f,g) = e^f^g + + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + + shld %%A, %%A, 9 + shld %%E, %%E, 19 + + mov %%G, t0 + + mov %%C, t1 + shld %%C, %%C, 8 + xor %%C, t1 + shld %%C, %%C, 9 + xor %%C, t1 + + ;ROTATE_H + ;;;;;;;;;;;;;;; + + vpalignr xT1, W3, W2, sizeof(dword)*2 ;; T1 = {w13,w12,w11,w10} + vpxor W0, W0, xT0 + vpxor W0, W0, xT1 + + %assign %%t %%t+1 + ;ROUND_00_15 t + mov t0, %%G + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%C + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + add t1, %%F ; t1: TT2 = SS1 + h + add t0, %%B ; t0: TT1 = SS2 + d + + xmmBCAST xT0, W0 ;; T0 = {w16,w16,w16,rw16} + vpsrlq xT0, xT0, (32-15) ;; T0 = {??,rol(w16,15),??,rol(w16,15)} + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + mov t2, %%H + mov t3, %%D + + xor t2, %%A + xor t3, %%E + + xor t2, %%G ; t2 = FF(a,b,c) = a^b^c + xor t3, %%C ; t3 = GG(e,f,g) = e^f^g + + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + + shld %%H, %%H, 9 + shld %%D, %%D, 19 + + xmmBCAST xT0, xT0 ;; T0 = {rol(w16,15),rol(w16,15),rol(w16,15),rol(w16,15)} + vpsllq xT1, xT0, 15 + + mov %%F, t0 + + mov %%B, t1 + shld %%B, %%B, 8 + xor %%B, t1 + shld %%B, %%B, 9 + xor %%B, t1 + + ;ROTATE_H + ;;;;;;;;;;;;;;; + + %assign %%t %%t+1 + ;ROUND_00_15 t + mov t0, %%F + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%B + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + vpxor xT0, xT0, xT1 + vpsllq xT1, xT1, (23-15) + + add t1, %%E ; t1: TT2 = SS1 + h + add t0, %%A ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + mov t2, %%G + mov t3, %%C + + xor t2, %%H + xor t3, %%D + + vpxor xT0, xT0, xT1 + ;;vpshufb xT0, xT0, [rel wzzz] ;; T0 = {P1(rol(w16,15)),zz,zz,zz} + vpshufb xT0, xT0, xWZZZ ;; T0 = {P1(rol(w16,15)),zz,zz,zz} + + xor t2, %%F ; t2 = FF(a,b,c) = a^b^c + xor t3, %%B ; t3 = GG(e,f,g) = e^f^g + + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + + shld %%G, %%G, 9 + shld %%C, %%C, 19 + + vpxor W0, W0, xT0 + + mov %%E, t0 + + mov %%A, t1 + shld %%A, %%A, 8 + xor %%A, t1 + shld %%A, %%A, 9 + xor %%A, t1 + + ;ROTATE_H + ROTATE_W + ;;;;;;;;;;;;;;; +%endmacro + +%macro QSCHED_W_QROUND_16_63 9.nolist + %xdefine %%nr %1 + %xdefine %%A %2 + %xdefine %%B %3 + %xdefine %%C %4 + %xdefine %%D %5 + %xdefine %%E %6 + %xdefine %%F %7 + %xdefine %%G %8 + %xdefine %%H %9 + + vpalignr xT0, W1, W0, sizeof(dword)*3 ;; T0 = {w6,w5,w4,w3} + xmmROL32 xT0, xT0, 7 ;; T0 = ROL32({w6,w5,w4,w3}, 7) + + %assign %%t %%nr + ;ROUND_16_63 t + mov t0, %%A + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%E + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + add t1, %%H ; t1: TT2 = SS1 + h + add t0, %%D ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + vpsrldq xT1, W3, sizeof(dword) ;; T1 = {Z,w15,w14,w13} + xmmROL32 xT1, xT1, 15 ;; T1 = ROL32({Z,w15,w14,w13}, 15) + + mov t3, %%B + mov t2, %%B + and t3, %%C + xor t2, %%C + and t2, %%A + add t2, t3 + + mov t3, %%F + xor t3, %%G + and t3, %%E + xor t3, %%G + + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + + shld %%B, %%B, 9 + shld %%F, %%F, 19 + + mov %%H, t0 + + vpxor W0, W0, xT1 ;; W0 = {w3,w2,w1,w0} ^ ROL32({Z,w15,w14,w13}, 15) + vpalignr xT1, W2, W1, sizeof(dword)*3 ;; T1 = {w10,w9,w8,w7} + vpxor W0, W0, xT1 ;; W0 = {w3,w2,w1,w0} ^ ROL32({Z,w15,w14,w13}, 15) ^ {w10,w9,w8,w7} + + mov %%D, t1 + shld %%D, %%D, 8 + xor %%D, t1 + shld %%D, %%D, 9 + xor %%D, t1 + + ;ROTATE_H + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + %assign %%t %%t + 1 + ;ROUND_16_63 t + mov t0, %%H + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%D + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + xmmROL32 xT1, W0, 8 + vpxor xT1, xT1, W0 + + add t1, %%G ; t1: TT2 = SS1 + h + add t0, %%C ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + xmmROL32 xT1, xT1, 15 + vpxor W0, W0, xT1 + + mov t3, %%A + mov t2, %%A + and t3, %%B + xor t2, %%B + and t2, %%H + add t2, t3 + + mov t3, %%E + xor t3, %%F + and t3, %%D + xor t3, %%F + + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + + shld %%A, %%A, 9 + shld %%E, %%E, 19 + + mov %%G, t0 + + mov %%C, t1 + shld %%C, %%C, 8 + xor %%C, t1 + shld %%C, %%C, 9 + xor %%C, t1 + + ;ROTATE_H + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + vpalignr xT1, W3, W2, sizeof(dword)*2 ;; T1 = {w13,w12,w11,w10} + vpxor W0, W0, xT0 + vpxor W0, W0, xT1 + + %assign %%t %%t + 1 + ;ROUND_16_63 t + mov t0, %%G + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%C + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + add t1, %%F ; t1: TT2 = SS1 + h + add t0, %%B ; t0: TT1 = SS2 + d + + xmmBCAST xT0, W0 ;; T0 = {w16,w16,w16,rw16} + vpsrlq xT0, xT0, (32-15) ;; T0 = {??,rol(w16,15),??,rol(w16,15)} + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + mov t3, %%H + mov t2, %%H + and t3, %%A + xor t2, %%A + and t2, %%G + add t2, t3 + + mov t3, %%D + xor t3, %%E + and t3, %%C + xor t3, %%E + + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + + shld %%H, %%H, 9 + shld %%D, %%D, 19 + + xmmBCAST xT0, xT0 ;; T0 = {rol(w16,15),rol(w16,15),rol(w16,15),rol(w16,15)} + vpsllq xT1, xT0, 15 + + mov %%F, t0 + + mov %%B, t1 + shld %%B, %%B, 8 + xor %%B, t1 + shld %%B, %%B, 9 + xor %%B, t1 + + ;ROTATE_H + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + %assign %%t %%t + 1 + ;ROUND_16_63 t + mov t0, %%F + mov t1, [kPtr+%%t*sizeof(dword)] + shld t0, t0, 12 ; t0 = t + add t1, t0 + add t1, %%B + shld t1, t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + vpxor xT0, xT0, xT1 + vpsllq xT1, xT1, (23-15) + + add t1, %%E ; t1: TT2 = SS1 + h + add t0, %%A ; t0: TT1 = SS2 + d + + add t1, [rsp+(%%t & 3)*sizeof(dword)] ; t1: TT2 = SS1 + h +w[nr] + add t0, [rsp+(%%t & 3)*sizeof(dword)+sizeof(oword)] ; t0: TT1 = SS2 + d +(w[nr]^w[nr+4]) + + mov t3, %%G + mov t2, %%G + and t3, %%H + xor t2, %%H + and t2, %%F + add t2, t3 + + vpxor xT0, xT0, xT1 + ;;vpshufb xT0, xT0, [rel wzzz] ;; T0 = {P1(rol(w16,15)),zz,zz,zz} + vpshufb xT0, xT0, xWZZZ ;; T0 = {P1(rol(w16,15)),zz,zz,zz} + + mov t3, %%C + xor t3, %%D + and t3, %%B + xor t3, %%D + + add t0, t2 ; t0: TT1 = SS2 +d +(w[nr]^w[nr+4]) +FF + add t1, t3 ; t1: TT2 = SS1 +h +w[nr] +GG + + shld %%G, %%G, 9 + shld %%C, %%C, 19 + + vpxor W0, W0, xT0 + + mov %%E, t0 + + mov %%A, t1 + shld %%A, %%A, 8 + xor %%A, t1 + shld %%A, %%A, 9 + xor %%A, t1 + + ;ROTATE_H + ROTATE_W + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + + +align IPP_ALIGN_FACTOR + +bswap128 DB 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 +rol_32_8 DB 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 +bcast DB 0,1,2,3, 0,1,2,3, 0,1,2,3, 0,1,2,3 +wzzz DB 80h,80h,80h,80h, 80h,80h,80h,80h, 80h,80h,80h,80h,12,13,14,15 + +;******************************************************************** +;* void UpdateSM3(Ipp32u* hash, +; const Ipp8u* msg, int msgLen, +; const Ipp32u* K_SM3) +;******************************************************************** +align IPP_ALIGN_FACTOR +IPPASM UpdateSM3,PUBLIC +%assign LOCAL_FRAME sizeof(oword)*2+sizeof(qword)*2 + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM xmm6,xmm7,xmm8,xmm9 + COMP_ABI 4 + +;; rdi = hash +;; rsi = data buffer +;; rdx = data buffer length (bytes) +;; rcx = address of SM3 constants + +;; stack structure: +%assign _wj 0 ; W[t+3]:W[t+2]:W[t+1]:W[t] +%assign _hash _wj+sizeof(oword)*2 ; hash pointer +%assign _len _hash+sizeof(qword) ; msg length + +%xdefine MBS_SM3 (64) + + movsxd rdx, edx + + movdqa xT0, oword [rel bswap128] ; swap byte + movdqa xWZZZ, oword [rel wzzz] ; shufle constant + movdqa xBCAST, oword [rel bcast] + movdqa xROL8, oword [rel rol_32_8] + + mov qword [rsp+_hash], rdi ; save hash pointer + mov qword [rsp+_len], rdx ; save msg length + +align IPP_ALIGN_FACTOR +.sm3_loop: + ; read data block (64 bytes) + vmovdqu W0, oword [mPtr+sizeof(oword)*0] + vpshufb W0, W0, xT0 + vmovdqu W1, oword [mPtr+sizeof(oword)*1] + vpshufb W1, W1, xT0 + vmovdqu W2, oword [mPtr+sizeof(oword)*2] + vpshufb W2, W2, xT0 + vmovdqu W3, oword [mPtr+sizeof(oword)*3] + vpshufb W3, W3, xT0 + add mPtr, MBS_SM3 + + mov A, [hPtr+0*sizeof(dword)] ; input hash value + mov B, [hPtr+1*sizeof(dword)] + mov C, [hPtr+2*sizeof(dword)] + mov D, [hPtr+3*sizeof(dword)] + mov E, [hPtr+4*sizeof(dword)] + mov F, [hPtr+5*sizeof(dword)] + mov G, [hPtr+6*sizeof(dword)] + mov H, [hPtr+7*sizeof(dword)] + + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_00_15 0, A,B,C,D,E,F,G,H + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_00_15 4, E,F,G,H,A,B,C,D + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_00_15 8, A,B,C,D,E,F,G,H + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_00_15 12, E,F,G,H,A,B,C,D + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 16, A,B,C,D,E,F,G,H + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 20, E,F,G,H,A,B,C,D + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 24, A,B,C,D,E,F,G,H + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 28, E,F,G,H,A,B,C,D + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 32, A,B,C,D,E,F,G,H + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 36, E,F,G,H,A,B,C,D + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 40, A,B,C,D,E,F,G,H + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 44, E,F,G,H,A,B,C,D + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + QSCHED_W_QROUND_16_63 48, A,B,C,D,E,F,G,H + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + ROTATE_W + ROUND_16_63 52, E,F,G,H,A,B,C,D + ROUND_16_63 53, D,E,F,G,H,A,B,C + ROUND_16_63 54, C,D,E,F,G,H,A,B + ROUND_16_63 55, B,C,D,E,F,G,H,A + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + ROTATE_W + ROUND_16_63 56, A,B,C,D,E,F,G,H + ROUND_16_63 57, H,A,B,C,D,E,F,G + ROUND_16_63 58, G,H,A,B,C,D,E,F + ROUND_16_63 59, F,G,H,A,B,C,D,E + + vmovdqa oword [rsp+_wj], W0 + vpxor xT0, W0, W1 + vmovdqa oword [rsp+_wj+sizeof(oword)], xT0 + ROTATE_W + ROUND_16_63 60, E,F,G,H,A,B,C,D + ROUND_16_63 61, D,E,F,G,H,A,B,C + ROUND_16_63 62, C,D,E,F,G,H,A,B + ROUND_16_63 63, B,C,D,E,F,G,H,A + + mov hPtr, qword [rsp+_hash] ; restore hash pointer + + xor [hPtr+0*sizeof(dword)], A ; update hash + xor [hPtr+1*sizeof(dword)], B + xor [hPtr+2*sizeof(dword)], C + xor [hPtr+3*sizeof(dword)], D + xor [hPtr+4*sizeof(dword)], E + xor [hPtr+5*sizeof(dword)], F + xor [hPtr+6*sizeof(dword)], G + xor [hPtr+7*sizeof(dword)], H + + movdqa xT0, oword [rel bswap128] ; swap byte + + sub qword [rsp+_len], MBS_SM3 + cmp qword [rsp+_len], MBS_SM3 + jge .sm3_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSM3 + +%endif ;; _IPP32E >= _IPP32E_E9 +%endif ;; _ENABLE_ALG_SM3_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm3u8as.asm b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm3u8as.asm new file mode 100644 index 000000000..813501ca7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpsm3u8as.asm @@ -0,0 +1,364 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; +; Purpose: Cryptography Primitive. +; Message block processing according to SM3 +; +; Content: +; UpdateSM3 +; + +%include "asmdefs.inc" +%include "ia_32e.inc" +%include "pcpvariant.inc" + +%if (_ENABLE_ALG_SM3_) +%if ((_IPP32E >= _IPP32E_U8 ) && (_IPP32E < _IPP32E_E9 )) || (_IPP32E == _IPP32E_N8 ) + +%xdefine a r8d +%xdefine b r9d +%xdefine c r10d +%xdefine d r11d +%xdefine e r12d +%xdefine f r13d +%xdefine g r14d +%xdefine h r15d + +%xdefine hPtr rdi +%xdefine mPtr rsi +%xdefine kPtr rcx + +%xdefine t0 eax +%xdefine t1 ebx +%xdefine t2 ebp +%xdefine t3 edx + +%xdefine ctr hPtr + +%if (_IPP32E >= _IPP32E_U8 ) + +%macro ROTL 2.nolist + %xdefine %%x %1 + %xdefine %%n %2 + + shld %%x,%%x, %%n +%endmacro + +%else +%macro ROTL 2.nolist + %xdefine %%x %1 + %xdefine %%n %2 + + rol %%x, %%n +%endmacro + +%endif + +%macro ROUND_00_15 9.nolist + %xdefine %%a %1 + %xdefine %%b %2 + %xdefine %%c %3 + %xdefine %%d %4 + %xdefine %%e %5 + %xdefine %%f %6 + %xdefine %%g %7 + %xdefine %%h %8 + %xdefine %%i %9 + + mov t0, %%a + mov t1, [kPtr+ctr*sizeof(dword)+%%i*sizeof(dword)] + ROTL t0, 12 ; t0 = t + add t1, t0 + add t1, %%e + ROTL t1, 7 ; t1 = SS1 + xor t0, t1 ; t0 = SS2 + + mov t2, %%b + mov t3, %%f + + xor t2, %%c + xor t3, %%g + + xor t2, %%a ; t2 = FF + xor t3, %%e ; t3 = GG + + add t0, t2 ; t0 = SS2 + FF + add t1, t3 ; t1 = SS1 + GG + + add t0, %%d ; t0 = SS2 + FF + d + add t1, %%h ; t1 = SS1 + GG + h + + mov t2, [rsp+ctr*sizeof(dword)+%%i*sizeof(dword)] ; t2 = w[i] + add t1, t2 ; t1 = TT2 + xor t2, [rsp+ctr*sizeof(dword)+(%%i+4)*sizeof(dword)] ; t2 = w[i] ^ w[i+4] + + add t0, t2 ; t0 = TT1 + + ROTL %%b, 9 + ROTL %%f, 19 + mov %%h, t0 + + mov %%d, t1 + ROTL %%d, 8 + xor %%d, t1 + ROTL %%d, 9 + xor %%d, t1 +%endmacro + +%macro ROUND_16_63 9.nolist + %xdefine %%a %1 + %xdefine %%b %2 + %xdefine %%c %3 + %xdefine %%d %4 + %xdefine %%e %5 + %xdefine %%f %6 + %xdefine %%g %7 + %xdefine %%h %8 + %xdefine %%i %9 + + mov t0, %%a + mov t1, [kPtr+ctr*sizeof(dword)+%%i*sizeof(dword)] + ROTL t0, 12 + add t1, t0 + add t1, %%e + ROTL t1, 7 ;; t1 = SS1 + xor t0, t1 ;; t0 = SS2 + + mov t3, %%b + mov t2, %%b + and t3, %%c + xor t2, %%c + and t2, %%a + add t2, t3 + + mov t3, %%f + xor t3, %%g + and t3, %%e + xor t3, %%g + + add t0, t2 ;; t0 = SS2 + FF + add t1, t3 ;; t1 = SS1 + GG + + add t0, %%d ;; t0 = SS2 + FF + d + add t1, %%h ;; t1 = SS1 + GG + h + + mov t2, [rsp+ctr*sizeof(dword)+%%i*sizeof(dword)] ;; t2 = w[i] + add t1, t2 ;; t1 = TT2 + xor t2, [rsp+ctr*sizeof(dword)+(%%i+4)*sizeof(dword)] ;; t2 = w[i] ^ w[i+4] + + add t0, t2 ;; t0 = TT1 + + ROTL %%b, 9 + ROTL %%f, 19 + mov %%h, t0 + + mov %%d, t1 + ROTL %%d, 8 + xor %%d, t1 + ROTL %%d, 9 + xor %%d, t1 +%endmacro + +%macro SCHED_16_67 1.nolist + %xdefine %%i %1 + + mov t2, [rsp+ctr*sizeof(dword)+(%%i-3)*sizeof(dword)] ;; t2 = w[i-3] + ROTL t2, 15 ;; t2 = rol(t2,15) + xor t2, [rsp+ctr*sizeof(dword)+(%%i-9)*sizeof(dword)] ;; t2 ^= w[i-9] + xor t2, [rsp+ctr*sizeof(dword)+(%%i-16)*sizeof(dword)] ;; t2 ^= w[i-16] + + mov t3, t2 + ROTL t3, 8 + xor t3, t2 + ROTL t3, 15 + xor t3, t2 ;; t3 = P1 + + mov t2, [rsp+ctr*sizeof(dword)+(%%i-13)*sizeof(dword)] + xor t3, [rsp+ctr*sizeof(dword)+(%%i-6)*sizeof(dword)] + ROTL t2, 7 + xor t3, t2 + mov [rsp+ctr*sizeof(dword)+%%i*sizeof(dword)], t3 +%endmacro + +segment .text align=IPP_ALIGN_FACTOR + +align IPP_ALIGN_FACTOR + +bswap128 DB 3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12 + +;******************************************************************** +;* void UpdateSM3(uint32_t hash[8], +; const uint32_t msg[16], int msgLen, +; const uint32_t* K_SM3) +;******************************************************************** +align IPP_ALIGN_FACTOR +IPPASM UpdateSM3,PUBLIC +%assign LOCAL_FRAME 68*sizeof(dword)+3*sizeof(qword) + USES_GPR rbp,rbx,rsi,rdi,r12,r13,r14,r15 + USES_XMM + COMP_ABI 4 + +;; rdi = hash +;; rsi = data buffer +;; rdx = data buffer length (bytes) +;; rcx = address of SM3 constants + +;; stack structure: +%assign _w 0 ; msg extension W0, ..., W67 +%assign _hash _w+68*sizeof(dword) ; hash +%assign _msg _hash+sizeof(qword) ; msg pointer +%assign _len _msg+sizeof(qword) ; msg length + +%xdefine MBS_SM3 (64) + + movsxd rdx, edx + + mov qword [rsp+_hash], hPtr ; save hash pointer + mov qword [rsp+_len], rdx ; save msg length + + mov a, [hPtr+0*sizeof(dword)] ; input hash value + mov b, [hPtr+1*sizeof(dword)] + mov c, [hPtr+2*sizeof(dword)] + mov d, [hPtr+3*sizeof(dword)] + mov e, [hPtr+4*sizeof(dword)] + mov f, [hPtr+5*sizeof(dword)] + mov g, [hPtr+6*sizeof(dword)] + mov h, [hPtr+7*sizeof(dword)] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; process data block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align IPP_ALIGN_FACTOR +.main_loop: + xor ctr, ctr ; round + + movdqu xmm0, oword [mPtr+0*sizeof(oword)] + movdqu xmm1, oword [mPtr+1*sizeof(oword)] + movdqu xmm2, oword [mPtr+2*sizeof(oword)] + movdqu xmm3, oword [mPtr+3*sizeof(oword)] + add mPtr, MBS_SM3 + mov qword [rsp+_msg], mPtr ; save msg pointer + + pshufb xmm0, [rel bswap128] + pshufb xmm1, [rel bswap128] + pshufb xmm2, [rel bswap128] + pshufb xmm3, [rel bswap128] + + movdqu oword [rsp+0*sizeof(oword)], xmm0 + movdqu oword [rsp+1*sizeof(oword)], xmm1 + movdqu oword [rsp+2*sizeof(oword)], xmm2 + movdqu oword [rsp+3*sizeof(oword)], xmm3 + +align IPP_ALIGN_FACTOR +.rounds_00_15: + SCHED_16_67 16 + ROUND_00_15 a,b,c,d,e,f,g,h,0 + SCHED_16_67 17 + ROUND_00_15 h,a,b,c,d,e,f,g,1 + SCHED_16_67 18 + ROUND_00_15 g,h,a,b,c,d,e,f,2 + SCHED_16_67 19 + ROUND_00_15 f,g,h,a,b,c,d,e,3 + SCHED_16_67 20 + ROUND_00_15 e,f,g,h,a,b,c,d,4 + SCHED_16_67 21 + ROUND_00_15 d,e,f,g,h,a,b,c,5 + SCHED_16_67 22 + ROUND_00_15 c,d,e,f,g,h,a,b,6 + SCHED_16_67 23 + ROUND_00_15 b,c,d,e,f,g,h,a,7 + add ctr, 8 + cmp ctr, 16 + jne .rounds_00_15 + +align IPP_ALIGN_FACTOR +.rounds_16_47: + SCHED_16_67 16 + ROUND_16_63 a,b,c,d,e,f,g,h,0 + SCHED_16_67 17 + ROUND_16_63 h,a,b,c,d,e,f,g,1 + SCHED_16_67 18 + ROUND_16_63 g,h,a,b,c,d,e,f,2 + SCHED_16_67 19 + ROUND_16_63 f,g,h,a,b,c,d,e,3 + SCHED_16_67 20 + ROUND_16_63 e,f,g,h,a,b,c,d,4 + SCHED_16_67 21 + ROUND_16_63 d,e,f,g,h,a,b,c,5 + SCHED_16_67 22 + ROUND_16_63 c,d,e,f,g,h,a,b,6 + SCHED_16_67 23 + ROUND_16_63 b,c,d,e,f,g,h,a,7 + add ctr, 8 + cmp ctr, 48 + jne .rounds_16_47 + + SCHED_16_67 16 + SCHED_16_67 17 + SCHED_16_67 18 + SCHED_16_67 19 + +align IPP_ALIGN_FACTOR +.rounds_48_63: + ROUND_16_63 a,b,c,d,e,f,g,h,0 + ROUND_16_63 h,a,b,c,d,e,f,g,1 + ROUND_16_63 g,h,a,b,c,d,e,f,2 + ROUND_16_63 f,g,h,a,b,c,d,e,3 + ROUND_16_63 e,f,g,h,a,b,c,d,4 + ROUND_16_63 d,e,f,g,h,a,b,c,5 + ROUND_16_63 c,d,e,f,g,h,a,b,6 + ROUND_16_63 b,c,d,e,f,g,h,a,7 + add ctr, 8 + cmp ctr, 64 + jne .rounds_48_63 + + mov hPtr, [rsp+_hash] + mov mPtr, [rsp+_msg] + + xor a, [hPtr+0*sizeof(dword)] + xor b, [hPtr+1*sizeof(dword)] + xor c, [hPtr+2*sizeof(dword)] + xor d, [hPtr+3*sizeof(dword)] + xor e, [hPtr+4*sizeof(dword)] + xor f, [hPtr+5*sizeof(dword)] + xor g, [hPtr+6*sizeof(dword)] + xor h, [hPtr+7*sizeof(dword)] + + mov [hPtr+0*sizeof(dword)], a + mov [hPtr+1*sizeof(dword)], b + mov [hPtr+2*sizeof(dword)], c + mov [hPtr+3*sizeof(dword)], d + mov [hPtr+4*sizeof(dword)], e + mov [hPtr+5*sizeof(dword)], f + mov [hPtr+6*sizeof(dword)], g + mov [hPtr+7*sizeof(dword)], h + + sub qword [rsp+_len], MBS_SM3 + jne .main_loop + + REST_XMM + REST_GPR + ret +ENDFUNC UpdateSM3 + +%endif ;; ((_IPP32E >= _IPP32E_U8 ) AND (_IPP32E < _IPP32E_E9 )) OR (_IPP32E == _IPP32E_N8 ) +%endif ;; _ENABLE_ALG_SM3_ + diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpvariant.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpvariant.inc new file mode 100644 index 000000000..a1685e1a5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpvariant.inc @@ -0,0 +1,202 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Intel(R) Integrated Performance Primitives +; Cryptographic Primitives (ippcp) +; +; Purpose: +; Define ippCP variant +; +; do not changes in definitions below! +; + +;; +;; modes of the feature +;; +%assign _FEATURE_OFF_ 0 ;; feature is OFF +%assign _FEATURE_ON_ 1 ;; feature is ON +%assign _FEATURE_TICKTOCK_ 2 ;; dectect is feature OFF/ON + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; %define _XMM7560_ 1 +%ifdef _XMM7560_ +%include "pcpvariant_xmm7560.inc" +%endif + +; %define _TXT_ACM_ 1 +%ifdef _TXT_ACM_ +%include "pcpvariant_txt_acm.inc" +%endif +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +;; it possible to force use of C-version of some implementtaions +;; instead of ASM one +;; +%ifndef _USE_C_cpAdd_BNU_ + %assign _USE_C_cpAdd_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpSub_BNU_ + %assign _USE_C_cpSub_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpInc_BNU_ + %assign _USE_C_cpInc_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpAddMulDgt_BNU_ + %assign _USE_C_cpAddMulDgt_BNU_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpMulAdc_BNU_school_ + %assign _USE_C_cpMulAdc_BNU_school_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpSqrAdc_BNU_school_ + %assign _USE_C_cpMulSqr_BNU_school_ _FEATURE_OFF_ +%endif + +%ifndef _USE_C_cpMontRedAdc_BNU_ + %assign _USE_C_cpMontRedAdc_BNU_ _FEATURE_OFF_ +%endif + +;; +;; set _AES_NI_ENABLING_ +;; +%ifdef _IPP_AES_NI_ + %if (_IPP_AES_NI_ == 0) + %assign _AES_NI_ENABLING_ _FEATURE_OFF_ + %elif (_IPP_AES_NI_ == 1) + %assign _AES_NI_ENABLING_ _FEATURE_ON_ + %else + %error + %endif +%else + %if (_IPP32E >= _IPP32E_Y8) + %assign _AES_NI_ENABLING_ _FEATURE_TICKTOCK_ + %else + %assign _AES_NI_ENABLING_ _FEATURE_OFF_ + %endif +%endif + +;; +;; if there is no outside assignment +;; set _SHA_NI_ENABLING_ based on CPU specification +;; +%ifndef _SHA_NI_ENABLING_ + %if (_IPP32E >= _IPP32E_Y8 ) + %assign _SHA_NI_ENABLING_ _FEATURE_TICKTOCK_ + %else + %assign _SHA_NI_ENABLING_ _FEATURE_OFF_ + %endif +%endif + +;; +;; set _ADCOX_NI_ENABLING_ +;; +%ifdef _IPP_ADCX_NI_ + %if (_IPP_ADCX_NI_ == 0) + %assign _ADCOX_NI_ENABLING_ _FEATURE_OFF_ + %elif (_IPP_ADCX_NI_ == 1) + %assign _ADCOX_NI_ENABLING_ _FEATURE_ON_ + %else + %error + %endif +%else + %if (_IPP32E >= _IPP32E_L9) + %assign _ADCOX_NI_ENABLING_ _FEATURE_TICKTOCK_ + %else + %assign _ADCOX_NI_ENABLING_ _FEATURE_OFF_ + %endif +%endif + + +;; +;; select Hash algorithm +;; +%ifndef _DISABLE_ALG_SHA1_ + %assign _ENABLE_ALG_SHA1_ _FEATURE_ON_ ;; SHA1 on +%else + %assign _ENABLE_ALG_SHA1_ _FEATURE_OFF_ ;; SHA1 on +%endif + +%ifndef _DISABLE_ALG_SHA256_ + %assign _ENABLE_ALG_SHA256_ _FEATURE_ON_ ;; SHA256 on +%else + %assign _ENABLE_ALG_SHA256_ _FEATURE_OFF_ ;; SHA256 off +%endif + +%ifndef _DISABLE_ALG_SHA521_ + %assign _ENABLE_ALG_SHA512_ _FEATURE_ON_ ;; SHA512 on +%else + %assign _ENABLE_ALG_SHA512_ _FEATURE_OFF_ ;; SHA512 off +%endif + +%ifndef _DISABLE_ALG_MD5_ + %assign _ENABLE_ALG_MD5_ _FEATURE_ON_ ;; MD5 on +%else + %assign _ENABLE_ALG_MD5_ _FEATURE_OFF_ ;; MD5 off +%endif + +%ifndef _DISABLE_ALG_SM3_ + %assign _ENABLE_ALG_SM3_ _FEATURE_ON_ ;; SM3 on +%else + %assign _ENABLE_ALG_SM3_ _FEATURE_OFF_ ;; SM3 off +%endif + +;; +;; BN arithmetic +;; +%assign _ENABLE_KARATSUBA_ _FEATURE_OFF_ ;; not use Karatsuba method for multiplication + +;; +;; EC specific +;; +%assign _ECP_IMPL_NONE_ 0 +%assign _ECP_IMPL_ARBIRTRARY_ 1 +%assign _ECP_IMPL_SPECIFIC_ 2 +%assign _ECP_IMPL_MFM_ 3 + +%ifndef _ECP_128_ + %assign _ECP_128_ _ECP_IMPL_SPECIFIC_ +%endif + +%ifndef _ECP_192_ + %assign _ECP_192_ _ECP_IMPL_MFM_ +%endif + +%ifndef _ECP_224_ + %assign _ECP_224_ _ECP_IMPL_MFM_ +%endif + +%ifndef _ECP_256_ + %assign _ECP_256_ _ECP_IMPL_MFM_ +%endif + +%ifndef _ECP_384_ + %assign _ECP_384_ _ECP_IMPL_MFM_ +%endif + +%ifndef _ECP_521_ + %assign _ECP_521_ _ECP_IMPL_MFM_ +%endif + +%ifndef _ECP_SM2_ + %assign _ECP_SM2_ _ECP_IMPL_MFM_ +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpvariant_txt_acm.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpvariant_txt_acm.inc new file mode 100644 index 000000000..9045fd4e0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/pcpvariant_txt_acm.inc @@ -0,0 +1,40 @@ +;=============================================================================== +; Copyright (C) 2015 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; +; Intel(R) Integrated Performance Primitives +; Cryptographic Primitives (ippcp) +; +; Purpose: +; Update standard ippCP variant +; +; do not changes in definitions below! +; + +%ifdef _TXT_ACM_ + +;; +;; HASH algs outside settings +;; +%assign _SHA_NI_ENABLING_ _FEATURE_TICKTOCK_ + +;; +;; select Hash algorithm +;; +; %assign _ENABLE_ALG_MD5_ _FEATURE_OFF_ + +%endif diff --git a/plugin/ippcp/library/src/sources/ippcp/asm_intel64/reg_sizes.inc b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/reg_sizes.inc new file mode 100644 index 000000000..429796389 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/asm_intel64/reg_sizes.inc @@ -0,0 +1,290 @@ +;=============================================================================== +; Copyright (C) 2020 Intel Corporation +; +; Licensed under the Apache License, Version 2.0 (the 'License'); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, +; software distributed under the License is distributed on an 'AS IS' BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions +; and limitations under the License. +; +;=============================================================================== + +; define d and w variants for registers + +%ifndef _REG_SIZES_ASM_ +%define _REG_SIZES_ASM_ + +%define raxd eax +%define raxw ax +%define raxb al + +%define rbxd ebx +%define rbxw bx +%define rbxb bl + +%define rcxd ecx +%define rcxw cx +%define rcxb cl + +%define rdxd edx +%define rdxw dx +%define rdxb dl + +%define rsid esi +%define rsiw si +%define rsib sil + +%define rdid edi +%define rdiw di +%define rdib dil + +%define rbpd ebp +%define rbpw bp +%define rbpb bpl + +%define zmm0x xmm0 +%define zmm1x xmm1 +%define zmm2x xmm2 +%define zmm3x xmm3 +%define zmm4x xmm4 +%define zmm5x xmm5 +%define zmm6x xmm6 +%define zmm7x xmm7 +%define zmm8x xmm8 +%define zmm9x xmm9 +%define zmm10x xmm10 +%define zmm11x xmm11 +%define zmm12x xmm12 +%define zmm13x xmm13 +%define zmm14x xmm14 +%define zmm15x xmm15 +%define zmm16x xmm16 +%define zmm17x xmm17 +%define zmm18x xmm18 +%define zmm19x xmm19 +%define zmm20x xmm20 +%define zmm21x xmm21 +%define zmm22x xmm22 +%define zmm23x xmm23 +%define zmm24x xmm24 +%define zmm25x xmm25 +%define zmm26x xmm26 +%define zmm27x xmm27 +%define zmm28x xmm28 +%define zmm29x xmm29 +%define zmm30x xmm30 +%define zmm31x xmm31 + +%define ymm0x xmm0 +%define ymm1x xmm1 +%define ymm2x xmm2 +%define ymm3x xmm3 +%define ymm4x xmm4 +%define ymm5x xmm5 +%define ymm6x xmm6 +%define ymm7x xmm7 +%define ymm8x xmm8 +%define ymm9x xmm9 +%define ymm10x xmm10 +%define ymm11x xmm11 +%define ymm12x xmm12 +%define ymm13x xmm13 +%define ymm14x xmm14 +%define ymm15x xmm15 +%define ymm16x xmm16 +%define ymm17x xmm17 +%define ymm18x xmm18 +%define ymm19x xmm19 +%define ymm20x xmm20 +%define ymm21x xmm21 +%define ymm22x xmm22 +%define ymm23x xmm23 +%define ymm24x xmm24 +%define ymm25x xmm25 +%define ymm26x xmm26 +%define ymm27x xmm27 +%define ymm28x xmm28 +%define ymm29x xmm29 +%define ymm30x xmm30 +%define ymm31x xmm31 + +%define xmm0x xmm0 +%define xmm1x xmm1 +%define xmm2x xmm2 +%define xmm3x xmm3 +%define xmm4x xmm4 +%define xmm5x xmm5 +%define xmm6x xmm6 +%define xmm7x xmm7 +%define xmm8x xmm8 +%define xmm9x xmm9 +%define xmm10x xmm10 +%define xmm11x xmm11 +%define xmm12x xmm12 +%define xmm13x xmm13 +%define xmm14x xmm14 +%define xmm15x xmm15 +%define xmm16x xmm16 +%define xmm17x xmm17 +%define xmm18x xmm18 +%define xmm19x xmm19 +%define xmm20x xmm20 +%define xmm21x xmm21 +%define xmm22x xmm22 +%define xmm23x xmm23 +%define xmm24x xmm24 +%define xmm25x xmm25 +%define xmm26x xmm26 +%define xmm27x xmm27 +%define xmm28x xmm28 +%define xmm29x xmm29 +%define xmm30x xmm30 +%define xmm31x xmm31 + +%define zmm0y ymm0 +%define zmm1y ymm1 +%define zmm2y ymm2 +%define zmm3y ymm3 +%define zmm4y ymm4 +%define zmm5y ymm5 +%define zmm6y ymm6 +%define zmm7y ymm7 +%define zmm8y ymm8 +%define zmm9y ymm9 +%define zmm10y ymm10 +%define zmm11y ymm11 +%define zmm12y ymm12 +%define zmm13y ymm13 +%define zmm14y ymm14 +%define zmm15y ymm15 +%define zmm16y ymm16 +%define zmm17y ymm17 +%define zmm18y ymm18 +%define zmm19y ymm19 +%define zmm20y ymm20 +%define zmm21y ymm21 +%define zmm22y ymm22 +%define zmm23y ymm23 +%define zmm24y ymm24 +%define zmm25y ymm25 +%define zmm26y ymm26 +%define zmm27y ymm27 +%define zmm28y ymm28 +%define zmm29y ymm29 +%define zmm30y ymm30 +%define zmm31y ymm31 + +%define xmm0y ymm0 +%define xmm1y ymm1 +%define xmm2y ymm2 +%define xmm3y ymm3 +%define xmm4y ymm4 +%define xmm5y ymm5 +%define xmm6y ymm6 +%define xmm7y ymm7 +%define xmm8y ymm8 +%define xmm9y ymm9 +%define xmm10y ymm10 +%define xmm11y ymm11 +%define xmm12y ymm12 +%define xmm13y ymm13 +%define xmm14y ymm14 +%define xmm15y ymm15 +%define xmm16y ymm16 +%define xmm17y ymm17 +%define xmm18y ymm18 +%define xmm19y ymm19 +%define xmm20y ymm20 +%define xmm21y ymm21 +%define xmm22y ymm22 +%define xmm23y ymm23 +%define xmm24y ymm24 +%define xmm25y ymm25 +%define xmm26y ymm26 +%define xmm27y ymm27 +%define xmm28y ymm28 +%define xmm29y ymm29 +%define xmm30y ymm30 +%define xmm31y ymm31 + +%define xmm0z zmm0 +%define xmm1z zmm1 +%define xmm2z zmm2 +%define xmm3z zmm3 +%define xmm4z zmm4 +%define xmm5z zmm5 +%define xmm6z zmm6 +%define xmm7z zmm7 +%define xmm8z zmm8 +%define xmm9z zmm9 +%define xmm10z zmm10 +%define xmm11z zmm11 +%define xmm12z zmm12 +%define xmm13z zmm13 +%define xmm14z zmm14 +%define xmm15z zmm15 +%define xmm16z zmm16 +%define xmm17z zmm17 +%define xmm18z zmm18 +%define xmm19z zmm19 +%define xmm20z zmm20 +%define xmm21z zmm21 +%define xmm22z zmm22 +%define xmm23z zmm23 +%define xmm24z zmm24 +%define xmm25z zmm25 +%define xmm26z zmm26 +%define xmm27z zmm27 +%define xmm28z zmm28 +%define xmm29z zmm29 +%define xmm30z zmm30 +%define xmm31z zmm31 + +%define ymm0z zmm0 +%define ymm1z zmm1 +%define ymm2z zmm2 +%define ymm3z zmm3 +%define ymm4z zmm4 +%define ymm5z zmm5 +%define ymm6z zmm6 +%define ymm7z zmm7 +%define ymm8z zmm8 +%define ymm9z zmm9 +%define ymm10z zmm10 +%define ymm11z zmm11 +%define ymm12z zmm12 +%define ymm13z zmm13 +%define ymm14z zmm14 +%define ymm15z zmm15 +%define ymm16z zmm16 +%define ymm17z zmm17 +%define ymm18z zmm18 +%define ymm19z zmm19 +%define ymm20z zmm20 +%define ymm21z zmm21 +%define ymm22z zmm22 +%define ymm23z zmm23 +%define ymm24z zmm24 +%define ymm25z zmm25 +%define ymm26z zmm26 +%define ymm27z zmm27 +%define ymm28z zmm28 +%define ymm29z zmm29 +%define ymm30z zmm30 +%define ymm31z zmm31 + +%define DWORD(reg) reg %+ d +%define WORD(reg) reg %+ w +%define BYTE(reg) reg %+ b + +%define XWORD(reg) reg %+ x +%define YWORD(reg) reg %+ y +%define ZWORD(reg) reg %+ z + +%endif ;; _REG_SIZES_ASM_ diff --git a/plugin/ippcp/library/src/sources/ippcp/cpinit.c b/plugin/ippcp/library/src/sources/ippcp/cpinit.c new file mode 100644 index 000000000..1cde86db6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/cpinit.c @@ -0,0 +1,475 @@ +/******************************************************************************* +* Copyright (C) 2001 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// + +#include "owndefs.h" +#include "ippcpdefs.h" +#include "ippcp.h" +#include "dispatcher.h" + +#if defined( _IPP_DATA ) + +static Ipp64u cpFeatures = 0; +static Ipp64u cpFeaturesMask = 0; + +static int cpGetFeatures( Ipp64u* pFeaturesMask ); + +extern IPP_OWN_DECL (void, cpGetReg, ( int* buf, int valEAX, int valECX )) +extern IPP_OWN_DECL (int, cp_is_avx_extension, ( void )) +extern IPP_OWN_DECL (int, cp_is_avx512_extension, ( void )) +extern IPP_OWN_DECL (int, cp_issue_avx512_instruction, ( void )) + +IppStatus owncpSetCpuFeaturesAndIdx( Ipp64u cpuFeatures, int* index ); + +IPPFUN( Ipp64u, ippcpGetEnabledCpuFeatures, ( void )) +{ + return cpFeaturesMask; +} + +/*===================================================================*/ +IPPFUN( IppStatus, ippcpGetCpuFeatures, ( Ipp64u* pFeaturesMask )) +{ + IPP_BAD_PTR1_RET( pFeaturesMask ) + { + if( 0 != cpFeatures){ + *pFeaturesMask = cpFeatures;// & cpFeaturesMask; + } else { + int ret = cpGetFeatures( pFeaturesMask ); + if( !ret ) return ippStsNotSupportedCpu; + } + return ippStsNoErr; + } +} + +/*===================================================================*/ + +int cpGetFeature( Ipp64u Feature ) +{ + // We provide users the ability to build their own custom build of 1cpu Intel® IPP Cryptography library + // and turn CPU features on at compile-time if they are sure these features available on the target systems. + #if (!defined(_MERGED_BLD) && defined(IPPCP_CUSTOM_BUILD)) + int if_feature_enabled = ((IPP_CUSTOM_ENABLED_FEATURES & Feature) == Feature); + return if_feature_enabled; + #else + if( 0 == cpFeaturesMask ) { + Ipp64u loc_features; + // set up cpFeaturesMask and cpFeatures for the proper work of tick-tok in 1cpu libraries + ippcpGetCpuFeatures(&loc_features); + } + + if((cpFeaturesMask & Feature) == Feature) { + return 1; + } else { + return 0; + } + #endif +} + +/*===================================================================*/ +#define BIT00 0x00000001 +#define BIT01 0x00000002 +#define BIT02 0x00000004 +#define BIT03 0x00000008 +#define BIT04 0x00000010 +#define BIT05 0x00000020 +#define BIT06 0x00000040 +#define BIT07 0x00000080 +#define BIT08 0x00000100 +#define BIT09 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + + +static int cpGetFeatures( Ipp64u* pFeaturesMask ) +{ + Ipp32u buf[4]; + Ipp32u eax_, ebx_, ecx_, edx_, tmp; + Ipp64u mask; + int flgFMA=0, flgINT=0, flgGPR=0; // for avx2 + Ipp32u idBaseMax, idExtdMax; + + cpGetReg((int*)buf, 0, 0); //get max value for basic info. + idBaseMax = buf[0]; + cpGetReg((int*)buf, (Ipp32s)0x80000000, 0); //get max value for extended info. + idExtdMax = buf[0]; + + cpGetReg( (int*)buf, 1, 0 ); + eax_ = (Ipp32u)buf[0]; + ecx_ = (Ipp32u)buf[2]; + edx_ = (Ipp32u)buf[3]; + mask = 0; + if( edx_ & BIT23 ) mask |= ippCPUID_MMX; // edx[23] - MMX(TM) Technology + if( edx_ & BIT25 ) mask |= ippCPUID_SSE; // edx[25] - Intel® Streaming SIMD Extensions (Intel® SSE) + if( edx_ & BIT26 ) mask |= ippCPUID_SSE2; // edx[26] - Intel® Streaming SIMD Extensions 2 (Intel® SSE2) + if( ecx_ & BIT00 ) mask |= ippCPUID_SSE3; // ecx[0] - Intel® Streaming SIMD Extensions 3 (Intel® SSE3) (formerly codenamed Prescott) + if( ecx_ & BIT09 ) mask |= ippCPUID_SSSE3; // ecx[9] - Supplemental Streaming SIMD Extensions 3 (SSSE3) (formerly codenamed Merom) + if( ecx_ & BIT22 ) mask |= ippCPUID_MOVBE; // ecx[22] - Intel® instruction MOVBE (Intel Atom® processor) + if( ecx_ & BIT19 ) mask |= ippCPUID_SSE41; // ecx[19] - Intel® Streaming SIMD Extensions 4.1 (Intel® SSE4.1) (formerly codenamed Penryn) + if( ecx_ & BIT20 ) mask |= ippCPUID_SSE42; // ecx[20] - Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) (formerly codenamed Nenalem) + if( ecx_ & BIT28 ) mask |= ippCPUID_AVX; // ecx[28] - Intel® Advanced Vector Extensions (Intel® AVX) (formerly codenamed Sandy Bridge) + if(( ecx_ & 0x18000000 ) == 0x18000000 ){ + tmp = (Ipp32u)cp_is_avx_extension(); + if( tmp & BIT00 ) mask |= ippAVX_ENABLEDBYOS; // Intel® AVX is supported by OS + } + if( ecx_ & BIT25 ) mask |= ippCPUID_AES; // ecx[25] - Intel® AES New Instructions + if( ecx_ & BIT01 ) mask |= ippCPUID_CLMUL; // ecx[1] - Intel® instruction PCLMULQDQ + if( ecx_ & BIT30 ) mask |= ippCPUID_RDRAND; // ecx[30] - Intel® instruction RDRRAND + if( ecx_ & BIT29 ) mask |= ippCPUID_F16C; // ecx[29] - Intel® instruction F16C + // Intel® AVX2 instructions extention: only if 3 features are enabled at once: + // FMA, Intel® AVX 256 int & GPR BMI (bit-manipulation); + if( ecx_ & BIT12 ) flgFMA = 1; else flgFMA = 0; // ecx[12] - FMA 128 & 256 bit + if( idBaseMax >= 7 ){ // get CPUID.eax = 7 + cpGetReg( (int*)buf, 0x7, 0 ); + ebx_ = (Ipp32u)buf[1]; + ecx_ = (Ipp32u)buf[2]; + edx_ = (Ipp32u)buf[3]; + if( ebx_ & BIT05 ) flgINT = 1; + else flgINT = 0; //ebx[5], Intel® Advanced Vector Extensions 2 (Intel® AVX2) (int 256bits) + // ebx[3] - enabled ANDN, BEXTR, BLSI, BLSMK, BLSR, TZCNT + // ebx[8] - enabled BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX + if(( ebx_ & BIT03 )&&( ebx_ & BIT08 )) flgGPR = 1; + else flgGPR = 0; // VEX-encoded GPR instructions (GPR BMI) + // Intel® architecture formerly codenamed Broadwell instructions extention + if( ebx_ & BIT19 ) mask |= ippCPUID_ADCOX; // eax[0x7] -->> ebx:: Bit 19: Intel® instructions ADOX/ADCX + if( ebx_ & BIT18 ) mask |= ippCPUID_RDSEED; // eax[0x7] -->> ebx:: Bit 18: Intel® instruction RDSEED + if( ebx_ & BIT29 ) mask |= ippCPUID_SHA; // eax[0x7] -->> ebx:: Bit 29: Intel® Secure Hash Algorithm Extensions + + if( ecx_ & BIT09 ) mask |= ippCPUID_AVX2VAES; // ecx[09] - Intel® Vector AES instruction set + if( ecx_ & BIT10 ) mask |= ippCPUID_AVX2VCLMUL; // ecx[10] - Intel® instruction VPCLMULQDQ + + // Intel® Advanced Vector Extensions 512 (Intel® AVX-512) extention + if( ebx_ & BIT16 ) mask |= ippCPUID_AVX512F; // ebx[16] - Intel® AVX-512 Foundation + if( ebx_ & BIT26 ) mask |= ippCPUID_AVX512PF; // ebx[26] - Intel® AVX-512 Pre Fetch Instructions (PFI) + if( ebx_ & BIT27 ) mask |= ippCPUID_AVX512ER; // ebx[27] - Intel® AVX-512 Exponential and Reciprocal Instructions (ERI) + if( ebx_ & BIT28 ) mask |= ippCPUID_AVX512CD; // ebx[28] - Intel® AVX-512 Conflict Detection + if( ebx_ & BIT17 ) mask |= ippCPUID_AVX512DQ; // ebx[17] - Intel® AVX-512 Dword & Quadword + if( ebx_ & BIT30 ) mask |= ippCPUID_AVX512BW; // ebx[30] - Intel® AVX-512 Byte & Word + if( ebx_ & BIT31 ) mask |= ippCPUID_AVX512VL; // ebx[31] - Intel® AVX-512 Vector Length Extensions (VLE) + if( ecx_ & BIT01 ) mask |= ippCPUID_AVX512VBMI; // ecx[01] - Intel® AVX-512 Vector Bit Manipulation Instructions + if( ecx_ & BIT06 ) mask |= ippCPUID_AVX512VBMI2; // ecx[06] - Intel® AVX-512 Vector Bit Manipulation Instructions 2 + if( edx_ & BIT02 ) mask |= ippCPUID_AVX512_4VNNIW; // edx[02] - Intel® AVX-512 Vector instructions for deep learning enhanced word variable precision + if( edx_ & BIT03 ) mask |= ippCPUID_AVX512_4FMADDPS; // edx[03] - Intel® AVX-512 Vector instructions for deep learning floating-point single precision + // bitwise OR between ippCPUID_MPX & ippCPUID_AVX flags can be used to define that arch is GE than formerly codenamed Skylake + if( ebx_ & BIT14 ) mask |= ippCPUID_MPX; // ebx[14] - Intel® Memory Protection Extensions (Intel® MPX) + if( ebx_ & BIT21 ) mask |= ippCPUID_AVX512IFMA; // ebx[21] - Intel® AVX-512 IFMA PMADD52 + + if (ecx_ & BIT08) mask |= ippCPUID_AVX512GFNI; // test bit ecx[08] + if (ecx_ & BIT09) mask |= ippCPUID_AVX512VAES; // test bit ecx[09] + if (ecx_ & BIT10) mask |= ippCPUID_AVX512VCLMUL; // test bit ecx[10] + + if (mask & ippCPUID_AVX512F) { + /* test if Intel® AVX-512 is supported by OS */ + if (cp_is_avx512_extension()) + mask |= ippAVX512_ENABLEDBYOS; + + #if defined(OSXEM64T) + else { + /* submit some avx512f instructions, returns 0 */ + mask |= cp_issue_avx512_instruction(); + /* and check OS support again */ + if (cp_is_avx512_extension()) + mask |= ippAVX512_ENABLEDBYOS; + } + #endif + } + } + mask = ( flgFMA && flgINT && flgGPR ) ? (mask | ippCPUID_AVX2) : mask; // to separate Intel® AVX2 flags here + + if( idExtdMax >= 0x80000001 ){ // get CPUID.eax=0x80000001 + cpGetReg( (int*)buf, (Ipp32s)0x80000001, 0 ); + ecx_ = (Ipp32u)buf[2]; + // Intel® architecture formerly codenamed Broadwell instructions extention + if( ecx_ & BIT08 ) mask |= ippCPUID_PREFETCHW; // eax[0x80000001] -->> ecx:: Bit 8: Intel® instruction PREFETCHW + } + // Intel® architecture formerly codenamed Knights Corner + if(((( eax_ << 20 ) >> 24 ) ^ 0xb1 ) == 0 ){ + mask = mask | ippCPUID_KNC; + } + cpFeatures = mask; + cpFeaturesMask = mask; /* all CPU features are enabled by default */ + *pFeaturesMask = cpFeatures; + return 1; /* if somebody need to check for cpuid support - do it at the top of function and return 0 if it's not supported */ +} + +int ippcpJumpIndexForMergedLibs = -1; +static int cpthreads_omp_of_n_ipp = 1; + +IPPFUN( int, ippcpGetEnabledNumThreads,( void )) +{ + return cpthreads_omp_of_n_ipp; +} + + +#define AVX3X_FEATURES ( ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512VL|ippCPUID_AVX512BW|ippCPUID_AVX512DQ ) +#define AVX3M_FEATURES ( ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512PF|ippCPUID_AVX512ER ) +// AVX3X_FEATURES means Intel® Xeon® processor +// AVX3M_FEATURES means Intel® Many Integrated Core Architecture +#define AVX3I_FEATURES ( AVX3X_FEATURES| \ + ippCPUID_SHA|ippCPUID_AVX512VBMI|ippCPUID_AVX512VBMI2| \ + ippCPUID_AVX512IFMA| \ + ippCPUID_AVX512GFNI|ippCPUID_AVX512VAES|ippCPUID_AVX512VCLMUL) + + +IppStatus owncpFeaturesToIdx( Ipp64u* cpuFeatures, int* index ) +{ + IppStatus ownStatus = ippStsNoErr; + Ipp64u mask = 0; + + *index = 0; + + if(( AVX3I_FEATURES == ( *cpuFeatures & AVX3I_FEATURES ))&& + ( ippAVX512_ENABLEDBYOS & cpFeatures )){ /* Intel® architecture formerly codenamed Icelake ia32=S0, x64=K0 */ + mask = AVX3I_MSK; + *index = LIB_AVX3I; + } else + if(( AVX3X_FEATURES == ( *cpuFeatures & AVX3X_FEATURES ))&& + ( ippAVX512_ENABLEDBYOS & cpFeatures )){ /* Intel® architecture formerly codenamed Skylake ia32=S0, x64=K0 */ + mask = AVX3X_MSK; + *index = LIB_AVX3X; + } else + if(( AVX3M_FEATURES == ( *cpuFeatures & AVX3M_FEATURES ))&& + ( ippAVX512_ENABLEDBYOS & cpFeatures )){ /* Intel® architecture formerly codenamed Knights Landing ia32=i0, x64=N0 */ + mask = AVX3M_MSK; + *index = LIB_AVX3M; + } else + if(( ippCPUID_AVX2 == ( *cpuFeatures & ippCPUID_AVX2 ))&& + ( ippAVX_ENABLEDBYOS & cpFeatures )){ /* Intel® architecture formerly codenamed Haswell ia32=H9, x64=L9 */ + mask = AVX2_MSK; + *index = LIB_AVX2; + } else + if(( ippCPUID_AVX == ( *cpuFeatures & ippCPUID_AVX ))&& + ( ippAVX_ENABLEDBYOS & cpFeatures )){ /* Intel® architecture formerly codenamed Sandy Bridge ia32=G9, x64=E9 */ + mask = AVX_MSK; + *index = LIB_AVX; + } else + if( ippCPUID_SSE42 == ( *cpuFeatures & ippCPUID_SSE42 )){ /* Intel® microarchitecture code name Nehalem or Intel® architecture formerly codenamed Westmer = Intel® architecture formerly codenamed Penryn + Intel® SSE4.2 + ?Intel® instruction PCLMULQDQ + ?(Intel® AES New Instructions) + ?(Intel® Secure Hash Algorithm Extensions) */ + mask = SSE42_MSK; /* or new Intel Atom® processor formerly codenamed Silvermont */ + *index = LIB_SSE42; + } else + if( ippCPUID_SSE41 == ( *cpuFeatures & ippCPUID_SSE41 )){ /* Intel® architecture formerly codenamed Penryn ia32=P8, x64=Y8 */ + mask = SSE41_MSK; + *index = LIB_SSE41; + } else + if( ippCPUID_MOVBE == ( *cpuFeatures & ippCPUID_MOVBE )) { /* Intel Atom® processor formerly codenamed Silverthorne ia32=S8, x64=N8 */ + mask = ATOM_MSK; + *index = LIB_ATOM; + } else + if( ippCPUID_SSSE3 == ( *cpuFeatures & ippCPUID_SSSE3 )) { /* Intel® architecture formerly codenamed Merom ia32=V8, x64=U8 (letters etymology is unknown) */ + mask = SSSE3_MSK; + *index = LIB_SSSE3; + } else + if( ippCPUID_SSE3 == ( *cpuFeatures & ippCPUID_SSE3 )) { /* Intel® architecture formerly codenamed Prescott ia32=W7, x64=M7 */ + mask = SSE3_MSK; + *index = LIB_SSE3; + } else + if( ippCPUID_SSE2 == ( *cpuFeatures & ippCPUID_SSE2 )) { /* Intel® architecture formerly codenamed Willamette ia32=W7, x64=PX */ + mask = SSE2_MSK; + *index = LIB_SSE2; + } else + if( ippCPUID_SSE == ( *cpuFeatures & ippCPUID_SSE )) { /* Intel® Pentium® processor III ia32=PX only */ + mask = SSE_MSK; + *index = LIB_SSE; +#if (defined( WIN32E ) || defined( LINUX32E ) || defined( OSXEM64T )) && !(defined( _ARCH_LRB2 )) + ownStatus = ippStsNotSupportedCpu; /* the lowest CPU supported by Intel IPP Cryptography must at least support Intel® SSE2 for x64 */ +#endif + } else /* not supported, PX dispatched */ + { + mask = MMX_MSK; + *index = LIB_MMX; + ownStatus = ippStsNotSupportedCpu; /* the lowest CPU supported by Intel IPP Cryptography must at least support Intel® SSE for ia32 or Intel® SSE2 for x64 */ + } + + if(( mask != ( *cpuFeatures & mask ))&&( ownStatus == ippStsNoErr )) + ownStatus = ippStsFeaturesCombination; /* warning if combination of features is incomplete */ + *cpuFeatures |= mask; + return ownStatus; +} + + +IPPFUN(IppStatus, ippcpSetNumThreads, (int numThr)) +{ + IppStatus status = ippStsNoErr; + + IPP_UNREFERENCED_PARAMETER(numThr); + status = ippStsNoOperation; + + return status; +} + +IPPFUN(IppStatus, ippcpGetNumThreads, (int* pNumThr)) +{ + IppStatus status = ippStsNoErr; + IPP_BAD_PTR1_RET(pNumThr) + + *pNumThr = 1; + status = ippStsNoOperation; + + return status; +} + +IPPFUN( IppStatus, ippcpInit,( void )) +{ + Ipp64u cpuFeatures; + + ippcpGetCpuFeatures( &cpuFeatures ); + return ippcpSetCpuFeatures( cpuFeatures ); +} + + +IPPFUN( IppStatus, ippcpSetCpuFeatures,( Ipp64u cpuFeatures )) +{ + IppStatus ownStatus; + int index = 0; + + ownStatus = owncpSetCpuFeaturesAndIdx( cpuFeatures, &index ); + ippcpJumpIndexForMergedLibs = index; + cpFeaturesMask = cpuFeatures; + return ownStatus; +} + +IppStatus owncpSetCpuFeaturesAndIdx(Ipp64u cpuFeatures, int* index) +{ + Ipp64u tmp; + IppStatus tmpStatus; + *index = 0; + + if (ippCPUID_NOCHECK & cpuFeatures) { + // if NOCHECK is set - static variable cpFeatures is initialized unconditionally and real CPU features from CPUID are ignored; + // the one who uses this method of initialization must understand what and why it does and the possible unpredictable consequences. + // the only one known purpose for this approach - environments where CPUID instruction is disabled (for example Intel® Software Guard Extensions). + cpuFeatures &= (IPP_MAX_64U ^ ippCPUID_NOCHECK); + cpFeatures = cpuFeatures; + } + else + /* read cpu features unconditionally */ + cpGetFeatures(&tmp); + + tmpStatus = owncpFeaturesToIdx(&cpuFeatures, index); + cpFeaturesMask = cpuFeatures; + + return tmpStatus; +} + +static struct { + int sts; + const char *msg; +} ippcpMsg[] = { +/* ippStatus */ +/* -9999 */ ippStsCpuNotSupportedErr, "ippStsCpuNotSupportedErr: The target CPU is not supported", +/* -9702 */ MSG_NO_SHARED, "No shared libraries were found in the Waterfall procedure", +/* -9701 */ MSG_NO_DLL, "No DLLs were found in the Waterfall procedure", +/* -9700 */ MSG_LOAD_DLL_ERR, "Error at loading of %s library", +/* -1017 */ ippStsInvalidPoint, "ippStsInvalidPoint ECC: Invalid point (out of EC)", +/* -1016 */ ippStsQuadraticNonResidueErr, "ippStsQuadraticNonResidueErr: SQRT operation on quadratic non-residue value", +/* -1015 */ ippStsPointAtInfinity, "ippStsPointAtInfinity: Point at infinity is detected", +/* -1014 */ ippStsOFBSizeErr, "ippStsOFBSizeErr: Incorrect value for crypto OFB block size", +/* -1013 */ ippStsIncompleteContextErr, "ippStsIncompleteContextErr: Crypto: set up of context is not complete", +/* -1012 */ ippStsCTRSizeErr, "ippStsCTRSizeErr: Incorrect value for crypto CTR block size", +/* -1011 */ ippStsEphemeralKeyErr, "ippStsEphemeralKeyErr: ECC: Invalid ephemeral key", +/* -1010 */ ippStsMessageErr, "ippStsMessageErr: ECC: Invalid message digest", +/* -1009 */ ippStsShareKeyErr, "ippStsShareKeyErr: ECC: Invalid share key", +/* -1008 */ ippStsInvalidPrivateKey, "ippStsInvalidPrivateKey ECC: Invalid private key", +/* -1007 */ ippStsOutOfECErr, "ippStsOutOfECErr: ECC: Point out of EC", +/* -1006 */ ippStsECCInvalidFlagErr, "ippStsECCInvalidFlagErr: ECC: Invalid Flag", +/* -1005 */ ippStsUnderRunErr, "ippStsUnderRunErr: Error in data under run", +/* -1004 */ ippStsPaddingErr, "ippStsPaddingErr: Detected padding error indicates the possible data corruption", +/* -1003 */ ippStsCFBSizeErr, "ippStsCFBSizeErr: Incorrect value for crypto CFB block size", +/* -1002 */ ippStsPaddingSchemeErr, "ippStsPaddingSchemeErr: Invalid padding scheme", +/* -1001 */ ippStsBadModulusErr, "ippStsBadModulusErr: Bad modulus caused a failure in module inversion", +/* -216 */ ippStsUnknownStatusCodeErr, "ippStsUnknownStatusCodeErr: Unknown status code", +/* -221 */ ippStsLoadDynErr, "ippStsLoadDynErr: Error when loading the dynamic library", +/* -15 */ ippStsLengthErr, "ippStsLengthErr: Incorrect value for string length", +/* -14 */ ippStsNotSupportedModeErr, "ippStsNotSupportedModeErr: The requested mode is currently not supported", +/* -13 */ ippStsContextMatchErr, "ippStsContextMatchErr: Context parameter does not match the operation", +/* -12 */ ippStsScaleRangeErr, "ippStsScaleRangeErr: Scale bounds are out of range", +/* -11 */ ippStsOutOfRangeErr, "ippStsOutOfRangeErr: Argument is out of range, or point is outside the image", +/* -10 */ ippStsDivByZeroErr, "ippStsDivByZeroErr: An attempt to divide by zero", +/* -9 */ ippStsMemAllocErr, "ippStsMemAllocErr: Memory allocated for the operation is not enough", +/* -8 */ ippStsNullPtrErr, "ippStsNullPtrErr: Null pointer error", +/* -7 */ ippStsRangeErr, "ippStsRangeErr: Incorrect values for bounds: the lower bound is greater than the upper bound", +/* -6 */ ippStsSizeErr, "ippStsSizeErr: Incorrect value for data size", +/* -5 */ ippStsBadArgErr, "ippStsBadArgErr: Incorrect arg/param of the function", +/* -4 */ ippStsNoMemErr, "ippStsNoMemErr: Not enough memory for the operation", +/* -2 */ ippStsErr, "ippStsErr: Unknown/unspecified error, -2", +/* 0 */ ippStsNoErr, "ippStsNoErr: No errors", +/* 1 */ ippStsNoOperation, "ippStsNoOperation: No operation has been executed", +/* 2 */ ippStsDivByZero, "ippStsDivByZero: Zero value(s) for the divisor in the Div function", +/* 25 */ ippStsInsufficientEntropy, "ippStsInsufficientEntropy: Generation of the prime/key failed due to insufficient entropy in the random seed and stimulus bit string", +/* 36 */ ippStsNotSupportedCpu, "The CPU is not supported", +/* 51 */ ippStsFeaturesCombination, "Wrong combination of features", +/* 53 */ ippStsMbWarning, "ippStsMbWarning: Error(s) in statuses array", +}; + +/* ///////////////////////////////////////////////////////////////////////////// +// Name: ippcpGetStatusString +// Purpose: transformation of a code of a status Intel IPP Cryptography to string +// Returns: +// Parameters: +// StsCode Intel IPP Cryptography status code +// +// Notes: not necessary to release the returned string +*/ +IPPFUN( const char*, ippcpGetStatusString, ( IppStatus StsCode ) ) +{ + unsigned int i; + for( i=0; i:$ENV{ROOT}/compiler/include $ENV{ROOT}/compiler/include/icc> + $<$>:${CMAKE_SYSTEM_INCLUDE_PATH}> + $<$,$>:$ENV{INCLUDE}> +) + +add_subdirectory(src) diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/Readme.md b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/Readme.md new file mode 100644 index 000000000..ae3e07e46 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/Readme.md @@ -0,0 +1,135 @@ +# Crypto Multi-buffer Library + +Currently, the library provides optimized version of the following algorithms: +1. RSA, ECDSA, ECDH, x25519 multi-buffer algorithms based on Intel® Advanced Vector Extensions 512 (Intel® AVX-512) integer fused multiply-add (IFMA) operations. This CPU feature is introduced with Intel® Microarchitecture Code Named Ice Lake. +2. SM4 based on Intel(R) Advanced Vector Extensions 512 (Intel(R) AVX-512) GFNI instructions. +3. SM3 based on Intel® Advanced Vector Extensions 512 (Intel® AVX-512) instructions. + +## Multiple Buffers Processing Overview + +Some of the cryptography algorithms cannot be parallelized due to their specificity. For example, the RSA algorithm consists of big-number (multi-digit) arithmetic: multi-precision modular multiplications and squaring operations. + +Digits of multi-digit numbers are dependent because of carry propagation during arithmetic operations. Therefore, single RSA computation based on general purpose mul/adc instructions is not efficient. + +The way to get high-performance implementations of such cryptographic algorithms is a parallel processing using *single instruction, multiple data* (SIMD) architecture. The usage model implies presence of several independent and homogeneous (encryption or decryption) requests for RSA operations, using of SIMD leads to performance improvement. + +Multi-buffer processing collects up to eight RSA operations. Each request is computed independently from the others, so it is possible to process several packets at the same time. + +This library consists of highly-optimized kernels taking advantage of Intel’s multi-buffer processing and Intel® AVX-512 instruction set. + +## Software Requirements + +### Common + +- CMake\* 3.10 or higher +- The Netwide Assembler (NASM) 2.14\* +- OpenSSL\* 3.0.8 or higher + +### Linux* OS + +- Intel® C++ Compiler Classic 2021.9 for Linux\* OS +- GCC 8.3 +- GCC 9.1 +- GCC 10.1 +- GCC 11.1 +- Clang 9.0 +- Clang 12.0 +- GNU binutils 2.32 + +### Windows* OS + +- Intel® C++ Compiler Classic 2021.9 for Windows\* OS +- Microsoft Visual C++ Compiler\* version 19.24 provided by Microsoft Visual Studio\* 2019 version 16.4 +- Microsoft Visual C++ Compiler\* version 19.30 provided by Microsoft Visual Studio\* 2022 version 17.0 +> **NOTE:** [CMake\*](https://cmake.org/download) 3.21 or higher is required to build using Microsoft Visual Studio\* 2022. + +### macOS* + +- Intel® C++ Compiler Classic 2021.9 for macOS\* + +## Installation + +You can install the Crypto Multi-buffer library in two different ways: +1. Installation to the default directories. + > **Note**: To run this installation type, you need to have appropriate permissions to write to the installation directory. + + Default locations (default values of `CMAKE_INSTALL_PREFIX`): + - Unix: /usr/local + - Windows: C:\Program Files\crypto_mb or C:\Program Files (x86)\crypto_mb + + To begin installation, run the command below in the project folder that was specified with `-B`: + ``` bash + make install + ``` + > **Note**: Installation requires write permissions to the build directory to create the installation manifest file. If it is not feasible in your setup, copy the build to the local directory and change permissions accordingly. + +2. Installation to your own directory. + If you want to install the library not by default paths, specify the `CMAKE_INSTALL_PREFIX` variable at the configuration step, for example: + ``` bash + cmake . -B"../build" -DCMAKE_INSTALL_PREFIX=path/to/libcrypto_mb/installation + ``` + +You can find the installed files in: + +``` bash + +├── ${CMAKE_INSTALL_PREFIX} +   ├── include + | └── crypto_mb + | ├── cpu_features.h +   │   ├── defs.h +   │   ├── ec_nistp256.h +   │   ├── ec_nistp384.h +   │   ├── ec_nistp521.h +   │   ├── ec_sm2.h +   │   ├── ed25519.h +   │   ├── exp.h +   │   ├── rsa.h +   │   ├── sm3.h +   │   ├── sm4_ccm.h +   │   ├── sm4_gcm.h +   │   ├── sm4.h +   │   ├── status.h + | ├── version.h +   │   └── x25519.h +   └── lib + └── libcrypto_mb.so +``` + +## How to Build + +1. Clone the repository from GitHub\* as follows: + + ``` bash + git clone --recursive https://github.com/intel/ipp-crypto + ``` + and navigate to the `sources/ippcp/crypto_mb` folder. +2. Set the environment variables for one of the supported C/C++ compilers. + + *Example for Intel® Compiler:* + + ```bash + source /opt/intel/bin/compilervars.sh intel64 + ``` + + For details, refer to the [Intel® C++ Compiler Developer Guide and Reference](https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/current/specifying-the-location-of-compiler-components.html) + +3. Run CMake on the command line. Use `-B` to specify path to the resulting project. +4. Go to the project folder that was specified with `-B` and run `make` to build the library (`crypto_mb` target). + +### Building with Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) + +The Crypto Multi-buffer library will be built automatically with Intel® IPP Cryptography if optimization for Intel® Microarchitecture Code Named Ice Lake is available. For more information see [Intel IPP Cryptography Build Instructions](../../../BUILD.md) + +### CMake Build Options + +- Use `OPENSSL_INCLUDE_DIR`, `OPENSSL_LIBRARIES` and `OPENSSL_ROOT_DIR` to override path to OpenSSL\*: + + ``` bash + cmake . -B"../build" + -DOPENSSL_INCLUDE_DIR=/path/to/openssl/include + -DOPENSSL_LIBRARIES=/path/to/openssl/lib + -DOPENSSL_ROOT_DIR=/path/to/openssl/installation/dir + ``` + +- Set `-DOPENSSL_USE_STATIC_LIBS=TRUE` if static OpenSSL libraries are preferred. diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/cpu_features.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/cpu_features.h new file mode 100644 index 000000000..577f81d37 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/cpu_features.h @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef CPU_FEATURES_H +#define CPU_FEATURES_H + +#include + +/* definition of cpu features */ +#define mbcpCPUID_MMX 0x00000001LL /* Intel® architecture with MMX(TM) technology supported */ +#define mbcpCPUID_SSE 0x00000002LL /* Intel® Streaming SIMD Extensions (Intel® SSE) instruction set */ +#define mbcpCPUID_SSE2 0x00000004LL /* Intel® Streaming SIMD Extensions 2 (Intel® SSE2) instruction set */ +#define mbcpCPUID_SSE3 0x00000008LL /* Intel® Streaming SIMD Extensions 3 (Intel® SSE3) instruction set */ +#define mbcpCPUID_SSSE3 0x00000010LL /* Supplemental Streaming SIMD Extensions 3 (SSSE3) instruction set */ +#define mbcpCPUID_MOVBE 0x00000020LL /* Intel® instruction MOVBE */ +#define mbcpCPUID_SSE41 0x00000040LL /* Intel® Streaming SIMD Extensions 4.1 (Intel® SSE4.1) instruction set */ +#define mbcpCPUID_SSE42 0x00000080LL /* Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) instruction set */ +#define mbcpCPUID_AVX 0x00000100LL /* Intel® Advanced Vector Extensions (Intel® AVX) instruction set */ +#define mbcpAVX_ENABLEDBYOS 0x00000200LL /* Intel® Advanced Vector Extensions (Intel® AVX) instruction set is supported by OS */ +#define mbcpCPUID_AES 0x00000400LL /* AES */ +#define mbcpCPUID_CLMUL 0x00000800LL /* Intel® instruction PCLMULQDQ */ +#define mbcpCPUID_ABR 0x00001000LL /* Reserved */ +#define mbcpCPUID_RDRAND 0x00002000LL /* Intel® instruction RDRAND */ +#define mbcpCPUID_F16C 0x00004000LL /* Intel® instruction F16C */ +#define mbcpCPUID_AVX2 0x00008000LL /* Intel® Advanced Vector Extensions 2 (Intel® AVX2) */ +#define mbcpCPUID_ADX 0x00010000LL /* Intel® instructions ADOX/ADCX */ +#define mbcpCPUID_RDSEED 0x00020000LL /* Intel® instruction RDSEED */ +#define mbcpCPUID_PREFETCHW 0x00040000LL /* Intel® instruction PREFETCHW */ +#define mbcpCPUID_SHA 0x00080000LL /* Intel® Secure Hash Algorithm Extensions (Intel® SHA Extensions) */ +#define mbcpCPUID_AVX512F 0x00100000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) Foundation instruction set */ +#define mbcpCPUID_AVX512CD 0x00200000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) CD instruction set */ +#define mbcpCPUID_AVX512ER 0x00400000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) ER instruction set */ +#define mbcpCPUID_AVX512PF 0x00800000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) PF instruction set */ +#define mbcpCPUID_AVX512BW 0x01000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) BW instruction set */ +#define mbcpCPUID_AVX512DQ 0x02000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) DQ instruction set */ +#define mbcpCPUID_AVX512VL 0x04000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) VL instruction set */ +#define mbcpCPUID_AVX512VBMI 0x08000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) Bit Manipulation instructions */ +#define mbcpCPUID_MPX 0x10000000LL /* Intel® Memory Protection Extensions (Intel® MPX) */ +#define mbcpCPUID_AVX512_4FMADDPS 0x20000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) DL floating-point single precision */ +#define mbcpCPUID_AVX512_4VNNIW 0x40000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) DL enhanced word variable precision */ +#define mbcpCPUID_KNC 0x80000000LL /* Intel® Xeon® Phi(TM) Coprocessor */ +#define mbcpCPUID_AVX512IFMA 0x100000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) IFMA (PMADD52) instruction set */ +#define mbcpAVX512_ENABLEDBYOS 0x200000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) is supported by OS */ +#define mbcpCPUID_AVX512GFNI 0x400000000LL /* GFNI */ +#define mbcpCPUID_AVX512VAES 0x800000000LL /* VAES */ +#define mbcpCPUID_AVX512VCLMUL 0x1000000000LL /* VCLMUL */ +#define mbcpCPUID_AVX512VBMI2 0x2000000000LL /* Intel® Advanced Vector Extensions 512 (Intel® AVX-512) Bit Manipulation instructions 2 */ +#define mbcpCPUID_BMI1 0x4000000000LL /* BMI1 */ +#define mbcpCPUID_BMI2 0x8000000000LL /* BMI2 */ + +/* map cpu features */ +EXTERN_C int64u mbx_get_cpu_features(void); + +/* check if crypto_mb is applicable */ +EXTERN_C int mbx_is_crypto_mb_applicable(int64u cpu_features); + +/* supported algorithm */ +enum MBX_ALGO { + MBX_ALGO_RSA_1K, + MBX_ALGO_RSA_2K, + MBX_ALGO_RSA_3K, + MBX_ALGO_RSA_4K, + MBX_ALGO_X25519, + MBX_ALGO_EC_NIST_P256, + MBX_ALGO_ECDHE_NIST_P256 = MBX_ALGO_EC_NIST_P256, + MBX_ALGO_ECDSA_NIST_P256 = MBX_ALGO_EC_NIST_P256, + MBX_ALGO_EC_NIST_P384, + MBX_ALGO_ECDHE_NIST_P384 = MBX_ALGO_EC_NIST_P384, + MBX_ALGO_ECDSA_NIST_P384 = MBX_ALGO_EC_NIST_P384, + MBX_ALGO_EC_NIST_P521, + MBX_ALGO_ECDHE_NIST_P521 = MBX_ALGO_EC_NIST_P521, + MBX_ALGO_ECDSA_NIST_P521 = MBX_ALGO_EC_NIST_P521, + MBX_ALGO_EC_SM2, + MBX_ALGO_ECDHE_SM2 = MBX_ALGO_EC_SM2, + MBX_ALGO_ECDSA_SM2 = MBX_ALGO_EC_SM2, + MBX_ALGO_SM3, + MBX_ALGO_SM4, + MBX_ALGO_ECB_SM4 = MBX_ALGO_SM4, + MBX_ALGO_CBC_SM4 = MBX_ALGO_SM4, + MBX_ALGO_CTR_SM4 = MBX_ALGO_SM4, + MBX_ALGO_OFB_SM4 = MBX_ALGO_SM4, + MBX_ALGO_OFB128_SM4 = MBX_ALGO_SM4, +}; + +/* multi-buffer width implemented by library */ +enum MBX_WIDTH { + MBX_WIDTH_MB8 = 8, + MBX_WIDTH_MB16 = 16, + MBX_WIDTH_ANY = (1 << 16) - 1 +}; + +typedef int64u MBX_ALGO_INFO; + +/* check if algorithm is supported on current platform + * returns: multi-buffer width mask or 0 if algorithm not supported +*/ +EXTERN_C MBX_ALGO_INFO mbx_get_algo_info(enum MBX_ALGO algo); + +#endif /* CPU_FEATURES_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/defs.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/defs.h new file mode 100644 index 000000000..aa5a2346b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/defs.h @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef DEFS_H +#define DEFS_H + +/* data types */ +typedef unsigned char int8u; +typedef unsigned short int16u; +typedef unsigned int int32u; +typedef unsigned long long int64u; + +#ifndef NULL + #define NULL ((void *)0) +#endif + +/* alignment & inline */ +#if defined(__GNUC__) + #if !defined(__ALIGN64) + #define __ALIGN64 __attribute__((aligned(64))) + #endif + + #if !defined(__INLINE) + #define __INLINE static __inline__ + #endif + + #if !defined(__NOINLINE) + #define __NOINLINE __attribute__((noinline)) + #endif +#else + #if !defined(__ALIGN64) + #define __ALIGN64 __declspec(align(64)) + #endif + + #if !defined(__INLINE) + #define __INLINE static __forceinline + #endif + + #if !defined(__NOINLINE) + #define __NOINLINE __declspec(noinline) + #endif +#endif + + +/* externals */ +#undef EXTERN_C + +#ifdef __cplusplus + #define EXTERN_C extern "C" +#else + #define EXTERN_C +#endif + +#endif /* DEFS_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp256.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp256.h new file mode 100644 index 000000000..2ffa7c58d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp256.h @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_NISTP256_H +#define EC_NISTP256_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + + +/* +// ECDHE +*/ + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp256_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp256_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp256_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp256_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + + +/* +// ECDSA signature generation +*/ + +/* +// Pre-computes ECDSA signature +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer); +/* +// computes ECDSA signature +// +// pa_sign_pr[] array of pointers to the r-components of the signatures +// pa_sign_ps[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sgn_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages that have been signed +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp256_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_setup_ssl_mb8(BIGNUM* pa_inv_eph_skey[8], + BIGNUM* pa_sign_pr[8], + const BIGNUM* const pa_eph_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_complete_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_sgn_rp[8], + const BIGNUM* const pa_inv_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp256_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp256_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sig[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +#endif // BN_OPENSSL_DISABLE +#endif /* EC_NISTP256_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp384.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp384.h new file mode 100644 index 000000000..4c3fa9895 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp384.h @@ -0,0 +1,186 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_NISTP384_H +#define EC_NISTP384_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + + +/* +// ECDHE +*/ + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp384_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp384_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp384_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp384_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + + +/* +// ECDSA signature generation +*/ + +/* +// Pre-computes ECDSA signature +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer); +/* +// computes ECDSA signature +// +// pa_sign_pr[] array of pointers to the r-components of the signatures +// pa_sign_ps[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sgn_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages that have been signed +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp384_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_setup_ssl_mb8(BIGNUM* pa_inv_eph_skey[8], + BIGNUM* pa_sign_pr[8], + const BIGNUM* const pa_eph_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_complete_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_sgn_rp[8], + const BIGNUM* const pa_inv_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp384_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp384_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sign[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE +#endif /* EC_NISTP384_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp521.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp521.h new file mode 100644 index 000000000..1e938c386 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_nistp521.h @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_NISTP521_H +#define EC_NISTP521_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + + +/* +// ECDHE +*/ + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp521_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp521_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key is represented by (X:Y:Z) projective Jacobian coordinates +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp521_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE + + +EXTERN_C mbx_status mbx_nistp521_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + + +/* +// ECDSA signature generation +*/ + +/* +// Pre-computes ECDSA signature +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer); +/* +// computes ECDSA signature +// +// pa_sign_pr[] array of pointers to the r-components of the signatures +// pa_sign_ps[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sgn_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer); + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_nistp521_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_setup_ssl_mb8(BIGNUM* pa_inv_eph_skey[8], + BIGNUM* pa_sign_pr[8], + const BIGNUM* const pa_eph_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_complete_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_sgn_rp[8], + const BIGNUM* const pa_inv_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp521_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_nistp521_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sig[8], + const int8u* const pa_msg[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +#endif // BN_OPENSSL_DISABLE +#endif /* EC_NISTP521_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_sm2.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_sm2.h new file mode 100644 index 000000000..43d6f970a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ec_sm2.h @@ -0,0 +1,154 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EC_SM2_H +#define EC_SM2_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE + #include + #include +#endif // BN_OPENSSL_DISABLE + +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates (or NULL, if affine coordinate requested) +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_sm2_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer); + +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +// +// Note: +// This function implements ECDHE over SM2 curve according to IEEE 1363-2000 standard. +*/ +EXTERN_C mbx_status mbx_sm2_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + +/* +// Computes SM2 ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_user_id[] array of pointers to the users ID +// user_id_len[] array of users ID length +// pa_msg[] array of pointers to the messages are being signed +// msg_len[] array of messages length +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_sm2_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + +/* +// Verifies SM2 ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_user_id[] array of pointers to the users ID +// user_id_len[] array of users ID length +// pa_msg[] array of pointers to the messages are being signed +// msg_len[] array of messages length +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +EXTERN_C mbx_status mbx_sm2_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer); + +/* +// OpenSSL's specific similar APIs +*/ +#ifndef BN_OPENSSL_DISABLE +EXTERN_C mbx_status mbx_sm2_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_sm2_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_sm2_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); + +EXTERN_C mbx_status mbx_sm2_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sig[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer); +#endif // BN_OPENSSL_DISABLE +#endif /* EC_SM2_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ed25519.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ed25519.h new file mode 100644 index 000000000..8cc737dac --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/ed25519.h @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef ED25519_H +#define ED25519_H + +#include +#include + +typedef int8u ed25519_sign_component[32]; +typedef ed25519_sign_component ed25519_sign[2]; + +typedef int8u ed25519_public_key[32]; +typedef int8u ed25519_private_key[32]; + +/* +// Computes ed25519 public key +// pa_public_key[] array of pointers to the public keys +// pa_private_key[] array of pointers to the public keys Y-coordinates +*/ +EXTERN_C mbx_status mbx_ed25519_public_key_mb8(ed25519_public_key* pa_public_key[8], + const ed25519_private_key* const pa_private_key[8]); + +/* +// Computes ed25519 signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// msgLen[] lengths of the messages are being signed +// pa_private_key[] array of pointers to the signer's private keys +// pa_public_key[] array of pointers to the signer's public keys +*/ +EXTERN_C mbx_status mbx_ed25519_sign_mb8(ed25519_sign_component* pa_sign_r[8], + ed25519_sign_component* pa_sign_s[8], + const int8u* const pa_msg[8], const int32u msgLen[8], + const ed25519_private_key* const pa_private_key[8], + const ed25519_public_key* const pa_public_key[8]); + +/* +// Verifies ed25519 signature +// pa_sign_r[] array of pointers to the r-components of the verified signatures +// pa_sign_s[] array of pointers to the s-components of the verified signatures +// pa_msg[] array of pointers to the signed messages +// msgLen[] array of signed messages lengths +// pa_public_key[] array of pointers to the signer's public keys +*/ +EXTERN_C mbx_status mbx_ed25519_verify_mb8(const ed25519_sign_component* const pa_sign_r[8], + const ed25519_sign_component* const pa_sign_s[8], + const int8u* const pa_msg[8], const int32u msgLen[8], + const ed25519_public_key* const pa_public_key[8]); + +#endif /* ED25519_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/exp.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/exp.h new file mode 100644 index 000000000..b5a76b8ae --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/exp.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef EXP_H +#define EXP_H + +#include +#include + + +/* size of scratch buffer */ +EXTERN_C int mbx_exp_BufferSize(int modulusBits); + +/* exp operation */ +EXTERN_C mbx_status mbx_exp1024_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp2048_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp3072_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp4096_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +EXTERN_C mbx_status mbx_exp_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen); + +#endif /* EXP_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/rsa.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/rsa.h new file mode 100644 index 000000000..f71f2d596 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/rsa.h @@ -0,0 +1,104 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef RSA_H +#define RSA_H + +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include + +EXTERN_C mbx_status mbx_rsa_public_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const e_pa[8], + const BIGNUM* const n_pa[8], + int expected_rsa_bitsize); + +EXTERN_C mbx_status mbx_rsa_private_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const d_pa[8], + const BIGNUM* const n_pa[8], + int expected_rsa_bitsize); + +EXTERN_C mbx_status mbx_rsa_private_crt_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8], + int expected_rsa_bitsize); +#endif /* BN_OPENSSL_DISABLE */ + + +/* +// rsa cp methods +*/ +typedef struct _ifma_rsa_method mbx_RSA_Method; + +/* rsa public key opertaion */ +EXTERN_C const mbx_RSA_Method* mbx_RSA1K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA2K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA3K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA4K_pub65537_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA_pub65537_Method(int rsaBitsize); + +/* rsa private key opertaion */ +EXTERN_C const mbx_RSA_Method* mbx_RSA1K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA2K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA3K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA4K_private_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA_private_Method(int rsaBitsize); + +/* rsa private key opertaion (ctr) */ +EXTERN_C const mbx_RSA_Method* mbx_RSA1K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA2K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA3K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA4K_private_crt_Method(void); +EXTERN_C const mbx_RSA_Method* mbx_RSA_private_crt_Method(int rsaBitsize); + +EXTERN_C int mbx_RSA_Method_BufSize(const mbx_RSA_Method* m); + + +EXTERN_C mbx_status mbx_rsa_public_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); + +EXTERN_C mbx_status mbx_rsa_private_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const d_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); + +EXTERN_C mbx_status mbx_rsa_private_crt_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const p_pa[8], + const int64u* const q_pa[8], + const int64u* const dp_pa[8], + const int64u* const dq_pa[8], + const int64u* const iq_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); +#endif /* RSA_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm3.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm3.h new file mode 100644 index 000000000..8f7f7d8b3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm3.h @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#ifndef SM3_H +#define SM3_H + +#include +#include + +#define SM3_SIZE_IN_BITS (256) /* sm3 size in bits */ +#define SM3_SIZE_IN_WORDS (SM3_SIZE_IN_BITS/(sizeof(int32u)*8)) /* sm3 hash size in words */ +#define SM3_MSG_BLOCK_SIZE (64) /* messge block size */ + +#define SM3_NUM_BUFFERS (16) /* max number of buffers in sm3 multi-buffer */ + +/* +// sm3 context for mb16 +*/ + +typedef int32u sm3_hash_mb[SM3_SIZE_IN_WORDS][SM3_NUM_BUFFERS]; /* sm3 hash value in multi-buffer format */ + +struct _sm3_context_mb16 { + int msg_buff_idx[SM3_NUM_BUFFERS]; /* buffer entry */ + int64u msg_len[SM3_NUM_BUFFERS]; /* message length */ + int8u msg_buffer[SM3_NUM_BUFFERS][SM3_MSG_BLOCK_SIZE]; /* buffer */ + __ALIGN64 + sm3_hash_mb msg_hash; /* intermediate hash */ +}; + +typedef struct _sm3_context_mb16 SM3_CTX_mb16; + +EXTERN_C mbx_status16 mbx_sm3_init_mb16(SM3_CTX_mb16* p_state); + +EXTERN_C mbx_status16 mbx_sm3_update_mb16(const int8u* const msg_pa[16], + int len[16], + SM3_CTX_mb16* p_state); + +EXTERN_C mbx_status16 mbx_sm3_final_mb16(int8u* hash_pa[16], + SM3_CTX_mb16* p_state); + +EXTERN_C mbx_status16 mbx_sm3_msg_digest_mb16(const int8u* const msg_pa[16], + int len[16], + int8u* hash_pa[16]); + +#endif /* SM3_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4.h new file mode 100644 index 000000000..144fb6f56 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#ifndef SM4_H +#define SM4_H + +#include +#include + +#define SM4_LINES (16) /* Max number of buffers */ +#define SM4_BLOCK_SIZE (16) /* SM4 data block size (bytes) */ +#define SM4_KEY_SIZE (16) /* SM4 key size (bytes) */ +#define SM4_ROUNDS (32) /* SM4 number of rounds */ +#define SM4_XTS_MAX_SIZE ((1 << 20) * SM4_BLOCK_SIZE) /* SM4 max buffer size (bytes) */ + +typedef int8u sm4_key[SM4_KEY_SIZE]; +typedef int8u sm4_xts_key[SM4_KEY_SIZE*2]; +typedef int32u mbx_sm4_key_schedule[SM4_ROUNDS][SM4_LINES]; + +EXTERN_C mbx_status16 mbx_sm4_set_key_mb16(mbx_sm4_key_schedule* key_sched, const sm4_key* pa_key[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_xts_set_keys_mb16(mbx_sm4_key_schedule* key_sched1, mbx_sm4_key_schedule* key_sched2, const sm4_xts_key* pa_key[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_ecb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched); +EXTERN_C mbx_status16 mbx_sm4_decrypt_ecb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_cbc_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_cbc_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_ctr128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_ctr[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_ctr128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_ctr[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_ofb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_iv[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_ofb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_iv[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_encrypt_cfb128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_decrypt_cfb128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]); + +EXTERN_C mbx_status16 mbx_sm4_xts_encrypt_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], + const mbx_sm4_key_schedule* key_sched1, const mbx_sm4_key_schedule* key_sched2, + const int8u* pa_tweak[SM4_LINES]); +EXTERN_C mbx_status16 mbx_sm4_xts_decrypt_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], + const mbx_sm4_key_schedule* key_sched1, const mbx_sm4_key_schedule* key_sched2, + const int8u* pa_tweak[SM4_LINES]); +#endif /* SM4_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4_ccm.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4_ccm.h new file mode 100644 index 000000000..45128b777 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4_ccm.h @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef SM4_CCM_H +#define SM4_CCM_H + +#include + +#include + +#define MIN_CCM_IV_LENGTH 7 +#define MAX_CCM_IV_LENGTH 13 +#define MIN_CCM_TAG_LENGTH 4 +#define MAX_CCM_TAG_LENGTH 16 +#define MAX_CCM_AAD_LENGTH 65280 /* 2^16 - 2^8 */ + +#define SM4_CCM_CONTEXT_BUFFER_SLOT_TYPE int64u + +#define SM4_CCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES (sizeof(SM4_CCM_CONTEXT_BUFFER_SLOT_TYPE)) +#define SM4_CCM_CONTEXT_BUFFER_SIZE_BYTES ((SM4_LINES * SM4_BLOCK_SIZE) / SM4_CCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES) + +/* +// Enum to control call sequence +// +// Valid call sequence: +// +// 1) mbx_sm4_ccm_init_mb16 +// 2) mbx_sm4_ccm_update_aad_mb16 – optional +// 3) mbx_sm4_ccm_encrypt_mb16/mbx_sm4_ccm_decrypt_mb16 – optional, can be called as many times as necessary +// 4) mbx_sm4_ccm_get_tag_mb16 +// +// Call sequence restrictions: +// +// * mbx_sm4_ccm_get_tag_mb16 can be called after mbx_sm4_ccm_init_mb16 has been called. +// * functions at steps 2-3 can be called as many times as needed to process payload while this functions processes buffers +// with full blocks (Blocks of 16 bytes size) or empty buffers and length of processed payload is not overflowed. +// * if functions at steps 2-3 called to process a partial block, it can’t be called again. +// * if mbx_sm4_ccm_encrypt_mb16 or mbx_sm4_ccm_decrypt_mb16 was called, mbx_sm4_ccm_update_aad_mb16 can’t be called. +// * if mbx_sm4_ccm_encrypt_mb16 was called, mbx_sm4_ccm_decrypt_mb16 can’t be called. +// * if mbx_sm4_ccm_decrypt_mb16 was called, mbx_sm4_ccm_encrypt_mb16 can’t be called. +*/ +typedef enum { sm4_ccm_update_aad = 0xF0A1, sm4_ccm_start_encdec, sm4_ccm_enc, sm4_ccm_dec, sm4_ccm_get_tag } sm4_ccm_state; + +struct _sm4_ccm_context_mb16 { + int64u msg_len[SM4_LINES]; /* Message length (in bytes) of all lines */ + int64u total_processed_len[SM4_LINES]; /* Total processed plaintext/ciphertext length (in bytes) of all lines */ + int tag_len[SM4_LINES]; /* Tag length (in bytes) of all lines */ + int iv_len[SM4_LINES]; /* Total IV length (in bytes) of all lines */ + __m128i ctr0[SM4_LINES]; /* CTR0 content */ + __m128i ctr[SM4_LINES]; /* CTR content */ + __m128i hash[SM4_LINES]; /* hash value accumulator for AAD and TXT processing */ + + mbx_sm4_key_schedule key_sched; /* SM4 key schedule */ + sm4_ccm_state state; /* call sequence state */ +}; + +typedef struct _sm4_ccm_context_mb16 SM4_CCM_CTX_mb16; + +/* + * Initializes SM4-CCM context. + * + * @param[in] pa_key Array of key pointers + * @param[in] pa_iv Array of IV pointers + * @param[in] iv_len Array of IV lengths + * @param[in] tag_len Array of authentication tag lengths + * @param[in] msg_len Array of total message lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_init_mb16(const sm4_key *const pa_key[SM4_LINES], + const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + const int tag_len[SM4_LINES], + const int64u msg_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Digests additional authenticated data (AAD) for 16 buffers + * + * @param[in] pa_aad Array of AAD pointers + * @param[in] aad_len Array of AAD lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], + const int aad_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Retrieves authentication tag for 16 buffers + * + * @param[out] pa_tag Array of authentication tag pointers + * @param[in] tag_len Array of tag lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_get_tag_mb16(int8u *pa_tag[SM4_LINES], + const int tag_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Encrypts 16 buffers with SM4-CCM. + * + * @param[out] pa_out Array of ciphertext pointers + * @param[in] pa_in Array of plaintext pointers + * @param[in] in_len Array of plaintext lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +/* + * Decrypts 16 buffers with SM4-CCM. + * + * @param[out] pa_out Array of plaintext pointers + * @param[in] pa_in Array of ciphertext pointers + * @param[in] in_len Array of ciphertext lengths + * @param[in/out] p_context SM4-CCM context + * + * @return Bitmask of operation status + */ +EXTERN_C mbx_status16 mbx_sm4_ccm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context); +#endif /* SM4_CCM_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4_gcm.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4_gcm.h new file mode 100644 index 000000000..9dede98e9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/sm4_gcm.h @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef SM4_GCM_H +#define SM4_GCM_H + +#include + +#include + +#define SM4_GCM_CONTEXT_BUFFER_SLOT_TYPE int64u + +#define SM4_GCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES (sizeof(SM4_GCM_CONTEXT_BUFFER_SLOT_TYPE)) +#define SM4_GCM_CONTEXT_BUFFER_SIZE_BYTES ((SM4_LINES * SM4_BLOCK_SIZE) / SM4_GCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES) + +#define SM4_GCM_HASHKEY_PWR_NUM 8 + +/* +// Enum to control call sequence +// +// Valid call sequence: +// +// 1) mbx_sm4_gcm_init_mb16 +// 2) mbx_sm4_gcm_update_iv_mb16 – optional, can be called as many times as necessary +// 3) mbx_sm4_gcm_update_aad_mb16 – optional, can be called as many times as necessary +// 4) mbx_sm4_gcm_encrypt_mb16/mbx_sm4_gcm_decrypt_mb16 – optional, can be called as many times as necessary +// 5) mbx_sm4_gcm_get_tag_mb16 +// +// Call sequence restrictions: +// +// * mbx_sm4_gcm_get_tag_mb16 can be called after IV is fully processed. +// IV is fully processed if buffer with partial block (Block of less than 16 bytes size) was processed or if mbx_sm4_gcm_update_aad_mb16 was called +// * functions at steps 2-4 can be called as many times as needed to process payload while this functions processes buffers +// with full blocks (Blocks of 16 bytes size) or empty buffers and length of processed payload is not overflowed. +// * if functions at steps 2-4 called to process a partial block, it can’t be called again. +// * if mbx_sm4_gcm_update_aad_mb16 was called, mbx_sm4_gcm_update_iv_mb16 can’t be called. +// * if mbx_sm4_gcm_encrypt_mb16 or mbx_sm4_gcm_decrypt_mb16 was called, mbx_sm4_gcm_update_aad_mb16 and mbx_sm4_gcm_update_iv_mb16 can’t be called. +// * if mbx_sm4_gcm_encrypt_mb16 was called, mbx_sm4_gcm_decrypt_mb16 can’t be called. +// * if mbx_sm4_gcm_decrypt_mb16 was called, mbx_sm4_gcm_encrypt_mb16 can’t be called. +*/ +typedef enum { sm4_gcm_update_iv = 0xF0A1, sm4_gcm_update_aad, sm4_gcm_start_encdec, sm4_gcm_enc, sm4_gcm_dec, sm4_gcm_get_tag } sm4_gcm_state; + +struct _sm4_gcm_context_mb16 { + __m128i hashkey[SM4_GCM_HASHKEY_PWR_NUM][SM4_LINES]; /* Set of hashkeys for ghash computation */ + __m128i j0[SM4_LINES]; /* J0 value accumulator for IV processing */ + __m128i ghash[SM4_LINES]; /* ghash value accumulator for AAD and TXT processing */ + __m128i ctr[SM4_LINES]; /* counter for gctr encryption */ + + /* + // buffer to store IV, AAD and TXT length in bytes + // + // this buffer is used to store IV length to compute J0 block + // and reused to store AAD and TXT length to compute ghash + // + // length is stored as follow: + // + // J0 computation: + // [64 bits with IV len (buffer 0)] + // [64 bits with IV len (buffer 1)] + // .. + // [64 bits with IV len (buffer SM4_LINES-1)] + // + // Only half of buffer is used for J0 computation + // + // ghash computation: + // [64 bits with AAD len (buffer 0)][64 bits with TXT len (buffer 0)] + // [64 bits with AAD len (buffer 1)][64 bits with TXT len (buffer 1)] + // .. + // [64 bits with AAD len (buffer SM4_LINES-1)][64 bits with TXT len (buffer SM4_LINES-1)] + // + */ + int64u len[SM4_LINES * 2]; + + mbx_sm4_key_schedule key_sched; /* SM4 key schedule */ + sm4_gcm_state state; /* call sequence state */ +}; + +typedef struct _sm4_gcm_context_mb16 SM4_GCM_CTX_mb16; + +EXTERN_C mbx_status16 mbx_sm4_gcm_init_mb16(const sm4_key *const pa_key[SM4_LINES], + const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C mbx_status16 mbx_sm4_gcm_update_iv_mb16(const int8u *const pa_iv[SM4_LINES], const int iv_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_state); +EXTERN_C mbx_status16 mbx_sm4_gcm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], const int aad_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_state); + +EXTERN_C mbx_status16 mbx_sm4_gcm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_GCM_CTX_mb16 *p_context); +EXTERN_C mbx_status16 mbx_sm4_gcm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C mbx_status16 mbx_sm4_gcm_get_tag_mb16(int8u *pa_tag[SM4_LINES], const int tag_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_context); + +#endif /* SM4_GCM_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/status.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/status.h new file mode 100644 index 000000000..add3b5c04 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/status.h @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef STATUS_H +#define STATUS_H + +#include + +typedef int32u mbx_status; +typedef int64u mbx_status16; + +// error statuses and manipulators +#define MBX_STATUS_OK (0) +#define MBX_STATUS_MISMATCH_PARAM_ERR (1) +#define MBX_STATUS_NULL_PARAM_ERR (2) +#define MBX_STATUS_LOW_ORDER_ERR (4) +#define MBX_STATUS_SIGNATURE_ERR (8) + +__INLINE mbx_status MBX_SET_STS(mbx_status status, int numb, mbx_status sttVal) +{ + numb &= 7; /* 0 <= numb < 8 */ + status &= (mbx_status)(~(0xF << (numb*4))); + return status |= (sttVal & 0xF) << (numb*4); +} + +__INLINE mbx_status MBX_GET_STS(mbx_status status, int numb) +{ + return (status >>(numb*4)) & 0xF; +} +__INLINE mbx_status MBX_SET_STS_ALL(mbx_status stsVal) +{ + return (stsVal<<4*7) | (stsVal<<4*6) | (stsVal<<4*5) | (stsVal<<4*4) | (stsVal<<4*3) | (stsVal<<4*2) | (stsVal<<4*1) | stsVal; +} + +__INLINE mbx_status MBX_SET_STS_BY_MASK(mbx_status status, int8u mask, mbx_status sttVal) +{ + int numb; + + for(numb=0; numb<8; numb++) { + mbx_status buf_stt = (0 - ((mask>>numb) &1)) & sttVal; + status = MBX_SET_STS(status, numb, buf_stt); + } + return status; +} + +__INLINE int MBX_IS_ANY_OK_STS(mbx_status status) +{ + int ret = MBX_STATUS_OK==MBX_GET_STS(status, 0) + || MBX_STATUS_OK==MBX_GET_STS(status, 1) + || MBX_STATUS_OK==MBX_GET_STS(status, 2) + || MBX_STATUS_OK==MBX_GET_STS(status, 3) + || MBX_STATUS_OK==MBX_GET_STS(status, 4) + || MBX_STATUS_OK==MBX_GET_STS(status, 5) + || MBX_STATUS_OK==MBX_GET_STS(status, 6) + || MBX_STATUS_OK==MBX_GET_STS(status, 7); + return ret; +} + +/* +// Helpers for 64-bit status mbx_status16 +*/ + +/* Accessors for the low and high part of 64-bit status */ +__INLINE mbx_status MBX_GET_HIGH_PART_STS16(mbx_status16 status16) +{ + return ((mbx_status)(((mbx_status16)(status16) >> 32) & 0xFFFFFFFF)); +} + +__INLINE mbx_status MBX_GET_LOW_PART_STS16(mbx_status16 status16) +{ + return ((mbx_status)(status16)); +} + +__INLINE mbx_status16 MBX_SET_STS16_ALL(mbx_status16 stsVal) +{ + return (stsVal<<4*15) | (stsVal<<4*14) | (stsVal<<4*13) | (stsVal<<4*12) | (stsVal<<4*11) | (stsVal<<4*10) | (stsVal<<4*9) | (stsVal<<4*8) | \ + (stsVal<<4*7) | (stsVal<<4*6) | (stsVal<<4*5) | (stsVal<<4*4) | (stsVal<<4*3) | (stsVal<<4*2) | (stsVal<<4*1) | stsVal; +} + +__INLINE mbx_status16 MBX_SET_STS16(mbx_status16 status, int numb, mbx_status16 sttVal) +{ + numb &= 15; /* 0 <= numb < 16 */ + status &= (mbx_status16)(~((int64u)0xF << (numb*4))); + return status |= (sttVal & 0xF) << (numb*4); +} + +__INLINE mbx_status16 MBX_SET_STS16_BY_MASK(mbx_status16 status, int16u mask, mbx_status16 sttVal) +{ + int numb; + for (numb = 0; numb < 16; numb++) { + mbx_status16 buf_stt = (0 - ((mask >> numb) & 1)) & sttVal; + status = MBX_SET_STS16(status, numb, buf_stt); + } + return status; +} + +__INLINE int MBX_IS_ANY_OK_STS16(mbx_status16 status) +{ + return MBX_IS_ANY_OK_STS(MBX_GET_HIGH_PART_STS16(status)) || \ + MBX_IS_ANY_OK_STS(MBX_GET_LOW_PART_STS16(status)); +} + +#endif /* STATUS_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/version.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/version.h new file mode 100644 index 000000000..8e6c86375 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/version.h @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef VERSION_H +#define VERSION_H + +#include + +/* crypto_mb name & version */ +#define MBX_LIB_NAME() "crypto_mb" +#define MBX_VER_MAJOR 1 +#define MBX_VER_MINOR 0 +#define MBX_VER_REV 9 + +/* major interface version */ +#define MBX_INTERFACE_VERSION_MAJOR 11 +/* minor interface version */ +#define MBX_INTERFACE_VERSION_MINOR 9 + +typedef struct { + int major; /* e.g. 1 */ + int minor; /* e.g. 2 */ + int revision; /* e.g. 3 */ + const char* name; /* e,g. "crypto_mb" */ + const char* buildDate; /* e.g. "Oct 28 2019" */ + const char* strVersion;/* e.g. "crypto_mb (ver 1.2.3 Oct 28 2019)" */ +} mbxVersion; + +EXTERN_C const mbxVersion* mbx_getversion(void); + +#endif /* VERSION_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/x25519.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/x25519.h new file mode 100644 index 000000000..ab0231fab --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/crypto_mb/x25519.h @@ -0,0 +1,31 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef X25519_H +#define X25519_H + +#include +#include + +EXTERN_C mbx_status mbx_x25519_public_key_mb8(int8u* const pa_public_key[8], + const int8u* const pa_private_key[8]); + +EXTERN_C mbx_status mbx_x25519_mb8(int8u* const pa_shared_key[8], + const int8u* const pa_private_key[8], + const int8u* const pa_public_key[8]); + +#endif /* X25519_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/crypto_mb_ver.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/crypto_mb_ver.h new file mode 100644 index 000000000..f1c1e1e4b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/crypto_mb_ver.h @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#define STR2(x) #x +#define STR(x) STR2(x) + +#define MBX_LIB_LONGNAME() "Crypto multi-buffer" +#define MBX_LIB_SHORTNAME() "crypto_mb" + +#ifndef MBX_BASE_VERSION +#define MBX_BASE_VERSION() MBX_VER_MAJOR,MBX_VER_MINOR,MBX_VER_REV +#endif + +#define MBX_BUILD() 1043 +#define MBX_VERSION() MBX_BASE_VERSION(),MBX_BUILD() + +#ifndef MBX_STR_VERSION +#define MBX_STR_VERSION() STR(MBX_VER_MAJOR) "." STR(MBX_VER_MINOR) "." STR(MBX_VER_REV) " (" STR(MBX_INTERFACE_VERSION_MAJOR) "." STR(MBX_INTERFACE_VERSION_MINOR) ")" +#endif + +#ifndef CRYPTO_MB_STR_VERSION + #ifdef MBX_REVISION + #define CRYPTO_MB_STR_VERSION() MBX_STR_VERSION() " (r" STR( MBX_REVISION ) ")" + #else + #define CRYPTO_MB_STR_VERSION() MBX_STR_VERSION() " (-)" + #endif +#endif + + +/* ////////////////////////////// End of file /////////////////////////////// */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/ifma_cvt52.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/ifma_cvt52.h new file mode 100644 index 000000000..5a8137879 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/ifma_cvt52.h @@ -0,0 +1,43 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_CVT52_H +#define IFMA_CVT52_H + +#ifndef BN_OPENSSL_DISABLE + #include +#endif + +#include + +// from 8 buffers regular (radix2^64) to mb8 redundant (radix 2^52) representation +EXTERN_C int8u ifma_BNU_to_mb8(int64u out_mb8[][8], const int64u* const bn[8], int bitLen); +EXTERN_C int8u ifma_HexStr8_to_mb8(int64u out_mb8[][8], const int8u* const pStr[8], int bitLen); +#ifndef BN_OPENSSL_DISABLE +EXTERN_C int8u ifma_BN_to_mb8(int64u res[][8], const BIGNUM* const bn[8], int bitLen); +#endif + +// from 8 buffers mb8 redundant (radix 2^52) to regular (radix2^64) representation +EXTERN_C int8u ifma_mb8_to_BNU(int64u* const out_bn[8], const int64u inp_mb8[][8], const int bitLen); +EXTERN_C int8u ifma_mb8_to_HexStr8(int8u* const pStr[8], const int64u inp_mb8[][8], int bitLen); + +EXTERN_C int8u ifma_BNU_transpose_copy(int64u out_mb8[][8], const int64u* const inp[8], int bitLen); +#ifndef BN_OPENSSL_DISABLE +EXTERN_C int8u ifma_BN_transpose_copy(int64u out_mb8[][8], const BIGNUM* const inp[8], int bitLen); +#endif /* BN_OPENSSL_DISABLE */ + +#endif /* IFMA_CVT52_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/ifma_defs.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/ifma_defs.h new file mode 100644 index 000000000..a9ae832df --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/ifma_defs.h @@ -0,0 +1,84 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_DEFS_H +#define IFMA_DEFS_H + +#include + +/* define DLL_EXPORT */ +#if defined(__GNUC__) || defined(__CLANG__) + #define DLL_PUBLIC __attribute__ ((visibility ("default"))) + #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) +#else + #define DLL_PUBLIC + #define DLL_LOCAL +#endif + +/* define optimization on/off VS2019 (>= 19.27) */ +#if defined(_MSC_VER) && (_MSC_VER >= 1927) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) + #define OPTIMIZE_OFF_VS19 _Pragma("optimize( \"\", off )") + #define OPTIMIZE_ON_VS19 _Pragma("optimize( \"\", on )") +#else + #define OPTIMIZE_OFF_VS19 + #define OPTIMIZE_ON_VS19 +#endif + +/* define SIMD_LEN if not set (Default is 512 bit AVX) */ +#ifndef SIMD_LEN + #define SIMD_LEN 512 +#endif + +#if ((SIMD_LEN != 512) && (SIMD_LEN != 256)) + #error "Incorrect SIMD length" +#endif + +/* internal function names */ +#if (SIMD_LEN == 512) + #define FUNC_SUFFIX mb8 + #define MB_FUNC_NAME(name) name ## mb8 +#else + #define FUNC_SUFFIX mb4 + #define MB_FUNC_NAME(name) name ## mb4 +#endif + +#define SIMD_TYPE(LEN) typedef __m ## LEN ## i U64; + +/* max internal data bitsize */ +#define IFMA_MAX_BITSIZE (4096) + +/* internal radix definition */ +#define DIGIT_SIZE (52) +#define DIGIT_BASE ((int64u)1< + #include + + #if (SIMD_LEN == 512) + SIMD_TYPE(512) + typedef __mmask8 __mb_mask; + + #define SIMD_LEN 512 + #define SIMD_BYTES (SIMD_LEN/8) + #define MB_WIDTH (SIMD_LEN/64) + + __INLINE U64 loadu64(const void *p) { + return _mm512_loadu_si512((U64*)p); + } + + __INLINE U64 loadstream64(const void *p) { + return _mm512_stream_load_si512 ((U64*)p); + } + + __INLINE void storeu64(const void *p, U64 v) { + _mm512_storeu_si512((U64*)p, v); + } + + #define mask_mov64 _mm512_mask_mov_epi64 + #define set64 _mm512_set1_epi64 + + __INLINE U64 fma52lo(U64 a, U64 b, U64 c) { + return _mm512_madd52lo_epu64(a, b, c); + } + + __INLINE U64 fma52hi(U64 a, U64 b, U64 c) { + return _mm512_madd52hi_epu64(a, b, c); + } + + __INLINE U64 mul52lo(U64 b, U64 c) { + return _mm512_madd52lo_epu64(_mm512_setzero_si512(), b, c); + } + + #ifdef __GNUC__ + // memory ops intrinsics - force load from original buffer + #define _mm512_madd52lo_epu64_(r, a, b, c, o) {\ + r=a; \ + __asm__ ( "vpmadd52luq " #o "(%2), %1, %0" : "+x" (r): "x" (b), "r" (c) ); \ + } + + #define _mm512_madd52hi_epu64_(r, a, b, c, o) {\ + r=a; \ + __asm__ ( "vpmadd52huq " #o "(%2), %1, %0" : "+x" (r): "x" (b), "r" (c) ); \ + } + + __INLINE U64 select64(__mb_mask k, U64 v, U64 *d) { + __asm__("vmovdqu64 %2, %%zmm0 \n" + "vpblendmq %%zmm0, %0, %0 %{%1%} \n" + : "+v"(v) + : "Yk"(k), "m"(*d) + : "zmm0"); + return v; + } + + #else + // Use IFMA instrinsics for all other compilers + #define _mm512_madd52lo_epu64_(r, a, b, c, o) {\ + r=fma52lo(a, b, _mm512_loadu_si512((U64*)(((char*)c)+o))); \ + } + + #define _mm512_madd52hi_epu64_(r, a, b, c, o) {\ + r=fma52hi(a, b, _mm512_loadu_si512((U64*)(((char*)c)+o))); \ + } + + #pragma optimize("", off) + __INLINE U64 select64(__mb_mask k, U64 v, U64 *d) { + return _mm512_mask_blend_epi64(k, v, _mm512_load_si512(d)); + } + + #pragma optimize("", on) + #endif + + #define fma52lo_mem(r, a, b, c, o) _mm512_madd52lo_epu64_(r, a, b, c, o) // gres + #define fma52hi_mem(r, a, b, c, o) _mm512_madd52hi_epu64_(r, a, b, c, o) // gres + + __INLINE U64 add64(U64 a, U64 b) { + return _mm512_add_epi64(a, b); + } + + __INLINE U64 sub64(U64 a, U64 b) { + return _mm512_sub_epi64(a, b); + } + + __INLINE U64 get_zero64() { + return _mm512_setzero_si512(); + } + + __INLINE void set_zero64(U64 *a) { + *a = _mm512_xor_si512(*a, *a); + } + + __INLINE U64 set1(unsigned long long a) { + return _mm512_set1_epi64((long long)a); + } + + __INLINE U64 srli64(U64 a, int s) { + return _mm512_srli_epi64(a, s); + } + + #define srai64 _mm512_srai_epi64 + #define slli64 _mm512_slli_epi64 + + __INLINE U64 and64_const(U64 a, unsigned long long mask) { + return _mm512_and_epi64(a, _mm512_set1_epi64((long long)mask)); + } + + __INLINE U64 and64(U64 a, U64 mask) { + return _mm512_and_epi64(a, mask); + } + + #define or64 _mm512_or_epi64 + #define xor64 _mm512_xor_epi64 + #define cmp64_mask _mm512_cmp_epi64_mask + #define cmpeq16_mask _mm512_cmpeq_epi16_mask + #define cmpeq64_mask _mm512_cmpeq_epi64_mask + + // Mask operations + #define mask_blend64 _mm512_mask_blend_epi64 + #define mask_add64 _mm512_mask_add_epi64 + #define mask_sub64 _mm512_mask_sub_epi64 + #define maskz_sub64 _mm512_maskz_sub_epi64 + + __INLINE __mb_mask is_zero(U64* p, int len) { + U64 Z = p[0]; + for(int i = 1; i < len; i++) { + Z = or64(Z, p[i]); + } + + return cmpeq64_mask(Z, get_zero64()); + } + + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) // for MSVC + #define mask_xor(m1,m2) (__mb_mask)(_mm512_kxor((m1),(m2))) + #else + #define mask_xor _kxor_mask8 + #endif + + #define get_mask(a) (a) + #define get_mask_value(a) (a) + + #define TRANSPOSE_8xI64x8(X0_, X1_ ,X2_ ,X3_ ,X4_ ,X5_ ,X6_ ,X7_) {\ + __m512i X01L = _mm512_unpacklo_epi64(X0_, X1_); \ + __m512i X23L = _mm512_unpacklo_epi64(X2_, X3_); \ + __m512i X45L = _mm512_unpacklo_epi64(X4_, X5_); \ + __m512i X67L = _mm512_unpacklo_epi64(X6_, X7_); \ + \ + __m512i X01H = _mm512_unpackhi_epi64(X0_, X1_); \ + __m512i X23H = _mm512_unpackhi_epi64(X2_, X3_); \ + __m512i X45H = _mm512_unpackhi_epi64(X4_, X5_); \ + __m512i X67H = _mm512_unpackhi_epi64(X6_, X7_); \ + \ + __m512i X4567L, X0123L, X4567H, X0123H; \ + X4567L = _mm512_shuffle_i64x2(X45L, X67L, 0b01000100 ); \ + X0_ = _mm512_mask_shuffle_i64x2(X01L, 0b11111100, X23L, X4567L, 0b10000000 ); \ + X2_ = _mm512_mask_shuffle_i64x2(X23L, 0b11110011, X01L, X4567L, 0b11010001 ); \ + \ + X0123L = _mm512_shuffle_i64x2(X01L, X23L, 0b11101110 ); \ + X4_ = _mm512_mask_shuffle_i64x2(X45L, 0b11001111, X0123L, X67L, 0b10001000 ); \ + X6_ = _mm512_mask_shuffle_i64x2(X67L, 0b00111111, X0123L, X45L, 0b10111101 ); \ + \ + X4567H = _mm512_shuffle_i64x2(X45H, X67H, 0b01000100 ); \ + X1_ = _mm512_mask_shuffle_i64x2(X01H, 0b11111100, X23H, X4567H, 0b10000000 ); \ + X3_ = _mm512_mask_shuffle_i64x2(X23H, 0b11110011, X01H, X4567H, 0b11010001 ); \ + \ + X0123H = _mm512_shuffle_i64x2(X01H, X23H, 0b11101110 ); \ + X5_ = _mm512_mask_shuffle_i64x2(X45H, 0b11001111, X0123H, X67H, 0b10001000 ); \ + X7_ = _mm512_mask_shuffle_i64x2(X67H, 0b00111111, X0123H, X45H, 0b10111101 ); \ + } + + #else + #error "Incorrect SIMD length" + #endif // SIMD_LEN + +#endif // IFMA_MATH_H diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/mem_fns.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/mem_fns.h new file mode 100644 index 000000000..fda962b18 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/common/mem_fns.h @@ -0,0 +1,36 @@ +/******************************************************************************* +* Copyright (C) 2021-2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* + * Auxiliary functions to set and copy memory + */ +__INLINE void CopyBlock(const void* pSrc, void* pDst, int numBytes) +{ + const int8u* s = (int8u*)pSrc; + int8u* d = (int8u*)pDst; + int k; + for (k = 0; k < numBytes; k++) + d[k] = s[k]; +} + +__INLINE void PadBlock(int8u paddingByte, void* pDst, int numBytes) +{ + int8u* d = (int8u*)pDst; + int k; + for (k = 0; k < numBytes; k++) + d[k] = paddingByte; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p256.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p256.h new file mode 100644 index 000000000..0968e52b2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p256.h @@ -0,0 +1,173 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_P256_H +#define IFMA_ARITH_P256_H + +#include +#include + +/* underlying prime's size */ +#define P256_BITSIZE (256) + +/* lengths of FF elements */ +#define P256_LEN52 NUMBER_OF_DIGITS(P256_BITSIZE,DIGIT_SIZE) +#define P256_LEN64 NUMBER_OF_DIGITS(P256_BITSIZE,64) + +__ALIGN64 static const int64u ones[P256_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(1) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) } +}; + +static const int64u VMASK52[sizeof(U64)/sizeof(int64u)] = { + REP8_DECL(DIGIT_MASK) +}; + +#define NORM_LSHIFTR(R, I, J) \ + R##J = add64(R##J, srli64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + +#define NORM_ASHIFTR(R, I, J) \ + R##J = add64(R##J, srai64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + + +/* set FE to zero */ +__INLINE void MB_FUNC_NAME(zero_FE256_)(U64 T[]) +{ + T[0] = T[1] = T[2] = T[3] = T[4] = get_zero64(); +} + +/* check if FE is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_FE256_)(const U64 T[]) +{ + U64 Z = or64(or64(T[0], T[1]), or64(or64(T[2], T[3]), T[4])); + return cmpeq64_mask(Z, get_zero64()); +} + +__INLINE U64 cmov_U64(U64 a, U64 b, __mb_mask kmask) +{ return mask_mov64 (a, kmask, b); } + +/* move field element */ +__INLINE void MB_FUNC_NAME(mov_FE256_)(U64 r[], const U64 a[]) +{ + r[0] = a[0]; + r[1] = a[1]; + r[2] = a[2]; + r[3] = a[3]; + r[4] = a[4]; +} + +/* move coodinate using mask: R = k? A : B */ +__INLINE void MB_FUNC_NAME(mask_mov_FE256_)(U64 R[], const U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = mask_mov64(B[0], k, A[0]); + R[1] = mask_mov64(B[1], k, A[1]); + R[2] = mask_mov64(B[2], k, A[2]); + R[3] = mask_mov64(B[3], k, A[3]); + R[4] = mask_mov64(B[4], k, A[4]); +} + +__INLINE void MB_FUNC_NAME(secure_mask_mov_FE256_)(U64 R[], U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = select64(k, B[0], (U64*)(&A[0])); + R[1] = select64(k, B[1], (U64*)(&A[1])); + R[2] = select64(k, B[2], (U64*)(&A[2])); + R[3] = select64(k, B[3], (U64*)(&A[3])); + R[4] = select64(k, B[4], (U64*)(&A[4])); +} + +/* compare two FE */ +__INLINE __mb_mask MB_FUNC_NAME(cmp_lt_FE256_)(const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + + /* normalize r0 – r4 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + + /* return mask LT */ + return cmp64_mask(r4, get_zero64(), _MM_CMPINT_LT); +} + +__INLINE __mb_mask MB_FUNC_NAME(cmp_eq_FE256_)(const U64 A[], const U64 B[]) +{ + __ALIGN64 U64 msg[P256_LEN52]; + + msg[0] = xor64(A[0], B[0]); + msg[1] = xor64(A[1], B[1]); + msg[2] = xor64(A[2], B[2]); + msg[3] = xor64(A[3], B[3]); + msg[4] = xor64(A[4], B[4]); + + return MB_FUNC_NAME(is_zero_FE256_)(msg); +} + +/* General 256-bit operations */ +EXTERN_C void MB_FUNC_NAME(ifma_amm52x5_)(U64 R[], const U64 inpA[], const U64 inpB[], const U64 inpM[], const int64u* k0_mb); +EXTERN_C void MB_FUNC_NAME(ifma_ams52x5_)(U64 r[], const U64 a[], const U64 m[], const int64u* k0_mb); +EXTERN_C void MB_FUNC_NAME(ifma_add52x5_)(U64 R[], const U64 A[], const U64 B[], const U64 M[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52x5_)(U64 R[], const U64 A[], const U64 B[], const U64 M[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52x5_)(U64 R[], const U64 A[], const U64 M[]); + +/* Specialized operations over NIST P256 */ +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_p256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_p256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_p256_)(U64 r[], const U64 va[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_p256_)(U64 r[], const U64 va[], const U64 vb[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_p256_)(U64 r[], const U64 z[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_p256_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_p256_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_p256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_double52_p256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_tripple52_p256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_half52_p256_)(U64 r[], const U64 a[]); + +EXTERN_C void MB_FUNC_NAME(ifma_ams52_p256_dual_)(U64 r0[], U64 r1[], + const U64 inp0[], const U64 inp1[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_p256_dual_)(U64 r0[], U64 r1[], + const U64 inp0A[], const U64 inp0B[], + const U64 inp1A[], const U64 inp1B[]); + +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_p256_)(const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_p256_)(const U64 a[]); + +/* Specialized operations over EC NIST-P256 order */ +EXTERN_C U64* MB_FUNC_NAME(ifma_n256_)(void); +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_n256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_n256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_n256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_n256_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_n256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_n256_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_n256_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_n256_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_fastred52_pn256_)(U64 r[], const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_n256_)(const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_n256_)(const U64 a[]); + +#endif /* IFMA_ARITH_P256_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p384.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p384.h new file mode 100644 index 000000000..2098c1806 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p384.h @@ -0,0 +1,182 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_P384_H +#define IFMA_ARITH_P384_H + +#include +#include + +/* underlying prime's size */ +#define P384_BITSIZE (384) + +/* lengths of FF elements */ +#define P384_LEN52 NUMBER_OF_DIGITS(P384_BITSIZE,DIGIT_SIZE) +#define P384_LEN64 NUMBER_OF_DIGITS(P384_BITSIZE,64) + +__ALIGN64 static const int64u ones[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(1) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) } +}; + + +static const int64u VMASK52[sizeof(U64)/sizeof(int64u)] = { + REP8_DECL(DIGIT_MASK) +}; + +#define NORM_LSHIFTR(R, I, J) \ + R##J = add64(R##J, srli64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + +#define NORM_ASHIFTR(R, I, J) \ + R##J = add64(R##J, srai64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + + +/* set FE to zero */ +__INLINE void MB_FUNC_NAME(zero_FE384_)(U64 T[]) +{ + T[0] = T[1] = T[2] = T[3] = T[4] = T[5] = T[6] = T[7] = get_zero64(); +} + +/* check if FE is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_FE384_)(const U64 T[]) +{ + //U64 Z = or64(or64(or64(or64(or64(or64(or64(T[0], T[1]), T[2]), T[3]), T[4]), T[5]), T[6]), T[7]); + U64 Z = or64(or64(or64(T[0], T[1]), or64(T[2], T[3])), or64(or64(T[4], T[5]), or64(T[6], T[7]))); + return cmpeq64_mask(Z, get_zero64()); +} + +__INLINE U64 cmov_U64(U64 a, U64 b, __mb_mask kmask) +{ return mask_mov64 (a, kmask, b); } + +/* move field element */ +__INLINE void MB_FUNC_NAME(mov_FE384_)(U64 r[], const U64 a[]) +{ + r[0] = a[0]; + r[1] = a[1]; + r[2] = a[2]; + r[3] = a[3]; + r[4] = a[4]; + r[5] = a[5]; + r[6] = a[6]; + r[7] = a[7]; +} + +/* move coodinate using mask: R = k? A : B */ +__INLINE void MB_FUNC_NAME(mask_mov_FE384_)(U64 R[], const U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = mask_mov64(B[0], k, A[0]); + R[1] = mask_mov64(B[1], k, A[1]); + R[2] = mask_mov64(B[2], k, A[2]); + R[3] = mask_mov64(B[3], k, A[3]); + R[4] = mask_mov64(B[4], k, A[4]); + R[5] = mask_mov64(B[5], k, A[5]); + R[6] = mask_mov64(B[6], k, A[6]); + R[7] = mask_mov64(B[7], k, A[7]); +} + +__INLINE void MB_FUNC_NAME(secure_mask_mov_FE384_)(U64 R[], U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = select64(k, B[0], (U64*)(&A[0])); + R[1] = select64(k, B[1], (U64*)(&A[1])); + R[2] = select64(k, B[2], (U64*)(&A[2])); + R[3] = select64(k, B[3], (U64*)(&A[3])); + R[4] = select64(k, B[4], (U64*)(&A[4])); + R[5] = select64(k, B[5], (U64*)(&A[5])); + R[6] = select64(k, B[6], (U64*)(&A[6])); + R[7] = select64(k, B[7], (U64*)(&A[7])); +} + +__INLINE __mb_mask MB_FUNC_NAME(cmp_lt_FE384_)(const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + U64 r5 = sub64(A[5], B[5]); + U64 r6 = sub64(A[6], B[6]); + U64 r7 = sub64(A[7], B[7]); + + + /* normalize r0 – r7 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + + /* return mask LT */ + return cmp64_mask(r7, get_zero64(), _MM_CMPINT_LT); +} + +/* compare two FE */ +__INLINE __mb_mask MB_FUNC_NAME(cmp_eq_FE384_)(const U64 A[], const U64 B[]) +{ + U64 T[P384_LEN52]; + T[0] = xor64(A[0], B[0]); + T[1] = xor64(A[1], B[1]); + T[2] = xor64(A[2], B[2]); + T[3] = xor64(A[3], B[3]); + T[4] = xor64(A[4], B[4]); + T[5] = xor64(A[5], B[5]); + T[6] = xor64(A[6], B[6]); + T[7] = xor64(A[7], B[7]); + + return MB_FUNC_NAME(is_zero_FE384_)(T); +} + +/* Specialized operations over NIST P384 */ +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_p384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_p384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_p384_)(U64 r[], const U64 va[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_p384_)(U64 r[], const U64 va[], const U64 vb[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_p384_)(U64 r[], const U64 z[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_p384_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_p384_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_p384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_double52_p384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_tripple52_p384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_half52_p384_)(U64 r[], const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_p384)(const U64 A[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_p384_)(const U64 a[]); + +/* Specialized operations over EC NIST-P384 order */ +EXTERN_C U64* MB_FUNC_NAME(ifma_n384_)(void); +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_n384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_n384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_n384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_n384_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_n384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_n384_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_n384_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_n384_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_fastred52_pn384_)(U64 r[], const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_n384)(const U64 A[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_n384_)(const U64 a[]); + +#endif /* IFMA_ARITH_P384_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p521.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p521.h new file mode 100644 index 000000000..063c2e062 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_arith_p521.h @@ -0,0 +1,201 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_P521_H +#define IFMA_ARITH_P521_H + +#include +#include + +/* underlying prime's size */ +#define P521_BITSIZE (521) + +/* lengths of FF elements */ +#define P521_LEN52 NUMBER_OF_DIGITS(P521_BITSIZE,DIGIT_SIZE) +#define P521_LEN64 NUMBER_OF_DIGITS(P521_BITSIZE,64) + +__ALIGN64 static const int64u ones[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(1) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) }, + { REP8_DECL(0) } +}; + + +static const int64u VMASK52[sizeof(U64)/sizeof(int64u)] = { + REP8_DECL(DIGIT_MASK) +}; + +#define NORM_LSHIFTR(R, I, J) \ + R##J = add64(R##J, srli64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + +#define NORM_ASHIFTR(R, I, J) \ + R##J = add64(R##J, srai64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + + +/* set FE to zero */ +__INLINE void MB_FUNC_NAME(zero_FE521_)(U64 T[]) +{ + T[0] = T[1] = T[2] = T[3] = T[4] = T[5] = T[6] = T[7] = T[8] = T[9] = T[10] = get_zero64(); +} + +/* check if FE is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_FE521_)(const U64 T[]) +{ + U64 Z = or64(or64(or64(or64(T[0], T[1]), or64(T[2], T[3])), or64(or64(T[4], T[5]), or64(T[6], T[7]))), or64(or64(T[8], T[9]), T[10])); + return cmpeq64_mask(Z, get_zero64()); +} + +__INLINE U64 cmov_U64(U64 a, U64 b, __mb_mask kmask) +{ return mask_mov64 (a, kmask, b); } + +/* move field element */ +__INLINE void MB_FUNC_NAME(mov_FE521_)(U64 r[], const U64 a[]) +{ + r[0] = a[0]; + r[1] = a[1]; + r[2] = a[2]; + r[3] = a[3]; + r[4] = a[4]; + r[5] = a[5]; + r[6] = a[6]; + r[7] = a[7]; + r[8] = a[8]; + r[9] = a[9]; + r[10]= a[10]; +} + +/* move coodinate using mask: R = k? A : B */ +__INLINE void MB_FUNC_NAME(mask_mov_FE521_)(U64 R[], const U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = mask_mov64(B[0], k, A[0]); + R[1] = mask_mov64(B[1], k, A[1]); + R[2] = mask_mov64(B[2], k, A[2]); + R[3] = mask_mov64(B[3], k, A[3]); + R[4] = mask_mov64(B[4], k, A[4]); + R[5] = mask_mov64(B[5], k, A[5]); + R[6] = mask_mov64(B[6], k, A[6]); + R[7] = mask_mov64(B[7], k, A[7]); + R[8] = mask_mov64(B[8], k, A[8]); + R[9] = mask_mov64(B[9], k, A[9]); + R[10]= mask_mov64(B[10],k, A[10]); +} + +__INLINE void MB_FUNC_NAME(secure_mask_mov_FE521_)(U64 R[], U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = select64(k, B[0], (U64*)(&A[0])); + R[1] = select64(k, B[1], (U64*)(&A[1])); + R[2] = select64(k, B[2], (U64*)(&A[2])); + R[3] = select64(k, B[3], (U64*)(&A[3])); + R[4] = select64(k, B[4], (U64*)(&A[4])); + R[5] = select64(k, B[5], (U64*)(&A[5])); + R[6] = select64(k, B[6], (U64*)(&A[6])); + R[7] = select64(k, B[7], (U64*)(&A[7])); + R[8] = select64(k, B[8], (U64*)(&A[8])); + R[9] = select64(k, B[9], (U64*)(&A[9])); + R[10]= select64(k,B[10], (U64*)(&A[10])); +} + +__INLINE __mb_mask MB_FUNC_NAME(cmp_lt_FE521_)(const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + U64 r5 = sub64(A[5], B[5]); + U64 r6 = sub64(A[6], B[6]); + U64 r7 = sub64(A[7], B[7]); + U64 r8 = sub64(A[8], B[8]); + U64 r9 = sub64(A[9], B[9]); + U64 r10= sub64(A[10],B[10]); + + /* normalize r0 – r10 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9,10) + + /* return mask LT */ + return cmp64_mask(r10, get_zero64(), _MM_CMPINT_LT); +} + +__INLINE __mb_mask MB_FUNC_NAME(cmp_eq_FE521_)(const U64 A[], const U64 B[]) +{ + U64 T[P521_LEN52]; + + T[0] = xor64(A[0], B[0]); + T[1] = xor64(A[1], B[1]); + T[2] = xor64(A[2], B[2]); + T[3] = xor64(A[3], B[3]); + T[4] = xor64(A[4], B[4]); + T[5] = xor64(A[5], B[5]); + T[6] = xor64(A[6], B[6]); + T[7] = xor64(A[7], B[7]); + T[8] = xor64(A[8], B[8]); + T[9] = xor64(A[9], B[9]); + T[10] = xor64(A[10], B[10]); + + return MB_FUNC_NAME(is_zero_FE521_)(T); +} + +/* Specialized operations over NIST P521 */ +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_p521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_p521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_p521_)(U64 r[], const U64 va[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_p521_)(U64 r[], const U64 va[], const U64 vb[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_p521_)(U64 r[], const U64 z[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_p521_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_p521_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_p521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_double52_p521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_tripple52_p521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_half52_p521_)(U64 r[], const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_p521_)(const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_p521_)(const U64 a[]); + +/* Specialized operations over EC NIST-P521 order */ +EXTERN_C U64* MB_FUNC_NAME(ifma_n521_)(void); +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_n521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_n521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_n521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_n521_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_n521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_n521_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_n521_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_n521_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_fastred52_pn521_)(U64 r[], const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_n521_)(const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_n521_)(const U64 a[]); + +#endif /* IFMA_ARITH_P521_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p256.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p256.h new file mode 100644 index 000000000..73fd2d6b9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p256.h @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPOINT_P256_H +#define IFMA_ECPOINT_P256_H + +#include + +typedef struct { + U64 X[P256_LEN52]; + U64 Y[P256_LEN52]; + U64 Z[P256_LEN52]; +} P256_POINT; + +typedef struct { + U64 x[P256_LEN52]; + U64 y[P256_LEN52]; +} P256_POINT_AFFINE; + +typedef struct { + int64u x[P256_LEN52]; + int64u y[P256_LEN52]; +} SINGLE_P256_POINT_AFFINE; + + + +/* check if coodinate is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_point_cordinate_)(const U64 T[]) +{ + return MB_FUNC_NAME(is_zero_FE256_)(T); +} + +/* set point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_to_infinity_)(P256_POINT* r) +{ + r->X[0] = r->X[1] = r->X[2] = r->X[3] = r->X[4] = get_zero64(); + r->Y[0] = r->Y[1] = r->Y[2] = r->Y[3] = r->Y[4] = get_zero64(); + r->Z[0] = r->Z[1] = r->Z[2] = r->Z[3] = r->Z[4] = get_zero64(); +} + +/* set point to infinity by mask */ +__INLINE void MB_FUNC_NAME(mask_set_point_to_infinity_)(P256_POINT* r, __mb_mask mask) +{ + U64 zeros = get_zero64(); + + r->X[0] = mask_mov64(r->X[0], mask, zeros); + r->X[1] = mask_mov64(r->X[1], mask, zeros); + r->X[2] = mask_mov64(r->X[2], mask, zeros); + r->X[3] = mask_mov64(r->X[3], mask, zeros); + r->X[4] = mask_mov64(r->X[4], mask, zeros); + + r->Y[0] = mask_mov64(r->Y[0], mask, zeros); + r->Y[1] = mask_mov64(r->Y[1], mask, zeros); + r->Y[2] = mask_mov64(r->Y[2], mask, zeros); + r->Y[3] = mask_mov64(r->Y[3], mask, zeros); + r->Y[4] = mask_mov64(r->Y[4], mask, zeros); + + r->Z[0] = mask_mov64(r->Z[0], mask, zeros); + r->Z[1] = mask_mov64(r->Z[1], mask, zeros); + r->Z[2] = mask_mov64(r->Z[2], mask, zeros); + r->Z[3] = mask_mov64(r->Z[3], mask, zeros); + r->Z[4] = mask_mov64(r->Z[4], mask, zeros); +} + +/* set affine point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_affine_to_infinity_)(P256_POINT_AFFINE* r) +{ + r->x[0] = r->x[1] = r->x[2] = r->x[3] = r->x[4] = get_zero64(); + r->y[0] = r->y[1] = r->y[2] = r->y[3] = r->y[4] = get_zero64(); +} + +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(P256_POINT* r, const P256_POINT* p); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp256_add_point_)(P256_POINT* r, const P256_POINT* p, const P256_POINT* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp256_add_point_affine_)(P256_POINT* r, const P256_POINT* p, const P256_POINT_AFFINE* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp256_mul_point_)(P256_POINT* r, const P256_POINT* p, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp256_mul_pointbase_)(P256_POINT* r, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(get_nistp256_ec_affine_coords_)(U64 x[], U64 y[], const P256_POINT* P); +EXTERN_C const U64* MB_FUNC_NAME(ifma_ec_nistp256_coord_one_)(void); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_is_on_curve_p256_)(const P256_POINT* p, int use_jproj_coords); + +#endif /* IFMA_ECPOINT_P256_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p384.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p384.h new file mode 100644 index 000000000..54340656b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p384.h @@ -0,0 +1,104 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPOINT_P384_H +#define IFMA_ECPOINT_P384_H + +#include + +typedef struct { + U64 X[P384_LEN52]; + U64 Y[P384_LEN52]; + U64 Z[P384_LEN52]; +} P384_POINT; + +typedef struct { + U64 x[P384_LEN52]; + U64 y[P384_LEN52]; +} P384_POINT_AFFINE; + +typedef struct { + int64u x[P384_LEN52]; + int64u y[P384_LEN52]; +} SINGLE_P384_POINT_AFFINE; + + + +/* check if coodinate is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_point_cordinate_)(const U64 T[]) +{ + return MB_FUNC_NAME(is_zero_FE384_)(T); +} + +/* set point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_to_infinity_)(P384_POINT* r) +{ + r->X[0] = r->X[1] = r->X[2] = r->X[3] = r->X[4] = r->X[5] = r->X[6] = r->X[7] = get_zero64(); + r->Y[0] = r->Y[1] = r->Y[2] = r->Y[3] = r->Y[4] = r->Y[5] = r->Y[6] = r->Y[7] = get_zero64(); + r->Z[0] = r->Z[1] = r->Z[2] = r->Z[3] = r->Z[4] = r->Z[5] = r->Z[6] = r->Z[7] = get_zero64(); +} + +/* set point to infinity by mask */ +__INLINE void MB_FUNC_NAME(mask_set_point_to_infinity_)(P384_POINT* r, __mb_mask mask) +{ + U64 zeros = get_zero64(); + + r->X[0] = mask_mov64(r->X[0], mask, zeros); + r->X[1] = mask_mov64(r->X[1], mask, zeros); + r->X[2] = mask_mov64(r->X[2], mask, zeros); + r->X[3] = mask_mov64(r->X[3], mask, zeros); + r->X[4] = mask_mov64(r->X[4], mask, zeros); + r->X[5] = mask_mov64(r->X[5], mask, zeros); + r->X[6] = mask_mov64(r->X[6], mask, zeros); + r->X[7] = mask_mov64(r->X[7], mask, zeros); + + r->Y[0] = mask_mov64(r->Y[0], mask, zeros); + r->Y[1] = mask_mov64(r->Y[1], mask, zeros); + r->Y[2] = mask_mov64(r->Y[2], mask, zeros); + r->Y[3] = mask_mov64(r->Y[3], mask, zeros); + r->Y[4] = mask_mov64(r->Y[4], mask, zeros); + r->Y[5] = mask_mov64(r->Y[5], mask, zeros); + r->Y[6] = mask_mov64(r->Y[6], mask, zeros); + r->Y[7] = mask_mov64(r->Y[7], mask, zeros); + + r->Z[0] = mask_mov64(r->Z[0], mask, zeros); + r->Z[1] = mask_mov64(r->Z[1], mask, zeros); + r->Z[2] = mask_mov64(r->Z[2], mask, zeros); + r->Z[3] = mask_mov64(r->Z[3], mask, zeros); + r->Z[4] = mask_mov64(r->Z[4], mask, zeros); + r->Z[5] = mask_mov64(r->Z[5], mask, zeros); + r->Z[6] = mask_mov64(r->Z[6], mask, zeros); + r->Z[7] = mask_mov64(r->Z[7], mask, zeros); +} + +/* set affine point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_affine_to_infinity_)(P384_POINT_AFFINE* r) +{ + r->x[0] = r->x[1] = r->x[2] = r->x[3] = r->x[4] = r->x[5] = r->x[6] = r->x[7] = get_zero64(); + r->y[0] = r->y[1] = r->y[2] = r->y[3] = r->y[4] = r->y[5] = r->y[6] = r->y[7] = get_zero64(); +} + +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(P384_POINT* r, const P384_POINT* p); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp384_add_point_)(P384_POINT* r, const P384_POINT* p, const P384_POINT* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp384_add_point_affine_)(P384_POINT* r, const P384_POINT* p, const P384_POINT_AFFINE* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp384_mul_point_)(P384_POINT* r, const P384_POINT* p, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp384_mul_pointbase_)(P384_POINT* r, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(get_nistp384_ec_affine_coords_)(U64 x[], U64 y[], const P384_POINT* P); +EXTERN_C const U64* MB_FUNC_NAME(ifma_ec_nistp384_coord_one_)(void); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_is_on_curve_p384_)(const P384_POINT* p, int use_jproj_coords); + +#endif /* IFMA_ECPOINT_P384_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p521.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p521.h new file mode 100644 index 000000000..30757e749 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecpoint_p521.h @@ -0,0 +1,112 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPOINT_P521_H +#define IFMA_ECPOINT_P521_H + +#include + +typedef struct { + U64 X[P521_LEN52]; + U64 Y[P521_LEN52]; + U64 Z[P521_LEN52]; +} P521_POINT; + +typedef struct { + U64 x[P521_LEN52]; + U64 y[P521_LEN52]; +} P521_POINT_AFFINE; + +typedef struct { + int64u x[P521_LEN52]; + int64u y[P521_LEN52]; +} SINGLE_P521_POINT_AFFINE; + + + +/* check if coodinate is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_point_cordinate_)(const U64 T[]) +{ + return MB_FUNC_NAME(is_zero_FE521_)(T); +} + +/* set point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_to_infinity_)(P521_POINT* r) +{ + r->X[0] = r->X[1] = r->X[2] = r->X[3] = r->X[4] = r->X[5] = r->X[6] = r->X[7] = r->X[8] = r->X[9] = r->X[10] = get_zero64(); + r->Y[0] = r->Y[1] = r->Y[2] = r->Y[3] = r->Y[4] = r->Y[5] = r->Y[6] = r->Y[7] = r->Y[8] = r->Y[9] = r->Y[10] = get_zero64(); + r->Z[0] = r->Z[1] = r->Z[2] = r->Z[3] = r->Z[4] = r->Z[5] = r->Z[6] = r->Z[7] = r->Z[8] = r->Z[9] = r->Z[10] = get_zero64(); +} + +/* set point to infinity by mask */ +__INLINE void MB_FUNC_NAME(mask_set_point_to_infinity_)(P521_POINT* r, __mb_mask mask) +{ + U64 zeros = get_zero64(); + + r->X[0] = mask_mov64(r->X[0], mask, zeros); + r->X[1] = mask_mov64(r->X[1], mask, zeros); + r->X[2] = mask_mov64(r->X[2], mask, zeros); + r->X[3] = mask_mov64(r->X[3], mask, zeros); + r->X[4] = mask_mov64(r->X[4], mask, zeros); + r->X[5] = mask_mov64(r->X[5], mask, zeros); + r->X[6] = mask_mov64(r->X[6], mask, zeros); + r->X[7] = mask_mov64(r->X[7], mask, zeros); + r->X[8] = mask_mov64(r->X[8], mask, zeros); + r->X[9] = mask_mov64(r->X[9], mask, zeros); + r->X[10]= mask_mov64(r->X[10],mask, zeros); + + r->Y[0] = mask_mov64(r->Y[0], mask, zeros); + r->Y[1] = mask_mov64(r->Y[1], mask, zeros); + r->Y[2] = mask_mov64(r->Y[2], mask, zeros); + r->Y[3] = mask_mov64(r->Y[3], mask, zeros); + r->Y[4] = mask_mov64(r->Y[4], mask, zeros); + r->Y[5] = mask_mov64(r->Y[5], mask, zeros); + r->Y[6] = mask_mov64(r->Y[6], mask, zeros); + r->Y[7] = mask_mov64(r->Y[7], mask, zeros); + r->Y[8] = mask_mov64(r->Y[8], mask, zeros); + r->Y[9] = mask_mov64(r->Y[9], mask, zeros); + r->Y[10]= mask_mov64(r->Y[10],mask, zeros); + + r->Z[0] = mask_mov64(r->Z[0], mask, zeros); + r->Z[1] = mask_mov64(r->Z[1], mask, zeros); + r->Z[2] = mask_mov64(r->Z[2], mask, zeros); + r->Z[3] = mask_mov64(r->Z[3], mask, zeros); + r->Z[4] = mask_mov64(r->Z[4], mask, zeros); + r->Z[5] = mask_mov64(r->Z[5], mask, zeros); + r->Z[6] = mask_mov64(r->Z[6], mask, zeros); + r->Z[7] = mask_mov64(r->Z[7], mask, zeros); + r->Z[8] = mask_mov64(r->Z[8], mask, zeros); + r->Z[9] = mask_mov64(r->Z[9], mask, zeros); + r->Z[10]= mask_mov64(r->Z[10],mask, zeros); +} + +/* set affine point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_affine_to_infinity_)(P521_POINT_AFFINE* r) +{ + r->x[0] = r->x[1] = r->x[2] = r->x[3] = r->x[4] = r->x[5] = r->x[6] = r->x[7] = r->x[8] = r->x[9] = r->x[10] = get_zero64(); + r->y[0] = r->y[1] = r->y[2] = r->y[3] = r->y[4] = r->y[5] = r->y[6] = r->y[7] = r->y[8] = r->y[9] = r->y[10] = get_zero64(); +} + +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(P521_POINT* r, const P521_POINT* p); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp521_add_point_)(P521_POINT* r, const P521_POINT* p, const P521_POINT* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp521_add_point_affine_)(P521_POINT* r, const P521_POINT* p, const P521_POINT_AFFINE* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp521_mul_point_)(P521_POINT* r, const P521_POINT* p, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(ifma_ec_nistp521_mul_pointbase_)(P521_POINT* r, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(get_nistp521_ec_affine_coords_)(U64 x[], U64 y[], const P521_POINT* P); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_is_on_curve_p521_)(const P521_POINT* p, int use_jproj_coords); + +#endif /* IFMA_ECPOINT_P521_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p256.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p256.h new file mode 100644 index 000000000..3406c32cd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p256.h @@ -0,0 +1,682 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPRECOMP4_P256_H +#define IFMA_ECPRECOMP4_P256_H + +#include + +#define MUL_BASEPOINT_WIN_SIZE (4) + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE +#define BP_N_SLOTS NUMBER_OF_DIGITS(P256_BITSIZE+1,BP_WIN_SIZE) +#define BP_N_ENTRY (1<<(BP_WIN_SIZE-1)) + +__ALIGN64 static SINGLE_P256_POINT_AFFINE ifma_ec_nistp256_bp_precomp[][BP_N_ENTRY] = { +{/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x00030d418a9143c1,0x000c4fedb60179e7,0x00062251075ba95f,0x0005c669fb732b77,0x00008905f76b5375}, {0x0005357ce95560a8,0x00043a19e45cddf2,0x00021f3258b4ab8e,0x000d8552e88688dd,0x0000571ff18a5885}}, + {{0x00046d410ddd64df,0x0000b433827d8500,0x0001490d9aa6ae3c,0x000a3a832205038d,0x00006bb32e52dcf3}, {0x00048d361bee1a57,0x000b7b236ff82f36,0x000042dbe152cd7c,0x000a3aa9a8fb0e92,0x00008c577517a5b8}}, + {{0x0003f904eebc1272,0x0009e87d81fbffac,0x000cbbc98b027f84,0x00047e46ad77dd87,0x00006936a3fd6ff7}, {0x0005c1fc983a7ebd,0x000c3861fe1ab04c,0x0002ee98e583e47a,0x000c06a88208311a,0x00005f06a2ab587c}}, + {{0x000b50d46918dcc5,0x000d7623c17374b0,0x000100af24650a6e,0x00076abcdaacace8,0x000077362f591b01}, {0x000f24ce4cbaba68,0x00017ad6f4472d96,0x000ddd22e1762847,0x000862eb6c36dee5,0x00004b14c39cc5ab}}, + {{0x0008aaec45c61f5c,0x0009d4b9537dbe1b,0x00076c20c90ec649,0x0003c7d41cb5aad0,0x0000907960649052}, {0x0009b4ae7ba4f107,0x000f75eb882beb30,0x0007a1f6873c568e,0x000915c540a9877e,0x00003a076bb9dd1e}}, + {{0x00047373e77664a1,0x000f246cee3e4039,0x00017a3ad55ae744,0x000673c50a961a5b,0x00003074b5964213}, {0x0006220d377e44ba,0x00030dff14b593d3,0x000639f11299c2b5,0x00075f5424d44cef,0x00004c9916dea07f}}, + {{0x000354ea0173b4f1,0x0003c23c00f70746,0x00023bb082bd2021,0x000e03e43eaab50c,0x00003ba5119d3123}, {0x000d0303f5b9d4de,0x00017da67bdd2847,0x000c941956742f2f,0x0008670f933bdc77,0x0000aedd9164e240}}, + {{0x0004cd19499a78fb,0x0004bf9b345527f1,0x0002cfc6b462ab5c,0x00030cdf90f02af0,0x0000763891f62652}, {0x000a3a9532d49775,0x000d7f9eba15f59d,0x00060bbf021e3327,0x000f75c23c7b84be,0x00006ec12f2c706d}}, +}, +{/* digit=1 [{1,2,3,..,}]*([2^4]*G) */ + {{0x0000b650bc6fb805,0x0004effe2e6b808b,0x00083f5495882e07,0x00072385ef2f7c2c,0x00004d63c80e103b}, {0x0001bd652a23f9b6,0x0008eb0b6587f2f1,0x000580e9e3670c31,0x00021ff5c4623bb1,0x00004edf7b261efe}}, + {{0x000fccfc5e3a3d83,0x000c1079dfbfd8c5,0x000ad0197befd904,0x0002a48c6d6a58fe,0x0000922707799553}, {0x0003e6ddbef42f56,0x0003e80a990809e2,0x0009a2e407e449b6,0x0002a41b969c1aad,0x0000231d792f591c}}, + {{0x000413077adc612c,0x0008fbd803a06b34,0x0008805bda749652,0x0003ac5a1baaa76d,0x0000840390307034}, {0x0009f66175adff18,0x000b37d8c5b739f5,0x0009d75e30b26d7f,0x000cc22875f5ce52,0x00005efc7e9c1325}}, + {{0x00096f305968b809,0x0002789f73b9db6d,0x000c61e01380a091,0x0008c6eda70b83c2,0x00005fb8394e69b3}, {0x000651280edfe2f2,0x00096faeaf829a3c,0x000424bf88f726bb,0x0009706010a4a078,0x000096720442e844}}, + {{0x000dc0752b3e584c,0x0007f5f86a2c492b,0x0007de57335ff9aa,0x0003296074213db2,0x00000bfffc512638}, {0x000c22a1d49c6052,0x00059320ebfb2429,0x00020f4281b037d7,0x00066032b6a17392,0x0000995919cc4cd2}}, + {{0x0008d2333e12b701,0x000b09dd329b802b,0x000bc354d6d490a4,0x000a0d04f356cc6a,0x00001eddf7fe0a0d}, {0x0008328d87fd1d83,0x000ccd0258131e20,0x00029bca2fd2f4f8,0x000b70d3b48cc47c,0x0000f2a78b3541a2}}, + {{0x00005760a99cbca7,0x000594a428f26a95,0x00032ba0c94e258f,0x000166d5ab5a4d78,0x00001704d00f938c}, {0x000ab0ef88b8b706,0x000e600eb207db97,0x000367d8056feb92,0x000a41870352687d,0x00005000c2527973}}, + {{0x000cb817a2ad62aa,0x00090c62ff5463c5,0x000ad9db57ef2b6b,0x0006169749bba4b3,0x0000d311f2ce6d5a}, {0x0008087c2ff3b6df,0x0002467834ffb77a,0x000d6b138b46feaf,0x00018808aa266d75,0x0000a38d321dc008}}, +}, +{/* digit=2 [{1,2,3,..,}]*([2^8]*G) */ + {{0x0008ffa696946fc7,0x000849cba56d486d,0x000f35a1550fbc6d,0x00062c0e3d423e90,0x0000c3da19630dd9}, {0x000fdb03cfd5d8b3,0x0002589dfca5e673,0x0002305aa0704b7c,0x000e53c6ce581ff5,0x000099d49ebc14d5}}, + {{0x0008110399492969,0x000aa61db1b544e3,0x0006eaff55b63827,0x00028fae5323ed20,0x000042370d3521f4}, {0x000af2ee0d985a17,0x000b0239846df2ca,0x0006312f8192cc64,0x0001080c0b8f47ae,0x0000dc61f9206620}}, + {{0x000a53eed4c37174,0x000efd0ed2a335d6,0x000543aa59f8240c,0x0004b44c0d4d05e5,0x00005d5bbfc1d33b}, {0x000cc73137fd28e3,0x000f973b3ffdfa04,0x000f51ef2862ac6e,0x0005a2103ff9f531,0x00004d5e0fcec73f}}, + {{0x00081e144cc3adda,0x0005e7be82cf4f70,0x000dd6472d5ffa1d,0x000862e9890b6c0e,0x0000da26e1aded17}, {0x000271563483caaf,0x00083f6077fd276f,0x000466e3ce6924cd,0x000d1e15a7fe980a,0x00001c794b1a1902}}, + {{0x000385c08369a907,0x000aa90eb4f833b2,0x0008eac802990c59,0x000014119a6145c6,0x0000a786d629ec4a}, {0x000adbe20ac3a8dd,0x00008aba2d3033fa,0x000a4f56531a2178,0x000fba509d2742db,0x0000b2ce9e425aa0}}, + {{0x0006bf38bd7aff18,0x000a9d81b146b315,0x00028a9151b5ee4c,0x00099dfba1ac41d6,0x0000f3a8f9d7d896}, {0x000b9c9a0748be7d,0x0004d92e621f7329,0x00010a8371d391c9,0x000435151e6b214d,0x0000255f53b1947b}}, + {{0x00058d474a861082,0x000fce4c5d900c4a,0x0006d4c80f8048a8,0x000e60c3c7c924e8,0x00008c889de256a1}, {0x000662eb214a040f,0x000747e1034757e2,0x000ac748ae8c48e9,0x0006f19774286280,0x00001c24023086b0}}, + {{0x00024b9eb7926b83,0x00039dbe55093d2b,0x000dd640bbff88cb,0x000d45a0f399afe4,0x0000c5fe1305f76e}, {0x00062f43764fb3df,0x00074151b62d6f35,0x0009ce5f37b5af31,0x00090ee5bd0bc7d7,0x0000daf6b21dc668}}, +}, +{/* digit=3 [{1,2,3,..,}]*([2^12]*G) */ + {{0x000b0e5ab4b35a24,0x0001b5eeaacf6772,0x0005b95801d8b600,0x0001da328f7ce479,0x0000a20ed2a81fb8}, {0x0005cd44fec01e63,0x000c77ff50ad9f68,0x0002d97fd3ed7ddc,0x0004f9160fd2640c,0x0000a2414271b82f}}, + {{0x0009862d5d721d5b,0x0002abd3a1828000,0x000a2cda40c3357a,0x00008477f3a83b7a,0x000058ae74fa6f83}, {0x0001a812e6dad6be,0x0001143d6c5b2a91,0x00096c4d8de28605,0x00024d6bdccc41f9,0x00007312ec0eae1e}}, + {{0x00068feaae6ee702,0x00053602b0c96faf,0x00094052a78f4cc1,0x000d805e3321a86e,0x0000fb3a0d6934d5}, {0x0008f3bb25a43ba1,0x000109ee2951f3b9,0x000b0612a30bf803,0x0001d06ffee43321,0x00002f775e43eb82}}, + {{0x00012e76e6485b37,0x000b071c52f8f8d1,0x0004a2f6d4d3e24d,0x000550d8e3ee4168,0x0000161957d91d95}, {0x0001283cdb12a6c3,0x0001fe50e1641963,0x00066cc73bf3fa88,0x000c38c6254b6331,0x0000aefa7aedee8c}}, + {{0x000008037a929a9e,0x000d39fec6bd46f7,0x000ab8b6265601a8,0x0000ce737f5edc12,0x0000497cd963e599}, {0x000387f9aa5b2f93,0x000f37b78fe82fcd,0x0005d5e30e5faa3f,0x0007ebebcf538d29,0x0000a573239d813a}}, + {{0x000286bd17c24093,0x000333264d9be9f5,0x000f6880f2c4e479,0x000e42e77042b117,0x00009b7e2c87ce1e}, {0x000e722d096f4a9c,0x000afed5e697cec8,0x0002319116861aec,0x00037a02d153f06c,0x0000c2f42b8e8905}}, + {{0x000cb51d0a917b49,0x0002b899f93133e2,0x000a2f6b6c2cfa3f,0x0002b722c94f4be9,0x0000707b1820ca16}, {0x000a172d5f8b10d2,0x00052fd4542ab602,0x000996992fd30783,0x0005e1cef226dddd,0x000021fa98a0b0a1}}, + {{0x000fe623b36f9fd2,0x0003dde19fc079b0,0x0008482ef26543b2,0x000824f36e64a095,0x00003f63771bb095}, {0x000d596b6a1142e5,0x0005e35aac0b14cf,0x000081dd55ea6aac,0x00012a36a0e8bdf3,0x0000fb89d79503dc}}, +}, +{/* digit=4 [{1,2,3,..,}]*([2^16]*G) */ + {{0x00065fce3779ee34,0x000d7d495d9e0f01,0x000284e7ae00e7f9,0x000218dfa4efa220,0x0000564bade87ac6}, {0x000312ac4708e8e4,0x000b671e9adf90e6,0x000684b9f4f5725f,0x000415a95f55ae3d,0x00007f7ccb15e94b}}, + {{0x000890361a341c13,0x000fdcfd61423617,0x00033316c3604dc5,0x000921d22295eb85,0x0000dbde4ac74af2}, {0x000fc5d1c7eef696,0x0005714f4fa1898a,0x0003c21ca5889680,0x00030aa500216020,0x0000f0d1f30a0ef7}}, + {{0x0008b1dbe7a2af37,0x0008dfb74a72bd9b,0x000879697ec51caa,0x0007d549937a4b63,0x0000c9a9d215c268}, {0x000e44f6ef5f0145,0x0002990c69001773,0x00042161e8abcf41,0x000f29e87bd02281,0x000003937564cb6f}}, + {{0x000770977f7195ad,0x0006ddeb838ffabf,0x0004f012d8ec8616,0x000b3f1a1285a8bb,0x000068835046a3ea}, {0x00024f8309004c28,0x000593ffe95eee5d,0x000223ea4a96e4b7,0x000a528cdffe12bd,0x0000f5c2ee636739}}, + {{0x000333959145a65f,0x00080a4063373d61,0x0008a52a0cd9bc36,0x00058f92d11be32d,0x00006877b2887a1c}, {0x000819bf5cbdb258,0x00085e090249837a,0x000990e5f2a4fd1d,0x00011ae22a7de774,0x000040fa5a0f9455}}, + {{0x00090b36b0cf82eb,0x00057615b5e7e58e,0x0009c145a6438d24,0x0001ca57b1f8fc66,0x00000d8b2dae6f1e}, {0x000dadbd9184c4d2,0x0005d93d997654d5,0x000147d473dbb18d,0x000608ea3e0f56d1,0x0000afa8c8dc0a48}}, + {{0x0008c07e3533d77b,0x00097e341c9926e0,0x0002dc4edd7222e6,0x000cf7ed60ec3d8d,0x0000dfe0d902c476}, {0x0009ab61d056605f,0x000596a8551f1fe5,0x000fb8d8ca9ea9df,0x000b0f9489941e47,0x0000eb874ec3a7f1}}, + {{0x0006aa9bd7638026,0x000005303da1ed40,0x000e62ec4c21486a,0x00033e01ae291ec7,0x000022a04933f993}, {0x0000c9dbb7a8ee0d,0x000b9c01aedb7fd8,0x000be74ecdc2ed3b,0x00071e65c35a1208,0x0000540cb1b169f6}}, +}, +{/* digit=5 [{1,2,3,..,}]*([2^20]*G) */ + {{0x000746a584c5e205,0x000169dc7035a7a8,0x000548c9b267e4ea,0x0002f3093a15cfb9,0x0000e6e21359bd01}, {0x000cc6a8c8f936e6,0x000455c241dcdf31,0x0005efb868af84d0,0x0002cb03990a6f34,0x0000fef4e6219b96}}, + {{0x0008f09257226088,0x000a931cf5c6f636,0x000b4f7ac131260d,0x000828c0eb353bfa,0x00005c78880b7eee}, {0x00081ffc3bdf24eb,0x000b45c3c5a84c15,0x0004e6f405bff75c,0x0000c985e8c83fa1,0x000081d1c0fb295e}}, + {{0x000e23d442a8ad11,0x000cf6b9c164f2ef,0x0000aa5e5c3816a7,0x000e6599df2d8bdc,0x000091ae46f220a8}, {0x0007f8700611c5bf,0x00070f1099488366,0x00069595283171ed,0x000a1243a2ecf8ca,0x0000a4a73efe48d1}}, + {{0x0007cc8f43a730f8,0x000bb3ab590efcde,0x00003240be89b6f3,0x0005db4823f529ad,0x00002b79aff18bea}, {0x0002856962fe5de3,0x000b30c591f3568f,0x00028a8580c590ad,0x000f4befc74a144a,0x0000b662498e3203}}, + {{0x0004ed082dd1b6ad,0x000797b703af48fc,0x0005d6aaa5783a13,0x000d425463cb9a00,0x000031ec55d406ec}, {0x000d33f8e9a76414,0x000cc98d9e7a9f8e,0x000887493625453e,0x00056663beade4ec,0x000042b80509a795}}, + {{0x000cf0d6c39765a2,0x000d8c3cca0b91e3,0x000953b50a2db3ac,0x000f1a088f2f08cb,0x0000414582cef43c}, {0x0008bbc60eee9a8a,0x0001d29aa0428dec,0x00032f5d554c79f0,0x00015f381cd5ec65,0x0000672303b6f82e}}, + {{0x000582d3bfab839b,0x00037f8adade46df,0x0007a1bc392474e0,0x00097886a7766a14,0x00006940f54bdc0f}, {0x0008ef2f2759f255,0x00095719f4c64473,0x00050c3459dd9578,0x0000d4d859b7f407,0x0000e788bf302218}}, + {{0x000afa8719c05631,0x000cac5fc79f376a,0x000750cd3cd8ad2d,0x00008e203fdb9fcb,0x00004ff052f5418b}, {0x00084cf3e2d65208,0x0007944ed509f750,0x000f25b987ebdf0f,0x000837743bf0f2d3,0x00006ad71d02354d}}, +}, +{/* digit=6 [{1,2,3,..,}]*([2^24]*G) */ + {{0x000c8c4868af75df,0x000e55c8c7ead9d0,0x00081ecb0d7325cf,0x0004ecbb471996cc,0x0000f5d55f451182}, {0x00045411977a0ee8,0x0004f22038c6be31,0x0004bb4955085c4c,0x000081ad5335bff9,0x000094ad8a748e2a}}, + {{0x00034b22c11bb373,0x000dbd4c74a35402,0x000c5f25d2d0366d,0x000142c9a968daee,0x0000660106897b63}, {0x0006d2c68d7b6d44,0x0008cc84294207cd,0x00068b1eea8f74f0,0x000ee4a275140477,0x0000b5f7e8a3e62a}}, + {{0x00059b21994ef202,0x0009438ae318d1e0,0x0006990102a653b6,0x00084a50d5eb582f,0x000079739f729f5f}, {0x000663c8b799336a,0x000c803c37eb5da4,0x000dbfb2dfdfdf14,0x000f9a92d8a9dca1,0x0000b40cff117d48}}, + {{0x0009f0b879fbbed4,0x00069a9d1869f236,0x000766f450ff0ae8,0x0000fc1251d75956,0x0000984d8c06be8d}, {0x00095a6d21008f03,0x00000a1a1c497ecc,0x0006c50f329bd54a,0x0002517b9828c5d2,0x00002c0087c81d0d}}, + {{0x00090abfbaf50a55,0x000b184e0750f617,0x00076b005df55e76,0x000dc79c516da7f1,0x000075553bbca2dd}, {0x0007ca3553afa736,0x000bed55c25137c8,0x0003e5d35315f3ff,0x000f288846442aaf,0x00001b91149c495f}}, + {{0x000eb6662b5f3af3,0x0000dabb373447fe,0x000f35cb1cefab56,0x000eb9149de60e19,0x00009f8db14457f0}, {0x000cc5b3c61bfd60,0x000d41216703ffae,0x0004e1cc2a5a4d41,0x0009537f8fabed22,0x0000d5a8186871ad}}, + {{0x0003a4956f908239,0x000fe41d777b4bdf,0x0008bf760ba0f507,0x000b01791d71c3f3,0x0000633d5102b625}, {0x000b743b8c9de617,0x0003ede7472003ec,0x000ce1cb2b475125,0x0002ef2f9defc974,0x000074a4f6a70bd3}}, + {{0x0008ea601799a527,0x0001486d2952190d,0x000ff2a7ca20cec4,0x000d36c062ffb27f,0x000041b32e5e9f19}, {0x00081814eb57d471,0x000406aef06bf80d,0x000ecb5887a2d0ed,0x000f5af9735fb01c,0x0000641caaad6061}}, +}, +{/* digit=7 [{1,2,3,..,}]*([2^28]*G) */ + {{0x000824f20151427a,0x0005f24302067f99,0x000112357206828b,0x0004ec0a9097d7e1,0x0000cf9a2f2a9e41}, {0x000c9da279153564,0x0006c01efee3dbda,0x000b288e27e0734b,0x00009c14fab5bbd2,0x0000c630fc5362dd}}, + {{0x000107a1ac2703b2,0x00084bc857b58537,0x000daccd1b49258d,0x00052937df14debc,0x00004ab68d7e4ae8}, {0x000b5d4734e59d08,0x00084495cc807ed8,0x0001db9b35f8740c,0x0005be04aedd5a29,0x00000b360f8cfb99}}, + {{0x0005f5d5fa067d1d,0x000ec668960cae91,0x0008edaac4134b57,0x000435ed3656d6a4,0x0000ac1e3e5cc1d7}, {0x000f869d81fbb26c,0x000bf26c33d4674f,0x0004203e8449ed3e,0x000f49c5138705d9,0x0000cde538c7eeb6}}, + {{0x000c68da61a76fa3,0x000d9a1554dc55d5,0x0003b279c598b441,0x000efca39923b977,0x00003331d3c66bf9}, {0x000848e298de399d,0x0006d1a27f562d4c,0x000b8ab70cfdb8e7,0x0009b9c4c855ea57,0x0000cdb9daf3f787}}, + {{0x000f8c2019f2a596,0x00036b4fbc747bdf,0x0009173ddb3ce5bb,0x0004398a907f688a,0x0000cd3d0d3f5a75}, {0x000c4d6efed021c1,0x00005a77339a92ec,0x00088c64a09a9f9b,0x00015877ca6b1571,0x00000c2996854899}}, + {{0x000a229ed6e82ef1,0x000355ebaf4e5859,0x000ad67ae16f338e,0x000bb3fcd313875e,0x0000c73d22864ef0}, {0x000513174a5c8c7d,0x000faf69ad6a4cb5,0x00066f87e01cd296,0x000320d04d00dde9,0x000096fe447db7b0}}, + {{0x000c06e88fbd3813,0x00042c35a493342a,0x000f1bbcd02cd4a8,0x000d4cb8fa89de54,0x000041d63675575e}, {0x00057fbd238202b9,0x000a1984ead9ebe3,0x000436ea0600b4d1,0x00051b335c9f4452,0x00006fe0a3a33707}}, + {{0x00007367f636a38c,0x00064e76d5cb4c4f,0x000b68b8b9f943fb,0x000a1ef03510baa8,0x0000246780b5ed07}, {0x00014156d549fc2b,0x0000b07781ca3c05,0x000d95413c2953f3,0x0002e2e55e2c69d8,0x0000300fadd2bd28}}, +}, +{/* digit=8 [{1,2,3,..,}]*([2^32]*G) */ + {{0x00086024147519ad,0x000b56b372f02028,0x00085ebc8d0981ea,0x0008e8d9d4a7caa7,0x0000953c50eabdf5}, {0x00061ccfd590f8f8,0x000ac4e6c9179d63,0x000eb64cf72e9626,0x0008f2ffd9611022,0x000063ebb7f1eb28}}, + {{0x0007cf5678a31b0f,0x000d4998b620877b,0x0000fb396d50301a,0x0002a5834257c5c0,0x00009fb18a0f4e67}, {0x000d8ebe8758851b,0x0005ad99ba44ff8b,0x000fd93b71e64e4c,0x000b8b9b8eaedf7d,0x0000a2f2a98b4e76}}, + {{0x00007e0e90fb21e5,0x00006ba7fca1a18f,0x000cd67b500fd2b8,0x0007f6d0387f2795,0x0000b89a4e823970}, {0x000ad3f894407ce5,0x00041c2261328f83,0x00006c13ba0025b9,0x000025779563c7f9,0x0000f548f319e7bb}}, + {{0x000d3a7c35d87949,0x00077356bae50ee6,0x0003322fd042e655,0x0009670f59698d64,0x0000379ae15e0a61}, {0x000ae62fcc9981ea,0x0000cd2934c664b9,0x0004e65ebaed3d63,0x0004278454b3025e,0x0000b09f64899950}}, + {{0x000d3d331b85f091,0x000a988ae64ac1b3,0x000ec50fd0f45354,0x00034f98b626d32f,0x0000bdcfbd4f8288}, {0x0002866cd5225391,0x0002710f7ab3e45a,0x00005f293fa9d473,0x000597c8c1d6b4c9,0x00000ac80474461b}}, + {{0x00015366d91cd2c0,0x000adaa3f0e4e2c8,0x00041e08340a2bee,0x000347fb167a5924,0x000004675e9e9240}, {0x000aaff840e446e0,0x000fea308f727848,0x0009bfad99f9f258,0x000af650f1289963,0x0000939ae63205c0}}, + {{0x00075146fc627e20,0x000591573a51bbb1,0x0008243d5a0569bc,0x000692a7016d9e35,0x0000dac0c56ac1d6}, {0x00033b5da590d5fc,0x00031e8174919938,0x000bf75d0a806780,0x000cfaa5b4f2124d,0x0000c9602338cf80}}, + {{0x0003a1222248acc7,0x000ec264e366b208,0x000fdee281f6ec0e,0x000bb4e659b7045a,0x0000a823a4156430}, {0x0002a04e1900a791,0x000ab9ee65762459,0x0005ea54acde09d4,0x0005a742b6463f4b,0x0000efe9ed3e3ca6}}, +}, +{/* digit=9 [{1,2,3,..,}]*([2^36]*G) */ + {{0x0006dbe305406dd9,0x000f4d5d1957e27a,0x0007d4d8f8eb7dc7,0x000de4654a687638,0x0000c47940a57762}, {0x0005b5d99b307781,0x00065e793682be4d,0x000c740e325380c5,0x0004ae502d37f3da,0x000040deabe2566e}}, + {{0x0006126c49a861ec,0x0005214f0d06eaee,0x0009bfc17024f3b6,0x00038091a3f1e8c6,0x00003c3a8ea67686}, {0x000752cb103d4c8d,0x0002c218b36b3400,0x00051504a02bc461,0x000bf9f67f75eb76,0x00006848b57a02ae}}, + {{0x00081db1782269b6,0x0008c597e5509583,0x000385153ae34bf7,0x0000485b5c60645f,0x0000f0e96b043088}, {0x000021577884456e,0x000b89310ea7bf6a,0x000fad2deb3b5688,0x000d4c37c9429504,0x0000020f0e5f7896}}, + {{0x000428dbbe5a1a9a,0x000e9126bd67cca4,0x0001058268187fd5,0x00019f6036973a48,0x000039b666458bd6}, {0x000deef2d65a8087,0x000f24636b196d42,0x0005d564c4969044,0x0000778611ee47dd,0x0000b2f3a4a42873}}, + {{0x000d8dd0f82b2148,0x00097103cbc603b0,0x000d79e19460c34f,0x0007f8732e5c0318,0x0000b8888bb28411}, {0x00037dcc07226779,0x00088c1c0f278f3c,0x000f7a0c610d21be,0x0000e0447c8468e0,0x0000bf022143decc}}, + {{0x0004160b7fe7b6e0,0x000a400a3fb29755,0x00028ca1e7d16189,0x0008ccd73e9beae3,0x0000dd04b97e793d}, {0x0003c9b506db8cc0,0x000ecf38814ca9c8,0x0004b45e65cd47aa,0x000a8426fc430db6,0x000079b5499d818e}}, + {{0x000d21ae0ac29416,0x000462d3193703b5,0x000c992d0279b025,0x0001f2d307c052ca,0x0000aa7cb934fa8b}, {0x00025800d37c7a50,0x0007342d54225a18,0x000d2ef9213380c3,0x0003c692ac2d66d5,0x000035a70c9030c6}}, + {{0x000b78571ba18615,0x000c80c8f93d5109,0x00033bb9348b22d5,0x000d0898fa84a786,0x00003fba6baaaebb}, {0x0007df3e5eea7d82,0x000648ca71587ff2,0x0006f1a05521c879,0x000ee499d5133bce,0x0000d50cd541d0eb}}, +}, +{/* digit=10 [{1,2,3,..,}]*([2^40]*G) */ + {{0x0006d65533ef2177,0x000453ca2e87889f,0x0002b41677158c7e,0x00057f8b670dfbdc,0x00005910a01f44c2}, {0x000bf07cf88577d2,0x0000c45e2acef336,0x000a23d852224525,0x000f580ed92e8d7c,0x00009f8be4c4b812}}, + {{0x000b2452133ffd9d,0x0000b30f1a20fbb9,0x000a1f52a39a8b2f,0x000df7784bc97dd5,0x00006aebf57740ed}, {0x0007acb76ccdac60,0x000c1586ff273225,0x000de7dd1af4d36e,0x000c168eaa8863f8,0x0000045d5cf88647}}, + {{0x000414351facc618,0x000d668a25bcc51e,0x000f872edbaf2647,0x0006590f5271a00f,0x0000f32ef99bd2d9}, {0x000488c7593cbd4c,0x000c42b82fabca12,0x000eb3f16ed266c5,0x000fe24a2f78ad14,0x000034049490d47a}}, + {{0x000d574c005979da,0x0001ca40e350a6f3,0x000e2ecf9c2072b4,0x00044e5ca5c1568d,0x00008c8bf5c45153}, {0x000e555114df14a7,0x000d8dc5ec6b97ae,0x000a85418d4374a4,0x000f78054cc28f2c,0x00001cb9e2843c41}}, + {{0x0006702094704963,0x000dbbd2381509c1,0x000dd4398a489a5e,0x00069694dde4648e,0x0000ca7b94ab0111}, {0x0005d682ad636a41,0x0004f8dc5f1e3c38,0x000a219436702702,0x00069dfc1965deaf,0x00008666e16710be}}, + {{0x000fd350369c8e10,0x0002b9dc843b6792,0x00002e2ab9271aa6,0x0003838711a4b14d,0x00002b2a3e27ee1a}, {0x000e35f0e2b379be,0x000bf652ab25b226,0x0005601063d3de39,0x000876cca6d4c93b,0x0000ced0cf5a95bd}}, + {{0x000b4ca2a604b3b7,0x0003ca61676245be,0x0008b806e56f6518,0x000480852f5a7097,0x0000aa3978781dc4}, {0x000ac2a0e01fabc4,0x0004e37d99f9e13f,0x000211ffe7c6ee8a,0x0003eae51384ee05,0x0000ff6976d5bc9d}}, + {{0x000507903605c397,0x000e3142c96c8910,0x000923684f0843d9,0x0008938374493416,0x000032caa306a0a2}, {0x000c27061160170e,0x000b637fbaa3b2e8,0x000eda3acc32788c,0x000e0659cd818ea6,0x00002e9423a7e2b2}}, +}, +{/* digit=11 [{1,2,3,..,}]*([2^44]*G) */ + {{0x00075455922ac1c3,0x000c752b3f638df2,0x000de57c4a7b3ef5,0x00008b5e77b21471,0x00001682c10b34c0}, {0x00024f04bd55d319,0x000587b61c71c768,0x000a5089db6d1c08,0x000d3ea1db0903c2,0x0000c092172a84e5}}, + {{0x0005035ea6c39976,0x000a62610bef5ace,0x00080dd3954259aa,0x000a398f18bb3f3c,0x0000910b95bbfc3f}, {0x000f51043e09aee6,0x000f47675665fce2,0x00072db61ced56c9,0x000e68b0e265acd8,0x0000982812f0e9fc}}, + {{0x000b690768fccfce,0x000cd835b362ca2e,0x000fdfccef402d37,0x00098f2efac0d0e2,0x0000fc9cdf09638d}, {0x0002b72d1669a8bc,0x000b9774ccbd2af1,0x00034870e33c536b,0x000ac970b21909fb,0x000038fa2f83df25}}, + {{0x0003d931341ed7a4,0x000c67b59d49b8fa,0x000b8c4a44223272,0x0002e3fdcb194783,0x0000e413c022d130}, {0x0009127e17e44ceb,0x000483b3adfb6d99,0x000aa96caee86bf7,0x00047d46902fe625,0x000073540e595aae}}, + {{0x0005e75b2c69dbcc,0x000843c3da6c7bfc,0x0009102713aa77a2,0x000c551e0df03cca,0x0000bd5ca4b3806d}, {0x00058076db476cb9,0x0001cf37a31ee1ca,0x0001af416fde15d6,0x000db5649af520f4,0x00006c5c5b20d342}}, + {{0x000ef6c872b4a606,0x0003e613521bcc50,0x0003e15d1ab2a34a,0x000511d9c5c19098,0x00001dde5dfb9905}, {0x000f6219f2275f33,0x0006151d894be417,0x000b0bdaa0750c8b,0x0009bd45b04ab978,0x0000bfd9fd475858}}, + {{0x000e02adb22b94b8,0x000921eaa45bc792,0x0001e1c63993d8ae,0x00088a0aad6cd3cd,0x00009529ca845ce6}, {0x000e3aae572a2530,0x000802a21efb2cce,0x000430358e02b643,0x000504a7091b6ec9,0x00006d1b1fa9d7db}}, + {{0x000bfabaf95894c5,0x0006d76b2241aafc,0x000dda48b7b9bdc0,0x0004df9af983625b,0x0000977faf2f3fcb}, {0x00042ef052c4b5b7,0x0000967591f0bed0,0x000f24ec79fe87f7,0x000f1b589c73ca22,0x0000d37fa9f564a9}}, +}, +{/* digit=12 [{1,2,3,..,}]*([2^48]*G) */ + {{0x00064880a750c0f3,0x00031e548e83cc7a,0x000110f0539bacfe,0x0005880d418c760c,0x0000e4daa4ce1f11}, {0x000e7b55ffc69ff6,0x000c320531272733,0x00022df9446f147b,0x000b7c285b2434d7,0x0000a444f6646fc6}}, + {{0x000465ac3f16ea83,0x000d82f1d11c7a1a,0x00068a172115a461,0x0006981767dd956c,0x0000392f2ec013a4}, {0x0009ccde526cdc7f,0x000b32292b81c7a9,0x000d391988e537fd,0x00052c86d8cf69a6,0x0000fc5ff4414468}}, + {{0x00016f4bdaedfbdc,0x000fc6746ced6d0b,0x0004b3e1723fd325,0x0004c7cbfb1d2fff,0x00007f2ec2dc19c1}, {0x00032f245104b0d2,0x000b8dea2b7e3e08,0x000fbfb0f5f00daf,0x000cda09e5cf6699,0x000064f972381827}}, + {{0x0004f7ea90567e6d,0x0006e6ae5cb797b1,0x00010903d513257b,0x000723b5454a3c9f,0x00008d2c9ae39bc3}, {0x00093246b29cb44f,0x000c87c8cbac38da,0x000918e42b540a21,0x00014dabbfe43501,0x0000ffa707b46c36}}, + {{0x000a2f3e30bc27ff,0x0009c08365116eb1,0x00065ab0ee5f0c05,0x000bbc5d741bbf49,0x0000eec41cb73464}, {0x000705f99d0b09f8,0x0006742da5fa1aca,0x00052b931c5d6cc5,0x0008d7c9964eddcc,0x0000ae596164884d}}, + {{0x000e3f1d4e353b7b,0x00043f46b0a00ce4,0x0004b73fd062d8a1,0x000ffcb408d5ab57,0x0000c41d1ca83273}, {0x000e1e76be77800a,0x0007256550313538,0x0009b331a71fe8b3,0x000f727cd916216b,0x0000d825d0c5b388}}, + {{0x000b57b39f8868a8,0x0003f5cc69aff634,0x000d5496ee27f4fd,0x00007f247e58cbd0,0x0000a2679405323e}, {0x0009b72fa30f349b,0x00090696d134c61a,0x00080a6d194c9d9c,0x000994c92beca858,0x0000dcc46465f039}}, + {{0x000e05b1cb76219d,0x0000a1567e7e56c2,0x000c4c9100ec0bf9,0x0004d917076f8661,0x000067b085c8abc0}, {0x00004595e93a96a9,0x000a6bdc249a9fb9,0x000dd0bb77526c1e,0x0006947d44d367ec,0x000053999182dc0d}}, +}, +{/* digit=13 [{1,2,3,..,}]*([2^52]*G) */ + {{0x0009167ceca9754a,0x0005ab7939a083f4,0x0003fd0bf426d2cf,0x0004e18555e35572,0x000096e6d0764f14}, {0x000a8dd87880e616,0x00058508e4d54768,0x000b65e151554381,0x000f9fa9d7e772b1,0x00003439dd70c302}}, + {{0x0003145983c38b5e,0x000b837abc8b859d,0x000ff7be6b14f176,0x000a594793fb9dca,0x0000be5a56015a66}, {0x0001dcd9f87dc596,0x00039bdbf5607cec,0x000eb32577c595cd,0x0005fcfb543b2226,0x0000908064724c93}}, + {{0x000688eadd70482e,0x00099b4a4e8a6aac,0x0008a6eef708de92,0x000c4295b6dd7375,0x0000a4bf353525b3}, {0x0001f2c87912868c,0x00052f09297a1004,0x000f3860ab1b1be9,0x000f4a59ae23c5a9,0x00004f0f83a115dc}}, + {{0x00052381d531696e,0x000fa8cdde69b934,0x00086afc757201bf,0x000ea7fde922519a,0x000030438969d35c}, {0x000c1e18555970de,0x00084535935e7608,0x0002ea38b8267dfa,0x0008b4f4c60a5732,0x00000bf7978604ef}}, + {{0x000049f16a66e918,0x00007a1b0e0dd730,0x0004c28eae97f282,0x000c61c131e00330,0x000020ab732d26ba}, {0x0009ef9287144234,0x000a6db10cb2b2ac,0x00086a4cc54ecfff,0x000d494781476ef8,0x0000b2c87b61b2f8}}, + {{0x0001d4286d2e0f86,0x0001ae8a9fd56ada,0x0008c1b49e592012,0x000afea2c936af70,0x00000f30fee8b4bf}, {0x000ad06858e6a61a,0x00069fd374d06637,0x00088defbce4c776,0x000b6599d54b2d71,0x00008c9d251956a6}}, + {{0x000c0965f5206989,0x000db4f7b8d90e6e,0x0005a68b9640631f,0x000f4e02fd34fca3,0x0000c5a4b66dd40c}, {0x00054bf80b6783d1,0x000e2a320a109494,0x0000a39b280e701f,0x0007db7d1a564a1a,0x0000436d53d42058}}, + {{0x000ea68c094dbb56,0x000e7968d4106233,0x000b3002db77d062,0x000d57de719bbc58,0x00008e7dd3d9dc49}, {0x0005740013a5e585,0x0006ec9e3c1b8d82,0x00099b6ab2131174,0x0008f1bcb0a2a77c,0x0000c48a3b412f88}}, +}, +{/* digit=14 [{1,2,3,..,}]*([2^56]*G) */ + {{0x0003e91991724f36,0x000bd9cbd686c791,0x000d4fc1e5eda799,0x000d547db595c763,0x0000b63b80c0c4fe}, {0x000fc697e5fb5166,0x000a70f1c9646ea0,0x000a92ca5737708b,0x00067a3628745f11,0x00001f37958fa869}}, + {{0x0009b2caa6650728,0x00046fd324ef9af3,0x00027bd3178322fa,0x000aafbd153394c3,0x00001d5f271b129d}, {0x0000c42f48027f5b,0x000bd536e717c72e,0x000369d0faa40cdb,0x0004e6445a657a2d,0x000003bbfc59a7f7}}, + {{0x000c4180d738ded3,0x0000b0de572946a8,0x000a816756f1a5bb,0x0003d4c10230b98b,0x00002c6f30c412b3}, {0x000129dd8fffb620,0x0007b459bf057559,0x0003b67766a281b4,0x00073a77c1bd3afa,0x0000709b38078299}}, + {{0x000b232a3326505c,0x00022e1d41bf8c26,0x000e32afa38d6927,0x000a864459453eff,0x0000e8143ae3cb3e}, {0x000c1fa7e6ab6665,0x000fd2286264932e,0x00036f8ed6cd2d22,0x0005baf59a46fe67,0x00000bf0d00eeca8}}, + {{0x0005852877a21ec5,0x0006bf537a940b82,0x000a9a6a2300414a,0x000bffef1cba4021,0x00000824eeec6943}, {0x000fcecf83cba5d5,0x000843b4f3c0a0db,0x000f24dd7f953814,0x0009dd1174416248,0x0000322d64e34fb0}}, + {{0x00073843d9325f3b,0x00004371cb845744,0x0001e36c5a9bef2d,0x000f71c7d2188ba6,0x0000bd6a7d87602d}, {0x000a9028f61bc0b8,0x000ceed0b6a1ba3a,0x0006e8298f49085e,0x00001d0bc625d6ae,0x000032b0b1e22e9c}}, + {{0x000c447f1f0ced18,0x00031492dd2ba337,0x000a08efa800cc79,0x00041dcb93151dbe,0x000020cf3f95e0a7}, {0x00082dc1c0f7d133,0x000054dde6caff19,0x000f96ee3ef92196,0x0000c6ead7d97245,0x000019c8dbe59dea}}, + {{0x00038717b82b99b6,0x000ce70eb624d3ea,0x00095d46675922d4,0x0003462f66ec543b,0x00006e673cd1ee1e}, {0x00067c4b5f2b89a4,0x0005e90e5cd36afe,0x0000a2ada3de9c1e,0x00023b4c278bb631,0x000020fa3844bdb3}}, +}, +{/* digit=15 [{1,2,3,..,}]*([2^60]*G) */ + {{0x00096796424c49b9,0x0007d7c241c9646f,0x000f68b49f888dfe,0x000f20512d4b9324,0x0000a6b62d93571d}, {0x000b26d179483cb7,0x00022511fae281b4,0x0003aa51f666f963,0x000d166281b3e4d5,0x0000f96a765ef3db}}, + {{0x000d37c051af62b9,0x000a7bf944968553,0x000d59aa1e9a998e,0x00081350844f9fb0,0x000083fd55976afb}, {0x000c0ca65d698049,0x000ddea5ff2d9670,0x000d8623b732b22d,0x00078247640ba95f,0x0000f61916436351}}, + {{0x000b4e0bdefdd4f1,0x0005e366e401f167,0x0003bbec06995846,0x000c214aa368aba7,0x000021487098b240}, {0x000323318969006d,0x000e11fe53d1378c,0x0000c4361cb4d73c,0x00012a8f50a80e13,0x000067f59524ef52}}, + {{0x00081088cad38c0b,0x000fbbd68ae2332f,0x0008e27a3471b7e8,0x000b0ca6ac3fb20d,0x000054660dbc36b4}, {0x0001e11a6fd8de44,0x000a637799ef123a,0x0006ac17c44dbffe,0x000cef0540b977ce,0x000095173a8ef60a}}, + {{0x00037434573eab0b,0x000b21ac6031eb44,0x000dd9afd11570df,0x00023147d9b45b44,0x00008066addd2067}, {0x0002ad8f8a3f0b44,0x0009a0ace2a215f9,0x000b38b809e0e489,0x0000527dcd0aadfa,0x00006506ae957020}}, + {{0x00069f78fca399da,0x00016207bb63429a,0x00088f582fe9e27d,0x000f6e4c655ed687,0x0000426d7494db75}, {0x0005c02ca81c66da,0x00070531d4251869,0x000ff48ba84fb8d2,0x0002469a3a8956de,0x0000f1d0d57166d2}}, + {{0x0009565352c4b5c2,0x0001390bc3e25a05,0x0006f9f5f4926153,0x000a9b609f7521f6,0x0000baef6bfe70a4}, {0x000fa6509ed3561b,0x0002e84b230ce7e6,0x0004cdc691137023,0x0004157151659bd0,0x0000db83c64a007d}}, + {{0x000284d391c2a82a,0x0002758308e89ebb,0x000f1edcabcdd486,0x0006c7606f16ec83,0x000013e2c38095dc}, {0x00056f04a057a87a,0x000006b48f982ab7,0x000651c44a876550,0x000e01a252face68,0x000052b540c81765}}, +}, +{/* digit=16 [{1,2,3,..,}]*([2^64]*G) */ + {{0x0002fc516a0d2bb2,0x000bfa6234994f92,0x000c62c8b0d5cc16,0x00067f7241cf3a57,0x0000f5e69621d1b6}, {0x000c70bf5a01797f,0x000c709561925c15,0x0001fdb523d20b44,0x000f7a14911b3707,0x0000648f9177d6f0}}, + {{0x000c8b8fac61d9a1,0x0002d3c6fe8a027c,0x000bff5037d25e06,0x0002f7d08805bfe5,0x00003271e6c7ff63}, {0x000a6c0232f76a55,0x000d201ef42655dc,0x0000a51788957c32,0x0001739e728bcba1,0x0000ea60412062c5}}, + {{0x000914bb5def9961,0x0003133dd1e74090,0x0003d5e761cb69c8,0x000012b1e9c1d39b,0x0000f3338ee0ccf6}, {0x0005d0d2f5378a8d,0x00065f00cd21b1e9,0x0005fe290acf4c2c,0x0008ad9e984240eb,0x000066c038df4808}}, + {{0x000462bb4d8bc50a,0x0006091957709ad5,0x000412a68181c0b1,0x00048c4bd4fe1c78,0x0000e0341bd60dff}, {0x00045cf7003e8666,0x000a2a24a41bb6bc,0x0004c24c2f11a6de,0x000b67f407151ad0,0x00002c9d27e3a5b7}}, + {{0x0002b30614c09004,0x00017d00c24bd499,0x000c4bfa1da98d12,0x0004bc3f534dc87e,0x0000a5ff67477dc3}, {0x00096b81d7ea1d7e,0x0002a0a6d20868c1,0x000cbbd6e38cf289,0x0005b61d56cd09e3,0x0000c72e27f2205a}}, + {{0x0005719a8afd30bb,0x0007da826dce3286,0x000a8fbe08679832,0x000ad32f04e891c4,0x0000b6b6e1c9bf56}, {0x0005b11471f1ff0f,0x0008ce15baf00a69,0x00096c43ed76c338,0x000157118edb95be,0x00002beaaf580794}}, + {{0x0007932b88756ddc,0x0002317e3e61e8b9,0x000e1c4a4ed4e865,0x000c0e02dd14993e,0x00000aaee18197f8}, {0x000edb96c168af3a,0x000f139ae87515c4,0x000adb4366563c7b,0x000ac00dfadb6f20,0x0000d55e8ca3a042}}, + {{0x000b12e523b8bf60,0x000b8f910c1b0a50,0x0001675888009eb5,0x000abdf535af824a,0x0000f835f9cfb2a2}, {0x00029312afceb620,0x000a169d383ff59b,0x000ac02b0c797df2,0x0000caeb3f5fb066,0x000029d4c6fdaa2d}}, +}, +{/* digit=17 [{1,2,3,..,}]*([2^68]*G) */ + {{0x0002010f5b343bcf,0x000a02f142fe58af,0x0005f4bdf0f2e400,0x000aa84483bfdea8,0x00000b1d093f3bfe}, {0x0001b95c70816030,0x00093dba10972ea0,0x00038f3a6e943e4c,0x00063647be92adb4,0x00000bb7742e5bf6}}, + {{0x000481b7bfe71786,0x000e05405868b674,0x0008c867d4e1deba,0x0000e9a61b2821c4,0x00009c15b35b13b3}, {0x0001666368710884,0x000cd220b1ff3b4a,0x0003d9f4de5e29f5,0x0006750b82bb3523,0x0000e07633358cdc}}, + {{0x000c39731815e696,0x00067cdd28023a63,0x000b4f6af6df9cbd,0x000977ec47ed4a15,0x00002009d82cac0f}, {0x00080d28b898fc75,0x0009dc17c91f664d,0x000ae660972f1eed,0x0008954e84d3bc7a,0x00008c7c19578376}}, + {{0x000f5c7a3e6fced0,0x0005f45fbdeb0d53,0x000339a70e8cbbdd,0x000b81f85c01df13,0x0000ff71880142ce}, {0x0008774bd70437a2,0x00019a0bda6a4c4e,0x0008bd26e5fb3289,0x000521fcdbebd2f1,0x0000f9526f123a9d}}, + {{0x000c905a8271d7e9,0x0004c8e5810ba752,0x000925aeb4735dfa,0x000853518a44ee5d,0x0000708697fa3c8a}, {0x000d540bfcc9a0be,0x000c0574d4038377,0x00060a8a67b27e01,0x0008be5d3d180ccf,0x000048ef153d1c29}}, + {{0x0002e8c0aeaa3c09,0x000e1be85b0a313a,0x000a97d3a89f46d9,0x000cba42889ebd2d,0x0000484026aa03f8}, {0x0009f8a87d83b5f4,0x000671ef02955215,0x000c01acfdb2220d,0x000fe37da0746e03,0x0000f97b2a754419}}, + {{0x0007ac2c880e5cac,0x000dcd11c450ccbf,0x00077a6bf8299dbe,0x000792fb27d11b0f,0x0000601630c1edce}, {0x000b9fb79e7f8ea9,0x000764367288db73,0x00035571be448bba,0x0001a265b6416fb0,0x000081b8f5e34889}}, + {{0x000305192c4d6840,0x00057612efcd40ce,0x0009cae208b04d72,0x00056cb9dcda366f,0x0000edc4d24f0588}, {0x000e6bf854279005,0x00058c09dfea64f2,0x0009bf26c3de8129,0x0005a9841b448737,0x00000b62c6dbdf13}}, +}, +{/* digit=18 [{1,2,3,..,}]*([2^72]*G) */ + {{0x000fb5ed005832ae,0x000ab1042e4f0db2,0x00070f8ca5f5efd3,0x0009cbac4ffdc6ed,0x00004645d0c952da}, {0x000f58bc9001d1f8,0x000bce1172059596,0x00098a08452c8f0b,0x0009de7d4aa0d2e3,0x000015bfe3a904f4}}, + {{0x0003acce548b37b2,0x000264d4054954eb,0x000341b4fb38e754,0x0007fa6c3daa517b,0x0000f6928ec890bf}, {0x000b32386ce6c413,0x0004e0adadcd0496,0x000b5faf901be1c5,0x000985904e67e74b,0x0000cbaf679115c9}}, + {{0x000226ad7ab9a2d8,0x000cfdfae958524d,0x00051d8c29c00090,0x00062c8ba5f53987,0x0000afcbcddbab82}, {0x0002729e99d043b6,0x000b4ebc943a5739,0x000862935ef51263,0x00017b3feace9320,0x000039efc04106c8}}, + {{0x000be7d341d81dcf,0x000842148379e839,0x000026eadcddb688,0x000c5dea6211a1f7,0x00003b25760e4d1c}, {0x000c8f6a7a73ae65,0x000e11d5b48340cf,0x000a50ebc83879a5,0x0008fa75acb1ed41,0x00009a60cc88c07d}}, + {{0x0008d4ac3b819900,0x00029e0cc8fedec9,0x000b427b91cb8372,0x00066cfe0b0491d2,0x0000f2386ace983a}, {0x0004d1eb32912137,0x000de9a62ae4930c,0x0003e89e3a2f82b2,0x000c7f07233853f9,0x0000f8063ac81777}}, + {{0x000c97c593710000,0x00007f759c18604a,0x000db6b65e1c48c7,0x0004953f62ecc5a5,0x0000a78b17338a21}, {0x000819dbcc8ad945,0x0006889c34006be1,0x000b4840a70dc04f,0x0001bff62557b4a6,0x000044c6adeb0bd2}}, + {{0x00007cf02ff6072b,0x0008dad98cdc36e6,0x000f56609a47d2ca,0x000da00f471d1ef5,0x0000cf86624a264a}, {0x0000687aa9e5cb6d,0x000147401c6cb70c,0x000a61435c98124f,0x000ea5b189635fd4,0x000028fb8b079d98}}, + {{0x00030b665c7322db,0x000103c1b3fb4395,0x00072f685cf12cc0,0x00091d170b018601,0x0000915ee22cb583}, {0x000f03ba317db248,0x000897b8ffc49afd,0x000d3d05087dec65,0x0000e6ff46597be4,0x00000a1c1ed80650}}, +}, +{/* digit=19 [{1,2,3,..,}]*([2^76]*G) */ + {{0x000a7b397acf4ec2,0x00003ea8b6403e22,0x0009692850426c40,0x0006703e3295a64e,0x00002aabc59c6a45}, {0x000714c5f5942bc4,0x000dba3182edb929,0x0004152ba9a6168b,0x000367e216a66510,0x00006908d03f6926}}, + {{0x000d8745a1251fb6,0x0008672725c7a9f5,0x000ffe89e967747a,0x00035db95c33e531,0x000009d211049649}, {0x0006ca82fe122271,0x0005f426469dcafd,0x00093183caf9b5b9,0x000fef1e9ee04c56,0x0000084a333d8146}}, + {{0x000b88210395755c,0x00039ec1df80ce06,0x000f55e96117ce63,0x000d1e3efae513ef,0x0000f36cba7bd7fe}, {0x000eca9a40ebf884,0x000f73d37e127340,0x000bbf9ffe6ec1bc,0x00005e8a51b64e86,0x0000e0dbb58cb40e}}, + {{0x0009933aed1d1f71,0x0003405630909664,0x0002e39cf566eaff,0x000124245057f0ad,0x000048ff65b2f832}, {0x00089d4cf94cf0dc,0x0003920c58b3042e,0x00061aa0d319bec8,0x0007ac6a26762653,0x000086fa3034fbc8}}, + {{0x0007b9c7ea2ee345,0x000bb9cc3a71359d,0x0001ea37a3fd0d94,0x000c876b53c31c3a,0x000033425fb1f818}, {0x00099c3810156e0e,0x000350c164487cd1,0x0006425420ea020e,0x0005ea0557ba094a,0x0000657e7e87465f}}, + {{0x000d2ab5c8b06d5c,0x00023e4eac46fc83,0x0006f7779b1a785a,0x000504f99315bc84,0x0000f31d817af9ea}, {0x000fe6a15d7dc85d,0x0003e4016b332391,0x0001cb4c72f132b0,0x0005a059547fe318,0x0000b66d8a735015}}, + {{0x0000e8b593d070f7,0x0005e255625d59cd,0x0007a03994375751,0x000eeae51fdda75b,0x0000bb6e6b09dec1}, {0x000b662334c0922f,0x000e1cf41b79729b,0x000f324023df631d,0x000c8711abf3c578,0x0000cb4666d8cd33}}, + {{0x000d7e1adc1696fc,0x00024acd72d06b66,0x0001b743598ebe59,0x0005eba5f24550cc,0x0000e23139474b9a}, {0x00022d4db067df91,0x0005baff9b00234a,0x00000c9c198dda09,0x0006950bbc75a061,0x0000560a9c8a39cf}}, +}, +{/* digit=20 [{1,2,3,..,}]*([2^80]*G) */ + {{0x0000f1cf1c367cab,0x000b190fbc7de405,0x000a110329bc85a9,0x0003a8f373c4a2e1,0x000064232b85d039}, {0x0007eb0167dad297,0x000124b78ab2f557,0x00029348b1604f30,0x0003419baa94afe8,0x00007fbd8ddb1654}}, + {{0x0004802fcf0a7fd8,0x0008d488b01e31f1,0x00052b49842fd078,0x000200f1d78d6d99,0x0000eb572d987ac5}, {0x000a44c4d194a88b,0x00090a017e66e0a2,0x00088aefcd2b63fd,0x000a10c8efc6c8f8,0x000076f6bdafa881}}, + {{0x000932c68af43eec,0x000db03d00bda2f7,0x000b061f55502468,0x0005ad25dc978f2f,0x00009a1904ae8c81}, {0x000538d470c56a4f,0x000e293d8cedd3af,0x000108ef3159abc5,0x0001773a37245f20,0x0000a17081f123f7}}, + {{0x000a9b2b4b4b67c8,0x0000680206041fe2,0x0008058d8c1d10df,0x000fbb1d64abfcbc,0x0000943b9b2f12a0}, {0x000d9143b3def048,0x0001cce775ff90ee,0x000bc904085ab3aa,0x000dfae05fd4ca7b,0x0000b34a56562c75}}, + {{0x000acf88e2f7d902,0x000757be32cd5c18,0x000eb5ee9fdbf33d,0x000114ea085cd7d2,0x0000d702cfbd3201}, {0x000ebdb85c88ce89,0x000b8e01d617b6e0,0x0007333ac23a3ce3,0x000b6aa041618e56,0x0000dd0fd8fa57ed}}, + {{0x000610798fa7aaac,0x00043073aa4eb2b2,0x000d6b19b41209ee,0x000caf31570359f2,0x0000be6868dbc577}, {0x0004bdc32c04dd3e,0x000defeee397186c,0x00086c0cfa6c35fa,0x000fe1d4a1b312f0,0x00000a5ccc7b9461}}, + {{0x000f3a36fa6110cc,0x00013b93561f516f,0x00057522b74fb1eb,0x000dc5ac0c904784,0x0000fd321052bb8b}, {0x00084a2cc80ad571,0x000576a9b6372d68,0x000f4e8cd7c27fc3,0x0002f02461baedad,0x0000d56251a71724}}, + {{0x00011a9431dd80e8,0x0009f3306cd9b840,0x000b3b730eb7c7cc,0x0003d2a0fadd29d1,0x00003858b5c7e37b}, {0x000d193b6251d5c7,0x0002a352d952bf4c,0x000fbc0511cca1fd,0x000636566157a490,0x0000990a638f9b98}}, +}, +{/* digit=21 [{1,2,3,..,}]*([2^84]*G) */ + {{0x000692a87dec0e16,0x000d97b39d00e5aa,0x000cfa0b5010ded8,0x000a281b1b80c854,0x00006beb87700f8e}, {0x000f5313476cd0e8,0x0005308d394950d7,0x000479fc6a63d0e6,0x0007419a09eea953,0x00002ae98927499e}}, + {{0x000b9105ca7d8669,0x0001aadb3b34ab58,0x000eac0bc582967e,0x000af4f9ae4447cc,0x000019c667d0bf56}, {0x00017b160f5dcd7b,0x000f2dcaadbc9aec,0x0003467f5ec697b9,0x00032e5b98f34146,0x0000187f1f859671}}, + {{0x0007a1d214aeb181,0x000c641432f790fe,0x00091a0c41506af3,0x000bc3ab5565f9e5,0x00000d41a77c44f1}, {0x00065e4a84bde96b,0x0008420a6a1ca09d,0x0007f9ce742f060d,0x00039eb52a3bfdf2,0x00006bdb65ceb3d7}}, + {{0x000dcb6ec7fae9f1,0x0004dfb66e5aeb5d,0x000445d52995f271,0x000620cee95d8e69,0x0000b6c2d4619e27}, {0x0001c318129d7161,0x0000f958c1aa3262,0x000f4af63b03909f,0x000df67c468ef91a,0x000062c42a00ba5c}}, + {{0x0002343753b9371c,0x00099f1f9cd72f68,0x00045db9629cab45,0x000998971623abb2,0x0000507db09ffd79}, {0x000f652af036c326,0x0007a5018e5c4e2e,0x0008be35086f0cc7,0x000327610a73d4ab,0x0000519b397de826}}, + {{0x0005eef9c053df72,0x00079300ea6fe8cb,0x00049cffb8de25b3,0x0009bbbb03fa92c8,0x000042e43a808416}, {0x00051f4dd6f958ec,0x000f34445a8de4fa,0x0000d89496925a77,0x00039026e72a50e9,0x000066648e3eb1f6}}, + {{0x0001957173e460c5,0x0004e0704590b2ab,0x0001c71621bbbce7,0x00065d70a90dbddb,0x000005e399e65cdd}, {0x0004dcb57797ab7b,0x0009ba2ca8e86843,0x0003336c160ad35b,0x0000149bfdb1e0de,0x0000bef99ec88b39}}, + {{0x00096f31711ebec8,0x000f4e98fdc46c3b,0x000b4411f2da40f1,0x000bb6399774d357,0x00007c8bdf495b65}, {0x00089e3c2eef12d5,0x000aec7471f3da3a,0x00012c594de95bb9,0x00056b100f225bd8,0x00004907c5d7b75a}}, +}, +{/* digit=22 [{1,2,3,..,}]*([2^88]*G) */ + {{0x0001db6f79588c00,0x0009b55768cca80d,0x00054438afa52fc6,0x000a4f0b4df1ae7f,0x0000cadd1a7f9b46}, {0x000a6b31803dd6fc,0x000495eaae35b40e,0x0002e4e16488e4fa,0x000c97df047d5538,0x00009b5b7e0ef6e0}}, + {{0x00038b67c4a658ad,0x000870e72182c127,0x00098e44fb3c4763,0x00085e6b77be4687,0x0000c047df2e7a7f}, {0x000d4c55e59d92d3,0x0005b8e64d8d2439,0x000ca9b16cedca47,0x000dfe7724cd0d87,0x00005e4fd59d5540}}, + {{0x0000e0683a7337bd,0x00042fecf2494b7d,0x000a2b71f1e3416d,0x00026c54840eff66,0x00000d9a50b837cc}, {0x00081506fe28ef7e,0x000543324c7fe219,0x0009b52633cc5ef1,0x000474420f345576,0x00002ade2f2810bf}}, + {{0x000344f3a29467a3,0x0009951eba6d9894,0x000e5c2f2de81e94,0x0007b3aaea066ba5,0x0000fc8a61438c8c}, {0x000f88f06d0de9fa,0x00049b75ce0a7adf,0x000bc87d5bbc11cf,0x000de1ffbb7accfb,0x00001458e271badf}}, + {{0x000c8c7dacddb7dc,0x0003be1edcad03b6,0x00008063392ed500,0x0001cde0e46c2f54,0x0000d37663e06dec}, {0x00084c5f365b7cc3,0x000ab79bb95d3969,0x000b1d3c1294e3a2,0x0000f56aa17d7727,0x0000ffd3cfb14944}}, + {{0x00093e3abb830d13,0x00022c2c5270041c,0x0004b259d2ad2353,0x0008577efd1be2ee,0x0000ef267774eadd}, {0x000f7039b0d7d86e,0x000c9b7e6f202af8,0x000c8e29580f5af2,0x0009f5d5fa1d3cce,0x000073f3903d68f0}}, + {{0x0009d11399f9cf33,0x000dee3c43942667,0x00098daf178e7a48,0x000ea2d8722dea0d,0x00007e7ed58b0030}, {0x0001ad43c8aae72e,0x0004cc729695f373,0x000c283527878be9,0x000b608a643affbb,0x0000f8b801c58759}}, + {{0x0003668e039c2560,0x000b7c17fd5d1cb4,0x000aa062b5f26fb8,0x000f04eee426af79,0x000072002d0d78fb}, {0x000a237e84fb7e3e,0x00002c82133d4c9c,0x0007e4181b401d8a,0x000151caa525926d,0x0000943083453dbb}}, +}, +{/* digit=23 [{1,2,3,..,}]*([2^92]*G) */ + {{0x000da31be24319a2,0x000bc095a8e7f92d,0x00078218503f7d28,0x000dbc852fe84098,0x000076ddafe49c24}, {0x00054961d7a64eb7,0x00090f1dbe4280cd,0x00038d2d5e436088,0x000035bf81a87784,0x0000e4d52a8f5169}}, + {{0x000fd9d615faa8f2,0x0000768554ed7b15,0x000a448828fa1eb4,0x000f325bb4447e7a,0x0000bb2d0d1229ff}, {0x0002a646caa6d2f2,0x000e02e7351b075e,0x000506c628eb879d,0x0004dc9cd5624e9a,0x000018eaef0c87e2}}, + {{0x00047d83d30a2c5c,0x000e378a81dc1fe6,0x0001a4a9b0857f77,0x0003f451d5a33413,0x00000a94af9e9d39}, {0x0005c0bdaa6ec1a9,0x0002f8d2d7edbc3a,0x000614797ba9fe49,0x0005332b4335b4bb,0x000091c4d6902f83}}, + {{0x00068cee978a1d35,0x00032ab92d0477b8,0x000a5b862e3a68b3,0x00041d0102979487,0x0000f0606c38a61d}, {0x000be276f9326f11,0x0004b6fe3c2e2814,0x000df73512f521c1,0x000e4407464d7dac,0x00000f5f9d3877f7}}, + {{0x0004ce43d34a2e3f,0x000dc43b5d611fd8,0x0009186c7ee3759c,0x000259995bc78c61,0x000019c380abbb97}, {0x00021aade744b1f6,0x000000f8056bc0be,0x0003efe11a7d222b,0x00025314be6157b2,0x0000fab2b4f6cd68}}, + {{0x0003878a4d32282f,0x000c58020ae7b6e3,0x000a9b750e36e029,0x000818f05847fb37,0x0000876812da29e3}, {0x000138ed23a17f08,0x000070b3950e84ad,0x000d67ae06d7b448,0x000af65fa8aef42f,0x0000d3eea24d2333}}, + {{0x000a522b99a72cb0,0x0007876180162101,0x000f3653e06de6e6,0x00054a5ff8c7cde6,0x0000a821ab5c7a67}, {0x000a52b7cb0b5a2b,0x000c190487907e3f,0x000ce053aa7fb121,0x0009af6a72502006,0x0000490a31fb4e92}}, + {{0x0001244c5f95cd80,0x0000f4ab95f4b06b,0x000e5836dda8c8af,0x000ffc1bae59c2b9,0x00007d51e7e3acff}, {0x0005e6ac2ccbcda6,0x000f2528c3e001e1,0x0009fead43bc1923,0x000710e3324577a4,0x00001a1b8848aa7a}}, +}, +{/* digit=24 [{1,2,3,..,}]*([2^96]*G) */ + {{0x000ee31b0e63d348,0x000229e54fab4fe7,0x000e7b5a4f460057,0x00083140493334d5,0x0000589fb9286d54}, {0x000f5cc6583553ae,0x000a025649e5aa70,0x0000446520879094,0x000c4eec90450710,0x0000bb0696de2541}}, + {{0x0001a3ea2dee7a63,0x000c434b2284758c,0x000aba6addcde2f3,0x0000a77ba445d24e,0x00005aaf668a6cee}, {0x00004a9e5aa049a6,0x000d31103e847e0b,0x000afecc3e74083a,0x000f7a5eb183ce40,0x0000b89dea04a043}}, + {{0x0000e0399375235e,0x0006d9917970b99f,0x0004ec0677614c84,0x0005201ec93ce952,0x000040e7bf97b122}, {0x0000631ee4c47744,0x0009fb04914cb567,0x0009dd2266f03847,0x0001f8896e9429dc,0x00003489b6ccc57c}}, + {{0x0009d23fe67ba665,0x000043cf2f340e29,0x000fcf9139145076,0x000ddaa45b5ea997,0x0000be00843dbd7d}, {0x0003e05d53ff04d3,0x00032de91ef7358c,0x0009ec1a0bf7ccdc,0x0009977d684dbfb6,0x000067e7cf2b01fd}}, + {{0x000d227cc2338fb4,0x000950e2615346ff,0x0001a007689ff6fa,0x0003af7e57077933,0x00003d241c546e1f}, {0x000b97dde9b62a31,0x000490ae30eafdcd,0x000bddf7d6a06e98,0x0003c4b9bf16804f,0x000070471a2e3616}}, + {{0x000a8ae3113655ef,0x000a67b83180ff5b,0x000e0eabefa2c6e2,0x000a962c48271977,0x00009f3c556237fe}, {0x0007022a42581cb1,0x000208f710e3340f,0x0002e5aa8e1de0bc,0x000940de640adef6,0x00006b2389159428}}, + {{0x00019e455950cc3a,0x000bb6b66bb83616,0x000ac6d84c71d665,0x0007e34a034b34af,0x0000987f83385e4c}, {0x00027727a79a6a7a,0x0007426d6c23a074,0x000167e1056e5d01,0x00084dde50b97638,0x0000a6c81f0888aa}}, + {{0x000f3b7b0dc85957,0x00082f1d9f2e0ca1,0x000dd82a727de460,0x000447aaf3bf39ba,0x00009356a79d5862}, {0x0002345f5f9a0529,0x0008839a42f9c060,0x0004d40fc1a8b0f8,0x000368253eee4284,0x00003b0bfe5de5b6}}, +}, +{/* digit=25 [{1,2,3,..,}]*([2^100]*G) */ + {{0x0003a5dc8de610b8,0x000ae7e223ce0f89,0x000ad6dc5e8c515f,0x00028ef774bfa64e,0x00009d20f96125c7}, {0x0000966098583ce0,0x000493f2a7d77a1e,0x000304d4aa2eedb9,0x00082d1b2820974c,0x0000842e3dac0772}}, + {{0x0000e9d74cd06ff8,0x000f2ca3eeaca101,0x00063aa2b9c17c7d,0x0004fef4c86cd380,0x0000595c4b3f3461}, {0x00000ca990f62ccd,0x0002fa0c3be5a3de,0x0008ce9f5d9bed21,0x000443a886078adf,0x0000db27ce42cd44}}, + {{0x00097befc15aa1ee,0x0007d54b07455a30,0x0009a5f1240d1254,0x000ee57bad470651,0x0000d03f7188439d}, {0x000bb6c4a02c4997,0x000d5ffe71d20794,0x0003adcaff725083,0x00030fbcad75190f,0x0000f68ea1cb3729}}, + {{0x000581d26ee83821,0x0005259d638e9c7c,0x00028ae3dcf17dcc,0x000047de8273abb7,0x0000d1129270821f}, {0x000847750491a746,0x00019de0dfb91149,0x000a435ab687fa76,0x000e3ecc2580227e,0x0000b8bdb94f1ce7}}, + {{0x0006d8af7f91d0f2,0x0001882a57289c80,0x000d767543b61b0f,0x0004c62640032d94,0x000073eb5de67d83}, {0x000abf77b4e4d538,0x000f5e4017772988,0x0005071b3b7ce66b,0x000a981fba6b3271,0x00002413c252d3a1}}, + {{0x0007b7e3cc8ac855,0x00078d02753b7553,0x00037df2f8d725f5,0x00031dad05ff64b7,0x00005fe871346d25}, {0x00004a96ab6b01c8,0x0008fcd9372457ce,0x00086699b69a02a8,0x000231cf82ac35cf,0x0000242d3ae1cb4b}}, + {{0x00035269be47be0e,0x0007eb28fea169c4,0x0006c67e5323b7dd,0x000e461a5538ba3a,0x0000f921d70fd378}, {0x00061fc3c4b880ea,0x000df8940a67f929,0x000f0ff393f6f914,0x000f9c0990eb0afe,0x00006c2921090eef}}, + {{0x00003a553fb2b560,0x00074e057f78b23a,0x000e490d96ce141e,0x000e75796525c389,0x0000bc95725a31a7}, {0x00067911220fd06a,0x000ba08b0bd61ec5,0x000ebeba9716e3a3,0x00066f91cd6bf7e8,0x00007326ca75ee6b}}, +}, +{/* digit=26 [{1,2,3,..,}]*([2^104]*G) */ + {{0x000c982cf7d62d27,0x000cb3ba815020d3,0x000763f9e1f36e29,0x000006d8ae0bf092,0x0000a527e6b8d3a7}, {0x0009097581a85e38,0x000f5c158be5b4a8,0x0007d726e1f1a520,0x000862798db37d16,0x0000802786e9113e}}, + {{0x000149e36f09ab05,0x0009fa10bb5befb2,0x000e2099803f163c,0x000bab8029704506,0x00006f0af006b5a3}, {0x000cfec70880e0de,0x000ede3d913f7af4,0x000ceb4bd7332a66,0x000f5452e6c84a7e,0x0000dc4a79b7c228}}, + {{0x00094d1f4c6b6ec2,0x0006f8b3cd9bf6e8,0x000117fbf526b082,0x000bf553f952a812,0x0000be864b031945}, {0x0008ea542099b646,0x0009a7548ce286f1,0x0005c1c9c2770b28,0x0006c337390f2829,0x000072e6a442b520}}, + {{0x0007dd0c55c44969,0x000695bbabd2c37c,0x000d7f363a6a9635,0x0001decb7e63f2ad,0x0000dce3782be73f}, {0x000a16ab2b91f71a,0x0002bba0163ce1e5,0x000e515ade448982,0x000ecf52759c32f6,0x00005e2f1f92615e}}, + {{0x000e2c847c643671,0x000f35af4ec0cacc,0x00034042c6a496b9,0x0002ea1a0836f360,0x00004a1f3901b6c6}, {0x00093633ef1f5404,0x000a32a76d93e7fa,0x000eae451d323b30,0x000f87bfeec8b50f,0x0000eafc172fd04e}}, + {{0x0009be7abded5516,0x000868b744107451,0x00010d9a903d358b,0x0002b6ed00b10b0e,0x0000392b0b188da5}, {0x000a2980b75c904f,0x000db8f7f96c6744,0x0002cf932c305b0a,0x0006c9142e421d18,0x00006fc5d518e463}}, + {{0x0005a51b3e59b897,0x0004d133a1c9e443,0x0000bee591361395,0x0001e417f4697344,0x000014710f870c40}, {0x0004bced6c446c96,0x00060c4d5368c0cf,0x00068fc37e0aa7fd,0x0000577e5d811afc,0x00001febd7317c2a}}, + {{0x00047c9d64cc78c4,0x000b5b6cb27b7958,0x0008022ab6c50621,0x000a1cc7099bf8df,0x00008f862ec004ed}, {0x00032ede1603c166,0x000efc9a9450d127,0x00029b4fc19a80e0,0x00051582257f54b4,0x00006d3b2c6a5460}}, +}, +{/* digit=27 [{1,2,3,..,}]*([2^108]*G) */ + {{0x000b7bc453cadd69,0x00072c0bc1f88de2,0x000abd3af203900a,0x000ffb2cd86e47a6,0x000011cac131502e}, {0x0000242ec965469f,0x000139e0017e2d55,0x0009798850e9f769,0x0001ee733f078f65,0x0000b87d44a3cf75}}, + {{0x000e2a2d551ee106,0x0008127e09a66066,0x00001148d87a8f1d,0x0003fda0d08bab2c,0x0000da8e4f1a24f3}, {0x00017f0cf9a4e718,0x000fbbf5cb19466d,0x00062ecc0ff50200,0x000ac45ccf97d8d0,0x00000c0d9b001d80}}, + {{0x00045ff1d7aadabe,0x000ff5f6a67c1a04,0x000cfb26f65d3825,0x0001d58e62fb0891,0x0000f1e0fa63c7d9}, {0x000c7ba33db72cdc,0x00093a7c74b247e7,0x0000a503c017cbc0,0x000a417c931590f5,0x0000ac54f61216ba}}, + {{0x0007ceb1bf4581ca,0x00060ca7b1669885,0x0009722ace635e18,0x000006878ddd2265,0x00000903c4cbdb68}, {0x000458948f214029,0x0004296abda2366e,0x00040319031b49c1,0x0003fda29c4b09e0,0x00007197ca4629f4}}, + {{0x000dd5d4b07e2b19,0x000afd9ea2217173,0x00005ab14d144c4c,0x0008f158b04ea411,0x00002dda5438e80d}, {0x0002fa8cf03dce66,0x0004ba22cffce998,0x000ad88c48b5ea96,0x00095c97f4ea7f3f,0x00002db773eca5ba}}, + {{0x0003fb4820357c72,0x000e4f1458ad18bd,0x000b44aa1992039a,0x0002817a1df3c525,0x0000d7803580d3d5}, {0x0007e4dc77ad4d4a,0x000859df4fc458cf,0x00071205ed49a799,0x0004a9a465a8b51d,0x00000ee0ea704925}}, + {{0x000e6e89c92b2350,0x000e6b3993a14baa,0x0003dd031a73bbd0,0x00081cd06d60ec69,0x00003cab91b71568}, {0x000862f1db3574b2,0x000544bb061ad615,0x000181e06485b018,0x00075707434988a0,0x0000cd61ad4e1c0c}}, + {{0x000de1cf3480d4af,0x0006cc8acf1a03e2,0x000295a9cf0d8edc,0x00097d023e330368,0x0000add5f69b546a}, {0x00097ad96f8acb1a,0x0004c71bdae28955,0x000dd43f4bddd49d,0x00041976fcd52821,0x00005a4541306191}}, +}, +{/* digit=28 [{1,2,3,..,}]*([2^112]*G) */ + {{0x000b6bfc360e25a8,0x0004875a1a788ce9,0x0001732f4e642519,0x00057a1dc756a848,0x00003c0440fd432b}, {0x000b3f1d720281f6,0x000e7135e051c670,0x000052be72205910,0x000a397ed14b0edb,0x000097b3d282568e}}, + {{0x0009b9afb3ff9ed0,0x000b17f6515c2e59,0x0004da44928c2e0a,0x0004521cbee4fd47,0x000071279a44f364}, {0x000ff6601fbe8556,0x0007ffda51c497ab,0x000597c0b3ee394e,0x00034ab90385f667,0x0000e9fccc7027ee}}, + {{0x000de9314092ebb4,0x000d028e240c0b89,0x000d2f064f17256b,0x000b148f89a7f393,0x0000f57841f21ed3}, {0x0004405e708d8553,0x0001d3f1c3d04ee1,0x000d7eed5856aae7,0x00027098e5424fbd,0x0000333e4efa3ab4}}, + {{0x0007adedda492f81,0x000a682972053bc7,0x000931b4cc11a3ae,0x0004bb4e89a3e734,0x00007512e2eaf569}, {0x00049f3177bf8b6c,0x000948c7ff3e5dc3,0x00011145d232ea4b,0x0009c2dc4f9d16f5,0x0000cf109a3f3b37}}, + {{0x0007a88a1f258972,0x000f81b5d4d8e75e,0x000f3ed5c7ac6961,0x000dfbc3e1077308,0x000008a54ec2a892}, {0x0006e1978660710a,0x0006837df2c8be82,0x000704da50cf70a9,0x0003fca18a7340ed,0x00003eeb9a9a8ca3}}, + {{0x0006233169bca968,0x0003ada6aafb49d9,0x000c2fa9404d286d,0x000fb3409606eca0,0x0000869d0d5a3ff0}, {0x00037e5d0150d651,0x0003140c14c9a999,0x0008e2d49a92e250,0x000e2b556bf94510,0x000052a733ab2f59}}, + {{0x0003d588434a920a,0x0002c22103c5b432,0x0008dbf9ac0af8e9,0x000df1c67518ef93,0x0000184307423a9c}, {0x00094aa5447ab801,0x0005b75a3d61350a,0x000411a9ee5e5a32,0x0000c564ba507f68,0x00000581fc1694f7}}, + {{0x000857080eb24a90,0x000d488e0cfd60e2,0x00059cdb87bedfb4,0x0000a9721ebbd7c2,0x0000b0da855bc639}, {0x00004dbde314c709,0x000bdc32e8462b4d,0x00062fc9ecdbf1fb,0x000ab6a3833eabb1,0x0000939b48c40dd3}}, +}, +{/* digit=29 [{1,2,3,..,}]*([2^116]*G) */ + {{0x0002c1f711b0eb9e,0x0007980ab9549689,0x0000792dbb905f2c,0x000125cce26309a2,0x0000c8ac9b3e684e}, {0x000d8b6b40a24474,0x00015fe3fb24486a,0x0008e3b3f60121fc,0x0003941626fccf1a,0x0000e568622aad1f}}, + {{0x00046c64a8a3d626,0x000fc47743d25a4b,0x000f7e4338469c4c,0x000848cbb3a13d88,0x00002b23a1061be5}, {0x00096b4a63d1a4c4,0x000a3d183f3ee835,0x000afb01c454e7fe,0x000638243fce6117,0x0000e65e5e65c4c3}}, + {{0x00077176add85450,0x000672c49b66e5db,0x000421d771b71cb6,0x000fead856073968,0x00003840fe883e3a}, {0x000dad51ec699775,0x0008e07f6726b391,0x000ca160cae243fb,0x0005f4788ac87be8,0x0000174cced9ce35}}, + {{0x0007eb6cbc613e57,0x0004d97ea61cc1e1,0x0007eded533131d5,0x00011abf69d39eaf,0x00003c2f4354e6af}, {0x0002493a4a375fa7,0x000c4833c5c24ca5,0x0006e71cf5f06787,0x000666114e091f3e,0x00006451f57fb746}}, + {{0x000ab8495fe1347f,0x00087f24503c5ee6,0x00086dd6bab0f6c3,0x000ef4907e3ffb44,0x000000b6c757002f}, {0x000f9a6a78629992,0x000c9ed89e2648bf,0x0008419eb85e5a06,0x000f1666d311af3d,0x00004f3ad7854733}}, + {{0x00003fc6c68d6876,0x000cbff052c75e3e,0x000d16e7a3e732c3,0x00074692d0efa66e,0x00003d92b27165bb}, {0x00082badd44867cb,0x000e48c081b8ffcd,0x0006c8785a71b4a9,0x0002cfbc1676a773,0x0000e2c06174d893}}, + {{0x0006d282bcffbc46,0x0006a6eadb7a5337,0x00035ae69708817a,0x000fde0ff50e05cd,0x00003b5fb75d4bc7}, {0x000e953e7fe08c4a,0x00045583ca1871c9,0x000e81c5cb4d8bfd,0x0001383e8d788245,0x00005f5e93d80474}}, + {{0x000bdef694db7e04,0x000779fcddc680f9,0x000b8dce1edca878,0x000ba111981c3403,0x0000274dcf1b0e10}, {0x00043b86def6d1a2,0x0000cbdb1866f727,0x0000c6f58d25b167,0x0007f5a4491e8c05,0x0000be2b2aba7fbd}}, +}, +{/* digit=30 [{1,2,3,..,}]*([2^120]*G) */ + {{0x0005c9dd111f8ec7,0x000d47c4e7603e0e,0x000392a51bcc33f8,0x00092d002f9a91bd,0x0000da4a7963132e}, {0x0000ae30bb1151be,0x000722e322511a0b,0x0004e9e7854febac,0x0000b80a3a508269,0x000058ffec2c4fe4}}, + {{0x000349d29c4120ba,0x000f20d0d915fbb8,0x00010ba519f94391,0x00091124074fa754,0x000066adbf6b50a5}, {0x000543c34bfca38e,0x000fd9e1ccfcc164,0x00020219ce0f2755,0x000979b9da0f53e8,0x00008234499a6b49}}, + {{0x000c513516e19e45,0x000775c4d5937b23,0x000e71ef656e2e84,0x0004c54f727d735c,0x0000b6304a7479a4}, {0x000a7363ab7e433f,0x00000e742f836638,0x0007fc19f1adea47,0x000697f054b8545b,0x0000935381baa1d0}}, + {{0x0004f9d918e49366,0x000652513982b550,0x0004d9cb965035ef,0x000508a553a0c26f,0x0000cb10d571ea85}, {0x00057b7a242da112,0x000d472b726848d9,0x00002a96b16a4d3d,0x00063b1d7e637c85,0x00007c7032b930d4}}, + {{0x0006b7d5846426f7,0x0008b47d441d5536,0x0006fbf48e7d09e8,0x000d7ce10b404d73,0x0000fa003d15784b}, {0x000614f17fd95965,0x0000e5cb98db25f7,0x00083a76a49e0e0a,0x0000f7dc65957b2e,0x0000d40da8e1ddbe}}, + {{0x0008bb4a595939dd,0x00085874021737f6,0x000ad76120355647,0x00095ebe740e7c84,0x000089bc84460446}, {0x000da5d85a9184d6,0x000b3fc0b074f7f3,0x0008a888e562563b,0x000e7ba6d2e6aaf8,0x000012d8643761fb}}, + {{0x000bba354530bb24,0x00078b0869ea9fb3,0x000431163bde3ef7,0x000a3549bc90460b,0x0000d03d7d324819}, {0x0004f9e43b6a782b,0x0006ec88a68633ae,0x000ffedd9216db30,0x00083fe1dd88e000,0x0000280da9fc2bd4}}, + {{0x00086913e538cd75,0x000c3e08ad53458f,0x0005d15ffa7001f6,0x0005dd02b8c6e6bf,0x000048234a451121}, {0x0009d2d3d5b40458,0x0005ca904190ff5a,0x000607f8bb0ffeeb,0x000729d5a3aca448,0x0000cbd665cb0a06}}, +}, +{/* digit=31 [{1,2,3,..,}]*([2^124]*G) */ + {{0x000a8f833f6746cb,0x00054ea990cac7f3,0x000ddb0a921e46f6,0x000554e15fd5c5ca,0x0000d41f01728614}, {0x0004434426ffb589,0x000584dbc204346f,0x000969b7f8055943,0x00039a63dd20fe5a,0x0000d59e9577899a}}, + {{0x0000ba9b733aa5fc,0x000b305af2353c2f,0x000ac82a5dece47c,0x00018a38e3f715a2,0x000097ba641e203f}, {0x000550409c110608,0x0004c6af512dc3af,0x000f2814656ea2c0,0x0004947ac28daff3,0x00007fab43b159ef}}, + {{0x000115c775d6ece0,0x000be8c0e78def4f,0x0005cfc8169d2e3b,0x00088bb0264ef114,0x0000a41e9fa1b697}, {0x00033be909a1f0b1,0x0001fae76b300d92,0x00032bb69150a845,0x00084ada33753706,0x00005f7b3cfba255}}, + {{0x0001641d4c5105f3,0x000e3d7fbd650989,0x000e6bdb01ae80f8,0x0008606d67225fbe,0x0000b433b59afc4d}, {0x0006db693e856387,0x000273e9862f44e6,0x0005c32ecf7b5925,0x000f506b78515766,0x000002fefd81e362}}, + {{0x000a9141339609ae,0x000d5e37eabd6eb4,0x0008c8d9c2b627de,0x0001e40a4083d172,0x000070814d5318f2}, {0x0005b5717398d14c,0x0004c003f6c94cb0,0x0008292759d37d25,0x000e4eb0577af760,0x0000b4a9a9b867d7}}, + {{0x0006a5c97290293f,0x000be388acbffe75,0x000916bdabf04a19,0x000bec0bbbb9cf5e,0x0000489527481f93}, {0x0007ec32a5923d75,0x000bade0c370dee0,0x00019d8fcc7bc949,0x00093f6d51217504,0x00004f5d4768fdcc}}, + {{0x00005f7d13fb27da,0x0002cc7195c0c20f,0x000fc56c5c05b30d,0x00082b0335cf1832,0x0000e65bcd402b3a}, {0x000aab8630d99eaf,0x0005f62cec6ccbf6,0x000eed2f1164be81,0x000d0c7d41819d2f,0x0000cdc5907fb91b}}, + {{0x000475d0fefb0c3a,0x000aa6d7c35d3754,0x0003798a4d48fb56,0x0008e60070b63336,0x0000e89f3d32fdb9}, {0x00089c86363d14cb,0x0000b7abd27d970b,0x000d5a0218981752,0x000aedebf7d47444,0x00003083bb07ac72}}, +}, +{/* digit=32 [{1,2,3,..,}]*([2^128]*G) */ + {{0x000c244bfe209256,0x00032fdce86762a8,0x00038706391c19ac,0x0004f5fa96a5d5dd,0x00001d587d481d32}, {0x00073a2a37173eaf,0x000763778b65e876,0x000bab43e2384800,0x000fbd20f8441e05,0x0000a11fe133621e}}, + {{0x00049feb8a24a205,0x0001a52ca53f23f9,0x000fb485317ebfed,0x00005d4b691bbebc,0x0000617ff6bb278a}, {0x00034c5e3c99ebdb,0x000d6784156a241b,0x0005d67dffc64242,0x0000109206482f69,0x0000967ce0f9e27c}}, + {{0x00034a3b23358342,0x000a70ef6860c0f7,0x000e2bb0d9526205,0x0003faab8be71704,0x0000418871e22f38}, {0x00076814082c1576,0x000fc9c20073d717,0x00087e728cc914ac,0x0005fd9186c1ebe5,0x0000fdb3c22c1bcd}}, + {{0x0000f0441c23fa36,0x000061989a2eb448,0x000a29ca7b4712eb,0x00028bdccbba0f93,0x0000e205c1536194}, {0x0007957b36416860,0x000d45ac8b4e90db,0x0004e03500432691,0x00051707a759acf6,0x0000514d89c9c972}}, + {{0x0004c1c2cf9d7c1c,0x000a2e95e5abcc7c,0x000ae170c1320886,0x000661fb7b9056be,0x00008a5b2519bc0d}, {0x0001432c11d23031,0x00020f03769f4ed8,0x0005398287da6691,0x000d022ac7a5fd84,0x00004dada944bccd}}, + {{0x000f7aaf0dcbc49e,0x000890bbb45b7bb4,0x0002ca2e57de551f,0x0006eeefd0f3e49f,0x0000ce58709ff5c7}, {0x0000edd167d79ae1,0x0002ea7d7ec13292,0x00030af91039df8a,0x000b59e46206c0bb,0x0000ff5e2f532676}}, + {{0x0000651cbae2f701,0x000583aaa8eb51b9,0x0001df499efc4bc0,0x0007a57ecd8689dd,0x0000aee99a832f36}, {0x00085b9ae8274c57,0x00050d30b39c95d4,0x000c1ef816c14d44,0x0002ed4afea90bbc,0x0000c5f317b1459a}}, + {{0x0002c6bc4fe3c395,0x00031c7bebdfe3b2,0x000693459ba4a815,0x000b11a23ab6b725,0x00003bc377064922}, {0x000c8ab5afc60db8,0x0004a0b9f2a34645,0x0000fc507aa02235,0x0002e6d2a2954cce,0x0000c2731bbfce1c}}, +}, +{/* digit=33 [{1,2,3,..,}]*([2^132]*G) */ + {{0x00091c2e48fb8898,0x0002fb8a9d066a70,0x00082a0e226882c1,0x00052d224986631b,0x000044ed736b5181}, {0x000476fd86e27c75,0x0009b4afefdc282f,0x00019e34da04edac,0x00078b3b256ebc61,0x00006a413e95787d}}, + {{0x000061d5a74be506,0x00047ea16ff582ee,0x000bfc8a2e41781c,0x000e2d80b0c81e99,0x000024f4d696b547}, {0x000545dbdcc9ae4f,0x0005509b1e8e3a83,0x000c935392573dbb,0x000797582960c4a6,0x000001059ae4ae18}}, + {{0x0001e274d559d96d,0x0002e8db6c013815,0x0009921af4f18c0d,0x00002879a3aa836f,0x0000beab27c5c046}, {0x0009eaa7040bf3b5,0x0004c614b091242b,0x0004baf5d39c479e,0x000944e38ede2b0e,0x0000bb192b840a53}}, + {{0x0009f973112795f7,0x0007284e6ee1715c,0x000b66bcde824443,0x000bede5cb4858ec,0x0000c1367361baff}, {0x00015955dbec38e2,0x000c188ad1535466,0x000e0952f51c0782,0x000fa87ba4c53ac6,0x00007e6782a3b21d}}, + {{0x000c251ec5d7f652,0x0006703940877d89,0x000691ab30c8f561,0x000b21409e1cfcf0,0x0000a0300c009b20}, {0x0002fadb114faf4d,0x0008821bf5d1bf53,0x000fc36de328fc0b,0x000f5fed51f93c3b,0x0000989050f4a4e5}}, + {{0x000903d4ed2dbc25,0x00082c3b2d83682f,0x0007e93350eba59c,0x0006d73e9dc84d9c,0x0000f9b21b05eb22}, {0x000d394af267bae5,0x00056e2e15aee33b,0x0008ec500aa86cc2,0x000657ff0bf67d6a,0x0000846aa4549630}}, + {{0x000ba38e7e0c2780,0x000e588b2e6f6786,0x0005fee3a09bf87c,0x000394723b702246,0x00008b8411464682}, {0x0002ce029e646294,0x000f8ca78e430eb5,0x00054a991adb60e8,0x000fe4e0dd7062b6,0x0000281d429069a6}}, + {{0x0009740e2c2bf152,0x000589e99704feb0,0x000fbc565627a220,0x000de8cc8d73d0c2,0x000023eed8fe20c8}, {0x0002583a8363b49a,0x000929c2b0a61ee3,0x000dbc85c1a0b6cb,0x0001aba9f7c3d290,0x00008dfbb97bef4c}}, +}, +{/* digit=34 [{1,2,3,..,}]*([2^136]*G) */ + {{0x000236e846e364f6,0x000c7ea50ca0c16c,0x00026b86d7f33527,0x00070c6481077509,0x0000c2a36096598e}, {0x0005e52f024e9245,0x00044db4afcaa675,0x000831790e0fa07a,0x0000d5c5c3ce7d66,0x0000b4ef350f6cbb}}, + {{0x0004c050f15dde91,0x0007fd5f2b820521,0x000e82b62a47a76a,0x0005eeab254d3062,0x00001a05fe04ec95}, {0x000f46e9d529b36f,0x00009f9e3df67eaf,0x00031769855ab130,0x0007acd463e37199,0x0000d251439bcda4}}, + {{0x0007598a9d82abfd,0x000b16c170f5e2a3,0x00066b0875f188cc,0x000ad9b168220050,0x0000a22c21397155}, {0x0005d3afbddb4799,0x0003dd715b99151e,0x00097cb2e4b606b8,0x000b65ba73b54bf9,0x0000a1bfe43cecd8}}, + {{0x00022f3dbfb894e2,0x0006ae274b18e131,0x00058aadfbe9b79f,0x00035165a49de5ca,0x0000495775831487}, {0x000ef61bb9390993,0x0009f6d13694111d,0x000fc253b1d6a974,0x00015e1474b4ced3,0x0000a1485e67c5db}}, + {{0x000dab61430c9ab7,0x0002b238e9975afd,0x0008042ae0bdd41d,0x0004cb8094743041,0x00001f9addb3dddc}, {0x000c016c52dd907b,0x000c79e2047f7090,0x0001011a6d9bdf44,0x000c7836f1fe801b,0x000063accbd89acd}}, + {{0x000acab4baef62e3,0x0002785b91e87817,0x000e576109f5a220,0x000e036666ebe66c,0x00002ad31f4273bf}, {0x00030a425bcf4d6c,0x0002915056e66283,0x000332156ea95059,0x0002d699811c89e1,0x000089cf1ff4c11b}}, + {{0x000337ac0b7eff35,0x000e75e48b3c0ad7,0x000f13a5f8552225,0x000cbe96f78b0c73,0x0000e70062ed2349}, {0x0005048e7073969a,0x0009233cb3d26b8d,0x000caa20f392d2a2,0x0007074e4f727c4e,0x0000068c99ecccde}}, + {{0x00086ec1ed66f181,0x000bc61fce43ebde,0x000bed74d225d906,0x000ab74cab07d6e8,0x00006e4617f37855}, {0x000aaddb2fbc3dd3,0x000f5aeddf5b6568,0x000cf2fadedb5484,0x000699578f20e86d,0x0000516497c915f5}}, +}, +{/* digit=35 [{1,2,3,..,}]*([2^140]*G) */ + {{0x0003fecfa181e695,0x0000e0d69a98ef0a,0x000eab95d9ea02f8,0x00002162e9cf8e66,0x000020f2beb74720}, {0x000540a1df843618,0x0000f1fa6d5d621c,0x000f5f6ff1203772,0x000ef2ee3c7b510f,0x000017a069c2bb2b}}, + {{0x0002fb6b294cda6a,0x000519039f348357,0x0005cbb216ce9bf7,0x0000d980e012f009,0x00000aecc1c7063f}, {0x0001c3af02909e50,0x000f48ce9cdc57c2,0x000e336f8c7d59ec,0x0005f42732b8448a,0x000056e37233f4f8}}, + {{0x000b53189e800ca4,0x0006d45208fd8a10,0x00014ba3750fe0c1,0x000acc5e43c0d3b7,0x000027d200e74189}, {0x000e24fe616e2c00,0x0008ee1854c105de,0x000342a739c25f4c,0x0009524d3222a58f,0x0000807804fa027c}}, + {{0x000653a4f0d56f34,0x00078a28b805c222,0x00073434b961e404,0x000a18ec03f8b04a,0x0000c966787eb712}, {0x0006c42864fee422,0x000a3b0ece5ccc19,0x00031c159c1be93d,0x000655887d9f22c1,0x0000bb6d593fce45}}, + {{0x0009ec9b809b7ceb,0x000b32c72c2c22c4,0x000a0bf368a41486,0x000c68d13b9420fe,0x00003d36eea566da}, {0x000c08a328cc987f,0x000b4a3264616fdd,0x00010dbba0a3bcd2,0x0004c38103c49dd8,0x00009d81a293b78a}}, + {{0x00065ade4d559419,0x000da03840873de8,0x000f18b9bdedafa5,0x000267df414abb4e,0x0000ee9ea438aee5}, {0x000aa1637a55a4a5,0x0003b15f93b9260f,0x0009c3598eb19a51,0x00078e01d7ebd29e,0x000023fc56d69321}}, + {{0x000070cb98fe684f,0x0009224a1458501d,0x000bc6b3fd60fbe9,0x0007cab45761c892,0x00005384859ee6f2}, {0x00071f7b59e763bd,0x00088b5a8e5e4b02,0x000a482923d4606a,0x0004454eda5d9b05,0x0000a7731d1b6fec}}, + {{0x000369390d458714,0x000fc6166d8da3e3,0x000a90403e976403,0x00063775c3368289,0x0000bd17983b2f1d}, {0x000679ed5d2c53a7,0x00088dcf3b87a616,0x0006a694e5ec4bcd,0x0007e53e6d7613b6,0x0000460fc7753fc2}}, +}, +{/* digit=36 [{1,2,3,..,}]*([2^144]*G) */ + {{0x0001fe1c63c4962c,0x0008d81fdb258053,0x0004c2b6b50541e8,0x000fca1c1291a1fd,0x00000693a1866df4}, {0x000604e0117f203b,0x00025a99b8d0b2c4,0x000212c44245f196,0x0002a7fedc20aac6,0x00001ed4e57020f5}}, + {{0x0000fb6700a1acd0,0x0003fd999681b556,0x000b4e1bae823fd7,0x0000a3da915d1f6c,0x0000d0301186ebe0}, {0x000b0c989fca8cdb,0x000b49da0e0b744f,0x00031d76f970d01d,0x0009695ad8c56479,0x000015737c0a659b}}, + {{0x0007a9c6bdf22da8,0x000f10dc82df18f3,0x000703651efbc432,0x0001a5452cef8e5d,0x00002887ba159988}, {0x0009ddab920ec1de,0x00030c3e8d3b7cec,0x000a88747d0d7e8c,0x000534645bc3954c,0x0000deaa2e17fd53}}, + {{0x000384ece53c2d04,0x000d1e4606daa12b,0x000ec12b0779d897,0x0001ad653e47b073,0x000062dbbba9756f}, {0x00009f2cafe37b68,0x000f6cce2e1769fe,0x000f607fd273d1eb,0x000c250ac1d5383c,0x0000035f7ff92e10}}, + {{0x000cc0f296c9005d,0x0009ab0aebdbb7d4,0x0000ec8d44b9094f,0x00010111bf10f1c0,0x0000807b1c5a667c}, {0x0002cdfbe7133835,0x000e31142ba1a941,0x0000a6bdc435e063,0x000ab9484c15ecaf,0x000092c2460e2a3d}}, + {{0x0002d5a2093c22a9,0x000145703aedca44,0x0003287b6ebd0bd3,0x0008b9a08f2afd65,0x0000bb88bac9d1bc}, {0x000853875c1e3b2d,0x000ffa11447cfbaf,0x0005c4c8dbd2ac94,0x000207586d816cea,0x0000c3aa800f8dc3}}, + {{0x000690016e23e9d2,0x000b87cc41e19365,0x000d6245ccb220c6,0x000a6a936b20c369,0x0000d63c348d62e9}, {0x0003e19cdc0bcb5a,0x000eef601b98a347,0x000e346e470f18b3,0x000a63ead7a2c7cd,0x0000e9f6ec45d3aa}}, + {{0x00034c77e6c55202,0x000fbcb9ea58854d,0x00086666dc27df9e,0x000a85205f2369d6,0x00009d1febf2417a}, {0x000819e93470afed,0x000912a27f9e9846,0x0001e65043e6a966,0x00080954d008a2e3,0x0000ba7ced06cb76}}, +}, +{/* digit=37 [{1,2,3,..,}]*([2^148]*G) */ + {{0x000f541338d6e434,0x00030541d5ccecaf,0x000bc88ca56f7dd7,0x0002c375d426de96,0x00008d94f6bded3a}, {0x000a3bb2ef8279cf,0x000a1b1867f26354,0x000225151d575465,0x0000d7ff99b0ff95,0x00003e19d89e9450}}, + {{0x000f6ce51efb3108,0x0004158df5be0d0d,0x000158e59cb5b2eb,0x00033656459e2936,0x00002aae2b99466e}, {0x0008a39411aa636f,0x0004e4c0a933fb65,0x000f026b77152ecc,0x00011f010c758a49,0x00004837f98bb093}}, + {{0x000f364b71698f58,0x00021f7b605e7807,0x0003b2cbb6ba418d,0x00086f7d20b00fa0,0x000083eca385a543}, {0x000e43ff3437f24a,0x0002048bb33cff0b,0x0009df765e910b43,0x0006f6a963a12832,0x0000c1dd5575e2fe}}, + {{0x000523a626332d5d,0x00028561bb44994f,0x000845ea27bc3883,0x000089305ed4b03d,0x000039d3ee292a1f}, {0x000fdd3e7676b0dc,0x000f3b7060176561,0x00064f9a8620e35f,0x0001f676ce424ff2,0x00004c341a09a268}}, + {{0x000861cf405ff065,0x000cf86e828b1c30,0x0006933fcebac86b,0x0009479791a97163,0x00000e7c2becaeee}, {0x000a095fa90d7679,0x000b5670ab7bc3d4,0x0007b056dae60eb7,0x0002a987633a6439,0x00003a21f33a0501}}, + {{0x0001f22369b87ada,0x000892fca556857c,0x000b064663c00e5d,0x000af17ad74cab90,0x00007112386f50fa}, {0x000e1986d9bd5f51,0x000849c3463f7435,0x0007bd4b22dcc7e3,0x000f31cc7df748ca,0x00003cd4c08adec2}}, + {{0x000e46022caf46b4,0x000f5a96fe4f5936,0x0008f474e6a45dd8,0x000f15b7925434b9,0x000014104124053e}, {0x0008d1241de97bff,0x0000cd80bef471cf,0x000db0037b8547b6,0x000dfec47d3970c4,0x00001bcd329eef20}}, + {{0x00031769bb816483,0x0005353120d000f8,0x000cabc62d69eb48,0x000cb1a17d75f44c,0x00004a07f82e749f}, {0x000f787bbfb55541,0x000052e283f82c3a,0x0009213a0b06ed4d,0x0007b44722889fa1,0x000062b085eecf3c}}, +}, +{/* digit=38 [{1,2,3,..,}]*([2^152]*G) */ + {{0x0000d2f7189e71f4,0x00081ecf91e73267,0x000757a21c643874,0x000ce4d5758e57db,0x000027d09f8690a9}, {0x000308f38384a7a9,0x000420732b99846a,0x000845819aac3acb,0x000e030e94100917,0x00005cba11237ce5}}, + {{0x000851aaaca5e9b7,0x0000e6713b9797b7,0x0000a61f6518aa52,0x000b68c357e8c715,0x0000842e7e35c2c2}, {0x000af656868a5489,0x00025068fc818dff,0x000917733d963bd8,0x000327d4da5c8b65,0x000027091000b247}}, + {{0x0001e48a105fc8eb,0x0009789ba48c37a0,0x0001c2180769d754,0x000387108c6fe1d5,0x0000032dd3467bd1}, {0x00026db020b0aa69,0x000f7664c73c9538,0x0000cf95d05137e7,0x00028a366302c466,0x00009004e1242cef}}, + {{0x000c9a7d298c241d,0x000986807cfd214b,0x00064eadbe3b697b,0x0009c51f1c780245,0x0000de8cdd084814}, {0x000f0a75a4d2604d,0x000e9c1538af946b,0x0005b1fcc27154d7,0x000f81c5cc9230de,0x000088519ea36864}}, + {{0x000e4f796ea6ca1f,0x00092f7928711013,0x000658d45567cdc2,0x000e97bdb728705c,0x00007c1ff4bbe600}, {0x00086574b6cad39a,0x00041a20b428a1ba,0x000e6fdfb3d58d63,0x00060d20011cdea2,0x0000832367b1b189}}, + {{0x0008c9f0e4938f75,0x00098c83719e4761,0x0001a64cc58d47d6,0x000f66874c1a23f4,0x0000d28e06905829}, {0x0007529210466f66,0x000f66a64ef8d8d3,0x000ce6a7a2af1152,0x0002d6f5d4485c19,0x0000d0bd2f65648e}}, + {{0x000032af416448df,0x000ffc76d9711ecc,0x0000b6eae4a7e8c0,0x000593954f9805b9,0x0000d0b15333bed0}, {0x0001848d98b5ca3e,0x000c1039b3ef89f7,0x0007bda2ed01fe5f,0x000e406481332e62,0x000067cecd885073}}, + {{0x000dd1a7cb1282c7,0x00064e46973ab828,0x00008d6b2a08d762,0x0003f2fbaf8d40e7,0x00002571fa1bdaeb}, {0x000732ff22dfd98c,0x00064087108d85b1,0x00088207a87ab01a,0x000754eaaafea859,0x0000cc832f929f00}}, +}, +{/* digit=39 [{1,2,3,..,}]*([2^156]*G) */ + {{0x0001185ca8d9d1ae,0x000cf987ded2488f,0x000c46124adf2c77,0x0005f37f3039f060,0x00005d70b7651e09}, {0x00086506260e70ff,0x00070750d10582d5,0x000bac36439d75ea,0x0003289cf3d0b175,0x00003a7564e11d01}}, + {{0x000a43e3fcd3efca,0x000418088e9ab24a,0x0003d46eadd26c03,0x000a6f05ef4dc9bd,0x00002f99d592a4c6}, {0x000d3552f1da46cd,0x000d4afacdd1ddab,0x000d4057872c3f8c,0x000b94090c4eee92,0x000028bb4209a623}}, + {{0x00092d2e7417ce17,0x0001270ee7f52427,0x00067a41eff42bc7,0x000a57aff4dc6d5c,0x00007709b7b90882}, {0x000731dbe217f2cb,0x000cabb721773554,0x0001dd0592af2a8c,0x000476a8eee76959,0x0000b2930c9fbba6}}, + {{0x000dddaf176f2c08,0x0004625726581e6a,0x000342ffb01ca460,0x0008d58a404ded85,0x0000cf60f96c4183}, {0x000691cc9071c4aa,0x0003944428039bbc,0x0009c0d81fd58874,0x000f7ef7101c8580,0x00007fb754d2c456}}, + {{0x000a1d5af71013f7,0x00049bedc9466af7,0x0007370a0e68216e,0x0001cc84cba30bd2,0x0000981afbff7042}, {0x0006a679449f0e1f,0x000d1a47edae0249,0x000feca2286cfc4b,0x0008fa4073c936b1,0x00005694612f3f8f}}, + {{0x000d6715bde48f8d,0x00025189bc7dbcad,0x00009ee8ac970387,0x000ff78d45299ec7,0x00001287ee3545aa}, {0x0008874db1dbf1fd,0x000ac90c88d67d1f,0x000368313ea46588,0x0003ad90ba649a84,0x00005fdcbcf30d54}}, + {{0x000e9959890272db,0x00098e713a10cf3d,0x0008227b875f3432,0x000dc7ae13479fe2,0x00008561eaaaefac}, {0x00097a08332aafd7,0x000503809b62a6a2,0x00063036f9b0d8bb,0x000da862fa1cfd0c,0x0000a16eb562d64b}}, + {{0x0008e8a2ac13e274,0x000f0eb1a9f5f7e4,0x0001f0a624494f6d,0x0008f0adbf84eb98,0x00009badc3293643}, {0x000a541004f7571b,0x00002f1c94ee50be,0x00027bc31bac67d1,0x000e27753d73a1b7,0x00003d01cf2e0686}}, +}, +{/* digit=40 [{1,2,3,..,}]*([2^160]*G) */ + {{0x000e50f6d3549cf8,0x000f7acd665ed433,0x00011fcb46f33696,0x00085fe95bfdacce,0x000010ee2532f7c9}, {0x0000fe17159bb2cd,0x000da58b357b6545,0x0009fea72f7dfbeb,0x0007445b057e74d6,0x0000485717b62731}}, + {{0x00042e8ee36860ce,0x000c6113c22d896c,0x000104213daf04df,0x0004e93adbb7b744,0x00005fd5fa1ffd39}, {0x0005d941a4e0551e,0x000d38d101516823,0x0009845236772cfb,0x000a97476071e309,0x00004e879df3a56b}}, + {{0x0000aa9b898fd522,0x00079e9af1a76c8d,0x0004f03f82fb38a5,0x000c6fc1f2b9a93b,0x0000b1aad44e3f0c}, {0x000332e7cf2c0846,0x000ea367d26d58b5,0x0006e4a8d1c57d96,0x000b69c297eabdfa,0x00005a947eeaa0e2}}, + {{0x000afb0285b94916,0x0007be4c705eaaaf,0x000d9caab01a0be8,0x00033f9f1d4f5d2a,0x0000e349a4b237a2}, {0x00012464a1c6a163,0x0005f9383260cf1c,0x0006d5471d99e6b6,0x00089bba3d43665f,0x00006974d052f8cc}}, + {{0x000b616fdd5b8549,0x0007c728719ff535,0x000921cad592549c,0x000ef85231468606,0x00008c8ce34c11b1}, {0x00037e7e9090b363,0x0008dbf7bbb728b9,0x000d8797467fc3ab,0x0003fde2337097a9,0x0000e5adca22970e}}, + {{0x00049a1cfe89d80f,0x000cea9c8371c26c,0x000d066d2b42c026,0x0003edda6c013ada,0x0000b8f722946a4f}, {0x00079ecd850935b3,0x000ca631e1b308b5,0x00019853434c1a74,0x000f259b5fe596ac,0x00009ff21f711f24}}, + {{0x00068a7b3f85ff0f,0x000c2a888044cdcc,0x000dbe894acd21cd,0x0000d3c6719b2e05,0x0000ae1d3d97b826}, {0x000dece8a1c5d92d,0x00040c52077eedfe,0x000dd13edbca01a9,0x000aacf085549c16,0x0000c5c3baf195eb}}, + {{0x0009e148f9290579,0x000630c853df27f2,0x000e9c5ce7a64ae0,0x0002a4956cd18358,0x0000d9cce836ed09}, {0x00059796e93b7c7b,0x000181bb9e27cc6e,0x0009e29a0e1e4709,0x000644070b3083aa,0x0000f181a75e785e}}, +}, +{/* digit=41 [{1,2,3,..,}]*([2^164]*G) */ + {{0x000a13f1402b9d0c,0x00026c7bc863d3b3,0x0008c3e6e573441c,0x00057d8b301ec457,0x000026fc9c4cadaf}, {0x0001bfd7493cea35,0x000ecaf8145696e7,0x0008c608fd05d4b3,0x0002768aca2a8a6a,0x00003ef07f65725b}}, + {{0x000c9d646ac49d20,0x000b83137aa9a6b5,0x000225a3842c77c0,0x00090724d000fc68,0x0000f63cfc82fe1e}, {0x000b01bc6441f959,0x00095c8e448f22d1,0x0007fb1ba7d38f71,0x0008df0b33fa5f78,0x00004dcfda1a9015}}, + {{0x000ed45526f09fd2,0x000c6128240a057f,0x0002bfd8de8a4f10,0x000a317332efc4ff,0x000014e77a0dd35a}, {0x0006d7314faa40ec,0x000b41e5f1863289,0x000a1813e767867e,0x00079509adf8f117,0x0000b6cda7914741}}, + {{0x000de10296c36eff,0x000192c4da77211c,0x0007836da7ee8967,0x00060ac617d270a5,0x00000cd9c328cb75}, {0x000cbf7e455fe908,0x000afe7334f301fd,0x0007de4ec3fb53cb,0x000fcff81e2ea44e,0x0000adab3ad8b384}}, + {{0x000d47d53b618c0e,0x000b8a2279231c6b,0x00092d964c424f46,0x000bf19303ffdedd,0x0000971287951b5a}, {0x000a632f815561dd,0x000503c055d18f48,0x00025684f85f48ff,0x000cc2522a142775,0x00000d841a137360}}, + {{0x0008a2b599ff0f94,0x00074104fc6b0177,0x000694ff368a923d,0x000f121bfa44dfda,0x0000f7199dc37667}, {0x0008ff6e46f2a79c,0x000d29f8131dc06d,0x000b4ce7c08b5dea,0x000c3d42519a59ab,0x00004f710bd742ae}}, + {{0x000a90f0e0b040d2,0x000225ff897fb228,0x000fa6122baf02d8,0x0005570aac79e600,0x00004828817ae36f}, {0x0001d31113ec3567,0x000da5eff1f8b952,0x000d417159e48861,0x0001b7baa1d412e0,0x00001f86203c3f13}}, + {{0x000368b4ed80940f,0x00058a6fcedd3014,0x00097579f67e6d05,0x0007f58c208c49ca,0x0000e3d7a8292359}, {0x00032027e096ae27,0x0006b4b393665e20,0x000dcdffcb1f3e1e,0x000e82b6da26f32f,0x00009422f1dd097b}}, +}, +{/* digit=42 [{1,2,3,..,}]*([2^168]*G) */ + {{0x0002cfb9db3b3818,0x000e54df0a4b263a,0x00004e61f9c3a2de,0x000324f28d06e97d,0x0000b1adfbcc2449}, {0x000d9397e053a1bd,0x000696daf7076ec1,0x0000ac7abee2be5c,0x000173b0ba1e1481,0x0000d2ae779c530f}}, + {{0x000d97a205b9d8b0,0x0004056756d40435,0x000f8210e6eb8f06,0x0009ead5e88a8bb6,0x000070ef12dec9fd}, {0x00095053bcc876ae,0x0007c7404ce34d84,0x000a1db5e12a7533,0x0005acf22b49e1b8,0x0000c1f2051f4bfa}}, + {{0x000eb79b6828f364,0x0007c1bd5b9eadba,0x000844b0c9d7a025,0x000fc9ada01e0d1e,0x0000b625175c87ed}, {0x0009fdd9669b6210,0x0006f6f87b981410,0x0000df6bc88a2ca5,0x0003f9fe2eb78817,0x0000cea06f4ffa47}}, + {{0x00081b5c4e83d33c,0x00089efd488b43ed,0x000eb4d0fd9f3587,0x000393564a620f9d,0x00006927bdc6c6a7}, {0x0008df79f9e0f036,0x000e9cd7e1a945c2,0x000a348f12868661,0x0008e01cf4e8d0ff,0x0000bd4c28499853}}, + {{0x000a091289a8619a,0x000fc671b1732618,0x00090c632ef796e5,0x0008fac64e46e590,0x000038062d4be66f}, {0x0004a200573274eb,0x0003f92713946c74,0x000dc0e20d07b67e,0x0005a6891223b26b,0x0000e2d93f29b0a0}}, + {{0x0002e533f36d1411,0x00043dfca442f23e,0x0007c023ae84bb3d,0x000c3ba804a48d6b,0x0000e16a8fa86431}, {0x00052adddd472e03,0x0006dd1ee1271b54,0x000a275997d405ee,0x000b3520fc6f1dff,0x000051ac53cef391}}, + {{0x00014b84444896b8,0x000f794027fb7efa,0x00084487d64974d2,0x00089b6fdcd0e8de,0x0000c45b260ab489}, {0x000bbc2d84634875,0x0006efbc476ca8fc,0x000f443c0d1b2b3f,0x00039bd1d005b7c8,0x000018f2e6790c01}}, + {{0x0006e8c06d75fc1f,0x00064249a89f5603,0x00045e7dd2dcf7bb,0x0002a691dd1d3de2,0x0000578dc4cdbd6e}, {0x0008903df2ce7a06,0x00083c39afac4c02,0x0006404abaee3628,0x0008187c847c3114,0x0000304c0d904e97}}, +}, +{/* digit=43 [{1,2,3,..,}]*([2^172]*G) */ + {{0x0008b33070d3aab6,0x000b3a2cd5e5e4ac,0x000fc91732643672,0x00013ef2eff79b1c,0x000065ca49bf0a7c}, {0x000da59b3efb9983,0x000cd52f13415a8d,0x000f9a5308a5b922,0x0004d77e9ebbab3c,0x00005986e7c256da}}, + {{0x000cf4fda79e5acb,0x0009d630215f534a,0x00085756e68b83b3,0x000cb1ac748b2ed0,0x0000031725995d37}, {0x000841ac5ccc2c46,0x000add9d50696735,0x0001754bd7d7dc96,0x000dd54147e410fd,0x00005296e953399d}}, + {{0x000b3edf0290a8fd,0x0005fb47c387831a,0x0004efb4fcae8196,0x00010ddad7dece18,0x0000cfc53b417491}, {0x000f23c4cb632f9e,0x0005d91f80676698,0x00084180ac42a1ad,0x00026ed116a81d62,0x0000bedf5f9c9013}}, + {{0x000c4cdb30cfb3a6,0x00010c9db4c8d7e0,0x000c8d9df6d09b8c,0x00066ce0ba1a4207,0x0000fd495f77c52c}, {0x000169f275264daf,0x0005f57d8362fb0e,0x000ad722280c2b74,0x000c7afdd987f749,0x0000dc229b03398e}}, + {{0x000fe5a59b0ff628,0x0002c094d0d454a6,0x000437f1d25ec81a,0x0004dc7cfd834e33,0x0000e98378c26760}, {0x0007dd6f48485983,0x000f32fda36a5313,0x00074df4687f2c5b,0x00005640dc1c27ef,0x0000ebf428f3a86a}}, + {{0x000ac7ad0d350a3a,0x0008705a1f2f6713,0x00025404684f6ebf,0x0006f677a1495816,0x0000fa5e9a54ef40}, {0x000af7c1cdd69b63,0x00002ee86474f97b,0x00027f62a64081a3,0x00052cbb9f7f0912,0x0000e47f1dc64856}}, + {{0x0005e7fb7f01d83d,0x000a75ccf5cb6f97,0x00070930f5f1f860,0x00087852702eba8b,0x00008186df7fb5cc}, {0x0005da01720468f0,0x000100464c808c06,0x00077e1ca4247726,0x00042fd8c4bbbec2,0x00004aaea1766ba6}}, + {{0x000ed8452666a58c,0x000026a9c3c2b0d1,0x0009064084bcb6e0,0x0003ff7c57411c26,0x0000fc20755d3556}, {0x0001c505294dba30,0x00068b7dd31ea08b,0x0001eca74a30ba28,0x0002b9d70ba90e99,0x000094e142ce762c}}, +}, +{/* digit=44 [{1,2,3,..,}]*([2^176]*G) */ + {{0x000783e979f39254,0x000a6f4c89a7b81d,0x0001bf7fa1efd130,0x000a9e125c2144fd,0x0000b2969045b265}, {0x0009634b9db65b69,0x000173599d8aed8e,0x0003563f335c82e3,0x0008ab4aa7a54f40,0x0000df088ad922c3}}, + {{0x0004f124237b64b8,0x000963ecfd078d08,0x000845dd8688ebe9,0x000324d7b8a70cf6,0x000008fc59cdda4a}, {0x0002b2ba3585862b,0x00053df29386a903,0x0001ec29bb66825d,0x000dc805a5a8db43,0x0000b143a98ea1e8}}, + {{0x000ba24f111661eb,0x00040105eb049e93,0x00024b578edced48,0x000068e6dc9ba1f4,0x0000f8f66b8983e9}, {0x0004df4d7ed8216f,0x00069e2cbecf872d,0x000e73754bf07f37,0x0007075281d89998,0x0000ec85fbc7aab8}}, + {{0x000bf22765fa7d04,0x000fdd6a537013b5,0x00080db9859805be,0x000ce327a5e29d42,0x0000f53916fb76b1}, {0x000f61f33ddf6269,0x000e1085d103714f,0x000809ee34206238,0x000b1c8c50d4b7e5,0x000099f450e15f8e}}, + {{0x000be731a3a93bc2,0x0005821adc1a82ee,0x000030efd42bbf46,0x0007bba10b6fa4ef,0x000047aa4c7a7b09}, {0x000c632f60c77da5,0x000a7223523e8b8d,0x0004579cf6ffbc26,0x0000f654f6ff1134,0x0000825653ce8025}}, + {{0x00067ba4a493b31c,0x0001dbf7f0264bf3,0x00095914b54f20a5,0x0006abf696e06297,0x0000ddab96e4bf23}, {0x000c70aed25ea138,0x000b01cbbbe74ff2,0x0008544c5fa1d09e,0x00031708fc8c8746,0x000047a670de96b3}}, + {{0x000c595d314e7bc2,0x000b267899ededa6,0x0001ed5d32ee7464,0x000612fcef423c0a,0x000017e76ea89cc7}, {0x000ce1fe7cda917f,0x000a9a893f1627cc,0x000c74f6b12d8016,0x000e60ccd6de849f,0x0000a5817e3e3144}}, + {{0x0004cc5ac751e7b7,0x00028d4211bdb79d,0x000de4fc693f9647,0x0000641c72d3d2c8,0x0000b69cbf64f44f}, {0x0000ca2f4bf94e19,0x0008612894e23da9,0x00017d60b1a5325f,0x000b5c7a437f6c79,0x0000be7048726c9c}}, +}, +{/* digit=45 [{1,2,3,..,}]*([2^180]*G) */ + {{0x0009976e1337c262,0x000db73d68e5949c,0x000b768d96faadeb,0x0000697e158614f1,0x00002dfa557bcc4f}, {0x000da17be93c6d61,0x00019504f5b9ccd6,0x000694da124866c6,0x0008c61121353c8d,0x0000c6ca5801140b}}, + {{0x0004a7dd4b79bb87,0x000ae2c878c8f160,0x00047b8e8aee806f,0x000053c4144f118d,0x00002edf52c049f9}, {0x000a84e2127015a3,0x00006cb7cef3ebfc,0x0006deec89051d0c,0x000d7456e8fe5829,0x00003b2818871010}}, + {{0x00060ed9aed9f40e,0x0000732a8c99bd56,0x000c371ea70ca6ad,0x00009ce4978bfb95,0x00005464d0e50031}, {0x0002fdfd9e535ef8,0x000718c9185b1af3,0x000b42488abf57ea,0x0006fa6d7a741712,0x0000e0296a869728}}, + {{0x0009383171b445fe,0x0002a131ad4c0107,0x0003987e89bcf21e,0x000c8eacdfe205c9,0x000063f4153a92e8}, {0x00062a930add43df,0x0002d980f05a7294,0x00006e96862ebb14,0x0006b05f3954e53b,0x0000e1d75ae142cf}}, + {{0x000416e1f017d5eb,0x0005c674e99b8b57,0x000f488a03753339,0x00095dbe6d94c0e8,0x000093a787b8c16f}, {0x00051a2dcc99ccc0,0x00039aa47c1dc3ac,0x000dfd8d5c134b41,0x0001edf28fcdafaf,0x0000d57bd8e10b83}}, + {{0x000fbccf0bcfc46a,0x000e15cffee69276,0x0005d915b3a822ac,0x00076b928ed2fec7,0x0000145c11463594}, {0x00081538be17bcdc,0x0002ea6c3d8ff61a,0x00016c82f01e867c,0x0009af9634e15d65,0x00001437bd32948b}}, + {{0x000d2006c19d4c7d,0x000711b1e976d2fc,0x000f237e8a0f3c43,0x000bb120545ff694,0x0000d10ec4090bf8}, {0x000696cac7cd3e1f,0x000b6f24bfe64f89,0x000af7706ed3714e,0x000c31463eb1d85f,0x0000cbd604eb027c}}, + {{0x000c6c7af8685c8b,0x000d7f8f01aa5f95,0x00074692ad4c1c8c,0x000068144bbe3225,0x0000800347984a4a}, {0x000c6e52eca3cdb7,0x000b7c04d3997c8f,0x0002bc5cfea1db16,0x0003d2405bc82e8f,0x000063d518064479}}, +}, +{/* digit=46 [{1,2,3,..,}]*([2^184]*G) */ + {{0x000963f4c8303203,0x0000603203e3f3b7,0x000327afb842c7aa,0x0009b67f22ca0ae7,0x00008e13092c6760}, {0x000fb62757558f1a,0x000157eca8c173b8,0x0003316273cc3e83,0x00023444174474f6,0x000077989cb63c40}}, + {{0x00017f4b0166f7a3,0x00079eec74e6ae83,0x000874bfdfbd3e3f,0x0003a3cdb516ace0,0x0000d846019f681f}, {0x000ee5c7c1620b02,0x000d0b63c5010b12,0x00068c51eba68b4d,0x000b5b8c03cd3266,0x0000a6279f76e0bc}}, + {{0x000b8b0b796d2197,0x000ec4741dd9b32c,0x000edf6f5c3e95f4,0x000b8e1721212568,0x0000a03aee512b9c}, {0x000c376f53a89aa8,0x0001148a28dc0cd3,0x0002ab04f0d8af9b,0x00002d4f86a3f490,0x0000aacb62aff420}}, + {{0x000139f8f5fcda83,0x00048dee5bfdfd8e,0x0003f9f77f3e558c,0x000969a76cbaf4e3,0x0000a4c97a4a1771}, {0x000e84bf6dce6a73,0x0005e3e6c2d1da27,0x00059a6e9ff373d9,0x00062cc115193cd7,0x0000f9b702593d22}}, + {{0x000ae6c252bd4796,0x0009b2b5848f9cb0,0x000c9766305e0f88,0x00025c18f6d2b2a5,0x0000f6e149c21622}, {0x000235cde601a897,0x00088373be1fe602,0x000471827d17bbe9,0x0001165af49a5ba8,0x0000e1a0a8588aaa}}, + {{0x0006fea87baa6279,0x0001672aa6801253,0x0001e5dc958c1fec,0x0001b8dc29b63760,0x0000e3c3c1d6e9e0}, {0x000127b2bcfe0b0f,0x00013a12f50defc8,0x00079b3973510710,0x000f207ccd6cb148,0x0000792f805e8a82}}, + {{0x000572235e6fc06c,0x000e4b3e13d58b1e,0x0008a73723477728,0x000289550c294daa,0x00000291d43fbfa5}, {0x000bc67cec5a196b,0x0003ac2e8a7cc6c8,0x0006e1c51deeb31e,0x0001560a93e244fb,0x00009f8b71bde28e}}, + {{0x00084911a335cc88,0x0009ea5913e48c31,0x000b32919563459b,0x0005ac9b920d61c7,0x000005ab8b720242}, {0x00012da8d006086c,0x0009fcf5c0fd2ac5,0x0002138d76ca4846,0x000442efea51d8ac,0x0000b647545f44cd}}, +}, +{/* digit=47 [{1,2,3,..,}]*([2^188]*G) */ + {{0x00053e453544774f,0x000b4adba2bc5110,0x000e371f5834d0ec,0x0003bb5215d7f7ba,0x0000cfd57c05c866}, {0x000383dd6901b1d3,0x000485587dc3ded2,0x000625f623b49fbb,0x000762cd44a08d07,0x0000ee4d65bcde9b}}, + {{0x000137d0d63d1fae,0x000122a9d89f64e5,0x000436309658fc05,0x000a606889487450,0x00009ae30f9b598d}, {0x00010d1818baf918,0x00060b6a0c202ed7,0x0001a6b44e27e9e0,0x0007db9e28dcfb1c,0x000083acb6556ac5}}, + {{0x0002e774e6daae2d,0x0002ce0a19bced7f,0x000ae677e7b3ae0e,0x00011f03293f8a91,0x0000363b0cc15c86}, {0x0001ccf309ae93b1,0x00072920cae1be1d,0x0008edf01a3f80be,0x000c909aacba7449,0x0000e6d2a4ac2f5a}}, + {{0x000728dc2c6ff707,0x000f55dc22358735,0x000e277f979d6122,0x000cc6b3f5d00319,0x0000ee84e264ded8}, {0x000afb063cd880a6,0x0005d574af6091a8,0x000de7f423f3ea7c,0x000151acfcdc8402,0x00002d07930131aa}}, + {{0x000f5aabeccefb5d,0x00086621d7c740fd,0x000b576c1cf56ede,0x000026e632a9ce52,0x00003403ae96a6f6}, {0x000050de8785a64c,0x0006d682652e660a,0x000bcbe0210f3d64,0x00015cb8b25edf4f,0x00009710fdf74f93}}, + {{0x0004e438a5807cef,0x0002f4109a7e8e1b,0x000d59ddaad28389,0x000092d30cc9cbaf,0x000065f36c72d8d8}, {0x000469ea60d32b2d,0x000a6e8191c8df31,0x0005bdeb5ee93df4,0x000a27cc1017c535,0x000026231865616a}}, + {{0x000ade73245980e9,0x0006f1067200d655,0x000136be1a6f5965,0x00087954fc23bedb,0x0000f246cdd3f13d}, {0x0003117f961ac0ef,0x0004fbdb9e1ac2b9,0x000693bd1c8a741b,0x00001d92ede2466c,0x0000cde6b502dd17}}, + {{0x00083f9dec31a21e,0x00028ad9d573b02c,0x0007be365988c8b2,0x00034d73e983aea5,0x0000968734e446f8}, {0x000ea8f5da6309bd,0x0003f1f1ce169137,0x00044092110f3a62,0x0001b4a82a9ea2ca,0x0000f94739f2b46f}}, +}, +{/* digit=48 [{1,2,3,..,}]*([2^192]*G) */ + {{0x000410ef4f8b16a8,0x000e447b266a56f8,0x0009c87c197241af,0x000b1a8a406b8e6d,0x000003f3e034d42a}, {0x00009a804dbec69c,0x00067bbad05f7f03,0x0008e197fa83b85f,0x000dc106097273ad,0x0000097440f1067a}}, + {{0x0007fa0b311898c7,0x00045d0eac653f74,0x00014d0bce2a272e,0x000ee2dbba5851f9,0x0000a1a966134a43}, {0x00067cea1c8cde9a,0x0008d271abe3e5a3,0x0001615cd9d958ba,0x0000b053ff7eb63d,0x00002280dcf95ae2}}, + {{0x00044a43794f8dcb,0x0009983c5c362663,0x0009d10a0dcca923,0x000df27d6b6bbf3f,0x0000320c5cb31d9b}, {0x00028ff47b50a951,0x0001bef03371620e,0x000100153933e3b0,0x0008d6e081bf8599,0x000083be9a0d3a8c}}, + {{0x00085c341dca5663,0x000aa8622aa3b6c1,0x0001b6dfb7de7fed,0x00028869e84d9290,0x00000a02b0eac4ad}, {0x0001daa2fd3cf36d,0x00070f89e59fc7c8,0x000496733d131954,0x00012ae2be8184cd,0x00005f449ec63d34}}, + {{0x0000fabe085116b3,0x0005572853102547,0x000bfd52f04a4337,0x000c741e39187ee2,0x00006166b44ad9eb}, {0x000433cfd4b322cf,0x0006ca79ab5192ad,0x000db15eb726aa81,0x000e63096eacd8c1,0x0000af71e91f476b}}, + {{0x0009bdac97e65165,0x00007230f49ed74e,0x00074ea498877936,0x0005a256ec1de31e,0x000081dcee58fb64}, {0x00023918f483f148,0x000c5137d13bbaef,0x000743a426d2dddf,0x000e66d4cde50ed2,0x00009a34fc664d97}}, + {{0x000d2e949dee1686,0x0002de2af23972cf,0x00094066a1ae0522,0x000412a09e75be1d,0x0000cca31c798abf}, {0x000d61d9bc499082,0x000cd5e2bc1eb50b,0x0006f83ac4a9b4a8,0x000b28cb6cc5f794,0x00007da93fd0bffa}}, + {{0x000ec644cd8f64c3,0x000ff79d7b51c492,0x000c7525658a2d78,0x000016dced1fc51f,0x0000e658aedbf433}, {0x000942e05da59eb6,0x0002addc37220b61,0x0002e7f87ba3d60a,0x000b6e1c311cd174,0x0000473ffef56b01}}, +}, +{/* digit=49 [{1,2,3,..,}]*([2^196]*G) */ + {{0x000604f692ac542f,0x0000327b91d38303,0x000aaf9bdf079ffe,0x0004fa29f63e6315,0x000099ee566e1f34}, {0x000661fd62191997,0x0006648ce41c8a1d,0x00074d9048c883bc,0x000b1aa065118f3c,0x000013889ee7faf8}}, + {{0x0003f8f81a1b3bed,0x0004fe2764a0972b,0x000c4f5f74f3ce14,0x00085b12d0f1cc28,0x0000eee0c0e97f39}, {0x000adc0d39e25c35,0x00007467a0807df4,0x000cf5a584061982,0x0005fff40ebc9361,0x000027729a6922ad}}, + {{0x0000937b1b76ba6f,0x00045d2026dcca6c,0x000d9ae0a1a2eab8,0x000025c1715e1519,0x00001ad919aaac4a}, {0x000dfb807ea7b0ef,0x000e4ed9eb8935b3,0x0006d08abedf5496,0x0007309932e5ff2d,0x0000314874f15bd2}}, + {{0x0006a753f73f449b,0x0007dd44fc79efb2,0x000c0dc4d1d1c94f,0x0000cf99f0fbc53b,0x0000747ea0be698a}, {0x000c3fe228d291e6,0x0004e3c129d65218,0x000acc51635b804b,0x0006689ac859b8d1,0x0000c10697df5d6e}}, + {{0x000438f0876fd4e6,0x000723d2f383c38e,0x0000934cb45f0c30,0x0006edc03cc2ecb1,0x0000a8f24398c9d4}, {0x000431b65ccde7b6,0x0007c7e76a6ff16b,0x0003484d741e2cd1,0x00044a59c8cf8f4e,0x00004426efde3152}}, + {{0x0008e44fc94dea3f,0x000eead6a0b01c0a,0x000113cef34c8cdb,0x000ff9a19c384004,0x0000d32fba505490}, {0x00090f6795dcfb75,0x000333588baf58d1,0x0001fc1c0fef01b0,0x000ac94e6d1d63ca,0x00003173f9740a41}}, + {{0x000402aba16f73bc,0x0003ccf9b9fc2b1d,0x0006ef7bf2fb3101,0x0007446d51e60e44,0x0000731021c791e1}, {0x00047244fee99d47,0x00068ac5c1ea9d3b,0x000ea9af74bca48b,0x00083a00f5f514bb,0x000051f55a6074c2}}, + {{0x000251acb452fdbb,0x0004a0f306506e30,0x0003548d931ee696,0x000f5b00b3e50893,0x00008949a50a4b0e}, {0x00083263c88f3bd1,0x0000cb1d9989208b,0x000d4df03ab147c3,0x0000c5dd6515fd44,0x00007a12f75f72eb}}, +}, +{/* digit=50 [{1,2,3,..,}]*([2^200]*G) */ + {{0x0004f7881fdad909,0x00057d2cf6ab2591,0x000054de5cf638f5,0x000350290bc03fcc,0x000032811a7a8b06}, {0x000b3309bbd11ff0,0x000fb40449742f00,0x00051d26676108a6,0x0000c1801bb9e0a8,0x0000dd099bebf899}}, + {{0x000dd8a58d6cd461,0x00057e6634d214c6,0x0001bc3289cb633b,0x0007e5b1305047f8,0x00002ede0e236a17}, {0x000ca62065a6f4f9,0x000cd7be487b332c,0x00047ed1cc3a47ec,0x000b13e41eb1870f,0x00009e66e5977598}}, + {{0x000a6777b0ac93d1,0x000d68f5e0d7ebd6,0x000f5492ba6e37b0,0x000f3a1516c09676,0x0000e4bf888aac05}, {0x0002ce04df0ba2b4,0x000d1062341bcdb4,0x000acac20935d5cf,0x00000e4a30333382,0x000029438c49198b}}, + {{0x00038be67e573e06,0x0008e084c44bfb28,0x000c1c2c505891db,0x00044b3131137396,0x0000aebfa4039584}, {0x000dce9e56e55c19,0x00029caa46d0ac9c,0x0001fe8eb7148ced,0x000f4c9e10c7efb6,0x0000fd835db8f97c}}, + {{0x0006f56c17706169,0x000d79da9a2d6c62,0x000730e455351909,0x000a79558e6825a3,0x0000d8c8bc093ef0}, {0x00078b6056becfd1,0x00039090b36d543f,0x0004432f933f1325,0x00050272ad499779,0x0000386493c5721f}}, + {{0x000eefa5abea82a6,0x000933fe62d43794,0x0001ef6068dc611b,0x000e6909f1af3728,0x0000af546c899839}, {0x00078c7c977ec238,0x000c3d5c05766255,0x000d1a4c0a8de294,0x0004d462ddaf0f7c,0x0000243fc70cf95f}}, + {{0x000f400b008733a5,0x000d012e1f57e566,0x000509cd0cba0697,0x000d8c4537c2b240,0x0000f989c69a7353}, {0x000c9724c3c2b2fb,0x00084f031fa87dbe,0x000d5d11f90e02fa,0x000dfc44d15c53cf,0x00003404faef8314}}, + {{0x000a109081e9387c,0x0006cc935828a36d,0x00040b015fb9780d,0x0006fa15940332e5,0x00009d7b51ca0f46}, {0x000cd41d6d9f6711,0x0008a1a2ac17faad,0x000201e5fba6c1e2,0x00062af66a7833ed,0x00009d9971a090f4}}, +}, +{/* digit=51 [{1,2,3,..,}]*([2^204]*G) */ + {{0x000f462060b5f619,0x0003ebd057c2f431,0x000e1bf65a56f46b,0x0001fea48dca6c47,0x0000a38783ed1bcf}, {0x00033a9da710718f,0x00063e0aeaf67a5d,0x00029d1875a77998,0x000732da87314d2d,0x0000a0edc3fb687d}}, + {{0x0004849cb198ac73,0x000cdf2646651c89,0x000200678a884a93,0x0004e5fda964ef9b,0x0000c351b8730983}, {0x000ef9fe2c4b44b8,0x0006b326790cafb2,0x00002264a580f6c4,0x0004e2384805210b,0x0000ba6f9e2c2a19}}, + {{0x0006ab65eb03c0ee,0x000392bc3fde499b,0x0003a80d2f19b795,0x00019ec86b5b9c6e,0x000043775094d428}, {0x0003650bb3ee8a3e,0x000bd132075fc166,0x000d834f675eb14f,0x000ffcc8ccc9067a,0x0000a6a2475c6e92}}, + {{0x00034abd3c095f18,0x000e64b76d7139d9,0x0003e698404b261b,0x000b109d2e6970e7,0x000079fb23bde5fc}, {0x0006c72dfd754907,0x0004f1bcf1c11150,0x0005e70073a97d08,0x0002a6d3201d82bf,0x0000f0ac52fe9823}}, + {{0x00020ee4b049136e,0x0001556a4613cb4d,0x000e081288b63bf1,0x000b153221aef670,0x000062d8c522acb6}, {0x0004a67379e7896c,0x00020afd7fa571f6,0x00041ba6ab25237a,0x000e7e3077bd9838,0x00004ac0244fcd16}}, + {{0x00001fb319d76820,0x00090a982feeb251,0x00061b344b029312,0x0001fa51c1c9b902,0x0000e008c5bbfd37}, {0x000dd1c0278ca331,0x0006d5aa53b1d866,0x00013a2cf666f76a,0x000836d5cfb77960,0x0000d3a1aadb3521}}, + {{0x00004ff50f75f9cd,0x0002ae752b223c56,0x0009a11181d8eddf,0x000d7a3ef074dd3c,0x00000ffc1739cb86}, {0x000ece3037d90f29,0x0005d055856cabd1,0x0004c6dafe3f307d,0x00099fb22f93287e,0x000002aac66c3487}}, + {{0x000131a567193ec5,0x000a95f6e70b76b4,0x0001eebddaf3c305,0x0008314587bd3903,0x0000709def8c1bbe}, {0x00099830eb2b6692,0x000b675b70295705,0x00064ac164d80ce1,0x0003ab638a7da803,0x0000f431d23de1c8}}, +}, +{/* digit=52 [{1,2,3,..,}]*([2^208]*G) */ + {{0x000bc15adf7cccff,0x0005efa1e1b075d9,0x0009bc17e81a3e5d,0x000d429c39e44424,0x000037dccb37ea7f}, {0x0004873907fba12d,0x00097a372904da65,0x00083a6c535daa6d,0x0005be3564cfc662,0x000009fa4f71a939}}, + {{0x0007080eb6b242d6,0x0002db71e246832d,0x00031139dd30bd02,0x000e531027991bbe,0x00008797e91a62e4}, {0x000e20a6b4e185ab,0x000d92d9b707423f,0x000f7811b82f2c67,0x00095c75c817684c,0x0000d53005eb45bb}}, + {{0x000a29e5cfe5c487,0x000e115ee096c51a,0x00049a68a82c020a,0x0003550848ad8275,0x0000933d489d0471}, {0x0008d2e67c51e574,0x000a99944afc0499,0x000fadac60f64020,0x00092c3a299fe1a7,0x00000c73ff49aefe}}, + {{0x00049be9d8e68fd9,0x00028b044320e5f6,0x000c33398db0f053,0x000fae66fde9b3e0,0x00002f4209bf6c8c}, {0x000afcc1a739d4b6,0x000f428ab8dee9d1,0x000c6f1d009aea75,0x000aa4b4375fb5ea,0x0000420b560d08f7}}, + {{0x000ffc75488771a4,0x00013f2f2191bf44,0x000f86a42cb76e3f,0x000d9a0197bde394,0x00005c25bb9b0641}, {0x0009e31f88ce6dce,0x000c6bb7ac7dd8a2,0x000670cc7be2becf,0x00043233094214b5,0x000090a8fd640af8}}, + {{0x000fd5696f37750f,0x0006a1507ff22d1a,0x0006543ed25dda55,0x0009103b95fd4c00,0x00003c778da923c3}, {0x000f4463b04938d5,0x00062eef947b84cc,0x000e325b53d9dded,0x00055d6ed83735da,0x0000ba0f75d49214}}, + {{0x0009b8b4ebd3f02d,0x000cb6b770ea0ecf,0x000a213cea47acd9,0x0008cec3b84a6a2d,0x0000760871c23e7c}, {0x00058e536e530d74,0x0004d912ad517a5f,0x000a0252a7abc52a,0x0007423ad43db02e,0x000098b00ed0176b}}, + {{0x000499c6254dc41f,0x00038a837e7e9eae,0x0000524a77e29392,0x0005f184aec08c09,0x000082b921a7d6f5}, {0x000962e1402cec5e,0x00071a2f30e7493c,0x000b879cb9f17ca1,0x00045edcd783e8e9,0x0000a3d8c153a6f1}}, +}, +{/* digit=53 [{1,2,3,..,}]*([2^212]*G) */ + {{0x00046e60ebcf7262,0x00014231470e103c,0x0007c21094482b83,0x0006ef4f6dfaca48,0x0000e0ace9782e66}, {0x000a9d31f8d1f420,0x0001574944d23246,0x0007f334b1b1e83f,0x000d8113dfa63aa5,0x0000cf8daed9f025}}, + {{0x0001f0d1e935abb5,0x0003c54de37a85de,0x0009cebb5defd10b,0x0004be68d9e39236,0x00004d5ef9bc6132}, {0x00041ba74f17e266,0x000818c1dde44d63,0x000d918fdc0a0e3c,0x000a1346d7758187,0x0000687601562ca3}}, + {{0x000180c207674f17,0x0006c3ae8fdbbc19,0x000aeb71e112e09a,0x0001c7296675546a,0x00009432af25101b}, {0x000558fde2ddec64,0x000f1357753fd5eb,0x000e1158a81392d1,0x00099167a76b973a,0x000016fbbff8a899}}, + {{0x00032c7904fc3fa4,0x000587e3636aee73,0x00091d9aa14a23f4,0x000540838659c3f0,0x0000a995e5df12d8}, {0x0003becf3a5598a7,0x000741eaa99520a5,0x00004e03c56534b1,0x0002682ed3dca4bf,0x000016c563b48d56}}, + {{0x0006e892f3b26e7d,0x00000a8752476d95,0x00082dda3f470986,0x0002ef6ad1517924,0x000064110e3d17d8}, {0x0008d2cfad414e41,0x00081ed02b241492,0x000821bf12b155f5,0x0005da381a141bcb,0x00002e3c7705f81f}}, + {{0x00044ea308780f21,0x00012845f5e4dd59,0x00024d7a3dc8de76,0x00011e5beaba7d76,0x0000e709afd404df}, {0x0004376021704560,0x000ac8f94b649536,0x00080ca68bf204b3,0x0005744e53af7c56,0x0000526074ae0c67}}, + {{0x000a63e7882f14f1,0x0004f7c6cadce29f,0x00082bed0c9f6dc3,0x00052c36f22d6fb8,0x0000a45755be118e}, {0x0007c277c4608cf7,0x0001e68012c29f2c,0x000729b0e7ccbdf3,0x000dbf8cb0aedd61,0x0000ca2ca9f67d75}}, + {{0x000dea7e0f222c2d,0x000ba2e651425043,0x00016cd30309d42a,0x000eebc4fe9ddd92,0x00006539c7ddf87f}, {0x000a57c432ac7d72,0x0000127fda1003c5,0x0000698de72692cf,0x0003b1cc28c85f28,0x0000331fb469ec28}}, +}, +{/* digit=54 [{1,2,3,..,}]*([2^216]*G) */ + {{0x0008eeae457a4773,0x000bbe6ddc05a015,0x000c41671d19857d,0x000d588326522418,0x0000ffdfc7e6c2c0}, {0x000525426ee7cda3,0x0009af02c3a83a3a,0x0003bbfc8341b086,0x0006917023bf4272,0x0000d15002a44452}}, + {{0x000324c85edfa308,0x000407d4f3da5ef7,0x000b50c862597655,0x00096bb52f5bc0dc,0x0000f6927b0c832a}, {0x000e1ba55f2f94c5,0x0008e44b45fad08e,0x000aa455d6a996f9,0x0001f79133cb8da8,0x0000d0721ecc58dc}}, + {{0x000e7e9262a35393,0x000d3670d59ef3ca,0x000c5e1b978a49d1,0x000c1c07de0f63c1,0x0000072c30c99cb7}, {0x0008a5277c850e61,0x000f0f6a3de61d27,0x0002ca7ad84f15f8,0x0004b836a8bb4559,0x0000912e3eef4d42}}, + {{0x000a92079e5fb67e,0x000a90aa725e6ba7,0x000f5d837e1331fe,0x000e207080ccf57d,0x00004cae01e5ff72}, {0x0003ee60412a77db,0x000c2f449025d924,0x000ef5a3106ff7ca,0x0007a80e75f7cd23,0x0000c957822bddef}}, + {{0x0008086365e668b9,0x000a1abda5fbdc98,0x0005f1fbeada8dcd,0x000fc32c146b4c25,0x0000cfcde2a5f34c}, {0x000453e7e85d1e48,0x0009792358b5acbb,0x0000823ff9ca0967,0x00011d95fc2d9624,0x0000d65adf78c11d}}, + {{0x000230cb0ce1c552,0x0004ebbfb6078cf7,0x00016363b5b534d0,0x000e82ce1ef1130e,0x00007e0aa7ad4999}, {0x000ac2d79362c410,0x000091bb6cb0ce1d,0x00023df2467920c9,0x000f281e648d6322,0x0000f7d9eefe32e8}}, + {{0x00057f10296f4fd3,0x0003ba51b4367755,0x0009508051dca76a,0x0007f1c3e98f60fb,0x00001ff32eab31cf}, {0x0007bf18d2c714bf,0x00083e9d2aca643e,0x000dc2d2364b5c33,0x000b9ab9fd9ccc6a,0x0000c2397edbc721}}, + {{0x000f39afa8338349,0x0002163285626943,0x00070fc102295172,0x000e6cf1d63dd541,0x0000f5fa5903ecc2}, {0x0008725e77d9a3b0,0x000a6384ebe0b66c,0x00045e24a11235ce,0x0003b106a8c11858,0x0000137b286ebd09}}, +}, +{/* digit=55 [{1,2,3,..,}]*([2^220]*G) */ + {{0x0007d6ac42bd6d29,0x00082b1f96aedb56,0x00043b28e6df8646,0x00023f7efe5b1a48,0x000061bbb05f379b}, {0x000f5f070a6a26b8,0x000cb28e6e39b6ca,0x0005fc8d370686c0,0x000dc900da06cf89,0x000004d88113363f}}, + {{0x0009ce74462007dd,0x00047cb5f5b763b9,0x0005edde7b8ab48a,0x000fd9cec673d2f5,0x00001567f755cfae}, {0x0001b6b0887bcec5,0x000e9178f3c24638,0x0006266cb694497c,0x0004130e6525e31e,0x0000931de26b97d6}}, + {{0x0009da11f17a34c7,0x0008b35a145614e4,0x00050363b5420ab3,0x000b6e476372412f,0x0000b15d62433fab}, {0x00040b1e274e49c4,0x000456b1860aa0ef,0x000afe5a45cf5074,0x000e9a96583fbf66,0x00004240511347e3}}, + {{0x00055021a93507a4,0x00074d3c06cf142b,0x000ec3f40b4cd118,0x0003c29f70e76a91,0x000084e81ad8e755}, {0x00087b5272e9d6ec,0x000506ff514a830f,0x000192a8eea1c93e,0x000359a7cc2adcc4,0x000077e27e302f45}}, + {{0x0008b1e48ac28403,0x0004bcba9477b535,0x000946b431831129,0x000819aa58f990a6,0x0000098baf9cab41}, {0x000c1584198da522,0x000bf46bfd1b66c4,0x00036a908ab4fc17,0x0008380f0a4c3cbf,0x0000ae9e34b78cf7}}, + {{0x00040ec0ccced589,0x000b7da44f9845eb,0x0001812c625cd4b9,0x000650b3e0645887,0x00009f80d55a6cef}, {0x00040c9ce6dc1532,0x0007b86655215713,0x00007014d138d511,0x000b918cdb45bc4e,0x0000f34bb38a4b60}}, + {{0x00099e84a34f239b,0x000c090402d54174,0x0003aa83215fdb83,0x000db1075f46bf43,0x000061e15b013215}, {0x00059d4a127f89a5,0x000bb7e816daaabe,0x00018b6925d541e0,0x0000265aba0659a6,0x0000532773367266}}, + {{0x0009cf2d0c051995,0x0002aae784548cda,0x00072a182502fbc2,0x00037270bda9dff5,0x0000f9b71b8b158b}, {0x0003a592b82dd077,0x00052523032ee0f3,0x000505a327630273,0x00009f0fe1a721c4,0x0000b6e3e8367964}}, +}, +{/* digit=56 [{1,2,3,..,}]*([2^224]*G) */ + {{0x0007bc035d0b34a2,0x000b6327c0a7e341,0x0000362d1440b386,0x0009436fb7262dac,0x0000c41114d00cdf}, {0x000cef1ad95a0b12,0x000847d543622ba5,0x000e486c9c09b37a,0x00029706d6cdd201,0x00000477abf62ff9}}, + {{0x000dcb3292a92874,0x000637b092c7a004,0x0006c0605ddc15cf,0x0007afc83a846480,0x0000a68df707db99}, {0x0004e4505bf7dd0a,0x0008eccf7f8c9c13,0x000b5f8afa4e63d3,0x0001cc06e6517f41,0x0000a8b93434d7bc}}, + {{0x00035b51e706ad97,0x000453a9ebdf126f,0x000608d90b99cebb,0x000858375389afbf,0x00006113c5036c89}, {0x0008eb097e2b5aa3,0x000c33b9130480de,0x000cc066c7e1022c,0x0009000bdab6056c,0x00003cbb144e2edf}}, + {{0x00064717af715d2e,0x0003f0134a96c417,0x0001ec956e2f7f59,0x0003034c1873efa4,0x00004e7b4f757821}, {0x000ff9788d5374a6,0x000320823d5be5c8,0x000ee8fe22b915e6,0x0006518a6bc755b2,0x0000657624d47112}}, + {{0x000f101dace5aca9,0x000181a6a267157a,0x0009c8609c4fdbcf,0x000a654addf340c4,0x00007e49f5379604}, {0x000e790937e2ad5c,0x0007726e17f19be8,0x000bbc0dc846e250,0x0006d57f38007a0b,0x0000f036040711e1}}, + {{0x00000e07442f1d58,0x0000e6e0e3abd6f8,0x000c64047475607d,0x00083d02807f16b7,0x0000858e1e427498}, {0x000120b8231ee10a,0x000ac38a1ece5859,0x000aa73a41b80e7e,0x0003ac2b72525ac6,0x00007cdea3e24442}}, + {{0x000c007f8ae7c38d,0x000b6d7401925ed0,0x000e36db36db07a5,0x000045ee5e9c2a5f,0x00005b9d57b46e95}, {0x00032e78eba20f2f,0x000e81b9a35254ac,0x00098a658ef11ca8,0x000666405e373eff,0x0000fe5a101723eb}}, + {{0x0007b11e51732d26,0x0007c538fc0e5747,0x00039eec5dfd6eb2,0x000c56fc43b0cc3b,0x0000af127792b36c}, {0x000852d06c425aef,0x000b6c221b9b70b0,0x000826d9c6df92f8,0x0009c27c8d4f9ece,0x000059aba7ca4935}}, +}, +{/* digit=57 [{1,2,3,..,}]*([2^228]*G) */ + {{0x0002c2e421d3aa42,0x000cc84fa840c37e,0x00054e41cf926407,0x000643f8abc03d14,0x00006605ecd5f7af}, {0x00041a6d6a5eabf5,0x0003d16b668e2423,0x0000101021edb84f,0x000d8c8836edb804,0x0000b337ce7e45e1}}, + {{0x0006b86d23ddc820,0x000c7e0143f04c07,0x0007af2c503fd344,0x000a4fa95362ff31,0x0000add3db7e18b7}, {0x0003e3f8260e01bc,0x000494a1cc919c67,0x000f2e433fbeb49e,0x0001ead1351bf292,0x0000755e7ed45114}}, + {{0x000e368da9f3804c,0x000de164349c349a,0x00062baa5470f07f,0x000df3152f4cc985,0x000074a9e86eb290}, {0x000aa3543471a24c,0x000df8194511d3a1,0x000dcd44d239446b,0x00082cfec2dd0081,0x0000a3d7f10842ac}}, + {{0x000db47f23206d55,0x000fcd2601522bf5,0x0008ff89a2f6d341,0x000457c7b876533f,0x0000157c30c878fa}, {0x000c5c52d4fb936f,0x000bf6518cdc7517,0x000847a64ef22f7a,0x000a88eeb483e6bf,0x0000508455982e0f}}, + {{0x000c2a69b583160e,0x0003d4e59194b418,0x00083e3ffbe74fcd,0x00029b1178eeaa3c,0x0000051f896c296f}, {0x000523806ceb84af,0x000df111fe6bd023,0x0000455455ace48c,0x00014550e43a491c,0x00003fa86decd522}}, + {{0x00016fa908ec5b55,0x000d501ab12d9596,0x00082ae8a882d661,0x000f5e749f608243,0x0000cdf92ebad133}, {0x000cc425ef6c9c1e,0x0001864d84ee98ce,0x00025b8c4b52d668,0x000e87be285ed86f,0x0000b80cdc828deb}}, + {{0x00094c1ec222ba0e,0x000e723e5d482d97,0x000e4846bc3dff42,0x0001736a7cd5700f,0x0000fc5b114df135}, {0x000b25bc6b05e85d,0x0008954cd0772630,0x000d8b89d0a6d302,0x000c26e4f1f54f32,0x0000e3baff2e627f}}, + {{0x00059d8df7304d44,0x000bbf210e8eab96,0x0003fbd60b71bcf1,0x0004de69a2438bd7,0x0000595cd1f9d11b}, {0x000329a4835859dc,0x000cbdbb6e569c0d,0x000928a4e4a0f0d2,0x00015406038e5edf,0x000094296224f5ad}}, +}, +{/* digit=58 [{1,2,3,..,}]*([2^232]*G) */ + {{0x0003462f23f2d925,0x000d10b940789121,0x0006cde206cab71b,0x0004bc1bdd0a6317,0x00004c9b20d3e4d5}, {0x000d8aa9f2ac02f8,0x0006a06eedb03cd2,0x00008643403f8e61,0x000db947f68e1693,0x000031469c612dd3}}, + {{0x000a1583ae9c1bde,0x0008037ce2407aa7,0x000ab38b4e0af6d9,0x0008ca054342d928,0x00008b75007ea1c9}, {0x00086afe02358f2b,0x00063a921228efce,0x0001c67fc31b8b85,0x000d58552a19120a,0x00004069ea593aea}}, + {{0x00090cde36d07576,0x000179a293824a90,0x000b48ddff722d7b,0x000f439b7fb04c04,0x000028ad2a84be16}, {0x000bfb520226040e,0x00007104b6c4cd3f,0x00003c1886c34ecb,0x000aaf50c0754ec9,0x0000c336b090d23c}}, + {{0x000439e558df0194,0x000a6c712b279f51,0x000185a24230da4b,0x000f50118919e355,0x0000dcefcddc4b78}, {0x0000fb2a47d4c5ab,0x000f030e009ea7d9,0x000eed27355ac9ab,0x000faf4d2fc35974,0x000072d824d8bea8}}, + {{0x000f923cbb13d1b0,0x00025bfb9bfed213,0x0001144a998799f4,0x0005ee1ae8ddc970,0x0000b8b3bb64c559}, {0x000ef2e3ecebb211,0x000b2671f9a70ea9,0x0006f1d1f17cb6c4,0x00027637ef464f72,0x000071b94847943a}}, + {{0x0008552de7e5c194,0x000981c0256c779b,0x000d4743dfab2860,0x00093b24f58eeeab,0x0000e8ef838bb6cc}, {0x0000d264cb1bf3d1,0x000963dedf61ee65,0x000b70ced4c1f9d0,0x000e1e9ef7c9d7bf,0x0000ec0507e2641d}}, + {{0x0001109a607419d5,0x00026b6bca80c994,0x000c431f3faa71e6,0x000479e4158c1307,0x000094abebce92bc}, {0x000a691eb78399f1,0x00052f42cba46dfe,0x0007c04f048aafb3,0x00091addcd65af07,0x0000a29a366f8844}}, + {{0x000b2b5ef7d92893,0x0007e97f015a549d,0x0000493b62480d4a,0x00033131d5590bc4,0x0000a55b52e9f780}, {0x0008115309eadb09,0x000a02e5c62540eb,0x0006a3d5adea7de5,0x000d60d4d631f0cc,0x0000d5e9d7d23e8d}}, +}, +{/* digit=59 [{1,2,3,..,}]*([2^236]*G) */ + {{0x00060411e84e0e5b,0x0002fea34c931968,0x00073a732a5db84d,0x0007c049d5bb1970,0x00008d2fe571bcfd}, {0x0005f36f3eb82fab,0x000c4dff8b584577,0x00074c1108cb20cc,0x0008996659b65f83,0x00008b4a422e30c7}}, + {{0x000cda3af2ebc2fd,0x000cfb4efe24c4f4,0x000cd10b1a0af843,0x000e0383b857c19c,0x0000dc9d1ec614d3}, {0x000c8bb62771deb1,0x000a81c5aa817bde,0x0002391ae829277a,0x0004ca6af18dd683,0x0000740f316d71a8}}, + {{0x0000910cab91f1eb,0x00039d1cd2162d50,0x000d02252bedd9e4,0x00017a2634b74fed,0x0000d60f8e1c2586}, {0x000537b9e05614a8,0x000667af5fc5d8c7,0x0002bd926fd26c76,0x000fc78660b58158,0x000070192452cf07}}, + {{0x000e99aeeaf8c495,0x000d1e24d7288928,0x0002b156cee7aa73,0x000a1cfc5007c2e7,0x0000fcf57c63d408}, {0x0009e39b6057604e,0x0000e2868bbf9f71,0x000103e2d7d343c0,0x000ea14cca254b7e,0x00006eb38aad131b}}, + {{0x000e3520a981b0d0,0x0003bd1a41a40ba4,0x0009fab9c1c354cb,0x0008d51aabaa3adf,0x0000701a7d153c41}, {0x0007cefdcf2b9218,0x00033cf48061dd1a,0x00025cce66ceef0b,0x000e339083b598de,0x000090a54c8690a5}}, + {{0x00018db4f6d01b11,0x00027f11e8a04057,0x000591a3be73c6bc,0x0005319c11bb8ca0,0x00002d09a5a1acc4}, {0x00074eee7de13f4c,0x0005444fd682cbf1,0x00048af70177e2be,0x000b7ba5f574cb1c,0x0000e5966935961c}}, + {{0x000ed6c048752a14,0x000e601341b4c59e,0x000c6b09241f2702,0x000b232e35903b9d,0x0000291aba85f5b5}, {0x000aa70a653d61da,0x0003af2eb51e8173,0x000b93f8fd1b648d,0x0004fd91b7ce065a,0x000055408ef39e2f}}, + {{0x000624f8be762b49,0x0000758e3413b33e,0x000d805fa2a9ee4d,0x000fd7068e636967,0x0000848949c0db8b}, {0x000d7e5d23a84178,0x000d73e29da55308,0x000ee471f892f3b1,0x000089495c139e3d,0x0000631594e5757e}}, +}, +{/* digit=60 [{1,2,3,..,}]*([2^240]*G) */ + {{0x000e2ea1f095615b,0x000664e68c331083,0x0008818be0a28ad7,0x0000ccbbfc02523d,0x0000585113ba3585}, {0x0005f0b30df8aa1c,0x000b8ab7e3ac7d93,0x0002f00cbaddda07,0x000f6bd2c3429955,0x000033ed1dee909d}}, + {{0x0000d483e07113c9,0x0008ed8b63ae2dc4,0x000684c2b6e4a5d3,0x00026bc582a94b79,0x000032b33d4f22da}, {0x000f6510dbbf08dd,0x000894c23a52f534,0x0005bdc9b211d07c,0x0005573eeece0fee,0x0000f178169c7015}}, + {{0x000905a83cdd60ed,0x0004d1170184abe7,0x00023642a50602fb,0x000aff989886cdb0,0x0000568d09176e1f}, {0x00022c70259217fd,0x0008f43141e45b19,0x00095f86e93831cd,0x0008280fca35870c,0x0000ec2057b268ae}}, + {{0x0008925913cc16df,0x000cf1a26f5a568f,0x000f499ae18bc5b6,0x000e83efa413bef5,0x00008835dedb3f0a}, {0x0000bd865a40ab05,0x0008c94b377eb6e6,0x000084a696559643,0x000de06cd8562592,0x0000ce433b99f23e}}, + {{0x000523d42e06189e,0x00006e3aff13860d,0x000b20650bf07794,0x00000c2b616dcac1,0x000066dd6d201313}, {0x000fd67ff99abde3,0x000097aac50dd4a0,0x00046b2d7c990355,0x0002aed22ecf8b7c,0x0000333b1e86abf9}}, + {{0x00065e784d6365d8,0x000f0f759fb8c0da,0x000e81930bcb7443,0x0008aab5c712b17a,0x00000428dffcc6e0}, {0x000afefa4faf8433,0x000dcfa9855ff19d,0x0003ac7ceced8538,0x00071df0ac409cbe,0x000058c1fb6b82da}}, + {{0x000def7be42a5821,0x000055046be6efec,0x000e8dba9d3fc608,0x0001ffb9af13c809,0x0000e6c984774149}, {0x0004925d30c31f70,0x000aac2a21223b57,0x0000859e7b7eb72b,0x000942776a0dacef,0x00006fec31421900}}, + {{0x00094b07e50122b3,0x000b1af07ca53247,0x0003fc97bdd744f8,0x000d9d00a12f08d6,0x00009650f1aa6626}, {0x00047f71fa38477c,0x000914dc124f101b,0x0006eb58a3d815f1,0x0008865569ae95b2,0x00003cde18955fb1}}, +}, +{/* digit=61 [{1,2,3,..,}]*([2^244]*G) */ + {{0x0007a952f41deff1,0x000ad63b89b702b3,0x0003ff9510e44a59,0x000af4573257dc14,0x00009c02205e752b}, {0x0003069c4b7d692e,0x00031d1502ac46c2,0x0002208462e6392c,0x000b628057b1a21b,0x000051ff946ec1b5}}, + {{0x000cb51566c5c43e,0x00085597f0466e85,0x00094d94acff9c91,0x00027cb354e90c49,0x00000a3933301479}, {0x000fac10dc1eb2bf,0x00013ff319fa8427,0x00096527488cfd8c,0x000745f2d4e68401,0x0000a2e067e57aaa}}, + {{0x000857c5b0f7bd45,0x0008c08ea1cdb9dc,0x00084c7a96990c2c,0x000a7834730b83b9,0x000052723d33ab18}, {0x000c2e2919ba0f93,0x00091bf408909752,0x000d98212075a3bd,0x0004c841e52a04a6,0x0000fb6607acf18a}}, + {{0x0002a7f3e5f9f11f,0x0009e6cb3b8eb6d9,0x000f800bd9afe153,0x000e185d1a6dd7dd,0x00006c13cc1baf17}, {0x000c58e325fc3ee3,0x0000731dc3b215f6,0x000a3d3e77109540,0x000e2ce68e7c07af,0x0000f8417a1c4c7a}}, + {{0x00075216ce400bb1,0x0007baf07d99f47b,0x000ce62e0f72919f,0x00000e85b86e0600,0x00001872baf9fcfd}, {0x00021eb211f7dc69,0x0005c4ebd6f6049b,0x0002d78dab8900e5,0x000d9fec38cea416,0x0000a586c9e9bfa3}}, + {{0x0004772813b230d7,0x000ea7344427ec23,0x0007fc56a634d0f5,0x000f76a1548ab1d7,0x0000fab17513e06a}, {0x00010a74f7c4f830,0x0004220a67d9b62c,0x0001209a0a7d2edc,0x0009f01c40417092,0x0000b9815a0face5}}, + {{0x00083e151c3ebe53,0x0007a25d7be8ad38,0x0008ea8c9db14d5c,0x0006aaf3e4491155,0x0000a68529f6f45c}, {0x000a1dc149f75b88,0x0000879c7cb2eb18,0x00057a94e9b8946a,0x000859a7ad2a1911,0x00004b14f469106f}}, + {{0x000589b319540c33,0x00097283d6f82842,0x000ae9fcb18490f5,0x000ba072731f84da,0x0000db6d960f3683}, {0x00063bb146110697,0x000e9788bf05c85c,0x0007460d2b19436a,0x000db1205459df34,0x00003f6e095511a7}}, +}, +{/* digit=62 [{1,2,3,..,}]*([2^248]*G) */ + {{0x000a3c8ee3c76cb3,0x0003a32a1f6ef306,0x00063e9563cf1162,0x000c26b6d5ab6468,0x0000b8a4cbe8c005}, {0x00029a59ce6bb278,0x000184d4b16fdcd5,0x00023798dc4afaa5,0x000fab30624a2679,0x00005e56df6eb307}}, + {{0x0000fef4e4ca4631,0x00072566cc63b233,0x000780900bcef728,0x00027dc161d2cacf,0x000035dc5396b548}, {0x000052e27bf1bc68,0x000f87dfa06c638f,0x0003321da10a224e,0x000c8f6973586d6d,0x0000b0c5738a6152}}, + {{0x00095959884aaf7a,0x000267b348a68968,0x000147c87b1959be,0x0001f7f6250e573c,0x0000e0efb3b7d0c6}, {0x000745eca8c325e7,0x00067cff3f70ed00,0x0009ad41d3c91169,0x0007ef03acbc6531,0x0000b01a02160b1c}}, + {{0x000ba6b23a5d8961,0x00056fe4364e9910,0x00033c6771fe19e3,0x000fd05e1da8c39a,0x00005b4488b39fd9}, {0x00092541a1f22bff,0x000fbb8163e81f43,0x000e5658e920a8a6,0x00039a4fd1b24907,0x00002c4f79da6ec8}}, + {{0x00043b5224c08dca,0x0003e1b50c912621,0x000a8c84f2bbb09b,0x000ca8216ed709ac,0x00006210d9e52850}, {0x000f67a09cb54d69,0x000fc00919a46d8d,0x00013285791eef6d,0x00028b00f613810f,0x0000acede4888d50}}, + {{0x000a0691416a6a5e,0x000863ef881c84ce,0x000038a5d8f860c7,0x00006661311f8a38,0x000078c2ec1dc612}, {0x0002e815ad735813,0x000029604097494d,0x000612cbab4cc9e0,0x00039ecf558aecf3,0x00005beef7ace36c}}, + {{0x0001446de6736294,0x000e303c2d2145e2,0x000c868c757f7aa1,0x00067660e99b7f98,0x0000e42f66dcb641}, {0x00084dc910778965,0x000f72c9885b6028,0x0009a5187a0d690c,0x0007eeaeb4da333b,0x0000f789598653c8}}, + {{0x000619c76497ee80,0x0006c717370e8b5c,0x000cf68e15d2b0ac,0x00079298204cb64f,0x0000bdec21162bc6}, {0x000ccefa63b10110,0x0007e0de1ac56973,0x0000e0c8bf9e3fa9,0x000cb45efb693e3d,0x000037248e9d2d4f}}, +}, +{/* digit=63 [{1,2,3,..,}]*([2^252]*G) */ + {{0x0002dc91ec34f9e7,0x0004c38106038080,0x0000cb4f3d8772d3,0x000128cf06d66c53,0x0000be5ed0e3475c}, {0x0003c1931e82b100,0x0007c9ff6b4ccb9e,0x000a1b45ec63d285,0x000bcab92118c692,0x0000aec44147285b}}, + {{0x0009ae71e29a3efb,0x000f9c93302efc18,0x000aae10ecbe906e,0x0009f820107914ce,0x00007a23f35668e1}, {0x00075c2efd2119d3,0x000eccadc9c8e9d8,0x000a1711303198c6,0x00003835591bf64d,0x0000cf0bbf86d443}}, + {{0x0005bb72b7247593,0x000182d4c63aae48,0x0007d6f2c945353e,0x00010952159d07de,0x000089caef37ec5b}, {0x000bb53db65ef147,0x000e6d99de434a8e,0x000f2405f2dc2cb7,0x0008a3116fa3ed83,0x00003429bba31420}}, + {{0x000d590b01e6e274,0x000da180b2dcb618,0x000aea4a9047e2cc,0x0003a491b299b504,0x000012c9e1edfa40}, {0x0008a36794075521,0x0006e332b8e388d2,0x00068de1949c5013,0x000b972a1b6fcce6,0x000078851bc85122}}, + {{0x0003752fb85fa4ca,0x000d983c8ce9b1e1,0x000f74daed61257c,0x000bbb343da670d2,0x000035aa2405f846}, {0x000235d4421fc835,0x00007363473b5e74,0x0004aa158f6df8ee,0x00022de4d7f52a3c,0x00000d05aabebc6d}}, + {{0x000e735a64785f45,0x000b0f29cd078c56,0x000e35067bc56637,0x00027003b2bb803e,0x00000235a102c919}, {0x000b6d8f2c4aa658,0x00010396023b191a,0x000f805bac347583,0x00080f00400ba5f0,0x0000881065bdec0f}}, + {{0x000e522cc1b5e838,0x0001060b8bfbc370,0x000b256dfde2d4ad,0x0009972d364df067,0x0000f12502f60138}, {0x000a0dc7783920a0,0x000dc0bc866a503f,0x000064ba6e80014a,0x000ba53f89b744d3,0x00003511dcdcba5d}}, + {{0x000d46d95a7b1a29,0x0005ac6341fb197d,0x0004c2ece9c4e7ad,0x000f89b26eca2948,0x0000211e48a6e7f4}, {0x0007f6ec78ef1f42,0x000fe65745861499,0x0003eede82b2c090,0x000017f7286a6e1c,0x00005f92e472f60e}}, +}, +{/* digit=64 [{1,2,3,..,}]*([2^256]*G) */ + {{0x00070af3aeac968f,0x0008d4b63266b4e3,0x000ac5664e4f7fee,0x000cbec4acd4c2e3,0x00008910bd3beb38}, {0x000e50cc9c0726e3,0x0009a97b40bf1c3a,0x0005a5a1b1530956,0x0004cd40884b7ffd,0x0000890896b1f831}}, + {{0x0003c9f82e4c6346,0x0003da4464f85ced,0x0001dca258efb831,0x00012b8706381b7a,0x0000cd15a3cba2a4}, {0x000a8fdbfcd8fb51,0x000f5e54cd229347,0x000d8932f31db2ee,0x0001afb4aeb11ef8,0x00001e7c1ed44441}}, + {{0x00084f5903fa2711,0x0002a9da921e9968,0x000b01e54e6da0fd,0x00014e96f2f2695d,0x0000ee3e9bd78762}, {0x000181ce27a94979,0x0003fe215e04a26e,0x0002cabca36d254e,0x000613b2f32a6c25,0x0000948148810b57}}, + {{0x000b43a43228d831,0x00003ad63f99ab41,0x000a5122924ae1c3,0x0002b47e525f1a46,0x00004af860fdd26d}, {0x000ef613f714aa18,0x000d6b78795ed6ba,0x000a9d694f51865a,0x00052753e21fcee6,0x00002ceb1de0a37b}}, + {{0x0005bfd2f9fd51a3,0x0002181b97f74a66,0x00036ce507f2f1fe,0x000ded9ad05d69ad,0x000014fc2a4b44f4}, {0x0003d8cb55fc5c6d,0x0007efb1e23dd559,0x000453ccee3510ce,0x00063129b7be6937,0x00003541b7a39fae}}, + {{0x0006525eca445df4,0x0001ecdfa4c69929,0x000a6d3bcf1af24f,0x000cc7b5b4eb61eb,0x0000560910cd8972}, {0x0001c32093eaa327,0x00090d3c67bb5475,0x0008711100183134,0x000a7dcbd90ce62d,0x00005fc863ac38ba}}, + {{0x0008a4176a9f05d0,0x000b9011d488711b,0x00048a65e06ca4e4,0x000894543bc62ba2,0x000017535ffc9290}, {0x00084ce406851d75,0x000f40e960b4840b,0x00028fd34afa3acd,0x00092c5c3394af71,0x00004eb4d5b7ac0f}}, + {{0x000e87355dbd4b3d,0x00079639bbb1db09,0x0006519621f87992,0x000573e83e47e51c,0x00004ef0fb7943fb}, {0x000b9d8f1bfb12a4,0x00082e5e8b7227d3,0x0007b90146ab877e,0x000b644eebdc9d15,0x0000c2110057aa5c}}, +} +}; + +#endif /* IFMA_ECPRECOMP4_P256_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p384.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p384.h new file mode 100644 index 000000000..e79cf27b5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p384.h @@ -0,0 +1,1002 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPRECOMP4_P384_H +#define IFMA_ECPRECOMP4_P384_H + +#include + +#define MUL_BASEPOINT_WIN_SIZE (4) + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE +#define BP_N_SLOTS NUMBER_OF_DIGITS(P384_BITSIZE+1,BP_WIN_SIZE) +#define BP_N_ENTRY (1<<(BP_WIN_SIZE-1)) + +__ALIGN64 static SINGLE_P384_POINT_AFFINE ifma_ec_nistp384_bp_precomp[][BP_N_ENTRY] = { +{/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x000607664d3aadc2,0x000fa3dd07565fc8,0x000e1e26a4ee117b,0x0003afc541b4d6e6,0x000459a30eff879c,0x0004ede2b6454868,0x000513812ff72361,0x00000000000299e1}, {0x000af93c2b78abc2,0x0006e23043dad1f8,0x000d385481a72d55,0x000e7562e83b050c,0x000968f4ffd98bad,0x00069a840c6c3521,0x0005e9dd80022639,0x000000000005a15c}}, + {{0x000a271bdb93b776,0x00066c8229e549ca,0x000a0046a4ddbf0b,0x000e6f0ff9d48a26,0x0005f0687f503504,0x000e4b506da82149,0x0000c39c90a4fd2d,0x0000000000042746}, {0x000777e3e34947f7,0x000cf42ea84624df,0x000c322ca0a5f414,0x000f18bdc588259c,0x00015172bad915e4,0x000b0e68409f1fe4,0x0000c2070d430900,0x00000000000123df}}, + {{0x0008420bd283fe68,0x0000405e4dbe5ef5,0x0007d2a868c2d376,0x00034e9a170ccf19,0x0002d51c6c3e6b20,0x0003aa4703a48d73,0x0003ace36f7e2d26,0x00000000000e7c1c}, {0x000a7b5b465465fc,0x000697e28482179f,0x00092befa3c13549,0x00063c04ef67446d,0x000ad2e1d0b41326,0x00002b33968012d5,0x0002aff6db68b151,0x0000000000098329}}, + {{0x0007a84fcfeee6dd,0x000c00aae84771bc,0x00004833a9bdf308,0x000153b0aecac470,0x0004736400ad2e4f,0x00085d979078358d,0x000228fb40f647d6,0x0000000000034179}, {0x00059b3d50946875,0x000f354f3e8e74aa,0x0007e02066cc9331,0x00061a34c542ad23,0x00030418c6938e3e,0x00020017d147162d,0x000319e607b9e338,0x00000000000303df}}, + {{0x0006ca2ee1bb26b1,0x00017bb595eb9873,0x000340e77dae425b,0x000b1b5293c703ca,0x0005aacc05e67f1e,0x000e8e4c660db2cf,0x000ffbc676b987e2,0x000000000001d178}, {0x0002304b4db1c9d6,0x0003c2b694ba022c,0x0000733804c0a50f,0x0001b3101c35b997,0x000f982c041180b6,0x000de236d4b237fa,0x0004a3e6c5944024,0x00000000000e209e}}, + {{0x0003f94fc482e189,0x000c37eb5c930b8d,0x000fa7363cfe5622,0x000930f580d57f38,0x00061bdf6015ec52,0x00002d33b2a33f66,0x000c404f0f6a962b,0x00000000000f0430}, {0x000a60b1c9962152,0x000203f62b16dde1,0x000d30e7f024d36f,0x000bffcb79e33b13,0x00061b546f058bd4,0x00021559a93c9e5f,0x000eba586d8ededf,0x00000000000af2a9}}, + {{0x000c82aa932c9f81,0x00032df13b9d0ea3,0x000012e0e11a7414,0x000dcf8211faa95e,0x0001659753ed731e,0x000b2df555f4215d,0x00025bf893db589d,0x000000000001c890}, {0x000c8f68d90a16b6,0x0002f0996b21f9df,0x000c5d608c816e33,0x000d76f50130844e,0x000401fff78065aa,0x0003b07060ff37c0,0x000b3ef57f238e69,0x00000000000af6c9}}, + {{0x0006da365db4f184,0x000fe23f60a057fe,0x000be85f6a0c5049,0x0002e7193d7e30ff,0x00064f3ddb371c5c,0x000b664231d9aebd,0x0009b11c7b5fe116,0x00000000000349cd}, {0x0008ec6d3c0c6dd7,0x0005e0d2cfe83aa5,0x000f7a290df3f1cc,0x00054bf7d8686e4b,0x0003a42dbba27017,0x0008ecf0ee992326,0x000f617008d943c4,0x000000000000d27e}}, +}, +{/* digit=1 [{1,2,3,..,}]*([2^4]*G) */ + {{0x000b56e7a10896aa,0x00082da6e8a7edb2,0x000a339205afd669,0x00065517917652b3,0x000a2887d5ff37cf,0x000bdc3fa317b63e,0x000aa137065f5313,0x00000000000435ab}, {0x000e15a5659db481,0x0008e9b21615f8a0,0x0000a5926b88aaa4,0x00071dc154d41105,0x000bc88ee1489148,0x0002d1967b333bdf,0x00051351c305c6a7,0x0000000000081ef2}}, + {{0x0007c0045dd2a4a0,0x00075ad852b872e3,0x000b4af19266ca1e,0x000b9fcc651b1dd6,0x000612e8dc871896,0x00031cfb0ba8953d,0x000d793a9865baa6,0x00000000000626b3}, {0x000b7328c510ad93,0x000901148bc71a36,0x0008838d56b7b5d9,0x0005f9e9448fd096,0x00000a2377b67731,0x0005b4ff04bcb06f,0x00099f73b42725b3,0x00000000000aabca}}, + {{0x00077d8466e4794b,0x000763ccf806a4c7,0x00041b06944ed785,0x0004e06ea52bef99,0x00053a7d2f3c4f50,0x0003a1bc940d01ff,0x00040062e5c5d3e7,0x00000000000ae7d7}, {0x0000b071271e42a1,0x000923d30625e38e,0x000c9ea33ece8520,0x000a10d04bab9856,0x00009da2a2ca5c3c,0x000c9462c2605ca0,0x00058348eab00eb5,0x000000000002624a}}, + {{0x000c57a24f5d5ab6,0x000eded4de4f83f2,0x0004d9f2c578d7f4,0x0003d30f8a0580de,0x000dca57b7bde04b,0x000e44d56a309199,0x000e5cfc8e87cf3b,0x00000000000d1b30}, {0x000dc1d0888b708b,0x0008cb213c69fa81,0x00085d35b9791d2c,0x000bbbf1090fede9,0x000c301fe259fe51,0x000cd3fe86d97cab,0x000a513ee127895e,0x000000000009404c}}, + {{0x0004d8911e8568cc,0x000c5194924b48e8,0x00026b2f852cc83a,0x0006428b12136094,0x000351fea1dc4906,0x00015ace6dd2ec6d,0x00024620fe8c27a7,0x00000000000a4463}, {0x0003c328530abb42,0x000b900c213bba9c,0x000bf43a5f2c2e1e,0x000903c6484641de,0x000a1378e68fbc7a,0x000cd8ae42413063,0x0006f9b960b5efee,0x000000000000614a}}, + {{0x0001dedb8bf3dccc,0x000a0dc529384912,0x000bc9fafda07c1d,0x000597e52ce08f71,0x000581998af2ee21,0x00041eb4226de4c6,0x000b96cb4aa43c97,0x0000000000039c18}, {0x000a9ce2b257fb6c,0x000a566e1d5da261,0x0002d61f72303077,0x000396f305ee4f10,0x0000c831254b8545,0x0005680b8f9d19ea,0x0004a4cee0842f5d,0x000000000005a443}}, + {{0x00007168b4a67147,0x000a12e206547853,0x0001c6a852120cb6,0x00009d5504c8129c,0x000c9710b70b2b56,0x000296a52fb25e37,0x000dce83f2fd2cd8,0x0000000000062f45}, {0x0000b128f82bb944,0x000a8a818b9bda93,0x000ed2d611039805,0x000e43a2ec76a180,0x0007caa846883e7e,0x000182141473e687,0x00004db9a19eb57c,0x0000000000045ed2}}, + {{0x0001e64ba6661cc4,0x000cee484fd9edbf,0x0005b5c2b4988114,0x000449e7c1c3984b,0x000118eb5195c0dd,0x0007a16d2f313389,0x00020a0336aab877,0x00000000000c2417}, {0x0001e21e239dcab2,0x00034678db970845,0x000627331787ffae,0x000a0e4a022c7a44,0x000434a02a6b5d85,0x000791ce3b01f1e0,0x000c5b2657eedda5,0x00000000000a277a}}, +}, +{/* digit=2 [{1,2,3,..,}]*([2^8]*G) */ + {{0x000fa21fa335ab82,0x000a49a7a5b41c7a,0x000300862e13765b,0x000438e3d9f0e627,0x0009e328c2e27539,0x000cbf891013c671,0x000d287f4a706ccc,0x00000000000735a2}, {0x000a7119424dd00b,0x0004246694eeffb4,0x000059afb703b483,0x000ed8b423d47e45,0x000bf44c91809d54,0x000e9b3848075a8c,0x000c75d4f5b184ab,0x0000000000041abd}}, + {{0x00093e732cc6e06c,0x000c65e2cb07faab,0x0006c10c7767a2e6,0x000c53fd4de1f262,0x000c838f7169a296,0x0008a6ce7d408060,0x00067168e19d7b2e,0x0000000000094b58}, {0x000136755dca2adc,0x0000293d02a07640,0x000ed9dfab92ca5c,0x00069f51aa3bc4ef,0x0000dd09b1426aa0,0x0002e59450e44fbf,0x0006ace264f34383,0x000000000001fc16}}, + {{0x0001b41eba2511e6,0x0003e9ee4f521f6d,0x0005af7a840c9880,0x000396db7edb07d1,0x000c2e8290630d5f,0x0003495da09b3457,0x0009b8f1d28188f8,0x00000000000cce55}, {0x000f6b035c499b66,0x0005617cbaf577ca,0x0007eb3582ad9848,0x00008995145b8fd9,0x00081a33b1a72982,0x0005149e992cb5da,0x0004c0ca49fe334c,0x000000000001772b}}, + {{0x000b80038e0f9767,0x0006756ad758212d,0x00066af19dfc2941,0x000c6ffe2c8b0369,0x0007fcd7336b85f2,0x000a46acd55c6d35,0x000ac7b1ecc56d22,0x0000000000036277}, {0x000330b02f145871,0x000c1a4ed11e8d27,0x000297add7ae640e,0x000ba45266158ab0,0x000d89e0dff05fda,0x0006b02d06f0b27f,0x0006e132ef7ae2eb,0x00000000000cc1b4}}, + {{0x0008162061985fbc,0x00005c112733b3ba,0x00062ae17de90bd5,0x0008e01810097859,0x0002bfe16c4fbb7d,0x000d9f8107640a3e,0x0005d74e34813ec1,0x000000000008d260}, {0x00078cdfc58ed763,0x000f72a544cd81e6,0x000e167259300b75,0x00057bacec18a7f0,0x000511b882d69e61,0x000f86563a555fc9,0x00096e4305a4dd04,0x000000000001d0fd}}, + {{0x00008da90a96090a,0x00032f04145e8229,0x000a916fb6ff9132,0x000ba4e12aa299fb,0x000991b3b5179ffc,0x00081c747cc5ec24,0x0003eb9edcd4616f,0x0000000000077a88}, {0x000a4909883002a4,0x0008b9b0bab581a7,0x000e659d0317cb87,0x000d81e438a9d43f,0x000e25ca8b3cfe8c,0x000bc720cf40e2b5,0x0006a34254030067,0x000000000006b244}}, + {{0x00099b58a43c6d42,0x0005180e1cd16205,0x000e96620312fe6d,0x00019d509ddce071,0x000e70c4b03267a0,0x0003ba57e52573e3,0x0004f716d253e14d,0x0000000000016250}, {0x0003e944594baca0,0x00013a237bbf8f9b,0x000a642b05f4171f,0x000531a1f384daed,0x0003981251654b13,0x0002dccc139067f3,0x0007b5e98fb14167,0x00000000000a75e2}}, + {{0x0009f542630002ea,0x00044e65245ce93e,0x00012350ea59da7e,0x000c121bad2c8070,0x0002060fcf245677,0x00078cccac52dec3,0x0006fb78d070675d,0x000000000001bc8b}, {0x000ac9684403d046,0x000b5c5cb86bea72,0x00053d522dc955a1,0x000cdf2c92a70d83,0x0001f53cd2a1fbb7,0x0004f11395a9ff1f,0x0009f1fdbe6b7a98,0x00000000000a470a}}, +}, +{/* digit=3 [{1,2,3,..,}]*([2^12]*G) */ + {{0x0006766eb19e084c,0x00028eb06571b5db,0x000430cbda13e4c9,0x000966726eed225a,0x00046100e387a185,0x0006298d18d9e56e,0x000ad0470506b9dc,0x00000000000f3350}, {0x0009595e79f27f3a,0x0006683eb62a798b,0x000ae3d2069c14b3,0x000e880e1bd4a82e,0x000fcaf3b3fcb089,0x000ffd65cd4d1e70,0x000ebbd0b1ec6395,0x000000000009b184}}, + {{0x000d72326a677bdc,0x0001bd4277730e1a,0x0004e8c2adc8ef98,0x00046b099f1867d4,0x0002602dd4cc6b07,0x0000811201ec73d7,0x000f2d27fae51538,0x000000000002f8b2}, {0x000e28e4b1971c05,0x0001bb924af64246,0x0005d0fd898e9387,0x000e9ae068565acc,0x0005a9a4f1464e88,0x00093f7348a3dbd2,0x0003bcdb4a3e483f,0x000000000008f1d3}}, + {{0x000da9f02128c46a,0x00049d1de964bafd,0x0007f571d595c1ce,0x00055af0de9eb074,0x0005a60289bfbc4b,0x000392c619f11b99,0x0004fc3e59000c52,0x000000000005ccff}, {0x000c017748720be7,0x00064b28b306ba1a,0x0007e101bd3e41b0,0x000542ce3f824faa,0x00022f52b71c59b0,0x000c6d26370f097b,0x000e5b4483b72604,0x0000000000034d93}}, + {{0x000b2e0b9f0415b8,0x000c7721bb8359b7,0x000a5f46c16031df,0x000a789348538714,0x0007af598c4f9cc9,0x0006f27c878b604a,0x000ba5d370375e47,0x000000000000b15c}, {0x00021b9613cec089,0x000662bcfd9a4c03,0x000e3ea0c45f94ee,0x0006464a211b19f3,0x00019990b504b05a,0x0004951d3ce059d4,0x0007b0011c5f87d9,0x0000000000000d9c}}, + {{0x0002533a1c8fbed1,0x000ce64e84c28804,0x000338cbe4f167c9,0x000d9ed9fbf23cc9,0x000f5b93118bb77e,0x0006255cf155fd45,0x0008941e9f6d7d9c,0x00000000000c4f64}, {0x00008205c725e2b1,0x000154bc3a502a87,0x00030c3fbf39b6ac,0x0005548d3c862428,0x0004030f713cc7df,0x000785cbf9dbfc08,0x000637f3623326ad,0x00000000000dd3ad}}, + {{0x00053a3eba12bfa4,0x000ced8b8b37a274,0x000ff25533a7ef36,0x000684bd17d58a93,0x0002032fda408ac7,0x0004b49645f9557e,0x0001097fe128e6ed,0x00000000000ed02e}, {0x000f765f56c35dab,0x0008c0052d88eb68,0x000256931b154329,0x00010798446a4f6a,0x0007c99ad35fbf46,0x0000906073bc4391,0x0008aada18234dda,0x000000000005164f}}, + {{0x000f715095892612,0x0004e02c16c7865e,0x0009e82bb73222b5,0x000bbc0795486af0,0x00070427332d3abe,0x0005d3cabad858cc,0x00019c9a1d4b6aa3,0x00000000000e208c}, {0x000d5b54420318c5,0x0000afcc14276eea,0x0008e6c4a86b5358,0x0007cb4e7706b5bf,0x000e479e2c750027,0x0007ad688c01ed42,0x000626ff1759604d,0x00000000000c045f}}, + {{0x000e0b227c3a04b7,0x00029f365419f1ee,0x00001db5dec2705b,0x000c165c41880aa9,0x0007f9712fbd8a91,0x000c556783eb27a9,0x0009cfa6587aec76,0x0000000000002cd7}, {0x000e78bc85d2b5fc,0x000fefc878f9c549,0x000d411713959cf3,0x00084d8caf6df5e8,0x0002aabcde7509a1,0x000de597ad32bf23,0x000858f601d0de03,0x00000000000c5da2}}, +}, +{/* digit=4 [{1,2,3,..,}]*([2^16]*G) */ + {{0x000f068a28ea9470,0x0008bb6029961859,0x0007d86ade910602,0x000693b4df3e5b1b,0x0008a0c3e35782db,0x000b2f577b513148,0x000cc3bfb01ff3cc,0x0000000000027a72}, {0x0000fdf0e7cd346e,0x000f626170927fbd,0x000aa1bbda6cc535,0x0006a634c872d772,0x0000b14d9c9f0bec,0x0006c7778a0a7cc9,0x000a4c8a32d2c44f,0x000000000003b889}}, + {{0x000f462aea173d82,0x000a4860ef793767,0x000a7a5856850902,0x00083662ee7f523d,0x000f54122af0322c,0x000bb2d8058ccd95,0x0005777454880c2b,0x0000000000086d8d}, {0x000038487c4c8fb9,0x00042d5a3057c6dd,0x000955643c37ff31,0x000c99ec3c512f97,0x0006556d891e26aa,0x0009f6112c3eac03,0x0007e9866c3aa7bf,0x00000000000c144f}}, + {{0x00000b161de71555,0x000aead0d24c7983,0x0006a55d94bbb854,0x00034ff7655aa29d,0x00057a5e217ea551,0x00021b295a3d1038,0x00036dfbb9eeb53a,0x00000000000c84a1}, {0x000aac3258d9db81,0x000087579398db29,0x000fa470f6fa27aa,0x0002e1e464522581,0x0005479d8f2c99b3,0x0000b80ef99d5495,0x00050bc2a8a6a193,0x00000000000656c8}}, + {{0x000f81f2532800c4,0x00045171898aa3c4,0x000ea2712f9cc33b,0x000835ffdb2c1bad,0x0001591f5aafbc0e,0x000272c6a4ee3028,0x00068afd71de3bcc,0x000000000006e93f}, {0x000145dbf5847f9b,0x000bc35ee08038de,0x0001b04c30c2d081,0x0007ff5957b2ff76,0x000e5ec029c049f3,0x000324c12315d8e7,0x00057833230602ef,0x00000000000966b2}}, + {{0x0003e43e11c6c113,0x0002e86283e21e81,0x0009c3e50b313030,0x0009b1bb9784a9a5,0x000ea0c0acb57d02,0x0007c682b7c7798b,0x0002b041241c716d,0x000000000001d33c}, {0x00079a15b39e351d,0x000dc5d469ca181c,0x000ce825406e72f2,0x0004cc2a13cf4ce5,0x00069e3ce2793d05,0x0004beafc13bd216,0x00087e01bc70e68a,0x000000000008aba0}}, + {{0x0009cf16a3c4418b,0x0005884aa863e012,0x00089c47322b55de,0x0003206b5c399b2c,0x00073cc109bd553f,0x000384088775b921,0x0003cf25c01263fe,0x00000000000d5f74}, {0x00057c2efedc75c2,0x000933d69705ce0b,0x000359bbe99d9a50,0x000ab1a2626cebe5,0x000285b1afe80198,0x0007e6efdaf8320f,0x000bb6b9c0968ce1,0x0000000000090215}}, + {{0x00066543cf4fd691,0x0000d3ee52d8e909,0x00094816ee49cd7e,0x00095c61881a757d,0x0009c13e370735ce,0x000d2d3f60a8cf9d,0x000c0de71258d548,0x000000000000bbe7}, {0x000476d4cb00031d,0x000bfbd6496e1309,0x000c1c69b8768cb6,0x000501358cfdfb53,0x000b59275b4acbe8,0x000f722ba655c902,0x000aad7e0ff05b20,0x0000000000042b17}}, + {{0x000b76411fcb09e7,0x00066da643272cd3,0x0006802b1cc8eac2,0x0005a7c35b43943a,0x00084606bbf22386,0x00059fb9a6ac0158,0x0001a59660ab7215,0x000000000003ce2f}, {0x00083d9ad8b4f172,0x0006e62af29aaa08,0x00060fa06813a370,0x00029b744c110388,0x0001d36c2571ee9f,0x000b552b7b2a19cf,0x0003d4b87d88e265,0x00000000000beb25}}, +}, +{/* digit=5 [{1,2,3,..,}]*([2^20]*G) */ + {{0x0002b4a5d3a4b643,0x0000231bdb4829ee,0x0006d713dc69c388,0x00042469b6fc64eb,0x000a15786b8c18c0,0x00063da4a0dcc15f,0x0000fb81acdb068e,0x00000000000dada7}, {0x0008c1ca45ab6321,0x0009146361afe98f,0x0001d88fcfcf648c,0x000b61b615694e72,0x0001872951d2f389,0x0003badc77036def,0x0008d340fd3bdad9,0x00000000000380a6}}, + {{0x000d66b2c4fdf4c0,0x0007ac5cf8997090,0x000a08d2a2626f49,0x000681e307b254af,0x000775cd94d78139,0x000684954cc87fb5,0x00099190e7027478,0x0000000000095ceb}, {0x0004649153ee63bb,0x0006891bbc0ab337,0x0001f845e221f84c,0x0003d704b93d45fb,0x0004f541da1f1cb8,0x0007ffd10e229902,0x000b9a3eef7ce14b,0x00000000000b3fc1}}, + {{0x00067cf1182bf349,0x0007f23c1f744697,0x000288faa5d1b184,0x0002c9d5afd1bfd3,0x0004f89d76fea4f8,0x000702f80a3d1e9a,0x00089d964f705075,0x00000000000f56c0}, {0x000478c2e0092e1f,0x00012e205fa8ede0,0x0002998cd8ea4a27,0x0001004356d43961,0x0001fdbbdfde331a,0x000a00e7158b7890,0x000a30a52a15979b,0x0000000000055497}}, + {{0x000d05d101bb2988,0x00097e5004e8001a,0x000e96c63ff7fdd5,0x00050d1bd869f77c,0x000de7ebea2c405f,0x0007620baecffa54,0x000ff43354dc22d8,0x00000000000b1c01}, {0x000d9286dd26e577,0x000c2d9370076043,0x00025722a20b989f,0x00076273291e5c62,0x0007f0a7ca55c0de,0x000592a305cfebd8,0x000ce4de1162809e,0x00000000000a78eb}}, + {{0x000153343d6d3c05,0x000a15562a856338,0x00041dfd1ca25266,0x000317409c75b8cc,0x000124923f80c19f,0x0005b291e21c7cc3,0x000b05e63fe47f8f,0x000000000000dc08}, {0x000a81ce4831b7d3,0x0001558ae455ea5d,0x0000f05c04530b31,0x000c97f3ee3989cc,0x0005f38759ae42c7,0x000f46899c1b03af,0x000c7d1a673c75bc,0x000000000008d508}}, + {{0x000fc69642676f12,0x0008d1e9b23b9bca,0x000626ac6d6d75ba,0x00000fe59b7721d0,0x000c9e2f4cebd4cc,0x0000af70ed5c36f9,0x000799deca06bac9,0x00000000000416ee}, {0x000affe525098c8a,0x000df0d7afe1b4a6,0x000083fa6f5ecd29,0x0003d6ee6eaed183,0x0002496087e011e4,0x000a3a66e5baf860,0x000677f833634fb1,0x0000000000079398}}, + {{0x000c39f67e66a95e,0x0005b76512d1b46e,0x0009e5603da596ca,0x0003aa8025a5f25a,0x00095cbd2a40d1c7,0x0008d61c62aba192,0x0000f3b53cadc3c8,0x0000000000009829}, {0x000894e8b1d3bb8b,0x0003a72800ecafd7,0x0003c62dea4f99fb,0x00092a7282ba9d23,0x0002bd5f1bb214bf,0x0007c6c969062967,0x000601362f68eba9,0x000000000007ea9d}}, + {{0x0004d04ff62d3721,0x00071e141e762de4,0x000fa0d592d3e0eb,0x000cde496131447a,0x0005cb6c2ef746e6,0x0002f9fd80458a5d,0x000457b774763453,0x0000000000016544}, {0x000adb5cae252cf8,0x0005abfacb4de24e,0x000e9db72a61c26c,0x0003220f22d92e51,0x0006557232589b54,0x000ddb8bcaa4590f,0x0007bdc7b6730e01,0x0000000000069e1e}}, +}, +{/* digit=6 [{1,2,3,..,}]*([2^24]*G) */ + {{0x000e98d9a0583230,0x000f77d27d71f312,0x000823b17edc1a45,0x000afeb6075b2d00,0x0006d93a06f7418c,0x000d001b9c0d691e,0x0007b9c16a95259d,0x00000000000026f1}, {0x000b72219cfa1dea,0x000984c1041afdb4,0x00056e257be49c48,0x000efd62c1758e9c,0x0007e6c3229a8d08,0x0002d89249cc6f20,0x000fe7ec69e90208,0x00000000000f331d}}, + {{0x00061c722c01a99c,0x000518ec4335f7fe,0x000df3425d366c49,0x0006de001141ab62,0x000c2eca98a13ff9,0x000fdf648b21acc2,0x000e8b6154849010,0x00000000000d1403}, {0x00097be7041b8df0,0x0008ff1a35f306b8,0x000b8cedd3e80c1c,0x0006c077fc9a752f,0x000e420d48a089c2,0x000fe2e738d2535f,0x000f3980ec5ddd52,0x0000000000071704}}, + {{0x000259172095dfcf,0x000a020aa15d95a2,0x000d85bd292d185e,0x00005caef579e8f8,0x000b325981bfe2f2,0x000438be8ad27e38,0x0000d9087b8284c3,0x0000000000042236}, {0x00091bc7ac277af8,0x000bb87cdf5accaa,0x000de0f7da8c4a28,0x00040c1891046669,0x000c9c1578e8a712,0x00050ffa2eb5a175,0x000a28bd66910ad1,0x0000000000011459}}, + {{0x000f920077501dce,0x00091498808ed4f0,0x000dc6c59ac5d089,0x00025f176c6b964a,0x000bac474261796e,0x000a460c11aced64,0x000e48a62470fc29,0x000000000005e751}, {0x000842d2c145f36f,0x0007acc00053aac5,0x000ca1b81e5b854d,0x000cc2e3f9ca178e,0x000a0b80d1b0ddac,0x000642225ad33f34,0x00061b6a76df9364,0x00000000000778e7}}, + {{0x0009eb69fa5f1bc6,0x0008ed30302342c1,0x000e3ef7d69039f0,0x0009b575c4630f26,0x00008d098d745364,0x0007f5cbc60197fc,0x000efc9c295d5464,0x00000000000c0813}, {0x0001c5999be2ce7e,0x000e7f6e08007370,0x000b6019bc473a63,0x000e08e11d9b388e,0x000a5db61c657af3,0x000b4dc4d073ec38,0x00082a9b480cb89d,0x00000000000372fa}}, + {{0x0003179049382c1e,0x00069dffb03ae77d,0x0002e9528cdd6bd1,0x0002521b19fe0db8,0x000f3d5c7fee4c26,0x000e68e1e0ec1e54,0x0008a62856510b05,0x00000000000dc80b}, {0x000ac17897e6fc5d,0x0000680a509308c8,0x0000b4dde3197e47,0x00012ee28235c538,0x0008301f9653ca61,0x0001fcdf8d28a0eb,0x0005f322b11e26e1,0x00000000000e4d73}}, + {{0x0002a6a91ebadb85,0x0006346a2a08bc3b,0x00020e574ba891b2,0x00056a2b3df9fbc8,0x000eb121d51228c5,0x0003bc86c81d3161,0x0000d14e27ce0b12,0x00000000000bfb24}, {0x00072db1b86f039c,0x0005986edb71958e,0x00011b5a99c9a865,0x000c6d8067f5870b,0x00033fe8e5322f6b,0x000a7997ff558b88,0x000b9be9433e2321,0x0000000000087e53}}, + {{0x00084d7bdfada95f,0x0008b9c66a32b0d1,0x0004ace9a2f6c763,0x000fab721e716f0c,0x000b96ed74e68c6c,0x000110c8332c8fcc,0x000efe475890dd0b,0x000000000005cb4e}, {0x0003947e05207b63,0x000d29d7b89a68e0,0x00001e2e33262bf2,0x000b55bca7a7d527,0x000655d04585c3f0,0x00057acc5a6e56a0,0x00039e818e221c42,0x00000000000fcb8d}}, +}, +{/* digit=7 [{1,2,3,..,}]*([2^28]*G) */ + {{0x0007398749666d45,0x0009c0a74da828f4,0x00001ff782080bc1,0x00026bb57c2f5ad1,0x0002845d45e4896c,0x0009a7d36981e2f7,0x000e8fca152b877e,0x000000000007b582}, {0x000b1649b1810a70,0x000c3ea3b9bd9987,0x000d4cd2bb2df2fb,0x000fc5d5748a6550,0x0007622665eed346,0x000f16e277ac2f21,0x000dc8bb5efe7fb6,0x00000000000644c9}}, + {{0x000db9a336c7d7d8,0x0003598d0898164f,0x00065860354f4784,0x00018287cfc13dbd,0x000c8655a658651b,0x000c91b712d606e4,0x000090ba64d3c563,0x00000000000b82a5}, {0x000726397fcaaf5f,0x0006c2d1dff024ae,0x00092238373e43a8,0x000ee6b0ea1fe022,0x000cd5c1273c1ac2,0x000e603e7c100b60,0x000dfb4496084cea,0x0000000000077c2f}}, + {{0x00064d07c56a20fe,0x00000a93fec079c4,0x000155e36a436889,0x00045a5cce5662fd,0x000f83a9a4a9c00b,0x000bbeb632e8a0a7,0x00080f6e0cdebbc0,0x0000000000063ccd}, {0x0008f36be2f62c1e,0x00061fc10fa07d22,0x000b3e653f03a3be,0x0009cc66bf53af92,0x0000f10bb6c9fda6,0x0007625e1474b744,0x0003cbcda9db3b1e,0x000000000001dc7f}}, + {{0x0006fec7b896d97b,0x0007de8e32259b22,0x00051ccb0af3cd54,0x000a4219f42edba4,0x000d0d411d4df147,0x000014bb46d4bc00,0x00066fa1a13a2770,0x00000000000fa101}, {0x000b6039e0c4cc34,0x000d8b2a1dfa62b6,0x000ae98992614f2f,0x000a3a2f88c7359e,0x0008347726a08409,0x000507bb9071f383,0x000167d18a551c27,0x00000000000b359b}}, + {{0x000fae4c55d4b2c3,0x0000aeaaaf45fd46,0x000aa7e37459675f,0x0009b673fe123f1e,0x000dd8fd0129989b,0x0004982a4e2ca56d,0x000ec777d6d0cd62,0x0000000000071e1f}, {0x0001c6bdd9bc3a7f,0x000043e9a049f5c5,0x0006deb929a38a20,0x00008e24fed8f86f,0x000ce199e8dbac2b,0x0009cc964a1d1357,0x00063b7cf06ec8e9,0x00000000000d85ec}}, + {{0x000ba68a3fc0bcb2,0x0004e7d111c66c1b,0x000d9aa66fbcd347,0x000730c6db857e9e,0x0009f4b46d124cd8,0x0008472dc3c9c03e,0x0001bbd42f0242a7,0x0000000000026084}, {0x000aac1b65a94c0d,0x000ea6332b11a21d,0x000acbe9385d6783,0x00028eee7e8944ac,0x00005ab28372402f,0x0005e1ff33d1bab5,0x0007296944e82cad,0x00000000000e8c75}}, + {{0x00058e168fe9a81d,0x00043a151dcbb9f9,0x0002eed94828803a,0x000fc00604d46e1d,0x000572f3e28c947a,0x000b1cd1dc3c9d57,0x000a45ce4c1cbd14,0x00000000000f80de}, {0x000d8f65d998669e,0x0003c50920f39bce,0x000b6be78ee5193f,0x0008ba13f798e332,0x0006c5edde471997,0x000714a1e1294aaa,0x00003c280002c2be,0x00000000000f2126}}, + {{0x000493dde1b54616,0x0002ea44f6ef79f3,0x000c2b67fffeca1c,0x0004ed80eaf66728,0x0008181514a2cb0e,0x0002927ea2bf485f,0x00064574670e180a,0x0000000000012c14}, {0x000339b9a314b3a8,0x000724068c073875,0x0004212e0016a517,0x000651d698b28177,0x00096da14fa8391b,0x000a578b1f310d16,0x000ad7a089be6bd8,0x0000000000044389}}, +}, +{/* digit=8 [{1,2,3,..,}]*([2^32]*G) */ + {{0x00024e7304503422,0x000f0ba86aec16bc,0x0007f0cf87c57f69,0x000ff0789df2f808,0x000d97a773d58978,0x0003f35f685750cf,0x0008c9806bb730fc,0x00000000000fed86}, {0x0006b0ff06192aaf,0x000eadc0fcde080e,0x00055bc2901e7a1e,0x0007d028d3ad6cd9,0x000997293550fefb,0x0005cfbba5c652b5,0x000d2232e12942ed,0x0000000000098800}}, + {{0x000418b23a7be4e3,0x000cb162cdf33f48,0x000c8d04be100c6b,0x000d114454eb977c,0x0008dea38a674478,0x00035728a8ce403d,0x000504d459633b74,0x00000000000a63b0}, {0x00010a5f9fdcafdf,0x000c40c74066a938,0x000e6c61b766c71e,0x000b588a99690ede,0x000c3ad775623398,0x000bb60ee4949517,0x000becf9824f09cb,0x0000000000085660}}, + {{0x00083bb80ede991f,0x000a02daddb11952,0x000f09f6c4b181d6,0x000e82721a6aa89b,0x0007467506deb73c,0x0008d8daa1091958,0x000dfd0927724c42,0x000000000007c17a}, {0x0009a9bb30e43182,0x0003a8518dab18e9,0x000594c3465b3913,0x000c37f89e7a3983,0x0008e273f6f35943,0x000143d228e63f5e,0x00028ec6d0352b83,0x00000000000ebd16}}, + {{0x000731dadf48f7e1,0x000a14074ee26b83,0x00088243bc9a29c8,0x000d53972cecb4c8,0x00079a7dd9c4aa01,0x000c787cf4b0cf12,0x00053f3e3e3f165b,0x00000000000942de}, {0x000bfa5d149fa2b1,0x000010cc6971941d,0x0007bdd5c6a1acca,0x000c1e292314a097,0x000614a1adcb9fed,0x00062b86a7547d22,0x000b7d405561a486,0x00000000000f5480}}, + {{0x000be69f3af05d97,0x00082c4e59f2ff48,0x000865d4a01ec6bd,0x0000d824464bbbbd,0x000016f9540dfbc8,0x000595b5d3bacfa2,0x00080d1954efb613,0x000000000007a5cd}, {0x0009c6dbd9d7e6b6,0x000ac926a54cf784,0x000f3366624e7b07,0x000167ccb5c8d4c7,0x000ff9a21ce20677,0x0002df8cdc994d22,0x0009083a25ff6b42,0x00000000000f68e9}}, + {{0x000a093607905265,0x000ede544b89ab7b,0x00017731e314dedd,0x0000da69a73104b6,0x00067274b105a6a9,0x000c61bb65c26021,0x0005068f9705cf60,0x000000000003c4d1}, {0x000ed5677f9dc5c6,0x00020ab5a27accb8,0x000e0bb2ed27cc25,0x00036d15a36afae3,0x00095c455916e68f,0x000b5d1fa79004b1,0x00048916ffe6249b,0x0000000000049338}}, + {{0x000a7603914a9a59,0x0000b941be86e102,0x0001a6f35b551149,0x00095b469d75ec8a,0x0003db0d4374658f,0x000fc77053fa79d5,0x00012885da635c6a,0x000000000008e7e8}, {0x000f4285c3e56baf,0x00002558cfa8eed1,0x0000effdf411ca89,0x00098b96a32e8849,0x000e3c45ce1a104f,0x00085de0268237ef,0x000de35c820dc22d,0x000000000007459e}}, + {{0x000a78ec870a31bb,0x00036923d0b44369,0x0005db7ea085ecd1,0x000be009cf5b87e5,0x000d1d61103d1656,0x00065239313a37d0,0x000ed81d705880fb,0x00000000000ed712}, {0x000ff1a5976c303e,0x0006f15ad02e6160,0x00077114865ad858,0x000376cba2b3ffe8,0x000f9745443c56aa,0x000903660c3be2b2,0x00092d47c8a870eb,0x000000000006c6c1}}, +}, +{/* digit=9 [{1,2,3,..,}]*([2^36]*G) */ + {{0x000b550138d02bd3,0x00038148bd39cbc2,0x000f6b4c6038c07a,0x000fbe2ce5484157,0x000c87fdde9ff397,0x000e9c179441e5c2,0x000c716366b49ffe,0x000000000002938d}, {0x0008a64bcbf3adf9,0x000d026d450f9f8a,0x00015da756f71781,0x000bf4d298fd8771,0x0007544768b65f68,0x000491267e86df04,0x00071a40b69a32f8,0x00000000000f917c}}, + {{0x0007f3a58f523dab,0x000a7a66c70349a5,0x000f8ae356d6f09f,0x0003e96b5ab54115,0x000c7c57d123dee3,0x000d6ad37d068929,0x0001780839a208f1,0x00000000000123f8}, {0x000f3c2b5c9dfc15,0x000f4b3e5e52449d,0x00055ba373af8955,0x0000ab7389f2dd3e,0x0005890bba6f513a,0x00066bf093197a14,0x00072261add75b6f,0x000000000004eef1}}, + {{0x000fbdf154b15bac,0x00063810b6ab3193,0x0006da8c3809a3ef,0x00038dd898977511,0x000e7a336c9a3cf8,0x0006f89c03e391e4,0x000e227014833717,0x00000000000bc4f1}, {0x000e7d4400e0ab41,0x0006b32b104f92b2,0x000d1a7a3b67e3fa,0x0000437bf178ac12,0x0005c99370d5b831,0x0002b93a8722299f,0x0007190a493cf033,0x00000000000a420f}}, + {{0x00046acf9a0ee15c,0x0006a21feb7fb87b,0x000579369777bef5,0x000557624b04e704,0x0006342cb0ad03a6,0x0004f64262531f18,0x0003ea088c4d54a2,0x0000000000006a87}, {0x000f1f11e0fca837,0x000d5dbe0253ef23,0x000bcfdbd73eb554,0x000368173e65902b,0x0002ccbfa504eaaf,0x0000e163e71f1fab,0x000f3bb7b845224b,0x000000000003c779}}, + {{0x000cf36036019ecd,0x00029cd7b3c4286b,0x0005e1ca08cbdeb9,0x000bcbd24ef5c386,0x000ce579c309eb66,0x000f6c9007edcc21,0x000c2c7b19d49116,0x00000000000b6317}, {0x000aad793c4e52a3,0x000e7554ba553558,0x0002315e3b514170,0x000e33bffda4032e,0x00082306675c3d1f,0x0000c91e75dfec47,0x000879be59305e00,0x0000000000025a6b}}, + {{0x0002c6fd041a12fc,0x0006aa35802f5d21,0x0000c3d459456256,0x000991d472b9d211,0x0006a2f8e875261a,0x0009b6d63d81a1ed,0x000758942f213a69,0x000000000000ae57}, {0x00067bfe08ea2ebd,0x0007061191c82b48,0x0000611a48f73652,0x0003e86525112224,0x000d30dabb91abe2,0x000d2742466dd967,0x00005077650c597e,0x00000000000ab25a}}, + {{0x000abb01ee5e0194,0x000bca624ab366b4,0x0009dc413b0af513,0x0009c4273aa694c3,0x0009779288abe822,0x000575e0e0cc3102,0x00003ef8eff30f57,0x000000000007d528}, {0x00093a51fb5fbbe1,0x0002f32d87e548f1,0x0004001c13dfb44c,0x000b8dd16c6e6274,0x000c2c140452aa2c,0x0003031b1add098a,0x000543d25f285d2d,0x0000000000075b59}}, + {{0x00032a5061a42b94,0x000dc520b0bb8a42,0x000466f1305a432b,0x000c73a73c239760,0x0009783aabba85c1,0x0004631556e4dec4,0x00017b69f0c69bb0,0x000000000009c97b}, {0x000fbbef3e8375b4,0x000b155af24a9074,0x000991d9ad3481f7,0x000283d708671c48,0x00035fd9001a4034,0x0002eaf3b200ddab,0x0006c4e45f28e434,0x000000000001ba93}}, +}, +{/* digit=10 [{1,2,3,..,}]*([2^40]*G) */ + {{0x000e8393cd68c757,0x000b2b083ba6a1e9,0x0004638d474c7417,0x0007a21fc82dc041,0x000a9d3679d89536,0x0009724c0227be26,0x000c0fc70f6d6c7e,0x00000000000f9ebe}, {0x00075bdec21bc5d4,0x000b029dde03dcdd,0x000a669d8fc534ff,0x00090c90f602f4cb,0x000849722bc4daf5,0x0009b22b617c5288,0x000b90a8df99f008,0x00000000000e59b9}}, + {{0x00015e6442d15d01,0x000dc6f5775290ef,0x000cdd79298e58a8,0x000842778b96c6d8,0x00022f59350519a1,0x0007209d6a674f99,0x000fff5abeeec46b,0x0000000000047cf5}, {0x0009d3497d146805,0x000ede24509b7378,0x000ed2fba1e0b34e,0x000af595761e8e3f,0x0008d420a2887f7d,0x0000ff696ed5cfcb,0x000c8f365b29eb7a,0x0000000000099a1a}}, + {{0x000785db50fa1164,0x000694936c6a0393,0x0005ce545ed4b2d3,0x000e8b45714f2c6a,0x00023f5ac25a03ae,0x000b33794139bd69,0x000ba96a2e42bab5,0x000000000003ff7b}, {0x00034248c56f7e51,0x00088b61d8643327,0x0008d647e582cbe4,0x0000e1472eb77fae,0x00013b99c6356211,0x00074c9f23d5b96f,0x000250956ecf64f6,0x00000000000ef2ba}}, + {{0x000a8baf84131eb9,0x000019ee1ec3a29b,0x000d9f684960ce84,0x000737588102ac15,0x0009c08527f432b9,0x000e3dfbedd296cf,0x000c4fb74f8145fa,0x000000000006cd7c}, {0x000debad8e4205ae,0x00062a0f2fe7a043,0x00094ce3fc7d23aa,0x000f2d40eeb90a7f,0x0000be4de6846e7d,0x000dd06bce2f46e2,0x0009f6cd28feba3f,0x00000000000e6d6d}}, + {{0x0002283f4c1e03dc,0x000bc246ffcb6b34,0x000a382150ba305c,0x0003ae2250e66766,0x0000924ce5fab4b4,0x000d8c77695c1b5f,0x0009d02555795beb,0x00000000000acd9d}, {0x000cf0d26acc1b8f,0x00088e1d74aa6321,0x00035822f91490d5,0x000df2795af56df1,0x000fb331b6f4df74,0x00059e13724b10c5,0x0007f2b0a6df9a65,0x00000000000c0663}}, + {{0x000c55f77d493f59,0x000089ad73168775,0x000791ccc3015317,0x0006c2d30b3a5f4a,0x0007c89723d59e94,0x00031f6077bc4ced,0x00034179f514a1bd,0x000000000003a274}, {0x0007950f4645c0c2,0x000e07eb010278e1,0x000a3d29cb5ab91d,0x000760f35be21cba,0x000b7c793331718d,0x00030d29eba58160,0x00003afbc0ce1f8d,0x00000000000c6f4b}}, + {{0x000986e6462b5c9b,0x0000cbd8c0867ee8,0x000db80962770b4f,0x00012de024593896,0x000fdef840b687ed,0x0000b56e13f7d98f,0x000e8771eee0cb5f,0x00000000000d8d9b}, {0x000f5c1c38b9eff3,0x000c1e6b50b5a5f4,0x000fada267894657,0x0001bd17cb1f9925,0x000d4ff11827418b,0x000042c63607818e,0x000ae3e630d93a9b,0x000000000008c779}}, + {{0x0000de60ecec558f,0x000bb35d474260aa,0x0007deb342712d19,0x00015e22e91bf5f3,0x000cc08b6b1abd6a,0x000b97de8e366a84,0x000f29759c122f55,0x0000000000008a03}, {0x0005b54173576b1f,0x00000dcc9fca2774,0x00073c06ae128d8b,0x00039029b59cd052,0x00006f5e5bd4deae,0x000099f4df532ede,0x00005284fbeeb936,0x00000000000088d2}}, +}, +{/* digit=11 [{1,2,3,..,}]*([2^44]*G) */ + {{0x000b3d633d0721cb,0x000732ba8c78fe5a,0x00016e2c1c57f816,0x000f36a2fc2451f3,0x0008bb91e1e36842,0x000ead762fc5c955,0x000556035d1dfcc3,0x00000000000031e5}, {0x000b4359fe8646d5,0x000383af0cc803c6,0x00070f15b8bb97ea,0x000de0a6ade1d137,0x000d93b2dcb580c3,0x000a2214de8c3a5b,0x00048de3adbd7c90,0x0000000000011929}}, + {{0x000e8783f9b6f97e,0x0009b65026296c0d,0x00086ba77888a60e,0x00063a460c8bbf8b,0x00078b2a71206237,0x0005497e7fa8f5ad,0x000618fd744bdf08,0x000000000002ba35}, {0x0004df87b45c7eff,0x000870cebfe9d444,0x000c034f12ddb3df,0x00017a3fcf19627f,0x0007c2f112616558,0x000f2c85030ab44f,0x0000c3bb001c9ddd,0x0000000000007326}}, + {{0x000e365e9f55b0a4,0x000aeb08fb116bd9,0x0002cf623c1f798f,0x000fc7b6f9549671,0x000f76bd243c73ae,0x00009d5a8c0fb886,0x000049871eacc5ce,0x00000000000e773f}, {0x0001eb3732cb8726,0x000aa92945c840e9,0x000022c04533de34,0x000bc1d0509d7400,0x00010f1af1754762,0x0008c160f15cf97f,0x000f0c1f85569532,0x000000000003b439}}, + {{0x0004f7c9bedca76f,0x0006dfa7d1236235,0x000a7e4930642e7b,0x0007288beb1282c5,0x000a07fee8a99ea2,0x00070fee91c069ef,0x0006fa5749c7b558,0x00000000000afcec}, {0x00048441716f41a1,0x00064a3f8f1b0daf,0x000b8af2f805e4cc,0x00029a9b59dc06f1,0x000b98a92c387533,0x0002b4662fa8e5f5,0x0006c66b6f46fd3c,0x00000000000ec04c}}, + {{0x00054b9f6efe8494,0x0005eaa16c27a15a,0x000106292d7b104e,0x000d193aae87c9d3,0x0009916d634e7ae2,0x000a65b4b125ab45,0x000e2202ded714cf,0x000000000004e212}, {0x0009494225bd1826,0x000c097c48a1862b,0x000bf9e4c3ff8573,0x000b77b2652f5018,0x000d078efd386fe8,0x000cb82991daa602,0x00062635885364db,0x00000000000b8240}}, + {{0x000f5a3697f1c244,0x0000e0430af76c1b,0x000f0e87f66ce63d,0x000905f12e919108,0x000012db9e14e1a7,0x000baeeac1c689b7,0x0003196bdd3dc90a,0x00000000000504f0}, {0x000e18cdf6373284,0x0003c874afd60b16,0x000a978150da10ac,0x000eee1ebf4aab2c,0x000c1aa49fe60d33,0x000217cfda3631ca,0x000e770d8340fbf2,0x00000000000423b7}}, + {{0x000b3813851ecc4b,0x0001df8c07372826,0x000ea9f99e2d35f1,0x000faf1a6305a291,0x0007f3e0f93d2b97,0x000aeb8c15bc61f6,0x00024b7238583cd7,0x0000000000039f5f}, {0x0002b746db300ac6,0x000a11cc8b467be6,0x000e46954d17b55e,0x0005f95ba2641ae4,0x0002ce9d565b1b9a,0x000eedc6287a0c36,0x00003d07fb51b2e1,0x00000000000a9739}}, + {{0x000d77fe5e566bbd,0x0001978a53b5a370,0x00081dca6fe505a1,0x000f427019a6f8e7,0x0006dc3ad0ba3520,0x000745b7cde6fcad,0x0002dcfec96e4f79,0x00000000000b133f}, {0x000924a225ecf745,0x0000c50088a2b006,0x000c145291ebead7,0x00032ff23ae4b9d3,0x000e85246712f213,0x0000b515e8cbc659,0x0008b727fa9c8df5,0x00000000000494ac}}, +}, +{/* digit=12 [{1,2,3,..,}]*([2^48]*G) */ + {{0x000ff6bf222c5c9c,0x000322986475308d,0x000309c5ef927cbf,0x000d6b4216ab9acb,0x0007be12d76a038c,0x000347bdb3df9b7b,0x00048913f4d9785f,0x0000000000013e94}, {0x000466717b5c75f3,0x0000a5f8e796eab2,0x000d6af2aad3919a,0x0005d8ad10740b88,0x000b5337dee6254b,0x000f02247c38b8ef,0x000c4cf688c2e194,0x000000000006c25b}}, + {{0x000272cd3b35df41,0x000d936c9dbbec27,0x00026ae70fa619c9,0x0008db696a8f9f19,0x00056b01e6bc1ab3,0x000fc4adae031d23,0x0004e410466ae68a,0x00000000000ed9c4}, {0x0005ea962547af52,0x000cb61272c12a27,0x000f929706a5a2ac,0x0007a910ecc49eb8,0x000ccbe84d5cf4c4,0x000e497d7eb95dfe,0x000ce443f3b71c8e,0x000000000004c6fe}}, + {{0x0002d9d94d551889,0x0006182e5d818574,0x000101531df0c231,0x00044261daa2e22b,0x0000e46f32576b02,0x00069db38b86a358,0x00027eacf145bd76,0x000000000004df27}, {0x000d2ba752047cd9,0x000c203d9391e25b,0x0007c9592434b2d4,0x0007845ec38fa9ac,0x000a265ad6bbefb7,0x00054a1b2dd40660,0x000499a22d988618,0x00000000000737ea}}, + {{0x000ef1248ca55f15,0x00028e323ed0c422,0x0001736a7d35b006,0x0002f06e8d68e4e9,0x000ad0742e5d9c09,0x000d3df92d8f5555,0x000eabe2d175bf00,0x000000000004f71a}, {0x000a6a143a42cf09,0x000c6d1762d7229e,0x000840a2cbe90735,0x000cb4c6281f2a74,0x00003603e53a2caa,0x000fecf29635ba47,0x00036194a9811d49,0x00000000000466bf}}, + {{0x0009fc85048451fa,0x000fd4737236d065,0x0005b89cfa755eca,0x00070306da6e06f0,0x0006f3838f569da9,0x00043188730279bd,0x0005d0fb328c8b94,0x00000000000be90e}, {0x000859016f87df1b,0x000843334a6711d3,0x00078d74e5890358,0x0007b6e38904b738,0x000296b588a53493,0x000577ae391e227c,0x000c7da599b21544,0x00000000000214a0}}, + {{0x000fcc62fe159c27,0x000c9e63fbb0fb71,0x0007ab3cd12c8947,0x00030677afd4bf85,0x000dfd37120d5cea,0x000d718a74494e39,0x0005fb8c572c7249,0x000000000005fa30}, {0x0005abf2e0c1181d,0x00074751c217ee1b,0x0005917c5a26a520,0x0006e6efe7a64872,0x0000f53b0e479a99,0x0005fd5931a4f6d1,0x0009ee651390ecd1,0x00000000000739ee}}, + {{0x000e27c9677a2151,0x000ef0b6d37446aa,0x0007f13e8f2bd87e,0x000c94fa109847d5,0x000044944c7712bb,0x0005a31b874c0d53,0x0005920d280b18eb,0x000000000007ef42}, {0x000c07ddca373d80,0x0004ef11030c77be,0x000075bee798eeea,0x0002d013d22f1b04,0x000cd93ee54dd5e0,0x00041d4b1b6d66c9,0x0006ed80b4154faa,0x00000000000acf8f}}, + {{0x0004ca485f1804e7,0x000ad0f05710ab2a,0x00002b0d41da0420,0x000a67a46b8d0e2d,0x000c698b78cc137d,0x0008a9393454b89f,0x000e69f2a6e1de25,0x0000000000016488}, {0x000b96b954a8287c,0x0003d7c6c5501c10,0x000fb63222050457,0x000e30e92f152478,0x000327e70a0a4b9d,0x00014936309d4ca9,0x0001379c8b16340d,0x00000000000ce642}}, +}, +{/* digit=13 [{1,2,3,..,}]*([2^52]*G) */ + {{0x0003c432161be476,0x000c0f8a8499b505,0x000715248b87d78c,0x0001b1d515e1328e,0x000ba941e788b85e,0x0005dd8d888a2636,0x000350a045241d2b,0x00000000000332f0}, {0x0008eeabc026bdc0,0x000f796c4b204e16,0x000ce54b1f342310,0x0003fc6d00b602a1,0x000e89aa3b796fc3,0x000d4dd0007a914e,0x00095635353eb7a4,0x00000000000673e8}}, + {{0x00027e0f6ecb7465,0x00040f36e83987c1,0x0002e0c806d929c2,0x00007464efc5b0d5,0x000ad316c43436ab,0x000ccf839b211e59,0x000a072515ec9f16,0x0000000000003dc6}, {0x000ec4a69e8d5661,0x00017842b727527c,0x00065c4526d40261,0x000711ccef5255e9,0x00075108cb92967d,0x0001b9740cd3bfb0,0x000308e50c0d8aec,0x000000000001a9e6}}, + {{0x0002078cea733c1a,0x0005b283eec25eca,0x00036d44d991d5b4,0x00083b827ad302e8,0x0002bde3fdd0269a,0x00030b3a6225f2f1,0x000043046fcf3801,0x00000000000c3ed9}, {0x00066dedc2439ae4,0x000eff870f14cae6,0x000680b39cf67cb8,0x000d5f4847be7732,0x0003d0ed73a0f3e1,0x000b3babba949822,0x000f706933ccf014,0x0000000000037f08}}, + {{0x000ba839c8cf3524,0x000ed1afa6aa5579,0x000f9ef0d2ddddd9,0x000920b5d36da502,0x0009291e774f07fb,0x0000d87a8144d51f,0x0001a026c2c134f4,0x00000000000a932f}, {0x0003544f31a7b78f,0x0009935bb2a42294,0x000ea47969f6664d,0x000cabfaa1838ed8,0x000fe2855f1f5c40,0x000525934ea0c05f,0x000fd4931ebb02fd,0x0000000000016246}}, + {{0x000bd623cb7fe067,0x00038ecfabd26775,0x0008c3832c0a3527,0x00064ccfe2691ca7,0x00058347566acf4e,0x000b8c733e3889e2,0x000f5748da354885,0x000000000009d9c9}, {0x000592cc5e5c9fb4,0x0000e8c26a8d609c,0x0000459f168ec210,0x000a70a3f8db9f92,0x0000e758213e181c,0x000b2653e25aa645,0x00003aa4898f9169,0x00000000000ccd83}}, + {{0x000fac468f3d59db,0x00099517d13b0e90,0x000cf2490366b8de,0x00026866d752aaab,0x0001cab026676e2e,0x0003163c395da9fa,0x0003c9be8d91ad42,0x00000000000a6995}, {0x0007a57ea4ee9030,0x0006ef728b1d231f,0x00013aa7ae93d8f6,0x00000a82e75d9c30,0x000e3ad09def97a9,0x0008a2be8136c6b1,0x0004474bab14a6dd,0x0000000000025cf1}}, + {{0x000e1d30e97eb41c,0x000b411b59f3da92,0x00020acfcec12d54,0x000f0a1936595900,0x000cca0b1b0e5cad,0x000274a5e8fef04f,0x00027ebcb4d9fb0c,0x00000000000ba784}, {0x0008e71ae4477c5e,0x000fbc49f0bc478a,0x000ac96d890c62e2,0x0009e583f796b820,0x000b17964262200e,0x000db00395bbea92,0x0002ba86b3c15756,0x00000000000ead48}}, + {{0x0007642e08638534,0x000b5cd92906c650,0x000ae6db49a06b5d,0x00029781fdc19156,0x000c269d611e0d69,0x00065b00a45d01a8,0x000388e7bd1e7096,0x000000000009bcaa}, {0x0007591cdd6ae97d,0x000ed8f189e87506,0x000ccf1d10959a9b,0x000bf16c633b1123,0x0009d6f1dac8ca65,0x000c3381dc6adc9c,0x000d120df2c293a3,0x000000000008388c}}, +}, +{/* digit=14 [{1,2,3,..,}]*([2^56]*G) */ + {{0x000653d60a9d872c,0x0003bffdbd0eb2dc,0x00061fddaf39f568,0x000cead35e7a3a29,0x000c67833028c11a,0x0004c79764998cf8,0x000a1c8f3a346b84,0x00000000000db9b1}, {0x000642a471b701b9,0x000628735dabc47d,0x0005300f39a216a2,0x000dd49d267a01b0,0x0003ffa20d117c0a,0x000ab2d4a2b46c91,0x000080f2acef26d8,0x000000000003d926}}, + {{0x000ba70a22083784,0x00084e9d2a98a2f2,0x00091072e4da23c2,0x000325dceaf86ae5,0x00088f161525f399,0x000211b9d03b17c8,0x000a48d8ac35c984,0x000000000009050c}, {0x000bbfa19d5ef891,0x0006ba818c44b2c9,0x0005e1b560830da0,0x000af35f8715b052,0x00099d8829a9633a,0x000a820f15463e1b,0x00075db18df52d84,0x00000000000d0966}}, + {{0x000ae853a945611a,0x000bed54e2c7c031,0x0009b2bf77ae12b1,0x00005e8e60f7f5a6,0x0008427483adcb41,0x000bff383705db30,0x0006e9f73ba98bf2,0x000000000000220e}, {0x000231b48f25af77,0x000e8c01c46b84a3,0x0004ae472f3bd7a2,0x000dc0bfa3403e6d,0x0007d2202896f738,0x000882e5e098bc68,0x000b13ec0c217a5f,0x00000000000a1f4e}}, + {{0x0009208204f520a2,0x000ed2615c78254f,0x0002b7a2ee7b484b,0x0001d771c84a04b5,0x000fcb9f9e349c3b,0x0004f7846b6fc203,0x000248bed65464c6,0x00000000000eb004}, {0x00040455a574f8cd,0x0003f5c017726a4e,0x000b0a7d5066828d,0x0006666aceb0e3ac,0x0008fc046f0ab78c,0x000aa959518d3c18,0x0004e87f3e2f301b,0x000000000008a284}}, + {{0x0008a96d207a2eb2,0x000e3c899eba3614,0x0002ec9689146ad2,0x0008629da55568ed,0x00082b1dc1d9607c,0x000c001ff6b54722,0x000b8523232311c9,0x00000000000488f8}, {0x0000aca655c2cd82,0x000723867ac9a850,0x00092fe2557b4773,0x000c647a74488fff,0x000fbe0876407398,0x00019a571f6ed920,0x000aeb72beddc763,0x000000000006a244}}, + {{0x0006fe658431a6d6,0x00064b7da79c5a1c,0x000fc6b2b6576354,0x000b7b54aa36d18e,0x0008ed0e30913481,0x00093074c6efeaf8,0x000654eb017bddc9,0x00000000000529dd}, {0x00089f1ff5fdf666,0x000fcf5177230c70,0x000373317732e646,0x00082d34ca267426,0x0005adcd1650194d,0x0007758b7eaeffe1,0x0008194dcec3d9af,0x000000000004cc2c}}, + {{0x0003e55601cd21ee,0x0004794bdc7f4a7b,0x00080eb7c8f212fa,0x000dab0d654cb574,0x00037a49195627e2,0x000d5d0991d4e1e5,0x000de7a1ef570c31,0x00000000000295f3}, {0x000c78902e5817a8,0x000198681b00d89c,0x00061b3376c1d033,0x000e90c6a1b57484,0x000c1222e5544324,0x000d53dd044f9324,0x000ef0e30ba10fff,0x00000000000b48ee}}, + {{0x0004a14fee68295a,0x00041a349bb65da9,0x0006f09eba200d68,0x000d891c18d37516,0x000dae8d2bfba6e1,0x000b330789985aa4,0x000e948baec9ae31,0x0000000000098750}, {0x000e6cd5311f8630,0x0009c0d834bf8a5b,0x000c536623c88198,0x000faaa0c51d098d,0x0002b887a10f0c22,0x0008bed323240404,0x00066231f6a61424,0x000000000001ce0d}}, +}, +{/* digit=15 [{1,2,3,..,}]*([2^60]*G) */ + {{0x000c2532e44da930,0x0009eac6dbdf6097,0x0009dd0474f3e9a9,0x0004de3dc28e1b18,0x0002a66477111669,0x000b08b4b2d039cf,0x0008cea13bbe6fc5,0x0000000000010ebd}, {0x0006e345ee3db6d1,0x000c2cd4720862b2,0x000fcd0516567c14,0x0006303929bfa29c,0x0003818249bfb3f6,0x0007f7cd97c378e4,0x000a1676068c8084,0x00000000000987eb}}, + {{0x000e55f593b72e2d,0x0008c1238e0971aa,0x00081a4c08ea4523,0x00054e7f74c5c514,0x00028805813b4512,0x0005e7a6e238b16d,0x0000bc23987b2892,0x000000000002a1a1}, {0x000c0e8fa1a83cf0,0x00010944c784c643,0x000f1939fa2e366e,0x000ab2aead457171,0x000631c042056bf1,0x0000b8881d5f8f0e,0x0005a8ac062526a1,0x00000000000fe550}}, + {{0x000d9597e54c99bb,0x00076cbbd8575ded,0x000019092c8277a0,0x00056202e6b72a58,0x000e7c024443e5cb,0x0005368f35738ea0,0x00044f8ed06170b5,0x000000000001aeed}, {0x0001a7ce730f30e4,0x0003a3d90a6b26fd,0x000480ba5c428a59,0x00093dcc5612aec9,0x000f99c1bacc0890,0x00043eaadc272ef6,0x00089147db3b43dc,0x000000000000832d}}, + {{0x0001abaa498687bf,0x0001bac92ee14ee5,0x0002ef494748554e,0x000ca876e7a32661,0x000a8456c9af29a7,0x00054326f0f2b7e7,0x000ec87471824e97,0x00000000000364d2}, {0x0007a1e32547416e,0x000f386d8aacd172,0x000735a9921c3b5f,0x000fc881d79f7eb2,0x00040040547d9805,0x000b4e90b377ac3a,0x00081bd39215d461,0x000000000004c5fd}}, + {{0x000bf8e11ac3f3fa,0x000df9ffe5562f1b,0x0000905bb11344f5,0x000f981cbefa3c77,0x0003667bfd643039,0x00040e3df2ab0688,0x0009ca9007a25743,0x000000000005a3a4}, {0x000a64031de3bcfa,0x000fd9c7be629ab9,0x0003fbe0cdc1be9c,0x000ff39e7380dbb1,0x00059facc3b8ffe7,0x000ae422c620bb9b,0x000c432ddcb8cd31,0x00000000000d12c3}}, + {{0x00072db65199d9d3,0x000d703621d34a54,0x0008bb1d8b92a619,0x00000f66ca2933b1,0x0002de1494a2886d,0x000dcdf82d0a2238,0x000832b8656c4d0b,0x00000000000c4a58}, {0x0005f2f5aceb0154,0x0002fa982c1aa34d,0x0006b9fce5077d2d,0x0008de431390c6e9,0x00018c4fe595fc26,0x00090d82fea4160e,0x0009076c427a6367,0x00000000000fc519}}, + {{0x000775c688e983e3,0x0003e8c0749464df,0x000f192d78daad34,0x000e96904bb2048e,0x0004d6dc8b606cda,0x000438bbc6dec959,0x0005a58d26586954,0x000000000001b0e9}, {0x0001e04544fa17f3,0x0005e8189f1141bd,0x000c131e8abc17dc,0x00075a227f8ec1ab,0x0000607e37397757,0x000793e4e7a12524,0x000af4afae84e74f,0x000000000005bf5b}}, + {{0x00039549b6d366af,0x0000aa10292b850d,0x000fff80cff6798a,0x000f18f73ad7a1fd,0x000c5897b11f7a36,0x000664c618b2c7b0,0x00022cf7b9a272cb,0x000000000008f81e}, {0x000e957ffad5963b,0x000663b99b210935,0x000ea3abc7ab4283,0x000175d001db74bf,0x00067159cb8a3af1,0x000de4601526f084,0x000eac6a3c6e1feb,0x000000000008c232}}, +}, +{/* digit=16 [{1,2,3,..,}]*([2^64]*G) */ + {{0x0004c667c92f7888,0x000aaa54768d9e88,0x000d1397d0aa7f52,0x000f203faef6863d,0x0004bd7471b3774d,0x0007de2e9f795a03,0x000cfff0958718b4,0x00000000000e1160}, {0x0005c7ba07a0ffd6,0x0005186ded97af9a,0x0008fa18cb4fab4b,0x0008920424e84590,0x0004eecf8b2b0558,0x00068a6fa3745591,0x00019fe7d3df1fb9,0x00000000000bad07}}, + {{0x000b4e8b4136f0e4,0x000ae2566021f579,0x000cbf2ef6760188,0x00047a5d9f51b6a3,0x000df8efa64634e0,0x0001f584f0b50d91,0x00091cc2bbcbb297,0x000000000000907c}, {0x000fd43610d5f812,0x0000ca7ebeb0dd65,0x0008a7b6eef1e9c1,0x0009a073f5c962ab,0x00053ff74a2fc04d,0x000f0749d95c155e,0x0005d0923c65a53d,0x0000000000027ae3}}, + {{0x000cd3b33afd62e7,0x0003c4d37c266037,0x00042b261375e38f,0x000a2e928ca9d674,0x000a79beb236566d,0x000f801e7a9771c1,0x000358af6b97a976,0x0000000000071259}, {0x00004ab4fe03d3c3,0x000bcc23a5e31cf5,0x000c506466ff69e3,0x000233b1911ccf3a,0x000cfa3b3ace3f3a,0x0004c5f5c93e4664,0x0003c04bdc14832d,0x000000000006abf1}}, + {{0x000832aefb763bd9,0x000f0d5469c7af17,0x0000d7bc962f1b04,0x000ca21a16caa7b0,0x0002e6cc7f39f881,0x000378723221de18,0x00066010d61ab531,0x00000000000520c9}, {0x000ed27c50cc42c5,0x000ac145214ccbc9,0x000ac441f327ce66,0x00059e30cb1fe6a2,0x000a3e299fe79fce,0x000af78cf2e6e77f,0x0001593a0cf652d5,0x000000000003e852}}, + {{0x00087e649fa97c56,0x00029ebbe18b74d8,0x000417a0e476f2ee,0x0005a2a0b24f97ba,0x000262fc61243ddf,0x00003b73af9a400c,0x000fde9ad9b0bc6b,0x00000000000153c8}, {0x0006f3a6ac904b01,0x000f41b6477d9542,0x0008ea414bce433e,0x0007128953069569,0x000db9e775794428,0x00005e0d14b5db01,0x0002f5237edf0bde,0x0000000000085533}}, + {{0x000e220415482512,0x000190791dfa1ca2,0x0007078d88a1aeff,0x0005b77ccedf4f34,0x000d5d965c0549f2,0x0009e672705170cc,0x00017637d9521bd4,0x0000000000086a00}, {0x000e53f005b29758,0x000b5dab44493664,0x0005df02ede5bef3,0x0000c3e4c2506ba1,0x00065ec6f1324366,0x000ac7691b2fb261,0x000eb5ccc4221a99,0x00000000000a576d}}, + {{0x0006b1405a6d6a62,0x0001e3a17f86cedc,0x000ffc614b14d0e0,0x000a3f0927935e2a,0x000ac04d4fb0a86e,0x0007694212f43742,0x00012f32a30bce38,0x00000000000d8d39}, {0x00091bf3c81523e6,0x000ed34154b18f9f,0x0001725c2ac49b1c,0x000be0f9f7a13c1b,0x000a531736e526cf,0x000cfa2c250d50b3,0x000e5f81849773b2,0x000000000003ba8a}}, + {{0x0003089126b94126,0x000854a87307686d,0x000fced9f497ff98,0x000042f427ea198a,0x0001ed259219c1d3,0x0004850cadc59211,0x000e8d0abdbd1623,0x0000000000043b6f}, {0x0004352ff19d9aba,0x00069d3c79d16450,0x00090120dc8bc8d6,0x000535d5a98bf664,0x000dab2cdb2ba736,0x000af89eeacb3b7d,0x00053237d3743ada,0x000000000000b348}}, +}, +{/* digit=17 [{1,2,3,..,}]*([2^68]*G) */ + {{0x0006e0a86f5827e3,0x000e1a68295d9bd5,0x00032e6b7dcbdf31,0x000a0cffe0c3df09,0x000b3cd00a1a8deb,0x0000f90885b4d037,0x000ef7e9edc429aa,0x000000000005847d}, {0x00025d7642f87bf0,0x000f49739d03ced7,0x000f63949ff1cd98,0x00034ff1759060ab,0x0009a7e94dbbdc3d,0x000e8b7f3029e9aa,0x0006f42a3cdfa0f7,0x00000000000bbd8f}}, + {{0x000178a4d4ad7d87,0x00040cd8c2ec862e,0x0003f7b9dc665542,0x00086d4db83e1ac5,0x0002bb549bb5e123,0x00007c0f19a79203,0x00008eaf81cba628,0x00000000000abf20}, {0x000001ed540ad4e0,0x0000a9d7a72302a9,0x0007110b90df5c50,0x00024daec9005170,0x00037193eb3047c3,0x00015c655408cd0d,0x000c228f0bcce2d3,0x00000000000869d6}}, + {{0x000e5354c88a38dc,0x000717192a26df13,0x00059c532d5dc6ab,0x000195620aeab120,0x00057c2328498938,0x00079bc39ebe39dd,0x0000925787970e4f,0x00000000000143e4}, {0x0006e01b286241f3,0x0001e5f60303562b,0x000cf202635ec6b7,0x000b3a2f1856e619,0x000bbf77d65c7ec4,0x00011058fbef7dc4,0x000945b444d50670,0x00000000000c33cb}}, + {{0x0000e30b66c01c80,0x000354b5e753d742,0x000c1ca06540fdb4,0x000d75f42fa905c4,0x000ac33e462b4034,0x0008de3bb89b85ed,0x00039131f413c305,0x000000000006ba75}, {0x00046bc0a659bd1e,0x000573f50020190e,0x0006ea7059f1f5a4,0x000aa10efa2adddf,0x000e1a6566aa7297,0x000b4f2143e8ccdb,0x000ae74dfda07fd7,0x000000000007cb1c}}, + {{0x0008cb34259001d3,0x0001d49d1cfcc46a,0x0008f80188e0d2b9,0x000d285d2ab0a996,0x00071df5b6cb8cd5,0x00003fadd9c5cff6,0x000c0019f4095a30,0x00000000000aa463}, {0x0002c2d4a3652c8f,0x00087f86673b013d,0x000814cd905b85f4,0x00075b44cc2cd5ed,0x0000b0342517b376,0x000817cd771d5262,0x0006183af1f31657,0x0000000000079199}}, + {{0x000066ce8afe9a22,0x000815600fedffd0,0x000fa276d4e1e61e,0x00062674cb08e4e2,0x00052e9ab52d8f12,0x0005686adfab0c1f,0x000e4e090b1ac94c,0x00000000000bb10d}, {0x000c301d650cbaa8,0x0003b3383f48546f,0x00045006d2b6b386,0x00092fe500058f01,0x0007f4ce508ac5ab,0x0007a5166f03c7c9,0x000d66525ac2cea7,0x00000000000996ef}}, + {{0x0002ee0f55870dbe,0x000f522daed9eb3c,0x0008bd7a619de4ba,0x0007daa46ec27562,0x0004df0f7a076593,0x0006036c14c58eeb,0x000aa5eb972393fa,0x000000000004d17f}, {0x0005a44cb91701e0,0x000a3de29c31e831,0x0004699fe7072908,0x000952e2c563ddbf,0x000e5d6b0b57ac00,0x000c4728203a767f,0x000d56e858fdf3a6,0x00000000000a5213}}, + {{0x000b5ed7b705b7ba,0x0002631796c22d0c,0x00099ed65d60e408,0x000cb716cb0c301b,0x0007d1702ca94ff0,0x000a02a90dd0cdbd,0x000625470a26c8e1,0x00000000000d7054}, {0x000218ab60af89bd,0x000e0fadc2e8673f,0x0000890003c99982,0x0005ebb2951a8fe7,0x000364197a76042b,0x0009c1b5de4af9d0,0x0002b1dd2c6bb324,0x00000000000f0193}}, +}, +{/* digit=18 [{1,2,3,..,}]*([2^72]*G) */ + {{0x0004ea16a709d85d,0x000329ded9b0ccd4,0x0002e9bda4d583bd,0x000aaf5393937290,0x0002a438413e94f3,0x0003c7de32213686,0x000540449286da37,0x0000000000029aa1}, {0x0001d592acb2cf64,0x000ef1bd13e4055d,0x0004681cce9d2c6b,0x000558f6bcd0cb2e,0x000e9e610369d43b,0x0006e0651f5757c0,0x0000aa15c80b23c1,0x0000000000000182}}, + {{0x0004d40f93bd737d,0x0008c10a8aabc8f9,0x000d5b1177a72237,0x000df1a076945a2e,0x000c03861f02a009,0x000866a3cf869152,0x000cbbc405226e9f,0x000000000008b41e}, {0x000cb1b314f36d3a,0x000bab5c9ed101e9,0x0005d83bc9ae2498,0x000f22e57589279a,0x000d7fe2d6aa1a9e,0x00073dbfa83ef607,0x000066f2da845434,0x0000000000057879}}, + {{0x000f91047abd3166,0x000593df98ea92d5,0x0002ec06cefe6ff8,0x000d1b5ea6d69771,0x00097e25ffbcc9cb,0x000a6280e3f9f231,0x000713bca8e0567d,0x0000000000035cda}, {0x000fe70b79caf906,0x0003946ef321cfa3,0x000b4a657c54ec43,0x0003b4b51de40452,0x000cccd9ba8d37b7,0x000f7045b5bccf3c,0x000dcca2ca080dd0,0x0000000000068cf4}}, + {{0x000d265e2cd7626e,0x0007e3499b44b9a9,0x000ad7706fd7669e,0x0000406c1f517d80,0x000b82a174e83014,0x0002c9b3ad4b3c8e,0x0006f4c8835b13af,0x0000000000044371}, {0x000fa90f05b33562,0x000c2336c4f4b966,0x000385e7d9f805d4,0x000a2dc828c34d3a,0x000c34d0d1f76ffb,0x000a4fbce257a345,0x00049fbc1eff056c,0x0000000000007683}}, + {{0x000db1540add72ad,0x0009e5ebdc79cc93,0x000baaf845cf7653,0x000efe79c8b7f7df,0x000ac469aa5793f6,0x00033c455b2f1e40,0x00012a882f0e9434,0x00000000000aea07}, {0x00030f4a7dec8786,0x000e9b13578c31bc,0x0001af154c9f03fd,0x000a2d854e09133c,0x000cc6ad853283ac,0x00004f75cae03943,0x000c37ce0a619171,0x00000000000f9838}}, + {{0x0004bc7eb2d5ec5c,0x0007e9db114e2be8,0x000c421a1f0f05da,0x000016bd2f3080f0,0x000fb9b7203704df,0x0004fe2ab0cb3f7c,0x000ec1adb877c781,0x0000000000037761}, {0x00081bf9c70c3c38,0x0003cb5d6068d8ec,0x0006b75a387ed168,0x000aa5457d36d422,0x0007423cc8cb39b4,0x000a6566dec1de46,0x000f55280e02dafd,0x000000000003ca55}}, + {{0x000e1cebdad8aedb,0x0006b340d77c218d,0x000b7391085bcda5,0x0005b028b74d32db,0x000a3cc1117e3e91,0x0006c5939ae7101c,0x000caa3c36152b52,0x00000000000d3ec0}, {0x0001039f162ada74,0x0004534de058e1ef,0x0005d23a486e5201,0x00030efc214ac0e4,0x000cc7100acb27c0,0x0009097b72a216d1,0x000aaf3b73004330,0x000000000007afd8}}, + {{0x000af1b588df6219,0x0003a5d7afe99881,0x000b20bd69a8d3f2,0x000067dc65234936,0x000527557f5de39a,0x0000e9f9d3458527,0x0002d8756b8d8693,0x00000000000040d5}, {0x0003845ac0bf2beb,0x000a9606eb60a92a,0x000238ad785ef768,0x0005748e068d2949,0x00022fce158da621,0x000183c8f73fbdca,0x000c989cfee07dcb,0x00000000000a5e03}}, +}, +{/* digit=19 [{1,2,3,..,}]*([2^76]*G) */ + {{0x0000e52cf2e9b4ad,0x0003f86230933fe6,0x000fe37b1c8aab75,0x00086ba6f595ed40,0x000de2284a5801e1,0x0009e5e25d3291c3,0x000f5303dee2311b,0x0000000000015cc9}, {0x000f15883981ad15,0x000444fba15675de,0x0008ff144b8a465b,0x0001eb92532d015f,0x00084e7455de8690,0x000f811c94396fd7,0x000b372fbcea8fbc,0x00000000000ae952}}, + {{0x0007195bc501819f,0x000f06bd2c54c87b,0x000c8e0d99fb53f8,0x0002654e3eee748a,0x00039598d90727f5,0x000cb371256f2058,0x000c5b5f91c2d027,0x00000000000a3e33}, {0x0002b15fc69c25d9,0x0003e248490a9884,0x000516ef1dee14b6,0x0008b3d74f7d38ca,0x00002fb602142013,0x000033d4eae791f6,0x000f176b4fb300bd,0x00000000000bdfd1}}, + {{0x000558e7c27dd125,0x0004d9bd2b68cfc0,0x0001783c86b4626f,0x000f35989586da1d,0x000afd0944ca67e7,0x000569b5abc04c8a,0x00046eb8db5424f0,0x000000000000cc55}, {0x0008ec9be17ec8dc,0x0009e8f0ef9decbe,0x000cdc094579a394,0x000eb644e7329b8f,0x0007e6896b042ec1,0x00018b6bf3e0e7f3,0x000fa6ad2bff11c1,0x0000000000040f93}}, + {{0x000fa586c442030a,0x000a30c3d2055f9d,0x000061ff065411bd,0x000a98b1fbf56cae,0x000f396e31cd1b68,0x00082c03b56fd85f,0x000917d2ca584443,0x000000000007d3ef}, {0x000572f96fe58801,0x000c74129a730d28,0x000ce4a000ce9071,0x0004180653f3b241,0x00049ee066bd9e85,0x0002ea5fee65a1a1,0x000e2e3420084e36,0x00000000000c7911}}, + {{0x00079bb68a21bf45,0x000b04c3f4f487b8,0x000f5bdc807ffd5c,0x0009bad1844be875,0x000e272afc140fbd,0x00040a7386b3b80e,0x000a37d727b0b6aa,0x000000000004d809}, {0x0001886f07e4e9c3,0x0004c09fb0640689,0x000e568c8f4da447,0x000ff8ad73a211ba,0x0001d9a6b97da7e5,0x0009e8f56ccdbf62,0x000a0938448e2cc8,0x000000000002126d}}, + {{0x000bfb3f1befeb61,0x0004c43f0ae67505,0x0007b68cdb6c3beb,0x0006c25dbb4492ec,0x000884bff97fd5be,0x0002da2e27efc9ee,0x000c3254fbd9d706,0x00000000000c6d2a}, {0x000d04af3852eaac,0x0003e14cf6dc0935,0x0006b6f8f3aa240c,0x0006543d9a16800c,0x0009beb1e28dd056,0x000e658339cc2ade,0x000cb2cbfeb45038,0x00000000000d0f5a}}, + {{0x00014927529fad7a,0x000714f10299a19b,0x0007bc14eebc4178,0x00018bc0cbede41f,0x000e6b03ac7d024b,0x0005213be7883c01,0x000540a7b99e741c,0x0000000000085a97}, {0x0007979358dabc76,0x000060b6fe59caa3,0x000a32d2efcf0218,0x000969d6ad1891a4,0x0003ee7761dccaa0,0x000b12539c47afe1,0x0005f4cae681fcdf,0x0000000000002ea6}}, + {{0x00033b53cfd1d032,0x000865e930d64f49,0x000e6882e13322aa,0x0004f7efa08bd4a8,0x0006a6e10f64cfac,0x0007ac162277e845,0x00068b41be306740,0x0000000000052a9b}, {0x000cf81e872685ed,0x000e28d8d216a150,0x000406cac9d54222,0x0004102c60d54c43,0x000028815187ad9a,0x0003b8e59b09420f,0x000ba1881179c60b,0x000000000005b09a}}, +}, +{/* digit=20 [{1,2,3,..,}]*([2^80]*G) */ + {{0x0002bb0ebd1ffa8d,0x0000c22313ded9b3,0x000c76c37673c0ae,0x000eeaea76ec3812,0x00060275ad3643d6,0x000095bdaa165513,0x0004b0e5c1b65adf,0x00000000000367c4}, {0x000f3876ae1976b5,0x0007de2b419c1bd2,0x0005d5344cebbb0b,0x000e51fa2baff060,0x00006269b5d0b5fb,0x000e8d667a0594d7,0x0006e70b07b70523,0x0000000000063e01}}, + {{0x00082243f0134f99,0x000d9022aa09c335,0x0001e1b9a8966dc5,0x00044c5b38b417ba,0x000b436451ec3173,0x000b1c87629a74cd,0x000ffdd898eb6ca8,0x00000000000b74ee}, {0x000187e3675bea14,0x000410d9eab63bb0,0x000dd59e68360fb6,0x00094ce14dbff2ff,0x00092706528037c8,0x00029a0cd3704d34,0x000c4f9ee435d8ba,0x0000000000009c11}}, + {{0x000414827bc8962c,0x000552fde4893802,0x00000bdd0aabfbb8,0x0008a5b09456ed5c,0x000925797c6c157b,0x000c14c0673606a7,0x0001caa9d0f47c33,0x00000000000faf97}, {0x00082453cb3879aa,0x000ec6e763c509a5,0x0006f45dc5dfe238,0x0007ecbc49e9efce,0x0007b38f2b59d95b,0x000c397db0c31792,0x000bc797912b53b3,0x0000000000045c7a}}, + {{0x0002600fe807b0d9,0x000578b3269a1894,0x000cd6a11a8caa23,0x000c714e428865d4,0x000ffdaba094bc5a,0x000d657f2531dd17,0x000bbf86d2405718,0x000000000002f99d}, {0x00063a9cad22b4ec,0x000d1c428a80ebb2,0x000111bbf67dd9f1,0x000691922a5d2566,0x000318a18586a752,0x000f633b3bfe6392,0x00029828a0c772fc,0x000000000003f3c5}}, + {{0x000cdc4baa08bf36,0x00052cd81bdce7a2,0x0009dbe6198554f1,0x000228bf8ebe39d1,0x000eb2cdd8524cb0,0x000e9b3af496a9dc,0x000f8a0f115a1ad0,0x00000000000d8eee}, {0x000de9efc567fd4a,0x0009b5232a514417,0x000762e720496fa2,0x00018b08994b4e8e,0x000809097a52289d,0x0004621d0b4e346a,0x000ab8c641510f32,0x0000000000095a41}}, + {{0x000c5913c30a847d,0x00004c8c9b0adae6,0x000c6088d1ec2259,0x0007946e62c508f6,0x0006e9fe2321b03b,0x000c1d1366042592,0x000c9c73b10bba80,0x000000000009d218}, {0x000e72b1483512ee,0x0006d6ed0c8eed83,0x0009abfdad8b62ec,0x000096ab9e96167e,0x000cc473e3773078,0x0003a3bc8b28f0e6,0x000796b44e499568,0x00000000000d3523}}, + {{0x000ec81c53fdc5cd,0x00095261578c7817,0x000dba0eec8c348b,0x00066b414c803900,0x0005faa7cc399932,0x0009b7e27bacad75,0x000533418c4defd6,0x00000000000ae751}, {0x000b26e534337f55,0x000f36f3bd3298fb,0x000bd59fe7197151,0x0004f73dc4c54ecd,0x000d44d3d74eb716,0x0009ea511ca66290,0x000c49f77c62424c,0x000000000001f714}}, + {{0x000343bd88e025df,0x000b893a62e7c716,0x0003b75e6fa4a448,0x0003cbb10cc95456,0x00062f37154c265e,0x000f2e08b28cceb0,0x0000916b79b0713b,0x000000000003ab39}, {0x00046ae52480b7d8,0x000a750a8d04cede,0x000f3c798fdbfa72,0x000336ac21cc62f0,0x00036fc004503db4,0x0004b2d954747f0a,0x0007a7067cbf1c54,0x00000000000fd2be}}, +}, +{/* digit=21 [{1,2,3,..,}]*([2^84]*G) */ + {{0x000f8f632d3f21bf,0x000880233e423a7e,0x000fc3a5113e93d2,0x0009cef6349e35be,0x0003ded2ec542ca0,0x000dded3d3b70afc,0x000ee0c813474d52,0x0000000000012f00}, {0x0002c304534f52c2,0x00002a0908f763fa,0x000cccb3aba1eb57,0x00010c134b6a8e10,0x00056e7c163e84ad,0x00057e0c36f37fd9,0x0001a27caae8c8d0,0x0000000000055372}}, + {{0x00086fa76217d20b,0x00015a354c1de108,0x000a55c4648be905,0x00010999d532bbe4,0x000f520117516766,0x00059e35eb7c2f4c,0x000b7b6945d34ff6,0x00000000000a1303}, {0x000495f21c8085bb,0x00028a200ddba08f,0x0003caf84b1e53dc,0x000445faa82b46fc,0x000cfccedc1b3018,0x00053e29fc3e6a3a,0x000547e86ae87033,0x00000000000fd7e8}}, + {{0x000683184a93e477,0x000a4728c8e14128,0x0003d8bece755c7e,0x000c2da4796df734,0x000e00a55efc3016,0x0006b1cb8f6d79e4,0x0005a94fced26952,0x0000000000091f16}, {0x00031165825c7f6e,0x000cf528b857275f,0x000d8cb6dce0ced4,0x0003520e07bb990b,0x000f4ea8ae6b4f90,0x000b735bb07ddb97,0x000d4a29c01e70b3,0x000000000005000d}}, + {{0x000f814f4e7d6929,0x0005e306b63e3665,0x00098d89bb61e0d2,0x00068898bdeddea9,0x000d67a329ac36bb,0x00092ccce9331655,0x0009b414c7fe26ba,0x00000000000be051}, {0x00042824d37928be,0x000830dc39dbc42d,0x00083d595f84e0c5,0x0008818fa8682bba,0x000db60aad97c7f7,0x0002c64cc43396ea,0x00043e751784d7ff,0x00000000000866af}}, + {{0x0007b94e1c1e3bf9,0x000a53742b61de85,0x0004d0debb63955e,0x0006787abce34016,0x000ea4cb41b4f52c,0x000ca817e4749711,0x0000487ce0dfb03f,0x0000000000096e85}, {0x000c4c6d7efe5c7c,0x000b6cd65250dc1f,0x0007ec2aec96d815,0x0003cb2b4dd561a2,0x000abb5379f57352,0x000a847ba15ba773,0x0002decc5e62d6c0,0x0000000000004d85}}, + {{0x0003450b4a8e849f,0x00036f0a69e68100,0x000d9356a0504fb6,0x0003ab7cd14af1d4,0x000d558d555d773a,0x000e63dd6c0b88ed,0x000db3eb12d197d2,0x00000000000bcd9c}, {0x000ed15d1fefd8b7,0x000fa06432985766,0x00052d6c3d3a4a47,0x000f6164171b9bc6,0x0009bbfcf90abd28,0x00036084d3778163,0x000a751f93898f3a,0x00000000000dd00c}}, + {{0x0000e82da9d478f7,0x000ae3b8d8e48b47,0x0000534e09405090,0x000430c2aad8c684,0x0006b82c16731d72,0x0000fb41de8c5d50,0x00034f989978868a,0x000000000000f812}, {0x000d9518cbfe70fc,0x000f1a0c941ce78c,0x000c323a8cf0aba1,0x000e296101f89af8,0x0003ca6a3227aa7d,0x00064ec0c4cadd8e,0x000db43b4db51f27,0x0000000000009256}}, + {{0x000e28a122d0f32b,0x00022b9207dbc085,0x000dce5b9cc6b932,0x0004e5534ba150b8,0x0001dfec99724992,0x0006f870d2935ebf,0x00085c34bf5e94b7,0x000000000004c203}, {0x000bdbb9ed40b2b9,0x000c3c78ac1719f8,0x0008866adbfa0f7d,0x0007ee4cfb4b8bb6,0x0002cd8724b676c6,0x0000bc1efecfaefb,0x0001b5e9bc3d6734,0x00000000000ca554}}, +}, +{/* digit=22 [{1,2,3,..,}]*([2^88]*G) */ + {{0x0004ccdc054842bd,0x000704f293478100,0x0000ca74cad5c267,0x000c94f64d55f6f2,0x000d725c51251bf7,0x000b6a0914489b57,0x0000fa3aa4d43ab1,0x00000000000cf7a6}, {0x0007fef943134dbd,0x00038aa918a4ce7d,0x000eee4d56ef907f,0x00000a16812a03d0,0x00070b0a1e4bed0e,0x00028386bb09acf2,0x000321c73a41f7ac,0x00000000000f4cd1}}, + {{0x000b2804db21ede5,0x000fd10a53b8f9a2,0x00080087f23a6e5f,0x000513fabef2b974,0x000cd3f802fd740d,0x0000627afff6cc47,0x0002dc1be6825beb,0x000000000005886c}, {0x0002ebc44567c313,0x000afb6cfb2c6b07,0x000e1dddbc404a5d,0x00016f53a5a485ba,0x0002e7b2223e7a1e,0x000a13a9b16b60b9,0x0001a2332f33d836,0x00000000000876cd}}, + {{0x000bcac1cf1b2eda,0x00095802f495c1f2,0x000e55ffc912d44b,0x000b294e9b3f0f6d,0x000033cbdcd1eaf3,0x00083fce582cc760,0x0004cc1a5642278e,0x00000000000ffa0e}, {0x000dada72c71a95f,0x000ed7d93e9766ea,0x00015d2d9c24e57f,0x000dd79eafe5f361,0x0000fcaafabbcb53,0x000053efecbbed8f,0x000b7a570472705f,0x000000000001ebfe}}, + {{0x0005f3669cd44c3c,0x00025a896d28dae1,0x0002e7c6820a84bb,0x000fe8c06fb15cd6,0x00061cdffdad1bba,0x000119b3a2daab29,0x0005a3984defc8e1,0x00000000000de2a2}, {0x0000f914a19c745f,0x000b3a7f54ecdb35,0x00041f75def22ce4,0x0000efc6a3b94437,0x00076785163b6913,0x0002b1d0a5d17f12,0x00093cc019911b17,0x000000000007e3e0}}, + {{0x00049fc81e69d5e0,0x00085d307d4279b4,0x00039a33441f2443,0x00078371531d6263,0x0008b42639ecfff7,0x00099fb76fdd61b0,0x000f0eca9462e7be,0x000000000007c3f2}, {0x0008f656f3641bfa,0x000f85c07066bcc1,0x0008bd883c4e6617,0x0001387d93ff4937,0x000b864eed19b6d3,0x000fad6382fd7d67,0x000fe667b707ff5a,0x00000000000d0206}}, + {{0x000bb568a2a2f3e3,0x000a9235455295a9,0x0008072539522964,0x0006d10c75720aab,0x0009f6a0df88ac83,0x0005a9c96ea2c538,0x0007bedfbf31519e,0x000000000008cad4}, {0x000d6b001091ce3f,0x00036dbd5de982e7,0x000e935fa43e76d4,0x000fef6324ba9235,0x000e8f14a2f5a2bd,0x000880ade8b0f981,0x000d4a590de1c45f,0x00000000000107f3}}, + {{0x00091e8b5ebad75d,0x00009b03d47621b9,0x000da50c79b05bb6,0x000ca72548723c56,0x0007c944e3849da9,0x000947973a12e40d,0x0001ea403dbcf2cc,0x00000000000c6ef4}, {0x000f1cf0966fef48,0x000d74ccc2856b9a,0x00011bbeae1e30d2,0x0007f7e43ee1576e,0x000a0a894961701a,0x000396f6e7f061c1,0x000ca956059fb88f,0x000000000001a91f}}, + {{0x0000a27b9e3336b7,0x0000be185bdc20d5,0x0008a8bb1575f81e,0x0003397c3fe5695a,0x000f61f6a04f1f6f,0x00090a92b6c9f3a5,0x0004543c0f9d4bb3,0x000000000004793b}, {0x00055e696b3d9202,0x000d991ad0c33a93,0x000c4d967cf46a4f,0x000d90565d53c83a,0x00034176007dfa24,0x000d1623cd63e583,0x000345741089fd2c,0x000000000002685d}}, +}, +{/* digit=23 [{1,2,3,..,}]*([2^92]*G) */ + {{0x000883b867d2fbb5,0x000271d51015761f,0x000afd0328ae7e6f,0x0007e2fc6dde9e2b,0x000937d5bb1f2ea0,0x000cc6e28ceed9ad,0x000fc43121994b98,0x0000000000067ad8}, {0x000d53a60b81c5b7,0x000ca34707fb3d11,0x0005e1e4ff2b5765,0x0009b8d81ef6cb57,0x000b1223a9a1fe93,0x00074cf375c51e8a,0x0008e18f6d7993db,0x0000000000097280}}, + {{0x00067952d0358e02,0x0005b0db3322730d,0x000098edfd5f000a,0x00085380e8a38fae,0x0005769360d86efd,0x000f27ef5c1812ea,0x0002e8505723dc76,0x00000000000f35af}, {0x000764970d5cb557,0x000849f7bb7fecc3,0x00052323da5066c3,0x0007549773eaf7f9,0x000489d51bda0118,0x0000ccde605bbbba,0x00087d52cabb0664,0x00000000000e7ff3}}, + {{0x000fa071b96c7c7e,0x0009c70187dfb0a2,0x0000f19decc5bd43,0x0008b816a6c0d616,0x000d6a27e97b3018,0x000a389aaeaeda67,0x0002734a5192826b,0x00000000000a2bf1}, {0x000832bf68c7b455,0x0000c8ff10656bdb,0x0008bc56c7023546,0x000a3e11dc7aed54,0x000b38853d61e34b,0x000cbf658c457048,0x000edde89825db1c,0x000000000006b255}}, + {{0x00067336ad6a8789,0x000d0c377b3730db,0x00063e31dca6f13f,0x000f2adf39b68951,0x0006bd6da22ed9c2,0x00009678e1bbff10,0x000e783f7e5b8e7e,0x000000000007ed3e}, {0x000a0e3ab40df97f,0x00071689e6b30fb8,0x0000b670f8712d68,0x000277edda78c55a,0x000cefb65cb717d3,0x000a30f0ce686cac,0x00071e758aa1ab19,0x00000000000b11f0}}, + {{0x0007d3d2024290f7,0x0000c0bef2d25159,0x000b908d7c494e4d,0x00017cedd4af7aeb,0x000bc8e88ca42c24,0x00020d15452b5b3b,0x000d4bc00328c44f,0x0000000000030af5}, {0x00053687c2073cc9,0x000dee8bacbeb2cf,0x000bf613b57931f9,0x0001da61d9e70314,0x000c0e70a331b67d,0x000e325772ddefcb,0x0009797d09bc6d61,0x000000000005b52e}}, + {{0x0000d7a5438e4dd1,0x000b5d40f36e5e3e,0x000702a395a7941d,0x00094d7cc51dbaf1,0x000f0edf8bf9e340,0x000b5e16520f93f0,0x0003a8534b75aa23,0x00000000000dc1b7}, {0x000196b771cc1d7e,0x000b09dd48c40ca1,0x000664851f0b3766,0x000f8a2a9ffa0db3,0x0004d94ed9bd4212,0x00069cb198d5236c,0x000dfc81bec489f1,0x000000000006104e}}, + {{0x00076550d0174653,0x0008d9cb21b56311,0x000fe59ad5e35eee,0x000a67100d7b34c9,0x0001a6c1b0c3e3f3,0x0003c3e31d4bcb3d,0x000be86ebd26fb9f,0x000000000002dc79}, {0x000582f4b4dfea09,0x0002ae7cf9a0a1f3,0x000c37b50dcbdab8,0x000320e69e1f08bd,0x000b946f83d78b0e,0x000a399ad2a8caf9,0x0000866daff0ba98,0x0000000000038ed6}}, + {{0x000af81ab2009a09,0x000fc16f3708ae33,0x000f381b02290f16,0x00015b227bb71a8b,0x0004162f8b5597a6,0x0001e3fb9a8b9a86,0x000ff680ee8362d9,0x00000000000f83a4}, {0x0005ffc830c362b9,0x0009507a7873a90a,0x0008c2637b53ccc0,0x000683d860d60ba4,0x00071f87d32a427f,0x00050319dea99592,0x0009ceb2ac69faa0,0x00000000000d2d0b}}, +}, +{/* digit=24 [{1,2,3,..,}]*([2^96]*G) */ + {{0x000fbfb66a502f43,0x0008324480c57881,0x000d6a55d7a45e41,0x00002c3273e2bc82,0x00053ef1ed4c7350,0x0004948e88c42e9c,0x000632028babf67f,0x000000000008a978}, {0x0008edce917c4930,0x0001bf5f13a4625c,0x000e9dd4dc6a263a,0x0006bcc37232768a,0x0001576e8c1830f3,0x000bcb766c5317b3,0x0004dcef1d57a69b,0x00000000000b3e3d}}, + {{0x000aa97e11eb2f75,0x0004f53ebbaaea28,0x000f59d2921161ee,0x000f25d340986b44,0x000e3365312a3c15,0x000641f96c5925d2,0x0008e4c35d3ee251,0x0000000000098412}, {0x00032040e2f19c59,0x00029b41a21a75a1,0x0005c4225a472860,0x000f4c0faf5663dd,0x000a0a62c9dc4ffc,0x0002d60c5889d285,0x000be50908665acb,0x000000000000a131}}, + {{0x0006f87a21caa381,0x000a6318feb4c006,0x000ed4b6b2c3b939,0x000786d5b2386621,0x0005a722c5911e4a,0x00006cb0188e0430,0x00036438eb062af4,0x00000000000e7216}, {0x0003e9f2fb9e0c73,0x00093450c1d28f54,0x00023904331c181f,0x000a53a6f6c06813,0x000a25eac032fe46,0x000c497224553199,0x000a2941fa659aff,0x00000000000bbcb7}}, + {{0x000a3dcccc791733,0x000a8c0de60f43c9,0x0004454fef6e3630,0x0002aa8e734e2e0a,0x0003ef773db6f412,0x0002d71c508f40f6,0x0008250a7e9484ce,0x0000000000078a3f}, {0x0005a99063a64539,0x000ef0cac7a5b50d,0x000064e61e079dfa,0x0009a90d3e181458,0x000a0aadf689ecf1,0x000f0acf70d1b062,0x0002b942299f1ff3,0x000000000005ac25}}, + {{0x000b4c356075ce0d,0x000a8a4bfe150fb5,0x000907dbaf6f1c40,0x0008260a0ee708f9,0x0004abc9d5f541e2,0x000aae99eff4fdff,0x0004d96ed92241ff,0x00000000000c04fe}, {0x000731763369357f,0x000a8f10a173e2a4,0x00065723921ac826,0x000823f8ed02e85d,0x00042e522dc1d2a0,0x000c939fdffa78cf,0x000bba07041e4600,0x000000000003a9a8}}, + {{0x0008012ba5de4e7d,0x000c7a1fc20f7144,0x000540a292e6e434,0x00081c28e2e8e16b,0x000a4c4562342e55,0x000e31ad4912c80f,0x0008117fd61fb9e9,0x000000000001c19e}, {0x000de815bbe3ce38,0x0003b6a7ab2cb6d7,0x000aeaa95e1796a8,0x0006a85ab06af4e7,0x00044866378d33f7,0x000826f8cda387e5,0x000cb6bb71deb856,0x00000000000eb64e}}, + {{0x000d7e72d8af89da,0x000ba0e93593424a,0x000584230569d130,0x0003dba8e15d8645,0x0001cab64644ab77,0x000fff0619cea4a5,0x0006a4516754d72e,0x00000000000cd3a3}, {0x000ee6af7eb6909f,0x000c6c7d352abc75,0x00007221eaa0649d,0x000ed979199938f5,0x000acd6f34958a8a,0x0005f93eeeb06789,0x000851c51d776677,0x000000000000a8af}}, + {{0x000b089742823cef,0x000c544bfd166199,0x0008c58b08cf9fc3,0x000cf81c39366838,0x00068b08680fe50f,0x00032aab0c9b4eb0,0x000ddaf90882c528,0x00000000000ecbf5}, {0x0004bc1447794cdc,0x000f8fd4d51c6fd3,0x000cc355ce034b68,0x00053dbfb187c34f,0x0006f8ed037fb729,0x0007bad45166f7f2,0x000808d2b1077a09,0x00000000000790dd}}, +}, +{/* digit=25 [{1,2,3,..,}]*([2^100]*G) */ + {{0x000273ed4a6f3c1a,0x00092a05c751c876,0x000bdb5d554c8320,0x000e26cf4c98fee4,0x0009e7b3a7c79c56,0x000cc16466084f8b,0x0000bca0b042f6de,0x00000000000fbf3a}, {0x000078eb34f9801e,0x0006694524c2c1cd,0x0008ad2d5e6f66b7,0x0002d6e7ce1f9f62,0x0007fc0c34fa1879,0x0000a16938ebc2fd,0x000019032a9f4178,0x0000000000056a60}}, + {{0x00009be19d72cca6,0x0009ea4b957d1c55,0x000c88712c99979c,0x0005e80a271d9e14,0x00044b9367e51157,0x00079779f0fff68d,0x000f68f55ba67322,0x00000000000d4d68}, {0x000ebae305d14369,0x000b401474ab1533,0x0007e0884a0d1ea6,0x0003a8336111d25d,0x000fab531cef6390,0x0002ed86737342a5,0x0007e1d3c93fe770,0x000000000006279f}}, + {{0x000ed609fa3c6148,0x000beb398290bf69,0x000b5366c9b47f2a,0x000aa2956560b89f,0x000c50e6647b3e71,0x000be42da80817aa,0x000a4e35c833ada0,0x00000000000f1bab}, {0x000a4dc6e615148d,0x0009ac57be644e77,0x000de3f8f9ac6cc1,0x00077310defd9095,0x000e899cba568300,0x000effb5a92fe9bc,0x0004bf48450ec4bc,0x00000000000f2f5f}}, + {{0x000e1a6a67c12c1b,0x000e7dccf68bc63e,0x000af5107f8ecb57,0x000e199254dd3e41,0x0006ddce5c84e43a,0x0000b4258e8526e2,0x0004c452bad815ea,0x0000000000009457}, {0x000fc838b5157d7f,0x000e1a5362fcad0f,0x0003a5c9b577c868,0x00012b5eeffc2cdf,0x000b14de4e5b0f93,0x000233fa55475657,0x000ec2746e67d4f0,0x0000000000035471}}, + {{0x000afd6c233d63fa,0x0009cf55edabb6d7,0x000b353b7e2a9194,0x000822b9bf171614,0x0003afe808dcf53e,0x000272f554a5b3b9,0x0009a1590bbbded7,0x00000000000eaea7}, {0x000101d093edb837,0x000b5d7042bea6a3,0x0006a766d7a462c5,0x000e69031078aa66,0x00087e37bc8bd8d1,0x0000089759e837f1,0x0008679558ff4f85,0x00000000000421fe}}, + {{0x00076617121c3ac1,0x000a13503d9370d0,0x0006e1d369d53e18,0x00001ef5b52e0f07,0x0002f955b5fa67f1,0x0000e0569b6b5b4c,0x0003efb5f03d5388,0x00000000000c9939}, {0x000c81fd72768469,0x000a690755bd5e4b,0x000324dbfd474da1,0x000fd519e9ce792e,0x000396ccfa14326f,0x0004a22de1b772d7,0x000342652710f487,0x00000000000db210}}, + {{0x0008597293bd01e8,0x000dfaa6489def01,0x000dc630321a7c29,0x00043a95fa2efed7,0x0003720e1a8c4d89,0x000a4f8a3c9baae5,0x00006bc055444b95,0x00000000000a7c12}, {0x00017016dee8b7c9,0x000dfd97765b5926,0x00050b911df827d2,0x000c35af1503b16b,0x000fa9fa21f8115c,0x000fed1f11dd5359,0x000679197c32996d,0x00000000000f77f2}}, + {{0x0004d7575fc73ce2,0x000ce58d6998db75,0x000d11d5d661c62a,0x0002a0165739fcf5,0x000822f7a073420b,0x000042f005c5db30,0x0003d9016c547805,0x00000000000a1241}, {0x0008aac8eaa9ff4f,0x000fe8ceb2d6ffe8,0x000f806ab6efe1ae,0x000d012339c146c9,0x000628ac05552638,0x000d46e6302fbb7b,0x00088e7fcb0c8162,0x00000000000066d0}}, +}, +{/* digit=26 [{1,2,3,..,}]*([2^104]*G) */ + {{0x00029831f2b8ed10,0x0004917e3d0b77e8,0x00062b9d59b96ed5,0x0000261d0bb1849e,0x000ec71a3bbef8ef,0x0002a88ae9b804ce,0x000b9e00b7d17154,0x00000000000e9097}, {0x0001f74d24b8094d,0x0000cdbad9f12075,0x000917cb364517bb,0x000834fb83debf54,0x000d637e449ba8a4,0x000b82664c3ee226,0x0000e8e3070d93ca,0x00000000000b3732}}, + {{0x000cd133b578c566,0x0004bb506b7b86f8,0x000a189da5b723c8,0x00029ad3789281ee,0x0001f9af456164b7,0x000f9186069ae8f8,0x0000fb007befe156,0x00000000000edc25}, {0x0003b5e8dc3a9219,0x000ab1c16d7598b7,0x0000fdec987e0e87,0x0007da936881f89e,0x000103a5b1ea5dc9,0x000153a0faddb603,0x000ee27eb515b13e,0x000000000002b4a1}}, + {{0x000bcceb06f924be,0x000d4e6b739c7071,0x0004a4fc7ff778b8,0x0003acc1b4b45493,0x0008f6bad44a14e3,0x000020972d6704b2,0x00033543cd7e5ddf,0x00000000000e0d6c}, {0x0008ad0a64850139,0x000b67d395c3ef6a,0x00040e40560ce9c8,0x0009f21efe4a5757,0x0004f55ea727b626,0x000450c823f97b37,0x0005d5b689b4de42,0x000000000004f5ae}}, + {{0x000bd2a72ae0f683,0x000d7e7365f9e264,0x0009dec60e7c539c,0x00089ac8e611fc3c,0x0005699c227dbfb3,0x000f2ef17ce778fd,0x000ed4dc1f47b63f,0x0000000000002672}, {0x00013b4caed73e7f,0x000a551c63805fa1,0x0002b72b6fe7e133,0x0003d13e00e12a38,0x0000bf8df325375b,0x000f5f21a91f9f75,0x000584f1ea0e421d,0x0000000000032c60}}, + {{0x000c6a3d385d54a6,0x000a26d720050d7c,0x00008151ff431078,0x000aee6f1c89ce3d,0x000b57b2b79d5d1d,0x000c7ce823f7644b,0x000b0bb1063f92fc,0x00000000000c15a9}, {0x0004b892e4ed0e8c,0x0007865661a5290d,0x000a266171fca5c3,0x000dc5d42ecede66,0x000c8eb0689e0661,0x000d7ff77be586ca,0x000c3bc86641a02d,0x00000000000b9ef4}}, + {{0x0006b862a25bd60b,0x0005903b07fb53e1,0x0000603f2bb26df9,0x0006449356376454,0x0002a55bcadf272e,0x00071c6af2b6ad1c,0x00080686c527765c,0x00000000000c1678}, {0x000fb64422cb7cb4,0x000660cae829453e,0x000b68619a56abb9,0x000f8337513dfb65,0x000e1b351dda504d,0x000af7cd04260ee8,0x0000fda473c5d9db,0x0000000000071e39}}, + {{0x000c98e3f8d5e928,0x000c217544e9789d,0x00047053e368c072,0x0000e3937af8cf8c,0x0009a2f308e2e146,0x0005060e98b4aa2f,0x000a7dafa2bdbc3a,0x00000000000f84dd}, {0x0004961384232a8d,0x000d53b256b55aeb,0x00063be03fa9b44c,0x00010d13c8e52f06,0x000b38865772c405,0x000416f1062c1542,0x000eb54755de7ebf,0x0000000000097aa2}}, + {{0x0009115b2961da7d,0x000f01d9aa9f9fd6,0x0004c642e6501980,0x000d6a17f167b479,0x00085bd9153d7ebe,0x000682ba6324c13f,0x0006e2e9ea5b734c,0x000000000007e3ff}, {0x000ac4814edd792c,0x000361ed2b04fb2c,0x0001100e4a13806f,0x000a5d3d68b8ec70,0x000d1c6ce0d2afce,0x00019410c21dc058,0x0005340043de75e7,0x00000000000e15cf}}, +}, +{/* digit=27 [{1,2,3,..,}]*([2^108]*G) */ + {{0x000e0e09fdbcad95,0x0004ef7aaa73197d,0x000fdf5aa02c7c2e,0x00017372e0c286f0,0x00025da3472da1a4,0x00076f2a23b66850,0x0007d4bc0d116b75,0x00000000000a36a2}, {0x000b11735059e67b,0x0001ecdb3f4744cf,0x00033adc74dab02a,0x00011b969d4f1723,0x00066cca4ef7c70d,0x000c6afdfdf96d13,0x0004da570693db2f,0x0000000000056750}}, + {{0x00080567673bd755,0x000df02c6b607d3c,0x00025bebf3a2d95d,0x000b01d4f57eb0c9,0x0004d750e515af5a,0x00089ad6859935b9,0x000eff32721b408f,0x00000000000a7e3c}, {0x0009a7a317218bf0,0x00010bd462fd8d81,0x000035ae54257b2d,0x000da619263fa61b,0x000eb6488eb34162,0x0005680c42ed1f2d,0x0007b0b0bd37a872,0x0000000000029ec2}}, + {{0x000d73368a1e2f2d,0x00047170f8a745d8,0x00056c4ca9228944,0x000bd224b08921af,0x000de6caca3a5f65,0x000cb9d5b1017ae3,0x00099b613f36b626,0x00000000000ed19d}, {0x00092b03ebebeebf,0x000c752c915a4d7d,0x00088621f044eee8,0x000f7c206a51a132,0x00066e0197ce2cd7,0x00071b04cfed60db,0x000b134e5b2bb7d9,0x000000000002f45a}}, + {{0x0009fb6e89b64981,0x00034fb09e755c21,0x0005804661454c99,0x0005b01cdb1f4f66,0x0008f1dd1cf0451c,0x000687e41b02f906,0x000bd3d4765e7c0c,0x00000000000d1967}, {0x000f135de5248a08,0x000f406a0e4ec0b1,0x000b70c2868ad046,0x000d01ac651d8073,0x00030618a96cc1e9,0x0004ad8ce5e6ebd8,0x00090f9ce1aacec5,0x000000000009953f}}, + {{0x000f6e431dc5b814,0x00044fa4b66978a6,0x00032f1c66e89ca4,0x000ba60986c85001,0x0004dae014e110aa,0x000bc0e4649bdfff,0x000d5fe2a810bd0a,0x0000000000062d1d}, {0x0007dc411c936920,0x0002c15d2f2c7072,0x00075b1f6234ac4c,0x000b6f94c545f5b7,0x0002f99241e840c6,0x0007082935875b6b,0x000344fa3e88a9d6,0x00000000000ad6d9}}, + {{0x000edb2b4857e570,0x000fba8d7901c33b,0x000ae7d92e8b3979,0x000d7c504e4bce1a,0x000e5ab0696fb905,0x000db9cd5dfbf9c4,0x0000fe0f4e6e2ab6,0x00000000000482e4}, {0x000aa1f98e714cdb,0x000225ccd9b418dc,0x00058c553b3cc2f6,0x0000dbe59065754a,0x000a461c1620cebe,0x000e541a74d052d3,0x0002d8396bac422f,0x0000000000070bf3}}, + {{0x000a0c1fea68e228,0x0005003c88a847c6,0x0008f73e5d2fc7c6,0x0003d393870d90fd,0x0004f2fdb976d90a,0x000312a302fd78d1,0x000f2f9472a6066a,0x000000000003484a}, {0x000f5efbe46efdf7,0x0008c7cf25950c82,0x0006be05e61c118c,0x0009379e563a2bde,0x0004b46e93d85d47,0x00037285ce87b50a,0x0007e69128fc11f1,0x000000000007c67d}}, + {{0x0006a0e99182cb3e,0x00059da2b072529a,0x0000a5cae364c3e2,0x000e35a5b132756b,0x0004fadb6907c721,0x00083f546e5695e8,0x0008aebc5a3bf4c2,0x00000000000dde12}, {0x000842d7630a9d87,0x0000d179c7fa6028,0x00016ae518569923,0x00083bea16bad558,0x000e9137ecd8af7e,0x00030d1ab6f41231,0x000ee8ac87543d8f,0x00000000000b1ee0}}, +}, +{/* digit=28 [{1,2,3,..,}]*([2^112]*G) */ + {{0x00021880433d0094,0x000fe359cbfa01b1,0x000ccfcddd1c5f17,0x000e90f630cbcb5a,0x00006ddbf2382fd5,0x000f753e62b0f613,0x0000165070970a3a,0x0000000000041727}, {0x000724192d1373c9,0x0003e2eb15b3b70b,0x000786ed962decdc,0x00074aee930a75c6,0x0006849e77270d43,0x0006a19ff3cd3604,0x000c049ac3117e33,0x00000000000433dd}}, + {{0x000b49aee05ae3b9,0x0005d985dcb4303d,0x000d13447c8994a2,0x0007f3055fbf1d6c,0x000f43fcd98a4059,0x000ec99cab6d166b,0x0003705932570915,0x00000000000c5bdd}, {0x00050b2df8b6890e,0x000dac18f782613c,0x000d7472d5468bfb,0x000a89df478e56c7,0x000864d290535d50,0x000cf7e0e242c2f4,0x000d40cda12c6161,0x00000000000ac8d1}}, + {{0x0001c7858f5f5373,0x000027a9a9dd7275,0x000baba450a60383,0x000267b6726c3253,0x000d7f841afb1550,0x00004643012cfb2f,0x0006cba41b19052f,0x00000000000b7d78}, {0x0007d7e12176321a,0x000667b61b39c512,0x00091b7379479d0c,0x000efb84a3489052,0x000cf2e864b965d6,0x00096cdb2f377862,0x0000f63c94000dab,0x000000000008efef}}, + {{0x0001ea0f696fd259,0x000ff8c558000585,0x0007b878d3ed6d3e,0x000d75ceb7a35cc0,0x000cf0a93110acf0,0x000c50c850fbdce4,0x000d6f82b2d13a9c,0x00000000000cef70}, {0x000ce46086dea462,0x0001e1cc9be2dbe9,0x00043757ada5e365,0x000479f195a532b9,0x000a1ab3605c52bd,0x00024c1e0769fe6c,0x000d7aba6a63e48a,0x0000000000099da5}}, + {{0x000ad5fa3c1cbaf9,0x00066df2a6cec962,0x0003dc76a0f4995b,0x0007e4c0de8a6aa7,0x0004be7b8f5d7c8a,0x000da3e7e5c806b9,0x0008e5ccca1c714f,0x00000000000cff78}, {0x00056778e2279cec,0x0006e17a081a8743,0x0007133643f614b8,0x00090549e4cfac8a,0x00029d53a2000d7c,0x000977a8b6fb74c6,0x0007c465b9ed6d5f,0x000000000000ba2e}}, + {{0x000a6aa57649a837,0x0000f8435e295b6f,0x0009b668270d6cf9,0x0006e6fece5cb161,0x00095336f7ffe2fe,0x0008ee2676f249b0,0x00017b5801feb990,0x00000000000fc8f2}, {0x00006b2a4f1b5cde,0x00053fc1adc3e51d,0x000e0bc8cae40bdd,0x0005404cc1d9b726,0x0001a1f2c5a44afb,0x00008f19575cabd6,0x000f492bd797e1cd,0x00000000000cbea0}}, + {{0x0008ce5f4471b983,0x000d8e9759aa9a33,0x0001c65f7f2a0258,0x00059aa2c80bb617,0x000230c9b328e49a,0x0004ebffcdb89e21,0x0008e4f42b9adb00,0x0000000000047967}, {0x000c42c02e645b6d,0x000f20dde5b0e690,0x000d9a21c0cf9036,0x0007a5cd8c8285c5,0x00071d1562069f8d,0x000e126bcd7cde59,0x00060bdbe765d7a8,0x00000000000e3f4e}}, + {{0x000bcd16afac5b0a,0x00041509abccab5b,0x000ba67813ffa4bc,0x00071bd640bc2f7a,0x00078f546c681ae3,0x0008b8cbfa155c29,0x00048b8858cadcc0,0x000000000001d969}, {0x000da5c95714aa4d,0x00010919cb2262bc,0x00085c89980779aa,0x0000f1ab4abe5612,0x00069cb75bd125dd,0x000a778e4c6bbe63,0x0004b3bb367cf947,0x00000000000bde52}}, +}, +{/* digit=29 [{1,2,3,..,}]*([2^116]*G) */ + {{0x000545d771f3d008,0x00076c6307398a47,0x00054915c4cf9c72,0x00026aae3a993222,0x0006da9308d18e01,0x00068e5050fbfdf7,0x0008bd2163ed6b61,0x000000000007500d}, {0x000f06ed5b023878,0x000d3f571595fffb,0x000ccfd2dfb01965,0x0005f7e53d84c661,0x0009025029da6b22,0x000d89aed9c03126,0x00015054c1edfa17,0x000000000006b435}}, + {{0x0007c3fb4d5bcba6,0x0005b009ef80a60c,0x00017966ca95c6c2,0x00055ed685add960,0x000672c7dac8ab44,0x00072f16818f323f,0x000a99e7009790e3,0x00000000000067be}, {0x000c5bcf19664dda,0x00043f15bdbcc383,0x0007e49d4e4912df,0x0002c304bdbec36f,0x000d1b3ac6c72fd6,0x0002938898b3ea93,0x000f8bce1c8e5c9c,0x0000000000011564}}, + {{0x00098a86761cd6cf,0x0008477faac22471,0x0009e917079e4be8,0x0001dd45fbd35ab8,0x000a45d6d40e31ad,0x000749ef67e0de9d,0x000cf2a16c5f1939,0x0000000000085691}, {0x00046f38fcf548ca,0x000e7156536ac506,0x000b8e250c84b9f9,0x0001eacd35088fde,0x000538fb995c165a,0x00093b3a5ce8a733,0x000e7934d0d33132,0x000000000008b570}}, + {{0x0002b3fc481df360,0x0006d6a3a232752d,0x0000509b75e73d18,0x0000c3322a82d404,0x000a14cbc8351703,0x000da272724bf18e,0x000d4a319dc4cab2,0x000000000006d020}, {0x000398eafd6e92bb,0x00066aeebdd89825,0x000a73a882a68cbb,0x0002978595f361eb,0x000c1ae8fa3cfc8a,0x000341575e60dd96,0x000e4819c2109aa5,0x0000000000006a0e}}, + {{0x000065dd44a81443,0x00083443deaaabf2,0x000c83e66800298b,0x00018ded51d6acd9,0x00017d4ec9bef889,0x000c48a6948c9b2f,0x000f5478b41104df,0x0000000000078827}, {0x0003f535562e2f60,0x0004674ed7948c07,0x0001ccc08940c103,0x000449b0d9fe252c,0x0006c14e825a6fe6,0x000690f0031743d0,0x000748d9d4ad8c08,0x000000000000e65f}}, + {{0x000eaf196980dd99,0x0009692501ff821f,0x00072b4a2cc10b2a,0x0009a05e53038473,0x000c2543d1a995b9,0x00080877130a72fd,0x0001456648126b11,0x00000000000eefb8}, {0x00041f6a86207b43,0x000d8d9a87f836b7,0x00016f9bd17dd926,0x000e118c40122e4c,0x000f853b291e3341,0x000565bade513567,0x000f77d4f1bbb73b,0x00000000000a7658}}, + {{0x0007b4a08d152bb9,0x0007cbab37a630ed,0x00077618410cb7bb,0x000086c1d4a8f5be,0x00046581428269e1,0x00076cc7d3a87384,0x0003a0b642dc1626,0x0000000000097e42}, {0x0008ca2aba5729e1,0x0005b66ac1b365bb,0x000e67e449b0ae7e,0x000debbadcc68242,0x0004b1536fa18f47,0x0009e546144e9bf6,0x000b901cfdd50493,0x0000000000043bb3}}, + {{0x0005a0a5974046e0,0x000112e32f89636a,0x000495f55b511bd6,0x000b1ad8f8328866,0x0008adcbd933278d,0x00064f863271d907,0x0003652208fae34a,0x0000000000039c89}, {0x0000e167567c2b6c,0x00048cb46f2725d5,0x00086f7986cb61ca,0x000d316edd504188,0x0004cabe36ed3421,0x0002efcdab1d8a06,0x0003eedb13e56036,0x00000000000c71eb}}, +}, +{/* digit=30 [{1,2,3,..,}]*([2^120]*G) */ + {{0x0000e8a3d453ef19,0x000752af8ed809c8,0x000017d0798a8632,0x000726f782193578,0x0001b87254c44c0e,0x000e7691a8c1962a,0x0002ee30796a71c9,0x00000000000a75a1}, {0x000c339094f215d4,0x0003e535f42c17eb,0x000b753210a29b6e,0x000ef35e39a7a591,0x0002d459b91ab7f1,0x000fd429da2789ae,0x000f57eadbca7f02,0x0000000000065290}}, + {{0x000ffd02d3a50b87,0x00027c085500177e,0x00023ee786608759,0x0001d964318e861c,0x000604fe9b85dda7,0x0005e7e2001d3d39,0x00081cda4bc065e2,0x00000000000e076c}, {0x000171ac92e482e8,0x000095b9f82189f0,0x000cf8881039863b,0x00083e4d8dd159bf,0x000720b18043f526,0x000a0d8f5ca9c888,0x0005c473c040fa08,0x0000000000017952}}, + {{0x00023e634e793b49,0x0000c37ed2be4ce8,0x000e92823d3628c0,0x000ad8ae77c2f00c,0x000a44de16a8b061,0x000e490ffe87e1a9,0x0003eddf4f57c87e,0x0000000000000599}, {0x00036b9f1b67eda0,0x00020e1036387a16,0x000cdc81b1b14889,0x00020d15ab42f920,0x000dac0ff03359cb,0x000c1e7f4a738a18,0x0006e0da501a2e2a,0x0000000000084d8a}}, + {{0x0000efaf35b1418f,0x000173a8289046f2,0x0004fa8840c897aa,0x000898ae5fa19d2f,0x00065e1c5fa4c574,0x000390fc20b13dbb,0x000187f11343ba7c,0x00000000000d7d32}, {0x000b8b2ed2cc734d,0x00011c92cb1bab11,0x000e6307a3aa4fd9,0x000dfe5672f2af7d,0x000430932441da69,0x000af02d69c62d7b,0x000c22165672ad94,0x00000000000cde81}}, + {{0x0006bff8295a2913,0x000d91d27efcde72,0x000bdb7b59692a46,0x000fb83caa26d18c,0x0003b82babbe99a3,0x00083dd60d27e613,0x000cb861030dfdd7,0x0000000000073c78}, {0x000a3caf05842de3,0x0002d8707a2cf633,0x000f47297bf43775,0x000d412a2b176b8c,0x000fc72021017c3f,0x000a6d536d5b52e2,0x000ec024a63030f0,0x0000000000004648}}, + {{0x00024dd131928645,0x00063d45e3501026,0x000cd2a97f7d8b99,0x000a088e302483ae,0x00082c2485c01532,0x0009cdbe63475e8b,0x00073808f9ea5696,0x00000000000253cd}, {0x0002a544f2d5917a,0x000581cf323a3b9c,0x00023a0e49f58c76,0x000e84fc06f3d0ad,0x000e39efe6d99a31,0x000ac4decd326b86,0x00058277e3e1df14,0x00000000000f3e0c}}, + {{0x000611e8121168e1,0x0008967477cdc1e4,0x0003ef00563660fb,0x00060b9917eec666,0x0004d66c5c1d31fd,0x0009508baacd95bd,0x0002432e0551f3bf,0x00000000000688cb}, {0x000033e51fe09e4b,0x000448c039740256,0x0004cddb41207f6c,0x00025e144db62afe,0x000bc4a030da1918,0x0000815043ee8aca,0x000cd08ab154a894,0x00000000000486c9}}, + {{0x0009bbd8fc757c25,0x00003e92b56bf065,0x0003d138d6f390b1,0x000d0ef50f5c483a,0x000611fa89fe7754,0x0004ea7d8850a9ef,0x000a2e97d74b1bba,0x00000000000aab7b}, {0x00042e268ab251b7,0x000af06f30ab067f,0x000bbd0bcb9d997c,0x0000bca7a2e053e3,0x0008dcf0e14c4758,0x000f553108579559,0x000e18c3596781d6,0x000000000004c9b7}}, +}, +{/* digit=31 [{1,2,3,..,}]*([2^124]*G) */ + {{0x00056db726934b05,0x000d28db8b78ca20,0x000efbe1df76bc8b,0x0000f022dde2e3c8,0x00038cbf406c67e5,0x000f7ff602e2461f,0x00068832182781e1,0x00000000000e30e2}, {0x00008c8748c4086f,0x0000895adc204b38,0x00054339345edf7d,0x000f060b73417379,0x000fd128d46cd5ca,0x000fc1e04ed93187,0x0000a13f2819cb20,0x000000000002b7f7}}, + {{0x000424a4cdc9ef0a,0x0009fd74d09c0410,0x000c23c8eb2570ac,0x000cfdce132b9412,0x000c843d3c66db1c,0x000cb3ef4a0e5309,0x0001771fbd03a5f9,0x0000000000000ea5}, {0x0001bb0b6df68f60,0x000fa1ebf5a155d8,0x00046a120ff8039f,0x000c37aa0d34d161,0x00050fca43af3256,0x000841bdeee40efa,0x000a0bc299bbd4b9,0x000000000003bef4}}, + {{0x0001fdb0e87d4c69,0x0008f5bbf8bfdcec,0x0002c8b1b68f641d,0x000718bfd3fb74be,0x00015a085196abd2,0x000dba2ea03c0150,0x0008bc147474dc4d,0x00000000000eaa2c}, {0x000a67e6cbd2f408,0x000e9bc3dc5c2f94,0x00045e933f00eed5,0x000e98325d341410,0x000406fcbc8e0276,0x00024ebab9372694,0x00050b8c4b7f2ca3,0x000000000007dc3a}}, + {{0x000547a274927d68,0x00075e01295fd654,0x0003c43252dc8b6c,0x000689f9eaf8eb82,0x0005c622acc52ec9,0x000757f2a327b96c,0x00006eae918f81b2,0x000000000004fd66}, {0x000f52e65907ef2f,0x000a109bb7fcdbf4,0x0007ab72ec41ee7a,0x0006f125fb475125,0x00018e399520df2a,0x000b1c3a2be88faa,0x00081f0166d57e3f,0x00000000000e525f}}, + {{0x0005132af5b85725,0x0006e0c64cec623a,0x000d73b377e49971,0x00043ae5a8027b17,0x0007d0a7406ac27a,0x0002bfeed1c5729c,0x000357445fc7d34e,0x00000000000809bc}, {0x000fe2c3577b04e1,0x000a30598626b6a7,0x00059236250da683,0x0009b314294839a7,0x00093ab9bc662151,0x000ab597466282da,0x00012e84c422c25c,0x0000000000071c0f}}, + {{0x00044dd5af953087,0x000b3f24fab9aa7e,0x0007e53a0eea7298,0x00070e733ac4fb68,0x0002c8a6976575e3,0x00030aa0ed8d6164,0x000637f057f10a5e,0x000000000004f1e8}, {0x000514c4bb67bcdc,0x0005e887f06b2b4b,0x00032e66a34587bd,0x000f7eb6e6483a19,0x000f475d4bfd4319,0x000811fc744f1aaf,0x000f8ba8ee73b50f,0x0000000000082916}}, + {{0x000b0ecbb3371c13,0x0009596495c1e57a,0x0002216cb93b15bb,0x000c858fe6e84ffb,0x000b0b189be26806,0x00058a7685c215e8,0x000202ac61577e80,0x0000000000088e0d}, {0x0004f2a99a53c49a,0x000de70322e164ce,0x000973bc42c42efc,0x0001f014d701ab8e,0x0004a61df25f8863,0x000f6dbeb889f10d,0x000168affec5a9bb,0x00000000000934ee}}, + {{0x0006f789ccd0fed7,0x0003cdefe3a7abd6,0x000569da64526056,0x000c26a73d1f9b54,0x0008237ae8b77366,0x00047825935d5d71,0x000ee33efb20feb4,0x00000000000aa545}, {0x000d70972e2560bb,0x00081750edd05bef,0x000da581b51c4635,0x0000f370a9e29dc7,0x0006bfbec7f616e6,0x00047e1439cf0a13,0x0001a9b430a34b2e,0x00000000000c6cdd}}, +}, +{/* digit=32 [{1,2,3,..,}]*([2^128]*G) */ + {{0x00056f0266d7e788,0x00065f186d6bc61b,0x000e03ac4fb95d1d,0x000432edfe64dc3e,0x0002d795ea57c9e7,0x00045af2bd9fc483,0x000517f4ffdb81c8,0x000000000002b670}, {0x0004d8950582c931,0x0007aa7c1be04d23,0x00045b4daadb356b,0x0008aba03f2ef6dc,0x000420dc701d62ff,0x000f1011960ecaac,0x000fd09f4b559f4f,0x000000000003cd54}}, + {{0x000973c51356e0d2,0x000aa31954a56667,0x00047c018911cdb5,0x0003ec5e37ef1d2d,0x000575bc3b668c43,0x0009cd98bcd0f203,0x0002a33723f14524,0x00000000000ea3b4}, {0x000998df93db2ed6,0x0000ff607fee05d9,0x0005662b349502ed,0x0005d74cea5417fc,0x000a10fca22bd47b,0x000635e8b6891940,0x000fef5cea41332b,0x00000000000b5934}}, + {{0x0000bd5aa7cff3d9,0x0003c365a4a426e6,0x00069eea0aae5d6c,0x000c8b4b7205a704,0x000357df815ca330,0x000a926744858eab,0x0005d76e522afaf1,0x00000000000f4136}, {0x0001a59021cca096,0x0002a00dd3461384,0x0008629f956ac671,0x000103f7c082301c,0x00076b092b71f427,0x000037a3314a2a18,0x000e14210f632130,0x0000000000039340}}, + {{0x00025fc00f86f9f5,0x000b5b1f4fead323,0x000e624d9ef69f8a,0x0007efe2e28aa2a7,0x0009b3151d6748b4,0x0006a346070dad2e,0x000af787a8178b43,0x00000000000801f7}, {0x000701583b4bfabc,0x00034fab462e36e3,0x000ddd2177064fe4,0x0006b3fe66812831,0x000a6a3fdc1db469,0x000e37dac3bd9910,0x000fb34409128449,0x00000000000cf605}}, + {{0x00081f556f82acd9,0x0006f59470e4953f,0x000963a40f813b02,0x0003c1e0fb30ecd3,0x0003b62892f14761,0x000eefa161fbeffa,0x000719ddfeef49f8,0x00000000000daeff}, {0x0004929822ef7d6f,0x000dcff1872cd89c,0x0009edd2dba5c5c9,0x0003a387695218a2,0x000720802b8852a6,0x000f4a473a0d413a,0x000a4a233f1f3118,0x00000000000c9d7d}}, + {{0x0006ae71b9b2b784,0x000ca86737912907,0x000e250552a02dec,0x000185ee92c712de,0x0006c201e3272efe,0x000f6b0788b908f8,0x000bf33ab5528894,0x00000000000ce0a5}, {0x000abf1c0844ab25,0x000185eab37ac7f5,0x000c6bca8c37680c,0x000edff304f1cf97,0x0008f6fd3e90f3a3,0x00016e5ed8992ecd,0x0005c4ff24d7c69f,0x00000000000def9a}}, + {{0x00054a31e739d50e,0x0001e2edaaaa9c57,0x000574cc3b6825a1,0x000fc42bcb161908,0x00046709d8513542,0x000af4ce06c04ec2,0x000e2e5fe9768ea9,0x00000000000eb6eb}, {0x0005126ebc807472,0x000c87b7da4abcae,0x000d07139021766d,0x0001c51fd563c816,0x000926c775e17f69,0x000b58889ea990d6,0x000c2c2cd96f1321,0x000000000000f1aa}}, + {{0x000e697116bc35a7,0x0002057edf71ec8d,0x00063f77e7793641,0x000ba1aa6934160d,0x000c5e639a54b37a,0x000bce957d45b3d2,0x0007f362c6b9ad70,0x000000000005d7e8}, {0x000a8127f71a285b,0x00017b02169816f9,0x000c7a7939056bf2,0x000692b478e4b92a,0x0009be3fe25a15aa,0x000bdd4a8dd67cf2,0x00027af1ef75b006,0x0000000000041df6}}, +}, +{/* digit=33 [{1,2,3,..,}]*([2^132]*G) */ + {{0x000455d88f7fc60e,0x00091a58a27c4fad,0x000ee65aa7e47d3c,0x000826600079a263,0x000f2606caf52431,0x000cb28c8113f6fc,0x000aa6f6ff2be316,0x000000000003c17c}, {0x000c05f668a9dc76,0x000798ea577e0148,0x000c912137590c65,0x000eff4592a57ef2,0x000c5e3f67b24b28,0x00000890276e1f87,0x000b7e40d7a676fb,0x000000000004b6e6}}, + {{0x0007f95d338f5fb6,0x0000076e27519dec,0x000fefb9477deeec,0x0002dfb71fba6625,0x00085e0886af5832,0x000ee544c228aec0,0x0006398d83b6276a,0x00000000000e29f9}, {0x0004808391599977,0x0006d1ba4cfe02e0,0x0000441e3d4b3e92,0x000ed58cee95d92c,0x000abe5355407e0e,0x000a9a1f42d29282,0x000c82866638b607,0x000000000006ab8d}}, + {{0x000c43ee7094e067,0x0000b599ece9688c,0x00025bcbe937baac,0x0005ba86373ccef5,0x0003c64f72612afc,0x0004ce1abe455683,0x000a77f29ad54041,0x000000000003ee82}, {0x000e0b1548890be5,0x00094fa26eaa0940,0x000c96b0a3e57442,0x000ade54e1c94bd7,0x000e20b0ddbe9570,0x0006eff6ff4a86d8,0x0007a4967ab653dc,0x00000000000e8bab}}, + {{0x000de87dcf2f3d8e,0x00056a16c79cee01,0x000db47cfbc9e301,0x0006aa0c2f47e69c,0x000f2c9b4914b8bd,0x0007242a8277d590,0x000512b6d1c81009,0x0000000000045f75}, {0x00044d25d22dbf16,0x000f02176162aa27,0x0001167bcefd598c,0x000c0d1a503aee8c,0x00057af4dd78fcf8,0x000b43be45d1f94a,0x00071b8f0bc1a62a,0x00000000000ba9e0}}, + {{0x000adf4d6bef5a3d,0x000a19a2dc376622,0x000b08bb2e394780,0x000e5cf7c0765207,0x000c4063c3538e70,0x000baec46c0dbb4a,0x0001ad3f4550566a,0x00000000000f9356}, {0x000e15a92e3f32ae,0x00055d0bc6d91fc6,0x00092d1d7bd54520,0x00033424b80c021f,0x0007af5e458c62a7,0x000bfde586e1d546,0x00052c6922574f70,0x00000000000d19f0}}, + {{0x00077ca19b6937db,0x000c3bf87f30d9c2,0x000f3d29bdf61e62,0x00032bd50ec0ba46,0x000ae60d1e72d5fd,0x0004ff2d37de8fe0,0x0007e452d77fe0e1,0x0000000000055ca4}, {0x000fd784e6c9781f,0x0000339e3d19e6d1,0x00045fa26fa441a0,0x0000c7afe92c6d07,0x000869a829043bd7,0x0006d1d9ea3fbc06,0x00024be263f00ed9,0x0000000000075c0c}}, + {{0x0002619f4e7dcc16,0x00090a1d1a8f0893,0x000f4151f0e91898,0x000c39b84ee41fc5,0x0002e4a019099db2,0x000a66c12ad292a0,0x0000f6ee6b26ddfc,0x00000000000f04f7}, {0x000e18e3a8161ac5,0x0007f01e66788b92,0x00099db080ad62ab,0x000e4542595d5a6c,0x000bdce965cc3e7c,0x000ec7931f894a64,0x0005be12e46952d9,0x00000000000fb65b}}, + {{0x000d91fc53fa82b7,0x0007d705bfe3760e,0x0006eb6118c41a96,0x00077a9bc4567977,0x000617081a2f811e,0x000e1640e4f52c4e,0x0001d787405d819f,0x0000000000070771}, {0x00085581b6dc5925,0x00062dc6fff82580,0x000af03b55b43c90,0x00066bea9cf3eae3,0x000e87139b8b0ecb,0x00042b4d77418372,0x00032e6aaccf295e,0x0000000000031fc9}}, +}, +{/* digit=34 [{1,2,3,..,}]*([2^136]*G) */ + {{0x000f65dda78f831c,0x00073fa3b4c8e10f,0x0006b8117d5cb12e,0x00039562e8c4d8cc,0x0005cf89935b06aa,0x000fa071e4981c3e,0x0003bebdbd0c4745,0x0000000000049607}, {0x00004bb91c157448,0x0007009a7298688d,0x000867eb798cb22b,0x000b5b3988f2781c,0x000d73b1719d9a64,0x000d2e8076ac9440,0x00042b58ad54c7e3,0x000000000008f067}}, + {{0x000489635dd868b5,0x000ef339521774bb,0x0001f606d4b5774d,0x000d61e0a285bd5e,0x000e71171b1c1084,0x0009b29f93935a84,0x0009bd8ac2433cf2,0x000000000006dd1e}, {0x000f576ac5f0cc26,0x000f788da0477c71,0x0007313f812b64cc,0x000a25f9d5b19e1d,0x000b6a27fa79a792,0x000a16a8e9ee015c,0x000e67ea3bf8b57b,0x00000000000c15fd}}, + {{0x000f3b091fcd53e3,0x000c537f50e43695,0x00003782e79d52fb,0x000af85e1d111511,0x000f6785ae1c3916,0x0006ada8cf56e852,0x0005b2bf8c72adae,0x00000000000e1328}, {0x000cbe0d0bda153b,0x000e35327920cb17,0x000e7daa3650306d,0x00028573caf37928,0x000b550ffe1ca713,0x0005d4e4fb15ab34,0x000f9d818980666a,0x000000000002f854}}, + {{0x0005d9265089916f,0x000013b623150146,0x0007ede4f0fb2f49,0x000c31c56471100e,0x000b1bae8d2a4bc2,0x000f1f76a4a0e73b,0x0006cabfc0770a8d,0x00000000000a7bb1}, {0x00039cb13d9c4b7d,0x000f42afe5b1cb58,0x0008a2ce9b2dade4,0x000a333a1af2a824,0x0005dafed6cd97ca,0x000c3b2e393cb92c,0x00095609553e7e92,0x0000000000061af2}}, + {{0x000ea55edca2a058,0x0003f5559dd3109c,0x000f7ba60d37c6c8,0x0000fabcaf57d0dc,0x000578742ab60d84,0x0009c1c8e9625866,0x000167c85482ad40,0x00000000000adaa6}, {0x000208d39ae67d2a,0x000dcec26ad9971a,0x00067a35ccc54689,0x000a7fc2539986bb,0x0006a23dee41340a,0x0001a9837d767487,0x000da9a948a9292e,0x0000000000071438}}, + {{0x000778a60c6bd7ad,0x0007f39038863eb8,0x000e85efa03ef35f,0x000682ef3d8310f4,0x0008f412315338aa,0x00026310bb52d41e,0x0006924fbef3dd70,0x00000000000f6ff5}, {0x000ba50eddf2b7fe,0x000b63831c6b1cbc,0x0003bc6684c6c5e0,0x0006abc6516bba59,0x0005446d35a876d2,0x00012a8d0c237f9a,0x00015bb2b16c0ff0,0x000000000000ee03}}, + {{0x00014182dba86bd2,0x0009c817d77b02b0,0x0006420950654aca,0x0004107da68b7691,0x000dbebc4c4dd3ac,0x0003d39e96904bcd,0x000950b0d2103ca5,0x0000000000030a5e}, {0x00028ff31a9f909b,0x000c7b092568034b,0x000262a60542e8eb,0x000ab34c15855ae5,0x00063017194f2389,0x00046b838c14dfd9,0x0006fc420e071911,0x000000000008fb4b}}, + {{0x0009c78614d38ab4,0x000d813722ab0651,0x00088626a03970e0,0x000f467f76fdaf74,0x000912ddfd9ad3d0,0x000bdefd37ce072f,0x000315ce918a5747,0x00000000000750e5}, {0x000fa00e65975639,0x000cd08bbb20dcda,0x000822e7b86b49be,0x0005c21ca865ba6a,0x00002e6e8e6fc8fb,0x000608b60ee6e41e,0x0005cdd00ae6214c,0x000000000006ff68}}, +}, +{/* digit=35 [{1,2,3,..,}]*([2^140]*G) */ + {{0x000cd00e20fc1fe8,0x0002bbbccce39826,0x0009c6cbc7ade77c,0x00035a5d2252fdaf,0x000954e7dd499eae,0x0005100fda8f4f20,0x000727a56d72a629,0x0000000000056767}, {0x000898f026420cbb,0x000adbf60b247e57,0x000b35db15577b1e,0x0007ad4b93dab9cc,0x000022d71f39c2a6,0x000304db218cd0ed,0x00082104380c425f,0x000000000006729c}}, + {{0x0000345995afd46f,0x0009dca07923b790,0x000129149d2f3565,0x00079e83cb025114,0x0005beb383ef41e3,0x00076dd0dfabac00,0x00012724d12d9a10,0x00000000000b208f}, {0x000d58cd6475c579,0x000359cc38a604c8,0x000857e410d47fbc,0x00060d98ac219eff,0x000faf284c806f63,0x0009e366a1edaab3,0x0007269c3b528101,0x00000000000bc9e9}}, + {{0x000a386526319283,0x0008d26bd07d697c,0x0006e6a9c305333a,0x000c5466798b96c3,0x00081d3f3859d831,0x0001b9ec71d6b410,0x0001a9501d38ec99,0x00000000000d7843}, {0x0008f62f7d623e0d,0x000dd8b85baf6942,0x0003f90bead64135,0x000c1107acdcf58c,0x000c848d5842efc7,0x000c7fdacd9af415,0x00019b6b5a06bc0a,0x00000000000a3443}}, + {{0x000517cc17c08a8e,0x000a28410d82975c,0x0000ae8bc362b8a4,0x0000d0d18c253486,0x00007eb035a3ae46,0x0001144145d0279a,0x000f7987e7c1289a,0x00000000000c0744}, {0x000ccad1ad801112,0x00072b7b2b4f054d,0x0007f502703051c0,0x0007395b51ee6864,0x000bf6122422124a,0x000f1a7fff2937c4,0x00032eb4ec133207,0x00000000000f8860}}, + {{0x000daf15d19f8632,0x000794c0d78053af,0x000ade8ac0a0ca73,0x000c453e4b57e236,0x0005f4172b285217,0x000f999f8b4669e3,0x000d41509a3cd049,0x0000000000087c69}, {0x000ec5ba18211916,0x00032e14d01e8346,0x000c499a14031eb7,0x000bff270dc2bf04,0x000bc01864000e17,0x000a4dd3446560b7,0x000d06e28c7b9c49,0x000000000000f325}}, + {{0x000161555383d319,0x000d0dd4eb3d0283,0x000dca801a8bb250,0x000285ddc1973c7e,0x000aa0046b981200,0x00019a7fcfd342be,0x000fe5d191734912,0x00000000000b7caf}, {0x000a5ee9f805422f,0x00057ea5a0c4d360,0x0004c8206c9d4abd,0x00016dc6046eeeb1,0x000ecc8e64b15b2a,0x0007fadda1755e1f,0x000ec251e4946e9e,0x00000000000fcbf4}}, + {{0x00024bd4d62de244,0x0001d46d7088801b,0x0002ae4b99b01f02,0x0008fca4fbea2725,0x0005bd80a9dfe494,0x000871c717d6c776,0x0005701b470ea6f3,0x000000000008330a}, {0x0004db08d904e89f,0x0009bdaecddc0ed5,0x000f26cdb2e08463,0x000cd84caeeef145,0x000fc685a35656c7,0x000d93ddcc60c910,0x000895e68bc5c59d,0x00000000000feb64}}, + {{0x0001bb5474d7445b,0x0008af877e8c6483,0x000948d44b23fa45,0x000269f2b004cfe9,0x000795450f8b19ff,0x000a7d4588adc5d7,0x000fdc688ce8bce2,0x0000000000097bd7}, {0x00043a2684d27187,0x0007c1b9f4ad5bd1,0x000b255e8d74e0bd,0x0001f7e71d83d86e,0x000d25ffc219abee,0x00073f553e693c76,0x000a551c9a84afc8,0x0000000000066d77}}, +}, +{/* digit=36 [{1,2,3,..,}]*([2^144]*G) */ + {{0x000e4a9a609d4f93,0x000f05584cbb3289,0x0002a9b59e61225b,0x000d8267df2d43de,0x00000109e8014126,0x000172f1cdd5bbbf,0x0000d985b92ee338,0x00000000000f3143}, {0x000ac2d50dd03701,0x000b11e059a07dd0,0x000eb68a6d1ce296,0x0000751560f20e77,0x000e7aaf3a9ad622,0x000bae14ea59489a,0x0002497b70e2f664,0x0000000000076d08}}, + {{0x0001e7720f69ad57,0x0004baff47822226,0x00011f4e0e8fa5c8,0x0005f8d2ef696aa0,0x000b4fa94fcabeb8,0x000d41a438ce5baa,0x0007720a32f96200,0x0000000000074f6e}, {0x0005b3ae79f59da9,0x000a8be0221aef2d,0x0005793443a4452f,0x00085d6a7e49f3a4,0x0009cb5d3c6378ff,0x000eb65f56300658,0x000bdfe8e4383596,0x00000000000ff8ad}}, + {{0x000ec83ab52a5d83,0x0006cf6fd26cb934,0x000ee1af72ab19a2,0x000788be372817f8,0x000ae8c90c31694a,0x000aa0ce585f3dc1,0x0002238c90c6bf15,0x00000000000f01bb}, {0x00043ef688d7f41f,0x00075bdae01dd56c,0x000cf79ad5ecb5f0,0x000ff4ec2548f251,0x0008d12802a750dd,0x0004d924054a4986,0x000d1acd922fb640,0x00000000000957f6}}, + {{0x0006a17488184bb0,0x0004d082ea61c88d,0x0004b5a68e9c5821,0x000df962e54f5d00,0x0006e39dc6ab7d33,0x000179b13340b0d3,0x00088cd97a8b848d,0x00000000000288d3}, {0x000bcf17110adf56,0x000462237e507d00,0x000fa28fb932260c,0x0008bcb42be74594,0x0004de2176b6645f,0x000e2f09cce2b0f5,0x000001af570a09d1,0x0000000000057fdc}}, + {{0x00009414087acee6,0x000fc7dd81467f3f,0x0007997c546fe735,0x0004e832d2e9fbfb,0x00061c9d9c7ca2ae,0x000f27f140f127f6,0x00029ef06c5a57e6,0x000000000001f303}, {0x000b431a1206d910,0x00037a1b2b82f82b,0x0007312610c2e220,0x000cb8b039f12bbb,0x000902b92d6b1cf0,0x000f649e606ce433,0x0006eccb5e826869,0x00000000000e9309}}, + {{0x000f672480aedb22,0x000c79d21c740037,0x0001a34fe6cb5f73,0x000b1a3aae5d701b,0x000891978d1557f8,0x000b85b1e477e4f8,0x000fb42913ffb40f,0x0000000000058489}, {0x00047efe2cde596c,0x000a60e1ab266dc3,0x00073cc3adaf7198,0x000ccb657ab8d871,0x0006547f64bdf578,0x0003e497e339fd79,0x000706904693943f,0x000000000001d864}}, + {{0x0009da8454e1979d,0x00030da92e482d7a,0x000b666249139a91,0x000ebb3639c78714,0x0009d77aac3c8763,0x0002769a43bf7177,0x000eda92a5420d3f,0x00000000000d092e}, {0x000352bd3a0254a9,0x000b5d7bd8d8f8e8,0x0009446f6266c164,0x000fa3ed6b0cf872,0x00040490a771a5ea,0x000ff37225255afc,0x000cdbd40bb0fd15,0x0000000000079294}}, + {{0x0005908307814aa6,0x00009158bfe27b53,0x000df35ce707d624,0x000153b8e71aca19,0x000171b11643f07b,0x0004e2f905e67698,0x00010977b7dd7dd0,0x00000000000f0dcf}, {0x000bd23edf0138e0,0x00071d3bab2a41f1,0x000facf3129d6b1f,0x00099afc6f53cda2,0x000f628039e454fe,0x00083aa16071f2a4,0x0006f9f1f44181b1,0x000000000005010f}}, +}, +{/* digit=37 [{1,2,3,..,}]*([2^148]*G) */ + {{0x000b28d4d03ca18c,0x000a0b1e36500cc3,0x000e44ebafd13e2f,0x0001d2ca4bfdcedc,0x000fb29cdcfebf45,0x000514871d210892,0x0001e35b12bcd894,0x000000000001809b}, {0x000c86d0fbcc5e1a,0x000ce09b243105c8,0x00037f6b6be14182,0x000a16b5de334b63,0x00020b116076cef0,0x000ae2bf4fe0bd1e,0x00093754e4b48289,0x0000000000068c8a}}, + {{0x0007e2c503fdc14e,0x00049309b1eb33af,0x000b5e3acfac1d05,0x000b81ebf8a894ca,0x000e0d29329387c2,0x000bf371427a40bc,0x0008957f4c315be4,0x0000000000001236}, {0x0002d22bfd1d81d3,0x000f4319c88f7e2d,0x000189361ce75d22,0x000a05df0dd13811,0x00024acba9fafcc2,0x00027313ec8d55b0,0x00094a871358de59,0x0000000000017ce2}}, + {{0x0002c99cf8ff48b8,0x0002410777188c8a,0x00068c821fc35883,0x000b515120380e77,0x000fe13577d1261a,0x000862db1453c858,0x000e1cb1f6bb58f3,0x00000000000b9529}, {0x000338bb0bed7b45,0x0008003f63a416f7,0x00081208dbc793e6,0x000048b756e5af2e,0x00031c984bef8423,0x000a00f3e4d978ed,0x0009e7a06242995b,0x000000000004f4d1}}, + {{0x000e08308825a639,0x000e8d3797831773,0x000f79843c567224,0x000a6a611a4e33a2,0x00005328043a2ff7,0x000e9f7dd904f86f,0x000904e29d31c012,0x00000000000c0a51}, {0x0002dae695c951e1,0x00024070c2696563,0x00060638255bc0fb,0x0000d0c12c8a1f65,0x0001ab352a835b97,0x0005eb0c7572aaaa,0x00059963df45a90c,0x00000000000d4977}}, + {{0x000fe53cf0bc7d5d,0x00073e35daffd3d8,0x00005ab0f149d24a,0x0005a40f009a48b1,0x000d308a81c693f0,0x000885426a4a801f,0x000f0575e5dc467e,0x000000000004629f}, {0x000c6c457ceba67d,0x000c6356b879b5ee,0x00084a5c7d7e4e3e,0x000856eec2dd55b5,0x000880f0c80411c9,0x00001b21720f0443,0x0007b8c0b5e3e218,0x000000000006ea09}}, + {{0x00042a359a9c02d9,0x0006601c2df8ca11,0x0001ea46897d0b3b,0x000341c8360fa6b2,0x0002c52bb2d6e198,0x0002efba5e67f809,0x00032af944dc63a0,0x000000000002c123}, {0x000d5d58228e0e7d,0x000b239684f6c863,0x000f4f910b494aa3,0x0008eb646594725d,0x0005793c32ddb7fb,0x000f94b55bb4f5f0,0x0002773ef3c33845,0x0000000000009eac}}, + {{0x000bc0df5aa0ebff,0x00046efd26dca17d,0x000d31eadaba6e9d,0x0008a89e1830a96b,0x00013e039a029f10,0x0006fbb3b7e8e368,0x0002f11747b3e925,0x00000000000abb3b}, {0x00023cb577b95e94,0x000e2cac5818c280,0x000b36c4a5c24e15,0x000fd4d7a5485367,0x0009aa3645074081,0x0001a5f81fe2d8e7,0x000db4e86ce00ea8,0x0000000000077a9b}}, + {{0x000a3bf39d563e4f,0x000f02c5b0e421f4,0x000bae31a917643d,0x00085959aa907285,0x000af658699bace4,0x0003b18e632be886,0x000667ce75d6c6da,0x0000000000069caf}, {0x000af371b713c401,0x000f0c17c66ce4f4,0x0002f4e783050dba,0x0000041623db4f0b,0x0002c74762e1ceb8,0x00071c52fe75615b,0x0002ecade8a54386,0x00000000000cacaf}}, +}, +{/* digit=38 [{1,2,3,..,}]*([2^152]*G) */ + {{0x000ea5d38989c046,0x000c5a933aaf71af,0x00084b51a5d47afc,0x000dff8854de4972,0x000b247bec1525a9,0x00061e58da8b31d9,0x000707468a25c846,0x00000000000786a0}, {0x000d126f8d197fbf,0x000be282db8ca2e4,0x0000d8a3ccd2e3a9,0x0000faaeaeda06f0,0x0009add94b47a2c4,0x0000690766963292,0x00092cc72354f6b0,0x000000000007878e}}, + {{0x000456ff7fbc201b,0x00083854b0583e19,0x0005b9f9d05986b8,0x00093894c32fc71b,0x000c9ec8f90dec82,0x000c7b9c0882fad4,0x0005e52d39990dc6,0x00000000000d71a2}, {0x0003262dabc3b450,0x000866b852e64a5a,0x000281968ae95022,0x00011545857f0497,0x000c1ccb9bc83700,0x0002bb853746621f,0x0004ed97e44e6361,0x00000000000758da}}, + {{0x000e66dca895aedb,0x0007e58775856e71,0x0003edbdf1471e8b,0x0002e3da62265d35,0x000672d98b0886a1,0x0001e9c858ec4278,0x0004ceb9da8016f6,0x0000000000080099}, {0x0007a34c46f751da,0x0004f63d0878c9c9,0x00077928ee65f2b7,0x0009e126a1c1efae,0x000eebd0497a780b,0x00065231eeed68d0,0x000127bfeee3d292,0x0000000000080e03}}, + {{0x000369b381ff008e,0x00068d25f6507829,0x000435b503d33f46,0x000031108b9b08bf,0x000f3fe92e910b36,0x000189ddc16477af,0x00038f6e5f6cb103,0x00000000000c698a}, {0x000953f049518733,0x000e102a092187fe,0x000b4e74068daf16,0x0005eac8fd6b76cb,0x000611ef96b455a1,0x000e433b51e37ec3,0x0004c3d1b3b3fc30,0x0000000000051d17}}, + {{0x000c3efd55e9f108,0x0004ee67813dd55d,0x000e8b95d557829a,0x0007b634c8cf1647,0x000fa3556b4674ea,0x000db03dff1bde0b,0x0006b45343f260c1,0x00000000000e0a1d}, {0x000557bdaa85b25c,0x000b5af56bed0543,0x0009694c640e2d2a,0x000c5892c72fa801,0x0006a49486e504e0,0x000f78943812e259,0x000431d5e0bddb2e,0x00000000000acdba}}, + {{0x0005b2c1b41a7e30,0x000e8b6e95494a98,0x000e156b8fa7f1c3,0x00012ee2183ce113,0x0000cc01d1434741,0x000d0d25f4180ec4,0x00016ddc5f8f7b8d,0x00000000000974a6}, {0x00054a8b6ee62d01,0x00072b9a7f0a96a9,0x0007a0f1f81abc8f,0x0000b82bc5671a8c,0x00000466ffaf50eb,0x000fdc348fa58667,0x000299a75ff5aab9,0x000000000007f784}}, + {{0x00064348b9a55592,0x0008f24b18ccf351,0x00046d73b67eefc8,0x000977c532d340c4,0x000191002448043a,0x000960397a2de526,0x00034e1e11027870,0x000000000000164e}, {0x00056330f30da4d6,0x00014cc5f57288f2,0x000974f0c19f8ace,0x00020963266aaedd,0x0002c3ccd59f3b15,0x000a6dd5dfaea30f,0x00035a1da2e1fbc9,0x00000000000ceda8}}, + {{0x0007996f48325ebf,0x0004f7914213d709,0x000270acf84435ed,0x000e5a126a34238c,0x0000701ce8c76eda,0x000656e02e566bf5,0x000fbf3562e87555,0x00000000000b4e8e}, {0x0008d6657de7885e,0x0004a5f10a503e86,0x0006a10baa0b8f13,0x000fc25cc2f2e415,0x000caf5718c149d1,0x000d6b890e973bb1,0x000f129b8825dad2,0x00000000000e2f00}}, +}, +{/* digit=39 [{1,2,3,..,}]*([2^156]*G) */ + {{0x0009cd8cd3edcb0c,0x00022e37211bdab0,0x000bfe0383f52218,0x0007e26a1b9f8b57,0x000d7d7f72d5fdcd,0x00049c9205641e45,0x0002a15377c1bec4,0x00000000000efc7b}, {0x0007344da1d40eaf,0x000b6c657a9ff3f7,0x000acc6777a25729,0x000d1bcd020eaa96,0x000a3f6860c76bfc,0x000c7c80617534b0,0x00056b8ce5722284,0x000000000002bd74}}, + {{0x00070f4fca1b2907,0x000d2aed02b6a844,0x00048854f708389d,0x0006ec4654e7c314,0x0003e7034bfd8222,0x000d6b555008ac00,0x000d44e343c5407f,0x000000000001b429}, {0x0003fda90bb8f0f9,0x000bce0702a33908,0x0003c08ba27edf85,0x00072f6d46524015,0x000d35f600437e6d,0x0003e8cc4d92655e,0x000b40a0dbaac627,0x000000000003c3ff}}, + {{0x00098d832fcb2cab,0x00078bc06ecab0e1,0x0004e7cd0ece1448,0x0006fa0453c94bf2,0x0003ed1a6731a6fc,0x000c3f1fb5460f94,0x000d4eeb11656a4e,0x00000000000ff1e7}, {0x000efd2eb43b2558,0x0009059526466dba,0x0007bc3cfc024713,0x000588824fd2ce63,0x00039f2c29257bdf,0x000e97f3013df0c8,0x0006411bf621e6de,0x00000000000ebea6}}, + {{0x0003b015d907e90a,0x0004e5906a35b43f,0x000f32388b4d1260,0x000ac9136f847648,0x000bbe0f1dd365c8,0x000d26c21f73b3de,0x000ae740358868a2,0x0000000000076792}, {0x000fc16ec80c7bf1,0x0008d3ecea1669e7,0x000b1ce4e42f6130,0x00091090e0062443,0x0006dd94681b6db8,0x0005a3de2d29106e,0x0006ccb40b8694a8,0x00000000000936b8}}, + {{0x000fa93eb46c6ed1,0x0009f28d33e792c1,0x000af8e666ab1b38,0x0009f3bce683c5c2,0x00098371fe755a74,0x000712c1d717629d,0x0001aa5e828fc057,0x000000000007e4c6}, {0x00082c4505e4cd17,0x000035d927bad55e,0x000bbbc997dd1436,0x00099a398591dc25,0x000a4836664c560a,0x000d79298c885fe8,0x0001d7d18acd4226,0x00000000000185df}}, + {{0x000755a507c76d63,0x000c69d8a925b591,0x000ef5ac5d730610,0x000ca6ddfb534b8b,0x000c6dd78a324f53,0x000a146d54e64874,0x000201336e5b46c2,0x0000000000098395}, {0x0001a5ef82624226,0x0004ca4c095220d8,0x000ae0a7c3b4840e,0x0002f64c36286ed0,0x0003c3ebb08c0ff9,0x000f00c3057b1b90,0x00036ec6bdc9b665,0x000000000009a46d}}, + {{0x000c3639d049078f,0x00048d67dc92ab51,0x000e52783edc1242,0x0009baa8b87c0b05,0x000052760ef4b6f0,0x00047bf855a8a903,0x000e742e2ae75610,0x0000000000085bd4}, {0x00097e1bd11078ed,0x00093ced11ff7661,0x000e3244d9aa20e1,0x00088ff24b3e912a,0x000a1afd219683d4,0x0000d21286e166fd,0x00039c66a912114f,0x0000000000005c9f}}, + {{0x00070dd4c4f3a35e,0x0006d913f92069a9,0x000aaa1c8b2107ab,0x0004e2c787c35959,0x000fe7b7b7ddefab,0x000e28e6aa55d465,0x0007bc921aaad834,0x0000000000012d6a}, {0x000d81dd493823d1,0x00072109803c417d,0x00095b2d5e30421d,0x0008bdb99c5bb670,0x0006bc7c2da71a8c,0x000927eef1cd1c2b,0x00041050189c975f,0x00000000000229f9}}, +}, +{/* digit=40 [{1,2,3,..,}]*([2^160]*G) */ + {{0x00086c2a1c05c1ca,0x000a911a8fde5d4c,0x0008768c091692e8,0x000c275c74dfe82d,0x000c38373a506818,0x000e5f88f2b0294a,0x00083a584c4061e8,0x0000000000073423}, {0x0003f61270e03ada,0x0002d263895b3203,0x00007b3b0d15f74f,0x00059da84da7f0d6,0x000a924a09f21443,0x0009ad83576e3095,0x0002af612986e3d6,0x0000000000039212}}, + {{0x000c342a3198c068,0x0005d3ee0a31c35b,0x0003fc2cd3c80f60,0x0004f4ff0fbfa963,0x000efafea65a90a6,0x000f4b9f9513f054,0x000590796ba7479c,0x00000000000932a9}, {0x00037547e06b6b4e,0x0005d93af8a64743,0x000922627b827de1,0x00071e9c1a46c909,0x000f4c9bca7223bc,0x0008cea30000643a,0x000ec2b6d967c784,0x0000000000073312}}, + {{0x000ecb2626cc0655,0x000eafeb707ee40d,0x0001edb8dca9d02f,0x00016459a0d32bae,0x000a1ffb926626de,0x000578b4a9a2ff38,0x0004434e5ad96d8f,0x00000000000883e7}, {0x00041045bc252635,0x0002d1d8eecaa72c,0x000edd696d444309,0x0002faed758ae41f,0x00004a85d867e49b,0x0008cba866a9a229,0x0009822fb89dcee6,0x000000000007f09a}}, + {{0x0009f15eb1bbb5c7,0x000d952ec99556bc,0x00015795c8a4dc35,0x000337c6dcc7816c,0x0009791f7cf1e881,0x000885a42e4e7b6d,0x000e41faa717aa59,0x00000000000f9c01}, {0x000171c4ffe4a6bc,0x0000ccf208d57a05,0x00042714fd20944a,0x000871b264ce04b2,0x0006cd42026a7261,0x0009f99fe66be4a8,0x000e2bc5397b7782,0x0000000000024578}}, + {{0x000b87e03bf622cc,0x0002fadc79436506,0x0000be1fdf9a8888,0x000aaa40406c1296,0x000c8b658d3cef9f,0x000435baff4e6388,0x000c997262beb41e,0x00000000000fdaea}, {0x000ba84e0b8f458e,0x00045d359f7d8428,0x00016b951ae31b5d,0x000f03229498ba51,0x000a85bf35adb18c,0x000aa4bc8c67388c,0x00027a8a7a6aa262,0x0000000000072f46}}, + {{0x0001e4a772f0f152,0x000520733667a853,0x000ae90cf08b2488,0x0009b27a7bc26604,0x0008eb4f0c7a7ca2,0x000f276309fefa69,0x0001337b6f351301,0x00000000000fcfb1}, {0x00022648d86fc4cc,0x000979928d9cf841,0x0009da8838c5ffbb,0x0001acbe041bef47,0x000af8d998547fbd,0x0005a0dc57d25159,0x0009332ec3a7d8db,0x0000000000087e3e}}, + {{0x00088fc716a5b4c1,0x000423fb812eeafe,0x000a6b9f65779527,0x00041838fbefbe46,0x0004a4b24a05e572,0x0000c0a432b7d49f,0x0001db23b138d071,0x00000000000a85ec}, {0x00095de9d8768d19,0x0006d7cc1f3d657e,0x000b6e219733e2a8,0x00023128f56981d2,0x000eb4080a011bda,0x000999b7f68663ea,0x00080c8dd7ba7e9f,0x00000000000b6865}}, + {{0x000b2ea58bc5b2ba,0x00008ba8418f2c05,0x000ab2d74f8719f3,0x00038d7bce1e82e0,0x000eb397915b4e64,0x0004cf6599e489b3,0x000affa9baea9ffb,0x0000000000042ef4}, {0x0001f2cfd470aeb9,0x000eeae3fb532a9f,0x0001d5334d1ddf3c,0x0008e28defe047ca,0x0009d24e60fe8972,0x0000f710c63a8c67,0x000d3cadacbf9247,0x000000000005e198}}, +}, +{/* digit=41 [{1,2,3,..,}]*([2^164]*G) */ + {{0x0008597cdef10944,0x000f4294d29542ec,0x00058a58394c4343,0x0007f9158f95038b,0x000164420c94fa1a,0x0003caea8b137981,0x0003402b686e1e09,0x00000000000f9e1c}, {0x00006da6276d2e4f,0x000cacd1beecf39b,0x000bd69a9fc92254,0x000c7192dfc2b165,0x000dcee7e854cecb,0x000635cc82cdb955,0x0007d39fefc321f2,0x000000000002936f}}, + {{0x000f165eb19500c6,0x000f54962c020b57,0x000116eb855d7c76,0x0009a79dd189c401,0x000d6ce517a77854,0x000d6bb9747675cd,0x0000295102294e32,0x000000000006ed1a}, {0x000926ef8530f97d,0x000353efb54e82c3,0x0002eec5a292f22f,0x000c2948967fb050,0x0009be04e909955b,0x0001efad6373615c,0x00097af1fcf82011,0x000000000006fd2e}}, + {{0x000445389cf3da63,0x0002b85e1e4ab383,0x0004d8f24163478b,0x0004da1a717e0356,0x00080f1bf3dfc0b8,0x000a6fd41f1a63b2,0x000cab47b74201ab,0x000000000003518f}, {0x000a17bf41f156b8,0x00031e12511fae1c,0x0005a421fc7a58f4,0x000fb10db5665c05,0x0003b99f4d5a20e0,0x000b7dbceb5448a3,0x000b87cb1847ad46,0x00000000000fdcad}}, + {{0x00040c75d27c479b,0x000823f2b5bd3e20,0x000298ef45cbe8a6,0x000f2db94256fe1f,0x0009318ddb03532e,0x00024c8e1acbfc45,0x0003db2375f9fd5f,0x0000000000037078}, {0x0002335b7531e78b,0x000251bd461e7e12,0x000e223c32f4b08c,0x000777d8845f315e,0x000697fc92c7c9f8,0x00092954081aed29,0x000fe09f2f8d7949,0x00000000000ff5eb}}, + {{0x0004fbb34790cc07,0x000a4397049f47ff,0x00000e7e84e96f9b,0x0005ec1e7862c0cf,0x000834350bf1ce6d,0x000ec8d7417a98db,0x000aa86ceccd8030,0x00000000000bcab4}, {0x00032ba3b5c44605,0x000c04378b1fdff3,0x0002189e90f61242,0x0000faa8d60f86df,0x000a3573271abddf,0x0008f8032987583d,0x0003f6b0afe4ec4b,0x00000000000b69d0}}, + {{0x000f8df0532bb051,0x000c5bd9a66d6010,0x000c7470f77e12e7,0x00051dfef38e9b37,0x0005754fb3fba751,0x000069b72a3348ae,0x000faf1218fa8f13,0x000000000000835d}, {0x0007a4c220543f04,0x000c02121a98ebed,0x0005ec4ceabea5d8,0x000a4be1a1eb6eea,0x0002adeb3ae51b23,0x000ea2b45b5c48b9,0x0008eaeebd305ded,0x00000000000c3719}}, + {{0x00055d2a529f419b,0x00062f73471b59c9,0x0003ecf010a8f9e8,0x000497dae082cef5,0x0005c3e563bc57cb,0x000125f95dfcbf2b,0x00001922149c0fd1,0x00000000000425bc}, {0x000c9ac134356e8b,0x0000e049476de7aa,0x0008c62ed440f124,0x000c62d1256424f6,0x000541bc66fa56c5,0x0006ada140a118ee,0x0008c50d8e9ff829,0x000000000000134f}}, + {{0x000b2c8bea306a01,0x000b1d0960bd7257,0x0002ca4efc9832f7,0x000cc77a98509175,0x0001e5f81554975c,0x000cff2c8b41bd53,0x000be3bdf8ab57c8,0x00000000000f5822}, {0x000ad597c5610627,0x000ae1f0ac0e6f99,0x000855b71125b2a5,0x0008b82e3cc86ac3,0x000d2b2beaee22bd,0x0002617ffc43bde8,0x0000968168781e41,0x00000000000b7ee7}}, +}, +{/* digit=42 [{1,2,3,..,}]*([2^168]*G) */ + {{0x000956a7f54f949d,0x00074086945790c5,0x000771ce236fcb82,0x000b0c6000575064,0x00080b09adeb2c04,0x00081474f468be6e,0x000cce2f3bf32b6f,0x00000000000a712c}, {0x000c24bf8b416a6b,0x0004c292cee41c19,0x0008e149d7276386,0x000a66156f47b2ac,0x0005840b5d1be54d,0x0006e8cf62ca7683,0x00053eb52adb6a8a,0x00000000000dade1}}, + {{0x00026c98ae834331,0x000b365f7d2c0d6e,0x0004cfcca31f7dbe,0x000634c986436f32,0x000133356165e268,0x000c7957d6334d8d,0x000983f17164269e,0x00000000000b8093}, {0x0008676a1037657d,0x000d9edb1fe5cc2a,0x0001cd1de0787da3,0x0005f4da691b6657,0x0001e1e2727e746e,0x00027b0296117129,0x000197bb4aa8f16f,0x000000000007f42c}}, + {{0x000a6e4b3ca52862,0x000cf2af8bdfa5a6,0x000675c2d00d6d96,0x000d5ced7046d2e5,0x0007d545fd33d57f,0x00061ffd75ea025f,0x000242e2ccb6f431,0x0000000000009406}, {0x000194e235777423,0x00019f3536d60805,0x0005fe57dd0b2a05,0x000b06a5cc554450,0x000f9a9e2a66fd15,0x0003dfd0261b0feb,0x00051fdc3c057665,0x000000000000a8ab}}, + {{0x00014e15511a3745,0x00067fe19901abc4,0x0000c6f09a808e87,0x000012556c4ce5cb,0x0005938c89ab92fd,0x000a587b123172d6,0x000c50a71f8a33aa,0x00000000000b55c9}, {0x0009dec34d6b29ab,0x00056ec005f6a241,0x000b67510d45fff0,0x000d67f9e26361fb,0x000321389c2598a4,0x000ffbcee7f0a2b2,0x000888d158820795,0x000000000009f36a}}, + {{0x00065f3227de5d3c,0x0001e5ffec1d7642,0x000dceb00d947f3b,0x000844c649c850b5,0x000610fa337dfbe3,0x00080773d450263e,0x00066c44f7c8f402,0x00000000000e8969}, {0x0009e0325576575b,0x000a42587f475435,0x0002c020daa3c5c5,0x0002f667071543b1,0x000e06577b749e90,0x0000bee1303398aa,0x000cec030926d691,0x00000000000ffa92}}, + {{0x000298023770357c,0x000dae4ee3345cdf,0x000943bb20278bd9,0x000ca667ce118490,0x000dcb69c7ead817,0x000680afeda222cd,0x000ca874ac74709d,0x00000000000d9596}, {0x0002187a0dd3835c,0x00082dff57da7e9a,0x0006d7aa1a2ea94a,0x000ba28b7fbc1b01,0x000c13d4ed0f71c0,0x0003a2ef260faab1,0x000dff6fbe3567ea,0x000000000004e577}}, + {{0x000b9f236346df15,0x000f89b758b50c99,0x00075b638b06df34,0x000b3c39ee88a784,0x0001105e1ec04669,0x00088ea133f36a67,0x000aadd0f30e5d9e,0x00000000000baecb}, {0x000d89dcc4fedb34,0x000d3ec65be650a4,0x00093dd7d659e073,0x0005d29942ce52c4,0x0007d3ce28d4f719,0x0007fc9041220187,0x00055e9c962aa1a9,0x0000000000065c5a}}, + {{0x00095e9750ada30e,0x00094eccb421e7ff,0x000dfa5cb406ba75,0x000da9e05a53972f,0x00007bc99fead344,0x000f77bf53a8035e,0x00078ae0214485c0,0x00000000000e54df}, {0x00053ac771ed9aaf,0x00027def45af5dcd,0x00024afc33d18821,0x0007db1c337e0181,0x0006b84671d5a9b1,0x0007d696d026a4f6,0x00022a606142343b,0x0000000000081cfd}}, +}, +{/* digit=43 [{1,2,3,..,}]*([2^172]*G) */ + {{0x000d2a53b2756567,0x000f3feb984b33c0,0x0004e95d9895327d,0x000f97e3ca0a9a03,0x000dacc000ac177e,0x00040f51a76d4796,0x000810bad0fa6eb1,0x0000000000006ebc}, {0x000c76db6b103c54,0x00004f89eb78f367,0x000ad3bb031162c2,0x0009cfbb25e9d1c3,0x000fb4e7aef3e2b2,0x00067e8459388ea8,0x0006d7ee606c12e2,0x000000000009f580}}, + {{0x0008f59540514451,0x00028cf947c06046,0x00062665be2e4fbd,0x00015c05f1835ca3,0x0002d8c79d90d001,0x000b5f791df08415,0x0008cdc0c3a6846d,0x00000000000749b1}, {0x0000ce2ed12d25c3,0x000d8d314b7d4a22,0x000dfaf9b4508139,0x0005af06855a9438,0x000ee9d02ab997ed,0x00038a5d0ea84ae9,0x000eabb87e903432,0x00000000000650a0}}, + {{0x000c8f034ea36274,0x00088357540ab419,0x0000f5e32c760e57,0x00073ac14d7fed37,0x000fd186ee3d33d2,0x000a7b1d9fef6b9f,0x000bc2a94c207101,0x0000000000050bc8}, {0x00013f9560f76983,0x000e5c68959c999a,0x000056367228b52b,0x000a4fce6861310f,0x0000c828330f7a73,0x000f74fdb19bcac9,0x0002f473e3b66f7e,0x0000000000052d8f}}, + {{0x0008b2d06a3248b0,0x0008e58225208828,0x00095368e614a61f,0x000e45562fe86dbb,0x00082dc5b2f11224,0x000096555a8c8a47,0x0004528a957b8dc3,0x00000000000b1591}, {0x00063a60dfca11b8,0x000161e563c57eb9,0x00024a9e6e7bbb16,0x0002de99462e7a31,0x0001c2489214f8f6,0x00074639c6b3dfe9,0x0004b56c1d8fc421,0x00000000000ef88d}}, + {{0x00071f1bee09bff3,0x0004a6eda384edeb,0x0001d457a27a9c42,0x000e6af10e01b58c,0x000ae1175185c441,0x0000dfcc6ac962bc,0x0001b472d34d676f,0x00000000000a9412}, {0x000f38c043747e7d,0x000ad77dea14649d,0x00065b52576e79ef,0x000c09dd5d17db20,0x000db45a6e94625a,0x0001f8caf579edea,0x000b8ea659282a84,0x00000000000c11a7}}, + {{0x000f9bf364d3e9eb,0x000407d0850b3dae,0x000e31cf311bd53b,0x000f1f891cb75575,0x00089d3b6afe68ce,0x0003b46e427a6ba7,0x000059f220f9c1f8,0x00000000000f526e}, {0x0007512e159b9fa5,0x00094edf3cccac66,0x0003e3258b2c0e34,0x000d9e98cc78d3e7,0x000b5fa48469cc09,0x000686001391bc40,0x00073a22bcdcd522,0x000000000007c599}}, + {{0x0002ae0971dbb084,0x000bd9de8555bad1,0x000c9834d42cb891,0x0000285de654b80c,0x0008802be80bf17f,0x000d823bf33998d8,0x0006b64095923d5a,0x00000000000e848f}, {0x000fcca2a1ce91f8,0x00015c6e95017db4,0x00048a3538b7e8ae,0x0001be7a70558759,0x0008441da4770c3f,0x00048d4c2b652671,0x0008deaba3b06f9c,0x00000000000086f1}}, + {{0x000d473962fbc397,0x000b15a4a5ce3b56,0x0003f34c786123b8,0x000388e4efe9a313,0x000aef9d074bd459,0x000ab9cb03a45c11,0x000566f68ab50b93,0x00000000000ecd9a}, {0x0008303c4d104a42,0x000f0bfb79b7f7f4,0x000a0520b1df9755,0x000aa21877390f14,0x0005e314cfb54f31,0x0008eab122de0c64,0x0004f656d904f623,0x00000000000ccb4d}}, +}, +{/* digit=44 [{1,2,3,..,}]*([2^176]*G) */ + {{0x0007aa3a213de299,0x000c93eb83a8707f,0x000eb1f52edb04b6,0x000c77a53abe4e9c,0x000ebb9feb8257b8,0x0006f922e0a14673,0x00026cc0a6cbf7f2,0x00000000000a32e5}, {0x000ec20f9c4de649,0x00049ca417e66df1,0x0009b8c741987bef,0x0000e7a62e135de2,0x000ea7ee82c72bae,0x000776c74962bdca,0x000feb573d7f6ae5,0x000000000006ffbe}}, + {{0x000a70e677b6f831,0x000b9cbc0bb18f0d,0x00037297c3884bb7,0x000b350d38064428,0x000c397a7602f62c,0x000987d82e4d2f1c,0x0009faa54bd48e43,0x000000000004f0a1}, {0x000a1b4997cc48fa,0x00005fa0c9a44d6a,0x00012729fa8ce7f0,0x0002c5b9cbd8d343,0x000813d979568e24,0x000da55fa1671eb0,0x000ce5ccae388f40,0x00000000000f376d}}, + {{0x000f917fe9a26ae0,0x0003ae54d92cd055,0x000e0e9599c7454d,0x0007fd2849f6143a,0x000dacd0202d7c90,0x00092d19abb11dd2,0x000677a4913a701d,0x00000000000cf610}, {0x000f3626f0aa0d9f,0x000a3fff1e1d462d,0x0009edea6495252f,0x000f33a92cabf724,0x000ce329d1adcafc,0x0009a0e4cd571e13,0x000f867626ad237a,0x00000000000130d7}}, + {{0x000f8196d845d3e6,0x0002f8a89daef137,0x0004ece7e9ffa3ea,0x00023775b80bb4b5,0x0002a45b362648d9,0x0005bfe910a587c5,0x0007d7daff503cc7,0x00000000000116d0}, {0x000600a28d48ec00,0x000916b5a471517d,0x0001f4eebe019105,0x0006cfc595abf8dc,0x0009ed0391ce8f07,0x000fcabd3c9de4ce,0x0009edaaaad03ae1,0x0000000000087b19}}, + {{0x000b51557a9fd4ff,0x00034b0641d0941f,0x00049c97e60548cf,0x0005b4b00d5ec6f7,0x00015569d89ad12a,0x000ac72089be1a11,0x000df19c0566deff,0x000000000007034e}, {0x00000817b5f1bb5e,0x000e5636aeb6adf8,0x0006c2164b0bbfac,0x000f898734e9d301,0x00095ccdc6bcf4e2,0x0008a4f28daf7421,0x0002c39d39249f60,0x000000000008820e}}, + {{0x000d9387d2303055,0x000ac620248118e0,0x00080c838dc206ab,0x000eb38d7f033fdf,0x000232646d6f86b3,0x000dae596ee3226b,0x0008e58c4825f6f1,0x00000000000a5bcb}, {0x0000edaef1eabcc8,0x0006f904a53484a2,0x0007fa1deed27103,0x000329f21d45f8ad,0x000a06605546af6a,0x000a93d14f20ad88,0x000174cf7a0e9619,0x0000000000091c97}}, + {{0x000ae272638371ad,0x0005559edd263abb,0x000509e662e63add,0x0000d304e7f07169,0x000119b88200bf4a,0x000da801e36fc0e4,0x0002c791db560240,0x000000000002c72c}, {0x0006387b3ebbf52c,0x0000dfe960c2596c,0x00093166fd89300b,0x00080febccc1576b,0x0005c3c88f475a64,0x0007bd8ec72f4e5e,0x00055e224e7e749a,0x0000000000076314}}, + {{0x00073d61157ae785,0x000ab42c9fad4fc2,0x0000e5d3107f2d93,0x000c7fdb149854b8,0x00002fc359eb0cf4,0x000ec86034a7d900,0x000e149ff0c3ea29,0x000000000009b24e}, {0x000512a0eb94d71b,0x000e0638c80999de,0x000012d24a63feaf,0x000e0f8a07ea5482,0x0002aecdec3f2fb1,0x00074025b1e580d3,0x000164bbf895730f,0x00000000000dd529}}, +}, +{/* digit=45 [{1,2,3,..,}]*([2^180]*G) */ + {{0x00051b4cfaf372e5,0x000b9fa2db519927,0x000d4edc529b8ffb,0x000af1d605917201,0x000e782a09939f88,0x000c710d31c5fea5,0x000365e0fb15884e,0x00000000000d32ce}, {0x00054592dfab29b3,0x000d7d9f896aa46a,0x000ce02cec631ef0,0x000992dca6e73436,0x000a6fd0c08b1b76,0x0000f5c2376338fc,0x00035bc3ea4c65a0,0x00000000000b316b}}, + {{0x0001e6b975664a84,0x000aa14f962e38f4,0x000c4a3248d485a4,0x00011c079e777bf3,0x000b4657c31b2c0e,0x000494de3a1705ef,0x00071802688fd23c,0x00000000000412a8}, {0x000b58909626d6fa,0x00004878fc7ace41,0x000bfc58da0a4094,0x0003c4c704b70c17,0x00087323c0087c81,0x000089f1a98553da,0x0002914f63cec663,0x000000000009655d}}, + {{0x000f1be887dbd011,0x0008384e5541ec05,0x0002bbc7edd0f227,0x0003ad69beaad3d1,0x0000f51c2714e0a4,0x000ea5b0c97dd182,0x0007caac2b4cb457,0x00000000000d1176}, {0x000327be0b446dbc,0x000e318ccf36cb48,0x000fe4f5fd270bff,0x000ce43d8d292a8d,0x0008d58c4ee79811,0x0005c65a772c5fc6,0x0006695bc0f0bed3,0x00000000000cbbf9}}, + {{0x00002ac6c24f6061,0x0003810586ea68e3,0x0007603f1b64b158,0x000c4d7dfbfa352d,0x00021e1c2291a42f,0x00011760abf38c38,0x0004d746e40ef60e,0x00000000000dcb97}, {0x000c4f8f01f54098,0x000f1755b105ba56,0x0001f9ffa1baf4e7,0x000d0b00945db608,0x000cf2809e1ca630,0x0006c95c5a160ac9,0x00074f38fc1113dc,0x000000000005d525}}, + {{0x0001da84872cc14a,0x0009a7eba3da615c,0x000558d3935c6438,0x0007d982b93d8b2c,0x000c7cad1f758c91,0x000ff150aca8fc6a,0x0007fa5f581f19a0,0x00000000000e0832}, {0x0005d538d28d5c50,0x00038c774f18716a,0x00051c30fd1c0854,0x0006e9b8ad72b112,0x000b917986cfce03,0x00025cf9b463f9eb,0x000feabe51632813,0x00000000000dd7e5}}, + {{0x000710a35bbc6ad8,0x00005a4e9f29eaf6,0x000a92c5e19e2d59,0x00084e42993359de,0x000f224d5aa30e21,0x000132c484f96ce7,0x000f5f0862e2003a,0x000000000000f015}, {0x00066db2ab4fc1aa,0x0007cab9d51492bc,0x0009b538d3bdb7a7,0x000e671c1fd96e3a,0x000e71a703b24865,0x0002add107baf4db,0x000d3083dd6cf914,0x0000000000098461}}, + {{0x000b2da1393d8e42,0x00051714c1d1ba41,0x000ef78ff03cd88b,0x000ea3a6951ac80b,0x0000ac00c8377f23,0x00024cc1b5c59929,0x00062bf6efa2b3bf,0x000000000001e844}, {0x0006a668e721edeb,0x000069bda627d119,0x000d91ed1a995ffb,0x0007089c3b94ec3c,0x000e3031699ad1ee,0x0002b2453f75dba6,0x000ed48ff75f7924,0x00000000000289bf}}, + {{0x000ac44be8741dd1,0x0002fcda68a7d811,0x000fb56aeb52d290,0x000e2dadce20b92a,0x000cfc69dca6483b,0x0004f98917de1601,0x000a564bec17aaac,0x000000000008d479}, {0x0009255137ea7d35,0x00025c623cb8d743,0x0009f513ea4e4bb1,0x000b7c030dcde621,0x00073a1733fdda9b,0x0002fac31f84ea32,0x000449d7afb6c3e8,0x00000000000d3897}}, +}, +{/* digit=46 [{1,2,3,..,}]*([2^184]*G) */ + {{0x0006c80cb0000ec5,0x0007da189f30f16a,0x000d675bfc196669,0x0009ec37d8da76e8,0x0006c1ea7c10307c,0x0008c62d4b3e1d00,0x000b3ac15e20b3b8,0x000000000000bff3}, {0x000b01f1748ea86b,0x000e29e330eb12b6,0x000af2a26953e630,0x0003cb002e1eb2af,0x000bf525e4d4157d,0x000a3dff1638f297,0x000051a20f833234,0x0000000000045a9c}}, + {{0x000b35a3033b3940,0x00007fe9fdde8b8e,0x0004a1bfc8bd5420,0x00049acddde6f6e9,0x00097e54356ca653,0x00009f73cc53c29c,0x000277ee15ad9457,0x00000000000e5429}, {0x000bdd741f2769e6,0x000d6f52035cdb19,0x000b835933b3195b,0x000b0ceca319bd4b,0x000b6951fd8d26e0,0x000c34d6f4e7eb67,0x000b59ac3a6f4395,0x0000000000000f60}}, + {{0x000d7763c7959780,0x000c02c47010c514,0x000f6a495cc56b87,0x000be509d930f6e7,0x000d5f56cf045c8a,0x0002f1fc16bcf875,0x0007101f6456c006,0x000000000005304d}, {0x0001668b6ef47661,0x0006dd76452e46c9,0x0004266da10fc06f,0x0009fc89021bde74,0x000f4babfae0b5ae,0x000a61fd6505c6b9,0x00025a99d943c17e,0x0000000000059bf1}}, + {{0x0003de8a392493e6,0x0009cbd10b8bfc25,0x00082fa94d1d5f3e,0x000be5ec0c907818,0x00071ad167ce9a18,0x0008c1c563677f4c,0x000275ccb254e2a6,0x00000000000e2c4d}, {0x000250541623e5c3,0x0003f44958cb1bf9,0x000db2f9dd62ce34,0x000a767a2ffdbd52,0x0009b0b6c22d7445,0x000c92b2e0e789c9,0x0007823ff8b6565d,0x00000000000eca98}}, + {{0x0000ad4fec1eb621,0x000c36618fcad673,0x0002540e2f8dc71a,0x00039947d7ce5530,0x00095257f24b90ad,0x00098768cbf8c458,0x0008305a94992020,0x00000000000bb6d8}, {0x0007503283325be4,0x0007dfae8f1616ec,0x000fc3e0aeb8a2a8,0x0001ea9139ea0507,0x00012e39e1d8a72b,0x0009c7bc282229a9,0x0008254153bf3e47,0x00000000000c5541}}, + {{0x000605d76cba7718,0x000a6fadf9be90b6,0x000490316f096fe8,0x00024ec2f9953940,0x000861203303cbad,0x00089a4be6236a26,0x000a82e4bafc3365,0x000000000005e23f}, {0x000642137e1da447,0x0005c8ccbc576c76,0x0003f63011c9e098,0x0002d5841df8dd26,0x000914d31fcde6bc,0x00026010bec24e1d,0x0002f3acaaf13efc,0x00000000000e01b9}}, + {{0x0005639fc34e5a27,0x000c7c52789bb2f8,0x0006d4ce23fe7231,0x000f95aacafbbfb9,0x000dc7f6eb6d8b6d,0x000b4c9d737afdcb,0x00045357775bdd6c,0x0000000000011007}, {0x000bddf07c5f1b9e,0x000e3903e5ba1399,0x000d7d2fc919a9a5,0x00018932d7ac9e4f,0x000543ce66a8046d,0x000956410e2fe9d1,0x000f7244b5beb4d4,0x00000000000bb147}}, + {{0x0006e03c443812f7,0x0005c6f6a6104456,0x00098182647d3e84,0x0009a6ab51989e5d,0x000f68f5b16842fd,0x000f7fe671b60ce0,0x0005a897324d8756,0x0000000000067681}, {0x00061f269664533a,0x0002a265ee993d1f,0x000a90ce6a02c969,0x000232334b4adb0c,0x000e1e5a8d18e909,0x0004f6456ddcd233,0x000d9b3dc5b27c5f,0x000000000007f421}}, +}, +{/* digit=47 [{1,2,3,..,}]*([2^188]*G) */ + {{0x000b170252588bc8,0x00099bfc40c30a63,0x0001ef23d6587c46,0x000b54dc027511d3,0x0004cf3484ce4fd7,0x0009beea5f479928,0x000280655ab81106,0x000000000007392e}, {0x000148f913baced2,0x00084522e7b403b5,0x000493599cdac0b8,0x000b95877f3913fd,0x00067dd525149cf1,0x00008cbca3e06b92,0x000529992e920e29,0x000000000006d6ed}}, + {{0x00097dff92ad4838,0x0001e8a46c9112d1,0x0000711ed277a798,0x00064f15cf8e4ca2,0x000a01cb3488d4ba,0x000bd7ded01b3908,0x000ae169b1fa5d38,0x0000000000018b2e}, {0x000f3694f52a1f22,0x00019619324bdbe0,0x000d1d925851b48d,0x000f42e925b3f6ab,0x00095f7e4d11a397,0x0000d9f0132169a4,0x0002e5c0fa9a548d,0x0000000000089d8f}}, + {{0x0000115baf0f7c2d,0x00040240239ae483,0x000c7482d351827f,0x0007151f58ec53e4,0x000cc080d59ff9ab,0x000f782f4d397862,0x000d5873eee88536,0x000000000006c1d8}, {0x000c16042c611b2f,0x000f258bed3e5b15,0x00036e097964eba0,0x000c8ab8a482af89,0x0009e746a8549044,0x000a0548e0065858,0x000a492538d1b926,0x0000000000007cdd}}, + {{0x000178ddffec9175,0x0004c9c0d5230baa,0x0004bce21493d0f7,0x00090dd985154559,0x000c8dbfb46a67df,0x000757ce3223e8b9,0x000296f39529a36d,0x00000000000b4648}, {0x00000562605aa919,0x000dc330749e8973,0x000a3ffdafa653e5,0x0000b3494083aa87,0x000321e321c68c32,0x0003e78921161f5a,0x000ccc0980deedde,0x000000000006ad76}}, + {{0x0003725fda5a777d,0x00086af9a69e965a,0x000a3534516a8b8a,0x000a77f3e52375ce,0x0009a019a5932dff,0x000238091ac65569,0x000085d402f5c4df,0x00000000000d3518}, {0x0004a37271e8fafd,0x00007dcee2db4b54,0x0006c1d813edf12e,0x0005b6121bc49990,0x000e68b9808d9cb1,0x000d6ac5b40b34f9,0x000b8a98de63590b,0x0000000000039766}}, + {{0x00069c8c3d7c7657,0x0005171191261c8a,0x000244a0eba69bbd,0x000344bdda57f44c,0x000ac4f0cfd2ad4b,0x000543efd674b758,0x000d063bc058a077,0x0000000000056618}, {0x000a82ca14a01b7a,0x0009d95107c74391,0x000a3c4cfae47f34,0x000af35e3f1d63cf,0x000643ab87265dbe,0x00056c6fd012029c,0x000e304f588a4ea2,0x000000000003e5d2}}, + {{0x00081d2046b48f0f,0x00043847622b5217,0x000c2a7014a5d0be,0x0009da7b82c435cd,0x00025b73e01114da,0x0008b37b399c8c43,0x000ddab978fe55ec,0x00000000000337d6}, {0x00034bf111412925,0x00071e0d4ffda16d,0x0003fc3275d2e3f4,0x00062872913cddbb,0x0004f67405be2a7d,0x000a31060229afd0,0x0009d6e372202e49,0x000000000009fc21}}, + {{0x0001a0d511e4c022,0x0009173fa3508062,0x000e92c1603f0953,0x000549f58493d985,0x000adc79f602f64a,0x000512b84d9ceae0,0x0001516569e37bd1,0x00000000000151c9}, {0x000c6addaeefed36,0x0004c075678c2066,0x00015cc88eb8c3b8,0x000dca3a57fb96a6,0x0000223dc3ce6334,0x00011e2770ed9082,0x0008e274f9c3aebd,0x0000000000079c0b}}, +}, +{/* digit=48 [{1,2,3,..,}]*([2^192]*G) */ + {{0x000688b6fc0935b1,0x000f5378205dd339,0x0000b901357b7bc3,0x000c06c682e00f2c,0x0003114d5423dbce,0x00052463ef2a145c,0x000b0aa01d98747a,0x000000000007d717}, {0x000d2bf78a72f39e,0x000d29653bc4f4a5,0x00051b32471fd3a0,0x00043dcaf8e3f402,0x0000e86fe16ef779,0x0009ffdcf70774a1,0x0005c96b62e6f1bf,0x0000000000058874}}, + {{0x000b3ac410563249,0x000bc2a5f8ecef60,0x000af14f01d834e5,0x0001cedc59c4301d,0x00010111d9989de3,0x0000d5b951e0f40b,0x000ab8d29d229f96,0x00000000000d1dab}, {0x00033bacd39b8f1d,0x000bd7b225cc8ccc,0x0003c9f7b44c8f47,0x00052a1f5fb06b38,0x000f842b9081009b,0x0002725128a575d3,0x000cb7fddb48afe9,0x000000000000b452}}, + {{0x000dcfd459bff4dd,0x00050ae10069e26c,0x000e9f25bee973af,0x000caf27ebaad0bb,0x00073dd6119cbbe4,0x000fceefe5907bf3,0x000c7e0a723dff9d,0x00000000000f7cff}, {0x0002a3a44c0ca01e,0x000d17bc95fa21e6,0x000c0e71f388ad82,0x0007ecd27b3335bd,0x00027b8d7d49316a,0x00019058fbf08e67,0x0009ea4b209f93c6,0x0000000000059d8f}}, + {{0x000cfbdc0726f5f2,0x000ba167ec88a4a8,0x00009c64d249271a,0x000e2443877e6342,0x000603462cb310f2,0x0003afcee6321bf2,0x000dcd1dbd10ee9d,0x000000000002ca17}, {0x000667ac9826886c,0x000d509465265738,0x000151279a7a2541,0x000b0f95e1c59136,0x0001757d3a630043,0x000def1e0a09b94d,0x000d41533956529f,0x00000000000d4fed}}, + {{0x000c29ae93761a8a,0x0008a3459097559c,0x000f79e8fee087bc,0x0009a286ec406ef0,0x0006fee5454dcc93,0x000257f708d21427,0x00085e66a0e1a56b,0x00000000000006fb}, {0x0006c4387ea9f222,0x0000ac44f9df22bc,0x000c5644721083d5,0x000a8224fca1a819,0x0008f3ed85bf5894,0x000899b5b8586e41,0x000371d494dfb202,0x00000000000ecb8e}}, + {{0x00094e8a6ed08358,0x000cf690c0cfe457,0x00092e98638a5e98,0x0008042204d98a6b,0x0005bad2eb082250,0x0005823eec87a97f,0x0003f6d307c59ed2,0x000000000000df8b}, {0x0002a9b6fd1bc660,0x000e9280ae343343,0x00077184e86c10ae,0x0000e5a24d04e396,0x0007309830fcea93,0x000afeebc0269d9a,0x00002d41dc8f0ae4,0x00000000000f14ee}}, + {{0x000ef795d8c64486,0x00026efca7f7acdf,0x000411f7c32b0a9c,0x000b87fe57d08e0a,0x000a7d9a1967c9ea,0x000c2749248c01c2,0x00063911c97ed97d,0x000000000001cf1f}, {0x000b6334379af438,0x000d1541f8c0d49b,0x0006f782375b1fd6,0x000935ba6be190e1,0x000764494b4e9806,0x0003c00b6ec6c5de,0x000f15f04e2d4cb8,0x00000000000c0b84}}, + {{0x000c9d81a70917bd,0x000702e75a26e455,0x0005bf4870175e47,0x000d057ee7d8e4ba,0x000d8994f44953df,0x000538367b959110,0x00029cb4a16596bb,0x00000000000ef82f}, {0x000ea0c85d7d05e6,0x000305a7642ffe63,0x000b9d7a5d2d391f,0x000b23803a4184c4,0x00020f7fcd62c7ea,0x000a8a0c660c67ef,0x0002b041e05799df,0x0000000000004d35}}, +}, +{/* digit=49 [{1,2,3,..,}]*([2^196]*G) */ + {{0x000ffb708a3b5e85,0x00030c97c01eab92,0x0007510b2d7953a7,0x000ce807fa7d3c2a,0x000e81060874dba1,0x0007eeead69e6f96,0x000f3d6e3e0df74d,0x00000000000b0c87}, {0x000317c5146f214f,0x00028c55ae3dbb43,0x00014b4be1d3dc49,0x0008c591de7860a7,0x00066e546731a600,0x0001e45d48202f8b,0x00015a652f2d07aa,0x000000000006df54}}, + {{0x0007d6371007dea2,0x00049041c706cbe5,0x000dcf6b55c23258,0x000cd27839e9d5ae,0x0003bf3c4c067dc4,0x000b7bd22dfc9db8,0x0002da85b8094138,0x00000000000d0f4c}, {0x0000b16d9a334a33,0x00092d7b340062c0,0x0002bb5502deaa2f,0x000b2c2752366864,0x00010113a85fa340,0x000b327045ddd055,0x0002ff7dfc7ab29c,0x00000000000dabf2}}, + {{0x000a8373e5c690f8,0x000ca2fbce9bdf20,0x00049076d1995e9c,0x00045939f4cbaf1b,0x00092574a3bd48ea,0x00092c39a56c5400,0x00034384a39630e7,0x00000000000eef81}, {0x000361503c11fa79,0x00095f996760edb5,0x000c1bbc8ea81e13,0x00012e6966d70279,0x00052e6f7c63a0ca,0x000d13ead92a6d5d,0x00068146809d269b,0x0000000000067aac}}, + {{0x000cf4e4cd35d7a3,0x000a13fc9b3cedea,0x000ac33c871e844f,0x000a58afe1ad536c,0x0008cb39149f2003,0x000edf470cec4be3,0x0005194d578c99bd,0x000000000003a356}, {0x0001980c5865f55f,0x000607a762f2732a,0x0003ce874c8a141c,0x000817f270c508e9,0x00049fdb29c8dc0e,0x0002711d35a7be20,0x0000c2fa1a0be3cb,0x000000000003786a}}, + {{0x00065cdb1cddc024,0x000c41d0af6b5128,0x0006106e0f532684,0x0001951b1ea8fc4c,0x0004b1fae4826764,0x00023477bc0b9006,0x0009ce7012642f66,0x000000000005bf01}, {0x00001d44438309f3,0x0007fca1f46757f4,0x0004d56451db59bb,0x0004ef2d3868de95,0x0001044e0c189c03,0x0005e38c30533d92,0x000053ba6cf14ecb,0x00000000000509d7}}, + {{0x000af6aee4d4a85d,0x000c0e164268de02,0x0001633ba7cb9816,0x000979478ab17f45,0x000e0179ed0e734f,0x000a2686746d468d,0x00085d7e68f006df,0x00000000000e3d04}, {0x00073699ad94d8f6,0x000c30913a1d74ab,0x000e2aa1b6d33ea2,0x000a79e49eadd08e,0x00017dd8f954eeb1,0x000bb26d0433f5e4,0x000e2970a6281430,0x00000000000ff5e8}}, + {{0x000235f9cfa08aab,0x000eb6a352b56ce9,0x0002152b2e478d04,0x0007c7a240e6dc62,0x0002d313b4a9ee1f,0x00001a40585d5be6,0x000d5a1522c5d25c,0x00000000000960af}, {0x000459bf66d63a1d,0x000e4a3cb77f327b,0x0001a15093d3f2d2,0x0000c7d3b93fa9e1,0x00013c0383ad8409,0x000f7a220c77f1ee,0x000bfc461c93b776,0x0000000000004ac0}}, + {{0x000fd3f75cd14c88,0x0002a3c7d6b63ea7,0x0002b345f341120e,0x0005d20aa0eaa1ec,0x000fc0eab4908ed1,0x000d9f260e944ad2,0x000ba371525aa1f6,0x0000000000016146}, {0x000bd29ab6e83fdb,0x00068f94019075db,0x0002a02a4fd970a1,0x0001c37cab1060af,0x0000c8cac96f6a4e,0x0002466ec357fe4d,0x000e7097a8b8ab6a,0x000000000009c01b}}, +}, +{/* digit=50 [{1,2,3,..,}]*([2^200]*G) */ + {{0x0007eae876f30205,0x000645b0b5d68b38,0x0002f6471178cf56,0x0000a4a404a3458c,0x00059f467b6072ad,0x0006348091de8e25,0x000178a4b3570590,0x00000000000706f0}, {0x0007cba07f8d2545,0x0006d588d21aac4c,0x0001bb1a8ee3a06e,0x000e73d241bcd915,0x00022facc7ccf4e7,0x00025d2a0b8d8a1d,0x000608483c35a71d,0x000000000001ef9f}}, + {{0x0009cd91f152b14c,0x00034a704015f319,0x000a64fabfbdef40,0x000301f2ccb94180,0x00046f00d8aa697f,0x00038a0173ee8776,0x0005432b5afaf881,0x00000000000832d7}, {0x0002183eafee3abb,0x000d627c27ce1884,0x000735007191c91b,0x0005ac75b752008f,0x0001e84fe5f192dc,0x0005929cecf382e0,0x000ffa90e034197d,0x0000000000015ca3}}, + {{0x000596896506329d,0x00058cb51f038efe,0x00073c05f41ddada,0x000fafab41fe1a74,0x000da719f25493c8,0x0004f5cde6297701,0x0005426e9165bc64,0x000000000000c11c}, {0x000368f61fe7d95a,0x00098a2564809894,0x000e829acda88407,0x000592622b1d1be2,0x00026ecdd041286a,0x0009f952486a3d75,0x000b0f4b867e0a64,0x000000000000629c}}, + {{0x000259f3facaa9bd,0x0001d11dd860d21a,0x000b8c19c604b970,0x000aff635c019302,0x0001e3a4a900d4f8,0x00078c8ba96a727b,0x0007c41426daffde,0x000000000008d152}, {0x0001e6f4fd354295,0x0004a0c0d5233cfd,0x00066c04a38eba93,0x000bee43d914fb41,0x0008f3ba26a64828,0x0004eb26f8324ea3,0x0007bf027590f3a9,0x00000000000acd95}}, + {{0x000a71b96f713d9b,0x00013f4f668435ae,0x0008fef0f35f5919,0x000e86e7365712f9,0x00088a822bc0f607,0x0001299b3d588229,0x000b1a2cfbd63ac6,0x0000000000067167}, {0x0006f5a47be411d6,0x000b0750f673f622,0x00032c38df6a058a,0x0005bd169123c758,0x0006eab99b375e6d,0x000aec6a36a93d1b,0x0008186ef4f7e68c,0x00000000000cf3ed}}, + {{0x0006410726f50135,0x000fd959353be170,0x000b4de98d5dc91d,0x00026f799d7a4f4a,0x000e52fe4b656a48,0x000038573ab146ec,0x000e8494fc21d735,0x00000000000f4d56}, {0x0006901ebf8c490f,0x00093e15ca04c71d,0x000ef178dcf47997,0x00079244f21a9114,0x0009dcc76132ef7e,0x000e890482eecb7e,0x0002c55b484745db,0x000000000006e43a}}, + {{0x000b8d876ab51a4b,0x0001af92b3072f8e,0x000d8f5d67f2d2e3,0x000d5edc578e3a39,0x00029587fa22e51b,0x0002eba85efda70d,0x000530cfec17089b,0x00000000000af7ba}, {0x0004893a5eb2bed8,0x000bb5ac155ae396,0x0009a3394a2b6335,0x00086c2c38718a82,0x0003d63745b7280e,0x0008a79aa9d12de7,0x000bf70e8ea855bf,0x00000000000bd705}}, + {{0x000260c123f30563,0x000c53ede2484b68,0x000620a80e97a435,0x0009e93962a667bd,0x000b130f2cea5606,0x000366a66c931266,0x0003b14bd6a6fca7,0x00000000000aa5ac}, {0x0004e3f2adddce7d,0x00044a025d0ef29e,0x00075ab6560ff06a,0x000927f2b3057f30,0x000a1499f8844809,0x000b9a653b001c10,0x000d05309d141c30,0x00000000000bf659}}, +}, +{/* digit=51 [{1,2,3,..,}]*([2^204]*G) */ + {{0x000d68f9d41abcc8,0x00016a6c328ffdb0,0x000797038aa63e5d,0x0007d39063de7eb8,0x000710daf9bd691e,0x0008b5d7a998df4e,0x0004b8c7085b9e71,0x0000000000016b3d}, {0x00019da01ecaa2a1,0x000494dfce693daf,0x0007011a8e84696a,0x00004bf4491fb345,0x00014552451c2c19,0x0005e5e407c1bf11,0x0003726562cc2c3c,0x00000000000fe0e4}}, + {{0x00073ecab0b13cfe,0x0002484c3630b425,0x0005d7cee5256fab,0x000125ff61af001c,0x000fbfea35255abd,0x000e0cb6e69bca56,0x0005a6384af19900,0x00000000000d0047}, {0x0001438f80a7fcba,0x00090edafde48dd9,0x000a30b2135b9aaa,0x000f97a6c8ffcca5,0x0003e5a9cc5cf14c,0x000104e054d6cec2,0x0007c1b0d678f88a,0x000000000009fb52}}, + {{0x000cf7bdfab400e3,0x0009e8618ffa6a37,0x00041539f0cbda9a,0x0000d744f61edff9,0x0009eb7a476f5b1b,0x0002ee99b33df67d,0x0002cc7f1a767ea9,0x000000000002223a}, {0x0004324c9cd0a9f1,0x000f616f376f2586,0x000c0794e16b9222,0x000516ca58765df0,0x00062260ed6b8dc1,0x0004b29ba8934082,0x000bba060eb0afcf,0x000000000001d252}}, + {{0x000bb25431b5857e,0x000160d6cadbf906,0x000790df51943fb8,0x0003c734ab19507e,0x0005660086b33b43,0x000eb0f434fc5340,0x00058d770ae903a1,0x00000000000f6b5b}, {0x000dc8bc8bb4bdd2,0x000d6e206e14147d,0x00079b5341d6e69b,0x000ca2f47449e081,0x000639fef8e1cfbf,0x0006fc80cebaef25,0x00061b959e37b8c1,0x00000000000e911d}}, + {{0x0006b0541df5b61f,0x000b0014a0907c72,0x00060742ec5c6420,0x0007c4dc999acc04,0x00075e7ab1e3dbbb,0x0008fb11e01b7710,0x0005c2a33fefbfcd,0x00000000000c0b8a}, {0x0004467ba7747f4b,0x000ec774dc2669d0,0x0007562d1fca7010,0x000dc694d9c84626,0x000a1e772c5f5ac4,0x00083fe91bf6e002,0x000dce4922120e0b,0x000000000003efba}}, + {{0x000263fbc0d157fd,0x0005bc483d4b1827,0x00037dfadf4ae121,0x000df6fcbab1fb10,0x0000f6cdfc0c5165,0x0004320fceb28437,0x000e80ab565c0099,0x0000000000062133}, {0x0007401414422436,0x000ee7850cda5472,0x0007bd0ba094b0ec,0x000805cc2c82eddf,0x0006cf244539d14b,0x000dbe92dcb5468b,0x000f1e97d43ee825,0x0000000000089fb8}}, + {{0x000a494639f26e1a,0x000b5421afbe0092,0x0004dc6db28bf654,0x000cf4db1a2705ad,0x0006d128bcd556ca,0x000191ad86a3a413,0x000d242411c4b866,0x0000000000015b45}, {0x000845fec1268b55,0x000a74cc82459052,0x000da0992b42bc3f,0x000bb1c69f6298e1,0x00031933fdb59c88,0x0001308c3fe567b0,0x000dfa8a6aea7188,0x00000000000a2f0a}}, + {{0x0006a4d1fcc1ad65,0x000d2d7bf2ac5a3e,0x0005e362c26e5671,0x000abaa9afa97632,0x0004b62b36ab162f,0x0006a84e97b7f166,0x00043d77b9f79729,0x000000000007dbd8}, {0x000519c3add29e33,0x000fcc6e9c1e11fa,0x000ac380a63f4305,0x000a93d3bfa90c04,0x0009d050e46afa7f,0x000c5625655846fe,0x000a65473b9a0d35,0x000000000002b656}}, +}, +{/* digit=52 [{1,2,3,..,}]*([2^208]*G) */ + {{0x000f0e1b25d4e4dc,0x000a6372798f002b,0x000537a488c42515,0x000f9a98a1e25677,0x000ce70391c85e64,0x000f024585870254,0x000bed2def81a341,0x000000000001d087}, {0x0002a1629bafa8b1,0x0006d3557d07cb43,0x0009543a3877e0bb,0x000c5675f73ba510,0x000b9c7c670608c8,0x0009850725309050,0x000e962ab67da3bd,0x00000000000e5df4}}, + {{0x00057ab93a62b1b3,0x0004b7be81fb0ec2,0x000d385405273506,0x00040e27a8d16791,0x000ad520811ebb3d,0x000f65d231806c67,0x0003d7add4bb6686,0x00000000000e20e2}, {0x0008a96c64700a7f,0x00088208b470000d,0x000907fb1a1c5c32,0x00064f8121c37e26,0x0001a598efbbbd39,0x000eef966d35ef30,0x000e46bd76a276c5,0x000000000000af64}}, + {{0x0007b8ba2901e630,0x000573f40494a69d,0x0001d7e86c246f17,0x0003360c9e634b1f,0x00096ab166bbacc3,0x000fdb67e6cf72ff,0x000736477d8f2db9,0x00000000000cb644}, {0x0000821b2e82caf8,0x0007549454e1ad4f,0x000486f6c48cff7d,0x0005f0be8e7b06ec,0x00047dc40b498042,0x000ed620b862df52,0x000a648ca7d7c812,0x000000000003c45b}}, + {{0x000d7620f273aa67,0x000e1169474a1e10,0x000056ab42590c74,0x000de922ede425c9,0x000a6df8a8908589,0x000a8b8e350e03fe,0x00091a0d8a5c1c4b,0x000000000003fffb}, {0x00026981fafa18b5,0x000f721cf05437b0,0x0007e513859293da,0x0007eaed0962c826,0x0004213f6004c323,0x000148b6b43d6ac3,0x00080a45e619b2d4,0x00000000000ea5fb}}, + {{0x00014768f5f99aa5,0x00067314ea217285,0x000017c8fd29a716,0x000fb46a63ea8fc5,0x000890d84e5b0902,0x000e49b8a925a6dc,0x000be5e2e74f9c14,0x0000000000007d45}, {0x000cae18673b6270,0x000667b768d075ba,0x00089b2a5deeff6b,0x000223360d5b216a,0x00080a7386f475db,0x000c47746b132b67,0x00031d7f933fd580,0x00000000000fbaa6}}, + {{0x000ee5b308cc45e3,0x0002faba967ac481,0x000d29b2fe96bd68,0x000c601ef5f681db,0x000ffddc580fe033,0x0007572d85c34f77,0x0004d0d30f5b66f3,0x00000000000da20d}, {0x000030e8bcc549d9,0x0002cdb2310273e6,0x000ec784d2efa81a,0x000a33f7899cd7f5,0x000fda29c3821cce,0x000e14ecf0f4e0a7,0x000839c6d7c5f32b,0x00000000000d9caa}}, + {{0x0003fe55b28c2fec,0x0007ba884edf1601,0x000775572e4af6c1,0x00004152d7852a27,0x0007f26efb4c66d0,0x00022f8cb34732d7,0x000ff518b3ef8e29,0x0000000000018bcc}, {0x000ec4cab3e21461,0x00004a219cb1deb6,0x000868a49e96a154,0x00099e1d90760ec0,0x00078a94df2ef0af,0x000058f89e6fe194,0x000d9764b5dfcd04,0x0000000000023d21}}, + {{0x000d7944d758c20d,0x000209a8580a957a,0x000f955204f37a28,0x0000970be07f7827,0x0000712f7b7cb4da,0x0006a7b970ac2a26,0x000f62c9b8ee8443,0x0000000000011fb2}, {0x000ff5f68230c1a3,0x0002a5daabed96f3,0x0003bdf181469c85,0x000b5b7d96cfb8e8,0x000344d9e84382d6,0x000e7da3c4d7d0d9,0x000253fa2a9ea991,0x00000000000d531b}}, +}, +{/* digit=53 [{1,2,3,..,}]*([2^212]*G) */ + {{0x0003b2a8a65e5b7e,0x000424cc41f278dc,0x000bf1d7ec4af5a5,0x00066640fa1ca255,0x000b91e5edaf7053,0x000d3de14eeb40f3,0x000c43cdf98235f1,0x00000000000ff018}, {0x000927ebce051283,0x00074aa3228e6dee,0x00043f750dae9462,0x0000425650b2dab8,0x00026d875f1790e9,0x000e8a46ee4a8cad,0x000fb5c212029c9c,0x000000000005ed7c}}, + {{0x0007539a8f390740,0x0008eadb5966f40b,0x000e0b7342eb902f,0x00073e244693a961,0x00055982bbd3a76e,0x0002ca13214da743,0x000e7646e982cd5d,0x0000000000024938}, {0x000cf856b36cb844,0x00029749206b2571,0x0006030c0c47215a,0x000d1567025bb7cf,0x000e19555c9ebee3,0x0001639bae23f0e1,0x000bd00dec383775,0x0000000000005d43}}, + {{0x0002c235491635a5,0x000e4e4e52e86121,0x000459dc25e36e9d,0x00051bfb49f2b393,0x000b3f8097cf73b9,0x0008fbf057b6cb7d,0x0002119dfb8d0b32,0x00000000000ebce6}, {0x000c890c36814c6b,0x00007a31a15235a7,0x0009c26d4a535440,0x000834e6b5638766,0x000d10ee5a281d22,0x000aee4eafd91b30,0x000a763d7a282d59,0x0000000000073300}}, + {{0x000f6efbfb5bea3a,0x000f878b5c14b0f6,0x0005485b973e6dbd,0x0002ab209e1759fd,0x000db4b2f68cffa2,0x0005be7f45a86263,0x000f6d71e77c516b,0x0000000000019844}, {0x000dc7fe7c7337ad,0x0009d2519d0058c1,0x000edd3b9e6ca5d6,0x00074a685b3c2a9b,0x000fc294f4492c6d,0x00069fb469306f68,0x000886552e77c22c,0x0000000000010bb9}}, + {{0x0001ae09a4f32c66,0x0007beba7daac862,0x000767fe0f73dc31,0x00018f885bdbc832,0x000094d43909985c,0x0009e108b86555ff,0x000313b0b1b2b653,0x00000000000c0bf1}, {0x0003b62754d457e4,0x00021bd4777c10d3,0x0007d7f58d2fb40a,0x00057374a27f1ddc,0x000eeaaa58ab85bc,0x00076fac29a8ae24,0x000377161cb2f5e8,0x000000000006636e}}, + {{0x0001f89428b5c457,0x0007f1674b959a73,0x000b96ebf7106c2e,0x000a32dc67c36488,0x000368d720a63962,0x00057a5b24949617,0x000c0f4e81df85a9,0x0000000000053123}, {0x0003624d70103a1a,0x0003f5091dd340e1,0x0000c9fe10861f33,0x00020f52c119dbe8,0x0006c94d609a5e77,0x000dccd1fd584ae7,0x000c6e476c63ba86,0x0000000000032508}}, + {{0x000df9bca60288d5,0x000016bbf77cab44,0x0000fa9d18796041,0x000eb1a2b9febf8d,0x0001a25330ce357f,0x00091799874240a8,0x000f5c7a9ab575b4,0x00000000000eda3e}, {0x000c7149276e2420,0x00036360410d2e37,0x0006d4d0d5e12db0,0x000b466cc381b581,0x0008247a49047bae,0x000c58130024a98b,0x0006d26e70b4c3e3,0x00000000000ae8a5}}, + {{0x000d9a7dd453995c,0x000393313a9d4705,0x000fd95bba01fcaa,0x000ef915e4dd5cea,0x0003c565dd67c0fd,0x000ed05ac902a2a9,0x000ae9d8eba4dc7f,0x00000000000e157d}, {0x00019071237f3ae4,0x00006d655d0b3ced,0x000513db82a990cd,0x000525a0652872b6,0x000fe68c0ddb5b7e,0x0001cb31caf7968e,0x00071e2ec02930f5,0x00000000000f2be0}}, +}, +{/* digit=54 [{1,2,3,..,}]*([2^216]*G) */ + {{0x0003b3ac56ccd2a3,0x000649b23ab4e3e0,0x000d023509576972,0x0009e51e798edf99,0x0009307675c7dbe9,0x0008c0fb63854744,0x00037223ffaf5562,0x000000000001698c}, {0x000420dd9073adb8,0x000d039f45a56f2d,0x00011e9a2cdfa00e,0x000079e4af138fd7,0x000a2ee4ecc02a89,0x000bbf92fb86371e,0x000c51076d256a06,0x00000000000ae3c4}}, + {{0x000340cb6908d50e,0x00092ba2e95430b3,0x000660e7e985a29e,0x000b95145bdc19ee,0x000e382e77bdf94d,0x00020b29a951d00a,0x0001f19940a5fbb2,0x0000000000058fc9}, {0x000d804932dbc0b5,0x000be682e42eaaa2,0x000400a2efd4aee0,0x000810016294d055,0x00032e326d68be15,0x000e64fceaea13fe,0x000a8ac0dfe1ef15,0x00000000000b8237}}, + {{0x0004480f8fce3f16,0x000a7e59b80017bf,0x0006c7396aa46dc8,0x000172a5af5b47f5,0x0000160d7e8d8799,0x000f9a549f72c978,0x00044a1d1ce972b2,0x000000000004857b}, {0x000d15fb2758caea,0x000542545bdd6f77,0x000984fe91e9b1e2,0x000343a4e23c0644,0x00091d1fd9cd5a60,0x00070b5b3986779f,0x0005a35bd5611b35,0x00000000000f9d76}}, + {{0x000b72123cb1cd13,0x000e76ee65a0886b,0x00081e4e332045b1,0x000cc382876e523b,0x0006d3bf53aac4a2,0x0007f290cab7aba2,0x0005bd5bf00871db,0x000000000001ee6d}, {0x000bcea869ddbc32,0x000334cafb21874b,0x000bcaaf9d600f4d,0x000785520b281cd0,0x000e64d9c65ea1fe,0x000a0e67be457198,0x00068aa3d1a6d0c5,0x0000000000090cc4}}, + {{0x000450a44e08b4d9,0x00014cb0a365753f,0x000b82633a02b2b6,0x000210997ed887af,0x000f30d9b2970b85,0x000fb9c745fec3e1,0x0007854ce4149f10,0x000000000008cbff}, {0x000dc4bd785a06f1,0x0009f81b0d7b3b6a,0x000116390fc1ac37,0x00021de2b841eb88,0x000ad83c22e6aec2,0x000affe9162c7d86,0x00081d5504dcf885,0x00000000000f4454}}, + {{0x000578651af84c0a,0x000e0d4ee3f7f52b,0x000cec289c787837,0x000ee1363ebab5bb,0x0007005ec2374c0b,0x0002fb00670e32d7,0x000899302fc73dc5,0x000000000008f159}, {0x000ba114d96a8216,0x0009d42a5478e2d1,0x000e66d84b639b08,0x0004970c8378f0e8,0x00058e2c86c5042c,0x000c7c76770c1957,0x0003a861a95e6884,0x00000000000d6fb4}}, + {{0x0000a2299e18ff96,0x0001ceaf237a8503,0x0006d80455ecbada,0x000fa473f251ad61,0x0006d828578e5fbf,0x000e118adc40570f,0x0005485cc65c0dd4,0x000000000005da48}, {0x00073e60bf0732eb,0x0000fe27fc2e7307,0x0009067267d2e6a8,0x0002fa55e27fb12d,0x000810003fae35a3,0x0009800c17fcfd72,0x0002e6c74b50a3f4,0x00000000000dbafb}}, + {{0x0002a6bfc8996b96,0x000bd0c62fd2c8ba,0x000a840806b7cf85,0x000933dcef3f9e43,0x000d9889ffa276b0,0x0003c88d251b1ec2,0x00052f9e84b2ba9a,0x000000000001913e}, {0x000a4507b899f92f,0x000e6bafc5e94164,0x0002238654296051,0x000cc41bed171099,0x00036c7a41c84e9b,0x0005369cd0db5b73,0x000934d4be07a779,0x000000000007bd3a}}, +}, +{/* digit=55 [{1,2,3,..,}]*([2^220]*G) */ + {{0x0006d08f59277dc6,0x0008a3f2eff5384f,0x00049c170a3dfb6a,0x000b18a0dde190dc,0x000da26b0409af10,0x000b1d944f491b98,0x00054166080782a2,0x0000000000097e8c}, {0x000baebab71369f0,0x000d1fdbfc5f5495,0x000a70804cb1f0f5,0x000263857645ef4f,0x0006a02583638e5d,0x0005d250331bcfda,0x000285f5330ab8d3,0x00000000000c7cab}}, + {{0x0004a7ee3780eead,0x0001ef16938f4dd4,0x0005af2b9dcbcc11,0x00095530b6490d71,0x0001a28a296a2d50,0x00026415c8432fef,0x0008656f254dd08d,0x00000000000d50c2}, {0x0005457026e64224,0x0003c4f5bc4553f7,0x0006183dc27db1b2,0x000dd6e65e593411,0x0002a56dc2eabab8,0x000a90e05676baca,0x000da038eea06bea,0x00000000000174ba}}, + {{0x00021d43da6aa865,0x0005de6a19dcb664,0x0006a4c857b63184,0x0009b9fc6455613f,0x0004a7390d0eb4d8,0x000ea135a6cb0fe4,0x000982ade197a459,0x0000000000020680}, {0x000776554c3cb5c6,0x000b803db9be90e0,0x000e56e339783849,0x000e8d4753c196c6,0x00000b7c6ff544de,0x000a1b14259adcc7,0x0004f2c6260ec24c,0x0000000000046cbd}}, + {{0x000c69e90d279f7b,0x00051a35e411c1f8,0x000aa4eec7d05943,0x000859e89a66f2be,0x000e0def8ecd7c7c,0x0004947b79908c37,0x000ce88274124e34,0x00000000000568b0}, {0x000eb0436a41e1a9,0x00070e52919611c1,0x000a98c568a44a8e,0x00039e156bd3a7e1,0x0006268f856260fb,0x000fd8293e56a34d,0x000fcbb3a1fe1613,0x0000000000067537}}, + {{0x000d9811d879790e,0x000da8a15d6fdcb9,0x0006c38fcc4a52b8,0x000e38c55bbe733d,0x00051ff94a9d7a7e,0x000585ab5eff146a,0x000a5de572d13edd,0x0000000000006491}, {0x000a7bbc541e4f72,0x000a29c84e1c4d63,0x000bbb62e6c0b1d5,0x000cd9b385f06c82,0x00077a7759c3db12,0x0003bd7060c93eb9,0x000d50f1f5b0fe68,0x0000000000085ec3}}, + {{0x000e87011f7cd75e,0x0006e89e48d8ba73,0x0007fdc53e3e2631,0x00033d7302c0daa2,0x000a048eefe360f0,0x000a7224415e4578,0x0009cdfd6dec89b0,0x0000000000030948}, {0x0003345fd128739e,0x000ad7cdcc2a0188,0x0002b63966c3b413,0x0000a455812b560a,0x00052ca31d8ca630,0x0003a5b5a8fa5c41,0x0004e036aa3c234f,0x00000000000c86cf}}, + {{0x0004ff5664ce36b2,0x0005e9a0e15351cb,0x00019cbdd0d2f66a,0x00059eafb29777cc,0x000ae354cafdc170,0x00007c3717e40e5f,0x0009459cf594054d,0x00000000000a71c3}, {0x0007429ea783b1e9,0x0003469309e95af4,0x0004f55088c266f7,0x0004070e25823b6e,0x000d0bc27359f216,0x000925094ead851b,0x000f4e3d21bfe8b0,0x0000000000034a97}}, + {{0x000a4c18541d03ec,0x0004ad927282fbf3,0x0005c034c274cf2b,0x000207f450db7135,0x000423e16d9558b9,0x0000e349cae95338,0x0002bc4f10c6d4e6,0x00000000000feb12}, {0x000eced76985b33a,0x0002f22548cd1c2d,0x0005b37b87399908,0x000f912b6167b3cc,0x00027902d2baa1c6,0x000de34ba6967bab,0x00025eebbe0b0836,0x000000000004b796}}, +}, +{/* digit=56 [{1,2,3,..,}]*([2^224]*G) */ + {{0x000e99ecf706c6bf,0x0005c9e857f32800,0x0001e880e21c15d7,0x0008d68ff4f65674,0x0005ac339148f853,0x000dfc12f35380f1,0x00093efef0bfdd5d,0x000000000001387d}, {0x0009274bbe5eb9e6,0x000aa618ce77c94f,0x000ef0d12ae1c332,0x000f06e00dc0da6a,0x000e07603cc724ea,0x0006963c7049113b,0x0003005cf489088f,0x00000000000ede4a}}, + {{0x000abae3c29bb132,0x000af77e486f79a6,0x000ea167f51170e1,0x00028ab7df36628c,0x00016704dcd6322b,0x0009a35672d14d13,0x0003b6d359977af2,0x00000000000ec96d}, {0x00053212afaa74ef,0x000f0fd6e400a371,0x0003860e13fc28c5,0x0001c7d9b8533afb,0x00028de66eb862d8,0x0006784eeefa638c,0x0002237405a9d7e8,0x00000000000a6c22}}, + {{0x000fc1e6b9032350,0x000a46909994e4c6,0x0006261c6638f0ac,0x000ca05884aacaa5,0x000996995a981505,0x0002c000ee4b6530,0x000b0930e00a5ed0,0x00000000000236e7}, {0x0005ec99c1d0db26,0x0002ce696f09d532,0x0002f7914e3f9268,0x000a7b401e1e2a4e,0x00069d2d025aa9ad,0x0004ffeb19630acb,0x0004f69fab2c6ed8,0x00000000000ab758}}, + {{0x000c87e27d06e6af,0x00073f9b2dba43cc,0x000cbbdd7e7ab099,0x000a4f33b8104eed,0x0000e4e1896e7692,0x000d2aa365da885b,0x000bcac2a30fec73,0x0000000000086f60}, {0x000adfed330d989a,0x00086bc8bf16d541,0x000f4b7104707db4,0x000e2f37e35610a9,0x000482f9d71c8e79,0x000e62733981139f,0x000061f8997ec424,0x00000000000a3518}}, + {{0x000efb4736bf4182,0x0003f6cf0e6ef64b,0x000b24ffed39dfee,0x0007783856111dce,0x0000c0e9f2b00277,0x0007fe5073a1d36f,0x0008f1fcf4f6365e,0x000000000007fa7c}, {0x000ce2543c17ec02,0x0005509a02de874d,0x000cd3e25ee5e59f,0x000a9654b7f4e35d,0x0009805b58bd7211,0x00057860ca6b2ba7,0x000d58418302c209,0x00000000000f99f9}}, + {{0x000634f7fb73c6b6,0x0002e4e6ef40fcf1,0x000c701a714f0702,0x0003403fd41d144d,0x0007e0774c37a4f0,0x000c7484a3a50717,0x00066b078e8c568e,0x00000000000fbb3f}, {0x0000fb0d6daae4e9,0x0002c169c9474ce5,0x00027d6aef77ce07,0x000968508303114b,0x0008fad0def23e8e,0x000c1c8da7a9797b,0x0007210ad14404ef,0x0000000000021ced}}, + {{0x000169a6e51baf05,0x00088fde0d1b3e6e,0x0008e5407b7aa0be,0x000ad79c9eb9de48,0x000b0ffbcdac16d3,0x00020287c2707ec8,0x00055ad7e6750fa2,0x000000000009c2e1}, {0x000dcbd856a04522,0x000e43018c309307,0x000def4e0648d266,0x00023aecf15a4af5,0x000cc1b8cca01aa3,0x00043a969f085d69,0x00043047a3eaccb1,0x00000000000f3a98}}, + {{0x000270a279eabd20,0x000d5c7e9ddef0ef,0x00060c66b8938b7d,0x000746db239bb82a,0x000b28ea13416bc0,0x0001309b0c811a8e,0x000b345f714ca71d,0x00000000000d4eb9}, {0x000f50441ed062cb,0x00091e0e5afdcc03,0x0009d20438aad877,0x0001e7b843343663,0x000a0eed1116670e,0x0009bbd50c8c38f9,0x00095af914fae261,0x0000000000051c19}}, +}, +{/* digit=57 [{1,2,3,..,}]*([2^228]*G) */ + {{0x0001b38ab493e121,0x0005bde849cd1240,0x000576b3d2c358dc,0x0009e3dabe92fbab,0x00043324900a3fbd,0x00020904e785414d,0x000ba8daead1abde,0x00000000000aa5f1}, {0x0002d0438c4bd099,0x0002fd60a4f2ce26,0x000593174efc1656,0x000c78934efa243c,0x000f216a8d8c163d,0x00001617b3067dcc,0x00051e116b6534a9,0x00000000000bbabe}}, + {{0x0004b6e85f0076cc,0x000c1929454f6549,0x000021b9b8ac3fe0,0x000a7c5ee25c0b0a,0x000f2e752295f5b0,0x000acac687d3372f,0x000e3cd6dadc7d6e,0x00000000000a96a8}, {0x0006465e062c14dc,0x00030ea831db66b4,0x0000548165c8c6c9,0x00017e572e3c00c5,0x000d2a5fb6ba5ff8,0x000392476b022e25,0x0005a0b611c5bcbb,0x0000000000019048}}, + {{0x0000dddcc280d252,0x000d5efda99d90b9,0x0002988f9d0202d2,0x0006cd1ad14ac705,0x00031f4138808b9e,0x000dd7fb91239ee3,0x000b12d98e93d993,0x00000000000894fc}, {0x000d9440883321ae,0x000d433a92019c9f,0x000ee20fd3f674ff,0x00051280d0a320b4,0x000b4b607b538450,0x000228c2ec20551d,0x00025c6e63c766ea,0x00000000000ac48f}}, + {{0x000ea4ad3f5b0bfd,0x000140372678d84b,0x0008ab3dd6009aeb,0x000bca4b79594c43,0x000baf3b75cfebae,0x0001e09c6e587850,0x0004cd534183ac2c,0x00000000000c0820}, {0x00012c542116a023,0x000a7dac2cf06c18,0x000f5e79e9f15f10,0x00009f490b0f6c27,0x0006c2c62207f6f5,0x000ff18873ffc3cd,0x000c6fbb21eb1132,0x00000000000e62cc}}, + {{0x000a11bec64a35cd,0x0004f1ca74a30c77,0x000de3a654c55d5a,0x00049038d6b4b005,0x00002f7906ee3709,0x000452bbb12ba86e,0x000039aa76f77adc,0x00000000000f9837}, {0x0000782bfd430ed7,0x0001841fe306f87d,0x000ce68ff3cdd73a,0x00024ccaa7d44b2c,0x0005d86900f9cffa,0x0003ecfa022bae39,0x000980e7a138782e,0x0000000000086d28}}, + {{0x000489915b0c1e42,0x0000991b8b685879,0x0005ba3b38e17597,0x000d69ea7d9931a2,0x000c7632a26bcdb0,0x000ba170f3c8441d,0x0008adf11a365c62,0x0000000000034e74}, {0x000d3f6d2f87f536,0x0009d523ca2d7db2,0x000b5fe1b40ff204,0x000c7771d07308bd,0x0007c291c2ef71af,0x000b40d1773588d7,0x00015629baa3b0aa,0x00000000000eea9f}}, + {{0x000a95a8a249bd36,0x000f90ae9143a26d,0x000709bd167b8510,0x000f7a7f3b4b882d,0x000de22d9b9923df,0x0004f02b1b178e73,0x000c2fa83861afaa,0x00000000000b9064}, {0x000de7d4573c6d34,0x00022142eb294574,0x0006f55c30205aad,0x000717fe649a8b70,0x000cad53c9bbd589,0x000ecd8f7a925c47,0x000142c339b11a09,0x000000000001bbf1}}, + {{0x000abd60f6eb49c8,0x0008c406a7e201fa,0x0007246dc14c8322,0x0002eff020748efc,0x000af39b58dbd440,0x0008cfb047827442,0x00078f77e3f2768d,0x00000000000e45a9}, {0x000ab42dc779cb3d,0x000229db0829881a,0x0005eb7284cde06b,0x000ce47b82775f69,0x000f63910016e434,0x00047792fe84995e,0x000eb9a35e8b971e,0x000000000007c6aa}}, +}, +{/* digit=58 [{1,2,3,..,}]*([2^232]*G) */ + {{0x00097b7667d86ea7,0x0001b1fa064cf475,0x00026db64fb0c148,0x00002a1fa9d94539,0x000bdc6bd7eada81,0x0002f6044786aeca,0x000208caf91e3bca,0x000000000008573f}, {0x00036746e95246de,0x0006cd309fce8dbb,0x0001300c9068d932,0x0001ae0f3d530575,0x00000d1fd61e5779,0x0005ebfa626b053f,0x00097991c962c004,0x00000000000076ed}}, + {{0x000013c3d6e02921,0x000c449f2499410e,0x000e2ab53501cdc4,0x0009103d5e91bc0f,0x000bcb404f68897b,0x000f7fc0263db1ef,0x0000af70efd9d842,0x00000000000c6a23}, {0x000a0390300406c6,0x000308d5b199ee1a,0x0009868ea4fe37e1,0x0003d34504dd889f,0x0001f823686fde58,0x000fc73dc0375600,0x000f42f19ab86f95,0x0000000000093f12}}, + {{0x000b8a18e1e24b49,0x000143f896ca9186,0x000d7ce3f5b4c07a,0x0001632600e4e2b2,0x000f69e702d5d074,0x000e0df2b87c7db5,0x000fba1f5a3b8053,0x00000000000f443d}, {0x0005af3bc7c98ae2,0x000deeb90e22f972,0x00070953899b58fe,0x0008299a5aa335b5,0x000d4197b32afb1e,0x00055918ed78504c,0x000c720e7a79cc67,0x00000000000883b1}}, + {{0x0004af5925d66db3,0x0008dbf66baa58e7,0x0001c386a0ca25fc,0x00032abeaaa466ce,0x0007e5f2733b80bc,0x000531afa605b789,0x000369e9e7e3a1a2,0x000000000003deb8}, {0x000174c1d570e84f,0x0008d36212ea2dd8,0x0008479c4475fe18,0x0004b31444e9ea02,0x000169530c1befa5,0x00079bdd19c2229a,0x000cc368feb9854b,0x000000000008b984}}, + {{0x000682b315cae64a,0x000981df8d98c41e,0x0009fabd7bca288f,0x00064f91703e1431,0x000e9de0ab4ca54d,0x000dc4e0fa12198b,0x00091f160e06241d,0x0000000000066958}, {0x000b5c1e9cafc463,0x0006f808565e66f7,0x000a9467f76914c8,0x000cd934bac17690,0x000ca5be965f6682,0x000a38e9062e7ac2,0x00016ed33f6f8ad7,0x000000000005b8b5}}, + {{0x000509d8741fea0a,0x000c1f041e421362,0x000c0d8899228fbc,0x00093751128ed62b,0x000acec6eae64fea,0x000a65dae041a1c1,0x0008e81f32359415,0x000000000000154e}, {0x000a9eb331e84371,0x000ec309e9f286a4,0x000765936bc21528,0x0004dd5692420c27,0x000ec4fa1a6a7bb5,0x000779e77193a41a,0x000b8c35f5f3b43d,0x00000000000046eb}}, + {{0x000b5769d7b9ec0d,0x000aa3a5a366dc99,0x0005d073ce2a60d9,0x000e4aafe5355bee,0x0003ced676663e16,0x0003440036d8bac0,0x00020c403eb33ed9,0x00000000000333ab}, {0x00094bfc36e2db30,0x000739fce19869f6,0x000435b17be8c513,0x0009611921a58e5d,0x000620d5c61a8e68,0x000c81b4e8f5f115,0x000779b17f612fad,0x00000000000e562f}}, + {{0x000d75f385d1b0f1,0x000f0d6a4d25bfe8,0x0007b705bfa0d54e,0x00059731cdedfc0f,0x000603d6502f9420,0x0005ce8c80c4e385,0x0000b7981a4fc5e1,0x000000000007aca3}, {0x000ea22cf2bcfc17,0x0009ef2037ef684f,0x0007e5010cdb37dd,0x000a23c71f3e4e4b,0x0009f47b504b9c98,0x0003233aaa73c8b8,0x000f68b9e33f5402,0x00000000000f92c9}}, +}, +{/* digit=59 [{1,2,3,..,}]*([2^236]*G) */ + {{0x000a9e3a73909533,0x00090ba03ba3b07a,0x00090d7a3c9c5a5a,0x0008cfe4f0f60b35,0x000e6fcccd96f96b,0x0009dd17ab908d77,0x0000487208ef7de7,0x000000000003ec3d}, {0x0006af6a704d4f0e,0x000d09c5ad2d9a11,0x000e77d5943d9764,0x0009449470eb938b,0x000bee7d772fac99,0x000b7ad09faaf27f,0x0000a9fbe402abd0,0x0000000000057db0}}, + {{0x000ca62ea2a4a457,0x0001b10c082a59d1,0x000bdd4313beafb9,0x000935b4cb291a7f,0x000313e9ce08785d,0x000f6f1c4fc2ae15,0x00024c3146fabf4d,0x00000000000c87dd}, {0x000f74ecc24bd4cf,0x0000385fdd8765b9,0x000dc418405d512e,0x00005013e7e0297e,0x000fb92df904c81d,0x0005ddccbb56ddd1,0x000f1d4612df9f29,0x000000000000e27c}}, + {{0x0002069dae7548ac,0x0002986d9b05f69f,0x000025ad33463063,0x0008e7c27d9d64d3,0x000aba04e6ad9b6e,0x0008abbbe79bd66b,0x000d0477e4d0b082,0x00000000000cc540}, {0x000bdbdb8d90e2e4,0x00067f5d8a46ef90,0x00078bfd47c637af,0x000b852563fe6b52,0x000997cdd04fb93b,0x0007de47d06bb3ae,0x00061c07f011d48b,0x00000000000de78f}}, + {{0x000eb7904785958b,0x0007d7830460f8a0,0x000cf49e72cbbaa0,0x000e2aa307d9c790,0x000b5aad8b6c73be,0x000848db51b02af1,0x0004765e31882703,0x00000000000f230f}, {0x000b79128735694b,0x000bd4ea6535cc84,0x00008e33135971e8,0x0007b332fd33cac2,0x0001c566914f4c19,0x000952d3b24c7b0b,0x0005f2956ce3c371,0x00000000000fabae}}, + {{0x0004121555388dc8,0x0008b8a95e5c1a8a,0x000cd5dbd7b0133e,0x000df6acda40bc0b,0x00058234471d1859,0x0003c0100f9097aa,0x00067caddc0c9b78,0x00000000000feb70}, {0x000ce59ade26052d,0x000a6e3805fd0a27,0x000626ac8acaae6d,0x00099921943a0a1d,0x00091dfe627ea459,0x00006515fb47f061,0x00073e313d4f09da,0x000000000001f54a}}, + {{0x000f6dd7137bd615,0x0007e0db87bc3c53,0x0002eda89127238c,0x000e9c4a3fd2a60d,0x0001c9f017e5ea81,0x000c75768190c9c7,0x000de621864180bc,0x0000000000043dbc}, {0x000fb5dd8276da18,0x000de5b090c70dac,0x000cd9057894e345,0x000d268a918bf24b,0x0008ae204f49fef3,0x000d7c356e10c52c,0x000a17f4be898d86,0x000000000002fdb5}}, + {{0x0009bfc4aad5cc44,0x000a20079c69c96d,0x0008a5713957941d,0x00086660139685a2,0x0004946fbeddb8d1,0x0001aace408590ca,0x0001b67fecd9b964,0x000000000002936a}, {0x000267114a49f247,0x00065925b6235aee,0x00055e3538cd2015,0x000663d8c6fb34ac,0x000c2fc1c10d971e,0x00042b822543146d,0x00024d6e4053c706,0x00000000000492e5}}, + {{0x000d356fb82e9b9f,0x000beca9872e0a14,0x000f54683a031c30,0x0007cb84e05b2811,0x0006fa234d4596b1,0x00035a7d89798714,0x000384ba78949ebb,0x000000000006fc59}, {0x0001361f78e02fa8,0x00081a303e549f81,0x00064be08532a2fa,0x0002de8ee7220467,0x000563e27035e57e,0x000d2fe6fa05c106,0x000aadaa38e86602,0x00000000000ee2f6}}, +}, +{/* digit=60 [{1,2,3,..,}]*([2^240]*G) */ + {{0x00044971cf281b0a,0x00052c0426b768f1,0x000ef3f4445c186e,0x00012e3172c0d3e8,0x0006ee75473731d3,0x000a7ee615f49fde,0x0005fb895530f06d,0x00000000000e8b3a}, {0x0006345afdc270e9,0x00019fd14973443f,0x000f6896912e434e,0x000ae07653908d03,0x0006ba02a278e2ba,0x00021b8f8c3d0143,0x000297a0d0222e7b,0x00000000000d7ec1}}, + {{0x000653659b1a252c,0x000514f120aa7478,0x000c72dfe03d7757,0x000ac5ecfe5f7a92,0x0009bbf3cec6c96b,0x000361cd5d4e73d5,0x00044ced8d233560,0x00000000000562f4}, {0x00045d3e2b7ac684,0x00022bd37d3cf9b9,0x000cb601f2d0a968,0x000535a3d2f41ee1,0x000ee8b1743e7e35,0x0005a27650353b52,0x0008b831d89dfd7b,0x000000000008d9ea}}, + {{0x000718fb55d90569,0x000b306a67bd2493,0x0001471031374c3f,0x0005d5197bc62d32,0x000924c51874ee0b,0x000a1a0d552b1703,0x0000acfed1f42382,0x00000000000db627}, {0x0006189cf7edbc97,0x0006c36be4a9b658,0x000680236e8f5c91,0x00036d3b8f8074cb,0x0009718545c6c174,0x000757d213bb4d39,0x0003668e1ea3555c,0x000000000008c474}}, + {{0x00063be615177c6f,0x0002773457010af5,0x0001ce08b2f26f1c,0x0000e8c9c25fe5be,0x000182dd0485705b,0x000ac280540f36ea,0x000b923d55bc8527,0x00000000000ad921}, {0x000b6da293461f09,0x0009551586cd4c76,0x00086171a05efa67,0x000605e84f0abcb8,0x0003772dd0dabb4e,0x0004e1d41354ef8e,0x0004917f1a8f795e,0x00000000000de5d8}}, + {{0x000beb4ebddc46f4,0x00073ec72c64fb0c,0x0005bac2d9d9096a,0x00022001819efb1b,0x00068cdde8703c5e,0x000a87aeedf5ab6d,0x000f1975a44e9d92,0x00000000000bcf77}, {0x0009407ed3c226cf,0x0005e8191efbc92d,0x00064a74c9c1339d,0x000e58265cf242d2,0x000180b1d17be62b,0x000de59a9ae99a3b,0x000ce248cbb44692,0x000000000002dcb3}}, + {{0x000a48783de6cfb4,0x0006bf3899558552,0x0009d51bfff43e77,0x0004fd32df8d1a75,0x000376d3fbbf0b1c,0x000fd52bcf16bcc2,0x0001f0d5888916f4,0x00000000000d5cde}, {0x000f03d1ac917a2c,0x000ae764ffffd280,0x000af8be538ef59b,0x0004762ccd57b860,0x00032935106234f6,0x000c642f32233a4c,0x000f34df076095d9,0x0000000000059f0d}}, + {{0x00010c66eff8425e,0x000379580cdfaafe,0x000d1f7ccb185b5d,0x0005f77c327f3e8d,0x000c35353c5f5d3d,0x000258eb105d5339,0x000f79c56fb5fe5c,0x00000000000edce1}, {0x0005bd6f7b6e122d,0x0007cab7aa141541,0x0008987b379beb7f,0x0001491458d9e533,0x000caa7f0f31e124,0x000fda7abdd2448c,0x000a4dec58d3c7f0,0x00000000000c91bb}}, + {{0x0002f037fabc6138,0x000b73bd258d77ca,0x0006aa4d0ec1d1f3,0x0002512e3f966a14,0x0007709d0c2d5b43,0x000658259338bfca,0x000023d142cc1049,0x00000000000636b8}, {0x0007458ca547abc1,0x000cda9ef9400a80,0x000ad926836a9402,0x00063c55cb644887,0x00011cea475bfd2f,0x00067a25fbae949b,0x000a6aa45446031e,0x00000000000dc6a7}}, +}, +{/* digit=61 [{1,2,3,..,}]*([2^244]*G) */ + {{0x00085fa16820f665,0x0009fd699ea2d24e,0x0004f1772a862ed3,0x0004bad66a8b35ba,0x00024233fccb4660,0x000d3cf0c0c779b6,0x0007af578458acbf,0x0000000000096bf5}, {0x0008a325d9d68d07,0x00045a9724244e54,0x0005b4b1e20150f9,0x000a5b8c6be8c159,0x000c774d62c40980,0x000bde24b6230e3e,0x000204da1467d84f,0x00000000000cc862}}, + {{0x000b4d1a75edabf3,0x0007567c51633fd8,0x00020dc66cdc521c,0x000c8dc9ee450d03,0x0008b41a3e2f77fc,0x000bf06898dd2b31,0x000464df6a935e93,0x00000000000a92e5}, {0x0001e3ee6beb3c9c,0x000e449afcd9ef46,0x00031a4b44405106,0x0008ad2c7ea7810a,0x000e550822b2cdbd,0x000606adcfe61571,0x000110744a4f9386,0x00000000000d9d4e}}, + {{0x00006ff4ac15d783,0x0007ef1084276ccf,0x0009d3b1212d957e,0x000dcf5bfb4283a4,0x000db74017eb3752,0x00078fcf8f6b2214,0x00039afc1cdf7245,0x0000000000012265}, {0x000c5dc1b7858cd2,0x000cdcc0796680d4,0x000e05b222bc5975,0x0003a9a504cf7d65,0x0003c93ed5932027,0x000303f1b0c7b7e5,0x0006a4aaf9c36866,0x00000000000cb013}}, + {{0x000bfa5cdf24bf96,0x000411fef389c07d,0x00022753fd218088,0x0000a1437f04a344,0x0009d0169369bd77,0x000377cc3c7438e2,0x000a4f6b265742e2,0x00000000000c369f}, {0x000bb384dc3d9a84,0x00060dfdbcf462e9,0x000d3f52e65bb342,0x000a0b82a9c483da,0x00042de432285574,0x000d1fabe0563fe9,0x00096658ca0e8aea,0x0000000000066023}}, + {{0x000afbbacd3ede36,0x00007746325d090f,0x00094f8b4a38ccef,0x0001c2866c3931a7,0x000a783a73e7d9f2,0x000d82d13c12880e,0x00010e382e1ce28b,0x00000000000ac023}, {0x000fda6b09a40144,0x000b69802d06233d,0x000de8140422422b,0x000367efd4cf75a0,0x0000e8f2f6ed38b4,0x000e72ff4765cdee,0x00070ae0b4d72b35,0x00000000000947d4}}, + {{0x000a35bb9d72eb2a,0x000c5383bda07268,0x00038c9d09f99c2f,0x000717d369f39c03,0x00011a5a39006f3c,0x000ec6c2b1bb593d,0x000202d0f07ecc2a,0x000000000004240b}, {0x00083c5449860db8,0x0001935342f6c7b8,0x0009a1541ab519cd,0x000eb09ccb6a888b,0x000785aa42c5fcd6,0x0004e5895abb7a6f,0x000582952f8824aa,0x000000000005c406}}, + {{0x0001d7b0f8433a5d,0x0004359d6e052cda,0x000fea341e325461,0x000d07d7907cc890,0x000dc4ce5d800459,0x00004f40267d720d,0x0002a83262028eed,0x00000000000d7881}, {0x00055f59d844fe29,0x000fcf735fd6cf7f,0x0001c0c0179cc733,0x00006e8e19a43f29,0x000f19592b76328c,0x000b836f7b97ef65,0x000a9981325f3db8,0x00000000000d6e6c}}, + {{0x000a67318a4b19fa,0x000a63667a71faf0,0x0007be6235b29837,0x000535efc62f7919,0x000b389faf7fe084,0x00071b7f65bc1652,0x00070340cf51683a,0x00000000000d4f39}, {0x0002b576e30c499d,0x00099823e7549478,0x00032769bfa306a4,0x000ee027225b31ad,0x0006fc282f165639,0x0009f61ae7533bc8,0x000803710009d2c6,0x00000000000bf65e}}, +}, +{/* digit=62 [{1,2,3,..,}]*([2^248]*G) */ + {{0x0006c5f4c042c4cd,0x0001ceb29e44bf59,0x0004c11cc5ce653f,0x00004943d2bf689a,0x000a47428dd2d09c,0x000aafac83ab7799,0x0006e0dc558d6be9,0x0000000000087f9f}, {0x00056bc34f65dad0,0x000c793842bcd3a9,0x000241a2ffbfced6,0x00052687e6d47b5b,0x000a4c37eeee1645,0x000c412ceab304b7,0x0002c8dbb3d4e13f,0x00000000000a726a}}, + {{0x00059e97675084b3,0x0008d79d88dffddc,0x00002dc16c994a53,0x000000fce7d606f0,0x000e2fa27fd3b528,0x0009436afc773557,0x0004c755b53dd3e1,0x00000000000e10b6}, {0x00077a15a41de95f,0x000bfe5832664b2b,0x000d15e689d49c17,0x000bf537af3e3dd9,0x000cf47d298c7b93,0x00012136994fafa2,0x000ff694c2ff9a21,0x0000000000033468}}, + {{0x0001b740495480b0,0x0003f91e8c991baf,0x000b4c043871430f,0x0003f6dd095f5b94,0x000cddf3cad27c5e,0x00057aacfed7522f,0x000f5180bb87056c,0x000000000000cc5f}, {0x0006cac5a2f35aa0,0x000e0964def7e61e,0x000e006a84529a7b,0x000192584de66a22,0x000e075f07c5cc75,0x000eade939acaf7f,0x00058f6505c2f81e,0x000000000000e3cf}}, + {{0x0001fb7f00850a1a,0x0001dbe45d81a1aa,0x0000ee7897985bd0,0x000a516b078ea895,0x0001b446476463c5,0x0001e52329f3efe4,0x00022084580e2410,0x00000000000c8ae8}, {0x000539dde4d08a27,0x00077bff4077d088,0x000c1e715cd7b849,0x000eef207e1c03eb,0x00096e654d584df4,0x0006f15964ab3d03,0x000cd5b20056cd08,0x000000000008acd7}}, + {{0x0008f4a5a8f26e12,0x000538caa623c979,0x000e7d0ec3691999,0x000f856ee285bfe4,0x0006d0674ecd089a,0x0006f661277b461f,0x0009f8baa9d9b38d,0x0000000000059066}, {0x000460fe25d6fd2a,0x000d2b164340c38e,0x0003981c9e27c186,0x0003b9176e4346f2,0x00017caad5fc73c0,0x00087803d6a678eb,0x000a94103ff0790a,0x00000000000f7430}}, + {{0x000dd3174fcc39a0,0x00094517075af0fd,0x000fd65c623f7ba2,0x000e9493b86f6398,0x00017f296bf4320c,0x0001082765115657,0x0009000919607a96,0x000000000002f035}, {0x0004b29394d28cac,0x0008f5d13de7c5ae,0x000ea9b2719ceec5,0x0008089c0f58697a,0x00030ca7ca20f1b2,0x0001e1be52adcd1a,0x000ba096c07f42c2,0x00000000000baa0a}}, + {{0x000dc0265a01c54c,0x000233027c169336,0x0003342d9c6b202a,0x0006cd31b8b0179e,0x000a6dd5a4a7e6eb,0x000c82f110d2d27e,0x00002241682c0007,0x0000000000081075}, {0x000f1169b3430f67,0x00019f3903f514b2,0x00091dfa21d2d176,0x0005eed470bd3b32,0x0007e85a62931b62,0x0005ad640a46398a,0x0003a58ff6ef8c80,0x0000000000095bfa}}, + {{0x0006e424a5742fd1,0x0003a8cd6c9f7239,0x000180484ef81e04,0x000b0f589b8ad2c9,0x00070d9c999d9c0d,0x000f84ab4692a8db,0x00006ca407fd03c9,0x00000000000cc9a9}, {0x000b5d757bfbcaf2,0x000014813a7654ce,0x0008615f305ee56c,0x000f2934fa0a23f1,0x0007cb1f8d7aca6b,0x000d10c531dfa3af,0x000c1328036f5498,0x000000000000e012}}, +}, +{/* digit=63 [{1,2,3,..,}]*([2^252]*G) */ + {{0x00034e0d2aae29e9,0x00091a53f1a10241,0x0004dd23936a5886,0x000ed8532976d137,0x00065ee692d130ef,0x0009e7cc1cf5ada1,0x0004723ceda69d25,0x000000000009baab}, {0x00095b8627836d36,0x000237ee5baef4bf,0x000e9b1caaa769fb,0x0008ddacfdaff633,0x0009cec076939e5c,0x000fb509d575c8db,0x0006979afc8ae0fd,0x0000000000085651}}, + {{0x0000da11d13ab853,0x00042a7342f9446b,0x00039f5ef3dbc527,0x0008bf07471c3856,0x000130827f3450e4,0x000779c23729e5ab,0x000d5817199191ea,0x000000000009fa9f}, {0x00077a9b9dc5fca3,0x000827d5799369d5,0x0003bee46a6f5cc0,0x0007d51e85417260,0x000dec720355253f,0x000a16268107a793,0x00031b1c14d0566a,0x000000000008bbb2}}, + {{0x00016132445f3e21,0x0009ef5689c5dce5,0x0006397102e2e73d,0x00079d012eaa5340,0x0006d9271e941af8,0x000e63c34dba775e,0x00024b60f8507310,0x00000000000a686a}, {0x0006624c82f5c532,0x000dded5ca8f992c,0x000b2edebcb9407c,0x00039426d90a7d51,0x000bccd37e76e2ee,0x000412e0fe5b3e4c,0x0000489013bd08f1,0x00000000000ce999}}, + {{0x00009cf56d1d974c,0x0005561d0e01b86e,0x00046be97f98120d,0x000e224b362902dd,0x00029e0a5d16d4a4,0x000e580e945923c1,0x0009544fc2bdd495,0x00000000000a8c3d}, {0x0004daa7a4671003,0x000a1aeff11352c5,0x0005a1c5b6c0120c,0x0007d3eab8f9f31a,0x00066d566c158090,0x0002e6fa7af2c121,0x00003a0082daba95,0x000000000002df9e}}, + {{0x000fc79dfc540dc4,0x0004091b379c535c,0x00090bc691de574f,0x0004208176b3b828,0x0008aaba5cd3d0f4,0x000794f9fd18c211,0x0008944aed5c9770,0x00000000000f4c33}, {0x000946afeb1a61f9,0x000b9b8e67989163,0x0000523ed92edf12,0x000ef39ab5573985,0x0004b71031051b7e,0x000ac89e4175e393,0x000db8943abf4a82,0x0000000000057ffc}}, + {{0x00066f02c7c0f325,0x000f899c2b4cc9e8,0x000f2b3e2c2a45ff,0x000b66b5a352b7b1,0x00043ec757ed067b,0x000d36adc3c7d6fc,0x0003a42f69291cb9,0x000000000007c914}, {0x0004d853fbc3268f,0x00006768c3c3f0a6,0x000dd7feada4c10c,0x0004b025299ea1bb,0x00091a2d4005d86e,0x00017fa60be46b7e,0x000fbeaf865a1693,0x00000000000cdce2}}, + {{0x000297083b5951f8,0x0002b66fcba529da,0x000a6f9544c17490,0x000b97241b4305fd,0x000e25b6af89a371,0x0005f9e8cb2d858c,0x000ef8bab07d5327,0x00000000000d525b}, {0x00073848e93e22c2,0x00084ebf79e3bb83,0x0007a079aa9da5d4,0x0008b66cba1a65a3,0x00038b1eb8b67dbd,0x000a6436a88ea401,0x000e33210ac1b38f,0x000000000003df40}}, + {{0x0000b48bcae58bd8,0x000c45f79f0de54f,0x000db929ac4cc6a4,0x000a68e11571c5c9,0x000e2474faf7d631,0x0002a924a6d072b4,0x000d7a5e043a6d86,0x00000000000b0fc8}, {0x000fb0fbc0056e2d,0x0008bf54bb7f2f12,0x00058e2455c41895,0x0009f4c5909ec050,0x0005abd164608145,0x000b1c69ed28cda2,0x0006f4bb676d018d,0x00000000000ac503}}, +}, +{/* digit=64 [{1,2,3,..,}]*([2^256]*G) */ + {{0x0005d534448865a4,0x00079dbe04c30004,0x000de820bf917110,0x000b54670911457d,0x000b3f7a1757dbf8,0x0007bd62c9e683b5,0x00097e7b89a08a9c,0x000000000000b3fc}, {0x000ba720a0047774,0x000980ac9abfb9ba,0x00007bd7b6be79d8,0x000c335d9deed984,0x000f72603e080aa6,0x000783bb2e270580,0x0009ae70857a946c,0x00000000000caa92}}, + {{0x00008763d38fe0f6,0x00001f071c986bc1,0x000413c627ede21a,0x000b12a61483bc2d,0x00001caf6dd6845e,0x000c21b9217471d8,0x00036d7b603616dd,0x00000000000b9925}, {0x000a996617818c3e,0x0007f433f065211f,0x000b56653ac9464b,0x0007386a9adf49b1,0x00092cb2944fdf61,0x000d9c0764bfeb39,0x000576bf288427b3,0x00000000000965b4}}, + {{0x000b333ccbe322d0,0x000fbce23a199d59,0x000074dc302e3830,0x00000121d15a0063,0x0005f4355a1fc720,0x0007f780715fde73,0x0006913849761f60,0x0000000000018204}, {0x00074bfa03274297,0x0002575756e4ea63,0x0009809c9584a1de,0x00032763d4ce3dc3,0x000ef1d66e006312,0x0008829e6a769d2f,0x0006ef8624ddbac2,0x00000000000d2df0}}, + {{0x000f606b2db32f32,0x000b59ec11596f9e,0x0004a5f37de5fafc,0x00094e131fca111c,0x000896076f45acf7,0x000732588438b917,0x0000daad71035b51,0x00000000000a5d91}, {0x000d85cad07f3bba,0x000a7efaad0e82d9,0x000f829c6ffe7ff7,0x0002426474ce3273,0x000a2aa270da9940,0x0008fa6ebd53b687,0x00041196c8bb78d7,0x000000000006e699}}, + {{0x00044c83de3d28f8,0x0008b2dfc39e611a,0x00099024ec940ff4,0x0002123313aa4788,0x000b9c6acbd11cf1,0x000d54177785b025,0x0001eab4aeb5b8e4,0x00000000000d943c}, {0x00041945f056ffdc,0x000097892db846ab,0x0000f6f8e04921ff,0x00013c61cbd3232b,0x000700b6c34ebdee,0x0003de32b873e0a7,0x000302b279505ae2,0x00000000000c5a03}}, + {{0x000395d621a49e0a,0x000c7430b669fc05,0x00093c4a448f25c5,0x000730c4c33493e3,0x000fca00ed3901ad,0x0004a55168c882c1,0x00027dab2e9c89d2,0x00000000000f5d03}, {0x00020231a1107ea0,0x000f946488bd7b79,0x000d5a9d2b183f55,0x0000e90aecfac7d9,0x000fac6a9e8cf9f6,0x0008bcda84afd1f5,0x00099857a20bf8c9,0x000000000008b46b}}, + {{0x0005f4b3119ad50d,0x0006c1f2f6c1efc1,0x000be8ee71be11e0,0x000e4a6569c090bd,0x000adb3986d020dc,0x000f553eae4f7401,0x000bff1389799485,0x0000000000009026}, {0x0003665df6023a4c,0x000b388067aa6ec6,0x00069e9d017576cb,0x0005019459bf26a1,0x00058b6e76f68416,0x0000d2434ec125bd,0x0000b0d636f9321f,0x000000000008e05e}}, + {{0x00021074c1c07346,0x00068fe1f11ac76d,0x000a3e93fcce998e,0x000015a3c5babf98,0x000d5929ea0a99d0,0x000fb7b7e7e795b4,0x0002e8c9cf68331d,0x00000000000a6499}, {0x000716aaedb25dc3,0x0000d0b7e0dd7aad,0x00064fd90a09f648,0x0003cf034f02b979,0x000a5662f0c86402,0x000058ccaf7dd410,0x0001eda3bb6088a1,0x000000000004e780}}, +}, +{/* digit=65 [{1,2,3,..,}]*([2^260]*G) */ + {{0x0006b5199cfd1ff1,0x0009d140a0f9f409,0x0004971fd020b4cb,0x0007c2304a1f742e,0x0001195ba34e78ff,0x0007f78b4c0568f5,0x000a53e97183603b,0x00000000000f9efa}, {0x0009e6e1cb2c1b4d,0x000bae924d2c4efd,0x0004b415d4c5ceca,0x000e73f6ee37e106,0x000a5e5a1dde4b12,0x000cd64161836fdf,0x0004d87f1b92259d,0x0000000000067754}}, + {{0x000befa999003a02,0x0000e279fd119411,0x000606c204c4310e,0x0007da4da44105e5,0x000a28223fe1d8f5,0x0006f2d2eb1814b7,0x000e06cf2fd241e0,0x0000000000001dfd}, {0x0001563b8cdc2810,0x000a4876a31af711,0x000bd72037bc4e78,0x000d608493a6a0aa,0x0008a88c03e75117,0x000916897dcec808,0x000c57eae1d352ea,0x000000000006e8b2}}, + {{0x0001a9c4fdcf93d1,0x000650254486c9e5,0x0006796f28c8ff02,0x00058ba000f54926,0x000934009fb6fb58,0x0002bde301315bdd,0x000358b18a8e0ac4,0x00000000000f1070}, {0x000b8de4d767059a,0x0004ebeb1db7458b,0x000305d015a22913,0x00014d4e4122b217,0x0002aabccc7b1522,0x000d07571d3e673f,0x000f1794c50f64ae,0x00000000000e66b4}}, + {{0x0004bef0d3847d2e,0x000aa09f8bb05816,0x000388d5b381065f,0x000c7b6076e13ec8,0x00035d5ac07f26eb,0x000ab69e6bda0b55,0x0001fabcb8132248,0x000000000001c0f2}, {0x0006ceb771ee0889,0x0007b7a466528564,0x000e55b024527048,0x00011864c1d7cb8d,0x000f2d08130185dd,0x0005ea0f0096f849,0x0009b2b4f503dd8a,0x00000000000d1bf6}}, + {{0x000f0c6218b7c4e9,0x0008540336b12c41,0x000f74c446fc6c56,0x000048d9c841f0d0,0x00051d617f50c337,0x00017d3794ce6d02,0x00024300fef21981,0x00000000000f95be}, {0x000f7d33fe9f8bcc,0x000ec98de119d3a3,0x000e778f8a8c16b8,0x0005b720f9678bed,0x000d334ace309412,0x000e86e04fc5b57c,0x00003909486527b7,0x000000000006e552}}, + {{0x0001aa0f2e0127d7,0x0007b4ab7a22bd4a,0x00047f417a4172fd,0x0009f95078de336c,0x0006f786924520f5,0x000f1d96ffd28fa3,0x000f0f1de42581cb,0x00000000000366e1}, {0x000e183b180aaf06,0x000febc65fa9d0a4,0x000739e25cf57814,0x0004f3a4a0822a93,0x000bfd05a0aa0638,0x0005ee3ce1c81332,0x000d00bfb12361d9,0x0000000000042016}}, + {{0x000f0b32c63695dc,0x000143b75c45b10b,0x00037d16d187f9f5,0x000227df8e0a114c,0x000e73ddba245450,0x000f246455e69f1a,0x0007412007b80e57,0x000000000003d159}, {0x0007528fbc79a394,0x000ffcbe54d2888b,0x0004e47907e4e2fb,0x00070594cc39f745,0x00032b1b8da9e19f,0x000f68d2680f00ab,0x000829b765aaf973,0x00000000000e993f}}, + {{0x0000b5faa7527283,0x000530a159f61ee6,0x0008e1f9dcf0213d,0x000b8ee1661a2405,0x000ec95c41b36d1a,0x00051eb56cae7f40,0x000250bc3d20407c,0x00000000000e8754}, {0x000ae69a0a837ff0,0x0000281561056151,0x00032df2869a92d9,0x000c1bf6af2a00cc,0x00042d0a56c0abdb,0x000c8959ee9a9425,0x0002f34774a7b77b,0x0000000000019cef}}, +}, +{/* digit=66 [{1,2,3,..,}]*([2^264]*G) */ + {{0x00035e2ab65ec55c,0x000b3114a25c78e3,0x00036712a123ad50,0x00068411e7bd7df9,0x000ad6da54dbc49b,0x0000da3215b0359f,0x00087ea6e6e5f93f,0x00000000000d640a}, {0x0003244eb630ddc0,0x000f7c1a4f6cdf83,0x0008137a92bebef0,0x000eb8e3c0a631d4,0x000db756445ff44c,0x000c8880e0205b11,0x0000d304844e845b,0x00000000000b85e0}}, + {{0x0005c0fc3837219a,0x000cee76894c3764,0x000faaa07cdf021d,0x000fcfbe55cd1e6b,0x00023a7ad5b9566d,0x00087a4ef5421a9f,0x000423a005838a46,0x0000000000023a2c}, {0x000326b6922fa665,0x000ed4b780011f85,0x00024bae2459585b,0x00069e937ced8f3d,0x000d8c1e1eaa2b5f,0x00089cc4d306b621,0x0007748acbbe71d3,0x00000000000f4ab7}}, + {{0x000e8b5d217d418f,0x0002ee557e7c707f,0x000dffc8ed3b58d7,0x000efa4b42b3ab4b,0x000d8e53b32db9b0,0x000b1bfbd9d71dc4,0x000d3fe3a93e4e11,0x000000000009901b}, {0x0009bf805b79f71c,0x000b35f3a5304e02,0x0007d4e3dff75554,0x0007a7bef469e919,0x000278f160dcf415,0x0009189a9f03282f,0x000f2197e4b7f4c8,0x00000000000a967e}}, + {{0x00083fb3cef3edcd,0x000642df6f242046,0x00054e87770387bc,0x000232b372bcc88c,0x00086e428cc59e80,0x000a1b76326ba13b,0x0005f32526ef1f13,0x00000000000dc97c}, {0x0007320a0cda3969,0x000344954867fb10,0x0004f1baa6436a30,0x000fa69be143027a,0x0003cf54f28b7e39,0x00097c2da1232946,0x000099cf0991dc75,0x0000000000052e07}}, + {{0x0004ba256e3a80b8,0x0005fbdfea74874f,0x00090a65af244c4b,0x0005675aaba39901,0x0006a12be348d5a6,0x00018ac5d2250648,0x0006f9766dd428e8,0x00000000000fff9b}, {0x000ff89f1b07248b,0x000174b3b10f3ab0,0x000ac70bef37c1ca,0x00011ed5c9e36bef,0x000364cdfcdd2a61,0x000462f54a99a302,0x000b5fdbfbbe7a59,0x00000000000cc266}}, + {{0x00081f8725c117c2,0x00037dc9daeefc8d,0x0009cda216a5b4ef,0x0002271ca53d53df,0x00054d1aa50b206d,0x000001e99b054633,0x000aa452bca91088,0x0000000000017fb7}, {0x0007b7c6cf80a17f,0x0007afff3af9472e,0x0007c0765e5ecd82,0x00004be24753989d,0x0006e90950c6aac0,0x0008efe5b4a5de2b,0x0009f9b46af0ab73,0x00000000000db445}}, + {{0x000c5196b2aa222f,0x000d15bdb6d3f8f0,0x000389884e011601,0x00008a96ddd9e23e,0x0008467e7577ab50,0x0007555edac1e974,0x000d57e74e35b601,0x000000000009d04f}, {0x00080785cb147efa,0x000908585c6fc59b,0x00035ae9e9b63afd,0x000d1e80b684dd21,0x0009edbaddcc2739,0x000c57660e1ba788,0x00089a464f42059d,0x00000000000a7cf2}}, + {{0x0002dd131270b84a,0x000dd412f64a3e09,0x000b9c94f3cfd9dd,0x000cdc2c2e964e0f,0x000d0011cb01fbe6,0x000228f23e9a3b1f,0x0009a16c30762dcf,0x00000000000be919}, {0x000e7d10046b4ea1,0x000b4732711dfdf5,0x0008160cd8dd88e3,0x0008ba0c6eceba7a,0x0001f3c3d31d8ee0,0x000716948b171153,0x000add65060b633c,0x000000000002ff2c}}, +}, +{/* digit=67 [{1,2,3,..,}]*([2^268]*G) */ + {{0x00000725d23401df,0x000096f178dbeb92,0x000498bead595449,0x000b4b459b46611d,0x0007c72b4a58a6e8,0x0005985adafce826,0x00073321142175a4,0x00000000000e649d}, {0x000052db6dbc2445,0x0003a6bf42fe0182,0x000384cfd9aea017,0x000a58acd0291983,0x0009215492e1b0c8,0x000b5a5f0a73ff32,0x00049b895c545eb1,0x000000000006fcaf}}, + {{0x000a5a0bc1e856f0,0x000f28baef5de481,0x000a8b075c84a181,0x00058d754c8267b1,0x0005ccf703932685,0x0008ee021f924f79,0x000a4be3763f30f6,0x000000000005c01b}, {0x0006ee7749647d88,0x0008acc01a3e928c,0x000c22c3ac36bfb8,0x000512e6c45e3401,0x00084ef433f61ab3,0x00021f5afa978fe4,0x000a4023e2ea018e,0x0000000000011524}}, + {{0x000ecc04426e192d,0x000c692a7fbcd69c,0x000df4111d9bb7a6,0x000db2d02a8feb62,0x0002728cecbe8e45,0x000837662176c0cb,0x00082c33fcfbb0d1,0x00000000000d6f28}, {0x000d967a59df021f,0x000bc75a0f344b04,0x0001f4de7fbff391,0x00090cefa0453b03,0x000ff54c96fbf4ea,0x000f77afc5108858,0x0002fc86b46b5731,0x000000000006bf7e}}, + {{0x000215c3f055a1c5,0x0002fe1d42d93e03,0x000c50c3e0aa63b9,0x00098e783686967e,0x000474a30dbf5f66,0x000d20230bb5e159,0x000f8bef86bb5bcf,0x00000000000403b8}, {0x0001c2443b169c63,0x000fbf249aac89ec,0x000e2f941f78369d,0x000960cefca9a90a,0x00088f449c4b3b80,0x000cfe09ef28e338,0x000d260cdfc61bf0,0x000000000008b22c}}, + {{0x0001733d4c0dd30d,0x000af7013d596371,0x00017f590b1fdd3f,0x000898e35915f523,0x00039fd967d4bba7,0x00073558f9fbe5f1,0x000bea0aba8344d1,0x00000000000ffeb6}, {0x0009792191976aee,0x0004e928f68cbbf7,0x0007210e163722d8,0x000c4e06abb0ac9a,0x000a6895762709b5,0x0004045a401ef3f8,0x000ac355dbe9f79f,0x00000000000ef178}}, + {{0x00094c375a95d7b3,0x000dd7f89c2c3b20,0x000a45fd88318202,0x000e48b12d9f811e,0x000dc7a43dd0be70,0x00018ca3a703ac1b,0x000012a4309a2c21,0x0000000000001943}, {0x0009ce1f49259e54,0x000e6d9597d8737f,0x0001541e69df2d37,0x000760df1561aaa4,0x000e2d91ee39fcf8,0x000bbcb6de1e0306,0x00074699979031e0,0x00000000000cfcc8}}, + {{0x0005490cc3cc0b27,0x0002a4073f24615c,0x0003e0a87e36ac6d,0x00006c18fcec6a28,0x0005d75a73f10abb,0x0008c94883a7d129,0x00074165fd8700f1,0x00000000000732f7}, {0x00049117079dd0b3,0x00098d15d8c801e0,0x0009200404155fcf,0x00007c7120e12665,0x0001f42cc9fd9816,0x000a888cf0e486b1,0x000249e606c16c01,0x000000000001ea23}}, + {{0x00014f7d981a63eb,0x000cb923e948b882,0x0000fdde16bb34e4,0x000011a6df27debf,0x0001d57f4ca2345a,0x0004196e9ba6784c,0x00026df01b370311,0x000000000001aab4}, {0x000a2240acace9dc,0x000d82ffdc977a4c,0x000a7e87839c540c,0x000c01216f09c1f8,0x000e5b9cc0b65ca1,0x000150569612021d,0x0003ea910e10e95e,0x00000000000e2ab9}}, +}, +{/* digit=68 [{1,2,3,..,}]*([2^272]*G) */ + {{0x0008093fcd51c0da,0x000aaac58c9dfd06,0x00005aab38065215,0x0004afc2cc4252aa,0x000397c2bdf932ef,0x00049e19a08bd48b,0x000496ac8a7803a8,0x0000000000075c31}, {0x000fef0d3072e592,0x00057733dc7dec06,0x000d0f9063e4be72,0x0005b0847be21a8a,0x00055ebf426f6d9c,0x0004e9e5bfab0fdc,0x000089d60748caf9,0x0000000000069366}}, + {{0x0000e5d6509e91ef,0x00048b06c17a3a05,0x0001e37973be9551,0x000ae990038aeb31,0x000b58b402ca2440,0x00077732a83bf711,0x000932b8763e00b5,0x00000000000f651a}, {0x000cf91f09ef177f,0x00070be02ab9cf6b,0x0005ba59eb97ec90,0x00072f64283f8100,0x00072365da5e7ed2,0x000dc6beb098cf05,0x000d72d90e6f1805,0x00000000000cf7b9}}, + {{0x000bed14c2e5c1d5,0x0009f89b2edba20f,0x000638f30da8440c,0x000d9ce8943fce4f,0x00045a2ff9961dde,0x0006e87feaaf07ff,0x00008c69e60f92c9,0x00000000000b9ee8}, {0x000d99ec41a8cc2a,0x0005279d6d8c67c9,0x000b28385a21a71a,0x0005267350b7fc9c,0x000d8a2abab0c8a6,0x0004faf7ce9fcb46,0x000c8a57c3bfc62c,0x00000000000a8207}}, + {{0x000f000e371891b6,0x000b56f101762b79,0x0004acb33b163eb0,0x000e2aaac1dc8274,0x0009f835a1b62c58,0x0009915a451410e8,0x00048d981333a762,0x000000000000c141}, {0x0009810640a6c340,0x000184d20b3d37fe,0x000e4eb008d53e3a,0x000b68c2a2645f81,0x0007add082eaa664,0x0005ff2067a6bc85,0x000fcce7467dc63e,0x0000000000004e2d}}, + {{0x0000cfcf5d6b5960,0x000cc57fe04dac14,0x000998e82d998b8f,0x000bd40e0a341ea4,0x000b9c24fdba5128,0x000c1dea81adf3cb,0x000ef2b1ce8520f4,0x00000000000db22e}, {0x000911256ee6f617,0x000b2e9f05f28713,0x0000043d1376f349,0x00052d3f63bfade4,0x00006cbcc395a2ad,0x000714bd81b43575,0x000ca6fd1d7e0666,0x00000000000a40ea}}, + {{0x0004ca398c06d768,0x000c23d0efae2846,0x000878540a1ede95,0x0005a253f00eeef2,0x000cd86161cea5cb,0x0004a389ac2f9258,0x000159d2b0865f5c,0x000000000009b1f2}, {0x0008e174cdba2f0b,0x000245a758a60599,0x00087073a8d80dcb,0x0005a4949d301c92,0x00061c4bb89b8865,0x00060259c129647e,0x0007d106f0665ec3,0x0000000000006619}}, + {{0x000cae6e407127c8,0x000070262c90bff7,0x000ca8e9829543e7,0x000f8fb1577634a8,0x0004597668ad6514,0x000ff6ecf4678d63,0x000dfc90213b637c,0x000000000007518c}, {0x0005a2999ad1c0e5,0x00071d006db8f897,0x0004562511312669,0x0003aeadf6356731,0x000f1a366456acc7,0x000e73aeaaeaa4fa,0x000a480df51aea1c,0x000000000009a8e4}}, + {{0x0001074c67a33fda,0x00086a23545689bd,0x0009b9de484075b5,0x000247b132c568a3,0x000dcc4760bbab0c,0x000ae821b129a5c9,0x000f8303eba46726,0x000000000003df1c}, {0x000f0c5101b30f29,0x0009f010813cfb68,0x000cc25f999a807c,0x00020b31fe4b6007,0x000398dd32399073,0x000abb34cda3bfeb,0x0005f123f1ed1641,0x00000000000946f8}}, +}, +{/* digit=69 [{1,2,3,..,}]*([2^276]*G) */ + {{0x000261be9524972c,0x0005728524830014,0x000a9e4b0c851ae7,0x000fa9900e4f78b6,0x000b54a3f7a33a66,0x00065a79afd8a65b,0x00069a505d3f6319,0x0000000000018914}, {0x000675265cae6514,0x0008278367cbbd6a,0x000c906352414281,0x000b3f6f5af173f1,0x000a5ca36597e41b,0x00099f79557cb03c,0x000ef127f86cb87b,0x00000000000ad4dc}}, + {{0x00092527cce78878,0x000b138a49bf4890,0x00076c4f31c0490e,0x0009eca01b2f7c2e,0x00005be8359f5f70,0x000646b3fc479a65,0x00011b6b6a22bfd6,0x00000000000cc5b7}, {0x000c9aa1253a31c2,0x000d18e7dbc638f0,0x00085601e946c9b1,0x0007e04030271eb4,0x0008e22fb3c72d3a,0x000e0d46cb08b597,0x000915860d62789b,0x000000000001d49a}}, + {{0x000e171e53bdf97e,0x0008556d65155b11,0x00013206465d7fcc,0x000049f10dfaeae2,0x000ae30b70b8ef9e,0x000c6a56219750b3,0x00002611ed860015,0x0000000000012097}, {0x000714d4a4467bbb,0x000e279559d04c7c,0x000363f176594d50,0x0007323ae8fb3c53,0x0009a4111f88d6fd,0x00010a683834639c,0x000e9afc69a029a3,0x00000000000255f2}}, + {{0x0006e6e51e1dd6f5,0x0009766797f569dc,0x0007480d93f86f88,0x000f4a531adb034d,0x000e5d185cfc18ee,0x00053c27bcf1cb5e,0x000569f596a59bbd,0x0000000000069002}, {0x000a4105949da385,0x00053d9433e78e1e,0x00022ac847a15a5d,0x000d7ed65d68ece1,0x0009fb2aded8233c,0x0009b750e201bbe0,0x000f25987f4975ac,0x00000000000337f7}}, + {{0x0009f8de8126d12d,0x000626fb6b7bb82e,0x000f3dc00034e80a,0x00089d8316ff5318,0x00079894d65f98ad,0x0002801704800ee1,0x000537034ea3c448,0x00000000000c30be}, {0x00066423e58a8102,0x0009243c2d27d6b9,0x000c30559bd3f060,0x00040105eaef29b7,0x00017b678fc76545,0x0003012701d8f07a,0x00036554bc6f737b,0x00000000000e9473}}, + {{0x0005ee6b65e3f046,0x0002a3561b3fe3d4,0x0003adfe7b57a7b4,0x000831347fb79d76,0x0001c48002ed4374,0x00044dcb0a7f497e,0x000e0686221cce2c,0x0000000000043785}, {0x000bdab4ad1119ad,0x000279ee9061f323,0x000458b83a9d33ec,0x000e85b76f7f52c7,0x00090fd6c65f1d8d,0x0001f8a3939a713c,0x00040af74ca06771,0x000000000008ebc6}}, + {{0x000c37bd5d97c8e0,0x000841942c2ff6fd,0x000f5c9ed6475a4f,0x00052b5771a5972c,0x0004363c2048f3c1,0x000db8da24cfb1e7,0x00043dcd2ce8249d,0x00000000000a5ee4}, {0x00044b387eb3689d,0x000606fa84b3cea2,0x00069e100b1b94b7,0x00071368e13869e1,0x000c96f0f8a12e45,0x000d93dc039ac6a0,0x000ec9e24458ac42,0x000000000005f60b}}, + {{0x0001937d698b9991,0x000c7514cc1dc470,0x0007f6d12f9a74ce,0x00022ac2fc9230fb,0x000d92e23e21f0e4,0x0006d1ac0aa50a1a,0x00049370ac46d867,0x00000000000f9f54}, {0x0006e32302426e7c,0x0002059a6b86a840,0x0004338952e5938c,0x000cff13192968cc,0x00040b342dd8d3d9,0x0001da44113e700b,0x000760fd5dc7bb3b,0x000000000002c883}}, +}, +{/* digit=70 [{1,2,3,..,}]*([2^280]*G) */ + {{0x00067944f366244c,0x000d59e9af31428e,0x0009cbe9f6c4942e,0x000bd92582864947,0x0009b2e09205204a,0x00056b1017995988,0x000f260c727a3dfe,0x000000000008b657}, {0x000fac647b56af7e,0x0004cde35d954514,0x000e44c1af2c53f1,0x000261f36019feec,0x000966511d8ffa03,0x0001148b9afda42d,0x0003e1f63211dd82,0x000000000006f13a}}, + {{0x000fe40d0b19b4c9,0x0006a3997900ec16,0x000abf1980c5bfc2,0x0005b0a661f3c579,0x0008aab1292b71bf,0x000d993f244b1338,0x000966cbe80cb9d4,0x000000000002203f}, {0x000fa9a95e9148b0,0x00053bc82a651a1e,0x0005a004b90c2827,0x000c7e7502f0003e,0x000056a38f73a388,0x00087d9b09c704ef,0x0001f393cde8a734,0x00000000000ec11a}}, + {{0x0004e6a4ec3efae0,0x000e047fe47986cd,0x0007fd532d6e5353,0x000fa8b9a8671744,0x0000514bf471b76c,0x000dcf1fc9bc87bf,0x000fa837392dce71,0x000000000003ad1e}, {0x0001e59290757ebf,0x000cebbea5a33841,0x00075b7402f28c87,0x0004ecd9b1665aa2,0x0006e329df225b3d,0x000aa808de7b0df2,0x000faf18fb438e0b,0x00000000000dd516}}, + {{0x000d8d8f4a6b2b66,0x0002a63f27a255cd,0x0003341f52773d72,0x0007cd965f9ce38b,0x0000635ba3005d31,0x000343662162c92e,0x000ac85259f64ffe,0x000000000008e614}, {0x000a1c59580d5fe2,0x000e397fb55baa90,0x000365cc03ff132a,0x0007325780618255,0x00086c1e6306a57e,0x00067b14c892f6b3,0x0008c5f12e4c0723,0x00000000000c83a4}}, + {{0x00040eada4657ebb,0x000e31e6f9a95314,0x000a04269b290326,0x00056256e8b41991,0x000b7a4a53f9365d,0x0002b9b16e1b9c53,0x00070155dc1d50e3,0x00000000000bb6d5}, {0x000b5b1121311bd1,0x000984c270249c99,0x000f7b0846375c38,0x0005b610689902bd,0x000fa4cfc5a819a9,0x000e5b424dd5706b,0x000a87d33bdb7314,0x00000000000e69eb}}, + {{0x000fd0482abbdf6b,0x0004f6897401cbf6,0x000652cc2d40814f,0x000b32939e2b43ba,0x0001bf809331e511,0x00058f8f43952286,0x000727815f6c1dc9,0x00000000000c213e}, {0x0009a038bd421fe7,0x0008ceb09ae59065,0x000d25d81924ad76,0x00015a2a20f86c7b,0x00069aa308078f48,0x000758878748a176,0x0003d7f1f46a211b,0x000000000006f6fc}}, + {{0x0005626ca6bcb860,0x000ac75ba2f9acbe,0x000c234135494b93,0x0009e0b610d080fd,0x000333a99c2f3c33,0x000580aff614ac29,0x000a3aa5e23af2aa,0x00000000000e1fdb}, {0x000ca5f5b322ee30,0x00065aa603365011,0x0001b05f57ab1134,0x000524456330a336,0x000b9e025aa3a2b2,0x000a0d5cfc396b5b,0x00083babbf77faf8,0x00000000000ea31c}}, + {{0x00047a49edb97340,0x0002d300b04831fb,0x0008ca060cb164c9,0x000c5420cc10a74f,0x0004eff9d01017d9,0x000aa12857f637e8,0x000114d732aa1e27,0x00000000000e2a77}, {0x0008fc5f031be351,0x000d262acf1585bd,0x0001b0dfbfbd395e,0x000c5d22e6eb2db2,0x00028d18263d88be,0x000bbd6acaec2720,0x0004c04b687353e4,0x000000000000ff7e}}, +}, +{/* digit=71 [{1,2,3,..,}]*([2^284]*G) */ + {{0x0006ecc79d0fef75,0x000dfa6e19d09c24,0x000097d1dea89821,0x00080950ee527a58,0x000b7c4278a6ef73,0x0000798ff78b7174,0x0000cac133d867e7,0x000000000009e923}, {0x000f7954ffb5e165,0x000877431eeef1ad,0x000728c869881eba,0x000306a8d6af3f83,0x0000bbec076af7a4,0x000257ca3633bb5a,0x0006636d07623e7a,0x0000000000021c00}}, + {{0x000f8db3d9e25bfd,0x000ed35ae891ae18,0x00094f42c82c0dd3,0x000b3cae63745c4f,0x0005f218d139c2da,0x000f3b0e255b8c18,0x0003fa6ab039c889,0x00000000000c644c}, {0x0008fe1e4d75d65d,0x000d9c8496f1ff0b,0x00010bc25fdaddb7,0x0008392921149191,0x000fef73f3455c67,0x000fcfb22e962e52,0x0009113818baf354,0x000000000009d4bc}}, + {{0x000af695e08e48a8,0x000683a35938698b,0x0003114a51ff94f2,0x0000f82899d204cf,0x0009158780b5fcce,0x0004edd4f4ca4158,0x000c34c28f1bb73c,0x000000000007a6ae}, {0x000b281e555c9d40,0x000676d4783df7ee,0x000d1f8a08acdccd,0x000c2bcdf6d7f923,0x00000f356ca3b7b8,0x000b8e964f0a8d47,0x0000e1229894bfde,0x00000000000d3aa7}}, + {{0x000d000279a1a838,0x000b77f1f985b888,0x000a43ce9b20f9f6,0x000930a5188fcf70,0x000ba3a82904b40a,0x0001510273fad79a,0x00017b7bee8d22f3,0x00000000000c2c3e}, {0x0003fdcf0848373a,0x000041fbe06e92b8,0x000ae48de4a30594,0x00090ec2d9cf7a56,0x000a9bd062c5fff2,0x000d353815d0deda,0x000eda080344abd7,0x00000000000f5cf9}}, + {{0x00012d81fb28e752,0x00018093526223ac,0x000d23e13369699e,0x000d26ee94c9abed,0x0003a20b52679a62,0x0003d5fa4425b86b,0x000fc68164f9c8e7,0x000000000003b12c}, {0x0006c5fe565db2c2,0x000be6cc34bad21b,0x0002901d6245306f,0x000f50970e4963cb,0x000cf0813b31f80f,0x000f1ab8ee403ccc,0x000b92a72ab5f584,0x0000000000070f15}}, + {{0x000e213ed814f6f4,0x00034170098ddc99,0x000e9c62ee04edbc,0x000b04b8660d7749,0x000b5152ad1e35b1,0x0008e92aa8b4b6c4,0x000f4e0b0bd1c24a,0x0000000000088172}, {0x0007445379f53f7e,0x000d513a76898c7b,0x000f4e73336bcd42,0x0004f973dc17e72a,0x00060a7124b24b39,0x0008a372c1b0cd16,0x00003b7549880cce,0x00000000000e7126}}, + {{0x00055aa45f74a004,0x0008dc14a3abb979,0x0004a411c66e9f88,0x000f1828a4be08cc,0x0009deca5a89e49b,0x000fbb36be6e7bf8,0x000e57a7326cf88e,0x00000000000c7f6a}, {0x000da2212d19f21a,0x0005dceced37b724,0x00062d313930a591,0x0005b3fb62a62e4c,0x000793e5c0e1a7e6,0x000b8d77382cb79a,0x0002f014c9a99461,0x000000000000b05f}}, + {{0x000a2dd7deb1dde9,0x000a831d31f799b5,0x0008e986349103b0,0x000362e52f04d685,0x000921c7b6511793,0x0006f47f65808e70,0x00040533fe9123ed,0x0000000000058f71}, {0x000d5dbe8f1956b4,0x00061821d30451f3,0x000e7b4e166f399a,0x000db145b2048aa2,0x000ed7811330932d,0x0008fd85f17d989f,0x000434032ae4cb12,0x000000000007d1ef}}, +}, +{/* digit=72 [{1,2,3,..,}]*([2^288]*G) */ + {{0x000acb4203cc71b2,0x000a9070d34e112c,0x00047b523d821ba6,0x000f9b95eb8ad292,0x0006a6a45dda269a,0x000df41e0dde0a03,0x000f2aa18b528e63,0x00000000000a260d}, {0x000c22d6a6aefb01,0x000d424a67709f9b,0x0002a9971343d570,0x000e2a1968444330,0x000d131a6cf073c1,0x000e794543660558,0x000dcdb0289c832e,0x00000000000c6d8d}}, + {{0x000d86ee6f475d5b,0x000d30ed1082f1a9,0x000a6711ccf28680,0x000ef0eece773534,0x00064bf0c426a35f,0x00011b2fb76adaa4,0x0004d3fbab929aa0,0x000000000009d8cc}, {0x000bb954fd395b2c,0x000dabe6d7f2076f,0x000a4cbdfe911e02,0x000cba5106ceaac2,0x000a45258697c7e2,0x0005945b0fe94528,0x000f7a7109b17d07,0x00000000000cae17}}, + {{0x000ce6be22a12c0b,0x0008a6855029961b,0x000a3c801158be2e,0x000d2b4a8e92e70b,0x000f0cc9fca9f601,0x000bc2e96fd02799,0x0009b889f99ca013,0x00000000000ff9db}, {0x0006b1bd37f91ceb,0x000616ae70849faf,0x0005d65bd4da44b0,0x00092a4e0945e8f9,0x0002ecea36f6394d,0x00018a069ddab675,0x000860650b74d60d,0x00000000000ad650}}, + {{0x000bf5b4a4380ef4,0x0001cfc1faedb8cc,0x000e6ba03d77f4c0,0x00085456416defe8,0x0000c58653e7f004,0x000f6f99e75de777,0x000c07dd2dcbebe2,0x00000000000d159a}, {0x000c9af1998a9b17,0x000a045dd713c4a8,0x000e1c3678ddf502,0x000756b6b962b38d,0x000bbffd3f0c3f73,0x00008ebae3cb9f53,0x000dbad723c40b7f,0x000000000000c3cd}}, + {{0x00003107748ef382,0x00058a804b2f0156,0x000b319b886fb1eb,0x000f4fd353970be7,0x000712854a9131ba,0x0009713983481c8b,0x00094ab0424eecf3,0x000000000000f4ed}, {0x000648ea129bd87a,0x000a992b74ad013d,0x000692f5d2444d08,0x000b28070a5f0c93,0x000b9f5101ca6741,0x000d0f81e46c12cf,0x000288e7014d7901,0x00000000000d758c}}, + {{0x0000c39f81600214,0x000686a565269228,0x000c17ee858626b0,0x00011a7d8c6ddb92,0x000b2332347b0bda,0x0009dff48b7ebfaf,0x000c83cf791881e9,0x00000000000dc357}, {0x00082704ffef2257,0x000fe2a264f8831e,0x000c9352584eb7a7,0x0008260bb47d4188,0x000c3d8170326d47,0x00005f901544de4e,0x00063cac7150a9dc,0x0000000000075c09}}, + {{0x000bcfd07a0f22c4,0x0007c58805ca858d,0x000b1c2b2351e4ce,0x000c9a1349cfed00,0x00017800a980f9cb,0x000847e9d67bc7b4,0x000c48e7e6dbc0f6,0x00000000000af379}, {0x00047d63263e04cc,0x0003c80b6fc048b9,0x000808eb22fe8f7f,0x0001ed14e9dc24bc,0x00073fab87e6d2d1,0x000c630ae48d74f1,0x00020a1feca5af50,0x0000000000062d06}}, + {{0x000e56ad2bfbbdbc,0x0008ff6377e3bcab,0x000f30b92835c3f0,0x000ac42c21c0cf1e,0x0009857d8edb7f85,0x000b77ed67a3e31c,0x00010b2eb1076327,0x0000000000038dae}, {0x00026ce2d0dbce6d,0x000dced7c6fb0aad,0x00066cec0d07ac1c,0x00035504569e7309,0x0007bedae3ab4dc4,0x00027e463aa82fb9,0x000a1106d37bef4f,0x00000000000f0c35}}, +}, +{/* digit=73 [{1,2,3,..,}]*([2^292]*G) */ + {{0x00011f784b3a0046,0x000066edf5561b45,0x000c8578d54224c1,0x000ae56d8d66d29a,0x000ae9d58eb27699,0x000f9176d5f81602,0x0003b1d0c04874fa,0x0000000000052315}, {0x00067980492adf03,0x000309690930fad0,0x000146ea47ef3788,0x000725873bcba90f,0x000de902e3292d0e,0x000bc27b957efe72,0x000c093fcd598676,0x0000000000093940}}, + {{0x000cdd973668c530,0x00077c68b641e912,0x00064e1ee190b62b,0x0008cbad89ce6688,0x00006c269d8eeda9,0x000f3402315f84dc,0x00034af0eb685ecb,0x00000000000c0326}, {0x000bc909db075650,0x000562e3d7fff094,0x00012e59576050a3,0x000abcfa3e050e0c,0x0007c001dcd9f02c,0x0006d2d52ccd2da6,0x00041f50aa372306,0x000000000007224a}}, + {{0x000ec1f1185b9762,0x0007e4b1f8698c94,0x000d0af36ed765ea,0x00049f56536e156a,0x000109c95a75ba1c,0x0006d9af131c3163,0x0008b7268a308f0a,0x00000000000fa9ca}, {0x000f13b9ac944487,0x000b1c3b1cbccb86,0x000446bb4e60be0c,0x000c7b334396850c,0x000a048a69431b4e,0x0005820bf42f21d5,0x000a580bf948f55b,0x00000000000b48dc}}, + {{0x000b86ea9a29c966,0x000cd04418b58cb8,0x0002d1612a6d4e73,0x000e22c7c65a6da4,0x00051dbeffe45f87,0x0003cc05caac7106,0x0002c4ff619d64bd,0x00000000000e65c9}, {0x0002126bd4b5ea52,0x000d123af2b21062,0x000e0691b9e9f16b,0x0007efac6478c561,0x000af6cd140ec34a,0x000a0db2e57cde95,0x000b7664b74575f5,0x0000000000075d7f}}, + {{0x00078c972345257c,0x00058a9532cb266c,0x0002b89ba64976de,0x000067545b1733a4,0x0004cc6e65dd74ea,0x0006ff2aa7f37f02,0x00079e6612b1425c,0x0000000000030374}, {0x000f1ac7f7aa2f0c,0x00097e512bca4fe9,0x0003049963042b95,0x000bd29a259d6515,0x00077373034f5b97,0x0005aa640215eb65,0x0008b779da0fc488,0x000000000007e435}}, + {{0x00041294c6ef7a53,0x00023ce3cc51372d,0x0009af7f675a386a,0x000d981efc9f71b0,0x000a20bea9baa9e6,0x000ef7c1fc01ded6,0x000a5cc4b7e6424f,0x00000000000f9dec}, {0x000954a122b474b3,0x0002aa0a43d0a3de,0x000a0d55c109a592,0x000a173b5d57bbf3,0x00056299978197ce,0x000ca2bb13c3f30f,0x0002e069a7820a8e,0x000000000000ff69}}, + {{0x000deeb8201c384c,0x00029aca3f998176,0x0001642e9c9fe922,0x000dbd63d82750be,0x0002faa3400be031,0x0005fd54bfb2552a,0x00030374e9b5d365,0x0000000000035894}, {0x000839a12661f3f2,0x000a15a575a4221a,0x00056e3aabcc078b,0x000ada596e1e1175,0x000d0f305dc3ca6f,0x0008d7af5126e9af,0x00069391da8d7305,0x00000000000d8353}}, + {{0x000cb9cfccb5f12c,0x0002c28405061c1b,0x000211e4805b5eb0,0x000944405547f7c3,0x000d3441e472789d,0x00044ce877fa445e,0x000d14feb198254a,0x00000000000129ae}, {0x00073247d16dc8ed,0x0008622b05de2de2,0x000590692ea55dfa,0x00052caa83f7f094,0x0006cefaa757fba2,0x00017d8060f6ad6e,0x0007ade1ad187165,0x000000000008e9d9}}, +}, +{/* digit=74 [{1,2,3,..,}]*([2^296]*G) */ + {{0x000c5ac4350713f2,0x00062cbb991946e6,0x00025875bf6be408,0x00024aab6ab6c041,0x0000bc41f4b7d50b,0x0005496cf419d281,0x000ac0e2e88d7a29,0x00000000000f2457}, {0x000a357ad05dad34,0x0008e838e4a3533c,0x00068ef45f1df4fb,0x000ab1c7a5c5fdd4,0x000dde34cb8d9fa3,0x0009105fe324798c,0x000249bfa5a9d088,0x00000000000fd0df}}, + {{0x000b286ea52474ce,0x000419974759bb2f,0x00039b1e3f8aef8e,0x000c58ec64941cb4,0x000a01d055758afe,0x000448db52d7c57f,0x000440c07c74cc5c,0x0000000000001bb1}, {0x0007977c86a9c43f,0x0003893162d96796,0x000ee52587841e45,0x000c57e6af18dedc,0x000f174a30894f28,0x000dd626536faed8,0x000d7b702dbd64a3,0x000000000006adc0}}, + {{0x0002a70e7d991630,0x000854981be688ec,0x000de0f53a95f8f1,0x000e05074cff00d2,0x0001b52c7f9c3168,0x0001c7986111150a,0x0002ad0db2ed84a5,0x00000000000e6127}, {0x000c16b3e4d1fe2a,0x000897443d935440,0x0002c51d6c8aaceb,0x000ef4e866b5e41e,0x0005b965a67071e0,0x000e1aa7705c57a4,0x000e3285bdb58c70,0x000000000009df3c}}, + {{0x0009a11de31a0e3c,0x000c6c41e4aed12a,0x000342590d5103b5,0x000ab7b8ed812d38,0x00081afb58b8f5ea,0x000efcc3a7801fbb,0x000b91be5cdba671,0x00000000000cd10c}, {0x000761b96524aa0d,0x00013882e821e20b,0x0008d1b11d20578f,0x000de2bd8a0f0393,0x000c857fd3a03afe,0x00060f767e20a117,0x000da1ebaa2aa430,0x000000000002b9d1}}, + {{0x000d9fea4e493f3b,0x000e070e478fb44f,0x0000254b6a02edec,0x0002b005be36ea75,0x000f6717e06aaec8,0x0008f197782618b8,0x0000d12db1f6d400,0x0000000000016b39}, {0x000ddfa794ec9644,0x000bafe86fd4d041,0x0006bc15de0d2bf6,0x00023e70c0491593,0x0005ed4562356cbb,0x000d836efd05be7e,0x000604601374069b,0x0000000000032e5f}}, + {{0x0001ebab46405b61,0x000f009db138cd2b,0x0009fd7df23c53c0,0x00047794feebab9a,0x00017fdb1e710bb6,0x000f1f65dfce4aee,0x0006cd7d5c0c61a7,0x000000000008d02d}, {0x000621234d968fad,0x0005c7cac0485224,0x0002b8dbf87d2555,0x0009a59db0aa864d,0x0008ff94f8b5b587,0x000c97f8e75f391b,0x000232a6c994ae49,0x00000000000d690b}}, + {{0x000e6486f79bfa96,0x000e507c60c742b4,0x000d5aa8cb9b07e8,0x0000a09dcba89982,0x000a802ce50ca8b0,0x0002144b0a77f1f3,0x0000db6c4050df2a,0x00000000000ab1b1}, {0x000a93fc6ce00720,0x000e89025d46fd65,0x000c1e4037fdb9f5,0x0002d629ae2d5361,0x0009eff0f6a9bcad,0x0005fa5a07a15282,0x00039ce87345cd92,0x000000000000e840}}, + {{0x000cab548e246919,0x000d15017e1454d5,0x0005f67186d3e9b6,0x000059dfa98234b5,0x00099985af982541,0x0005b7b1c4bf344d,0x0001ad39737ed67b,0x0000000000087c41}, {0x00069e3ff4c10920,0x000022fad8cecc3b,0x0008e45c000ca718,0x000d856404043f8d,0x0005863927a11a53,0x0008921216c1f07a,0x000c8f38d3a4f4b6,0x0000000000001976}}, +}, +{/* digit=75 [{1,2,3,..,}]*([2^300]*G) */ + {{0x000dd4906efe62a1,0x00063bcc8842253e,0x0007a247757fdab1,0x000a1ef2571d6b1e,0x0001739a956e745d,0x000bffc16f01c292,0x00072ceffd8065e4,0x00000000000f36fe}, {0x000478592361b14b,0x0003ff49e90d1ebe,0x0001338e12b047f8,0x000b583b7240d91d,0x000c03f8387fcb78,0x00000f2d92e1a7c3,0x000a8416566c2232,0x00000000000aaf80}}, + {{0x000f32d335de93bd,0x0002d7a1a522aee8,0x000b425f9e81403f,0x0004abe3d4ac4abe,0x000337f996e841bb,0x000727761c52950b,0x0007d201d991e679,0x00000000000978fd}, {0x0006e2e2907ff054,0x0007486bad5e5c68,0x00010431aa78725c,0x000eb7705757453a,0x00093939df7758ff,0x00078ea0fbb18612,0x0001d3bfdd394a6a,0x000000000006e33e}}, + {{0x000c3ccc7d56f63d,0x00076db1cffd2381,0x0002131b488cf4cf,0x0001e5aa3c1db85a,0x0001ac55d391a418,0x000d270d0e5183e5,0x0005462793d5efef,0x00000000000c0631}, {0x000c80c1d49264dc,0x00008ecb40a58378,0x000aa60ec18fee5f,0x00014ab6c5830fab,0x000ca03f201ea89b,0x0008c54f64dc477d,0x00066e5604f5dac8,0x000000000002acfc}}, + {{0x0003e9c742a5516d,0x0009da7f29531cb5,0x0007fe865f9eba30,0x0004ce9efae348cc,0x000cac52758dd2f5,0x0002961a45acb931,0x000fe1287b3e18d2,0x00000000000748f8}, {0x000f0554bb131f76,0x0001d1b62b340cc5,0x000b08ad2a8e1d6a,0x0008dadbe8da8486,0x000954f18276bad7,0x0004bfdad85fa710,0x000237e2cc9d287c,0x000000000002c75f}}, + {{0x0004d2c2f1f927d3,0x00033283dd7ef2a5,0x000a91f40054b9d9,0x000c095870282aba,0x0008f4e36324ba08,0x0004cecf2b02b00d,0x00024e53aaddc060,0x0000000000084ddd}, {0x000a889fa3214142,0x000ca34bc00a03f8,0x0000c263c00349e0,0x000eaaacef68f74d,0x00023c0293515228,0x00042e3b740a790d,0x0001e0e0e9af5c84,0x00000000000a9f14}}, + {{0x00087ba6916bcaca,0x0005bcdcdd7d6721,0x000b58247a460e0a,0x000c569c00ce5c40,0x000fc589d0c75923,0x000fa6fe6099c17f,0x0008c40335eeea89,0x00000000000a4e86}, {0x000a7415516e07c0,0x00024b7037325a9f,0x000944c467e9c1bd,0x00032efd5e26d28a,0x0008de919cbedf31,0x000bbb18d7ed994b,0x00050812df67cd6f,0x000000000006baff}}, + {{0x000c3f58ee594ee5,0x0008b72f4949e0b4,0x0001e5bef192dfaf,0x0004726092a58066,0x00010f5cdb7271b0,0x0004bfc49ad5c3c1,0x000be7d4951f9e55,0x000000000006131e}, {0x0009f77a3840f92f,0x0009237da59f303d,0x000ff0c06b034503,0x000962a4d89fa660,0x000e71d824f5d020,0x000050e312610c61,0x000bfb9c917da73c,0x00000000000e6e7e}}, + {{0x0003a9eb85c489f9,0x0003af2ec9ef5122,0x000d827990bab108,0x000b2387d2ac6e41,0x00020318a3b790e2,0x00084a7a0cf682b1,0x000d057fe76089ea,0x0000000000016546}, {0x000bc6c0a0421345,0x00041f987118eca7,0x00079f0cde4a8da9,0x0007774888a7e8d0,0x000a63ec5831544c,0x0002fe985bd2647b,0x0003e8b479cea3fd,0x0000000000028d16}}, +}, +{/* digit=76 [{1,2,3,..,}]*([2^304]*G) */ + {{0x0005b08a8a2a82b4,0x000fa04baa17598e,0x0006a0661405c62f,0x000031dc6cd61096,0x000030bf87a5c4a6,0x000e497ccba2534d,0x0006657ebc6e2131,0x00000000000851fd}, {0x00018d257f3e221b,0x000e69ecae010ee2,0x0009788f9b15d390,0x000a9c22fa527837,0x0001236d442e39e8,0x000c289ce74c9380,0x0009cf8b21ba23b1,0x0000000000025c76}}, + {{0x000aafc618669c84,0x00037761e10e2b1a,0x000c03aea1a1a99e,0x0000ff43dbc6fcaf,0x0006cbe0ba8aa087,0x000f1ff6a9765128,0x0005b647d46075c0,0x000000000003abeb}, {0x000f7f59840e13b0,0x000af1234c80e297,0x0000d9f885a37dab,0x0002d41d82ab780a,0x000fde426e50399a,0x0006dde778a03afa,0x0005eca2bcb109ca,0x000000000000618f}}, + {{0x000adbd12143606f,0x0003e0d27500f7d7,0x000cde21714cb370,0x00078f8610763e40,0x000f47ef08feee75,0x0007d04c06e56078,0x000aa3a8d03a7f04,0x0000000000027cc8}, {0x000677d27af9cf4f,0x000056b08eb37c00,0x000a4a2b5d3fdd3b,0x000869ae3f10ba99,0x0003e500e8466f9b,0x000171b1a3bfb983,0x0000456d975557b9,0x0000000000018fa0}}, + {{0x000e348941e625d9,0x000fc15d47e52aa7,0x000dc7038ccf5369,0x0006a3070cddb11e,0x00032b5a8db75122,0x000f37d6563a253d,0x000b91e8be4d1fbe,0x00000000000c0920}, {0x00045423a83becc9,0x0008308b713a8319,0x000ebb9d576c8cba,0x0005877917ee393e,0x00091528cd12a897,0x000daf6aa294792e,0x0009b94512dc8c37,0x00000000000197a9}}, + {{0x000e5d8cfc9c3b49,0x000e0cfebe026cd6,0x00010748e4a52d81,0x0009d16725ebd099,0x00007a584e8d00f8,0x0001cab5894c6f2b,0x0003c8095ac9cc91,0x000000000009c407}, {0x000462695d0ed83f,0x00056265919b06a1,0x0003cfa033d1cd2a,0x00097f1815a70aa4,0x00001c5fd35a6db5,0x000d52a8bdd9e4a1,0x000fab38b8e35112,0x000000000002ef20}}, + {{0x000003aa77fd8f2e,0x000b43b21dc1edb9,0x000008b1e2380339,0x000e5d30da87d664,0x000f0cd999a0f536,0x000e08f5d4ce10ed,0x0007e68949181450,0x0000000000052664}, {0x000bcdd23ee4cc2b,0x000a3cb207ee8e61,0x0002ac9dd73c4f6c,0x00040d225e0cf154,0x0001067fa0527d49,0x0008b2e21b688b31,0x000eab89308326a9,0x0000000000072311}}, + {{0x000c6c4de58ef59c,0x000db2a6280408d6,0x000f4e9cd796cbfa,0x000daa3c647fcba8,0x000f4952d3a44a2c,0x000e2e2c3e1a9e91,0x00040ebc1b3d8011,0x0000000000018e43}, {0x00017ee00926dad8,0x000cceb8696ff13d,0x000436379cf7b867,0x000d6ce6c1e905c6,0x00091ed2e8cba471,0x0007c8c914e13d60,0x00084e52951509c7,0x00000000000e2348}}, + {{0x000a3b1514eda4ba,0x000ac37be5d3f53e,0x000cab6203ce338b,0x00024b59d1569e7a,0x0009b4e293ab165a,0x000b7c0a4254aaf5,0x000b183c751fbd6f,0x000000000005018c}, {0x0000fe7bbd1e6c72,0x000eaacb3b8965e4,0x000a2f2ab6db69d7,0x0007258621df6d82,0x0003185f0e2a245d,0x000ddbd812af0e28,0x00002a1e7edc818f,0x00000000000c538d}}, +}, +{/* digit=77 [{1,2,3,..,}]*([2^308]*G) */ + {{0x00042da90721f8f9,0x0009f6858b6747d2,0x00082ecd0813dd9f,0x000674e29d9194d6,0x0006dcb30a51324e,0x0008aa5492dc6fdf,0x000a923f3ecb7752,0x0000000000023ffa}, {0x000c7344981b01f4,0x00090d8efcbd58f8,0x000d0144b46e312e,0x000b0b74cf4a1708,0x000fbbf335fd04f2,0x000928c36bc0bb49,0x000d45c6b6e5bd5a,0x00000000000d893d}}, + {{0x00016a2799bedc34,0x00022fb083c2a5e5,0x0000296a1d9c8cea,0x00030e747a81b965,0x000658a987376e41,0x0002829c9cd704dc,0x000d63842ae32959,0x00000000000be20d}, {0x000f531daa9bdad7,0x00053abee8e552a9,0x00078232300aac8e,0x00039b2467112ba1,0x000fbe341038781f,0x000a2f8be6f06058,0x00066e5effdca512,0x00000000000af344}}, + {{0x000afa3ee32c886c,0x0006d3933b4c0742,0x000439c40f3f936d,0x0003c0f0b7e019e4,0x000fa48715d652fd,0x00039be537f8e5dd,0x000cdc0879c5defa,0x0000000000056f01}, {0x0005bfa2d160b7fa,0x0004671b2dcba45c,0x000e0bb6fffdcb60,0x0004846640b2d753,0x0000049a2cbe6af9,0x0002ab0f178a1071,0x00043841a1ce67ac,0x00000000000a76d8}}, + {{0x000a317691072fc1,0x00025ab86639e0b1,0x0006a85f7a13b8bd,0x0004418d763f0bbd,0x000211a9802cb573,0x000269b8ad2cc332,0x000355e41d7db881,0x000000000002ecfa}, {0x0004e57bc1e94af4,0x0006159d6912442e,0x000356e842631b03,0x0008b6b8a7397395,0x00091cc83ae38447,0x0007ccd97e86ad7d,0x0004c6bc9b208479,0x0000000000069494}}, + {{0x0006d3d1d84bf486,0x000a4bbb6725a843,0x000b1260c5ec574a,0x000dd0664bcb2d64,0x000a780d5c1bab65,0x000a61e6e755e848,0x000b4b84e6f686a3,0x00000000000bd100}, {0x000cfe4a11d7ea4f,0x000a3b34fdf84517,0x000d9afd2967c440,0x000c881f9a125f0d,0x00064aeadf8e3c2c,0x0006bf0c2b1fcce5,0x0001bebdfc54c0c4,0x0000000000009d28}}, + {{0x000af84d84069bc1,0x00010e1aa844a91f,0x000628bd439b9e84,0x000aba65ddcb5d25,0x000a38009c6a3025,0x000261ee5ac8cdab,0x000430b9ee07b46e,0x0000000000006ab8}, {0x0003196ba81697a7,0x000207a36b461d0a,0x0005a884d3b0fe10,0x000f469341275a1d,0x000f1c7cf858ae4e,0x00092af3df7cb393,0x00017683c00eafd1,0x00000000000a1e15}}, + {{0x000475d9329b61bc,0x00078687d0980c72,0x000d109af3ad73e4,0x00007fabbcde5b3c,0x00016ed103a56414,0x000a6ee2212ec9d2,0x000c11f858c7851f,0x00000000000818f2}, {0x000247f6c002433a,0x000a04720d42a19d,0x000f64099b42a8aa,0x000f25533723e4ef,0x0003d3260b6299af,0x000391c33d6c67ce,0x00038163a6fc9d86,0x0000000000031de2}}, + {{0x00092324c0c2dff4,0x0004f585edee2c89,0x000820f42406ab00,0x000924fd85ad3203,0x00019124bffa3bd7,0x000c628682e7d8f9,0x000f5d885397c044,0x000000000007fda9}, {0x00035c11900b0d2c,0x000e6d302582e314,0x0003e1f066fcf73e,0x0006b5b63653c06e,0x000d9c70dad4b021,0x000bba93d8f08a1a,0x0002b7ccf014aaff,0x00000000000a33f1}}, +}, +{/* digit=78 [{1,2,3,..,}]*([2^312]*G) */ + {{0x000cb198f774dfa5,0x000dd1e347819af2,0x00020411ce747fbb,0x0005ccc28af85bb9,0x000b3ae9ba11fc18,0x000bdb313c923d78,0x000b877d494d7ea7,0x00000000000af8f8}, {0x0004fe8c8323652c,0x000bdc178ccc093c,0x00006a94572bacfb,0x00047cc80a50372b,0x0000e6f901976087,0x000c2f2168147aa9,0x000b514683d4c978,0x00000000000552f3}}, + {{0x000f8017d10c6b96,0x0002229d81537326,0x0007f1980aaaed23,0x000ce6e8783d1fe4,0x000df0e3c126aa4a,0x000ca4b719c14ebd,0x000f350eb1c08d6e,0x000000000001c91d}, {0x00013bd5d85a7c75,0x00064db8119bb0fc,0x000fdf5036f03e4b,0x000916835436f82c,0x000b9b18d212053c,0x000bc3497eb41ccb,0x000d8193b3fb43b1,0x000000000008c1ce}}, + {{0x0007ad7a8ff88fe5,0x00031521f4af6aed,0x00033eaf4c7af196,0x0009ab7ae0377807,0x000db65f73ffad09,0x0006059b9541cadc,0x000f8253430463a8,0x00000000000043e9}, {0x00061f938516beb2,0x0001bd515f4c75f1,0x000d0a9d767932f1,0x00053567ef1b9007,0x000f1295b5fe7bed,0x0009176278782b45,0x000d9fab54ebaa03,0x000000000008787e}}, + {{0x0006f626b572390e,0x000905255508b5c5,0x000fa6a60258070c,0x0005eea3095205c4,0x00002c470ef7d976,0x00040bf0afea2ed7,0x000a16f5e8a0fc9c,0x00000000000e4137}, {0x00055209e40da33c,0x00003b917537047e,0x00003ab2893cdb40,0x000bce9023854871,0x0008a8bc3a94bea6,0x000c450444620840,0x00015164a87a2a3a,0x000000000007df70}}, + {{0x000cf2f10b0520cd,0x00004c38d07270c5,0x000e4dc64fc6cd1a,0x0001d8f300e953df,0x00040a7dce63abde,0x000425847b98b23d,0x00061b63e51543fc,0x0000000000043a21}, {0x000d54e8ecf42bd9,0x000ee2650a1d5920,0x00086c043a07e5a3,0x000b7048bd9bd78b,0x000df89e86bdc15d,0x000579426bad1dba,0x0005f8d7d4845024,0x00000000000287bf}}, + {{0x0006ca98107f85ef,0x000615fb05303f18,0x00091aa7ab0bf32f,0x0000fa47d92132d0,0x0008994564bf7a0a,0x00029e066e993faf,0x000574bf30252517,0x00000000000d4260}, {0x000990cf5caa4f19,0x00009f1eecc3d948,0x000f8dbc962efd6e,0x0001cf1d1dd88736,0x0003b6f1aae115fd,0x0009344b97ce882a,0x0009ca7efb7ec6da,0x00000000000cc5b5}}, + {{0x0003c28364de2038,0x000c48bcbf6cdce6,0x000e355114722287,0x000febf92ebe1bcf,0x00019af24c2e4ee8,0x000a861d57847829,0x0007ec618760b094,0x000000000006bae2}, {0x000de113e64c1ae9,0x000fc77c174b9e18,0x00055d1ba670f4b5,0x0004f6a58a0062c2,0x00047781acd1db9e,0x0006d86b03480c9b,0x000ef52d7c628ef5,0x00000000000b3e2e}}, + {{0x000ade0c1eab3d7e,0x0000fee9e25d91a6,0x00060f30210199eb,0x0001157d2d91300a,0x000fffcbe50fd2fc,0x0001d376ee7597e2,0x0005624be3814fe1,0x00000000000dbf14}, {0x000860a341c4b797,0x0005638a107c07ee,0x00045c1dbdbe39f3,0x0004e09caebd481c,0x000bf9ace60d1801,0x0001cb8e7b28c331,0x00065ee8fba04f21,0x00000000000e42dc}}, +}, +{/* digit=79 [{1,2,3,..,}]*([2^316]*G) */ + {{0x00060f98795275e8,0x0009d009dc2f44a9,0x000392d1d1132d95,0x000faa2ec5d91fec,0x0000f160afcbc89b,0x0007566b5461be9a,0x0009a2fdd084bb7d,0x00000000000e4809}, {0x000f69da99c8ac01,0x000bd1b461fc964c,0x00012ac0cf0d2b27,0x000332d9f09a206f,0x00036941d6ef3246,0x00087f5f6bde4c0c,0x00040044ef03fdf3,0x0000000000057b63}}, + {{0x000b480bf51dac8f,0x000ea7e485158a07,0x0002c9e9ee8b46dc,0x0000dafa6fbabfcb,0x00038f09fff720de,0x00006994f04f0158,0x000d335a0562976a,0x000000000006e3cc}, {0x000d89d62ca77de2,0x00045c087ef9c0e4,0x000f0235509703e4,0x0004814d916ee937,0x0008d23d140b4fc0,0x00062028f3369c97,0x000adbb0fcd70f16,0x00000000000e1e28}}, + {{0x0003a6684cfed7ee,0x00094e3ccfe8dea6,0x000d721274c869f9,0x000e2cbb605c4274,0x0005b0d809923f13,0x0009913815ee1239,0x000b6e4dcaea94b9,0x000000000008c4c4}, {0x000ec88cc6307d53,0x0004bd7aad54ab94,0x000859bdd379b119,0x0001eee68048fd9e,0x000fd57225fc6eb3,0x0008dfd3f693842d,0x000cf13e62cd85a8,0x00000000000d5462}}, + {{0x000df1c3e7de2ba1,0x000ff99b5f14f615,0x000c00e1f8e35232,0x0003900ff19bf251,0x0000260925ede749,0x000ea1eafc82e5b8,0x00021e3398d340c0,0x0000000000012871}, {0x000896ddafdbd954,0x00046ea6dfb0ad7a,0x00039aa9f60646cc,0x00078bf1201299a2,0x000d32e5cebce266,0x000181e32b5369e4,0x000add2304eac86d,0x000000000003d364}}, + {{0x000f357cfbf02e91,0x000a2f55f868d743,0x000049d92d19de08,0x000ff9bbb5ba194e,0x000957724703bec0,0x000e0e4fbf7325c4,0x000d7c5ab8f06323,0x00000000000ecb0f}, {0x000a0f97049bea9a,0x00069cc72e8da9e4,0x000c7a0fc237673e,0x00046e64252763c4,0x000eb8d81de3bfa6,0x000772f007a769ef,0x000a5ef5ec70031e,0x000000000002729a}}, + {{0x000cc742f063ab99,0x0003b51f19bb30d3,0x000878f139d45b8c,0x000de2f987112cb9,0x0008759de2cb5f7c,0x00049bd98dc51d94,0x0001fd9d05c410ed,0x0000000000036434}, {0x00020d69ae77fca8,0x000a9d7869d68233,0x00007a8daf0bfe29,0x0008180c25910747,0x000a6ebc4ebc7f25,0x000da1d687b90fc7,0x0004935565390f3d,0x00000000000a44e4}}, + {{0x000116432be8131b,0x000ebb4a2742da3f,0x0008bb7a8fda7aaf,0x000adccdd7fcf4fc,0x000337d4fcc6b15f,0x0001c7ab70b1fa2b,0x000cc9242c7b26f0,0x0000000000050574}, {0x000069eaa2593652,0x000b76ee50f421b3,0x000a5035e1a2b7ad,0x0003af18420501c6,0x000b1b6e7d2a04d1,0x000516f80c22e092,0x0005b5a393be7ee9,0x00000000000b80bb}}, + {{0x0003f2ad59508de2,0x000bd9e41b9b6b62,0x0006d3eb906556a9,0x0000c8cf272346c8,0x0005def5749367e5,0x0002676fcc98a5ef,0x000659c2dea8afa0,0x000000000006ace4}, {0x000f1f5cd12db7d7,0x00090c2b707aa093,0x000d4cda421d1577,0x0000fa2a778c20c3,0x000d57af166b5b58,0x00078ce62272c3a1,0x000087e47a64a9ca,0x0000000000071d35}}, +}, +{/* digit=80 [{1,2,3,..,}]*([2^320]*G) */ + {{0x000e3ee1ae74a706,0x00069c20fb9106bc,0x0005cf0e923045cf,0x000bc6a5cc0aa89b,0x000b4fb9f01e12bc,0x000ae1b895279c6a,0x00003cbc8e178911,0x00000000000c2900}, {0x0006736dff18cbd8,0x000579949d6eb7ac,0x000931ae3b95e19f,0x0006ee2dd2275c0b,0x0008c419f1d568de,0x0002b5a40a9e4fff,0x00096dbc759ca4a5,0x0000000000063b09}}, + {{0x000eafd50b503ff0,0x00058f682715078f,0x000b7ec2b450662f,0x0008f55c51916c40,0x000b61ee081fa46c,0x00064872a98c3524,0x000faa5ab7f2c2ad,0x000000000007e555}, {0x000425ebf2c1673e,0x0003c802e0d22c20,0x0004e9f77f229a7f,0x00019087af20d270,0x00016be50784b56d,0x00072b8518d619e2,0x00076e10fdbb7213,0x0000000000049355}}, + {{0x000df2627e9f5583,0x000e073c57fde593,0x000f9da9fd5339d4,0x00071f1cfb9821f2,0x0009cf6a1d68d25c,0x000d24e649427e20,0x0008b5bf3c3916ac,0x00000000000bda7b}, {0x0001a88dfb057584,0x000e2e7c5f7c7d49,0x00071c4b5c378478,0x000c472e66b277de,0x0007b2816f1e818d,0x000383c6d4413fd4,0x00053740f262af48,0x000000000004f190}}, + {{0x000aa901e2868cf5,0x00009d97a9b136f1,0x000f9d37eb7a3b6c,0x00060c2548188194,0x00061d59be44c571,0x000f2b2474dbdeab,0x000b33b93a9dad81,0x00000000000ecbca}, {0x000a766b5fedf0a6,0x000ce5e1ce82823b,0x000997bad589b344,0x000273a2d82b0df8,0x0006ac8ff52fe716,0x000ea7ccdb017f5f,0x00074b7563e79970,0x000000000003f0e6}}, + {{0x000fda8d824654de,0x00033487edc06864,0x00024946c59b50d3,0x0002bea10fdba0ce,0x00052c3dbf337fc6,0x0007d2a46c836bbc,0x000f714fdfb5c34f,0x00000000000dca0d}, {0x00024bebc7614440,0x0007730a0767544c,0x00067fffd43f5d03,0x000d49dfacc13dc4,0x000aae1a261ad307,0x000d98650148d673,0x000fdee008f95b52,0x000000000009f558}}, + {{0x000015df21e067c3,0x0003dd084564b8db,0x000d0b4c4a73b501,0x0004bf63bc7206d7,0x000ffc3d577224bd,0x000c4924fdd37b4e,0x00096e8156d6f635,0x000000000001d1d3}, {0x000ca9d7511fd3e1,0x0009d977b3b3982e,0x000fc4c09646cd37,0x000f9c4ae811d70c,0x000ca06c7f0de581,0x00049d87fe5441d5,0x0009bb0275c92b19,0x0000000000078046}}, + {{0x000cdb7d87948ad3,0x0009117cd6af6151,0x000e60b294f18979,0x0005b1d788224330,0x00031b9745257e49,0x000f3ce21fed338e,0x000896527743d386,0x00000000000b515c}, {0x000e2d7dc921023b,0x000d19fde7038e85,0x000c1b9c9ba2d99f,0x000600b36ff74dd6,0x00048302c3c95d46,0x00044b5eb8ea74b0,0x000402d560f570f7,0x00000000000fe762}}, + {{0x000cf97b63daba80,0x000eea7f8501424f,0x000f397f945052f2,0x0006b8a2ad5053d9,0x0003fbcebe43c658,0x000054f1688c09a4,0x00047fde7f2a4a20,0x00000000000bbbb1}, {0x00041659e06114fc,0x00075087e48f29cd,0x0009df479d6378c0,0x00002ff7f27cac87,0x000c37b1f6e18ae8,0x0006d1deab01a131,0x000f803f0d4c2e9a,0x00000000000e7cee}}, +}, +{/* digit=81 [{1,2,3,..,}]*([2^324]*G) */ + {{0x000643c3f46ade04,0x0007aaa03b473d97,0x00091126d04a500a,0x000ef86f37b57bd6,0x000b2a6371d2b286,0x00077ccbd95b797e,0x000a6da489ef8940,0x000000000008e99c}, {0x0007980fdcec94f4,0x000845cf9e236463,0x0000b4681fa85d18,0x00023b6ba7ba4781,0x000757de30bf3295,0x00036ca01d406ab8,0x000ac5aa10e4a215,0x00000000000dfa7a}}, + {{0x000146df48d94f2a,0x000a9762a5eebd68,0x000728ae94bf3482,0x00034aeaa4f964b4,0x000ed6526f010fd5,0x000d71d72cf46648,0x0008eabc62a54a18,0x000000000004f848}, {0x000d9dd392598cb3,0x000a262c40de70e6,0x00099451ce04b75f,0x000d7466ab190976,0x000b2dd1ad3d3a51,0x000f88078f07bea4,0x00035d2a0ec4672e,0x00000000000664e4}}, + {{0x0002f7cfce391389,0x000d017c563bd4e7,0x0006d61076868226,0x00049ac4cd1bfc15,0x0000d4e53d3b591d,0x000079a6ed446551,0x000eb4ca95ccf6ad,0x00000000000b5ea6}, {0x00099522fba1cf25,0x000cd600ccc9ba8e,0x000c729701bdaf25,0x000edc569c6c6e81,0x000a586abcdc5f27,0x000dbc5b6b3fc0f4,0x000fe0dbfdf3f985,0x000000000004ea80}}, + {{0x000e7847d76787ae,0x00083ee6e7005dda,0x000646f5e7ea8d16,0x000df7dfc45111c8,0x0001875c23c8373a,0x000039d490c7535b,0x000a062a7e04f897,0x000000000009afd1}, {0x000cbb06099a2183,0x000fb049dd385881,0x0008a6ac539cc7cc,0x00057b9925498c29,0x0002da25daa3dce0,0x000decb7d7b9c9bd,0x0006ef6d0b70a3d4,0x0000000000003df7}}, + {{0x000405f3ffe95388,0x0004eff54e8bb8ae,0x000ad0d572466c0c,0x0005bc4ed1fae2ed,0x0009ea983db1b226,0x000851454a5e23c2,0x0005064af5f55909,0x0000000000036eb4}, {0x00062710e23e547f,0x000844c72b2d0dfe,0x0003b7abb313e4c9,0x0008ad4e19c9c269,0x00053e8b8004b1aa,0x000c747fdb9cfea9,0x000e4107782d788a,0x00000000000ce9d9}}, + {{0x000aeca3f9d9a2f2,0x000f8779905b5deb,0x00064a28a88ba6a4,0x000f0aa679096dc3,0x0000f558913cce9a,0x00024a2e2fdf04f1,0x000b3505300cb06f,0x000000000005d581}, {0x000679a2a74abdaf,0x000aa855c8de8c32,0x0000f6e26bb556cb,0x0002a4197740d667,0x000744c9360d6761,0x0005cc8807588a52,0x000188928ac91032,0x00000000000acdd3}}, + {{0x000ac6fa45a00390,0x000933774af3674c,0x000bcfd34179ae6d,0x000205ec11875399,0x00018799c22ede45,0x000b0842ef3b1144,0x000d64fd53f681e8,0x0000000000066d36}, {0x0007de25fd86d3c2,0x0009ca2c3391c37b,0x000760d08855c7c1,0x000fa4a6ab8ab4bf,0x000bd841a6234df1,0x0000b189a2b0cd34,0x000da752441d79b1,0x00000000000fa025}}, + {{0x0009e3af5a1f4313,0x0000c3c6c56185fb,0x00083406c1a4afdd,0x0009c90ae2fb830d,0x0003ec31a504b325,0x0006230bdf7cc6e4,0x000e3a83bb13c612,0x00000000000ff1da}, {0x000c261cfaa4903f,0x000010cc6c1a44f0,0x00029f13aa21ef15,0x000c75fe604a58e6,0x00012491f872d454,0x000e116a5ceadfd9,0x0004816c5575da9c,0x00000000000b24a4}}, +}, +{/* digit=82 [{1,2,3,..,}]*([2^328]*G) */ + {{0x00087efd2e620105,0x00045c5ad791e85f,0x000885fe6de88f7b,0x0009e4998544bc47,0x0005d273c360673b,0x000a75a8c934d8f5,0x000c977fb48d0768,0x000000000005e0fa}, {0x000ee7923fcfedee,0x0000dbe01655fb13,0x0001ed409cde6661,0x00030de533251391,0x0001de9f3fc574f8,0x000e01fa5a724033,0x0004b496b25206a7,0x0000000000007eda}}, + {{0x000a5e409b41a55f,0x000283e6e9380f21,0x000bd6398225ced2,0x000c8b4b843ec071,0x0002af8a23f1f2d7,0x0007923350055d88,0x000e74e848010ed3,0x0000000000055e08}, {0x000839aa213ff6af,0x0003d956ea8e93ca,0x000299a04653a35e,0x0009271cca1b5491,0x0001f1d0b7f15f7b,0x0009963fbd41d228,0x000cd8b187047b5c,0x0000000000002536}}, + {{0x000a16fe10008718,0x000fd7138a03f4b5,0x0008b9afc3d67514,0x00041fd2a7cbcc17,0x0005f6073ecba29c,0x00004fa086014349,0x00053298b46d3805,0x00000000000401f9}, {0x000b314f178aa1e6,0x0009808cc4abc63d,0x0005190f1545e910,0x000c8faa75d9af1b,0x000fc2e5592d6eb2,0x000468e666f50198,0x000fc3773b9d55c0,0x000000000001a2a9}}, + {{0x0004cdf21adad97a,0x00008e51a956ff23,0x0002a26288680976,0x0000fa2f974d2cb8,0x00074c6a78dec616,0x000c89d11e00474f,0x000133ee916e510a,0x00000000000f826f}, {0x0002a0e3be0ad710,0x000103fc65d3ecf2,0x00089ef785c9b19a,0x000a82e0b9196b29,0x0000a572b6f55237,0x000bed2bc4975e68,0x00025e41ea8b92b9,0x0000000000098268}}, + {{0x000bc901bf39d0d3,0x000fae352fb9c164,0x0000b33959aa5988,0x000ce6fafcb7de1c,0x0004f694cad0f9ff,0x00061d6110e574cf,0x0005d8adb4671cb7,0x00000000000c8aa0}, {0x000b2a78a9127846,0x000a987cd7872df6,0x00010a813ed5d7a6,0x000531ec2cb43e23,0x0004b9e6b89f1c41,0x000e5d4d262fc310,0x0001dd7f406a0dc4,0x00000000000df3f6}}, + {{0x0005300bc3a99814,0x0008c06f721d246f,0x0003df2a36c6f8d6,0x0006b7a5a44ffdab,0x000915764390c5ca,0x000747d7dc53e328,0x0001227f16917459,0x0000000000061f79}, {0x000965ef8eb0e108,0x000ae099f4e3a08f,0x0009b651d265b539,0x00043576b72f3285,0x000cc33695bd270a,0x0002249029d6bb26,0x00051f60f9202126,0x00000000000e1b0a}}, + {{0x000bf8353cd33783,0x00086265d4eff002,0x00010092c6e845e0,0x0005c996be6ce254,0x00096b6056eec399,0x000a007266fd43e5,0x000fb1d328c28f28,0x00000000000f719a}, {0x000f1e2a3462b4c4,0x000fb75dcabd2f96,0x0006c939c482a7c5,0x000a522d764ab7e8,0x000dcf8a487267c6,0x000810a449458c96,0x000786af1af61b78,0x0000000000073902}}, + {{0x000b7c441c7f3df5,0x000a88a390dca834,0x0004f92ea9440c60,0x000ea69bc5e82f15,0x000d4628d6f177bb,0x00068e24071f02e2,0x0000ee6260790cf9,0x0000000000066527}, {0x0001df8e5c25d23a,0x000f233639544be6,0x000c37cf5bac2371,0x0000f867807ed557,0x00019dfa452c6906,0x000d27c0d1b0ac01,0x00090cbbdb25fe06,0x00000000000a60ef}}, +}, +{/* digit=83 [{1,2,3,..,}]*([2^332]*G) */ + {{0x000957058557b81a,0x000dc1877dfd042b,0x000fe0adb79e32df,0x0009536c78e295f6,0x000374a04cc59d08,0x0007f75edcbb5d55,0x00078ce366600682,0x0000000000061e73}, {0x000dd46741146ae1,0x0000a74170170ac0,0x00052de550198353,0x00030f8ac1c4a0fc,0x000d3cd92824d75a,0x0005e86d4d7e7be0,0x0005ef5ea0abdb1b,0x00000000000b3b61}}, + {{0x0003f4e13d621f8b,0x0005a618ca06b4bf,0x0002813dfa928efe,0x00072cca3b6ce7e1,0x000e5f14bb579813,0x00073abbbb44a68e,0x000c0afc1167e963,0x00000000000767d4}, {0x000277deb88a4f9a,0x00077c6dcdfeb3e6,0x000664e1fd3b5c4b,0x00001aabfcbf2f89,0x000a67aa82774775,0x000aab9cd0be7228,0x000b4a5de7b8331d,0x00000000000262fe}}, + {{0x000cce85ebd04b7f,0x0007f7a9623b5682,0x000f8d813f260bd0,0x000dec9e0f8e530f,0x00091d65dcd4f8a5,0x00039541c88bcbe2,0x00097a09fe380367,0x00000000000e716a}, {0x000184fc8c1d72cf,0x0003bbd8e34de924,0x000a19b51363e270,0x000d905351941206,0x0006f7a3c4830183,0x0003557396345099,0x0002f718283cea01,0x000000000009aaa7}}, + {{0x000a56eb624d0cf2,0x0006a7b7da0287f4,0x00087c61d1ede60c,0x000d83c51f3dbd9c,0x000fa91d085ac056,0x00035262de2f4d46,0x00029e31759c9ceb,0x000000000000c9dd}, {0x0009a41b82bb0c12,0x000e8108cf9ba936,0x0004fc5060b7103d,0x00016b273d372b32,0x0007d5415e53f698,0x0006b8b0e126575a,0x000a5e546bb4c130,0x000000000004d54e}}, + {{0x0002c932a7c5abec,0x000a881dd074d9bd,0x000f76c734b204ea,0x000e1f0352b58f62,0x00029c390eefb5af,0x0006a8d236d2d948,0x000be5d073f9a0f3,0x00000000000466eb}, {0x000118cb3dd8d87a,0x0004d968c04a5c76,0x00007c8586d1cdac,0x00096bb15c0970b9,0x000370ab8dda98e1,0x000039fa92af28ea,0x000ff6b912fbda7a,0x00000000000cbd02}}, + {{0x000e45ea08b7c4d8,0x0001d5bcf28785c2,0x000fc63d7c5e8cf8,0x0005de6707a7138f,0x000cfb2041a48868,0x000db3060a77646d,0x0006908608695289,0x00000000000e27a1}, {0x0000f0b051870cd1,0x000794148d936eb2,0x000a4e50dd50fda5,0x0002d4db0391d14a,0x000462b0373f9d72,0x000a9992c5683112,0x000b8487b0363be9,0x000000000008853d}}, + {{0x0002c578f8f683b4,0x000576c8e5a2524a,0x0007522f4370ef9a,0x0004aad50ad6f3a6,0x00051f107e269b01,0x00051bf732a3933c,0x0006df4b04395cc9,0x00000000000b0ef5}, {0x00017d2e75e44b21,0x000cd28c9fcdca32,0x00061a5012b72649,0x000f58e53ace23e2,0x000efe688f02b546,0x00091406dee5fec4,0x0004d9d8b43f6d2e,0x0000000000026176}}, + {{0x0002d2ad73a4790a,0x00034daa7fcc985a,0x0000276056234a54,0x00018c59894edceb,0x000da9ac29a7fbf9,0x000372f2c470c45e,0x000d3fdfd44f6fbc,0x00000000000a1e38}, {0x00009dd8fe96aa5f,0x0003923d2400aaad,0x000c441c1c12013d,0x000488148baa4ac3,0x000ebc26e6b0c76a,0x000ef566273227e4,0x0002bbe732edcfe8,0x000000000000c566}}, +}, +{/* digit=84 [{1,2,3,..,}]*([2^336]*G) */ + {{0x000d5d97020dd4a2,0x0005087c7dd7d118,0x000d6556f04f9110,0x00048789fff00158,0x000b909eaf1abcbc,0x000443a788ffcef8,0x000fed9905f4eef1,0x00000000000e15cb}, {0x000831894b4ea50c,0x0006cca2969ec57b,0x000ae2b1ba048b54,0x000fab787ea6e3a2,0x000ff98c4fe567f7,0x0009cb91e0d0ee10,0x000ab4c646879ac1,0x000000000007d1d7}}, + {{0x00092725c84d0435,0x00013cfbcbc49b56,0x000166c387130162,0x000e05622322f91f,0x000a7662ae23735d,0x0002be7a6d2590bd,0x00017263d468fed8,0x00000000000695ea}, {0x0005986e2611645f,0x00050c50f4940fa9,0x0003729def8820a9,0x000cd041fd257785,0x00044a3d0808680c,0x000684cba25ddac4,0x00088841d8b738c4,0x0000000000053963}}, + {{0x0003a8028963f3e3,0x00076b05cb83426c,0x00074bc4cf79f053,0x000b5aaefa9e4f0b,0x000d9bd075ecf023,0x000a41bfbb8061e5,0x000d967d2ba50f1a,0x0000000000090865}, {0x0004ae64b7cf3e16,0x000d97f221a788f4,0x00000b032e3ccff2,0x000eb6af6ab15418,0x0004dc87cd93085f,0x00039dbf6fd14102,0x0003643e196fdb32,0x00000000000dbcd5}}, + {{0x000d4ecde2fce0e7,0x000891466c9f4fd3,0x000b63a0ee692739,0x0008c75b58655519,0x0004e65862cc291e,0x0009971671ddb715,0x000c19285153bc2b,0x00000000000954b6}, {0x00039e1aad688b1d,0x000e0985d4505697,0x000559cd349baa64,0x00098dafa5fe5e6a,0x0006f90f231d39e0,0x000afd0b53fc2604,0x000c18de5d5ced32,0x0000000000060c09}}, + {{0x000b1d0586854e54,0x000cf3720b17188f,0x0005eebb9c78a9a7,0x0006e315b54eefca,0x000472b0edaa03c4,0x00077476e387e466,0x000259fc59b03dee,0x00000000000607a7}, {0x000e6b356394b5a7,0x0008b1478bceddaf,0x000e3cdb4ff0323d,0x0002f72cf272ee0a,0x00038bd885cd7127,0x0006ba31c19e3a4a,0x000b369af6415b37,0x00000000000807b2}}, + {{0x0008b39051ba2cdd,0x00030dbfcfa7593b,0x00015a46addd3783,0x000851d67a19b610,0x000431ae1a67cc6c,0x000d1e135ace88bf,0x00090a74554a6193,0x0000000000042118}, {0x000bd87496a1468e,0x000277cb3268907e,0x000047feb42207f2,0x0002c21766e72f3c,0x000a880642e30a67,0x0004d2b3624bb718,0x0004ab425dc41d18,0x0000000000089102}}, + {{0x000caa1ac9c2c636,0x000673180789b5d1,0x000d386a756090c3,0x000b895e99e922ea,0x00003d0bbe807951,0x000fe79c0987ea25,0x000d2a6d2f49f0e2,0x00000000000c2b18}, {0x000ed8226be989ea,0x000d8707798f36cd,0x000ebf8dc541b02a,0x0001e32bc4479412,0x000938a845f346cf,0x0005e5d924dfc145,0x000c3f210083fe45,0x00000000000a1fed}}, + {{0x000faea0d2bc54ec,0x000a972fc8198080,0x00029736c6c3c3d0,0x00098bbd99e30373,0x000a0efddfca3691,0x0009147416b68390,0x0008078c35f3e4f0,0x00000000000ca7d7}, {0x0005a76575b0ee6c,0x000e9564d991dc4d,0x0003cf033490be81,0x0000dab5d635893d,0x0006f944e49a51f3,0x000233bc00427e34,0x00093e1e0bf1b56a,0x00000000000617bf}}, +}, +{/* digit=85 [{1,2,3,..,}]*([2^340]*G) */ + {{0x000129009060318c,0x00056d23658c8428,0x0004596f83a71a5a,0x00010ec082210f1b,0x0001bfc364906dab,0x0004f2d14fb1add9,0x000443eda8b02f9a,0x0000000000056560}, {0x0004169ffc0d0413,0x000986c01479d686,0x000d5173dbdf44ef,0x0003c1d718883983,0x000e13c34fd24dcf,0x0000c15ac87a9c04,0x0005d2fe0e08ec51,0x00000000000c0f49}}, + {{0x00099e97b82e73d1,0x0005db097b2c50cb,0x00071fe923d57f3e,0x00066e9420996453,0x000eff7290736382,0x0008c394043d059d,0x000925eebb5fe114,0x00000000000daa8e}, {0x000995963e49eb67,0x00007f43c78d7e6f,0x000a34a7c03b2d6b,0x000a7d66b6363576,0x000be096a954cdd5,0x000afa2fc8b70a2e,0x00095a011d5419d0,0x0000000000004fb0}}, + {{0x00033bb61172fb0c,0x00008eb05c51603f,0x0000d435c61a818f,0x00073cd489576f54,0x0000535a8d57cfd5,0x0001436c4e653538,0x00022d1394731467,0x000000000005f0a1}, {0x0007992fb047bfc7,0x00099aecc7ec110e,0x000e8ab91f3e896f,0x000f6523d4221aba,0x000f2851996bdf96,0x000cfb67efef5649,0x00005246fb9f26d5,0x00000000000ef5c4}}, + {{0x00016ebee78befa2,0x0003188e7ac8d2f0,0x000b37c50c491499,0x000d52918be419b3,0x0004c057621c3b96,0x000e57e597e75e35,0x000463cb1b709f5c,0x00000000000844f2}, {0x00053157dde1a349,0x0006d53608198549,0x0000450e27f360c3,0x000d348e04114157,0x00004d73eeae6dd0,0x0000ed85e5b28e95,0x000b580843923269,0x000000000006da14}}, + {{0x000ce0f0a89b6284,0x000735cbdc4424ba,0x0003b0cbdca1bfb5,0x0006886c118d02b1,0x000675aaf27658a2,0x0005f6ec187ff74e,0x000d32b133be95f6,0x000000000004b1b8}, {0x000fda7aaf38358a,0x0001bdd8a8ef25a8,0x000eba5b65bc2a4f,0x000a6db26623fb02,0x0000bae15453d525,0x000f89fc9f2368d4,0x000a3e55d6a84d84,0x0000000000086021}}, + {{0x0009f5565cd739fd,0x000f210520b26d6e,0x0004ac2940ef5ddb,0x0008ef88948f78bf,0x000550ad452e1246,0x000c4847040a9d27,0x000ace5e382347c1,0x0000000000033e73}, {0x000c8b4278956db1,0x000437d83d02e97a,0x000af99c625baa1b,0x000d448885679e6a,0x0005fc95919c6716,0x000c2194a0e12bdd,0x000d2d7da4420492,0x0000000000015ffc}}, + {{0x000c11f07976d090,0x00025bd048bdc85d,0x0003c8a142cbe0e8,0x000a758a985ac100,0x000cf2c7ace940aa,0x000ec347d6039bcd,0x000ab7712092cc6a,0x000000000006b5ac}, {0x0003db66ec59bab1,0x000551ebcf80c829,0x000fffebfb9d4dbf,0x0003d1ad0b610f09,0x000498c28ac73fdd,0x00059750fdd3f6f9,0x0001ac650b77943a,0x000000000002d399}}, + {{0x0001cfefd0dbceda,0x000826cbd2756691,0x000e925943cf3919,0x000aa0be4c58c7c2,0x000f0e488784177e,0x000916b0f603551e,0x0002e2c8eba131df,0x0000000000015973}, {0x00008eec1292bc0e,0x0000355acca849df,0x000e7c404ec832b8,0x0002c703bd3b202e,0x00056ddd8eba162a,0x000b1d93d4c5e5d2,0x000dcf66e7844a77,0x00000000000110b9}}, +}, +{/* digit=86 [{1,2,3,..,}]*([2^344]*G) */ + {{0x0003ab751954f075,0x000f91b66faabe09,0x0001714e51539902,0x000f3a0a675f7c8e,0x000f30313a711a82,0x000aea9e682884a2,0x00005d7ac5d7b058,0x00000000000cd5ff}, {0x000d5d715b7b74ff,0x000287c29638d05f,0x0006736db974b38e,0x0003c47a17ae3a7c,0x00077009e38ae85e,0x000f9c52e91b107c,0x0008a0f3b777d8f1,0x0000000000011b68}}, + {{0x00072d048b012b70,0x0009a4ae3d232353,0x000ebed55756fa98,0x000c769ec62fd6b0,0x000f62a4720cba73,0x000c1f491d586ba7,0x0005716497cd140c,0x000000000007b2ac}, {0x0007af894008277c,0x000b9a65eabb5e68,0x000cb737865439ae,0x0001b84231457d7c,0x0005901645c525b3,0x000f7b656cab62f7,0x00095c2377d74db2,0x000000000002d33c}}, + {{0x000e54e4ebfecf4f,0x000b310105dfc241,0x0000ded90576b5a5,0x00068324e80fc085,0x000287dc7da6122e,0x0004728cf3b26e76,0x0001297bc183de6d,0x000000000008bcdc}, {0x000bafda0190b71b,0x0005d8b995cec24c,0x00099629f2c641a0,0x0009e6b4da5b77d0,0x00096caf9161612e,0x000f45eb68ec048a,0x0000e9e3628ee2c7,0x00000000000d8565}}, + {{0x000dc37cf3c258c7,0x0005aaae2f447f93,0x000c6f7663c30e3d,0x000b2f482c1f372f,0x000d351a5f7f3262,0x0006c75a85521feb,0x000fb8f8ec919091,0x000000000002728d}, {0x000f483180d24d43,0x0005f5dd4ff4f0a1,0x0000b042bcddd9b8,0x0005b98ba8b777b7,0x0006fb7f8409318b,0x000fd31dbd971d42,0x000347ed1465e8b0,0x0000000000000f66}}, + {{0x000f5311360afd40,0x000bacea0374a33b,0x000feb5ded889fab,0x00002361bb01f474,0x000a8c328b8bf6ce,0x00053d6302a5b28b,0x0005d86991b1d8b2,0x0000000000085945}, {0x0008eeb3e3866a93,0x00024f5c6e141989,0x000231ed9c304f2e,0x000032f67e76ece0,0x0002338980594eb4,0x000001b765bf14aa,0x0001340804a7c00e,0x00000000000734cd}}, + {{0x00036d45a9f2195d,0x0007e5ba5288b70f,0x000e413923c56371,0x000a997602f3c65a,0x000fe08c0223c1a9,0x0007e6f1dc5c7512,0x00059748a19c3c36,0x00000000000fb241}, {0x0001d161a9f86145,0x000879f674a5f0bc,0x0001526754b42988,0x0008c4303d6f13ed,0x000d917433fb5aeb,0x000f534900fed575,0x000616e4a5ef9a59,0x00000000000f315e}}, + {{0x0008596b7b07e015,0x0009c7059c585ee9,0x000cfabffa6395f2,0x000d9318d9633cd0,0x000f37bda14896dc,0x0008964dcb2abc44,0x00076ce31adb3feb,0x00000000000e3168}, {0x000ed4ab82ecfd95,0x000363173288028b,0x000f24a3fd6c4552,0x00034c91d6f69add,0x00022c34e118b5b3,0x0005984ede613e56,0x0003a18bbdbf5c5f,0x00000000000cf4f6}}, + {{0x0008f4401a1165b4,0x000b4315ad7a4644,0x000672c1b06e4df0,0x00097a8baa564733,0x000446edcfcbe12f,0x0001a968ef263db4,0x00087547cf91d53c,0x00000000000c15db}, {0x0007f5c515f16ba5,0x000345d35e53a1e8,0x000a90f359724b01,0x00011ea246da3d37,0x000653f068205d3d,0x00010c00fc1ddfcc,0x0008c78169d71166,0x000000000004bddc}}, +}, +{/* digit=87 [{1,2,3,..,}]*([2^348]*G) */ + {{0x0005418902e018d8,0x000328002f4583b6,0x00029b160f5eca39,0x000d112fb93f735b,0x0002196e3084a8ce,0x000e8c74427cb629,0x0005ff72395bdd77,0x00000000000ee71f}, {0x00030cc165e06d5c,0x000ca7cfc14d95b5,0x000ac1b9673d9545,0x0000129d213738ef,0x0001bc0b5ea366e5,0x000a067007a905d9,0x00082192cb630afc,0x00000000000bf3a0}}, + {{0x0009c76f27cbedd6,0x00086e96c4aebbe2,0x00087447d6551831,0x000d2f632f9151d3,0x0004302b99e2f86a,0x000fd317105daf87,0x000c624299dbfa14,0x00000000000812cf}, {0x000ccd383b8a542c,0x0001b42e615367ce,0x000e792323a5de78,0x0006c70548fffa38,0x00077b6db825c34c,0x000f2989e1fbed77,0x0003ee850bded44e,0x0000000000081546}}, + {{0x0008bd3d7d2dac19,0x000ce352e14371a1,0x000574a96d5757aa,0x000d9395a7b7719e,0x000b8544328b64d5,0x000f9c5934d5197b,0x00045e5220626522,0x0000000000074d6a}, {0x000ed277c567a2e7,0x00003f52c9eeb86b,0x00037cef0ab9cbea,0x000b3bfc9ed39349,0x0007a14c3d70e606,0x000db5876fc5046d,0x0007a181cd053e5e,0x00000000000a3034}}, + {{0x00026a12e217941d,0x0008a9decf2164e6,0x000546598e5e9913,0x0009ce8aeb36b93a,0x000158fb4dc8d564,0x0002d60cfab9f77d,0x00061966b11fb6b5,0x00000000000eaaa4}, {0x00098700891e3d12,0x000dbf3522a998ce,0x00034cf7624bc215,0x00097c625e387237,0x00072d4595ee2679,0x000e5456ced5047b,0x0006feaaa41e5f55,0x0000000000078cfc}}, + {{0x000abf51b7538110,0x000353fd75579f7b,0x000019e5c13ce4a6,0x00076854d208bb77,0x000ac1c9512f4c82,0x00081e9f3941aeb9,0x0003396ce0bed5a1,0x000000000003744a}, {0x000bd7c923f4230a,0x0006180eaff7a041,0x000dbb73984381c7,0x0007c1b0f8e7fd8b,0x000aaf499630f16e,0x00080a16856bdddd,0x00012be8c112df11,0x000000000002987f}}, + {{0x000b02027989cfc0,0x000a60ce9ab12f61,0x000973d1a5ee6cd8,0x000b3b69a1753a9f,0x00002bae5685f031,0x000d3c06632160ba,0x000f5cdfde9ae80c,0x00000000000a180c}, {0x000f0a3aff152330,0x00023e2c194158b5,0x000e1481b10c0c49,0x000e7d12ea20322e,0x00007968c7ff67ea,0x00027bab93eb507b,0x0006eaeb300ff9ce,0x0000000000097575}}, + {{0x000b71b2ec924484,0x00007325de655ef5,0x00027d8f4ae5da5e,0x00026ad89e4c34bb,0x0000ec5a615fa909,0x000c770ac8e61adb,0x000f8a5a2233d43f,0x00000000000cbb23}, {0x0003b01804f61225,0x000a4a7e6c5861cf,0x0004fcae81492249,0x00040be697e7dc09,0x000eb6f29135b0f3,0x000e89899783a7d0,0x000f55412469b007,0x000000000001bfaa}}, + {{0x0003c3de6d71b673,0x000cca438634e69c,0x000f00cb40863203,0x000dedfac40dd56f,0x000e4956a5de2ab4,0x00013f84d758e95e,0x00016cfc11e39451,0x000000000006059f}, {0x0008f87a862c83c5,0x00038fd8e2236750,0x000df4ebd7b9092c,0x000b1538ea13b455,0x0003013d382702ae,0x0009ca201de1275d,0x000351470a7b7e65,0x000000000005c77b}}, +}, +{/* digit=88 [{1,2,3,..,}]*([2^352]*G) */ + {{0x000bd58c2fd385c4,0x000d8281f6e58982,0x000c3afee2ff7056,0x000a41afd89abd8e,0x00007984feefe29f,0x000d20a64fcb0b0b,0x000cd50b0928a6d9,0x000000000006979c}, {0x0008ab27cda5c7bd,0x0001cce9c34c7521,0x0006dc0b027875db,0x000635250946a5c3,0x0006f39f53b9d464,0x000bc8b64b09a97c,0x0000d61d47bc20dc,0x00000000000d458b}}, + {{0x0004b16a9cc79c48,0x00075763e36638c9,0x000ff772bf788245,0x00011a8c66b40e9f,0x0008f384b70862ab,0x0001978760624469,0x000837e7cdf3bd69,0x00000000000064f8}, {0x000fbc5f9be69c3f,0x0007895900a21f89,0x00053a9326cbd6b2,0x000fbbddd3e6e471,0x0006baa2e2a03f65,0x00085282484f52e0,0x00032c1dc462a8e3,0x000000000007e4c0}}, + {{0x0008c150b5ec2626,0x00094cc580ea6853,0x000526b13f535e43,0x000604fb23480cfc,0x000a344146898665,0x00010a94595787cb,0x000c78425d7c6f4d,0x00000000000b2f1c}, {0x000940b59f5f9db6,0x000f455da8884e6f,0x000468b788890b3d,0x00081d7d99e417f5,0x000abf28fba2c648,0x0004eff801eeba5a,0x000fb720feb7b350,0x0000000000050deb}}, + {{0x0002dafb4e000df5,0x0009720ebf79c9aa,0x000a041b02faa426,0x00007e78d630d2b3,0x0007fa605dcb016c,0x000d0470520021d5,0x0007e66190f3e942,0x000000000008974b}, {0x000bb7ed0e0135bf,0x0003b6710da6c4cb,0x00011bda556d9709,0x0004b8ba583089a0,0x0004ea7dbcdd192c,0x000df1097171ab8c,0x0000ed715f60818c,0x00000000000205d1}}, + {{0x000c0f09863d151a,0x0004b4a6226f970c,0x0004a88f8872d167,0x0002e60a1193cac8,0x000543dda270b44e,0x000d647382ce6393,0x0006751a9e8a2138,0x000000000009d843}, {0x000abb28a3b6891b,0x0008a98a1222e3ef,0x000341bb8ccbdd0d,0x0005be5555088026,0x00017b38f0648047,0x000e249f5c39ccd9,0x000b74ea31304de8,0x000000000004d42d}}, + {{0x000330dc4e7217de,0x0009c39a689bbd9a,0x00001ce7a86200c3,0x000108a8d29457b6,0x000014ed4b4dcf33,0x00015625f312612e,0x00063bcbb21f3451,0x00000000000303a3}, {0x0009f7756d9dff06,0x00004aeb0c8c0639,0x000d964999e9958d,0x0002604683b37dcb,0x0007862b08477a02,0x000d69390fa4ced7,0x0003145a49bdc136,0x00000000000c0215}}, + {{0x000155abc265f191,0x000f0544874b6521,0x0007a036ebfb6d29,0x000afd631411ba1e,0x0000466d6415b303,0x000d4c2de30047aa,0x0007b13a1b676594,0x000000000002860c}, {0x0008a20d9745d768,0x00046fe140a72d14,0x0007d03c948ac2bf,0x0006df9f46f144f8,0x000bc0defbc46c9f,0x00024c075f7e7b95,0x000c39fbc9a96978,0x00000000000d7773}}, + {{0x000f0ec4d363b0b7,0x000bdd2db4d34f56,0x0005740dc154bacd,0x00065cc723a57c02,0x0007d8ded62c4475,0x0002f1a9ed98c359,0x0003b20aeac6d9de,0x000000000000a98d}, {0x0004a99c9e88ef97,0x00034d9708f06642,0x0001bd570d037e70,0x00032cf49cda0113,0x000a858467e24993,0x000748e8e546df74,0x0000738b84a55093,0x0000000000006f09}}, +}, +{/* digit=89 [{1,2,3,..,}]*([2^356]*G) */ + {{0x000f37fe6b03f897,0x00052c0a40cabe70,0x00091f1b94fec55b,0x000898c340187426,0x000636d9e57a8625,0x0008aa21169c9f3f,0x00016869d9d7f337,0x00000000000e7dca}, {0x000214154225907a,0x000ba24d49aebb77,0x000fbddce2036f3c,0x0001d01576f533f5,0x00099ef82ece667c,0x00007c14d372eee1,0x0007f6577723c0c2,0x000000000000eed3}}, + {{0x000850ebff25b818,0x00013c61db976bce,0x000a1c9cf36381eb,0x000b8ca060b1adcb,0x000188e2c178ce89,0x0003bdd3c41db448,0x00042cba6339f392,0x00000000000d29db}, {0x000bbd1437baf649,0x000f53521116eaf1,0x0005d6c8cce9ea0c,0x000c984bd79fe5d8,0x000e9d45eee49357,0x00088e01f2eda73b,0x0008731a50c59f62,0x0000000000075018}}, + {{0x00038b1bc1ced6c1,0x0004df323953ab33,0x000a2512b2fa2401,0x000dfd9bd32cb8d7,0x00037ecf35382937,0x00039941507c4e56,0x000a06b573960eb6,0x00000000000dd1a4}, {0x000a33b92253abc1,0x00050c625f400562,0x000bec6e4c3f3a23,0x0001e5b6220f24df,0x000827d01c6f66c5,0x00012372d9f97d75,0x00004860b1572404,0x0000000000004d55}}, + {{0x000a3b570044f6d8,0x0005fc552c6c6093,0x000f9e99da8c0559,0x000375c19610b0cd,0x000bb051dad5c9ed,0x000556643f0e7b4e,0x0001d87267a304c6,0x00000000000c96dc}, {0x000cd649696f60dc,0x000dbf0ed5f9a8b8,0x00051f0009075842,0x00066f4af5a4b4c2,0x000d20644cf2ef5d,0x000ae23c00b5bed3,0x000b66f7e4543a75,0x0000000000041325}}, + {{0x0006798502ee1353,0x0006c04ef7ad5a7b,0x000c6878548d78d6,0x0008a6a47591d88b,0x00046902edb49ae3,0x0002b143a27d9125,0x000df65dae3d8381,0x0000000000093a2f}, {0x00091ef1ecb7e486,0x0000807a00388858,0x000fb3b7ca4398f1,0x000c17172b1bcba8,0x00032d0033c73fd6,0x00016c28aa8d70f9,0x000ad79ea9eea329,0x00000000000423ed}}, + {{0x000a6b031af68d65,0x000b59949b33d112,0x00063134f5d066ef,0x00071e788e17f2bf,0x0002da9c088188ce,0x000d8c9e9d851baf,0x0005b6e869c5ba86,0x00000000000a0142}, {0x0009ab9cc7c38dc7,0x000eceae8b1c5d3f,0x000b0c8e79b3cc01,0x0002910c374bb97b,0x0007054874831494,0x000bc6ee13e13c45,0x00047be0e6fad435,0x00000000000b54d2}}, + {{0x000e68e47f9ea217,0x0003c9c85e50a3a1,0x000b0543d8520966,0x000ce81807f33dba,0x000a3db81e06cb78,0x000638d709d337d8,0x000babe223eae472,0x000000000006bf2e}, {0x0006763908bcca20,0x000662804b59c92a,0x000900c614fc9957,0x000ca1e7bc6949c1,0x00008f051155321e,0x000539f40bf2906c,0x000808b802a3289c,0x00000000000073cd}}, + {{0x000fc3dc90267bca,0x000956d34bdf61b1,0x000bd7a38090ba35,0x00051135a3bfdd10,0x0005f1296bdd61d0,0x0002e9a7c4abab57,0x00003d72da68494d,0x000000000008d11f}, {0x000319b6e5281755,0x0002247811121597,0x000526a929004138,0x0003ec67521898f7,0x000996c1da75ec29,0x000f2c7b3f0cf026,0x000af8b0dbd4c380,0x0000000000034e4b}}, +}, +{/* digit=90 [{1,2,3,..,}]*([2^360]*G) */ + {{0x000c4e9ab57885e4,0x000f3c32730e8279,0x00033a83277668a3,0x000fdbf3f5cd8478,0x00067272d4dd2bac,0x000b7577645f3641,0x000be2dd813a795e,0x0000000000050997}, {0x0005df7d4526b8ac,0x00040da054e2b966,0x00068890ccefdc5e,0x0008f31026116a38,0x0000dcd85e914c42,0x0003adc2d372af9a,0x0009e6fda6e90367,0x00000000000a8db5}}, + {{0x00029349f348fe26,0x0004251a033a4db8,0x000e0f2d8a80c6e4,0x000ce49a42a266f1,0x000b82c4d11e92ee,0x000bae08a87e037d,0x00078c875be1416f,0x00000000000c5394}, {0x000064a55c345b79,0x0001651f8b907a36,0x0000a11c59759db6,0x000bd666c51b9c32,0x0004ee565de82c74,0x00082c8c3635d3d2,0x00093c6bd6566389,0x00000000000daf6a}}, + {{0x0007ac96ab52d7dc,0x000dd68fe359d36e,0x000f3dea99f83698,0x00052c3fc704935e,0x000952e4e22d0ec6,0x0003e3ada1eeff1f,0x000871ba6777cb08,0x000000000008befc}, {0x0007324fc4458b0a,0x000e34ede689e853,0x000cf3cdc3eb9d08,0x00080517ab83c288,0x00052c8c1f48e0f0,0x000241aac1f3d5f2,0x0007e057991607af,0x00000000000b8a33}}, + {{0x000ca2047d1f8f40,0x00004179c59cea3e,0x000880cb97b10e4b,0x0005cfdba0cf3857,0x000b3a8fbafadda7,0x000384e0b94081a5,0x000a45b91de90a33,0x0000000000027aa2}, {0x00058a31cd3d8717,0x000220747bcc094c,0x0000191551c0619d,0x000e3e9722484f1a,0x000da62d1dda9c1c,0x000963bce13a7ee5,0x00021b77fd79343a,0x0000000000083d2f}}, + {{0x0009d92935034280,0x0008b3dbb3fa61cd,0x000a3f5ecd8961d8,0x0006574793ce8041,0x000783dbce4f35ac,0x0003cf6b0b2697dc,0x000164e35c5bf2e1,0x00000000000b0c4a}, {0x0008df1996e7f4a8,0x00038aa49090842d,0x0003b655f6623523,0x000e96c54d504e4c,0x0001b73310a3f646,0x000bde5dad74e754,0x000ef7ead7159618,0x00000000000aa09a}}, + {{0x0005ac9c05f620d2,0x000df609deb16279,0x000a25447b2b8795,0x0003132b378305ce,0x000869275f5e4a9f,0x000b089b5f101799,0x0000c514be746761,0x000000000000c81b}, {0x000e2dd3d7fa135b,0x00030ca90a9bf94b,0x0006097de4edabc4,0x000ac9620c71989d,0x000a390aedd01b25,0x000d8cd39b971b61,0x00011a995214d779,0x0000000000065c6e}}, + {{0x0003855cea5ad9ec,0x000d4a8393a23731,0x0006e8588fe37236,0x0004e0255a202691,0x0002a446bcc6d882,0x00051499b9dd9a27,0x000535c929cded53,0x00000000000cfe76}, {0x000bc0f428a70f0d,0x0009626f3d7d9b38,0x000a6acd906c92a5,0x000cc06759e6ddb7,0x0004e302b89191fd,0x00007e1f7ac2e190,0x000b4aad25c645c2,0x00000000000ab3de}}, + {{0x000338669b2cb8c7,0x00071a13f19b3741,0x00031ac1789cc21d,0x0000c997044a6f4f,0x0008dca1075c00ec,0x00020ab0caf5665f,0x000effded5ca3f06,0x00000000000a896d}, {0x000378285debab1d,0x000a5032ab2b2a9f,0x000438bbbc4fc5ea,0x000b6f725133304f,0x0001977a45672286,0x000abae4f0d16d53,0x00003b00a66036f1,0x0000000000095f01}}, +}, +{/* digit=91 [{1,2,3,..,}]*([2^364]*G) */ + {{0x000925dc8a89e47c,0x00066f2cdae310b9,0x0002591b317d8ec6,0x000f25ad750b29bd,0x0005dba15f3e9d14,0x0009fe2dd931b9c6,0x00043334db169ebf,0x0000000000052663}, {0x000c577396a26bac,0x000968859a4f76bc,0x0005596f973fb63a,0x0008d6a67ac4db88,0x0002be25d7557463,0x000db10ee5c8ea7b,0x000cd38a0f0a8738,0x00000000000e890b}}, + {{0x000bf56a7de9f2ff,0x00022883533aee6b,0x0008916bc1e75ddf,0x0005fb546d0fcf42,0x000a4ab05da78f0b,0x0007b66147e6b0a0,0x000cf2cd91a869c6,0x000000000006c6f7}, {0x000593da575680e9,0x000d7c072a1067a9,0x0006a216ef99f7a9,0x000192c8f0ce9469,0x000fd11494417378,0x000ccf45adf2e7b9,0x0005684fa17cb614,0x0000000000045f03}}, + {{0x000725d8721dd338,0x000930f4ca77fc15,0x000b6681d170fa2e,0x000625b4ef805afc,0x000fc015c5864873,0x0001a8c93bddba22,0x000f427091b50aa4,0x000000000004c005}, {0x00044f31df11a4ec,0x0009ff43d3745415,0x00007d532af636b7,0x000a10c82770690b,0x000b77513f003efc,0x000c3af9bd0c25d7,0x000adac0015cc12d,0x0000000000094c6c}}, + {{0x000e8ca221c6ffc6,0x0008d8b70e94f6d7,0x000aee261a6327ec,0x00019ba4d3ef22f4,0x000a1999f948e222,0x000fe73027f8a712,0x000af025575e96ab,0x00000000000564a1}, {0x000b25cff3d9db0b,0x000b1045e9c658aa,0x0003561802f8c969,0x000b825c3db161be,0x000aba33a906dd23,0x0000e41f205fb173,0x000d1d9a8b5ecb87,0x00000000000ccc30}}, + {{0x0002aea737bc7de5,0x000c2bed7d94c6a0,0x00033bc161f07397,0x0006af6106834bff,0x00044c4f74486541,0x0001dfc06dade8a1,0x0007bc62227a1d88,0x000000000008dc2b}, {0x000d41c50320c146,0x0001c4f1154170fa,0x0005645ed0c5caa2,0x00053aba0f1b9617,0x000d48b0ec8e98cc,0x00072d0342f68011,0x000e384bbc34679c,0x000000000009c576}}, + {{0x000919b377dae55c,0x000a5d9243926709,0x000605401369e5f3,0x000feee0e35f201a,0x0003196f23f3a1bc,0x000c1d068d25be5f,0x00050b298c67f2ff,0x000000000000c3d9}, {0x000d303412559962,0x000fa5e15ab9975c,0x000533c7cf964ba3,0x0002ec947a7e2696,0x00022ac22e49a9f8,0x00006f090f02af9a,0x000cb0dfb3103fa7,0x000000000003cf8d}}, + {{0x000298e2791b8ead,0x000259f5f44f9ed5,0x000ce416b16e73bb,0x000f258f9627f9cc,0x000938fd51bdd7e8,0x0006a4a7922499dc,0x000250a9d7497c84,0x00000000000026ae}, {0x000e3b88b9c7c3db,0x0009084d47d19214,0x000f52469be04308,0x000138806a52e316,0x00027f08953f9b2f,0x000fcac083fc8da0,0x0003fc22d074d292,0x00000000000701d7}}, + {{0x000b913b1d418177,0x000cbb7b856256b6,0x000f3717023b8633,0x000ddd5c91b8ffd9,0x000155d38511b4eb,0x0000da525ef815ae,0x000bbd98587d551b,0x0000000000034a9e}, {0x0005ef8ce15a684b,0x000b8844811fa3d0,0x000d70ffbd583fff,0x0008bb4f623789be,0x000e404980584b26,0x0002b435ab26ae5b,0x000eb3b47a5ded3c,0x000000000008fcec}}, +}, +{/* digit=92 [{1,2,3,..,}]*([2^368]*G) */ + {{0x00069e40601a7dfa,0x000cb70765682efa,0x0003c3be2bc6c542,0x0005ef0a6db6169b,0x00012032d5992a93,0x0006f13160029276,0x000f51b5babb2d3a,0x00000000000db26a}, {0x00039e460e4f3b3d,0x0000200c3401304d,0x0003ff9e293a0443,0x000e2ed0f9b36565,0x000934031d18a1bb,0x000fe1224e17a5d4,0x000cf5e3661047f8,0x00000000000623c6}}, + {{0x000ad46943acea12,0x000a859367582797,0x00066c45ce5e5faf,0x000351af6a27741d,0x00087f929e0d5d96,0x0003f1afbeab94db,0x0001dd865ba01104,0x000000000005fb63}, {0x00040d1f1e090717,0x00038192e065294f,0x0002fb37089941d8,0x000228db7cae5f66,0x000d6a828b037bcc,0x000f301aa02eaecc,0x000a077c48a2ea91,0x00000000000f5eb1}}, + {{0x0000bb651b864105,0x000154dd3bd8408c,0x0001daf9340de0f6,0x0006998ba0668966,0x000cad713bbd1ad4,0x000ca4fa5b7c679a,0x000a1cef9389aff7,0x00000000000d68b6}, {0x0009051030865994,0x000093acfff601ae,0x000275b28bea6bfe,0x0006441c66ad734b,0x00042fd3eb165e2f,0x0004e211749f144c,0x0001a3bd7f22082e,0x0000000000041791}}, + {{0x0002b76266c69181,0x0004edf0ae8df2d5,0x000906801183c79d,0x00017ca1dd286917,0x0009709b678ede37,0x0000acdc60c1db87,0x00003a0288959a40,0x000000000005ca2d}, {0x000fd72975fb9eb5,0x00084e52534b365b,0x000f103241b3e4c6,0x00034f873eece315,0x000d642a67991a9a,0x000a7e8a80fb0c7b,0x000238375cc0cfea,0x00000000000d00ec}}, + {{0x0005a38c81bac32b,0x000bdb67d88fb498,0x000506df3f19aea7,0x000433ede7910791,0x000a20ec085cc26e,0x0000eefb30ed8fc0,0x0008c22684a901b3,0x00000000000e855e}, {0x0003801582a535c0,0x000a23d31d6c91c3,0x00014e8637446682,0x000380e755f1af17,0x000a6c985ecfd938,0x00065084e6a8e434,0x000ec653bec9c1cb,0x0000000000070309}}, + {{0x000a18c1c3a6f1f6,0x000f49a2461c2364,0x0005b210149e5bc7,0x000bfea0ae15fd0a,0x00027ac4d98f2265,0x000831902d817b35,0x0001fe9788aa4511,0x00000000000d4616}, {0x0004b65395df8642,0x0003d2a7cac2f471,0x0003af0e90c12844,0x00048d211070e2f3,0x000ab769926571a6,0x000aea1556050d8b,0x000411cf8f24a040,0x000000000003522b}}, + {{0x000a6d728de1a709,0x0002e45d4ed63b83,0x000803bc165cd24c,0x00029022b267f598,0x000fc8446afe76be,0x0004d6f50791c22a,0x00077ed6ce8b8859,0x00000000000e3f1f}, {0x0000a258fb32c514,0x0006d1a72b16f0c7,0x0009dc6ac4083dba,0x000743e1cad2e785,0x00041e0e640d6a1c,0x00074648529ff0a5,0x0001fb4cd519be4b,0x000000000004584f}}, + {{0x00051eecfb6439ff,0x000619ca8cc9cbbc,0x0007f10adb0b792f,0x0005d53059b2bbb3,0x0000730e5dc37211,0x0001d89988fe7ac3,0x0007a54e67ef6984,0x00000000000c8ed3}, {0x00004a045edf3ac0,0x0005e48164b3dc80,0x0006b3cd6d953b04,0x0004643beed38ce9,0x000fa3e30b3db7fd,0x000ddd484993cfa9,0x00075ddcc5e7af01,0x0000000000068401}}, +}, +{/* digit=93 [{1,2,3,..,}]*([2^372]*G) */ + {{0x0007c9efed4b7222,0x000ab79768e9e648,0x000c0eb72891fdba,0x000821bbe0c67d8d,0x000a6909fdfcc194,0x000ccdda7537a6a4,0x00026cae6d705195,0x0000000000092b39}, {0x0004e2be194fc116,0x000ab2c5dd6af51d,0x000bd2ad4ffd8821,0x0007388397a3bd3a,0x000a8baf59c2dd3c,0x0000ec9589d176c6,0x000315d5c6219e38,0x0000000000054e8e}}, + {{0x00045f27ccc6232a,0x000560683349d797,0x0004a272721dca0a,0x000181050663b9f6,0x00099733dac647c7,0x0002137c5f327d14,0x0001c703f55e4a29,0x00000000000da59e}, {0x000b58d5c8ca43e3,0x000c7baa8b4dce4f,0x000e015119c73eca,0x0008c1db0322dfa0,0x0007fd69954f99a8,0x000a29889394440a,0x00064a9060473da5,0x000000000002f048}}, + {{0x000df3b38c2a0a79,0x0000190762c1ecbf,0x000c4019f47729e5,0x000849f5c47c645a,0x00056d72e7487420,0x000e11773b082319,0x00050eaeac683b8e,0x00000000000fb5c5}, {0x000722990680a985,0x0003e6d986d69658,0x000da73ac5c10442,0x000136fd94d52235,0x0009ed5b01c6d13e,0x0008fcdcc1aa7541,0x0005ee7c2014b140,0x00000000000cffde}}, + {{0x0009c28bf944531a,0x000bbc7d0abb1f4a,0x000c2054201bd117,0x000defca80767df6,0x000871820908eb67,0x00074d19a6fa174d,0x00081a3215df4856,0x00000000000960a0}, {0x000602066fc6cc5c,0x0006993ed71807f6,0x0002dfba1c3883c8,0x000d56efe787e592,0x00098fe8b96f0909,0x000ab68115ae74fc,0x000e0c8fc342c435,0x000000000000b991}}, + {{0x00047f2399bf97b6,0x00021c600dd569b8,0x000917d84fb94235,0x0000a27de43c1d70,0x000e616bdb162d7b,0x00029795321bf3a9,0x0008b233ce767c96,0x000000000009e439}, {0x000800714c3c1216,0x000934069cced410,0x000f1cffed0b3d13,0x000bf89c53942369,0x0009acb24e389981,0x000da473507d9c07,0x000cd9d2e5e904a2,0x000000000002f1b6}}, + {{0x000ee38595e6d6e3,0x0003bfeecc6e7a5f,0x00087ab2bdd62b28,0x0004e20e81879cac,0x00089c4a27124845,0x0000749c3d0ea9cb,0x000f93ba8b6f3354,0x00000000000e971d}, {0x0002b66fa9a77846,0x000b64c2a1b129de,0x0005071339da6099,0x0000b53435739873,0x000a57040c00e6c6,0x00091a7b4b9f56a6,0x0002466de6489f62,0x0000000000053bc3}}, + {{0x000554330abff5cf,0x000ae828a9dbe5c5,0x000263a5672326a0,0x000428089faa5816,0x00002dba2a1d1558,0x000197ae62da0922,0x000abba225f631df,0x000000000008f4eb}, {0x0005dcc2ee38818c,0x0001bbbadc9b2cb5,0x000ab544fb33427b,0x0006cc2759413f76,0x000121dd1222072a,0x000ac2c737b39ea4,0x000296d6baf9e196,0x0000000000075d46}}, + {{0x000b2448cce42a48,0x0001555671128874,0x0000a30717d307ff,0x000207ce99ca16c1,0x00057c7a26b97e21,0x000c3ab00785fa10,0x00059f33c28658c2,0x00000000000d79cd}, {0x0004e804722ed471,0x0006f9a674db4469,0x000c9ef186db33b8,0x000722166bf2c6d5,0x000abd4c3791990e,0x000696ee1ba29aff,0x0006a5d98510cf20,0x00000000000f93d2}}, +}, +{/* digit=94 [{1,2,3,..,}]*([2^376]*G) */ + {{0x000bbb4af21bdc49,0x00065e7cf5babca3,0x0003f75a29c95b64,0x000531d04fa84740,0x00045780efda9c1a,0x00062cb5a399e848,0x000f3b6e9c12be4f,0x0000000000094a5d}, {0x000aeeb34b3f3b9c,0x0006d3c15fe11c69,0x0009e05f576f256d,0x0006da4be294c912,0x000aa99b83983ef7,0x0001b9f6a5cf21d5,0x0007bf50679cf875,0x0000000000054d0b}}, + {{0x0009b2dd4ee443f9,0x000fcc84f9171b4d,0x000ea8b580b8da51,0x000753ba05068eb1,0x0004077777efcdc4,0x0004cf44aa177ad1,0x00044e0b7f54eb7e,0x0000000000018601}, {0x000becbcecff7dd7,0x0002b1279ed4c55b,0x000e10b5af306b99,0x00058fab8cdb6cf3,0x0004a0c7614aebc9,0x0002c6d8ebc4f93f,0x00038ac5bd6cde7b,0x000000000008d65f}}, + {{0x0000f0922779f009,0x000bb4da7d63a943,0x00025a4f402efdea,0x000001668841d1ef,0x0005b10366f61e8c,0x000b121e90688f48,0x000c1e38ee34b005,0x0000000000014e0d}, {0x000a8eaa6c54d224,0x000e683c1d44e6fa,0x000050a1a6ad5a9a,0x000274453715349d,0x000dc5ca18f66b73,0x000ef86e35065bdc,0x000f5d677313cf2d,0x0000000000033ebf}}, + {{0x000a3669bab3aa8c,0x0001fffec66743ba,0x000af6b2298cee7c,0x0001365ee61bc95f,0x000e8948b6e23181,0x0001644be358bbd6,0x0007a71cd9c342e3,0x0000000000060a8a}, {0x000569b8813054fe,0x0000ae065519f224,0x000901053fc569ee,0x000c03b8517ae8b7,0x000173750d6e8957,0x000aee6d7c96a040,0x0001144eb2e364b2,0x00000000000ed099}}, + {{0x0006635997173f0f,0x0003b71714896339,0x00025444ec94256f,0x0005f33fe56d0905,0x000638a1b2efb078,0x0000fc15add43e0f,0x000d362df35cfb36,0x0000000000090b3e}, {0x000659873829fac7,0x0000bd4970bdd7ef,0x000e315a3dccca14,0x0008a3e4a43c4f3e,0x000fd9cb4808c99e,0x000c3d0948013609,0x000223f3fef0eaec,0x000000000008642d}}, + {{0x0005a811304eaea0,0x00018ffe3104b37f,0x000808bc57214341,0x000ed42cca2f1506,0x0002c421c69415aa,0x000b87b368618aa0,0x000d5f4d6a091dfa,0x000000000000e786}, {0x0009341357580c61,0x000ee0be97746d4b,0x000cd6467b049086,0x000823b7a70d4224,0x000809de860f6094,0x000cf60205928791,0x00086e7f7fca496d,0x000000000005f460}}, + {{0x0007768861c39ce8,0x00007b509f7028f0,0x000fc09189281be1,0x000832a7f07f3291,0x000d8fbdcb83853d,0x000a4650d074fdec,0x00072080ed8de9d6,0x00000000000a5d68}, {0x00079ea50cb0600f,0x0009ae66666d224c,0x0008a45c66bc5d53,0x00099510da620fbe,0x000fdf866f777e2d,0x000045beb901145f,0x000008442a37e5db,0x00000000000beb1b}}, + {{0x00048a2dbd606668,0x000c9bb39a179bed,0x0009439710e05c24,0x000abe3b91f14833,0x000fbd39a2bc6be6,0x0001d813ef972804,0x000d4a06737e54f9,0x000000000001a87c}, {0x000d0c4b5d0bc923,0x000b2bf88b2e5982,0x00052c33a491bb9f,0x000aedfa58af0431,0x0006ac0511b07a93,0x0007e2c198853cdf,0x000d8a9d7f416d06,0x00000000000f9671}}, +}, +{/* digit=95 [{1,2,3,..,}]*([2^380]*G) */ + {{0x000f6957a24c76d1,0x000222e7d0a157df,0x0001697f0073308f,0x000ddc63eb317f9f,0x00015adf71d715f1,0x000858bc3f027507,0x00071a2ce33c2eee,0x00000000000da73b}, {0x00035cb76cad67cc,0x000de9ef6a709ffc,0x000c7c7ed1727cfd,0x000f5a67502de655,0x0001a47019739f5b,0x000ea7b24d11122a,0x0002e182cfaac2a2,0x000000000000a458}}, + {{0x0007ab134ebd334b,0x0005196a1e74f032,0x00014e69e2323c83,0x0009c4fbe35109cc,0x00004521d7e61244,0x000d002931fad8b3,0x000229c85eb23d57,0x0000000000035f68}, {0x0000d113aed4dbde,0x0000c7c5b86677f2,0x000189b64d0338ba,0x0000456757cd5717,0x000e3a1c866b067b,0x000ba88c0eaab81b,0x0007dc72a6af75bb,0x000000000000ef56}}, + {{0x000ac045af51c5bb,0x00010597a26ff058,0x00059bcfafa87a4b,0x000aff65c27f5f6d,0x0005d8d544e60b06,0x000275c32ce5ab66,0x000e7c92f031be99,0x00000000000f42e0}, {0x000c8a905adb28dd,0x000175bb28b05c35,0x00031ae347df4e7d,0x000d299f93fb7dcb,0x00086e2ccad9e73f,0x0004d4f57fcd999a,0x000c9bb8c8a6df33,0x000000000009a2ac}}, + {{0x00030bea7fcf0ecc,0x0006a3afdee26fd5,0x000cc01988c78a70,0x0008ee3ba4a33026,0x000a2a883b7f340c,0x000d7412b1a6ea51,0x000b6e64f27976d5,0x0000000000091251}, {0x0008bb3d89325d7a,0x000d25f3f8f40ad2,0x000216e9116c139b,0x00073d6ad61b2cbc,0x0005d542676dde3b,0x0007d712bf08398d,0x000023d373931e8e,0x000000000007f96e}}, + {{0x0004e4e1b942add8,0x000e15adf3d9957d,0x0005ba50de0860ba,0x000ce33a82d3736d,0x000e718c8aa3f9fb,0x0006ccf69f307823,0x00065b860578cf41,0x000000000001ef84}, {0x0009d5f6cc7a9ceb,0x000939ee0cf97011,0x0002f3cbdb7c8fc5,0x0009a8dc09da90cb,0x000dcbf3ccb8f99b,0x000a626321f521c2,0x0009da6bf6694891,0x00000000000854fe}}, + {{0x0000917c5016c853,0x00049e44e3f85fb2,0x0000e1793eed8bac,0x000254501c4e171e,0x000cce52defb1004,0x00063100ac12df68,0x00035fb1fae2fbf3,0x0000000000035732}, {0x0007edc8c1da40d3,0x000c58d4deb655bb,0x000bfb14f6d9d28f,0x00085835a4e118f4,0x0001308772e93249,0x0004e48765abfa96,0x0007b241c7611ff5,0x000000000001f586}}, + {{0x000782cfada548c3,0x0001e463031709b7,0x0005afd4d0d5166c,0x00097fff172c7d05,0x000735b193cfd8e4,0x0009df4bc7f7009d,0x000e376b9fd3f7f1,0x00000000000b46f1}, {0x0004c800fedd3a70,0x0000987c6eaa8c8c,0x000dff8047ad562a,0x0001042539eab96e,0x000779b8f5cc2a12,0x0007840dc29a6d5d,0x00030f33803a10b7,0x0000000000011a6a}}, + {{0x0000457a60ad991e,0x0005e3c90a59f250,0x0005eeda9345d42a,0x000885c1a0d58e29,0x000d6816b0099aca,0x000e4718f77b9b6d,0x000c458e5c12139e,0x000000000004e4ea}, {0x0005f9c85e9bfc5c,0x00086c00c3568eed,0x000b5b4b0eba61f9,0x000ffc75eaf3eab0,0x000d42a87e32cba1,0x0007a882f5f99092,0x0005122e7b49c76f,0x0000000000029040}}, +}, +{/* digit=96 [{1,2,3,..,}]*([2^384]*G) */ + {{0x000dbfc10083fe9c,0x000bfcf17f9dc084,0x0005e1e364b063e9,0x00054ffe437b29cb,0x0009e27ee9e2a694,0x0003af03b6628d78,0x000d6256e3b975ee,0x000000000002f532}, {0x000e1d6aa4b057a7,0x00043cae15213418,0x000003dc9b2b9ddc,0x000a959fa4d82608,0x00055ae17566902b,0x000c82eb4bad700d,0x000ea716b2c5dc14,0x0000000000036708}}, + {{0x000e41b4a9c3409a,0x000849cbd62cd8bb,0x00047e8c2d4de38c,0x000bbe98f886eca3,0x00049b432990b7f3,0x00030035684860e8,0x00029ed19a3bafa4,0x000000000000e209}, {0x000ed539231869f6,0x00098f15ff660294,0x00050e66a84ebdc7,0x000de8d2955612f1,0x0006ec97a4a53ec6,0x0000d15fe2d95b4e,0x00024d868731f0f9,0x00000000000aefae}}, + {{0x000253f48e5fab58,0x0006889f97859df6,0x000dee3f7bba228a,0x0001d4ea62a5c827,0x000ea3045da6826e,0x000d3d237ecba3e4,0x000358beed1da058,0x00000000000b8b41}, {0x000293271a9d4293,0x000d2730e7ac94c3,0x000f438703e7096b,0x0004cace8c1c6462,0x0001055d39de9ba9,0x000b71db3ec7c382,0x000a11c89705a82f,0x00000000000781b6}}, + {{0x000606caa5686427,0x000cdc1951fb0886,0x0000daff401d6319,0x00009bb2754f1d38,0x000e0e0e2bf19831,0x0005a3da40f7db33,0x000197348c4e1937,0x00000000000840a6}, {0x0008d7f45b2f9769,0x000d11687a735d22,0x000434d1e1dee1ff,0x000773c0aa9e79d1,0x0009f56de9654a25,0x000dda7af656f6e2,0x00063fdf84666df0,0x000000000003f9e4}}, + {{0x000a9c9951735edd,0x0006afe9f90d3ad9,0x000f97a0b45a07d7,0x0007d6ec36e3b706,0x000f580c8e6dd513,0x000bab45c3ea55f4,0x000d5819398b33e1,0x00000000000aee76}, {0x000d9c115c469d59,0x00071e72c8214ce4,0x0006b3ef7ac6abe3,0x0001ac198f9553cb,0x000a1c98ad467fa5,0x0000ebbb2019ac4e,0x0000a68942e16e01,0x00000000000bed3c}}, + {{0x000f13cdd62e69a0,0x000461a814bf695a,0x000e4323f4986584,0x0001bfa2a4dd16f8,0x000a76fb9f2b33c9,0x000b1f1114af4d9c,0x000b45a23635ef75,0x00000000000a0891}, {0x000bef0dcdd6b903,0x0005f5d1b87ba5f6,0x0005d7ac1d6bdae8,0x000cb4543d4ef435,0x00064aa784ea70bd,0x00070e4220ed12d3,0x000483009cd34901,0x00000000000280cf}}, + {{0x000bddf9aa596a1d,0x0008952c04b79c0e,0x00099a2770f3fa4a,0x00044bf1911b3184,0x0006bb897d318407,0x000e9de5dd13f080,0x00052b376dc8b81d,0x00000000000c996b}, {0x00047f465159b51f,0x00041d91e47b224a,0x0009b71ad19e642b,0x000c167eface7572,0x0001d4805ed6a441,0x0003fd6654eb9588,0x0005778fc93daf3f,0x00000000000cc570}}, + {{0x0000b16f46a35f8c,0x00065a630c20c4e5,0x0001f4362772ed03,0x000aca10c0dec6cd,0x000ba9e2f55428c8,0x000bbb1705d34bb5,0x000f6e8e81b4f732,0x000000000008363b}, {0x000ca7950547e910,0x000969603fe028be,0x00047954fea1ddef,0x000bb8efc191d12e,0x0005dba97347c0da,0x000656aaaf0e463b,0x000cf0b7f7c207a8,0x000000000003f08d}}, +} +}; + +#endif /* IFMA_ECPRECOMP4_P384_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p521.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p521.h new file mode 100644 index 000000000..13433c286 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp4_p521.h @@ -0,0 +1,1342 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPRECOMP4_P521_H +#define IFMA_ECPRECOMP4_P521_H + +#include + +#define MUL_BASEPOINT_WIN_SIZE (4) + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE +#define BP_N_SLOTS NUMBER_OF_DIGITS(P521_BITSIZE+1,BP_WIN_SIZE) +#define BP_N_ENTRY (1<<(BP_WIN_SIZE-1)) + +__ALIGN64 static SINGLE_P521_POINT_AFFINE ifma_ec_nistp521_bp_precomp[][BP_N_ENTRY] = { +{/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x00031a16381adc10,0x000f3f18e172deb3,0x000e0c2b5214dfcb,0x00017fd46f19a459,0x000ac947f0ee093d,0x000d50a5af3bf7f3,0x0001457b035a69ed,0x00009c829fda90fc,0x00011cada214e324,0x000274e6cf1f65b3,0x0000000000000000}, {0x000460e4a5a9e268,0x000f4a3b4fe8b328,0x0004351396120445,0x000fd683b09a9e38,0x000132062a85c809,0x00064bf7394caf7a,0x000d7de8b939f331,0x000224abcda2340b,0x000163e8deccc7aa,0x000de0022e452fda,0x0000000000000001}}, + {{0x00090cf08640909d,0x000f1c99dd36bc1e,0x000b26b07ecb3fa1,0x000ae2d7a0e797d1,0x000aa83d508251d1,0x000bd9d9026d377a,0x000372a82ebb4df4,0x0003cd8e66031a96,0x000a461413a3a019,0x000f3f3417e59440,0x0000000000000001}, {0x0003d2ee331fe1b6,0x0001ab6b30fa0d81,0x0004af6e07a7b8df,0x000d19247a757e5f,0x0008fb5c9c9bfd4c,0x000dd9f1bbef4f92,0x00090d14c836216d,0x00083e26d4bba055,0x0007769f85ae35a8,0x0009338053f9f677,0x0000000000000001}}, + {{0x000e9cf4d4910f78,0x0008ce976f1bd6be,0x0004316197502d2c,0x000acff10dd75a48,0x00019028ed35e8b5,0x0008d69f8b251d24,0x000d6bd0896bd46e,0x00072d891ecd5cf2,0x0005acaca3cda953,0x00048caeec8eb532,0x0000000000000001}, {0x000cfa6c0ee5f7e9,0x000c4650f7436072,0x000de49d2c8212fa,0x000f61e3867882e4,0x000bad816ad6768e,0x00061716ea67c6e2,0x0007c558fd1aae77,0x000fd4154e818be9,0x000655c0a7978aab,0x00016eeccbcfc363,0x0000000000000001}}, + {{0x0008d6d77d92b8ab,0x00043a09438c8179,0x0002d8472d2f17de,0x0003c5783350ea81,0x00083a8745c474f8,0x0006432cf1257f1e,0x00062eaaaa0e9e75,0x00048e2ff9cd7e03,0x0003e483866e30e4,0x00010261aa5a41a4,0x0000000000000000}, {0x000a0825be109849,0x000fa3fe1a372686,0x00078234ce8ecf10,0x0004adc2f75dbfd7,0x000c2a029127ba85,0x00093cf941f2a5d1,0x000731ff178cc83f,0x00077b7371970dad,0x000585a55db2a90d,0x000ce95b39f00bc7,0x0000000000000001}}, + {{0x000194afcf14a49e,0x0005a84b7647983c,0x000f36c498b9c6ad,0x0009bf3cd194ebf0,0x0000a11b8897f578,0x00021c1e0636af18,0x00081ed5c78bbd67,0x00077eda9f869267,0x000e027585fbd2cb,0x000219639ede19c8,0x0000000000000001}, {0x000d6f9bbc6f7598,0x000e61f46f584865,0x00092b9aa7bfc0b9,0x000e7affbce8f803,0x00079ba188aa0108,0x0003ddb44be48396,0x000ec0be4d01a384,0x000f4743970028f6,0x000a54089488e6c7,0x0000eb764515b988,0x0000000000000000}}, + {{0x000fb915a75b36d6,0x00098df6fbc9035c,0x000ab2bf9c05711b,0x000a98df4617b374,0x000b9ca70393d11c,0x00092fde650b0a9f,0x0000a8356f25580a,0x00084bbfeb8e79cc,0x000a24068cab11e9,0x00090ca9977f9a7c,0x0000000000000000}, {0x000f780956b43319,0x000666bc2c6a278b,0x0005aae506d6f0f5,0x00013a79101ee3dc,0x000464efcb64c26f,0x000b655b96872b32,0x000205493100d454,0x000db9ed2d404739,0x000a371d8889555d,0x0007ac35716e9382,0x0000000000000000}}, + {{0x00015b574766756d,0x000756c4140b766a,0x000a87ee130cd00e,0x000e71dde237ca9f,0x0004c6c64d36f986,0x000ec61846855fe3,0x0000c69617b88a62,0x0000747aa4191478,0x00005839d062f917,0x000fb1a3775b2fed,0x0000000000000001}, {0x0008f4b46df66eaa,0x0005c5e48292928d,0x000952eef7e3dae3,0x0008e70d2fcf3b38,0x0004f15ca91d1a2c,0x000ab5e87949e6f6,0x000edecc51365ef2,0x0001681412786eb8,0x0001ceb423c5ae2c,0x0001508868ec18bd,0x0000000000000001}}, + {{0x0000208b103ed8c0,0x000cf52a553c6734,0x000dad37a0202c37,0x00046bcf0d5ab144,0x000a4f845acc60de,0x0007adff52dc2bcf,0x000c51d82fc1314c,0x000ec54d801f0545,0x0005808712dea714,0x000fb931541a41cb,0x0000000000000000}, {0x00058cc64475550b,0x000b21788f8bc00e,0x000a004a389a9c56,0x0002e2bc34cf9dd4,0x000da5ff85d06f83,0x0008c4f4e0552c88,0x00041ef30833bd47,0x0006f4f16038ada8,0x0003c429dcd227c7,0x000e2410247ed5b7,0x0000000000000001}}, +}, +{/* digit=1 [{1,2,3,..,}]*([2^4]*G) */ + {{0x000f45f44362a272,0x00062847c0d42017,0x0004003ee6e299d3,0x000c2b186f86dfae,0x000005072cb2ed3c,0x00094a1ff8c430e5,0x000197c69058c452,0x000b30c97e9f9eeb,0x000563a1d859543f,0x0005682eed4bed13,0x0000000000000000}, {0x0001e8dcd0f160b5,0x0001397c4de39d5f,0x00069468c3199a97,0x000eccc4294f1802,0x000a3d505983ad64,0x0000e0c1709cc6da,0x000e51864a5b5c16,0x000261dc006a8763,0x0009e9f34b9099af,0x000b800fe38a58c6,0x0000000000000001}}, + {{0x00059ae8d65b4828,0x0008ad5c3b72b54f,0x000ae6b62e3c123c,0x000d2e8fca4e7ba3,0x000cb7633eb4deb5,0x000b750251aee39a,0x000d3f677dcf2f5e,0x000b32a703401c6d,0x000a5d0ad9a1f1f0,0x000d234a21b83d7c,0x0000000000000001}, {0x00011dec3fd34650,0x00054d4c8a50ab55,0x000b2d5cb0b1b4ae,0x0005079b6fe6cc64,0x000eb5cdba6f0e3f,0x000ef10266dc0c66,0x000ef80e32e16ebb,0x000c5faff80cb3e0,0x000f9f041347fbde,0x00055c088b1af3af,0x0000000000000000}}, + {{0x000fecd778ec8555,0x00013eb0956c3cd6,0x0005e90a57516438,0x0007f84773320ba9,0x000dfd66f6e10d88,0x000a16d04c079fb7,0x0009e6452c01f397,0x0006b339081619a5,0x00076316466573eb,0x000a315640ac72e5,0x0000000000000001}, {0x000e34d296b0561e,0x000ac0c9e92b6a35,0x000402420e573d8c,0x000d871e142cb792,0x000bf1bdbe0a1707,0x000d7310a6b250ec,0x000894a7b366170d,0x000fe4a684f16643,0x00025d9fae0bb793,0x000c96f6d42adcf6,0x0000000000000000}}, + {{0x0006ae6a85f73844,0x000ee1c671907ba1,0x000014d027ea0da9,0x0001f3800efad55c,0x0001bb9d3e0160b0,0x00038df5e9e2f7ed,0x0000a5ce67c43969,0x000dd40c305dd65b,0x000c97f61533f5ed,0x00097668a79ebe01,0x0000000000000000}, {0x0009d235c3ae123a,0x0008b82c52fc6fad,0x000edd0329eea2d7,0x0007cac021e0e0d2,0x000a5887a53dcf1d,0x0005d60b2dd0a846,0x00031dd1b4f43d5c,0x00064597d8ee0e86,0x0002bdcac36cdd8e,0x000902b9d50810be,0x0000000000000000}}, + {{0x0002ff15cc9efbda,0x000d0adea1bf15e4,0x000712003c28f70c,0x0009acbb183fe29d,0x000e35ff46058b74,0x0000e6fbe9505c1f,0x000949d4ed7c586f,0x0006bc96db22c518,0x000e9fa6b4caa767,0x0006b3b723ba4dae,0x0000000000000000}, {0x000d4a1dbb01ce30,0x0002733373d1589b,0x000695b9bd79abea,0x00024c417444789b,0x000a3e366b3687f5,0x00018eccb8e87edb,0x0007fa4355949d4f,0x0003b1b5225855c5,0x00040d600e111ea7,0x0002ca9912224327,0x0000000000000000}}, + {{0x0001ccaa77955b13,0x000980cc45066e57,0x00005f6f02b3f9b1,0x000f381f6757639e,0x000d14e03775ce84,0x000770c3535ef348,0x0000c573845ff7f4,0x0007edbd50365fb5,0x000ae96135b16a31,0x000b1cbda8a1cae0,0x0000000000000000}, {0x000fb5af8ac6debc,0x000ccace499e422e,0x000f85f9a34dea5d,0x00099ffe8fc76f8d,0x000700f62f621078,0x00048a20afbdb94b,0x000353ffe99ecf56,0x0009d5421253436c,0x000d53ffd3fcac92,0x000092a9413337e3,0x0000000000000000}}, + {{0x000cc6739bc22034,0x0002d46c578a3cfb,0x00074dd1918f2158,0x000820e4ee32d9c8,0x000ee4769c451119,0x000a52dc0b788cd9,0x000ea08ad1dce239,0x000e6c51ce30fbf6,0x000c6808b739646f,0x00014612aa8ed807,0x0000000000000000}, {0x00084f57ce386096,0x00001bd8dd33a19d,0x0006d6cf7616b3bf,0x000aa0ec8a31fd3f,0x0000f33cd7d20cf3,0x000d8c7b490a7ae4,0x0003afd25187398f,0x0001d4b82d520c24,0x00008bc63a1c99f6,0x000da20702f937af,0x0000000000000000}}, + {{0x0005f3504967c9f8,0x00081372b9b7d4f0,0x00090711a09dabb5,0x00052fc0a79713f3,0x0008ebea8efb840b,0x000ba724a4b43b13,0x00089257bae703ec,0x000c5de16b6e9669,0x000a9811fd41e4b4,0x000c0fc1b18e0380,0x0000000000000001}, {0x0009bdb977d41aa0,0x00084a0964efd898,0x000049a3954725e1,0x0002567309871a1a,0x000d6462734e1923,0x0004d24ffa586e4c,0x000a7d5e1d8d7ce5,0x000f69f3efbcb30d,0x0007de3d3416e700,0x00041ee729987fef,0x0000000000000001}}, +}, +{/* digit=2 [{1,2,3,..,}]*([2^8]*G) */ + {{0x000757d0283c0ad6,0x000745c834df0056,0x000e5caf285c0d9c,0x000faea391f23599,0x000232d4e48a9620,0x0009bdc7a7b74615,0x0002fd4f47934e59,0x000c4f65ada3d4dc,0x0000798974c81e39,0x00061064a2c57e3c,0x0000000000000001}, {0x000a38d40ea9cd04,0x00060922a435ef3f,0x000a826a53bc247d,0x000e94d33d8a1866,0x000de75ac695cced,0x000bcb2e7b2b9c71,0x00016e1d52b9aa78,0x000540f2da2b1a83,0x000881db4e2a0769,0x000e217e4c0ddd49,0x0000000000000001}}, + {{0x0008396a04a1a9b5,0x00071e1d4dea3fc9,0x000f1b1b60428524,0x000875279e270a42,0x00031e46c1327bff,0x000c05c823fe0222,0x0001988e4c1b07ef,0x000346e86dbfa458,0x000ea14d7c3803e0,0x0002698c2f4163f3,0x0000000000000001}, {0x0004df73f1c64b3b,0x000bae3f77cba047,0x0009fac52f482f0e,0x00046303eabe2a5c,0x000605a86c7774d0,0x0006157561d8716f,0x0006dae76cfe4cf1,0x0006f10528e0564b,0x0008d8ad69113bb2,0x000c2f933ccc8b87,0x0000000000000000}}, + {{0x000963cd234bdeab,0x0005b961fb152043,0x000192d80595fa4f,0x00021e095276439a,0x000ab3cdd8200acb,0x000b977cb97a7564,0x000f1ac5e95df534,0x000082ed91f8da63,0x0005eeb0ff149253,0x000e11676ac3e35f,0x0000000000000001}, {0x0001cccbb8a0782c,0x0008ef764987a4d5,0x000621e7649cd3df,0x0006ca705ffe9912,0x000d887d63f6769b,0x000a2f7ad40e5963,0x00074e3b9fc2e426,0x000bd597aa3dacd3,0x0000fea916df09cd,0x000c4db4a1b5ffeb,0x0000000000000000}}, + {{0x0006312ffff6fab5,0x0006b5b394c36d7c,0x000ae9f8123d8c52,0x0007a4616b7fb3e1,0x000a92d9f22f9728,0x00095d4a0fd21b31,0x0002d23d7cbfded8,0x000b5c10574881ff,0x000e2bd04e830bd0,0x000fd69dfeb7774f,0x0000000000000000}, {0x000b243fcf68f023,0x00066b7e7441cd83,0x0005c91b009a23e1,0x000f85c785f70865,0x0002122e7768c122,0x000fb751856db403,0x0001836d6df94b82,0x000098df3edc80b3,0x000298e9aeea7ce8,0x0006e6048ecb9605,0x0000000000000001}}, + {{0x000cad0b80b053c4,0x000883158e365644,0x0001acd6f66175a4,0x00078eba00f9062c,0x0000f302446bdc8b,0x0004ffcc5c874a3b,0x0001cc9e542baabd,0x000ca8d66f56fe73,0x000fec6e656e27fc,0x0000e12576ad29e3,0x0000000000000000}, {0x000f2114ad6a5008,0x000ff37b5e9ff077,0x000fe609c9e85ddc,0x000612f68cb97937,0x00035cc97418d8cb,0x000e6da8506bf5e6,0x0001561e4122e23c,0x00026ba1b08bd010,0x0007eb4a708cbd94,0x0000c9d309deaf41,0x0000000000000001}}, + {{0x0001bba765fa9bcf,0x0003babdc21b3ff6,0x00025b55117dbb2e,0x000cd85081bffb4d,0x00081cb8cbfa61b2,0x000244b920db891a,0x000db06e819df932,0x000532ca257bcc77,0x000ade96bb81f698,0x000552846b3d2e5e,0x0000000000000000}, {0x000cc4965acbbc52,0x00019fc3317e41d4,0x000a394d289bf4a3,0x000dfcc926b6b451,0x00099fdc4795a3bb,0x000fbdeb87e6005a,0x000e9db4adbdc0b3,0x00050e680b14c0a6,0x000a1f2811642efe,0x000396ef97cb540f,0x0000000000000000}}, + {{0x0005f3ef0a7bd1f0,0x000acae8e898fb4a,0x000ba953fee10eac,0x000ac34b13e74541,0x000d80a4f317458b,0x000699b6bc22b700,0x0009d659b3752d47,0x000972beec5644da,0x00015e14a99a228f,0x0008731fa64678ce,0x0000000000000000}, {0x00076f9ee24a5ff4,0x0001761a3d49abfd,0x000099dc50257cde,0x000182905bef244d,0x000f586d9a90e6d1,0x0007ebb4cb4857b6,0x00070d79d0a32ad0,0x0004bfe6c4dca5d6,0x0009e03cd5b7b143,0x00028c04a0538f51,0x0000000000000001}}, + {{0x000c6fc14a74584c,0x000402292021e48e,0x0009500ecd0a9680,0x00002339ed719b16,0x000ebb81e8a19412,0x00040e8e4db85440,0x0002a313f6a53c2d,0x00082796c5c684a1,0x000636765497c008,0x00020c751837b791,0x0000000000000000}, {0x000740897b89a933,0x000f39feb6c7cfd4,0x0006675504305fd0,0x000708d724da0165,0x0003fcde5846c915,0x000cbcc847c7bb1c,0x00035875d5c58a40,0x000f531dd999d009,0x000ff3f98178ab52,0x000a7c4485d31888,0x0000000000000000}}, +}, +{/* digit=3 [{1,2,3,..,}]*([2^12]*G) */ + {{0x000bc092fe2354e8,0x000850a2f27fd64d,0x0002ad51407fff03,0x000808402ffc14aa,0x0007fbe516b67c4b,0x000f027098449910,0x0009af3715688b40,0x000dbddce7795e2c,0x0008a5dc626ec8f7,0x00032acc9e1305cc,0x0000000000000001}, {0x00014a5956e30ed0,0x000921ce664e13cd,0x000b7485d5a678ff,0x0001d65fed6fe685,0x000152b7d0453dd6,0x0001e48dc7a066d9,0x00012560c3395f08,0x000d6053e587c1cb,0x00076afca630f2cd,0x000814f0d70553c7,0x0000000000000001}}, + {{0x000a19c3686b1f78,0x0009545540d3da61,0x000fed5fc9dde90b,0x0009be8908cbe546,0x0002b931292ec657,0x000e0b221531c8bf,0x0003dcf64709233d,0x0006a91e2913f0e3,0x0003880d89929920,0x000d07ab37b02493,0x0000000000000000}, {0x000b1d587081c0df,0x00062b5f29f3ee6e,0x00013755e246f468,0x000c2e51e2652ae3,0x00046ba6a65e2952,0x000fd1b792013b94,0x00049175e7bffb43,0x000166af7dd896a1,0x0003d0d5f68a4101,0x0003a34ff29cf955,0x0000000000000000}}, + {{0x000b9e5f2e5de279,0x0006be9e4c557ee8,0x000c510883da6331,0x00016eedfba63955,0x000b55eba66cb586,0x000d93dd071f901b,0x0000d11e4c33f467,0x00029c2288bdd752,0x000f22d4f3c9b728,0x000416f979cce9a3,0x0000000000000000}, {0x000f91fa66b3408c,0x0009041780ab3969,0x0001e17f9e99f2b3,0x0002825a0408a22e,0x00013e814b39af10,0x00017c70c14077db,0x000fd91116e8d047,0x00025157bba11642,0x0003d53fd072760c,0x000130f596860d22,0x0000000000000001}}, + {{0x000ddddf5d1e5c64,0x000b39631d236577,0x0005fc5e812c4b6d,0x000ec807d1cccab0,0x0002c8729f1a1c38,0x000999e4061629e9,0x00088f56b4c00d1c,0x000c3cac8f29781d,0x000b02141cce3380,0x000920c7e0e0cc16,0x0000000000000001}, {0x000234580d88382b,0x000b0ad02da7d076,0x000cc82cf5ae2d27,0x0008a15c3adad7f2,0x0004d7009305d2c0,0x000e9e632a55fa7b,0x00011560b55b693d,0x0008b565732e2a82,0x000f0adb63788cf9,0x00038e2d1f605489,0x0000000000000001}}, + {{0x00007e33611831c8,0x00062ce163c826e6,0x0001c1873d3e07b5,0x000df7813a79a532,0x0007451a6bebf65d,0x000789f014abc3f1,0x000cc2aa01512853,0x000bc25e7cee2985,0x000dd32f61a13543,0x000f9b061a57a2a5,0x0000000000000000}, {0x0003734e520ae3c4,0x00041544fe045295,0x000321b2f9da98d0,0x0004ac066f5c4118,0x0004f9ed8d4d338c,0x000c2ea3577c3f4a,0x000a775eee973782,0x000efa3a3176188c,0x000aa0ec53f7823f,0x0009b227eec20996,0x0000000000000000}}, + {{0x000cab486125bb6b,0x000ce02028378ff0,0x0005e625f7d1c380,0x000dc7cec93bc7c0,0x000d0c3b6e1a5a67,0x0001da033baa95ac,0x000e0b126ba3c688,0x0005b900f71e6919,0x000cfb69d4bcab68,0x00090d9f859cecf3,0x0000000000000001}, {0x00030307c7f8906c,0x0006bf1f14afae02,0x00001d0c8e70d7c3,0x00031fcdd396a945,0x00035972de152221,0x0001149c59aa6c9c,0x000e743c53f3251e,0x00072a17186bca64,0x000bae52281f6178,0x000c98982b2d35fe,0x0000000000000001}}, + {{0x000abaada33bf5eb,0x000334cbe9475074,0x000503921efaf87b,0x0001a3119b05ca55,0x000a4fa919940136,0x000a8bd8f158f3c3,0x0002e855587cab4c,0x000fd133003309bc,0x000a468f055eab49,0x0008de65f435935f,0x0000000000000001}, {0x0005a479ed62ca37,0x00046fb6c0237009,0x000c6558be89daa3,0x000e86cd9c606b6e,0x000dcb5426f2b48f,0x0002744bfa702fd9,0x000e9ceab7372571,0x000cd8bef4768a91,0x000d361ea2d4f5d1,0x0000ca847b5f94d5,0x0000000000000001}}, + {{0x000c6a7b65b21bde,0x000fc723a29c73b0,0x000392643c39c3ea,0x0000b213f81be3c4,0x000e3ec734fa388c,0x000b26d37a33b98a,0x000332e230742689,0x000e28354ec1687a,0x0000d4b7e6935b64,0x000ba79d55aecff6,0x0000000000000000}, {0x000073362910afa1,0x0007fb8bcd336bd6,0x000b6c7a7845b5f6,0x000017305633e845,0x00076a907be72df6,0x000e65734d2814a5,0x000f113c7084b86f,0x000cd7bad9f20758,0x000f6af2a5030c22,0x0001647ff1cabc3e,0x0000000000000001}}, +}, +{/* digit=4 [{1,2,3,..,}]*([2^16]*G) */ + {{0x00084cce9eb37269,0x000406ac65525f61,0x000c9acc4f25051a,0x0007bdd2651c4a44,0x00059571fa6bdb63,0x000cf1489d2ae9ce,0x000a821f56bdf324,0x0000e5fa827f61b0,0x00046a2449dcea62,0x000c947027c9ed4b,0x0000000000000001}, {0x00095f1c50d4d450,0x0002c227a410cd04,0x000bc9ba135ee643,0x0004257073536858,0x0000b7e39c350531,0x00016eeb65d0616e,0x000e949a694a0693,0x00069aba0dc455bb,0x000d36d721f9d7b7,0x000a041dcb7a1d32,0x0000000000000000}}, + {{0x00030d330fc15e51,0x0006a88312448f9b,0x00027c12fd1499ca,0x000b765eaf5a132e,0x0008d01b2d2a5c3f,0x000e3517c807951a,0x000936a97c68ed6c,0x000f8cdd161ce67d,0x0005d9876ad5eb28,0x0009976496ac4a79,0x0000000000000001}, {0x000d912524de7c0e,0x0001e66e4dff627f,0x000a96a9194e4460,0x000ccae884a673b1,0x0005d06054966f81,0x00032269452eba8c,0x000ba7677e70b535,0x000298891e5c17de,0x000f9a70e2fe55a9,0x0004d48b39032dcc,0x0000000000000001}}, + {{0x0009dc9a72f4ff50,0x000df54e86b3f74b,0x000b7fc672cd56a4,0x000ac313c91daa4c,0x00053d8b04fac047,0x000047ffb771df8b,0x000a8ad48cf7c44d,0x0008bf663542e196,0x000aa68b0ea4fed6,0x000483dbd49e0b45,0x0000000000000001}, {0x0007d603e389e5cb,0x000ee233664de2d7,0x000994f96855ef7d,0x000c5bf8c8ab10b1,0x000c2f5ab3d235e3,0x000bff37afff2ae5,0x00050de9d0fd0f4d,0x000ca6d91d5250db,0x00042da0be2c950f,0x0001c70ec3836fa7,0x0000000000000000}}, + {{0x0009b222a53c1578,0x000733b1bb114a22,0x000887f6c13ff59f,0x000d5dfb2679cded,0x0001fd35dec8bbba,0x0000930770ea94d4,0x0007da8d4f0a6019,0x000d2142901c2ad0,0x0002aaa8648f142e,0x000f42252e455969,0x0000000000000001}, {0x0004f335e4753950,0x00010578c42f0d9b,0x000fda89975c2716,0x000761372c49b195,0x000583ac76051357,0x000cd0c4d54de0d0,0x000c35f47ffa549f,0x000731f21817e11b,0x000ac2b103f57a56,0x000284cde0cd7146,0x0000000000000001}}, + {{0x000bb2a3bcba0504,0x00052359d22ba169,0x000ee4d727c18bc1,0x000338aababfd9ca,0x000cae35505124c8,0x000599b6e8a9cc3c,0x0003c6415386807e,0x00043919da2fc5ab,0x0001a4c6fd2ee43d,0x0007be38ead93480,0x0000000000000000}, {0x0008c66b564a97d4,0x0002177834d44e8b,0x000690ef30774807,0x0007151d926feb1c,0x0003fbe2f1f3454c,0x00048ce8e6456bd0,0x000270c04a6964dc,0x000fe8febbc7afec,0x0000f159a483b3a5,0x000aca96cb139ad3,0x0000000000000001}}, + {{0x000c0e9763d8a013,0x000baa65d7b1d37f,0x000608a4b87c8c06,0x0008c2592e527b8c,0x000aacc19bb3aa2d,0x000ce5b0adb09308,0x000e0f42458761d4,0x0002d73d4f707a6e,0x0003867f8d791c44,0x000c943ba7a1a60d,0x0000000000000001}, {0x0007ffca3e51b076,0x000d23467af3d90e,0x0009427b9fa60c44,0x00054ce0e4a16358,0x0001655e4129aaff,0x000befd5ea275c28,0x0000ce27c03c7fcc,0x0000c97ca421b716,0x00069ee6f84bb35f,0x0007ec35e0436eea,0x0000000000000000}}, + {{0x00033b8c99430421,0x000e3aa65723117d,0x0001482e2ca3fcee,0x0006dfdb52560262,0x00036a105a9eb6d9,0x000c0fd8b7bdc41e,0x000c58ba2f2edd58,0x000c050043d8b271,0x0009966a34a51907,0x000aee0fa52e13a7,0x0000000000000000}, {0x000c2d7066d5fc91,0x0000d462accbe2da,0x0008397028d0b78e,0x000b525e2c9d107f,0x0003dfedd5666711,0x00083957250c9620,0x0006d0f2be094638,0x00026dd96c8ff985,0x00098fe829c7a670,0x000dacfc430b6d43,0x0000000000000000}}, + {{0x000aba8bae3f0048,0x0006fc5f421abd9f,0x00094ac402ce8227,0x0005bead91f2efc8,0x000d28241f32e7d5,0x0008bce170cc1090,0x00050cb19f59df3e,0x00034ac35c2de273,0x0003cf90c3e6cfc4,0x0002a784bc2847d1,0x0000000000000001}, {0x0003f87f754f1aa3,0x0003382713cbe9fd,0x00034163c334fd8d,0x0004cbe346cada61,0x000dd6aa94a54721,0x0007b9235830a042,0x000500be120acf2f,0x000d30c3e8d009be,0x000225e2751dc7f0,0x000714b7edd06e6f,0x0000000000000000}}, +}, +{/* digit=5 [{1,2,3,..,}]*([2^20]*G) */ + {{0x000c1256fe47d13c,0x0007012fd1181020,0x000c4a469315aa78,0x000b1163ea26a86c,0x000e4be00b905056,0x0002f1dad4a0ac68,0x000e2d8c19c57695,0x0000bbc11daec6fd,0x0003baf9c6293f81,0x000d375056fba03a,0x0000000000000000}, {0x00073f08bbfc9af7,0x0006c14cc716b559,0x000b5b613b18efce,0x000f005d64d3ad94,0x00034ba83b800248,0x0009ee4cf2a375eb,0x0007d29413af2a4c,0x000525ea872268a2,0x000c082bd8d12fde,0x0006fa2d233189c9,0x0000000000000000}}, + {{0x000f1bef2c1b123b,0x000c9ca73fb5cd85,0x0001a80d76a111a8,0x00025f888d3b7461,0x0003f7765b87f2e3,0x0002e36012c8ad9e,0x0009dc42c7cf6c49,0x000d7d5db366bf5a,0x0005359f96228a81,0x000772725123cd91,0x0000000000000001}, {0x0006c7a0e2cfcba5,0x00097fa38cc5da8b,0x000b43bb38eee14f,0x000f15c0770c4afd,0x00093138850f3aa0,0x000658cf7e3953b9,0x0007c8bb70f07792,0x0000d78fd38c1d44,0x00023ebe4681177a,0x000c9d704ca7518e,0x0000000000000001}}, + {{0x0008fa7e4527a9d3,0x0004db4e9fda74ba,0x000404855f433494,0x000f130f65201753,0x000d719a9846d31d,0x000c651ab9661cb9,0x000b653c04c2995b,0x00031b2c3fb591c2,0x0000b91d21b65fb3,0x000c1f9233b624c9,0x0000000000000001}, {0x000eac108061f9eb,0x000a2e86d9cc5afc,0x0000e2ec8f94cdd0,0x00040675309b7d38,0x000320d2223f6f2c,0x0003be480dc1e34e,0x0007b72b364f62ba,0x00063595753dec52,0x000283d90f6639f0,0x0001d567ed0c354e,0x0000000000000001}}, + {{0x00067e2e3d478324,0x000b9d2b33e93756,0x0005cc9c7d0711cf,0x000aa7c2edf0adb9,0x000b6610b704fc5a,0x000107368e770150,0x000cc4ef9af2a471,0x000afe1e566d06e6,0x000a67146814dd0c,0x000fd36c67f6637c,0x0000000000000000}, {0x000b744b33ca6a46,0x000a2ad960d19dec,0x00099ff41dbc0bcf,0x000977ca933b28a6,0x000a7951faf63b97,0x0005168f23ca3752,0x00097d901e0f16b1,0x000105f55f964ea3,0x0003c0d403b374a5,0x000d43e408ed3a81,0x0000000000000001}}, + {{0x0007586c50a55f86,0x00026583c230d093,0x0009c8f1eaf61062,0x0009876910419f67,0x0006e8d67dbad2c6,0x000c3c184d440783,0x000753899fd2f814,0x00037825fefa52a3,0x000f0758545a721e,0x000498a4b823d5ff,0x0000000000000000}, {0x000e376ebd4ed258,0x00004d6a23fbe496,0x000b69ec3505f765,0x0008fe6b545afc26,0x0000e87ed2073fb2,0x0006145047af95f2,0x00053f84d27cd1ba,0x000fa35d865dc4cc,0x0007b711a9ee96b7,0x0008ec430aefdeb0,0x0000000000000000}}, + {{0x000354ba169146af,0x0008c79fdb88cac7,0x0009f85e2efdc64a,0x0001012d7f3a69d0,0x00017d2bed232563,0x0004dfd89cfd4d1f,0x0008288e64d46be0,0x00089f8bf20fd559,0x0001d08641f269d1,0x0009fc333e29ffc1,0x0000000000000001}, {0x000c7dab1b832059,0x000223bbef8e949c,0x0007f10fed75c714,0x000647b0bb61d266,0x000b8e823dbf309c,0x000601c5a1f58db2,0x0009c023a71fa3e4,0x000a0b5cbdd6344f,0x000df6a6577b11f1,0x00027e6eb12db5f8,0x0000000000000001}}, + {{0x000b94e9f2c64c2a,0x000dff9c4cc3460d,0x000339e03c0646b9,0x000ca76c7ae26f18,0x000612ba1712f64d,0x0006950e5f2c8040,0x000569eb5bf0fae1,0x0006185858b613d1,0x00080b1245b35ba8,0x000d9a3c93740668,0x0000000000000000}, {0x0005f1c44e1c9646,0x00061096f83044ee,0x000e69176fe10924,0x000a78875cfb2614,0x00007825516a8324,0x000065d69cfbad90,0x0001f873d71727bc,0x000185c81c530662,0x000c1471ae21856f,0x00047e68582e4e3a,0x0000000000000001}}, + {{0x000ce1c67b68f07c,0x000dfa5469124c9a,0x000ccd6db2024f3d,0x0002fc6faadd52b4,0x0005124af076574a,0x000510591517b271,0x0000081118a106bb,0x0007cffda2d67e24,0x000b3b39fc6925ec,0x00012037b374e288,0x0000000000000000}, {0x000d91b81541ec51,0x000c413a683e17ef,0x000952a60eda72b7,0x000b61d80495c130,0x000f6bf06a5749c4,0x000c7cbd39872c4b,0x0001a82e01cb7ce0,0x0001726d7547989f,0x000742de944906b4,0x00009f2e02ff3752,0x0000000000000001}}, +}, +{/* digit=6 [{1,2,3,..,}]*([2^24]*G) */ + {{0x0000872f1cba7983,0x000a9c28a369cd44,0x00007ce63b6f5daf,0x0009c12dc12c54cd,0x000a00a67eec84f7,0x000bc7a4edee7a34,0x000ea82ff4e7f63d,0x000950ab492940f7,0x000953027dc3353f,0x000be21b37a3c6cd,0x0000000000000001}, {0x0005f758ab77d6e7,0x000bab416ce18f4c,0x000b9e45e70a1adf,0x00038074a53a6ae6,0x0005919bbc5eaf8e,0x0006580a40639d33,0x00033f83c3446f86,0x0009f20b5de7abe3,0x000a42c48703c063,0x000ed659dbbfadd4,0x0000000000000000}}, + {{0x00025b49cc7d0744,0x000d5ca66a4107d0,0x00009a278704a0b9,0x00027e26383562d7,0x000c28bfb3e1fb8b,0x0006132452cd156b,0x000d9a249ca82ac0,0x0005a22d3a0e92d3,0x000b19aafd34655b,0x00048d36ff20dea2,0x0000000000000000}, {0x000f6b3025835a5b,0x0008531143727c86,0x000c5c003858192a,0x0001da9352b2fd4b,0x000d25e79d62bdaf,0x0003c74903de7c27,0x000ad4718fc47302,0x00063e48286ed6b3,0x0005e2dbee1fb246,0x000857558feb16de,0x0000000000000001}}, + {{0x0009f56e96a543bc,0x000d31c6bb399ae7,0x00031b99e11a37bd,0x0006c0e42fdb7dca,0x00074aad0723ad0f,0x000aae97e4f8e5ac,0x0000fdee33ad0efe,0x000675078a78e14a,0x000909b38b03996b,0x0007469ca609f2ac,0x0000000000000000}, {0x000466dcc50132b4,0x000eddd95df5a1fb,0x000a8d9a82cb91aa,0x000178685d056d78,0x000f44580cbb5024,0x000b8404125b7ea5,0x000c959397a21279,0x000b3c397b77ec41,0x00050358651ee34e,0x000febe48525c5d2,0x0000000000000001}}, + {{0x0003aa997f7f37af,0x000bd0399f83a0f3,0x000f152344eac6ee,0x0003cc5d1e36ba58,0x00058bcb7b01bb23,0x000e6e01c3b95ccb,0x0003f3cbd70b3470,0x0005471f142928b7,0x000f33fe8192a8fa,0x00067751b82a4272,0x0000000000000000}, {0x000ea1f801a1be23,0x0000e029d67e2091,0x000355df0fe9219d,0x000069ec86128187,0x000e9196ceb57b88,0x000b831fc0c5d6f3,0x000b18561a90e72c,0x0006875cf51476cc,0x0009d0fdc775daca,0x000556f11fb0d65e,0x0000000000000000}}, + {{0x000d755a99415514,0x00085952e4dc0b72,0x000ddaa98f7198b9,0x0002cf0597f96150,0x000e7060ed10994b,0x0005df6128c96445,0x000ea5cf35637a95,0x000b47cf25cfbeee,0x0003e924da7f8ade,0x000d5d59754f0973,0x0000000000000000}, {0x0007794536974a33,0x000bee39625b4887,0x000c916eff917626,0x000c143d7b2fe99a,0x0002b42a1f214f15,0x000a92c52323d0ac,0x000fb97a09db1674,0x00097d2bc99da798,0x000062e5a6c7b18b,0x000498e32a3a4e9d,0x0000000000000000}}, + {{0x0006f0528c6a99de,0x0005f78365a5404f,0x000a6130da7d607f,0x000ce8f385d457a1,0x000127a71db8c282,0x00075b1780f22e8e,0x0005f271ed981d16,0x0000879b71615445,0x0003f2395d4c8d2d,0x00002ffbb885eae5,0x0000000000000001}, {0x0004e8a699830814,0x000f60c1a29f03dd,0x000620f1843d15d6,0x0005370351aa6497,0x0003f3bdc3d85b92,0x0005713630b15aa8,0x000b25038bafd76d,0x000aa324c45046f5,0x0008ff854c7ef0e3,0x000f873074cd9a42,0x0000000000000001}}, + {{0x000a5c1655f0c965,0x000ad8760b75d0c0,0x0002d3b7a7dc8ea4,0x000d9d864941a528,0x000eb47e8ca867c6,0x0001a8847066dfb5,0x000249722cfbbbd6,0x000d270c27ad4dec,0x000e74307c896550,0x000812fcfddc8f52,0x0000000000000001}, {0x0009df50d9240b18,0x000a5431583e94ff,0x00044e5e649470bb,0x000156c0cde5a76d,0x000ad9f50c93b508,0x00099e86567b7ad7,0x000e7618f9dede32,0x000b84978d6f1f46,0x000aba70858d56a1,0x000626f5aa274be1,0x0000000000000001}}, + {{0x00038150eda6a189,0x000d5498edde21db,0x00010e8c4a802c3e,0x000d570892441512,0x000a6f9b009f95d3,0x000c80e954785d69,0x0008dbfa197859ea,0x000f9a954ad6166d,0x0005360545cac81c,0x00042d01aaa83bd5,0x0000000000000001}, {0x0008a0342c362ba4,0x0008202cf6246957,0x0008c4987d0b8dd8,0x000becfec2b48e0f,0x000a0d5c621a63b1,0x000668f2b6a90343,0x0008bd4fe098700f,0x0008bd8fa8829c08,0x0007948513f0936a,0x000733ae92e72067,0x0000000000000000}}, +}, +{/* digit=7 [{1,2,3,..,}]*([2^28]*G) */ + {{0x000f8517a4c96e5e,0x000b0e039e54c124,0x0001ec83d522549e,0x0008ead8eb02627a,0x000ef95771e9618a,0x0004f3a6b4497c2c,0x00055a41c4917c7d,0x000be8babd80080b,0x000548c7990585b7,0x000c64dabe54a06c,0x0000000000000001}, {0x000269bac978d382,0x000c6bdf9b98b02b,0x0000247e075c4ed8,0x00030716d8e1a299,0x0003a019c94edbc8,0x000c1665fb3458f3,0x000e700cd4d82fa9,0x000a2326e507ff63,0x000452b8341c9bbf,0x0000dfc9214a3f5b,0x0000000000000001}}, + {{0x0001109faf34910d,0x00006e16fb098733,0x000f23db2247dc5b,0x000f53ef62c76a0d,0x00018f68431633f2,0x0003cbe6a9413972,0x000253b6d05ffc26,0x00047ed103a8b14a,0x00089d6938ee0b45,0x000f4f3310d7c6f3,0x0000000000000001}, {0x000ae5ea5e61f0fe,0x000803eba63d9ee3,0x000ff5d7d44281cc,0x0006da525a289454,0x000688b5bf3e7fa2,0x0006c91ab88b9a08,0x0009907565a2877f,0x0001737c021210a3,0x00031db551223d6a,0x00041419f277aae1,0x0000000000000000}}, + {{0x000ab41a098c92a7,0x00072fa6811333e6,0x000851f03fd8fe3b,0x0008e34493163c43,0x00028174f0009cb6,0x000db83d4e177695,0x0004d1bfc734499f,0x000c56272647cc55,0x000d38b2b770d722,0x000fcea5c023f6ae,0x0000000000000000}, {0x000d52df57e5ca52,0x00065ec98ce0bb77,0x0002140495f37162,0x000d03a5ffc6d632,0x000f0d0061a4f743,0x000af61ada3e0094,0x0004b70091a92992,0x0003fe83591d84a0,0x0008b7e8b2e59f37,0x0006892e459b7561,0x0000000000000001}}, + {{0x0005e28d077485e2,0x00020e97a1a0b220,0x0006679b5d8662c1,0x0000da8bd256806d,0x000925177882d56f,0x000fd447d9b3a0c2,0x000077e15eb4fc81,0x0000f15d98b7d44b,0x00021ac9944ac5bb,0x00096438b1a53927,0x0000000000000001}, {0x00015ec8db3161c2,0x000f397c19309926,0x000de0771a46014e,0x00075e027929bb3e,0x0009dcd3fad002d9,0x0008c634c3d387bd,0x0009c3f4ebf24793,0x000a2c2da2b50807,0x000e85151e2b2209,0x0005f4bb80ad2ed2,0x0000000000000000}}, + {{0x000d84a6577d1d88,0x000209b195d9875f,0x0007dc25315ab09e,0x00041e59650e28f1,0x000f81b07fd77f04,0x000191d3288a8ccb,0x0001838964e3273f,0x00014aa2bd5786f8,0x000d924c29c83190,0x000d240eca2dec17,0x0000000000000001}, {0x000c94cf500620a8,0x00017a01ff5bfc59,0x0001d4396ff8b7cb,0x0004fb6ee69226c5,0x000565facfed55e4,0x000fa0b30de43edc,0x000b20ea8612b643,0x00056d93e66dab8d,0x00098f9a9e46bfc5,0x000537cf26d7b09b,0x0000000000000001}}, + {{0x000ab3bbacf312ed,0x00003114377687ca,0x000ecbe360e1fdea,0x0000336e644349d4,0x000ce9701c97498e,0x000b970f76e36640,0x000d18aeb034f110,0x000d8c04737b96e3,0x000b828ff89d3a4a,0x000ceb091b279c08,0x0000000000000000}, {0x00002832632c0b79,0x000f06083c30b6b6,0x000d6d46a5784fec,0x00018a1a822c2ef2,0x000ffd16846c810e,0x000859c7f32abfb3,0x000410206687e5a6,0x0001a4731948bcab,0x0009310e425eab64,0x0006640ebb114d39,0x0000000000000000}}, + {{0x000759039c7a9d17,0x000c2d4dd47b8758,0x000c1f2cd883e5fd,0x0007f9cf12cfd22e,0x000b330c8103c8b6,0x000fef902907b0c0,0x0008540db26c476e,0x000e726a64472792,0x000b090ef761ac1d,0x000f96107e57dd18,0x0000000000000001}, {0x0004650aeff40f19,0x000f9022a822976b,0x000a5007e542efc8,0x0007e6336d263df3,0x000d3e6b563a86e0,0x000fc14e677c3dd9,0x0001920cf4b81cd1,0x0001cedaf8056af9,0x0006ebfcbc28b238,0x000af30ce3975f89,0x0000000000000001}}, + {{0x00090c95c3d0b9c7,0x000844b8f686b48f,0x000a746779417d91,0x000bd2f6b498e1e2,0x0002adf2e61e9354,0x0000db08d1aea1ed,0x000a497f347f08db,0x000c7871378402cb,0x000753c735de0850,0x0001f9ed5b707951,0x0000000000000000}, {0x000d045e45f819b7,0x00024591e83186d4,0x0002f07b1add4180,0x00067074059bab68,0x000ea2b0f371c1d4,0x0000e5f219b0e391,0x000f844f22e68c28,0x000679b7f960b058,0x0002502036ca9899,0x00028a1f63acdbd1,0x0000000000000000}}, +}, +{/* digit=8 [{1,2,3,..,}]*([2^32]*G) */ + {{0x00023b6569acb75b,0x0008bff580463d22,0x000bd3d896f7a55f,0x000bc35819d6f3c8,0x000fcf8dfdd32dc1,0x0007477a57a2786c,0x000a3b0ae5589b65,0x000806de5eae9f47,0x000782fcd93f2178,0x00096dd9479ee32c,0x0000000000000001}, {0x00029435cbeebc5d,0x000d8352a35de209,0x0004ce809af5b11d,0x000a76cf080ab8c3,0x0002250478b1ce25,0x00003b3ff7216bfb,0x0004133d87f47621,0x000a4132748099b3,0x00029b68995f627a,0x0006fb62b3cf30a7,0x0000000000000000}}, + {{0x0009267d43d108b4,0x000b5b0396f4d947,0x000b1e5f7f088692,0x0009c3c1fd9437e3,0x0006cb9b9b7fa950,0x000a37b6c115a75e,0x00062d05b42f650b,0x000d5b3cf510dbbc,0x000a49bf06d5fe62,0x000049824e6593c6,0x0000000000000000}, {0x0007f70f36b1fb53,0x0004a3eb94fc53cc,0x00082c0e60f6a2b3,0x0002888aea4bc9d4,0x000d37ab9ed318f4,0x000a505ae0c0fe3e,0x00082c9e94fad3b1,0x000efa0f31285453,0x000bd4be69ae4fb8,0x000003a516fe8844,0x0000000000000001}}, + {{0x0005e8088591d8c2,0x000c6e24bb4a7ab3,0x000968fd3709e47e,0x000d55e3e7d95582,0x000f8783f2538474,0x0003b454e19d35c0,0x000724c4578fbe58,0x000b98f51326114b,0x00090d99b97ee546,0x000691801229b8f1,0x0000000000000000}, {0x000e4a0a2aa86765,0x000aa08b19b4b67e,0x000c220cb11d4f5f,0x000c7d426ad0862b,0x0002dd7a63508ce1,0x000aae47773236a7,0x000cce936cda4ace,0x0000808ba7a0be3f,0x000c14a5b972c384,0x000887cda4655c79,0x0000000000000001}}, + {{0x0007786aa39096d4,0x000a4070017bccec,0x000926b1ae026576,0x000026855e810d17,0x00039def24d306c0,0x0008ac55c7d826c4,0x000b521e40f66cc7,0x000ae26697c9fbf9,0x000a75caf01aaaf8,0x0002a9d094aec346,0x0000000000000000}, {0x000a161f4c1b67b7,0x000e72cc3c7e5f99,0x000fefa749b88977,0x00063737d6e24cf4,0x000ed4607a910568,0x00017686854dcfe4,0x00011acac7bc09c0,0x000cc731394d9ec2,0x0009e4dd8ac76909,0x000bc7246fb612d5,0x0000000000000000}}, + {{0x000d5c2ad970ea88,0x0000eb7dbc22b4be,0x00070d534e1a9e33,0x0004b0eab21921c0,0x00071b3a90f4b6c3,0x00015ce8387fd7ac,0x000ec28efad61dad,0x000f792985d577d5,0x0009ac313d175e05,0x0002d86582a5f995,0x0000000000000000}, {0x000258f797f0af53,0x0006198f53a67607,0x0008e97661c802c3,0x000001f410140442,0x0003c270534a9c94,0x000a5333d3d840fe,0x00076ed16f99ddeb,0x00021b94ff80e532,0x0002761460189f70,0x00007bce48c909c6,0x0000000000000001}}, + {{0x00018e1640843ac0,0x000d435c11720f14,0x00057cebd3881c75,0x00023104876137be,0x000da25ae87bc97f,0x000052fc640f68c5,0x00027372b9f14882,0x000b4e854fcb3017,0x0009d3406b0f1a39,0x000e653db1df6886,0x0000000000000001}, {0x000c416fe50a1e7a,0x000c29b7a99148a5,0x000d660bcfe2e7c6,0x000630309213716a,0x0004b63e38c0d1fe,0x00033bb86d3923a4,0x00056213e592fda9,0x00080b360f884315,0x000db3b21dcd9fe7,0x000617bc0a7836eb,0x0000000000000000}}, + {{0x00035cd63c7c9de3,0x000a91ffca828c02,0x000b3e377bfdd504,0x000496682e625999,0x000b8af1c462d519,0x0009570d96676ec9,0x000bf815f3869cb1,0x000b476a8b4fba76,0x00057597ce654eda,0x000e2235375a2127,0x0000000000000001}, {0x000e9252adfeeb9b,0x000707b233b4a650,0x000ab158faa771d2,0x000df78fbc7a8536,0x000be88e5009a864,0x000abbc52635e311,0x0008769bd53cfa60,0x000305e36a566f93,0x0000e758e66271c0,0x000b10e12e9cdd0e,0x0000000000000000}}, + {{0x00092f38031c9da3,0x000f6f0dd54d0455,0x000298fe24144d05,0x0006274ae2d191b2,0x000909113fc1ead4,0x000dea702ccc54c5,0x00008c5763ea8c10,0x000635441e7274f2,0x00006b2f2578c573,0x000c3b8134369537,0x0000000000000000}, {0x000ada464a85cfcd,0x0006064c2605a588,0x000004bbf31d5464,0x00010805ca04e18d,0x00067998cccf9032,0x0008398a6f896278,0x000dacf8d2faed14,0x0002de01ea7eca85,0x000eb7d829278474,0x000eb89fe5859b0f,0x0000000000000000}}, +}, +{/* digit=9 [{1,2,3,..,}]*([2^36]*G) */ + {{0x000a73aaf5f01aa9,0x0009abe5e08d9505,0x0009fd8bcd318e91,0x000915895b386f06,0x0004a0b5abd07d68,0x00039901b007bc24,0x000ff05c36936913,0x0003179dcef7684c,0x000125196e69b799,0x000a2823db7308b0,0x0000000000000001}, {0x0008e83616d0d063,0x0003bf0c66e267f8,0x0006d375b822f9f9,0x000dc02109656c0d,0x000530c1fc16b6d5,0x0006bf6541ba81db,0x000443cb4caf94b8,0x000a87f59d3c1a6d,0x0002afcd60e10fe1,0x000a088d7e1995b7,0x0000000000000000}}, + {{0x0005b8daa50517e7,0x000dbed46676160a,0x00016e7a7e78dcdb,0x0008e1fc1b0f5e9c,0x000933cb9503e917,0x0006f78b36f2294c,0x0006ec3420442aae,0x000c01e17c7ffb2d,0x0007293b87d30fdd,0x00092836bed4739c,0x0000000000000001}, {0x00075943e2ebfd04,0x0007b784cf37b849,0x000645eaa02ab285,0x0000b0ace12a0d65,0x000ff267c93aa3d3,0x000fa6954230be3e,0x00001e1903aa7ed6,0x000c311ae0c82cdb,0x0005f0bd3c5056d4,0x00022094d54a9827,0x0000000000000001}}, + {{0x0001c0660a4f2bbd,0x000c3d2fe061f455,0x000a2b6dd7091d40,0x000bf7437cc4883d,0x000f258011ddabd2,0x0001bdaba7aee852,0x000195b39f463ce7,0x000efb33b881bd7c,0x0007d695aede085f,0x000380f8fa2471bf,0x0000000000000001}, {0x0006eeab983554b4,0x000f138a6f5a6dc9,0x000b29f154f07f71,0x0007d1c7242d7a9e,0x00042f3c7f1afb70,0x000af2896b44aee8,0x000b55601f569990,0x00061e36ed07c5c5,0x0005430facca2678,0x00016ea78eb21424,0x0000000000000000}}, + {{0x000aeaaabe68e207,0x00098b6eaee3177d,0x000f5c1267a6e353,0x00092ae2d01bbbbb,0x000bf3af1a4f4a2b,0x000532088e5cdfa4,0x000c8ee638a58f55,0x000bbce5e7aa2a0e,0x000a1644879c3f50,0x00025e378387c246,0x0000000000000001}, {0x00069ee8884e88e1,0x00090f8ec2984b67,0x0001f9e47bd62fea,0x000f9867e7522665,0x000cb916cb0493d9,0x000106987f5be2cc,0x000869c71156e1c1,0x0005011576bd7bad,0x000b76a6e945007a,0x0000aec18de41f38,0x0000000000000001}}, + {{0x0007c59949c6f67a,0x000c897a229d2368,0x000118e3e788aa53,0x000794e3080e973b,0x000815a91046f15c,0x000ac04ed530c0f2,0x00078a4fe35eb925,0x0001fe18e7070c54,0x000f409ce7d9c57a,0x0008aafcd17edd4b,0x0000000000000001}, {0x0002850fe8174557,0x00037e234694753d,0x000c528ec7d2c45c,0x000bdd41f346792a,0x00032ca964be2a36,0x000fef3e7911d679,0x0000101c72673a03,0x000653d6358ef0bc,0x000f874e2b9caaba,0x00045ebbcc31882b,0x0000000000000001}}, + {{0x00090baa505384e0,0x000993148d7d8454,0x000d948464cae379,0x000f46feac4f8ace,0x0007268d1b7c8dda,0x0000d4770e6c39b6,0x000c1955967ac571,0x00052098b74830a2,0x0008d17fe1904773,0x000191e5071ced85,0x0000000000000000}, {0x000b4f003b56551f,0x0000872a7e419344,0x0001262c90a767f8,0x00015a9791770fa4,0x0001a4bc5606e253,0x000a665041696dd3,0x000da6d7ec137466,0x000cac07c562bd01,0x000c4a92e59de1e2,0x0007068f7d29994b,0x0000000000000000}}, + {{0x000172698b05a9bf,0x0000570dde3c4b9d,0x0004dad7e2ab8a86,0x000cc4fe376d08bb,0x000df2d396e50709,0x0008138716b38f91,0x0004e9a6a45d9577,0x000feda477817a06,0x0007062a4f79bf83,0x000ca12aff8e0103,0x0000000000000000}, {0x000748577bd0ea3b,0x00068ca23c2d1e49,0x00079fc968bdb9b4,0x000359089d5d5807,0x00037ae7478afb4f,0x000f6ac1a17ffb5a,0x00076fb0ad6d0956,0x0003cc73da4935d0,0x000b38ddd4e896c8,0x00091fcd942654f0,0x0000000000000000}}, + {{0x000d06bf88e947b1,0x000a0ca717a0accc,0x000b428946c6ceb8,0x000992652bd2594e,0x00041806882365c1,0x0004f2f3523a8241,0x0002e27b634a60c7,0x0006f4680f2b83ce,0x0005e159f3342680,0x00053718c76ca148,0x0000000000000001}, {0x00063dec4e0c9dd7,0x000cb7d74bb74e1f,0x0004a5f09446f95c,0x000f4555c75d0662,0x00028d6e7583fd36,0x00083fa30323cc2b,0x00010012c0c49bb7,0x0009907cd3d64f77,0x000c79e69ac90f89,0x0006c12cb352bde2,0x0000000000000001}}, +}, +{/* digit=10 [{1,2,3,..,}]*([2^40]*G) */ + {{0x000bc2a7fe05ab80,0x0001a246f49f7a93,0x00091072db7cc0b4,0x00011f97d30ac7ec,0x000169de685e7537,0x0008a2ae9aef0acc,0x000e3c46bded4c6b,0x000604789cdc4497,0x000a082feb2b2ea2,0x00078fe890cba4fe,0x0000000000000001}, {0x000edbc5c5076824,0x000298a472aca466,0x000a80660505ad15,0x0000c1cc1b16ca97,0x000dda2937bbf38b,0x0002545fac4d56c3,0x00090f07e35494b7,0x0000903e9ca74b57,0x000b43111b0c8bc4,0x0005465923f9e9c4,0x0000000000000000}}, + {{0x0008b52bfb73ff4e,0x000a4d6410d489c1,0x000ae318bb528530,0x0004b71f3f7d7028,0x000970b21b686b53,0x00001ea2751f5995,0x0001322663379ddf,0x000e77c11915800a,0x000261c476db4bea,0x000ae8e89c22a1e3,0x0000000000000000}, {0x000e16965a7b1dfa,0x0009afd6426762fc,0x000532ec13f2e53d,0x000fe4131e801ed5,0x000c86963e2f9e9e,0x000f46e5098aecc3,0x000faa2b47801a35,0x00043b6f3406c3d8,0x000b57971349f37b,0x0007d749ef39f4ad,0x0000000000000000}}, + {{0x000dcaceb126ca58,0x00046c5a73dec3f9,0x0000e0ffb30d8879,0x00026935e7e62831,0x000f5e074c83b841,0x0008b04291158a7d,0x000f72a08eaada21,0x000a40d05438fa20,0x00005e6ac9aa8c4a,0x000b92b755928484,0x0000000000000000}, {0x00081326c74e90da,0x000cdbf1a037a879,0x0009887e29013ab2,0x000ffd6598bd3d86,0x0003b3c803a95fec,0x000e4c50722fd839,0x0004e70129b699c3,0x0000fa72cdd65e3c,0x0000ccbba65f24da,0x0008975325682f6c,0x0000000000000001}}, + {{0x0008d8231d21b98b,0x000f46eede07ff72,0x000c57dc8bc52ba3,0x00096a93bbd28782,0x000609e0a7a0e49d,0x0009fbe4aa495765,0x0004c5f79dbfb8ae,0x0005e1789960cccb,0x000b74da3d25ebfd,0x000c2e56df642b09,0x0000000000000001}, {0x0007057a2be83a30,0x00026ba759ce4dd1,0x00057744ef0ab9d2,0x000c9ee2b7115a63,0x00000d77f24c2ddd,0x000142ea1adfee89,0x0000f3fa9d5346a2,0x0007a84ecd7e6d50,0x00035caeb7a1527e,0x000c8110e6262dae,0x0000000000000001}}, + {{0x000457989aea7c3e,0x000a16bd6196a6cd,0x0006f76c2cbdd85c,0x0005840dcfd847e9,0x000ec8ea001b3aa2,0x000898be24444e27,0x000397d8a0c53dda,0x0003fa5f98a5b3e4,0x0008e197364ea986,0x000bbd922c6bbfbe,0x0000000000000000}, {0x00064b7db5084e37,0x0008c954735a1906,0x0007371d65a99056,0x000bdaf052b4c902,0x0009ec2cc9668600,0x000adac668469729,0x0002f7ceb4949cfb,0x0001eda14ca03327,0x0009270923989fbe,0x0002a80f1714c9d9,0x0000000000000001}}, + {{0x000da9fadd2d2e35,0x000ebe39d9c06e00,0x0007878b1c269b9b,0x00045c0350e16aa4,0x000d604f7fb31a05,0x000233dc435d57a4,0x0004a59629977c5d,0x000caa747e5387e5,0x0006980680cca577,0x000c7f3aa2473480,0x0000000000000000}, {0x0006ecf72ff177c1,0x000ea087d84398f4,0x000f8e3dbad5b5e3,0x000793b7c29bdf29,0x000d48b4ad4a2c86,0x0004cf9d25337e0d,0x000be01c858ea723,0x000fe90a676bb282,0x000306f507590c7b,0x000915155053c47d,0x0000000000000001}}, + {{0x000311b42bb970cd,0x00056fa08e6727fa,0x0006285b2f7609fc,0x000807c307ce1a3e,0x000d8c9c1df6de94,0x00070b979619a317,0x000fdde052a3379d,0x000baa7d20b3870e,0x0006e443d8f7406d,0x000355511beafebb,0x0000000000000000}, {0x0002e82c90634dd6,0x0002249d51e499d6,0x000615ca9d89995a,0x00097ac7d99162d9,0x0009551034000ab8,0x00070ca9d924f35e,0x000b526853be7dfb,0x000638dc8c8aff11,0x00031fb01463b8a6,0x0004e7b55e740433,0x0000000000000000}}, + {{0x0008d4f13a03485a,0x0004c5dd3ccf1850,0x000d8ab1776f2552,0x000a54a5e0bf0c9e,0x000e81226e24a017,0x0000e5b1ecb9626b,0x0006acb8b7b3bc5b,0x000414da0130f24c,0x000b2f1d94673605,0x0003ae73af8b9c7d,0x0000000000000001}, {0x0001a4baf806025a,0x00068cf7b99ef6b1,0x000b70549901e9bb,0x000cc5d4a5ca0071,0x000b555009f7be57,0x0008dbaab6501aba,0x0005c582d17b21b0,0x000d9921c7bacde3,0x00013fb4b9991c48,0x000d72c6f664c93f,0x0000000000000000}}, +}, +{/* digit=11 [{1,2,3,..,}]*([2^44]*G) */ + {{0x00000e09c15f3e5c,0x000f97f45b409fb9,0x000ff4a01087837b,0x000d204b2bcafcbc,0x0000a0da165ec6b8,0x00011716978423a6,0x000f2f7f8295351b,0x00081f58e2d13eb1,0x000ed84592b66922,0x00025f5f9819aebb,0x0000000000000001}, {0x0007ea077d668278,0x000b9653ee2ff77b,0x00098e8334b5b359,0x0005210487baabe1,0x0001a95a5886c85a,0x00009649f4c23788,0x00056127f95c6f68,0x000aed6c6419d339,0x000be49aa657d29f,0x000da67ae0b376a5,0x0000000000000001}}, + {{0x000fb32bacbbde73,0x0004f08a721e3545,0x000584020b45c467,0x000fd3a284a774fc,0x00004477afffeada,0x0006a2c4ec266e10,0x00066dc326c6652d,0x00070b3a65b94280,0x00055b8104c7d5c7,0x000d8c4b6af237e3,0x0000000000000000}, {0x0000b97b7ca1cffd,0x000435de1358221c,0x000876cab38cc7ac,0x00054cdc8f30b09e,0x0000ccb3a4f5aec6,0x0002ac30ca26a9da,0x00011038e2a6fa3b,0x0004545c20a577ee,0x000bff8e2f50fb14,0x00093158359a6d97,0x0000000000000000}}, + {{0x000b8fa7bdc8384d,0x000f2859e636e718,0x000ed301cc9c465c,0x000006a5b105b2b7,0x0007075698827d1b,0x000fbe7e34565b30,0x0006110c56ecfa0a,0x000be3136324ecec,0x000a684fbfe59f06,0x00056bc39bf313cf,0x0000000000000001}, {0x0008543e894e8a16,0x0006d339681c386b,0x0001fc0aac97005d,0x000c6eaa38aa9f79,0x000a90d6089956c5,0x0005ec33374fdc05,0x0007a4eaa1631484,0x0008df64f8ad9e1c,0x0007f44336b984af,0x000859e7ad53b8dd,0x0000000000000000}}, + {{0x000c8ba9ccf89d24,0x000874ddf8d1b9b2,0x00027291ffd7f24e,0x0008bd9d563287c7,0x00065d01bdb48d02,0x0001b99b973b0c12,0x000050d618319b97,0x00038420d531f686,0x000d7c201c411c3a,0x000d97468eb84cae,0x0000000000000000}, {0x000eb2fc05bf609a,0x00073e1dab9da1f6,0x00049847c3ac275b,0x0007880554d322f9,0x000fedd0cd2b7f05,0x00085bb3e74958ea,0x000fcd8d9061a481,0x0006f9ac370d5c6d,0x0004cb188a021786,0x00057aa132c3b5f5,0x0000000000000000}}, + {{0x000a082d83368da6,0x0009c04ba3a92f9d,0x00018e366fb4a189,0x000dca28f8a4aa8f,0x0008c98efdf41b12,0x000e7f6ce11df724,0x0003850179926b22,0x000c0fa0bae8aa29,0x0007fa3acc87191b,0x0008222f18a88f29,0x0000000000000001}, {0x0009dda00370c8d5,0x000720c0497d2a02,0x000cdb5a6b3dc411,0x00032f0daa73c7c9,0x000505d3784e14b1,0x000d7b77b06edb5d,0x000c1f94b45f2c9d,0x0003193f38ea4c8e,0x0001706f6af3bbf0,0x000f0df22ed99a0b,0x0000000000000001}}, + {{0x00097825d9e0b2bb,0x00096d1340276af1,0x000d82fe6324bbcc,0x0000475ecad6233b,0x0009a0cd8d04ac29,0x000e8e067d738cce,0x0004317aa038ad08,0x0009a7ce55aad83e,0x0006a1887d5e91f4,0x000a135efeae9285,0x0000000000000001}, {0x000fa0b6a035b085,0x0005853d153ead9b,0x000ca7f6fb4ef7bc,0x000bfbb30b798e2a,0x0006653595cf1f8a,0x000774e7d1791820,0x00048df862d39281,0x0002db1e40868b45,0x000153b336e38fc5,0x00052ce2e4b80e72,0x0000000000000001}}, + {{0x000306c918831eac,0x000de7b8556b1913,0x000c579621fb2237,0x0001fa1088e011f5,0x0007511558db4265,0x000c63131310e896,0x00029cec356a91fc,0x0004b85a2f85b7d1,0x0006bc4404e3b5cc,0x000ac5c4fcc3a6fc,0x0000000000000001}, {0x000498b1e054105b,0x000818b7c971dcbb,0x0006cf66f8ee2eea,0x000fa05b49db517f,0x00012073a35daeb3,0x000d5bb674f202b9,0x00032d411842792d,0x00076cdcc487632e,0x0006568c96ca8dd3,0x000ecdfe1c986f51,0x0000000000000000}}, + {{0x000595043dc23233,0x0008d9e1b752f3f5,0x000f6e2b3641b931,0x00064e0f5c02bb70,0x000169d8f287038d,0x00062f3a1b075424,0x00001bf3b8c6755a,0x000a2b642127d597,0x000c17f0c20fbe8b,0x0005263410177dfa,0x0000000000000000}, {0x00008cc560c65efb,0x000ef6706807502b,0x0007a1e8980e532c,0x0007963729a4a8b8,0x0007ccb3a4f193b6,0x0002e07ae80043db,0x0005be0346fea839,0x0009ef33f7a00da3,0x0001ea778cb41f4e,0x00096ebb760e7727,0x0000000000000001}}, +}, +{/* digit=12 [{1,2,3,..,}]*([2^48]*G) */ + {{0x0009ba658c1f9460,0x000b18b48e1df3f7,0x0005fc03a103eb15,0x0001ad263bed592a,0x0000a127b78a3359,0x0000337c7b07e9d8,0x000d2a0349dd74fc,0x0003b1a807c5364e,0x000d92cca588d420,0x000d9e772a1716ec,0x0000000000000001}, {0x000fc1df3f66f295,0x00015742d25980f6,0x00036f0fdb08922f,0x0001fe47a583206a,0x00001c73f88168cc,0x0001b777671d2798,0x00068317ac8979ce,0x0002a98b48363dba,0x000f36b7460d4015,0x000da1c3d46c62c7,0x0000000000000001}}, + {{0x0001fb046e7fab2a,0x0000e190213473d6,0x000cbb6e9b84f9db,0x0008fb8a36fcff78,0x000c47cd5e9d16aa,0x000c2601e9337a00,0x000713efe8445d72,0x00030681fd15bbab,0x00051cff90b2dd23,0x00024900ab444b21,0x0000000000000000}, {0x000de9a880ca8289,0x000e3bcb8ede5206,0x000e1369e32209ab,0x00036516b711e224,0x00025533569db531,0x000419656e59d965,0x000ee21f2d680255,0x0001d59bb004326e,0x000bb722c073cca7,0x000866aa784f931c,0x0000000000000001}}, + {{0x000d262bb3ca8da3,0x00045288c7563397,0x000d10c59451797d,0x0004e594575ac7f4,0x000311006db0bd6b,0x0004d6485bec56e6,0x00089e23442953a9,0x000610efbe7ae598,0x000f1a0f166d5639,0x0004e5f91e0ed7d5,0x0000000000000001}, {0x000aca95d51d383f,0x0000d23ae1d67e17,0x0001b867b62738a3,0x000907e6a529f72f,0x00059335e44e6986,0x0001d5fbd59c1e58,0x00018393e6789776,0x000e5bc878acd1b0,0x00059b26328cd9f3,0x000f3d83306eef44,0x0000000000000000}}, + {{0x0009313593b1d240,0x0003b3672b4b0a51,0x00078ea42e614acc,0x000784cd22fe0a9a,0x000a6c20faf43e72,0x000e49f3038f9c3e,0x000fb914c50987c5,0x00000c76e9b912d1,0x000dc2b7b96a89b9,0x0008de238b29a074,0x0000000000000000}, {0x00068ea377031f72,0x000e9606adb168ca,0x000e58dde885ecba,0x000177424d422e92,0x0008aa609937ceba,0x000f30fc81145199,0x000c9f99eba807b8,0x000e200db6e7a724,0x000db2dc7651c126,0x00009cb58e38f0c9,0x0000000000000001}}, + {{0x0002dda36b654cc9,0x0008acdfcec83248,0x000164e7c3c6f06e,0x000ff27341f98b3f,0x000b145595e7208c,0x000f8fbf6e4d7416,0x000a519d6e691f26,0x00082c10e5fd7be7,0x000b1af42c760524,0x000f36238c97dbcb,0x0000000000000000}, {0x000a3b8e5e8a7251,0x0006fabc0a713664,0x0004fe41fe20cb31,0x0004067dc2b00d32,0x0004fa30d7f12a4e,0x0003f79c759905ca,0x000ef9b323da1724,0x000357ea84efa0af,0x00083350488b839e,0x000408f03e5cf22c,0x0000000000000001}}, + {{0x000e616991835801,0x00028f75d4e1a857,0x00031b04bb8869ad,0x000fb7737091410d,0x000cdd4fad2e164a,0x0004c7cf900934ac,0x0009b433f8948c75,0x00028687541974f6,0x0008f0af013f8d2a,0x0000b59eac62d398,0x0000000000000000}, {0x0000c23b25d034e1,0x0007d927e7c611fb,0x0007596a05e54d05,0x000f8995596eb4b3,0x0005b26be4690555,0x000ae1277dbebe99,0x0006bc99c064aa3f,0x0001128fda3fad13,0x000cd244392bf3eb,0x000a481bf8fac406,0x0000000000000001}}, + {{0x000d8f6c1e9aa431,0x000e3d32dbe1679d,0x0006391e1828c205,0x00026f450a2821e3,0x000a00cf3fc9e32a,0x000a2fc5a7a744f6,0x0006b70facb792c6,0x000e8edf92ab0b29,0x000d53faf8f11ba4,0x000b1e87f01ff5b4,0x0000000000000000}, {0x000e6fdf30e29338,0x00014840cefab311,0x000c4e092d034ea0,0x000be36bee8c5b8d,0x0001f39e2788cf85,0x0008f32c467a702e,0x0005e353cc3b7917,0x000f137377576e06,0x0000db55d1c5fcce,0x000d16e9cd523a0e,0x0000000000000001}}, + {{0x000e8870b81dfb8c,0x0006908ea654a671,0x000c3eb3660a23dd,0x000daf70673dbdf6,0x000c19bbf5d38a5d,0x000fe1371d1e7af5,0x000e30bcc1eff610,0x000f1308bdd31572,0x0000db70b20ce33c,0x000e036ab6b3edc6,0x0000000000000000}, {0x000357b86d4f22a6,0x000b893ce6e16bae,0x000a3849b8d94e06,0x000e1675b6058ad8,0x000ed6add0f99ace,0x0003cd380c39df12,0x000e2335c645ff14,0x000994a0f6180481,0x0005a52a4c84b4bf,0x000e9849a710f480,0x0000000000000000}}, +}, +{/* digit=13 [{1,2,3,..,}]*([2^52]*G) */ + {{0x0002ea2996fba378,0x000cf933ae1a32c4,0x000b43b79b9d0dda,0x0002636c30561bd9,0x000f9122413700ad,0x0005a779a0d830de,0x000580fda5f65618,0x00067e785d8628b8,0x000ce8b188bafa8c,0x0006d2c75df63d48,0x0000000000000001}, {0x00090afd2d7e01b7,0x000e57c72b304c5a,0x00040d7dec21b4b2,0x00094cfde0f45d07,0x00010aabbfa713eb,0x0007fa8b4fae1b3f,0x00047d2b080d24d3,0x0001142abdb36f64,0x000470df72045350,0x00047e76e433f8fd,0x0000000000000001}}, + {{0x000081cbd682dd91,0x000d2c1433b543ad,0x00094641d2488d8c,0x00036e702da0394f,0x0008248288ca4d8e,0x000112c8a6461fe7,0x0004a486f063613a,0x000f77efb66bb862,0x0006e8d41511d90f,0x0009a1ce80969401,0x0000000000000000}, {0x000feced91fc3935,0x0002e83ecdac7136,0x000ee8e2857921f4,0x000ef9bbe82b293d,0x000bd182b25ab2c3,0x00097ad819ac32f4,0x000916b74b598de2,0x0004d5e666a5dd15,0x0007be0b151456a2,0x000b794dc25c5c44,0x0000000000000000}}, + {{0x00087c377c23c5aa,0x000d33ca314119f6,0x0002512d0943eacf,0x000f9fd69c0e1850,0x000b7c3c6ea7ee55,0x0006291556c20685,0x00053374868b07c6,0x0009f9f339d7b589,0x000d6855b9238a10,0x000491ac6af37f75,0x0000000000000000}, {0x000b5d5b2f49812c,0x000855e7603bff6e,0x0008f73b087f7552,0x0005c0adc19b7320,0x000d355df5442e8f,0x000a4b8876b6aeab,0x000a7378dc2b22b3,0x000c26f89265f8bc,0x0006645f23dbb040,0x000f38b09ab1bbfb,0x0000000000000001}}, + {{0x00011ca0d8fcc245,0x0008ea92267e1494,0x000bbfcc2abb385c,0x00029656bfd56d29,0x000075f2180a734b,0x000dc3400006f728,0x000f754023104376,0x00021bae73e6854a,0x000a8d2ddbc75324,0x0003d711770a3406,0x0000000000000001}, {0x000476594b8d6365,0x000aedeb8cb49714,0x000c86324ad6ba99,0x00016428c49863ca,0x0002a2e5cfc3d8a3,0x0009adc3e0cb62d8,0x000eff79e5f3fda7,0x000eb4f990b6cadd,0x000b0e410ae15a98,0x00000aedf394c7b9,0x0000000000000001}}, + {{0x00021de1984e2e65,0x000603254887ed1d,0x00087e7535512fa1,0x0006f4ddde7dd7d2,0x000fd9cd7f2faac0,0x00009274ea570744,0x000b8cb9c92e3b10,0x000294aa3ad7752d,0x0001e25f444d43f5,0x000d6a378f2a4af0,0x0000000000000000}, {0x00007294901179cf,0x000fc01f2357da9c,0x0003c6543ad3aafc,0x0004db8aa97c6078,0x000dd86b1f882854,0x000e842c5d55c6a1,0x000e30c9aff1c67b,0x000d71107c0af546,0x00097038444a87de,0x000d8c2bb6354272,0x0000000000000001}}, + {{0x00086f90f323a729,0x00082963dacbf625,0x0004056ab9d5b07c,0x0001d30212e37a0e,0x00065da9a3d1070f,0x000445a33677e429,0x000c39a6aee3c700,0x0006b968d6cd0279,0x00098776415f9a3e,0x0007bd59dc1684b7,0x0000000000000000}, {0x0005cafc1fb833a8,0x000b18657b2cb0ad,0x000af58b0bf123c6,0x000acc1e7ceb4334,0x000e5575f0e10ca6,0x000d22916c7bc194,0x00097f735880fd80,0x000604a86980d5b3,0x0002f218f0f8d8fa,0x0000806dbeec3ed6,0x0000000000000000}}, + {{0x000b6c1669c31b94,0x000b37bb5eb33b20,0x000f2f86abcd3194,0x000093b3893ef395,0x000d0b48537fd7dc,0x0006863b5109af48,0x000cb076c2fca9e7,0x000fc785f088e6f5,0x000c88facfd552fb,0x0001054316685a3b,0x0000000000000001}, {0x000b6af5d1972479,0x000ccf45d30e213b,0x000db2b3881288b7,0x0008f7bff9008ba2,0x000607009e5be8cf,0x000e10b176da0a78,0x000522cf433a33d0,0x000090924737e4d8,0x000cc0a11c296771,0x0001fd3715d11b75,0x0000000000000001}}, + {{0x000c391c2f2938b1,0x0006b396d1c5f420,0x0006bb17f5eeaef7,0x0006a57b7feb16a1,0x00026cc8015523f1,0x000ded6e6d4aadf1,0x000f602e23393c9c,0x000e2c8dbcb36848,0x00011e23c49f3a9a,0x000730c0c1ebfaf8,0x0000000000000000}, {0x0001b88cdd5da561,0x0002fcb4c22029af,0x0009624d6d5aa7f2,0x000db935bb120735,0x00019a8308449416,0x000467f9f185fd32,0x00057d8b4d3e00fc,0x000e187052a8a69d,0x0009e66380528c91,0x0007a42a603bc9b7,0x0000000000000001}}, +}, +{/* digit=14 [{1,2,3,..,}]*([2^56]*G) */ + {{0x00026efe1474fe09,0x00029da3ad38a0ca,0x000ec34abeaf5cd5,0x000847ac94808b1e,0x0001587ade96127c,0x000a43fa8cfa6df2,0x000bb39bcfdb5ad6,0x0005dd4d0c9f947f,0x000772a4ebca687c,0x0009227d79e215e8,0x0000000000000000}, {0x000926e1c81cb032,0x000ffdb04fbc5abf,0x00034707ba5b9c12,0x000a347c4ee8c89b,0x00072367a152d81a,0x0004511a3a4cd565,0x000b8f1a66429397,0x000260ea13e9d0e3,0x000a19a28ee14ab4,0x000d5dea76ba4c81,0x0000000000000001}}, + {{0x000f1e1b3fe2f1a3,0x0006da87421ab9af,0x000a3305ebdbbfcc,0x000cb7784b75a8e1,0x0006a4410056f8f4,0x000ff65612b5abdc,0x0004b1cd83f32f54,0x000fb989d25121c4,0x00014abed80a7bb1,0x0005ba8f200e1152,0x0000000000000001}, {0x000fb8525d63a07f,0x0002a4f5f23c02f4,0x000405911d9aa8e0,0x000dae0345abb8b1,0x0007b4834d14e7a6,0x000b31fdc5462195,0x0005dca7cbf9b75e,0x0001ee84304e26ee,0x0006a2c7d37349cc,0x000fc85a34c3afcc,0x0000000000000001}}, + {{0x000cefac8c58a5d9,0x000939b188506808,0x0005985dd6ee8422,0x00094a64ab14cf0e,0x0001ac27af983cda,0x00024f6eafd12785,0x00025d8bab20f8ff,0x0004a549d9c6da3b,0x000f18f37ed810bd,0x000655f630e4c95b,0x0000000000000000}, {0x00018594e51ad76d,0x000d8952697460ae,0x000aec56660f8de9,0x00093a39294777cd,0x000bdf7dc98fde3a,0x0000c53dc363fcc0,0x00091985d2c2708c,0x00093692d05055da,0x000c4d312ebcde24,0x0000c18d0017f5cd,0x0000000000000000}}, + {{0x000a3f86e5f8496f,0x0007f32df7ec8ea1,0x000d8551991f1f8f,0x0000f4eeb16ec397,0x000f5ebe5be1abc8,0x000f8233b8a1e6cb,0x00037675c403702a,0x000cbf97ecb04148,0x0006555682899a5c,0x0000280720d39958,0x0000000000000000}, {0x000312054dc27af9,0x00074dd550df7288,0x000193eb1e2f87e2,0x00073656a715c43f,0x0006ecb67dce2977,0x000aacb5db8a585c,0x000d92a6332fcd10,0x000cdeebccba4f16,0x00036c8da2b8001a,0x0007817b62765789,0x0000000000000000}}, + {{0x0002d6d084e03d59,0x000c244d84ecf179,0x000c93fa7f1e0110,0x000f695cc72b1bb4,0x000921730f1b2908,0x000b0b36b38d0bc6,0x00029c0e4bf469cd,0x000c1d41428da1db,0x000d1253d7a577f2,0x00006a23b655222c,0x0000000000000000}, {0x000ba5fbd7ebe31e,0x0005209808ec8aa4,0x00049718327a5383,0x000bb2492c210a5f,0x0002eef53e1dbdc5,0x0009d3c1717e38e0,0x000d4877b41e983c,0x00012d8aedea3a07,0x0007e058b6c0e3ba,0x000fd022c8be6da1,0x0000000000000001}}, + {{0x000870ab98aeb123,0x000044a353002cf5,0x0006150f34fa12da,0x0006eea20086b83e,0x000a0a2cdf13169e,0x00028616b25e80e0,0x000c5982d13e0cc5,0x00019702e01a4a67,0x000b60ef183d6e66,0x000a1f6f9172f815,0x0000000000000001}, {0x0002b57766386476,0x0001a0e6acc5477b,0x000ba422b2405581,0x00090991a9873020,0x00045310acf2c8c9,0x0008701ea796459d,0x0008c83917c30ec7,0x0009db51be44d168,0x000514c3bb42ce9e,0x00048d0b03fd870b,0x0000000000000001}}, + {{0x0007edbd640c9bb6,0x0001c6f483d72a01,0x00058a225c5b0849,0x000e8697568a7e71,0x00022821bf73d7fd,0x000c765e3aef4bc0,0x0001d2e8d1daf2fe,0x000772d486e7b59a,0x000595f951edfc03,0x000ffff1683f882a,0x0000000000000000}, {0x000fc53814c4cc13,0x00014196f30cc555,0x00076a3af64c6ce2,0x0009bfff339f5668,0x000ffe438adb5544,0x000aa59ae8f3c48d,0x0006c57ce59b5441,0x000eb7bdc7b7c0fd,0x0003b8e1d8e51d10,0x000d6a6427d57897,0x0000000000000001}}, + {{0x00005519264c8b35,0x00066ff272a08c1d,0x000142d545c343f7,0x000ef117b8bd86e9,0x0001c60c69c66860,0x000b54e53cb6de93,0x0000c9b9924f2f51,0x00030b949095878c,0x00016f5f1fba7e2a,0x0005817da79c3a69,0x0000000000000000}, {0x0006ad6babd55997,0x000be6d551de11e0,0x0006c45d4c33b3cb,0x0009e3dfcc4aa553,0x000821bb5c238e3c,0x000dfc012d05a1e3,0x000650684d8d4638,0x000805b7e2413b85,0x000718949cdcfd8e,0x0002efc1a85e6627,0x0000000000000001}}, +}, +{/* digit=15 [{1,2,3,..,}]*([2^60]*G) */ + {{0x000f6a9bd09d8e58,0x00004bdca0a6cc0a,0x000d9e6d336fe5f9,0x000c9d8bd87d0339,0x0003f4d463bab3b8,0x000203e46dfb629c,0x0000ef34ea62ed4c,0x000564035458998a,0x00069592c6278328,0x00081b3c56ebb377,0x0000000000000001}, {0x0009a17aab96cc87,0x000f8ed51ce44125,0x000c62b1c658666d,0x000b6999437c7966,0x0008f0fecb36474d,0x000f725b1f7c6099,0x000396c71fdafc21,0x0006a547fb5a5b56,0x000566ae79d88868,0x0000f4130033ff0f,0x0000000000000000}}, + {{0x000a6c73f41a4fd1,0x000bf46616431912,0x0009c6ffbd2fe4c8,0x0009e4fd42f313ec,0x000b9f8b100ba286,0x000e18229bbae712,0x000550161a1f1da0,0x0000032c80f2ffe5,0x000f0b1d53bfaa0e,0x00035fb83c760748,0x0000000000000000}, {0x000ed33353cf7a1f,0x00075b8b3c031fa0,0x00053c30e33c1415,0x000945a8fa62217c,0x000aa8b667de4f9f,0x000c4952fb889399,0x000b6e3b711abc77,0x000959e7e12fabed,0x00057ebfe5a1b2cb,0x0005344206e24318,0x0000000000000001}}, + {{0x0005f9c5a301de7d,0x000b800d937115a9,0x0004b1412c82ee0e,0x00039cf3df5a5904,0x00016cd50327ee6f,0x000841dfd19a796b,0x0005d79c493ac5c0,0x00097275eb2319d1,0x0003b6feb4b9d447,0x000542e1eb10df1a,0x0000000000000000}, {0x00051bac56d17f38,0x0007837a907c7875,0x00082e7d67e232dc,0x000c3c225acaf222,0x00056e17100c95eb,0x000198b234622502,0x0006b8a4beb3ba23,0x0005492d30351698,0x000c0dd28973e413,0x00031b2e1155d6fc,0x0000000000000001}}, + {{0x00014d7bc4df6981,0x000c45e951da151f,0x0003964143f3d397,0x00056c9c24be6549,0x0000ae1293e252e5,0x000bfda40e3aed33,0x000e72cdf82159a4,0x000f514f7b173b13,0x0000684bfa5b859f,0x000fce90812f67e2,0x0000000000000001}, {0x000a9abf7e9a0c25,0x000a823b0b3a0fbc,0x00011d2709072194,0x000b7a7f17f5564f,0x0007987f0af999bb,0x0009d6201796c014,0x000d35c45cce25a6,0x0009265843370c43,0x000a55401cbff6e8,0x0000eab503e2ea19,0x0000000000000001}}, + {{0x000caabc4b5cd512,0x00034cdeccde50ae,0x000395d24049ffdf,0x0005918925068e1b,0x0003f93fb9ea4405,0x000a60ba95d141ad,0x0005981c42f76f02,0x0005946bf800414a,0x000435023138c47b,0x000f3cf314147e38,0x0000000000000001}, {0x0008bdcc69ae19e3,0x000ac73cebd917e3,0x000c35337880966b,0x000e6ede2718c3e8,0x000fd10236ae833e,0x0004797bb14f5b88,0x0001296485e76bd4,0x000a68194c12b2b3,0x000b75dc1e45112b,0x000dd88574000b0c,0x0000000000000001}}, + {{0x00037d315eea24bc,0x000160f77a65b38f,0x000de27962237731,0x000bd3346f06ae65,0x0007a25b38b1587e,0x00055c6b9f2a1d2c,0x0002f34b1687394a,0x00054f27c66a0ccf,0x000866c84ecf3de7,0x000b4da4a0f4aaa9,0x0000000000000001}, {0x00066dd8b8dffeb8,0x000121bfeaeff003,0x000a80b5c3bfe941,0x0005b6a4c3fed2fa,0x000c623dfdf4718a,0x000b0791d22ef007,0x000949ccec61c6bd,0x0006e328d9cc6d79,0x00014a1530d03e69,0x000d45fdb36710aa,0x0000000000000000}}, + {{0x0006dcfa61a8d3cd,0x000ff977e2649373,0x000089ee4ac6af49,0x000b86d61720bd71,0x0007848d2c5df2f3,0x00078e07afbcc66a,0x0007ceb1f230a9ed,0x0000d2f61bf5077a,0x000770c3ffbf99e7,0x0001487ae5f08492,0x0000000000000000}, {0x000ee44c464c2996,0x000d8f990f4f03a6,0x000453774274aacb,0x0005c8730ef447b6,0x000e5e02e661f55b,0x0009f13f1011e65a,0x000f4c8fe17d3ed9,0x0000dbeb35dd393c,0x000a7d1cd2327711,0x0003fb444802cd65,0x0000000000000000}}, + {{0x00071a842f621fd7,0x0008594c057a1dea,0x000e1689c80fc8fb,0x00022f52adc9a8e1,0x00099c47b816309c,0x0000c495f00a960c,0x0002e200a0f356d9,0x000a87494b798824,0x000dcd587b7f9ca6,0x0009c4d76d2c396f,0x0000000000000000}, {0x00035970dd6ecf15,0x000449aee47a261e,0x000adfd394c8df13,0x000dfbec67553f2c,0x000aca43c615471c,0x000606556ef09db2,0x000a225f2e040114,0x00099dfb28da12ec,0x000812bc587a4c83,0x0001ab8cba898428,0x0000000000000001}}, +}, +{/* digit=16 [{1,2,3,..,}]*([2^64]*G) */ + {{0x0006146954276a1b,0x0000c171344edf1e,0x000b30130812b4a5,0x000314a14896c770,0x000e796a686592cf,0x00079226d890053f,0x000869a5847ac79d,0x000cf60993a83ada,0x000e4b5fe7d156a5,0x000add7850cdf667,0x0000000000000001}, {0x0005bcbb35fb3dea,0x0000a34e2d6021f3,0x00090be93989877f,0x000303404d6435bb,0x00007e5919257861,0x000c99d1992710c0,0x0001c7987d3586cc,0x0008e8681c58c145,0x00059a487fa896da,0x0009a8b1a9e54366,0x0000000000000000}}, + {{0x00029533273f3ddc,0x0009580b259ba7fa,0x000a4092fea94f8c,0x000efd38be9d56f6,0x000720f2ba425622,0x0007c0adb2a4d25a,0x00018752498a9ea5,0x000d893bbb4d11f1,0x00056b02f195ec41,0x000bca2ad72c4b2f,0x0000000000000000}, {0x000a4013f1ab7060,0x000f17521f983a0f,0x0005292b2f1ebae7,0x00075002debce289,0x00003b6cd203ad6d,0x000c3592c993bfe5,0x0005400a40b351b3,0x000e9b6bafed180f,0x000d6a9f0291283a,0x000563036cf95dd4,0x0000000000000001}}, + {{0x000efa3e474a5b75,0x000e5a6d55141813,0x00008a31bd3435d9,0x0006a68b3c599425,0x000252817b3af9bc,0x0006a695a37f35e7,0x000f06836ac1d6b0,0x000b19a92f525bb2,0x000215d9b8e544be,0x00080723f1554fe6,0x0000000000000000}, {0x000e709e6109d280,0x000e367fd7bcb2f8,0x000be531b1c6fe21,0x0002d1fc5388b64a,0x000c169c0609b0df,0x000cd0fc3d5f664a,0x0003de00815f78ff,0x00049af9ff38956a,0x000e62c250aedb30,0x000af977c662b6e7,0x0000000000000001}}, + {{0x000cfa5a95db7680,0x000cc333878665a8,0x000809b2a4ba5401,0x0009594f6cdc3f0e,0x000e99bbfac6790d,0x000d836074d551d6,0x0009d9ae874e847f,0x000a264b3b0b13f8,0x0003ac51f7a6ec5f,0x00021d6dd250c60a,0x0000000000000000}, {0x000e14abaa7747bd,0x000f127c3196cad1,0x00078a629241495e,0x000ded5d0cbcf8af,0x0005b83d56ec31f4,0x000c6ef029fa54b1,0x000cc516f0a12c6c,0x0000ce830e11ae62,0x000747fe9964fd2d,0x000c6756076a3288,0x0000000000000001}}, + {{0x000b9a69b333564c,0x000cec5ad994fbe9,0x00091ab4f5d4d95d,0x0004dbde503f2b0d,0x0003c8b32fed7498,0x0009fa10339bf799,0x000b1e6b4c7bd908,0x0001c54e64a99794,0x000598ef7979d915,0x000f29a322ae1bc8,0x0000000000000000}, {0x00042520c237fcf4,0x000303a14c0e24d4,0x000f7ed62c67df4c,0x000ee5dfd3635dff,0x00097bcf94654c63,0x000eb529e2ea1f28,0x000969c7cff702bb,0x0003bf0591306903,0x000474be25c3afe3,0x000d8f2570e7350c,0x0000000000000001}}, + {{0x0003d3d928f89c37,0x0004d9c668cfa4b7,0x00097ee2907da69c,0x000fb743bf4c3402,0x000cd4034c59cbf5,0x0009bc4b73d60ae9,0x0007664da82be729,0x0007e3800a84da1f,0x000700f12fb007b6,0x000882b546161eb7,0x0000000000000000}, {0x000e150bbd0f66b9,0x000122fc5d0def4b,0x0001ba0f43d660c9,0x0004e9263a5b4550,0x000ef33c24e5b722,0x000249e1b7ba92b4,0x000aa152b1856c8d,0x00095fe68108b2c9,0x000e766ae6e54017,0x000903a379f58c2f,0x0000000000000000}}, + {{0x000980153e2aed11,0x000ca0053853a90a,0x00003bf5f23c9661,0x0009061283e91bda,0x0006236d967ae1de,0x0004f3d80708ed52,0x000bb014e9c6763d,0x0002f3d82f09bad2,0x000f8d828de34c80,0x000187805c46ac1b,0x0000000000000001}, {0x00086a0c8fd9feb0,0x000d468bed15d861,0x00036573dedab729,0x000d88e4dce7ee93,0x000d9e86caa8e75e,0x000c0d08d6110fe2,0x00082b709f0b0d08,0x000ab3fbb5af39b1,0x000c1b7910befecc,0x00062bf43fafb941,0x0000000000000000}}, + {{0x0005341f232f3278,0x000c66dff5ad0b4d,0x0006270a82ebb141,0x0002897d7912e413,0x0006b6b16ad87fc6,0x000fe7c18f348f2e,0x000a03bae57af6d0,0x000a6d2d6ab02f22,0x00017c3e7efa7a28,0x0009c673423958d7,0x0000000000000001}, {0x0004f0f2ce49ed5e,0x00055b8c6c92190b,0x000aff1be7fa884b,0x0002c375de74b331,0x000f37a676c7d888,0x0001190b6b57c355,0x0009c95180dbbfa7,0x0001d7dc77b1599b,0x0007eba118f76648,0x0004aa840229ee22,0x0000000000000000}}, +}, +{/* digit=17 [{1,2,3,..,}]*([2^68]*G) */ + {{0x000507b4b3de6fe0,0x0009064574b533f1,0x00076eaa707b56c3,0x0005e98aa9532376,0x00034611c9b6716e,0x000eb6a26112d9a9,0x0006e068430b4789,0x000e50fd96103fab,0x000509b62d215cdd,0x0000b7c4da786d1d,0x0000000000000001}, {0x0002a0af86e4be0a,0x0008383ebf635e75,0x0009175f3f7680f5,0x000b999d9f1a0d87,0x0001f04cce1e2861,0x00086e6afd75ef23,0x0004476af7240e6e,0x0005e887f56c0473,0x00094ba352837e09,0x000f469e3dc524c1,0x0000000000000000}}, + {{0x000726e7d4a98265,0x000a397d1e874b3c,0x0008c78c755a513d,0x000fef1392677915,0x000e1e9e24f3ae62,0x00096cf6213d1cf9,0x00004b1f503d4fcd,0x0000f07e39bb0e12,0x000406c607195818,0x00046d3b7b9a617a,0x0000000000000000}, {0x000b43a8c35ac9c8,0x000a92f37f3857cd,0x0008ae49b6bed377,0x0000e3380827d789,0x000e2deff6865bd5,0x000758e466fdb287,0x0001f3ba0c560a0e,0x000db418a2645432,0x000aa26f5d44767f,0x000d36cc7b7f8bfa,0x0000000000000000}}, + {{0x000020f87c5aeb2e,0x00035693c551e0d7,0x0004a7f0938f3f98,0x0008d4d829ae419e,0x000d8e42f19ee358,0x0004d94560e54e60,0x000ddb20bc96b546,0x00014bfcf64c2c92,0x000518fec9517e43,0x000a92773a95b0b8,0x0000000000000001}, {0x000c159b5e61b250,0x00070c6538519060,0x000d0372c4dd1c2d,0x000fd8998866b5fd,0x000ceccabb79115b,0x0000eee1fb689260,0x000b839fc8378f05,0x000677dee33a7134,0x000b9326b080c62a,0x0003ae07e602129a,0x0000000000000001}}, + {{0x0000dde02f16a4fb,0x0001ca814d149b58,0x0003cc8c599eaa3b,0x000d833d43a45440,0x000afdba29de3c98,0x000b2ff2056e31f2,0x000ab3bf81e95cba,0x000649419f19b530,0x000585b648a6e1bb,0x000ff11dfbba1ed0,0x0000000000000001}, {0x0004734696bc60cf,0x000199c0250d4a2b,0x000d4759758b9f4e,0x000f68bc326d4e2a,0x000cea78113abc32,0x000d248f92840b01,0x000d61ebd87644ac,0x000ae9a32d38a8d8,0x0000c706b58a69c2,0x000561f4b942e16a,0x0000000000000001}}, + {{0x0002fe7e20769488,0x000a1c068b87a199,0x00032a3459c496fa,0x000e96c391b8839f,0x0007f4914cec7211,0x00039756176c58a1,0x000aa63441905f9c,0x0008ea16377fb867,0x00042578ce2a2865,0x000cd140c73dd697,0x0000000000000001}, {0x00074ef7ab059a14,0x00031e0f7d0f636a,0x000fea67e10b4430,0x0006ef5711a15a06,0x000f717856862153,0x0002513381cfd3a9,0x000a8b9906086974,0x000a08521bae079c,0x00052ef6a1d4b90c,0x0004f5ad24ad39a3,0x0000000000000001}}, + {{0x000c2d28a3a30e7c,0x000933949c694069,0x000d1f2a5ed527fa,0x000e2b5573d97d5c,0x0006aa892b500798,0x0008ac4418f1419e,0x0007bf2d1e227f12,0x000bc2143f4c8a62,0x000ae6ef99da3403,0x000679827f46143c,0x0000000000000001}, {0x000a8cba49268935,0x00038ccee58ce9de,0x00061df0ac493218,0x00075eb49225f314,0x000073000d3eb206,0x000145d79e65edfa,0x00007b1990aba7cc,0x000c916353a37685,0x000854a40d94fba3,0x000cb2e109e1b50c,0x0000000000000001}}, + {{0x0000c263771f69c1,0x000d1595543d358f,0x000ef2e3d8a56184,0x0005866bc8c3965a,0x00021c100a7748c1,0x00029b46541a4ddf,0x000c5cb49ea744d6,0x0007a3a96b8b1fb0,0x0005aa7e85061bd2,0x000163e83c339e28,0x0000000000000000}, {0x000102ac6923a672,0x0004153c3e1bd59a,0x0003473bcdaf9384,0x000f589da2a6c958,0x0003af0eb1a0311a,0x00041f50baac8d3b,0x000bd2c8728d9afa,0x000fc24b4e16e953,0x0003e6d4570ad37f,0x000aac57efaaa8de,0x0000000000000000}}, + {{0x0008c7fccb0a85bf,0x0003bdff198eec53,0x00029ee8af84ec04,0x000572ea125b846f,0x00025280cfc9ed01,0x000f73f2654ba803,0x000ffbf57e3b7be3,0x0004f83701a26bca,0x000d20a251a2d372,0x0003ec410f80b319,0x0000000000000001}, {0x000961197dc0e519,0x0003d8c136f93b3b,0x000000ba8d6c2646,0x00084f848d99824e,0x0003fcfbb42b20e0,0x00038715f781fef3,0x000bdd048ed10781,0x000042869724ca7d,0x000de2c203c66b90,0x00090489fab2c4cf,0x0000000000000000}}, +}, +{/* digit=18 [{1,2,3,..,}]*([2^72]*G) */ + {{0x00038bb0c7aa46ca,0x000d2cad2e37a158,0x00054d33ad65a28c,0x00004b20d4f1caa9,0x000b180e4c9d244b,0x00070a13f58c65ce,0x0008816ecff016c3,0x00016ad260aeee75,0x000dbb7b595c36fe,0x0002944d06dfe8bb,0x0000000000000000}, {0x000c325d67839921,0x0006a5955c2a22f5,0x0001664092579a37,0x0003aac4f8e9390b,0x000722a8dbf2236b,0x0007b02d94034f2b,0x000fcd8d5de86b97,0x000fa8bc9f80729c,0x000bcbc03be296bc,0x000364ec1469f11d,0x0000000000000001}}, + {{0x00048e2fcaa83f58,0x000495fafcc6105f,0x000d34073fc2c5d9,0x00042510321d1a08,0x000d83427742e304,0x000ec5f97b8068ff,0x000530da7faa8a52,0x00005d010e52ac14,0x000df5701f277a14,0x0000eacdd532283e,0x0000000000000000}, {0x000f566cbb172daf,0x00050c51771845f8,0x00066aafeeea7b0e,0x0005258081cf4ee6,0x000c71bc2c6ec8fd,0x000790d250232a19,0x00011bed4c06ab26,0x0000acd06e0bdc44,0x000734273e0fd2a2,0x0005c1c9fb738a19,0x0000000000000000}}, + {{0x000b6ef22ab96e69,0x00026b8cd18dc5dc,0x000563a07bc4111e,0x000f73913482455e,0x000edcb5ec4ad0e2,0x0000caacaf21483b,0x0000f16a5a48441c,0x0005bffbf280c9e8,0x000f37a7690242b8,0x0002eed954418691,0x0000000000000000}, {0x00066d6e31428479,0x000f47fc4b8794a7,0x000a81360ec38293,0x0004d77d31e9f867,0x00042db92af31be3,0x000d799976882df8,0x00005ddd34a906cc,0x000b961ddfb3abb5,0x000bbb326a3a37b0,0x0005d4f7af85a74f,0x0000000000000001}}, + {{0x0006d183b4b1bfc3,0x000143cdd1f50d0b,0x000721cf9d088770,0x000338fad247118a,0x0004efa498ee55a8,0x0008d9808733ff45,0x000faa72107a954a,0x000a392986064eae,0x0000c503bc385af5,0x00095cfc7e0cec3e,0x0000000000000001}, {0x000f6c1133ea5097,0x000685bf161ebfa2,0x000bb087e9c48b5f,0x000987c958eb481e,0x0001ea465a54c3b7,0x00081943446e92e0,0x000a8941e66d88ba,0x000d40dc6c71b0c7,0x0007f59a3690cafa,0x000130f02679ac05,0x0000000000000000}}, + {{0x000c5b4b93b19e8d,0x0001b316df16919e,0x000549bdce1a1a0a,0x0001cc00d06d528f,0x000cf17722a1d1b7,0x0009c7821f1ae098,0x00007c6fc2825a3d,0x000f796a6b06d5bd,0x0004ca4366a06040,0x00072103b88040d4,0x0000000000000001}, {0x00038b6ea0266cec,0x0003d4ff03eab713,0x0008f81bfb033aae,0x0004b58cdd700e03,0x0002486b62595d6a,0x00027288e5a75ffb,0x000043649c2c3428,0x00056516d9dc3a87,0x000145473b4564bc,0x000f9a0961272b27,0x0000000000000000}}, + {{0x0006ad885aea13aa,0x00022fbb0e237052,0x000115fb0a1aa034,0x000ccb8ce398278d,0x0004178f8f78a3bc,0x000403be5854a510,0x0006bcde0e2e720a,0x000edf5f632b7fc4,0x00038eed71d606d0,0x000d21f92dbc6d75,0x0000000000000000}, {0x000631ff7cd8f78c,0x000698475f524849,0x0005eafa796bd6f5,0x000fa7a4ee42bd53,0x000b8f8540687776,0x000540f9fdea3095,0x000f5bf17004e5b9,0x000834c440599d47,0x00063874f7c8a4ef,0x0006bec9a4f28185,0x0000000000000001}}, + {{0x000c12a0297bd390,0x00020c5821857743,0x000e07f2b528d6e4,0x000318df51deafc4,0x0009c03086d94e26,0x0004d01fde5e064b,0x00071c1d5855c1d9,0x000cdd2d762cca56,0x00022e583500cf8e,0x0003f52279b68b61,0x0000000000000001}, {0x000b572837258eb6,0x000b88af33e25ea0,0x000ba976e7082c63,0x0000d0abef5e06ce,0x0005c8fda6ac69af,0x000f82b26435f42d,0x0005ef9369e629b7,0x00029491bb2be768,0x000ae13ca4da59b7,0x0000f00ce8846bfb,0x0000000000000000}}, + {{0x0000079959682d5c,0x00076719e3233b3a,0x000c78c2194cd545,0x000e51d3c744ff86,0x00053afacd6dd789,0x00098cb1ba7a5cd2,0x0004fb918b560853,0x0009ff1bce38273c,0x000a7efa90ba240c,0x000ba73bb2e372bc,0x0000000000000000}, {0x0003a114b353d398,0x000d2df4adbd1d56,0x000e9ad940e90284,0x000fca7fe3af63ef,0x000de96feaa4e61f,0x000bf94ff4ba0669,0x0005279d7b8471ad,0x00071dda976e696c,0x00066b8800a22911,0x000f5fba44b58815,0x0000000000000001}}, +}, +{/* digit=19 [{1,2,3,..,}]*([2^76]*G) */ + {{0x000b896b5317311c,0x000ccb025efc3b29,0x000bcd9f85c60e34,0x0005f821ae29c1d9,0x000293dcc63561e8,0x000f95824c27219e,0x000843c9e01039f3,0x00048ef0f79fd3a9,0x000ddb5a3bba44b8,0x000011f0a7f5379c,0x0000000000000001}, {0x0000be31597dedd3,0x000aaa0d73669dd4,0x00090c605d60706d,0x0007d62f262a826a,0x0005e90997b0e2e6,0x0004dc73225ac29c,0x0008be39728fe4ca,0x00038656b7a746c2,0x0008bd5a3cf46a3d,0x00080a0c58ac7031,0x0000000000000001}}, + {{0x00070e2b4e96cd1b,0x00023ea39d68ac53,0x000f98a99040b26e,0x000362a9be557ba1,0x0003c202765cccef,0x000726d7b5a7731e,0x000faf8cd815e2ba,0x000ba6579cd91c25,0x000ec8fb3dafb2e8,0x000af4648049fac5,0x0000000000000000}, {0x0004b6251452046e,0x000cb296110b89a0,0x000551f88c9d1ddc,0x000bbb0b0f26d015,0x000c2b5bd39d39b8,0x000dc18ef79d52ff,0x000b527ab6d006e2,0x000a804f61d0142f,0x000be5992391511f,0x000815a3e717ea9d,0x0000000000000001}}, + {{0x00029eaddc553333,0x000212246b16c20f,0x0009da31a639b833,0x0005a63d297cf150,0x0003190a2a3a8499,0x0002ca8af6260545,0x00018490cdf918d2,0x0005a5ed4b646253,0x0004fec387ca9de6,0x00010b72b35acffa,0x0000000000000000}, {0x0006d539b23d78ec,0x000a4b221e3646f9,0x000b6bf83af256f3,0x000d62f0c408a90f,0x000fdaefff14a7ab,0x000e41ce0c4069cd,0x0001cba29824953a,0x0007a382ab7eb47d,0x0007f64599eb440b,0x00074a4c148b6095,0x0000000000000001}}, + {{0x0005a160c85caa71,0x000f0e79edff6be6,0x0007704970c1ae3a,0x000a395f8b957c42,0x000c85f0f181eb8a,0x0007d8f529bdf3d6,0x000d3534e626c58e,0x000c770dabfad83f,0x0003e65d7e5ada98,0x0005676430730bac,0x0000000000000000}, {0x000d0476d73fcec9,0x000d714dcf97c309,0x000a56a3252ab9b5,0x00097fc79648c08c,0x0006b897ba609ff2,0x000c446a06ff8430,0x0002d01ddb643744,0x000f97ee1218bc20,0x00048db33f9b0f80,0x0005e8b5f54bb8f0,0x0000000000000001}}, + {{0x000851bfcfbb80d1,0x00082b51c40077e9,0x00087cd565dbfe09,0x000954bdd372a1cb,0x000f6bbff7b4dccd,0x000237c51d294b36,0x00003d64ce0f8798,0x0000569d6e3c2614,0x000a6224fb79e0e6,0x0004d7c33dd3b5eb,0x0000000000000001}, {0x000f054ad5a9cfa1,0x000bee5f93daceaa,0x0008aa260aa160bb,0x0005025da9f4b722,0x00004817d1e67b1b,0x000e00279781308a,0x000c2084afd2f00f,0x000c154f68e6680c,0x000c6b0f1d4b7ecc,0x000fe2b89761184c,0x0000000000000000}}, + {{0x0007fbeff2b9ea68,0x00035c954c6cefab,0x000062277d67291b,0x000820637553137c,0x000e8b75730d8af4,0x00068d2250710c68,0x0007a2fbae3e7c1b,0x000f6b643e1aff63,0x000dc46991ef002b,0x00096e38ab4582dc,0x0000000000000000}, {0x000bea0d80f3758d,0x0001d6899ee62692,0x000cdd2a79a4d763,0x0002f50f2ee3aea9,0x000fb1476eea0816,0x0007c81475c4d433,0x0009d9fe82142372,0x000756c76934dc96,0x00033eb086d918c8,0x000e3056d2a89175,0x0000000000000001}}, + {{0x000ef0de9496fb55,0x00076806fa762c50,0x000770bcaf6f226f,0x000a0d3e47cff6b0,0x0004eb780ef8cec1,0x00034df87449872a,0x000896382a505c84,0x00046b56a94dfc29,0x00021c7a5c037f2d,0x000659ef98ff9417,0x0000000000000000}, {0x000001c935289072,0x000f4a229e4010ce,0x000b1be023ab7710,0x00073fb44f780b68,0x0002944ddc611373,0x000ba09ab8b61290,0x000be003d4bb157e,0x000f7557730f52d1,0x000506c275d184bf,0x000c57abea8b4979,0x0000000000000001}}, + {{0x000004498fadaa48,0x0009d0bea3c3894e,0x000a8f46458aa39f,0x0000008b0b3654a0,0x000ca4cd7392bf83,0x00012eb97aa46a22,0x000b9cb80e1d7afb,0x000cf74c8adcd888,0x000b51d04bb6e179,0x000b50968eb22473,0x0000000000000000}, {0x000f96d03d831756,0x0007499de9e10051,0x000ecddcd4ffade3,0x0009dbdffc72771e,0x0006b5e1bb9647aa,0x000addb508dc2415,0x000ddf40de78eeab,0x000ab1c488946fac,0x000c823824a964d6,0x0003b16f258c8749,0x0000000000000000}}, +}, +{/* digit=20 [{1,2,3,..,}]*([2^80]*G) */ + {{0x000cc508d53fa611,0x00057fcd40894532,0x000f3eb54e960b10,0x000ea40877d231ff,0x00043e5110313bd6,0x0005209f6eb9ee83,0x000589764924e778,0x000332e258b2e7fa,0x000e2e038618a6eb,0x000aaf96067c3511,0x0000000000000001}, {0x00022156015c8ff4,0x0003a0ef974e440f,0x0008ea1f931a1b7a,0x000e417472932b48,0x00003bb75d745720,0x00096758e51bf9c8,0x000f97c7f0b39099,0x000b39d56a488d83,0x000fe1ded1fac932,0x000399aaf43ccf55,0x0000000000000000}}, + {{0x000fb78344f73774,0x000a49ad3e73876f,0x0008771e37ad3158,0x00003f2cb98ec469,0x000f31bd531106f1,0x000434959ff8325a,0x00064eee47f875ba,0x0001cf224bc0a102,0x0007d33a19ccf2f6,0x000f2186ce603133,0x0000000000000001}, {0x00006e91f2869773,0x0000239179c5ea67,0x0009aa4ed3879ba3,0x0003eb977e239f26,0x00090ef091443aa8,0x00036fc4d282853a,0x000a0bb2b260d343,0x0008119fbd0756b3,0x00053a3a6e0f1619,0x000016a2af080234,0x0000000000000000}}, + {{0x00000185bd1fcc92,0x000a0002ebe1f280,0x00030d3e5f23ebcd,0x0009d40f75cccaba,0x00063108edd488ea,0x000028024e152a65,0x0008296732e422c6,0x0006142e6cc11761,0x0004e44889dea726,0x0004d1b05325e95d,0x0000000000000001}, {0x000270a2e4063870,0x0004d9c29b5dcaf3,0x000d2f759d7bad98,0x000ff7c2ad7bc046,0x0000fa4e4f59d347,0x000a06be29c16d4c,0x000bb31872d14ff0,0x0002b7a5b6ec2390,0x0008ae4cc66be2ce,0x0007006b9b1fe040,0x0000000000000000}}, + {{0x000c4cee52cfafd0,0x000916a99628d59c,0x0004417813a4764e,0x0003f0c49a05da16,0x000992babb644e42,0x000179a66e24dca8,0x000cbef894f6883d,0x0001ed7756c7c157,0x000ff08e144c3013,0x0008ac78b0a3e9cd,0x0000000000000000}, {0x000dabd753963ba6,0x000426be7ba3ec43,0x000d17b8f8b93626,0x000d7ac0bfcd2a78,0x000c2aeda53c9486,0x000c99eeaefc3c49,0x0003d0949fb4a9cb,0x0005db07562812ab,0x0005da4c6c0f863b,0x0009e08ec31fe43d,0x0000000000000001}}, + {{0x0008d00b0f45825d,0x00075f4acb7a9109,0x000fe317cf8f4f81,0x0009a77cf8155d16,0x000d7ac3ddeef2bc,0x000aeae3c417520b,0x000e6ff44ee6fbc0,0x0008d8c238521aaa,0x0003f42c9f47bc82,0x000d2fc09b26d055,0x0000000000000000}, {0x00032ac7c6897ed6,0x000498c1e669bb9a,0x000697322f4c8aca,0x000625a543042d46,0x0003cdf16aa69334,0x000b4b67c267bda0,0x0005d6f205d341fa,0x000005daa2bd83a5,0x000c9573fcdfd94e,0x0004e81cb76afe9a,0x0000000000000001}}, + {{0x00074fcede51930f,0x0001c997863b91f0,0x00092d449a3c4328,0x000c91197a68c2d7,0x0006a3b2de0b3063,0x0003e7d82555e166,0x000f427f70b4227f,0x00066c04e18d6aac,0x0004c82c2c2b9b61,0x00095a376fa210aa,0x0000000000000001}, {0x000de0f4a3a29f55,0x00023263844f1727,0x000fd0bec7770941,0x000e79f43b5f4e85,0x000035cbc9a5768f,0x0005bb2328826a73,0x0008a77da7d22096,0x00096978fe424078,0x000ae1a0514c7cf9,0x00085e77943ce3c2,0x0000000000000001}}, + {{0x0000d1b4594afc85,0x0006a925e9937fdb,0x000d1cf398814c56,0x00000694cd250848,0x0005fbfd82b6ccc3,0x00047db4ae135bc7,0x000c1f18639e63fa,0x000730a5e5b32295,0x00041bb1c61f91b2,0x0009451335383b28,0x0000000000000000}, {0x000df27e3f2dca32,0x000ee40fb695c7e1,0x000c8c313d1721a9,0x0008bc93267e9801,0x0006a9aafbe12b28,0x000e34c2b180d7a3,0x000e6b65e8b79ae5,0x00047da7f03b22ef,0x00094e563552e913,0x000f4aab16538cee,0x0000000000000001}}, + {{0x0006db42e9e50fad,0x00042149f7546b33,0x00057093c06f6900,0x000dbce88e00d7d3,0x0004ad9ede7428d2,0x0001940521d004dc,0x000e4970d3be2ce0,0x00031bb5cf60dc4a,0x0003df5670a6ccb0,0x000b64df04605d80,0x0000000000000001}, {0x0005f0fb0c7d8a77,0x0006951f8ad28aa0,0x000e5b908dd39d0a,0x0005f76fd67e92ff,0x00080f281077f416,0x0009ee2db2c8d529,0x000e9a09ff0b841c,0x000f9a5850f2e792,0x000e9887cd74d1ff,0x0009aa468c4978db,0x0000000000000001}}, +}, +{/* digit=21 [{1,2,3,..,}]*([2^84]*G) */ + {{0x00045bc39568d9b4,0x000deebca99c74cf,0x000ae132b3816aa0,0x0003fb57b713a9d8,0x000e4139b0131f8d,0x00042164bbc38156,0x0005a533293d5ffc,0x000f28a54d0e74da,0x000246758970fcef,0x0005cb3ef8fd2b56,0x0000000000000000}, {0x000e59886b3941bc,0x0009ade1a4b217a0,0x00023117719aa3f6,0x000c88c1b7b4e45e,0x000c3f1294233118,0x0001ed8c9dd7dfa5,0x0003ffafa2104f8f,0x000e89ed71382221,0x000d0f8573ea0a97,0x000a81f09db9f82c,0x0000000000000000}}, + {{0x00077d542b1d8c85,0x0009eb6c76648a7d,0x000ae9936fca1675,0x000c8db3d9556eeb,0x0008f1fc23af7239,0x000956a6643df02c,0x0005264fec894e1d,0x0000aaa92f802a0d,0x000d756f014a90b9,0x000e0753d197ff93,0x0000000000000001}, {0x000dc80b7f62d4df,0x0005de026f897406,0x000bf46ad6add1ea,0x000f1c5d1c416858,0x0004d6b3d82ce8f0,0x000459159df587ce,0x000ca473b92c19aa,0x0006da5bec10b6ba,0x000e0b4be600af3c,0x000cf6c81e2b9b40,0x0000000000000001}}, + {{0x000c67c15f2b99a5,0x0002e78f41b12d02,0x000f7e85b9e3bb96,0x000e6c293dd82110,0x000a0b7296f35eee,0x0008b9f01a446a48,0x000f7d8d89873daa,0x000d90409d0bfd67,0x000b42d1c91c3962,0x00005e6c3afa1fdc,0x0000000000000001}, {0x000607a511880114,0x00046b3caa5f65bf,0x000ed1d7edcb6427,0x000223b76ca3eaf2,0x000c254785aeacd8,0x0003d96bed772614,0x000fe17074c3138f,0x000fc4599803c303,0x00029d4441854c4a,0x00068d2f47c7e6ad,0x0000000000000001}}, + {{0x00027dadf66942d9,0x0002d934d4f0887d,0x00024ab4a3b4ff58,0x0008094d151ee4b7,0x00059df116aee58c,0x000c8ad8141ceee5,0x000c277f6cc0cd16,0x000b9d41dd2c3d13,0x00018d63c75e0cd1,0x000c06bb0767f3f3,0x0000000000000000}, {0x0003f3f369ef6b69,0x0007808f1170f91f,0x0006338ef6344906,0x000cb4597495e6b8,0x000283f524ab766d,0x000d7731127ec634,0x00075be86373e0af,0x0008d2af0e3a5495,0x00014c6819dfc2be,0x000f7affa7af5c63,0x0000000000000001}}, + {{0x000892c7124cd33e,0x000b92182e71043c,0x000db014cae4df90,0x0009ceb0a4ea4119,0x000ef942ed19b706,0x0000628b68098d1b,0x00084c6cb159ff0e,0x0004d4b5184cdc53,0x000190191d032e77,0x0006b2ec68efce97,0x0000000000000001}, {0x0003436236c90d20,0x000e12c74816ecfc,0x0003e074e74849dd,0x0007be255b09c30d,0x000526507824bfa8,0x000ef7cb512aeee2,0x0002afeb20a50c2e,0x0008aa489a2c4123,0x000334adba554c1c,0x000ed1b94b601c93,0x0000000000000000}}, + {{0x0001c752e894f83b,0x0001102db47294b0,0x000efd031528755f,0x0008e7a5233b9d7e,0x000dc69c62c7500f,0x00051f44711ee3b5,0x0009d94a5e280f05,0x000b11042cd8c7dd,0x0008b14370c2167e,0x0007807f4636e4af,0x0000000000000000}, {0x000598691d482817,0x000b8412f599a077,0x0000459d6b4cf61c,0x000405e26f27cc0b,0x000ddbc7fdaf5126,0x000cdbba7c4a3026,0x000b262658e4a3b0,0x0000f2e795bb25d0,0x000766509eec95e9,0x0005a452259c52c8,0x0000000000000000}}, + {{0x0005f6dc2c523bd7,0x000003d082f18f83,0x000ef7ee57fec42f,0x000f2558c3c5a1e3,0x00038f0a9e89f93b,0x000efbe9151ca6a7,0x000ed767c4685458,0x00079d486204e6f8,0x000a36a1a4b728f1,0x00043b885c25b705,0x0000000000000001}, {0x000eabc2b52d4646,0x0006c95bf22f084b,0x000314aed2f78fee,0x000dd61877362fd0,0x0009044697d005db,0x0001d56d41727a4e,0x000627e07ab413dd,0x0000b5903e3cd67c,0x0009c224e9a02779,0x000806739d1d3428,0x0000000000000000}}, + {{0x0004109673b0becb,0x00029788f9eb9435,0x000ae5dfb3d20da6,0x00057d88527623e5,0x00015c844e99c175,0x0006a57ec3b40311,0x0000b594aff5aa0b,0x000cea2e84adbe7d,0x0007fcbaf1e84a37,0x0008e3048c293594,0x0000000000000001}, {0x000f58bede275de5,0x000b21503171b093,0x0007b8e1c737aaa2,0x000dfceb6261f263,0x000d21e8e8701620,0x000e453d37db241d,0x000825774e79c85c,0x00066f92bc717db8,0x000b9d9ff5a2566e,0x000bfd4ae0bd7b6f,0x0000000000000001}}, +}, +{/* digit=22 [{1,2,3,..,}]*([2^88]*G) */ + {{0x000cd0f9ef7a9efa,0x0001757bbdb01042,0x0001996a380a3fbb,0x0009e651f39db731,0x000cdf3f08146bb6,0x000679b0b6ec6679,0x000ae26608474788,0x000d883e5a5990d1,0x00061924fa5e209e,0x0001de3c755c0bba,0x0000000000000000}, {0x0007c1f82ebae92f,0x000ccf8ace9c6a84,0x000857d9026a1434,0x0005b0b7ad864d4c,0x00018f613e2210ee,0x0001165b2c86a357,0x00019fb55984d679,0x000f15401901080d,0x0009a0e8b3389ecc,0x000e608b509b98d9,0x0000000000000001}}, + {{0x000a526cf604c662,0x0003afa9ed0f7a0c,0x0001dd685ac125b3,0x0007ff8f516f5290,0x000ad927c416e17e,0x000fc77cc9720475,0x000071767e1e9190,0x000f6652fcb33aec,0x0000f0d48cb2653d,0x00086c8bf16720d8,0x0000000000000000}, {0x000404c440590fcd,0x0003377f43e4e408,0x000defb22729c42e,0x000241aec3b37e10,0x00092c795c866daf,0x000f4d30790a07c8,0x000075bb2425f5fb,0x0001b7cb5830a5db,0x000c950890875f16,0x000e6591cad66493,0x0000000000000000}}, + {{0x0003de8c91c31e47,0x000a2de46bc7eb7b,0x000f3de301a0b479,0x00094aa7479aa235,0x000be5191502fe1c,0x000266a8b4adef28,0x0002961e0e185a17,0x000f211c2c23ddea,0x0007d3314a5b8f85,0x0007d3d59f2b026d,0x0000000000000001}, {0x00032b1fd4f159bf,0x0003721f923e006e,0x00024a7d38b715f2,0x0000994620d23277,0x000ab6678b2917d4,0x000fa4a8245b0c3a,0x000912038e0b4172,0x000f6fdcf8c4b1b8,0x000ccd3b3eaaf19e,0x000d40f97e7249e4,0x0000000000000001}}, + {{0x0007975597dddacd,0x0009d9266f6975c3,0x000599f544c22dfb,0x000c2be6db081480,0x0002aeb8ec462839,0x0009d49cd3b5cdf1,0x0006a8ba917fb29d,0x0008233b216f9614,0x000abf1a9d936c0b,0x0007878c8a45a2f0,0x0000000000000000}, {0x0005dd64a0356029,0x0008c2d1625aef0f,0x0005ff56fc705652,0x000323cb9b293d67,0x000bd02b295cca5c,0x000c7129104d697c,0x000d83fe4eb4b02b,0x0004a4e9327cc1e4,0x000f46cdc9c23cdd,0x00053f946406995a,0x0000000000000001}}, + {{0x000d1e43a1e16a36,0x000514cd5be788b6,0x000f3827d2f55b7d,0x0000a3f8f594d05c,0x0006accb980d1448,0x0004ad1e4f1f6b59,0x000e7dd3016801fc,0x0007c435098ccf31,0x000c6bc2e61b9059,0x000588b12be241e3,0x0000000000000001}, {0x0000b8e2e65481b3,0x000aef410135fbc4,0x000c7a2e23221960,0x000fd4a513faa141,0x000a0357c6f569e3,0x000f4ac3eadff143,0x000f6174146f64bf,0x000c13f9a5506c59,0x0005ed7b5be845e0,0x000d0deb4721eef8,0x0000000000000001}}, + {{0x000e8dfde28d4a2d,0x0001761a2d5208a2,0x00005b6ff5ebb541,0x000b58d09bebbafe,0x000a9eccec1be769,0x0004b3933ce41d83,0x000e22e31e1a1a39,0x00081430e109c5df,0x0005c36dffc66dc3,0x0006a93ad68549c2,0x0000000000000001}, {0x000135d5a197f614,0x000b4beb4875f558,0x000374737f60f213,0x000b3391150b17e2,0x000fd51cce3f02fd,0x00090f492191217f,0x000bccbadc4f8a8a,0x0005d89eef2479ce,0x000b7145781a1c26,0x000e4d791a7d8953,0x0000000000000001}}, + {{0x0006a3d38b806bee,0x0002ffcbc7fbb018,0x0004904b1192a4cb,0x00039b7f571c01df,0x00040717c8035f6f,0x000f75f4a725c0f7,0x0003575b1f8427ca,0x000cefd7922924c3,0x000c3f91c6705a27,0x000f14804d6b5694,0x0000000000000001}, {0x000d6688c387623f,0x000533d1b2b7249a,0x0006a96c61952611,0x0009fa8adb7cd547,0x0006614cc5f19687,0x0000dc38a5b55739,0x000b43a1185de8e8,0x000489b0890de38d,0x000cfe16e6aaab3a,0x0009a02c0ab01066,0x0000000000000000}}, + {{0x00047414fc9de104,0x000b82aed9435d61,0x00062ff16a9bd16d,0x000caf4a3b07e71a,0x0003ff9456ee752d,0x000d78dd65ea0d3e,0x0005bf864901fef1,0x0007bc9f42253114,0x000cb13ee366fd36,0x000fe6290083f481,0x0000000000000001}, {0x00032088e6e77ebe,0x000f38c5e887c852,0x000f005e149cc7b3,0x00089874e1bede78,0x000c72dfeaf32e8c,0x000cb0a4d9cb4e28,0x000aba5da48c7113,0x000b1fe289a0af7d,0x0005d0dc00d3633a,0x000801c0b05c86bd,0x0000000000000000}}, +}, +{/* digit=23 [{1,2,3,..,}]*([2^92]*G) */ + {{0x000567a7a06de008,0x0007cf045155d807,0x000ce8bb24635169,0x000c2900cba64633,0x000c724297174dd5,0x000c3a3851e7f044,0x000f59548c830bf0,0x0003817a26f0d35f,0x0003d8b027d923f5,0x00062c2b3dd7cad9,0x0000000000000000}, {0x00094cbf6924bf9f,0x000c09986d299bcc,0x000f89ccb5adf6f5,0x00099f825aee26f4,0x00056c1b545bb186,0x0000d22aa56595e6,0x000ba5ea3953faeb,0x0003a9580b4b6abc,0x000465246d4e240d,0x000d8613b6fdf7ef,0x0000000000000000}}, + {{0x0008a64cd725af51,0x000d6dda66823389,0x0001f40d7d1c8516,0x000115e05fb1f564,0x000ad7906c2d8d5a,0x000f4efe00496ac4,0x0002d973643f7076,0x0004414f58386c89,0x0002d83c2e34b14c,0x000437c00d08bc7c,0x0000000000000000}, {0x0004451656bebe71,0x0003f2219e2e5bca,0x000118227eacbf3a,0x0007e2cef1a84019,0x0002d58a5f9de601,0x0001ecfa6e192212,0x0006fb198696eb0f,0x000854826be2d3df,0x000dea0068fefc08,0x00074e77c2979102,0x0000000000000001}}, + {{0x00048eb205a5b22a,0x0007d680f21ad148,0x0008e50bcbdde0fb,0x0006f6074c1119fd,0x00079f9f2e43583d,0x00065361f1d9961c,0x000463e625f26bb7,0x000f2b47c8db008a,0x0008c397787cd134,0x00029b36eea7ef32,0x0000000000000001}, {0x0006647223894ce2,0x00087adfe036fb3d,0x00067daf1eb206e8,0x000b19b372f017c4,0x000a8ad33a99ef7d,0x00055c0da806ea7b,0x000c02414bd637ef,0x000b598649739b12,0x000feed3dd282f3b,0x0003ecce69b37255,0x0000000000000001}}, + {{0x000e5f81ac137092,0x0000518f81e9a3bd,0x0009720014a7f4da,0x0001f457a02bf073,0x0006be074553e9ff,0x0004351eaa3a46ea,0x00022b27e32f0dd6,0x0003b488462fd22b,0x0006ddddacafc2c2,0x00035bfb75908f56,0x0000000000000001}, {0x000987332b5b9a11,0x00044ffe94dfd9e8,0x000f9b91bc64f63b,0x00077f430dbd772b,0x000dfd580392aecb,0x000ddc69fb2fb67d,0x000314d2fdb69c91,0x000e754b9b9f9ea2,0x000f2e9c2e624f23,0x0000a3c6e677e1f3,0x0000000000000001}}, + {{0x000e37a930c3bc57,0x00006f969b4cf1af,0x000df3ff74237c4c,0x000d1ea35c488b6e,0x000e084f47372a77,0x00065b61ccb75b2d,0x000a4e47577fd773,0x000dbd98a086f5f2,0x000533002b74aa9d,0x000bedfb9c8068e6,0x0000000000000001}, {0x000b7aec02da823b,0x0009baf08dcbb7e2,0x000400bf0e5f485f,0x0003a3c7f9dfd4e3,0x0007472ece43050d,0x00091a092b1134f2,0x0004c1a0e70ff8a8,0x00037f3b75a31807,0x0000f51f254e9906,0x000c2183d0367614,0x0000000000000001}}, + {{0x000a39c0dd80f6fe,0x000a13cb07adfd25,0x000ee3ca4d8c1a3a,0x0007a28212986a18,0x000c5167c4c47943,0x000beb7b7306e9bb,0x00038cfc9b26c1f3,0x000b68e5bc206604,0x0003bd9665b63ba8,0x000661b9d7de6c40,0x0000000000000001}, {0x000c9e6e7c3229ea,0x000fb93cb721672d,0x0002429ae120fbe8,0x0007d3de1f64e3d5,0x000492888bee099a,0x0009c2f4894dc1d6,0x00011bda9ef3c7dd,0x000289559ae47758,0x0008fcbb34df4ae3,0x0005c440c5d0ce22,0x0000000000000001}}, + {{0x000fc1fd2377e231,0x000257cc9235e4c6,0x000a8f0482692e0c,0x00027d24355728b1,0x00087856d3663645,0x000dfe4f7c7f19ee,0x000c0f9ccd7eb847,0x0001019511788244,0x000c4838c54b2a98,0x0008b89d2d46944a,0x0000000000000001}, {0x000e02a1a1d2a70d,0x000b7d63b4d27dff,0x000ab61d5fa9a970,0x000d7730420f7a7f,0x00079f4479996041,0x0001189500cc1597,0x000981b342dd1a18,0x000b0c87b154435a,0x000fe5a645fb9438,0x000a1ab34fb7fc43,0x0000000000000001}}, + {{0x000f438f4b100160,0x000f22d13ff0c314,0x000d55796ecb8e45,0x0000ab873dd2e2bb,0x000789eb71d33f83,0x0003167e0b14a364,0x00002c246513aa48,0x000b03e86d3a7935,0x000b2db2bb0fe98c,0x0000d70404a0ec4e,0x0000000000000001}, {0x0004384c5c6b60bc,0x0002570cd19a5c8f,0x0001c33b468c19b3,0x000cbac39210942f,0x0007d36048a2a29c,0x000f69ef5fd4ffa9,0x000ece5cd6b0a674,0x000b1322973982d0,0x0001493bd4bce1b8,0x00083d4d6596bf49,0x0000000000000001}}, +}, +{/* digit=24 [{1,2,3,..,}]*([2^96]*G) */ + {{0x0000db5e813acae0,0x0005831117f6d456,0x0001106059c8e19b,0x000f908ce8232c57,0x00092d0f09782c78,0x000bd0fcb64a24aa,0x00077e3d766becf8,0x000f155f53d2f599,0x000389ae2fa9a727,0x000920ff877e9249,0x0000000000000001}, {0x00085d510d2d4458,0x000dc73b4e520499,0x000aa68342be4788,0x0004f89c8a0ca8e6,0x000e8668748927b1,0x00017375ddf19eb3,0x00041d15e5f8b7ce,0x00052912af54652a,0x000b9a777a86a727,0x00003bbaf706d85a,0x0000000000000001}}, + {{0x00017d39542a7b35,0x000d6953d2cbb145,0x00044a3ef5b5b733,0x00076565472126ff,0x000b2a4a1334dee0,0x0002573d17b26c37,0x0002c7ab5b295171,0x0008d328148c129c,0x000907f5aa2c72b0,0x00018b1d10e10308,0x0000000000000001}, {0x000159666154b57d,0x0005dd9359d8885e,0x0000281b6f14827d,0x0009bc4ba475f3a4,0x000c32eef44696b1,0x00082b50dbdc6dfb,0x000236a9ef4383e7,0x000fd73208450583,0x000d190b07767db3,0x0003153c0278a00d,0x0000000000000000}}, + {{0x000ba905f5456251,0x0008ee5b3d8d39c0,0x000ea2a0a4462a26,0x000032f3094457cb,0x0009bab36ceff80f,0x0001b0fdf3879073,0x0009dc840209bce2,0x000df0c1c8e03824,0x000c51d81213ecb4,0x00063c2b025e0d70,0x0000000000000001}, {0x0003bb32c4b899f8,0x000ccb798bfbf249,0x00028838277f622f,0x000e5b67c2594827,0x0003c2c07c4dd5cb,0x000c19526a2c4c70,0x0000177dcd0df4c1,0x000457a743a1ed39,0x00032bea63a4c527,0x00075d1c302e78ac,0x0000000000000000}}, + {{0x000fc5003828ff0b,0x000436a9841f4323,0x000c6f35f8a62407,0x0009286efc260a1f,0x000fbe74c4b2df5e,0x000cb3568b504bfa,0x000dbcf3548e5047,0x0005d92aaad71af9,0x00018241085e423c,0x0004f894d1d8842d,0x0000000000000001}, {0x00075b2a3f29b75d,0x000ec555f7834899,0x00092b31a410939e,0x000b7bc223255263,0x000db65a25c264a1,0x0008fc1aed283464,0x0005c70ecd1a9b70,0x000d90a7a2a0ea33,0x000d21f2e9f14ffd,0x000fb49566dadd7f,0x0000000000000000}}, + {{0x000fa5757545376f,0x000ae164cbfd55ff,0x0008a8545451f1c3,0x0002e007d0be9705,0x000ed2a8f4c49727,0x00097ed736254138,0x000516215e864c7c,0x000bb624fc1b83df,0x0000313aaf4114fd,0x000a7a8c7f0423cc,0x0000000000000000}, {0x000ed76abc8d276d,0x000bfe3e74f599a4,0x00025d1f92d8b381,0x0005a3599e406956,0x00071869bdf5e06a,0x000ec86f625afaf6,0x000d724bbcc12cda,0x0003da7516890dd1,0x0009b69252163060,0x0002541f15a18b40,0x0000000000000001}}, + {{0x000e1c4e632e5d61,0x0002987ad659b7d5,0x0003f7f338de2f2a,0x000b55a5aaeb06f1,0x000b9a60e84f26d9,0x000d10563130c6f8,0x000e760d017d58e9,0x00039e20b973fa41,0x0000eaafdb2f4acf,0x000501ec9c6ab584,0x0000000000000000}, {0x000f4549ba5a6302,0x000a98b140b89722,0x0003e099225c2510,0x000f31b19117bbe6,0x00046ba7147bd18a,0x0000f540e368bb5c,0x000eacf29d33114f,0x0007e59588a01c9a,0x000ef0e25eb2d0e6,0x00058e4bb1b8d029,0x0000000000000001}}, + {{0x00057915cb5440b5,0x00088e89a3e1eb04,0x000ed12c670e08cc,0x000eab1d89133ab9,0x000f615d9bc0c1fa,0x00081504d63c4250,0x00062cd084c8e8f8,0x000aaf76dbe53ead,0x000bf1dcc49cfac6,0x000fc7007ea0b885,0x0000000000000001}, {0x000472352fc50515,0x000fa2123835c747,0x00067bab29e80692,0x000cca008379c2a8,0x000799065aafbc2e,0x000a605d2e32da97,0x0002283421bbbfbd,0x000dbdc2e1151243,0x0007a9d899c126b9,0x0007467ce3f8d643,0x0000000000000000}}, + {{0x00000c97f4a1ee70,0x0000a55fa6cdb3e0,0x000fd5fcd60595ed,0x000522bda02a23c6,0x0000361844a1d76e,0x000c6c179ebaf8c0,0x000a6ccd0a47af40,0x000071e2a1156aa1,0x000a1b0fc4eb0062,0x000bb4c1c5314a2c,0x0000000000000000}, {0x000c048376702b16,0x0002ef5b4e8123cd,0x000a7d67834242a3,0x0003bc3accb0fead,0x00007e65ed32fc2a,0x000b8b44e6e71194,0x00077e9aeb1712aa,0x000039ce4f895a59,0x0009d43ed708cfeb,0x0004254957cd1ca1,0x0000000000000001}}, +}, +{/* digit=25 [{1,2,3,..,}]*([2^100]*G) */ + {{0x0009a3fb62f03e91,0x000fc3cfe3b9a1c2,0x0008c5a528bca033,0x00096cd7b4bc3e3f,0x0008c4bd134e2233,0x00065224c739c3eb,0x00071ec25548c0a5,0x0007b0fb17f6f014,0x000aee1015fc6579,0x000448c4d69b6d18,0x0000000000000001}, {0x00074be708f600f9,0x000042a14b550a00,0x000f8e6b95a52425,0x0004e9813f438c42,0x0005181004aa1017,0x00010cd9a834ae43,0x0002105b1b67e295,0x000141438bad8cdf,0x0004d11308ec5ba9,0x00034300e8c08dc6,0x0000000000000000}}, + {{0x000625d111480c24,0x00034cdcf3505fb2,0x000c306874b99629,0x00004410981e8fcd,0x000492bd0a650027,0x000a534a84249eb3,0x000e1326b6bb40b6,0x000ebe5d29140c32,0x0009956b2cb2ca52,0x000b8c77c7225102,0x0000000000000001}, {0x0002b4e077c5c4dd,0x0008846314442efe,0x00066618e794431d,0x000a933fcd3eeea2,0x00006644159656a5,0x00022dc52fbda24f,0x000542f82f45dda5,0x000e0e5075c9d412,0x0002aba0fff34a66,0x000d69512c4a1d9a,0x0000000000000001}}, + {{0x000dc5b949f6aa55,0x000cb79872016ba3,0x0001df5e18d2889c,0x000aebf5e0129254,0x0003a4cd20b4cdbc,0x000f30108963d6c3,0x000c0dbc46a1dad1,0x00042c0e39b6755f,0x00007fa126ef9e69,0x000805d500d36fac,0x0000000000000000}, {0x0000b5e7bd19e5fb,0x000b3765e8dbbff9,0x000e491cc2deb8ec,0x000ab995d314c068,0x000b4e810513ad31,0x000b50dc0fcca181,0x00029580c1e05269,0x0006b6453c858930,0x0009a98b2de5a7d2,0x000b386f7a77183c,0x0000000000000000}}, + {{0x000d861fc542368a,0x000a737b3c184cd7,0x00014a6e3b95c425,0x000f514e85d4a651,0x00098b665bb45532,0x00066a39b08b87e5,0x00008dbdbcbbabba,0x000ba64b561fa462,0x0005692509520864,0x000281de8b31e205,0x0000000000000001}, {0x0001bb6a74473c21,0x000932e76a8c5ddd,0x000c6ee633cc0f66,0x000f68d0c546bb80,0x00006828f4e0c911,0x000b2a4276c213a2,0x0008cb204a16b2ce,0x000d38c09aa1cbe9,0x000f3ebeebcc1671,0x00032c7a684ba9a6,0x0000000000000000}}, + {{0x000a3463989cd762,0x00035114b160b22c,0x00057f2d520e3cc4,0x0000ff788707011b,0x00068b1a346a61d3,0x00084618b8d69eda,0x00020c04008115fa,0x000dfeeecaa806f5,0x0007e08436a14e30,0x00005f68bc839ccc,0x0000000000000000}, {0x000ae58e3c998f3f,0x000951d35d5af6b3,0x00038625415f29bb,0x000fd087552cd755,0x0002087ef7e8ab49,0x0006b067b5de9ebd,0x0001e74110309c17,0x0007b224505a1ece,0x000ba962991a5a2d,0x000b8879263dad03,0x0000000000000000}}, + {{0x0001b7e0189fcda6,0x0008775ba885f2a7,0x000b98305b9915b6,0x00019b2753769a90,0x000638d87ac0d10c,0x00083c77c18f7acf,0x000d23964d02af25,0x000de5be92026e04,0x0005a30998f85294,0x0002d2bb22f8803a,0x0000000000000001}, {0x0000daae09876e93,0x0007b9f1b9b10415,0x000e48eb13c50096,0x000cf9ccec3e5c4d,0x000f7b6158629895,0x000aa201ea7d90f3,0x0006e88c0cda29f8,0x000f4c0d70150c9a,0x000ee70bc97d1c62,0x000b8e4fd0f68d56,0x0000000000000000}}, + {{0x0003edbb844d6c8a,0x00076a792ccd3b41,0x00072527a7c1564f,0x00055b682778d6f2,0x0002167ba3cee45b,0x000d96d43a6e138f,0x000806538c932f15,0x000d4892afee6363,0x0002b82f06ed7c45,0x000fee287b4614b8,0x0000000000000000}, {0x000953f4fc1bb9d4,0x000e995150d18cb0,0x00067e23c2e107a5,0x000bfba071a733f6,0x00008ca46066c2e8,0x000cfb49871d6c61,0x0004ece39bb5a648,0x00040cf34f514816,0x0009b9250336996f,0x000c69d6e08146e9,0x0000000000000001}}, + {{0x00008e517921a752,0x000ab87a6c13d140,0x000c4597b07c5d69,0x00074a68c66db12e,0x00019ca40dec9dbd,0x000a617fff4579d7,0x0005876131725395,0x000d09e3b946e383,0x000d20c852478942,0x00087982ecbef742,0x0000000000000001}, {0x000589886da1602b,0x000c3fc9ae2bbd5f,0x0002126ee978ba22,0x00075595e212b5ab,0x000a2389b739eff8,0x00063595af9d6707,0x0000f9787d12dd72,0x0003b014c3309267,0x0002f506a0067880,0x000f67060764da69,0x0000000000000000}}, +}, +{/* digit=26 [{1,2,3,..,}]*([2^104]*G) */ + {{0x000365108b90f9d0,0x000f80765f67fb1e,0x000b1b38d141aae9,0x00024d697a9407e4,0x0003f9693e7ccc84,0x000a50e7d291d93e,0x000cd34385c13c5b,0x00066fcf73c9d94e,0x000598f4a80eb0bb,0x000b721c4d4c290d,0x0000000000000001}, {0x0000fb9a3bbeb3c7,0x0007ba326d546e3b,0x000a848cf094c6d2,0x0000e41609d2dc18,0x000266f0069ca46c,0x000c4aef799231b9,0x000abacbdbead081,0x000b272ba1959d4d,0x00049b7208e216ce,0x0002ba83cc03eccc,0x0000000000000001}}, + {{0x0004c0998b5250d8,0x000c867c43b599d6,0x0004c9f6ac785a2e,0x0004ec8b59f29f0d,0x0004df16ae8c0faa,0x000b8d8f78201760,0x000bc38bb59089da,0x0007384039822772,0x000d1571c6e88e81,0x000a7b7d4e8e0cf3,0x0000000000000001}, {0x0007bc572ea0f919,0x00064539b5eb1047,0x00077d71bc88d22a,0x0004dc62d769223e,0x000adfe2b562c973,0x000173fab241cdb0,0x000603370ddf3ff3,0x000f70dbbbbd997d,0x0008a88a56d59561,0x0004be64aafc3299,0x0000000000000000}}, + {{0x00045d30a00d827f,0x0006bbe20955e997,0x000cead0ee1643eb,0x000fce2db7c5ac6f,0x000ad1d2efb30bc2,0x000d9fbc667affb8,0x000bb6fb3983d3ef,0x000f70a834538091,0x0008384fd172dade,0x0003f32390fa3030,0x0000000000000000}, {0x00022aae53d2000c,0x000caf0273baad84,0x0004a6a878c712a8,0x00002615beecdb4d,0x000b0e868dba85ad,0x000964d03b5c6537,0x000cbcf8b6d0fd98,0x0006a16ca9f74a32,0x000552ffb8c5dbeb,0x000bf0f20d682f2c,0x0000000000000000}}, + {{0x0009a64c8deb9f4b,0x000532674c0fe944,0x00001e88fe681603,0x000b8697595c6e13,0x0008cf6f513d4913,0x0008c1e3203b6d47,0x000b68db28573518,0x000bdfb9fd4390cf,0x0006601496c4bb93,0x0000633f388af7cc,0x0000000000000001}, {0x0005258fb2317523,0x00040dacae0a8b9a,0x000ba0560abb741a,0x0008bc6a795d005e,0x00096caa47999397,0x000ff04fef1c0b24,0x000b0926ddcefe71,0x0008f281ff3947c3,0x000027cc7cc93f3d,0x000e78773c9a3f23,0x0000000000000000}}, + {{0x0001c60cc85e7257,0x00011fa52f42f768,0x0002f380ec8fe41b,0x0004893bc07fb9d3,0x00034451f49fbf7a,0x000388023d1b4705,0x00079c42053de8b9,0x000cf909c04d42cb,0x000eca57f6797b3a,0x000cf34d35027c43,0x0000000000000001}, {0x00086008351763ff,0x000f9e1103300427,0x000991707dcb32e9,0x000efb21a41fbb4f,0x000b5649d55978db,0x00004e4d7b3fa6d3,0x00012196968dee3a,0x0003561c60989b74,0x0009c91c53ee540c,0x000b9823a2ee0db7,0x0000000000000000}}, + {{0x000f6a15601d1f8d,0x000406c4591dc921,0x000b36c8aaaf7c15,0x000834fd3b0d0813,0x000e544ef9e76287,0x0002fb609294a18c,0x00008d9bd0198775,0x000cd4816092b24d,0x0008b097d39d2d32,0x000b3a5b9f00f218,0x0000000000000000}, {0x000da9d6f0979e9d,0x00080741dad104cc,0x0004ee619b7637d2,0x000d71560f5a9cc8,0x000b897bb554b4f3,0x000890a210367054,0x000aff63f1f61c3e,0x000cb92963c20784,0x0009317afc9acc43,0x0005c1dadb0d3e30,0x0000000000000001}}, + {{0x0004debc7af95096,0x0002bf8bc26e7cbc,0x000070bd1c43e146,0x00017181a62e8acb,0x0001c46b5339f3b4,0x000a2c14c9b646ef,0x0005de576b9f4c81,0x0004f9a155e97645,0x0003cfbba219f7e3,0x0009fb1fd4f92031,0x0000000000000001}, {0x000bcf11449769d9,0x000ea5acc7cb996d,0x0006bdb653213f43,0x0003a2cf9c396c5f,0x000777fb3075bc28,0x0009fab46fa97f51,0x000d80cd600dc1e5,0x0008ba6a57a9d490,0x000c9975b8111175,0x00067a2ad8270658,0x0000000000000000}}, + {{0x0005e67b8d52ab83,0x000eb2049665d86d,0x000b56e1ced19993,0x0009c1fc7a62ba87,0x000276fc5cf75dfb,0x00054f5dad4712b6,0x00089fbe0548bd15,0x000d1ee24125ecba,0x000176a53fa18f5a,0x0004e18796b5267e,0x0000000000000000}, {0x000a0f1a17a9eb45,0x000584e4e5f968ad,0x0008e12a3e089107,0x0009c73cd6a2ba69,0x00002e23b2a1f1ee,0x00028e9adc43a76e,0x00062c6e3d7526f4,0x000d0557ab8af09d,0x00058b1d337cd537,0x000000e54434b827,0x0000000000000000}}, +}, +{/* digit=27 [{1,2,3,..,}]*([2^108]*G) */ + {{0x00036c3a6abc7042,0x00004a11953f80fe,0x0000b4cc57cd15f7,0x000df44d3d3a8bb5,0x00015b5099398347,0x00081f3a553789e2,0x000d0115f2bce30d,0x00090b7f91f0853e,0x0007ec29320d53ac,0x00085b63e7bfbe8d,0x0000000000000000}, {0x000cdcd80232c6da,0x000d8fc636cf5e56,0x0006e4c3d9621241,0x000b84a86812f9d5,0x000287741d3de81f,0x000ab3d77eb50a79,0x00048627cc80386b,0x000a1901afee8f37,0x00095591fbf5ceb2,0x00080aed0c8140dd,0x0000000000000000}}, + {{0x0002fcdd07efc38c,0x000c9ad8b1dbd166,0x000af6b6e1566c06,0x0005c4ad28998a9b,0x000b12d2005dbca4,0x00009acb17fcd947,0x000af2e6bf7b35f6,0x0000b8a8aba325eb,0x000302e3f599df52,0x00080d2bf9b973e4,0x0000000000000001}, {0x000aebd112a3c0c1,0x000c408868630c25,0x000af7c4f6ba5529,0x000d49e0f5657b1a,0x000da3fa70b84c0f,0x0009f530044d86ec,0x0003f7ec59dce6d3,0x0004bdaf73433951,0x00022dd61822c292,0x000466acb0786ece,0x0000000000000000}}, + {{0x000bab3d6168fc90,0x0007cbb6b2be9857,0x0001cf2ccb017656,0x0001630304c6ccfa,0x000ab9344dbdd28a,0x00075f0fec3093b4,0x000ff2494e7a4029,0x000ca3bad1c9c568,0x000b17aa4b7bc2e4,0x0001be8844e06c12,0x0000000000000001}, {0x000748f359f51efa,0x0006b016fa4643bf,0x000de784a5c3f1e9,0x0006412db1ab3996,0x0002a042b01eeae2,0x0005a0d3a2a424ea,0x0009b9a7aeefe348,0x000b209614c9d52b,0x000556ff1e6afd00,0x0001e2290dec8fe5,0x0000000000000000}}, + {{0x000dedb27f20e8c4,0x000f535a0fc33855,0x000788ccd8803e8a,0x0001f7d6e10cabd0,0x000355f889d7fa1f,0x000583e3030487ee,0x000f3dd1885d800a,0x000f09ae9a4a2fc9,0x00054fc302887b5b,0x000678d91181d3a5,0x0000000000000001}, {0x000b146d6cdca631,0x00046652f280d553,0x000e0b73d63dfaac,0x000399cd0d77869d,0x00057ba5ffe6aa8a,0x000ffc1da65c61b7,0x000738771cf6c9ea,0x000620ae124834d2,0x0006504def184b95,0x000d761c974cb47f,0x0000000000000000}}, + {{0x000b12824a32cfa1,0x0009c552049f6e5b,0x0002cf47aab27c7f,0x000c49affe61e35a,0x0002247309f28abd,0x000d8f5d3d157087,0x000c6b864fe18c22,0x000addbbfad216e7,0x0006e83c0b6f0f26,0x000fd5df730de2cf,0x0000000000000000}, {0x000d5ed49aa6d720,0x0003b8bf56601c9e,0x000932a05f265897,0x000b6e7997e501b5,0x000a12ea7ac82871,0x0009ee973ffc91a5,0x0008bc4a89b5c6c1,0x0003ff7cc4ea3cde,0x000dd04f7b689969,0x000d1dbe61024f53,0x0000000000000001}}, + {{0x0009c8cbe80fbbcf,0x0001820704f59919,0x000a2837d2432345,0x0001d7c57c052221,0x0004dd7abcf6f7fc,0x000ceb0c9ac384fa,0x000cbcbae19fcf70,0x00044465c2e5cd22,0x000a11ffc8ca98c5,0x0007b72231b3018f,0x0000000000000001}, {0x0005516f6500002e,0x00015b8dc7f05ee2,0x000111229aa6356e,0x0006bd0e54525c30,0x000dcfc5ecb4c0df,0x000355785f844693,0x000ab74792af79c9,0x0007357c34213765,0x00008a7b5867734f,0x00069a6d820a3083,0x0000000000000000}}, + {{0x000b3a34b0a583e8,0x0004109d1c2a05b3,0x00056d185c8227f4,0x000c30eb0f8b309e,0x000e5f0d836e7213,0x0002fdae4ffef15c,0x000257bcdd2d7309,0x000dad1ff9a8d757,0x00098efcc192b734,0x000fe0e5b46f1d9f,0x0000000000000001}, {0x000ec3057c0b1268,0x000e1eea4fea07c8,0x000ac5ab201c4cbc,0x0001b75086654bcd,0x000e612c2aee9474,0x00065fa077070bf8,0x00015dd97afeaab6,0x00088802f9979ef0,0x000c9b3109eb556d,0x000e513d135fae08,0x0000000000000000}}, + {{0x0009b9b53c1efab4,0x000babd37156ff65,0x000a115d2c7f8338,0x0007371c9d1175b5,0x000a353c22d6aa92,0x00079ee37be5b07d,0x00020293585421cb,0x000abe2b0a938ac9,0x0003622f3d489e47,0x000ac9ccd5811b36,0x0000000000000000}, {0x000cb54f0f506ac3,0x000feebf83fb7441,0x0007d9fa2d5527b4,0x000b40376d4a3597,0x00045e4619c87f8a,0x000b913b27d590e9,0x0001da0e8861075a,0x000dd8fb707f389b,0x000140b6fe0beb49,0x000bf7392dd17235,0x0000000000000001}}, +}, +{/* digit=28 [{1,2,3,..,}]*([2^112]*G) */ + {{0x00082a01cdf12457,0x000bf550e3442670,0x00027cfd7b191616,0x0009bf54426bd9ae,0x000375f468d0ec29,0x00095e63540487ca,0x000f558b93aa7dc6,0x00028f48edec9322,0x0007ee742818f059,0x000d23aca5b08895,0x0000000000000001}, {0x00018972085008e4,0x0009e445a0130711,0x0005bf246e5348cb,0x0008ccf1f5c183c6,0x000f2e9a40aeb3fd,0x00087abdef0fbda6,0x00050f5daf09cee0,0x0003e33344ee90c4,0x0004044243abe107,0x000b8f02a065d1a3,0x0000000000000000}}, + {{0x000b66d418145236,0x0007896ea70c3fff,0x000cb17d54fc5491,0x00042a641eaf6e4d,0x00096b15be10c7c6,0x00011efe5f993282,0x000c04930829e9c6,0x000a5f18e8613cde,0x0007985a51a7c38d,0x000b8f3536d908ab,0x0000000000000001}, {0x000ce50b447f989e,0x0006725435f6e48e,0x00060505d7413d04,0x00051fa907efc4e5,0x00091cc601ad28a5,0x000eeaf4b18fed33,0x0002e1a4338a8549,0x000b61868d3372c5,0x0003a511bce70bb6,0x000e1f5c8d75eb9c,0x0000000000000000}}, + {{0x000d68d2a3e7e05d,0x0009bf6f65a63322,0x000368db479d7794,0x000e22f5738f46ed,0x000947212d465e52,0x000bb783e24758d1,0x0009d33d677a59c8,0x0005609046041b23,0x000f6497a9c2f277,0x000e7a9be5339a8d,0x0000000000000001}, {0x000804d780847503,0x000fb6bd5cd190b5,0x000d58769b6bfbeb,0x000a5b2366d25685,0x00084206ac283f9e,0x00045e93a909d14a,0x0007818e03b612f8,0x0005061fa312c680,0x000501efdeb98070,0x00043cfa3670b66b,0x0000000000000000}}, + {{0x0008296f30c9bed5,0x00099a4bb11c1f32,0x00015b4084960501,0x000c50ce53a7ca7c,0x000f50a2c1da281b,0x0002c0e34f682873,0x000f21f441021705,0x000e9f354fbc9c5e,0x000d7990a0bba954,0x000ca402432a326c,0x0000000000000001}, {0x000e6dddd976d76d,0x000a57e55cac7b2b,0x000da37392c8a3b8,0x000fecd4ec1dc93e,0x00009cf4f78c92e3,0x000ff689fefedf3f,0x000abd5033740521,0x0000df4087ca092d,0x00002763eb9e4e11,0x000689f3f329b79d,0x0000000000000000}}, + {{0x000d09236f94e981,0x000f3b87c2492089,0x000090559806590f,0x0006b638cb962e83,0x00043caf0b4cf40f,0x00066f61c7a2faca,0x000edaa5c1d246d3,0x000b19d9f9d7b0bc,0x000d3b97c04cafce,0x000f23bf9f27399e,0x0000000000000000}, {0x000b2a804eb31689,0x0009a2a7437938a7,0x000f3c9cd990c2d5,0x000b68b7f843ec1e,0x0005141dcc07de04,0x000fdd1e7d56eecb,0x000a099220b61db4,0x0004184b463b9f76,0x00076a6a6fd2bcb4,0x00067d87f98ad9c6,0x0000000000000000}}, + {{0x00025736286ff497,0x0002401f1271e328,0x000981dcd7607683,0x000cfb7ab6548084,0x000df4da03d9c990,0x000d822ebf4ae8a1,0x00099db5f23d4a99,0x000f6315e3fb9894,0x000021f262e80d80,0x00027457b91d5ecd,0x0000000000000000}, {0x0007a0ed90d98205,0x000cf6f6b6c517c8,0x00057c5ae11bc6b8,0x00000efaef845be3,0x0005e74813e365be,0x000c8e0106700aae,0x000d776c99ef5ca6,0x0001e3d37bff71e1,0x0003a89779b96572,0x000c15ea2a31bd25,0x0000000000000000}}, + {{0x0000092959940ede,0x000bb4c7bf2ceef4,0x000d604555c30636,0x0003fe5635d8d5c1,0x0008cdef0cb902ce,0x000b6f22235732b0,0x000fddf6f7cfc6cb,0x000369004df1a446,0x0004ba65bcff1dc7,0x00020adfd4756b77,0x0000000000000001}, {0x000afeaa9dfdfa89,0x0000b80d92606c1c,0x0006888e19c65eb3,0x000bf9bb4db51900,0x0008e84280b5d191,0x00077a1cb4c3d007,0x00055fc83156ea4d,0x0009f40279edea0b,0x000aa5223480bee2,0x000f264b4f70afa9,0x0000000000000001}}, + {{0x00054382d016c8d9,0x000ec7826f7b17bd,0x000dce64f2832c36,0x000193ae22a16680,0x0000aaf6a85c2ab2,0x000f20270252cc0a,0x000f317cc1335b32,0x00003743776e2afb,0x000a199000deb474,0x0006bc61591f25f9,0x0000000000000001}, {0x00084eebf2800729,0x000608b06a4eb61d,0x000b23e73968bb72,0x000a3ae82e886104,0x000d27c8605d2992,0x00033bec6e418a91,0x00029d45f2b49e6e,0x000bd1f4a3f4a9d8,0x000bc4ceaeb2f044,0x000c63b1ef09fa28,0x0000000000000001}}, +}, +{/* digit=29 [{1,2,3,..,}]*([2^116]*G) */ + {{0x000826845611f97e,0x00015b6b1ee54a04,0x000608b1dc092400,0x0009050925698b8a,0x00031b5e532ada13,0x0000c41c46df4acb,0x00090c116e05bee3,0x0009642c127307d1,0x000365a48b566eca,0x00046d5c3cffa21b,0x0000000000000000}, {0x000b8836b9754189,0x00079ea005768621,0x0007bf51510520f5,0x000bbc0ca43d38cb,0x000c9fe21891a0a4,0x000242b093687446,0x0006d618feab8811,0x00047a921f31cacb,0x000cb09d3cf611aa,0x0007d8fef9a8efc5,0x0000000000000001}}, + {{0x00042c81af50749b,0x00081540e019366d,0x000d6072e7b7487e,0x0004156c32da913c,0x0003df1e87478e7b,0x000880f5ccb21742,0x0002347ca344dd54,0x000d15da2c269018,0x000993e2887d2337,0x000379604cc23f8d,0x0000000000000001}, {0x000778d40c2ec9c0,0x00027ec9dd1808f9,0x000dcd7b63f43450,0x000cf65f198a63ab,0x000d3a7a4c38803b,0x000476f99f1130c2,0x000d6b9c1ea5019b,0x00034f67377e991a,0x0009047dfa9f5ad1,0x0005dc80641e2fd9,0x0000000000000001}}, + {{0x000de0d9dfa7af75,0x000eba7ea5710283,0x000dd5435234652c,0x0006f821b8a36856,0x000c319e00261b58,0x000ed079e56ce309,0x0001099e0f75ac31,0x000e2442020d51ff,0x0008b83fa0c077ae,0x000e6fc85e1f8724,0x0000000000000001}, {0x000872b798445d10,0x00032b311d3108af,0x0005040c97d2ca2a,0x0005703d4fa4c2f0,0x0006980d5eb27761,0x0005f074a536c8c1,0x000181395daa1e3b,0x000b672dad89bda9,0x0001f3d94395bd4f,0x0004b4c4a2c81ef6,0x0000000000000001}}, + {{0x000924e7856ff846,0x000ee4f61f664ccb,0x0005ac67cb02e404,0x00050da76b002de5,0x000c4537e3c3c875,0x000c36c052b6b43f,0x000b204b2d5ce01c,0x00088e7f6d0e0c5b,0x000c188bbf930fde,0x000168056f87d909,0x0000000000000001}, {0x0001106b668bd3a0,0x0008dce76203aabd,0x00002fff3110182e,0x000f7d1e1307d3fa,0x000347101339296b,0x0004a22e456ed2ca,0x0002d011b668eed2,0x000b79cf95e5e410,0x0006693b0681d10c,0x000355f94e08ac6c,0x0000000000000000}}, + {{0x000323242b9413a5,0x000d8925b57cdbcc,0x0004d31e6960afac,0x000cc1c8075e88b1,0x0003a4d853d5880e,0x000c2d17b4e21339,0x000c35a1d02b3405,0x000f7f4eb22a29f6,0x0001b6570763f945,0x00008a38d9e91699,0x0000000000000000}, {0x0009e262a8faf74b,0x000d89cdb707d091,0x000c28362e27b3cc,0x0000a8d2e31adec3,0x0004f2e5340b0d97,0x00076d44ac11f1ff,0x000ddee42bd388ab,0x00052165e718528c,0x000c2384a7cb055f,0x000e3bd81cae87a8,0x0000000000000000}}, + {{0x000e0ef29067ec5b,0x000b3efb1759268e,0x00093d33d241c82d,0x0005ebc6b912da50,0x00004cea7d557bb1,0x000a95c0c2531329,0x000338d1728bce52,0x00023e934774d703,0x000bdaa179ff6232,0x0009c05a25267ea4,0x0000000000000000}, {0x000b3f1bf490cbf7,0x000ec049cf21d24d,0x0001567c730a18c0,0x0008c3e0f359d391,0x0004ea1bf7eca8f7,0x000252d4d89f9aa6,0x0007a2e5b2ffd6d4,0x000e70d5197d3cf7,0x000ac046e420f1fd,0x000f82fbaabfd6c4,0x0000000000000000}}, + {{0x00023d833bf81b28,0x000064787960d20f,0x0001e23da2c1a82d,0x000fca0df31fd1ab,0x0000d67beaa32632,0x0009e45d2648f548,0x000d563bb162f9bb,0x000110e02089d434,0x0007082d3a10eef0,0x000cb7b7735d1d64,0x0000000000000000}, {0x000d95b89701e6ec,0x0003bbe61d29d940,0x0001c7d5b4e68b4d,0x00012a5ad78df4bc,0x00047d83302cabd6,0x00011140b2809827,0x000211a754f62795,0x00041d43610e16e7,0x00099e665f0dec95,0x000ee6baca9f0f39,0x0000000000000001}}, + {{0x000657257b2d9252,0x000915208861aaee,0x0008adfc02b5d4bf,0x000f78398b2a8792,0x0002cd1929e3951b,0x0001878fc66ac2d8,0x000a1972453f26a5,0x000c0ebd963c67c6,0x0006feb8829e6f9c,0x000c986a8aecc7ab,0x0000000000000000}, {0x00030636d8df74f1,0x00011de6a5beb09f,0x000247b37675f6af,0x0003d122a04301fc,0x0003f577167d7789,0x000a69addd4d974f,0x000f8be983fc60de,0x0003627055a8d35b,0x000c83aaf95c80a8,0x000a9aa21f06b151,0x0000000000000000}}, +}, +{/* digit=30 [{1,2,3,..,}]*([2^120]*G) */ + {{0x000c1e136664d27c,0x000e853cf04eac1d,0x000599f98901c4f5,0x000f0e3ecbc44867,0x000ee5a12a7f834f,0x000066c152851c12,0x0002df97ca61be6f,0x00027153da2c7383,0x0003e882e14acdbe,0x00030b87567338b7,0x0000000000000001}, {0x000fe8148de5b00a,0x0003a405fd56d3d1,0x000e986a7db49ee5,0x000cf7bc11101981,0x000a9750760e2695,0x000815cb90b6aca2,0x0009f299f5ace2a4,0x000d6b06b61bc3dc,0x0002e5c223b28698,0x000c0b5687880a6b,0x0000000000000001}}, + {{0x000f552c0e5d59cd,0x00029aaaadcddf1a,0x000f071e91a160c3,0x000bbaf777f33e93,0x000696e836178f9c,0x00030ecc6d74f3bc,0x0002571349ec6474,0x000dbbec63ff9e68,0x000eff8b43f624e0,0x0008000d19e23a64,0x0000000000000000}, {0x00060d53484cb54f,0x0000d83eff3832ce,0x00012f600dae89d0,0x00089d2df8745dbd,0x0008a48217cd83eb,0x0005ce0f8ae79b86,0x0004021c2c4ae44c,0x000ea980ca2b0fe9,0x0004146745ab9482,0x0001c2cffa33fcf0,0x0000000000000001}}, + {{0x00076fd51fd99bf9,0x0007e3a2b01fa7b1,0x0001a17875cbebf2,0x0008df20ca98073a,0x0001c738732531a0,0x000c360b05cea958,0x0008986bad316bfd,0x00009591db5fb8a6,0x0008ce8516941db2,0x000cd50df495ad83,0x0000000000000001}, {0x000d46b24a5b2933,0x000a4af0d09b27b5,0x000e34ef392f2b04,0x00028d0cc4e0cb50,0x0005bbe1270619c0,0x00002d927660b899,0x000c444a9beaf922,0x0003686effea3a61,0x000321e427cc238c,0x000fe609075147ce,0x0000000000000000}}, + {{0x000e9dd164c62b53,0x0001878a3599a216,0x0000821091d05317,0x0002cda324ef2697,0x000e94950f2f16ed,0x000815b553eaefd2,0x000f8019f00612dc,0x0001930eacc547c1,0x0006fc4a1fd1730a,0x000db88252d52d13,0x0000000000000001}, {0x00077522a6c4bee6,0x0006b12deb38426b,0x000ca869197aea9f,0x000c43193823d16a,0x00028f12c9d38187,0x00031f43dad5cc98,0x000728a436529c3e,0x000863d40c6f0781,0x000da1798bfbb097,0x0001e17a19693394,0x0000000000000001}}, + {{0x000a20633820f8b6,0x0008884ce6057395,0x000b9e9ac4298b05,0x000f80c79f28e7bc,0x00012abb15751770,0x000ce75763d01472,0x000afbe67296f82c,0x0002a2950d9f8034,0x00031ca6f1179141,0x0008bb87c616f997,0x0000000000000001}, {0x000f27dc8004bd5d,0x0004fc5fa5d017c7,0x0009fdb4deb95bcc,0x00051c1e39917e40,0x000cfbefa777d300,0x0006ebd51f3f36df,0x000089ed9696a852,0x000c58a6c0bc16cc,0x00093efb56723f03,0x000f77e4f7a67531,0x0000000000000001}}, + {{0x00082edbf63cd0fa,0x000fb67ff0d41a00,0x00076aa53cf1522f,0x00099dda453dcda7,0x000bf634bcd8a3ac,0x000f09af12ca31a6,0x00045d3da6aee65d,0x0000b2e1c131b960,0x0001888166f3c7e7,0x000d21cb58f8b972,0x0000000000000001}, {0x000f3e0321dcdf91,0x0009a8d4da7b1151,0x000e3a95788cafbe,0x0007071e39c010af,0x0004b05cb3faf8c8,0x0008a702fbafcfc0,0x000618742c775b70,0x00068aab53d65b3b,0x000b27ffbb84f938,0x000a7508491b708b,0x0000000000000001}}, + {{0x00020328d4b15dd1,0x000274b581eaa62f,0x0008fb2a285d269e,0x0006ea89604b1779,0x000933aa53ad75b2,0x000fa62691d5119e,0x00067e03e002a949,0x0000629215018ba1,0x000ae2796195dffb,0x000282dc1f93eae4,0x0000000000000001}, {0x0000977c61f7743f,0x0008f7654950f798,0x0009f0fcf77422ba,0x00070562b7dc1d4c,0x0008f0b2f76176b9,0x00094ad6c12de606,0x000d53dd34579508,0x0001fc63f78fe569,0x000a90b5214981ae,0x0005ab902dadf9f2,0x0000000000000000}}, + {{0x00006fc86d7474a9,0x000491c759885f54,0x0002d4cddc55bd2a,0x00061045c35aa122,0x0007a2154985eb54,0x000f0dcbe4188b45,0x0006a7e235148dff,0x0006a2535a30d70c,0x000e2be337d8e901,0x000cf899a19ee96b,0x0000000000000001}, {0x000dc1860747030f,0x000a1d519771baa1,0x000e6bf7f8dea4c9,0x000b88d5c44825c6,0x0001648270d80fd4,0x000d7c088d619d7b,0x000e67f50ac4887c,0x0009d1ac72f9cc2c,0x000dce091aafa6b8,0x000ac9b9365de8af,0x0000000000000001}}, +}, +{/* digit=31 [{1,2,3,..,}]*([2^124]*G) */ + {{0x000c9884018b1bd5,0x00017e335350476d,0x000f240ea34a105e,0x0007225c0ca7c1ed,0x0002e60ee9bcde0a,0x0001b7a04f8d5abc,0x000d636ed201196d,0x000fee08dcde421f,0x000648f1c3a41da5,0x00014b37a2b18a4d,0x0000000000000001}, {0x000574ca3d13216a,0x00000c8f4aa46ce2,0x0005e6cb8b142b50,0x000aeecc2cc007b3,0x0008b139d4602d18,0x000857b6e6fad62b,0x000703a0b8035154,0x00047dfe5be4aaf5,0x000e255f15b88d9b,0x000ceeb42f23b0c7,0x0000000000000001}}, + {{0x00027bf41035c3be,0x000003d6c228d698,0x000ac8482db53bd6,0x000f6c6cedd6d84e,0x00055554b59c1199,0x000b3dd0d5c80a25,0x00098fd9a255d70b,0x00088ce8ece5b616,0x00010e4ff0160238,0x000e8b21f2b5b409,0x0000000000000001}, {0x0009be6e93956f12,0x00028be014bad7ba,0x0007941a6f1d6c8e,0x000374aa983d3be4,0x0001ab03efe8a93e,0x000ecc1517778750,0x000a07f3863f0102,0x00022339ade08ce1,0x0002e138fb118165,0x00037ded66083914,0x0000000000000000}}, + {{0x000be450955d0f49,0x000350db3612b4e4,0x0008b05c6937d0f5,0x00091d0bc00589e9,0x000f08134602fbb3,0x00072898cb46a43b,0x0000c3f425983612,0x00092a9319d102b7,0x0002adb9889640c9,0x000f69984da61b9f,0x0000000000000000}, {0x000925b413e1ae3e,0x00046d808d55308e,0x0001e8e95f85495a,0x0001aa328926b87f,0x000e6f7c0b2cf48a,0x00097c234327b453,0x000bc1b584c452ac,0x000ac04a1db1b2a7,0x0002c2df96a4716f,0x0008b35f6c998afc,0x0000000000000001}}, + {{0x000c246de542c405,0x00006abed2f33bb7,0x000d46decdec7b50,0x000afeed50c509c6,0x0007109502cf683e,0x000fa7b0916c8d21,0x000971ce284eb826,0x000b5478a9a06ef3,0x000dbb05d7e812b4,0x000fa9bdf3afd0be,0x0000000000000001}, {0x000c0e4a6519aab5,0x000d79de9fb97617,0x0002d46f889510f0,0x00025cb75085caf9,0x000f963379f4c576,0x00002dc4877679ee,0x000748161e8da062,0x0007933c7094d95a,0x000527ab96f198e7,0x0000a23cef9bb67e,0x0000000000000000}}, + {{0x000254c4bef57a31,0x000f8fe05ebbca4c,0x000036d19011dab0,0x00092f09f97449f1,0x000feb784d8ec601,0x000551e5955591a4,0x00088c74b266204b,0x000fefa58c8cd4d4,0x000954c3d29f9c68,0x000262f04bf8acfc,0x0000000000000000}, {0x0005e5c9d99f906b,0x0005ebe8f2ee55b8,0x000f127eee6b4d59,0x0005b10ba97a057a,0x000c7680e692309f,0x0007c47d151a8543,0x000975bcc38cb298,0x00056b40037e7ed1,0x00069095953732ea,0x000e079710f9d766,0x0000000000000000}}, + {{0x0007ef5561843b50,0x000725adb4b17e58,0x000223554b9e6db7,0x00040d6a298840a9,0x00089b9987d3e8ea,0x000c544359088f19,0x000712498c4e6798,0x0009d49555742687,0x000531911aeb4757,0x000c25edd6bd8c42,0x0000000000000000}, {0x000da2be384ee90b,0x000ed1578452ef17,0x00026ec7e64f3506,0x000d93fd400c530b,0x0006442c14bcb0a9,0x000bc44330eec280,0x000b7a321d894abd,0x000383284ca21784,0x000aabf2cbd2fe67,0x000a0b333a314bbd,0x0000000000000001}}, + {{0x000deccb4cc0fcd3,0x0002b5d6f0d87e14,0x00022447f7757c4f,0x000f03b5e4d05426,0x0003dcf9d56f98d5,0x0001c6d571746b68,0x000648164a40c197,0x00086a775d32054f,0x000bbccdf9c7e93f,0x000ab95b370c616c,0x0000000000000000}, {0x000ad22f9be04193,0x00049e68cea75e3b,0x0004683245da929e,0x000316e38a93792f,0x000965e00dbe19e7,0x000e9c59fb61ef64,0x00094c5036fbab0d,0x0009e4c2c8f5993c,0x000c76d4a049b3bd,0x000c781dc2d523d7,0x0000000000000000}}, + {{0x00010cba8003a62b,0x0002963dead37561,0x00024e572ee261b1,0x000924c14f710c53,0x0003a3234879da4d,0x0000242c6b2bb72d,0x00025965319d73bf,0x000c5d438ac356b7,0x000eb1ea69c1467e,0x0006ea40556d55e4,0x0000000000000000}, {0x0003bb0cfbfbdc6b,0x000292f755482f11,0x000b750229b1fdd8,0x0006dd9d36eb56b3,0x0009fd65055f0875,0x00005fbea1ad24bc,0x000b5ba29626eb13,0x0004c9855409fcec,0x000000d0af627326,0x000b249d561b2281,0x0000000000000001}}, +}, +{/* digit=32 [{1,2,3,..,}]*([2^128]*G) */ + {{0x00097f8c2da756c3,0x00065716b51e78af,0x0004d4e4ac9bb4d7,0x000be63f12ece85a,0x0007f2c2556ca2a2,0x0002341b0c191c3b,0x00063796c15ecee1,0x00092e302dd7df66,0x000d162a4ce9cb82,0x0003dfa7f8ba9276,0x0000000000000000}, {0x000403973587aa55,0x000a9956dae839d8,0x000d9da7dcbd9d38,0x000d0fffb69b8acf,0x000544e0adb2ad93,0x000b2ad644f74f04,0x000e7d5b5de013bb,0x000f944ef674d489,0x000e01d0ea2d2bd3,0x0008aedd32d1ec0a,0x0000000000000000}}, + {{0x0003c3743a6b3bf8,0x00083b2cea274d8e,0x000f6accb4a79b20,0x000ac9cff7eff159,0x000c5bd1a458b1a2,0x000af5afd8c30597,0x000e95f67ad0a34d,0x000ffcb5f547ad0c,0x0002c927ef492633,0x000118d70d201bd4,0x0000000000000000}, {0x00025271d14dfd7c,0x000f83511be77473,0x000e33f2540532d9,0x0002d9c50e1e6624,0x000b9f8f4394e620,0x00085289919c8fa1,0x000d6412359d3b9f,0x000a4c00c9ead88e,0x000626daa054c125,0x000853e0db1f33bd,0x0000000000000000}}, + {{0x000ad013227cbee4,0x0005d963a674d5e9,0x0002422839e1c90e,0x0006f11c073f8abd,0x00051cbde443fb90,0x000f94add68e37cb,0x000d9cdf247fb6d7,0x0003b3ec024c71cd,0x000015c9b5032da9,0x0007607e0d83a94a,0x0000000000000000}, {0x000d4287c9083b11,0x000b167379dfa59e,0x00092871f05ea23f,0x0000a530c1fbcc90,0x000c9b670aaadfc5,0x000840b4f012b3f9,0x0006d74574236725,0x0005827f0582ac31,0x00047f13870e7720,0x0006f314a9061f10,0x0000000000000000}}, + {{0x0003be466658f617,0x0009fd565e43add7,0x0004a046e438ce3b,0x0007e9edef2d69e6,0x0006c7f11d4e7b33,0x0009fce23db4d264,0x0007ee69cfe36cf0,0x0009d497797ff857,0x0000fa9f71e1b23f,0x0002d2813fdfceba,0x0000000000000001}, {0x0005801d34f0db76,0x0008b9ba1d6ad8bc,0x00038f8437efa8c8,0x000755dc58d2c493,0x0008ea5d4147adf5,0x000454e0d19f3138,0x0005174d880f0ef2,0x0006f4ab4400ed7c,0x0002f97c02972f59,0x000bb7fd1f05bd42,0x0000000000000001}}, + {{0x000f26521378e02f,0x0002d730a6852468,0x000763f810a221e5,0x000f48636e9cb246,0x0004c1b9e4959290,0x00093bb4ca5e4a52,0x000f2a6103eedfad,0x0009e3ea2bb0a0a9,0x00013663d597d7ac,0x000a98c50bf00061,0x0000000000000001}, {0x00050b19a3ef90bc,0x0000ea69cbaa303c,0x00074f8f2fe993d5,0x000223c8be835b07,0x000f455e7085ef84,0x0002207ec6b0871e,0x000e48bd79a714e6,0x000daa1613ef3b51,0x00098f36229d3dd8,0x000c2d9134c94bcc,0x0000000000000000}}, + {{0x00050a19f5342c54,0x000dc653d78301f8,0x0006bbf10f389ca9,0x0004326e54a5af67,0x000fdd8a13b29709,0x0008aa3fafda8b65,0x0006c2e3f7baf8bf,0x000bca4111083f35,0x000cdf78842a34d7,0x0002a973106a6473,0x0000000000000001}, {0x000155f05f4ec88f,0x000ffd8679f932ba,0x000e00ae69c605da,0x000b7c72ba823e0d,0x0009e0bbb62edf8b,0x000f7bf5bd871069,0x0004e610f36c3cf4,0x000e41a06519118f,0x00014868b2ff5976,0x0000f7b8d8554854,0x0000000000000000}}, + {{0x0003e5d502754293,0x000e9ee9e0f2543e,0x000a3731f423dc07,0x0003b8bc5bf91184,0x000726f4ea8f1d1a,0x0008035844d23059,0x000c7266e29e66af,0x00082574f0c5767c,0x0001a6dd0e57d5d2,0x0004e537115bccdf,0x0000000000000000}, {0x0009f7ce1bfb6728,0x0000ccb130bc8170,0x00039a62c614cf63,0x00068e187476935f,0x00034de841f4a723,0x00011647b88ac5f1,0x000e09f54f07f6bb,0x000f505a8bf2adfb,0x000d75a5f605b64d,0x0000df9bbeb2b499,0x0000000000000000}}, + {{0x000308733efc5f8c,0x000b75cdb37e83e5,0x00060b5bfda48081,0x0009f06138365296,0x0009688a8974b9f6,0x0005444cc05fb9ec,0x0005a67f252002f7,0x0009664675a1899c,0x000b6d7be11db7cc,0x000549e5e85617c6,0x0000000000000001}, {0x0000536e04ec0d89,0x000ceb7897a84665,0x000b8acad3957bde,0x000ba89439f416b8,0x000cfde12e814bb4,0x000a77e0ef45c679,0x000f35bbfcd091bf,0x0009f3ea6cc5ae92,0x000f66583ff4f9db,0x0009a867f0fed315,0x0000000000000000}}, +}, +{/* digit=33 [{1,2,3,..,}]*([2^132]*G) */ + {{0x000487d30649cced,0x000796a5efc98a70,0x00086f3d00556482,0x000c177d81ed5742,0x000f3693c918841a,0x00044078e141f63f,0x000ad9ccb0cceba5,0x0005cd9ca803f396,0x000a3b9f81f2f890,0x000c5b4318691bb9,0x0000000000000001}, {0x00076e3095e41a52,0x0001ffb6fd45a8f8,0x000a8a0715ef8788,0x000192a0b8d73d7d,0x00086ca88981c074,0x0000f41a80dc66d0,0x0002bbb8f279d460,0x000cb55640383488,0x00052b11c10c7a90,0x000053f89b04d855,0x0000000000000001}}, + {{0x0002e1e8d88792dc,0x00022e3ae581427b,0x00090f869db2e712,0x000e06689d393376,0x000702d537bfdb1c,0x0007346bbf1a9bff,0x00090f54aeeb8464,0x000273c9dd468a0e,0x000c871a654e3afa,0x0007465945d8c3b6,0x0000000000000000}, {0x0000e770af4a5960,0x000be4ac70e87a10,0x000797d6d911c87d,0x000533fb961a5c5e,0x000b8548c0001c5b,0x0009d47191b560cf,0x0009eeca65c8463a,0x000ecad37d2137d3,0x0000514ad716bab4,0x000f8789ad5bc27b,0x0000000000000001}}, + {{0x000dbc583693bf30,0x000ef8d24b6766c6,0x00095890706d31b0,0x000c51cce3a35296,0x00080b8ed7618c90,0x000973ebf17cff3a,0x0009c68d473b1c44,0x0001098525e43a12,0x00074031f5036c9f,0x0001d33955ea92c3,0x0000000000000001}, {0x0006f1c314ce3a37,0x000a4064ddf24cf4,0x00070db52569e1fd,0x000405305ea2c55e,0x000d5f14297acf89,0x00046ea96e034f59,0x000622a42888331a,0x000a102ad1347dc4,0x00088a514e007741,0x0000461db8ec7cfe,0x0000000000000000}}, + {{0x00023847d8cf0718,0x00021ccb2c301d0f,0x00024b1883c46a31,0x00063cce64fb5faa,0x0003cc10bc090432,0x000510506a731fce,0x0009a05134986c0e,0x0003aa30a907d289,0x00071f165d859243,0x000eeaa5074a4066,0x0000000000000000}, {0x000b1d8c9f3b369e,0x0008874f03f7bd39,0x0004a870054ed9a2,0x000756adbd121753,0x0001a9a0d0a37510,0x000529605385faa5,0x000c2eddf5c089f3,0x000a130a237e15a5,0x00074ff2cbd316fb,0x0007ee2c9d3ce137,0x0000000000000001}}, + {{0x0009dbdc68f3280d,0x000657e090c25dbe,0x00024c6421981e70,0x00037a5a5d0a99ac,0x00037fc8c760c5df,0x00044d1a53e37845,0x000ff43dddfe06f5,0x000e4ab44983d93f,0x000c0915a82bb80c,0x000646c74033c3a1,0x0000000000000000}, {0x00004b5d5c7ce211,0x0001372b933ba5de,0x000ea64d116a103a,0x0006df2d3d823414,0x000619b7a1bf8333,0x0006eac1655d2034,0x0009aeedd521f9b1,0x0006d98d98725948,0x000610e8ae934636,0x000efd7b215cbea4,0x0000000000000000}}, + {{0x0005d0308e1127f5,0x000cf03c8e2019c4,0x000aa0237cf6545f,0x000764372510cd18,0x00097139d47739de,0x000a85188927140f,0x00037dc9b8b5e192,0x000b2545731c10b5,0x000991ea59d03831,0x00067dea66743632,0x0000000000000001}, {0x000cc6866cf98c39,0x0009016f3fd54524,0x000592bcebafd818,0x0002f06cc34bdbb8,0x000b6cb2e7a209f5,0x0005749dab7ee649,0x00076406958e2abb,0x0009516d049dfaf2,0x000de5f7e8adfc4b,0x0007ce97062d4c5e,0x0000000000000001}}, + {{0x0007da121df0699c,0x000ad3597a95de87,0x000181d213d52a92,0x00002da71c92de4d,0x000dd3803396793e,0x000c8761f332f0e0,0x0005c1e0d83b70eb,0x00048cf70527f5a7,0x000ceb82fe3e31cf,0x00029a56f1047f6a,0x0000000000000001}, {0x000ae721531eb7f3,0x000c70c79169f267,0x000d345b58d29bb0,0x0006c1daec3533a3,0x000115913b369665,0x00099820ca585f3e,0x000623473863b5d7,0x0003e2b952a9549d,0x00011f22279d7812,0x0007e6cad8cfd481,0x0000000000000001}}, + {{0x000c384b610f9960,0x0009e42d4100e245,0x000c5264e577187b,0x0000ec202477a817,0x0009dc146fbb4cb2,0x000c49fc51a5dd07,0x000dd34b66b540f6,0x000418cb3114a207,0x000042a4afc85f36,0x000592a886f4d479,0x0000000000000000}, {0x00062b5959d642be,0x000c107df28ef33c,0x000c98bc18d09a83,0x000908cb61720266,0x00034bfa40c64e8b,0x0005f7d00d3266ed,0x0006699785d5c5ac,0x00070fda50cded6e,0x000a7129a0528d63,0x000df6226a01349f,0x0000000000000001}}, +}, +{/* digit=34 [{1,2,3,..,}]*([2^136]*G) */ + {{0x0004a83b5020b6b5,0x00064ea6b7250085,0x000f5cc5dee82b8a,0x0007e307a44f4310,0x00061a979f99982f,0x0006271c95260383,0x00087bd9d4a6e7e3,0x000183121a682c2e,0x000a0c42c801461a,0x0009efc46dd1bbdd,0x0000000000000001}, {0x000ff9d53c8adce8,0x0004cbac7e6d6ff5,0x0008a2a18c9ba604,0x000457234e0b1c61,0x0001b538c1881476,0x000d20849fff1d07,0x000e3333d9430380,0x0001d1326f05033a,0x0004a49c4e89c642,0x000e640c63716450,0x0000000000000000}}, + {{0x000a7c6657e0c514,0x00010e4ba5060489,0x00003183bcaf92c4,0x00051063325bb838,0x000624a227afade7,0x000d611fad61ce2f,0x0001f27e1c057fe8,0x000426a808156374,0x00051e188cc3f494,0x000e601fb19202dc,0x0000000000000001}, {0x000f5c4ba35ecd6e,0x000c838b90f28423,0x000ecc8f9f7eac00,0x0004ae3bc63ca5b1,0x0000a61f4eb49abd,0x000e5e94c7586825,0x00050828aa62e59d,0x000ca27ce17d2e20,0x000f7dcd24d94b7e,0x0004ed84ff72ff3c,0x0000000000000001}}, + {{0x000dae22413fe9d4,0x000881c93ceb2c9e,0x000376b68f1c40b8,0x0004d107493ec443,0x000de2613f0552fe,0x000264177a2adbc0,0x00044456850f4d4c,0x000c024b1759999b,0x00032c490b5528e8,0x0004e4fe9cb25fa5,0x0000000000000001}, {0x0002401de7dabddf,0x00056529f2c840ea,0x0006004e218ae4f0,0x00026d7d9745c833,0x000bc1aa8e8c745a,0x000254366c2e1e3a,0x0009a65d176c592f,0x000575f2ce2f5dba,0x000390121cb70eda,0x000ad4df3bd7c9ef,0x0000000000000001}}, + {{0x00052f406338228b,0x00000044f05c5be3,0x0003a7061d336069,0x000371f2e7fd3e15,0x000ddb123a32ed82,0x000a15e8eec0c29b,0x00046b80938b2d11,0x000ba2ae38c19bba,0x0000c4e7466a69b9,0x000ba8e7a0607a47,0x0000000000000001}, {0x000e250e34d513c2,0x0009900d3d611604,0x0002850e69a99aa8,0x000ea018e87aacf0,0x0008ea9b70f5d0f5,0x0009dfec50e62995,0x000ef7267ad0ad8c,0x0009fbbc4dd8a19f,0x000ef73af4e91334,0x000d0636506a6e44,0x0000000000000000}}, + {{0x000533f2ba0eb14a,0x000b9fc6b2073504,0x00059889c71f37ca,0x000d3e3b2957243a,0x00033cd4ef031ee6,0x000e1fa792c82e2f,0x000936a9431aaa2b,0x00075897dee2d5df,0x0005c1a2769038db,0x0004c149337ba93c,0x0000000000000000}, {0x000ff077c9595fa2,0x000b4e92632965da,0x00073090129d489d,0x00024c2f940397cb,0x0000f08747c463ab,0x000063f57ea7844d,0x000a687de4ab15b4,0x000d7bdc8db9dfb6,0x0000393c5c4b7272,0x0002b3cc129fac67,0x0000000000000001}}, + {{0x000d85352986f86b,0x000b3bb5e1a9d134,0x00096ed674c04b6f,0x0001eaebc5869197,0x0001ec13b24f0220,0x0005acb88043fe14,0x0006b2f77717702d,0x0001f913c28eb4c3,0x0008bc0cbbd9e8fe,0x000014871dc376bb,0x0000000000000000}, {0x000b182392919d22,0x0005619062a004b3,0x00084b9c0aa0d96f,0x000e6a14d38134a4,0x000b962e9b9dd384,0x000d2a3f87434945,0x000e17c26111d5b0,0x000cca088afb0558,0x0004109b67e83601,0x000ebef3372d865f,0x0000000000000000}}, + {{0x000c5a0356b17ac7,0x000f616fb80668c9,0x000f7001431d3037,0x0006786061783bd7,0x000e2a8db044a7eb,0x000d63e80e687c5b,0x0006dba72619e19b,0x000b3f54433d79bd,0x000179eabd3da5ab,0x000fcebeded88553,0x0000000000000001}, {0x0001156c4d223604,0x0006fa0e48c3398c,0x000d70c895f6a870,0x0000aa32def1e5d8,0x000a3628036e774e,0x0006fa3b42b31a93,0x0003f15e7bb3f2aa,0x000fd667e0a491ab,0x0002f04b61d5276e,0x0001fdac2e330e17,0x0000000000000001}}, + {{0x000760d231c36820,0x0008bd2a50426c8d,0x000d4451d722fd74,0x0001877484a5084a,0x00019395bd1ac7d5,0x000dc03d6541ad77,0x00068a254b40eaa5,0x000dc699a962f42c,0x000f2ecdd481b2b4,0x000345d9badbf178,0x0000000000000000}, {0x00090c94035684fe,0x000e517a9849bb68,0x0005822be91e8615,0x00067ca7e3c3e516,0x0004c5ebee67a9ed,0x000f03236f5438f4,0x000029ef9e45ec0b,0x0003412d001129c5,0x000bad0b64fd4f4e,0x0000e15f591e3c09,0x0000000000000000}}, +}, +{/* digit=35 [{1,2,3,..,}]*([2^140]*G) */ + {{0x00067ca62dd9afd4,0x000678b2e8cc8368,0x000d7d6c96a2abfd,0x00075f62bb6c702c,0x000988eb9ab34b7b,0x0007b382272a8eb6,0x0005e40ee1d17286,0x000b6f600751bff1,0x000ff996b4ec3001,0x00015d7fb8efdf30,0x0000000000000000}, {0x00062d76a29a2746,0x000f091c80dd81fc,0x000c1a9825d4a2f2,0x000a4fb54ae9b61a,0x000db71a812fcb05,0x000bb96eaaa7baf2,0x000dfd9cc434e4e8,0x000b8fce567253c2,0x000b948eeceeb8e7,0x000abac787b7e9d6,0x0000000000000001}}, + {{0x000566d2087a8f7e,0x000f8d816dab3c44,0x00068ad0a5ea555e,0x000ab76093fa3eae,0x000bcad51a41fb45,0x000c784a1114a732,0x0002d99cd96f3573,0x000f7808bc957e91,0x00022a461547dff3,0x000e9dd3f93d98d0,0x0000000000000001}, {0x000f5792b3bed20d,0x0003199e50e443dc,0x000ab35921f1c5d0,0x000cb763ce7e3777,0x0009ec69a2c8061a,0x0004921d8bd5a1f1,0x000d3f186d49b86d,0x0003d287849a3eff,0x00019a1d3969ee2c,0x00097e7987e8d923,0x0000000000000001}}, + {{0x000e6b3554a3f3c4,0x000c8b48d7c64666,0x0004319bb26494ce,0x00023bd53c15f132,0x000a4b25b7340a49,0x0002c82187e36296,0x00076cb62a70b23d,0x00013ce0a44b3a26,0x000e1376215ada95,0x0004bdcdd5bfa093,0x0000000000000000}, {0x0006f0577c34a522,0x0002d6eb1d23f2e1,0x00074b1ae5a563bc,0x00076c1922ce417d,0x0008d8b56e586f06,0x0003d2111864665c,0x0007a1f4a9d1f08d,0x00009ad18a2eb5b5,0x000f16f69121b144,0x00055ad3dba51f31,0x0000000000000001}}, + {{0x000a0990f6c14c34,0x0002ae1571f4bd14,0x000a7e981428a12a,0x0008a57064ea4bd5,0x0005ec2f56d89f54,0x0004fcfb513a99f0,0x00081deb029c28b2,0x000c16eb364a4688,0x000f6df6754a22d8,0x00039a8e7ba7c29d,0x0000000000000001}, {0x000585b840875f9d,0x0006688b87eab66d,0x00061b8a4aef8f2e,0x000968d01b210ab1,0x0007a38c32d9fcd5,0x000170203f9469f2,0x00027ba7e65bf262,0x0003268e8f3ddf53,0x000d5d6a50d743f2,0x0006f76866dcf3bb,0x0000000000000001}}, + {{0x00075ceb39ee406f,0x000fddc2dbf93cfe,0x00005aa3d0f7d044,0x000c04043459ab15,0x000bfbea051fd1e4,0x0005c86723eeca2c,0x000dd90428637a5a,0x0006d3aca9d581d9,0x000277709f646127,0x000d9e5fdc588878,0x0000000000000000}, {0x0005fdeadee7c5a7,0x000b59b799ae3c10,0x0005e3595acc919d,0x000b6f6b2aa1f7f7,0x000cc519dab324e9,0x00070aa0c81054ee,0x0006840dab1fa02d,0x000ce8162c464504,0x0007fc117382d8fa,0x00079cc63a2e343f,0x0000000000000001}}, + {{0x000f45643ca65cbd,0x0007305e42072e40,0x0006980bc47b22b4,0x00091f480c0959ae,0x000df17382117d00,0x000fb6755fe76ce6,0x0008195083b13716,0x00053ce928778e33,0x000eadd235784446,0x0005f288650fd122,0x0000000000000001}, {0x00032d4f966b7e9c,0x0006ec40795011b8,0x00056106a162f5eb,0x00060472439d72fa,0x000ed9a6959807a3,0x000d3315f177c4b5,0x000b196cd83808fb,0x000c21f3f41dc773,0x000518607dcca40d,0x000920d975bf1042,0x0000000000000000}}, + {{0x00043d0a4a0b7f26,0x000c9bca61488d76,0x00078d40864c9a4e,0x0009191208ac32aa,0x00065e2c33dbbd1f,0x0006b041d84ce172,0x00022f6c73e5e84a,0x0000caf07f551302,0x000e0bc76bc20bdd,0x000a43482195b22f,0x0000000000000000}, {0x000f04c8745c6a12,0x0002b2bdd6ee1437,0x000b9431fd260182,0x000e54b7f10879b1,0x000a6b8d5c027ebe,0x0002358509530c61,0x00071ee3b953e075,0x0001d055e247c05d,0x000f78c21fc120f3,0x000c40b71a77f551,0x0000000000000000}}, + {{0x000ca1655dd01fc4,0x00023cfcdcd83fdc,0x0006fe01dad6f137,0x000a92f448fc724e,0x00071e9506b3510e,0x0002c50316bacd31,0x000812e5b9c38263,0x0005b06a2041b525,0x000d1e51d6095bd3,0x00018f8c9f2aff29,0x0000000000000000}, {0x000e8440d9f6b1c5,0x000d8f5815a76ff5,0x0000ba6e7eb4652d,0x0000cfa7a2d772d1,0x000e12c2c10a367d,0x000122408a9134fb,0x0006be74d3fc999e,0x0007f158ed729839,0x000445a86f173644,0x0008103589b3e72e,0x0000000000000000}}, +}, +{/* digit=36 [{1,2,3,..,}]*([2^144]*G) */ + {{0x00002ef5664a50e9,0x000569e6626b5584,0x000bb9dc4c85c34e,0x0006cac4009d6dab,0x00047cf68656c674,0x000e65ab973336b9,0x000ecf3e266a898f,0x000b5830a2ee0371,0x0007109821d57e75,0x0002643e097669c9,0x0000000000000001}, {0x000e2ad77fec8187,0x0001deddfb754e78,0x0004aaa3d5328431,0x000f5938ac9d56ca,0x0000419e9ec29fe5,0x00089e92d324185a,0x00068c4746f628de,0x00086959a461fd09,0x00039e1752cc1b19,0x000f685c4efa867f,0x0000000000000000}}, + {{0x000578941d3daa6e,0x0001e81a86314a15,0x000e2ec49066a742,0x00085f37e975bc97,0x000abd59fd20aa74,0x000b001318e5e712,0x000bdca951133a15,0x0006057f57ee1259,0x000dad04acbd3b2c,0x0009e7ef3153ef33,0x0000000000000001}, {0x000d37d508c6263d,0x000d87a4e81e7b2e,0x0005a01a3eff8f36,0x000726730288c3e4,0x0009b846f52088b3,0x000f560651a99118,0x000aeef71db52e56,0x000e58e36c06431c,0x000d03f83a3f98d5,0x000adc020099b8d8,0x0000000000000000}}, + {{0x000d0b7b6a8a3320,0x0007c1820c541666,0x000008d89959635c,0x0006f6b2d261e2b0,0x000b20857dc9286c,0x0008490da31aca2d,0x00001835ecf8b430,0x000769b376d5c408,0x0006c3593326d702,0x000ae359276d5c27,0x0000000000000000}, {0x000052b955ccca9f,0x000132f8bdb8b0e1,0x0001fc788aac66dc,0x0007aff377f81134,0x0005f3f5c42cf8fe,0x00063a0cd5ec56c8,0x00044e19f92551b9,0x0005a03e4e9df2c1,0x0005981a18a9c38e,0x00038410aaa01483,0x0000000000000001}}, + {{0x000ab1b79d73f8b8,0x0002c67e2040bd52,0x00089ab066095a12,0x00020058f1cb78af,0x00035c77cb75101a,0x000e13361531375e,0x00075eaea159ba65,0x000a7ecbfca3524c,0x00019d039ab8ae0f,0x00099c623ac91c57,0x0000000000000001}, {0x0001430a249d36df,0x000efe8450eb5d6b,0x000afb92b30c47b9,0x00024beea9991147,0x00039e1752c3ff68,0x000fd6a6252b160b,0x00046e76256f4b47,0x0009076f7bff5746,0x0003f350ce5bbdfa,0x000da84642b5dbcc,0x0000000000000001}}, + {{0x000f59f034423df4,0x0000c74c6502a253,0x00051f6b04936dd5,0x000ac1dfa20fd420,0x000a26ee480942df,0x000b8f32c2aa1793,0x0008f9fd5819aba5,0x000593ae9a68c3be,0x000809f95c514dfc,0x0005832a0100c51d,0x0000000000000000}, {0x00084df91d0b9d7b,0x00019af96dda8b28,0x0009e06515fe82b7,0x0004e7882cd87d52,0x000d3f4a8cd84bcd,0x0005a839e5e4c173,0x000eace8b4e2b402,0x00009c378fed4c2c,0x000b8a183c245522,0x00026032daca8b53,0x0000000000000001}}, + {{0x00021d74b7f15174,0x000b1737719209fa,0x00000c8bba28cfe5,0x0000523f1c2878b2,0x000c0170331c9a62,0x000cd83b50a5843a,0x000131d0381135b8,0x0003a643b75eb047,0x000ef1464d2ab54c,0x0007f362ed0e42c5,0x0000000000000000}, {0x000bb20fbad15614,0x00040a78f8613291,0x000895f7e0d7805c,0x0004b54ca2a8624a,0x0000e6579a8713ce,0x000626e2cc1b0cde,0x00093c66377df41d,0x0009cd6454de0451,0x00009db1f1c3ca34,0x000d91b047b0a149,0x0000000000000001}}, + {{0x0006148c3607c309,0x00072dd5c6a1cd15,0x0004ea2e6d51f4ab,0x000bb9012a38398f,0x00025cc1f09df84a,0x0009c3bace064bf4,0x000f3b1a1aeaac49,0x0008ba0e470586b9,0x00026aca2a7b1cc0,0x00037064de7e58e0,0x0000000000000001}, {0x000f70f6864c071b,0x000cebbcde808997,0x00042d9268c9d10f,0x0001f3646bf97f61,0x00099c6124289f61,0x000f65308f5fa877,0x0003b1cbe10f2164,0x000db1cfb717f6c1,0x0002178fd0705446,0x00053784aa2a3cca,0x0000000000000000}}, + {{0x00032b93eb6bf0f8,0x0008d44a6f35d7f4,0x00062f74f5a61124,0x0008d968ff45509d,0x00090f78b11dcef9,0x000e0fdb4e540d2d,0x000178df19486918,0x000b775c9c48f839,0x000a4516e1546952,0x000548b05a9a422d,0x0000000000000001}, {0x0000e6542e705240,0x000ea85c40801a5a,0x0008cf4381fc9bfc,0x00026551ecff5ed1,0x00006e3765708042,0x000f10bb393addaf,0x0004c0be6d6327db,0x000ade98dcbda7a9,0x00045d1d2c9cc265,0x0001d23919800694,0x0000000000000000}}, +}, +{/* digit=37 [{1,2,3,..,}]*([2^148]*G) */ + {{0x000136d3adf7c0d8,0x000a615150ed1e22,0x00048b602d1f12f4,0x000a438f58c86ca8,0x0006c2ad94dbc8f3,0x0001741520fd2861,0x0006926fc8f344fa,0x000aa2867b7697e9,0x00063769f3f74f49,0x0003389eafe4ecc9,0x0000000000000000}, {0x0003271ab880c04c,0x0007eceb904c8b8d,0x000cf0e8b6b36124,0x000b8dfe9dc846a9,0x000c71bd5a3dcf58,0x000bb872ef46766e,0x000ea257028f76aa,0x00037d56cad75976,0x000e6e410a7a4c1e,0x000aa4d9ef6dff50,0x0000000000000000}}, + {{0x0003f21a068b1990,0x00028b83926d837e,0x00046424f5058ff9,0x000540b150a21088,0x0007bd69839e2656,0x000836bb43217215,0x0008f5d34535e3bc,0x000a61ec6b271f81,0x00014bd57f4cd40a,0x0009c8fdb8302a87,0x0000000000000000}, {0x0006b22f2553a3a3,0x0003b58b7033af0a,0x000213a07cddbf4f,0x000434d1d71e271e,0x0003ac069f3affa9,0x0004ccd448d5d23e,0x0005a3de785990cc,0x0009500536e9dd21,0x0005a1f484316890,0x0008d39f92d8e2e4,0x0000000000000000}}, + {{0x000e463b75bb6ea5,0x000ed0a11789a549,0x000dd32eea4152e4,0x000b779f3244c612,0x000a765d467497f7,0x0001f2317d762ed2,0x000fb479fdc0f1f6,0x0005b625c778a26f,0x00086e4279e293c7,0x000778007cc51b6a,0x0000000000000000}, {0x0008d10c9ca3a103,0x000303626747aa01,0x0009d0d1059a4b9c,0x00047b992888178d,0x0005dee73f8df999,0x0003009b79f58ee6,0x00095bbb19efb6cd,0x000ee364f704fdad,0x00075210ba101581,0x0009e1f5ffb0008b,0x0000000000000000}}, + {{0x00061dbbf0d6ad65,0x00037943121ba6f6,0x000176edfca2325e,0x00061e28f0cef68c,0x00084617ac6eda38,0x0007535e8ca77e7f,0x00023d1d31f498d5,0x0000546d78b2f36e,0x000c7d55e2c3f881,0x000891156a1cb9cf,0x0000000000000000}, {0x0004ce76bf8c0b46,0x000f73894a4c0a97,0x000e4d65f8fc178a,0x000cb9405d4f42d7,0x00089f73dac29f71,0x00028141921d35c6,0x00055dee3cb66f43,0x0003af9effca7532,0x0004e3d9ea981425,0x00042022e23b71d3,0x0000000000000000}}, + {{0x000d0b7e99b465d6,0x000dcdbbc6a7f631,0x000fdb4862b8d0eb,0x0002d00e72a3f599,0x0003fff9e95d96f0,0x00098b66f4cdbc62,0x000ac921634cb2b5,0x000ec0deea0b5c81,0x0005b0a27a76f063,0x0001e02d30431834,0x0000000000000000}, {0x000c98aa1c9ac7a1,0x0007c5a7466568e8,0x000fb66755607c49,0x000ef99d83842e7b,0x0003f63d03b04212,0x000eea39bde1d43a,0x000c0a3d0947a656,0x000da642406f1e3f,0x000c396f50ca4ece,0x00002261add500ea,0x0000000000000000}}, + {{0x000faccc08dd24e3,0x0002a75b2039c36b,0x0007b00e10c370cd,0x000decd44a6f8b5d,0x0005623fd6ab9f44,0x00019a1ddd85e65f,0x0007f5f2f27bfaa2,0x000934e1d6c8baa2,0x0002398cf5bc3e40,0x000936e76ebca08a,0x0000000000000001}, {0x000b72cc3defb1bf,0x0007c48e0f8a00ef,0x000b50a281abffca,0x000290112a957074,0x000c6cc0bcd2913c,0x00080828c73f9cbe,0x0002b7332c142bad,0x000b82fd75dcc17d,0x00071d9dc563b115,0x000fa46eb1fc833d,0x0000000000000000}}, + {{0x000293af2196db74,0x000aa8f516dffa78,0x000ab476917c3f2d,0x000a17a44ba1c0ca,0x000771d0d213b4e6,0x000872d37a8c50d3,0x000a9d4f31d594dc,0x00020ae17df8f34d,0x00012ccecab30c4d,0x000fa5e5b7722b87,0x0000000000000000}, {0x000e6e4b1df4a900,0x0005d66c421f23c8,0x000473d466e42335,0x000dad17c61ddae2,0x000ed279fa7168cb,0x000addca2ea2657f,0x0004d479a5bdfda6,0x0009ec1a80eb84e8,0x0001a95ca1a89847,0x000f2ca605fdb8f2,0x0000000000000001}}, + {{0x0000bda5161e9684,0x00055c62c59939aa,0x0001e39fae89d4f2,0x00072aef74c49bbe,0x00060180fc9e6093,0x00063da12ade7248,0x00028defa823f501,0x000a965a30e8a72a,0x0005cf1083c600ec,0x0004af9f8b968790,0x0000000000000001}, {0x000afd7d7d936a7a,0x00003b13810cfd26,0x00037d1ddbf986aa,0x0005d035eede05c2,0x00071b7ae0b88271,0x000812487895ef9e,0x000f170e50423460,0x00003054f1639f87,0x0002e674eebc0936,0x000654593b42f2ce,0x0000000000000000}}, +}, +{/* digit=38 [{1,2,3,..,}]*([2^152]*G) */ + {{0x000a2f3a1cbc282c,0x000e19a09feeb1c6,0x000c54628c6180b5,0x000cefbae8c61be2,0x00031054eeedc773,0x000005e41190648d,0x0004925364893510,0x000a54e9064644b7,0x00026639e573a22c,0x0003b5a6074dacd6,0x0000000000000001}, {0x0002e1f28cb4398c,0x000fba11161ac99e,0x000aaf012b04f328,0x00060a6cb74a91c1,0x000690cf3c48dadb,0x0007c4e07d1b8182,0x000bed19eb0dacbf,0x0001aba090482e6f,0x000b8c6fb9ea1ef8,0x000d6d4b567809aa,0x0000000000000000}}, + {{0x0006de757b8ee9dd,0x0004f4a9eb572b8b,0x000650813f9e5a92,0x000081024cddfbbc,0x0003e750529ae0f8,0x000c407a678dbdc2,0x0005c643db36c6df,0x0009adee9ab1549e,0x000add1f855d46bd,0x000aedf68182d8ac,0x0000000000000001}, {0x000e2fb66eef3f12,0x00004b24a7282866,0x00050b3c877e75f1,0x000590fae38bb301,0x00008b7b5535d2f8,0x0001b50eaef87c62,0x0000c4541ba355de,0x00098bfe96023f0d,0x000dcf2eadc15969,0x000f41ab8c033f3c,0x0000000000000001}}, + {{0x0001bfbe835763b7,0x000da08736745919,0x000d000c52158859,0x000dbafd4373d9cc,0x0003efeee235e560,0x000fe980f98d303a,0x0004f012a6082ad1,0x000e567ed43eb524,0x000eddca68306748,0x000f954e531e38a7,0x0000000000000000}, {0x0000101b465ee778,0x000f8f4e95956310,0x000bcb6c6057ab1d,0x00052b140218cd6f,0x0000a217b7b093a1,0x000924c99c9b3267,0x0000b388550cfd67,0x000eda396f8cf9af,0x00035154327557bf,0x00098cf74a0d9f01,0x0000000000000000}}, + {{0x000cd9335dea0190,0x00015fcbf855836a,0x0007808f96352fb5,0x0005c5cb374fc6d2,0x0001eebbbb50f586,0x0007f3a5b9a4d0c8,0x000bc6329ed702e4,0x000264f0fada97b4,0x0005e3bbcf73be9b,0x000dd442f9f14de6,0x0000000000000000}, {0x00029cdbcd6414f5,0x000db247ce590b47,0x0005be836ddf363c,0x00032e4b6a8da968,0x000c049bdb9815fd,0x000d8f7528076e41,0x000d50b097db4cb8,0x0007f829470b7fc1,0x000b6caef75b1cc6,0x000ed3d55324b1d2,0x0000000000000001}}, + {{0x0002ed4b0886efde,0x0002e69216f70caa,0x000a19fc084c43fa,0x000bf1fcd447360e,0x00088b44bef17255,0x000c941e542e92c6,0x000c9462ab05687b,0x000f4a55ed27b06d,0x00006c4879438508,0x000b3f5a16cdbf59,0x0000000000000001}, {0x00090da308f335bb,0x0002c62f75607156,0x000ac3878c204f5d,0x00019a70e1d9ebee,0x00065ce18d8dd345,0x00053d4a7a6a59b3,0x000ab840d7a66249,0x000e9f8efc3edfda,0x0006a32d022f5317,0x00072a29be1120dd,0x0000000000000001}}, + {{0x000bdbfdee3c7792,0x000b747684a7e37c,0x0006fd64e032b7ae,0x00031287b0371790,0x0003245ed96aa7b2,0x000bcb2d9689dd51,0x0009eceb1d9918cd,0x00053e6e8dbeb445,0x0003cd8435c2226c,0x000a212888b11938,0x0000000000000000}, {0x0001020457ce98be,0x0009fbe80ddb3555,0x000e385ff7a0d009,0x000821584b1de3c2,0x000f36cd64d47bdf,0x000d2c6d2f0d97c5,0x000126f061319f64,0x00050f118e4e9aeb,0x000dd0fd66a1918b,0x0008c9bb60247ff9,0x0000000000000000}}, + {{0x00006452a69b40ef,0x000a58916404d8d3,0x000489351fe54188,0x00083228fc171eb7,0x000410e07508f15f,0x000b2d0bdc317f64,0x00075755181b0c85,0x000c4ca35cc09ad3,0x000bdec4e4688b7b,0x000ec2f6e18ec10c,0x0000000000000000}, {0x0000b91ff7109c43,0x0001353357108dc1,0x0006db397b6c17eb,0x00038d3f418ed53c,0x000a1a7d0d6f5104,0x000558963fe8aa2f,0x000629ed52f70d0f,0x00070987dde60b3f,0x000b95a72bb4ccee,0x000aae64e168b593,0x0000000000000000}}, + {{0x0009ff50fcb47b0c,0x000001fc1e2456f6,0x0001c124be702b84,0x0007f671a6c9b545,0x0000e07337c72285,0x000d3661d0b0a89f,0x0007db2af0223087,0x0001d9b173b261f1,0x000c65404d0457b5,0x00086eefc1cd30f8,0x0000000000000001}, {0x000fafb34fbb3972,0x000db4c5bd6770ff,0x0000de59815fc7a7,0x000b5602342e8ca8,0x000220e1c9e4f843,0x000b0b7c5b3bfe91,0x000b313a1e2826c8,0x000988ce465ce442,0x000217ce5f2ef9e9,0x000682a10ff59077,0x0000000000000001}}, +}, +{/* digit=39 [{1,2,3,..,}]*([2^156]*G) */ + {{0x00041390c3361b6e,0x000b58054f802294,0x0009b74e1597143a,0x000652a48a901ba0,0x0004b9b4f3635116,0x0005e2ee300afb31,0x00079f7d46228864,0x0001b66e61674d2f,0x00005aad2298ff3c,0x000bd327d6400925,0x0000000000000001}, {0x000b20dd543f093d,0x000dac4b51c2ba0e,0x000bf1d364874c9c,0x0002601310d4063e,0x000c6c8c6fbaa6b7,0x000ce6639ff8b94a,0x000066c91f488ec6,0x000524c600b8f454,0x000ff656ef37706e,0x0008a0434286c21c,0x0000000000000001}}, + {{0x00077e284b1fd44f,0x0001dc37f60445d8,0x00069f0b4dfca419,0x000aa285358c7759,0x0003172cf55e112a,0x000ffea4f47f71ae,0x000412afc352eb30,0x000bc7ffc3d95b8d,0x0009ccbacabdbf74,0x00030dd4b6acd123,0x0000000000000001}, {0x000870d6326f819d,0x0001f9d1598751a6,0x000c925f0b6c6b0d,0x000c309ba890fd44,0x000f1cedd20fe106,0x000408588dc46673,0x00053cbebfbcf6f2,0x000da52fed53b541,0x0002bbf3f7b4aace,0x0008d484a22a2167,0x0000000000000000}}, + {{0x000d633fc6b2523f,0x0003c8573eaf11ae,0x0005f254d2bc0511,0x0001c7fd283764aa,0x000f770135776ee7,0x0003df5ba988759f,0x00065da842051883,0x000b809c0705d522,0x0001067f4912507f,0x000fb628d91a9464,0x0000000000000000}, {0x000e6e2ac33e3aac,0x00065c0000ebfac5,0x000ced796bda6c05,0x000a32836c90c0d4,0x000d2ee187fc8100,0x000d7848e982bcb3,0x000be08290e6b628,0x00085ab586db4a59,0x000b07e2fb9a0080,0x000d56210d8de2f4,0x0000000000000001}}, + {{0x0000ac7a2fd05258,0x00034c744e57f4bf,0x0002edb448a88343,0x0004d56a4c1f9523,0x0003b85d4cde6c8e,0x0003063d710bd23e,0x000833d45b52f378,0x000d2012d08a14ca,0x000ccbe55ff85aae,0x000e919fa9b95c02,0x0000000000000001}, {0x000999b76646e255,0x0001f5f355b09a04,0x00000d64b669309a,0x00089605b2bd55ad,0x000656b121bac578,0x000d693b7220d91b,0x00053ea1faab888e,0x000745d07a303444,0x000e7a52e75e36d6,0x000a7986433618f7,0x0000000000000000}}, + {{0x0002484fcef15b60,0x000485fc2dc91c4b,0x000d7e9f8403b5be,0x0005ec8542217cb5,0x0003f3deede9d858,0x0008c56ddda1f005,0x0009028845902ce4,0x000cdbb111feb2e9,0x000537c2b8f6659b,0x00075d89960f5bf1,0x0000000000000000}, {0x000a9e85b9799e89,0x0001de39c6986f88,0x0000fa555ee69af1,0x000f3b270c555b9d,0x0004c62266b30411,0x00084a11940b0e86,0x0005b26112da8247,0x000fc56950bfb7ec,0x00066d81f8a57ba0,0x0003b772e0aa0038,0x0000000000000000}}, + {{0x000710f55ddf9e13,0x00018f67ff0e8dc1,0x000601481b67ef67,0x00009ffab39b462d,0x000b5ad90ba1057d,0x00018d94f2f83bbb,0x0008d2eed4c7a169,0x00019ddb61a12bee,0x00096ab74dadd029,0x0003902e5753e9de,0x0000000000000001}, {0x000926dcd7de034d,0x000eab5af3e375a3,0x000eb250dce827a6,0x00008bd108623cdc,0x000d49a7d0e9c524,0x00066e3019236fda,0x00040ab55ed033af,0x000667077bc755cf,0x0006972e633b49be,0x00095334396ea43d,0x0000000000000001}}, + {{0x000671c0c20009e5,0x000956db94fffef7,0x000bca8fdc30361d,0x000ebfa5860aa7a6,0x000feca2b724bff4,0x000572f34fd506fb,0x00048ff2e88a7d1e,0x000874822e19430c,0x0003c0129eb20b17,0x0003db07cc6f0162,0x0000000000000000}, {0x000244f5da60b490,0x000fbd8954a885e9,0x000f39699542bf3b,0x000c93a6a7e331fd,0x0009816b29c5180d,0x000ad960c8e85d80,0x0003a3a7931b35df,0x00092e570f2974ab,0x000904daaf442234,0x000cf25e1f700754,0x0000000000000000}}, + {{0x00056e1b7ae8ee13,0x0009b65f8128c4ea,0x000e5e0d92d02840,0x00074f688ed0e1c4,0x000f9c55f66d6f3b,0x000eb2ab8035d3f9,0x0006b643bde4296d,0x000f25e29f7ea7cb,0x0007f5f239b9d057,0x0001af17e3fac208,0x0000000000000001}, {0x00063cbb323c7d21,0x0002b6d926fd3ed4,0x000ab9ee679014b1,0x0007e6093a1bcb9a,0x000dc171705931f4,0x000b0a4387f44f73,0x000c7cdd2a12e513,0x000a473ec3b73ce5,0x000ef17967f341e3,0x000a3809a474c86a,0x0000000000000000}}, +}, +{/* digit=40 [{1,2,3,..,}]*([2^160]*G) */ + {{0x000dc98081f0b504,0x0002377f1bc655c2,0x00067de245fb688a,0x000260cdd7a61e34,0x000d89aaf28a330b,0x0004e078039aeae5,0x000a42253d349d8d,0x000438cabcfed7ae,0x000a9960f3728bd2,0x000af658af568325,0x0000000000000001}, {0x0006e52ab17d640b,0x00019d1bc21ee481,0x00026613d4c31a58,0x000c14072a5969b3,0x0005babfa75ee1a8,0x000c563bc4d35701,0x0000425d2086ecb7,0x000c9b8fafb1a4a8,0x0007ef737c2661a2,0x000c20e7afb2d654,0x0000000000000000}}, + {{0x000726f329838a5e,0x000204b7a9942b65,0x0004a26b80fa33e2,0x0006f40abbf82a56,0x00026970dfcc973c,0x0001c38e96f95485,0x00019abd2bbae55f,0x000c1edd71d62ecb,0x00020adf26d97496,0x0000d917e1cf322e,0x0000000000000000}, {0x000aaf44ac399116,0x00067bb67e29ba76,0x0003d1213c21031c,0x0003b345e37fdfde,0x000dab46f2bbeb4f,0x0003442227ef5d5b,0x0005c11bdace9105,0x00060e12dac175a6,0x000cdb1cf99010c3,0x00087106f2502658,0x0000000000000000}}, + {{0x00044188249a4961,0x000eb8deb1c61cee,0x0006080b71cf8ff5,0x000b75b57b2ccc29,0x000b9ffb3c6aa214,0x0000a50e70e80f53,0x000fd2ffeb156be9,0x0005a94620e80211,0x0005db41e15422e5,0x00055d2030526508,0x0000000000000001}, {0x0009e1933e619307,0x00086b5084131313,0x000b6d55898976e9,0x0003f79536a0866b,0x000b8e06bc0b2a44,0x00034e542863ba00,0x00040e4dd7a73a37,0x0008b2efa3822134,0x0005312ecb0905af,0x0008efb084f884e9,0x0000000000000000}}, + {{0x000172c5ec6e6f32,0x000784d8ddaafa3f,0x000785f2ae4eb6e8,0x000db162f77d65ef,0x00085dec5c58d4e5,0x000a30bffa2375c7,0x0000bb7c92e0f7f4,0x0002294b17a00c92,0x0009107e026f93d7,0x000911ce9dc0950a,0x0000000000000000}, {0x000841c6766f1f49,0x000079724523292b,0x0000e7ddb4cb0490,0x000d47f955646515,0x000b44b2a0877c3a,0x0004c3de4bd8708d,0x0009d24b4a9131fa,0x000585e650ae938e,0x000bb2e4980176c4,0x0001820248559a60,0x0000000000000001}}, + {{0x000cef71c9a9281b,0x00078b2e3e260928,0x000b15a4e8453115,0x000c76cc66031c77,0x000e2f2c06ffcc30,0x000a471db8c352a0,0x000184b9a687b94e,0x0009b19798642e1e,0x0001d84cf08e1a1c,0x000462a36c823a7d,0x0000000000000000}, {0x000b775551fedfb4,0x000c921b0d298e47,0x000071e1319e7833,0x000e6f4ce5e5ae43,0x0001348ff7cbdbf6,0x000c042f31447260,0x00061f1861a992ae,0x00020e5f80d48204,0x0008846b75b72853,0x0005ef4edf14c058,0x0000000000000001}}, + {{0x00051608c9277436,0x00036641c6cf4e0f,0x000263e7b7515b1b,0x000a50636eb6d459,0x000df53679a56041,0x000b4abcaa6ef1d0,0x0005077b47a03019,0x0009d2d427efae97,0x0003dfa9162f30c4,0x000f8bc801e5655a,0x0000000000000001}, {0x000202783ac347e0,0x00001a26d59f4868,0x0003895e6664e175,0x000031f4202e3866,0x00069d2af7613aa8,0x00021cc1e58ddf28,0x000159ee13d84ffa,0x000c8f6eb59a5da3,0x0005df9b7b87bbc9,0x000771b8b6006cdc,0x0000000000000001}}, + {{0x0006aa5bb86ea29f,0x0000e29e7a21c03e,0x0009e430844ee3c4,0x000584b091ca8307,0x0006afb05a033420,0x00015d7ef65dc354,0x000acb0dfae44d05,0x000bad35608c8e97,0x000a78e5d1c181a0,0x0007cad8ba90d885,0x0000000000000000}, {0x0001cba5026e7f38,0x0009593d89eff94b,0x000b88834191828d,0x000881379cd1acbe,0x000c4d9c16250e77,0x000f4d66dbf51b1f,0x000703cbf985d682,0x000998e4fae0e78a,0x000e124668125e5c,0x00095c7096d1799f,0x0000000000000001}}, + {{0x000c267dbe90f79a,0x000a682de8af3a96,0x000fc2373c7d7a0d,0x00046c045ae71058,0x00067b05a94e6008,0x0009ec9a78879108,0x000973f0df20f654,0x0003d4a6c168aecf,0x00050f6bc30604ed,0x000f342722d4210b,0x0000000000000001}, {0x00089badc8348ffd,0x0005ea32767a9d3c,0x000dc1a4baa76ac9,0x000219cd3eced60d,0x0007d2d3cddf3114,0x000c14e1ea557cfa,0x000c466d40b6e234,0x000224ae183077a3,0x000e59e159bfca75,0x0004c30d62fa0c8e,0x0000000000000001}}, +}, +{/* digit=41 [{1,2,3,..,}]*([2^164]*G) */ + {{0x000acef3fd9ab352,0x000a04dda16fb097,0x000e90de3351fbdc,0x0001f9baff197a3e,0x0003610909fc0701,0x0003d538e2bf8355,0x000fbd9d3c214c4a,0x00064b2db047d1ad,0x0000b9e3fa7800e1,0x0001033ba0bb0ce3,0x0000000000000001}, {0x000cb2552f015a84,0x000cdab20301de3c,0x000af7c3af2c8c0d,0x000fe99606c79c8a,0x000d638fb52847ee,0x0009bf56737cb586,0x00000b1ec4f260f5,0x000362ff887d36f2,0x000ed3b693913291,0x0006e3c40f0d7ae5,0x0000000000000000}}, + {{0x0008a516e5648dad,0x00047202a3fb8a9d,0x000ecb3edff5fedd,0x000220d17fb9838f,0x000dc8b9ac40f762,0x0009a8311e23ad98,0x00084edfb615d6c5,0x0004e6c85dc486c7,0x000bf81a7ee5f8f8,0x000ecc58d5bb866b,0x0000000000000001}, {0x000d41ef176fcfa3,0x00078f007acce1a1,0x000d8b8126b20e97,0x000a71b3438944de,0x000134e76c73c437,0x0004a56abd9a1b4b,0x000de8db7385f9b1,0x00043115d58229b4,0x00034725891b4078,0x000c55ba8c32f815,0x0000000000000000}}, + {{0x0008e051939a3b7d,0x00010361ba38d482,0x0009c9a686091017,0x00050f6456db6700,0x00031ba66d450ac6,0x000e0bdd4225b759,0x0006e52d315738bc,0x000d21403d74797c,0x000a041eb53ed58e,0x0002f948ee60c564,0x0000000000000001}, {0x00014e408d1cd601,0x000cfebde9152461,0x0004123bd5f4532c,0x00083ab7b9fe9b7a,0x0009704a01b31e49,0x00040d9c79a4402d,0x0009ff5b8e0a168a,0x00048d442aea1790,0x0001410d782cc3c0,0x0002bf2d98ba10cb,0x0000000000000000}}, + {{0x000943818d1af858,0x0005d42684f68399,0x00068a5f9139d27b,0x000d03a1a3ed9c84,0x00024e699de7f9f9,0x000ddd7e41e31174,0x00089cc967769d86,0x000a0e9e00b5f6fd,0x0007b63934a6926e,0x00011c5b068a8b3d,0x0000000000000001}, {0x0007d21cfa86aa41,0x000f529a2aecb429,0x000251f8677cf147,0x000bad3bd2a35774,0x00090bedc57bbf0b,0x000a31f1dbfe5b37,0x0001e75b3cb7422a,0x0006476bcd9901bb,0x000278bd8b31cdbf,0x00082a6fb171258c,0x0000000000000000}}, + {{0x0009d9b88bd44811,0x00086c7bafe985de,0x000eb018e7fc2f20,0x00037a5b53cb3738,0x0000a097f28e364d,0x0000b5541e546ab4,0x000530e972bd2ec0,0x000b65a95e020994,0x000221ddc10db4cf,0x000295000b94fc68,0x0000000000000000}, {0x0006ace5e2ed6000,0x0008ffd606613047,0x0002a24af3b853da,0x000aba583e1b87cd,0x0004618719533717,0x000d61f56ae2be40,0x00025ef5e9069ea8,0x000f94027fe98e78,0x000db6fc7d9c1583,0x00075271696c0d71,0x0000000000000001}}, + {{0x000f12734c3ec92d,0x0002bb3d48fbed19,0x00049bdd26ff69ad,0x000fbf26985b989b,0x000ad451c21eb61b,0x000237a30e35f12c,0x000a3b3680a082df,0x000188ebe4c92751,0x00087a8fbc731694,0x000b03a8bdfe9408,0x0000000000000001}, {0x0006f89f4e0d5883,0x000d80de19c8b935,0x00077afef27eab9c,0x000538f8f941390d,0x0002b8c79f62a16f,0x0004a907ee9a2c1a,0x000951eb7aa5d968,0x0001fe7d75aa9877,0x0007b983b59fbafe,0x0002bab437db42c1,0x0000000000000001}}, + {{0x000bf512d363aeb8,0x000e0db50c6d9411,0x0000e1101f753fc2,0x0006d62a0ded1b7d,0x0004a1ec0fcb3b8e,0x0000a9719f9cb02e,0x000fa60331be1189,0x000525c569643656,0x00081aa5691f4f2d,0x000a963a9ea530b1,0x0000000000000000}, {0x000098b88fd83f01,0x0009e9aed5969329,0x000769c1597dbeae,0x0003f34dc1aadb7c,0x0006d041d0f773cd,0x000dcc7a18555ae3,0x00057b66cab6672b,0x000c3dbd797513fa,0x000ec420f27eb3f3,0x0003c62ce13b7853,0x0000000000000000}}, + {{0x00057f7ec577ceaf,0x0009584ce56b583a,0x000ce15377e1306d,0x0005b26b1e23a49b,0x000f42d98c317bad,0x000c523283ae8b11,0x00081ddf50073f0d,0x0004ab516099e7af,0x00029299e519277c,0x000c0d8cb7cfdd6a,0x0000000000000001}, {0x00029a85f4a1c822,0x000b7e9213cb42ad,0x000364e5e4a37030,0x000a3941f8a54d03,0x00050b7d507ec771,0x000db1def4d6f8ad,0x000eab3bd493bf4d,0x0009716822a9c65e,0x0005d463b7e2f601,0x000728062fa75d1d,0x0000000000000000}}, +}, +{/* digit=42 [{1,2,3,..,}]*([2^168]*G) */ + {{0x0002ee214ad0e3d6,0x000d51de6a66c4a4,0x000c1ce94446c6c7,0x000c0d5dd2eee21b,0x000e88f8f4a8deaa,0x00055296fd5914a3,0x000dd876c3945207,0x00083798ebb4e647,0x000fd6484696a7a6,0x0001d866ec9d8ec9,0x0000000000000001}, {0x000ca34e120495f9,0x00050701e46446f4,0x0004431e6d90fc27,0x0006b7610b310d40,0x00086e5199614976,0x000e7e80f704e266,0x000aa764f7efe74a,0x0003d9535c6d9829,0x0005a23c25702e18,0x0000a0457bd92a75,0x0000000000000001}}, + {{0x0009cf085024c2f1,0x000c0aff178cc9fb,0x000cd1f6670717cd,0x000588548870fa8c,0x0001a99c44c6bc4d,0x0007a4c31ed62743,0x000f88c552f232dd,0x0008940140f085da,0x000a8211a1d88681,0x00041216e4c1b09a,0x0000000000000001}, {0x0006cac59e6c3159,0x0000ba3374279c4b,0x0008991eda2c878a,0x0003b4cf84ea0b3f,0x000025e729a3932e,0x00047222c0cc5f31,0x000ba94b4346c5bd,0x000e2995032ec5c9,0x000db493f41a4bab,0x00024e7b6e042b7d,0x0000000000000000}}, + {{0x000aefc5789d3eda,0x000070117b5af24b,0x000a5c6b9c3050d4,0x000dbfc9621085b7,0x0006f4c0b7973deb,0x00006f6cf4b4e834,0x000082f092a35673,0x0002d877db7b37b4,0x000c2eac8682b506,0x000eac10f86afedc,0x0000000000000000}, {0x0002caf651b8b0a4,0x0008310eef2a1934,0x00026025b8808ec6,0x000dcff1e64f055a,0x000a67192e09ae5e,0x000d785482258125,0x0007daa7d24e92c4,0x000a9c45e5162876,0x000fc7c72fb7aba4,0x000522976bb5f88c,0x0000000000000001}}, + {{0x000921c0f982798b,0x0001a2079475b7fe,0x000ea0fd52e410ea,0x000e44af77d4bbcb,0x0001f260a54b0212,0x000269af2ec66a7d,0x00034794993bda84,0x00050b15e358d04f,0x00067a4d30bdfadc,0x000e912250ea3d1c,0x0000000000000001}, {0x00083de4fe7bebfa,0x0004fdfb63579e27,0x0001abe0cbad5ac8,0x000820014b8a145c,0x000a85d987c51840,0x0009eba9aacfadab,0x000291af5fccfd5d,0x000785e551a982de,0x0002bcee4372c455,0x00049c9d89842d5e,0x0000000000000001}}, + {{0x0000817678d00826,0x0003072fc12b3906,0x000fabe24fd4868f,0x000b2a4f9e0b8813,0x000ccd87b27441cf,0x000e7fd0a48234db,0x000ea747d9a2a9fe,0x000c91ba0d4add56,0x000c9d0dd2d3e7c8,0x00005660e4fd17f4,0x0000000000000000}, {0x000a904f88c1be1b,0x000e5cce4c6964ff,0x0005fb6194a74952,0x0000f033d222444b,0x0008c26fbb11965c,0x00055ed1ac1d1bab,0x00020c09d970630d,0x00075b608324cefd,0x00050cf259835d15,0x000462cd49bc1143,0x0000000000000001}}, + {{0x000b46239d54de36,0x00013af2871bf6df,0x000bb6d9f31a1b7c,0x000528b0f5b2569d,0x0006b9497778a81b,0x000c963043af6788,0x0003bf9954a12672,0x00059feeec8df36a,0x000d60c22b5fdead,0x00060d265f0f8b6f,0x0000000000000001}, {0x00050d0b6534b1ea,0x000703b71e08797c,0x000d2bd35e284a7c,0x000105aa68827a45,0x000902245c12e4ca,0x000f1afdb8eeeba0,0x000caa7693b8db6c,0x000824a39f45018e,0x000945d0c9d12756,0x00055f86289ff82e,0x0000000000000000}}, + {{0x000f246813a5e2f3,0x0004d2dd1bc96870,0x0005743352958a8b,0x00007a9386d4a79c,0x0008b4a29091d043,0x00059ba9e47bd2da,0x000478de8a606e11,0x0008c9f2a8c27ae1,0x0002946224c1c93c,0x0003ef3adcff2ded,0x0000000000000001}, {0x0005100b79546483,0x000ac268f6c48348,0x000e4b2ec17a54ad,0x000f85818d6815bf,0x0004f425318546e1,0x00013cbacecaadf3,0x0006d908fa2a9c92,0x000e8808196d6c46,0x000ad801f4a291fd,0x000b7ecba0623fa6,0x0000000000000000}}, + {{0x0007b0f39088ef39,0x000a435ae74e03d1,0x000fbdcdaf3b17b1,0x00090868e5084910,0x000019102285b63c,0x0005454d88d8e63c,0x0009e2380d185fed,0x000af9e19dfe50f9,0x0008e09d7ce8d3eb,0x0000155127749872,0x0000000000000000}, {0x0007fda1b031ef4b,0x000dfd7188feeb77,0x0006801e0f6f597f,0x000e9d1729652f82,0x0009d58dec034252,0x0003cc68d0c6aa0c,0x000a4e76779b37e4,0x00008d509f569c62,0x0000c41330558ca7,0x00056956b5657bd9,0x0000000000000000}}, +}, +{/* digit=43 [{1,2,3,..,}]*([2^172]*G) */ + {{0x0009008a556937c2,0x000f76241f10378e,0x0004e7ecf0092193,0x00097f48f8905d70,0x000c86b4870ad280,0x000f86eb6f389aca,0x0003ffbc3b9a3132,0x000a9c6b9598fe5a,0x000429f1014fb463,0x000e06408908552f,0x0000000000000000}, {0x0000c94ae41024de,0x000a6dd0399afa53,0x0007da5ef17ac70c,0x00080b49854eb299,0x000104afd62b1e2c,0x0000b1375777d7cf,0x000794db8dbecfef,0x000ff21b1b05dfbd,0x000f1e68e47404db,0x00080928abdaf296,0x0000000000000001}}, + {{0x0001636898bf4d11,0x000fb75ab01bffaa,0x000ba4b1f3e58bf7,0x00059cab50bc67e3,0x0008acea4689ce8b,0x000f1932a30d30cf,0x0006e5cb3d1d8eda,0x0005fa7949e492c0,0x00041db2db16d8b2,0x000b0610d851b96f,0x0000000000000001}, {0x00054a2b36667691,0x000ca196d36fe2b1,0x000766e2a6109d47,0x000f9263f1863dba,0x0003be92b5a5ba8e,0x000aad9918a5da16,0x0009189520c8298c,0x00010a27963af5e7,0x000b8c3b84ab05f9,0x0007bafd0103c420,0x0000000000000000}}, + {{0x000e3e45f8d73683,0x000eb8ebb6d11caa,0x0000f274ee508fde,0x00020c83562c576b,0x0008510e47baeee6,0x00079b810588c571,0x000894a919ff42e2,0x00007edf259b927c,0x0009d16a223100a0,0x000a5b2acb9ccb16,0x0000000000000001}, {0x000e8415a9179d06,0x0004b594d74f07fe,0x0004fb6e0e5cacca,0x000788b708cc549b,0x000c0c62edae508e,0x000b9ef886c2847d,0x000e40664c8eee69,0x0003ed24b57a9dee,0x0002b9d44a547432,0x000a6f16f12261ca,0x0000000000000001}}, + {{0x0005496bc42e6e51,0x000d33d320585033,0x000cf402bd388067,0x0003e6730074be0b,0x00043e8db4e94291,0x000f7beef462a0cb,0x000e58a8c2ead81c,0x000b97eccd5df06d,0x0005954e3501f23b,0x0004b4a8b8e4e11d,0x0000000000000000}, {0x000598c1e025da1b,0x000b09bf9648fc1d,0x000d224f8ad9987c,0x00065a60d88fba1f,0x00054d86a1d9f606,0x0006c4ad1df1e7f7,0x000e1da4acf77f72,0x0000938971a27713,0x0007fc94e0f78da1,0x00083992811d7d3b,0x0000000000000000}}, + {{0x000c9cc6dd4a5914,0x000862d80be96443,0x00008c7a249fd0f7,0x0001ea54a0d2c9f8,0x00048d9e55013f6b,0x0007ab76e8d002ac,0x000cbf4462d73cac,0x000faf5cdb58c492,0x000ca322b819e5c1,0x000b840745406425,0x0000000000000001}, {0x0005f739a14940b4,0x00097d20ee2a886c,0x00035ab04c341a53,0x000f7a9d2904ba7b,0x000d9cae762f47f9,0x00007d2eaeeeb5be,0x00070ab079042e0b,0x00060a339ed63e5f,0x000c7b9658ba8e43,0x0002d18d85499745,0x0000000000000001}}, + {{0x000b401e3813737f,0x000ff61118cf0239,0x000909b65cbad1c8,0x000da081fe099573,0x00028cfc70caa9fc,0x0002bfc31062db69,0x000e85af4aac9c83,0x000ba3d1d4e51a7e,0x000363dd1405fca7,0x0009117097ec2370,0x0000000000000001}, {0x00065c78edf4f376,0x000f36321b45daed,0x0003283085bc71ee,0x00018a85f5b5aa08,0x00055758f2c2f181,0x0001623497212c90,0x0006ecdfee014f92,0x0000a48aadb790d1,0x000881e12f4528d4,0x0004482acaa286a1,0x0000000000000000}}, + {{0x00050bbeb7940a25,0x000eb62b0dec1d2e,0x000f7146dd0fa42c,0x00051beef911c829,0x0009947cccb28e02,0x0009505362c5e903,0x000767ef06d55451,0x0003dcda2ee6b16e,0x000b2373652d7be8,0x000cb5af116c86d2,0x0000000000000001}, {0x000d36b874b6449e,0x0002d7bb963c1def,0x000de8609229e57d,0x000375fd0ce127b2,0x000b5890dc213b70,0x000a1d88db3c82d4,0x0007b583b09ebdc9,0x000cc6b137b10089,0x000cf29a5fc13efd,0x0001907605ca17a3,0x0000000000000001}}, + {{0x000665e2bbfdb04a,0x00017e4232c5cb5c,0x00026232f5f9a245,0x0007a0275981cd79,0x0005ae253d4d80a2,0x0006c00bb7783b1d,0x0004c2589b5ab0bd,0x000f6c48caf740ea,0x00082e177fc5351c,0x0000fd2b0e714ba4,0x0000000000000000}, {0x00052b5ad6ac73dd,0x0007a311881ba785,0x0004ccac10cfb206,0x0003dcbe5d449097,0x0008b8873accd901,0x00080d70e5b2cf2a,0x000440b2c2817333,0x00067c3b711d4631,0x000b996623747bc6,0x000383423c70b2d6,0x0000000000000001}}, +}, +{/* digit=44 [{1,2,3,..,}]*([2^176]*G) */ + {{0x000b11d1789dc869,0x00016c2eed227fa8,0x000916842cb7fd9a,0x0008564ce12a5d02,0x000bee59ed474675,0x000e675f354b48f9,0x0005d69ece126be8,0x00018ce3aca2f7c7,0x000768d6000f88d2,0x00090f26ea6ff29a,0x0000000000000000}, {0x00096ef4ce69e270,0x000f2da0efb2f05d,0x000a99dc276ac3a2,0x000e0342757c443d,0x0003b390d2a5e23c,0x000e7ea78e9b674e,0x00085e132e72b987,0x0006b6c21856dca4,0x0005bed8cda17d0d,0x000237220788bdee,0x0000000000000001}}, + {{0x0002364996ca25a6,0x0007ec8d70cd440e,0x000d8467c5161afc,0x000408724c9aa882,0x000b962a215cbbc1,0x000c4986c1ad6d3c,0x0001332912aaf7a6,0x000d6db2702d8369,0x000a17e017d4a1ec,0x000f2dbf2405e93f,0x0000000000000000}, {0x0000641168090c5e,0x0006fce42ae3e68a,0x00039938713395b0,0x000394a15bb1098f,0x000db97734c1bca3,0x000edfc62ae8c0be,0x000bc2f9b0452cb1,0x000304c79c90c661,0x0000dada4e625332,0x0006fc2e4ae4342a,0x0000000000000000}}, + {{0x0001bd7fc156252b,0x0000ddb25b337fb0,0x000ac5d025ae1e66,0x000c26056a73c379,0x00095dede6af2b69,0x0001ae9121b7e81b,0x000754f6cd030d2a,0x0008b47d1e9a5f7f,0x00025d238c9b7c0f,0x000d32d6fa902ce9,0x0000000000000000}, {0x0005ace423d94184,0x00056f6ab6a655f9,0x0008fa78d47709a3,0x0003f5d39d32f258,0x000beab0a90b8c58,0x000bc517995d68b6,0x000ea4acae9d65d8,0x000fd569fb104a80,0x000b09db02cb3b12,0x000c624b3e1e5f67,0x0000000000000000}}, + {{0x00093cbca6dca0b6,0x0004a2146559221e,0x0006c357ebc20032,0x000e73dafbe29569,0x00073f1c77b70537,0x0002b0a8e959d415,0x00055d9c50a71dc1,0x00037c9b3656d184,0x000283b617fcbc17,0x0000976acf8093d9,0x0000000000000000}, {0x0008b573715b4734,0x000173f0027024fa,0x000386bfccf3b38a,0x00095480bbc99c54,0x000668bfbf241bdb,0x000353dffbcc88d5,0x000216b7968e8858,0x000de22f661faa2a,0x000189437f0cc373,0x000c1f5601679c0c,0x0000000000000001}}, + {{0x000a86967182c501,0x0001f634e40148fc,0x0001c864ffbfa398,0x0009d6d142879632,0x000443e4b6047507,0x000e1e5a879eef57,0x000d2b8fd7f7f136,0x000d19b6378838d5,0x0007815ed1c2726d,0x00042ef17abcb4c1,0x0000000000000000}, {0x000b9a5999895b25,0x000be140e558227b,0x0007f28ae923d146,0x000d00a58852f582,0x0000e60ada16c8cd,0x000158a85a7def11,0x000e5c61d1152d28,0x000d4be61bf1a55a,0x000cf413c0a31606,0x000b3cd625cdfd8f,0x0000000000000001}}, + {{0x0003f2f8ccce2027,0x000fd5cd45c4a564,0x000a6b2411224a0a,0x0007a5ca2258c4c8,0x000678f855fedfa8,0x00055199f43975cb,0x000e9a39edc6298c,0x00007312684e5a48,0x000adaeb9f55daba,0x000b39c9f5f377bf,0x0000000000000001}, {0x0003e0968382a7ce,0x000869c70ffd115a,0x000ba001f2afcccb,0x000107bdfe8068fd,0x0000206868f7c124,0x000821a90928b9fe,0x000afc533728dac3,0x000b3e9edff0ac94,0x000d10c697f67565,0x000bea250773ba0b,0x0000000000000001}}, + {{0x000275a2c8f91400,0x000bb4c241f78224,0x000c4fd93b4ba60f,0x0002941b616268c1,0x00020107f7964087,0x00031b438825e04f,0x00019247786625f8,0x00028de20083c5f6,0x000abde39791c6d5,0x000b3b75c25ecfb0,0x0000000000000001}, {0x0008e09f47b9d8c3,0x0009374c6bc5ceb5,0x00038e27941b3112,0x000e3235cee2666e,0x000ea8dbee896ca0,0x00030660009b498d,0x0005f8f0f2897645,0x0000fb5ee44458ff,0x000fb559aa7b5e14,0x000272ac85e138f9,0x0000000000000000}}, + {{0x0009f0c6193905a5,0x00013e99256667bb,0x00027fdbbfc34892,0x0000d2c71218ca33,0x000915a83f00e563,0x000d628331bdc8df,0x0003e8128ee96b80,0x00016a5f7e06bfe7,0x00016364a2a7cd33,0x000c748cd2a08bdd,0x0000000000000001}, {0x0001d90fa51d3800,0x00020c814ecb8822,0x00000fc79208b5df,0x000f252076343a10,0x0008a14b68032c99,0x00054fe0dc71413b,0x000d97c9a173cb46,0x000c85a386e9a9ac,0x000bf160a14a40bf,0x000032849e997087,0x0000000000000001}}, +}, +{/* digit=45 [{1,2,3,..,}]*([2^180]*G) */ + {{0x000384b0dc2ffbb2,0x000e0c16c289b477,0x0009eabe48cf9601,0x000199d671ddca51,0x0006f3fce7863b3f,0x000e01be3ea3ecba,0x000b70167c58c7d2,0x000f4893679afbf4,0x00019a4362cb78d1,0x00061515a3d7fee0,0x0000000000000000}, {0x000f2840f746e722,0x0002ef160c51fc25,0x00097156a16516e7,0x000e8398d9625db3,0x000d63f5b2c0ebf6,0x000c5b6523651404,0x000476dd10c4d87f,0x0001f40ffa318eef,0x000788025e5d3977,0x0003c298fa2547e3,0x0000000000000000}}, + {{0x000523e81658a625,0x000aef8e050759b2,0x000b0377d5042659,0x000b9ae72b36823c,0x0007eff957169419,0x0009705cebf46fc1,0x000bd18b61ce7ad5,0x0007a7135b602fff,0x000f2e092fe9192a,0x00074d30a3a8e596,0x0000000000000000}, {0x0007c895ead96751,0x0006523da4889766,0x000467afe86eb732,0x000a5ee25b7a7cf8,0x00000f2568e46393,0x00079a3304b15dd0,0x00036bd203f1569b,0x0009a5e938c0d91a,0x0001da1271a34645,0x0004c688c575bf52,0x0000000000000000}}, + {{0x000c62a6b633bf04,0x0003c0eaef0121c8,0x00058d7354098cc5,0x000448cc925273a9,0x0006f73c56bf4c04,0x00042b800bc52be4,0x0008d6b39147d475,0x000444cb5cfe3029,0x000d4247fb2312e0,0x0007054c4d89dd9e,0x0000000000000001}, {0x0000edd6a97a9163,0x000582ed4f4d5b46,0x000b9ca61309206a,0x000fafa93e18c6dd,0x000bda68f9bb8a3e,0x00070a52c8b2d783,0x0007728c0dda564b,0x000c0dc789e7dbe4,0x000119aa3e8a6481,0x000bed27f421a4e4,0x0000000000000001}}, + {{0x00001ee133405081,0x000b94055dadf3f3,0x0008803374bd3d6a,0x0000e431a078817f,0x0000ae1298465c73,0x000a08da98aae817,0x00076bc8b779119b,0x000c1b8f7410f128,0x000bc98dcbe46247,0x0001761805980867,0x0000000000000001}, {0x0009de67dab5cae2,0x0003d2d0125b70f5,0x0008c5ad3a01682d,0x000cf59a9c7c1b26,0x000ada095cf6362f,0x000b79b1ed6482c8,0x0002b3bc253c84e5,0x000756917d1dd695,0x0008f439fdfad9c3,0x000651a63232aa5c,0x0000000000000000}}, + {{0x0003a055275e1f13,0x000bce620ca4b51f,0x000765c9fcc48133,0x000387e5710e23a7,0x00041d9c294797a6,0x000fe4eedda6621b,0x0009f733bf9d9ac9,0x000e4cb8a3045df1,0x000d5c96c4f51d70,0x00041a25c50ad245,0x0000000000000000}, {0x000acd86687a04f6,0x0009bc4b6a5c45b3,0x0003f85a2b09f7d1,0x000f69420758494b,0x0007e554c9337d50,0x000ccb9c2f40c240,0x000e482c5dfc1a60,0x00016ad44e8b11e7,0x000d080e60fea531,0x0001889fd549f4ed,0x0000000000000001}}, + {{0x0007e29c5ef5cdd9,0x00046b2b2e558b7e,0x0004702314f3e6bc,0x00026fae56eeaa30,0x000145ca44a1b067,0x000ea8da792ee6f2,0x0007e4c829cf9680,0x000d723cb279141e,0x000c514c645b326c,0x000b3d5e8e8931da,0x0000000000000001}, {0x000e5ed0862bd48f,0x0009404a34e74e61,0x000e1d4a98483644,0x000f45001f65c56b,0x0008e062ee7183e5,0x000a39ef75aa764b,0x000f4509012ed646,0x000742837f0ebdde,0x0009ab588faa786a,0x0008d7474accf0f8,0x0000000000000001}}, + {{0x000f31aa7add26e0,0x000b5f70683b341e,0x0002190eb5f5ed33,0x000e3b2bf3278604,0x0002cdb29e4008f6,0x00042f0700c911a6,0x000f5e3688f5189d,0x0007c2de5c257eff,0x00089c193e2d4667,0x000cca5de47c9861,0x0000000000000001}, {0x000dddac10383cca,0x000803caddccaca7,0x0000778df17cf555,0x0009278c5faf93e7,0x0000e7cfbb523b02,0x0003ef004ba7546c,0x0007290d52d052d3,0x000f54a34c36c895,0x000e1b89dcc555fa,0x00058777136cbca3,0x0000000000000001}}, + {{0x00060b5ef6c20e82,0x000bf430fe1ead47,0x0003a480e70d1479,0x00097c0aba684ec7,0x000549990971954c,0x000a1c5645d306cb,0x000cc85cc5c264ce,0x000739efac323d9e,0x0003b20c4465cbfa,0x000b4ee9cad749e6,0x0000000000000000}, {0x000242934808827e,0x0008a9860bc18213,0x0007a452bdb41b29,0x0006c3f651ceda44,0x000f153ca2965078,0x000e0cd8cc7845a5,0x000c9cd5913baf87,0x00050312de2e060b,0x000a1444279bfb31,0x000ff8a16f8265f7,0x0000000000000000}}, +}, +{/* digit=46 [{1,2,3,..,}]*([2^184]*G) */ + {{0x00033bcc8924eb55,0x0002e9d518ffb740,0x0001ae0cd732da2c,0x000cfbc19a4290d6,0x000d8784c1f06357,0x000fe209893ca1ae,0x000969a85a8dedb3,0x0009c8eb2e932f87,0x000bcc740550ff52,0x0004f554bf85aafb,0x0000000000000000}, {0x000bc6372d7f8438,0x000dc0557f4f2ed5,0x0009d0c30f3c2efb,0x000ddabb262ac2fc,0x000f7a05b87d4d5d,0x000c91e745769d1c,0x0008c994d0a4907f,0x000889250072dcd3,0x000ffae1ac453a28,0x0002a8e72458000d,0x0000000000000000}}, + {{0x000d9177fbc76a5c,0x0003975e3cbf7406,0x0002f09def039ed5,0x00034da80caf736f,0x0008efcc790febc5,0x0000ad47e746448c,0x0001ca336b92fa7b,0x000b90e92c64c767,0x000dfd8d6637080a,0x00032f5711517b52,0x0000000000000001}, {0x000a0257ff4a1581,0x000bc02441238656,0x000364971ed77234,0x0008b1d09b2d316f,0x000bfdf4ae5e00cc,0x000468fa8d307856,0x000805be3791c041,0x0003fa589236fc69,0x000a337620c1fe73,0x0001e737b5760989,0x0000000000000001}}, + {{0x000e1990ae2c44bd,0x00083ee2175b6a29,0x00005d1fb5989698,0x0001375eaf1c4bd3,0x0009f54aec5725cd,0x00017c1f0f7d222f,0x000f9f96b74e2d73,0x00053fff253f88e6,0x000b31a11aea1b12,0x000aa32748b4a307,0x0000000000000001}, {0x00007b074c7b461c,0x000258e6e4224b52,0x000162fc7af983c9,0x0004966825052f5a,0x000f9138a0346a4a,0x000a7041242b7952,0x0000a366f5699476,0x000460c88c7d5eb7,0x0003f2b3125e31d3,0x0002a892d14ada09,0x0000000000000000}}, + {{0x00001e6a21a7b432,0x000c3971b4886b8a,0x000dae7cb7883120,0x00059d28f3efe6ce,0x00028e1699713fd6,0x000252af65756250,0x0002a3acd7c4a210,0x000f7efc9c5a81fe,0x000e2a5f82fab4ec,0x0005c0924441558a,0x0000000000000001}, {0x000495dd493563c9,0x000ccadf9b0e7295,0x000ab5a8f70bb0fa,0x0005b32501ed29d2,0x00036f439adfe6b6,0x0000a6c7202e9c24,0x0006531bcd403e24,0x00064526a2b69777,0x0001dc2d590cd125,0x000b64170acdcfa6,0x0000000000000000}}, + {{0x000b0bb5e03ac48f,0x0009bb5837030273,0x000a05cded5e6ec1,0x0008034dce79ed12,0x0000fc54532094d5,0x0008fcc6c534a769,0x000bca87d8be0fee,0x00041150d981f9e6,0x000222345254c456,0x000b2aa496b6e112,0x0000000000000001}, {0x000d2c8de5bb7e5b,0x000278f0be2794e5,0x0001b31bbb57b1c7,0x00001958330187ab,0x000f5dd751abf9bc,0x0002de4b57d090a0,0x0009cb74fbe565f2,0x000f83e310b95170,0x000d1301cd0ee2f4,0x00049fd2006501c7,0x0000000000000000}}, + {{0x000e8d883bcef9f8,0x000be3770de7cc8b,0x00007c65e3e95107,0x000ac96f780e3eca,0x000413d615089cf6,0x000585b5b22549b6,0x0008b5facd5da79f,0x000f3c8b5c5a4c0d,0x000d6dfaa970b49f,0x00065cc025c0e7ad,0x0000000000000000}, {0x0003c64dd34154da,0x000343c797b7cd0b,0x0001f367813bc308,0x000fbf3f138ae118,0x0006f1f8c6302e7b,0x000f35ea2ee3cc54,0x0003a0b904ac34ee,0x00052596f106852c,0x0006e533ab1310ec,0x000abf763b19381e,0x0000000000000000}}, + {{0x000d9a73e24c887c,0x000707461d095f01,0x0005d3ad552ce968,0x000f402b6c527f5f,0x000818672d6016b3,0x000279bc4633dd66,0x0000c571c90fed28,0x000cee78b5512020,0x00048d6ae97b4812,0x00055292fa8b91d9,0x0000000000000000}, {0x0004608b8c1577cc,0x00058615049c4716,0x00077fa05c3b187a,0x0000d33110dc1846,0x000554a923122c03,0x00015b3d3cf40b2d,0x0005e05a3843c4de,0x0006438408a6964a,0x0005f646af7c591a,0x000ae89a0f7132ab,0x0000000000000000}}, + {{0x000b5e462dd556b6,0x000f3aab5e9c2f29,0x00040c3ae00c87a1,0x000aade98fdfc7cb,0x000f2f671ec86f72,0x00069dd7b2aa376f,0x000b6f90c4b07483,0x000ae5c39e831a9e,0x000ef6929b8bdb31,0x0007125a4c5224c9,0x0000000000000000}, {0x00080ab908d10b8d,0x000b7c8a32a9943d,0x00051b7d4fd0edbb,0x0008eaa89eb83ad0,0x000fb343de0ebbe0,0x000d3c4d0cc33cc9,0x000b15124b0953fa,0x0007582773fc9c30,0x000ab2c193a021a4,0x000b73ddfb881675,0x0000000000000000}}, +}, +{/* digit=47 [{1,2,3,..,}]*([2^188]*G) */ + {{0x000f014ad29ca649,0x00075a10e7e9c3d6,0x000042dda6a91edf,0x00069276fbe9047f,0x0005a497f91416df,0x000b982ab7fce403,0x000b8b61e6adadfa,0x000d218a9fd9d973,0x0001c8c04e2c23f1,0x000cb12274d47d9e,0x0000000000000000}, {0x0000ec3de397b98a,0x000d9a272cecd709,0x00050e492db6d724,0x00082a50e32d2f19,0x000db6bf40e9c68f,0x000b25727f0678af,0x0007a36e6ae78194,0x000cbb096d1806b7,0x0001afd3feedfa35,0x000e57c17d9b9ff4,0x0000000000000001}}, + {{0x00078e57ab05c549,0x00081a123d2b219f,0x000ecb0183ca3cf9,0x0008ed9f1eddfd07,0x0002f8f90e3c6699,0x000ad41bb20e0515,0x00019c77dab5c5ef,0x0002ca7830069394,0x000ae5cd1de605b3,0x0003933d6039cc98,0x0000000000000001}, {0x0000ae5b05bb2b74,0x00071168c4bf8259,0x00001a66f3efdf4f,0x000e1da4a65b0015,0x000ba0665dbdf241,0x00015f360d4c3387,0x0004e85c88fe301f,0x000c061a8e048acf,0x000bcc0119ca9957,0x0009ea8585dfcf51,0x0000000000000001}}, + {{0x000c2a4869f8ca68,0x0005748af64adfdd,0x00044c661ce61bf4,0x000fa33532bda5e6,0x0004409ebd1c4df9,0x00063b107af0f45d,0x00013ef2dc8804b9,0x000a186c6c3f3d75,0x0005a7ed73f6b67c,0x0000b525bc5b72fc,0x0000000000000001}, {0x00008fa0f93430b8,0x000bf3cdf63616c2,0x000a2ed8b79415ed,0x00008df169f3be1c,0x00006a9b7669442a,0x000be581a2acda6a,0x00093d2dae365779,0x0006ea987608134d,0x00059b31b3052589,0x000d8078ebfe0716,0x0000000000000000}}, + {{0x000a0e4faa59f069,0x000d33d96e52e437,0x00029f2632f3aebd,0x0000c85e4fd15682,0x000de4f3be7892c7,0x0007d9fb180a1634,0x000b175638b44c2c,0x0002e33499b53e6c,0x000cdad290b60dc3,0x0009d1cf1fcbab2e,0x0000000000000001}, {0x0001854cefb1da9f,0x000257b5b7539f5d,0x00096df1240b9d47,0x000f9e9a561ffc72,0x0000d6d9452715e9,0x0005aea9109f0df3,0x0005d521e814b452,0x000c7037d6e74c47,0x00060afbb2239aca,0x000dfe3a178a1e6b,0x0000000000000001}}, + {{0x00085fac7aac5d24,0x000e6efcd816f4de,0x00001aa65b85ec90,0x00042ef288a94272,0x000527aa3e5baff2,0x0002c225dbf973aa,0x00073237d80e262e,0x000ac84d268b446c,0x0000056980d17882,0x000089041c6047c7,0x0000000000000001}, {0x000f5b36106ae92d,0x000b658d82ab92e5,0x00036754a0792779,0x00032fae5cee6721,0x000bd0394c90fe6b,0x0001825f86d43336,0x000fa2e7d57eb880,0x00022294f3c7cd21,0x00070bb4a5b81f76,0x000e5c797152fbf7,0x0000000000000001}}, + {{0x000d4560b8c46ee0,0x000b73ca40a188f7,0x000b593661397fde,0x00026cffd18ba8cc,0x000c47a735170abd,0x0002887e49a94d3e,0x0002a2ec01caeb9b,0x0007426e36269901,0x000522aa9c52b5bf,0x00066af9e1ef518f,0x0000000000000001}, {0x000d742afa309fe0,0x0006f810d9df60b6,0x000084e739c300f5,0x00056da63d1a036a,0x000cd4f33c2df42f,0x0000b456fee1f0f2,0x0008f569e5589fab,0x00062492c9b09b89,0x000079adb7885960,0x000cf412b618c75e,0x0000000000000000}}, + {{0x000e60d6e9faeb2f,0x000298054778495c,0x0000f99d00d5919a,0x00052dad049c1204,0x000e8b4f342e902f,0x000c225bd4b3fa2a,0x0004f48aaba21576,0x0009d33ad4b48b96,0x000a24fa9d5b26df,0x000f2799a4fd763d,0x0000000000000001}, {0x00017650a566263d,0x000e25ee8cfe1893,0x000763623662e408,0x000a4360ad7e6d05,0x0000ba65a8e233ee,0x000338261baaa5ea,0x000af51b8dde194d,0x000003aaa23ac37d,0x000ab55391298a43,0x0008f52d2a4172a8,0x0000000000000000}}, + {{0x000760e887bee904,0x0009f91c8cff613a,0x0003af1d33766225,0x0002f55a798ee44c,0x0002c7171b76304c,0x00051b89de6b4202,0x000754ce995dc454,0x000a5d7e90f40166,0x00037fe2c45f5e9e,0x000d835f81a1be14,0x0000000000000001}, {0x000c04a7dafbcd8e,0x0007d22e0b1aaf34,0x000ad92815662ecd,0x000b88ed3ef4d947,0x0000190778cccdc8,0x000ea32bf7d0a755,0x00094ed615d6df41,0x00066cdce7de3703,0x0005d94b6a5a2d85,0x000869b1500a755b,0x0000000000000001}}, +}, +{/* digit=48 [{1,2,3,..,}]*([2^192]*G) */ + {{0x000556d5fcb0ca3e,0x000bb40eb6f5de7b,0x00092b00751e1fef,0x000d985badf10d77,0x000bda78c0fd8245,0x00097cec621ec6c5,0x0009de36f6534761,0x000929578b20f59e,0x00008129148b6a34,0x000260858df1e4dd,0x0000000000000001}, {0x0002df7b80140bb6,0x000f0872cf54b64a,0x0005ba02c9e702cc,0x0006a4694fa2136f,0x000ae62ca46c9431,0x000a69d6c72a601f,0x000ff0af210ce686,0x000a108647e23ca9,0x00072d54b7301dc8,0x000b4fc0d011e4bc,0x0000000000000001}}, + {{0x000c2c9272139ecb,0x0008248890056b04,0x000319a82e4c5944,0x000bd6a55d37d95b,0x00074d80dfb735a8,0x000b368732a7edec,0x000dbb960fac47dd,0x0009b7d149244f46,0x0005c8153e4ae15b,0x000dd7d6f5637025,0x0000000000000000}, {0x00023077c37f59fa,0x000e01c814ef1183,0x000d2dfe1b52b965,0x000d66c5cad600e8,0x00064cd44f8d02cd,0x000b170f04ad1f49,0x000b95d6b03da74b,0x0009721ac42809f8,0x0003fd08dc3ee705,0x0005bd69cd062aab,0x0000000000000001}}, + {{0x000b883d845a0ae0,0x000afbae353f2a2f,0x000473d0adeb61aa,0x00037ae3890f51bd,0x000480f0c4103d1b,0x000087e22deca493,0x000ae96c669a58f0,0x0000d7ec27b93462,0x0005f63a771fe3af,0x0004035d6f692734,0x0000000000000001}, {0x00047ce82b6063a3,0x000a032d78ca1a20,0x000ffe80d92bf2a2,0x000357128144148d,0x00065f437565141e,0x000044794e70453a,0x000ed9d74d6e72f4,0x0002c9dec888c3b6,0x000d35b1703c9efa,0x0005564a8b5ee101,0x0000000000000001}}, + {{0x000408c0ef420ccb,0x0003751466bdddb5,0x000686318317d090,0x000f5c351d77faab,0x000e6e1c56990fd6,0x00044f54fded7bc7,0x0007a03658746405,0x000acb87ac9e9b1f,0x000e1a951d060b45,0x0002d4d46b22b133,0x0000000000000000}, {0x000b308639e1f9dd,0x00088fb9f340687c,0x000545e0d0da3dfc,0x0007c0127b5897e6,0x000708cdc1322bbf,0x0003ce8bdc5bfb35,0x0009aefe13ad9991,0x0006b6cb7333e158,0x0005d1b9d92265f8,0x00065e9dfffba15f,0x0000000000000001}}, + {{0x000dfc8b990a47ce,0x00010afcf7dc8ef3,0x000e84517ba6c8fc,0x0002906aab79d6ea,0x000563aab2198045,0x00005b6fc1e2c314,0x000e1c75139c8775,0x000f87b03c5339f9,0x00013db5c7dd8d56,0x000be729d4f04194,0x0000000000000001}, {0x0003ca2969a49a45,0x0003d7263734a805,0x000a96220f01659f,0x000a81ea503a05cb,0x0009a4b1e826b6e7,0x000b9124852cc317,0x000a53155592390b,0x000adcbcb9064287,0x000f6cda7ecb3423,0x000745fa7b75f585,0x0000000000000000}}, + {{0x000020f9870c5652,0x0008ed2cf4bf5440,0x00043a293130a211,0x000b5775772ea602,0x00033659b8c321b9,0x000b8b914e8eddd5,0x00016d7acd2ea084,0x000600a84078289a,0x000073293df2fe16,0x000f1b7632be02d1,0x0000000000000000}, {0x000ae60c00fc41df,0x000dee1aec5298cf,0x000dc3a384668cb0,0x00039330262dc7a6,0x0008200480e942b2,0x0007f1ad6908e660,0x0004d8902ca00250,0x0009dfae47555ead,0x000dd7fb7e96dfa4,0x0004d09336664145,0x0000000000000001}}, + {{0x000d1eaa79614564,0x0008f53026152677,0x0004e1ef41c569ec,0x0009c61bebc6f47b,0x0005a764d392b91a,0x00081c91fd03bca4,0x000d12e91e91f33f,0x000ceb9cb7de2868,0x0000e9b7cc6516bd,0x000c8bcc47c28272,0x0000000000000000}, {0x0007539aee683a33,0x000df86171edb94b,0x000cb40fe4798476,0x000b93f35533bd14,0x0009da702f13dc6d,0x000ba7ad4d348188,0x000a392741f6a108,0x000c52b97e5c2cce,0x000568205c383605,0x000d4f58766e7a6c,0x0000000000000000}}, + {{0x000d3d9203521aef,0x0003dde5091b5f60,0x000ec304735ae314,0x000afe69e360b755,0x000f3119298c9f78,0x000c6a7738e3ed2f,0x000298a24d640365,0x00078b486bf006b1,0x000e9050b3448a96,0x000ac46d50f02b81,0x0000000000000001}, {0x000b1ce68a1d8699,0x000b8559ff13a9f1,0x00023011f5efc1bf,0x0004e57b1d2b17a5,0x0008efdcb9ac6bec,0x00009c3a1153d5a5,0x0006b2a4b16461a1,0x0005a5edc709e6c0,0x000d62c80c93e99c,0x000b0218529aa94e,0x0000000000000001}}, +}, +{/* digit=49 [{1,2,3,..,}]*([2^196]*G) */ + {{0x000e7cc655ddb9f3,0x00013549c78f7abc,0x0006489c7f6e90f1,0x000e52627145775f,0x00027c353f1cebe8,0x000a2f29fc36a4b9,0x0000acc3ef5baced,0x000fb8074e6a3d4c,0x0008d3fd643a9c64,0x0004c070fffe4c63,0x0000000000000001}, {0x000fbd2cdf57826f,0x0005bd9bf19e6e5e,0x0007942ab0ce8665,0x0000c790e82b0e8c,0x0001e2f2b552cb1c,0x00090a098c9dab8e,0x0009810a67eba463,0x000c6a4756fc9b4d,0x000e8cb25c97785e,0x000215f5f5b6c18f,0x0000000000000000}}, + {{0x0002bf06c6b067f9,0x000a2b3dcbcaa8f7,0x000559f9fa4cedc2,0x00001ff4707cbdc6,0x0005eb59f1a1d653,0x000b9620b3fc409d,0x00091f76c53a5feb,0x000e766a3eea48b5,0x00013597ec3fc458,0x000a5eb4cf309e19,0x0000000000000000}, {0x000b24162ae5ce89,0x000e57dda1da6f8b,0x00092393366cd895,0x000d0cbc02de8414,0x0007365ce8f0759a,0x000cfa2564893b65,0x000a74873186b40b,0x0004d0156cb04fbe,0x000490f66512a03d,0x00036b328165e70e,0x0000000000000000}}, + {{0x000d63dbde7982b9,0x000c29e4cd39f5d1,0x000aa87372309f98,0x000951ea561fec44,0x0001afd07b42ddc9,0x00045755866c4665,0x000b2e07bf78c6a3,0x000e9284f87ca447,0x00035d4199cdea2e,0x00049a677e175372,0x0000000000000001}, {0x000229ff95010f5f,0x0003cbc8f306c814,0x0001a7861e7a79e9,0x0002d63c05616521,0x000d995f90f64784,0x0000e16cd8cf737e,0x0001408ff0413e3c,0x0009c3a4f30dedcf,0x000a0a6b443a170a,0x0006e0cc49b5c711,0x0000000000000001}}, + {{0x000ac308c74d834c,0x000a8dd825f7406b,0x0000fbb496f34b0d,0x000075e1de870fb5,0x000227841bcf2365,0x000b8e05ffd3c983,0x000e33dc39c86d83,0x0009f0fd6d0e74cb,0x000d62a5a8904ae1,0x0008c32b1e28056e,0x0000000000000000}, {0x000d2a2671b67c79,0x0004494c1cde5597,0x000c0326e9105031,0x000b1ee150606033,0x00061f18317b0423,0x000cc474ed398c9c,0x000df4796a972375,0x000696b52ef07eb4,0x000ed96071372ae4,0x0005ffabf9d1feb1,0x0000000000000000}}, + {{0x00045b8e28f19059,0x000286054435bd90,0x00012ddcca1e377c,0x0009f510d747b1a8,0x000d3775c0ea63eb,0x000865c7834fcce9,0x0007bbad37d19f75,0x0007bbc7cb402eb6,0x000530a0f5327111,0x000908600a1a8bd5,0x0000000000000001}, {0x000abbe5e02132c6,0x000b17b10fe3c6dd,0x00011b655993587d,0x0008aa4f1c163208,0x00092e7539751ad7,0x000229bfb751c187,0x00003ce5719f77dc,0x0009dd5c3eedf84f,0x000b8c257bb9c60b,0x000345e60da1b9c4,0x0000000000000000}}, + {{0x000e7d40935779ea,0x0002b583ea2a70e6,0x000137328e54c9ba,0x000501ecd4654390,0x000e5d733683ab93,0x0009f374dd118e98,0x000b90700d407bd8,0x000c13b0afb65295,0x00048095857db6bf,0x00070895fc47c66b,0x0000000000000000}, {0x00037df304273762,0x00053684543a49aa,0x000af1483095c127,0x000176dbbf08a1c2,0x000fbbab267dccb7,0x000bd6efdfa7bbd2,0x000abfc8aeeb27ea,0x0008c902ad03e86e,0x0009e682a4e44e71,0x000fe0064991f1f0,0x0000000000000000}}, + {{0x000aed77f4d8e151,0x000d64f6fa111299,0x000d4feb2e79c04e,0x0007b4f97a120999,0x000d370550af65d5,0x0001340660d07357,0x000084ce4afb7c64,0x00040826e57205ac,0x000a7fc0bae197ca,0x0008238f07d6803e,0x0000000000000000}, {0x000454a02cb353a2,0x0000deb5cdf6d6af,0x000f3bb89c8b32bd,0x000b355a1bd8c3f6,0x000e63db355ab5de,0x0005c6b3982f043a,0x000910f0e90987dd,0x0001380521adabe8,0x000fa044a4bf6a24,0x000fd8fb752ed23d,0x0000000000000001}}, + {{0x000fdd1be70b4926,0x0009a826f6dba658,0x000cb4e95121bc79,0x000f676af00f6eae,0x000cee75a521d56d,0x000eca7d7729d333,0x0002e5027fb68ac4,0x0004a49aec5f206d,0x0006a988faa272aa,0x00047f341efc691b,0x0000000000000000}, {0x000df0f078415461,0x0006ca3afd9193e6,0x000e7785c7d78268,0x00030f1e3c2a9148,0x000aaa49f1fa54c3,0x000e96229782ded4,0x00093b6b845da08d,0x00020729c99179a9,0x000904b0df8fef02,0x0009cee6016c6aad,0x0000000000000001}}, +}, +{/* digit=50 [{1,2,3,..,}]*([2^200]*G) */ + {{0x0008c22f80cbfbe4,0x000130943a347193,0x000e2773aac837e8,0x000010c64a3c4f46,0x000be2b750229f24,0x00007131ff138446,0x0000ce7731813b90,0x0000e94672d6c2c9,0x000dcb075dd149a0,0x0006d07531381b69,0x0000000000000001}, {0x000b38c7be8e6de0,0x000a9739ced7c6b6,0x000a61fbc4fb63d5,0x000fe4d18f6b6bae,0x000bd6ae1dbab075,0x0002c3dbf8c1ebed,0x000b0516dce109a1,0x000e4a2962c4c087,0x0000db685a1e1733,0x0001ad9f800e79f4,0x0000000000000001}}, + {{0x0003feea78bb9ff0,0x00046e4fde5cbe66,0x0003f440437dd027,0x0002a08933232942,0x000e421f2f6038cb,0x0008d7b95a50b4f0,0x00073ae18c0b0f4a,0x000bc9451cc035a4,0x0005154ba8955b22,0x000d349d1fd0859c,0x0000000000000001}, {0x000f04652c1a8bcf,0x000b73e19db868af,0x000eea574f2961dc,0x00027664f8c3e1f9,0x000839b512b73f43,0x00002a0ec5b683e4,0x000b38a0fb615a0b,0x0001b1e55bb87991,0x0003094173f71955,0x000d3c0ba8f16419,0x0000000000000001}}, + {{0x000ed0fcb63247bd,0x000c61e26950f920,0x0008ac76960a5916,0x00049cfc2ae5b02a,0x0008cda5eb1a5171,0x000118595b5c8f4a,0x000c88e0004518e9,0x00089dcbce699e0c,0x000dca7cdb0b0583,0x0009678f7a0d455e,0x0000000000000001}, {0x0003e3080d452c74,0x00067cd9ebc5ab77,0x00092748ad132f85,0x0000eb812f890896,0x0009083d0c649d6e,0x000d13cd26dc1732,0x000539d6815ffdae,0x0007727168b4775e,0x000ad256509166ff,0x0001747a36c1d3bf,0x0000000000000001}}, + {{0x000e6e936a559258,0x000787f262712646,0x0007ee8f55296d6c,0x000b44326540e78b,0x000ef2fb8850453e,0x000e4739b6073a9c,0x00032c19bbfb39a0,0x0005bec805ba5b65,0x000b74df44331c49,0x0009d3002e8ec8ed,0x0000000000000001}, {0x000d7ba6c48685b3,0x00073d4bae18cecb,0x000a9e818b43a66d,0x000e109d5a439da7,0x00084e2bd60c3422,0x00082785ad715748,0x0009a5bf6bd330b4,0x00066c8383da8c0c,0x0009a00bf0007cc5,0x000256a489783e2a,0x0000000000000001}}, + {{0x0004a8e407a2ccd9,0x00086ad221fba29d,0x000fddda1e9d46ad,0x0008643114fcb5bf,0x0005a60db0e24f96,0x000659be98b0468c,0x0000c785c91bca8a,0x000b1e072204cabd,0x000ebbe04d9453df,0x0007688aef77cf50,0x0000000000000000}, {0x000b62e349b426c5,0x0004467872d194b8,0x000ddbd4e1c43334,0x00024117aad0f260,0x000ea7d8cfb9c423,0x00083e18f4bd6c92,0x0008dd5687682258,0x000359ac483a7289,0x000ec708225923bd,0x00062148de2e57ff,0x0000000000000000}}, + {{0x0004d07f78796d38,0x000a0307a33d42f6,0x0008948a2a44d434,0x000f90db03ccc6f0,0x000696ff7592ebb8,0x0007ff2ae969af49,0x00014fcec7fca3c8,0x0000d6cec6f56874,0x0009ae9c6b325541,0x0003ea961c98239a,0x0000000000000001}, {0x00084bbf91f7e4e9,0x0009ac472d023742,0x000d63ca5a686ea8,0x000614346cd552ac,0x000072fb24ab8e61,0x00080d3677dc07d1,0x000c8c0d1833f7c8,0x000717c50635d225,0x000f8a2192bf84ae,0x00027f2e83c678c1,0x0000000000000001}}, + {{0x0007ea965c0d1be3,0x000dffe0762dd1bf,0x000d60aa7917e003,0x0002fc7262c54da8,0x0004421eaa7edfa9,0x0002c86ea7ff6dc2,0x000473729f82d5e6,0x000d535c6df46821,0x0004bda6bb69bc00,0x000b33f34e260149,0x0000000000000001}, {0x00096ecec3563dba,0x0004fd12da169210,0x0002f945903cc5db,0x00014cb4c4f95586,0x0007af70f6fbb150,0x000a6967e23d80e4,0x0003ebeadb489f20,0x0006a009490665a1,0x000afaa96a28958e,0x000a31da82221f9f,0x0000000000000001}}, + {{0x000b5dfd8f4cc713,0x0009de59f2c453ba,0x0000c9b2cc1e3fa6,0x00033c17b6318b0b,0x000e92d5d399a56b,0x00008f8a6f6dc3c1,0x000b7f39e28633ff,0x000ff1fbcd4351ff,0x000013e8c77388ee,0x00066a953e5ebf9d,0x0000000000000001}, {0x000bfd2f419a3879,0x0001d195e5a481bd,0x0001ef3e1ae017a3,0x0008b706b5b37267,0x0003f748e8ba9898,0x000e9de7d3391698,0x0007cde6e3e3c930,0x0009ee4ca324e7e3,0x000b6a772ae3cdd9,0x0004235fda48d82f,0x0000000000000001}}, +}, +{/* digit=51 [{1,2,3,..,}]*([2^204]*G) */ + {{0x000ce56e11c7765f,0x000fe4cfdef6377d,0x00035b399363df3d,0x000ca630a715e9e9,0x000a21011f820ffa,0x00022d3bc633f64d,0x000dab0c59875522,0x000dc95736a8523a,0x0008fef5b787c715,0x00032a66393c6305,0x0000000000000000}, {0x00034ecf897f6f48,0x000d40891f4ace54,0x00051c5f6bf7708a,0x0007ca62fe89ee25,0x000eae6011a07c37,0x000028c949d24cd2,0x000ab99c094a1a4d,0x00031fed19d9cf84,0x00051c154036f7f0,0x0003d437b50c3205,0x0000000000000001}}, + {{0x00036aa0bf5fef4c,0x000b4bb069d26c89,0x0002e3dd1d0d3718,0x000bf3daeaaab400,0x00076315a34c426e,0x000eb5f38604c676,0x000805197e2eb1b1,0x00037226db1abc31,0x0009ad73df5e17eb,0x000d3797d098f510,0x0000000000000000}, {0x00082cf0882acea0,0x00006b48806f5a59,0x000abd275055f094,0x00049a504db94328,0x000ec38e43c40b3c,0x00082b99e608d386,0x000cf443b07fe475,0x000b7186cac29089,0x000d982cfac474a1,0x0009aa7b0368d422,0x0000000000000000}}, + {{0x0006f1287e600c1a,0x000cffcc5624ecb0,0x0002d1ca07fb78a4,0x000a1f9666cc7bc9,0x0008539fb634b6eb,0x000c73e361397798,0x00014a496c8d68c2,0x000d7ca4181be620,0x00069a299a451732,0x0001c06004061fe8,0x0000000000000000}, {0x00029e4b308242d0,0x000a13eeecee128a,0x000f659548ea451c,0x000490cf14707b99,0x000362f80a26ba79,0x000292eee64971fe,0x000871b89c8fc38f,0x000d6dc0d122e55c,0x000979f11919fbb1,0x000f85c98fe350a4,0x0000000000000000}}, + {{0x0006cb60e51b31a9,0x0009c2f6d82cb3ba,0x000f86e04fd98949,0x00087bb6cb66fb0c,0x000cb7e6257cf354,0x000caa5a38dbe642,0x0007ff70132dd977,0x000a9fe7cec8cf0c,0x000f2a9f98b24a15,0x000c7552eb7ce954,0x0000000000000000}, {0x000aec9e842f8ae5,0x00096d766fc55447,0x00099065768ced0e,0x000adad9493166bd,0x000c328be045e2b9,0x000e70d305222a08,0x000ec1d4f554727a,0x0002fed1873d61d8,0x0001c46d541e23d8,0x00042ef348b3f19f,0x0000000000000001}}, + {{0x000ccf976377d19f,0x000f1cf68ff2fc1a,0x000d98b274ba0faf,0x000788c074f0bd37,0x000a798f5cd04250,0x0003cafaaeab508b,0x0009fd1e881c2856,0x000dd63706ee8361,0x0001b79794f0ad14,0x0006f33d5c0505bc,0x0000000000000000}, {0x000090b50612a9e3,0x0003e3a662f706ea,0x000cdebf25eed8bb,0x000d3a7d888eb094,0x000fdc87a6c4d17f,0x000574531e25001b,0x0007e6d823c00762,0x00014c6a486f9d98,0x0006d2d6573a4d0f,0x00074c191e9a8851,0x0000000000000000}}, + {{0x000d58220482e6f9,0x000c77488e8bdb82,0x000ba1084c7aabd7,0x000ae76567c7272c,0x00079ab82a151ca6,0x000826c75c1ca84a,0x000434806316ad0a,0x00040dd7f329f3c6,0x00033bd2dde3d6a0,0x000c43689c3e453f,0x0000000000000001}, {0x00061be6ee98af37,0x000291b8361cc48c,0x000b8a7b622624c3,0x0000547d4c3e4e24,0x000c937a21d5f3c1,0x00007a153ffa09bf,0x000a63d54fa325a4,0x00048d13bea75c7f,0x000e1e55bfb7c45a,0x00055a1a8b85312f,0x0000000000000000}}, + {{0x000094bb55dffec6,0x000b1ee483a0b1a7,0x000e63531718eed4,0x0009354c0be15b59,0x00029a3b937fed84,0x000295e4506353d0,0x000205f7b6d68fbd,0x000e59b3375fdbda,0x000b4aaddd0cb573,0x000348c879da0f51,0x0000000000000000}, {0x000afd066ea2106e,0x000ee293d8c45af2,0x000bc67374a1f66a,0x00016d7c0fd1fd2b,0x0002493231dcd541,0x00019502a277efda,0x0003c7872e2fab64,0x000a95c3d06567be,0x000fa48d7ff41d2a,0x0001cc69c52d2e6d,0x0000000000000000}}, + {{0x00046d25ca0b12ed,0x0003e7af11f36102,0x000d246f5c00ca56,0x0005f2713dbda22c,0x000571517fe92c1f,0x000e558aff5b82f3,0x000852ec7e4811aa,0x000a0a7d7a0cfe93,0x0009a571e80c69ef,0x000d5ecf0c8dc85a,0x0000000000000000}, {0x000629e0362ea61b,0x00019570463933fa,0x0004d8bdb2997e91,0x0008d16c1670ff63,0x00042ac0e352c375,0x000bf5c218c31489,0x0009269789d4077e,0x000eedd9111468df,0x0009e59bdc949bb1,0x000694a97ced001c,0x0000000000000000}}, +}, +{/* digit=52 [{1,2,3,..,}]*([2^208]*G) */ + {{0x0000e658f63653aa,0x000362a4e263b15e,0x000f1a72f5cb787e,0x0008dd85ade21c8a,0x0009351d6c477346,0x000ea4254fd69f8f,0x000c982ae15e0af4,0x0005dd836935db86,0x00023278398d3a2d,0x00082c5ffb0769dc,0x0000000000000000}, {0x0002ae6ecd27779d,0x000456043db3d94c,0x00073642e7c09230,0x000692df6f9dd795,0x000422cd985762a8,0x0006ac0a49a83e72,0x00059cfa2e9e20f1,0x0000d0093708d3fe,0x000c84d0b10a4692,0x00035fa5bda12a10,0x0000000000000000}}, + {{0x0009924edfb9aeab,0x00028a46d2968a10,0x000fe84ed7a9147a,0x000478aa49744c91,0x00030fd88965188e,0x000dc8d99e65a34f,0x00006f221fd955c8,0x00027ea7cd997402,0x000f83ab9dedce89,0x0006e8a7c26d23d4,0x0000000000000000}, {0x000728e182c8cb8b,0x00078b0fa5f32091,0x000760a4e2a3ad9d,0x0002b50f65aca369,0x0003d46ee027e681,0x0005a7e2b8db993f,0x00003752acac076e,0x0003a179054a6029,0x0007bff0fddbfa0d,0x0008feee0dfeeff8,0x0000000000000001}}, + {{0x000e1e66266af2df,0x0002e36c081c96d8,0x0002c3c896d714ef,0x0002acfe977ac59e,0x0001a95d1b3f90be,0x00003c79555da335,0x000ac68d1f4138b3,0x000d2dc5e8301aff,0x0007f5144ad06837,0x0000d0ff81349a59,0x0000000000000001}, {0x0003ebad0af48caf,0x0005e5d9aadd9976,0x00026bfaeb96c7e8,0x000c9ceb03564b50,0x000254586ab1371e,0x00038a2ddf7b0228,0x000ca35a77209961,0x0003fd9f60e7f5a6,0x000f0eb7073273c4,0x000a1bce76f5e62d,0x0000000000000001}}, + {{0x000a60a63bd16196,0x00077f090aae19bd,0x000e7638c32cb3f5,0x0002a6ddf59abf93,0x0001d3548613634b,0x0001b5e6513c50db,0x000b5bd49476ec89,0x000a83b636d2f4bb,0x000071e3a3dd95f7,0x000ef977c02f69d5,0x0000000000000000}, {0x0008603799531d83,0x000ec49c9ad3cfc6,0x0004e50cb9635f1e,0x0003ca9d26b39588,0x0006f3bd6a0e5d70,0x0008ef03a93fe903,0x000aad2605b0ecc0,0x000b6abd3a9b070f,0x000a81977f3494ea,0x000831164f95f67f,0x0000000000000001}}, + {{0x000d576c129bba19,0x000dc781b1958f67,0x0004c725830444b8,0x000d772989a02957,0x0003160191e1f14a,0x000b3aba62ef31af,0x000a9c026782cae3,0x0005e2df9de1d797,0x0007d5d393897669,0x000e09de2e3f7f60,0x0000000000000001}, {0x0002f590d9230f6d,0x0008e59ce71ff8f2,0x00065bfab0b97ecb,0x0005b773840ae894,0x0005df550efa55da,0x000a03525e361e4f,0x00032a275d9fd4c6,0x000f30d16226c4bb,0x000512eb88ebc1cc,0x000a048dd37790a6,0x0000000000000000}}, + {{0x0005c82e7c82fe0b,0x000b6b153f48688a,0x00079cad28ce32c1,0x0004dd65d7330f19,0x0005fd6ce0841643,0x0004ad25ddac7886,0x0007705833e0df48,0x0008294753bb4502,0x000ad8dbbbf63937,0x00019b436c10a463,0x0000000000000001}, {0x0005b7516a304d40,0x0008185865f25816,0x000cfc1c163a4965,0x000ed7eed35d77f6,0x0002d2246fce8e80,0x00064fa59660ff02,0x000081304ce77dc8,0x000c6fc813dd85ee,0x000db13057fabb84,0x0008d66a509ef64a,0x0000000000000000}}, + {{0x000ae85bb3c1e90e,0x0001923787b4a031,0x0009e575e9892a6e,0x00074c2ebb769eea,0x00063064d9df4bf8,0x000e1bf584f54d2f,0x0007ecc49f863e83,0x0003213fe023848a,0x000c07e3d527042f,0x000c51626ab6da53,0x0000000000000000}, {0x000783a377f5ac26,0x00010cfafa402a74,0x000f762b70abfb39,0x000eac42e208b3a1,0x000497274db0b567,0x000b54ede1f18ddf,0x0001de4808fda6ea,0x0002ceac81237a87,0x0007edd6e7428e9d,0x0000cb9fb5801abb,0x0000000000000001}}, + {{0x000205d81676b493,0x0001cfe8f546e257,0x00087afe8b644287,0x000676bad5e346c5,0x000f4a964afa3748,0x0001422f71ca39ba,0x000328b0e9e0a58e,0x0001d31cca18d62c,0x000787f6507714d7,0x0009ad810168e375,0x0000000000000001}, {0x00030f78aa1440c8,0x000f7e509d6354b7,0x000beae80e0ec14f,0x000f7cc09793053f,0x00025b6b1fd1b019,0x0004558d48e4fca0,0x0002aae7ed4a0374,0x00070e2db1c48699,0x0007f4b02f033375,0x000af43011764955,0x0000000000000001}}, +}, +{/* digit=53 [{1,2,3,..,}]*([2^212]*G) */ + {{0x00015e37a2d438c7,0x0006bb436c808cd7,0x000782325918615d,0x000d68ce58c6e6b2,0x00075a40e8f75ca6,0x00001da381c4c378,0x00055d9be962879c,0x00075dd3d4cf58a1,0x00099fd85847d5de,0x000e158f7f76b4ee,0x0000000000000000}, {0x000c9f66a4cec18d,0x0006e45302a76bd4,0x0001b679cdf64708,0x0002c24293b84a7e,0x000a092243bc4d41,0x0005c3c375519ccb,0x000d06b585371f2d,0x000590f4c0f28ba3,0x00073b4091daa768,0x00073c6342e78bf5,0x0000000000000001}}, + {{0x000dcb7fa9fca3c3,0x00047144679a2a9d,0x0003be369b38069c,0x000a82620de84dbc,0x00098d5e1f28d82c,0x000205de8989e877,0x000abac84051f10a,0x000ac26a5b9c5c22,0x00074ecbb99bba5f,0x000253359fa6c2dd,0x0000000000000001}, {0x0002ac09a82c210a,0x000b422ac08c572e,0x000c5c720e071535,0x00095966a7bd1c3d,0x0003a0a4b0c9e18f,0x000faa6c6449a62e,0x000bdd44f85595c2,0x00047bb9f75f529c,0x000f46a6493955cf,0x000622defa5af650,0x0000000000000001}}, + {{0x0006df335e8acd01,0x0009b6996f91a727,0x0008be8a5f6bba5b,0x0006ef24a13311be,0x000b7fe2a95d51f2,0x00084a38b4ee11ba,0x000caf93233a4f76,0x00073771e4762ff2,0x00024adb050176c1,0x000a9e7e6a96ea5e,0x0000000000000000}, {0x000540fbecee1541,0x0003f39f444fded1,0x0006ce01534c5cef,0x000a886125f5b460,0x000b437e2199b1d8,0x000a994fb5a77157,0x000fcae599e6b65e,0x0002599cf24da91d,0x0009f0d7248964c9,0x0007ac171d21915d,0x0000000000000000}}, + {{0x000ca4b8955dde0b,0x000f850c9b5cc251,0x000b99572d6cb500,0x000f8952b82356c8,0x00088575ebe209ee,0x00089253a4607df2,0x000ff9ba421a6b33,0x000799f0eb4dd513,0x0003ed789c84b56b,0x000293e6a5c4d425,0x0000000000000001}, {0x000ff217c0f18530,0x0008986930ae0198,0x00012fd1e778abc5,0x000f509594fad4d8,0x000656733dccef2f,0x0006afad83f10fab,0x00078f717d75c593,0x00018a1a313cd995,0x000cd73871602741,0x000f5446078ec40b,0x0000000000000001}}, + {{0x00034871165b0407,0x00041aa1bdd6d509,0x000fcc9e894c7b1e,0x000369e1389494fd,0x00087f5116c5472d,0x0000a1b0d04b3663,0x0000b4c49058303b,0x0002bdbdc1d8cd26,0x000ae8f01c121d9d,0x000dc1d8c7270b76,0x0000000000000001}, {0x000d922f0e06b7cb,0x000f07bd16843c5d,0x000c01dd32245ab8,0x000fa9f6081477df,0x000c2db624f56ea9,0x000b2fb3e2bccdb5,0x000cb3b768793cb3,0x000c8d894f04384c,0x00010a3af20b15d0,0x00045ab5af8411db,0x0000000000000000}}, + {{0x0006b9ed8590e4a5,0x0008a58a2974d283,0x0001c7668bc64c35,0x000acc81cd837cfc,0x000fc7b9eb02f729,0x000fee9d6ad1171e,0x000a8d7ca7eeb433,0x000a79ea2e79ed5e,0x0001fb8522e38381,0x000cc8162a76e7a5,0x0000000000000001}, {0x000c67543c98a4ea,0x0001f713941c4de6,0x00081dc75d38a3eb,0x000374ce9c459cdd,0x000bdd7ff2d1d555,0x0000d7b03a560a54,0x000ad6193d7f976c,0x000099ff27e977d0,0x000749edcba5d394,0x0002c6804ed826ed,0x0000000000000000}}, + {{0x0003e3bd3291cd15,0x0006a26271a72635,0x0001ef4581082f50,0x000cb6109637a812,0x00043e376f158b63,0x000e1fb8b4f92150,0x000fd4238523b166,0x000edb09ffe09019,0x000a7d8e27b82fb2,0x0001989a4df94f9f,0x0000000000000000}, {0x000410feb007ca74,0x000ed314198cb45e,0x000e234a35b4b72c,0x000c1779579fdfb5,0x000da54f63558ebf,0x000b68211f279305,0x000b7f7a88ea265f,0x0000914728cae4ca,0x0002ed65205137c3,0x00045ed6df45a086,0x0000000000000000}}, + {{0x0001cfb71cb23bf8,0x00067b25479ac001,0x0002f48bcdb785ff,0x000da267c454fd25,0x000154e460f65f62,0x0006fa21e0ac759a,0x000770bdb56d239e,0x000db91d7ccefa07,0x000f07f46fe275a8,0x000527a152927368,0x0000000000000001}, {0x000969a0d74d64a1,0x00059c36f066b2d7,0x0003a664061d81a7,0x0008c41d929c3e1c,0x000a4033ad63b5ba,0x000387b665fdb5a8,0x0002e2c2b433c84f,0x000e4f2d4d931e74,0x000631141b030d2d,0x00086de3845c248d,0x0000000000000000}}, +}, +{/* digit=54 [{1,2,3,..,}]*([2^216]*G) */ + {{0x0000c039d020c1dd,0x000d44ab7b690765,0x00026b42700b4f64,0x0002c1e20576d051,0x0009e70d2ad712c7,0x00015f46314322ae,0x000dfb189904b573,0x000124905a45ef02,0x00026cce68a7b470,0x0004ac5f0db2cade,0x0000000000000000}, {0x00042cd205524778,0x0000d86fcfeb993a,0x0001cc7f2d2ee992,0x000c209546bdb299,0x000531516a6eab71,0x0005f1492f99e62c,0x0002cf5197ae7709,0x0002013e12e8e95c,0x000b78cb72aad7be,0x0000320e70b96760,0x0000000000000000}}, + {{0x00011fae297851e8,0x0004f69afd113575,0x000ab322fa242843,0x000f361ecbe5e3de,0x000b7c1b08880d89,0x000a50aa80c1fbd2,0x000104d9e40537e6,0x000ed4f51df57fdf,0x0008a6cfbe707164,0x000f36d887e3d0b7,0x0000000000000000}, {0x000365e7f9a5983b,0x0003c6129d87d996,0x0002952186a64aad,0x00009284f8224d3c,0x0007bc689c1d4452,0x0003f44aec2c194d,0x00057e00e7c6b2d0,0x000de28c9eb3f18a,0x0008b7de6fac4981,0x000009552159064b,0x0000000000000001}}, + {{0x000147285c5f1e84,0x00054bbe273f4c79,0x000ec66bd4d71c06,0x000771b4dd0505e9,0x0002d4c891619ed4,0x00021a0542316ff1,0x000ffae0c65ede48,0x000db678c0c5a23c,0x000bbf48abf05e02,0x00032691ff4f9e32,0x0000000000000000}, {0x0004ec586f495f39,0x0007665c351b2d94,0x0003939c0c800e74,0x0000a9b2fe310474,0x000c05e63ba55b78,0x00011119c911cfce,0x0000043322972c9c,0x000235f5ba3b0c8e,0x0002b78daa0946bc,0x000a82622257dc22,0x0000000000000001}}, + {{0x00053147b3b22c3b,0x00004897a83e73cf,0x000d11d0f510fba4,0x000de4abfcf9128e,0x00047095c92d56df,0x000f3cd334bcfa2a,0x0000038a5b6f4d4f,0x00095df73169a249,0x000aba80e663bcbc,0x000c64a47769e841,0x0000000000000001}, {0x00004365a62c4cf6,0x000531a582938f21,0x00043321e6dc439a,0x00061253f7387146,0x0008352424fe3ee8,0x000a676302135902,0x000702fe71ab2ae0,0x0005f460396ca837,0x000882e04f7bce51,0x000f93d936239901,0x0000000000000001}}, + {{0x000dc17de84a8cec,0x0000802c374c6c6c,0x000bd6a5b20e3454,0x00046c40337b0f58,0x0003431d7aff9402,0x0001dba6a849292d,0x000f90b37486a260,0x000c12d61cbe41a0,0x00033f828782067d,0x000486ebc39fcd30,0x0000000000000001}, {0x0006818da93cb68a,0x00039ef42673be02,0x00040e906d3f2e27,0x0000e1f1d8ecf6f0,0x000655c024d3837b,0x000417cf596708c0,0x0000946c57882083,0x00058942a1031702,0x0009752bc7086a40,0x000474bd8d65b027,0x0000000000000001}}, + {{0x00057bccc2137aff,0x0003cdce9d3ef437,0x000021aa7d7b10a8,0x00014071804bf03e,0x0005009822fa479a,0x000c4d2fe91adecf,0x000bad18fc3b061e,0x0002ffe82ea4479f,0x000b0bed7b70c576,0x000d5c8a667da425,0x0000000000000001}, {0x00036c22b574750b,0x0001a79beeade4d8,0x000d7c41634d28e0,0x00030d7e124715f6,0x000b28e33c4f983d,0x000442a0682ee2bd,0x0000a48a18cfc1f5,0x0009a6cb16376839,0x000ecc58844abd78,0x000383bd6682cba8,0x0000000000000001}}, + {{0x000c36944a224339,0x0002221a86a3568f,0x000a933230388a55,0x0002ca0cfc1f186c,0x000051f24d4d5f8c,0x00053ac024a82a69,0x000e4e0b6761f2a7,0x0006b4a03fa98a0f,0x000862d5fd1d2058,0x0006922bcb9949cb,0x0000000000000001}, {0x00085574f50da47c,0x000f8cb1192295a2,0x0002436f1d423eb5,0x000f6ae23f4febd2,0x000640f1f266f842,0x000e94d3498091b2,0x00016f1f4561f25e,0x000c6e303b526f4a,0x000bbc14e80ed7ff,0x0009ac6f957c1908,0x0000000000000001}}, + {{0x00089a398d206da8,0x000e6a92326c61c3,0x0000b658149c80b1,0x000f4f6423067f4a,0x00022c96735aed5c,0x0003cb53c31cf4dd,0x000c7214b478ba14,0x000d3b1bbb1eb353,0x0005aa79b46f2e84,0x0007d44a4fa3d67b,0x0000000000000000}, {0x000d31f07cf711e2,0x00031e5402e45d5a,0x0005565057819f0b,0x00050ebe214cdf81,0x000e63efd8e063fd,0x000c82d63ad808de,0x000d0ee39ccec300,0x00085249be7d39df,0x000e9271ab6c788e,0x000a727ffa3cadeb,0x0000000000000001}}, +}, +{/* digit=55 [{1,2,3,..,}]*([2^220]*G) */ + {{0x00061361be3ee97b,0x0006e1f3125658fd,0x00096b636a1d69b6,0x000b9e470c7ac9e9,0x0005bf9bb3617e69,0x0002050a8c1b1e89,0x0002213fa5a11a51,0x000bc2919affa249,0x000be1b1008d55c3,0x0003926dcf2c08c4,0x0000000000000001}, {0x000fb57fda93efc6,0x0008276ce4aac2b4,0x0009277cab16292f,0x000e677dc90518a9,0x000ab0432d015144,0x0005d9214eea4408,0x000b8a649b20eb23,0x000b48a45d8a2560,0x000cf7d1d37dd269,0x00049d71a47616ce,0x0000000000000001}}, + {{0x00034d86d189072b,0x0000b9475ac257a7,0x0003a9d12f132433,0x000adf08cecaa5dc,0x000dc33641cc3048,0x00040352a6bfcc4f,0x000dac876f01bade,0x00035bd7dfb06e93,0x0001d4494c0e1ca5,0x000219b51965b8b2,0x0000000000000001}, {0x000f90e9be7f6998,0x00040776cb857a46,0x00031907caf1b517,0x0007040038843e17,0x00014b3c14ab5377,0x0008c99d12b47cfe,0x0001590d18daa185,0x000f84db2817d455,0x0008544bbc4d8f7e,0x000ee1752b595c5a,0x0000000000000001}}, + {{0x000718c9c3382876,0x000798d016412ea8,0x000c7059eeb3d459,0x000e910707afd251,0x000366ae603f57f6,0x000f1d424b7c29b3,0x000f4591f08b6d11,0x0004fa0b188406f8,0x000a09ce46dfa46f,0x000f3e1ee6193a22,0x0000000000000001}, {0x000ef37aacfd9628,0x00044abc282a7b59,0x00016eca5fb04908,0x0002a4a0fa414af6,0x00010748c915edd4,0x0003d4af5a6f1ab8,0x000aff331ef86bba,0x0006d8ffc35ce768,0x000278d36b6c4e53,0x0006238f61ddd56e,0x0000000000000000}}, + {{0x0008204ec1fe994f,0x000a401febacf810,0x000a1fbe66e0a0c3,0x000654b72570b727,0x0007b5299d8ae343,0x00058b323a83e064,0x00034d13d86ee0d1,0x000be946224b7585,0x000a38321cb77d0e,0x000ea9b845ec39e9,0x0000000000000000}, {0x00021327ccd07b3e,0x000b9c13edfc5044,0x000efee69b80c4b9,0x000b9736ce07a452,0x000de2779de28110,0x0009cb506b810433,0x00009831468d2371,0x000fb54615eed293,0x000a72f30895d360,0x0000822a939f9fa6,0x0000000000000000}}, + {{0x0003613a0bad2c78,0x000a2841479bab61,0x000ae853dfe64b3b,0x000c5d69d7d5f8f3,0x000913c023c98edd,0x000e51c064c2af1c,0x000caf23e811beb5,0x000a297f73a13e28,0x0002c2db1b2c63f7,0x000869272783c6e9,0x0000000000000000}, {0x0009e33e7c2b0e8b,0x000a6e2930859a4d,0x00021c82319f96d2,0x00062855234b3a37,0x000cfe1e952c7999,0x0009fff526834c3f,0x00082932d66290aa,0x000ed0618b6fc1aa,0x000f51b1765d795b,0x0000fa7ad3a784d8,0x0000000000000001}}, + {{0x000b99ec5345605e,0x000d705b03ab3b6f,0x000d514df02df673,0x000d979497926d51,0x000327f3cad9968b,0x00007b8edfa7bbd7,0x000fc5c1dee65278,0x00036db8f1709072,0x000d430f38a088d0,0x000f9df3373c9bfa,0x0000000000000001}, {0x0002932b26523f7a,0x000a4698ce826d56,0x000d64992b915d43,0x000f137e0e1471fe,0x0006811a1c25612c,0x0007e5e74619907c,0x0000f455dcff6a59,0x0006fe503afcb4d1,0x000af47382daf8e9,0x00085e51a1e9e2bf,0x0000000000000001}}, + {{0x000c899ed52c7ebf,0x000805309ddc9f57,0x000f9ec0561000b8,0x0005599061be65ad,0x000c7c6ac2e8bdb7,0x000546a9f7f8f392,0x000b38f709f90fbc,0x0005b81ee256aa4e,0x0000cd9ffe3bb73d,0x000ad1e54f791392,0x0000000000000000}, {0x000e432eaecfeb4f,0x000efd7d99d4376f,0x000ecbf257042314,0x0006524d0d11bf19,0x00070c070e8811a2,0x0009bb46ac80db71,0x0005deced6976256,0x0001f5d4f1996e7f,0x000c6d1bc35c855b,0x000b7fcfaf131b63,0x0000000000000001}}, + {{0x0007faf89dff5e6d,0x000701e289504c4c,0x000c21c143d7c67c,0x000b8b1051104808,0x0001a8547ea3f429,0x00042d1597643f8b,0x000c20d8e30463a4,0x00019700b9ca1322,0x000c7c74112313e3,0x00021d429e582d53,0x0000000000000001}, {0x000df174dc25e320,0x000421f30a9c65a6,0x000cca7bd70734a8,0x000970e912f441c1,0x000b0da35c85642e,0x000fbc6108990f29,0x00004f9201a5ca87,0x0000b4ba5b8a0067,0x00032f15dd79c420,0x0001dcaa2c572053,0x0000000000000001}}, +}, +{/* digit=56 [{1,2,3,..,}]*([2^224]*G) */ + {{0x0009f88e8ef42daf,0x000fa3828b99d9e1,0x00051fa512ec2bee,0x0004d684d33e3c3c,0x000ae34a6c37abe1,0x0009d4bea55b5936,0x000e6492802583c8,0x000098da605bd938,0x000288cfc1f04542,0x000ed0659c47e455,0x0000000000000001}, {0x000ddaea5046a68e,0x0003e422472a49b9,0x000c2da95690aefe,0x000dcef36e21cee3,0x000eab14f0abf0c7,0x00064941e198c3c9,0x000fcf64819eee0b,0x000dbfe77fa8433c,0x000c3b28a2f7686d,0x0009c3dbfd233403,0x0000000000000001}}, + {{0x000b7107c522fbbd,0x000c42e8887082c3,0x000cd304c29d218c,0x0004d8477a96d44b,0x000ecee7f483ff1c,0x000951d19c530d4b,0x000d68d4d6bf1fdc,0x000fe03d009b71d2,0x0005537694d3bd1d,0x0003c3db4cb1a2c4,0x0000000000000000}, {0x00086f0e3fa15f33,0x000388caf5fb4c5e,0x000b2f14ba7715c3,0x0002610381191db4,0x000e0f68a08e3384,0x000342059cb75d25,0x0002bd292f767fcd,0x000a7a696b414dec,0x000dfb67016057d6,0x00035999c277b18a,0x0000000000000000}}, + {{0x0008ba73e1f475e0,0x000dd3f1b783f77c,0x0007375b491b116c,0x0007d166e4a377a6,0x00011bc5434f7131,0x000a2dbe9d40b215,0x0001220856a6b5e6,0x0007b890e757f7e0,0x000f02578a944660,0x0004883ff77008f5,0x0000000000000001}, {0x000a3e2632a212b7,0x000302b8f038a3d8,0x000a306506181a49,0x000301702b3192c1,0x0002c30f8e6d2d73,0x0002a0c5b0c340d2,0x000f8bfe6e8c90fd,0x000e8d703d0478e5,0x0005135b5979aaf2,0x00034da81fa7add8,0x0000000000000001}}, + {{0x000f16b10733860a,0x00007e088e20bfd6,0x000859fdd39b30d0,0x00096072d4c40b6e,0x0007d0a59d2a4c91,0x000f5b531a3c4f60,0x00005885c546c30a,0x000ddc1d5df2fdc4,0x00026f4df2971b1a,0x000bb67cb15104fb,0x0000000000000001}, {0x000f74646d17eec9,0x000e3de3bee8f39f,0x000560fc63e96143,0x000d7aab2e0395d9,0x0003f099cc808fd9,0x000e3c3dca422f15,0x0002c61efabb0d74,0x0008d736943aed2c,0x000d74e4178f87c1,0x0003d1b76afadf96,0x0000000000000000}}, + {{0x0009583eea912fe1,0x0006a5587f3b9010,0x0002a020829ea8e9,0x000b82ec346b73a8,0x0001f44eda406972,0x00067b4504fbb553,0x000e7a6189bcd268,0x00039bdb40c39e05,0x0005c436a03e5e06,0x0007019eedb498d3,0x0000000000000000}, {0x000662e3f77764f2,0x000cda79a7c8507e,0x00040c75e0594299,0x000bed938a93a1fb,0x000829d1bab3f2df,0x000df99ce48d52d8,0x00032fb8c4092f5f,0x000036b5fa768aef,0x000201a9ee7997be,0x000ca0344038e8d5,0x0000000000000000}}, + {{0x0004ae17c6c4ef83,0x000409ab5b4b2b20,0x000c4c863d0780e0,0x0003a003f73d00d9,0x000f7d17b97edd24,0x000335ec2eca6e6e,0x0007def3f246d97d,0x000f0e2518ced6c0,0x000f728fdb8b0595,0x0006dcc1ccb10bfd,0x0000000000000001}, {0x0009f012dd02f504,0x0009d50a767d8e86,0x0001bbb0510be6fa,0x000cdab7deeebbfe,0x000f08332cdf98f4,0x000468782175d651,0x000610add0fc83f5,0x0004965277afa428,0x000ff5c3438635dc,0x0001fc0961df5b9d,0x0000000000000001}}, + {{0x00069bd3ef1fabd9,0x00064fe7b00b747c,0x000195c6097cd6a8,0x000470709e13f896,0x0002cf79709fe958,0x000b72450de744f3,0x000df3f80fb1524e,0x000527ea0bf24b8d,0x0001b2774e7c3f06,0x00031ad38e7aad24,0x0000000000000001}, {0x000b784c1f4489c7,0x000f2a889f589505,0x000a5a3175ee6df1,0x00047a68c157fe56,0x000497f7b784bd67,0x0005ed8ff0792025,0x0001528aca7e0427,0x000d473d7c41594f,0x000cb017e35b5669,0x000f1ce78bb2a52b,0x0000000000000000}}, + {{0x000290556eb6cb2d,0x0005feea12a072e4,0x000d082bac976238,0x0007c4331be16424,0x00021f06c7a59869,0x000de72b68a812dd,0x000652502f900697,0x000d9acaec02a2e5,0x0009120c4a89c7ef,0x000a1bdf713a324f,0x0000000000000001}, {0x00067220e1027a34,0x000cabc964145333,0x00029a9fac99b048,0x0001c2850e9e757a,0x00057de9cc170cb2,0x000d017c03bef969,0x0008cbf0f3534a37,0x00085a627fd6a9c1,0x000c29da8ed78ac5,0x000ae4ef092acab9,0x0000000000000001}}, +}, +{/* digit=57 [{1,2,3,..,}]*([2^228]*G) */ + {{0x00060edf11bb374f,0x00007883a0baf3f0,0x000eb8cb2a326de7,0x00095554f5a8d631,0x000236ba14fb5cfa,0x00053769e29d950c,0x00043eac3b6e6d4c,0x000400e396b6857d,0x000b3b40a28cc2c6,0x000f0142ca52de79,0x0000000000000000}, {0x000536d43744d95a,0x00080dbb696fec4e,0x00086879c7360fe9,0x0006d4736a564e15,0x0001262e7ce9d679,0x0004cced89ee75c8,0x0005fe2dd4f732cd,0x00004a4d97d2a3a7,0x000e046cc62def6c,0x000c590bfe781afc,0x0000000000000001}}, + {{0x0001e39da3d53729,0x000c68258dcf68b5,0x000b1289a021c50c,0x00028ef654112229,0x000f4c73b83c7489,0x000a0ebdbdf0df33,0x00033245f1663936,0x0006bdfac3bf0988,0x0001bcc9c21bceec,0x000bcb64a15de987,0x0000000000000001}, {0x000fb2f27cba002c,0x0002f0ce8d66f97e,0x000c4f49e106a48e,0x000720d60d05177f,0x0001b9e35427304e,0x00008c355b746f84,0x00061577b7b7cd5e,0x0008586eb9a88122,0x00003b21c38ce383,0x000aec02872c5a8c,0x0000000000000000}}, + {{0x0003ee736c032ac5,0x000efdfdb4c3d4de,0x0006ff01d94dbf41,0x000a0bb5ee1889b9,0x0009e7a8dc456a87,0x000c2bb8ca379bb9,0x0000100b2eae0668,0x000d2063b0184325,0x0006daafabf5c71a,0x000da2051e835c68,0x0000000000000001}, {0x000eaacab83acf78,0x000761a09a5ec30c,0x000838055c361c20,0x0002e34e4fa05860,0x0001b9a7a3c102c4,0x000f91746c97086b,0x000c731ba10529e6,0x000e8a7f6450292d,0x00076f3144af4061,0x00077cacdce041a7,0x0000000000000001}}, + {{0x0004b67237f032bd,0x0003fda08c68528a,0x000c719571479a5b,0x00011c75d8054fed,0x000bf503c35807c6,0x00037b9ea9e88e5d,0x000c9422b4c4521b,0x0002950eb17e75f1,0x0008eca427950847,0x000c0f845c91f923,0x0000000000000001}, {0x000c1e80ea8c1010,0x0002e1978ae396a0,0x0002c0d00f914b24,0x0004e43fb47bf7bf,0x00034b416e50ae94,0x0007c8d114906c36,0x0000ad0347f03a3e,0x0006a6eba25165b0,0x00021e9dc53a14e2,0x00076911eb83f4f5,0x0000000000000000}}, + {{0x000bb95adc5ef776,0x0008da0ab8c5f233,0x000a4ab915fb3034,0x000423a63a5dffb8,0x00063715aa2304a4,0x000018304840df01,0x00037b80028296bc,0x000854f7402fb23a,0x0006ebdeaf3e5fac,0x00005463cd3d8406,0x0000000000000000}, {0x000c9468fa481453,0x0003a0abd61a0348,0x00047c025f468b21,0x00090d7078cd984d,0x0005284e72a10788,0x000156fa2b542f64,0x0003b3c956017512,0x000991f2c57b982f,0x000989b3c05c1c45,0x0001ce6eb96dccdb,0x0000000000000001}}, + {{0x000c0c76c91a3d86,0x00001a3cab8eb5fd,0x000752ec9cff796c,0x0003f81d37bdda1a,0x000e12c746df5d95,0x00027c38d512fd50,0x0004e23ce093d983,0x0004adeb3545f200,0x0008acce0db1764a,0x0004097d3ea0eee0,0x0000000000000000}, {0x00057c8acd0df62f,0x000a235a3f7e354d,0x00043547a0eeee98,0x000831405ee1adbc,0x0006a916c043f6f0,0x000e4844ab1da766,0x0000728cc7b74a71,0x0007192544b4fdc6,0x0009d41decd4aad8,0x000497605d2bc303,0x0000000000000000}}, + {{0x000c16253894ed63,0x00072cd0f6a2350d,0x000412983f7baee8,0x00009f78d054975c,0x000d7bad42e9614f,0x0005f2ac60d67eaa,0x000622d671f099d8,0x00021f07bed1e830,0x00081424aeea7845,0x000f7592014c5f2e,0x0000000000000001}, {0x000619d3fbb4d7a6,0x000a9269d1beee9e,0x0002e4ef27debfd4,0x00069156fc40ac5c,0x000b31c86af27730,0x000f4aa3fc30b8ff,0x000bfd86f500b895,0x000c9dccb88b68a2,0x0003b7832b9f66f8,0x000853497ba1895e,0x0000000000000000}}, + {{0x0000b0ab29d3bde4,0x0009c71ea0d8e5cf,0x0004b6204df30d49,0x000d3f548f748b9e,0x0006eba95c754c4d,0x0007ad6cc9c44387,0x0009e2d08e10896d,0x000ea9428b4a544e,0x000fe71891a2d3e1,0x0006b905c7660eb6,0x0000000000000000}, {0x00066e6414125179,0x000e2877106f8fb3,0x0002d9d82f542b36,0x000b4eca63743c2e,0x000cfc887146aaf2,0x000ed669e0b28d08,0x000c885c73913714,0x000914ee1f56da28,0x000d4479d84424da,0x00015e3364622742,0x0000000000000000}}, +}, +{/* digit=58 [{1,2,3,..,}]*([2^232]*G) */ + {{0x000bd25b5edea690,0x000347c3abc5bd1f,0x00078a11d29a3138,0x000c6d62f2283223,0x0007b4af4ece3ada,0x0001c75e4372b0dc,0x0009560a7308e28f,0x000d0ea7127d9913,0x0000172da9cb3c31,0x000c36c69386a7ee,0x0000000000000000}, {0x0003be2a2cae0b56,0x0000778293313929,0x00041cdee07af8d3,0x0000895f4118b415,0x000b9b3a9502ad6d,0x00004e1d44242767,0x0001a843924f3834,0x000a3c5c40dce7a9,0x000443e9e0f30db5,0x000c5338df60b62d,0x0000000000000000}}, + {{0x000d88264070b39a,0x00060f5a265bdb95,0x000717063ef771ed,0x0004ca000dd813de,0x0005a4d348196d97,0x000def16129d2691,0x000bcbbfcdfb3523,0x00057290d6981eca,0x0000c5d2444e08c7,0x00091c65a063c65c,0x0000000000000000}, {0x0001941d0c9b7cd3,0x000cc0a5845e0e75,0x000c51c09cc90c04,0x000ce8aff11f3a2b,0x000303944ca09536,0x0005cb9d10d614a2,0x00062674cf73a00e,0x000639b5262911f3,0x000379f49e681d43,0x000ea07634bb0927,0x0000000000000000}}, + {{0x000aea3b47740815,0x000ede22e76e20e2,0x0007e03afde6eca1,0x000f70d608d1c44e,0x0000b88d585444ed,0x00074d298cd8ec39,0x0001146c4c3f6754,0x00073274110e9ce2,0x0009cf1f4b12ae7e,0x0004fa67e9f4b4ce,0x0000000000000000}, {0x0002ef9318bf7948,0x0004cb3efdaff610,0x00059bd31047a8b9,0x000fad7c4b8b1235,0x000a02488482725a,0x0003b462badd939d,0x0009f8945cb99ab4,0x000c0f6b65c66a4b,0x000e97dd0bddb4b1,0x0009d75a1f797639,0x0000000000000001}}, + {{0x0000ec0aca9d0f94,0x0002fb13ee984570,0x000e5ad047be55b4,0x00073a0845bc6993,0x000ffee41f2aee8f,0x0003c832041ac680,0x000bb4a740b12fcd,0x000521ebc1645e36,0x000dfcc7735a45c9,0x0008ef92b0fbdab8,0x0000000000000000}, {0x000805ed4e45e0eb,0x000584829d754db5,0x00036cc488a6c810,0x00060f1ec9632468,0x000c0f2ebc30d39f,0x000e960758390502,0x000f4626d1feec9d,0x0004f944bca363ad,0x000375dbfdeea282,0x00050ba887d0959c,0x0000000000000000}}, + {{0x000857ce82a61386,0x000fab480b18fa40,0x000223002b9297b0,0x000f9b41f698e6a5,0x0005eb688e33b253,0x000cc09f30bec2ad,0x000eeb6333a5ffe4,0x000bc81e94524303,0x000091b660b277fb,0x0008fd03ed404dad,0x0000000000000001}, {0x0005dd59faaf5be9,0x000abe017edd5410,0x000aaa4856720e0a,0x000d987f4b1178d8,0x000fe5e556ef405d,0x00081f659d8f4002,0x000f7836cb450ed9,0x000350d35c2f69df,0x00095c15741d4705,0x0004c982d30172da,0x0000000000000001}}, + {{0x000f854cfa0f1b9c,0x00036c27f5709e7d,0x0002fcca4c8efcec,0x000a965fa53691ad,0x000f70705ad9f4c9,0x0006ca89080d5043,0x0005cff60c807ea8,0x000ff2e47ec8fa95,0x000846288bda4094,0x00003dd7b4f68fa6,0x0000000000000000}, {0x000c953f0c60b7aa,0x000060469787d616,0x0009579f0ed52085,0x000faf3c529ad3be,0x0006f18223d47482,0x000c07ac1ad869d6,0x000437b5cb0dcd56,0x0004dc765feb592a,0x00004a294944df05,0x000184cb4ad2de82,0x0000000000000000}}, + {{0x00003d153000960d,0x0008f85dc5ffb696,0x00009b3d9302c4f3,0x000fd9668bf9ae36,0x000a25bdc3c8ecf4,0x0005c1a7bbfdb2a9,0x000393a4a4463083,0x000a4d41df85c97b,0x000d92cc6610ea8e,0x000bee7a14446540,0x0000000000000001}, {0x000fe7092ab307cd,0x00055b75f48236e0,0x0009f206af987311,0x000191b95f1aca72,0x000b01a57a7e9b13,0x000784300caa5513,0x0001b4e8ad08534f,0x000e7a92df980dd1,0x000edd78871ce4ff,0x000f2fbe3e6a8b6a,0x0000000000000000}}, + {{0x000cf8b0ae3366de,0x000c06074154422f,0x00007a17d21e5dad,0x00001e78c237ee85,0x000d108f5fd2183c,0x00098eec2dada49a,0x0001c303e35f7659,0x00091f2075445a12,0x0007426d8f5fdddb,0x0006af1dd7a92c53,0x0000000000000001}, {0x000c31da2f658936,0x000e72228504949a,0x0007646877ed3189,0x000cbac9e04fe426,0x00093f8802494ee0,0x000975ea85d9fdf7,0x00038fb0c9c6045a,0x000802b88cb118cf,0x00057e39ea12c877,0x0002548e571e0697,0x0000000000000001}}, +}, +{/* digit=59 [{1,2,3,..,}]*([2^236]*G) */ + {{0x0001f89eed993384,0x000860d77e7f7ed9,0x000e9a249862cf0f,0x00026963705ade19,0x0005d0f929eafa4b,0x000a12f7eef6f18b,0x0009d590ff1861d1,0x000d6b67d2954ef5,0x000540dd418bcbd0,0x00096e83b51e5170,0x0000000000000000}, {0x0000a67de6f33ef5,0x000d0f090cb0d50b,0x000b8b3eeba89c8f,0x00026dc5289c0d96,0x000e0e6dd7431a8a,0x0000a660c8afde18,0x000cfa02cc76374f,0x000b7654494d397b,0x000476b8fd958a15,0x00097d53a314e324,0x0000000000000000}}, + {{0x0005d2d913938d7d,0x0006d9d471ad5a92,0x00018a88bdce6ad3,0x000b90be599734aa,0x00099aa6c0fb7b20,0x000eda14b233c887,0x00024ee7dad41f1c,0x000cb7c643d13bb9,0x000e7d84ea63db6f,0x0003a846de4666cf,0x0000000000000001}, {0x000e6128e81e8c45,0x0001464a9235f4eb,0x0002db34ea2780d1,0x000ad3e8b3ecdbc0,0x000f8cdbe120731f,0x000f4318097ab5eb,0x00079ebbf1d4990d,0x0007e93c15830f8e,0x000c40a1cfba03ee,0x00068df76de664ef,0x0000000000000001}}, + {{0x000267eeb458a4eb,0x000e492a1279f17f,0x000c76f729af11c0,0x0007339e92b8f2a3,0x00014e00c8ca3543,0x000dbcc01641f96b,0x000755e449dde571,0x000a0a0df11e5fa3,0x00031770742dc646,0x0006f53610d1c65d,0x0000000000000001}, {0x000e5b808553c438,0x000499c99fe83176,0x00019eef1a061f75,0x0007deb8d4c21a60,0x00033192fdd7ecc6,0x0003250ef2ec37ce,0x000aff8f6ed93441,0x00058d1e9777ac4b,0x00083407f0d67d5c,0x00079fd1b5287171,0x0000000000000000}}, + {{0x0009d6152b9c90b3,0x000aff28f438100d,0x0000a2146e64ecd5,0x0009ad5b7e0c0df1,0x0003f6775181b0d1,0x0003c7a1b8151d7c,0x00035c338a3ef9f4,0x000e1fdd81712dd2,0x00034726a1f2597e,0x000cb3083971de47,0x0000000000000001}, {0x000c041200d9bef5,0x00067c85ff590dfa,0x0008b72aaea952b7,0x000265e7843ae9c1,0x00032307d7542004,0x0002dea503395a89,0x000e1eec7f73a8fc,0x0004b86c7eb53399,0x00021cf862926b2c,0x00019347a4f0820d,0x0000000000000001}}, + {{0x0004f7b384cd7297,0x000acc1a4787e2cb,0x000a5590739ea069,0x000be73fa99d3f7a,0x000e7cf6cca23601,0x000960cc53aa83e6,0x000b86b5920b1173,0x000fa7ac9dbe20e0,0x00068bb6f6b3ef99,0x00064060ac6c56f4,0x0000000000000001}, {0x000626c189f97eeb,0x00092eb7dd82a1dc,0x000142f8425008f8,0x0004b241705cbf37,0x000c04c8483d101a,0x0002075cfd275951,0x000f282a7dae45a8,0x000263c98e81a9d9,0x000c331b130bf290,0x000c95c5f55addef,0x0000000000000000}}, + {{0x000ac9a1c36e3c24,0x0008e09fb461cd04,0x0007bca251b2abd0,0x00098ad8fa6e8384,0x000087e953f04f5d,0x000d9f6c57ca3dcc,0x000f179679c5992f,0x000cc9cf93cdfac8,0x0000d1a320e29622,0x000580703c650a05,0x0000000000000000}, {0x000188e58d397fdc,0x00021860a160b5c1,0x000be9a3f426d729,0x000f8747311911d3,0x000b78a79eb1a864,0x0006b881dee2ff5e,0x000fc87ef83107b6,0x000ed139997a8784,0x00080e84fd894e5e,0x0003aa1a2f41979a,0x0000000000000000}}, + {{0x00031707560bd53c,0x000c9501712fc58e,0x00010e30ced00607,0x000465e677b023a2,0x00067620a31c653b,0x0008ea62e5b10af4,0x000d99048d08ca5a,0x000d65af877831dd,0x00029f5ab5be8899,0x00028321d38a082b,0x0000000000000001}, {0x0006bb42378c6e38,0x000fb8ba4bc4d5d5,0x000a4ef2e4b28b7a,0x000b41f7c314822c,0x000a2882d9a51ae9,0x000e6c2280f2b327,0x00019697ce965ab1,0x00075708dae4a49d,0x000f1175eea346d9,0x0000e9572d2fbccf,0x0000000000000000}}, + {{0x0007d4bad9839247,0x0002744af0bab5bd,0x000cd1e04b0ade61,0x00080a7fe21c3a53,0x000864b9871244ec,0x0003f6fd1428f483,0x000889d63b180bf2,0x0006acf748b0e2b4,0x000a061072996dea,0x0006607cdec9d5f3,0x0000000000000000}, {0x000a9858e242fc0a,0x0001fa2d38ce4fc2,0x00087521e69c709b,0x0005bae8f5996fd9,0x0005e131ac99f4d0,0x0002578fe3c3bad7,0x0002279c9d139206,0x0004b6fbac903ada,0x000292885696da36,0x000ddbd02ce1356c,0x0000000000000000}}, +}, +{/* digit=60 [{1,2,3,..,}]*([2^240]*G) */ + {{0x0001074e0ee1b4c2,0x0001a0ff10eeb73d,0x000c77549f2e087c,0x0006808a5e2e0837,0x000e948c7156c74d,0x000c13bf7c11f82c,0x000a51472ee287eb,0x000b28c4e6f906f6,0x0000fef0b165038c,0x0002d8b6f1c9d932,0x0000000000000001}, {0x000d310ce2cf5a19,0x000c08add6b6df57,0x000dcd4cb28cd825,0x000e1cbe48bebf85,0x00051f1d5aa6a644,0x00008ba85cbebbd3,0x0001bc84d8a2aa19,0x000d343d2d77518b,0x000a9098229b988e,0x000a9f940fc8d07e,0x0000000000000001}}, + {{0x00096ebc173a5d8b,0x0000ed54a67c958f,0x000ef67809a984cd,0x000abb728dd8453d,0x0009f4fe5f363de0,0x000e4fc4614b7360,0x000fee4aab1b83c8,0x000606d2158cb989,0x000096597fe56f7d,0x00057270734a0c52,0x0000000000000001}, {0x0004ef503a18dccd,0x0009b732b2f44d09,0x0002c29898debd6d,0x0005ffd4e0ef3ff7,0x0003830b99ae2e5d,0x000dd5fca5e1c94a,0x000e97015b084de2,0x0000e94504be6d08,0x00079eaed90fe0fe,0x00051eafa2897ddb,0x0000000000000001}}, + {{0x000dd470cee4255c,0x0008ea907208e445,0x0001157ba3e551b3,0x000f94c51b72b693,0x000b183c616c9cf9,0x000fe84fcaaf1c59,0x00077c97ed67f1d2,0x000a1d1e1a09f1bd,0x000c2f47751550da,0x00038d58d345e7ba,0x0000000000000001}, {0x000d95b5f854d3f8,0x0004daa404c99ba5,0x0005a1bac7d29f41,0x000da46981c9d673,0x000652c1bc49956f,0x000e505f2a66bdcd,0x00081069783eab5f,0x00036f9996ab9237,0x000238170a7330e6,0x000670fa70e33da6,0x0000000000000000}}, + {{0x000e86a58386cf1e,0x000572f15be04bfe,0x000e35f663e32b87,0x000f5c5294b48632,0x0001362fb4267165,0x00007dadeb7d3b94,0x000012e189d86c34,0x000d63e5f7805689,0x000b7e33561c7907,0x0003c0c0dc085fa2,0x0000000000000000}, {0x000cbe4f2b4f6916,0x0002f30cfb081da9,0x00011fe0a525ac2d,0x000bbd4632662679,0x000223e344c2d8fc,0x0000a08757b1ff41,0x00001c0a48229e9a,0x000456b8c92c6f71,0x0009a086c4af0e80,0x000d74c21360d8bb,0x0000000000000001}}, + {{0x00000ce7164d30ca,0x000fedb34ef3a45a,0x000800620f8ac5c1,0x000c7c79ba6237c0,0x00088ff56f44997d,0x0008ab94745563d5,0x000df21b2b00a9ae,0x00086a286295b8d1,0x000426dbb4cf9b37,0x000ec830b7004300,0x0000000000000001}, {0x000a97f98f792db1,0x000f9d5a4e4b251f,0x00061b4d385d3a62,0x000b4cdaad987701,0x0002341727a73b90,0x000c4abf7e84f908,0x000f0ded814c4a3e,0x0002c453671bed3d,0x000a888690c8945f,0x00019a94087855dd,0x0000000000000000}}, + {{0x000e5f28e7fb0752,0x0005ca705e5e780c,0x00093ca952d3af74,0x000eccdc7351cb28,0x000bfc12e9837fed,0x00014b93567e7bfb,0x000546247999f34d,0x000a3f729887c629,0x0006edd285692b0d,0x000fc9812e383cc9,0x0000000000000000}, {0x0001bc941d72f110,0x0009ba70199860ef,0x0002d090c33493b9,0x000503ff279e0c37,0x0005c3fbe286bbe1,0x0006d81c3e80f646,0x0008d3a0a9257bf0,0x000e402ee72a2a44,0x00092b91c6a5669f,0x000ad95315497ce5,0x0000000000000000}}, + {{0x000b397c9c0b3f5e,0x0008573318572b93,0x0000e667f17a3327,0x0000b9137af5bff7,0x00017fb65a96b2e6,0x000188dfee9e25ef,0x0002c9edd117ab29,0x00015472d03d830a,0x000512ca1063aa4e,0x000adf9593f42bd8,0x0000000000000000}, {0x00043be475ba796e,0x00023dbbccf7b7a1,0x00080d4a4b140a81,0x000247748562ea6a,0x0002f53e144c7e84,0x0009ac8b6fa39d88,0x000b1eab451fe154,0x000ec4538f34ffe4,0x00076cc290527aed,0x000d83bcd8efdc10,0x0000000000000001}}, + {{0x0000c5c5bcdaef57,0x000720046d980167,0x0000601ff33f7b5e,0x000e6b0aa07084cc,0x00007791af83b900,0x000dd856fdd2391e,0x0008d880430654d2,0x000f826068896340,0x000a4b443c176e8b,0x000c4e18c663e62f,0x0000000000000001}, {0x000d8ae0441a598d,0x00065c950e8cec48,0x0001316d53d11b80,0x000cd6863a5ccc8c,0x0008ced41a668fee,0x00076ba771bb4164,0x000b49a9a4bb4b6f,0x000e370974d5a9b2,0x0000485def9f130a,0x0001b84c25f49d20,0x0000000000000000}}, +}, +{/* digit=61 [{1,2,3,..,}]*([2^244]*G) */ + {{0x000f43bc2dfb404c,0x0008b314169ebb20,0x0004d9ce016776ec,0x000b6f3c40cc814f,0x00075de6701fd64d,0x000be16687bc27b3,0x000c8ca41b2641f1,0x000e5c7ebdd8aaf1,0x00021918a667e429,0x000d9384d2d4cd92,0x0000000000000001}, {0x0009667398bc8b35,0x00026c502a6f1f65,0x000612fc65ae7726,0x00047588d1717c45,0x000b0cd0bd27306b,0x0007b68702fd9dbc,0x000a43a5beaed3af,0x0008d9e3bfb560d2,0x000c14b9b618c615,0x0002421dad1537ee,0x0000000000000000}}, + {{0x0009e7889bf8b6ea,0x000292e957ebe27b,0x0002bd715ca3ae1f,0x000ea4756ae08fea,0x000f5cab67aaf3b2,0x00047caa37f247c9,0x0001b8953af0925d,0x000557e7bd1f409f,0x000979eb14ee5b8e,0x0008bb0e2890300b,0x0000000000000001}, {0x00078d6b71ea9467,0x0000c63dfcb1d01d,0x0008e6aaf05595db,0x00006ff49217ec90,0x000b8ab12df36451,0x0004207aff8489ad,0x000b85d257b835bc,0x0003706e08a1abbb,0x0002a5b7d71ad10a,0x00056ae224792f6d,0x0000000000000001}}, + {{0x00028daca765356a,0x0000ee74680323bf,0x00005f51f95b6f29,0x000c6656c3eab37e,0x00038ce239752348,0x000cf8aff4ec8ff2,0x0003adc6745b80af,0x000e56c344a76be9,0x0006011d48a9f827,0x000ed4a3e016c1c3,0x0000000000000001}, {0x00096e22c7a80fb0,0x000891624b09ab2c,0x00049f6d4616a383,0x000b275d1cd7006e,0x000adb9075332618,0x000586e58c4079b5,0x000645e2b19bf36f,0x000f76906dc5820f,0x000f6bdd7a51a11b,0x000b67dd8137d034,0x0000000000000000}}, + {{0x00095b8b650fd71f,0x00014965b39aaa82,0x0001270c9510690f,0x000b3a9f763e6fce,0x000be3f839143baf,0x000866c1890dc990,0x00074c8a0d6a0e73,0x0004b520d476087b,0x00081006ed8910a1,0x00052b16e6fb91bd,0x0000000000000000}, {0x00057756a63f7354,0x000a1ebe4b13d097,0x0003f1884cec54fb,0x000503924519ff97,0x00059fb9e4f42689,0x0002ce5e202d309b,0x00098e0004b85f0f,0x000b05c20b1735d8,0x000add1fbd4f54e0,0x000dcb178e2a7f34,0x0000000000000000}}, + {{0x000b4ec871f1c2e0,0x0003b5de22756058,0x0000837f536100e3,0x0000c16f1ccaf424,0x00056dcf857da01f,0x00038c07ebb5fb6d,0x00096a096d6242a9,0x0003055c2b2c30cf,0x000a782e55f66ac8,0x0004f012cc9c2c3a,0x0000000000000001}, {0x000506352d9bc635,0x000b06aeaaa56b9a,0x000095186c35174d,0x0002167f537385d7,0x000cf421a089f0ea,0x00022c37dc99678c,0x000356bf33a69466,0x0003e97eafc66d63,0x000e3c0197b16669,0x000d912a0fa3fee5,0x0000000000000000}}, + {{0x000a52c892d50f2a,0x000dfd8fc48ea89f,0x0004b09bae86a680,0x000a1e1278d67917,0x000370f37ae3b7ce,0x000f51107a8383d3,0x0005c8e157913dc9,0x0004c347e479bbd0,0x0007dfb63e7f7f02,0x000ac4a32c2410c2,0x0000000000000001}, {0x000c5983d275b47a,0x000f3ebc8a42a9a0,0x000db0533ac31f03,0x000cb9b707b4440f,0x00064522041e91b5,0x000076367218816d,0x00023be78c44489a,0x00060289668fa7d8,0x000b7bda9a033e06,0x000c041bf9880e14,0x0000000000000000}}, + {{0x000df487e3ac46f1,0x00026f6aeda132f0,0x000f9138020c745f,0x000a8841334fb2d5,0x000c66722bd6a712,0x0005a1ea4533d309,0x000636323c57e66d,0x00008eb26f26bbe3,0x000fa479b5dc3fac,0x0008f02e50177e02,0x0000000000000000}, {0x000c92b56635aa25,0x0007f4d610ada23b,0x00010104e5566f0f,0x0004f4b30ea26b57,0x0004efd9675fd322,0x0001af8f50ca2f0b,0x000382d177aefb1d,0x000538151171ef73,0x0003347891a319cf,0x000711dcdab779a2,0x0000000000000001}}, + {{0x0002b024db8d3d78,0x000aa5cc47fd4499,0x0004ca3c2ae301e6,0x000f6635a239d460,0x0001e72a93968b59,0x000f3e7cb493da74,0x00057a0e451c8476,0x00090539a4ae9584,0x000df123a0ccc6f4,0x000f3e4b36ee4a70,0x0000000000000001}, {0x000bf5964aec0226,0x0008d0d54e934ea5,0x000838881f3a4f9d,0x0001904c5759057f,0x00054f74d21e3d23,0x0009110e0965fa28,0x00025473e3fbb9d0,0x00066659568773f8,0x000e05953c3213d4,0x000de0c6c9fbf74e,0x0000000000000001}}, +}, +{/* digit=62 [{1,2,3,..,}]*([2^248]*G) */ + {{0x00023dd4a823eac8,0x000e2984db5faf62,0x000d39d495d0b0f5,0x000841ce0a14e52d,0x000cb365ed8de723,0x000bcb1fe9b4ef0f,0x00047ee3aa7d5d2d,0x00032d33c7e0b190,0x000d3b9dde2978f5,0x0005329dbc97d12a,0x0000000000000001}, {0x000d165556c00ac2,0x00057fb3172c7a02,0x000beeb32c48804b,0x00099dadad774958,0x0007934b2bc9659e,0x0003fd281f90ab3c,0x00013abe477effe3,0x000378b329a3faa7,0x00036cbb9f3df235,0x00014562e824d0ac,0x0000000000000001}}, + {{0x00078de5aeb19662,0x000d1f458b071bd2,0x0000313ed9b5b584,0x000ce5fe5f476cd6,0x00077007678c1c54,0x000258964a6d145a,0x000420c0c62f8fee,0x0008595f7056fa68,0x00089119263621f2,0x00019c5d8cf9f82d,0x0000000000000000}, {0x0000243d2e6cb7a7,0x0008d78d5a87bb13,0x000c4e517b3bcf90,0x0000f65dd0ef67bc,0x000d930e5dd35ba7,0x000eb9fb0741af2f,0x00075eb448314eea,0x00003702fdd3f71f,0x0002c0a91bac4835,0x0008e91ebd11ec1d,0x0000000000000001}}, + {{0x000160f761d5cda1,0x000d737ebbdcd5d3,0x000d7809f98ac1a9,0x000dcdbd555d558c,0x000fa398a682b263,0x0004f2c8dcb516cf,0x0003f1fdc39fa308,0x000c8f35f0892119,0x000b1a2e7b6b0e00,0x00060305cb4b78de,0x0000000000000000}, {0x0005dc3804225ef5,0x000a4dd0142d36ef,0x0006183af50e0ed5,0x0006c670fcbeb371,0x0008629b90cb9a81,0x0002af3261b35739,0x0008aa6b6e9823af,0x000fbd19a0ec458b,0x000311a98270a0a9,0x000299fe388efd5b,0x0000000000000000}}, + {{0x000bf04df8057734,0x000b1031cb2cfcf4,0x00013e25b6e0c3ad,0x000fa4cf3dd2ab40,0x00007758e2edfff8,0x00031ad907feffd3,0x000b4564baf111bf,0x00073c4f6a12eba1,0x000fad75513a8160,0x00074de7fc43bd94,0x0000000000000001}, {0x000d44eee593810b,0x000f1e369ffff5b8,0x00064f19da65334d,0x00021d0f5c2b9ceb,0x00091c5ca3390013,0x0005689acf02b87e,0x000bf7c3a49c8b54,0x000093f7ed7c049d,0x000a0a1d58d27784,0x0003d7726f20ba73,0x0000000000000001}}, + {{0x000ec366cfe8b8dc,0x0005109510bbe0e0,0x000aea6451541d52,0x0007f0a613f8478f,0x0000f85f758544a0,0x000f2b250e479f86,0x000b98246494bdaa,0x000483bd40872db5,0x0001ef43cbf9eee7,0x000bc8abec7ccf7e,0x0000000000000001}, {0x0005c21b7bfcf30c,0x0003ee117f493af1,0x000fdb4b0534832d,0x0001fa1bf55f45c9,0x00078f7e3c1efc43,0x0008a7de78a32d11,0x000dc3559e7ee791,0x0004e7a865c863d0,0x0007e1e671e05898,0x0005634bd3bf85ef,0x0000000000000000}}, + {{0x000d81691c2ab48f,0x0002541bcc0607cd,0x000da791a7f87cac,0x0008347771261610,0x0008e3bac250c120,0x000659e04001e2db,0x00052cf1b9282899,0x0009b392289990cc,0x000164d7d417f75a,0x000945df41fb11a9,0x0000000000000000}, {0x0009c07103c6ae84,0x000480fee72710d4,0x000b8360a2b9d155,0x0000e0d3d7e07da2,0x000d149f0388daf1,0x0002f71dfdfd1523,0x000418130ff86f14,0x0009f7346c3e8b09,0x000b2e35c5e699a7,0x00052b1c1fdc6ba3,0x0000000000000001}}, + {{0x0003345adc3b52d1,0x00068ceb5ac071d1,0x000e11041a7e60d2,0x00074a2a70677323,0x00040734a03353e1,0x00041105a4c9d8da,0x00044e1f19873918,0x00091f314a743285,0x000322e1b26f9179,0x000d3d1613ed69ba,0x0000000000000001}, {0x0004543cf00ed5fb,0x00053fab663cf4cd,0x000be8cc8843f104,0x000f74fe45dc2276,0x0004319b78ce0e03,0x000389520a05dc90,0x000cbb592960d2ca,0x00026ed0dfe3e1c7,0x0009036fca8841aa,0x000549d9ea193025,0x0000000000000000}}, + {{0x000d95d4b57fe6e7,0x000237e45eed99e3,0x000ddc0cb978fe19,0x00073f687eb46e14,0x0006f57bdaf6e4df,0x00047741a18670ac,0x0004925a46fbe2b8,0x000282f9632d0245,0x0002e144fc15a10d,0x000815c55aed10af,0x0000000000000000}, {0x0004dce0659c9bac,0x000b25a506cebbc4,0x00048b6559b03aaa,0x0008048a933863a2,0x00020d37a9de4c34,0x00020f440226cd5e,0x00074e9ee95db69c,0x00082f425e1eff1c,0x00033a6f8d820bb8,0x000ef06f95cad219,0x0000000000000000}}, +}, +{/* digit=63 [{1,2,3,..,}]*([2^252]*G) */ + {{0x000e4e5c561d5097,0x000b584aedde8b8f,0x000aba27830c0d36,0x000c7d59c0f869dc,0x000b714a35cbc32b,0x0004bed4bc22d71a,0x000061f00680d9e0,0x00033bf0836adf25,0x0000d7fedb3d768c,0x00095c616b984e3b,0x0000000000000001}, {0x0008c5d5c16b3659,0x0009b2bd923c283c,0x000fbaf03219a32e,0x0005bdb0f0d8e95a,0x00027d3039b5fed1,0x000c59ce26d89427,0x000676fa1dec9a4c,0x000121992696f0b3,0x000260c98b8c7cfb,0x000541c1c9792927,0x0000000000000000}}, + {{0x0002f821dc52854f,0x00009f01e839c81b,0x000f9520b0acb7e7,0x0005ef6ec4857ab9,0x0007209f9eda63a8,0x0006daca6651f475,0x000d6976e7173379,0x000240b37bfaccec,0x000b4437229f4ce0,0x0001910fe8a0ffcb,0x0000000000000001}, {0x0007819702adce4e,0x000559cf2ed75ea3,0x000524a7d80f948f,0x000a15733e1fceef,0x0008e25fd5510058,0x0004c29ed3586531,0x0004e51cb7d9fa11,0x0006f171b487caa6,0x0006163b82558054,0x000686de74000000,0x0000000000000001}}, + {{0x000b150deff72861,0x0006369a87c08222,0x000222ff210ad76f,0x000b4d66f2177234,0x0006ffb6d673f874,0x00059b847a7a63aa,0x00088181fb601b85,0x00061d5a56e17f52,0x0009cad3b2dceae5,0x000b7064799ea515,0x0000000000000000}, {0x00071777678fbf96,0x000ee3fb840953c6,0x0006c82ee1fe6943,0x0000476345986586,0x00027b2c01a1da88,0x0001dd9ed1d2e620,0x00093b57ac9ecf98,0x000aea3ed52ca86a,0x00083c732ab42d43,0x0005274badd57297,0x0000000000000000}}, + {{0x000860f86c3463c3,0x000fa451b92975d3,0x000e9c89aced751f,0x00082df00fff3b8f,0x0004d44ceed1d22e,0x00022e7d389ef4bd,0x000e91dec43e5b63,0x00003ac6cd725daf,0x0003c7139385f22e,0x000deeecc87ca1c2,0x0000000000000000}, {0x00051580221e0fc8,0x000941fbf97dbfd6,0x000689ac9e872372,0x000740f84611974e,0x00046e04ba0c6ce7,0x000419caa07a8f97,0x000565905b0cdaf7,0x0003cd2570033075,0x0003b2c015af7e40,0x0003287d54b47d8e,0x0000000000000000}}, + {{0x000087653c1971e3,0x00077f0a153e5f28,0x0003ed97c2828991,0x000095935157a12d,0x0003722663e4ec8c,0x0008ec4fe824b403,0x000dd44aff641d97,0x0006da087485323c,0x00044e2cb2c2b861,0x0006eba170078d74,0x0000000000000001}, {0x000b5b83303bc746,0x00013dec62dad85e,0x000eb52890ef39fd,0x0007414a67a192cc,0x000ca32294492ed1,0x000e1460a8a16787,0x00024c190537d3f9,0x0004d8dd49fa5c1c,0x00025dcc6564966f,0x000872ce77f122af,0x0000000000000001}}, + {{0x000f907cb543fab3,0x000c69a83a50077e,0x000cb4bde1d63e29,0x000c33fc44a3bb56,0x000f82a91020da98,0x00021551aca18ce5,0x0000524e8061c783,0x00030bbde84c8ff8,0x00080aaffd7e7a07,0x00025503d2cefb4d,0x0000000000000001}, {0x000d489c09cd7406,0x0003bbf72e670d86,0x000584e3d6cd578d,0x000c5357fb7dc505,0x00078eb6069dbc02,0x0003d4fa59d19b85,0x0000398d29e9ce8a,0x000efb99649fd29d,0x000ce49c616fbd54,0x000860686cd02ccf,0x0000000000000001}}, + {{0x000b5280bf38c012,0x000b16e5d0e927a5,0x000e0fabbb77cb27,0x0009a5fc1a89a6d3,0x000a92cdb34cf1fa,0x000464dc9a9cf793,0x000eb464387be7aa,0x0007fbfde96cd4d4,0x000232f3e162772a,0x000656aee57c0a02,0x0000000000000000}, {0x000a4f88de057838,0x00017126373b6048,0x000e4a0f6263ace7,0x0001d00ce841a9eb,0x0004964f3fadfdda,0x00053a6795df2847,0x0007970db46fe5d6,0x000fc5cc5ee32eac,0x000634cedbf5f3ce,0x000fca10e755fd0e,0x0000000000000001}}, + {{0x000aeb844e0e5a47,0x000278171b725206,0x0003ef95a8f2f67f,0x0001fdfb411d7c3d,0x0002cbc9db5d5134,0x0004cd3d499c831f,0x00090a75fa0db406,0x00072c8d72cfb8bb,0x00070a986050fdef,0x000f2a584d26e897,0x0000000000000001}, {0x000357b6cd8cc5f7,0x0006b375fe114c8a,0x000aa2296d0e1fc2,0x0007cba1e2fe623c,0x000b8ca73315ce03,0x0007e86db236843e,0x0005e04b5b70ddfb,0x000420198f9d4b15,0x000535cfa0692139,0x0005a2aa06d43751,0x0000000000000000}}, +}, +{/* digit=64 [{1,2,3,..,}]*([2^256]*G) */ + {{0x000cc45663bc9f5b,0x000b2868f57feb89,0x0004bd3cbd6a2543,0x000a5e560bf63c0e,0x0000e648f4a5666d,0x000591427cb7d9cc,0x0005977ab848b1a7,0x000af4656829e85c,0x000ae8f7a4025667,0x0003b4ab876527cd,0x0000000000000001}, {0x0004ed81840ffbcd,0x000e4830db96c420,0x00026c352dd1b3e5,0x00003369497308c9,0x000023370174e547,0x000c6d8497a95345,0x000ecbfae86058c7,0x0008a32e4cdcae7a,0x0004e9eb567daf0b,0x00085eaf8dd7df3a,0x0000000000000001}}, + {{0x000deae24e7511a4,0x000762cb23734ed7,0x00066bcd84d23939,0x000c037c989a46bd,0x000c06543988385e,0x0003f08c8acc808e,0x00000e7680dc66ca,0x000e4c3c5332a768,0x00063204acc98ee9,0x000db0a0ef46de86,0x0000000000000000}, {0x000b4a4e27fff289,0x0007eeb14e22b305,0x000e9d3141e930a3,0x0004f15435f5cd09,0x00052f55ccf3f336,0x0006c9377055f313,0x0000f610c74549ef,0x000c8d0207da4bf8,0x000b6ee97b1c2b15,0x0000920992fd2caf,0x0000000000000001}}, + {{0x00043f2525d2ebb4,0x000811edb2cca106,0x000c996f27900e32,0x00092edb6f6af92c,0x0002dbdef8275bf9,0x0004dd3d26338446,0x0004401818a7ff9a,0x000d60e7694d8e21,0x00054e87fa7aec62,0x000f988bdd22449d,0x0000000000000001}, {0x00063c9fbe4e6775,0x00026d7e7ff11afb,0x000c6b3e18f7eec0,0x0005c983e08b80f1,0x000b75d6b5a4c84b,0x0005f99e3a4b0fd4,0x0005a7cfc4904ce8,0x0006c336a99a7afd,0x000e4a736ba1e62f,0x000595be20ba2924,0x0000000000000000}}, + {{0x0008c92f010fc781,0x0002463423f6e871,0x0005f129e35dae8d,0x000d59f4aeff7db0,0x0000c963932f5dba,0x0005e468db3cf82c,0x000e23c6b7d10e1f,0x00006e08595910e6,0x0008880e8c76fb1b,0x000134e8c1259453,0x0000000000000000}, {0x000506649d87b671,0x00014c272ea4f089,0x000aa2740669dd1a,0x000622f8a6cc0d62,0x000e392244f6f191,0x0003dcbd9dd28338,0x0000c61a8dd7166c,0x000e4930a90ca39c,0x000d41296b979b8c,0x000037aa5c88b76c,0x0000000000000000}}, + {{0x00051d16f31cd955,0x0003fd720fff5e54,0x0006c62e42ceacd9,0x000b72856f74fc83,0x0002b8a51db93ff9,0x0006ca983e7b6bb4,0x000e06f8fd893a36,0x0002491c6c8908ee,0x0008e9f64e123094,0x0005764984e58063,0x0000000000000001}, {0x000ad9aba979f347,0x0005557b9d835c0b,0x00089b7877984846,0x000ce8c3c6bb325d,0x0002e0fb571c388f,0x0007185f17237c5f,0x000ac5737bcf4832,0x0005f037df6f53b0,0x000b6f7ae34a972e,0x000821f685c7b273,0x0000000000000001}}, + {{0x000e5575bc0dd4ad,0x00028eabf66053ac,0x00054861cbd6dc53,0x0005b123ea9fdaff,0x000c00ecf823c855,0x0005d8934d09e411,0x000eb090ae97a01a,0x000591dabc9c170c,0x000f751f273c40a7,0x000f0f52861011d8,0x0000000000000000}, {0x0002bc9a33075cd8,0x000bb779de4fde35,0x0002eb1b199f0130,0x000e29003c4457b6,0x0009ff04878d3a95,0x00004ebfeec1a9dc,0x0007d0d097a6545e,0x0008673c7b41f5aa,0x0007894e63c5c4ce,0x00005b385d1700a6,0x0000000000000001}}, + {{0x00046d7efcbdeae0,0x000fbb2f349cfbe6,0x00022f14a9cfd187,0x000ef46f7fb5a2ff,0x000d8084df701781,0x000b2e7da6ada115,0x000273537b36285a,0x000d779e5cbe2143,0x0007b1bb342159b5,0x000321182d17ef98,0x0000000000000000}, {0x000974b9395d5c1b,0x000a203e9046670c,0x000c9fa51be4f31c,0x0000167fed87df23,0x0006d7ab1aee3553,0x0006c8a7b334d671,0x00037b8b3f821601,0x000677ee013df3eb,0x0007a3a1013ff132,0x000a7ed7d1a2e9a5,0x0000000000000001}}, + {{0x000b3fd002806466,0x000fd4605cfac818,0x00085d2f0b811efd,0x000167145bb41efb,0x0006e3c03cac7ee2,0x00085c4b2dade36a,0x000220dcd3725a14,0x00032cf525a550bc,0x00014db66b11c84f,0x000013664e47ace3,0x0000000000000001}, {0x000a48858e7d464c,0x0002276f7bbfd1a7,0x000e24ada567d04c,0x0006a941adced466,0x000c270addbb103a,0x000761ca82f14e02,0x0004d0794b62798c,0x0007a0bec3f90326,0x000caf618966e8d4,0x00021a1f211c02e6,0x0000000000000000}}, +}, +{/* digit=65 [{1,2,3,..,}]*([2^260]*G) */ + {{0x000c24408b5b4bc1,0x000d861e48c2aa26,0x0008746f93b2fb6c,0x0005f018515690c4,0x0008d76a3c1b771e,0x00093035c899fbb2,0x000d18ac338e0049,0x0001b4e7f02fa3d8,0x000fabf9b804c035,0x0002f83e6175e309,0x0000000000000001}, {0x000830680485a054,0x000962c1a8a622f6,0x000f94a3f3450d94,0x0007a83e0a44d62d,0x0000105319e21805,0x000a4a1ebdd2bed2,0x000f4863d6076c13,0x00034672ca137368,0x0006135e4ef4b1a4,0x00020b6692537ff9,0x0000000000000001}}, + {{0x0001b7a5e08fe30e,0x00029eb048815ab8,0x0002e0a161f11e12,0x0001801becb84207,0x000ad5b394a58f8e,0x0007512807890edf,0x000f675b3e4e4773,0x0008c99841055d81,0x0003ed35c1050ce1,0x0006c217bd56acf4,0x0000000000000000}, {0x0000d6c8c5a1e005,0x000ddbaf53db5dcf,0x000c6ab4e4f6ee72,0x000e686032c8481a,0x000415c545af61b4,0x0003595ad60e7c0e,0x000f59b261ffe75c,0x000cf66fa7cfbf47,0x0002e7097fa1aaf6,0x000a8386b7977f21,0x0000000000000000}}, + {{0x0000029a7619e46f,0x000f29f5c333074b,0x0009e45f3bb1eec5,0x00035aadf8396133,0x0000825d3e2a3176,0x00034ef799bdaba5,0x0007f38574f4d09c,0x0009085e808678d4,0x0004a57483db0387,0x00054465ae9f6d1c,0x0000000000000001}, {0x0002fb74fcaebc4b,0x000ef4b901e46eb5,0x00068ec4a861868e,0x000f51a07bab1199,0x000748f19df109f2,0x000d75da4f6a75a0,0x000f255613859652,0x000e60c8067759f7,0x000b663826b7b569,0x000f450533f4d440,0x0000000000000001}}, + {{0x0008e66704c4911e,0x000b5ad20de07d3b,0x000dab27e9b7aafa,0x00052dbe3fb66eb5,0x000cf7ce856345ac,0x000025496cdf84c8,0x00082f095b8e1e29,0x000e8e6db4cd7761,0x000b0faa321aaa54,0x00088ae73fef003b,0x0000000000000000}, {0x000d643fd4fac454,0x000c4870e138d616,0x00069ca59b85612f,0x000a26a00889a9e6,0x000c093e3dad6fb3,0x0006ce66bb43df1b,0x000244dae036271e,0x000c05182a82fcd4,0x0002559d8958ca2a,0x000a7526838c8510,0x0000000000000001}}, + {{0x00084b954cc2f383,0x000a776cd88b3801,0x00070c99422dcf3b,0x000bd45086f66f43,0x0005f7b81c0e8bc4,0x00004cad2493575c,0x00070ce4091825d7,0x0004f1ff4bbf4b9f,0x000d28bd9ac2a0a2,0x000c23e5ebf7a3b5,0x0000000000000000}, {0x000270e7ebdf9c15,0x000050eb783548eb,0x00081562bc5fd0b1,0x0005f68896b8a59a,0x00073bc130375edb,0x0001c5bd938ab1fc,0x000c19c89b28feaa,0x000f8d6e4b1c7f18,0x0009f7384e98a494,0x000a3f55131bf640,0x0000000000000000}}, + {{0x000a27923d9331dc,0x000f04ffb6351b25,0x0007f29f1e1c9bc2,0x00069b7d91e80528,0x000d48a56cb26370,0x000d9a9a20ff75d6,0x0000b393f52dd397,0x0003703dee3c5227,0x000f9c1c267288a6,0x00083849651d4713,0x0000000000000001}, {0x000d56c853c2dd2e,0x000a93bc1a8d521c,0x0008735173646598,0x000967ee4685de4b,0x0004cf35701ef418,0x00080b116b6dbbce,0x0006b03c5acf7cf3,0x000fe839b4243541,0x000841fbd8d1a9cf,0x0003a6e1730d1f15,0x0000000000000000}}, + {{0x000fdbea99958b96,0x000e01f76bf65ac0,0x0000c6778adf573b,0x000d0f51ffd85a6f,0x0004afe98c72d927,0x00087e8ec8173887,0x000d76d032ae57d1,0x0004df95e88800c6,0x000ec4042dee55d1,0x0008e8cd5760c30d,0x0000000000000000}, {0x000eac1084c10f00,0x0001c37bdb463a14,0x00076281603cbf77,0x00034037d48543b5,0x000f3b965ac3efc6,0x0009a7be5b6e5426,0x0003d0f87fba3664,0x0004ddb5ca9f2e20,0x000052649abbc317,0x0004b72eb6083655,0x0000000000000000}}, + {{0x0001bc4f61438294,0x00002964a43b5d5c,0x0005d7c26171c634,0x000967cc93c0fb82,0x0004b96145dca1b7,0x000b5c4ddfd06836,0x0007f0eec5bd3c73,0x00082d7bf8f0d500,0x0005b93c7771d6fd,0x000475f222990f21,0x0000000000000001}, {0x00026e01b4722367,0x000926340c9a0a1d,0x0007edb2bec04b5b,0x0005d17d0417ca25,0x00072b41c7280efd,0x0003c942f670df33,0x0007910fbfcef999,0x000437ef3a577e3d,0x0004d4c9039005c5,0x000edddb0ceb3a8c,0x0000000000000000}}, +}, +{/* digit=66 [{1,2,3,..,}]*([2^264]*G) */ + {{0x000a3a0634a3ce07,0x0008f38d14324956,0x0002232fc3562771,0x000d389e5a0479ef,0x000b882744b806a6,0x0000bd687af4d435,0x000d3172792b960b,0x0001f792e60e4cec,0x0009dcb17063be91,0x000c5902f6ffb4b0,0x0000000000000000}, {0x0004fbf6f215ba3d,0x000918e7c66f8fb0,0x00095b38bbb07b90,0x000022d201c5b207,0x000344fdf3937c67,0x0005a11142ee01b8,0x000cb5fc7b97506e,0x000c2ae4043311b8,0x000e1937f2450b7b,0x00045fa26a70cfe3,0x0000000000000001}}, + {{0x000fdc4396bfa539,0x00092b7edbcb88f2,0x00019d35421db912,0x0000a538d5dee79a,0x0003b035e9ea2a42,0x00021709fe9cf14f,0x000a5b749703f94e,0x0002495b47e8690c,0x0002ef0574deb7af,0x000dd4b09d6324cc,0x0000000000000000}, {0x000f7df3b9fe6e0b,0x000f9e25c764e67f,0x000b9153d851593e,0x000822d7ef6d9489,0x000c9238e5449117,0x000bd3333b1e34e4,0x0006cfb58cc8198b,0x000b7b487650416c,0x000068c07a8085b4,0x000b7b5e20cc8eb3,0x0000000000000000}}, + {{0x000af6a4691425a8,0x000eb7a958bb9efe,0x00085a7002151b0a,0x0006a8775208123e,0x000055575f5446b3,0x000528fdeea0c896,0x000a43b1b4d824bd,0x00096f550c5c7315,0x00050cdbb6610168,0x000b9c3638cd4a93,0x0000000000000001}, {0x00039bfed8d0ec30,0x000230c0cb3e1745,0x0004b3cb7f69dddc,0x000a60a97d0d2a3a,0x000c6d61d74827e9,0x00048c2e237c10e2,0x000c78dae64ccf95,0x00031e036445ee96,0x000bee13f244e4cb,0x00012ec220b81c78,0x0000000000000000}}, + {{0x0008b837d4bef687,0x000919e15922b2f9,0x000c8afde9c62c29,0x0009534c95a1a3c5,0x0008f604b1043ffe,0x0007a01a13fa2f63,0x000393b04cd8a8d2,0x0006e26fd0c22660,0x0000808a072545d9,0x0003871dd10699cf,0x0000000000000000}, {0x0007dfe3a4ea56b7,0x000094c38223ef03,0x000e8b66c87d36e2,0x0002766ee28405ae,0x000f0a065b535e3e,0x00084a317ded4b87,0x000866d3f53ac0b0,0x0007a0ee55860ca5,0x000a7080382b21bd,0x0002f3ff1d58cf1f,0x0000000000000000}}, + {{0x000760a0d077a674,0x000256d1eb02b933,0x000a86e63e76464f,0x000e22b473632441,0x000db481034e4b15,0x000914ef870834a6,0x0004c2dffa8bbf34,0x000d9d0466943feb,0x00031a2dbf893cc1,0x000615fa26911a87,0x0000000000000000}, {0x0002f76d13211f86,0x000b53e5f9871239,0x000bd8e3f6da4b87,0x000367de3555d6f5,0x00095ebc54c2b323,0x000413dbb2bd8e48,0x000ddef4e974c105,0x000de08da1d15f48,0x000eb47f901deb65,0x0004f245e4c32880,0x0000000000000001}}, + {{0x0005b2c93a39a68f,0x00012def13c9b690,0x000a5eaf60ed34ff,0x000eed4546115d13,0x000acc0704820ad4,0x0000c499c60761b0,0x00013af5dd51e45f,0x0007a978e5524abd,0x0009f811db1ec09b,0x0005900dab7d3aa7,0x0000000000000001}, {0x0005f21e6490481e,0x0009c0ea3d3b19a7,0x00068df5edf0364a,0x000c93c95e1d6b4a,0x0008333e2dcc0b44,0x000a8fc7be078322,0x000350437cb9512e,0x0005c965c20fe9e1,0x000d3176a887068c,0x000004e870a54162,0x0000000000000001}}, + {{0x00005c3b211947b8,0x00027fda98024305,0x000832a6aa27a459,0x00057be3feea006c,0x000ba0bb599ef407,0x0009c187eff74059,0x00032aa4ef6180b7,0x00072b398f55afe2,0x000cc5ddc46af4a2,0x000e611d5ea71271,0x0000000000000001}, {0x00085981da5484c4,0x0002661fa0fa34a4,0x00025e8fb282c8f6,0x00009d9542344d00,0x0005e720cc73e773,0x00081ad0388c6b65,0x00097a5b5f85f411,0x0006173a273c5fde,0x0000126c0a036ea1,0x00030085c778a65a,0x0000000000000001}}, + {{0x000dd3a67c2984a5,0x00072c7824703af1,0x000bf0c69c5b39c7,0x0000901a46f942bc,0x000f89e0174be31d,0x000b6326f7d38bdf,0x000eadb91bfcc1ea,0x0002541868bb8787,0x000a48a8ba038566,0x0004606d8787616b,0x0000000000000001}, {0x000e290f5d5f8e88,0x000eb41d33d54569,0x000662b634f1ba52,0x000fc5049dfd1d1b,0x00059be51c909876,0x000b7406ba93e420,0x000475a49355b9dc,0x00048963ea182651,0x000985ceebcf7670,0x00062eaa85c80508,0x0000000000000000}}, +}, +{/* digit=67 [{1,2,3,..,}]*([2^268]*G) */ + {{0x000b5648e1eb2291,0x000ba734c2f6e413,0x0008535398b202b7,0x000a8b23ebd7f177,0x0009fd3b0fc5e7ee,0x0003df55ddc7a0f1,0x000261d577641e2a,0x0008f496646ecb9f,0x000f2be9c112454e,0x000e02c23da6a9da,0x0000000000000000}, {0x0009d35c52fed679,0x0007671efd66d8e5,0x000904f29b91b401,0x000c352b084f27ae,0x0000123e88566129,0x000229faaea32636,0x00087f4c04620cfd,0x0005535f695ec91c,0x000fc2a2127c5854,0x000fa1c94873fa3c,0x0000000000000001}}, + {{0x0004b028b8f44cc5,0x000fa18c73e470d1,0x00046af781c684d5,0x000aadf0eb44feae,0x000604610320e3e3,0x0008fffa44fd9c59,0x000908270d9d9d3d,0x00088a6283f3ebbc,0x00060d649fcec534,0x000e1d44a603fadd,0x0000000000000000}, {0x000740ae33023df3,0x0000135f6a91ebce,0x0003780772b2000b,0x0004747ae7ea71ec,0x0007f6f03b13d0e5,0x0006603e33fc299d,0x0000d28b6e9df68d,0x000a2043747f8604,0x0006089683aeee37,0x00024e9926fb8de4,0x0000000000000000}}, + {{0x0006c9f15018542e,0x00079fb1f6fe5f6f,0x0005889ab7c13ba5,0x000129b7c5358418,0x000a9ac0306d8ad0,0x00008b37c84cfb84,0x000acf7da701dcb0,0x00014bb42427b3eb,0x0006e318d3d02d27,0x000958db234da419,0x0000000000000001}, {0x00031a9f2e6d1d68,0x0000ba7009240e02,0x00063eb8c05422c8,0x00081b3a6ec6a77b,0x000bc58689a5aa19,0x0006306dfb930061,0x00007013549ec203,0x0005410416293e63,0x0001a4d303fabd7a,0x000ac172f1e81c7f,0x0000000000000001}}, + {{0x000b9ad3970b9e18,0x0000bf6af8e430ab,0x000f59d55e652348,0x0002bd614bc56b8b,0x000183df0a6ecc07,0x000ee1786d25c98f,0x0003feabcc84059b,0x0007b20a09a6f26f,0x000d600ce79a2dfb,0x000f39cf2e6f0393,0x0000000000000001}, {0x00072a39f3507cb8,0x0007042b1470af9b,0x0007da313b04804a,0x0000e590e67c9622,0x000cabec90cccc29,0x0005e76e6a796f29,0x0001637cadb620bf,0x000d15b03af38ec0,0x000dcf7634087520,0x0001906c0ca6b7d8,0x0000000000000000}}, + {{0x0007eccab473c8b5,0x000354c80ff211e0,0x00045d2bf3c3aaa3,0x0005bdea352cfb52,0x00016f804d4fc256,0x000e5ad706ca34f0,0x0006619c96cff608,0x000490525e689857,0x0004163c78de4a6f,0x0007e4b87dad9b7c,0x0000000000000000}, {0x00035a48ce31e1e3,0x000c4a6aef85129a,0x0002e4b9afe02466,0x000a8b4fb7e5c1b3,0x000e4ea65ec8abb1,0x0009979db25393ba,0x00064b047eeb2086,0x000d6e5e56906ac0,0x0008d958b203281d,0x000de4155ed9842b,0x0000000000000001}}, + {{0x00019bc174c6d988,0x000cf4d9f702e572,0x000883fd073431fc,0x000f7c52e0996638,0x000331a7f7f18050,0x000e9196a2374342,0x00087a7400e71f3a,0x0003791b5d724c12,0x000499ca89fe518a,0x000e565820d945a9,0x0000000000000001}, {0x00035b7cb9fac00e,0x000a632b3417a9e4,0x000077b9768bc095,0x000afb46dde432fd,0x00032553ea0ffde2,0x0000725529dbe056,0x00071cbdddb8ca1c,0x000edb41a198fcb3,0x000f5060041dd314,0x0009a1fe368a743c,0x0000000000000000}}, + {{0x00059195e6de2d3f,0x00030ea9f4518076,0x000e3f066c30b9f7,0x0003bd981db2f294,0x00046e95c601e580,0x000782f5d49b6ae4,0x000f2a24bea15da5,0x000d57d82c482be0,0x000747b852b55a3b,0x000400c12ad66ee4,0x0000000000000000}, {0x000106fc9ab22be0,0x000f3ff85e4be397,0x00064c04ee049a9a,0x00068c1771b2f4aa,0x0009c56a4f6e25c6,0x0006c0243a7cc3be,0x000082558b6f8b1c,0x000d25ba47737910,0x0009a82551abc22c,0x00044f195c4a902e,0x0000000000000000}}, + {{0x00037e57ac34630d,0x000fc2c030f2d54f,0x000b84aa880649ef,0x000b55a13ad19d77,0x0002091bd296d1ca,0x0008f7f0b28c0816,0x000d7580c469726c,0x00021840b8cfb847,0x000fd3c1cc59a8b1,0x0008b90e2778fdc8,0x0000000000000000}, {0x0006cc1f42f98900,0x00026c3bf2f82644,0x0008d5f8bb74fc86,0x00077c747df08423,0x0005d41c77ea13a8,0x000556d8fe471d93,0x0008287e98cde5b5,0x000c068f4d40279a,0x000305a88e400538,0x000e77c091d74bdb,0x0000000000000001}}, +}, +{/* digit=68 [{1,2,3,..,}]*([2^272]*G) */ + {{0x000190a6f12cf864,0x0009e0eee766f86e,0x0005b775cd536070,0x00057c69d4566a98,0x0005745df1e07e40,0x00047733f9c06722,0x0006e2b1b1c2a5a9,0x000fc80987a24bcd,0x000f4061ae7293fb,0x0007d711f7042b89,0x0000000000000000}, {0x0003c1b0341e791c,0x000537daedd9c1c5,0x000495a12d7c48bf,0x0002d4a32c8c9765,0x0005a662fe9dfe7c,0x0007c6bad9faed52,0x000660c5c4df70a2,0x000bba7fb07624dd,0x00091b1d621abac8,0x000771b618ce5d4a,0x0000000000000001}}, + {{0x000c915030a7a399,0x00068b673999f751,0x00008c22b2afe146,0x000bf6a5fc300d5b,0x000b3e178c0bceca,0x0009d38258020b90,0x000176381c171fe7,0x000e86f32623a2f1,0x000f64b9bf3a66cd,0x0002c55668f5ac6f,0x0000000000000001}, {0x0001812516e735d9,0x000aea3ea58c5dac,0x000356a5f10de279,0x000295b07e9f7153,0x000f586ce9eb4d08,0x000daab1a3f7c783,0x00000a0030b2d7c4,0x000c2198f3166033,0x000184aa9d0c0475,0x000b11a6fe88caba,0x0000000000000000}}, + {{0x000ba5c8d0193b1f,0x0007644c52e9d2ec,0x000084d971b1a2c0,0x0000ba2904071452,0x00016420810c95b0,0x000726c12ee37ace,0x0005cdbfb3b34658,0x0001ddb8f12176e9,0x0002665465a782ea,0x0005989e91fb9ee1,0x0000000000000000}, {0x0000c16d55245f9b,0x000a5ab01d1b1ade,0x000186cc016cdfa5,0x000f20c1907f643d,0x000b819ce2692951,0x0001e463db499758,0x000551bae173a15a,0x000c9960164a1a60,0x0005b509da7db4de,0x000254d9cec8875c,0x0000000000000000}}, + {{0x000b44e11c323d06,0x000fd5d6d986113f,0x000894e506cf902d,0x00052247fd0b1d00,0x000a2782247b185a,0x0003bd1827ee7a96,0x00075cc817a81ab7,0x000d58e21da1b5a6,0x0006b1f8c96f3b0a,0x0005eb0b4feab1ba,0x0000000000000000}, {0x000e1e70f2721b75,0x000160a2caaa6a94,0x000c595ff3de4a5a,0x000a75c84e2aab67,0x000e555f145b7c4c,0x000c6003a47731be,0x0008f07e7fe03b5f,0x0007c95ac06b0bfb,0x0000ec8f9062bb21,0x000d58a73aafef97,0x0000000000000000}}, + {{0x000123c6709431e0,0x00010ae6e4e2793d,0x00084b28d12b01b7,0x0007bca51962e973,0x000f98e6a52dea7f,0x0002d8bb8dd35519,0x00063c8d202bed1f,0x00009ec87640cd7a,0x000e8802cf11aa3f,0x0002789d1734b8f7,0x0000000000000000}, {0x00015a8a3e8d859e,0x000534ae889a29d5,0x000da86637742cb4,0x0005ee22c15c8252,0x000ad4f9397a87f5,0x00093d8a684e2ab5,0x0006af7ba63ff2ec,0x0004f0fe6a52e297,0x000effff8321e195,0x000d2957562f8dbd,0x0000000000000001}}, + {{0x00023e7069e42e0e,0x000d2239c3ca8089,0x00005746ae0d546f,0x0009bcbb8ee8194a,0x0005279f5c84f339,0x000373c06a06d19b,0x000c70d34e701108,0x0008ba438171e418,0x0007c7306769b5b5,0x000064bf193f46da,0x0000000000000000}, {0x0005544b033a42d2,0x00061e556329a54d,0x0006aab67ee7a477,0x000c61bcc63287d0,0x00034397f22f1672,0x00021907d612d307,0x000ccf64c77cc188,0x000f80df2be0b759,0x0001db9d853899e4,0x0007cb0c4b9b73aa,0x0000000000000000}}, + {{0x000ff9f36c3349d4,0x000c3db537864c16,0x000d990835ee2990,0x0003c5fb1d408a12,0x0004b5ff931b6504,0x000452158a1b1e0b,0x000db8a2c29f72a6,0x0009d61be31c5985,0x0007a2320489621d,0x000480174d202617,0x0000000000000000}, {0x000294c195148880,0x0009ed88751bd34b,0x000f46ac8a70ae99,0x000917e5c0560f97,0x0002525c8ba24922,0x00048c3502a88bf3,0x000ee6a458ba7134,0x0003f607a14e42a8,0x000dd29054842573,0x0009c1acd66ae0e2,0x0000000000000000}}, + {{0x000edee700e2b9a1,0x000ca05fd3e47e10,0x000775354363597f,0x000b8ab9d14d9e5f,0x0009809ae6cb63e8,0x0008a4dd84740965,0x000dd249f1a5c96c,0x0004d2f79af0cb6e,0x000166e5361d2b7a,0x000692fe3d22a60e,0x0000000000000000}, {0x0002fa6f8995a329,0x0006e396d7a363f7,0x000d92f57cc488ad,0x0009d1958510a286,0x000c0b888aa8bf0a,0x00042decec317136,0x0008b9bdf9fc71bf,0x000ac0298d41b6cc,0x0009ecbb249e5d99,0x0004db314b57f810,0x0000000000000001}}, +}, +{/* digit=69 [{1,2,3,..,}]*([2^276]*G) */ + {{0x000d708c668b7357,0x000d96ce839038b2,0x00020e1ea62ce28e,0x000713c58763eab5,0x000e2c4523fd6ed2,0x000eae1cb271027f,0x0005e4f9c4b8cf67,0x0009601ad02024a9,0x0007d73ac0716494,0x00064337442ffcdd,0x0000000000000000}, {0x0007851b23ec84bf,0x000beedb8574d7b7,0x000286ebfe9b645b,0x000e45ce0c8710d8,0x00056a79aecb4766,0x000f379f83c2d312,0x000bbc5340ea164b,0x000df851521a164b,0x0009d5d5e1ac3081,0x000081b205779b7e,0x0000000000000001}}, + {{0x0003e4b56c489ffe,0x0000450823173431,0x000479ae5276717f,0x000cb05ce3d436d8,0x000ddf2257834d02,0x0007cf804300a63f,0x00048d555acde6aa,0x000b3233d0de457f,0x000aa55b4de5db66,0x0008a60379d9ac81,0x0000000000000000}, {0x000e90717067058f,0x000132c47bead613,0x00090e8a449f2111,0x0001c278b92dfa6c,0x000a20e5052e4286,0x000d62ef7fbb21a8,0x0005d03da29cea2d,0x0002b105405706ce,0x000dda27b321921a,0x000d13a8070a212b,0x0000000000000000}}, + {{0x000d23cf55c45926,0x0005b98778f5f299,0x0001705a5c8c8b02,0x000b88f43919b71b,0x0001fcb92372e0d5,0x00043296e160fa37,0x000a4970a89cc719,0x000334a3ae695fe1,0x00051e4b95dec2f9,0x0004d6275a594212,0x0000000000000001}, {0x00047e08dd859c11,0x000f2faa12f1b2ff,0x000ffb55ea0ad152,0x0005927a2d49016e,0x00063e898a743956,0x0007e768ee6cdbde,0x0009ce79201bbe74,0x000b64e8832a0a06,0x000cff0774d3af5c,0x00081d58cc25a522,0x0000000000000001}}, + {{0x00027f0e1b46fd00,0x0003f1c1b9a1af5b,0x0003c2c754fc491a,0x0007d3165cbaab1f,0x000360310665c2a7,0x000a6d64bd760e64,0x0004ce1abfa1968d,0x000d2b0e1701fb5f,0x000d3c4d7b466c4e,0x000f912ebf21257e,0x0000000000000000}, {0x000f6e44d2ef47a9,0x000cdeddd0d09650,0x000acd3234c8ca37,0x000cba5fb7244def,0x000f3acca56c2d39,0x0004d3ff0e42e4fe,0x0003498d03959e10,0x000b101ed923e651,0x0000842e240deada,0x00047140cf65c53a,0x0000000000000000}}, + {{0x000420de7a3cca92,0x00078c40b5d961dc,0x0000669c0650c56a,0x0006512b20ea2fcd,0x000c80cfdc1ced7d,0x0002dc4c42793f28,0x00014af2a2c66b61,0x00038712d0f465ef,0x000a3e10f498de28,0x000eefd43378b1ab,0x0000000000000001}, {0x000182339af2de22,0x0000f52743e62529,0x0007cb967f975c8a,0x000a495f3b942e5d,0x000442c93c4c7a6f,0x0005ea4e81af911e,0x0001c3361393032e,0x00046ad975cf453b,0x0008fb85fbd84437,0x000e9f19bef58359,0x0000000000000000}}, + {{0x0001c8a03a758373,0x0002ff5d3c5d987b,0x0008d28755f9b053,0x000696c9a6811aec,0x000671a05c762526,0x000b50917885c6fe,0x000e435b1cd97329,0x0007d6424b129ce1,0x000fb69b5d25c001,0x0005bf8fd3449e7d,0x0000000000000000}, {0x0003b3b4745aa0fc,0x000a304f13caa8db,0x000c42581d38c65d,0x000a26e3f1637449,0x00075086fb17831b,0x00070bccf51f20a3,0x000ec67794f66bbe,0x00008759114e8fb9,0x000e55fefba15c3e,0x0006b06274e840ba,0x0000000000000000}}, + {{0x0001392a85eee65b,0x00037ebdba8a73a9,0x00057c70feb31623,0x000f9841fe6064d0,0x000abb8ea58571cb,0x000f4d78e10f9265,0x00010194ea34ee68,0x000ee932bccc86c6,0x00018b05ba4d88af,0x000c7f1b666c9e95,0x0000000000000001}, {0x000bfc49e59e8fd1,0x000ae405208c75f8,0x000d373c5a99df54,0x000a977279933e71,0x000da64aa0b3f5b8,0x00036d2c0da96b6a,0x0002eed5227ca046,0x000b6e0ffb64c414,0x000baa05111d0f26,0x0006496cce8a3203,0x0000000000000001}}, + {{0x000c440343aef952,0x00019eda15115cbf,0x0004c0ca17c7be65,0x000b899e1e404697,0x0006bd56cb968d39,0x00077f25afafaffc,0x000e8460c48baa89,0x000cb8ddcae733c5,0x0004e7b4d8db3dd6,0x000d4730c42ef0ea,0x0000000000000001}, {0x000ded4336e0e996,0x0007761c36485b3b,0x0003a9ef9b460a85,0x000ea119c163b2e2,0x000f8699c32d39ca,0x0009afc21d6fbf2a,0x0006105b2f30acbc,0x000d2782e1795cd4,0x000bd0296c5de1eb,0x0003f540db331e94,0x0000000000000001}}, +}, +{/* digit=70 [{1,2,3,..,}]*([2^280]*G) */ + {{0x000566c4dd75c1b4,0x000a0570856265b3,0x000cbace31affa63,0x0002b4ed64645336,0x0006de49945b2d79,0x000ffedb2ccdc41c,0x0001239fc3fec1e4,0x00056c094341fb38,0x00028185bb5868f9,0x000adaf680572da8,0x0000000000000000}, {0x000e0585aa2d876a,0x000b95480f8f0fbf,0x0005be334d530bd3,0x0002f278c2d3c86e,0x0006b676d6c82d76,0x00039dec8e1488b5,0x0003e4b756194ec5,0x00094e5ad8a2c0fc,0x0001d4129e01cce4,0x000c459cb7e94c1e,0x0000000000000000}}, + {{0x000e172f71314c57,0x00073776d707122e,0x00007937b43cc86b,0x0005775ac42e1bf4,0x00055e0abab130a1,0x000a4930e58a6f41,0x0005a237af5f75c8,0x0004f7ffdb8ee4d2,0x0008fe7af47745ba,0x000467da1f09c11c,0x0000000000000000}, {0x000ab833ab90a6b8,0x000669bed4019358,0x00007b7fe4d74f45,0x000d834f00a5516c,0x000f035a36d318fe,0x000f8a31bb46f3d5,0x000972946e1df3bc,0x0001ef24a7e886c9,0x00085864c383ab5e,0x000a5b85a50c0d32,0x0000000000000001}}, + {{0x000d65b66d82688c,0x0003872c2925e382,0x00080fde81ac79d0,0x000a2b38a2432027,0x0005fa34422b6bc3,0x000948d55e24a659,0x0004efa7ed8f149b,0x00071011867cfac1,0x000bd1e94e578bbe,0x000803efa0276501,0x0000000000000000}, {0x000f7389f88ed003,0x00099b4f58dfa2c9,0x00027af2024d3bff,0x000a0ca5e0ca7fb1,0x00083782dbf7ba09,0x0009fa5d6101098d,0x0005231abdbaa4b1,0x0009c03b0d70ddb8,0x000cba60cbb85949,0x0003ba8d596ce326,0x0000000000000001}}, + {{0x000ec042211830fd,0x000f78b67d56f78a,0x000d0dd5f0085f0a,0x00077ef6d1879493,0x00009d412929cede,0x000f8f47fc6254c3,0x00038136cfbb6a12,0x00090a561c304af6,0x00064012770283e0,0x0006e8c77dd363b1,0x0000000000000000}, {0x0009730231689c1a,0x00078a2910104065,0x0006adb22ec70366,0x00007eaa5919dc9a,0x0000eff75ea6bb96,0x0001b154022f103f,0x0002e9dc4300dcfa,0x00023ebbf1abfdcf,0x000c7610a1be47bf,0x000ee8e48e43b23b,0x0000000000000000}}, + {{0x000366222079ff20,0x000dd6c255282fb1,0x000e5f65eafcf45b,0x0009b30515c02959,0x000efd5074c2f0d5,0x000460bf3169d34d,0x000d88198c4daf0f,0x00042d35aae9cd4d,0x0006f8fb3a3e2b92,0x000e5b7ee19179cd,0x0000000000000000}, {0x00015c0c8bdd26b4,0x0009fc2499885330,0x000c27ee4ed9b18e,0x000e30d901ee8c44,0x000a438c4d057961,0x0007a847d74e4722,0x0005e9ebd34c3ce2,0x00049ec1f371fc17,0x00062cfa628ad626,0x0000258cb8ba2199,0x0000000000000001}}, + {{0x000414eef61746f8,0x0002f44b16d63548,0x00091c53690466a2,0x000700b4b9b4826e,0x00069ba41d6fddfa,0x000f48b184a9d1c2,0x000af1a9a1ae5623,0x000688445e2f1d66,0x00028a0ef16e7621,0x000ea0a509e87455,0x0000000000000000}, {0x00016c4ebf9d1f30,0x000002405c88d64d,0x00021995ea2cb159,0x000476f59206340d,0x0007fbdb47138c1b,0x0001fc51a673c4a8,0x000c132d81d7d81f,0x00033035e2c568d2,0x0001981e0c2e86c3,0x000c9f25fcaa15dd,0x0000000000000001}}, + {{0x000b2a49ca5dfb81,0x0008d370aadb7c4a,0x0009f4ebf1398343,0x0004d610d25c9ac8,0x000b49c7f0f75d8d,0x000cfed5c3ca14e0,0x000cd7f4d6f7590d,0x0007d93cbfaa36f5,0x000dce79a65cb3d1,0x0004b4bd97f1011d,0x0000000000000000}, {0x00001207087dd6cd,0x00049477a85a518b,0x0007671964d279a4,0x0001d11aff88af2c,0x000a1dbb6c2c5f27,0x0005ba326b82395c,0x0003c2898f431018,0x000463dc513c0cb7,0x00069f2786b20305,0x00061fc5c18db944,0x0000000000000001}}, + {{0x00080adc636061c1,0x0006244e403a263d,0x000ad04e1deab320,0x00059720dcbb6130,0x000d66e8505322a2,0x00060fb3f5231b1a,0x00049e1cd79b6e2a,0x0006179c366e663d,0x000c6ea0d01277eb,0x000473883c4ffde6,0x0000000000000001}, {0x00040167fca5210d,0x000d95aec71f687e,0x0001c63bde59a231,0x00074dfa4af79a44,0x00060fd79e68ddec,0x000b613ae2a19527,0x000036b08e61ca70,0x0003e30d2b549e73,0x0008fb383d922e0f,0x000aa028c146216d,0x0000000000000001}}, +}, +{/* digit=71 [{1,2,3,..,}]*([2^284]*G) */ + {{0x000090e2290855e3,0x000c63856faf70c3,0x000a537fff7cf9c3,0x00002007d0317a7a,0x00010dc853b3261c,0x0006ccdf2c616875,0x000385cd6f188d53,0x000a2955fa1d26fd,0x00087bdaef2d7d6e,0x000b0f3173148e30,0x0000000000000000}, {0x00084c9a254216ed,0x00047cc0770de6d7,0x00035e4c8fa4bf8c,0x0000f637aece660d,0x000adedb7b99e891,0x00082ce72b5ced4f,0x0001d4d0fa07446a,0x000194600c851570,0x0004ffcea4152f30,0x000c96f31c15edf3,0x0000000000000001}}, + {{0x0005b1c7831bdcc8,0x000d027bafc7d23f,0x00050c19efdbe5d1,0x0007a7533cdce225,0x000573af279d2535,0x0006015a5e144120,0x000803b571412097,0x000eb203384ac91c,0x000edd68012ba72d,0x00091d825c3d8d2b,0x0000000000000000}, {0x00023553a39f8385,0x0005b8eaf27fe164,0x000c4539fb7ef933,0x000adc9ffa5830e5,0x000950a5e503466b,0x0003a2a96a1dcbb8,0x0001a89a62dca0dd,0x0001d5f98db48a88,0x000554b9506e0a31,0x000dcd69efeec8e2,0x0000000000000001}}, + {{0x000b8cbe4b97fc6c,0x000e5a71915ba245,0x00044263935f5290,0x000ce189775a8de5,0x000cd0549c8def51,0x00027c89477b9645,0x00047cfbc54728e8,0x0000c7cb6412bf4c,0x00016bf97806ea22,0x000feea61b447d92,0x0000000000000000}, {0x000a3fafee06d0a1,0x00032a2cf4c624fa,0x000baceff4ee9dd4,0x0007411d429aa2e7,0x000d154759f7bffe,0x00091cde409d4d9c,0x000a9a31ac9508e0,0x000deb0f736891db,0x000c17f78c058b52,0x000b43e218c9736e,0x0000000000000001}}, + {{0x0000f4f238352945,0x000f07d445a023b0,0x000551441addd54c,0x00008f85e62fb5bf,0x000ffd275f3aa334,0x00001eb4ed1f4e87,0x0000af1b08c2f8d7,0x00093b5987facbec,0x000542336f0bc311,0x000587219a8c1237,0x0000000000000001}, {0x00052f04dae724bc,0x000e221a68b0a55d,0x0005bdff6f9d5fa5,0x0007e3f2da24e831,0x000628b43c649948,0x000a393f548cc549,0x000acee934d621cc,0x000e0ce12d1b52e8,0x0000b93c4f0e6025,0x00077116663ffdcb,0x0000000000000001}}, + {{0x000b53f717a44956,0x0002c65fee76e1bb,0x000ae70d2da363ec,0x000cd6887a61f9c3,0x0002283a4e23325b,0x000ae6d909c60aab,0x000702a1dcca3dd1,0x000938d6a31c5517,0x0003e01f167bc2d3,0x00067596be65d549,0x0000000000000000}, {0x0007978a4e132cb0,0x0005df10adf1702e,0x000364f7e05324c1,0x000693e3866569f8,0x00082e303b6c9df3,0x000298933d134854,0x0003d7696e64c215,0x0000f465322046cb,0x000e839e686c1c09,0x000b7f8ac2e6f682,0x0000000000000001}}, + {{0x000e71627b708629,0x00012bf54385d85d,0x0007bb4ab478b057,0x000a3b2ccc6b5489,0x000f67fa6f6a05a9,0x00073cd5233bfef8,0x000c4c4f505a80c7,0x0006a3fe8c185c9c,0x00059e110f37ae33,0x00054cb440dc7a62,0x0000000000000000}, {0x00050c98bc7b0e1e,0x0005a04b3793331e,0x0003b8d31034a8aa,0x000c95dac900df01,0x000fd52027ee1c99,0x000b5be3aeb891a1,0x00042f3b68574224,0x000ae00bb37d5ba8,0x000a7f31f3f36375,0x0008c304743a2813,0x0000000000000001}}, + {{0x000c7e03b7aa645a,0x00091f7e39a28977,0x000995d7d443d68e,0x0009f39216c442e1,0x000b376cc21c4025,0x000705644f75967c,0x000592e3b90bca20,0x00056be0ef613507,0x00097f2f7456e836,0x0004b46438409baf,0x0000000000000001}, {0x0005a21df85e1c6c,0x000b0ab454500393,0x0004c5912b476c6d,0x00065a0d1aa49d94,0x00059cdd7e7069d5,0x00090a402b7eeef8,0x000283db40b228bb,0x0005dcdf2c268733,0x0005a42d37d44810,0x000b80e5d1af0360,0x0000000000000000}}, + {{0x000c14cb537e819c,0x0005f2b3bf6b7569,0x000cc275187a0bac,0x000925ef6c2d559b,0x00025a54533380eb,0x00019f0d6cd0382a,0x0001433bbf74a021,0x000bbd994d4caf68,0x00027772c53999a9,0x0003af249226a38d,0x0000000000000001}, {0x0006a46b5b493127,0x000bee887c8f7779,0x00045dd063eabbf7,0x00029199a0a8e117,0x000918d22e28aea4,0x0000ecebe77e69a9,0x0007cecb0ed2deab,0x000637aa98d20edf,0x000a194790e52888,0x00060c73078fbd0c,0x0000000000000001}}, +}, +{/* digit=72 [{1,2,3,..,}]*([2^288]*G) */ + {{0x0009af391a8697ed,0x0007fe5bb7320546,0x00080d05ad03f5f9,0x000f9b7973b1a3ca,0x00033b52add9800a,0x0003cc487ccc82c5,0x000f71a0da2ae069,0x000c060c7047e46c,0x000a21503aeb64ab,0x0004ed0075b1d33a,0x0000000000000001}, {0x000a2bed91298551,0x0000c49a79f6b129,0x00022374a19da463,0x0001305962f001a1,0x000a3a3cc4dcc90a,0x000188b4cc026cef,0x0002ff30fbb1d3fb,0x000c36e3761cad09,0x000dbdbdc6354b93,0x000b2ab73317cff3,0x0000000000000000}}, + {{0x00003f3665635e4e,0x0004e17fd85da26c,0x00052fd006ed5f69,0x00032d252f043a61,0x0005c8bc9cc74510,0x000f5370ca9348d5,0x000540b56333c4c6,0x000bc9a5ca533610,0x000d8071b716d25c,0x0002367337f70a39,0x0000000000000001}, {0x000db6fc5387c11b,0x000cfd3251b14397,0x000d84aa2bfdb755,0x000e38100cc3e62a,0x000046071f1f89e9,0x000e7012d9e47fb1,0x000e6ad97ec5c7c3,0x000698bc4de4f6c7,0x0000c6a07a4e7cef,0x000198a03a3a1224,0x0000000000000000}}, + {{0x0003b8713123ec24,0x0000419a51d2d151,0x000c8ee7e2c9c855,0x00039f110d3d8f17,0x0008ce870e320ac3,0x0000d4e71030e599,0x000ace1a5cbbd4da,0x0007c15bfcfe41d9,0x000408b36096093d,0x0006b26a0c56d39a,0x0000000000000001}, {0x00035ac9181317f5,0x0008d46d26280ae2,0x0003c29370c4bff6,0x000addee48f7eaa2,0x00030f605627b203,0x0003e03ba6674883,0x000cdd81ae186660,0x000d8bc04a9667b4,0x000cbc45ee0c1b5b,0x0003d34e81dc5ff7,0x0000000000000000}}, + {{0x00063b161dddd94b,0x0003d7c93f0cc576,0x00022d6ac11071af,0x00012d84b9149bdc,0x00088e44e4632e63,0x000448cc8ec50d4c,0x000f89a6c85277ac,0x000e128700eabfe4,0x00042928ea38e5f2,0x000e293e261880b7,0x0000000000000000}, {0x00051028cc113b68,0x0001919b6a14e2fa,0x00082dfd5da09549,0x000ca662e13022a3,0x0002996fafc24233,0x00018dea4f505fe4,0x0005a2d96182166a,0x0000199ba55815ea,0x00077232622a4ac8,0x000311b13c3b8133,0x0000000000000001}}, + {{0x0008673adf41d204,0x000e2a0a390575d9,0x000dcb844f35fe0b,0x000b6f4f917550d3,0x000fc6ecf7285d09,0x000925f580342d9d,0x0008746022d9fb4c,0x0001b6b73d4bc619,0x0004aa1c30d7a3bb,0x00003bf32bccb3c5,0x0000000000000000}, {0x000783e73d6e9052,0x00006db6e57f7b8e,0x0005d1afd274f869,0x000318770758e016,0x000290175b314342,0x000e6d25df464413,0x000da9ee1f0d5093,0x000297855e553138,0x0007c7b64937a717,0x00057ccbf262664b,0x0000000000000001}}, + {{0x000d9056eeba30b5,0x000355a8c404c7b9,0x00039ffec5e11fca,0x000c3ac7b4f4c637,0x0001ace1869851e4,0x000e1816afc7de47,0x000d517fb7e6978f,0x00040e256f62bd56,0x0004bb4c53034a6f,0x000aa98eb4b9ad2d,0x0000000000000000}, {0x000fd2909662ab1d,0x000c55f8463596cd,0x000074f62f74b11c,0x0004dfc43f12c5ee,0x000ad69405653ae5,0x00089f1d6e4668a4,0x000187ca431697ab,0x000831cc4eed080d,0x0003a69f7d775edf,0x0004e434435eef6f,0x0000000000000000}}, + {{0x000a1403851eb93a,0x00085c9ae49b53f2,0x000926a512455b57,0x000ca729dbef4a6b,0x000b8440248e399a,0x000191c77a9a0e66,0x000873c8f27a8296,0x0005408861a08ed7,0x0002bbe9c5e3865f,0x0003549235be42ba,0x0000000000000001}, {0x000a46fbe3334020,0x000abf1524bdbc9e,0x000b376fa382ce55,0x00075b35cc1fb214,0x0000910d13b19369,0x000cf5d3212ad3b7,0x000c7e93b691b3bd,0x0001ba22d0312eb4,0x000285b3975e5da3,0x000c999e2ec96eee,0x0000000000000001}}, + {{0x0005bf15f46be575,0x000a1061cb09c821,0x000ae2de789e5912,0x000cecccd84851c6,0x00001b95ccd21d74,0x00032dddf26a2851,0x00049210122d3f6d,0x000f02c5d952db55,0x0004be99796a4aa1,0x0004078cde88aab2,0x0000000000000001}, {0x000d753b80855f9f,0x00078288aff9b92c,0x000f7cdce61cc49d,0x00048cc3dac4e445,0x000cb0ac2a937fad,0x0008c5bdda956fdf,0x000bb3e81841ce29,0x0005170e6c819f12,0x000efd73ecab58ad,0x0000f476a3a48130,0x0000000000000001}}, +}, +{/* digit=73 [{1,2,3,..,}]*([2^292]*G) */ + {{0x0004f332dc67a3c5,0x0003213d82a4383a,0x0000fc0621356af6,0x0004ca32ca05acfd,0x000c1e80103ea886,0x0009dd0ff4c2e9c7,0x0009d764c64b7589,0x000680c128a8c988,0x000fdb7cd881a125,0x000ec5f09f58ad77,0x0000000000000000}, {0x000ecd4f9cda86d6,0x000c4c41a633a8c6,0x000847c2f58ecb1f,0x0007b29592dae51a,0x0006e268f50e3a7d,0x000a27de2a3b5eef,0x0006d540d7a599e3,0x0000d01f9b571491,0x0005e52e5204fbca,0x0003d9eb48615c67,0x0000000000000000}}, + {{0x000d9eaa867420c4,0x0002f7f5caa2ddb0,0x000c31038c0ddc32,0x0001596a08fb4b57,0x000a6d9ca6980a65,0x00095c78a8ab32e2,0x000ba78e5808eeac,0x0004f5f9923d5a32,0x000ad1c8d3bbece3,0x0007098f8b845926,0x0000000000000001}, {0x000843645beef787,0x000fa28875d75316,0x000e13608c5a90e9,0x0005556eaf90c364,0x000dacc40e05857e,0x000c5012b59e332d,0x000230b2b76768f9,0x00032932d53c8a76,0x000999fbd573bdff,0x000840eee9300114,0x0000000000000001}}, + {{0x0002362363f6901a,0x000be66748446167,0x0005f5c47c0db36f,0x0002fbb39fb54024,0x000e344525a7871f,0x00071375bdbedf63,0x0000bd89f085fb8e,0x00001c59b6e647d5,0x0008031fa2f2ea43,0x000d9b58012b6657,0x0000000000000000}, {0x0003015fd48eca8d,0x00082cfde2151d47,0x000e4d908c99616e,0x00004977d4ec3b2f,0x000f513df9ad204a,0x000b66641e3ee923,0x0009df2175bb5d92,0x0004cdb5c3c90fcd,0x000de8809fac5725,0x000985c6981a627f,0x0000000000000001}}, + {{0x0001a0d912586411,0x0001b0d49fbe5702,0x000bb57b277de5b2,0x000a4b2d7291e7e7,0x0008c16da29ce1e6,0x0008f8b71f4426f8,0x000fbf76a6ebaff6,0x000cab510adb9995,0x0004b996a6ec18d2,0x0003bc3ce11f1f8d,0x0000000000000001}, {0x00004c4051321f3c,0x0003af34703d798e,0x000dd55e68b6b0a3,0x0007f09cb14161e8,0x0005357558d9c473,0x000d9a485a90c00b,0x000dac2508e73fc9,0x000ed252e5f5bb09,0x000b1efcb4ba2132,0x000593c58bf23933,0x0000000000000001}}, + {{0x000d1217cba9c6d8,0x00087cb7a562f7c7,0x00004fa0d0ea0e23,0x000c05e3acd8379e,0x0006d159e80cdee0,0x000029ffd63834d6,0x000500f3ee777b61,0x0007b75be130d659,0x0003756de768a261,0x000a541b809584c6,0x0000000000000001}, {0x000af54a67204972,0x00085857b547d484,0x000954a25746036a,0x000bc1881e0295bb,0x000d3d231831b4de,0x00002708fd517190,0x000b1e9571812770,0x000c3e25dfa6c88c,0x000fb3c57a9f5467,0x0001d404949d8103,0x0000000000000001}}, + {{0x000a34fad1eabbbf,0x000de71fa7ad8210,0x000d67acfecf1047,0x0005ec7ec527279f,0x0007906ba2abc3a7,0x00066a25ce54f7d9,0x0001e7d558ddfb44,0x000ba77bccd91efa,0x0005405027796dc3,0x00072f9ae8e511f6,0x0000000000000000}, {0x000feaa4cfcc2a79,0x000d60cf749b854d,0x000ac1632a7218b2,0x000a7ce21f4e0ce3,0x000550325628caf5,0x0006b7d84c8e6b8a,0x00081d8e5bd9a461,0x000bb7affd9d5730,0x000dca775afff520,0x0006a52e629d73fb,0x0000000000000000}}, + {{0x0008f6b8297fa26e,0x000d76f386ac99ac,0x000ce235f3a2acb0,0x000620801a076df3,0x000c62031f455ef8,0x000d6e488b1627c3,0x0008ebc5bf3c9afb,0x000c4512c254ea59,0x000abb87bcef237d,0x000cb4dcacb5a5ed,0x0000000000000001}, {0x0008e7718ef189e7,0x0004207cf70cc015,0x000e9a66810fd747,0x000d69bb7c99d1b5,0x000454409a3962cd,0x00014e1d3b541825,0x0008bec33aca5afe,0x000a9c5e4a92268e,0x000bf2e95060a307,0x00093a289c336375,0x0000000000000001}}, + {{0x000781a84aba36d2,0x000ad7584291d55b,0x000992c0a266ea73,0x000e02af20e9954c,0x000ca4d73d175169,0x0001612ee12718e0,0x000cf1ded50926de,0x0008c1060d91c638,0x0007dc332b5998df,0x0002624eb7dc884b,0x0000000000000000}, {0x0008eae21aadf4bc,0x0005c2a9f4bf2cd7,0x00086c74c6b37272,0x000a4de4b5b5158f,0x00093ba4800d6736,0x000138590e451f46,0x000263ed2239cb95,0x000545bdc4c56f5d,0x0006676d4c0f8acf,0x0004038bbd0743d0,0x0000000000000001}}, +}, +{/* digit=74 [{1,2,3,..,}]*([2^296]*G) */ + {{0x0004fe80d04c169d,0x0001452da244cb71,0x000cda8b72206f04,0x0005887084ee9fa6,0x000920e111da7c3d,0x0003bb35ef1c2673,0x0008e61906e57c45,0x00073eebaa206a85,0x000dd3b5bf458238,0x00015dcf71c4a720,0x0000000000000001}, {0x000605cdd81e2955,0x000ac0e98756fb91,0x000f0286c4ccda7a,0x00017819b4372718,0x00031dae0a5d8a40,0x000720f8cb219351,0x0003217261dafa40,0x00006fb18c8c40e0,0x0003c7d483485194,0x000d46e02770cacd,0x0000000000000001}}, + {{0x000b16ebe5676f0c,0x0006e7f47e5b4652,0x00071c81701e6ae3,0x0007f8d6e3a4cc33,0x00067b29431c31ae,0x000869125faeb29c,0x000fd62e16be2afb,0x0004934ce6d0052c,0x000cd74901063882,0x0002e62b021800e1,0x0000000000000001}, {0x000a39e3523a9de5,0x00076121f34b3253,0x000d9c36b4aaa3b5,0x000b23992e0442ed,0x00023d2725144419,0x000ced8d6e4d3747,0x00011186d58a7080,0x00050cd63ed11b1f,0x000c6faa6d7a4d0b,0x0002559c897561f4,0x0000000000000001}}, + {{0x000657d806465325,0x00095fd29c362706,0x000e70b9e028365a,0x000fa40d084d6b18,0x0009d80bbbcfec68,0x000a06728aae56df,0x000361eb62533738,0x000dc77e1c92bd4a,0x0004fbeefd3c11b1,0x000cfba52dffafa9,0x0000000000000000}, {0x0009acb1f00a47f4,0x000024e668d3f2f1,0x000095d2d5d23cbf,0x00076b697f105b84,0x000da5b550d7489f,0x000c9d3a15e73345,0x00093e0d2b26a8fb,0x0001e4494adfd6a2,0x0008e6417e038745,0x000fb0b051833181,0x0000000000000001}}, + {{0x00013685fee3f167,0x00059193a123f397,0x000f28bae616ef5a,0x000d2c6567b33050,0x0004dae5b6596da7,0x000481adbd59fc9e,0x0002c1618dde4a40,0x0001f2a194682fe9,0x000c05bc15adc043,0x00013edb30fcceea,0x0000000000000001}, {0x00047d7a2900c6ea,0x000e954cf35b8dee,0x00074908606c425e,0x00094a88cdac359e,0x000fbef2c858622c,0x000d0f745810d20b,0x00041d71ca77f658,0x000782f59f1e4267,0x0004af36c640314c,0x000e35ec0709c829,0x0000000000000001}}, + {{0x000c5c739f094c18,0x000b75fcd89a8d55,0x00071a4d047c0dcd,0x000ef9a3d498ccfb,0x0008f669e7edb8ba,0x0008d6b13c20d8ae,0x000a564d16a48c79,0x000250d241703f4c,0x000680ef9509f9dc,0x000970b2c17a388c,0x0000000000000000}, {0x000778808942861e,0x0009abe8d8d33c23,0x0009bd2fb189dd26,0x000112581e8769b1,0x0009d657bacd662b,0x00084fbcaa8521c1,0x00091c546adc05d5,0x000c68fad3f4e938,0x00057bce78617aeb,0x000701e39a422608,0x0000000000000000}}, + {{0x000d79f624f8eb1a,0x0008e9c5d103b9cf,0x00071b65a5829554,0x00034991b8462f3d,0x000b51453c2b2409,0x000cf62fb341c087,0x0006cdb37eea50d1,0x00027ada571b02ab,0x0009e677d1b49b69,0x000004b52dc4d6da,0x0000000000000001}, {0x00042f171b839d5a,0x000765b6cceda32e,0x00009960889dbcc6,0x00040e8e2e336d9f,0x0001f34cefd7de54,0x0008bc6b5ab410a8,0x0000cbb91782d60d,0x000a95e22f3046d8,0x000775cf7c99291e,0x000282ca473be09e,0x0000000000000001}}, + {{0x000b6a03ba3e1ec6,0x0006b7fefa851ec2,0x0003a92f6680a7bf,0x00075deabf4905c0,0x00096ff483a6ae8a,0x000c163b2b784673,0x000be098999b6fbd,0x0009c4a535388968,0x000b8e919419a12c,0x000b0bd87c889640,0x0000000000000000}, {0x000f69e3681b9e47,0x0008fc5971b3c868,0x000bd601db453ea0,0x000aee960ff01a96,0x000a0347158b6a72,0x0008994151ef1dc3,0x0007de4b70d9ea4c,0x0005a29068423993,0x000e4276c73a1788,0x0008a834f8bee71a,0x0000000000000001}}, + {{0x00059366b70a0b8b,0x000d60abadb72457,0x00087caf5b975b84,0x000cc3f1983f793d,0x0002e94d8de541ce,0x00090b687cd8885c,0x0006b6cd952f2acf,0x000016cc05b6d504,0x000f97cdb266e5bb,0x0007c95959c78452,0x0000000000000000}, {0x0001e70e0efd1f63,0x000528c8989bfc93,0x000c244410e36663,0x000645d5f14f2667,0x0008cf8059cc8bca,0x000d2134f71c94e0,0x000ba7b1d1a84e91,0x000e21c35b983489,0x00003bfc5dddbab1,0x00099886156a8fa3,0x0000000000000000}}, +}, +{/* digit=75 [{1,2,3,..,}]*([2^300]*G) */ + {{0x00083fd796b1a72b,0x000c549640b910ec,0x0001f3c076c5166d,0x000b7e4e553ff932,0x000e97e2f7e676d2,0x000a2cdad5097c11,0x0004bc0c5cedff5a,0x000757d09eef397f,0x0007434958d95f66,0x0004eee32eada9e7,0x0000000000000001}, {0x00041f85b3f06836,0x0003aba0e3496ce6,0x0007931548ea6b77,0x000149273aecbf5b,0x0001858c42c5d2ef,0x000ddc70d91528b8,0x0008d341c157c1ef,0x000a690e10df0a32,0x00064f5d30760fd8,0x0000d14ec3b44ea3,0x0000000000000001}}, + {{0x00087f011572bb6c,0x0000d126f1e48db1,0x0000d05c4b7b6201,0x000a2ba1e0fbe5e8,0x0000224d802f13f0,0x000e0b8698189e96,0x0001b4bc0b8af43d,0x000c706b742b2859,0x000d9196336bf7ae,0x00007fec0d2fd363,0x0000000000000001}, {0x0000b0b6ce7179b1,0x0007cde982e3e244,0x000d814a6fad99d6,0x0007d3497edfbb4d,0x0007a46c6afc84ac,0x0004cd907a63bbd7,0x000909a18bcc3d68,0x000d756b5193f098,0x000f37ab5d6e0581,0x000ffb06adf4d102,0x0000000000000001}}, + {{0x0000415e4f4b1ce2,0x0002f16bd8544ce9,0x0003e7600d6c664d,0x000d9aa401912f05,0x000dd3e0c268e1e8,0x000f14013443dcda,0x000f59cbf936e212,0x0004b8aaec39252c,0x000d652c200b8cef,0x0000aac64c11e47e,0x0000000000000001}, {0x000c08e2e7a2dfe0,0x00048459176893a7,0x000c7c5a8f0afe8a,0x000e999b6f043d0d,0x00000b3c3cfd6e33,0x000b4fbc5e2a496c,0x000f5eee2690de5c,0x00073d2db4511dfa,0x000fecdd2743e927,0x0004f4ade6a1948b,0x0000000000000001}}, + {{0x000039609cadf211,0x000339488fdf258d,0x0000e39945a1e037,0x0009a8444d16fa60,0x000c454408c23f53,0x000ef729fbf7f8cc,0x0001fe369b8abc6b,0x00053dbd87a47666,0x0000f6266a890341,0x000de3c7b4bcd279,0x0000000000000000}, {0x00006e205ec9aa47,0x00063cce1af477a4,0x000f7fcf64572e77,0x000c931743d00999,0x0003902adccdc1f7,0x00041be26f8b87a1,0x00006779ffcb96f5,0x0001c0636264bb59,0x000484331c0db1d6,0x00076e5585c8ae19,0x0000000000000001}}, + {{0x0005899b377cc15c,0x000f315fff92e2e8,0x000a8cf599eb4a44,0x0002e4cfca1a3e87,0x0003f205f34e217a,0x0009eb1362e4f28f,0x00061c84aa7c205e,0x0006fa76515b6ace,0x00083aca37e55058,0x00030435e870f8ec,0x0000000000000000}, {0x00002203ed113de7,0x000655318327d42e,0x0005d903904004d9,0x00094adb7cd1d2f1,0x000ebca1242c89d2,0x000af2a1423b5bb4,0x00066f393818e824,0x00079a30444115e3,0x000183b2cd6a53de,0x00047bfd324d8249,0x0000000000000001}}, + {{0x0001ee196db2cf29,0x000718a1d049034d,0x000acaf386ae53d6,0x00006d746605e4e6,0x000c4458e136fcc3,0x000b7a1ac677dc40,0x0006ee4bb331955a,0x0007b95c386ed47f,0x0006640fb4384103,0x00081000a37bb752,0x0000000000000001}, {0x0008cc55b8f1bcdb,0x00025171d84cd78b,0x0001b8eb12ee7e03,0x000bd8c564c45f59,0x00076c2283df12d7,0x0008a36461b03bfc,0x0000c8cafd6fc812,0x000ae72b6275a058,0x000438282511c376,0x0008780ca3213fce,0x0000000000000000}}, + {{0x0002c0f6f353cadb,0x00056c17179cb81e,0x000af140db008101,0x0001bb5e63cd1fa8,0x000b0729533d8217,0x0006676827544c77,0x000fe1b0143af56f,0x00045a759df2599e,0x000962b593accffd,0x0007a3c61321e555,0x0000000000000001}, {0x000e58a6aa5358dc,0x000739bb4d42d566,0x000e6ef3760e0cfd,0x0004fb370620ef46,0x000c2253e0f9e680,0x000b5c8c64f4e9cd,0x00008daec6f6658c,0x000504153037a80d,0x000215b47cc959be,0x000e4e7aaaa8653d,0x0000000000000000}}, + {{0x0002bc233166381e,0x0000199700029af5,0x0003201dddf2a837,0x00085cdad02e2c74,0x0006daea6cd36d88,0x000c3f784e7e3512,0x000e882fa40cea6b,0x0001eec16a3a5130,0x000c43706ace2f12,0x0009ccf3c3a16a13,0x0000000000000000}, {0x00064823f9e7a6c2,0x0007bae8e4729ac9,0x0003fe54edfeed8d,0x000a4e7bcfba42bd,0x00039e917bf88ec6,0x00004163c606be20,0x00009b017d5a63a6,0x000c276869bd6bdf,0x00094144ff021410,0x000a13f038cdd94b,0x0000000000000000}}, +}, +{/* digit=76 [{1,2,3,..,}]*([2^304]*G) */ + {{0x0002f8bd1741a941,0x000d4f3177637189,0x00060a2c8b16c0b1,0x00012ea49a688a19,0x0004556eef3eca0d,0x0000c833814746c3,0x0008d8b842db71e9,0x000b1bf4ae9e3fdb,0x0000ee706bc576b9,0x00054e85a8de649e,0x0000000000000000}, {0x00032799b9f19edf,0x000975259805923c,0x00076f95241c4760,0x000d3b18d6c8d637,0x000fa677dee0ddd3,0x0002ad9334e5bcea,0x000ceb27ca464781,0x000594d56dac3990,0x000338deb39d6e55,0x00096c7a9d83d78e,0x0000000000000001}}, + {{0x000d7b49014b2147,0x000f134215e0ae52,0x00084df8cb33a781,0x000b10bfaf858985,0x00065449e13a9c3a,0x000859368bea1a4d,0x000d78c2c8134dfb,0x000ba7d94439b51f,0x0003f1c754b1e6f5,0x000d464cf5d47b00,0x0000000000000000}, {0x000c286403cdb3ba,0x000c15d6597a8e6d,0x000e5e853fbe3d2a,0x0004c9898bd192da,0x0003c76032d13f80,0x00038d5e8bdb66ee,0x0007ea1349bcb167,0x0001e4001679e16c,0x000f1f584d22ec20,0x0007b7d9f317a982,0x0000000000000001}}, + {{0x000196d862941c7f,0x00015fd4c9380d4d,0x0000a23a9cf4968a,0x00039223ad85ace8,0x000b20fbe77f6374,0x0003ae3be886de7e,0x000a36dd5eea175a,0x00061d0a78e19da4,0x000a64f9638a5733,0x00007bdb82dd1f3a,0x0000000000000000}, {0x0007fe74ebe49201,0x000a7702be0b4d0b,0x0000cad19bf2f6ec,0x000d6c0b5b514f13,0x000c08518708375c,0x00035c8f337b8d0b,0x00055fc06adb3974,0x00083bfc4b137fa3,0x00045b3d91207a07,0x0009d53cd23a6fdf,0x0000000000000000}}, + {{0x0000a67f092fe026,0x000e142efbca10ec,0x000cc433a343767e,0x000f6b9e68131944,0x000e836fcc884370,0x0005328231b4d1b5,0x000895d85b956e68,0x000117afd7ce3e4b,0x00028a48e23cd96a,0x0007756cbf1cc4fc,0x0000000000000001}, {0x000c45bb98d0ddee,0x0002774201b8565c,0x000b4f52020bec2c,0x000bda65cd76ab62,0x000ae2fb221ac3aa,0x0007ba962fd348e9,0x000e7c381d5e875b,0x00068ae119edacdd,0x000b495d57186eb9,0x00056fdf795bd0d5,0x0000000000000001}}, + {{0x0003ca5ab59ddb41,0x000f7f1ebc9c6cc7,0x000f57e85f634cbe,0x0005a16eddf122c7,0x000c8a63efc695ac,0x0003541555a07f9c,0x0002a4d80e98783f,0x0006230998aabf3c,0x0008cb24667129fc,0x0002de1b3b8ba86c,0x0000000000000000}, {0x00062aec0af56692,0x0007719a7045c1fc,0x0005b9718436f251,0x000c9b5d581f4e26,0x00069b5489f5725c,0x00051e7c1aa8e91e,0x00028ec256fe93ea,0x000487a680376ebe,0x00030e63df392cad,0x0009887cd96ae342,0x0000000000000001}}, + {{0x000e42367a9d725f,0x00039383477d80ab,0x0009bf84781ae655,0x000527eaf1389d3f,0x0004102ffac6350d,0x000a3b0583300052,0x0001cf3332af83e5,0x0006d633aac030a5,0x00033508c7e87b5f,0x00094e54cf554461,0x0000000000000000}, {0x000f352ebddfa61b,0x00025e3d5e304a79,0x000673478bec8a85,0x00072acfcd082890,0x000446528a7ef652,0x000120a7a607746b,0x000c8aaaa126f2d6,0x000e0714c411ed8d,0x000219322242ecc1,0x00076f4dd29b9909,0x0000000000000001}}, + {{0x000c19050d8003bd,0x0000966c18887790,0x000653ed598ed239,0x000bbd18179a89ab,0x00050e32e18d6ebb,0x0003a242275a6e33,0x000cf9fda141c240,0x000cba7fbc6f732a,0x0007d9042bdcaed5,0x0004cddd17f09749,0x0000000000000000}, {0x000dc494bed8e1aa,0x00072f9b4efbdcb4,0x000846e40ceacaf0,0x0008e7a08c964b79,0x000b697992c6dba0,0x000a31236d2a3b33,0x000f13c67e503cfa,0x000758371b2297ad,0x000a30fe4d1b0d5b,0x000937f2f3ba13a0,0x0000000000000000}}, + {{0x0001e3e792f54f5e,0x0002d66e1c349e9d,0x000411c782a7cb86,0x0004b067774f6f73,0x000f3d88b7029f91,0x0008ac9342be145f,0x000fba10730a2fc6,0x00017ace014c77dc,0x0006ebecfe34f062,0x000f04b7a85b9087,0x0000000000000001}, {0x000e45d39d99da4a,0x0006122af68cfe2b,0x000beab553aeda14,0x000338ecc8cf47bb,0x0007a9f26575d185,0x000dafc93ebcf570,0x0006b569b4f26152,0x000a1c5170968500,0x00059575a58e4408,0x000d43a451b6b327,0x0000000000000000}}, +}, +{/* digit=77 [{1,2,3,..,}]*([2^308]*G) */ + {{0x00031eea8652aa77,0x00075a9b33eda2b8,0x000ccb42fd2dd1ac,0x0005ab8fe55769fc,0x000ee2ea2c9e4a86,0x0008effb93c60208,0x0001522321dff3f2,0x000e5124fb782d6b,0x000f961e96e29dc3,0x000a6d2f39193c4c,0x0000000000000001}, {0x0005e63b7e317479,0x0009d667da851f03,0x0007183aa797e9f3,0x00059f9fe886c75f,0x000d96d9e68574aa,0x000ee25277706045,0x000aa94b18ceb8f2,0x000d5bc3971ae4bc,0x0007b608157fc8f0,0x000150dd6428487b,0x0000000000000000}}, + {{0x0003f45b89aa7776,0x00091f2af99e2d25,0x00076414d1e112b4,0x000800014a8e2b12,0x000ffa17691a71c3,0x000bd4233ab0f6f9,0x000bd49cf4e764a4,0x0004012735f0ccb8,0x000037d3dc7fc071,0x000ae03da811ddf6,0x0000000000000000}, {0x0004a8fb960d3228,0x00048eb39e1a42f2,0x00007ea05b5a3c40,0x000b7bd9d581bb93,0x0008feeb6ce36fa0,0x0000329bb28b7b8d,0x000e608fcc8cab6a,0x000504c03b085c44,0x000593cce3f2c4c9,0x00093bb2ef5a3d51,0x0000000000000001}}, + {{0x0005eee4a29b9e00,0x000dc20740482d3d,0x000e9ca5a465e210,0x000dbcf9b04be3f8,0x000cf79a10d11c21,0x00098890d16c757a,0x000df4eccacfdb2e,0x000f11b8ece9836e,0x000bc4d7a9a35695,0x0009ee2c9b7d003b,0x0000000000000000}, {0x000e2dd26ff13203,0x000133cc51c6bc72,0x0009ca679c2a2da6,0x000951011dc4426e,0x00093bedba6ea308,0x00088d9217c2a099,0x0000e9979694eb83,0x000d521e97150620,0x000035d356c66be4,0x000161e2cef90abf,0x0000000000000001}}, + {{0x0002a5d7a2fe5424,0x000c5abd77fdcc05,0x0007ae8084591e67,0x0006481030c17511,0x0001f92e55b534fb,0x0006bd1eba6c21b3,0x00096514d056aef9,0x000df597cfd93bd8,0x000c4de2939ce9f5,0x0004ef6737cbaf10,0x0000000000000001}, {0x0006ccf17f5b4aa6,0x00049ba070d7b272,0x00033084cb0ef8a2,0x00018fa7fece71d7,0x000e7f11b328ddbf,0x000b8c5b898e7f8f,0x000699bc5842d33d,0x000944b7141938ef,0x00039a13d619477d,0x000d5228db36f5cd,0x0000000000000001}}, + {{0x000b8747f420dd4b,0x000fb52bb177eca6,0x000f43dcaa9b6760,0x0007a3f15a0ec05a,0x000736800fc5d305,0x000bb74572a151d8,0x00065a96cf22ff7d,0x00019519394cd42f,0x0008227699f90840,0x00068419e24fe2e2,0x0000000000000000}, {0x00025578363927ed,0x000574db66d688d6,0x000d409ddc1459fb,0x0007f82b70d69f87,0x000cb67c0931340b,0x000a17e9ba495398,0x00095f5bb6fc86af,0x000372330a201b0b,0x0002bfb684331f96,0x000759b31f0fa4ba,0x0000000000000001}}, + {{0x0008a9686e50ea9a,0x000fa53caf16bb29,0x0001e6775d854b08,0x00037450aecb3742,0x000a7e3971ac67a8,0x000916720ee3a053,0x0007ef527af5a2ad,0x0008c78907d26a51,0x0000187ff88dddeb,0x000580501085ffc1,0x0000000000000000}, {0x000bd54c631b5ef7,0x0000a533ff81bdf1,0x0000234fa962cf5c,0x000a7f99121d8411,0x0004d769fb90a1f3,0x0005f3f42e621b7c,0x0007e5f02655798a,0x000d995fc9fe9a95,0x000560ed712fc645,0x00059000f20fc194,0x0000000000000001}}, + {{0x000ca8aff309b100,0x0000c85dcacc4c44,0x000282732cee9318,0x000efc73a9f020ed,0x00070ac2ec46ccda,0x0004edd612a22d61,0x000fb7673b4cf6d2,0x0000510828deb00f,0x000a061d4c49e843,0x00016c8aea6c342b,0x0000000000000000}, {0x000ffaa28b87e79b,0x0001bb9617a5663f,0x00097f1ba9e99062,0x0002ee20742a4b1f,0x0000500e34cdf43b,0x0002b6de4ad6c0ab,0x00002eba08ef6f81,0x0004e0bbfd3a6364,0x00094460899a3582,0x0008335d3e07b17d,0x0000000000000001}}, + {{0x0005a71e395d239e,0x00026a160db974ae,0x0004df55ba5b2671,0x00091fe0f2bfd214,0x00027e4215d39cf2,0x000849498b3dc0a6,0x0000c7dfec311ed8,0x00029fbb50995b22,0x0005f9ca4a3d83cc,0x00085332f62dd6c5,0x0000000000000001}, {0x0003278db69ec48f,0x000c56caebf5d4e7,0x000e4ab979b38b01,0x00005e1e7e210f66,0x000e800e35bf7fe3,0x00041625bdbbd247,0x000140764eabbcaf,0x000ae49d3fb6b3c0,0x000bed09dc31a840,0x00044a6c67185e6e,0x0000000000000000}}, +}, +{/* digit=78 [{1,2,3,..,}]*([2^312]*G) */ + {{0x000976185cedb78e,0x00000d5ac29ab973,0x0005376ef5010492,0x000fcfdeb7cabe96,0x000e82ebeaa6eb29,0x000856863e849702,0x0002b7dd5820c1d9,0x00080b85b8b6adb3,0x000cc2bebcb2a1da,0x0001cb911240a24e,0x0000000000000001}, {0x0009339d66471f42,0x00086865738f288e,0x000ec9ab31ac9389,0x0006dfc0b78b477c,0x000d22531d4c9b75,0x000957b1f72bea7b,0x000f90819668750a,0x000023544082b7ac,0x00010dd35fa97aa9,0x0000657c9376d4d3,0x0000000000000001}}, + {{0x000d393a7e12c9a1,0x00087315af1e7695,0x0005dad48c909f6c,0x00065a7e168b010a,0x00026d86fdc5603c,0x0008f52d5373f51c,0x000a497697c8b7d8,0x0006670982debc64,0x0009f942aaf7a067,0x0000beb15cc57a80,0x0000000000000000}, {0x000728397fd456a4,0x000c8ff5563ef971,0x0004e73a2dd305f3,0x000cc516a80ae4a1,0x000352258160b828,0x00008533e6e74db7,0x000028314ad68011,0x0007541598a03b32,0x000c3d815763ab10,0x000089f632644f56,0x0000000000000001}}, + {{0x00096953520ee092,0x000306d200f67521,0x0008a20dfb41aa95,0x000ecbdc450070d5,0x00044a73c2aa2e56,0x000cf15e09936979,0x00039822bf1cc5f8,0x000ba98dee98b81e,0x00049763f39d2614,0x000dce88bf80d042,0x0000000000000001}, {0x00090be494194f3d,0x00009eeb5f7526ea,0x00042892f629d76e,0x000de6b9665e7661,0x000e4db45bef0dd2,0x000f0c29ede66edd,0x000cdcbd947a3fe0,0x0009dc0bb66739bc,0x000aa185f9760092,0x000d98f355b62fee,0x0000000000000000}}, + {{0x00095d178d8fc8db,0x00088ab909e6143a,0x00089b7600c18603,0x0000f4aa942112c1,0x0008b5a1967f7a08,0x0003543a0e5057c0,0x000cafbf9ac78fd1,0x00049408a20a1598,0x000b58bcdfa7974b,0x00036217ad4e198f,0x0000000000000000}, {0x000138c5bd603cb6,0x00072af896026457,0x000ea9d78b2185f1,0x000482318652917b,0x0008b9b757159621,0x000f2c7ae3b7470a,0x000d10f532d77474,0x000d6b40b8bfc96f,0x0004da23277081db,0x0005192cd44f13a5,0x0000000000000001}}, + {{0x000210b018203491,0x00081f7f56d37ef1,0x0003499eb28c2bde,0x000d16d800ddf3bd,0x0001a8ad11d2638e,0x00081f6ac5a19953,0x00073cbdac06d819,0x00089e5df343701d,0x00080e56132b9d88,0x0008f82b847a3187,0x0000000000000001}, {0x000ae2fb5a3b782f,0x000dfec66b9766a4,0x0003802b7f84c2ba,0x0002adc75633f423,0x0009ba300fd1c729,0x000a85bdc16e7491,0x000bea7ecdc049f9,0x0008cba7fd0e8182,0x000a5a9aa8bce3aa,0x00008a0977d90d48,0x0000000000000000}}, + {{0x000ee51072d71e54,0x000e9e2a68ca9bef,0x000a9707bfc11ef4,0x000ae91635e6d8f0,0x000dd87435cc0e00,0x0002d6a89b217b9e,0x000c5bada1452b8b,0x000d602de29b175c,0x0003f43b9bd73fb3,0x0000724373642133,0x0000000000000000}, {0x0002c3dc04031002,0x000c73ba54808162,0x00084fe7d46fa018,0x000e61eb44ff91a6,0x000448f89778fb3a,0x000d0dc5c96379eb,0x000f26ee0588d9eb,0x000aafd623f750bb,0x000b6e0aafb4a855,0x000ab06c0e1eab53,0x0000000000000001}}, + {{0x0001292993c3f0c9,0x0009243ce8e0477f,0x00002cd6d125a6a7,0x000424b8f8d2f4dd,0x0000e036966f98b0,0x000b28d9609c6ed4,0x0006f54dde908ae8,0x0001261395876628,0x0001a89f477ea392,0x000b89a6253dab22,0x0000000000000001}, {0x0000776cda9e2906,0x0004dd51a83a13fd,0x00024cb69c0833d7,0x000afa9f2d0d7515,0x000d5068104d274c,0x000b1536c256cfc3,0x00005c2c5a3bb4ea,0x000e695b252297e0,0x000674ad5032178b,0x0007afaaac5118a0,0x0000000000000000}}, + {{0x000b5f87444140a9,0x00070937761e89c1,0x000052402d8c768e,0x000e0d8fa7063fcc,0x000065032ca28437,0x0000560b81d70497,0x000a63bfcc5af72e,0x0007abb68cfddac1,0x0007b3b85e89f391,0x000e3880d7454a25,0x0000000000000001}, {0x0001d4cbebc9cca5,0x00014fe965181800,0x00064d65a9766b10,0x000646ec511b3639,0x000cc26e7c4e0d56,0x00094ae11adfae8d,0x0001a6886e8d406a,0x000547bbf4ad6e9a,0x000e8901b3004a68,0x000c8d5981c48013,0x0000000000000001}}, +}, +{/* digit=79 [{1,2,3,..,}]*([2^316]*G) */ + {{0x0003223ffb7f0034,0x00056eeed01f7ec6,0x000a95759d3b10c6,0x0008fe9fc8ceacdd,0x00036b6ab8ec35f6,0x0008c0b21550e979,0x0008e1de4ccc3b92,0x0007fc6be17e92be,0x0001bdb6320828c7,0x0009d213352a78b8,0x0000000000000001}, {0x0009b3c1ecfa9e13,0x000b3a0b5daa423d,0x0006bf95aa594567,0x000fbfb5a3d149d4,0x0003d4e9979588d0,0x0001e08ca45e636b,0x0005c358fa3b11bc,0x0003552e11b17364,0x000b67bc8931ab99,0x0002d3ce614c5f0d,0x0000000000000000}}, + {{0x000ed714844f3544,0x000cc4bb9010843a,0x000996ac0026321b,0x0003453553c74ad5,0x00041741982c7cb6,0x000196d8fedc48a0,0x00020d244c9f0921,0x00070a8fce97fabc,0x000a6d44732828d2,0x00060bcab0c77562,0x0000000000000001}, {0x00061da3943969d2,0x000d674b749d7b3a,0x0009df6dae1fb5b6,0x00005c30ec275083,0x000ae7da1a9284fd,0x000c82a28eb7bd6d,0x000a71d66cd19bae,0x0002d599b2c6a08c,0x000faa1546c312c5,0x0007f06795e3065b,0x0000000000000001}}, + {{0x000fff9188aa7d8c,0x000deb80ad064a0a,0x0007114ab9689af5,0x000fad0b4dbde778,0x00055fd29cd3c099,0x000d379d42525d60,0x00016d04df50e85b,0x00053602e006dfc1,0x000e6c63f374d96b,0x0000f26509a7f32e,0x0000000000000000}, {0x000822c176aa9790,0x000f58fc039cb1ee,0x0005872cad56c2fd,0x000e8ae0ea665324,0x0004daf2e64bf3b9,0x0008f96bb4b8314c,0x00090e063c57f41a,0x000d5149d3063df9,0x000ba61281d5f9b0,0x0004ba3d6cc9c608,0x0000000000000000}}, + {{0x0005d4a76da49005,0x000c3b224e91125c,0x00062ab184a74621,0x000b682a17406495,0x00053c3f7c8cdedf,0x0008e38d4416ae20,0x0009c28df044060d,0x000f86143e5739ed,0x00095f9f7f327b97,0x000872538531478b,0x0000000000000000}, {0x000b98e468155010,0x0001fc05661b3943,0x0009ee23198c1bcc,0x000744fc64ff1647,0x000560f20d871115,0x0002c9feeacdf5ac,0x00070b263cba9c39,0x000badbac8fda72f,0x0001aad35365c71d,0x0002f99d51687d17,0x0000000000000000}}, + {{0x000acd4ec9302acf,0x00046876812a6969,0x00062f921abd47ef,0x00030834c8ee3434,0x00087c08c033bb79,0x000e51d0a2369c3e,0x000c1fbd98cac8fe,0x0006a309b704c675,0x000a173a43fcbb3c,0x00009432c4949569,0x0000000000000000}, {0x0005e781f2ef36de,0x000e3479bd3a702b,0x000d74e86eb68837,0x0003849622881aa5,0x000ba91b89a84ecb,0x000caeee87dd2964,0x0000f40b0230b757,0x000e7853cadc83a1,0x0005f5ad1465657a,0x000e75100e5033e4,0x0000000000000000}}, + {{0x000e44f3911651e4,0x00088f7f22b492d2,0x00072f850dbf1662,0x0003ab2a45a14853,0x000e1480b82ee674,0x000ca609c8235a84,0x00085d8422668b9b,0x000a5d6f0bf02f4e,0x000afb880792321d,0x000cb82c095f0261,0x0000000000000000}, {0x000bc2f5725cea9c,0x000e1f43f99381e6,0x000e6089c844a832,0x00000aa951ad7011,0x000282a695207656,0x00007e689c114477,0x0000e537bb9a4c6a,0x0009df06eaf0cd7b,0x0007c474d7895232,0x000f0710d2b00b77,0x0000000000000001}}, + {{0x00093c8e0aebae92,0x0001a4248ef98180,0x0005353d71384b97,0x000564228ab8dd10,0x000ee9e95615cf3f,0x000dbed91f163427,0x000ff8c7cd8d83e1,0x00002a117b26a05b,0x000d651309094b7c,0x0005fa8d73f3a728,0x0000000000000001}, {0x00045cf4f3fc6c29,0x00069a5dd01b3bfb,0x000e3b24278a983b,0x000ba6e8dda15e64,0x0007ceabdafeb0be,0x00028dd1f4ce3cbe,0x00083c003c3a01ee,0x0004286b68f03154,0x0003661bd44cc13c,0x0006d7a5a2b18a65,0x0000000000000001}}, + {{0x000f4f2d2f859a83,0x000584cf466ff03e,0x00078dc82b847044,0x000110dcb52d320e,0x0007adfe140d78b5,0x000b45fd46e07b11,0x000943939af65810,0x000f26b6d5c5bda1,0x00091095a8309f53,0x0000d4aad23c7d80,0x0000000000000000}, {0x000dd82bca9e7ca1,0x0001551ee78b6090,0x000453fc776839c5,0x0001d0262966b875,0x000729e2a29966bf,0x0008c49cfc825d3c,0x00009961345ab1d4,0x00007e6049f3ad60,0x000007da4f1b3985,0x000c382c8f36cb0b,0x0000000000000000}}, +}, +{/* digit=80 [{1,2,3,..,}]*([2^320]*G) */ + {{0x000a284c690646dd,0x0003eedcd5cc91eb,0x000ea471fd6292fa,0x00023a125841cc32,0x0002e35810a749fb,0x00061336484e18eb,0x000b6f65228a2bfd,0x000207542e7452ca,0x000526cd940c7469,0x000d2936b9b32962,0x0000000000000001}, {0x000573e4f063ef2a,0x000418ca996c2a17,0x00033e1f9c1c3d42,0x000b3cbf970fbd47,0x000088c0b1561246,0x0006e93234f08535,0x0009d7f8ff901881,0x0000aa556f8574d9,0x000a5d989d3b1d29,0x000ed0ab78218edd,0x0000000000000000}}, + {{0x000233d6557077d6,0x000f2b32cea9ff87,0x0006963e65db1454,0x000b05b7d5f2627e,0x0005a68cad15bd15,0x0009679cfef2c921,0x000cc1f982da4ecf,0x000673910763dd21,0x000110fdc3925aff,0x000a3cad0858b1ce,0x0000000000000000}, {0x0000c51bfdb7b566,0x000e8b88f58f7516,0x000713a7cf39e39e,0x0004ac365af813ed,0x00040a788e43e8ac,0x00010b5e01e789c0,0x000ddf33d0cb49ec,0x000a3f2d9bd726fd,0x0006e3c30504e525,0x000e51a456acdf77,0x0000000000000000}}, + {{0x000707d7da6499d4,0x000c004b6d85bc23,0x0004b483dd72372e,0x000b15c9838f63c9,0x000dd40b6584e869,0x0005bb5ad6291644,0x00069be693ec1c90,0x0007b5c6018dc109,0x000c9c113b81150c,0x00040bbd460de804,0x0000000000000001}, {0x000d558a1b81757d,0x00046da356589b5a,0x000f093ea9cf88e0,0x000cd54eede9de0f,0x0001f19ec3f8839a,0x0004ec243ffcbf45,0x000d0d1f8b02c0e4,0x000a42d2cc07981f,0x000363b43f4701bc,0x0007f930f2e9e43f,0x0000000000000001}}, + {{0x0006b0772d9f5845,0x000f28a8c7c3d700,0x000c1d96b231ba3f,0x0000f432c17a4f5f,0x00014ca88f653da5,0x0001ac5da9fce5ef,0x000105dd10257bb3,0x000206b910de18d3,0x000d121d64f95008,0x000e83748b9a298e,0x0000000000000001}, {0x000dc94560ad3e4a,0x000b34cda193affe,0x000f39dff5030add,0x000d72c1a3a58a0d,0x0001ad7c02e84586,0x0006dddddd7190f7,0x000431dd7f7815ab,0x0001b059af2893fd,0x0006d66ebdb90a30,0x000ac5b55b254562,0x0000000000000001}}, + {{0x000a7032755a2cc5,0x00087b60173b4c02,0x000853a0c8b700e1,0x000d3fcbebfa5d41,0x000106636a248a74,0x000d439df17f1529,0x0001a48433bf866c,0x000ed52b92a93d36,0x000de5dbf96508fc,0x00064c08fb48dbcd,0x0000000000000001}, {0x000e6d70757d607d,0x00099aa287bad741,0x000aca83d8bc1d01,0x000a6deb3248272c,0x0006281490886dee,0x00003b3e7ed5830e,0x000b8f50b5515018,0x000ee61ae410329b,0x000dd209b1b1ec67,0x0009f79d8f057d2a,0x0000000000000001}}, + {{0x0009240ac4aeeb4f,0x0009de701cba0d15,0x0001e2030d5be49e,0x000f5b9fa8d80ea6,0x0009e389aa0a7891,0x000f08f46a281d5c,0x0003d8942c2a6a9b,0x000dcae5c6263013,0x0006ed6f226d80fb,0x000e7cd744527397,0x0000000000000000}, {0x00064112eebe5a16,0x0005561ba10f054b,0x000076de3983c715,0x000338a0051c721c,0x00017ed93ec2b1b6,0x00040d08e30b18e6,0x00086d02546a805e,0x000b289546bf39d9,0x00029a40d87fe36c,0x00003828ca6d96cb,0x0000000000000000}}, + {{0x000888aaaf08b61b,0x0004baeb89b8a3b8,0x00013c31ce0504b2,0x000084891577d88f,0x0001501541da01d3,0x000be18906c31edb,0x000cf8acb88a0c0f,0x000de0a54814b123,0x000d30b10ce17eb8,0x0003c65435ad1112,0x0000000000000001}, {0x0003c3081d6e0b2e,0x000bd1198cbd6e7a,0x0009feff60218481,0x0009559a8a4e33b7,0x000ae242155d34dc,0x000458dbdb49b265,0x0003688660033750,0x000853753ede19c3,0x000b6969aac09e0c,0x000a5225b275670e,0x0000000000000001}}, + {{0x0004c030e13db910,0x000b8e4bb182d8fd,0x00024d5733c45ba7,0x000e09929bbae322,0x000c5e18395c5857,0x000beb34317a4b7e,0x00065979d2ffacfb,0x00000dac7ff47099,0x0002ac181634b33c,0x000b325a113dabd2,0x0000000000000000}, {0x000f6d0b44a18451,0x000ebd4b60b5e31a,0x0007c6c236a60067,0x000b1be8ccf47b3d,0x000a21dbd1cc7199,0x0004932466e888eb,0x0001dee034c21f8b,0x000ff9da169619ff,0x0007e95c7e040c95,0x000b5a9dbe56efee,0x0000000000000000}}, +}, +{/* digit=81 [{1,2,3,..,}]*([2^324]*G) */ + {{0x0008f08161486b22,0x000be755ab4efe68,0x00048d9609c012b1,0x00098843db068e78,0x0002d958488ad0fb,0x0003f6d23cff5eda,0x000c41d3ec7372a8,0x00035d185ec0b176,0x0006314a5925e490,0x000a3de4ff957947,0x0000000000000000}, {0x00029cc94c1b43aa,0x000d43d2ad417dd5,0x000360ab4fa2dfe7,0x000e9eb552cc454d,0x00035a4732c24fb2,0x0008d1e843cf82a2,0x000ab8e67bb7a406,0x000191877eafbca2,0x000574ab099566cd,0x0009f922f9872f62,0x0000000000000000}}, + {{0x00085f8208bbe4fe,0x000ecc287db7bb2d,0x000e568667e702fb,0x000cbeb7a157f36d,0x000bf484f3352f4e,0x00058da014941bbf,0x000586c3d5fe38d5,0x000a8a8ef1b37b22,0x0005949627a9e7fe,0x0004740c422ebeba,0x0000000000000000}, {0x000c2ec0fe63724c,0x000be0eb88269034,0x00016f607ed8c7ff,0x000b235b0a729f09,0x000b2fb783d219ca,0x000a1f91a0e85a3b,0x000f36eaf1659ef7,0x00023c3d4be9067e,0x0005e5bd92b43e99,0x0001e3e81391aa3b,0x0000000000000000}}, + {{0x000cdab06c0f497a,0x000ba682d62fd58a,0x000624d8816a960e,0x0006c48669b75099,0x0001fb169d6d2670,0x0009d5b924784941,0x000361b9811c3888,0x00005ccc21278392,0x000173173a0f5de5,0x000862da0030f596,0x0000000000000000}, {0x000580503b5bd1a6,0x000460a53f77d734,0x0009ac0fc516703a,0x000cc1b1f0c1292d,0x000599d98d3204b9,0x000365fabf012bdb,0x0001f82c240390bf,0x0007f3c05cb807a9,0x0001aacb4486b03f,0x0002d4bf3cd7e64a,0x0000000000000000}}, + {{0x000cf4fb66902a59,0x0006522d970cf058,0x0008db985646108b,0x0005bd091c524ec7,0x0001c8ded01bac37,0x000a7571d5eaf41a,0x0003ae41513bf75c,0x0000831a58ce8343,0x000b5c1d0b1cbad6,0x000a127e3558b4d4,0x0000000000000001}, {0x000c5bcaa2423577,0x000e95cd90416c5f,0x000f9cd3e851fd11,0x00043cec77429d71,0x00033818263e74b1,0x000b0bed2ab694e3,0x0009d3b078fef207,0x000322c62d90900d,0x00013057fb2dcc39,0x000b0aee2cd8c7f7,0x0000000000000001}}, + {{0x000ca837cf1af373,0x0003ae0bc7638546,0x0005fbd88b9c057e,0x0000f14623993437,0x000d8418b02866d1,0x000938602b2a7398,0x000d172bab8e8fb6,0x00001960cc17eb57,0x0000f437b4d86f8d,0x0000c3266073d8a3,0x0000000000000001}, {0x000b4a64de3a3170,0x000d07d300586858,0x000590b48d2c8237,0x00064608c48f8521,0x00055a4fad372745,0x000ad1664c3cb9d0,0x0000e5148678bfbc,0x000ce1f67995bdb9,0x0000ce6b82ba0137,0x000865e65d5e9060,0x0000000000000001}}, + {{0x000a3697b62e274a,0x0004f036666b6cc6,0x0004615de0a77111,0x000d1a544656bc00,0x0004cfe1b0ffd27e,0x0007b011fe7a367a,0x000028f9395287ba,0x0000e474d2cd1539,0x000df81c967ab663,0x000809d416f7d850,0x0000000000000000}, {0x0004ff0171522411,0x000cb614e9eb99cd,0x000efe5013168ce9,0x00000068878690dc,0x0003ea58b25b4f05,0x000697bfbefe708a,0x00061484cbc18871,0x000fd61b572d109e,0x000507a67ea6e538,0x000c108cf0642bcd,0x0000000000000000}}, + {{0x00073712d28f1037,0x000dcbb85bee07b2,0x0002d427b383b0b0,0x000886a4c921569c,0x000a22bb54a08b63,0x00016efd18019f62,0x000be30e896a901a,0x000b1c79b63790d0,0x0007550d4ad3f339,0x000c014ebb2a7324,0x0000000000000000}, {0x0000eb80b7360646,0x0004292a8064819e,0x0001aa8d66966eba,0x000cb5433c6786ce,0x000c176010116f6a,0x00042b7f40b26c85,0x000bb51bb431c00e,0x00079fd699bb4a71,0x00083711f2c2acd8,0x0008a64b1e3905a7,0x0000000000000000}}, + {{0x0004f281744c4f31,0x000fb974f0427525,0x00022ee390de534c,0x000caed9f368e25e,0x000470d3f5a1ebc4,0x0006bb7427d70104,0x000830891f024042,0x0006993cd5f37f0d,0x000a9d89f4ebe578,0x000c7b2549a02c1b,0x0000000000000000}, {0x0005527d2ef3c160,0x000aa733afd2d857,0x000200435a36240e,0x000dbed50df72a8e,0x00064e9f3dcc7104,0x00084041401f5c34,0x000b281791b398c9,0x000ad77cd49e1581,0x00029530ca203aa2,0x00024a7004073823,0x0000000000000000}}, +}, +{/* digit=82 [{1,2,3,..,}]*([2^328]*G) */ + {{0x0004b896de83f7b2,0x000dd1b2e000727a,0x000d43d965547a68,0x000c1f1e1ce79a50,0x000e5ec87252c6ab,0x00060d6a5ae7160f,0x000985fdcf45caab,0x00091b3180d9d235,0x000646ab8f898256,0x0009f0446d6798dc,0x0000000000000000}, {0x000ec719b8387586,0x0001de5f9db6636e,0x00038f4a187cc943,0x000ac366ef383b03,0x000022fa366743db,0x000760fac1cc0b0d,0x000265067948b1b5,0x000693934495e8d4,0x000c64b8f4f88921,0x0005281cd8ec2ed3,0x0000000000000001}}, + {{0x0008479d81fdc38a,0x00096a893e0d1c8a,0x000972cecee045ea,0x0000ed0b37445b26,0x000bf1c0a16a9b25,0x000509c76808e477,0x00070c4c826b6837,0x0008008a3f9fb748,0x00088d0f74d58040,0x00063d18d474fc4b,0x0000000000000000}, {0x000a143fb2178ecd,0x000ee2726dcabd2f,0x000e017d3cb36d39,0x000d77e2d8d9e011,0x00069332c865043b,0x000231a13fc89650,0x000e078f7a775c43,0x0002e93c91cf1e3d,0x000d48604e0f7c89,0x00031d2709749250,0x0000000000000001}}, + {{0x0006fca2f24da625,0x000adeacc535625c,0x00020bfcd99308f2,0x000732872a2697fb,0x0007578b9abdd39d,0x000d7e3c3e30d29a,0x000dc63c314955de,0x0002de0cf2a14e6d,0x0002e4f4d6b0bbff,0x0008423dc75d4cf8,0x0000000000000001}, {0x000dc6563086abd4,0x0007f2e300951d8c,0x000a989054197751,0x000a88edbb68daee,0x000ee17db6bcc0fa,0x000d996d71fcc36f,0x00038a1dafea4a84,0x000fc8d72ef68c32,0x000c6b07cf974baf,0x000b2a140ef1e1e5,0x0000000000000001}}, + {{0x0006034713a3e42b,0x00008cfb50e4479e,0x000f617634a25363,0x000ba17f9549272f,0x000163e264556302,0x000db056ef0f6ed9,0x0009449c67d2e92d,0x00027bf608bef04b,0x000a41494e0fd2d6,0x000ecafaa0f9ad5b,0x0000000000000001}, {0x0000394a908a0374,0x0002739ed3e6c1ac,0x0002bf950e49017e,0x0006ca69441c9b0d,0x0003c717b7978985,0x0006f1bf123315b5,0x000d5ffc5bce1316,0x0000f7b0dacbdc85,0x0005306a73236570,0x0000fc22ce0f19f8,0x0000000000000000}}, + {{0x000a6e6af09b8eae,0x000343b43c513568,0x0003425270500040,0x000fb4508580e8a3,0x000b307fa3d1f99e,0x000113638a6f65cd,0x000be36db7f5ca63,0x000ede447eb7ec8b,0x00022e6ed48cec2c,0x0007bb1afd7c927f,0x0000000000000000}, {0x000c11f9a334fdc7,0x00026ae8011e9b06,0x000ba4fc7ee152d9,0x0005ebe2d92b45f4,0x000643466d3d6908,0x000a09e637a743ca,0x000aba719664e4ce,0x0003162cc6d5e41c,0x00060cdf202e7dd3,0x000c307d09d0c5c7,0x0000000000000001}}, + {{0x000b621fceac0c99,0x000cd9f0c6398393,0x000246af19db94f8,0x000def03f4511189,0x0007e278282d9eea,0x0005d51872d67451,0x00069251c97cb275,0x000152306520f8d9,0x000f0746e9696ce9,0x0009ec26638c1b12,0x0000000000000000}, {0x0006fbb28d6db318,0x000282f1e3fd8169,0x0001638aa745ba97,0x000741cbd6f6afe6,0x000674be06f9a37c,0x000f0e4d5ef37aa1,0x000c66c847151102,0x00086ff305cd0c0a,0x000dec0bec87dfaa,0x0006e29a33525521,0x0000000000000000}}, + {{0x0009e94294764d17,0x0002085b396e5ed1,0x000a114f1c4a72c2,0x0007528c8545f538,0x000963b0d0aaa085,0x0000ee6c82fe930c,0x0009cc321991f876,0x000bfd79b22e04e6,0x000e404e5103af68,0x0009a8126bf818d5,0x0000000000000000}, {0x0006f18c56b9245c,0x000be8cf2d749759,0x000d0534792607af,0x000737082c9ac67b,0x000b81d246c242f3,0x0004a1675a873285,0x000b8be65c0f0c83,0x00031f4367aaf8a7,0x000eeb7fdd2c4760,0x000b71b7bc940b35,0x0000000000000000}}, + {{0x000e474b29bda866,0x000e2b3a2640ed4a,0x00021f91da93684d,0x0005df67424bab62,0x000b550d60209995,0x00096c99d55193b4,0x0003c748e9f27481,0x000631e6b3fe7e7f,0x000f47f4e257248f,0x000f8f56db9ba373,0x0000000000000000}, {0x000bc357ebc4dd12,0x0003a33556892c48,0x000b72124cffa435,0x000e35056ea40bee,0x000a1b37aa3c71db,0x000ddc96c72e951c,0x000291c71de6fcaa,0x000ff88244eb58ae,0x00089a7bf96fd42a,0x000eb41c5d8ae97e,0x0000000000000001}}, +}, +{/* digit=83 [{1,2,3,..,}]*([2^332]*G) */ + {{0x0008ac7511fc1235,0x0005af51e9a589c7,0x000c09d63e56a5f8,0x00055b518ce24a89,0x000a75441652a9b6,0x0004ffab489b445d,0x00071289523b0e9f,0x000290aaf7cb23e7,0x000c9bc7899234af,0x0001dda65dc198b5,0x0000000000000000}, {0x000eeaccabd5a6f7,0x000d5900e72c44fa,0x00047a63782a2bbb,0x000393bbf531aecb,0x00009c7dda45067c,0x000719fa6f31630b,0x000f3a0c95e46b2e,0x0004deaf5d70f849,0x0007dd5d46829965,0x00096c286bc1f082,0x0000000000000001}}, + {{0x00012d5838ca6af1,0x000964e9241a8a04,0x00024077ab2ac6aa,0x00089da3e1536c1d,0x00001df56af4aad1,0x0006ef9e57fbfb6e,0x000b17f8ca8e6244,0x0009cbcb351a7c9e,0x00085fb54f3eda4f,0x000c296970873909,0x0000000000000000}, {0x00056d8d32e5fdd1,0x0006814d7980be46,0x00065dbc6a68d7ed,0x000cebebe9b6528d,0x000269dfcc27d433,0x00073aec8225c88d,0x000d90643f7caaf2,0x00041c78327e8662,0x000763fdae4a09eb,0x000b0ead9bd2f604,0x0000000000000000}}, + {{0x0008f42a8c29bd6f,0x0001879cf21db610,0x000555cfe2bddcfd,0x0004d452af269c11,0x000fcc4011856e7b,0x000e6e45593cb7c3,0x000b215415957c0f,0x000d3b983b2c8996,0x00012f953be5cf31,0x000f7078abc3a003,0x0000000000000001}, {0x0002c0d6b39b80ab,0x0007b2847e724ed5,0x000cfdfc83942bcb,0x000c1c0a2ddac314,0x0001da690e67e2aa,0x000310507c60736a,0x0008b8515f2f407e,0x000203447dd4a30b,0x000208fe5f3ddc7c,0x000470482e113587,0x0000000000000001}}, + {{0x000d7682eb5538d3,0x00058bd8734ac8b7,0x00075fcdec6d3223,0x000ffc3556d9d86e,0x0003a6c363b61e72,0x000d03c2ead1066f,0x00074fd7095dbd73,0x0002b42f9972cd16,0x00070acc2acc3e68,0x0006fd80c7114993,0x0000000000000001}, {0x00049c09589c235f,0x000294e10709485a,0x000e55bcaedd0d2a,0x00084da3a073e38c,0x0004725346561d28,0x000ed8195e95d347,0x00001ec990b2c19b,0x000817664aecefe7,0x0005f12464c59ce8,0x000f85a23cc1c6cb,0x0000000000000000}}, + {{0x000fb48cd5b9dd85,0x000ea5640b16ec8e,0x0004991733d00d1c,0x000e2230142b823b,0x000d1646ff2bfccb,0x000e87a4efbbe898,0x0007933417bfbbcd,0x0002ac0c744278e4,0x00079c8483d8b4b3,0x000fafae62ecea8b,0x0000000000000001}, {0x00063d47c065003b,0x0004185cb3cef55d,0x000bfcfe8d3872f3,0x0009112c490c5e61,0x0003b1e7d4274313,0x000517366c9c6308,0x000bc9bb53389bc7,0x00025afa81750fe0,0x000afda6e1b71dc2,0x000c6a9aba51c85b,0x0000000000000000}}, + {{0x00000e070af57b1c,0x000441246548fb7a,0x000c563ead66464d,0x0007508f0851b47e,0x000f31999ecfeae6,0x000f85797a3840b6,0x000c74080d60c378,0x000f3eaf1e242bf3,0x00003ca35d886cbe,0x00022754c9a357ba,0x0000000000000000}, {0x000982d0aaae9f75,0x000176d1b4b6ca3d,0x0007980f7d421826,0x000979133a61fcc4,0x000cb63f41cac3bc,0x00079bb4b9516419,0x00033cd18a279569,0x00075e18895b57d5,0x00063599127b0d23,0x00063dbbded01670,0x0000000000000000}}, + {{0x000342ad817f361c,0x000cb1bd9eb81b06,0x000c7b97a0843c43,0x00083f804f029e13,0x000b3486644af0ff,0x0002a64dc632346d,0x0002a39cc0dcbed6,0x00056457b2ff9c5a,0x0000fe8536001cce,0x000def7d14af048a,0x0000000000000000}, {0x0006c4115861eef1,0x0006a14bad6b1ac1,0x0005dee3e9d201f9,0x0002b396cf147ed1,0x000f4643f8a21b3b,0x0004c9915584149b,0x000a893cfd7ba449,0x00027a8a4eb7aef9,0x000cc4fa992b1d31,0x000eec6c99a8fa7f,0x0000000000000001}}, + {{0x000a8d985f7ab9a0,0x000b7d39a70c2f72,0x000f6f8acabea7d5,0x00095d0273f642dc,0x0007d8a54bc56deb,0x000a63f1883f3cc3,0x0004b831ef1bba05,0x0008e112f14c8c07,0x00089737917f937a,0x0004874d335ca229,0x0000000000000000}, {0x0008374f770af11f,0x000cad8ee96d7e99,0x000bff9e11a7d432,0x00056384e6665366,0x0004a9b692423f6d,0x00075f044efc7e34,0x000ee60ee1b3dddf,0x00039cd00df7a827,0x000529eb5b2612c9,0x000cd7c4ffa6a13d,0x0000000000000000}}, +}, +{/* digit=84 [{1,2,3,..,}]*([2^336]*G) */ + {{0x000c16671a6774f1,0x000af03753ce5839,0x00054c5f8c07356f,0x0001afc71165a356,0x000f9d6adf86cf5c,0x000a6b4966903b89,0x0009f4ebff86c3fb,0x0004a87b0151b151,0x000efd27bbe4f95b,0x000b040513d26385,0x0000000000000000}, {0x000622a63fa5d90d,0x0008d92aca99c7d4,0x0001d6acf3aa6efd,0x0001b7387e55d6dd,0x00010db119c2295a,0x00011a67dad9703d,0x000eedb427c0f52d,0x0001e055192fe412,0x0004a5758174c7a3,0x00055cfd4b1dde40,0x0000000000000000}}, + {{0x0000d119f7fe9853,0x000fe49990254b37,0x0008a86cb40764d3,0x000820af39be0e2c,0x00027458321b04b9,0x000c2ba583294752,0x000ae89a07a5c7f2,0x0008fa6d520652e9,0x0005604c9bdc0eee,0x0000c06f2e484243,0x0000000000000000}, {0x00014a30a2bfa81c,0x000cbd6640003017,0x000ab87a938a3f37,0x000e1c91f3132874,0x000e57e9d7ac6ecb,0x000e33fb881734fa,0x000073b600765b07,0x0009428cbfb5edfc,0x00029028585e9a20,0x0001e077ef7692bd,0x0000000000000000}}, + {{0x000cf34a0d6f6ffe,0x000370c22b280291,0x000e87a26b1fd975,0x0008088a662b3666,0x000eea746601046d,0x0008edbdfb0988f2,0x000f2131f7fc1ebd,0x0009266b6d41f4b2,0x0003c1c020089694,0x000be27c849de8c8,0x0000000000000000}, {0x000bcda37f3a594e,0x000726480ec74a90,0x00026216e2ddde9d,0x00064b02bef16495,0x000aafba3c749a5c,0x000a872930c3f630,0x000654a8695df3be,0x000cb5372491b21d,0x00017f3b3a2f3f6f,0x00094613fe01cfe9,0x0000000000000000}}, + {{0x0008937b47b39090,0x000415bb7112fdec,0x00066e9e19d3ed5a,0x0006597801eab0fa,0x0005e740c409bbbe,0x000050b19bba9267,0x000df2c3e8b56daa,0x00012fbcf099e6ee,0x000195262a55e069,0x000ee2f2c7d1e980,0x0000000000000001}, {0x000c1384c013e53c,0x00074951ffea5bee,0x000d0ad477deaca6,0x0004ee3245756473,0x00030808642161fd,0x00050c8b97a30694,0x000340f405f653b8,0x000d5a543cae9de4,0x00031ca24347d550,0x00092a75f4312ea3,0x0000000000000001}}, + {{0x000c8162c746ef6f,0x000f6715dbf9ea58,0x0005523d8217dd87,0x0000b2c52bc5b0b4,0x0005db8903ecd878,0x0004296f75f92e78,0x0003c6e6397e4045,0x000e84bad1cccce3,0x000b82162d3c5f54,0x00009333f935ae95,0x0000000000000001}, {0x0004ff1c33e26a2e,0x000785b4ec10e1f5,0x000a1634274c2886,0x000b5d5ee5822d49,0x0002fbe9122e0bfa,0x00003c2cc2955a06,0x000e08e579ad9b7f,0x0001dd6ee255f2e5,0x0004f08f71b65e70,0x000c9dcd7d23cb93,0x0000000000000000}}, + {{0x000927819d85c389,0x00088dd986cf5001,0x000eb6ebdddab174,0x000a1e388628281f,0x000014511bc0392f,0x000b79c2a5e1691b,0x000d866b842f8440,0x0000343c71a48805,0x0002ac5c5d5d795d,0x0004aaedd8558804,0x0000000000000000}, {0x000896067875f110,0x00080b0d43dab8fa,0x0009a3104ecd6f15,0x00017c31840b3b59,0x0007841201091767,0x0008de871b2243eb,0x0003f7be2323a388,0x000f764799c353ac,0x0009d244edaf476f,0x000513c595b87c99,0x0000000000000001}}, + {{0x000800832e6fdb7c,0x000df2ceb7712003,0x000625cbf7ec3398,0x0007b9eb4c74b442,0x00090424f2515df6,0x000abc10516b9778,0x0005df82462b4902,0x000a6d60d9807c8f,0x000606aee1bb838c,0x00030e1e7a2ff1ff,0x0000000000000000}, {0x0008fce9b8ce853f,0x000b7049a4c20923,0x000ae2b39f773f7b,0x0002f55bcfbf4b1e,0x000b07309ae9653e,0x000cf869d6026775,0x00099fe1b0e83daf,0x000202f8a21d72ed,0x00037619de81bf7a,0x000b7b2bf238b7d7,0x0000000000000000}}, + {{0x0008ca9dd54298a1,0x0000e1308270c47f,0x0002be3ff9743378,0x000471b0b186cdf8,0x000b1747ce696eb6,0x00015fe31005f60a,0x000ac1b5a457da88,0x000f4901af0f6bb9,0x0002f972c925bd14,0x000186acd8b58a65,0x0000000000000001}, {0x0000f355372184c6,0x0005e1f7ba0c693e,0x0005b11db3d6dbda,0x00051b89e46fae1c,0x000c97c0b46b0f1f,0x000cc037caa48d5e,0x0000355bdcc75991,0x000f28784dc0e5f4,0x000837eadd1a3fa4,0x0009eeb5a1926d0b,0x0000000000000000}}, +}, +{/* digit=85 [{1,2,3,..,}]*([2^340]*G) */ + {{0x000847fc397e26dd,0x000de02cc0ff17de,0x00063e6fe388ee8b,0x0001e73a774123d0,0x000daf8cb9f5597b,0x000b938535ee20c8,0x0000d7da8b1bfac8,0x0008e2a819363df1,0x00079861ae7d4273,0x00003eaf0a677999,0x0000000000000000}, {0x000611141de00c8a,0x0001d2aefc5b58bb,0x00033633ce29b3d9,0x0004bfef0d5e3306,0x000d78956c10a254,0x000fa84101beaa2d,0x000f9588ba22402c,0x000e0df8f46296a5,0x000c7018734ace12,0x000ca8e0e00d25c6,0x0000000000000000}}, + {{0x000c26d9a28cda66,0x000ac34788e2808c,0x000a2e3c895ddb52,0x00092cc3305bc55d,0x00086ee8076376e7,0x000da2d9cb5f9d99,0x000f0d8aea185a30,0x00068ef462b956f8,0x0000f61c2096bebd,0x00044e7be11b5930,0x0000000000000000}, {0x000ea58bb15fdd13,0x000d5b2585fb779d,0x000d75c3d978271c,0x000e827a5ac1a4b5,0x0006c6fe4d4804ee,0x000f66c09f0147df,0x000b3203f6a4c217,0x00081eeb950292c3,0x000da3f441776841,0x00071712f688beeb,0x0000000000000000}}, + {{0x0004586de8027c8d,0x0003b7dc25b073ea,0x00049b36fccf2477,0x000032458466e794,0x0006f36f854043cc,0x00051e24c902d71d,0x000ec681a81ea4c2,0x00060e710d119e39,0x000dfa8e50e27e69,0x000bc96885ae0f44,0x0000000000000001}, {0x00072cc7ee3e54e0,0x000e54b8224b0f78,0x000e5d4bd3db5696,0x000d27cc64ead37d,0x0009b5b2f36d2cba,0x00021210e2a45e52,0x0002c8d788fbf745,0x000440c5440be1bd,0x000157b392b99018,0x00045deeecc510bc,0x0000000000000001}}, + {{0x0001f34441941c1e,0x000786af242ed224,0x00082ffb7bd73f71,0x00040040ee8f684b,0x0000b0e0a77660b9,0x00055090773cb918,0x0003b4341ff934d0,0x000efe154397d7e6,0x000566086597b1f2,0x00038e115dad8d73,0x0000000000000001}, {0x000320279e97eed7,0x00092b44ad3c59a0,0x0009546c02d95d0b,0x000317d617644016,0x000b3b1278de80cf,0x000150eec20cc035,0x0004047a454911ca,0x000eb15350f140f3,0x000297dd664a854c,0x000c1545fd389a24,0x0000000000000000}}, + {{0x00054c6d42f4ddeb,0x0001a5d46442b31b,0x0008eb97dd3c9497,0x000f35259e3e1ff6,0x00049058db0b2e2d,0x0006968077e0b694,0x000456e4ea6ec9f4,0x00098457796aba76,0x0005412cc7718336,0x000c5eb4e4306f25,0x0000000000000000}, {0x000f4a91bf2060dc,0x000e9a57dadc33ce,0x00051f56adeb934d,0x000b29d22e8fe341,0x0000f85723b5e49a,0x000ee66b41fabf52,0x0005253bffe67611,0x000c50202f550a60,0x0006d250b9e49468,0x0001a2956ea13fef,0x0000000000000000}}, + {{0x0000dc097ea2b524,0x000c5eb5323240e3,0x000082d33c53dd49,0x000c5d6917c692b6,0x000337e9d695a12b,0x00078372d602c7fd,0x000ef2985e92117b,0x0008ceacebcbefa0,0x00068cc3e9b4e8e1,0x000db3e3e50ee13d,0x0000000000000000}, {0x000980bec0d2f5e3,0x000eaa9b062f585f,0x00083ee3b5103eda,0x000605534f1f8028,0x000add292d29ee4a,0x000f9ba28df95f8d,0x000d134fb5785f57,0x000f0fe162fe54b8,0x00047f0902bd8287,0x000de3769ce1a122,0x0000000000000000}}, + {{0x0006e3d538c32c91,0x000eb774341e7141,0x0009e6b225ba2b4e,0x000824dcff742236,0x0004d5e3b9c67d3c,0x0006e4276dd54722,0x0001d2dcc105d46c,0x000392da4b3a8a00,0x000e2f3953b25248,0x0002fecbb5174b67,0x0000000000000000}, {0x00008d720508826b,0x000b9b4e2e807123,0x0001bf6b1169562d,0x0006d2acb14e6841,0x0008cbfd3257245f,0x000189ac1c8cdf45,0x000ee493f894fd3e,0x000fa59cbf0ab5d6,0x000476d8e672a0c8,0x000ed9fbb78753d8,0x0000000000000000}}, + {{0x00039334c1cd9788,0x0008ab0560e3e74e,0x000fa2ff6e2c62b5,0x000acd7d25b0cfee,0x000c456f469aee3d,0x000a862fad6476d0,0x000688f0d8d2340a,0x000b648a9494468a,0x000f4ed209d4d2fe,0x0008a93e7c5890e9,0x0000000000000001}, {0x000cdd07e3f60721,0x0002466078437612,0x000ea1835868d6d1,0x0005ba6a85400753,0x000f7f252808d5c3,0x0007b45d6857ba4d,0x000d683048ddde70,0x000c759393e38c60,0x0000c630e919b183,0x0007209017172576,0x0000000000000000}}, +}, +{/* digit=86 [{1,2,3,..,}]*([2^344]*G) */ + {{0x00060ead50b81885,0x000bcef73cb6f0c1,0x00053fb7eb3e2cd2,0x00062b319bb7bc05,0x000a38a471706b6b,0x00046c6b42daf298,0x00005e59d404cf98,0x00048fac2e73085e,0x000ff0af6c53893b,0x000de9e3d8eea7a8,0x0000000000000001}, {0x00034470acd5b055,0x0000c4c1af94ede9,0x0004fba6b3889b3f,0x00023ee49af80496,0x000f0d89fd53a3e4,0x00053cc302793fad,0x000b36dcd463b613,0x0003782e102e51fb,0x000c63732d6d1c6c,0x00059dc97f604bbb,0x0000000000000001}}, + {{0x000db31484a7e177,0x0001740a1bc3a05f,0x000c265e95ebda07,0x000546d643b1d3c4,0x000c2611b9709edc,0x00015784fc807b04,0x000e5bd473ceec4e,0x0003c97fb33e58af,0x000d6d5327b94dc5,0x00062a914fc6dc39,0x0000000000000000}, {0x000cbcf73d880ddb,0x000029df80627a67,0x00091ccf95a67d3e,0x000ec7aefd91b52d,0x0003aa855273ca53,0x0007213a95113157,0x000b98a49db550c0,0x000b470643affa5f,0x000f0628a0fa67f5,0x000d2cf906186e6b,0x0000000000000000}}, + {{0x00039cff07a9f5bc,0x000b27814ba6cdbc,0x0008da0e67469efd,0x0004ccf0a198fcd4,0x000cbf71a6e5b71a,0x000500eabe51b9c8,0x0007908463c5cf80,0x0004962539aa0260,0x0001de61db956e33,0x0004f9e2c1ac338f,0x0000000000000000}, {0x0005f37dc080da53,0x000c1c2a74369386,0x000025722593f4e4,0x000a4e09b626a8d5,0x0004b1e7f8c96db6,0x0002c5a75c187079,0x000cb91e644a3045,0x00024e7eb18af641,0x000fb48086d9cefa,0x000b4dd6532fa3f7,0x0000000000000001}}, + {{0x0001be067e3e2f37,0x0007737f152d2c7f,0x000242f8dec8659f,0x000c7d958df47d63,0x0001b91c63b0acba,0x000c2c6ad3f62088,0x00099adda54c0028,0x000a3012f6937019,0x00014f4c499516f6,0x000da068d44cb73c,0x0000000000000001}, {0x000209ec58d1b414,0x0008e876dcc7401d,0x0009323106751dc5,0x000f75f24e14fe98,0x000ac88f5086e5a4,0x000294dbdb4ccd6a,0x000be99edf86543f,0x0003767f48ab30e3,0x0007667c622dcd0b,0x000d7fd6615681d8,0x0000000000000001}}, + {{0x0008c453ac10be58,0x0006d75a48dfcf2c,0x000c4944bc5042f3,0x000e7ad5c9cee1eb,0x000996c45d109bc9,0x000689f02d424fbf,0x00023528e926c326,0x000e84ac793d58e5,0x0008eeaddb5a4ed0,0x0005d31f9ea2560c,0x0000000000000000}, {0x0007ba171a6ebc35,0x000d39e242ba28da,0x0000694f0cc97464,0x000d7fb496b0d2fb,0x000d7e1b5b66b3d8,0x00001db81788dc1a,0x0003854dd5fe4e9e,0x000f9965063e6021,0x0003751c74ab4631,0x00006945420e7941,0x0000000000000001}}, + {{0x0005b110bb6dcc9c,0x000e9d1e6c13e60d,0x00058585159a0842,0x000b46fe443356f4,0x000853b25c086265,0x000ebbff20877291,0x000136ec71c4d1d0,0x00003ebeca5e79c2,0x000a0af3b3a96ed2,0x000f93012e330a32,0x0000000000000001}, {0x00017ed67dacd4b6,0x000ceade583a567d,0x000316840b4e5703,0x000c414303d396ce,0x000ed6970ea480cf,0x00063761b9b1974c,0x000788f3de4383da,0x000ad07d6726e400,0x0003056bda545993,0x000385d3fe822ea3,0x0000000000000000}}, + {{0x000285c58225166f,0x00072d2451ec99f6,0x0005efbddf5101b0,0x000dbc066e055890,0x0002c29985ac7cd6,0x000f1839b6caca94,0x00093cafd8d9c1ce,0x000b177ba7911d6a,0x00098fc762e30d5d,0x00067686b89a78b5,0x0000000000000001}, {0x000dff4557a32b93,0x00037e16c6af191e,0x0007ad7362550f1a,0x000983cb772b5537,0x000b0746f50f2068,0x000dbb42f7ee6b8c,0x000f0cdda882070d,0x000a732384a13e83,0x00055b3be67dc4f2,0x0003cf20d84f4cbc,0x0000000000000001}}, + {{0x00007348004e40c0,0x000448f78fb0602f,0x000c2ac8aebb2604,0x00064b78277ca03f,0x000eb2c6f473d278,0x000cb793a9eb1664,0x000e2b358eee9a37,0x000194f18cbc9c2c,0x000f6078bc87a3dc,0x0006220e93cd112d,0x0000000000000001}, {0x000d1ed5d96d6d2f,0x000b72be10752f3f,0x000d1e476660c38f,0x000b1d6d9b093c35,0x00026d898dff773a,0x0004b445df00e4cf,0x000d1ce422c1136c,0x000db6e821b59ee0,0x000de6252e82511e,0x0002f481c804e41a,0x0000000000000000}}, +}, +{/* digit=87 [{1,2,3,..,}]*([2^348]*G) */ + {{0x000d7989af2b44ed,0x0006f91b1a9086f8,0x0002b4d5672b30f1,0x00072009919c3dae,0x000003b6ec0a964f,0x00012b7f4f64ce56,0x00076bfe0f0d4fbc,0x00043eb40f821444,0x000cbb4480332a8a,0x000f3ff375566080,0x0000000000000001}, {0x00018caf35e5d712,0x0009aba53d6591e5,0x0004f1b1b50e170d,0x000f9eca3e56ed3e,0x000288dfe4cc67c4,0x00059c7726fa0dd0,0x000a0660a01f234a,0x000a704007db6c8f,0x00070b32e8366767,0x00096994810fb845,0x0000000000000000}}, + {{0x00092a1897b4c0b5,0x0009027fe35612df,0x000a5105c7f9f97d,0x00021853ba021326,0x0005dd2cadb219c5,0x0003ab9d259b3ed4,0x000857fddadc1ebb,0x0004addab0607b4a,0x000ff916fbbc92a3,0x000721ee7e6c527d,0x0000000000000001}, {0x000ba1dabc6f5958,0x0000087b0e564aa3,0x000b9c963dd27f6c,0x00028eca3c030970,0x000c23cd7a457768,0x00017b833d0834d3,0x000be25f44c50d54,0x000a153d4a6bf0d8,0x000e9c71da49590e,0x000d43f3a30dc247,0x0000000000000001}}, + {{0x0009bd585a57c01e,0x000ee844d7078c7b,0x0006c16cb258be3e,0x000a3282f9caf55b,0x000e08d004fc2ebd,0x0009db3ca2d054d0,0x000ff89010ddde2b,0x0006615b9b156d6c,0x00000ee87cbb5e96,0x0000965826673f04,0x0000000000000000}, {0x0005c973c58e4e2f,0x000bfed17990af45,0x000982806a235d03,0x0003a7e6203578b6,0x0002679d20d4837e,0x000fa09a67212915,0x0001e993e548aecf,0x000034e7752d33de,0x0008c0133b8d99be,0x0005d644443ed88b,0x0000000000000001}}, + {{0x0005d09795891669,0x00055ce0c6b8f799,0x000cdfa7a67baad2,0x0009a5462a84102f,0x000ca5fff322b2ed,0x00016895f0238b4c,0x000e1fc27a1fc8f3,0x0007399300db4369,0x00016f718708ed71,0x000aa4931503fe5f,0x0000000000000001}, {0x00040da9e1ff0c6b,0x00022af9967269a0,0x0005871908b86944,0x000801c88350fa73,0x000f680cd1b5d61c,0x000f0b415826cc63,0x0008b363474f5f7a,0x00027800e5401e93,0x0002305262f20f7f,0x0005e6d27bb44c56,0x0000000000000000}}, + {{0x000dab714dbca0be,0x000450d634bc786d,0x000d2802c42f3afb,0x000ef6e542d9994d,0x000946669336b0ea,0x0006a8fe65059b68,0x000f702cce1812e5,0x00030e3c70e359c5,0x0009fd5b9f2069d5,0x000093f3f0186d75,0x0000000000000001}, {0x0006d10e2b40858b,0x000a417e22a4fbc2,0x00013ba0de831401,0x000d41a31a86b763,0x000893ad0b78b7c2,0x000aacf20f1564cd,0x000bac0041297947,0x0004ac69dc2da24d,0x000ba071987933c2,0x0007176068dfbd75,0x0000000000000000}}, + {{0x000c8b4eb4601064,0x00099a991f16e053,0x0005bcf58e425bfa,0x000b1e6fefc21bff,0x0005da04d7e97cf6,0x0003f93bddaedacc,0x000336130ff2741f,0x00028f428d033ae2,0x000b98d58f0cc054,0x000281be6796c6ea,0x0000000000000001}, {0x000562d3cd261bc6,0x000c4e652831be2e,0x0007f84fc06f2ac2,0x000b078d9ca13774,0x000d2b248e882f5c,0x0006981dfa0231e8,0x0005f7dcfabfd673,0x000f3658f51759de,0x000d6a68de41452d,0x00038358c049f993,0x0000000000000000}}, + {{0x000dba36a11f468b,0x000ddefecb4596c7,0x00004044ba328343,0x000e3d89658e943c,0x000955f5e1aeb372,0x00008650d658c0f4,0x0004309aed6ff5c1,0x0000ad875f7bb480,0x000c35156e670707,0x00066875cf1c6033,0x0000000000000000}, {0x000bceb289713705,0x000a8a9a03fa8061,0x000cac052e91978c,0x000b61eb6bb99c20,0x000e50fb8f33460f,0x000ec61a887398ae,0x0007437f45e3c633,0x000fcf4c74c22971,0x0004691a2d9b4866,0x0009004647f4a64b,0x0000000000000000}}, + {{0x0004f3cfa7e54e73,0x00076a7075c33047,0x000b446bdd4b3ee5,0x0003371a1b7efe90,0x00013826a3c98a14,0x000412cdba45fcf1,0x00048a44b5601caa,0x000206ebe3f76143,0x00050e4439f111b6,0x0008451f6bb4a9d7,0x0000000000000000}, {0x000c0d59b5f2d48b,0x00029bcb29ae2863,0x0003a9a3c78e216b,0x0007856c2465c5b5,0x0004736d155fd956,0x0001ce6b07dfbfe0,0x0008361c3a4fa43a,0x000d0e9f03c0f19b,0x000e803f9b21f548,0x0002f885460ccb9d,0x0000000000000001}}, +}, +{/* digit=88 [{1,2,3,..,}]*([2^352]*G) */ + {{0x0006b287cbed671f,0x00071c978130d6d2,0x0007aadd881d433a,0x0004f45fb4ad7bb1,0x000d7b1940d6b52e,0x0002d44569722e2b,0x000de70f91dc84e7,0x000ed42546436d3f,0x00047e41abd1bc41,0x00010f544a7be2b8,0x0000000000000000}, {0x000e82545325818a,0x0003cf3d8e5d2be2,0x0005f30317d1c986,0x00015ce098fb8ec2,0x000158947db8581f,0x00055d8793f3e6c3,0x000f50843a7feb50,0x0008ac153d3d8417,0x0004329e7248bbc3,0x000d2ffcfbcb0366,0x0000000000000000}}, + {{0x000b91e88872c802,0x0009859329a6f390,0x000332091e85e0fd,0x000d0a1fc7233994,0x000c07172741e069,0x000870fafc953488,0x000d8073b040fb91,0x00089e841e1bbb2f,0x000f582161687272,0x0007bfa72dc0f548,0x0000000000000001}, {0x000c2f4044695d52,0x000e9fc898f3ae4e,0x000d6d16346893df,0x000cc356cfc2a2d6,0x0008f9780e14adcf,0x00040c34a952a0f5,0x000bf1f1f74017fe,0x000ae85cc7e49637,0x0002400547db8273,0x000eafd4e119d7f7,0x0000000000000000}}, + {{0x000a5355afe08a2e,0x000687a2f29baf29,0x000653058a23e11c,0x000110b2ab5abb63,0x000e4ead1d1b9533,0x0005d1b7b6254324,0x00074059ad5a8616,0x00090712ab62d100,0x000e9d5016f88f2a,0x000afeefd62c6b78,0x0000000000000000}, {0x000d2d42ce0d173b,0x0009198d15289e62,0x0004baf7b535d68b,0x0008566e4a9af773,0x000402c278158bfd,0x000603f6310f0f5b,0x000331a366d639ea,0x0007457655beed79,0x0004b46175b5f4bc,0x00048f6ced012274,0x0000000000000001}}, + {{0x000b20efdb706d0d,0x000c40117c40b081,0x0000a6d9c2aec008,0x0004d3e0693270e3,0x000674266a5ea611,0x0001ebf62144a6af,0x0003d45ee3917e38,0x0008c35ff5d67fca,0x0006e79dba352604,0x00081a7e7bfed40f,0x0000000000000000}, {0x00006eb8dc692380,0x000fe33343c5a20c,0x0003e67d0a53418c,0x0008959e15eb001a,0x000ac0ead5e7c7e4,0x0002e4162f0962e6,0x00017bb3e28513c3,0x0004317568fafb81,0x000912ceb3a2e303,0x000102559381740c,0x0000000000000001}}, + {{0x0005f372c77f1047,0x000b3d958eb7b744,0x00069ac2a8ab1157,0x00057d2ec5015809,0x0007f4db5c158ff6,0x000e3fc15a71737f,0x00048e949735c5de,0x0003845758233ed6,0x000e91137608f198,0x000720cc72b9199c,0x0000000000000000}, {0x000b050528cb006d,0x000ac29d53a71cfd,0x0009a1f2ad6eb262,0x0006c829676f56dc,0x0003dd6ddbfb591a,0x000c61cac801979f,0x00031b13cd6cc83a,0x0003cf1a5e5c85bc,0x0007cff1f95623b3,0x0004f7b2cd595d6e,0x0000000000000001}}, + {{0x000699fc8b3dab7b,0x000229f393f97b3f,0x000012376dbad08a,0x00038a797638cccb,0x0006110a40e7e328,0x000e3d1acf08dea4,0x00003f85adfc07de,0x000fffa8d9d37eb4,0x000db3ca114eff2b,0x000b41dd72c79e23,0x0000000000000001}, {0x000822fbbe3ad3af,0x000ddd71461cfcd7,0x000d3d8f03aedaa8,0x000f069c35282be1,0x0009283f776eb004,0x000746b05b9838ad,0x0002fcc85c205f31,0x000bd9143e61b0eb,0x0004e7f4435b3321,0x000a673088e100ce,0x0000000000000001}}, + {{0x00052e132b686982,0x000419eaf166734f,0x000edb4ffc59ba11,0x0004fda13f9e0e45,0x0000c12226a0efde,0x00070adf716ee2a5,0x000402012f467257,0x000f2ecf2b32d94e,0x000205b1386ade63,0x000b3bc779c31b50,0x0000000000000001}, {0x000cbbdbe0875f47,0x000a208dcda3e65d,0x00048b61b40cb945,0x0002b16480725e0f,0x000aa186079b7359,0x0007e306ab144462,0x0004b09effdc0e10,0x000a76ab4395ae17,0x0008c3ddeeefeec9,0x000216cdb5d669d6,0x0000000000000001}}, + {{0x000c70f6d4b2fef7,0x000c0c92ef06acfe,0x000790f3344c38aa,0x0000fed753c30edf,0x0003dfc8006501b4,0x000df722f2f6da80,0x000c340284a42e2f,0x0002a0f154005cec,0x00082f0dfb36ac65,0x0007bed1506b21ef,0x0000000000000000}, {0x000d76b785906061,0x000edca1c3d7b884,0x000307e9a89c6050,0x000e0ccc1519baa6,0x000663495eff88c7,0x000a17475b22e916,0x000c39e69639f1ce,0x000b1f0e827f8c53,0x000066355ede8121,0x000d5b91249281eb,0x0000000000000000}}, +}, +{/* digit=89 [{1,2,3,..,}]*([2^356]*G) */ + {{0x000ccccf35a37229,0x000465167517203a,0x0001bf938eaa2ac7,0x000d73d683a983dd,0x0007f598a6f1db73,0x000235f9ed630b4f,0x000f332db784cb56,0x0003b330540f52bd,0x0005843b0221e5e8,0x00044a09499b4ec2,0x0000000000000000}, {0x0000fb3cab0a1b02,0x0008968b6e52dc01,0x00022c046dc60a24,0x000695beae1e187a,0x000d3006acf49482,0x000960f10535934b,0x000df011e1d0143b,0x00085de371d84cfd,0x00082841456c439e,0x000585582ff3b564,0x0000000000000001}}, + {{0x000e94ac6fbf17fb,0x00044289803b61bc,0x0002e798f31e8afe,0x0005e43d9a42f37b,0x000f377aef7a7947,0x00003a6947a8f685,0x000c1b4969c3b8c2,0x000b9c542cdbdf0d,0x000501682c76bc8f,0x0006972a768660ff,0x0000000000000000}, {0x000f9daec5f3009b,0x000325c4a46652c8,0x000b09499ac89b1c,0x0003ccd5721c0cae,0x00098da46e3445e6,0x0002db691caca0b9,0x000845a793a1fc73,0x000ad927f614049e,0x000024bf07aea310,0x0007245359be8b80,0x0000000000000001}}, + {{0x0000db1596cc9e80,0x0009a231d0f49f13,0x000f1d499d6bd9c7,0x000757ac7ea9b7cf,0x0005305a4d545367,0x000f2c85480a42a4,0x00029efd461a5b51,0x000fe691c9e6b8ed,0x00090ea1ca549541,0x00058f09c0153e64,0x0000000000000000}, {0x000525f593f9a0ed,0x000edbc140a1f67f,0x000f5bef166a98aa,0x0007a559750be5c2,0x000fb8cba58b2d45,0x00014d93d0c5d96c,0x000723470bfa2f95,0x0004f6b79058b86d,0x000d58f11a8a7858,0x000fe32b2d0ad418,0x0000000000000001}}, + {{0x00016f6d1a0d42ca,0x0000a7c2c062afb4,0x0001630676c3dacb,0x000c297ad74ee6b3,0x000d18f736e4995f,0x00064edc2548a7a2,0x00031596b5d5f53d,0x00040e945b2c8330,0x000587c06dfaa52c,0x00037c462a8f05b0,0x0000000000000000}, {0x000cd636b4f0d870,0x000b2b0835ddc02f,0x000d233347086482,0x000bf92bc7f1c7b2,0x00050d5f30c92b32,0x000ce136c0491539,0x000254d29288cec9,0x000c34eb38494ac8,0x000ba2a1b0b3117a,0x000c473a85376a14,0x0000000000000001}}, + {{0x0002a61629b67537,0x000edcfef26d3aba,0x0004bac42f2af22b,0x0004da8b32bd0514,0x000be474d59e6af5,0x000c190f17846ca3,0x000f3e17e7c79bfa,0x000a13543ecbaea0,0x000e74acd0ff996b,0x000cbde27a5f5aab,0x0000000000000000}, {0x000ccc73ffeccff0,0x00082b1e746179a8,0x000b19b717d62af8,0x0005045a4e0895be,0x0006b8f194a8bb25,0x00089f1cd50b3736,0x000f2a57b3da3e10,0x000691e4f67468b1,0x0008976ca9c4602f,0x0005e53ed98ad969,0x0000000000000000}}, + {{0x000f79bf523ecdd9,0x00097ebf36d74486,0x0000fe48147bf45f,0x000868d46235b3ae,0x00073a9b13d93d40,0x0004e9264c45fa91,0x0008c79b5705f4c3,0x0000fd4b166fd0d5,0x000aca2edaf4ff87,0x000955b68a488f7a,0x0000000000000000}, {0x000f3e0b19951fb2,0x000c26747dd972f5,0x00092d84bc8f6fc0,0x000255f7088102b5,0x000c984970893201,0x000a6791707f6288,0x00072769309b54e6,0x0006389f4da5d532,0x000c1eb23c48b5de,0x000d1bac794b858f,0x0000000000000000}}, + {{0x000e2d8dfd2d5a87,0x000e5a708c918328,0x0009b9fb00f1dbe8,0x000fe9c7a3695cb8,0x000749205b4caaea,0x00056f204bd6ec0b,0x0001a73a9e0254c7,0x0004152441cfd51d,0x0000d2b8b0ca9156,0x0004dee3cdd9e937,0x0000000000000001}, {0x000ab13754dec146,0x000b5d5322d78e9d,0x0000adbfc5578b8a,0x0000ce27a2b97f9c,0x000b49cd573f2d5d,0x0006ee23d2e94e39,0x00061ea213bd15a0,0x000e561b9d34708d,0x000fb576c6271f59,0x0001669ae9450741,0x0000000000000001}}, + {{0x0001a66376c54f37,0x000a06b888102e23,0x000430b0efaaecdf,0x0003b1e3d888793c,0x0004f8beed2dbb12,0x000ea5e72a8887df,0x000d4aa2425e9853,0x0009d98e93f3ccc7,0x000cba97fe918171,0x0006b08ea6eef307,0x0000000000000001}, {0x00019b171f51c344,0x000d5e5d9f40be57,0x000fea96313e16ec,0x0001461efe1e359f,0x00043de9904f3d9f,0x00081bb7a038f6d9,0x000ed552c5787d58,0x000a67fc2cd9a74e,0x000643f377ccb483,0x0009db7070b5762c,0x0000000000000000}}, +}, +{/* digit=90 [{1,2,3,..,}]*([2^360]*G) */ + {{0x000188556b53942b,0x000736bd7c7672ca,0x000a466705820ced,0x00039ba4b83d6897,0x000af174ecbf7e3f,0x00003dc58b34188f,0x000b453db5dba0b2,0x000ef54df32d5206,0x000d08e3c52fcf51,0x0003732f551f3408,0x0000000000000000}, {0x000937ade92603b2,0x000b6a7f7f5dfd6b,0x0003151876b632c9,0x0009040d3ee4a789,0x0007441b009fd7a5,0x0008b427fedfc2d2,0x0007f921c0ceded6,0x0002220fc8f207d5,0x0000f675383c79a4,0x000d6f410a2e837b,0x0000000000000001}}, + {{0x000fb8b792ff9c0f,0x00062d82addc4301,0x000b9cdf1d9fdb00,0x00042255b1cf25ad,0x0009daaea42ebb5a,0x000dffd105199066,0x00001d688f207641,0x0001da7769bd6130,0x0004ea507a275aa1,0x000073ea612e43e0,0x0000000000000000}, {0x000f18b4b24386fb,0x000f72268a5e0821,0x000ad126436a7554,0x000ba02f714fe1c3,0x00019b7c7cde45b5,0x000c576f09f2da35,0x000aef34fb328e0f,0x0001a0386e0f185f,0x0007a6bb32adc73d,0x000733da21be9ac9,0x0000000000000001}}, + {{0x00023d540d542b80,0x0004cc500040b26a,0x000e6a09fa7f8755,0x00027fbb548aea96,0x00065fa1d8c060cf,0x000943cfee1a6187,0x00061bce6a8c7ea1,0x000d99730b0b20bf,0x000eac170744528d,0x000423d049742c42,0x0000000000000000}, {0x0002bba636da345a,0x000a62e601cd801e,0x000c9e240a6cbeef,0x000103af8106469f,0x00007c7109e54da8,0x000b9a3ec3dcc449,0x0007788e44b6df8d,0x000d0e67c93ee34b,0x000e8347b4a58495,0x00037223b5096e63,0x0000000000000001}}, + {{0x000417e035b970b5,0x000ca1b60364c1bf,0x000ea847f52dda37,0x000517fb28527f5c,0x00007a1e399f798d,0x000452c79fff102f,0x000688a87dfab3cc,0x0006490b0295c5aa,0x000d17acd0dbc605,0x0005acb4f6972c3d,0x0000000000000001}, {0x000fa35559042635,0x0004e33a903ffa23,0x000c46f6e3526281,0x0007bc6b1cec4214,0x0004bca2e1dc8726,0x000b50045720b747,0x000c697f394811de,0x000ba5001f3d4304,0x0009ea7fd0f7a5e2,0x00090dead3d0124c,0x0000000000000000}}, + {{0x000e47c23d19de00,0x0009afd475bc3cb7,0x0001acc6490ff459,0x0009f5dc39b1950f,0x00064d14540f1ee0,0x0001b75050e51c95,0x0005647bebd088ff,0x000f240dba4c1789,0x0009b95e8097400c,0x00085b5d4b842055,0x0000000000000001}, {0x000986a76d06fbfb,0x000d7fc2ffb65385,0x00018e264c5a478e,0x0005a2784841d184,0x000fe21d9e8a017a,0x000bf52154297fe2,0x0007dad072d6d911,0x000eae77c8ea8832,0x000786b6a02d1fcb,0x000e682555450013,0x0000000000000000}}, + {{0x000de731f9f48a0a,0x000a357753cff617,0x00073655403972b7,0x0000484d28d73a10,0x000c846d46c140c7,0x00055b7ef1516a9d,0x00014890b5525944,0x0005f418ade1b816,0x000a465f264a9164,0x000ed37693e9a176,0x0000000000000001}, {0x000e5c3bfdcbca2f,0x000121dc135bc4e5,0x0003d39b5c7ca946,0x000be46855877498,0x000879fb5d801318,0x000afd92b1e5cb62,0x00024aecd7f80343,0x0004a3835c8434ed,0x00025764c6aa7d95,0x000a0241780668d3,0x0000000000000000}}, + {{0x000c0928cf2280c1,0x000f2c37933b1734,0x0006bae2a2974a56,0x0001e8bdb1d26ac8,0x0009c84c336cb6bd,0x000ca41014cdaa1b,0x00024b87838c44fa,0x000f525239cae2ce,0x000cb0507515f204,0x000993dbd0e0a58b,0x0000000000000001}, {0x0001411bdc3926ce,0x00087f3e15aa5363,0x000ade47bf68672c,0x000028e493da50d5,0x000120048f8cd148,0x0005ecfaeb03c756,0x000e1347b7867aab,0x000ba0208953afcd,0x000be9b23e2411e3,0x000a2e848d40b424,0x0000000000000001}}, + {{0x000583ec08d4ad28,0x0007687b7ba7d916,0x0002b3f0b4e2bbb4,0x0002caace0e4b3fb,0x000b0e6fb63a6917,0x00000520c822aab4,0x000f41f7930e37aa,0x00046bfa91da4dcb,0x0008bd604f521a69,0x00040fa707c1f0b8,0x0000000000000001}, {0x000520b880d23952,0x000bb822333018d8,0x000aa6a00bca6bc2,0x000f3469011553af,0x000c20ed5fc0a5de,0x000ee0e8c5bcfec7,0x000476e2f464224d,0x0002d844542e8adb,0x00009924fd3c1bdb,0x000f2fac98d161a7,0x0000000000000001}}, +}, +{/* digit=91 [{1,2,3,..,}]*([2^364]*G) */ + {{0x000c9a655367407c,0x00001acf48b04d30,0x00004344830b68ea,0x00058a53174d6fa7,0x000f59044eeb31ac,0x00087d51a60524d6,0x000a344fb882d4df,0x000d1ed41d08aa0b,0x00086b6aea85fb93,0x0007f27fa57f4860,0x0000000000000001}, {0x0006f6fa7b7febd7,0x000ef92aae956259,0x000abc183c404813,0x00011be4ded30d2a,0x000e220b7ae966a0,0x000c3e6cfc88e77b,0x000a92b77d5e0cab,0x0003d7f99c6dac06,0x0000a6be4c76c302,0x00032d1d55150da8,0x0000000000000001}}, + {{0x0000d37f0300cf42,0x000564d1a1ebfaea,0x000bce4cf04b07ea,0x00084f2b4677d784,0x000db14a4f867741,0x0000b95ce93b8741,0x000a31735b5960b0,0x0003d2c80a76fae4,0x00022c4d123107ec,0x0006cd8678a9d705,0x0000000000000001}, {0x0004b58dcaec13d9,0x00067d88c3d5f230,0x000f847248f45f52,0x0003da2628ef4e85,0x000e37945a7b9c0f,0x000a2da387ea2c17,0x0008e98e84de9888,0x00038290c88f211a,0x0004ce3667557434,0x000040ca4612f56b,0x0000000000000000}}, + {{0x0009e872c584974d,0x0006ca75132450c3,0x0006c420ca2dafbb,0x00069da0e632e68f,0x00018e1d45c5a963,0x0000394fa7a8601f,0x00098adcea6c9852,0x0001b23e3c6dad95,0x000f0655b2b99628,0x0001992529d81db4,0x0000000000000000}, {0x00000b6625e14e8c,0x0006611065dd0a46,0x0000a833140f2868,0x000735d82490f09d,0x000326d182482735,0x00074f69a678ac02,0x000e336a3425366d,0x0000093a8f215358,0x000644f6ddf3569b,0x000d19beff776a6e,0x0000000000000000}}, + {{0x0007a73bd7975b73,0x0004ba1e3ef4b56c,0x000835871e0104fc,0x000ed4624759b57a,0x000eed3c95d4d9b4,0x00029d8353648a71,0x0006bedece81ad28,0x0001452c12f2b2a5,0x000ab19b8b67ec3e,0x000ccd3f8f88bf35,0x0000000000000000}, {0x000062e0d5c7f0b6,0x000dd34abff69676,0x0009b89962a6641c,0x0002be1c0add12e1,0x00014a078191a9f4,0x000c488cf972d9da,0x00090e9607f65fc7,0x000d5cdadd7da7e7,0x0001ca37f83b3584,0x000dd43c6df02d38,0x0000000000000000}}, + {{0x0003f8ca58799292,0x000601d1cbef0700,0x000f41308b0cefb1,0x00090de4387a468e,0x00035f90ae8d18bb,0x000b356306c0a768,0x0005e167044866de,0x000114237a5a47dc,0x000143e3b4bbc084,0x000c1c6d0277c186,0x0000000000000000}, {0x000c81887bc12544,0x0006af4b6c2a8e8c,0x000ba5958fe82cbe,0x00067cd479340299,0x000d360f1809e7e6,0x000de77ee94fcc0f,0x0009d25d201341ff,0x000fac2af6e20977,0x000dfea19f8974a2,0x000fba7a5252c712,0x0000000000000001}}, + {{0x0001e6367ded4905,0x000fd6fd8b41173a,0x0000c717ef3cdcf0,0x000608fdb3300d01,0x0000d527d7c8e07e,0x00039cd9ece69c0a,0x000677211bdaf48d,0x000b5d520c7fa557,0x000bf842692f3c61,0x000055814bffe31f,0x0000000000000001}, {0x000c94502a0e0f49,0x0000528193bb953d,0x000d7bdda5ab1a23,0x0007c4a219650b25,0x0000f78abb7ba4c6,0x000eb157bdb9dbe1,0x000ace6b3d0ff943,0x00048180c4dc1a32,0x0000124b69e9b36a,0x000da7fee72796eb,0x0000000000000001}}, + {{0x000530dbdddc111e,0x0004131a0423e417,0x0002a2fcd4c890b5,0x000685a6ffdb8021,0x0001c68bcc7cf314,0x000fb29a153281e3,0x00090775f2e2a729,0x000fe4fc20716627,0x0005fa8915460a5d,0x000b7744dbded762,0x0000000000000001}, {0x00058330ded93a3e,0x0002ad9ca2943c52,0x00031d21ab8030d0,0x000fe30e76f64897,0x0002b30fd418c647,0x000815868a20f82e,0x00098d35bf8cbd5b,0x000facccde412b85,0x000358ff02bb4ec8,0x000fa54fb1673bc1,0x0000000000000001}}, + {{0x000aed08c7bd3b0c,0x0004e546195fa3ed,0x000c31c13efbcb9e,0x000f2eaeb2cc8a6a,0x000a1912ca200483,0x000f0ff27a5ee60f,0x0000a7b9e9c56cff,0x00044977503cdac7,0x00064deabbda5a3e,0x00038efe3a9fcba5,0x0000000000000001}, {0x000821113784eeb7,0x000a12560a5e577e,0x000ae4b9aaf4ec38,0x0005c9a38358d926,0x000497b69c24b1cb,0x00007485410e5464,0x00026fb660a2d50c,0x000987263ee5a4c4,0x000b3ba20c286e0b,0x000ae54bed6c50f7,0x0000000000000000}}, +}, +{/* digit=92 [{1,2,3,..,}]*([2^368]*G) */ + {{0x000e2418ebe8f2ee,0x000f4560bac026d4,0x00008c6a85ee3153,0x000c7d7d8e05a0fb,0x000d35867d053abe,0x000ebaaa06ca6918,0x00022207d8627f01,0x000fdfe74b9c6ea9,0x000478deb27dc332,0x0006b633ddba7b54,0x0000000000000000}, {0x000eb3b84da8ae44,0x000dced254321c2f,0x000ae0be12cbd92c,0x000b5fae91edd7e2,0x000adacef448565a,0x0003f288c1607c22,0x000ea8d01e22b70e,0x0004e3598c73a3ba,0x0009cd9f6c24e3c9,0x0007a5595791d3f8,0x0000000000000000}}, + {{0x000cd049d3a9026e,0x000dbe859af0b3a1,0x000d9aa6b9632b70,0x00029dc483656cba,0x0007d02bc7ba1a52,0x000fc68a06574b48,0x000470a9518ff35f,0x000aaf20c720ad36,0x0003bb49ecf8b908,0x000f66f8b9d88aee,0x0000000000000001}, {0x0004ae92aaca41ff,0x0009e2ff799aa5c0,0x00048de6d0a352ca,0x0008f5f2eb0f3051,0x000fea98f1062e2b,0x000285eca4dfe726,0x00044d322419400c,0x0001441ba1f95272,0x000c0f6113ec0c84,0x000b67f7b093769a,0x0000000000000001}}, + {{0x00010c16516e4d3c,0x000611e277c39f9f,0x00040673dd719aec,0x000e007e471514eb,0x0006cb0a884f04c5,0x0007cdfc977e1e7d,0x00096fd19b101b5e,0x0008b661589b4413,0x0006ee58455ad5da,0x00030384dfd6a666,0x0000000000000001}, {0x000dcee7cc09a195,0x000f049d8452fc3f,0x000453637f0d8b3f,0x0001dc43d12fc712,0x000f4b97aa7b885d,0x00030970db43c87b,0x000015eb8214e6b6,0x0006a5744b5ac5b8,0x0008d3fab8987808,0x0008438a227d82a5,0x0000000000000000}}, + {{0x0002d58e6de7c70e,0x000a184fd2b399ce,0x000d46ffafde56a0,0x0003266443a772e3,0x0009e5e99ec73618,0x00068acc975a652a,0x000b99dda22ced10,0x000f17534159829e,0x000ab0176c94c616,0x000fbda334609df6,0x0000000000000001}, {0x000e586ebac6018e,0x000f2f03144a03f0,0x00070d82d13df49e,0x000fad35f054795a,0x000bfca4e83c93d4,0x000ccd2e817178dc,0x00006d906f96d5dd,0x000999860a4c0599,0x0007c4473b0cc898,0x0002a9c7a2422f0b,0x0000000000000001}}, + {{0x0002b09542f251bc,0x000e9c6a4a88693c,0x000ca160d5142fa0,0x000a8912377d1615,0x000e8a6efbddaae6,0x000a4c058235658a,0x000f27a6a6dd7c56,0x00070769ea7bd61f,0x0006f5dde4e365fe,0x000d56d5c0ff87a3,0x0000000000000000}, {0x000ceae2e0074d51,0x0000c081ba44424f,0x000d9e0eec434166,0x000bbc85793c6ecf,0x0000cfdda19dc769,0x0009ff9b44e244b1,0x00055190f00a8e3e,0x000a30e6f1e94105,0x0002df24f630f9cd,0x000164028859bc1d,0x0000000000000001}}, + {{0x00091d8b229586b3,0x00062d4212a9d0d7,0x000a44dcf82dea37,0x000886a8066a0e31,0x000c8d5c7f9428cd,0x000e7fa7c681f5e4,0x000db54aa6ccbecd,0x000e8442c468c6ab,0x000eb0d35eb4fd66,0x000ecc62bfda1f45,0x0000000000000000}, {0x00043fbb4e2cb5f4,0x000b78f0a96488d5,0x0000f4585ef033e7,0x000ccf9f3f7c9386,0x0002c56f736843a4,0x0003c2a98300d2f8,0x000d0e9651445c74,0x0006ad9774234178,0x000b0d7d2ff89fee,0x0002dc8f018f3a2c,0x0000000000000001}}, + {{0x000a0b1e42fb1d75,0x0005875ba8ec633c,0x0009652adf59ccbb,0x000c9a8c4da98461,0x000058421fa35715,0x000861494cf70c21,0x0001a367a4a6e22b,0x000f1f29e364cf7f,0x0002eb8412063103,0x000046241f101761,0x0000000000000001}, {0x00035295fd113dfe,0x00087ca26d83dc56,0x00009b60485e1379,0x0006992ee53da791,0x0003f63e81d304b9,0x0005e83c82169ed5,0x000cdfc2181cd77e,0x0002864256eb4e4a,0x000dd24e836cab6d,0x0000560017a3ed5b,0x0000000000000000}}, + {{0x0000d40ea7dbd218,0x0000bffd292d5f99,0x0000b3c033efe2aa,0x0003caf5350ffa07,0x00062cba18d05709,0x000de1ef348e77aa,0x00050628dcafce95,0x000654c13b978d30,0x0004b7581a218420,0x000aebc1eed7a302,0x0000000000000000}, {0x000467c3cff7787c,0x000cc65919f6e7d2,0x000e4ef4ee66f3a2,0x0005339dd95dc335,0x00083538624188b1,0x000c9f6ee9c47f71,0x000c2d00164075ad,0x0000fb8c9b9b8fc3,0x000ab425082f15ec,0x0003706da80b242c,0x0000000000000001}}, +}, +{/* digit=93 [{1,2,3,..,}]*([2^372]*G) */ + {{0x000981c54aaf54da,0x000345cebb5e6933,0x000544b1b1632546,0x0001b01f84cafbc6,0x000115cddc181798,0x000378ad86aa1393,0x00075fe68cbb4941,0x0009588ce3ac7e26,0x000708d627f2694e,0x000a9deda381ddab,0x0000000000000001}, {0x000d5f56fe3c020f,0x00064c1a13df6f31,0x00002f2a54ccdb45,0x00018f47586ae362,0x000f6db9ebb1f191,0x000b71b6517fa3e3,0x000f8c282c695b00,0x000758306aa882ec,0x000bb71fac8a72bb,0x0005351671f4f924,0x0000000000000001}}, + {{0x0008318350691a0c,0x000b269d0103c9cb,0x000bca486ca47a18,0x0001af062d151fe9,0x000e7c2bcd6c38a3,0x000a2dd4944c38da,0x000d5e2d0cab5f56,0x0001aaffb6b80e8d,0x000b4ab87f1aa045,0x000baad7ec926bd1,0x0000000000000000}, {0x0001499620b24214,0x0007f0d276179361,0x0005f42f5e14dbe6,0x000a3745bdaa4d19,0x000b02770c1ff9ae,0x00030746fe336a10,0x0005a19965986ef7,0x000598b61ae7500d,0x000c2b7c92c56a5b,0x0007c0f20ece26fb,0x0000000000000000}}, + {{0x00087e69d72ded5b,0x000cbed0493c7849,0x00059557a83ba0a5,0x000cabc475bbdb17,0x0003d65e4a623f2a,0x00071fb7df8bf3c5,0x000f576c8eb2466d,0x0003c6d8140f7545,0x00002bd4e620a012,0x000cb967837a469f,0x0000000000000001}, {0x000871f9216cfc43,0x000a4dc25382488b,0x000ef93af7d4b3a3,0x0003ed77dbf730c3,0x000a6f764526ebfd,0x000b6152b407f935,0x00025711c016476c,0x0003dee3ad5a2bf3,0x00009ed5688aaec7,0x0007cb5a614fc9fb,0x0000000000000001}}, + {{0x000d2983eb57fb01,0x0006f8090fc8d49a,0x00055cd8ed43313e,0x000063128651d168,0x0009d55315e356a9,0x0003731bdb591a91,0x00090f35172884d8,0x000ce2ac6b9b209c,0x000e9deccfbd125c,0x0004c67d19839d92,0x0000000000000000}, {0x0007835fb081749a,0x00038c29318405ed,0x000c88969fe7858c,0x000d9e6b39c13839,0x0001a193b85889e3,0x0000167b73a0e542,0x000e3a6c6ebad78e,0x000fea5061213cbb,0x000f99af7a8cbcf0,0x000934dbdf82d320,0x0000000000000001}}, + {{0x000dd97cee516977,0x000fc49266fa93ba,0x000b3371de037896,0x000f3467c9ec4ba4,0x000bff13f9988671,0x000c0500963fcb88,0x0009447add0b56dd,0x0005dc495e382a32,0x000c531e8e3d8f13,0x0003f8ab53419d64,0x0000000000000001}, {0x0005999b06e01bce,0x0004ac4c86e9d1b3,0x0001acac55379f5c,0x000ed5f60cf793db,0x000deecc778efaf8,0x0005438ff64587a9,0x000da09df4f7f063,0x00095b550b56ea7d,0x000d4a2f2118371b,0x000897f5ee846337,0x0000000000000001}}, + {{0x000e73c876ead4f8,0x000074f77e1ef006,0x00068e9d113a8d10,0x00068c4c79701512,0x000c8af63c9e4975,0x0001a355ba1ddb87,0x000a7f69e6cd38b6,0x0001a9ae068bd113,0x000bc3a633214952,0x000e40b4f3b0cfc9,0x0000000000000001}, {0x000dc3573f4bb5e4,0x000ce2ef087b7068,0x000ffeeffd386368,0x000053bd77e46931,0x0008c8fd63c43732,0x0009915ece7b6a54,0x0009d1980b122996,0x0000807d3a509f62,0x000abb80ee8c76fd,0x000ea6d20af82699,0x0000000000000001}}, + {{0x00023cc70a1b7646,0x000fb2fea8f69076,0x00051b6f61d27313,0x00053b59960e18ea,0x0003b52c79117607,0x0003c4870ae1dead,0x000b0ba34bd1f16b,0x000eb6ec0bc7a291,0x000e48716fbdf694,0x000f3b9ceb0fbb83,0x0000000000000001}, {0x000f4df150c14682,0x0004d73e71ecfad2,0x0001f4eed11e2bf5,0x000e8f7ba0e6130a,0x000d0ee611881177,0x0004b3748fb1ee0f,0x00018bc0f1b2681f,0x000d95b14d7b81f4,0x0005715bb9df9123,0x00010458047bf5c1,0x0000000000000001}}, + {{0x0007c0378bc40ed7,0x000325851811caa9,0x0000425fd5a042ad,0x00083181ae223e37,0x000dcf721e5a193b,0x000e3457f090e949,0x000bab83df6a8520,0x00045f22447cb654,0x0000dfbcc720ad35,0x00030064eddb51ec,0x0000000000000001}, {0x0007e2d48a4ebf78,0x00086d5a22dda9a9,0x0004ad7ed63a6603,0x000bdfd6f4eac86c,0x0006ea0b3cfe90e9,0x0009746e43f3d057,0x000247c38598edeb,0x00066c63f53c5a4f,0x0007de7ce9110d7d,0x000580edc5628f93,0x0000000000000001}}, +}, +{/* digit=94 [{1,2,3,..,}]*([2^376]*G) */ + {{0x000ceb75a39240f6,0x000cd422d17ed307,0x000816d46db1d003,0x0000a452acb6fef8,0x000cb9bbe93acb00,0x000e7044e1a33425,0x000fc32d94105ed8,0x00077b448d72bf04,0x000527b278a8006d,0x0003f3ce1c27af77,0x0000000000000001}, {0x000e21a0404fea41,0x000ba2bea8a562ed,0x0007dcaa390fe905,0x000e3be58bd01814,0x00024ad37906a8c2,0x0004147c934bd6ba,0x0008700ab35993ee,0x0003eb32c19654b1,0x000e9fb6dc4b6283,0x000fffefce4982fd,0x0000000000000000}}, + {{0x0008ddce89d919a0,0x000c8653953842cb,0x000510be22ec94ea,0x0004fc6818af52b2,0x000d36cd384c6520,0x0000918e38b08bd4,0x0008cd3bbca8f664,0x000f9b3d5866c2ac,0x00015b5a22e4fdae,0x00028fcebfa696bd,0x0000000000000001}, {0x00086becff5dbeff,0x0002b0a9f4f0a089,0x0002781857ab5bde,0x000f7d34f623a384,0x000ab2fc32d5df48,0x000357b29a5aed2e,0x0002a4f85d8000c3,0x000a47c091a8d7a0,0x0008c875883e2289,0x00004c78f3991d74,0x0000000000000000}}, + {{0x0006929bd70c6394,0x00085f2018c22473,0x0004be72094183d0,0x00086c43b8504d5a,0x00086b6f18e21a1b,0x000ad297dd4ff469,0x0000f368a9142ac6,0x000e09fe86beaf09,0x0008c552b3b6921a,0x000bce953006e93c,0x0000000000000000}, {0x00072ac6e0006309,0x00015780956c6baf,0x000c4c2c5f7fa741,0x0001eba55e9870c9,0x00060f57cfca17ec,0x0006e490ccc10b4b,0x0008a9db0618cc6a,0x000131fe5f0039e9,0x000970dbcf0f5361,0x000700a442baa6b1,0x0000000000000001}}, + {{0x0003ec842981eb23,0x0008fb16678799e5,0x000db8c26f2eb3f7,0x000307e41091298b,0x000c2265d3b22e09,0x000829161a79682b,0x00094108a62536ff,0x0002002fb6dedea9,0x00079fdbc3d369ec,0x0002baf58b2f20ca,0x0000000000000000}, {0x00056d9fea698757,0x00041a61419646f7,0x000308b017c99346,0x0002b76a5de627fc,0x000cb23ee7d29bea,0x000ab47900ba8603,0x00096bb85c794766,0x000df41684cc004b,0x0007656ed94d547e,0x000e302003142b8b,0x0000000000000000}}, + {{0x0005cdf0222a69bc,0x0005e1e346fabbc8,0x000e07629de2b094,0x0005724f76a1e2b5,0x0006b43bc885c45e,0x000d1f53506f8c50,0x000458ec4a247aeb,0x000ee8c49a8e9759,0x000961f24ad9f81f,0x000c780789ce81ef,0x0000000000000000}, {0x000ac3a5a536c8ac,0x000fe30d120ebbbd,0x00029a29c912f38c,0x000d27e5470f8673,0x000f785f54b6aa93,0x00069bc2c6347ce7,0x00091c1681c6e838,0x00015f8951322402,0x00054c132d778a68,0x0009133565718293,0x0000000000000001}}, + {{0x000f8e71a3d24acd,0x000de7f8ccaa4039,0x0004a565eb389f9f,0x0001445b3a88c7c8,0x000b1b88e20b6224,0x00022d8db00479b1,0x000369096695cdce,0x000d48a7013202fe,0x000e3713baba6a66,0x0009b65be868e0af,0x0000000000000000}, {0x00018718a6375d71,0x0003fe3e38b8c6c5,0x000ee16d3bd00a61,0x0001a73a8bab2dac,0x0001decd0dde75f5,0x0009a19d5d5d598b,0x0002f5dcc2ed8e1f,0x0007b66c768674ed,0x000717b781a03645,0x000cd5eb14d9fd45,0x0000000000000001}}, + {{0x0009a4c40a33f00c,0x000d2d3bef2c63e1,0x000922215ae57c68,0x000763ee03e85348,0x000337a4a0d2cb54,0x00047d23204381fb,0x000be443d9712227,0x0007d96627f6c828,0x000fb6b5f6d1199b,0x000a433d2170b3ab,0x0000000000000001}, {0x0001d3366971bb69,0x0007a38c946a2ebb,0x000b29fb103a111d,0x00047d3675997def,0x000fd82824e10a96,0x00029d6d05a45fde,0x000500fa9b94f37f,0x0002317e08c1e35c,0x0006ed9214c60102,0x000ee0a2afcd4a2a,0x0000000000000001}}, + {{0x0003291f02ce62ff,0x0005b8a731176ae1,0x00053e5b4c8c2f09,0x000d5a2322d8f01b,0x00092f09c90539b8,0x000c4c22646cfad1,0x0008df5016016f3a,0x0002500c56f4c2d4,0x0006618c9bed5731,0x000f52249d380720,0x0000000000000000}, {0x00052bb2164b93c6,0x00009ba854f0dba7,0x0002bd9fbffad821,0x0002cee339d0e928,0x000515cfc63fee61,0x0008541bf33aca9e,0x0001f0f0fd5f8231,0x0008dccc44f51df1,0x000e26d92e5d7f0f,0x000334dc204c43c8,0x0000000000000000}}, +}, +{/* digit=95 [{1,2,3,..,}]*([2^380]*G) */ + {{0x000df775a4cea698,0x00057fa877dfb590,0x000f628f95d0e8c6,0x0004b622c58775b2,0x000e755966c521f9,0x000b826bcad94ba3,0x000585e536e18362,0x00056a8bf64e1429,0x000c0d065ab9cff4,0x000c6b7ad254f1fd,0x0000000000000001}, {0x000be22413e6824f,0x0009f5a869cd6010,0x000399cde94b5cc4,0x000c96f6029dfb84,0x00068c7d0822053b,0x0006cb5f4bf3d33d,0x00090bad70bd72fb,0x000c5f85b78281e7,0x000fbd3aad6b87dd,0x00067e9bddab2fd6,0x0000000000000000}}, + {{0x000f0963f658551e,0x0002ea1215b91acf,0x000276c4b8c7ce3e,0x0002c599ae4d76fd,0x00006cf3a3b9f27c,0x00006667b3985a81,0x00095ab3dd5545f7,0x000e9ae8ea63e5bf,0x0008eb3015a494d9,0x00014b36df8e2aac,0x0000000000000000}, {0x0001e0605f96eb43,0x000d54ec384ae024,0x000bfb3e2ee19fc3,0x000c041bce0a2d7c,0x000b57e0aa0d1a5a,0x000f6adf1022b978,0x000452550508726c,0x000b77d6d81e1380,0x000536c9802fbac9,0x0007d16666d2c234,0x0000000000000000}}, + {{0x000d75964c31ca58,0x0004e22c167fba0f,0x0006865896879fb3,0x00085f113d2ac14b,0x000fcf92650326bb,0x0009815c6ae567c4,0x000703330478f2d0,0x000c2d4e045bb2da,0x0004917027450186,0x0001cb3d6ff5bbeb,0x0000000000000000}, {0x0006aee5ed6230d6,0x0006f57fa7f974a9,0x000d445b19954b86,0x000cc41b7edd540d,0x0002f6672b9eada3,0x0005adb45c3c302e,0x00085355ea3de1bf,0x000a70efd3fa201f,0x0002e28049bc11d2,0x000a9e4d97e0553d,0x0000000000000000}}, + {{0x0005aaa83e0b7193,0x000ef4020dd38cdb,0x0000a2db89cf16c4,0x0008b727a5cd426b,0x000baf5617c8e43e,0x00043d6e5823ddc0,0x000180e259e17f2b,0x000506737413c826,0x0004e741255f63ef,0x00009623e6163c43,0x0000000000000001}, {0x00095e5ae0c64c88,0x0006e547505a1996,0x00074ec16e26e1e3,0x0001814a43d8b0e2,0x0004c037ed439483,0x00075672e85b1a10,0x00064a05bc4b4563,0x0004f4e8604b9fdc,0x000d8d54cdb5b099,0x0008d7035e5850a1,0x0000000000000000}}, + {{0x0006358cac1e1dd9,0x000326ae97ec9d6b,0x00096931bf3f89cd,0x0008a8a20db33ff8,0x000f15df6988b172,0x0009cd5efc8b413b,0x000bb187876052fc,0x0004662d8014980d,0x000d9235f7d44d41,0x000edff0c8921456,0x0000000000000000}, {0x0002553d46a6bdb6,0x000a25d43349dd7d,0x00098c5095dc275f,0x000e81697e9d6a23,0x00021486070955da,0x000de66e5e004d62,0x00061fc887538530,0x000b0cbeddeb407e,0x000968acbb1e576a,0x000ee36df6504685,0x0000000000000000}}, + {{0x0001376b4df2834d,0x0009122c927fc01d,0x000cb3e3200f4b1b,0x00077db8d6a633a1,0x000324c991410544,0x0009a4d4ddbf0c1c,0x0004f89da008df0a,0x000df68e550730c0,0x000e5c51e1a10f51,0x0008da410315475c,0x0000000000000001}, {0x000c76b031581137,0x000f3f4ca12b9bde,0x0004e3a329753a8b,0x000499c86ef86a89,0x000c838a372fcc5a,0x000ec44e4a97d666,0x0000ea241b991236,0x0001650c8dbf9560,0x0007627fd4eb71cc,0x00078654f79c844c,0x0000000000000000}}, + {{0x000ce7225c38fca0,0x000cf6f1a6e96969,0x0009cc6268e77785,0x000308efc7d8303c,0x0008a6b0e52762b8,0x0004bf9968cba9dc,0x000db7c416fd26fa,0x0000e7d932fa8c4c,0x0002063b5de7df0b,0x000a1bd8e36d9447,0x0000000000000000}, {0x0002f11b9d88f945,0x000b6a528d0c6d85,0x0000491c222e34eb,0x0005246f572cf3b4,0x000826a507a97323,0x00051b49545419c4,0x000f246a45d14681,0x0008555cac591e9f,0x00067c66c74cf909,0x000c814d10852a3f,0x0000000000000001}}, + {{0x0004d6495109aae5,0x000c4b86a81e7f4d,0x0004316eb1054df2,0x0006877c19b90005,0x0007963ac12d941b,0x000bdc46a9dbe383,0x000befbe68280f87,0x00071d97d1dc04af,0x000aabbcc64f8fe9,0x0008543ef9d7ecfd,0x0000000000000001}, {0x00056ebb21998e32,0x000ab05f744a3f42,0x000c6587a4d462bb,0x000c14a18de305cc,0x00056d2c0e8c5f7c,0x0007f552fd1c2fa4,0x000165b93096db0d,0x0003eef9e935df5d,0x00013440e0a7d4ef,0x00020c2ecbc3b683,0x0000000000000000}}, +}, +{/* digit=96 [{1,2,3,..,}]*([2^384]*G) */ + {{0x0003ac5243ed86b5,0x00075f9805e79dc4,0x0002bee2dfe95a21,0x000284b06125c31c,0x000a0103195082b6,0x000cedfa4a2264eb,0x000afa325bc143e8,0x000ae3ae24853199,0x000ebe96963067c6,0x00096c54a7cecdeb,0x0000000000000000}, {0x000e3a5229434e36,0x00055f3a1a50446d,0x000644f2db4f7215,0x000ad43f6dc38924,0x0002239beb126b72,0x000840de05e7dd77,0x0002862d6caacd0d,0x000bce6fa639c67a,0x000087602ba53021,0x000679ec9b598271,0x0000000000000000}}, + {{0x0005ed4dab9a7e9f,0x0006797aaab2f5b7,0x000301593051ee37,0x000962a30b02f44a,0x000a1d622cf13021,0x000a7dfa0555a3ee,0x0006aca4fcd685c9,0x000ad2e750777a2a,0x0006aa905bd4c914,0x0008ffeec52d7b1e,0x0000000000000001}, {0x00095204a3f6fa1e,0x000c34539f85e4fa,0x000e8ddc16e36eee,0x00044a9e74599d1c,0x0007ab343c6c5502,0x00007951ae714c01,0x0005c8c4503f92db,0x0006830499e544d1,0x000188a7b94680ff,0x000147d6c4809fe7,0x0000000000000000}}, + {{0x000e6ff25ab97af1,0x000ec754ac7f57b5,0x000607a92403e802,0x0000eca9aece9592,0x00080834b57b8bd9,0x000e2fcd37a127de,0x000ed63155d3ec1e,0x000f99b11a3b9b54,0x000db302a147172f,0x0005d9290b10d36a,0x0000000000000000}, {0x000eee6089f16e1a,0x000772f210e83cea,0x0002496230bbfc3c,0x000c1fbbcea01caa,0x00032cc99a5937d0,0x00074603f91be511,0x0003cfecb00c641e,0x000ef833255bc0f0,0x00085cab2f6311c8,0x000c7fcc61e9c871,0x0000000000000000}}, + {{0x000f147189a2546b,0x00070bf89fcfd41b,0x000a403ed89c0790,0x0003f861a107b324,0x0009b4dade6e318c,0x00032b6327665e9f,0x00016ecb408e3b33,0x000c11ee2181f62f,0x000ba590467bbd1b,0x000a0f4b5440b9d0,0x0000000000000001}, {0x000b1aa7ade86660,0x000d1a8a32a33d9c,0x0009ae722d5edb96,0x0004c7770654bd1b,0x0001d03d0e5a5166,0x000b01ee816a4a63,0x00015843d1d9344f,0x000c1e1821b3c769,0x000c22520be2d285,0x000fe7e0834d6faf,0x0000000000000001}}, + {{0x000a30d8168852db,0x0007853d06621fd0,0x0000e561a31ba03d,0x000e2351f7abbee6,0x000bfa802185d2d6,0x000a8cb11d19a8eb,0x000b4f2b7623f602,0x000f149b3db4a55d,0x000399a66e1d6eee,0x000dded7de613b1a,0x0000000000000000}, {0x000694da4aed0861,0x00013409999d11ea,0x00021cefe8e175cf,0x000ca47b4e5a0420,0x0008274d934ac552,0x000e270720e741b5,0x0003c0a8bd69787c,0x000e75f9cc756f74,0x0003e654e1ea2208,0x00040979701ca5a9,0x0000000000000000}}, + {{0x000d12f4d256a679,0x000fb6f240706408,0x0001c6799f2d7255,0x0002b1c7ad7d86d9,0x000c6259fb2898c3,0x000dc9f2eb172083,0x000f61ec85a5a26c,0x0002303eee79dca9,0x0003cc24582cff2b,0x000018aea38a1c28,0x0000000000000001}, {0x000fee514ac3447b,0x00004db0b385f6f7,0x000785b0f880a482,0x0006256aaff858dd,0x0005224f69e65ae6,0x00099c8d9092f5e3,0x000a4d5b2e1cceee,0x00065201f6ee40cf,0x000abc908fefbb83,0x000f4461f21689bc,0x0000000000000000}}, + {{0x0006ba04a3b21865,0x000b257a4daf424e,0x000a3bec5e4ad4b6,0x0001bf9b577cca5f,0x000e764bad272e02,0x0003f73ae3883e3d,0x00078df5e21be44c,0x00046e6d9107b020,0x00009a9e8ecf5414,0x00062dbf7ce0cbdd,0x0000000000000001}, {0x000ed268a93dd876,0x0001345efa0e6741,0x000a124edec5cb04,0x0002301ceb5830ec,0x000c074b8d138854,0x0003717a195a4b92,0x00078d388cdf3e4c,0x000aa6e0172f6f1a,0x000474fe593756f7,0x00063e14f10ad2f4,0x0000000000000000}}, + {{0x00056d8ef5183d33,0x0006d4aef07505d7,0x000fd1d5c09dd4c2,0x00026645b43bb4e7,0x000876a817eb253c,0x000209c32af92f54,0x00083a63e205a086,0x000d802502f8b9b8,0x00069b5a7a6f9cb8,0x000e8d87089ec121,0x0000000000000000}, {0x000c2981d5c3f78b,0x000fd7c0b6dcff4c,0x000e2051e1d39135,0x00056f990f800ca1,0x000bbae12c766764,0x000fc5fcbf987a86,0x000db02cbf344cfd,0x000965a4f55ea853,0x000d8cf4b24b115f,0x000ddb28cffa2bf4,0x0000000000000000}}, +}, +{/* digit=97 [{1,2,3,..,}]*([2^388]*G) */ + {{0x0004c9f1b01bbcb1,0x0008c564ba5d43cd,0x000b6d345ac26289,0x000156220f11b91d,0x000dcfa53c395f80,0x000e8f0647eb32e3,0x00071de125c49a24,0x00035c7837015374,0x000bc6a877a9741e,0x000a3e1c5d3aa600,0x0000000000000000}, {0x000eae31d5cbf2fb,0x000ff21336f73218,0x00063097ec47555d,0x000e41ac8f16a8d5,0x00010c063790a928,0x000842e2a872cf72,0x000d214bed4668e2,0x000e7b5aab91e7f0,0x0002089cbbd94783,0x000d7755df6f3c47,0x0000000000000000}}, + {{0x000c45be80c5ceff,0x0008b5f3a736f81d,0x000f684853db7b94,0x0007af37a1d8a120,0x000c1e37602997de,0x0001ba866cadb401,0x000496a24e3e6caa,0x0002c3eae9d6cd94,0x00074e14e06f82a8,0x000343069d99834a,0x0000000000000001}, {0x00060baf525e3e5c,0x000adc3855bae42a,0x00020017824fbb6a,0x000d2439950ab7cd,0x0001396b971049df,0x000925d16b65cd1e,0x0000815f2ec4dd14,0x00099059e2e1d82c,0x0007231633ba03a7,0x000c17f35a3c602f,0x0000000000000000}}, + {{0x0005cd392892c72b,0x000067c79588a466,0x0003e61043554996,0x000e4fea3dc40ec6,0x0006245b592ed7ab,0x000d5fddb91366af,0x0005bcef5cf9183d,0x0006f2afe7d93c79,0x00038f789bd81e98,0x000a24ae25969d23,0x0000000000000000}, {0x00015df628bff28b,0x0008b0238f67e086,0x000debae13d569b1,0x000537b081c52561,0x000e3e637e8d5f7e,0x0000b558a9b4dba0,0x00092e9e6c338cb1,0x00054c7742924ded,0x0001b877e357069a,0x00077dfb12df7675,0x0000000000000000}}, + {{0x000eac10daa6fc06,0x000a451d0d93fa05,0x00030dbe3663fb80,0x0003df5569a67246,0x000583a7b7740137,0x000a1bf5763b688d,0x00007976f4ce0d19,0x000972348a80c203,0x000296b9dd874e74,0x000ad726fc872424,0x0000000000000001}, {0x000626a33acca649,0x00019c0b206a34a4,0x000597e1cfe661fc,0x000915e61f98c11b,0x0006400c41adb010,0x000ed21859bdcb2d,0x000247507de82c2f,0x0007ba1295daeffa,0x0000842d673a4f29,0x0001721fc083b457,0x0000000000000000}}, + {{0x00034490e59e8714,0x0004db94a827c594,0x000be5c43f7b8f49,0x0005c1ed99f38332,0x000c89e5a5eae6d0,0x0007a328c3f873b0,0x000b195eb0205cc5,0x000957c8e1b9bcde,0x000a9c05764ec15f,0x0003785ee6082c58,0x0000000000000000}, {0x0006efc5f7d22a96,0x000c221343eb9e1a,0x000752365f225594,0x00006ed92aaffd4a,0x00047b4ac0a51a79,0x00034752a1b444db,0x0000b01d86935b36,0x000ff91905b43171,0x000a16a9f33a34ae,0x00098febd2ea9993,0x0000000000000000}}, + {{0x0009425bd3be24b1,0x000ddf604bb70186,0x00004732993f7d31,0x0003e481243d40e7,0x000cdd085631cbfd,0x00020a779443a447,0x0005a3d17a4bd6e9,0x000c2ba013a6f159,0x000091ba40454351,0x000bd45892d66dc6,0x0000000000000000}, {0x000413e025588ac6,0x0006b5fdc28cccb3,0x0001b7df9aa499d4,0x000dec43b5bc5fae,0x00066d0478edbc5a,0x000c5c7523db595f,0x000f66c3689cc921,0x000369286e3460ae,0x0009f5650aae055f,0x000ecf05c2d82ed3,0x0000000000000001}}, + {{0x0002dc4c335595b5,0x00087d3146806d12,0x000280502c85e0da,0x0006080ca34c63d6,0x00057bee19e4fbfb,0x000b329c24618627,0x00059c63cee44932,0x000729a1018b673d,0x00038096ab196705,0x0008deabcefcd004,0x0000000000000000}, {0x0008d702c45db29c,0x000164a83c7ff2f7,0x00004bdcc8d9c10d,0x0006a51badde1985,0x0007b3d628a8f0d9,0x000238514e884060,0x0003ad2af9123d94,0x0001c02c79997897,0x000547f0e64e4ad3,0x0009546706bd2921,0x0000000000000000}}, + {{0x000474c793f4e626,0x0001b9f27eccc505,0x0004061bf3c9bbd8,0x000776661385eed6,0x000ca2d5cbcfee54,0x000b0a8618a0f415,0x000c45418675f88a,0x000e0d5df7ae47e7,0x000f8808275324e3,0x0005bfe818ccf0e2,0x0000000000000000}, {0x000d8f452acbfbda,0x000031ef224de6c2,0x00070dcb7f79ce12,0x00097b18d958660b,0x000224dfd1c89c45,0x000d69ce10da0fa5,0x0001b65989afa822,0x00094e1b3fa146e8,0x0002ae217dcac503,0x0006327d3eef4183,0x0000000000000000}}, +}, +{/* digit=98 [{1,2,3,..,}]*([2^392]*G) */ + {{0x000f424e1d9c6487,0x0001fab2d1847091,0x000c18abe11482b3,0x00002a204548d244,0x000d2901117bfc9e,0x00086c34a4b1dc1c,0x00025a48ee98a6d2,0x000cb76b3ae604c3,0x0001c8298db518ae,0x00008fb7194b2498,0x0000000000000001}, {0x000055d976a5cca1,0x000a2cc7061a3bfd,0x0005a667bf88a107,0x00028dc3af0a63ac,0x000873e8641fb210,0x00040a558da80d94,0x000fc0963f8d8c7d,0x0009ccc465473acc,0x0005ce362fbd5307,0x00081d15006f15e8,0x0000000000000001}}, + {{0x00022141cc3287fc,0x00038266149a76c1,0x000fdcc4f6ec602d,0x000673e316b23844,0x0002f7ff0591cea0,0x000226449753082d,0x0008c9cafeaf6b58,0x000801a84f6bca52,0x000738672e240363,0x0000fb54c4174c43,0x0000000000000000}, {0x00005f340ab8f558,0x0003c50b6de62a42,0x000c67ea2a5a8485,0x000584f292e0d583,0x000976bb7a441296,0x000e6eb31fa9f0cd,0x0005886d0d33dfac,0x0005ca9b5dbb850b,0x0003bbd95e75a3fb,0x000aa9fc35ee4214,0x0000000000000000}}, + {{0x00048296df946f82,0x000d1ae0f7178948,0x0009fea01e8f3835,0x00032c83af761a04,0x000c81060dc76c7d,0x00037519156c5ff4,0x000bd4aec6a8a45c,0x000cdf6166cd6f1d,0x00042edd4a64bcec,0x00087353c4d352a9,0x0000000000000000}, {0x0007c5d100fac674,0x000db9e757c12a95,0x0005aae530260819,0x00099d6efbc64c70,0x00069b00bbd4972a,0x0000b755c13bf68d,0x000c9bf125fdc71f,0x0002e7e830894502,0x000fe09937e20c9f,0x00002b5fa7bc0dae,0x0000000000000000}}, + {{0x0006f3e4a3b653b6,0x000d1a688f6e0a4c,0x0009e0c6a622a9b6,0x00092759febdd4b3,0x0007de14d66ca7fb,0x000a2edb8e3d698e,0x0001ab808ea4d110,0x00080f85570610b2,0x0004c29e8f8405b0,0x00027dadf7ff6310,0x0000000000000001}, {0x00057c2f52f741db,0x0008e2e671ed8847,0x000d5288875b3801,0x000d96a8629331d9,0x0005a7e602196279,0x0001f2dc09559eca,0x0008fe5f274c1468,0x0006483d04249681,0x000f5286b1c8246f,0x00077944ba105276,0x0000000000000001}}, + {{0x00065afeabf73b11,0x0008c74def9ab376,0x00022e8ebbf2f73b,0x000cbc3cc29566a6,0x000e491e3c34a56e,0x0005e3e30062fb22,0x0008f34bd61c9faa,0x0006ad9002a6b766,0x0001e57f55fbc947,0x00052212e9e41cf0,0x0000000000000001}, {0x0000895f7a4eff76,0x00077650f0c0269a,0x000b638552f2435d,0x000cabbe1734cb6d,0x000ac1912708cc1d,0x00051cb37cd08219,0x0002a65eea8444e1,0x000bbf996f86f52b,0x000fc6bb767f7430,0x000d61b13f4e2c8e,0x0000000000000001}}, + {{0x000d5ccc9d50240d,0x00084d2e5496b2b0,0x000f884405e473c3,0x00057903c51b5ae8,0x000d55afcc0675e0,0x000125af4b250a76,0x000937bc2b1d7e99,0x000a633470b9206a,0x0000cfe28137ad4e,0x0002cd8906210714,0x0000000000000000}, {0x000877153680ec3c,0x00019913626b5dae,0x000bd89f532b2d72,0x000d578470af1c82,0x000b3f975bb94d7b,0x000f53a6076b8092,0x000db22bb5b744d5,0x000f43f924c34cb2,0x0006114e078b5812,0x000fb3e3de49501e,0x0000000000000000}}, + {{0x00028536905d5e34,0x00092fdd83e93bc7,0x0001a64b28a1f75a,0x000a170fe5a66cb3,0x0001e6a59754016b,0x000c5178f6263ade,0x000bc78f0892f5d7,0x0002723285c0f5f3,0x000ce420f8de3807,0x0004c264b36ac9d2,0x0000000000000001}, {0x000334fb73061393,0x000f6bbeabea50b7,0x000a60e0b4b57374,0x000565e15377dc7c,0x000ef0ff94b0e964,0x000e47e49a96f0ea,0x00030ac68d3dc2bc,0x0009347ee5d6453c,0x000eac1f6901d599,0x000086abf91bda19,0x0000000000000000}}, + {{0x000d441660f7e89b,0x0004d20a8f4b5442,0x000f7bf31e592476,0x0002835026e4af60,0x000359fc53bdf7be,0x00012726ea080568,0x00075b1726e147ea,0x0001ca2a0207d5e1,0x000322cae833e591,0x000e936cba51a14d,0x0000000000000001}, {0x000a1d6534e7b937,0x00065ce0948dd2da,0x0002f88e2acca2b5,0x00091e6c94ccb3a4,0x000c7d8fe477585d,0x000807f46db59ceb,0x000b940f42378210,0x000e402ecff0fc9e,0x0007bc598d173f94,0x000f16af975145bf,0x0000000000000001}}, +}, +{/* digit=99 [{1,2,3,..,}]*([2^396]*G) */ + {{0x000942a4c75e9fe7,0x000c673dad29e115,0x000e6be55a2350de,0x00045659ca3c399f,0x0003c87e22652712,0x000bd4c4458f51c6,0x00057db758ae1a11,0x000c547db810319b,0x000c8ba847d5c89d,0x000239959a5bbe62,0x0000000000000001}, {0x0003d490f3876f02,0x000521482b690e8c,0x00083aada0850d48,0x0004a53582c13331,0x0007bae5a342545c,0x0001c50d6f31c146,0x000d97c2d093b815,0x000e82d6fbdb84a7,0x00053468edb41ffb,0x0009e6ae0e9fad49,0x0000000000000000}}, + {{0x00060773f6c223a7,0x000ee1e8255739aa,0x000672547b158459,0x0000639d3f4e65fb,0x000635059b89e003,0x000ffb7b9ac29a4f,0x000cad3267e18233,0x000a7f7d6bbb6854,0x000d91b6e79c3b99,0x00065ebec22c4720,0x0000000000000000}, {0x0002fbb0f6be8071,0x0006dc307d9b73d7,0x000c6fa2f527f8c4,0x000e537cfbf3d06f,0x00018d7888122d62,0x0001ea61a84ebd38,0x0005532479a6f831,0x0004a4bf3325eafa,0x000717809c7a3155,0x0000399520a8095a,0x0000000000000001}}, + {{0x000b807898f2ae67,0x000d7e4f60fc8927,0x000bd2ecac1c97bb,0x00075b365b008578,0x000f53b54d53eaaf,0x000e5a0ab86540b6,0x00009c6ac54c1d9c,0x000267e6b65d52d9,0x000a061126607ea0,0x00011c0a94e0f97e,0x0000000000000000}, {0x000dd52c7077ac64,0x000e6849bb24e97f,0x000e60101c7fc9b8,0x000e52f0dcbe3ce9,0x000023c779930c2a,0x00050df58185f016,0x000a6864a7c2cfea,0x000d52f720dc8c89,0x0006aecf1e2d3b3f,0x000fe51ac6cabd56,0x0000000000000000}}, + {{0x0002f47341f417ba,0x000cd8bb740324e4,0x000e45bfed89909b,0x00089a7fe9550616,0x000b7861f9828778,0x0008946a71446a53,0x0006502fbe6cdbfc,0x000f70373dcf7291,0x000b59a0e59c8ba5,0x0004ed07606ee31a,0x0000000000000001}, {0x0003f237a7cf7e71,0x000f61b5ddd50efa,0x00056f3a63a0f211,0x0004dae68319e664,0x00090e5acc6a3312,0x000d6c5fe3f2c7d0,0x0005f435cc8df625,0x000420f4229fa016,0x0009c92c95adf8ff,0x000c03d951affc2e,0x0000000000000000}}, + {{0x0008e856f1a63237,0x000c38cfb4864e09,0x000a9b6c8ef2a48d,0x000565ee070c9954,0x000b247d25c31c3e,0x000d383653eec5d7,0x00033815ac0ce45d,0x0001d40035f31f5f,0x00016fd77486c728,0x0002145bbe546eb5,0x0000000000000000}, {0x000f8a00f9535f58,0x0006793f432f2f0d,0x000a22b5ed0740ff,0x00046e71ff907935,0x0006ed013a6683d4,0x0006c4dc5feeee1f,0x000e49d371167831,0x000c07fabe848ed6,0x000dbccd8d710493,0x0003939263e99e29,0x0000000000000001}}, + {{0x0009123d0b7caf2a,0x00010c9813e058eb,0x000b14ecd8d170c4,0x000aafb543a445ef,0x00066b13251ba12c,0x000a58ee44692c76,0x0009f4193734f736,0x000a0ff39b6d1ecf,0x00049d16c582e2c3,0x000a54bc874e11dd,0x0000000000000000}, {0x00086c1422f1debe,0x000be6be161bed99,0x00094c11992adb85,0x0007d02a974392b1,0x000dc1355dd0b472,0x00001779ff9ef84f,0x0008dc1dbbcd1c30,0x0007615360f70921,0x000cd90cece2bff5,0x000a085b2b4772a1,0x0000000000000000}}, + {{0x000bac8ffc9b1cbb,0x00041fbeb1c7a5f9,0x00032bb744d70f6e,0x0006377a1f50a7aa,0x00008611c61b42a6,0x000ce936f3324a60,0x000a084c3dc201c1,0x0002b70db700c5bc,0x000f0caf347988c8,0x00025e2dfe3675fe,0x0000000000000001}, {0x000fee427e9f9424,0x00069a165d8d1c76,0x000dc1fbe1e937f2,0x000db180dfee35cc,0x000b55475d4c9745,0x00036d0a2fefc6cd,0x000476726ccd4e8b,0x000f3783e580f7ab,0x0005d079b31ff3c1,0x00009ced18ab19ce,0x0000000000000001}}, + {{0x0000806a0ffa1183,0x000b368c8ad93735,0x00045322006bc207,0x000356cef3feb2a7,0x0000d9772041b29b,0x00015326534db436,0x000c3a4ffd400337,0x0004525bb0cb62b4,0x0003dfc1aef8cba9,0x00023c5f95e7e7b2,0x0000000000000001}, {0x0009f0d5faafe7a7,0x00079f056236883a,0x000e0f2e02fe7ca4,0x00020a75821e669e,0x000fc3208dc12d93,0x000c95bd4d2a90f1,0x000127ab836d5d0a,0x0006a56f1f5b0f15,0x00053533b35a8c80,0x000e1db5d6ee484b,0x0000000000000000}}, +}, +{/* digit=100 [{1,2,3,..,}]*([2^400]*G) */ + {{0x000b291af321cc48,0x0000d263480c29b1,0x000ec9060276afae,0x000489d0d90afac7,0x000ec62d3da37067,0x00088f38b3e31b78,0x0007f35ff5fafe7d,0x0007885361013dfa,0x000270f897a6237d,0x000c2a42a2eac980,0x0000000000000000}, {0x000b6527c69198d0,0x0008c038b2196095,0x00056c8573aab3e2,0x000c299349dbf002,0x0009c016fc238b06,0x000c26c63dc550c5,0x000712822cb43957,0x00044a5765b7d6c8,0x0000be87f42f34ea,0x00061a9436ed5036,0x0000000000000000}}, + {{0x0006c0f3c9200410,0x000c1523b6d0c7cf,0x000b2a524b701323,0x00080e1d445c4f05,0x000cfb721bd24fb2,0x0004d74f5043a450,0x000c3ca459a36903,0x0001f8a997769ed3,0x0004569349bd35cd,0x000fa7a1b94559af,0x0000000000000000}, {0x000479e9fda50d86,0x00039193e5dd5ac7,0x000fcfc382ffdaf1,0x0006e937727251e2,0x000819f976e0e477,0x000e0dea37faf936,0x0002b3218ec38c97,0x00020308bb264566,0x000441534d581e3f,0x000046c275dc071a,0x0000000000000001}}, + {{0x000cb5968e20ed2c,0x000a52702c5bb89b,0x00033f897addfb47,0x000f030ce16c51a7,0x000945e8bc092078,0x0000a224a9b9a4c1,0x00074fb0d2a2dbea,0x000a00b01506244c,0x000403180ef3b3ed,0x0000d544f09c72f4,0x0000000000000001}, {0x0007f0289c261b7e,0x000d803c0211ff4a,0x0001ffe93b188323,0x000b503181a127a4,0x000960bd651117de,0x000f238b1565ffd2,0x000706280cef133f,0x0004ddb33d18643d,0x00057a46393ccc6e,0x00011d1fcc4678c9,0x0000000000000001}}, + {{0x000cb18067eb6c9c,0x000904e0e232321c,0x000c2c362eb5eae4,0x0004f20ada675b34,0x0009513d2fa912c1,0x000c8c7ff960f4ae,0x000ea3278df20646,0x0004b702cc146790,0x000b87bb57608da3,0x000f1fadae0fb9e2,0x0000000000000001}, {0x0006a843b0ca7a84,0x000ffac89f77d5a2,0x000265d14c35a368,0x000486e7957c89a9,0x000f9514b7e05bd1,0x00037cf3d5a9030e,0x0002008b9ea39985,0x00050c45cfba4fb3,0x0008d5a1561ff956,0x000bc01cc6a56407,0x0000000000000001}}, + {{0x0005bb52ea9ac7ec,0x000e28f7ce0ec366,0x0004c059fd569d2f,0x0000e89276b354dc,0x00013674b639e129,0x00051c92206d8283,0x0005fd8d62852509,0x00083a0ba16eee81,0x00023ff408ee3851,0x000e736678fced53,0x0000000000000001}, {0x000a8b28dba67d24,0x000216ba84ecb673,0x00034998afbbd048,0x0004e06cfb264967,0x00064c024c958fcd,0x000c3e07fdd668c7,0x000e902ee5004559,0x000c7be484240ea9,0x00085d1cbdf78504,0x00001fc315ffe9b1,0x0000000000000000}}, + {{0x0003f67e6d554604,0x000a7edbdf25d6db,0x0004a86faf823503,0x000561d458cbd82a,0x000fd50ad1fb2727,0x000d57e2f00994b8,0x0006a571b2b47251,0x00025dcba3cd1573,0x0003351634df5819,0x000f90f716e579ec,0x0000000000000001}, {0x00015c741fd15e62,0x000782e4509eb436,0x000bb1dede8ef754,0x000e32d87a793f6d,0x000cb27d972fea02,0x0000af4ace00b65e,0x000665980ede0c9d,0x000f6c809dcb9681,0x0003f6f1f979a653,0x000fa70638c8e694,0x0000000000000001}}, + {{0x00069573569a82f9,0x00074c79907894c3,0x000923a4f546a942,0x0003c148a698895f,0x000c357afe3d1621,0x0000597be114eca3,0x0008bde57638ac14,0x000ab1f30c4d2325,0x000c1e648b9d09ce,0x000b5b544e3974e2,0x0000000000000000}, {0x000a45f392d296b8,0x0008740111ad4028,0x000c3e262fdbe28f,0x000c3453830a9ee4,0x000ae0fdaa4f4e3c,0x000db8b9c8044def,0x000827b06665f64c,0x0004b0bfa5e94a06,0x000288ab3926f336,0x00095cd9d3c3ecaf,0x0000000000000000}}, + {{0x000b181f2f210670,0x0009ac047db30c5e,0x000f0b9977abb73f,0x000685fec5355db3,0x000cba356655da26,0x00050bb7fd48c1a2,0x000094ac2c2dc459,0x0002437ff8a8e766,0x00026425d80146ca,0x000d215b7aafe50b,0x0000000000000001}, {0x0008a54b77260e44,0x000200683c3c461c,0x000806c758fee244,0x000ee02fb90af5d8,0x0005167ac6f6571d,0x000f1dfed253aeab,0x00051fc762d73380,0x000f059d556559bf,0x0001430491432973,0x00077ebf133e93a9,0x0000000000000001}}, +}, +{/* digit=101 [{1,2,3,..,}]*([2^404]*G) */ + {{0x0002ff226442343f,0x000cd833f176501e,0x00095759918597f6,0x0008de415f1a7fb7,0x000e4316d41dcb51,0x00029d89c6966644,0x000513d7775eaca8,0x000a9d45da4eed7a,0x0002852aadd14ef8,0x00062ec016fff623,0x0000000000000001}, {0x00091f95c7b230dd,0x000a732cc46d0d07,0x00004775f23d4641,0x000d9d15b9dcdfdd,0x0007a727ace99c9b,0x00077fe3e5aec6f6,0x00023beeac1ee2fa,0x00008f21d63275b9,0x00065885355852cf,0x000ce1be6d4550b6,0x0000000000000000}}, + {{0x0006e321251c61dc,0x0002560a1fff242c,0x000a45d55894b5a6,0x000bc8f1bc1ece0d,0x00099655945af852,0x00081d51a6f4152e,0x00048184573b7d9f,0x000f69e42e8015c7,0x000b2c20669dba53,0x000e9f9624512355,0x0000000000000000}, {0x000c96019553b866,0x000abe8a5146d011,0x0006c8e83c7c8d9f,0x000d33f93fede45c,0x0006fb87d2fad3d5,0x0007a48456e1fe30,0x000e6e9f030c2436,0x000ab8f59e2c2aa7,0x000e2ecee8097392,0x000ce7dbed7e8f7a,0x0000000000000001}}, + {{0x0009869c0eb3066b,0x000607798fe984da,0x000507796822415b,0x000b35e4cf4e7bb0,0x00043514e2eac3dd,0x0006f5f2ec73d5e0,0x00073c55dac4fc5a,0x00009ae9d9b66b29,0x000e7849157dbfd1,0x000a5482a9437d4b,0x0000000000000001}, {0x000c4e943ae95512,0x0006cf652253cdb5,0x000d6ec12d70a741,0x000569eacfb8355d,0x000eedc557ace0f2,0x00079ed65a726737,0x000cbaa427929f79,0x000f9f7b12d69985,0x000f61768135719d,0x000ae5a402492b60,0x0000000000000001}}, + {{0x000feaf2d1e3892c,0x000ab68c7ed96e8e,0x0003cb959b9f3e2f,0x000c2e34fe65989c,0x00089b397dfd24ce,0x0005a4f7a72a8210,0x0003d4d194fcfc29,0x0004009eac36cd18,0x0004df54ac2005f3,0x00037ac4355ce338,0x0000000000000000}, {0x00018f15a5288002,0x00084aab158f0c62,0x000919d3c1cc9db6,0x000c654f22157c5c,0x00061a5d7e7c5733,0x000dc89cd41bb67f,0x00046690cac1f786,0x000f2b55f183f6e7,0x000f41e4cb445fa4,0x0005a969c4dd429d,0x0000000000000000}}, + {{0x000f3df64800b6f3,0x000d7480b73133bc,0x000b600425660d57,0x000b837e3aef4df6,0x0005fb5d2c2dd02d,0x00011fe018b03d5a,0x000c71322317085a,0x000d374ad3a452d3,0x000a4d81aa830346,0x0004a3299709ce7b,0x0000000000000001}, {0x00016776ed8701be,0x0009a6af0a211f00,0x000ee5799e2d0b99,0x0004ffaa89dc73ac,0x0005974371ca9e1e,0x000e0cc77bcb98c1,0x000c6b4ceea4b327,0x000a8308bd6b7617,0x000c8a4f2fabfb14,0x0006930491f45b7a,0x0000000000000000}}, + {{0x000d9bdcbcf79471,0x00074d3dd4ca53d8,0x0001af7d8d51306c,0x000b82f03e680d58,0x000a7884ca0be9c6,0x000c62e3720aacdb,0x000ad9ad633f5955,0x0000c84d067a1c4c,0x000e24eee54e3c55,0x00019dbe3f67b54f,0x0000000000000001}, {0x00099b839c026b9e,0x000bc7d75cb7b6b9,0x0005e6b4aa8a5275,0x000156cdfaa9f40a,0x0004a1992d1c2e6b,0x000b18092816e51f,0x00027a900c94afd0,0x00010f9d0fb16b34,0x0008f98b409eefa5,0x000aaed3cae46309,0x0000000000000001}}, + {{0x00060d5e996dc11b,0x000619082845b56f,0x0006ef36f7ab0ecb,0x000d028f81fdfa6c,0x000060da295844af,0x0009596e31cc9ebb,0x000308c32eb79211,0x0001ea951754105b,0x00008750f063690e,0x00083b8a021ee964,0x0000000000000001}, {0x000d813e43ebc1f3,0x000af78ecca7ac06,0x000d8eb52a4c2d59,0x00067d3099d75877,0x0005b00d48668cb3,0x0002755481aaf570,0x0000b8ddd277a751,0x000dd4573c6cfa3c,0x00075e83624bf68a,0x000ee89ee03e9ce2,0x0000000000000001}}, + {{0x0001adc31d17fe65,0x000ba5bb3a93b688,0x000b603dd9e8ce1c,0x0008b0cf4f5b70c1,0x000175f958dd3aed,0x00070f44e15eae25,0x000177aa5b942f5b,0x000302efb949c526,0x0002ba3a2c8dd115,0x000b89f9288a9513,0x0000000000000001}, {0x0005972ebede20db,0x0005b1bc841aedc4,0x000933a99b87853d,0x000597276e1536aa,0x000a0238abf3c852,0x000485ab1105488f,0x0006d521debe07d8,0x0002f1ad18f16d6f,0x000d3c55a54637f9,0x000804a2b58773df,0x0000000000000000}}, +}, +{/* digit=102 [{1,2,3,..,}]*([2^408]*G) */ + {{0x00085142795b0fc9,0x00032b75a8973a1f,0x000125d27c2f65e5,0x000245efb7e6ca7e,0x000a3d37a1c1d680,0x0008ed8871c0ac3f,0x000f92273ed1f61c,0x000f1c0619b125a3,0x000c151e1baaf99b,0x000b5fb9c92ca12f,0x0000000000000001}, {0x000d45f1302c2800,0x00028a46eca65c4c,0x000181d940c2f16b,0x00008156dae561c3,0x000ffdb51b5dbdef,0x0007d0f3f05aff9f,0x000216756731470d,0x000d3e4323b09f64,0x000c256f1c5c736f,0x000c46af757ebac2,0x0000000000000000}}, + {{0x0008b99d3a5cf086,0x000a6f7dad9f189d,0x0009613956296f2e,0x00029ebaf5d410b4,0x000d4c6b1f46d86c,0x0001709ad92dbba6,0x0000cc09de07504b,0x0006c7c9ec95eea8,0x00007648647d01eb,0x000b3919b1d6cd99,0x0000000000000000}, {0x0005f9f34e61ba7e,0x000eff53cc24a00a,0x000672781ea5e367,0x0005266f275cfce0,0x0009992d98139edc,0x0002c0efd50d9e20,0x000de18f3d9cb26c,0x000b647d23fe687b,0x00054a71ad97b9cc,0x00027a258eaff20c,0x0000000000000001}}, + {{0x0008f39dfcb8ed4b,0x000811922f1fcd37,0x000a2846f7edab95,0x000566857a64449b,0x0005d6755b91a9b1,0x00033e748b542e81,0x00055f4eecb18a57,0x0006c4663a3a4f59,0x00052acaf4bb5b32,0x00079a0d2cfa0bdf,0x0000000000000001}, {0x000a0b89e0ca131f,0x000be75df1d52db6,0x000534480e6cb8fa,0x000be7af1d438291,0x000ad1a493673eca,0x000a16c7e34998f0,0x000d3ab56804db13,0x000479fc142bd461,0x000daa988aca4c3a,0x0001acd3bd93e84a,0x0000000000000001}}, + {{0x000cbad8f99ea394,0x000cf3fa23022a30,0x0009f3a186b0f3c6,0x000e922b33420e3c,0x000c1bffbbdb1dc6,0x000aa59cdeeac227,0x0003dd943d5b8787,0x0005513a5be5e367,0x0004c0fefae77a5b,0x0003518e4c10fcbc,0x0000000000000000}, {0x00024505728229a8,0x00014b020fe0ed2a,0x00039e8625b5e8e9,0x000ac893dbd2dbf4,0x0002a5bf5b95c3df,0x0009c6d879c2cfde,0x000a75fca30a3152,0x000f3ac05ce905a9,0x000445553894b84c,0x000dc2eb87696cb5,0x0000000000000000}}, + {{0x000c1e6489e4e3ff,0x000e40fadb280ee1,0x0009bea8383ad81c,0x000e1b3d235f576b,0x000a3198405d1a52,0x00058352c1e2f66a,0x0004288cd9077fa6,0x000dbd50c9d00a90,0x0009bd9a7d893793,0x000b363fd16ecce4,0x0000000000000001}, {0x00020eac52973702,0x0003e0c70e76207c,0x00006b2a996d0f74,0x000f4f6a44bb0744,0x000df28bc6807b4d,0x00017b088a4a4664,0x000ec1355d57eb8f,0x000182cf9ce6cfbc,0x000610a314e418de,0x00010173ffff5e3f,0x0000000000000001}}, + {{0x000165051d386e1e,0x000bd47b826f3a9b,0x000a1c2b86d2360d,0x0009b8835ea5cf34,0x0009783bb9260611,0x0002b789b3e982a5,0x000e987100210011,0x00097fc2b9ab3e6b,0x000ba0e81d76b916,0x0007fbcd1d8d4518,0x0000000000000000}, {0x00091e776c559b38,0x0004c1e4fe7c517d,0x0006b3ca068cf1e7,0x0001a6fbc371e38f,0x0003b1539a3d7c5a,0x000cd0c3d50e8468,0x000c7e40ea4660b7,0x00012b9d873faeb0,0x0007f3ea3f2ff663,0x000c8c52e58fcf13,0x0000000000000001}}, + {{0x000e0d1c0e7b0a6e,0x000182d5a79223c1,0x0002d07160d41c08,0x000de95d46cca38e,0x0004d00dd9df759c,0x0001f3ff3dc94e0c,0x000ad18e4b33fc34,0x000d2cfdbdfdd807,0x000c70a120714770,0x0005cb86265c3704,0x0000000000000001}, {0x0002e095e7588e93,0x000bb0fc7a7538c8,0x00049b1bf8ce184d,0x0006eac46bad884f,0x000da577205521af,0x00073592b9bc40d1,0x000dae6302c8fae5,0x000e9a408dc07f7a,0x000d86c203a973c3,0x000db4c1145f0edb,0x0000000000000000}}, + {{0x000b134fd6bc3c71,0x00030305a92256f9,0x0007ccfce0b23245,0x000ca36a6d8cb621,0x000236d0ef54fd61,0x000a182b1b210c1e,0x000e2c48ae4f2531,0x000aa16671b7b1f2,0x0001cf556d29f38d,0x0001c83fa6c8eaae,0x0000000000000000}, {0x000a18df67396e49,0x000978a098406db9,0x000d15a5ed3d588a,0x0008786d781ea818,0x000c4ad06fce15e6,0x0006d7a550f98680,0x0004140981589bd6,0x000f7ff83976d3ff,0x00088eabc6ffe6df,0x00031647479f189c,0x0000000000000001}}, +}, +{/* digit=103 [{1,2,3,..,}]*([2^412]*G) */ + {{0x0000d7e3378fb507,0x000c9bb0731c42eb,0x0005dc372a3657ba,0x00074ab3d967282a,0x00057f9ac8856a93,0x000b740967bdf210,0x0003024fec8274b3,0x00015596459a5693,0x000d21c1794a1687,0x000a98ef7bcfc7c8,0x0000000000000000}, {0x000af7b9ab0a89f0,0x000a24bfd8b660f9,0x0009cb13ed97b728,0x0000fd15ee5e0227,0x000febd3b7d28a45,0x000367bf5b972ff1,0x00091b608f71ea2f,0x000f496276edaa41,0x000a6a4c152d016b,0x0000bf52e7daddc4,0x0000000000000001}}, + {{0x000ed176dc4c781a,0x000f2149979e6d8c,0x000b3c390a71d8f2,0x0009ec42d1cc9018,0x00013805d407dff4,0x00092c79f656592d,0x000250a69b4fae8b,0x0009ea40b75d7816,0x000e49fbb9c23c18,0x000630012080c698,0x0000000000000001}, {0x000297ec2f3d27ef,0x0009b4394adc76de,0x000084a2dca39d2e,0x0004162fa4a3c98c,0x000de4df52d9fff5,0x0006af6c27847a48,0x00049729a4d9dcca,0x000b96ed3609128a,0x0002001168323c41,0x00051e81fed2290a,0x0000000000000000}}, + {{0x00023ceeaf6fda5e,0x000fb751aba8d27a,0x00058878762241c7,0x0009d28160069d96,0x0001830ade2dd51c,0x0001c3eb509b6317,0x000cb86f909879a9,0x000dee7eb48aca8d,0x00028bf799244bc3,0x0009202a06470538,0x0000000000000000}, {0x00015f7fc2843df9,0x0002f53ba48f85a0,0x00095ae129c2b6a1,0x000ddb2a444e10a6,0x0006aecfba54d8ae,0x0007c39b4f0e8bdf,0x000e6010a72c4d1c,0x000d5cdfd0f373b3,0x00068c9e099b50a0,0x0001c8bed1929d51,0x0000000000000001}}, + {{0x000c2c46683ba5b5,0x00057c57128a2090,0x000dbf610a813452,0x000009fdd16c4a33,0x000c78f1d5b65bff,0x000560ad02b49af8,0x000ea450eb8499df,0x0003a52dc630fb45,0x000da8ac57e35202,0x000fb72fd6cb3d8a,0x0000000000000001}, {0x0006d77839d10202,0x000f1f4a52a42a8f,0x0004175b2fd3f44a,0x000ac14905fe7f14,0x000701757d0c0079,0x0008ae6d1c475fac,0x000d56b7bfd93878,0x0001b7dbf13b33f3,0x000d1df20cacad13,0x0006098aef62c8eb,0x0000000000000000}}, + {{0x000224c02776a096,0x000fdf0428bd2668,0x000824486a9c4320,0x0009f3de8bb8cb98,0x00008a99c85515ad,0x00087cd9c5ea0fc3,0x00030bd0c213cb33,0x00075f7ddf36e0e9,0x0008b09a16a3e9e2,0x000ff92ba0c69ed0,0x0000000000000001}, {0x000dd8b8dacd787a,0x00044526b1b4ed23,0x000c4fcde2872824,0x000a0aecc5884baf,0x0000edf7e8ded34b,0x000a4bc010f4ef7d,0x0007a006485cbfe6,0x000ba70311a2f225,0x00032199cd733758,0x000ee0992d474968,0x0000000000000001}}, + {{0x000d4dc4b29d1e7e,0x000ced039d3b8a01,0x000815590ff2c2bd,0x00021d5655ef3773,0x0006fddb06996f34,0x0006f2915cab4832,0x0005a14903f506e5,0x0004bd51fa3522da,0x0009df3d4ada1113,0x00041c2c8aabe985,0x0000000000000001}, {0x000708b80fba1a02,0x00028b6a0afd8d60,0x00058773df43d0b1,0x000ecec358a258ce,0x0008b0ae7440af59,0x0000e74789fcab99,0x0007429cf7b8fd56,0x000584c72e545e3c,0x0001897264b148aa,0x000a07b9a2d9b131,0x0000000000000000}}, + {{0x000edce9ca1286ed,0x000ff3a46b7fad16,0x000535c9d7d2b840,0x0003708d5ca958c2,0x0005420c1e063332,0x000713a6fa0fa9a8,0x000918405a51ff70,0x000da85f855da776,0x000d1bea73da5e0f,0x00064183a6508fa4,0x0000000000000001}, {0x00083d4f23ca730b,0x000725501529af4b,0x0008000d1b6d21a0,0x000a7b3eee3507cb,0x00022a88a07a33b4,0x000540f9d09c28e9,0x0004983b28faa40e,0x000f54edb432d0fc,0x000ce23569311803,0x000d266759b9bb64,0x0000000000000001}}, + {{0x000fd03e2a0c4500,0x000d5cf3f782f796,0x0003ffeae620bf4a,0x000ca0158514f603,0x000545633e085e39,0x0004884fbea88f4e,0x000882a85fc77f29,0x00012678c646f605,0x0009ba323a505f9b,0x00029223217b4379,0x0000000000000000}, {0x0002e8744f4170bf,0x00081a29194f6c03,0x000a932a7916cab1,0x000fb0f9f60ec063,0x000ff217a0ff0b94,0x00003ea56b8f066a,0x000ed4a56ee8b26d,0x0005efbf8ce2c1ff,0x0002eb114ed13051,0x00043d7447433992,0x0000000000000000}}, +}, +{/* digit=104 [{1,2,3,..,}]*([2^416]*G) */ + {{0x000affb50d183763,0x000c1c5fc7f37a88,0x000a1f73a2f170a0,0x0001192983474ff9,0x0006b4738ed4fea8,0x0004d293dcdd7868,0x0000cd916188a232,0x000bc585fd523667,0x000b67188a2e54db,0x0008ed10b37344d3,0x0000000000000000}, {0x000548b086336003,0x000991fbe0b348b4,0x000ef3cdca5ad120,0x000cfcd2034c9a59,0x0004f56699960d16,0x0006df1f5f10f252,0x00000324733c5f1f,0x000a757f84ed98a5,0x0002f7eec2ce4fa9,0x000ae3d296f3ba03,0x0000000000000001}}, + {{0x0004e9382b32007c,0x000d81cd77eae7c3,0x00013604a2dad7f0,0x00043d13d0e3fde5,0x0004c6cb59871704,0x000a8441d1c5f3e6,0x0002361adfd909c7,0x0004efba78610053,0x0001559070eb9abb,0x000708ee4fe6fb05,0x0000000000000001}, {0x00079200ca4f6cc8,0x000579128ad5ec75,0x000c265973749006,0x000f0a7f8cf2fa39,0x0002ddb548c37c9d,0x000da31069648b65,0x0006a7e075eeef13,0x000504d0e4093491,0x000fd613bea6b782,0x00055bba92eb2c08,0x0000000000000001}}, + {{0x0005ab4da4a4107d,0x000f0dbf85411a8b,0x000a933992a7b991,0x0000accdce47a748,0x000c5662f2eb8c82,0x00064b5fdd12508c,0x000db73adddfe6b9,0x000af97a44a31358,0x00044c5ddfefeaca,0x0003403a084f6ff5,0x0000000000000000}, {0x000ad406fec21428,0x000e8954cddbeba4,0x00092a7fe19ec844,0x00084bffa4c49f5f,0x000ec8eb76b96304,0x00014948f0f75a70,0x000dff2c139503c4,0x00032fdf031b7606,0x000fa11a5ead6208,0x00047ef7a1eba7c5,0x0000000000000001}}, + {{0x00073a3dabdb3534,0x0006dd5d8f611c69,0x000799bf33f3f4e8,0x00026f63749fb625,0x00092667bd3584a3,0x00060fa9fea81613,0x000999ea3a8de550,0x0004dd75d71ac4af,0x00078319418b1e64,0x000c67e995c857c8,0x0000000000000000}, {0x000c7afa552eb541,0x000a7222bb4a0732,0x000c7e0e1a608c59,0x00009057e1132506,0x0009c5c6a19981fa,0x00019205096b7bf3,0x000a7d38ab7490c4,0x00099e016ba7462b,0x00007f474dc3595d,0x0006636a3d8c9f12,0x0000000000000001}}, + {{0x000058d88f35f241,0x000a59b2e8d2532f,0x00015502597aca02,0x000fb1e8bd7d1caf,0x00055680e361da0d,0x000ed31cfd9355f1,0x00047c0b0064d2b2,0x0004f348830f3080,0x000b7440fbffaf7d,0x000a5a553b98e17b,0x0000000000000001}, {0x0000f6eacb637570,0x000d4925881bc39f,0x000d655e7e9a7105,0x0002f09a033db883,0x000e97d5a4975dc8,0x000036e619a17847,0x00079d0e9b209304,0x000434fdadf80484,0x000412216e6c7daa,0x0000eb152f330b19,0x0000000000000001}}, + {{0x000362cca8e2db27,0x000b58fb4260cc2d,0x000e2d527b899614,0x0001f0b467cb8aa3,0x000d1ef71b82f08c,0x000dc68072c4649a,0x00098aa11a9313c4,0x000165002fbe1ac2,0x0000bf5399f23796,0x00024b537dfdd6e9,0x0000000000000001}, {0x000f6c830ade2b53,0x00074af2e76469fc,0x00051f1bc5f4ed41,0x0000406c3a450f7e,0x00002b53708a683c,0x000428a6e3aa7dce,0x000c0df44b377b62,0x000e9c1a58f5f1ab,0x000c5458b0f02c35,0x000b16ea8718da27,0x0000000000000000}}, + {{0x000134d37c05c59c,0x0007233d57586878,0x0006cf5af7409f53,0x0008ae6dfc4fd018,0x000e8b54df4cc39a,0x0005f3046db1d402,0x000312aeece717b2,0x000da13a0c5d98af,0x00073d6305f96c47,0x000587c80a3e3a7f,0x0000000000000001}, {0x00027d5a2516f5d0,0x000f9338bbf8fa7f,0x0002109c7d0c4360,0x0006004be57b26a1,0x000da32aad5aeeea,0x00041aa5daf9dede,0x000b0a16abc83073,0x000088080bdafdd6,0x0004fa8814cecd6e,0x000f5f24b2b7fe1d,0x0000000000000000}}, + {{0x000cc19d6d74494a,0x0009296d31ebaa05,0x0003edd43b02f30e,0x000c79aac72cbbb4,0x000d57829df3e827,0x0008bb62624e4cf8,0x0004f05ffe745fb9,0x000950b350aaad89,0x000ea5e2db566ef1,0x000e1e37f6dcf4f2,0x0000000000000001}, {0x00034202ee7f3c59,0x000ed5d748da48fa,0x000e1cf505b68fd9,0x00031b86c7778cb3,0x000dbdadb45073af,0x0004b6e80bfe717f,0x0001ee413036b30b,0x0003482b138b2c3f,0x000e1ed1e4fc0159,0x000e84d788bd2771,0x0000000000000001}}, +}, +{/* digit=105 [{1,2,3,..,}]*([2^420]*G) */ + {{0x0009afb73836ce2c,0x00035d1c0854627d,0x000acf6649f2eb9d,0x000acf4c38a8a9ec,0x0002178be52c0095,0x0008f6e06df7d7ea,0x0008285115ce7bb4,0x000b7f232680bedc,0x0004103a6e51e8f4,0x000aaa09aa0bc0d2,0x0000000000000001}, {0x0001c4bc539f42b1,0x0009f1f757159ce1,0x0000e9e10c0bc8d0,0x0007345be3621884,0x000d1822e5e0a60d,0x000ae792acddc802,0x0006be0f49763d76,0x000dff0f1717868a,0x0004437867cae1bc,0x00070e8bfe19f269,0x0000000000000000}}, + {{0x0001b8994b02326b,0x00031ce496416ae0,0x000dc0825cea213f,0x00050bdf0281aa93,0x00059236853f9e44,0x00041e294dc8c09e,0x000b03a595c72a58,0x000c2bc6e5381e14,0x00020b03546b3008,0x0008eca57d1874ef,0x0000000000000000}, {0x00051a61ce5948af,0x000925d36a169359,0x0001712f7655b84b,0x0002f3fdc1e05016,0x0009aa758020ba42,0x0006927405b02281,0x0009822fced2aa8b,0x00019ae63d9313a7,0x000d9c07887cbebb,0x00065e13e45febcd,0x0000000000000001}}, + {{0x00034f1f7e499842,0x000a48878049fec4,0x000692a3fe1f0c9c,0x00048261277fbbb0,0x00032263dc0fe7ad,0x000e09052ac6fec0,0x000683804d38aeb7,0x000d6c55fb1237fd,0x000bce4b453925e9,0x00056ac33e2d8263,0x0000000000000000}, {0x000a764c5c6d3730,0x000ed9705b2adb70,0x0003bab4631b9f1b,0x00014535b4850149,0x0009c2385e82937a,0x0007aa5ebdcd9ea7,0x000656517e5b5eb0,0x00078fb6885fd321,0x00087f791c6b2bd8,0x000bcad44bfcfcce,0x0000000000000001}}, + {{0x000a7c1bbda99502,0x000d13ad86ee95d4,0x0001edd6edef741f,0x0001221485b8fada,0x00062b65b3c0a089,0x000583aac0300922,0x000ec2e6716727e3,0x0006d6729d8a817e,0x0002ad34233bfe29,0x000806779921dca9,0x0000000000000000}, {0x000373f0b0bc37c3,0x0006835632a2bfc1,0x000a8cd4f472c2b1,0x0004b6c9a4cedeb1,0x00076180690c132a,0x000eca05f9fa510c,0x0004e0551eb02c41,0x000e63213fc52e0f,0x0001b429bb6165cd,0x0002bc1fdd188cd9,0x0000000000000000}}, + {{0x000629f7658d599b,0x000b1e87d39d0d52,0x000caaa997607dbd,0x000fcf23eb7d6dd2,0x000857e0cd30a02f,0x0003ecd22778d510,0x0005c5e961e1f158,0x00068aa70a145465,0x000c8fb1ff96ec7c,0x0009b464d2f55e62,0x0000000000000001}, {0x000e904d20ac7941,0x000e4f0bec2602b6,0x00080f6effaef59a,0x00060688330793e6,0x000db2442ae08549,0x0005e3d773ff5a5f,0x000cecbc6ac0199c,0x00012fa7a795cacf,0x000d6f9bfc57e52d,0x000ce32e4eaeafdf,0x0000000000000000}}, + {{0x000eeeccbba2a7d7,0x000ad1d77ed0ffef,0x0005e752d769db74,0x00015b240b6200a7,0x000597b48ab8cfc3,0x000f97504538ef48,0x0005a2e980da41b6,0x000c0010c2010969,0x0007fe53f0d2b23a,0x000a1efe8b48887b,0x0000000000000001}, {0x0007b952e8dd021c,0x00026e6b8cb163c9,0x000d62feeed16bdd,0x0007e3db6129cfd5,0x0009dcfa4489e9be,0x000f551707d804ec,0x00012a2adb1fbcf8,0x000c05be22830553,0x000c9f74b7d87937,0x0008d7e5edd3be33,0x0000000000000000}}, + {{0x0004b2f4546a8f7e,0x000d2a223a807885,0x000155358a6954ae,0x00086e4b30349ae5,0x000a5982c7a2aae1,0x0006ca4f6415564a,0x000013abb73fd2e2,0x00092d10cb063fca,0x0006104963b01aea,0x000bbcd0f1f68f33,0x0000000000000000}, {0x00069aedbf43f1a2,0x000ebe1ef2c9b47f,0x0003246ee727e6d3,0x0003f5bd1a5a6120,0x000987e829b05fc2,0x000b70444c023806,0x000f0d6e903fa23f,0x000baba52743b14c,0x0009994d97e9872d,0x000a52cbf74f834a,0x0000000000000000}}, + {{0x0007ea3240feb8cc,0x000792ae77094407,0x0001201418e13db8,0x0003920cbc07e7f8,0x000aed56c93837f4,0x00013ae3d2a87da3,0x00044b8ddc44f1df,0x00069328fcaa2209,0x000b928d8e381964,0x0007313e55f26bee,0x0000000000000001}, {0x000ec4f451bd8008,0x0007bdfe195b7e42,0x000e12b70e68b680,0x000159222b99f5fa,0x0000c4e0659127ea,0x000efe86909b5076,0x0008c58b9b667112,0x00047b7026cf16a3,0x0007373740ea01a9,0x0000153963989580,0x0000000000000001}}, +}, +{/* digit=106 [{1,2,3,..,}]*([2^424]*G) */ + {{0x000546c7f70bcb2f,0x0007212027084052,0x00013f0d6d83c3eb,0x000eaca7142e7b62,0x00029f973a763019,0x000be00c2a025efc,0x0003eca6f6199ab8,0x0002b5618bcc0394,0x000b02749fbfb9ab,0x00013c0ae9ab795f,0x0000000000000001}, {0x000f295b93c3d712,0x000bf1ab6d0e9f50,0x000bf53d7cb083d8,0x000d744e07076abe,0x0005a51a53561f29,0x000d647b915c2fc1,0x0009ead253f84287,0x000e91bd9d6251a2,0x00006dd74006b7bc,0x000c92c770e4efe1,0x0000000000000001}}, + {{0x0002703ae4d5c812,0x000427e95afaa341,0x000271961d1eb61e,0x0000fb71509a4412,0x0007bef04644ecf6,0x00044d4556d64abf,0x0002a7bfd03e651f,0x00094add4bdd9b05,0x000438d74bb2156b,0x000fa36c6c16572a,0x0000000000000001}, {0x000ae16f96be2911,0x000d52afa2d73a0e,0x0005bc81a5a44951,0x0000fc89324d90b4,0x00018cab36337849,0x000cb411d87db838,0x00021f7d6cb710ad,0x0006ad26521480af,0x00094a666f370ca0,0x000375d8bc966e31,0x0000000000000000}}, + {{0x00082baa7d62ed15,0x000a2a0c35293a3e,0x00068a91eba6b63e,0x000715c2cd81a65b,0x000ed39839d20270,0x0001cd1c736c49a2,0x00023b8eae3fee67,0x000006012e0a11a6,0x0006b901f0657746,0x0003944e0864a739,0x0000000000000000}, {0x00089e4689d04d8a,0x00060efa98dca953,0x000708ea3f1bf018,0x000f379e0740bbd3,0x000ab07cf1111586,0x00040f6bae4389cc,0x000c0c62ec14d78f,0x000a8ca2edc050cd,0x000eb9e22353ae3b,0x000221497d609a22,0x0000000000000000}}, + {{0x000dc15d0ed0cc63,0x0001ce35b540e1bb,0x000973de7aa979e9,0x0005e965745fa684,0x0008a999e957c84d,0x00071ead702675f7,0x0002beeec63eb2b6,0x00062262a9349f4e,0x0005b027fa151a2d,0x0005b45a63374388,0x0000000000000000}, {0x000ade9fdcbfe121,0x00019964a13f4063,0x000ea6e576b23957,0x0009fa2021e1e294,0x000f93e8e8d0c1a3,0x000627a8aaeb1db8,0x0001c83a239f73f2,0x0009dc2704f34ba1,0x00053062be1591a1,0x0004c975cd21326d,0x0000000000000001}}, + {{0x0006b8fb25e6414b,0x0003f3c35210ef6c,0x000fcf4305218c66,0x00044c1aba52d092,0x000ad9ddbd46b892,0x000a630015bf7459,0x000b32b246737751,0x000ced081a65d447,0x0002e2e5f643a94b,0x00044927f131866d,0x0000000000000001}, {0x0004645014a53592,0x0009ee4e5661d1ca,0x0009024d9b573293,0x000159f5f55c84df,0x000a0100b8c24f2c,0x0002de6a0aef0178,0x0009e7eedb7e96ff,0x0002067fc1f195df,0x000897eb377d8a42,0x000f1229a3daed81,0x0000000000000000}}, + {{0x0005287cf2f5961b,0x000cef9beb6f8461,0x000a7eaedc75201f,0x000d39dfabd8969f,0x0004252116284485,0x0002945b419a298f,0x0000f03b98d985bc,0x0007be292f990254,0x0007d1f59fb5c829,0x00002d379bfc2592,0x0000000000000000}, {0x0001179af2527211,0x000f2724128932bd,0x000920719e949c7f,0x000f184c1ce441c4,0x00091d4d77a7c7bd,0x00086d6826d00ec0,0x000125b3901be8d2,0x000c6d7da5fd8de5,0x00084f0587b71c09,0x000ecbd13d8a200a,0x0000000000000001}}, + {{0x00034258888b309d,0x000da5700df117ec,0x000eecc1e03d3856,0x000d69afef5df311,0x000ced3bd1e65823,0x0009ca00a3d94409,0x00053de41e7eb569,0x00002f1291722236,0x000dbd2ee0ded7b4,0x000a909f40f6e980,0x0000000000000001}, {0x00082d95c76e2f3a,0x0006d18779f8f974,0x000021eeb4e7e5b3,0x00070089298e7654,0x00003aa90b7f11d4,0x00020fd2c120d0de,0x000ddfdcf3b2e6f9,0x000134293b957e6e,0x000d5361a94456e0,0x0004bc62d97be2a1,0x0000000000000000}}, + {{0x00047691dfe1ac32,0x00095bb25141cf40,0x000cb8b02c59109a,0x000eb57046b0d286,0x000a8b7de816343c,0x000109a4f745b33c,0x000bf34e4de2617d,0x000950869270fe1e,0x000a3a1b01ca6170,0x00012e38634a9ad0,0x0000000000000001}, {0x000f079109fbe1e8,0x00071bce15260c38,0x00059aca1efc1bab,0x0006c7ad5da68584,0x000030bec54d9816,0x0009a9c32e8f4612,0x0001154d88a51704,0x000ebe8180a7efea,0x00008abc6ec5ede1,0x000d7de0d26459ad,0x0000000000000001}}, +}, +{/* digit=107 [{1,2,3,..,}]*([2^428]*G) */ + {{0x000019394140932c,0x0009a362bec3a200,0x0005ab884c7a2c57,0x000cab2ba06cf4c6,0x0003ee7eda004083,0x000107bb12f5f6cd,0x0008a0ae8649e92a,0x000a5a344683492e,0x000cfb24291fc3fb,0x000c3894cfd1718d,0x0000000000000001}, {0x000751b1b1d1f30f,0x00043fce22373903,0x00023da45dac2f10,0x0000105df9307b4a,0x000892b6d1b2c311,0x000f645131b39e6a,0x0006331d8e317be2,0x0000b2f395de9046,0x000d56345f1e436a,0x0001b0547fe7481c,0x0000000000000000}}, + {{0x00078f4b7084325f,0x000727f8bc0fa450,0x0001eb36b7bf5948,0x0004268cea0106cf,0x000e8c80e06d4c70,0x000c216323300186,0x000b3016e94d5075,0x000d882e86c372cc,0x00048a28a053b8cf,0x000343d171001931,0x0000000000000001}, {0x000c0287664ae003,0x0002766d8c63b224,0x000b8220989c0738,0x000b967cd418521b,0x0004152d761e7a59,0x000fa019e4601efc,0x000f11b41cb4d7c0,0x000dcac0131d9d52,0x000c991e4e27a162,0x000789975ffa76aa,0x0000000000000001}}, + {{0x000adcdaf64c0019,0x0002a5ef0c2175ba,0x0001cfec89a01d6c,0x000b25fa94296a25,0x00089c7ef16afeec,0x000c007e24585f16,0x000bbbc143cb4742,0x000531bcdafbbc24,0x000013773a99937c,0x000e19b7d849db6c,0x0000000000000001}, {0x000e83417610eec6,0x000e934e9e9d81b9,0x000af4480e73d7b1,0x00086003aa3fea2a,0x00079c57f5c52d5f,0x000495c2aa9268f2,0x000922e4d082c9f5,0x000448a981d714f5,0x000bdf27622c6821,0x0001ae01e6436230,0x0000000000000001}}, + {{0x0007602120347ad3,0x000dd3e9ad407753,0x0002f89c76c52251,0x00044aaf5957d5e2,0x0006157c28051b58,0x00069eb597630bd3,0x000a387acac6af33,0x0002aad0ef875611,0x000ccba64de2edc3,0x000ff1731d170b0b,0x0000000000000000}, {0x000557f665f21957,0x00064548e1ee52c2,0x0000cf955615f44f,0x0002bf2c64b6036a,0x0008d89213e751e5,0x0005aa570d34bd85,0x0005ae3bf1cb2e71,0x0003f29e703acc20,0x000a34a47fb1911e,0x00089578616fc498,0x0000000000000000}}, + {{0x000dc828f86252e4,0x000d09ec8dfb2555,0x0005077092f2430a,0x00078d5b0c56862b,0x0002f9b2b116f869,0x0007b998e4dcbf23,0x000fbcf91af3491c,0x00056f1110038af4,0x000e0888ba8f38ec,0x00043daf07963a9c,0x0000000000000001}, {0x0008da925a008487,0x0004f369188e0311,0x000ec8e641278107,0x000a270db9969754,0x00072aaa78c429c9,0x0001a344c1da5196,0x0003087bd58c2f7e,0x00088aeffcfb4dad,0x000fbcec5f2532f6,0x000a809230f905b4,0x0000000000000000}}, + {{0x0000b4a0ddb8dfab,0x0009deda0e27481d,0x000949ab745b2f9c,0x000dc2842dbe3df2,0x00059b98be5c35da,0x0002ed3249c0c912,0x000dc475c0841958,0x0005a3cc60128529,0x000078110f67e016,0x00017fe4fa3624ca,0x0000000000000000}, {0x0006abd2bfebf71d,0x000617fcd7e4413e,0x000ac8bf7c39197b,0x00022ac8be897f87,0x000878bd60d51691,0x000ed69bb2587c48,0x000a51aae1defc49,0x0003d1f77705c7ae,0x00021ab01c739c3e,0x000801dacd9f17c4,0x0000000000000000}}, + {{0x0002a912967cbb3e,0x000f46687e4df221,0x00007e4eef350ebe,0x000e38a4de052972,0x0009d5282d27fb20,0x0006e64b3686af97,0x00067350cb71692e,0x0008437b220d3baf,0x00042c826bce6850,0x000642d60e139b00,0x0000000000000000}, {0x0004eb43ead3cd1c,0x0007d1cbedb5fe6f,0x0001b45fb1ca7933,0x000a503cea7b46bd,0x000fef3868c8b110,0x000f9fe2cde99fc9,0x0006dd89f348e20b,0x00022d25b6cd54cf,0x00051adcb2128528,0x000ea79e7afb9c6c,0x0000000000000000}}, + {{0x0001fc12e7ca5055,0x00025e91d6adbf30,0x000587a0d31dc42e,0x000cc8a9cecd10d8,0x0009d8d1b41ccf88,0x0003b3f96490bd95,0x000e028999c5a513,0x0004c3a0882547be,0x000fc3438b39f5f7,0x000fa75af39ed4d4,0x0000000000000000}, {0x00002b54c1f9ad9d,0x000dbd0a29ee5fbf,0x00057045bbc4f0d6,0x0000fce2e6fde293,0x00033040027dfc7d,0x0003be51ffcda45a,0x00054869841c14d2,0x000156ff1e336d04,0x000a634d9fdc8522,0x0003ae619b696b5e,0x0000000000000001}}, +}, +{/* digit=108 [{1,2,3,..,}]*([2^432]*G) */ + {{0x000019f2fc6beb7f,0x000666646b70deb9,0x00090a5717d2e533,0x0006810fd38f5274,0x000233bb33bad791,0x0009b6b88efd9526,0x000d5745dad71c05,0x0004ca300788fe6e,0x000ed4a6a21a98ac,0x000e10eeff58916d,0x0000000000000001}, {0x000da52e803a67cf,0x0007d398c1a5fc48,0x00042b185c01901e,0x0004eda6cb2700b0,0x0004eeec867cdaca,0x000dcb7e930a19ae,0x00010a288471dcc7,0x0003198ed17517e0,0x0004e8756bb36f68,0x00027df915ed36bb,0x0000000000000001}}, + {{0x0009d95ae2bd1168,0x000fb9d6f73873c0,0x00027b3bc9e7cafd,0x00005fa81f14d40f,0x000ed4eebf4e66fc,0x000bb6036a4e6b76,0x0009e3f736cb7387,0x000b2277b08a58e1,0x00055c0d7a4986be,0x0004d18f830adabb,0x0000000000000000}, {0x0005e59f982356bc,0x0000599a3ae563b2,0x000d06e16bf18997,0x00088dac7505891e,0x0004c76b3eb973d6,0x0006498b2d10cb08,0x00074af2d6e8e95c,0x000a503f71b8afa5,0x00066999bc16133c,0x000bd76f3443fa99,0x0000000000000001}}, + {{0x0009cc5a1fdf300d,0x0000ede5aa101a8c,0x00053342a7d32907,0x000bb4fe852398fa,0x00036673ceb9c007,0x000c9247b3a94312,0x0001ee51cb682683,0x00075c07f2ef115b,0x00083b0143f6486b,0x000d101585ec3771,0x0000000000000000}, {0x00080da54d84cedc,0x000e569a2e8c0006,0x000e94c0472e41a7,0x000a41c1b7c713ec,0x000e5742d18ccf2a,0x000df3c3763e3162,0x0006b9977417a84e,0x000f165b44c75791,0x00045d988246f2e2,0x00095c8287828d1c,0x0000000000000001}}, + {{0x000f9c015fdb1c06,0x00099f25767d4418,0x00077c536b749d61,0x00054bfdb54e847b,0x000237979776c1af,0x0001eefa220b8386,0x00018acdf9bb4a75,0x0008ce45beb5028f,0x00030f98a7dd8621,0x0003023f055e3ab9,0x0000000000000001}, {0x000f321b72c7f6a2,0x000659eeb57c141d,0x0000b2255cf53902,0x0009dbecf2a776fd,0x000e6453cf8ab4cc,0x0002d5647863e94e,0x00049fe93a4007af,0x00039cf116d00271,0x000dc8184a637605,0x00061de7465f7317,0x0000000000000000}}, + {{0x000dae8508371ab1,0x0009f5759cf42671,0x0001705cf63d991b,0x000e90ca5edd0265,0x000af5c715a86e95,0x00096331dd94a89f,0x0005808565c73b46,0x0004c9ca8a595723,0x000561170be646eb,0x000a57b5fc879ce5,0x0000000000000000}, {0x00080540adb44437,0x000abb97c57c16dd,0x000be7baf4488307,0x00019e753dbf21d2,0x000ac5be29dc51e1,0x000df21c9ad3cc57,0x000a9aa74fbb9193,0x000a11ec7b8e665f,0x000c01bfce350115,0x0009909f2c73b53a,0x0000000000000000}}, + {{0x000744ab95b71183,0x0005aa6c81566c3d,0x00033310fbbacd74,0x00006a2dd55a7d6d,0x0002db05de914221,0x0001ffd4282301fd,0x0008cf7489b2de85,0x000c6f0a02baf309,0x0002ce9af0a85604,0x000261197b0884c2,0x0000000000000000}, {0x000e2c60da7deb89,0x0008d4b2f2e54489,0x0002e5dee75d5785,0x0005e0e953899934,0x000ecd968f2eb742,0x000229cbd8cbbbd2,0x0008dcc6b871d5e3,0x000490c7582e68a9,0x000cde3999720429,0x0005eaec58ffb639,0x0000000000000001}}, + {{0x00028ab59549216b,0x00005d61d82596b8,0x0009fa679fcfc930,0x000ccf438ed2cad9,0x000a40190b3069f6,0x0007f5af4bb6d49c,0x00002f9e7c50f6a7,0x00019940efdd8671,0x00002add96c554a6,0x000e007d80786684,0x0000000000000001}, {0x000ad0fb54ef0a37,0x00046af5d15fc57d,0x000b825452e8ccd9,0x00044232c710cb6b,0x000cf88855ecdc6f,0x0001d6d2b8f40b3c,0x000436e2bc3e510d,0x00007b1ff42aeddf,0x0000ed88484552b4,0x00075c1505c18430,0x0000000000000000}}, + {{0x000a55f734e8c16e,0x00026ef042fa2f6e,0x000b24c1848ab1d2,0x000acbe86862a1dd,0x000651f4168e7413,0x000d596e07914083,0x00079ca23961d189,0x000e6d53679701b3,0x000cf35fa05ec7b7,0x000d20d7f6b70713,0x0000000000000000}, {0x00018785b4c707b1,0x00038676095f2dbc,0x000e28a0370a0054,0x000af09e50c89610,0x0000f144bba0bfee,0x0004cf6dd7455cf1,0x000e722f509d9783,0x000b05c279e5f94f,0x0001244fe8092deb,0x000153b314f061e7,0x0000000000000001}}, +}, +{/* digit=109 [{1,2,3,..,}]*([2^436]*G) */ + {{0x000803868bfafe94,0x0002ddeb7719717f,0x000911e1ad005b4c,0x00076f1e0df34f87,0x000b29958d5da570,0x0005d1ebf66f49ec,0x000f5712ca7b49e5,0x0005b2ff1b32fcb4,0x000f97d3d42a971c,0x000804838bb32749,0x0000000000000001}, {0x0002e7908789eb65,0x000af786529c3ba5,0x000e71594737ddd9,0x0005400f6dd64d51,0x00039922bf016830,0x000db4bbaa21ca42,0x000935d8c94ee851,0x000c80623440afda,0x000110efc0a576c9,0x000396d79f58dcd9,0x0000000000000000}}, + {{0x000b38ccc9df95f7,0x000d1849ee6062ae,0x000164333dec1411,0x000e81b4a4a4727a,0x0009c74b241dc566,0x0005069fb7290aa5,0x0009d322865cb6d8,0x000ecbd648392838,0x000909864ce3c8f7,0x000ac9fef248d28c,0x0000000000000001}, {0x00061d435126259d,0x0005a6b96bec8542,0x0001f509bbc62a6f,0x000ddbc8b43f9c90,0x0005e94118466c53,0x0002a386779ad388,0x000db58d109dd2e2,0x000aeef4f2af60b6,0x000bc0cd7adf1adc,0x0008220fb47811d5,0x0000000000000001}}, + {{0x000f1b4d9b2b9d58,0x000635d4601e4549,0x0005712ad28d37e9,0x000e19b42c3143dd,0x000fdc6366f04af7,0x0004b34637aa565a,0x0005b2ac12b452bc,0x000277fe7f5bdd13,0x000c6ff31feea8b4,0x0000c45cdaec8e9e,0x0000000000000000}, {0x0007813178366af1,0x000e83664c221b3f,0x000afac4ecd652c3,0x0007c4666da93d03,0x000652ceac0d6cfa,0x000b1a4cf4039d2b,0x0005c58a6eb1946c,0x0007422c9b53a228,0x0007349ed1b4d836,0x000afa4c55a379cc,0x0000000000000000}}, + {{0x0009ee173ac4010e,0x000fb942f467a4b5,0x0005770a30141b66,0x0004198802513df6,0x0002c7e0148f2f1d,0x0009a1b6c6f54abf,0x00056f2bb47b51bd,0x0004f5846505fba9,0x0002a3ddcb02618f,0x000a7b69ec8c6450,0x0000000000000000}, {0x0004b69533aa9231,0x000b0804316d8f19,0x000006107c58f7bc,0x000310f29f43afd0,0x000e7a15ea5dc32f,0x000849a363e2b91a,0x00074452b4966c63,0x00071d63455b6a45,0x00039b535b8835c1,0x0005091ae86f54cd,0x0000000000000001}}, + {{0x000de1ec8614daa5,0x000f0834c4db4a7b,0x00048a29f6ba70a6,0x000be231587d1015,0x000bb998c9a2049d,0x0005eedcf88aceaf,0x0008878e6b738f7e,0x00019b693ecfcab0,0x0008dd1ddb374ede,0x0003be7a6cd94f00,0x0000000000000001}, {0x000bd130c16a2f12,0x000343c20757ed83,0x000228e06b217bff,0x000046a91bef19ad,0x000400e88da5cc51,0x0000a9f961011b58,0x0003f9049ae6f047,0x000e9d079a03c6f8,0x000401435912f072,0x0007490b78fe3f9a,0x0000000000000000}}, + {{0x00081fdfff4245fc,0x00050168c14a6614,0x000764d4d2b84edc,0x000aaa60be356501,0x00030e6771588736,0x000714d50c0c40e3,0x00029157b8fe8875,0x000a9215aac4fbdf,0x000b4091b549e25d,0x0001ad442d2b0058,0x0000000000000001}, {0x000ee6a91c584138,0x000d84934568ba88,0x00010dd1585307ef,0x0009b046cb644b24,0x000dc2bd376e1321,0x000cecc49bef0c68,0x000f76556c2d2d1d,0x000d810f8810c907,0x000a20da5052b3dd,0x00079ec3448a3c1b,0x0000000000000000}}, + {{0x000084366f4dadcf,0x00087f5cc0a55e0e,0x000a139c3fe7ef01,0x0003f2e749d53f7b,0x000ffd809a727542,0x0002e74f9e5a94a4,0x0001929541f08d0e,0x000114dd07932254,0x000f53ad14915984,0x00078a408f5bb7db,0x0000000000000000}, {0x000b74adedde4d64,0x000eeb46e287111d,0x0001ad3605f3b22d,0x000070fc8863541b,0x00093fdd530f51fe,0x000f3d69c04af47e,0x000f551d93cb6477,0x0002bc684cde6d16,0x000154a9f50cd685,0x000e9f16ac0cc2b5,0x0000000000000001}}, + {{0x0006190bccf09089,0x000de2a4a386bf1b,0x00095703cbb17c47,0x00013d223bf84891,0x0007a124742673f0,0x000290f2b86fdb82,0x000f44e50e9b7e10,0x000ecc65826079a8,0x0004d12b589a9228,0x0001b683a119d1ab,0x0000000000000001}, {0x00025950f93cc637,0x000b7a6b02229a2d,0x000fb0617d538c46,0x0001dd7b6bc581dc,0x0005b6b522d590ce,0x000133e3f5d0dcdf,0x0005bdf5cce47e79,0x000e21b8ecd0d71f,0x000ac21b717d9aef,0x000b887b6090257a,0x0000000000000000}}, +}, +{/* digit=110 [{1,2,3,..,}]*([2^440]*G) */ + {{0x0009fcba235d8a1e,0x000ca359a63f98f8,0x000f60025c086d07,0x00018d4e590915cb,0x000c915cc7c3b68c,0x000933480185575e,0x000511ae8d10d820,0x000082704b904789,0x000a4e997db2e76c,0x0008c3f5824d99f6,0x0000000000000001}, {0x00053628d8f32dc9,0x00000ea757555069,0x0008537e14185044,0x0007f7a0609d8295,0x000c55da70118c7b,0x0009ad1223c50379,0x0008629c936f6ea7,0x00054f7f839cbde4,0x000f8def61ba0172,0x000f5c1bef09ebdf,0x0000000000000001}}, + {{0x0002eeedc5fe3f41,0x0004f9330d665ae8,0x0003f5e64a30753a,0x000e92f39e477096,0x000aa07f9d297ef9,0x00048c3ddf388062,0x000e61e60ab0df5c,0x00095a47567e55e6,0x00066d0129872a6f,0x000953425f368c3a,0x0000000000000001}, {0x000b7cc7bf66ffa4,0x000f16b2825eba03,0x00090e67535ba3ce,0x0004aef14aec5704,0x00001511ac67bcc3,0x0001002739d95c0e,0x00029220f4f36575,0x0001465557ab45e9,0x0009abecf1baabf9,0x000fe98337c9760e,0x0000000000000000}}, + {{0x000025751d2b325a,0x000cde6a01039da1,0x0005ba8462228499,0x0003490747232500,0x0001a523417ab4da,0x0003451baf54b07c,0x000516f3fa7e4ffd,0x00042fbff2147ce5,0x0003f1b0afc522cc,0x000cb395c7010ca3,0x0000000000000001}, {0x0005ed5f55af51c6,0x00015b980e568466,0x000a5a1b30bd5964,0x000bb04e8834a37b,0x000becf282494fee,0x00040dc6ceb29d17,0x0004a868d5399a53,0x000276012bcea50f,0x000c769aa83faa31,0x000d8e6550a0654b,0x0000000000000000}}, + {{0x00066fa0ef4dbc14,0x00071d134a53f7ec,0x0001ee39cdaa7b28,0x0009b3f183070c04,0x000c76da77991974,0x000916f1eb867841,0x000b27421e5438ae,0x00051b0e12d8e409,0x0005e08b83842a6e,0x00094374b9e008de,0x0000000000000000}, {0x000a4cba763a6340,0x00013308e07acdfe,0x000db2143a906789,0x000fe6dd815c887a,0x000e2a9d2043c85f,0x0003ceab79a68d05,0x000986393674d33d,0x000d12ee73ca7a8a,0x00003b9bbd54b7af,0x000b702eead11264,0x0000000000000000}}, + {{0x0000b987f57f80d5,0x000d4367c06145fa,0x00034438e79fd55d,0x0000f9f8e8ca9c52,0x00036810f12c2fad,0x0003ec5af1a97a71,0x00085613d0eababb,0x000aecb3da01b7b5,0x0000150798aadf26,0x0008029cce9cadbb,0x0000000000000000}, {0x0005a72e54383960,0x000decd025e95126,0x0005b2c914390e3d,0x000864784955e972,0x0008cdae63ed0053,0x000aa5ded860c28f,0x0001dd80fb99e774,0x00020f07854bb74c,0x00091581c2caae0f,0x000d48069f6ba766,0x0000000000000000}}, + {{0x000f135836126647,0x0004208b738df6f5,0x000786c7341e91f4,0x00084ed91ae2188a,0x0000b08e3293bda3,0x000e09af3119b1a0,0x0003662652676669,0x000fd07b9f37322f,0x000ae129d764ea40,0x000b85c16a911b11,0x0000000000000001}, {0x000021aec95ad18b,0x00080eeb3197c759,0x000dfd4a4334daed,0x000ff78d606234ad,0x0003ff98a1d73ab3,0x000c9cac669f90a4,0x00063cf99bed1762,0x00028f03fcd45e80,0x000b17bf750672a2,0x000879027e080bfd,0x0000000000000001}}, + {{0x0006a647cfcf8e23,0x000d745dafe04723,0x000c3212b4d30081,0x000945780f548f13,0x000a0d885e14f51f,0x0006ed3092941059,0x000651e189c478f0,0x00007a26e8c75042,0x000a14b52f36b6ee,0x0001a032dfdec009,0x0000000000000000}, {0x0008ca67379eb582,0x000b6f527f0a50be,0x000adaba76e4c6be,0x0009b987fc7fd1fd,0x000a047c90091990,0x0006d6f45b992155,0x000e37e2da697e00,0x00011a38bcd1740d,0x0009b93e8ce3867f,0x000b60503be8b250,0x0000000000000001}}, + {{0x000c16ca71ab9de2,0x000d4b4d3bbd16e8,0x00053785c45519f4,0x000fab776454947e,0x00019d9b9416f1aa,0x000337e34e6883b4,0x00041570208ba8ab,0x000cab67774a7e58,0x0008ac5165a84d18,0x0003a977b69d3110,0x0000000000000000}, {0x000e5bcfd652943f,0x000743cd5e892a91,0x000502744c85aa27,0x000bb91ba0414bf5,0x000f8bc4ef773e26,0x000f9e301b8bcd45,0x00028983589038c8,0x00019a5f5e5a30d4,0x0005c6671a609f77,0x000a3aade09eb4af,0x0000000000000001}}, +}, +{/* digit=111 [{1,2,3,..,}]*([2^444]*G) */ + {{0x0008fa162e0dbf60,0x0003f486c08a442e,0x000d94f9cd2b15f8,0x000f2a2350bb6a89,0x0005b606cc5727bb,0x00003f198a74b132,0x0001a6f73b79d3ab,0x0001c95046a9cf73,0x0005ed71e298efd1,0x000274d622bb2409,0x0000000000000001}, {0x000c383b3b59eae1,0x000e81b2f1927508,0x0000d888be6e14de,0x000fb612ce4b12e8,0x0001378248f53213,0x000330dbca43092c,0x0009ef5e40c52b24,0x000e9d869889952b,0x000c05f4131f1126,0x000503fd03ae1dfb,0x0000000000000000}}, + {{0x000868b8bbdfd1e3,0x00069e244e266c6e,0x0007c7bf40b05a43,0x0003b7e1e296776b,0x000e22cfd9c18aed,0x000ea90d63ddbc31,0x000929198abb7bc1,0x0005791f36a5e50b,0x000737c71c2f87e5,0x00024f75c6d8e7fe,0x0000000000000000}, {0x0004c9eb7d596ad7,0x0001e1a0fb486ad5,0x000d820f02c91d1e,0x000160179160a67f,0x00057f1163f25e5d,0x000cbc9a928b61c5,0x000df9b84ed79f2f,0x000854ba69556a33,0x000c5cb8ac8febe1,0x0009a7ec5a344343,0x0000000000000001}}, + {{0x000a1f2d5d90dce2,0x00048086d7fdecb8,0x00005e3d618ccc17,0x00081c1e93d5b7f5,0x000a9cc469c44a02,0x000561bd59d9df3b,0x000788578aa5fba5,0x000f6a295757cdc7,0x000387a16bd50e1c,0x00029d1a6695b773,0x0000000000000001}, {0x000b40770bcc13d9,0x000a0b4cb7c0701f,0x00058a0433c71ad0,0x000e93cd5406bd3d,0x00098c999eda26c3,0x000092f416481951,0x00047a1b9bfd4b10,0x000f450e0ae46263,0x000aa14d201a717d,0x000a1f0cadae7402,0x0000000000000000}}, + {{0x00025a8ecef36f15,0x0000495828c615a7,0x000ac113424f603a,0x00042c1687a77e81,0x00098761c2762346,0x0009b1a4749d0db2,0x00097828ac3391f2,0x0005050c5b69143a,0x00078b0a25ae0092,0x000d6c144730edc5,0x0000000000000001}, {0x000bfa3844e6437c,0x000f55606aeb933b,0x00097e413566e3da,0x0001c1ae4263527e,0x000823a0378934ac,0x0002143f588c3363,0x00027262bb7d997b,0x00082419935b6941,0x0004eeef99cb555c,0x0009b82ef7f7cb72,0x0000000000000000}}, + {{0x000f0062dfac9c48,0x00002d81a18ce131,0x000ddcf23a0713ab,0x000a1fcdc4c43fef,0x0007bce6f244518e,0x000ad87348b34742,0x0006967b2b850180,0x00045248a8e5aac5,0x000029c18af90606,0x000027d44e26ac08,0x0000000000000001}, {0x000cb47b7d6fa01c,0x0000fa06669eb12a,0x000ba3426d87d938,0x000cc362d25b1811,0x0005c938c9a5e9c2,0x000513be5311d61f,0x000c741f99e49306,0x000858e6ea44630f,0x00001034df68ea15,0x0009fda601eea831,0x0000000000000000}}, + {{0x0001335ca463c947,0x000056d6526151f8,0x0003c494f0f999ff,0x00082dc10a7433ca,0x000067fa3bcdc41b,0x000c803bb39af11e,0x00031fc0ac7bb35e,0x0005b5e185aa457b,0x0006ab2cbed55591,0x000c973304481958,0x0000000000000000}, {0x000c07b3b2112108,0x00057bae813666bf,0x0008eee1f424f0a9,0x0002122582cf0958,0x000314daeb7bdc33,0x0004de4e23458ec0,0x000a768d0f97884e,0x000a1655c201fc50,0x000f1a537b424f36,0x000a6c0cdff48114,0x0000000000000001}}, + {{0x0007e2caf6bd29ac,0x0003376357d313a7,0x0007372bec99c462,0x000dae50c449ad64,0x000a9851fff00473,0x00047fec5d20efdd,0x000826de033e859f,0x000f46311785804a,0x000104e3184caf5e,0x0001ecedcc25e31e,0x0000000000000001}, {0x000e47c0beec6da0,0x0001b1920715db74,0x000ae32e6188b124,0x000b5dfc6ee77c87,0x0006b132638e4040,0x000b86b665e1c6f4,0x00028fe14b060006,0x000b71efffb869b7,0x0006eab86370f188,0x0003e80379ec88c1,0x0000000000000001}}, + {{0x000f8cb24f3b637b,0x00076af131c20322,0x000815ccfff0c2b0,0x000fbdbff056364e,0x00060c8028853dbd,0x000af0ee0841ab57,0x000da56ca93ac088,0x000d301350923094,0x000228a255054010,0x000a058e7dde6774,0x0000000000000000}, {0x0005176aa5c512c3,0x00020d3779fd868a,0x0007658fb3dbe164,0x000cf13041f45c5c,0x0005049dea64d110,0x0003f6746e19e0e3,0x000a39087ca45757,0x0008108ab4e2fe7d,0x0009cce4e874c545,0x000b791d64965ce3,0x0000000000000001}}, +}, +{/* digit=112 [{1,2,3,..,}]*([2^448]*G) */ + {{0x0001f7c72b336855,0x000f76e247b483cf,0x000202781dc97b6b,0x0005bb58c0f81747,0x0000c92efba888b6,0x0009612af59611a6,0x000ccbeaf54a57cd,0x000ef8689ba520d7,0x00091cc366d3cbf9,0x000056dc1abfe905,0x0000000000000000}, {0x000a04beccd53894,0x00021b1e600b02d4,0x0006c3ebe8f2a150,0x00007cfe9586be60,0x00062f4028af5b85,0x000d392e8954dda7,0x000dadc519d37584,0x000b58c3813ebde8,0x000557ce681db641,0x00006323fa3b9991,0x0000000000000000}}, + {{0x000327209a17e11d,0x000d294da0ba85ba,0x0002e3b7145fac1e,0x000fef1248cf218d,0x00034de112f175cb,0x00094a8f1676f3e2,0x000f9c2657870861,0x000518958d56de1a,0x0003dbcba495c76a,0x000cbfa5e9c9c9dd,0x0000000000000000}, {0x000fcebaff9f1e95,0x00070930a1b712b1,0x0008296f1f273d82,0x00071eddfa6e1f41,0x000af7dd190815ef,0x000f6fda9bc4a2f8,0x000482585b1234b2,0x000e23556036541a,0x0001ac1cc79e6b22,0x00079988ea71f991,0x0000000000000000}}, + {{0x000a9c0f0a888100,0x0007d24e7957d723,0x000347cf9592bff9,0x000365bb77516430,0x000532639eeab522,0x00075ffdcf80bee0,0x000715b06a25a527,0x000f841be2cacf87,0x000bc301ef1a4c9c,0x000be09159817e68,0x0000000000000000}, {0x000ae077a00f18c6,0x00066d4baba09883,0x00026a600e57c245,0x000d614baadec7ac,0x000df9f1c7a24538,0x0006e61c4241b694,0x000e25d7cba200ff,0x0002e6c811de028a,0x000a7a2ca09bc137,0x0004b214e3d38684,0x0000000000000000}}, + {{0x0002cc5d8d86efa4,0x00086c8ee779a0a2,0x000fd2159545dd5d,0x000c7262fd5e2c81,0x0008275f13cf7ab1,0x000759a0b74f36ad,0x0003c0c8c3ddc91e,0x000d10948a51d222,0x0007160cf9b2c7f7,0x00060f285822b597,0x0000000000000001}, {0x0001e962392851c3,0x000b50d7c127ef1a,0x000d984c5287e5e2,0x0005ce7d3999dfdf,0x0006fd1373907aad,0x0007f8f0825c8472,0x000b5c55ebbc32d9,0x0002bd51b3a068dc,0x000935287a1b4f59,0x0006c8f3eb9dca36,0x0000000000000000}}, + {{0x000e20e45266c880,0x000d20d089ee45a2,0x000924531cdc6e8e,0x000f7ce2e1fa4436,0x0002517f9a18e676,0x000d570398bec610,0x000dea4d0f9eb1c1,0x000c9914ddf30f65,0x000cb21d0d421e9a,0x0002d38fb5fd0304,0x0000000000000000}, {0x000db46cd0b507ab,0x000ba53f3ce83b8d,0x000a8aca81c50a03,0x000245a83198cc38,0x0008bb4ffb6faabe,0x000c93601934e1ba,0x000061b676968674,0x000710e9ebcf5033,0x000185f4475389bc,0x000687b9bd9763f5,0x0000000000000001}}, + {{0x00029514447f1de3,0x000d950771604321,0x0003a8cfdfffb078,0x00022ba412e08811,0x00097ef9f248a108,0x000b82c1196accaa,0x0001f8d1787041bc,0x000ec8430565e6d4,0x000eacea7ff3e1c3,0x000896b9bec2206b,0x0000000000000001}, {0x000508946b504e8a,0x00067cc71474da28,0x0009ad4094d373bd,0x00068f87798411db,0x000b0b90d5d507cc,0x0000617d88846f61,0x000a437ea42aac2f,0x00012a4ea205a926,0x000adcb25d613e80,0x000fb7ef615aab09,0x0000000000000000}}, + {{0x000127afd82f8260,0x000f4ea3f09c69bf,0x000b49f3f0e43a3e,0x00052457b8b9c3f9,0x0004fe6ce00409f0,0x00044efa3e31f441,0x000e3e0240cf1253,0x0001f0b4a170983e,0x000d166b0cc9e8c1,0x000b455417a2207f,0x0000000000000000}, {0x0000fd522cdf167d,0x000b48039daf9a36,0x0007cdbcd7341cc4,0x000c7db3b7805076,0x000641b0db786edf,0x0006ea9b69b8bccc,0x000eded2a4e25e3e,0x000651b8f0911cf0,0x000614b601e95ba9,0x0005000aeb19e877,0x0000000000000001}}, + {{0x000c0c51d56f967b,0x0008dddbb7684495,0x00035dbc45f7bb76,0x000f9e6deda49098,0x000e73639006a39d,0x000878e5a247f77e,0x000cd83d141b2c8d,0x000804a47e332c8c,0x0009dc7a02d4027f,0x000b1b9934bb002c,0x0000000000000001}, {0x000777a838efe004,0x000368d9919c1d8d,0x0009dd721650f685,0x0002b1de892863f1,0x000d78f2b25a32a9,0x0002a4320690ff3d,0x00005a4af7bb8bc1,0x000cd763efcfe035,0x000701c70cf4f256,0x000443ef26775353,0x0000000000000000}}, +}, +{/* digit=113 [{1,2,3,..,}]*([2^452]*G) */ + {{0x000e0800cd422057,0x000077d1b7504d49,0x00004fd80e159ebe,0x000a18a8714afb4f,0x000de28810d8b90e,0x00019cff83f02c3c,0x000eb9e19367a867,0x0009952bac438786,0x0000e0748ecceb4e,0x000faa55aefa6646,0x0000000000000000}, {0x000aa315b1f2623e,0x0002b544f96e097a,0x0005dae237e7a5db,0x000873d0a9362519,0x0005569799223163,0x0001a58ea84d0fbf,0x000d43fd3bb728ac,0x000f100cfe43661e,0x0004f55c6f1cd21a,0x00091825dcbe9fa2,0x0000000000000000}}, + {{0x000fc794a5858d75,0x000a4affcd84d641,0x0005082ece4f5985,0x000b4853cf3bb3f4,0x0000bb1d8af65850,0x000953dc3e670d98,0x000424ef579458a6,0x0008ac2f2e4a7963,0x0000d771e540b685,0x0009be1f5fed2292,0x0000000000000001}, {0x0001be223c4864af,0x000fbb662c4dc573,0x000a57017521419c,0x000c0240d65099ca,0x000b13af88f3bfbc,0x000bc4861e1643ac,0x00067ed67405bcdf,0x000d9351f1c835f0,0x000d0e188cb8018e,0x0001f8d276f971ee,0x0000000000000000}}, + {{0x0006a9e449621f3d,0x00052e91ee418d60,0x0007e5ea0e7d2dd0,0x0006f73c92e787f3,0x000cc4508ea4869d,0x0002d461acfe248e,0x000bd24529ffcc1a,0x0002f90dc5dc22dc,0x0002f8abba336456,0x00056cd254e4f954,0x0000000000000001}, {0x0000aa036c0262fa,0x0002edc4f4234a99,0x0001031cef9b59ee,0x000145d5d5d4b081,0x00087df2c037b984,0x000a2d6af2c7b077,0x0006ff431d568532,0x000e309a7c9b6d5e,0x0006a3ee9bb40c66,0x000c81af9db41cda,0x0000000000000000}}, + {{0x0000f6f067a194c8,0x00066d7ad7abcf3a,0x00041cf832b531ca,0x000f470a4ac4965a,0x000cbe00766a00f9,0x000432af80a92657,0x0008968ac40c892b,0x000cbd44ededa94b,0x0008d46204be8b74,0x0005dd98f760bd2a,0x0000000000000001}, {0x0007f464f2479db1,0x000c0fdb3e7dcb2a,0x0001a96b28900b58,0x0000a2993c1d7ee5,0x00057bf0ce9357a3,0x0001f5d39eb49f5f,0x000fb8b8f0c1970f,0x00060718d4faac9c,0x000ec4ed9e1c25a3,0x00004bb0d7504b66,0x0000000000000000}}, + {{0x000c9e1b2fe9b1f5,0x0008d34221feb754,0x00042a589958e706,0x00008c19119e3c31,0x00021ac738645a87,0x0004d7be72a33383,0x000a72a39907dc71,0x000beb5759bb91f8,0x0009abd4b13e9374,0x000b96398db67d76,0x0000000000000000}, {0x0000945a75d3799d,0x00031dd530ad32ad,0x0000c605c645aa0c,0x000c247141d0f230,0x000876cc8fca8350,0x000943188b899279,0x0001484afb9ffa8c,0x000536d0aa571f07,0x0002b7a0c7fbe8ba,0x000c736f36c17e51,0x0000000000000000}}, + {{0x000618a7bb29e0e4,0x000c09c2bff10aed,0x000781dbe57f3993,0x000965b0e2b9baeb,0x00005cf5dc5bd4b3,0x000ce5975c6e0f92,0x000471ab0fcf2bf8,0x0002a2d43bae9f5d,0x000bcafa18f22cc7,0x0005911e3b357902,0x0000000000000001}, {0x00057df200a9fe3a,0x000b50d956c845fd,0x0007f211bf361887,0x0009b4007c382ac0,0x000ee4f517e7f4f0,0x0008256df5e905bd,0x000fa86a9368d1c3,0x000a7df56d37c426,0x000efab6ec26a5b8,0x0005cdfe9cfac9c1,0x0000000000000001}}, + {{0x00082202f99826cc,0x0004867eca10dd40,0x00071f5c4e281cfc,0x0007b5da880b8221,0x000325e5cd3e67f8,0x000671c0e0906564,0x000df4bd6ef65d7c,0x000c8a693695da96,0x00076e79dcdb1aea,0x0005bd96f080eaaf,0x0000000000000000}, {0x000240c6e69e5a49,0x00080c138884ae0a,0x0002f7e55e87844e,0x000a57d17ee0d45e,0x00033a1990475a82,0x0004fc5139e3efb1,0x000093a8d1fcb820,0x0007e2fdf23f8eaf,0x000aec2eac127538,0x000a0742581e77ed,0x0000000000000001}}, + {{0x000de604b9db6d8d,0x000262da62b65572,0x0009db8d0d3fb7d9,0x00067b7f8e9c2aa3,0x00074f2912d3c9b8,0x00079e6d831a5ad6,0x0006f3cc6935b1c2,0x00009a75e08b8223,0x000aaa28cfcf8f6f,0x0004f75ff407271b,0x0000000000000000}, {0x00024706c120a90c,0x000b4f991d9aa4ab,0x000767e06952ed85,0x00006ffc0793e3c1,0x0003d6115d975f7d,0x000c57472c131644,0x00024430b8651df9,0x000bda1a64f28b97,0x0006db846f1bbd8d,0x0002f562aea1650c,0x0000000000000000}}, +}, +{/* digit=114 [{1,2,3,..,}]*([2^456]*G) */ + {{0x000d810c86eab937,0x0008e6e6eb51bdd5,0x0009bc2e3a0e4219,0x0007e391c4b3dc48,0x000736ed77fe5eda,0x0005e60972cd0e3d,0x0001aaa05f70f41c,0x000db07669f426a5,0x0005914839830a47,0x00029045b98cf434,0x0000000000000001}, {0x0009d9c576932524,0x000409f4c3b8bddc,0x000d467dc9295086,0x000bdef23e6cf0fa,0x000729684c1e0fbe,0x000c3a23011daa3a,0x0008c4ef40ca0da8,0x00034dda12c0850f,0x0002c5e51990ccbe,0x000494c2f0adaf8f,0x0000000000000000}}, + {{0x00087b36a390065e,0x000c93a9bb0064f8,0x0004572329d651f2,0x00010e01d988aed3,0x000be48541e9e6f5,0x0000ac10a8abc023,0x000b700a8621efc9,0x0003eb208400f943,0x000d85b1c768bb3b,0x000f42634af0db64,0x0000000000000000}, {0x000e0a10a250b4be,0x0000634e42e593a7,0x000adef0026acaa8,0x000002da6f2f96cb,0x0008dca66aa2e955,0x0005a69e8157271d,0x000f32666dc76291,0x000c378977ddcf29,0x0000e5eaa07d6619,0x0002a548e47a94e1,0x0000000000000000}}, + {{0x000cd510985c6ead,0x000d1cc399a1876d,0x000fc77243f5c966,0x000c3b2c4abf82c9,0x0001efaf22c713ae,0x000a22e1704988df,0x0002a2d8f28a287a,0x0000f724ea967d19,0x000ed48e76179ade,0x000ff318acdc5b8c,0x0000000000000001}, {0x00063196ac8ad685,0x0002708e70052b0c,0x000d8ff45f4a08be,0x00064862e9bd37fa,0x000efcc39748e461,0x000dcfa2843cc067,0x0006ae8688367317,0x000b8aabfd38c458,0x0005642ea85ecef5,0x000873af78e84b81,0x0000000000000001}}, + {{0x000b763fd4a23b33,0x00004ce905f61100,0x000ad5b3ffa31c96,0x000817bf059b27d0,0x0004f957d997fe85,0x0008adabfcc9cea6,0x0002fa1bf24cb58a,0x000afe218a3174dd,0x000ee69ca08cb0de,0x000fdf310fed00cf,0x0000000000000000}, {0x0006e131eb000160,0x000a4d18c779a4d6,0x00013180dd747a1f,0x0009340c23f27ad3,0x00004df4a2f35316,0x000ec77b35a8c2be,0x0007fb23a1f8aa1a,0x0009e69edc272eed,0x000d58ddb6110abc,0x00042ae7590226a5,0x0000000000000000}}, + {{0x000f3cc8ae818a77,0x000f54ede150dbf6,0x000c2f06bc371295,0x0006ab2d173c2266,0x0007fda0b8b46bd2,0x00070909e3958aad,0x0005242beb035184,0x00006b5aad800c13,0x0003a70dce6b782b,0x0007761ebe42a4f4,0x0000000000000001}, {0x000ee87f40792877,0x00080b5c7acfe8e9,0x0007c5775efcb053,0x0007bf0a2d540e71,0x0008c839d644d450,0x000d1ff451c6b81a,0x0001b7ea45f8834b,0x000306bfc9c3c653,0x000cabe92f1a607c,0x000c13152a3731fa,0x0000000000000001}}, + {{0x000ad1ff805361f9,0x0003b3536327ce4d,0x0005b0b62672d1bf,0x000ddf3847367af0,0x000278798d158f13,0x0004fbc252a948f1,0x0006fc03d0fe92b8,0x000c0138676b978e,0x000ea4ba8ef9334e,0x000f98b13cf22496,0x0000000000000001}, {0x000ac5c627d693fd,0x00015f19d6d21fa8,0x000b4a2fb70b6705,0x0002c39928de441a,0x000db0fd9e912476,0x00096888c13371fc,0x00013f185fb68ee8,0x00092d86c189d0e2,0x0001cf6facea1f84,0x0005b949b94eff15,0x0000000000000000}}, + {{0x0003e85508c930d5,0x00050167c798885c,0x00018ef2850f4f27,0x000547f00d7f6b01,0x000899cb15ed2f40,0x000bc417a989d6f1,0x00008165c9378941,0x000bb0e0c28f2218,0x000839d9572ddfe6,0x000d6ab0b70e2e95,0x0000000000000001}, {0x00092c31b5a755fc,0x0005623261be8d00,0x0002ed776ec81547,0x000ed7b92bc72da3,0x0006d943fbdb47af,0x00096c45167b5a5d,0x0006fef44f208158,0x000d5bd5c28e23f0,0x000da432e8f4f6c6,0x0007b3355da25eae,0x0000000000000001}}, + {{0x00076c8ab8c349a0,0x000850693d15749f,0x000d18a6991254fd,0x000f60f54944e4ef,0x000febc73879cf78,0x0004c63e00125696,0x00042f68e1e2dbe0,0x000b688fd93a88e1,0x000f1e83abbe7321,0x0003aaa7b2fa13d6,0x0000000000000001}, {0x000caa293a9d97c5,0x00059519ff3b97cb,0x000cedb5893b39ad,0x00064ed07e59369f,0x0003315852af3473,0x000d5a40d47c32e9,0x000386582768fe34,0x000453f8e4c60653,0x0004a96dcf43bf2b,0x000e332542e1828b,0x0000000000000000}}, +}, +{/* digit=115 [{1,2,3,..,}]*([2^460]*G) */ + {{0x00011a7aae3fec0f,0x00081883626ec806,0x000aebe504491b56,0x00031dd2ecc113fd,0x0001068171e0f3fc,0x000d2fbb6b5fdadf,0x0000ee0e94a492b4,0x00090723f06e06c2,0x00016b906e2fed2d,0x00033b2f32d5d083,0x0000000000000001}, {0x000731c43f27e685,0x000c912924bed063,0x00058df5bd8f8996,0x00080e3a04d16a64,0x000303ff6f14cb47,0x000f56c8175aed03,0x0003011b62e0f3ec,0x000eee8bd1d8f816,0x000a055be5c28fa8,0x0005635edb8d9c9f,0x0000000000000001}}, + {{0x000eb4c2e9d6a36d,0x000f1c0e66e6ba0d,0x000058a747cb2451,0x0004b10a20962d66,0x000e1da104e82021,0x0004693d32e594ca,0x0003bb7f837609cb,0x000e53eda7c5059d,0x000b602751dd16ca,0x00007ac67ede2a3e,0x0000000000000000}, {0x00038202cc49b145,0x00003535c208aec8,0x00056079145b2fb2,0x000814d455be9713,0x00082fd8f0bb395c,0x000c755426c09f67,0x0000b748edafadbc,0x000deaf4bc3a4ecf,0x000bff049553943e,0x00057ee542c407a2,0x0000000000000000}}, + {{0x00058193376e77cb,0x000e72c0bba4380d,0x000bc54c3a89ddc3,0x000dd63a1bbc6d0f,0x000bf1518f660f2c,0x0007e5bf5faf2f62,0x0004682bfe7727a2,0x000da33defeb7b16,0x00032b5ef40ec257,0x000a0e902b2e8961,0x0000000000000000}, {0x000ab468387524e3,0x00024e69a88271e3,0x0004545479e82998,0x000121a7373761e0,0x00093e3b1f753397,0x000463acb40aaebe,0x000cb721af707dad,0x000c14e152331d6d,0x00065553048e5280,0x000612aaad009d91,0x0000000000000001}}, + {{0x00092b39f964e28f,0x000fa7cfd7976897,0x000f279c07ec556d,0x0001cf40d7670e8c,0x0007b5e04abdedad,0x0006fcc19990b137,0x0008572f5067ad94,0x000a28101c966a08,0x000b5e33c2ad58ac,0x000eb0e333e24c43,0x0000000000000001}, {0x000f0361a475ac89,0x0002dcf79463ef54,0x000dd053538c22ce,0x0001013b4e6817ca,0x000b44b01a6e12bc,0x000d109d85844a6e,0x000b985bfdaef54a,0x000f6830be544481,0x000fd8dd0297f121,0x0007cb6d0b67a68b,0x0000000000000001}}, + {{0x000ba65ede23b338,0x00026845dcbcdc45,0x0000a0b1cdddd83e,0x000092ea63968b4f,0x0004b71e6e72d35e,0x00046c5ed03f1ddc,0x0006efc5a166bbfa,0x00090de0b5f6b7c7,0x000445136c1387b7,0x000ba78923450ab6,0x0000000000000000}, {0x000a850194005e74,0x0009c00cae44ea99,0x000e5e17b631e4af,0x0001c80d51c0dae8,0x000120c3cbe08ee9,0x00023c8041a40936,0x000ada73446b0eda,0x000643d14026f215,0x0006fbac37813fb6,0x000fc70031b68bb2,0x0000000000000000}}, + {{0x00075ab901660b40,0x0001e645ee7e0ee2,0x00037b06a37399f2,0x00080496e9bd12b1,0x00026a5d50d58960,0x000c1e3f3705ba3f,0x000274a1d4a00817,0x000d2d00866a4d39,0x000f146bf0317c40,0x00024e2ec71ea064,0x0000000000000001}, {0x0003c199f5c7f563,0x00062e4f78f16893,0x000a194ad2a3fb13,0x000080225259655c,0x000bc5898f9da5f4,0x000553edffd8a6c1,0x000e20b2793c4797,0x00041ea73083e26d,0x000a2971a533d937,0x0000e54fd22035b2,0x0000000000000000}}, + {{0x000f9d4de9a27585,0x000400debb5987f8,0x000d526ec09e3156,0x0008bd03e0023f66,0x000aed7d715cc557,0x00058cc9c03099f2,0x000506b4417ca0c8,0x000d23b4df572ea5,0x000c5dc147420ffb,0x00032899652bdfe0,0x0000000000000000}, {0x00031987cf8e9148,0x000b259461ad7d0d,0x000c859a4a7e6bba,0x00030e2b3d2a289c,0x000e9be629139087,0x0003904cf1cf6e14,0x000cca9dab045a7c,0x00082a43de3eacb2,0x000d82c3afa439f6,0x000decd187ae70d4,0x0000000000000001}}, + {{0x00087b4497808581,0x00012be293d33455,0x0004ce4906c6f8ad,0x000a66938d521bfa,0x00046a914bdb3b26,0x000ae5f6e99dc3e7,0x00059dbb0881c2e3,0x00009191a1b5ac25,0x000c6a97a72e5343,0x000ddd07226ad4a6,0x0000000000000000}, {0x00039e249234483b,0x000669419af2063a,0x00042122752c72bc,0x000aa7e19a44c7a3,0x00011188ac573c28,0x0009a3360e14ec6b,0x000bc0bc86245880,0x000741e192993af7,0x000d8d75742bd481,0x0006cd8768555ba8,0x0000000000000000}}, +}, +{/* digit=116 [{1,2,3,..,}]*([2^464]*G) */ + {{0x000ebaeb9266fcb3,0x0006c49166afc8c7,0x000b1a4fb9f8df09,0x0003a2759ef63e0b,0x000ded0e62d1d0a6,0x000215cb79a13c16,0x000942482d5b46ef,0x000a5cf390334543,0x00039ce21c9b239a,0x0000a2fcf03ed34a,0x0000000000000000}, {0x000466a8adf517f0,0x000775523be0b6d8,0x00074759167493a7,0x000284c64894bb12,0x000e2864e9ca25e2,0x0008b7f98fd07d26,0x0003fdb6d6620610,0x000ef64b5a668e1e,0x000d31c44a0ba6ca,0x000891dac14a11ed,0x0000000000000001}}, + {{0x0007e005c5b2f805,0x00010b6d99c24dd3,0x000813da1409fa02,0x0008bf13d53cbcd5,0x0005bb6d8655f948,0x00021f224e5b2d05,0x00077dd3ba305b4b,0x00005337f568059a,0x0008b4b1e783aa9f,0x000d6ce8c56442b8,0x0000000000000001}, {0x0007e0acb71f23b1,0x0007f2e0e90fde9b,0x000336f8ff1da186,0x0004751614e3d072,0x0003187e51c7e8e6,0x0007ef17101ca72a,0x0008a9761c42d892,0x000ebb69cc0c641d,0x0002903e96138250,0x0006b8d2873a54c1,0x0000000000000000}}, + {{0x0007b97b6b68155f,0x000799e78b707b09,0x000e1f75bd19e80f,0x00035096285e6628,0x000d9b8661ae0f1a,0x000fe90a8911dc8a,0x00018180a1d7fb12,0x000733dbb76ae258,0x000085cc47bdbf1a,0x0008c417eada4711,0x0000000000000001}, {0x0006498715c0f18b,0x0008cd3093549e44,0x0007888a48d3a384,0x000a0d971c9394dd,0x000f79cc4aa385aa,0x000d44729501e42f,0x0002ea4042d9ad6a,0x000c1e43ab081b30,0x0002a374ef11901b,0x0009de3ad60e42b4,0x0000000000000000}}, + {{0x00023f47f06415e1,0x000ec51fe7219c05,0x000bd8a88f411a49,0x000308976713e8b2,0x0006ee0f84892d3f,0x000957e9fa410c61,0x000903d60b015584,0x000f41fc07f1fce0,0x000fa3ce182117ef,0x000654b039b5693f,0x0000000000000000}, {0x000f700d59c0d688,0x000bcc693fd9aa04,0x000b8b0e7fea0743,0x000182c181c35812,0x0008864896cc8fcb,0x000c77cf499f019f,0x00010bba6594c508,0x000e88406e142c41,0x000b45fd50fcaee7,0x0009894dc1ba3eb8,0x0000000000000000}}, + {{0x0007488ba3fe2367,0x000752106ad62ea4,0x000980bc62d3b8ad,0x000328ef733708df,0x000d47b00f88c069,0x000f6bb0176a2cf3,0x0009f6480ef1ba36,0x000ac0712001822e,0x00032f8aac418a68,0x000ff326047c12c9,0x0000000000000001}, {0x00039bbf3cc8d8c5,0x00091d5e4cf0789b,0x00042078d73c679f,0x000b71a650f7aeca,0x00082a530b74abff,0x000a71711bd8405b,0x000c3bb0ac95d510,0x00094cee94894b3c,0x000906c5e7b66990,0x00030a027cdba56d,0x0000000000000001}}, + {{0x000c446c47eef0c8,0x00044a0878421c07,0x0008722c55cf2755,0x000ec763424a48fb,0x000f4f6b5b3b9028,0x00078d4fe3ca8f7b,0x0003f4277d82e20f,0x000fbc6300a704e2,0x000a908b8f5f71bb,0x000b090bc8e8a53a,0x0000000000000001}, {0x000dcad6549fc8da,0x0004e635d31de3d0,0x0009ac9c9dae5fbc,0x0005d812525deba7,0x00028465a1ffb0b8,0x000039c002085422,0x000d1431962a343c,0x0001729577d460c9,0x000befcdb0fe4b63,0x000f982552806705,0x0000000000000000}}, + {{0x000c16470afeefa0,0x000c0df482969752,0x000988294a6b7345,0x000192c323f56fda,0x000ece866a0fbb9d,0x0003fb58e433eb87,0x00044e600bdf291f,0x000bc9a43f5fab4d,0x00060683951124ce,0x00065a7c641677f4,0x0000000000000001}, {0x000ce490f8bb04ea,0x0002e7ad3382ee72,0x000272231533e6b8,0x000186b13ffe5f10,0x000cc8faf0cc5e1a,0x000c709ed2b173b2,0x00067e514381962f,0x000cd58bc198455b,0x0006402864604346,0x0009d46f62db1463,0x0000000000000000}}, + {{0x0007bb607e896c28,0x000e0a894887a4bc,0x0006eb1e97614230,0x00003e71e2c653f8,0x00096dded494be93,0x0008ac95d09fc0dd,0x000bea563fba0619,0x0008f3c1624d738a,0x0009df64d4a0ea98,0x0001d5c6ae182338,0x0000000000000001}, {0x000eeeb900454516,0x0006377d7a8b0a7f,0x000a9c345a7de36c,0x000100d5611067e9,0x000806bcdcedd0a9,0x0002b5dec6f6c68c,0x00051f38d7d4a349,0x00022d5061b9ad36,0x0005c9ea7f739c0f,0x000ee734e6cedbd1,0x0000000000000001}}, +}, +{/* digit=117 [{1,2,3,..,}]*([2^468]*G) */ + {{0x000eb05013cb5aab,0x0009afca55bd420f,0x0009c3c71fd8695f,0x00000cafcc6e5ed1,0x000728edc89ca3d5,0x00076471854e21b8,0x000201f0ff872ac7,0x0003e23036d8ee45,0x0002c13f7c8bee8b,0x000707a1d51a1e5f,0x0000000000000000}, {0x00022b011bf68532,0x0000cf529ed8e280,0x000b8a477a52b6ff,0x000cd2f63b6e8238,0x0007c291c55c9cf5,0x000f4796ab42ab24,0x000c0989f93937b3,0x000bca7b47aa5dbf,0x0006f0a6b7620e79,0x000f58dd4ea00729,0x0000000000000000}}, + {{0x0004f87aac9cea1d,0x000fabffc3ba2342,0x000a3b2b167162b1,0x00073da5b86c7978,0x000769b5f991d83e,0x000cb3d9088d484c,0x0004542e085b4392,0x0004eba2ea8f2806,0x000c46cb82b91d2b,0x0008c0e83321f8cd,0x0000000000000000}, {0x00097601a9d31426,0x0009ef4a0c50dffd,0x000fc4b8056305e9,0x0000c1c8a29f6e86,0x000d4be1babedf5b,0x0005e98d4d558d2c,0x0007fd7d17d7bc87,0x00009a0a33b745e5,0x0008c2a2bc3cf9b6,0x0006235277b76d2d,0x0000000000000001}}, + {{0x000ad9eb395de05c,0x00050bddffa75224,0x0008d48f88a50e57,0x0005bffe3c2175d5,0x000aded74a44ab8f,0x000f36097483dc36,0x00041e5290fdaaf9,0x00051f0f28ee6aea,0x00006d6a082ff0ae,0x000068e3568c35a6,0x0000000000000000}, {0x00052b137174e56f,0x000a242808c3c521,0x000cee713ccf3a0d,0x0007f4523126e210,0x0009790a26049fad,0x000293cb237c8c65,0x000391754b82c700,0x0005060129b75ceb,0x000ad78c9cbc1be8,0x000452fab6d7a60a,0x0000000000000000}}, + {{0x000614e7a62b479f,0x00091b1806f1503e,0x000c937295d07735,0x000468f3b432690c,0x000027af2bc376d3,0x0001568b1fc765b5,0x00004c84508081cf,0x00093b08d2fa4f2d,0x000aa23530d43841,0x000eddd4118eb0fd,0x0000000000000000}, {0x00095d916a74bf7e,0x00052f879c30fb73,0x00033e906c3732a6,0x0009ecd6d707078b,0x000764fe7914feb0,0x000164429576e244,0x00070601ef70830f,0x00038d1a94c290ff,0x0007e067e8e38b39,0x00004d7b7a7e7934,0x0000000000000000}}, + {{0x00092dd8b3c6e87d,0x0006c49275954a31,0x00016b291ceab935,0x0002ae4fca80283b,0x0002ae3f769e974a,0x00047d8e3a1a96a2,0x000875bc17f080fc,0x000a5eabb84f45c1,0x000e2f2661df31c8,0x000663147f43e69b,0x0000000000000000}, {0x0002716571c12164,0x000b5580b0b11754,0x000bedf056c51a6e,0x00019d3572bd29fd,0x0006ce46ac6d5756,0x000d711d909ced7c,0x00056c0ec115b51f,0x0005ebe8c1ea4d63,0x0005d77cf7a0032e,0x000ddbec9919b1e6,0x0000000000000000}}, + {{0x0002437a972f2c78,0x00015b5e5010e549,0x000fb968e48079c6,0x000ee7041338af95,0x0007cad3cea2147a,0x00063a330c01aad8,0x000ecdd3002cfb58,0x000bf58e568343ac,0x0007567e97251d0a,0x000b568be5a71fbd,0x0000000000000001}, {0x0003982ec0a47e47,0x000862df20207b07,0x0002c656e08dda4d,0x0005ad59afe9aa6b,0x000ee04d8bf8d524,0x000d84cab42cc2b5,0x000ee837ff8c6d4a,0x0008b691af448525,0x0003b100c345fb36,0x0000d061abec1e80,0x0000000000000001}}, + {{0x000c9cc4477a0393,0x0002f0a9ecb165af,0x0008a80444bd4fb6,0x000a9d4dd001619b,0x0000b10c19a21051,0x000801b4ef3f9384,0x00076219bc4d71f3,0x000ea7190314526d,0x000da93e188e8697,0x0000967b67776acf,0x0000000000000000}, {0x0006ab2717f542c5,0x000ae82426abc0aa,0x000641af35023777,0x0005dcf6c7153a96,0x000977e0ee60ca55,0x000c371732ddcc64,0x000063579dd744f3,0x0004f34c496af4bc,0x00000f9df0536028,0x000b1c2a26167cf5,0x0000000000000000}}, + {{0x00061fdc0b1fc134,0x00059fe59da03f7e,0x00051831e7698bd3,0x0009f81df982fb68,0x0001c64253ce4407,0x00084a0c0fffbd0a,0x000fd2724ab08376,0x000aaefd7b900fa3,0x000017be08cd54b9,0x000359398932034f,0x0000000000000000}, {0x0008bfed571b358d,0x0006e5bd73f12c5f,0x0007574722cbd9b4,0x000789de672fc532,0x000cf9d4c5de795b,0x0008e00647313e84,0x00001e2002f19344,0x0007649a15d6dda4,0x000a4f04c96114ef,0x000ac34a9dc08537,0x0000000000000001}}, +}, +{/* digit=118 [{1,2,3,..,}]*([2^472]*G) */ + {{0x0005e5ed4ea72f88,0x000dc27eafbd5d75,0x0008274c8f222817,0x000e4b956ed11c56,0x0002ac506cd96a0b,0x000c56121cfca3c6,0x000e3c5160f64376,0x0001cd969d9794e1,0x0002818ba2a1b9ac,0x000bbd5d12cb946a,0x0000000000000001}, {0x000065269838f81f,0x000a256eaf242367,0x000743908912f4af,0x00048d332342e954,0x000f75565f855ec0,0x000e4ec59a3a8816,0x000505255b015d48,0x0006bf898ef06a71,0x000af90ae385313b,0x0001d5415dc8688b,0x0000000000000001}}, + {{0x000115486df6f2ba,0x000803b08c738eec,0x0002302443593e59,0x000e60eb4f00e934,0x000e57c91438ebdb,0x00080e89c523e859,0x000d75cba0053e05,0x0000d11317c9b329,0x00035e5703d38955,0x0003845aac6426d2,0x0000000000000000}, {0x000349105fa06b94,0x000e9b21c69e6c42,0x000f70eb1519a81d,0x000827ae2990539b,0x00048fe9bf0bbafc,0x0008dbb3c1ee9dd5,0x0002a908c4d4274b,0x000cb7224476f3be,0x00028346b6e6842b,0x0003ad39da0c7384,0x0000000000000001}}, + {{0x000a9a342fa007b1,0x00065415bb7a90ea,0x000dcc6aa0c26771,0x000a1f0bc720264a,0x000b5e93f7bc1986,0x000bf6b3fca182f9,0x0009a7b5c22f84c1,0x00087bdec7ad14eb,0x0008902c942c3b07,0x000a69d7973e7810,0x0000000000000000}, {0x000230ff44676602,0x000d3064b8821220,0x000d730a5228928d,0x000ea087c0f54e1a,0x0000abe8035de528,0x000d9e98d62188b8,0x000d85f12fe3f391,0x00095d1c13b3c4b4,0x000c9a4940436d0a,0x0007d2cc5f243602,0x0000000000000001}}, + {{0x000c484e2708d61a,0x000e14446b62d85c,0x0009c0fff451d84c,0x000a49ca08f1ae70,0x0003d71899e1ae53,0x000709a90d9917f9,0x000f39b12fbb0503,0x000038af72a2045e,0x000817cd90b8cc9a,0x0002f352b4ed83f0,0x0000000000000001}, {0x000a71d48ae023ef,0x000d8744e50d53a7,0x000192ec22667e7a,0x0002e19437867d3b,0x0007124825f0cce3,0x000aa41f07fce902,0x000fc674b8262125,0x000d1f602e03c9ce,0x000f93cc0c071ae6,0x0003fae4c52caef9,0x0000000000000001}}, + {{0x000d102ba58b5201,0x000cb021f49742da,0x00078984de6430a2,0x0005002098f1e552,0x000c9b804a37766b,0x00095479cd052eaa,0x00083f87dcee9cc2,0x000ce159b125b614,0x00001a384dc69331,0x0002e4ec5a2f8699,0x0000000000000001}, {0x00049fffc681e26f,0x00001b52ea90f687,0x00080117445f69ef,0x00093fb5f32e704c,0x000d36110b81abea,0x000a3e64f4ffada3,0x0000ff99dcba475c,0x0000eb1b968c2040,0x000ded29d4be59cb,0x000ba78061ed859d,0x0000000000000000}}, + {{0x0004949755c59603,0x000c796691a84904,0x000a8445d0aabdba,0x0002396cff6a7bd7,0x000562547f935def,0x0009038b91c344b0,0x0001f20274812ef2,0x000e1fe565e5087b,0x00074866fd902829,0x00032844aad6b8f8,0x0000000000000001}, {0x00092e9251d05a0d,0x000328420cd4a328,0x000e00dfce4ccaef,0x000beca3a94d516d,0x0000fce64bd11bb9,0x00054cb1e99e5269,0x000cfc1bfec9624a,0x0004e634fe2023b3,0x000e53481128c3b5,0x000cd2258147276f,0x0000000000000000}}, + {{0x000e9ad8d783865a,0x0008e5a58d54402a,0x000e236d64e3be62,0x000daf46f4aae16f,0x000049ba7000cd7f,0x000deb437c36e86b,0x00025e5a9179d63e,0x000fb30e5ec5adff,0x000fc4d691408156,0x000d8b4dff418608,0x0000000000000000}, {0x000c4eed479219ce,0x0008e4d5ead8e114,0x0005f4f71316535a,0x0001c636b70e9489,0x0008aa2310479eec,0x0004e1dcd4f2eb70,0x000474c99b5134b7,0x000ce4754e99035c,0x000218919b4c0dad,0x000e1d1dd3f97981,0x0000000000000001}}, + {{0x000cc18c358773b9,0x00036bf6385f12eb,0x0008a0c24ba8caf5,0x0003093cd83891ca,0x000f5b8c3762108b,0x00041e3399b26a0e,0x000fadfca8c426db,0x0004173bf6760263,0x000a6677ad40bf58,0x0004eca4760acdd8,0x0000000000000001}, {0x000c42b8b4207fa1,0x0006dc5a60d34efb,0x000a367e08d67868,0x0008cead3e942c85,0x000409d289bdc2dd,0x0004b034c3a6d1bb,0x000889304955940a,0x00080034f3684e43,0x000808a7cddeee0c,0x0001148f3d9aa263,0x0000000000000000}}, +}, +{/* digit=119 [{1,2,3,..,}]*([2^476]*G) */ + {{0x000df4a3fd3e1bab,0x0006287d84daca3d,0x000d7eaf57017e3e,0x000d1a4e4870b354,0x0004c26a3e3ca9fe,0x000ce1ea5e5710e0,0x000709e17a2ff920,0x0000f8a3bc06ee67,0x000788ab8c019a66,0x0006f43d909c0fdb,0x0000000000000001}, {0x000c0c61eebda5c3,0x000395c130704b51,0x000762ffbcb5d086,0x000f660bf6639983,0x0001646d9fb03337,0x00065cf06a8fa37c,0x0005f2e3f14b6d28,0x00088227d360e736,0x000a48fcdc5c3e58,0x00059e8c2eaf07b6,0x0000000000000001}}, + {{0x0001ce2b5f2dc50d,0x0007e39f8c4d01b0,0x00078d34284f417d,0x000d157acbf04214,0x000c0c4238071f59,0x000b0a1e05f8a594,0x000d81bbaf85cdc7,0x000d1d1329e8c9cf,0x00068fc55c9be4f2,0x00029b5c20884e31,0x0000000000000000}, {0x0009fd4109cb4727,0x00021d96d542276e,0x000d61e57db16c16,0x00052da58656adf3,0x00089d546ecce2da,0x00041508ee2098e0,0x00011997499c874b,0x0006f525839d9cf3,0x000de08e59654896,0x000e511cdd85c0a0,0x0000000000000000}}, + {{0x000db13610c4d993,0x000192018344e51f,0x000cb8a7e81016f0,0x000425ff1ca2c27e,0x00047a8df5318c36,0x0004872bcd56d5d2,0x000d142a2e0d2618,0x000a83feb22e4866,0x00013dac70999b14,0x000ed007863be6ab,0x0000000000000000}, {0x000023bbbd62b467,0x000e6ef8f48d21ce,0x000ea9c5f9c35940,0x0009af532bd76e0a,0x0000f8ff97911a1f,0x000efcff41750c50,0x0007cfa3985ad13d,0x000136812ef99c02,0x000319ee534694b3,0x000b9d9722dca85d,0x0000000000000001}}, + {{0x00040d25bac4c923,0x0005026132b9fa82,0x000ddc2ef3e74ec9,0x000151b0a9db4e16,0x000ff5ad95c1429d,0x0008144cde9bb57b,0x0000c02f2a19e480,0x0005655b0b6aef98,0x00038725b1f2df6c,0x000672346457ed21,0x0000000000000000}, {0x0003077ffe12bd18,0x000e682804b9bb8e,0x000b8a3a7328db75,0x0007b6f50cb1bbec,0x0007a823e8549b58,0x000d7be7a7e70575,0x0007103b60b8617d,0x0004131d7bc32367,0x000713f91128ac22,0x0000deadb3b9bf03,0x0000000000000000}}, + {{0x000b46eea58e4f6c,0x000e8500cef9c4a5,0x000e36179b50381a,0x000498cb317e7dbb,0x000df2d824ab9ac6,0x000aa97d96328707,0x00068fd80e79f5f6,0x000ee03799c5c193,0x000688d4b109d20b,0x000fae5dfd91a5a4,0x0000000000000001}, {0x000e4aa8649aaa1b,0x000caf8a4a894ffc,0x000f0a6af855f3c5,0x000fa6ef0a082826,0x000564cf46392869,0x000d9060255a7500,0x0007688b437590a1,0x0005fa2a21425afd,0x000dd69d65b91f19,0x0008045302895146,0x0000000000000000}}, + {{0x0009a872aecfc094,0x000c8cde3af050fb,0x000ebe6b500bec0f,0x0004d4b7e7c4ef2e,0x00094b38a6c4228e,0x0004f9fb0e82362d,0x0000dbf4e229d20c,0x0003a6e45bdfa369,0x000b1c90f730c74e,0x000306f2fc481fa7,0x0000000000000000}, {0x000e496c4b887a36,0x000e6ae46148f8e5,0x0004268188f16f8a,0x000cf1b360936452,0x000ea828f2ec9dce,0x000a581be5eec097,0x0000a093e062b3a8,0x000e4da12b498543,0x000b50541562092d,0x000eae33c27b17cb,0x0000000000000001}}, + {{0x000bed4ffad0684c,0x000bb264e57bfffb,0x0009eb6b035825f2,0x00013466fd8b6643,0x000ab9c3537903c2,0x000b0366be7313de,0x00096ae2121723c9,0x0005953e87c3ac29,0x000b6974bbd38278,0x0003e43a30236cf9,0x0000000000000001}, {0x0003b2707ffdea7f,0x0002da68809f795f,0x000374c5228ca4a1,0x000ef9a132cc5a86,0x0002bae5f8c0d15c,0x00061ce20672616f,0x000abed75c41da6e,0x0006a5fc5af7de33,0x00076a4d15065912,0x000ed44c16e78857,0x0000000000000001}}, + {{0x0003498018e534a0,0x00031b029f064c8f,0x000b893aedc07be9,0x000b0eea14f71f6a,0x000eee179067b242,0x0009f6bf528af895,0x00020985e852a279,0x000b94bc19691d5c,0x00005deba296ab7d,0x0000b231b9475f76,0x0000000000000001}, {0x000c45d63f8d3bc5,0x000aab0d9145a0f8,0x000bc0cd8bbb3a1d,0x0001299d614875d3,0x0008bad650d624f5,0x000b91d8407baf74,0x00054a383b9d385d,0x0006840ae765f5cc,0x0005a54bdbe2653a,0x0002865728a0edab,0x0000000000000000}}, +}, +{/* digit=120 [{1,2,3,..,}]*([2^480]*G) */ + {{0x000e419064732d33,0x0000fb9f1fdd6e2b,0x000b458dd169ab15,0x000b79def3f55fa5,0x0001fd9b88ebfb1b,0x000b8b17a8c1d98e,0x000e6b37f6beb8b7,0x000dbc72340b6c86,0x0007c19d37bb70ed,0x000f6867a99418dc,0x0000000000000001}, {0x000a4a09f22c0fb3,0x000bb19cb6bc1256,0x00077d8b51c8ded9,0x000574809f35ca45,0x000bef1168ba7eb2,0x0002cdae11770b52,0x000ff68ed4f42bd1,0x0003d326b225de9d,0x00037f1445631a8c,0x00012cb14a3c371d,0x0000000000000001}}, + {{0x000b0b95f0603f03,0x000fa7f969adad66,0x0001acf774657813,0x000a2615220707f6,0x0002f71d4cd53712,0x000f82a44a2fd4ef,0x000773fd9e262931,0x0002f763ad200681,0x0009b206fe31fd70,0x000765c3a8767fa9,0x0000000000000000}, {0x000a7f8ce84569e5,0x0009a821c3dd4741,0x000e90e3290cc915,0x000cf99306b623fa,0x000d7531760ae9e8,0x0009e7cf282874af,0x0006e1ae6527ae8c,0x0008f99eef73293d,0x00037109e03d3d87,0x00036ee1efdba892,0x0000000000000000}}, + {{0x00051928ed074ce9,0x000b292af7a58dcc,0x0005ec5d4bdfb374,0x000cdd85d01fb1db,0x0006e626365656d8,0x00074fc478641e47,0x00016a5e28d244d6,0x000adbaa94ddb39d,0x0007fdde95fd5183,0x000b47ea66d8626b,0x0000000000000000}, {0x0004c9d4962ab02a,0x00021388f7fd2b57,0x0006c23d66031232,0x000a1a6ab2ca0c2c,0x00017664a406bce3,0x000f5497442ca199,0x000866b6f2fc1498,0x000a41cbc3b0ab32,0x000557ca37a277ae,0x000af01602653825,0x0000000000000000}}, + {{0x000db75622a8dfc2,0x0005479be9e5c74f,0x000548d39ec29bd5,0x0007942d29c79da4,0x00079c4bc1f5df3f,0x0004a7cecb948e1f,0x0008793b63229ed3,0x000939c1a7d67689,0x00057ad78be3b341,0x00052f2801351b91,0x0000000000000000}, {0x000cbeae6fece889,0x000b3085ddee3b59,0x000eeab1d348140d,0x0006bba941a033c2,0x000b685703aafb67,0x0005046b6423a9d8,0x00075dab832a7c83,0x00015b8c259b9e24,0x00018a6bbb51f863,0x0003a253eb5dc8db,0x0000000000000000}}, + {{0x000cca37a85cafbb,0x000b3657f26e3623,0x000787ec793c4d2a,0x000337f7520b9137,0x0000dbcfb7906436,0x00018cfaf22caa7a,0x00044625a502d754,0x0000066c6a130ba1,0x0001212f51d083e4,0x0004ebb9541e99d2,0x0000000000000000}, {0x0009384f4e2ab22a,0x000ff707cf7953a3,0x000aa5f9b05bdfba,0x000626e81b083e95,0x000defb350599782,0x00092399d206f421,0x0008bd9415729d3e,0x0008cf10387904ad,0x0006e0bc19370ad7,0x000b48f2c002a076,0x0000000000000000}}, + {{0x000b8bb85d8adb3e,0x00067b9a142f9bd6,0x000fc51be0f979dc,0x000cb118f84e32d8,0x000a7f5b6ca36f9c,0x000a900f565e79ab,0x0003143fcfd2df63,0x000122db9b751516,0x00086015e5f85f9f,0x000bf0e7c48af6d8,0x0000000000000001}, {0x000cbc466d0dec7f,0x000fcfc13f4daf5d,0x000613ac2b0043ae,0x0007d2ec60909041,0x000eff4b79cb6956,0x000e04188e57b5e5,0x00045aa9dd05dcf8,0x0007cd8106c6759c,0x0004b84b0c6c633a,0x00041ee796334569,0x0000000000000001}}, + {{0x0008ed21f68b4a3f,0x0009e0f39b982afe,0x000ef033664df945,0x0006109c1245ad2f,0x0004d6578f9c34c2,0x0008e9fc097b7383,0x0007b3121a085c72,0x000365666df584bd,0x0007af58ed558596,0x0007e9fd1e18ec9d,0x0000000000000000}, {0x00017df29af6bc16,0x000dbbf468848de7,0x000d747cd3b7c888,0x000801a051097e9d,0x000f68bb9b824e70,0x00027a8a5f172bbf,0x00074f9f45d5351c,0x00080ba6fcc24020,0x000d4e050d7e5a57,0x000cebcb9d2f1cc1,0x0000000000000001}}, + {{0x000b990fe3b9d773,0x000eb81096bf3df2,0x000eb580e653b2d5,0x000cfd31a2ad7396,0x00065cddd150bca4,0x000cde916b4cdae8,0x00019b56ffe74e35,0x00021e7dc0b21b6f,0x00099d8bf333016e,0x000eb146cec318c7,0x0000000000000000}, {0x00030acdbab36d51,0x00089ddd1e911c98,0x000891db5801a0df,0x000f1a5d646bbddd,0x0000ac4d27510e25,0x00044af2f910d55b,0x00024a75bcea08e1,0x00037ae5f37d50da,0x000d372739ad211e,0x0002a2d9d5c41773,0x0000000000000001}}, +}, +{/* digit=121 [{1,2,3,..,}]*([2^484]*G) */ + {{0x000ce74763660052,0x000da3e409da1731,0x000098b5f715b328,0x0003538d607382a2,0x0007bc3ee7b0651c,0x0006d5eed9abf1dd,0x000eb18e8c0d16d9,0x000e3fe464dc1a4c,0x00030d6fa6b9f8f1,0x000cfa359d987d0c,0x0000000000000001}, {0x00047d09810803ed,0x0007b5b97b578929,0x000cc27fc5005d73,0x00040feb2087e2c1,0x000b7dd0d960662d,0x00025ee555f37345,0x000d7c17f3858a72,0x000a0cf2ae739ae8,0x00000ee77dcf4e1a,0x000c12649e41ecee,0x0000000000000000}}, + {{0x0008de672d619b61,0x0000ea8326922a80,0x0001a0841b015626,0x0000f8a963e3e317,0x00037806aeb44acb,0x000d9d8a14334837,0x00026bd761a3419a,0x000d2e7a343fbffd,0x00086e32c6d361b6,0x00023ef433219c4d,0x0000000000000000}, {0x00025620f22d4f25,0x00067dd5c03d381f,0x00080f734643a87f,0x00006c5ee876505e,0x0002b491baac4e49,0x0003e07deb178a01,0x000ad060f735b869,0x000576ce5dd8d75f,0x000dd4cd9c97cb18,0x000cbc634bbb55f5,0x0000000000000001}}, + {{0x000b9733710e8e01,0x000e73a5711788b8,0x000bf8afcacf73a9,0x000d6725ee57149b,0x000e7fe486c64e2e,0x000322f9087bd5a6,0x00009af08709418b,0x000084990390cb99,0x000a6bb3ab911d03,0x000d2868a69e665b,0x0000000000000001}, {0x0005e749b382f6d2,0x000a9a1034406b89,0x000826ec06265b52,0x000e64e9aec95b07,0x0003982f9a9c5d16,0x0000698b37d7e83c,0x00050d8bbdbeb42b,0x0007c82f4fbc8ae9,0x000adc1e63d423d5,0x000b249310802372,0x0000000000000000}}, + {{0x0007033614a6d5dd,0x000fddc5f2fac137,0x000e014aa4b4dee5,0x0004a9b72218fde8,0x000c10e229612a68,0x000cb5b99f1d9b66,0x000eff01796c1307,0x000ec087152271c7,0x0009f171d27930b1,0x000dd53091f21ad1,0x0000000000000001}, {0x0004c873e4172f54,0x0006ecbd512368a7,0x000d3ea21d4bc31a,0x0003a95f62eff689,0x0007c73a33474bd4,0x00088fa97a141350,0x000b4d3b01846eff,0x0005fbac8f6a8f06,0x0009ddd58dc2a301,0x00001f7b911f1a15,0x0000000000000000}}, + {{0x0002e681058bcd0b,0x000ecb766f6bc98d,0x000866fedccaaef5,0x000b2e2473204d11,0x000f6e18757016ad,0x00011d59effc1a8a,0x0002050629e88cfc,0x00093c7bdc024782,0x000a9b2aeb9bb00e,0x000336991f06d2c0,0x0000000000000000}, {0x0001568955531744,0x0008281170681859,0x00050d7be99cf6e1,0x0008cb9d185c0963,0x000f49cfc22a2afc,0x000f9d20626a2a56,0x000ad87b48f04b95,0x000bd1441cc30d3e,0x0003e9b72d43f56f,0x000e3b3843d17383,0x0000000000000001}}, + {{0x000e873b05f77e97,0x00071d5ebf3c8d2f,0x0005b9ca7cc32fe3,0x0008798cc245b054,0x000e6eaf83f8b265,0x00061d87bdf09afd,0x00048a529e1b9707,0x00001501c97ba4fd,0x000ca96655ab0a10,0x00042f0ec7beee1d,0x0000000000000001}, {0x000296b82c7a9289,0x00070c171dfdb228,0x0001dac3a3a171bb,0x000b7ea6ad9a13af,0x000251fe361dde21,0x000cea9acd2f8b81,0x0008480e8df3c1ec,0x00038a5f495ca4b4,0x000fd225cb8ecc78,0x000454bc6bffc707,0x0000000000000000}}, + {{0x000af33412f12687,0x00015e41163cf0f3,0x000967fdc5a6a476,0x0004235cf9f62e34,0x000b314d06a6a848,0x000820f5665619a2,0x000f11a14ea427a8,0x000ce9a80c44b6a1,0x000f92bed7985fca,0x000dc713540bdff6,0x0000000000000001}, {0x00065826c0cb51e6,0x00030220ec95e76a,0x00064aea77a786d0,0x000cb5ba9e93c602,0x000f020c5b781189,0x000e7b4655282299,0x000e97af8ea95e4d,0x000a8a80a0f194a4,0x0006433581c41d62,0x00066e34a29ca8e3,0x0000000000000001}}, + {{0x000cef36ab807b63,0x000040cdf4c99984,0x000c211953a5f8d7,0x000ab4c0faefc5ed,0x0005ca17066a1563,0x000fb2c0940c339a,0x000b1e8517a5667a,0x000c3d2a94a0b135,0x000185e4d4526e2e,0x0001b53c05d493d9,0x0000000000000001}, {0x000c5ced3676f843,0x000195ff470fab2f,0x000ed29f4a221ddb,0x0000868b2d94f5fe,0x0003caf8fcc5069f,0x000dcfc1418631be,0x000998943a070623,0x0009bafa5f731c9d,0x000c5c56c1cc4a06,0x000a82f502e626e1,0x0000000000000000}}, +}, +{/* digit=122 [{1,2,3,..,}]*([2^488]*G) */ + {{0x0009edf282d019ec,0x00099e8e335e18d2,0x0004ace8ce0e046e,0x00001d0f72c0503a,0x0007e9c6d09e242f,0x000998b6c2fcb456,0x0000be40686ceb13,0x000db8fca6af9143,0x000c77e852236ef5,0x000ba3718e1a2901,0x0000000000000001}, {0x0005ae430ab427d9,0x0003d8a843a1b6ab,0x000c9500fb6025f6,0x000b9cb8d803e788,0x000fcea023d9bfb7,0x00003f3ec5cdad70,0x000188da7e50d4c8,0x000f9eb540fd9c07,0x00014ab57822ee2a,0x000574aff12ba00d,0x0000000000000001}}, + {{0x0003c20dbe0952a3,0x000480b6013f7fd5,0x000447348d109d4a,0x000fe6fecb6a7da1,0x0006564e8c529d8b,0x000034045fa60672,0x0003ee2a8df68fa9,0x00021796dbc7ff3f,0x000a130fededc279,0x000fe24c3f368ae9,0x0000000000000001}, {0x0002961eb9eed66d,0x000919ed55f27279,0x0000068193a9b014,0x000f317444cb0bf8,0x00096e22227ee32e,0x00047c8b854cb4a8,0x000bf6dc6a73b281,0x000d6804296e2ed1,0x0003e6f8a77be001,0x00084c89b143ab22,0x0000000000000000}}, + {{0x0008d791f2d40215,0x00003b05d1fd525c,0x00037b16b3ca30ae,0x00070792a856131f,0x000b7639faf0f678,0x00006b7cf12eff42,0x00098ab7a44f2173,0x0006714e846ec06d,0x000eac350874a266,0x000b56e5920dc3ae,0x0000000000000000}, {0x000d703e34853d1e,0x0002cd53a7cce717,0x000410bff4f394e1,0x00074ecb0bba0cc1,0x000de8fa9da2c436,0x000f5e3f74e2caa0,0x000cc28b148d1eb1,0x0009fc1ac5bad585,0x0001220666fb73af,0x0000c3241a57ee07,0x0000000000000001}}, + {{0x0000e99218ea1f1f,0x000ccf21044500ec,0x0000c873630cba88,0x00064f806fd4e4b8,0x000a7056645dd457,0x0002ed87394551a9,0x0008987025ba6b17,0x0005dd01b45fa9a7,0x000ccea3a1f9f135,0x000592807cbab8d2,0x0000000000000001}, {0x0006c96e8e24e119,0x000d921a51e8134c,0x0002ab9759957065,0x0004035ca89e1baa,0x000df057c2aafabc,0x000c0890aa1a6716,0x0006bd3f802387d9,0x0006a39383e5c778,0x000601e4e1f62705,0x000096f226577900,0x0000000000000001}}, + {{0x0001d3b5076ee66b,0x000068e996c31106,0x00063f8bf5d922ca,0x00008ed44203a2fa,0x0001df0821d991eb,0x00019d54e602f04f,0x000bf35cd4ee7bb8,0x00015f2609e3729a,0x0009e8e65b2fcd60,0x0001df9e9c109298,0x0000000000000001}, {0x00058eae5edc3042,0x000fe31ba09cdc97,0x0006f52853b56fdb,0x0003df0f5ca36adc,0x0000a54940d61878,0x000902cef58665ba,0x0004efbb68e67641,0x00036806e0aaf0f5,0x000194a89e785e8c,0x0008883379ceb241,0x0000000000000000}}, + {{0x0001a19f7b341ee3,0x000076e0e5354bd1,0x0001806a485286dc,0x000d2bf681431840,0x0002c82334b1343e,0x000b6908add258b2,0x000737bf47a5dbe4,0x0007303c531a0b11,0x0003a29d6501615d,0x0009313aaea01e10,0x0000000000000000}, {0x0007b22b906a725c,0x00024ad4ce011033,0x000bf242639d28fc,0x000fa39cd38de6c9,0x000a72beeb0f8fd8,0x0009a0ad9b93380e,0x000c8221fc799b7c,0x000be51116d9d8de,0x000a10526402ca53,0x000777aa2c9ac3b1,0x0000000000000001}}, + {{0x0001a723455b8da2,0x0001d0c7c777796b,0x000fb41cc9b1644a,0x0000ef5ce0972939,0x000637a26ddcdf7a,0x0008cf1a639f0844,0x000023a3ce642ca3,0x00098f7db827cdb3,0x0005279eee7f6f0d,0x000565523e47e762,0x0000000000000001}, {0x000fd1b034828d4a,0x0000721a61eafcaf,0x0001ce95f4ec0ae3,0x0003ba2db4a66fba,0x0006525e6f06fee9,0x000817b26fcb0ef3,0x0000265db68ac06f,0x000f74e811cb24b3,0x0006550f9c2bf885,0x0003940f2d2fcd83,0x0000000000000000}}, + {{0x000e8955d1b109b2,0x000e1de1d0f381d4,0x0006407a6cf45a79,0x000f2393e689a76d,0x000d3d92aed2a407,0x0005547cc6ac261b,0x0005e0b9e62fcac9,0x00081e2910774983,0x0003d6780dde8f90,0x0003c5c4cab77f7b,0x0000000000000000}, {0x000e052d3f3dc82c,0x00039caa1aeecdbd,0x00024153092958c9,0x000c11b7ca5c0f7b,0x00027c92847965c0,0x000732af643698d8,0x0000367351c0ba1d,0x000f1b1bf491a3ee,0x000df3514ec2302c,0x000b4c4436d640af,0x0000000000000001}}, +}, +{/* digit=123 [{1,2,3,..,}]*([2^492]*G) */ + {{0x0004265bd7179d88,0x00032014b97128c5,0x000fd3dafdfe0b08,0x000b1956b3fd6699,0x00091416a87bbb8b,0x0001dd4344038f86,0x000566c88826c840,0x000f07a8a4b77456,0x0007671e1b2fca59,0x000200797dc52a03,0x0000000000000000}, {0x0007843bbe8d7f70,0x0004f9ee9b4c465d,0x000303b1652fa39c,0x000ae7c4c4a55ae2,0x000263ccdcb67c15,0x000a17fd06da8ac5,0x000c10d8d1d1e927,0x000e5bfc6232685a,0x0003162cd048bbb8,0x000b11c2cffebb23,0x0000000000000000}}, + {{0x0002cb202ec3c178,0x000285de81ad92d1,0x000b71b77497dfd0,0x0007a8a10c150a03,0x000bbe99f4ad3f59,0x000f4533b0aef51d,0x0003b27838ed4931,0x0008ffc95a8ebcf1,0x0002cefcf5623ddf,0x00010737c166832b,0x0000000000000000}, {0x000e740d8da2ff7e,0x000624f3d3ab048c,0x000376415ced03ed,0x000fbe5676391c7d,0x00081671ffe7b22f,0x0000390438cc5f49,0x00084a5ae289dd49,0x0008f9a1f5bbef09,0x000b05c4941c6652,0x00083aef77ff073e,0x0000000000000000}}, + {{0x000604a9bc6900b6,0x000878e5f51ce9df,0x000b763f98cad97f,0x000f5a1389d3ab54,0x000ab3d0efdef6fe,0x0009be5cf0df2543,0x0002a0d518696763,0x000134850193d832,0x000860abf9047761,0x0004b4f04b3d8de0,0x0000000000000000}, {0x000e57c44a551894,0x000a3fa66238e065,0x000d140af7878a12,0x000de14d55dcc858,0x00061c7b391cc65f,0x000d7dbf324d8825,0x0005d09aa74e78f2,0x0008ed166a4503f8,0x000da0c2a7ad860c,0x0002048d8fe387e6,0x0000000000000000}}, + {{0x000505ddc7162a8e,0x0001fb5ed0deab66,0x0005e972cc689dc5,0x000e495fb69dc78b,0x000ca3f1826690c6,0x0005f6186896d605,0x000fd32f66789288,0x0008863f96f8edfb,0x000e644e5dece22e,0x0009b7f857a4d564,0x0000000000000000}, {0x000691ddbeebfc5d,0x0005901566a70055,0x000e1f4e6067fa43,0x00086e62796a672c,0x000b4e5ee14cf308,0x000b327c1a40aaca,0x0002fed3294bd689,0x0009103e56992c00,0x000b1323df8494f5,0x000d7b51fec2bb9e,0x0000000000000001}}, + {{0x0009f1b91641749a,0x000415c17bca5ff6,0x000c6d3a845d2248,0x0005f9b6f404856a,0x000cbf400b63630d,0x0003b4ba273b60be,0x0005d238fa843e67,0x00015df9fe916d32,0x000747b338f22dd6,0x000213df0dde0478,0x0000000000000000}, {0x0000235c1fe8e923,0x0003196a6c0855b8,0x0009e7caa33347ee,0x000bc0a45596b47b,0x00011e3fa8377c58,0x000acaedbc6f8b16,0x000fc365c99edd72,0x0002dbbec0f6e0a6,0x0002b70a4b7723c1,0x000a4bf65f3c20c8,0x0000000000000001}}, + {{0x0004bf14c1a4d603,0x00062d773ba946d2,0x000a858973ed2e17,0x000af47e821e4637,0x000c4e2f1b685a3b,0x000a24d7fe743f00,0x00011c916f0b3711,0x00019d3f29631796,0x000070eeb3ea27a8,0x000fcf9d0e9d8d24,0x0000000000000001}, {0x000a9e0cc6d6de0a,0x0007d8c5fca34ad4,0x000c81d46494c7d6,0x0008c618856d1751,0x000ea22fc514e835,0x000e085f741c8235,0x000c321d004a049d,0x000bcb516087e553,0x0002d6363ccbbe68,0x00083e572fe7f6b5,0x0000000000000000}}, + {{0x000e20ba96faf5c5,0x000e8d8c8a0cc4ab,0x0009b5c593a344d4,0x000c6c34af049395,0x0005aa8d456d94a3,0x000ed953bf7c9473,0x000962cd0b8cc1dd,0x0000c01bb3088b5c,0x000c82c42c7d7139,0x0005bd26c576d9ee,0x0000000000000001}, {0x000ee2f364e79144,0x000e681f5a9a561f,0x00014c6812d4021d,0x000e552f50051d32,0x000f6a99f35033a6,0x000e505a2349153d,0x0001622a1be8e97e,0x00067971f625164b,0x000d441d9fc2328e,0x000d2eb0550478b4,0x0000000000000001}}, + {{0x000769c73aea3c08,0x000df9a9593240cb,0x0004e8217f3b057c,0x000ceca2220054ab,0x000c95ba1c2a734d,0x0006500d1322b719,0x000ec571b4360381,0x0006f76e87cb0ba1,0x000c5938559db2c7,0x000397be033b5877,0x0000000000000000}, {0x000b6a77feb075ca,0x000d9cc6a6cde3dd,0x000e49872538f578,0x000e469feaf37819,0x0002ddc9c48cda10,0x0001a6e5450f9883,0x0002d31bf05ea5f5,0x000375cd216a195d,0x0008007e689987c4,0x000cbc358f3e07d1,0x0000000000000000}}, +}, +{/* digit=124 [{1,2,3,..,}]*([2^496]*G) */ + {{0x0006a73f6f2770c4,0x0000f968ca281cd6,0x000827efca6a0867,0x0003a96b180e8f32,0x000809979b757eac,0x000d9223bfbff7df,0x00047dd166015fc2,0x00065475a88730d7,0x000ce16229ea9d12,0x00076d23756de3fb,0x0000000000000000}, {0x000ed537bee27c6e,0x000943e46c7c15a8,0x0004b3f87656d7df,0x000a9213335be530,0x00076cb0ee208db8,0x0004f5fc16b61ee3,0x000c1114ee85495a,0x000253ced62c2d47,0x000641c92453ad35,0x0003e4e1a21d73af,0x0000000000000001}}, + {{0x000483ff2c9de102,0x00017f0cb9492bab,0x0001999673c19107,0x0005c7a75ba40ad7,0x00022ec8c1ec861f,0x00078704457a9540,0x0001194ab6d023c8,0x0000daf5008c607c,0x000d394925361233,0x0005ab5bf20a934a,0x0000000000000001}, {0x0008ed3301b16277,0x000b31045574d7ab,0x000ed11cb44f38e3,0x0001af67ab10bb4e,0x000d033cee10ca51,0x000549874c9fe7c1,0x000392d6999489f1,0x000ffcfe4a15a85b,0x000b006a13684dec,0x0007b8baefda3eb3,0x0000000000000001}}, + {{0x000e82cbfe7306a8,0x00002e52832eb494,0x000b381c8b461b41,0x000a6e877f0afbca,0x0006b8482ae88f1b,0x000709eb28c8cc07,0x0000cd45fc8e5ced,0x000b1363d1cf0c64,0x00093a63d6be8f78,0x0001407a8e7f6a49,0x0000000000000000}, {0x000fd703c088bf64,0x000708b3415df01b,0x000f82eeb2c8b57f,0x0003ed35407aa69d,0x000449767c6b4a72,0x0002e1a8184dbc3f,0x000d25edffc3e965,0x0003e8855e29ad89,0x000c695a889f2e49,0x00025dae2a995ab2,0x0000000000000000}}, + {{0x000c300d63dacf22,0x000f84149cc93249,0x0004f71e87a984e1,0x000ebeada635f884,0x000cac51f48942eb,0x00076c6b878d815d,0x000587460dede95b,0x000883c91cf8c3f2,0x00013e9be5375387,0x00076d4ce987a56d,0x0000000000000000}, {0x000fb20151675f42,0x000bf54bf1c2d622,0x00022da7f9e8bc4a,0x000051b0e7b83f3a,0x00073eda536a6e42,0x000ce8431a9d89d5,0x0002b7a64d23c5a3,0x000007a6be7b3eec,0x000672919b5fb43a,0x000c454a7d18005b,0x0000000000000001}}, + {{0x0009f484a29e97a0,0x0005e90aa411ba92,0x00016fc135a72a99,0x0006cfa3c8dd8a3a,0x00066efeed6df222,0x000e66eb40ebb1a2,0x0000f8ad15ad7b0b,0x000e0c3a19929e39,0x00051e3404d13a05,0x000175cf393bacd1,0x0000000000000000}, {0x0006cdbeb4d89814,0x000b884f6ce10295,0x0003138d1321a20d,0x0006528c4bd065b9,0x0003d082878ee395,0x00029465651ab383,0x000cb4e49e6b0dcc,0x000710248d30e955,0x0006e01a51ae9cc3,0x0002fc5567eab89e,0x0000000000000001}}, + {{0x000c59218072f54a,0x000195bad5f014fe,0x000deabd55429cb3,0x000b2ab5fb9c1406,0x0006cf39524ff8ca,0x000fbb57c01480bd,0x00018cbc932f5376,0x000c9e4e5da034f1,0x000fb16c36eb8d83,0x000048c80fc4eaa6,0x0000000000000000}, {0x000668aa11e1cfe6,0x000d4f614afa98be,0x0004cadab479a412,0x000864b0b94d7822,0x0002651053a74933,0x000dd43fe6424e5f,0x0004f2c600bdaac3,0x000ec0b432ccf8a0,0x0004d82574257110,0x00024e58edc3e12f,0x0000000000000001}}, + {{0x000d5163c2f29845,0x000271b8856ff717,0x000a79d0557c5c08,0x0001484032810d21,0x000a5a6e95174165,0x00093b8782ce8f06,0x000a6f7f14b15d03,0x000ca398eeacdf3d,0x000eb31c7c040c1a,0x0003ace9ed34f4d2,0x0000000000000000}, {0x00086bac2cc4ff50,0x0008d5294f7bd063,0x000ec0b7a55f986d,0x0006868155592285,0x000e215833824965,0x0003366d9a307162,0x0001de9196efa150,0x00076afbb75f7833,0x00046ce65ce11aa8,0x0002f7a207e31942,0x0000000000000001}}, + {{0x000d6129f7d0fa54,0x000150bddf5a7cf8,0x000b4988625b2f43,0x0009bbfb3c2f3809,0x000f5b080f7b3129,0x0000ab0abb84ed45,0x000510d824f7bed2,0x0006d6447243533e,0x000c576b7b64fbbb,0x000e16caa9ee8267,0x0000000000000001}, {0x00053a269ea0b07f,0x000e06f68fe62242,0x000a777b6874572d,0x000d5f86cf599bf5,0x000fe2a811045a16,0x000873264294a33d,0x0007a04ac970a0c0,0x000ceb2b7d05d686,0x00029a28a0e51a57,0x000bacbf79a38ead,0x0000000000000001}}, +}, +{/* digit=125 [{1,2,3,..,}]*([2^500]*G) */ + {{0x0003efe866dc2f62,0x000853cb9e407c10,0x0000e6c71edaaa13,0x00018f751b70a2af,0x000b0cf7e3e825ae,0x0005c36a5a1ec11b,0x000487f56ab4b564,0x000a86df052ea4e5,0x000d750313868ef9,0x000e60ee422740c7,0x0000000000000000}, {0x000ee652bd47edd5,0x000397faa97f40b7,0x000294d2d1ba3dd7,0x000344d3453daecf,0x000d324bd3f56e65,0x00078c6f611c9985,0x000e24f2675985ec,0x00038b4060d38ad7,0x000dfb7496c92821,0x000be627a6ad57ff,0x0000000000000001}}, + {{0x0009be6a7e5a166a,0x000d06313031bd58,0x000704962d984289,0x0002ec5b522512df,0x000386a669eef493,0x000fe747674db075,0x0004dbaabd7aebbc,0x0004d27fb22ce794,0x000e70494458ef81,0x000fadc96805636a,0x0000000000000000}, {0x0005b60c511b3ff8,0x000584915adb1e6c,0x000f8937e8e108c6,0x0008406d64ea3a9f,0x0004461d268f9ab8,0x000e3ff279d6126f,0x000d3b3ed1f3032a,0x00023a1b63af22a5,0x000caf9282fd7a53,0x000d99f7a42a7590,0x0000000000000001}}, + {{0x000dfb005014a6bc,0x000d36179f05f79f,0x0001f0a00c591c70,0x00009f861bdb8aa0,0x000851877e4cc13b,0x00004921bdab098b,0x000265f47ca34718,0x000478a5d59cb874,0x0008aac74eb734d8,0x0002f6a87e5bc7bb,0x0000000000000001}, {0x0005dd559082ec4f,0x000fd3340b409a63,0x000e395e6174cff9,0x00035fdf83237476,0x0006e995df5d90e4,0x000535beb0acf902,0x000ddc2f60fe3f20,0x000821d68a60c3ba,0x0008005435d079f0,0x00084ef7a20c388b,0x0000000000000000}}, + {{0x0001ce9624902c85,0x000dacee54d7fc06,0x0008e982883e676d,0x000cea68fc5997cf,0x000b94f3d06f1e8c,0x0007b80d8242831b,0x000ec2e625c36045,0x00015466a1d87389,0x000c5009313ff25b,0x00045efb5d45d1f9,0x0000000000000001}, {0x0004e32c6f246301,0x00064608ec78b5ab,0x00053a9c0b324014,0x0004ddead5ffb795,0x0008bf933bdcc559,0x0005249289dc110f,0x00047d25d52f652d,0x000d95ab06c0cb41,0x000bbff17968adb2,0x0002664039be6fa1,0x0000000000000000}}, + {{0x0006c159dee64527,0x000d486c1da85118,0x0002ffecac887f87,0x000401c5326e8ac4,0x000fe68a082d270a,0x000b17b4ec0bd703,0x0009b1a9fe82427b,0x0008f75c6b25d502,0x000ac56e28859df5,0x000bc70f97f9bffa,0x0000000000000001}, {0x00073b932e4e3e21,0x0005f8e721dc13af,0x000825bde1498f11,0x00080fd3102f60c7,0x000f292e5a9e9f07,0x0006a4edbc9fcac3,0x0008f2651ae44279,0x0002622ca1bb123f,0x000a4ca103d2d6a7,0x000ca577d0f1994f,0x0000000000000000}}, + {{0x000e577af10e1302,0x000156bf557eaa33,0x000ca7cba0f98005,0x0001e9d6e3d41486,0x000ad3a30b9f973d,0x0009856b55aa3443,0x000724f819219409,0x0008250cf13f0ca4,0x0006f0f69ba1696b,0x00063bba1deb1e9b,0x0000000000000001}, {0x00037cb6672f9435,0x000d7e7437eb08a0,0x000579149c6faf55,0x000e4c6943f7c61c,0x00026eba03e36921,0x000a3ade34c342ab,0x000052386264eb60,0x0000ffc57653cf12,0x00070eec7914e6e2,0x0004912d67845657,0x0000000000000001}}, + {{0x00006fc3e072e1bd,0x00066e9739a62b31,0x0006ea97e6ad1669,0x0002aa2bbc843284,0x000871768bc4f0fb,0x000a51f2d1bd1f5f,0x000245a8890f99b0,0x000b6a0000aa5f53,0x000547c1538e0dc0,0x0001c33dbece2149,0x0000000000000000}, {0x000b56de17b97c51,0x0000fccb15a8e3ea,0x000c00352a78e0ff,0x000e7d480dae3bf3,0x00092273cee30716,0x0000962a4283dde8,0x000e674e18ae53b0,0x0002b8c78835cb2c,0x000faee271217641,0x00046294e0f5e7c6,0x0000000000000000}}, + {{0x0005697612d854d6,0x000590266d871a78,0x000015aa94be7df9,0x000482ac4e8bbf72,0x0007c12880439150,0x0003495f23aa4b2f,0x00074815ef777bb5,0x000838a798c004a6,0x0008a425cc7aadc8,0x000c432ccb5f5730,0x0000000000000001}, {0x00006af85640f288,0x0003a6718ebc6cb5,0x0002c50bba9dd21e,0x000e3c4d56098fde,0x000a4a8a721857b6,0x000218f9c402f4d7,0x000a6f255530e5d9,0x0000bf7b3c63a541,0x000f0181b97421bb,0x00023de7a08f2804,0x0000000000000000}}, +}, +{/* digit=126 [{1,2,3,..,}]*([2^504]*G) */ + {{0x00061ebad9ee2c24,0x000dd46aced3ddaa,0x0000bd3e3fde5fe2,0x00020569fe14f9f4,0x00088d818d1a2095,0x0002f0bdc9b4968b,0x000e3de0b8b77328,0x0007fe9e8edc6520,0x000017cf0272ff76,0x000eda0f65dc99bc,0x0000000000000000}, {0x0009b50b03dc034f,0x000ff04ea634ab0a,0x0007b191db6e6308,0x000a9de7ee04399a,0x000e6da7bdea8dde,0x00054c55ae492d45,0x000f4e939e666b7b,0x00090c925a51f573,0x000f916220292c15,0x0002d380fc7f5071,0x0000000000000001}}, + {{0x000639a92b83d191,0x000b3a1ce7b1b453,0x0000d260e431474f,0x00032954aefab808,0x0006dfaf9e670c4e,0x000e42d0d7b5bae7,0x000bfa89eb4687fd,0x000c7d89b1ca5f45,0x000ecce4fba638bb,0x0008a21de873fcc0,0x0000000000000001}, {0x000c9c2b49165fd5,0x0005fb318f9f9636,0x0006f676d6c2cb81,0x000c633a7560919e,0x00011e2d4752541c,0x000199c5999a79e2,0x000515dfbee081ee,0x00053107dec5265f,0x0002bdc9ed0ea4e2,0x00041c5a539ab36f,0x0000000000000001}}, + {{0x00009de7ecb2ac56,0x0002d837bb7a345c,0x0004863cfd4369c7,0x00077c66a5755a3b,0x000682ccc872cef3,0x000bc1363c743442,0x0008b997f1a0d907,0x000d72224eed734a,0x000d1850457f924f,0x000f3bbd996258f2,0x0000000000000001}, {0x0004953714391350,0x0002a08de1fb04ea,0x0009bb0ca7d3f0e3,0x00020e2fc4a54760,0x000d525812eece55,0x000dc3c7c680f4ea,0x00064f097079b269,0x0001e81a267b891a,0x0002df53061afa20,0x0007339d7335dbc1,0x0000000000000000}}, + {{0x000fa11c22d57017,0x0007061bfc65866f,0x000e25c9a781f882,0x00052d54eb5d1a25,0x00034e5fcb1fe128,0x0008c5dfb74f3317,0x000cca2e48b7e54d,0x0005e9b41639cfad,0x000e1f8c2193402d,0x000348c49e8f71b8,0x0000000000000001}, {0x00033ca43943f50d,0x00016ce98a1f644e,0x000bd595ac8a7cb4,0x000d4eb1e328cd45,0x000e8ec3fd8cbf8f,0x000eb626b0f768cf,0x0001524476b1bbc9,0x000d8d0ffe31069d,0x00025aa89220edd8,0x00063660b3755829,0x0000000000000000}}, + {{0x0003a78191abe914,0x000aed083110e37c,0x00072de9a657b228,0x0003d434d0dfafec,0x0009778c8ba568ce,0x00021f193e09ab8a,0x00032b59891165df,0x00090a0e20c8f7ac,0x0005b8a1f64088c4,0x000b717ed2f2d69f,0x0000000000000001}, {0x000ac4849a39a0ab,0x000e9224368b5d72,0x0009a57abd9c0589,0x000f04bfeb21218d,0x00049bfe57f2080a,0x00082fbca66b72d8,0x000f0c09eaa93852,0x000e04db305e15a6,0x000bb2bcc4365052,0x000d0e18047907b5,0x0000000000000000}}, + {{0x0003c1031f4f778c,0x0009bbc5cc621ce8,0x000ac957c67434bc,0x000a368627bcbc47,0x000adace0a905430,0x0008aa0831ed2cb5,0x000c11d0f4f5d323,0x0001c48e91c91fa3,0x000229765edbfb35,0x00032bdf2591e498,0x0000000000000000}, {0x0008e455572bcfd0,0x000ecba53bea9ae3,0x000196518c997db1,0x0005c33258970b56,0x000a3c6b46d1e689,0x0008e44ad30fe772,0x0005dd6482160561,0x000b86d1933faf1a,0x0005a53d718ae6de,0x000e4e4345a6badf,0x0000000000000001}}, + {{0x0009f15950170034,0x0008a7d9e0681bfb,0x0002dc602830c283,0x000e8af178838dfd,0x000987d3f8bcc134,0x0008904081cb94f3,0x000a460c0da2bca6,0x000f718b8913d63c,0x00022ed274e647de,0x000ff3a58fd52338,0x0000000000000001}, {0x0002950ff4836dad,0x000fe4a51fa111b5,0x000e13de206b61a9,0x000941373ab42508,0x000c7bf8c1651d7a,0x000dbd9276666a02,0x00056dcdd411c37b,0x000f5a9ab3e87536,0x0000f464671775e6,0x000bc59bc827eaae,0x0000000000000000}}, + {{0x000eafce57fbc903,0x00072ba11885f40d,0x000d640aa98f9421,0x000bfcf817ce6b52,0x000389d8e40bcdc1,0x000c804e7d14a7d6,0x0008fa880e955163,0x00034af7c92b6304,0x000fd685115381b0,0x000faf73ec6a9688,0x0000000000000001}, {0x000f85d1af3848b2,0x0008716ba36666f4,0x000fbfc6c17f47de,0x00003b35f9474540,0x0004b72b1ddc670e,0x000f48bdd3ad6387,0x000d7cfd249ea687,0x0009c16141926a15,0x000d8d963e9d101f,0x0000771b9b1c2fac,0x0000000000000000}}, +}, +{/* digit=127 [{1,2,3,..,}]*([2^508]*G) */ + {{0x0006bccc65f30461,0x0006e44b51d15f3b,0x00061b0ed084d989,0x000f84c9df4f3be0,0x000626ed8e29bced,0x000a49395cf45bde,0x0001bfb128499bea,0x000d30e7b9a9812a,0x0000016d9442e44b,0x000577251b4710e5,0x0000000000000000}, {0x000c58ea8faa5f8e,0x0006398972e1afb4,0x0002d603c3a6a3b7,0x000090f464b41953,0x0003e1c1cc6d5ad6,0x0009fc4551644bda,0x0003bf0e003b3c67,0x0004879a2d4dc4fe,0x0002492059f3993d,0x00089490933a0bd0,0x0000000000000000}}, + {{0x0003d39ba21abe88,0x000b8dfe497366b8,0x0003fb2e32d1a08b,0x00040dcc68fadea4,0x0009bc78d9e5b900,0x000999242f620135,0x000e38d4ca94e098,0x000f3e9a937783f1,0x000c271edf5e42de,0x000cdad3d42e09c5,0x0000000000000001}, {0x00014caf1b7e4897,0x00092052b710207f,0x000840b578b42fb2,0x000c859d4e0acb78,0x000efbd1059c69f5,0x000fc0d187f5ce1f,0x000018dd99b98e1d,0x000fd9d695b6b702,0x00087f7037056ff1,0x00080b73121d9b11,0x0000000000000000}}, + {{0x00078d674ce9ba28,0x00098667edd1931d,0x0007a2c798ce814e,0x00054444ef1eef63,0x000bbc4342cdf2cd,0x0008690dad1f9bf2,0x000e17a85c72b72f,0x00027215c615b685,0x000ab98eb37dbb69,0x00072850ebda62ab,0x0000000000000000}, {0x000b543dc482d1d8,0x00066dc72bee2f05,0x000576c719cbc26f,0x000bf9361970fe88,0x00012aede3868858,0x000d0a81339054e9,0x00050f3227db12ff,0x00054f85925da234,0x0007c4995e06e9ee,0x000343899d0c96c8,0x0000000000000001}}, + {{0x000622bfd7a6e63b,0x000ca212bebe9c89,0x000487abee2cafd2,0x000143f4d290457b,0x0007d05d13bf4c04,0x00067f0ae3716aab,0x000a3097740d4130,0x000debe6d02d5925,0x000ef2c2714370b8,0x000fcffae20be9e8,0x0000000000000001}, {0x00009dc727eac0b8,0x000802b463618a8d,0x000e00f824949d83,0x00021e8850666aae,0x000a354be3730d5a,0x0006ce164b258522,0x000386cbf3fd223a,0x0000b7ba5ba4fefa,0x0008ecff5479bc6a,0x000ec6ece410bb37,0x0000000000000001}}, + {{0x000fb0fd2b03ceeb,0x000c34d346742d91,0x0007fb1da808f925,0x00014c3e50e576d5,0x00045dde45aec274,0x0007634b06ff5225,0x000e8f635cfee4ae,0x0006af16b33722c1,0x000b6c9512df9861,0x00087905f5ba1ed3,0x0000000000000001}, {0x0006849e44fd7308,0x000ca8c188190c88,0x000568eece8b82ee,0x000afcede37dce03,0x000956f0105616d6,0x000fcd4f42159b96,0x00016a63204d42e3,0x000f90e66b95446b,0x0003ff7137d7895f,0x00015f08ed8c3b6a,0x0000000000000000}}, + {{0x000080c877cdc551,0x00063fd88170e394,0x000069a5394fa226,0x000fe13aafd4abd3,0x000aac77685a1a56,0x0002270caf504acd,0x000b15ab3b28bcb6,0x000ff30df2535d28,0x000dad1836a25af3,0x000fa6c25940501a,0x0000000000000001}, {0x00072e0f5dfd0431,0x000680aa3b20ecdb,0x000be825e1b5fe43,0x0005a5c2422130db,0x000f0dc02a5e8b8e,0x00053d6d0a6ed0ac,0x0007b39bd52bad22,0x000defc7beec9197,0x000d80e249e46059,0x0009869fd32b5153,0x0000000000000000}}, + {{0x000d5488a9c159ea,0x000c7c99f362daa9,0x000520e4056562a1,0x000f58587c3780d4,0x000cf122d12decdc,0x00066fa3df2e094a,0x0006c99c7f2dc2a5,0x0005a3f3e1f8fe88,0x000ead106c542a2f,0x0001bd548c70f9bd,0x0000000000000000}, {0x00025e9e39905a6d,0x000d9b4651431540,0x0007d3343ac64109,0x00071e3dd6b3d33e,0x000a550593155d88,0x0005e988444776c0,0x00092c204b5ef211,0x000132ec6af46f8f,0x0000975bc42ba82e,0x0000ec605e3e60a7,0x0000000000000000}}, + {{0x000ebdae497fc314,0x000068fcc42342b8,0x0002e8a76fa0addd,0x000d98aa1ba58a99,0x0006f585d2056972,0x0001a667125a290a,0x000e664a47990be5,0x0003e44696beab19,0x0000ab4a22f64d1c,0x00054a0b8ce48449,0x0000000000000000}, {0x000cf9a538895145,0x000e7e3b3fd1990a,0x0001c1f1592daaaf,0x000016843015bdb3,0x00095b2dbb2d0adb,0x000f77ef5d670d12,0x0008bf1b3f98aca3,0x0003b5280fd35140,0x0007a58660b5ee9d,0x000f86e58791223a,0x0000000000000000}}, +}, +{/* digit=128 [{1,2,3,..,}]*([2^512]*G) */ + {{0x00031c51f5b59b03,0x000c7665ab584951,0x0008739b754d5115,0x000b253e840523eb,0x000078a1f77e3b96,0x000742a046765d97,0x000823d7e942e5b8,0x00080b3194bd1539,0x0002679bf560b997,0x00061abda6ff32b5,0x0000000000000001}, {0x000820e93e66dad8,0x000f2c881e08a892,0x0007e5fd839208f9,0x000d25804e86968c,0x000fc76aeb554305,0x0004c686c9b44037,0x0002e51b80d02e02,0x000e5774d5a620e6,0x000000eae653df90,0x00072ac9b31961f0,0x0000000000000000}}, + {{0x000f8d7860917b4f,0x000bb3357359429f,0x000995f4b0a05d76,0x000e0f1c58d0fe01,0x0002921dccd2ee40,0x0000ab0ca33af9c6,0x000637c074069c34,0x0002098a102fa30b,0x00037701844888bc,0x000d6cb2e96e33de,0x0000000000000000}, {0x00070d506a96d190,0x000f2ce57ed3ba0f,0x0002492cf26e59c4,0x000305995879a0eb,0x0000675760ae93d1,0x0009f9d0d04103b2,0x000d618a2b740898,0x000e723e7b444b0a,0x000b80451ab5c813,0x000616305a1f27eb,0x0000000000000000}}, + {{0x000b480b60680f46,0x00097a71a65ccb4a,0x0002360920f061e1,0x000428aeb306dab3,0x0005aee5267509d9,0x00058e47b1cbaf9d,0x0003350d9a6f7e9f,0x00035af36c30696a,0x000ff438c1f66ddb,0x000119d4937e17ea,0x0000000000000000}, {0x0009df61e7821be6,0x000b8322655044ac,0x0001ae7bb1e106e2,0x00039508343bc8e6,0x000a2bc1e06e0991,0x00066bd6b8166453,0x00044e23756d0eb9,0x00003795c5a1b4bb,0x000605deb625fe17,0x000248426f42f1b7,0x0000000000000000}}, + {{0x000ebb49b8b6d8d8,0x000c9576edd0b2c0,0x000089746d87ef78,0x000ee54686ff89a1,0x000cd51992a8e30d,0x000fcb70ff8362ad,0x00008d8883f2631a,0x0002a13e25b5a551,0x000d32baa9313847,0x00049764387fbe1f,0x0000000000000000}, {0x000652373d0f2fcd,0x0007e9e1299928e8,0x00016c54d21ce8fd,0x000e62d7938b0123,0x000ce4d602bacad0,0x00055138cbf9df41,0x000e0e625dfe098c,0x000dbf9a6851bc01,0x0000b0da12bdbc63,0x000aec8b07cebaa7,0x0000000000000000}}, + {{0x0006a52b356ba3e0,0x000fa486ee1abbf6,0x00074bf145f1f28e,0x000ef4af39b6c538,0x00084376c3d3f698,0x00007cbe4b46d363,0x0003db26e35a57f0,0x000ecc45a1933b62,0x0007b9610a9a44f8,0x000057b84f95bccb,0x0000000000000001}, {0x000bdacb48b9bb6b,0x000642a5eb931fe7,0x00097c327f5fbd2e,0x000a3062ea3deca5,0x000a3dad9ef787fc,0x00092f83b35a8216,0x00042427945728d9,0x0007537c6394f3cf,0x000b615698a93762,0x0001f468793ceb99,0x0000000000000000}}, + {{0x000217c6562eea14,0x000a6a042cb3da1e,0x00060f9ac91e9595,0x00013fef00e33063,0x0001954b4b6c8a05,0x00007e6bb37592ca,0x00018fef0e569527,0x000f4449441c7534,0x0003c8e93a050abd,0x00050bb02598e0eb,0x0000000000000000}, {0x00044683d956af18,0x000340076bbbf06c,0x00006b8e5826911d,0x000bd47b4442693c,0x000bdbfb4883b7be,0x000a67f8d229f111,0x000eceec785481be,0x000d18ec8ccc0a58,0x000ed2b1cc9fd671,0x000ee9b77fbdfe40,0x0000000000000000}}, + {{0x00033f2848525772,0x0002def8aeb9f6cd,0x0009c738e373fa1e,0x000ca3f54bf1bb33,0x0000dd3b12e5c621,0x000856fbe6604112,0x0004fa2d98399489,0x0000ba4686140d31,0x000be8a65034e7d6,0x000fc1d2c9034f2b,0x0000000000000000}, {0x0002e0e02cbac5de,0x00036d1bbef4bfe6,0x000db812e9ceffa7,0x000c4f097569d138,0x000c2795f975ff41,0x000cfa1a794c9978,0x000e1e65c9b377a9,0x000e6d66f7a547fd,0x00058785dc7270ac,0x000b34d6e188dec1,0x0000000000000000}}, + {{0x000a511d09de2eac,0x000031698e16faac,0x0002e96a74ccb4d0,0x000b85017b609854,0x0005887d91373679,0x00039fd4a56f39c3,0x000f60f3aea2bb2a,0x00084e8edd3fc7ee,0x000e1d001d481288,0x0003732f4d1fa989,0x0000000000000001}, {0x000629c27855b7b6,0x000652d6fdccbf0a,0x0005f32800f6bc14,0x0007f62ad29c1358,0x000dbf3a9fdce69e,0x000aa9f4b69418d0,0x000e5fef492796fd,0x000332f4a27a525a,0x0001a7293d91d135,0x0006fadc6b1bb1cc,0x0000000000000001}}, +}, +{/* digit=129 [{1,2,3,..,}]*([2^516]*G) */ + {{0x00076fe9e4b410aa,0x0002e2e46e8257e7,0x000285dece1c90ea,0x0004f07e02e70a0d,0x0007d9e22652fd2e,0x000325ca4b7fb066,0x0001305e36daaa95,0x000feebe9d3d04df,0x0000e3be0fcd0755,0x0005f74f74e60357,0x0000000000000001}, {0x000a7ff33f158714,0x00012737b93b28b8,0x000a408dc4f02791,0x0009c78d219fcf52,0x0008fbf0f03e3758,0x000d6cdb0c0bb10f,0x0007428d517b4d78,0x000d37e06b1f9904,0x000f8786ba69f3ae,0x000b508624d39698,0x0000000000000000}}, + {{0x000314e66fead340,0x0009f5c35e0de977,0x00086281b424220d,0x00095c9d69b8f421,0x000075fd90a74e5f,0x000c09fc499a89c7,0x0004b64e12f34808,0x00068c161166a676,0x000f40cf1886f3c3,0x000c4968ad8aaa55,0x0000000000000000}, {0x0001f4bec36790bc,0x000d77489002d4f9,0x0001759ca38e8177,0x000e759ae14e5a1f,0x000289005868dab2,0x000a1dff8ca02b41,0x000a4d82b9cd06ea,0x0004578741ea12d6,0x000343e8d641aef6,0x0002d4c6a85c8b1a,0x0000000000000001}}, + {{0x0007c33639a0b3f1,0x000010f791b828fa,0x00069b98b785836e,0x000f9367ba2d3b6c,0x0005ecea4290d504,0x0003dd0621586083,0x000de6622ac6245f,0x0002d8153e71208b,0x00091cd77d2a1a55,0x0007ebc7df7c52cd,0x0000000000000001}, {0x000fe4e1268ac84e,0x000d05fdf620f30b,0x00078c9c26de9aa6,0x000fef3a7d0e875e,0x0001f45acf57d581,0x0009769d1b4f2f3f,0x000f8a2b516d4fb8,0x000ca50e2afa7161,0x00069ea98a831731,0x000a4069e2a679a5,0x0000000000000001}}, + {{0x000573b5ab69b37b,0x00099e464e098a37,0x0004b6ae9bd2eac1,0x0007e83941109e44,0x000b3638c710996c,0x0005b0374099e6be,0x000e0cd0943a1c3a,0x0008fab6ecb18490,0x0009f0eb14e71bae,0x00011229f06246b6,0x0000000000000001}, {0x0006e2d865b8fa8c,0x000e4ba2a3d8ca53,0x0004c428120f4f50,0x00003e5bcb6eaa4c,0x0006c69871129b42,0x00018bdacf6da13d,0x0006a314f621f852,0x00031ea900e85204,0x000d280193a13fa0,0x000437167b70a8c7,0x0000000000000001}}, + {{0x000e47d41aa029d1,0x00083c1c1e4e8c82,0x000819d110bf6923,0x00080e340caaa47b,0x000e4f6e315e8cb2,0x000865960449f5a7,0x0002a736db3e3bf6,0x0008b38233a8c18d,0x0006ab95cab54c2d,0x0007b4670af6e721,0x0000000000000000}, {0x0009cd8d15df2f21,0x000c9e95f873ccf7,0x000d4ae259b8946e,0x0003026a352c8cec,0x000c84b6773b4638,0x000327edc3574f14,0x000980243f9e1167,0x000c58a2e8d3fc2d,0x000e789b426360b9,0x00084beac487c72a,0x0000000000000001}}, + {{0x000a504d7a128f19,0x000bec706161d077,0x0008d3f449e0d717,0x00027553cd6aa437,0x00023bfa097584c3,0x00031032e9ecfed0,0x000de734abfe6661,0x0005972524c62301,0x00068a20ad67cd7b,0x0001d7d8e4bd981b,0x0000000000000001}, {0x000dd411d75c8560,0x00020a136bd0f9a0,0x000e9c06f6a8521a,0x0001770134117a07,0x000c6625cc2c0b14,0x0006f01c93534fec,0x000bcd3698e9742e,0x000543a9724acea5,0x000820ced54b554d,0x00005a7954cbcc77,0x0000000000000001}}, + {{0x00060a7aed1a8afb,0x00037a6526a7b404,0x000f752335e80ab0,0x000a8f65f14c43bd,0x0004f9b989eabd11,0x000976a80f23fa92,0x0000171f16dad870,0x000d3baaac454e44,0x000f34704b9635c0,0x00051b0e1ca863f0,0x0000000000000000}, {0x000fcc07647c957a,0x0007e8420a4e5f40,0x000cec847e324cf5,0x000db2fe1f189869,0x0009827f88deeb20,0x00023c17a4487124,0x0009568284e63444,0x000010b9bfa3fe02,0x000626ee2d426c18,0x0006c496cbf2d807,0x0000000000000001}}, + {{0x000a48e1016cc257,0x000e7a08472093bf,0x000b7492e4ec8ac9,0x0001bd1c471d73ed,0x000a7243428ce53d,0x0007d49d1740adec,0x000c66dd60077c0b,0x0005737593cb7a95,0x0007c6f6ef237e1e,0x000660a7929ff06a,0x0000000000000001}, {0x0004bcc2e6c3da59,0x0003e87b3c416f89,0x00021231992a493d,0x0006d0824c0a5993,0x000e60d5c6c61f37,0x000a3430f29e1550,0x0005e81f1d1beb92,0x00027b6bc5ab11f9,0x000858c60a78bae0,0x000f95bdd9ea9017,0x0000000000000001}}, +}, +{/* digit=130 [{1,2,3,..,}]*([2^520]*G) */ + {{0x0008b69f6c0a103c,0x00014cb96747cd0b,0x0009e707ed23f30c,0x00092336029690c8,0x0002b884265ced12,0x00087e627555cfec,0x0008f62a097ab7dc,0x000df635118ea555,0x00070b69e23dda1a,0x00011d1b70ffff57,0x0000000000000000}, {0x0002606bce985157,0x000cf38c9c6bbd4f,0x00058d1b308ccb92,0x000fb6fe2ce6913c,0x0005b1967bfefbbd,0x00053132fce5cb51,0x000b2f22527584e4,0x00082a1591dfc389,0x0002d57610460d61,0x000dc57498b0d160,0x0000000000000000}}, + {{0x0008cffee5938175,0x000028a135a61fb3,0x0002c9fe1a18ac17,0x000b968e30418249,0x0000b4c958b813ec,0x00023285e86f834a,0x000b05e54df836f5,0x0008f77b5fb229e4,0x000371505e864d89,0x000fb3cce3c32e48,0x0000000000000000}, {0x000a0e5e3ce8bcd8,0x000dc2fb74fd48c4,0x000875aaa2018996,0x000827185e9f86f5,0x000196642422b5eb,0x0006d6f0dd874310,0x000f5719d7e7982d,0x0005346044e6cb46,0x00002d250a348c67,0x0009ec517508afdc,0x0000000000000001}}, + {{0x000145140a7a865f,0x000095ded9f8c118,0x00040df2b19ba498,0x0007dec03834dace,0x0009e3687e664a0c,0x0009d971f2feee9a,0x0008796a032ee720,0x0003a0b2cc310714,0x000067d48b65bcec,0x0007f5d8c2af6546,0x0000000000000001}, {0x00015c856b094864,0x0004f779c821c5d7,0x00062cf6310bebe0,0x00086c833844c220,0x000322644f899899,0x00080ac439439357,0x0009f2dfd741ec2f,0x000c3022b589299a,0x000663af1bcf4790,0x000a46767587f6f5,0x0000000000000001}}, + {{0x000cdfa0667f8929,0x00055eda7b7826f1,0x000dd93845997fea,0x00073f54c39699cc,0x000d85971fbd417d,0x000631f8049f08e1,0x0003b8e65a870ee3,0x000aa3cdc8e351a7,0x00099901454f69b2,0x0002d659cbe0fe85,0x0000000000000001}, {0x0005bfaeb9c77879,0x00078817f6a7aa08,0x0001e5f6c61e07f9,0x000a5dffb271762a,0x000df5d3e3cd3cc6,0x000eadd52e895eb0,0x0003b342cd665b46,0x000393078c5b9252,0x0006202122ebcff3,0x0005f4777dd50c48,0x0000000000000000}}, + {{0x0003fcdbd57bfa90,0x000d1b118dee98fe,0x0000a524ceccfc4a,0x0007420c6d1ffa5c,0x00053919d859de0d,0x00081fb74544af55,0x0007c3f0981d6def,0x00076680c297a17a,0x000d22135e0cc4fe,0x000d15de36e57af6,0x0000000000000001}, {0x0008ae03fd78b0a1,0x000c06ac0c41950b,0x000c994e2c7c2638,0x00075a944523ebb6,0x0002bdb72a76549b,0x0007a73d0573310e,0x000ae4c8ce6d6b85,0x000e4309eb9e1e23,0x0008aedc0842f06a,0x0006ededf71264f9,0x0000000000000001}}, + {{0x00047c62f7f81bbb,0x000568d4c38f8cbe,0x000085a52c049173,0x000151d87d057b19,0x000462de5c929612,0x0004036de18a4ea9,0x000290b0a8300ddc,0x000e195518bc5a6e,0x000e21097894ed83,0x000a74d8dd898c35,0x0000000000000001}, {0x000eee2e29a47676,0x000325c0b89ddfd0,0x0000c5c995a8a7bf,0x0003e514a5131a24,0x00078e5998b6e957,0x000ba59336939798,0x00032157906f3c87,0x0001093cead5ff51,0x0003bc2e1b76588a,0x000a055abc03c824,0x0000000000000001}}, + {{0x000c9d2081074b7d,0x000b4b234d223107,0x000c6fe7d17524b8,0x000b3e26469a9182,0x0001d35461f18688,0x0008f9ef1eb0f49d,0x00072164bb2130a7,0x00069240661ee72b,0x0004674d4ec1e4e4,0x000df195346b1529,0x0000000000000001}, {0x00094d4cd2beae09,0x00021cf533e3fea5,0x00099051c26db75a,0x0000237aea1a808b,0x00066230cfcd19c1,0x0000aedfcfe63965,0x000965518cdd9349,0x0000446502d88c39,0x0006de0650de6be1,0x000c487b3640aa4a,0x0000000000000000}}, + {{0x000315f2c4f3b202,0x000844f2e07c55f6,0x0009040fc8f62ee6,0x0006bb02af168881,0x000eea1922677aec,0x0003b90132968e4d,0x000b75f92b21f9e5,0x000b4ae4c1d62b9c,0x0000f373265408d1,0x00013d70be8f94d2,0x0000000000000000}, {0x000c00995b2d1ac5,0x000acf4e16ae2b05,0x000d04ee882f20b5,0x000b5e061f8c5834,0x00040c9dbfe4135d,0x000f7b55b63a42f5,0x0003b47500e266e3,0x0004da6911e652ce,0x00043c4db0c53d0a,0x0009946052a6d7ee,0x0000000000000001}}, +} +}; + +#endif /* IFMA_ECPRECOMP4_P521_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp5_p256.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp5_p256.h new file mode 100644 index 000000000..f5e41b1ae --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp5_p256.h @@ -0,0 +1,968 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPRECOMP5_P256_H +#define IFMA_ECPRECOMP5_P256_H + +#include + +#define MUL_BASEPOINT_WIN_SIZE (5) + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE +#define BP_N_SLOTS NUMBER_OF_DIGITS(P256_BITSIZE,BP_WIN_SIZE) +#define BP_N_ENTRY (1<<(BP_WIN_SIZE-1)) + +__ALIGN64 static SINGLE_P256_POINT_AFFINE ifma_ec_nistp256_bp_precomp[][BP_N_ENTRY] = { +{/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x00030d418a9143c1,0x000c4fedb60179e7,0x00062251075ba95f,0x0005c669fb732b77,0x00008905f76b5375}, {0x0005357ce95560a8,0x00043a19e45cddf2,0x00021f3258b4ab8e,0x000d8552e88688dd,0x0000571ff18a5885}}, + {{0x00046d410ddd64df,0x0000b433827d8500,0x0001490d9aa6ae3c,0x000a3a832205038d,0x00006bb32e52dcf3}, {0x00048d361bee1a57,0x000b7b236ff82f36,0x000042dbe152cd7c,0x000a3aa9a8fb0e92,0x00008c577517a5b8}}, + {{0x0003f904eebc1272,0x0009e87d81fbffac,0x000cbbc98b027f84,0x00047e46ad77dd87,0x00006936a3fd6ff7}, {0x0005c1fc983a7ebd,0x000c3861fe1ab04c,0x0002ee98e583e47a,0x000c06a88208311a,0x00005f06a2ab587c}}, + {{0x000b50d46918dcc5,0x000d7623c17374b0,0x000100af24650a6e,0x00076abcdaacace8,0x000077362f591b01}, {0x000f24ce4cbaba68,0x00017ad6f4472d96,0x000ddd22e1762847,0x000862eb6c36dee5,0x00004b14c39cc5ab}}, + {{0x0008aaec45c61f5c,0x0009d4b9537dbe1b,0x00076c20c90ec649,0x0003c7d41cb5aad0,0x0000907960649052}, {0x0009b4ae7ba4f107,0x000f75eb882beb30,0x0007a1f6873c568e,0x000915c540a9877e,0x00003a076bb9dd1e}}, + {{0x00047373e77664a1,0x000f246cee3e4039,0x00017a3ad55ae744,0x000673c50a961a5b,0x00003074b5964213}, {0x0006220d377e44ba,0x00030dff14b593d3,0x000639f11299c2b5,0x00075f5424d44cef,0x00004c9916dea07f}}, + {{0x000354ea0173b4f1,0x0003c23c00f70746,0x00023bb082bd2021,0x000e03e43eaab50c,0x00003ba5119d3123}, {0x000d0303f5b9d4de,0x00017da67bdd2847,0x000c941956742f2f,0x0008670f933bdc77,0x0000aedd9164e240}}, + {{0x0004cd19499a78fb,0x0004bf9b345527f1,0x0002cfc6b462ab5c,0x00030cdf90f02af0,0x0000763891f62652}, {0x000a3a9532d49775,0x000d7f9eba15f59d,0x00060bbf021e3327,0x000f75c23c7b84be,0x00006ec12f2c706d}}, + {{0x0006e8f264e20e8e,0x000c79a7a84175c9,0x000c8eb00abe6bfe,0x00016a4cc09c0444,0x000005b3081d0c4e}, {0x000777aa45f33140,0x000dce5d45e31eb7,0x000b12f1a56af7be,0x000f9b2b6e019a88,0x000086659cdfd835}}, + {{0x000dbd19dc21ec8c,0x00094fcf81392c18,0x000250b4998f9868,0x00028eb37d2cd648,0x0000c61c947e4b34}, {0x000407880dd9e767,0x0000c83fbe080c2b,0x0009be5d2c43a899,0x000ab4ef7d2d6577,0x00008719a555b3b4}}, + {{0x000260a6245e4043,0x00053e7fdfe0ea7d,0x000ac1ab59de4079,0x000072eff3a4158d,0x0000e7090f1949c9}, {0x00085612b944e886,0x000e857f61c81a76,0x000ad643d250f939,0x00088dac0daa891e,0x000089300244125b}}, + {{0x0001aa7d26977684,0x00058a345a3304b7,0x00037385eabdedef,0x000155e409d29dee,0x0000ee1df780b83e}, {0x00012d91cbb5b437,0x00065a8956370cac,0x000de6d66170ed2f,0x000ac9b8228cfa8a,0x0000ff57c95c3238}}, + {{0x00025634b2ed7097,0x0009156fd30dccc4,0x0009e98110e35676,0x0007594cbcd43f55,0x000038477acc395b}, {0x0002b90c00ee17ff,0x000f842ed2e33575,0x0001f5bc16874838,0x0007968cd06422bd,0x0000bc0876ab9e7b}}, + {{0x000a35bb0cf664af,0x00068f9707e3a242,0x000832660126e48f,0x00072d2717bf54c6,0x0000aae7333ed12c}, {0x0002db7995d586b1,0x000e732237c227b5,0x00065e7dbbe29569,0x000bbbd8e4193e2a,0x000052706dc3eaa1}}, + {{0x000d8b7bc60055be,0x000d76e27e4b72bc,0x00081937003cc23e,0x000a090e337424e4,0x00002aa0e43ead3d}, {0x000524f6383c45d2,0x000422a41b2540b8,0x0008a4797d766355,0x000df444efa6de77,0x0000042170a9079a}}, + {{0x0000b650bc6fb805,0x0004effe2e6b808b,0x00083f5495882e07,0x00072385ef2f7c2c,0x00004d63c80e103b}, {0x0001bd652a23f9b6,0x0008eb0b6587f2f1,0x000580e9e3670c31,0x00021ff5c4623bb1,0x00004edf7b261efe}}, +}, +{/* digit=1 [{1,2,3,..,}]*([2^5]*G) */ + {{0x000fccfc5e3a3d83,0x000c1079dfbfd8c5,0x000ad0197befd904,0x0002a48c6d6a58fe,0x0000922707799553}, {0x0003e6ddbef42f56,0x0003e80a990809e2,0x0009a2e407e449b6,0x0002a41b969c1aad,0x0000231d792f591c}}, + {{0x00096f305968b809,0x0002789f73b9db6d,0x000c61e01380a091,0x0008c6eda70b83c2,0x00005fb8394e69b3}, {0x000651280edfe2f2,0x00096faeaf829a3c,0x000424bf88f726bb,0x0009706010a4a078,0x000096720442e844}}, + {{0x0008d2333e12b701,0x000b09dd329b802b,0x000bc354d6d490a4,0x000a0d04f356cc6a,0x00001eddf7fe0a0d}, {0x0008328d87fd1d83,0x000ccd0258131e20,0x00029bca2fd2f4f8,0x000b70d3b48cc47c,0x0000f2a78b3541a2}}, + {{0x000cb817a2ad62aa,0x00090c62ff5463c5,0x000ad9db57ef2b6b,0x0006169749bba4b3,0x0000d311f2ce6d5a}, {0x0008087c2ff3b6df,0x0002467834ffb77a,0x000d6b138b46feaf,0x00018808aa266d75,0x0000a38d321dc008}}, + {{0x000fa1ae3451a09e,0x0002dc117423c04a,0x000cf56ee7cc6910,0x000a24a76be3aa51,0x00007577d588d844}, {0x000ed8cdb77f3410,0x000c23ae4a2a266f,0x000782760cfa258d,0x000d4a53a7a98cda,0x00004b48868ceaf7}}, + {{0x000affc4e6916c6d,0x0006b11842dac0f2,0x000b4d1576fb9495,0x000b8f9034bcb624,0x0000e2efdc8692ef}, {0x0007eceac793c87f,0x00058dc6fdcdd66f,0x000a1c50102f0262,0x0006efa0d3235c9a,0x00006e494971b466}}, + {{0x00036d19c0859c3e,0x0005d269386a0827,0x000a87b3389ea551,0x000236125071871a,0x00009d82f60504e8}, {0x000612442e855f5b,0x000d895e00d87834,0x000e7e62b209f50f,0x00037b1d9e03aae6,0x00004b4959f0e5be}}, + {{0x0008ffa696946fc7,0x000849cba56d486d,0x000f35a1550fbc6d,0x00062c0e3d423e90,0x0000c3da19630dd9}, {0x000fdb03cfd5d8b3,0x0002589dfca5e673,0x0002305aa0704b7c,0x000e53c6ce581ff5,0x000099d49ebc14d5}}, + {{0x000afbb10e6d9501,0x0004d2bf970a7966,0x00054ca2a37e4a4c,0x000a1013d0c8559d,0x00003d628660ee39}, {0x0003c38d3bd15e94,0x000d44a80bcc15f5,0x000d8f608014b8be,0x000feed0674c77bf,0x0000dfab987093fb}}, + {{0x0007c367b92d4531,0x0002149a26c024c9,0x000d14a39d2c271a,0x00000550eb4b2b89,0x0000198de20532e8}, {0x000ea75799b80d93,0x000b5f826ae59eab,0x0000061ecab6e0c2,0x000fd89a004eedd1,0x00001a9f43a199c4}}, + {{0x0008b75b5498a7c3,0x0009f9f64c2d734c,0x0005b1677aeccad8,0x00096865dd54fa29,0x000083902a0e4c54}, {0x000276feb9d33a9f,0x0000bf55286978cb,0x0005c163000aedca,0x00050cb01d14594c,0x0000eba17076cf7d}}, + {{0x000496d6ec293cde,0x0006ae7051f5380a,0x00049140a733dbda,0x000bf5237e388db8,0x0000e4b32b13946d}, {0x000fda9cae368d14,0x0000bdb0b2f3b1c4,0x0003ac46e5001a7b,0x0006562df593742e,0x0000af675f279b3e}}, + {{0x000ffdcc01b0a469,0x000ef3f843c21a1f,0x00038e81a07ad675,0x000da82cec2d0767,0x000010aec763a8b7}, {0x000d740a4509ba71,0x00033c7b821613b4,0x00091f1e50570107,0x000d902d75c8f715,0x000034c1b6f1dfe1}}, + {{0x0007c44d67826eb7,0x000f3c379637b20e,0x000e03a5d1212d3c,0x000a25f14f67877d,0x0000538a2fcf02ba}, {0x00037a19d252415f,0x000f7eb4b587133c,0x00049d1d97db3904,0x0004b96d40d7574c,0x00001126b9a9801c}}, + {{0x000aeb9c56729fc9,0x000857a8bd8539a7,0x0009d10c621a5944,0x000afb47c6da5d04,0x00003a4c4a955197}, {0x000539c259338612,0x000a07494d9dd185,0x000e7bfa94994bcb,0x000236cf033de14c,0x00002e9b000521f9}}, + {{0x0008110399492969,0x000aa61db1b544e3,0x0006eaff55b63827,0x00028fae5323ed20,0x000042370d3521f4}, {0x000af2ee0d985a17,0x000b0239846df2ca,0x0006312f8192cc64,0x0001080c0b8f47ae,0x0000dc61f9206620}}, +}, +{/* digit=2 [{1,2,3,..,}]*([2^10]*G) */ + {{0x00081e144cc3adda,0x0005e7be82cf4f70,0x000dd6472d5ffa1d,0x000862e9890b6c0e,0x0000da26e1aded17}, {0x000271563483caaf,0x00083f6077fd276f,0x000466e3ce6924cd,0x000d1e15a7fe980a,0x00001c794b1a1902}}, + {{0x00024b9eb7926b83,0x00039dbe55093d2b,0x000dd640bbff88cb,0x000d45a0f399afe4,0x0000c5fe1305f76e}, {0x00062f43764fb3df,0x00074151b62d6f35,0x0009ce5f37b5af31,0x00090ee5bd0bc7d7,0x0000daf6b21dc668}}, + {{0x0007fe891e5d7d3f,0x000683a076783202,0x000dfdd61f14b7d1,0x000f48088497b3c0,0x00007c2eec11a8c4}, {0x00073f43756e621a,0x000f7825b948aa55,0x000878572c013a23,0x0001837c03b34563,0x00000472beb053a4}}, + {{0x000b0e5ab4b35a24,0x0001b5eeaacf6772,0x0005b95801d8b600,0x0001da328f7ce479,0x0000a20ed2a81fb8}, {0x0005cd44fec01e63,0x000c77ff50ad9f68,0x0002d97fd3ed7ddc,0x0004f9160fd2640c,0x0000a2414271b82f}}, + {{0x0002cf983dfedc91,0x00047d87631a29ae,0x00029c8d2f843713,0x0002729f57171174,0x00008d15867246d9}, {0x0003ecf69769bb7a,0x00062479ab828305,0x000b0f4b2c55eb85,0x000524bef7791c21,0x0000a5956badd491}}, + {{0x000bfa1c5c5ea50e,0x000b8796068184cf,0x000d50942d3baf14,0x000662463984030d,0x00004b7839d2716a}, {0x000f794e7de6dc08,0x0003e22aa7ced5f1,0x000acfeec5cd0f4d,0x000606d295f3f159,0x0000d933553153e0}}, + {{0x000533b3cef0d7d8,0x0007abbb4381e652,0x00080f500d94f7b1,0x000bfb038752be0e,0x0000e6e24891e9c9}, {0x000169716caca6a2,0x000818531ad9c975,0x00051ade1866c49d,0x000407a917e23971,0x0000d016ec18037c}}, + {{0x0009862d5d721d5b,0x0002abd3a1828000,0x000a2cda40c3357a,0x00008477f3a83b7a,0x000058ae74fa6f83}, {0x0001a812e6dad6be,0x0001143d6c5b2a91,0x00096c4d8de28605,0x00024d6bdccc41f9,0x00007312ec0eae1e}}, + {{0x0006e3960e913af1,0x000e88bf140d903f,0x0004890b8b2b58be,0x00024e8deff02535,0x000055810069d2e9}, {0x0005db493c95e5ba,0x00003ae20eb8b575,0x000b6d8e03fac42f,0x000efef377c8c109,0x000043e2b474b47c}}, + {{0x000b2fbfacfa4591,0x0008b1b5aa6b5f57,0x000db2092874b149,0x0001daa9e89acac4,0x0000362bf8def438}, {0x0006830b76328a07,0x000028572ae425d7,0x000132f7d38188b7,0x0002c9443e941429,0x0000895a29f92dd4}}, + {{0x00078dd5e22cbb29,0x000ae6bb4391cbde,0x000a4273bf449c85,0x000a18b289f357b6,0x0000fce23fdd8e84}, {0x0002730939eb3b47,0x000ba6c32280cfc3,0x000f1346c8b3d982,0x000fc8eac234bad5,0x000081954b4e0769}}, + {{0x00068feaae6ee702,0x00053602b0c96faf,0x00094052a78f4cc1,0x000d805e3321a86e,0x0000fb3a0d6934d5}, {0x0008f3bb25a43ba1,0x000109ee2951f3b9,0x000b0612a30bf803,0x0001d06ffee43321,0x00002f775e43eb82}}, + {{0x000f805f57209b51,0x0003e952ac8d4fdf,0x000969a6f9bd65ac,0x00075ef2a3abd3c7,0x0000359927f05237}, {0x000463f88d2e8610,0x0009623287c3e09b,0x00070eb7a661d219,0x000684821e64495a,0x0000afbbb1dd67dc}}, + {{0x000e3d3acff89f9f,0x000de852251f7418,0x00084658b227f16a,0x000f7ded5bc6e4eb,0x0000066b9c9e90a9}, {0x0009071800a7f873,0x000d2a72862ac236,0x000776da5383ddc0,0x0003182b48465d8a,0x0000d82f64f8e2d8}}, + {{0x000104b87453b283,0x00088387344d5852,0x0007cfc08073e812,0x000088000e78e481,0x0000a82ed47c9362}, {0x000304c88de46a44,0x000d17fadf4ae222,0x000c8e108666c94f,0x0000fa00b2d08ea0,0x0000b2955b949e05}}, + {{0x00012e76e6485b37,0x000b071c52f8f8d1,0x0004a2f6d4d3e24d,0x000550d8e3ee4168,0x0000161957d91d95}, {0x0001283cdb12a6c3,0x0001fe50e1641963,0x00066cc73bf3fa88,0x000c38c6254b6331,0x0000aefa7aedee8c}}, +}, +{/* digit=3 [{1,2,3,..,}]*([2^15]*G) */ + {{0x000fe623b36f9fd2,0x0003dde19fc079b0,0x0008482ef26543b2,0x000824f36e64a095,0x00003f63771bb095}, {0x000d596b6a1142e5,0x0005e35aac0b14cf,0x000081dd55ea6aac,0x00012a36a0e8bdf3,0x0000fb89d79503dc}}, + {{0x00065fce3779ee34,0x000d7d495d9e0f01,0x000284e7ae00e7f9,0x000218dfa4efa220,0x0000564bade87ac6}, {0x000312ac4708e8e4,0x000b671e9adf90e6,0x000684b9f4f5725f,0x000415a95f55ae3d,0x00007f7ccb15e94b}}, + {{0x00077e5522e6b693,0x00038bcd6c18da3a,0x00024fd5669c908c,0x0003f6ef1b9e48d9,0x00007c64e36da4bb}, {0x000dbdfee478d7d1,0x000bf193f7a05a4f,0x000cd16dfba75c8b,0x00015174bc1e8456,0x0000fb08f0856fad}}, + {{0x000890361a341c13,0x000fdcfd61423617,0x00033316c3604dc5,0x000921d22295eb85,0x0000dbde4ac74af2}, {0x000fc5d1c7eef696,0x0005714f4fa1898a,0x0003c21ca5889680,0x00030aa500216020,0x0000f0d1f30a0ef7}}, + {{0x0001b4b12cfe2978,0x000ba92f74e54820,0x000e874e83eee129,0x000c4161fe114ec9,0x000099b055d12c5f}, {0x0007a643a39c8cf8,0x000df8963cc94e47,0x00033f86382f09ef,0x000c62efd3fd8fd3,0x00005132b2b5c949}}, + {{0x0008b1dbe7a2af37,0x0008dfb74a72bd9b,0x000879697ec51caa,0x0007d549937a4b63,0x0000c9a9d215c268}, {0x000e44f6ef5f0145,0x0002990c69001773,0x00042161e8abcf41,0x000f29e87bd02281,0x000003937564cb6f}}, + {{0x000072232398baaa,0x0001bcfca031766e,0x000029cf2205fee4,0x00090d049f53417a,0x000088c68b8e0238}, {0x00050417337aaa82,0x000ceeb384f4bc27,0x000aba92f9ed364a,0x000a88c0816f8529,0x0000e9e194124e38}}, + {{0x000770977f7195ad,0x0006ddeb838ffabf,0x0004f012d8ec8616,0x000b3f1a1285a8bb,0x000068835046a3ea}, {0x00024f8309004c28,0x000593ffe95eee5d,0x000223ea4a96e4b7,0x000a528cdffe12bd,0x0000f5c2ee636739}}, + {{0x000e1dda1887395c,0x0005d32a65deecac,0x000a9552940960f3,0x000a35d611ff5c3a,0x000058215b13c1e5}, {0x0009b58f0e1a5240,0x000bf590dfb8d48c,0x000d95662b406856,0x000f82c7605e049c,0x0000dd036eea33ec}}, + {{0x000333959145a65f,0x00080a4063373d61,0x0008a52a0cd9bc36,0x00058f92d11be32d,0x00006877b2887a1c}, {0x000819bf5cbdb258,0x00085e090249837a,0x000990e5f2a4fd1d,0x00011ae22a7de774,0x000040fa5a0f9455}}, + {{0x00093277946d3f97,0x000397472273fe28,0x000b6ae86e132bd2,0x0000677eeb510c1e,0x000077708c660595}, {0x000c8cd1297029e8,0x000c3bf9305e18e2,0x00085d6d92c61095,0x0005306466c2586b,0x0000ac06c375a1ea}}, + {{0x00090b36b0cf82eb,0x00057615b5e7e58e,0x0009c145a6438d24,0x0001ca57b1f8fc66,0x00000d8b2dae6f1e}, {0x000dadbd9184c4d2,0x0005d93d997654d5,0x000147d473dbb18d,0x000608ea3e0f56d1,0x0000afa8c8dc0a48}}, + {{0x00039ad653ae3263,0x000a774cbb438712,0x000d4c08314bcf72,0x0004af5737650e20,0x0000df86536410ed}, {0x0006fe7b53ca5557,0x000d3bd5d538d2d8,0x000d38468688cb00,0x0007b65f81bda31a,0x0000ccfe3cd60116}}, + {{0x0008c07e3533d77b,0x00097e341c9926e0,0x0002dc4edd7222e6,0x000cf7ed60ec3d8d,0x0000dfe0d902c476}, {0x0009ab61d056605f,0x000596a8551f1fe5,0x000fb8d8ca9ea9df,0x000b0f9489941e47,0x0000eb874ec3a7f1}}, + {{0x000181060a716760,0x0008f66a8ad161fc,0x00017231ee852d1a,0x00011f172bbd6564,0x0000d6de7bd3babb}, {0x0006f88c8e347f89,0x00070bd99cc36fde,0x0000769501c58754,0x0003b9e8e54ed034,0x00007f0f335096e8}}, + {{0x0006aa9bd7638026,0x000005303da1ed40,0x000e62ec4c21486a,0x00033e01ae291ec7,0x000022a04933f993}, {0x0000c9dbb7a8ee0d,0x000b9c01aedb7fd8,0x000be74ecdc2ed3b,0x00071e65c35a1208,0x0000540cb1b169f6}}, +}, +{/* digit=4 [{1,2,3,..,}]*([2^20]*G) */ + {{0x000746a584c5e205,0x000169dc7035a7a8,0x000548c9b267e4ea,0x0002f3093a15cfb9,0x0000e6e21359bd01}, {0x000cc6a8c8f936e6,0x000455c241dcdf31,0x0005efb868af84d0,0x0002cb03990a6f34,0x0000fef4e6219b96}}, + {{0x0008f09257226088,0x000a931cf5c6f636,0x000b4f7ac131260d,0x000828c0eb353bfa,0x00005c78880b7eee}, {0x00081ffc3bdf24eb,0x000b45c3c5a84c15,0x0004e6f405bff75c,0x0000c985e8c83fa1,0x000081d1c0fb295e}}, + {{0x000e23d442a8ad11,0x000cf6b9c164f2ef,0x0000aa5e5c3816a7,0x000e6599df2d8bdc,0x000091ae46f220a8}, {0x0007f8700611c5bf,0x00070f1099488366,0x00069595283171ed,0x000a1243a2ecf8ca,0x0000a4a73efe48d1}}, + {{0x0007cc8f43a730f8,0x000bb3ab590efcde,0x00003240be89b6f3,0x0005db4823f529ad,0x00002b79aff18bea}, {0x0002856962fe5de3,0x000b30c591f3568f,0x00028a8580c590ad,0x000f4befc74a144a,0x0000b662498e3203}}, + {{0x0004ed082dd1b6ad,0x000797b703af48fc,0x0005d6aaa5783a13,0x000d425463cb9a00,0x000031ec55d406ec}, {0x000d33f8e9a76414,0x000cc98d9e7a9f8e,0x000887493625453e,0x00056663beade4ec,0x000042b80509a795}}, + {{0x000cf0d6c39765a2,0x000d8c3cca0b91e3,0x000953b50a2db3ac,0x000f1a088f2f08cb,0x0000414582cef43c}, {0x0008bbc60eee9a8a,0x0001d29aa0428dec,0x00032f5d554c79f0,0x00015f381cd5ec65,0x0000672303b6f82e}}, + {{0x000582d3bfab839b,0x00037f8adade46df,0x0007a1bc392474e0,0x00097886a7766a14,0x00006940f54bdc0f}, {0x0008ef2f2759f255,0x00095719f4c64473,0x00050c3459dd9578,0x0000d4d859b7f407,0x0000e788bf302218}}, + {{0x000afa8719c05631,0x000cac5fc79f376a,0x000750cd3cd8ad2d,0x00008e203fdb9fcb,0x00004ff052f5418b}, {0x00084cf3e2d65208,0x0007944ed509f750,0x000f25b987ebdf0f,0x000837743bf0f2d3,0x00006ad71d02354d}}, + {{0x000c9fdfd67ca259,0x0007d0f2015ca839,0x0007b2a65023e626,0x000cba9414a7930e,0x00002dbe373413ed}, {0x00081ee64c2200f7,0x000f1446f2f3f649,0x0001367bb94fb9cd,0x00033091411a6a3f,0x0000985c191ca1e8}}, + {{0x000fe9226f435728,0x000add824758b827,0x0009094c1dfd3ab5,0x000d67b15dd23a53,0x00005c0e37ae6623}, {0x00079727be19ae06,0x00067f0d36b5575c,0x000b1ff7e616a339,0x00045341ebb3c826,0x000035b9485740ad}}, + {{0x0003c6037e2efeaf,0x0001134a96f6c812,0x0003e4a958d49b50,0x0000fe566a346b97,0x0000176b5bba7de0}, {0x000fa3b82dfa945b,0x000559e429ae1c58,0x0002b187c2eb27a9,0x000bb9a7c67a67a1,0x0000155ba8392298}}, + {{0x0003cdada430c0b9,0x000daa96dac692bf,0x000ac326a4702850,0x0005e4391cf0a515,0x00005de4f4a3b8c2}, {0x000ad09e265c17ce,0x0003287b3881b01b,0x000fac5ca24e4546,0x0007a5f43e583ce1,0x000017cb3194ead9}}, + {{0x00042073d99bcfab,0x000c38becf6df1a5,0x00045956959db703,0x00090f7e455142d2,0x00000ee51445901b}, {0x000d451e26d994fa,0x00037360caaffc05,0x000a639b17a6062b,0x0008b03f1ded5f4f,0x0000f9303497335b}}, + {{0x000924374dcec468,0x000cd4c2b73f6cc3,0x0006cd99c33cfc02,0x000f8902917844f2,0x0000819dd9651773}, {0x0002aa60871f4274,0x0005b6f01c340957,0x000f1f5af8e0cf36,0x000e503fa52988bf,0x0000eb357eb275e8}}, + {{0x000248a21fd08616,0x00043bd5a4b63d8f,0x000e2a6bfade3bd6,0x000c5f6b56c953c2,0x000099cd2b5887d6}, {0x000e1be47d05e8f9,0x000318f53732debc,0x000852b081a4fbb1,0x00087a07163beaa5,0x00002c49e6d7ec69}}, + {{0x000c8c4868af75df,0x000e55c8c7ead9d0,0x00081ecb0d7325cf,0x0004ecbb471996cc,0x0000f5d55f451182}, {0x00045411977a0ee8,0x0004f22038c6be31,0x0004bb4955085c4c,0x000081ad5335bff9,0x000094ad8a748e2a}}, +}, +{/* digit=5 [{1,2,3,..,}]*([2^25]*G) */ + {{0x00034b22c11bb373,0x000dbd4c74a35402,0x000c5f25d2d0366d,0x000142c9a968daee,0x0000660106897b63}, {0x0006d2c68d7b6d44,0x0008cc84294207cd,0x00068b1eea8f74f0,0x000ee4a275140477,0x0000b5f7e8a3e62a}}, + {{0x0009f0b879fbbed4,0x00069a9d1869f236,0x000766f450ff0ae8,0x0000fc1251d75956,0x0000984d8c06be8d}, {0x00095a6d21008f03,0x00000a1a1c497ecc,0x0006c50f329bd54a,0x0002517b9828c5d2,0x00002c0087c81d0d}}, + {{0x000eb6662b5f3af3,0x0000dabb373447fe,0x000f35cb1cefab56,0x000eb9149de60e19,0x00009f8db14457f0}, {0x000cc5b3c61bfd60,0x000d41216703ffae,0x0004e1cc2a5a4d41,0x0009537f8fabed22,0x0000d5a8186871ad}}, + {{0x0008ea601799a527,0x0001486d2952190d,0x000ff2a7ca20cec4,0x000d36c062ffb27f,0x000041b32e5e9f19}, {0x00081814eb57d471,0x000406aef06bf80d,0x000ecb5887a2d0ed,0x000f5af9735fb01c,0x0000641caaad6061}}, + {{0x000d171656e8c3aa,0x00027acd0705ae2a,0x000b6055cc0e2a46,0x00026d606f6a8aa0,0x0000f4513d7cb65a}, {0x0009e14d616d5bcb,0x0004c1253b1f3f54,0x000ce243a64ee395,0x000e7738b10bc1b8,0x0000cbeace6413a4}}, + {{0x0002256f779d6a77,0x000ca9e7284e68d3,0x000f3b15320423b4,0x0007036e19aa1b38,0x00003d0b6c2f444f}, {0x00061489c64e6a37,0x0006c72562246661,0x00033156399587c3,0x00002dff5277fe61,0x0000174ad4b16565}}, + {{0x000fc920133918d8,0x000e32c9ef97ec1f,0x0006cbb9a15d9bf5,0x000f5cf885b542fc,0x0000abe6453d720c}, {0x0005dced4ec68aba,0x0003879c24a34e71,0x000bb61cf57a6761,0x000002d88ed52a31,0x0000ba824459437a}}, + {{0x000824f20151427a,0x0005f24302067f99,0x000112357206828b,0x0004ec0a9097d7e1,0x0000cf9a2f2a9e41}, {0x000c9da279153564,0x0006c01efee3dbda,0x000b288e27e0734b,0x00009c14fab5bbd2,0x0000c630fc5362dd}}, + {{0x0003e66bd70a5e18,0x0001505de7136d88,0x000d8487d9bd884c,0x000404c8d9d445d4,0x0000440cd8b8eeae}, {0x0000f293d26f83eb,0x000f72a3c5e4a3cd,0x000fa2ca73fd9452,0x000096b3a078663f,0x0000feadd29b0d4a}}, + {{0x000a559d68432ba6,0x000b733915db13ae,0x000e8da08940043f,0x0005bae76c7c94e2,0x0000b1630c4a4306}, {0x000546d19f06c75d,0x00015eb35abdd6d8,0x000157d8e7e1e98c,0x000074a51c9310f0,0x0000ef84328c6fa6}}, + {{0x000993c3a7a4e0e9,0x000f0d79d314765b,0x00019eb24fb8f4ae,0x000c8bcea2c50e2a,0x000025016e64891b}, {0x000afdc3ad1ece76,0x000c908fabe28f70,0x000f6132b0abba84,0x000d76aa9922c815,0x0000c021373bd076}}, + {{0x0002615a44539610,0x000b993d112c00af,0x000cdd6521705494,0x000cb30032e12aa1,0x0000ebfa612046d9}, {0x000a9f31b63728c8,0x00025e022b059f03,0x00077c5c98f3618a,0x00077c55b24d903e,0x000037838a3f2acb}}, + {{0x000cbd98fceb0471,0x00052f8b11a1fe65,0x000ec802fde872ef,0x00081d8aba0d3d8f,0x000039f1d32aa9f3}, {0x000aed9c587958d1,0x000ca9f6a7da0721,0x0005d9d06066a015,0x000a1ef59ec4e3ed,0x000044285717cbac}}, + {{0x0000fffe298cdf56,0x00041b2e51b666fe,0x000d3afa43f61bea,0x000e2f1d372117ba,0x0000521a09d4f656}, {0x000c966e8a58fe76,0x0000fa47ebc7b3b8,0x0004be57325203a1,0x00003c9e81588d5c,0x0000132e2f37f49a}}, + {{0x000b0130f8c2c991,0x000fe17725c2ec1a,0x0000a980b60e8968,0x000cb1d1a4a59394,0x00005ed15b030e9c}, {0x00054cc64a00bec8,0x0002c168738277d7,0x0001fb65190d09c3,0x000e52a94fe02dc3,0x0000372cd1a9c94a}}, + {{0x000107a1ac2703b2,0x00084bc857b58537,0x000daccd1b49258d,0x00052937df14debc,0x00004ab68d7e4ae8}, {0x000b5d4734e59d08,0x00084495cc807ed8,0x0001db9b35f8740c,0x0005be04aedd5a29,0x00000b360f8cfb99}}, +}, +{/* digit=6 [{1,2,3,..,}]*([2^30]*G) */ + {{0x000c68da61a76fa3,0x000d9a1554dc55d5,0x0003b279c598b441,0x000efca39923b977,0x00003331d3c66bf9}, {0x000848e298de399d,0x0006d1a27f562d4c,0x000b8ab70cfdb8e7,0x0009b9c4c855ea57,0x0000cdb9daf3f787}}, + {{0x00007367f636a38c,0x00064e76d5cb4c4f,0x000b68b8b9f943fb,0x000a1ef03510baa8,0x0000246780b5ed07}, {0x00014156d549fc2b,0x0000b07781ca3c05,0x000d95413c2953f3,0x0002e2e55e2c69d8,0x0000300fadd2bd28}}, + {{0x0001163c27901b4b,0x000fd99b8bf3a14b,0x000c6da0afd9236d,0x00029692b091eccb,0x0000b1dac700ad1d}, {0x0001d53a91cf76e1,0x0002c31f1ee780e6,0x000efcf774110a41,0x000d761d87c3ba13,0x0000f374bb4ef450}}, + {{0x00086024147519ad,0x000b56b372f02028,0x00085ebc8d0981ea,0x0008e8d9d4a7caa7,0x0000953c50eabdf5}, {0x00061ccfd590f8f8,0x000ac4e6c9179d63,0x000eb64cf72e9626,0x0008f2ffd9611022,0x000063ebb7f1eb28}}, + {{0x0000a0a097e4403b,0x00056985466515e1,0x0007d4826cb3d0a8,0x000838d8d8e211d6,0x000039af66ebb9d2}, {0x0004588bd475ca8d,0x0005f077b80ba5f9,0x00027c26ce06b796,0x0005e02edb1485da,0x0000290d33bce0fd}}, + {{0x00002f31306583d2,0x0000237c622e6862,0x0006a7bc805b10da,0x000e439f9aaa0f07,0x00005e94efbaf8f4}, {0x000c9b7fa3dc26dc,0x0002d6ff03c58a35,0x000c394cee0e5fb9,0x000e5fe77e3843eb,0x0000ede65964361d}}, + {{0x00075090c22b5403,0x000a87c267d4bf90,0x000b0d6932cde42a,0x0000d98a18f9ed5a,0x0000ba62aa69e466}, {0x000f97bab9ea96a6,0x000283b60e32b24b,0x0004d9bd55d03964,0x0006a3ee6a45067c,0x000066c5b9eded4a}}, + {{0x0007cf5678a31b0f,0x000d4998b620877b,0x0000fb396d50301a,0x0002a5834257c5c0,0x00009fb18a0f4e67}, {0x000d8ebe8758851b,0x0005ad99ba44ff8b,0x000fd93b71e64e4c,0x000b8b9b8eaedf7d,0x0000a2f2a98b4e76}}, + {{0x000a2f09b56ddbdb,0x000bda2f1cf3ae02,0x0009dff0d1339b5a,0x00043d42b569c783,0x00000b9e865aee9a}, {0x000ca4177bb064e9,0x00026d249f634ff8,0x0006f689a145a281,0x000f5daab7beacf8,0x0000bafec2791d35}}, + {{0x0003fddae57c7b7a,0x00017b932522bba2,0x0006d4aa3345342f,0x000b615d9c80fe55,0x000003907bb0525b}, {0x00010e1ff2189336,0x00044a52117b38b0,0x000f2e6eac066b65,0x0002b22e14192094,0x00006a27dca6d32f}}, + {{0x000b121fbabbe926,0x000b81330076b2e6,0x000890015281850f,0x0007f4a93581ec97,0x00009b1ddedd5ff7}, {0x000b18fab1051053,0x0001789ccfef7cf0,0x000914009953ced3,0x0008ad0151f85feb,0x0000c9f1b87b8ed4}}, + {{0x00007e0e90fb21e5,0x00006ba7fca1a18f,0x000cd67b500fd2b8,0x0007f6d0387f2795,0x0000b89a4e823970}, {0x000ad3f894407ce5,0x00041c2261328f83,0x00006c13ba0025b9,0x000025779563c7f9,0x0000f548f319e7bb}}, + {{0x00089494fde0c1fc,0x000e25b6ec20ff75,0x000e1db6cbf8a1ab,0x00058eb02278fb87,0x0000447ad7af5ed6}, {0x000aa3803d0ccf24,0x0008419a7c0348d4,0x00017cecc80acb33,0x000d825bc7c89e6e,0x00006736b8b43be1}}, + {{0x000f742d43b5eaaa,0x00063fa59b852126,0x0006bfd45054a076,0x000a8efd0d5e3612,0x00001f8fbd7d84f8}, {0x00080f5d563fccc1,0x0005e280a9283176,0x000b578cf48ca505,0x000514d00b81b227,0x00000aad9183994a}}, + {{0x000301f358bcdc04,0x0008ca9d47f8e63f,0x00043d43a07689e9,0x000903df689e2f4f,0x0000d542a16d0920}, {0x00093d59ca0a7072,0x00056ac68065aea2,0x00090008cd061fe4,0x000db5f033bf1b00,0x00009749558e08a6}}, + {{0x000d3a7c35d87949,0x00077356bae50ee6,0x0003322fd042e655,0x0009670f59698d64,0x0000379ae15e0a61}, {0x000ae62fcc9981ea,0x0000cd2934c664b9,0x0004e65ebaed3d63,0x0004278454b3025e,0x0000b09f64899950}}, +}, +{/* digit=7 [{1,2,3,..,}]*([2^35]*G) */ + {{0x0003a1222248acc7,0x000ec264e366b208,0x000fdee281f6ec0e,0x000bb4e659b7045a,0x0000a823a4156430}, {0x0002a04e1900a791,0x000ab9ee65762459,0x0005ea54acde09d4,0x0005a742b6463f4b,0x0000efe9ed3e3ca6}}, + {{0x0006dbe305406dd9,0x000f4d5d1957e27a,0x0007d4d8f8eb7dc7,0x000de4654a687638,0x0000c47940a57762}, {0x0005b5d99b307781,0x00065e793682be4d,0x000c740e325380c5,0x0004ae502d37f3da,0x000040deabe2566e}}, + {{0x000d067afd32acfd,0x000a11f71ccf4481,0x00096f2dad8f0fcc,0x0003f90208dd0cb5,0x0000049d7316aad9}, {0x000263d42ab580e7,0x0000b3f707b4c79f,0x0005e0eda09411bb,0x0004021cfde1ff83,0x0000270749100f03}}, + {{0x0006126c49a861ec,0x0005214f0d06eaee,0x0009bfc17024f3b6,0x00038091a3f1e8c6,0x00003c3a8ea67686}, {0x000752cb103d4c8d,0x0002c218b36b3400,0x00051504a02bc461,0x000bf9f67f75eb76,0x00006848b57a02ae}}, + {{0x00002e6c30fa92bf,0x000caa552784bd98,0x00083169b5a70d96,0x000227a085c4ea3f,0x0000a9423bbf6908}, {0x000be12fe97a5b9f,0x000881b991182ffe,0x00017884685da604,0x00018dacbc2f7f63,0x0000d96bc7181532}}, + {{0x00081db1782269b6,0x0008c597e5509583,0x000385153ae34bf7,0x0000485b5c60645f,0x0000f0e96b043088}, {0x000021577884456e,0x000b89310ea7bf6a,0x000fad2deb3b5688,0x000d4c37c9429504,0x0000020f0e5f7896}}, + {{0x000a0ab0976505f7,0x0002995e2ec5730b,0x00031ab71567f681,0x000b9ed706201063,0x00002cfa977b1d22}, {0x0005ead8a2373da8,0x0003fba45a6833e5,0x000029d15a8d0d5f,0x0009f33a1d8f9c03,0x0000f34f1cd7c55b}}, + {{0x000428dbbe5a1a9a,0x000e9126bd67cca4,0x0001058268187fd5,0x00019f6036973a48,0x000039b666458bd6}, {0x000deef2d65a8087,0x000f24636b196d42,0x0005d564c4969044,0x0000778611ee47dd,0x0000b2f3a4a42873}}, + {{0x0007d45300eb294a,0x000d769c14949415,0x000a47aa92b2a656,0x000ea42000dd76d3,0x00002864e5046243}, {0x0006c47db89842e4,0x000721479fb78271,0x000b2f6dc12dfd7d,0x000d66fb9a2c56e0,0x00006be862b17f85}}, + {{0x000d8dd0f82b2148,0x00097103cbc603b0,0x000d79e19460c34f,0x0007f8732e5c0318,0x0000b8888bb28411}, {0x00037dcc07226779,0x00088c1c0f278f3c,0x000f7a0c610d21be,0x0000e0447c8468e0,0x0000bf022143decc}}, + {{0x0007d1242b48b998,0x000cc84240960baa,0x000fb5cfb1bcb665,0x00010d0b847cd6eb,0x00007c2ae571ad4d}, {0x000b1220de367261,0x00082fdfbd21f1cb,0x00079d460e7043c6,0x0002cb3bd0826a4e,0x00001f5e5985bd1a}}, + {{0x0004160b7fe7b6e0,0x000a400a3fb29755,0x00028ca1e7d16189,0x0008ccd73e9beae3,0x0000dd04b97e793d}, {0x0003c9b506db8cc0,0x000ecf38814ca9c8,0x0004b45e65cd47aa,0x000a8426fc430db6,0x000079b5499d818e}}, + {{0x0001102c1c24a3b9,0x00078c161c1aebb0,0x000f00a4aca24e56,0x000c7a803eea6936,0x0000ad76ee906176}, {0x0001fc2538e0ff72,0x00094604b3b09745,0x00049cfd794f8980,0x000f694311436e32,0x00007b4a7bd61224}}, + {{0x000d21ae0ac29416,0x000462d3193703b5,0x000c992d0279b025,0x0001f2d307c052ca,0x0000aa7cb934fa8b}, {0x00025800d37c7a50,0x0007342d54225a18,0x000d2ef9213380c3,0x0003c692ac2d66d5,0x000035a70c9030c6}}, + {{0x00025dd4ce4f152f,0x000109df7c06c160,0x000e4bb141f419a7,0x0004cd7d5b221491,0x0000c43c6cd739fb}, {0x0006591925d6b2de,0x00028218659849f0,0x0001b16294b37d9d,0x000e04ac54a971d0,0x00001a9c2a031d50}}, + {{0x000b78571ba18615,0x000c80c8f93d5109,0x00033bb9348b22d5,0x000d0898fa84a786,0x00003fba6baaaebb}, {0x0007df3e5eea7d82,0x000648ca71587ff2,0x0006f1a05521c879,0x000ee499d5133bce,0x0000d50cd541d0eb}}, +}, +{/* digit=8 [{1,2,3,..,}]*([2^40]*G) */ + {{0x0006d65533ef2177,0x000453ca2e87889f,0x0002b41677158c7e,0x00057f8b670dfbdc,0x00005910a01f44c2}, {0x000bf07cf88577d2,0x0000c45e2acef336,0x000a23d852224525,0x000f580ed92e8d7c,0x00009f8be4c4b812}}, + {{0x000b2452133ffd9d,0x0000b30f1a20fbb9,0x000a1f52a39a8b2f,0x000df7784bc97dd5,0x00006aebf57740ed}, {0x0007acb76ccdac60,0x000c1586ff273225,0x000de7dd1af4d36e,0x000c168eaa8863f8,0x0000045d5cf88647}}, + {{0x000414351facc618,0x000d668a25bcc51e,0x000f872edbaf2647,0x0006590f5271a00f,0x0000f32ef99bd2d9}, {0x000488c7593cbd4c,0x000c42b82fabca12,0x000eb3f16ed266c5,0x000fe24a2f78ad14,0x000034049490d47a}}, + {{0x000d574c005979da,0x0001ca40e350a6f3,0x000e2ecf9c2072b4,0x00044e5ca5c1568d,0x00008c8bf5c45153}, {0x000e555114df14a7,0x000d8dc5ec6b97ae,0x000a85418d4374a4,0x000f78054cc28f2c,0x00001cb9e2843c41}}, + {{0x0006702094704963,0x000dbbd2381509c1,0x000dd4398a489a5e,0x00069694dde4648e,0x0000ca7b94ab0111}, {0x0005d682ad636a41,0x0004f8dc5f1e3c38,0x000a219436702702,0x00069dfc1965deaf,0x00008666e16710be}}, + {{0x000fd350369c8e10,0x0002b9dc843b6792,0x00002e2ab9271aa6,0x0003838711a4b14d,0x00002b2a3e27ee1a}, {0x000e35f0e2b379be,0x000bf652ab25b226,0x0005601063d3de39,0x000876cca6d4c93b,0x0000ced0cf5a95bd}}, + {{0x000b4ca2a604b3b7,0x0003ca61676245be,0x0008b806e56f6518,0x000480852f5a7097,0x0000aa3978781dc4}, {0x000ac2a0e01fabc4,0x0004e37d99f9e13f,0x000211ffe7c6ee8a,0x0003eae51384ee05,0x0000ff6976d5bc9d}}, + {{0x000507903605c397,0x000e3142c96c8910,0x000923684f0843d9,0x0008938374493416,0x000032caa306a0a2}, {0x000c27061160170e,0x000b637fbaa3b2e8,0x000eda3acc32788c,0x000e0659cd818ea6,0x00002e9423a7e2b2}}, + {{0x000492316e043a20,0x00011dd3d209dde0,0x00031ebe898a4526,0x000abdeaf9f61bd4,0x00000919f4dbaf56}, {0x00017db6d8774b1e,0x000b78e0e309e424,0x000df81ea5fc5279,0x000c7e84aa40613a,0x0000f419edb9c627}}, + {{0x000759239ef620fd,0x000fa4fa29c43919,0x000416d839d47283,0x0002687e428fa39d,0x00001a7c251f9f30}, {0x0006e1cd746218f3,0x0007e10d967e4607,0x0000ae61ff3ad6ee,0x000929cbb5f434a0,0x0000cd2c019b0d4c}}, + {{0x000d0537a4af00f8,0x00064a294614fa24,0x00082182e3f93892,0x0009468d700c1839,0x00000133443ccc59}, {0x0007106ec87c9255,0x000bbed6665cf039,0x000cca8b562bd59f,0x000a3098414348c7,0x000074c7620ef9f0}}, + {{0x000d39b0260e52a4,0x000c506533256967,0x000ca7954d42585c,0x0007b2cd9bd60521,0x0000fa20877c1ed5}, {0x000eff8e34a0bbeb,0x000bd4f6ef6460c1,0x000af848356b0040,0x00061378be2b24b1,0x00002278164a5531}}, + {{0x00042e2bb8b6a071,0x000eba23f86a95be,0x0004ce47064be74e,0x00076a973d74fd15,0x0000c2d2857e8dc0}, {0x0001c575a8878682,0x000b1de64818b1fa,0x0004e896738df8e0,0x00076cb88e52f9c3,0x000074b4f01ab4cc}}, + {{0x0001ec2c11c208bc,0x00098e3a723459c8,0x000a089d8240207d,0x0000718957eb80f4,0x000086960bce137a}, {0x00054fd7f1a932c2,0x0004b3f2fa17de11,0x00011c0ebb517fe7,0x000d360d5d945571,0x0000aa33789a0929}}, + {{0x00005b4f8b7559df,0x000c0ae292003f5c,0x000532acc0be4c7a,0x000284ed6d3ef756,0x00006c3ed88dea7a}, {0x000b0a8f46ec59b3,0x0004bcea6c83e463,0x000dc836b531d9b1,0x000f0b0d6bdbafc2,0x0000ee501e95ab27}}, + {{0x00075455922ac1c3,0x000c752b3f638df2,0x000de57c4a7b3ef5,0x00008b5e77b21471,0x00001682c10b34c0}, {0x00024f04bd55d319,0x000587b61c71c768,0x000a5089db6d1c08,0x000d3ea1db0903c2,0x0000c092172a84e5}}, +}, +{/* digit=9 [{1,2,3,..,}]*([2^45]*G) */ + {{0x0005035ea6c39976,0x000a62610bef5ace,0x00080dd3954259aa,0x000a398f18bb3f3c,0x0000910b95bbfc3f}, {0x000f51043e09aee6,0x000f47675665fce2,0x00072db61ced56c9,0x000e68b0e265acd8,0x0000982812f0e9fc}}, + {{0x0003d931341ed7a4,0x000c67b59d49b8fa,0x000b8c4a44223272,0x0002e3fdcb194783,0x0000e413c022d130}, {0x0009127e17e44ceb,0x000483b3adfb6d99,0x000aa96caee86bf7,0x00047d46902fe625,0x000073540e595aae}}, + {{0x000ef6c872b4a606,0x0003e613521bcc50,0x0003e15d1ab2a34a,0x000511d9c5c19098,0x00001dde5dfb9905}, {0x000f6219f2275f33,0x0006151d894be417,0x000b0bdaa0750c8b,0x0009bd45b04ab978,0x0000bfd9fd475858}}, + {{0x000bfabaf95894c5,0x0006d76b2241aafc,0x000dda48b7b9bdc0,0x0004df9af983625b,0x0000977faf2f3fcb}, {0x00042ef052c4b5b7,0x0000967591f0bed0,0x000f24ec79fe87f7,0x000f1b589c73ca22,0x0000d37fa9f564a9}}, + {{0x000148045ee2f40e,0x000e616b60cfbd78,0x00049a8c475e354a,0x000535fe0b58a18d,0x000040e94e3da359}, {0x000a59f62accd765,0x000a3c762837bd4f,0x0008c277b05cf466,0x00074065abda9944,0x0000a9e01bf98b13}}, + {{0x00055e6f2606a828,0x000110f2fb57b51e,0x000a4e37ce25f706,0x0007062cef6c2ab1,0x000064e359dddcf2}, {0x0006b187ce573162,0x00001a96b23d479e,0x000f16df72cab250,0x0008b5cd4898628e,0x0000056538d0f375}}, + {{0x000a0c3d41d3bd3d,0x000837a26bdeef69,0x0002edf9fb533b8c,0x000af012801d97db,0x0000c4a826ab1877}, {0x00058513d590dbeb,0x000b3e4e93576c1c,0x000b3337484632f6,0x0002e6236d36b779,0x000046833e44bbca}}, + {{0x00064880a750c0f3,0x00031e548e83cc7a,0x000110f0539bacfe,0x0005880d418c760c,0x0000e4daa4ce1f11}, {0x000e7b55ffc69ff6,0x000c320531272733,0x00022df9446f147b,0x000b7c285b2434d7,0x0000a444f6646fc6}}, + {{0x000e4bb346ac9cbf,0x000339811bb2008b,0x0001540c12e6cb02,0x000e46b6ccc747f4,0x0000119334febf6d}, {0x000ffe9cc97fe6e0,0x000bf3d828834e6b,0x0003dd1c77f4b578,0x000495459db72275,0x00005843cd82066b}}, + {{0x0008cd5dbf2af333,0x000e7f6b0eab7cb8,0x00040d844ded9566,0x00067fa1caf5488e,0x0000ae59bd6ace1f}, {0x000ad33dd82429e5,0x000b6c4467c7acf4,0x00083d011cc7ebd2,0x000db7a4f6e95de7,0x0000197e39166e92}}, + {{0x000031885e7a4af1,0x0000e7a6878dd4f2,0x000051913291bf9a,0x0000349dd8b6eebd,0x000074f5125036be}, {0x000364527f601893,0x000d5b37ec732ac3,0x000fdb42ed8902ee,0x000421246166a11c,0x00001c4e3b837076}}, + {{0x0009dfdbc6ebdfb0,0x000589de549b7de2,0x000f26a64a1ee450,0x000980fd7181aa3e,0x000003179eedf2f3}, {0x0004d30fd71bc789,0x00042e86a5831bce,0x000b85711eb842b1,0x000405500125dc5e,0x0000f5869848f11f}}, + {{0x000089eb833eccba,0x0009dbc51c795b5a,0x000be0e93c1b3077,0x0001724581157f9f,0x0000b487d69fb29b}, {0x00051082222f24bf,0x000c06dd35dfc725,0x000c24afe338cd22,0x0006eca2010e6f5f,0x00008298f16581d4}}, + {{0x000f723042389edd,0x0004d54b19722ce7,0x000251d75df7de0d,0x0008c7e8ea2e142c,0x000022a4d38c4e8e}, {0x00058566c29c8bcf,0x000d2d1e201ee999,0x000c885c99fefdbf,0x000c6fc97d946eda,0x00006ea9768c38ea}}, + {{0x000a8e974e75a2ec,0x000dedac968f9aac,0x000306befcda6fc1,0x0007f87f6651bf46,0x00007445e4f8b2ed}, {0x00012d8d1571ac12,0x0004baf3a679584a,0x0003fbc43684846c,0x0004f2afc622a986,0x0000f9e101e0a681}}, + {{0x000465ac3f16ea83,0x000d82f1d11c7a1a,0x00068a172115a461,0x0006981767dd956c,0x0000392f2ec013a4}, {0x0009ccde526cdc7f,0x000b32292b81c7a9,0x000d391988e537fd,0x00052c86d8cf69a6,0x0000fc5ff4414468}}, +}, +{/* digit=10 [{1,2,3,..,}]*([2^50]*G) */ + {{0x0004f7ea90567e6d,0x0006e6ae5cb797b1,0x00010903d513257b,0x000723b5454a3c9f,0x00008d2c9ae39bc3}, {0x00093246b29cb44f,0x000c87c8cbac38da,0x000918e42b540a21,0x00014dabbfe43501,0x0000ffa707b46c36}}, + {{0x000e05b1cb76219d,0x0000a1567e7e56c2,0x000c4c9100ec0bf9,0x0004d917076f8661,0x000067b085c8abc0}, {0x00004595e93a96a9,0x000a6bdc249a9fb9,0x000dd0bb77526c1e,0x0006947d44d367ec,0x000053999182dc0d}}, + {{0x000c583a4c506ece,0x0007f1acfe972ccb,0x000f1aea2957ed18,0x00062cabaed83312,0x0000f2a6cb563253}, {0x000de428e195c43b,0x00095e6050c6130d,0x000686a5dc842025,0x0004a77da972a708,0x000052999a29508b}}, + {{0x0009167ceca9754a,0x0005ab7939a083f4,0x0003fd0bf426d2cf,0x0004e18555e35572,0x000096e6d0764f14}, {0x000a8dd87880e616,0x00058508e4d54768,0x000b65e151554381,0x000f9fa9d7e772b1,0x00003439dd70c302}}, + {{0x000f8e1698e04cc2,0x0002f69005c8b11d,0x0003c6179877be20,0x000c0512749e8c4f,0x0000dbc9d0a9853f}, {0x0004f939454d9370,0x000db4800e1b187d,0x0005e68e8e682ce9,0x00085ba9129ad816,0x0000fe29735be7f7}}, + {{0x0009ccf3a4434b4b,0x00006a7954dc3101,0x0004972a7a345811,0x0008dcf9dac80de3,0x0000043d05524f6b}, {0x000319e11137b1a0,0x000eed5cc03f021c,0x000ea5ad400a754c,0x0005b60aa2c794cb,0x000093e67f470c01}}, + {{0x0000351d598d7107,0x00065b3a4da420ac,0x00071de1f272c416,0x000b0f6b82fe1aca,0x000046e79f348f54}, {0x000c7364b573e9b5,0x0006ad4b50406e7f,0x00098d87b75d03f4,0x000da10c1cc36d0b,0x000013ba3f16f472}}, + {{0x0003145983c38b5e,0x000b837abc8b859d,0x000ff7be6b14f176,0x000a594793fb9dca,0x0000be5a56015a66}, {0x0001dcd9f87dc596,0x00039bdbf5607cec,0x000eb32577c595cd,0x0005fcfb543b2226,0x0000908064724c93}}, + {{0x000b70678a6513b9,0x000a0edb1943dca3,0x0006e2dd892ea4a2,0x00089372642216db,0x0000b45d0b52fd57}, {0x00070dbc69d11ae9,0x0008bc57595f114e,0x00077c2721477dd1,0x00059c2c2208b4ec,0x00005c5b4d86b68f}}, + {{0x0001fa47ea67c77a,0x000f43ea810cfe54,0x00001d374952bd2a,0x00036dd91fef568d,0x00003a1c621af113}, {0x000d5a9c7ec6d792,0x000f1225c3425ad0,0x00069601bff7038a,0x00047ce03c6689bc,0x00005059bc765e87}}, + {{0x000c80676cb25661,0x0001a24892d99a75,0x00008fe458f76acb,0x0007d86ae7b9cc1f,0x00009ef73297a490}, {0x000ab715f228bf03,0x0009517032d72db4,0x000abe3c0f3cdea3,0x00025bdb1f482edc,0x0000baf76b4eb863}}, + {{0x000688eadd70482e,0x00099b4a4e8a6aac,0x0008a6eef708de92,0x000c4295b6dd7375,0x0000a4bf353525b3}, {0x0001f2c87912868c,0x00052f09297a1004,0x000f3860ab1b1be9,0x000f4a59ae23c5a9,0x00004f0f83a115dc}}, + {{0x00027bf8538a5c69,0x000cf9abff17c71e,0x00071e3da195c63d,0x000fa06d3152851b,0x0000cbdfda88a680}, {0x00076ca849d7eab8,0x000abc2732719db8,0x00008dceaebe2764,0x000b6fe63357e3f2,0x0000c5bd833d65b1}}, + {{0x0000d7c2fa4f1264,0x00051c99a2327590,0x00025e0c308a3b86,0x000edee478b6bfdb,0x000082cc2c2b1db2}, {0x0007e645f321bb80,0x000b9a8005b437df,0x0008c19588a93821,0x000d0a3fa2f10ccc,0x0000d3322182c269}}, + {{0x00014df3fd165e81,0x0008f61f8811ba55,0x000ef9f00499fd6a,0x000e8a62cd1fe0bf,0x000020a4bb989ad7}, {0x000d0955f4a5ac5d,0x0000c5a7a2f0f2ff,0x00017baf1cfd174f,0x000089042301ba9d,0x00002fa487b47f22}}, + {{0x00052381d531696e,0x000fa8cdde69b934,0x00086afc757201bf,0x000ea7fde922519a,0x000030438969d35c}, {0x000c1e18555970de,0x00084535935e7608,0x0002ea38b8267dfa,0x0008b4f4c60a5732,0x00000bf7978604ef}}, +}, +{/* digit=11 [{1,2,3,..,}]*([2^55]*G) */ + {{0x000ea68c094dbb56,0x000e7968d4106233,0x000b3002db77d062,0x000d57de719bbc58,0x00008e7dd3d9dc49}, {0x0005740013a5e585,0x0006ec9e3c1b8d82,0x00099b6ab2131174,0x0008f1bcb0a2a77c,0x0000c48a3b412f88}}, + {{0x0003e91991724f36,0x000bd9cbd686c791,0x000d4fc1e5eda799,0x000d547db595c763,0x0000b63b80c0c4fe}, {0x000fc697e5fb5166,0x000a70f1c9646ea0,0x000a92ca5737708b,0x00067a3628745f11,0x00001f37958fa869}}, + {{0x000fd610979e6b3b,0x0004e3d407235320,0x00080bacc1d0bd3e,0x0005145ac006fcaa,0x00001d9c60f82002}, {0x0007ed0af780b927,0x000e10a9ce31610e,0x00020b54bf5bf446,0x0006c2d41c011d3c,0x00007f76da189159}}, + {{0x0009b2caa6650728,0x00046fd324ef9af3,0x00027bd3178322fa,0x000aafbd153394c3,0x00001d5f271b129d}, {0x0000c42f48027f5b,0x000bd536e717c72e,0x000369d0faa40cdb,0x0004e6445a657a2d,0x000003bbfc59a7f7}}, + {{0x000d5429b6a42eae,0x00045daf41b97a04,0x0006b0b89fa597e8,0x0003dd6c58ec2772,0x0000d8eb16ae30d4}, {0x000e5e1ec9dcf577,0x0000f97cff8165e1,0x0006e2b22b7a770c,0x0002b6ae6d918f9f,0x0000c277a9b364e8}}, + {{0x000c4180d738ded3,0x0000b0de572946a8,0x000a816756f1a5bb,0x0003d4c10230b98b,0x00002c6f30c412b3}, {0x000129dd8fffb620,0x0007b459bf057559,0x0003b67766a281b4,0x00073a77c1bd3afa,0x0000709b38078299}}, + {{0x000e0c1da36cb47f,0x000a2e0210f00875,0x0003787c8fdf5b7c,0x00041e8e0c7e4d3a,0x0000043f5271b1c7}, {0x0001b006d74d72d5,0x0002e8b45ba976df,0x0006b797a0514df7,0x000c395ecf7c3e0a,0x0000e30b2862deaa}}, + {{0x000b232a3326505c,0x00022e1d41bf8c26,0x000e32afa38d6927,0x000a864459453eff,0x0000e8143ae3cb3e}, {0x000c1fa7e6ab6665,0x000fd2286264932e,0x00036f8ed6cd2d22,0x0005baf59a46fe67,0x00000bf0d00eeca8}}, + {{0x0008f7d605238a52,0x0002248496ab15c7,0x00010acc1e9d8784,0x0004e2afcf75d0d2,0x0000948f2297c8c1}, {0x000d76de8daf0cb3,0x0004703be800e81f,0x00078d30cd02d11e,0x0009cadc4df35187,0x0000482bc96c6513}}, + {{0x0005852877a21ec5,0x0006bf537a940b82,0x000a9a6a2300414a,0x000bffef1cba4021,0x00000824eeec6943}, {0x000fcecf83cba5d5,0x000843b4f3c0a0db,0x000f24dd7f953814,0x0009dd1174416248,0x0000322d64e34fb0}}, + {{0x000cf278a448bbc2,0x000fa85251da56b6,0x000e79b240ca898d,0x0001a77082cad836,0x0000e7b9ed33a8e5}, {0x000318a43e1c8025,0x00037bf8689ddc7d,0x000071b1a4750e52,0x000dc14887a072f0,0x00002090f87d14bf}}, + {{0x00073843d9325f3b,0x00004371cb845744,0x0001e36c5a9bef2d,0x000f71c7d2188ba6,0x0000bd6a7d87602d}, {0x000a9028f61bc0b8,0x000ceed0b6a1ba3a,0x0006e8298f49085e,0x00001d0bc625d6ae,0x000032b0b1e22e9c}}, + {{0x000f2196196bc6e2,0x000bcf097efd5beb,0x00087293a0e66736,0x000cddf128f3b8ea,0x0000998e4058addf}, {0x00031b85d16c9619,0x00009418f05655cc,0x0009fe81987a434e,0x0000c59e94aaccdc,0x00004a486c235649}}, + {{0x000c447f1f0ced18,0x00031492dd2ba337,0x000a08efa800cc79,0x00041dcb93151dbe,0x000020cf3f95e0a7}, {0x00082dc1c0f7d133,0x000054dde6caff19,0x000f96ee3ef92196,0x0000c6ead7d97245,0x000019c8dbe59dea}}, + {{0x000385bde259ec84,0x0009f0f67b0d1ff2,0x000661cfff6b0836,0x000f5bc4cc65b006,0x000067e635914230}, {0x0008c802dbed3d35,0x0002a1920da6ce46,0x00037479f7b98426,0x000de0e4d2574215,0x0000c8aa88cd7bb8}}, + {{0x00038717b82b99b6,0x000ce70eb624d3ea,0x00095d46675922d4,0x0003462f66ec543b,0x00006e673cd1ee1e}, {0x00067c4b5f2b89a4,0x0005e90e5cd36afe,0x0000a2ada3de9c1e,0x00023b4c278bb631,0x000020fa3844bdb3}}, +}, +{/* digit=12 [{1,2,3,..,}]*([2^60]*G) */ + {{0x00096796424c49b9,0x0007d7c241c9646f,0x000f68b49f888dfe,0x000f20512d4b9324,0x0000a6b62d93571d}, {0x000b26d179483cb7,0x00022511fae281b4,0x0003aa51f666f963,0x000d166281b3e4d5,0x0000f96a765ef3db}}, + {{0x000d37c051af62b9,0x000a7bf944968553,0x000d59aa1e9a998e,0x00081350844f9fb0,0x000083fd55976afb}, {0x000c0ca65d698049,0x000ddea5ff2d9670,0x000d8623b732b22d,0x00078247640ba95f,0x0000f61916436351}}, + {{0x000b4e0bdefdd4f1,0x0005e366e401f167,0x0003bbec06995846,0x000c214aa368aba7,0x000021487098b240}, {0x000323318969006d,0x000e11fe53d1378c,0x0000c4361cb4d73c,0x00012a8f50a80e13,0x000067f59524ef52}}, + {{0x00081088cad38c0b,0x000fbbd68ae2332f,0x0008e27a3471b7e8,0x000b0ca6ac3fb20d,0x000054660dbc36b4}, {0x0001e11a6fd8de44,0x000a637799ef123a,0x0006ac17c44dbffe,0x000cef0540b977ce,0x000095173a8ef60a}}, + {{0x00037434573eab0b,0x000b21ac6031eb44,0x000dd9afd11570df,0x00023147d9b45b44,0x00008066addd2067}, {0x0002ad8f8a3f0b44,0x0009a0ace2a215f9,0x000b38b809e0e489,0x0000527dcd0aadfa,0x00006506ae957020}}, + {{0x00069f78fca399da,0x00016207bb63429a,0x00088f582fe9e27d,0x000f6e4c655ed687,0x0000426d7494db75}, {0x0005c02ca81c66da,0x00070531d4251869,0x000ff48ba84fb8d2,0x0002469a3a8956de,0x0000f1d0d57166d2}}, + {{0x0009565352c4b5c2,0x0001390bc3e25a05,0x0006f9f5f4926153,0x000a9b609f7521f6,0x0000baef6bfe70a4}, {0x000fa6509ed3561b,0x0002e84b230ce7e6,0x0004cdc691137023,0x0004157151659bd0,0x0000db83c64a007d}}, + {{0x000284d391c2a82a,0x0002758308e89ebb,0x000f1edcabcdd486,0x0006c7606f16ec83,0x000013e2c38095dc}, {0x00056f04a057a87a,0x000006b48f982ab7,0x000651c44a876550,0x000e01a252face68,0x000052b540c81765}}, + {{0x000a1a85ca37ff0e,0x000bed2f1c8fcb35,0x000a26112e1a04f1,0x00077d438816ce15,0x0000206a111e95b1}, {0x000b6048a4241497,0x000704752cfb3c10,0x000f1dbb8c6a3f56,0x000dfb4f16a37a47,0x0000c372f9b431a3}}, + {{0x00005b5c20b4d2a0,0x00050c662a67122d,0x000ffc9e9ff659cf,0x000683ed57c128e8,0x0000fbb15859e987}, {0x0000df247319a2b3,0x000a074be470add7,0x000a7b3074b98bab,0x000f30c03d747356,0x000042e696e6efeb}}, + {{0x00048f7864ac537c,0x0008e6940d3df84b,0x00074c7ae0471340,0x000033414db22d61,0x000073a1c444c213}, {0x0004ea5ffdd93ec9,0x0006d102783e18ac,0x000c3e83f724fc75,0x000bf50fe13fcc91,0x00002a8c2c9808f0}}, + {{0x00022fd8f67f6de6,0x0003786931777f2e,0x0003eca95ab01883,0x000f2ac66d1db686,0x0000bb7732b91b5e}, {0x00027c6915f80ced,0x00018f90efd84fa9,0x0006b48ad6fa1d6d,0x000428abd75de845,0x00002cb507b545b6}}, + {{0x000f82ae255d7eca,0x00030460e204a72c,0x0005b0a4452025c2,0x000ed970ae542d7d,0x000085143113305a}, {0x00015f5a14bbfe81,0x0006285365fe9583,0x000d950403f36182,0x000da2b2b3a36b66,0x00002c7b3348cf4e}}, + {{0x000b4d1e744119d4,0x0009429a71e7a545,0x00017fcbf4c93b16,0x000d84edbb908c61,0x0000dc97320f35a3}, {0x0004f856bf88105f,0x000d2b51bc1f94c0,0x000013af3452e1bc,0x000e231c41ff50b3,0x000007af446124d7}}, + {{0x000e57ca3d24f6a1,0x0007e345a763bdb9,0x000cfbb5f8a8246d,0x0004db63bd2a6d98,0x0000dd8e85e96ed0}, {0x000da42c01f420b6,0x000304407bc776f2,0x000f548f57ef0547,0x00064a1e98ba7faf,0x0000b7afbef5d30b}}, + {{0x0002fc516a0d2bb2,0x000bfa6234994f92,0x000c62c8b0d5cc16,0x00067f7241cf3a57,0x0000f5e69621d1b6}, {0x000c70bf5a01797f,0x000c709561925c15,0x0001fdb523d20b44,0x000f7a14911b3707,0x0000648f9177d6f0}}, +}, +{/* digit=13 [{1,2,3,..,}]*([2^65]*G) */ + {{0x000c8b8fac61d9a1,0x0002d3c6fe8a027c,0x000bff5037d25e06,0x0002f7d08805bfe5,0x00003271e6c7ff63}, {0x000a6c0232f76a55,0x000d201ef42655dc,0x0000a51788957c32,0x0001739e728bcba1,0x0000ea60412062c5}}, + {{0x000462bb4d8bc50a,0x0006091957709ad5,0x000412a68181c0b1,0x00048c4bd4fe1c78,0x0000e0341bd60dff}, {0x00045cf7003e8666,0x000a2a24a41bb6bc,0x0004c24c2f11a6de,0x000b67f407151ad0,0x00002c9d27e3a5b7}}, + {{0x0005719a8afd30bb,0x0007da826dce3286,0x000a8fbe08679832,0x000ad32f04e891c4,0x0000b6b6e1c9bf56}, {0x0005b11471f1ff0f,0x0008ce15baf00a69,0x00096c43ed76c338,0x000157118edb95be,0x00002beaaf580794}}, + {{0x000b12e523b8bf60,0x000b8f910c1b0a50,0x0001675888009eb5,0x000abdf535af824a,0x0000f835f9cfb2a2}, {0x00029312afceb620,0x000a169d383ff59b,0x000ac02b0c797df2,0x0000caeb3f5fb066,0x000029d4c6fdaa2d}}, + {{0x000ebd1e0a1b12ac,0x000cb70ba95f87a7,0x0002ae9cb1e4ef88,0x000402cc33345cdc,0x0000ecf1276c1cc8}, {0x000012e1b39b80f3,0x000d05c33ba4687c,0x0009661c2fd90d0a,0x00029e73ef5a675c,0x000068fc88f10174}}, + {{0x00026052b7ce5421,0x00096472bde1b822,0x000d2f4dae6d4ce9,0x000b2e43e16ebe09,0x000080ff42e63b92}, {0x000cc022c34a1c65,0x0008f22c46c2c59b,0x00014a8a23803d6f,0x000b27c8aff74f5c,0x00005aebf8060a08}}, + {{0x000970e2fdd23cc0,0x000c5682e971b956,0x000e86ebcb80288b,0x000939e6e6d91e9a,0x0000564c83f8c9f1}, {0x00032a239560368e,0x000a249c28e25519,0x000a158c3e893752,0x0002622b03cee5a6,0x000012d656be4964}}, + {{0x0002010f5b343bcf,0x000a02f142fe58af,0x0005f4bdf0f2e400,0x000aa84483bfdea8,0x00000b1d093f3bfe}, {0x0001b95c70816030,0x00093dba10972ea0,0x00038f3a6e943e4c,0x00063647be92adb4,0x00000bb7742e5bf6}}, + {{0x00014576be5f7de2,0x0008a2263c9e4ed7,0x000cacb36d93006f,0x0008abc073694cca,0x0000ff7a5b45ae11}, {0x00053f1cd871236b,0x000d12aa6d523cce,0x00098d76df156a39,0x000d38ecc5f271b1,0x0000c615b7031383}}, + {{0x0004fb486df2a61b,0x00073cf7b4a2137a,0x000d042ffa1ed9c0,0x0005ec02e460e27b,0x00007f5e2fb0f62f}, {0x000ec6bcc2423b79,0x000f2a63eea77aa6,0x00050a6e175ce0a7,0x000c9ed7a45fb1f2,0x00003bc919d753cd}}, + {{0x0000af231f63950e,0x000034caa2c96793,0x000ac7e62a77797c,0x000aeb726e80ee27,0x00001e6e62738b28}, {0x00078b0b3c9fef02,0x00004d5f90be6361,0x000ce51cfaf7752e,0x000e1f74ecaf18ee,0x0000864d0edea806}}, + {{0x000ccaaddce33450,0x0007012a4350ec2f,0x000598bdc2a6811b,0x00012896760ff1ac,0x000054d652ad1bf4}, {0x00051d492a210056,0x0000d3110fdf0a11,0x00060100fad7f397,0x0003622c95928c19,0x0000c91c825dbf03}}, + {{0x0005b7799eb6df0e,0x00009386b7791778,0x00017a48e26c3cc5,0x000f30545ed98864,0x0000990b4e4e7d6e}, {0x0006b7e2586abba3,0x000529c96e9a0f45,0x000eb4206239ca6a,0x00090ab327459ce2,0x0000a4c3313d002b}}, + {{0x000125dec3f1dec5,0x0000411178da19e6,0x0004a673807b1f04,0x000dcd893ededa90,0x00005187a5a5bebe}, {0x0004722eb329d415,0x000ea170b391f7d0,0x00099f828f449099,0x00076dad317a69ca,0x00000c3db2b84a49}}, + {{0x000b69b92222f1f5,0x000a1cf7ae703806,0x0005217ee5a2459c,0x0005ac1789f69ca8,0x0000f232b5f33dc8}, {0x0003ec548e9e5167,0x0006c197eb31660e,0x000fcca23124b4e4,0x00024ea0a0cb13aa,0x0000bd63ba4f2132}}, + {{0x000481b7bfe71786,0x000e05405868b674,0x0008c867d4e1deba,0x0000e9a61b2821c4,0x00009c15b35b13b3}, {0x0001666368710884,0x000cd220b1ff3b4a,0x0003d9f4de5e29f5,0x0006750b82bb3523,0x0000e07633358cdc}}, +}, +{/* digit=14 [{1,2,3,..,}]*([2^70]*G) */ + {{0x000f5c7a3e6fced0,0x0005f45fbdeb0d53,0x000339a70e8cbbdd,0x000b81f85c01df13,0x0000ff71880142ce}, {0x0008774bd70437a2,0x00019a0bda6a4c4e,0x0008bd26e5fb3289,0x000521fcdbebd2f1,0x0000f9526f123a9d}}, + {{0x000305192c4d6840,0x00057612efcd40ce,0x0009cae208b04d72,0x00056cb9dcda366f,0x0000edc4d24f0588}, {0x000e6bf854279005,0x00058c09dfea64f2,0x0009bf26c3de8129,0x0005a9841b448737,0x00000b62c6dbdf13}}, + {{0x000e3b4c72dfe67a,0x0005f0e19fdfd4f8,0x00013bd35c416b0f,0x000b9d78b9098d4c,0x0000c11118ab5b8c}, {0x000a318f00628413,0x000f59f356f4f598,0x000177a0cbfe0602,0x0005374ae3637e30,0x0000409774791136}}, + {{0x000fb5ed005832ae,0x000ab1042e4f0db2,0x00070f8ca5f5efd3,0x0009cbac4ffdc6ed,0x00004645d0c952da}, {0x000f58bc9001d1f8,0x000bce1172059596,0x00098a08452c8f0b,0x0009de7d4aa0d2e3,0x000015bfe3a904f4}}, + {{0x000443f23885e5fd,0x000918433aab97e5,0x000d4e604f72f8f9,0x0003feed00b154e4,0x00000b35e6bb5e17}, {0x000a0489164722d3,0x000b58761ec857b2,0x000a838323e3c665,0x000e3b3bdd13973d,0x0000c8b1a1ea3daf}}, + {{0x000ace654317cac3,0x0009221771b34497,0x000dfe8b8be600ab,0x00010f842e409eb0,0x000086a67d769423}, {0x0008d8d4431cc288,0x0002185dc5242554,0x000c4be32a7cff14,0x0006e0cd60f5a193,0x00003ebd5c95071c}}, + {{0x00080a7b1fd2b0bc,0x00059bec33e8ba3a,0x000743fb39b3ad39,0x0002f9f3868d6179,0x0000fd169fdbdb46}, {0x00099d79ce0a6af4,0x0001a42d3ff8d3b4,0x000c3e1b255dc1cf,0x000473c4fb9e6cc6,0x00007e6961daf69a}}, + {{0x0003acce548b37b2,0x000264d4054954eb,0x000341b4fb38e754,0x0007fa6c3daa517b,0x0000f6928ec890bf}, {0x000b32386ce6c413,0x0004e0adadcd0496,0x000b5faf901be1c5,0x000985904e67e74b,0x0000cbaf679115c9}}, + {{0x000214550ca42470,0x000ae7dd30aa8cd1,0x0008fee24ba1aa47,0x0000e82f81ddf1e5,0x00003452936eec9b}, {0x0003b81243aea965,0x000ec5c3d0e58bdc,0x0009483619a2919a,0x000ccf4ea640ec10,0x0000ac86d5bbe0bc}}, + {{0x000d918c36cf4406,0x00076939719cf892,0x000218b64aed3e83,0x0000dd507b08d2c0,0x0000f1bcbbb2e979}, {0x000d6ed60919b8eb,0x0000dac1f9eb4a84,0x000d5daefd890079,0x0002c5484941aa0d,0x000022fe40b17fd6}}, + {{0x0005ba2157f2db33,0x000f5e28ca9c97e1,0x000b9f454bda2fc8,0x00072e2d050da437,0x0000d57eb575379d}, {0x000eba2fb5ee9973,0x0002b11538cae9b5,0x00032797401648ca,0x000bb702bb76f6f6,0x000038f14b92f3f4}}, + {{0x000226ad7ab9a2d8,0x000cfdfae958524d,0x00051d8c29c00090,0x00062c8ba5f53987,0x0000afcbcddbab82}, {0x0002729e99d043b6,0x000b4ebc943a5739,0x000862935ef51263,0x00017b3feace9320,0x000039efc04106c8}}, + {{0x00054b366b4be7ad,0x000db4a37a1e1fe0,0x000d75cd93f25a9d,0x0001b5239ef1ad78,0x00007b58f4a2062c}, {0x000f9a9ff563436b,0x000938af51e76f74,0x000e97fecf718ff2,0x000c09a234d31315,0x00006a8e2b1d92f1}}, + {{0x0003aa8327720c15,0x00026a092cc8a7f5,0x000746c4d956ca32,0x0003923f03d64a28,0x00001fe1782b6d0d}, {0x00034db3c832c80a,0x000bcda2e3b4d19b,0x000104ccc60dccc5,0x0001fc845dd62e0a,0x00007ab1de2020b2}}, + {{0x000ae0b3893d123d,0x0002e15ee71cb293,0x000a9468bf7b7578,0x0007438aa3c61442,0x0000686123dab15d}, {0x0006891a7ab4116f,0x0007b4e6a4598c61,0x000e5fad76fcd72c,0x00046abc21911077,0x0000b6a20e8604fa}}, + {{0x000be7d341d81dcf,0x000842148379e839,0x000026eadcddb688,0x000c5dea6211a1f7,0x00003b25760e4d1c}, {0x000c8f6a7a73ae65,0x000e11d5b48340cf,0x000a50ebc83879a5,0x0008fa75acb1ed41,0x00009a60cc88c07d}}, +}, +{/* digit=15 [{1,2,3,..,}]*([2^75]*G) */ + {{0x00030b665c7322db,0x000103c1b3fb4395,0x00072f685cf12cc0,0x00091d170b018601,0x0000915ee22cb583}, {0x000f03ba317db248,0x000897b8ffc49afd,0x000d3d05087dec65,0x0000e6ff46597be4,0x00000a1c1ed80650}}, + {{0x000a7b397acf4ec2,0x00003ea8b6403e22,0x0009692850426c40,0x0006703e3295a64e,0x00002aabc59c6a45}, {0x000714c5f5942bc4,0x000dba3182edb929,0x0004152ba9a6168b,0x000367e216a66510,0x00006908d03f6926}}, + {{0x0008ac6c2babcc13,0x0008ce81ae8d52cb,0x000f1a7114748d44,0x000ac42844f03f80,0x0000db784b328df4}, {0x0008f122df1fe365,0x0009a33cc7c0ad91,0x0005e5555e40f25b,0x0006f8f700d0e73b,0x0000c28fa0900332}}, + {{0x000d8745a1251fb6,0x0008672725c7a9f5,0x000ffe89e967747a,0x00035db95c33e531,0x000009d211049649}, {0x0006ca82fe122271,0x0005f426469dcafd,0x00093183caf9b5b9,0x000fef1e9ee04c56,0x0000084a333d8146}}, + {{0x000b1c8321a518cb,0x0005dbce226f56da,0x000acb9fafd4439a,0x00071b30b30d194f,0x00005052f3125835}, {0x000641012afd4761,0x0001f3fe624a1442,0x0001c92e6d02e417,0x000b52ec394f6553,0x00006d4bf5ae4bc0}}, + {{0x000b88210395755c,0x00039ec1df80ce06,0x000f55e96117ce63,0x000d1e3efae513ef,0x0000f36cba7bd7fe}, {0x000eca9a40ebf884,0x000f73d37e127340,0x000bbf9ffe6ec1bc,0x00005e8a51b64e86,0x0000e0dbb58cb40e}}, + {{0x000d0bf5f8b8a84c,0x0005c66f3ede120a,0x0000ebc2cbfa00f3,0x000e3ae8c6064ec3,0x000039e40b8e3001}, {0x000f7cde7b1cbab5,0x0006b4a562849614,0x000857a19cd4420c,0x0006cb3446a8f316,0x000019b93b236f70}}, + {{0x0009933aed1d1f71,0x0003405630909664,0x0002e39cf566eaff,0x000124245057f0ad,0x000048ff65b2f832}, {0x00089d4cf94cf0dc,0x0003920c58b3042e,0x00061aa0d319bec8,0x0007ac6a26762653,0x000086fa3034fbc8}}, + {{0x000e5b80863b6647,0x000accabdb533805,0x000feff918be7ac6,0x0002062f7d70505d,0x0000dea8bd105896}, {0x0005a3b410e3c4e4,0x00097c603ebf2800,0x000ec15d224a4f0e,0x00041d8c4fd5ae4a,0x0000dc253f84f966}}, + {{0x0007b9c7ea2ee345,0x000bb9cc3a71359d,0x0001ea37a3fd0d94,0x000c876b53c31c3a,0x000033425fb1f818}, {0x00099c3810156e0e,0x000350c164487cd1,0x0006425420ea020e,0x0005ea0557ba094a,0x0000657e7e87465f}}, + {{0x0003ad1fbc824398,0x000b7896e9fdea72,0x0001c33ffc726868,0x000231597c913c51,0x0000a3fa8e362114}, {0x0000e5608445b3e7,0x000488d098d32a6c,0x000ea77d42c4cd88,0x000f710bf51faf2f,0x000009f208aeb1c4}}, + {{0x000d2ab5c8b06d5c,0x00023e4eac46fc83,0x0006f7779b1a785a,0x000504f99315bc84,0x0000f31d817af9ea}, {0x000fe6a15d7dc85d,0x0003e4016b332391,0x0001cb4c72f132b0,0x0005a059547fe318,0x0000b66d8a735015}}, + {{0x0004843f45aac50f,0x000da1eaaad05b9e,0x00054eea0c31e042,0x000a567e8c0b345a,0x00000437b95862c7}, {0x0001ce8fe1d348b4,0x0008a3786432e453,0x000510d38e148937,0x000b0095e19c4a3f,0x0000df3f0170e348}}, + {{0x0000e8b593d070f7,0x0005e255625d59cd,0x0007a03994375751,0x000eeae51fdda75b,0x0000bb6e6b09dec1}, {0x000b662334c0922f,0x000e1cf41b79729b,0x000f324023df631d,0x000c8711abf3c578,0x0000cb4666d8cd33}}, + {{0x000b445735e843cc,0x000cd7379134b805,0x000ab9f872a8e890,0x0002b62bc7c10c52,0x0000bb5e1ed780a9}, {0x000a2d9dc2c4efe8,0x000e2e8cc7bdd6ad,0x000418a74fccf504,0x00080be50115acb2,0x0000dd90e07452bd}}, + {{0x000d7e1adc1696fc,0x00024acd72d06b66,0x0001b743598ebe59,0x0005eba5f24550cc,0x0000e23139474b9a}, {0x00022d4db067df91,0x0005baff9b00234a,0x00000c9c198dda09,0x0006950bbc75a061,0x0000560a9c8a39cf}}, +}, +{/* digit=16 [{1,2,3,..,}]*([2^80]*G) */ + {{0x0000f1cf1c367cab,0x000b190fbc7de405,0x000a110329bc85a9,0x0003a8f373c4a2e1,0x000064232b85d039}, {0x0007eb0167dad297,0x000124b78ab2f557,0x00029348b1604f30,0x0003419baa94afe8,0x00007fbd8ddb1654}}, + {{0x0004802fcf0a7fd8,0x0008d488b01e31f1,0x00052b49842fd078,0x000200f1d78d6d99,0x0000eb572d987ac5}, {0x000a44c4d194a88b,0x00090a017e66e0a2,0x00088aefcd2b63fd,0x000a10c8efc6c8f8,0x000076f6bdafa881}}, + {{0x000932c68af43eec,0x000db03d00bda2f7,0x000b061f55502468,0x0005ad25dc978f2f,0x00009a1904ae8c81}, {0x000538d470c56a4f,0x000e293d8cedd3af,0x000108ef3159abc5,0x0001773a37245f20,0x0000a17081f123f7}}, + {{0x000a9b2b4b4b67c8,0x0000680206041fe2,0x0008058d8c1d10df,0x000fbb1d64abfcbc,0x0000943b9b2f12a0}, {0x000d9143b3def048,0x0001cce775ff90ee,0x000bc904085ab3aa,0x000dfae05fd4ca7b,0x0000b34a56562c75}}, + {{0x000acf88e2f7d902,0x000757be32cd5c18,0x000eb5ee9fdbf33d,0x000114ea085cd7d2,0x0000d702cfbd3201}, {0x000ebdb85c88ce89,0x000b8e01d617b6e0,0x0007333ac23a3ce3,0x000b6aa041618e56,0x0000dd0fd8fa57ed}}, + {{0x000610798fa7aaac,0x00043073aa4eb2b2,0x000d6b19b41209ee,0x000caf31570359f2,0x0000be6868dbc577}, {0x0004bdc32c04dd3e,0x000defeee397186c,0x00086c0cfa6c35fa,0x000fe1d4a1b312f0,0x00000a5ccc7b9461}}, + {{0x000f3a36fa6110cc,0x00013b93561f516f,0x00057522b74fb1eb,0x000dc5ac0c904784,0x0000fd321052bb8b}, {0x00084a2cc80ad571,0x000576a9b6372d68,0x000f4e8cd7c27fc3,0x0002f02461baedad,0x0000d56251a71724}}, + {{0x00011a9431dd80e8,0x0009f3306cd9b840,0x000b3b730eb7c7cc,0x0003d2a0fadd29d1,0x00003858b5c7e37b}, {0x000d193b6251d5c7,0x0002a352d952bf4c,0x000fbc0511cca1fd,0x000636566157a490,0x0000990a638f9b98}}, + {{0x00081a321175ec17,0x00057e018109892c,0x0008be3169159a50,0x0002e5570130532d,0x00006060c21b26fa}, {0x0002dfc6b6f0f228,0x00044a01a671074d,0x00070bd8e9725fc6,0x0003fdbf6679b927,0x0000fe6605057c9b}}, + {{0x0001154b6e00a84b,0x000174890e60ce71,0x00060988fd9fe7e4,0x000004210bc6c345,0x0000dc2ef531859b}, {0x000d868d5c890ee1,0x0006019c47dcdcf0,0x000714567893115e,0x000a53d97966fbee,0x000017813356c85a}}, + {{0x00030cc732043499,0x000d04a0679c71d5,0x00061e031c9df473,0x0005fe3572f00142,0x0000786b71fb2f13}, {0x00005fa6b64e56fd,0x000835219c46ed65,0x000f53d71e2fb48e,0x0004053dbec45bed,0x00007d782f39589f}}, + {{0x000b66b73ed09660,0x00082886032b350f,0x000390493968e4b0,0x000dbe5a16ed6e88,0x0000a83ce84a121e}, {0x000fc10a3d9cda09,0x000505ce67fb7c86,0x00037dbf65a40a6d,0x000282dcb8cda7f9,0x00005b44768f51f6}}, + {{0x0003c8a446cd7f44,0x000b506d52a60651,0x00023866c158c423,0x0008ee31503261c4,0x0000b96f570d3c14}, {0x0009cc7239a85237,0x000625ac4b8b5daf,0x0004bf7f6611b597,0x0004436e3981db72,0x0000e7d0f78d7afc}}, + {{0x000101ed6fc38377,0x000eee1b3a09984f,0x000942626340bf99,0x0006184b96036f06,0x0000bc878ab7c7da}, {0x00016441c6fb0358,0x000e2182fe9fb374,0x000c7a67ac65bd5a,0x000d7c9b9c2fb86c,0x0000d1b19afdce68}}, + {{0x000b80c8ce59954f,0x000388222ac03d1a,0x000f878dd742c5a9,0x000a984ddacbf894,0x0000c085118d7d54}, {0x0001dfa21e38ec27,0x000aa6f4ff7ffb0f,0x000a888fe1c7b59c,0x000889288752397e,0x000005d270d210dc}}, + {{0x000692a87dec0e16,0x000d97b39d00e5aa,0x000cfa0b5010ded8,0x000a281b1b80c854,0x00006beb87700f8e}, {0x000f5313476cd0e8,0x0005308d394950d7,0x000479fc6a63d0e6,0x0007419a09eea953,0x00002ae98927499e}}, +}, +{/* digit=17 [{1,2,3,..,}]*([2^85]*G) */ + {{0x000b9105ca7d8669,0x0001aadb3b34ab58,0x000eac0bc582967e,0x000af4f9ae4447cc,0x000019c667d0bf56}, {0x00017b160f5dcd7b,0x000f2dcaadbc9aec,0x0003467f5ec697b9,0x00032e5b98f34146,0x0000187f1f859671}}, + {{0x000dcb6ec7fae9f1,0x0004dfb66e5aeb5d,0x000445d52995f271,0x000620cee95d8e69,0x0000b6c2d4619e27}, {0x0001c318129d7161,0x0000f958c1aa3262,0x000f4af63b03909f,0x000df67c468ef91a,0x000062c42a00ba5c}}, + {{0x0005eef9c053df72,0x00079300ea6fe8cb,0x00049cffb8de25b3,0x0009bbbb03fa92c8,0x000042e43a808416}, {0x00051f4dd6f958ec,0x000f34445a8de4fa,0x0000d89496925a77,0x00039026e72a50e9,0x000066648e3eb1f6}}, + {{0x00096f31711ebec8,0x000f4e98fdc46c3b,0x000b4411f2da40f1,0x000bb6399774d357,0x00007c8bdf495b65}, {0x00089e3c2eef12d5,0x000aec7471f3da3a,0x00012c594de95bb9,0x00056b100f225bd8,0x00004907c5d7b75a}}, + {{0x0004d2945c1dd539,0x0007931debb5699e,0x0007f00e0cadc589,0x000a0e4f49fcc7a7,0x00003057bc0373e5}, {0x0007ecd027a4cd18,0x00034614011a2f8b,0x000677c68114734b,0x000f4f67a01db767,0x00009d9be5efe273}}, + {{0x000ee5931fba2393,0x000368bd91d1e0de,0x0001a3c1df47424d,0x00033adf8886f407,0x0000f7d41e8d8192}, {0x00023c2cf6eb9980,0x000f609a287f7086,0x000c9076286bb49a,0x00054b942bb24963,0x0000ef6eea555a96}}, + {{0x0004a2e649d4e574,0x000fd917526e4add,0x000b44ac4cd53a2a,0x00031d8526233020,0x0000028746afaa2c}, {0x000839064291d4c7,0x00017e5ad9095131,0x000185681bf48f15,0x0004425ce57f597b,0x0000c3ac1b0b854d}}, + {{0x0001db6f79588c00,0x0009b55768cca80d,0x00054438afa52fc6,0x000a4f0b4df1ae7f,0x0000cadd1a7f9b46}, {0x000a6b31803dd6fc,0x000495eaae35b40e,0x0002e4e16488e4fa,0x000c97df047d5538,0x00009b5b7e0ef6e0}}, + {{0x00072d0b611c24be,0x000480a8f351c199,0x000cf64211d468e6,0x0004910b7580697b,0x0000c9dd0ef68fbc}, {0x000d2bf956c2e32a,0x00043cddf94e5b59,0x000ee766573dc686,0x0006c45d5e2321bc,0x00007b4f8effe9a0}}, + {{0x0008f17cf41c6e88,0x0009837b925c03cc,0x000d2427cf1f03c2,0x0008e4439c19cc66,0x000023d24bafb6c1}, {0x0009013901f0b4f7,0x000188941c2e32ef,0x00028092e684360f,0x00032e9ebaff522c,0x0000891e4e3956c9}}, + {{0x0008f82d8d38a9b9,0x000057de1391174e,0x000c175dd2e97c60,0x00003535709850a1,0x000069041a0c2ae5}, {0x000533b76a2086b3,0x000ba7c2e8fecbfd,0x0009dfb67d6bba71,0x0005d982d58ee609,0x0000a8b342d364a8}}, + {{0x000bf0502f40d9ab,0x00077c318a4df83c,0x0009c26744681c46,0x00092de85756180e,0x0000e79d046c8470}, {0x000480a78bd01e0c,0x0003b2a51db9af1e,0x000afbab66dd359e,0x000198a2ce3821e3,0x00005cee5b6d7733}}, + {{0x000d8fc3b922bf8a,0x000fac29b133671e,0x0006e99c4e4d8c09,0x000eb9e7eb12393b,0x0000ff3974d2793b}, {0x00094052c18df9b0,0x0003910071390374,0x0007a0b95c5c3a29,0x00096b6a77234fe3,0x00002c29a21b661c}}, + {{0x000fe2e34d74e31b,0x000f8bf79ab65a52,0x000feeb8fa352c30,0x000304e7ff6c5aab,0x0000fbe8ff0a5c97}, {0x0001ce6a79046089,0x000a34fca249d608,0x000e5e2001f812f3,0x000ee80b24bc9ab9,0x00001022c67c8012}}, + {{0x000e7d7cc5f43941,0x000c3536e142184d,0x0004aa60ab5551b5,0x0001d51e89b212d3,0x00004a96feb05005}, {0x000ef740d12bb0b3,0x000030b9677e4e21,0x000f7731dc522f02,0x000d315b12e4672d,0x00009f80382ab326}}, + {{0x00038b67c4a658ad,0x000870e72182c127,0x00098e44fb3c4763,0x00085e6b77be4687,0x0000c047df2e7a7f}, {0x000d4c55e59d92d3,0x0005b8e64d8d2439,0x000ca9b16cedca47,0x000dfe7724cd0d87,0x00005e4fd59d5540}}, +}, +{/* digit=18 [{1,2,3,..,}]*([2^90]*G) */ + {{0x000344f3a29467a3,0x0009951eba6d9894,0x000e5c2f2de81e94,0x0007b3aaea066ba5,0x0000fc8a61438c8c}, {0x000f88f06d0de9fa,0x00049b75ce0a7adf,0x000bc87d5bbc11cf,0x000de1ffbb7accfb,0x00001458e271badf}}, + {{0x0003668e039c2560,0x000b7c17fd5d1cb4,0x000aa062b5f26fb8,0x000f04eee426af79,0x000072002d0d78fb}, {0x000a237e84fb7e3e,0x00002c82133d4c9c,0x0007e4181b401d8a,0x000151caa525926d,0x0000943083453dbb}}, + {{0x000ad1e6ee7c983a,0x000c141328f52f5f,0x00078d5f7eb0f9d7,0x00026efba68b441d,0x000006b3b9ed5bc7}, {0x0000255593e1ff1d,0x000d0fbec115a255,0x000a8f046552dd43,0x0001325c48a7abbb,0x00004fc56a47d0bf}}, + {{0x000da31be24319a2,0x000bc095a8e7f92d,0x00078218503f7d28,0x000dbc852fe84098,0x000076ddafe49c24}, {0x00054961d7a64eb7,0x00090f1dbe4280cd,0x00038d2d5e436088,0x000035bf81a87784,0x0000e4d52a8f5169}}, + {{0x0001cefba04b5d1d,0x0006524c735262f2,0x000c6171f9a44270,0x0006afef07966c33,0x0000b7ba891ee081}, {0x000ea59033745a93,0x000090a78f67306f,0x000251bf92aacf7e,0x00008685aa3883ad,0x000045aede956bd7}}, + {{0x000d5b11d59715df,0x0001e788983e19e3,0x000f1f248c7eaa76,0x000d82f5a730b0ab,0x0000bab8085eae3f}, {0x0000d2153765b2f5,0x0003aa127f3d65e5,0x0007b1b10bdd4e08,0x000fd34cf3c07439,0x00009f8090d01b59}}, + {{0x000e17d98119f103,0x000d188c36a6dc1d,0x0008e23df74353c5,0x000592e4aaf33a3d,0x00001e075c0a8baf}, {0x000a03a46d1ca3c2,0x000c27b660c70f7c,0x000fe2e5999c5e3a,0x00000550d0241388,0x0000e9a6be14a7ec}}, + {{0x000fd9d615faa8f2,0x0000768554ed7b15,0x000a448828fa1eb4,0x000f325bb4447e7a,0x0000bb2d0d1229ff}, {0x0002a646caa6d2f2,0x000e02e7351b075e,0x000506c628eb879d,0x0004dc9cd5624e9a,0x000018eaef0c87e2}}, + {{0x0009695241fbd6f3,0x000fd81c1223ac44,0x0006aac6f67c9b16,0x000720e6868f21b5,0x00004bd8fa428bcb}, {0x000bd33b6691c76d,0x0005681a797306b6,0x0004078db6c92476,0x0001cb9a12444ca5,0x000002e91aa3d105}}, + {{0x000684744ddfa350,0x0005dab3f74737e5,0x000e96cf49ccfc5c,0x000b8f9ac1df3f1e,0x0000c0571a13b480}, {0x000b3d54b3a7b3cd,0x00088dcdbb992fbe,0x000415b3a35c0366,0x000d9982a0f5dcb2,0x000057759b51413e}}, + {{0x00079c00b33d3f8b,0x0005c064e4090773,0x00029c8f6421883c,0x0000c77d0873d76c,0x0000fa433a48274c}, {0x000778f23a5891e0,0x000535e2de0456dc,0x000b517ced663bf6,0x0006c2488fdb485d,0x00000bba55e19b22}}, + {{0x00047d83d30a2c5c,0x000e378a81dc1fe6,0x0001a4a9b0857f77,0x0003f451d5a33413,0x00000a94af9e9d39}, {0x0005c0bdaa6ec1a9,0x0002f8d2d7edbc3a,0x000614797ba9fe49,0x0005332b4335b4bb,0x000091c4d6902f83}}, + {{0x000eee78a058fb62,0x000cdb09121aedbb,0x0004dddceb9d19dd,0x000bc4841bb45bd3,0x0000dbc80b920964}, {0x000137d1d6cb654b,0x000a983d01c54ed9,0x00028e22e1b9016d,0x00046aafc501bc65,0x00002d2f8821cad6}}, + {{0x0008c28d2f01cb3a,0x0003375db0b15325,0x0007d0db493d6eaa,0x000492a19a2b0de8,0x00001e48f0478fe8}, {0x000faf6c508b23ac,0x000975d53549f747,0x000f9b838f137571,0x000cf4df5e58e2fc,0x00007186cef67fd3}}, + {{0x000fb2f286bad396,0x00033dcad1e25e76,0x000c7e904bad9efe,0x0005a500e75190ed,0x0000a6f063e6fecb}, {0x000ed85aed8acc3a,0x000bcd20af6c5150,0x00069dbfab56ccfb,0x0000a8de0d1e982c,0x0000bf5628b1c7e1}}, + {{0x00068cee978a1d35,0x00032ab92d0477b8,0x000a5b862e3a68b3,0x00041d0102979487,0x0000f0606c38a61d}, {0x000be276f9326f11,0x0004b6fe3c2e2814,0x000df73512f521c1,0x000e4407464d7dac,0x00000f5f9d3877f7}}, +}, +{/* digit=19 [{1,2,3,..,}]*([2^95]*G) */ + {{0x0001244c5f95cd80,0x0000f4ab95f4b06b,0x000e5836dda8c8af,0x000ffc1bae59c2b9,0x00007d51e7e3acff}, {0x0005e6ac2ccbcda6,0x000f2528c3e001e1,0x0009fead43bc1923,0x000710e3324577a4,0x00001a1b8848aa7a}}, + {{0x000ee31b0e63d348,0x000229e54fab4fe7,0x000e7b5a4f460057,0x00083140493334d5,0x0000589fb9286d54}, {0x000f5cc6583553ae,0x000a025649e5aa70,0x0000446520879094,0x000c4eec90450710,0x0000bb0696de2541}}, + {{0x0005247d95ea1682,0x000a0970764a172a,0x0009781691758fad,0x00001b8c803a511d,0x000099cfe2efe77e}, {0x0001e17b0a98927c,0x000060014495652a,0x00075b56a2e26e1d,0x000f94bae0af9f71,0x00002e22a81964b9}}, + {{0x0001a3ea2dee7a63,0x000c434b2284758c,0x000aba6addcde2f3,0x0000a77ba445d24e,0x00005aaf668a6cee}, {0x00004a9e5aa049a6,0x000d31103e847e0b,0x000afecc3e74083a,0x000f7a5eb183ce40,0x0000b89dea04a043}}, + {{0x000b1eda4f7e665e,0x0009c23df8e7afbf,0x00012c2f4403cce6,0x000c33d49cc83f13,0x00001cc2367571a9}, {0x000a6c0db92faac1,0x000ddc3befe17ab6,0x0003a0f36acd15e0,0x000e096f8ed98858,0x0000821de7715f9b}}, + {{0x0000e0399375235e,0x0006d9917970b99f,0x0004ec0677614c84,0x0005201ec93ce952,0x000040e7bf97b122}, {0x0000631ee4c47744,0x0009fb04914cb567,0x0009dd2266f03847,0x0001f8896e9429dc,0x00003489b6ccc57c}}, + {{0x00022a5c5f264649,0x000b1442809a7b97,0x000644810ca4c3df,0x000f81ed10986723,0x0000e495172cc924}, {0x0006968a2c5bc14a,0x000ec8de6b7aef4a,0x000a2cbb5750eac4,0x000445ae01884d52,0x0000c40830b94a5f}}, + {{0x0009d23fe67ba665,0x000043cf2f340e29,0x000fcf9139145076,0x000ddaa45b5ea997,0x0000be00843dbd7d}, {0x0003e05d53ff04d3,0x00032de91ef7358c,0x0009ec1a0bf7ccdc,0x0009977d684dbfb6,0x000067e7cf2b01fd}}, + {{0x000f1076103adf86,0x000c5e8e98108c54,0x000bd3c9b2d813d6,0x000a7651466fa85f,0x00008c65d22a0e1c}, {0x000aa40255f9164e,0x000df1a864b2b81b,0x0002ca1415b34c3e,0x000dea5602209b12,0x00007d7248f685ba}}, + {{0x000d227cc2338fb4,0x000950e2615346ff,0x0001a007689ff6fa,0x0003af7e57077933,0x00003d241c546e1f}, {0x000b97dde9b62a31,0x000490ae30eafdcd,0x000bddf7d6a06e98,0x0003c4b9bf16804f,0x000070471a2e3616}}, + {{0x000e207a6469d438,0x0000af753a85fd23,0x000b5ca72cb9f5f1,0x00078b5e2625d4fb,0x00002e4e54b37b1c}, {0x000ca5378b9e8143,0x0000e25b817a2cd0,0x000cfd965fcd4405,0x000974868f719f30,0x0000164471a0848a}}, + {{0x000a8ae3113655ef,0x000a67b83180ff5b,0x000e0eabefa2c6e2,0x000a962c48271977,0x00009f3c556237fe}, {0x0007022a42581cb1,0x000208f710e3340f,0x0002e5aa8e1de0bc,0x000940de640adef6,0x00006b2389159428}}, + {{0x000738f25f653f59,0x0007a764f6355045,0x00011ffc3e42b8cb,0x0004aa24f89406dc,0x0000959314546b3e}, {0x00049f3c97400525,0x000105ffc48b81c8,0x000f67a492c9cf4c,0x000c621299e52177,0x0000869f6e4100c6}}, + {{0x00019e455950cc3a,0x000bb6b66bb83616,0x000ac6d84c71d665,0x0007e34a034b34af,0x0000987f83385e4c}, {0x00027727a79a6a7a,0x0007426d6c23a074,0x000167e1056e5d01,0x00084dde50b97638,0x0000a6c81f0888aa}}, + {{0x00086f75fe015763,0x000caea51395b841,0x000f3f8d4446e276,0x000142c3c5ef8105,0x0000d7f7df6a4f7f}, {0x000b565f9ef16565,0x00042c414ef67c69,0x00029206087efa42,0x0001ae9b7e620d3d,0x00000b1de34beec2}}, + {{0x000f3b7b0dc85957,0x00082f1d9f2e0ca1,0x000dd82a727de460,0x000447aaf3bf39ba,0x00009356a79d5862}, {0x0002345f5f9a0529,0x0008839a42f9c060,0x0004d40fc1a8b0f8,0x000368253eee4284,0x00003b0bfe5de5b6}}, +}, +{/* digit=20 [{1,2,3,..,}]*([2^100]*G) */ + {{0x0003a5dc8de610b8,0x000ae7e223ce0f89,0x000ad6dc5e8c515f,0x00028ef774bfa64e,0x00009d20f96125c7}, {0x0000966098583ce0,0x000493f2a7d77a1e,0x000304d4aa2eedb9,0x00082d1b2820974c,0x0000842e3dac0772}}, + {{0x0000e9d74cd06ff8,0x000f2ca3eeaca101,0x00063aa2b9c17c7d,0x0004fef4c86cd380,0x0000595c4b3f3461}, {0x00000ca990f62ccd,0x0002fa0c3be5a3de,0x0008ce9f5d9bed21,0x000443a886078adf,0x0000db27ce42cd44}}, + {{0x00097befc15aa1ee,0x0007d54b07455a30,0x0009a5f1240d1254,0x000ee57bad470651,0x0000d03f7188439d}, {0x000bb6c4a02c4997,0x000d5ffe71d20794,0x0003adcaff725083,0x00030fbcad75190f,0x0000f68ea1cb3729}}, + {{0x000581d26ee83821,0x0005259d638e9c7c,0x00028ae3dcf17dcc,0x000047de8273abb7,0x0000d1129270821f}, {0x000847750491a746,0x00019de0dfb91149,0x000a435ab687fa76,0x000e3ecc2580227e,0x0000b8bdb94f1ce7}}, + {{0x0006d8af7f91d0f2,0x0001882a57289c80,0x000d767543b61b0f,0x0004c62640032d94,0x000073eb5de67d83}, {0x000abf77b4e4d538,0x000f5e4017772988,0x0005071b3b7ce66b,0x000a981fba6b3271,0x00002413c252d3a1}}, + {{0x0007b7e3cc8ac855,0x00078d02753b7553,0x00037df2f8d725f5,0x00031dad05ff64b7,0x00005fe871346d25}, {0x00004a96ab6b01c8,0x0008fcd9372457ce,0x00086699b69a02a8,0x000231cf82ac35cf,0x0000242d3ae1cb4b}}, + {{0x00035269be47be0e,0x0007eb28fea169c4,0x0006c67e5323b7dd,0x000e461a5538ba3a,0x0000f921d70fd378}, {0x00061fc3c4b880ea,0x000df8940a67f929,0x000f0ff393f6f914,0x000f9c0990eb0afe,0x00006c2921090eef}}, + {{0x00003a553fb2b560,0x00074e057f78b23a,0x000e490d96ce141e,0x000e75796525c389,0x0000bc95725a31a7}, {0x00067911220fd06a,0x000ba08b0bd61ec5,0x000ebeba9716e3a3,0x00066f91cd6bf7e8,0x00007326ca75ee6b}}, + {{0x0003d32343bf1a9e,0x000757d1a6b170b6,0x0006865b48fd3bd2,0x000fa12454879c31,0x0000e959ff7a458e}, {0x000dcf89706dc3f5,0x0001c64e4b2e0461,0x0008843c8737db0e,0x0006f5b92626802f,0x00004498bbcc745e}}, + {{0x000352b5acf6e10e,0x000ccfe652c35341,0x000577a7fc50343f,0x00023c6af3792d18,0x00001a4c6188f168}, {0x000d0cd33425d0a3,0x000d6b7bc47f9b26,0x0006bb20b306399e,0x000054fa792f3370,0x00001219614c8111}}, + {{0x000428cd5f30851d,0x00065a4f66304c1f,0x0005d48a494dfed2,0x0000cd7df53772fc,0x0000d2d5a3063326}, {0x00015bdd44cc7a57,0x000d4d12533a5741,0x0003057c94ba6b20,0x00020dc0e93cb824,0x000094c486a84de3}}, + {{0x000355699f241d77,0x0006901a349d6095,0x00089e491ee4adbd,0x0005459b35bf6aaa,0x0000f0076f4836f7}, {0x00018ba9264da3d1,0x000d52a7a28bd19a,0x00061c9716eb2d2c,0x000a5dbdba941f87,0x0000550518bb3be4}}, + {{0x000d97302f1cd1e1,0x000b0dd212a4c232,0x0009802f7ce87eac,0x000dbd5e4c8c73e6,0x00002ef02902fffd}, {0x000c74e1bcea6e23,0x00040cb92cbb941e,0x0008f9d05d0b5402,0x000aae509fb9d47e,0x0000bf1615a22992}}, + {{0x0007007eafbb1e1a,0x0006475b7a93b249,0x000b68d78d75c9ce,0x0003959558352def,0x00002f26699c23f6}, {0x0001ecfe469b17ae,0x0009072d3ec2eb91,0x000cb113f6254577,0x00098caea47de782,0x0000be4b0872e1fa}}, + {{0x000e675b055cb405,0x000b477b5167bdb8,0x0002fb863898f8e7,0x00001f9cc65651b8,0x00006544814bd88f}, {0x0008e95263a75a91,0x000f0a22fcdab092,0x0003bd37ccfb6836,0x000664551d14db3f,0x0000d3837fbc6ad4}}, + {{0x000c982cf7d62d27,0x000cb3ba815020d3,0x000763f9e1f36e29,0x000006d8ae0bf092,0x0000a527e6b8d3a7}, {0x0009097581a85e38,0x000f5c158be5b4a8,0x0007d726e1f1a520,0x000862798db37d16,0x0000802786e9113e}}, +}, +{/* digit=21 [{1,2,3,..,}]*([2^105]*G) */ + {{0x000149e36f09ab05,0x0009fa10bb5befb2,0x000e2099803f163c,0x000bab8029704506,0x00006f0af006b5a3}, {0x000cfec70880e0de,0x000ede3d913f7af4,0x000ceb4bd7332a66,0x000f5452e6c84a7e,0x0000dc4a79b7c228}}, + {{0x0007dd0c55c44969,0x000695bbabd2c37c,0x000d7f363a6a9635,0x0001decb7e63f2ad,0x0000dce3782be73f}, {0x000a16ab2b91f71a,0x0002bba0163ce1e5,0x000e515ade448982,0x000ecf52759c32f6,0x00005e2f1f92615e}}, + {{0x0009be7abded5516,0x000868b744107451,0x00010d9a903d358b,0x0002b6ed00b10b0e,0x0000392b0b188da5}, {0x000a2980b75c904f,0x000db8f7f96c6744,0x0002cf932c305b0a,0x0006c9142e421d18,0x00006fc5d518e463}}, + {{0x00047c9d64cc78c4,0x000b5b6cb27b7958,0x0008022ab6c50621,0x000a1cc7099bf8df,0x00008f862ec004ed}, {0x00032ede1603c166,0x000efc9a9450d127,0x00029b4fc19a80e0,0x00051582257f54b4,0x00006d3b2c6a5460}}, + {{0x000f87e822e37bef,0x0003353bda4e6ca4,0x000190aeb73f237b,0x0002840747f3a241,0x000006fa370704cf}, {0x000bb6efc621c127,0x0003d0b80ec60a6b,0x000a556f35d624b6,0x0000a7db0724257b,0x0000fa0c354ae2d2}}, + {{0x000fa31e3229d41f,0x0001a4531bd4e921,0x000d38209a929c65,0x0007bc94156027a6,0x00003d69f745bdb9}, {0x000d19a168336319,0x000d73d51be38906,0x000511cd868a34c2,0x0002a83b59583b0e,0x00009ce6bfe8dc13}}, + {{0x000daaaffcdb4631,0x000a24a38b083fac,0x000a9078d658bbc1,0x0005de02a801f8f1,0x0000567bcf97ab85}, {0x00098e03572359bb,0x0004d659e68be084,0x00023807ccf0353e,0x0008a20b86e9c87d,0x0000c08728dd198e}}, + {{0x000b7bc453cadd69,0x00072c0bc1f88de2,0x000abd3af203900a,0x000ffb2cd86e47a6,0x000011cac131502e}, {0x0000242ec965469f,0x000139e0017e2d55,0x0009798850e9f769,0x0001ee733f078f65,0x0000b87d44a3cf75}}, + {{0x0000e4bfc25419a6,0x0002ebff3cfde179,0x000b6e83f3646720,0x000fd268db638625,0x0000cc69f23ccad6}, {0x000e45a6bc68bb94,0x0005e97f73340219,0x0005dc97ce43d79b,0x00049a3d44536846,0x0000b9eea326a0b9}}, + {{0x000c6ba6102d0212,0x00080f4461ea1b96,0x0009f19a8eaafac7,0x000875b4b85c41c4,0x000075c28e4ef538}, {0x0001a9ddd2e54e03,0x0004d605618b3545,0x00036cd246991adb,0x0002162b8b4bcd7b,0x000072a4f8c86f37}}, + {{0x000bd73a6a5da60f,0x000fec4c9ff0c890,0x000536e576f083d9,0x00024304e14d94f0,0x00009ee1edb9aec8}, {0x00041ec8bdcf8e7c,0x00004b041e265712,0x000fff040a5db827,0x000201da0b9a99e3,0x0000aaf21de3c271}}, + {{0x000b2e14f0dd2e8f,0x000e1a377ac7b4e2,0x0007a2198e77e7c4,0x000eb779202c3f0d,0x0000759b80018200}, {0x00026eddcfe314e5,0x000403d5cf99c875,0x0005138b6eb84c52,0x0003f461b52ace51,0x0000aa7ff8c73fca}}, + {{0x00013c3b9791a263,0x000a9dd58b16ff0b,0x000aad2de960022d,0x000619abd55c9257,0x0000baaaaa4230fe}, {0x00023460d881efdb,0x000f96325e2a9a4b,0x0005c18d4506416b,0x0007afe1381e7603,0x00003bb68bfa2781}}, + {{0x000b8bf5116f9379,0x00063126894315bf,0x00019a2c87c64a58,0x000462e1e25cc384,0x0000fd6b0c51335f}, {0x000ba3ce8ee0e0e2,0x0000098c21fa4bf0,0x00066bee06f6fba6,0x00054437d57b39ae,0x000092d513042672}}, + {{0x000105dbab093b30,0x000902839986f451,0x00074a89c012f59b,0x000e978a91580234,0x000048c919c2de03}, {0x000a2b591071cd58,0x0009834970a5c476,0x000b7994b791ed89,0x000ffd09bd9042e1,0x0000eaf517a21057}}, + {{0x000e2a2d551ee106,0x0008127e09a66066,0x00001148d87a8f1d,0x0003fda0d08bab2c,0x0000da8e4f1a24f3}, {0x00017f0cf9a4e718,0x000fbbf5cb19466d,0x00062ecc0ff50200,0x000ac45ccf97d8d0,0x00000c0d9b001d80}}, +}, +{/* digit=22 [{1,2,3,..,}]*([2^110]*G) */ + {{0x0007ceb1bf4581ca,0x00060ca7b1669885,0x0009722ace635e18,0x000006878ddd2265,0x00000903c4cbdb68}, {0x000458948f214029,0x0004296abda2366e,0x00040319031b49c1,0x0003fda29c4b09e0,0x00007197ca4629f4}}, + {{0x000de1cf3480d4af,0x0006cc8acf1a03e2,0x000295a9cf0d8edc,0x00097d023e330368,0x0000add5f69b546a}, {0x00097ad96f8acb1a,0x0004c71bdae28955,0x000dd43f4bddd49d,0x00041976fcd52821,0x00005a4541306191}}, + {{0x000c79f439f29cfa,0x000fadd82a3bfa32,0x000a2c1b17bf321b,0x0006185f127f54ea,0x00008365f2e935e9}, {0x00029024d0ef8dd1,0x000149228c4a852d,0x0005afed3395ce2c,0x0008e3a69f44e821,0x00006c1f898c2745}}, + {{0x000b6bfc360e25a8,0x0004875a1a788ce9,0x0001732f4e642519,0x00057a1dc756a848,0x00003c0440fd432b}, {0x000b3f1d720281f6,0x000e7135e051c670,0x000052be72205910,0x000a397ed14b0edb,0x000097b3d282568e}}, + {{0x0009005dc4532331,0x000a1fac4bcfdef2,0x0003d55acc208c47,0x0002075057a3feac,0x0000723725da02c1}, {0x000c62733eb0fec9,0x000b2b3c63bb9c31,0x0003058384913ccd,0x000d96813e542b07,0x0000d48e72ac10c2}}, + {{0x0004ec4d9bbeb3da,0x000337b2921c5442,0x0006d37c534ceafe,0x0006afbe68022e29,0x000028e0a2bd59f1}, {0x0002dd9bc3f9d739,0x00092af3e1fffdd8,0x000736dc46939a8f,0x0008e6c5cff45c31,0x000010f56430892e}}, + {{0x000b349dfe392607,0x000703549093de09,0x000853b02984612f,0x0007030cede28167,0x0000d809bb499d17}, {0x0006bfb2756c4f00,0x000a93f02b80450b,0x000ad9561c59ff9b,0x0002c73e69545720,0x0000c7cf0be3331e}}, + {{0x0009b9afb3ff9ed0,0x000b17f6515c2e59,0x0004da44928c2e0a,0x0004521cbee4fd47,0x000071279a44f364}, {0x000ff6601fbe8556,0x0007ffda51c497ab,0x000597c0b3ee394e,0x00034ab90385f667,0x0000e9fccc7027ee}}, + {{0x000d419362fb228d,0x000136aa0be4ced2,0x00094b197894637c,0x0001e7aa4fc55eb2,0x00009cbac1dcd4ca}, {0x00074800ccdb6ce3,0x000550dfaa49068b,0x000033b78ca4c556,0x0008a7b835382176,0x00005db7525f5ce9}}, + {{0x000927274fd1997f,0x00010fadeb588cf5,0x000db260c987d203,0x0003bd6647c6c3d4,0x000008bb13c88554}, {0x000eb1056fad695f,0x000d78334cc7566e,0x000dd1db239e17dd,0x0002ff9a97b3bb7d,0x000091199d9b1c5a}}, + {{0x000a437bdc47fe45,0x0002ff3751f0402f,0x00057d48535bd252,0x000cb63c2281b7cf,0x00000083ea5df607}, {0x000e480df6d730de,0x000db1bb06a26f41,0x0001fb48a1164e47,0x000da6f9040c2239,0x000012df252ba23d}}, + {{0x000de9314092ebb4,0x000d028e240c0b89,0x000d2f064f17256b,0x000b148f89a7f393,0x0000f57841f21ed3}, {0x0004405e708d8553,0x0001d3f1c3d04ee1,0x000d7eed5856aae7,0x00027098e5424fbd,0x0000333e4efa3ab4}}, + {{0x0002b5148f835b12,0x00030adaaba8f9cf,0x0007beade4a70faf,0x00003280d2e24fed,0x0000b1e4e6735f04}, {0x000c0b91fb3ceeef,0x00054a54b0b4eadb,0x000d4a188b817b08,0x000e5f24a787257f,0x0000f13304713482}}, + {{0x00012ec4efe42dc3,0x00029664b2bc3120,0x0008f9cb97251b2c,0x000465696c2e6b79,0x0000543376a6b8f3}, {0x000e8416fbfb6a97,0x00039cb91a03337a,0x00002d855e0893a8,0x00073ee3744e9d7b,0x0000e673186906d4}}, + {{0x000996f3ef143db6,0x000dd99378bc9509,0x0008ccc899cf1e82,0x0006be559cd09b0b,0x00004b4a2fcb2cda}, {0x000a8b31bcd55df0,0x000d2507cb37d3bd,0x00010e49bfec4e87,0x0004453d48a85eb6,0x00002fbe1bd1f9cc}}, + {{0x0007adedda492f81,0x000a682972053bc7,0x000931b4cc11a3ae,0x0004bb4e89a3e734,0x00007512e2eaf569}, {0x00049f3177bf8b6c,0x000948c7ff3e5dc3,0x00011145d232ea4b,0x0009c2dc4f9d16f5,0x0000cf109a3f3b37}}, +}, +{/* digit=23 [{1,2,3,..,}]*([2^115]*G) */ + {{0x000857080eb24a90,0x000d488e0cfd60e2,0x00059cdb87bedfb4,0x0000a9721ebbd7c2,0x0000b0da855bc639}, {0x00004dbde314c709,0x000bdc32e8462b4d,0x00062fc9ecdbf1fb,0x000ab6a3833eabb1,0x0000939b48c40dd3}}, + {{0x0002c1f711b0eb9e,0x0007980ab9549689,0x0000792dbb905f2c,0x000125cce26309a2,0x0000c8ac9b3e684e}, {0x000d8b6b40a24474,0x00015fe3fb24486a,0x0008e3b3f60121fc,0x0003941626fccf1a,0x0000e568622aad1f}}, + {{0x000bb22236f4a982,0x0008e66800bb5cfb,0x0009a77740b0c59e,0x0009482ac69a8f5a,0x0000b33f804f6bec}, {0x000929532e6c4662,0x000f2e599c73b372,0x0005c31cc68956d0,0x00084e847a249f15,0x00004d80f0e01ce2}}, + {{0x00046c64a8a3d626,0x000fc47743d25a4b,0x000f7e4338469c4c,0x000848cbb3a13d88,0x00002b23a1061be5}, {0x00096b4a63d1a4c4,0x000a3d183f3ee835,0x000afb01c454e7fe,0x000638243fce6117,0x0000e65e5e65c4c3}}, + {{0x00030e3dc09508b4,0x000f34317655b7e8,0x000690355faf6d2c,0x000ed632606cebdf,0x00008bb92b410c3d}, {0x00054845c7cf8929,0x000945d5f01f65b7,0x000401d69f6cd7ac,0x00087832c30a5996,0x000012686517d921}}, + {{0x00077176add85450,0x000672c49b66e5db,0x000421d771b71cb6,0x000fead856073968,0x00003840fe883e3a}, {0x000dad51ec699775,0x0008e07f6726b391,0x000ca160cae243fb,0x0005f4788ac87be8,0x0000174cced9ce35}}, + {{0x00067f8ff81578e1,0x00008045447d7520,0x00005aa6f7862215,0x000c77b0c22fcf05,0x0000030f0a67bed1}, {0x0009f151f0bd7390,0x0007e6debe8531f2,0x000677e982d7989c,0x000fd55c070e728e,0x0000a817bd306e81}}, + {{0x0007eb6cbc613e57,0x0004d97ea61cc1e1,0x0007eded533131d5,0x00011abf69d39eaf,0x00003c2f4354e6af}, {0x0002493a4a375fa7,0x000c4833c5c24ca5,0x0006e71cf5f06787,0x000666114e091f3e,0x00006451f57fb746}}, + {{0x000e082e1539388e,0x000f959a9c6b01c7,0x0006bacfbfd286f2,0x000e52b458104117,0x0000580f07d1bc3d}, {0x0006f75884d772fe,0x000760bb9d4fdcdb,0x000083011d75c3bb,0x00098cfc6c2e4edb,0x000018789a3ad9c2}}, + {{0x000ab8495fe1347f,0x00087f24503c5ee6,0x00086dd6bab0f6c3,0x000ef4907e3ffb44,0x000000b6c757002f}, {0x000f9a6a78629992,0x000c9ed89e2648bf,0x0008419eb85e5a06,0x000f1666d311af3d,0x00004f3ad7854733}}, + {{0x000551311820d440,0x000c86c4473a5e20,0x000d80eef0c651bc,0x000be51d230c2b9b,0x000042c4a1207515}, {0x0007ca0bfe9e2841,0x00081369827a4251,0x00038699de8f6057,0x000d05084f04f016,0x000074618ee02bc6}}, + {{0x00003fc6c68d6876,0x000cbff052c75e3e,0x000d16e7a3e732c3,0x00074692d0efa66e,0x00003d92b27165bb}, {0x00082badd44867cb,0x000e48c081b8ffcd,0x0006c8785a71b4a9,0x0002cfbc1676a773,0x0000e2c06174d893}}, + {{0x0001a4b9eca1c9f0,0x000c8ce5e5357bfa,0x000eec30a960bc1d,0x000d38e267d9f317,0x00006fb89ef6c257}, {0x000999ad364a26d0,0x000b26eaab582328,0x0005ba59669b794c,0x000a94ad28ab1fb8,0x00005dcbff356d0a}}, + {{0x0006d282bcffbc46,0x0006a6eadb7a5337,0x00035ae69708817a,0x000fde0ff50e05cd,0x00003b5fb75d4bc7}, {0x000e953e7fe08c4a,0x00045583ca1871c9,0x000e81c5cb4d8bfd,0x0001383e8d788245,0x00005f5e93d80474}}, + {{0x000160f293c9f316,0x00038864d7a7426c,0x000bbba308eb5633,0x0003025e1164023e,0x00004c2bae38fd5a}, {0x00001e1265aff7bd,0x000f96fd4b148006,0x000075a9c52d8a87,0x0004c58aba20e746,0x0000aa32bf94e123}}, + {{0x000bdef694db7e04,0x000779fcddc680f9,0x000b8dce1edca878,0x000ba111981c3403,0x0000274dcf1b0e10}, {0x00043b86def6d1a2,0x0000cbdb1866f727,0x0000c6f58d25b167,0x0007f5a4491e8c05,0x0000be2b2aba7fbd}}, +}, +{/* digit=24 [{1,2,3,..,}]*([2^120]*G) */ + {{0x0005c9dd111f8ec7,0x000d47c4e7603e0e,0x000392a51bcc33f8,0x00092d002f9a91bd,0x0000da4a7963132e}, {0x0000ae30bb1151be,0x000722e322511a0b,0x0004e9e7854febac,0x0000b80a3a508269,0x000058ffec2c4fe4}}, + {{0x000349d29c4120ba,0x000f20d0d915fbb8,0x00010ba519f94391,0x00091124074fa754,0x000066adbf6b50a5}, {0x000543c34bfca38e,0x000fd9e1ccfcc164,0x00020219ce0f2755,0x000979b9da0f53e8,0x00008234499a6b49}}, + {{0x000c513516e19e45,0x000775c4d5937b23,0x000e71ef656e2e84,0x0004c54f727d735c,0x0000b6304a7479a4}, {0x000a7363ab7e433f,0x00000e742f836638,0x0007fc19f1adea47,0x000697f054b8545b,0x0000935381baa1d0}}, + {{0x0004f9d918e49366,0x000652513982b550,0x0004d9cb965035ef,0x000508a553a0c26f,0x0000cb10d571ea85}, {0x00057b7a242da112,0x000d472b726848d9,0x00002a96b16a4d3d,0x00063b1d7e637c85,0x00007c7032b930d4}}, + {{0x0006b7d5846426f7,0x0008b47d441d5536,0x0006fbf48e7d09e8,0x000d7ce10b404d73,0x0000fa003d15784b}, {0x000614f17fd95965,0x0000e5cb98db25f7,0x00083a76a49e0e0a,0x0000f7dc65957b2e,0x0000d40da8e1ddbe}}, + {{0x0008bb4a595939dd,0x00085874021737f6,0x000ad76120355647,0x00095ebe740e7c84,0x000089bc84460446}, {0x000da5d85a9184d6,0x000b3fc0b074f7f3,0x0008a888e562563b,0x000e7ba6d2e6aaf8,0x000012d8643761fb}}, + {{0x000bba354530bb24,0x00078b0869ea9fb3,0x000431163bde3ef7,0x000a3549bc90460b,0x0000d03d7d324819}, {0x0004f9e43b6a782b,0x0006ec88a68633ae,0x000ffedd9216db30,0x00083fe1dd88e000,0x0000280da9fc2bd4}}, + {{0x00086913e538cd75,0x000c3e08ad53458f,0x0005d15ffa7001f6,0x0005dd02b8c6e6bf,0x000048234a451121}, {0x0009d2d3d5b40458,0x0005ca904190ff5a,0x000607f8bb0ffeeb,0x000729d5a3aca448,0x0000cbd665cb0a06}}, + {{0x0003573f37f59371,0x000dc1e4fca5a37f,0x0008ab0fceb0f6c7,0x0006ac1965a554ac,0x00007fbf56c37467}, {0x0006bd9acf7d720d,0x0007402247662e2f,0x000d53bef41fc8f8,0x0007d0817a14b385,0x0000ae327a64d76a}}, + {{0x0005c891f5f82dce,0x00068361079e515d,0x000a353309a7f67d,0x000e1ac8da81e311,0x000044990c52b18b}, {0x000ed95af103e596,0x00072dac9261c7d5,0x00094b8d3ece8aba,0x000e835e82b09993,0x0000830f09a76adf}}, + {{0x0001ac194d7d9b17,0x0002582e7f1743c4,0x000da0fca5bafdd8,0x0007ad6f0614c15f,0x00004b043a818ae3}, {0x000afa19e71734c5,0x000e4c450f2e3ba6,0x000e242b115d5437,0x0003c1fa5883fe67,0x0000143bdc27c195}}, + {{0x000ce7c6b53f5f95,0x0004cb176d99a2a9,0x0005c081b6424659,0x000ee661298d36b9,0x00003505bb86d9a9}, {0x0009e61f2ba70b0d,0x0008bafad4533f6f,0x000eb4a6ad07e16c,0x000c8dcf1694bbe7,0x0000febceda0cb0b}}, + {{0x000d7f2b1f3390b4,0x000c65b61272c676,0x000e127a99f7a1b8,0x0007bf0ebebfc9c2,0x0000602500c9dd99}, {0x000771c4711230f9,0x000b720f09c17f09,0x000e5e38b058eb37,0x000bc01b693d4bfe,0x0000289eb1fd653c}}, + {{0x0002b391770f5a7b,0x00005e44eb82a44d,0x00069712ae4d4d79,0x00020d92e69d1e3f,0x0000f11c4d75c6a8}, {0x000f3e542c4224c6,0x000be49d941cb5e7,0x00050e878d6b4e81,0x000c53fd72bd1654,0x0000a61e28b4e25a}}, + {{0x0009dc7ab952578a,0x000186e84d0b54da,0x000872042b5423df,0x0006df08b64eeb9b,0x0000c205782f990f}, {0x00096eb21f4c77af,0x0003bab273af4ff6,0x00036b3f11a79c3e,0x00027939bc922e94,0x0000f807ef9c6d9a}}, + {{0x000a8f833f6746cb,0x00054ea990cac7f3,0x000ddb0a921e46f6,0x000554e15fd5c5ca,0x0000d41f01728614}, {0x0004434426ffb589,0x000584dbc204346f,0x000969b7f8055943,0x00039a63dd20fe5a,0x0000d59e9577899a}}, +}, +{/* digit=25 [{1,2,3,..,}]*([2^125]*G) */ + {{0x0000ba9b733aa5fc,0x000b305af2353c2f,0x000ac82a5dece47c,0x00018a38e3f715a2,0x000097ba641e203f}, {0x000550409c110608,0x0004c6af512dc3af,0x000f2814656ea2c0,0x0004947ac28daff3,0x00007fab43b159ef}}, + {{0x0001641d4c5105f3,0x000e3d7fbd650989,0x000e6bdb01ae80f8,0x0008606d67225fbe,0x0000b433b59afc4d}, {0x0006db693e856387,0x000273e9862f44e6,0x0005c32ecf7b5925,0x000f506b78515766,0x000002fefd81e362}}, + {{0x0006a5c97290293f,0x000be388acbffe75,0x000916bdabf04a19,0x000bec0bbbb9cf5e,0x0000489527481f93}, {0x0007ec32a5923d75,0x000bade0c370dee0,0x00019d8fcc7bc949,0x00093f6d51217504,0x00004f5d4768fdcc}}, + {{0x000475d0fefb0c3a,0x000aa6d7c35d3754,0x0003798a4d48fb56,0x0008e60070b63336,0x0000e89f3d32fdb9}, {0x00089c86363d14cb,0x0000b7abd27d970b,0x000d5a0218981752,0x000aedebf7d47444,0x00003083bb07ac72}}, + {{0x000a2ffcc5e62e9f,0x00046edb02a40acd,0x000120c763b8b7d7,0x000063b700741c66,0x000077e84806d974}, {0x0000678a5e3d4647,0x0002d6bf35a30d31,0x0002f9043de68b1f,0x0000cb5ae83028d3,0x000024e4717c17cb}}, + {{0x00041debe949a447,0x0007e46a4fa53897,0x000047bdc638e938,0x0007c9cfe6419ca0,0x0000047f6491aea5}, {0x0008a9041fbab170,0x0008576bdba254e4,0x0002afddcda8e0b2,0x0007bfe807eebcc7,0x00007d3336df4257}}, + {{0x000563b4f3011dbc,0x000476610c03fae8,0x00081af0bda33776,0x0008ebed4f6f2a63,0x0000277984d99537}, {0x000a10c5751d2b2e,0x00089a4bf3f45ab0,0x000e3caf370a18bb,0x00036058d07ad4ea,0x00008ef5530cc430}}, + {{0x000c244bfe209256,0x00032fdce86762a8,0x00038706391c19ac,0x0004f5fa96a5d5dd,0x00001d587d481d32}, {0x00073a2a37173eaf,0x000763778b65e876,0x000bab43e2384800,0x000fbd20f8441e05,0x0000a11fe133621e}}, + {{0x000389a8391d54b2,0x0008a8afe546edd0,0x000e60bbddac74c0,0x000b876525a4ad5b,0x0000419ac96b0ad7}, {0x0003a0277eee51b9,0x0005e239768d078a,0x000d48035e86ecf3,0x000a5b3b0a259d8f,0x00004db43cc2d29c}}, + {{0x000772e81685d7b3,0x00018f34a976047b,0x0005f48ef23f27d8,0x0005c3927608e291,0x0000b0b43fad521d}, {0x000fb2663ca72840,0x00041d4db8377613,0x0003b526b7f5729b,0x0003d187b1489858,0x00000b732a6bbadd}}, + {{0x000a25b90f8550aa,0x00027c8dae9d4fff,0x000fbb232254db3d,0x000f0eb8cef963c1,0x0000d1cb48244bfd}, {0x0006ea1958773c2f,0x0003110114f184d2,0x00051e67e5862266,0x0005c5fadb3a87f0,0x00003185723a69e4}}, + {{0x000f4262048e3968,0x0005b83d9de48e02,0x0001e85ad436b50b,0x0008d6778d348147,0x0000b01ea6b5005c}, {0x000afee97015c07d,0x00087e3ba2aed3c7,0x000d3a1d246cdf1a,0x000ff3aa42e50183,0x000054b52698541d}}, + {{0x000c4f948a48e22e,0x000df0335a96e120,0x000151c7bf24977e,0x0008d7baf3442336,0x00002815a80b3664}, {0x000deba66e0a6b21,0x000f717515e8b4d2,0x0003ff24a783a84c,0x0005d968424c0bff,0x00002dd1bb648e1c}}, + {{0x000cf304e23e9bca,0x0005726e36243f24,0x0000b6d614387f81,0x00077b86a46a033b,0x0000f1bc8462b2d7}, {0x00001ba527de79c6,0x0003e261bbb625c4,0x0007b4bc70e1346d,0x00062eeb96c44b28,0x000058493c7b2545}}, + {{0x000e9d8fdd41d983,0x00018cc7c7fbfcb0,0x0008fa4d98be980c,0x00088d772e86506f,0x000056b14ada48cb}, {0x000ccefea6178f26,0x000d18bb0e35fd9f,0x000f391a9c84a620,0x000c055c75367c62,0x0000a83a5c683100}}, + {{0x00049feb8a24a205,0x0001a52ca53f23f9,0x000fb485317ebfed,0x00005d4b691bbebc,0x0000617ff6bb278a}, {0x00034c5e3c99ebdb,0x000d6784156a241b,0x0005d67dffc64242,0x0000109206482f69,0x0000967ce0f9e27c}}, +}, +{/* digit=26 [{1,2,3,..,}]*([2^130]*G) */ + {{0x0000f0441c23fa36,0x000061989a2eb448,0x000a29ca7b4712eb,0x00028bdccbba0f93,0x0000e205c1536194}, {0x0007957b36416860,0x000d45ac8b4e90db,0x0004e03500432691,0x00051707a759acf6,0x0000514d89c9c972}}, + {{0x0002c6bc4fe3c395,0x00031c7bebdfe3b2,0x000693459ba4a815,0x000b11a23ab6b725,0x00003bc377064922}, {0x000c8ab5afc60db8,0x0004a0b9f2a34645,0x0000fc507aa02235,0x0002e6d2a2954cce,0x0000c2731bbfce1c}}, + {{0x000efb6d9790ed61,0x000c96aa793b5066,0x0003e042ea77a0cb,0x00074b0a915f3c22,0x0000c5def0479c58}, {0x000007873b6c1da8,0x00027cd8557a0e83,0x00060f3b155cf85d,0x0000628f7c7c7604,0x00007052acbc6e58}}, + {{0x00091c2e48fb8898,0x0002fb8a9d066a70,0x00082a0e226882c1,0x00052d224986631b,0x000044ed736b5181}, {0x000476fd86e27c75,0x0009b4afefdc282f,0x00019e34da04edac,0x00078b3b256ebc61,0x00006a413e95787d}}, + {{0x000b6a20d645fd62,0x000dd61d314816ea,0x000079ae9632cbd8,0x000cbbac1bf7cf62,0x000057ee5c8133ec}, {0x00034a81680ac730,0x000872c77aa0bf6b,0x000a0a1d1aa084e8,0x000b167b5a864e05,0x0000641f6db359a1}}, + {{0x000095dc8385050d,0x00050f4b441cf01d,0x00027706a0d54a5d,0x000b7d5a37ccb409,0x0000f008f5515d7e}, {0x00034f35bf716c71,0x0008541bd6ca74eb,0x000e6fa0257a65b5,0x000a09df345e4835,0x000091f913b98342}}, + {{0x000d46da670ff1d2,0x0008ab97a1cc1554,0x000d9749324833d8,0x0004986fa6ab3cde,0x000015e0371a9926}, {0x000d592e56d74ff8,0x0004c3b5e1ec549b,0x000e93cb958a8caf,0x00083bbc6087a323,0x0000b054987d648b}}, + {{0x000061d5a74be506,0x00047ea16ff582ee,0x000bfc8a2e41781c,0x000e2d80b0c81e99,0x000024f4d696b547}, {0x000545dbdcc9ae4f,0x0005509b1e8e3a83,0x000c935392573dbb,0x000797582960c4a6,0x000001059ae4ae18}}, + {{0x000a238013ff83b1,0x0002ead69d08c431,0x0009589ea7c0018b,0x00019f89aeb52a4c,0x000021f41abab1cf}, {0x000bcbaef0f59585,0x000b2be8fbdc0cfb,0x00015aa318deb3ae,0x0006fcc2b954081f,0x0000acc09b39c0c0}}, + {{0x000bfa86d518ffb0,0x0006930f124b775c,0x000e81d0fdecee1f,0x000b2f9a402804f5,0x0000e8225c52a0ee}, {0x0005d39fee9e867d,0x000f2b505454884a,0x0007a70d19540428,0x0002a9e2bf2e2010,0x00009917c3c7010b}}, + {{0x00042fa3d843d538,0x000593ef927aa98f,0x00084ca7433777cc,0x0005dd4440cdbecb,0x0000c22f9639dc7c}, {0x0002b70c8d947081,0x000cb814364f4bc8,0x000f59b7e7e0b43f,0x0004c4186d4e2486,0x0000abc895e5d6bf}}, + {{0x0001e274d559d96d,0x0002e8db6c013815,0x0009921af4f18c0d,0x00002879a3aa836f,0x0000beab27c5c046}, {0x0009eaa7040bf3b5,0x0004c614b091242b,0x0004baf5d39c479e,0x000944e38ede2b0e,0x0000bb192b840a53}}, + {{0x000572337e440d7b,0x0008fde23f68896d,0x000c64918685c5fd,0x00080c05b1a26dc2,0x00009390e318ad65}, {0x0001c4e7dee5b9b3,0x0003aeb04f6e8791,0x000065aa6b90c505,0x00028d07b942a18f,0x00004acdf2a4ca09}}, + {{0x00064d39de40ca36,0x000f72f3857e733b,0x000ed92f71d4b6d6,0x0002485e2be8e9b2,0x00004ca7048177da}, {0x000ae9b8da993153,0x0004dfc698a4c65d,0x000958c279c14517,0x0000975a296b94ff,0x00008684e0873950}}, + {{0x000e34b3390ff239,0x000b4e7d18ef7872,0x0007fe7b1968ce4a,0x000e2a0b4a745e62,0x0000607b0a15aff3}, {0x000818eeb40e3a5b,0x000410fa8d7a1b05,0x000ed48096ac6220,0x0005f205b9058571,0x00002432ef1a7cb6}}, + {{0x0009f973112795f7,0x0007284e6ee1715c,0x000b66bcde824443,0x000bede5cb4858ec,0x0000c1367361baff}, {0x00015955dbec38e2,0x000c188ad1535466,0x000e0952f51c0782,0x000fa87ba4c53ac6,0x00007e6782a3b21d}}, +}, +{/* digit=27 [{1,2,3,..,}]*([2^135]*G) */ + {{0x0009740e2c2bf152,0x000589e99704feb0,0x000fbc565627a220,0x000de8cc8d73d0c2,0x000023eed8fe20c8}, {0x0002583a8363b49a,0x000929c2b0a61ee3,0x000dbc85c1a0b6cb,0x0001aba9f7c3d290,0x00008dfbb97bef4c}}, + {{0x000236e846e364f6,0x000c7ea50ca0c16c,0x00026b86d7f33527,0x00070c6481077509,0x0000c2a36096598e}, {0x0005e52f024e9245,0x00044db4afcaa675,0x000831790e0fa07a,0x0000d5c5c3ce7d66,0x0000b4ef350f6cbb}}, + {{0x0006b2da6dc1d29b,0x00094871e1444280,0x000f49276d303000,0x00004af1feb333aa,0x00005583b9f770bc}, {0x000be7895695f204,0x000149d012b51db0,0x000f61643fc84181,0x0001282409f27205,0x00000d3417515883}}, + {{0x0004c050f15dde91,0x0007fd5f2b820521,0x000e82b62a47a76a,0x0005eeab254d3062,0x00001a05fe04ec95}, {0x000f46e9d529b36f,0x00009f9e3df67eaf,0x00031769855ab130,0x0007acd463e37199,0x0000d251439bcda4}}, + {{0x000669c72ba075b6,0x00055a4690158c3c,0x0009f8ba889f78b5,0x000ed6f706aade3e,0x0000d8bd566132d7}, {0x000e63b805f08d67,0x000d53bcc1b525f4,0x00025d8477f48200,0x0000a7de801968b0,0x00004afac04f7cbe}}, + {{0x0007598a9d82abfd,0x000b16c170f5e2a3,0x00066b0875f188cc,0x000ad9b168220050,0x0000a22c21397155}, {0x0005d3afbddb4799,0x0003dd715b99151e,0x00097cb2e4b606b8,0x000b65ba73b54bf9,0x0000a1bfe43cecd8}}, + {{0x0002522cccc18ad5,0x000da1a6e0277973,0x000c2354daadf3f8,0x000689a7382c9317,0x0000ce1680d2818b}, {0x000bbfcd9ecbee97,0x000bacae62ac359e,0x0001ac38a4330689,0x000ee8455ce5b4c5,0x0000921dfeb6e238}}, + {{0x00022f3dbfb894e2,0x0006ae274b18e131,0x00058aadfbe9b79f,0x00035165a49de5ca,0x0000495775831487}, {0x000ef61bb9390993,0x0009f6d13694111d,0x000fc253b1d6a974,0x00015e1474b4ced3,0x0000a1485e67c5db}}, + {{0x0004ddb0f5f27cac,0x000ae80d59ff6599,0x000601023e85461f,0x000bfb3f05481a66,0x0000665427bbc9eb}, {0x0001a697587fd52b,0x0007dd49efceb057,0x000420688935289f,0x0006aeb1becc60ea,0x000022639d9c3a78}}, + {{0x000dab61430c9ab7,0x0002b238e9975afd,0x0008042ae0bdd41d,0x0004cb8094743041,0x00001f9addb3dddc}, {0x000c016c52dd907b,0x000c79e2047f7090,0x0001011a6d9bdf44,0x000c7836f1fe801b,0x000063accbd89acd}}, + {{0x00076680448087c4,0x000f31432dae264c,0x000f9bf47ac30903,0x000d02f851b26600,0x000000ed311acdd6}, {0x00079fef8fd24247,0x000a8a6da98b045e,0x0001e673afdfd974,0x000167d5c9f6410c,0x00006f2e733cb2c5}}, + {{0x000acab4baef62e3,0x0002785b91e87817,0x000e576109f5a220,0x000e036666ebe66c,0x00002ad31f4273bf}, {0x00030a425bcf4d6c,0x0002915056e66283,0x000332156ea95059,0x0002d699811c89e1,0x000089cf1ff4c11b}}, + {{0x0005acbc46d7ce17,0x00071b085877889e,0x0007a50509a515bb,0x0000358ac1a03d0b,0x0000d3e738b62926}, {0x000c2ce2a6cb0ebd,0x0004bf7adc79861c,0x0000163766f2e295,0x00008f91c4d45133,0x00009fd2c812ad59}}, + {{0x000337ac0b7eff35,0x000e75e48b3c0ad7,0x000f13a5f8552225,0x000cbe96f78b0c73,0x0000e70062ed2349}, {0x0005048e7073969a,0x0009233cb3d26b8d,0x000caa20f392d2a2,0x0007074e4f727c4e,0x0000068c99ecccde}}, + {{0x000d65861a023efa,0x000419e5246e1888,0x000563ec01d72aab,0x000a4309a26348e5,0x0000097196463439}, {0x000d54badb9b5b76,0x0001645a524b567d,0x00038e60873fac1a,0x000f482fe97ef7fe,0x000008748d29f384}}, + {{0x00086ec1ed66f181,0x000bc61fce43ebde,0x000bed74d225d906,0x000ab74cab07d6e8,0x00006e4617f37855}, {0x000aaddb2fbc3dd3,0x000f5aeddf5b6568,0x000cf2fadedb5484,0x000699578f20e86d,0x0000516497c915f5}}, +}, +{/* digit=28 [{1,2,3,..,}]*([2^140]*G) */ + {{0x0003fecfa181e695,0x0000e0d69a98ef0a,0x000eab95d9ea02f8,0x00002162e9cf8e66,0x000020f2beb74720}, {0x000540a1df843618,0x0000f1fa6d5d621c,0x000f5f6ff1203772,0x000ef2ee3c7b510f,0x000017a069c2bb2b}}, + {{0x0002fb6b294cda6a,0x000519039f348357,0x0005cbb216ce9bf7,0x0000d980e012f009,0x00000aecc1c7063f}, {0x0001c3af02909e50,0x000f48ce9cdc57c2,0x000e336f8c7d59ec,0x0005f42732b8448a,0x000056e37233f4f8}}, + {{0x000b53189e800ca4,0x0006d45208fd8a10,0x00014ba3750fe0c1,0x000acc5e43c0d3b7,0x000027d200e74189}, {0x000e24fe616e2c00,0x0008ee1854c105de,0x000342a739c25f4c,0x0009524d3222a58f,0x0000807804fa027c}}, + {{0x000653a4f0d56f34,0x00078a28b805c222,0x00073434b961e404,0x000a18ec03f8b04a,0x0000c966787eb712}, {0x0006c42864fee422,0x000a3b0ece5ccc19,0x00031c159c1be93d,0x000655887d9f22c1,0x0000bb6d593fce45}}, + {{0x0009ec9b809b7ceb,0x000b32c72c2c22c4,0x000a0bf368a41486,0x000c68d13b9420fe,0x00003d36eea566da}, {0x000c08a328cc987f,0x000b4a3264616fdd,0x00010dbba0a3bcd2,0x0004c38103c49dd8,0x00009d81a293b78a}}, + {{0x00065ade4d559419,0x000da03840873de8,0x000f18b9bdedafa5,0x000267df414abb4e,0x0000ee9ea438aee5}, {0x000aa1637a55a4a5,0x0003b15f93b9260f,0x0009c3598eb19a51,0x00078e01d7ebd29e,0x000023fc56d69321}}, + {{0x000070cb98fe684f,0x0009224a1458501d,0x000bc6b3fd60fbe9,0x0007cab45761c892,0x00005384859ee6f2}, {0x00071f7b59e763bd,0x00088b5a8e5e4b02,0x000a482923d4606a,0x0004454eda5d9b05,0x0000a7731d1b6fec}}, + {{0x000369390d458714,0x000fc6166d8da3e3,0x000a90403e976403,0x00063775c3368289,0x0000bd17983b2f1d}, {0x000679ed5d2c53a7,0x00088dcf3b87a616,0x0006a694e5ec4bcd,0x0007e53e6d7613b6,0x0000460fc7753fc2}}, + {{0x0009b8295caabee0,0x0005889501e37046,0x0006ed265de024ca,0x0008b26bdadc0607,0x0000cb1236b5a0ef}, {0x000ddbf0972ebf9d,0x000452aca4324065,0x0004aff76f1dd387,0x000d23d88b97cf74,0x00001359afece8e3}}, + {{0x000ba2b91502cf37,0x0007984db75d52a3,0x00030b1c92c3832a,0x00060b94a12dddde,0x0000802eabd531fd}, {0x0007327a37fddab7,0x000b8aafa9733370,0x000e6f91a65d6f2a,0x00030ac525c5b811,0x00006aeb0c9cf465}}, + {{0x0005ff62f93a6750,0x000405f48679e881,0x0008ae884a6ec968,0x0008736dcbb55635,0x0000af61472e19e3}, {0x0004372a5f696be1,0x000a5f22fb707233,0x0006cea90c65e57e,0x000b2a168da30c94,0x000036a8a8775681}}, + {{0x00081dc0f9f44d43,0x000ffc46585aad5e,0x00047d1b1f09a695,0x0008b1a1649164c4,0x0000b4b36c8b79dc}, {0x000177b3b6b234cb,0x00046730d9d020d4,0x00080531d096a250,0x00095c5611b9b8ef,0x0000a904b3c14bb4}}, + {{0x000d9d493a3147a2,0x000c7a5655451192,0x000f072129f30a5d,0x000c1370b1f9cb6e,0x000099585462d87f}, {0x0003effc17db9ba2,0x000cab1644a8d332,0x00049ffbccb18548,0x000683f8a306d44f,0x00008d658f16c2e8}}, + {{0x00060cda99f8c71a,0x000aabf742ff44ba,0x0004b3f9967b7abd,0x000160c6310f9c91,0x0000e430a339412c}, {0x00076d388ace52f4,0x000412d7067d1e67,0x00007cd1b4bc0fa2,0x0002c0c3c286aa8f,0x0000cb8f38ce985b}}, + {{0x000be808c3bff364,0x00021263e57583cc,0x0009bdcd1005a0bd,0x000b6b060d7dda25,0x0000a1c56433a5ca}, {0x000dbb99fe4fc88b,0x00081c97bbb52b7b,0x0002321ae09418e2,0x00064e28274fb4a1,0x0000137007e0c87b}}, + {{0x0001fe1c63c4962c,0x0008d81fdb258053,0x0004c2b6b50541e8,0x000fca1c1291a1fd,0x00000693a1866df4}, {0x000604e0117f203b,0x00025a99b8d0b2c4,0x000212c44245f196,0x0002a7fedc20aac6,0x00001ed4e57020f5}}, +}, +{/* digit=29 [{1,2,3,..,}]*([2^145]*G) */ + {{0x0000fb6700a1acd0,0x0003fd999681b556,0x000b4e1bae823fd7,0x0000a3da915d1f6c,0x0000d0301186ebe0}, {0x000b0c989fca8cdb,0x000b49da0e0b744f,0x00031d76f970d01d,0x0009695ad8c56479,0x000015737c0a659b}}, + {{0x000384ece53c2d04,0x000d1e4606daa12b,0x000ec12b0779d897,0x0001ad653e47b073,0x000062dbbba9756f}, {0x00009f2cafe37b68,0x000f6cce2e1769fe,0x000f607fd273d1eb,0x000c250ac1d5383c,0x0000035f7ff92e10}}, + {{0x0002d5a2093c22a9,0x000145703aedca44,0x0003287b6ebd0bd3,0x0008b9a08f2afd65,0x0000bb88bac9d1bc}, {0x000853875c1e3b2d,0x000ffa11447cfbaf,0x0005c4c8dbd2ac94,0x000207586d816cea,0x0000c3aa800f8dc3}}, + {{0x00034c77e6c55202,0x000fbcb9ea58854d,0x00086666dc27df9e,0x000a85205f2369d6,0x00009d1febf2417a}, {0x000819e93470afed,0x000912a27f9e9846,0x0001e65043e6a966,0x00080954d008a2e3,0x0000ba7ced06cb76}}, + {{0x0003e41d07fa53db,0x0009c4e35bc526a4,0x000da2f8c3154a78,0x000f99cb768924e0,0x0000a964a2bd3613}, {0x0008d35ba1d16c4f,0x00010b54d0575a54,0x0006402052e1bfed,0x000f290f992136bc,0x000039cb9157156d}}, + {{0x000e64699b444ad9,0x000d340504c5c913,0x0002e53dbddfce99,0x000536c8482a99d4,0x0000aaf2c2661aff}, {0x000f7962664cf67c,0x000931393e2bee90,0x000225bb074ab5c9,0x000d6c3ad0faeae6,0x0000355648ced63d}}, + {{0x0001d271d91cf9d3,0x000d8377b20ae4e3,0x0005e1327cb35d4f,0x000e7544de1e4505,0x0000298e31b58703}, {0x0007237de0133394,0x0000e3d101c65508,0x000aab0dc32cbf30,0x000bb9870dba22e8,0x0000a52623d7d155}}, + {{0x000f541338d6e434,0x00030541d5ccecaf,0x000bc88ca56f7dd7,0x0002c375d426de96,0x00008d94f6bded3a}, {0x000a3bb2ef8279cf,0x000a1b1867f26354,0x000225151d575465,0x0000d7ff99b0ff95,0x00003e19d89e9450}}, + {{0x00035acc85dcf572,0x0008a88f5415dbf4,0x000c558076174565,0x00056f06367e9a17,0x00002d077a5ea90c}, {0x0002258a2e04e763,0x000e3e06e405fbf7,0x000e6f954ba965d3,0x000a742724d06fe3,0x0000e47d475b1251}}, + {{0x0000151e0fb82f76,0x000675668ac2b8ba,0x000d711b00d16072,0x0002f2022ba25814,0x0000addf557df3fe}, {0x0001e1c6b9c94354,0x000a773826bd2b83,0x000240f89ce3a060,0x00003a53fa11c11c,0x0000f9cc8d8d56e3}}, + {{0x00031f6641f82c90,0x0004dffec7564b93,0x0009158abd97c7c5,0x000a7ff5ee6d1f1a,0x000054493a385c3d}, {0x00005f5eb7d96df8,0x000764473a39a57a,0x000e16d55a3afd44,0x0006adc2a4d9c488,0x00003e144f675f87}}, + {{0x0003268e32dd620a,0x000ec27849a292a8,0x000378882913ec99,0x000cfe4dd8fdfa2c,0x0000f96f33f8e6f8}, {0x00037e5dc3fa8a51,0x0001a0b03a1dc067,0x000f037b0236bb53,0x000a5323e59f2989,0x00003f9b5a7e9a12}}, + {{0x000ae9559029aa6e,0x000b7a4db2ed50d8,0x0008f373dd74e292,0x000b372b9c335584,0x0000c018db78c45a}, {0x000690269cc53a8b,0x000c6a8798641f44,0x00013475e8c4b628,0x0009f56c743d284b,0x0000f4a933923de1}}, + {{0x0004f47f0cefa69d,0x0009d45468664a8a,0x000f603c1dc8e4cb,0x000ac4659ba69b23,0x0000ab4d601e87b7}, {0x0004337c1ebc8d9d,0x000382b4074ba6ca,0x0002fb7339fa6585,0x000ea94a4b4f8190,0x00002bb5d7b7525d}}, + {{0x00092d5f81f95671,0x000a3d698470eb2e,0x0004c81eb54cb95e,0x000c644f2acb28e0,0x0000c1ebfc508cee}, {0x0009fac06e074235,0x0008e7fa0c858f79,0x000f4db4472225f9,0x00009160cd861634,0x0000ec36159c52c9}}, + {{0x000f6ce51efb3108,0x0004158df5be0d0d,0x000158e59cb5b2eb,0x00033656459e2936,0x00002aae2b99466e}, {0x0008a39411aa636f,0x0004e4c0a933fb65,0x000f026b77152ecc,0x00011f010c758a49,0x00004837f98bb093}}, +}, +{/* digit=30 [{1,2,3,..,}]*([2^150]*G) */ + {{0x000523a626332d5d,0x00028561bb44994f,0x000845ea27bc3883,0x000089305ed4b03d,0x000039d3ee292a1f}, {0x000fdd3e7676b0dc,0x000f3b7060176561,0x00064f9a8620e35f,0x0001f676ce424ff2,0x00004c341a09a268}}, + {{0x00031769bb816483,0x0005353120d000f8,0x000cabc62d69eb48,0x000cb1a17d75f44c,0x00004a07f82e749f}, {0x000f787bbfb55541,0x000052e283f82c3a,0x0009213a0b06ed4d,0x0007b44722889fa1,0x000062b085eecf3c}}, + {{0x0000ddaeb300f7aa,0x000c4db5e80136d9,0x000d5244c9dcf7df,0x000aa1c45cb26874,0x0000127ee79d48e3}, {0x000cc53575f1dbba,0x0004e0e6161e488a,0x0002650d095037e8,0x000215b7e5928329,0x0000be67d99b4938}}, + {{0x0000d2f7189e71f4,0x00081ecf91e73267,0x000757a21c643874,0x000ce4d5758e57db,0x000027d09f8690a9}, {0x000308f38384a7a9,0x000420732b99846a,0x000845819aac3acb,0x000e030e94100917,0x00005cba11237ce5}}, + {{0x000aa377378058e6,0x0000a4411154eb81,0x000828ac741c746a,0x000b29410c73bcfb,0x0000439be91fd972}, {0x000b4b043a2fbad0,0x000f82b5e8404bf3,0x00097bd4c39e6dad,0x000ccb4f71640863,0x0000f7de5687f1ee}}, + {{0x0002a73f37ec3c39,0x000d4d59eba0db33,0x0004d3257c65259b,0x00038f9291709cdb,0x0000a793b264d389}, {0x000e34be43756f0e,0x000dbafb56c9f39f,0x000208b272f76bdc,0x0002c2bf37867a61,0x0000a1d4307e8997}}, + {{0x00044878a429f4f8,0x000b5b516609d0a7,0x00069b5df0649712,0x000af23826ba57e7,0x00002335df29fc7a}, {0x000f0675c93d9950,0x000a68677be62389,0x000d9951b59ac367,0x000ccea77985ff21,0x000038956fb85011}}, + {{0x000851aaaca5e9b7,0x0000e6713b9797b7,0x0000a61f6518aa52,0x000b68c357e8c715,0x0000842e7e35c2c2}, {0x000af656868a5489,0x00025068fc818dff,0x000917733d963bd8,0x000327d4da5c8b65,0x000027091000b247}}, + {{0x000db942f6d0d97b,0x0000943b9373d6ff,0x000d36db605c3ee4,0x000c3e02e541ebff,0x00007415a977e1dc}, {0x000682e163aa2f64,0x0003ef3af218e383,0x000fdbadb46febdd,0x00021a50a0507eba,0x0000ca8ab4e0e52e}}, + {{0x000832e1b7cfb737,0x0001cec354c9a3f0,0x0008eadca7a8afe5,0x0002bb3e91c97e37,0x0000449c59a1c3b3}, {0x000c3710b1c4655c,0x000a379da87ea619,0x00038d96a692e4c6,0x0000ec3f3f5d86de,0x00005320f42dc08c}}, + {{0x000f2bc8fec5dec0,0x000f84d6786c92a6,0x000ffa084a71383f,0x00071587588c06db,0x0000d85f5ca6857e}, {0x00011b3b6c774d40,0x00084c3521a8e873,0x00029fe0f672357c,0x0008cde5fe74615b,0x00002bc51105b715}}, + {{0x0001e48a105fc8eb,0x0009789ba48c37a0,0x0001c2180769d754,0x000387108c6fe1d5,0x0000032dd3467bd1}, {0x00026db020b0aa69,0x000f7664c73c9538,0x0000cf95d05137e7,0x00028a366302c466,0x00009004e1242cef}}, + {{0x0005b284f9735368,0x000e535b04ea824f,0x000a03089b43e299,0x00042c472c88f74d,0x0000269d57ac5a2e}, {0x00063fc6607b38e8,0x000ea9390b0c7c1e,0x000ee2869e89e2aa,0x00097447c740da1b,0x0000556f6fd2f3fb}}, + {{0x0003995a4b6bed1a,0x0004f7095c541a0a,0x000a73ce92dab579,0x0008a666c6a1ff2a,0x0000dd0a54bede43}, {0x0006b1afca906cd1,0x000619de10dd160b,0x000633da325fc601,0x000d5a248e9c99d3,0x0000fe3f746258a4}}, + {{0x000edc88be85c1d0,0x00083ca09cb6c253,0x000e3055add3d0e4,0x000dbfb997f6879a,0x0000c929ad007431}, {0x000621584d2db42b,0x000e578828cdcef1,0x000bd4b66b50df3e,0x000b039589da9d6d,0x0000c4fd2e4899c2}}, + {{0x000c9a7d298c241d,0x000986807cfd214b,0x00064eadbe3b697b,0x0009c51f1c780245,0x0000de8cdd084814}, {0x000f0a75a4d2604d,0x000e9c1538af946b,0x0005b1fcc27154d7,0x000f81c5cc9230de,0x000088519ea36864}}, +}, +{/* digit=31 [{1,2,3,..,}]*([2^155]*G) */ + {{0x000dd1a7cb1282c7,0x00064e46973ab828,0x00008d6b2a08d762,0x0003f2fbaf8d40e7,0x00002571fa1bdaeb}, {0x000732ff22dfd98c,0x00064087108d85b1,0x00088207a87ab01a,0x000754eaaafea859,0x0000cc832f929f00}}, + {{0x0001185ca8d9d1ae,0x000cf987ded2488f,0x000c46124adf2c77,0x0005f37f3039f060,0x00005d70b7651e09}, {0x00086506260e70ff,0x00070750d10582d5,0x000bac36439d75ea,0x0003289cf3d0b175,0x00003a7564e11d01}}, + {{0x0004700ec3128c2f,0x00019e383f4994ab,0x0003024eb6c76d86,0x000c68ec36b150c0,0x0000b43947843daa}, {0x000764a8dc796230,0x000db440fbb2fc68,0x000c5ee0d5b86995,0x000bd3d66879bfcc,0x0000522894295aa8}}, + {{0x000a43e3fcd3efca,0x000418088e9ab24a,0x0003d46eadd26c03,0x000a6f05ef4dc9bd,0x00002f99d592a4c6}, {0x000d3552f1da46cd,0x000d4afacdd1ddab,0x000d4057872c3f8c,0x000b94090c4eee92,0x000028bb4209a623}}, + {{0x0003becee8314f30,0x000ddbea298f5e7c,0x00080acec1c068ae,0x00095b08d381f17c,0x00003b56be8e3304}, {0x000b8f29222882d6,0x000664af8bf7aeff,0x000c57d8c95ff38f,0x0004eff0e32d351f,0x0000635be5277b44}}, + {{0x00092d2e7417ce17,0x0001270ee7f52427,0x00067a41eff42bc7,0x000a57aff4dc6d5c,0x00007709b7b90882}, {0x000731dbe217f2cb,0x000cabb721773554,0x0001dd0592af2a8c,0x000476a8eee76959,0x0000b2930c9fbba6}}, + {{0x0009126cecdaa7af,0x000d1b13247b174a,0x00084c1c4fc8c7e0,0x000c3a39c110d234,0x00008eb8758731df}, {0x0000212c00674527,0x000e0b9b926c022f,0x00042daf43f6f69e,0x000de399032da0ef,0x00009f00adef3f80}}, + {{0x000dddaf176f2c08,0x0004625726581e6a,0x000342ffb01ca460,0x0008d58a404ded85,0x0000cf60f96c4183}, {0x000691cc9071c4aa,0x0003944428039bbc,0x0009c0d81fd58874,0x000f7ef7101c8580,0x00007fb754d2c456}}, + {{0x0009ff4c1e99d816,0x000643c617c0f855,0x0008c6ba708e1a7d,0x0007945398fd4324,0x0000ffedd9231283}, {0x00059d2d629d2080,0x00053490530e8a6a,0x000505989a9d141d,0x0004ee42f6fc1838,0x00009bf250d479d9}}, + {{0x000a1d5af71013f7,0x00049bedc9466af7,0x0007370a0e68216e,0x0001cc84cba30bd2,0x0000981afbff7042}, {0x0006a679449f0e1f,0x000d1a47edae0249,0x000feca2286cfc4b,0x0008fa4073c936b1,0x00005694612f3f8f}}, + {{0x000f9e12cb7191e8,0x000865b08ea6ec14,0x000332bb978ea1bd,0x000e24bc65aa9b46,0x00004cc22b43f80c}, {0x000e9e9d49d5bf18,0x000599087da40098,0x000f6e357cd4ec1c,0x0004b7bc9d07c5ae,0x000039a02691f8f6}}, + {{0x000d6715bde48f8d,0x00025189bc7dbcad,0x00009ee8ac970387,0x000ff78d45299ec7,0x00001287ee3545aa}, {0x0008874db1dbf1fd,0x000ac90c88d67d1f,0x000368313ea46588,0x0003ad90ba649a84,0x00005fdcbcf30d54}}, + {{0x000643037577dd85,0x0003d9c5fe88f795,0x000bdc13283b82af,0x00039e4c1bea26cd,0x000089fa086ec043}, {0x0009538b13799dff,0x0000e295d034033e,0x0009ddcca85fa8b2,0x000333ef17f73fbd,0x000032bd123cdb66}}, + {{0x000e9959890272db,0x00098e713a10cf3d,0x0008227b875f3432,0x000dc7ae13479fe2,0x00008561eaaaefac}, {0x00097a08332aafd7,0x000503809b62a6a2,0x00063036f9b0d8bb,0x000da862fa1cfd0c,0x0000a16eb562d64b}}, + {{0x0004ec13cf482834,0x00055c8a705e4cc3,0x0007d4f84b09daa2,0x00029d91e9d0d05b,0x0000df6ef651b389}, {0x0000763aa21ba469,0x00081293f8fbe16b,0x00020aabfc6b1d17,0x0009797ff5b602d5,0x00004d671be53393}}, + {{0x0008e8a2ac13e274,0x000f0eb1a9f5f7e4,0x0001f0a624494f6d,0x0008f0adbf84eb98,0x00009badc3293643}, {0x000a541004f7571b,0x00002f1c94ee50be,0x00027bc31bac67d1,0x000e27753d73a1b7,0x00003d01cf2e0686}}, +}, +{/* digit=32 [{1,2,3,..,}]*([2^160]*G) */ + {{0x000e50f6d3549cf8,0x000f7acd665ed433,0x00011fcb46f33696,0x00085fe95bfdacce,0x000010ee2532f7c9}, {0x0000fe17159bb2cd,0x000da58b357b6545,0x0009fea72f7dfbeb,0x0007445b057e74d6,0x0000485717b62731}}, + {{0x00042e8ee36860ce,0x000c6113c22d896c,0x000104213daf04df,0x0004e93adbb7b744,0x00005fd5fa1ffd39}, {0x0005d941a4e0551e,0x000d38d101516823,0x0009845236772cfb,0x000a97476071e309,0x00004e879df3a56b}}, + {{0x0000aa9b898fd522,0x00079e9af1a76c8d,0x0004f03f82fb38a5,0x000c6fc1f2b9a93b,0x0000b1aad44e3f0c}, {0x000332e7cf2c0846,0x000ea367d26d58b5,0x0006e4a8d1c57d96,0x000b69c297eabdfa,0x00005a947eeaa0e2}}, + {{0x000afb0285b94916,0x0007be4c705eaaaf,0x000d9caab01a0be8,0x00033f9f1d4f5d2a,0x0000e349a4b237a2}, {0x00012464a1c6a163,0x0005f9383260cf1c,0x0006d5471d99e6b6,0x00089bba3d43665f,0x00006974d052f8cc}}, + {{0x000b616fdd5b8549,0x0007c728719ff535,0x000921cad592549c,0x000ef85231468606,0x00008c8ce34c11b1}, {0x00037e7e9090b363,0x0008dbf7bbb728b9,0x000d8797467fc3ab,0x0003fde2337097a9,0x0000e5adca22970e}}, + {{0x00049a1cfe89d80f,0x000cea9c8371c26c,0x000d066d2b42c026,0x0003edda6c013ada,0x0000b8f722946a4f}, {0x00079ecd850935b3,0x000ca631e1b308b5,0x00019853434c1a74,0x000f259b5fe596ac,0x00009ff21f711f24}}, + {{0x00068a7b3f85ff0f,0x000c2a888044cdcc,0x000dbe894acd21cd,0x0000d3c6719b2e05,0x0000ae1d3d97b826}, {0x000dece8a1c5d92d,0x00040c52077eedfe,0x000dd13edbca01a9,0x000aacf085549c16,0x0000c5c3baf195eb}}, + {{0x0009e148f9290579,0x000630c853df27f2,0x000e9c5ce7a64ae0,0x0002a4956cd18358,0x0000d9cce836ed09}, {0x00059796e93b7c7b,0x000181bb9e27cc6e,0x0009e29a0e1e4709,0x000644070b3083aa,0x0000f181a75e785e}}, + {{0x000063fbe7b643ab,0x000796085760cc17,0x000214c9e7872e1c,0x000637d6b0fffbb4,0x000018bbc0f22bf3}, {0x000de0c722591c92,0x000928c29e0c8b17,0x000304f201edeab1,0x000fb67fbfd98ef4,0x0000d1dbb6bbc77f}}, + {{0x0002c658ead09f79,0x00050780d14df53f,0x0001b66bc1335e1d,0x000fc7d9cc20e0cd,0x0000b670a384be0b}, {0x000dc8128efbeedb,0x000bd326a6e5ce53,0x0008e9a630c74e77,0x0002478604e0d2b8,0x0000ab38fcac3dc2}}, + {{0x00016d3c7141771f,0x000a3f226b662556,0x000ca63a9a86691a,0x000f2aea19fea4b3,0x0000c05dc439e672}, {0x000e786718ba28fd,0x000acc66b984a9c6,0x0003702f207b7995,0x000efe3f434f551b,0x00006f62130aa84e}}, + {{0x000e8c85c0a3f1ee,0x00019c87c37f8ed6,0x000e3b78dbcad249,0x000a461dfb62bb9e,0x0000ba8e478abceb}, {0x0008cb0eeaede4b8,0x0007f976deb637d3,0x0006147fb0bc498e,0x00060932944c046b,0x0000b123f36771f9}}, + {{0x0007987b5b41d786,0x0006ebf0c4f84b0e,0x000b80ecdea7df90,0x0007e554d03560fa,0x0000cf306f75b1db}, {0x000fb5689fd4773f,0x000f10f9be330d59,0x000352da4ab254f3,0x0003ee28a09a9277,0x000081862f6541ea}}, + {{0x000dcc7de79dc241,0x0002458f69cda155,0x0001850dff1168a3,0x000848aac215950d,0x00005c8295bc204c}, {0x000aa367d8184ffe,0x000d50447bdbf661,0x000e4a59ec396228,0x0005e531cd5143bd,0x00003a26e3c4beab}}, + {{0x00001579f759d014,0x000f3eae4fdeb59b,0x0000ba8c0a2923d2,0x000442d832775769,0x0000bf7e38b84f51}, {0x0002563b413fc268,0x0002f9e53b36b681,0x00089f66dedb7d36,0x000415cfa585c4c3,0x0000e1adc31d4bd3}}, + {{0x000a13f1402b9d0c,0x00026c7bc863d3b3,0x0008c3e6e573441c,0x00057d8b301ec457,0x000026fc9c4cadaf}, {0x0001bfd7493cea35,0x000ecaf8145696e7,0x0008c608fd05d4b3,0x0002768aca2a8a6a,0x00003ef07f65725b}}, +}, +{/* digit=33 [{1,2,3,..,}]*([2^165]*G) */ + {{0x000c9d646ac49d20,0x000b83137aa9a6b5,0x000225a3842c77c0,0x00090724d000fc68,0x0000f63cfc82fe1e}, {0x000b01bc6441f959,0x00095c8e448f22d1,0x0007fb1ba7d38f71,0x0008df0b33fa5f78,0x00004dcfda1a9015}}, + {{0x000de10296c36eff,0x000192c4da77211c,0x0007836da7ee8967,0x00060ac617d270a5,0x00000cd9c328cb75}, {0x000cbf7e455fe908,0x000afe7334f301fd,0x0007de4ec3fb53cb,0x000fcff81e2ea44e,0x0000adab3ad8b384}}, + {{0x0008a2b599ff0f94,0x00074104fc6b0177,0x000694ff368a923d,0x000f121bfa44dfda,0x0000f7199dc37667}, {0x0008ff6e46f2a79c,0x000d29f8131dc06d,0x000b4ce7c08b5dea,0x000c3d42519a59ab,0x00004f710bd742ae}}, + {{0x000368b4ed80940f,0x00058a6fcedd3014,0x00097579f67e6d05,0x0007f58c208c49ca,0x0000e3d7a8292359}, {0x00032027e096ae27,0x0006b4b393665e20,0x000dcdffcb1f3e1e,0x000e82b6da26f32f,0x00009422f1dd097b}}, + {{0x0009c748c878145f,0x000e49c635655054,0x000cf2d5e67f14ed,0x000d0f32ddf78c9b,0x0000faa843058201}, {0x0004a9dd1b2de28e,0x0007254be41447d9,0x00082755bc09c4be,0x0003bccc80e178ca,0x00003251d113697c}}, + {{0x00009d35001417b1,0x000e4962ed5e2bbe,0x0009f46c3795e84e,0x000a2e4b79d1ca27,0x0000f7f8a3b93836}, {0x00000b14a64dc32e,0x00042f84f7396922,0x0009155c0c842433,0x0005071110da07cc,0x0000e8fbe62394b0}}, + {{0x0005391035703ccf,0x000950c7e24d2f6a,0x000fcbb9a9899bf6,0x00075ad3f7f248bb,0x000065027dfc5558}, {0x0006b69ffff3b37b,0x0003645b4431a7a1,0x000afd67967b6eb5,0x000cde69d7e1d249,0x0000d819babc10fc}}, + {{0x0002cfb9db3b3818,0x000e54df0a4b263a,0x00004e61f9c3a2de,0x000324f28d06e97d,0x0000b1adfbcc2449}, {0x000d9397e053a1bd,0x000696daf7076ec1,0x0000ac7abee2be5c,0x000173b0ba1e1481,0x0000d2ae779c530f}}, + {{0x0008e703b9f04267,0x00059c84f17c3e70,0x000b70a0be5b02fb,0x00065cbf4ff35be3,0x000081b3c600b155}, {0x000636a6e124c3a1,0x000a7b496784e76c,0x0003f0370bde81eb,0x00045d9412f8e244,0x00005d42362a99be}}, + {{0x0003ae2a4af76c14,0x000bc8276fe70f50,0x0003a33c6550e66d,0x000f84d1e0c1fcbf,0x00002be231046629}, {0x000743e516ace497,0x0007d36a2262edf7,0x0006ca192ce43666,0x00013e71ac703644,0x00003631cb5b76fe}}, + {{0x00082d4a160bcfa6,0x000558ceb1f2d47f,0x0005a8d25258fb07,0x000c9cef818e8fdf,0x0000685475ecfd31}, {0x000385ae1e9b13f4,0x0004b0508bdbcef6,0x000f1f90de0a4259,0x00081e1ad7ae16ae,0x00005a155efa3f8a}}, + {{0x00007c28034b95e9,0x000587bdc5608ca4,0x0009807e8c93eb97,0x0004eabec24e8d33,0x00001b734d76d64a}, {0x000ce398f668b26c,0x000a541823d5d0fe,0x0009e4e004822cc4,0x0001adf953bc32f0,0x0000a0a7c60c6d86}}, + {{0x000d4470f33e712d,0x000555a87cb04c74,0x000962db43cec1e0,0x0006a98cec0610e5,0x0000971af1641a25}, {0x000c983a2ef4ac95,0x0003874e9d00a044,0x00073d881caa1da6,0x000c8bab972d8346,0x00000747c5a53a26}}, + {{0x0009982a3e25566d,0x000d48e1b8960434,0x000b2d24beef9075,0x000a547c7bead092,0x000099f72fbda21b}, {0x00009315005e541b,0x0007eece3205b93e,0x00062f2f62a7a983,0x0000a63b388ed114,0x0000488b15ade346}}, + {{0x000cd67969d56af1,0x000ccfc58a8b43f6,0x000e703779e0d872,0x00046c301c1509a4,0x000003d1a1318ad6}, {0x000e37e9d0624278,0x000c39bef78c078e,0x000e661424e69c5a,0x000d81d21ec00136,0x0000de1ecb32634c}}, + {{0x000d97a205b9d8b0,0x0004056756d40435,0x000f8210e6eb8f06,0x0009ead5e88a8bb6,0x000070ef12dec9fd}, {0x00095053bcc876ae,0x0007c7404ce34d84,0x000a1db5e12a7533,0x0005acf22b49e1b8,0x0000c1f2051f4bfa}}, +}, +{/* digit=34 [{1,2,3,..,}]*([2^170]*G) */ + {{0x00081b5c4e83d33c,0x00089efd488b43ed,0x000eb4d0fd9f3587,0x000393564a620f9d,0x00006927bdc6c6a7}, {0x0008df79f9e0f036,0x000e9cd7e1a945c2,0x000a348f12868661,0x0008e01cf4e8d0ff,0x0000bd4c28499853}}, + {{0x0006e8c06d75fc1f,0x00064249a89f5603,0x00045e7dd2dcf7bb,0x0002a691dd1d3de2,0x0000578dc4cdbd6e}, {0x0008903df2ce7a06,0x00083c39afac4c02,0x0006404abaee3628,0x0008187c847c3114,0x0000304c0d904e97}}, + {{0x00036c327d02dccc,0x0001ba68bcc2fb68,0x0005e912d5ad0098,0x000cfd5b24b44c00,0x0000c83d210411fd}, {0x0007ec1666fba0ca,0x0006747546353652,0x0006da9c26994819,0x0002b25cdcb1a855,0x0000593426821a73}}, + {{0x0008b33070d3aab6,0x000b3a2cd5e5e4ac,0x000fc91732643672,0x00013ef2eff79b1c,0x000065ca49bf0a7c}, {0x000da59b3efb9983,0x000cd52f13415a8d,0x000f9a5308a5b922,0x0004d77e9ebbab3c,0x00005986e7c256da}}, + {{0x0004cbd8088b454e,0x0006ba9e0c8a63ee,0x0002447cbdb7f32f,0x00019ad377d4186b,0x00003e982abb3702}, {0x000c1e4c2a2a5938,0x00048773f24f06cc,0x00085942372c3686,0x000c8f213b4da795,0x0000bbf1d33f5040}}, + {{0x00087d0ad886aac2,0x000a9771b64503c1,0x0004045ab5c16878,0x000aed907dfc6fc7,0x0000c6360bf9800c}, {0x0005bb5b9c972a3d,0x000dac9a6dba2429,0x000a79aa6c9e6f88,0x000ac1c0ffbf2492,0x0000e29d50b11c26}}, + {{0x000fb68d84d835d2,0x0009661dc1e6b1f0,0x00094f8d7c90caf3,0x000b91f2e5b04675,0x00006897ae285012}, {0x0008a08a4d6755dd,0x000b3991fbdabcf6,0x000bf17e8403ee41,0x000d64a33e343e3b,0x00002c7980e379b3}}, + {{0x000cf4fda79e5acb,0x0009d630215f534a,0x00085756e68b83b3,0x000cb1ac748b2ed0,0x0000031725995d37}, {0x000841ac5ccc2c46,0x000add9d50696735,0x0001754bd7d7dc96,0x000dd54147e410fd,0x00005296e953399d}}, + {{0x000c9a1deb8568b6,0x000020fb3d321e71,0x000f8fb81a35daea,0x00096a88b6f2662c,0x0000d51afe8f4906}, {0x000ac6e51803a198,0x000f0621908081be,0x0006f463ce3d24b7,0x000ee7f27cfd9ddf,0x0000c6865caf2284}}, + {{0x000f169d23233f3a,0x0005d7cb637fe00d,0x000a0cf6c3e32279,0x000bdc7f897c0e1d,0x0000651f5d8d1d6b}, {0x000af191a230c767,0x00025daa5e4add61,0x000abcd7ebd52727,0x0008dc5a753636d0,0x00008bdd37ca70bd}}, + {{0x00027c17078c4322,0x000c977fedb7cddb,0x000290570e1961b9,0x000885fedc2f5cc2,0x0000c3fefca39cbd}, {0x0000a36c2af389a8,0x000d3da71ceacf88,0x000aa846396c610f,0x00090a703977a932,0x0000eb776400586d}}, + {{0x000b3edf0290a8fd,0x0005fb47c387831a,0x0004efb4fcae8196,0x00010ddad7dece18,0x0000cfc53b417491}, {0x000f23c4cb632f9e,0x0005d91f80676698,0x00084180ac42a1ad,0x00026ed116a81d62,0x0000bedf5f9c9013}}, + {{0x0003f0ab2cf89408,0x0007ef948f519163,0x0002653c872b0b17,0x000a04ad28dc3078,0x0000882984a5b903}, {0x0005d0c6a19d2bbd,0x000bb6f782cbb809,0x0009070644b9e7f0,0x00043baaf739882d,0x000012be0ff5b326}}, + {{0x000f28b638a7e819,0x000ec980ddc39561,0x0006f247a54155cd,0x00010022db4a96d2,0x0000d774e4ed787d}, {0x0006e2e078637d27,0x000cee0ae06a1a9e,0x000cfa3541c363e2,0x00098d0493483ee9,0x00006843cb3ef74b}}, + {{0x000f1bc789a283b1,0x000d780836f40491,0x000e5402d72d3ac3,0x00073d9a1c5ea388,0x0000b192421e5cc4}, {0x00099989dc84cacd,0x000ccc6e75b85c0b,0x000191ce2b0a8482,0x00092f939961d03a,0x0000a3bc8663d837}}, + {{0x000c4cdb30cfb3a6,0x00010c9db4c8d7e0,0x000c8d9df6d09b8c,0x00066ce0ba1a4207,0x0000fd495f77c52c}, {0x000169f275264daf,0x0005f57d8362fb0e,0x000ad722280c2b74,0x000c7afdd987f749,0x0000dc229b03398e}}, +}, +{/* digit=35 [{1,2,3,..,}]*([2^175]*G) */ + {{0x000ed8452666a58c,0x000026a9c3c2b0d1,0x0009064084bcb6e0,0x0003ff7c57411c26,0x0000fc20755d3556}, {0x0001c505294dba30,0x00068b7dd31ea08b,0x0001eca74a30ba28,0x0002b9d70ba90e99,0x000094e142ce762c}}, + {{0x000783e979f39254,0x000a6f4c89a7b81d,0x0001bf7fa1efd130,0x000a9e125c2144fd,0x0000b2969045b265}, {0x0009634b9db65b69,0x000173599d8aed8e,0x0003563f335c82e3,0x0008ab4aa7a54f40,0x0000df088ad922c3}}, + {{0x000b066bb3fd30a1,0x000adff0354ee5cf,0x00024e36c429169d,0x000e1d709cf85235,0x000036f4fb31155b}, {0x000af011fbba712e,0x0003706ba1a14826,0x000aea73e6ef0f0b,0x00044df9928b3177,0x00002bf6af33eaa2}}, + {{0x0004f124237b64b8,0x000963ecfd078d08,0x000845dd8688ebe9,0x000324d7b8a70cf6,0x000008fc59cdda4a}, {0x0002b2ba3585862b,0x00053df29386a903,0x0001ec29bb66825d,0x000dc805a5a8db43,0x0000b143a98ea1e8}}, + {{0x00094ce12ae381b9,0x000bf6ccda9035ee,0x00006eaca3a7f176,0x0004df363a657e46,0x0000ae5a380d3cd0}, {0x0008d15ed251b464,0x00008aca5e649bec,0x000f20f071f5d6d3,0x000285f47b3b359f,0x0000d65f03537e4b}}, + {{0x000ba24f111661eb,0x00040105eb049e93,0x00024b578edced48,0x000068e6dc9ba1f4,0x0000f8f66b8983e9}, {0x0004df4d7ed8216f,0x00069e2cbecf872d,0x000e73754bf07f37,0x0007075281d89998,0x0000ec85fbc7aab8}}, + {{0x0000deea5ba5b0b7,0x000dd2d052999a3c,0x000b02d42e6a116c,0x000cb63e9775fee9,0x00002b0520111545}, {0x0006f7d31a3b4ea6,0x00082bbd9b32bc50,0x000b12a97e589307,0x00067168bc5f37e4,0x0000b000c06aa73b}}, + {{0x000bf22765fa7d04,0x000fdd6a537013b5,0x00080db9859805be,0x000ce327a5e29d42,0x0000f53916fb76b1}, {0x000f61f33ddf6269,0x000e1085d103714f,0x000809ee34206238,0x000b1c8c50d4b7e5,0x000099f450e15f8e}}, + {{0x0006051e4c79e9bf,0x0002d66a9fea658a,0x000be7b231394cb7,0x0008fd37f31ed5c6,0x00004c88f374aa6f}, {0x000721f4aaa499e0,0x0005e3fb2a6b0fb0,0x00092851d68b3a7d,0x000913a788097d3a,0x000060e7f8ae96f4}}, + {{0x000be731a3a93bc2,0x0005821adc1a82ee,0x000030efd42bbf46,0x0007bba10b6fa4ef,0x000047aa4c7a7b09}, {0x000c632f60c77da5,0x000a7223523e8b8d,0x0004579cf6ffbc26,0x0000f654f6ff1134,0x0000825653ce8025}}, + {{0x000097ebc1aa2b92,0x000317a0333ab2dd,0x000a0db380788939,0x000612fcf55e7137,0x0000648487f992c1}, {0x00013363fcef2614,0x000cceabf129dad0,0x000276be26239c81,0x000ad34ee761de9d,0x000006a7a345eda6}}, + {{0x00067ba4a493b31c,0x0001dbf7f0264bf3,0x00095914b54f20a5,0x0006abf696e06297,0x0000ddab96e4bf23}, {0x000c70aed25ea138,0x000b01cbbbe74ff2,0x0008544c5fa1d09e,0x00031708fc8c8746,0x000047a670de96b3}}, + {{0x000421e64bcb626e,0x000746dee0b5f133,0x00010346caea638c,0x000ed2f6e7680bb3,0x000006f4098b5d4c}, {0x00014527512a30b9,0x000d5589a59a0996,0x000d0c180f3d867f,0x0004ab9e73254f52,0x0000063d8a3c33c7}}, + {{0x000c595d314e7bc2,0x000b267899ededa6,0x0001ed5d32ee7464,0x000612fcef423c0a,0x000017e76ea89cc7}, {0x000ce1fe7cda917f,0x000a9a893f1627cc,0x000c74f6b12d8016,0x000e60ccd6de849f,0x0000a5817e3e3144}}, + {{0x00041640821ee4c9,0x00037bc619921f35,0x00072879f1583eab,0x0007b1e490caf61d,0x000098ad9f4876ae}, {0x0001950a41157f70,0x0006e8da3a7e1e18,0x00026b95fa9d7e1e,0x000a10963784eb84,0x0000ee4ed6e542e2}}, + {{0x0004cc5ac751e7b7,0x00028d4211bdb79d,0x000de4fc693f9647,0x0000641c72d3d2c8,0x0000b69cbf64f44f}, {0x0000ca2f4bf94e19,0x0008612894e23da9,0x00017d60b1a5325f,0x000b5c7a437f6c79,0x0000be7048726c9c}}, +}, +{/* digit=36 [{1,2,3,..,}]*([2^180]*G) */ + {{0x0009976e1337c262,0x000db73d68e5949c,0x000b768d96faadeb,0x0000697e158614f1,0x00002dfa557bcc4f}, {0x000da17be93c6d61,0x00019504f5b9ccd6,0x000694da124866c6,0x0008c61121353c8d,0x0000c6ca5801140b}}, + {{0x0004a7dd4b79bb87,0x000ae2c878c8f160,0x00047b8e8aee806f,0x000053c4144f118d,0x00002edf52c049f9}, {0x000a84e2127015a3,0x00006cb7cef3ebfc,0x0006deec89051d0c,0x000d7456e8fe5829,0x00003b2818871010}}, + {{0x00060ed9aed9f40e,0x0000732a8c99bd56,0x000c371ea70ca6ad,0x00009ce4978bfb95,0x00005464d0e50031}, {0x0002fdfd9e535ef8,0x000718c9185b1af3,0x000b42488abf57ea,0x0006fa6d7a741712,0x0000e0296a869728}}, + {{0x0009383171b445fe,0x0002a131ad4c0107,0x0003987e89bcf21e,0x000c8eacdfe205c9,0x000063f4153a92e8}, {0x00062a930add43df,0x0002d980f05a7294,0x00006e96862ebb14,0x0006b05f3954e53b,0x0000e1d75ae142cf}}, + {{0x000416e1f017d5eb,0x0005c674e99b8b57,0x000f488a03753339,0x00095dbe6d94c0e8,0x000093a787b8c16f}, {0x00051a2dcc99ccc0,0x00039aa47c1dc3ac,0x000dfd8d5c134b41,0x0001edf28fcdafaf,0x0000d57bd8e10b83}}, + {{0x000fbccf0bcfc46a,0x000e15cffee69276,0x0005d915b3a822ac,0x00076b928ed2fec7,0x0000145c11463594}, {0x00081538be17bcdc,0x0002ea6c3d8ff61a,0x00016c82f01e867c,0x0009af9634e15d65,0x00001437bd32948b}}, + {{0x000d2006c19d4c7d,0x000711b1e976d2fc,0x000f237e8a0f3c43,0x000bb120545ff694,0x0000d10ec4090bf8}, {0x000696cac7cd3e1f,0x000b6f24bfe64f89,0x000af7706ed3714e,0x000c31463eb1d85f,0x0000cbd604eb027c}}, + {{0x000c6c7af8685c8b,0x000d7f8f01aa5f95,0x00074692ad4c1c8c,0x000068144bbe3225,0x0000800347984a4a}, {0x000c6e52eca3cdb7,0x000b7c04d3997c8f,0x0002bc5cfea1db16,0x0003d2405bc82e8f,0x000063d518064479}}, + {{0x0008eddc355363b4,0x000fb8820d6e16ce,0x00061a5084af2f70,0x0004728b7ed4d276,0x00001d3444f1d195}, {0x000a2b438da9649c,0x0005eeb4a20017fe,0x000b19c3d9bf6935,0x0000a5e13b5f916a,0x00000519c159c936}}, + {{0x0001ae92e42e1716,0x00038d41ccf9c257,0x000c8854fcb31ab6,0x0002a0d7f3c576b5,0x00006e5191c26239}, {0x0005a1c6cd5683b8,0x0002e06fe6897156,0x000e2fda6484b028,0x0000a473a25d6767,0x00007ba21df0a65c}}, + {{0x000e49ca70684d10,0x000133e80c3dde74,0x000a5c34d3ae8766,0x000c355984a2a916,0x00009a83eccb8298}, {0x000867caa4ca4c09,0x00002375b8ff9a19,0x0000396dc0208561,0x000e636296328bf7,0x0000c9ddc4d6e6fa}}, + {{0x000c1b808bd98d05,0x00041575f2404451,0x00075d270644b1cd,0x0006bd1907eb3373,0x00006c8bebe4a228}, {0x000d2acc4632b46f,0x0009bfd60242c713,0x0005c754617da427,0x0003dd413065b7c9,0x00008239899af17a}}, + {{0x0003d260b083b6e6,0x000aa6f6a54d9468,0x0002074dd0a3752e,0x000592e8bedc2375,0x000037622fc9e822}, {0x00005136be55d3b0,0x0004324d006dea00,0x000fc02709f5e12f,0x0009e6529486a964,0x00009ba0d0c92339}}, + {{0x00058473a9770805,0x0007bc6a6ab63638,0x00082261e4cf8e1b,0x000806419a5c6c04,0x000017a9ad135ce4}, {0x000d40c056aa7aa0,0x000ae56c61b02792,0x000b19e0c4c7c6ad,0x00067ff19cb178a4,0x000046d5c4fe4ba2}}, + {{0x00026ab121550b37,0x000a5147ce84d3e9,0x000ff722ae4975e4,0x0002a00a8be0f95e,0x00001e4702cdfd4f}, {0x0002acf3cb7b2807,0x000cb8272d7313b9,0x000a9fe5cc588716,0x000e42162c7bf3da,0x00008c008f352a79}}, + {{0x000963f4c8303203,0x0000603203e3f3b7,0x000327afb842c7aa,0x0009b67f22ca0ae7,0x00008e13092c6760}, {0x000fb62757558f1a,0x000157eca8c173b8,0x0003316273cc3e83,0x00023444174474f6,0x000077989cb63c40}}, +}, +{/* digit=37 [{1,2,3,..,}]*([2^185]*G) */ + {{0x00017f4b0166f7a3,0x00079eec74e6ae83,0x000874bfdfbd3e3f,0x0003a3cdb516ace0,0x0000d846019f681f}, {0x000ee5c7c1620b02,0x000d0b63c5010b12,0x00068c51eba68b4d,0x000b5b8c03cd3266,0x0000a6279f76e0bc}}, + {{0x000139f8f5fcda83,0x00048dee5bfdfd8e,0x0003f9f77f3e558c,0x000969a76cbaf4e3,0x0000a4c97a4a1771}, {0x000e84bf6dce6a73,0x0005e3e6c2d1da27,0x00059a6e9ff373d9,0x00062cc115193cd7,0x0000f9b702593d22}}, + {{0x0006fea87baa6279,0x0001672aa6801253,0x0001e5dc958c1fec,0x0001b8dc29b63760,0x0000e3c3c1d6e9e0}, {0x000127b2bcfe0b0f,0x00013a12f50defc8,0x00079b3973510710,0x000f207ccd6cb148,0x0000792f805e8a82}}, + {{0x00084911a335cc88,0x0009ea5913e48c31,0x000b32919563459b,0x0005ac9b920d61c7,0x000005ab8b720242}, {0x00012da8d006086c,0x0009fcf5c0fd2ac5,0x0002138d76ca4846,0x000442efea51d8ac,0x0000b647545f44cd}}, + {{0x000f521e447f2c48,0x0009e04291f0a3f4,0x0005926de81b8da7,0x00002f5680bc467d,0x00004f21fd5b4a12}, {0x00031814e9df3d85,0x0009e9ab8d341d1e,0x00019aa4a1ca4861,0x000366309ddeec5b,0x00009f72f7e9d329}}, + {{0x0002466cdedca850,0x00001a09538c9f1b,0x00011115d140bb71,0x00059eac8ae8515e,0x0000d63ff676f03f}, {0x00055517d234afbb,0x000dce208fc1755e,0x0008a4b5d61c2db4,0x00030efa9859cef2,0x0000dd6d4fce4af0}}, + {{0x000e67f906151e50,0x000f55e106493f39,0x0007cf7b7cea27f5,0x00062ddca1d4e1c1,0x0000c326d122fe23}, {0x000ac337dd35df39,0x00093396dbdf05f7,0x000b7db1c0c3b763,0x0004a87912f5ac03,0x0000dea4b70ec9ed}}, + {{0x00053e453544774f,0x000b4adba2bc5110,0x000e371f5834d0ec,0x0003bb5215d7f7ba,0x0000cfd57c05c866}, {0x000383dd6901b1d3,0x000485587dc3ded2,0x000625f623b49fbb,0x000762cd44a08d07,0x0000ee4d65bcde9b}}, + {{0x000fe5bdf53aad08,0x000564604a673e56,0x000a261a051314de,0x000c90b86ad98607,0x0000b7e021297afc}, {0x00011273b72aec51,0x0005b4f9f509cbf4,0x000484b5713c85d0,0x00095bdda56845b6,0x00003cb1642c3d09}}, + {{0x0004b6e717815de8,0x000027e131d15a99,0x000c023aad995c7a,0x000ced48b46df226,0x0000cfd094df02af}, {0x00043cdced6a8867,0x0003afcabe757bc7,0x000ac9390b7d70ec,0x000a8fba6c9e47dd,0x000020694260310a}}, + {{0x000b3263e8f793c6,0x000e6de3b289a607,0x000915b21a541166,0x000da6944ff2924a,0x00008bea907158ec}, {0x00037b4402928970,0x000e4b768423d85b,0x00013bbbed2a508a,0x0001f4d10bb79da4,0x0000262f48106149}}, + {{0x00080f55464d0ebe,0x000687a613a7d17e,0x000c97dad89d3e1a,0x000be697791260c8,0x0000c2ff220c4f0c}, {0x0004ac2e9e6bc105,0x000827cba305ed98,0x000624fdce3c53de,0x0000ec4bbaf9b283,0x0000e9451cd6485c}}, + {{0x0009f63b7abad118,0x0001e3a46189fdfc,0x0007037b7c7ec3a9,0x00070fc9ebee42f6,0x0000247f5054dac1}, {0x0008f8d397583e59,0x00067c3f8c2efc51,0x0005edcb1e7d24de,0x000efba54832669c,0x00004bba48488c2c}}, + {{0x000756db1761ec84,0x000864b97e551f13,0x00096cc28e53c8b9,0x000a8d72aee3f840,0x00008c361a0d20f1}, {0x000672d8c31190a9,0x0000701855d4a98b,0x0003f4b2a7bc1e7d,0x000bc3942cfb07bf,0x0000bf44a3fc2a28}}, + {{0x000976299da550cc,0x000956baa042eba8,0x0008c2f9db2c1781,0x000a9d7068b08278,0x00000fa414654869}, {0x0009e39d50b693f4,0x000c588e2c5e73bd,0x0008f9f62b79e2a9,0x000c7bb1cb8de40f,0x000015b04ee5ea50}}, + {{0x000137d0d63d1fae,0x000122a9d89f64e5,0x000436309658fc05,0x000a606889487450,0x00009ae30f9b598d}, {0x00010d1818baf918,0x00060b6a0c202ed7,0x0001a6b44e27e9e0,0x0007db9e28dcfb1c,0x000083acb6556ac5}}, +}, +{/* digit=38 [{1,2,3,..,}]*([2^190]*G) */ + {{0x000728dc2c6ff707,0x000f55dc22358735,0x000e277f979d6122,0x000cc6b3f5d00319,0x0000ee84e264ded8}, {0x000afb063cd880a6,0x0005d574af6091a8,0x000de7f423f3ea7c,0x000151acfcdc8402,0x00002d07930131aa}}, + {{0x00083f9dec31a21e,0x00028ad9d573b02c,0x0007be365988c8b2,0x00034d73e983aea5,0x0000968734e446f8}, {0x000ea8f5da6309bd,0x0003f1f1ce169137,0x00044092110f3a62,0x0001b4a82a9ea2ca,0x0000f94739f2b46f}}, + {{0x00065a434a35ea84,0x00070d4412f61df1,0x0008836c33418e0f,0x0009651af1f8af51,0x00002ceef4d530e1}, {0x000ca0b543a1957f,0x0004986cb1235560,0x00098ed30c33761e,0x00097c76624b1ffe,0x0000772f4c000909}}, + {{0x000410ef4f8b16a8,0x000e447b266a56f8,0x0009c87c197241af,0x000b1a8a406b8e6d,0x000003f3e034d42a}, {0x00009a804dbec69c,0x00067bbad05f7f03,0x0008e197fa83b85f,0x000dc106097273ad,0x0000097440f1067a}}, + {{0x000b6dd418e7ddd1,0x0003372f19d6c507,0x00027eb4d39888d9,0x0008846eae26be0c,0x00007b53ed40babb}, {0x000021b2b01ae4fe,0x0006ef488682fc27,0x0005e2d8788462e8,0x00029adee096ec21,0x0000b2fea9bb242e}}, + {{0x00000c756b95bce4,0x0006216da680bbcc,0x0002142525ec0390,0x0002d239162ee672,0x00003132b63c6a89}, {0x0003ff22f3263bf6,0x000c3cd0a1424bdd,0x000415ccbd5b3733,0x0004e9f92eaa8244,0x000063e8924ed547}}, + {{0x000ab35ce7c42d4d,0x000eb2feab100d38,0x000111b459fd493e,0x0005c276056b6d82,0x0000a11dae243efc}, {0x00002785545a7fb2,0x000c20d507e6dc74,0x00066fa58bdb2601,0x000c29f21dfeeb70,0x000014369a859ae8}}, + {{0x0007fa0b311898c7,0x00045d0eac653f74,0x00014d0bce2a272e,0x000ee2dbba5851f9,0x0000a1a966134a43}, {0x00067cea1c8cde9a,0x0008d271abe3e5a3,0x0001615cd9d958ba,0x0000b053ff7eb63d,0x00002280dcf95ae2}}, + {{0x000d566d4312483b,0x000cb43e216f8c0e,0x0000444935179a95,0x000a211c185fec17,0x0000306333a04991}, {0x000ecdb0081a726e,0x00056fa89bbbd801,0x00091b6b90149b0c,0x0003a2cfe9065a43,0x0000dc92787b633f}}, + {{0x000d9e37a6a308bd,0x000f7c2767d3d6d9,0x0008cbeb66237582,0x000d9db74a8bc6f3,0x000094d3f1b9cb6f}, {0x000735bba21f248e,0x00048cd1efb092a9,0x000b03284272ad0e,0x0002249437b69c05,0x00007f047034948c}}, + {{0x00068a9e9adfe1c3,0x000d014e39bb9ae8,0x000fe378f3984403,0x00062885875720f2,0x00003f901e0ea44a}, {0x00025fe3652438c6,0x00063dd1f20bea11,0x000bf7fbdae9ec4e,0x00079bbe740d9ebe,0x0000dbd3ddca2dbe}}, + {{0x00044a43794f8dcb,0x0009983c5c362663,0x0009d10a0dcca923,0x000df27d6b6bbf3f,0x0000320c5cb31d9b}, {0x00028ff47b50a951,0x0001bef03371620e,0x000100153933e3b0,0x0008d6e081bf8599,0x000083be9a0d3a8c}}, + {{0x00043d77613aa81f,0x000f95fe65848a94,0x000b10288801007f,0x000ee780fc4dbc7f,0x000058280d4d86be}, {0x000d82f7c978c385,0x0000bde44d7b14fd,0x00060252fdf1204c,0x0006a5508a1c8441,0x000091554cb11764}}, + {{0x00081ea77b46a081,0x0007b74806997ddc,0x00033f683cf5a647,0x000c6033a8cb3466,0x0000b867e6ba2363}, {0x00011141f60558ee,0x00024f41450e4392,0x000630e8bcdbcdd6,0x000b429fc04601cc,0x0000a7c66d677038}}, + {{0x0008820fbeee3f97,0x000fd9091afd34fc,0x00031f35c93e5348,0x000924064b9be59a,0x00001f37864c7e3d}, {0x00034e0943aa75e5,0x00085b8ff6e402fb,0x000cf0d19a18c9c5,0x0008a6b80f31b133,0x0000c9682db58351}}, + {{0x00085c341dca5663,0x000aa8622aa3b6c1,0x0001b6dfb7de7fed,0x00028869e84d9290,0x00000a02b0eac4ad}, {0x0001daa2fd3cf36d,0x00070f89e59fc7c8,0x000496733d131954,0x00012ae2be8184cd,0x00005f449ec63d34}}, +}, +{/* digit=39 [{1,2,3,..,}]*([2^195]*G) */ + {{0x000ec644cd8f64c3,0x000ff79d7b51c492,0x000c7525658a2d78,0x000016dced1fc51f,0x0000e658aedbf433}, {0x000942e05da59eb6,0x0002addc37220b61,0x0002e7f87ba3d60a,0x000b6e1c311cd174,0x0000473ffef56b01}}, + {{0x000604f692ac542f,0x0000327b91d38303,0x000aaf9bdf079ffe,0x0004fa29f63e6315,0x000099ee566e1f34}, {0x000661fd62191997,0x0006648ce41c8a1d,0x00074d9048c883bc,0x000b1aa065118f3c,0x000013889ee7faf8}}, + {{0x000f697960eb8c77,0x000c72de04d3c035,0x000ad9228f1599f2,0x0001ab192450f8d2,0x0000d48129c2829c}, {0x00085e13a50afc95,0x000713a96ee024d7,0x000fb6d7b2745ba2,0x000a42456534013b,0x000036202676bad2}}, + {{0x0003f8f81a1b3bed,0x0004fe2764a0972b,0x000c4f5f74f3ce14,0x00085b12d0f1cc28,0x0000eee0c0e97f39}, {0x000adc0d39e25c35,0x00007467a0807df4,0x000cf5a584061982,0x0005fff40ebc9361,0x000027729a6922ad}}, + {{0x000398a4a9eb3f0a,0x000e9b99a48fa691,0x0004b5b3256c1dbf,0x0005fdfa87e1b91b,0x0000d639614f378b}, {0x000243ec26b53020,0x000c3ccb4c10437a,0x000e070150275878,0x0003c00e81e4a21d,0x0000c6265c9850df}}, + {{0x0000937b1b76ba6f,0x00045d2026dcca6c,0x000d9ae0a1a2eab8,0x000025c1715e1519,0x00001ad919aaac4a}, {0x000dfb807ea7b0ef,0x000e4ed9eb8935b3,0x0006d08abedf5496,0x0007309932e5ff2d,0x0000314874f15bd2}}, + {{0x0007149a8c25ff63,0x0006482e6569c832,0x00068fc3829bf255,0x000ad56012f5c6cd,0x0000e67e8bd6b982}, {0x00075386ecdca88a,0x000621753a045e3a,0x000db3256f297eaa,0x00005470121e5405,0x0000b9697d590851}}, + {{0x0006a753f73f449b,0x0007dd44fc79efb2,0x000c0dc4d1d1c94f,0x0000cf99f0fbc53b,0x0000747ea0be698a}, {0x000c3fe228d291e6,0x0004e3c129d65218,0x000acc51635b804b,0x0006689ac859b8d1,0x0000c10697df5d6e}}, + {{0x0007171f6bdf1bf4,0x0006bacb0d8fe5d2,0x00096a31b0b77b87,0x0001039a95471d84,0x00006a50dbb7f16b}, {0x0003f977b865bff3,0x00063b1c198c2a4f,0x000702ea6848195e,0x000228191ad08821,0x0000f20b43779035}}, + {{0x000438f0876fd4e6,0x000723d2f383c38e,0x0000934cb45f0c30,0x0006edc03cc2ecb1,0x0000a8f24398c9d4}, {0x000431b65ccde7b6,0x0007c7e76a6ff16b,0x0003484d741e2cd1,0x00044a59c8cf8f4e,0x00004426efde3152}}, + {{0x00098093a69fc01b,0x000b4aa9dfc2e6ec,0x0006f2a557e20fec,0x000fdeacfdbb07f5,0x00001cd6868bbbdb}, {0x0004995986eb9ed8,0x0004bdd0955e247b,0x000c7a20174785bf,0x00080d08f74f61c0,0x0000861a15bdd01a}}, + {{0x0008e44fc94dea3f,0x000eead6a0b01c0a,0x000113cef34c8cdb,0x000ff9a19c384004,0x0000d32fba505490}, {0x00090f6795dcfb75,0x000333588baf58d1,0x0001fc1c0fef01b0,0x000ac94e6d1d63ca,0x00003173f9740a41}}, + {{0x0007e4182997cc14,0x000ca3720c9c5463,0x000de5d4508c5a96,0x00075a38bce01c11,0x00009d623e54dfdd}, {0x000a4680fb2a3acc,0x000e719c25af8c72,0x000a92421cc53bbf,0x000cf2598eba7978,0x0000d61f28c63bde}}, + {{0x000402aba16f73bc,0x0003ccf9b9fc2b1d,0x0006ef7bf2fb3101,0x0007446d51e60e44,0x0000731021c791e1}, {0x00047244fee99d47,0x00068ac5c1ea9d3b,0x000ea9af74bca48b,0x00083a00f5f514bb,0x000051f55a6074c2}}, + {{0x0009fe8662595c2b,0x000661a807732389,0x000d1d43b495d672,0x00065ed6c971d2b0,0x0000518637d43b7a}, {0x00053bad98c99cec,0x000954d39f5b30e4,0x0001ce415ba6e0d4,0x00082337db02a643,0x0000d909c7db6e1d}}, + {{0x000251acb452fdbb,0x0004a0f306506e30,0x0003548d931ee696,0x000f5b00b3e50893,0x00008949a50a4b0e}, {0x00083263c88f3bd1,0x0000cb1d9989208b,0x000d4df03ab147c3,0x0000c5dd6515fd44,0x00007a12f75f72eb}}, +}, +{/* digit=40 [{1,2,3,..,}]*([2^200]*G) */ + {{0x0004f7881fdad909,0x00057d2cf6ab2591,0x000054de5cf638f5,0x000350290bc03fcc,0x000032811a7a8b06}, {0x000b3309bbd11ff0,0x000fb40449742f00,0x00051d26676108a6,0x0000c1801bb9e0a8,0x0000dd099bebf899}}, + {{0x000dd8a58d6cd461,0x00057e6634d214c6,0x0001bc3289cb633b,0x0007e5b1305047f8,0x00002ede0e236a17}, {0x000ca62065a6f4f9,0x000cd7be487b332c,0x00047ed1cc3a47ec,0x000b13e41eb1870f,0x00009e66e5977598}}, + {{0x000a6777b0ac93d1,0x000d68f5e0d7ebd6,0x000f5492ba6e37b0,0x000f3a1516c09676,0x0000e4bf888aac05}, {0x0002ce04df0ba2b4,0x000d1062341bcdb4,0x000acac20935d5cf,0x00000e4a30333382,0x000029438c49198b}}, + {{0x00038be67e573e06,0x0008e084c44bfb28,0x000c1c2c505891db,0x00044b3131137396,0x0000aebfa4039584}, {0x000dce9e56e55c19,0x00029caa46d0ac9c,0x0001fe8eb7148ced,0x000f4c9e10c7efb6,0x0000fd835db8f97c}}, + {{0x0006f56c17706169,0x000d79da9a2d6c62,0x000730e455351909,0x000a79558e6825a3,0x0000d8c8bc093ef0}, {0x00078b6056becfd1,0x00039090b36d543f,0x0004432f933f1325,0x00050272ad499779,0x0000386493c5721f}}, + {{0x000eefa5abea82a6,0x000933fe62d43794,0x0001ef6068dc611b,0x000e6909f1af3728,0x0000af546c899839}, {0x00078c7c977ec238,0x000c3d5c05766255,0x000d1a4c0a8de294,0x0004d462ddaf0f7c,0x0000243fc70cf95f}}, + {{0x000f400b008733a5,0x000d012e1f57e566,0x000509cd0cba0697,0x000d8c4537c2b240,0x0000f989c69a7353}, {0x000c9724c3c2b2fb,0x00084f031fa87dbe,0x000d5d11f90e02fa,0x000dfc44d15c53cf,0x00003404faef8314}}, + {{0x000a109081e9387c,0x0006cc935828a36d,0x00040b015fb9780d,0x0006fa15940332e5,0x00009d7b51ca0f46}, {0x000cd41d6d9f6711,0x0008a1a2ac17faad,0x000201e5fba6c1e2,0x00062af66a7833ed,0x00009d9971a090f4}}, + {{0x000c3a9f327a07f6,0x000ae490937df02c,0x000b3afa5efb27a9,0x000be421451e96b1,0x00007e24de8f1883}, {0x0005d4770869e549,0x0003d4a3856a1ad6,0x00032e880d36291a,0x000fde770a1abf71,0x0000511d0a39e28d}}, + {{0x000d650f8d1cac45,0x000b1d16bda5fdee,0x000abbe46eb99194,0x00076c653b19f71c,0x0000f45af5089b92}, {0x0004c6126ee9d77a,0x000a6c02ca5dd078,0x00032e720f7a1558,0x0003f7161d6c59f0,0x0000e3ffb95e70cf}}, + {{0x0005facc72a4be52,0x00062d8480899b18,0x0007afea9f66de23,0x000c1c9a14d07c71,0x00005bfbfc04d551}, {0x0000ecd4cdf3d880,0x0003647f73c42cef,0x0002d67f78cee2aa,0x000a21c10a7d3d72,0x000090037a294564}}, + {{0x0007987fa9ced27b,0x00037a9e5dbce656,0x0000d8e8c36b2d88,0x0000d044bdeec638,0x00005e6a6b18bc30}, {0x000e9b9592bef367,0x000f7e81b7497ba7,0x000ce596b2b373c4,0x0004cbd84b5e01f0,0x0000cc51c6330bf5}}, + {{0x0007bb84f3815c4e,0x00033aa9017e6ac0,0x00085720addb9f62,0x00083751e30228ca,0x000059d63f65cb75}, {0x0008e777baad2d02,0x0004b42f5d7369e1,0x0007749832cfdb78,0x000d51e25dd53df5,0x0000f80e7cf0042c}}, + {{0x0006bafec695bb00,0x0008f13c78ad4bf5,0x00082abb022da1ca,0x00049e0f9c4b1311,0x00002ea555aae7d2}, {0x00083f25e05d9e30,0x000f70382afa8685,0x000080408e09cdcd,0x000658df072ec787,0x0000a317847cbf75}}, + {{0x0008d7f4d6ee4ab7,0x000e2570c3dc43f1,0x0008c9b2ad3ac8cd,0x0000f0e27e49070b,0x000016709a835a4c}, {0x00052b0916a26b1e,0x000e6e0711779308,0x0006948683cc17fc,0x00055c54f5e3d459,0x0000e0341ac828f6}}, + {{0x000f462060b5f619,0x0003ebd057c2f431,0x000e1bf65a56f46b,0x0001fea48dca6c47,0x0000a38783ed1bcf}, {0x00033a9da710718f,0x00063e0aeaf67a5d,0x00029d1875a77998,0x000732da87314d2d,0x0000a0edc3fb687d}}, +}, +{/* digit=41 [{1,2,3,..,}]*([2^205]*G) */ + {{0x0004849cb198ac73,0x000cdf2646651c89,0x000200678a884a93,0x0004e5fda964ef9b,0x0000c351b8730983}, {0x000ef9fe2c4b44b8,0x0006b326790cafb2,0x00002264a580f6c4,0x0004e2384805210b,0x0000ba6f9e2c2a19}}, + {{0x00034abd3c095f18,0x000e64b76d7139d9,0x0003e698404b261b,0x000b109d2e6970e7,0x000079fb23bde5fc}, {0x0006c72dfd754907,0x0004f1bcf1c11150,0x0005e70073a97d08,0x0002a6d3201d82bf,0x0000f0ac52fe9823}}, + {{0x00001fb319d76820,0x00090a982feeb251,0x00061b344b029312,0x0001fa51c1c9b902,0x0000e008c5bbfd37}, {0x000dd1c0278ca331,0x0006d5aa53b1d866,0x00013a2cf666f76a,0x000836d5cfb77960,0x0000d3a1aadb3521}}, + {{0x000131a567193ec5,0x000a95f6e70b76b4,0x0001eebddaf3c305,0x0008314587bd3903,0x0000709def8c1bbe}, {0x00099830eb2b6692,0x000b675b70295705,0x00064ac164d80ce1,0x0003ab638a7da803,0x0000f431d23de1c8}}, + {{0x000276638235d4e4,0x0007096e3298e781,0x000175bc81c62bd6,0x000d4d4378660c3f,0x0000d04e18957afd}, {0x000160185a8068c5,0x000142b29a8532a8,0x0000d8a3bdb58e4e,0x00003b98a65b86c7,0x0000f0e6f4ee8a04}}, + {{0x00092b73f894ae03,0x0005875f18ce2c24,0x00053cad0f59df3e,0x0002944cb740d28f,0x0000eb585fbf4f01}, {0x0000c8632c7f717e,0x000acf943f4c17da,0x0007c51d2eb8c795,0x0009486ee23fb5f6,0x0000f18757648889}}, + {{0x00011a4e822f0d08,0x0000da8704f83ea0,0x000c6820fbc647ad,0x000bec3b315b3550,0x000063dec3e37e76}, {0x0005d3af017bfc7f,0x0008a76b822901ff,0x000bd0d3b2005443,0x000d0e167fca370b,0x000063dde656f5e3}}, + {{0x000bc15adf7cccff,0x0005efa1e1b075d9,0x0009bc17e81a3e5d,0x000d429c39e44424,0x000037dccb37ea7f}, {0x0004873907fba12d,0x00097a372904da65,0x00083a6c535daa6d,0x0005be3564cfc662,0x000009fa4f71a939}}, + {{0x000b3b56aa39dff0,0x00029f8e4d8cb510,0x0004c4b9f59b43da,0x000c01a8ce31fd9e,0x0000e20be26c1303}, {0x0007182e8ee47c94,0x000b3db981011818,0x000e14ff6d9687cd,0x0005723a520e4da1,0x000029808bac836d}}, + {{0x00046996d16768e9,0x0009d28bf217174d,0x0004e490d9fc4ff6,0x000979e7705a9415,0x0000d96dd291d2d9}, {0x000d9d8ce5d72c41,0x0004b11c714f77e2,0x000e4a03e9d06c5a,0x00028af2aa513679,0x0000386b3c2130ff}}, + {{0x0002d69ea40dc3a4,0x00026ecc018f26a4,0x00070f04adc84ad2,0x0002ece5c36c7b32,0x00006ba6d4790fa7}, {0x000d1c593e58a8e2,0x0000f20c088c6c37,0x0006e86daa239473,0x000038a3be4263cb,0x0000c417d369126d}}, + {{0x00023bb440e22296,0x000213ef4d04cca5,0x00011ec39324673a,0x0008d34f3adf343e,0x0000136d7f23c596}, {0x0002899b053a9270,0x0001ae067ecd7a7b,0x000779cd93eaa266,0x0005ea8549b9c802,0x000061d7940c5338}}, + {{0x00041fcaaa2902bc,0x000924f69ad3e071,0x0003f9ffd539ad79,0x0002f6e6453f9481,0x000058d3c48f75bc}, {0x0006fad5dc64e964,0x00097240e354b332,0x000a1e7a93aafcaa,0x00089fdd1b0903ac,0x0000ceb97675211b}}, + {{0x000de4687032d585,0x00030e2c79e01eb4,0x00004ef23c54f3d8,0x0001b3b7818df45d,0x00005faa9c8b73d4}, {0x0004f6f89b95355d,0x0009e7415c84ced6,0x0000ebad34860d2e,0x0005be8fdb9bd205,0x0000b53e0cd3685a}}, + {{0x000ca5fabfae1ca1,0x000c0a21459b919f,0x00066a4d2937afaa,0x0003318e0ca91c1f,0x000094cc7f333ec1}, {0x000143a8aa116906,0x000ca9b59e08ad25,0x00050860abe40ad8,0x00034bd7d60d9be7,0x0000c53b00926bf4}}, + {{0x0007080eb6b242d6,0x0002db71e246832d,0x00031139dd30bd02,0x000e531027991bbe,0x00008797e91a62e4}, {0x000e20a6b4e185ab,0x000d92d9b707423f,0x000f7811b82f2c67,0x00095c75c817684c,0x0000d53005eb45bb}}, +}, +{/* digit=42 [{1,2,3,..,}]*([2^210]*G) */ + {{0x00049be9d8e68fd9,0x00028b044320e5f6,0x000c33398db0f053,0x000fae66fde9b3e0,0x00002f4209bf6c8c}, {0x000afcc1a739d4b6,0x000f428ab8dee9d1,0x000c6f1d009aea75,0x000aa4b4375fb5ea,0x0000420b560d08f7}}, + {{0x000499c6254dc41f,0x00038a837e7e9eae,0x0000524a77e29392,0x0005f184aec08c09,0x000082b921a7d6f5}, {0x000962e1402cec5e,0x00071a2f30e7493c,0x000b879cb9f17ca1,0x00045edcd783e8e9,0x0000a3d8c153a6f1}}, + {{0x00015e75e0dee6e5,0x00028c628aa2dede,0x00061bb9374f2487,0x0002e083e9c4fe78,0x00006d4822ab187b}, {0x00017cfc59826f90,0x00092408169eb664,0x0009ef885ca26096,0x00038fedf69d06c7,0x00000031f8adc7d1}}, + {{0x00046e60ebcf7262,0x00014231470e103c,0x0007c21094482b83,0x0006ef4f6dfaca48,0x0000e0ace9782e66}, {0x000a9d31f8d1f420,0x0001574944d23246,0x0007f334b1b1e83f,0x000d8113dfa63aa5,0x0000cf8daed9f025}}, + {{0x0008ea800ee11c1c,0x0003f5e3dd7530d7,0x0008c43c5eb053cd,0x000662db65b13ed5,0x00003ad49be7d151}, {0x0008e41b64279905,0x000d207eae1e99fd,0x000abb71e12cf15b,0x000d0dd9ad4f1b1a,0x0000143e74d57545}}, + {{0x0006336c88bdee1c,0x00059876767c3026,0x00073199625f2930,0x000950dc078571c6,0x000088690b3ad552}, {0x0002c2d852705b44,0x00040e09552d274f,0x0006575d1b0bf8d4,0x0006513628beeb98,0x000007be238bf864}}, + {{0x0003049a639fc6b8,0x0009060036250e5e,0x000cc1646e75c35d,0x0007398cf35bd85d,0x0000bcaced2ec262}, {0x000cf1db55367425,0x0006ca9e068be22e,0x0007909c5013dd89,0x000505c7f411cb8a,0x0000757ac98d61dd}}, + {{0x0001f0d1e935abb5,0x0003c54de37a85de,0x0009cebb5defd10b,0x0004be68d9e39236,0x00004d5ef9bc6132}, {0x00041ba74f17e266,0x000818c1dde44d63,0x000d918fdc0a0e3c,0x000a1346d7758187,0x0000687601562ca3}}, + {{0x0003e9cf36658f0c,0x000bb1f8057ec731,0x0006a835ac433ef1,0x00094bc53262461b,0x00008f053993c863}, {0x0008cdfe983c4a11,0x0001f3b7b931ff39,0x000b9045bbf5e816,0x00046b83193c46b7,0x0000e4ebf5db4a6e}}, + {{0x0002a6043a24fe7c,0x000e3fb3492bf994,0x0002fde0529c1191,0x00032cdf66244990,0x0000792a7ad2713c}, {0x0008ad8b737982c6,0x0009421e60e32fd8,0x00083591a7e3a031,0x000455a9b0de4473,0x0000df141eee310a}}, + {{0x000a039e6d6f4714,0x000ed198d12eaec1,0x000eee5ac14b2ba0,0x0004ceabc1a1603a,0x000001f483720b96}, {0x00037964fd03f663,0x0009ad8f3f122ee4,0x000380f183fdb4e4,0x000d163ef267f629,0x0000e8e9670bda64}}, + {{0x000180c207674f17,0x0006c3ae8fdbbc19,0x000aeb71e112e09a,0x0001c7296675546a,0x00009432af25101b}, {0x000558fde2ddec64,0x000f1357753fd5eb,0x000e1158a81392d1,0x00099167a76b973a,0x000016fbbff8a899}}, + {{0x000fdfd0d4a9dcf2,0x0008744ddf129e65,0x0008568667bc29e4,0x000fe29c1a92d93c,0x000073c69058e98d}, {0x000e418cdfaa6b88,0x0002d061c69f69fc,0x000f75e27606bd82,0x000a1ec2d495a06a,0x0000ed3d505ed873}}, + {{0x00028416ab25b6a0,0x00072b1a4523af55,0x000c99e03c6c0ffc,0x00091bab18827b21,0x000060e864890346}, {0x000f90f93c7f3988,0x000b02f8d10b5207,0x000d0f9e39f4a96c,0x0004f55d71cd793a,0x00004f435d37c3a5}}, + {{0x000c55b8e33787f1,0x0005963846734b03,0x00051b9f0ef42f97,0x0007c2ef7304f750,0x00008aca1dc841c8}, {0x00020a72d4bfe80d,0x000c353e732c56f1,0x00037ca16fd823b3,0x00096a41bccfe475,0x0000f6c9c74eb5a9}}, + {{0x00032c7904fc3fa4,0x000587e3636aee73,0x00091d9aa14a23f4,0x000540838659c3f0,0x0000a995e5df12d8}, {0x0003becf3a5598a7,0x000741eaa99520a5,0x00004e03c56534b1,0x0002682ed3dca4bf,0x000016c563b48d56}}, +}, +{/* digit=43 [{1,2,3,..,}]*([2^215]*G) */ + {{0x000dea7e0f222c2d,0x000ba2e651425043,0x00016cd30309d42a,0x000eebc4fe9ddd92,0x00006539c7ddf87f}, {0x000a57c432ac7d72,0x0000127fda1003c5,0x0000698de72692cf,0x0003b1cc28c85f28,0x0000331fb469ec28}}, + {{0x0008eeae457a4773,0x000bbe6ddc05a015,0x000c41671d19857d,0x000d588326522418,0x0000ffdfc7e6c2c0}, {0x000525426ee7cda3,0x0009af02c3a83a3a,0x0003bbfc8341b086,0x0006917023bf4272,0x0000d15002a44452}}, + {{0x000b2f687500b96e,0x00064dcd9425c961,0x000615433795510e,0x0000282308172978,0x00005d0145545445}, {0x0003302bf690cbe3,0x0001431eca675bd1,0x0008038a444e4883,0x000f0243306bc72b,0x000051d151eef57b}}, + {{0x000324c85edfa308,0x000407d4f3da5ef7,0x000b50c862597655,0x00096bb52f5bc0dc,0x0000f6927b0c832a}, {0x000e1ba55f2f94c5,0x0008e44b45fad08e,0x000aa455d6a996f9,0x0001f79133cb8da8,0x0000d0721ecc58dc}}, + {{0x0004e1f9a8764417,0x0003a47a818df3d4,0x00003edde82bc0c1,0x00025fc3ddc11706,0x00007163f2e7a25f}, {0x00002caa3bfaa53f,0x0001f2256982b54c,0x0006f37dcbd1b250,0x0004a4d4e1728c1a,0x0000e36c214714c9}}, + {{0x000e7e9262a35393,0x000d3670d59ef3ca,0x000c5e1b978a49d1,0x000c1c07de0f63c1,0x0000072c30c99cb7}, {0x0008a5277c850e61,0x000f0f6a3de61d27,0x0002ca7ad84f15f8,0x0004b836a8bb4559,0x0000912e3eef4d42}}, + {{0x000e2d490e317342,0x00065fca007cc1ff,0x0003f77e891b1f12,0x000c883459b1d0ae,0x000062b051d66425}, {0x0008f765c51e2741,0x0002204e6146cf5c,0x0004046b5997481e,0x0006bd5fc1198bd8,0x0000cb0a6bbf7f7a}}, + {{0x000a92079e5fb67e,0x000a90aa725e6ba7,0x000f5d837e1331fe,0x000e207080ccf57d,0x00004cae01e5ff72}, {0x0003ee60412a77db,0x000c2f449025d924,0x000ef5a3106ff7ca,0x0007a80e75f7cd23,0x0000c957822bddef}}, + {{0x0007ad11b7f30b08,0x0005b629dcf9c473,0x0006ae160525ab2c,0x0006e0163f4cc118,0x00005076713f3e6b}, {0x0003180f6998bcf4,0x000371c8d8d8d9be,0x0008c005493d91da,0x000768b902ce661b,0x00007e7924db4a8a}}, + {{0x0008086365e668b9,0x000a1abda5fbdc98,0x0005f1fbeada8dcd,0x000fc32c146b4c25,0x0000cfcde2a5f34c}, {0x000453e7e85d1e48,0x0009792358b5acbb,0x0000823ff9ca0967,0x00011d95fc2d9624,0x0000d65adf78c11d}}, + {{0x000fd177e19a46f4,0x000746161156323c,0x0007d33630948a7a,0x00079d10d06b977e,0x00001c47ec1e7025}, {0x000998e59e9260b4,0x000406c242609455,0x000bc3744c865e44,0x000149f93021ec13,0x0000981994f0d92a}}, + {{0x000230cb0ce1c552,0x0004ebbfb6078cf7,0x00016363b5b534d0,0x000e82ce1ef1130e,0x00007e0aa7ad4999}, {0x000ac2d79362c410,0x000091bb6cb0ce1d,0x00023df2467920c9,0x000f281e648d6322,0x0000f7d9eefe32e8}}, + {{0x000f264d66f51c09,0x000acd9ccea59766,0x00021e232644317a,0x000737139b37bcd7,0x00008bdde0c49daf}, {0x000c758165166bd1,0x000592802108c2ec,0x0007aa66f0951a28,0x000a27d39fbf2499,0x0000a2f6862eb62d}}, + {{0x00057f10296f4fd3,0x0003ba51b4367755,0x0009508051dca76a,0x0007f1c3e98f60fb,0x00001ff32eab31cf}, {0x0007bf18d2c714bf,0x00083e9d2aca643e,0x000dc2d2364b5c33,0x000b9ab9fd9ccc6a,0x0000c2397edbc721}}, + {{0x0001fc764465367b,0x00047b098f57ab65,0x00082376fe438701,0x0009285a91d519d3,0x00005afdb0b03cad}, {0x0001875138d55231,0x000e0aecacfb457e,0x000484f49a92beca,0x000c2af762f6e811,0x000014b5c86eda16}}, + {{0x000f39afa8338349,0x0002163285626943,0x00070fc102295172,0x000e6cf1d63dd541,0x0000f5fa5903ecc2}, {0x0008725e77d9a3b0,0x000a6384ebe0b66c,0x00045e24a11235ce,0x0003b106a8c11858,0x0000137b286ebd09}}, +}, +{/* digit=44 [{1,2,3,..,}]*([2^220]*G) */ + {{0x0007d6ac42bd6d29,0x00082b1f96aedb56,0x00043b28e6df8646,0x00023f7efe5b1a48,0x000061bbb05f379b}, {0x000f5f070a6a26b8,0x000cb28e6e39b6ca,0x0005fc8d370686c0,0x000dc900da06cf89,0x000004d88113363f}}, + {{0x0009ce74462007dd,0x00047cb5f5b763b9,0x0005edde7b8ab48a,0x000fd9cec673d2f5,0x00001567f755cfae}, {0x0001b6b0887bcec5,0x000e9178f3c24638,0x0006266cb694497c,0x0004130e6525e31e,0x0000931de26b97d6}}, + {{0x0009da11f17a34c7,0x0008b35a145614e4,0x00050363b5420ab3,0x000b6e476372412f,0x0000b15d62433fab}, {0x00040b1e274e49c4,0x000456b1860aa0ef,0x000afe5a45cf5074,0x000e9a96583fbf66,0x00004240511347e3}}, + {{0x00055021a93507a4,0x00074d3c06cf142b,0x000ec3f40b4cd118,0x0003c29f70e76a91,0x000084e81ad8e755}, {0x00087b5272e9d6ec,0x000506ff514a830f,0x000192a8eea1c93e,0x000359a7cc2adcc4,0x000077e27e302f45}}, + {{0x0008b1e48ac28403,0x0004bcba9477b535,0x000946b431831129,0x000819aa58f990a6,0x0000098baf9cab41}, {0x000c1584198da522,0x000bf46bfd1b66c4,0x00036a908ab4fc17,0x0008380f0a4c3cbf,0x0000ae9e34b78cf7}}, + {{0x00040ec0ccced589,0x000b7da44f9845eb,0x0001812c625cd4b9,0x000650b3e0645887,0x00009f80d55a6cef}, {0x00040c9ce6dc1532,0x0007b86655215713,0x00007014d138d511,0x000b918cdb45bc4e,0x0000f34bb38a4b60}}, + {{0x00099e84a34f239b,0x000c090402d54174,0x0003aa83215fdb83,0x000db1075f46bf43,0x000061e15b013215}, {0x00059d4a127f89a5,0x000bb7e816daaabe,0x00018b6925d541e0,0x0000265aba0659a6,0x0000532773367266}}, + {{0x0009cf2d0c051995,0x0002aae784548cda,0x00072a182502fbc2,0x00037270bda9dff5,0x0000f9b71b8b158b}, {0x0003a592b82dd077,0x00052523032ee0f3,0x000505a327630273,0x00009f0fe1a721c4,0x0000b6e3e8367964}}, + {{0x000155d3f6effc78,0x000f1c90f0c7023c,0x000ec2c5d1fbd69f,0x00027365d7da8abe,0x0000813872c57e86}, {0x000c2c655f5e228d,0x0008e0923b419f3b,0x000a307ca1148286,0x000ee495d75c741a,0x0000a92c2584f24e}}, + {{0x0007732edc665d13,0x00017939ef1b2635,0x0009680899fb5b73,0x000c524db720fb94,0x00006f75f2c63138}, {0x00093ec48d3cb97f,0x00047d261726f8b7,0x0005c4ffb8dff1d4,0x0008700b65791b88,0x00007c79e2ee1a3a}}, + {{0x0001028754c92e1a,0x000a2f0fef3408dd,0x000f55919ca90b57,0x00086a7a9b84ac8a,0x0000a95e0e28d936}, {0x0007315167021a4e,0x000940d5ff984673,0x00092e7066cb6a0d,0x0001a60cc4801a10,0x0000dcab23b1c5e6}}, + {{0x0006356ea37ba9e7,0x00049afff55db4c6,0x0006cc8621adc841,0x000ab680080ef959,0x000056c85b8dd647}, {0x00094aa1db9c2153,0x0000f013b1a5c9db,0x00086c9032dd36db,0x000884ae6ac61c42,0x0000fd32f88f76cf}}, + {{0x00090fca06d107eb,0x000d076611377f12,0x0007b4b38697261f,0x00012f6bb5be4e94,0x000049826b6ebb79}, {0x000dfe85ba8bffb2,0x00005e3fa8e4019d,0x000bcfe7fb1af790,0x000aea52e1bdf201,0x0000ed3ca8ff1169}}, + {{0x000da8cd745fff18,0x0005e9b9924e3bef,0x00051138170b9e9b,0x00053525df48cfd1,0x00004f93fe3506bc}, {0x000c5a9b279a6c36,0x000478f96132aa42,0x000b6aea5651da6c,0x0002a250368c8b01,0x00004e44c480c786}}, + {{0x0009947d9de99a88,0x000d493477bde17a,0x00019e287c2e61b2,0x000134d7f684d41d,0x000043c21237e358}, {0x000e2e904f7e8aba,0x000915f27aeee2d3,0x0001858c4bf93ffe,0x000dbe89830d1d7b,0x00008f449652106a}}, + {{0x0007bc035d0b34a2,0x000b6327c0a7e341,0x0000362d1440b386,0x0009436fb7262dac,0x0000c41114d00cdf}, {0x000cef1ad95a0b12,0x000847d543622ba5,0x000e486c9c09b37a,0x00029706d6cdd201,0x00000477abf62ff9}}, +}, +{/* digit=45 [{1,2,3,..,}]*([2^225]*G) */ + {{0x000dcb3292a92874,0x000637b092c7a004,0x0006c0605ddc15cf,0x0007afc83a846480,0x0000a68df707db99}, {0x0004e4505bf7dd0a,0x0008eccf7f8c9c13,0x000b5f8afa4e63d3,0x0001cc06e6517f41,0x0000a8b93434d7bc}}, + {{0x00064717af715d2e,0x0003f0134a96c417,0x0001ec956e2f7f59,0x0003034c1873efa4,0x00004e7b4f757821}, {0x000ff9788d5374a6,0x000320823d5be5c8,0x000ee8fe22b915e6,0x0006518a6bc755b2,0x0000657624d47112}}, + {{0x00000e07442f1d58,0x0000e6e0e3abd6f8,0x000c64047475607d,0x00083d02807f16b7,0x0000858e1e427498}, {0x000120b8231ee10a,0x000ac38a1ece5859,0x000aa73a41b80e7e,0x0003ac2b72525ac6,0x00007cdea3e24442}}, + {{0x0007b11e51732d26,0x0007c538fc0e5747,0x00039eec5dfd6eb2,0x000c56fc43b0cc3b,0x0000af127792b36c}, {0x000852d06c425aef,0x000b6c221b9b70b0,0x000826d9c6df92f8,0x0009c27c8d4f9ece,0x000059aba7ca4935}}, + {{0x0002cf152bfda056,0x00090197b98cd2eb,0x000a1726fe0e4c4e,0x000e3cbd35076cf8,0x0000c06085b8db11}, {0x000c4d74463ba14f,0x00021030238c15c0,0x00027536d9d292f8,0x000c1d2311ee8b37,0x0000eea86f0aeaed}}, + {{0x0006054afa05dd8e,0x00011caf119ea7f9,0x00064bb5926dfcf2,0x0002b8020ef2e305,0x0000f4dca5141cb0}, {0x000838a65d306723,0x0004cd657e86cda7,0x000d595c88b08d53,0x0008361c5b439546,0x00009b58725725cb}}, + {{0x00053931a62cc262,0x000630c0e052fda8,0x000c633f323c69b9,0x000d488227df15bf,0x0000ac788483bae7}, {0x00078f9187d073d8,0x0009167f807d4878,0x0006e6d8f6c2be91,0x000a42f65861d833,0x00008b8974d4e528}}, + {{0x0002c2e421d3aa42,0x000cc84fa840c37e,0x00054e41cf926407,0x000643f8abc03d14,0x00006605ecd5f7af}, {0x00041a6d6a5eabf5,0x0003d16b668e2423,0x0000101021edb84f,0x000d8c8836edb804,0x0000b337ce7e45e1}}, + {{0x000a2dccc78cf662,0x00044fdbff77666b,0x0008d4668b301817,0x000a2a6d4dd0db16,0x000059455d03dab3}, {0x00064c5cde3acec5,0x0004c3adb276f585,0x000303f657714192,0x000f7b027d725d8a,0x00005deb6ca36f38}}, + {{0x00005d73272d8383,0x0009ca6295c5864d,0x0002fda32e22924f,0x0005445189593f6c,0x000030d7189e184b}, {0x000a62cbde1f7140,0x0004e5cb1a6379ef,0x0001c833235771c9,0x0008542f4826b864,0x00000a894fbc8cee}}, + {{0x000cd0a1058a3184,0x000538053a9adcda,0x000c68de2369cf3f,0x000d9f86c3de5031,0x0000653a5767c4b6}, {0x000dd5aaa4e5c975,0x000167ab3c741688,0x00065c2835be80aa,0x00009120cefe7cbc,0x00007f95f1356867}}, + {{0x000b6de34eaacda9,0x00079ba0f1dec240,0x000438e55d9e116e,0x0002d73be45ec779,0x00001787c9e26f75}, {0x000532bf129ac2fd,0x00078a36e22c897f,0x0009fb8f3d307b7c,0x000b27c194067574,0x000014f95d0e57fd}}, + {{0x000360416df4285e,0x000af0c56ae21625,0x000c5cfc3b0c9bab,0x00005593032b19cf,0x0000497e5c3e9752}, {0x0006bb4164bda960,0x0009a0b74da11209,0x0003826ba1ee4241,0x0006608fc3624340,0x0000c8f0069dc09e}}, + {{0x00074a15b0ec6f5e,0x00037289b2b8c44b,0x000d6fc7347989fe,0x0000aa945f848458,0x0000c362a70d61c7}, {0x00098a7b3a8ad418,0x000ffb63db51070c,0x0004c35f473a20fb,0x000dca6d2c2173f4,0x0000a56149e1acc9}}, + {{0x000c36f35d33ae72,0x000330bb5a94a395,0x000afe84b200ea12,0x00076a00c789bd0b,0x000043ef52d29192}, {0x000c577e23ae233d,0x000ed460d1ec3934,0x000fa76a4b93807a,0x000490e72a53b1f8,0x00008914cb193ca4}}, + {{0x0006b86d23ddc820,0x000c7e0143f04c07,0x0007af2c503fd344,0x000a4fa95362ff31,0x0000add3db7e18b7}, {0x0003e3f8260e01bc,0x000494a1cc919c67,0x000f2e433fbeb49e,0x0001ead1351bf292,0x0000755e7ed45114}}, +}, +{/* digit=46 [{1,2,3,..,}]*([2^230]*G) */ + {{0x000db47f23206d55,0x000fcd2601522bf5,0x0008ff89a2f6d341,0x000457c7b876533f,0x0000157c30c878fa}, {0x000c5c52d4fb936f,0x000bf6518cdc7517,0x000847a64ef22f7a,0x000a88eeb483e6bf,0x0000508455982e0f}}, + {{0x00059d8df7304d44,0x000bbf210e8eab96,0x0003fbd60b71bcf1,0x0004de69a2438bd7,0x0000595cd1f9d11b}, {0x000329a4835859dc,0x000cbdbb6e569c0d,0x000928a4e4a0f0d2,0x00015406038e5edf,0x000094296224f5ad}}, + {{0x0003840a70c6ec41,0x0007d031119508a3,0x0008ab2029e8819f,0x000a27dd209d9670,0x00000d7c4e7de943}, {0x000b317a29b49a1f,0x000256627d1f372f,0x000df39ec57a67fb,0x000f170912561e7c,0x0000a3ce6f35f7c8}}, + {{0x0003462f23f2d925,0x000d10b940789121,0x0006cde206cab71b,0x0004bc1bdd0a6317,0x00004c9b20d3e4d5}, {0x000d8aa9f2ac02f8,0x0006a06eedb03cd2,0x00008643403f8e61,0x000db947f68e1693,0x000031469c612dd3}}, + {{0x0007465653f3c5f5,0x000ea040feb1fe7d,0x000b7edfe283dd45,0x00031141fe599bf3,0x0000ff039add0379}, {0x000995b4e96fa49d,0x0001d3e25094bf76,0x000c83f742640b6b,0x000ac2bb096341c1,0x00002bec885ca560}}, + {{0x000df248f9813540,0x000c3588a2598521,0x000a0992c587e23e,0x000407cbedf281d7,0x00006930a5538961}, {0x0000debbe5bbe21a,0x00048491817f0932,0x000065160a7ffa5b,0x0002a946c8b4d909,0x0000c4f39939ff6d}}, + {{0x000b2a3cc53da664,0x0001b17a9b4e2e4e,0x000e05b2c04708a7,0x0002019bfdc7b20d,0x0000cdc9aee8907a}, {0x0008dfc6c475566e,0x000a67be1691e5cc,0x00005c3fd2b83cbf,0x000eaf895833a74c,0x0000e938a7323b0d}}, + {{0x000a1583ae9c1bde,0x0008037ce2407aa7,0x000ab38b4e0af6d9,0x0008ca054342d928,0x00008b75007ea1c9}, {0x00086afe02358f2b,0x00063a921228efce,0x0001c67fc31b8b85,0x000d58552a19120a,0x00004069ea593aea}}, + {{0x0006205c6ffcfe64,0x00066a39418a3b82,0x0008521fb2eb3125,0x00061584b4a9e1c1,0x00008614dd91b610}, {0x00062bbeea7475fe,0x0008c8ead16204c3,0x00010a876916ab96,0x000ec38a7975bc03,0x0000a4e7d12ccc77}}, + {{0x000d6e27fa03cb3d,0x000a3fdd7d883232,0x000cbfc5ddb938e5,0x00080e34c1d2cd2c,0x00002f45c137f3a5}, {0x00020b57883e6142,0x00089e7c5f265926,0x00067e1e35fd27e6,0x000aaef39e45a915,0x0000cc71d2d64d8a}}, + {{0x00093c706ba8e6ff,0x0007223deffd6ef4,0x0002b5a4f05c07bf,0x000e9bdebf9b4d9c,0x0000958147f1d038}, {0x000cee03e5561c4e,0x0009994a6afc5af5,0x00072168b8d0b5a7,0x0007fcbde22df137,0x00005d249c6b8409}}, + {{0x00090cde36d07576,0x000179a293824a90,0x000b48ddff722d7b,0x000f439b7fb04c04,0x000028ad2a84be16}, {0x000bfb520226040e,0x00007104b6c4cd3f,0x00003c1886c34ecb,0x000aaf50c0754ec9,0x0000c336b090d23c}}, + {{0x0000b4295c69248e,0x000d1ed9030374c7,0x0008cc87a8813259,0x000a94c3e330684b,0x0000689371cf11a7}, {0x000bbf7fbbbc20ba,0x000cc5f9a6e252bf,0x000413e6d73a8543,0x000031c7bb2fdd7e,0x0000066b3f065cf2}}, + {{0x00062a21e206ee56,0x00002c49a633473d,0x000f6b2c3f1e2748,0x0006ea27ab956ce9,0x00001830b48c2b60}, {0x0006846e78e815f7,0x000edc02082a67cd,0x0002ec365fe40139,0x0006aae2bbbfcb95,0x00004c11642db983}}, + {{0x000b89c44f489710,0x00076d660683cf61,0x000d431bde2d700f,0x000f4a72ef285cd1,0x0000593b24e9bdeb}, {0x000bc5b0561f8a1a,0x00000a16f2564084,0x000f6d27784ce74d,0x000dfdfcbc79d309,0x000094fe2fee139b}}, + {{0x000439e558df0194,0x000a6c712b279f51,0x000185a24230da4b,0x000f50118919e355,0x0000dcefcddc4b78}, {0x0000fb2a47d4c5ab,0x000f030e009ea7d9,0x000eed27355ac9ab,0x000faf4d2fc35974,0x000072d824d8bea8}}, +}, +{/* digit=47 [{1,2,3,..,}]*([2^235]*G) */ + {{0x000b2b5ef7d92893,0x0007e97f015a549d,0x0000493b62480d4a,0x00033131d5590bc4,0x0000a55b52e9f780}, {0x0008115309eadb09,0x000a02e5c62540eb,0x0006a3d5adea7de5,0x000d60d4d631f0cc,0x0000d5e9d7d23e8d}}, + {{0x00060411e84e0e5b,0x0002fea34c931968,0x00073a732a5db84d,0x0007c049d5bb1970,0x00008d2fe571bcfd}, {0x0005f36f3eb82fab,0x000c4dff8b584577,0x00074c1108cb20cc,0x0008996659b65f83,0x00008b4a422e30c7}}, + {{0x000ff87aedbae9f1,0x000926880a54c925,0x0004d0e717daf0eb,0x000cf58284ddf59c,0x0000581cf93416f8}, {0x000a8873ac1f4527,0x00098b6aeffe3eec,0x000fb8dc3b417fce,0x00040035918046ee,0x00003d318ac72209}}, + {{0x000cda3af2ebc2fd,0x000cfb4efe24c4f4,0x000cd10b1a0af843,0x000e0383b857c19c,0x0000dc9d1ec614d3}, {0x000c8bb62771deb1,0x000a81c5aa817bde,0x0002391ae829277a,0x0004ca6af18dd683,0x0000740f316d71a8}}, + {{0x00012d8e12b31f8c,0x000b577736e6dd4a,0x0008935e8577e29b,0x00086c6353722ba8,0x0000a1d3729c15f2}, {0x000b6a239a3e0358,0x000f53b03a9f86c7,0x0000d536e6e5250b,0x000831f9d98930fd,0x0000c4cbbac7a0c3}}, + {{0x0000910cab91f1eb,0x00039d1cd2162d50,0x000d02252bedd9e4,0x00017a2634b74fed,0x0000d60f8e1c2586}, {0x000537b9e05614a8,0x000667af5fc5d8c7,0x0002bd926fd26c76,0x000fc78660b58158,0x000070192452cf07}}, + {{0x0006ccfaf64ecb6b,0x00069bd72775afa2,0x0000f695ae6054f9,0x000fde0bcbab5b14,0x0000c71b4a59348e}, {0x00052becc96d9633,0x000f2e5d9018fc2e,0x000568771150abf5,0x000f838d182fa604,0x00005b4c061a0339}}, + {{0x000e99aeeaf8c495,0x000d1e24d7288928,0x0002b156cee7aa73,0x000a1cfc5007c2e7,0x0000fcf57c63d408}, {0x0009e39b6057604e,0x0000e2868bbf9f71,0x000103e2d7d343c0,0x000ea14cca254b7e,0x00006eb38aad131b}}, + {{0x000a04e5f40ff526,0x000f9cd2914ac624,0x000d3bfd63611d7c,0x00063a57e8b42b1f,0x0000cde40fe5a850}, {0x000c449178b7e5bc,0x00006972cc137811,0x000b461354cb6093,0x00056e3579125e33,0x0000a102ef848a4e}}, + {{0x000e3520a981b0d0,0x0003bd1a41a40ba4,0x0009fab9c1c354cb,0x0008d51aabaa3adf,0x0000701a7d153c41}, {0x0007cefdcf2b9218,0x00033cf48061dd1a,0x00025cce66ceef0b,0x000e339083b598de,0x000090a54c8690a5}}, + {{0x000956640ac1807d,0x0005b4da0b1ec535,0x000b82421d4c1e56,0x000dfff4b33f97e0,0x00000bd23184b41b}, {0x000b42e147b72e1a,0x000f5777104c53a4,0x000fb530df8d39f5,0x000fdc96e64e64d3,0x00007a6ba67f6074}}, + {{0x00018db4f6d01b11,0x00027f11e8a04057,0x000591a3be73c6bc,0x0005319c11bb8ca0,0x00002d09a5a1acc4}, {0x00074eee7de13f4c,0x0005444fd682cbf1,0x00048af70177e2be,0x000b7ba5f574cb1c,0x0000e5966935961c}}, + {{0x000e84ebc6fab9f1,0x0001b80f6474989f,0x00002a1bce70ce6b,0x000fd3ae9ff3053b,0x00002ef4866a9c0a}, {0x00057f9e3411a268,0x0000fb485b9822d9,0x000e201190b41d88,0x0008e0020e56d04a,0x00001e3d01fb2852}}, + {{0x000ed6c048752a14,0x000e601341b4c59e,0x000c6b09241f2702,0x000b232e35903b9d,0x0000291aba85f5b5}, {0x000aa70a653d61da,0x0003af2eb51e8173,0x000b93f8fd1b648d,0x0004fd91b7ce065a,0x000055408ef39e2f}}, + {{0x000ed0985e341605,0x00032a03cde21fa4,0x00084df2da26d7dc,0x000107cdac0848fa,0x0000e9a28d66b697}, {0x00004d914ea0ea1e,0x00075ffe5520a880,0x0009b139ca8d1542,0x0008606f422dae63,0x0000edccc0eb4b5a}}, + {{0x000624f8be762b49,0x0000758e3413b33e,0x000d805fa2a9ee4d,0x000fd7068e636967,0x0000848949c0db8b}, {0x000d7e5d23a84178,0x000d73e29da55308,0x000ee471f892f3b1,0x000089495c139e3d,0x0000631594e5757e}}, +}, +{/* digit=48 [{1,2,3,..,}]*([2^240]*G) */ + {{0x000e2ea1f095615b,0x000664e68c331083,0x0008818be0a28ad7,0x0000ccbbfc02523d,0x0000585113ba3585}, {0x0005f0b30df8aa1c,0x000b8ab7e3ac7d93,0x0002f00cbaddda07,0x000f6bd2c3429955,0x000033ed1dee909d}}, + {{0x0000d483e07113c9,0x0008ed8b63ae2dc4,0x000684c2b6e4a5d3,0x00026bc582a94b79,0x000032b33d4f22da}, {0x000f6510dbbf08dd,0x000894c23a52f534,0x0005bdc9b211d07c,0x0005573eeece0fee,0x0000f178169c7015}}, + {{0x000905a83cdd60ed,0x0004d1170184abe7,0x00023642a50602fb,0x000aff989886cdb0,0x0000568d09176e1f}, {0x00022c70259217fd,0x0008f43141e45b19,0x00095f86e93831cd,0x0008280fca35870c,0x0000ec2057b268ae}}, + {{0x0008925913cc16df,0x000cf1a26f5a568f,0x000f499ae18bc5b6,0x000e83efa413bef5,0x00008835dedb3f0a}, {0x0000bd865a40ab05,0x0008c94b377eb6e6,0x000084a696559643,0x000de06cd8562592,0x0000ce433b99f23e}}, + {{0x000523d42e06189e,0x00006e3aff13860d,0x000b20650bf07794,0x00000c2b616dcac1,0x000066dd6d201313}, {0x000fd67ff99abde3,0x000097aac50dd4a0,0x00046b2d7c990355,0x0002aed22ecf8b7c,0x0000333b1e86abf9}}, + {{0x00065e784d6365d8,0x000f0f759fb8c0da,0x000e81930bcb7443,0x0008aab5c712b17a,0x00000428dffcc6e0}, {0x000afefa4faf8433,0x000dcfa9855ff19d,0x0003ac7ceced8538,0x00071df0ac409cbe,0x000058c1fb6b82da}}, + {{0x000def7be42a5821,0x000055046be6efec,0x000e8dba9d3fc608,0x0001ffb9af13c809,0x0000e6c984774149}, {0x0004925d30c31f70,0x000aac2a21223b57,0x0000859e7b7eb72b,0x000942776a0dacef,0x00006fec31421900}}, + {{0x00094b07e50122b3,0x000b1af07ca53247,0x0003fc97bdd744f8,0x000d9d00a12f08d6,0x00009650f1aa6626}, {0x00047f71fa38477c,0x000914dc124f101b,0x0006eb58a3d815f1,0x0008865569ae95b2,0x00003cde18955fb1}}, + {{0x0002fbbf4737f217,0x000af209f5ac7ec6,0x000f9adbed8dba5a,0x000767b4b5d7a9a5,0x000007d28f8161dc}, {0x000460bcaa999eab,0x000c6c92e4cc7711,0x000d4bf2dba7b174,0x0002788c4bab6618,0x00008f0c9819b8bd}}, + {{0x0008932790691bf5,0x0008b6b736ae9d65,0x000d63b6eed61058,0x00088f212c2f04c0,0x0000cf06fd6163d4}, {0x0003facd9588e411,0x00021b93257e9736,0x0007acace1f9bf76,0x000ecf99d1ffc466,0x0000cf4a1aa1a061}}, + {{0x00075b2c0519a238,0x000dcf6952e328d6,0x000294a8a9ebf94f,0x0003f5728bb767a2,0x00005512b4e7e0af}, {0x0008ba899b16a0de,0x000bda7548a71895,0x0006be61595c2430,0x00074bd30d1b10a1,0x00003ebbb9865bfb}}, + {{0x0003f5eb2e636456,0x000724c8423207b5,0x00014d5cfbe57e54,0x000aca7779c21672,0x000017969cd629a3}, {0x00068cd8a7017a0a,0x000a1e9b7ee8d176,0x00016177677b4d19,0x000a71b8fd0e939c,0x00008c4f4f075968}}, + {{0x000b865d2fdca23e,0x0007ec8ef89581ee,0x0009056145a15ee0,0x00019a968fa10a01,0x0000ff5b8f0680ee}, {0x000cabbcb1c8a0ef,0x000cc8c838f9f0c0,0x0004a14c02e1ee9c,0x0008e41587d8b88a,0x00006f278971ff69}}, + {{0x00034b3bf44da801,0x00094ab32e66519d,0x00078a000283834f,0x0002f65e60879762,0x0000e62960e72731}, {0x000b27be6901c550,0x000824fdbc1f9b87,0x000acc27d80e7853,0x000b5abbbc09512f,0x00006394239ac143}}, + {{0x000646e9e2fce99d,0x00004e80857f9c4b,0x00043b52a68a2108,0x00084236d54e4436,0x0000e8d6d63dd8eb}, {0x000156342146a0a4,0x00021eaa36227032,0x0001387878ba826f,0x000d36e27a58bd86,0x00003b6c03c50281}}, + {{0x0007a952f41deff1,0x000ad63b89b702b3,0x0003ff9510e44a59,0x000af4573257dc14,0x00009c02205e752b}, {0x0003069c4b7d692e,0x00031d1502ac46c2,0x0002208462e6392c,0x000b628057b1a21b,0x000051ff946ec1b5}}, +}, +{/* digit=49 [{1,2,3,..,}]*([2^245]*G) */ + {{0x000cb51566c5c43e,0x00085597f0466e85,0x00094d94acff9c91,0x00027cb354e90c49,0x00000a3933301479}, {0x000fac10dc1eb2bf,0x00013ff319fa8427,0x00096527488cfd8c,0x000745f2d4e68401,0x0000a2e067e57aaa}}, + {{0x0002a7f3e5f9f11f,0x0009e6cb3b8eb6d9,0x000f800bd9afe153,0x000e185d1a6dd7dd,0x00006c13cc1baf17}, {0x000c58e325fc3ee3,0x0000731dc3b215f6,0x000a3d3e77109540,0x000e2ce68e7c07af,0x0000f8417a1c4c7a}}, + {{0x0004772813b230d7,0x000ea7344427ec23,0x0007fc56a634d0f5,0x000f76a1548ab1d7,0x0000fab17513e06a}, {0x00010a74f7c4f830,0x0004220a67d9b62c,0x0001209a0a7d2edc,0x0009f01c40417092,0x0000b9815a0face5}}, + {{0x000589b319540c33,0x00097283d6f82842,0x000ae9fcb18490f5,0x000ba072731f84da,0x0000db6d960f3683}, {0x00063bb146110697,0x000e9788bf05c85c,0x0007460d2b19436a,0x000db1205459df34,0x00003f6e095511a7}}, + {{0x000938eb6357f373,0x0008fbd8aa62dc7f,0x000a979fcc5d00f7,0x000a999878dcb92c,0x00007e83eda1b023}, {0x000e2731560bf3d1,0x00090d0fae616b23,0x0009414bd1086e45,0x000ea1682483169a,0x0000b956bc100ea9}}, + {{0x000bb91c31b9c38e,0x000a68ef57b57b85,0x0003bab6f0c5aa90,0x000684fedeb169af,0x0000610ad740d373}, {0x00070df02ba8e15d,0x0005bca7f771f138,0x0002c036c0337edb,0x000e8114acf747b6,0x0000921d57786b94}}, + {{0x00064392c422f7ac,0x00022d348898dbc8,0x0005bfcd1fb63536,0x000e10c3084668c4,0x0000357c9e3eb315}, {0x000b5405b2e5b8ce,0x00010102b9a4b173,0x0000fb1997e94693,0x00062a37c890eb7b,0x0000c225a84b61b6}}, + {{0x000a3c8ee3c76cb3,0x0003a32a1f6ef306,0x00063e9563cf1162,0x000c26b6d5ab6468,0x0000b8a4cbe8c005}, {0x00029a59ce6bb278,0x000184d4b16fdcd5,0x00023798dc4afaa5,0x000fab30624a2679,0x00005e56df6eb307}}, + {{0x000893c2bf296984,0x000497ce76030281,0x0009a558f91fc19a,0x000f7735a5dca3ad,0x00000ceb3fa8d50b}, {0x0006060bc9ba369d,0x0006897888c21baf,0x000a34c07927e103,0x0009800936bf1986,0x00004cf10c2934ae}}, + {{0x0005334859dd614c,0x000a58d0c8ee3a3e,0x000cd51d59c475b5,0x000325a3080d1f07,0x00009c0d0a7788b4}, {0x0008691c234296f5,0x000444887fb61ac9,0x000ea9cf22a0a83a,0x0002f5065114270c,0x0000230a6e8f2480}}, + {{0x000bf0f72e3d5c1e,0x00056f21439ef7a2,0x000e303343771744,0x0002f91edcbf259c,0x00000030a795ce20}, {0x0009ebf1202e9ca6,0x000c15e6e5916f2d,0x000dac4f8e79dde6,0x00004d952072aff1,0x0000c8d087f1b9b4}}, + {{0x000c73dbce913af4,0x000b058a07cbad0f,0x000f00c8a909e587,0x0006abd300da84d4,0x000025cd048f5446}, {0x000b9be90e9d8bf9,0x000aae431b0eb59c,0x0001aecff991616d,0x000c3b43aa117a53,0x00001af92d3e9f4d}}, + {{0x000c292e93fda293,0x0007b97d91bc9b1e,0x000ace1e676bb6c1,0x000ae34509d95faf,0x0000653fe47ee855}, {0x0000b280f680e752,0x000bceb6c26c7318,0x0006d423675eefd1,0x0001d884cdf29fb6,0x0000d70a9978b582}}, + {{0x000e20720445c36d,0x0001898771747a3e,0x0009f73e971d1ac8,0x0000803fc539f794,0x000005cf3d8682e3}, {0x000e20b7b1c7129b,0x000fa69e61f28758,0x000544c2dffadcc1,0x000e53005d3a2f59,0x0000e16f5c24fff5}}, + {{0x00065b8aad581350,0x0009037aa5be73cf,0x0006fd6a0622c211,0x0008cf79373b3f64,0x0000e029db50d397}, {0x000c43794fba0377,0x0006f20797a68bdf,0x00030d38eaefbd68,0x000463cfa5382bbd,0x0000627cfbfc85d7}}, + {{0x0000fef4e4ca4631,0x00072566cc63b233,0x000780900bcef728,0x00027dc161d2cacf,0x000035dc5396b548}, {0x000052e27bf1bc68,0x000f87dfa06c638f,0x0003321da10a224e,0x000c8f6973586d6d,0x0000b0c5738a6152}}, +}, +{/* digit=50 [{1,2,3,..,}]*([2^250]*G) */ + {{0x000ba6b23a5d8961,0x00056fe4364e9910,0x00033c6771fe19e3,0x000fd05e1da8c39a,0x00005b4488b39fd9}, {0x00092541a1f22bff,0x000fbb8163e81f43,0x000e5658e920a8a6,0x00039a4fd1b24907,0x00002c4f79da6ec8}}, + {{0x000619c76497ee80,0x0006c717370e8b5c,0x000cf68e15d2b0ac,0x00079298204cb64f,0x0000bdec21162bc6}, {0x000ccefa63b10110,0x0007e0de1ac56973,0x0000e0c8bf9e3fa9,0x000cb45efb693e3d,0x000037248e9d2d4f}}, + {{0x0004e2ab20364e46,0x00088770b20dd369,0x000d77d1c6269971,0x0000a50183291b6e,0x00009aada7fcd618}, {0x000054bf185509bd,0x0005a870107751f9,0x000b96d8dfd7e845,0x0007ee06a2308a7f,0x000053e48d2f8dc8}}, + {{0x0002dc91ec34f9e7,0x0004c38106038080,0x0000cb4f3d8772d3,0x000128cf06d66c53,0x0000be5ed0e3475c}, {0x0003c1931e82b100,0x0007c9ff6b4ccb9e,0x000a1b45ec63d285,0x000bcab92118c692,0x0000aec44147285b}}, + {{0x0001afbe8316c455,0x000cf6700b8b3707,0x000ff8578982be4f,0x000fa73d5d177c64,0x0000ec4058319a82}, {0x000e37bcfa86678a,0x0003ff0312845518,0x000bbb74c24e809f,0x000de5912f39604b,0x0000d4b4f7060c14}}, + {{0x000f4868eb6e843f,0x000abc4ab3aba3d6,0x0003cf2dc6415834,0x000c3d128a81514f,0x00003b496304f3e6}, {0x000ae90987dd2f21,0x000ad10bce559119,0x000149ed6437a6d8,0x000332b31cdd6b9b,0x0000b77791d16871}}, + {{0x000b650e16e05e91,0x000084e746409c34,0x000a3f029965a774,0x00077c93fd22fbce,0x0000eb6a9689f952}, {0x000a63d7bad84f61,0x0001e58f2fee2520,0x000840d48ad91720,0x000cbdda92c1669b,0x00002109c4abcef5}}, + {{0x0009ae71e29a3efb,0x000f9c93302efc18,0x000aae10ecbe906e,0x0009f820107914ce,0x00007a23f35668e1}, {0x00075c2efd2119d3,0x000eccadc9c8e9d8,0x000a1711303198c6,0x00003835591bf64d,0x0000cf0bbf86d443}}, + {{0x0003027aad991c1a,0x0007e49be4b7ab29,0x00072da90598d0bf,0x00083fec94a21ab9,0x0000da4cfde1ecfa}, {0x000b9c0fbcec63aa,0x000163219a3493d4,0x000652a557ca617a,0x0002dff00424eb6a,0x0000f9346ea8b856}}, + {{0x0004d79023814615,0x0005411bc478c3e0,0x0000b3ef2b1643ab,0x0001b6792becfa39,0x00004476778fcd2f}, {0x0000c4d66bf3aafb,0x000a7c21c65a8daa,0x000a13ac32bc1287,0x00090a3e182910b5,0x0000b04730140b07}}, + {{0x0006947d17d4e0b1,0x000eedc3a47b8376,0x0006fd0ffc5772be,0x00095e665a50db1a,0x00007f904ba55b09}, {0x00043832883487ec,0x00030270aaedcee6,0x000cb1fd9f56db7f,0x0004d4a738d94f46,0x00008fa426ad42fd}}, + {{0x0005bb72b7247593,0x000182d4c63aae48,0x0007d6f2c945353e,0x00010952159d07de,0x000089caef37ec5b}, {0x000bb53db65ef147,0x000e6d99de434a8e,0x000f2405f2dc2cb7,0x0008a3116fa3ed83,0x00003429bba31420}}, + {{0x0008febd56daf065,0x000afa837f6908ed,0x000b6e05a8d98277,0x000abd4947c636a9,0x00008c8a77b10d58}, {0x00096a45f121e4ff,0x00062076d3d3f454,0x000fb0c5d16cd67c,0x000b46fcbd1958e3,0x0000be185ed28e1e}}, + {{0x0009760ff79d2ee9,0x000f639e7832b7ef,0x00005b499dd4d06a,0x000d316d025001b9,0x00008fe1c6285b61}, {0x0003980c5f128050,0x00083009cd9aa9f8,0x0004eb16d376e3b7,0x0002dfa322b09f51,0x00008e213122c383}}, + {{0x0008626dc4ad4f4b,0x00019ddbc0b6aea6,0x0002e90655dc5168,0x00088df76697bd60,0x0000eeb3ea63c378}, {0x000a2f2145691136,0x000c435f44841ec4,0x000e44df2e48b820,0x0009fd3fb560949a,0x0000ca13462f2cc0}}, + {{0x000d590b01e6e274,0x000da180b2dcb618,0x000aea4a9047e2cc,0x0003a491b299b504,0x000012c9e1edfa40}, {0x0008a36794075521,0x0006e332b8e388d2,0x00068de1949c5013,0x000b972a1b6fcce6,0x000078851bc85122}}, +}, +{/* digit=51 [{1,2,3,..,}]*([2^255]*G) */ + {{0x000d46d95a7b1a29,0x0005ac6341fb197d,0x0004c2ece9c4e7ad,0x000f89b26eca2948,0x0000211e48a6e7f4}, {0x0007f6ec78ef1f42,0x000fe65745861499,0x0003eede82b2c090,0x000017f7286a6e1c,0x00005f92e472f60e}}, + {{0x00070af3aeac968f,0x0008d4b63266b4e3,0x000ac5664e4f7fee,0x000cbec4acd4c2e3,0x00008910bd3beb38}, {0x000e50cc9c0726e3,0x0009a97b40bf1c3a,0x0005a5a1b1530956,0x0004cd40884b7ffd,0x0000890896b1f831}}, + {{0x0007d205ffe7b376,0x000ab747d2da090d,0x0004fc5193b7f3ef,0x00071e42cb525fb5,0x0000e220933566a9}, {0x00060dfb486d440d,0x00056fe13465ddc1,0x000e4c1517fcfec4,0x0002b4b3da7e4e76,0x00006fa48a2a8d30}}, + {{0x0003c9f82e4c6346,0x0003da4464f85ced,0x0001dca258efb831,0x00012b8706381b7a,0x0000cd15a3cba2a4}, {0x000a8fdbfcd8fb51,0x000f5e54cd229347,0x000d8932f31db2ee,0x0001afb4aeb11ef8,0x00001e7c1ed44441}}, + {{0x00065ef12045cf9f,0x000eaccce8bdae40,0x000cf65256fcb2ca,0x0003112fa0ba4ef2,0x0000683125ebb72c}, {0x000a4eae312410e0,0x00076cd8e830a01d,0x000fb3f0767e2867,0x0009a5abd9575298,0x00005f11e11eef64}}, + {{0x00084f5903fa2711,0x0002a9da921e9968,0x000b01e54e6da0fd,0x00014e96f2f2695d,0x0000ee3e9bd78762}, {0x000181ce27a94979,0x0003fe215e04a26e,0x0002cabca36d254e,0x000613b2f32a6c25,0x0000948148810b57}}, + {{0x0001058fa28a7e00,0x00050bf5ec74ea96,0x000229666c726cf2,0x000799e74d55c8db,0x0000bd9abbfa57f5}, {0x000ef074dfc47b3a,0x00026c52f91d7479,0x000a8bde2d9c65fc,0x00027fee0283fe36,0x000032a8b5f1d4b7}}, + {{0x000b43a43228d831,0x00003ad63f99ab41,0x000a5122924ae1c3,0x0002b47e525f1a46,0x00004af860fdd26d}, {0x000ef613f714aa18,0x000d6b78795ed6ba,0x000a9d694f51865a,0x00052753e21fcee6,0x00002ceb1de0a37b}}, + {{0x000d27d483076829,0x0003510566da8605,0x000f2d7ab745aaba,0x000823557cae36bf,0x00001332ba1db127}, {0x0003638f3429f438,0x000f6c462929cb5c,0x00018b7bd43a21c4,0x0000c669bc95352b,0x0000c2addf4678cb}}, + {{0x0005bfd2f9fd51a3,0x0002181b97f74a66,0x00036ce507f2f1fe,0x000ded9ad05d69ad,0x000014fc2a4b44f4}, {0x0003d8cb55fc5c6d,0x0007efb1e23dd559,0x000453ccee3510ce,0x00063129b7be6937,0x00003541b7a39fae}}, + {{0x000cbcad7154cedc,0x00067f52651ab013,0x0005e642e949b285,0x0004a343b41f6e9f,0x00003a3462a46ed9}, {0x0006cd6222b24dc4,0x0009c28c9c26f3c8,0x000dad3b67578fe8,0x00040a6ac7bfa12e,0x0000112c5d7c8479}}, + {{0x0006525eca445df4,0x0001ecdfa4c69929,0x000a6d3bcf1af24f,0x000cc7b5b4eb61eb,0x0000560910cd8972}, {0x0001c32093eaa327,0x00090d3c67bb5475,0x0008711100183134,0x000a7dcbd90ce62d,0x00005fc863ac38ba}}, + {{0x000f8b64ae3a2787,0x0005a37cdf658fe1,0x000be0492160c530,0x000d81b2f029e733,0x00009a68042ea75c}, {0x000094a5b3f3ada8,0x000d965c32501d8c,0x000792e225d723bb,0x000ea988b958ffa5,0x000029fa987311c1}}, + {{0x0008a4176a9f05d0,0x000b9011d488711b,0x00048a65e06ca4e4,0x000894543bc62ba2,0x000017535ffc9290}, {0x00084ce406851d75,0x000f40e960b4840b,0x00028fd34afa3acd,0x00092c5c3394af71,0x00004eb4d5b7ac0f}}, + {{0x000a73e4a14f8366,0x000790946328923e,0x00017a4dfc8cc8c5,0x0009296e3f117fe9,0x0000372f934572ce}, {0x0000249c29ba567e,0x0005ac829cca7500,0x00002ec7acbd437e,0x000d168c63aaabdd,0x00009b2f90d5b42b}}, + {{0x000e87355dbd4b3d,0x00079639bbb1db09,0x0006519621f87992,0x000573e83e47e51c,0x00004ef0fb7943fb}, {0x000b9d8f1bfb12a4,0x00082e5e8b7227d3,0x0007b90146ab877e,0x000b644eebdc9d15,0x0000c2110057aa5c}}, +} +}; + +#endif /* IFMA_ECPRECOMP5_P256_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp7_p256.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp7_p256.h new file mode 100644 index 000000000..e32a40317 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ecnist/ifma_ecprecomp7_p256.h @@ -0,0 +1,2474 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPRECOMP7_P256_H +#define IFMA_ECPRECOMP7_P256_H + +#include + +#define MUL_BASEPOINT_WIN_SIZE (7) + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE +#define BP_N_SLOTS NUMBER_OF_DIGITS(P256_BITSIZE,BP_WIN_SIZE) +#define BP_N_ENTRY (1<<(BP_WIN_SIZE-1)) + +__ALIGN64 static SINGLE_P256_POINT_AFFINE ifma_ec_nistp256_bp_precomp[][BP_N_ENTRY] = { +{/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x00030d418a9143c1,0x000c4fedb60179e7,0x00062251075ba95f,0x0005c669fb732b77,0x00008905f76b5375}, {0x0005357ce95560a8,0x00043a19e45cddf2,0x00021f3258b4ab8e,0x000d8552e88688dd,0x0000571ff18a5885}}, + {{0x00046d410ddd64df,0x0000b433827d8500,0x0001490d9aa6ae3c,0x000a3a832205038d,0x00006bb32e52dcf3}, {0x00048d361bee1a57,0x000b7b236ff82f36,0x000042dbe152cd7c,0x000a3aa9a8fb0e92,0x00008c577517a5b8}}, + {{0x0003f904eebc1272,0x0009e87d81fbffac,0x000cbbc98b027f84,0x00047e46ad77dd87,0x00006936a3fd6ff7}, {0x0005c1fc983a7ebd,0x000c3861fe1ab04c,0x0002ee98e583e47a,0x000c06a88208311a,0x00005f06a2ab587c}}, + {{0x000b50d46918dcc5,0x000d7623c17374b0,0x000100af24650a6e,0x00076abcdaacace8,0x000077362f591b01}, {0x000f24ce4cbaba68,0x00017ad6f4472d96,0x000ddd22e1762847,0x000862eb6c36dee5,0x00004b14c39cc5ab}}, + {{0x0008aaec45c61f5c,0x0009d4b9537dbe1b,0x00076c20c90ec649,0x0003c7d41cb5aad0,0x0000907960649052}, {0x0009b4ae7ba4f107,0x000f75eb882beb30,0x0007a1f6873c568e,0x000915c540a9877e,0x00003a076bb9dd1e}}, + {{0x00047373e77664a1,0x000f246cee3e4039,0x00017a3ad55ae744,0x000673c50a961a5b,0x00003074b5964213}, {0x0006220d377e44ba,0x00030dff14b593d3,0x000639f11299c2b5,0x00075f5424d44cef,0x00004c9916dea07f}}, + {{0x000354ea0173b4f1,0x0003c23c00f70746,0x00023bb082bd2021,0x000e03e43eaab50c,0x00003ba5119d3123}, {0x000d0303f5b9d4de,0x00017da67bdd2847,0x000c941956742f2f,0x0008670f933bdc77,0x0000aedd9164e240}}, + {{0x0004cd19499a78fb,0x0004bf9b345527f1,0x0002cfc6b462ab5c,0x00030cdf90f02af0,0x0000763891f62652}, {0x000a3a9532d49775,0x000d7f9eba15f59d,0x00060bbf021e3327,0x000f75c23c7b84be,0x00006ec12f2c706d}}, + {{0x0006e8f264e20e8e,0x000c79a7a84175c9,0x000c8eb00abe6bfe,0x00016a4cc09c0444,0x000005b3081d0c4e}, {0x000777aa45f33140,0x000dce5d45e31eb7,0x000b12f1a56af7be,0x000f9b2b6e019a88,0x000086659cdfd835}}, + {{0x000dbd19dc21ec8c,0x00094fcf81392c18,0x000250b4998f9868,0x00028eb37d2cd648,0x0000c61c947e4b34}, {0x000407880dd9e767,0x0000c83fbe080c2b,0x0009be5d2c43a899,0x000ab4ef7d2d6577,0x00008719a555b3b4}}, + {{0x000260a6245e4043,0x00053e7fdfe0ea7d,0x000ac1ab59de4079,0x000072eff3a4158d,0x0000e7090f1949c9}, {0x00085612b944e886,0x000e857f61c81a76,0x000ad643d250f939,0x00088dac0daa891e,0x000089300244125b}}, + {{0x0001aa7d26977684,0x00058a345a3304b7,0x00037385eabdedef,0x000155e409d29dee,0x0000ee1df780b83e}, {0x00012d91cbb5b437,0x00065a8956370cac,0x000de6d66170ed2f,0x000ac9b8228cfa8a,0x0000ff57c95c3238}}, + {{0x00025634b2ed7097,0x0009156fd30dccc4,0x0009e98110e35676,0x0007594cbcd43f55,0x000038477acc395b}, {0x0002b90c00ee17ff,0x000f842ed2e33575,0x0001f5bc16874838,0x0007968cd06422bd,0x0000bc0876ab9e7b}}, + {{0x000a35bb0cf664af,0x00068f9707e3a242,0x000832660126e48f,0x00072d2717bf54c6,0x0000aae7333ed12c}, {0x0002db7995d586b1,0x000e732237c227b5,0x00065e7dbbe29569,0x000bbbd8e4193e2a,0x000052706dc3eaa1}}, + {{0x000d8b7bc60055be,0x000d76e27e4b72bc,0x00081937003cc23e,0x000a090e337424e4,0x00002aa0e43ead3d}, {0x000524f6383c45d2,0x000422a41b2540b8,0x0008a4797d766355,0x000df444efa6de77,0x0000042170a9079a}}, + {{0x0000b650bc6fb805,0x0004effe2e6b808b,0x00083f5495882e07,0x00072385ef2f7c2c,0x00004d63c80e103b}, {0x0001bd652a23f9b6,0x0008eb0b6587f2f1,0x000580e9e3670c31,0x00021ff5c4623bb1,0x00004edf7b261efe}}, + {{0x0001dcbd53c5c9dc,0x0005ec0a177b9709,0x000fe2dfff17624b,0x00074df0f139752c,0x00001a35c0b2c7a5}, {0x000314693e79987e,0x0000089cb80e227d,0x0001883bb0575bf3,0x0003cf4f4e247f0d,0x0000bd512271274c}}, + {{0x00051c856ada97a6,0x000d2f8b403e5f3e,0x0002e29794afc964,0x000bda46f247ab41,0x000075abd1bcf80e}, {0x000bd725e485a1d6,0x000f2f4f0b3c66a2,0x000847bba4b2a5ca,0x00094cc626927f1b,0x0000c6fc7d965023}}, + {{0x00012baa5659ae8f,0x000935e1a16efea9,0x0002c41ac68363ab,0x0003fbc884227775,0x0000e545c291897c}, {0x000e9e7dc4c696bf,0x000a0ba977c52d36,0x0009508c15806244,0x00097a95665e9be3,0x0000720ee265d125}}, + {{0x0009129d2337a31e,0x000e2f862bdc8a97,0x000d283ba5916868,0x000b4d248099d95d,0x00002d1eeb7de5bf}, {0x0001c417884005d5,0x0007afffcbae82ef,0x000a95e66a2d4ec1,0x0000d04161c53f8a,0x0000ee104e215fee}}, + {{0x0004cecc135b208e,0x00046783f47d562e,0x0003f3b3074e1b26,0x0002fb8d2a506c5a,0x0000cead9f5a1676}, {0x000d4b2e286e5b9c,0x000fc3bb3c61f29d,0x000ac29a41b0fadb,0x000fa2ba75023e7f,0x0000086d5f289477}}, + {{0x00011352f6f3076f,0x0002f3912a9a0fc6,0x000f8ba3dc99ffa2,0x0008a37a0b0685d2,0x0000dc777e9d9335}, {0x00087bb35415f047,0x0009dd23fea494a7,0x0003a35b5640c2d6,0x0000742de917da15,0x000093e8d07cd5cd}}, + {{0x00076532de45068a,0x0007fe2e1f6ef4f8,0x00058406937c7a7e,0x000f4230825fa2a3,0x0000f2cea7cb727b}, {0x000a4fb9e4785a98,0x000ba7299f4a0360,0x000ac2f71e5fda49,0x00066ec8068e1371,0x00003d0687c10776}}, + {{0x00083b215d02819f,0x000f50dd9a356d38,0x0002b469f6d0d754,0x00011471d7cbf91d,0x000097b23301efc3}, {0x000d750b24bcbc75,0x000938a1e356a551,0x000cb750111ea494,0x000b8a2669f03193,0x000095dc55f1a737}}, + {{0x00019acd837879f9,0x000e5d6b67b0a4a3,0x000f1f3af6fc1b49,0x000a2e5395993332,0x000066742ebf5432}, {0x000c9feb49662287,0x0001d3f439504b8d,0x000b731ee96cc631,0x000967a2068859c9,0x0000b948dc3c6f79}}, + {{0x000ad32ed1f80089,0x000a48b1753861e4,0x0007ff6fbe6c9267,0x000b0f8ac7c5eb85,0x000094baaa8e5f2f}, {0x00014e11d248018e,0x000a828ac50884cf,0x000a944f55a39898,0x000ac634fde97b5f,0x0000d178031b12e5}}, + {{0x0002af497e2feb49,0x00071ebf7313042c,0x0004ffdd7d36a42d,0x000769b9d2c9eb08,0x0000f8aa54bbef7c}, {0x000b7ba09895e702,0x000fbdb7fb589200,0x000eb4cbb3bd0c66,0x000e310d97d10878,0x0000d431068f84bd}}, + {{0x0003eb7172ccd1fe,0x000750a6a8924b52,0x000e153eb7323cb2,0x000b96b7082ec0cf,0x000097f6b6bd2aad}, {0x000393ed1a83da1a,0x0006e04b2a681d3d,0x0000cb71ea6a7f9c,0x000277aa688b482d,0x00009b4cc5fe0585}}, + {{0x000b46acb66e132e,0x00092d9258805e5d,0x00017b9e2f1be963,0x000d47b44a702703,0x0000266f95a28603}, {0x00066735c2088993,0x000772fb18a398db,0x0007c619f9047244,0x00021b5a96693977,0x0000798142a5a3be}}, + {{0x0001cb13298b343d,0x0008e44f65a1b424,0x000c77acda3a14e4,0x000c3bf5f4d6cd3a,0x00000288cb622b6f}, {0x0008c2f1c040abc4,0x000dc6bf9b4ad5cc,0x0003aa441b675511,0x000f729667da379b,0x000060d45ce91601}}, + {{0x0003c696755ff899,0x0006b73017e6e2f7,0x000f7600ddd3cf7e,0x0007b3fef5689d3c,0x000048dc4f941fc8}, {0x000fe814ea53299f,0x0001a8eb6028d9e9,0x0009803fc2d921ca,0x0007450aecedfd0c,0x000038ae8923d7b4}}, + {{0x000fccfc5e3a3d83,0x000c1079dfbfd8c5,0x000ad0197befd904,0x0002a48c6d6a58fe,0x0000922707799553}, {0x0003e6ddbef42f56,0x0003e80a990809e2,0x0009a2e407e449b6,0x0002a41b969c1aad,0x0000231d792f591c}}, + {{0x00014560f6645343,0x000c1b68f1038715,0x000578ab985ceae7,0x00010c7c09c4ae65,0x00003ec68692044b}, {0x000832b3a8ec1f1b,0x0007a847d5ef6ac4,0x0003f15745509d12,0x0003c44909604f76,0x000016c4304732f6}}, + {{0x00020147ca23cd3c,0x0005e391849db6ab,0x000678d94caa7a5c,0x000e639b0673a375,0x0000982ddd59d303}, {0x000000b5db6f971a,0x000ecf876f92fd7b,0x000569426bba2cb1,0x0004f8277332a33c,0x0000159100cf70d7}}, + {{0x000847fdec67ef5c,0x0003633e76b7fd16,0x000c2b4c8742ee46,0x0005204b8e4134ef,0x0000a640b8702a3e}, {0x00001908ceb6aa92,0x000c347852d5653a,0x000237af7313c300,0x000af804e4ab126b,0x0000ba90162abb47}}, + {{0x00058d6a8219bb73,0x000ceb06c57f3d5e,0x00057576ec691d0b,0x000dc2dae4cb10d2,0x0000569656d054a3}, {0x000aebd94cda03a4,0x0002d62bfe13e5eb,0x00051a0c6934e82d,0x000526050ac0bae2,0x000080b9e121d6da}}, + {{0x0007bc58cce08b52,0x000c5f178d550046,0x00077d806b636458,0x0004eba5748baea6,0x0000763a387ffa39}, {0x000448a7d3cebb65,0x000e1f20d850a12b,0x00058462ce7adda3,0x0008a8a63ebce515,0x00008b36143b2008}}, + {{0x000c3ca4d63c0eea,0x00066fe948ce8a2c,0x0002ef33b5123311,0x000d6bd463fd8522,0x0000df0c7dd1c603}, {0x0002d3bfe7765e5d,0x0008ef3804090ec3,0x00059319cccaab35,0x00034cedaa84d68e,0x00009a4c2816c80c}}, + {{0x0009488a059c1425,0x0004af0b9346a9d8,0x000fb36646f5ae71,0x0006abb68f237d16,0x0000853e4c486318}, {0x0007d2363c52f980,0x000681828876e2d8,0x0004e7b1c2ec4a76,0x00040847b864fae1,0x0000c0bc0e569192}}, + {{0x000681db82e9f3e4,0x000b9f25e13ce4d7,0x000f2728083200f0,0x0002274909984c66,0x000062d7b00b5f73}, {0x000a188f26517980,0x000c36ab1c34d90b,0x000f5435974c6e18,0x00002fab256ea35e,0x00003466612d1aa7}}, + {{0x00060492ed22e919,0x0004df072822624d,0x000ce22716fdfe0b,0x00014f5eca111539,0x00008100a506b016}, {0x000daa2a35c628ff,0x000dd87e9a47b6b0,0x00057d9ceb6f94d2,0x000a7ad67732591d,0x000070bfeecf3884}}, + {{0x0005ccfed2bad016,0x0002bda6a5c75fb3,0x000a92f8fa155cbe,0x000e4362e2594c30,0x000049c89cebbfaf}, {0x000667de9ff257af,0x0001032c50aed158,0x0006014cf9b35961,0x000d3c5b00b20b90,0x00003a8cfe479bc7}}, + {{0x0003ffd248a7d061,0x0004778873fa4ff2,0x00074598180c5bfb,0x000994a7d9ad9005,0x000079c85db4db01}, {0x000b06261a6966c4,0x0002aadce5a8ba41,0x000e6a3184d82d05,0x000da05e91cd3ba5,0x00007795f4fd5b2d}}, + {{0x0007c1fd55a897c5,0x000b629110fbecfd,0x00081d3b0009194a,0x0002910f0e2046e3,0x0000f3425f6f98dd}, {0x0006687730d50dae,0x000b6b083b7fbfa0,0x0009d34170423446,0x000429597a247dd6,0x0000b629f91187ba}}, + {{0x00026ccd5cd79bfe,0x000ab46c6e181ee4,0x000477f580032940,0x0002773b1e8ae057,0x000094f7d354d823}, {0x000cb96782ba21ad,0x0009272b33a5c747,0x000f80c81c525446,0x0006b4a72ef6dec7,0x000073acbfefcd9e}}, + {{0x000b5b149ee90d9c,0x0009e06e9eba4075,0x000f825e0785c339,0x0001dbe1030d5bab,0x0000ec684c464293}, {0x00062c9c1586e630,0x00065ab43f2b42ab,0x000f7835d45431d6,0x00086557c8b2c055,0x000033da338c1b7f}}, + {{0x0007513caa760974,0x0008f6c83906283c,0x0005af2c70a624fa,0x000bfd2b20afec71,0x0000b9699752ba78}, {0x00055ccd921d60e9,0x000febaeca132207,0x000ed93d49b944e0,0x000d2674819d515d,0x0000bbff86efdddf}}, + {{0x000413077adc612c,0x0008fbd803a06b34,0x0008805bda749652,0x0003ac5a1baaa76d,0x0000840390307034}, {0x0009f66175adff18,0x000b37d8c5b739f5,0x0009d75e30b26d7f,0x000cc22875f5ce52,0x00005efc7e9c1325}}, + {{0x0000b421ff6acd3a,0x0003b3dc69092195,0x000766127ffe7048,0x000b2b5f4cd0b228,0x0000bdbe608efb7d}, {0x00092285e1109e8d,0x000724645b5a837c,0x000818ed826147d2,0x000a357d78f592f7,0x0000394077fc247f}}, + {{0x000c2d0488c171a0,0x000a136852780fb9,0x000b1fa6aa78bfba,0x000ba7edfbe268d5,0x0000dceb8db2b7ea}, {0x00080899ae2b710d,0x0005d4449c96bf9e,0x000143a46efde7ae,0x000c1273b7716bcc,0x00007d3419593628}}, + {{0x000ec1c3b3f64c9d,0x00094e5edf3f508c,0x0004318d4e20bc0b,0x0004430a1deb852f,0x000020ebe0e2c3fa}, {0x0004ea773241ea3d,0x000b8e1a5f65370b,0x000681c6261f1511,0x000c2cc9a5e23d82,0x0000731e38472f54}}, + {{0x000f36e834459048,0x00092f45f9c02692,0x0007528b72e0ec46,0x000542105a3201c6,0x00008f77f3550e5e}, {0x0008d295864687c7,0x000db2df3562f67a,0x000bec39e23b92ea,0x000f8cec27014b9b,0x0000ef2f2270c0f0}}, + {{0x0009638546c4d8de,0x0003b2f246799735,0x000c8acd95f9c3fc,0x0004afb12e8beda8,0x0000c3a318e10663}, {0x0007f41c31cb264f,0x000e622113f28016,0x000afe1973db82f6,0x000282c155bcd2dc,0x0000ba1da5a33465}}, + {{0x0005b8eb212cf53b,0x000e48557c5fa042,0x000c4d56c4f2e512,0x00085111286ff925,0x0000b8a0feb9e26c}, {0x00070d2e7d6107e1,0x0004d76265aac28f,0x0001936b17ee0c44,0x0005eb2df277a41d,0x0000a556e3ffa959}}, + {{0x000bbf9e73056835,0x000eb7ef5be6258b,0x000c814c131eea5b,0x0000dcbdeb0e4a46,0x0000cee8449f7b73}, {0x00095c5a0182bde2,0x00077e27a6b4eab4,0x000e518caee759f8,0x0003f4a2cf6a6880,0x00005e80140114cf}}, + {{0x00041407e8d7a14b,0x0009e556f36a8fc4,0x000600044bb1ff3c,0x000e62ba84438514,0x0000a3f0c4b2451a}, {0x000c25b1f9af32a8,0x000631f2214bdfca,0x000b596ac01e0db8,0x000c07ce9a5bc2a4,0x00003927681826c2}}, + {{0x00032e77acaca28c,0x000707385b293ec8,0x0001eaf381bfeea5,0x000ccb468212e3fd,0x000013298312acf8}, {0x000f2db2aac9e59d,0x000ce661782ab909,0x0009b7a015748060,0x000625f5ab2632c7,0x0000a44c6c6d0017}}, + {{0x00000e8a7ea82f03,0x000db4299aaff26c,0x000d78be199cac80,0x0002cda66fe3b67e,0x000005f725f948d0}, {0x0001bc4623fb21b0,0x000e7a6319ad33ed,0x0005ffb3efa70533,0x00074117ab562dbe,0x0000637499456674}}, + {{0x0004ed65c46aa8e4,0x000368d063d169d4,0x000d17c362100d5d,0x0003b78b9727eaa2,0x0000c2bab1bcadd5}, {0x000e90c15426704a,0x00030837ebeaa084,0x000e477f8778afcd,0x000a8ac651f7017c,0x00000624998e6fb7}}, + {{0x0006828ed8a6e19d,0x00057189d9c7dc1e,0x0001c39bc33fc233,0x000914326f8fe267,0x000040c4cce8c6f9}, {0x00035bbf80e75ca0,0x000022adff2cafa1,0x00051ad9612c651a,0x000832c40a04bd4f,0x00004820109bbe4e}}, + {{0x000eb1a7f4c04cc9,0x000119404f843667,0x000ceb50a5955662,0x0005f9e1cdf6537e,0x000094a44a72b833}, {0x000f819dbeb9b690,0x0000eed4350dd7fa,0x00044bba2473c568,0x000bf3b6658466da,0x0000d1bc780872bd}}, + {{0x000f175a1962f910,0x0001ed58f5a7e535,0x00089a2336ed7e06,0x000413177aa4c020,0x0000dbcb03ae539b}, {0x000424ebb32e38e6,0x000f0806701ee3dc,0x0004be9ee6472e5e,0x0000097d47ff9881,0x0000b60cfff95ace}}, + {{0x000d9319ff91fe50,0x0000f0518eedb8d3,0x00082cb26039c480,0x00068d95c3763291,0x0000763a43482fc5}, {0x00004d5383e76ba9,0x000ff24e8197707c,0x000230de0ac98b92,0x000b7002bf7c8f91,0x00000876a01d0959}}, + {{0x00096f305968b809,0x0002789f73b9db6d,0x000c61e01380a091,0x0008c6eda70b83c2,0x00005fb8394e69b3}, {0x000651280edfe2f2,0x00096faeaf829a3c,0x000424bf88f726bb,0x0009706010a4a078,0x000096720442e844}}, +}, +{/* digit=1 [{1,2,3,..,}]*([2^7]*G) */ + {{0x000cb817a2ad62aa,0x00090c62ff5463c5,0x000ad9db57ef2b6b,0x0006169749bba4b3,0x0000d311f2ce6d5a}, {0x0008087c2ff3b6df,0x0002467834ffb77a,0x000d6b138b46feaf,0x00018808aa266d75,0x0000a38d321dc008}}, + {{0x0008ffa696946fc7,0x000849cba56d486d,0x000f35a1550fbc6d,0x00062c0e3d423e90,0x0000c3da19630dd9}, {0x000fdb03cfd5d8b3,0x0002589dfca5e673,0x0002305aa0704b7c,0x000e53c6ce581ff5,0x000099d49ebc14d5}}, + {{0x000496d6ec293cde,0x0006ae7051f5380a,0x00049140a733dbda,0x000bf5237e388db8,0x0000e4b32b13946d}, {0x000fda9cae368d14,0x0000bdb0b2f3b1c4,0x0003ac46e5001a7b,0x0006562df593742e,0x0000af675f279b3e}}, + {{0x0008110399492969,0x000aa61db1b544e3,0x0006eaff55b63827,0x00028fae5323ed20,0x000042370d3521f4}, {0x000af2ee0d985a17,0x000b0239846df2ca,0x0006312f8192cc64,0x0001080c0b8f47ae,0x0000dc61f9206620}}, + {{0x000fb5bc2da7de94,0x000ecff8d3beb830,0x0008a9641d0e643d,0x000501f1ee77ba18,0x0000e8aa3aafcf6d}, {0x00065329a49110f0,0x00062dd6b220f9fb,0x000c3ea5ad18317f,0x000c4a7e3ced4152,0x0000d296a147d579}}, + {{0x000a53eed4c37174,0x000efd0ed2a335d6,0x000543aa59f8240c,0x0004b44c0d4d05e5,0x00005d5bbfc1d33b}, {0x000cc73137fd28e3,0x000f973b3ffdfa04,0x000f51ef2862ac6e,0x0005a2103ff9f531,0x00004d5e0fcec73f}}, + {{0x000682008913f4f8,0x00016ac93d95f252,0x000a6b26cea20ed6,0x0007afd1ed38b46c,0x0000662dcbd6a432}, {0x000295c725d2aaaa,0x000eee52dcda6daf,0x00017daccbad2752,0x0002318210e7210b,0x000037f7913751e8}}, + {{0x00081e144cc3adda,0x0005e7be82cf4f70,0x000dd6472d5ffa1d,0x000862e9890b6c0e,0x0000da26e1aded17}, {0x000271563483caaf,0x00083f6077fd276f,0x000466e3ce6924cd,0x000d1e15a7fe980a,0x00001c794b1a1902}}, + {{0x000368882a8042c0,0x000fcd278298e521,0x00097a740d931cfa,0x00007c069a0ae0f5,0x0000adbb3f3eb591}, {0x000951e5eaa8eb87,0x0004a1b48e78983e,0x00003f2c5e663a8b,0x0001e1a631cc0d8a,0x0000577c11e81e27}}, + {{0x000385c08369a907,0x000aa90eb4f833b2,0x0008eac802990c59,0x000014119a6145c6,0x0000a786d629ec4a}, {0x000adbe20ac3a8dd,0x00008aba2d3033fa,0x000a4f56531a2178,0x000fba509d2742db,0x0000b2ce9e425aa0}}, + {{0x000334b168984df5,0x0006e38796388cef,0x0003720f0e81dce1,0x000beca6e6949c26,0x0000c56feb04593c}, {0x0005601fde58c84a,0x00068eccb3148bff,0x0009a8a7874e2411,0x0008681cf01b614c,0x0000233e35ef44c9}}, + {{0x0006bf38bd7aff18,0x000a9d81b146b315,0x00028a9151b5ee4c,0x00099dfba1ac41d6,0x0000f3a8f9d7d896}, {0x000b9c9a0748be7d,0x0004d92e621f7329,0x00010a8371d391c9,0x000435151e6b214d,0x0000255f53b1947b}}, + {{0x0009e04f1788ee3f,0x000eb86938a20766,0x0003a01c0c14f27a,0x0008079b47a334e9,0x0000f627439c9366}, {0x00085d8ca2a59655,0x000286e9b9b37a09,0x000f972e83d9a554,0x0002fd723eb80b4c,0x0000c1c33bb9fdf7}}, + {{0x00058d474a861082,0x000fce4c5d900c4a,0x0006d4c80f8048a8,0x000e60c3c7c924e8,0x00008c889de256a1}, {0x000662eb214a040f,0x000747e1034757e2,0x000ac748ae8c48e9,0x0006f19774286280,0x00001c24023086b0}}, + {{0x000d4c35f74040ab,0x00014ceac957ac2d,0x000c4ec23409aeb7,0x0006eb9fbad78255,0x0000359ed623a7b7}, {0x0004926ed6f4a607,0x000edb912de31274,0x000705a59e21e8d7,0x000c0e72575a59fc,0x00002f1d4df5d2db}}, + {{0x00024b9eb7926b83,0x00039dbe55093d2b,0x000dd640bbff88cb,0x000d45a0f399afe4,0x0000c5fe1305f76e}, {0x00062f43764fb3df,0x00074151b62d6f35,0x0009ce5f37b5af31,0x00090ee5bd0bc7d7,0x0000daf6b21dc668}}, + {{0x00067ec6063540cf,0x0001f5f9cb8f735c,0x00099c6ab50b259c,0x000c84c8734f9a3f,0x00008cc13d693a7b}, {0x000b305c52176597,0x0003dec12a5480c1,0x0001345fefe5364d,0x00097f4d87045e68,0x0000f8efeb1c82f8}}, + {{0x000f1e5d59233595,0x000d039b9fb0e8cb,0x000859b98db0cea9,0x000cc5bc5b34cf49,0x0000e583c56f4403}, {0x0001a2dd48185b77,0x000dfe52178711fc,0x000105b8bc93fbc7,0x0000c7d7e7a05805,0x0000b4d4d594b826}}, + {{0x00030b046eb842ab,0x0009cbdae56de339,0x000f7fdfc8e844a9,0x00017584ef3a9e13,0x00003768f83136ca}, {0x000f4e04e09e61c1,0x000190c7cddc2821,0x000945fcd414dc3a,0x000ff1c537943754,0x000051b6eefc3555}}, + {{0x000d6136339c0831,0x0005cfb64701b31b,0x0009604ab39ff815,0x0004426c3388d2e2,0x0000e19084bb6b10}, {0x00054c0eccd47ef9,0x0004ba5dfb3017cf,0x000daf9f68969338,0x000958d9d023fb47,0x0000222840c0d91d}}, + {{0x00008f5803bac625,0x000ce79bd45f4391,0x00063c5810b7dd91,0x00004f8651e827ca,0x0000c5d75f6a09c1}, {0x000c7381f2dc308f,0x000ee98454be7d5f,0x00017b03120faa7b,0x0002aba5374beea5,0x0000036b9b254269}}, + {{0x000610939842194e,0x000d69d05295c510,0x000b42ee0b7e2353,0x00011c1c8c1d5cef,0x000004884ebe8ce8}, {0x0005d817419f40e7,0x00023995c241f1f7,0x000c556465b0ac16,0x000f96a20921bbc4,0x000013520c2fd33c}}, + {{0x0005a5ce98c51002,0x000d0ddd0f5ab4a6,0x000a2e78b6cec871,0x000a5f051f0b7f9b,0x000024a8434ee3a2}, {0x0007f6125f5c46fd,0x000b78545ec02682,0x000bb5cdc6a22bed,0x00098e55ae5fa0b1,0x00006936830ccb9b}}, + {{0x0007fe891e5d7d3f,0x000683a076783202,0x000dfdd61f14b7d1,0x000f48088497b3c0,0x00007c2eec11a8c4}, {0x00073f43756e621a,0x000f7825b948aa55,0x000878572c013a23,0x0001837c03b34563,0x00000472beb053a4}}, + {{0x0002e270ac69a804,0x0005b51e54f6f422,0x000ffa59134096d2,0x00027ec0a648cb8f,0x0000e87acdca9b65}, {0x000e037e285ccb47,0x0003e0ddcf520575,0x0000ff719188089e,0x0003693a96c9a887,0x00004a56cd88fc7e}}, + {{0x0004ee21726931ae,0x00075660ecfd41d0,0x000818e180bbbb2c,0x000886c6ef6de524,0x0000421cc52c7d57}, {0x000d208bea87be65,0x000361cdd682f127,0x0009b63f716a475d,0x0003b64db1b68443,0x0000359b3dc40f11}}, + {{0x000f1de8bf06e31d,0x00040d383901dfcc,0x00017e7d21fdf8f4,0x000eee40775cad50,0x0000fc3a59828d11}, {0x000c8a0b1ecff106,0x000bc84005496ec9,0x0004f8d73ee6ed6c,0x000ab955ad7bae1b,0x00001b4f11e400aa}}, + {{0x000d69bd4eff2d71,0x00013288b60f7b32,0x000a1e72388ae677,0x000e8c059461b437,0x0000f3d4789670aa}, {0x00018c07f9871da6,0x00089635e2788691,0x000541dac35fbda7,0x00045f138f3641e1,0x0000794b13b20dae}}, + {{0x00064ac09cc0917d,0x0008f68540fd0650,0x00022767127c5372,0x000a033d2d4c8eef,0x000023a9f8171785}, {0x000952852650359a,0x0000d4a1acad98c5,0x00055bf5cfa09ad0,0x000083682d5a290b,0x000040f1c67e19b8}}, + {{0x000752edcc18770a,0x000ee825c3a53a5c,0x000b153ed4baf1f2,0x0007234bd63f7421,0x00002383e4852f64}, {0x000620a2646d19a8,0x000b83c83ffde7bf,0x0006be9f156cb44e,0x0005e92f7267c94f,0x0000b2dfd7c406bb}}, + {{0x00072f2a672c5c73,0x0007dd53c5e2b870,0x000435932eacb11c,0x00093bf2dac29dff,0x00007bdb99d74086}, {0x0002fb62899c20f7,0x0001d47ece24f6e6,0x000577ce33535d51,0x0005f28bdc6b88ff,0x000026693bd89057}}, + {{0x000b0e5ab4b35a24,0x0001b5eeaacf6772,0x0005b95801d8b600,0x0001da328f7ce479,0x0000a20ed2a81fb8}, {0x0005cd44fec01e63,0x000c77ff50ad9f68,0x0002d97fd3ed7ddc,0x0004f9160fd2640c,0x0000a2414271b82f}}, + {{0x000df2c6a8ea8208,0x000b722cc25417d1,0x000291426b2b50d3,0x000e3883856cbab7,0x00007fd26ae84f5e}, {0x00096cc02bee4ba6,0x0003a6820fd69cb6,0x00012e9855312180,0x000a0945dfc26902,0x000066f7ffa760f9}}, + {{0x000cd33bccd9617a,0x00041a7730a3c503,0x000db0786365dede,0x0003bbd98c63555d,0x00006c3200f9c9cd}, {0x000fb2ce5e35efd0,0x000b5555a1c1060f,0x0000b375199a4e25,0x000bf611d95375f7,0x0000a57354a160e1}}, + {{0x000ae4bf8e4b0651,0x00041e53022becb3,0x00092ed9607a834c,0x0004ec0cd300b386,0x00006a6f79271ee1}, {0x00063c66a8649edc,0x000dc69f3e148f10,0x000a7b3ecfbcdfcf,0x0002f06cfb97c100,0x0000ea49b3d3130c}}, + {{0x000044fe9d964888,0x000e0182a0c1462d,0x00091e9e94b53d52,0x000a0904b6ddd303,0x00000ab7b4931741}, {0x00015d427d3317fc,0x000a5a64671eec0e,0x0009c5b928dfc1dd,0x000330d3cc5d5fd4,0x0000995d53df674a}}, + {{0x00041ec090090ae0,0x000cedb06830302e,0x000c996902278a0c,0x0008da1d025932fb,0x0000c32fbd2b80d6}, {0x00046daf341a6c11,0x00090bef68a0d791,0x000774b3aae0ba13,0x0004d7b6b8a5638d,0x0000cf307bd980ba}}, + {{0x000bdc719803511c,0x000ac888c3bec033,0x000c6d05ea9f97b3,0x0009ea7d68aebc85,0x00003b88a9dd9391}, {0x0000748c48b0ee35,0x000bb7a746c12d30,0x0006d57f37506bc7,0x00091aac48437c6e,0x0000bd715881feaa}}, + {{0x0000408c1bc52257,0x000ab719226da4ed,0x0008d2d43d0b946d,0x00059aa09ecd6275,0x00005c8485a97517}, {0x0005f499ce4177a4,0x000e39c10c3db0b7,0x00067fcd74fa61a1,0x000fa88062d300a1,0x0000df3874cb50f0}}, + {{0x0002cf983dfedc91,0x00047d87631a29ae,0x00029c8d2f843713,0x0002729f57171174,0x00008d15867246d9}, {0x0003ecf69769bb7a,0x00062479ab828305,0x000b0f4b2c55eb85,0x000524bef7791c21,0x0000a5956badd491}}, + {{0x00096c29fe20ebae,0x000b052a5ad3407a,0x0001d9d89f27168b,0x00027963b60ab3bf,0x000045c51f0510e7}, {0x0005276099b42210,0x000c2557a159dfca,0x0000358958dc6407,0x000c320ead833591,0x0000a9db9579c55d}}, + {{0x00036d3df61bc767,0x000fcf778cdbe407,0x0006ea28f13a619b,0x0007b3fdd921a4c5,0x00006a524339fa64}, {0x0001891ac5bdc5d3,0x00028ac7dc012359,0x000df8453ff4a1a7,0x00065f6905e26162,0x0000ac045e0163b2}}, + {{0x000341bad53dba78,0x000c037b625a8a3f,0x000e311898ec269c,0x000120571a27823a,0x0000fb4f9a3d5e96}, {0x000f823ff9875cf9,0x0006cd442a9b804a,0x000c6267923224f5,0x000db08c4d3b9eec,0x00001da22fc30e7d}}, + {{0x000324d6c04a661c,0x00059e376d17a370,0x00044e3579710d3b,0x00001c2d8c98f030,0x0000364ebbf24227}, {0x0005d517733d61c0,0x0009cea826c3347f,0x000a25548d55644b,0x0000a780c6e0ad55,0x0000aa7641d84422}}, + {{0x000ec81318106601,0x0007ce4b40431438,0x0003e02739dfa650,0x000fb200b515d8cc,0x0000b6066dd38d8c}, {0x00045919c9efebdb,0x000ef21c1ff4d3b0,0x0007607d3425d4bd,0x000083afe5af19d5,0x0000bf773f804481}}, + {{0x000bd6994b03ed1e,0x0002834cc5468435,0x000e420cad9ad1de,0x0006dc4cf423fc00,0x0000ed26d8180309}, {0x0000be7a4db09d2e,0x000cb60622f7d7f6,0x00096c729f47f569,0x00071505925fd772,0x0000ff2db2706ca2}}, + {{0x000d014b913e759b,0x0005dff4de93a6fc,0x0002068e153da478,0x00052d64616d79c3,0x0000187d6657cdf3}, {0x000b6501dc90b596,0x00031daa1b26f7af,0x0000c0a848170e94,0x000dfa68e3bdd870,0x0000e8d345fc482b}}, + {{0x000bfa1c5c5ea50e,0x000b8796068184cf,0x000d50942d3baf14,0x000662463984030d,0x00004b7839d2716a}, {0x000f794e7de6dc08,0x0003e22aa7ced5f1,0x000acfeec5cd0f4d,0x000606d295f3f159,0x0000d933553153e0}}, + {{0x0008ec5776c57224,0x0001eb5f290cc7db,0x000f425a9dc467e6,0x000b7294297e704f,0x0000be924c14cf7b}, {0x000c5aea18921310,0x0003a705c9920d5d,0x000305ac58bf8a8e,0x0007a873a0b0647a,0x00000c9ca4e9a8c7}}, + {{0x000e80f83774bdde,0x0001a57344855dfe,0x0004a69a96313160,0x0000d6c1b524ae91,0x0000bc2ffb0b4e30}, {0x0003db77cfa46a5c,0x000e61653b5052c9,0x000bc580a71e6161,0x0002527574fc57a4,0x000009015dea1bc1}}, + {{0x00047b2d174d7aa6,0x000893a15d044b7b,0x000fa07ed4072d8e,0x000fb18eb7d47fd6,0x0000f2b9ffa4dbda}, {0x00016153760fe8aa,0x000f506c6c1318c5,0x000a2d0717a96e6b,0x0005cdad7a04100e,0x00001914e9babe2a}}, + {{0x000e357d8a3c5cf1,0x00031abb2b135726,0x000ae88dd1197ecc,0x000efe5c0d7f7f31,0x00005b20d1b0dbb3}, {0x000aa26705840398,0x000927dc9747cd06,0x00055d8152277c96,0x00032a3ca6958778,0x000099ea238d188b}}, + {{0x000228b760c1c9d4,0x00015b5c18da37d9,0x000f6dbc5c7efbb1,0x00005b3f0d1bc819,0x0000875384b47e69}, {0x0000baa3ba8cd86a,0x000b22905de0c7c5,0x000231952b0ce40f,0x000e25d08406737a,0x0000912a2636f43d}}, + {{0x000ddcceb5b76c16,0x0004c6fc0ab49c38,0x0002c269f746f528,0x000620f2a63a50d6,0x00000049c55f9458}, {0x0008f823c2f7c9eb,0x0002e17d5cf3e7f4,0x00001f4696bd9904,0x000fe03b1317a887,0x0000d3fe2ee4a449}}, + {{0x00079ca12ef3d36a,0x000b9e7ea5de421e,0x000ff36f79ee3c36,0x000228448198b5cd,0x0000ff4f96866b82}, {0x0009dd0c47adb7e5,0x0002b32e7dfa15e1,0x000ae026a45699b2,0x000f4cf0680c8b1f,0x0000a347a48a50db}}, + {{0x000533b3cef0d7d8,0x0007abbb4381e652,0x00080f500d94f7b1,0x000bfb038752be0e,0x0000e6e24891e9c9}, {0x000169716caca6a2,0x000818531ad9c975,0x00051ade1866c49d,0x000407a917e23971,0x0000d016ec18037c}}, + {{0x000ccc900eac3f90,0x0000e2ed4748a407,0x000c98e0d835f628,0x0002ebcc54c3471c,0x0000e969937dcb57}, {0x000c8e88f30c9cbf,0x0004473c46611b16,0x000502caba606ae7,0x00064e57aa689b35,0x000089014af3d9bb}}, + {{0x0006a9c31c71f7be,0x0002496ffe5c202f,0x000cec3a301f95aa,0x000a447fc0601453,0x0000b9912383f498}, {0x000935e5d91ba877,0x00009b564a19ae9a,0x000d44e69c6ac628,0x000d451a8fe81c3b,0x0000c8b46800dd11}}, + {{0x000251fea5b8e69b,0x000d15b75fbcf772,0x0007ff0e5aeecb3b,0x0001306aca333188,0x0000e5d49ffc9f0a}, {0x00013aae5c8646f1,0x000810e19980582c,0x000abbd94dbaa12e,0x0006637f40f31af7,0x0000f13f5a82dfc7}}, + {{0x000f1eeaceb4fc02,0x00023e6f0f425d81,0x0001370c83625600,0x0005892b67d6d775,0x0000608b69823e80}, {0x000d2fc05268301b,0x000890309212cfc0,0x000d0e1c2a6943d3,0x000c75692a90c21f,0x0000209f113e7f1d}}, + {{0x0005e0697bf1298a,0x000f819d639eefcc,0x0001e8c6fcbdb672,0x0002e53009c116b8,0x00003ffdde3ba7ce}, {0x000baaaa914d3ba5,0x000f38df85eec53f,0x000ee0751836d500,0x0006fd898dc71b66,0x0000a3d7005c1451}}, + {{0x000634d39eedbbab,0x00075455a46d21d3,0x000d7eb0c35cd2e6,0x000b3e18cafe65f9,0x0000da3ce9eb0cef}, {0x0007a602c9cf7a47,0x00040bcb8773ddc1,0x0007548df01572ee,0x0000e3392b2b018c,0x000032fd30a18460}}, + {{0x00009c716543a402,0x0006dede3c6ce221,0x00024e6149acafd3,0x000ca0db20685268,0x0000a4544a9fa25d}, {0x000526291d60b063,0x0008f87535452598,0x000f13b27281b7be,0x000eb4bc667b1a90,0x00003a83affc40e2}}, + {{0x0009862d5d721d5b,0x0002abd3a1828000,0x000a2cda40c3357a,0x00008477f3a83b7a,0x000058ae74fa6f83}, {0x0001a812e6dad6be,0x0001143d6c5b2a91,0x00096c4d8de28605,0x00024d6bdccc41f9,0x00007312ec0eae1e}}, +}, +{/* digit=2 [{1,2,3,..,}]*([2^14]*G) */ + {{0x00012e76e6485b37,0x000b071c52f8f8d1,0x0004a2f6d4d3e24d,0x000550d8e3ee4168,0x0000161957d91d95}, {0x0001283cdb12a6c3,0x0001fe50e1641963,0x00066cc73bf3fa88,0x000c38c6254b6331,0x0000aefa7aedee8c}}, + {{0x000fe623b36f9fd2,0x0003dde19fc079b0,0x0008482ef26543b2,0x000824f36e64a095,0x00003f63771bb095}, {0x000d596b6a1142e5,0x0005e35aac0b14cf,0x000081dd55ea6aac,0x00012a36a0e8bdf3,0x0000fb89d79503dc}}, + {{0x000c33af72e34d46,0x000fb10eec35f615,0x000dea34e0bd9ea3,0x000698bc12bc5bc1,0x000086584c9a9ae4}, {0x00095d38c97b942f,0x00095e5c756213ad,0x000737f894609561,0x0008b5ae94a4aef2,0x000057594c7271c7}}, + {{0x00065fce3779ee34,0x000d7d495d9e0f01,0x000284e7ae00e7f9,0x000218dfa4efa220,0x0000564bade87ac6}, {0x000312ac4708e8e4,0x000b671e9adf90e6,0x000684b9f4f5725f,0x000415a95f55ae3d,0x00007f7ccb15e94b}}, + {{0x000851b8d9465810,0x0003bdf4a0127322,0x00084dae0f0d1313,0x000c6da3510f6965,0x00003a7c1713c9f6}, {0x0007f38e475381a1,0x0002758233345be9,0x000e17ddaca1ba42,0x000c0fe83cc5c70b,0x000058b14941b918}}, + {{0x00077e5522e6b693,0x00038bcd6c18da3a,0x00024fd5669c908c,0x0003f6ef1b9e48d9,0x00007c64e36da4bb}, {0x000dbdfee478d7d1,0x000bf193f7a05a4f,0x000cd16dfba75c8b,0x00015174bc1e8456,0x0000fb08f0856fad}}, + {{0x000abf9842e9f302,0x000f3eab83af8a7c,0x0007f2a6aa331d4b,0x0000e3b272cfba01,0x00007560abca3aba}, {0x00033870e3a6b750,0x00026b9f50f594b8,0x000fdf6d025c6aea,0x000514803d691db5,0x00003b77509e6333}}, + {{0x000890361a341c13,0x000fdcfd61423617,0x00033316c3604dc5,0x000921d22295eb85,0x0000dbde4ac74af2}, {0x000fc5d1c7eef696,0x0005714f4fa1898a,0x0003c21ca5889680,0x00030aa500216020,0x0000f0d1f30a0ef7}}, + {{0x00044d4196224f85,0x0004e74d079d8e8c,0x00048f12375a4ab9,0x000ad829085ecc7d,0x00006f04d316bf65}, {0x000bf1cbda602b24,0x0002b9612c69e220,0x0004fd06b73ee174,0x0000d136008fc808,0x0000000efa031138}}, + {{0x0001b4b12cfe2978,0x000ba92f74e54820,0x000e874e83eee129,0x000c4161fe114ec9,0x000099b055d12c5f}, {0x0007a643a39c8cf8,0x000df8963cc94e47,0x00033f86382f09ef,0x000c62efd3fd8fd3,0x00005132b2b5c949}}, + {{0x000a3ab516eb17bb,0x000f22c7372b7e06,0x000896da673bec06,0x00040f34f74f55ba,0x0000b4afef93e9eb}, {0x000bec8e61d66b0f,0x0003ff29300b2d75,0x0006baa5a02bda4b,0x00043f9bbaa8de02,0x0000f54befe907f4}}, + {{0x0008b1dbe7a2af37,0x0008dfb74a72bd9b,0x000879697ec51caa,0x0007d549937a4b63,0x0000c9a9d215c268}, {0x000e44f6ef5f0145,0x0002990c69001773,0x00042161e8abcf41,0x000f29e87bd02281,0x000003937564cb6f}}, + {{0x000fd56ed6def63f,0x00018d53106c9813,0x0001f7ac153cf648,0x000faea91a35bd43,0x00001e274de53e65}, {0x000fa3c44cc78808,0x000afc256981f63f,0x000a420e0411a426,0x0008fe3698b9fd93,0x00009fdddc12e53f}}, + {{0x000072232398baaa,0x0001bcfca031766e,0x000029cf2205fee4,0x00090d049f53417a,0x000088c68b8e0238}, {0x00050417337aaa82,0x000ceeb384f4bc27,0x000aba92f9ed364a,0x000a88c0816f8529,0x0000e9e194124e38}}, + {{0x000f44a3dafd2d50,0x000597ed98d857ee,0x00007f9b135d1fae,0x0005c650628c0923,0x00009d84aaed6cba}, {0x0001bc788aaa6917,0x00093fe6cb036707,0x00078ac012dea57a,0x000a516fe11bb43d,0x0000286418cefd7a}}, + {{0x000770977f7195ad,0x0006ddeb838ffabf,0x0004f012d8ec8616,0x000b3f1a1285a8bb,0x000068835046a3ea}, {0x00024f8309004c28,0x000593ffe95eee5d,0x000223ea4a96e4b7,0x000a528cdffe12bd,0x0000f5c2ee636739}}, + {{0x000aaa5dd968198b,0x0001c2413a6c5cb4,0x00036d903fa131c5,0x000d8da3d46a9095,0x0000270f0d3f8606}, {0x0007564a053a3bc5,0x0006ca86caef518c,0x000b5efd0088254b,0x00045d63ba8cb40a,0x0000c59900e96059}}, + {{0x000e1dda1887395c,0x0005d32a65deecac,0x000a9552940960f3,0x000a35d611ff5c3a,0x000058215b13c1e5}, {0x0009b58f0e1a5240,0x000bf590dfb8d48c,0x000d95662b406856,0x000f82c7605e049c,0x0000dd036eea33ec}}, + {{0x00071acc33156b3e,0x00096a80172ea501,0x000dc8eeff09d24e,0x0004ed6e1f72c676,0x000060caadd3e3d4}, {0x000f8a6979b1d8f6,0x000c37788d26006e,0x0006feec060908a1,0x00094e0e08f95b26,0x000018427c282e8c}}, + {{0x000333959145a65f,0x00080a4063373d61,0x0008a52a0cd9bc36,0x00058f92d11be32d,0x00006877b2887a1c}, {0x000819bf5cbdb258,0x00085e090249837a,0x000990e5f2a4fd1d,0x00011ae22a7de774,0x000040fa5a0f9455}}, + {{0x00074be6558842d7,0x0003a7f3d0a630b9,0x00042e46d70df8c6,0x0008230c80352075,0x0000251fe8054ecc}, {0x00034cb5e9aac9a8,0x000470045d71e591,0x000cb1d4e11bb093,0x000c90d3e5d9b5db,0x0000d97a90612def}}, + {{0x00093277946d3f97,0x000397472273fe28,0x000b6ae86e132bd2,0x0000677eeb510c1e,0x000077708c660595}, {0x000c8cd1297029e8,0x000c3bf9305e18e2,0x00085d6d92c61095,0x0005306466c2586b,0x0000ac06c375a1ea}}, + {{0x000dc39a13046683,0x0004d7f89606a365,0x000c7228de4a9c88,0x00030335a4898fac,0x0000e2347ffb4ca8}, {0x000fb77ea7d23a38,0x000ce72a71cda5f6,0x0006a44d32fac257,0x000d79e908bef87e,0x0000ff87567091d3}}, + {{0x00090b36b0cf82eb,0x00057615b5e7e58e,0x0009c145a6438d24,0x0001ca57b1f8fc66,0x00000d8b2dae6f1e}, {0x000dadbd9184c4d2,0x0005d93d997654d5,0x000147d473dbb18d,0x000608ea3e0f56d1,0x0000afa8c8dc0a48}}, + {{0x00053e8bc36742c8,0x000e6ea0ed902753,0x000477b00898f427,0x0001e2a6f4947e3e,0x0000ad8848ab0874}, {0x0003c38d74a2a464,0x00095ba17ba26c70,0x000b9a9e45e3e05a,0x0006ec81fa6f664a,0x000074a2d9a7841d}}, + {{0x00039ad653ae3263,0x000a774cbb438712,0x000d4c08314bcf72,0x0004af5737650e20,0x0000df86536410ed}, {0x0006fe7b53ca5557,0x000d3bd5d538d2d8,0x000d38468688cb00,0x0007b65f81bda31a,0x0000ccfe3cd60116}}, + {{0x00047e06c4c1fe61,0x000a198bbb79cf4f,0x000d45a14557e1f1,0x0007c4e93b974f30,0x000074a1d2d1baf9}, {0x0003b30c51fbf539,0x00015e68b2257a00,0x0000f4173d894099,0x000152cb0aa7b71c,0x000075797ca320a7}}, + {{0x0008c07e3533d77b,0x00097e341c9926e0,0x0002dc4edd7222e6,0x000cf7ed60ec3d8d,0x0000dfe0d902c476}, {0x0009ab61d056605f,0x000596a8551f1fe5,0x000fb8d8ca9ea9df,0x000b0f9489941e47,0x0000eb874ec3a7f1}}, + {{0x000ea867ee0d98fd,0x000b0bf61864fe5f,0x000c031d4201ad34,0x00082175d8fe4737,0x00005f49faf495f0}, {0x000b291c7f4a40c8,0x0000f30ddd92db0f,0x000d769872e69d9c,0x000b86f54e105449,0x0000a24911df662d}}, + {{0x000181060a716760,0x0008f66a8ad161fc,0x00017231ee852d1a,0x00011f172bbd6564,0x0000d6de7bd3babb}, {0x0006f88c8e347f89,0x00070bd99cc36fde,0x0000769501c58754,0x0003b9e8e54ed034,0x00007f0f335096e8}}, + {{0x000e1ce4924867ad,0x000f90b84917e4db,0x000b09a79bd5f51a,0x0003d7675300403c,0x0000b3fe0f9cf174}, {0x00094d8556fa9db6,0x0008c3412fbfed78,0x0007b9291fa26216,0x000233f63be0dbba,0x0000ca8b8c06c9fb}}, + {{0x0006aa9bd7638026,0x000005303da1ed40,0x000e62ec4c21486a,0x00033e01ae291ec7,0x000022a04933f993}, {0x0000c9dbb7a8ee0d,0x000b9c01aedb7fd8,0x000be74ecdc2ed3b,0x00071e65c35a1208,0x0000540cb1b169f6}}, + {{0x000ed4ecf84f6c7a,0x000b8d090f43d16c,0x000239db48561fb9,0x000d93de693d796f,0x0000736f92917bd0}, {0x000d9292c1950ee1,0x000346dc11b307b4,0x0006a878eda17754,0x00008a95dfbbaa7a,0x0000c70cb295decb}}, + {{0x0008c8b6f0f7c500,0x0008854dcc6dfba2,0x000b78642a8eba2b,0x000adf5ff8e89a36,0x000070c1c8ef6873}, {0x000c3716484d2e49,0x000e7d414129bbd3,0x000d93b0bfb78318,0x0007f69621a39c6a,0x000079d74c339e91}}, + {{0x000564761fb04286,0x000a5ee624d4fc19,0x000ae86fd4d78954,0x000b13594896e0b8,0x0000667ac0d291c8}, {0x000051243bcf832f,0x0006b00101379f18,0x000ba8aa7fbadf8b,0x000e84d69b4089b3,0x0000ac4baced687c}}, + {{0x000088d977eab403,0x0005f760b3909164,0x0000dd55351f4c5b,0x0001c9a238238f34,0x000058566c40b1d3}, {0x000d69e5068f5ff5,0x000c8aff6b063a5a,0x000debff0f31435f,0x0003315e549a5bd6,0x00009e5f0b7c5e01}}, + {{0x0002fb898559acf1,0x000e3db79b505d49,0x0009f66aa96018c2,0x00014f45f4a48f60,0x0000943b3af5900a}, {0x00096df15a40d39b,0x00039c20f7c5c224,0x00098404cb2a4468,0x000b76c6a35afa3b,0x0000ec75726af5d1}}, + {{0x000a163bea064441,0x0002e724b6f2b67a,0x00038c8ab27e95bb,0x000e172c20e3e9d2,0x0000213754eedd6a}, {0x0001020716e0f742,0x000edfc095c28c43,0x000ac29326679c82,0x000a760eb3adf4d0,0x0000cc970d321bb7}}, + {{0x0001f2f740f0e66f,0x000a3b6b23cc70c7,0x0000a8bd7545c616,0x0007215528cfcbb4,0x0000f8396341ab27}, {0x00027d9025ac99a0,0x00002b63e33b0491,0x000d84519d314d4a,0x0004bac8c310e728,0x0000fcb8983b3bc8}}, + {{0x000226138634818c,0x0003f44c2e0b2cc5,0x000dfdba3501814f,0x00018c37e181aa54,0x0000fd58ff1a7597}, {0x000db14d3b507a84,0x000e850bdad8f90c,0x000e5f9aa57bd478,0x000854e9c197e250,0x0000db6eef9240bc}}, + {{0x000f21ad1fc0654d,0x0002b1269d732cc8,0x0007f49f9c71cc96,0x0007931cfbb20407,0x0000de925729a56b}, {0x000d6a3f97ad8f78,0x000f124de3bd9abe,0x00040a800e6c19d3,0x000f070dce92f4a1,0x00005f44d1e9337a}}, + {{0x000c08b09d64c52b,0x000f45df97495953,0x000735f7da1b5e49,0x00076a836a8fb852,0x0000332b6dc4add6}, {0x00088a0b4511aa47,0x00026bd5cc55558b,0x000cd52bd0978875,0x00096aa6b43b9cd8,0x0000f0bc5a132a26}}, + {{0x00012d4c11f61ef0,0x00043a83e79e146e,0x000bfca159ce1075,0x00053f08ec73d96c,0x00009ff29ad5b496}, {0x00072bde7da946e1,0x000bde80a4f2e31b,0x000598ce4ebf9eb3,0x000e80c1aabd0817,0x00008b5fef463f37}}, + {{0x000cdd35958cd79a,0x00047d373114d5d5,0x0009357263580a1b,0x000760036e4c91fa,0x000038c534e8f20d}, {0x000e40a2ff5845be,0x000cdd78177f7088,0x0007f9920e5bb40b,0x00005c6f06a7a885,0x00003cc3e51c968f}}, + {{0x000b7fee5682d265,0x000f5ec7f87c1d68,0x0001951ab5206f76,0x000719f111053004,0x00008ec52c224b5a}, {0x0008f990f75cf9ae,0x000eda82d0d5f348,0x0008895abf411951,0x000b1347ee75be61,0x0000ae060d54d8aa}}, + {{0x000df737fb54dc25,0x000ad59636499ae1,0x0000550811f3e391,0x0009bcd42ec32afe,0x0000bd450efd491c}, {0x000fc67981eb389e,0x00075a0550d5367e,0x0003ce75ced7e192,0x000522562e776bab,0x0000890e308ff24c}}, + {{0x000b682feccef760,0x00058bba6d92b961,0x0002375c48b8e11f,0x000cfa8f2ccc4c2b,0x0000d7f7a52e2f86}, {0x000d30a9efe5633d,0x000a8451f934fd94,0x0004e6a002d8d246,0x000c4f5234c6e324,0x0000e2b5b0eadec8}}, + {{0x0003c5abf776f5b8,0x0000e0357b052ce5,0x000bf3f7a6f72407,0x000a9f3259371771,0x00007d2501cc40c4}, {0x00052e187b053405,0x0007d1624c324405,0x000facddbb7bf7cc,0x0007eef155a6ce22,0x0000a4228cbd8983}}, + {{0x000d6d6fd4fd6717,0x000e52daa10eef87,0x000c0eb96a233687,0x000be60562224403,0x0000632d184fbf19}, {0x000f8e940735ff4f,0x0002d00931f105d0,0x000fe3f183a3e6e1,0x00020641ccde6ada,0x0000381366bbfe51}}, + {{0x00022a960167d923,0x00084529f18c24c2,0x00053b11462f9d6f,0x000043112397c003,0x000034d89dd1f808}, {0x00063ba2a4383ce6,0x0006fcf92ba0d9ec,0x000be74c0cec8e93,0x0003919b8b4288c8,0x00007d6912f705d4}}, + {{0x0006c461b9131492,0x000f1a4e02da7b99,0x0002de59436aae2e,0x000545968aa00397,0x000084ec70d6ec6d}, {0x000b2d061391d54e,0x00061e114e92f3d2,0x000482dff69c5d5d,0x0003c4de0f00b5b4,0x00001596fa6d5bf3}}, + {{0x0005b5696a71cba9,0x00026dcadeb71059,0x000cd8471944938b,0x000fe11282da4cfc,0x00008ec05f39d37b}, {0x000ce1b0698304a7,0x0003b1bdf79be171,0x00021dec12d69144,0x000f7160cd3b741b,0x000012ecd8b86a15}}, + {{0x00000a700fd56e19,0x000269527c188d4c,0x0003e42e102ec969,0x000e0991c449374a,0x0000176fbaba392a}, {0x000f1ba44b7b6187,0x000981de491c8726,0x000b582c0b4d7aae,0x000a3a891df7b907,0x0000e116c315f60a}}, + {{0x0000f81466265d74,0x00020df7adf09927,0x000738f7fb15b6fe,0x000f95be33b2d3f9,0x00008553aba16d70}, {0x0002ac8c21e94db8,0x000d3dc0bbee2cc7,0x00040478f795ac38,0x000e548a1be4492e,0x00001bd3394852bd}}, + {{0x000dbe956b3c4f2a,0x000ef04177cc63c8,0x000010fc1017a99c,0x000b20f47bbddb4d,0x0000cf9b00c5b2c9}, {0x000bc8d47173611a,0x00080c7d756f2970,0x000d541a21a4cbe0,0x000f4366d9f4aa67,0x00003e8b689f9c2c}}, + {{0x00066da4d88f1dda,0x0004dad35deaaad0,0x00078ca67c604f16,0x000e05dedc072044,0x000010dfae15a02c}, {0x0001c76af36f4e47,0x00023f3f8f48eceb,0x000c8a68c994b229,0x000c9d4f9ed77b77,0x00004f544eac1744}}, + {{0x0005bb98113a7572,0x00046a9885e482d0,0x000a7865f4ef2d2b,0x000a51fe332be51a,0x00002b76b18490d1}, {0x0002310443516830,0x0006a3f22840308a,0x0001ed9479d86189,0x0003bf5959ddcd84,0x0000def0c94154b7}}, + {{0x00054174c7c15e09,0x0001aa277c32f010,0x000dccf5f539bfb0,0x0003bd5699268ef9,0x0000f5796a59247a}, {0x0009de84f157269f,0x00048a30196b8b83,0x0008a5a91c825c1e,0x000fe57ef0aabcdc,0x00004a8ce6d398b7}}, + {{0x00035a770cbac78d,0x000b26b239581cce,0x0006cb01183488e9,0x0006573341a070d7,0x0000a6c9d077e1b2}, {0x000fb30dd648c523,0x000c22fb9fd1b701,0x000563086994ca02,0x000baad69331176f,0x0000d2b810047856}}, + {{0x00048c85963a46e3,0x0005799e61c7e89f,0x0008517b4658ab87,0x0006563e296f874b,0x00006c4fcdd2c1bc}, {0x00027a1a3906def5,0x000712418945de52,0x000d96cde9fe95f5,0x0000ddd0c91e81fd,0x0000adbe47f2a448}}, + {{0x000370f396de2b60,0x000bf0ecc7bda009,0x0001d067298583d4,0x000984f44f6b57e5,0x00003d6b078556b1}, {0x000dd93b0b64912e,0x000335687b0927db,0x000ec20a99b3a343,0x00087b2dba646151,0x0000c93db80df281}}, + {{0x0008c2466e48bdd8,0x000891ccd78e00ff,0x0002506032514f2f,0x0001566ba11f4fe1,0x0000a22cd41a43fa}, {0x0008df4b283e4c6c,0x0008cb39783fa4e5,0x00025980978c2985,0x0007dc9235aee2a5,0x000016284b5ce022}}, + {{0x00079161338830dc,0x000b12123fcaa5f5,0x000c546f86d4b8a6,0x000d35636ea68af9,0x00001d36874ba608}, {0x000e4958d436d13c,0x0000cfb080afcd76,0x000ad3fb5d4d9c22,0x0002dfa65c1728e8,0x0000f1ebe4e73d57}}, + {{0x000746a584c5e205,0x000169dc7035a7a8,0x000548c9b267e4ea,0x0002f3093a15cfb9,0x0000e6e21359bd01}, {0x000cc6a8c8f936e6,0x000455c241dcdf31,0x0005efb868af84d0,0x0002cb03990a6f34,0x0000fef4e6219b96}}, +}, +{/* digit=3 [{1,2,3,..,}]*([2^21]*G) */ + {{0x0008f09257226088,0x000a931cf5c6f636,0x000b4f7ac131260d,0x000828c0eb353bfa,0x00005c78880b7eee}, {0x00081ffc3bdf24eb,0x000b45c3c5a84c15,0x0004e6f405bff75c,0x0000c985e8c83fa1,0x000081d1c0fb295e}}, + {{0x0007cc8f43a730f8,0x000bb3ab590efcde,0x00003240be89b6f3,0x0005db4823f529ad,0x00002b79aff18bea}, {0x0002856962fe5de3,0x000b30c591f3568f,0x00028a8580c590ad,0x000f4befc74a144a,0x0000b662498e3203}}, + {{0x000cf0d6c39765a2,0x000d8c3cca0b91e3,0x000953b50a2db3ac,0x000f1a088f2f08cb,0x0000414582cef43c}, {0x0008bbc60eee9a8a,0x0001d29aa0428dec,0x00032f5d554c79f0,0x00015f381cd5ec65,0x0000672303b6f82e}}, + {{0x000afa8719c05631,0x000cac5fc79f376a,0x000750cd3cd8ad2d,0x00008e203fdb9fcb,0x00004ff052f5418b}, {0x00084cf3e2d65208,0x0007944ed509f750,0x000f25b987ebdf0f,0x000837743bf0f2d3,0x00006ad71d02354d}}, + {{0x000fe9226f435728,0x000add824758b827,0x0009094c1dfd3ab5,0x000d67b15dd23a53,0x00005c0e37ae6623}, {0x00079727be19ae06,0x00067f0d36b5575c,0x000b1ff7e616a339,0x00045341ebb3c826,0x000035b9485740ad}}, + {{0x0003cdada430c0b9,0x000daa96dac692bf,0x000ac326a4702850,0x0005e4391cf0a515,0x00005de4f4a3b8c2}, {0x000ad09e265c17ce,0x0003287b3881b01b,0x000fac5ca24e4546,0x0007a5f43e583ce1,0x000017cb3194ead9}}, + {{0x000924374dcec468,0x000cd4c2b73f6cc3,0x0006cd99c33cfc02,0x000f8902917844f2,0x0000819dd9651773}, {0x0002aa60871f4274,0x0005b6f01c340957,0x000f1f5af8e0cf36,0x000e503fa52988bf,0x0000eb357eb275e8}}, + {{0x000c8c4868af75df,0x000e55c8c7ead9d0,0x00081ecb0d7325cf,0x0004ecbb471996cc,0x0000f5d55f451182}, {0x00045411977a0ee8,0x0004f22038c6be31,0x0004bb4955085c4c,0x000081ad5335bff9,0x000094ad8a748e2a}}, + {{0x0002341ada354383,0x0008d49b8c4e5c3e,0x00017cf34f4a9fc8,0x000e108eeb355a9f,0x0000f311e0e9c91f}, {0x000003892ab98919,0x0000ae8ce9a9c2d2,0x000c53bee257bdcc,0x0004398b2d978988,0x000027ce89b5dba1}}, + {{0x0002cca523db2808,0x0009d0d43783b0a3,0x00097d16f5c889f8,0x0002e7d03e04b348,0x0000cdb6e7888f5f}, {0x0001cf0179c8e744,0x000208211d606ab9,0x000851200d8874e5,0x00040ab948d4d5ea,0x0000076d41f26f98}}, + {{0x000263c47b517ea8,0x000cb0685e5ec20e,0x0000631a079a448f,0x000346655f6f78f9,0x00008a790b2279e6}, {0x0000c7d80969fe8f,0x000351491bb96216,0x00095752654f92fd,0x000e7ab6645c235c,0x000044cc5afaea3c}}, + {{0x00083278b1e68b79,0x0009a03f29d3f762,0x000d03ecbc731ad7,0x0007a76e5a9ca957,0x00006c0d50cd1bc9}, {0x0009fe79b4f7f248,0x0007bd9967efc466,0x0002c208dfdd781d,0x000cb2f892c7c35d,0x0000bf64f7d2e545}}, + {{0x000862c467be912a,0x0009273d30ccc01f,0x000b83ec7f4c85ee,0x000cf87fa6f4be6a,0x000007a3c1cee3e3}, {0x000ef450c00beb33,0x0002d00d4c3e87f8,0x00008bf5b30e2c2b,0x000f51eaa00b94fe,0x00002c133aac224e}}, + {{0x00016bb32e5685df,0x000868e6f54438df,0x000c5ebc668a9e06,0x00035e595aaff7cd,0x0000894a646278b1}, {0x000350a09e27ecf4,0x000e18f7179df316,0x0007861baeced201,0x000e2deeec273ce9,0x00007ec2caf1693b}}, + {{0x00097c4f68367ced,0x000aee5a5755fa4c,0x00098a979e4f47d0,0x000c7c47de815db2,0x00007eca65a9177d}, {0x000bb7149ded0a33,0x0004cb34d3c520fd,0x000858a334cb2aad,0x00040efcf31d2860,0x0000b6873efd24aa}}, + {{0x00034b22c11bb373,0x000dbd4c74a35402,0x000c5f25d2d0366d,0x000142c9a968daee,0x0000660106897b63}, {0x0006d2c68d7b6d44,0x0008cc84294207cd,0x00068b1eea8f74f0,0x000ee4a275140477,0x0000b5f7e8a3e62a}}, + {{0x000717789070d267,0x000e6d1c8bc7c6a7,0x0009e1f17a1f28e4,0x0008e07a5f4f0646,0x00008fc242b6bdb7}, {0x000c5928b0588f1b,0x000c6535921ec9c7,0x000e5ae35b6b7a0f,0x0008641c5bdb91bd,0x000042c485ec2ff1}}, + {{0x0003e13dbab98aa3,0x000b717b1024a111,0x000462d3ade9d469,0x00078cf3f48b37c0,0x0000752e537ac5c0}, {0x0006add15544eb9e,0x0006a0fba279e3a8,0x0002001b5f013aea,0x0001aaab5bb76cf2,0x0000617ba15d0289}}, + {{0x00082a6936219d36,0x00044e51cb19d391,0x00007a74c5ce1f19,0x0001bc678f8598bf,0x0000d7158f282cbf}, {0x0006b21e300ce18d,0x000f5d11275d3b84,0x000239b9b35fba62,0x00093f8fe25c36a0,0x00008beb35eaf05d}}, + {{0x0002bb01f7e320d9,0x0003dda320ea4db0,0x0001389a30641c36,0x000e3cdd95fa5d82,0x000026997491fcd8}, {0x000ef17ceb6c1434,0x00019933762b316f,0x0008b17f867fcb84,0x0008217b837e3511,0x0000b92552fdfd24}}, + {{0x000c70e46aca7930,0x0004e579311bae6b,0x00002f7161cf0b0e,0x000e4d8dc631be58,0x000099bdc6fbddbe}, {0x0002bb20caf8b051,0x000a62d63df2cc35,0x000c4f408f74d505,0x000b2da9876d4b91,0x0000ce18473ae229}}, + {{0x000759783abdb4a0,0x0006dee84b184950,0x0009e67dc850fbcb,0x0006d86325236e60,0x00004d831d99336c}, {0x000ae3bfa12d45da,0x000da746e2468dea,0x000f5f31ee425f8c,0x0003b6e004c17524,0x0000ca16d904d62c}}, + {{0x0005a6a9152f9347,0x000d7d0e12c10dc1,0x000477dacf1235e5,0x000006533c06ecda,0x00006be873322ea0}, {0x00078310c0cd3130,0x0003a614260dcf3f,0x000b22d153c52455,0x000a2031a756f8ca,0x00003ee10d177827}}, + {{0x00059b21994ef202,0x0009438ae318d1e0,0x0006990102a653b6,0x00084a50d5eb582f,0x000079739f729f5f}, {0x000663c8b799336a,0x000c803c37eb5da4,0x000dbfb2dfdfdf14,0x000f9a92d8a9dca1,0x0000b40cff117d48}}, + {{0x000b383d20b42d5b,0x000eef78845fc018,0x000ba9df0f9a810e,0x000df890af3753bd,0x000090bdcfcc31df}, {0x0000591f01ab782d,0x00009af12a881872,0x000c14401c823f21,0x000be2d51b80f30d,0x0000e248f78cb2df}}, + {{0x00044e50cafe751d,0x000c04dcd221ef5a,0x00085402473997c9,0x0004ba62fd86d1de,0x00005b53add709b8}, {0x0007a11dcedd8d12,0x000854b32c84008d,0x000dde8b1406bd1c,0x00032f3d4472ff05,0x0000e25f2ce1ce2b}}, + {{0x000dd5e29dfc254e,0x00054b98b267bec0,0x0002df2ad4455fcf,0x0003962b4d43a5c7,0x0000a70e6bf28a75}, {0x00061695820f3bf6,0x000d3e37f68f2aad,0x000e5ac83f410d2d,0x000eec10fb7dba7b,0x000036bb64596ec3}}, + {{0x0004ea39754e21c0,0x00068d63c3732710,0x00009db9abc87a3e,0x000da7483351d741,0x0000fa724e360134}, {0x0004c29b0720b169,0x000276aceead9ff4,0x0006929a62dd0cf1,0x00092ac942758ce2,0x00006c5db934766a}}, + {{0x000d4c05f18395e0,0x00041f80d032cec7,0x00086075bd3f2274,0x0002db7a68b37acb,0x000074764ddafef9}, {0x000e9507bc7f3893,0x000089756460ded1,0x000a48157c580c85,0x0007b37eeec2a47d,0x0000f0b4e7fb2c58}}, + {{0x0006de8a9f19c539,0x0002d974e34e231c,0x000508fa95717bd7,0x00012449e1d216f1,0x0000f1123626adaa}, {0x0005e31823b73482,0x00058c6340698014,0x00097c2584dd8f0d,0x000431c3d82fc722,0x000076fcfeebcee7}}, + {{0x0001b5e2bc0aea9e,0x0004fe3294318eb6,0x000e4b87e4f668fd,0x000f0a23a32ab138,0x0000137451853d0e}, {0x000f7e6853ac983a,0x000dc8e78a571a46,0x000a96dd1c3bdf42,0x0004600cf207852e,0x000010649ba91638}}, + {{0x0009f0b879fbbed4,0x00069a9d1869f236,0x000766f450ff0ae8,0x0000fc1251d75956,0x0000984d8c06be8d}, {0x00095a6d21008f03,0x00000a1a1c497ecc,0x0006c50f329bd54a,0x0002517b9828c5d2,0x00002c0087c81d0d}}, + {{0x0003ce60c1cdb260,0x0007557ca2059bac,0x000b1fdcdcd94d94,0x0001491b1bd5989d,0x0000eda0108a3d8b}, {0x000661056152fcc1,0x0006d7192b339506,0x0002e05a4c2f037e,0x00062eceffb41ac9,0x0000105f6c2d2f6c}}, + {{0x00035008733913cd,0x00026f3adc4068e7,0x000a278e9cce8616,0x0002922407a94238,0x000013c1b9dfab21}, {0x0007ec71c74cf5c3,0x0008c1a4c1b493ed,0x0003a11f18887dc4,0x000cb60830ff304b,0x000058c5a3c88937}}, + {{0x000c404890228299,0x0006ab798f79027d,0x000be6ead40e9397,0x000a5d00ad333738,0x0000c23f6bd834c0}, {0x0001a35fbffd8bb2,0x0008f949d3ddd171,0x00025d93a60fcfb4,0x000967e9c8ef4b78,0x00004233cffc0a8c}}, + {{0x000e46ce6d982af4,0x000ea7544d7c67ad,0x0008bd087ebb6bf3,0x00028096b9ba763d,0x00006fe382d8dc61}, {0x000a7e8b5bdbd756,0x000158f228febd39,0x0001c4300ab38133,0x000eaba709a77cce,0x0000a247e575337c}}, + {{0x000f21b636288bec,0x000408a7c3058f34,0x000919e049dfdca7,0x0001f7adecfd1bea,0x0000df2688e4e199}, {0x000df44d0f8a67ee,0x000a2b58d010e607,0x00024f8f4d985df4,0x0001ad77f834c50c,0x0000976ef5780bf0}}, + {{0x00095aca1c323732,0x000a534c0a135363,0x0006bd5bc351027a,0x000bedb2f1b5d65e,0x0000b539e24423de}, {0x0004cec0eaa1d710,0x000d661dcf65d499,0x00054c7402a83381,0x0005ee5f1aed2f7b,0x0000bea3fa5d6dda}}, + {{0x000b68436cc61347,0x000350a443dd9d4f,0x0003b7d2a8eb9bbf,0x0002578c500e2e38,0x0000aad621ccb775}, {0x0004d740a8f7cc07,0x000d97562d656928,0x0009758eee820c2c,0x000c2d4f9531b949,0x00003e95ca5dee0c}}, + {{0x00090abfbaf50a55,0x000b184e0750f617,0x00076b005df55e76,0x000dc79c516da7f1,0x000075553bbca2dd}, {0x0007ca3553afa736,0x000bed55c25137c8,0x0003e5d35315f3ff,0x000f288846442aaf,0x00001b91149c495f}}, + {{0x00095d3fa326dc3b,0x000e68fc2cea23cc,0x000a37d591df4da1,0x000e1d74bf9adcd0,0x00006710053e20d6}, {0x000667e618344d14,0x0002606445af96f9,0x0008dbc3acc7ce04,0x000a5b602d8514d6,0x0000ea109e4680b5}}, + {{0x000a7acb40961bf5,0x00071aa56bfa5741,0x000b765d14ada593,0x0005822feb914502,0x000061e97bf36ad1}, {0x000a5b6da3982f5d,0x000ce546f468bbc4,0x000612d200c2659e,0x0008dfe8e7e6aa59,0x000083dfe217c19e}}, + {{0x000c45fb835398c3,0x000f838a41c28530,0x000f5dcdb6106a8b,0x0008ecf1e8f9a635,0x00009707137fae49}, {0x0003834d8249f00d,0x000edb2537a070c2,0x00061c0c29f14b58,0x0004a70043c3655f,0x0000c5926d6d9a19}}, + {{0x00003398e77738ae,0x000f1ba46426ddec,0x0007f6e86d07a63e,0x0002404e58e79cee,0x000059b045adf32d}, {0x00084e520fa03389,0x00085aff5acec5ec,0x000a3831397939ac,0x0008847310a4e3b4,0x0000115fba31f9d9}}, + {{0x00010c25fadf8c35,0x00027e19c0e28dd7,0x000fe502266be38a,0x0001b8842a279c4c,0x000097bb5305e24e}, {0x00086b7c153ca7f9,0x0002e07d63bd3cde,0x00060d21ea8d30fb,0x0004ab1c905f92bd,0x00008e7ffb70b9a5}}, + {{0x0007df8e9726a306,0x000f4fce3533d714,0x000f1ec40b5e216f,0x0003fd5550b7992f,0x0000b613b8801e95}, {0x0008dba792d56100,0x000aa190fbe187b8,0x000f581da2ee1270,0x000a9502f4e2dc2e,0x000016530e4eff82}}, + {{0x0003dfd8fd6ee891,0x000636848fffcbb9,0x000a47adf16d3d98,0x000a71500eff241d,0x0000b9754a01ad47}, {0x00066df70c33b988,0x000e5f34186e8f92,0x000d24132aadc87a,0x000eb98d2ce8e14a,0x0000a47cbfc99946}}, + {{0x000eb6662b5f3af3,0x0000dabb373447fe,0x000f35cb1cefab56,0x000eb9149de60e19,0x00009f8db14457f0}, {0x000cc5b3c61bfd60,0x000d41216703ffae,0x0004e1cc2a5a4d41,0x0009537f8fabed22,0x0000d5a8186871ad}}, + {{0x00074f7d22da9a9b,0x00081c8a9b0df107,0x000c32cff45b8a67,0x0002a529c2e722bd,0x0000f71b5f5e3720}, {0x0007f2f69fc4db96,0x000c165d01e195c5,0x000904635b6dad34,0x00088c1e0bd13fcb,0x00001751253d63a5}}, + {{0x000299781af2c2d1,0x000471b9d7dad85c,0x000533e8dc0f7d9c,0x000311738a34ae08,0x00005c4cb08411d8}, {0x00032858e121e14e,0x000da5000a5f97f8,0x000256274eea7dc1,0x0005bf2c6059b65d,0x0000c9beacf99507}}, + {{0x000aad71df978283,0x000578937877173d,0x000646f3cbf851cb,0x0003528083c59401,0x0000bad30cf80c6d}, {0x000b202496bbcea3,0x000ee8a1e8bafeb2,0x0000660293cf9fd4,0x0004f8a26de7ff1c,0x00009c81e9e7e9ed}}, + {{0x0000cb97b390d355,0x000d464aab27d8be,0x000ef64f801df2bb,0x0001dcee8c1a65c3,0x000067291d1c16ed}, {0x0009c6c5f5406d3b,0x0008aba8e23f9549,0x000096ece71fdda3,0x000d161feb320ed5,0x0000e7ba92c7a66d}}, + {{0x000d36bc6fb5a7df,0x00097d2dd0e04608,0x00097a36ae3eea15,0x000e1d85b0a3eb8f,0x000059814cd0c83d}, {0x000c5b01c33c23f3,0x00043faa413656c9,0x000316551a96c1da,0x000c8f16bf2074de,0x0000b866e7b4f756}}, + {{0x00027d81495ed6bc,0x0002f682dce77277,0x0008610f3b239424,0x0002a3cab8454e75,0x0000243ce85457d7}, {0x0000d71dbbf370fb,0x0006c8e0f7ca7b32,0x0007b523fff9afa3,0x000d415119d1e0ea,0x0000997f8cbb58c7}}, + {{0x000cd2a37bbb1840,0x0009a45d1fa6285b,0x0009634cb51dcec4,0x000ef16ade3b64e2,0x000080c94a726b86}, {0x0003db12283fbe37,0x0007ea9315edba58,0x000964bec902bddc,0x00030097c1ccb386,0x00008f4ead026258}}, + {{0x0003a4956f908239,0x000fe41d777b4bdf,0x0008bf760ba0f507,0x000b01791d71c3f3,0x0000633d5102b625}, {0x000b743b8c9de617,0x0003ede7472003ec,0x000ce1cb2b475125,0x0002ef2f9defc974,0x000074a4f6a70bd3}}, + {{0x00085f773848f22f,0x000603f8558eaca3,0x000c471f953dad71,0x000bc6bb7b34b093,0x0000530e06a09644}, {0x000b1ffdd59d31ae,0x000e28daa7953d9f,0x000cc88d74382e0d,0x0008ff365c6f4bd5,0x0000aa392d62a18c}}, + {{0x0003c67648024ee6,0x00022c2fabcd9420,0x000aec835188763f,0x000d54480f87acbb,0x000032c96e1529d8}, {0x000a60e4c00a95ea,0x00004011e9fa29b0,0x000b772232ef17f4,0x000e3256c0e1d115,0x0000aec2c62b4b04}}, + {{0x00088d83d84e58c4,0x000c558571dbd356,0x0000682a62af5094,0x00007c0fff7e1976,0x0000cb27078239a4}, {0x000c5474ff0e321a,0x00057b34c8ff0f59,0x000bc1ba7169f34a,0x0005438bff109652,0x000025423b823583}}, + {{0x000d5d50ac8b7823,0x000bfdb3c8925d55,0x0008bb642ff6622e,0x0003dc18fce7416b,0x00001d6998c99d7e}, {0x0008004cadcaed01,0x0002c81d053cdbaf,0x000630ec6801b014,0x000c8e84b189fc59,0x000020e9934bf762}}, + {{0x0009aa4fdc6a4043,0x000e7190994853a2,0x000e8968119d8e01,0x000d370cfcabf1d7,0x0000321a50d7e132}, {0x0006863e9a861112,0x0000e6a3bc65d049,0x0009f8eef8c0cde6,0x0001418f866c49fc,0x0000066350f1f7f5}}, + {{0x0004689e56ddfbd6,0x00079e32983a4f8a,0x0003cb8cbea1b0c0,0x00029ecb31746287,0x000058deddc8d932}, {0x000af4d0f64ef589,0x000ce30cc7a865ef,0x000047d70fe43287,0x0006c91ebc0c723d,0x00002efa53a692d2}}, + {{0x000845794b565268,0x000e8961002d06e7,0x000dcb10f415cb80,0x0009fe09e5c56576,0x0000bbb69837f925}, {0x000795b9abc26689,0x00038e678fb14fe8,0x0007da2b9b5d4f53,0x000804d601f3be7b,0x00008da59e3313d6}}, + {{0x0008ea601799a527,0x0001486d2952190d,0x000ff2a7ca20cec4,0x000d36c062ffb27f,0x000041b32e5e9f19}, {0x00081814eb57d471,0x000406aef06bf80d,0x000ecb5887a2d0ed,0x000f5af9735fb01c,0x0000641caaad6061}}, +}, +{/* digit=4 [{1,2,3,..,}]*([2^28]*G) */ + {{0x000824f20151427a,0x0005f24302067f99,0x000112357206828b,0x0004ec0a9097d7e1,0x0000cf9a2f2a9e41}, {0x000c9da279153564,0x0006c01efee3dbda,0x000b288e27e0734b,0x00009c14fab5bbd2,0x0000c630fc5362dd}}, + {{0x000107a1ac2703b2,0x00084bc857b58537,0x000daccd1b49258d,0x00052937df14debc,0x00004ab68d7e4ae8}, {0x000b5d4734e59d08,0x00084495cc807ed8,0x0001db9b35f8740c,0x0005be04aedd5a29,0x00000b360f8cfb99}}, + {{0x0005f5d5fa067d1d,0x000ec668960cae91,0x0008edaac4134b57,0x000435ed3656d6a4,0x0000ac1e3e5cc1d7}, {0x000f869d81fbb26c,0x000bf26c33d4674f,0x0004203e8449ed3e,0x000f49c5138705d9,0x0000cde538c7eeb6}}, + {{0x000c68da61a76fa3,0x000d9a1554dc55d5,0x0003b279c598b441,0x000efca39923b977,0x00003331d3c66bf9}, {0x000848e298de399d,0x0006d1a27f562d4c,0x000b8ab70cfdb8e7,0x0009b9c4c855ea57,0x0000cdb9daf3f787}}, + {{0x000f8c2019f2a596,0x00036b4fbc747bdf,0x0009173ddb3ce5bb,0x0004398a907f688a,0x0000cd3d0d3f5a75}, {0x000c4d6efed021c1,0x00005a77339a92ec,0x00088c64a09a9f9b,0x00015877ca6b1571,0x00000c2996854899}}, + {{0x000a229ed6e82ef1,0x000355ebaf4e5859,0x000ad67ae16f338e,0x000bb3fcd313875e,0x0000c73d22864ef0}, {0x000513174a5c8c7d,0x000faf69ad6a4cb5,0x00066f87e01cd296,0x000320d04d00dde9,0x000096fe447db7b0}}, + {{0x000c06e88fbd3813,0x00042c35a493342a,0x000f1bbcd02cd4a8,0x000d4cb8fa89de54,0x000041d63675575e}, {0x00057fbd238202b9,0x000a1984ead9ebe3,0x000436ea0600b4d1,0x00051b335c9f4452,0x00006fe0a3a33707}}, + {{0x00007367f636a38c,0x00064e76d5cb4c4f,0x000b68b8b9f943fb,0x000a1ef03510baa8,0x0000246780b5ed07}, {0x00014156d549fc2b,0x0000b07781ca3c05,0x000d95413c2953f3,0x0002e2e55e2c69d8,0x0000300fadd2bd28}}, + {{0x0007b5087e9189fa,0x000c542dda2781fe,0x0000a5904db17375,0x0008e582f7d896cf,0x00000e57c5b8be34}, {0x00011d3f40e3c80d,0x0000bdb705c5a610,0x000fedec3b118932,0x000c1c7ed9309e50,0x0000cf14a111d6d5}}, + {{0x000265b556913429,0x000401049dc7056c,0x000bae20ae8e0850,0x000db3831329f5c9,0x00006c8b3e969dcc}, {0x000f838fb4ee6b40,0x000b41e8ccf08c5f,0x000e050c6fc5a9ae,0x0000807417b764fa,0x0000953c3d700452}}, + {{0x000268238dfe7e82,0x00050bb79d4b2137,0x000e7cf2dea417e1,0x000fcc39641f1c76,0x000071e305a0a0bc}, {0x0007dfd7253ecbd7,0x0004dfca6186624c,0x000866e9c2f552e2,0x0006105bf84ecd4d,0x0000396770a668d4}}, + {{0x0001163c27901b4b,0x000fd99b8bf3a14b,0x000c6da0afd9236d,0x00029692b091eccb,0x0000b1dac700ad1d}, {0x0001d53a91cf76e1,0x0002c31f1ee780e6,0x000efcf774110a41,0x000d761d87c3ba13,0x0000f374bb4ef450}}, + {{0x000e2f20d188dab3,0x0000c4b885ef5e78,0x00014570fe3968ed,0x00052116c0568e73,0x0000161633831170}, {0x000e7e24f0c8afe3,0x000faeea78da18e1,0x0005d8a514caa75f,0x00037052db67f27c,0x00006a44d869f505}}, + {{0x0005bda0333974fb,0x000d77a70146d72c,0x0000ef9215db516a,0x0008e48470528121,0x0000ff17a8fbc9c3}, {0x000814e12476da14,0x0002f3c1698078f4,0x0004d4bcac1e1661,0x0000de5e5b386f42,0x0000c274e8808574}}, + {{0x000b88d6c2f5226c,0x0003950d7ca8b6a9,0x000c4170914d1b94,0x000518980c85fc1f,0x00001da368c14c6d}, {0x00085ced5113cf71,0x00034a34708f2b07,0x000cc3f880670f63,0x000c8f36e2376715,0x0000b480cfa60c72}}, + {{0x00086024147519ad,0x000b56b372f02028,0x00085ebc8d0981ea,0x0008e8d9d4a7caa7,0x0000953c50eabdf5}, {0x00061ccfd590f8f8,0x000ac4e6c9179d63,0x000eb64cf72e9626,0x0008f2ffd9611022,0x000063ebb7f1eb28}}, + {{0x000b7616aca8ee7c,0x000917b403586e6a,0x0005feb0d97d10b3,0x0002795687d3771e,0x000083e50e54265a}, {0x000a9fec954b3132,0x0007110d1f618f75,0x00057d0e0cc2e8f4,0x000207d5ba81c565,0x00005f9680c5eaf6}}, + {{0x00066094354080b3,0x00054bf2fe1cf95c,0x0007d98fa5225bfa,0x000f6095c004e25c,0x0000561bf1c319aa}, {0x0009f17ba1514741,0x0004a04f6eca5e6f,0x0009acb1edec2f93,0x00049354e368a126,0x0000332d9e41cdda}}, + {{0x000cf69df23de05b,0x0001509339a060d6,0x00069392366d17da,0x000a6cefcac9850a,0x0000cf057fd9d7c6}, {0x000c8c5f0b5662c7,0x00086cba4f24c3c5,0x0002b69ff25318dd,0x000c00f0e8cb7508,0x0000c23b3ee8e728}}, + {{0x0000a0a097e4403b,0x00056985466515e1,0x0007d4826cb3d0a8,0x000838d8d8e211d6,0x000039af66ebb9d2}, {0x0004588bd475ca8d,0x0005f077b80ba5f9,0x00027c26ce06b796,0x0005e02edb1485da,0x0000290d33bce0fd}}, + {{0x000cc47f34fb0fa1,0x00080fb1ab09a40b,0x00073bfe3b4760cc,0x00013c7fca0993a2,0x00003e4fe08070b2}, {0x000b992fdb05163c,0x00004c2b19b63bcd,0x000f2e3e28c484b1,0x0001b35acb815faa,0x00006905936789ff}}, + {{0x0006f9d586e74e18,0x000ce7b80484b2ad,0x0009c3ddb488883a,0x000d30f58aa2c736,0x0000ab74e6a1f9af}, {0x0002d285e21beb19,0x0009a18c42f910fc,0x000cf40c33484518,0x0001d8a77427dc53,0x0000de0781ac91bc}}, + {{0x000e858693807e1b,0x00069e81ccc78fae,0x000835b84a386532,0x0008d352c30ff26f,0x0000604437bbd3d3}, {0x0008a985ca1823d5,0x0008b3be0324b3fc,0x000684a33b82f7ec,0x000f7d9e36d761cf,0x0000a01df0eef29b}}, + {{0x00002f31306583d2,0x0000237c622e6862,0x0006a7bc805b10da,0x000e439f9aaa0f07,0x00005e94efbaf8f4}, {0x000c9b7fa3dc26dc,0x0002d6ff03c58a35,0x000c394cee0e5fb9,0x000e5fe77e3843eb,0x0000ede65964361d}}, + {{0x00022f6a19935459,0x000594d671bad27c,0x00069c28eab01cc3,0x000375d3fa2877a1,0x000025ef904beb08}, {0x000a3cf53aa0b32d,0x000aa1c49d7a3b2f,0x00005e27fb27beb5,0x00070ce60e1834d1,0x000060897891f685}}, + {{0x0004ce0d6fbc2acd,0x0000b15ff5512309,0x000ef119c738037a,0x0006ba0a73b1bb6b,0x0000cf6c431bef50}, {0x000fe7be3ef104a2,0x000bea06562800e4,0x00092043eebdd9a2,0x000108653a81c387,0x00002ad6eced3b59}}, + {{0x00013c039cd297dc,0x000d45bda5d99fb8,0x000104b968ec7e16,0x00050f6834797c0d,0x0000c11a2e83c511}, {0x0005a5396ee63809,0x00053ea3874296ca,0x0004dfa7d054c865,0x00020725946852d5,0x00007c422e7af4ab}}, + {{0x00075090c22b5403,0x000a87c267d4bf90,0x000b0d6932cde42a,0x0000d98a18f9ed5a,0x0000ba62aa69e466}, {0x000f97bab9ea96a6,0x000283b60e32b24b,0x0004d9bd55d03964,0x0006a3ee6a45067c,0x000066c5b9eded4a}}, + {{0x000dcd98edbd7cc8,0x000746ccd753fa3f,0x000e6b64f4660bb8,0x000b3f1ae9082021,0x0000a56a714336bf}, {0x000e0965726d47f7,0x00019b1a9a7fabfc,0x000b74a379eed01b,0x00066cc0e9cad44e,0x0000b2524ccc3e96}}, + {{0x000683b8f4b002f6,0x0009e1f4fc206a29,0x000338accc2200d7,0x0009756f3af47a3a,0x0000539a4fc47128}, {0x0001c14c33c7fcf7,0x000b57be322bcec3,0x00046f6237eb6799,0x00099aa19ef4e966,0x0000b7a26a5c4d72}}, + {{0x000f08d403f46f2f,0x00022a0ec0c7cb37,0x00032142f94b8fc4,0x000a79cb8514e3c3,0x00003ed2c34d80d2}, {0x00080afb639126c8,0x000063553ade8d20,0x0007e2b09f7b6be6,0x00002ab950aa9f1c,0x000047ff958e410f}}, + {{0x0007cf5678a31b0f,0x000d4998b620877b,0x0000fb396d50301a,0x0002a5834257c5c0,0x00009fb18a0f4e67}, {0x000d8ebe8758851b,0x0005ad99ba44ff8b,0x000fd93b71e64e4c,0x000b8b9b8eaedf7d,0x0000a2f2a98b4e76}}, + {{0x0000cbae8053433d,0x000f6d2c95857d79,0x000d8f5edc8e7259,0x000e1c88c5c476cd,0x0000106b953bfa9f}, {0x000775b0eff13a96,0x000a8057b9303c5c,0x000b70cbd242442b,0x00089a89f458d4c9,0x00009b7144903cdb}}, + {{0x00046f60e2ed7422,0x00052006749341ee,0x00054c304573f104,0x00050291e154ff9d,0x0000ad0436aad3a7}, {0x000aa2d431a8121d,0x000ab86f11edee4a,0x0004a0eb7cd38b3a,0x000e5787d49ea603,0x00002b773bec7e85}}, + {{0x0009ac49b5c1f14c,0x00097e54df2b4a55,0x000a41891c444be1,0x00078753aad704ed,0x0000d927bed1eb5c}, {0x0008516e48c8a348,0x0001cb546669eb3c,0x0004df8ec1b7ac81,0x0008649815f89659,0x00007c6a79cf9227}}, + {{0x000a2f09b56ddbdb,0x000bda2f1cf3ae02,0x0009dff0d1339b5a,0x00043d42b569c783,0x00000b9e865aee9a}, {0x000ca4177bb064e9,0x00026d249f634ff8,0x0006f689a145a281,0x000f5daab7beacf8,0x0000bafec2791d35}}, + {{0x0004c654265aa91f,0x0003135efe422805,0x00039dec7a4b1830,0x000ea47887b0e696,0x00004b8f6ae2d52a}, {0x00093cc971a8a130,0x000d4c934d07fb92,0x000acbc293f159e5,0x0001292c50e9b109,0x00008eb65e67154d}}, + {{0x000f58930b75c3ed,0x0001c4491c934fef,0x000af62bb0bb82fe,0x00049f08ac377a89,0x00007b514916685e}, {0x0009a7b04497f19d,0x00094a7ad13fabca,0x000c86ed61b35ed0,0x0006f09b601e213e,0x0000a91fcba9e0c7}}, + {{0x000507bd7ab27e14,0x000523945b7b9e28,0x000fc98277c19a55,0x000b912b43f0a1aa,0x000043b4fbd7aa55}, {0x0002e656962c88f7,0x00045e0db0ca962b,0x0008d6c4f139da8d,0x000824493f05dd1b,0x000079cdff7880b9}}, + {{0x0003fddae57c7b7a,0x00017b932522bba2,0x0006d4aa3345342f,0x000b615d9c80fe55,0x000003907bb0525b}, {0x00010e1ff2189336,0x00044a52117b38b0,0x000f2e6eac066b65,0x0002b22e14192094,0x00006a27dca6d32f}}, + {{0x000f993048b37172,0x000a9178ae1c69c7,0x0004f1d6bbf5a989,0x000e4e29fa905856,0x00007ec6e15f31fd}, {0x00003737276e7fc9,0x0008f9d6bf024cce,0x000cdd97964086d7,0x000630ca72f0464c,0x000009c3566d7775}}, + {{0x000bc6b75dd7125f,0x000697a0428d1c07,0x000eb6b9db4c6bc9,0x000431607ece52fd,0x0000ca56513a2c95}, {0x0007181d0e8bd06b,0x000716bb46ea15d9,0x00052b624384dd31,0x0002faa441ea2039,0x0000cf70deefe7dc}}, + {{0x000016e6628e8c30,0x0007b60a7522372b,0x000344ee207a0d66,0x000eeccf05751b0a,0x0000ec09a48118bd}, {0x0003d4ed83dce467,0x000d29d2fc6e6e4b,0x000cf044c43a6316,0x000fb7399d898956,0x0000c7f44551e3e5}}, + {{0x000b121fbabbe926,0x000b81330076b2e6,0x000890015281850f,0x0007f4a93581ec97,0x00009b1ddedd5ff7}, {0x000b18fab1051053,0x0001789ccfef7cf0,0x000914009953ced3,0x0008ad0151f85feb,0x0000c9f1b87b8ed4}}, + {{0x000a1a14a7eadcb4,0x0001122e71cfc9ab,0x0002e4f83928e750,0x000bd3aaede7273a,0x000067e10d15ce3b}, {0x0002ac3b955dcf05,0x000d83d5e527f344,0x00077f474ba96307,0x000ff0a763a10efd,0x0000d744bd0ba6e1}}, + {{0x000282aa777899e0,0x000fd03f3cded287,0x000b07d31e20eda8,0x000de46a7e75bb50,0x0000b7e2a946f379}, {0x00064ad19f593cf4,0x000ede76ef1d31cb,0x0002d609c7b1a9e4,0x000650a18c9c9db6,0x000039bad6e2779a}}, + {{0x0009066e032f1445,0x000898b2ec6a219d,0x000a12f781db632b,0x000265af0d0fd4fd,0x00006fb4c2d7a25d}, {0x0002ee1255a03f19,0x0002596af1765f4e,0x00068bc9761cd6af,0x00088e50317ba8d0,0x000027d6babb64b9}}, + {{0x00007e0e90fb21e5,0x00006ba7fca1a18f,0x000cd67b500fd2b8,0x0007f6d0387f2795,0x0000b89a4e823970}, {0x000ad3f894407ce5,0x00041c2261328f83,0x00006c13ba0025b9,0x000025779563c7f9,0x0000f548f319e7bb}}, + {{0x0006b8feac6d1135,0x000bbe813c762b4c,0x000e1f4b9a67e3f9,0x00050de982717c3f,0x0000886581976d80}, {0x000640cf7f06f200,0x00062a66ebc299f3,0x0007a1e08dc61021,0x00071b52f2c17576,0x00005660e1a59998}}, + {{0x00017626d3c46934,0x0006f7ed7bea6b0f,0x0005b226df0e7d62,0x00013b851758c7b7,0x00000a886285f916}, {0x000baa7bbb38ce0f,0x0004cddcad81889d,0x000c9671fe0404b6,0x0003750ebccd3a8b,0x0000bf9a358de1f5}}, + {{0x00069b028f33398d,0x000ca2e90f655dc1,0x000ab1eb1b07ec11,0x000389de7f3b4afa,0x0000970195f2f175}, {0x0005cbe0181e6402,0x00020643313d52b0,0x000f31f82f5debd6,0x0003c5561481545d,0x00003e03b335a9e1}}, + {{0x00089494fde0c1fc,0x000e25b6ec20ff75,0x000e1db6cbf8a1ab,0x00058eb02278fb87,0x0000447ad7af5ed6}, {0x000aa3803d0ccf24,0x0008419a7c0348d4,0x00017cecc80acb33,0x000d825bc7c89e6e,0x00006736b8b43be1}}, + {{0x0007b60c0432f963,0x0003aeb5442fd65d,0x000ff69a2ddebe7a,0x00012249a253077d,0x00007a56d9432cf3}, {0x0008aedf2350d0a8,0x0005837b0d9a8bab,0x000c65cae13c3f27,0x000a884664957c44,0x00008b4408a42e71}}, + {{0x000e5a35cb026649,0x0000f686c72edb88,0x00082d53e5d4c0bf,0x0004315a3d9b62a6,0x0000b605ef49b2ad}, {0x000c202c69645d0f,0x00097a1b66e771ba,0x0008f4dc4a115f03,0x00078c0e2c563a15,0x0000715b3a13d12a}}, + {{0x0000a48d413213a4,0x000d804becdb8f7f,0x0008587f52035806,0x000a71acd34a995d,0x0000d8c3079df6d3}, {0x0002a678d95a8f6a,0x000d52110d0d1b2a,0x0008fba3fc58c9d7,0x000f683eee81d5cf,0x000042be3c0ac7cd}}, + {{0x000f742d43b5eaaa,0x00063fa59b852126,0x0006bfd45054a076,0x000a8efd0d5e3612,0x00001f8fbd7d84f8}, {0x00080f5d563fccc1,0x0005e280a9283176,0x000b578cf48ca505,0x000514d00b81b227,0x00000aad9183994a}}, + {{0x0007b62b7bdc9534,0x00021bc086ddd9e0,0x0005eee779f0f6ff,0x000df0c9d1ccff65,0x00005475f799bef7}, {0x00028fa86f702ccb,0x00045f021f073faa,0x0008fa8c692e6090,0x000a2c39e629687f,0x0000d71419ba036e}}, + {{0x000e1cc6028da9ad,0x0009f251f573171e,0x000a997f45352fe1,0x000d5f28ff236e3f,0x0000831b6ca75749}, {0x0002e1de350e2c27,0x0008ae0ce4037c87,0x00074f5cbc56240d,0x00072889deb07769,0x0000d50ba88061c3}}, + {{0x00094265a3a2518a,0x000926303d43d6f8,0x0009e5696cf81779,0x00007ab10a047161,0x0000b049ff6da5e3}, {0x000f9b0feb13ec70,0x00079d8ff90ce4cd,0x000fa96afd5e9711,0x0002a2f6f64d069a,0x00000d0bf5e9d201}}, + {{0x000301f358bcdc04,0x0008ca9d47f8e63f,0x00043d43a07689e9,0x000903df689e2f4f,0x0000d542a16d0920}, {0x00093d59ca0a7072,0x00056ac68065aea2,0x00090008cd061fe4,0x000db5f033bf1b00,0x00009749558e08a6}}, + {{0x000fc59c1d5d0340,0x000667e215e074b5,0x0000200e6f712e9f,0x000588fd520cbd86,0x0000229acb43ea22}, {0x000e14cfff0c82e2,0x000239c69e739cd1,0x000ccb98987684b6,0x000493ba85e61c96,0x0000d5dbb02c3d06}}, + {{0x000d33ae86b173c3,0x0005779ff0e3f22a,0x0000d0c10e8e41ea,0x0008f8d1d2d725dd,0x00001f39088332d2}, {0x00071e17829839ea,0x0003a502ae587b3f,0x000fc61150cf691b,0x0003144f658dbdbe,0x00005cd6ee653ab5}}, + {{0x0008d7b5f1d23474,0x000a0cc2253a206c,0x000389e08794645b,0x0002889517d8ff58,0x0000fa20deedf847}, {0x00072d8d797770a6,0x000d5f429e26eba0,0x000af82797360c91,0x000ce31200a3b380,0x0000a1c9150e2dad}}, + {{0x000d3a7c35d87949,0x00077356bae50ee6,0x0003322fd042e655,0x0009670f59698d64,0x0000379ae15e0a61}, {0x000ae62fcc9981ea,0x0000cd2934c664b9,0x0004e65ebaed3d63,0x0004278454b3025e,0x0000b09f64899950}}, +}, +{/* digit=5 [{1,2,3,..,}]*([2^35]*G) */ + {{0x0003a1222248acc7,0x000ec264e366b208,0x000fdee281f6ec0e,0x000bb4e659b7045a,0x0000a823a4156430}, {0x0002a04e1900a791,0x000ab9ee65762459,0x0005ea54acde09d4,0x0005a742b6463f4b,0x0000efe9ed3e3ca6}}, + {{0x0006dbe305406dd9,0x000f4d5d1957e27a,0x0007d4d8f8eb7dc7,0x000de4654a687638,0x0000c47940a57762}, {0x0005b5d99b307781,0x00065e793682be4d,0x000c740e325380c5,0x0004ae502d37f3da,0x000040deabe2566e}}, + {{0x000d067afd32acfd,0x000a11f71ccf4481,0x00096f2dad8f0fcc,0x0003f90208dd0cb5,0x0000049d7316aad9}, {0x000263d42ab580e7,0x0000b3f707b4c79f,0x0005e0eda09411bb,0x0004021cfde1ff83,0x0000270749100f03}}, + {{0x0006126c49a861ec,0x0005214f0d06eaee,0x0009bfc17024f3b6,0x00038091a3f1e8c6,0x00003c3a8ea67686}, {0x000752cb103d4c8d,0x0002c218b36b3400,0x00051504a02bc461,0x000bf9f67f75eb76,0x00006848b57a02ae}}, + {{0x00002e6c30fa92bf,0x000caa552784bd98,0x00083169b5a70d96,0x000227a085c4ea3f,0x0000a9423bbf6908}, {0x000be12fe97a5b9f,0x000881b991182ffe,0x00017884685da604,0x00018dacbc2f7f63,0x0000d96bc7181532}}, + {{0x00081db1782269b6,0x0008c597e5509583,0x000385153ae34bf7,0x0000485b5c60645f,0x0000f0e96b043088}, {0x000021577884456e,0x000b89310ea7bf6a,0x000fad2deb3b5688,0x000d4c37c9429504,0x0000020f0e5f7896}}, + {{0x000a0ab0976505f7,0x0002995e2ec5730b,0x00031ab71567f681,0x000b9ed706201063,0x00002cfa977b1d22}, {0x0005ead8a2373da8,0x0003fba45a6833e5,0x000029d15a8d0d5f,0x0009f33a1d8f9c03,0x0000f34f1cd7c55b}}, + {{0x000428dbbe5a1a9a,0x000e9126bd67cca4,0x0001058268187fd5,0x00019f6036973a48,0x000039b666458bd6}, {0x000deef2d65a8087,0x000f24636b196d42,0x0005d564c4969044,0x0000778611ee47dd,0x0000b2f3a4a42873}}, + {{0x0007d45300eb294a,0x000d769c14949415,0x000a47aa92b2a656,0x000ea42000dd76d3,0x00002864e5046243}, {0x0006c47db89842e4,0x000721479fb78271,0x000b2f6dc12dfd7d,0x000d66fb9a2c56e0,0x00006be862b17f85}}, + {{0x000d8dd0f82b2148,0x00097103cbc603b0,0x000d79e19460c34f,0x0007f8732e5c0318,0x0000b8888bb28411}, {0x00037dcc07226779,0x00088c1c0f278f3c,0x000f7a0c610d21be,0x0000e0447c8468e0,0x0000bf022143decc}}, + {{0x0007d1242b48b998,0x000cc84240960baa,0x000fb5cfb1bcb665,0x00010d0b847cd6eb,0x00007c2ae571ad4d}, {0x000b1220de367261,0x00082fdfbd21f1cb,0x00079d460e7043c6,0x0002cb3bd0826a4e,0x00001f5e5985bd1a}}, + {{0x0004160b7fe7b6e0,0x000a400a3fb29755,0x00028ca1e7d16189,0x0008ccd73e9beae3,0x0000dd04b97e793d}, {0x0003c9b506db8cc0,0x000ecf38814ca9c8,0x0004b45e65cd47aa,0x000a8426fc430db6,0x000079b5499d818e}}, + {{0x0001102c1c24a3b9,0x00078c161c1aebb0,0x000f00a4aca24e56,0x000c7a803eea6936,0x0000ad76ee906176}, {0x0001fc2538e0ff72,0x00094604b3b09745,0x00049cfd794f8980,0x000f694311436e32,0x00007b4a7bd61224}}, + {{0x000d21ae0ac29416,0x000462d3193703b5,0x000c992d0279b025,0x0001f2d307c052ca,0x0000aa7cb934fa8b}, {0x00025800d37c7a50,0x0007342d54225a18,0x000d2ef9213380c3,0x0003c692ac2d66d5,0x000035a70c9030c6}}, + {{0x00025dd4ce4f152f,0x000109df7c06c160,0x000e4bb141f419a7,0x0004cd7d5b221491,0x0000c43c6cd739fb}, {0x0006591925d6b2de,0x00028218659849f0,0x0001b16294b37d9d,0x000e04ac54a971d0,0x00001a9c2a031d50}}, + {{0x000b78571ba18615,0x000c80c8f93d5109,0x00033bb9348b22d5,0x000d0898fa84a786,0x00003fba6baaaebb}, {0x0007df3e5eea7d82,0x000648ca71587ff2,0x0006f1a05521c879,0x000ee499d5133bce,0x0000d50cd541d0eb}}, + {{0x00015d6c5a3ef169,0x000d2a079221c821,0x0005da81c993eff9,0x000d8554da2c5e4b,0x0000a89dbdc1033f}, {0x0009ebf2b892891c,0x00009d14a4d56081,0x000fda42153902b2,0x000283aac35051d7,0x0000c6ab88621c83}}, + {{0x000a133f74cff170,0x0003ecb813f214eb,0x000665bee240aaa0,0x000d73cfbb65406f,0x000084b1fe4a425a}, {0x0005d16d081f6a60,0x0008eef82c90009d,0x0009eaa2235304fe,0x0001e3f20346d5aa,0x0000ada9f07ac1c9}}, + {{0x0001678968a61446,0x000ba7b31a1ea6e2,0x00081fbe154c1f77,0x000c4a76bb787e57,0x00001bd2ee1431f1}, {0x000a1e9781105fc0,0x000f7b2f8e80f25a,0x000ff919b9cf2971,0x00096e26d15412cd,0x00001db4ebe34bc8}}, + {{0x0003e23b40df1cf8,0x000314e971b47d9b,0x0009cf9215933737,0x0000643f57bd1466,0x000065daedf8c1a1}, {0x0000bd3832791254,0x000ef4ecdaab3eb7,0x000755cafbc3d5b9,0x000f0251e3ed7e5f,0x00009699f55141e6}}, + {{0x00070e1d4a7a15b6,0x000a8aac87e71857,0x0003133ea08f3587,0x0000fbd52018db47,0x000074ce71964fd3}, {0x0009835088b3e0e6,0x0008fd0d47a17b8d,0x00074a3c47a0356a,0x00066c3d9e765964,0x00001ea48a85f669}}, + {{0x00077580f3e48342,0x0001f7a9afcb3041,0x0009a67b3fdbb21c,0x0001a8556fa17f2f,0x0000a6b2421c245c}, {0x00027944af02291c,0x00056a5804fe64be,0x000f08fd7ade465c,0x00003acdffbd39a6,0x00004efa84d6a144}}, + {{0x0001b2a442b0f5c9,0x00073f997736a1b9,0x000e90e16b748e31,0x0008bffd1b62bfce,0x000007ae2719b207}, {0x000534b0c9bcddd6,0x0003d9adce83df31,0x00026846a043fb05,0x00039339031043d8,0x00001a9c0d71144f}}, + {{0x0008046477184276,0x000b0e830f8bdab4,0x0009a1347df17ff9,0x0004ade08d7ee8e4,0x0000ac71e23f1c1d}, {0x000b9fd1defd73c7,0x00074bbbfec5c8cb,0x0007ef8ea1984065,0x000f2fc9db1cb59e,0x00008aa8296d4105}}, + {{0x000b7f0a3738c290,0x000abc3250a3a3d9,0x0005e4caf0a2f235,0x000f7a55e506f644,0x0000974f73d33475}, {0x000bba35ba2f5a80,0x00036af40066d37d,0x000d73e2c542c6e6,0x00033e26d99b53c5,0x00006060d7d6c3ca}}, + {{0x000f1c2065fef4a2,0x000ddd5b92e3cdbe,0x00070835077e60f7,0x0001bfb7c549f026,0x000001b3ad054f12}, {0x000c2a10334fc145,0x0008e44552f65fca,0x0006530828a9a9e0,0x0002892dd8a1d397,0x0000fc0738fc9d4f}}, + {{0x000244d17d2d8c38,0x0004f0830684787d,0x000f73ae5effc634,0x0009a4dddb96dde4,0x0000efb14b197254}, {0x0003eee2245ae7aa,0x000e4a11f13e6eb7,0x000b01f5dbca4061,0x00052c1577421d30,0x0000a688b25182e1}}, + {{0x0008e71bd3502bad,0x0003e4de75a06760,0x0006125e54ef41f2,0x00043ee08dde5efd,0x0000e48482674095}, {0x0008d9865cc22950,0x00016e0edfa21f19,0x000f35fc7428a377,0x0003c74f9697a2ad,0x00001a43c79f7cac}}, + {{0x00070590fd3659a3,0x000c8b7f2d9ab05d,0x000f984d38927f30,0x000a451023d1ac8c,0x00002125ed332897}, {0x0002dad3d4142055,0x000293fa82a9fb57,0x0000a558173000ef,0x000ca4fc0868e9f1,0x0000b61fc67bb0b3}}, + {{0x0008d5b7cae440c3,0x0001102b7531c125,0x00093232121c08b4,0x0008afc61a8955de,0x0000568faf85d140}, {0x0005e999ecf965b6,0x00088917276f71b1,0x0000cf9e2f14ed24,0x000c7e66f4caa182,0x000081b20b278d83}}, + {{0x000738dc6c011203,0x00037e70e0db6cde,0x000afe18c71db081,0x000be765fc064474,0x00004619053429e2}, {0x0005ceadb2a3b15d,0x000e0b4c70738061,0x000d2d3670a49a19,0x0008a93e1b84c88f,0x000074bf462d33fb}}, + {{0x0006d65533ef2177,0x000453ca2e87889f,0x0002b41677158c7e,0x00057f8b670dfbdc,0x00005910a01f44c2}, {0x000bf07cf88577d2,0x0000c45e2acef336,0x000a23d852224525,0x000f580ed92e8d7c,0x00009f8be4c4b812}}, + {{0x000baa7076fe12bc,0x000aee1537f9dd9e,0x000bdfb463f2400c,0x000b405aa9352817,0x00000f9843127883}, {0x000ede10170911db,0x000a84d4b17f5590,0x00026b8d27562f5b,0x000d5931fa1df218,0x000040b796b1bd80}}, + {{0x000f1973467ba92a,0x000b570954b0d65b,0x00078f15d8c9b46d,0x000960f7c8a0f30e,0x00008f3a69b25a4c}, {0x000660f61e4ce9b9,0x0002dea6790c4242,0x000986416bf06aab,0x00022536706f8eec,0x0000e56dec22a9fc}}, + {{0x00046f49a9898d9a,0x000ab633cdef527c,0x0009e4297d799e77,0x00073384eacc167d,0x0000bb61ceb0b1cb}, {0x000e8a7f778443cd,0x000059de2fe6bee2,0x00003bb6f3bb42bf,0x000df5fbed86a130,0x00003918e6da781c}}, + {{0x00032719a5103f11,0x0006e50eac064bee,0x000dcc1195243efc,0x000a08a8e122cb6a,0x0000b7faa84d0b80}, {0x000d1bd6dfcd08ca,0x000d6be427de32c3,0x000263c83129dec4,0x000efef8ab679c1d,0x0000fc83cb86ef64}}, + {{0x00060882fa6be76c,0x000a5328cbfe85eb,0x000618dda892585f,0x00026e0154d3edcf,0x000044f601bfabaf}, {0x0007d0b2be1fdfdc,0x000c61137fee7bf5,0x000b591a8a833bd2,0x000055d353af362d,0x000076f26dd1562a}}, + {{0x000e47d3fdf5a517,0x0002e5c9cab01d87,0x000e0586e7afb5f9,0x00070921bbf58f89,0x0000c72c0187d843}, {0x000aafb99b5c3dc4,0x000cf844aeb0a9a5,0x00067e482a48a0f1,0x00059a3178b7ddb6,0x000053985e9ae23a}}, + {{0x000c86001b25dd8c,0x00083b897c8a4a54,0x000a90cd90dd37f4,0x00030c9f8aa6100e,0x00008892c68d6d58}, {0x000efc0ef514ca5f,0x0008f72c9ee6eb4b,0x000c40d5f478eb67,0x000649abca20dadb,0x0000015de22cde4f}}, + {{0x0004de0eaf4b8a5d,0x00097bc60e32aa6a,0x000d15e7068cfd9c,0x00009c968a4b017f,0x00009f0694bc27dc}, {0x000cad5ba708bcd2,0x00093bb95c2af6c3,0x000c0a58f5cd2ba6,0x0008708a28c1d333,0x00003e274e3cbc77}}, + {{0x000692ddfd20a4a9,0x0002f1a6665344c3,0x000a0757d091c5fd,0x0003e9dc0bb69109,0x0000072e8b9f6734}, {0x0000eb080848beca,0x0009d9fd36cc31d4,0x000ed43f595bd480,0x0000be61a77c6165,0x0000fccd127ce0d4}}, + {{0x000c82d1cc1884bc,0x00009d4753b4eccf,0x0008e099fc85ac20,0x00039007a6caac65,0x0000f46369ec4b27}, {0x000d049506467ea2,0x000217cdeccce2e7,0x00080143a481b63a,0x000b882029abd8ed,0x00008bfe3c7dcb00}}, + {{0x00010090643d84a3,0x00087bd110413bec,0x0003a34d6885f366,0x000ebeab02432cf8,0x00002f7b360a19ce}, {0x0007837dad1fe7ac,0x00089441a0b0f06c,0x000d4755060a157a,0x00001fb04970e9e2,0x0000d2bd553e71b9}}, + {{0x000f82f33e24a0b2,0x000fd2565079ff57,0x0005f58259cbee23,0x000661f6353427eb,0x000076feec50948d}, {0x0002bc6da10032b9,0x000d60e72a53d1b6,0x00020e7ba718351d,0x00018d0345207624,0x00006368fffca001}}, + {{0x0002d26150a49e46,0x0005df04706b00ce,0x000b196d00c28b63,0x000b7c5ad65a4658,0x0000c8455fd4c9f8}, {0x000895f2d71867e2,0x000bcdf9f38ce90c,0x000f6ec045c0be31,0x0002510a37a15ed8,0x000039639e7acd85}}, + {{0x00053159c7c4c6b6,0x000077409af7d897,0x0007132fb603aa3c,0x00023858d53d0c00,0x00008d12af806849}, {0x00007e7bf5d92796,0x00054ada74cebe06,0x0007e8ccb9aa5005,0x000f5e881079cbba,0x000010c71d205f4f}}, + {{0x000e1a75aa07093f,0x000ab75da47c9e2e,0x000e75401ca84004,0x000591174d39513d,0x0000938f757ab311}, {0x000761800a43421b,0x000157bc78c89619,0x00017127639a2536,0x000f07778f710a0a,0x000028446eb3d1a8}}, + {{0x00081bfe3b6a6611,0x000dd6d279f71847,0x0009eb6627751cb1,0x000ea7e8ff95d6c5,0x000086d90b768d3d}, {0x000b6c1dfb4f754b,0x000a7b2801dc0e4b,0x00054564d5c5cf56,0x000f131561e4521f,0x00004fb8c61a0dd7}}, + {{0x000963033ff98c71,0x000abf17769cf884,0x000fdd80a9619fff,0x000e63e8090bf61b,0x00004d9a149522cf}, {0x000c3606f6df9ea2,0x000d018f17eab354,0x000eb3480dbcf770,0x000a26007db7c879,0x000013dbda8759b6}}, + {{0x000200b29fc81b30,0x000f171d87c1ac4c,0x00081aa9eebc3e09,0x0004fa9179953014,0x000051b92e192e11}, {0x00092e9ecb5537f9,0x000b990c7483df8f,0x000deb01644b1b2c,0x000c2c1711455a2a,0x000064b685711a10}}, + {{0x0009d99cec036235,0x00059f3271ea4f15,0x000ee48490553222,0x0001036231bea3c5,0x00007a54f50c094f}, {0x000421d9598b3525,0x000c17412ab43e2d,0x000c3a912e865a49,0x00065d82998a251c,0x0000d0928085c74d}}, + {{0x00059084088567a3,0x000def214a6173f4,0x000f0c13deb6b280,0x000b805c9adc34ca,0x00009d129392561f}, {0x0003a5ebc6edfb49,0x00016e4d210eb2dc,0x00086ae727485b1b,0x000b87762e0400e1,0x00001e32d5cfeeb3}}, + {{0x00074d74be59224c,0x000bb16d55f36df5,0x000d6ed33ebc88cc,0x000b0f66c2e6d0ca,0x00006e21e7dcd3e8}, {0x000840e5bcc36bb3,0x000e4da74f692cc5,0x0005193a89292445,0x0004135be8d3214e,0x0000ec23629bdf06}}, + {{0x000ae85b134defa9,0x000f8bb2d475c7e9,0x00063c00d6073b1c,0x000ac429ad615e28,0x0000e29493de25f4}, {0x0001dea4e9acf4f7,0x0008350db88dc32b,0x000da916c3e1f01c,0x00003e405d70ea04,0x000014b0d0b48658}}, + {{0x00093fc9920cb5e5,0x000742c7a3ac4bd4,0x000ec92355b44b1f,0x00055352a77293bc,0x0000ee06e881d378}, {0x0008173da621607b,0x000be9f5d290ceff,0x000f734ac2bb03e4,0x0007317945106aa6,0x00005056605825c4}}, + {{0x000920ce079afee3,0x00003789831f5945,0x0004a5ae5686e17a,0x000d462966bee8b7,0x00008a673a24e258}, {0x000c1f283141c954,0x000ece96e486bd1c,0x000e5fc783b2ecf4,0x000a7a8d3aa89674,0x000015ec10c6482f}}, + {{0x0004419805033800,0x000ad314b3921523,0x000caecae513d917,0x00080bb0b52f4e63,0x00007bf22ad2dc77}, {0x000e8a1e4306839f,0x00016dd7feaae761,0x000c778f11b3be96,0x0000f55fe728de74,0x00001fa0bdb4e007}}, + {{0x0005a316ec3f510d,0x0004029804758520,0x00030ebfd2c7e4a1,0x0006440e3c19c06f,0x0000b1c1f39a4b7e}, {0x0001a755dce364a2,0x000be58f5be3fe29,0x000fea38cb7b22a3,0x000e170cd2c30237,0x0000930967a4e17b}}, + {{0x00009de0c061c658,0x000c6dc6ed4487f0,0x000afb1ebcb014aa,0x000687c9bd1cb43b,0x00001bd8b5ca82d3}, {0x000b87ef01a17aff,0x0003f710063b1cda,0x000fc819321f37ac,0x00015b6a6c567642,0x00004753e7146a60}}, + {{0x000795ea15b0a44b,0x0006d958a958020f,0x000b675b58f37c8d,0x000ae9b3b7e89ba4,0x00004fb0c0cbfc31}, {0x000e639a7ff1f2e5,0x0003119614fbed95,0x0007151ab9880f5a,0x000cdb8eb6ff0294,0x0000bc5118cf868d}}, + {{0x00020554c20cea5a,0x000d74c4d69ad8da,0x0002d599bcac2776,0x000b502ccb22c162,0x00004ddb65408a9b}, {0x000f1511b4941b44,0x00042efba5882c4f,0x0008345e0e1ff19b,0x000fc3f5034363c4,0x00005542e3d5e29d}}, + {{0x000cb91349f7aed5,0x00003fca8420f197,0x000aaf6d83b2b5a0,0x0002b62c175ee823,0x00004dcf42185af3}, {0x000430727d6561e7,0x00046175b1e20ba1,0x000807db5879d5ee,0x000bcd57c4367399,0x00007a544560cd55}}, + {{0x000ff130105c0720,0x000f8dda7da4e6c2,0x0002d35c118f7a99,0x000c824c3018200e,0x00006a53ca0d9cc6}, {0x000cc1ef1aa1d9e1,0x00043a75b1e8aa21,0x000be9fdc3241433,0x00055a1a6d13280e,0x00006bd173fa8a47}}, + {{0x000b2452133ffd9d,0x0000b30f1a20fbb9,0x000a1f52a39a8b2f,0x000df7784bc97dd5,0x00006aebf57740ed}, {0x0007acb76ccdac60,0x000c1586ff273225,0x000de7dd1af4d36e,0x000c168eaa8863f8,0x0000045d5cf88647}}, +}, +{/* digit=6 [{1,2,3,..,}]*([2^42]*G) */ + {{0x000d574c005979da,0x0001ca40e350a6f3,0x000e2ecf9c2072b4,0x00044e5ca5c1568d,0x00008c8bf5c45153}, {0x000e555114df14a7,0x000d8dc5ec6b97ae,0x000a85418d4374a4,0x000f78054cc28f2c,0x00001cb9e2843c41}}, + {{0x000507903605c397,0x000e3142c96c8910,0x000923684f0843d9,0x0008938374493416,0x000032caa306a0a2}, {0x000c27061160170e,0x000b637fbaa3b2e8,0x000eda3acc32788c,0x000e0659cd818ea6,0x00002e9423a7e2b2}}, + {{0x000d39b0260e52a4,0x000c506533256967,0x000ca7954d42585c,0x0007b2cd9bd60521,0x0000fa20877c1ed5}, {0x000eff8e34a0bbeb,0x000bd4f6ef6460c1,0x000af848356b0040,0x00061378be2b24b1,0x00002278164a5531}}, + {{0x00075455922ac1c3,0x000c752b3f638df2,0x000de57c4a7b3ef5,0x00008b5e77b21471,0x00001682c10b34c0}, {0x00024f04bd55d319,0x000587b61c71c768,0x000a5089db6d1c08,0x000d3ea1db0903c2,0x0000c092172a84e5}}, + {{0x000ed5bc00cc638c,0x000aa1278fc2dd7c,0x00037f8d61a2015e,0x0003ac6e8e52886a,0x00004577870a7993}, {0x0004cce2c51211a6,0x0001c4c20498b3fe,0x0008db5e5ad9b10b,0x000fc330d87a4fd2,0x000098cd1059aca2}}, + {{0x0002d07e91b536de,0x0001beba09d64f11,0x0007c396fceb982f,0x000b235c157b2c19,0x000023c2d425b66e}, {0x00057d93f330d370,0x000179108deb480c,0x000199ce5b3a4c8a,0x0008d4702388decb,0x0000b019211b944a}}, + {{0x000a692840bb3366,0x000c4669fa7b24f2,0x000c9c3007c353bd,0x000f177a20d6fcde,0x000025fbe30013a4}, {0x000b61adbc173281,0x000f99515621a2b1,0x00020ff46008965b,0x00091c39690939c6,0x000082dd27d9717e}}, + {{0x0005035ea6c39976,0x000a62610bef5ace,0x00080dd3954259aa,0x000a398f18bb3f3c,0x0000910b95bbfc3f}, {0x000f51043e09aee6,0x000f47675665fce2,0x00072db61ced56c9,0x000e68b0e265acd8,0x0000982812f0e9fc}}, + {{0x00011c6ce8009982,0x0002990360d929be,0x0004ad59072bb175,0x000bc00c1931975a,0x0000ba2f548bfc1d}, {0x000eebbe490ebe0c,0x000cbfae11c07fe4,0x00003ba3712a0a4c,0x000dd7b197cf81e9,0x0000f7d4aa99e1c6}}, + {{0x0006bf43fd5684c4,0x000f40360aa192af,0x000546a822b26eec,0x0008fe7d960f3000,0x000007b3c44359ad}, {0x000e5fe249c82ba0,0x00072463744c86ca,0x0009162729e0faec,0x00061587f551e894,0x000033f93446ceb0}}, + {{0x000b0d18be82e84d,0x000daa582fef1e5e,0x000e921fa89967f0,0x0009b9ecf687d5a6,0x0000fee4cf4a37a0}, {0x0006965b493c465c,0x000bb635c03094f0,0x000f05e9f638b9a1,0x000724b666786466,0x0000caf6809804da}}, + {{0x000b690768fccfce,0x000cd835b362ca2e,0x000fdfccef402d37,0x00098f2efac0d0e2,0x0000fc9cdf09638d}, {0x0002b72d1669a8bc,0x000b9774ccbd2af1,0x00034870e33c536b,0x000ac970b21909fb,0x000038fa2f83df25}}, + {{0x000f02bbf81f3f5e,0x000dcf7e458174c5,0x0003c54ae0525a5a,0x0006c4a8d2aaba43,0x0000d9775dc606a5}, {0x000738ac0edb37d9,0x000dd6cc1f51d320,0x000600d7625fdb6e,0x000d761c661d1710,0x000031ec1f44dd1e}}, + {{0x0001d6219ee43f1f,0x000d70829d9765c1,0x0004be6e85cd57c3,0x0003bce26c91a398,0x000008d930a7b0c5}, {0x0009e5bc016e4eae,0x000831d43d2b94bc,0x000701155d391683,0x000714a86c5ad773,0x0000037762700b00}}, + {{0x000c9ecaa80ba596,0x000a08538e517f01,0x0008128af3083411,0x00014b370370f1e8,0x000025cc3dbf1dec}, {0x000666c01ac3107f,0x0006e5057ac3fef9,0x000be5df7b2a8d57,0x000923c0f2629992,0x0000579c8e5f0353}}, + {{0x0003d931341ed7a4,0x000c67b59d49b8fa,0x000b8c4a44223272,0x0002e3fdcb194783,0x0000e413c022d130}, {0x0009127e17e44ceb,0x000483b3adfb6d99,0x000aa96caee86bf7,0x00047d46902fe625,0x000073540e595aae}}, + {{0x0001d7b1b4a158cc,0x000d67e2a3693280,0x000d9f197e571c99,0x0000ad80cb76c010,0x0000308c289f167c}, {0x0009dd3eb7958f24,0x000bf00879b1a6ef,0x000df0636a7226df,0x000eed2cd0b3627e,0x0000efbce6cbbc37}}, + {{0x0002a058d6990216,0x0009172566e375f9,0x0001ad23a586d4c7,0x0008abd78ca5f176,0x000050d86fc7465a}, {0x000d457842ba251a,0x0005a22349337a4e,0x000aad6576b65e3e,0x0003690f1543b731,0x00004cefe996bfec}}, + {{0x000da909f47befbc,0x000a81312d13b587,0x000f1cefe6562e9f,0x000cf5e691ea59ef,0x0000c30477ac5fc4}, {0x00024610b0ffd3dd,0x000a8b355956a163,0x00024ec24a1f16f3,0x0001298b148d5342,0x0000c834e7cc9770}}, + {{0x0005e75b2c69dbcc,0x000843c3da6c7bfc,0x0009102713aa77a2,0x000c551e0df03cca,0x0000bd5ca4b3806d}, {0x00058076db476cb9,0x0001cf37a31ee1ca,0x0001af416fde15d6,0x000db5649af520f4,0x00006c5c5b20d342}}, + {{0x00043b7eb4ceb9be,0x000f6e77371a155c,0x0005d43af2e99300,0x000d713d2987da67,0x0000f2bc1c16599f}, {0x0004b7b9342f6b2e,0x00019c8e71f09689,0x0001f3efc201eadf,0x00070413479d9f4a,0x00000f8a743502a9}}, + {{0x00044b6b3eba40cc,0x000901c1e0d0eafd,0x0009d505ef9739f2,0x00063d4091471a61,0x000015f9c975d7c2}, {0x000728583afbe332,0x000ee4f1e0925be4,0x0001a9d11a3b6d6a,0x0004d2c76526b975,0x0000ec5b26dba4ae}}, + {{0x000f4d902f6fb8d2,0x000176912164eb66,0x000ef30004063c56,0x0003f0cb7050c180,0x000088d1c340aa5b}, {0x00068d607806fd8f,0x00045bbbf50fe87c,0x0008d6627b2f7f9d,0x00013a35972f3aac,0x0000854777500e8c}}, + {{0x000ef6c872b4a606,0x0003e613521bcc50,0x0003e15d1ab2a34a,0x000511d9c5c19098,0x00001dde5dfb9905}, {0x000f6219f2275f33,0x0006151d894be417,0x000b0bdaa0750c8b,0x0009bd45b04ab978,0x0000bfd9fd475858}}, + {{0x0003e30ee9120b67,0x0002b3a4743ef101,0x000d14d9e2b51af9,0x000d327a96ffae48,0x00001dc0dbed98a1}, {0x00062d20180cca4c,0x0007035689639149,0x0007bc4441ae6067,0x000c79ccf227b143,0x0000650c83c89962}}, + {{0x000c7ddfe7ccfc4a,0x000c7b929d4823c2,0x000783c33f925c89,0x000759a460f74b06,0x0000c2c8d4a45904}, {0x000b407b807bba06,0x000d09ff8f3afb40,0x000ef64a49d1e362,0x0004b2433e9681cb,0x00007ece5fa932fb}}, + {{0x000a99b739f10e3a,0x00095f5259256900,0x000e2d041c3341ca,0x000ddd4e18a626a9,0x00005a83685c9580}, {0x0000c819d7de3cd3,0x0005f062cf9cf347,0x00010edb0edf0258,0x0001aec43522fac0,0x0000031413543a4b}}, + {{0x000e02adb22b94b8,0x000921eaa45bc792,0x0001e1c63993d8ae,0x00088a0aad6cd3cd,0x00009529ca845ce6}, {0x000e3aae572a2530,0x000802a21efb2cce,0x000430358e02b643,0x000504a7091b6ec9,0x00006d1b1fa9d7db}}, + {{0x0006d32c47447335,0x0000e79f9e345884,0x0000ef6ca40517c7,0x00003edf65655f13,0x000026e448941f35}, {0x000bd177ee4a9765,0x0003421363d18467,0x00069e0411d9dc91,0x000f5188d24c33b0,0x0000eb5da0a7cdf7}}, + {{0x0003cb1197b994f7,0x0004b843eae91c0f,0x000097ea53c95a6c,0x0008670766ffc9a6,0x0000bea40944723b}, {0x0001f734db378f9b,0x0000337b77acb48e,0x00024ad4670025b0,0x000a84e43dc8e7af,0x000098a15acc6d00}}, + {{0x00038ba2743b0043,0x0007034415ee3adc,0x00062d05ab1c7f4f,0x0003b6ba43df8f1e,0x00002618905cd76a}, {0x0000bb5a23a0f46b,0x000aba01918c2fbd,0x000743f945bc971d,0x00022ac801d94ab4,0x000094df65f176ae}}, + {{0x000bfabaf95894c5,0x0006d76b2241aafc,0x000dda48b7b9bdc0,0x0004df9af983625b,0x0000977faf2f3fcb}, {0x00042ef052c4b5b7,0x0000967591f0bed0,0x000f24ec79fe87f7,0x000f1b589c73ca22,0x0000d37fa9f564a9}}, + {{0x000841a15562627c,0x00030243b0342710,0x000c686092c01a61,0x0001f55d135c562b,0x00002ca17164b03f}, {0x0006c2d3eb81d82a,0x0009ef6df13ec996,0x00072b43bc02abf4,0x0002afd7b34bd78f,0x0000ff6218fd60c8}}, + {{0x000726c8d55b9d21,0x000989e9bffb0aa5,0x000b9e72adc0adbe,0x0001118097549cef,0x00006755712adfb3}, {0x000f984f26847f99,0x00074fb30cb7dd8b,0x00071ef9cbcb8e38,0x00063f31fd32a751,0x000077f3fc7c89b3}}, + {{0x000af2bf4babda01,0x000de7113c8e116e,0x000def526feab68b,0x000a02c1e3f064b7,0x0000ac30885f0b3f}, {0x0006e7b40142d9d3,0x000300921c0b1c5a,0x000a116a3839b560,0x000e6d18f301fa36,0x000080e1107ffd9e}}, + {{0x000ead858854be16,0x000e6bd4d49d7945,0x00029c2ef4111c12,0x0006f58ce3b1ec3a,0x0000356d404ed361}, {0x0006a8f594d320e9,0x000d6651ccd29f0d,0x0008fdde40989316,0x000bbbdc32117a0f,0x0000abe5cc6326a9}}, + {{0x00060fb9723f6711,0x000d6f3d593ccff5,0x000ba069621b2a12,0x000384d4cb18da24,0x000086e2220d3543}, {0x00064e088312c29f,0x000827dc7752722f,0x00085ee8994282a9,0x00069f72467bbf5a,0x0000435c651e1007}}, + {{0x000153943b3a50bb,0x000b6a53efbcc9ff,0x000b0c5b77132130,0x0004cb81bfe063f7,0x00000179a7dfea99}, {0x00064b3c85f455b2,0x00086f6e006212d0,0x00075d6d94725932,0x000cc7d64e590bb8,0x00002dd6225cd92b}}, + {{0x000038eb9c3bd6dd,0x00062bba27c8b658,0x00062c45d00cdb0d,0x00007c3c68133710,0x00008515b8cfd334}, {0x000699e8cbb5ecf2,0x0008a608d7d8cb8f,0x0003e00db8c4347f,0x000d190c11850abb,0x00000a8dafe0cb49}}, + {{0x000148045ee2f40e,0x000e616b60cfbd78,0x00049a8c475e354a,0x000535fe0b58a18d,0x000040e94e3da359}, {0x000a59f62accd765,0x000a3c762837bd4f,0x0008c277b05cf466,0x00074065abda9944,0x0000a9e01bf98b13}}, + {{0x0007798326aad8d2,0x0004a396f7e79d45,0x00053e292bdef495,0x0003e74fb274a2c2,0x0000800bf0a3cfe5}, {0x0006d3144438fd49,0x0002ce259f9a2242,0x000f66264ef23392,0x000faab188503c03,0x0000e5e7f140f9fd}}, + {{0x000b76c5fcc1aba9,0x0007c9b5bff8565e,0x000b6d3faea63254,0x000c1ac587c087aa,0x00002b639eafce39}, {0x000e782953b135c8,0x000dc25268ef0706,0x0000e74697308912,0x000e74d99e92c709,0x00003b90f531bc35}}, + {{0x000b3d0244975b3f,0x000721965d724750,0x0008dc751f3a4435,0x000fef279c67749c,0x0000f18cdffc23d9}, {0x00038332028e2472,0x0002d3bfbc79c401,0x000880a8496e280e,0x000151d60417bdd0,0x000063c9f3d4a568}}, + {{0x00015b32d2ce8114,0x0002b8291d2136be,0x0009fcfdb846dc0c,0x000b9a1cfa0ecb78,0x00005a0beee17535}, {0x0009f0796d69af13,0x0008299ab6dcec8e,0x000e2e09f31a7c5b,0x00054ba36d45eff9,0x0000cf49ef20cee9}}, + {{0x0004cf3086cff9bc,0x000079a3360f6be3,0x000bfbd1d88dbd49,0x0005515e96b8cc0d,0x00001e5f7c08b7e2}, {0x000b21428819d98c,0x000bbaea9dcb0547,0x0001d68c8c770dd9,0x000ba7eef0d4c704,0x0000c2b9818d3cb9}}, + {{0x000bc76fe86c6072,0x0007302a9a957fc7,0x0004dab636b7b933,0x0007bdf948dc27d1,0x000049dd198fae04}, {0x0006584a981a2029,0x0007aa893387e835,0x0005c72093531dd1,0x000b598be11f90c8,0x00003d2fe1f72a52}}, + {{0x000bfe2ec6d6b975,0x00046d0aa5de8225,0x000779f5f9cf6d6f,0x0001f3411459cb54,0x0000649cddbd6aeb}, {0x00035793f26ce5a8,0x0001d50f431e3213,0x000b84c6fc289a10,0x0004d6d59dcfda73,0x0000497381a6e3ac}}, + {{0x00055e6f2606a828,0x000110f2fb57b51e,0x000a4e37ce25f706,0x0007062cef6c2ab1,0x000064e359dddcf2}, {0x0006b187ce573162,0x00001a96b23d479e,0x000f16df72cab250,0x0008b5cd4898628e,0x0000056538d0f375}}, + {{0x000865ef15d31016,0x000a01b553d7a7df,0x000d1429480c5533,0x000cd5d66e19974e,0x0000620742013c0b}, {0x000d9c4edc454181,0x000eb1cc4a9d21d1,0x000c462f0005b859,0x0000c7cf01f630a1,0x00005d06cf402682}}, + {{0x00024ee3484be472,0x00062a0c902f9f7f,0x0000bc4532ff33e9,0x0008dae0bdf4575a,0x0000378dfaf3aa23}, {0x00020ec856720f22,0x000b767972912724,0x0008a15582ad9d95,0x000aa8b1242cc676,0x0000e287f8b7cc86}}, + {{0x00073d0990cecaa7,0x0000f75d40807968,0x000f0cd84ade55f8,0x000d01b645eea321,0x0000a1efa1024e17}, {0x0008420037cc0618,0x000055d43e12f685,0x000218710682e05f,0x0002fbd9c3699427,0x00005cbba4dbf7cd}}, + {{0x00097297a3cd22af,0x000b5a628397726f,0x0003165ed9f8cd5d,0x0003d327b93ab9c2,0x0000f5f5dc002282}, {0x000e4b5654a446d2,0x000f477257bac1e4,0x000766a56d1a9496,0x00074a4387ba94de,0x00003608bc8721ec}}, + {{0x00022d76688c4d4f,0x000117373abd16a5,0x0002efaa39d6b428,0x00017fb62f07acb4,0x000073e00f8d3b90}, {0x0005fec49421c3e1,0x000b2dcf26783617,0x00020f09fc4e44f9,0x0006cf66df436b72,0x000072755fb4aa8b}}, + {{0x0009d57446139cc3,0x00022fe0208fbab8,0x000e5d3990a0a6e0,0x000f0b9dbb63e211,0x00003ecaa12d8977}, {0x0008b21f7c426641,0x00029b65d08a5959,0x000502526b3e91b3,0x0002a8f35822eef4,0x0000dcf0176820a8}}, + {{0x000598f3d589e023,0x000f81d63d2c50f8,0x00071cd07df0478f,0x0000cd5b8068bd15,0x00000c3aa5007967}, {0x000fd4b941ade7f2,0x000c1279001125e8,0x0003f9ff03d1debd,0x00069c45b6dcbd3a,0x000082736a4993de}}, + {{0x000a0c3d41d3bd3d,0x000837a26bdeef69,0x0002edf9fb533b8c,0x000af012801d97db,0x0000c4a826ab1877}, {0x00058513d590dbeb,0x000b3e4e93576c1c,0x000b3337484632f6,0x0002e6236d36b779,0x000046833e44bbca}}, + {{0x0003913f7fc0586d,0x000696bf47193789,0x0001855dc385315f,0x0001fda2c56293b3,0x00001416d4f54906}, {0x000ab7851047213e,0x00011040c996beb3,0x0008b1d0c447f6e6,0x00022df06d310d63,0x000028a41409ad15}}, + {{0x00076cb82003f867,0x00069bcdbca3685a,0x000a4c455610d07f,0x000eebfff660219c,0x0000df39b883ea10}, {0x0005f96e22db2188,0x000a88a34c44b925,0x0009f92768cc6d9e,0x0003354d4ffb8685,0x0000fa15eb2d0d07}}, + {{0x0003845cf2c24b5a,0x000eb2f9c3badf55,0x000a7ceb389f66a9,0x000685ef22b5b9e4,0x0000ffef809ae134}, {0x000e1c68eb8fac22,0x000b08aec98e3e53,0x000a43bcb93c1e4e,0x000a5196b91ec532,0x0000dbfa947d2d74}}, + {{0x000d190ca84bad76,0x000f4d58e65ce065,0x000cb6e31fb13919,0x000c3edc41718bf1,0x000088969f066d05}, {0x0004ce721264d452,0x00095367532bd4f9,0x00045a39dfdfb65e,0x000f3b3b1be8b109,0x000029f789c4b8ba}}, + {{0x0001f3e6f49f15d1,0x0008807f0792d8f4,0x000a6e867678ce82,0x000c89b69ace82fc,0x000006451aee01dc}, {0x000f7f019fc32d29,0x000c200c52d21bb4,0x0009ea44564633df,0x000704ff13549aad,0x00009a3bf518b323}}, + {{0x00025a2534d4dbc4,0x000182a2fea30c96,0x00030fc1a45b8f1d,0x00073436ec21a1a5,0x0000bac9c2ade5bd}, {0x000d76a7b4e35876,0x000db182d9e35996,0x00007f13d0045cde,0x000a40baee24b912,0x00006452e97f7345}}, + {{0x000b0549f950cd0d,0x000107fdd07516e5,0x0002496639cc72fb,0x000cca9edd61e766,0x0000e4caa4ec043c}, {0x000f57a55c7ac17f,0x00032a85e24d11b1,0x0006081e7779cbd4,0x00064288030f86e4,0x0000d4a60337e20f}}, + {{0x00064880a750c0f3,0x00031e548e83cc7a,0x000110f0539bacfe,0x0005880d418c760c,0x0000e4daa4ce1f11}, {0x000e7b55ffc69ff6,0x000c320531272733,0x00022df9446f147b,0x000b7c285b2434d7,0x0000a444f6646fc6}}, +}, +{/* digit=7 [{1,2,3,..,}]*([2^49]*G) */ + {{0x000465ac3f16ea83,0x000d82f1d11c7a1a,0x00068a172115a461,0x0006981767dd956c,0x0000392f2ec013a4}, {0x0009ccde526cdc7f,0x000b32292b81c7a9,0x000d391988e537fd,0x00052c86d8cf69a6,0x0000fc5ff4414468}}, + {{0x0004f7ea90567e6d,0x0006e6ae5cb797b1,0x00010903d513257b,0x000723b5454a3c9f,0x00008d2c9ae39bc3}, {0x00093246b29cb44f,0x000c87c8cbac38da,0x000918e42b540a21,0x00014dabbfe43501,0x0000ffa707b46c36}}, + {{0x000e3f1d4e353b7b,0x00043f46b0a00ce4,0x0004b73fd062d8a1,0x000ffcb408d5ab57,0x0000c41d1ca83273}, {0x000e1e76be77800a,0x0007256550313538,0x0009b331a71fe8b3,0x000f727cd916216b,0x0000d825d0c5b388}}, + {{0x000e05b1cb76219d,0x0000a1567e7e56c2,0x000c4c9100ec0bf9,0x0004d917076f8661,0x000067b085c8abc0}, {0x00004595e93a96a9,0x000a6bdc249a9fb9,0x000dd0bb77526c1e,0x0006947d44d367ec,0x000053999182dc0d}}, + {{0x0000ee99e240d181,0x000ca4b944666136,0x000e5325c057cdca,0x000e3bd7667cd12f,0x0000fa297b531974}, {0x00081e7db083d762,0x0006d206bd15fa40,0x000c19f8c31993be,0x0003576949269b14,0x00001468d72c9d92}}, + {{0x000c583a4c506ece,0x0007f1acfe972ccb,0x000f1aea2957ed18,0x00062cabaed83312,0x0000f2a6cb563253}, {0x000de428e195c43b,0x00095e6050c6130d,0x000686a5dc842025,0x0004a77da972a708,0x000052999a29508b}}, + {{0x00090b910a5a8bda,0x0008696864dad9f0,0x00067dbc1ca91d24,0x00064bee6a93be3f,0x0000cae6fbb95f47}, {0x000c6e0d21411a01,0x000fca0a4ad81563,0x0008c803028fa787,0x000f07c524491c90,0x0000257ba0e5c795}}, + {{0x0009167ceca9754a,0x0005ab7939a083f4,0x0003fd0bf426d2cf,0x0004e18555e35572,0x000096e6d0764f14}, {0x000a8dd87880e616,0x00058508e4d54768,0x000b65e151554381,0x000f9fa9d7e772b1,0x00003439dd70c302}}, + {{0x000802fc14e35c23,0x000c1341333cb93f,0x000d4f36271735b7,0x000c8dd3a2510416,0x0000f4d069bef433}, {0x000ae01f78f5a7c7,0x000e0c4eed070d83,0x000e10f8350a8ffb,0x0008e1574f890676,0x0000d0809670ddaf}}, + {{0x000f8e1698e04cc2,0x0002f69005c8b11d,0x0003c6179877be20,0x000c0512749e8c4f,0x0000dbc9d0a9853f}, {0x0004f939454d9370,0x000db4800e1b187d,0x0005e68e8e682ce9,0x00085ba9129ad816,0x0000fe29735be7f7}}, + {{0x000f40c5b9e02b75,0x0001e5ee04e85303,0x000d6632ba37c969,0x00045b0f46cc2034,0x00005ef72b2e6ac5}, {0x0005c1f7b91b0620,0x0007bb33e821abec,0x0009f41170a79e1c,0x00075abb04b4283a,0x0000de1f28ffd2a4}}, + {{0x0009ccf3a4434b4b,0x00006a7954dc3101,0x0004972a7a345811,0x0008dcf9dac80de3,0x0000043d05524f6b}, {0x000319e11137b1a0,0x000eed5cc03f021c,0x000ea5ad400a754c,0x0005b60aa2c794cb,0x000093e67f470c01}}, + {{0x000fee9c97e3f6b8,0x000436da746172cd,0x0009806b9c10bcab,0x000f46bb02d2fcb5,0x00005185e8a21de6}, {0x000931f0eb6c4d46,0x000d74fa5b0439e6,0x000be7eb84d4440b,0x0009bbf418786e34,0x0000380e521fd725}}, + {{0x0000351d598d7107,0x00065b3a4da420ac,0x00071de1f272c416,0x000b0f6b82fe1aca,0x000046e79f348f54}, {0x000c7364b573e9b5,0x0006ad4b50406e7f,0x00098d87b75d03f4,0x000da10c1cc36d0b,0x000013ba3f16f472}}, + {{0x000af26abb177dde,0x00079891d56479d0,0x000232173f82ab56,0x0006184b6768a972,0x0000fbb3bb16c1f6}, {0x00011dba6d183586,0x000750916d3ab29c,0x00088e290519e279,0x000a7f74dc18f091,0x000048e86e3f8b0c}}, + {{0x0003145983c38b5e,0x000b837abc8b859d,0x000ff7be6b14f176,0x000a594793fb9dca,0x0000be5a56015a66}, {0x0001dcd9f87dc596,0x00039bdbf5607cec,0x000eb32577c595cd,0x0005fcfb543b2226,0x0000908064724c93}}, + {{0x000440381e9ede3c,0x00040af6df0a7f2e,0x000073b11243c389,0x000a61bc605bb11c,0x0000d06a5427a6a4}, {0x000894949d4e2e5b,0x00069af668802916,0x000a8503533649d0,0x000f4b0fc0c885e9,0x00004e52114ac410}}, + {{0x000b70678a6513b9,0x000a0edb1943dca3,0x0006e2dd892ea4a2,0x00089372642216db,0x0000b45d0b52fd57}, {0x00070dbc69d11ae9,0x0008bc57595f114e,0x00077c2721477dd1,0x00059c2c2208b4ec,0x00005c5b4d86b68f}}, + {{0x000fc6342e532b72,0x00027ae35290b8c4,0x00001ecbc386ba42,0x000fd6db5dda42d2,0x0000353dc8bc0e38}, {0x00085ea68f7e978d,0x00015ad6d11f9a0b,0x000f6886d96ec568,0x00014c8e279d6ce5,0x00003fe03ce0cb19}}, + {{0x0001fa47ea67c77a,0x000f43ea810cfe54,0x00001d374952bd2a,0x00036dd91fef568d,0x00003a1c621af113}, {0x000d5a9c7ec6d792,0x000f1225c3425ad0,0x00069601bff7038a,0x00047ce03c6689bc,0x00005059bc765e87}}, + {{0x00065b2f2086fbfe,0x0005a6916078fa49,0x000081d6cf6840ea,0x000644f7ac762070,0x0000600da3295328}, {0x0006f63529b8a80f,0x00073d7d6f3e0191,0x00064ca7ce80e485,0x000b0b39eb0fe8d6,0x0000017637cd7b43}}, + {{0x000c80676cb25661,0x0001a24892d99a75,0x00008fe458f76acb,0x0007d86ae7b9cc1f,0x00009ef73297a490}, {0x000ab715f228bf03,0x0009517032d72db4,0x000abe3c0f3cdea3,0x00025bdb1f482edc,0x0000baf76b4eb863}}, + {{0x00065e010089465d,0x0008be77c596d490,0x0003dbd953bab5d2,0x000498a636c3a619,0x0000ef5d2958246e}, {0x00058b9286b24756,0x00096d80862bb22c,0x000992388a0b9393,0x00014bd002c83af0,0x0000de01f9c4acbe}}, + {{0x000688eadd70482e,0x00099b4a4e8a6aac,0x0008a6eef708de92,0x000c4295b6dd7375,0x0000a4bf353525b3}, {0x0001f2c87912868c,0x00052f09297a1004,0x000f3860ab1b1be9,0x000f4a59ae23c5a9,0x00004f0f83a115dc}}, + {{0x000cca397f6306a7,0x000df8a3a4b03c7e,0x000a1d8a2744c44a,0x000577f9cd13a0b3,0x0000cad0a1ec256b}, {0x0003fcd33791d9ed,0x000ca4b2e05fea65,0x0007affa29cc2a05,0x000441a3b391dcfd,0x0000db7091f86b05}}, + {{0x00027bf8538a5c69,0x000cf9abff17c71e,0x00071e3da195c63d,0x000fa06d3152851b,0x0000cbdfda88a680}, {0x00076ca849d7eab8,0x000abc2732719db8,0x00008dceaebe2764,0x000b6fe63357e3f2,0x0000c5bd833d65b1}}, + {{0x000b4f59837fc0d8,0x0008279cf00fccc3,0x000df39909b641ba,0x0006b0f428243ddf,0x00003a594c482078}, {0x000451a526c45028,0x000deadb3f93b712,0x000ff0ccd9d39438,0x0004c37db261e3e9,0x00000344e3d607af}}, + {{0x0000d7c2fa4f1264,0x00051c99a2327590,0x00025e0c308a3b86,0x000edee478b6bfdb,0x000082cc2c2b1db2}, {0x0007e645f321bb80,0x000b9a8005b437df,0x0008c19588a93821,0x000d0a3fa2f10ccc,0x0000d3322182c269}}, + {{0x0008119e246b0e64,0x00049349fd1720ab,0x0001aa100b39781e,0x0001689293231eb3,0x0000b779c97fb032}, {0x00019e1c84705003,0x0008dc4c869d4b3f,0x000a6bbcc45b7efe,0x000bc1ab84f38aa1,0x0000b59cb15e2fdd}}, + {{0x00014df3fd165e81,0x0008f61f8811ba55,0x000ef9f00499fd6a,0x000e8a62cd1fe0bf,0x000020a4bb989ad7}, {0x000d0955f4a5ac5d,0x0000c5a7a2f0f2ff,0x00017baf1cfd174f,0x000089042301ba9d,0x00002fa487b47f22}}, + {{0x0009efeb1dc77e1f,0x000831c996829cb0,0x0006067bbe956693,0x0004559c5469016c,0x0000d37857551c24}, {0x0006cbe81796b334,0x000618e87f8b2b6a,0x0001b01b462d550f,0x000e11db763e1c7f,0x0000b93cfea5b1b5}}, + {{0x00052381d531696e,0x000fa8cdde69b934,0x00086afc757201bf,0x000ea7fde922519a,0x000030438969d35c}, {0x000c1e18555970de,0x00084535935e7608,0x0002ea38b8267dfa,0x0008b4f4c60a5732,0x00000bf7978604ef}}, + {{0x000ab28c06fece4c,0x000dd4e7b49d1a0d,0x0006dab28d405991,0x0008fb0542b6d270,0x0000b228da469161}, {0x0004164107d1cea6,0x000370f5d8f1224e,0x0006e41cdeb9fdab,0x000146602ba3860d,0x000076a72c5fb1f7}}, + {{0x000dd984d6cb00b1,0x000ace2e8d7cffd6,0x0001c7936cef9c5c,0x00072e91bbf5d764,0x0000b95b230fe8f7}, {0x000a92ee8ac25b1c,0x000b7a18b7c6f765,0x000cc8966ceb04cf,0x00000367944cef0a,0x0000bb3c958034c1}}, + {{0x00071a1a43ff93c7,0x000731e358a99c99,0x000d9bc825bc2db1,0x000051d5b4862ea8,0x00000ebfbfb9201e}, {0x00064c792871591c,0x0005f42d0219afdf,0x000d8f03cea5bcae,0x00033c1e536c552a,0x0000d6c3f4e676aa}}, + {{0x000f6230bca6de32,0x000991e706fdbeb5,0x0009059d4dd20dd9,0x000c4e70b3ff9dac,0x0000d7b29029cccc}, {0x0000a59ce98840f7,0x00001410680a8a09,0x0003379a5a5d947e,0x000155d9ae346a92,0x0000dbc84fa228a3}}, + {{0x000d91654a1aff29,0x0009aa78fb9bfd40,0x00029f95eabf318b,0x0007f9c0152ed830,0x0000fc1dd78558ad}, {0x000791513595c172,0x00086f62b3a95fa5,0x0003055b0b950466,0x000125707b5b24ff,0x0000e995e35ba84f}}, + {{0x000cf697e9bbcfb2,0x0006c86d96e387da,0x00095a75c95d0c1d,0x000f2145726e3c2d,0x0000c3c9001ccd27}, {0x000b5616c973f57b,0x000bf52216431dea,0x000ef79d4108b7e2,0x0008c5afee9859c4,0x0000d62b88af0d4b}}, + {{0x00029c4197c75d61,0x0002a7076febb4dd,0x000f2df11266a6df,0x0009ec8512d0ea4b,0x0000320c24f7b0cc}, {0x000e0e101a595966,0x000b8ff9aaac6bb1,0x0005aa6c98317c5b,0x00088f05bb405e38,0x000013439c1ef079}}, + {{0x000049f16a66e918,0x00007a1b0e0dd730,0x0004c28eae97f282,0x000c61c131e00330,0x000020ab732d26ba}, {0x0009ef9287144234,0x000a6db10cb2b2ac,0x00086a4cc54ecfff,0x000d494781476ef8,0x0000b2c87b61b2f8}}, + {{0x000cd200a44295d8,0x0000d8c6b044e857,0x00096757c707d7d2,0x0007142e8521f9f5,0x00007448f03e7b2b}, {0x000bc455ebcd58d0,0x00099122d3c113a9,0x00007664279bcced,0x00067d3c6442479e,0x0000cf227782df47}}, + {{0x000aee471d444b66,0x000f65084a1d5e61,0x000d3eaf6211236b,0x000bf51e15bc9a4f,0x00008df2c350b622}, {0x0004f0f59bf4f363,0x000ba7f34d739e67,0x000497b1df883669,0x00003b948ac1b831,0x000023b925d81067}}, + {{0x0006f4274082008c,0x000a08482bcb2215,0x000173479effc521,0x00048f9c6831bf12,0x0000aa2529084739}, {0x000102a8f1b3c4d1,0x00011d9bec0d84d2,0x000a546efcf64dfc,0x000ef1333febad78,0x0000f621ec38b73c}}, + {{0x000d627373386156,0x000aa1d8edf66aec,0x000e86b66162082a,0x0005db233a811919,0x0000023a2523299b}, {0x0000c3abbf04b89f,0x0008be749a44f5bb,0x00013de3b6735eb6,0x000ccce0e058c547,0x0000df2593f1c3d4}}, + {{0x000414efdd236675,0x000aaa2015ee1b8f,0x0009625ffdd52aac,0x00018bee31b517bd,0x0000ec9322dddb59}, {0x000ac85a96f5294d,0x000291a0666abc73,0x00008ac4282aa5bf,0x000dfb79755810bf,0x000021cdfd6591ce}}, + {{0x000b57b67f8be10c,0x000b96ffa726918c,0x00032de93365d1a7,0x000d016435c50465,0x00000fc5e10e674c}, {0x000fcf89cbbb1423,0x000a7fc506926e51,0x000bcae221d436e5,0x0003b8466bffff3f,0x0000148c2fe2d55d}}, + {{0x000fdc9233222fa2,0x0002c419fb6b52c7,0x00025497789ff109,0x000ca71cd6db9925,0x0000e85a1613cf12}, {0x000547cdc810bc9e,0x000ebd257c22add2,0x000d6b19bea3f458,0x0001a5842c1fbe27,0x0000d07e6b5f4048}}, + {{0x0001d4286d2e0f86,0x0001ae8a9fd56ada,0x0008c1b49e592012,0x000afea2c936af70,0x00000f30fee8b4bf}, {0x000ad06858e6a61a,0x00069fd374d06637,0x00088defbce4c776,0x000b6599d54b2d71,0x00008c9d251956a6}}, + {{0x0000f5eb24fe1dcd,0x000d9b73f24c58fc,0x0006507059eaf9de,0x000728d90d588b33,0x0000e5b62c67f2ec}, {0x000cfaed3c2b36ea,0x0004634435da5c72,0x0007ee145868c19d,0x0005b0e8605f93e1,0x0000a60c4ef17a5d}}, + {{0x000bfd23b60c472f,0x000bfb1d3049bcf5,0x0003895c9af4ef13,0x000821473f44fce1,0x000029b382ffcbc9}, {0x000b85373efaef69,0x000c18c96f401bfc,0x000191e24cf56ac9,0x000dc247adf1097a,0x00008035f454f8a8}}, + {{0x00071b91e750c846,0x000bfdc6c469f40a,0x000bc19c1c57f7b0,0x000db7e9a0e79c6f,0x0000b0f588a048eb}, {0x000d084a07c4e9ff,0x0000bb27de145d3f,0x000e08dccc383011,0x0003a21e4929fe33,0x00004a5ad2530bb7}}, + {{0x000c2bf490f97ca7,0x0005f7a1ce18de86,0x00044478d288f09c,0x00003fc64bb88618,0x0000840fa433eedb}, {0x000fdd25a631b378,0x000e247c8b7d1269,0x0001c626694761f1,0x000fa77c0c2e1748,0x00005e16ea2bdaa5}}, + {{0x0006033924910480,0x0003f4d402d7ccd8,0x0006a865c0c2f696,0x000a876336f7dfdf,0x0000a2a463cb5c02}, {0x0009be7bf2f12ee2,0x000246bad988b0e2,0x00023c1d7f0a2200,0x000c9807f87e0391,0x00001669c55528a8}}, + {{0x000980392f145296,0x000c03954df3186b,0x0005a46f6d3d056c,0x000557cf03fd5817,0x00003e34ebe71558}, {0x000edee5b80cfa5b,0x00002401dbd1e13f,0x000a9d667e872a12,0x000692a2657616e8,0x0000c8da4b7908d6}}, + {{0x000b9bb1b703e75a,0x000634338363370f,0x000ef7bff6773b18,0x0007d978dad378ec,0x0000ac787ee39567}, {0x000ea8b0437164b0,0x000073fe795e4801,0x000e5eb73f430ad2,0x000c0eb164154d8e,0x0000884ecd8108f7}}, + {{0x000c0965f5206989,0x000db4f7b8d90e6e,0x0005a68b9640631f,0x000f4e02fd34fca3,0x0000c5a4b66dd40c}, {0x00054bf80b6783d1,0x000e2a320a109494,0x0000a39b280e701f,0x0007db7d1a564a1a,0x0000436d53d42058}}, + {{0x0006e6d6556c3629,0x000052455d7ef509,0x0007230f9bc23a3c,0x0002fcaa7aee5480,0x0000ba1cfa6b2ae8}, {0x000057a99c5d7062,0x000b642315c9833a,0x000a72f128be85f4,0x0003cdb083179a66,0x0000fc77d5dedcc7}}, + {{0x0008a805616ee306,0x000f87ab108322b8,0x0001270cdfb09548,0x0009ab2ad6ab0d51,0x00001f6c57ac924d}, {0x000bf7290aecb08b,0x00085df784a4a0f7,0x000af1d03849f87c,0x000acd77c79c15cf,0x0000bf9f6767463f}}, + {{0x0002c65765ba5436,0x000be2ea60dd9150,0x00043ecb318ce3ca,0x000eeb85cee6ac6e,0x00003e4e910c8f2a}, {0x0004fa3c85932eeb,0x000a9c90c44d2623,0x0008a50f696883e8,0x0000de79b9e738a1,0x0000fc62b2aef042}}, + {{0x0007d906d3e1fa9c,0x00083e05b8a3d22a,0x0002b9c011711561,0x0006a16a0c9926bb,0x0000739fcc7a07e7}, {0x0009157165e439a0,0x00026a9063d8540e,0x000e927a306353a6,0x000e7f84d9559461,0x000013b9b26e2e0b}}, + {{0x000ec3b973497f10,0x000e093ebc2d4fea,0x000af058315c0f94,0x0003406af5f22733,0x0000c2af206c61f3}, {0x000bdf14457397cb,0x00071abcbae0d25d,0x0008153062e8ed01,0x000d6833010938c2,0x0000aa9933898c6c}}, + {{0x00031823b0ec7de9,0x000ac8df05df0851,0x000c3b6831e1b822,0x0004cdcc14842fa5,0x00008fe977eceba3}, {0x00016c20d5e88732,0x000a9d0d427dfd23,0x0003fc961e48d839,0x000a5e295b221862,0x00004ee56e7d46fb}}, + {{0x000a55b91e4de589,0x00054fdea2889184,0x000dcc943a7488ca,0x0000fc1723862ea8,0x00002d762b3149dc}, {0x0004a12091ff4a95,0x0009bcada2743c44,0x000d8eae2581113f,0x0001ea69de0a4530,0x0000e0fcd862f6b4}}, + {{0x000ea68c094dbb56,0x000e7968d4106233,0x000b3002db77d062,0x000d57de719bbc58,0x00008e7dd3d9dc49}, {0x0005740013a5e585,0x0006ec9e3c1b8d82,0x00099b6ab2131174,0x0008f1bcb0a2a77c,0x0000c48a3b412f88}}, +}, +{/* digit=8 [{1,2,3,..,}]*([2^56]*G) */ + {{0x0003e91991724f36,0x000bd9cbd686c791,0x000d4fc1e5eda799,0x000d547db595c763,0x0000b63b80c0c4fe}, {0x000fc697e5fb5166,0x000a70f1c9646ea0,0x000a92ca5737708b,0x00067a3628745f11,0x00001f37958fa869}}, + {{0x0009b2caa6650728,0x00046fd324ef9af3,0x00027bd3178322fa,0x000aafbd153394c3,0x00001d5f271b129d}, {0x0000c42f48027f5b,0x000bd536e717c72e,0x000369d0faa40cdb,0x0004e6445a657a2d,0x000003bbfc59a7f7}}, + {{0x000c4180d738ded3,0x0000b0de572946a8,0x000a816756f1a5bb,0x0003d4c10230b98b,0x00002c6f30c412b3}, {0x000129dd8fffb620,0x0007b459bf057559,0x0003b67766a281b4,0x00073a77c1bd3afa,0x0000709b38078299}}, + {{0x000b232a3326505c,0x00022e1d41bf8c26,0x000e32afa38d6927,0x000a864459453eff,0x0000e8143ae3cb3e}, {0x000c1fa7e6ab6665,0x000fd2286264932e,0x00036f8ed6cd2d22,0x0005baf59a46fe67,0x00000bf0d00eeca8}}, + {{0x0005852877a21ec5,0x0006bf537a940b82,0x000a9a6a2300414a,0x000bffef1cba4021,0x00000824eeec6943}, {0x000fcecf83cba5d5,0x000843b4f3c0a0db,0x000f24dd7f953814,0x0009dd1174416248,0x0000322d64e34fb0}}, + {{0x00073843d9325f3b,0x00004371cb845744,0x0001e36c5a9bef2d,0x000f71c7d2188ba6,0x0000bd6a7d87602d}, {0x000a9028f61bc0b8,0x000ceed0b6a1ba3a,0x0006e8298f49085e,0x00001d0bc625d6ae,0x000032b0b1e22e9c}}, + {{0x000c447f1f0ced18,0x00031492dd2ba337,0x000a08efa800cc79,0x00041dcb93151dbe,0x000020cf3f95e0a7}, {0x00082dc1c0f7d133,0x000054dde6caff19,0x000f96ee3ef92196,0x0000c6ead7d97245,0x000019c8dbe59dea}}, + {{0x00038717b82b99b6,0x000ce70eb624d3ea,0x00095d46675922d4,0x0003462f66ec543b,0x00006e673cd1ee1e}, {0x00067c4b5f2b89a4,0x0005e90e5cd36afe,0x0000a2ada3de9c1e,0x00023b4c278bb631,0x000020fa3844bdb3}}, + {{0x000d63b0eb919b03,0x000d774b96200ae1,0x00074290cd74ee51,0x000510095458d0a6,0x000024c930f7620a}, {0x0004d19fbac27d45,0x000a4bedeeac2d1f,0x000679ab84086e8c,0x000ec3bcdd211b9b,0x0000970167dc090f}}, + {{0x000f2c9faf1fc639,0x0009a28c8bb43420,0x000f1fe4a616d333,0x000739ed65364c57,0x0000343e877e5e5c}, {0x000176be970e78cb,0x000eb05336275795,0x000cdfc1ba36cceb,0x0003264c7c738009,0x000039a2aff63fec}}, + {{0x0001ba16224408a4,0x0001e47cfc5eb7ff,0x0008bc493cc856e9,0x000726c1f102e7c1,0x0000613ab746091c}, {0x000e89cc420bf2b3,0x000660337ec2aa25,0x000025fc700a5317,0x0003dca2be9f437d,0x0000316fb859e6fe}}, + {{0x0000af59ac50814f,0x0007aa8e42232752,0x000bec5a0fdf95e7,0x000e5cc7e7df2a56,0x00007022f7ecf159}, {0x000eab1cac1fe8ff,0x000b4745116893ee,0x00067dce68040188,0x0002988ee8aa8ad9,0x0000a0e79e82abc9}}, + {{0x0002cfc2064cfd1e,0x000dd06519346733,0x0003bcbea339c31d,0x0005c5919b28d52a,0x0000e74c82c7d6ae}, {0x000d05ebaf28ee6f,0x000bad7190280927,0x000b3028982cecf2,0x000e281b0d353edd,0x0000e4bb978eddb2}}, + {{0x000b990640bfd9e7,0x000712f62108bb5b,0x000ffdd56d226e27,0x0001b4dbf0098502,0x0000756758a9ca1b}, {0x00062a35285fe91b,0x0009dc9cd140c32b,0x0005cb008edbc546,0x0008f16e47a013af,0x0000ca7e720b73ce}}, + {{0x0002ab817a91cae1,0x0004f8e27f63e10b,0x000a3ddf9b89aab6,0x0009726b3074a7db,0x0000c20ce09430c2}, {0x00017b45fcf7e33a,0x0002f45ceb426b99,0x000633d19e679374,0x00047378fc22155c,0x0000d1adb3d67485}}, + {{0x00096796424c49b9,0x0007d7c241c9646f,0x000f68b49f888dfe,0x000f20512d4b9324,0x0000a6b62d93571d}, {0x000b26d179483cb7,0x00022511fae281b4,0x0003aa51f666f963,0x000d166281b3e4d5,0x0000f96a765ef3db}}, + {{0x000b5bf074a30ce2,0x0006e05a32e6a7f8,0x000237ed4d7f5210,0x000a2b4f9e090750,0x0000f21da47a096f}, {0x0009cb4eec863a09,0x000d0527620af3e1,0x0007c1cf8d18f77f,0x0002840505c81c40,0x0000998db4eab6ec}}, + {{0x00089e5c247d44d3,0x00010f4f3d807e33,0x00078a6c71250714,0x0000bea4ba01104a,0x000012874a0a6772}, {0x00059a6759443709,0x000fab2c0bddded0,0x000c108e3d6123d8,0x0003e9156b717b51,0x0000bb7940e97062}}, + {{0x0002d5984ac066c6,0x0002868c69a0794e,0x000d99dccf5954a9,0x000516c8c524584f,0x00000e639fd11012}, {0x00001257de792488,0x0004712fc6d7c2e6,0x0003b5d32e9ef640,0x000b89cc4f28082a,0x000065ad32f4768e}}, + {{0x000331b13fb70b6a,0x0000f5599b27ac02,0x000bd082c037b44c,0x000d007a860fc460,0x00002e257466980c}, {0x00087a81da0263ef,0x00043d10f3d6ee33,0x000f24a32931bfb9,0x000b856b687270a1,0x0000140e65eba494}}, + {{0x000df91b2f1ac7a0,0x000b760fee274f4d,0x000c228e5f99eaab,0x0003bb57f4008a49,0x000090be4401cf71}, {0x000fbe45004f022a,0x0001b69e1af6ac91,0x0001daaa5d838c2c,0x0002c036c7d20b0f,0x0000a063ac1bbbb0}}, + {{0x000a42259558a787,0x00091435da2f0938,0x0004410dc5343c66,0x00080426f67b1803,0x0000cc1e424f4510}, {0x000543f16dfbb7d8,0x0001db5bd59286a1,0x0003dd03c921fa94,0x00051e1dcccb6eb3,0x0000581ddda3843f}}, + {{0x0005fcb81d73c9e1,0x0008fa5e97ab5493,0x0003a6bab6d07e97,0x000e113dc7b30acf,0x000047ab1f3270be}, {0x0008e3d9fafdee4f,0x000a638a8b950aaf,0x000f13871fab3dbc,0x000a48505df4b36e,0x00001f4e9cbf88d5}}, + {{0x00024d366b33f1dd,0x000f8ce445c09bcd,0x00093ff613b97b81,0x00061612926549ba,0x00009c341cf1dafe}, {0x000a76e16efb6f3b,0x0009b05b953cfb30,0x000fffb9fdf24b8c,0x000b95dbd52afec2,0x0000bac5ff8919d0}}, + {{0x0001b87459afccd8,0x00033743265243c0,0x000b5d78e6bd4514,0x000a7d0473453055,0x00001088fdb9554b}, {0x000a52c1e269375c,0x00036dc5ec10ada0,0x000bfbc11f9f037c,0x000d2f0066060794,0x00000a630bc89c40}}, + {{0x000797eab64c31ee,0x000a945071445efc,0x000a6790cffdb1da,0x0001bf161242871c,0x00009609d82c69bf}, {0x000859500d24fc90,0x0003e51fb417db89,0x000f7bbde9c75033,0x00085c51830a91fe,0x0000ce67dc8945f5}}, + {{0x0000ed44763eb501,0x0001b1ab0d669a73,0x0008748f324a0e22,0x000291543b639364,0x0000982daa17d3c6}, {0x000a9f78bbc55499,0x0000ef36384e6f00,0x000977f507a1783e,0x00002a58346323de,0x00001ab688e42455}}, + {{0x000b6b56d0bdd662,0x000e44b71229331a,0x0007c352f0a6ef32,0x0009d2f028150efe,0x00007e04350ee7b3}, {0x0008acdc1070c828,0x000300c9feef2a3c,0x0009f3729fb2034d,0x000548ad72962170,0x0000df290bfe2cb4}}, + {{0x0009f33fc2e43263,0x000d2eddf03202f9,0x000652fb53b30076,0x000f7b8b21f8cf0c,0x000014fb49f1d91c}, {0x000eca52f7007501,0x0003612a4575a013,0x00030fbb02b9e3c2,0x000771d5355557af,0x0000ada35168c77e}}, + {{0x000ecb27b1356705,0x000f2cfc202e45f6,0x000d1be9fe85d19d,0x000343bf1b50c758,0x0000ebf2c0b3ad2e}, {0x000fe4eabc199c90,0x000256bab0ae1531,0x0001fec54c703259,0x00018816ab2e486c,0x0000f87fda804280}}, + {{0x00046fc609e4a74a,0x00031a667f91dc9f,0x000d834362a44a14,0x0009581c3d8b95b4,0x000001e4bd167bd2}, {0x000293273483c908,0x000127c7b5987b18,0x000aac07ea79c6aa,0x0004e63f3983c6ea,0x0000f18181f16e0d}}, + {{0x000d37c051af62b9,0x000a7bf944968553,0x000d59aa1e9a998e,0x00081350844f9fb0,0x000083fd55976afb}, {0x000c0ca65d698049,0x000ddea5ff2d9670,0x000d8623b732b22d,0x00078247640ba95f,0x0000f61916436351}}, + {{0x00027eeacee50437,0x0002beb10f020bfc,0x00043fb05ae419e7,0x000a29a9c028d189,0x00001f01cf86f13a}, {0x000737e8887a132f,0x0008763184107790,0x000db795e6751330,0x0000b1a819e8a37d,0x0000ecb8ef6cad10}}, + {{0x0004a223021926a4,0x00092f9b4c1c59f7,0x0002ad0abb7c28a4,0x00059cad1a733f91,0x00002a910af41a56}, {0x000c6e07bd68cab6,0x000816d70ac83842,0x00053aaeb2b57fa3,0x000b182a6707a83c,0x00002c1c510c5b4d}}, + {{0x000c1fbb2d09dc72,0x0002066bd23b8de2,0x000b27db6c3dfed1,0x0003da727d039bd5,0x0000fb2f0f130324}, {0x000a07b80be73992,0x000dff9f27a8f855,0x0009bdef7ed9327c,0x000d8880bd99c772,0x0000b67125e48250}}, + {{0x00026e88670ced73,0x000f931bd3b4784b,0x000c85cbce3dfe41,0x000a9d6e353a06bc,0x000002e290990178}, {0x000bf11a6eac16e3,0x00007a2b3aac860a,0x0000afdab7644700,0x0004c116ff9d1985,0x00005bdd6a62db2d}}, + {{0x00094b07e5c9ce97,0x0002b0af346ee825,0x00065ad4a0f379e5,0x000825f08b31e3bc,0x000010c6b12967c4}, {0x00066f971954cf1a,0x00026d0aa21551c9,0x000bd23a8b1cec79,0x000e857f15598986,0x0000e2ff99d99452}}, + {{0x000953c340ceaa2d,0x00045e2e9333d8dd,0x00086f06d2635527,0x00054545d4e5f985,0x00006bf94a9c7cab}, {0x0009a0ab76a9af0c,0x0002fa095af733c5,0x000389ca052740ab,0x0000cb0444de8a24,0x0000c6f9864306da}}, + {{0x00041a76b2515cf3,0x00016585c749b5a7,0x00083de9771c4160,0x0005f548350d4fe6,0x00001d6152493d0b}, {0x000c5e1fbce090b8,0x000d7bcb2a5b7a0c,0x000d84c35aac927e,0x000e266920de4920,0x0000c06a0b6a2b4d}}, + {{0x000d58bafe7ddf39,0x000d31e6e55bd34d,0x0000696e755851fe,0x00005f4139561696,0x000040304b2ef227}, {0x000f861b0a2a8600,0x00020e7cc9816f43,0x000b64a96cf12128,0x00083c121862120a,0x00009215b9ab7893}}, + {{0x000b30537387c09e,0x000e103ee760311e,0x000f7ea19c5832fc,0x00055050358f5832,0x000001d3c3571d53}, {0x000ee41da48ea80e,0x000def4fa4c11ca5,0x000f1e1c734e71e8,0x0004a4512abd257a,0x00003afcdec0153f}}, + {{0x00084d700235e9a6,0x00042c4c836f9d5c,0x000332de50308d3f,0x0006ef60a66b0489,0x000010dd399e9e56}, {0x000a460d1ac16352,0x000b00a2c0dff8ee,0x0004a48c584cbb3f,0x00015020afb488e7,0x00009738198f326b}}, + {{0x000747fa6d74081e,0x000475a262142a17,0x00088c5fe60ea4c0,0x00026b73514bb41f,0x0000dd645685e834}, {0x000cbec96460b259,0x000dd8dc115ed5d6,0x0007840eaa12fd0c,0x000e3135bc3ed269,0x000069876a936331}}, + {{0x0006217472ff5805,0x0004fad4139360c3,0x0003b8b92f422970,0x0004f5fbd99ef0a0,0x000001c73181144f}, {0x00009b318464945d,0x000ba4c5c6be1590,0x0001a36606d5e594,0x0000215d58701132,0x00001e184b20898d}}, + {{0x00047524c6a7e046,0x000ae5550b655ba0,0x000c0a9a547fa1e2,0x0002363419daf048,0x00006362953dc243}, {0x00044b15cb12a88b,0x00097b646188cd07,0x000c2c0c0561b6f9,0x000099a99415a566,0x0000e3f0859bf83f}}, + {{0x000c5beb92041b8f,0x000636477d0d9141,0x0002c7a9401ae38c,0x0000dada8b71f3d1,0x0000ab5b320665c7}, {0x0007492487443e97,0x0000290d134976ae,0x000460a378595a31,0x00038f88dbeda87d,0x0000f7ad0828e45a}}, + {{0x0004db61059705ab,0x000a36b9c697ed1d,0x000b38bd5a3dd492,0x000bb69b92ee3a6e,0x0000ab2609e17cc0}, {0x000fe896e70ee822,0x000df3e6b7e37fc4,0x000d26fcaeff2c56,0x000b457b18959e34,0x0000517ab66a89d6}}, + {{0x000b4e0bdefdd4f1,0x0005e366e401f167,0x0003bbec06995846,0x000c214aa368aba7,0x000021487098b240}, {0x000323318969006d,0x000e11fe53d1378c,0x0000c4361cb4d73c,0x00012a8f50a80e13,0x000067f59524ef52}}, + {{0x000e21e9e70c72e5,0x00090566d2fbf145,0x0002397f5b2e52e2,0x0007ddf4eaba4a03,0x0000e56937bce31a}, {0x000f517456c61e10,0x000aa8b0a38868dc,0x000a8b755bc2e954,0x000cdee3552fa760,0x00003442dae73ad0}}, + {{0x000e747ceb26210c,0x0007b87baef937ff,0x000a3de31983545e,0x0006dacb8c853586,0x0000621dbccbacd4}, {0x00042e959266fbbf,0x0006439d471c82e4,0x000cdad96a3514c3,0x000def4a11b77162,0x00000cb3b3ddcf9b}}, + {{0x000dbce478e2135c,0x000efda353423fcb,0x000677af67547b5c,0x000986e97e81f18a,0x00008c2bf83e8817}, {0x000eaaf455809854,0x0005893b45cbdf07,0x0007b4cacc68d1f0,0x000e85d06aa2fec7,0x0000c1d8afc44a7a}}, + {{0x000c3fd9eb45ab26,0x000b74b22e74db41,0x00015958a5b234b5,0x000fa07a253decf2,0x00007e0606f004ed}, {0x000f070ef751b115,0x0005a6f06dceabbb,0x00039f6b4f352f17,0x00048e8fc4b6af68,0x00003ddf9a8e9598}}, + {{0x000c379c21520b0e,0x000ffbd5d1b6da49,0x00049c7f790864fe,0x0002d74f055d235f,0x000051e4e6b8796b}, {0x000a67f5c9dc340a,0x00071ca7c620c361,0x000c756d05ad53c3,0x000e133a1d658832,0x0000d60d9122bb67}}, + {{0x0007bdf0eeec8c68,0x0000878a1821d6c4,0x0000995244a27fec,0x00005f881f7415c3,0x0000effdf0c02cd8}, {0x000ec1c65842df85,0x00088319a901db70,0x00042b5298821b35,0x00028622ee56eede,0x0000bb39592736e4}}, + {{0x0003316fd6f7140f,0x000acd8e81f7d118,0x00002d962f9fadb5,0x000323801d5e0c5a,0x0000dee4dc00b601}, {0x000740735d7620e5,0x0003a48c0012bed1,0x00055449a04e3c2c,0x0006c44ee29da734,0x000062cdef4e1a83}}, + {{0x0002a5f477010973,0x0008cf88d0c28f68,0x000bb86dd617125d,0x000286648fda2457,0x000048abb8f589f7}, {0x000eab599d94bbd6,0x000de684d160eb10,0x000c8f41ad51ba28,0x000f4a4be0e51c30,0x00006588b4573254}}, + {{0x000bf01fad097a5a,0x0007c10e815d147e,0x00011de5649883ea,0x000a6d444d60ba8a,0x0000970de6f227a7}, {0x00014245e17fc196,0x0006a12140572be4,0x0003e723fd833c65,0x000e9ab375813b36,0x0000820bb8946a52}}, + {{0x0006970d875d56ae,0x000b71fbf6bf7e7f,0x000083c12d6a0a9a,0x000b6374ba8790a3,0x0000baeb23e4ae7e}, {0x0005c3ab99a907a9,0x000f726bf40ba868,0x00002cd9ef1e7454,0x000634eb73a027c8,0x0000a8a927cdfef4}}, + {{0x000f60c08191224d,0x000b0e4ec091e1b6,0x000e38d84c4126eb,0x00098511dff4dc4a,0x0000e3f57dc1f2ef}, {0x0004337d446a1dda,0x000fe59e77f63496,0x0001d13f57bf2179,0x000e26eff105278e,0x0000304ef0414eea}}, + {{0x0005e47d19dfa5a2,0x00035fad982bfc6f,0x0003715f5db007de,0x00029e08205ad161,0x000051e672998895}, {0x00051841ae98e78c,0x000c671cac327270,0x000f410f5f818537,0x00039308a15b7eb7,0x0000474357041f62}}, + {{0x000dc5ac242316b4,0x000c9bf4aff592db,0x0009a8ec6abe060a,0x000b942e8c38fe90,0x00003e514e5a116c}, {0x000fa3807d784f90,0x0000f4b5b3572078,0x000adea3d1161a88,0x00010b5283ce7913,0x0000756c3e6cc6a9}}, + {{0x000fe01aaa79697b,0x0008a6391db160bc,0x0009b45a004a73b2,0x0008d92d8dad4718,0x0000fac0dd0f8d5b}, {0x0003af57d3d2ec27,0x000cb07bd3af34ab,0x000550ded6fa2fc2,0x0009132ff4009266,0x000019b3e878fd5b}}, + {{0x000a4966d17fbc7e,0x000993d2b24ea573,0x0006769370cd1a70,0x000f2054e2c5cab2,0x00007050b079f669}, {0x00048b61ede9046d,0x0000c7662659fbe9,0x0000124c5a053005,0x0006c788cbd4edf1,0x0000e2646e5ad6c0}}, + {{0x00081088cad38c0b,0x000fbbd68ae2332f,0x0008e27a3471b7e8,0x000b0ca6ac3fb20d,0x000054660dbc36b4}, {0x0001e11a6fd8de44,0x000a637799ef123a,0x0006ac17c44dbffe,0x000cef0540b977ce,0x000095173a8ef60a}}, +}, +{/* digit=9 [{1,2,3,..,}]*([2^63]*G) */ + {{0x000284d391c2a82a,0x0002758308e89ebb,0x000f1edcabcdd486,0x0006c7606f16ec83,0x000013e2c38095dc}, {0x00056f04a057a87a,0x000006b48f982ab7,0x000651c44a876550,0x000e01a252face68,0x000052b540c81765}}, + {{0x0002fc516a0d2bb2,0x000bfa6234994f92,0x000c62c8b0d5cc16,0x00067f7241cf3a57,0x0000f5e69621d1b6}, {0x000c70bf5a01797f,0x000c709561925c15,0x0001fdb523d20b44,0x000f7a14911b3707,0x0000648f9177d6f0}}, + {{0x000acafe60b7cf78,0x000004a9d8696dc1,0x000ba8ac425860a5,0x00029dd6fc6f09e7,0x000028c5bd0e148d}, {0x000435edc55ae5f2,0x000ca0117411ac6b,0x00024342ca527f56,0x000c0d74d5045efd,0x0000c4c0a3590b67}}, + {{0x000c8b8fac61d9a1,0x0002d3c6fe8a027c,0x000bff5037d25e06,0x0002f7d08805bfe5,0x00003271e6c7ff63}, {0x000a6c0232f76a55,0x000d201ef42655dc,0x0000a51788957c32,0x0001739e728bcba1,0x0000ea60412062c5}}, + {{0x000964ed0b8892be,0x0002b301bb74fc4e,0x000c486269ea1768,0x0001018265c5aefc,0x000060cf82f9b3e9}, {0x000f797d4df55311,0x00017deeefe257ad,0x000306eb1235b59a,0x00092d50adcf583f,0x000005c27534d094}}, + {{0x000914bb5def9961,0x0003133dd1e74090,0x0003d5e761cb69c8,0x000012b1e9c1d39b,0x0000f3338ee0ccf6}, {0x0005d0d2f5378a8d,0x00065f00cd21b1e9,0x0005fe290acf4c2c,0x0008ad9e984240eb,0x000066c038df4808}}, + {{0x000264af94d70cf7,0x000f0314bf7e804d,0x00033ed02bdb802e,0x0005d91fb54de243,0x000040461e098563}, {0x000b2c8365e9383a,0x00029fdef6524113,0x000b956c1ea762c8,0x000fa3aeec6e2e47,0x00003d814bf05620}}, + {{0x000462bb4d8bc50a,0x0006091957709ad5,0x000412a68181c0b1,0x00048c4bd4fe1c78,0x0000e0341bd60dff}, {0x00045cf7003e8666,0x000a2a24a41bb6bc,0x0004c24c2f11a6de,0x000b67f407151ad0,0x00002c9d27e3a5b7}}, + {{0x000423588cceff67,0x000f1b07ed692e96,0x0004d0d0d8594c54,0x000867a578e73cc8,0x0000b4e10566f532}, {0x000c0d5b5ec995a1,0x000504289a54a348,0x000fbd777bf4b9d5,0x00091d8ba155a658,0x000086ed7a82a844}}, + {{0x0002b30614c09004,0x00017d00c24bd499,0x000c4bfa1da98d12,0x0004bc3f534dc87e,0x0000a5ff67477dc3}, {0x00096b81d7ea1d7e,0x0002a0a6d20868c1,0x000cbbd6e38cf289,0x0005b61d56cd09e3,0x0000c72e27f2205a}}, + {{0x00068f5a44f77f7a,0x000d143c52bc15ea,0x000f0e6097aa5f9f,0x00032ae6ff676f94,0x00004cde963ce2d4}, {0x000a0c0eee470afa,0x000dea3f5ec88caf,0x000a3123184137d0,0x000ccf4bb40411fa,0x0000239c1400f7f7}}, + {{0x0005719a8afd30bb,0x0007da826dce3286,0x000a8fbe08679832,0x000ad32f04e891c4,0x0000b6b6e1c9bf56}, {0x0005b11471f1ff0f,0x0008ce15baf00a69,0x00096c43ed76c338,0x000157118edb95be,0x00002beaaf580794}}, + {{0x000b09ec3076a27d,0x000e1416545d152d,0x0006d6f2e5e82908,0x0004e0d2c4127235,0x0000c9c964301fd7}, {0x000b88d519bf6156,0x0005a5a2274e66ce,0x0005e2fa0e29ecd7,0x000e66da0473c4bf,0x0000b6eb671c4284}}, + {{0x0007932b88756ddc,0x0002317e3e61e8b9,0x000e1c4a4ed4e865,0x000c0e02dd14993e,0x00000aaee18197f8}, {0x000edb96c168af3a,0x000f139ae87515c4,0x000adb4366563c7b,0x000ac00dfadb6f20,0x0000d55e8ca3a042}}, + {{0x0001ed8b76da1f56,0x0006458acb94975a,0x00006028210dfa46,0x00051e2dd7f7e3ac,0x0000813e66ab72a0}, {0x000ae1e350cb901c,0x000590cb7822b4cc,0x000ab3b87b653d65,0x000fcf82484710df,0x0000d7ee5385b670}}, + {{0x000b12e523b8bf60,0x000b8f910c1b0a50,0x0001675888009eb5,0x000abdf535af824a,0x0000f835f9cfb2a2}, {0x00029312afceb620,0x000a169d383ff59b,0x000ac02b0c797df2,0x0000caeb3f5fb066,0x000029d4c6fdaa2d}}, + {{0x0009bc1afab4bc58,0x000ed6783247d405,0x0002d3605833f5c6,0x000433353466308d,0x00003387892534d8}, {0x000b30fadd9419a0,0x0009afe3fce8d973,0x00009aac6bcca109,0x000f110817831508,0x00001b7f21a540f0}}, + {{0x0009219909523c8b,0x000ef3a1c74165c2,0x000c9e55aa62f648,0x000479d8598d4f60,0x0000ce9141bbe4f3}, {0x0007d8435f9b9887,0x0001c20475b69af9,0x00091476c0210da6,0x000833cc076e2291,0x0000520dbd9b4fc7}}, + {{0x0002cfec1ab1bbdd,0x000e0c6509386a6b,0x0005d7bc4ef8a65b,0x000dfca285554080,0x0000a389397bd11f}, {0x000bd3674660876b,0x0004045dff35a9d5,0x000f5da9411d67c5,0x000b30baf7d148a4,0x0000b8d4c4070bbe}}, + {{0x000ebd1e0a1b12ac,0x000cb70ba95f87a7,0x0002ae9cb1e4ef88,0x000402cc33345cdc,0x0000ecf1276c1cc8}, {0x000012e1b39b80f3,0x000d05c33ba4687c,0x0009661c2fd90d0a,0x00029e73ef5a675c,0x000068fc88f10174}}, + {{0x0006761196a2fa2a,0x00071d5b312ed30c,0x000f54a31931b981,0x0005411a01000c72,0x0000203d2c906eaa}, {0x000dee098939db32,0x000c1e606c02f2ab,0x0001ff643e37d6c2,0x000ca3d292157452,0x0000781b3c4f7e2f}}, + {{0x00000b07850ec06e,0x00089d3a10cf6643,0x0004ab39dac5a38b,0x000bb8b233188de3,0x000077057e53072c}, {0x000c042b59e78df5,0x0007cd97de52bcf0,0x000e0ca4a4cfc91e,0x0007bbf661a26c3e,0x0000620a4c24b850}}, + {{0x000d4aa049f842cb,0x00046540e82b4b44,0x000c6f156ceabc5d,0x000d71806710fd15,0x0000e5ae52c13db1}, {0x000e7e6334957f10,0x000031144a7006f1,0x00096447b57e388f,0x000a12fb69bb2fdf,0x0000f78ebd373e38}}, + {{0x00026052b7ce5421,0x00096472bde1b822,0x000d2f4dae6d4ce9,0x000b2e43e16ebe09,0x000080ff42e63b92}, {0x000cc022c34a1c65,0x0008f22c46c2c59b,0x00014a8a23803d6f,0x000b27c8aff74f5c,0x00005aebf8060a08}}, + {{0x0007d587135593fc,0x00066be570cd6609,0x0008c860d32e6eff,0x000162984e6a102a,0x0000d18589162eb4}, {0x000e99d6d97e1340,0x0000dd8447ce7cea,0x000c50273d42c6b7,0x000e1e59ddbb4ab8,0x00003c612df3cf34}}, + {{0x000ca1504b6c5a08,0x000898f0e3a384b9,0x000986c0035216f3,0x0008fdbec2d2bcbd,0x0000bf546da51922}, {0x00055a44cd623c3e,0x0007702b8e5ad1c6,0x000a0bfe7366ce71,0x000e8d4cfc84b4ee,0x000001d5cefaf443}}, + {{0x00045d9036520f83,0x000162d40e988ec0,0x000559a04dfb3c3d,0x0006b0dbac4ccecc,0x00005eccae5540ea}, {0x00032dbf8a5a0ac5,0x00059b699700180b,0x00026bca0547972a,0x00025a53765801ca,0x00007e09d0ef647f}}, + {{0x000970e2fdd23cc0,0x000c5682e971b956,0x000e86ebcb80288b,0x000939e6e6d91e9a,0x0000564c83f8c9f1}, {0x00032a239560368e,0x000a249c28e25519,0x000a158c3e893752,0x0002622b03cee5a6,0x000012d656be4964}}, + {{0x000554e63e3bc1da,0x0001a5044ff74b47,0x0008daa07c719b6a,0x000dc2af24d30ae4,0x00003f3755768c1e}, {0x000bf760700d3607,0x0004122ae4e29a47,0x000f1fb4cbb1a182,0x0005f4b2e275a389,0x00002b1aa240968c}}, + {{0x000eacabe063f644,0x00037ce47a09a75f,0x000d07aca9b392f4,0x000d0f942415091a,0x0000b0c591bcd26c}, {0x000ddfd92f1169ae,0x000b6cbf23922d42,0x00091a2af63aeb1a,0x0001d93de9e87706,0x0000be79af8b9802}}, + {{0x0002a4e40e50acf6,0x00074f01d665cfdf,0x00031be1ff0a98ad,0x000da08fb640bf18,0x0000fe8bd2fe0e9a}, {0x00003a16cafbc916,0x00092308e08c94c1,0x00080ff4f170f875,0x0001f1fde2d2ab97,0x000066466bca5b20}}, + {{0x0002010f5b343bcf,0x000a02f142fe58af,0x0005f4bdf0f2e400,0x000aa84483bfdea8,0x00000b1d093f3bfe}, {0x0001b95c70816030,0x00093dba10972ea0,0x00038f3a6e943e4c,0x00063647be92adb4,0x00000bb7742e5bf6}}, + {{0x0007083824297b45,0x00000584455f136b,0x000c7d69e9d0e558,0x000e765b48cedcf1,0x00003a9e4817a256}, {0x000b0e065eb24132,0x00046fc407a70402,0x0007f5492dadbbb8,0x000294865cd5a48d,0x00001d4429394bae}}, + {{0x0007ce63b5f1cc41,0x000abe872e626691,0x00005f24437ae52e,0x00074fab087b7229,0x000020770862e6af}, {0x0004e491058edeaf,0x0002c638ca1d4b64,0x00038591c827510e,0x0000629cf2b70460,0x0000fc8b47bee635}}, + {{0x00020e61b4d5e634,0x00025d961b4b3ae2,0x000d16bedbd86474,0x00047b210c107e9b,0x0000270352a51271}, {0x000ffe664cfc50e9,0x00098e36cb427d17,0x000dc5f9a50dee01,0x00062b768a762235,0x0000a08d5376f53f}}, + {{0x00014576be5f7de2,0x0008a2263c9e4ed7,0x000cacb36d93006f,0x0008abc073694cca,0x0000ff7a5b45ae11}, {0x00053f1cd871236b,0x000d12aa6d523cce,0x00098d76df156a39,0x000d38ecc5f271b1,0x0000c615b7031383}}, + {{0x00038e8de3eee6b3,0x00087b910d91a545,0x000d278bd58c7753,0x000cae01e5bdbc58,0x0000cde4adfe963a}, {0x0001fd25302169cc,0x000fe989ed8bb188,0x00096a0ee8ca60f9,0x00083ce1999458ff,0x00001141f046c6c2}}, + {{0x000408d6dfafed30,0x0003396615887677,0x000726fa033a0165,0x0006da3c9c15ec0b,0x000090cfd936c9b5}, {0x0004baea3c40af51,0x000bc21129f1e34f,0x000207ce83469ead,0x000ef9bc51674a1e,0x0000e293b24d83b1}}, + {{0x0003d131e6c0bb48,0x000510776d351717,0x000e6f9221900469,0x000a2267980e346d,0x000073554cc74dd9}, {0x000c627cbf18a512,0x000b1032c0810316,0x00046834d4d93651,0x000f80007f277139,0x0000c08d7b450cdb}}, + {{0x0004fb486df2a61b,0x00073cf7b4a2137a,0x000d042ffa1ed9c0,0x0005ec02e460e27b,0x00007f5e2fb0f62f}, {0x000ec6bcc2423b79,0x000f2a63eea77aa6,0x00050a6e175ce0a7,0x000c9ed7a45fb1f2,0x00003bc919d753cd}}, + {{0x000f56f871942dfe,0x000e9859ad669271,0x000cb1a782372ff6,0x000a827f4c2b9633,0x00003e291023838a}, {0x0001611e4e8110ce,0x0004530198cea7ed,0x00020efe02a2d70d,0x0001beddf132e867,0x000061a896346a47}}, + {{0x0003a85825808bd3,0x00070fd6e902796d,0x0006219d151dc3cb,0x000d32343c768a91,0x00006cd7685d2ad7}, {0x0009d05b22922a44,0x000e9ba29660e3db,0x000d2ebc76494c87,0x000f8db0ac91dfbc,0x0000deb57a085107}}, + {{0x0001f59c3d12a732,0x000c85c2c51d4227,0x000797bcb5f71687,0x000eb0ab1f50c605,0x00009ed0ed9f6d34}, {0x0005b474683c2eb9,0x000507447c46e5fe,0x0002071674956eeb,0x0005eecb163a4371,0x00003fa2fed9248c}}, + {{0x0000af231f63950e,0x000034caa2c96793,0x000ac7e62a77797c,0x000aeb726e80ee27,0x00001e6e62738b28}, {0x00078b0b3c9fef02,0x00004d5f90be6361,0x000ce51cfaf7752e,0x000e1f74ecaf18ee,0x0000864d0edea806}}, + {{0x000e38397c69134a,0x00064b2912936de2,0x00060bae05a42c31,0x0009d1277792196a,0x000024de3470b759}, {0x00074aab75d49411,0x00061d501ff049d3,0x0007974cf9890058,0x0001158f16d40eeb,0x0000033860bddd8c}}, + {{0x0009ac82094cec3b,0x0007903b770cb6c6,0x00059590d9976fb8,0x0001fc6dea026c48,0x00006acbb473562d}, {0x000c46144569d857,0x000627f0891d7cd6,0x000d5a17dc3190a3,0x000bc856f5319548,0x0000d9199674749a}}, + {{0x0004837dd1c8a206,0x0007cf6834196510,0x00094022e7e5410c,0x000ac2358c3ca8be,0x000005c3197c145d}, {0x000750101683d546,0x0004f95b12343fc0,0x00081277f1d7127c,0x000adab0b8f87c94,0x000077db2a9465a1}}, + {{0x000ccaaddce33450,0x0007012a4350ec2f,0x000598bdc2a6811b,0x00012896760ff1ac,0x000054d652ad1bf4}, {0x00051d492a210056,0x0000d3110fdf0a11,0x00060100fad7f397,0x0003622c95928c19,0x0000c91c825dbf03}}, + {{0x000b2a2ce309f06b,0x00091a27204bc8c8,0x00048e32efdb27b5,0x000f1e2223eaa508,0x000093e4b2f97bfa}, {0x0008ae644aa3dedf,0x0009d015d573c530,0x000979707317a666,0x000957d888ce231a,0x0000141c1e6fd5c4}}, + {{0x0007de5619063736,0x000e8b999595b53b,0x0009e5c36858dbad,0x0008422cbb47b2a5,0x000060318b43cf4e}, {0x0001ccd12ba4b7aa,0x000b58c8282abd16,0x000b2130df399daa,0x000d7c7587633aee,0x0000465311b7a38d}}, + {{0x000eec864d3779b8,0x00062d64c1715f75,0x0009144283c5d047,0x000c29074103712a,0x0000096a89210e2f}, {0x000ae9d23b3ebc2e,0x000ac580cfd6d3d2,0x000b01f6c90bdd6d,0x0002db72dbb7f3c5,0x000068eded5c102a}}, + {{0x0005b7799eb6df0e,0x00009386b7791778,0x00017a48e26c3cc5,0x000f30545ed98864,0x0000990b4e4e7d6e}, {0x0006b7e2586abba3,0x000529c96e9a0f45,0x000eb4206239ca6a,0x00090ab327459ce2,0x0000a4c3313d002b}}, + {{0x0004806f6a3f6fbe,0x000ea5c251dd2a11,0x000a784d3ad5cad2,0x0006d4b2c1f613f5,0x0000c7bfad014976}, {0x000cd333e23cb3ba,0x000425a64b2d04b3,0x0005891063979fe8,0x00027e792e27207e,0x000060c43d2415b5}}, + {{0x0009082be7cf3a64,0x00027c9672742dae,0x000a0a8a9cc86ba9,0x0008b3b28a2ce8ae,0x000004ca6d9aee98}, {0x0009c5d005921b83,0x000114e79bf9fd7e,0x00075ddc2f56297f,0x000e877163b4600d,0x00000b23616d1f2b}}, + {{0x0000d21bfe50e2b2,0x0000c1bfede14b07,0x000ac4ae07ef8cfd,0x0000338dba00112a,0x0000a3e7d01d9ebd}, {0x00077ece38d9d1cc,0x000ddc5d2de39952,0x0003ca8c9b500249,0x0003aec912b820f1,0x0000879811547779}}, + {{0x000125dec3f1dec5,0x0000411178da19e6,0x0004a673807b1f04,0x000dcd893ededa90,0x00005187a5a5bebe}, {0x0004722eb329d415,0x000ea170b391f7d0,0x00099f828f449099,0x00076dad317a69ca,0x00000c3db2b84a49}}, + {{0x00077843757b3927,0x000d3a3ca05ae9ba,0x000e593d4326caef,0x000d1308e5293bf1,0x0000842a9377d98f}, {0x000bf965f96b10d1,0x0005f6a8cd05e694,0x000f0c7fc373a9df,0x00072e897d1e51e8,0x0000d01979073fd9}}, + {{0x000d8585499fb325,0x000927a8aeb70064,0x00008eec57b67bad,0x000e1ccd3eb9772d,0x0000fc047a71baba}, {0x000d159e54a64bb8,0x000b443497e40577,0x000e0608d8862201,0x000aac2d6b4e282c,0x0000b687b7d8b167}}, + {{0x000d3678b2ecfa91,0x000d990c3c386ed4,0x000e5c42b24dfe62,0x000a9f91862e103f,0x0000ca73dcae5732}, {0x00038b776bb87ad6,0x000b9242b81f35f0,0x000fd90cd674976a,0x000091ef2bde7eb0,0x0000efc172f07fdf}}, + {{0x000b69b92222f1f5,0x000a1cf7ae703806,0x0005217ee5a2459c,0x0005ac1789f69ca8,0x0000f232b5f33dc8}, {0x0003ec548e9e5167,0x0006c197eb31660e,0x000fcca23124b4e4,0x00024ea0a0cb13aa,0x0000bd63ba4f2132}}, + {{0x000d7cc290a7f4fc,0x000d4286b461affa,0x000a407af6b409c9,0x00007298ab809fff,0x00003122eee868ac}, {0x0009e504ef24d7e7,0x0003ce2a581117bf,0x000902e015d92979,0x000850e19bc86702,0x00006bba5daa9c8a}}, + {{0x000669cda94951ec,0x000ca6b8d418e9f9,0x000d426a44b6af58,0x0000273a32107417,0x000078e66aa5dde6}, {0x000c0834a53b9649,0x00086f6023300516,0x000c5c897fc659d3,0x0005de7ab55e5c58,0x000085099b3138bc}}, + {{0x0009efcc52fc2384,0x00082ac1da3f061d,0x00083fe08712b272,0x0002f7bb65814992,0x0000954ac94f8aaa}, {0x000ada47fb2e74f1,0x000ea89926b085c0,0x000d1af5bee8ba98,0x00015ed4f9d37d23,0x00004ccdbf9ca9b0}}, + {{0x000481b7bfe71786,0x000e05405868b674,0x0008c867d4e1deba,0x0000e9a61b2821c4,0x00009c15b35b13b3}, {0x0001666368710884,0x000cd220b1ff3b4a,0x0003d9f4de5e29f5,0x0006750b82bb3523,0x0000e07633358cdc}}, +}, +{/* digit=10 [{1,2,3,..,}]*([2^70]*G) */ + {{0x000f5c7a3e6fced0,0x0005f45fbdeb0d53,0x000339a70e8cbbdd,0x000b81f85c01df13,0x0000ff71880142ce}, {0x0008774bd70437a2,0x00019a0bda6a4c4e,0x0008bd26e5fb3289,0x000521fcdbebd2f1,0x0000f9526f123a9d}}, + {{0x000305192c4d6840,0x00057612efcd40ce,0x0009cae208b04d72,0x00056cb9dcda366f,0x0000edc4d24f0588}, {0x000e6bf854279005,0x00058c09dfea64f2,0x0009bf26c3de8129,0x0005a9841b448737,0x00000b62c6dbdf13}}, + {{0x000e3b4c72dfe67a,0x0005f0e19fdfd4f8,0x00013bd35c416b0f,0x000b9d78b9098d4c,0x0000c11118ab5b8c}, {0x000a318f00628413,0x000f59f356f4f598,0x000177a0cbfe0602,0x0005374ae3637e30,0x0000409774791136}}, + {{0x000fb5ed005832ae,0x000ab1042e4f0db2,0x00070f8ca5f5efd3,0x0009cbac4ffdc6ed,0x00004645d0c952da}, {0x000f58bc9001d1f8,0x000bce1172059596,0x00098a08452c8f0b,0x0009de7d4aa0d2e3,0x000015bfe3a904f4}}, + {{0x000443f23885e5fd,0x000918433aab97e5,0x000d4e604f72f8f9,0x0003feed00b154e4,0x00000b35e6bb5e17}, {0x000a0489164722d3,0x000b58761ec857b2,0x000a838323e3c665,0x000e3b3bdd13973d,0x0000c8b1a1ea3daf}}, + {{0x000ace654317cac3,0x0009221771b34497,0x000dfe8b8be600ab,0x00010f842e409eb0,0x000086a67d769423}, {0x0008d8d4431cc288,0x0002185dc5242554,0x000c4be32a7cff14,0x0006e0cd60f5a193,0x00003ebd5c95071c}}, + {{0x00080a7b1fd2b0bc,0x00059bec33e8ba3a,0x000743fb39b3ad39,0x0002f9f3868d6179,0x0000fd169fdbdb46}, {0x00099d79ce0a6af4,0x0001a42d3ff8d3b4,0x000c3e1b255dc1cf,0x000473c4fb9e6cc6,0x00007e6961daf69a}}, + {{0x0003acce548b37b2,0x000264d4054954eb,0x000341b4fb38e754,0x0007fa6c3daa517b,0x0000f6928ec890bf}, {0x000b32386ce6c413,0x0004e0adadcd0496,0x000b5faf901be1c5,0x000985904e67e74b,0x0000cbaf679115c9}}, + {{0x000214550ca42470,0x000ae7dd30aa8cd1,0x0008fee24ba1aa47,0x0000e82f81ddf1e5,0x00003452936eec9b}, {0x0003b81243aea965,0x000ec5c3d0e58bdc,0x0009483619a2919a,0x000ccf4ea640ec10,0x0000ac86d5bbe0bc}}, + {{0x000d918c36cf4406,0x00076939719cf892,0x000218b64aed3e83,0x0000dd507b08d2c0,0x0000f1bcbbb2e979}, {0x000d6ed60919b8eb,0x0000dac1f9eb4a84,0x000d5daefd890079,0x0002c5484941aa0d,0x000022fe40b17fd6}}, + {{0x0005ba2157f2db33,0x000f5e28ca9c97e1,0x000b9f454bda2fc8,0x00072e2d050da437,0x0000d57eb575379d}, {0x000eba2fb5ee9973,0x0002b11538cae9b5,0x00032797401648ca,0x000bb702bb76f6f6,0x000038f14b92f3f4}}, + {{0x000226ad7ab9a2d8,0x000cfdfae958524d,0x00051d8c29c00090,0x00062c8ba5f53987,0x0000afcbcddbab82}, {0x0002729e99d043b6,0x000b4ebc943a5739,0x000862935ef51263,0x00017b3feace9320,0x000039efc04106c8}}, + {{0x00054b366b4be7ad,0x000db4a37a1e1fe0,0x000d75cd93f25a9d,0x0001b5239ef1ad78,0x00007b58f4a2062c}, {0x000f9a9ff563436b,0x000938af51e76f74,0x000e97fecf718ff2,0x000c09a234d31315,0x00006a8e2b1d92f1}}, + {{0x0003aa8327720c15,0x00026a092cc8a7f5,0x000746c4d956ca32,0x0003923f03d64a28,0x00001fe1782b6d0d}, {0x00034db3c832c80a,0x000bcda2e3b4d19b,0x000104ccc60dccc5,0x0001fc845dd62e0a,0x00007ab1de2020b2}}, + {{0x000ae0b3893d123d,0x0002e15ee71cb293,0x000a9468bf7b7578,0x0007438aa3c61442,0x0000686123dab15d}, {0x0006891a7ab4116f,0x0007b4e6a4598c61,0x000e5fad76fcd72c,0x00046abc21911077,0x0000b6a20e8604fa}}, + {{0x000be7d341d81dcf,0x000842148379e839,0x000026eadcddb688,0x000c5dea6211a1f7,0x00003b25760e4d1c}, {0x000c8f6a7a73ae65,0x000e11d5b48340cf,0x000a50ebc83879a5,0x0008fa75acb1ed41,0x00009a60cc88c07d}}, + {{0x000bdceb18762621,0x000002af4ee91b73,0x0006e1d072b0d79f,0x00052f7bcf3b0bd4,0x00007d6af9df45d1}, {0x00004616d7364517,0x0006e6b0bf5a7352,0x000999b9d43cbbd9,0x00039840833a5bd5,0x000002614f15b72e}}, + {{0x000f01a59c3e9f87,0x00075e6b3d160aad,0x000ddafad40200e7,0x0002e16a22bdd3de,0x00006dedaf4a10d7}, {0x000807c4bc2e88f8,0x0000946dd5a549ef,0x0008d59e96ba8129,0x00034921a4077a7d,0x00007b6a2e8002db}}, + {{0x00099971b4e598eb,0x000e56fe4b1dd567,0x000b267c5f499ef1,0x0006cf8978d3aefc,0x0000582b557d3578}, {0x000b2ca1715cb07e,0x0001a480241d32b3,0x000571ecd4c3de6a,0x0009a883b5ffedcb,0x0000af53901cd2fe}}, + {{0x0008d4ac3b819900,0x00029e0cc8fedec9,0x000b427b91cb8372,0x00066cfe0b0491d2,0x0000f2386ace983a}, {0x0004d1eb32912137,0x000de9a62ae4930c,0x0003e89e3a2f82b2,0x000c7f07233853f9,0x0000f8063ac81777}}, + {{0x000b56759ad2877c,0x0001d865c754ff0e,0x0006e9a846f45464,0x000fc326fe701a23,0x0000586ef16c6e40}, {0x000b6e024bafad93,0x000234da906a3f62,0x0003276a0c8b42bd,0x000852998e1eb4da,0x00000d0e5fc36cbf}}, + {{0x0002ae1e8b4dfd4f,0x00069301cbac1b6b,0x0002a39acd754d5c,0x000ab87609762911,0x000086b599a83ba4}, {0x000dea799f9d5812,0x0008a2fafeaa26c9,0x0002505a50473b1a,0x000322f469af553b,0x000027d16d7f6a43}}, + {{0x000f73cad3d97f9a,0x00047f1374553316,0x000954e7c52bf3bb,0x000410f53eafeb09,0x0000721dfee7d732}, {0x0009821141d4579b,0x000bfa3bd435b492,0x000fa60153411321,0x000f0dffb355aa17,0x00004e7ef4ac8e42}}, + {{0x000c97c593710000,0x00007f759c18604a,0x000db6b65e1c48c7,0x0004953f62ecc5a5,0x0000a78b17338a21}, {0x000819dbcc8ad945,0x0006889c34006be1,0x000b4840a70dc04f,0x0001bff62557b4a6,0x000044c6adeb0bd2}}, + {{0x000f24e907a544b9,0x000aa13da2106a00,0x000e4994ba7520dc,0x000d706e939b7511,0x000018b6ba74c275}, {0x000e0fc644be8924,0x0006bdaf6c42d3e5,0x0005c13fe707a981,0x00054a20145567f1,0x0000818ebab2130a}}, + {{0x000d3ad58d2f767a,0x000d37e7c77328aa,0x000afcc98dc5267f,0x000d4aa919cc88c3,0x0000a2e6ab0cdb8c}, {0x000ec04d0c63eaaf,0x000429ffa832d46f,0x0003a631fa1cb92c,0x0008b2778dd178e4,0x0000b5ae1ce2dc78}}, + {{0x000fb906e77de048,0x0000706dbb9768b4,0x00017c01d7992bcf,0x000e01096e6a13c4,0x0000d96332d3956b}, {0x000c93a413aa2b94,0x0005bc98c8a5902f,0x0005f113799a4d91,0x00028112c2940756,0x0000072690f61e4f}}, + {{0x00007cf02ff6072b,0x0008dad98cdc36e6,0x000f56609a47d2ca,0x000da00f471d1ef5,0x0000cf86624a264a}, {0x0000687aa9e5cb6d,0x000147401c6cb70c,0x000a61435c98124f,0x000ea5b189635fd4,0x000028fb8b079d98}}, + {{0x0007c2a40c251f81,0x000792da44beb9a6,0x0009b542388cd5d8,0x000dc1337deb96e0,0x000050467db74287}, {0x000debbcdabb8397,0x000281839a3ee161,0x0002d202ba79e974,0x000d964b8dd3c265,0x0000b3e67f859f97}}, + {{0x000d78fb1cb6ac9d,0x000dfa1d0d455aa5,0x000a5bf95ffa13e8,0x00005d669295dd2b,0x000068bd1f909aff}, {0x00086f926d783f2c,0x00033c3aafc1af0d,0x0007da97c543a59b,0x000e457fcf81d27b,0x0000990a057925de}}, + {{0x00075b8519cce2c4,0x000f6e13d8633e67,0x000c1605cfc9af71,0x0005e8374a4a6f47,0x00006ba42456fd20}, {0x000eea4d3fd524d4,0x00012de1acc2a06f,0x0004e2b421e72464,0x000024b53816f133,0x00009e5918ed22f0}}, + {{0x00030b665c7322db,0x000103c1b3fb4395,0x00072f685cf12cc0,0x00091d170b018601,0x0000915ee22cb583}, {0x000f03ba317db248,0x000897b8ffc49afd,0x000d3d05087dec65,0x0000e6ff46597be4,0x00000a1c1ed80650}}, + {{0x0002a9678bf030ed,0x0009805601488490,0x000362426fb5e9c9,0x000c3f9dae0a9263,0x0000caeecf579e30}, {0x00087bb518d0c6b1,0x0002bb985b9dc0d8,0x0007bc3819918115,0x0002019d186898ef,0x00008168ffbaee46}}, + {{0x000cdaa2502753c1,0x000641407c419a04,0x0003564e5bb279e2,0x000016dacb03aaf2,0x0000833658281e61}, {0x000b8c4eb8098772,0x000dca0e672e8684,0x000ee5867b336e18,0x000fd1cfb601f034,0x0000733edbe3341c}}, + {{0x000809a26025c3c4,0x00065350df88b15e,0x00002fd8ee6e981a,0x000e9b5237623785,0x0000791f2164c12b}, {0x000678925f02425c,0x0003ba974443b725,0x00041cc52ec86319,0x0007f1bc0ce882fb,0x0000266ff7fb25c0}}, + {{0x000a8c3017025f39,0x000c6b9579b43d4d,0x0003716ecefcf628,0x00016dcc4d00161f,0x0000c27ebc4f8011}, {0x0000ea11da1767e7,0x0001d7004c575eba,0x0002373b7fe15145,0x0007abcace6df68c,0x00005c3dffecdbc3}}, + {{0x0002a73ddc925fcd,0x00005f65ee0b3dc3,0x0001cbfebb679c84,0x000a28a15a329545,0x00009889769c76e9}, {0x000ce7fb28ad2470,0x000400894d79ec20,0x0005e3ea7e99146c,0x00003171457d7c9f,0x000097b266238030}}, + {{0x0006ae6cf9f82a81,0x0009338f473adb7f,0x0003856c3319decb,0x00061b963ab38628,0x00003e3172fc06a3}, {0x000f8dc7d5a006c0,0x000675fba7522959,0x000c22c9e2dbc27c,0x0008b2c1227ab287,0x00006f61f7571a26}}, + {{0x000b97104779ce2a,0x00016aadcb1d1b6b,0x000aab2d5aca8381,0x000f12897ae0bcae,0x00005c14ee7fbfb9}, {0x000c583f17a62c70,0x000c173759f6aa00,0x000c9a88f39eb962,0x000c5e1eeba1d486,0x0000ab6c37adf016}}, + {{0x00047dba28a0749b,0x00063e519165a2a1,0x000810715246c20d,0x0000b8a068d1b1d3,0x00001e7018d24816}, {0x000b1faf380ff628,0x000d73cb2c1e03f5,0x00091a7daef7fb1d,0x0005616ab539a8fc,0x00003ddb70873f9b}}, + {{0x000e211fe7df7a4b,0x0001563f6f40c550,0x00076879ca7cd07f,0x0001da00de363529,0x00005f83f8695574}, {0x000d25ef3d8ac3d1,0x000f52819f024ea9,0x000f4a5646fe2066,0x000de33ab2b9c2ce,0x0000e155d966ffa2}}, + {{0x000a19bc3a72d004,0x000b4513c31b0eb0,0x000c646374037665,0x000638efb2b6bf04,0x00005c34d6e48cdc}, {0x000e10ff01fd7967,0x00018e3667b856f1,0x00021d0c04dfb810,0x0006ab70eda25390,0x0000a94e9fffa06c}}, + {{0x000b0d9bb9aa8822,0x0005cc05fd102d3b,0x0001ca64eea20e4e,0x000cbdcd7eeb5f1a,0x0000fa6b43ce6327}, {0x000e3cf3aa91121f,0x00094a34079bb577,0x000e02fc08c6bd5e,0x000bf7e7e5ba3960,0x000016dd2c480141}}, + {{0x00076d980101b980,0x000db82f0f66b572,0x000c3eff3760883f,0x000b4089d7de754b,0x00003b606435dc2a}, {0x00053dfe05beeac9,0x00022c3325cdcd6e,0x0004f03c3f2f1e86,0x000c1b4d0f792177,0x00007ca7221d552c}}, + {{0x0006afe1cd19f723,0x000cc183fbeb5a0d,0x0002c403ca20915d,0x0004426fda4b4083,0x00002738eddee425}, {0x0001df6b5eccf1aa,0x000188bbe1f0469a,0x0000dfc934b5aff4,0x00062791359d7f57,0x000018be23690088}}, + {{0x0000fbab00ed3a95,0x000423cdf8bea5b3,0x000c5679734c6137,0x000ae1dc5c5f46ab,0x0000cecf93e082a8}, {0x000be41a968fbf0c,0x00025a5c7f3d7d3d,0x00087a9c7d23d458,0x0001ca328f69a0c0,0x00002d7547207447}}, + {{0x0009f4a4eb732ec8,0x000d31ca6bed36ec,0x0004578926c943bb,0x000c06564535e1f2,0x0000b84a8eb77e2a}, {0x0006cd32499dd5f3,0x000dded04e57e093,0x000305d9d12053d7,0x0000a21bdd0076e4,0x00004a527b94f67f}}, + {{0x0004af09cec46eaa,0x0000c58b9bc7e79a,0x000af2f75b15347a,0x000434cbd2796f35,0x0000c957990e051c}, {0x000dda3c33a655d3,0x000e58514aa32669,0x00053dd415d503c2,0x000f78afa1133737,0x0000f0546733b754}}, + {{0x0005677496125bd4,0x0007f775006cbf18,0x000037899fb0023c,0x000a57ba0f072f3a,0x0000222b6eb4e4ae}, {0x0005e767866d25a6,0x0007e837aa6f3dde,0x000f1cdb8b6eb04f,0x00083bf315591a2c,0x0000dfb4f418d4e6}}, + {{0x0003ea448ee1f3a5,0x0006b5a2afd57e92,0x000ea49489604d9f,0x000d2f6e1d4a3340,0x0000b45f1f5044cb}, {0x00083764acc757ed,0x000793d68ff75faf,0x0000e404ba7cf9ab,0x000fdebad62f69df,0x000065f33c2e2bda}}, + {{0x000de15a377b14ed,0x000abe39f60cc365,0x000e681486bf5463,0x0003a792030d2d2c,0x000095867f0b6f84}, {0x0000244ef5ab0172,0x00012ab55d12d39a,0x0006391690bd2d8c,0x000c8aa9503db341,0x0000d4e25b117660}}, + {{0x000b3b5e224c5d71,0x000c58616919760c,0x000142552fa3baf8,0x000bf58fbca1138d,0x0000ab18bf18669e}, {0x000f53e9bdf25ddf,0x0002db6cd15455e6,0x000e8908004cc0bf,0x000ac0695bef4995,0x0000e9459a9004a9}}, + {{0x00089cacce9bb324,0x0001b7de8285ad2d,0x00051bd4bddea65e,0x0009a722ed8c35b3,0x0000150ff364c0e1}, {0x000c801345f4e475,0x0000d03a266c86e3,0x0005b1f133bf21f7,0x0005172ae110d485,0x0000d6aaf6a57262}}, + {{0x00012e1813d28f11,0x000d6ad7a5231e0f,0x00044a17b6000e11,0x000a00b7d8deefc7,0x0000e990b4824c05}, {0x000daee93e976d58,0x0000c6610d6368fd,0x0003dda88696241d,0x0009463204e7c389,0x0000bccfa65ea3a6}}, + {{0x00025b4c5cd14112,0x0002df3658b1b594,0x00084cf93701b404,0x000d60c3e56bca47,0x00007de5f15afe68}, {0x000cfcef8d53f19f,0x0000b40a730d4ab9,0x000ee0a8addb1031,0x00019c7fa73cd14e,0x0000d54874942497}}, + {{0x0006316a8123ef0f,0x0003f7f9543849d6,0x0009e785473c32db,0x0005063e2ed2090d,0x000098a932a8d9f0}, {0x0003cf60c6aa20a6,0x000415279bb2c5d3,0x0004a73079a32ba1,0x000dbd1e3202cb77,0x00004ed4bc548c42}}, + {{0x0001a06d4caed0d9,0x0006871d22b3c20f,0x0003268d7b802140,0x0001264426ca04d1,0x00002377007b5f4d}, {0x000cbc371f21a855,0x000aa82369ba4204,0x000c858f918461b7,0x00056970c07d313f,0x0000deb5a5132bab}}, + {{0x0009d46d5eea89e7,0x000398437f4bd595,0x000fe254ffdff842,0x000321821071e43c,0x0000241769705468}, {0x00088b9102cae3e6,0x000d91965dff5d82,0x00078d8472d143e3,0x000730a0c9a376a0,0x0000fc0da3186028}}, + {{0x000eadfe45083a2c,0x00079e5b4bcda2ba,0x0004b8e7f66bc721,0x00086a6c826442d0,0x000019f54522c4b5}, {0x0002c495b7eeed57,0x000d0aa9dfa16018,0x0003884add9954ec,0x0000413403a8ecc7,0x0000fb17de30bb39}}, + {{0x00064c5abb020e8c,0x000359c4eec7694b,0x0004793e53d18c18,0x0002e5dc4673ef1c,0x00007b8aeb5c5609}, {0x000ca43f0f8c16bb,0x000c2679b2f63aa1,0x000a205c9224ed5e,0x00028a5d56eeaf55,0x0000fe115bafb8e0}}, + {{0x00008493927f4fec,0x0003b59aa7c597e6,0x000e90a51f91fbf9,0x000822d85af7696b,0x00001277b7938ccb}, {0x000656ee7a759524,0x0000528da5f5395b,0x000a4454f00df7de,0x0003c0c9c231754c,0x0000ec971f4baa2d}}, + {{0x000c507e75d9ccc5,0x0009edc9030645c3,0x000b44bdc63b7be8,0x0006a1e7e09c665d,0x00000d60da1b841c}, {0x00065ee08df1b120,0x00097ff089df6f9b,0x000e8013d3873487,0x000cc89c331a663f,0x000017f5de95f42f}}, + {{0x0007866e8e575672,0x000ed9fcdb184307,0x00012e174c9f781c,0x00052a18131dda9b,0x00005d84aa3aa037}, {0x0009e094d0c0ce2b,0x000ae2bebba545e0,0x0007284c71564008,0x000baa47e8ad31a8,0x00007c4b46d47e7b}}, + {{0x000a7b397acf4ec2,0x00003ea8b6403e22,0x0009692850426c40,0x0006703e3295a64e,0x00002aabc59c6a45}, {0x000714c5f5942bc4,0x000dba3182edb929,0x0004152ba9a6168b,0x000367e216a66510,0x00006908d03f6926}}, +}, +{/* digit=11 [{1,2,3,..,}]*([2^77]*G) */ + {{0x000d8745a1251fb6,0x0008672725c7a9f5,0x000ffe89e967747a,0x00035db95c33e531,0x000009d211049649}, {0x0006ca82fe122271,0x0005f426469dcafd,0x00093183caf9b5b9,0x000fef1e9ee04c56,0x0000084a333d8146}}, + {{0x0009933aed1d1f71,0x0003405630909664,0x0002e39cf566eaff,0x000124245057f0ad,0x000048ff65b2f832}, {0x00089d4cf94cf0dc,0x0003920c58b3042e,0x00061aa0d319bec8,0x0007ac6a26762653,0x000086fa3034fbc8}}, + {{0x000d2ab5c8b06d5c,0x00023e4eac46fc83,0x0006f7779b1a785a,0x000504f99315bc84,0x0000f31d817af9ea}, {0x000fe6a15d7dc85d,0x0003e4016b332391,0x0001cb4c72f132b0,0x0005a059547fe318,0x0000b66d8a735015}}, + {{0x000d7e1adc1696fc,0x00024acd72d06b66,0x0001b743598ebe59,0x0005eba5f24550cc,0x0000e23139474b9a}, {0x00022d4db067df91,0x0005baff9b00234a,0x00000c9c198dda09,0x0006950bbc75a061,0x0000560a9c8a39cf}}, + {{0x0006d3e99e0925f5,0x00061322375acf00,0x0006af5ba2dd74a9,0x0004f1758b446ab5,0x0000029268430b9b}, {0x0004cb41aeaffa32,0x000f7b9587c1e2c3,0x000d1350c8b17203,0x0006044d559207ea,0x0000b66a2161b7f9}}, + {{0x000325efe51bf748,0x000dde4600940850,0x000da2f259c4f579,0x000f32dc87b92a76,0x000089de4e0efebe}, {0x000ec06646083ce7,0x00054fe127736900,0x000344110be2a033,0x000d203dd1da35c5,0x000057568b82802c}}, + {{0x000977900f7e6c85,0x000ebfacd2f07555,0x000fde37538e8b94,0x000dfcaea1f3af03,0x0000e11a1d8c5881}, {0x000b02ec1e2f2ef2,0x000ba605a6c5b3a6,0x0009a0b2d193d2bb,0x000846125ffeee33,0x00007b6a724be0c8}}, + {{0x0000f1cf1c367cab,0x000b190fbc7de405,0x000a110329bc85a9,0x0003a8f373c4a2e1,0x000064232b85d039}, {0x0007eb0167dad297,0x000124b78ab2f557,0x00029348b1604f30,0x0003419baa94afe8,0x00007fbd8ddb1654}}, + {{0x0000ea5b964e39a7,0x000c60d3c76edab5,0x000d11964d4c29e3,0x000c2f10dae67c56,0x0000307a8c055ffc}, {0x000c1aa91708c3b5,0x000bd8bf0eeb65bb,0x000a34db7a151e62,0x0003a81cb533816f,0x0000139e05cf2940}}, + {{0x00051b494a7cd2e1,0x0000f699336c6ff6,0x0009a896a5671ffd,0x000cef5f5fd2cc97,0x00001e893a8e8148}, {0x00006a165cf7b104,0x0008850d84859889,0x00035b3de81b6717,0x0007993c0deb358a,0x000023ac85601d29}}, + {{0x0000d87dac50b74b,0x000ea869734caf58,0x0004e28fb28b2b89,0x000739e9a3b93687,0x0000b2c9190d5f3f}, {0x000691884a9d5b7c,0x0004be770374199f,0x00038efe27ebe232,0x0002d23442e10707,0x0000f9f3f578f908}}, + {{0x00069e1096187086,0x00046183f9b1719f,0x0006a21afcc9e836,0x00041f8c203a9536,0x0000aec5d6d668b1}, {0x000f78a994f04e95,0x0007d71245b0ee2d,0x000e43f4fb39ccae,0x000a986875a4a997,0x000007dfe122b2ce}}, + {{0x00081cb489b03e9c,0x000aaec414fa4fbf,0x0001b3ae5db86ec5,0x0003fe3ad444f9f5,0x0000a7d33d6d914e}, {0x0002f5c0ae6c4d0e,0x000d93969568a9c3,0x000a7467ea9ca1d1,0x000ac5b8043c311a,0x0000832e75dc21b5}}, + {{0x0007aea5232123db,0x000bb5ae86db314b,0x0004668ed08307c8,0x000c3856e7165caa,0x0000170458c64d3e}, {0x0003ec6c19bb9866,0x00064e0304ed4d2e,0x0009f9722c5f3484,0x000c0a317695a06c,0x0000c7f7317acab1}}, + {{0x000940e9d6d2e8b4,0x0001149f7c976295,0x000713885d318b8c,0x0000fde245320497,0x000068d834be8a44}, {0x000e5b2bfba796e0,0x000b6d71f116d81f,0x000b66e53152364d,0x000192bb8c7c59b5,0x0000b12c61b2641a}}, + {{0x0004802fcf0a7fd8,0x0008d488b01e31f1,0x00052b49842fd078,0x000200f1d78d6d99,0x0000eb572d987ac5}, {0x000a44c4d194a88b,0x00090a017e66e0a2,0x00088aefcd2b63fd,0x000a10c8efc6c8f8,0x000076f6bdafa881}}, + {{0x000314bb46c2397b,0x0005aded2819187f,0x000764d34004cf56,0x000708f9ea570438,0x0000ba4521828084}, {0x00045711171121e1,0x0001d7c9b6710647,0x0000f7507ad7b7eb,0x000bd1cacfbc4073,0x000078cd8c6d7ad7}}, + {{0x000e101b2a672385,0x00075f9c14f2bf0b,0x0006620753556d36,0x000609c04b7831a5,0x00008ca59bbc9d9e}, {0x0005392a569a73b1,0x00084698f6c94bc4,0x000add755517a52e,0x000b8475643da5ae,0x0000aed0cd53a581}}, + {{0x000ff8480af13722,0x0003d1ba5d1fb9b4,0x000f98d31244c311,0x000c2a0a5dacbef5,0x0000c3323e86375b}, {0x000ab4a5594b1dd8,0x000b4eb4797e17a3,0x000886a19a1928bf,0x00074a683af245e4,0x0000979d546f2b5a}}, + {{0x00026bc19f9e9676,0x000288fbbf4ea0f7,0x000707d40d9d0315,0x0006e06fd6f51db7,0x000033084d9c3f6e}, {0x0009cdc55667eaf7,0x000abe44d56fedcd,0x000962b1473b7f92,0x000cbf8b2e39b64e,0x0000d408f6f6671f}}, + {{0x0004ddc164a89bb6,0x0001def3bd05cc63,0x0008decbb74a42bb,0x000595b280dbb242,0x0000103f6bba02c8}, {0x000f581355a5752f,0x000710946674fa2b,0x000a0223b562f96a,0x000a245e4ca16d6d,0x0000e4781a018d3a}}, + {{0x0003075f8dfcf8a2,0x000a756698259eea,0x0007d3fd8a284f0a,0x00091e93fca25086,0x00000757b5f469d6}, {0x000402093b8a5ded,0x00091bc06da6f2c2,0x000739c33d3f9335,0x0006e44178293eb2,0x00002a3e7718cd68}}, + {{0x00049f4cd941534e,0x000b03c71c0ea76f,0x00097f7e30d37406,0x0000dd372d93973b,0x0000c17e23a9d7fd}, {0x00005516f496ba27,0x0001c6ad50e7e329,0x000e7eff56a69317,0x0004cf54e539a283,0x000052737e788e1b}}, + {{0x000932c68af43eec,0x000db03d00bda2f7,0x000b061f55502468,0x0005ad25dc978f2f,0x00009a1904ae8c81}, {0x000538d470c56a4f,0x000e293d8cedd3af,0x000108ef3159abc5,0x0001773a37245f20,0x0000a17081f123f7}}, + {{0x000fb2b10c8c0f59,0x0009b065054727b0,0x000c3bfa72102c3e,0x000d95c94564df8a,0x00008102033e09da}, {0x000643ff1d18a13b,0x000127fc5af06989,0x000eaafd835eebd9,0x000e97578d096afa,0x00007a893428ef3d}}, + {{0x0006e8decf2a73a0,0x00078e5519942a20,0x0008d53a2066a639,0x0004aa3a6a088ab9,0x0000ce7c67c2d112}, {0x000c671759a113ce,0x00026f6f67fa48ce,0x00036727be3b373d,0x000d807455d479fd,0x00005a428ef813c0}}, + {{0x000dbc81c86682bd,0x0006e8d02b2ab853,0x000bc329ab78d272,0x000147daf69bed8e,0x0000b6b40b3f93b2}, {0x000a77db8c4961f6,0x000bc0e5e0abe42e,0x000e8b05eb1a12f7,0x000a8040ec527479,0x000080273925ab60}}, + {{0x000ea5f16b1bd5e5,0x000ffde30ad36bfe,0x000353b9ef957e41,0x000feb7baf664e6a,0x0000c87331276d14}, {0x000f98cb65f57cb1,0x00014e0cdd414e87,0x000881440db60a62,0x0002aa57c16865a6,0x0000093ef1a56ab5}}, + {{0x000afb53f4ece64e,0x000d9604551ac095,0x00026b8cd6a6bb02,0x00068975d44b4e0b,0x00005f9a99ad9712}, {0x000c42511a7de841,0x0005eda469ddc08e,0x0006c90a28356809,0x000831637bfba16c,0x0000cb9c4a0ce229}}, + {{0x000cbbabb2eec644,0x00049a03adbe93bc,0x000e86ac4a0c23b6,0x0001e61f7aa00ae0,0x000070b941f3c140}, {0x000d6799df435742,0x0008ef65d8105ad8,0x0007fbd814ccfb8a,0x000209fbce80e3aa,0x000073291adb508d}}, + {{0x000b46b42a92806b,0x000bf86ab44af5c4,0x0000bc9f8810684e,0x0000539591640bca,0x00005efcdfd0c4b6}, {0x00089076e9edd128,0x000054d792f916fc,0x00003116de29d0b5,0x0005a4245fd01c9b,0x0000503523648176}}, + {{0x000a9b2b4b4b67c8,0x0000680206041fe2,0x0008058d8c1d10df,0x000fbb1d64abfcbc,0x0000943b9b2f12a0}, {0x000d9143b3def048,0x0001cce775ff90ee,0x000bc904085ab3aa,0x000dfae05fd4ca7b,0x0000b34a56562c75}}, + {{0x000c94a10358560e,0x0001be5c28aa41ff,0x000c7eb152d8a507,0x000f5d0915a0fc4c,0x00009efab066f6d0}, {0x00047a9d19e9b915,0x0004b276154cdbab,0x000fede0d8cfed74,0x0004eec54357ae2c,0x000020630df69f5a}}, + {{0x0009f7ce382360f1,0x000978bf58572575,0x00058d46cb6db05c,0x000b7a1917d61d6c,0x00004f8e4920d20c}, {0x000727a11c203407,0x000f3f7ccbb6b68a,0x000e09a200386f86,0x000a34ec8bc6ccfe,0x0000d76ff4b2b7ee}}, + {{0x000ebe7db15be7ac,0x0004189f0302a7bd,0x00019336467a0805,0x000ebd96bf0ea9c1,0x0000824446822837}, {0x0008e8b20d841b88,0x00085bb8a54f32bd,0x000b20236127a054,0x0001fa03dd4ca663,0x00007714718a0349}}, + {{0x000caaaaa8a5288b,0x0009ff23a1c94dab,0x000220e0c91cc0c8,0x00044984c72c6a3f,0x0000cc20bdfc2321}, {0x00042daa20ede1b5,0x000c24a005156e2f,0x0004b8c4bc441f00,0x0009a46f46a5b673,0x00007409503cb56c}}, + {{0x0005261e4585d453,0x000d3734e6429f73,0x00070ee6c9231fae,0x0001bee158a176be,0x00005f1068dac350}, {0x000f900a2d261155,0x00029f0afee36bee,0x0002420a1649406f,0x0004abef43a60abc,0x000009002a825aee}}, + {{0x00036a53ff3571bf,0x0007937927c1b468,0x00033c71624f98b7,0x0001957254256a45,0x000027abb0cc07ee}, {0x00064fc5c6d5bfd7,0x000180cd7a77d7cf,0x00098f5346915c75,0x000b5f69f5901287,0x000072b0da9681d8}}, + {{0x000260c2e03fa69a,0x00099be1a3741244,0x00006b96036cf0e3,0x0000f5ce7c1633ef,0x000071a4c56071f9}, {0x000125133c673db2,0x000053e8c1317a94,0x000f6c734c0bea51,0x00000141a8a699d4,0x00005e78c88541ed}}, + {{0x000acf88e2f7d902,0x000757be32cd5c18,0x000eb5ee9fdbf33d,0x000114ea085cd7d2,0x0000d702cfbd3201}, {0x000ebdb85c88ce89,0x000b8e01d617b6e0,0x0007333ac23a3ce3,0x000b6aa041618e56,0x0000dd0fd8fa57ed}}, + {{0x0004702b57872b88,0x000ee57d5fe127f7,0x000cf3d402ef26b4,0x00067a15426f0a57,0x000047e2ad1e5a60}, {0x000d9a009996a74c,0x000c6a26115cd474,0x0006f4d4316a56ac,0x0005b642a615c3d1,0x0000c3fc9666adb8}}, + {{0x000da73ce07d1b0c,0x000198ad4178386b,0x0002617f4d82910c,0x00076f524f82cfcd,0x0000c2f5e8eaf691}, {0x0002550b8c30ccc0,0x000a1a8e575a8270,0x000ab94597b856ae,0x00038ebb822fefb1,0x000085928bcec24e}}, + {{0x00002ecba8f4b4d6,0x0009a0b4d58b5d04,0x000227e7ac07cd4b,0x00086efd8dffd529,0x00001d44d0c91bf3}, {0x000dc2b135e6f4d6,0x000b879410efe486,0x0000088b5680962e,0x000686461bd343f1,0x0000aa7607742e28}}, + {{0x0003d118fb98871c,0x0002fbc76aff8046,0x000e03614cb26f5c,0x000dee14ab8eddfb,0x00008eb579c80cf2}, {0x0004c15c93bae41a,0x000c9aeca3b2cc00,0x0001e9ab146fbae5,0x0005c0c71235cf0f,0x0000dfba9353ec28}}, + {{0x000d013f216c980b,0x0008479e0bc188de,0x00097a237c8ac4fb,0x0008e6f29b89c6fb,0x0000697b7814922d}, {0x000c639ddb945b56,0x00078094c3a93142,0x000266c90447b06c,0x0000466dcb364272,0x000033aad0909385}}, + {{0x000936bb57c64779,0x0004594dbcc6a36c,0x00091a67b871f8b6,0x0006f498d0fb62a5,0x0000d40e08251d92}, {0x000eaf6f2d84b5af,0x0008b565b6443111,0x00083188b228993f,0x0001961ccbf5922c,0x000087b30ac2df3e}}, + {{0x0008b317642bca8e,0x000e72800f17b865,0x000bf94451a032d7,0x000252251dcae579,0x0000ba6b8ef34a2e}, {0x0009cadd44856928,0x000e0986e9be5c8b,0x0000db44884bda40,0x000188516d16a42f,0x0000ec80051214d4}}, + {{0x000610798fa7aaac,0x00043073aa4eb2b2,0x000d6b19b41209ee,0x000caf31570359f2,0x0000be6868dbc577}, {0x0004bdc32c04dd3e,0x000defeee397186c,0x00086c0cfa6c35fa,0x000fe1d4a1b312f0,0x00000a5ccc7b9461}}, + {{0x00078aa1536189f8,0x000f3a6df571c322,0x00094560e1126c55,0x0006e08f71a602b1,0x0000b2d7405b24bd}, {0x000939e3738be712,0x0009fa4d97a98481,0x0005ba915b5090b1,0x0008a9f16c65a3f0,0x00001863ad3cae44}}, + {{0x0002679a7aae5d37,0x000c9de5c1c4d24e,0x00005b6297076013,0x000fbabd50f8babb,0x00003c1abe2de66e}, {0x000b422f2488af76,0x0002063ba575efd4,0x000a69457e4105d0,0x00073b1eb60a8b53,0x0000221000929459}}, + {{0x000547877a50ec69,0x00067a37a72cfb25,0x000e18e7abf0392f,0x0000af10a7a19c4b,0x00000d8ea16b5b1e}, {0x000a293ef953f575,0x00056dc5465a7582,0x00051071790a64d0,0x00041f7a79c497e2,0x000060dbb7c68cb6}}, + {{0x00032864b66abfb6,0x0004f90309001d8e,0x00084941ad26f52e,0x000957bee3f64355,0x0000d3b3730b69f5}, {0x000a62f4789dba54,0x000532b5c9b79ff2,0x0008f9a0e91fcb81,0x000cb5b446cb7d6c,0x00008f625c179b7e}}, + {{0x000e8011c6219b80,0x000928ac2f23baba,0x000e20588e7a562d,0x000051e1b4873226,0x00006ee1cad775af}, {0x000ae43faff79f72,0x0002452ee9e0da29,0x0005f4bd0c141a41,0x0004f7fe127f6f19,0x00009c6ab4f272f3}}, + {{0x000147730448112c,0x000124a386567b7c,0x00031501082b51af,0x000cd36bf2028a2f,0x00009a4a0202ea88}, {0x00095d8257e5818e,0x000fd4519b16f63e,0x000a910bfdd8efa0,0x0004a90d8973e00d,0x0000d49d0783c0fe}}, + {{0x000ac5eb7caee1e4,0x000d67f4da57ac3a,0x0006669b91033898,0x000aa002145c0e5c,0x00002daa68901aa2}, {0x000c15c1a1d885a8,0x000074b76817629c,0x0008f8f2825572ec,0x0004900312e4359c,0x0000107f8ce01965}}, + {{0x000f3a36fa6110cc,0x00013b93561f516f,0x00057522b74fb1eb,0x000dc5ac0c904784,0x0000fd321052bb8b}, {0x00084a2cc80ad571,0x000576a9b6372d68,0x000f4e8cd7c27fc3,0x0002f02461baedad,0x0000d56251a71724}}, + {{0x000d209c955bef4d,0x000136adb0470b80,0x000c74feedf02cad,0x000a4420d7cb915e,0x00002503375e111b}, {0x000755edf53cb366,0x0001d368551b9671,0x000a025a454dcb61,0x00044506d69aacc8,0x0000be946c7477ef}}, + {{0x00046d1a995e0941,0x0006d51e04d87199,0x0001e311365e848f,0x000503d62f33006a,0x0000541c7c1601de}, {0x000c9faf4acfade6,0x0006e4cd0b714daa,0x00051cd770e58589,0x00016cf44fd8690a,0x00000fc20ed60310}}, + {{0x00004eca42768678,0x000bb4f3499358b4,0x00036e5bd46f6c3c,0x000b46c77ca007c6,0x0000018f5e5fc458}, {0x0002270e47b668f5,0x000d9e14f203a120,0x000ff9b4dcef48cc,0x000ddcd3f98bae62,0x00005acc0361589e}}, + {{0x00012af64db44442,0x00049ecdd4803fe7,0x00030978a19e9d63,0x000733c08bc047a9,0x0000dbf24ecc1280}, {0x000e38c2cd706b27,0x000ac59017b93c0a,0x000e0f5ae5b012a5,0x000fa2c943c38c72,0x000086167eac7176}}, + {{0x000897d594881dc3,0x00089fb820c1e5f9,0x0005018de6b5efad,0x0006ce82179093d5,0x00009ad7d323bac5}, {0x00022e02cfc0e816,0x000196d89daab551,0x00064fa09117c466,0x000ddcd62d01e1cb,0x0000a309b4e9e9c4}}, + {{0x0009fb7abea49b1e,0x000c30e2c6c5fa97,0x000afde7ab4b1d27,0x000357dd61c2c423,0x0000b6614f97786d}, {0x000816b7f6f7459c,0x000e49360e7b4a5d,0x00009914ce431a44,0x0003d7cc27a032c3,0x0000ea5d68b8aede}}, + {{0x000f6653a0a3f957,0x00060ceba27b3668,0x000728fe98936941,0x00056219981fade4,0x0000102c8a0fa093}, {0x000310e235d21c8d,0x0000eefb7f7bbb80,0x000958a67505e55d,0x000feed0a9081112,0x000067e106b1d851}}, + {{0x00011a9431dd80e8,0x0009f3306cd9b840,0x000b3b730eb7c7cc,0x0003d2a0fadd29d1,0x00003858b5c7e37b}, {0x000d193b6251d5c7,0x0002a352d952bf4c,0x000fbc0511cca1fd,0x000636566157a490,0x0000990a638f9b98}}, +}, +{/* digit=12 [{1,2,3,..,}]*([2^84]*G) */ + {{0x000692a87dec0e16,0x000d97b39d00e5aa,0x000cfa0b5010ded8,0x000a281b1b80c854,0x00006beb87700f8e}, {0x000f5313476cd0e8,0x0005308d394950d7,0x000479fc6a63d0e6,0x0007419a09eea953,0x00002ae98927499e}}, + {{0x000b9105ca7d8669,0x0001aadb3b34ab58,0x000eac0bc582967e,0x000af4f9ae4447cc,0x000019c667d0bf56}, {0x00017b160f5dcd7b,0x000f2dcaadbc9aec,0x0003467f5ec697b9,0x00032e5b98f34146,0x0000187f1f859671}}, + {{0x0007a1d214aeb181,0x000c641432f790fe,0x00091a0c41506af3,0x000bc3ab5565f9e5,0x00000d41a77c44f1}, {0x00065e4a84bde96b,0x0008420a6a1ca09d,0x0007f9ce742f060d,0x00039eb52a3bfdf2,0x00006bdb65ceb3d7}}, + {{0x000dcb6ec7fae9f1,0x0004dfb66e5aeb5d,0x000445d52995f271,0x000620cee95d8e69,0x0000b6c2d4619e27}, {0x0001c318129d7161,0x0000f958c1aa3262,0x000f4af63b03909f,0x000df67c468ef91a,0x000062c42a00ba5c}}, + {{0x0002343753b9371c,0x00099f1f9cd72f68,0x00045db9629cab45,0x000998971623abb2,0x0000507db09ffd79}, {0x000f652af036c326,0x0007a5018e5c4e2e,0x0008be35086f0cc7,0x000327610a73d4ab,0x0000519b397de826}}, + {{0x0005eef9c053df72,0x00079300ea6fe8cb,0x00049cffb8de25b3,0x0009bbbb03fa92c8,0x000042e43a808416}, {0x00051f4dd6f958ec,0x000f34445a8de4fa,0x0000d89496925a77,0x00039026e72a50e9,0x000066648e3eb1f6}}, + {{0x0001957173e460c5,0x0004e0704590b2ab,0x0001c71621bbbce7,0x00065d70a90dbddb,0x000005e399e65cdd}, {0x0004dcb57797ab7b,0x0009ba2ca8e86843,0x0003336c160ad35b,0x0000149bfdb1e0de,0x0000bef99ec88b39}}, + {{0x00096f31711ebec8,0x000f4e98fdc46c3b,0x000b4411f2da40f1,0x000bb6399774d357,0x00007c8bdf495b65}, {0x00089e3c2eef12d5,0x000aec7471f3da3a,0x00012c594de95bb9,0x00056b100f225bd8,0x00004907c5d7b75a}}, + {{0x000c5f08db60e357,0x00068a833319a93c,0x0001683c9743e3cd,0x00007e0dad5c41f8,0x00000c1e7da0c341}, {0x0004a39a6be09070,0x000586d0b7d30edc,0x0002bfa6036d4703,0x0004148c76da0327,0x0000b4a07ea0f08a}}, + {{0x0004d2945c1dd539,0x0007931debb5699e,0x0007f00e0cadc589,0x000a0e4f49fcc7a7,0x00003057bc0373e5}, {0x0007ecd027a4cd18,0x00034614011a2f8b,0x000677c68114734b,0x000f4f67a01db767,0x00009d9be5efe273}}, + {{0x000cb2e089808ef0,0x000dd59e4107d225,0x00011b9c9f1f7a27,0x00015953afc76182,0x0000361bc67e6819}, {0x0005d0b7f071426a,0x0000470725672a86,0x0006bcabd6a3c181,0x0001bb9e3bca1e0d,0x00001b02bc1e0859}}, + {{0x000ee5931fba2393,0x000368bd91d1e0de,0x0001a3c1df47424d,0x00033adf8886f407,0x0000f7d41e8d8192}, {0x00023c2cf6eb9980,0x000f609a287f7086,0x000c9076286bb49a,0x00054b942bb24963,0x0000ef6eea555a96}}, + {{0x0002d7236f5defe7,0x000be6f991765f6d,0x0008ce0c7fa9922d,0x00055dfc8c5ecef7,0x0000b44589e2e09b}, {0x0003bca9ea837700,0x000f2ab71547e11b,0x0001ddcc0d7fa2c7,0x0007072a3dd6fa2a,0x00009acb4305a7b7}}, + {{0x0004a2e649d4e574,0x000fd917526e4add,0x000b44ac4cd53a2a,0x00031d8526233020,0x0000028746afaa2c}, {0x000839064291d4c7,0x00017e5ad9095131,0x000185681bf48f15,0x0004425ce57f597b,0x0000c3ac1b0b854d}}, + {{0x0007dc3c093c171c,0x000364f42b656558,0x0005996cbae7acb2,0x00091a9a338adb95,0x00008e656762051f}, {0x0001fba28b8d0b1c,0x0006f6c10a906671,0x000232a8015d7413,0x000d23b0cdd7eb3a,0x00009e2f0802191e}}, + {{0x0001db6f79588c00,0x0009b55768cca80d,0x00054438afa52fc6,0x000a4f0b4df1ae7f,0x0000cadd1a7f9b46}, {0x000a6b31803dd6fc,0x000495eaae35b40e,0x0002e4e16488e4fa,0x000c97df047d5538,0x00009b5b7e0ef6e0}}, + {{0x000d2d3957626499,0x000737aea3f66b1b,0x000c6f896a9604ee,0x000ad0a646ff276d,0x0000bf0e7f5b860b}, {0x000c8217cb44b924,0x00036ea9c1822d92,0x00054a5fda2f5ce6,0x000da690a2afb191,0x000082e474cd5801}}, + {{0x00072d0b611c24be,0x000480a8f351c199,0x000cf64211d468e6,0x0004910b7580697b,0x0000c9dd0ef68fbc}, {0x000d2bf956c2e32a,0x00043cddf94e5b59,0x000ee766573dc686,0x0006c45d5e2321bc,0x00007b4f8effe9a0}}, + {{0x00018dd7280f8553,0x00005baec688fba9,0x000400f42bbaac26,0x0006e473b3f00f33,0x0000d2dba2996f2e}, {0x0001a94985093755,0x000f7ea423ccb6f7,0x00007e6fb8f33031,0x00054bb09b8dd048,0x0000163cfe5acdb9}}, + {{0x0008f17cf41c6e88,0x0009837b925c03cc,0x000d2427cf1f03c2,0x0008e4439c19cc66,0x000023d24bafb6c1}, {0x0009013901f0b4f7,0x000188941c2e32ef,0x00028092e684360f,0x00032e9ebaff522c,0x0000891e4e3956c9}}, + {{0x0004319ac445e3d2,0x00076ea743815126,0x000e9c50a553432e,0x0008c7c6eeaa6967,0x00007ced28482e62}, {0x000d3757a4afa571,0x0003d484c1503f96,0x000bd9923de0a14c,0x000422264a24eb38,0x0000df18da0f5177}}, + {{0x0008f82d8d38a9b9,0x000057de1391174e,0x000c175dd2e97c60,0x00003535709850a1,0x000069041a0c2ae5}, {0x000533b76a2086b3,0x000ba7c2e8fecbfd,0x0009dfb67d6bba71,0x0005d982d58ee609,0x0000a8b342d364a8}}, + {{0x0007649522f9be32,0x000bbf1f49a83bc0,0x00054ec42690c075,0x000dc760e1aee838,0x0000a7dbf4437689}, {0x000fc0e3faf40783,0x000eaf11862cc004,0x000a1b7b3b2f02e9,0x000c80c10a5e0fa0,0x00000aca623b936e}}, + {{0x000bf0502f40d9ab,0x00077c318a4df83c,0x0009c26744681c46,0x00092de85756180e,0x0000e79d046c8470}, {0x000480a78bd01e0c,0x0003b2a51db9af1e,0x000afbab66dd359e,0x000198a2ce3821e3,0x00005cee5b6d7733}}, + {{0x00030d46ffd9fbbc,0x000876c610b7e08b,0x000e262cf6e5bc69,0x0004c13343cff29c,0x0000a2e4e3628b91}, {0x00064c016de36c5e,0x000c62e2b829011d,0x00085aaf8e0b10fd,0x000e969894298166,0x00007511709030ed}}, + {{0x000d8fc3b922bf8a,0x000fac29b133671e,0x0006e99c4e4d8c09,0x000eb9e7eb12393b,0x0000ff3974d2793b}, {0x00094052c18df9b0,0x0003910071390374,0x0007a0b95c5c3a29,0x00096b6a77234fe3,0x00002c29a21b661c}}, + {{0x000f1d6141ecf611,0x000e2bb22f53c3aa,0x000d513579195509,0x000d601959740422,0x0000b083822637be}, {0x0006e35e07289f09,0x000bddd86effcd7d,0x0000f9cfa1f94c48,0x00097d38bb1f82eb,0x0000ee0b7e6ab2eb}}, + {{0x000fe2e34d74e31b,0x000f8bf79ab65a52,0x000feeb8fa352c30,0x000304e7ff6c5aab,0x0000fbe8ff0a5c97}, {0x0001ce6a79046089,0x000a34fca249d608,0x000e5e2001f812f3,0x000ee80b24bc9ab9,0x00001022c67c8012}}, + {{0x0009c5d30a713a1e,0x000fa4ef0f93e83d,0x000fbf9284876e3e,0x0002a3e9777029c1,0x0000f7a6bb49ce7d}, {0x0007228dfa2a659d,0x00080877a48fb806,0x0005d0f3fd5cd339,0x000c2aeea4fd8f02,0x000067d2e35feae7}}, + {{0x000e7d7cc5f43941,0x000c3536e142184d,0x0004aa60ab5551b5,0x0001d51e89b212d3,0x00004a96feb05005}, {0x000ef740d12bb0b3,0x000030b9677e4e21,0x000f7731dc522f02,0x000d315b12e4672d,0x00009f80382ab326}}, + {{0x000630c39024a940,0x000897319452dfb8,0x000a3867caacb96a,0x000fcad68a3961ed,0x0000c58e2b077c4f}, {0x0005d634da919fac,0x000a315e22893d54,0x0008bab10ef79b69,0x000c3694bc3d3d80,0x00008ab300805f82}}, + {{0x00038b67c4a658ad,0x000870e72182c127,0x00098e44fb3c4763,0x00085e6b77be4687,0x0000c047df2e7a7f}, {0x000d4c55e59d92d3,0x0005b8e64d8d2439,0x000ca9b16cedca47,0x000dfe7724cd0d87,0x00005e4fd59d5540}}, + {{0x000ff18e4bcf6b1a,0x0004895018faf8c1,0x00063c949856d628,0x000408a33f665c32,0x00006a76dd741f21}, {0x0002334cc7b4f79f,0x000116720e4a17d3,0x000d9bed5a1d0312,0x0005d0bdb6661d81,0x00000d6fb0301db1}}, + {{0x0001ad51fb747d2c,0x00087033762b7fd1,0x000efaf5aab50f95,0x000bbe6a7e711bfb,0x00007393278ffef2}, {0x000a2440df6f9be3,0x000b41efd215e29f,0x0003d6fd99092757,0x00078bbe60e3114f,0x000038542d43acfb}}, + {{0x0003f0838961a0f4,0x000e586987ca44a2,0x000863cc61426ead,0x000b78f6e6ee2e4a,0x00008059420a28b8}, {0x0003ad87396e1dea,0x000798c5aad13030,0x0008f50665c8bdc4,0x000bbc9e40e11f5c,0x0000bd6e7692d246}}, + {{0x00040bb23330a011,0x0004b34eafa068aa,0x000e02c21d23f5ee,0x000d062bbee3155d,0x00008dd4397e1d8d}, {0x000939a122d7b44f,0x0009b33870d63ba1,0x0004fe3f8e6d3b40,0x000cbe9e620f701c,0x00006bba1a6c3a50}}, + {{0x000bde5cfc0aee0c,0x0006008c50bd4a78,0x00063c9b2847edc4,0x000acafaa2439cad,0x0000eb4a728d0fc2}, {0x000e40e26da033d0,0x000d03e02683a419,0x000ccf7256cc3889,0x0002081cd28559fd,0x0000fd7e0f18d13d}}, + {{0x000733b1f0df9d48,0x000322b5e4f301b9,0x000304fd48cc2c5f,0x000aa6c3053bfa3a,0x0000e87665c8a9f1}, {0x00029ecd73dc965f,0x00044e9023db087f,0x000ce28b415ace45,0x0008493370e3092b,0x00009723443a6b1e}}, + {{0x000662eb72d9f264,0x000eb0e47109beee,0x0003289d0b19396d,0x000e3245b1fa73e1,0x000036cf77e94e58}, {0x00033b3e990ef77c,0x000c5b11fc250ec8,0x000c332ce7373e3e,0x000855fe0eda870f,0x0000ed049714d7ea}}, + {{0x000f7857e977ca05,0x000a8fdd5d2bf85f,0x0005af461b66ee8d,0x00087ca5e3795090,0x000087b9090e66d4}, {0x0008a1b32ba0127e,0x0006341615ac6a19,0x0006ef2f2a7720e0,0x000b3cc23f349999,0x0000f5f64b5270bc}}, + {{0x000a96292b8c5599,0x000fd9740a0fa526,0x000bdc0a50c14aab,0x000ef37d41a9e3a6,0x00007d521072c48a}, {0x000bd303e7c253b2,0x000a27fdedc1cf16,0x0003aab2ecc834b1,0x0000ff5362c6e537,0x000064ed85ee5f59}}, + {{0x000d9c066d41870b,0x00009787ba097a46,0x000d44635a50c20b,0x0008db685e7e51e3,0x00003b3e080e1e2d}, {0x000e558a179e9d94,0x000934a76781bed1,0x00040864f2daa3f7,0x000cb50372baf23a,0x00006900c548fe75}}, + {{0x000171ef76765d05,0x000245c87502b95f,0x0007c99bd4ad726d,0x000fa7dec769da4d,0x0000e2ddd1a136cd}, {0x00017fca93e6dea4,0x000b53771123c221,0x00008a3a2e8a2583,0x0001127e2f6089fa,0x0000809d5edcf0e1}}, + {{0x0004aa3da7a095ed,0x000056f5aadd3b41,0x000e8b84a9049acf,0x0009b2a8d46a4d6b,0x000066b19648732b}, {0x000c2a0de6e95555,0x000865bd87705c2a,0x000d28921cf52d09,0x00036cc5a15fa60f,0x00006ccb81edb275}}, + {{0x0008ab89f4ccbb8c,0x00021b2217290f0d,0x000bed10ced5f44d,0x000b8a8314198800,0x000094348a4dd735}, {0x000e9c429ef8479b,0x0002b14c693f79f3,0x000143a144c13a4e,0x0005c382c9af568e,0x0000c51779a929ac}}, + {{0x00079922774856f7,0x0004fc1bf55f05e1,0x000f19e166e52fb0,0x000b263eda4225e4,0x00000f4728b1f5cc}, {0x00018d1b2947f224,0x0005e81d6fb95d21,0x000f0eabdc827ea1,0x000dcf4412328d8c,0x00005ee9fb243ef9}}, + {{0x0000421bb937d636,0x00056c4b37a68e70,0x000ed7b68df8ff2d,0x000f5944c0d5b25c,0x0000537c1f027308}, {0x0006a263b37f8e84,0x000b9eebc6ce25ce,0x00028d72c170e9a9,0x0004bc9d03795287,0x000045b0e55c5015}}, + {{0x0000e0683a7337bd,0x00042fecf2494b7d,0x000a2b71f1e3416d,0x00026c54840eff66,0x00000d9a50b837cc}, {0x00081506fe28ef7e,0x000543324c7fe219,0x0009b52633cc5ef1,0x000474420f345576,0x00002ade2f2810bf}}, + {{0x00020fa458d36710,0x000c2dc4847b28cd,0x0001941e31549722,0x000ccb6dd01e5559,0x0000e6fbcea27128}, {0x0001e6b3bef0262d,0x000bbf54e103ae1a,0x000c052ecfa8c472,0x0000e8a539c0a872,0x00007b2736a2a349}}, + {{0x000e1f1716843491,0x000e22e19b97143f,0x000980aff36b4722,0x000674cc05922790,0x000075c9c88ae13d}, {0x0005b226e6bfdb1f,0x0001cedb4b46a7de,0x0004a6e445ea5b7b,0x0007e5e5570191d3,0x0000cf60d2f924ff}}, + {{0x000392d677819e1a,0x000e0a5a29e8614a,0x000c85f3f7be74c7,0x0003370b50fece63,0x0000ca2e2a9e6cab}, {0x0000388122a6fe3d,0x0002b82a04a87f70,0x0007aed57db69f70,0x00086eca77935dcf,0x0000f16207d5d91c}}, + {{0x00049ab63ed9998a,0x0004077ddf962fca,0x000344072a3125c4,0x000b5565dd8a8624,0x0000023dda39ec3f}, {0x00041fc0c743032b,0x0000ae438639421b,0x0003c1b074f2120c,0x00071a4b7cae51c8,0x00002370cab7ac21}}, + {{0x000d9626cc820fb6,0x000c585a44bf2eb2,0x0006598f059feee5,0x00005134620fca5b,0x0000b922caede314}, {0x00045ad106bed4e9,0x00054fa1e9abff87,0x000c29487546e71f,0x000530035c1e481e,0x0000509216cdd936}}, + {{0x000306785c9a2dbc,0x0001abe8606fc7ca,0x0004c651dd6ae515,0x000f9549dbcae6e1,0x00009536e245bc32}, {0x00035a934521b032,0x000c678756ffa905,0x000edf03cf39c526,0x000034183172ec8a,0x00000a8075f0fe0c}}, + {{0x0009c62640264225,0x000fd4b9d076f22f,0x000ef29508dd1077,0x00000b444c742a3b,0x00005b9502ed8a2b}, {0x00014b486a098170,0x000c47bb4071a59e,0x000e0592fa39dd3a,0x000f5b55137f663b,0x00007fcafd4c9e63}}, + {{0x00052ee346eb2263,0x0005bc2facb79636,0x0001add267dfab08,0x000c43f73bf2b869,0x00000d7454122b46}, {0x000e73ef2c2d065e,0x000ff42eeac905e8,0x000209d22ff9b89f,0x000a2b4fcbd20597,0x0000b740ffbbe14e}}, + {{0x000f913a8aef5181,0x000beff4cfa2c71f,0x000b360487bfc74b,0x000af10716680cb6,0x000021b2cceaef79}, {0x000c836a01eb3d34,0x000a1f79077bbff3,0x00004bbcf50eb1c6,0x00061d648c32d6a0,0x00007a59316bd64f}}, + {{0x000147f931020167,0x000424d125766068,0x000bc6b9112c5f65,0x000a957fb071a7c9,0x0000c2da0c5de23e}, {0x00045b6d4a1dd5d1,0x00068122b13cf4fd,0x000f57a483e7ad9b,0x00088f242ca118e6,0x0000c2e94a716f82}}, + {{0x0008f075a97d231b,0x00069d83875899e6,0x0008727277c80de9,0x0000160ce0f5d005,0x0000e5d95c2c9c4d}, {0x0005cb19c2492eed,0x0000704d6fb3921d,0x000f988d342192dc,0x000e847c84dcd132,0x0000e26d620717b8}}, + {{0x000dcb6137c7408e,0x000556a266dac466,0x000bebf1b9a38d7b,0x0004e29ef5cb0683,0x00005cdcbbfefd01}, {0x000376df65965a08,0x00026bb3e95e30aa,0x000ee6f2060fe88c,0x00009fb3fd0b6166,0x0000827dcdbbf41f}}, + {{0x0009d240c56c6904,0x000d9db7641dbf8a,0x0006b662b40265da,0x000c9b122b05bf3a,0x000066d1dfef1478}, {0x00069621484469b5,0x0008b2df8f9faa61,0x000b8bf510db6054,0x000ce8737bca023c,0x0000effe34671371}}, + {{0x0005264ff112c32f,0x000c8b971fb2e8f6,0x00075080d8a9c736,0x00059ab4f194707b,0x0000c3f2c5b7839c}, {0x000777e5aeb49c20,0x000dda1addfe1d6c,0x00035affcf3db034,0x0001fdd76fee5a55,0x0000853ac70b9225}}, + {{0x000d5948b2a29d5d,0x00067de00ddb37e3,0x0002c328b28f1f45,0x00073ab083c1b5f4,0x00008ef1d90b493c}, {0x000626041dc61bde,0x000c47ee2f8a96fb,0x000946a5df74e8a9,0x000cfc9c605a802c,0x0000ed48d661839c}}, + {{0x000344f3a29467a3,0x0009951eba6d9894,0x000e5c2f2de81e94,0x0007b3aaea066ba5,0x0000fc8a61438c8c}, {0x000f88f06d0de9fa,0x00049b75ce0a7adf,0x000bc87d5bbc11cf,0x000de1ffbb7accfb,0x00001458e271badf}}, +}, +{/* digit=13 [{1,2,3,..,}]*([2^91]*G) */ + {{0x0003668e039c2560,0x000b7c17fd5d1cb4,0x000aa062b5f26fb8,0x000f04eee426af79,0x000072002d0d78fb}, {0x000a237e84fb7e3e,0x00002c82133d4c9c,0x0007e4181b401d8a,0x000151caa525926d,0x0000943083453dbb}}, + {{0x000da31be24319a2,0x000bc095a8e7f92d,0x00078218503f7d28,0x000dbc852fe84098,0x000076ddafe49c24}, {0x00054961d7a64eb7,0x00090f1dbe4280cd,0x00038d2d5e436088,0x000035bf81a87784,0x0000e4d52a8f5169}}, + {{0x000d5b11d59715df,0x0001e788983e19e3,0x000f1f248c7eaa76,0x000d82f5a730b0ab,0x0000bab8085eae3f}, {0x0000d2153765b2f5,0x0003aa127f3d65e5,0x0007b1b10bdd4e08,0x000fd34cf3c07439,0x00009f8090d01b59}}, + {{0x000fd9d615faa8f2,0x0000768554ed7b15,0x000a448828fa1eb4,0x000f325bb4447e7a,0x0000bb2d0d1229ff}, {0x0002a646caa6d2f2,0x000e02e7351b075e,0x000506c628eb879d,0x0004dc9cd5624e9a,0x000018eaef0c87e2}}, + {{0x000684744ddfa350,0x0005dab3f74737e5,0x000e96cf49ccfc5c,0x000b8f9ac1df3f1e,0x0000c0571a13b480}, {0x000b3d54b3a7b3cd,0x00088dcdbb992fbe,0x000415b3a35c0366,0x000d9982a0f5dcb2,0x000057759b51413e}}, + {{0x00047d83d30a2c5c,0x000e378a81dc1fe6,0x0001a4a9b0857f77,0x0003f451d5a33413,0x00000a94af9e9d39}, {0x0005c0bdaa6ec1a9,0x0002f8d2d7edbc3a,0x000614797ba9fe49,0x0005332b4335b4bb,0x000091c4d6902f83}}, + {{0x0008c28d2f01cb3a,0x0003375db0b15325,0x0007d0db493d6eaa,0x000492a19a2b0de8,0x00001e48f0478fe8}, {0x000faf6c508b23ac,0x000975d53549f747,0x000f9b838f137571,0x000cf4df5e58e2fc,0x00007186cef67fd3}}, + {{0x00068cee978a1d35,0x00032ab92d0477b8,0x000a5b862e3a68b3,0x00041d0102979487,0x0000f0606c38a61d}, {0x000be276f9326f11,0x0004b6fe3c2e2814,0x000df73512f521c1,0x000e4407464d7dac,0x00000f5f9d3877f7}}, + {{0x000616b269fb37d5,0x00042de62de5ce8e,0x000dd4153aaf7380,0x00049b5ba111754f,0x000015759ba8770b}, {0x000ebf8aa423a61a,0x00012d41fb928b09,0x0004c8936592245a,0x00010d7cba8ec19b,0x000087e91e44f367}}, + {{0x0004ce43d34a2e3f,0x000dc43b5d611fd8,0x0009186c7ee3759c,0x000259995bc78c61,0x000019c380abbb97}, {0x00021aade744b1f6,0x000000f8056bc0be,0x0003efe11a7d222b,0x00025314be6157b2,0x0000fab2b4f6cd68}}, + {{0x000ea5f4bf1d7255,0x0001ff6c950fad33,0x00077af069c1d8ee,0x0003e1044ee78aa3,0x00004f489bbe4a11}, {0x000d634992fb7e89,0x000a12a443478f11,0x000020e000169a7a,0x00020a8d49d4af95,0x00005945723708e1}}, + {{0x0003878a4d32282f,0x000c58020ae7b6e3,0x000a9b750e36e029,0x000818f05847fb37,0x0000876812da29e3}, {0x000138ed23a17f08,0x000070b3950e84ad,0x000d67ae06d7b448,0x000af65fa8aef42f,0x0000d3eea24d2333}}, + {{0x0002075b15d5acc9,0x000f2d815bc40d05,0x000a36cf2c6d9c79,0x00006ffdcafd88df,0x000008ccbe2c8aa9}, {0x00022c4ba35afce8,0x00007d6abf0b6387,0x000c335c15a3da8b,0x00099aadce252cc9,0x00004e7f0dee5aa7}}, + {{0x000a522b99a72cb0,0x0007876180162101,0x000f3653e06de6e6,0x00054a5ff8c7cde6,0x0000a821ab5c7a67}, {0x000a52b7cb0b5a2b,0x000c190487907e3f,0x000ce053aa7fb121,0x0009af6a72502006,0x0000490a31fb4e92}}, + {{0x000e47d62dd61ad3,0x000c3be01371e17b,0x000e3cbba781a961,0x0009b9e063bfd3da,0x00005647406af73c}, {0x000957b2736a129c,0x00022d13f256f50e,0x00019fcc5a631370,0x0008b5d436ee653a,0x0000f2bdb2aa7a4c}}, + {{0x0001244c5f95cd80,0x0000f4ab95f4b06b,0x000e5836dda8c8af,0x000ffc1bae59c2b9,0x00007d51e7e3acff}, {0x0005e6ac2ccbcda6,0x000f2528c3e001e1,0x0009fead43bc1923,0x000710e3324577a4,0x00001a1b8848aa7a}}, + {{0x0006e08700230ef6,0x00015d19adf8f9a8,0x0005ad8f20af585a,0x00014c1645f361f5,0x0000e676223a6c36}, {0x000257c4e774d3fe,0x0002cc102d1b23cb,0x000126aa582a3851,0x000ee3bbcddd887b,0x0000716998ccefd3}}, + {{0x000d571fb1675839,0x0008416c8f8a4239,0x000a27519dd011c7,0x000b69971c289569,0x0000ce0a3b862d64}, {0x0007289d5ec67385,0x000a3840ef6b8c97,0x000453419a3b49f9,0x0002d5308c14c99a,0x0000c00295b5cf0a}}, + {{0x00014fb1d4bcc766,0x0001e59a88f15244,0x0000d110fb07691d,0x0009f317f43263f7,0x00004ada5e117abf}, {0x000f94e5b544cf50,0x0005fd2713feafd0,0x0000c74f4b4a13a1,0x000e45b99b7d6e25,0x000097f2f7320324}}, + {{0x00037d8affa8208d,0x000b0c29aafc994b,0x0003a607fc3c31b0,0x0005d56da746517a,0x00008e1b8c2ce695}, {0x0001815c8418682f,0x000e8dc91d97716e,0x000996982541d487,0x00002d58a04669c6,0x000039cab1673a65}}, + {{0x00001a0e68db0554,0x00087a3338d50258,0x0002afa84f356975,0x0002d170c8c0aaee,0x0000f6985d43b656}, {0x0001f15132ed17ab,0x0004104365fe351f,0x000b1f066510ed0b,0x0003dbf3f98138e5,0x0000c9d95d6e2df0}}, + {{0x000cf6e19abd09e2,0x00012ff17edba83c,0x0004a06ce0b4097c,0x0008fd38a5c478d6,0x0000ddcc3fd744a5}, {0x000503d9e8153b8e,0x00019774179bd449,0x000d9120c3324fd0,0x0004dacf5d47c8db,0x0000b86016314fa9}}, + {{0x000bdd1972f07f4b,0x000e227bbceb5817,0x00011e5a6e5579e2,0x000047d6847a1f5f,0x000039ed2562c3cf}, {0x0006417a2f62e55f,0x000e2bcf82a2e107,0x000eb29f96b9ab38,0x000a455bb7c3197a,0x00006d17da407227}}, + {{0x000ddbd0f968c006,0x000ba00c880bab53,0x0009ad24da03da7e,0x0000d01b2396246a,0x000012c040161ec6}, {0x0000493109f5df10,0x000080af755070d1,0x000b9a9b3fbda403,0x00041830b93f95c6,0x0000c74ec71007d9}}, + {{0x00055646edb951fb,0x0007cf22c2829417,0x0008d11965f4a9d7,0x000e7c07870895b3,0x0000c593df45228c}, {0x0005bd46af3641a8,0x000abd9b3dccc78c,0x000e333047802200,0x0007998dc73f328b,0x000047ed87de1ffb}}, + {{0x000974e6d6711921,0x000ace16f60ff85c,0x000c387971e14100,0x000da435cb0d5a95,0x00008923bbaab022}, {0x000e899bbe7e86e1,0x000e116067bfef2b,0x000d5ce3e4a1510e,0x000b90c98c815484,0x0000af777f1092a2}}, + {{0x000b4004ef657241,0x00092c0ca6fe9fbc,0x0000029943e04a4c,0x000cabeb3e2cb555,0x0000f3a93c56363e}, {0x0000efe3923555b8,0x00089e1751ea1fe0,0x000b69357744bedd,0x00018abfb2db596a,0x0000dbd736675e66}}, + {{0x0003099df1ea40e2,0x000b37d61e6499d5,0x0006eb812b3f24a0,0x00040bb088a19859,0x00002c8361b77629}, {0x0001f97f9c0d95c1,0x00027e43cdae66f0,0x0002b15c38846117,0x0005cc01599a7fb7,0x000035a7536520d9}}, + {{0x000f0f75f7ae2f68,0x000d57fa6da22dcd,0x000d441b615fc6e1,0x0006b601ca829ad1,0x00004c10cf884a10}, {0x0006c95a73fbbd0f,0x000a5d8f6ee8a9b2,0x00025a0437f24e0c,0x000dfd58b459371e,0x00008a74fcaf36f3}}, + {{0x0006585c9f842969,0x000aabc278b01ed4,0x0004fcbd07fbaa8f,0x000a5f18e96cd46c,0x000040a120303b60}, {0x000e12055a4aec84,0x00049bd742f034aa,0x0008c68ab550e9a7,0x000ec6394456d722,0x000092f8868e4e25}}, + {{0x00015adb2d8f3984,0x000c1b84c9536829,0x000b917d6f13b51c,0x000ee18da90ab85b,0x0000b6155608ea3d}, {0x0004e850a52c1c82,0x000500b75fc4578b,0x0000bb3c6eab1a69,0x00009440c14f3caa,0x000020f448ad8216}}, + {{0x000ee31b0e63d348,0x000229e54fab4fe7,0x000e7b5a4f460057,0x00083140493334d5,0x0000589fb9286d54}, {0x000f5cc6583553ae,0x000a025649e5aa70,0x0000446520879094,0x000c4eec90450710,0x0000bb0696de2541}}, + {{0x0001fdeb9718710f,0x00080374a9f55a17,0x00039bdc138f1bed,0x0000cdd8c582e1ba,0x0000c457b0b808cc}, {0x0007fd4883841e20,0x0009387253819a18,0x000f843958ec25b3,0x0008972553ed0596,0x000095c76616f6c6}}, + {{0x000c85c4bdc56104,0x0003d79eb301917a,0x00078bdccb2885fe,0x0006991fc655478b,0x0000a9fc894259e4}, {0x000f0cd3ce299af5,0x00035df38b20bb7f,0x0008ddb8f195be9b,0x0001b91a929c87d3,0x00005fcc99d021a5}}, + {{0x0005b4c721a4593f,0x0004868eaac22b69,0x00089f914ed1e9a1,0x0009100b63d71c74,0x000098ba31d68118}, {0x00013739b128eb4e,0x000df448af4a8029,0x000418dd37801214,0x000241fbd2e22b55,0x0000ffb3c0eb3998}}, + {{0x000077cc7bf3827e,0x000a67f8238fdfa6,0x00064d554f2165bc,0x000b981e37cf6885,0x00005f825c4ea81f}, {0x0004f67ffed4d6f5,0x0008650a34b043cc,0x00041faf1bc60957,0x0003b63aa8fcf950,0x0000659f053b5177}}, + {{0x00082c36044d63bf,0x00081cdb0ca0e875,0x000b2bcf6a608940,0x000cfb9c993e0fbf,0x0000c64a71a35985}, {0x000da8083dbedba1,0x00021be67df715c4,0x0003defde804ae11,0x0000d3ca4c9658a2,0x00002002ddd6156e}}, + {{0x000ae895dd21b96d,0x000aff44624de68e,0x000c8897a8b99f28,0x00076d3ae008081e,0x0000d0a93043712f}, {0x00075224e233de42,0x00010b36a8a59623,0x0003993d9192445b,0x000a8f8bf9ff7402,0x00001f37bf44aad4}}, + {{0x0004349f8bd2bbd7,0x0008d868195d340a,0x000fdb6f11d902cd,0x000f1bcd27bbf1e5,0x0000a5ab088824f9}, {0x000ab06f7a09e03c,0x000671f2c123c466,0x0001b66572f8a197,0x000a7c1a355dc704,0x0000b840d134ece2}}, + {{0x000ad9f7db326750,0x000307a06f1bb600,0x0001f609478fea13,0x0007aa5d032269b3,0x00007753ef583ec3}, {0x0005aed9c0bea786,0x00095c3f45240348,0x0007f726d41bb398,0x00081fa940376169,0x0000109beb43f394}}, + {{0x00011ea3b6d1145a,0x0009085826548041,0x000e66562b6271ea,0x000d9bc19615e624,0x0000255494677b6a}, {0x000985e99bfe35f8,0x000ffb51cdf6d9c4,0x0008818329770ccb,0x0006d0fc32701392,0x0000777d45fa86b2}}, + {{0x000da22d847999db,0x000613525d329bbe,0x000a959a103aa33b,0x0002339b7b96d428,0x0000b3786e5e1e5d}, {0x000d3ce6961f247b,0x000e52f93d3faeb5,0x000a7ae4f20aa85a,0x000aa7ecd1ad3dd7,0x0000f6688f1281ad}}, + {{0x0000e867469ceadb,0x0003809fca48b1b4,0x00054bbc71904c52,0x000fa1eb7312af4b,0x0000e24bf90093af}, {0x0000790bd98764be,0x0006c26e299ebe5e,0x0008fe4c7a0f45f1,0x0003e56af0d2c26b,0x0000f170db26ae8a}}, + {{0x00061a029e0ccc17,0x000df0ad36ca0e8d,0x000173822cd53e87,0x000e54c28c6623c8,0x0000ee1767e1496b}, {0x0003259648945af4,0x000ce5c8009c89f1,0x00061ab8c9e45a5f,0x0003856f2febd91f,0x00003f6bc86ca275}}, + {{0x0002348f2142e791,0x0009b6e6238a8779,0x000839d9b17d8925,0x000bdc6536d2f64a,0x0000f428fce86a1f}, {0x00096010db06dfe5,0x000100a3a3cc1c10,0x00030f41bbfc16bc,0x000ccea9cbd9ec9b,0x0000b5da0d650138}}, + {{0x0000a4856ef96a74,0x0008582bf842ec1d,0x0003f700db47eb84,0x0001e026deae32ec,0x0000e43c42cea118}, {0x0002a31d1a4aa2a8,0x00084004f3cea1d7,0x000fe8a7a440d466,0x0003648d6a2d3b45,0x000020e52e37b128}}, + {{0x0005fcf25e51b09f,0x000e3023d15929ac,0x000ebf90e180cd2b,0x000180b9892171a1,0x000097c4c886c132}, {0x000c724c03dbb7ea,0x0004618cbbe49f1d,0x00067d153ae04376,0x000aeb5b0b2a3607,0x00008e2f4d6c49cb}}, + {{0x0005247d95ea1682,0x000a0970764a172a,0x0009781691758fad,0x00001b8c803a511d,0x000099cfe2efe77e}, {0x0001e17b0a98927c,0x000060014495652a,0x00075b56a2e26e1d,0x000f94bae0af9f71,0x00002e22a81964b9}}, + {{0x000f9fbd90a060ab,0x000b0af380854d0f,0x000776bcf496a27d,0x00009d82305401da,0x00008cdcef7225f2}, {0x0000f37436a0bbaa,0x0007d686004961ba,0x0003542cf263fa10,0x000537f2beb98eda,0x00002d4d14b75849}}, + {{0x0009d6812e9a1bcd,0x000b8f6e3268989b,0x000ace63861d9075,0x0003fe652c6aa999,0x0000e4e4a56620f4}, {0x000144ad673c0175,0x000e1f6e05eae5e4,0x000d1bd56667417a,0x000711113416aedc,0x0000eb36201d6693}}, + {{0x000c5043a1aa9145,0x000926dc59752d7b,0x000c8125c175a129,0x0008759900e0f23f,0x000069ef68c61198}, {0x000db6363a113b4a,0x0005f88357669012,0x000412deae3bd3f5,0x000e5c05c94a5276,0x0000d9e2a0a4a735}}, + {{0x000984c508b65e9e,0x00008df1a0d1405a,0x000ba80dabde4a1d,0x000d2d3a9433a1df,0x00009192ffa7440a}, {0x00096965099fe925,0x000bbb27a54a9f64,0x00090da6125ddb65,0x000819c78279ddc5,0x0000479a99a4bde6}}, + {{0x0004e05013fe1620,0x0002632d471bd0e8,0x0000e089fbe11dc9,0x000025df0b0c45fc,0x00004fb15b04c144}, {0x0005fc213c999279,0x000fade2eb35a61d,0x000dacbb4a033e9d,0x00049d68185d5cb8,0x0000a88e26616445}}, + {{0x000af6254671ff6c,0x000a9fa58603f717,0x0007773c04bd4241,0x0007e846fba40be6,0x00001d933d32a284}, {0x000acf3689e2c70c,0x000686bafd31f4f5,0x00073f6e592aab0e,0x000933b98d76aa34,0x0000c6641dc53141}}, + {{0x0007757d31e535ec,0x0005c7c2ee11cae2,0x000029ffa04cc43b,0x000a2bcd1f96752e,0x00002150673a4cc7}, {0x000c1e08d68b0139,0x000f5df298f33b03,0x000804464a9d6816,0x0001248bfbb529a2,0x00005a52faeedb22}}, + {{0x00021600e1cb64eb,0x0005ce7fc9fe55b3,0x000b0fb93004828f,0x00091f63394b821b,0x00006293a2de5f1a}, {0x000ef21d145d2d9a,0x00031b8fa603de35,0x000cf252dbe6225b,0x0008c160fc8f6b32,0x000028e52e6b17cf}}, + {{0x000c89b4c371e6da,0x000496ef0f289d1d,0x000292f81cebe067,0x000082bde05d09a4,0x00008303593d53e3}, {0x0005b0a7e37a9bb0,0x000e2b8faec3a171,0x000c9b1028c56f61,0x0001f05250743133,0x0000130cefca4443}}, + {{0x0009fa0bd865cfbc,0x0007fc5f1dd75603,0x000be72244b03e57,0x0008f580edf2e4ba,0x0000752496dfa198}, {0x0002d3b564beb6b0,0x000039a1c608d157,0x000f601260db1d11,0x000f33568d193416,0x00005ae9668f354a}}, + {{0x0006d37c92544f2b,0x0002f35837d519de,0x000514ececc08435,0x0000661bb6869c1a,0x0000633e728de1d1}, {0x000d69f936c581cb,0x000dc439c4f9f15d,0x000448a5b96e7b8c,0x000bbaae676f482e,0x00002ca7d5cad916}}, + {{0x0002541f50240258,0x000964c2d937d55a,0x00062189f47bc576,0x0006f8fd31b92a03,0x00003f3086f6f781}, {0x0006d94b587579ab,0x000780e76c5ff9f4,0x00000ffcfec2d22d,0x000c2b77d57461b0,0x0000b7e65f9e64ff}}, + {{0x00094776652a220f,0x0008e696c9817c7c,0x000effff361618f8,0x0001626021701d89,0x00002c8ff8f6c314}, {0x00013ad8efb4d3e2,0x000fae176d952da4,0x00067d51c937b5ad,0x000ac902867d342a,0x000062b9b1038eb3}}, + {{0x0004fe4c43ff28b8,0x0006ea664e7a4e31,0x000a565c27647662,0x000830be90e40bb7,0x0000588993b41acf}, {0x00001d68f938829a,0x000d9edd7d4cd7b5,0x000cd34c7996627e,0x000e8c97d44a6290,0x0000832749a93833}}, + {{0x000917d4bf503533,0x000b256765fb2e18,0x000d5ab6685dd726,0x0005fe24fe65d693,0x0000ddbacedc15c2}, {0x000d9a412f22e85f,0x00067d06f6bca799,0x000ca1637e2a2486,0x00030a04f1ee5643,0x0000da2828c51ece}}, + {{0x0001a3ea2dee7a63,0x000c434b2284758c,0x000aba6addcde2f3,0x0000a77ba445d24e,0x00005aaf668a6cee}, {0x00004a9e5aa049a6,0x000d31103e847e0b,0x000afecc3e74083a,0x000f7a5eb183ce40,0x0000b89dea04a043}}, +}, +{/* digit=14 [{1,2,3,..,}]*([2^98]*G) */ + {{0x0009d23fe67ba665,0x000043cf2f340e29,0x000fcf9139145076,0x000ddaa45b5ea997,0x0000be00843dbd7d}, {0x0003e05d53ff04d3,0x00032de91ef7358c,0x0009ec1a0bf7ccdc,0x0009977d684dbfb6,0x000067e7cf2b01fd}}, + {{0x000f3b7b0dc85957,0x00082f1d9f2e0ca1,0x000dd82a727de460,0x000447aaf3bf39ba,0x00009356a79d5862}, {0x0002345f5f9a0529,0x0008839a42f9c060,0x0004d40fc1a8b0f8,0x000368253eee4284,0x00003b0bfe5de5b6}}, + {{0x000dd02c024789cf,0x000951b57bfc5434,0x0003398df90dca9e,0x0004ba9aa898e224,0x0000607c835794a9}, {0x000be97c2c99b76f,0x000628c29302bb07,0x00003a88c6576ba6,0x0001054d79efcce7,0x0000259ced8a6a0d}}, + {{0x0003a5dc8de610b8,0x000ae7e223ce0f89,0x000ad6dc5e8c515f,0x00028ef774bfa64e,0x00009d20f96125c7}, {0x0000966098583ce0,0x000493f2a7d77a1e,0x000304d4aa2eedb9,0x00082d1b2820974c,0x0000842e3dac0772}}, + {{0x00072a33b9e2d7b5,0x0007748218ffe4d9,0x000149d917cc60b2,0x000ecc3fc7083884,0x0000c04346f7f461}, {0x000fdf2614650a98,0x000741f666acebe9,0x000babc835e35b53,0x00093de45613d188,0x00008cace3b45e1c}}, + {{0x000a3753de92e23f,0x00076fbbb6e3209c,0x000b1487eccb03cc,0x00041edcb90f03d7,0x0000a9c2a39b7109}, {0x00038236724ceedd,0x0007492d0323756c,0x0005e038e3a90225,0x000590e150e519ea,0x0000cba286697427}}, + {{0x000237f788907328,0x0008d3fcb4d9e549,0x0003480d6c443bef,0x0001861884d8a6eb,0x0000a35b6a1b048b}, {0x000471665e9a90a2,0x000d453006c0b4e4,0x000e9ae3b45bf380,0x000b716f3f820d4f,0x000044a35a0b79a3}}, + {{0x0000e9d74cd06ff8,0x000f2ca3eeaca101,0x00063aa2b9c17c7d,0x0004fef4c86cd380,0x0000595c4b3f3461}, {0x00000ca990f62ccd,0x0002fa0c3be5a3de,0x0008ce9f5d9bed21,0x000443a886078adf,0x0000db27ce42cd44}}, + {{0x0004a6658926ddd8,0x0009108015b8ed37,0x0001f7ab8138b2d4,0x000b7a086c6579de,0x000088b9aa143020}, {0x000034e3a96e3551,0x0008e30fbe9ad3ec,0x00021367aba65b0b,0x00046df64c8e50ff,0x0000f508ea41b04b}}, + {{0x0001a49747c866c7,0x000d9518a0629856,0x000dc3608bbb1e5f,0x000026b0ff4e8bec,0x0000f55cded90184}, {0x000ec95f38c85f0f,0x000e9bc3b8c38d73,0x00012b66f5b589fd,0x000e00ce95dd980f,0x00005bd1a09fe338}}, + {{0x0003ae55e915918c,0x0008c6f8a46b6516,0x000ebf99c6158d6d,0x0007eec466b538ee,0x0000a8761f77ca47}, {0x00049c29ebbc601e,0x000100c3ae2faf34,0x000e63752ef3b0f4,0x000a50ca6c577d5d,0x0000916660244682}}, + {{0x00097befc15aa1ee,0x0007d54b07455a30,0x0009a5f1240d1254,0x000ee57bad470651,0x0000d03f7188439d}, {0x000bb6c4a02c4997,0x000d5ffe71d20794,0x0003adcaff725083,0x00030fbcad75190f,0x0000f68ea1cb3729}}, + {{0x000c8c7b7ffd977f,0x000490761a22e747,0x0003ffb83ec104c3,0x000db69395ebaf5a,0x0000b3261f5d4b63}, {0x0004960d883e5448,0x00000cc2eeb85354,0x000d65f9913520d7,0x00095a88f6337bd3,0x00003997db2f81cf}}, + {{0x000f1060dbd2c016,0x000abf9ce934ce6f,0x0009939214f8eea6,0x000fc6f46f7c4b0e,0x0000236a324be753}, {0x0001f84a16022e9a,0x0007a3d1dbb265a4,0x0004cef9c0c18d87,0x000c73d3c556402d,0x0000042810910444}}, + {{0x000f15e9afdfb3cb,0x0002abdfb6df68e4,0x000823d9749a5614,0x000c29f9bc1bd45f,0x0000ceb59719a111}, {0x000455fb269bbc4a,0x000e49bc5d62366b,0x00018b0867cd85e1,0x000fb92743c41c4f,0x00004b4099135294}}, + {{0x000581d26ee83821,0x0005259d638e9c7c,0x00028ae3dcf17dcc,0x000047de8273abb7,0x0000d1129270821f}, {0x000847750491a746,0x00019de0dfb91149,0x000a435ab687fa76,0x000e3ecc2580227e,0x0000b8bdb94f1ce7}}, + {{0x0005dc93bf834aa0,0x00094f6c7e4b4c5b,0x00036bcad0437181,0x000f8dc284e00a37,0x0000d88111821ae8}, {0x0000f82f48c8e33c,0x0004e1bf40dbf9cf,0x0002733e5a11fd07,0x000bd71ceab0dedc,0x0000560a8b64e986}}, + {{0x0001fe23929d0979,0x000002f188f148dd,0x0006fcdac3885b29,0x00046b7f2ae613da,0x0000054303f4662a}, {0x0001e440738042ae,0x0006ddaf6449b687,0x000c9df1b98e6a97,0x0008f8f8bc0650d1,0x0000f3d645216e09}}, + {{0x000ae82b6d72d285,0x0001a5d8408003fb,0x0008efc1c77ca9db,0x000b4a3a112cffa5,0x000018d761d1564c}, {0x000740ef0d1b5ce8,0x000c69eb178569b5,0x000f53382717039c,0x00095bbfe29f9022,0x0000e54ba56ebc7c}}, + {{0x0006d8af7f91d0f2,0x0001882a57289c80,0x000d767543b61b0f,0x0004c62640032d94,0x000073eb5de67d83}, {0x000abf77b4e4d538,0x000f5e4017772988,0x0005071b3b7ce66b,0x000a981fba6b3271,0x00002413c252d3a1}}, + {{0x000c8c4e0e8ad934,0x000e1fab868d5b7f,0x0003946f3b5679ae,0x00050a71f9d2fa2b,0x000058897dc9685b}, {0x000c93089d0caf3f,0x000e88642e921e98,0x000bdaf1839564c5,0x0002e52b77729a0d,0x00009170723479e8}}, + {{0x0000317e4515fa57,0x00048b0c790f680c,0x0002e0765f85cff8,0x000b3257a82aab6d,0x0000446bca9a5c82}, {0x00007aa6d63184f9,0x0007962803a65de6,0x000be80357c1a46a,0x0001f84218313dae,0x00002113ffe573c5}}, + {{0x000e08312e7e46ca,0x0009b6126bd54b38,0x000c07e0469d0a37,0x0002675b3f324b73,0x00000c22f682fda7}, {0x00000514d2c7d8fb,0x00031be2cae58f2c,0x000f0f277bc45ced,0x000a9831c6cf07a8,0x0000c392312ceb99}}, + {{0x0007b7e3cc8ac855,0x00078d02753b7553,0x00037df2f8d725f5,0x00031dad05ff64b7,0x00005fe871346d25}, {0x00004a96ab6b01c8,0x0008fcd9372457ce,0x00086699b69a02a8,0x000231cf82ac35cf,0x0000242d3ae1cb4b}}, + {{0x0000f65d62105e5f,0x00093d29be61713d,0x000fbef09bb222bf,0x00082f02f9a79e6c,0x0000c24d8d4c5d67}, {0x0007085d41299673,0x000cac3c2a435db7,0x000d8d9a3db81c3c,0x0000266d655fc005,0x0000f5d057a84298}}, + {{0x000f56d88c546946,0x00053b09573e1157,0x000adffd1b26baba,0x000382ccab03b022,0x00000a412c93d69f}, {0x000e98b54b25039c,0x0002a87e714ded76,0x00000b594d4ee67d,0x00009ac77396487b,0x0000e41977689ef7}}, + {{0x0006f851c203a40e,0x00060afd8f9140f7,0x000578dd230d352d,0x000f3ccf196d3d95,0x0000a4bb3d857cc3}, {0x000bd03b98e782b8,0x000f8624920d42a5,0x00056fcc8ac958c3,0x000e5e3838134cfc,0x00006ec4cd009572}}, + {{0x00035269be47be0e,0x0007eb28fea169c4,0x0006c67e5323b7dd,0x000e461a5538ba3a,0x0000f921d70fd378}, {0x00061fc3c4b880ea,0x000df8940a67f929,0x000f0ff393f6f914,0x000f9c0990eb0afe,0x00006c2921090eef}}, + {{0x000416651b8d9a36,0x0008affb0db1ca80,0x00082e7ce42531bc,0x00074112ce4718aa,0x0000e1999143f574}, {0x000b13dd5d369463,0x0005c68f0194d5f1,0x00010d2308255dc6,0x000988ac9df4cd87,0x0000453c20f438c1}}, + {{0x0008dc089a6ef014,0x00005857df859af9,0x0001ad9244dbcc3f,0x000045f48056015c,0x00000448da610493}, {0x000926d4ee343e2f,0x000ca0e8a301f629,0x000815b3f6343f1b,0x0006faffc9349140,0x0000882a424ce8f6}}, + {{0x000d5f4e7db9f57e,0x00095c384c273a12,0x000c660b17dfba38,0x00021b9a904bfd6f,0x0000b6c5db40773b}, {0x000ee661cdfe0491,0x000e34540f29c350,0x000ec6aad9baac0c,0x000baaac57b6aba5,0x000067ce8c31a7c1}}, + {{0x00003a553fb2b560,0x00074e057f78b23a,0x000e490d96ce141e,0x000e75796525c389,0x0000bc95725a31a7}, {0x00067911220fd06a,0x000ba08b0bd61ec5,0x000ebeba9716e3a3,0x00066f91cd6bf7e8,0x00007326ca75ee6b}}, + {{0x000851ccd090c436,0x0003912c39883d9f,0x0004b7be4561e8f1,0x00037af0490b6a90,0x00001690ce164107}, {0x0009a370f009052d,0x00002026092e299e,0x000fcdc0f258758f,0x000cd1cfa255f3fd,0x0000bc9fb2090e1b}}, + {{0x000dd6e246518404,0x000465c59abc35f9,0x000ca4938dca45a8,0x000f28d03d396fec,0x0000532da0af97b3}, {0x0005ea51999a6bf9,0x0009ce6bf2eec413,0x0005be0933aa9505,0x00052e677cef063f,0x00007d1a0f939431}}, + {{0x000ebba2e1c21dd4,0x000bec6797c42cb0,0x00000101ff41b29f,0x000a8986e17321b3,0x0000422b0ea10d79}, {0x000901c92f1bfc4c,0x000f21e10ed949e4,0x0002926b806ab1f8,0x000ec1c4d35577db,0x0000a349d39f56e8}}, + {{0x0003d32343bf1a9e,0x000757d1a6b170b6,0x0006865b48fd3bd2,0x000fa12454879c31,0x0000e959ff7a458e}, {0x000dcf89706dc3f5,0x0001c64e4b2e0461,0x0008843c8737db0e,0x0006f5b92626802f,0x00004498bbcc745e}}, + {{0x00073faa29e24afb,0x0003c0aa87a13594,0x000573acefcc3c45,0x0009654d2c4bf500,0x000065b514ed8dd1}, {0x000e7cf2193e3934,0x0001b5444d97e46a,0x000ff38ed60e9a4e,0x000f02a7594e9600,0x00003d84d2f4a0e0}}, + {{0x000b141ee398a212,0x000ec3bcc5be8b6d,0x0003460eab88a56a,0x00019aea1aa52f37,0x00000da1a56360bb}, {0x000999d65bf0384d,0x00038d5a180efb54,0x000737b0471a14d2,0x000e91ec44db7b21,0x000084fcb18d1dd8}}, + {{0x000937bfa44b4794,0x00091c98fd4f80de,0x000f087275350549,0x000f52dedb12ab28,0x0000c58b582e5f3e}, {0x00036d88327f246f,0x00095d7df320bfb2,0x0006024f2c3a3bfa,0x000432fcd96c59b9,0x0000c293a546f4e0}}, + {{0x000352b5acf6e10e,0x000ccfe652c35341,0x000577a7fc50343f,0x00023c6af3792d18,0x00001a4c6188f168}, {0x000d0cd33425d0a3,0x000d6b7bc47f9b26,0x0006bb20b306399e,0x000054fa792f3370,0x00001219614c8111}}, + {{0x000c06487f5d28b0,0x0001962277fd864e,0x0006aed5f11392d9,0x0009d9b5aa7942bb,0x000080094dc47e79}, {0x000588c208ba19bd,0x000eb512f2844afa,0x000f5799ad3e7570,0x000491fbae64e602,0x0000eebe7f0214b9}}, + {{0x0000f98e5c298ff6,0x000dd678361f3030,0x000cb9a1617f561b,0x000490952ff31298,0x0000233c3bcb562d}, {0x00015a192e3a2cb7,0x0001763651197bfa,0x0008c53b1961bcfd,0x0004b9cbdd29bf2c,0x000039704dff2284}}, + {{0x000fb587e7b754b2,0x00018806c9b97dac,0x0005044522336079,0x000783c7eb88c923,0x0000983e996a52c1}, {0x000e529958d881dd,0x0002562c7b3cdd4a,0x0000b52d1026bae0,0x000cfa6a6f919396,0x00000980f9162696}}, + {{0x000428cd5f30851d,0x00065a4f66304c1f,0x0005d48a494dfed2,0x0000cd7df53772fc,0x0000d2d5a3063326}, {0x00015bdd44cc7a57,0x000d4d12533a5741,0x0003057c94ba6b20,0x00020dc0e93cb824,0x000094c486a84de3}}, + {{0x000d4cef21496e4d,0x00081c696331e925,0x0008d812ff951d19,0x0004aac810e2de3e,0x00000a4725a08929}, {0x000a2b50e3bab661,0x00059bad306f513b,0x00004c49e462caff,0x000b0bd2dc6d59af,0x0000aeb8750f0b84}}, + {{0x000f12f2f7d0ca2a,0x0008406acf2fc034,0x000facc2f6d2e812,0x000606e01f4f8321,0x00001170c04940ef}, {0x0001d4f7805a99ca,0x00062c26aba5fe0a,0x000531f40bde56a3,0x000107bb1629d035,0x0000c212c2c3afa6}}, + {{0x0006bf315697be5d,0x000b5c63c7c130a0,0x000cdadaf6f0545d,0x0005ba8d8cb8427c,0x000052e379c7c701}, {0x0006147f462c23e6,0x0007e6bc24b0c4f5,0x000856d4fd44a429,0x000cdf5c73d23ae2,0x00001cedd8c6832b}}, + {{0x000355699f241d77,0x0006901a349d6095,0x00089e491ee4adbd,0x0005459b35bf6aaa,0x0000f0076f4836f7}, {0x00018ba9264da3d1,0x000d52a7a28bd19a,0x00061c9716eb2d2c,0x000a5dbdba941f87,0x0000550518bb3be4}}, + {{0x000e2f057d0b70c4,0x000e8d133ba3d0e8,0x000416aeceea8612,0x000061414670f044,0x000024db6c370775}, {0x00039d116213fd1b,0x000468a3478fd960,0x0000c5021c61e7fa,0x0006dcf805bdcccb,0x0000dd6f3a8bcc61}}, + {{0x00096675d97f7e2b,0x0000ff0bf4b60600,0x00091627a31db0fc,0x000fb073680ed454,0x000099a3c672d741}, {0x0005f5536b1ff923,0x0007212b388de9bb,0x000fcf2632973857,0x000b47ab8a2ce750,0x000085346d49c4f7}}, + {{0x000c5ef31631f9e0,0x000103a57a29be86,0x00023f821bf91da2,0x000354c3b1f7967b,0x0000f7d00d2770db}, {0x0006c3bd8fe79da6,0x00007525c9968ffc,0x000ff632acc5e8c4,0x000527e640991dcf,0x00004d97e8cc7112}}, + {{0x000d97302f1cd1e1,0x000b0dd212a4c232,0x0009802f7ce87eac,0x000dbd5e4c8c73e6,0x00002ef02902fffd}, {0x000c74e1bcea6e23,0x00040cb92cbb941e,0x0008f9d05d0b5402,0x000aae509fb9d47e,0x0000bf1615a22992}}, + {{0x000f279f8a7a838e,0x000025615660ad40,0x0001f6fa111aea63,0x000ec8df52e6f1a0,0x0000f0469961dc2a}, {0x000bec9d8080711c,0x0009dfdedf76785d,0x00021c126e1aec60,0x0007322ce797b5fa,0x000066e898fc5e52}}, + {{0x00069c408811fdbf,0x00073fc7f08239bb,0x0004f41388bfe1ef,0x000f97d8e7a39317,0x0000ba8ad1ec58d1}, {0x000d0cebfd2fd5bb,0x0001bee60d61bc21,0x000d222530b839a8,0x0006b2facf7658af,0x0000526bed95ae39}}, + {{0x000bbc2385644641,0x00077c45bc73ccc1,0x000188a789e3ff94,0x0008f7bde9bca358,0x000038b8ee0e73bf}, {0x000234c4123c4899,0x00086a6432975c7e,0x000a15fa366e6936,0x0009267629eeee39,0x00005fab88239e2a}}, + {{0x0007007eafbb1e1a,0x0006475b7a93b249,0x000b68d78d75c9ce,0x0003959558352def,0x00002f26699c23f6}, {0x0001ecfe469b17ae,0x0009072d3ec2eb91,0x000cb113f6254577,0x00098caea47de782,0x0000be4b0872e1fa}}, + {{0x0005ed78cdfedb1f,0x00070e211a74ec2d,0x000d244c5a535c07,0x000a75a678109b11,0x000017c8bfcae299}, {0x000412efb11fbc42,0x000274ab3f65b651,0x000f78243ea0b548,0x0001d4b8dffd950c,0x0000e719e57ee036}}, + {{0x000f085304ddc5b8,0x000ccdaba2ea9007,0x0009d28a9095e8c6,0x000002da33cdb43f,0x00005b95cd962283}, {0x000c819b97447336,0x00089c7f5783bcd6,0x0009038e429c5f53,0x0000180c49b2fad5,0x00008349cc19bbe1}}, + {{0x0000c1d21830ee5a,0x000e49bfa297cc49,0x000de1a9436f9c4e,0x000cdbb8fd729448,0x0000adb13a8ee8f2}, {0x000aaa081313dbae,0x0007e2152dd8515e,0x00053dbf8c76bb46,0x000142557f8d75a6,0x00004d8c4d2914ac}}, + {{0x000e675b055cb405,0x000b477b5167bdb8,0x0002fb863898f8e7,0x00001f9cc65651b8,0x00006544814bd88f}, {0x0008e95263a75a91,0x000f0a22fcdab092,0x0003bd37ccfb6836,0x000664551d14db3f,0x0000d3837fbc6ad4}}, + {{0x000b538ff4f94ab1,0x00025d7fb8f27c5f,0x0005c52877243c71,0x000d1bdf13d60ca8,0x00008cfb7c75bb8d}, {0x000bfe6729082196,0x000b3d5144ab82f9,0x000f4b42f35c4592,0x000dc3f2734f379c,0x0000bac55e7ec60d}}, + {{0x000811e94dea0f66,0x0004818cc1a3b5cd,0x000e660f8259ecae,0x000ff20a0e836e15,0x0000c639ea66e02b}, {0x000b8cb7e1026fd1,0x000b532619428721,0x000f01da39e73b50,0x00057fa8c7097477,0x0000839e6a69268f}}, + {{0x00094155150b8057,0x000e892c7097571b,0x000084b951892389,0x00095c1d69c18e4a,0x0000014c5132e5b4}, {0x000db361b07523ca,0x000d8c1c64fa4780,0x0002c105a2f6219c,0x000360238b81b060,0x0000b4f4f20fdc8e}}, + {{0x000c982cf7d62d27,0x000cb3ba815020d3,0x000763f9e1f36e29,0x000006d8ae0bf092,0x0000a527e6b8d3a7}, {0x0009097581a85e38,0x000f5c158be5b4a8,0x0007d726e1f1a520,0x000862798db37d16,0x0000802786e9113e}}, +}, +{/* digit=15 [{1,2,3,..,}]*([2^105]*G) */ + {{0x000149e36f09ab05,0x0009fa10bb5befb2,0x000e2099803f163c,0x000bab8029704506,0x00006f0af006b5a3}, {0x000cfec70880e0de,0x000ede3d913f7af4,0x000ceb4bd7332a66,0x000f5452e6c84a7e,0x0000dc4a79b7c228}}, + {{0x0007dd0c55c44969,0x000695bbabd2c37c,0x000d7f363a6a9635,0x0001decb7e63f2ad,0x0000dce3782be73f}, {0x000a16ab2b91f71a,0x0002bba0163ce1e5,0x000e515ade448982,0x000ecf52759c32f6,0x00005e2f1f92615e}}, + {{0x0009be7abded5516,0x000868b744107451,0x00010d9a903d358b,0x0002b6ed00b10b0e,0x0000392b0b188da5}, {0x000a2980b75c904f,0x000db8f7f96c6744,0x0002cf932c305b0a,0x0006c9142e421d18,0x00006fc5d518e463}}, + {{0x00047c9d64cc78c4,0x000b5b6cb27b7958,0x0008022ab6c50621,0x000a1cc7099bf8df,0x00008f862ec004ed}, {0x00032ede1603c166,0x000efc9a9450d127,0x00029b4fc19a80e0,0x00051582257f54b4,0x00006d3b2c6a5460}}, + {{0x000f87e822e37bef,0x0003353bda4e6ca4,0x000190aeb73f237b,0x0002840747f3a241,0x000006fa370704cf}, {0x000bb6efc621c127,0x0003d0b80ec60a6b,0x000a556f35d624b6,0x0000a7db0724257b,0x0000fa0c354ae2d2}}, + {{0x000fa31e3229d41f,0x0001a4531bd4e921,0x000d38209a929c65,0x0007bc94156027a6,0x00003d69f745bdb9}, {0x000d19a168336319,0x000d73d51be38906,0x000511cd868a34c2,0x0002a83b59583b0e,0x00009ce6bfe8dc13}}, + {{0x000daaaffcdb4631,0x000a24a38b083fac,0x000a9078d658bbc1,0x0005de02a801f8f1,0x0000567bcf97ab85}, {0x00098e03572359bb,0x0004d659e68be084,0x00023807ccf0353e,0x0008a20b86e9c87d,0x0000c08728dd198e}}, + {{0x000b7bc453cadd69,0x00072c0bc1f88de2,0x000abd3af203900a,0x000ffb2cd86e47a6,0x000011cac131502e}, {0x0000242ec965469f,0x000139e0017e2d55,0x0009798850e9f769,0x0001ee733f078f65,0x0000b87d44a3cf75}}, + {{0x0000e4bfc25419a6,0x0002ebff3cfde179,0x000b6e83f3646720,0x000fd268db638625,0x0000cc69f23ccad6}, {0x000e45a6bc68bb94,0x0005e97f73340219,0x0005dc97ce43d79b,0x00049a3d44536846,0x0000b9eea326a0b9}}, + {{0x000c6ba6102d0212,0x00080f4461ea1b96,0x0009f19a8eaafac7,0x000875b4b85c41c4,0x000075c28e4ef538}, {0x0001a9ddd2e54e03,0x0004d605618b3545,0x00036cd246991adb,0x0002162b8b4bcd7b,0x000072a4f8c86f37}}, + {{0x000bd73a6a5da60f,0x000fec4c9ff0c890,0x000536e576f083d9,0x00024304e14d94f0,0x00009ee1edb9aec8}, {0x00041ec8bdcf8e7c,0x00004b041e265712,0x000fff040a5db827,0x000201da0b9a99e3,0x0000aaf21de3c271}}, + {{0x000b2e14f0dd2e8f,0x000e1a377ac7b4e2,0x0007a2198e77e7c4,0x000eb779202c3f0d,0x0000759b80018200}, {0x00026eddcfe314e5,0x000403d5cf99c875,0x0005138b6eb84c52,0x0003f461b52ace51,0x0000aa7ff8c73fca}}, + {{0x00013c3b9791a263,0x000a9dd58b16ff0b,0x000aad2de960022d,0x000619abd55c9257,0x0000baaaaa4230fe}, {0x00023460d881efdb,0x000f96325e2a9a4b,0x0005c18d4506416b,0x0007afe1381e7603,0x00003bb68bfa2781}}, + {{0x000b8bf5116f9379,0x00063126894315bf,0x00019a2c87c64a58,0x000462e1e25cc384,0x0000fd6b0c51335f}, {0x000ba3ce8ee0e0e2,0x0000098c21fa4bf0,0x00066bee06f6fba6,0x00054437d57b39ae,0x000092d513042672}}, + {{0x000105dbab093b30,0x000902839986f451,0x00074a89c012f59b,0x000e978a91580234,0x000048c919c2de03}, {0x000a2b591071cd58,0x0009834970a5c476,0x000b7994b791ed89,0x000ffd09bd9042e1,0x0000eaf517a21057}}, + {{0x000e2a2d551ee106,0x0008127e09a66066,0x00001148d87a8f1d,0x0003fda0d08bab2c,0x0000da8e4f1a24f3}, {0x00017f0cf9a4e718,0x000fbbf5cb19466d,0x00062ecc0ff50200,0x000ac45ccf97d8d0,0x00000c0d9b001d80}}, + {{0x00071d8033f28764,0x00063d5cc3dbe877,0x000c9bc1db0186ec,0x00060e18e8bb803b,0x0000d1395ccaf6ef}, {0x00062d6186244a03,0x0002e10a5b53a73c,0x0001b7eab918e5f2,0x000e51bd4878ca74,0x0000038d71b0be03}}, + {{0x00004b7a93c32461,0x000990b9b4cd8402,0x000d6421821ab606,0x000191e5fa6e2bb1,0x0000de6ad0f03d56}, {0x000aa88ff1929c78,0x000ae40e87b5570a,0x0005f0cccc6df4c6,0x000c015e8a74f2c6,0x0000b972fd666f6c}}, + {{0x00036b60b846531f,0x000520a5e4753fff,0x00045b6c5ba7e45e,0x000d9c94a1d10e41,0x00001f7f91b4e046}, {0x000a69244de90d77,0x000a8199c15e0317,0x000d73deb951a1d4,0x00024f21f78046c9,0x00004c828296ab82}}, + {{0x00078fce7560b907,0x000137e824ceaa67,0x00042eba8b4073e6,0x000f388f0d693cd6,0x0000ce2e57acdcce}, {0x000c7891df1ad467,0x0001998346fd89c2,0x0002fc17783a0692,0x000f1cbd715d72da,0x0000b6dd71df5b6c}}, + {{0x0006d0a73fa9cb0d,0x000d628bf5a9c60a,0x0002c8c82edd3992,0x000f4ff380ddd083,0x0000182d41172a0b}, {0x0007438d9a528dba,0x00092af539947d9d,0x00019987ce8b1a0e,0x00059d3dd6e5fe0e,0x0000cb8df03b90b0}}, + {{0x0003a328300129f8,0x0001e8c43bfd5370,0x000e540511f63766,0x0008c53cbd191300,0x000012fcc62fbf5a}, {0x0009d5f29fb85da6,0x000a094759e83f96,0x0000726b772f4e00,0x000208e26b6e5279,0x000017bbc879bdbb}}, + {{0x0008bb997aee3170,0x0006e81536a8511f,0x000c09b9b812a409,0x000a7a137dfe593a,0x0000682238fba8c9}, {0x000ead6aeccb4bdf,0x0009792ba6337072,0x000ff9d336a34e9a,0x000b61d82eaec26f,0x0000b7535130d4d2}}, + {{0x00045ff1d7aadabe,0x000ff5f6a67c1a04,0x000cfb26f65d3825,0x0001d58e62fb0891,0x0000f1e0fa63c7d9}, {0x000c7ba33db72cdc,0x00093a7c74b247e7,0x0000a503c017cbc0,0x000a417c931590f5,0x0000ac54f61216ba}}, + {{0x000d380b2369f0f0,0x000d23c761519b6c,0x00062a9c697d3a70,0x000f515f9dd6fc98,0x000044c4ab212312}, {0x000a0fd834a2ddc6,0x00026c7b826d035e,0x000fce49049e6b86,0x0006e9503d688362,0x00002f2497b137e3}}, + {{0x00005b6c64582934,0x0006a8d10af704b0,0x000e617b836bb527,0x0003d46cf2dc138e,0x000070d2d35f004b}, {0x0000832feeb1b77f,0x000895657f9c0679,0x000f600042bb75c3,0x00018ae70bd4edc0,0x0000e797ecd119b0}}, + {{0x000ec2a753aebcc9,0x000c3939eca59b5b,0x00095ad09daf9f3d,0x0002fc46bc6833d0,0x00008abdd526aa4d}, {0x0000a318d168be52,0x00000325a23cd984,0x0006ecfafcf7c10e,0x000f1885c02aa07e,0x0000462e7e6d5bfd}}, + {{0x0008a8ba0cc3f125,0x000d6c672a29ab2d,0x0006f2cd368dd485,0x000d8d2203975259,0x0000d3eea67f0cf3}, {0x0001a81e6602671c,0x000f54026c0c810a,0x000b50f858f144a3,0x0004a3fc753a6d76,0x00004dc21e9245cd}}, + {{0x0002dea521d03782,0x000de5011c6fc526,0x0004c19ea802b8e0,0x000aebfba19cbb0b,0x00001db64b60bf0a}, {0x0004ee970342f9d6,0x000dbbc44a141f39,0x000fd0baa93a10ae,0x000e6547eed31b3e,0x0000e7c824e7d154}}, + {{0x000fa819966e7eef,0x000715b7920dee23,0x00090aad464ec4aa,0x000ad43d44462d2d,0x000044dd196cf277}, {0x00071f1bb46b6a1a,0x00035d8850908d64,0x000a977b41e65d31,0x0001ee93a800f513,0x0000ca9d721a797e}}, + {{0x00085a0fcff6a17e,0x00023eca7cee9a5a,0x000504be39970a3f,0x000ee1db9f0d6bc9,0x00000c504bf8dd24}, {0x000d95677fcc2f46,0x000705bb5fc47e09,0x0009286aaef1a522,0x00028ab45d4fb18b,0x00006fd0c5dc6490}}, + {{0x0007ceb1bf4581ca,0x00060ca7b1669885,0x0009722ace635e18,0x000006878ddd2265,0x00000903c4cbdb68}, {0x000458948f214029,0x0004296abda2366e,0x00040319031b49c1,0x0003fda29c4b09e0,0x00007197ca4629f4}}, + {{0x000dd1e274983d81,0x000e45717c8f8073,0x00061f9d1da1a3bd,0x0001ceed3d4da203,0x0000332d0815c7de}, {0x000f7a3aa6d0e10a,0x0003554f1c4a9b7e,0x000d3556717db2e7,0x000e710f3dffae4c,0x0000aa2f407856f4}}, + {{0x000759e7ace3fc7a,0x000ea5a8d8c68966,0x000834e0e9594eac,0x000420ede3bd8b91,0x0000fe4ca53f48c0}, {0x000e856e6ee81c69,0x000adb891a3afdd7,0x000e638298f671be,0x000c9f67a58f2bfa,0x0000ab186fc2c11a}}, + {{0x000b36910b5be761,0x0009eb040bcd8d6e,0x00073de88046b773,0x000e03bcb4529fcb,0x0000df0fefcdf26b}, {0x00057a6bcfcd0279,0x00052b3165caad77,0x00099a4d9a8786c7,0x00004b59db1e347e,0x00009ee86e0406c5}}, + {{0x0002dddc15c9f0ab,0x00039295989e5b7c,0x000d08fdadf87a73,0x000701a9ece47c03,0x0000074d3de5d5fc}, {0x000790351a03776e,0x000a4a6080072040,0x0001531852bb1f77,0x00044645c58f4fe1,0x00006df62f7566e6}}, + {{0x000d1beed51275ad,0x00065f0f483fefb3,0x000c2bedf5de47dc,0x0008a0a932d98e97,0x00005c11927d219f}, {0x0001200a73a294ea,0x0009fdc201729d75,0x0006f506a5f88434,0x000d48328d9fd3a2,0x0000890cd323d1dc}}, + {{0x000aec170f4d3b44,0x0008cffc8d000aeb,0x000d57838fd1a136,0x00036179d9c24057,0x00005929d26a8bac}, {0x000d06025b15ca6a,0x0000ce4744465a2c,0x0001e51344b3c83e,0x000f407aac7578ee,0x0000418f5d7691e2}}, + {{0x000fc8a213ed68b6,0x000cf10a52246936,0x000f09b53860ae7e,0x00098d03660335de,0x000041b28982d79c}, {0x00038e101110f35d,0x0001948b193729bd,0x0009164f479c26f4,0x00027294dae5199d,0x000085a2310d265c}}, + {{0x000dd5d4b07e2b19,0x000afd9ea2217173,0x00005ab14d144c4c,0x0008f158b04ea411,0x00002dda5438e80d}, {0x0002fa8cf03dce66,0x0004ba22cffce998,0x000ad88c48b5ea96,0x00095c97f4ea7f3f,0x00002db773eca5ba}}, + {{0x00002fb93f245674,0x0009f15257cad20f,0x000cab987fd46c69,0x0002f4cac74cc78b,0x00006f31c019ceca}, {0x000db59888b219e5,0x000791fccd0240ae,0x0001f816ce50ecc3,0x00000bcbcd9dad91,0x000083cc1ecddb9b}}, + {{0x0002e66a483bf119,0x000521b2c169f3cd,0x000e9fa28fa08a6f,0x00011f6375e2454b,0x00009a7ffeceb6d0}, {0x000bddbc4ae62da7,0x000dc74aef5d6a3e,0x0004d05bc6cea00a,0x0002523b5fb98d9d,0x0000cba14244560f}}, + {{0x000cc21208490def,0x0002ccfb287949b2,0x0006fb16f1ca66ec,0x000db28f1166b71b,0x0000ff63e0955fe5}, {0x0005abe8b2610bed,0x000f69de3df4b834,0x0001c32b4b732ed7,0x00027c3e24ed5021,0x000010d8a6a548ff}}, + {{0x0004398ed4de248b,0x000d60488927c107,0x000673e13d7cedac,0x0000aef4aa6bf885,0x000046bae921daf3}, {0x0008472fcef7ad8e,0x0007f4b35e970708,0x000e299866115160,0x000c78dcfe8f26dd,0x0000b84c4c8b5a34}}, + {{0x000c55c164e1214b,0x000cf147bb03c1ee,0x000a96835891be86,0x000e9eefab4d100b,0x0000f01e9b955c1a}, {0x000e139b186ebc0e,0x0005a5b91bca6b4d,0x000d93854d5c74c2,0x000fbb7086a99cc2,0x0000ed62a7c87a9d}}, + {{0x000ed6f76b7618a3,0x0004d3b660628778,0x0005186dbbff750a,0x000d131cb7be22b6,0x000069dfbf0fc3a6}, {0x000b26c7191a321c,0x000880ed718ec7da,0x000cfd1839edac3f,0x000692fc142b36d0,0x00008af82f73c991}}, + {{0x000e4d897ce0b2a0,0x000fc3a55cdfb3d1,0x000b81afee6d7c87,0x0009d835846b9568,0x000018d12afd3c23}, {0x000620801206e150,0x0003a3b882c62b2c,0x0000162d5e0e4245,0x00062a854470a3a5,0x000081574787017a}}, + {{0x0003fb4820357c72,0x000e4f1458ad18bd,0x000b44aa1992039a,0x0002817a1df3c525,0x0000d7803580d3d5}, {0x0007e4dc77ad4d4a,0x000859df4fc458cf,0x00071205ed49a799,0x0004a9a465a8b51d,0x00000ee0ea704925}}, + {{0x000eecfab7bd7712,0x000315c262b94b5e,0x0009d61e76c87307,0x0000d2bc5bd6483c,0x000033d6d5452146}, {0x0005626fc195bcc5,0x0007b4d78b63d20c,0x000ec8ef32544595,0x000781903fcb3d17,0x00004b690d196b8f}}, + {{0x0002c8a212306466,0x0008a84f418c82fa,0x00030ba43f51aabb,0x000df79f4fbec11a,0x0000a5acf73d43c9}, {0x000b357d635b4d5d,0x000d1cd5c1da1da2,0x0001af0ddc3de68d,0x000f98d689080bd6,0x0000ea5938ba665b}}, + {{0x000d71afe637294c,0x0005e5a81cd80231,0x0008e63b501968aa,0x0007e851252d5004,0x0000446bc532ca00}, {0x00050a696d6134bb,0x0004ee09a05cef8c,0x000a3291a9361fbf,0x000a21417f85a6dc,0x0000178d549af251}}, + {{0x000374ba4df39156,0x000ecfd5d60887f6,0x000e35102566ce1b,0x0005e1e25cba4d7d,0x0000b745f8fb8c5d}, {0x0002af663122edfe,0x000c5b989a898840,0x000ba31563190f9e,0x0009a46ad3d387eb,0x0000f385adaa7c46}}, + {{0x00081de3f642c293,0x0008610ffb88b082,0x00029254620be088,0x000262c353dd4ad5,0x0000f1627deb377a}, {0x000a013eefcd6385,0x000624cc77c3a5fa,0x00048f55e8f3bf62,0x000b9de2618f65a3,0x0000787c0dcefefe}}, + {{0x0003aa2d9a23e449,0x0002be10690df167,0x000f9110888dfa99,0x0006488ced1b362b,0x0000193cecacaf48}, {0x000327d2d738fc52,0x0007775fee6cfb34,0x0004079a56697b03,0x0001ac0f485da0c0,0x0000cdf57354feaa}}, + {{0x0004420bd55659e1,0x000b3376090c7694,0x0003b591a7973e32,0x0000ca76bb4fe116,0x00000441aedd196f}, {0x0001f4a045ad915b,0x0006f4afacb13b43,0x000fdbbd86c11b43,0x000acc80b0c7db71,0x000064293209da65}}, + {{0x000e6e89c92b2350,0x000e6b3993a14baa,0x0003dd031a73bbd0,0x00081cd06d60ec69,0x00003cab91b71568}, {0x000862f1db3574b2,0x000544bb061ad615,0x000181e06485b018,0x00075707434988a0,0x0000cd61ad4e1c0c}}, + {{0x000ed5a2ff9f403a,0x000ac22390293eff,0x00017b70d8dc98d8,0x0000148206021e1f,0x0000fbec0cb5f510}, {0x000716480130dfa7,0x00051a02dcf59fed,0x000b10fc0306dc2b,0x000f50d8f06620fe,0x00008d1e1d5ca57c}}, + {{0x0008c5a192ef7106,0x000adb7431f9adef,0x000250c9e88afbd4,0x000c071e1f740764,0x0000e31318e158be}, {0x000c4b824f89b4e2,0x000828c36a2afd4f,0x00024baa765a5dd8,0x0006502f1eccfff0,0x00002a21cf2eba94}}, + {{0x0009dee42a554f77,0x0004902ec4ba95d2,0x000adb73d828983a,0x0008391112a1f78b,0x00009ea8898127c1}, {0x000a5a7d065fd831,0x0001a262a0bc8969,0x0002b5127f49af79,0x000dbcecdea8b6af,0x00000e913e1664c2}}, + {{0x0009d14bc21ef518,0x000acce572925123,0x000bbcc3be51c3ce,0x0001e5f95ff06847,0x00006b46e1f3d7e1}, {0x000ba2380041ef4b,0x0004b262342e0ea6,0x000d294d4d72fe50,0x0002c8dabc6dfd31,0x0000be017a2c278c}}, + {{0x000fa09b389328ad,0x0002001771b5b1fc,0x000b045bf322fbc6,0x000d0034c0d06360,0x0000b652edce0e52}, {0x000932c03ec6627f,0x000cd1ee50e350ef,0x00037a90dde1b3b2,0x000a956ab7bdc5dc,0x0000ea6721421e33}}, + {{0x000b5cb4f2999aa1,0x0006a8cbf0dd6482,0x0003405bb38476cc,0x0009ec83ebfacb17,0x00005cdafe7f5236}, {0x0005ba4d935b7db4,0x0003dc99a4cdd42d,0x000b5545b648b600,0x000faf385101bda3,0x0000bf2c38addd67}}, + {{0x000dc634442449cd,0x000963ad4fb8b1aa,0x000686d82e0e9921,0x00066b8c552313aa,0x0000ee635fb165d8}, {0x000224a18ee6e8a7,0x00067d42e02fbc3c,0x00074cd08eed748a,0x000adf770f930ad4,0x000074ea6ed6ff24}}, + {{0x000de1cf3480d4af,0x0006cc8acf1a03e2,0x000295a9cf0d8edc,0x00097d023e330368,0x0000add5f69b546a}, {0x00097ad96f8acb1a,0x0004c71bdae28955,0x000dd43f4bddd49d,0x00041976fcd52821,0x00005a4541306191}}, +}, +{/* digit=16 [{1,2,3,..,}]*([2^112]*G) */ + {{0x000b6bfc360e25a8,0x0004875a1a788ce9,0x0001732f4e642519,0x00057a1dc756a848,0x00003c0440fd432b}, {0x000b3f1d720281f6,0x000e7135e051c670,0x000052be72205910,0x000a397ed14b0edb,0x000097b3d282568e}}, + {{0x0009b9afb3ff9ed0,0x000b17f6515c2e59,0x0004da44928c2e0a,0x0004521cbee4fd47,0x000071279a44f364}, {0x000ff6601fbe8556,0x0007ffda51c497ab,0x000597c0b3ee394e,0x00034ab90385f667,0x0000e9fccc7027ee}}, + {{0x000de9314092ebb4,0x000d028e240c0b89,0x000d2f064f17256b,0x000b148f89a7f393,0x0000f57841f21ed3}, {0x0004405e708d8553,0x0001d3f1c3d04ee1,0x000d7eed5856aae7,0x00027098e5424fbd,0x0000333e4efa3ab4}}, + {{0x0007adedda492f81,0x000a682972053bc7,0x000931b4cc11a3ae,0x0004bb4e89a3e734,0x00007512e2eaf569}, {0x00049f3177bf8b6c,0x000948c7ff3e5dc3,0x00011145d232ea4b,0x0009c2dc4f9d16f5,0x0000cf109a3f3b37}}, + {{0x0007a88a1f258972,0x000f81b5d4d8e75e,0x000f3ed5c7ac6961,0x000dfbc3e1077308,0x000008a54ec2a892}, {0x0006e1978660710a,0x0006837df2c8be82,0x000704da50cf70a9,0x0003fca18a7340ed,0x00003eeb9a9a8ca3}}, + {{0x0006233169bca968,0x0003ada6aafb49d9,0x000c2fa9404d286d,0x000fb3409606eca0,0x0000869d0d5a3ff0}, {0x00037e5d0150d651,0x0003140c14c9a999,0x0008e2d49a92e250,0x000e2b556bf94510,0x000052a733ab2f59}}, + {{0x0003d588434a920a,0x0002c22103c5b432,0x0008dbf9ac0af8e9,0x000df1c67518ef93,0x0000184307423a9c}, {0x00094aa5447ab801,0x0005b75a3d61350a,0x000411a9ee5e5a32,0x0000c564ba507f68,0x00000581fc1694f7}}, + {{0x000857080eb24a90,0x000d488e0cfd60e2,0x00059cdb87bedfb4,0x0000a9721ebbd7c2,0x0000b0da855bc639}, {0x00004dbde314c709,0x000bdc32e8462b4d,0x00062fc9ecdbf1fb,0x000ab6a3833eabb1,0x0000939b48c40dd3}}, + {{0x00098a7cb0c9c8cb,0x000fd1c4375c5aaa,0x000f1c90f75105f2,0x0007bf1eee50575e,0x000031e0660723a1}, {0x000d275d4b6d45a8,0x000ce2ec89965364,0x00091c65bd363f3a,0x000b4735d2123943,0x000045647666bb41}}, + {{0x0008ecc37107c78e,0x000a770c2a6620d1,0x000d0d845acff3b6,0x000f9f42f975d99b,0x0000f0a0c479a178}, {0x000965176b6028e0,0x0004248612d41a41,0x00038af55c49ec67,0x000a365b6ac4f273,0x00006145e627bee5}}, + {{0x0005d07e75746b54,0x000d840c78be33e9,0x0002ff8e21c1e1f6,0x0000ad567833ef22,0x0000bedcf6af4918}, {0x000e9c13d7a4c8a9,0x000bdddfe7606b37,0x0003a5bbc2748887,0x000e7467055123aa,0x000054ff2260bbb8}}, + {{0x0008ab197c3dfb92,0x0000af168154c42b,0x000b5069255a549b,0x000bcb8d6748e7c1,0x0000775780f8fc5c}, {0x00080b8e1c9d7c80,0x00013fdbcd564eab,0x00069eace8c69dae,0x000b5a47e6b4fb99,0x000002f1085a705c}}, + {{0x000ca446d3fea556,0x0006948105684e23,0x00062f27db4ae9c8,0x00028be7bfb91b2a,0x00000deb4ca39bac}, {0x000d8947de6c34cb,0x00089494587da892,0x0003f8a5b4ee6825,0x000384e14ee14e1a,0x0000b113eaad8700}}, + {{0x00003b92115b4c9e,0x0007a908cad181ca,0x00018179a7c163d3,0x000080e912a118aa,0x000009ed751686e3}, {0x000e3fa26f516cac,0x0006ce732f91a676,0x0003da8b4753cacf,0x0008a991592aea83,0x0000626f4300cbea}}, + {{0x000c899a7b56eaf9,0x000ba4ef7316ef9d,0x000818a8600c0e52,0x000e46cb1e4e24fe,0x0000d31e20e5538b}, {0x000932d3ed689748,0x0007fc4e87c422eb,0x000de9aefe44bbc0,0x000344c121086e0d,0x0000e6b9cff934f4}}, + {{0x0002c1f711b0eb9e,0x0007980ab9549689,0x0000792dbb905f2c,0x000125cce26309a2,0x0000c8ac9b3e684e}, {0x000d8b6b40a24474,0x00015fe3fb24486a,0x0008e3b3f60121fc,0x0003941626fccf1a,0x0000e568622aad1f}}, + {{0x000ae0d196aa5a1c,0x00065041b5fbda7a,0x000b318b7e0df8c7,0x0006e8851465d926,0x000029b6e563ab13}, {0x000b48b711484633,0x000334454a762c2a,0x00003abe4b5738de,0x00058e24ccf9a05a,0x000077c02963427d}}, + {{0x000f0b92bb39c1fd,0x000c1608d8c573f5,0x000fbb80514373f2,0x000cfb0cbfd31400,0x0000f18fb2153afd}, {0x0007f4242b3523f1,0x000d77f650fb81a5,0x0000a7d7ce958532,0x0006be9a8dc8b68b,0x0000b75dfb725016}}, + {{0x000f7c92d7d1413a,0x0004f834f59790e4,0x00008c3e867e2d6b,0x000ec0afd4f4f9a8,0x0000f8237e175281}, {0x0005fdc84687cee2,0x000185b26c0925ab,0x000ea7650c5ded6b,0x00017f6e4a5aecc8,0x00003b73e5c34cc4}}, + {{0x00043183037bf522,0x000558c725d72bfb,0x000b3e5d7b61e6db,0x00088e6efd4060bb,0x0000e014701fbac4}, {0x000cf9a360aa449b,0x0004c9634d08ac75,0x000fb15efb70cfd0,0x00006bf591536dff,0x00002c37583807c1}}, + {{0x0003fdcf50225f97,0x000c40e12b03b429,0x000a8bf64c52e175,0x0003c68649c3bad0,0x000045a8ff05b8ae}, {0x000e5a358321bc3f,0x00061bc4df4830d7,0x000ea5058b1732be,0x0007442f217993e9,0x00007a71cdf2e4fd}}, + {{0x000533e894c5bbba,0x0008c9d8308286cc,0x00015c2446915c7d,0x000ce506aa2d0558,0x0000eeee592e9b22}, {0x0009d13781354864,0x000ed6b76f2f89e3,0x00036e8f53a275c1,0x0009f59b6bcc1be0,0x0000df69b219e470}}, + {{0x000b2502d0f39aaa,0x000a75a85947a188,0x000e0f4fa622118b,0x0005388ebf520ffd,0x000040e9f29e860e}, {0x00051eb22b57f0fd,0x0008ae80644a7b6a,0x000f095fe849a33b,0x00000180e5d16f1c,0x0000754b54fbc55f}}, + {{0x000bb22236f4a982,0x0008e66800bb5cfb,0x0009a77740b0c59e,0x0009482ac69a8f5a,0x0000b33f804f6bec}, {0x000929532e6c4662,0x000f2e599c73b372,0x0005c31cc68956d0,0x00084e847a249f15,0x00004d80f0e01ce2}}, + {{0x0001dfb988baf015,0x000d8bb16647cd82,0x0004cb960e6331a7,0x000ca4ceb8ad3309,0x000093cca39191bb}, {0x000ac8d265674566,0x0009604b6490384a,0x000b6c8f640fa030,0x00055f37834cd6da,0x00008a7318d9f91e}}, + {{0x000d04efc4d31579,0x00019bf3bdeaa00f,0x000a57172b56f8ab,0x000db2714f56484f,0x000048c5860d50ab}, {0x0005df00ebd4f086,0x000cae82938e342b,0x000df5dd03e5168c,0x0005161aedc1ceb0,0x0000bbbc6da45732}}, + {{0x000d486605daaa67,0x00074b9a6c9ec7bf,0x00024fb8946fd72b,0x000fbc74847fb1a1,0x00005959cbe12d8f}, {0x0009f65c8a588eea,0x0006180b499d4257,0x0009a5df1368c92e,0x0006044a4ef6cd99,0x0000a73bb80336fe}}, + {{0x000a70d6457d188b,0x000adb7a388bf347,0x000cd601386eda86,0x000fb207cdff060c,0x0000eb1b6c880053}, {0x000238799240a9f2,0x000f576189b20b02,0x00066193a1bbb384,0x000c7e6695e71e90,0x0000eb5009726ffa}}, + {{0x000a9c04a7d2caa5,0x000155aaa2900654,0x000476e8f6f3fb3d,0x0005e4335db041ff,0x000040b8b0c14229}, {0x0003ac905e214f55,0x000a06a0b638a5c7,0x0009e680b9a74075,0x000af9de4b1090ce,0x00007a5b479bb8d9}}, + {{0x00048e726bfe65cf,0x000b8290c3070dca,0x00069e72e097e391,0x0009ab783c462e66,0x0000505be1ef6255}, {0x0003ea1e3a3035a8,0x00061cd50da85fbe,0x0006407f26431ebf,0x0006b87d169d5c1f,0x0000d838a95e0fce}}, + {{0x000fa7f650006f01,0x000340c0fbb22a2b,0x000f9ad96dfd7dad,0x0005f982452495cc,0x000083bf494e9563}, {0x000df434a7bd989d,0x000bd543109502d5,0x00043f53e505385c,0x0004a90d98e67dfd,0x000061e1a6d200c3}}, + {{0x00046c64a8a3d626,0x000fc47743d25a4b,0x000f7e4338469c4c,0x000848cbb3a13d88,0x00002b23a1061be5}, {0x00096b4a63d1a4c4,0x000a3d183f3ee835,0x000afb01c454e7fe,0x000638243fce6117,0x0000e65e5e65c4c3}}, + {{0x0005ea1ef74c45bd,0x0005de32850641d8,0x000da7da92cfbfa6,0x000fbac8b078f53a,0x0000985fe38bc752}, {0x00068fe5a0148b4a,0x00068d78136deece,0x000b729ce6f9a55c,0x000bc3832dccc4d2,0x000027e0dfe30aaf}}, + {{0x000445212b4603ee,0x00008b706d149647,0x000a9d412a876c55,0x000c33ff145fcf69,0x00002ab75b80d479}, {0x0009a761a23ff976,0x0001fd359d1012df,0x000835f22c613899,0x0004d90e51c7aefa,0x00009a79cb220fcc}}, + {{0x000350d594cc7e13,0x00030350ab79f57f,0x000ff594a3079ca6,0x00062af26fb6149a,0x00005afec029d59a}, {0x00046f406ed2c6ed,0x0004ad939a579bee,0x000d1797e58da173,0x0006c974c504028f,0x00008853e7d2ccea}}, + {{0x000508da35fcd5fe,0x000b695ccaeb4065,0x000e1a9628965df8,0x000cc32f2da85012,0x0000e471b95a1cf1}, {0x0009bc80a08fb758,0x000501de3591cef1,0x000ef4f88704958f,0x000a5ea867f8b23a,0x0000d7493856a9f9}}, + {{0x00055378c9049f43,0x00034b92d8b61b38,0x000e2bd6b5be948f,0x00054da96f725db6,0x00007a222bcc58c4}, {0x0001abb8809bf618,0x000b9346f18de7c6,0x0007c0d1c46f07fb,0x00007a7b567a7ae8,0x00004a461c8fef3d}}, + {{0x000dce6d9278d982,0x00037dfc73e10a5a,0x0004321c324d9481,0x0007062f3528b605,0x0000e03fdde892ea}, {0x000061947b533c0b,0x000e7ca3c05510e6,0x000b62b8f1a8bc73,0x0004e2fe58d4b21b,0x00002045a74084a2}}, + {{0x000d5afbd76e195d,0x000c9938a8103ab3,0x000e3d5cb478dd1a,0x0001e39ffab3936e,0x0000fb693dbf2b36}, {0x000449651dbf1a78,0x000e88a2e762f969,0x0009bba9acab4b4e,0x000d9668c92f25d3,0x000050e61bd71464}}, + {{0x00030e3dc09508b4,0x000f34317655b7e8,0x000690355faf6d2c,0x000ed632606cebdf,0x00008bb92b410c3d}, {0x00054845c7cf8929,0x000945d5f01f65b7,0x000401d69f6cd7ac,0x00087832c30a5996,0x000012686517d921}}, + {{0x000f913b78c558ff,0x000ad8afdaa9380b,0x000f169d343c0bae,0x00020a477f61d554,0x00008da07e49e5ff}, {0x000c49da8a90ea83,0x000b53a29b21b676,0x000d8d27681c1ff2,0x000982083297ac2a,0x0000001122fea89f}}, + {{0x00094be6718e4488,0x0001fc3e6e13e1d7,0x00026b5ef246c148,0x000cdcd6646ef85d,0x00000f5091f08069}, {0x0002e2f724bdd38b,0x0003d471e8c7c599,0x0000ff2a902e915b,0x00019fe6ff320a0d,0x0000f886487f384d}}, + {{0x000e6a6c93f72d63,0x00029ad800eabbe1,0x000acf117d5f75d1,0x000355ca40a09fe7,0x00002c8cdd5a581a}, {0x00019927023c4994,0x0006f8ec39017422,0x0000e83f0a8afe5d,0x000eac1691afcba9,0x00001bcaa034b8f8}}, + {{0x0005ff98d2668d5c,0x0009bad81965e38b,0x000c6ce110715281,0x0004355bc8fc7c03,0x0000bbee6e34b650}, {0x0000fe80cdb9808a,0x00065e3ed31506b0,0x0000b501817d6e06,0x000aee8e9d38c64d,0x0000b8bfd57244dc}}, + {{0x0004a59513aed8bf,0x000c414bd07a4289,0x00042b582f77f3b6,0x000fe5cbdecb8f8e,0x000010e2fa9c2390}, {0x000502262a2f201c,0x000f90ee32b0efb9,0x000a789a84d59ea4,0x0002c4187f77286d,0x0000f98a2d0b7949}}, + {{0x0007239720943c28,0x0004b990b9d0f957,0x000f2884aba044cf,0x0000aedaa8e82395,0x000034de6ed8278a}, {0x000ee9a5f25bd125,0x000a1f7ab271c8e1,0x000d00b769259cea,0x00032a2e6d97a277,0x0000c0c6eeaf4378}}, + {{0x000c20f5606b81d7,0x00049d991ee55232,0x00032d951abd7b37,0x000363dd2bfe3586,0x00008f8514708ed9}, {0x00073f0f30c3282a,0x00000789230b9518,0x00098967f0da8ac8,0x000fb49ac7789c53,0x000069b8f805dda0}}, + {{0x00077176add85450,0x000672c49b66e5db,0x000421d771b71cb6,0x000fead856073968,0x00003840fe883e3a}, {0x000dad51ec699775,0x0008e07f6726b391,0x000ca160cae243fb,0x0005f4788ac87be8,0x0000174cced9ce35}}, + {{0x0005966e58ba37d6,0x00021817335d98a3,0x000fbc7bffdcc8da,0x000983fb75283083,0x00008e419d539c96}, {0x00039f402a403801,0x000f0fe977bc409a,0x0008edea688940fa,0x00047db640a94b8f,0x0000e22cd17fd115}}, + {{0x00068ce59ffc3e20,0x0005c1dee4e7e285,0x0007cb36360aa1b5,0x000bf2c67497c883,0x00006fb438a105a2}, {0x0007ec4500d8e20f,0x000c1670db103035,0x0003b7cfd1ad9095,0x000d278f589a05c7,0x0000544607e780d6}}, + {{0x00093b1a20ef103d,0x000f9ba6577b17ba,0x000a214a0ad85912,0x000da495c91cf66f,0x00007d49c6cf7990}, {0x000ec8d20bb569d7,0x00027effbc33ecd9,0x000ed0467bd4b250,0x00028bb056ca5a6b,0x0000916a1f7cb637}}, + {{0x000497d53a4f5668,0x000417b56810d4f9,0x00094a6218973466,0x000c6878e1da7404,0x00002546a940d011}, {0x000cb19c61ac1625,0x000c5bad0d3e1f3a,0x000b7ea4352f8fa9,0x000124c5356523b4,0x0000a16ad61fe608}}, + {{0x000b87f4faed184c,0x000c9029f45fb0bc,0x000c6b1fc5f236b1,0x000ce3142c76070b,0x0000644324f28aef}, {0x0001d595c5d84462,0x0006f3ae19798e19,0x000a59cc7c020807,0x0001ba8dcaee553b,0x00000ed6d6bc2cb8}}, + {{0x000ba19b6efcffc7,0x000827c0b87c0952,0x000aa30bc60f12d6,0x000f4ddee2c7c49c,0x000067238b807fbf}, {0x0003921501b5d92f,0x000ed2a37737ebc7,0x0001975433279e3d,0x000b4dafc12bc86d,0x0000a94dc6ffa40d}}, + {{0x000b41a530ccbbd2,0x0006ca8235257392,0x000d98d0c87c8214,0x00074c852f984c05,0x0000ae57d737ef69}, {0x000f7bf3042a6dd3,0x000fe9647a649377,0x000ca9767b1a007b,0x0002d5caa9079a0c,0x0000d81a25c268f7}}, + {{0x00067f8ff81578e1,0x00008045447d7520,0x00005aa6f7862215,0x000c77b0c22fcf05,0x0000030f0a67bed1}, {0x0009f151f0bd7390,0x0007e6debe8531f2,0x000677e982d7989c,0x000fd55c070e728e,0x0000a817bd306e81}}, + {{0x000d830b0f2ac952,0x000a8b20e64ec110,0x00029cd9a48d0995,0x000945ef3e00e177,0x0000a570c20fd556}, {0x000bcfd4e86214dc,0x00020f615498912d,0x00030d76e2d014ee,0x0006d095e2b1e635,0x00005135ae5bd0fd}}, + {{0x000273ad4f3049fd,0x0003170874770066,0x000c6e5fdbb8e989,0x000e6b5dba1ddb14,0x0000ba3788721f57}, {0x000e0a65a72f2cfd,0x000eabea56425aae,0x000872c371208bfb,0x00022425c6aa3b67,0x0000726e08413f93}}, + {{0x000daa5061f16587,0x00016f0cd2b31854,0x0003d50dec0016df,0x00001752a3f23e83,0x00003b681d32bbd3}, {0x0006dc43ac343c03,0x000d557164212f04,0x00017eed49c847e7,0x0009c6b1e13c9109,0x0000fc9eebd93a1b}}, + {{0x0006a727fe02299e,0x0001494f33190f81,0x00045c5be6335ccc,0x00066d5820179f47,0x0000647b783722f0}, {0x00049de02cafb8aa,0x000f5cc2ecccc22e,0x0000e8282299bc2f,0x000204fa8feea26e,0x0000627278c9e893}}, + {{0x00097337933e47b6,0x0002ce766402a7e1,0x000440d9ff4ff6b1,0x00080844d8be0a98,0x000058f5c2f98938}, {0x0005677c95b3b3ec,0x00087137b6ff90b7,0x000c47c29fa04426,0x0005b1477b039b43,0x0000ca95dd44a644}}, + {{0x0008ba42333fc4c2,0x0008d736a1b10b49,0x0001d4b2e274f8e6,0x0001994ca348fd5f,0x00004d3be78c8f10}, {0x000f858ca14f530f,0x00026b982e518535,0x000e1bf62a6e7f16,0x000417947c851236,0x00006a7c58ef3448}}, + {{0x0003703f9374ab69,0x0004de564145583f,0x000526d50864f919,0x000495a3bc3f4822,0x0000f323c80a262a}, {0x000a7ae3f046a9a9,0x000e4f8a039aaa97,0x000aa0ba670da183,0x000c2ccb68f71c52,0x0000be0fe51b1459}}, + {{0x0007eb6cbc613e57,0x0004d97ea61cc1e1,0x0007eded533131d5,0x00011abf69d39eaf,0x00003c2f4354e6af}, {0x0002493a4a375fa7,0x000c4833c5c24ca5,0x0006e71cf5f06787,0x000666114e091f3e,0x00006451f57fb746}}, +}, +{/* digit=17 [{1,2,3,..,}]*([2^119]*G) */ + {{0x000bdef694db7e04,0x000779fcddc680f9,0x000b8dce1edca878,0x000ba111981c3403,0x0000274dcf1b0e10}, {0x00043b86def6d1a2,0x0000cbdb1866f727,0x0000c6f58d25b167,0x0007f5a4491e8c05,0x0000be2b2aba7fbd}}, + {{0x0005c9dd111f8ec7,0x000d47c4e7603e0e,0x000392a51bcc33f8,0x00092d002f9a91bd,0x0000da4a7963132e}, {0x0000ae30bb1151be,0x000722e322511a0b,0x0004e9e7854febac,0x0000b80a3a508269,0x000058ffec2c4fe4}}, + {{0x00092fcd1e0cf9e1,0x000db0e7b2e8f855,0x00035584edea75f0,0x00092ab04215cfc1,0x000074fc7273f570}, {0x0007877eb930beae,0x000a7eb02a5ae727,0x000241b9b504cacc,0x00095419fe08f7f5,0x00007fb62f56d5ca}}, + {{0x000349d29c4120ba,0x000f20d0d915fbb8,0x00010ba519f94391,0x00091124074fa754,0x000066adbf6b50a5}, {0x000543c34bfca38e,0x000fd9e1ccfcc164,0x00020219ce0f2755,0x000979b9da0f53e8,0x00008234499a6b49}}, + {{0x0008b769d4c54230,0x0000b0521c49cfb8,0x0008700a19e56eb1,0x00058a418e0b5ebe,0x00000cbaad6f93cb}, {0x000fbded92a5e67d,0x000b4f347f11e923,0x000c0585bca4979a,0x0000e2b9162d856b,0x0000d6254b07c3c7}}, + {{0x000c513516e19e45,0x000775c4d5937b23,0x000e71ef656e2e84,0x0004c54f727d735c,0x0000b6304a7479a4}, {0x000a7363ab7e433f,0x00000e742f836638,0x0007fc19f1adea47,0x000697f054b8545b,0x0000935381baa1d0}}, + {{0x000ab2d799e9a748,0x000e2949f729546e,0x00090055a96239e0,0x0009b04a274c6b70,0x000035142c41020c}, {0x000667aa2e8807fe,0x00043aa3d39ea405,0x000fc72f529f2c08,0x000b3bec555d6442,0x0000856e0e8dbeac}}, + {{0x0004f9d918e49366,0x000652513982b550,0x0004d9cb965035ef,0x000508a553a0c26f,0x0000cb10d571ea85}, {0x00057b7a242da112,0x000d472b726848d9,0x00002a96b16a4d3d,0x00063b1d7e637c85,0x00007c7032b930d4}}, + {{0x0002b18e4136a147,0x000cf78e32bfbdc0,0x0009c3c03bacf969,0x000c4f598d89a3dd,0x0000b92420a93bec}, {0x0001f78c64d565c0,0x000010f28295d4b4,0x0003d051a9f969d0,0x000585ec7f7f76b1,0x00008945e1ea92da}}, + {{0x0006b7d5846426f7,0x0008b47d441d5536,0x0006fbf48e7d09e8,0x000d7ce10b404d73,0x0000fa003d15784b}, {0x000614f17fd95965,0x0000e5cb98db25f7,0x00083a76a49e0e0a,0x0000f7dc65957b2e,0x0000d40da8e1ddbe}}, + {{0x000c405050bad247,0x000d52aa4823f2b8,0x0008365a78918426,0x00068fbaeab3dda3,0x00002031717ec91b}, {0x000d69960a94120d,0x000d199eaeec8b00,0x00060aafd478a255,0x0007b2ef656a5f6f,0x0000fd7cb762dee7}}, + {{0x0008bb4a595939dd,0x00085874021737f6,0x000ad76120355647,0x00095ebe740e7c84,0x000089bc84460446}, {0x000da5d85a9184d6,0x000b3fc0b074f7f3,0x0008a888e562563b,0x000e7ba6d2e6aaf8,0x000012d8643761fb}}, + {{0x000dba7f64085e79,0x000399aa8511465e,0x000a2d188b230f30,0x000648c3388426cd,0x00000885735db666}, {0x000ff9a652f54f6d,0x00038fae2bf06f02,0x000f5eee365c8229,0x000d6fa816ade062,0x0000cdbdf44ccc56}}, + {{0x000bba354530bb24,0x00078b0869ea9fb3,0x000431163bde3ef7,0x000a3549bc90460b,0x0000d03d7d324819}, {0x0004f9e43b6a782b,0x0006ec88a68633ae,0x000ffedd9216db30,0x00083fe1dd88e000,0x0000280da9fc2bd4}}, + {{0x000cb8a1635e7417,0x000a08be02a732a7,0x0007ae030fe14008,0x000ce8cfafb3341b,0x0000fd508e7cadd0}, {0x0003219d607ad51e,0x0009ad40964a72c8,0x000878da20f229c0,0x000b853be2c3361c,0x00000c96743cab2a}}, + {{0x00086913e538cd75,0x000c3e08ad53458f,0x0005d15ffa7001f6,0x0005dd02b8c6e6bf,0x000048234a451121}, {0x0009d2d3d5b40458,0x0005ca904190ff5a,0x000607f8bb0ffeeb,0x000729d5a3aca448,0x0000cbd665cb0a06}}, + {{0x00034e0425830687,0x000b83f6e68387f8,0x000c1224802da2ae,0x000efbfb763e5d05,0x0000230378fd5a8a}, {0x00080b571e8e5cae,0x000bd3b6252493bd,0x0009c552e53ab041,0x000e653b8605136c,0x000084d402db5524}}, + {{0x0003573f37f59371,0x000dc1e4fca5a37f,0x0008ab0fceb0f6c7,0x0006ac1965a554ac,0x00007fbf56c37467}, {0x0006bd9acf7d720d,0x0007402247662e2f,0x000d53bef41fc8f8,0x0007d0817a14b385,0x0000ae327a64d76a}}, + {{0x000a065c48182672,0x000b17c1bbc16ad0,0x000392a9233aa189,0x0005ea44970b5227,0x00001699a1c4d153}, {0x000779cc2d7a7fda,0x0008f9c83cf2cd20,0x000c0b8c7e318605,0x000e4cfb69440b72,0x000081497d81b9e0}}, + {{0x0005c891f5f82dce,0x00068361079e515d,0x000a353309a7f67d,0x000e1ac8da81e311,0x000044990c52b18b}, {0x000ed95af103e596,0x00072dac9261c7d5,0x00094b8d3ece8aba,0x000e835e82b09993,0x0000830f09a76adf}}, + {{0x00029b488172d014,0x00058aff9e02250a,0x000a6329a8b20bd6,0x00092078a7661ee8,0x0000520304e13fce}, {0x000da1f2b47f7ef2,0x00083bffc540ae45,0x00064f874e07f528,0x000f38d799700934,0x0000244c2cdc6fa1}}, + {{0x0001ac194d7d9b17,0x0002582e7f1743c4,0x000da0fca5bafdd8,0x0007ad6f0614c15f,0x00004b043a818ae3}, {0x000afa19e71734c5,0x000e4c450f2e3ba6,0x000e242b115d5437,0x0003c1fa5883fe67,0x0000143bdc27c195}}, + {{0x0008b53fc5e89202,0x00087a9cee08542b,0x000486e08363bf9a,0x0000d1e2375f10c3,0x0000037543bac5e7}, {0x000bccc625640b46,0x000e2bc62c3b7109,0x0003f26eacbc1051,0x00042498455fed80,0x0000badceac4b372}}, + {{0x000ce7c6b53f5f95,0x0004cb176d99a2a9,0x0005c081b6424659,0x000ee661298d36b9,0x00003505bb86d9a9}, {0x0009e61f2ba70b0d,0x0008bafad4533f6f,0x000eb4a6ad07e16c,0x000c8dcf1694bbe7,0x0000febceda0cb0b}}, + {{0x000dcdc53868c8b3,0x0002086107a692d3,0x0009b4e64174311a,0x000cb61109e07c68,0x00000e4587f5df3d}, {0x000ea310811b3b2d,0x000c3cce43ea841a,0x0009a78036144d41,0x00092f764c45812a,0x000003d37200e158}}, + {{0x000d7f2b1f3390b4,0x000c65b61272c676,0x000e127a99f7a1b8,0x0007bf0ebebfc9c2,0x0000602500c9dd99}, {0x000771c4711230f9,0x000b720f09c17f09,0x000e5e38b058eb37,0x000bc01b693d4bfe,0x0000289eb1fd653c}}, + {{0x00046abd51b9cf59,0x00020f0121afbecf,0x0000dc274d2aa9c0,0x000a3ba6aaf7d2e9,0x000009e4ea0d8b95}, {0x00004966f32dbdb8,0x00000b030b3ee6b7,0x000b617e2672188a,0x00009e6effe5b3cf,0x00007e947defc827}}, + {{0x0002b391770f5a7b,0x00005e44eb82a44d,0x00069712ae4d4d79,0x00020d92e69d1e3f,0x0000f11c4d75c6a8}, {0x000f3e542c4224c6,0x000be49d941cb5e7,0x00050e878d6b4e81,0x000c53fd72bd1654,0x0000a61e28b4e25a}}, + {{0x0002094e6f1cd952,0x000ced18673f3327,0x000fc14647512f30,0x00077b12f7a4ca5a,0x0000f0956568bbb9}, {0x00047caa82262004,0x000cdac07369586f,0x00013acbe02c868a,0x00054c0ef2b845c6,0x00003d7563e43860}}, + {{0x0009dc7ab952578a,0x000186e84d0b54da,0x000872042b5423df,0x0006df08b64eeb9b,0x0000c205782f990f}, {0x00096eb21f4c77af,0x0003bab273af4ff6,0x00036b3f11a79c3e,0x00027939bc922e94,0x0000f807ef9c6d9a}}, + {{0x000ea3d778f22a00,0x00085b5e746982ac,0x00018ee7dfb10b2e,0x000a2fc0b1698028,0x000011afff4c91c1}, {0x000d126ad124418d,0x0005172e295f95a6,0x000f4db7531c081a,0x00046166bb283af2,0x000011554104acef}}, + {{0x000a8f833f6746cb,0x00054ea990cac7f3,0x000ddb0a921e46f6,0x000554e15fd5c5ca,0x0000d41f01728614}, {0x0004434426ffb589,0x000584dbc204346f,0x000969b7f8055943,0x00039a63dd20fe5a,0x0000d59e9577899a}}, + {{0x000971c8ad4cf4b4,0x000feffb8fb8f1b0,0x000340ba40344885,0x000758b071ac3c65,0x000008d0596f27fd}, {0x0008ea498c364b09,0x0004751e8ab5e7c7,0x0005d9002a4aac4a,0x00045529e1d56048,0x0000acd518b18844}}, + {{0x000688fd06f56c0a,0x000d3f027972e4ca,0x0009a609da48af70,0x00070dc91f0f045e,0x00009dd82ce8e612}, {0x000ca63a0ef18d34,0x0004fd6ca3bd8903,0x000f47d039fb7ee3,0x000e8e67b4a09cab,0x0000cdada015c67d}}, + {{0x00037499355a244c,0x00058f2151a95200,0x000b4efcbe77fd2b,0x000e24a95d6cf666,0x00005a0cad09a2cf}, {0x000fe5cef8118650,0x00089ea5cc3d104e,0x000b58dbcf52813e,0x000b11855683dc40,0x0000338ecde175fc}}, + {{0x000563774921592b,0x000d09bb9d31f9a0,0x0009c5459b4f1261,0x000f52a51429b74e,0x0000e182e701ea71}, {0x000b07cdfc50573d,0x000992be8d44d3a3,0x000ab65d39ba1afd,0x000801cbcfd2cb52,0x0000f11d54879571}}, + {{0x00003ee02a2404ab,0x000371088a710994,0x00004ae71497406f,0x000361e947940950,0x0000db420795812c}, {0x000a30fd88284423,0x0007ccb5ed1c2b72,0x000a40015283add2,0x0005efc7c0e20066,0x0000e3be64138b29}}, + {{0x0007dc1e038a6759,0x0002fc5c6320ac12,0x0000d2c53729deff,0x000cd327df8fd4a9,0x0000b74b0ecf81e7}, {0x000a623dab407e5c,0x0004b6b340c65cb5,0x00028392ccdbd361,0x00082fe184415a7d,0x0000184c1d9a96f7}}, + {{0x0004f1981d3a80f5,0x000178e02432c320,0x00049e0c1fde0c84,0x000a7328203b3e81,0x0000904bdbb58053}, {0x0001dd1101b68053,0x000c19aa6d4930fc,0x00017408743c223b,0x0000086ed671417a,0x000011469a105997}}, + {{0x000b6845e43fc616,0x000580d3ab57b189,0x000181da8f328237,0x0002b7efa34b67b1,0x000021ed0b2f9ee5}, {0x0008de1ad9906763,0x000b26d540659b17,0x00038c201d51de67,0x000f5bfa2c27c475,0x00003856ec868a40}}, + {{0x000fc15be6cdcde0,0x00039f0c6f892522,0x0003e30a61e603f3,0x00053e7994edc310,0x000033a00db220c8}, {0x000a409f7bb7fd76,0x000de62d18f6d3cf,0x0007fe29570f8781,0x0009f35bd8298068,0x0000eef4c32b9566}}, + {{0x000303b2f7e85c33,0x000141988f9b86a9,0x00038acb55fce462,0x0002122b935bf6c1,0x00000ea7d6755661}, {0x000b5f4e51ab9a22,0x000a8e067c78ef1e,0x000ca9ca60587c98,0x00005793ce1b3c77,0x0000a553d4d74b5f}}, + {{0x00082364da29ec28,0x000339c57316c789,0x000d80d47dbdd5d1,0x000391457d6e6b2c,0x00000b460d07e9e7}, {0x0008cabf963c31e5,0x00037c4d32fd9864,0x000f7c68767f9f63,0x000ea6baf42a9dfd,0x00005f292a35b015}}, + {{0x00068b2cd21ab3de,0x0001e393d39289e4,0x000013af9e504f02,0x000acacb21e1d4a5,0x00003283f79a2c28}, {0x00035f6226bf99fc,0x00034e291e69f38b,0x0000c162de835427,0x000dbda1673a15b2,0x0000101dc76704fb}}, + {{0x000b4c2255bd6178,0x0002ec2a91548323,0x0006793876c96969,0x000e2346e6586062,0x0000e01db0d38c88}, {0x0002873893a55595,0x000af7a3e14933c4,0x000cf35f87630f04,0x00073265d80805dd,0x000082ca080c7dfe}}, + {{0x00056e10b1894a02,0x0001b81c68c02c71,0x000b115b59203400,0x0007f2cd225d00c8,0x000037f9c22a3b90}, {0x000f32f4470e2c05,0x000108be4e950ea2,0x000ae5463b725f7c,0x000c03bf1dcafab1,0x00009ed51876ba2f}}, + {{0x000f316d0115d4d7,0x000f63691599f6e0,0x0007f0a415180b12,0x000cbfa57e32c952,0x0000b0b081e18e0e}, {0x000aa8abf4f0dd06,0x0006ed2526966dba,0x000f864fe99b289c,0x0003ab19b7755edb,0x0000974e2b1d6cad}}, + {{0x000bee206ddd6572,0x00010ff3a96d35db,0x0006be758e7cbdd1,0x000f5d6838196807,0x0000d737e7228c91}, {0x000ab6286ec37766,0x000d345fa7a15f83,0x000ef093398aa649,0x0007b19477ec3772,0x00006f52b1e698c1}}, + {{0x00058fbd803738b6,0x000784e86aa49eec,0x000b5149291aaade,0x0009740b1ae617a5,0x000032721221bc45}, {0x00028f0862c51290,0x00093321a4a07e0e,0x00041c88f0a8f79a,0x000e3ae26d166450,0x0000571b80553233}}, + {{0x000ccdec95207114,0x000cfc8b84bfd1b0,0x000fef31455a9e4e,0x000f2b5426bd39a1,0x0000f5f638eaeb93}, {0x0001ed32bf9341bd,0x00007d42d5a9ba2a,0x0006dc7c5d63c132,0x00085102964a8931,0x000017596079a511}}, + {{0x000201ff9e6ed353,0x00053736925ad8a9,0x000581af7b7b5ee4,0x000050da83fbbc99,0x0000076bc4094eeb}, {0x000c98c02dec312a,0x0007838dcb785511,0x0009c08c9270de89,0x00006d8cf4cf9c53,0x000070cb65ed8d3b}}, + {{0x000c10ecfe57bbde,0x000555a0c2b5b12e,0x0001c67bd82c7b65,0x0002cbfdc7d5cd16,0x000032e89868e3a3}, {0x0009444d11a5529a,0x00018427fa1a7aba,0x000a1770ae964ed0,0x000fcc7528392d24,0x0000152ce2cb2c72}}, + {{0x00053a48ec07649b,0x000f959dd4537145,0x00064b11018b4c28,0x0007a23a32b7147b,0x0000871bfa5de6f0}, {0x00012e59e2e3c9b3,0x000514aa90f6b671,0x000539006fbf250e,0x00066fc77aedb8bd,0x0000b0cdf9b0172a}}, + {{0x0009feaf8c511875,0x000c241e4da7edf6,0x00011434505bb67e,0x0002b0f7df0f3208,0x00006facb080b979}, {0x00007e98f6229e49,0x0003c26fba0ff3e0,0x000339d7962d103f,0x000ec0bf33bef7b0,0x0000841357c459bf}}, + {{0x000bb59c34e67058,0x000affdaa84cfa8d,0x000108537c3c7180,0x000e5a795872fca4,0x0000750cc3c132a3}, {0x000c69db7275d7d1,0x000b1e59b2e9b61c,0x000cbb493ffa0168,0x0002d8ba032abc6e,0x0000d86dbd33c908}}, + {{0x0000b67e28ef5ba5,0x00097b18e169ae1e,0x0006bbd202c9a469,0x0001d1becd0e331e,0x000071b360eff5e8}, {0x000ea58101c1d454,0x000dd8880452cd9f,0x0008dd4466651788,0x0001d0699726351f,0x00004bed02323728}}, + {{0x0002b2d33da525d4,0x000dd3144fd8094b,0x000c1061df193678,0x0000f478ab5ba4f4,0x0000343b5fb1ccbe}, {0x0002371638127137,0x000d87611d93a870,0x00021e1d747bf6d2,0x00077cd6729b8cbd,0x0000484d4e14629e}}, + {{0x0006eea60dbac1fd,0x00040a06a2f7830e,0x000ca535b23d8c48,0x000a9ab96714b050,0x0000c8d3645bbd97}, {0x000f9fab12177b4c,0x0003934d5d9c106e,0x000ab360bf79bf46,0x00044e6537a349a6,0x00007c54254600c7}}, + {{0x000a047e5911a766,0x0008047f1ee7b3c7,0x00056ab4261ffa5c,0x000ac8b5aed36f8f,0x0000a0d41b103ff9}, {0x00069f5cc30d3577,0x0000fb72be9668f4,0x0003ad461be9adf8,0x00041aacd926fe90,0x0000e89e3903aca4}}, + {{0x0002de5facf69d43,0x00061775344cf0f8,0x000e36d04363b7e7,0x0009a53894f312b2,0x0000c6cb4fe41d1c}, {0x000c3394008e1f2c,0x0009649f326c85d9,0x0008c5e065e9a85e,0x000ba91c35c60a67,0x000008b94505f86f}}, + {{0x000c02c89f71f0f1,0x0001ef3da3c0de40,0x000125dedad8f3e3,0x0001832ea5096b42,0x00003879cbfb7379}, {0x00014a56b306a0b0,0x000667646c5e6f47,0x000726368359c2ea,0x00031efacf894307,0x00007a5893565ff4}}, + {{0x00061d168754ab0e,0x000c8f429a7624d6,0x0008ce769801fce1,0x000a2ae068a85fa5,0x0000dc35c553d5ec}, {0x000276fa3f660d1d,0x000de8fc7167ea31,0x0008db0aea0184eb,0x000e113f20f21a1d,0x000096d096026c35}}, + {{0x00002b5f8c2a25b9,0x0008759204b6edf4,0x000b4e34c1bb772b,0x000459c0cbeae219,0x00003109d80cfa08}, {0x000ccf78ef59fb59,0x0001f807096354f7,0x000f3ba9b3b438fe,0x000a920e28c65931,0x0000cc31b477ad9d}}, + {{0x0000ba9b733aa5fc,0x000b305af2353c2f,0x000ac82a5dece47c,0x00018a38e3f715a2,0x000097ba641e203f}, {0x000550409c110608,0x0004c6af512dc3af,0x000f2814656ea2c0,0x0004947ac28daff3,0x00007fab43b159ef}}, +}, +{/* digit=18 [{1,2,3,..,}]*([2^126]*G) */ + {{0x0001641d4c5105f3,0x000e3d7fbd650989,0x000e6bdb01ae80f8,0x0008606d67225fbe,0x0000b433b59afc4d}, {0x0006db693e856387,0x000273e9862f44e6,0x0005c32ecf7b5925,0x000f506b78515766,0x000002fefd81e362}}, + {{0x000475d0fefb0c3a,0x000aa6d7c35d3754,0x0003798a4d48fb56,0x0008e60070b63336,0x0000e89f3d32fdb9}, {0x00089c86363d14cb,0x0000b7abd27d970b,0x000d5a0218981752,0x000aedebf7d47444,0x00003083bb07ac72}}, + {{0x00041debe949a447,0x0007e46a4fa53897,0x000047bdc638e938,0x0007c9cfe6419ca0,0x0000047f6491aea5}, {0x0008a9041fbab170,0x0008576bdba254e4,0x0002afddcda8e0b2,0x0007bfe807eebcc7,0x00007d3336df4257}}, + {{0x000c244bfe209256,0x00032fdce86762a8,0x00038706391c19ac,0x0004f5fa96a5d5dd,0x00001d587d481d32}, {0x00073a2a37173eaf,0x000763778b65e876,0x000bab43e2384800,0x000fbd20f8441e05,0x0000a11fe133621e}}, + {{0x000772e81685d7b3,0x00018f34a976047b,0x0005f48ef23f27d8,0x0005c3927608e291,0x0000b0b43fad521d}, {0x000fb2663ca72840,0x00041d4db8377613,0x0003b526b7f5729b,0x0003d187b1489858,0x00000b732a6bbadd}}, + {{0x000f4262048e3968,0x0005b83d9de48e02,0x0001e85ad436b50b,0x0008d6778d348147,0x0000b01ea6b5005c}, {0x000afee97015c07d,0x00087e3ba2aed3c7,0x000d3a1d246cdf1a,0x000ff3aa42e50183,0x000054b52698541d}}, + {{0x000cf304e23e9bca,0x0005726e36243f24,0x0000b6d614387f81,0x00077b86a46a033b,0x0000f1bc8462b2d7}, {0x00001ba527de79c6,0x0003e261bbb625c4,0x0007b4bc70e1346d,0x00062eeb96c44b28,0x000058493c7b2545}}, + {{0x00049feb8a24a205,0x0001a52ca53f23f9,0x000fb485317ebfed,0x00005d4b691bbebc,0x0000617ff6bb278a}, {0x00034c5e3c99ebdb,0x000d6784156a241b,0x0005d67dffc64242,0x0000109206482f69,0x0000967ce0f9e27c}}, + {{0x000375121c80b5d3,0x000c731ecca065db,0x00038a07e2e7a563,0x000854b56ffc4e52,0x0000d6c296662ced}, {0x0007d1aaf70b8855,0x0008dd686459e99d,0x000c8ba5bafc3bad,0x000aa34c78bf460c,0x0000a43951968955}}, + {{0x00017a85fe4e3142,0x0000dcb8906ff8b5,0x000061b23e60234d,0x00059cdfe542acf2,0x000087e191f8b4cb}, {0x0007ddc09d877d88,0x000b946789412185,0x000e05ea41c23478,0x0004fe3bf0c056b6,0x00002da4b5430159}}, + {{0x0006791fadb86087,0x000d0b74cdf6f752,0x000b90a34049e832,0x00010c343581ccc2,0x00003639eb90360b}, {0x000331fe1e4a71b6,0x00032072f9194fba,0x0006790326ffd6b9,0x0002ce0e53271c65,0x0000720644551427}}, + {{0x00034a3b23358342,0x000a70ef6860c0f7,0x000e2bb0d9526205,0x0003faab8be71704,0x0000418871e22f38}, {0x00076814082c1576,0x000fc9c20073d717,0x00087e728cc914ac,0x0005fd9186c1ebe5,0x0000fdb3c22c1bcd}}, + {{0x00014a6f2f9f8e93,0x00031fec49d230d0,0x00005a8d9963ece2,0x00029a562025c596,0x0000987444549f89}, {0x000ff6512bf476a1,0x0007f9cf7d9101b6,0x000be56ca598a64d,0x000615c7ec774993,0x00000899785dbb33}}, + {{0x00092fd02eee3ad4,0x0004f0145270b8a0,0x00012b675a86b3d3,0x00040ef23d98c685,0x0000b8bc785a2ebb}, {0x0001f54413f9cdef,0x000e3bab56647d30,0x000bfec23a5e4fb4,0x00020c2d2b252d1c,0x0000cd576bcd1771}}, + {{0x0007d3e83731a34b,0x000e3d836e8e0442,0x00012ca7c2bb9028,0x00073a036acff8b6,0x000088fe5f083d9c}, {0x0006bc6edea4eb34,0x0003088eec77be2a,0x0007106e143b9313,0x000a32b41ff566b1,0x000069e9172a54ef}}, + {{0x0000f0441c23fa36,0x000061989a2eb448,0x000a29ca7b4712eb,0x00028bdccbba0f93,0x0000e205c1536194}, {0x0007957b36416860,0x000d45ac8b4e90db,0x0004e03500432691,0x00051707a759acf6,0x0000514d89c9c972}}, + {{0x000147fa8e67fc38,0x000b2b2085be1701,0x000284e579e2e0b8,0x00066455651824ac,0x000090d4325f4893}, {0x0005e6ec55e68a39,0x000ab339c85a8a7c,0x00022b655bf12e90,0x0006ffa1846b85f9,0x0000a54ce4d9bf4d}}, + {{0x000e83af1a142952,0x000c9285d4f9d7f4,0x000ffdaba916f955,0x000152c57bb0e099,0x00008a430350ab0d}, {0x000ffa2b8a9cef88,0x000e39ec051a0a36,0x00068e6725517407,0x0007fb1c796096ea,0x000053db5fc7b3c7}}, + {{0x0004ba9e864a51ae,0x00088e8a1b8b2147,0x000120a286c26769,0x0005da9c82362694,0x000061e9a496383a}, {0x00050039f84216d6,0x00074d43cd857dd7,0x00012c659ab020d0,0x0002ad3437ae48da,0x0000449c2ec46545}}, + {{0x0004c1c2cf9d7c1c,0x000a2e95e5abcc7c,0x000ae170c1320886,0x000661fb7b9056be,0x00008a5b2519bc0d}, {0x0001432c11d23031,0x00020f03769f4ed8,0x0005398287da6691,0x000d022ac7a5fd84,0x00004dada944bccd}}, + {{0x000c3217ef6b0d15,0x000a2c933f228b84,0x000440b8252a9477,0x000d5e0ef6728afd,0x0000c3bd859bce4b}, {0x00080f5f22c2d3e6,0x000057bb6cc5918b,0x00095a11c368d504,0x000a70566142a126,0x00000ac583b4b19e}}, + {{0x000bb980eab2437e,0x00047e2654c8317c,0x000d8307f8cc08c5,0x0009931e2d6520e6,0x00009f147f437428}, {0x0007d14d2fd6cf16,0x0003cd4fcbb05f9c,0x0007341f7a3ecd06,0x00015c4d83fef08e,0x000043f23a09a631}}, + {{0x00078abe65ab743f,0x000045edc89cd38a,0x0000df568bf7c75b,0x0006814dd8752e53,0x000085c4a77d308c}, {0x00055b2e68acf374,0x000d6b32af854c99,0x0005cf493a544df3,0x000feb0b8ec3f5a2,0x0000d8f27645a622}}, + {{0x000f7aaf0dcbc49e,0x000890bbb45b7bb4,0x0002ca2e57de551f,0x0006eeefd0f3e49f,0x0000ce58709ff5c7}, {0x0000edd167d79ae1,0x0002ea7d7ec13292,0x00030af91039df8a,0x000b59e46206c0bb,0x0000ff5e2f532676}}, + {{0x000a0396ea51d668,0x0005007d7a2611f4,0x0005a9b24506c144,0x00019de0da570575,0x0000fc8cc329f1a3}, {0x0002d4d9433d67d1,0x000f5a7dd2968364,0x0007bde077fa5cb8,0x0006fb476591db9b,0x00003173d2551971}}, + {{0x000599dd5b340fff,0x0006c0fe76c5ea30,0x0008f5adcfc6b529,0x00028c2c6968c8ab,0x0000723c7f6801c9}, {0x000c3219773d4025,0x0002cb51dd474203,0x0002be23cdf7c6aa,0x000e86ed49e37a55,0x00007febee85b5a6}}, + {{0x000bee47bd8e7397,0x00043e63bf75c5ec,0x000fb892379d4499,0x00012fa68bd00f38,0x00005d48ee540533}, {0x00077aadb5cdf33b,0x00058c696769554f,0x000fd674e3396e89,0x0003e47fdddbf2d3,0x0000bb8f6ef49d0e}}, + {{0x0000651cbae2f701,0x000583aaa8eb51b9,0x0001df499efc4bc0,0x0007a57ecd8689dd,0x0000aee99a832f36}, {0x00085b9ae8274c57,0x00050d30b39c95d4,0x000c1ef816c14d44,0x0002ed4afea90bbc,0x0000c5f317b1459a}}, + {{0x00010754ef442271,0x000ecc20f4960121,0x0009853cda17bed6,0x000ce6fcdfe42481,0x00003793299071e2}, {0x0003078dbbe307b4,0x000e36ee99363c1f,0x0003caa206dd1c20,0x00040de3ee4b5742,0x0000ac3793bcefb8}}, + {{0x00038ebed1f8ca0c,0x00078ebb25a29344,0x00069896f3e54665,0x00043d0415af0ec0,0x000013eddb15a5aa}, {0x000204fd49eb8f61,0x000cc74f16707a04,0x000fc0558d0d5bdf,0x000ade2697e28656,0x0000020737111ceb}}, + {{0x000e6900647a82b8,0x00040f40054f5f87,0x000853803908e0ed,0x00025229f633d479,0x0000ed13c9aca28b}, {0x000f6761f460f648,0x000ab6d063363e2e,0x000c4979b53930b9,0x000596b47073ac8f,0x00004380e0edecd5}}, + {{0x0002c6bc4fe3c395,0x00031c7bebdfe3b2,0x000693459ba4a815,0x000b11a23ab6b725,0x00003bc377064922}, {0x000c8ab5afc60db8,0x0004a0b9f2a34645,0x0000fc507aa02235,0x0002e6d2a2954cce,0x0000c2731bbfce1c}}, + {{0x00008ab18a0339d4,0x000cf735436cf396,0x000992b4fac7a658,0x000fd4722c2b07cd,0x0000e83daed340dc}, {0x000c7be2f39ea3e5,0x000f60a56d2e8a34,0x000dd8038ef0c005,0x00007512731f6a6e,0x0000721d7409e3cb}}, + {{0x0001511fbeeee1be,0x00030f1d0c051ea4,0x000c07d35d1ef5e7,0x00049262feefd173,0x0000530a00b6a329}, {0x000b7fef15ebfb03,0x000ca322491a5d55,0x0005b3237549de03,0x0002b6c7b5f60274,0x0000632a3a24ab6e}}, + {{0x000ba890ef59f78e,0x0002e9e52b9a0d3b,0x0006314470dfc644,0x0000b03dc7969972,0x0000f03391893be2}, {0x000735db13839481,0x0002b0dd7d7d0c92,0x0003ed068c1fc29a,0x000bdc5485b69740,0x00003bfaab3bac93}}, + {{0x000c6a90deeaf523,0x00021c641c15410d,0x000c504c4b003fb0,0x000a76e384978c5b,0x00007640487b64a6}, {0x0001bc6222a77da2,0x00073e47eb110599,0x0001b432c62260a5,0x0003e9a7af6613f2,0x00002f3acc9cb495}}, + {{0x00049228e41d155c,0x00077ac059ef5293,0x0008844114d02456,0x00078ef02017554d,0x0000e8055d0659a1}, {0x000d1aff62045490,0x000ec7066759cd77,0x00072c229a0a00a3,0x0006b0471071ef02,0x000009bcf6bd3c4b}}, + {{0x00038a822305177a,0x000ea1645bbf2a26,0x000a7a3c0d51d59d,0x0003ee081142fdc0,0x000017eca6dec706}, {0x00087ed60d9dcec0,0x000120ad24550bb8,0x0007102bad6d28e5,0x000408ebed6308a6,0x000042c31148bffa}}, + {{0x0009ac58aa68e305,0x000bc483513efd09,0x0002d8f0c7a6a3d7,0x000954afcc6b75ba,0x00004dacf966e78b}, {0x000696fa4a9af892,0x000fe6ac98ecf645,0x000a67a203a41193,0x00062621b8b3f622,0x0000d0b1e0fb9dec}}, + {{0x000919240be34e8c,0x0006d1907f3527c8,0x00056702bc7162b3,0x00069bd0188ec1a9,0x0000a132f7e9f937}, {0x00044f90e2025b4c,0x00084c62f14c3ece,0x000e3cc1167aaec6,0x00050ded74141822,0x0000f9b75c43ff9a}}, + {{0x0002b164d348272c,0x0009d959d56d02fa,0x000762916bd99d61,0x000c7ffc4f19db18,0x0000c7cce5109c1a}, {0x000ebaad846bd832,0x000c892028494d59,0x0001f4ca98775a9d,0x000f10e7ec4ae16e,0x00007eb5875da893}}, + {{0x0004d51662cc565f,0x000a1db4138d0028,0x00032a59482353a6,0x000c46e9c7aaaaaa,0x00005528b5f95669}, {0x00002312f23c5ff3,0x000a3affa3a1f322,0x0002ddda0e3e8147,0x000bd4cb423d5c20,0x0000d6414ac9b871}}, + {{0x00082e1a51a168a0,0x000148ae5448586f,0x000233eb8b712c67,0x000ca99a2e4bd176,0x0000188223a78811}, {0x0005e21f7c18de1f,0x0000c27bb286553c,0x00051e9297682e45,0x00034e4ed036b30e,0x0000487211cdc9cb}}, + {{0x00042770c24efc82,0x00049ef737a40d09,0x0004cdd280349fd0,0x0005214d1c9dd251,0x00009c135ff50da9}, {0x0004508f78b0b6f2,0x0002478c143cea6e,0x000e21e65176f5dd,0x0008c3e81484184b,0x00007f7525d07df3}}, + {{0x0000e09748ab1a42,0x00003efe44331fb7,0x000f75af29cba50a,0x000ea85846c7a615,0x0000a7c2c577ee73}, {0x00066a43f0a449a3,0x000b7d90fc3d42e5,0x00061d05745474c3,0x0000924447be3d8b,0x0000e9d1cf16a4ec}}, + {{0x000e453f380a6e68,0x00011b1437c21603,0x00029610a0b86e43,0x0007f6fa4173f2ef,0x0000fa729a8703d5}, {0x0006f6e6c9c217e3,0x0009619195243e18,0x0003d4fb1be1d307,0x000f7162a62a7015,0x00002ed3e35068c2}}, + {{0x000027f9eb1a8b70,0x0007c5b22fe8d785,0x000d6a191bc37eb7,0x000816466b34f0b9,0x000008a89af9a05f}, {0x00028fb7d42c10ab,0x000e99b3f6b819b0,0x000a0ade37fe8c92,0x000a7ba8907cc0a5,0x00003154f52059d1}}, + {{0x000efb6d9790ed61,0x000c96aa793b5066,0x0003e042ea77a0cb,0x00074b0a915f3c22,0x0000c5def0479c58}, {0x000007873b6c1da8,0x00027cd8557a0e83,0x00060f3b155cf85d,0x0000628f7c7c7604,0x00007052acbc6e58}}, + {{0x0002b80907eae66d,0x000f7d721c890921,0x00045ac1c3cb068d,0x000dbad87941aedd,0x0000e8d5c0dddaa0}, {0x0001fdce3502e6ed,0x00007d89a084da42,0x000c24bfbc894420,0x0000eea307ba5ef0,0x0000a212bebf0bde}}, + {{0x000a24bf82ce682c,0x000547f71fe4ea2d,0x000fad8de058d381,0x000faa75a024625f,0x0000d7b05dd6adce}, {0x000f8ed1d9f54ec8,0x000832d3b5cad442,0x0006b2ce28be3d61,0x0004c062220ed0e0,0x00002699a5f9b0da}}, + {{0x00006f571c0c3a75,0x0009bd34180c3ff1,0x000d7d3758f580f5,0x000674febb120e22,0x0000e5782cd39513}, {0x000580c99c82a70a,0x000e75ea8c4c2275,0x000415e70e8359fb,0x000013b3b48db87b,0x0000acf2240b00c6}}, + {{0x000ccf5e4652f1d2,0x000ab56157b29faa,0x00061ec50bd6fdd2,0x000d5284f4fb1f62,0x000044e55ad676bc}, {0x0009305047d320ba,0x0004c181263f881c,0x0008fb8ee1ca983d,0x000963954e9a4427,0x0000d2dbc0fd96e4}}, + {{0x0003aa29268b3de0,0x000ae6e0609a723f,0x000f442520d1ca29,0x0007ed794866aa6c,0x0000b59f3e301af8}, {0x000e5ff7f4a6c51d,0x000191dc2f7ee234,0x00094d81fa8768fd,0x000ce10afc73320a,0x00007f84282d6938}}, + {{0x0003c0e0546063ea,0x0001bd61abc6ae0b,0x0009ac4007fbadcb,0x00010c35d7a2c936,0x00005978d0a4e67d}, {0x000211e4f85eaaca,0x00015acac681290f,0x0008384cde61e2ad,0x00030f0e12522538,0x00007fb68ea6cfde}}, + {{0x000b9363daed4c29,0x000f9606f7897a59,0x000a6d90a80a9aa3,0x000885240c1ea5f6,0x000048364d3e14d5}, {0x000bc6070985182c,0x000d73310895062e,0x00029c2f5a6db5b0,0x00037da4a12175e3,0x00005f25bd350ea2}}, + {{0x000c5242d0a4c230,0x00046bb3cc527915,0x0009e2c92eb5d26e,0x000cf8369a9116c0,0x0000c527f92cf182}, {0x00019382aede0ac3,0x00083cc349399e59,0x000a34361b292220,0x000fe60c9d896299,0x0000c81836df1905}}, + {{0x000b57fa001ec5a8,0x000b20dc5dba4bfe,0x0004a1380e993f5b,0x000a03c788410972,0x0000a0369abb2fe9}, {0x0008d608c927db84,0x000f54655741ea06,0x000b6c7eabf5f37c,0x0009cb07d402a204,0x0000551c295aaf25}}, + {{0x00071e7ed77ee8ba,0x00005309d5c7698b,0x000e780cabddf7bd,0x000ef3c201c22c34,0x0000b04f7d8ec295}, {0x00072944313a8cee,0x000bb2ca4cfe1c94,0x000a7a97ae532e4a,0x000d5aa9738f80d0,0x0000c088c898580f}}, + {{0x0001ecc42ce9e515,0x000d625fdd2a612b,0x000e7f8398f9840f,0x00047fecda78c001,0x000046b3d3b3ce05}, {0x00019a980d309162,0x0007384c20c42717,0x000c786084549710,0x000a4c8f8f94785b,0x00008c7d484477e2}}, + {{0x000176788a2ffe41,0x000518e169a5fce0,0x000f9c93adc506a3,0x000e07fea108617a,0x0000ed2436113fa0}, {0x000aa92a3d694e78,0x000d6f50bc7496ea,0x000114db4c0f43b4,0x000fd44e6aa58c64,0x0000218e8eafc000}}, + {{0x0005dfb185f88448,0x000a9557abfbac81,0x000bfecdfcd7e90c,0x000c49a3d16655af,0x00000f3271f885ca}, {0x0009aa7d0e62f477,0x0000d60a48e57fc3,0x0008f101e88d519d,0x000815e9559ac4d2,0x0000981d9ea3a9ae}}, + {{0x000652c9ac382032,0x000f37657fe55c38,0x0001f541686eaf87,0x0007b5368fc472e2,0x0000afff39d07e59}, {0x000bb07256d4eab9,0x0001f285ab893adb,0x0001caefe2259869,0x000c8aa5f8112a04,0x00005df02e435064}}, + {{0x000356ec7004bf30,0x0004db83c7de4d63,0x00009a7b7230a08f,0x000d2dca27b27087,0x0000d1c4cc4cb9ab}, {0x000c66e7550fee88,0x00071cf7247e8a0b,0x000b5b7e7369cd4c,0x000f7af5562e8492,0x0000fed0da0d802a}}, + {{0x00091c2e48fb8898,0x0002fb8a9d066a70,0x00082a0e226882c1,0x00052d224986631b,0x000044ed736b5181}, {0x000476fd86e27c75,0x0009b4afefdc282f,0x00019e34da04edac,0x00078b3b256ebc61,0x00006a413e95787d}}, +}, +{/* digit=19 [{1,2,3,..,}]*([2^133]*G) */ + {{0x000061d5a74be506,0x00047ea16ff582ee,0x000bfc8a2e41781c,0x000e2d80b0c81e99,0x000024f4d696b547}, {0x000545dbdcc9ae4f,0x0005509b1e8e3a83,0x000c935392573dbb,0x000797582960c4a6,0x000001059ae4ae18}}, + {{0x0009f973112795f7,0x0007284e6ee1715c,0x000b66bcde824443,0x000bede5cb4858ec,0x0000c1367361baff}, {0x00015955dbec38e2,0x000c188ad1535466,0x000e0952f51c0782,0x000fa87ba4c53ac6,0x00007e6782a3b21d}}, + {{0x000903d4ed2dbc25,0x00082c3b2d83682f,0x0007e93350eba59c,0x0006d73e9dc84d9c,0x0000f9b21b05eb22}, {0x000d394af267bae5,0x00056e2e15aee33b,0x0008ec500aa86cc2,0x000657ff0bf67d6a,0x0000846aa4549630}}, + {{0x0009740e2c2bf152,0x000589e99704feb0,0x000fbc565627a220,0x000de8cc8d73d0c2,0x000023eed8fe20c8}, {0x0002583a8363b49a,0x000929c2b0a61ee3,0x000dbc85c1a0b6cb,0x0001aba9f7c3d290,0x00008dfbb97bef4c}}, + {{0x0004d4c65c7c2aba,0x000742c5ea84afb3,0x0003c4ab51d4610e,0x0005c3e93f6d1b97,0x00003cdd7ea345ba}, {0x0004983064417ee3,0x000c7d6bdf2b6051,0x000f726c31459b23,0x000549f3b2c3415c,0x0000a82963562d63}}, + {{0x000901fab192c181,0x000e6030164f294f,0x000246ba6ec5fcbf,0x000a0cd2e2fcb7e2,0x0000e7c88b3321a1}, {0x000dd93c92d88c5e,0x000d3106fb5972c7,0x000f60f1441c2148,0x000f30747dd4f5a0,0x0000d9b52b343960}}, + {{0x00049ebb0a5b358f,0x0001ae7e2ed66c83,0x000a462dbb154c5c,0x000b68dad5eccfed,0x00002d6dbe51de66}, {0x000edf38665e5b22,0x00035b7f5723426a,0x000cbb386488a851,0x000878f5cc43b38b,0x00007ad0af3f791d}}, + {{0x000236e846e364f6,0x000c7ea50ca0c16c,0x00026b86d7f33527,0x00070c6481077509,0x0000c2a36096598e}, {0x0005e52f024e9245,0x00044db4afcaa675,0x000831790e0fa07a,0x0000d5c5c3ce7d66,0x0000b4ef350f6cbb}}, + {{0x000afc4b6205969f,0x000206c7854f2c4a,0x000983b4842563f0,0x000754116aced51d,0x0000eb356d989949}, {0x0002c81d1a39bd77,0x000f76934ae98c2a,0x0007904da8f44340,0x000925a48cf91c44,0x0000340185f7f51a}}, + {{0x00000fb7409ab463,0x000650e289b22f8f,0x00088e5d1057e78e,0x0004e1d3e5022ca8,0x0000c87111acdede}, {0x0000e1c7809460b4,0x000231c9abc75b9b,0x000cc1dc9e751c85,0x000a084b944e28c7,0x0000f201ffa5d3cf}}, + {{0x000905c3e6721cea,0x000a30b3674c02fc,0x000810da4d52d70d,0x000d98bdc2e5ca18,0x0000984b273fc69d}, {0x000252784de5ca41,0x0002b852dec463b9,0x000e3de092f1c987,0x000c2f08b03593c2,0x00009d70b01a813d}}, + {{0x0006b2da6dc1d29b,0x00094871e1444280,0x000f49276d303000,0x00004af1feb333aa,0x00005583b9f770bc}, {0x000be7895695f204,0x000149d012b51db0,0x000f61643fc84181,0x0001282409f27205,0x00000d3417515883}}, + {{0x00096f5674198335,0x0002363b7b08d791,0x00056700c6059e25,0x000ec434da18171c,0x0000758ee57028d3}, {0x000771d013b0ea65,0x000b04c5e9b97da2,0x000305d80fddf524,0x00063f2df4faf824,0x00008f5c1bf8a977}}, + {{0x00037f17c696042c,0x000b8a2538dea5af,0x000a42600d4cba22,0x000888611cb9959e,0x0000d105f423b069}, {0x000cf19ddb81e743,0x00092157b8cab1e1,0x0009db885472f2d8,0x000130d86fb008ee,0x000065cd5703f26d}}, + {{0x00002bba2be70539,0x0005eab9a6d6284b,0x000f7a530dcbbf7c,0x0007c7b425559c20,0x000061f2dfaa8876}, {0x000943570dc80c4f,0x000300784120e2fd,0x000567122104d6b6,0x000d768f592bc153,0x00006bc1247e688a}}, + {{0x0004c050f15dde91,0x0007fd5f2b820521,0x000e82b62a47a76a,0x0005eeab254d3062,0x00001a05fe04ec95}, {0x000f46e9d529b36f,0x00009f9e3df67eaf,0x00031769855ab130,0x0007acd463e37199,0x0000d251439bcda4}}, + {{0x000354723d695ead,0x000d46e589b5ca9c,0x00087d08648ce626,0x0009479b5b64c7b1,0x000002e179582207}, {0x000e98f7198111d6,0x00057cf9c3cc8b58,0x0004089b090ca630,0x0000fef691fe72f3,0x00000941af25c7c8}}, + {{0x000c0a222eb51e58,0x00042a9cf09aa09b,0x000159f06c0bb724,0x00060db6a8077f80,0x0000b5c989f5ddc5}, {0x000f316512e1f433,0x00047d08ff6219d2,0x000d20b4e02eac55,0x0004e0d12ab84c07,0x00007d1e11606d4e}}, + {{0x0003e1aab7b19a8c,0x000e1ef8cd45b644,0x0005e03daf08d067,0x000915a3adf3e968,0x0000f15a10f0792b}, {0x000cce5b738a4250,0x00059636b2fdf44b,0x00050d605ebe131d,0x00049d9406884178,0x00009684eaab40d7}}, + {{0x000669c72ba075b6,0x00055a4690158c3c,0x0009f8ba889f78b5,0x000ed6f706aade3e,0x0000d8bd566132d7}, {0x000e63b805f08d67,0x000d53bcc1b525f4,0x00025d8477f48200,0x0000a7de801968b0,0x00004afac04f7cbe}}, + {{0x0002c2b7e63d6900,0x00000223cdb843ed,0x00084d3feefb6bbf,0x0005a44fec3cae28,0x000065ecce6d75e2}, {0x00094ce69f790713,0x000ed44b86666c22,0x000b69d8f0d9a8e5,0x000af72009f23817,0x0000c29f8fef5dfd}}, + {{0x000528febae68c4c,0x000170c5ba219067,0x000dd1aec5b38563,0x000c77940df1191f,0x0000f37825c8fba4}, {0x000f980beb11454b,0x0000b0c1b06677ef,0x00089a1c740a1a99,0x000be038018980f8,0x00009c52aea26c24}}, + {{0x000bcce45650ef47,0x00001aa29ac705fb,0x00004c470ae000f1,0x000c25184b71724f,0x0000cd4fde289bb5}, {0x000b22ae88408697,0x0008efbd06866477,0x00016dfbaa886885,0x000776823cc02e11,0x00006cd5640487d7}}, + {{0x0007598a9d82abfd,0x000b16c170f5e2a3,0x00066b0875f188cc,0x000ad9b168220050,0x0000a22c21397155}, {0x0005d3afbddb4799,0x0003dd715b99151e,0x00097cb2e4b606b8,0x000b65ba73b54bf9,0x0000a1bfe43cecd8}}, + {{0x00028092a67d48a1,0x000df31fa9e21c31,0x00043a34acd6a671,0x0007d3aec3312a0e,0x0000d93563965ef4}, {0x00024898fea73ea3,0x00047035afb25ea0,0x00065b54c8247b36,0x000148858300a652,0x0000286662fa22c7}}, + {{0x000d76bb4ec4c20e,0x00062f3fe3fdb77f,0x000d8c7e8f0a12fa,0x000aa81845bbf541,0x00004d969cb3ec10}, {0x00053b743e232a3f,0x000b47f8a45a4c00,0x000d81c8fdc7a3fa,0x000aff4c4261c520,0x0000d4b3454a00ea}}, + {{0x0008f86d36e30622,0x00078143ff0276d4,0x00076f42e626c527,0x000eac338174deaf,0x0000267aa868407c}, {0x000635172e572d59,0x00072a7330ebfad7,0x0008d8657ab861af,0x000a5210a1c8c741,0x000088821cbb0289}}, + {{0x0002522cccc18ad5,0x000da1a6e0277973,0x000c2354daadf3f8,0x000689a7382c9317,0x0000ce1680d2818b}, {0x000bbfcd9ecbee97,0x000bacae62ac359e,0x0001ac38a4330689,0x000ee8455ce5b4c5,0x0000921dfeb6e238}}, + {{0x000bef8271d1ca55,0x000798aabd183972,0x000a3e5e33e423bc,0x000d6607b09f3f44,0x0000da886aecb444}, {0x0006634a99643755,0x0003199cd0ff6820,0x000a515e9356a2fa,0x00079a5f0faa24db,0x000036e1f5d0321d}}, + {{0x000913a5c04e4ea9,0x000e46f11513d3b9,0x000fd1d94d549dcf,0x000c675e227bf579,0x0000f35afef443f2}, {0x0008d24f1314f53b,0x00081abcd822d263,0x000f48db062baf94,0x000bb1a542de294e,0x00003eb6a05ac5f6}}, + {{0x00010ae1208e16aa,0x000558363e2423c1,0x0004be00b1a4d15b,0x00090c9071684416,0x00008e2482596f46}, {0x00073a290b170cfe,0x000062f191f45487,0x00047aa97a1bef33,0x00014690f418d092,0x0000a06028f28be9}}, + {{0x00022f3dbfb894e2,0x0006ae274b18e131,0x00058aadfbe9b79f,0x00035165a49de5ca,0x0000495775831487}, {0x000ef61bb9390993,0x0009f6d13694111d,0x000fc253b1d6a974,0x00015e1474b4ced3,0x0000a1485e67c5db}}, + {{0x00067b4147c15b45,0x000b2bc61301e796,0x000094381e34f553,0x000a20b32b80f817,0x00005d8bafdc23ea}, {0x0007995f1c0e74e9,0x000e5bba289c5a98,0x0004c82515a9b292,0x000b09b13cd4b2eb,0x00008b5d2446162d}}, + {{0x000bf66683425204,0x00097aa862d1bb47,0x00006abcd08d6894,0x00000dd1f349c7e9,0x000054ce9862d7bf}, {0x0005c9eb55b803b2,0x000a11e3c16dacab,0x00073bf12b03468e,0x0008873c24213dd2,0x000011538eb91587}}, + {{0x0004a2f731dea2d9,0x0001e4ed7b2a198e,0x000a664fed5856cf,0x000290f6a632eb13,0x000032cd90a4da41}, {0x00095d4c0c4ddc0f,0x0007447fc2c9850e,0x000076bcbc0f422f,0x000285f68cbec486,0x00009e7c0c1bd6cd}}, + {{0x0004ddb0f5f27cac,0x000ae80d59ff6599,0x000601023e85461f,0x000bfb3f05481a66,0x0000665427bbc9eb}, {0x0001a697587fd52b,0x0007dd49efceb057,0x000420688935289f,0x0006aeb1becc60ea,0x000022639d9c3a78}}, + {{0x0006220361ecf90e,0x000f455064631a8e,0x0005c2b79001f23d,0x000db504ae9b5d0a,0x0000bc9cdaeb8149}, {0x00064a1934aa7289,0x000e1e9b60f3b331,0x0009cfbfd750eb00,0x0007f5ca91615b9b,0x00007015cc07f45f}}, + {{0x000c4a5bf5151dff,0x0000c07118f2b462,0x0003fa42c21adcc4,0x0001aae60c545b04,0x0000c21aa55d96be}, {0x000c32f4e51ea80e,0x000f459b5d8de84b,0x0008f1b5e3dae45e,0x00017cdb73c7ebc3,0x0000405a74bc8ae6}}, + {{0x000e9c69f1c56bdb,0x000799f196a4bb1a,0x00075092b8c176b9,0x0000331448f31168,0x00005afe3df4f976}, {0x000fd49145813e50,0x0009e2b34226a8da,0x0007ff57f687fc4d,0x000b46f2dfc92d4c,0x000004e3fc1401f1}}, + {{0x000dab61430c9ab7,0x0002b238e9975afd,0x0008042ae0bdd41d,0x0004cb8094743041,0x00001f9addb3dddc}, {0x000c016c52dd907b,0x000c79e2047f7090,0x0001011a6d9bdf44,0x000c7836f1fe801b,0x000063accbd89acd}}, + {{0x000e2351272a95b5,0x000756276ac8cfc7,0x000d7eef70c66771,0x000b3dec0d3709e2,0x0000add2b06ea685}, {0x000d32d14ea5d65e,0x0005ad7dd506363a,0x000b4aac6f8e01f0,0x000465e9ea221375,0x0000d2a2bf9ed353}}, + {{0x00079b5e9d3a7c31,0x000671b7f34b439d,0x000c4ba758e0ee5a,0x0000c7bf3dacf51d,0x0000d3d1773fb331}, {0x00071127747ae836,0x000fb97d6b40a8e6,0x00096140031f4315,0x000767a521cceecd,0x00007246f1256535}}, + {{0x000cc5aef0c31335,0x000d2e16693b702f,0x00029b749247cc45,0x00020fad484e49c7,0x000022cef7e02183}, {0x000f40559ab93b3c,0x0000df181071e56e,0x000330ed0225fba1,0x0002f673bd659515,0x00004be69d5dddb3}}, + {{0x00076680448087c4,0x000f31432dae264c,0x000f9bf47ac30903,0x000d02f851b26600,0x000000ed311acdd6}, {0x00079fef8fd24247,0x000a8a6da98b045e,0x0001e673afdfd974,0x000167d5c9f6410c,0x00006f2e733cb2c5}}, + {{0x000ebb52a6017539,0x000c357c2d491ada,0x0000bfd24b286514,0x000922487696701e,0x000050c547e94478}, {0x0001969e5d32bfe8,0x0001f50d6c3ed1d4,0x000e27f3a30bc147,0x000e0c0f3679fee0,0x0000f64a7dd24a6e}}, + {{0x0009937633dfb1fc,0x0004d77f25472fe5,0x0001ea646ea82c39,0x0004510bdfdf1a66,0x00007ccc59279085}, {0x000796281761e131,0x000f8196885c8217,0x000ffbd70da57596,0x00036fac17e84928,0x0000e6e0a413671d}}, + {{0x000872c4152fcf57,0x00002e77e75461ae,0x0004dff09441c87b,0x00017160799dd5a3,0x000066b4e44f8a6b}, {0x000a51211f1c7924,0x00030be35c3edc06,0x0000c469eea02ae9,0x000f5ca5ca4d6de9,0x0000df4368e96e4f}}, + {{0x000acab4baef62e3,0x0002785b91e87817,0x000e576109f5a220,0x000e036666ebe66c,0x00002ad31f4273bf}, {0x00030a425bcf4d6c,0x0002915056e66283,0x000332156ea95059,0x0002d699811c89e1,0x000089cf1ff4c11b}}, + {{0x000391304e60cc0f,0x000c5625d37575b6,0x00026e562ce811e8,0x00069f130e43fc2d,0x0000bb30b4c508d3}, {0x000f82c485281182,0x0005ad285911634f,0x000358f287c6fe08,0x000c095f2830c099,0x0000e60a95e865e6}}, + {{0x0007d3d9b785dbf2,0x000b8759bce70840,0x000f61239530889a,0x000e3cd228e0e652,0x0000b6d14618879b}, {0x0002c0451a7bbf7f,0x000f86f24a64e690,0x000bc6da030ad99e,0x000abf76d9317a98,0x00004f877f4bb596}}, + {{0x000f62d4c44f1190,0x0006e9b77416b05f,0x000aed63b4555f53,0x0002a9c7c0d0598c,0x0000cd2b7cec358b}, {0x000287b46945fa35,0x0000867c87913f33,0x00037bd08f8785b2,0x0009d7754a7a6196,0x00004d4598c68be7}}, + {{0x0005acbc46d7ce17,0x00071b085877889e,0x0007a50509a515bb,0x0000358ac1a03d0b,0x0000d3e738b62926}, {0x000c2ce2a6cb0ebd,0x0004bf7adc79861c,0x0000163766f2e295,0x00008f91c4d45133,0x00009fd2c812ad59}}, + {{0x0003738b2b836a16,0x00001c0d6622e5a8,0x000c19af1855b41a,0x000acab86fe3177c,0x0000465c2005dd99}, {0x000c23f6974b99e0,0x000ba2717cbe46e5,0x0002be65875a7cf8,0x000c984d2ebc3f06,0x000094b44475f209}}, + {{0x00085edb940cb5af,0x00018cc82f104af2,0x0000526fa6706d79,0x00013fd8c8776c03,0x0000a8e6f7790da9}, {0x0009d34591ee4f0d,0x00067027416677ea,0x0006714575f46e33,0x000fe14bdf98bbea,0x00007c08b47562a1}}, + {{0x000303c1c08ad635,0x000ffc845e7b46cc,0x000f36bf79954343,0x0003a6cb8fbdb548,0x0000b82c392dc827}, {0x00012c4928435d5c,0x0000b933038008f7,0x000da054a071cf0f,0x000b5c074c2d24a8,0x0000b0e720203c46}}, + {{0x000337ac0b7eff35,0x000e75e48b3c0ad7,0x000f13a5f8552225,0x000cbe96f78b0c73,0x0000e70062ed2349}, {0x0005048e7073969a,0x0009233cb3d26b8d,0x000caa20f392d2a2,0x0007074e4f727c4e,0x0000068c99ecccde}}, + {{0x000651fb87a29137,0x0004ccc252f0fcd5,0x0006cd3e4ea3e3c1,0x0002e7077d92df3b,0x0000a41414435a73}, {0x000951aa71ff4939,0x00022bd37cf6a895,0x000cfeefffe980c9,0x0003e8b5bd5e64de,0x000010dc2aa344c4}}, + {{0x0003f26cca9f54d3,0x000b6303f6dbcb40,0x000eee67c928bbdf,0x0001c30c37951ea9,0x0000bd61a5327996}, {0x00038e6395c9a791,0x000d51eb352d09a2,0x0008756316940ca2,0x0000d16d1e5c5ec1,0x0000e19742c2e1b2}}, + {{0x000d90823fc2e6e0,0x0009089591494633,0x000ed7da5a76e29a,0x000d5161069d9c84,0x0000baa11cf5dbca}, {0x000ec64961849da5,0x000f5f3d8c28d01e,0x000a2ee4493b75f1,0x00055807bc4f9f1c,0x0000a26322d50e00}}, + {{0x000d65861a023efa,0x000419e5246e1888,0x000563ec01d72aab,0x000a4309a26348e5,0x0000097196463439}, {0x000d54badb9b5b76,0x0001645a524b567d,0x00038e60873fac1a,0x000f482fe97ef7fe,0x000008748d29f384}}, + {{0x0001794c486094f9,0x0002fbf3a8d6b057,0x0000b0e25869254a,0x0007d7848a8dd131,0x00009ab9f402aa3f}, {0x000c68a6706c02e5,0x000c19790e6c0927,0x00071376c22b5e76,0x0006571c3252606c,0x00003a5769059ef6}}, + {{0x000f852edffcf3a5,0x0003ec0a6f558d63,0x000519b9eb4d2ed0,0x00069a8b3aa8de12,0x0000d38e9c46e0a5}, {0x00028bf303747e2b,0x000c45b5c18d8715,0x0006bf923a208e77,0x00039eed129c88ca,0x0000cbf19806f028}}, + {{0x000f030273231941,0x000b239ca59d9b9b,0x0006695203b055a8,0x000f24a46b23120f,0x00009789f1f597e5}, {0x0009468aaf018013,0x00005b69d59c9c49,0x000f4c07972ee119,0x0000485bd39595ac,0x0000ee11ecebe0cd}}, + {{0x00086ec1ed66f181,0x000bc61fce43ebde,0x000bed74d225d906,0x000ab74cab07d6e8,0x00006e4617f37855}, {0x000aaddb2fbc3dd3,0x000f5aeddf5b6568,0x000cf2fadedb5484,0x000699578f20e86d,0x0000516497c915f5}}, +}, +{/* digit=20 [{1,2,3,..,}]*([2^140]*G) */ + {{0x0003fecfa181e695,0x0000e0d69a98ef0a,0x000eab95d9ea02f8,0x00002162e9cf8e66,0x000020f2beb74720}, {0x000540a1df843618,0x0000f1fa6d5d621c,0x000f5f6ff1203772,0x000ef2ee3c7b510f,0x000017a069c2bb2b}}, + {{0x0002fb6b294cda6a,0x000519039f348357,0x0005cbb216ce9bf7,0x0000d980e012f009,0x00000aecc1c7063f}, {0x0001c3af02909e50,0x000f48ce9cdc57c2,0x000e336f8c7d59ec,0x0005f42732b8448a,0x000056e37233f4f8}}, + {{0x000b53189e800ca4,0x0006d45208fd8a10,0x00014ba3750fe0c1,0x000acc5e43c0d3b7,0x000027d200e74189}, {0x000e24fe616e2c00,0x0008ee1854c105de,0x000342a739c25f4c,0x0009524d3222a58f,0x0000807804fa027c}}, + {{0x000653a4f0d56f34,0x00078a28b805c222,0x00073434b961e404,0x000a18ec03f8b04a,0x0000c966787eb712}, {0x0006c42864fee422,0x000a3b0ece5ccc19,0x00031c159c1be93d,0x000655887d9f22c1,0x0000bb6d593fce45}}, + {{0x0009ec9b809b7ceb,0x000b32c72c2c22c4,0x000a0bf368a41486,0x000c68d13b9420fe,0x00003d36eea566da}, {0x000c08a328cc987f,0x000b4a3264616fdd,0x00010dbba0a3bcd2,0x0004c38103c49dd8,0x00009d81a293b78a}}, + {{0x00065ade4d559419,0x000da03840873de8,0x000f18b9bdedafa5,0x000267df414abb4e,0x0000ee9ea438aee5}, {0x000aa1637a55a4a5,0x0003b15f93b9260f,0x0009c3598eb19a51,0x00078e01d7ebd29e,0x000023fc56d69321}}, + {{0x000070cb98fe684f,0x0009224a1458501d,0x000bc6b3fd60fbe9,0x0007cab45761c892,0x00005384859ee6f2}, {0x00071f7b59e763bd,0x00088b5a8e5e4b02,0x000a482923d4606a,0x0004454eda5d9b05,0x0000a7731d1b6fec}}, + {{0x000369390d458714,0x000fc6166d8da3e3,0x000a90403e976403,0x00063775c3368289,0x0000bd17983b2f1d}, {0x000679ed5d2c53a7,0x00088dcf3b87a616,0x0006a694e5ec4bcd,0x0007e53e6d7613b6,0x0000460fc7753fc2}}, + {{0x0009b8295caabee0,0x0005889501e37046,0x0006ed265de024ca,0x0008b26bdadc0607,0x0000cb1236b5a0ef}, {0x000ddbf0972ebf9d,0x000452aca4324065,0x0004aff76f1dd387,0x000d23d88b97cf74,0x00001359afece8e3}}, + {{0x000ba2b91502cf37,0x0007984db75d52a3,0x00030b1c92c3832a,0x00060b94a12dddde,0x0000802eabd531fd}, {0x0007327a37fddab7,0x000b8aafa9733370,0x000e6f91a65d6f2a,0x00030ac525c5b811,0x00006aeb0c9cf465}}, + {{0x0005ff62f93a6750,0x000405f48679e881,0x0008ae884a6ec968,0x0008736dcbb55635,0x0000af61472e19e3}, {0x0004372a5f696be1,0x000a5f22fb707233,0x0006cea90c65e57e,0x000b2a168da30c94,0x000036a8a8775681}}, + {{0x00081dc0f9f44d43,0x000ffc46585aad5e,0x00047d1b1f09a695,0x0008b1a1649164c4,0x0000b4b36c8b79dc}, {0x000177b3b6b234cb,0x00046730d9d020d4,0x00080531d096a250,0x00095c5611b9b8ef,0x0000a904b3c14bb4}}, + {{0x000d9d493a3147a2,0x000c7a5655451192,0x000f072129f30a5d,0x000c1370b1f9cb6e,0x000099585462d87f}, {0x0003effc17db9ba2,0x000cab1644a8d332,0x00049ffbccb18548,0x000683f8a306d44f,0x00008d658f16c2e8}}, + {{0x00060cda99f8c71a,0x000aabf742ff44ba,0x0004b3f9967b7abd,0x000160c6310f9c91,0x0000e430a339412c}, {0x00076d388ace52f4,0x000412d7067d1e67,0x00007cd1b4bc0fa2,0x0002c0c3c286aa8f,0x0000cb8f38ce985b}}, + {{0x000be808c3bff364,0x00021263e57583cc,0x0009bdcd1005a0bd,0x000b6b060d7dda25,0x0000a1c56433a5ca}, {0x000dbb99fe4fc88b,0x00081c97bbb52b7b,0x0002321ae09418e2,0x00064e28274fb4a1,0x0000137007e0c87b}}, + {{0x0001fe1c63c4962c,0x0008d81fdb258053,0x0004c2b6b50541e8,0x000fca1c1291a1fd,0x00000693a1866df4}, {0x000604e0117f203b,0x00025a99b8d0b2c4,0x000212c44245f196,0x0002a7fedc20aac6,0x00001ed4e57020f5}}, + {{0x000f575f8547be3b,0x000cf9e45f98fe48,0x000c501000a7033c,0x0001d99b45d3a918,0x00002a6cd6b561d4}, {0x000b4f557933c6b8,0x000cab0d7ffc60bb,0x000d626b6a7538eb,0x00025a1ea3ab8d8c,0x0000273a484b6016}}, + {{0x00098450168e508a,0x0001f9a94abd8885,0x000b0a6718cbc9bb,0x000ffbd13ac792fa,0x00003995b1a0c9eb}, {0x000668e1239e1525,0x00086bb8dff4e711,0x000f179635689255,0x0002533bfc7dabdb,0x0000b59fe5b03de1}}, + {{0x00020eb34a9f7aec,0x00021751efe47e33,0x000be2f37e5e8cf7,0x000ef6bea003bcd9,0x00000f551a176c08}, {0x0006268038f67254,0x00052d92d3b65660,0x000cbd6861dd38e3,0x000da7c7dfce7cc3,0x0000e549e04a51c5}}, + {{0x000f93b08b193400,0x0004cac6d89d4058,0x000159cc7c2fae6f,0x00001c4bad8a8c8f,0x0000ddba4b3cb0b6}, {0x000c7b51dd95f8c7,0x00075ea5c255da4f,0x0004a8c4c1d163cd,0x0009cdc0707d0627,0x00009d9e0089802e}}, + {{0x0009ebfe6ddd5053,0x0004850bed1a02a2,0x000327d5737064e7,0x0000bc0f6bae65a7,0x0000846f5f228392}, {0x000749160df1b9b3,0x0004fd1da29f87c3,0x000d1743c4cfb289,0x0007c5e0a478ca4e,0x000090c60306edd4}}, + {{0x00053128c0a78de0,0x000a1e85df708f3e,0x0001b6582ccd02bd,0x000bd1d6c75c03a6,0x0000762921cfc0ee}, {0x0000823d85010c02,0x000ae044cf1fd34d,0x000b5e78ad73aaac,0x000f3fdb4159bba3,0x0000287c7f805826}}, + {{0x000f742580b1a014,0x000d20423b794aea,0x000dea144f080415,0x000472a12622cda7,0x00009ea499699d62}, {0x00091ef571f3913f,0x000405b25a8ab429,0x000b79e8f0610f21,0x0005a157adc58530,0x000090e3df6f7a06}}, + {{0x0005deb43e2e0349,0x0003b44024aa5d0a,0x0000c9f7f53fb5a3,0x00065618628c686b,0x0000c69c29d3c563}, {0x0001febbace47b69,0x00090ea5a2ec5a23,0x00063853ebdce028,0x0008a975da1fac94,0x00006812c52e09e7}}, + {{0x000577157151692d,0x0008098e1c44d3fb,0x000399be1eb2721f,0x0008b7f050608732,0x0000a5a5512a979d}, {0x000d55dc6f567809,0x00037dc7a7f4737e,0x000941a03e20d300,0x00083972ce7301f5,0x00001ef52167d30f}}, + {{0x0007fc14092d85f7,0x0005ec49e41a2872,0x0006a4d8172d223c,0x00087d37cf30a2ba,0x0000c08620a2030d}, {0x0004c7dfc588b090,0x00095874bbb00484,0x0004c0495728cd49,0x00058fcc1281eee8,0x0000769b5baec319}}, + {{0x000228bf99c24714,0x000ad91eb110665c,0x0006d7024f2d8a11,0x0005a10594f494d3,0x000082ded8c0dcb2}, {0x000a9d8dadd48854,0x000eb1d2b547c958,0x0000af5507004477,0x000350ca45f6ef2a,0x0000fc739d66f8d6}}, + {{0x000af27786f08a98,0x0005c2c2737f75cd,0x0004e26708700bb2,0x000fef055a71411c,0x000010188c195076}, {0x000d0c9abcd3297f,0x0007048108ebc251,0x000ceed30ae4c896,0x000ceccd146de718,0x00009d4f07bb986b}}, + {{0x0008ed583fa1e08b,0x000e0eabd1fb5ad9,0x0003b11967780d33,0x0008c43330513c90,0x0000a11de9f547bc}, {0x00034da02c2d064f,0x000cb48de23b6843,0x0009089d87ecf360,0x00034b67a1b4740a,0x000028fa43aef367}}, + {{0x00082cbea4570b35,0x000b55ebcee9f2a4,0x000694cd5ee65d68,0x000d32488d0036b9,0x00003edd0e987885}, {0x0003307beb9bc6d2,0x00077f5c6768e37e,0x000f2160fe9abb90,0x000da62396ccd551,0x0000500888c67336}}, + {{0x0009ed9926fce430,0x000704da2930383f,0x0004cb227809dd1c,0x000b3830f6f5968a,0x0000d700c7f73a56}, {0x000ea33ab64a0652,0x0004f338df801825,0x00063f57faab9b73,0x000633f516100d9b,0x0000574395a47a6a}}, + {{0x0000fb6700a1acd0,0x0003fd999681b556,0x000b4e1bae823fd7,0x0000a3da915d1f6c,0x0000d0301186ebe0}, {0x000b0c989fca8cdb,0x000b49da0e0b744f,0x00031d76f970d01d,0x0009695ad8c56479,0x000015737c0a659b}}, + {{0x00033e8a8b484e77,0x00090a26dec7dc99,0x0001f0136b2fdbdf,0x000ddab349e9a49f,0x0000860368ee0fdd}, {0x0002c1cf9ad3e183,0x0007389f4e79d93d,0x0004ff1b66d6c5f1,0x000d8c4a544d91b2,0x0000e12a5ec2e16c}}, + {{0x00074e9a56b872f8,0x000c7cf68ea25435,0x000560ef7a1ad550,0x000a8ae89e37d23f,0x0000c54b9cb49d47}, {0x0000a4a088ac342d,0x000b4576c6d046d4,0x0009689e9ec450c7,0x000717e589e31c1f,0x0000acf260388781}}, + {{0x00037c6c8cb6b42a,0x0003196ef381a892,0x000f078251326fc9,0x00022cb5d56c6db5,0x0000cba2eeb1449e}, {0x000887a633c30000,0x0002d7cbcf7174e0,0x0006cf1becb6cd17,0x00099b309e81dec3,0x00007a18a6d60ae3}}, + {{0x00026799edce57e9,0x00044f001d41b36c,0x000a1f2c652b892f,0x00070a4884ae5d16,0x0000b3294257fcc3}, {0x000daf2bd2e21df5,0x000cb2470a993120,0x0005db32e55298d2,0x000635bb78af6ca0,0x0000c76a331b01f5}}, + {{0x00061fff8a4f29c3,0x0000a68f8d49aae8,0x000b1321c70dc924,0x0004ce660e649f81,0x0000d2c801bb792e}, {0x000f772425218760,0x000c416c79b1f479,0x0003e5bc90bed93b,0x000049a67fbc0526,0x00001e8e630521db}}, + {{0x0006738c6f3431e1,0x0002d326754176f2,0x0008c877ce609cb0,0x0003cba10cff2d81,0x0000f0e75ce886a1}, {0x000ca641158544d7,0x0008fcb71ed0f4fd,0x000aa47555d777e8,0x000b3fcc233737a9,0x0000b4531935527a}}, + {{0x000f68839f05ffea,0x000fcd82574edb59,0x000292d1b8f4f4bd,0x0000862ce3450cee,0x0000a448a1301ccd}, {0x00091b3f7914967f,0x000a2908a5edabce,0x0001042e74537f09,0x000a33b812421ef5,0x0000af5cebddc0b3}}, + {{0x000fd874ca6b39ac,0x000c42efd342730f,0x0005c8edb70fb72e,0x000a512b4735f9d7,0x000011f21588278a}, {0x000f635bf3bfebf3,0x00043bd9601fc459,0x00020cb733a1ff0b,0x0005a399d12823c4,0x0000e9af3e26c291}}, + {{0x0002c72b41c34403,0x0005b3039a5fe0c8,0x0008795a3175239e,0x000c60b1084b8a55,0x000028d0a1e001e5}, {0x0005f2ed3788a049,0x0005d6c11a9f0a49,0x000d692d625d8ff1,0x000fe465155f059e,0x000054fa107df425}}, + {{0x000abf2e98aaa995,0x000046b0f88ad16a,0x00054026a90cd8ba,0x0006d2457f4782c1,0x00004ee0734a2af5}, {0x0009e5445b4147a9,0x00010a52816cbcf8,0x000b62e773d102f2,0x000ad7d808517e39,0x00002e25421f9169}}, + {{0x000d871bb608558c,0x000e36d4ff9bd721,0x000f2763e60e4eba,0x0002464ba1081941,0x0000a2e45bf11ee3}, {0x00072ec2bfd7a5f1,0x000f64d0b12d66d1,0x000be70dc528a8f2,0x00083cd17f1e38da,0x0000d5d7316af939}}, + {{0x000184adf423e315,0x00015edb1a1051b2,0x0005bcab9cb41729,0x0008efd054ca9362,0x00004396860f9899}, {0x000f6c4a54ae57ef,0x000ffe648e9d4e53,0x000faf6bc0ffeb58,0x000b8a0bbdaadc6a,0x000088ae7979a3bf}}, + {{0x0001d44d2359ed9e,0x000313544ce2209f,0x00051e569ac68dd0,0x0000971378da47fd,0x00001abd8610cc80}, {0x00018d9343b6e3a4,0x0008740a1bae23ca,0x0003f3e67480797e,0x000dfc91f0c71753,0x0000489697046e6c}}, + {{0x000105552a82e8de,0x000498460cdc8ca2,0x000037178b2caf78,0x000b576c1b7b62e9,0x0000fc09d2dbb514}, {0x000f9ee9113be5c0,0x000fb3f9271c5f2d,0x00083fc542fbda78,0x000141e09a81af8f,0x00006b138668afb5}}, + {{0x000480f43e3865d4,0x0007dddf47d938f6,0x000205ff772dd77a,0x000ad8b2a8e9714c,0x00006d449d8dd088}, {0x00019ea185d706fc,0x000b07dd7f629266,0x000bc2031e47e02e,0x000ac927f120a78c,0x000018bef01598d4}}, + {{0x0007a9c6bdf22da8,0x000f10dc82df18f3,0x000703651efbc432,0x0001a5452cef8e5d,0x00002887ba159988}, {0x0009ddab920ec1de,0x00030c3e8d3b7cec,0x000a88747d0d7e8c,0x000534645bc3954c,0x0000deaa2e17fd53}}, + {{0x0001d936cc874756,0x00020d2383bd461b,0x000903546d92a52e,0x0001129abccb59d7,0x0000111a7619d14b}, {0x00084feb3d5f6126,0x000d00e828ec0ae5,0x0000870305ea69b8,0x0001fe0c07898554,0x000049cab050c482}}, + {{0x000edcf8bdce214d,0x0001b6af736125ec,0x00038b9e2b5622f7,0x000a763e1227aa70,0x00000efb2747c20f}, {0x000f88b79df975b7,0x0005a999503e817f,0x00038ec46856bf28,0x000f6e44d5351f50,0x000040a52c66c42a}}, + {{0x000bb152cbb1a3f8,0x000d97a834292e38,0x00066bb74c3eb99f,0x0008fc4a4fcbf1dd,0x000080784d74de5e}, {0x0004c1cb4e7a0be1,0x000dad15a72fddc8,0x000ec30e18780510,0x00073e34bcf1af81,0x000041e50a81a610}}, + {{0x000571847be87ae0,0x0007f76a43720d95,0x00007c3d368a6141,0x000332f57e7e87c6,0x000043afaf85252f}, {0x000e1211552a4d28,0x00023b4d4ab4cc14,0x0003816a4b6dee69,0x000a2936ab74c8a0,0x00004001ae4ef394}}, + {{0x0008344d795fb455,0x000d679f55a55bed,0x000ccdffc57326e7,0x000a0479533ce04a,0x00003473caf8993f}, {0x000eb93a13df4c82,0x000677cbe46f7906,0x000e4ccf8a73e51f,0x000dbcb1ab3ae10a,0x00005614508aa5b3}}, + {{0x000f96211a71b27b,0x000abbb7fa3961ef,0x000d7f3efdf71412,0x000d29031ba6b82b,0x00000b9c41619180}, {0x0004552014cdde5e,0x000a427b4bbbeec1,0x000e988f3702c624,0x000d034b15e8c2d3,0x0000e3bcc6e84f7f}}, + {{0x000822a42ac6c853,0x0005edf9f2b79d00,0x000de1e582db0cea,0x000b61a7cad2ab42,0x000046ed5265d6fb}, {0x00029951a2faf097,0x00000c25612eb396,0x000f564902fa8a58,0x000960c0ae04da7c,0x000056629087eea3}}, + {{0x000f5c53d080847c,0x00089241d4f63609,0x000961a63cb081d3,0x0006fbf4fb381077,0x000020c5984eabb6}, {0x000aa7cf902f245a,0x0005ae536b1e3d40,0x000b3134f9cb1273,0x0001aebeda24da99,0x0000fbd9c69fcd01}}, + {{0x000e30ac7088c7d2,0x00001207389f9a16,0x000407a535ab6571,0x000eaafb09547fe7,0x0000322f9d76fdc6}, {0x000f22d7430de4de,0x0006068ca9a9c0f2,0x0008e58681938269,0x00020337f1eff191,0x00003b5b636386f4}}, + {{0x000f9803fbc43419,0x000fcb5eed4e146e,0x00082e41d359f2c7,0x0004c20f35744e74,0x0000a9ac3ed83b22}, {0x000a6fe91fc50ae7,0x000b5613fa7c9161,0x00032f15a89ccc66,0x000d0319268b14c7,0x0000cd6f4e32467e}}, + {{0x0009869ce56b40e9,0x000c302dde98fbf7,0x000ee2cd7f93e094,0x000d425fe0c3a8ed,0x00000f3ffc14268f}, {0x000fd5608241aedd,0x000730b1afe881a7,0x000310d5295ab7ad,0x000c42701270563e,0x00003ffdeb1d9d9f}}, + {{0x0005c91d11a8594e,0x000751cf6db8c8f8,0x000b5dfd02e74d25,0x000c85a29c7ca302,0x0000389cfbf49143}, {0x0006405941768d8b,0x000453bf825dd01b,0x000cd17e24510399,0x000e791c4ee16656,0x0000ea3c2846a037}}, + {{0x000c06ed9a475207,0x000a3f8524044e1a,0x00087648afbfe18a,0x0000d8e615f8e280,0x0000301e47f29d15}, {0x000f9ddb299b9777,0x000b35b7831479f9,0x0007c90e776697a7,0x0000b4a0d674687d,0x0000afffe0403721}}, + {{0x0003e4b28c22cee9,0x000779fd55ae5aef,0x0002a5d6aefb0ecd,0x000356bcea71320d,0x0000cfb5fa191db6}, {0x0000b57f36e1ac55,0x000ce6cafb7d395e,0x00008c4db008fa9a,0x0004773f6cdf7053,0x00001527a37e5ed2}}, + {{0x000ee305bd213110,0x0002909c90d7ba0d,0x0008696d36ed41b2,0x000a80c5f6b7587c,0x0000db8eaa83ce83}, {0x000fe37b24b4b6f6,0x0007f22d1f0dd297,0x00098dbd9fe58afe,0x000527373587368c,0x0000bc226caf454a}}, + {{0x000384ece53c2d04,0x000d1e4606daa12b,0x000ec12b0779d897,0x0001ad653e47b073,0x000062dbbba9756f}, {0x00009f2cafe37b68,0x000f6cce2e1769fe,0x000f607fd273d1eb,0x000c250ac1d5383c,0x0000035f7ff92e10}}, +}, +{/* digit=21 [{1,2,3,..,}]*([2^147]*G) */ + {{0x00034c77e6c55202,0x000fbcb9ea58854d,0x00086666dc27df9e,0x000a85205f2369d6,0x00009d1febf2417a}, {0x000819e93470afed,0x000912a27f9e9846,0x0001e65043e6a966,0x00080954d008a2e3,0x0000ba7ced06cb76}}, + {{0x000f541338d6e434,0x00030541d5ccecaf,0x000bc88ca56f7dd7,0x0002c375d426de96,0x00008d94f6bded3a}, {0x000a3bb2ef8279cf,0x000a1b1867f26354,0x000225151d575465,0x0000d7ff99b0ff95,0x00003e19d89e9450}}, + {{0x0003268e32dd620a,0x000ec27849a292a8,0x000378882913ec99,0x000cfe4dd8fdfa2c,0x0000f96f33f8e6f8}, {0x00037e5dc3fa8a51,0x0001a0b03a1dc067,0x000f037b0236bb53,0x000a5323e59f2989,0x00003f9b5a7e9a12}}, + {{0x000f6ce51efb3108,0x0004158df5be0d0d,0x000158e59cb5b2eb,0x00033656459e2936,0x00002aae2b99466e}, {0x0008a39411aa636f,0x0004e4c0a933fb65,0x000f026b77152ecc,0x00011f010c758a49,0x00004837f98bb093}}, + {{0x00002c4c753c45fb,0x000649c840feddfb,0x000f8a3e618ca81b,0x000dbbd46fd09ab0,0x00001162ade97733}, {0x000ad20236e3ab64,0x000572a563267070,0x0007cbc7af88cdaf,0x000271c5fc871999,0x000042cd4528b665}}, + {{0x000f364b71698f58,0x00021f7b605e7807,0x0003b2cbb6ba418d,0x00086f7d20b00fa0,0x000083eca385a543}, {0x000e43ff3437f24a,0x0002048bb33cff0b,0x0009df765e910b43,0x0006f6a963a12832,0x0000c1dd5575e2fe}}, + {{0x00010f924a0a3fcd,0x00041881c3f95576,0x0000dac9938e17bf,0x0009179ba84fafed,0x00004a222c429eeb}, {0x0001dbe13f542b66,0x000d8425d457c79c,0x000ebb7791fc65e0,0x000f608ffb754f1d,0x000038d8fd0fe08a}}, + {{0x000523a626332d5d,0x00028561bb44994f,0x000845ea27bc3883,0x000089305ed4b03d,0x000039d3ee292a1f}, {0x000fdd3e7676b0dc,0x000f3b7060176561,0x00064f9a8620e35f,0x0001f676ce424ff2,0x00004c341a09a268}}, + {{0x000fd2f69beb6e85,0x00031d700d03fb6a,0x00083a14f3a50b99,0x000bef7840b2ad0c,0x000073207bea4085}, {0x00082e309fe7e5b9,0x0003ab40a7e15af8,0x0003056e2957678a,0x000c09872d4bdd54,0x0000c1b26b49df13}}, + {{0x000861cf405ff065,0x000cf86e828b1c30,0x0006933fcebac86b,0x0009479791a97163,0x00000e7c2becaeee}, {0x000a095fa90d7679,0x000b5670ab7bc3d4,0x0007b056dae60eb7,0x0002a987633a6439,0x00003a21f33a0501}}, + {{0x000370babb886433,0x0006f2e21599663c,0x00076167191df36d,0x000bf0e83ba8358b,0x000081eea1da28f3}, {0x000f1ba39966e6ca,0x000847295492b9b2,0x000b26b7f7c464a2,0x0009de6fd5f70a09,0x00009aba1fa9be00}}, + {{0x0001f22369b87ada,0x000892fca556857c,0x000b064663c00e5d,0x000af17ad74cab90,0x00007112386f50fa}, {0x000e1986d9bd5f51,0x000849c3463f7435,0x0007bd4b22dcc7e3,0x000f31cc7df748ca,0x00003cd4c08adec2}}, + {{0x0005df8e32377106,0x000e6bd2f7b00d3b,0x000aa082b0dadb26,0x00066e3f5966abe4,0x000066ec8de950e9}, {0x0001ed5ee5242161,0x000b31dab0b61bfd,0x00086d6bacd93c59,0x000195558a8435d1,0x0000b7d34d2259d1}}, + {{0x000e46022caf46b4,0x000f5a96fe4f5936,0x0008f474e6a45dd8,0x000f15b7925434b9,0x000014104124053e}, {0x0008d1241de97bff,0x0000cd80bef471cf,0x000db0037b8547b6,0x000dfec47d3970c4,0x00001bcd329eef20}}, + {{0x0002e0910caad676,0x000ff531a1e131a9,0x0004fc8401f59195,0x000c6bdbb852e05f,0x00003e297caf3a72}, {0x0000b2e49abad67c,0x000c2d3db0d93c2b,0x000ef1d406ec405f,0x0006fc1c14a5307f,0x0000cd19846e8089}}, + {{0x00031769bb816483,0x0005353120d000f8,0x000cabc62d69eb48,0x000cb1a17d75f44c,0x00004a07f82e749f}, {0x000f787bbfb55541,0x000052e283f82c3a,0x0009213a0b06ed4d,0x0007b44722889fa1,0x000062b085eecf3c}}, + {{0x000cb31e0dd3eca2,0x000cc52f13a5bcae,0x000bac297c6237fb,0x00054aac2b6b0327,0x0000ae1cac5d917f}, {0x00007d47845ae4f6,0x00026e5972e04748,0x0007915bbfec7dd9,0x0007ca63bd25411d,0x00006f85dc539490}}, + {{0x000b888bdbcf0ca3,0x0006af279e9fd981,0x00054e934d75f5da,0x00034ae28bbf2470,0x0000c6ff6e5b1db1}, {0x0007cf4047d26e4d,0x00078049ec37795b,0x000d945aff370f7b,0x0002bbf6712d4dce,0x0000f30b5ecd9564}}, + {{0x0004c624896246e5,0x00069e90bbd19b03,0x000fedb735652c01,0x0006139b38636f87,0x0000e32f8475135a}, {0x000b312cf933c835,0x000dca7f47e60703,0x0009c2415d05bb76,0x0006f8325e4f0c94,0x000069e5622c250d}}, + {{0x000eb3a6568013e8,0x000ea2f243fcbbe9,0x00042734a8dbd203,0x0009841dbd7694b3,0x0000f6d12f8c6afa}, {0x00010a2c9eade291,0x000337dd0f18b986,0x0001c0d46bab4f32,0x00042a4779737b67,0x00000b6a7c6e3e0a}}, + {{0x000ddf33035b41cc,0x000ed9c45895fb19,0x000c857e5d336343,0x0007d4a1fe493854,0x00004d506bf6e4e5}, {0x000c8cbbbc33f758,0x000a1262c77d3cd8,0x0001a28237281f08,0x000e32883f4ea6f1,0x0000895041f1fba2}}, + {{0x000ea499c438edfc,0x0002d1edba44fcdf,0x000ba50f07678dcc,0x000c1b307b3b87e2,0x000013888f003948}, {0x0005ad41140af420,0x0003926ed1a7c213,0x000f6695f8e5104f,0x000120f24430cb88,0x0000ce0637b6d73c}}, + {{0x00001e6fe631e8f0,0x0007d7bdd24bb2db,0x0009ad44f1c5563d,0x0009f98daea3ba36,0x000000c81b68187a}, {0x000a951aae1fd9a7,0x00071d5aed8a5f48,0x00098c622e35626c,0x000503b095276304,0x00006d17634e73aa}}, + {{0x0000ddaeb300f7aa,0x000c4db5e80136d9,0x000d5244c9dcf7df,0x000aa1c45cb26874,0x0000127ee79d48e3}, {0x000cc53575f1dbba,0x0004e0e6161e488a,0x0002650d095037e8,0x000215b7e5928329,0x0000be67d99b4938}}, + {{0x000944b3f8e10652,0x0006130e89243c7f,0x000530136ed908cb,0x000168e8ee8fd56f,0x0000227b7d5f7ffc}, {0x000c893b5cd6dd54,0x0001662796e84f55,0x00018e12c82225e1,0x00051a1c6cead1cb,0x0000381ae0cc4f5a}}, + {{0x00013d37fafa4c8b,0x00015491aac03459,0x00069264c3d91808,0x0000cce347871f3e,0x0000ea9dd3d64f4f}, {0x000d0673eadd3e7c,0x00074573bcd8bda5,0x000a2486c0033c1b,0x000ee6655893795d,0x0000b89ee5c46abb}}, + {{0x000a8f322532e5d5,0x0000227dfc4c8fe0,0x0006726dbb6410ff,0x000dc7119b9d5822,0x0000ec25669ca2b2}, {0x0002e064c3beb017,0x00000acea556af4d,0x00083487a852123d,0x0003ea9e9470faf7,0x00005a7ea04c664b}}, + {{0x0008f356798e4ba6,0x000567d0e0914ad7,0x0002904039214e6e,0x0007496420b488b1,0x00004049e0b5c295}, {0x0005af13ae9841ff,0x0008c0b662a603ef,0x000453458dbe4ca1,0x00072156845c5ffa,0x00008dabf1a00b66}}, + {{0x000f0aacce2793bb,0x000e15ec47c1b650,0x000234fa971db851,0x0006cd8eb78f3e3b,0x00000c60f36ac010}, {0x0007121774eadbd4,0x000f8e3238630542,0x00008697625367fa,0x000ad13541b5c9cd,0x0000ff069e31c507}}, + {{0x00052568776e6676,0x000c523c6bb57414,0x0003a8a876e76142,0x0008367bf307121b,0x00000e7363ef8450}, {0x000450eb7366d800,0x000a4837dbdf5741,0x000d4316fe4ee14c,0x000825a765eb9b69,0x00004548dca8ef43}}, + {{0x0004e4c5ae888eb9,0x0000c6e9ac999c9f,0x0006ac029733abb5,0x00038e4aad3c20ba,0x0000b8dd3d3bba3e}, {0x0004c920bc5d11a2,0x00077c5f88a3a9bb,0x0001d3cb8f20127a,0x0000a62f52b06e16,0x00006c1ff098afaf}}, + {{0x0000d2f7189e71f4,0x00081ecf91e73267,0x000757a21c643874,0x000ce4d5758e57db,0x000027d09f8690a9}, {0x000308f38384a7a9,0x000420732b99846a,0x000845819aac3acb,0x000e030e94100917,0x00005cba11237ce5}}, + {{0x0004f7fb00009c49,0x0006fff28b5f6f3d,0x00097975db8396c2,0x000ed521a9ae431c,0x0000d7ba8b075d9f}, {0x000f09f34f485b64,0x000c24122516338c,0x000d471febc0ddac,0x0008c96450da1205,0x0000c3a6250a28dd}}, + {{0x000d103d1295837c,0x000f7807eb2f69c7,0x000b41491a2893e4,0x00023516e1e1debd,0x0000630745c1e138}, {0x000109e48661ae16,0x000b8a2b2674c892,0x00028d6b58d17e7e,0x000f9da0ec0f87c3,0x0000d8586465079f}}, + {{0x000243e19115ead5,0x000dfbac4fcf6cdf,0x00029f25b1ce1393,0x000a04dc960ed09c,0x00009be4d8eed388}, {0x000e06cd0def72b5,0x000d903427480d46,0x0006d4a3db923db5,0x00099ea7d3aacd93,0x000058519cc5b0b0}}, + {{0x000ebf8827097ef5,0x000b8054f55d3ea8,0x0002ed089259353d,0x000a7c34c89abc6d,0x0000c548b69de096}, {0x000f616994b995dc,0x0005e5845601d587,0x0001fd9f04d1531f,0x0006c9b92ab31e45,0x00008b57bb325adf}}, + {{0x0000fcb1cd5ad73c,0x0005a144da4f6844,0x00062beb8b9c860e,0x00097e6ab286aa84,0x0000c6b9000af467}, {0x0000da420c8a471b,0x0000c7ff7fafac82,0x000b5da7769ae05a,0x000b7a09163f39bf,0x0000d03e590dc73a}}, + {{0x0002b5eb2940d9e2,0x00062b9af5647e86,0x000e3033d3c663d8,0x000bc6b8309031bd,0x000098231b2f42c5}, {0x0000d2c552ad093f,0x000c0f8546954209,0x0001f0d00a4799d1,0x000b451a88b5d6d3,0x00008b4082692f26}}, + {{0x000b1edf1bd72186,0x000aeb24c86eec29,0x00095ea65d491c53,0x000f1572fe588f33,0x0000f3764f7a456e}, {0x000116dcdc348009,0x000631e33955db43,0x000ab286bcdbcd45,0x000d7c5fdb554074,0x000048c7a52618c5}}, + {{0x000aa377378058e6,0x0000a4411154eb81,0x000828ac741c746a,0x000b29410c73bcfb,0x0000439be91fd972}, {0x000b4b043a2fbad0,0x000f82b5e8404bf3,0x00097bd4c39e6dad,0x000ccb4f71640863,0x0000f7de5687f1ee}}, + {{0x000c5a1d2ffbfc15,0x0009fccb64515865,0x000b32558f74211f,0x00012e16368a88c0,0x0000b539dc2ead78}, {0x00083d02f3af6f6c,0x0007d9934ece5794,0x000c9e9835213207,0x000b8990b9650fdc,0x0000a989eca6ee42}}, + {{0x000c829d6f62f995,0x0008fc2a7c0c6a44,0x000a0cb0a8f06a30,0x000363fea2b3a098,0x0000c547b710eee8}, {0x00040e1682afe112,0x000a5b41c0a8461d,0x0000d5d369e0fc77,0x000f6359e4aefde2,0x0000916e52052dd9}}, + {{0x00052e83f883faf0,0x00092b868d35f59e,0x000a19881396f963,0x0001a6c902a9df4c,0x0000fc96822db240}, {0x000758766f1c68d2,0x0003db476c0d4123,0x0001f5d9010fc6de,0x00044ad8b6b57984,0x0000ba8446d1a24f}}, + {{0x000b920ef4a9975b,0x00037330435fa237,0x000b7e7b560bb600,0x00039126f4ab5acf,0x00002ac509833435}, {0x000ee2fb0d1ea67c,0x0009b4c56230f036,0x000838ae6ae779a6,0x0006ef99bff8c8ab,0x0000d83ca9a5b38e}}, + {{0x000bef5e33deed3a,0x000e601892a8bb27,0x000dfbd3ee6356f6,0x000c9d1f3be6cc7a,0x0000ecbc81cd3d1a}, {0x000b909e6e861dcc,0x000393f5f801e4fe,0x000346e5790a247a,0x000c1a41c50acb27,0x0000e29242f061ac}}, + {{0x000214a2f998a912,0x0001b4baf27b04dd,0x000c26722271ee9b,0x000ce55e3027d1e8,0x00001d1645c3820d}, {0x000242c7501779c0,0x0007fa0e8009086f,0x000187129f006140,0x000bd0f23ce47760,0x00005bbdedb0fde9}}, + {{0x000483225d984730,0x00055c658427682f,0x00066ffa1f207fe8,0x00099db6fdd7ba41,0x0000c3140569eed7}, {0x000048f4107e28f1,0x0001312168400db8,0x000a3c06e74ed387,0x00013464489f8f56,0x0000e1c005b22777}}, + {{0x0002a73f37ec3c39,0x000d4d59eba0db33,0x0004d3257c65259b,0x00038f9291709cdb,0x0000a793b264d389}, {0x000e34be43756f0e,0x000dbafb56c9f39f,0x000208b272f76bdc,0x0002c2bf37867a61,0x0000a1d4307e8997}}, + {{0x00053308bdf623a6,0x000a2441fb7d8c59,0x000ddfd955f5accd,0x000be79afa941832,0x0000ad40c5a6fde9}, {0x000ba89aeca8709a,0x00008c248a9d43fa,0x000637a76c64a7cf,0x0001ba7662025272,0x0000ee1c791c2b8d}}, + {{0x00098fd21a843b21,0x000d7d005cb1f0f7,0x0000d8abe56e4ed4,0x000326255f77801f,0x000097b04cf44522}, {0x000b31ffd42c13f0,0x0002b40f933d41f9,0x00060bad45ef7feb,0x000f8927326f425d,0x000027ecdb28c92c}}, + {{0x000e4d14e3352feb,0x000ec3591b9004aa,0x000da7d6008414d2,0x0004ebaed6124eb7,0x0000985b931fd13d}, {0x000d3ab96bf36f90,0x0005bbdf51dfa592,0x0006c177d012dbed,0x0009cfa57963c0df,0x000010ec86987ca2}}, + {{0x00000f6bf926dffa,0x000154bf6bc2ba17,0x000da11f57c9fdbd,0x000e753c18dc8f64,0x00006074b7b7938a}, {0x0000066e84f44a48,0x0008527b954e1427,0x000f38e9a99998d3,0x00001641be8ab2b4,0x0000bb55bbf95c01}}, + {{0x00072b40ea2ab303,0x0000c73d68ddf734,0x000c2e1ebd365a34,0x000719901a716819,0x00002f49e3764061}, {0x00057f101d8b4d66,0x000bc6b47700b73c,0x000d8826a03c8423,0x000637d21d0bc8a4,0x0000004213cabc0e}}, + {{0x00064a1c1c06681f,0x000eff018e50f78c,0x00042b2b316e0a16,0x000f5741cbdf91db,0x00008f4ffcfd0d36}, {0x00071cd4cc5e3e06,0x000a4129e3e0cdcc,0x000b2cbf1d55c7cf,0x0003cb6cdb6ba00f,0x0000aba000624bce}}, + {{0x000db30d232cfc4d,0x000e058a3cef501c,0x000e091499ddcf12,0x00025632d2cf9c87,0x0000c5d7ec7fc976}, {0x000986e0b50d7dd6,0x0007207f112a6447,0x0000ae9f688fdbaf,0x0007dff8c9822ab0,0x0000abfb950cd3d2}}, + {{0x00044878a429f4f8,0x000b5b516609d0a7,0x00069b5df0649712,0x000af23826ba57e7,0x00002335df29fc7a}, {0x000f0675c93d9950,0x000a68677be62389,0x000d9951b59ac367,0x000ccea77985ff21,0x000038956fb85011}}, + {{0x00048cbbb734e37e,0x00014be5b26f608e,0x000b1a0d9c08c0bf,0x00031837bbdd3bf9,0x0000ac7d898f0483}, {0x0004bafbc1a6dea1,0x000f072aafdbc95c,0x00035c41afdd0e2b,0x0001d530373cbc82,0x00004303f220b6f4}}, + {{0x00036210408f237b,0x000a3cd2d1edba06,0x000abb6a2cad3b09,0x00017a9667855a52,0x0000a9157dd5a8b4}, {0x00035074f013efbe,0x000aca38c4a2fe7f,0x000a643451b112c4,0x00080ac1406a609b,0x000053cba344993c}}, + {{0x0006063ded40d232,0x000d34908e254546,0x0003c3c313d5f1f4,0x0006247ebefe6240,0x000074ea0b52672a}, {0x0008d99451d1b71a,0x0002ef79cf79ff81,0x000ce37f580e8264,0x0001fd0165df1373,0x0000744ef509e3a2}}, + {{0x000e7f5cf551396c,0x000dc68c676b73f1,0x000442c36c616898,0x00017ca71c28c78c,0x0000fe5e5591e0a3}, {0x000d8187051f476d,0x000544f034421242,0x00044d0f656fad2a,0x000f4d562068bc0a,0x0000fa2cd6f9e6ed}}, + {{0x000813ad15d15174,0x0001f77d44f50f43,0x00039b35f61214cb,0x000c199399aa29c6,0x00002136d7194c51}, {0x000711b084172219,0x0002c2545a579774,0x00050582d0a5546b,0x0005bbf0624c4111,0x0000ec5c4198bc55}}, + {{0x000dcad771849f1d,0x000431d7bf6f2c87,0x000116eb2b0c932c,0x000bd29aa5cd3e89,0x0000378c25b21ca7}, {0x000a0da9e6e3e319,0x000d268ad5d0c612,0x000c6edb80417a54,0x0007cd70451e4a22,0x0000fbfe01a44282}}, + {{0x0002505ba9384a2d,0x000d94ad69c12fa9,0x0003b35a621b8596,0x000671bf4fcc4998,0x0000e09376142754}, {0x000ccc8f7bffe6d9,0x000ecd94263d2f14,0x000f3ec3027566bf,0x0006ba25b4e9c62d,0x00004f1d7d5ce6ea}}, + {{0x000851aaaca5e9b7,0x0000e6713b9797b7,0x0000a61f6518aa52,0x000b68c357e8c715,0x0000842e7e35c2c2}, {0x000af656868a5489,0x00025068fc818dff,0x000917733d963bd8,0x000327d4da5c8b65,0x000027091000b247}}, +}, +{/* digit=22 [{1,2,3,..,}]*([2^154]*G) */ + {{0x000c9a7d298c241d,0x000986807cfd214b,0x00064eadbe3b697b,0x0009c51f1c780245,0x0000de8cdd084814}, {0x000f0a75a4d2604d,0x000e9c1538af946b,0x0005b1fcc27154d7,0x000f81c5cc9230de,0x000088519ea36864}}, + {{0x000dd1a7cb1282c7,0x00064e46973ab828,0x00008d6b2a08d762,0x0003f2fbaf8d40e7,0x00002571fa1bdaeb}, {0x000732ff22dfd98c,0x00064087108d85b1,0x00088207a87ab01a,0x000754eaaafea859,0x0000cc832f929f00}}, + {{0x000950e36ff3bf0c,0x000f30b34638964d,0x000d7585f8ad20f6,0x00019e8d9177b3b5,0x0000f839761af3f0}, {0x000c5b38288c545c,0x000a53116bd1582f,0x0002120ef2f8e4e9,0x000d23391e1b2f33,0x0000f568724ea17d}}, + {{0x0001185ca8d9d1ae,0x000cf987ded2488f,0x000c46124adf2c77,0x0005f37f3039f060,0x00005d70b7651e09}, {0x00086506260e70ff,0x00070750d10582d5,0x000bac36439d75ea,0x0003289cf3d0b175,0x00003a7564e11d01}}, + {{0x00004cd2f52d2a7a,0x000a42df565a182f,0x0009fb2f74fde149,0x000897180c5eeca7,0x0000b491d7bc2ddc}, {0x0006c18c6312c7fe,0x000c8aa41a5799d7,0x0005363a0ca0d5f3,0x0002c191207325d1,0x000082aa2669eb25}}, + {{0x0004700ec3128c2f,0x00019e383f4994ab,0x0003024eb6c76d86,0x000c68ec36b150c0,0x0000b43947843daa}, {0x000764a8dc796230,0x000db440fbb2fc68,0x000c5ee0d5b86995,0x000bd3d66879bfcc,0x0000522894295aa8}}, + {{0x00040a51e6a75c1d,0x00053ea7d817b51a,0x00077459724327c7,0x0001633663018207,0x00006fdbec467fa7}, {0x0009dfb13c90f48c,0x0002a86ef26320c9,0x000f64eebd6ac527,0x000c3206a50bdcfe,0x0000d87b28246fdf}}, + {{0x000a43e3fcd3efca,0x000418088e9ab24a,0x0003d46eadd26c03,0x000a6f05ef4dc9bd,0x00002f99d592a4c6}, {0x000d3552f1da46cd,0x000d4afacdd1ddab,0x000d4057872c3f8c,0x000b94090c4eee92,0x000028bb4209a623}}, + {{0x0000711745edc116,0x000cddc8755850fc,0x0009d1e649dd9ad7,0x0000f96e6931fbb4,0x0000c77a0a3298bd}, {0x000a6296baf7cb10,0x0001ccf72d2262b9,0x000639071cf065f9,0x00032f7203cce979,0x00009ae4885f9cb7}}, + {{0x0003becee8314f30,0x000ddbea298f5e7c,0x00080acec1c068ae,0x00095b08d381f17c,0x00003b56be8e3304}, {0x000b8f29222882d6,0x000664af8bf7aeff,0x000c57d8c95ff38f,0x0004eff0e32d351f,0x0000635be5277b44}}, + {{0x0005276a5177900a,0x00075685875204d1,0x00015796c4e1dbb4,0x0007bebb475622c6,0x00006fa038809186}, {0x0005d562844c6d0a,0x000a63a2477ded7f,0x0003721d6c633cf9,0x0008e656be5c402d,0x0000f312eb889fd6}}, + {{0x00092d2e7417ce17,0x0001270ee7f52427,0x00067a41eff42bc7,0x000a57aff4dc6d5c,0x00007709b7b90882}, {0x000731dbe217f2cb,0x000cabb721773554,0x0001dd0592af2a8c,0x000476a8eee76959,0x0000b2930c9fbba6}}, + {{0x000e0477d930cfc2,0x0001196fd1f4863e,0x0009af7e14c262ad,0x0004f6d4765bc803,0x0000519834b7ba10}, {0x0001b4cd105f961c,0x0005163bca547cd6,0x000a1f17ca5415da,0x00012bb78280a088,0x00004968949e3295}}, + {{0x0009126cecdaa7af,0x000d1b13247b174a,0x00084c1c4fc8c7e0,0x000c3a39c110d234,0x00008eb8758731df}, {0x0000212c00674527,0x000e0b9b926c022f,0x00042daf43f6f69e,0x000de399032da0ef,0x00009f00adef3f80}}, + {{0x000db7181236c972,0x000b1ee0781f6210,0x000e4137274f7685,0x00053e2df7da7ba3,0x0000aae38b1d1a15}, {0x000e222f6dd9d1bb,0x0007ab8b64871688,0x0002edeaa5769544,0x000569978d21274b,0x00002818fa5ce859}}, + {{0x000dddaf176f2c08,0x0004625726581e6a,0x000342ffb01ca460,0x0008d58a404ded85,0x0000cf60f96c4183}, {0x000691cc9071c4aa,0x0003944428039bbc,0x0009c0d81fd58874,0x000f7ef7101c8580,0x00007fb754d2c456}}, + {{0x0003c5cd51805e1f,0x0008c299dca8c95f,0x000eaf500ab4ccd3,0x0008924e03d20b47,0x0000a3165c2c7b80}, {0x0008b54e160e552a,0x0009f019d11f005e,0x0009a4a7adc4972b,0x000fd681a6972e0c,0x000052c258fd7840}}, + {{0x0009ff4c1e99d816,0x000643c617c0f855,0x0008c6ba708e1a7d,0x0007945398fd4324,0x0000ffedd9231283}, {0x00059d2d629d2080,0x00053490530e8a6a,0x000505989a9d141d,0x0004ee42f6fc1838,0x00009bf250d479d9}}, + {{0x000d3b1b38227904,0x000053b8971c223a,0x000f7fa626c5926c,0x000989209efc7e75,0x00005d66a6d5ec2d}, {0x000d663987d2792d,0x000c6eb31d2b4422,0x0002cb9e64a73caa,0x000a84206c2ac1a3,0x00009445c6061aeb}}, + {{0x000a1d5af71013f7,0x00049bedc9466af7,0x0007370a0e68216e,0x0001cc84cba30bd2,0x0000981afbff7042}, {0x0006a679449f0e1f,0x000d1a47edae0249,0x000feca2286cfc4b,0x0008fa4073c936b1,0x00005694612f3f8f}}, + {{0x000b723901515ea5,0x0005249cf038d063,0x0009e50594c6c77a,0x0007c01361e360ab,0x000096cf171f76a3}, {0x00053fa6530ae7aa,0x000d6792a7a6800f,0x000db81c90f5e631,0x0000b9bcc29c24ef,0x0000269e868df9c4}}, + {{0x000f9e12cb7191e8,0x000865b08ea6ec14,0x000332bb978ea1bd,0x000e24bc65aa9b46,0x00004cc22b43f80c}, {0x000e9e9d49d5bf18,0x000599087da40098,0x000f6e357cd4ec1c,0x0004b7bc9d07c5ae,0x000039a02691f8f6}}, + {{0x000eb62c6d8607f9,0x0004daa995e4c5e9,0x000b48317759689f,0x00017ce0464669bb,0x000021474c074024}, {0x000135b2a354c8c4,0x0002412fa4b5cabe,0x000311fe8d51e52d,0x00014bac74109653,0x0000f774535f8645}}, + {{0x000d6715bde48f8d,0x00025189bc7dbcad,0x00009ee8ac970387,0x000ff78d45299ec7,0x00001287ee3545aa}, {0x0008874db1dbf1fd,0x000ac90c88d67d1f,0x000368313ea46588,0x0003ad90ba649a84,0x00005fdcbcf30d54}}, + {{0x0006d43810d5ab00,0x000904d7e5cc90b4,0x000337c336739d8f,0x000c40021c1a580d,0x00000a6116268e67}, {0x000413b379f0a1ff,0x0004f9e2ab9595ef,0x0005f199cfe12660,0x00091277578b852f,0x00005c0032a1cb84}}, + {{0x000643037577dd85,0x0003d9c5fe88f795,0x000bdc13283b82af,0x00039e4c1bea26cd,0x000089fa086ec043}, {0x0009538b13799dff,0x0000e295d034033e,0x0009ddcca85fa8b2,0x000333ef17f73fbd,0x000032bd123cdb66}}, + {{0x00088a7858b044cc,0x00019aa9e39755ef,0x000d855591f0d69c,0x000db195fd9cc340,0x0000774df733785d}, {0x000e9f6d3bd2e1c7,0x0000385dfed05dcc,0x000ed09c4eb30da2,0x0001bceed7f5bbd3,0x0000d42a35cf2a9c}}, + {{0x000e9959890272db,0x00098e713a10cf3d,0x0008227b875f3432,0x000dc7ae13479fe2,0x00008561eaaaefac}, {0x00097a08332aafd7,0x000503809b62a6a2,0x00063036f9b0d8bb,0x000da862fa1cfd0c,0x0000a16eb562d64b}}, + {{0x000f5f678e62ddc9,0x000377fd752b3f5c,0x000437bbe2267c45,0x000074ce361b6b5e,0x00005c595021354e}, {0x0005f85f2b254d9a,0x000c8cb52b4eec72,0x000425fb5844b617,0x0003124d8554f5cf,0x0000b67703ecaf9f}}, + {{0x0004ec13cf482834,0x00055c8a705e4cc3,0x0007d4f84b09daa2,0x00029d91e9d0d05b,0x0000df6ef651b389}, {0x0000763aa21ba469,0x00081293f8fbe16b,0x00020aabfc6b1d17,0x0009797ff5b602d5,0x00004d671be53393}}, + {{0x00098cf4f5792fac,0x0006512152617c7d,0x000c5a6d47c5e0d6,0x00074cdb19a631a7,0x00008511a633a452}, {0x000621ca5a60d998,0x00084f5e48cb0c16,0x000ddee08f7fbab8,0x000f3c2b1e6ca2f7,0x00003bd08cf67867}}, + {{0x0008e8a2ac13e274,0x000f0eb1a9f5f7e4,0x0001f0a624494f6d,0x0008f0adbf84eb98,0x00009badc3293643}, {0x000a541004f7571b,0x00002f1c94ee50be,0x00027bc31bac67d1,0x000e27753d73a1b7,0x00003d01cf2e0686}}, + {{0x0007b1b55fd0b8ba,0x00035eec317351b7,0x0000e72b7a099d18,0x00035e802b1fb767,0x0000dc88b3448e16}, {0x000216af989d9051,0x000019b58d0134e8,0x000e55a93c2e68d2,0x000f4001f81c926f,0x00005f1462a9f296}}, + {{0x000d375ea3d62f2e,0x000221c8977d1915,0x0007b26f6a17765a,0x0007a49559710ae4,0x00000bd29c933507}, {0x000976d08d84858f,0x000479ced5c1615f,0x00034fa56370dfe8,0x000573cbc7503ca7,0x0000bb9f1ed81ac4}}, + {{0x000ec53060dd7ef1,0x000d5e65797995d7,0x000a08235eef2dac,0x000a3d44511af3e2,0x0000e324aa42f4ae}, {0x0007e71e6e676710,0x0000bf52faf7550e,0x0003cc62abccd519,0x000b5df880d31622,0x0000d402c7e2b32e}}, + {{0x000c039306a5a3b6,0x000d36783a1ba40b,0x00053cdd44e0a41f,0x00063841e8d39a02,0x0000480be2727388}, {0x0005e1d2285f3821,0x000fdc0b5c36ee36,0x0000f4d82188d8d8,0x00029a24ef1a481f,0x0000a8f43e1b487d}}, + {{0x000226d77aefb3a4,0x000dde72c2538168,0x000594df1f69a751,0x0004674e04359ae9,0x000075ffd7e114c0}, {0x000c2b13844e95c1,0x0007cd12ef94b5a2,0x000063d0085caf64,0x0003110ecd2a9ff1,0x0000dd2e22933843}}, + {{0x000e09d73d172440,0x00068fc653f138f0,0x00020e21c3ede774,0x0009eaae4459f5dc,0x00000db2ffa6a859}, {0x0002c3930cfd9057,0x000435c112a61168,0x0008bfe954934d07,0x00041a4df063c556,0x000079a440a716c4}}, + {{0x000f21897d6fbdcf,0x0006f0776aac0c23,0x00012e8dbd3a5cd8,0x000e8cdee37f72d7,0x0000b28c70e16f74}, {0x000c728b61301a0c,0x000813724354ffe0,0x0008ffedca628216,0x000de8bff4cb0076,0x000051b3088c3b02}}, + {{0x000147c3902dda59,0x00066e6973b4a5a8,0x00057457e35d2f70,0x00011acac2efcfc2,0x000033f48d517006}, {0x000af884912beb26,0x0005b62edf94c365,0x00032f34b7f5a4de,0x0000746646ba7c0c,0x000032c6af412091}}, + {{0x000f2e3753e43a97,0x0006b4d4e23f58d4,0x000ede6a670e1d21,0x000b60424bf729af,0x0000f4a94d8e10c8}, {0x0000a968d4faa6a0,0x0002b066b690aad9,0x000b6dbfdd9ed0b3,0x00043152fcd37b78,0x0000b64615e8bd2b}}, + {{0x0002048cfb9fad53,0x000cf40b76bd228e,0x000dad7bcbeaa386,0x000f5dfd6681c890,0x0000e553fc336d38}, {0x000db9b9d5f97505,0x000a828c5b0ef27c,0x00047c39b3e85c52,0x000827c90795af52,0x000047831ec0ddd6}}, + {{0x000a2274a82f424f,0x00078e47f89df327,0x000c7392c36919c7,0x000efdf478391943,0x0000101b9ab1316f}, {0x0009e9c1c5009d2d,0x0002ccd18345bcdc,0x000ce77c7fb55ea1,0x000b3d25b5e231a3,0x0000e6b4528a2f2c}}, + {{0x000a3339bb26f5f6,0x000da44d85b610f6,0x000197e541e85db8,0x000ea863697a0894,0x00005e18cc107cb4}, {0x0004f50a471fe6ea,0x00098f13439ca38c,0x00007318bf031747,0x000b3cb3c4a6bac0,0x00008da3ee5bdecc}}, + {{0x000b31c558216b17,0x000bbf79e6c20555,0x0008eed3c90c7810,0x0001262b669f4dfe,0x00000398ec950fac}, {0x000449ef701b2350,0x0003eb94f395a96a,0x000cb74310ceecdb,0x000c64285fc368d0,0x0000d37bb5216a18}}, + {{0x0000d38b880d2dd4,0x000b25930d570511,0x0006235f5a60f177,0x0006b93da34a67f3,0x00007f5e17c58381}, {0x0004b57db394af4c,0x000cb036f789c766,0x00027b47239ba215,0x0004b686d2ca0e2f,0x000042647efb73a8}}, + {{0x000754564488f1d6,0x000894cf85d544bc,0x000e4df63aa92270,0x000ced121a01d553,0x000049c0c51bdb46}, {0x000d64e3cffcb6c1,0x000e40f71d966bf0,0x000c194a0e3bf93f,0x00055465044558bc,0x00006ae33727afdc}}, + {{0x0001adf5ca48f3fb,0x0006322a9b84bfc0,0x000099e4a64352f0,0x0009c01ee54da1c1,0x0000bda54e9aa1b8}, {0x0003df56f6e55fbe,0x000340176f88166a,0x000b7b5ff1ca44a2,0x00049fb36afd88df,0x000034c24386611d}}, + {{0x000bb75861421033,0x000aef34fc4d7eff,0x000c1b1226704ba1,0x000ce94c2a468f10,0x00006b3a610bc6aa}, {0x000c0a775a0d0508,0x0006bce33e32abfc,0x000fe09be066f919,0x0003514e905ef429,0x00009ee25bb28376}}, + {{0x000de22fd29dc766,0x0008d6f172602a3e,0x0004b41267fd32ed,0x000fc7acadcf6828,0x00003422f0907951}, {0x00024f40807e199e,0x000042ad4490562b,0x000b2b1b4fe9ce5d,0x000d0ce2f51b100d,0x0000b361400c4541}}, + {{0x0004a052680813be,0x000c761b08d6bd2c,0x000205558527aa55,0x000bebc9f8a40ea7,0x00003eea570043d0}, {0x0003817a0ff58b3a,0x00047a69e6277b85,0x00069b5d6b67d3f6,0x0003ec6b76bbb9a8,0x00003afeb82f4672}}, + {{0x000416d3e5548920,0x000d430e2a455f24,0x00032a2a08413b53,0x0007b199c56aee90,0x00009432bf6eec36}, {0x00050c6daf0ecc11,0x00054bc920485528,0x00081130749ebce5,0x000597cfb66ba654,0x0000b84f7977f298}}, + {{0x00004818d1d7a0dc,0x00027a6fa5567959,0x0009e5d35d9fabe0,0x000576e40f9c59ba,0x0000b1771c2b6247}, {0x00047cae9a6312bd,0x000f852dd8c5542a,0x000794716a34b355,0x0000942df94de00d,0x000046124aa6c623}}, + {{0x000435d68afe8b4d,0x000f9c0d8ea156b7,0x00018689827f2053,0x00090e42b77e1473,0x0000bc3dd4744794}, {0x0009842c03b0c057,0x00030921bc96951a,0x000202e0a8b1b3bb,0x000d563573b3462b,0x00007e4665db7254}}, + {{0x0000dfcd23e39845,0x000c9bd1423608b7,0x000114ba7ab86e8b,0x0004f25a3e07f857,0x0000ac71689fb0ef}, {0x000a3840139d9af1,0x000866644af088fc,0x000d74f4a72733f8,0x000c7ae122f72a65,0x00003931577b5626}}, + {{0x000d9eb70f8d5a4d,0x000707bbb228d5b5,0x0001c0b32375adde,0x000ba961e88b860c,0x00001f568c4e73ed}, {0x000fc835459df02e,0x000a2fcd9a7e1592,0x000473b0a2beac0f,0x000c47d0a6fdb81b,0x00003224c6fefe8f}}, + {{0x000d00ee87edf5b7,0x0001b0e77cf5680b,0x00042d1b230385f0,0x000d7779ab98c04d,0x00002d191d343816}, {0x000daca0917d9e55,0x0008cf8fed7f1564,0x000bb3896394eab5,0x00098e5209aa8d7f,0x0000564f3ba0e6ac}}, + {{0x0001d05d73654ef8,0x000393d78d74ead2,0x0004973a068d1a9c,0x000329e1e017086d,0x00003da3500c6e6d}, {0x000fca468ae01189,0x0009402da0696a3d,0x000ab8302a1b9a4c,0x0004357b2ff9c7eb,0x00008af07c4244ba}}, + {{0x0007326995f0f9ff,0x000f81b58bc68599,0x000625a2b467fadd,0x0008cc57e4495abd,0x0000dd2d01e23c3b}, {0x000ae28c693f9fa1,0x0009248f79992c38,0x00061f5834862232,0x000cc987bf738e21,0x00005ee2fa7665e8}}, + {{0x000c8455777e1891,0x0000356f2829a1a5,0x000762bd5cc10bee,0x000da87ad95c56da,0x000052e2214f9d91}, {0x0000e727cb23c74a,0x0000090c66df975b,0x0005ffc53fd5d767,0x0002ae15b5b8ad22,0x0000b6dff749aded}}, + {{0x00067816f4cbe9d9,0x0008da574bd7ebd5,0x000a881fa0ed8b24,0x000c6fb1c246fe81,0x0000156480653db9}, {0x0002b085b8628093,0x000125858d7bd7c1,0x00009e92a1facd1f,0x00025f4693747caf,0x0000b69dcba489a4}}, + {{0x0008e9f967365efa,0x00024801f5c90be2,0x00083352f57300eb,0x0002b6f3b8ac6ad5,0x00002cf1f8a6d05b}, {0x0009b744dcc40cc3,0x00057da523fb7c0c,0x00099cc4dfee38c4,0x0009c6849a4dec10,0x000025c377f99f06}}, + {{0x00058ce476cc9ff0,0x000cc6d4cb63e124,0x00072289b580e0b6,0x0006dad561c8b790,0x0000377f264a619e}, {0x000536288e591a5c,0x000cb523ca2b2668,0x000df4533a453a7b,0x000f78ca9536d2c1,0x00008e50f307e972}}, + {{0x000e50f6d3549cf8,0x000f7acd665ed433,0x00011fcb46f33696,0x00085fe95bfdacce,0x000010ee2532f7c9}, {0x0000fe17159bb2cd,0x000da58b357b6545,0x0009fea72f7dfbeb,0x0007445b057e74d6,0x0000485717b62731}}, +}, +{/* digit=23 [{1,2,3,..,}]*([2^161]*G) */ + {{0x00042e8ee36860ce,0x000c6113c22d896c,0x000104213daf04df,0x0004e93adbb7b744,0x00005fd5fa1ffd39}, {0x0005d941a4e0551e,0x000d38d101516823,0x0009845236772cfb,0x000a97476071e309,0x00004e879df3a56b}}, + {{0x000afb0285b94916,0x0007be4c705eaaaf,0x000d9caab01a0be8,0x00033f9f1d4f5d2a,0x0000e349a4b237a2}, {0x00012464a1c6a163,0x0005f9383260cf1c,0x0006d5471d99e6b6,0x00089bba3d43665f,0x00006974d052f8cc}}, + {{0x00049a1cfe89d80f,0x000cea9c8371c26c,0x000d066d2b42c026,0x0003edda6c013ada,0x0000b8f722946a4f}, {0x00079ecd850935b3,0x000ca631e1b308b5,0x00019853434c1a74,0x000f259b5fe596ac,0x00009ff21f711f24}}, + {{0x0009e148f9290579,0x000630c853df27f2,0x000e9c5ce7a64ae0,0x0002a4956cd18358,0x0000d9cce836ed09}, {0x00059796e93b7c7b,0x000181bb9e27cc6e,0x0009e29a0e1e4709,0x000644070b3083aa,0x0000f181a75e785e}}, + {{0x0002c658ead09f79,0x00050780d14df53f,0x0001b66bc1335e1d,0x000fc7d9cc20e0cd,0x0000b670a384be0b}, {0x000dc8128efbeedb,0x000bd326a6e5ce53,0x0008e9a630c74e77,0x0002478604e0d2b8,0x0000ab38fcac3dc2}}, + {{0x000e8c85c0a3f1ee,0x00019c87c37f8ed6,0x000e3b78dbcad249,0x000a461dfb62bb9e,0x0000ba8e478abceb}, {0x0008cb0eeaede4b8,0x0007f976deb637d3,0x0006147fb0bc498e,0x00060932944c046b,0x0000b123f36771f9}}, + {{0x000dcc7de79dc241,0x0002458f69cda155,0x0001850dff1168a3,0x000848aac215950d,0x00005c8295bc204c}, {0x000aa367d8184ffe,0x000d50447bdbf661,0x000e4a59ec396228,0x0005e531cd5143bd,0x00003a26e3c4beab}}, + {{0x000a13f1402b9d0c,0x00026c7bc863d3b3,0x0008c3e6e573441c,0x00057d8b301ec457,0x000026fc9c4cadaf}, {0x0001bfd7493cea35,0x000ecaf8145696e7,0x0008c608fd05d4b3,0x0002768aca2a8a6a,0x00003ef07f65725b}}, + {{0x000fbd27824fc56a,0x00077328907707a5,0x000c483493467521,0x000874bbf69fd5e0,0x0000613ddd456aa7}, {0x000c19c5450d8660,0x000c8f84a4817f78,0x000fce23946f4409,0x0004b99f1d192890,0x000016c4168b2ce4}}, + {{0x00023f0c74359787,0x0007b0e30e19bae0,0x000fa6fafb152c88,0x000e602c241645e3,0x000035d95c1f4823}, {0x0007573039553173,0x0009c03b49950319,0x0002746000b4b02a,0x000507d76bf55970,0x00002c5cc53daf57}}, + {{0x0006d1f606241297,0x00042a5e2b5ee8af,0x000082d72b7bc5d6,0x000779c814b0485f,0x00006f267f33e196}, {0x000630fb36eed930,0x00073bf56803626c,0x0002736a055230cd,0x0005f178837949ce,0x0000d792d60aa6c5}}, + {{0x000dbfdd5c7c5d2f,0x0006172b342d0318,0x0008de38ab38f8da,0x0008414569bddc7b,0x000025b588891c94}, {0x000b2842946ad608,0x000d69d1707eb2d5,0x0006a4509854f29a,0x0008372a5159dc2c,0x000099f94c0d7189}}, + {{0x000dc51f4a55b03c,0x000d75e3b2d5cf6a,0x000827b51261762d,0x0004418cc4301204,0x0000d22a11486021}, {0x000d61a247c9569c,0x00031152becace2f,0x000a716d459a5097,0x000dceac835a1163,0x000026455edd87de}}, + {{0x00036e049ce89e7e,0x0008ec890cb527f5,0x0003c2aa11890853,0x000bd2508909abd8,0x0000cd3142bfab73}, {0x000bf59b3f5ab84e,0x000812bea4c66a85,0x000a4541f3c320a6,0x000185cd8dc5386d,0x0000af34eb197c41}}, + {{0x0000129977c97c4f,0x000ad57eb9fa1c78,0x00022c4785ff9bee,0x000414b24d0524c8,0x0000d8eec2b361cd}, {0x000194ef027458c3,0x0008ed1be115fbde,0x00066d6f4b4ff531,0x0000c933f874d948,0x00005c75015e21ad}}, + {{0x000c9d646ac49d20,0x000b83137aa9a6b5,0x000225a3842c77c0,0x00090724d000fc68,0x0000f63cfc82fe1e}, {0x000b01bc6441f959,0x00095c8e448f22d1,0x0007fb1ba7d38f71,0x0008df0b33fa5f78,0x00004dcfda1a9015}}, + {{0x000b3395f6d4a09f,0x000bfe52b826c47c,0x0001b930a6b4f355,0x000f684d100f5df5,0x00004512fad8f668}, {0x00081d5206c4c74f,0x0003db4d2e485467,0x000085c2dd021d4d,0x0000a7594a54c2ca,0x00001dbaca542085}}, + {{0x0009326490a1aca3,0x000c11526b0263c7,0x000979258cb64dd9,0x0008468b772591a2,0x0000f58297078d97}, {0x00070d17c213ba70,0x0005e8a0ced4d66b,0x0000338c1c28febb,0x0006f36b911831c1,0x0000d54e389bf012}}, + {{0x000d4604af206ee4,0x000637e97cb97048,0x00064802e786c88f,0x00011c94375ae1ac,0x000069bcfe2153ec}, {0x000340d470622302,0x0007a5b4a3acfc9b,0x000ef45ace743bb5,0x000188de00b4aa59,0x00009a4ef2379edf}}, + {{0x0002efeb483689bc,0x0005913ac2624024,0x000a6db722575d3f,0x000be2330037c80c,0x00009fcce8358864}, {0x00012ff0149362d4,0x0001dc4ae97184a1,0x0005cf86c95e5758,0x000a2edfa4b1a894,0x0000525a7344b024}}, + {{0x0008b628f3383609,0x000298edf32be76c,0x0008b1aec483ff59,0x000a20d7e8e90a29,0x0000caab339036d9}, {0x000d2fd668927090,0x000cb55a1d415c09,0x0004a43942496b4d,0x0006c193f5fb1ae2,0x00008c750496fa8f}}, + {{0x000d1c2c905d85f7,0x000f9733ae57caea,0x0007cdd94e9d7f78,0x000930b4c9a65cf0,0x0000389359d14b55}, {0x00009b7367e45f70,0x0007cb7e7adcf587,0x000b728181f20306,0x00003382444bffc7,0x00007303b35baac8}}, + {{0x000e4e4d13b7ea1a,0x000440e741801e1e,0x00070ef70e6489b2,0x00089405f2c6107e,0x000016554135dd10}, {0x000befb7af4194e1,0x000c7e89bd9c555e,0x000895856533c1c3,0x000c15635b9b5789,0x00005fb3cd2667f5}}, + {{0x000ed45526f09fd2,0x000c6128240a057f,0x0002bfd8de8a4f10,0x000a317332efc4ff,0x000014e77a0dd35a}, {0x0006d7314faa40ec,0x000b41e5f1863289,0x000a1813e767867e,0x00079509adf8f117,0x0000b6cda7914741}}, + {{0x0001b6d349d51aa0,0x000ee3c7b8e9b752,0x000a096dff56b5a9,0x000024c6f1e5c932,0x000083667c4a3635}, {0x000a13518087f2fd,0x000c0136e45d365e,0x000aec989f1b8eaa,0x000258f8a0e48473,0x000075a324be42c9}}, + {{0x000d00101dae185d,0x000acb7a94bcb7b4,0x000d8cb0b45434e0,0x00049e254339affb,0x0000cc4569fb98ef}, {0x000318a09a512993,0x000682b025d87789,0x000e8579281b4d20,0x000af7c64aa418fa,0x0000e50258fdcd7b}}, + {{0x0004cdb2996864b3,0x0008ef485fa4dce8,0x0004c6a5aa2e6708,0x000d39828b2bb653,0x00001a7ec6bf94b9}, {0x0007766d6bc20da4,0x000c467611901d21,0x0007010634acdb5e,0x00029b2872632873,0x0000d24ee7c6128c}}, + {{0x000ebd3a19fd8680,0x000cdb8ddd3bc072,0x00064d852612e481,0x0004abb4e1d7541a,0x00000ef95acc4c6c}, {0x000d2edaa0a6c469,0x0005b37747901536,0x0003fda106129408,0x0006f1c4af25e834,0x0000ff9d98e8d25d}}, + {{0x000af7c468b8835a,0x000ad30ecea70746,0x000cf4a81977a31c,0x00037a05096b80c2,0x0000a9868340458c}, {0x0009bf3a6bd9d340,0x000b33c5d8546af2,0x000133b5e6a62fe9,0x00084850e6c304b7,0x00004b601597d6e6}}, + {{0x00096df5579bea49,0x0007cceedaf14cd2,0x000bcc5b110e35ac,0x000cf874c4c5fde3,0x00005f9ee8b19412}, {0x00059ee82b6eb0fd,0x0004c5c2aadd2c94,0x00027fcfe2e84576,0x000475a74a84aed3,0x00008c93722d368d}}, + {{0x0005748f83e8a3b0,0x00068d2495f30dbd,0x000496e9ba579aa9,0x000cc2535996a0ae,0x00007afbfe9b7f9b}, {0x000dc6d5b7bd2931,0x000f6022323d3ac1,0x0000a3e763b592cf,0x000acbaa0deb989c,0x00008e78e9f5b197}}, + {{0x000de10296c36eff,0x000192c4da77211c,0x0007836da7ee8967,0x00060ac617d270a5,0x00000cd9c328cb75}, {0x000cbf7e455fe908,0x000afe7334f301fd,0x0007de4ec3fb53cb,0x000fcff81e2ea44e,0x0000adab3ad8b384}}, + {{0x000ee2f53d648293,0x00077261492b129e,0x000cb4a2c7a471e1,0x000c2db4f9adb9e4,0x0000d359f6fc7ba2}, {0x00067860aacd6975,0x000325c2f8a8346c,0x0005df44e92b444c,0x000f31779fa117d8,0x00006782372898dd}}, + {{0x00090f2bbbab3b85,0x000e3b04816b60e6,0x00092e4d24851f8a,0x00036b772046ab9c,0x000018c74a1ccf31}, {0x000b50af9877d4ca,0x00000919cabbff4e,0x0005eb2b614578d9,0x0006e3e218f8c4ac,0x00003ccc547f4201}}, + {{0x000f48e327f83495,0x0006a43cb641025b,0x0000f1085f3e9734,0x0000558c2bafdf50,0x000071678767f063}, {0x00014b9411925a6b,0x0007f1123de55bd9,0x0002b165d7c078d4,0x0007273e6bf83518,0x000011b5e5c6a519}}, + {{0x000a76c1eea7b85f,0x0000a2d4f85ee33e,0x000e115bb2352b46,0x0005a30101d334af,0x0000abc129578917}, {0x000cdc05233f9251,0x000bd77fec557f6b,0x00069b659e0a802d,0x000d74adb47b7580,0x0000c5e12df098fb}}, + {{0x00058c64b8457ee6,0x0008ef7ea9f7869c,0x00060b38fa5360f6,0x000b368576c09ff4,0x0000b70d54882b7f}, {0x00037f13bfae3154,0x00028bdff3693fd2,0x000b516f93379785,0x000d2d57df25f525,0x00006f388f2fa38a}}, + {{0x000465889d8ddbbc,0x000db0f38ee8656c,0x0001212b08830b26,0x000db18320fd5cde,0x000034f30d0a4a2e}, {0x00031a356ab64b81,0x000cc99c5d26abb1,0x000981d947f77f0c,0x00076e56856a37bf,0x00009e76d09838bd}}, + {{0x0008ac396238f398,0x000e2830b366e76c,0x0004eb499c0a482b,0x00086537b8eaff0b,0x0000ecd83bccbfb4}, {0x0002cb7a2f3776f8,0x000474b88adf971b,0x0001fa446b42176a,0x000bd239617df5be,0x0000b32d5094d031}}, + {{0x000d47d53b618c0e,0x000b8a2279231c6b,0x00092d964c424f46,0x000bf19303ffdedd,0x0000971287951b5a}, {0x000a632f815561dd,0x000503c055d18f48,0x00025684f85f48ff,0x000cc2522a142775,0x00000d841a137360}}, + {{0x000a9260b9267c6a,0x00012f07f8634245,0x0000d9e24c78913f,0x0000170a844c8e4d,0x000042ad522dd5f9}, {0x0001749a2c989d55,0x000f91f5e78ebd37,0x0001ea6da928292d,0x000528f93b383e0a,0x0000136fd8d63aee}}, + {{0x00044b1f2c34a996,0x00045f5855ac860c,0x000af37be3b00aca,0x000c084bf6aaa0fa,0x00005f436828a53e}, {0x0005801a11b12e13,0x000cb20ed4751d9a,0x00041e0d578a7ab2,0x0003e9dde1067e9a,0x00000473f5f60502}}, + {{0x000e09d169c7d97d,0x0003ffaef9cddd3a,0x000a448035cd5baa,0x0004dd8cd7440b65,0x0000c13966b17f36}, {0x0002be82b8357c1f,0x0004f9d57c2a077b,0x000ff363e0cb1b4c,0x0009ee8a4ceb3205,0x0000310fa4eba35a}}, + {{0x000b352f97f68c6f,0x000f1b02cf58dbb7,0x0001f96d90c773b4,0x000814fa2e48213c,0x0000fb357b1dee01}, {0x00024cde0f28039c,0x000986a3fbe4b9c9,0x00046db6c0b36c95,0x000afe5faaaea45e,0x0000ae575c3d928a}}, + {{0x0001302a70dab865,0x000921c58cfc7f67,0x000e0cb92fcbd12a,0x0005837bef9acfbe,0x000073da0ba48c1b}, {0x000fcfe0d41d5505,0x0002d155cffe4752,0x0005ae248e7eec0e,0x00044dbfc39fcb54,0x000022cb8d1d065f}}, + {{0x000962a70cbb96cb,0x000a0cd124a9263c,0x0002ae58de034362,0x0005074120db283c,0x00009a38d4aaef6d}, {0x0002a821ff140fd2,0x000000aee7e0b1fd,0x000251949bd162f3,0x000c3d2e17a5d4cb,0x0000aebcb836f7e1}}, + {{0x000b25f937b05271,0x0007db7d9997608e,0x000a53a29f42e1e4,0x000536dba699c4b8,0x0000f921c71f091b}, {0x0009e7b5b26bbd51,0x000d2b61a680cce2,0x0001f1c7e7a8ef5e,0x000ddad5ef8043ba,0x00006ea821728158}}, + {{0x0008a2b599ff0f94,0x00074104fc6b0177,0x000694ff368a923d,0x000f121bfa44dfda,0x0000f7199dc37667}, {0x0008ff6e46f2a79c,0x000d29f8131dc06d,0x000b4ce7c08b5dea,0x000c3d42519a59ab,0x00004f710bd742ae}}, + {{0x000b05778bde41ac,0x000ff4186b5a3d77,0x000c657416474bf7,0x000153448b3f6788,0x000064519dec3c7c}, {0x00038460edfcc4f9,0x0006b8f1aa6bdf07,0x000909f77319aa73,0x000feefb9f8a02ca,0x0000025813a0580b}}, + {{0x000d3cac0c227196,0x000469ca151ed8bf,0x000a1a69cc60209e,0x000f8f1a744ab5d9,0x0000de5048b74937}, {0x00038d8e115ac04c,0x000f5c6b16d21719,0x0008e94e77df7093,0x000093e6aeb6637f,0x0000130388eea2cf}}, + {{0x000be8477f54e6e0,0x000265d60fe51850,0x0009146d69f258a7,0x00030bff7ff0c06c,0x000039aaf90e63a8}, {0x0007a739460342f0,0x000c3f795f8a38f2,0x00081a97e4703148,0x0005941bb5467b96,0x00000931ba5ecaeb}}, + {{0x000719d786f337c0,0x0002e704397dcdb6,0x0005c2fefd9c01cd,0x0002230f4a3f2055,0x000004525097c0af}, {0x000804784db8e765,0x000a43c8aa0654a5,0x0009194223bacf1a,0x000a3fc1ca957cf7,0x00000641053c8cda}}, + {{0x00038749f7144aea,0x000ea3d4acfd7a30,0x000ddd3ef170c963,0x000ba7be14814958,0x00007bde5833e72d}, {0x000da8b6fa687508,0x0001d72e02490769,0x00019ad31fa64e53,0x0009cd7caadf9d26,0x00007882dab27b34}}, + {{0x000b7316c67a7751,0x000adfc5d0b19f6e,0x000b806b2cb10471,0x000e7ea433750ce1,0x00009c5714d67b1a}, {0x0008b7bed03fd3f8,0x000eb1bc194ec0dc,0x0006320b5dd03344,0x000d93266c52a78c,0x0000bc82ce450b6f}}, + {{0x0003501b35f1341b,0x000c75a43e42f8e1,0x000aeb85ce53156d,0x000eb523adf27e4d,0x000081d837a6bedd}, {0x000546e2e4358674,0x0004aba5dd601b0b,0x00010cb9d9020eb9,0x0001cef7d9116182,0x0000c596b319c91f}}, + {{0x000a90f0e0b040d2,0x000225ff897fb228,0x000fa6122baf02d8,0x0005570aac79e600,0x00004828817ae36f}, {0x0001d31113ec3567,0x000da5eff1f8b952,0x000d417159e48861,0x0001b7baa1d412e0,0x00001f86203c3f13}}, + {{0x000a8da3fd19408b,0x000b778d9d99f60d,0x000c51c904aa716d,0x00051b894531f7a8,0x0000560b0e9a59db}, {0x000c992fa34bdad6,0x00043cd4f8bda28f,0x000a9d0d3f024fa1,0x000b55fcf530f723,0x000015ca194428c9}}, + {{0x000483d6f73c51e3,0x0002ba0dc2dd6d2a,0x000b917ffa4cb241,0x00099e20663c411e,0x0000d3a74d01ade2}, {0x000990f4a7a92024,0x000967b15c3d29b3,0x000df9208a9bccf5,0x00092926a3ccdca5,0x00008027c1483f2f}}, + {{0x000377c40b557f08,0x00064d684660d385,0x000183a27e001c36,0x0003289b18ed6be2,0x000079738d8e3210}, {0x000c74bbda948826,0x00084684b299a687,0x0003b3724d1bbcc4,0x0009f84f6f111286,0x0000943d1b48c8ce}}, + {{0x000a3bb098cafb4c,0x000fa0d48cafe044,0x00031b84d27ed230,0x000ed6942b56753a,0x0000bf3dd51bcddb}, {0x0001f1641b1d830b,0x000d1b0c1e272503,0x000ae75dba7ec851,0x00011ffc1c8fe0b5,0x000024c7557b8c52}}, + {{0x00011dc1d4636c38,0x0005e81a993957f8,0x00081adb3f843652,0x0000d39f6bc6d99c,0x000040f8ac3db7d8}, {0x0009811f4387f1af,0x0002c5156880731a,0x000e688677c501cd,0x00011fb5ca4a07df,0x0000123d8f14fcea}}, + {{0x0000e71d607039eb,0x00051d3a45461fbb,0x0003240912b70e21,0x00019a82d2f01d53,0x0000796ff08c80ab}, {0x0007a863c57c4aa3,0x000f87c49a2732d8,0x000630d982aed9ca,0x0000a36fb35eac31,0x000038e8cdf8c3e2}}, + {{0x000618266cde8dbf,0x000f3d72fd3680f1,0x0006e50724e15997,0x000dc0e7b8f13b9b,0x000052139082b7b5}, {0x0001f1d8ce4396ea,0x000007ed21424d43,0x0001aaf6b37a1a68,0x000b661f375696d0,0x0000a1c0c55863aa}}, + {{0x000368b4ed80940f,0x00058a6fcedd3014,0x00097579f67e6d05,0x0007f58c208c49ca,0x0000e3d7a8292359}, {0x00032027e096ae27,0x0006b4b393665e20,0x000dcdffcb1f3e1e,0x000e82b6da26f32f,0x00009422f1dd097b}}, +}, +{/* digit=24 [{1,2,3,..,}]*([2^168]*G) */ + {{0x0002cfb9db3b3818,0x000e54df0a4b263a,0x00004e61f9c3a2de,0x000324f28d06e97d,0x0000b1adfbcc2449}, {0x000d9397e053a1bd,0x000696daf7076ec1,0x0000ac7abee2be5c,0x000173b0ba1e1481,0x0000d2ae779c530f}}, + {{0x000d97a205b9d8b0,0x0004056756d40435,0x000f8210e6eb8f06,0x0009ead5e88a8bb6,0x000070ef12dec9fd}, {0x00095053bcc876ae,0x0007c7404ce34d84,0x000a1db5e12a7533,0x0005acf22b49e1b8,0x0000c1f2051f4bfa}}, + {{0x000eb79b6828f364,0x0007c1bd5b9eadba,0x000844b0c9d7a025,0x000fc9ada01e0d1e,0x0000b625175c87ed}, {0x0009fdd9669b6210,0x0006f6f87b981410,0x0000df6bc88a2ca5,0x0003f9fe2eb78817,0x0000cea06f4ffa47}}, + {{0x00081b5c4e83d33c,0x00089efd488b43ed,0x000eb4d0fd9f3587,0x000393564a620f9d,0x00006927bdc6c6a7}, {0x0008df79f9e0f036,0x000e9cd7e1a945c2,0x000a348f12868661,0x0008e01cf4e8d0ff,0x0000bd4c28499853}}, + {{0x000a091289a8619a,0x000fc671b1732618,0x00090c632ef796e5,0x0008fac64e46e590,0x000038062d4be66f}, {0x0004a200573274eb,0x0003f92713946c74,0x000dc0e20d07b67e,0x0005a6891223b26b,0x0000e2d93f29b0a0}}, + {{0x0002e533f36d1411,0x00043dfca442f23e,0x0007c023ae84bb3d,0x000c3ba804a48d6b,0x0000e16a8fa86431}, {0x00052adddd472e03,0x0006dd1ee1271b54,0x000a275997d405ee,0x000b3520fc6f1dff,0x000051ac53cef391}}, + {{0x00014b84444896b8,0x000f794027fb7efa,0x00084487d64974d2,0x00089b6fdcd0e8de,0x0000c45b260ab489}, {0x000bbc2d84634875,0x0006efbc476ca8fc,0x000f443c0d1b2b3f,0x00039bd1d005b7c8,0x000018f2e6790c01}}, + {{0x0006e8c06d75fc1f,0x00064249a89f5603,0x00045e7dd2dcf7bb,0x0002a691dd1d3de2,0x0000578dc4cdbd6e}, {0x0008903df2ce7a06,0x00083c39afac4c02,0x0006404abaee3628,0x0008187c847c3114,0x0000304c0d904e97}}, + {{0x000dca2a91f6791e,0x000fbbaa9efcae51,0x0009c7ac12abe418,0x000739f9d2e2f455,0x000082f4b52dc9f7}, {0x00030274073e81c2,0x000cdbb596fca771,0x00084f70cc0276fa,0x0001dffd819fc9a6,0x00009b47fdde9f7b}}, + {{0x000e103459b19402,0x00093b013e93358d,0x000532ad3ec881c5,0x0006de31574c9349,0x0000db1d445d37b4}, {0x0005b87df239fd84,0x0004d51d24eec644,0x0003c6259c718af7,0x0002f76ea1c4a4f4,0x00000c0e5d7b0be0}}, + {{0x00090f4721b33f2e,0x000b1edf04ea6a45,0x00045efe72124f1f,0x0006d918e53cde97,0x00007e1043345f04}, {0x000a28ee4d0c7e6c,0x0009c7253b1bc3fc,0x00043e643847e339,0x000fc4db59534837,0x0000b6a0a0c0fd12}}, + {{0x00036c327d02dccc,0x0001ba68bcc2fb68,0x0005e912d5ad0098,0x000cfd5b24b44c00,0x0000c83d210411fd}, {0x0007ec1666fba0ca,0x0006747546353652,0x0006da9c26994819,0x0002b25cdcb1a855,0x0000593426821a73}}, + {{0x00014eda714181da,0x000ac067b341ec12,0x00045df1f609ac13,0x00076b5f4b4c97a5,0x00001240501d4d20}, {0x0000c231409ca976,0x0007c0638c436efa,0x000fb46cd254cc1a,0x000a2774e363afdc,0x00002c2adc363942}}, + {{0x0009df056e464833,0x000033736356c67b,0x00051bc52a55abb2,0x00064b7b93c098c5,0x000082b49f9e15fe}, {0x00021ad4dff8d47e,0x0004637df4d69ec2,0x00045650979caf61,0x0007137f13dc64bb,0x00004c589d9f91f0}}, + {{0x000a8ab3fd40e095,0x000e27313ea927b6,0x00055988be455842,0x000bfc3b51d1e21f,0x0000716dd73562bb}, {0x00011e54e8bf3de2,0x0005fb85be3b633c,0x00011cca69a0e77b,0x00090f3651072909,0x00007e764960fa65}}, + {{0x0008b33070d3aab6,0x000b3a2cd5e5e4ac,0x000fc91732643672,0x00013ef2eff79b1c,0x000065ca49bf0a7c}, {0x000da59b3efb9983,0x000cd52f13415a8d,0x000f9a5308a5b922,0x0004d77e9ebbab3c,0x00005986e7c256da}}, + {{0x0006b5cff3513cc7,0x0009c198f7dd3a63,0x000f16f86bb0cf8b,0x0007bf48d4052241,0x000060575d94e13a}, {0x0004e169f7aa1811,0x000fe509ed1c36f7,0x00040a491163a3ec,0x000caa5aead61f3c,0x000058c95fcefe8f}}, + {{0x0001b6e13cda46f1,0x0005242faed0a399,0x0006b59707948241,0x0006dde3ba5bde66,0x0000d52e6bcc26ab}, {0x000a1e78608dd3d1,0x000ada076586768b,0x000dc1afa4930db2,0x000817c9575714e7,0x0000fc7bf7e07c58}}, + {{0x000accdd9eee96cd,0x000b158cec376b47,0x00002c42a0ca277f,0x000e50413fe413e7,0x0000d1764ef947cb}, {0x0007cde7b3ed7397,0x0008ece9e1c0041e,0x00025b21250cb745,0x00081bc556851329,0x0000cff95c4701b0}}, + {{0x0004cbd8088b454e,0x0006ba9e0c8a63ee,0x0002447cbdb7f32f,0x00019ad377d4186b,0x00003e982abb3702}, {0x000c1e4c2a2a5938,0x00048773f24f06cc,0x00085942372c3686,0x000c8f213b4da795,0x0000bbf1d33f5040}}, + {{0x0000973da50c991b,0x000ad22d6ee2726f,0x000fd777148afcd5,0x0007a135fc718b20,0x00009e8e77ead080}, {0x0000f4499a7703de,0x000d818e36f37f5e,0x000807bbe6972930,0x000f4f4b7c77b823,0x00005b82406ab27f}}, + {{0x0008be3bd3790620,0x000d2dce4a92ba8b,0x000952e37d64b7a1,0x000eca040a73c5b2,0x0000a9e252ed438a}, {0x000956bc39d3bcbd,0x000fe32b2d63dd43,0x000417a181a31c9f,0x0002c8067133b85c,0x000008e4790fef44}}, + {{0x0001ae9255c09801,0x00011b4a739f98cb,0x0004a45a14bd8638,0x000b2f4a5c31e11e,0x0000e5d55feacb0d}, {0x0001b068ff5cc292,0x000eeeb8a4f47466,0x000848c24026b389,0x0002b0336b21a458,0x0000e5bf8eca1dc7}}, + {{0x00087d0ad886aac2,0x000a9771b64503c1,0x0004045ab5c16878,0x000aed907dfc6fc7,0x0000c6360bf9800c}, {0x0005bb5b9c972a3d,0x000dac9a6dba2429,0x000a79aa6c9e6f88,0x000ac1c0ffbf2492,0x0000e29d50b11c26}}, + {{0x000f483d309cbe6a,0x000a40bced4f9f0a,0x0008023e35b020d8,0x000932c06e986db3,0x0000d8f2c9dbabc6}, {0x0002e1de7400e938,0x0008d2be5e4d1929,0x0000680bffe3e18a,0x00006368e9771d2e,0x0000c5bec99454db}}, + {{0x000662a74a55d1f0,0x000f046f66d82af9,0x000dc4794e3fbf28,0x000dd8a3a72ab4d4,0x00009779f455c7c2}, {0x000bdafc3d19d8d3,0x000427d6a6dfd893,0x0002e6255d5a7509,0x000aff5cf8fef995,0x0000da67cfc0a9a8}}, + {{0x000f62a2c160dcd0,0x00038f90eaef4c23,0x000a65d5a34e6c5e,0x000a3d35865519a9,0x00007c48aae8fd38}, {0x000aeda50068527a,0x00027c90936ab7e7,0x00079324c2c09ef2,0x00093791ecfeb6e8,0x00000871f6c9b0ec}}, + {{0x000fb68d84d835d2,0x0009661dc1e6b1f0,0x00094f8d7c90caf3,0x000b91f2e5b04675,0x00006897ae285012}, {0x0008a08a4d6755dd,0x000b3991fbdabcf6,0x000bf17e8403ee41,0x000d64a33e343e3b,0x00002c7980e379b3}}, + {{0x0006232d2e11305f,0x000203c07a6f3305,0x00015509d966be49,0x0009a37a8878ffbb,0x0000f221101fa9b5}, {0x000564aabe30129b,0x000f836e64cf6c9f,0x0000c8022c6f2c93,0x000b865fe752628b,0x0000e0267ea1ae8d}}, + {{0x00092f193bc042b7,0x00044237c45822e1,0x0002c4168f085b53,0x00071d30d192bd83,0x0000a76e9e42df62}, {0x00082fab88911b55,0x000464db0eb552a8,0x000a7c3ffc85345e,0x00046953be02a681,0x00001889c8d40ec0}}, + {{0x0001369a5e829e5c,0x000b5607aa419d03,0x0001d84c1cbb4c6f,0x0000edb5ac59a624,0x0000043f2c04829e}, {0x0008f758ea5e1853,0x0009a87cbd9f82a3,0x0008fc6018bda40b,0x0000b36e65e75e2d,0x0000d515f74d3569}}, + {{0x000cf4fda79e5acb,0x0009d630215f534a,0x00085756e68b83b3,0x000cb1ac748b2ed0,0x0000031725995d37}, {0x000841ac5ccc2c46,0x000add9d50696735,0x0001754bd7d7dc96,0x000dd54147e410fd,0x00005296e953399d}}, + {{0x000b2d0bc8fa5bc5,0x0007000c277bf6b5,0x000a08a5d8a5ead6,0x000046d14625e6df,0x00001fdfedce59cf}, {0x000430b289fca32e,0x000ebd9bdc3f6bc9,0x000ea0edee36ff0c,0x000b3e4fe187cb58,0x0000d66af213a900}}, + {{0x000968b5fa9f4d67,0x000dc7a362e700e0,0x00007e7722d4066c,0x0001d0399a9748bd,0x000010989c076a4f}, {0x000df35ce40cbd89,0x000f8743293dd5de,0x000a24e2cab55c5e,0x000cb3e66f11448a,0x00004d874f8f05fb}}, + {{0x000f0e8a518001b4,0x00065d04ef0fa365,0x0008d4d25ee605eb,0x0004721a3915cdba,0x00004c0e1b8f5113}, {0x00024e88b6740dc8,0x00036e1d4f0ccbb0,0x000c4e37289087a5,0x000af2288fa05c1f,0x0000bf395cc2f8b3}}, + {{0x000c9a1deb8568b6,0x000020fb3d321e71,0x000f8fb81a35daea,0x00096a88b6f2662c,0x0000d51afe8f4906}, {0x000ac6e51803a198,0x000f0621908081be,0x0006f463ce3d24b7,0x000ee7f27cfd9ddf,0x0000c6865caf2284}}, + {{0x0008b7db743f4ef2,0x000bc7d11dce32c8,0x000f2ebe83793909,0x000796b398f9222f,0x0000c70ca4505e49}, {0x0009929cb1131b10,0x000825888e79df4d,0x000d8740a7826f29,0x000a8b4d3a112cf1,0x00000384cb6270af}}, + {{0x000125b3ab480953,0x000632d05106cb64,0x0009558453451c25,0x000433a73d577da4,0x00009570c16ef9f4}, {0x000aad3adecf263d,0x00010c76e102d7df,0x000c6a836f1c3d8d,0x00047a8e774a5854,0x0000ad4b6730e92d}}, + {{0x000990ff0d796a03,0x0008af0e8b02be7e,0x0000c00ad5fc6247,0x000a0f5aae8bf403,0x0000d2db93bc004b}, {0x0008a79d85d5ddc0,0x00076bb07f34e48c,0x0009eaed5e907caa,0x00072458db343aa3,0x0000ea6e007adaf5}}, + {{0x000f169d23233f3a,0x0005d7cb637fe00d,0x000a0cf6c3e32279,0x000bdc7f897c0e1d,0x0000651f5d8d1d6b}, {0x000af191a230c767,0x00025daa5e4add61,0x000abcd7ebd52727,0x0008dc5a753636d0,0x00008bdd37ca70bd}}, + {{0x00016c217cd93fe1,0x000dcadce6e2c239,0x0004e42f865b97a4,0x00080ad04ed4eb17,0x0000491ccaacb214}, {0x0008280231963324,0x0007187b479a145a,0x000dcd0ed3c3862d,0x000f1f5f4a88a301,0x0000da2b7ef7ea12}}, + {{0x000ae33b126e48e4,0x0002b494e237f8e7,0x0005acadb404a0b3,0x000fd95beac474c5,0x0000ee5cf3c0bec9}, {0x00033b97df3c8c32,0x0003976808fd336b,0x00045c16abd905fe,0x000b626f436981aa,0x000055c5bfa5dd27}}, + {{0x0005cbfc3dd9b4d7,0x000f8c068a877196,0x0005b029bce23edb,0x0009bd478d472574,0x000046107143efdd}, {0x000f75f1266bf52e,0x000138e49bb67116,0x0006f19e30204672,0x000b2eff43df9f3d,0x0000f1bc7d1c685c}}, + {{0x00027c17078c4322,0x000c977fedb7cddb,0x000290570e1961b9,0x000885fedc2f5cc2,0x0000c3fefca39cbd}, {0x0000a36c2af389a8,0x000d3da71ceacf88,0x000aa846396c610f,0x00090a703977a932,0x0000eb776400586d}}, + {{0x00024542a296e775,0x0002f2837a353f34,0x00009c731c871868,0x0006db2dc710906a,0x00004778ffba1b81}, {0x000bfecaf06defd3,0x000f5592b70b6b33,0x000da6114fe3c105,0x000ad7c937fda461,0x0000c13e6517c266}}, + {{0x000a829855938e83,0x000e6de54b72e363,0x000ccfab92eeb5d9,0x000a258eb93b0e20,0x0000dffbb5f55e61}, {0x0005e431acc093d5,0x000ce964ce617f65,0x000e9b4600cb6cc3,0x00072d1ab283a1e5,0x00005d787c5f1c7e}}, + {{0x000fd47deadbf02f,0x0008bc4590684d2e,0x000f311f011e8021,0x000f52910c762671,0x0000a17ef8e3ab6e}, {0x000fd2593e43bff7,0x000e9be40632af47,0x000e61da35cb5ff3,0x000d0ee46871068e,0x0000764196f208af}}, + {{0x000b3edf0290a8fd,0x0005fb47c387831a,0x0004efb4fcae8196,0x00010ddad7dece18,0x0000cfc53b417491}, {0x000f23c4cb632f9e,0x0005d91f80676698,0x00084180ac42a1ad,0x00026ed116a81d62,0x0000bedf5f9c9013}}, + {{0x0004c9f97e3e0442,0x000ff1d09fc9f227,0x0008e6e234201851,0x00083c36a65f17d1,0x0000ea61e2a552b6}, {0x00091bc575eaa945,0x000168ff522d27d2,0x000f04d6f9e7bc72,0x0007480f7268bfa7,0x0000868c73ffba41}}, + {{0x000c2db7be0eead0,0x0002ff7191359f85,0x000ea90d7511e784,0x0006315a06b1e9c5,0x0000c19e28326fab}, {0x000f0cfe9206c550,0x00043553c06a8af8,0x0005f800489389cb,0x00091d39dbed97f6,0x0000621b037c5089}}, + {{0x000e63596e78cc4c,0x00014c06b4a81c52,0x000e87d035385c8b,0x000fad184ddfdbb0,0x000049dfb67534ba}, {0x000e17059f707727,0x0003ca1db56b7071,0x0008af1903a073a8,0x0000ef934949033b,0x0000d882de443292}}, + {{0x0003f0ab2cf89408,0x0007ef948f519163,0x0002653c872b0b17,0x000a04ad28dc3078,0x0000882984a5b903}, {0x0005d0c6a19d2bbd,0x000bb6f782cbb809,0x0009070644b9e7f0,0x00043baaf739882d,0x000012be0ff5b326}}, + {{0x000d23d0e165dc33,0x00021e2378ce358e,0x000b8a0873d47ce6,0x0000b94e2bb0b9fe,0x0000246e8af129e1}, {0x0004ec703ce2b4df,0x000acbc077cf459f,0x0009940c1e9b4ca1,0x000eb03613b4f20e,0x0000c598bb9f47d1}}, + {{0x000c62b45036099d,0x0001467c65d89744,0x000be1943a9dee74,0x0006233c511525da,0x0000a11055563c6c}, {0x000a52c651a3be27,0x000d184449a6ae00,0x00033bed1cda5111,0x0006b3963c06f4ff,0x00003baaf9a7d3d7}}, + {{0x0000c9d7fc63668b,0x000c5c039cde52fb,0x000b223516886c9d,0x000c12b02bd59955,0x000000cab02e60c7}, {0x00016bc81b69442a,0x0000155c3cee8cb6,0x0009ba2784148670,0x00070fd1093281f4,0x0000d956d9d04a50}}, + {{0x000f28b638a7e819,0x000ec980ddc39561,0x0006f247a54155cd,0x00010022db4a96d2,0x0000d774e4ed787d}, {0x0006e2e078637d27,0x000cee0ae06a1a9e,0x000cfa3541c363e2,0x00098d0493483ee9,0x00006843cb3ef74b}}, + {{0x0006591d4b66947f,0x000714460a8cbaca,0x000768f55b452ce9,0x0002de7830d24643,0x00004197ed96dff1}, {0x000b472400dd0f70,0x000f4b1e70936521,0x0000338ae59f5ca8,0x0003c66feff11b08,0x0000ada31f6a29ca}}, + {{0x0004eb694a2c2152,0x000ae5a57ab42479,0x0006f89fed83a43a,0x0007c2064a543a2a,0x0000c2a3868fd5ec}, {0x00039408439d9b28,0x00018acd1f11d337,0x000e6cc19715ea67,0x00085bc2c1d235e7,0x00001ce6e9739905}}, + {{0x000dfe0d809c7bd0,0x000c8f1050ab04e5,0x000a4176fd7b2580,0x00097c6d91ad78d8,0x0000af556ee4e2e8}, {0x0008b73921de0acb,0x0001cea78400162a,0x000ce217452ac9c2,0x000f793e2a4eeaef,0x0000e61844f1d637}}, + {{0x000f1bc789a283b1,0x000d780836f40491,0x000e5402d72d3ac3,0x00073d9a1c5ea388,0x0000b192421e5cc4}, {0x00099989dc84cacd,0x000ccc6e75b85c0b,0x000191ce2b0a8482,0x00092f939961d03a,0x0000a3bc8663d837}}, + {{0x0000653056e6f8fb,0x0000b4d133a7ca99,0x0006abe4084861c4,0x000302db40327674,0x00007b4d51b9bf8e}, {0x0003211220a255d5,0x000bb2419e6e05b4,0x0000c2feac997152,0x000ade26ff47b663,0x00000518677781fd}}, + {{0x000b8bacf902b0bb,0x000487db303b3283,0x0005011bc8d4b4eb,0x00019b1c89f42d75,0x000043d74bc8d09d}, {0x0006bc98adba3503,0x000c851c19276574,0x000ad72ec364eaf8,0x000c1fe3c7659610,0x0000004512228d40}}, + {{0x00099b7ea7b979b7,0x000476fb3bcd6d2d,0x000cffbfecd78cd7,0x0004f5a1e45a9e86,0x00008a61cf4d3702}, {0x000c8723d502295f,0x0003558cb288d06b,0x0002f8586f137685,0x00009dc9db26a134,0x000033effd03beee}}, + {{0x000c4cdb30cfb3a6,0x00010c9db4c8d7e0,0x000c8d9df6d09b8c,0x00066ce0ba1a4207,0x0000fd495f77c52c}, {0x000169f275264daf,0x0005f57d8362fb0e,0x000ad722280c2b74,0x000c7afdd987f749,0x0000dc229b03398e}}, +}, +{/* digit=25 [{1,2,3,..,}]*([2^175]*G) */ + {{0x000ed8452666a58c,0x000026a9c3c2b0d1,0x0009064084bcb6e0,0x0003ff7c57411c26,0x0000fc20755d3556}, {0x0001c505294dba30,0x00068b7dd31ea08b,0x0001eca74a30ba28,0x0002b9d70ba90e99,0x000094e142ce762c}}, + {{0x000783e979f39254,0x000a6f4c89a7b81d,0x0001bf7fa1efd130,0x000a9e125c2144fd,0x0000b2969045b265}, {0x0009634b9db65b69,0x000173599d8aed8e,0x0003563f335c82e3,0x0008ab4aa7a54f40,0x0000df088ad922c3}}, + {{0x000b066bb3fd30a1,0x000adff0354ee5cf,0x00024e36c429169d,0x000e1d709cf85235,0x000036f4fb31155b}, {0x000af011fbba712e,0x0003706ba1a14826,0x000aea73e6ef0f0b,0x00044df9928b3177,0x00002bf6af33eaa2}}, + {{0x0004f124237b64b8,0x000963ecfd078d08,0x000845dd8688ebe9,0x000324d7b8a70cf6,0x000008fc59cdda4a}, {0x0002b2ba3585862b,0x00053df29386a903,0x0001ec29bb66825d,0x000dc805a5a8db43,0x0000b143a98ea1e8}}, + {{0x00094ce12ae381b9,0x000bf6ccda9035ee,0x00006eaca3a7f176,0x0004df363a657e46,0x0000ae5a380d3cd0}, {0x0008d15ed251b464,0x00008aca5e649bec,0x000f20f071f5d6d3,0x000285f47b3b359f,0x0000d65f03537e4b}}, + {{0x000ba24f111661eb,0x00040105eb049e93,0x00024b578edced48,0x000068e6dc9ba1f4,0x0000f8f66b8983e9}, {0x0004df4d7ed8216f,0x00069e2cbecf872d,0x000e73754bf07f37,0x0007075281d89998,0x0000ec85fbc7aab8}}, + {{0x0000deea5ba5b0b7,0x000dd2d052999a3c,0x000b02d42e6a116c,0x000cb63e9775fee9,0x00002b0520111545}, {0x0006f7d31a3b4ea6,0x00082bbd9b32bc50,0x000b12a97e589307,0x00067168bc5f37e4,0x0000b000c06aa73b}}, + {{0x000bf22765fa7d04,0x000fdd6a537013b5,0x00080db9859805be,0x000ce327a5e29d42,0x0000f53916fb76b1}, {0x000f61f33ddf6269,0x000e1085d103714f,0x000809ee34206238,0x000b1c8c50d4b7e5,0x000099f450e15f8e}}, + {{0x0006051e4c79e9bf,0x0002d66a9fea658a,0x000be7b231394cb7,0x0008fd37f31ed5c6,0x00004c88f374aa6f}, {0x000721f4aaa499e0,0x0005e3fb2a6b0fb0,0x00092851d68b3a7d,0x000913a788097d3a,0x000060e7f8ae96f4}}, + {{0x000be731a3a93bc2,0x0005821adc1a82ee,0x000030efd42bbf46,0x0007bba10b6fa4ef,0x000047aa4c7a7b09}, {0x000c632f60c77da5,0x000a7223523e8b8d,0x0004579cf6ffbc26,0x0000f654f6ff1134,0x0000825653ce8025}}, + {{0x000097ebc1aa2b92,0x000317a0333ab2dd,0x000a0db380788939,0x000612fcf55e7137,0x0000648487f992c1}, {0x00013363fcef2614,0x000cceabf129dad0,0x000276be26239c81,0x000ad34ee761de9d,0x000006a7a345eda6}}, + {{0x00067ba4a493b31c,0x0001dbf7f0264bf3,0x00095914b54f20a5,0x0006abf696e06297,0x0000ddab96e4bf23}, {0x000c70aed25ea138,0x000b01cbbbe74ff2,0x0008544c5fa1d09e,0x00031708fc8c8746,0x000047a670de96b3}}, + {{0x000421e64bcb626e,0x000746dee0b5f133,0x00010346caea638c,0x000ed2f6e7680bb3,0x000006f4098b5d4c}, {0x00014527512a30b9,0x000d5589a59a0996,0x000d0c180f3d867f,0x0004ab9e73254f52,0x0000063d8a3c33c7}}, + {{0x000c595d314e7bc2,0x000b267899ededa6,0x0001ed5d32ee7464,0x000612fcef423c0a,0x000017e76ea89cc7}, {0x000ce1fe7cda917f,0x000a9a893f1627cc,0x000c74f6b12d8016,0x000e60ccd6de849f,0x0000a5817e3e3144}}, + {{0x00041640821ee4c9,0x00037bc619921f35,0x00072879f1583eab,0x0007b1e490caf61d,0x000098ad9f4876ae}, {0x0001950a41157f70,0x0006e8da3a7e1e18,0x00026b95fa9d7e1e,0x000a10963784eb84,0x0000ee4ed6e542e2}}, + {{0x0004cc5ac751e7b7,0x00028d4211bdb79d,0x000de4fc693f9647,0x0000641c72d3d2c8,0x0000b69cbf64f44f}, {0x0000ca2f4bf94e19,0x0008612894e23da9,0x00017d60b1a5325f,0x000b5c7a437f6c79,0x0000be7048726c9c}}, + {{0x00080bfe1dc5c055,0x000a9ebeeb57b4d8,0x0000fe6a3d738add,0x000f5a1f0119d3df,0x0000c686e55b6eaa}, {0x0000b50dfd0b7ec5,0x000b1a497c219cb1,0x000546c96bdd0264,0x00042aac0935148c,0x00008a947fac9dbf}}, + {{0x0008d4e49ccd6d74,0x000c48bd5580c0b4,0x000d473b2ff8fb02,0x000af3875235e907,0x0000fab1ac5e2188}, {0x000a3bc97576ec06,0x0007ab7e7d2f030f,0x000305600e8c946e,0x0003b3e0a5c9cc70,0x0000d8260aa28b01}}, + {{0x000304f70bba85cb,0x0000f4a0d3110368,0x00015eec1ad090da,0x000a46c170e87024,0x0000fba35ff3461e}, {0x000019ac1e919380,0x00031afc415f6279,0x000ba0e0fa47638f,0x000c4836c65cbbbc,0x00002160efb034e2}}, + {{0x0001073615cd9e45,0x0007a1243c06e6c5,0x0007b3d8c498ec04,0x0005f0ee5a8809b1,0x0000cd99e615cc56}, {0x00012df7851dafeb,0x0009f79061e281e3,0x0000c590ef156f5b,0x000aa0d0d62b7188,0x0000ec9746fba39f}}, + {{0x000a9c1c8ed1f7a4,0x0005681d5ff21d98,0x000a0794a09e43bb,0x00083695f00f680d,0x000012050d9a61aa}, {0x0007c4e90747e405,0x000b662a3686a89f,0x0008e33536dc05eb,0x000bb98f4de84730,0x00003868fbbefb53}}, + {{0x000d2c3cfdcf7dd0,0x0003723fcab42b09,0x000f57ca341a9fce,0x00055573d905f707,0x000080f9fb1ac8e1}, {0x0008e849ba7a5317,0x00067d9a147f7c08,0x00048c33607d3558,0x000e78f02846abaf,0x0000320fd327ccf0}}, + {{0x0000798b18bd1ff8,0x00002fdd2905aa78,0x0004267cd52c2e30,0x000b5f727ea3d643,0x0000b96d16d95605}, {0x00010494b45706bd,0x000da43d25f87bb3,0x000f30076e7f58b8,0x000d5a19b5e45b87,0x000019448d72d053}}, + {{0x0008cb9d3210a041,0x0003cafb52691ecc,0x000c3489f6bc7d46,0x000e1b2e59b10a67,0x0000769788c75641}, {0x000b82dbd6cb838c,0x0005636d5f228a53,0x00008536e7066d6e,0x00080843aa1c6169,0x0000971da0e26ae9}}, + {{0x000a86bc49a2fac6,0x000fd092e77a01b3,0x0006fb5563b8420b,0x000a86a20573007d,0x0000941b2a21ff40}, {0x00063080658ff2ac,0x00027424ab36140b,0x00051e2998780436,0x000e394253bd5157,0x000075bcd77049c3}}, + {{0x00040907f8f875d6,0x000df6c26bbf92eb,0x00010bbe79c9d754,0x0001e9b58cea6181,0x00002a6b802d45f9}, {0x00041aac6e7394b3,0x00037d57ef10a79c,0x000a6f40c445b6a8,0x000364dc5277eb6e,0x000019fe96bb8633}}, + {{0x000c61f385f63cb6,0x0003c2bdd1270b0f,0x000e942c241250c8,0x000d5d07d153f109,0x00000920d092021a}, {0x0005746724d81a52,0x00023bba3299229f,0x000413032b7ffb89,0x00094c318c51a1de,0x0000a9bfe775c2fd}}, + {{0x000e2393191f4fd2,0x0006b3d6ada1cbcd,0x00076960643093e1,0x00025bf84579f358,0x0000c94a8b3f2366}, {0x000b9c05c437d8e4,0x000398d9f3c86922,0x0007090a23d4ae42,0x0005bdb72c31c12e,0x0000ac3f5f4176a5}}, + {{0x00008fc6b6af9917,0x000fab5cebbd3425,0x000440dd70d5270f,0x0002fd484740d0dd,0x000048ef841e8016}, {0x000fe0edfc6fafb1,0x0005e7300f27a8db,0x000ba4ec9eadfdf0,0x000a976d06555ffe,0x00002c56f83ae25f}}, + {{0x0004203d39b8c34b,0x00058125eddb77f8,0x000e39dc5ed8b1be,0x000789abbf2441f6,0x000000f6ee71a5d6}, {0x0006ecf57d0ea992,0x0007f7e06c43ba45,0x0005b4baadcae0f5,0x0009bde1643de40f,0x0000c324341f161b}}, + {{0x0007f55e126d4682,0x000f56748e098017,0x000a9bdc2ed325f1,0x0004684116004acf,0x0000d8607e65a9fb}, {0x0003e276009d660b,0x000ddd10c5a10e57,0x0009009a03a525d2,0x000448226cb45c3b,0x00006b0cdc18e9d7}}, + {{0x0009976e1337c262,0x000db73d68e5949c,0x000b768d96faadeb,0x0000697e158614f1,0x00002dfa557bcc4f}, {0x000da17be93c6d61,0x00019504f5b9ccd6,0x000694da124866c6,0x0008c61121353c8d,0x0000c6ca5801140b}}, + {{0x000ad8ce964021e7,0x0009932b82b3c245,0x000ef9898b83bffb,0x00048a8aa220c647,0x0000e8d3ac7082c9}, {0x0002091bc2d124af,0x000c15b15ff41faa,0x0007c6fb7bd54c3d,0x000f65486bf3abc8,0x0000b2b0564edeb6}}, + {{0x000c5575b45afb42,0x0009cfb8912d4e77,0x000f6e557e9ded64,0x000f005ec9bbf542,0x0000570dfff82671}, {0x000fb7888e084bd4,0x0008b37fe5b42b3b,0x000649aeea024b23,0x0001d804e7dc0495,0x000098ca2559e7ec}}, + {{0x00066eaaaa07e869,0x000b636085863bc7,0x000c259c80db6fac,0x00049f2add2549bd,0x00005af3c6e941c6}, {0x000928c02e30afbc,0x000c408a88b8b36a,0x0001d9e9d9b5356a,0x0008cd8b67a5f1cf,0x00006542e4865d8d}}, + {{0x0001fe87adfb6cc6,0x0003386781417306,0x00080515acc826fd,0x000082a0e758b13c,0x0000afe3247a1485}, {0x00008b9b6ae8a751,0x000d3acf51e10fcb,0x00061b9d6b8cf388,0x000d0c244a556069,0x0000a6778b87a97f}}, + {{0x000fdc1ecc4c7e38,0x000c96db68ccd840,0x000e216aade9fe47,0x0008be695f89dea3,0x00004f1a6a51594a}, {0x0007d725a7b162b9,0x00091dc817a37ddc,0x000b58d46c5cfda1,0x000f18f0a5d35078,0x00003365b1412978}}, + {{0x000d22526a1fc900,0x00024d70705d2e44,0x0000c45f40d6d10d,0x000079d94b6b10d7,0x0000f201022b216c}, {0x00066c5658fde413,0x000d4e27601dcec9,0x000230be7a8d2bc7,0x000fb58fcce3e1ff,0x0000394ff6b3033f}}, + {{0x000c5098132c9af4,0x000af61e7868d890,0x0002d15aaaac4b0e,0x000b7d1194ded3e8,0x0000550bd2e63ae6}, {0x000318eea5399d41,0x000a81638b803fda,0x0004aa12dd989bff,0x0009444ea124d0a1,0x0000fb1b8994667b}}, + {{0x000796944c44d6a8,0x0009d7e8613795ec,0x000adac4491df144,0x000801115fd62073,0x0000f01732dd9a83}, {0x0009d253aa0a6332,0x000ca9d6d59cec57,0x000ef801006de5e7,0x000a02a132f958b1,0x00009476f97065c1}}, + {{0x00077c0d34c35659,0x00018b9f1e9e336a,0x000e08002ef1105b,0x00009dd3e6d08bf9,0x0000aff2f2256138}, {0x0004f853a80e75d8,0x000debbda681b575,0x00097fd7ade71853,0x0007fa06f041df81,0x0000b332e0892781}}, + {{0x0009be8b9c20cda9,0x000545cd0c9805d9,0x000b9418389f7aad,0x0007f1eef936fe5b,0x00002ca0754405cd}, {0x000db1174a1e0359,0x000783eaea929d65,0x000e4fbf202628cc,0x0008b762d9e24249,0x00004fdfd9c7384f}}, + {{0x000605463428c6ba,0x0001f0b409a565f5,0x00045ae112f7205b,0x0003b25778bb78ff,0x000013045bf65ee5}, {0x00014ff03ef77fee,0x000f1fef8befe00a,0x0009ade22689cd59,0x0006a75578f0ed1e,0x000099f3ec14268b}}, + {{0x0007d91ea1b3c3ec,0x0002f8823a4aa205,0x000ca451e2d1a705,0x000b5cebbb336a2c,0x0000d2466e3e218b}, {0x000f42fc8cb762d2,0x000e5690211f3ac1,0x000d074507e312aa,0x00013fcbb9bd7345,0x000007c4b8266c22}}, + {{0x00025c1375913eca,0x0005c790822099d4,0x00067dbf694e45e9,0x000056208f3087cd,0x00005670fbf60887}, {0x000b64a66f5b8fca,0x0009d86fec286717,0x000ff4952d5a56ae,0x00049b08c3f55fc0,0x000077fefaee57ac}}, + {{0x0002d7c98379d445,0x000b009edc8a2988,0x0006fe464d000bdf,0x000de076f95979e6,0x000004a61164a61b}, {0x000b871effea31ae,0x000d10c21a5456b3,0x0004753bf2d3de26,0x000d8541dbff3183,0x000067ecf4a49269}}, + {{0x0006952151fe690f,0x00038f2adb5f7a17,0x000b62a8d0351580,0x0004e5fe794b15d1,0x0000004ceed9ae45}, {0x000ea7cf0386fac2,0x0002b1fca7510897,0x0007a04ec3b62ff1,0x0007ebf54181df1b,0x0000008e04b1b584}}, + {{0x000148e41dbd7725,0x0002d2942654d147,0x000c544f72b419f7,0x000149169f30d3e9,0x00002a2c22418540}, {0x000ee14634dfb02e,0x0000147869f35da9,0x000933acc5f074ff,0x000ed094ee878da3,0x000065106522fe35}}, + {{0x0009482f1012e7a7,0x000038a566aeb3eb,0x000c00d3b51013cc,0x0000e56d5e924347,0x0000fde089e046bb}, {0x00054fec731b4b3b,0x0003e9fda0620307,0x0001a35bc12a136a,0x0004eecc1064b85a,0x0000f1f5763f46c8}}, + {{0x000a56da16d4b346,0x00097ca21c4fed29,0x0008de4867fba9d0,0x0005e106d7ac006d,0x00000061987d3a2a}, {0x0000f869da28ff0c,0x000783c4599c8b40,0x00028cb0d3133f70,0x00061cd911c9b8ee,0x0000d7e28754e0af}}, + {{0x000f0f272ed91fcd,0x0000ccd4a3735a85,0x00025253c85214f3,0x000c75b81fe5be19,0x00008dc98e161e8b}, {0x000affe585cc3a25,0x000d235bf97a7120,0x000b34581724952e,0x00057d0581e7dc3e,0x0000cbff4f3352ee}}, + {{0x0000a0e87d8cc7b9,0x000361d280d08d32,0x000eec7049beaa7f,0x000056ea0b95719b,0x0000126332eeb7f0}, {0x000c1b48ed3bd6db,0x00022945eb2401fb,0x0008ae25535bb2c1,0x000fb2b404694e9a,0x00006092eed3d6ab}}, + {{0x000143fcc058865e,0x00018e2499224d76,0x00050d3537b0a5af,0x000079aaef94406a,0x000011e4bcd44f0e}, {0x000993aa14a90fa5,0x000c6a0c51d44472,0x00032672d7706e20,0x000382a403292f15,0x00002573bfa71829}}, + {{0x000b6a93b5bdb831,0x000094a723186a7b,0x000eb065f08da65c,0x000685b58d22aa63,0x0000717596c2b15d}, {0x000f0d0b266d88b4,0x00071941945a112d,0x000292cacf688ae9,0x00085c087386e37c,0x00002f3b50d97d69}}, + {{0x000f9986a90fc34e,0x000285ca8a8d6da4,0x00051f762c8f257d,0x0003abe2feabca69,0x00001bc81d154c32}, {0x0008f67251a2a12f,0x0006ce8a70dc1bc6,0x000f84d2e10d8658,0x000c91e648af7ff0,0x00000aa9ebd5a43a}}, + {{0x000be04275968936,0x0005e5bf452b69e3,0x000c698c8b6bb02a,0x000793a875c11af4,0x0000652b5c81ece3}, {0x00055fd4f5c04999,0x000825532b387b37,0x000e96ef76ea1655,0x000f4841c69889a2,0x0000c773c3af1ed8}}, + {{0x0003a409b323abc8,0x000170e1d7912b65,0x00087157ae26605e,0x000615c5d410644a,0x0000f9a78b84bbce}, {0x00044aac407eddd6,0x0008435b964fcf1e,0x00008399981ddd1d,0x000801e73e339efd,0x0000c94bddeee796}}, + {{0x0004ada8545d185d,0x0009a38bb8cb5a30,0x00087e10e82ae44e,0x000fe2928a35e3df,0x00003624f3e715b9}, {0x000209b14be42542,0x000c9dbc2ea5cc44,0x000c37bbe7d0efcb,0x00052bff60336204,0x00001f363f576a58}}, + {{0x0003d1ca85015501,0x0001c8ab10bba150,0x00061c51c2251e0e,0x000f68ce129c9669,0x0000f7246a491910}, {0x00044ee5f2591f26,0x000efe6271572eb7,0x000f3bd683c47d33,0x000855ed6d62c922,0x0000120a64c2b8df}}, + {{0x000c6c07b5d07df4,0x00083ef397833a9a,0x0003a9b4fa92b955,0x000f05a128a134ab,0x00001c18807f1252}, {0x000d08980ba9b1c1,0x000eb532a9ddfc7e,0x000246809ac8dc6d,0x00080faf829cef55,0x000001b784f6b4ee}}, + {{0x00045bbb6f116037,0x000dd1d2801ec099,0x0007534a857b09db,0x0006148ba5202fa9,0x0000fd8ae60317b9}, {0x000a66678308435e,0x000bf3868c4da50b,0x000d7aab09572f77,0x0009fe2cef7bfd2d,0x00007958e090c7c7}}, + {{0x0002e42253466896,0x0000507c70048126,0x000950ee3716da29,0x0001b4d5f911eab7,0x0000fd72969861d2}, {0x000980308b640d30,0x000e887f12a15238,0x0002e93115b0026e,0x000ff720e2166074,0x0000ef6d5415ff77}}, + {{0x00027f0f9c41135f,0x000878a649939691,0x00041875cf21d60c,0x000232756e5d0ce5,0x00001e0f84f91d3c}, {0x000a35906002d609,0x000b761915529bcc,0x000181ec3be2da60,0x000f18cda8bbae61,0x0000f04b823f5806}}, + {{0x0004a7dd4b79bb87,0x000ae2c878c8f160,0x00047b8e8aee806f,0x000053c4144f118d,0x00002edf52c049f9}, {0x000a84e2127015a3,0x00006cb7cef3ebfc,0x0006deec89051d0c,0x000d7456e8fe5829,0x00003b2818871010}}, +}, +{/* digit=26 [{1,2,3,..,}]*([2^182]*G) */ + {{0x0009383171b445fe,0x0002a131ad4c0107,0x0003987e89bcf21e,0x000c8eacdfe205c9,0x000063f4153a92e8}, {0x00062a930add43df,0x0002d980f05a7294,0x00006e96862ebb14,0x0006b05f3954e53b,0x0000e1d75ae142cf}}, + {{0x000c6c7af8685c8b,0x000d7f8f01aa5f95,0x00074692ad4c1c8c,0x000068144bbe3225,0x0000800347984a4a}, {0x000c6e52eca3cdb7,0x000b7c04d3997c8f,0x0002bc5cfea1db16,0x0003d2405bc82e8f,0x000063d518064479}}, + {{0x000c1b808bd98d05,0x00041575f2404451,0x00075d270644b1cd,0x0006bd1907eb3373,0x00006c8bebe4a228}, {0x000d2acc4632b46f,0x0009bfd60242c713,0x0005c754617da427,0x0003dd413065b7c9,0x00008239899af17a}}, + {{0x000963f4c8303203,0x0000603203e3f3b7,0x000327afb842c7aa,0x0009b67f22ca0ae7,0x00008e13092c6760}, {0x000fb62757558f1a,0x000157eca8c173b8,0x0003316273cc3e83,0x00023444174474f6,0x000077989cb63c40}}, + {{0x00017a144a081e00,0x000db70e296ae5fd,0x0001f719cd797fb7,0x000c522b472b3048,0x0000e632a98fe6f8}, {0x000d116c5f0c2848,0x000ead987c6289cc,0x0002de6cff51088a,0x0000f8aa2bccda4c,0x000010f9eff7679f}}, + {{0x00094b97ffe4b3ed,0x000115fa5d21b0f3,0x000fbbc750b691d2,0x000affe0bd77479d,0x00002830fdbcaf78}, {0x000249c52434f573,0x000568096dabf78c,0x000f8c0b34b1f754,0x00034c43bf6f948f,0x00004aef03d754e1}}, + {{0x00051f4b7ac7ec57,0x000a750da7d5f8d1,0x0003a0eb8d6ceb95,0x00086331b492b0dc,0x00005157b6a23dd2}, {0x000c74ec5413d62f,0x0006cc5fc4c7e2c4,0x000fa9ddabe329ff,0x000b86935a2aea60,0x0000117f5ae6445c}}, + {{0x00017f4b0166f7a3,0x00079eec74e6ae83,0x000874bfdfbd3e3f,0x0003a3cdb516ace0,0x0000d846019f681f}, {0x000ee5c7c1620b02,0x000d0b63c5010b12,0x00068c51eba68b4d,0x000b5b8c03cd3266,0x0000a6279f76e0bc}}, + {{0x00069b06ae85c104,0x0008ddfdd3a617bd,0x000078bec7294697,0x000a5299a032682c,0x00001c6a658ffd68}, {0x00010240e0239001,0x0001a10d144dcdea,0x0008ab8dcbaeec12,0x000cdd4a600e7405,0x0000333af21cb89c}}, + {{0x000eae03aaba1f19,0x000dab7144cfdf25,0x000ab98bc2cada16,0x00096dd57ee27d71,0x00009088b4d0a6fc}, {0x000c0a03549dbd42,0x000fd158c3ac05d5,0x000edd68542cbdf8,0x0004d01fb6b3b087,0x00002071cf6a6f06}}, + {{0x000721fff2811e50,0x0003fe7fae8cd2d6,0x000f1f7bbdb81b70,0x000b5d3cfb74efd3,0x0000cdbcd7616cde}, {0x000642a566a808ce,0x0003540064d64f39,0x00028fa6f02b7445,0x000bb61abbadca05,0x00004c3074db3fc0}}, + {{0x000b8b0b796d2197,0x000ec4741dd9b32c,0x000edf6f5c3e95f4,0x000b8e1721212568,0x0000a03aee512b9c}, {0x000c376f53a89aa8,0x0001148a28dc0cd3,0x0002ab04f0d8af9b,0x00002d4f86a3f490,0x0000aacb62aff420}}, + {{0x00085ebf62ffd521,0x000e4797bf101069,0x000e30aefe670b54,0x0005e93b405209c5,0x00002c97a205365b}, {0x00046ce1fe32093e,0x00055907a8c91046,0x0006e726b13cb4ff,0x000498ab9f30d1d4,0x00001985e228ba0f}}, + {{0x000dea910a230cd3,0x00039d30f947c573,0x000e2010a24f46a9,0x000e4fc2623fcfab,0x0000f278cb2a3f00}, {0x000c67d50b920eb4,0x000d4e760571ed55,0x00095b709f1cb9a2,0x0003693c50d10908,0x0000207cf07590d4}}, + {{0x0007e81c4127fe1a,0x000c9ae9c5663b02,0x000bfbba5a9f8b9a,0x0006f4bab10851ac,0x0000747d648f6955}, {0x0002b5c2ba97bf75,0x000d6cfa3324cc17,0x00086279d15e0f77,0x0003d35345b79776,0x0000a72348133800}}, + {{0x000139f8f5fcda83,0x00048dee5bfdfd8e,0x0003f9f77f3e558c,0x000969a76cbaf4e3,0x0000a4c97a4a1771}, {0x000e84bf6dce6a73,0x0005e3e6c2d1da27,0x00059a6e9ff373d9,0x00062cc115193cd7,0x0000f9b702593d22}}, + {{0x0004a31317cd0627,0x000da99f8332d976,0x000b11b0b30779d8,0x000ed86807410616,0x0000917ab9fe8aea}, {0x0009cbe28fb1d8e4,0x0002d36eda33b67a,0x00071a86c2e31356,0x0006b6c10b7069a3,0x00004d90fa2a744e}}, + {{0x0000867d6b3e243a,0x000cb9048c486819,0x0007315389fe6cd9,0x00004f1900b02895,0x0000012062fd2cae}, {0x000c8bc9399d0822,0x000a21df12e28107,0x000ef3f7347e8c54,0x000f0af4ba5117b6,0x00002260beaa1362}}, + {{0x000261e1a18cc20d,0x000e5321d63690ea,0x00011b6a02192999,0x0001f51f64d314e3,0x00007401e4d0b54a}, {0x00099836fbca2bae,0x0002afbffc4b1901,0x00086bf4046ad329,0x0009fbc142d3f637,0x0000b5cbc2796703}}, + {{0x000ae6c252bd4796,0x0009b2b5848f9cb0,0x000c9766305e0f88,0x00025c18f6d2b2a5,0x0000f6e149c21622}, {0x000235cde601a897,0x00088373be1fe602,0x000471827d17bbe9,0x0001165af49a5ba8,0x0000e1a0a8588aaa}}, + {{0x0003196270580c34,0x0009b1c98a146c83,0x00034e0a51e23383,0x00028927b2f7b4ae,0x00007ac874618ce7}, {0x000779a100dd467c,0x00068ee50d092b74,0x000608bc9274a433,0x000387a03dcf1383,0x0000d9da6c4889e8}}, + {{0x000199f355116ac9,0x000926d18eed2660,0x0004bc071cc38bb5,0x00057da075f31f2f,0x0000774457fb65dc}, {0x000a9c8c6db88bb2,0x000f2ec98e0406a6,0x000ecaa8b6429d07,0x000a7b6d05e57b05,0x00000f140b19872e}}, + {{0x0000f09ca4946937,0x00008252e909df8c,0x000b14b1248d3a02,0x000d1bdc5c29af57,0x0000e6fa37e2f47a}, {0x000b50649a0c938c,0x0007abe5f41f66e7,0x000359412b72c0d4,0x00047faa6242b8b2,0x0000d35c7754e859}}, + {{0x0006fea87baa6279,0x0001672aa6801253,0x0001e5dc958c1fec,0x0001b8dc29b63760,0x0000e3c3c1d6e9e0}, {0x000127b2bcfe0b0f,0x00013a12f50defc8,0x00079b3973510710,0x000f207ccd6cb148,0x0000792f805e8a82}}, + {{0x0004804a9b46402f,0x000cd10f0850509d,0x0006208aaedddf85,0x0002dba28410dc4b,0x00006229c4729101}, {0x000c41e7727b9b64,0x000b6a444842c5a7,0x000a947ea289e4e4,0x000ebbc49ba1d9e9,0x00004f9e47fc3c8d}}, + {{0x000a1fe611f8b8ef,0x000a0518f427fa77,0x0004ebac3fd2e416,0x00097ad5fffa7011,0x0000e57c4ea4d896}, {0x00053acb1aaf6131,0x000fda585a45fdd0,0x00098503431df210,0x000130218cc10e24,0x0000a38efd16f1d6}}, + {{0x000f2370b1e9e212,0x000cfdbe88aabf86,0x000c1baf9b258514,0x000691fe38a58890,0x0000936a01eddb9b}, {0x000de986dd5b20c8,0x0000f0f98ecfd576,0x0002d2fd7b586bf7,0x000d7b4ccf0f12c4,0x0000717e61d7b35b}}, + {{0x000572235e6fc06c,0x000e4b3e13d58b1e,0x0008a73723477728,0x000289550c294daa,0x00000291d43fbfa5}, {0x000bc67cec5a196b,0x0003ac2e8a7cc6c8,0x0006e1c51deeb31e,0x0001560a93e244fb,0x00009f8b71bde28e}}, + {{0x000a287968a2ab91,0x000936bbcb1fce65,0x000ae3f30e3c5ce6,0x00082be8c835b9e7,0x00006bbee270f72b}, {0x0002017fd42cd227,0x000088b1d2a0665e,0x0002049321e13997,0x000ee4a25cda2979,0x0000aee94a5b9c3b}}, + {{0x000016089821a663,0x00085f98166968c7,0x000cc3645f7c3767,0x000dfca90829fc48,0x000046af04a070ad}, {0x000b232370bf29c0,0x000e42e650ee2057,0x00026ab90f90c73c,0x00087be03386eaa1,0x0000e266e7e975a0}}, + {{0x0008eb90fca65d93,0x0009e6af45b88057,0x000c75a4e7e2989e,0x0006b84438212dca,0x00008c7ca397fef3}, {0x000c494d402676af,0x0006072c7c488650,0x0003a464e26ab5a6,0x0008405e6cb426ce,0x00008f998971b72f}}, + {{0x00084911a335cc88,0x0009ea5913e48c31,0x000b32919563459b,0x0005ac9b920d61c7,0x000005ab8b720242}, {0x00012da8d006086c,0x0009fcf5c0fd2ac5,0x0002138d76ca4846,0x000442efea51d8ac,0x0000b647545f44cd}}, + {{0x000ee8fbd7d90402,0x000e619b9c960429,0x000a7d744ee66a2d,0x0001bb34f9ec25de,0x0000ffea64287172}, {0x000dbd1114344eab,0x00064d0dbc8b4f19,0x000ec7f910430453,0x00014c514b50aa29,0x00005fc22ff6b060}}, + {{0x00063a91ee682e0d,0x00002e85c72760d9,0x000707c2ddf48abc,0x000efe3cadba132e,0x0000e608d3b7645a}, {0x000c28bedafd8830,0x000ebd94de1f05f1,0x000593e413c362ed,0x000eaf8dd0629d13,0x0000a5e736f766d6}}, + {{0x0002311f68cf9d16,0x000761797556bfa9,0x00001c209a4f9ef8,0x000360b0d75a1f56,0x000051c374c69b07}, {0x0000b5888b5cead1,0x00085fa9dbaa4995,0x00015f33a0ef0005,0x000140e51ddc264e,0x0000f8b5ca63ef46}}, + {{0x000c0a3ee9523f07,0x0002275ea978343a,0x0007387f4bb75eab,0x00062dabccf33210,0x000090f925a0ab00}, {0x00063ad1e4f6a5f6,0x000402519a50f1a3,0x00065f1ee06e08b8,0x00085e0091518772,0x0000a80ca34f3ae9}}, + {{0x0009768aaba4864c,0x0001cd52a7d681b2,0x000ad03f1b13cabf,0x0001bff5c363488e,0x0000932ad9641c7c}, {0x000708ecae1e27be,0x00083b0df6485452,0x000cdb8bc9dac426,0x000173433e3f0cdf,0x00006cecce0cc540}}, + {{0x000845e95081181f,0x000f799355d5bd0d,0x000b375a8cc8a791,0x0000db211c0f6dc3,0x0000d95bc6ced51e}, {0x0006a266888523a0,0x0006cb01a06d4a10,0x000b9b3974d142bd,0x00091479bfd289ad,0x0000bdbfb94e9863}}, + {{0x000a2291660f6a6a,0x0005b51c042d29d8,0x000c3ffe87f6abcd,0x0003fa73039deb0a,0x000001be6298c852}, {0x00041030ca1c3287,0x000d4903928e6ea3,0x0009144b0c74114b,0x000b171aa4ff4e9e,0x0000064091fef9a4}}, + {{0x000f521e447f2c48,0x0009e04291f0a3f4,0x0005926de81b8da7,0x00002f5680bc467d,0x00004f21fd5b4a12}, {0x00031814e9df3d85,0x0009e9ab8d341d1e,0x00019aa4a1ca4861,0x000366309ddeec5b,0x00009f72f7e9d329}}, + {{0x0003f41386d5087c,0x000c1d67d64fa2f9,0x00070215840bf739,0x000177f449420566,0x000033c65bf33b1e}, {0x000657c38ca61533,0x000aac791976cdcd,0x0006e1f3997f4519,0x0009329c7c7f29cd,0x00008de9cfbae3c3}}, + {{0x000eba37b793f853,0x0009c067e914e448,0x00014ae87e9f8dbf,0x000e2a90390266f1,0x00009ed75a7fd6a8}, {0x00048487ffba390a,0x000acaf9bc09adb1,0x0007476db67f8cb8,0x0008d5922c38489c,0x0000320fecff2a53}}, + {{0x0003002b2aced2bb,0x0008b16bd430e049,0x00031be70dfba180,0x00044fa31c4644c3,0x0000c04d32f40d2e}, {0x000a0d10f9f142d6,0x0004e7ee5a231805,0x00089b4e32c44a0c,0x000480d1875a4339,0x0000b1949fd6c063}}, + {{0x0009e08be0f44920,0x0003e9d5e5172dfb,0x0009466a83ff0da0,0x00093203dbe9a1f7,0x0000b87bcd015ea9}, {0x000fc83ab1f58ab6,0x000a217edc8aeb64,0x0003b67e56d9598d,0x000853099cff661d,0x000045c0f29f2635}}, + {{0x000dd82eabaf21cb,0x00097241659e253c,0x0009f709182b9602,0x000d9a7cae07ec2d,0x0000e4c720d3b48c}, {0x000bc036f08d6c97,0x00073f10bf406ce5,0x00010ff1236e8a99,0x00049413422d213e,0x0000b26d3ec2cc12}}, + {{0x000d2d0c9469ad61,0x000d20afa05bb240,0x0006ba286c4a11b4,0x00064c3b604acedd,0x000084866004ee28}, {0x000d6ba8d9ce5be6,0x00059f4bfb0d5869,0x00000cf730d8f68c,0x000135569f210b57,0x00001f6653acd37c}}, + {{0x000432b5aff5a48b,0x0008c2ba3a69ff3d,0x0001899ef0d81c4b,0x000afd3e879ae9fa,0x0000ac7e2a0dd6ac}, {0x0003f6c1c664399f,0x00006bcb135dd6d9,0x000ab7cbf4c288de,0x0005ef93031dab9d,0x0000e23feb12abbf}}, + {{0x0002466cdedca850,0x00001a09538c9f1b,0x00011115d140bb71,0x00059eac8ae8515e,0x0000d63ff676f03f}, {0x00055517d234afbb,0x000dce208fc1755e,0x0008a4b5d61c2db4,0x00030efa9859cef2,0x0000dd6d4fce4af0}}, + {{0x000a26d3be01cb1e,0x000b443aa07cd1c4,0x0005035029ba14ff,0x0003ab195cd3a9b2,0x0000379bc075d2a9}, {0x00018e9d4ca8d68a,0x000be0bb412a3efc,0x00045a968083558e,0x00054f3903b94096,0x0000499f0b73ba60}}, + {{0x000573cb8349abe3,0x000500b4fc1c208b,0x0005249903baab3e,0x000e8057e978bacb,0x0000524194efcdf0}, {0x00017257d4bcc42b,0x000b090109ba6271,0x00023e1e0e90a3d9,0x0005988b1bdd5713,0x000078e9bd60eae1}}, + {{0x000b7469e03d2781,0x0005c70e62970794,0x000c978558017860,0x000b5c071792f899,0x00001b393ef05a86}, {0x0006582d8884f278,0x000a3f19ba5f48ef,0x0002062c6bd44737,0x000c540698de4ca4,0x0000975eb80e1ce9}}, + {{0x00057c7d7fe71f3b,0x00000c97ce38d50e,0x000f07b631534219,0x00087ca1bda2de4d,0x0000a12aeaed00eb}, {0x00035d2a9b4f8f67,0x00058ad6d99cabe1,0x00094937c04619d6,0x000099da6683a779,0x0000a778c8bdf94f}}, + {{0x000862320a71b899,0x000c8c2291658c50,0x000f83a99241a2ae,0x000ac7a52be595aa,0x0000fbfee7fa562b}, {0x00058b95c4017e32,0x000ff5120b86eaf6,0x000034d6f1dc7f9d,0x000038b84f13dd4c,0x000083dd7380aea3}}, + {{0x0002609cd85d6a2d,0x00052ae60177197f,0x00012fede6ebbc34,0x00086ae80f031b4e,0x0000e55d0c2d7a21}, {0x000e37f24dcdd5a7,0x00050ed191fb1fb3,0x000023e0d8d602da,0x0000bfa08fb05676,0x00000178c71b59c2}}, + {{0x000a3863fe54cf05,0x000eb2bbb475fad5,0x0009d94d7a4a3ec4,0x000ab2caa5ec2091,0x0000d3b63b5f81e4}, {0x00033d85ad3d2aff,0x000ce1ac7a377fa7,0x000779614fbc586d,0x000429382925de40,0x0000e0ffffcd74a2}}, + {{0x000e67f906151e50,0x000f55e106493f39,0x0007cf7b7cea27f5,0x00062ddca1d4e1c1,0x0000c326d122fe23}, {0x000ac337dd35df39,0x00093396dbdf05f7,0x000b7db1c0c3b763,0x0004a87912f5ac03,0x0000dea4b70ec9ed}}, + {{0x0006e53aae3f639a,0x000c5c278bac475e,0x00090375ffaba0e7,0x000d0976f9e22194,0x0000ebf974745a7e}, {0x000af3ff41ad5d66,0x000c52e9922445f9,0x000cf56aa03c4623,0x000ed322c5bb5cb3,0x0000431181994567}}, + {{0x000f2118be489ac8,0x000d39a1104bec57,0x00064e0072821895,0x0000fde10dc87560,0x0000e526f3fdb20d}, {0x000ca775b645aee2,0x000f600e10ff6e71,0x0009cf6de3d1dcb9,0x00035316b5116218,0x0000c5a3e308bb17}}, + {{0x000cd3e2a6c6fbf0,0x000a4bf97906c186,0x0009d6901a74516f,0x0007435b4b8f4b27,0x0000c4e57b42b573}, {0x000b229b6e386b6e,0x000cb9deac2775fd,0x000712629b46793f,0x0002dd0eec47eacf,0x0000965f3c5abc3b}}, + {{0x000fb83425c65590,0x00060af06fda8dd1,0x000d956df7fc00ee,0x0008a2e98c922533,0x0000f1ef3354fbdc}, {0x0005145b79b8ea2c,0x0004fdbff2882abb,0x000185db740fd294,0x000099aa814ac4d7,0x00004329d7080846}}, + {{0x0007b52ed1be45d6,0x000d84cd2c74c9ba,0x0004139b1891dd20,0x00070ffa4d4a7f82,0x00006c177171873c}, {0x000c1412843c4e0c,0x0006f97eb5bf5e5b,0x0000c95c7d5ac481,0x0006c500f8af5445,0x000091b3fa0f1840}}, + {{0x000340aab9d97f89,0x000700a2d611360c,0x000a6f7e5fb57bd0,0x000a0fb339ae3ca6,0x0000c1fcd2abfeb8}, {0x000cca9c7ea74322,0x000c108076f6972b,0x0005b4ca51b0b924,0x000b2960b2814a2a,0x0000f78f55b81ef3}}, + {{0x000744ac18a414fe,0x000db03d0a86f838,0x000453f55c611eaa,0x000278b4dabc162a,0x00006f2e3daf4efb}, {0x00060179320dc3cc,0x000ecdf6b5a45b7a,0x00040fa90692e382,0x0003177f5e15e02d,0x000087883af243dd}}, + {{0x00053e453544774f,0x000b4adba2bc5110,0x000e371f5834d0ec,0x0003bb5215d7f7ba,0x0000cfd57c05c866}, {0x000383dd6901b1d3,0x000485587dc3ded2,0x000625f623b49fbb,0x000762cd44a08d07,0x0000ee4d65bcde9b}}, +}, +{/* digit=27 [{1,2,3,..,}]*([2^189]*G) */ + {{0x000137d0d63d1fae,0x000122a9d89f64e5,0x000436309658fc05,0x000a606889487450,0x00009ae30f9b598d}, {0x00010d1818baf918,0x00060b6a0c202ed7,0x0001a6b44e27e9e0,0x0007db9e28dcfb1c,0x000083acb6556ac5}}, + {{0x000728dc2c6ff707,0x000f55dc22358735,0x000e277f979d6122,0x000cc6b3f5d00319,0x0000ee84e264ded8}, {0x000afb063cd880a6,0x0005d574af6091a8,0x000de7f423f3ea7c,0x000151acfcdc8402,0x00002d07930131aa}}, + {{0x0004e438a5807cef,0x0002f4109a7e8e1b,0x000d59ddaad28389,0x000092d30cc9cbaf,0x000065f36c72d8d8}, {0x000469ea60d32b2d,0x000a6e8191c8df31,0x0005bdeb5ee93df4,0x000a27cc1017c535,0x000026231865616a}}, + {{0x00083f9dec31a21e,0x00028ad9d573b02c,0x0007be365988c8b2,0x00034d73e983aea5,0x0000968734e446f8}, {0x000ea8f5da6309bd,0x0003f1f1ce169137,0x00044092110f3a62,0x0001b4a82a9ea2ca,0x0000f94739f2b46f}}, + {{0x000e006cce85c9b6,0x000644c7c2d39f9b,0x000fa1e60360e70d,0x000b6cccd5beeaae,0x00004cf63c0ec3d2}, {0x0007fa3e1cf6f904,0x000695e044e6fb10,0x00034db9fb7e937c,0x000bd034e8ca78ce,0x0000f8b36c17e210}}, + {{0x00065a434a35ea84,0x00070d4412f61df1,0x0008836c33418e0f,0x0009651af1f8af51,0x00002ceef4d530e1}, {0x000ca0b543a1957f,0x0004986cb1235560,0x00098ed30c33761e,0x00097c76624b1ffe,0x0000772f4c000909}}, + {{0x00040bb4885d4104,0x00005ba5f8d7f4e5,0x00098dfb17287f81,0x0008a2e2d0d865de,0x00009ff51a1fcfbb}, {0x000fa536bc3012e7,0x0001a70d541db6b6,0x0000f49663d31fd7,0x000e071018724f4b,0x00009e7399ff7dbd}}, + {{0x000410ef4f8b16a8,0x000e447b266a56f8,0x0009c87c197241af,0x000b1a8a406b8e6d,0x000003f3e034d42a}, {0x00009a804dbec69c,0x00067bbad05f7f03,0x0008e197fa83b85f,0x000dc106097273ad,0x0000097440f1067a}}, + {{0x000afb63524ff164,0x000e423fc6ce730e,0x0003e4ac0d7f9b51,0x000216e7bd0d3244,0x00000c59ad98d66f}, {0x000136f17c387a48,0x00056b86804d6c33,0x0005a73c95043b8d,0x0009b5f497031267,0x000038fdb3271666}}, + {{0x000b6dd418e7ddd1,0x0003372f19d6c507,0x00027eb4d39888d9,0x0008846eae26be0c,0x00007b53ed40babb}, {0x000021b2b01ae4fe,0x0006ef488682fc27,0x0005e2d8788462e8,0x00029adee096ec21,0x0000b2fea9bb242e}}, + {{0x0005b5fb821fc28e,0x0006fc1e2ad25d98,0x00030ba6289d2e19,0x0001c575b566b890,0x00003fd41b62f41b}, {0x000ac2eb9a96d612,0x000a169443f4b738,0x00003a4407f8567c,0x0004dc6698622df8,0x0000b586236afe2f}}, + {{0x00000c756b95bce4,0x0006216da680bbcc,0x0002142525ec0390,0x0002d239162ee672,0x00003132b63c6a89}, {0x0003ff22f3263bf6,0x000c3cd0a1424bdd,0x000415ccbd5b3733,0x0004e9f92eaa8244,0x000063e8924ed547}}, + {{0x000a25e5236344e0,0x000dbda76ee68058,0x000cc3d2282e8df9,0x000529dcf6efd811,0x00000089cda3b4ab}, {0x000a071bd38a3db5,0x00009f72b92591d3,0x0003edf754ea97fc,0x000ed2bc9fc15bea,0x0000a6297cdf4348}}, + {{0x000ab35ce7c42d4d,0x000eb2feab100d38,0x000111b459fd493e,0x0005c276056b6d82,0x0000a11dae243efc}, {0x00002785545a7fb2,0x000c20d507e6dc74,0x00066fa58bdb2601,0x000c29f21dfeeb70,0x000014369a859ae8}}, + {{0x00009cb06e0956ce,0x000e210cd34b1957,0x00071a5324c9d254,0x00054d151e13f704,0x000019d6791fe730}, {0x000a628db5c7be33,0x0008824dde05f702,0x0009b2e2ec714121,0x000dbaac18233cf2,0x0000a6bd1e8b5342}}, + {{0x0007fa0b311898c7,0x00045d0eac653f74,0x00014d0bce2a272e,0x000ee2dbba5851f9,0x0000a1a966134a43}, {0x00067cea1c8cde9a,0x0008d271abe3e5a3,0x0001615cd9d958ba,0x0000b053ff7eb63d,0x00002280dcf95ae2}}, + {{0x000a5c1cf6401471,0x000d4e83d11856db,0x00024c511ea5a2e3,0x000213f4cd6b6dda,0x0000c0f4671f854d}, {0x000b7a9695653812,0x0000becf1f5b91a6,0x000f5d009dc96624,0x000bd4fb22d21cfc,0x0000a05f641b021d}}, + {{0x000d566d4312483b,0x000cb43e216f8c0e,0x0000444935179a95,0x000a211c185fec17,0x0000306333a04991}, {0x000ecdb0081a726e,0x00056fa89bbbd801,0x00091b6b90149b0c,0x0003a2cfe9065a43,0x0000dc92787b633f}}, + {{0x000c24aae6a8e13d,0x000dcf3897abe408,0x0001a071585833fd,0x000c5e73800e7ed8,0x0000e08e347844ff}, {0x000184ccdeff2e08,0x000a965eaed17094,0x0007c468a49f9387,0x000dd7e35d612977,0x0000c0dcfd1d38c2}}, + {{0x000d9e37a6a308bd,0x000f7c2767d3d6d9,0x0008cbeb66237582,0x000d9db74a8bc6f3,0x000094d3f1b9cb6f}, {0x000735bba21f248e,0x00048cd1efb092a9,0x000b03284272ad0e,0x0002249437b69c05,0x00007f047034948c}}, + {{0x000c04acba2ececf,0x000ff3a73e418a56,0x000e937250c18126,0x0001a87cb34e9d03,0x000077c871439652}, {0x0009183fa7f9f909,0x000bfc9707ad9456,0x000c1c9a3f2e7aa4,0x0005073ed2c9ba26,0x0000109fe96d0197}}, + {{0x00068a9e9adfe1c3,0x000d014e39bb9ae8,0x000fe378f3984403,0x00062885875720f2,0x00003f901e0ea44a}, {0x00025fe3652438c6,0x00063dd1f20bea11,0x000bf7fbdae9ec4e,0x00079bbe740d9ebe,0x0000dbd3ddca2dbe}}, + {{0x0002aecedd36776e,0x0008098590396208,0x0002f7065f612c47,0x000210c493b20103,0x0000bd4d8f32ff9b}, {0x000a0aaaac4cb325,0x0006c5ed40053f23,0x000a27e63ea3aadb,0x00066c5cf17ea4af,0x00006125c1b111fd}}, + {{0x00044a43794f8dcb,0x0009983c5c362663,0x0009d10a0dcca923,0x000df27d6b6bbf3f,0x0000320c5cb31d9b}, {0x00028ff47b50a951,0x0001bef03371620e,0x000100153933e3b0,0x0008d6e081bf8599,0x000083be9a0d3a8c}}, + {{0x000dc5ad6bbe24db,0x000fa38437954e3d,0x000ec2d4cc6c7462,0x0009b1c8193dd765,0x00008df26cd7d3c8}, {0x000e3995a483f8df,0x00068dd3313a98db,0x0000bd37572d8a95,0x000d1575087294ab,0x0000cd892496c259}}, + {{0x00043d77613aa81f,0x000f95fe65848a94,0x000b10288801007f,0x000ee780fc4dbc7f,0x000058280d4d86be}, {0x000d82f7c978c385,0x0000bde44d7b14fd,0x00060252fdf1204c,0x0006a5508a1c8441,0x000091554cb11764}}, + {{0x00037d6a05bd5254,0x000ac7957b3c214a,0x000109bc948d5f09,0x000ce6c247cdcbd7,0x00000f9e4bb70599}, {0x000fa03f46ad2ec6,0x000f63e3f9eec325,0x0003a457700f766c,0x000b934b556668d4,0x00008d30a619ee03}}, + {{0x00081ea77b46a081,0x0007b74806997ddc,0x00033f683cf5a647,0x000c6033a8cb3466,0x0000b867e6ba2363}, {0x00011141f60558ee,0x00024f41450e4392,0x000630e8bcdbcdd6,0x000b429fc04601cc,0x0000a7c66d677038}}, + {{0x000b8a504e99fd8c,0x00018785549a7259,0x0000552e198a8dd1,0x00009d4e459a7c84,0x0000dfcf4d10bb09}, {0x0006db253758da79,0x00035ac997e134a8,0x0000c5b7ee643bb8,0x000b5206400bd753,0x0000f97af88441c8}}, + {{0x0008820fbeee3f97,0x000fd9091afd34fc,0x00031f35c93e5348,0x000924064b9be59a,0x00001f37864c7e3d}, {0x00034e0943aa75e5,0x00085b8ff6e402fb,0x000cf0d19a18c9c5,0x0008a6b80f31b133,0x0000c9682db58351}}, + {{0x0004ca6b709c3de9,0x0001a575b8f0873d,0x0000154bb64a8426,0x0001aad275da1f02,0x00007678cab617cf}, {0x000795f951a95c33,0x000320fccc088779,0x000d8f031dd35b16,0x00085c0270962733,0x0000c5ab10a798dd}}, + {{0x00085c341dca5663,0x000aa8622aa3b6c1,0x0001b6dfb7de7fed,0x00028869e84d9290,0x00000a02b0eac4ad}, {0x0001daa2fd3cf36d,0x00070f89e59fc7c8,0x000496733d131954,0x00012ae2be8184cd,0x00005f449ec63d34}}, + {{0x0001b1b25fe531df,0x00017a1d56467ea4,0x000de501af979743,0x00089b96067f722b,0x000091481c0fc85e}, {0x000e465f8b05bc60,0x000f02e83cdaca8e,0x000dbe33b1844e1c,0x000de2ca82114ab4,0x0000f9f87694eabf}}, + {{0x000b1c038b27fe29,0x000b1ba402df4936,0x0006bdbab63b6359,0x00039bb0c0ea2f65,0x0000c992a89f580c}, {0x0008f152a60aed16,0x000480bf49df600e,0x00042d99aeb089ca,0x0002fa3c233d7d2d,0x000048d3f95ac6bc}}, + {{0x00083a8e1add3f34,0x000a0f64a348dcc3,0x00030dbdbf42c0c6,0x00015deabd176f00,0x0000de501a3bd6c2}, {0x0007c1f4b9a64bc7,0x0002b496cd594a10,0x00088dffba77f0ad,0x000d8e8b78ac6276,0x0000025a2cad7937}}, + {{0x000b2d1d1a8f4e7a,0x0006d354927cfde8,0x000205735f5b3da4,0x000917448606a3d9,0x0000c477cc78177b}, {0x00073d2a883239a8,0x00064c8b8357fb1f,0x0001f4f86e12572f,0x000c6e1d355e9cfb,0x00009b795f959f3e}}, + {{0x00056f1b54398dc7,0x0006cfedeed527be,0x0006d01401890efd,0x000ee3f2f77f1f9c,0x0000ef0e314c96f0}, {0x0006631cc61dab32,0x000dd4866e4f50ca,0x000363b394a39801,0x0006aa46c8d032ae,0x00002c591e54ead6}}, + {{0x000a308de02a53e8,0x000f5389f357954b,0x000f40b662a6c060,0x000ce166cfcde8fb,0x0000e02fc5746340}, {0x000779573adb4ba8,0x000c27b03805e495,0x0008e6fa67b86122,0x000803e3f835120c,0x00003660ea0857d7}}, + {{0x000910521ba473cd,0x000e0ed5389dbad7,0x0007c9bc0b6c50be,0x0008a71e2caf4daa,0x000097b8de55c4e9}, {0x0003e70ab3bbddbe,0x000e4597815aa9f6,0x00015b3d93898aab,0x0007839659af89ac,0x0000df7725c503ce}}, + {{0x0000fabe085116b3,0x0005572853102547,0x000bfd52f04a4337,0x000c741e39187ee2,0x00006166b44ad9eb}, {0x000433cfd4b322cf,0x0006ca79ab5192ad,0x000db15eb726aa81,0x000e63096eacd8c1,0x0000af71e91f476b}}, + {{0x000a640641fad989,0x000799622559dd69,0x0004199dcb799591,0x000eb373c6daa5de,0x00002cadc983d545}, {0x000238b256534e4c,0x0005c595409a1028,0x0005dc59b73e80ce,0x000e7fa90d4c66d0,0x000095f7b90581de}}, + {{0x0007014d856ac253,0x000d7c524dcaf433,0x0000499f5441bd9d,0x000182340b3d855f,0x00009cf84aa05fda}, {0x000b055b2aa95a02,0x0009eddf186004e7,0x0003f6b4329e33f0,0x000b0ee82e74b542,0x000017edeb92aaa2}}, + {{0x0003f3583cbea55b,0x000d0c185d7058b8,0x0005f6992c485ee4,0x000dd4d33ff03b1e,0x00005b9b9cd7f0c0}, {0x000ee8e4e9e8a506,0x000b0269dafd7caa,0x000e791c6462e907,0x0007900ed5cee9fb,0x00008ca325a4d430}}, + {{0x000bdf213b5ba885,0x0009e5ef0ac42b72,0x000b99b0860294c8,0x0009aa4c3230ed19,0x000060fff17bc258}, {0x0008487d67703743,0x000d6a56f685552b,0x000f175d9a373202,0x000810a3e7f90745,0x0000c2f31600080d}}, + {{0x000e9dd7b9520e80,0x00020af037b51130,0x0009c104cc078f9e,0x000e9238cd2ec71e,0x0000f684368c472f}, {0x000b5ed6247e7ef6,0x0008d96dfe21d3f1,0x0009aa2c2b32d33a,0x000e40e6f59cf44a,0x00009cd51695f0f7}}, + {{0x000da0f4b3234da4,0x000574579ebe3f59,0x0002476c7cf0b023,0x000f082d1cbb256d,0x0000f0837e6ddc30}, {0x00075bb906f6e98b,0x00041761e7d19a40,0x00073af10253bb43,0x00031c2e2e645f6e,0x000089a4060bc5f1}}, + {{0x00040c5b8cc037fb,0x000ac405bb47d128,0x0006348b83d093a5,0x000ca6b202c25320,0x0000f5d57fd755a3}, {0x000c90c8c3bef483,0x00032a0a960a89f6,0x0002b42ab23ac762,0x0001f6afbd3d6b55,0x0000ef2245843206}}, + {{0x0009bdac97e65165,0x00007230f49ed74e,0x00074ea498877936,0x0005a256ec1de31e,0x000081dcee58fb64}, {0x00023918f483f148,0x000c5137d13bbaef,0x000743a426d2dddf,0x000e66d4cde50ed2,0x00009a34fc664d97}}, + {{0x000f5b312e08ce5b,0x0007f7f0b2ca13f1,0x000982805a80540b,0x000a03d54bcf7701,0x00008653ffdd33be}, {0x000878702b0b4c9b,0x000eeacb170a8e7b,0x0000c14e52675261,0x000be9561a9d9093,0x000059b30e18ef0a}}, + {{0x0009ea60200ec7db,0x00085bce132b1dc1,0x0003e27e0b6f4a3f,0x00016f08d5de90f1,0x0000aee5ef0cfade}, {0x0006aaae4c6cf389,0x0006413698156f40,0x000d550c6ab4cfe0,0x000d387dcffe87ef,0x0000d4f59c805ff7}}, + {{0x00053b151deb6adc,0x0003f1877749b025,0x0006006e1812399a,0x000e770e90f71fca,0x000032363a7702b6}, {0x0004fbedc36c64d8,0x000127e1ae610228,0x00009d94a86c81e3,0x000bafa576c7e5b9,0x0000b6f7d03018b2}}, + {{0x000ed0756faa38ab,0x000be305bb54eca3,0x000c73061a3790e6,0x0006142784eeda7b,0x0000d56d36a1dd50}, {0x0005949229a8aa9c,0x00068595ec28d657,0x000ab4fe6dcca8f4,0x000f15c14305c106,0x00008c39768e4f43}}, + {{0x0005f36523f2b367,0x0003220d93bbe2a4,0x000f1632b995c649,0x00095488afdab790,0x00009ebbecd8c295}, {0x0003ddb79592f48f,0x000a6f88e998c7bb,0x00001193e67216a7,0x0003fbe91f098bbc,0x00007d928a6a1db8}}, + {{0x0008417e991f600b,0x000d7981a93455e3,0x000b13bde2a91113,0x000f441bc9d64806,0x0000011b6acb755f}, {0x000b518045ec6135,0x000172f5930a6f4c,0x0002e65de522d2d3,0x00066f0acae1af38,0x0000764306777bc9}}, + {{0x000705d1c7193f0d,0x00066be8858e5e12,0x000c6dfc7f0f32f4,0x00095ca85c3d7d96,0x000075b4a218f317}, {0x000f17b342659d41,0x000434f0378f91ac,0x00052129de596ea3,0x0005853515708fce,0x00007387e1e89f2f}}, + {{0x000d2e949dee1686,0x0002de2af23972cf,0x00094066a1ae0522,0x000412a09e75be1d,0x0000cca31c798abf}, {0x000d61d9bc499082,0x000cd5e2bc1eb50b,0x0006f83ac4a9b4a8,0x000b28cb6cc5f794,0x00007da93fd0bffa}}, + {{0x0004c964821c8c54,0x000d683c15f4ea31,0x000f330048de49de,0x000e103a64cf207a,0x00005f1bfec09627}, {0x000062654b9df609,0x000c195c0b33878b,0x000035d8e5e4fdc3,0x000b8c554a37cac2,0x0000087cdaa10f20}}, + {{0x0001c238319ade44,0x000a9e8cfdf836f6,0x0006f3705766f287,0x0004a20882194834,0x00009a7b85356e4f}, {0x000f8a75cedadfd1,0x00057db2a815b9b3,0x000f68f958f56281,0x00008eb0b7d55401,0x00002971e27788a2}}, + {{0x000b696d0ff34fce,0x00013222718cc9f8,0x00095284d20824de,0x00023f9213cf9f0c,0x00002ad741cbc158}, {0x000a6df54043ccfa,0x000b384412b30ee3,0x000c98af016ff479,0x0002fb56c74ee0df,0x000078a169ff2fcd}}, + {{0x000874699c930e9d,0x000779e117a5d8ae,0x00024759f1d33e85,0x00001ca581fcb466,0x0000e5064502bedc}, {0x0005d00caf3155ed,0x000bec73e75fbeec,0x0000b01db672d66a,0x000b78b6b9d8c627,0x0000249ef8420f55}}, + {{0x000d6d473978fe39,0x0001e54b00a16131,0x000dfcfe9cc4e454,0x000befbe05df0557,0x00004b29cdde1ef6}, {0x0000cff9bc7edf24,0x000d93da65f3e453,0x000eb0b488ac236f,0x000038cfaf7d5fc8,0x0000d2de14ca60eb}}, + {{0x000bba760430e540,0x0006da3289abc006,0x000979c5910a2d0d,0x0009449c037a5dd7,0x00004d1f3d3a116d}, {0x00024738a0983cd2,0x0008a883cabb9ff2,0x000a5899528e25b3,0x000bdfc968dba547,0x0000c80b505974ee}}, + {{0x0003b714a953beb9,0x000e8642e7f6ee76,0x000d5e722502e223,0x000315dfe4b64161,0x0000d37c5b16bef5}, {0x000ed70f8330bc73,0x000645a727890115,0x000ceccc2139850e,0x0007f5f7d7faecff,0x0000016a8607fd9f}}, + {{0x000ec644cd8f64c3,0x000ff79d7b51c492,0x000c7525658a2d78,0x000016dced1fc51f,0x0000e658aedbf433}, {0x000942e05da59eb6,0x0002addc37220b61,0x0002e7f87ba3d60a,0x000b6e1c311cd174,0x0000473ffef56b01}}, +}, +{/* digit=28 [{1,2,3,..,}]*([2^196]*G) */ + {{0x000604f692ac542f,0x0000327b91d38303,0x000aaf9bdf079ffe,0x0004fa29f63e6315,0x000099ee566e1f34}, {0x000661fd62191997,0x0006648ce41c8a1d,0x00074d9048c883bc,0x000b1aa065118f3c,0x000013889ee7faf8}}, + {{0x0003f8f81a1b3bed,0x0004fe2764a0972b,0x000c4f5f74f3ce14,0x00085b12d0f1cc28,0x0000eee0c0e97f39}, {0x000adc0d39e25c35,0x00007467a0807df4,0x000cf5a584061982,0x0005fff40ebc9361,0x000027729a6922ad}}, + {{0x0000937b1b76ba6f,0x00045d2026dcca6c,0x000d9ae0a1a2eab8,0x000025c1715e1519,0x00001ad919aaac4a}, {0x000dfb807ea7b0ef,0x000e4ed9eb8935b3,0x0006d08abedf5496,0x0007309932e5ff2d,0x0000314874f15bd2}}, + {{0x0006a753f73f449b,0x0007dd44fc79efb2,0x000c0dc4d1d1c94f,0x0000cf99f0fbc53b,0x0000747ea0be698a}, {0x000c3fe228d291e6,0x0004e3c129d65218,0x000acc51635b804b,0x0006689ac859b8d1,0x0000c10697df5d6e}}, + {{0x000438f0876fd4e6,0x000723d2f383c38e,0x0000934cb45f0c30,0x0006edc03cc2ecb1,0x0000a8f24398c9d4}, {0x000431b65ccde7b6,0x0007c7e76a6ff16b,0x0003484d741e2cd1,0x00044a59c8cf8f4e,0x00004426efde3152}}, + {{0x0008e44fc94dea3f,0x000eead6a0b01c0a,0x000113cef34c8cdb,0x000ff9a19c384004,0x0000d32fba505490}, {0x00090f6795dcfb75,0x000333588baf58d1,0x0001fc1c0fef01b0,0x000ac94e6d1d63ca,0x00003173f9740a41}}, + {{0x000402aba16f73bc,0x0003ccf9b9fc2b1d,0x0006ef7bf2fb3101,0x0007446d51e60e44,0x0000731021c791e1}, {0x00047244fee99d47,0x00068ac5c1ea9d3b,0x000ea9af74bca48b,0x00083a00f5f514bb,0x000051f55a6074c2}}, + {{0x000251acb452fdbb,0x0004a0f306506e30,0x0003548d931ee696,0x000f5b00b3e50893,0x00008949a50a4b0e}, {0x00083263c88f3bd1,0x0000cb1d9989208b,0x000d4df03ab147c3,0x0000c5dd6515fd44,0x00007a12f75f72eb}}, + {{0x000796d36cf69db9,0x0008c6670c183b59,0x000070d8e1219eee,0x00090c6e3341f77a,0x0000b70130c3327f}, {0x00024620ae18e0e8,0x0002c6c0a63836a3,0x0002eb0d42021a62,0x000292a51b5817c6,0x00007bfbcdfcc762}}, + {{0x000b505cdd61d649,0x000c38c18857f78a,0x0001475158c7a53f,0x0002d51653ce6f16,0x0000c923aa67a7d5}, {0x00009cb5c18871f5,0x000823b3cc74c247,0x000d1d4c47d53bec,0x00058209264afffd,0x0000555917e740da}}, + {{0x000bbda548f5a0e4,0x0009fbbfbbe1cae8,0x00077afc31910eab,0x000b5c6e57968576,0x00009ea61f1b3ff0}, {0x00054784f7c39221,0x000d10c68eef7865,0x000779ab995d337c,0x0009a858f1e1e5df,0x00004b491b0c5cf6}}, + {{0x000bbe028e3fe894,0x000485aac0eb7a6c,0x0007e5140e7e1fee,0x00021f3f47eda569,0x0000f450137f4549}, {0x0005f8495cd81854,0x00018db2e583db62,0x0005e6de474be0ba,0x0007396ee4fd7cdd,0x0000251437e28101}}, + {{0x00072a0ac6203668,0x000c36d59344686d,0x000eb75b94be3fb9,0x00010bee8b44e7a1,0x00004e39da411a5c}, {0x0001490b38f04092,0x00030c2ade8237cc,0x00090a2d80295194,0x0002ba7b68878311,0x00005627d1443118}}, + {{0x00050aa658a6d877,0x00075f9c73256eb5,0x0008748c91405aaa,0x0000e06147142e5c,0x0000f637e4fc3ede}, {0x000277614ffad2c7,0x000d4afb6791f8ca,0x0008f93fce58fb1b,0x000654a7158c23bf,0x0000f15b3737a4a4}}, + {{0x000add2d842ca726,0x0000ded9630539d4,0x00000be14a71e439,0x000cf5fbb09cbe67,0x00008d69d5538bef}, {0x000536737183bcfe,0x000a5370dff7a45f,0x00012525b7152b7b,0x0003ccef887baabf,0x00007ac7bdeb6d1e}}, + {{0x0004f7881fdad909,0x00057d2cf6ab2591,0x000054de5cf638f5,0x000350290bc03fcc,0x000032811a7a8b06}, {0x000b3309bbd11ff0,0x000fb40449742f00,0x00051d26676108a6,0x0000c1801bb9e0a8,0x0000dd099bebf899}}, + {{0x000aaaaabe329866,0x0009f0d59c2758c5,0x0003073050fe9dd2,0x000b7824951ff48d,0x0000c23f829e6529}, {0x00022180b136a798,0x000df7a2099650bb,0x000bb4da67e2174d,0x0008d9ef00a4b9c0,0x00009a25a186fdde}}, + {{0x000a27ec11ee01d3,0x000ab5f10dfbf728,0x000ec893cf900553,0x000d76e89a83c802,0x0000ca5bdc153f66}, {0x000153797eada9f1,0x0003002562309878,0x0003c69b359c50ab,0x000449246042d932,0x0000b715a6d3c460}}, + {{0x000d4766ae06e0be,0x000dbd42e25fa41d,0x000b25a20cdd7888,0x00027d2f395f7456,0x0000adfe0af6700e}, {0x00052a9699500937,0x000ac27f8d40b09d,0x000df886a3525d9c,0x000ec248235a9467,0x00007e4b0dd735fa}}, + {{0x000b20a517d7061b,0x0002bc2df683115e,0x000c6fc6777fe343,0x000e82b870ddc7cd,0x00001610588bb87d}, {0x00084cad9c4ddbe2,0x000c1d754be23435,0x000e6c894b3164f1,0x00004be731ed3ac1,0x00006327dec6f6b9}}, + {{0x000c6de97b5cd328,0x000e35eceecd9d49,0x000ded7fe40835da,0x000804466350edd9,0x0000aeebb5cfa678}, {0x0002fb75b8ee9ecc,0x000cce3ca11851d4,0x000f4400ed7a17bd,0x0006f380d7511a2e,0x000048990ad475a6}}, + {{0x0007d2a2199e347e,0x00054a39e0518de0,0x0006e51dcbee7555,0x0009eb7691878691,0x0000b1913142a2d8}, {0x000610d37d341eda,0x0000b6d51c2b6679,0x000492dba434fbb4,0x000493454b7ee7d7,0x0000a33a79af9021}}, + {{0x0005054e4bd6d3d2,0x00043ab551d049fc,0x00042d3a609540f0,0x00023b6acc908549,0x000031af02f4d283}, {0x0008cac0992c163c,0x0000c88e3bb49345,0x0008c268c1fef8e7,0x000bff67578da5be,0x0000c8be793a805e}}, + {{0x0007baec61c3855c,0x000c98c1fd3b2926,0x0000b93b8ebff429,0x00095262d886c08c,0x0000a5e00b2eddb8}, {0x0000117c3fed8b79,0x0009f19c01f6cf33,0x0000fbd54d49ac6f,0x0002cedddaa6bd3c,0x000017430691049a}}, + {{0x000981eaff2ef812,0x00050818ae80d67f,0x0002aa892c3654d3,0x00032861d050441b,0x0000db067bf5d099}, {0x0009e86703dcc974,0x0007a133e215e7c7,0x0009a7a5ce66f9b3,0x000b618df119a6e3,0x00007c60de3c76f1}}, + {{0x0005939d860f1b25,0x000ca5ed4d4a6e40,0x000b6bcbd3e9a1db,0x000496ef23619ec9,0x0000ee790cfc34e4}, {0x00034b15bdaf9bbe,0x00066ca295f0f0a8,0x0008e378c02cedda,0x000ea36619aa2bcb,0x00005613245ac987}}, + {{0x00022cc76b23a502,0x000cea6c21ce0bc0,0x000cac3f54a2793a,0x000d561832878089,0x00009176f1beba26}, {0x00061874f6f59eb5,0x00093bdc658e0629,0x000e3040286e9bca,0x0009badca9c4d357,0x0000438b216a16a0}}, + {{0x000063c7672765ab,0x00035547b9bf0a6a,0x000b1a63337a3ce6,0x00096092c099c898,0x00005ab800db5ee6}, {0x0003f5911a5acd6a,0x0006a6201063f196,0x00096210abaee615,0x00038b96d9a649a5,0x0000ed04363bba71}}, + {{0x0007d1ca4a82b765,0x000ea3806be9cf81,0x000dc6bb55586960,0x0007eb2ab67c8909,0x00002ace7a0614fe}, {0x0007618cbbc9b701,0x000a504ca5e1cd98,0x000bde1334f06fd5,0x00026480af14ca6d,0x0000afe4322a48a3}}, + {{0x0002ca6c44b2c6c4,0x0008cef87dfea70d,0x000696377ab72679,0x00069ff10f64dc2e,0x00009b42e688c812}, {0x00044c3cea0b1760,0x0007cb2691820ea4,0x000ba9dcb53a8ddf,0x000d33f3e674ebbb,0x0000d2878a8d8669}}, + {{0x00035d5d019b6a39,0x000db06f1e4604b9,0x00057c111bb5cf88,0x000d7811912d165b,0x0000803fc21a9ebf}, {0x0001c9ec07764a90,0x000eb75bd0554f23,0x000e6c9ded93286e,0x000c9083a9457d8e,0x000046959156087e}}, + {{0x000dd8a58d6cd461,0x00057e6634d214c6,0x0001bc3289cb633b,0x0007e5b1305047f8,0x00002ede0e236a17}, {0x000ca62065a6f4f9,0x000cd7be487b332c,0x00047ed1cc3a47ec,0x000b13e41eb1870f,0x00009e66e5977598}}, + {{0x00044ca63d0ff123,0x00048610a05f6f05,0x000ad7b47e5efc78,0x0000c0c72917b17c,0x0000ff6ea2122cac}, {0x000791bf21db8b7e,0x0000f7d93565cc23,0x0004bdaad7dac70b,0x00016c882cda1d69,0x0000b88bb8cf0235}}, + {{0x00034b4dfdbeb1be,0x0001d4ee4deac4c6,0x00052482122f5ca7,0x0008b13045a368e6,0x0000d9e8a3fe52b1}, {0x0002cb1b961f49a5,0x00012b0096709b7f,0x000507a6d7fee2ec,0x000f1ce50d875422,0x000061bd7119db55}}, + {{0x0009ccc320bbcaff,0x000eef1de48c4c18,0x000a8f128568434c,0x00083b7af1b00e0f,0x00000ba9d0379075}, {0x000400432ff9f60d,0x0005f25dcf33735a,0x000c74cef3dd8e4b,0x0008ad22230f1642,0x00008117623d13fa}}, + {{0x0002876f51fe76eb,0x000b61d625893682,0x0002257188a6811c,0x000bcd13fc7e6546,0x00007df2ca0782fd}, {0x0004e52dd7b205bb,0x000797a2e4143b1d,0x000a91148b695947,0x00067455e4d793ef,0x000047ed447ad2e9}}, + {{0x00098b904c9d9bfb,0x00006b7930481a70,0x0001ee461661e288,0x00046f01a16966b0,0x0000c521308d9547}, {0x000a0fc2477de506,0x000c1dbd51efc909,0x000294905d80bb41,0x000f97485be7ec53,0x0000d465b18e3958}}, + {{0x000f330fb6840fd2,0x00041401e6c816f6,0x000b5b4f8faaeb21,0x000c4b8f83d30fcc,0x00002885739466de}, {0x000367c7bc467dfe,0x0002f842d27a51b4,0x000ea14a6926562e,0x000cd8ffcb66140f,0x0000b394dafd2734}}, + {{0x000e5d211c0be981,0x0001714e81653eea,0x0002bce1cb1e6ed1,0x0004da091086bce5,0x00004b74cc6b75a0}, {0x00011868c060985e,0x000d4dbd7f7c63cf,0x0000942ca071047d,0x00061c6e433b8bce,0x0000cbac448b8fec}}, + {{0x000d0e2ebf3232f7,0x000e552a2edd8f0e,0x000b55fdbfff80f9,0x000c113d9ab43375,0x00003ca7821542e0}, {0x000e0a0e6251b462,0x000c2c0d932d6dac,0x0005da19a89bc6b5,0x000dfb1438cd7709,0x0000f24a939ad48b}}, + {{0x0007e46766561b79,0x00057ed0322a99b4,0x0008e1865736600e,0x000fff76a47cb163,0x000027c1c2e5b135}, {0x00023370cc5df696,0x0001a9d649a92954,0x000efdb2799b37c0,0x000c2765f0043c6a,0x0000cdd99877be95}}, + {{0x0000931390420d28,0x000b8983efa46985,0x00039aead299c40a,0x000192ba05e778af,0x00004274408c3a45}, {0x0000fb991a711a0c,0x0007df52ab176bcd,0x0003c6ed6461592c,0x000066f49302b4da,0x000051fddc7f30d7}}, + {{0x000beb6da50d5311,0x000d96a7b9da94ba,0x0004bdc89521b840,0x0004494305151e40,0x0000bcde201e0d07}, {0x000a78b3b76a59a8,0x000d87791a1bf427,0x00091ed1cf84841c,0x0009436bd314bebf,0x0000e61d34d3f172}}, + {{0x000c4515541b8923,0x0001cc9d9e541d5d,0x000bf610db186ee4,0x000a9f6d9f345ed5,0x0000e7ba65e26acc}, {0x000787aa83694867,0x00071eb5ba539dda,0x000481bc309f9dab,0x000103eafb2033d6,0x00006f4ce311fa62}}, + {{0x00000cff4f066b52,0x0003261dafc2a8fa,0x00038999889ab514,0x00090324339ed7a3,0x0000ff862f1dc214}, {0x000f985b05556e3e,0x000d5467081e2c88,0x000c637eacd96058,0x000cdb9d6a4176ed,0x00001743d0a16a5a}}, + {{0x00072e27eb37726e,0x000d3481a03766fd,0x000f4aa79f7fa264,0x000e21bfbd3bde45,0x0000d1e0148567c3}, {0x000f97982e7abe2a,0x0001a5f633f87621,0x00037bf3a19eedc7,0x00094e469b155e61,0x00000ad13cee14ee}}, + {{0x000d5241c0e651a2,0x0009e2ce227e93e3,0x000b27ecaab1a6e2,0x000f39c7af17974a,0x000045446dedd444}, {0x0002a2156c07613a,0x000e5427549859e2,0x000fd094643deafc,0x000ede70834ccb67,0x000075841e5e7406}}, + {{0x000a6777b0ac93d1,0x000d68f5e0d7ebd6,0x000f5492ba6e37b0,0x000f3a1516c09676,0x0000e4bf888aac05}, {0x0002ce04df0ba2b4,0x000d1062341bcdb4,0x000acac20935d5cf,0x00000e4a30333382,0x000029438c49198b}}, + {{0x0003bc9049d33fa6,0x000a346f67ff1d08,0x000a1d6a358b82dd,0x000ac84c3e2db867,0x00002e6bead7798a}, {0x000980fde46c58c0,0x000969c8d7befc85,0x0007b35eca7f6937,0x000c0c2355792783,0x00006a933d8e0790}}, + {{0x0000e9b077ff55dc,0x0007fb26e680827c,0x0009cb54f5397779,0x0003ee995308741d,0x0000ca3f44a0aac5}, {0x0005c87a07eda0fc,0x000f3d6400c811dc,0x000e5da72c138bcc,0x00017d949680d313,0x000093eed8305406}}, + {{0x000b1574d0b75c00,0x00026386075bfd3d,0x0007b2c169716eb4,0x0002010639605c81,0x00009915109f1e4f}, {0x000a9285cca6c3bc,0x00097505c90035c9,0x0000480c4b25f7d1,0x00001c2b9f7d2063,0x00003c7b8c6ea1a5}}, + {{0x000183c5a1f8e24e,0x0009bdd255f03f99,0x0007f62a6fdb118f,0x000190d9b18b90c2,0x00008f732f8196ec}, {0x0002d910be786ab0,0x000f0ac5a0f5524a,0x00025f6945d32ade,0x000a899b53d4d697,0x000032a76c60510b}}, + {{0x00091a3ebeb15447,0x000bced73ac38403,0x0006cb8b344b7b88,0x000b12624bae7a25,0x0000ceb151b5394c}, {0x00066d05bc1e6a8e,0x000a290f07bfbd6b,0x000937589ec70cec,0x000cfd470644ed7d,0x0000e9e1a3e3f1dc}}, + {{0x0000a84745b98d25,0x0000d556ed40b0d4,0x000148cb9da429a2,0x000936a676eced85,0x0000a22d40d2ed18}, {0x000b9e570e8a4cea,0x000afeae03793bc4,0x0000bd47ebfd1445,0x000531523f2c0c1a,0x00009c0bb3281845}}, + {{0x0004d600a4c3f6b0,0x00092c15ef449ddc,0x000484accbdfaad7,0x000f15ce55a2367f,0x00008653ca7055b1}, {0x0008724538873a39,0x000d1ce1c7e72efa,0x000e332ba09299e5,0x0001b677afab66ad,0x0000be1fdf722dd7}}, + {{0x0005d595758b11cd,0x0002f8654f40a49b,0x0003794470b85289,0x00090be63ef6f452,0x00004957d29e05e6}, {0x0004363646559b01,0x000c39788a8e7d48,0x000ce54a9f4a8273,0x000a9bde406cb834,0x0000e1c2610086fd}}, + {{0x000e228cf6a4a81c,0x00025b488772e150,0x000a9c15b1fa3b6a,0x000a465e6ff110c5,0x00006133b924ad6a}, {0x000d55c9dffa978f,0x000c6f3965f28ac5,0x00032b52fba1d1c1,0x000a070969f4e077,0x0000ceecdb695172}}, + {{0x0000a5f10f2b8f5d,0x000e8c4c2f63b012,0x000f9c213c83a6cd,0x000bd47d47a491f8,0x00009e1cce6a3f1b}, {0x000bc7caba7e3721,0x0008cfd1a2db0d91,0x0004618e5fcdc74c,0x00025df5efa80037,0x0000121696925a79}}, + {{0x0009823f6021c5dd,0x00041ff14423d4c8,0x000cd1396880d5e8,0x00078a9523bc5a6d,0x00001acfdfce13c9}, {0x00064e8bbb66840f,0x000d82b58459b0c1,0x00038e8ecf7f4301,0x000698d29ad4a6a6,0x00005ab896236b78}}, + {{0x00079740e9547505,0x000814f9d2c69dbd,0x00085232e0121de8,0x000776de597b42d9,0x00005b6c3c5a3451}, {0x000e547519cb9fb2,0x000f6428600dbb53,0x00081791af134019,0x000c083a473176e0,0x0000f3e226355fb0}}, + {{0x000301773d273b06,0x00061721ef9ab28c,0x00050dc39ccd2107,0x00045da54cc292b6,0x000062246dec1880}, {0x00052fa6b83c0d12,0x000777e9cd46904b,0x0009725e4a72df26,0x000f22686b43cd89,0x0000b651688f849f}}, + {{0x0009b7902f345331,0x0003fc77c1486047,0x000537c785e354c1,0x00095fa4bb7581a8,0x000088043d7ffe14}, {0x0002f428c1d50261,0x000683d4aaab9ba1,0x00057c4502e0c8a2,0x000fefadba7b8baa,0x000040c9ad6abbda}}, + {{0x000aa4225ac0f182,0x000ae4d1fbf32067,0x000b04824f7b1295,0x000e90f4829111a4,0x0000ce3f19253bd5}, {0x0001d558f2e1b72b,0x0005802aa2439c7a,0x000be9554fe93228,0x000a6d997ca7b4d4,0x00008e821b990547}}, + {{0x00038be67e573e06,0x0008e084c44bfb28,0x000c1c2c505891db,0x00044b3131137396,0x0000aebfa4039584}, {0x000dce9e56e55c19,0x00029caa46d0ac9c,0x0001fe8eb7148ced,0x000f4c9e10c7efb6,0x0000fd835db8f97c}}, +}, +{/* digit=29 [{1,2,3,..,}]*([2^203]*G) */ + {{0x000a109081e9387c,0x0006cc935828a36d,0x00040b015fb9780d,0x0006fa15940332e5,0x00009d7b51ca0f46}, {0x000cd41d6d9f6711,0x0008a1a2ac17faad,0x000201e5fba6c1e2,0x00062af66a7833ed,0x00009d9971a090f4}}, + {{0x000f462060b5f619,0x0003ebd057c2f431,0x000e1bf65a56f46b,0x0001fea48dca6c47,0x0000a38783ed1bcf}, {0x00033a9da710718f,0x00063e0aeaf67a5d,0x00029d1875a77998,0x000732da87314d2d,0x0000a0edc3fb687d}}, + {{0x00036216a31e09bd,0x000cf1350e359df3,0x000a0cf52de89e44,0x000537592148714c,0x0000f379672db88a}, {0x000510a2591d61b1,0x0007485b447bc92a,0x000287f7779aa87d,0x000a80e67db604e5,0x0000697c8bf6efe7}}, + {{0x0004849cb198ac73,0x000cdf2646651c89,0x000200678a884a93,0x0004e5fda964ef9b,0x0000c351b8730983}, {0x000ef9fe2c4b44b8,0x0006b326790cafb2,0x00002264a580f6c4,0x0004e2384805210b,0x0000ba6f9e2c2a19}}, + {{0x000975f8fb547385,0x0007d7c3ead3fc87,0x0004a085a3516078,0x000996334116d2b7,0x00003c99a73f62fe}, {0x0005be05b81c51b3,0x00088e0852b78758,0x0004d19a7925bafa,0x0006d446a4fafda8,0x00009a4598288520}}, + {{0x0006ab65eb03c0ee,0x000392bc3fde499b,0x0003a80d2f19b795,0x00019ec86b5b9c6e,0x000043775094d428}, {0x0003650bb3ee8a3e,0x000bd132075fc166,0x000d834f675eb14f,0x000ffcc8ccc9067a,0x0000a6a2475c6e92}}, + {{0x000fd950f8d67583,0x0001108c07dd9d72,0x000e23221cb84e10,0x00042c89114bfda5,0x000058b5fe3194e7}, {0x00077ec95f40e756,0x0000dd73f3d61c05,0x0001b9b66f015545,0x0003c73d55cd67bd,0x00003e86e790f8d6}}, + {{0x00034abd3c095f18,0x000e64b76d7139d9,0x0003e698404b261b,0x000b109d2e6970e7,0x000079fb23bde5fc}, {0x0006c72dfd754907,0x0004f1bcf1c11150,0x0005e70073a97d08,0x0002a6d3201d82bf,0x0000f0ac52fe9823}}, + {{0x000cbc46eb564d4c,0x000bde570e292715,0x000f5fd5d8d6c752,0x000514380247c89e,0x00003c66b47953eb}, {0x000b4010f87de563,0x000f96c603b59666,0x0004fc942ce62c06,0x000c197e7b4c607e,0x00008ac0b77963a9}}, + {{0x00020ee4b049136e,0x0001556a4613cb4d,0x000e081288b63bf1,0x000b153221aef670,0x000062d8c522acb6}, {0x0004a67379e7896c,0x00020afd7fa571f6,0x00041ba6ab25237a,0x000e7e3077bd9838,0x00004ac0244fcd16}}, + {{0x000a86921fea4ca8,0x000773dfdac1548b,0x000685fafd36d081,0x00059989d8d71ff4,0x0000eff66bf452c4}, {0x000aee70b57235e6,0x0000a106712b182f,0x000fcdcb0ee3c39b,0x0004b9f107331fc0,0x000069fb9dd05105}}, + {{0x00001fb319d76820,0x00090a982feeb251,0x00061b344b029312,0x0001fa51c1c9b902,0x0000e008c5bbfd37}, {0x000dd1c0278ca331,0x0006d5aa53b1d866,0x00013a2cf666f76a,0x000836d5cfb77960,0x0000d3a1aadb3521}}, + {{0x000253173faa4851,0x000fb0a76878cedd,0x00011667dc8ee6c4,0x00095acdbccfc92a,0x0000a418ea92c2f6}, {0x000bd9251f73971d,0x00020a2ed89fdb11,0x0003e03193e4b3c8,0x0001aeca44f3f4e7,0x00001e3de1000343}}, + {{0x00004ff50f75f9cd,0x0002ae752b223c56,0x0009a11181d8eddf,0x000d7a3ef074dd3c,0x00000ffc1739cb86}, {0x000ece3037d90f29,0x0005d055856cabd1,0x0004c6dafe3f307d,0x00099fb22f93287e,0x000002aac66c3487}}, + {{0x000e7bf94cdfadef,0x000c8fc6d634b6a1,0x000fb63f86c97e1e,0x000404762ad24da2,0x000081be1ba95928}, {0x00065e4d14b4206e,0x000dafa0db6586d7,0x0007fc76cbecc2e0,0x00024dc28838e0b1,0x000049a602bc37cf}}, + {{0x000131a567193ec5,0x000a95f6e70b76b4,0x0001eebddaf3c305,0x0008314587bd3903,0x0000709def8c1bbe}, {0x00099830eb2b6692,0x000b675b70295705,0x00064ac164d80ce1,0x0003ab638a7da803,0x0000f431d23de1c8}}, + {{0x00012a6f9294dd32,0x000f7b4b0d77e568,0x000e8305cb448d01,0x00063ed3ae606104,0x0000bead645b4d8c}, {0x000434d84fd8b072,0x000fd7a9dee50a85,0x00055bd85537b983,0x000f8bcdcc5f18ef,0x0000041af6241c6c}}, + {{0x000874cb940c71e3,0x0009ab5f4b3a8e52,0x0001b1dc3211935a,0x0006206435049230,0x00003d2646d59958}, {0x000d64bef9114044,0x000a5a3c5ef416b0,0x000352c789d1f25e,0x000427e0f200eb4a,0x00003929f2c8bd0b}}, + {{0x0006667c7196e295,0x00004391be48a565,0x000e0cd6e7992c2f,0x0009bf5aa97cbd9e,0x00001b0310c8dc8c}, {0x0008acfdd9f22cb0,0x0001b585d584237f,0x000416388bb1d81a,0x00074f8d5d85f58c,0x0000d6e5a5a42fe4}}, + {{0x000276638235d4e4,0x0007096e3298e781,0x000175bc81c62bd6,0x000d4d4378660c3f,0x0000d04e18957afd}, {0x000160185a8068c5,0x000142b29a8532a8,0x0000d8a3bdb58e4e,0x00003b98a65b86c7,0x0000f0e6f4ee8a04}}, + {{0x000968469ed23707,0x000c9871ee260812,0x0009c5b0534dc30b,0x000c86ca5ce9487c,0x0000d487b80b3a90}, {0x000ba37dd0e71799,0x0001240418114089,0x000747ba545f8019,0x0005918c3e105898,0x00008c4e13afe1ae}}, + {{0x00036e6e82c9f9e4,0x000c833a1043d446,0x0008aec05711db87,0x0004aa2f431263aa,0x00003ff120d6744a}, {0x000892fae77779bc,0x0008ccdc9f82d3bd,0x000c5b1bcf0fe0cc,0x000a720a5f7fe6f1,0x0000c63a68304929}}, + {{0x000ba0c09dbe19a1,0x000d5b5c73c2c7ea,0x000e50c302f3585a,0x0000ba7ab8924b0a,0x00007fcd27a738b3}, {0x0004d3410b3d5a5a,0x00018a9accf1af41,0x0006a624209c107d,0x00064175dac49f94,0x0000ec3df2b7707d}}, + {{0x00092b73f894ae03,0x0005875f18ce2c24,0x00053cad0f59df3e,0x0002944cb740d28f,0x0000eb585fbf4f01}, {0x0000c8632c7f717e,0x000acf943f4c17da,0x0007c51d2eb8c795,0x0009486ee23fb5f6,0x0000f18757648889}}, + {{0x000bdb20389168b6,0x00088a577d03a6b4,0x000743082c4ecd25,0x0008ccda63782b55,0x0000f678f4d272f0}, {0x00011cf65e58dd88,0x000e5402c0cd5535,0x00037c14cd53b4e3,0x0002a9b7de3e29a0,0x00006b6c51740571}}, + {{0x000da3eb38dff6f0,0x0002ea636be82834,0x000dd37f8be012c5,0x0002db292d238c61,0x0000e54523f8f814}, {0x000b436036a05d8c,0x000e5e93c0ffe31e,0x000821ddf83e3cdf,0x00033a7fd2fe0f50,0x00008e19b0ebf9eb}}, + {{0x000943fb569a5fec,0x000414342d75c8cc,0x000eca000ad0090d,0x0000eac2090b4bca,0x0000a39687fdbd41}, {0x0000df765959d77e,0x0007bc964999e7bb,0x00041545139d7821,0x000107f87f62e8b2,0x00005efb7759ed76}}, + {{0x00011a4e822f0d08,0x0000da8704f83ea0,0x000c6820fbc647ad,0x000bec3b315b3550,0x000063dec3e37e76}, {0x0005d3af017bfc7f,0x0008a76b822901ff,0x000bd0d3b2005443,0x000d0e167fca370b,0x000063dde656f5e3}}, + {{0x000efb32a4c94e9b,0x000de6f8278a22db,0x00003793dafbff0f,0x000d28d0aea0b135,0x0000223802a0f06c}, {0x0003e578ec3fecad,0x0003693e70536570,0x0006734c406c3831,0x000f1dd0b751eb7c,0x00002e8a436959f0}}, + {{0x00090525e9ca895c,0x000dd72072df147d,0x000c6755c2f4dd31,0x000557e16fda8ee6,0x000066827008f196}, {0x00076a30cf43895a,0x000fe3c3097b1f1a,0x000390e0ea9d604d,0x000eff4190830966,0x000050bf75453c85}}, + {{0x000bddef6a702510,0x000b3c6ab16a0696,0x000d08762548b801,0x000c4e37fcf704a4,0x000090b3defdff76}, {0x000cb8969cb91584,0x0004595ece4387e8,0x000d9fbf544a9074,0x00082db85395f40a,0x00009b0f6c58fb0c}}, + {{0x000bc15adf7cccff,0x0005efa1e1b075d9,0x0009bc17e81a3e5d,0x000d429c39e44424,0x000037dccb37ea7f}, {0x0004873907fba12d,0x00097a372904da65,0x00083a6c535daa6d,0x0005be3564cfc662,0x000009fa4f71a939}}, + {{0x0009ec9aeb19a362,0x000ea7bfbfb4688e,0x000c2faa6d913f1c,0x000c12597b9a3c61,0x0000f979bec8a0a9}, {0x0009d0f359679ec3,0x000cd79b0460b596,0x000fab870ebcf523,0x00039ccd6b000810,0x0000f2edcdac373a}}, + {{0x000f9a76f568431c,0x000b42f8898c0d64,0x0000b5bd5f848c27,0x000ee83418ade126,0x00001f3e3242973d}, {0x000319c26c185ddb,0x0007a46f0ac446e9,0x0007f9d576d85b7d,0x000f47927965f224,0x0000519b63760035}}, + {{0x00063a9ab87d59c5,0x0002e9caaa116b61,0x00077387bff9f58c,0x0007f8fac39cde31,0x0000f6557c2d73e7}, {0x000400636a830417,0x000a05ef196c6750,0x0008c79409b1c96c,0x000316834283deb0,0x0000ea096448128c}}, + {{0x000b3b56aa39dff0,0x00029f8e4d8cb510,0x0004c4b9f59b43da,0x000c01a8ce31fd9e,0x0000e20be26c1303}, {0x0007182e8ee47c94,0x000b3db981011818,0x000e14ff6d9687cd,0x0005723a520e4da1,0x000029808bac836d}}, + {{0x000a60d4944b6639,0x000913f91ae5a37c,0x00036e3b1f901f7a,0x00025054e3e76e9e,0x0000aa219cfb9d93}, {0x000e275056a2512b,0x00092e65d95c347f,0x0009fc3eda4d643d,0x000bbde669d39669,0x0000598dee37f8c6}}, + {{0x000c1e5dda9e5c65,0x00027aa9fc95682a,0x0002bea444e0d3c7,0x0009c7c7faaade77,0x0000ef8428cfb000}, {0x000e47a460ff0166,0x000f125281cbcc4c,0x00023aad2da6d12b,0x000e27e4c6784802,0x0000e342afa96256}}, + {{0x000bb0b93a37c047,0x000b6d10bd961400,0x000ac46b762b1bc9,0x000f510251adeb0d,0x0000d33b92eebe4e}, {0x000a94be61fa29a5,0x000eb642223328b2,0x0000d8d374b2be13,0x000004e6d6d06233,0x0000ef80e1f028ca}}, + {{0x00046996d16768e9,0x0009d28bf217174d,0x0004e490d9fc4ff6,0x000979e7705a9415,0x0000d96dd291d2d9}, {0x000d9d8ce5d72c41,0x0004b11c714f77e2,0x000e4a03e9d06c5a,0x00028af2aa513679,0x0000386b3c2130ff}}, + {{0x000e8a6fb283f61f,0x000503abc3fbfe82,0x0004d36227df203e,0x000760fec7c3513a,0x00007d17dc0cf762}, {0x0006e44522055f0a,0x000aefa748dbc395,0x0001dcc14de3012d,0x000f3a2a9fcb63bf,0x000056d9dd05e4e2}}, + {{0x00086b68bcec9c2f,0x0008780b9f06b861,0x000d292817cf24df,0x000e11d46b45eac0,0x0000ff42bc5f7b10}, {0x0003c404d289427b,0x000904848ec41226,0x00040800c3d5f189,0x000b1f61f97010d0,0x00004c5f529e00fe}}, + {{0x0003f8fde94fdcb0,0x0009c7c2f05ecc54,0x0002692e1e96af73,0x000ae9aa5e003688,0x00009c75b68950d4}, {0x0003df2b5932a7a7,0x000e6e0979ad62f6,0x000e696312658252,0x00066aba19343fb5,0x000018c7501c25b6}}, + {{0x0002d69ea40dc3a4,0x00026ecc018f26a4,0x00070f04adc84ad2,0x0002ece5c36c7b32,0x00006ba6d4790fa7}, {0x000d1c593e58a8e2,0x0000f20c088c6c37,0x0006e86daa239473,0x000038a3be4263cb,0x0000c417d369126d}}, + {{0x000f9c58b6f8efae,0x0009577185365b70,0x00039c92b671a2fa,0x0003c1f3ced3c6b5,0x000056f1bda83120}, {0x0006ec49ff3c8eb5,0x0001f3491cea8b09,0x0009437942deae43,0x000842d465c6eb17,0x0000d267e6670586}}, + {{0x000116db07159d03,0x000f918962109d3d,0x000961579ae07a67,0x000dd65fc84d87bb,0x00000009e494c1f8}, {0x000af22e31328195,0x000ca23ab4ff8a8c,0x0005dd687cffa197,0x0007a208103a4420,0x00007b796c35ded6}}, + {{0x0003a6ca1779ad79,0x000da57c09c50b9c,0x000b4a57ea33cfe2,0x00052d9ea293153d,0x000019596961ebeb}, {0x000b9a6e546c8792,0x00044295c8d6118d,0x000ec806b8e996df,0x000035bd99048455,0x00004f291ca365c1}}, + {{0x00023bb440e22296,0x000213ef4d04cca5,0x00011ec39324673a,0x0008d34f3adf343e,0x0000136d7f23c596}, {0x0002899b053a9270,0x0001ae067ecd7a7b,0x000779cd93eaa266,0x0005ea8549b9c802,0x000061d7940c5338}}, + {{0x000a883f06d18bd9,0x0003227008433e0b,0x0001a9e4d4ba6de5,0x0000ed2966b66859,0x00003f675680f4fa}, {0x000711b4347237bd,0x000f1794608e5a02,0x000f73d8cbc041e2,0x0004f685af10f570,0x00002d4d4f88b756}}, + {{0x0007a89b3e93ce7b,0x0004ad3a2c1bd7d2,0x0005b218af7b5a87,0x000754029e68a025,0x0000533837f3af76}, {0x0005a73579fab2e2,0x0001ccd74385d1b0,0x0005e9115b41055a,0x00074e9236927444,0x0000972a7c515202}}, + {{0x000334ef678e68a2,0x000079b057ed6c08,0x000ccb69a4e4160f,0x0007721cfe11b852,0x0000fd1823a41c8f}, {0x000072f3298f0557,0x00098ec74a6edf7f,0x000b4d0418c0566f,0x0008507549e0195b,0x0000c3930bb0208d}}, + {{0x00041fcaaa2902bc,0x000924f69ad3e071,0x0003f9ffd539ad79,0x0002f6e6453f9481,0x000058d3c48f75bc}, {0x0006fad5dc64e964,0x00097240e354b332,0x000a1e7a93aafcaa,0x00089fdd1b0903ac,0x0000ceb97675211b}}, + {{0x0003e49e32a858e7,0x000e3e907badeca8,0x000b9b4944c32892,0x000e1b65b42ab62e,0x0000fde3ee28eaba}, {0x000ab09caf549579,0x000e55f5d5d513b5,0x00003e2c0bfb028b,0x000843028a065020,0x00000793aacf7476}}, + {{0x0002e79c81710a00,0x000627ccadd45e94,0x000cf6d0c557e4a3,0x00080c72a2bc564b,0x00009ee5f4326d7b}, {0x000dbe9d4292f19b,0x0005b3f16b186b70,0x000fbb42a56f74c2,0x000040123db0f735,0x0000606bdf71ae10}}, + {{0x0005d4d044573ac0,0x0006556b0ba41eb1,0x0000df6f77dc3cf8,0x000e8c97af9a33c6,0x0000b1ef85ca716c}, {0x000f884c96958bee,0x0003556909632922,0x000a000617c32fa9,0x00065b4d7f667cea,0x0000aaf7c1815473}}, + {{0x000de4687032d585,0x00030e2c79e01eb4,0x00004ef23c54f3d8,0x0001b3b7818df45d,0x00005faa9c8b73d4}, {0x0004f6f89b95355d,0x0009e7415c84ced6,0x0000ebad34860d2e,0x0005be8fdb9bd205,0x0000b53e0cd3685a}}, + {{0x000c0319feb65939,0x000fdaccff17b830,0x000555c10dd87f30,0x0000649303ebab9f,0x00004603695b87e7}, {0x00011c32e83358c6,0x00048efb0178f883,0x000ba8652508dd9b,0x000be51ca237062d,0x00002aac5a36047a}}, + {{0x000d2a08b1ea7b31,0x00039e8b14859a61,0x000052f99d495ab6,0x000eea28740f8487,0x000078ebe5bc2974}, {0x000bcca5b36d17fa,0x00030af86eea030b,0x000f8e9e0b5e4cce,0x000e75151a022068,0x00004348796a9eb3}}, + {{0x0002309eef1a7522,0x00074f2aa1edbe59,0x000007dd25d7162d,0x000d228ebfb5ed0f,0x000055e14b2e89ed}, {0x000e0720303b6972,0x0005d05720ffba85,0x00028ebb6c5d17e2,0x000112e2b58d6e51,0x0000c80242df754e}}, + {{0x000ca5fabfae1ca1,0x000c0a21459b919f,0x00066a4d2937afaa,0x0003318e0ca91c1f,0x000094cc7f333ec1}, {0x000143a8aa116906,0x000ca9b59e08ad25,0x00050860abe40ad8,0x00034bd7d60d9be7,0x0000c53b00926bf4}}, + {{0x000415d1356eb809,0x00030578ded8b572,0x0008fb38bb8bf9da,0x000b2192658e365e,0x0000b70ce22eaf8c}, {0x000018a829a81803,0x0003881ed2957c00,0x0003cea8384329f9,0x0005364c343ea25f,0x00008f8655f97586}}, + {{0x000a0d01d3ec517a,0x0001b12321aea661,0x000a925989874465,0x000fea684ca591ec,0x00009bb9dc9bdcb3}, {0x000435578b4c2405,0x000b110cafdc14c5,0x00038846b5ed62a3,0x000160b7512f371b,0x000071bb70b00e38}}, + {{0x000b95b2da705d20,0x0006b1a08f98b556,0x000ecfbe53ef8ada,0x0005cd85302ca7dd,0x0000e53057394310}, {0x0004d5521a9255d9,0x000162f3802a6055,0x00047787563a32fa,0x000da0a5c8c5b0cd,0x00007f458eafad42}}, + {{0x0007080eb6b242d6,0x0002db71e246832d,0x00031139dd30bd02,0x000e531027991bbe,0x00008797e91a62e4}, {0x000e20a6b4e185ab,0x000d92d9b707423f,0x000f7811b82f2c67,0x00095c75c817684c,0x0000d53005eb45bb}}, +}, +{/* digit=30 [{1,2,3,..,}]*([2^210]*G) */ + {{0x00049be9d8e68fd9,0x00028b044320e5f6,0x000c33398db0f053,0x000fae66fde9b3e0,0x00002f4209bf6c8c}, {0x000afcc1a739d4b6,0x000f428ab8dee9d1,0x000c6f1d009aea75,0x000aa4b4375fb5ea,0x0000420b560d08f7}}, + {{0x000499c6254dc41f,0x00038a837e7e9eae,0x0000524a77e29392,0x0005f184aec08c09,0x000082b921a7d6f5}, {0x000962e1402cec5e,0x00071a2f30e7493c,0x000b879cb9f17ca1,0x00045edcd783e8e9,0x0000a3d8c153a6f1}}, + {{0x00015e75e0dee6e5,0x00028c628aa2dede,0x00061bb9374f2487,0x0002e083e9c4fe78,0x00006d4822ab187b}, {0x00017cfc59826f90,0x00092408169eb664,0x0009ef885ca26096,0x00038fedf69d06c7,0x00000031f8adc7d1}}, + {{0x00046e60ebcf7262,0x00014231470e103c,0x0007c21094482b83,0x0006ef4f6dfaca48,0x0000e0ace9782e66}, {0x000a9d31f8d1f420,0x0001574944d23246,0x0007f334b1b1e83f,0x000d8113dfa63aa5,0x0000cf8daed9f025}}, + {{0x0008ea800ee11c1c,0x0003f5e3dd7530d7,0x0008c43c5eb053cd,0x000662db65b13ed5,0x00003ad49be7d151}, {0x0008e41b64279905,0x000d207eae1e99fd,0x000abb71e12cf15b,0x000d0dd9ad4f1b1a,0x0000143e74d57545}}, + {{0x0006336c88bdee1c,0x00059876767c3026,0x00073199625f2930,0x000950dc078571c6,0x000088690b3ad552}, {0x0002c2d852705b44,0x00040e09552d274f,0x0006575d1b0bf8d4,0x0006513628beeb98,0x000007be238bf864}}, + {{0x0003049a639fc6b8,0x0009060036250e5e,0x000cc1646e75c35d,0x0007398cf35bd85d,0x0000bcaced2ec262}, {0x000cf1db55367425,0x0006ca9e068be22e,0x0007909c5013dd89,0x000505c7f411cb8a,0x0000757ac98d61dd}}, + {{0x0001f0d1e935abb5,0x0003c54de37a85de,0x0009cebb5defd10b,0x0004be68d9e39236,0x00004d5ef9bc6132}, {0x00041ba74f17e266,0x000818c1dde44d63,0x000d918fdc0a0e3c,0x000a1346d7758187,0x0000687601562ca3}}, + {{0x0003e9cf36658f0c,0x000bb1f8057ec731,0x0006a835ac433ef1,0x00094bc53262461b,0x00008f053993c863}, {0x0008cdfe983c4a11,0x0001f3b7b931ff39,0x000b9045bbf5e816,0x00046b83193c46b7,0x0000e4ebf5db4a6e}}, + {{0x0002a6043a24fe7c,0x000e3fb3492bf994,0x0002fde0529c1191,0x00032cdf66244990,0x0000792a7ad2713c}, {0x0008ad8b737982c6,0x0009421e60e32fd8,0x00083591a7e3a031,0x000455a9b0de4473,0x0000df141eee310a}}, + {{0x000a039e6d6f4714,0x000ed198d12eaec1,0x000eee5ac14b2ba0,0x0004ceabc1a1603a,0x000001f483720b96}, {0x00037964fd03f663,0x0009ad8f3f122ee4,0x000380f183fdb4e4,0x000d163ef267f629,0x0000e8e9670bda64}}, + {{0x000180c207674f17,0x0006c3ae8fdbbc19,0x000aeb71e112e09a,0x0001c7296675546a,0x00009432af25101b}, {0x000558fde2ddec64,0x000f1357753fd5eb,0x000e1158a81392d1,0x00099167a76b973a,0x000016fbbff8a899}}, + {{0x000fdfd0d4a9dcf2,0x0008744ddf129e65,0x0008568667bc29e4,0x000fe29c1a92d93c,0x000073c69058e98d}, {0x000e418cdfaa6b88,0x0002d061c69f69fc,0x000f75e27606bd82,0x000a1ec2d495a06a,0x0000ed3d505ed873}}, + {{0x00028416ab25b6a0,0x00072b1a4523af55,0x000c99e03c6c0ffc,0x00091bab18827b21,0x000060e864890346}, {0x000f90f93c7f3988,0x000b02f8d10b5207,0x000d0f9e39f4a96c,0x0004f55d71cd793a,0x00004f435d37c3a5}}, + {{0x000c55b8e33787f1,0x0005963846734b03,0x00051b9f0ef42f97,0x0007c2ef7304f750,0x00008aca1dc841c8}, {0x00020a72d4bfe80d,0x000c353e732c56f1,0x00037ca16fd823b3,0x00096a41bccfe475,0x0000f6c9c74eb5a9}}, + {{0x00032c7904fc3fa4,0x000587e3636aee73,0x00091d9aa14a23f4,0x000540838659c3f0,0x0000a995e5df12d8}, {0x0003becf3a5598a7,0x000741eaa99520a5,0x00004e03c56534b1,0x0002682ed3dca4bf,0x000016c563b48d56}}, + {{0x00077a41d6178e77,0x000ff8a1ff8e27ba,0x00013f63de4c80c3,0x0006f3050110990a,0x0000bf33522161d4}, {0x000218e10b365bbb,0x00035fd7ea750aff,0x000b3a9258102180,0x0004e555a3fd8aa4,0x0000829e7604b3db}}, + {{0x00075a54d53e5fb8,0x0002552717e36bdc,0x000a42ec204a5dc0,0x00038206af502fe9,0x0000867e8fba630e}, {0x0005c6ebec9889bd,0x0001fb47c98dbf84,0x0000c2a1254f491f,0x00008ad3091fba79,0x00007f6fd79920f7}}, + {{0x000ac30acde5e173,0x00003852b4d7a569,0x00009ae54d0f996d,0x000061b51d4bb546,0x0000fa37d173daed}, {0x000868434b8fb41f,0x000caefb64f162a8,0x00048e1f299a2acb,0x000068c75c1a5e64,0x0000a99951b32b5a}}, + {{0x0006e892f3b26e7d,0x00000a8752476d95,0x00082dda3f470986,0x0002ef6ad1517924,0x000064110e3d17d8}, {0x0008d2cfad414e41,0x00081ed02b241492,0x000821bf12b155f5,0x0005da381a141bcb,0x00002e3c7705f81f}}, + {{0x0005de59fff83814,0x00021bbec894e49c,0x0004d88c41105323,0x00031b60d051cc45,0x0000f6db89c5f8e5}, {0x0003fd6ca563a441,0x000548da8ab934fe,0x00074f0a17f5c221,0x000a0a7445016d94,0x00007d34d61db7d8}}, + {{0x00039101c474019d,0x0009052ceefb8e9d,0x000622c2bcaff262,0x000a0529cf3e32c1,0x00004b95e3db9071}, {0x000a61f1594438c2,0x0005e4aadedffbbc,0x000e149401eb6e6a,0x000a9c653027f468,0x000021d322affabd}}, + {{0x000a9f6b7cb179a6,0x000d57934dcced8e,0x00009180ddc7b764,0x0002dd9cb139405e,0x0000629a6c0147dc}, {0x0005e4e9f5a915e1,0x00075204441ebfc5,0x0000c5f53b1db9d3,0x0005b1e82d68cf93,0x00007d3a142dbb60}}, + {{0x00044ea308780f21,0x00012845f5e4dd59,0x00024d7a3dc8de76,0x00011e5beaba7d76,0x0000e709afd404df}, {0x0004376021704560,0x000ac8f94b649536,0x00080ca68bf204b3,0x0005744e53af7c56,0x0000526074ae0c67}}, + {{0x000cef8ecd92af61,0x000a5cd1745a95d8,0x00025c3e4e6b9fa7,0x000aae2d546d3da3,0x0000f57691daae93}, {0x000f3fe9d2e1a33d,0x000edc063d35e891,0x00013a327d430093,0x00018f1da59b1255,0x0000c2134f42536f}}, + {{0x000fe2c5c2102869,0x000d8cab658caa51,0x0003572923f68aae,0x000becca23a00bf9,0x0000a626f3a0efda}, {0x0003bf3199d78e38,0x0006f1bbc345fe2b,0x00059802cb7a2af7,0x00051bbd19827a1e,0x000023bbc163487a}}, + {{0x00039f299d0a4221,0x0005e456c6fb8561,0x0001f8bd69ac3df6,0x000f879ddf65c670,0x000049f321e4758d}, {0x000f714721b7ebaf,0x000741a3312ab1ec,0x000c4d581e17df09,0x0001b2eb2fd6ecd5,0x0000d0299707fcea}}, + {{0x000a63e7882f14f1,0x0004f7c6cadce29f,0x00082bed0c9f6dc3,0x00052c36f22d6fb8,0x0000a45755be118e}, {0x0007c277c4608cf7,0x0001e68012c29f2c,0x000729b0e7ccbdf3,0x000dbf8cb0aedd61,0x0000ca2ca9f67d75}}, + {{0x000ecb16f640f620,0x000b39f51946f58f,0x00088af44e274b92,0x0009e57f4dfc0462,0x0000a91f32aeac32}, {0x000274bd6aaba315,0x000fbf6884f943ad,0x000f91e20719a163,0x000d52185d29f6da,0x0000ec1cc3377e49}}, + {{0x000de963b54a0599,0x00055fbcfdb338f4,0x000bb8da60e0015e,0x0007ac877d23d94d,0x00008724aa327a61}, {0x000885bfdb6558ef,0x0009d7899a9630f0,0x0002dc112f9f7a28,0x000458e2ae8ac887,0x0000a0642cb63c3c}}, + {{0x0006981e7dfc8d6c,0x000f5fb5b94a1529,0x000ddfd3767cd444,0x000dc64ec71cf10e,0x00007e5eeb45a8ed}, {0x0008e3d81d950286,0x000210b0e35d02ac,0x000881fe30088f17,0x000faa8c041fabe1,0x00002cf71b9399e7}}, + {{0x000dea7e0f222c2d,0x000ba2e651425043,0x00016cd30309d42a,0x000eebc4fe9ddd92,0x00006539c7ddf87f}, {0x000a57c432ac7d72,0x0000127fda1003c5,0x0000698de72692cf,0x0003b1cc28c85f28,0x0000331fb469ec28}}, + {{0x000fa322867e6332,0x0001ea9cc815d34b,0x0005e2fa578709a8,0x000fb597fe696487,0x00005cc064fbe98b}, {0x000151c493a65c5a,0x0000b31824649eb0,0x0004618e25fb5d94,0x000ab5c9e6f130f0,0x00008ecec23989c8}}, + {{0x000c88bb96209bd8,0x000b33e1c9e0cd6a,0x0008d8eac65fa8cd,0x000963247d22f54a,0x00003895ce00d33f}, {0x000ca59b56cd3d1b,0x000b2af38232a8ad,0x000080a9f10c8350,0x000b397b161fb3a5,0x0000e7f5c64eaf65}}, + {{0x000403997403a113,0x0006e21b96af2c75,0x000983ec294626cf,0x000df7131de7c46a,0x0000780dd3a82cc3}, {0x0000e462baf8e3b1,0x000d41d299aee28a,0x0007a2408abe68aa,0x000981503eb8f964,0x00004c61ed66c750}}, + {{0x0004414c53352e78,0x000b9337d46e88b3,0x0005f2bc85a34889,0x000a39e12c1560f9,0x0000a3f844254807}, {0x0009e975224da68d,0x0007f3eb00e9680d,0x0006bc37560cd6e8,0x0004c16875a98e9a,0x0000c80f9251fd55}}, + {{0x00034156ac774075,0x000ed54206816c4b,0x00007a458a1e5ea8,0x000bf9041bfa1446,0x0000dbc7e7ae6d7f}, {0x000851b31590a478,0x000995ee6df8646a,0x000b43fc0039e85b,0x000e04519fa231d7,0x00004bc8be8a99a0}}, + {{0x0002936f20df03ab,0x0001d608d4722b9d,0x00049202a2405438,0x0007b6c6b6ba0491,0x000021c3831e670e}, {0x0003059d6fdee104,0x000338488e71ddd9,0x000fcfb259da47ad,0x00095459cc1dfda0,0x00002abde10a4696}}, + {{0x00015fc17eab9fe8,0x000453e7097214cc,0x00032112cd6e863e,0x0004d7a9a7765c64,0x00008660001db077}, {0x000175a2c088eaef,0x000d9230b8d43729,0x0005f437913afbca,0x0008115476815191,0x0000086431bc8d22}}, + {{0x0001955c298b9743,0x0000c8711e043746,0x000969d18905fb5f,0x00094e487abf3afe,0x000092167c29f6a4}, {0x0000d2d28c511da9,0x000c266a262dfc7a,0x00063fdf0f127c7d,0x000f4669c4bb95fd,0x00000016589c913e}}, + {{0x000a73c11aa600d6,0x000d3fb5ab5274d2,0x000b700682f5379b,0x0009a7849e53a47f,0x00008dd39e5a04aa}, {0x000cf572ecaa9c3c,0x000b2824826bb9b0,0x00031a3c4ba0e103,0x0006a1a0c2198b46,0x00005ff84acba896}}, + {{0x000be22ac95aff87,0x000b45a46d092d6e,0x000ee4f8d1c9bb6d,0x000feed19062da53,0x0000b9042d12b97e}, {0x000f080830cf6bdb,0x0009bec8a6c60f87,0x0002f01aa4861d19,0x000bd523a0daa120,0x00000111675a25af}}, + {{0x000d6cf1afb20d91,0x000030671bc56d00,0x00085ea9b1369500,0x0001ac813ab0dc24,0x0000f2bed06aeef6}, {0x00082176d799e206,0x0006d271c2de850c,0x0004f591093415f3,0x000420fafb06e96c,0x000088a52e024e9e}}, + {{0x0005ba3e2a9a6db4,0x000d18f9268b3049,0x000b0f04f4601303,0x00036d7e3b0dad7e,0x0000ea4725084569}, {0x0008798d33fd3e7b,0x00093b4337088caf,0x000fd50ad1ccd8a8,0x0004deeeffe3e887,0x0000e240a571b29c}}, + {{0x000fd98ca0e7ebd0,0x000ae748616eec4f,0x0007baa99f586783,0x000c9ca5b00d8fc7,0x0000acada29b4f34}, {0x000d67d0fe723ac6,0x0004d9c36c1e36da,0x0004bea411d8e53a,0x0004e084dd342d1f,0x00004fd5e364bc9e}}, + {{0x0001f9057908805e,0x000c7ed480dd96f0,0x000fd2dd0b5b9ea3,0x000a26566c5dc23e,0x0000d2fe3064e9df}, {0x000e8926e9197e27,0x00093b502a5d4575,0x0001f213f11719c0,0x000456b64c7bece8,0x000041b9241c5f5c}}, + {{0x0007b6849a5f4f41,0x00028fc45b7d78ac,0x000f5f355f91d70a,0x0000d929b05544b0,0x00001f06bcefef93}, {0x000d25d038d05e1c,0x0004facc1d51db84,0x0008ee00b04838ee,0x000a1edda3ce869e,0x00003412058836ed}}, + {{0x000b91364d9c2f41,0x00039010a8ffae80,0x000359d417468bac,0x000acccfd2003737,0x0000a0f5ab825efe}, {0x000ad2f659d0ce0a,0x000ac785cff17c25,0x0002192c74011bcb,0x0000e7728b99127e,0x0000549d8e1b3ccb}}, + {{0x00088d8c85438b17,0x000d4c25cb278055,0x0004bfdf45680332,0x0005666cd1bc961a,0x000079ff428e06f6}, {0x000e998f059987ad,0x0001fc686de78bbe,0x0003cfdb2f6ce8cf,0x000a3628ad3c4a95,0x00001d426d9f205d}}, + {{0x000f13fc781a2419,0x000e475362a8b3c0,0x000a911843e89360,0x0007f43cd05863c8,0x0000bd0c9b87fa8a}, {0x0004d538a912a4b1,0x0008acf518fd97ee,0x00067e1e0de5e15f,0x0002565a055bf8c4,0x00000be4b4b2587e}}, + {{0x00014f2668621c9c,0x0000eb9c92c1d90c,0x000d47b3cd5518f5,0x000174ce6a0100d6,0x0000be980de26716}, {0x0003f10ddd83683c,0x000cd9cac73c500d,0x00083d5503b6cb35,0x00098693730c8b60,0x0000f1597689f0a1}}, + {{0x000cf5343ad73b3b,0x000f9f035a9484bf,0x000eeac691b528c1,0x00023f9294edf733,0x00006283e84317f3}, {0x000c9590a5f25b1e,0x00047844ee22c3fd,0x000dde4deefaf8aa,0x0003befe269ba5db,0x00003347161a5613}}, + {{0x00042198d9ea9f87,0x000b83fc1ab5c118,0x000f22cda090de5d,0x000893d04c37b10b,0x0000de20ec965618}, {0x000588eecdaecabd,0x000cb8342743754c,0x000a938ec6ca4b0e,0x000ccaa6f08bddf4,0x0000182de8a61493}}, + {{0x000c53ec8a4186a5,0x000b446d8e33d652,0x00037663cb3e878d,0x00048ab88453c05f,0x0000cd9daab04077}, {0x000197f586d5e720,0x0008c443ca59a1f5,0x00065242447500be,0x00067d78ef35b2e2,0x00009c5d26f6dd77}}, + {{0x000a79aa74d3f7b3,0x000d9f5ea4597175,0x000d1746d0428fd8,0x000278211cb97ca5,0x0000636393a171d1}, {0x000f95510350bf49,0x0008d0aae782cf2d,0x000688809b381743,0x0000061748c0e43e,0x00008021fc067a5a}}, + {{0x000a70c0e367a98a,0x00046f62b7c29076,0x000fe0343bea1bc1,0x00014e8645a68c30,0x0000caffa79099dc}, {0x0009964457bf9c43,0x000add2ead83f446,0x000c6f3eb0db6407,0x00056c38d56cadb2,0x0000b512e7423763}}, + {{0x0000e1ffce104080,0x00035a5e257de43b,0x00062e5b389ddc00,0x000161b0ae0d1203,0x00007f983c7b0519}, {0x0004d155d5231e7b,0x000c5b4f9513c2e9,0x000d0b0b5cff22ae,0x000cd5002588dd6a,0x0000967d1acc1d0d}}, + {{0x0006bc6cf777b6c0,0x000d4c6d19598dac,0x000f5cc850062bdb,0x00014f53da71b50e,0x00007012c7d4006f}, {0x000f962ac47800d1,0x000bb102ed754617,0x000b8c9d353365f2,0x0001c9a422efcb4a,0x000095cb26b44af3}}, + {{0x0006e2905f2c4ce9,0x000b0856966c3a92,0x000527015bd2bdec,0x000230cd16ab3a85,0x0000f81609ed486c}, {0x0006b2cda350002f,0x00000a1b7d36d8b9,0x0001d79bcbd05469,0x000e4dec90ebf5e7,0x0000241b6f9f8964}}, + {{0x00086432fe3cd4c0,0x000bb4bc633c7c83,0x000139f1fe0f33ac,0x000f49b4a9ecec3d,0x00005ce69cddc4a1}, {0x0001b16f5f98aaf9,0x0005df23e0efa19d,0x000cdfdd345bb71d,0x0000c9a3789fcd46,0x0000b8e29795ee04}}, + {{0x000b246ae0a6828c,0x0003b078d5aa9c69,0x000b4fbdbba533d2,0x00085bba2e42c07b,0x0000fb4879b30353}, {0x000d30b3281705b5,0x000bf04fe0818c3d,0x000604edf7e361c6,0x000e472b21649c3f,0x0000dbf6a40352ff}}, + {{0x0007c234b54d9bf9,0x0000a511c3d9c41b,0x000b2b7581374e68,0x000a958863bf16c1,0x00000e78507ae9e6}, {0x000f98d5d86f1749,0x0002f5e96fe4ab4b,0x000c5d344d74e0bd,0x000846fafde39fca,0x00000946dbd4d91b}}, + {{0x0002358fe1a838c8,0x0004e20ac9d8f5b4,0x000ce5a0b05aae6c,0x000d720e193bd8a1,0x0000f710571cdabf}, {0x000dd48182caaac9,0x0009740745cf8d8f,0x000b93e6d8c4aeef,0x000010e3c6c30af3,0x000091241f3a6f42}}, + {{0x0008eeae457a4773,0x000bbe6ddc05a015,0x000c41671d19857d,0x000d588326522418,0x0000ffdfc7e6c2c0}, {0x000525426ee7cda3,0x0009af02c3a83a3a,0x0003bbfc8341b086,0x0006917023bf4272,0x0000d15002a44452}}, +}, +{/* digit=31 [{1,2,3,..,}]*([2^217]*G) */ + {{0x000324c85edfa308,0x000407d4f3da5ef7,0x000b50c862597655,0x00096bb52f5bc0dc,0x0000f6927b0c832a}, {0x000e1ba55f2f94c5,0x0008e44b45fad08e,0x000aa455d6a996f9,0x0001f79133cb8da8,0x0000d0721ecc58dc}}, + {{0x000a92079e5fb67e,0x000a90aa725e6ba7,0x000f5d837e1331fe,0x000e207080ccf57d,0x00004cae01e5ff72}, {0x0003ee60412a77db,0x000c2f449025d924,0x000ef5a3106ff7ca,0x0007a80e75f7cd23,0x0000c957822bddef}}, + {{0x000230cb0ce1c552,0x0004ebbfb6078cf7,0x00016363b5b534d0,0x000e82ce1ef1130e,0x00007e0aa7ad4999}, {0x000ac2d79362c410,0x000091bb6cb0ce1d,0x00023df2467920c9,0x000f281e648d6322,0x0000f7d9eefe32e8}}, + {{0x000f39afa8338349,0x0002163285626943,0x00070fc102295172,0x000e6cf1d63dd541,0x0000f5fa5903ecc2}, {0x0008725e77d9a3b0,0x000a6384ebe0b66c,0x00045e24a11235ce,0x0003b106a8c11858,0x0000137b286ebd09}}, + {{0x000e1ce44ace1509,0x0008b381e97cc589,0x000c5a4b8e0f8d3d,0x0009f8c9e99b1162,0x00000d262f88d0ec}, {0x00054c9283e13c98,0x00072edc7085fbc8,0x000dcbecb2d04fde,0x000a5e857d776547,0x0000dbdf5921a76f}}, + {{0x00006950de1e5786,0x000789f72bc6d015,0x00039eca52e1463e,0x000f2f9fa684411b,0x000073c8530dc037}, {0x000a600747f91da5,0x000179cb78e9d0d6,0x000b5cef5b08d43e,0x000fd5bfc0c64427,0x0000c1d160af60a2}}, + {{0x000ae5328c8e13bb,0x000402eddcd1f98c,0x000ce06ad375f10c,0x0001ef24eb8b7f5c,0x00004669f4630a2e}, {0x000f9d05bbd8699b,0x000937976d13d593,0x0007e28d35528a4c,0x0005768923e0951c,0x00009293790ef6bb}}, + {{0x0007d6ac42bd6d29,0x00082b1f96aedb56,0x00043b28e6df8646,0x00023f7efe5b1a48,0x000061bbb05f379b}, {0x000f5f070a6a26b8,0x000cb28e6e39b6ca,0x0005fc8d370686c0,0x000dc900da06cf89,0x000004d88113363f}}, + {{0x000877b207f16700,0x00084e615291be22,0x000a3c2bf9b0dd18,0x0006e8625ae8dc97,0x00008584ef7439b8}, {0x00090a5dcd898ffc,0x000f6058ee3dde71,0x00087b1c126286c3,0x000db47db0b2175f,0x0000c334771d02a6}}, + {{0x000e9542f770fb1d,0x000f7cd7535ed99d,0x00009cefc97c1c61,0x0004f803b6c4483f,0x0000725af162a63b}, {0x000d24fc01e20ecf,0x0003aae7121f0c95,0x00077b7ecdfd3749,0x0004ad8d6ddb72ec,0x0000e079d3bf353a}}, + {{0x000e70a2e6ac8d23,0x0002e06e5c053066,0x000e59b8c9c6b5a4,0x0009ae22d3c6f5ed,0x00000d6a5c42ccec}, {0x0007c224fc0a9ef0,0x000395c16cededec,0x000de0fde190ff08,0x000433be12ec8f94,0x0000d131ab8852d3}}, + {{0x000e07e857012919,0x0008894061a842ac,0x000f4a48594793ed,0x000f4ca0e83ed6d7,0x0000eec726a89eef}, {0x000ba590c9d8005a,0x00077e79b9d190ac,0x000506a1e5feca45,0x000fa6efbe54271d,0x000032b2c8ec439c}}, + {{0x000c17373dd0b4ea,0x0003a4a054c61671,0x0008b53f137a2821,0x000b9de1760a1b4e,0x00006c0422599f93}, {0x0004b34cf671e3ce,0x0001eda9b9941878,0x000ab384881bbecd,0x000c2c58831979b2,0x0000f54feb8d2e03}}, + {{0x0007ca7fb8088fa5,0x0006fddc96c5cf19,0x0007771760142724,0x00071d52d2550a30,0x000034698989d0cf}, {0x00037b83a2aaac68,0x0002daf38d9b6ce9,0x000bf2899e9f91dc,0x000c15a598ad83c8,0x0000e706aca35536}}, + {{0x0007495f688dc983,0x0006e24c4afc40dc,0x00018775c26490cd,0x000f4ab651ec841f,0x000093ea6c3e4fda}, {0x00033437f338e0d8,0x000ae053e7b51e1f,0x0009e14d539fb832,0x0006dfc6e702da61,0x000059cacd24deef}}, + {{0x0009ce74462007dd,0x00047cb5f5b763b9,0x0005edde7b8ab48a,0x000fd9cec673d2f5,0x00001567f755cfae}, {0x0001b6b0887bcec5,0x000e9178f3c24638,0x0006266cb694497c,0x0004130e6525e31e,0x0000931de26b97d6}}, + {{0x000df7c0e58d4939,0x000fc8b73f1287f8,0x000a0c34db1ae5ec,0x0001a03368f784de,0x0000bd0a121159a9}, {0x00088b7cc863c683,0x000e0d1f4d65b00d,0x000a855933a1cc11,0x000ee8ba38e0e70a,0x00007f13e98adc4a}}, + {{0x0008667bc947badd,0x000d5a36ee2e10d3,0x00077fcac738e07c,0x00070cf93470cdc5,0x0000ee1b616f7824}, {0x0005e672e793d12f,0x000df0f186da36a2,0x000e07af7d6aa6ca,0x000cd3574d0fd980,0x00007cdc47eaa8a5}}, + {{0x0006d9dab15247f0,0x0000493a537f28af,0x000a334e77c789c1,0x0002777ac9b11023,0x0000236ac0912c9c}, {0x000bd251d7a51446,0x000a913ec4eca7e5,0x000f0abca098b9c2,0x0000f8d639dacad3,0x000042da81b02396}}, + {{0x0005c054f7269b13,0x0007b287c3857d2e,0x000a46f21fcf3077,0x000a35e0edc84ff2,0x000054417577f43f}, {0x0007899fd703431a,0x000576dd587af132,0x000c8352da438d7a,0x00024dc5c34c57e9,0x0000728edabfcc5a}}, + {{0x0008abc42531689f,0x0007110963efaed7,0x00017d9b30a51a0e,0x00028a6776fa0ad7,0x0000356c23a6dd34}, {0x0003fff8d3a3dace,0x00095d94491f2990,0x0004a56a4409597f,0x0004616cd7a5ffbf,0x000050964756adab}}, + {{0x00051265c3427b0b,0x000c2282c9bda97b,0x0002c5c456401405,0x000aec8629f8d722,0x00001c02c1798d50}, {0x000ed75d9635bc92,0x00074e24552fbea2,0x000f1d066226790c,0x000c2e1c33f2a365,0x0000a43463e8dfcc}}, + {{0x000453adb4837611,0x000555d5672b8cc3,0x0003efc87e7cc608,0x000eaf177ed6cbde,0x00009f2f36879234}, {0x00043175c0b800bd,0x0008bb6da6e29aaf,0x0004ec75e1f1e7c8,0x0008c19cfb4715b9,0x0000590dd6015311}}, + {{0x0009da11f17a34c7,0x0008b35a145614e4,0x00050363b5420ab3,0x000b6e476372412f,0x0000b15d62433fab}, {0x00040b1e274e49c4,0x000456b1860aa0ef,0x000afe5a45cf5074,0x000e9a96583fbf66,0x00004240511347e3}}, + {{0x000434311b2d595d,0x00091ec8df579925,0x00073dd05f136749,0x0000296cb12c613e,0x0000248c0344dac1}, {0x0004f13a77739f5e,0x000a43d2af42cf15,0x000e4a1cfbf4288c,0x0008f2ca64c9b632,0x0000e8c07a9a8a20}}, + {{0x00049996fe8393f2,0x000fc91f3a32e10d,0x0002f63c80f809a3,0x000d3d41096d1c80,0x000089e146277750}, {0x000167e9889feea9,0x000250993909ed06,0x000508ac6d5c9c0e,0x000e82b6fca0d856,0x00001826047df1b8}}, + {{0x000877a9a4a27515,0x00027ae6fead4f2c,0x000aa194171bd007,0x000aa7e8df8dcc06,0x0000a074b4cb3bee}, {0x0005934c1cec8edc,0x000deabc03bdd6d6,0x0008a8415a6ecb49,0x0006dfeade91c2de,0x0000fb0efe029113}}, + {{0x00045ee23ab3495c,0x00074b77463d11af,0x0005d06f4a132df8,0x000435c923c15c81,0x00003ceb3f5cd61a}, {0x000291de88fb1da6,0x0003bda12179af52,0x000fef720ea05797,0x00084550d7218cd2,0x0000c0899c9ee1d8}}, + {{0x0007504752ddad71,0x000f91a68a979815,0x00058fb99d60bd74,0x0001e46047a3a9f6,0x0000f5d86d66f851}, {0x000bc424b5a6d88f,0x00022abefa7db8a4,0x000c9c51069eb2c3,0x000b42a5bf39e813,0x0000571960bc48aa}}, + {{0x000fbcf704e23c66,0x0001c8aaa65b7e8c,0x0005e3c83c71b7d2,0x0004ff4041b2bd24,0x00009b9883532185}, {0x00027a3963bfeec0,0x000ade7da7cb89d2,0x00068a9b199947aa,0x0003681d9ee9dbee,0x0000a08f003698ec}}, + {{0x000409478ef24870,0x000502cfec26e9ea,0x000dcf328c8d2d41,0x000937c52f9a6eb7,0x0000ed489e385b6a}, {0x000986bbef3366e9,0x00005dddddb89b94,0x000dddbe20de59c7,0x000a406fdb748cea,0x0000b9784bc1266e}}, + {{0x00055021a93507a4,0x00074d3c06cf142b,0x000ec3f40b4cd118,0x0003c29f70e76a91,0x000084e81ad8e755}, {0x00087b5272e9d6ec,0x000506ff514a830f,0x000192a8eea1c93e,0x000359a7cc2adcc4,0x000077e27e302f45}}, + {{0x000ab36d2b713c5b,0x00001f7b0cd39cdb,0x000af826b86274ea,0x000ea2c84680f309,0x0000fcc837abc72d}, {0x000fe9dd6529b73d,0x000793a88002a8bd,0x0001d45b9708aa22,0x000f559c7a9a54c9,0x0000f1a38bccd004}}, + {{0x0009a26b8bad853a,0x00029723eae72e8c,0x000ca28302d52cea,0x000410654d6d8156,0x00003317d153a8dc}, {0x00062fefd4ddedab,0x000a055d792ba086,0x000c6e944ed2a153,0x000cf2c035c16abf,0x00006bc5834b0171}}, + {{0x00052b383d102b6b,0x00065646b848e271,0x0006e6d37fe695a4,0x00015df5bb09d891,0x00004269d64bd170}, {0x00056a10a1d22850,0x000146d26d728d81,0x0005434a7feef6c5,0x000e319dac57c84c,0x0000282e5be59d39}}, + {{0x000f181721c486d5,0x00006c58824eedff,0x000570031301baf1,0x000e683136a6aa00,0x00005aaf78c6cddd}, {0x000937159c639522,0x00046bc25baf2682,0x000e52dc33a3bd27,0x0006c8ccdf8657b7,0x0000dd8c0881d78e}}, + {{0x0003274f5531461d,0x00008d95499b2055,0x00080f9d28b4a128,0x00075812c8763a1a,0x00001dbe32c1ddec}, {0x000210d30c34169a,0x0002d8baa533af12,0x00038f254ba74a95,0x000f5a9d133c6ea4,0x0000431531ac01be}}, + {{0x0005e22f669d7ec1,0x0004257fb5151529,0x000a3fdb3ca374f6,0x000da87a8406ffea,0x000006ae448ef3f2}, {0x0000a9033c8e9a1f,0x000181ad58858f9b,0x0000aed14234645e,0x000d454d0832241c,0x000010a7d3f6a942}}, + {{0x000deee40d5c9be3,0x000f8a84ed987c11,0x000d58dddb2bae7f,0x000fa363e97139aa,0x0000d8727966f6d1}, {0x000ca818569ff132,0x000b7a600f72483a,0x0006f2b868b89a5f,0x000c0b2cbc27c3c0,0x0000213071383ad9}}, + {{0x0008b1e48ac28403,0x0004bcba9477b535,0x000946b431831129,0x000819aa58f990a6,0x0000098baf9cab41}, {0x000c1584198da522,0x000bf46bfd1b66c4,0x00036a908ab4fc17,0x0008380f0a4c3cbf,0x0000ae9e34b78cf7}}, + {{0x000529e3fa11b1f7,0x0007274af2b4f411,0x00030793b21e4367,0x0000f30c20958ec2,0x000010ea88586e84}, {0x00021fcc5dc67cf9,0x0006f8405718fc0b,0x000e49eb708d5164,0x000a1f4955c21fcf,0x0000722a5d5e6dd4}}, + {{0x00050e2c861baa5c,0x000cd505ac3ec9ef,0x0007c063fc0c21a5,0x0009c0ef6b9a338b,0x00006370339ef477}, {0x00099c7638167c3f,0x0005895db30c22df,0x000854989fe6ffe7,0x000aa43b822d33a4,0x0000ef031de20563}}, + {{0x0009f82d57c667f8,0x000e4c0b76f116b0,0x000118aecc70312c,0x0001333f04a9e6c9,0x00002fcb419b409d}, {0x000b385ab45d44d1,0x0002517b83a31a8a,0x000e81b52fba0722,0x000affa05f50dd58,0x0000d8db55331ce5}}, + {{0x000b8d4e344a8732,0x000dde36d53e3097,0x00075e7507d8d116,0x0004ea4db22f5878,0x0000dc5e37363e14}, {0x00032e6e799eb95b,0x000eb899e6ecc05f,0x000ab23d5e9e5f4d,0x0000e60dc3bd681f,0x000072b8ab823af6}}, + {{0x0007ae02cecc84ab,0x0007cbdb871c8db2,0x000c46f58600016d,0x000d3892a44b13d7,0x0000891972873a77}, {0x000bbbddafd60884,0x00062bd20d39cfc6,0x000c410721a74014,0x000ea14c747abd98,0x0000c91e765fdf68}}, + {{0x000e5ca08819a786,0x0009695879217c95,0x000bbcc7dcf48b72,0x000148a91c7c5fde,0x0000f28740550e05}, {0x0005ac226cd44ecc,0x00060fea250ef83b,0x00006ebc588ae32a,0x000780aac5047a1d,0x00007e550b59434f}}, + {{0x0001cf25c727bd2e,0x00003cf915b061ab,0x0009d39202e4badb,0x000dfd3b4dadecf6,0x000061b1ca7d14c1}, {0x00079ccbd6bd51f4,0x00014045ec3090b4,0x000ef0e628024e40,0x000bc08ab29ca325,0x0000f2e941689e4e}}, + {{0x00040ec0ccced589,0x000b7da44f9845eb,0x0001812c625cd4b9,0x000650b3e0645887,0x00009f80d55a6cef}, {0x00040c9ce6dc1532,0x0007b86655215713,0x00007014d138d511,0x000b918cdb45bc4e,0x0000f34bb38a4b60}}, + {{0x0004fd22ae8921e6,0x000e292ba1e2f44a,0x000c180b2b039288,0x000c873da50174b1,0x0000b70ab667693d}, {0x000abc9e70574810,0x000f9c80dc417e9b,0x0002946824581dde,0x0006e50c890da951,0x0000b5629d33f473}}, + {{0x000c79eb06f5b41e,0x000d6e2434692340,0x0005a71a9a42e84c,0x000fb619a2013504,0x0000fbfb416b27b6}, {0x000ea239d33cd6f3,0x00087a6c0af825eb,0x000ce6f969caedb8,0x00015a23dc7e9ad9,0x0000897f9fd81e0b}}, + {{0x000b1f88e5d788e9,0x000851d490eef51c,0x00058cb3c1aec7ba,0x000d30965991e0cc,0x0000f306e8d2fc3a}, {0x000006e5040a0acd,0x00032b476f2e5fed,0x000ea7a23ca9d504,0x000b62d19c06e8be,0x00002865801dedab}}, + {{0x000293f6967469a8,0x00090d8a8ed8db92,0x000c771222894d83,0x00026a07c9e406bb,0x0000671c6f1aea3a}, {0x000f8d6d7de9853b,0x000601f2bcc7e42d,0x0009d50cf2e3ce34,0x00098f2a601dfc89,0x0000fc913dfab1b5}}, + {{0x000909fe61f7908e,0x000ebbbc7b2981c4,0x00004b338192e304,0x000d60e3ed8738c1,0x0000dbe9e48583f5}, {0x000e9be2db30660f,0x000ed0eb7d8e0c06,0x0002e096eda3e613,0x000246e8fa3e9732,0x0000ebd91e9c336e}}, + {{0x000ccc4df655a499,0x000bceb202108f13,0x00056b6eaa9e00df,0x000946f4631d0fc6,0x00003a058ce68c0d}, {0x000904a67bd3448e,0x000a1394fd5c6846,0x000225f524a3d4e1,0x000e99e102c1a5db,0x00003455bbbdc4f5}}, + {{0x000985b4b9ad1ce1,0x00064bb7f7936b36,0x000b1a416a981853,0x000ee75c25e1d048,0x0000381dd534c81b}, {0x0000d617a4a76209,0x0005a9b8944cd2a3,0x00097c33ac841292,0x0004e6ac1c6fbe7a,0x000041e541e23866}}, + {{0x00099e84a34f239b,0x000c090402d54174,0x0003aa83215fdb83,0x000db1075f46bf43,0x000061e15b013215}, {0x00059d4a127f89a5,0x000bb7e816daaabe,0x00018b6925d541e0,0x0000265aba0659a6,0x0000532773367266}}, + {{0x000a0fc95f57552b,0x000fbcacb0c9af53,0x00021be013294764,0x000145753ff58dc8,0x00000309532506f1}, {0x000bdf505c2e54da,0x000c86e8dd2259bb,0x0007e1e53158f27a,0x00050d2c5b7ffb39,0x0000e03f65c1fc1e}}, + {{0x0004ebd9c95f0f98,0x0001a4640771a978,0x0005561c45ed9deb,0x0007ddb1244af703,0x00007332f3afee85}, {0x0006e9e2b9e0d888,0x0003d6a0604909e1,0x000592f4852d910f,0x000677d07ed477a9,0x00005cb917ba365d}}, + {{0x0001c934c8998d19,0x0000e30ea58ff851,0x000029db02186a3f,0x000759c0189626b2,0x0000137a6d992ceb}, {0x0007f37748bc82c0,0x000180469f8c2fe1,0x000891aa287c2e93,0x000d8d850f71cdbf,0x0000ca1b89b75ec3}}, + {{0x00043aa5e1cd3cd7,0x00082a887c28516c,0x000ea1f9f8939780,0x0008f69059c699dd,0x0000737d6fafe686}, {0x000746a60f1524b3,0x00058a052aa76d93,0x000923ea536985e5,0x000a1111b1d322ed,0x0000429759f55852}}, + {{0x0006ec3092e9f414,0x000622256bbdbeca,0x000ad487d3a238c6,0x000d93982958ea70,0x0000ac8aaf9a5610}, {0x00001b15e4ccab05,0x00024de14bfb3fa1,0x00031899d9bf430f,0x00017d510f5cc665,0x000090005fc3a8ce}}, + {{0x000912f24544cb60,0x000ad79ac2e3c437,0x00058a2129987b71,0x00060613e3d9ddc0,0x00000075aacd2de9}, {0x000508b6cac83696,0x0007954f6c8980ab,0x000c532a487842be,0x000bc847ad663d6b,0x00007813de7d8a91}}, + {{0x00061cec3427239e,0x000fe56934d95dcb,0x0001915915f3c7ce,0x000da6e079e0fbe3,0x000040896be901aa}, {0x00067910492d25f2,0x0009c74082768d46,0x00087aacc8aeb30c,0x0003d4c943749592,0x00003d4708d99fe0}}, + {{0x0009cf2d0c051995,0x0002aae784548cda,0x00072a182502fbc2,0x00037270bda9dff5,0x0000f9b71b8b158b}, {0x0003a592b82dd077,0x00052523032ee0f3,0x000505a327630273,0x00009f0fe1a721c4,0x0000b6e3e8367964}}, +}, +{/* digit=32 [{1,2,3,..,}]*([2^224]*G) */ + {{0x0007bc035d0b34a2,0x000b6327c0a7e341,0x0000362d1440b386,0x0009436fb7262dac,0x0000c41114d00cdf}, {0x000cef1ad95a0b12,0x000847d543622ba5,0x000e486c9c09b37a,0x00029706d6cdd201,0x00000477abf62ff9}}, + {{0x000dcb3292a92874,0x000637b092c7a004,0x0006c0605ddc15cf,0x0007afc83a846480,0x0000a68df707db99}, {0x0004e4505bf7dd0a,0x0008eccf7f8c9c13,0x000b5f8afa4e63d3,0x0001cc06e6517f41,0x0000a8b93434d7bc}}, + {{0x00035b51e706ad97,0x000453a9ebdf126f,0x000608d90b99cebb,0x000858375389afbf,0x00006113c5036c89}, {0x0008eb097e2b5aa3,0x000c33b9130480de,0x000cc066c7e1022c,0x0009000bdab6056c,0x00003cbb144e2edf}}, + {{0x00064717af715d2e,0x0003f0134a96c417,0x0001ec956e2f7f59,0x0003034c1873efa4,0x00004e7b4f757821}, {0x000ff9788d5374a6,0x000320823d5be5c8,0x000ee8fe22b915e6,0x0006518a6bc755b2,0x0000657624d47112}}, + {{0x000f101dace5aca9,0x000181a6a267157a,0x0009c8609c4fdbcf,0x000a654addf340c4,0x00007e49f5379604}, {0x000e790937e2ad5c,0x0007726e17f19be8,0x000bbc0dc846e250,0x0006d57f38007a0b,0x0000f036040711e1}}, + {{0x00000e07442f1d58,0x0000e6e0e3abd6f8,0x000c64047475607d,0x00083d02807f16b7,0x0000858e1e427498}, {0x000120b8231ee10a,0x000ac38a1ece5859,0x000aa73a41b80e7e,0x0003ac2b72525ac6,0x00007cdea3e24442}}, + {{0x000c007f8ae7c38d,0x000b6d7401925ed0,0x000e36db36db07a5,0x000045ee5e9c2a5f,0x00005b9d57b46e95}, {0x00032e78eba20f2f,0x000e81b9a35254ac,0x00098a658ef11ca8,0x000666405e373eff,0x0000fe5a101723eb}}, + {{0x0007b11e51732d26,0x0007c538fc0e5747,0x00039eec5dfd6eb2,0x000c56fc43b0cc3b,0x0000af127792b36c}, {0x000852d06c425aef,0x000b6c221b9b70b0,0x000826d9c6df92f8,0x0009c27c8d4f9ece,0x000059aba7ca4935}}, + {{0x000d8d5da64309d0,0x000691b307045c8e,0x0009b580861a6de5,0x0008a7d6b52f6a2f,0x0000eee419498c95}, {0x0009aab771e4caa3,0x000d48bc21becddd,0x000b504f583965df,0x000290d2affce3b3,0x00000847a21861c8}}, + {{0x0002cf152bfda056,0x00090197b98cd2eb,0x000a1726fe0e4c4e,0x000e3cbd35076cf8,0x0000c06085b8db11}, {0x000c4d74463ba14f,0x00021030238c15c0,0x00027536d9d292f8,0x000c1d2311ee8b37,0x0000eea86f0aeaed}}, + {{0x0008cd366131e2e7,0x000f10fe2682b9d1,0x000160289f31d974,0x00079946e49e0fe4,0x0000c48ec0b78e92}, {0x00011d8d1989aa7f,0x0009fbf926f98181,0x00045474ab34fa0a,0x000755eb5fe2f5a2,0x000080a6ebc2c7ca}}, + {{0x0006054afa05dd8e,0x00011caf119ea7f9,0x00064bb5926dfcf2,0x0002b8020ef2e305,0x0000f4dca5141cb0}, {0x000838a65d306723,0x0004cd657e86cda7,0x000d595c88b08d53,0x0008361c5b439546,0x00009b58725725cb}}, + {{0x00010593de9abe37,0x00012cdc03be8ea6,0x000edce8c4043488,0x0004a12b261245cf,0x00008c318b53f523}, {0x000cf16fde24c99d,0x0004d2c2ff5d510b,0x000960fb42a77cb7,0x00042acc895c2b27,0x000030ce97680eda}}, + {{0x00053931a62cc262,0x000630c0e052fda8,0x000c633f323c69b9,0x000d488227df15bf,0x0000ac788483bae7}, {0x00078f9187d073d8,0x0009167f807d4878,0x0006e6d8f6c2be91,0x000a42f65861d833,0x00008b8974d4e528}}, + {{0x0001177ff57d0517,0x00078b6a19610952,0x000d76ad42ff3803,0x000c178c0aba74a3,0x0000c76480395a7e}, {0x000d75f48879bc89,0x000fc8ce6bc17532,0x000896c16ea7eacb,0x000fed382176b48e,0x0000a30e0b2bc750}}, + {{0x0002c2e421d3aa42,0x000cc84fa840c37e,0x00054e41cf926407,0x000643f8abc03d14,0x00006605ecd5f7af}, {0x00041a6d6a5eabf5,0x0003d16b668e2423,0x0000101021edb84f,0x000d8c8836edb804,0x0000b337ce7e45e1}}, + {{0x0005c77c055dc14a,0x0004e1d89cdfd207,0x000fdcbaf2a0ffa2,0x000866ece815ea6f,0x000034288799b648}, {0x00099cf884655fb3,0x0006064d3e412776,0x0001e1cb7fa5b5bd,0x000d66d1f680c644,0x0000fd61e66e70a7}}, + {{0x000a2dccc78cf662,0x00044fdbff77666b,0x0008d4668b301817,0x000a2a6d4dd0db16,0x000059455d03dab3}, {0x00064c5cde3acec5,0x0004c3adb276f585,0x000303f657714192,0x000f7b027d725d8a,0x00005deb6ca36f38}}, + {{0x000b657b1fa70fbf,0x000ee8073a00fd5b,0x000a02500fa07f50,0x00040d072e3aa7bc,0x000068f895e89757}, {0x00020605cae2a6aa,0x0007628748423011,0x000e47bd301bd721,0x0004f59d4238917c,0x000066663c218954}}, + {{0x00005d73272d8383,0x0009ca6295c5864d,0x0002fda32e22924f,0x0005445189593f6c,0x000030d7189e184b}, {0x000a62cbde1f7140,0x0004e5cb1a6379ef,0x0001c833235771c9,0x0008542f4826b864,0x00000a894fbc8cee}}, + {{0x000a39b36194d408,0x0004f7612601b4b9,0x000cf2f58e857a7c,0x00048774209dd24e,0x00002b9e66dda033}, {0x0006934e4e8b9dd4,0x000d642377d7c1e3,0x0003ae43bd2372c9,0x000f6f11dc94c70e,0x0000c57761e44474}}, + {{0x000cd0a1058a3184,0x000538053a9adcda,0x000c68de2369cf3f,0x000d9f86c3de5031,0x0000653a5767c4b6}, {0x000dd5aaa4e5c975,0x000167ab3c741688,0x00065c2835be80aa,0x00009120cefe7cbc,0x00007f95f1356867}}, + {{0x00014e24415503b6,0x0005ecbb17e9a391,0x000dec966c08ff7c,0x000f62beff674dd7,0x0000d4690afb3376}, {0x000e32eea74237b0,0x000ecd57508eff6f,0x000cc40fec436d17,0x000b4415aa28e1ed,0x0000d769c04581bb}}, + {{0x000b6de34eaacda9,0x00079ba0f1dec240,0x000438e55d9e116e,0x0002d73be45ec779,0x00001787c9e26f75}, {0x000532bf129ac2fd,0x00078a36e22c897f,0x0009fb8f3d307b7c,0x000b27c194067574,0x000014f95d0e57fd}}, + {{0x000d0296ae550430,0x000f44a87de1fe51,0x000e4fee28931e98,0x000d92e57f1cc609,0x0000d063b674e072}, {0x00098b9ed0e4316a,0x000a906aca4670a9,0x000da97c7e74a736,0x000d934cf0fbf24f,0x000040f65cbde178}}, + {{0x000360416df4285e,0x000af0c56ae21625,0x000c5cfc3b0c9bab,0x00005593032b19cf,0x0000497e5c3e9752}, {0x0006bb4164bda960,0x0009a0b74da11209,0x0003826ba1ee4241,0x0006608fc3624340,0x0000c8f0069dc09e}}, + {{0x000e981c27253c98,0x000b12b36a458667,0x000b7bb4605a6aef,0x00027b262c4b369c,0x0000394f37591f70}, {0x000c79c5f109d0fe,0x00057b8cc60a747b,0x000f09e68cad88a7,0x000eaba0c5a66b58,0x0000753d452d6127}}, + {{0x00074a15b0ec6f5e,0x00037289b2b8c44b,0x000d6fc7347989fe,0x0000aa945f848458,0x0000c362a70d61c7}, {0x00098a7b3a8ad418,0x000ffb63db51070c,0x0004c35f473a20fb,0x000dca6d2c2173f4,0x0000a56149e1acc9}}, + {{0x00078819ac6e0f4f,0x000eb413b5ed98f1,0x00000b0fd360fdea,0x0002d21625b8f4a3,0x00001f4d76b4b322}, {0x0005109587f76b89,0x000c9317fdb59d6f,0x00068b0958b4ee08,0x0009b8f8089bb78c,0x00005570e9ae808d}}, + {{0x000c36f35d33ae72,0x000330bb5a94a395,0x000afe84b200ea12,0x00076a00c789bd0b,0x000043ef52d29192}, {0x000c577e23ae233d,0x000ed460d1ec3934,0x000fa76a4b93807a,0x000490e72a53b1f8,0x00008914cb193ca4}}, + {{0x00084943fb42622f,0x000b600907d52e12,0x00095ec633b2700a,0x000fbd0370fb091a,0x00008f30be321b6d}, {0x000f8d269e55f156,0x00016c1323e9f2b2,0x000e5eef61fead85,0x00007e9a366010d9,0x00004d487b143161}}, + {{0x0006b86d23ddc820,0x000c7e0143f04c07,0x0007af2c503fd344,0x000a4fa95362ff31,0x0000add3db7e18b7}, {0x0003e3f8260e01bc,0x000494a1cc919c67,0x000f2e433fbeb49e,0x0001ead1351bf292,0x0000755e7ed45114}}, + {{0x0005139296077453,0x0000726f2b28c9a9,0x000c6f9dd0ca0742,0x000fc09b2790e74b,0x000045bbb58ddcaf}, {0x000a38cbe0f27a29,0x000bd41fcb56c65e,0x000e2c75767c24d7,0x000c489c25f0a7a9,0x00003f5cdb0a6f16}}, + {{0x000a9d7c5ee30a1e,0x0004d909b7292ca5,0x000deff48d159363,0x0000c2a04ce9f3da,0x0000c464752907c3}, {0x0005ff39e49af6a5,0x000a1f3d01bc89d6,0x000ced843f2d6238,0x000fd7c095561e0b,0x00001789e1318a13}}, + {{0x000f929763231dff,0x000cf7cbddefd633,0x000265da846df9f7,0x0006d111c889c0cb,0x0000ce1ad119f433}, {0x0000df6fc6a0a7e8,0x0007eda425dc8d11,0x00034aabedd431b9,0x0007fc4dc4aeab18,0x00004deb1250439b}}, + {{0x000f1693c2a59987,0x00040947190d8796,0x0005970149b9247b,0x0006ede5b9d9a511,0x0000e9dd70deb156}, {0x00078f7cbcd5e64a,0x0006fbd4c03294ad,0x000c222ae0359ac1,0x0008119b11baaf7c,0x00006a6e2855a78e}}, + {{0x000053f24cea1a04,0x0009f36214918392,0x000399ee9c97bce4,0x000ad13eb1db3435,0x000073f78f02ce81}, {0x0002fe0f63d3d0d4,0x00006fab62fc41d7,0x000158383e620b88,0x000f6c52096bc993,0x00001a21357cf896}}, + {{0x000e2fac7dcfcabd,0x000dc546e0071b5e,0x000b02e07650acfd,0x00003cf081b749b1,0x0000a9e41a1c9eca}, {0x000a727175a54ab2,0x0000ca5d8d10013b,0x000fd96a9ca0cd19,0x00094065ea52c095,0x0000c591b9fdc5c3}}, + {{0x000d4e42bad4d5f9,0x00006ef0059b6fb4,0x000122294fa4c359,0x0001d0da10218af5,0x0000a78a81b38575}, {0x0000579a98e84e7f,0x000f5997e5b504f2,0x00021e1e4fe1242b,0x00039cf77a273bca,0x0000cc8b1f084119}}, + {{0x000a30292d0487a1,0x000c194b91fee20e,0x0006b0e8f1442dbe,0x0003180f7a4afebb,0x0000700ef747889c}, {0x000ffc370f1fc62b,0x0005b9c79ccaf5bb,0x000f6340d3b31d4b,0x00010a38bc2aaba7,0x00000b08ab55725e}}, + {{0x0005701ae3400501,0x00060cf0c56944f0,0x000e19a51ba4b301,0x00052e4aa29f83fb,0x0000b9ed428c71d7}, {0x000e54eeb4819f5f,0x000cae18b75b1666,0x000e27b0b616cdfe,0x000e4c212ed5be3e,0x0000bf2831a34c7d}}, + {{0x000ec85e0e60d843,0x000fedb7ee78d685,0x0003c4d6e68037e2,0x000a6a2b65bdcd00,0x00003e7363ac3e29}, {0x0003a6108d0756c9,0x000b9faf134b995b,0x000337823d727f85,0x0008b46ac6edf71d,0x00009b9aa509439b}}, + {{0x000b104e2b4e075d,0x0004737c4926722e,0x000a9b82d4998729,0x0006f4e1e4c0e446,0x00000cb319827a00}, {0x0000f7dd7808c569,0x000ec1f89772f3de,0x000bd31aab5c54d8,0x000caac00a114aad,0x0000afaaaa6b95f6}}, + {{0x0005e2104cf667af,0x000aad3935d79470,0x00009267cfc2a811,0x00053a660b02806d,0x000019ed11ae780e}, {0x0007c09067b6269c,0x00029caef599f022,0x000efeebc967b853,0x000ae5555b924368,0x0000d6d34f68497b}}, + {{0x000d5d36cceb3707,0x0009378d7bf91dd8,0x000b67a622aeac57,0x000f66ed65017d70,0x00000c8e44f87c53}, {0x000095086a34d092,0x0006c7134907d1fc,0x000fdd315e0fca25,0x0009adc24fa29c80,0x0000c4acd03f8749}}, + {{0x00075173b5a9ba6e,0x000532e51a51baaf,0x000154897b9cbe1f,0x000c9ff88edae35e,0x00004309c3d57b66}, {0x0005805f67f37466,0x000a436401fff555,0x000499a5385fc37b,0x00055b7f86e2cad9,0x0000270b2a44cbc9}}, + {{0x00064f5974ad33b0,0x0007fe7b2df1afae,0x000b03f7304d8597,0x00040a2a3db3ff4a,0x0000b87878a87027}, {0x0003f015a0617323,0x000e732a19016d26,0x000155018c25430c,0x00078ec7ebab3ddb,0x0000a86f69393a9b}}, + {{0x000e368da9f3804c,0x000de164349c349a,0x00062baa5470f07f,0x000df3152f4cc985,0x000074a9e86eb290}, {0x000aa3543471a24c,0x000df8194511d3a1,0x000dcd44d239446b,0x00082cfec2dd0081,0x0000a3d7f10842ac}}, + {{0x000b085fdaf45207,0x000fd549daf21f3d,0x000ad5c42bb6d3e7,0x00051185969d8a19,0x0000052b13e4bfd1}, {0x0000d1b682b90604,0x00036c34452c1189,0x0003805b4a71d388,0x00023e6438055b78,0x000032412778725b}}, + {{0x000f96e4901bbed5,0x0000a432a2bbf20c,0x000a9cd7d6419c71,0x00024907a0fbb9df,0x000089111e450daa}, {0x0009a337b60554e1,0x0007dde283a41980,0x0003bfd35ea5f888,0x000a531d71380250,0x000051bb0af685d2}}, + {{0x0008f7443b30ca81,0x000ac993458340b0,0x0001110ade10b5bb,0x0006c5d8a546d6b5,0x0000dd50e6638e0b}, {0x0009d54cff2b821f,0x000c57281760292e,0x00024d6e33882555,0x000da0234838f837,0x00002c679e112ddc}}, + {{0x00088156d2a57687,0x0001ac1e7e2d40ee,0x0004ff4437f227bd,0x00054ad87ba134d0,0x00006e2ff3e3614e}, {0x0008d6fa3177ec75,0x0000d328fff536b8,0x000ba158ebf731d5,0x000188258caea249,0x0000ab8ff4c52938}}, + {{0x000605635edc56d2,0x00095e940d7933e1,0x000866dcb5a69d34,0x000def4c4fd00103,0x00000a38f576893c}, {0x000e790fac3a15b2,0x000e5a4f8e6bfbf3,0x0003aca866ed7ea2,0x0003f78663eb4fbc,0x00002061ea5280d5}}, + {{0x000dfe6f546783f8,0x0009da0a641e2480,0x000de8965d38bc6d,0x0005cf7b093cd12e,0x00009654db52cb45}, {0x000bf9a26e1adee2,0x0004173294d4413c,0x0008083fe291f376,0x000340e079725764,0x00005f504d3408cc}}, + {{0x0008e5ec3a0ee43c,0x0009a79898ff635a,0x000c63d5670aaebc,0x000cffdee9f5475d,0x0000e987967bfb34}, {0x0006b195e26310aa,0x0003982a8ca8f9f8,0x000352fe49e43548,0x000570853bcb81c2,0x00004eac8b0e474b}}, + {{0x0007512c1ad8cf84,0x000e59e0b697c1b9,0x000e85df0193b4e9,0x000afd539d271601,0x0000fb265b40d44e}, {0x0007dcde51e1ae29,0x000653d8b096321e,0x0006049988e3a8ca,0x000aa6fde46cb052,0x00001099ad8c9072}}, + {{0x000f91c93aa96b8d,0x000aafca2e132617,0x0003287230fc8716,0x000521d7106f5e95,0x00001c9c40bf62e6}, {0x000fe8642b7c094a,0x000c7543c021b9ba,0x000befd5d1873439,0x000aff41baa5de5c,0x0000363fc5ef21e8}}, + {{0x000320df862eaacc,0x000262c647dcefe6,0x00046d42814419c6,0x000f8e4e06707c4e,0x0000b6c83500a178}, {0x0003a45d30f917c7,0x00092879afee0f99,0x000500063d4c4b04,0x00060546142a1e70,0x0000c9b41c415d9d}}, + {{0x000fc2f2f8ba2c73,0x000f4c67aa28bc00,0x0007869720966eb2,0x000b9fe3f7b5165a,0x0000bfb7557ba2fb}, {0x0004f235a2b96204,0x00072faf46be131c,0x000172323bff3ed2,0x0002465b4473d17e,0x000021e8878739f6}}, + {{0x000587a25a416322,0x0004835b6c930fa8,0x000ebb8dbc081412,0x00029c0b18a9f559,0x000064e335796edb}, {0x0005ccdc87c51e26,0x000af01e6214af24,0x0003882ce16b3015,0x000e045b31c5600a,0x0000961bb955ec11}}, + {{0x0005b8deff7a3a0d,0x0007e1df73263b82,0x000604a1fbec3373,0x00049898ad747c99,0x0000154c9356a3bd}, {0x000506f1cc7a906c,0x0001ac560e8fac33,0x0003e394473bb539,0x000433a428fcbe26,0x000011828d5dc387}}, + {{0x0004be13e4b12ff9,0x00089d88667c3cd0,0x0008120cfc3aad9f,0x000532352ddcf824,0x000085a892eba389}, {0x000b21b3bb85fa06,0x00002dfc6269fbb4,0x000e2aceaf95375e,0x000d1f9b4fb06c7e,0x0000785426e909c4}}, + {{0x00017c8d8ceb147d,0x000de70a5554659b,0x0006bc6349b649ee,0x00032e9b7fa0b5ac,0x000099fe2c7ed6e7}, {0x000e7628d3abba2e,0x0006c797b79930e6,0x00096464d18fee6e,0x000e117c9d360dc6,0x00003baeb4907bfd}}, + {{0x000db47f23206d55,0x000fcd2601522bf5,0x0008ff89a2f6d341,0x000457c7b876533f,0x0000157c30c878fa}, {0x000c5c52d4fb936f,0x000bf6518cdc7517,0x000847a64ef22f7a,0x000a88eeb483e6bf,0x0000508455982e0f}}, +}, +{/* digit=33 [{1,2,3,..,}]*([2^231]*G) */ + {{0x00059d8df7304d44,0x000bbf210e8eab96,0x0003fbd60b71bcf1,0x0004de69a2438bd7,0x0000595cd1f9d11b}, {0x000329a4835859dc,0x000cbdbb6e569c0d,0x000928a4e4a0f0d2,0x00015406038e5edf,0x000094296224f5ad}}, + {{0x0003462f23f2d925,0x000d10b940789121,0x0006cde206cab71b,0x0004bc1bdd0a6317,0x00004c9b20d3e4d5}, {0x000d8aa9f2ac02f8,0x0006a06eedb03cd2,0x00008643403f8e61,0x000db947f68e1693,0x000031469c612dd3}}, + {{0x000df248f9813540,0x000c3588a2598521,0x000a0992c587e23e,0x000407cbedf281d7,0x00006930a5538961}, {0x0000debbe5bbe21a,0x00048491817f0932,0x000065160a7ffa5b,0x0002a946c8b4d909,0x0000c4f39939ff6d}}, + {{0x000a1583ae9c1bde,0x0008037ce2407aa7,0x000ab38b4e0af6d9,0x0008ca054342d928,0x00008b75007ea1c9}, {0x00086afe02358f2b,0x00063a921228efce,0x0001c67fc31b8b85,0x000d58552a19120a,0x00004069ea593aea}}, + {{0x000d6e27fa03cb3d,0x000a3fdd7d883232,0x000cbfc5ddb938e5,0x00080e34c1d2cd2c,0x00002f45c137f3a5}, {0x00020b57883e6142,0x00089e7c5f265926,0x00067e1e35fd27e6,0x000aaef39e45a915,0x0000cc71d2d64d8a}}, + {{0x00090cde36d07576,0x000179a293824a90,0x000b48ddff722d7b,0x000f439b7fb04c04,0x000028ad2a84be16}, {0x000bfb520226040e,0x00007104b6c4cd3f,0x00003c1886c34ecb,0x000aaf50c0754ec9,0x0000c336b090d23c}}, + {{0x00062a21e206ee56,0x00002c49a633473d,0x000f6b2c3f1e2748,0x0006ea27ab956ce9,0x00001830b48c2b60}, {0x0006846e78e815f7,0x000edc02082a67cd,0x0002ec365fe40139,0x0006aae2bbbfcb95,0x00004c11642db983}}, + {{0x000439e558df0194,0x000a6c712b279f51,0x000185a24230da4b,0x000f50118919e355,0x0000dcefcddc4b78}, {0x0000fb2a47d4c5ab,0x000f030e009ea7d9,0x000eed27355ac9ab,0x000faf4d2fc35974,0x000072d824d8bea8}}, + {{0x0001a744513e2cae,0x000158240b2cce72,0x000baa4500b41861,0x000c2425199968d5,0x0000b1757ee0b0e8}, {0x0003e283dfac6d55,0x000df8a237f56ebc,0x000f61499b2431e2,0x00036adacb5e2352,0x0000558a2a8306c9}}, + {{0x000f923cbb13d1b0,0x00025bfb9bfed213,0x0001144a998799f4,0x0005ee1ae8ddc970,0x0000b8b3bb64c559}, {0x000ef2e3ecebb211,0x000b2671f9a70ea9,0x0006f1d1f17cb6c4,0x00027637ef464f72,0x000071b94847943a}}, + {{0x000ae2d7ef0329c3,0x000261c4402a51a4,0x000d45bbc0850922,0x00085134a61d35af,0x00008f096fe6035a}, {0x0008b74a1dec0270,0x00074fc7dcbac746,0x000a06353e8cf10e,0x000d66ea35ff40f4,0x0000b4c0dfa8b77d}}, + {{0x0008552de7e5c194,0x000981c0256c779b,0x000d4743dfab2860,0x00093b24f58eeeab,0x0000e8ef838bb6cc}, {0x0000d264cb1bf3d1,0x000963dedf61ee65,0x000b70ced4c1f9d0,0x000e1e9ef7c9d7bf,0x0000ec0507e2641d}}, + {{0x0005cc7cde450794,0x000a116ac9e4cd7e,0x00070315cde173c9,0x0008fb117a8494c1,0x000038fd905d1d8e}, {0x000c506c7d9630b4,0x000bb47d4d755145,0x0009a80e86457a87,0x000abe931646bf0d,0x000053add2c0ef3a}}, + {{0x0001109a607419d5,0x00026b6bca80c994,0x000c431f3faa71e6,0x000479e4158c1307,0x000094abebce92bc}, {0x000a691eb78399f1,0x00052f42cba46dfe,0x0007c04f048aafb3,0x00091addcd65af07,0x0000a29a366f8844}}, + {{0x00040e51c21f2bf8,0x000c25057aee023a,0x000ab072ef99a513,0x000bcf23fe7e25bc,0x0000568d2e1c0e32}, {0x00094ebd3f69d9f8,0x000287affab19045,0x000e330f4181a973,0x000fc164d68d76b6,0x00007a6dafc475a7}}, + {{0x000b2b5ef7d92893,0x0007e97f015a549d,0x0000493b62480d4a,0x00033131d5590bc4,0x0000a55b52e9f780}, {0x0008115309eadb09,0x000a02e5c62540eb,0x0006a3d5adea7de5,0x000d60d4d631f0cc,0x0000d5e9d7d23e8d}}, + {{0x000bef5206d3ffce,0x00029d808bd4f297,0x0004cf5ba23d5e03,0x000a896a4f6912d2,0x00004d8163be9cda}, {0x000e9efd3082e8e5,0x000bb192f3600e0d,0x0008eee0a4fe1246,0x00091acf9001504b,0x0000219da8241da3}}, + {{0x000a5c1f7ea25aaa,0x000f5bb07d5f7bf6,0x000e78671d165e6b,0x0002194353936189,0x00003fcac89cbac4}, {0x0006fd4f0baa8abc,0x000122c1c2e5dfab,0x000d858495a4adac,0x000180acd75e3140,0x0000e263fead9b39}}, + {{0x00003d307032c722,0x000e590968c8cb68,0x000e978f07f40d5c,0x00051c86de86bddc,0x00005547c4f568f7}, {0x00085fd65fb2a9eb,0x000e6eb9179cb1e6,0x000504442ce69336,0x00006b015d1c2712,0x00007df465d6911a}}, + {{0x00004a3315980cd1,0x0002ea3bebf7b8d8,0x00053c504693bc49,0x0004a22578aeee22,0x000058de498dd247}, {0x000f5c7cfda83685,0x000328d7177e1331,0x000c1e46ed2d7bbb,0x000be88f61133af3,0x0000836ce7e230e7}}, + {{0x0004f1994f834cbc,0x0003829ed7828308,0x000e58243d35653d,0x00022ce542f16f59,0x00002b52f65c470a}, {0x000221b18f23d962,0x000c1f5252b4e3b6,0x000d61402cb05aba,0x0003e4aa00938b87,0x0000f186cdd61193}}, + {{0x000ece59a29a5c5b,0x00068b6c8402e042,0x000d92684b19b3c0,0x000372197667c719,0x000056246239bc66}, {0x0006e653c04fa024,0x000c4eaa39aa0cb9,0x000a1633f83a7176,0x000f72e033561dea,0x00005a9d0868533d}}, + {{0x0002c1d3dc090bc7,0x000f3a59c167e054,0x000e7fc4d82c996e,0x000b7973f735e80e,0x0000b179393ec35d}, {0x0009e25f8c5dbfdc,0x000d5f327b04b641,0x0008dfca84d9d7a1,0x000669d79f6f9b29,0x00007c5dff24de93}}, + {{0x000588d04c82bdd5,0x0004a8319dfd1b7a,0x000eb95806800553,0x000a818e8a55b5d8,0x0000ea886dadd5bc}, {0x0000a01252a0b4d7,0x000dc5eaa0a1e853,0x000e995631bffb4f,0x000d86bad828b1d8,0x0000de96ef605f9c}}, + {{0x0002d0cd77d970c2,0x0003b33ef9cb4abb,0x000211fe903cfb93,0x0001c690547c018b,0x0000fe64809c56ed}, {0x0005624c2ac98ccf,0x000f2a393e33cb7d,0x0006605212a1372b,0x0003e8d8d1ec1c29,0x00003d31b05a37ac}}, + {{0x000e9df5ece6e7ce,0x000e2facfb55a29a,0x000a233a50603ac8,0x0000b7efe85b7add,0x000061891a09d75f}, {0x000a3d299bf1603d,0x00092184255af555,0x0009a3e021f43afc,0x000a390cdaf34131,0x00003b117efd3903}}, + {{0x000da1365d1d131c,0x0007037ad03ee095,0x0002cd8dd86f1636,0x0000e59f37389e46,0x0000103fa05967a6}, {0x0004344f4b478f01,0x0008d117c98d57c3,0x0001fc12ece91edd,0x000ccaf01777b023,0x00001ae47f2c207b}}, + {{0x000cf8d20f8a2425,0x000da22e1ad8d983,0x000c4feb37aff5b1,0x0003e118fd11d07f,0x0000d53ae9100f1c}, {0x0007905ec0418032,0x0006f440488850fb,0x000628d8f85e3c97,0x00032bee67faedac,0x0000e86515086685}}, + {{0x000aaa46a67a6b02,0x0005925cec4115ac,0x000c6701ef4cdee2,0x0003d829ee565ae4,0x0000a04ca671c7d6}, {0x0005018ef0543fbf,0x0004e1b0d81deb10,0x00015d333f709a4f,0x0000aa6b906ee629,0x00004a8741386f1f}}, + {{0x0002fa74d82f4c2b,0x000fb804efb3b6b8,0x000c3425e90725a5,0x00043e0c82ec46ad,0x00007b80581d7878}, {0x000d91cdd1fc74cd,0x000b1783a6c4df46,0x00004cbbadc1c62c,0x00076389d1b9f31a,0x000087f6f7365e40}}, + {{0x000cfc1317f4a765,0x000b41036bce02b4,0x000e72a568d2703e,0x000b0f48206cc6a5,0x00007be9ed21f53f}, {0x0004571ef0b17acc,0x000e19181b380937,0x000935d0e74b2655,0x00093608f80ea889,0x00000d9e94351529}}, + {{0x00060411e84e0e5b,0x0002fea34c931968,0x00073a732a5db84d,0x0007c049d5bb1970,0x00008d2fe571bcfd}, {0x0005f36f3eb82fab,0x000c4dff8b584577,0x00074c1108cb20cc,0x0008996659b65f83,0x00008b4a422e30c7}}, + {{0x000c3ea6fe8208b7,0x0003b86e78fe75e3,0x000d93a1abd74b9e,0x000aad9be2e81bd7,0x0000ed06e284d0a5}, {0x0005a586be8b800c,0x00011846db28721f,0x000e88ed3428299d,0x000e10d5cb8e6b5b,0x00003186b23dc034}}, + {{0x0002c9e8977d99b6,0x000123f531e7a631,0x000d3b1d4be94433,0x000b732232c0c218,0x000017aae8c41247}, {0x0003fc4282aec3b3,0x000fc7b8f8234015,0x00004f94cc6063d2,0x00034638f10e5833,0x00001efae751e676}}, + {{0x0006c6d40a9b97c5,0x0002ff666256badb,0x00084b2e314702c6,0x000a408eb954f151,0x0000184a526e4b6c}, {0x0005337003c32ea4,0x000ce05974c7fff0,0x0000dd71a5aa374d,0x0007ec5a7638544b,0x000059cd2801eb94}}, + {{0x0008161459c2b92c,0x0007b5ee8ef5a6e2,0x000b063102f020fa,0x00052ff132ec2d30,0x00003e1589a7c6a4}, {0x00053feaa3f451a6,0x000362d9acacdc5f,0x00027e58b3a3c7f2,0x00099ecec2f8926b,0x00008466ee837427}}, + {{0x0004dd41fa266138,0x000b3dc29d639832,0x00012d657a2dc6da,0x000d1579675faad7,0x000013994bea1fd8}, {0x000b722fd4f75534,0x000bb3a36b205ccb,0x000559df55135ff8,0x000f3004be28af69,0x00000b65beddd41b}}, + {{0x000f2a43734e5205,0x0002d09bdcbad98b,0x000945b355e3abbe,0x0004aa27c76553bc,0x0000331c09416ef1}, {0x000fe2976b60c80e,0x000a9ace16f8518f,0x0002b97842285593,0x0001b5cb1f64ccbe,0x00008f2c0da8b242}}, + {{0x0007174c1df065c4,0x000b1f6578fa617d,0x0003b54a8afeeb5a,0x000ce2d6ff132926,0x00005c558090990d}, {0x000b6c0ecc8c1778,0x0004d982ecaa42ea,0x00007ef8e799ea9b,0x000c2c765da244b6,0x0000ab226ceb2a3f}}, + {{0x00041e57ea973dc8,0x000fa0888f2e7457,0x000fd9cf15c00ca6,0x000871fcdce3cf45,0x0000a741ef1d507f}, {0x0001c2f196b4cec3,0x0003997ea61847c5,0x000b18a2b70d08e4,0x000514630da15c15,0x00003b6c6785f610}}, + {{0x000e4f807ac97946,0x00005a06cb79c662,0x000d954e51eccf05,0x0001c2bff08623e7,0x0000ef2c5fb84cf7}, {0x00063d2679784532,0x0005fd654af8b2c0,0x000bdaa37a0cf379,0x0007e05cb242ea7e,0x000006e0b10d8674}}, + {{0x000ae5fd5ecfefc4,0x000882bff8fc481d,0x00032459607084fd,0x0000364040a01aea,0x0000c64698114de4}, {0x000ab4ed65abfc39,0x000e83541ec79eb8,0x000695012e01cb91,0x0009ebff029adbfd,0x0000ae28483cc756}}, + {{0x0004c9ea66d80a18,0x0003f5f5f911a561,0x000ba4fc1680a3e4,0x0001c08c07b14dce,0x000091c285c21307}, {0x0007ceb799ece3c0,0x000941e07e27cac6,0x000e4312329b910a,0x000cbe66bdb409f2,0x00006f8b1377ac9e}}, + {{0x000fafd385470908,0x000f05e3415d5981,0x000e31b2719ab8b9,0x000b427c28c194c7,0x000043be0aaefbcb}, {0x000ed43a6db836ca,0x000361a45c05f3b1,0x000c1a3772a1330e,0x000e32af19f3c595,0x000085f39d0e4b5e}}, + {{0x0008e6d4ae528342,0x00095423dcb03da1,0x000374aef5a403b3,0x0001119b555e0af2,0x0000ad599c43e8ca}, {0x0002fb9014b3bf81,0x0004e66d50071b3a,0x0003401027309268,0x0004ddf79f1426c4,0x0000827cf819fddf}}, + {{0x00005f6f10ff9276,0x0000c3739fc6c836,0x000c1c2ccd387145,0x000ac50d163450ca,0x0000b52129702ec1}, {0x000c4f96e3cb4a55,0x0001278abff70606,0x0008e3a45e47d3f4,0x00015ff25a8d5ebe,0x00003ea9e97f6102}}, + {{0x000106e39cbb688c,0x000233386d32477a,0x000b9b421532401d,0x00033ece564f64b1,0x0000a9b838941dad}, {0x0002b4e2093913eb,0x0001b9bc8112b142,0x000e7b2c7533d2f9,0x0007c58fa017beeb,0x00002767c4b7af19}}, + {{0x000ff87aedbae9f1,0x000926880a54c925,0x0004d0e717daf0eb,0x000cf58284ddf59c,0x0000581cf93416f8}, {0x000a8873ac1f4527,0x00098b6aeffe3eec,0x000fb8dc3b417fce,0x00040035918046ee,0x00003d318ac72209}}, + {{0x000400f728693e5f,0x000a439927ede800,0x000ea9910e87d814,0x000b68a3e94d3b57,0x0000f8a35b71245f}, {0x00053d77f200d34a,0x00076f653ce10438,0x000a06379470f1e6,0x000c28e1ac05bd59,0x000014052c2a3930}}, + {{0x000fab526bc27979,0x000609f167716b72,0x0003e48d113670d1,0x000677701700521e,0x000078fe40247adf}, {0x000fb92d41c5dd45,0x000777b27da555ec,0x0003fb6065ff8e24,0x000a3c9751827201,0x0000768d7e57f547}}, + {{0x000eaa360017a5ff,0x0003ac64ce9bbb24,0x0003dde076b18e6e,0x0007e9d225c65510,0x0000c3672af6592f}, {0x000ad77d06283a1a,0x000044d59d999606,0x00040e7c2542fc65,0x000f550bb57c492a,0x0000c948f1448db9}}, + {{0x0009682b04465c31,0x000a5468bd156d4c,0x000318d7ee3d062f,0x000c95951729ac5f,0x0000fc87df6aeb6f}, {0x00046a80591f6528,0x0006d89621aa63d1,0x00031348ca861b8f,0x0006d9d9f5f15ace,0x0000f663391c40da}}, + {{0x00078acb591ffa38,0x0004ccdfebcecfa7,0x0004ea6b3027ca9c,0x0002543e8e05a544,0x0000aab4e6a278d8}, {0x000f04fb474d6b85,0x0003b45b38552437,0x00047ecaa6597ffd,0x000bfc6b0aea4eca,0x000068aae83d5c7e}}, + {{0x0006e64c73b23834,0x0007917d87620e96,0x000a05dab49eb344,0x0002369e1078218d,0x000043d8baa416b7}, {0x00063a5ea7610d6e,0x0004ee1ca979163b,0x000baa132e47e418,0x000b63ce648b6580,0x0000bf53de2ee0d5}}, + {{0x000fcb4d3c8c1cab,0x0002ad04b3098d3b,0x000e7d3950d914ef,0x0000e7a5ef64153d,0x0000de1666fd6b85}, {0x000ca6ed449ab198,0x0002689a2672dbe1,0x000cb7a538902b32,0x0003ff31674b7eda,0x0000e9faf6f75252}}, + {{0x00035da9a85788bc,0x000dfd0626d46ba5,0x00073dc64d21f03a,0x00097d499f8c47e8,0x0000da8564dc18ec}, {0x0007a5cde92c68ca,0x0000d3323cc43e8d,0x00080ff7c78e035a,0x000da99ef26275f8,0x00004ee3dffc73ee}}, + {{0x0003507af4e18f85,0x0004b672f3285882,0x0009d3186967ec9b,0x00039c4ded19d955,0x0000e2ab3debcdce}, {0x0006e4d11c226dff,0x000297723014abad,0x000885719f9783f4,0x000dbeaa49a0cf1a,0x0000c0c1a5b80da9}}, + {{0x000ec49571d92ac3,0x000e1692517f8bba,0x0004ea4af569e85f,0x0005ad5333b014a1,0x00002f2a62f42e5c}, {0x000ce3a06d89b85d,0x00095ff77a0898c2,0x000f795a2b90741a,0x0001985530defc01,0x00006e5ba0c54b3c}}, + {{0x000845112e4c9366,0x000d5d0be17b7d8e,0x000262bc9ae419f7,0x0002bd4583fc8c22,0x0000b842ac7f1bfe}, {0x000f4e9440d68277,0x000e7f81fb1433ce,0x0004fbb925f69f4d,0x000158816cf6f623,0x00006ae3fc449e7e}}, + {{0x000f6c2e9740b335,0x000cf962d6a14e89,0x000d10d15677bc85,0x0001cd1c6d8a7f68,0x0000f9a72245257b}, {0x000b9164ad859617,0x00077657ab4a7096,0x000461d7e5f8c47f,0x000ee26e57d7d0f7,0x0000eb6094df0ce5}}, + {{0x0001dfd341905477,0x0003805dd1500b1e,0x000df44e68a394f4,0x0007189a9eb24d97,0x00008ca06bff7675}, {0x00034626ffeec228,0x0009b6cdd8fb6f0b,0x00005be479d91bce,0x0000e32c83363ca1,0x00001ba76c186971}}, + {{0x00024cb28c682c67,0x00081612575b3d1b,0x000e66e9827f2522,0x0001fe4587c779e8,0x0000b0c03e9b05eb}, {0x000d03015b548e76,0x000fd8b36af7fdf0,0x000310c40a8be76d,0x000aebecdab04a4f,0x0000287223f547ec}}, + {{0x00060558b399320d,0x0005f01e4646678e,0x000261a5e61fe3fa,0x000449f482866b03,0x0000fcf45b92c2f2}, {0x0009a512f684b432,0x0004a7220a668fab,0x000afa58ff796c65,0x0000ddfd90707ef5,0x0000c421d976fdbe}}, + {{0x000cda3af2ebc2fd,0x000cfb4efe24c4f4,0x000cd10b1a0af843,0x000e0383b857c19c,0x0000dc9d1ec614d3}, {0x000c8bb62771deb1,0x000a81c5aa817bde,0x0002391ae829277a,0x0004ca6af18dd683,0x0000740f316d71a8}}, +}, +{/* digit=34 [{1,2,3,..,}]*([2^238]*G) */ + {{0x000e99aeeaf8c495,0x000d1e24d7288928,0x0002b156cee7aa73,0x000a1cfc5007c2e7,0x0000fcf57c63d408}, {0x0009e39b6057604e,0x0000e2868bbf9f71,0x000103e2d7d343c0,0x000ea14cca254b7e,0x00006eb38aad131b}}, + {{0x000624f8be762b49,0x0000758e3413b33e,0x000d805fa2a9ee4d,0x000fd7068e636967,0x0000848949c0db8b}, {0x000d7e5d23a84178,0x000d73e29da55308,0x000ee471f892f3b1,0x000089495c139e3d,0x0000631594e5757e}}, + {{0x0002a3cde918dcce,0x000346fdcf4be0c8,0x000cb1b2d2e7b599,0x000e06a2c5024932,0x0000a613a9e5657a}, {0x0005f6cf1fdc9f70,0x0008879fe682c2eb,0x0001cbc7fb6eae8b,0x0000e6253dfee059,0x000000da7133e129}}, + {{0x000e2ea1f095615b,0x000664e68c331083,0x0008818be0a28ad7,0x0000ccbbfc02523d,0x0000585113ba3585}, {0x0005f0b30df8aa1c,0x000b8ab7e3ac7d93,0x0002f00cbaddda07,0x000f6bd2c3429955,0x000033ed1dee909d}}, + {{0x000195d80e877662,0x00087ddf4ac022c2,0x000e749349e99e6d,0x000240e9642e4e65,0x0000610ffa31f1ff}, {0x00047d4751c8159a,0x00050f3a93634d1d,0x000477c33697b498,0x000ff26318ca4687,0x000090cb5663441e}}, + {{0x000384836f024cb1,0x00072601616858bb,0x0007e07f185be1f7,0x000f025c59587cdc,0x000091be071bf1d8}, {0x0009fa5cca5e55cb,0x000c47d04eacbf16,0x0007d05db3864ba3,0x000e5ce15e367f8d,0x000048a876e56549}}, + {{0x000c656580e40a2f,0x000b828068bcef89,0x0007990c9f194ed8,0x00064884528045a4,0x000053fc7d84e1a4}, {0x000ae9b78593e7d5,0x0002f1db65d7bec5,0x000a3d39b2cac4ee,0x0003ef58c1eb2404,0x00003b7d63453f8f}}, + {{0x0000d483e07113c9,0x0008ed8b63ae2dc4,0x000684c2b6e4a5d3,0x00026bc582a94b79,0x000032b33d4f22da}, {0x000f6510dbbf08dd,0x000894c23a52f534,0x0005bdc9b211d07c,0x0005573eeece0fee,0x0000f178169c7015}}, + {{0x00046350a712229b,0x000759273f8cd429,0x00013bc8393cbe44,0x00078b50b095ef8f,0x0000b74197337989}, {0x00009a256dbe6e72,0x00063a5d39ec9d73,0x0001f9a31e578ec5,0x000eb41961151b85,0x0000da7715e05709}}, + {{0x000301753dfabf0f,0x0007c8e39259867f,0x0005d9958728d207,0x000be06c75a0cd81,0x000084867a706603}, {0x000b13d70e35b1c7,0x0007a9b03e2cc865,0x0001f31210241446,0x000a7c746041daac,0x0000c9017addf028}}, + {{0x0006de90a482873d,0x0000e77e54d4abc9,0x0007d88e74265d6b,0x000de298c38e79a5,0x0000461d7676ce82}, {0x0009ec564a7e489c,0x000ce0def5f2817a,0x0005d494ecc5675c,0x000149da00e78598,0x0000626833fdb035}}, + {{0x000905a83cdd60ed,0x0004d1170184abe7,0x00023642a50602fb,0x000aff989886cdb0,0x0000568d09176e1f}, {0x00022c70259217fd,0x0008f43141e45b19,0x00095f86e93831cd,0x0008280fca35870c,0x0000ec2057b268ae}}, + {{0x000a599f98a759a3,0x0002c7c23c1dc44e,0x000c4f68755a0a7a,0x000478a5ffb6e694,0x0000563cce242848}, {0x0003517e7b1fbe12,0x00092f7338e0812b,0x000d048db8a7dc97,0x0003b8011ecee952,0x0000eea4056e86ea}}, + {{0x00068a7ba772b34e,0x00007f4e2541d8cb,0x000ec14dbe16ed34,0x0008bdbb32f6a60f,0x0000ee376f819169}, {0x000aa1783674c027,0x0006e843022ae9a7,0x000a4990f65832f9,0x000215b9f3a8da5b,0x00009a59c3b6b8e3}}, + {{0x0004d2ebd19bb161,0x0000a3262d869cdc,0x0009c0b47c6c7cfd,0x000128c4ce14d096,0x0000fa352b723e56}, {0x00055b8973db6d32,0x0000c8e5b7bf383d,0x000bb571f7183685,0x000dd2a7714596e6,0x000059df31f4d5b2}}, + {{0x0008925913cc16df,0x000cf1a26f5a568f,0x000f499ae18bc5b6,0x000e83efa413bef5,0x00008835dedb3f0a}, {0x0000bd865a40ab05,0x0008c94b377eb6e6,0x000084a696559643,0x000de06cd8562592,0x0000ce433b99f23e}}, + {{0x000f04f6ad651437,0x000766e14af6e8e8,0x00095c0c71151182,0x000a15cd390a1082,0x00001e29ee4d21eb}, {0x000fc0963717b46b,0x000e306ad4a2a588,0x000c22b2202be02f,0x000848e31558c604,0x0000b4d4bd6c2f3c}}, + {{0x000f49620efd6628,0x000045952d1454a4,0x0009784c292ba6d2,0x000643adb8ea1ecc,0x00001cc10cacb353}, {0x00070ad4b4d7f6ce,0x0005a4a1dcd240b5,0x00047e7975c9f1d9,0x0009f421379f8131,0x00005c6097c0bd49}}, + {{0x000afa6328e5e200,0x000a5481555040dc,0x000bfc978f7b5244,0x0005b1b9a4f11847,0x0000ea0e79fd2582}, {0x00096eb646c7ecfb,0x0002946dea9da50f,0x000abcf69eb81149,0x0006e77af04677df,0x0000e3a06907713f}}, + {{0x000523d42e06189e,0x00006e3aff13860d,0x000b20650bf07794,0x00000c2b616dcac1,0x000066dd6d201313}, {0x000fd67ff99abde3,0x000097aac50dd4a0,0x00046b2d7c990355,0x0002aed22ecf8b7c,0x0000333b1e86abf9}}, + {{0x000113c6c491c14e,0x0007a0dd3f8811cc,0x000d932ed0597668,0x000b6d15b4d9e729,0x0000982aad982c38}, {0x00053478be0dcf0e,0x000d85ca53f26f92,0x0003ca77f700080a,0x000983f813115644,0x000092d6943cc51f}}, + {{0x0008af885dfe9aef,0x00045d2a86cad2a0,0x000dff020d825d9a,0x000c3f3c53988d39,0x000038b135b330cd}, {0x0008ae062a7150b5,0x000dbc340e9b0c91,0x000bbf02ef31fd8d,0x0002395fa0e7ae4d,0x0000847fb2aaeba6}}, + {{0x00047dcdccbac8b2,0x0007e6f485c86b16,0x00038ecdfb642aa7,0x0003fe673f376570,0x0000ce5e8661a49d}, {0x0003788c98c44004,0x000db1fa5279ea22,0x000becfd78104a8c,0x0004ae7cf7cc7a06,0x0000942431708f97}}, + {{0x00065e784d6365d8,0x000f0f759fb8c0da,0x000e81930bcb7443,0x0008aab5c712b17a,0x00000428dffcc6e0}, {0x000afefa4faf8433,0x000dcfa9855ff19d,0x0003ac7ceced8538,0x00071df0ac409cbe,0x000058c1fb6b82da}}, + {{0x000c0e5fd349961a,0x0000e421c2fcafa9,0x000a28d382b2cfa5,0x000e7d8a80db17f3,0x00008aba539fd138}, {0x0002d1d6e96eb8db,0x00001baf96225201,0x00064f56c65d8dea,0x000da1a7735447b2,0x0000eebef3fcb6c8}}, + {{0x0006d98ce7852541,0x0002ab64a161fc34,0x000794addd50e8d7,0x000ef6b03567c749,0x00005a76065852c7}, {0x000a222961f23d6a,0x0007d3ecc0b059f3,0x00082fde4378e443,0x000f34274be4345a,0x0000e509af378b9c}}, + {{0x000ee46577f44a13,0x000c8611deeb4a61,0x000f7b884e09b748,0x000a6b90481b2cf5,0x0000562667891acf}, {0x000c518bf8d21e6b,0x00010205a76d37f4,0x0004073c022d9653,0x00056687fb85e195,0x0000ceafe5015b3a}}, + {{0x000def7be42a5821,0x000055046be6efec,0x000e8dba9d3fc608,0x0001ffb9af13c809,0x0000e6c984774149}, {0x0004925d30c31f70,0x000aac2a21223b57,0x0000859e7b7eb72b,0x000942776a0dacef,0x00006fec31421900}}, + {{0x000bc10f8c22049d,0x0006b75ebf692464,0x00036326b9bfbcce,0x000cfa07a88e2a43,0x0000a05261d2bc2a}, {0x0005bdceba7efc8d,0x000955dbbf2ec29f,0x00075f127471237c,0x000325d72773f229,0x0000c744e8ed4d0b}}, + {{0x000ed16a56edb730,0x00072c007e7038a7,0x00080b40064357e3,0x000be1a167d15b50,0x00007b4116423de4}, {0x0001e3274c898834,0x0000e882e7edb2d9,0x00003e4823c16282,0x0003316d6b36ba75,0x00008434e8e4ea34}}, + {{0x000f24f2c7ae0b94,0x0000d939b44a79f4,0x000595eb1c46fbf8,0x0009c736fefae856,0x000017b66ac0d5f2}, {0x00032b2c5ceec209,0x000f51a1cae25f23,0x0000286e6d69661f,0x000992cede7e529b,0x0000d06252a7276b}}, + {{0x00094b07e50122b3,0x000b1af07ca53247,0x0003fc97bdd744f8,0x000d9d00a12f08d6,0x00009650f1aa6626}, {0x00047f71fa38477c,0x000914dc124f101b,0x0006eb58a3d815f1,0x0008865569ae95b2,0x00003cde18955fb1}}, + {{0x000f37bf9539a488,0x0005f408c1a554e9,0x000580cbbb0100e0,0x000c56021d9811ea,0x0000af52d3606e50}, {0x0009d47dbbf698b0,0x000a03dc1c73dfbd,0x0006a5df82961a1e,0x00007a203d38f8e7,0x00008a53a686def7}}, + {{0x000fb481bee45d41,0x00062c68803626ee,0x0002f2469b3cee34,0x000162363c5315c4,0x00009d84d2e91378}, {0x000c3c51c4d349f6,0x0003b63d59c522d7,0x000abceae6596584,0x0009d56f198c56b8,0x0000fb1fb1bc2855}}, + {{0x000fd0607bf8fe31,0x00082467734b8bbf,0x000f7f0d346259c5,0x000ff1c8953cea35,0x0000f0bece2e65b0}, {0x000b4b3f3c72914e,0x00045cb53389f7d5,0x0006b6d4629e8ea9,0x000fdd6a36562683,0x0000849f911ca174}}, + {{0x0002fbbf4737f217,0x000af209f5ac7ec6,0x000f9adbed8dba5a,0x000767b4b5d7a9a5,0x000007d28f8161dc}, {0x000460bcaa999eab,0x000c6c92e4cc7711,0x000d4bf2dba7b174,0x0002788c4bab6618,0x00008f0c9819b8bd}}, + {{0x000ea9a324b47379,0x0002a2a83bca024b,0x00032dcedfba9e42,0x0008b9de635643a2,0x00009619367b571c}, {0x000f35754b7032b4,0x0009e442d54ae8c9,0x00090c65af936b3b,0x000fdae263f0f082,0x000089897812e2c7}}, + {{0x000d55a13d4f95eb,0x0004fd9b8500adc5,0x00073f43d737cff8,0x000475771c557b8a,0x0000ed617a5918bc}, {0x00054017dfd8ab26,0x000dda2870aa6624,0x000a7e545ae7b89a,0x000e4bbb555f5323,0x0000791e2481e057}}, + {{0x00036ad324fa34d3,0x00071cbeae288601,0x000dd3299ea11144,0x000c33d23a4270be,0x0000d5c3a7ff1c35}, {0x000db678d0412d2e,0x00021cdc6b9ab0f6,0x00028a982d92625e,0x000e7db2ae5ccc4e,0x0000a251c3727a3c}}, + {{0x0008932790691bf5,0x0008b6b736ae9d65,0x000d63b6eed61058,0x00088f212c2f04c0,0x0000cf06fd6163d4}, {0x0003facd9588e411,0x00021b93257e9736,0x0007acace1f9bf76,0x000ecf99d1ffc466,0x0000cf4a1aa1a061}}, + {{0x0008a49dc1818d01,0x000993621ab040e4,0x0009ef6390643ff3,0x0008544768640ce3,0x0000fc099ea14d86}, {0x000b9c3eccd28fd0,0x00027eec54ab9130,0x000b475b6d743cbd,0x000d1f052b146fe5,0x000058d9a82900a7}}, + {{0x000229291262b72f,0x0008cb0edf0365e0,0x00020684296f924f,0x00071f6cfa59c8fe,0x000060370054eafa}, {0x000699e18d7dd96b,0x00021bab24955f30,0x0008be949381e878,0x0008eee1669b46dd,0x000040606f5d6aae}}, + {{0x000b839fc6751a47,0x00048ba800ef2812,0x0001a28751619621,0x000348d398d5ca4c,0x000020c00eed53d8}, {0x0009eb0d820007cf,0x000fb39b5825c269,0x0001f6984880ee65,0x0009998069469447,0x00007d16ea9d3dda}}, + {{0x00075b2c0519a238,0x000dcf6952e328d6,0x000294a8a9ebf94f,0x0003f5728bb767a2,0x00005512b4e7e0af}, {0x0008ba899b16a0de,0x000bda7548a71895,0x0006be61595c2430,0x00074bd30d1b10a1,0x00003ebbb9865bfb}}, + {{0x0003cfe18549fdb7,0x000edfcdb792a327,0x000aba56cf6e200b,0x000aa1e4a76e1883,0x00003ec66f6f9ef6}, {0x000add7d1b9a305c,0x0008f7ae1b9d8d17,0x000cc094aa959c5b,0x0009b8c86435226b,0x0000c5616c597d42}}, + {{0x000da01e6a33f7ce,0x0006bd4e70ada6da,0x000c15b7cc6217a0,0x000853f619a81809,0x0000a06b329ee80c}, {0x00011cea5f5e7b9c,0x000fb87c65f41748,0x00016ab5466dfc30,0x000f6f8ea7bd6933,0x000012c4acbddcc0}}, + {{0x0008d1a1e407dd9b,0x000be1afa997e430,0x00077b7a5e8a3587,0x000d523a296c12ab,0x00005ad49e5173c0}, {0x000b2b27006085ab,0x000fd7bf6ec240f9,0x0003066a6a88ff33,0x0006e1e78603b14e,0x00003f99fc365e48}}, + {{0x0003f5eb2e636456,0x000724c8423207b5,0x00014d5cfbe57e54,0x000aca7779c21672,0x000017969cd629a3}, {0x00068cd8a7017a0a,0x000a1e9b7ee8d176,0x00016177677b4d19,0x000a71b8fd0e939c,0x00008c4f4f075968}}, + {{0x00071cc67b3de77b,0x000db34f79052960,0x0007100c9ae3c0b8,0x000b41b7e440c28a,0x0000b8c3c1c9b4b9}, {0x000e8eac51b35836,0x000f3525e6426d71,0x000f509f37591f5a,0x000c9b973a2f7b13,0x000018487aab619a}}, + {{0x000e5f79d61718a7,0x000c0592d28c3a72,0x0003c35cf00413bc,0x0006ed0d9b11d396,0x00007623bd0290a4}, {0x000273bdcdd2a50c,0x000a4601846edeef,0x000c6e9294a741f9,0x0002cc73b89e510e,0x0000b0231a04b7f2}}, + {{0x000500d084bae24a,0x0006943d2693bbe1,0x000def8112f0ae8d,0x00094f0cffb5f27c,0x0000a0c030ac63fb}, {0x0000d61a0f442dea,0x000687b139d36eef,0x000d8bc28f92e181,0x00012f7ae6deb70a,0x000089e38dd60514}}, + {{0x000b865d2fdca23e,0x0007ec8ef89581ee,0x0009056145a15ee0,0x00019a968fa10a01,0x0000ff5b8f0680ee}, {0x000cabbcb1c8a0ef,0x000cc8c838f9f0c0,0x0004a14c02e1ee9c,0x0008e41587d8b88a,0x00006f278971ff69}}, + {{0x000ef1c89ee6256c,0x000dab353b45ed38,0x000e903b3f44ee1f,0x0001ded115c0c770,0x000078ec0a2418f3}, {0x0003324b7dccbc61,0x0003063bbc256c00,0x000edd805d96dd1f,0x0002f123aa82dd5c,0x000023aae4f8f7eb}}, + {{0x000fcf5a26262cd2,0x000ce060ebd51723,0x000eaa3af1f7f4d5,0x000ccfd19c5c01b2,0x0000ccb9b14b790a}, {0x0001cad52324aa65,0x00062247df541f9c,0x000c96f826320052,0x0003840732fe42ba,0x00002fe771f51a1c}}, + {{0x000a13db1001684e,0x000dc1709f75546c,0x000db8672b56b4ee,0x000cfa466545a9d5,0x0000d971c90fe8f3}, {0x0008691e3a07b296,0x000c84b696b94e7d,0x000c7e9ae7570d9e,0x0008447c5fa0677b,0x00008b44cb0282c4}}, + {{0x00034b3bf44da801,0x00094ab32e66519d,0x00078a000283834f,0x0002f65e60879762,0x0000e62960e72731}, {0x000b27be6901c550,0x000824fdbc1f9b87,0x000acc27d80e7853,0x000b5abbbc09512f,0x00006394239ac143}}, + {{0x0004a40376c1944a,0x0003c3da151135bb,0x000148a3b7cb6269,0x0002ee0fd29161b7,0x00006f9d9edee2ea}, {0x0002ca2880dd2123,0x0003761139a915dc,0x0000f8785903c381,0x0000fefaa7b46d6c,0x00006ce2871c01c6}}, + {{0x000b028e10d9c12f,0x0001132f33d3c683,0x000a31b587573baa,0x000e1197a9b1f667,0x0000d3ed11be4ffa}, {0x000aa9a0cb2748e2,0x00083d6fdf1683dc,0x0007539418239f01,0x000b369a67b49c72,0x0000beec455e321c}}, + {{0x00056063f8b84cec,0x0002cd38c86f8801,0x0008953dd7641708,0x000428454f1ca759,0x0000939e1110e8e7}, {0x000c2b35a914f2f1,0x0003d74b8f9c9b1a,0x0001b2fb039e35ed,0x000ba2c0debdb278,0x0000585638f3d997}}, + {{0x000646e9e2fce99d,0x00004e80857f9c4b,0x00043b52a68a2108,0x00084236d54e4436,0x0000e8d6d63dd8eb}, {0x000156342146a0a4,0x00021eaa36227032,0x0001387878ba826f,0x000d36e27a58bd86,0x00003b6c03c50281}}, + {{0x000afbbb54dde39a,0x000a3b6f2d5f6326,0x000f158e1744e5e8,0x00018ea8b2a99acf,0x000093c8fa18f879}, {0x000f956de058c5cc,0x0001d36f9e7a2182,0x000e31e67216235d,0x0003e6ece0c0dbd2,0x000096449c0b23ac}}, + {{0x0002874170693bd8,0x000d245e63357e9a,0x000427344a28e14f,0x000df8d757f6b356,0x000022e45572cf8e}, {0x0006ee2e6a285cd9,0x000119df3af02b7a,0x00045b8445866f21,0x000e48b0dde2ddf8,0x000086c3726a10e5}}, + {{0x0000c2af7172277b,0x000e5cccb2447368,0x000438ca757b94f0,0x0003fd0dff72672d,0x0000ad1ce127f466}, {0x000ed9dd8f71caef,0x0005a61fdaa69813,0x0006d1637f43272a,0x000977ceff0119bd,0x0000ebc4f9220361}}, + {{0x0007a952f41deff1,0x000ad63b89b702b3,0x0003ff9510e44a59,0x000af4573257dc14,0x00009c02205e752b}, {0x0003069c4b7d692e,0x00031d1502ac46c2,0x0002208462e6392c,0x000b628057b1a21b,0x000051ff946ec1b5}}, +}, +{/* digit=35 [{1,2,3,..,}]*([2^245]*G) */ + {{0x000cb51566c5c43e,0x00085597f0466e85,0x00094d94acff9c91,0x00027cb354e90c49,0x00000a3933301479}, {0x000fac10dc1eb2bf,0x00013ff319fa8427,0x00096527488cfd8c,0x000745f2d4e68401,0x0000a2e067e57aaa}}, + {{0x0002a7f3e5f9f11f,0x0009e6cb3b8eb6d9,0x000f800bd9afe153,0x000e185d1a6dd7dd,0x00006c13cc1baf17}, {0x000c58e325fc3ee3,0x0000731dc3b215f6,0x000a3d3e77109540,0x000e2ce68e7c07af,0x0000f8417a1c4c7a}}, + {{0x0004772813b230d7,0x000ea7344427ec23,0x0007fc56a634d0f5,0x000f76a1548ab1d7,0x0000fab17513e06a}, {0x00010a74f7c4f830,0x0004220a67d9b62c,0x0001209a0a7d2edc,0x0009f01c40417092,0x0000b9815a0face5}}, + {{0x000589b319540c33,0x00097283d6f82842,0x000ae9fcb18490f5,0x000ba072731f84da,0x0000db6d960f3683}, {0x00063bb146110697,0x000e9788bf05c85c,0x0007460d2b19436a,0x000db1205459df34,0x00003f6e095511a7}}, + {{0x000938eb6357f373,0x0008fbd8aa62dc7f,0x000a979fcc5d00f7,0x000a999878dcb92c,0x00007e83eda1b023}, {0x000e2731560bf3d1,0x00090d0fae616b23,0x0009414bd1086e45,0x000ea1682483169a,0x0000b956bc100ea9}}, + {{0x000bb91c31b9c38e,0x000a68ef57b57b85,0x0003bab6f0c5aa90,0x000684fedeb169af,0x0000610ad740d373}, {0x00070df02ba8e15d,0x0005bca7f771f138,0x0002c036c0337edb,0x000e8114acf747b6,0x0000921d57786b94}}, + {{0x00064392c422f7ac,0x00022d348898dbc8,0x0005bfcd1fb63536,0x000e10c3084668c4,0x0000357c9e3eb315}, {0x000b5405b2e5b8ce,0x00010102b9a4b173,0x0000fb1997e94693,0x00062a37c890eb7b,0x0000c225a84b61b6}}, + {{0x000a3c8ee3c76cb3,0x0003a32a1f6ef306,0x00063e9563cf1162,0x000c26b6d5ab6468,0x0000b8a4cbe8c005}, {0x00029a59ce6bb278,0x000184d4b16fdcd5,0x00023798dc4afaa5,0x000fab30624a2679,0x00005e56df6eb307}}, + {{0x000893c2bf296984,0x000497ce76030281,0x0009a558f91fc19a,0x000f7735a5dca3ad,0x00000ceb3fa8d50b}, {0x0006060bc9ba369d,0x0006897888c21baf,0x000a34c07927e103,0x0009800936bf1986,0x00004cf10c2934ae}}, + {{0x0005334859dd614c,0x000a58d0c8ee3a3e,0x000cd51d59c475b5,0x000325a3080d1f07,0x00009c0d0a7788b4}, {0x0008691c234296f5,0x000444887fb61ac9,0x000ea9cf22a0a83a,0x0002f5065114270c,0x0000230a6e8f2480}}, + {{0x000bf0f72e3d5c1e,0x00056f21439ef7a2,0x000e303343771744,0x0002f91edcbf259c,0x00000030a795ce20}, {0x0009ebf1202e9ca6,0x000c15e6e5916f2d,0x000dac4f8e79dde6,0x00004d952072aff1,0x0000c8d087f1b9b4}}, + {{0x000c73dbce913af4,0x000b058a07cbad0f,0x000f00c8a909e587,0x0006abd300da84d4,0x000025cd048f5446}, {0x000b9be90e9d8bf9,0x000aae431b0eb59c,0x0001aecff991616d,0x000c3b43aa117a53,0x00001af92d3e9f4d}}, + {{0x000c292e93fda293,0x0007b97d91bc9b1e,0x000ace1e676bb6c1,0x000ae34509d95faf,0x0000653fe47ee855}, {0x0000b280f680e752,0x000bceb6c26c7318,0x0006d423675eefd1,0x0001d884cdf29fb6,0x0000d70a9978b582}}, + {{0x000e20720445c36d,0x0001898771747a3e,0x0009f73e971d1ac8,0x0000803fc539f794,0x000005cf3d8682e3}, {0x000e20b7b1c7129b,0x000fa69e61f28758,0x000544c2dffadcc1,0x000e53005d3a2f59,0x0000e16f5c24fff5}}, + {{0x00065b8aad581350,0x0009037aa5be73cf,0x0006fd6a0622c211,0x0008cf79373b3f64,0x0000e029db50d397}, {0x000c43794fba0377,0x0006f20797a68bdf,0x00030d38eaefbd68,0x000463cfa5382bbd,0x0000627cfbfc85d7}}, + {{0x0000fef4e4ca4631,0x00072566cc63b233,0x000780900bcef728,0x00027dc161d2cacf,0x000035dc5396b548}, {0x000052e27bf1bc68,0x000f87dfa06c638f,0x0003321da10a224e,0x000c8f6973586d6d,0x0000b0c5738a6152}}, + {{0x0004f2a346060743,0x000870f7047a07ef,0x000a0e30680fe7fe,0x0002220d1a8152e1,0x00002cf43d8b8da5}, {0x000a95f5f02ffe6f,0x0003906ad3eabf89,0x000c8e55e3d9eb9a,0x000dab112c17bb79,0x0000dcd1a7589c81}}, + {{0x000178bb95560983,0x000f501c38867043,0x00067b9124090a1d,0x0000c8459800ff9b,0x0000e5c030453262}, {0x0003c4b70dceecab,0x0004681f648e4b9d,0x00033345cbb2d3c1,0x00097a4981d8376e,0x0000626289bbcf22}}, + {{0x000c6598baebdcf4,0x000935df01e5766a,0x0005876d81a28ae0,0x000800771283da37,0x0000865a96da07b9}, {0x0001bcd237936b24,0x000b2041749425dd,0x0000a2147332f4f4,0x00020390923d6837,0x000097f5dfc1c842}}, + {{0x0004cbd32be5e0fc,0x000657a013759dc7,0x000d872b17475bcb,0x00063c838477c950,0x0000ec6787abfe1d}, {0x0006014d8578c70c,0x0007b8bb6b8b9b00,0x000fb3806c9ad99a,0x000ab2a799008e11,0x0000fe814368d44c}}, + {{0x00015822f4fb344d,0x000f783fa6eba2ee,0x0002c7749b882344,0x00015a922d323d65,0x00008474a998eb0a}, {0x000154d5d1c00d06,0x0008ae3e7aace43c,0x00025ddf87fd581d,0x000738cb44c61925,0x00007a033ec18ae9}}, + {{0x000fec19ef2d2e4a,0x000e35a0ea7f113f,0x000714c0a1bf6767,0x0009edb7fff75e03,0x000023c422eaa23e}, {0x0006b2d540f83afd,0x000d85ea46a7dd5f,0x0002a1208c2c2c27,0x000f7a1b6b424667,0x000013599f87e634}}, + {{0x0004b5cd7b32c6ee,0x00000af61814cf91,0x0008a1bbb61a5a64,0x000aa4adc3df8b20,0x0000f627fd796d79}, {0x0002ffcc4c86bc81,0x000af61539fe4423,0x0008b9533e6f9231,0x0008850d04f25a95,0x000080cf93459e8c}}, + {{0x00095959884aaf7a,0x000267b348a68968,0x000147c87b1959be,0x0001f7f6250e573c,0x0000e0efb3b7d0c6}, {0x000745eca8c325e7,0x00067cff3f70ed00,0x0009ad41d3c91169,0x0007ef03acbc6531,0x0000b01a02160b1c}}, + {{0x000b29363a1483f9,0x0000ea248f96ea32,0x0003157e589eabe7,0x00046d0c6231d334,0x00003a375e66f3c5}, {0x00093436a2afe69a,0x00004166c88ee76e,0x000872093c4f8910,0x000a60848efd0d4f,0x0000e0eb3eb2fe0e}}, + {{0x000790d9d79046e6,0x000d0cee0976af89,0x000071eca4d650f2,0x000bfe43935d9a43,0x00006fcd2c9883b0}, {0x0005eb5696605f18,0x0007254cd38d0e66,0x000d950cfe77e5d0,0x0009b510ee050a43,0x00006ddebdb532e6}}, + {{0x0004a3dfddf74157,0x0008cf6e8d5a6ad9,0x000957f75f7fa130,0x00044754831d1de9,0x0000de2850245817}, {0x00070789e2aeb6b4,0x0004b67a53c26f1d,0x0009defc3ba2b9ff,0x00022bf6963767df,0x000079deed34d380}}, + {{0x000b89b3a8631e8d,0x000daa213746d2ed,0x0000c5f118de855d,0x0005e3e2056cb7b0,0x0000eaefbd0fc9b8}, {0x0009a8dd150892d4,0x0005e18b798503f3,0x000375f1a37b8468,0x00098df6296dd8b7,0x000072cd4b1f78e8}}, + {{0x000f651e9f05de9b,0x00087ce98ba915df,0x00038024cd404506,0x0005eed466a7ae9b,0x0000910e70195a6b}, {0x00056eab3aa8f0df,0x00068eee74a6ae1c,0x0004c4620bab2a50,0x0001f31dca11e24b,0x0000d896e2f3c47d}}, + {{0x000ae53308fbd93d,0x000d32c36fdaeb45,0x000a4838546cd5a2,0x00095f9a3d4e90ba,0x0000d55e62f6dbe9}, {0x0006aa02a81ede7f,0x000409274ea7a140,0x000414f866860dd1,0x000326dfdcb0c280,0x0000f410b1112f94}}, + {{0x000cc3849ad467b6,0x000baa7335f15a33,0x00053a360efb48b6,0x0009cbb4fb54a4b1,0x000004aa9d315246}, {0x000c486754e48e96,0x0004d7471e8e5e9d,0x0003b37b6693cb45,0x000f079b2fd7cd8d,0x00003345e172f09f}}, + {{0x000ba6b23a5d8961,0x00056fe4364e9910,0x00033c6771fe19e3,0x000fd05e1da8c39a,0x00005b4488b39fd9}, {0x00092541a1f22bff,0x000fbb8163e81f43,0x000e5658e920a8a6,0x00039a4fd1b24907,0x00002c4f79da6ec8}}, + {{0x000c3d04aa38d1b5,0x000c65d9510e1abb,0x00060dec03b0db35,0x000b32c754ac783e,0x00003272fd83a099}, {0x000494f07a8e1078,0x0006ea8191fa5fb0,0x0004ad5444a89e13,0x00097b2113b7f63c,0x00008a2e909ecb98}}, + {{0x0005de3b44a3f84f,0x000327c6c69017d5,0x000232390acb2f34,0x000bf64208816810,0x00002e8a6205c733}, {0x000aab69c2d76521,0x0003dd95c5bca774,0x00081f110fb5307e,0x0008c9905c73c249,0x0000baae31cb3945}}, + {{0x000185bcbea62e7d,0x000e1af630591def,0x00021851ce8ac9ea,0x000f5a398a8cfd99,0x0000959c3f20abe2}, {0x000952520e40ae55,0x0002b7a24aa1a4f1,0x00092b2bc320789e,0x00068ad59e692773,0x00008f6c66769186}}, + {{0x000b2bbc55d2d8b9,0x000764f6ca56ce1d,0x00087761441d58bb,0x0009ece650b6808f,0x000005e16bb84c34}, {0x0005140f661acacd,0x000ffb2270afed41,0x000402cba3b8784e,0x0002196bc280ac8a,0x000053f7146d9379}}, + {{0x0008ee5e5681e833,0x0005c6ac9e4ac03c,0x0006b1a386212610,0x000cbd6503a53f93,0x0000d45e2d4a82fe}, {0x000c43976e8ae983,0x000b8fb4b00e69a5,0x000386c89b53b2ee,0x000ce4c167471272,0x00000ca34a27268b}}, + {{0x000d86c783417303,0x00088525e2487f1e,0x0004fbf388ef5beb,0x0003828bc489fdb7,0x00008a92a0ec1a0b}, {0x000ba3f22433ccf6,0x0006429f05a97a77,0x000189afcde8362d,0x00014f1f6a30ea61,0x000093b5505b9ef1}}, + {{0x0006bc0cd1797a18,0x000e74b7af2d5026,0x000f9483eea17b47,0x0008c956c4025c3d,0x0000cbb9da0237b1}, {0x000fd9c4d8424cff,0x0000bb1c350691cb,0x0008206a3db7048f,0x0006cdaeaf641f02,0x0000986f3fa15bdf}}, + {{0x00043b5224c08dca,0x0003e1b50c912621,0x000a8c84f2bbb09b,0x000ca8216ed709ac,0x00006210d9e52850}, {0x000f67a09cb54d69,0x000fc00919a46d8d,0x00013285791eef6d,0x00028b00f613810f,0x0000acede4888d50}}, + {{0x0001b7190b771c33,0x00048a6426be844d,0x000b802ff563b71e,0x000a40fefa2e83bd,0x0000410cbabdb5b4}, {0x0002d2630da84dd0,0x0009ee1cc29a555b,0x000547792d0711ae,0x000b35cf3e8c602f,0x00003d7d5dedc678}}, + {{0x0002fa8ced806b84,0x0004297f1478071a,0x000fcdbbf222e613,0x0003b89c16fd5dab,0x00004912ebf521b5}, {0x00036742496c27c5,0x000bcffc26b0ac94,0x000debf2c8ea3176,0x00083266e224ac13,0x000024cc2364372a}}, + {{0x000e1d89f6f1b18b,0x000494cce35bd706,0x0008e31fc2552f00,0x000046dc8326c2a8,0x00005468b2da9552}, {0x0003e883ff90f2ba,0x000e8f0a5423ce68,0x00056e32877947bd,0x0004ac30a1b28bed,0x0000ee3525462013}}, + {{0x000367d3567962f6,0x000f2188bffb7e98,0x000f130a1379ed61,0x00073413bba348fa,0x0000c1f75e1f04ed}, {0x00066423b4a79fce,0x000c74ef44931895,0x00011eca1f20bc83,0x000dcea36d425d91,0x00005b5c318e09a8}}, + {{0x000b25d13221bc57,0x0001fb3eeaf73360,0x0003a95a1707baad,0x00009f67279ed874,0x0000450a876069e8}, {0x000bd53e5d0338fe,0x000e4b883bbc32b6,0x00063ecd01e77f7a,0x000e46b0da12cc10,0x00002697b59a315b}}, + {{0x000a5bdda85d5347,0x000f8f980eea2771,0x0000385e753e78c1,0x000b623df1cf8490,0x0000d3b14f739387}, {0x00074b0cb8f2bd25,0x0006327fa993170e,0x000f32bab2d50b48,0x000ab87dbe8c9af6,0x00005e906b113b93}}, + {{0x00022fc8fe280d19,0x000522e114ab747f,0x0000b68b0cd8e0de,0x0004b1cab7dbebe1,0x0000dc63a9d3480d}, {0x000bc3b4be1495fb,0x0007e359122d78d4,0x00009cbdc25eb3db,0x00002e8f8ac05b08,0x0000f4187bc837c7}}, + {{0x000a0691416a6a5e,0x000863ef881c84ce,0x000038a5d8f860c7,0x00006661311f8a38,0x000078c2ec1dc612}, {0x0002e815ad735813,0x000029604097494d,0x000612cbab4cc9e0,0x00039ecf558aecf3,0x00005beef7ace36c}}, + {{0x000c7cfdbcf41b9d,0x0009dea997c01845,0x00002f6d85703662,0x000161bb925afee4,0x00000a1b1af1dd72}, {0x000b37503c41c4b1,0x000af391d0429f47,0x0003b8b0aa023829,0x0000e54f5045c350,0x000023c2688a8c01}}, + {{0x000c0cc36ba06eee,0x00045dd2cc0c324e,0x00033e91fface311,0x0002afd364f3bef3,0x0000f8aff7408e83}, {0x000ad042d05841bb,0x000e856a21e21e9b,0x000dd627e42f0e3d,0x000710f3270bcb4a,0x000009a81598322e}}, + {{0x00026a10fee104a6,0x0007d703f65d86e3,0x000bc4833ad7788f,0x00093a1e76543047,0x0000cee582b8b9b8}, {0x000a167e8f55a7b8,0x000659e4190d9cd2,0x0000c2e9defbee3c,0x000547b3ee7185d4,0x000044cc9c62380b}}, + {{0x0008ecd66926e04d,0x000eb110c1ba323f,0x0006a7f070001e38,0x000826bdbcac12fc,0x000065e1d58dcec0}, {0x0004141be76ca2da,0x000c4892f33ad2cd,0x0007139d27895cf5,0x0004c0f56d230d36,0x000091abd3f7012c}}, + {{0x000488387eb36bff,0x0001a14b8fb434fa,0x000b9c95fc5f0710,0x000194a0f0e579ad,0x0000e6ea8cc18888}, {0x0005065edfa9284e,0x00014b8c8d657b9b,0x000e8aafd6c510bd,0x000a06f7b8ebefcb,0x0000db3af9976b1d}}, + {{0x000779d6295d4269,0x0006afa3ad7b28ff,0x0008e26040c4f6ac,0x0000e15c44d0548b,0x0000b32a66e1b005}, {0x0003366f0476ce2b,0x0002f602c7b41f94,0x0004f28097554d95,0x000bea0e35aca652,0x0000688122aad4ed}}, + {{0x0000c8f508efb637,0x0007fabcefc7e8cd,0x00041ab4f9eb5b5c,0x000b2285621f5fb4,0x00009e6c047276a2}, {0x000792ce37a1f698,0x000a83542b6074a4,0x000c20bd3cbd252c,0x00060bf85f65d5b3,0x0000dea6143cfabc}}, + {{0x0001446de6736294,0x000e303c2d2145e2,0x000c868c757f7aa1,0x00067660e99b7f98,0x0000e42f66dcb641}, {0x00084dc910778965,0x000f72c9885b6028,0x0009a5187a0d690c,0x0007eeaeb4da333b,0x0000f789598653c8}}, + {{0x000dd4752b16dba7,0x0005c524c1b12192,0x000383693deefc0e,0x000d97d65ea76ee4,0x00009401711a61b8}, {0x000ace9f21a15cb6,0x00038fee9aeba5f9,0x00077016c73d2616,0x000e066ca844b3e6,0x0000c122b07b7eae}}, + {{0x000dce715f096905,0x0001ddfc0fc9b782,0x000d89fc6508b9b1,0x000b0f4015ab4b65,0x0000e79dab826d5b}, {0x00021f06c775aa2e,0x000b57c7eca164f0,0x0002fa506df09d8c,0x000ec5ba761367ef,0x0000d4ca4773b81e}}, + {{0x000de3610bbb8b54,0x0002c641ada3262e,0x000831ccc0737ce8,0x0006350c94288ae9,0x000087fc1cec065e}, {0x0007ab3b8bb36591,0x000e755e4120b13d,0x000eb0244dea5df3,0x0000a3a9a1857385,0x0000a1b8ea3b7cfe}}, + {{0x000711967b0867ce,0x0007bd3645203b83,0x00030f0e38d5e0d0,0x000bae72dccc1ed9,0x0000fbbcec89f20b}, {0x000fcab0263ad100,0x000dfcd18f8a99cf,0x000f10617d8199e6,0x00084864e2773fe9,0x0000079e8e108704}}, + {{0x000989f8a3422839,0x000c183012e61169,0x0006a90018097799,0x0007fc5ce966cb8a,0x00003b3afef972ac}, {0x0003a2a2db3d5ba7,0x000219bf4fdce689,0x000396673263dc46,0x0002b61852dfc9e0,0x0000ac70895aaf36}}, + {{0x000ce4d5c2f342bb,0x000a052d7aaebb9c,0x00061bcd0bf80907,0x00044ce7f3d3cd21,0x000025b0834b9627}, {0x0008ea56c3a1ddad,0x000a36c92317c5b1,0x0001c4afefe4ec7e,0x000019e787b890ad,0x0000ccd9a92dede8}}, + {{0x000dddadb58da1f8,0x000f38cae6ee9ac6,0x0005c4a4322bbc12,0x0000c746f8bced81,0x0000105a92d79648}, {0x000dbf37a859d51f,0x00054041196b0dc3,0x0001067c9e3ec7ce,0x000dd7e9f64b250d,0x000023213222d1f8}}, + {{0x000619c76497ee80,0x0006c717370e8b5c,0x000cf68e15d2b0ac,0x00079298204cb64f,0x0000bdec21162bc6}, {0x000ccefa63b10110,0x0007e0de1ac56973,0x0000e0c8bf9e3fa9,0x000cb45efb693e3d,0x000037248e9d2d4f}}, +}, +{/* digit=36 [{1,2,3,..,}]*([2^252]*G) */ + {{0x0002dc91ec34f9e7,0x0004c38106038080,0x0000cb4f3d8772d3,0x000128cf06d66c53,0x0000be5ed0e3475c}, {0x0003c1931e82b100,0x0007c9ff6b4ccb9e,0x000a1b45ec63d285,0x000bcab92118c692,0x0000aec44147285b}}, + {{0x0009ae71e29a3efb,0x000f9c93302efc18,0x000aae10ecbe906e,0x0009f820107914ce,0x00007a23f35668e1}, {0x00075c2efd2119d3,0x000eccadc9c8e9d8,0x000a1711303198c6,0x00003835591bf64d,0x0000cf0bbf86d443}}, + {{0x0005bb72b7247593,0x000182d4c63aae48,0x0007d6f2c945353e,0x00010952159d07de,0x000089caef37ec5b}, {0x000bb53db65ef147,0x000e6d99de434a8e,0x000f2405f2dc2cb7,0x0008a3116fa3ed83,0x00003429bba31420}}, + {{0x000d590b01e6e274,0x000da180b2dcb618,0x000aea4a9047e2cc,0x0003a491b299b504,0x000012c9e1edfa40}, {0x0008a36794075521,0x0006e332b8e388d2,0x00068de1949c5013,0x000b972a1b6fcce6,0x000078851bc85122}}, + {{0x0003752fb85fa4ca,0x000d983c8ce9b1e1,0x000f74daed61257c,0x000bbb343da670d2,0x000035aa2405f846}, {0x000235d4421fc835,0x00007363473b5e74,0x0004aa158f6df8ee,0x00022de4d7f52a3c,0x00000d05aabebc6d}}, + {{0x000e735a64785f45,0x000b0f29cd078c56,0x000e35067bc56637,0x00027003b2bb803e,0x00000235a102c919}, {0x000b6d8f2c4aa658,0x00010396023b191a,0x000f805bac347583,0x00080f00400ba5f0,0x0000881065bdec0f}}, + {{0x000e522cc1b5e838,0x0001060b8bfbc370,0x000b256dfde2d4ad,0x0009972d364df067,0x0000f12502f60138}, {0x000a0dc7783920a0,0x000dc0bc866a503f,0x000064ba6e80014a,0x000ba53f89b744d3,0x00003511dcdcba5d}}, + {{0x000d46d95a7b1a29,0x0005ac6341fb197d,0x0004c2ece9c4e7ad,0x000f89b26eca2948,0x0000211e48a6e7f4}, {0x0007f6ec78ef1f42,0x000fe65745861499,0x0003eede82b2c090,0x000017f7286a6e1c,0x00005f92e472f60e}}, + {{0x000564631890a36e,0x000f77feea5b805c,0x0003c3030703ef5f,0x000738589f747caf,0x00000e5daec34dd3}, {0x000a4c3c9c9f1554,0x000675393962fe24,0x00020bf297e4bf17,0x000c3af7183de2af,0x0000a1bd7b6395a8}}, + {{0x000969946191d3d6,0x000d1b87f257a83b,0x000107588281fc8d,0x000fe8518e2c1354,0x0000372def7fb2ba}, {0x000bb480d8972cae,0x000676167a3fdaf4,0x000310cf43f2dd4b,0x0000a93eace32d84,0x00003bcefb0c4270}}, + {{0x000691ed785e73d3,0x0005fea604675fe5,0x000c6514aa5db5ab,0x000664d2e23d41df,0x00005e8048f103c3}, {0x000118f1adaa0f81,0x000574ce1a5a3f8b,0x0006646b828ec3b4,0x00040fd8cacc6e2c,0x0000343d185ebd0e}}, + {{0x000f844caaa358cb,0x0003e924182ae5d7,0x000875d9a1a1db7e,0x000ec8264cd42d9c,0x000037b515fb42ee}, {0x000d4097b165fbe5,0x00099206eff34d4d,0x000b7e17efc322ed,0x000a002dee410259,0x00005a481c0d236c}}, + {{0x0005312c23fc9759,0x000575d6297b8c88,0x0008edd391571580,0x000e521078868ef7,0x000056b31e093c45}, {0x00075d5ff7b33a68,0x00098c7e673f4702,0x0002f2598c8d5dc3,0x000974c19227b47e,0x0000b37b634cc14a}}, + {{0x0007ed68b11888c9,0x000df03e25dcd066,0x00087a24a5e0e8c3,0x000322a4e5d0dcb9,0x0000f40ac3c3e920}, {0x000de9534e0f63a7,0x0001fb6328f95463,0x00064f1b7a128bf9,0x000e34d91ccd7cda,0x0000ef1ec28347bd}}, + {{0x000240fa36a27378,0x0005e3621bc1a857,0x000fb689735dc136,0x00019cfa3a6453d4,0x00000f1a43a49293}, {0x000274bf8cb0ba05,0x00063078c5ebfc18,0x00001d0efb0b5376,0x00009cab0d49241e,0x00000d7c67d872ab}}, + {{0x00070af3aeac968f,0x0008d4b63266b4e3,0x000ac5664e4f7fee,0x000cbec4acd4c2e3,0x00008910bd3beb38}, {0x000e50cc9c0726e3,0x0009a97b40bf1c3a,0x0005a5a1b1530956,0x0004cd40884b7ffd,0x0000890896b1f831}}, + {{0x000515ca5618c937,0x000b07d942d158e1,0x000f767a8e665432,0x000110432181bfb6,0x000053794e8aa604}, {0x000eb7ce8c0dbccf,0x0002698673a309af,0x00046db0031e0261,0x000b276d98e5577d,0x0000c21fb8d8d985}}, + {{0x0000116b0843e0bb,0x0007b9b04531c904,0x000d7d83053b1b3a,0x0007e82d1649f085,0x0000b3bcc887b742}, {0x0001100c93dce831,0x000191922a2a7726,0x000149ce87e79da6,0x000c83487a2b02f3,0x000047e1384ee92e}}, + {{0x00083d3af077f30f,0x00031658b53a484c,0x0007aec53ea78f84,0x00077ca12076c202,0x000034714e483c81}, {0x0005d15c2376c840,0x00093d1aa78337ef,0x000852a908315b65,0x000bd43a75c484ef,0x0000ba0c58a16086}}, + {{0x0008d7a529a6d482,0x000da2f192032968,0x0002e2df99c7f250,0x0001bbf23042fb68,0x0000b7587e7cd812}, {0x0000233e0182a650,0x0007e3e1128a30fc,0x000fb098fb82ecf8,0x0006a77168286193,0x000043e21ae85e9e}}, + {{0x00049d666c834ea0,0x000847414287ab5b,0x0009a2a473be43e1,0x000f3cf40fb85921,0x0000e6559e9cc58d}, {0x000fe8e0c6615b48,0x000cd6459d70fe1d,0x000de038614abc8f,0x000c7bfbe0fa8e05,0x0000e63ef6969035}}, + {{0x00001b453b31e91a,0x0003a436b4d81164,0x0007afd660cba7ad,0x0004c3f151f9a010,0x0000faca8d0bf0ee}, {0x0005c1d9ee9761ca,0x000b50c0588f75fe,0x00004804c3497a16,0x0000b89ee2bebd03,0x00008fb9a6162c99}}, + {{0x00032fe392511143,0x000c9ac73366d14d,0x000a7495c36bf25b,0x00048b99562c66db,0x000024d301b76ad3}, {0x000620cd670407e5,0x000193733a019f46,0x000c324e00ea8d4f,0x0007cd8396d532b0,0x0000b211a0e53c31}}, + {{0x0007d205ffe7b376,0x000ab747d2da090d,0x0004fc5193b7f3ef,0x00071e42cb525fb5,0x0000e220933566a9}, {0x00060dfb486d440d,0x00056fe13465ddc1,0x000e4c1517fcfec4,0x0002b4b3da7e4e76,0x00006fa48a2a8d30}}, + {{0x0004f265872cd88f,0x000b378b90a1c630,0x000f0bc1c806c1d3,0x000d5b4553e725ca,0x0000f59e604ab9d8}, {0x0000f327a0b85dd7,0x000a23ecc217a455,0x000d62213dec5720,0x0009549b88b74169,0x0000212f245cb365}}, + {{0x0004111b5cae787e,0x00073dfd31242076,0x00075aefb13cb7f5,0x0007744dca77da11,0x0000b75466cdfaae}, {0x0006f3bdb6cff322,0x000a41fcda9a74d7,0x00025028b7440f37,0x000f28fbb3ac92b5,0x00000fbf8f7c1975}}, + {{0x00092e1df83097f7,0x000be54b08009826,0x000ce2f2f28738f6,0x0001946c703717a2,0x0000913b93cb0814}, {0x00045931fe896366,0x000f978834a60492,0x00014a5a17b98443,0x000f4bb1c6ab0151,0x00000deb3845fba5}}, + {{0x00054c601a982e6c,0x00007491cd264caa,0x000bd6b051dd35e1,0x000723d73c315f7c,0x0000ab0077612494}, {0x0009b1f6565e15ae,0x0008ac8fb0260465,0x000a0de37bf30f52,0x0001141c21641ba8,0x00009c7a367da5e5}}, + {{0x0009ca552f03ad8b,0x0008524e35c0db84,0x000c3c789c7e8dbe,0x000261f1a2bbaccf,0x0000f733e7e4c26f}, {0x000fbf5b8444823a,0x0007cbf8483b882f,0x000bef640b7224e8,0x0008ccb3023b8b65,0x0000abfec9274d5f}}, + {{0x0001510079ea1bd1,0x000cc05d5d26a40e,0x000e68d4f1ad9add,0x00003fcb3f2eab13,0x0000cff1ae2740f8}, {0x000b749d4cee1172,0x000b2036d909e0e7,0x0004d4c388e9f275,0x0000fcae34e31d8f,0x00002b37f69f7513}}, + {{0x000f1fdb40146044,0x00094941507883e0,0x000792efea8ce991,0x00015b42375b7541,0x0000f59bf5cd7d45}, {0x000324f923a277d8,0x000ce50f3406ac4f,0x00039bc51d9bc9b7,0x00008f46fa87d18a,0x00002588530dccc1}}, + {{0x0003c9f82e4c6346,0x0003da4464f85ced,0x0001dca258efb831,0x00012b8706381b7a,0x0000cd15a3cba2a4}, {0x000a8fdbfcd8fb51,0x000f5e54cd229347,0x000d8932f31db2ee,0x0001afb4aeb11ef8,0x00001e7c1ed44441}}, + {{0x000050cdc9a151e9,0x0007abb0a8592653,0x0005691e79edbfc0,0x00019a026c81c7fd,0x0000c1b2342ff390}, {0x0001c8b7f8474b9c,0x00064176181964a8,0x000e0375a90657c0,0x00047c790b333155,0x0000676c62776ebc}}, + {{0x0003247b7d6dee80,0x0007796593135162,0x000ab35ed0948d92,0x00040899700161e9,0x00006cc32b48ddde}, {0x000d664061ef338c,0x00020202e9ed6f2f,0x0009ba99b1606fa0,0x000f6895388bc192,0x00004428c5ede81d}}, + {{0x00028aef91b0b2ab,0x0003403dfd3fce20,0x000ffe8edce870a2,0x000bffb6ec2c870a,0x0000205fb46d84d0}, {0x000ffe744cefa48d,0x0007d19876d7bf5d,0x000b72863b6fc37a,0x00074eeecfa84c08,0x00007205ff5f5763}}, + {{0x0000d328887de41e,0x000ba69ea5348033,0x00056ea175de0df0,0x000a7733f427533c,0x0000b1f606a252b1}, {0x0004396e30ea15cb,0x0001114941255047,0x0006bb38f575816a,0x0000f70e1ce55bfe,0x0000901a94946ae3}}, + {{0x0000f08d8fc35489,0x0000473bfd08e5af,0x000fe655a5010b5d,0x0009fd093d288053,0x00009f2630bac130}, {0x0007bafb4e3b76fc,0x000bf840784bd867,0x0000092ce14e51dd,0x00020e726c750cbf,0x000083d306cb5283}}, + {{0x000671577d4715c5,0x00091b703235c445,0x00069e986d30019f,0x000c27d07ccb2ed6,0x00007c824b046dbf}, {0x000532fd8f92a230,0x00049bb98fd2f0eb,0x000e6199a4a557fd,0x0001eda57acea7c1,0x0000c6638208b94b}}, + {{0x000be8ff83a92661,0x0006f101bd459b42,0x000bd9cebc7741c9,0x00074485770c1107,0x0000f50250a9b2e0}, {0x000eec81477b6547,0x000da5efe59af762,0x00046a897c65b900,0x000d7c18c9614895,0x0000e8025b4330b4}}, + {{0x00065ef12045cf9f,0x000eaccce8bdae40,0x000cf65256fcb2ca,0x0003112fa0ba4ef2,0x0000683125ebb72c}, {0x000a4eae312410e0,0x00076cd8e830a01d,0x000fb3f0767e2867,0x0009a5abd9575298,0x00005f11e11eef64}}, + {{0x000faef9d3472c26,0x0007677d1345ba47,0x00015afee3adff69,0x000461e761fa04dd,0x00004f1f61b19e69}, {0x0001fab9bfb9093f,0x000eb1133dfefa69,0x000cc710d3df8ae8,0x000e78dd5f896758,0x0000bb88d5106c7f}}, + {{0x0001b4ce88c50d10,0x0007a8771c4f8e01,0x000278ee47532e80,0x00072a64c78a48e2,0x0000b283e8338450}, {0x000f29149e692749,0x00078868b21c98a6,0x000a8908eb96e966,0x00029ca8f0adc2b1,0x00000afcff7afeb8}}, + {{0x000a383210b08568,0x00025ef048899915,0x00064d509a5a8060,0x000f6f000e9af97c,0x00001382d0c38996}, {0x000ba5381927e27e,0x00016af50182490e,0x000ad62ce46c63b3,0x000735984c5fd9d3,0x00004fa1871d8ae8}}, + {{0x000d0bcd7466b255,0x000a8b235c654ec9,0x0003c168884ddbe1,0x0007470e2645ee16,0x000070bd00e50eba}, {0x000b629128bfa0f9,0x000cdc1d3b68fa51,0x0006778b192fce1b,0x0002baae7361dcb6,0x0000c7d249de561d}}, + {{0x00028bf0bbc6229b,0x000e2fd91497a40b,0x00083df051c83c05,0x000c9caf9f5154f0,0x0000ac38b3d9ee66}, {0x000b7e3ec0dfcfd2,0x000e6b0a8416f71d,0x00012aa66f2ecda8,0x00027232fddd8678,0x0000896ef106e6f4}}, + {{0x000186a0fe9a745f,0x000c59ca70dbff27,0x0001cac4908249fc,0x000f568425a2e644,0x00004a0885bdce5f}, {0x000b7317d7ead588,0x00059898d1046e2c,0x0002c9a89f96cf7d,0x0005bc2fe67c9d4f,0x00009895a509c7bf}}, + {{0x000b8e5573cecfa3,0x000ea15f03e6dc7c,0x00008442066497ea,0x0002b03bc0de693f,0x000023b9b36dcd53}, {0x000390a0115a3c12,0x000b0d65ca0ecfed,0x000530c789414c40,0x0008f2441406bd2f,0x00009369a44a3343}}, + {{0x00084f5903fa2711,0x0002a9da921e9968,0x000b01e54e6da0fd,0x00014e96f2f2695d,0x0000ee3e9bd78762}, {0x000181ce27a94979,0x0003fe215e04a26e,0x0002cabca36d254e,0x000613b2f32a6c25,0x0000948148810b57}}, + {{0x000fe6940d9cae17,0x000fa1a10f094c4d,0x00091b64b0586957,0x00053b5a287b5734,0x00007862d5dafd4a}, {0x000856e503491266,0x000111c5268fbf94,0x000b650a62be30bd,0x0009fcb0393f19cb,0x000039531fed78cf}}, + {{0x0006a11b29353593,0x00067f8c126e0255,0x00060167fda38aa9,0x0001cd17dbe6c209,0x00007bbabb680190}, {0x00079e02c9477784,0x00053a1a1dc6b6e9,0x0009faf0cd69a517,0x0005f083ed50959d,0x0000dd9c0965d5fa}}, + {{0x000304d64f16ea85,0x00062e718623a0c4,0x00067f03e8b1cac1,0x000c00bb5765467c,0x000059cf5ae1bd88}, {0x00077bb0e2af19ae,0x0000c1228c920748,0x0006e89201f717ec,0x00080390bcb80032,0x0000c6e2c5d2f312}}, + {{0x000ea7d3fca4752b,0x00087211f62a426a,0x000e7b6b5f12c094,0x00027c74beecd87b,0x000077eaf4ce6d7a}, {0x0002781fda78fd37,0x000fb64eeabe154c,0x000fe2bc4848a83a,0x000c2a11287ef04f,0x0000b6d88c726b6f}}, + {{0x000b947ce417d99b,0x0002db916cc4805f,0x0002733234b93dcc,0x00086dc2e65bb321,0x0000cc1bade1ea98}, {0x00030114bc5ee855,0x0004718ee1e40e22,0x000bcf1f1a561be7,0x000489262fd2d4a6,0x00000e6a5a4e5231}}, + {{0x000001fa00b500bb,0x000bad7dcdf5ca96,0x000446a855c098cf,0x000c61f64e2d2e8c,0x0000ae9bcf2471f3}, {0x00026838435a2c5b,0x000b9bad46434ec2,0x000ccf4e38ceaed6,0x00021e39f8fb47cc,0x0000d4f3fa4cce3b}}, + {{0x000b110a3db32927,0x000a4536c66ad79f,0x00049e6a9e28a37d,0x0008e2b79ce87b8e,0x00000ccfe8e6dcec}, {0x000e4e03ba464b2d,0x000ddca9a3982193,0x0002c12ab0f39d60,0x0000f6ad7932aff8,0x00008ff50ee61e7e}}, + {{0x0001058fa28a7e00,0x00050bf5ec74ea96,0x000229666c726cf2,0x000799e74d55c8db,0x0000bd9abbfa57f5}, {0x000ef074dfc47b3a,0x00026c52f91d7479,0x000a8bde2d9c65fc,0x00027fee0283fe36,0x000032a8b5f1d4b7}}, + {{0x0007c6112e832330,0x0002dcc9bf286a67,0x000780f610fbb351,0x00089c562e8ea50d,0x0000db8b22b1dc4e}, {0x000d1fb89be01445,0x00067a57113b0a6f,0x00009c91c8c77d24,0x00024bf639075dff,0x0000b47b17fa0608}}, + {{0x000a2b016287b52d,0x000000cd8eb058ae,0x000d58573a134352,0x0008ad9148b4d0c5,0x0000d2b6170f91c6}, {0x00039291da3b3b75,0x0008b8c4ac10a61b,0x00017d5835f946d7,0x000e5df105d4a572,0x0000061da3d75e6d}}, + {{0x000940dec1b49919,0x0000a6f485ae3113,0x0001a2ee0f12195e,0x00096e17507fb273,0x00005057a8efe9e1}, {0x000c9112e1301367,0x0005c3c60d15a3c2,0x00000ee2b97dfbb3,0x0008b85af3c581b3,0x00007f25d9164bac}}, + {{0x0004f986d840cd64,0x0000a634288cdb1c,0x000c8a161471d62c,0x000ae24ec2f85ece,0x00001f37cbd3a6f4}, {0x000a20f4b7099851,0x000bdfa8985b6793,0x0008e64467a7bd33,0x0007c11c6a3fbd93,0x000090426193a8d4}}, + {{0x0008667cc36975fb,0x0007ed5f1dfb1684,0x0003baa9402acf16,0x00066fb2d41ad461,0x000056fbb934f684}, {0x0000d0de9e405698,0x000eb5489fefce61,0x000f18b977b99c65,0x000eda8c88ad1b3d,0x00001b7d9bedd0e9}}, + {{0x00018c0c716cc0a1,0x000075691c49d852,0x000356ac6f4b5ff9,0x000a7a94fd666bce,0x00007c728955b327}, {0x0005085da6be7de9,0x000da301d34ef93d,0x000f448e8ff71530,0x000ff9bcd96442d8,0x0000283d331bed18}}, + {{0x000dd992a8498705,0x000af15763354d33,0x0009be0e5a716964,0x000632af5e3a9b17,0x0000b9d6b1bd3b13}, {0x000d7d4a52f313bc,0x000fa37a46603b8b,0x0003e218fc9dd959,0x000a3b700359620b,0x0000e1481a487b28}}, + {{0x000b43a43228d831,0x00003ad63f99ab41,0x000a5122924ae1c3,0x0002b47e525f1a46,0x00004af860fdd26d}, {0x000ef613f714aa18,0x000d6b78795ed6ba,0x000a9d694f51865a,0x00052753e21fcee6,0x00002ceb1de0a37b}}, +} +}; + +#endif /* IFMA_ECPRECOMP7_P256_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_ed25519.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_ed25519.h new file mode 100644 index 000000000..9a96a73a7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_ed25519.h @@ -0,0 +1,159 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ED25519_H +#define IFMA_ED25519_H + +#include + +/* homogeneous: (X:Y:Z) satisfying x=X/Z, y=Y/Z */ +typedef struct ge52_homo_mb_t { + fe52_mb X; + fe52_mb Y; + fe52_mb Z; +} ge52_homo_mb; + +/* extended homogeneous: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT */ +typedef struct ge52_mb_t { + fe52_mb X; + fe52_mb Y; + fe52_mb T; + fe52_mb Z; +} ge52_ext_mb; + +/* copmpleted: (X:Y:Z:T) satisfying x=X/Z, y=Y/T */ +typedef struct ge52_p1p1_mb_t { + fe52_mb X; + fe52_mb Y; + fe52_mb T; + fe52_mb Z; +} ge52_p1p1_mb; + +/* scalar precomputed group element: (y-x:y+x:2*t*d), t=x*y, ed25519 parameter d = -(121665/121666)*/ +typedef struct ge52_precomp_t { + fe52 ysubx; + fe52 yaddx; + fe52 t2d; +} ge52_precomp; + +/* mb precomputed group element: (y-x:y+x:2*t*d), t=x*y, ed25519 parameter d = -(121665/121666)*/ +typedef struct ge52_precomp_mb_t { + fe52_mb ysubx; + fe52_mb yaddx; + fe52_mb t2d; +} ge52_precomp_mb; + +/* projective falvor of the ge52_precomp_mb */ +typedef struct ge52_cached_mb_t { + fe52_mb YsubX; + fe52_mb YaddX; + fe52_mb T2d; + fe52_mb Z; +} ge52_cached_mb; + +/* bitsize of compression point */ +#define GE25519_COMP_BITSIZE (P25519_BITSIZE+1) + +/* +// conversion +*/ + +/* ext => homo */ +__INLINE void ge52_ext_to_homo_mb(ge52_homo_mb*r, const ge52_ext_mb* p) +{ + fe52_copy_mb(r->X, p->X); + fe52_copy_mb(r->Y, p->Y); + fe52_copy_mb(r->Z, p->Z); +} + +/* p1p1 => homo */ +__INLINE void ge52_p1p1_to_homo_mb(ge52_homo_mb *r, const ge52_p1p1_mb *p) +{ + fe52_mul(r->X, p->X, p->T); + fe52_mul(r->Y, p->Y, p->Z); + fe52_mul(r->Z, p->Z, p->T); +} + +/* p1p1 => ext */ +__INLINE void ge52_p1p1_to_ext_mb(ge52_ext_mb *r, const ge52_p1p1_mb *p) +{ + fe52_mul(r->X, p->X, p->T); + fe52_mul(r->Y, p->Y, p->Z); + fe52_mul(r->T, p->X, p->Y); + fe52_mul(r->Z, p->Z, p->T); +} + + +/* set GE to neutral */ +__INLINE void neutral_ge52_homo_mb(ge52_homo_mb* ge) +{ + fe52_0_mb(ge->X); + fe52_1_mb(ge->Y); + fe52_1_mb(ge->Z); +} +__INLINE void neutral_ge52_ext_mb(ge52_ext_mb* ge) +{ + fe52_0_mb(ge->X); + fe52_1_mb(ge->Y); + fe52_0_mb(ge->T); + fe52_1_mb(ge->Z); +} +__INLINE void neutral_ge52_precomp_mb(ge52_precomp_mb *ge) +{ + fe52_1_mb(ge->ysubx); + fe52_1_mb(ge->yaddx); + fe52_0_mb(ge->t2d); +} +__INLINE void neutral_ge52_cached_mb(ge52_cached_mb* ge) +{ + fe52_1_mb(ge->YsubX); + fe52_1_mb(ge->YaddX); + fe52_0_mb(ge->T2d); + fe52_1_mb(ge->Z); +} + +/* move GE under mask (conditionally): r = k? a : b */ +__INLINE void ge52_cmov1_precomp_mb(ge52_precomp_mb* r, const ge52_precomp_mb* b, __mb_mask k, const ge52_precomp* a) +{ + fe52_cmov1_mb(r->ysubx, b->ysubx, k, a->ysubx); + fe52_cmov1_mb(r->yaddx, b->yaddx, k, a->yaddx); + fe52_cmov1_mb(r->t2d, b->t2d, k, a->t2d); +} +__INLINE void cmov_ge52_precomp_mb(ge52_precomp_mb* r, const ge52_precomp_mb* b, __mb_mask k, const ge52_precomp_mb* a) +{ + fe52_cmov_mb(r->ysubx, b->ysubx, k, a->ysubx); + fe52_cmov_mb(r->yaddx, b->yaddx, k, a->yaddx); + fe52_cmov_mb(r->t2d, b->t2d, k, a->t2d); +} +__INLINE void cmov_ge52_cached_mb(ge52_cached_mb* r, const ge52_cached_mb* b, __mb_mask k, const ge52_cached_mb* a) +{ + fe52_cmov_mb(r->YsubX, b->YsubX, k, a->YsubX); + fe52_cmov_mb(r->YaddX, b->YaddX, k, a->YaddX); + fe52_cmov_mb(r->T2d, b->T2d, k, a->T2d); + fe52_cmov_mb(r->Z, b->Z, k, a->Z); +} + + +/* private functions */ +void ifma_ed25519_mul_basepoint(ge52_ext_mb* r, const U64 scalar[]); +void ifma_ed25519_mul_point(ge52_ext_mb* r, const ge52_ext_mb* p, const U64 scalar[]); +void ifma_ed25519_prod_point(ge52_ext_mb* r, const ge52_ext_mb* p, const U64 scalarP[], const U64 scalarG[]); + +void ge52_ext_compress(fe52_mb fe, const ge52_ext_mb* p); +__mb_mask ge52_ext_decompress(ge52_ext_mb* p, const fe52_mb fe); + +#endif /* IFMA_ED25519_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_n25519.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_n25519.h new file mode 100644 index 000000000..f284d69e2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_n25519.h @@ -0,0 +1,32 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_N25519_H +#define IFMA_ARITH_N25519_H + +#include +#include + +/* bitsize of base point order */ +#define N25519_BITSIZE (253) +#define NE_LEN52 NUMBER_OF_DIGITS(N25519_BITSIZE, DIGIT_SIZE) +#define NE_LEN64 NUMBER_OF_DIGITS(N25519_BITSIZE, 64) + +void ifma52_ed25519n_madd(U64 r[NE_LEN52], const U64 a[NE_LEN52], const U64 b[NE_LEN52], const U64 c[NE_LEN52]); +void ifma52_ed25519n_reduce(U64 r[NE_LEN52], const U64 x[NE_LEN52 * 2]); + +#endif /* IFMA_ARITH_N25519_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_p25519.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_p25519.h new file mode 100644 index 000000000..dab13725e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_arith_p25519.h @@ -0,0 +1,154 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_P25519_H +#define IFMA_ARITH_P25519_H + +#include +#include + +/* +// prime25519 = 2^255-19 +// in the radix 2^52 +// int64u prime25519[5] = {PRIME25519_LO, PRIME25519_MID, PRIME25519_MID, PRIME25519_MID, PRIME25519_HI} +*/ +#define PRIME25519_LO 0x000FFFFFFFFFFFED +#define PRIME25519_MID 0x000FFFFFFFFFFFFF +#define PRIME25519_HI 0x00007FFFFFFFFFFF + + +/* underlying prime bitsize */ +#define P25519_BITSIZE (255) + +/* lengths of FF elements */ +#define FE_LEN52 NUMBER_OF_DIGITS(P25519_BITSIZE, DIGIT_SIZE) +#define FE_LEN64 NUMBER_OF_DIGITS(P25519_BITSIZE, 64) + +/* scalar field element (FE)*/ +typedef int64u fe64[FE_LEN64]; +typedef int64u fe52[FE_LEN52]; + +/* mb field element */ +typedef U64 fe64_mb[FE_LEN64]; +typedef U64 fe52_mb[FE_LEN52]; + + +/* set FE to zero */ +__INLINE void fe52_0_mb(fe52_mb fe) +{ + fe[0] = fe[1] = fe[2] = fe[3] = fe[4] = get_zero64(); +} +/* set FE to 1 */ +__INLINE void fe52_1_mb(fe52_mb fe) +{ + fe[0] = set1(1LL); + fe[1] = fe[2] = fe[3] = fe[4] = get_zero64(); +} + +/* copy FE */ +__INLINE void fe52_copy_mb(fe52_mb r, const fe52_mb a) +{ + r[0] = a[0]; + r[1] = a[1]; + r[2] = a[2]; + r[3] = a[3]; + r[4] = a[4]; +} + +/* convert fe52_mb => fe64_mb */ +__INLINE void fe52_to_fe64_mb(fe64_mb r, const fe52_mb a) +{ + r[0] = xor64(slli64(a[1],52), a[0]); + r[1] = xor64(slli64(a[2],40), srli64(a[1],12)); + r[2] = xor64(slli64(a[3],28), srli64(a[2],24)); + r[3] = xor64(slli64(a[4],16), srli64(a[3],36)); +} + +/* check if FE is zero */ +__INLINE __mb_mask fe52_mb_is_zero(const fe52_mb a) +{ + U64 t = or64(or64(a[0], a[1]), or64(or64(a[2], a[3]), a[4])); + return cmpeq64_mask(t, get_zero64()); +} + +/* check if a==b */ +__INLINE __mb_mask fe52_mb_is_equ(const fe52_mb a, const fe52_mb b) +{ + __ALIGN64 fe52_mb t; + t[0] = xor64(a[0], b[0]); + t[1] = xor64(a[1], b[1]); + t[2] = xor64(a[2], b[2]); + t[3] = xor64(a[3], b[3]); + t[4] = xor64(a[4], b[4]); + return fe52_mb_is_zero(t); +} + +/* move FE under mask (conditionally): r = k? a : b */ +__INLINE void fe52_cmov1_mb(fe52_mb r, const fe52_mb b, __mb_mask k, const fe52 a) +{ + r[0] = mask_mov64(b[0], k, set1(a[0])); + r[1] = mask_mov64(b[1], k, set1(a[1])); + r[2] = mask_mov64(b[2], k, set1(a[2])); + r[3] = mask_mov64(b[3], k, set1(a[3])); + r[4] = mask_mov64(b[4], k, set1(a[4])); +} +__INLINE void fe52_cmov_mb(fe52_mb r, const fe52_mb b, __mb_mask k, const fe52_mb a) +{ + r[0] = mask_mov64(b[0], k, a[0]); + r[1] = mask_mov64(b[1], k, a[1]); + r[2] = mask_mov64(b[2], k, a[2]); + r[3] = mask_mov64(b[3], k, a[3]); + r[4] = mask_mov64(b[4], k, a[4]); +} + +/* swap FE under mask (conditionally): r = k? a : b */ +__INLINE void cswap_U64(U64* x, __mb_mask k, U64* y) +{ + *x = _mm512_mask_xor_epi64(*x, k, *x, *y); + *y = _mm512_mask_xor_epi64(*y, k, *y, *x); + *x = _mm512_mask_xor_epi64(*x, k, *x, *y); +} +__INLINE void fe52_cswap_mb(fe52_mb a, __mb_mask k, fe52_mb b) +{ + cswap_U64(&a[0], k, &b[0]); + cswap_U64(&a[1], k, &b[1]); + cswap_U64(&a[2], k, &b[2]); + cswap_U64(&a[3], k, &b[3]); + cswap_U64(&a[4], k, &b[4]); +} + + +void fe52_mb_add_mod25519(fe52_mb vr, const fe52_mb va, const fe52_mb vb); +void fe52_mb_sub_mod25519(fe52_mb vr, const fe52_mb va, const fe52_mb vb); +void fe52_mb_neg_mod25519(fe52_mb vr, const fe52_mb va); +void fe52_mb_mul_mod25519(fe52_mb vr, const fe52_mb va, const fe52_mb vb); +void fe52_mb_sqr_mod25519(fe52_mb vr, const fe52_mb va); +void fe52_mb_inv_mod25519(fe52_mb vr, const fe52_mb va); +void fe52_pow_2_252m3_mod25519(fe52_mb vr, const fe52_mb va); +void fe52mb8_red_p25519(fe52_mb r, const fe52_mb a); + +#define fe52_add fe52_mb_add_mod25519 +#define fe52_sub fe52_mb_sub_mod25519 +#define fe52_neg fe52_mb_neg_mod25519 +#define fe52_mul fe52_mb_mul_mod25519 +#define fe52_sqr fe52_mb_sqr_mod25519 +#define fe52_inv fe52_mb_inv_mod25519 +#define fe52_p2n fe52_mb_sqr_mod25519_times +#define fe52_p2_252m3 fe52_pow_2_252m3_mod25519 +#define fe52_red fe52mb8_red_p25519 + +#endif /* IFMA_ARITH_P25519_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_ed25519_precomp4.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_ed25519_precomp4.h new file mode 100644 index 000000000..e85315ef9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/ifma_ed25519_precomp4.h @@ -0,0 +1,351 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ED25519_PRECOMP_H +#define IFMA_ED25519_PRECOMP_H + +#include + +#define MUL_BASEPOINT_WIN_SIZE (4) + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE +#define BP_N_ENTRY (1<<(BP_WIN_SIZE-1)) + +__ALIGN64 static ge52_precomp ifma_ed25519_bp_precomp[][BP_N_ENTRY] = { +{ /* slot=0 [{1,2,3,..,8} * 16^(2*0)] * G) */ +{{0x00003905d740913e,0x00005d140beb39d1,0x00088f8a09fd399f,0x0001267a5c184346,0x000044fd2f9298f8}, {0x000c93c6f58c3b85,0x000c6fb8c0e192fb,0x00043d42c2cf932d,0x000ba65270b48986,0x000007cf9d3a33d4}, {0x00091205877aaa68,0x00023ccaac49eabc,0x000d43598c26d9e8,0x00065a85a1b7dcbd,0x00006f117b689f0c}}, +{{0x0009a56042b4d5a8,0x0000c4e60acf68a9,0x00016e37aa8f2b81,0x0002555e09e236bb,0x00006bb595a669c9}, {0x0004e7fc933c71d7,0x000967a0ff5b5922,0x0001d607029f469d,0x0002e2e5aa69a65e,0x0000590c063fa87d}, {0x000aa8b3a59b7a5f,0x000dd5d9acf7843f,0x000b3d6a3136c16b,0x0000b73500fa0840,0x0000701af5b13ea5}}, +{{0x00011fe8a4fcd265,0x000fde5c1ba7d566,0x00014bd6bd3bd353,0x000da628131f31a2,0x00002ab91587555b}, {0x0005b0a84cee9730,0x00030e8864b8aaf2,0x000f016732025a84,0x000f8f4c11b50029,0x00007a164e1b9a80}, {0x000e933f0dd0d889,0x000221c35da6214a,0x000cf2db4c589423,0x000b4c6d170e5458,0x00005a2826af12b9}}, +{{0x000e050a056818bf,0x000715660faa995f,0x0006a05073327e89,0x000a49ac3e8e3cd0,0x000027933f4c7445}, {0x000351b98efc099f,0x000f47dfd2538287,0x000b0a92656765c6,0x0008727ca348d3df,0x0000680e910321e5}, {0x0003fbe9c476ff09,0x000457b5cc1725a1,0x00002b44946e9e39,0x0003e2b5ddbdcf91,0x00007f9d0cbf6355}}, +{{0x000182c3a447d6ba,0x000d14b2729b77f9,0x000864a087d50014,0x00055f3e33cf11cb,0x0000154a7e73eb1b}, {0x0002bc4408a5bb33,0x000c3c75eed02a21,0x000abfec448d5048,0x00006ebdd1beb0c5,0x00002945ccf146e2}, {0x000bdbf1812a8285,0x00007d0bdd1fcbcb,0x000bbda72d270e08,0x000b69ab41b670b1,0x000043aabe696b3b}}, +{{0x000806b67b7d8ca4,0x0008427d22739499,0x00004553b9575be2,0x0007884bb085ce72,0x000038b64c41ae41}, {0x000ceeeb77157131,0x0008900c8af883a0,0x000a59a7369b2715,0x00038bd8065b668d,0x000051e57bb6a2cc}, {0x000c326702ea4b71,0x0000341a1bb0185a,0x00083bc144be70e0,0x00061e353e4a24b0,0x000010b8e91a9f0d}}, +{{0x000f2c9aaa3221b1,0x000533bba23a7ba6,0x0002192c3a6ca021,0x00017e09dea764f9,0x00001d6edd5d2e53}, {0x000a5cd0944ea3bf,0x0003ab39dc0d26b1,0x0008542e49747035,0x000927e71b252822,0x0000461bea69283c}, {0x00036dc801b8b3a2,0x00047053ea49af18,0x000877adf3b3035f,0x00090a7529c41ba5,0x00007a9fbb1c6a0f}}, +{{0x00075dedf39234d9,0x00080e1b558f9e2a,0x000e3c23fb963d76,0x00001c32c2741ac6,0x00003a9024a1320e}, {0x0007596604dd3e8f,0x00077e288702c59b,0x000ed9c3236cb303,0x000e52fb1339c665,0x00000915e76061bc}, {0x0001f5d9c9a2911a,0x000788bcca7d7e7c,0x000eb62a32b8a371,0x0004e95636412190,0x000026907c5c2ecc}}, +}, +{ /* slot=1 [{1,2,3,..,8} * 16^(2*1)] * G) */ +{{0x000b635449aa515e,0x0009f0bc6823aed5,0x000b42d1c4a865c4,0x00015b9850c1fe95,0x000030d76d6f03d3}, {0x000cdd0e632f9c1d,0x00096768931152ec,0x0008637a5851d0b6,0x000ef3952dfb76ba,0x00006dd37d49a00e}, {0x000444172106e4c7,0x00080928d7f696c4,0x00094d3f26fb53d6,0x0004bb0b4739ea46,0x000010c697112e86}}, +{{0x0003c4277dbe5fde,0x000ad19ad7ea2649,0x0006304590265d4f,0x000fe090e00dfc84,0x000025e61cabed66}, {0x00062aa08358c805,0x000e37a2042470ca,0x000b11eddc6a3d4a,0x00006ef7464d3a63,0x000003bf9baf5508}, {0x0003e128cc586604,0x000ecb459747e3f1,0x000c1268f56f5873,0x000e22ca0b63dedc,0x0000566d78634586}}, +{{0x0007a49f9cc10834,0x000d5a89bc451163,0x000f7fd2dbbc8e56,0x00035d91cb5ec0f7,0x000033975bca5ecc}, {0x00054285c65a2fd0,0x0002af31667c3a10,0x00031aee586c6411,0x000b22a680ae2407,0x000014fba5f34793}, {0x000746166985f7d4,0x00084c9c800573cd,0x000b61131e593e5e,0x000526c2fc3f2b67,0x000014829cea83fc}}, +{{0x00037b8497dd95c2,0x00030aa4eb5a7ff4,0x000c85e88b6c744e,0x00081739e0c5d613,0x00002fd9c71e5f75}, {0x00070b2f4e71ecb8,0x000b940a477e321e,0x000e1d4f80e656dd,0x0007b7ebf6556cec,0x000005fc3bc4535d}, {0x0008b3ae52afdedd,0x0008ced3b30cf24b,0x0009be8195349563,0x0001f0433a4bc83a,0x0000373767475c65}}, +{{0x000a99fd40d1add9,0x0006f96f4d0272fb,0x0005f03baeb30716,0x000f9994363f0521,0x00001fbea56c3b18}, {0x000095cb14246590,0x0004016c15535634,0x000910bc60ef1214,0x0007c8c9e38140c8,0x00006bf590573090}, {0x000778f1e1415b8a,0x000f7bac3a77e0fa,0x000aa29a5006409f,0x0005a566f52d7b89,0x000002521cf67a63}}, +{{0x000fee0b0a9d5294,0x0005c0fdf5a66513,0x000fe107ce8f98e7,0x0002cedd4618688b,0x00003fa00a7e7138}, {0x00046720772f5ee4,0x000b196079aceb11,0x0000ac824ae8f894,0x0006cc44af8224d0,0x0000001753d9f7cd}, {0x0009232d963ddb34,0x000dab49738583c6,0x000091f2851dde87,0x000edb6aad7d1f9a,0x000012b5fe2fa048}}, +{{0x0000fbc496fce34d,0x0006badf35bed71f,0x000f28c56173b982,0x000206fd2047261f,0x0000749b76f96fb1}, {0x000b7c26ad6f1e92,0x00023504b8913df2,0x00051c8bc34b66d3,0x000c7b88c409dc07,0x00006f7e93c20796}, {0x000af604aea6ae05,0x000f1bee49c991f5,0x000eff6b66c12351,0x000215161a808b5e,0x00000fcec10f01e0}}, +{{0x000d58a649fe1e44,0x000a231ad777e644,0x00087fd0d221fcae,0x00011f302441c5a8,0x00004901aa7183c5}, {0x0002d29dc4244e45,0x0007493d8de0a3df,0x00020c214d2b020e,0x000b90a6cc8067e8,0x0000413779166fea}, {0x0001b7548c1af8f0,0x0007c246299b408b,0x000e06d939ce0f7a,0x0001213f760b0f91,0x000041bb887b726d}}, +}, +{ /* slot=2 [{1,2,3,..,8} * 16^(2*2)] * G) */ +{{0x00087d44744346be,0x000d415b52b2540e,0x00013b603e1d48da,0x000bdf77c3a8a18a,0x00004eb728c12fcd}, {0x00034c597c6691ae,0x0003d0a85b4c87e2,0x00054afae764889d,0x0009e1ddae2c90c3,0x00000a871e070c6a}, {0x0001b5994bbc8989,0x0003a5bdd4260330,0x0009d59e3c736bae,0x000d4640d61ade21,0x00003ee7300f2685}}, +{{0x000255e49e7dd6b7,0x0005c610b1eacf5d,0x0002e187ca801611,0x00025c23c99975d9,0x0000138157629791}, {0x000a7947841e7518,0x00059639c46d743f,0x0003052b74e5c6fa,0x0009030a1065e1de,0x00007d47c6a2cfb8}, {0x000ad0148ef0d6e0,0x0009a91546f3c3fd,0x0006bb81579d3e74,0x000ec8071ec62102,0x0000148cf58d34c9}}, +{{0x000492f67934f027,0x000bef6840aa946a,0x0009611854469984,0x000bbd45ca1bc2a8,0x00003ff2fa1ebd5d}, {0x00072f7d9ae4756d,0x000bb88f3487fe25,0x000960a88d56c345,0x000a1b99fd10b6d6,0x0000278febad4eae}, {0x000a681f8c933966,0x0009c20290c98b1a,0x00019d3c528c2194,0x000677b391152912,0x00004104dd02fe9c}}, +{{0x0002bf5e1124422a,0x0003398a33ab572b,0x000a52b666a1fa0c,0x00053d594cb6101f,0x00002c863b00afaf}, {0x00014e06db096ab8,0x000c90ce44f35812,0x00009e2af521a8b6,0x000a4816524c12a4,0x00000165b5a48efc}, {0x0000a474a0846a76,0x00084cd2f7cc0f19,0x0008aa2b8f12eff9,0x000c8b8695e29065,0x0000591b67d9bffe}}, +{{0x000f0d1c80b49bfa,0x0005eabf3ec8a312,0x000ef01c88597951,0x0007bcb727033c09,0x00003de02ec7ca8f}, {0x0009b3719f18b55d,0x000faa18c641e99b,0x00029f05ede465e5,0x000128b61081136c,0x0000489b4f867030}, {0x0002102d3aeb92ef,0x000b46116a861d23,0x00090baa24e16253,0x000bebf3d7eabe71,0x000049f5fbba496c}}, +{{0x00049a108a5bcfd4,0x00070bc6473eb309,0x00007c0d1cdc40dd,0x0006e7492c294c13,0x00005604a86dcbfa}, {0x000d628c1e9c572e,0x000acc5884741155,0x00015763eb8a4d86,0x000515b91a352f65,0x000006a1a6c28867}, {0x0008d1d47c1764b6,0x00040e0418b51728,0x0008acf6d1725411,0x00042c69f031a601,0x000020989e89fe27}}, +{{0x000777fd3a2dcc7f,0x0002ca54fd892499,0x000207e3a032857c,0x0007e29a279d864d,0x00000403ed1d0ca6}, {0x0004278b85eaec2e,0x000077acb2bdf167,0x0001cbf45a5621dc,0x00095d3640a4c166,0x0000730b9950f705}, {0x000b2d35874ec552,0x000cf98246f8dc94,0x0006c035cec5e6c8,0x0003dccf7cb46fa1,0x00005bd745430830}}, +{{0x000ad19528b24cc2,0x000656335c1817f9,0x000fc072367f6b54,0x000ad8366b8b66e4,0x0000133a78007380}, {0x0004932115e7792a,0x000a2bdcdddc985c,0x000da3d762c64c89,0x000f82c9d1e3da8a,0x00005bb7db123067}, {0x0001f467c6ca62be,0x000d6211952ee096,0x000bd5477004ec21,0x000e0d2182360779,0x0000740dca6d58f0}}, +}, +{ /* slot=3 [{1,2,3,..,8} * 16^(2*3)] * G) */ +{{0x0008ee0752cfce4e,0x000f306ec08b7df4,0x00095459c4c3fffa,0x000a38d05710b2ab,0x0000161d25fa963e}, {0x000a8c570478433c,0x0000ec281439d231,0x0003d9079fb7b527,0x00003d9dbaa99eae,0x00002c03f5256c2b}, {0x000f18757b53a47d,0x00030cf0c5879790,0x00057ef7f9307b01,0x000bbaf31903d772,0x0000699468bdbd96}}, +{{0x000f2f46f4dafecf,0x00014a47fd6f7bd1,0x000a47b37f7cef01,0x0005785d31ffdda4,0x0000525219a47390}, {0x000d3de66aa91948,0x000c22fc0d2ccd8d,0x0004fdea2f485064,0x0002e3a9b4824663,0x0000293e1c4e6c4a}, {0x000e134b925112e1,0x000b5dca15da0376,0x00061c3111703778,0x0002823b04589af4,0x00005b605c447f03}}, +{{0x0005805920c47c89,0x0000c923b8fccb96,0x0002e2ef77e7f010,0x000b3ee000125650,0x000024a76dcea8ae}, {0x0009fec6f0e7f04c,0x0009e75e349623be,0x000e1de61a866a57,0x000bdd55542ef161,0x00002f12fef4cc5a}, {0x000522b2dfc0c740,0x0007f40c9a4070a4,0x0008cff66810d06e,0x0003790c6cf14417,0x00005e607b2518a4}}, +{{0x00031d8f6cdf1818,0x0004fc36258a258b,0x0006e61d6e35cfa7,0x000d5f7e1b3ff4f6,0x00005067acab6ccd}, {0x000c431ca596cf14,0x00040aed3e400a02,0x000e0f26dbe3c42d,0x0007068d24526802,0x0000201f33139e45}, {0x00027f6b08039d51,0x00064017c0006fd5,0x000e25a4a818b149,0x0000375d5220eb02,0x0000397cba886246}}, +{{0x00013093f05959b2,0x0008de9a9797630c,0x00021d5e26e23aa1,0x0006c3a222fd4917,0x00002339d320766e}, {0x0005c3fbc81379e7,0x00020dde12af1781,0x0005a8fdd5a66194,0x000c252ffa9c0f88,0x0000771b4022c1e1}, {0x000dd986513a2fa7,0x00071f9d4cf08d87,0x000ea283b3f5ac9b,0x0001a76d06bc31b1,0x0000331a18921997}}, +{{0x00066f45fb4f80c6,0x000de61c775cff51,0x000041d91c9c36c7,0x000fe21e3d4e81b9,0x000031167c6b83bd}, {0x00012f3a9d7572af,0x0008868074a9e265,0x000180f7c45bcbe2,0x000a67b84edc1c11,0x00001ac9619ff649}, {0x000b3842524b1068,0x0003bee9ce987f22,0x000a6250c8506834,0x000b111fc9d71844,0x0000612436341f08}}, +{{0x000d41db874e898d,0x000f16c07dc20d99,0x00000f9bbc09fea5,0x000ff40793d2c67d,0x000046ebe2309e5e}, {0x000349e31a2d2638,0x000009bd3fd358b6,0x0003a06ba49ddfb7,0x00004457f8bf1b8a,0x00001522aa3178d9}, {0x00082f5369614938,0x0009ab72d6d102c3,0x000646f227dafe40,0x000306ce8c83391b,0x000045fe70f50524}}, +{{0x000875a6960c0b8c,0x00076ef0e2f20da4,0x000d0b8fd45b68d0,0x00092d407fb51cf3,0x0000428d1623a0e3}, {0x00024920c8951491,0x000c83f630ca262f,0x0005c9d4b805f007,0x00022456fbb45d2f,0x000016619f6db57a}, {0x000f4a4401a308fd,0x000c376a5caac084,0x0003d1bc7da82219,0x00038c6deb8de464,0x00001d81592d60bd}}, +}, +{ /* slot=4 [{1,2,3,..,8} * 16^(2*4)] * G) */ +{{0x00068756a60dac5f,0x0006aebabdc57613,0x000cce0f7d17e02f,0x000dcf07f193f2d4,0x000020234a7789ec}, {0x0005b69f7b85c5e8,0x0008bd168bab2876,0x000d330f9b6ff067,0x0008e7c3a70e77c1,0x00003a5f6d51b0af}, {0x00020db67178b252,0x000f9d51ed16076d,0x0003e41170071c34,0x000e366f62a4a20b,0x00007cd682353cff}}, +{{0x0001a45bd887fab6,0x00032ba403b6e0be,0x00096e60002a846a,0x0000943d9921012e,0x00002838c8863bdc}, {0x0005cd6068acf4f3,0x000183cd7e3d3a66,0x00036025d942d92d,0x000d8ff5759389d3,0x00003ef0253b2b2c}, {0x000bb0cf4a465030,0x0004115c577abd16,0x0004ab419dfa496b,0x000281282cfae8af,0x000021dcb8a606a8}}, +{{0x000004468c9d9fc8,0x0006ed42aa3cb5c6,0x0002ee2f9c254009,0x0001dab125b4d4c1,0x00000bc3d08194a3}, {0x000d00fabe7731ba,0x0007e629e18899a8,0x0003f3d97f820360,0x000678bb2cc02374,0x00005d840dbf6c6f}, {0x000e380d309fe18b,0x000a6b9e165c7706,0x000dae20ab6eb02d,0x00096dd57bbba997,0x00003a4276232ac1}}, +{{0x0002432c8a7084fa,0x000e3dfb9e5454b4,0x000c58e45d898a19,0x000ebd1be9f00219,0x00001ff177cea16d}, {0x0008c172db447ecb,0x0001fc6282dbd3bf,0x0005aa15fe5fcfc4,0x000a9f980acffc07,0x00000770c9e824e1}, {0x0001d99a45b5b5fd,0x000e91b3a7924cf6,0x00003e3e89860984,0x0000b1ee73009193,0x000039f264fd4150}}, +{{0x000d3417dbe7e29c,0x0006a2b9c139ca7a,0x0003597ba9bd9437,0x0009840a0e91b8e9,0x00001712d7346888}, {0x000b4aabfe097be1,0x000e1dfe01929d19,0x000ca6f1ffa46dfc,0x000f14ec3c908942,0x000065c621272c35}, {0x000b89f8ce3193dd,0x00056a125c0bbe72,0x000e1cfe834d1033,0x000e2720419a93d2,0x000022f9800ab19c}}, +{{0x000a368a3e9ef8cb,0x00022a5504715605,0x000f24248fe3e9c0,0x00026e5553d48b05,0x000013f416cd6476}, {0x00029fdd9a6efdac,0x000be34a54941420,0x0007bdf37bb912ce,0x000cab4640f64b98,0x00004171a4d38598}, {0x000758aa99c94c8c,0x0006fb000b807fa2,0x000dda539223006f,0x000d1abfbd291dda,0x0000508214fa574b}}, +{{0x000269153ed6fe4b,0x00039511d77c4c20,0x000c14af94a65a67,0x000a74bcbde26462,0x000022f960ec6fab}, {0x000a15bb53d003d6,0x00088bcf3c965461,0x000c683a5ab21028,0x000b44727c576756,0x00003a7758a4c86c}, {0x000111f693ae5076,0x000df1dfd54a6548,0x0003115e651dae21,0x000f49412248c90f,0x00005d9fd15f8de7}}, +{{0x000408d36d63727f,0x000efd7c7b533031,0x000caee24b6a379a,0x000bed3a9e18fc5c,0x0000332f35914f8f}, {0x00044d2aeed7521e,0x00028432e96153f2,0x000e9c16d48e3a90,0x00098d8e164ba772,0x00003bc187fa47eb}, {0x00070115ea86c20c,0x000cb6c46d1256d4,0x000a660188998ab7,0x000ba03d77832b53,0x0000450d81ce906f}}, +}, +{ /* slot=5 [{1,2,3,..,8} * 16^(2*5)] * G) */ +{{0x000bb6a1a6205275,0x000d7413c8e836e7,0x00088f5cb2aa4f21,0x0005be16f56d155e,0x00002de25d4ba634}, {0x0004d8961cae743f,0x000f5ee1c63edd07,0x0007f4ed29f86d18,0x000b10897bdc55be,0x00004cbad279663a}, {0x00019024a0d71fcd,0x0000afb288af880d,0x000f3a6419c525c2,0x0007233b1a3974b5,0x00007d7fbcefe200}}, +{{0x000f1e6a266b2801,0x000c4d5739f16fae,0x000b03762c866c68,0x0005a8df68a2fbc1,0x00005975435e87b7}, {0x000c5dc5f3c29094,0x0009a2a9105abcd7,0x00021c3058c781a2,0x000d4d780c61d364,0x00004f9cd196dcd8}, {0x000297d86a7b3768,0x000241ad17a63199,0x000c1c0c17d0d058,0x0000307ba029cad5,0x00007ccdd084387a}}, +{{0x0006422c6d260417,0x00050948240bddca,0x000b68c677ae153d,0x000cf53a9c0c1b4f,0x0000428bd0ed61d0}, {0x000c84186760cc93,0x0007a1ab32a999b0,0x00020bda18cdae00,0x000ca44a88dec866,0x00003593ca848190}, {0x0003189a5e849aa7,0x0003565d8facd921,0x0003fdbbd1d4d8c3,0x00063e68c52545b5,0x000027398308da2d}}, +{{0x00038d28435ed413,0x000603278ccc942c,0x0009da03efbd50f3,0x0003355bb07ab1a7,0x0000269597aebe8c}, {0x00010e4c0a702453,0x00066d57d1bdeb9a,0x000d27daf70fa258,0x00033fdffb9d9b5c,0x0000572c2945492c}, {0x000fc745d6cd30be,0x000d3e3baaefbc77,0x000a5dda0ce4dfe8,0x000ca80a22c8830a,0x00007f985498c05b}}, +{{0x0009ce889f0be117,0x0001b7b54a288384,0x0003fc921c8005ad,0x000f3043da3c39f2,0x000076c2ec470a31}, {0x000615520fbf6363,0x00045cf4dfba6d35,0x00073fa0c208045a,0x00012e7eec24fbc8,0x000030f2653cd69b}, {0x0008c938aac10c85,0x00060db276bcb8a0,0x000e6fac7046179b,0x00073daa920c01e0,0x00002f1273f15964}}, +{{0x0009fc7c8ae01e11,0x000904a6aab9f473,0x0007728f2efd5274,0x00069f241d98a828,0x00005d9e572ad85b}, {0x00088bd755a70bc0,0x000a4f1d442e7304,0x000c59616206d6b5,0x000f784ead1a69eb,0x000038ac1997edc5}, {0x0006b517a751b13b,0x000867e9b858c066,0x00054dde49747d06,0x000e69cacacc0114,0x000022dfcd9cbfe9}}, +{{0x000bd2e0c30d0cd9,0x0005facbb43338dd,0x00022a961fad8e66,0x000c1c78f6b258c3,0x00006b2916c05448}, {0x000c59b4103be0a1,0x000ecd259f96956e,0x0003f5cd322ee3ba,0x000e472797cb2941,0x00000fe9877824cd}, {0x000b34d10aba913b,0x000822e6dac0e7ed,0x000578f8154ea3cd,0x0000a1766083dff6,0x00004c303f307ff0}}, +{{0x000a3bd617b28c85,0x000b739773bead30,0x000e6a5cbfc5d377,0x000b7c4c6c6e78c1,0x00000d61b8f78b2a}, {0x000c03580dd94500,0x000a46fbbec9329f,0x0002e2a7f8ecd27a,0x000a1d5130a155fc,0x0000416b151ab706}, {0x0008d7efe9c136b0,0x000cd58e44b2056a,0x000b57e0abbd07e5,0x000e8d2afe62fda1,0x0000191a2af74277}}, +}, +{ /* slot=6 [{1,2,3,..,8} * 16^(2*6)] * G) */ +{{0x0006f74bc53c1431,0x000ce2072eddece1,0x0005b23ee72b9725,0x000c908b8b9c36fb,0x00007e2e0e450b5c}, {0x00062b434f460efb,0x000d4a63607d69fe,0x0007a0da24ded303,0x0005b93f052210eb,0x0000237e7dbe0054}, {0x000575ed6701b430,0x000e69f0bfd10013,0x0003e47f22231094,0x00055e375320f158,0x000071afa699b111}}, +{{0x000e6f9b3953b61d,0x000eaafa141e665c,0x0009f759fec65839,0x000c28e0f435ffda,0x0000021142e9c2b1}, {0x00023c1c473b50d6,0x0001f3b38ef10ea4,0x0002c9be9551e87a,0x0009a1c9b84bf5fb,0x000000731fbc78f8}, {0x0000c71848f81880,0x000225ecec119e43,0x000bba15e3bf960c,0x0005808b6dae0836,0x00004c4d6f3347e1}}, +{{0x0007eccfc17d1fc9,0x000a651403c1418f,0x0007ee0cdf6c75f5,0x0007a22dbde712bf,0x0000193fddaaa7e4}, {0x000cddfc988f1970,0x00027b0b9f51b2f0,0x00079176be6b9162,0x0009fa86ec7b6c47,0x000038bf9500a88f}, {0x0002c93c37e8876f,0x0005a18d1462c1fd,0x0009241276a2f61e,0x00049695080f5823,0x00006a6fb99ebf0d}}, +{{0x0006c1bb560855eb,0x00038f893f09d6a4,0x000f71acc12416bb,0x00096ead71d11378,0x000075f76914a318}, {0x000122b5b6e423c6,0x00010f286ff8eeeb,0x000dcf5d8c939d70,0x000eb1090a92a831,0x0000136fda9f42c5}, {0x000cdfb1a305bdd1,0x0009d9ff82c08f94,0x0003bb588a0f364b,0x000dcba2a87d8a5c,0x0000022183510be8}}, +{{0x000766385ead2d14,0x00080ca7c58304af,0x0000211e3da08ed8,0x0006c030d13a6e61,0x00006a071ce17b80}, {0x000a710143307a7f,0x0009ec47da45f9d5,0x000e927ad3b063de,0x000426c22bbfe52b,0x00001387c441fd40}, {0x0003c3d187978af8,0x0003d7f0e4413b5d,0x000b477ca0722b5a,0x000dc920d7b4848b,0x00003171b26aaf1e}}, +{{0x000f319097564ca8,0x0004c2275e119a92,0x0004875150ff7bb8,0x000835a4f55fe37a,0x0000221fd4873cf0}, {0x000db7d8b28a47d1,0x000d61770a4f1a60,0x0003ddbd58a6bf14,0x00043e9d4a1f8935,0x00006c514a633442}, {0x0002204f3a156341,0x000e9ba0a032d232,0x00010f030efb73e0,0x0004aaafce0dd4c4,0x000048daa596fb92}}, +{{0x000a8e665ca59cc7,0x0004b2e38aca06ec,0x00021e17cea84725,0x0004af731afc708d,0x0000676dd6fccad8}, {0x00061d5dc84c9793,0x000e3ef41820614f,0x00046277ac9941f9,0x00079a9cdf5b88f3,0x000058c837fa0e8a}, {0x0009688596fc9058,0x000f37b56a01b0cf,0x000935d66a1ddcbb,0x0007f0adcc2e77d4,0x00001c4f73f2c6a5}}, +{{0x000a4fbd305fa0bb,0x000e054c663ad0e7,0x000fe33848829d4c,0x0004c42f421c3832,0x0000795ac80d1bf6}, {0x000e706efc7c3484,0x000b4c3c1cf61b36,0x00081cc7e573dfc9,0x000675ceb1d79c97,0x000070459adb7daf}, {0x0001db4991b42bb3,0x000234b02dcca1b9,0x000f8c78dc572696,0x0001fd39fdf9ee51,0x00005fe162848ce2}}, +}, +{ /* slot=7 [{1,2,3,..,8} * 16^(2*7)] * G) */ +{{0x0009214fe194961a,0x000c70d71cd4f4e5,0x000b50f22d49be7d,0x00072329300cfd23,0x00004789d446fc91}, {0x0009852d5d7cb208,0x00070687df2e7287,0x0001687891b8dedd,0x000aa35dc0bffab2,0x00002b44c043677d}, {0x000c87ab074eb78e,0x0008e99daf4671a1,0x00084f9067fac6d1,0x000a4e43eacbbcd4,0x000060c52eef2bb9}}, +{{0x000d89bc3bfd8bf1,0x00037c9f3551a0b5,0x00053028f5b06b92,0x000caab0e4c16b0d,0x000010bc9c312ccf}, {0x000bc5c27cae6d11,0x0009b54a48cab702,0x000a492eb244c769,0x000676defbc4056b,0x000070d77248d9b6}, {0x000ae84b3ec2a05b,0x000f4ed1781e0aa8,0x00008e85d198699e,0x000f413794513e47,0x000063755bd3a976}}, +{{0x000fa03e2ad10853,0x000909ee63569b55,0x000e69b890356f75,0x0006f849ff9f1fdb,0x00000d8cc1c48bc1}, {0x0007101897f1acb7,0x0005ec165bbd83dc,0x000fa1020f5dda7d,0x0002a56508e5b9c0,0x00002763751737c5}, {0x000402d36eb419a9,0x0007e77b460a5029,0x00043c4956f0b44e,0x00066e7cfa86230d,0x000070c2dd8a7ad1}}, +{{0x000194509f6fec0e,0x000a946c6518d656,0x0007e09b5cee2e7e,0x00084959733c1f36,0x00002e0fac636394}, {0x0004967db8ed7e13,0x0000ad776817a91d,0x000d85256474252f,0x0003ce5e40982e00,0x000032b8613816a5}, {0x0007f7bee448cd64,0x00067087886d079e,0x0000e4db2e6ac83a,0x0004f41f89fd4d9a,0x00004179215c735a}}, +{{0x000094e7d7dced2a,0x000c347d39c708c7,0x000906d90297fb8a,0x0009d76e13be033a,0x0000700344a30cd9}, {0x000e33b9286bcd34,0x000b6559dd6dce4a,0x0003d38e1fb7ef7e,0x000c286278b141fb,0x000031fa85662241}, {0x00026c422e3622f4,0x000879833502daf8,0x000b389123c12029,0x00024899bc1b7e12,0x000024bb2312a995}}, +{{0x0008ed1732de67c3,0x00018461b4948b1a,0x0006cfbcd23cb494,0x00080088ebd43437,0x00000fee3e871e18}, {0x00080c2af5f85c6b,0x000c304fa679441f,0x0003ba1bad687284,0x0005d168945df99a,0x00000d1d2af9ffeb}, {0x000a8aa132621edf,0x000a159226579a9d,0x00079ac19330b822,0x0001d764004197ba,0x000016acd7971853}}, +{{0x000f72af2d9b1d3d,0x00036a432245a72d,0x0006b3963763462a,0x00023093ecea0791,0x0000123e0ef6b930}, {0x0009c6c57887b6ad,0x000ad5f90febac95,0x000342f50494e19e,0x000170016e24e62a,0x0000164ed34b1816}, {0x000ed94c192fe69a,0x000ea3a911513487,0x0009a4de2761ae2c,0x000f3eb877bf6d3b,0x000078da0fc61073}}, +{{0x00015d28e52bc66a,0x0001870f01a8e5bf,0x0006c28bdd2c47e3,0x000173a2419afbc0,0x00002d25deeb256b}, {0x000f80f1680c3a94,0x000151ae9e7e6a29,0x000801797371f77e,0x0008ddd1100f1584,0x0000054aa4b316b3}, {0x0008468d19267cb8,0x0009c66e54dafdfc,0x00066eec170b2878,0x000a7602aeb1d2a6,0x0000134610a6ab7d}}, +}, +{ /* slot=8 [{1,2,3,..,8} * 16^(2*8)] * G) */ +{{0x00038ec78df6b0fe,0x00089e575f51b511,0x00017af1b95397da,0x000d65009207a1d7,0x00002102fdba2b20}, {0x000a65e777d1f515,0x000878faa60f1cd2,0x000abc06e5548991,0x000c9fbb1b73bbcd,0x0000654878cba97c}, {0x000ee405055ce6a1,0x000681251ad29969,0x000a7da41536bca7,0x000b2ba3a1af517a,0x00000ad725db29ec}}, +{{0x000267b1834e2457,0x000b570ce1bc5dc4,0x0007d15ed7b67544,0x00036501af07a0bf,0x00004aefcffb71a0}, {0x0007bc0c9b056f85,0x00068e7f5ffd7fec,0x000312aefa537d52,0x0009fd977afc6624,0x00004f675f530239}, {0x000d36360415171e,0x000118998483bc32,0x0000945110cd2bef,0x0006561870a6eadd,0x00000bccbb72a2a8}}, +{{0x000e962feab1a9c8,0x0003565147dcd185,0x000b5b6df286e7e6,0x000b73eb092e031b,0x00004024f0ab59d6}, {0x000d5e4c50fe1296,0x00082fee89f7e186,0x00007031b0e0397b,0x00037c23bc7f6c55,0x00006678fd69108f}, {0x0006fa31636863c2,0x00048572d33f2158,0x00089eaefc07f68c,0x00047014f73cc9f7,0x00002d42e2108ead}}, +{{0x0005131594dfd29b,0x0005d313f4c6a97f,0x0008455010615598,0x000d322eba13f070,0x0000676b2608b8d2}, {0x00017b0d0f537593,0x0000b131e064c217,0x00052ae09f914e69,0x0003c6e1bb687ae7,0x0000420bf3a79b42}, {0x0008ba651c5b2b47,0x000ec311b1b80813,0x000c3135b08671b6,0x000f1e07bff0cb1b,0x0000745d2ffa9c0c}}, +{{0x00025a1e2bc9c8bd,0x0000826479d81bf5,0x000f0155dbea5b26,0x000f5d0d511c70ed,0x00001ae23ceb960c}, {0x0006df5721d34e6a,0x00027997bb3d0603,0x0008756afab1db88,0x000c839d3c209c3c,0x000006e15be54c1d}, {0x00025d871932994a,0x000b5ceb1dab05b7,0x000ab7ca0532351c,0x000c1f77dc41549d,0x000058ded861278e}}, +{{0x00073793f266c55c,0x000c5cc454e49d81,0x000c26c3a8c8c976,0x000f6f95ce382f8b,0x00002ff39de85485}, {0x000b5ba8b6c2c9a8,0x0008ef52c598c2df,0x00012d157348eeef,0x0005bd833809107f,0x000008ba696b531d}, {0x000d3eeec3efc57a,0x00017d4ff481177e,0x0001a671cb04e055,0x000fe54ea3d7a3ff,0x0000120633b4947c}}, +{{0x0004987891610042,0x0003cecebfae80b9,0x0004f0a4c04ee7b1,0x000918570be73959,0x000035d30a99b4d5}, {0x000d31474912100a,0x0006d7e6fbe0682b,0x0001ea79c6de237b,0x0003bdee11e76191,0x000007433be3cb39}, {0x000944c05ce997f4,0x000e4b05c51a3ff7,0x000a76847c575d3d,0x000da9f583381fd5,0x00002d873ede7af6}}, +{{0x000a316443373409,0x000eef4aa81d9157,0x0005a64806fab8b7,0x000a7b6b093fee6f,0x00002e773654707f}, {0x000202e14e5df981,0x000175015e1f5aa6,0x000ae21d6ca20d59,0x000025318a275d3b,0x00000543618a0160}, {0x000abdf4974c23c1,0x000259dce46930de,0x00029aba2caa6f0a,0x000960d04202cb8a,0x00004b1443362d07}}, +}, +{ /* slot=9 [{1,2,3,..,8} * 16^(2*9)] * G) */ +{{0x0004b7c7b66e1f7a,0x00025f50c2f7eccc,0x00013eaf1c44157e,0x00063f73ef06dfc7,0x0000582f446752da}, {0x000c54e91c529ccb,0x0009264c635fb967,0x000812196530f626,0x0006f5c2747aff47,0x000017038418eaf6}, {0x00017bd320324ce4,0x000e8a4488bc4c63,0x000e5a1364a81042,0x0008dc9b21ef18b4,0x00000c2a1c4bcda2}}, +{{0x000dc7d06f1f0447,0x0003edb87c059d24,0x000bb2d28fb2269e,0x0004877d15b0272f,0x00007c558bd1c6f6}, {0x0004814869bd6945,0x0007dbe1c8d22edc,0x00055cc5ab0d6d90,0x000dc83c63bd212d,0x00005a6a9b30a314}, {0x000c1524d396463d,0x0008ac35a24f0d0e,0x000cbc5fa412bb62,0x000afc3a50c3a791,0x00000404a5ca0afb}}, +{{0x000f40070aa743d6,0x000cb5b265ee88c1,0x00068fd2deccbad0,0x0009633574b046b6,0x000046395bfdcadd}, {0x000c9e1b2a416fd1,0x00028e350598b62b,0x000d5d6967b5c6f7,0x000ee9804343fd83,0x000039527516e7f8}, {0x000fdb2d1a5d9a9c,0x000bcd1005c2a117,0x0004d56fea9c7745,0x000d016efd4bef15,0x000076579a29e822}}, +{{0x00068e7e49c02a17,0x000a2bca9a37f45b,0x000c224c1b23cd51,0x000bdb13ed65f11e,0x000043a384dc9e05}, {0x000cb51352b434f2,0x0004993de80e1333,0x00050d35ced83228,0x00077c1b55128877,0x000002c514bb2a27}, {0x000bd5da8bf1b645,0x0007ef6b54b53684,0x0009b0d253fb8bd3,0x0008059313916d7a,0x0000116092096154}}, +{{0x000d166929dacfaa,0x0004c8413598fb44,0x00053d5559da529f,0x0008e0be9ef63ca4,0x0000351e125bc569}, {0x00085616369b4dcd,0x000a7655c35637a3,0x0004f1802175c02c,0x000e0427dc21bf9d,0x00002f637d7491e6}, {0x00049b461af67bbe,0x0007ac8ab8961d4b,0x0009a699fbd60303,0x0002a9a71dee19ff,0x00007f182d06e7ce}}, +{{0x000c8e64ab0168ec,0x0005515edc5437a7,0x0007cd0edacb5a4a,0x00093b0095519d34,0x000067d4ac8c343e}, {0x00054b728e217522,0x000f4d484b8d8094,0x000f46903caa58e8,0x0005217d358254d7,0x000044acc043241c}, {0x000d6bbb4f7a5777,0x000d4918313e11c7,0x00096b46848b35fe,0x00071bd4adca1c6c,0x0000556d1c8312ad}}, +{{0x000f40e30c8d3982,0x0003e15a3fa3417e,0x000773646e31f707,0x0004eff4f21f3cb0,0x0000746c6c6d1d82}, {0x00006756b11be821,0x0002310a3f3dd81f,0x000a99465d0faff8,0x0007f05f8b2d0556,0x0000097abe38cc8c}, {0x0009c9877ea52da4,0x000559bdc1d430c4,0x0007ccebd24c4369,0x00084bd022c3809f,0x0000577e14a34bee}}, +{{0x000268ac61a73b0a,0x000103791a5f5f0e,0x000b6d00e9f2fafa,0x0008f42c1e13e826,0x000060fa7ee96fd7}, {0x000ecebebd4dd72b,0x000da060f221194f,0x0000c8d1fff46a4f,0x0009295124a5977c,0x0000705304b8fb00}, {0x000d1d354d296ec6,0x0003e5fad31d8b63,0x0004bd42ecf3c305,0x00053fd670b958cb,0x000021398e0ca163}}, +}, +{ /* slot=10 [{1,2,3,..,8} * 16^(2*10)] * G) */ +{{0x0005058a382b33f3,0x0000bad48c0b489f,0x00053db36e5ae2ba,0x00032e68f93b503a,0x00005aa3ed9d95a2}, {0x0008aaf9b4b75601,0x000135c8dad72279,0x0001b7a0235eac72,0x0007d4ed2ceaa616,0x00001bbfb284e98f}, {0x000777e9c7d96561,0x0005472c78036656,0x0009506eeecb2b12,0x00057cc65053299d,0x00004a07e14e5e89}}, +{{0x000412cb980df999,0x0006f3c6ec7714ee,0x00025c77fda315d7,0x0003402bba5edde9,0x00003f0bac391d31}, {0x000b58cdc477a49b,0x000de6447f017240,0x0007c86aadfd38da,0x000a08119928d32a,0x000050af7aed84af}, {0x000fde0115f65be5,0x00021216109b26e4,0x000badd6d9299826,0x000d006780205810,0x00001921a316baeb}}, +{{0x00022f7edfb870fc,0x000eb4f76b3bd894,0x0006c24df72c296b,0x000aeb00738f1d43,0x00006458df41e273}, {0x000aad9ad9f3c18b,0x000ef60b1c19cd75,0x00055c0ed9566a0e,0x000c7f53e9a0bac2,0x00007b049deca062}, {0x000be37a35444483,0x000330fedbe93dcc,0x0002c5dd87758879,0x0000e64786004c31,0x00006093dccbc295}}, +{{0x00039a8585e0706d,0x000d8b3e739331ff,0x00018f453b36d0a5,0x000a97c43b9f2e17,0x000057d1ea084827}, {0x000eeebe6084034b,0x000b6780fb8546bd,0x00062d06953199c2,0x0007d90973376abb,0x00006e3180c98b64}, {0x000ab6e7a128b071,0x0006d93a88baaee7,0x0002216130a4c159,0x000bd18f7b4de82b,0x0000363e999ddd97}}, +{{0x000843c135ee1fc4,0x0005508e4c8cf96a,0x00058cd330976eb3,0x000052bb42f6801b,0x000048ee9b78693a}, {0x000848dce24baec6,0x00055babcaf602f1,0x000cefe931769b72,0x000b35590cb3c6e3,0x0000231f979bc6f9}, {0x0001de4bcc2af3c6,0x00030fe208d1f5c3,0x00014fb466b04bb0,0x0002413b78d7009c,0x0000079bfa9b0879}}, +{{0x00003a51da300df4,0x000233da95ab0e39,0x000b356480843964,0x0007194ed3cf12d0,0x0000038c77f68481}, {0x0009ed80a2d54245,0x0007877f63952f3c,0x00010854750aa08b,0x000636bd76dac63d,0x00001ef4fb159470}, {0x000e5ee65b167bec,0x0004296d0cdc2854,0x000810219959590a,0x000ff5672b2df349,0x0000575ee92a4a0b}}, +{{0x000080908a182fcf,0x000c299489dbdd4c,0x0002f733de30e170,0x000fd0005babd575,0x000043d4e7112cd3}, {0x0006bc450aa4d801,0x00027a533b9d85d4,0x000b8906c2c3af12,0x000581b389e3b262,0x0000200a1e7e382f}, {0x000db967eaf93ac5,0x0009b056652c0518,0x00067197f571bc98,0x0004e38fe2b85d95,0x0000050eca52651e}}, +{{0x00031ade453f0c9c,0x0005eff703b9bc34,0x000d847b3de9f504,0x000f4c6fcd97ac9e,0x00004b0ee6c21c58}, {0x000c397660e668ea,0x000fe153ab49797a,0x0004eca79f9b19bb,0x000ae574cb179b53,0x00006151c09fa131}, {0x00055c0dfdf05d96,0x000e02ab4ee7a3af,0x0002171709dd262e,0x000030b11b2bb871,0x00001fef24fa800f}}, +}, +{ /* slot=11 [{1,2,3,..,8} * 16^(2*11)] * G) */ +{{0x000653fb1aa73196,0x000303fd7641837d,0x000b3a17b20f9495,0x000613ead200b09f,0x0000544d49292fc8}, {0x0002aff530976b86,0x00006c2d2460422d,0x000de5bae58d90b8,0x0000c17dca1896c4,0x000028005fe6c834}, {0x000fba9f34528688,0x0009425107da16ae,0x0006d94b365c1bff,0x0006dfaf75bbbcd6,0x000072e472930f31}}, +{{0x0005208c9781084f,0x0000b23450ee1269,0x0003efde02b1502a,0x000a34cfd9daea60,0x00005a9d2e8c2733}, {0x0003f635d32a7627,0x000865f6566f007f,0x0008d044507aaa4d,0x00064383c85e7972,0x00001fee7f000fe0}, {0x000305da03dbf7e5,0x000491434cdbd765,0x00024a88eca4daf2,0x00005437b4ad5cdd,0x000000f94051ee04}}, +{{0x00056b23c3d330b2,0x0009bb0471b068d3,0x000e42b83cf21c8b,0x000b10db36c316c6,0x000007d79c7e8bea}, {0x000f93bb07af9753,0x000cf3db766a7d7e,0x000e0b1ec5583ed0,0x0000452ce6998bf6,0x000047b7ffd25dd4}, {0x000bfb9cbc08dd12,0x0003ae1eec29b87f,0x000b1fc1bf8a066b,0x0004bb60d57242bd,0x00001c3520a35ea6}}, +{{0x000253a6bccba34a,0x000a13838219b80d,0x000882e3963e61c3,0x000e66f90c3b6019,0x00001c3d05775d0e}, {0x00086f40216bc059,0x0001d12bcd87ecda,0x0007c709901fbb23,0x0002e55b4956a9e1,0x000038750c3b66d1}, {0x000ef1409422e51a,0x0003c2b5df671692,0x00044ce029cbc0c7,0x000487c21014fe77,0x00000621e2c7d330}}, +{{0x000860cc8259838d,0x000c1c69f9adcaf9,0x0005581e3090ea48,0x000a5bc652648376,0x00000007d6097bd3}, {0x000e1796b0dbf0f3,0x000b9e17ce196b7a,0x0009aaa3b454dfaf,0x0002e9d25923071e,0x00005d8e589ca100}, {0x000f1d950842a94b,0x00063588f2e3ec0b,0x000b51e2efb2d3c3,0x000bf860a961438b,0x00001583d7783c1c}}, +{{0x000ea2ef5da27ae1,0x0001455670174ece,0x000609167a597c3a,0x0008f70c9a62a126,0x0000252a5f2e81ed}, {0x00034704cc9d28c7,0x0009ef72cc58f900,0x000e5b87261d1b67,0x000580a16e12b5fb,0x00004958064e83c5}, {0x000894265066e80d,0x00085307c8c6b0d2,0x000c1112fdfcc3f7,0x000b3881b53da780,0x0000079c170bd843}}, +{{0x0006ece464fa6fff,0x0001e6205e523050,0x0001b8ea42bee343,0x000fb00357942245,0x00006dec05e34ac9}, {0x0006cd50c0d5d056,0x0006dbb03573bcdd,0x0003c3ef489af768,0x0008acc3ca6723ff,0x00006768c0d7317b}, {0x000625e5f155c1b3,0x000a7997b7b9194b,0x000d6b2600417bf3,0x00052f4c22cbddc6,0x000051445e14ddcd}}, +{{0x00002b4b3b144951,0x0006b444bbcb3575,0x00066385db8e67ff,0x00095c8b8bd69271,0x000013186f31e392}, {0x000147ab2bbea455,0x0004f92079129893,0x000e30f7a78c53a2,0x000d43d4b49f948b,0x000012e990086e4f}, {0x000c96b37fdfbb2e,0x0005e121ceaf9f10,0x000a5b983f9f9a93,0x00099afdf1136c43,0x000077b2e3f05d3e}}, +}, +{ /* slot=12 [{1,2,3,..,8} * 16^(2*12)] * G) */ +{{0x000fa9c59c2ec4de,0x000bf4f84f3cb296,0x0007a8f908bc8b61,0x000255d1c7706d91,0x000063b795fc7ad3}, {0x0008639c12ddb0a4,0x00030c024866bd59,0x0008fce460a5d19f,0x0005e8ad17c2f035,0x000007a195152e09}, {0x00068f02389e5fc8,0x00002cf8de43ba83,0x000541264390433b,0x0000137afa1fd5dc,0x00003e8fe83d032f}}, +{{0x000b15b90570a294,0x00070670845492f8,0x0001bbfd8494f242,0x0004007de1c5ae16,0x000075ba3b797fac}, {0x00004c8de8efd13c,0x0008e33e03731087,0x000260cde3dfc51a,0x0008c86a59d5da51,0x000022d60899a625}, {0x0009dbc070cdd196,0x0008b6c7d8a9a623,0x000b40126060fe8a,0x0009e5eb38847bce,0x00000904d07b8777}}, +{{0x000e1fd4ddba919c,0x0003ec74c8daab4c,0x000d86cc51cf31db,0x000de072c63cc63a,0x000043e2143fbc1d}, {0x00022d6648f940b9,0x0000cbd2d0c39f43,0x000081f93106952f,0x0002a6c167697ada,0x00006240aacebaf7}, {0x0004749c5ba295a0,0x0005bca37d25af83,0x0007c9316ad6947c,0x0000cac66f13ba7e,0x000056bdaf238db4}}, +{{0x000ab9e3f53533eb,0x000d56eb93d40362,0x000d5a5572338568,0x00013189e0e14521,0x00001d24a86d8374}, {0x0000d36cc19d3bb2,0x000b7622386b9131,0x0007a14f5c062a6b,0x00057547c9b8591d,0x000003aa31507e1e}, {0x000c7648ffd4ce1f,0x000f054ac8c1cf4e,0x000d09357ce045ea,0x000485988d225821,0x000043b261dc9aeb}}, +{{0x000b1e1988bb79bb,0x0007dc17a359de55,0x00003dea33a09ed0,0x0006bc2b02c2ee26,0x0000326055cf5b27}, {0x00013d8b6c951364,0x00026000bf47b195,0x00054f956794fe71,0x0000964028d10ddd,0x000002b4d5e24294}, {0x000155cb28d18df2,0x00046186ce508b4a,0x000c824389eacc46,0x0003410c49cf4936,0x000027a6c809ae5d}}, +{{0x0006ebcd1f0db188,0x0003a675a5be88ba,0x0005f5585a37d3d7,0x000a17ef22edfa31,0x00002cb67174ff60}, {0x000c270ac43d6954,0x000576a66cab2cd2,0x0009d7036cdd4a3e,0x000259979fa59246,0x0000221503603d8c}, {0x000ecdf9390be1d0,0x00044728ce3f159e,0x000a94f0f4a94220,0x000f43682891c667,0x00007b1df4b73890}}, +{{0x0002f2e0b3b2a224,0x000062b551160e49,0x000d7f7b0e7c6c9e,0x000599215eb8fe20,0x000061fcef2658fc}, {0x000e221807f8f58c,0x0009fd49409d45f2,0x000fb6a630e3555c,0x000e03db2aaa88d1,0x000068698245d352}, {0x00015d852a18187a,0x000d386ddacd7dbb,0x000ff6c482f3e4aa,0x00001cf44bae2810,0x000046cf4c473daf}}, +{{0x000525ed9ec4e5f9,0x0000116903303426,0x000be5cadc0e5eda,0x0005f4072b1a7f2c,0x000029387bcd14eb}, {0x000c6ea7f1498140,0x000f8392b4854213,0x000629ceba7c1e7e,0x000c5bb2488c38c5,0x00001065aae50d8c}, {0x000c4525df200d57,0x000d6bfca674a1c2,0x00018340305c3b2d,0x000e7160a07e7b1e,0x000069a198e64f1c}}, +}, +{ /* slot=13 [{1,2,3,..,8} * 16^(2*13)] * G) */ +{{0x0002b2e0d91a78bc,0x0009cc8509667906,0x00005070b847c988,0x000a1bf9df54a664,0x00007369e6a92493}, {0x00014434dcc5caed,0x000963c84fb33e10,0x000d86a0e747ed5d,0x000f9e470019576e,0x000025b2697bd267}, {0x00073ffb13986864,0x000d9415dc7b89d6,0x000f273b5e3ca5fb,0x0004cd2e04ecc3bd,0x00001420683db54e}}, +{{0x0008bd1e249dd197,0x000005e58c102b47,0x000cbaac5c620c35,0x000a72dfb02d32fc,0x000060b63bebf508}, {0x000ebb6fc1cc5ad0,0x000e99646ac8b34e,0x00066bde536a1b0c,0x00081c1d3b0da49a,0x000031e83b4161d0}, {0x0008c7129e062b4f,0x0004f29320ad897e,0x000f18683f49e48f,0x00003175bece14b6,0x000055cf1eb62d55}}, +{{0x0009101065c23d58,0x0006d5094819c587,0x0002c55fa78b9d08,0x00091d4e2402fa91,0x0000669a65645708}, {0x0006b5e37df58c52,0x000dde799cc36307,0x000913ee20d73ab9,0x0000133bd831ce34,0x00001a56fbaa62ba}, {0x000e6b505c9dc9ec,0x000bba77c371a943,0x0001347651302557,0x0008a5c9873ae564,0x000013c4836799c5}}, +{{0x000a5d465ab3e1b9,0x00087c7f13f61423,0x000cb5b9b6fc13c1,0x000b60719f83664e,0x000066f80c93a637}, {0x000cfb6a5d8bd080,0x000ec571a4842c4d,0x0008e55365deebc4,0x000b827d4b2e883b,0x000050bdc87dc8e5}, {0x000d37836edfe111,0x00015f011abd9606,0x0005b73b9632353e,0x000d5ae64b03ac32,0x00001dd56444725f}}, +{{0x00047ff83362127d,0x000c471cd7c158fa,0x0009220c8bbc9f6a,0x000732e6e7145434,0x00000e645912219f}, {0x0007e60008bac89a,0x00011eae1c3e0c29,0x000fe7977c7d4cea,0x00005cdf3e38be19,0x00003a3a450f63a3}, {0x000f2f31d8394627,0x00083de94a510078,0x0007996f80389d31,0x000a87bd1e36c6d1,0x0000318c8d9393a9}}, +{{0x00045d032afffe19,0x000497f24db66f27,0x000a8598ef0c9f3c,0x0005314bc98d3e3b,0x0000224c7c679a1d}, {0x00069e29ab1dd398,0x00058342d9e3b5d6,0x00035973cdfc9216,0x0000af655851dfdf,0x0000509a41c32595}, {0x00006edca6f925e9,0x000f4641b1f33bdc,0x000d833e89793ef3,0x000138982ec12809,0x000005bff02328a1}}, +{{0x0002137023cae00b,0x0000ad1accf59363,0x00021a1c88544acf,0x00044a796741049d,0x0000780b8cc3fa2a}, {0x0001a0dd0dc512e4,0x000c844a5fafe688,0x000f4a52404fe70d,0x000a3ea1f748e6b8,0x0000576277cdee01}, {0x00038abc234f305f,0x000bd1405de081ef,0x0004e62a0d9a577f,0x000b7a15e82a5143,0x00005ff418726271}}, +{{0x000e080c1789db9d,0x00025f3e778f5398,0x0006bd035da76020,0x00066befa98894c0,0x0000106a03dc25a9}, {0x000b47e813b69540,0x0003b432610e1e5d,0x0008781276f35d2a,0x000cb69ac1f26e93,0x000029d4db8ca0a0}, {0x000d0aaf333353d0,0x000a5acd309e5d9a,0x000888f7f038669d,0x000befa3c57658ac,0x00004ab38a51052c}}, +}, +{ /* slot=14 [{1,2,3,..,8} * 16^(2*14)] * G) */ +{{0x000c2b256768d593,0x000574422ca13da7,0x000a0ace1d98c1c0,0x000a690f1a80bd5c,0x000029cdd1adc088}, {0x000fd1ef5fddc09c,0x000fdf7575dced6c,0x00001634c2e82b3e,0x0002b9b25d56b5d2,0x00003041c6bb04ed}, {0x0002f2f9d956e148,0x000759f356b2e0ff,0x000f6c025cade797,0x0009a7b1a4698bb5,0x0000104bbd681404}}, +{{0x0000fd3168f1ed67,0x000cdd86f3bc251f,0x0004d2f2de2c811d,0x000714944dc5c430,0x00005be8cc57092a}, {0x000d9a5fd67ff163,0x0009d4cc75681a95,0x000e20f257e92be6,0x0002df5b7f8024cd,0x0000204f2a20fb07}, {0x00043b3d30ebb079,0x0005abd652e30c81,0x000f6d5c31758915,0x000161f653c3c318,0x00002570fb17c279}}, +{{0x000a367f2cb61575,0x000761cd6026c3ef,0x0005b52562f5f96f,0x0000acde8c7142a6,0x00003dcb65ea5303}, {0x000ea9550bb8245a,0x000a88f9050d1192,0x0008a4c935c8e6fb,0x00086687986ea2d8,0x0000241c5f91de01}, {0x0008172940de6caa,0x000f022d9733a28d,0x00035b01d18fbf2c,0x000f0e516d7fcdd2,0x000008420edd5fcd}}, +{{0x000f20ab8362fa4a,0x000d4e21a3e6ecdf,0x000c39e62b57e118,0x00069fde3179617f,0x00000d9a53efbc17}, {0x0008c34e04f410ce,0x0005a276e0685035,0x000bb91521b6135b,0x000889c5d9670c7e,0x000004d654f321db}, {0x000dc116ddbdb5d5,0x000b68da5dd2d5e7,0x000334a2922954de,0x0001ad71cb608173,0x00004a7a4f261899}}, +{{0x000718025fb15f95,0x000346b5c1b8ff4a,0x0000e011123df65f,0x0001848cdfcf0850,0x000011b50c4cddd3}, {0x0003b291af372a4b,0x00070718147f224c,0x0006899ef293da82,0x000ee33dd8485648,0x00004a96314223e0}, {0x0008274408a4ffd6,0x0007e9c1576d9a6e,0x000d02b3f2738e17,0x000cc51773348b63,0x00004f4bce4dce6b}}, +{{0x000fce5ae2242584,0x0005692f58a9ea71,0x000cea3cf426ea72,0x00001e6d21a09d71,0x000073fcdd14b71c}, {0x0002616ec49d0b6f,0x0008fcaec231730e,0x00026b4fa6e45671,0x0005f3748eb409bf,0x00003042cee56159}, {0x000e7079449bac41,0x0006dbce2310a427,0x000f841a7c855ae3,0x000e1d64cae76215,0x0000389e740c9a9c}}, +{{0x000cb3ae34dcb9ce,0x00023e348d0ad64f,0x0002c6381b975003,0x000678845b3f07d6,0x000061545379465a}, {0x000d78f6570eac28,0x0003227919ce1c9b,0x00019b91ede55b0b,0x000369065fc3eaba,0x000025c425e5d626}, {0x000e06a6f1d7de6e,0x000278e0623083f3,0x000e8a6c773ef976,0x00047598c14f6264,0x00006539a0891548}}, +{{0x00021f74c3d2f773,0x0004125c46845e9d,0x0009b99e33c15054,0x000186c624e5ce8f,0x000011c5e4aac5cd}, {0x0004dbd414bb4a19,0x0003c98424f8eddc,0x0006ca716919b2bc,0x000bd9048a89fd73,0x00000f65320ef019}, {0x0006d1b1cafde0c6,0x000e3163b5181d48,0x000af2939a4f3fe6,0x000072a59a8af0df,0x00004cabc7bdec33}}, +}, +{ /* slot=15 [{1,2,3,..,8} * 16^(2*15)] * G) */ +{{0x000e9624089c0a2e,0x000c03afe4738239,0x00064fa12ac748c4,0x000858217dbed2a7,0x0000639b93f0321c}, {0x000f788f3f78d289,0x0002ca1404d9fc08,0x000f65cc9dfe30a7,0x0002021f2778bfcc,0x00007ee498165acb}, {0x000508e39111a1c3,0x000d4809074897bd,0x000e72fd192b2b90,0x00002a6e7d2aec2a,0x00000edf493c85b6}}, +{{0x000c8158599b5a68,0x0000febade20eaec,0x0002b67f07ea574f,0x0004fb44fe41d742,0x0000403b92e3019d}, {0x0007c4d284764113,0x0003ff7f5f835676,0x000ae6bedea09040,0x000a3691c8fcffac,0x000004c00c54d1df}, {0x00022f818b465cf8,0x0005a1480eff84dc,0x0004c7d65771a0f3,0x00076f4aee8bfad0,0x0000355bb12ab261}}, +{{0x000e64cc7493bbf4,0x000d9eca3b0c3a71,0x000a05e785e5bd84,0x000c3120a6bc50cf,0x00000f9b8132182e}, {0x0001dac75a8c7318,0x0009db3ceaa11a30,0x000bae3f2ded9003,0x000ad8e6f077cbf3,0x00007518eaf8e052}, {0x000859c41b7f6c32,0x000bcf4383298a48,0x0009b1d1d90f2d60,0x00055c41815a929c,0x000047c3871bbb17}}, +{{0x0004539771ec4f48,0x0007dc98c5d6e514,0x0007c3c66bf805b1,0x00099dcf762c11a4,0x000000b89b857646}, {0x00065d50c85066b0,0x000b0b3a299b0fbe,0x00041ae8e062ecc4,0x0008d5fe53754ea4,0x000008fea02ce8d4}, {0x000ddd7668deead0,0x000204b685d23824,0x000d89d665c86445,0x000d537b514cfcd5,0x0000473829a74f75}}, +{{0x0002da754679c418,0x000d8b2618df082d,0x000c47eb0ae63bd7,0x000c6b4355eef24a,0x00002078684c4833}, {0x0009533aad3902c9,0x000ceef03588f23d,0x000fe12fb464c2dd,0x000d39015257390c,0x00006c668b4d44e4}, {0x0008cf217a78820c,0x000b281273e973b4,0x000c8eed7bf76a0a,0x000433fa96c65a78,0x00007411a6054f8a}}, +{{0x00059d32b99dc86d,0x00075603af1154d6,0x000cc2e488044cdc,0x00034ffb34c712cd,0x00007c136574fb81}, {0x000ae53d18b175b4,0x00059f392a102579,0x000eef35f5687131,0x000398f8455ecba1,0x00001ec9a872458c}, {0x0006a4d400a2509b,0x000020bc882b4b8e,0x00019575619b81d7,0x000646057e7cc9bf,0x00003add88a5c7cd}}, +{{0x00095770b635dcf2,0x0006cf66c1fbcab8,0x000eb6d18702dfef,0x0009e7485530268b,0x0000249929fccc87}, {0x000298d459393046,0x000985ff659ec85c,0x0002f66e3a8f7e35,0x000a7201d2ca22af,0x000061ba1131a406}, {0x0000a0f116959029,0x0006cba7ebd89a3d,0x0006783307023b6b,0x000ece77bf15a3e2,0x00005620310cbbd8}}, +{{0x000993434934d643,0x00006a51222f5528,0x0003f41c22b9dbf8,0x00097308f6d878fc,0x000037676a2a4d9d}, {0x0006b5f477e285d6,0x000676c8f6193664,0x000bb594dd40e8ff,0x000ec4da6ec7311a,0x00007ec846f3658c}, {0x000e8f3f1da22ec7,0x000776c01cd139b5,0x0002989fb8130f1d,0x0009dd5214c8fcfa,0x00006daaf723399b}}, +}, +{ /* slot=16 [{1,2,3,..,8} * 16^(2*16)] * G) */ +{{0x000a7562eb3dbe47,0x000548ebda0b85f3,0x0005747299f7ea38,0x000d55100c3e5314,0x00001304e9e71627}, {0x000b04bfacad8ea2,0x000e8148be884583,0x000810c5db29b743,0x000bbaa2b1e583b0,0x00002b5449e58eb3}, {0x000814d26adc9cfe,0x0003f8b48dd0b789,0x000979c60a3c1bab,0x000d693da0fe1fff,0x00004468de2d7c2d}}, +{{0x000b355e9419469e,0x0004c23ddc75451b,0x00047f996233e6dc,0x000bd6393a5b6d64,0x00006cce7c6ffb44}, {0x000ad8c6f86307ce,0x00031435d0c284b9,0x00057a772c211135,0x0007352d4a866c56,0x00005da6427e6324}, {0x0004c688deac22ca,0x000f7bbae1ff81a9,0x000d59580fb9066e,0x0002ca888ad8c388,0x000058f29abfe79f}}, +{{0x000ecfab8de73e68,0x0009f377e76a5e90,0x000e01598254036f,0x0001e36f0495b0bb,0x0000577629c4a7f4}, {0x000a64bf710ecdf6,0x00038462c293c4b5,0x00050b3ab9b14ce5,0x00048703643d056d,0x00006af93724185b}, {0x0000024509c6a888,0x000134b558973322,0x000c33289fd2e036,0x000c18f83e236233,0x0000701f25bb0cae}}, +{{0x0008b0f8e4616ced,0x0000e9e25a87dc3a,0x0004bca59cf70066,0x0000be961e3061ff,0x00002e0c92bfbdc4}, {0x0008f6d97cbec113,0x000e674bfdbe49d1,0x000c4e60d6844a06,0x0005e5120f5b522a,0x0000720a5bc05095}, {0x000f09439b805a35,0x000376242abfc0c3,0x000c229346e84e8b,0x000f0ec691417f35,0x00000e9b9cbb144e}}, +{{0x000ad48ffb5720ad,0x0006bdbf90d0efbb,0x00035543bfee8191,0x0007bd8d48131526,0x0000221104eb3f33}, {0x000e9bd55db1beee,0x000370a723fb98de,0x000c68d791c9c3ab,0x0003cde44a8f1bf1,0x0000366d44191cfd}, {0x000c1743f2bc8c14,0x000fcb5856c3b9e3,0x0008a7fb972eda26,0x0003244ccb82f0e6,0x00004167a4e6bc59}}, +{{0x000b9d2876f62700,0x000400e7668eb643,0x0001fc06845d1d9d,0x000246a1b4b43032,0x00007938bb7e2255}, {0x000e2665f8ce8fee,0x00014e880d62cc2b,0x000f364eeee967ff,0x000d2f6f12e6e7e2,0x000034b33370cb7e}, {0x000591ee8681d6cc,0x0009ced85a753cdc,0x0008808883ce0210,0x00065e4ed7485c15,0x00001176fc6e2dfe}}, +{{0x000f6cd05b9c619b,0x000f4b2a58480b4a,0x000be94dc42ddfc9,0x0005f343d4fa502e,0x000008fc3a4c677d}, {0x0000e28949770eb8,0x0002aacf440a3db9,0x000ed7879b98fbcc,0x00006b621354ffed,0x00001f6a3e54f269}, {0x0004c199d30734ea,0x000b631165cd660a,0x000759829540c085,0x00000d1e2333e23f,0x00004f2fad0116b9}}, +{{0x000eb24194ae4e54,0x000511857ef6c44b,0x00068d04985f541c,0x000f7aba61e6b2d3,0x0000445484a4972e}, {0x000cd91db73bb638,0x000aafc129c08962,0x0003b61689e60577,0x000ee816f619b39f,0x00003451995f2944}, {0x0002fcd09fea7d7c,0x00094b0935cf6915,0x0007285c404a816c,0x00093b7258e9aaa4,0x000010b89ca60428}}, +}, +{ /* slot=17 [{1,2,3,..,8} * 16^(2*17)] * G) */ +{{0x000947499718289c,0x000c524533f263d5,0x0004c3ef1512ebf8,0x000518e0262bfcb1,0x000020b878d577b7}, {0x000941be5a45f06e,0x000ed6d9c5f65753,0x0002ff51b6d07cae,0x0004da911776b9c7,0x000017d2d1d9ef0d}, {0x0002af18073f3e6a,0x00019d752106927f,0x000ca60022fd3fe5,0x000c6a722e3b72c3,0x000072214f63cc65}}, +{{0x00037f405307a693,0x000d72f336795b4e,0x0003761099aba714,0x000cbc9d6fbd0a77,0x00005fdf48c58171}, {0x000db7b9f43b29c9,0x0004a4f518f751d9,0x00012f9dc4d60582,0x00045b0f2c072bd3,0x00001f24ac855a15}, {0x000608328e9505aa,0x000d10c1420ee24d,0x0006fb25a24748c1,0x00095e6c7ffe45c0,0x000000ba739e2ae3}}, +{{0x000e98de5c8790d6,0x000d345c2a2df592,0x0009b49922e5bfb7,0x00078f3115a3b60f,0x000003283a3e67ad}, {0x000426f5ea88bb26,0x000d984973bfbae4,0x0006694e50360679,0x000d2265c9f030c2,0x000072297de7d518}, {0x00041dc7be0cb939,0x0004d8b633080482,0x000228930832f19b,0x0001945d3dfc90d0,0x000005e129684627}}, +{{0x0002eeb32d9c495a,0x000fcf12bb97cba8,0x0003b5d1e0ceefc8,0x0008d9bb02dabae9,0x000039c00c9c1369}, {0x000fbbc8242c4550,0x000ecd03081d9adb,0x0005c8df92bcc80c,0x000ce4c843566a6f,0x000078cf25d38258}, {0x000e6b8e31489d68,0x000ab9c2bf08715a,0x00004efa05aa851c,0x000f832c9a75a97f,0x0000006b52076b3f}}, +{{0x0000cfe19d95781c,0x00018966310e229e,0x0000516b39b681df,0x000612257df39d37,0x00004d57e3443bc7}, {0x000b7e16b9ce082d,0x0004c417abc29f5c,0x000bf4a7ab3407f1,0x00075ced4b36bce2,0x00007de2e9561a9f}, {0x0000d4f4b6a55ecb,0x0007f5d85db99de7,0x0003ee9a81480152,0x00029eddbc9c440d,0x00006b2a90af1a60}}, +{{0x0003f4fc9ae61e97,0x0001de03f5fd1692,0x0006edd12d573528,0x0003e4aa764ae43e,0x00005fd8f4e9d12d}, {0x000bf3245bb2d80a,0x000472fb9079b77e,0x000cee7333d8301b,0x0002109c647e6f24,0x0000465812c8276c}, {0x0003beb22a1062d9,0x000753831dc164d4,0x000e2968d77065fb,0x0006790180d4a7bd,0x000005b32c2b1cb1}}, +{{0x00005eccd24da8fd,0x000ac05dfef83c8c,0x000df9cd61a1cf1a,0x0001e99dbbeeff27,0x00003b5556a37b47}, {0x000ca42c7ad58195,0x0006e4333f3ccf7f,0x00040b979d321428,0x00007e1b6c29d0d3,0x000031771a485673}, {0x0000c524e14dd482,0x000541a2ba4b632b,0x00082b5af3edb351,0x00036eba3d160482,0x00004fc079d27a73}}, +{{0x000938b089bf2f7f,0x0006502dfe9a751c,0x000880e4532497bd,0x0008e92ffffc09c7,0x0000124567cecaf9}, {0x00048b440c86c50d,0x000c9cc94e651dc3,0x00043e3cb91337cb,0x000cd086422f74d6,0x0000241170c2bae3}, {0x0009ab860ac473b4,0x000ee0113e4353ff,0x000bc6c4aff0911d,0x000000d4ae75060e,0x00003f8612966c87}}, +}, +{ /* slot=18 [{1,2,3,..,8} * 16^(2*18)] * G) */ +{{0x000a0cc9782a0dde,0x000b2ea718385559,0x0001ef238c551dcd,0x000613d7f62865b3,0x0000504aa7767973}, {0x0008fcfa36048d13,0x000b373899ddd9c1,0x000f92d0aa29159d,0x00019d4dc9f350b9,0x000026f57eee878a}, {0x000b2cd55687efb1,0x00062247af17b0ca,0x000f5a24675180d1,0x000306985c15a344,0x00004041943d9dba}}, +{{0x0000eeba43ebcc96,0x0009c26ea9cafc3c,0x000c77ccc68d749c,0x000340fd9fa95ee1,0x00001420a1d97684}, {0x00017743a26caadd,0x00024648ab7ce4b2,0x0003fbc9e347a6b4,0x000d019cb1d4f7a0,0x000012d931429800}, {0x00067799d337594f,0x00040b23aa47b00c,0x00035ff3955e3c51,0x000a01244182854e,0x00001b4f92314359}}, +{{0x000c109d89150951,0x000912de9696a3e5,0x00075f302039cefa,0x0002dae20eae43f9,0x0000239b572a7f13}, {0x000f3030a49866b1,0x000d2215f485933c,0x0001def4f6251f73,0x00023f6ab82aa405,0x00005ff191d56f9a}, {0x000ed433ac2d9068,0x000795fc98523819,0x000593eb3d2883ab,0x00036cbef4572805,0x0000020c526a758f}}, +{{0x000834f89ed8dbbc,0x000f9dc7ca46c779,0x0003e1b074c8f2aa,0x0003877a9524cdca,0x000002aacc461531}, {0x0001ef59f042cc89,0x0009d8e124bb6e93,0x000ec759972c589c,0x000c50cadc8e18aa,0x0000452cfe0a5602}, {0x0000f7a0647877df,0x000270e607c9f86a,0x0001fb11c9bbc464,0x000877bab17ea25f,0x00004cfb7d7b304b}}, +{{0x00043d6cb89b75fe,0x000d99c6adc8072b,0x000ee34c9f54c694,0x0005364b8c3aa373,0x000014b4622b3907}, {0x000699c29789ef12,0x00071df57190de28,0x000cc970d02b6ecd,0x0003ac5c343c857e,0x00005b1d4cbc434d}, {0x000b2615cc0a9f26,0x0002bb88dcce5b6f,0x000369a7053a4f0e,0x0002dd11301498b3,0x00002f98f7125859}}, +{{0x0004a74cb50f9e56,0x000a98e8e13200c9,0x0002300f675b1ff4,0x000aaf99a2acc218,0x00003a6ae249d806}, {0x0002ae444f54a701,0x000f0a9cbd7de2e1,0x0005835de0fcfe3e,0x0004554cebf890d7,0x00001d8062e9e761}, {0x000ada85a9907c5a,0x000b591b90f62657,0x000f34b4e91a0ea8,0x0005ff38d0e1dfbd,0x0000298b8ce8aef2}}, +{{0x00027953eff70cb2,0x0002a791570762a9,0x0000a7cf6a4b89c9,0x000e4859418457a3,0x000034b8a8404d5c}, {0x000a72ea0a2165de,0x000b40bcf79f6837,0x000738ae703fab07,0x000d7dc521636c77,0x00006ba6271803a7}, {0x000eecb583693335,0x000df63b5fefdc26,0x0004b22573d5a813,0x0001c6aa293aa9aa,0x000071d62bdd465e}}, +{{0x0003cc28d378df80,0x000790a0fa4b4653,0x000701da5af6db43,0x0002ba4e3645ff9f,0x000074d5f317f317}, {0x000db5dab1f75ef5,0x000cf16b065f5cd2,0x000f49f085d77f95,0x0002b3d14571fea3,0x00001c333621262b}, {0x000fe55467d9ca81,0x000752b298c37a86,0x0003ac623b398b7c,0x000d98cda6d0892e,0x00004aebcc4547e9}}, +}, +{ /* slot=19 [{1,2,3,..,8} * 16^(2*19)] * G) */ +{{0x0000071b276d01c9,0x000c586c48c7012f,0x0001d6fba9e7b8ba,0x000b7925308129b7,0x00005d88fbf95a3d}, {0x00008d9e7354b610,0x000535ba85b6e0b4,0x000a58a207806b32,0x000df2cdbe63a034,0x0000173bd9ddc9a1}, {0x00000f1efe5872df,0x0002ed43918c12b5,0x0009673ae058d658,0x000a319e6ed278ec,0x000006e1cd13b19e}}, +{{0x0000ad516f166f23,0x000931fab6abe40d,0x00004d088e118e32,0x00062663fe35e14a,0x00003080603526e1}, {0x000baf629e5b0353,0x00090278d0447472,0x000643bf273baa0b,0x0007b130c785f469,0x00007f3a6a1a8d83}, {0x000644395d3d800b,0x00055c901edf6f7e,0x00092c633995a8d5,0x000307e68cd78305,0x000030d0fded2e51}}, +{{0x00094d1af21233b3,0x0008ef0cc4d9ce05,0x000f499a771bdbe7,0x00098686965187f8,0x00000a9214202c09}, {0x0004971e68b84750,0x000296664bbcf9cb,0x0002fa412ba09572,0x00089d95c8de7267,0x00004615084351c5}, {0x000019c0aeb9a02e,0x0000d16034caebc9,0x00059932ec55c711,0x0005dfe0e6df5016,0x00003bca0d2895ca}}, +{{0x000031bc3c5d62a4,0x0003ecff07a6040f,0x00030fb54519fc8b,0x00013cd98183da21,0x00005631deddae8f}, {0x00088eb69ecc01bf,0x000ada644896f9c6,0x000f7a9fe2f0bc83,0x0008241ca2d955f5,0x00004ea8b4038df2}, {0x000d460af1cad202,0x00005a48cee832ae,0x0009f11a5f463053,0x000a463912177454,0x000024ce0930542c}}, +{{0x000890f5fd06c106,0x000355d8810f21fe,0x000e8caf3eb5c468,0x000d74b827808fe6,0x000041d4e3c28a06}, {0x000fa155fdf30b85,0x0008e36372ea43fc,0x000492f844d2f716,0x0004280b2e064de6,0x0000549928a7324f}, {0x000e32a763ee1a2e,0x000b7d25ffdeaf26,0x00017f4d69ae91e4,0x000ff6abc3bd33bd,0x0000491b66dec0dc}}, +{{0x0005b13dc7ea32a7,0x000cc7e16db9898f,0x000bf8d947e3d5f8,0x000e4acac0abf52c,0x000008f338d0c85e}, {0x00004a8ed0da64a1,0x000af67e2284b75f,0x000f7b7ba4ed222c,0x0008b678234a3791,0x00004cf6b8b0b701}, {0x0003a821991a73bd,0x00001df320c7ac38,0x0004777063ab27bc,0x0008a99c13d331b8,0x0000530d4a82eb07}}, +{{0x000c3630e1f94825,0x000268cab535a004,0x000c84ff8b7e2d78,0x00070b9c7482323c,0x000065ea753f1017}, {0x000973456c9abf9e,0x000fc4900a8806d6,0x0008cfb850257fb2,0x000bd5b2bacf412c,0x00000db3e7e00cbf}, {0x0006fc3ee2096363,0x0007f61b5cb6b3d6,0x0003443b1a81d62c,0x000a1db0fbe04421,0x000002a4ec1921e1}}, +{{0x0006259a3b24b8a2,0x000cc45afa0b85ce,0x000ba07037b8577a,0x00009bfcccbe6e88,0x00003d143c511278}, {0x00086162f1cf795f,0x0001926ee57f2f5c,0x000c063578118c86,0x0007fcf172124851,0x000036d12b5dec06}, {0x000d279179154557,0x0005cfc783a0a126,0x000f179bacd5e48f,0x000285936bdb6e8d,0x00002ef517885ba8}}, +}, +{ /* slot=20 [{1,2,3,..,8} * 16^(2*20)] * G) */ +{{0x0007974e8c58aedc,0x000fbabf041a4463,0x000980718ab9ef22,0x000a8a6e185d956e,0x00002f1b78fab143}, {0x000ebffb305b2f51,0x000ad889596b896e,0x0006d5dd25d3f938,0x0000095f0f52dc74,0x000057968290bb3a}, {0x000ab8430a20e101,0x0008d24f0ec47f71,0x000ee2eed1f39365,0x000a3e1cf7509a86,0x00007dc43e35dc2a}}, +{{0x00066665887dd9c3,0x000314bb05355859,0x000f2079b1c90f9b,0x000c12fc6e08df8e,0x00007ef72016758c}, {0x00082a5c273e9718,0x000995e4efd945a7,0x000f237d3e3576c6,0x0000a990f2ed8051,0x0000044fb81d82d5}, {0x000f18c5a907e3d9,0x0001dce4c6359c1d,0x000201bb4957b337,0x000dd2eca704534b,0x00007f79823f9c30}}, +{{0x0004d239a3b513e8,0x000d4b91fa8d8833,0x000590bd33c13670,0x000d9b412b54136f,0x00000a4e0373d784}, {0x000c1ff068f587ba,0x0004e0050c8de6a9,0x000ded5be7082789,0x000d6f03cbf99557,0x000064a9b0431c06}, {0x0003d6a15b7d2919,0x000a0d53a82352eb,0x0009a45d47b0b4f6,0x000346c7156ce438,0x0000071a7d0ace18}}, +{{0x00072daac887ba0b,0x00005bfa562eed30,0x0000ef768b012629,0x0007e9ccf543002c,0x00002c3bcc7146ea}, {0x000c355220e14431,0x0000709b15141cc0,0x00009d5f360d6595,0x00055d39af5621b2,0x00007c69bcf76177}, {0x0000d7eb04e8295f,0x000252f50f37d07f,0x00071798d710db18,0x000a51de951a9a31,0x00006f5a9a7322ac}}, +{{0x0001000c2f41c6c5,0x000c10cfefb9b8ba,0x000cc51c9fc49f79,0x000afca4efa47703,0x0000494e21a2e147}, {0x0009d4eba3d944be,0x000408078af9ee72,0x0007869c038d9e09,0x0003b244525567a4,0x000002ab9680ee8d}, {0x00048a85dde50d9a,0x0004e0fb9a249efa,0x00091ef6d9219a22,0x000bb34fa091f1dd,0x00006b5d76cbea46}}, +{{0x0007556cec0cd994,0x0006f5cd01dba885,0x000f42b4776472dc,0x0007354af0169148,0x00000ae333f68527}, {0x000941171e782522,0x00074036936d3e0f,0x0000fcc746f1e6ae,0x000313e408b3ea2d,0x000016fb869c03dd}, {0x000e199733b60962,0x000b4d8abe133288,0x000991d03e24fc72,0x000d0754811f7ed0,0x00003f81e38b8f70}}, +{{0x00010fcc7ed9affe,0x000a12465874b7f9,0x000b0c4704545cb8,0x0000993a8397ed24,0x000050510fc104f5}, {0x000b7f355f17c824,0x000c3d74299a40ad,0x000bf8eaf774b923,0x000dc3dd57c3e8bc,0x00000ad3e2d34cde}, {0x000c0fc5336e249d,0x00019c331cfd96f0,0x0009eefe1c745ede,0x0001ebef2d6fd000,0x0000127c158bf0fa}}, +{{0x00097c422e9879a2,0x000d452ca3647f61,0x000b4eaccba44add,0x0004f689b413fc14,0x0000354ef87d07ef}, {0x00028fc4ae51b974,0x000d3744dfe96dea,0x00073848a81d9973,0x000df956240680b8,0x00004ed82479d167}, {0x0003b52260c5d975,0x000fceb41b0b8fee,0x0009f6653c50352e,0x000236d8808ac30a,0x0000302d92d20539}}, +}, +{ /* slot=21 [{1,2,3,..,8} * 16^(2*21)] * G) */ +{{0x0003c1a2bca4283d,0x00091a1863dd9781,0x000268fa86ed62f0,0x000ae4caec7bcb8c,0x000010e5d3b76f1c}, {0x000c6fb6e4e0f177,0x00029a4bd6a932db,0x00087af6e804e1bf,0x000d0605e1966d47,0x00000edc5f5eb426}, {0x0003bfd653da8e67,0x000ec24a9f641545,0x0003578a23e9dc1e,0x000ba72bf87263b0,0x000045b46c51361c}}, +{{0x00002abf314f7fa1,0x000dc8e8cf450a94,0x0003a8be84e257f1,0x000713b1dbbd54b2,0x00002177bfa36dcb}, {0x000d4ddd8a7fe3e4,0x0005676620e30ce9,0x00030e9958ab1364,0x00029df4b594f7bb,0x00005c1c0aef3212}, {0x00081bbcfa79db8f,0x0001ec25f59b3370,0x000c832487604881,0x000b5bb087a76659,0x00004ae619387d8a}}, +{{0x000bf6aa5344a32e,0x000b4b41b40788dd,0x000a130d607d88ea,0x0003e035eb0eb974,0x00001a00d91b17bf}, {0x00017e44985bfb83,0x0002a71963136611,0x000425904bfce046,0x0003d6483ac3448d,0x000075685abe5ba4}, {0x00060933eb61f2b2,0x000a8c9ff49526e9,0x000af66569543d0f,0x000e6aadf7275107,0x0000135529b623b0}}, +{{0x0000dbd7add1d518,0x00088cfc11f1118f,0x000114759b979f78,0x0003a018732e1f07,0x000079b5b81a65ca}, {0x000716bce22e83fe,0x00019e80985c1f5c,0x0004254aaeb42beb,0x000a613ec9da6371,0x00005972ea051590}, {0x0004ac20dc8f7811,0x00094ac4d4fa80fd,0x00033604349a9ad2,0x0003bdbc01b2d64b,0x00004f7e9c95905f}}, +{{0x00074bbc5781302e,0x0003989addc0f626,0x0003fbd9c6d8520f,0x0008e4c8c2999ae5,0x000031993ad92e63}, {0x0008443d355299fe,0x0001cdbebead771c,0x0001a494668bcd3b,0x000adc88092499ef,0x00001942eec4a144}, {0x000c5319ae234992,0x000910cea3e927da,0x00053c11222c1b3d,0x000ca75553ce4942,0x00002a0a65314ef9}}, +{{0x0007937ff7f927c2,0x0000617d0a6352db,0x000155af76db741f,0x0002ded5982f3a21,0x00004cf6e218647c}, {0x00061acd3c1c793a,0x000ac5a35bc3bcf3,0x0008cda6ab2f9ebc,0x0001a1360e860e9a,0x0000055dc39b6dea}, {0x0009227cc28d5bb6,0x000bc774dffabb11,0x0004a32c8907e24e,0x00024b6a83c78cee,0x0000121a307710aa}}, +{{0x000b5d5e9f034a97,0x000093034bc2de4d,0x000551d3b1e153fc,0x000e52d460546919,0x0000333fc76c7a40}, {0x0009713ec77483c9,0x00077b82b96afd65,0x000097bcd388bfe0,0x0003a9b289e28231,0x0000527bb94a6ced}, {0x000d992a995b482e,0x0007c6e383801563,0x000f64d8e53405d0,0x000a9f7485035de2,0x00006b89069b20a7}}, +{{0x000aa0416270220d,0x000faf9245b4e812,0x000072ef05995a89,0x000eb73ffadc4ce5,0x000023bc2103aa73}, {0x0002fa8cb5c7db77,0x000f8c734c155408,0x0006e7a57e068686,0x0009bcf29e6c8d9f,0x00000473d308a763}, {0x000e792603589e05,0x0001246dcc492cae,0x000601a94f2b4b42,0x000341a02a1ef74e,0x0000102f73bfde04}}, +}, +{ /* slot=22 [{1,2,3,..,8} * 16^(2*22)] * G) */ +{{0x0008b9ab7f5745c6,0x000ee5787c690eb1,0x000df7afa9023a8a,0x000013db72712da2,0x000036597d25ea5c}, {0x0004dae0b5511c9a,0x000292bffff06a2b,0x00055042347ac860,0x000a12d981f375df,0x00003f6bd725da4e}, {0x000d8d7b106058ac,0x0009e6fc6905f734,0x000202932dd94057,0x000d6d06466f8f99,0x00007b7ecc19da60}}, +{{0x0002373c695c690d,0x000660642906e78c,0x000ae12bd2dd252e,0x0003956951d44444,0x00004235ad760174}, {0x000e4a51a77cfa9b,0x00054e7a386506da,0x000f2d82db822636,0x000caba09bbffcd8,0x000003bedc661bf5}, {0x0008cb0d078975f5,0x000549189f298625,0x0002e36ee4492942,0x00066a1a0cab423e,0x00000e7ce2b0cdf0}}, +{{0x0004643ac48c85a3,0x000f43c6139adc49,0x000ae94d48fd361d,0x000674a09db17dd3,0x0000666e0a5d8fb4}, {0x0006fedfd94b70f9,0x00051c1fcba2dfea,0x000f2fab89f130c0,0x000eeb54882d47e7,0x0000615256138aec}, {0x000bf64e4870cb0d,0x000f0aa458b6b2ab,0x0005e8985dcd65bc,0x000dee49abe4eba7,0x00007f0bc810d514}}, +{{0x00006ba426f4136f,0x0009e57e03035b90,0x000f463c288d6736,0x000dbf5cbc8dfd94,0x00000d1f8dbcf8ee}, {0x000c9dad737213a0,0x000ba2ef72e9883a,0x0003ec69579ff6f8,0x000ab75311e2edd4,0x00001d3a907ddec5}, {0x000693313ed081dc,0x000ad851b3480ba1,0x00030321cb29329f,0x000fde30128013c0,0x000000011b44a31b}}, +{{0x000fa06c3fc66c0c,0x0008e4dd60dd23fd,0x00068e4d715d40e3,0x00057e17ae38b382,0x00003ac48d916e83}, {0x00061f696a0aa75c,0x0005c5852bd6a165,0x000a7966adc1bf72,0x000102611a8dd7f9,0x000063d988a2d285}, {0x00020753afbd232e,0x000b8fdd8f683001,0x0004e72b91e92bce,0x000a066f81669b38,0x000033fad52b2368}}, +{{0x000649c6c5e41e16,0x00030333f7735540,0x000305e7460af864,0x000dca7b2acfcd2f,0x000016c0f429a256}, {0x000cc8d0c422cfe8,0x0007b05a13acb8d2,0x000cf6a56f072b4f,0x00071e2a3feb6e6e,0x00003cc355ccb90a}, {0x00069443903e9131,0x000cb7a5637cee9b,0x000aba9244b8a494,0x0007568c87cd1a4b,0x0000631eaf426bae}}, +{{0x00090410da66fe9f,0x000526c16e5a6b3e,0x000ef9bf8385dd4b,0x00019b5bc3d97611,0x00005599648b1ea9}, {0x000975b9a3700de8,0x000fbe2f8055247d,0x0002e45de17280c5,0x00080b553658f273,0x0000431f2c7f665f}, {0x00026344858f7b19,0x0002fa1ea514ad60,0x000090a9d714ab35,0x0003b268900441a2,0x00007b04715f9125}}, +{{0x000dbd28acf6ae43,0x0008b7d5c7ab483e,0x0007eb2c4486357c,0x000583fc0404769b,0x000059b37bf5c2f6}, {0x0006c280c4e6bac6,0x000dd6d1d9b0bb37,0x00050bf944970ed3,0x000e223b09a95584,0x000048d0acfa57cd}, {0x000f26e47dabe671,0x00097622f3a37b60,0x0009960394f1d1a1,0x0003bdb4208ce7ee,0x000016234191336d}}, +}, +{ /* slot=23 [{1,2,3,..,8} * 16^(2*23)] * G) */ +{{0x000499def6267ff6,0x0007b742c0843b9e,0x0009a4f2b17772ca,0x000500623a0153fe,0x00002cdfdfecd5d0}, {0x00099cd61ff38640,0x000c3063625a0dd4,0x000dd73dc329cd9b,0x000923151e2d8023,0x00004a25707a203b}, {0x0007668a53f6ed6a,0x000581dd170a12ab,0x000ae20161304242,0x00049fc4000144c3,0x00005721896d248e}}, +{{0x000e5517fd181bae,0x0009f2bb963b40b6,0x0002064625902262,0x00013da5509bce93,0x0000578edd74f63c}, {0x000d5091a1d0da4e,0x000a7b5fe3e08285,0x00019393b34baa6f,0x00030fd63e5177ce,0x000003c935afc4b0}, {0x000276c6492b0c3d,0x000c4dfe205fc997,0x000d623a3c47ccc2,0x000c7a2dcd29b84d,0x00003ec2ab590288}}, +{{0x0000d27be4d87bb9,0x000eb61391aeda1a,0x0003cb9b83a98b4d,0x000cace99a0ddd07,0x00002dd5c25a200f}, {0x00013a09ae32d1cb,0x000df40f5c2d5a72,0x00081eab290f2b87,0x000ac5e0baea4c6e,0x00000e1bf66c6adb}, {0x000bd5e9792c887e,0x00018cb926d5de2a,0x000aae5f1e1a0200,0x0008f5fbfba69cdb,0x0000730548b35ae8}}, +{{0x000551a3cba8b8ee,0x0001db2115f16c43,0x000b8c385065a26f,0x000b8ca760f4f52a,0x00003043443b411d}, {0x000b094ba1d6e334,0x0007709353f19805,0x000622702bbf3ef1,0x00045dd423f06cb0,0x0000585a2277d878}, {0x000a5f8233d48962,0x000b5ec78257fa18,0x00073e41ff6698c4,0x000981fa78e6fa53,0x00007656278950ef}}, +{{0x0003cf59d51fc8c0,0x000fd0506b6f238c,0x000b570e8f9bedd2,0x00046a626bf109fa,0x00003f4160a8c1b8}, {0x000073a3ea86cf9d,0x000b707155fdce17,0x0001838a8e3a8cfb,0x000f6164853e7fc3,0x000028bbf484b613}, {0x00012f5c6f136c7c,0x00007f6dd11bef26,0x0003de6f33afead1,0x000f75d527e9ad21,0x00001e79cb358188}}, +{{0x000436c3eef7e3f1,0x0007ffe9e10f8013,0x000cf9defc828b6a,0x00038317ff908e5b,0x000065d7951b3a3b}, {0x000953d8f5e08181,0x00044299dded977e,0x00064525e584a50c,0x000f2f4dc6c2d0c8,0x0000478ab52d39d1}, {0x0006a4d39252d159,0x000bc871ac80766a,0x0006c1c96fe5dde1,0x0002214b82c6b40a,0x000016d87a411a21}}, +{{0x000d7e5a42066215,0x000cd0c5a24c1b3b,0x0006f994b7879be3,0x0008ca657c05db1d,0x000028f87c8165f3}, {0x0004d5e2d54e0583,0x000d72ebd99fafba,0x000ee9778fe21faf,0x0006dde497ac2736,0x00001f990b577a5a}, {0x00044ead1be8f7d6,0x000ebacea798fa33,0x00020de0527d1e50,0x0006d3e77c6569e5,0x000045882fe1534d}}, +{{0x0009345d757983d6,0x0001117aa11a6666,0x00085e128f62b6ed,0x000f6dd7ddd18579,0x0000688fe5b8f626}, {0x000c9929943c6fe4,0x00061a38392a2d8a,0x000ec89af3b5f9f1,0x000f0742699db13b,0x00007dcf843ce405}, {0x0000d6484a4732c0,0x000fdca5632996c9,0x00015dc6e1d52143,0x000191bb3be28c39,0x00006739687e7327}}, +}, +{ /* slot=24 [{1,2,3,..,8} * 16^(2*24)] * G) */ +{{0x00082014385675a6,0x00030aafda9e8ef7,0x000cdfa8cba2649f,0x000c0b34cd1eb505,0x000046115aba1d4d}, {0x000dcc9dc80c1ac0,0x000f41b38a436a66,0x0005dbd7c697a05c,0x0007daba7ebf3be9,0x00007da0b8f68d7e}, {0x000f1953c3b5da76,0x0007321119e9bd40,0x000eb259601dac6f,0x0004b4b03cc6021f,0x00005a5f887e8367}}, +{{0x000301cf70a13d11,0x00015350dd0c48f6,0x0004bca47ecfceb8,0x0001434f70297d4a,0x00003669b656e44d}, {0x000628d3a0a643b9,0x00000e6c320649e9,0x000c2dec32b5c3cb,0x000c70c9b5302897,0x000043e37ae2d5d1}, {0x000e3f06eda6e133,0x0005199a13ac0387,0x000626381167301d,0x000e9bebd5ad8f83,0x00006a21e6cd4fd5}}, +{{0x0006170a3046e65f,0x0002a00d23524f1c,0x000c82b75558712a,0x000ff5769dbbd3c8,0x0000586bf9f1a195}, {0x000129126699b2e3,0x00047708d1301ef4,0x000182b0bd71d308,0x0008b36325432d01,0x000045371b07001e}, {0x000b088d5ef8790b,0x000dc610937e5a6d,0x0001a16eb85278f0,0x0002179ac0349d26,0x00000eafb03790e5}}, +{{0x000555c13748042f,0x000e6820baa11960,0x0003486d0c219a41,0x000c6611c81f7387,0x0000309acc675a02}, {0x0000805e0f75ae1d,0x000e32662cc30514,0x000a92396dec02fb,0x0005bb32cebdf1ee,0x000044ae3344c543}, {0x000289b9bba543ee,0x0009d5ac971429cf,0x000f9360aaf3760e,0x000678f1d82e5c64,0x000062d5221b7f94}}, +{{0x000c299c18d0936d,0x0006c8a0c1a0c524,0x000b4a8631c86bb5,0x0004562a375052ed,0x00005c0efde4bc75}, {0x0005d4263af77a3c,0x00011fee9144d758,0x0009f7193ddfae7b,0x0002037a50670805,0x000014f29a538392}, {0x00017edc25b2d7f5,0x000db99b53040df7,0x0003ed4c6221f970,0x000093eda9234b7c,0x00005e72365c7bee}}, +{{0x000bfc074571217f,0x0005d0694d95b575,0x0004191e33377967,0x000eabc9a0a37bbf,0x000077f1104c47b4}, {0x000339062f08b33e,0x000e5df9f32be7d9,0x000f9ebdfd5b9659,0x00049b7acff3dad1,0x000070b20555cb73}, {0x000113c555112c4c,0x0003a9a881fcdbe5,0x000e503b47668842,0x000404a446677855,0x00000e34398f4a06}}, +{{0x000d22d93ecebde8,0x0004127822f07b67,0x00005b6d8d09b3e8,0x0002372743fa61fb,0x00005e5405368a36}, {0x00030b093e4b1928,0x0000e73f3f640189,0x0003395d6f7de3e1,0x0009c3ef43217da7,0x00006f8aded6ca37}, {0x0000123dfdb7b29a,0x000e1a21ab291e34,0x000de6949e487b97,0x000de97f9967d02f,0x0000780de72ec8d3}}, +{{0x00028545089ae7bc,0x000cf1c7f4d060ae,0x000a4811b8388dde,0x0008ce438ac15510,0x00000eb28bf67192}, {0x000feaf300f42772,0x0002a2a8c41aa671,0x00073732928f72eb,0x00087a629a17fd79,0x00001defc6ad32b5}, {0x000bbe1aef5195a7,0x00077917b15edaf5,0x000ae5da2e148c12,0x00028672991f7fb7,0x0000467d201bf8dd}}, +}, +{ /* slot=25 [{1,2,3,..,8} * 16^(2*25)] * G) */ +{{0x000e919a74ef4fad,0x000ecf6a308a295f,0x0009a47b013a827b,0x000c797964e01d30,0x000071c43c4f5ba3}, {0x000ef4bd567ae7a9,0x000b2d64498bdbc1,0x000c1f4ec83f624c,0x0004001e41064d22,0x00002ef9c5a5ba38}, {0x000d6df6fa9e74cd,0x000bce4af267ab6f,0x0001ef990ef18278,0x000f2938255b3d0f,0x00005a758ca390c5}}, +{{0x00072710d9462495,0x000d2d57d5003a2b,0x0000b487ca3aa8c6,0x00072ece3d400bfa,0x00002dbae244b3eb}, {0x0000918b1d61dc94,0x000469a8130668ce,0x000fe8aad38ded36,0x000d43fd4e6a829a,0x00000a738027f639}, {0x000f4a2f57ffe1cc,0x0000de1839843980,0x0009fb15fd00670d,0x000a69c105c3f4a4,0x00002698ca635126}}, +{{0x0005318832b0ba78,0x000f7925cff8be76,0x0000291fcc381831,0x000eb0708a81b91a,0x00001fb43dcc49ca}, {0x000d702f5e3dd90e,0x00018e4d253862e3,0x00024da96a9e3f09,0x00033325e773ef60,0x00003c004b0c4afa}, {0x000946ac06f4b82b,0x000a5a806c4f39aa,0x0006cd47871ca284,0x000d2173ed3265fc,0x00006b43fd01cd1f}}, +{{0x00075d4b4697c544,0x00048df0fffbfc7a,0x000a46785a15fdf8,0x000f7142868b9eba,0x00005a68d7105b52}, {0x000742583e760ef3,0x000b9ee0ab990b5c,0x00072b923f75dc52,0x000d9f0bf1427c20,0x000073420b2d6ff0}, {0x000cf6cb9e851e06,0x00013c62238c4af2,0x0009fbf3738f5939,0x000bc9eda8ab8969,0x00003db5632fea34}}, +{{0x000eee2bf75dd9d8,0x000f6396759a5f46,0x00099e72730d17b1,0x0005f131bf2d1314,0x000004321adf49d7}, {0x000990b1829825d5,0x000873e9a89912e4,0x000c704af8edeaeb,0x0002b0eeef03d394,0x000059197ea495df}, {0x00016019e4e55aae,0x0007a7e2f92e904e,0x000f159aa4e77b43,0x0000cc0c7ce2dc16,0x000045eafdc1f4d7}}, +{{0x000401858045d72b,0x000a2cf2f0651698,0x000b222dc64c22fa,0x000dade941a36656,0x00005a5eebc80362}, {0x000e4624cfccb1ed,0x00092bd5c0395b60,0x000c0481c959dbc2,0x000d94031a09d1dd,0x00003f73ceea5d56}, {0x0007bfd10a4e8dc6,0x0007e44c9b339b7a,0x000557aefabe5700,0x00018db60c1207f1,0x0000260588912662}}, +{{0x000704a68360ff04,0x000de7661e6f459f,0x0002873551c3d93f,0x0005d57831b2a731,0x000054ad0c2e4e61}, {0x00018e3cc676e542,0x0009303ceccad4c8,0x0004129f085e422c,0x00043b8ec07cccab,0x00000dedfa10b244}, {0x000b67d5b82b522a,0x000469fa5c1ebee3,0x000ec19fd336f163,0x0009408a5b4d2f26,0x000062ecb2baa77a}}, +{{0x000d795261152b3d,0x0007d0eddd7d1e5e,0x00096b4c71496235,0x000d8be7482c8d0b,0x00002e59f919a966}, {0x00072836afb62874,0x0008579e104a5920,0x000630a14a5fcd5e,0x0003f985aad01adc,0x000061913d507566}, {0x00062d361a3231da,0x00032942002700dc,0x000f9594cefa4758,0x0005d5c02d801513,0x00003ddbc2a131c0}}, +}, +{ /* slot=26 [{1,2,3,..,8} * 16^(2*26)] * G) */ +{{0x000c0ff9ce5ec54b,0x0006b8c2f130d9ad,0x0000f89515039c2a,0x000b36b028007c7f,0x000078968314ac04}, {0x000a57a22796bb14,0x000b79b07da21f3a,0x0001a0391c883aba,0x00005f9e54be2183,0x00005ee7fb38d832}, {0x000dfdcb41446a8e,0x000a9434937f9538,0x00063c8c78a5acfd,0x0000d0946af908d2,0x000061d0633c9bca}}, +{{0x00044935ffdb2566,0x00089780b68bb637,0x00053eec03c5bd6b,0x000d7f56f1b32805,0x00006e965fd847ae}, {0x000328bcf8fc73df,0x0005da6f037fcada,0x0008c2a909ee8469,0x0007bdc637fb4db3,0x00005b23ac2df806}, {0x0002b953ee80527b,0x000aafade6d8d9ad,0x00050e82cfe88f19,0x000dedc0e7117041,0x000079b9bbb9dd95}}, +{{0x000355406a3126c2,0x000a868c8c393ebb,0x0005b97a82d26383,0x00021476c0c6429e,0x00005065f158c9fd}, {0x00097dae8e9f7374,0x000f8cfbb0816d19,0x000d445f0aa032a2,0x000b834cd6cba126,0x00001ba811460acc}, {0x000169fb0c429954,0x000acd76ecf67708,0x0000e645bae14600,0x000faf22eaab98a7,0x00003981f39e58a4}}, +{{0x000b8a7559230a93,0x0006960e6f45d18f,0x0004a93cb51d168f,0x000d0fd3a85a9451,0x000038dc083705ac}, {0x0005dfa56de66fde,0x000002c40483ac84,0x0007b4f632e152a5,0x0001b65e9d2e163c,0x000030f4452edcbc}, {0x000d2782c5759740,0x00069f99cbecc856,0x0000ea4e71fa1345,0x00024698844fc73c,0x0000632d9a1a593f}}, +{{0x000b6b15b807cba6,0x000dfbc54f0d7f6b,0x000e29670b1823c7,0x0004a57bb1d97036,0x00000b24f48847ed}, {0x0009fd11ed0c84a7,0x000810d9f693abf0,0x0007cf877963f071,0x0004ba221908c2d5,0x00003a5a7df28af6}, {0x000ad4be511beac7,0x00075ed26ccf2dcd,0x00005f9a65a45380,0x0001f63e19cff9f0,0x000034fcf7447548}}, +{{0x0007e04c789767ca,0x000cb38d9467dc19,0x0003f95fa8b8714d,0x00063f755de88828,0x00003d3bdc164dfa}, {0x000b1dab78cfaa98,0x00067190b72f2a5b,0x000a92608e5ceda2,0x00074b09309c9110,0x00000119a3042fb3}, {0x0002d89ce8c2177d,0x000f66895d0c167a,0x000282a2b0669da5,0x0000a73f56598e5b,0x000056c088f1ede2}}, +{{0x000d3d1110a86e17,0x000320b75b2fa336,0x0005072988d7f388,0x0008b87f91533762,0x000009674c6b9910}, {0x000b5fac24f38f02,0x000febae30cbd581,0x000acf92f0a90be9,0x000038f9a2169028,0x0000038b7ea48359}, {0x000ef82199316ff8,0x00082eaa78d4f9f4,0x000aef31742f49d2,0x000eb650971a5ab5,0x00006e5e31025969}}, +{{0x000c62f587e593fb,0x000deca5d3e71b16,0x0004cc3e6d4999ed,0x000dba8b491c1e01,0x000008f5114789a8}, {0x0004fb0e63066222,0x0008987acba3f330,0x000c1061a3fb3506,0x0008620bd1924778,0x00003058ad43d183}, {0x000c0ffde57663d0,0x00038a22ea610323,0x000c994f9a05c3df,0x000dc99bdc78abda,0x000026549fa4efe3}}, +}, +{ /* slot=27 [{1,2,3,..,8} * 16^(2*27)] * G) */ +{{0x000d5a461e6bf9d6,0x000fc7777a581741,0x000474d3d92305b3,0x000e0ffd45574a26,0x00001926e1dc6401}, {0x00068549af3f666e,0x00004f14a0ea5db4,0x0004ba0c47d77fcf,0x0003c853df23ff7a,0x00003a10dfe132ce}, {0x000f4e8aea17cea0,0x000463a1fc1fde07,0x0001f2c0f12fd515,0x0005d15175322fd3,0x00001fa1d01d861e}}, +{{0x000055947d599832,0x000da37f15520cc8,0x000e0593201e4656,0x000cf3399f6f7744,0x0000773563bc6a75}, {0x000cac00d1df94ab,0x000ddd1080de938d,0x000dd5e2622e712b,0x00001e57f13e93ef,0x000073fced18ee9a}, {0x0001e90863139cb3,0x00067c5a03ecd06b,0x000d638932a493da,0x0004f448d77cec8a,0x00001f426b701b86}}, +{{0x0009264c41911c01,0x000b817a22c25efc,0x00030f1447f1a3b7,0x000b0905875da6bf,0x00004e1af5271d31}, {0x000e35c891a12552,0x00053575e9c76f17,0x000d9b723eb76b81,0x000e438fa83406f0,0x00000b76bb1b3fa7}, {0x0008c1f97f92939b,0x000cbd444ab6e08b,0x0009bb8017be6771,0x000a95522e564639,0x00007b6dd61eb772}}, +{{0x000dc1e850f33d92,0x0004f608cd5cfb7a,0x000dfc5bdb7998fa,0x0002f4fad962dbd8,0x0000703e9bceaf1d}, {0x0000abf9ab01d2c7,0x000dc40143b18573,0x0000cbb28116fb76,0x0006afe866cbe65a,0x000053fa9b659bff}, {0x0004c8e994885455,0x0006665aed4e56c1,0x000cd65af1843a5d,0x0001f50181bb73eb,0x0000398d93e5c4c6}}, +{{0x000bd16733e248f3,0x0008715bf0a5f1c4,0x00010b0376bd9e12,0x0001b13d43f8cf0a,0x000053b09b5ddf19}, {0x00077c60d2e7e3f2,0x000a030828bb1c38,0x00039ef1383b34aa,0x0000577283e26e77,0x0000699c9c9002c3}, {0x0006a7235946f1cc,0x000b5cce5d97df30,0x0001b4e975921718,0x000d90728cdd2478,0x000051caf30c6fcd}}, +{{0x000ba7427674e00a,0x00070a17a7bf3a60,0x000f3324cc630e85,0x000fdaa3758563dc,0x00005504aa292383}, {0x000af99a18ac54c7,0x000dcc51cb30f737,0x000ce10cc7903378,0x000e99a2b89bc334,0x000012ae29c189f8}, {0x000ec0cb1f0d01cf,0x000cc3a34f7aea99,0x00009c4e220dd1ef,0x000a5ea55ca7521d,0x00005fd14fe958eb}}, +{{0x000c2ddf2845ab2c,0x000b10a7fe993b5d,0x000002e346069491,0x00074d14daaf3d64,0x0000093ff26e5864}, {0x0002fe5ebf93cb8e,0x0005136d4565f3c4,0x00084220e8bedfa8,0x000d128e0f0859e8,0x00007dd73f960725}, {0x000d24fe68059829,0x00072dbaf23e5b10,0x000457ac29757306,0x00070a41367253ab,0x00002f59bcbc86b4}}, +{{0x00047d429917135f,0x0001f567d03d7838,0x000e77aad1ad1b91,0x000af4a7e7748d9b,0x00005458b42e2e51}, {0x0001d560b691c301,0x0003fadd7e71e704,0x000133558585201b,0x00028b116c2e1631,0x00002aa55e3d0108}, {0x000192e60c07444f,0x0002d74421d10ed5,0x000db5c86442c54e,0x0008664352b4c82f,0x000013e9004a8a76}}, +}, +{ /* slot=28 [{1,2,3,..,8} * 16^(2*28)] * G) */ +{{0x000d8845832fcedb,0x000c9ae6bf863739,0x00074ffef7fa38d6,0x000e45e32bc0dcab,0x000073937e8814bc}, {0x000e00c9193b877f,0x00090e0dc506bbb2,0x0006de649fece3a8,0x0009e1aecf3b7c03,0x00005f46040898de}, {0x00037116297bf48d,0x00022d4f06834b90,0x000696bdc6a9d13b,0x000e835e19715574,0x00002cf8a4e891d5}}, +{{0x0003fd8707110f67,0x000d37c38b5496d9,0x0002736a86dd4c09,0x0002a097cb16a4cc,0x00002049bd6e5825}, {0x0005487e17d06ba2,0x0001c3950196b2cb,0x0005978a3024d238,0x000a4f6d7659c818,0x00007a6f7f2891d6}, {0x0009fd8d6a9aef49,0x000be5b3db90b7d0,0x00019ebfd4f0ee60,0x000941d4c21b52c5,0x00006011aadfc545}}, +{{0x0007926dcf95f83c,0x00061712890715f6,0x00098f7a5b7c7e85,0x000f9e0d6a1e7f39,0x00006fc5cc1b0b62}, {0x000ed0c802cbf890,0x000ca0dff6aaa63d,0x0009b6ed99fbd098,0x0000b1e624d0afdb,0x000069ce18b77934}, {0x000f5528b29879cb,0x0003cd47e9092d1e,0x00089f2352dd1aae,0x00001f1127e04421,0x000015596b3ae571}}, +{{0x000739d23f9179a2,0x0003197d6ddcf462,0x0003f2148aff8312,0x0004dda1307deb55,0x00000d2237687b5f}, {0x000f31167e5124ca,0x0008bd9c745df09f,0x000ef556e50be415,0x000d138292b7d227,0x00003aa4e241afb6}, {0x000138bf2a3305f5,0x0008fa2e926c32cc,0x000549d2eb48583f,0x000a36c083ab1a25,0x000032fcaa6e4687}}, +{{0x00056e8dc57d9af5,0x000ed9df0bdf27bc,0x0002efe4a33e0bd2,0x0006a5caac014de2,0x00004627e9cefebd}, {0x0007a4732787ccdf,0x00008f213e3f8320,0x00060d964e17e319,0x0000be9d5b2ecd7f,0x0000746f6336c260}, {0x000af345ab6c971c,0x000729943731f3f4,0x000344186de288eb,0x000629333596a8a0,0x00007b4917007ed6}}, +{{0x0005fb5cab84b064,0x000d289f3bc142d8,0x000b15ce0c497810,0x000fd7b476adc447,0x0000122ba376f844}, {0x00041b28dd53a2dd,0x0005bdf42fc3f543,0x000dd2f8f4aa1790,0x000d37d0ff592d94,0x00001d03620fe08c}, {0x000232cda2b4e554,0x00042115d187fc20,0x000dd479d99ed0fd,0x000ec4c2eabb4be7,0x000002c70bf52b68}}, +{{0x0007ec4b5d0b2fbb,0x00090074882caa28,0x0001d0815c415c57,0x000f5e0e044a61ec,0x000026334f0a409e}, {0x000532bf458d72e1,0x000e07cb73cb5ace,0x000e8bbde75be768,0x0003a0356cf7d94e,0x00006b0697e3feb4}, {0x0008f04adf62a3c0,0x000ef076da45db6c,0x0009f0d2a93ef000,0x0002fae9c9cb9584,0x00001cc37f43441b}}, +{{0x000f565a5cc7324f,0x000c0e506a922508,0x000c45ac19d061c4,0x000314afb18abdb5,0x00006c6809c10380}, {0x000656f1c9ceaeb9,0x000f818e5656ad76,0x00044c23341c5b15,0x000683826e728328,0x00003a346f772f19}, {0x00055112e2da6ac8,0x00031b1e851edd2d,0x000ec67262e9bd03,0x000c5d0960746dd8,0x000005911b9f6ef7}}, +}, +{ /* slot=29 [{1,2,3,..,8} * 16^(2*29)] * G) */ +{{0x00039983f5df0ebb,0x0008f512c4cacc13,0x000bb398e1c0f375,0x0000c622cf1130a0,0x00006b3cecf9aa27}, {0x0009acf3512eeaef,0x000d31cc1cb49534,0x00099a688d20c141,0x0002d1724180c07a,0x0000555ef9d1c64b}, {0x000770ba3b73bd08,0x00008a3afbf0c36a,0x00040946f2624aef,0x000749d5737ff98b,0x0000675f4de13381}}, +{{0x000c52036b1782fc,0x000816cad83b40e2,0x000964073e64816c,0x000c520d0dcbdd96,0x000013d99df70164}, {0x000ff6d93bdab31d,0x0000f9d652dfea12,0x000abe94870725d8,0x0003c43019c4ff39,0x000060f450b882cd}, {0x000b5ec321e5c0ca,0x000c9d719bfa2014,0x00050023a04fcb69,0x000ac804e5f1c187,0x00001c06de9e55ed}}, +{{0x000f7ad6a33ec4e2,0x00038be2ee08e990,0x00032845156608f9,0x000b60d9ca143c56,0x00004cf38a1fec2d}, {0x00052b40ff6d69aa,0x00018dc4049bbffd,0x00034d989734530b,0x000ba2d5e4a5c2fa,0x000078096f8e7d32}, {0x000aaa650dfa5ce7,0x0002a48b5478ca0a,0x000003725bf9c49e,0x0001abe4f09cc7d7,0x0000373cad3a2609}}, +{{0x0004634d82c9f57c,0x000e124934536b29,0x00018cdb5a1fcbfd,0x00019fc9e9c4db34,0x00000040f3d94544}, {0x000ea8fb89ddbbad,0x000bc61aeaecbf1b,0x000f9b8d9d3bcb2c,0x000a6868f58a7bb1,0x000021547eda5112}, {0x000de939fd5986d3,0x00089510a380cdef,0x000b3119b9f4272c,0x0004df4b72ba407b,0x000063550a334a25}}, +{{0x0007d6edb569cf37,0x000b00ca52ee1650,0x000b6bd65d178429,0x0008f51ea7c0090e,0x00003eea62c7daf7}, {0x000a584572547b49,0x000fae2c408e09bb,0x000734f18df305c6,0x000767a60e8fa69c,0x000039a92bafaa7d}, {0x0004c713e693274e,0x0007768dbd3759d2,0x000b8ab39a5f6385,0x000c4cd70525560e,0x000068436a0665c9}}, +{{0x000235e8202f3f27,0x000e264f975b0bc0,0x00038c2416c75c00,0x00089f991a4e9d5a,0x000017b6e7f68ab7}, {0x0006d317e820107c,0x00044840ae9651e5,0x00020ffc7ac52668,0x0001472c1e0a1c63,0x00005373669c9161}, {0x000814ab9a0e5257,0x00084c9cab3fc5d2,0x000b2d1eca908f20,0x0007d11afcaf5885,0x00001cb4b5a678f8}}, +{{0x0004c06b394afc6c,0x0002498da5fb1b66,0x000bcad8340c88de,0x00034a24f8d03164,0x0000330bca78de74}, {0x0004aa62a2a007e7,0x000b0f071c7b16b7,0x00000be223f311e0,0x0006eac5707e4380,0x00002dc0fd2d82ef}, {0x000eff841119744e,0x000962b074724982,0x000fc953fbf9695e,0x0001cf5c58ac14fb,0x00003c31be1b369f}}, +{{0x0004864d08948aee,0x000ee91ba1c6fb0f,0x0006aca15807dc19,0x000d4bb7975cdaea,0x0000330b61134262}, {0x0008bc93f9cb4272,0x0001fc7cedb98c16,0x0004ac8d7aaeb871,0x00055bb7f0e52aa3,0x000041cec1097e7d}, {0x000619d7a26d808a,0x0009e1d9e156df79,0x000ba1df27bb1fd4,0x000777d73d7c36cd,0x000026b44cd91f28}}, +}, +{ /* slot=30 [{1,2,3,..,8} * 16^(2*30)] * G) */ +{{0x000048478f387475,0x000f49cbecb3c51f,0x00099f2055b25dbc,0x000a5d69aab1244d,0x00002c709e6c1c10}, {0x0007f29362730383,0x000ffebca8a2ce1b,0x000fd413144b5279,0x000610fdafc778ab,0x00007deb10149c72}, {0x0002af6a8766ee7a,0x000045553cd0ecb6,0x000f0be4b566cbec,0x000e2ea588001380,0x000008e68e9ff62c}}, +{{0x000d500a4bc130ad,0x000493d0bd49c34a,0x00000a89be8d38db,0x0003b09a25c3d985,0x00002f1f3f87eeba}, {0x000d09d50ab8f2f9,0x0008dc55923df2f2,0x0003766cb9acb921,0x00019f54a8f34267,0x00004cb13bd738f7}, {0x00048c75e515b64a,0x000badb4a9038f78,0x000f751b50a59501,0x0002ee8c20d313f3,0x000019a1e353c0ae}}, +{{0x000c7560bafa05c3,0x000a0c6e55e617d1,0x0000d66473b3e1a0,0x0003486e3529718c,0x000041546b11c20c}, {0x000172cdd596bdbd,0x0004398eefc40b42,0x00044109b593e045,0x000ae349fb15347b,0x0000736bd3990266}, {0x00032d509334b3b4,0x0004b60816573855,0x00025c837546fd11,0x000ab5ccc5f5f304,0x0000412295a2b87f}}, +{{0x00099b88f57ed6e9,0x000266df8c82519c,0x00030ad2735393cb,0x0002e345cee3213b,0x000014e153ebb52d}, {0x00055261e293eac6,0x000032133acdb2e6,0x000900996b845a92,0x000dd80460975cb7,0x00000760bb8d195a}, {0x000e1a17cde6818a,0x000a9ed69a084413,0x0006caccb157156d,0x000c5f22cbf268f4,0x00006b34be9bc33a}}, +{{0x000f2f643a78c0b2,0x0001ef22e027cf3d,0x0009c1b5a34c3e97,0x000dd2dec7d1c5e4,0x00002012c18f0922}, {0x000c69656571f2d3,0x00045530e737a11f,0x0004fe5035c6c9e8,0x000d30be33ae7a2d,0x000001b9c7b62e6d}, {0x000b55e55ac89d29,0x0001f45a0a763880,0x0002e76c1f148324,0x000ade83d36efdfc,0x000008af5b784e4b}}, +{{0x000499dc881f2533,0x000da779323b6283,0x00073441f49d0525,0x000168d897addfb6,0x000032b79d71163a}, {0x000314d289cc2c4b,0x00011a287178de27,0x000a3364ce4be4bd,0x000826e18d528d6f,0x00006423c1d5afd9}, {0x0005f8d9edfcb36a,0x0008f3746e5f9cc8,0x0009e5d3cd22bcc2,0x0002dcce49de338f,0x0000480a5efbc13e}}, +{{0x0001e70b01622071,0x000cf8b1dafc50b5,0x000f5aabcd06b505,0x000bf312c6bb061e,0x000047aa27600cb7}, {0x00014ce442ce221f,0x000cc4c053928b66,0x000c1cbe036e199d,0x0008e06663fb4a4d,0x000024b31d47691c}, {0x00041eedc015f8c3,0x0007e7c693f7c2a5,0x000ea278d611a4fe,0x000a094f0af66134,0x0000545b585d14dd}}, +{{0x000f275ea0d43a0f,0x00034089beebe67b,0x000479e72eade68e,0x00054544289134cd,0x00000f62f9c332ba}, {0x0004e4d0e3b321e1,0x0007a28ff1e95620,0x000b99bd9e3baa63,0x000d0710b0ccffd5,0x00004d22dc3e64c8}, {0x00046589d63b5f39,0x0003f57cbcf61fcb,0x00053afa055cae6a,0x0001436febac2d29,0x00001c0fa01a3637}}, +}, +{ /* slot=31 [{1,2,3,..,8} * 16^(2*31)] * G) */ +{{0x000604b622943dff,0x000ce44cfb3a0d2c,0x0007808678bc8cbe,0x000a6bf5d254ff39,0x00000fa3614f3b1c}, {0x00082b0e8c936a50,0x00035c1dac5b6690,0x0004dfb634f9c9a0,0x000c1406fb73e54c,0x00004005419b1d2b}, {0x0003febdb9be82f0,0x000af3a44ac90a00,0x000954fa8e2089c1,0x000ab42f8499f911,0x00001fba218aef40}}, +{{0x00049448fac8f53e,0x0009a7ba63741ab5,0x000c2b5e0181f6e8,0x0006e4274fd6c7d6,0x0000392e3acaa8c8}, {0x000e57043e7b0194,0x000ee08daaf7f4f3,0x0009dcdef1a81d3e,0x00061d5c839c6ab9,0x00006c535d13ff77}, {0x000d34e93e8a35af,0x000445887e8164cb,0x00029ab0ab2e0781,0x000c13b19319c76f,0x000025e17fe4d50a}}, +{{0x00089bd71e04f676,0x00052d6420f950a2,0x0004691fab208e1c,0x000b3515186d8b03,0x0000255751442a9f}, {0x000f7ff576f121a7,0x000272fcd87e3915,0x000d1be526c34a32,0x000899bccba2fde4,0x00006bba828f8969}, {0x0001bc6690fe3901,0x00018a0997ad5e2d,0x000f8460d44cb54a,0x0007be4971d6914a,0x0000559d504f7f6b}}, +{{0x00038378b3eb54d5,0x00066a5553c7ca77,0x00092800ba1d69d3,0x00032170a26cf62f,0x000001ab12d5807e}, {0x000891e7f6d266fd,0x0009b0307781b9c4,0x000061e23b0744a1,0x000d50e88388f1d6,0x0000123ea6a3354b}, {0x000d189041e32d96,0x000c2d8315848118,0x00083245d9b9ede3,0x000a1541eab4271d,0x00004a3961e2c918}}, +{{0x000c3be0f8e6bba0,0x000347effe30a71d,0x00013a476ad6cef8,0x000b763a992425fe,0x00002cd6bce3fb1d}, {0x0007d644f3233f1e,0x0000e34fcf016032,0x0002dab979499a26,0x000111f83b5a716f,0x000068aceead9bd4}, {0x0004c90ef3d7c210,0x00024b7ad040c38b,0x0007e73e23308e6e,0x000f5973860d9f1b,0x0000595760d5b508}}, +{{0x0009bfe104aa6397,0x00008a4a7fccb612,0x000d9094588f9600,0x00091a93f8bc0897,0x0000709fa43edcb2}, {0x000acbebfd022790,0x00005c4115760882,0x000d3473f489af33,0x0005a2b65f492e37,0x00002cb2c5df5451}, {0x000a5d8c63fd2aca,0x000662e694effeb0,0x0008cbb03ad22bc1,0x000131f2723f36ef,0x000070f029ecf0c8}}, +{{0x000307b32eed3e33,0x00033a45581e7461,0x00095f0366ae042f,0x0004858c94449d31,0x00000b7d5d8a6c31}, {0x000aafaa5e10b0b9,0x00070ef041aa92a6,0x000a3ad61f78f0a3,0x000d9e1773efb77a,0x000044eca5a2a74b}, {0x000448327b95d543,0x00000a3340f1d25d,0x0000e1c52b70d383,0x000e9e4de1c531c6,0x0000272224512c7d}}, +{{0x000c92af49c5342e,0x00011b2e6fad01ab,0x000cc84e29ffeed8,0x000c543efa28c8df,0x000011b5df18a44c}, {0x000bbb8a42a975fc,0x0007796ada358bf7,0x000dedaa488c5c39,0x00020a6e27fc76fc,0x000019735fd7f6bc}, {0x000b90d042c84266,0x0000f7f19547ee3a,0x0005a497b9eb848e,0x000895f2503a1d06,0x00000fef911191df}}, +}, +}; + +#endif /* #define IFMA_ED25519_PRECOMP_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/sha512.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/sha512.h new file mode 100644 index 000000000..4f651264b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/ed25519/sha512.h @@ -0,0 +1,171 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Macros and definitions that is necessary for SHA512 computation +*/ + +#include + +/* define 64-bit constant */ +#if !defined(__GNUC__) +#define CONST_64(x) (x) /*(x##i64)*/ +#else +#define CONST_64(x) (x##LL) +#endif + +static const int64u sha512_iv[] = { + CONST_64(0x6A09E667F3BCC908), CONST_64(0xBB67AE8584CAA73B), + CONST_64(0x3C6EF372FE94F82B), CONST_64(0xA54FF53A5F1D36F1), + CONST_64(0x510E527FADE682D1), CONST_64(0x9B05688C2B3E6C1F), + CONST_64(0x1F83D9ABFB41BD6B), CONST_64(0x5BE0CD19137E2179) }; + +static __ALIGN64 const int64u sha512_cnt[] = { + CONST_64(0x428A2F98D728AE22), CONST_64(0x7137449123EF65CD), CONST_64(0xB5C0FBCFEC4D3B2F), CONST_64(0xE9B5DBA58189DBBC), + CONST_64(0x3956C25BF348B538), CONST_64(0x59F111F1B605D019), CONST_64(0x923F82A4AF194F9B), CONST_64(0xAB1C5ED5DA6D8118), + CONST_64(0xD807AA98A3030242), CONST_64(0x12835B0145706FBE), CONST_64(0x243185BE4EE4B28C), CONST_64(0x550C7DC3D5FFB4E2), + CONST_64(0x72BE5D74F27B896F), CONST_64(0x80DEB1FE3B1696B1), CONST_64(0x9BDC06A725C71235), CONST_64(0xC19BF174CF692694), + CONST_64(0xE49B69C19EF14AD2), CONST_64(0xEFBE4786384F25E3), CONST_64(0x0FC19DC68B8CD5B5), CONST_64(0x240CA1CC77AC9C65), + CONST_64(0x2DE92C6F592B0275), CONST_64(0x4A7484AA6EA6E483), CONST_64(0x5CB0A9DCBD41FBD4), CONST_64(0x76F988DA831153B5), + CONST_64(0x983E5152EE66DFAB), CONST_64(0xA831C66D2DB43210), CONST_64(0xB00327C898FB213F), CONST_64(0xBF597FC7BEEF0EE4), + CONST_64(0xC6E00BF33DA88FC2), CONST_64(0xD5A79147930AA725), CONST_64(0x06CA6351E003826F), CONST_64(0x142929670A0E6E70), + CONST_64(0x27B70A8546D22FFC), CONST_64(0x2E1B21385C26C926), CONST_64(0x4D2C6DFC5AC42AED), CONST_64(0x53380D139D95B3DF), + CONST_64(0x650A73548BAF63DE), CONST_64(0x766A0ABB3C77B2A8), CONST_64(0x81C2C92E47EDAEE6), CONST_64(0x92722C851482353B), + CONST_64(0xA2BFE8A14CF10364), CONST_64(0xA81A664BBC423001), CONST_64(0xC24B8B70D0F89791), CONST_64(0xC76C51A30654BE30), + CONST_64(0xD192E819D6EF5218), CONST_64(0xD69906245565A910), CONST_64(0xF40E35855771202A), CONST_64(0x106AA07032BBD1B8), + CONST_64(0x19A4C116B8D2D0C8), CONST_64(0x1E376C085141AB53), CONST_64(0x2748774CDF8EEB99), CONST_64(0x34B0BCB5E19B48A8), + CONST_64(0x391C0CB3C5C95A63), CONST_64(0x4ED8AA4AE3418ACB), CONST_64(0x5B9CCA4F7763E373), CONST_64(0x682E6FF3D6B2B8A3), + CONST_64(0x748F82EE5DEFB2FC), CONST_64(0x78A5636F43172F60), CONST_64(0x84C87814A1F0AB72), CONST_64(0x8CC702081A6439EC), + CONST_64(0x90BEFFFA23631E28), CONST_64(0xA4506CEBDE82BDE9), CONST_64(0xBEF9A3F7B2C67915), CONST_64(0xC67178F2E372532B), + CONST_64(0xCA273ECEEA26619C), CONST_64(0xD186B8C721C0C207), CONST_64(0xEADA7DD6CDE0EB1E), CONST_64(0xF57D4F7FEE6ED178), + CONST_64(0x06F067AA72176FBA), CONST_64(0x0A637DC5A2C898A6), CONST_64(0x113F9804BEF90DAE), CONST_64(0x1B710B35131C471B), + CONST_64(0x28DB77F523047D84), CONST_64(0x32CAAB7B40C72493), CONST_64(0x3C9EBE0A15C9BEBC), CONST_64(0x431D67C49C100D4C), + CONST_64(0x4CC5D4BECB3E42B6), CONST_64(0x597F299CFC657E2A), CONST_64(0x5FCB6FAB3AD6FAEC), CONST_64(0x6C44198C4A475817) +}; + +/* SHA512 constants */ +#define SHA512_DIGEST_BITSIZE 512 +#define BYTESIZE (8) + +#define MBS_SHA512 (128) +#define MLR_SHA512 (sizeof(int64u)*2) + +/* Logical Shifts (right and left) of WORD */ +#define LSR32(x,nBits) ((x)>>(nBits)) +#define LSL32(x,nBits) ((x)<<(nBits)) + +/* Rorate (right and left) of WORD */ +#if defined(_MSC_VER) && !defined( __ICL ) +# include +# define ROR32(x, nBits) _lrotr((x),(nBits)) +# define ROL32(x, nBits) _lrotl((x),(nBits)) +#else +# define ROR32(x, nBits) (LSR32((x),(nBits)) | LSL32((x),32-(nBits))) +# define ROL32(x, nBits) ROR32((x),(32-(nBits))) +#endif + +/* Logical Shifts (right and left) of DWORD */ +#define LSR64(x,nBits) ((x)>>(nBits)) +#define LSL64(x,nBits) ((x)<<(nBits)) + +/* Rorate (right and left) of DWORD */ +#define ROR64(x, nBits) (LSR64((x),(nBits)) | LSL64((x),64-(nBits))) +#define ROL64(x, nBits) ROR64((x),(64-(nBits))) + +/* WORD and DWORD manipulators */ +#define LODWORD(x) ((int32u)(x)) +#define HIDWORD(x) ((int32u)(((int64u)(x) >>32) & 0xFFFFFFFF)) +#define MAKEDWORD(wLo,wHi) ((int64u)(((int32u)(wLo)) | ((int64u)((int32u)(wHi))) << 32)) + +/* Change endian */ +#if defined(_MSC_VER) +# define ENDIANNESS(x) _byteswap_ulong((x)) +# define ENDIANNESS32(x) ENDIANNESS((x)) +# define ENDIANNESS64(x) _byteswap_uint64((x)) +#elif defined(__ICL) +# define ENDIANNESS(x) _bswap((x)) +# define ENDIANNESS32(x) ENDIANNESS((x)) +# define ENDIANNESS64(x) _bswap64((x)) +#else +# define ENDIANNESS(x) ((ROR32((x), 24) & 0x00ff00ff) | (ROR32((x), 8) & 0xff00ff00)) +# define ENDIANNESS32(x) ENDIANNESS((x)) +# define ENDIANNESS64(x) MAKEDWORD(ENDIANNESS(HIDWORD((x))), ENDIANNESS(LODWORD((x)))) +#endif + +#ifndef MIN +#define MIN( a, b ) ( ((a) < (b)) ? (a) : (b) ) +#endif + +/* +// SHA512 Specific Macros +// +// Note: All operations act on DWORDs (64-bits) +*/ + +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define SUM0(x) (ROR64((x),28) ^ ROR64((x),34) ^ ROR64((x),39)) +#define SUM1(x) (ROR64((x),14) ^ ROR64((x),18) ^ ROR64((x),41)) + +#define SIG0(x) (ROR64((x), 1) ^ ROR64((x), 8) ^ LSR64((x), 7)) +#define SIG1(x) (ROR64((x),19) ^ ROR64((x),61) ^ LSR64((x), 6)) + +#define SHA512_UPDATE(i) \ + wdat[i&15] += SIG1(wdat[(i+14)&15]) + wdat[(i+9)&15] + SIG0(wdat[(i+1)&15]) + +#define SHA512_STEP(i,j) \ + v[(7-i)&7] += (j ? SHA512_UPDATE(i) : wdat[i&15]) \ + + SHA512_cnt_loc[i+j] \ + + SUM1(v[(4-i)&7]) \ + + CH(v[(4-i)&7], v[(5-i)&7], v[(6-i)&7]); \ + v[(3-i)&7] += v[(7-i)&7]; \ + v[(7-i)&7] += SUM0(v[(0-i)&7]) + MAJ(v[(0-i)&7], v[(1-i)&7], v[(2-i)&7]) + + +/* +// SHA512 structures and data types +*/ + +/* SHA512 digest */ +typedef int64u DigestSHA512[8]; + +/* SHA512 context */ +struct _cpSHA512 { + int msgBuffIdx; /* buffer entry */ + int64u msgLenLo; /* message length */ + int64u msgLenHi; /* message length */ + int8u msgBuffer[MBS_SHA512]; /* buffer */ + DigestSHA512 msgHash; /* intermediate hash */ +}; +typedef struct _cpSHA512 SHA512State; + +#define HASH_LENLO(stt) ((stt)->msgLenLo) +#define HASH_LENHI(stt) ((stt)->msgLenHi) +#define HASH_VALUE(stt) ((stt)->msgHash) +#define HASH_BUFFIDX(stt) ((stt)->msgBuffIdx) +#define HASH_BUFF(stt) ((stt)->msgBuffer) + +/* +// SHA512 internal functions +*/ + +void SHA512MsgDigest(const int8u* pMsg, int len, int8u* pMD); +void SHA512Init(SHA512State* pState); +void SHA512Update(const int8u* pSrc, int len, SHA512State* pState); +void SHA512Final(int8u* pMD, SHA512State* pState); + diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/exp/ifma_exp_method.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/exp/ifma_exp_method.h new file mode 100644 index 000000000..59f551195 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/exp/ifma_exp_method.h @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_EXP_METHOD_H +#define IFMA_EXP_METHOD_H + +#include + +/* exponetiation processing window */ +#define EXP_WIN_SIZE (5) +#define EXP_WIN_MASK ((1< +#include + +#define ALIGNSPEC __ALIGN64 + +#define DUP2_DECL(a) a, a +#define DUP4_DECL(a) DUP2_DECL(a), DUP2_DECL(a) +#define DUP8_DECL(a) DUP4_DECL(a), DUP4_DECL(a) + + +//gres: typedef unsigned __int64 UINT64; +typedef int64u UINT64; + + +#define VUINT64 __m512i +#define VINT64 VUINT64 +#define VDOUBLE __m512d +#define VMASK_L __mmask8 + +#define L2D(x) _mm512_castsi512_pd(x) +#define D2L(x) _mm512_castpd_si512(x) + +// Load int constant +#define VLOAD_L(addr) _mm512_load_epi64((__m512i const*)&(addr)[0]); +// Load DP constant +#define VLOAD_D(addr) _mm512_load_pd((const double*)&(addr)[0]); +#define VSTORE_L(addr, x) _mm512_store_epi64(((__m512i*)&(addr)[0]), (x)); + + +#define VSHL_L(x, n) _mm512_slli_epi64((x), (n)); +#define VSAR_L(x, n) _mm512_srai_epi64((x), (n)); +#define VAND_L(a, b) _mm512_and_epi64((a), (b)); +#define VADD_L(a, b) _mm512_add_epi64((a), (b)); +#define VSUB_L(a, b) _mm512_sub_epi64((a), (b)); +#define VMSUB_L(mask, a, b) _mm512_mask_sub_epi64((a), mask, (a), (b)); +#define VMADD_L(mask, a, b) _mm512_mask_add_epi64((a), mask, (a), (b)); +#define VCMPU_GT_L(a, b) _mm512_cmpgt_epu64_mask((a), (b)); +#define VCMP_GE_L(a, b) _mm512_cmpge_epi64_mask((a), (b)); + + +// conversion unsigned 64-bit -> double +#define VCVT_L2D(x) _mm512_cvtepu64_pd(x) +// conversion double -> signed 64-bit +#define VCVT_D2L(x) _mm512_cvtpd_epi64(x) + +#define VADD_D(a, b) _mm512_add_pd(a, b) +#define VMUL_D(a, b) _mm512_mul_pd(a, b) +#define VMUL_RZ_D(a, b) _mm512_mul_round_pd(a, b, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC) +#define VMUL_RU_D(a, b) _mm512_mul_round_pd(a, b, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) +#define VDIV_RZ_D(a, b) _mm512_div_round_pd(a, b, _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC) +#define VDIV_RU_D(a, b) _mm512_div_round_pd(a, b, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) +#define VROUND_RZ_D(a) _mm512_roundscale_pd(a, 3) +#define VQFMR_D(a, b, c) _mm512_fnmadd_pd(a, b, c) diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_arith.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_arith.h new file mode 100644 index 000000000..679346596 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_arith.h @@ -0,0 +1,182 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_RSA_ARITH_H +#define IFMA_RSA_ARITH_H + +#ifndef BN_OPENSSL_DISABLE + #include +#endif + +#include +#include + +typedef int64u int64u_x8[8]; // alias of 8-term vector of int64u each +typedef int64u (*pint64u_x8) [8]; // pointer to 8-term vector of int64u each + +/* fixed size of RSA */ +#define RSA_1K (1024) +#define RSA_2K (2*RSA_1K) +#define RSA_3K (3*RSA_1K) +#define RSA_4K (4*RSA_1K) + +#define NUMBER_OF_DIGITS(bitsize, digsize) (((bitsize) + (digsize)-1)/(digsize)) +#define MULTIPLE_OF(x, factor) ((x) + (((factor) -((x)%(factor))) %(factor))) + +// ============ Multi-Buffer required functions ============ +#define redLen ((RSA_1K+(DIGIT_SIZE-1))/DIGIT_SIZE) // 20 +EXTERN_C void ifma_extract_amm52x20_mb8(int64u* out_mb8, const int64u* inpA_mb8, int64u MulTbl[][redLen][8], const int64u Idx[8], const int64u* inpM_mb8, const int64u* k0_mb8); + +// Multiplication +EXTERN_C void ifma_amm52x10_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void ifma_amm52x20_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void ifma_amm52x60_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void ifma_amm52x40_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void ifma_amm52x30_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void ifma_amm52x79_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); + +// New functions for almost half montgomery +EXTERN_C void ifma_ahmm52x20_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpBx_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void ifma_ahmr52x20_mb8(int64u* out_mb, const int64u* inpA_mb, int64u* inpM_mb, const int64u* k0_mb); + +// 4x Mont Mul +EXTERN_C void ifma_amm52x20_mb4(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); + +// Diagonal sqr +EXTERN_C void AMS52x10_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void AMS5x52x10_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); + +EXTERN_C void AMS52x20_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void AMS4x52x20_diagonal_stitched_with_extract_mb8(int64u* out_mb8, U64* mulb, U64* mulbx, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8, int64u MulTbl[][redLen][8], int64u MulTblx[][redLen][8], const int64u Idx[8]); +EXTERN_C void AMS5x52x20_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); + +EXTERN_C void AMS52x40_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void AMS5x52x40_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); + +EXTERN_C void AMS52x30_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void AMS52x60_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void AMS52x79_diagonal_mb8(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); + +// 4x Diagonal sqr +EXTERN_C void AMS52x20_diagonal_mb4(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +EXTERN_C void AMS5x52x20_diagonal_mb4(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); + +// clear/copy mb8 buffer +EXTERN_C void zero_mb8(int64u(*redOut)[8], int len); +EXTERN_C void copy_mb8(int64u out[][8], const int64u inp[][8], int len); + +// other 2^52 radix arith functions +EXTERN_C void ifma_montFactor52_mb8(int64u k0_mb8[8], const int64u m0_mb8[8]); + +EXTERN_C void ifma_modsub52x10_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]); +EXTERN_C void ifma_modsub52x20_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]); +EXTERN_C void ifma_modsub52x30_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]); +EXTERN_C void ifma_modsub52x40_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]); + +EXTERN_C void ifma_addmul52x10_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8]); +EXTERN_C void ifma_addmul52x20_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8]); +EXTERN_C void ifma_addmul52x30_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8]); +EXTERN_C void ifma_addmul52x40_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8]); + +EXTERN_C void ifma_amred52x10_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpM[][8], const int64u k0[8]); +EXTERN_C void ifma_amred52x20_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpM[][8], const int64u k0[8]); +EXTERN_C void ifma_amred52x30_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpM[][8], const int64u k0[8]); +EXTERN_C void ifma_amred52x40_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpM[][8], const int64u k0[8]); + +EXTERN_C void ifma_mreduce52x_mb8(int64u pX[][8], int nsX, int64u pM[][8], int nsM); +EXTERN_C void ifma_montRR52x_mb8(int64u pRR[][8], int64u pM[][8], int convBitLen); + +// exponentiations +EXTERN_C void EXP52x10_mb8(int64u out[][8], + const int64u base[][8], + const int64u exponent[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0_mb8[8], + int64u work_buffer[][8]); + +EXTERN_C void EXP52x20_mb8(int64u out[][8], + const int64u base[][8], + const int64u exponent[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0_mb8[8], + int64u work_buffer[][8]); + +EXTERN_C void EXP52x40_mb8(int64u out[][8], + const int64u base[][8], + const int64u exponent[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0_mb8[8], + int64u work_buffer[][8]); + +EXTERN_C void EXP52x60_mb8(int64u out[][8], + const int64u base[][8], + const int64u exponent[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0_mb8[8], + int64u work_buffer[][8]); + +EXTERN_C void EXP52x30_mb8(int64u out[][8], + const int64u base[][8], + const int64u exponent[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0_mb8[8], + int64u work_buffer[][8]); + +EXTERN_C void EXP52x79_mb8(int64u out[][8], + const int64u base[][8], + const int64u exponent[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0_mb8[8], + int64u work_buffer[][8]); + +// exponentiations (fixed short exponent ==65537) +EXTERN_C void EXP52x20_pub65537_mb8(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]); + + +EXTERN_C void EXP52x40_pub65537_mb8(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]); + +EXTERN_C void EXP52x60_pub65537_mb8(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]); + +EXTERN_C void EXP52x79_pub65537_mb8(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]); + +#endif /* _IFMA_INTERNAL_H_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_layer_cp.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_layer_cp.h new file mode 100644 index 000000000..8b434847f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_layer_cp.h @@ -0,0 +1,48 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_CP_LAYER_H +#define IFMA_CP_LAYER_H + +#include +#include + +EXTERN_C void ifma_cp_rsa_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); +EXTERN_C void ifma_cp_rsa_prv2_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const d_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); +EXTERN_C void ifma_cp_rsa_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const p_pa[8], + const int64u* const q_pa[8], + const int64u* const dp_pa[8], + const int64u* const dq_pa[8], + const int64u* const iq_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer); + +#endif /* IFMA_CP_LAYER_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_layer_ssl.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_layer_ssl.h new file mode 100644 index 000000000..e8145909a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_layer_ssl.h @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef BN_OPENSSL_DISABLE + +#if !defined(_IFMA_INTERNAL_SSL_LAYER_H_) +#define _IFMA_INTERNAL_SSL_LAYER_H_ + +#include +#include + +EXTERN_C void ifma_ssl_rsa1K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]); +EXTERN_C void ifma_ssl_rsa2K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]); +EXTERN_C void ifma_ssl_rsa3K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]); +EXTERN_C void ifma_ssl_rsa4K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]); + +EXTERN_C void ifma_ssl_rsa1K_prv2_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const d_pa[8], + const BIGNUM* const n_pa[8]); +EXTERN_C void ifma_ssl_rsa2K_prv2_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const d_pa[8], + const BIGNUM* const n_pa[8]); +EXTERN_C void ifma_ssl_rsa3K_prv2_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const d_pa[8], + const BIGNUM* const n_pa[8]); +EXTERN_C void ifma_ssl_rsa4K_prv2_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const d_pa[8], + const BIGNUM* const n_pa[8]); + +EXTERN_C void ifma_ssl_rsa1K_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8]); +EXTERN_C void ifma_ssl_rsa2K_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8]); +EXTERN_C void ifma_ssl_rsa3K_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8]); +EXTERN_C void ifma_ssl_rsa4K_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8]); +#endif /* _IFMA_INTERNAL_SSL_LAYER_H_ */ + +#endif /* BN_OPENSSL_DISABLE */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_method.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_method.h new file mode 100644 index 000000000..63874f09d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/rsa/ifma_rsa_method.h @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_RSA_METHOD_H +#define IFMA_RSA_METHOD_H + +#include + + +/* exponentiations */ +typedef void(*EXP52x_65537_mb8)(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]); +typedef void(*EXP52x_mb8)(int64u out[][8], + const int64u base[][8], + const int64u exponent[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0_mb8[8], + int64u work_buffer[][8]); + + +/* +// auxiliary mb8 arithmethic +*/ +/* Mont reduction */ +typedef void (*amred52x_mb8)(int64u res[][8], const int64u inpA[][8], const int64u inpM[][8], const int64u k0[8]); +/* Mont multiplication */ +typedef void (*ammul52x_mb8)(int64u* out_mb8, const int64u* inpA_mb8, const int64u* inpB_mb8, const int64u* inpM_mb8, const int64u* k0_mb8); +/* modular subtraction */ +typedef void (*modsub52x_mb8)(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]); +/* multiply and add */ +typedef void (*addmul52x_mb8)(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8]); + +/* RSA operation */ +typedef enum { + RSA_PUB_KEY = (0x01<<16), + RSA_PRV2_KEY = (0x20<<16), + RSA_PRV5_KEY = (0x50<<16), +} RSA_OP_ID; + +/* RSA size */ +typedef enum { + RSA1024 = 1024, + RSA2048 = 2048, + RSA3072 = 3072, + RSA4096 = 4096, +} RSA_BITSIZE_ID; + +/* RSA ID */ +#define RSA_ID(OP,BITSIZE) ((OP) | (BITSIZE)) +#define OP_RSA_ID(ID) ((ID) & (0xFF<<16)) +#define BISIZE_RSA_ID(ID) ((ID) & 0xFFFF) + +struct _ifma_rsa_method { + int id; /* exponentiation's id (=1/2/5 -- public(fixed)/private/private_crt */ + int rsaBitsize; /* size of rsa modulus (bits) */ + int buffSize; /* size of scratch buffer */ + //cvt52BN_to_mb8 cvt52; /* convert non-contiguos BN to radix 2^52 and strore in mb8 forman */ + //tcopyBN_to_mb8 tcopy; /* copy non-contiguos BN into mb8 format */ + EXP52x_65537_mb8 expfunc65537; /* "exp52x_fix_mb8" fixed exponentiation */ + EXP52x_mb8 expfun; /* "exp52x_arb_mb8" exponentiation */ + amred52x_mb8 amred52x; /* reduction */ + ammul52x_mb8 ammul52x; /* multiplication */ + modsub52x_mb8 modsub52x; /* subtration */ + addmul52x_mb8 mla52x; /* multiply & add */ +}; + +#endif /* IFMA_RSA_METHOD_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_arith_sm2.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_arith_sm2.h new file mode 100644 index 000000000..c58ca84de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_arith_sm2.h @@ -0,0 +1,136 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_SM2_H +#define IFMA_ARITH_SM2_H + +#include +#include +#include + +/* underlying prime's size */ +#define PSM2_BITSIZE (256) + +#define PSM2_LEN52 NUMBER_OF_DIGITS(PSM2_BITSIZE,DIGIT_SIZE) +#define PSM2_LEN64 NUMBER_OF_DIGITS(PSM2_BITSIZE,64) +#define PSM2_LEN8 NUMBER_OF_DIGITS(PSM2_BITSIZE,8) + +/* set FE to zero */ +__INLINE void MB_FUNC_NAME(zero_FESM2_)(U64 T[]) +{ + T[0] = T[1] = T[2] = T[3] = T[4] = get_zero64(); +} + +/* check if FE is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_FESM2_)(const U64 T[]) +{ + U64 Z = or64(or64(T[0], T[1]), or64(or64(T[2], T[3]), T[4])); + return cmpeq64_mask(Z, get_zero64()); +} + +/* move field element */ +__INLINE void MB_FUNC_NAME(mov_FESM2_)(U64 r[], const U64 a[]) +{ + r[0] = a[0]; + r[1] = a[1]; + r[2] = a[2]; + r[3] = a[3]; + r[4] = a[4]; +} + +/* move coodinate using mask: R = k? A : B */ +__INLINE void MB_FUNC_NAME(mask_mov_FESM2_)(U64 R[], const U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = mask_mov64(B[0], k, A[0]); + R[1] = mask_mov64(B[1], k, A[1]); + R[2] = mask_mov64(B[2], k, A[2]); + R[3] = mask_mov64(B[3], k, A[3]); + R[4] = mask_mov64(B[4], k, A[4]); +} + +__INLINE void MB_FUNC_NAME(secure_mask_mov_FESM2_)(U64 R[], U64 B[], __mb_mask k, const U64 A[]) +{ + R[0] = select64(k, B[0], (U64*)(&A[0])); + R[1] = select64(k, B[1], (U64*)(&A[1])); + R[2] = select64(k, B[2], (U64*)(&A[2])); + R[3] = select64(k, B[3], (U64*)(&A[3])); + R[4] = select64(k, B[4], (U64*)(&A[4])); +} + +/* compare two FE */ +__INLINE __mb_mask MB_FUNC_NAME(cmp_lt_FESM2_)(const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + + /* normalize r0 – r4 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + + /* return mask LT */ + return cmp64_mask(r4, get_zero64(), _MM_CMPINT_LT); +} + +__INLINE __mb_mask MB_FUNC_NAME(cmp_eq_FESM2_)(const U64 A[], const U64 B[]) +{ + __ALIGN64 U64 msg[PSM2_LEN52]; + + msg[0] = xor64(A[0], B[0]); + msg[1] = xor64(A[1], B[1]); + msg[2] = xor64(A[2], B[2]); + msg[3] = xor64(A[3], B[3]); + msg[4] = xor64(A[4], B[4]); + + return MB_FUNC_NAME(is_zero_FESM2_)(msg); +} + +/* Specialized operations over EC SM2 prime */ +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_psm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_psm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_psm2_)(U64 r[], const U64 va[], const U64 vb[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_psm2_)(U64 r[], const U64 va[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_psm2_)(U64 r[], const U64 z[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_psm2_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_psm2_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_psm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_double52_psm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_tripple52_psm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_half52_psm2_)(U64 r[], const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_psm2_)(const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_psm2_)(const U64 a[]); + +/* Specialized operations over EC SM2 order */ +EXTERN_C U64* MB_FUNC_NAME(ifma_nsm2_)(void); +EXTERN_C void MB_FUNC_NAME(ifma_tomont52_nsm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_frommont52_nsm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_ams52_nsm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_amm52_nsm2_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_aminv52_nsm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_add52_nsm2_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_sub52_nsm2_)(U64 r[], const U64 a[], const U64 b[]); +EXTERN_C void MB_FUNC_NAME(ifma_neg52_nsm2_)(U64 r[], const U64 a[]); +EXTERN_C void MB_FUNC_NAME(ifma_fastred52_pnsm2_)(U64 r[], const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_cmp_lt_nsm2_)(const U64 a[]); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_check_range_nsm2_)(const U64 a[]); + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_ecpoint_sm2.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_ecpoint_sm2.h new file mode 100644 index 000000000..c19717d14 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_ecpoint_sm2.h @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPOINT_SM2_H +#define IFMA_ECPOINT_SM2_H + +#include + +typedef struct { + U64 X[PSM2_LEN52]; + U64 Y[PSM2_LEN52]; + U64 Z[PSM2_LEN52]; +} SM2_POINT; + +typedef struct { + U64 x[PSM2_LEN52]; + U64 y[PSM2_LEN52]; +} SM2_POINT_AFFINE; + +typedef struct { + int64u x[PSM2_LEN52]; + int64u y[PSM2_LEN52]; +} SINGLE_SM2_POINT_AFFINE; + +/* check if coodinate is zero */ +__INLINE __mb_mask MB_FUNC_NAME(is_zero_point_cordinate_)(const U64 T[]) +{ + return MB_FUNC_NAME(is_zero_FESM2_)(T); +} + +/* set point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_to_infinity_)(SM2_POINT* r) +{ + r->X[0] = r->X[1] = r->X[2] = r->X[3] = r->X[4] = get_zero64(); + r->Y[0] = r->Y[1] = r->Y[2] = r->Y[3] = r->Y[4] = get_zero64(); + r->Z[0] = r->Z[1] = r->Z[2] = r->Z[3] = r->Z[4] = get_zero64(); +} + +/* set point to infinity by mask */ +__INLINE void MB_FUNC_NAME(mask_set_point_to_infinity_)(SM2_POINT* r, __mb_mask mask) +{ + U64 zeros = get_zero64(); + + r->X[0] = mask_mov64(r->X[0], mask, zeros); + r->X[1] = mask_mov64(r->X[1], mask, zeros); + r->X[2] = mask_mov64(r->X[2], mask, zeros); + r->X[3] = mask_mov64(r->X[3], mask, zeros); + r->X[4] = mask_mov64(r->X[4], mask, zeros); + + r->Y[0] = mask_mov64(r->Y[0], mask, zeros); + r->Y[1] = mask_mov64(r->Y[1], mask, zeros); + r->Y[2] = mask_mov64(r->Y[2], mask, zeros); + r->Y[3] = mask_mov64(r->Y[3], mask, zeros); + r->Y[4] = mask_mov64(r->Y[4], mask, zeros); + + r->Z[0] = mask_mov64(r->Z[0], mask, zeros); + r->Z[1] = mask_mov64(r->Z[1], mask, zeros); + r->Z[2] = mask_mov64(r->Z[2], mask, zeros); + r->Z[3] = mask_mov64(r->Z[3], mask, zeros); + r->Z[4] = mask_mov64(r->Z[4], mask, zeros); +} + +/* set affine point to infinity */ +__INLINE void MB_FUNC_NAME(set_point_affine_to_infinity_)(SM2_POINT_AFFINE* r) +{ + r->x[0] = r->x[1] = r->x[2] = r->x[3] = r->x[4] = get_zero64(); + r->y[0] = r->y[1] = r->y[2] = r->y[3] = r->y[4] = get_zero64(); +} + +EXTERN_C void MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(SM2_POINT* r, const SM2_POINT* p); +EXTERN_C void MB_FUNC_NAME(ifma_ec_sm2_add_point_)(SM2_POINT* r, const SM2_POINT* p, const SM2_POINT* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_sm2_add_point_affine_)(SM2_POINT* r, const SM2_POINT* p, const SM2_POINT_AFFINE* q); +EXTERN_C void MB_FUNC_NAME(ifma_ec_sm2_mul_point_)(SM2_POINT* r, const SM2_POINT* p, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(ifma_ec_sm2_mul_pointbase_)(SM2_POINT* r, const U64* scalar); +EXTERN_C void MB_FUNC_NAME(get_sm2_ec_affine_coords_)(U64 x[], U64 y[], const SM2_POINT* P); +EXTERN_C const U64* MB_FUNC_NAME(ifma_ec_sm2_coord_one_)(void); +EXTERN_C __mb_mask MB_FUNC_NAME(ifma_is_on_curve_psm2_)(const SM2_POINT* p, int use_jproj_coords); + +#endif /* IFMA_ECPOINT_PSM2_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_ecprecomp4_psm2.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_ecprecomp4_psm2.h new file mode 100644 index 000000000..9896297e7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm2/ifma_ecprecomp4_psm2.h @@ -0,0 +1,682 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ECPRECOMP4_PSM2_H +#define IFMA_ECPRECOMP4_PSM2_H + +#include + +#define MUL_BASEPOINT_WIN_SIZE (4) + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE +#define BP_N_SLOTS NUMBER_OF_DIGITS(PSM2_BITSIZE+1,BP_WIN_SIZE) +#define BP_N_ENTRY (1<<(BP_WIN_SIZE-1)) + +__ALIGN64 static SINGLE_SM2_POINT_AFFINE ifma_ec_sm2_bp_precomp[][BP_N_ENTRY] = { +{/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x0008990f418029e9,0x000e6ca6c04fd132,0x00024c3c33e7981e,0x000b05d6a1ed99ac,0x00001167a5f71c13}, {0x0004e593c2d0ddd6,0x0008ed3295fa6135,0x0002a48f8c1f5e57,0x0005bd8d4cfb066e,0x00003cd65d4e1d73}}, + {{0x00037bfbc3be46a0,0x000a2d8fa9380af0,0x00088cd2483bdc9b,0x00036a5349d94b57,0x0000d7e9c18caa57}, {0x0001a1d69db9ac19,0x000854a8e82ada7e,0x0007157acccbd8d3,0x000df5c7b145169b,0x000047e7465fc21b}}, + {{0x00054fdab589e4a3,0x000a0b4f0a0cecda,0x000eb4a0a2676528,0x000c640a265a308c,0x0000019fd6c2e887}, {0x000fbe94b2fc1902,0x000ba7cbce5fea10,0x000c13c97f40aa52,0x000bb4cc496bfa6d,0x00008ad34787bb3f}}, + {{0x0007c5a986150605,0x000039016208e93f,0x0009f9020487ea28,0x000be18a86bcb4a0,0x00000dc8e3b1899d}, {0x0009043fd6199986,0x000adc7383bd9c09,0x000cf70ed1de135e,0x0009e34d0bd55632,0x0000ffc31c585bce}}, + {{0x00056336a9c81620,0x000221dfcc539a57,0x000f5f4c515aa58f,0x0005b97ad354bf1e,0x0000f443ef363f87}, {0x000d68fd34501337,0x000e53607d17be81,0x0002258efb30f4bb,0x000768b1826a4c36,0x0000b415276842a6}}, + {{0x0009c4c0acd72ba8,0x0005de7ec73b936a,0x000e34db6b1274a2,0x000047f15a876e5d,0x00005e74ca10cba8}, {0x0004cddb469eb37b,0x0000799754f75845,0x00030e9848fbf6d2,0x00098a1060e7f8ec,0x0000568bc97fb8c5}}, + {{0x00031c781f06784b,0x0003b713251ffa35,0x000fe18c50b89419,0x000c2884ee5b69ac,0x0000bf492e189fbe}, {0x00035c1e5f6186d2,0x000e957a01b8113a,0x000d99baf0e449a2,0x00077796c9b9922b,0x0000ba05a8f5b84d}}, + {{0x0003a1c091226701,0x000a32cc810cce52,0x00087df9e90be6f2,0x000134086e634143,0x000015c2fc0e9c44}, {0x000430d8799302ae,0x0001c27b7ea3b334,0x0008f3382693b350,0x000247cbe1136f9a,0x000077fd5f395778}}, +}, +{/* digit=1 [{1,2,3,..,}]*([2^4]*G) */ + {{0x00060c939e8a120c,0x00093273b59a3715,0x000f4639d7121d6b,0x000d58649535ce8e,0x0000d01076ed4cc6}, {0x000729a96e74f8a6,0x0000b533037dc705,0x0003c5c62b07e323,0x000ac10846dcc166,0x0000a4759c170fc3}}, + {{0x0001369adbb3c8b5,0x000b9c8ec37856c1,0x000f0a982d78af40,0x00050affb3a80d03,0x000050e3e71f83be}, {0x0000fb2418ee45bb,0x0003b791b963d45c,0x00047e33b5297cf4,0x0005b2676b638ccc,0x00001c52fadaecf8}}, + {{0x000f511b36362ecf,0x0007240859590a8f,0x00070c62b11c5a9f,0x000827272b86f297,0x000006262266c7e8}, {0x00068bfea1e13ebf,0x0002be59b0f4a291,0x000826f34db89297,0x000cec6769e31d4f,0x0000a1dd934fa955}}, + {{0x000a5ae0d038ad4f,0x000426256c8e90ff,0x000978dcef44d3df,0x0003170a3077c8bc,0x00003d9b4b1645b8}, {0x0004484b6b1852c5,0x00045e78ff073bbf,0x000c242380cd02ed,0x000b5591cb827e49,0x00008adaee62aa3c}}, + {{0x0001687af48d3524,0x0000068c04010e5a,0x0003b2e10fa700b7,0x0001f5c06c84139f,0x00007cd5ff4bcf2f}, {0x000c6996a3ebd39b,0x00085f9371d6b52d,0x000c57dadb8d9103,0x000b8bee3f1d85f2,0x0000c987637ef0d8}}, + {{0x00091da5f6fbf645,0x000364de051b9b7a,0x0005a1ac8ad5bf46,0x0002fa13e4455d48,0x0000d09b6e064f3a}, {0x000ffc804bf14165,0x000c1e88e44737c3,0x0003777ca4b5beda,0x0001181fc4f3fd98,0x00005e4509f06d4b}}, + {{0x0007754a47073753,0x00053923a9dc5b93,0x000ab2dd726607db,0x0000a7690f12ae67,0x0000a39fc8c30a65}, {0x00095fd0ae53d66e,0x000319b1c44980fe,0x000eb8e6eefebcba,0x000c8cf8b3ca72f1,0x0000586e40734f5c}}, + {{0x000ce4d033fc12ae,0x00022886f31527e6,0x0006f3f11ba4f98a,0x000de3b24b38f3e6,0x00003f6205b3ea4b}, {0x0005387a77b998f4,0x0007d549f3b0c070,0x0003a61d62c9b445,0x00081adef6625b53,0x0000eda7e2abe4f7}}, +}, +{/* digit=2 [{1,2,3,..,}]*([2^8]*G) */ + {{0x0000aaafd1201340,0x0009c057309ce973,0x000726ce7b22b908,0x00058498e7956584,0x0000e1431a0d635a}, {0x0007023e834ffa6a,0x000fa36ab1ae1d38,0x00024b68464198dd,0x000c6d46e5ebb191,0x0000316fa44c33b3}}, + {{0x0000210a1371aa41,0x000064b5424eac97,0x00064269baff481a,0x0007cfbcdf91fd0e,0x00008bb37bbc02fc}, {0x000dd796f69d4390,0x000f169514b2d99e,0x000e19ae44e27a58,0x00096d80eca1ca66,0x0000470e96507886}}, + {{0x0008bfc3dfdc228b,0x000e69648a35b377,0x0005a99b5c0bae0a,0x00058ada8cb8ab01,0x0000045cccc3366b}, {0x0008ef44164cebd7,0x000935e00e5f04ef,0x00079468e41e71fc,0x00072d753cf90644,0x00008b5223fa32ea}}, + {{0x0009e2f5876d6e8b,0x000682b622d6a28a,0x0005411d793c48f8,0x000e9188d9eac83e,0x00007e4a6bab0a70}, {0x000e5baf1c43b2ea,0x000f42f347de0f18,0x00009638f46578c7,0x000d2919ca736df0,0x00006563f1f5d1ac}}, + {{0x00054b5577dae353,0x0006dac3a655cefc,0x000c31d009d2f054,0x00063db96bd298fa,0x0000328a51d1e695}, {0x000098e43195f4e8,0x00062998010ade19,0x00047ccb6657f4ba,0x000da645f29a8440,0x000033a5443ee423}}, + {{0x000f29899229a90d,0x0008ed71d5319e6c,0x000e3a8b7a6840bc,0x000a0e803e540771,0x00005611ee53afd9}, {0x000ca0ebbbefa73b,0x000c75ec48b72739,0x000dea0ec6082dba,0x000e03a0ab10dfbb,0x00001b7ebe5a1633}}, + {{0x0004475ad1cac223,0x000ef7e1139532e6,0x000479c4a2008653,0x0000d1a875ad01d9,0x0000e6cf633b04b3}, {0x000ef6eb6b06e46b,0x000fa7b8410aa8b3,0x00078458d74c45db,0x000bd102675759c2,0x00002ef49575cd30}}, + {{0x00012dd12ee579d7,0x000b76dd62d6170b,0x0001d75822a9a12a,0x000457bcd5259907,0x0000a36193b1869c}, {0x0006592e976ae5bf,0x00039dfecd57e29e,0x00014686de82c871,0x0003babc83a440f7,0x0000e19344afc21e}}, +}, +{/* digit=3 [{1,2,3,..,}]*([2^12]*G) */ + {{0x000010b2c4391719,0x0007781393878f41,0x0000776333ff85ee,0x0000234ada4c7d8f,0x0000976011b124e6}, {0x0001197eaf49f638,0x0000560b0c4c2250,0x000b3df90dff2123,0x000d5f1a6a3abbba,0x000054bbcc7366ff}}, + {{0x000c28718d13bd32,0x000443c6dd1a9b45,0x000b9cf87bbf3a89,0x00048dc8171c5e13,0x0000dfc779254f53}, {0x000662d985cabd47,0x000cbd971de02b9a,0x0004cba64588a6eb,0x000e67da9fd89457,0x0000e0f0ccad51e6}}, + {{0x000572f9f177d653,0x00055c2394c3f74c,0x000307ad6c39e9e1,0x0009c8c9e7b18c1e,0x00003da596c7c22d}, {0x0000e12b74b9c00c,0x000e19f5d1339c30,0x0009e84425f434a9,0x0001c35b87294371,0x00000164ba54acd1}}, + {{0x000276c4b8bceb84,0x0001b52d110648ca,0x00034dcbf6d4ec10,0x0009d02ad98063f8,0x0000da81d1a1fff1}, {0x0007cd23a9828ffc,0x0000ee64b3318ccc,0x00008b81cf1e389b,0x000ac6e2fb6a6c73,0x00006df66b31bcc0}}, + {{0x00029d74220fbbff,0x0004f09ba10d52f0,0x000858df9405e1d8,0x000b23e53bd89048,0x0000d7bc7aa35dab}, {0x000f3807f06c21c7,0x0000b324828efe76,0x00017d5a3616f89c,0x00060fe30abf04a5,0x0000714fd2e0d0db}}, + {{0x00013306dccac081,0x00050610b07430a3,0x000edd616b67ab62,0x0006666fd86597e7,0x000029abb54bf0c4}, {0x000f5f3c3ca87bd2,0x0002fde60e830fef,0x00077b8c7bee8fe9,0x00030251c192c984,0x0000b0bc40c43995}}, + {{0x000e53d299f5d074,0x00060132e675167f,0x0007ce589b1afc7c,0x0006d18ac9a60464,0x000054e627504184}, {0x000160130ed07dbb,0x000342bd885fb63b,0x00069a710648bea2,0x000c83def2b055c5,0x0000a36e625f096b}}, + {{0x0008c75e1c58c801,0x000493fcc95a4ccb,0x000ccbcf92ba9de0,0x0003adccdeb0eedf,0x0000d667d4f80f3d}, {0x00014a536269820c,0x000bcfe8794006aa,0x000e5cfb2329a308,0x000b2c39869970ed,0x000033c3069b601b}}, +}, +{/* digit=4 [{1,2,3,..,}]*([2^16]*G) */ + {{0x000045511c092897,0x0007864079c97c25,0x0003879a283042ba,0x0002ee4881640c6e,0x00007c5babcf0245}, {0x00059a67088f360a,0x000d574be7e8da77,0x00033828902da352,0x0008c615800cdbe0,0x0000d69f7c9f0168}}, + {{0x000c67faee039995,0x0003c9ff7f90c64a,0x0008da6ea4de174d,0x000df7063e494354,0x0000264880c2b7cc}, {0x000f34b49b992ccc,0x000dd406586f8a18,0x000db0e21e16b6f4,0x0009f8d32479ac4c,0x0000e8151f6d62bc}}, + {{0x0002a1cc216cf37f,0x0006673828be9ae8,0x00051a85bac437f4,0x0005788c12ff189d,0x0000eb563bf24c16}, {0x00053b6c67069662,0x000a2cda87337d93,0x0004953dbcdc6eb5,0x000f7c033c186e3e,0x0000ba46a66d2e37}}, + {{0x000f516da0abf3eb,0x000511b3381eceb7,0x0004188703c92ac9,0x000066bad7320ed3,0x0000ab7a126b7dbe}, {0x00059be2def303f7,0x00079d1e0c9f77ce,0x000f418dc0bf1f23,0x00067612c18d1e38,0x0000fcc5e3f285bb}}, + {{0x000e7047e1754b8b,0x000261c0027aeefe,0x000af4e6d5408547,0x000569c5e7a6fa45,0x00004d3cd58e0048}, {0x0000014f3ae8e79e,0x0004649f3f22f2c2,0x000982a8cd0b6af1,0x000f903a1db91517,0x0000a3c809ad9ffc}}, + {{0x000c9530fa12b5b4,0x0003b7d159b4d8ea,0x000844a0d45ccf07,0x000c18a74804446e,0x0000404e6c7177d1}, {0x00043a6ce1af18fa,0x0001b7fdffcb603e,0x000bf3d178a82808,0x00028691b63c11ca,0x00004dedc224d26f}}, + {{0x000853b60aa5c141,0x00044850cc05c202,0x000abccfd1dc35d3,0x00025a8014357e0c,0x0000aa44ce9d5a52}, {0x000f9203a8444b4b,0x0004795384b0f3ce,0x000e5da54cf3f91b,0x00046a1d625ba1c9,0x0000f1fba3861d0f}}, + {{0x0005caee30ae90b2,0x0000eaabea0d0cda,0x000e678562cc3429,0x0008b7564afcd941,0x000010c7a09ef6ef}, {0x000d352f82a591d2,0x000dcb43d2a1a316,0x0004e94705fe8cc4,0x000a07d8ebce978b,0x00006c78f44da321}}, +}, +{/* digit=5 [{1,2,3,..,}]*([2^20]*G) */ + {{0x00038c7656047260,0x0003247a421e681a,0x00094956e4f8c6ae,0x0003241a51eaa012,0x0000984b1ef47c9b}, {0x000bd0d597b76968,0x000888e57ee6b749,0x000a112d29d432b7,0x0007f53092afe12b,0x00009ccee4996c5a}}, + {{0x0009d7b54089685c,0x000000818348755e,0x00061b80f9f0ec69,0x000a144cf4d8cd38,0x0000ce669fe81f5f}, {0x00025091788f9dae,0x0004d3ccf2390a21,0x000027f3b3295361,0x000bcb1048d09250,0x0000807b39e2270f}}, + {{0x000c73cdf18eddfb,0x000a92465ee8a660,0x000f950c877edb4b,0x00068baf24eff83a,0x0000822c6b31f6cb}, {0x00052f6149d2bb2d,0x000bc4a66ae65503,0x0007e1c68926809d,0x00029b9964c2803f,0x0000253298b86681}}, + {{0x000dc5595e388c34,0x00062a44e3ea1099,0x000b41f7bd0670ff,0x000305d212c99361,0x0000f594afa3af13}, {0x0008bf205c01232b,0x0006e9ff08a50c50,0x00037741a7683353,0x000d2aa1cf70bdb8,0x0000a8e66175af7b}}, + {{0x00068da909bf8c66,0x000bef4bad4a4b7b,0x000e39585b5bd7c8,0x0002d9a0ebb027fa,0x00008932a372676d}, {0x000954b730901cb5,0x000774fa3192062f,0x00047b351108194a,0x000765e32829e6a5,0x0000ca08b2eab343}}, + {{0x000c343def27938c,0x000208cee32a1e04,0x000d142da3f15ca9,0x0009bccb61573b9d,0x0000094eefdd26dd}, {0x000f1a5136bb4da9,0x00036b2f3448cd42,0x00016795e7569395,0x0007db98017cd65c,0x0000e401530bafb6}}, + {{0x000608550643d18f,0x00046902eb90a0cd,0x0007964ba821f27f,0x000ad5766f7c645d,0x000056feaa57c7bd}, {0x00029281bfda5eca,0x000e6624a7de56aa,0x000f7f3b15c09581,0x000e4b33d1a64a6f,0x000019a86e60c36d}}, + {{0x000749f9b7c6c75e,0x000d8cbca35c8376,0x000145b32680eacd,0x0006afe87fd5b55e,0x0000b20d1bb16b88}, {0x0009055779b12bbf,0x0002fbe39fb6da49,0x000a128ce6f290ff,0x000a8133ad6fe0f4,0x000009e2a418b31d}}, +}, +{/* digit=6 [{1,2,3,..,}]*([2^24]*G) */ + {{0x0004783f357999bb,0x000cd6bfacb340c2,0x000ddb9452c21474,0x0005eae3abed6ad3,0x0000b21b7651031a}, {0x000b68b8afc2a09a,0x000921306b70cdb3,0x0002eb6f51aac2f0,0x000b6f882c337185,0x0000dfe0c1b798e9}}, + {{0x000f0633fd5a1de4,0x0001e75b5b8bde0b,0x0003c617a5d05e90,0x000706bbbdb1abcb,0x00004954a8c5aef4}, {0x000eea3ff6a6e47c,0x0001cded1274fc3c,0x000abe95f6140f42,0x000813bb4b4c044d,0x000055e87db3135e}}, + {{0x000fda84e1d5d9a1,0x0005445ccdef5a65,0x000d72c0a0c0fe38,0x00013119ff360fd6,0x0000be1e8d80b016}, {0x0007e91025b45e13,0x000635259bf1b2f2,0x0001cc67e25bec26,0x00020ed7b8b4e7e5,0x0000a839aa5db80a}}, + {{0x000de9738f4194d9,0x000acb996b636fa1,0x0002053a733d2726,0x000c0c787c0ec30d,0x0000447e9cc7ecd5}, {0x000121c284773c09,0x0005115829a0777f,0x000def08b496427e,0x0007784b11978694,0x0000e7b29e72c15a}}, + {{0x0009c5550b66feca,0x0001ac065cfa1f7e,0x000d459ea5db7dd7,0x00041a3525e31050,0x0000d7abe5b21229}, {0x000ba80122d92fa4,0x00062fcc1c2487ae,0x000fd71b1066c376,0x000dbca6d767ca8f,0x0000a75fab5dcc16}}, + {{0x00018af2988abcdf,0x00007e7da51801b3,0x000836b57f887559,0x000cf3b8b9939c97,0x0000793e3b6b0a74}, {0x000008a376841700,0x000b05cb453ce191,0x0001beb2c7708823,0x0008f4ec221d4036,0x0000e5a6cceeb1b6}}, + {{0x000a0068ae66f002,0x000e98d648f0a6f0,0x000d2880f2620157,0x000017fc71776240,0x0000e0e293cde105}, {0x000f214854116f41,0x00003d5cd4eca320,0x000fc1c555e4fa70,0x000a1583fa0a23df,0x00008fcb8d2d9a9c}}, + {{0x000995e2a8ed3d7c,0x0008ef319e47285f,0x0006d98a29dc712e,0x000e35c4402eff53,0x0000a61e310f7521}, {0x0009621c3196672f,0x0000ef17e8a70ed3,0x0002a7c4929e7744,0x0006da47eca48841,0x0000011451423a2a}}, +}, +{/* digit=7 [{1,2,3,..,}]*([2^28]*G) */ + {{0x000a12ae6880b5f3,0x000d12606d252675,0x0003b21259ba1e92,0x000099b012facbeb,0x0000c50fdfbf37b0}, {0x000461c9ce223e96,0x00074efbd8ac69ce,0x00031ea8ecb90bdd,0x000ff6f657e5a4c6,0x0000584520b98a83}}, + {{0x000f317635abcf02,0x000fb9e17618b959,0x0003bd99ba516a43,0x000290ed90ccf2ce,0x0000fc6d460c9fb3}, {0x000be090cde43021,0x00000908003ba61e,0x0000f57875a3b062,0x000c2ff51bb736f6,0x0000717f6e9157ef}}, + {{0x000cf931ca260efd,0x000ec1811d22865a,0x0003e42c87d6e797,0x000158e63c692078,0x0000c9dbce95dcb5}, {0x000dc7ac8e39022b,0x0004e0ebfe466426,0x0007d6395f3037f3,0x00053975aa6845f8,0x0000f792fd611f53}}, + {{0x00021726ddc3d836,0x000f388207bb48bf,0x00003bd7ef68deb6,0x0009a4a8eae2ebcd,0x00004c7f57ef51f5}, {0x000b223a1786d576,0x0000d11827902bad,0x0005a94572e7fda6,0x000e079dc90e369a,0x0000eca838c54b07}}, + {{0x000235b032648719,0x000448b933de1d2e,0x000354c8eb4c5624,0x000c76d9c2bdda91,0x00007d743fffa73f}, {0x000109dce88013e3,0x000623b3bf4f8ed4,0x0001e761ca242827,0x0006c2900d356001,0x00004925d7e124fd}}, + {{0x00066caa81982353,0x000d1d2d7649d8b9,0x000d63f3a355d098,0x000140fac27f7ca3,0x0000e553f6d03edc}, {0x0002c7f11ff4334c,0x000c7c62cb56a4d7,0x000a2108248735aa,0x0006fdcf064294eb,0x00001f9e4577b8d9}}, + {{0x000bdbc293cd9450,0x000bea254e361d24,0x0006fb48576985bc,0x00073d3df2cb6a87,0x0000176969fcd1f6}, {0x000cacb642133a78,0x0008b73880e20b41,0x000b1463f31ea88f,0x000a27ccf1ff85b3,0x00008fffa162ca74}}, + {{0x0009b92167cdd1ff,0x0001e879b893aa4b,0x0005479f5a9118fc,0x000292f6e73387c5,0x0000adf82eeb626d}, {0x000b76156e80e6a2,0x000a127555d1803b,0x000087e4359a783f,0x000ded027d63b63d,0x00009f9ff3222fde}}, +}, +{/* digit=8 [{1,2,3,..,}]*([2^32]*G) */ + {{0x000f92d0cf4efe5d,0x0005660e2d221cb8,0x00059f07988c4721,0x000a7cca9549ef60,0x00000a3774b4016d}, {0x00095f61d001cabb,0x000053feeec1251c,0x000fedf2b2d744df,0x0004a5b7c20cc20a,0x0000f16c5f221d14}}, + {{0x0005450677b7a8f8,0x000f669273d20112,0x0002c5990ba889fc,0x0004c34a40a85958,0x000036638b474893}, {0x000e189f3596ba60,0x000ede8b0754e964,0x000f93f1b2f417c0,0x000389d883169fd5,0x0000318fe4ed45bb}}, + {{0x000e34d674d10cf3,0x0009cf962ec58559,0x0002af42d6955bb6,0x0002568bf1ab6c54,0x0000f2f33fb0fa61}, {0x000019573d1049ed,0x0009afd7f39a6214,0x000237be0f508927,0x000e57b42eb51cb4,0x0000f747f45574d0}}, + {{0x000537af0c1bb4f5,0x0000206b90f4d6bc,0x0007c89cf37f3770,0x0000034d48d994be,0x000011c2158dd572}, {0x000bac1088dda1ee,0x000a5ad4934be26f,0x000dcaf7cc3d5518,0x00073d5233c17685,0x0000c3a8a2a888b4}}, + {{0x0000fbb573c9aaf3,0x000a13cc6c7870a3,0x000cc5c2f0e71124,0x00003e3b57c921a1,0x00005b1badbfd70c}, {0x000286a9384dc1ec,0x000903a5febac82b,0x00046e3c694e98c4,0x000b10f2872b3abb,0x00008258ff96fa45}}, + {{0x000a3a880b5f763f,0x000a54ed2fd06e09,0x00069d361c365267,0x000a6292b39fb7bd,0x0000801859aa1386}, {0x0002d562056479b9,0x0004e837087f6f64,0x000a2e3c3ace29a1,0x00010ad5dac94ce8,0x0000f0d3dce1bbf8}}, + {{0x00001c95b2614292,0x0003bf1c4c90e560,0x000708120f1566d6,0x000a442e30662c3c,0x0000130cfa81a306}, {0x0001a8e4f57f7720,0x00069cca3398686c,0x000fde0e6d53c9e6,0x000b53a355d4890b,0x0000daf31990e2ee}}, + {{0x000667ab1f0c1753,0x00015ab99e7dcd96,0x000e43f9da256a61,0x000cd6ff07c1ea05,0x000005700bcae1c9}, {0x00025462b2887a31,0x0009d772fd142f1e,0x000584057dd782f4,0x000cf99125f99638,0x00009fd039626a02}}, +}, +{/* digit=9 [{1,2,3,..,}]*([2^36]*G) */ + {{0x0002bd34c58174d5,0x0003f900551f58d6,0x0002802c3872251d,0x00055506f5862df1,0x0000d93c48b2d925}, {0x00067d5bd6006f82,0x000c196ccc67a39b,0x0003014dbea6f756,0x0002c0140e853e54,0x0000bdc567509de4}}, + {{0x00058faeda49f746,0x00076e4545a39a1a,0x0004c07e4ddb8995,0x000008d3576489c7,0x00004e4b39f159b1}, {0x0000340f66b546c5,0x00041deb912eeb09,0x000e55cca0e0f401,0x000768bb00b46c01,0x00005b61b34e9ad0}}, + {{0x0002337e989963ee,0x000fb3778d59e0d2,0x0008c41782c4831c,0x000894d775c6a5ee,0x000023916557d0c2}, {0x000fe865d0eb314c,0x00004b2290d337d4,0x000cefa7842801b9,0x000fea73e9b332cd,0x00000d169d9fe877}}, + {{0x0002370734a13273,0x000c4951afa89ab0,0x000638b8aa1df7af,0x000aa6581cfbaf42,0x00009db6d2b5130e}, {0x000805bda2f91a5a,0x000f8569add7abbc,0x00021fa7d3dcb0a7,0x000008724ab65ad7,0x00005152b96988f8}}, + {{0x0008dc441177a460,0x000b7f039a7bedf3,0x0008ae7c2d9a955b,0x0008194f1525814d,0x000063c9f834f848}, {0x0004526841e87839,0x000a3a5f2b31c4ea,0x000846dcfe86a411,0x000d70b7529a3b19,0x00001356a07c5689}}, + {{0x0004dea8910763ed,0x0008d76a0f7f958f,0x00065f9b96e5fcb4,0x0000c56a5447a4ab,0x00007d863d5775bb}, {0x00034a7e87e79168,0x000a4d961e88006c,0x000fe6aeb0539155,0x000ca15def2d8874,0x0000ac350b379226}}, + {{0x00035d081443d166,0x000b06cc364b9f96,0x000bf84382342cbf,0x00029863b0a03225,0x0000ccd3ce60078d}, {0x000d10891292fd30,0x000b14073286f93b,0x00062cd16c887a31,0x000b46eb1275bf9f,0x0000335bae361578}}, + {{0x000aca7614d9ff3c,0x000cf58f2459fee2,0x0006f62abd1f13b2,0x0003749e92d83fc4,0x00001dd32de427d7}, {0x000d593c3e566e7a,0x0007a4ccb02a7636,0x00035b65281c2f4e,0x000d42b57782c6cd,0x0000d88787f28210}}, +}, +{/* digit=10 [{1,2,3,..,}]*([2^40]*G) */ + {{0x00083c6150b0fcd3,0x00011d9b0f4c85b3,0x000d05413f948da8,0x000e64cf075225cc,0x0000f31b12c7f62b}, {0x0001fc8368c17f6e,0x000a200bc68f43b2,0x000ac140e423d536,0x000d615335dd1ede,0x0000631c24a7493a}}, + {{0x000262021afa86f1,0x000396b11457a23d,0x000148d30ea757f0,0x0001700bc4d2d1b0,0x000019b553598ce4}, {0x000bb670aa9c8f62,0x000ca8e05de28ab5,0x000f1e9c3dfc9693,0x000b9c6cae7e57e3,0x0000b1ceb548f6c3}}, + {{0x0009fcb03cdcc63a,0x00026fc3afa8c753,0x00099aa9772fdb55,0x000651573534e102,0x0000ffe7179c664d}, {0x000fa10f5ecccf0c,0x0000003d6c622660,0x0007f57868df4395,0x000d741bec4f0f31,0x0000019916d7a461}}, + {{0x00035ca876361830,0x000a719d1ca312e3,0x0004161d81461a65,0x0001128150080ab1,0x00008da4ebfc612e}, {0x000fb6ba8498a9af,0x000eaa0f8db9d95d,0x000b4f497099cf91,0x00030612d2ae144f,0x0000a3a28b123cb7}}, + {{0x000577b9ec7f1ff9,0x0007936c299fce38,0x000f0939b9deaab6,0x0005c0624127222c,0x00008c2a3492b510}, {0x000a08656706b8d6,0x000bd14add6ad069,0x000d85a98a2296ff,0x000bd6537a875bde,0x0000705fef2603de}}, + {{0x00079bdc3141d130,0x0002918736859cd7,0x0004305b9e4acdef,0x000d6de804c2cc4e,0x00003c2e8392d86b}, {0x0003c44aee7c9a30,0x000a9f8d49b095d5,0x000c57bc9b303ea1,0x0006a65c3579b5c2,0x00009ac7359ad03f}}, + {{0x000cfc3afb8cec58,0x000eb630ab5869b3,0x000322634533076a,0x000a3dd50dcfb8f0,0x000053af6f4fb737}, {0x00062cefa4582dca,0x000b14554a478703,0x0004c8a663019bfd,0x00010e61487a210f,0x00005b5f361c1306}}, + {{0x000c5d00f01c7cee,0x000e5283bdefe89f,0x0001519236fc45ff,0x000cc971dece8181,0x0000d1cb14da433f}, {0x000612bd3959bcfe,0x000c15b5732e6279,0x000d0a1cae163880,0x0007f335414ca771,0x00008b9e6520c1e4}}, +}, +{/* digit=11 [{1,2,3,..,}]*([2^44]*G) */ + {{0x000a78a08b213629,0x000069fe0b35cce8,0x00087837cf37f5e8,0x000993dca66c7f2c,0x00002524b949bf2e}, {0x000020c71745788b,0x0006ecbfbf4c4c0f,0x0003de1c86018de4,0x000e41a8446691ac,0x0000194d41a0de5a}}, + {{0x000a4a89ce76a94e,0x0002a0725c9649aa,0x000e16665847cd08,0x000fc40c099e9097,0x0000409ffca6f7b1}, {0x0005b80690941ed6,0x000af2c0ee9d6057,0x00075837d8e25100,0x00022b71662d279b,0x0000eeb9e98456bb}}, + {{0x0000d52390e35da2,0x000347a9947be434,0x000cc7a3fc098e3d,0x000df6e6d781989e,0x0000c39102e43aa6}, {0x000ed0d300f3cb15,0x00072cfbe054683f,0x000cf45a8c0b1e35,0x000eda3da2224c20,0x0000be55df77f30d}}, + {{0x0006e66528960b13,0x0004084aecb383e7,0x00012ad64445dc39,0x000e371361843616,0x0000ccbecccbc831}, {0x000bd416121383c2,0x0003a0d895a2efb0,0x0003f2f1e316164a,0x000225c3d3415323,0x0000905907000d92}}, + {{0x000f0d3a3d89e152,0x00092d07f5eb1d0e,0x000e4887a4d5a30c,0x000349c359e31073,0x0000f4c6b7efbdec}, {0x000d3e9ba1426435,0x000e61c794b675a1,0x00010c63d8f4fd58,0x00076ccad091d118,0x0000b61623a40bfa}}, + {{0x000afb7b790881c4,0x00047663e76c567d,0x000e824902002b8e,0x00047a3bd28edef8,0x00004dd2e818bb2a}, {0x0000dfedbc3f2f8d,0x00033e2eec700e75,0x0004c4d2fd9b6e91,0x000be2e8400e2f1e,0x00003325697f3217}}, + {{0x0008e40347dfaefc,0x000e24464bf2717c,0x00064ec20795b0f7,0x000d3f15dc99d613,0x000007fce2951600}, {0x000338bc8bebbdac,0x000768547c02d825,0x000040b845e5e89f,0x00033d3c50032f1a,0x0000ea7544feb3a5}}, + {{0x00087934d217a2e3,0x00064fa4702d663d,0x000431f1b099e8c5,0x0003996d91bc47e6,0x0000fd21287d5f61}, {0x0000bae682fa08b0,0x0005c1ca371c2fc9,0x0001c428f51699c8,0x00050416f29d7483,0x0000ecefb669fa2b}}, +}, +{/* digit=12 [{1,2,3,..,}]*([2^48]*G) */ + {{0x000eb9068755cf37,0x000eefe125411487,0x000af8ca81887394,0x0009dc2e4c65d446,0x00002aae64629e11}, {0x00000941ec6ad734,0x0004cce4573e558e,0x000254b9684a7eec,0x0007323d6d00d4f9,0x0000ef44f58ce421}}, + {{0x000e0f87d3ad2ac1,0x0001d0f92c5ce59d,0x00000b6a5d2670cb,0x0008eb8f05944ac9,0x00001aeed239d966}, {0x00038e47c488ea6d,0x000848083d7451b0,0x000d31fe2406ea3f,0x000f9ad22197b43b,0x0000c8f8ccbf8a6e}}, + {{0x000cfbffc9188216,0x000c7e0fbf5fd2b3,0x00062452f51cb7e5,0x0009f0a73f6716bf,0x00002b74252c05f2}, {0x0009d259e88b0f1b,0x000175841f6142f1,0x000378ac867525d1,0x0002d6e54c3b5661,0x00009fade95d9a45}}, + {{0x000648302887281a,0x000c1f9de66ec79a,0x000a7dee213f3d39,0x0008b8289c3c50f1,0x0000510a53ce0b69}, {0x000c3fb06f799adb,0x000a653746501566,0x000c947b2cc95a87,0x00051bbd7343c061,0x0000bbff69e4543e}}, + {{0x00041aa7a0a745a0,0x000243371bd1327a,0x000b5f82492d43e3,0x000478cde41b9031,0x0000f5e1e18cda04}, {0x000c186247853141,0x00025ef5518b5db2,0x000b7c8ee0c4cfdb,0x0009d7acc9f6ec1f,0x0000efb06595d6c0}}, + {{0x00038dcba75aba90,0x0006d150f881b80d,0x0007b47c5e9b61ac,0x0001289f56af52ca,0x000040300d977fb3}, {0x0007184c01fd0c1e,0x00056b6e134a5687,0x000d7165340112a0,0x00062e56daed90cc,0x0000c553aa7974bd}}, + {{0x000472aab109ef7c,0x000d759b268a33d8,0x000314e79dbdfe41,0x00077c147dd06eeb,0x0000ae5583823c5b}, {0x000d83c8b1c89525,0x0008f1ba0321bc8b,0x00098beeecf4b71c,0x00034268f32934ea,0x0000580dbb671a4b}}, + {{0x000381d11476ddee,0x000dfea0923e2398,0x0007745bd4959204,0x000467d67427ad01,0x0000f022a754935e}, {0x00099f524e0380a0,0x000fb5f1a73057e7,0x0001771d86ee2b64,0x00013c9aeaac4852,0x00002c8521c0992a}}, +}, +{/* digit=13 [{1,2,3,..,}]*([2^52]*G) */ + {{0x000c43b153adbf74,0x000fc0351fec7fe5,0x000109e6007a66ed,0x0001623d8042353b,0x0000dc97176e832c}, {0x000c75fb1db1e5c9,0x0007315b98ff73fe,0x000aa1cff6aa02da,0x000a265f9e808f4f,0x00000aa28be36412}}, + {{0x000f1c99ce0fcd68,0x000eb232a8468dba,0x00075d822732ea65,0x0003cadb2ce2186a,0x00008ffd479bd227}, {0x0002ad2f2f26b61a,0x000e086706aae909,0x00023597cfb7041b,0x000c84e3d5fa755e,0x00002035bf8f995f}}, + {{0x0006c1ab9ac4754c,0x000a0d3f305a1b45,0x000a62dc0f497e6e,0x00094f84d27e3a3f,0x000018c3569e524b}, {0x0008954e380f5cb8,0x000ca72ea4581219,0x00032849181d8221,0x000ccf6fa082f65f,0x000010ca5b00e304}}, + {{0x000b892313de667f,0x000856a478a7c5de,0x00099242875c872d,0x000e09b67b5513c4,0x000097e010fe70fd}, {0x000f05360ee268c1,0x0002067cd32139b0,0x000bc187c981b514,0x000da8b5a1ac8d4f,0x000062417e2d12e6}}, + {{0x000e262502e26d19,0x000cc294e23f905e,0x000a7733db961ef9,0x000f737178f1fb6d,0x000089b69fbb32ec}, {0x0008a359a9bccae8,0x000bc00a01f33727,0x000b213bab1c81a0,0x00017e0781855aa6,0x0000acc1b78b4298}}, + {{0x000d3a83016e5135,0x00004b0f7bfadbde,0x0002be716a3c508b,0x000b9fa6a490deaa,0x0000a04d9e644485}, {0x00099d16ad25b5d0,0x000965a72cb4d07b,0x000c45a95a184010,0x000cffc8e2b32d14,0x0000fae6e86e4f2e}}, + {{0x000115e55a0c9314,0x0009e5c920a3d764,0x00090371034ea18b,0x000c7a6a099ddcaf,0x0000b937dc2249f2}, {0x0004a1a430f0a7e5,0x0008921dbe965cfc,0x00011d3fe8f106a5,0x0003c548ac702618,0x0000484226b080f1}}, + {{0x00050f8849e6d32e,0x0005de16485df445,0x000343924e7bc29d,0x0005ce29bbfec62f,0x0000eb802f320f2b}, {0x0007542bbb64f333,0x0006cf9bdb3bfb33,0x000a1cb884c1d3a3,0x000b6e1067cf3bc7,0x0000f12a31d7601f}}, +}, +{/* digit=14 [{1,2,3,..,}]*([2^56]*G) */ + {{0x000a78f1f8a4a913,0x0001a53dbe738720,0x000d0991a59e2221,0x00026f9f5ad99cad,0x0000a0db802a3807}, {0x000761c7dfb4f1c5,0x000aaac819cce7f0,0x000ffe34868e7098,0x0001409683d61037,0x0000bf205e57b7b5}}, + {{0x000b5f661a972624,0x000bd74a82f75846,0x000439654edf2cac,0x000e093dfab85faf,0x00003fb0efa0724e}, {0x000016f53b0119a0,0x00035bc8fc81d0d5,0x00065d2986844536,0x00064f6d10b6491f,0x0000f3c88c621a4e}}, + {{0x00072a17f34c5177,0x00069378bc26c203,0x000aae0245602bd1,0x000daa666a592d91,0x000016886aba17bb}, {0x000fe68e30451039,0x00030de1d7013e55,0x000724cb6f2c4b0b,0x0003148da358857d,0x0000aac623d2ec47}}, + {{0x000ff46b8529a018,0x0002c856b95c024c,0x0005af7f76e4d82a,0x000e5358c6b833c6,0x0000a6c41262e110}, {0x0007c304f0833403,0x000b476cdb310820,0x000882de171aa384,0x000e4a1ada294142,0x00008b1ad2ef16a2}}, + {{0x0002720142bcb30d,0x0004caf604d0edda,0x0007963145617526,0x000d19086189c1e6,0x0000ab01c692b04d}, {0x000e4b0ba8ed3c18,0x000c6281acfb4e54,0x0000a6319f616513,0x00087baf1796295e,0x00005e79ac9b28b5}}, + {{0x0004588c9fd7da08,0x00009238d0c391d8,0x0009d6475a78682d,0x000e18333ddde082,0x00000c88440e9de9}, {0x000f21ac6d8176ff,0x00059509d46f6d15,0x000bbfcd5daff943,0x0006880191bb0a8b,0x0000f7732b8f8fc2}}, + {{0x000772d5ab3d89e9,0x000a2a786c9072fe,0x000323866f1580ec,0x00096f8fd834175a,0x00003711d4a4adec}, {0x000c34a6b9b4a308,0x000138b0de23a020,0x000de3ce5bf10e00,0x000c632a5f298d28,0x000007a398f7e1a1}}, + {{0x00040cd73f7c45c6,0x000d6afe059c3fb6,0x000b168d4eb1f87a,0x00003fa3c3979a52,0x0000eef460cdb1e4}, {0x0003e502724bb3f3,0x000c29d922d13d94,0x000538b4a53f3f1b,0x00045f547e7a03cd,0x00007631e2102c41}}, +}, +{/* digit=15 [{1,2,3,..,}]*([2^60]*G) */ + {{0x000bf06970e164d1,0x0008cd3d3087a7c9,0x000e7c899c27a88d,0x0003718a37c9cdf4,0x00008494d5abb411}, {0x0002375d9d8b29c0,0x000c915a2f740653,0x0005acb02b92dd45,0x000a898a23f6bf51,0x0000e69248c435bf}}, + {{0x00054fd6113a9f82,0x0004070e67e63614,0x0003f2feb78ebe73,0x000f368764360b90,0x0000ba3b3d8b7902}, {0x0008cef87490b8a1,0x0005005f31b31880,0x0009b4f4db117595,0x000e60bd5d60056c,0x00002b13fcaed254}}, + {{0x00074449a7a4edea,0x000695cfd20f1f84,0x000b33b64b26b1f1,0x0008c9f380ed7d83,0x000021f9564dd199}, {0x000c7d3a720e347f,0x00057bdf09d4e985,0x0009476929807897,0x000385a1f34ce2ce,0x000069e6145e419c}}, + {{0x00071ef16f55d400,0x00089bb45ea57fc0,0x0005543ca7019543,0x000c1983cf09f2a3,0x00007e91a8420554}, {0x000d70162a9d06ef,0x00031044a66261ec,0x000423dd900e14c6,0x000b4cb1317c1300,0x000049431bd946ea}}, + {{0x000548a60bffa601,0x000b7e0c4e341ed5,0x000db5bad903708b,0x0008a5cbc42d78a1,0x000052ad7377be14}, {0x000cda3ef8265d6d,0x0004490c675cbb3f,0x00033d235cfcb34f,0x0003cb0c2954b5d3,0x00004a7d16a1a320}}, + {{0x000dffbcdc0e5cfb,0x00040f611432a75b,0x000c16d43eeb8cc1,0x000997e3b489f974,0x00005c174e0722ed}, {0x000a9b6afb9c1d83,0x000295cb574a38ce,0x00015c4a8da546da,0x000307688d2edc0e,0x0000ffc898fef45b}}, + {{0x0005f1be45b69cf1,0x00077a5a8c531e35,0x0007d0264570bb79,0x000a61a0a43c059f,0x0000cd74a04320e4}, {0x0002e876cf3ac0a3,0x0002b212cb77fc35,0x0006c032db7672e6,0x000bc2045a0ba3fc,0x00003e7bc4433ad9}}, + {{0x0008434d0614aa12,0x0009f14184341511,0x000c15b898bae977,0x0002ebf5641d82b8,0x0000383af5661643}, {0x000d3f02c73f990c,0x000f66bbdc7ce552,0x0005ec6348df82e9,0x00053f0f336aa8d7,0x000042e3b2dd603e}}, +}, +{/* digit=16 [{1,2,3,..,}]*([2^64]*G) */ + {{0x000e020bad830d23,0x000e890dffb31b33,0x00080ecb05c101f9,0x00093ecd0e0498bc,0x000002787f882aa2}, {0x0004ced220f8fc84,0x0000fe0ee3777fd6,0x00013b128cf5cebe,0x000279dc03a03889,0x0000b0969723de23}}, + {{0x00089aff727ef3ad,0x000603db88fa9c53,0x000ae077795ffeb9,0x000f0227cb70429d,0x000020afe82316db}, {0x0008e18914bf7060,0x00030517cd090fab,0x000e406443b1e66f,0x0008fa24b46dce12,0x0000ff1016808f2d}}, + {{0x00034c883dc54470,0x000b04e4e9a0e55f,0x0009166a2be76243,0x00080a78fb4cbc81,0x0000bdfb703ae37f}, {0x000288ec217cda8e,0x000242af41561869,0x000ae9d302662bb7,0x0003c9ce64f29150,0x0000e0d4441bc035}}, + {{0x000aaddca9a95262,0x000a89a303e9913c,0x000a50f3c701c63f,0x00057fb97d667ab0,0x00007c03d7c88e65}, {0x000e712eb1056070,0x000d8dd86ccbab24,0x000986d684936aed,0x000a6532196f8a0a,0x0000307b826248f5}}, + {{0x00058b5ebbe949f8,0x0006e982215ad88f,0x000f863c0b776229,0x000f513cc83dd6cf,0x00001ec094d81098}, {0x00069aabe0432d02,0x000c8455957d014d,0x000dc1eabe4e52a9,0x00016f94743ba8fa,0x0000c395d97a1763}}, + {{0x000ab7799458b24a,0x0005ceba3064364b,0x000068f036fe19e2,0x0006559aabd83d74,0x0000ef812190fdf8}, {0x000d27b65593fefe,0x000edaa457b21506,0x00003dff40a1ad85,0x0006e3266d0f06a3,0x00008114f4f8bb41}}, + {{0x000e2d38fc2ed938,0x0005f8f0f8582acf,0x000a35ec48344664,0x0009b158de6f09dd,0x000091e5ece778c6}, {0x0004ba991c13d675,0x000d987d5575af4a,0x000303a7e6e78063,0x0007ed226b621e8d,0x0000c9bc10419598}}, + {{0x000581a88a45b65d,0x000138e58c1b905f,0x0005bfe1ccb78920,0x0001d714cbed65bc,0x00001af7dc8c02b1}, {0x0001bc0cd3a7cc82,0x0008c01a77b79834,0x000e2a4028e9aefe,0x0008598eeafe875a,0x00007a0698fe11f3}}, +}, +{/* digit=17 [{1,2,3,..,}]*([2^68]*G) */ + {{0x0005759c85448853,0x000aabfcad786b80,0x0008fe78ebe9b99c,0x000bcfd1db36e12b,0x00007255a2e05387}, {0x0003a3ea150ad323,0x00039671ae58d44b,0x00052384bc65bc2a,0x00030041ce078e1d,0x0000115f1b1ce72c}}, + {{0x000517480eed542e,0x00021362ef7e34a4,0x000dd0396add6456,0x00038b39228bfcc5,0x00009fdf904ca0c5}, {0x00091ec74d235de0,0x000824aa0a476bfd,0x0008d616896ec237,0x00060bf5699241af,0x0000a7b9be3c548a}}, + {{0x0002854f2b4c5818,0x0009ca26223a3e67,0x000aa188c6df8d84,0x0004ebd1debdf2e3,0x00000bfdc0a33d8c}, {0x00049164502ad485,0x00013c4eec044436,0x000526b7ad1ce82b,0x000ec1b7c386c272,0x0000a6cc4f4bb8de}}, + {{0x0005c302ade9556b,0x000c25ba2e9b3525,0x000ce9e47e328af1,0x000cc99d3391ef41,0x000074cd669ab0ff}, {0x00003e4e3226acf3,0x000d02959e429671,0x000d490fca65ad22,0x0003563aaa840699,0x0000e26a1c2cecc6}}, + {{0x000c3180561c002a,0x000500356bad1178,0x0006c78568e636d7,0x00001af8d07145e3,0x00007730567cae79}, {0x0005ddcb77d9db90,0x000989d16e89691f,0x0005142a2f824b7f,0x000bfaafb5c9b7eb,0x00009b34446f6015}}, + {{0x0000be45824c88aa,0x0001e847b35a949b,0x000027aa0e3a35e8,0x00082301594fd284,0x0000aff184b8e873}, {0x000e135810fa4740,0x000a8f7398d7d5fc,0x00096a1f3aba6165,0x000924e3aaa99a8a,0x00006ff0fd3b6295}}, + {{0x0008b7dfddda1bc2,0x0009d5f713ecc26b,0x00012edcbc93512b,0x000095029ffeb33b,0x0000ea0649923564}, {0x000b5a0fcd32167d,0x000a0c2eb30bde37,0x0006cd0182008416,0x000502b2663d607c,0x0000810c96305b2b}}, + {{0x00075de4e92defc4,0x00041008988331c9,0x000c0919081aeb17,0x000d648a30ce4a2e,0x000026e7838a9a36}, {0x000a0b6309bd2d7d,0x00000cc1a4ae8899,0x0005163b33b1c24b,0x00086db2aa814234,0x00002ad9a69fc78c}}, +}, +{/* digit=18 [{1,2,3,..,}]*([2^72]*G) */ + {{0x00033c6ba4e4651b,0x0000b714d4ac4672,0x000f1f8da8cf9566,0x00070ed70decc371,0x0000674732b20783}, {0x000416d4ccc773bd,0x0006ae87951d7270,0x0003dfb56c848ff3,0x000110a61506a849,0x00008371eaa467eb}}, + {{0x000ee2fda3adfe0b,0x000cbc964e7d1066,0x000859476ce6a9bd,0x00099c04a0115b0c,0x00005e02dca4c956}, {0x0001f6211377eb91,0x0002272bca2ee830,0x00047cf1f57b245a,0x0001c1a7d9b4707b,0x0000b469bab2774b}}, + {{0x000fa67dfd6586eb,0x0005cba23faa1dfc,0x000ec5d6f358953e,0x000b2a0f467275ae,0x0000815967b0b0e6}, {0x000f133012b89b41,0x000c7839cc04a01b,0x0000dfd73dd924bb,0x000098a5cd218012,0x0000abb11ef29bf8}}, + {{0x0007889f1ef22320,0x00019c7409a50397,0x000004e03be2c82f,0x0003a335ac44f932,0x000048bb35985682}, {0x0008d6cec1cf253f,0x0008603eb1d13e10,0x0000ac34de98e74d,0x0007facaf64f6057,0x0000f814e7e3d779}}, + {{0x000b2eb0d1b96aa9,0x0003ce52ccf0cdee,0x000d534ef25783ce,0x000dade4e251f429,0x0000fe9693de5797}, {0x0003d69c6ab9935e,0x00095721ca8d8a17,0x00093eb262399131,0x000a9e38cbcd30c3,0x00003627aba51d95}}, + {{0x0000e575ef764b4a,0x000d5e73c69849b6,0x0002be1ee61ad29f,0x000a7118489017dd,0x0000c95e3b71febd}, {0x00053465ac960924,0x0003ffc835666698,0x00072fa4a906265c,0x0005401692c81259,0x0000e76f87940773}}, + {{0x0005c3ea7b82f5c5,0x000f3a98adfad6a4,0x0004b182c494694d,0x000b4144a06ec313,0x0000570befac5b82}, {0x0006808129f952e9,0x0000214f87c3f19f,0x0007be905a6fad26,0x0005c2831e56687c,0x00003107f397623a}}, + {{0x0001bcc89e35108a,0x000433f1cbaf57cd,0x0005b13ac924efa4,0x000a1de3716559f3,0x00000a88e8800370}, {0x000be0a8c286ea33,0x00069ebd50c6e203,0x000284d0897fc5ab,0x0000e02b5b360274,0x0000055716f994a2}}, +}, +{/* digit=19 [{1,2,3,..,}]*([2^76]*G) */ + {{0x000a63d5b99708d3,0x00077b80189a4d67,0x0001c402efb29bef,0x0007673cb7eeaa24,0x000028cb6de5c5c2}, {0x000a7b49cec231d2,0x000c2e2e6a7eed24,0x000f17b13725955f,0x0001cfa2040cfab7,0x000015eff8dc25c7}}, + {{0x000cab1c0d41a942,0x000abe60f7d4c4d9,0x00036116cc38b202,0x000f132bbf6b1793,0x0000f9aa8774e068}, {0x0000627a4bac9fd4,0x000eca593cb4b882,0x0004179312209cb9,0x000fbfaa78ec63c7,0x00002d21251bcfcc}}, + {{0x000fb305334d7b56,0x0005a11f7073b233,0x00097794e41b5755,0x0000dd099a53713c,0x000056ead5a9a5f0}, {0x000696f1e3511dc7,0x00070e5e30fd2ece,0x0004ace651828a64,0x00061ce007b8ff60,0x00003da66390b892}}, + {{0x000e5ae3e6119407,0x00097aa090ebd0ce,0x000926e424e2d9ea,0x0002a373d167ef1b,0x0000fff36dfcd511}, {0x0007745caffa3fbe,0x000fa5a835034558,0x00047bf2a224f7f4,0x0005c65ceff0183b,0x0000d9bfa74ccfab}}, + {{0x000c13c73f076b32,0x000eaa3baf1a5581,0x00086b1ccf225af7,0x0005b36fa0d82d4e,0x000009f416823464}, {0x000cfcb2fbe643e7,0x000163c46a73f613,0x00019477d806abcd,0x000c02d04bc1028a,0x000068888cb668be}}, + {{0x00070b8d9b429c9a,0x000765ad81cb53d5,0x0006825bd6946011,0x00036a30833a082f,0x0000297122b1c99f}, {0x000b84805c3abdf7,0x0008cf2e24b1ffc9,0x00015d922efe9529,0x000726f045275a89,0x00009146aab998a9}}, + {{0x00051d89cdbd4b33,0x0000e1195d208087,0x000c6618eae8de7a,0x000cfbdb08e2fc12,0x000097fc24f3fc4a}, {0x0002071844eeaa70,0x000b2c004c259869,0x00035fcca2b3e1e6,0x000be4a1211da1e8,0x0000c881208c73ff}}, + {{0x00059054f831d0b7,0x000c9d47d4fd9c7d,0x000042e12faaaa26,0x00077d5ac2859985,0x0000eda370be7969}, {0x000d71d95c0be637,0x000cfe8210052f0b,0x0002ffae97c4601b,0x000173f1ecbc604c,0x0000e3efc580b688}}, +}, +{/* digit=20 [{1,2,3,..,}]*([2^80]*G) */ + {{0x000ca15587feffa0,0x00007d69e4ad8348,0x0005a0745585d074,0x0004dd6fbe561988,0x00004ee9ebab10b2}, {0x000075c0f4c12d76,0x000c9c51c604fc27,0x000e336d0acf4acd,0x0001d2782fa52bfc,0x0000e1d078fa8362}}, + {{0x0007a1bb2b806a85,0x00010ad5d0f42438,0x000a0e9e414efa30,0x000decee7e442123,0x000004ae4288b6ab}, {0x0006fcb927b1aac6,0x000c923b71d358c0,0x000d6dae155e1c85,0x0000b8f47e180f48,0x0000d80dd64084cb}}, + {{0x000c3819ec64698b,0x0001cef36dd1f0db,0x00056bdfd770e4d1,0x00094701d179158d,0x000048153ce25eb9}, {0x0007a54fde983909,0x00079fe2d6fc31d1,0x000a704f10817eaf,0x00018244a63591a6,0x000042346600f554}}, + {{0x00086430d7fff59a,0x000407bfe742e8a6,0x000ce06f982b9219,0x0001341a8b86cfc2,0x000038414a199ad6}, {0x000261028e2c39f1,0x0000580856a06f10,0x000c3034d34805c2,0x000c9d1b3f930218,0x0000713f457674c0}}, + {{0x000c8821b96672b1,0x000b479d1f5709cf,0x00069a5142759c76,0x000413a6cc7a9822,0x0000bc2015b783b1}, {0x00011781bf4be622,0x00059bf2b0bea43b,0x000591cfdd294197,0x0004951eac3587c4,0x000083169e62e66d}}, + {{0x0004800da0723bca,0x000093c8381d3859,0x0008ca980524452e,0x000e56846dfa0213,0x0000a77a80d82d32}, {0x0003fbc419c86b5a,0x0008570216c28757,0x0002036e6e748680,0x0003d88b7a685ac7,0x00001764627b5fae}}, + {{0x000d0556b1fb1041,0x000441fe146f9ea8,0x00063c4132ff339a,0x00097b3d7ef85bcf,0x0000f0f57c5389a0}, {0x000f83b5bda1160f,0x000e5fea66e792f2,0x000e11651433eea4,0x00043b1f3fff4fca,0x0000a71c3fe5b1c2}}, + {{0x000edc2023cb0df4,0x000e15a245918b52,0x0002a907208773a4,0x00086e0d9a6aaae1,0x0000261f56f9bf55}, {0x000040260a081069,0x0004409cfa60884b,0x000dae4831b39805,0x000cdedf7f55b1d5,0x0000554210f16ef2}}, +}, +{/* digit=21 [{1,2,3,..,}]*([2^84]*G) */ + {{0x0006e859204db305,0x00087aa84cdf064d,0x000476456139bb92,0x000a669413d7ea88,0x0000c554483aa1ff}, {0x00030892ed180808,0x0001514e5daefb86,0x0005f81ca589aaf2,0x000415eee4f96f7b,0x00008d470079bb0b}}, + {{0x00000d355c9bd11b,0x000cb6fc28506bb4,0x000063b3e8402465,0x0000c6a81ba22d65,0x0000ab2dcbd1e1aa}, {0x0003f1abe645e253,0x00037df84be1b5f4,0x000a2eaf46232053,0x00026f14ac708021,0x0000f94646488beb}}, + {{0x0003e9a7a82d20f0,0x000c191011f25f2a,0x0006ac8e6399e015,0x000f96fbec312a88,0x0000dd5140aeda47}, {0x000f31326b47318d,0x0009b6685ec73d4d,0x0008442cde2c9ec7,0x0001cf4df119aecd,0x0000b1ca9564b32a}}, + {{0x0005852126506ccb,0x0007b8b3567cce2c,0x0005a3f24ba94aac,0x0008b36905cdf4c0,0x0000f5f559be547f}, {0x0004e62aade7a1df,0x00070fda3087ae4b,0x00043d89f56b8b9d,0x000047ea3eb4c64c,0x0000b7e537d8c69e}}, + {{0x0009491dfe5f6ab4,0x000e01a9c0af823d,0x0007d2b3542fc362,0x000aeb04170b0112,0x0000f0f17bc44116}, {0x00001dfc9184cf6f,0x0008795ceae6816c,0x0000bff2e914dc87,0x0005db696b2ae839,0x00006ccd629e88af}}, + {{0x0009bb90f88095a6,0x000ff19ce3057ada,0x00078b2667155c28,0x0004f832a01e476d,0x0000da9445a1652c}, {0x00083a6827ea8efa,0x00075db1af2b0317,0x00031dab94d69b7c,0x000ace2874eb38af,0x00000ed99114fd9b}}, + {{0x0002e3a4037f17e3,0x00018f91a4fa4d89,0x0001cf02f81fa984,0x000c7517c7292d96,0x00005af0c0e688bc}, {0x000ec90127a29b07,0x0004ad087444c40b,0x00087c273955714a,0x000da2fd430880a5,0x000015ecd51424df}}, + {{0x000066daafd6cefe,0x000fd8c1decb6ade,0x000b96ecece59c8d,0x00010c3e12a24a77,0x0000e7c32fd24cc7}, {0x0000e4f240e9bb7c,0x00052a63b06db070,0x0009644ee837ada5,0x00051ca58ce980d1,0x0000aa5d14de7e74}}, +}, +{/* digit=22 [{1,2,3,..,}]*([2^88]*G) */ + {{0x000d50cf1edd62f5,0x0000229f48d97a0e,0x00072ae88c3c7ae7,0x000666ff47bf288a,0x000084ddfe5848c6}, {0x00037e936731fdf9,0x000c18d98bc79711,0x000a6be30714bc7d,0x0006a5cea912c10d,0x00001cb844e4e62d}}, + {{0x00093634626e343e,0x0009d4e4c8f9696c,0x000648a06f699957,0x0006e5ce7306f6b8,0x00002775c8d8e799}, {0x000e678bf09d221c,0x000f115c2acdbb47,0x000b48b41f5251e1,0x00074b087f912177,0x000040e7726ab38d}}, + {{0x0008aaae4fdd396c,0x000f9371c3f3cdc1,0x000dfefdef6e8a9e,0x000577c6b58042a5,0x0000cc3bbb7bc4f3}, {0x0003e4adedfdd556,0x0004148c5fb23f58,0x0002d61e09ea4513,0x000b38ca2b322923,0x000042101a910b5c}}, + {{0x000ab3cc064f530b,0x000f8e1758919b7f,0x0004c4e60731153a,0x00013a335e65033d,0x00000876a8b276ce}, {0x00066ee22241ecd1,0x000e111e861c98a5,0x0007dd490b7456b3,0x000c40a9aff4eb17,0x000089b1ed9d8f77}}, + {{0x0006f5a394d7786d,0x000dd7ff0605880d,0x000dbaf4d3e66b3f,0x000f09abeb798da3,0x000055a81a432168}, {0x000e4853cae87841,0x00051aa0e48c3e00,0x000e17bcbf4bf671,0x0005a084ce2b4df4,0x000010852e0a41f1}}, + {{0x000666f50956c896,0x000bf47304e9abf6,0x0001770f44938548,0x000bb75c17622116,0x00005f7c0b74c493}, {0x000e3303459a009a,0x0002d40ab80bc6fb,0x000f5d3096dbed19,0x000e7a5fc682575b,0x0000ba698d48d53c}}, + {{0x000db6a830ae3327,0x0006ec5c4f57bc5b,0x000a40ac4ef38847,0x000d07b5329ba2d7,0x00004b55633b22e2}, {0x000719d1f38f3c87,0x0006dba25c7f63e8,0x000c8bb16e712c08,0x000bbc9fb85a3b64,0x00004ee16f039ef0}}, + {{0x000e6872857a1fc7,0x000c9ff8f504f24d,0x00081bc9abd0a0d9,0x00041beecb4fadc3,0x000023862936a94e}, {0x0003f83e75fc753c,0x000467a5a6be754d,0x000f568dc06afc75,0x0006471ce792eeb2,0x00005faaee47d2f9}}, +}, +{/* digit=23 [{1,2,3,..,}]*([2^92]*G) */ + {{0x000beb0f912b74fe,0x00024e0ceedc375f,0x000233ee745fbe8e,0x00026ef0e1aa68d9,0x000055fc1cf206a6}, {0x000a1b9e08712e7a,0x00065cfd635f80ef,0x000c1edac5fd108b,0x0003f1ea431df6ee,0x0000e1c052234080}}, + {{0x0007fb664bc0f09b,0x00027953cd07f8e9,0x000c3bf000b91399,0x000d8f8385a1b37f,0x00006e74ded609cc}, {0x000f026ec473ea77,0x000ec30766bcfe1d,0x00092052bf2f7fbb,0x00066af18cb47a32,0x0000f8d459301148}}, + {{0x000d957b3086691a,0x000bc6640915a8d6,0x000db59a99946a29,0x0001ba932ca93c43,0x0000a61a0c684fe9}, {0x000e112815bf0033,0x0008f86ba8d36e22,0x00069f434a9ed1b1,0x0007541b5d3c1410,0x0000cd2ebd04cc01}}, + {{0x00007cb8e419e083,0x0007df855eebfb75,0x0008683a5785328d,0x0007e9875db0c77b,0x0000d1bc968c0a59}, {0x000fa1047eeeab4d,0x0004a680ca70ad4a,0x0003650232668dd4,0x0001ccc3210d1f17,0x00005bb2ee4e7fb3}}, + {{0x000156fb22c5f89f,0x000baf786759c0c3,0x000b8ad9fd10ece4,0x000420e270e31780,0x0000e7a6211a0c2b}, {0x000d738125ef6358,0x000741a6f2027091,0x00087d9bbf1f277d,0x00084be2727e7b35,0x00003b209aa33e2b}}, + {{0x000bab750f2b65b6,0x000bbe5d53e3b5b9,0x000529212a7403d4,0x0007672e23e37628,0x0000fe903a2ce050}, {0x00091a16cf570fb7,0x0007ea30b325dc52,0x000c572a94bfb860,0x000c31ec4905f827,0x00002eeb8c97f381}}, + {{0x000502e9c14b6997,0x00067948a290b6b8,0x000efd415f1bcdca,0x000fb573e43a322a,0x0000f52335841e2c}, {0x00051c097d3fa948,0x0008f21296302601,0x00054acf5820c0d5,0x000ac3b8f2e1ed58,0x00006d6646cbc656}}, + {{0x000f6acf96ec2b85,0x0003f961cc16524c,0x00017f0a2d06747c,0x0002d657c7001cbd,0x0000f298db084afe}, {0x0001ef2df12f671a,0x0006fce712fdb1b0,0x000a74776c01c506,0x0006bdac0f403492,0x00003e9934fa8d69}}, +}, +{/* digit=24 [{1,2,3,..,}]*([2^96]*G) */ + {{0x000b8941abd31f02,0x000dba1da7d32599,0x000f0217ddb34198,0x00084ea8b89523a0,0x0000014cc44056b8}, {0x0004f8849efd4ee8,0x0000a87f4adfefb9,0x000fd2debf1b8171,0x000a5389d38a9a99,0x0000179277af2b67}}, + {{0x000ee9e2d3a6e28e,0x0005486d8ca2fd5f,0x0000834918eed56d,0x00045736889a2778,0x0000a1a65569ef20}, {0x000b609a501e2a36,0x000a5b23de2f87e6,0x0002c9a6b1ea0ae2,0x0009615f537d0763,0x00001770d1ffa3db}}, + {{0x000d1fa9047d3c68,0x00041e2d51ce4e21,0x000b10c9c847d157,0x00062380167a634e,0x00008966868f8c07}, {0x0008f2cdc401ce66,0x000ac97d1c838e87,0x00062b7c27f46062,0x00036e04a047da68,0x00008a2cacd5afd6}}, + {{0x00060db7497e8a5a,0x00092c6949a8925c,0x000bd589805d8eab,0x000e3f3169e466c7,0x0000dc06264b92d8}, {0x00068f4d55959fe4,0x0000602dba18dff4,0x000cf84bb97b33ee,0x000176aa0c3fe221,0x00008cdc0af44a8d}}, + {{0x000730ec599b822b,0x000e71db1fe734f3,0x0008091cd821b583,0x000cffa5b97c09f6,0x0000eb36d9557afb}, {0x000e9729ef451b2e,0x000cc72474ce4e71,0x00075c396c20a694,0x000fa4d30f6220dd,0x00000b129e07fa41}}, + {{0x0007a8b81ba9b34a,0x0005d196b5125a9f,0x00076f535e32ba94,0x00063f93a571c824,0x0000fdf2923b8108}, {0x0009a3c16169f605,0x0002eb5c7c3503bc,0x000d93e032a0397f,0x000ef4f1059d5016,0x0000e6e9109888f5}}, + {{0x000a9ddaaa05d08c,0x000b651b5a2480ce,0x0005d54b4d0caffa,0x000009d63010c858,0x0000852d0347e35b}, {0x000e50ef3df425c4,0x00023f86f10c9508,0x0001059ff9e45970,0x000ff4e36cccc208,0x00008d3f15023989}}, + {{0x000c4489c0d40099,0x0007be24dba9c3d8,0x00062e5f1d371461,0x000c8add92e7309b,0x00007b344d82922c}, {0x000009b0bfe3e8fb,0x0005a3c82268916b,0x0006235555687383,0x000e54f82a980fe6,0x0000027ecab0ce68}}, +}, +{/* digit=25 [{1,2,3,..,}]*([2^100]*G) */ + {{0x0002c86fbd613c3f,0x0006b366f179f698,0x0005c2343f4af69d,0x0001168683eed6b8,0x00005bb244b14bc2}, {0x00074bcc9fc77d46,0x0001cf44b54b397a,0x000997e76e202eb9,0x00037e77886412a6,0x0000996c8fb62c88}}, + {{0x000371c902c343de,0x0009ba4fdba0d2e9,0x0007703a1f57b2de,0x00020343f9afa4b6,0x0000afafb42d79fe}, {0x0009dc9f649a4940,0x0009fe378232fec9,0x00084e31e14799ef,0x00087fba3f811471,0x0000abbb815dc0e9}}, + {{0x0009ad6e069de1c1,0x000a8ee09300c258,0x0008ae49b3fe8e67,0x000a905b8818602f,0x000086a1482363a6}, {0x0009b399b35b33a4,0x000993d3411d8607,0x0000b2f996c38d78,0x000d08743c446272,0x0000d903dd769e14}}, + {{0x0005efcb4e31aa48,0x000098b26adf5408,0x000a7400dc760aec,0x00012814c1f78e76,0x00007b8acedb17fe}, {0x000582ecbd85bb42,0x0006a6adc0412433,0x0000d578158f0142,0x00082f3596dd508f,0x0000e7f3b803a31a}}, + {{0x000bd80d6d7878c9,0x000ec4ff7c7505c9,0x000ccd599e1ef20e,0x0004f93fab197ad2,0x0000e480594252ef}, {0x0007fd206ea34109,0x000504fa7dd4d977,0x0003bb5fcb028045,0x0008a8641b6860c4,0x0000f359d5c7cd7b}}, + {{0x0002c379ce084523,0x0009d3a870244ff1,0x00049dcb63dd8dd0,0x0006de61ff0d39b8,0x0000f5eab872efad}, {0x0006886251523f97,0x0002cbe2135b4614,0x000d2c5d445ac1d5,0x000e726350799541,0x0000f19f79a23064}}, + {{0x000044ae1118539e,0x000d3192a0069335,0x0003a2bd4ed6d43f,0x0003a51a8bf622a4,0x0000fec3fb7cfa9f}, {0x0004bbc6d834bde9,0x000940fbc743dd22,0x000ea1652aaebfcb,0x000816383b2bfcc4,0x0000cd26d91051ae}}, + {{0x0002a29161f6475b,0x0009ac8797ea7d83,0x0001b609c435b8d7,0x00000466bc156dd7,0x00003dca799ae0c2}, {0x00047bf02fd92d7b,0x000978b03082945d,0x0009a7c511d1c979,0x00089aca46d98d07,0x000093f286ccafeb}}, +}, +{/* digit=26 [{1,2,3,..,}]*([2^104]*G) */ + {{0x0002d2d4919affec,0x00046009bd158037,0x000a62eb12d4a2ea,0x00012448f1e7f8c1,0x0000e083726187a1}, {0x000261be7ebadd32,0x0006257b93e9c874,0x00039e6ff7ca5c15,0x0005c3e8b381e5fe,0x0000d16b32ff3081}}, + {{0x0000b28ad2e996a9,0x000d2df0fc374fd3,0x000c3976364d4eee,0x000e8e8e049e3ddd,0x0000f55e0cec7ea2}, {0x000ba4e4bf019842,0x000dbd55bc4bd3fc,0x000da895f764d5c3,0x000a6998cb92a1cf,0x00007dfe7957c7bc}}, + {{0x000d127df32d462e,0x00069353d1362a82,0x0001a23472b2d2a5,0x000b450ec57e5916,0x0000f4ff6eae5ff8}, {0x000400ac40a9d454,0x00004596718f82b0,0x0007a0dba9ecfec5,0x000cc066c183470f,0x0000f1aef698d4ca}}, + {{0x000decf23a86e2cd,0x000c0387f711b6df,0x0003509d102ac466,0x000bd1c30a1ac2d6,0x0000391342333aeb}, {0x000789f068ae34fd,0x0002187dcd100c7b,0x000e8a4b4499f2d0,0x00026c68e2a3bca3,0x0000f87ba71e4d2a}}, + {{0x00026848490bfdd6,0x000e35430226bf58,0x0007ae001b81059a,0x000449d5557551b1,0x00009a0e4f06a9c0}, {0x000ffb5aa7f70c1b,0x0000de46ce99fb72,0x000a020f9ac4e4ba,0x000477e56ecf595b,0x000074c5d6609374}}, + {{0x000b99934479e7b9,0x00044026e7800e3a,0x0001bd4299d5f2dc,0x00079a131374fd4f,0x00002e2e7392be13}, {0x0002f80d13bc1116,0x0000e6f81c920cc3,0x00063913a6fbfc35,0x00075c12ca1b3092,0x0000f7da200406ab}}, + {{0x000ea765fe235a8e,0x00004de31523f94b,0x0000ebfbb64be92a,0x0007ec6ed505fa08,0x000003434e32a6db}, {0x0006ebad02efcc64,0x0000d651266ce100,0x00052a6a6f23ba6a,0x0009c596fc0cc05d,0x00008d95322f6ce0}}, + {{0x000f12a19301b163,0x0001ec368a201780,0x000adb344233bc23,0x0005a1d9650892cb,0x00008a0d964dd942}, {0x000bcf24a8d4d7e5,0x00020806ce9dd77a,0x00070d4734ccd16b,0x00078082ff40f075,0x000074914152f130}}, +}, +{/* digit=27 [{1,2,3,..,}]*([2^108]*G) */ + {{0x00041205d8f6fabf,0x000a9bed09c79d8d,0x000acbb1e5e42083,0x0009965120e0794a,0x00007e840f9dc1bc}, {0x000d63b9707c3bb7,0x00091e891a716921,0x000bb22783ab4b8b,0x00091cbe46575673,0x000076ce040c53ee}}, + {{0x000b010fdc7945f2,0x000023750a4bcbad,0x000c85b9d62c9cff,0x000bf975192383a0,0x0000aba7b5336eb0}, {0x000adaaa4c06f9ad,0x00032f8e482bc3d4,0x00091a79f573a86a,0x000ec2109c6fdce7,0x00009ed02cf837ee}}, + {{0x00019d38fc7ea72c,0x00063211ef447211,0x000eda1a2390b4ef,0x000596289f39451f,0x0000ee9cb34205c8}, {0x0009e96971b6897f,0x000409701ea6a110,0x0002c6b2bdf70c17,0x000766a07d0ecda9,0x00008eb97ff99eab}}, + {{0x0008c448b63b669b,0x00071972d2d0d6f1,0x000ff59bc53c6eba,0x000ce52a522d8c8c,0x0000c181d161ed25}, {0x000173d5feb0eca8,0x000e2207bd71113f,0x0001715ae34273f8,0x0004ae41b7572efa,0x0000a8ffea2ff16f}}, + {{0x0005e681e13eaee1,0x000419dafdb94ed7,0x000941fc4bebd474,0x000bc08b46621f69,0x0000fd3c13fa1129}, {0x00048d0b7b9da22f,0x000bc87a47414714,0x0001c38b9d452cce,0x000bfee2f04778f9,0x0000b443a5ead516}}, + {{0x000b4797e8215d87,0x0007023b4b27721a,0x0003d21ef8438468,0x000e1ca93c08fe6a,0x0000bd962489fa6d}, {0x000ecd7ca6de3e08,0x0008c7c9fced3858,0x00008239e466a48c,0x00083323ca9b75c7,0x000060d553e35bbe}}, + {{0x000e02a5022112c4,0x00015461b1c6a66c,0x000247c388415df8,0x0004d6c2546e6aad,0x0000b9788e6da9c7}, {0x000b2e0a22be3e86,0x000c895f76ad3d0c,0x00033767015db086,0x000f549758f99ba2,0x00001ae09bbfab57}}, + {{0x000917a2f8ebcf55,0x000be53f056ca356,0x00084bb486f2c400,0x0008e309d9ac41dd,0x00000dc7a8ef61e9}, {0x000a9d33d3a67762,0x000736de8b3df179,0x0006e2beadda312e,0x000ca062a8b7c3ce,0x0000b00036c845e4}}, +}, +{/* digit=28 [{1,2,3,..,}]*([2^112]*G) */ + {{0x000cbd7ab6cf0b48,0x0005713d1ddf1ad2,0x0006003ba7a1e67f,0x000fcca58f0c7374,0x0000263e889264a8}, {0x000be37be2452f79,0x0006fae81a75c35c,0x0005537019312576,0x000d787d2ed0ab3a,0x00003d7e7e040717}}, + {{0x000013cf9cf03baa,0x00099eee3a77c1bc,0x0007e4c9536223b8,0x0005e486efc9233d,0x0000f3801bf36562}, {0x000a1413f32fd9d0,0x000c4e564acba7bb,0x000edcac170724de,0x00098552587f32b7,0x0000b1cd94cb3969}}, + {{0x000407a661fbdabc,0x000718e52150df08,0x000dfe954c4d7c53,0x000dd1a3765bce63,0x00006829bfc6c2dd}, {0x0003f65dc6e44874,0x0002ff04c9305739,0x000838c0a9ba2942,0x0005cd493c691418,0x00001b137ff8b2f3}}, + {{0x000aa244e1c5e60d,0x0009e3253d50f9e4,0x000babe5354bb528,0x000a64f4a86ab39b,0x0000561feaf3ac0a}, {0x00096ab1911bad71,0x00087433730317a8,0x0001f69289cb22b9,0x000c9ff14262fb16,0x0000661885c69ba6}}, + {{0x000ebd3b82574dbc,0x00034d8af3f58666,0x0009319bfc5e8667,0x0001a8cc64520520,0x0000183c12ef834d}, {0x00073da49eb0f402,0x000c8aca649e333d,0x0009e83613bcab0b,0x000c85a02f4c41e3,0x0000391e7aec89bd}}, + {{0x0007c5e608cbe2f2,0x0007116c22f26806,0x000faf9dccdec82f,0x00085c80aa719af1,0x000061fe95143401}, {0x00013669713e72e6,0x000ecd8a2a466b41,0x000106ce0db1e405,0x000e69ed17475711,0x0000d70cf6f571c0}}, + {{0x0000322cf707c76a,0x000fe0b4b7d71531,0x000a2d26d3a1eb2f,0x0000c0b83259fbb1,0x000083ffb1019972}, {0x00019280bedb326e,0x0001c92717150ecb,0x0002d71a94473e82,0x00056d506e6d202f,0x00007b253b223197}}, + {{0x0009335f576cb3cb,0x00048fb3b78e77e1,0x000da0001e16e457,0x000c5eaf96d78563,0x000038deafea7444}, {0x000b38cc0eb0e287,0x0001efe41b983ca6,0x000965b31a6ca354,0x000bc6feb37b4718,0x000039cc322c97d5}}, +}, +{/* digit=29 [{1,2,3,..,}]*([2^116]*G) */ + {{0x000ac99a211ffd3e,0x00051f1f6bca019f,0x000648244408f942,0x000d671f5b76d1a5,0x0000f3942e975b2b}, {0x000ee7fb538f1d7c,0x0001044b8f845b9d,0x0008ea6a31cb7862,0x00071f9f8ecd63cb,0x0000a111b2f79d3b}}, + {{0x0000e21091e1c4cc,0x0005467ccc747cc0,0x000ebbbe4d500db4,0x000ac0a8e2e84bf5,0x0000326688284279}, {0x000b4de7a1706589,0x0001e1da4a2d9e8f,0x000acee19219c5ec,0x000243da69a3fdee,0x0000d4c6fbdc0462}}, + {{0x0001d166087c5e5f,0x000fb53a8bc4e962,0x000d314cdae49c2c,0x000f18d7868882ca,0x0000de10dc89a57a}, {0x000a60d3800f3973,0x000b688b333c0fa8,0x000fa8129cec8ae7,0x000c32efd8d69285,0x00003d5685bc0776}}, + {{0x000f768680dcbf99,0x0005df0a51df60ac,0x0008df9c55072b82,0x0003323a74751cd8,0x0000d20f989acc1a}, {0x000042b6926c34ad,0x000ed076687f7e90,0x0006e9dcb5c728b1,0x0005aef2e3bfe8f7,0x00009822f0ae5a12}}, + {{0x000eafec58b6d022,0x000373443629441a,0x000823652750cd60,0x000d5ea68af789e4,0x000084d1e24e8d6a}, {0x0003ee3c4d56ddf6,0x00000c18e36243f9,0x000a2fe798365005,0x000df90e409c5b85,0x0000127bfe085cfd}}, + {{0x000ff1d35689ad9f,0x0003932addf1ec56,0x000fdde42e0f2114,0x000f5f4d52297877,0x0000402832dcd838}, {0x000267d915ac8813,0x00003c9963a5fa13,0x0002a42bdcf224e2,0x000c500d44419ac5,0x0000ed2898d4cc0a}}, + {{0x00005799f67b96be,0x000b3f509e955e73,0x00016dc34c6d265e,0x000493e985dceed4,0x0000308208028803}, {0x0004271dc7a39d4f,0x00032b9f5dc3afcb,0x000d33ea6839afda,0x00065a1c08ba2fc7,0x00003ae1c287c591}}, + {{0x000db58f51b14b08,0x0006239a79f03f84,0x0005a1f11df73ccf,0x0004000ce1e5842b,0x000041fa6a3985fc}, {0x0009c682455c32a3,0x000eefa71cc364b0,0x000797929383c9bd,0x000a5db63814861e,0x00003036faf923d0}}, +}, +{/* digit=30 [{1,2,3,..,}]*([2^120]*G) */ + {{0x000cf7c90f17cbaf,0x000520c7c5f351b6,0x000cc7f385d655ff,0x00079ec64f29d54c,0x000028e85325124a}, {0x0008d5167bf1e98c,0x00001d7a33af5efa,0x0009a40a48610028,0x000a0b35fe2bb2cb,0x00005cc1bf203d50}}, + {{0x0002bbfa32106c2a,0x000ade91774fc0ae,0x000853a30ef155b2,0x00005b5567c3c713,0x00006be82918ddb3}, {0x0008c21ade26eecb,0x000cb03c17ec7db5,0x00093f8a2fa3c895,0x0000c696ab0de162,0x0000d2365ed5c371}}, + {{0x0003e73e194c6423,0x0006a89e3c856ab0,0x000dacd55607b710,0x000084952aab024b,0x00001ca3ee251cc6}, {0x0009b2b1c6b93f9e,0x000ccad930f7f314,0x000872630cbc5ef3,0x000fe2ed04984f22,0x0000f5d052e4c4b6}}, + {{0x0008d05570286777,0x000c3e9aabdf6202,0x000d4e5d090eebee,0x000873ab977aee06,0x0000a98c52869361}, {0x0001251b7c2474df,0x00074f3e7b01f49b,0x000e54af1cdaf2a3,0x0006b7638bcaf46f,0x0000ec426250dac0}}, + {{0x0008cf51eafe37b0,0x000430dd7c2bda73,0x000dd77af503eac2,0x000e7cf9b7b7a511,0x0000ade03afe9dcf}, {0x000d34af479e3b5a,0x0003a30a33f2a89b,0x000b64068993ab40,0x000110aef322bf9f,0x000047cc71bae27f}}, + {{0x000f8f8c63b9e759,0x000c9d7d130a519f,0x0008490b743f6b4f,0x00014adba3385d7c,0x00007889df79252c}, {0x000ca86b2f18b9f0,0x000ec3a87422fccf,0x000474838f092ff9,0x000e9ff96dd67567,0x000039e82875bad2}}, + {{0x00009112da32c0af,0x0003a2676ca256a6,0x000614dc6b2e1ac3,0x000965fb74093f17,0x000044939e52f27f}, {0x000a402c922422bc,0x000afff5c56e8656,0x0009aa62ed60a55b,0x000cd20d061b41ab,0x00009ceacff6ca3a}}, + {{0x0001d47515f954cf,0x000c6f470a3f5f58,0x0006feaaf145f925,0x00043bfee6b6b073,0x000090744b01ea57}, {0x0008ceaa2f36f565,0x000f33ed4006fd8e,0x00015e6db4239a6c,0x0003d10906b5bdd5,0x00003622990dac97}}, +}, +{/* digit=31 [{1,2,3,..,}]*([2^124]*G) */ + {{0x000667432efbbce1,0x0003f9639719548d,0x000662e7d64a6c2b,0x00018438c0465730,0x00005d1d7ca452c9}, {0x000630ccc3020cc4,0x000cf09f038f30e8,0x00076a744e4b56c9,0x000988db9cb5edfe,0x0000c85f020a947b}}, + {{0x0004873ec83c9534,0x00037a21ef09f49e,0x000f7d93eb4f59fb,0x000c823872d31440,0x000079e1d0302568}, {0x000dc9a65d43d228,0x00026775efa857e4,0x0006defa6cc068e8,0x000956b78ccae932,0x0000f92b296ada64}}, + {{0x000aaa9c8a3e3ac8,0x000f43979374b572,0x000f271ebf9bc4e1,0x0008468117501ecc,0x0000c636f82980b7}, {0x000ef401522bb338,0x000b1a451df84842,0x000adce528726480,0x000bb68955aa02ed,0x0000e83cf34e78d0}}, + {{0x000f8d5dea227eee,0x000d1dda8b9fd721,0x0003e3520f48c766,0x0008b60583d94be4,0x0000bda36cac1d89}, {0x000286a6627adaac,0x00015938368d5808,0x00050949f19c4c62,0x0006d9e0dbd707f7,0x0000adf4beaccf35}}, + {{0x000cce23329e671b,0x000133ba85f9fa3d,0x000d2f0acbfe89cd,0x000dd5a661b1f182,0x0000ec370f3d49b0}, {0x0004271be20fb25c,0x0003f8f79665eacb,0x0008e416948ffff8,0x000ba1df8d3d2cbf,0x00007a6d9edd03f5}}, + {{0x00053eeb5763ed71,0x00076458542565c0,0x000cd718c4a553fb,0x0004bb3b2736a46c,0x0000c4f9cded6489}, {0x00001a0f71211b78,0x0003f2974258adf0,0x000ff25912c5325f,0x00020be8e172f449,0x00002e960cb21a37}}, + {{0x000c4a93631bfbda,0x000ad77461c62943,0x000958036ce38afd,0x000c48f0ad59d5c1,0x0000e284bfe02556}, {0x0003006d8b01967d,0x000c55a31d662fba,0x000c592b66b2f4ad,0x000018fe6af925e2,0x000030c029c1eb3e}}, + {{0x00021262dc890a77,0x000605aa75a385de,0x000070b3276b7b67,0x00068f475fc1432a,0x0000429a646fe31d}, {0x0009aaa09be3dcab,0x000a5f780ed73c3a,0x000fd96c407e119a,0x0005776212562564,0x0000571495098e80}}, +}, +{/* digit=32 [{1,2,3,..,}]*([2^128]*G) */ + {{0x000561a8a914b50c,0x000f5154d376bb9f,0x0009b4c352bf7130,0x000c566800f69651,0x00009e65041168b4}, {0x0006e006d98a3316,0x00074211ce1dd070,0x000562e5f781a12f,0x0007471fff9e3d40,0x0000356cf46ec166}}, + {{0x0008d63003b40dd2,0x00025951b7ae5a74,0x0004a91b08a68240,0x0003ea41e92dd970,0x0000dfb3eb9a58cd}, {0x000af35f5094667d,0x000d4435aa2cf3c2,0x00062714fffa287d,0x000b0ed03f397974,0x0000b550f67f03e5}}, + {{0x000549dd3341d809,0x0007c1a2a0a44759,0x000164f75079e9fa,0x00018275da56c72a,0x0000313ef5b4eefc}, {0x00065b6bde130ad1,0x0007a841117ffaa3,0x00026466a4426597,0x000404a65373f7aa,0x0000a43bee63e2cf}}, + {{0x000e1b8207eecd99,0x00047c07b47c29da,0x0004292dad3f50d6,0x00075b02b4d90936,0x000019a6df48c359}, {0x000d4aab616452e4,0x000d9cfc6abb741e,0x00089b025e58689c,0x000de5eac325d9f3,0x00005ceb1e6cf255}}, + {{0x0005a9858bf21d97,0x00074beab706075d,0x00032d47700eb684,0x0001c29d714c9f82,0x0000cde2c3f270f9}, {0x000a8cee9871f0c4,0x000b59e8444aa6d0,0x0000cd43a902bc60,0x0002228651ed57ff,0x0000418cc081480d}}, + {{0x000188534a70bfed,0x0008736345c44b2b,0x000322ae9cfa421f,0x0007a02f33f4cc6f,0x0000ac0bb761dabb}, {0x0005536923cea0a8,0x0005ed9cb50c7ba3,0x000812c96c16f73e,0x00042423216dc625,0x00002945e67bd7ab}}, + {{0x000bb350b6da2b61,0x00068b65ee5504ae,0x0000a004d91fef33,0x0001f7db77b57b1a,0x0000c59b62833aef}, {0x0008c893ec88d182,0x000a6fde31f1879c,0x0004e30b652cca38,0x000cbbe2f64a94cf,0x0000b4cdbd757ff1}}, + {{0x000b7fc506f7dcd8,0x0006dd037d68f4e7,0x000c8d374985e854,0x000180ff00a4da1e,0x0000c339ae3d05b4}, {0x000d4f23a5f71c42,0x000f87ac3e9f58bc,0x00065dad12fb4d99,0x0004dc7dd25aa6ee,0x0000fd63fc2d62c3}}, +}, +{/* digit=33 [{1,2,3,..,}]*([2^132]*G) */ + {{0x000671fe43332ef5,0x000b941c2217f3e0,0x00022ba1871c5dd5,0x000b674c1d2c1fe9,0x000058e9c302619c}, {0x000cde01ec51255b,0x00015f824507204a,0x0004c6afe824b374,0x0002e362d1b9de74,0x000099616dc5b0d5}}, + {{0x000c0847f6a1cda6,0x0004e23d634ffec9,0x000bad00768839c1,0x00054ecbbb678b03,0x0000a727255a7888}, {0x000fea2ef5c72941,0x00085875e775b747,0x00061a8937485277,0x0008b1ad7b8e8baa,0x00008ff333550da9}}, + {{0x0006ca48d15f612f,0x000661a8a9100439,0x000e4801edc27609,0x000765b388a29a0d,0x00001786469e2330}, {0x000153bbefdde3b2,0x000c66b8ce1ac63e,0x000313e17ecffc16,0x000fc5ab70c46999,0x000063b28a2fa50f}}, + {{0x0009f4f5529ec802,0x000a8fd146d1851e,0x000300c2c0420274,0x000feabbf1ab668e,0x0000d0b3a9d61653}, {0x000180f23a495b9a,0x0004f415d73a8be2,0x0007ae4fc6ef3c37,0x000f5f1d3e1ec8c6,0x00005839e9d38d31}}, + {{0x000c8b9c3fb67790,0x000ca57ee680c4c8,0x000673efc54fc9c6,0x00079e99003261b7,0x000067670079b117}, {0x0001da6250891c34,0x000b9d785ab3fb15,0x0006759c64720dec,0x00008e872b351ffa,0x0000c7ad29ae4f10}}, + {{0x00014d637d77c019,0x000bd1023c876541,0x0006e1221c2e18a4,0x0008f96fa6c3d39e,0x0000a6cf4e2d10e4}, {0x0001140b181828fb,0x000a28cb78333088,0x000cd236717c6df2,0x000922c1eb8df1a7,0x000078f1c8e7a89f}}, + {{0x000bcacbd862cefb,0x000dbf8f23c2598b,0x00045228f58f4234,0x0003688bce359f81,0x0000605d0f84812c}, {0x000dddfe4018fcda,0x000f9f797960b8b4,0x0005d8257b8139dd,0x0009bf631ee83dd5,0x0000c8b3932c4571}}, + {{0x0004777d0d428874,0x00086b7a2707b25d,0x0003966fe4b48921,0x000bec1b4dbf9b2d,0x0000bac5f4881ae2}, {0x00027331733964e6,0x000fca814a6908db,0x000898348a10c5df,0x0003f484ebdaf0a9,0x00000e46824074da}}, +}, +{/* digit=34 [{1,2,3,..,}]*([2^136]*G) */ + {{0x0002d18f9066d734,0x0003e098b3bfa064,0x000b4954cbe1d2ec,0x0009bbefee860c21,0x0000d7c4e6d67b62}, {0x0001e038e8b81b09,0x000f0fe77eb03d8f,0x000247c734a80168,0x0003564d977591ce,0x0000b30c9f3157e0}}, + {{0x000ead488c06b1c4,0x000089d9d4e8273a,0x0009e86bfea8af42,0x000a56a7b4409acb,0x00009f76f719414a}, {0x000c8018c13857a2,0x0002ee7423844603,0x0006657197c26f1c,0x0000c6042fb2242a,0x0000619f2550175b}}, + {{0x000699444bb5a795,0x000cebd1fdbfb12c,0x000e49191f5928e0,0x000dd3d30b8a973c,0x00002792b8633a05}, {0x00089161d3d69c3b,0x00099d59a28c5da0,0x000a05485931759e,0x000964412148d96c,0x00001517aa0ed6e9}}, + {{0x000bcc7d9b45206a,0x000e8abc463fed6f,0x0000e37d100ab735,0x000718428c701781,0x00004365872c7af5}, {0x00058230a910146d,0x0007dff76703bf19,0x000d6f1c8c13ccdd,0x0001b459d34ad644,0x00003dfa6b3495b6}}, + {{0x0005d0a1685e4603,0x0007455d00b5d0e1,0x0005614566fae8b3,0x000c63277126d8dc,0x000031c02e59bf70}, {0x000da4e515f39b7c,0x0006566c206009b7,0x00001f926b7e0d13,0x00037e9a801457c4,0x0000c560826bfb01}}, + {{0x000ffb56487a5d42,0x00054f53e25f6874,0x0006ba8fcc02a12b,0x0005d638654a5741,0x000026356f22c0b2}, {0x000eaa66030f2ac9,0x00022cea9175a4f2,0x000912104b788baa,0x000e3d66fbe9f74e,0x000082ef71dc9a69}}, + {{0x00090f62369ce91c,0x000a1754d218b653,0x000018afb2dc3763,0x000b66bc5523697c,0x0000a835077f5bf6}, {0x0003e4361d4b0a62,0x000747cf66c541b8,0x00057cbf28f87f59,0x000fb7ace5784093,0x00004834481cbe47}}, + {{0x000c2c96fd8b3094,0x000ae055809f298e,0x00022943c512ea17,0x0003e628cb44e788,0x000034dc70a1eb7d}, {0x00024d11be76434d,0x0004082ff0b0e8b3,0x00005e7267cf24ed,0x000abcda8265fe29,0x000057b3916be6c3}}, +}, +{/* digit=35 [{1,2,3,..,}]*([2^140]*G) */ + {{0x0000095d2a819b58,0x0009c8f2f6537901,0x000afe3665291aaf,0x000e27fa533907f0,0x00008a58ed00e279}, {0x0007127fae130bc9,0x000b88a54c747f07,0x000d82b6aee9ccf1,0x00052438a6783ebe,0x0000a1acb3e7d414}}, + {{0x0003ceed9c12e2aa,0x00021fc1308f44e5,0x0002c2d0f11983fc,0x0007233eb4d84d89,0x00000bfc1cb14499}, {0x00044d90145176bf,0x00015f12e75a8083,0x000a67545bb2988e,0x000989df73ceadad,0x000037069d21bb8f}}, + {{0x00035e69cc17f65b,0x000b39d9abdff24a,0x000c09ae3c49b3e9,0x00058782f403032f,0x0000ffe7d4db02cc}, {0x000f4e6424ef7136,0x00050658f65ff511,0x0008baea2b86bf65,0x000759623388d91c,0x00000664a7193656}}, + {{0x0006198d8447e168,0x0006e62171dc9899,0x00048b8e617195d7,0x00092328cfe6a1f4,0x0000a3c28238658c}, {0x0008d899c35e852f,0x00001b3781561c54,0x0000113b6adf1cd3,0x00096f999e41aff3,0x000087515a68cf46}}, + {{0x0002c559778aa8ee,0x000bb1b8d8b18c33,0x000533883290ae3e,0x000ee23e2bfa0bbf,0x000048e3747fa523}, {0x000f1d550fde3eda,0x000be8710432ad40,0x000241f3fb57e695,0x000abca41012581b,0x00000cabf7bd042c}}, + {{0x00019c7edfea5220,0x0008a400db7b68eb,0x000f03a0868e028b,0x000e366cd97bf7a8,0x00009f4d266f442f}, {0x0007f915d713a1ff,0x00061f58ccb42ac7,0x000ddc47d356e3a3,0x00011531d657f1f8,0x0000ea7aedf80092}}, + {{0x000a1d24ad49f66a,0x000e3d40861a8aeb,0x000a225f516ff2ba,0x000f0b25464f377d,0x00002fe66ccbffc3}, {0x0004d7fac757f415,0x00021d0a2c202407,0x00074b2665c85d3d,0x00004fccda2a05c9,0x0000c2e25121c10a}}, + {{0x0002535510d515f7,0x000cb89e785591ea,0x0000d17bcc861c54,0x000c869bc8485b68,0x00001472c11f19cc}, {0x00094850e9b5d8b0,0x0008d029720da7ef,0x000f50161698c9fe,0x000bf66ce987d161,0x000035f6f329d240}}, +}, +{/* digit=36 [{1,2,3,..,}]*([2^144]*G) */ + {{0x00015879c34971bf,0x0008d76545cefe03,0x000a81bb95829eb0,0x000710b7a3a6ae33,0x0000f42db0039c9f}, {0x000ae85bffb951b7,0x00033e70f324194e,0x0008b1f12815fe3e,0x0000bd636564cb42,0x000022e00511029b}}, + {{0x000578b41aeb39f1,0x000e8dd55c1fcfc9,0x000814075eeda86f,0x00017cd4b8fc54fb,0x00002e32a7843a13}, {0x000cd2b2fd217d16,0x00013bd076388b79,0x000dc7d8b5f5f20c,0x0000e2fc57643a53,0x0000512601550835}}, + {{0x0007479d0058ffac,0x000fd80b0de5705b,0x000a0585fe459ecf,0x000fa0fbe00c088c,0x0000169e23b83dd4}, {0x000009a44026f6ee,0x0003fd96fe5785d9,0x0008ed1e0bbc258c,0x000884d7ed379c32,0x00008b4574503970}}, + {{0x00091e139bb481ab,0x000b49984155263e,0x000d8e622dcdc072,0x0000349fce6e38d2,0x0000f6978b73e8c8}, {0x000e8748c37990a9,0x00089e749b861a1a,0x000dc7c12d1f0e06,0x0002115aa303b1cb,0x0000a78bab059130}}, + {{0x0000e8c48790aacf,0x0009154ad24e5601,0x0002090b8ac7a52d,0x0007dfbca462bd2d,0x0000cd84ef5a2f8d}, {0x00055b07ec8e0744,0x0003ba9b88dbf017,0x0007e09a00e4205e,0x0009130170f7d14d,0x00007f7d48d0e9d8}}, + {{0x0000b8acc130e8b6,0x00003c6f0871db27,0x0000d3f3417f5f79,0x0000319683bd22e5,0x0000d5852afc2699}, {0x00054cd8f15058ac,0x000b74cfe9dcc3d5,0x0009479d624038de,0x00059bb19336ecc8,0x0000aa9ed55b03eb}}, + {{0x000c5c0e0b77ebf3,0x0006d45a471d41ab,0x000e535e9dc41d92,0x000a8528f162333c,0x00005db2f52ebbd0}, {0x0005bf4eaec8559f,0x000702b31f5e4c0e,0x000d337b87be9434,0x000280c2b24a8e89,0x0000564495937b34}}, + {{0x000a910b3e2087b0,0x000344a61a335eeb,0x000cd5c0fbd016dd,0x000e94ffd1f08148,0x000041c6aa02e6a8}, {0x00035c5c4ac3d913,0x0005934767a4b09c,0x00040c2b55829810,0x00089f6120e7cb10,0x00002a661efd7135}}, +}, +{/* digit=37 [{1,2,3,..,}]*([2^148]*G) */ + {{0x0006a90bd74c70ea,0x000e2af672f2ba05,0x0004e9a4844f7d00,0x000069dc25ab68ef,0x0000dd15cc49dfb1}, {0x000fd289f3033bf4,0x000c2bb8b8a771f4,0x000d2861c088a49b,0x000fb5ea485869a8,0x00006dbfdafab977}}, + {{0x000ef4002d0aaff9,0x000dfe679fe21264,0x00088bdcea678c07,0x000db8cff13be7fd,0x0000a8efe8df17ba}, {0x000a815ad5a22f46,0x00015ec398b2b388,0x0004fc2da8f82140,0x0004f385a6a565ff,0x000081f0181e58dd}}, + {{0x000b637f8ec1151c,0x000c6adc8544ee61,0x000d0985a415dd36,0x000f50ed21d17669,0x00004d062b057893}, {0x000ba1a337b81f9d,0x000f87c163a17d93,0x00016e4edb995fe9,0x0008e7447eff3b54,0x00007660300dbf4a}}, + {{0x0008fbc4e933b192,0x000d054ea9692416,0x000acbb56af2db74,0x000d1d36fade13ae,0x00009708665a4e6c}, {0x000f1e1b692df97b,0x00031ae66306bf7f,0x000685f205a68c1a,0x000eec85bc544ce7,0x00003f42e6dbf65e}}, + {{0x000bbad2a08a1dcc,0x000b3f2dba7953f6,0x00064f5a3a7131e4,0x000109751dce4878,0x00005af1b45c8135}, {0x00075f74f08636e0,0x00052e251e483c4d,0x000d988539949b2f,0x000e84d04979779b,0x00009d8e627909b0}}, + {{0x000078177ef7f672,0x00074b6340c9166d,0x0007acf63fefec94,0x000dec7ce3a05609,0x00006538c7ccf306}, {0x000b55e287dc8d19,0x000bd48823adfa8b,0x00070fc519431095,0x0009ac8358087a79,0x00005299959d1350}}, + {{0x000ef0bfb48bd3a8,0x000f4508309e0814,0x000709c101bbbe13,0x0006557ddaf06167,0x00002b67847e436f}, {0x00001c603712e641,0x00024e3f9b2e1a56,0x000184b5dac1f036,0x000149cc7e6a0909,0x0000258b265c4625}}, + {{0x000033a675b47a06,0x0004c542378f9bf7,0x0005ec248cb3669c,0x00034696abb0f712,0x0000d5d2047d95fc}, {0x000c9e88f5cffb67,0x00082ea5ee0936c6,0x0004ffd6fb968f2c,0x000ac82f2ce73584,0x0000931b87797e40}}, +}, +{/* digit=38 [{1,2,3,..,}]*([2^152]*G) */ + {{0x00015ecfe73e6993,0x000c7752648968bb,0x0001dcc6d7533abd,0x0003634b26960749,0x000025ec2a0a7187}, {0x000aa197e9ab8653,0x000af25a9448466f,0x00031b5ba1c105b4,0x0005790b6b896305,0x00002691f115db1a}}, + {{0x0005f7341690d1cd,0x0009c0edac8bdbdf,0x00038cfb00e857a7,0x0001d259f40fcf82,0x0000cb54f68211d4}, {0x0006ac80e6451179,0x000f0af5fdcbaf03,0x0007bab2cdc4e833,0x0002bd67d859b23d,0x00002489b23ef8b3}}, + {{0x00034b4c22eb7ffd,0x000bad66596a89ef,0x000b3f3e1fc26171,0x000de06ce57d2c0e,0x0000e4177dcd587b}, {0x000f7eb6ebf95ffe,0x0004ff55b87342f0,0x0000cbc46efde869,0x000190b699bdb308,0x000032804f430cd4}}, + {{0x000aaf7b9e2f9f82,0x000a2ff419acc412,0x0007bcb900484c1a,0x0008ca9d94498941,0x0000b73dbe41e731}, {0x00071e552dd7b0ad,0x000b0954afeae91b,0x0007e3958d61f8ee,0x000f49aaeab13ca0,0x0000e442032d2a1f}}, + {{0x000f06ac55c0828f,0x0001667e2247abc6,0x000c49d4d62a7430,0x000b34e42b4c8984,0x00007a8dd4742091}, {0x000b96540a8295bd,0x000c39e900eb5ffb,0x00042ae0a36db01c,0x0009ebd9b90987de,0x000051f12e4efc53}}, + {{0x000fbd4a3b4ab0fb,0x0004907bdb60d581,0x000ae79b355d3bb1,0x00024ee65507f786,0x000085fa584e36d8}, {0x0004492bc0d8c261,0x0003a9b3e8d4611d,0x0004029cfbbdbeb6,0x000bf2f201f709e4,0x00008a99397c6748}}, + {{0x00020b3838c4ab94,0x000cb736cae32a95,0x00039f308526b695,0x00017f0f8eab84d2,0x000009b53e4d08c5}, {0x0001bcad169e4b4c,0x000767a467b7d378,0x000cc9436a91f107,0x000ec70e885579f3,0x00000d1f792fe123}}, + {{0x000d96d0b054a0fb,0x000924b90779d292,0x000f1d49fa978af8,0x000ab170bd185bff,0x0000e6d0844b279e}, {0x000fe45b8ed07e9d,0x00029b920e54d8ff,0x0001bb143714824a,0x000bb7cd5c628aaf,0x0000151afce4637d}}, +}, +{/* digit=39 [{1,2,3,..,}]*([2^156]*G) */ + {{0x000bd2e5a26a1d4d,0x000ea1c2d78bd433,0x0001025151148bb1,0x0003844aae419e64,0x000003b993a36489}, {0x00058b1d61a99194,0x00068a0ef3d4a21d,0x000e8c0dd17618c3,0x000a752519020d6f,0x00008d837d640b87}}, + {{0x0003a693f11fc001,0x00019bc8eade4cfd,0x000b9f7ae1f2b5d0,0x0004635160359ba6,0x0000e2601dd0a696}, {0x000c6d2915f60844,0x0009a79176d53f5a,0x00026abee6e38778,0x000d227fb99f4bae,0x0000798a2fcea409}}, + {{0x000342d86b383b5e,0x0000506b01d4e192,0x000cdcb89e85f304,0x000e2a19e1921388,0x000088f19440ce0d}, {0x000f8cfe453aecce,0x00097a67b49f16fc,0x000ece9610dcd10b,0x000b53b93d5b4daf,0x0000232f34ba39d0}}, + {{0x000cd7c64ca2efc0,0x000b4e0bcb6c799a,0x00058a26c3397a15,0x000faab9b10ced03,0x0000a30dbbe4b8dd}, {0x0009712e20f6facb,0x0003811451aff70e,0x000eece8f87c7f73,0x000e2df0c967b1d5,0x0000c62882b5b370}}, + {{0x000ba8516a010bce,0x000bca4f3e8e09c0,0x00070a1e52fd90fb,0x0000048af1837145,0x0000869e8f85cca9}, {0x000afb72dd830199,0x000e8d99b38652c8,0x000adab87b877995,0x00091a1e3efc16f5,0x00003105fe53a3b1}}, + {{0x00065d10a020be77,0x0002666eaf8ac051,0x000d2380e4856041,0x000b115ff898ddff,0x0000da35f08e84b4}, {0x0003e2c38fd05c77,0x0002b7ada3a4e0f5,0x0008995de64b3ee8,0x000605672ae31667,0x000047074614fe96}}, + {{0x000ce8b62a0b0ed7,0x00037abbc9be00cb,0x00069c2d692f5dc3,0x0003e1bb92b7d3f3,0x00000dd90c8e9ef8}, {0x00031537937ab45e,0x0005a054af6d00b3,0x0005ebfc43a8d1f7,0x000d0c35cf7380b0,0x0000fb8dac338c2c}}, + {{0x000cb400c11e65a4,0x0002a8ff2be53722,0x0009f9352c94a7f5,0x000544420085cc8d,0x0000addb9870a4b2}, {0x000eac006264a479,0x000472b48ccbac6c,0x00094fef2ebc01a0,0x000a8ac430e7abea,0x000073bb6f14d94a}}, +}, +{/* digit=40 [{1,2,3,..,}]*([2^160]*G) */ + {{0x0004c2e24424a48f,0x000f27d4471b21cf,0x0007a488b843c73e,0x00061cb3047fc561,0x00002a9170ad3cf8}, {0x00044211c3a60f77,0x0006966791481444,0x000d9404b74787a3,0x000ef0115fbd0653,0x00000fd3365d244c}}, + {{0x0005c9b2b574b7f9,0x00065369b6bde669,0x000108dedcca8040,0x000fce1f4bae99e3,0x0000e715ce37a133}, {0x000205554c2ee1ce,0x0001f680742d80d5,0x000e438b956bab30,0x0007cea409b5f63f,0x00003a8e4d16036f}}, + {{0x000fbfea62e08420,0x000360d426c06d25,0x0003a816cf07a613,0x00059db28fe4774c,0x00007987198b8d12}, {0x00021b150044888d,0x000211a2ad57348c,0x000ba884ad0b1f74,0x000a0385be8dae4d,0x000096bc030d9802}}, + {{0x000ec0f247fdfdf5,0x00079a23d1dc91d7,0x0000fdc41fb9d90e,0x00048c7012eb2c19,0x0000c2bbff72dced}, {0x000426a68cd7febc,0x00032b4854e0ca93,0x00072bbd8b596396,0x00040a8ac72b8ee7,0x000010d24d366b30}}, + {{0x0004b14e735cafe0,0x00044e80373d66ab,0x00095617fb275399,0x000da6bc5bba23f5,0x0000802dcbf70cce}, {0x000ba1cc60401601,0x0004eb5524732bf5,0x000b1a5907e18137,0x0003b1abdeb3cad1,0x00004f0c02531750}}, + {{0x000ef1694d5f3478,0x0000ab04af0a0fdf,0x0002ca633f318949,0x00014a30e3da7a6d,0x0000d002aeac8038}, {0x000311f95a0bfe97,0x000ebb4cc50c515e,0x00034df252891ec7,0x0002890936fed888,0x0000e5d7dbfe8e00}}, + {{0x000b4ae1863c1b58,0x000c296f5659ba49,0x000c2f3cb84af9fb,0x000bbdb45c071ded,0x0000db1c01e276f7}, {0x0009a9ea84ee50fc,0x000b09145b546f3e,0x000692134508e794,0x000adc6acff4f7e9,0x00007c5a5c9155cd}}, + {{0x0002d78fbfcf1b56,0x000c48427d7459a9,0x00066e74e17ce4fa,0x0005e5bae98ffdac,0x0000d548304745bb}, {0x000c6030992abe13,0x000aeefdc5c58f3d,0x000f8efb8318cfbd,0x000ef8bb5fa37d59,0x000047874a07ef5b}}, +}, +{/* digit=41 [{1,2,3,..,}]*([2^164]*G) */ + {{0x000cb614b4558fbf,0x000c0f2545a97f5f,0x000e5e4699602597,0x0006bcfd89ab3fab,0x00001daeea3eb2e1}, {0x000acd73a12940f8,0x000ccd7c73116699,0x0006c8ec624980f6,0x0003dc4a5cf97533,0x0000e180e330c27d}}, + {{0x000ece400e25a956,0x0002dac1732def02,0x000149260ef94740,0x000d51ecdb65ac51,0x0000043aa2a09180}, {0x00092bd852deca02,0x000735237c8ce7fc,0x0004b3f38f333829,0x000f17ecfb0e76e8,0x00001f2f5c58b89a}}, + {{0x0007134ca9bf60f5,0x00000c7da3a4dc68,0x0005fb57e2473ea9,0x000adbf54ef685b4,0x000094e84458383c}, {0x000d3fb4a7df4bbd,0x0008917c2c9211ed,0x0008fcba8a783d98,0x000e4c0d498637cf,0x0000ebd801e0acd6}}, + {{0x000aa5c7fd181e78,0x00004a3ad1eb08ab,0x00094aab5136a0ca,0x0004a5e6e5e6c2f3,0x00004d697d51349e}, {0x000578bf76f4b3be,0x0006f2feeb5ea215,0x000876bc381a1cec,0x0002ca5d336eb73e,0x00008afdcb5e7189}}, + {{0x000bc8cc051e9f61,0x000f5be2d9ca608a,0x000ab534875194e9,0x000490031d69c1d6,0x0000785990e88b0e}, {0x000f125f6c41f8ea,0x000aafbf2fe63825,0x00087161e429924e,0x00015353c044befb,0x00003bbdf1ba651d}}, + {{0x0002085894f7f160,0x0002b5c353fb791b,0x0008db0d442eb80f,0x000ef2377777f7df,0x000023c096334c42}, {0x000eb5ea34cb6d01,0x000e65cd1242aa05,0x000cd9f24ffb8b01,0x0009fceab6ff7d87,0x000075e94c9bb3c0}}, + {{0x00067251454f76ed,0x0005125c87a8a389,0x000efb7d652772de,0x000c11e59e4516c6,0x0000ddb8bf4a76bb}, {0x000ebd9c6fd2066d,0x0005ed7082e94acb,0x00069cea388c3b52,0x0004056a3b3d626d,0x0000bf73dfb5d065}}, + {{0x0002f06978f92cc2,0x0003431967527579,0x000cfcac1b11574d,0x000f67c3249711b8,0x0000061c767ef93a}, {0x0009a1b2f63dbe7c,0x000708091edd2ff0,0x000bba5a9527776b,0x000221f0fa985e19,0x000054f89f426ae3}}, +}, +{/* digit=42 [{1,2,3,..,}]*([2^168]*G) */ + {{0x00062846a436476c,0x0003f5dbb9cafc5a,0x00012ffbf6fcc231,0x000d14a77d2d9f50,0x0000c25e9f50ae4b}, {0x000cfc41a5e40c6e,0x0000df085321f17f,0x0003077c47d716a6,0x000e619dcbc50bee,0x0000bfe953dbb4a6}}, + {{0x0006f2fd3d777d71,0x0004df1a6b09d7e6,0x000f88dcf3519dc6,0x0001050df07bebdb,0x00007b09654bcd4e}, {0x000acd04e70c7833,0x0007c6b9d5779bd7,0x000e52f8ada66e74,0x000c1b6d0488a1e3,0x0000ec0fd119ff71}}, + {{0x0004cb6be4f27824,0x000b81c2c0cd3547,0x00065e29c10ef5e6,0x000608592c6b066a,0x0000d424663112d0}, {0x0000949b1a714fe2,0x000c3199f802d528,0x000a4ff3a52697bc,0x0009cec68ba4f8e6,0x00005a5380f55184}}, + {{0x0007f69573ec6f50,0x000e67bd2e8b3320,0x000fe24207ecc4bb,0x000cdda07acd348f,0x0000a957eb8a13f9}, {0x000f95b9ec9c0c55,0x000cba8578ccbbc7,0x00061923cd82147c,0x000f2507a2e7c59e,0x000091eb06682e83}}, + {{0x0001588957c94fa4,0x0007764911fb6aa6,0x000907b196a2bc70,0x000cc409771450c4,0x0000cc48773d694c}, {0x000216e50c878ace,0x000d4f3031f0bdb6,0x000d0d41e6e89210,0x000751b711dcbfce,0x000039bfe3eefbf9}}, + {{0x0007a45764636b5e,0x0007975d48f238fd,0x000a80177e437ee8,0x0000eae323bb1860,0x0000dc3c8f49c94c}, {0x0001164ec8cb0cf4,0x00096472936d9835,0x000059756ccdd882,0x00084aa8db1b8558,0x0000eda8cf9155c1}}, + {{0x000727d2923b8cb6,0x000d46773d5e7fb5,0x0006411656e793e5,0x0000958ecc901ba0,0x0000077ab2736da5}, {0x0009b0c6b127d9d4,0x0001163e2e1ec066,0x00041b6a28140e4e,0x0007b01ad5b03c96,0x00004299f88dbaed}}, + {{0x000296d1ea4a0569,0x000d677811b98736,0x0002dd74b6f74702,0x0004ab5c92754843,0x0000cc7327277a19}, {0x0005eded6328dca6,0x000988db755daf03,0x000192a4a5292aa3,0x00095cb5488385a0,0x0000e7d2fa93fc68}}, +}, +{/* digit=43 [{1,2,3,..,}]*([2^172]*G) */ + {{0x0002e2a0133903ba,0x00038495ee31871b,0x000991f285b3686f,0x000b8a89bcc9740c,0x0000dd20cced4f93}, {0x0001768680b65b66,0x00090ad41c3fff5a,0x000fb42690c453ab,0x000929d479630fa7,0x00000039d01b2c4e}}, + {{0x0008134bce59c0f4,0x000d159f7f86ae6e,0x0002834573d068b4,0x000bf0afa2753c96,0x000053fe33c5aedc}, {0x00094c8483c0b1ac,0x00041c2ad1edb812,0x000383e0b9e6f513,0x0001422a77b6ce69,0x0000b5a83acba9f0}}, + {{0x0003a2c72aa1c89b,0x000eda4d513df328,0x000d5ea181969613,0x0005fe0d4c0347dd,0x0000bad9ce4f3cee}, {0x00050a857313b49f,0x000def09bf30f8c0,0x0000395cb3b91c3c,0x000befe6e5ab6d61,0x0000c36cde1ceb31}}, + {{0x0005b26c3d8ed981,0x000aaa66a6e50991,0x000dab6a3f451e57,0x000ebb2984360730,0x0000710267c4d1a1}, {0x000cfd4e11d88c05,0x000761ce026a7e4e,0x0001227de12fc278,0x000dae9801cecd69,0x000017a92f3c6ce6}}, + {{0x000cdebb47b16903,0x00003a3866812439,0x00031334f0593b0e,0x000b1e46074e6e4b,0x0000e26a9771cf7c}, {0x000122b7e2ad0ee3,0x000b8e1b1a8ab475,0x0004832eadccc365,0x0004afe9dfaa7c6c,0x000071d9e4ff6790}}, + {{0x000c219e2b4f275e,0x000726d34c98a0c0,0x000d9305c8f7b63c,0x000ad6bdc5d00f11,0x0000fd56e73fd1d4}, {0x0003f94904a1f2ca,0x000a28430c3b8940,0x0000badcc559b8f5,0x000d737be89d20c3,0x0000c788b568b970}}, + {{0x000b800d37be97f4,0x000ccd54501eddee,0x0001ba27f575aed8,0x0006ea907f9efe29,0x0000430900142b1e}, {0x000e3526fcec9dcf,0x0004f01459aea95f,0x00067f611a37d324,0x00039d4ec59125d7,0x0000df685f85fe02}}, + {{0x0000fdf648c48e5b,0x00074f45a432d21b,0x000572855689e6d5,0x000547a5a9dca82e,0x00000f07eb83adfb}, {0x000b166552c8d550,0x0008ce85417148ec,0x000ee9bc0fe3fc26,0x000c80323af5ebee,0x0000666a2a341ae1}}, +}, +{/* digit=44 [{1,2,3,..,}]*([2^176]*G) */ + {{0x00020bc9ff262fb8,0x000e5075868b206d,0x0003fd973cba032f,0x000e027037602694,0x00001c57cbb635c5}, {0x000e700ba871f1bd,0x00053b265f564964,0x000950259f03a8c0,0x000a8bc8ebc9120b,0x00002b0ee317d32c}}, + {{0x000f1ffdeec441ea,0x000c701b21568c88,0x00045cf5cab52096,0x000caa37eee2756c,0x0000070d24ea520e}, {0x0005bd1546b9fd3e,0x00050c96db1b81d1,0x0005b29b73276fb7,0x000254c5c1b041b9,0x000018008dc9d7d3}}, + {{0x000a71dd360d017e,0x000609b0ed7245f5,0x00025a0184c0779b,0x000dd0c662fedc98,0x0000ee8912641d4a}, {0x000814d92163d14f,0x000017370d3b2543,0x000e1af7a79f2377,0x0001f7f80c6963cb,0x00002d521bddb9e4}}, + {{0x0000bf0ae309a0a5,0x0008875b8fbc68eb,0x0004993b7a9f52f5,0x000292b8e4f9481a,0x00000ce578edf73c}, {0x000a4a602e503d65,0x000134c68ea2d437,0x00016f34820cdfc5,0x0000dffec5993b36,0x0000d96b4c610c42}}, + {{0x000e136d3399e1e7,0x00016e2f8b74ee5d,0x00077db29e38bab0,0x00021e736126de3a,0x0000b0d186662aa1}, {0x000e45edecf9cde0,0x000e2318be705545,0x00055b0e59608ebc,0x000ca0e6596006fa,0x0000c8c2f41bc4b6}}, + {{0x000a7d03b64dcd73,0x000c858c9d559fb0,0x000fbc656f4c2f1f,0x000bea110c2db2a0,0x0000cad85cb1f5b6}, {0x000dd0e4e0b12301,0x0007198a2fcd6099,0x0001e7407c769b93,0x000b479209f5501e,0x0000b47255d2ba7c}}, + {{0x0005aa5d562b5f1e,0x000b15dac657dc80,0x000c28e5a7101b9d,0x000d0a5b7f211ddd,0x0000a89f24db3d1c}, {0x0009ef57567c80db,0x000e4a60c5ee0aaa,0x00036cd64e0d1f26,0x000de6c88a044cab,0x00008e03d02cb125}}, + {{0x000699827c7e6ebc,0x00032625bc7e8926,0x000c9cb1584ffa37,0x00084eedec924705,0x0000fad0b914075b}, {0x000d316bc0898d3a,0x000cb1f92524f4be,0x0007e59d702481ee,0x00012919896e1b0d,0x000006adb6d92bb3}}, +}, +{/* digit=45 [{1,2,3,..,}]*([2^180]*G) */ + {{0x0006950fe94629d0,0x00059f860b15c35f,0x0004f8f151cbaa93,0x00045829b4bcd3f2,0x0000ae5b06ad29c8}, {0x000c31d1b6c2df19,0x00016804facc1645,0x0002b33e6640b099,0x0008287a4a7f5912,0x00004bb0b2c0479b}}, + {{0x000aed34397ee7ca,0x000cd6fbc7fe5460,0x000b03dfef249e4c,0x0009f3c42d9da8aa,0x00003d73ce3e35ab}, {0x000dbc33813a3f3c,0x000b779c32a2c6dd,0x0008a2c3f86d5779,0x0002bf7c3d9aff02,0x0000687e71c71add}}, + {{0x000b3d6ce2a7da5c,0x000c86d365094a23,0x0009d79cd7efbfc9,0x000529dddc5f43e4,0x0000642b12101334}, {0x00052b60eb07da3b,0x00084623cceb073d,0x000ccb9c3e0c9a6e,0x00040e65e4f274a8,0x0000c6dacba8214d}}, + {{0x000a56209b3fed36,0x000a95799669e612,0x000960971f296c17,0x000a05a124a36f07,0x0000d03b214980c4}, {0x00046e270f1f268a,0x00003341aea42b07,0x0002f59cccc9b480,0x00015d1b3662d56d,0x00006c65b2e74b1a}}, + {{0x0006d5faba617ca5,0x000b0788f1e74ce6,0x000bd2024f5bb17d,0x000aae03ea09fdff,0x000053dd7097abd4}, {0x000458bc19c4561c,0x000dcb2676dc42c1,0x00074f7de4ecc53b,0x00051b1614610252,0x0000f5fa738c9ebc}}, + {{0x0000f5608a104d47,0x000f2317079a22df,0x00031eaa8fa16cf8,0x000c540425bed530,0x0000f7c45cba44f3}, {0x0004e5f9db182a9f,0x000f49f23a6d6157,0x000b6efa6cae923f,0x0005174b19b78d03,0x0000fa74d30af8c3}}, + {{0x0000568ac0e00ce2,0x000821c05e349afb,0x000a524f0ff4bc59,0x000539a94e0be1f6,0x0000995e87848303}, {0x000f99cde02dc40a,0x00037e00fcad06cb,0x00030a510be18069,0x0007327a71994d91,0x000072b5007a9e07}}, + {{0x000113acccb0a4b8,0x000ab615f016796c,0x000ad2f5b24c26bb,0x000abb52fe115aee,0x00005623d268d7aa}, {0x0001fd031a2564fc,0x000e8d0d59a39079,0x0008b74663659974,0x0007b02cffdb747a,0x0000f6b36e611478}}, +}, +{/* digit=46 [{1,2,3,..,}]*([2^184]*G) */ + {{0x000aa41b6223f04a,0x000f241c3faaed9d,0x0000b42cf803c9c0,0x00019360eee3f9c5,0x0000f4a7a5b17298}, {0x000c2e1bf809ad69,0x0002867c0ff24379,0x000f8e637903ab4b,0x000363c779d7ed90,0x000068b0cc0bcf3d}}, + {{0x000871cb79f82af7,0x00029dab52f5f4ca,0x0008239a731304b0,0x0007361825ab5492,0x000040413b2fe4ad}, {0x000d3fa44071d191,0x00014f0b2da8b5c5,0x0000a198183e438f,0x000ae3fd759448c7,0x00003e0c7ee665eb}}, + {{0x000eaba5568f2420,0x000b029afc1f58f4,0x0004d7dfc83b0c37,0x00053293de2d2799,0x0000d9a6edbb1679}, {0x000427995f085b0f,0x00099299355e4b83,0x0004427f846ebac9,0x000d0e0212e48904,0x00009e4ce3592f37}}, + {{0x000d314ef7750f08,0x0005a2da84d6834d,0x0000d647b2ceaa70,0x0001574561a254fc,0x00001cf09163be01}, {0x0003d4e34b798ebd,0x00065b1c7543847a,0x000194168bb5dd62,0x00010b94fee01bc8,0x0000b4c2600caeb0}}, + {{0x0006baf530c98b7b,0x000c0acf023af1b3,0x000de150304503d7,0x00089f96bc444921,0x0000b8a123082a9c}, {0x00099dfd5d4b133f,0x000cb97d3e5176df,0x000b318d61bb4a13,0x00052edab370f379,0x0000a6c823f8f185}}, + {{0x000b22514fb96241,0x0008da4229d70f09,0x000dc8c192eba4ff,0x00053e5b159dd121,0x0000e1f968fc1aa5}, {0x0005976c7674d527,0x000ceb283500fea2,0x0009468c298e73ad,0x000a627cfce0e1d3,0x0000aad0af978438}}, + {{0x00009f62eb1db212,0x0005b2c3e3e183cd,0x000a43da5be37048,0x00025eeb51fa296a,0x0000c7fa809f7266}, {0x000786ff0ec0e998,0x000388135cbf10c6,0x00004751bd315af3,0x00081ac1b6017215,0x00008674e2d8e287}}, + {{0x0000f771e33b2a39,0x00002f78986f8fee,0x000f05b7ed4bed82,0x00062a6396feea6e,0x0000c5d6a01b640b}, {0x000fec96834bea4e,0x0009c131fec9370c,0x000affb4d68d1672,0x0002564be9c5d600,0x000034a423d79a6f}}, +}, +{/* digit=47 [{1,2,3,..,}]*([2^188]*G) */ + {{0x0002874d8247f131,0x0001f3c11f564dfc,0x000503b97c211a7a,0x000c827512563fa2,0x000024cd9846c007}, {0x000b682491cd2498,0x00042683359ccf6e,0x000302b62af4f70a,0x000f562f1dfe71cc,0x00003c474bc657fb}}, + {{0x0007ab7916a8016d,0x0000232bfb9b73af,0x000174971f93d488,0x0004d4a5f9af3ce2,0x00001b9cf1ffd59b}, {0x000941844f4eb91b,0x000d7226edc49a77,0x000d4bb336a131fa,0x0001fe472ab89780,0x000069687a5df6ca}}, + {{0x000cc72520cd267f,0x000403d37ceb7c99,0x000c45cd39b83c2d,0x0001efc2b56ed68c,0x000061a49ae9d3ff}, {0x0006205a05677aaa,0x0009311b22bc4589,0x000beaef3c87845d,0x00092199ef1336bf,0x0000542906a3b1a9}}, + {{0x0003ca2fabd066a0,0x0008f9c78bfdffa7,0x00055cfef494e03a,0x000784e585a878ff,0x00000770b1fd7053}, {0x000da4a056fe70b0,0x000857bd444fdec4,0x0005df668e37395d,0x000583666250d468,0x0000549569ebe6cc}}, + {{0x000aac0ba9b5ca4d,0x000c4512a151524a,0x0000680f2f556fea,0x00041a6cff93f359,0x000033c25c629212}, {0x0007a1300ee2808d,0x0001896afc72b53f,0x000f030ead83e2c6,0x000f23a0abf470ea,0x00006c675098a456}}, + {{0x0009830ab11639e9,0x000b34488d52f762,0x000f06eb6869dd3b,0x000c3710fe1c0bba,0x00009034839a687a}, {0x00083777f1ffe7b3,0x000c55bd7c570841,0x00008ba673334a74,0x00012dc57cb7ed70,0x000084c12d0f1e4e}}, + {{0x0008690fb57459b5,0x00067b878006d66e,0x0007ea63d14bee76,0x0002bc9b5267dd2c,0x0000e8f2a4c53e01}, {0x000c64aca5e07275,0x00053875bdcccc3f,0x0006194383dd2f10,0x000d012a09337b76,0x00005415071fe1e9}}, + {{0x000dca6db4bdb35e,0x000d54d913a7148c,0x000ed94d56bc23ae,0x0009e78f0ccd9d12,0x00004aabd1366db0}, {0x000f31a1e9483261,0x000c27a479a1fcbf,0x0007686f1cf68c47,0x0006693cced8e2ca,0x00005ed1e995eb62}}, +}, +{/* digit=48 [{1,2,3,..,}]*([2^192]*G) */ + {{0x00092a4202bde39d,0x00050d6bab982b39,0x0007125122549f56,0x000e500b56464287,0x000052442b54fde7}, {0x000fd08a3d3e16e7,0x000b383b29bd36ce,0x0006dec8c5b194f0,0x000c1e6db0edd890,0x0000a09095972570}}, + {{0x00095d0eb10175e2,0x000aed236aa11106,0x000dfff4079aaa6e,0x000063f78539ff3e,0x0000369c51722cd6}, {0x0003ae55c8631ff6,0x0002816a60bd21e4,0x00061a5f9065e821,0x0006fa225cb473e7,0x000095ef8610b6de}}, + {{0x000e6c9f60ee3e5a,0x00004236377f06b9,0x000a4af71b397af8,0x0009fbb7a318ac7d,0x0000e64b613aa9d3}, {0x0006c74902b34119,0x0000ea199e52d6ce,0x0000fb76fea256a7,0x000f9c8dcddd8955,0x0000443b47793e70}}, + {{0x000fe2d952980037,0x00011d8412fbc96c,0x000997dd3caa6655,0x000587f41d021583,0x0000066e356b5534}, {0x0005c3e5b6de0d7f,0x0001becd5f251d5b,0x00052ae508ead45d,0x0000bfe2f24e2cd2,0x000071e5d5071515}}, + {{0x0004735e1d88c25d,0x00026bd66b66d27a,0x000af9942339905e,0x00083ca9bfa0ed62,0x000094dd9e0fe2cb}, {0x0008fdaab28e268b,0x000c01a97517779d,0x00091f33ef28ab69,0x000d64ce9bd2ea96,0x00009e8b2ff24be3}}, + {{0x000c0908b9f8e8c0,0x000024e94ce19274,0x0000f3ec1a375761,0x00026f8f2b1f2c4f,0x00002e53bb23938d}, {0x000da2c701e5ae8c,0x000b6271dcc9d0a3,0x000fb237260c2eac,0x00008ac9c08e3931,0x0000aa3245f78389}}, + {{0x000f3382b02578ba,0x000f04b2c6071100,0x0001611794716339,0x0002a092c923ae5b,0x0000da2e4daadf44}, {0x00090c547f854740,0x0009824e31954d4b,0x00078a0d4a378bf7,0x0009e24469339d24,0x0000972e7880c1e6}}, + {{0x000585b36a1f3a8d,0x0000613ba5f1a9d0,0x0005acf11a3d8f18,0x000e791eaee5d622,0x00004dfd0a2dd32d}, {0x000324b6b3ceff30,0x000cab4478700cec,0x000c759ac3acc6de,0x000938abbf7e6db9,0x0000d5c1f47a5196}}, +}, +{/* digit=49 [{1,2,3,..,}]*([2^196]*G) */ + {{0x000215745e7ea912,0x000dccadfc40581a,0x0002cd3934da3f86,0x0000fcc81d6c7d16,0x0000c38a2a1cd6e6}, {0x00025d6f753479d6,0x000f1dec6024f75b,0x0002d5547c914e08,0x000969f81cea3449,0x0000bbb8bb25b1b6}}, + {{0x000082c1279504c1,0x00023c92ffb70ee8,0x00081c7e2a466abb,0x00033a4118b26a3e,0x0000a76cc510c60e}, {0x0008bc25736d7aeb,0x00096d1ef9928499,0x000bf252520b3955,0x000626d669e2ae5f,0x0000f956ec6b1cc7}}, + {{0x0007029b0ccbaa5e,0x0003079b78a5ee81,0x000f45d8957ef5bd,0x000fd3c92837474d,0x000086b91a90ec4b}, {0x0004c6dfe5659152,0x00069c58a042c5ab,0x00001c4bce657471,0x00013ae141deda63,0x0000f95d561a0845}}, + {{0x0004508eecede3d7,0x0005a86440d06c42,0x000de0d7711889b3,0x0004477b229f9398,0x00003fced8aa00a7}, {0x0001c79e31c8f881,0x000dcb277e4fe75e,0x00087c02c8db20bd,0x000c1a8ded0a702b,0x000066281b55d164}}, + {{0x00056cfeedd8e0c9,0x0000744c012af873,0x000aa3eb68afab38,0x000a570795935fe4,0x0000b9efc0d6a6df}, {0x000f8aaa8ab0840e,0x0004a85616042ff0,0x000db93150f3a4b6,0x0009f82ca911efd5,0x0000f70e5bba8ded}}, + {{0x0009209a6aae58bb,0x0008d74edda2943d,0x000be3c9a3d0798e,0x0002dc5c2d462cc2,0x00005488239f3988}, {0x000bb41977d4de44,0x00005e8245c42391,0x000093dc27fd9104,0x000e121a6d3c713b,0x000023a4e3abb22f}}, + {{0x0006f403a9a04a3f,0x0006197d9afef315,0x000a898509b32c4e,0x0000827e0b401e62,0x0000fbf542f984ef}, {0x000c0e0f990caf53,0x00041c88ea9b077c,0x000f96a510270434,0x000c47846fd46c63,0x00007f5cec019855}}, + {{0x0000bd8e6ad29dc4,0x0000aa04da287d14,0x000e05b337dca4b1,0x000acfa84feafcad,0x00004d031f8b630a}, {0x0002fa6cdee269c2,0x000ba697a40af8af,0x000e5f8261e40571,0x000fe6f71d44adf0,0x0000a47ddf9c434c}}, +}, +{/* digit=50 [{1,2,3,..,}]*([2^200]*G) */ + {{0x00092d346410cb1f,0x0002f3a5a1354b38,0x000de068d72097f2,0x000890db3a1b8098,0x0000b7438e53b1a3}, {0x000d5ea3839d3d99,0x000e84bd8125fa10,0x000800261d9ad034,0x000c5207d108efd4,0x000078d98bb2c5d6}}, + {{0x0002d017375f2deb,0x00093aa152399f94,0x0007e5c4c968a760,0x00040e55dc7da637,0x000075fff53d82b5}, {0x0005c15fd4b69512,0x0007104ddfaedee3,0x0007c87146d1d64f,0x0006fd320f1769af,0x0000b5f86a4682ba}}, + {{0x0001f3bdd857b31a,0x000b69513734201e,0x0009327b892c2263,0x000164562652d558,0x00008edd06636a1c}, {0x0008f9879f8df8df,0x000230847ddd3cbf,0x0007c06223d5cf77,0x000f2a69b08ee459,0x0000ff18c4e7a868}}, + {{0x000d7a99107901be,0x000f8211d1153c6f,0x0001b78a85dc4a41,0x000b6a597e94e7af,0x000072da34e33afc}, {0x0004db774512c248,0x000a32811e913c36,0x0000469b1c26a8fb,0x000535fdd39d7f29,0x00004515392a0612}}, + {{0x000606a4a98f93dc,0x000eb3475d7197ef,0x000e3f8cf41b9190,0x000a4f7ec792db91,0x0000a37ec10e2396}, {0x000c219d0879e176,0x00044ac57d3f90b9,0x000037ea761303af,0x0001ec13293c3be1,0x00001557e050058f}}, + {{0x0007cd15c5d384fe,0x0000d74de832cb99,0x000fb7ce336884af,0x000ef76be21274d8,0x00000bb298f86608}, {0x0001a0cd53bd4269,0x0000feb3293b527c,0x0006fc1ac78035a2,0x000fed0d7689eb2a,0x0000a38274adf2c4}}, + {{0x0001c4eccf60d0bb,0x0004bcab95d81e7f,0x00025a060c7918e1,0x000f357af4761e14,0x0000fa0bf6fa8e80}, {0x000629801e11b3e0,0x0008d92d8a4f88e7,0x0004a9e6f4b7ca48,0x000b1f247db98bcf,0x00008745cd1c9705}}, + {{0x00096a01539cf31c,0x000acded7c6dbfe9,0x00016f6144a3f729,0x00016386f1f29930,0x00003d44e1946cb9}, {0x0004531558fa36c2,0x0005569c89d67698,0x000ee923f58e8bf0,0x000fbc287da114f9,0x0000032e9850c271}}, +}, +{/* digit=51 [{1,2,3,..,}]*([2^204]*G) */ + {{0x000579dd39207ad8,0x00058b1fe91611b8,0x0009e01bf6f62c72,0x0008430f1599acd8,0x0000d9bb86dcd1e5}, {0x00090d4726e38d1e,0x000b32a8c6b8548b,0x000d2f6f4b824a1c,0x00012e984d9309b1,0x0000fa485b8231ec}}, + {{0x000560776ac19252,0x000b5442fc587972,0x000311e74086449d,0x0005618dbab9202e,0x00009dee69b9ea25}, {0x000b6ee19a7cd6c0,0x000c0d0dd5a05a62,0x0006d0ff1ba38cc4,0x000dae779279e516,0x0000eef53ccf48b3}}, + {{0x00078408c7c6d897,0x0008b2c2555f255b,0x0009c3165bfa78bc,0x0001bc8c56ae3da6,0x00002b20e73533bb}, {0x00070b4d1aa6416e,0x000c5db03cdc8868,0x000a0fd40f000040,0x000f1fd25b16a9b0,0x0000b89e93316815}}, + {{0x000393579f34a8a7,0x000fa0046434c9b4,0x00005fdb161acf55,0x0007fff0a23fe63f,0x0000d6baee17c4fa}, {0x00062b6e2daf735f,0x00091948637a353f,0x0004e6206e370ead,0x000ad3da57c16ad8,0x000019ffe09fdd22}}, + {{0x000ed1e4263a5660,0x00041d5e8f55fe64,0x00094342c735bbee,0x0009359ac6191582,0x0000f522e5ad4904}, {0x00083b57c1e11f47,0x000060c237f3bee8,0x0009550860a2ce31,0x0002dbf4a7157b8d,0x0000ec0462e722dc}}, + {{0x000a5c739620daa9,0x000fff7c078f1e65,0x000177db88ef6f93,0x000535b06d52bcb0,0x000015cdd08f8fdf}, {0x000d150c51832222,0x000d9817a2ade070,0x000194f0b2b6495c,0x000dfb3ce476140b,0x0000eec6acf713bf}}, + {{0x000814fd7daf836b,0x0007bd6169217cd2,0x000066012877b72b,0x00059dea73ca1bdb,0x0000e336c7c60d41}, {0x000b07f0f8fcd765,0x000ada5935626993,0x00091ec195fdceab,0x0003c0716595fbf6,0x00001a77f61de68e}}, + {{0x00045a51d63aa7f7,0x000623b32da2680f,0x0007088588d5eba7,0x000c610ef233dfa4,0x00004c3f4f7c2161}, {0x000fe6be6420de40,0x000197dd86d5fa9b,0x000ce233b96c0c50,0x000d6328e6827bcf,0x000035cc9a958e74}}, +}, +{/* digit=52 [{1,2,3,..,}]*([2^208]*G) */ + {{0x000997917a86e187,0x00022e029110b2de,0x000cc5a17e2ac232,0x0003cfbfd3439735,0x0000a93461fc25e1}, {0x000542c5122d6f14,0x000ec33982c79433,0x000c24d2741d2d9d,0x000d58e9f1f29a8e,0x0000ae251f433b99}}, + {{0x000a46047920742a,0x0000545f94cba02d,0x000608dd4b142d6f,0x0004b5c2d613e876,0x00002c06cddfd75d}, {0x0001bc53c564ff4a,0x000c4d1d5ecd0195,0x0002135ade60f126,0x000695a634e76570,0x00005a56a6f2df44}}, + {{0x000482697e839b67,0x000b3f49adaf9986,0x000795531cfdae67,0x000aa4f713da0fb3,0x0000b2f6f6d8d391}, {0x000b8c351b5e7aa9,0x000244f29191734a,0x000692f40fc4a912,0x0008ba8f8e2cdc12,0x0000b0bee740f405}}, + {{0x0008c7a9e2207b45,0x000147ee9f61d34b,0x0008e21b61f724f3,0x0006aefa908ca2c5,0x00005587744f7429}, {0x000913002911ae14,0x0003dd3af02e3dbe,0x0003955a1c207543,0x000d66505b724b0f,0x000080e1a930aece}}, + {{0x000246ba01d1d691,0x00061c28f15519cf,0x000dcd8cb66c23cf,0x0000f0441e71089f,0x0000c22323a9398c}, {0x000ea418a3f400f7,0x00008b3a0959e3ad,0x0003b53b4787d2e1,0x000436e7464f0fbf,0x0000e7cda2bec46e}}, + {{0x000f0871be603736,0x00064f9180e995fe,0x00060416e4dd25ba,0x0005530d3996f9ef,0x00002be886c4b749}, {0x000c5fbb48089d39,0x000e6a2b6d24c533,0x000c20f7f06c8690,0x000dbfdf149e4e00,0x00000f3d7e0794a9}}, + {{0x00015dcfc8176c4d,0x000d68bad0d95505,0x000ec582805f29f5,0x00027312d25fc5ef,0x00002f5fa1bfdd52}, {0x00071e3717366b82,0x0002d2d99b2a09d8,0x0005ed437bda0f49,0x0001592abda54f23,0x0000449feb33935c}}, + {{0x0006128446d9f664,0x00050354b5a1720f,0x000558aacd6e06b1,0x0008fda72d287d63,0x0000819be29ee68a}, {0x000c324205fbdf26,0x0007810927f95024,0x000658f802fca94e,0x00004674798be7be,0x000018e07f24f07c}}, +}, +{/* digit=53 [{1,2,3,..,}]*([2^212]*G) */ + {{0x000a94654b01bbca,0x000da55d4820b47b,0x000575f207c56c36,0x000cf48e93362005,0x0000ec65be9da621}, {0x00096df462879372,0x0003933c67e7620b,0x000cf3e0535cea88,0x00077330366a3a58,0x0000580d5654da39}}, + {{0x00061815832cd6cf,0x0008885e90b9553b,0x00014f686c002e33,0x000d454b33afde64,0x00009ab29ea7511f}, {0x00009726fb9a688c,0x000d3202a1b2467f,0x000a881ab7db6e14,0x0006600c15b6e973,0x00008c324e1bad10}}, + {{0x000d412c9489dcb4,0x0005512d084ba43e,0x0004c7cd2cec053a,0x0007f70fd4fe4266,0x00008ee06f4c2a91}, {0x000197083cd65f5f,0x00094569c42ed5de,0x0008761103a17657,0x000bc4f24508f34f,0x0000350374bfa415}}, + {{0x000108255ade88b5,0x00019b212e84bc89,0x0001362fa0525b50,0x000cac9ede010bb6,0x00002f3d088d81ee}, {0x0007b6ebc6f0ae45,0x00036659701cf995,0x000b76f4525fe726,0x000d4241e9b7f507,0x0000f2ad6650da77}}, + {{0x000518c9bb777fc6,0x0001e24151875571,0x00020284bf369c39,0x0001cc2d7c5dd927,0x0000feab634aeec4}, {0x000d5db24ecd0bef,0x0007f03387353522,0x0001452791fca0d9,0x0009257441610520,0x00004492e1ef496e}}, + {{0x000dac0d193a5260,0x0009e2b2d54f3c44,0x000c67d11d071709,0x000ad865624fb4c4,0x00004aa7033bcced}, {0x0002fac31470c527,0x000aa3b05d539c52,0x000565e5708eb33c,0x000370940e0693b4,0x0000e2fd553ebe56}}, + {{0x000f5d0be4d36ec2,0x000348e952fe8568,0x000ad6b241e9e539,0x000de9768113f9ea,0x0000bc798fcc8fbe}, {0x0007f9baaa9010de,0x000b561834c94c78,0x0002c25d832cbc77,0x0006dd449e55f703,0x0000824a5c0aa621}}, + {{0x000065a848bdc535,0x0004578554dcb366,0x000ff3b4dba2af07,0x000cbb3c755fba19,0x0000ea9337285a22}, {0x000fe021eb3e23bb,0x000b265dede35e55,0x000f445da2626ecc,0x000578187bf09481,0x0000a0110184df30}}, +}, +{/* digit=54 [{1,2,3,..,}]*([2^216]*G) */ + {{0x000ee9a1baea5745,0x000853ae5167cae4,0x0006911240d922f2,0x0007c407df28fdca,0x0000aad2f31ddd45}, {0x000f443137384cac,0x000b2620ea8c20d4,0x00067797ad93d424,0x0005bc21d544d350,0x00008a8cc9a5d8a1}}, + {{0x0000e26941d80a3b,0x000a5d36514db10f,0x000f226013092787,0x0000f6aa2dfd4898,0x0000c5b31b838c8b}, {0x0001f376c841cc81,0x00096a412b84a128,0x0008f210ddae1671,0x0009019ec1f6c882,0x0000935d576f8d92}}, + {{0x0009be8f731e66e3,0x000ff7c9ac6742c8,0x0007788475c65a3b,0x0005a7621746f622,0x0000e38982159449}, {0x0004aab948c94967,0x0008741e79476b0c,0x0005283abdfdec51,0x000bc091420e3a60,0x000099ec46fa4c7d}}, + {{0x0007921af3840f27,0x00034f3fcdfbd724,0x0003961bd348325d,0x000c29ef578508c4,0x0000d5e8ccd8bd98}, {0x000ba10f8a30164d,0x00004cb8c65289cd,0x000056ef40757409,0x000d1bcd7ed73fc3,0x000028e7cc2cb99c}}, + {{0x000c0f95182958d0,0x00075749c24bf1b7,0x000638c77ee0c407,0x000cee32f35fcff3,0x0000a46c52952773}, {0x000d4f7e2fb9042e,0x000a32ce916d9ae3,0x000bf7ae89855249,0x0002b7e48a640b04,0x00003eb60417c9cb}}, + {{0x00074946bb62286f,0x0007d7d87466b8a6,0x00073b6d58d6ef81,0x00001b3529f938f6,0x00005c0ee777bbf1}, {0x000ed6149fdc9493,0x000eff405ee00768,0x00018e51a53b6999,0x000bd7bf0108a017,0x00008e609ec8181e}}, + {{0x00079083a6a2a006,0x0007ee549a6dc288,0x0005facfa82df7fb,0x000de38f1d62b44e,0x00005566a01600ca}, {0x000bcf5b76201357,0x000ddb75df8e1672,0x0002fd615cf00849,0x000a8a8f5d3e0fe1,0x0000fb3f7894f727}}, + {{0x0001640d85951597,0x0006c79a38761205,0x00098a67c30e1c70,0x000d27091154c602,0x00006d9a9c9c1132}, {0x000e8b75c661a4d6,0x00068a6dcbaf841d,0x00014e045f24b5e9,0x000c701ed4cb0cd7,0x000005926a46c187}}, +}, +{/* digit=55 [{1,2,3,..,}]*([2^220]*G) */ + {{0x000e0f2aa1ff4af5,0x0007890503a3c558,0x0004f76f161f4348,0x00032e661647323c,0x00000d0706eee134}, {0x00087caf5eba0fb7,0x000ff0bda2c4ef1a,0x000ae646228a95c0,0x000ba610d693e012,0x00009871341645e6}}, + {{0x000b01264b496679,0x0007ae05f7601dc4,0x00085d27aa4bdafa,0x000747171b28b3f1,0x000087e5163c3425}, {0x000ac4ec3864a656,0x00091f449c121c42,0x0009658322dae1bb,0x0009f4680d974306,0x0000ac1ef01de31d}}, + {{0x00068563958e0555,0x0000adf44aeea780,0x000c18b8dac35ee4,0x0006cd2b47891397,0x0000396824f4a258}, {0x0007b251b23f8c4a,0x000f6decdef982b3,0x000fc39c0f9ced36,0x00032b28c3bee5c2,0x00001731faf0d9db}}, + {{0x0004f74ea3d44467,0x0008b0ad1c7f045d,0x000374e92a439f17,0x000008c95d951051,0x00005870ea000229}, {0x00098c2c54e7e812,0x0009b4b3860b1fec,0x000bfc8f6ef537ee,0x000403139dd83440,0x00000b513642f114}}, + {{0x0006ab6dd13b3c94,0x00072371f872f32f,0x0005712ab70e052f,0x0001000574074212,0x0000239152df3512}, {0x0005eaa80b229154,0x000cf896f6fa5835,0x0002b4c8fd0e263e,0x0005bb9378a8a644,0x00000c2b54736579}}, + {{0x000fe8c284745301,0x0003eb7fec008f80,0x000cb05ca5649a17,0x000c41deed5bf4d9,0x00004b1a3a9e7077}, {0x000d239096883ec3,0x000e74ae671d1c2e,0x000b7362ad550edf,0x0004f2b233e5dcf7,0x00002c158207fd46}}, + {{0x0006a81c61ae9676,0x000cd2a2e1e5c52e,0x000211ef8af11042,0x0005fcb353902a1a,0x000044d16e1299a2}, {0x000d6065b67e48ad,0x000421a0b664937f,0x000e072b8fa57096,0x000727aa661c737e,0x0000e1eb4ffc2e0a}}, + {{0x000bc2afda6a4a95,0x000a5106ae0dbdd9,0x00069a4bbdba0178,0x0007153820c9f549,0x0000031e9fde9fbc}, {0x000030ac193d9428,0x0007c54cbb38e42a,0x0008fa77cdc3d6ab,0x000a95507c17b91c,0x0000465bcc963642}}, +}, +{/* digit=56 [{1,2,3,..,}]*([2^224]*G) */ + {{0x000265bc25dfad35,0x0009993f44b6974e,0x000d6d473d03630b,0x000992b3270892bf,0x0000b2d95436c5ee}, {0x0004537a36f7c5f4,0x000dcab0b81daeb9,0x0008b45e59befc01,0x00048b483cdb0818,0x00004c753b741e46}}, + {{0x000bc87b24116186,0x0003507924c48e43,0x000c9255708754bd,0x0007f4ef2050334a,0x0000e7e4fe74e038}, {0x000e2e276961d0e3,0x000767eac10f21f3,0x000757a882b69d41,0x000d3536d0f45f73,0x00008b967e55b0c7}}, + {{0x0008fc4b31fa7794,0x00054f13036e54ba,0x000d754b78024dc8,0x0009aefda2af6382,0x0000a784242ee9ea}, {0x00014abf9887947d,0x00059d555a0997dd,0x0003a46aa7f2ecfc,0x0004b5b37c4244f6,0x0000032cfc2cf71b}}, + {{0x00084c16b8a6a975,0x000e5b2bca35baef,0x000174d43d2e7f3d,0x000c5b721c6c095b,0x0000719cf32252cc}, {0x00061f03adf95177,0x000a1be20ff4fc73,0x000eacc0e1e26416,0x0005d201f9d99769,0x000021eba6432e63}}, + {{0x000e9c825df8bb5c,0x000f75752d7d8225,0x0003b281d931f721,0x0008be3c4ed4750a,0x0000f9276830a466}, {0x000358e75b7e90c9,0x000e47a29b998b7f,0x00067f2c806e5c24,0x0002d30058967aa1,0x0000f1a6fba34ee6}}, + {{0x0009c4f278291f13,0x000524e64c1d9a89,0x00062916e69a9032,0x0007cc46cc5d428d,0x0000c802e661c100}, {0x000f2aa6219cfbbf,0x000dc10258b1eadc,0x000e142af942870d,0x0007a377264e68a5,0x000025675e2f89cc}}, + {{0x0008a3b7336aa166,0x000e1c5c622bb77e,0x00089e0295a92cc2,0x00057333a35a2c17,0x0000f91306eae4d5}, {0x000a581da0a46f52,0x000d62640bbac5a2,0x0007b3ae4fb532be,0x000a7188ff0f114a,0x0000223e7b6d8ff7}}, + {{0x00031335d21d261c,0x000b8abb1fbcb593,0x0001b3b61a336289,0x000511797db2f363,0x00002cedb2697e6a}, {0x0006f34103553328,0x000add0ae37f3880,0x00017c5c7e5f1fb4,0x000ec357cf26a55d,0x00002e8df47e8c43}}, +}, +{/* digit=57 [{1,2,3,..,}]*([2^228]*G) */ + {{0x0001128ffb5e7ce8,0x00032ecb96c1e0d4,0x0005ca788dbd8b54,0x00038c029ab3dd0b,0x0000b1148a2990eb}, {0x0008db869fb19245,0x0001018391a80904,0x000d311b9cd2149f,0x0009b96bece5b6fe,0x0000edbe9b9effd2}}, + {{0x00093e7532e8d6a4,0x0005302a1ee4ab55,0x0000496c09409290,0x0007c8379b32e820,0x00006fb6e9e760a2}, {0x00077ba620051584,0x00014de3f1914a33,0x0004d21271a3266c,0x0002f3e60fad96c9,0x00001553dd1a4630}}, + {{0x00031a2a6ec0fe46,0x0002959645720704,0x000da5c3949da0b4,0x000e51bb12d1b09d,0x00004170fe1d2d3d}, {0x0002b16a4a2f5d9b,0x00059590be923a8b,0x000b9b0b5de1bad6,0x00067eb7f93581f0,0x0000007f4de9115d}}, + {{0x000d36fe12a94abc,0x000a75ad7c477b0c,0x000768469f364b3b,0x000cc596a7a2a78e,0x0000cc31c7edbbc7}, {0x000d5d0080dbb92c,0x000316fb0f1f270a,0x000d99f57fb201e9,0x000da5dfce7a1e29,0x000012a02b0c6457}}, + {{0x0005482a048530b6,0x00040467f15d9468,0x0001b7d84b4a3120,0x00095db5f8a2605b,0x00001ceef97bf452}, {0x000832a07e7578a7,0x0003d915eb7cc48b,0x000cc58340724963,0x00028995bbad2d0f,0x0000fdeed650da95}}, + {{0x000b56d84457fa16,0x00061e11055dfd9f,0x000d8d3cf1cddb6c,0x000b08d4173a6b13,0x0000e1b2d83761d2}, {0x000efe79a7aed4b6,0x0009fc67b13ce887,0x000a8d47351b67cc,0x000cf5ffd958d4f0,0x00002c566abb452e}}, + {{0x0002367962f3f098,0x000b1784e6f456a0,0x000fc496b5d1b73a,0x000d88b82f0e3c6e,0x00005b2fe37d1f96}, {0x000de1a58c6ee495,0x0003ae7abc0c0aeb,0x000075de7d3903b0,0x00051633f3381ecc,0x00009c9d48206fa7}}, + {{0x0002ba62a80f39c6,0x0001c8cbe0887ea7,0x000bd1cc1cb2174b,0x000ce69c73ec69d6,0x0000a2dbe21520dc}, {0x000150beeaae9da5,0x000dedf630d9d0a5,0x000634cd8c935e85,0x000f022147144fa1,0x0000eccb56c94f3a}}, +}, +{/* digit=58 [{1,2,3,..,}]*([2^232]*G) */ + {{0x00079cfc0e2b70a5,0x000d3e8cbae7a77a,0x000db18fc2569c8b,0x0000ff392a5dbefa,0x00009bc96b48ce6a}, {0x00004f48b5510059,0x0006344b2bd7987f,0x000c447d77efe3aa,0x000dd00e9cb8ed6a,0x0000b4eb10b0783b}}, + {{0x0002acc711923485,0x000f8f17ef5fecc3,0x000e25b0e545401b,0x000ab9e209a493cd,0x0000c11886bb63ab}, {0x00081b128ec7c90b,0x000725b57f5c361a,0x000d9169618b125a,0x0007ff86d1b45afa,0x000031a786e54c3f}}, + {{0x000189659471f1f2,0x000d1630357339d2,0x000bf5a4b2e613de,0x000be5a799579478,0x00000adf6b5df19f}, {0x000c95f1574d34dd,0x0009d9323cea6a48,0x0002df9cf95488f0,0x000500450aee7f55,0x0000f016f7b23557}}, + {{0x0004c6f8d9fceb6f,0x00099b528f3748cf,0x000303b2b11e85f7,0x000605e2896d2552,0x0000929675bdd68c}, {0x000237410c708a9a,0x0007e0d7e5a75bd2,0x00041047f4682ca1,0x0008404242b5c590,0x0000f571053af9c6}}, + {{0x00066978e93edd55,0x000207ea4f453969,0x000d33d8735cdb8e,0x0002d636f8305dfe,0x00007623440b2564}, {0x000b580945dd7d69,0x0006031739bc4fd9,0x0007bf127965ffcb,0x0001c734588e1f63,0x000036c0ba0e39d2}}, + {{0x0006a599a93a5c94,0x000ce8d12f613d87,0x000b2aa43026be75,0x000dade49900ede9,0x00004d6dc80f3a68}, {0x000116b7d23e11bc,0x000376814209396b,0x000c659561279121,0x000fae3e2807cf6c,0x0000c606ca8b405f}}, + {{0x000017dc145a6c70,0x0002968798dab36c,0x0000eff5dcca6438,0x000681d13b63768d,0x00006e39e2d2206e}, {0x000ffa43add517af,0x000900d95fee2d9d,0x000c7c7a8e670e6c,0x0003050ecb51abf1,0x000017dff5264945}}, + {{0x00068f9e5137d20c,0x000acf7e70ac618e,0x000b86b0a79588cb,0x0001feb6d37f5258,0x0000b281c993cc59}, {0x0003fed8fe40e06c,0x0006ad9ca79270e0,0x000d3a3da394ded9,0x000130f1d22cddbc,0x0000b88cb27cc591}}, +}, +{/* digit=59 [{1,2,3,..,}]*([2^236]*G) */ + {{0x000eb34649966a56,0x000f86639e18c8c7,0x000ce0f3897587f4,0x00080a0724cc000b,0x00003578addaae62}, {0x000aa57c7fd6a1af,0x00046b017e3501be,0x000df2ed183b1a53,0x00085201c027e3ef,0x0000373d4ebc2d31}}, + {{0x000546827502203e,0x000538ade3161e8d,0x000687415985039d,0x000774efd373f10a,0x0000fccb79223526}, {0x000d46e0f4497d9a,0x0001b601ab9a4ef8,0x0007b2ad14152df7,0x0001804250cd2fe4,0x00002b63fa69b048}}, + {{0x0004ab81e6799c95,0x00006d148443a72e,0x000a73a1b4c0452b,0x0003dc4f3d6068b1,0x00003d967d92a918}, {0x0006305308773b32,0x000dd107d1c4a6ba,0x0002936f7c5535c5,0x000e7282492b6d5d,0x0000207d5e4da0f0}}, + {{0x000cb6f787d1f1c8,0x0004bd219a6658a6,0x0003146b0427bac9,0x00078151d7d49f38,0x0000164b77ff863d}, {0x000b0842f9631b8b,0x0009349388de6646,0x0008cd383ef5b3aa,0x0003a060536422e5,0x0000079d912a43ea}}, + {{0x000234ea69b16e89,0x000bc1d5e5a6f2c1,0x000b57835cef457b,0x000ddf906b1d3021,0x00008fccf893f260}, {0x000af0d389fa01e6,0x0009e0e60cc9a47b,0x000e5dd23920c8f4,0x0001cdf9674c7ce3,0x00003ba7e5f5ab84}}, + {{0x0003293983884693,0x0006f55208130d55,0x000c8b1b292a9779,0x0008e2c2bb329ebf,0x0000c6f15324e83e}, {0x000d963e4290a26e,0x00017cf40c04de61,0x000e829f7d35af4d,0x000a8efac154d763,0x00001d9debc16dc9}}, + {{0x00063e677bca7881,0x000e37d394580513,0x00024e144be8d0ae,0x00028e4dbde8185b,0x000023188f4e65e5}, {0x0008b9cefe44eb7f,0x00022e76be281a4f,0x00062f74431f9f1a,0x00073701910bc8e4,0x00002e6f9dbd037a}}, + {{0x000c041cb73887ee,0x0009a3ce3a32704a,0x000393e75f878b61,0x00008c57ef73d556,0x00004372d2fb276c}, {0x000c8940924cf58a,0x000c4aa317e25d9b,0x000608da5fa2a4de,0x000960e51edccc79,0x0000dcc68fb2cd4b}}, +}, +{/* digit=60 [{1,2,3,..,}]*([2^240]*G) */ + {{0x0004f09a9e0eeaed,0x000f7b05a6569f15,0x00045b85d2246e6f,0x0004324d7c1c8110,0x0000e99ea38a3bb7}, {0x000818763184ff43,0x00020134bfc2d58f,0x0001203202a22342,0x000e9c1560dbed23,0x00007243c95a6a3d}}, + {{0x0006c8fe256b02b0,0x0003fa5946e09f11,0x00035452a7149569,0x00062eeb9696ffc3,0x00001ca592949711}, {0x0001f50c0f28e720,0x000c70d8df1aee0a,0x0009110f82baac62,0x00016acf65d297f4,0x000041dbb019a45e}}, + {{0x0009223d39e1ee45,0x000c9e3e6c2bd0b1,0x000a45c34c8832a2,0x00091b64a8f43da3,0x00002a05eef71fb2}, {0x000e24ae4b68e385,0x000b3e2d8a3fc0d3,0x0005b7da85289120,0x0004e133836b9842,0x0000bd418f4000c6}}, + {{0x0002241cedc2c975,0x000b7b632640e1a0,0x000fb588ff0f5489,0x0008e7b09091ddcb,0x0000ffd0f38ad947}, {0x00041a1dae35eda9,0x0006f2f0b26b83f1,0x0009dde18d25563a,0x000b3680014b171b,0x0000fcf8f820da49}}, + {{0x000380540096f25a,0x000e8c8201311e99,0x000993f9c900d4bd,0x0000072170cfd32a,0x00000e3d894cdfe1}, {0x0000b5a0e7df1098,0x000ac7fde3dce00d,0x00089816ac904985,0x000b9e15597a84cb,0x0000ac8b02839dfe}}, + {{0x000a4fdf7a2df835,0x000bb4524d444e3e,0x0006aee218b68b26,0x000e1c74caeeab12,0x000090a00a5e15d9}, {0x000a6ab49b90eff5,0x000e7df4fe510ae2,0x000fcb6ed74b4cb1,0x000b300306ed1107,0x000064ebe2ea02f5}}, + {{0x000a0c3c0a9d128d,0x00047ed0d3bce0f7,0x000e778e62adc34d,0x0006ba4ebf577813,0x00003b89bd18b847}, {0x000b52837413953c,0x000d98ba3471209e,0x000a79c09952b705,0x000b2acaa81ade86,0x000008eed3e3e0e7}}, + {{0x000c2bc9a8f42ff5,0x00009a1c0299dea0,0x0004dd41b6297424,0x0002495ee5f5f69e,0x0000b1bba807e110}, {0x000eadb78da80167,0x00008809f79eeac4,0x000f8c0dec297878,0x000ba939d2dbcee3,0x0000fb4b5fc764d3}}, +}, +{/* digit=61 [{1,2,3,..,}]*([2^244]*G) */ + {{0x000179c7f034ff4c,0x0009f781eac1a607,0x000022138efb8fcd,0x000039fa57f8a97b,0x00005bb9f1e16ab6}, {0x0007e24e4d2ab7f7,0x0001e7a9e3648902,0x0007f487d3d67ad7,0x000bd0c579e70c1f,0x0000fefc8949a7e6}}, + {{0x0001662a45cfd31b,0x0003c6f65cfd7cb9,0x000f3de5109dd56d,0x0004fc983e005d14,0x00009dc05b0d10f6}, {0x0000afd885eafe56,0x0003d444bdebc279,0x00087300abd5213d,0x000b76289dca9289,0x00009fb2ac313960}}, + {{0x0008bb43e4e99c48,0x0006f1f5ac02913a,0x00083f958b0c5fed,0x000eb65c5ccabdd7,0x0000d10225585a25}, {0x00075bc2701b5ef5,0x000f34ead28ab53b,0x000d37ba17cdfbb9,0x0007b8a111be6984,0x0000324f41a75991}}, + {{0x00048869ae7540fb,0x00021131e9213327,0x000a360c8d738663,0x0001e02e3d4fd8f2,0x000020a59b6ed9d4}, {0x0007eae99082a34c,0x000e1181946fb2b6,0x000d1d007fad6aa7,0x000ed07c299b9aa2,0x00001f841e14100b}}, + {{0x0008bf21619db767,0x000be5dbcdc6ba04,0x00053cfdca928899,0x00089daaf1e8f8a0,0x0000e49dcc581266}, {0x000001ccbf14e0ef,0x0002592029f13992,0x0002972a8aefbe02,0x000c66a3c0cc8691,0x00008495b3926f9a}}, + {{0x0007d4c43e90ebdf,0x00080fc72b063c1f,0x00094f40258b7810,0x0004b0da8503e1af,0x0000bb724b849f24}, {0x0002186fcd8755a4,0x000ec68482b6efcd,0x0009be3d57407cde,0x00002c4d62f57834,0x0000a0125451cc62}}, + {{0x00018c779f099ea8,0x0009290f6a520a5a,0x00025d678dfefc64,0x000de97c3b4cc277,0x0000d87ef5ce132b}, {0x000ee07a7023e899,0x000f309c8784c042,0x000c1268d9681a7d,0x0002c2fa00007a86,0x0000f76f114b2bf8}}, + {{0x00014d2151ffc085,0x0000c40d6b5568a4,0x000f472abaa79acf,0x000f1deeab0104cd,0x0000014a8c1f3aa5}, {0x000340533f134256,0x0009b7eb54d42c74,0x0008a723b2b776b4,0x00063a3a0cc4ac54,0x00005aae6f4279fe}}, +}, +{/* digit=62 [{1,2,3,..,}]*([2^248]*G) */ + {{0x0007ef9dfa782a41,0x000184cd95006944,0x00038f7626dadc8e,0x000a140574020edc,0x00007596d7ef2ee7}, {0x0005af79e1f8adc5,0x0006f4791da04ef7,0x0007b5d805ac5f21,0x0006cc1583226b7b,0x00009f3f053f21c2}}, + {{0x000abd049c879a59,0x0008347ac42e5e16,0x0009c2326844874a,0x00033bee3f8a203c,0x00009a120556eaed}, {0x000a15b63b333ae3,0x0005cd923fa01814,0x000b1b1efee9f28a,0x0009285b0cd25033,0x0000ccc39b9b346d}}, + {{0x0005e1d161e13e79,0x0001207e7068bb79,0x000522fe70f9abc2,0x00034efb3be61854,0x0000e2d0f37a9381}, {0x0007c36d292c6b0e,0x000da1e77894d8dc,0x0006c55f3bafbf59,0x0000877d0132cd1b,0x0000fa02edad609f}}, + {{0x0009359d93f6e1a6,0x00049d41c11898ea,0x000b641af729005d,0x000e784c2934107c,0x0000b2b4671e95e8}, {0x00051d05958fad35,0x000ec8619fe3da12,0x00011d318b69bc2b,0x000704d74df34cd9,0x0000def837865102}}, + {{0x00058678c673c89c,0x0006c99c7bae39ff,0x000b1e1b64925a04,0x00084f0b3bf59adb,0x00007e9d9f2f0ae0}, {0x00023960fa1776f5,0x000fb24c897b2098,0x0003534d5b2e1b98,0x000f63a9a6407d6c,0x0000e22319bf4dc3}}, + {{0x0006a2e916ef5271,0x0000393dc0853d90,0x00091da3eadeb94d,0x0002eb03a0780114,0x000077dceae1b84d}, {0x000a3c17b691e0c9,0x00086172cea2d1e5,0x000a76bce47d40bd,0x00035f7d0646ad8c,0x00000b030aa564d6}}, + {{0x00037b31f6e396ce,0x000f29a782f2d083,0x000c9b9746166b21,0x000d3d1ac6198b8e,0x0000e2e3446ebb44}, {0x000374035039dd98,0x0005a9f5c6925b28,0x000ddb4667c708f9,0x0003cf8914cce098,0x0000bb1b9f25446f}}, + {{0x00075c2a2c539e41,0x000db756daf9d315,0x000f55a120bac5dc,0x000299e917cecf91,0x0000e96433bf96f6}, {0x000c71c3700d8fb3,0x00060c9b4444bec7,0x00074f19c9a1d296,0x000d6b3d2c6970cf,0x0000b444c48dc5e0}}, +}, +{/* digit=63 [{1,2,3,..,}]*([2^252]*G) */ + {{0x000cefd8ccb854c3,0x000b95b0c45ab563,0x00037f743f5452cd,0x0004abb3c787699c,0x00004e9d192c5d44}, {0x000794652ff26b7c,0x000b5b94d6416934,0x000affb8f70d6ecf,0x000c717d201858fd,0x0000288719e05dcd}}, + {{0x000469d0728a2eb7,0x000f3433d11c5695,0x00006c08e7b46244,0x0000834a8b99baf1,0x0000989794fd3422}, {0x0008867d4fc5696b,0x0008ec79cdb7d221,0x0006d50496b021f2,0x0006285ff7bbeab2,0x000078611cb57261}}, + {{0x000f961531313d77,0x000bd6dcdc9dea75,0x00060e99185a1f4d,0x0007ccae3026b964,0x0000d467bef87ecf}, {0x000bf6705118708a,0x000993b2f1c8ea0d,0x000c0e4e054bfa36,0x00011ba9fc9d5cf2,0x00008c2ad11fe936}}, + {{0x000faf0aa1256bd2,0x0005be4631de1ef1,0x0009c26760f22454,0x000b2469cb9800de,0x00006019816b5782}, {0x000172ca66c0ccdc,0x000674407199d45c,0x0009f681a6c25f63,0x000df4917d5dbaa4,0x00000cad04872dc5}}, + {{0x000cf4c5960ef1c9,0x000e1c6979d5445b,0x0009090d6babcb16,0x0007288e3be750ae,0x0000481d2623c0eb}, {0x00036cd0d6a7d46e,0x0003ff97650066b4,0x000e1064f6eb1a6a,0x000c205984ffa2db,0x00006575fb2d809d}}, + {{0x0006d804d974a81a,0x000037a74be65042,0x00048653161304f1,0x00081a2346ff98a9,0x00001242ccb953d7}, {0x00003df97355f15a,0x00045d6058cea82f,0x000aefe28c607ed3,0x0007e403bc8cd468,0x00006e7de5b25130}}, + {{0x000df0fc6af7d445,0x0000015a9187dc07,0x000e15c2f310b252,0x000313d42661ced3,0x0000198fd906b4d8}, {0x00062cdda8368a13,0x00018e9c25424a60,0x000e37cee1a905d1,0x0004ca1d752b70da,0x0000ed8c1a546bf8}}, + {{0x000fb0feecc2f22b,0x0004198d8e5fa190,0x000f3ce723df210f,0x000fc6cce57d3af5,0x00002fb6223e12b8}, {0x000700571867c84a,0x000d5e139ebdd994,0x000e7944e141cd92,0x000058415efc9e5d,0x0000e9ee919e5821}}, +}, +{/* digit=64 [{1,2,3,..,}]*([2^256]*G) */ + {{0x0001a6a32f9eaf5b,0x00055cfc13dbbf7b,0x000b18adf2c440f9,0x00033f2cf39bc566,0x00009939fe94f015}, {0x0004553383a64506,0x000450102086a31c,0x0001f136016d96ad,0x000c08cbd6fa9550,0x000067d3ea0c5f96}}, + {{0x000c13ba12fdf41d,0x000c5224f5d1fa1f,0x000d5872bd798c04,0x000da822f4594e1d,0x0000ee12df5ebddf}, {0x0003ff0ed83420ad,0x00085daa27f3c647,0x000cefd8af41cf1c,0x00047f2772cd56ae,0x00005ddaf191902b}}, + {{0x0005abf53e86ae11,0x00004850830d88e0,0x0006bc33cc1dc4d9,0x00086fbd7fd806e0,0x0000ac330d6bcf12}, {0x0002303e1588c1e5,0x000b6b7e9c18d8ce,0x0007149f2dc25e54,0x000a2511e51e494b,0x000051b839205c7f}}, + {{0x0005ddf1510a406a,0x000569f0e98c83fc,0x0002843a0475a78f,0x0005a6b6d681c4e7,0x000090af2a4ea00c}, {0x0006d45a34f44127,0x000357f5d70325fc,0x00011092560f9c0e,0x0004d52bc0642bad,0x00009abfc112e24a}}, + {{0x000ee0691cf6cf09,0x0001b6b6bb14f844,0x000f77954e05b5ed,0x000619049c4bbcb7,0x0000d0f82198d94a}, {0x000e53617b8a0fde,0x000a78a163c77369,0x0004efcc52f1c014,0x000f9ea95975cd72,0x0000be1ab00c9aa9}}, + {{0x0000621245e20bef,0x0009134bbfc574fd,0x0007b3b6835a502d,0x0005cd40b56e370b,0x0000ca24ac75641f}, {0x00049d7102ae1815,0x00001fe146bde29a,0x0005146a8d2205d3,0x0009632a432de4b8,0x0000f90d9d766c61}}, + {{0x0004e18f143aa0fa,0x000641cf03d329bd,0x000345f4cf3894c5,0x00089dd25d055813,0x0000da5c0a11d580}, {0x000b9b65ddf3b293,0x0005e8afdfa60988,0x0006ebe1439c3438,0x000d381e3c991790,0x0000c9efd259ca95}}, + {{0x0009ce39b3d6844b,0x00093320f9bee042,0x0007dc2d2af562e9,0x0005ea5fbc2c5d71,0x00006fa79ff0722f}, {0x00070a079eea8d96,0x00019377e5ee65aa,0x000ad14cb624a2b9,0x000ac930ec06eaf7,0x00008d07bdd35640}}, +}, +}; + +#endif /* IFMA_ECPRECOMP4_PSM2_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_common.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_common.h new file mode 100644 index 000000000..e90fdf596 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_common.h @@ -0,0 +1,207 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_SM3_COMMON_H) +#define _SM3_COMMON_H + +#include +#include + +#include + +#define SM3_MSG_LEN_REPR (sizeof(int64u)) /* size of processed message length representation (bytes) */ + +#ifndef M256 + #define M256(mem) (*((__m256i*)(mem))) +#endif + +#ifndef M512 + #define M512(mem) (*((__m512i*)(mem))) +#endif + +#ifndef MIN + #define MIN(a, b) ( ((a) < (b)) ? a : b ) +#endif + +/* +// accessors to context's fields +*/ + +#define MSG_LEN(ctx) ((ctx)->msg_len) +#define HASH_VALUE(ctx) ((ctx)->msg_hash) +#define HASH_BUFFIDX(ctx) ((ctx)->msg_buff_idx) +#define HASH_BUFF(ctx) ((ctx)->msg_buffer) + +/* +// constants +*/ + +static const int32u sm3_iv[] = { 0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600, + 0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E }; + +__ALIGN64 static const int8u swapBytes[] = { 7,6,5,4, 3,2,1,0, 15,14,13,12, 11,10,9,8, + 7,6,5,4, 3,2,1,0, 15,14,13,12, 11,10,9,8, + 7,6,5,4, 3,2,1,0, 15,14,13,12, 11,10,9,8, + 7,6,5,4, 3,2,1,0, 15,14,13,12, 11,10,9,8 }; + +__ALIGN64 static const int32u tj_calculated[] = { 0x79CC4519,0xF3988A32,0xE7311465,0xCE6228CB,0x9CC45197,0x3988A32F,0x7311465E,0xE6228CBC, + 0xCC451979,0x988A32F3,0x311465E7,0x6228CBCE,0xC451979C,0x88A32F39,0x11465E73,0x228CBCE6, + 0x9D8A7A87,0x3B14F50F,0x7629EA1E,0xEC53D43C,0xD8A7A879,0xB14F50F3,0x629EA1E7,0xC53D43CE, + 0x8A7A879D,0x14F50F3B,0x29EA1E76,0x53D43CEC,0xA7A879D8,0x4F50F3B1,0x9EA1E762,0x3D43CEC5, + 0x7A879D8A,0xF50F3B14,0xEA1E7629,0xD43CEC53,0xA879D8A7,0x50F3B14F,0xA1E7629E,0x43CEC53D, + 0x879D8A7A,0x0F3B14F5,0x1E7629EA,0x3CEC53D4,0x79D8A7A8,0xF3B14F50,0xE7629EA1,0xCEC53D43 }; + +/* +// internal functions +*/ + + +__INLINE void pad_block(int8u padding_byte, void* dst_p, int num_bytes) +{ + int8u* d = (int8u*)dst_p; + int k; + for(k = 0; k < num_bytes; k++ ) + d[k] = padding_byte; +} + +__INLINE void TRANSPOSE_8X8_I32(__m256i *v0, __m256i *v1, __m256i *v2, __m256i *v3, + __m256i *v4, __m256i *v5, __m256i *v6, __m256i *v7) +{ + __m256i w0, w1, w2, w3, w4, w5, w6, w7; + __m256i x0, x1, x2, x3, x4, x5, x6, x7; + __m256i t1, t2; + + x0 = _mm256_permute4x64_epi64(*v0, 0b11011000); + x1 = _mm256_permute4x64_epi64(*v1, 0b11011000); + w0 = _mm256_unpacklo_epi32(x0, x1); + w1 = _mm256_unpackhi_epi32(x0, x1); + + x2 = _mm256_permute4x64_epi64(*v2, 0b11011000); + x3 = _mm256_permute4x64_epi64(*v3, 0b11011000); + w2 = _mm256_unpacklo_epi32(x2, x3); + w3 = _mm256_unpackhi_epi32(x2, x3); + + x4 = _mm256_permute4x64_epi64(*v4, 0b11011000); + x5 = _mm256_permute4x64_epi64(*v5, 0b11011000); + w4 = _mm256_unpacklo_epi32(x4, x5); + w5 = _mm256_unpackhi_epi32(x4, x5); + + x6 = _mm256_permute4x64_epi64(*v6, 0b11011000); + x7 = _mm256_permute4x64_epi64(*v7, 0b11011000); + w6 = _mm256_unpacklo_epi32(x6, x7); + w7 = _mm256_unpackhi_epi32(x6, x7); + + t1 = _mm256_permute4x64_epi64(w0, 0b11011000); + t2 = _mm256_permute4x64_epi64(w2, 0b11011000); + x0 = _mm256_unpacklo_epi64(t1, t2); + x1 = _mm256_unpackhi_epi64(t1, t2); + + t1 = _mm256_permute4x64_epi64(w1, 0b11011000); + t2 = _mm256_permute4x64_epi64(w3, 0b11011000); + x2 = _mm256_unpacklo_epi64(t1, t2); + x3 = _mm256_unpackhi_epi64(t1, t2); + + t1 = _mm256_permute4x64_epi64(w4, 0b11011000); + t2 = _mm256_permute4x64_epi64(w6, 0b11011000); + x4 = _mm256_unpacklo_epi64(t1, t2); + x5 = _mm256_unpackhi_epi64(t1, t2); + + t1 = _mm256_permute4x64_epi64(w5, 0b11011000); + t2 = _mm256_permute4x64_epi64(w7, 0b11011000); + x6 = _mm256_unpacklo_epi64(t1, t2); + x7 = _mm256_unpackhi_epi64(t1, t2); + + *v0 = _mm256_permute2x128_si256(x0, x4, 0b100000); + *v1 = _mm256_permute2x128_si256(x0, x4, 0b110001); + *v2 = _mm256_permute2x128_si256(x1, x5, 0b100000); + *v3 = _mm256_permute2x128_si256(x1, x5, 0b110001); + *v4 = _mm256_permute2x128_si256(x2, x6, 0b100000); + *v5 = _mm256_permute2x128_si256(x2, x6, 0b110001); + *v6 = _mm256_permute2x128_si256(x3, x7, 0b100000); + *v7 = _mm256_permute2x128_si256(x3, x7, 0b110001); +} + +__INLINE void MASK_TRANSPOSE_8X8_I32(int32u* out[8], const int32u* const inp[8], __mmask16 mb_mask) { + __m256i v0 = _mm256_loadu_si256((__m256i*)inp[0]); + __m256i v1 = _mm256_loadu_si256((__m256i*)inp[1]); + __m256i v2 = _mm256_loadu_si256((__m256i*)inp[2]); + __m256i v3 = _mm256_loadu_si256((__m256i*)inp[3]); + __m256i v4 = _mm256_loadu_si256((__m256i*)inp[4]); + __m256i v5 = _mm256_loadu_si256((__m256i*)inp[5]); + __m256i v6 = _mm256_loadu_si256((__m256i*)inp[6]); + __m256i v7 = _mm256_loadu_si256((__m256i*)inp[7]); + + TRANSPOSE_8X8_I32(&v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7); + + /* mask store hashes to the first 8 buffers */ + _mm256_mask_storeu_epi32((void*)out[0], (__mmask8)(((mb_mask >> 0) & 1)) * 0xFF, v0); + _mm256_mask_storeu_epi32((void*)out[1], (__mmask8)(((mb_mask >> 1) & 1)) * 0xFF, v1); + _mm256_mask_storeu_epi32((void*)out[2], (__mmask8)(((mb_mask >> 2) & 1)) * 0xFF, v2); + _mm256_mask_storeu_epi32((void*)out[3], (__mmask8)(((mb_mask >> 3) & 1)) * 0xFF, v3); + _mm256_mask_storeu_epi32((void*)out[4], (__mmask8)(((mb_mask >> 4) & 1)) * 0xFF, v4); + _mm256_mask_storeu_epi32((void*)out[5], (__mmask8)(((mb_mask >> 5) & 1)) * 0xFF, v5); + _mm256_mask_storeu_epi32((void*)out[6], (__mmask8)(((mb_mask >> 6) & 1)) * 0xFF, v6); + _mm256_mask_storeu_epi32((void*)out[7], (__mmask8)(((mb_mask >> 7) & 1)) * 0xFF, v7); + +} + +__INLINE void TRANSPOSE_8X16_I32(int32u* out[16], const int32u* const inp[8], __mmask16 mb_mask) { + __m256i v0 = _mm256_loadu_si256((__m256i*)inp[0]); + __m256i v1 = _mm256_loadu_si256((__m256i*)inp[1]); + __m256i v2 = _mm256_loadu_si256((__m256i*)inp[2]); + __m256i v3 = _mm256_loadu_si256((__m256i*)inp[3]); + __m256i v4 = _mm256_loadu_si256((__m256i*)inp[4]); + __m256i v5 = _mm256_loadu_si256((__m256i*)inp[5]); + __m256i v6 = _mm256_loadu_si256((__m256i*)inp[6]); + __m256i v7 = _mm256_loadu_si256((__m256i*)inp[7]); + + TRANSPOSE_8X8_I32(&v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7); + + /* mask store hashes to the first 8 buffers */ + _mm256_mask_storeu_epi32((void*)out[0], (__mmask8)(((mb_mask >> 0) & 1)) * 0xFF, v0); + _mm256_mask_storeu_epi32((void*)out[1], (__mmask8)(((mb_mask >> 1) & 1)) * 0xFF, v1); + _mm256_mask_storeu_epi32((void*)out[2], (__mmask8)(((mb_mask >> 2) & 1)) * 0xFF, v2); + _mm256_mask_storeu_epi32((void*)out[3], (__mmask8)(((mb_mask >> 3) & 1)) * 0xFF, v3); + _mm256_mask_storeu_epi32((void*)out[4], (__mmask8)(((mb_mask >> 4) & 1)) * 0xFF, v4); + _mm256_mask_storeu_epi32((void*)out[5], (__mmask8)(((mb_mask >> 5) & 1)) * 0xFF, v5); + _mm256_mask_storeu_epi32((void*)out[6], (__mmask8)(((mb_mask >> 6) & 1)) * 0xFF, v6); + _mm256_mask_storeu_epi32((void*)out[7], (__mmask8)(((mb_mask >> 7) & 1)) * 0xFF, v7); + + v0 = _mm256_loadu_si256((__m256i*)inp[0] + 1); + v1 = _mm256_loadu_si256((__m256i*)inp[1] + 1); + v2 = _mm256_loadu_si256((__m256i*)inp[2] + 1); + v3 = _mm256_loadu_si256((__m256i*)inp[3] + 1); + v4 = _mm256_loadu_si256((__m256i*)inp[4] + 1); + v5 = _mm256_loadu_si256((__m256i*)inp[5] + 1); + v6 = _mm256_loadu_si256((__m256i*)inp[6] + 1); + v7 = _mm256_loadu_si256((__m256i*)inp[7] + 1); + + + TRANSPOSE_8X8_I32(&v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7); + + /* mask store hashes to the last 8 buffers */ + _mm256_mask_storeu_epi32((void*)out[8], (__mmask8)(((mb_mask >> 8) & 1)) * 0xFF, v0); + _mm256_mask_storeu_epi32((void*)out[9], (__mmask8)(((mb_mask >> 9) & 1)) * 0xFF, v1); + _mm256_mask_storeu_epi32((void*)out[10], (__mmask8)(((mb_mask >> 10) & 1)) * 0xFF, v2); + _mm256_mask_storeu_epi32((void*)out[11], (__mmask8)(((mb_mask >> 11) & 1)) * 0xFF, v3); + _mm256_mask_storeu_epi32((void*)out[12], (__mmask8)(((mb_mask >> 12) & 1)) * 0xFF, v4); + _mm256_mask_storeu_epi32((void*)out[13], (__mmask8)(((mb_mask >> 13) & 1)) * 0xFF, v5); + _mm256_mask_storeu_epi32((void*)out[14], (__mmask8)(((mb_mask >> 14) & 1)) * 0xFF, v6); + _mm256_mask_storeu_epi32((void*)out[15], (__mmask8)(((mb_mask >> 15) & 1)) * 0xFF, v7); +} + +#endif /* _SM3_COMMON_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_mb16.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_mb16.h new file mode 100644 index 000000000..5412f7c3b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_mb16.h @@ -0,0 +1,43 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_SM3_MB16_H) +#define _SM3_MB16_H + +#include +#include + +#include + +/* +// change endian +*/ +static __ALIGN64 const int8u swapBytesCtx[] = { 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 }; + +#define SIMD_ENDIANNESS32(x) _mm512_shuffle_epi8((x), M512(swapBytesCtx)); + +/* +// internal functions +*/ + +EXTERN_C void sm3_avx512_mb16(int32u hash_pa[][16], const int8u* const msg_pa[16], int len[16]); +EXTERN_C void sm3_mask_init_mb16(SM3_CTX_mb16* p_state, unsigned short mb_mask); + +#endif /* _SM3_MB16_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_mb8.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_mb8.h new file mode 100644 index 000000000..c61231fcb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm3/sm3_mb8.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_SM3_MB8_H) +#define _SM3_MB8_H + +#include +#include + +#include + +/* +// change endian +*/ + +static __ALIGN64 const int8u swapBytesCtx[] = { 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 }; + +#define SIMD_ENDIANNESS32(x) _mm256_shuffle_epi8((x), M256(swapBytesCtx)); +#define SM3_NUM_BUFFERS8 (8) /* max number of buffers in sm3 multi-buffer 8 */ + +typedef int32u sm3_hash_mb8[SM3_SIZE_IN_WORDS][SM3_NUM_BUFFERS8]; /* sm3 hash value in multi-buffer 8 format */ +struct _sm3_context_mb8 { + int msg_buff_idx[SM3_NUM_BUFFERS8]; /* buffer entry */ + int64u msg_len[SM3_NUM_BUFFERS8]; /* message length */ + int8u msg_buffer[SM3_NUM_BUFFERS8][SM3_MSG_BLOCK_SIZE]; /* buffer */ + __ALIGN64 + sm3_hash_mb8 msg_hash; /* intermediate hash */ +}; + +typedef struct _sm3_context_mb8 SM3_CTX_mb8; + +/* +// internal functions +*/ + +EXTERN_C mbx_status sm3_init_mb8(SM3_CTX_mb8* p_state); +EXTERN_C mbx_status sm3_update_mb8(const int8u* const msg_pa[8], int len[8], SM3_CTX_mb8* p_state); +EXTERN_C mbx_status sm3_final_mb8(int8u* hash_pa[8], SM3_CTX_mb8* p_state); +EXTERN_C mbx_status sm3_msg_digest_mb8(const int8u* const msg_pa[8], int len[8], int8u* hash_pa[8]); + +EXTERN_C void sm3_avx512_mb8(int32u hash_pa[][8], const int8u* const msg_pa[8], int len[8]); +EXTERN_C void sm3_mask_init_mb8(SM3_CTX_mb8 * p_state, __mmask8 mb_mask); + +#endif /* _SM3_MB8_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_ccm_mb.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_ccm_mb.h new file mode 100644 index 000000000..7d7e15d90 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_ccm_mb.h @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#include + +#ifndef SM4_CCM_MB_H +#define SM4_CCM_MB_H + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +// Internal functions +*/ + +/* + * Set IV for 16 buffers in SM4-CCM context + * + * @param[in] pa_iv Array of IVs + * @param[in] iv_len Array of IV lengths + * @param[in] mb_mask Bitmask selecting which lines to update + * @param[in/out] p_context SM4-CCM context + * + */ +EXTERN_C void sm4_ccm_update_iv_mb16(const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context); +/* + * Set message lengths for 16 buffers in SM4-CCM context + * + * @param[in] msg_len Array of total message lengths + * @param[in] mb_mask Bitmask selecting which lines to update + * @param[in/out] p_context SM4-CCM context + * + */ +EXTERN_C void sm4_ccm_set_msg_len_mb16(const int64u msg_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context); + +/* + * Set authentication tag lengths for 16 buffers in SM4-CCM context + * + * @param[in] tag_len Array of authentication tag lengths + * @param[in] mb_mask Bitmask selecting which lines to update + * @param[in/out] p_context SM4-CCM context + * + */ +EXTERN_C void sm4_ccm_set_tag_len_mb16(const int tag_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_ccm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], + const int aad_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_ccm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_ccm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_ccm_get_tag_mb16(int8u *pa_out[SM4_LINES], const int tag_len[SM4_LINES], __mmask16 mb_mask, SM4_CCM_CTX_mb16 *p_context); + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* Context accessors */ + +#define SM4_CCM_CONTEXT_MSG_LEN(context) ((context)->msg_len) +#define SM4_CCM_CONTEXT_PROCESSED_LEN(context) ((context)->total_processed_len) +#define SM4_CCM_CONTEXT_TAG_LEN(context) ((context)->tag_len) +#define SM4_CCM_CONTEXT_IV_LEN(context) ((context)->iv_len) +#define SM4_CCM_CONTEXT_CTR0(context) ((context)->ctr0) +#define SM4_CCM_CONTEXT_CTR(context) ((context)->ctr) +#define SM4_CCM_CONTEXT_HASH(context) ((context)->hash) + +#define SM4_CCM_CONTEXT_KEY(context) (&((context)->key_sched)) +#define SM4_CCM_CONTEXT_STATE(context) ((context)->state) + +/* Calculate offsets for acessing blocks in buffers */ + +#define REG_SIZE_BITS (512) +#define REG_SIZE_BYTES (REG_SIZE_BITS / 8) /* Register size in bytes */ + +#define SLOTS_PER_BLOCK (SM4_BLOCK_SIZE / SM4_CCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES) +#define BLOCKS_PER_REG (REG_SIZE_BYTES / SM4_BLOCK_SIZE) + +#define BUFFER_BLOCK_NUM(buffer, n) (buffer + SLOTS_PER_BLOCK * n) +#define BUFFER_REG_NUM(buffer, n) (buffer + SLOTS_PER_BLOCK * BLOCKS_PER_REG * n) + +/* Internal macroses */ + +#define sm4_ccm_clear_buffer(p_buffer) storeu((void *)(p_buffer), setzero()); + +#define SM4_CCM_CLEAR_BUFFER(p_buffer) \ + { \ + sm4_ccm_clear_buffer(BUFFER_REG_NUM(p_buffer, 0)); \ + sm4_ccm_clear_buffer(BUFFER_REG_NUM(p_buffer, 1)); \ + sm4_ccm_clear_buffer(BUFFER_REG_NUM(p_buffer, 2)); \ + sm4_ccm_clear_buffer(BUFFER_REG_NUM(p_buffer, 3)); \ + } + +#define SM4_CCM_CLEAR_LEN(p_len) \ + { \ + sm4_ccm_clear_buffer(p_len); \ + } + +#endif // SM4_CCM_MB_H diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_gcm_mb.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_gcm_mb.h new file mode 100644 index 000000000..c1659c7fe --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_gcm_mb.h @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#include + +#ifndef SM4_GCM_MB_H +#define SM4_GCM_MB_H + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* +// Constant from NIST Special Publication 800-38D +// (Recommendation for GCMmode, p.5.2.1.1 Input Data) +// len(P) <= 2^39-256 bits +*/ +static const int64u MAX_TXT_LEN = ((int64u)1 << 36) - 32; // length in bytes + +/* +// Internal functions +*/ + +EXTERN_C void sm4_gcm_ghash_mul_single_block_mb16(__m512i *data_blocks[], __m512i *hashkeys[]); + +EXTERN_C void sm4_gcm_update_ghash_full_blocks_mb16(__m128i ghash[SM4_LINES], + const int8u *const pa_input[SM4_LINES], + __m512i *input_len, + __m128i hashkey[SM4_GCM_HASHKEY_PWR_NUM][SM4_LINES], + __mmask16 mb_mask); + +EXTERN_C void sm4_gcm_update_ghash_partial_blocks_mb16(__m128i ghash[SM4_LINES], + const int8u *const pa_input[SM4_LINES], + __m512i *input_len, + __m128i hashkey[SM4_LINES], + __mmask16 mb_mask); + +EXTERN_C void sm4_gcm_precompute_hashkey_mb16(const mbx_sm4_key_schedule *key_sched, SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C __mmask16 sm4_gcm_update_iv_mb16(const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_gcm_finalize_iv_mb16(const int8u *const pa_iv[SM4_LINES], __mmask16 mb_mask, SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C __mmask16 sm4_gcm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], + const int aad_len[SM4_LINES], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_encrypt_j0_mb16(SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_gctr_kernel_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_inp[SM4_LINES], + const int len[SM4_LINES], + const int32u *key_sched[SM4_ROUNDS], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C __mmask16 sm4_gcm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C __mmask16 sm4_gcm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context); + +EXTERN_C void sm4_gcm_get_tag_mb16(int8u *pa_out[SM4_LINES], const int tag_len[SM4_LINES], __mmask16 mb_mask, SM4_GCM_CTX_mb16 *p_context); + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* Context acessors */ + +#define SM4_GCM_CONTEXT_HASHKEY(context) ((p_context)->hashkey) +#define SM4_GCM_CONTEXT_J0(context) ((p_context)->j0) +#define SM4_GCM_CONTEXT_GHASH(context) ((p_context)->ghash) +#define SM4_GCM_CONTEXT_CTR(context) ((p_context)->ctr) + +#define SM4_GCM_CONTEXT_LEN(context) ((p_context)->len) + +#define SM4_GCM_CONTEXT_KEY(context) (&((p_context)->key_sched)) + +#define SM4_GCM_CONTEXT_STATE(context) ((p_context)->state) + +/* Calculate offsets for acessing blocks in buffers */ + +#define REG_SIZE_BITS (512) +#define REG_SIZE_BYTES (REG_SIZE_BITS / 8) /* Register size in bytes */ + +#define SLOTS_PER_BLOCK (SM4_BLOCK_SIZE / SM4_GCM_CONTEXT_BUFFER_SLOT_SIZE_BYTES) +#define BLOCKS_PER_REG (REG_SIZE_BYTES / SM4_BLOCK_SIZE) + +#define BUFFER_BLOCK_NUM(buffer, n) (buffer + SLOTS_PER_BLOCK * n) +#define BUFFER_REG_NUM(buffer, n) (buffer + SLOTS_PER_BLOCK * BLOCKS_PER_REG * n) + +/* Internal macroses */ + +#define sm4_gcm_clear_buffer(p_buffer) storeu((void *)(p_buffer), setzero()); + +#define SM4_GCM_CLEAR_BUFFER(p_buffer) \ + { \ + sm4_gcm_clear_buffer(BUFFER_REG_NUM(p_buffer, 0)); \ + sm4_gcm_clear_buffer(BUFFER_REG_NUM(p_buffer, 1)); \ + sm4_gcm_clear_buffer(BUFFER_REG_NUM(p_buffer, 2)); \ + sm4_gcm_clear_buffer(BUFFER_REG_NUM(p_buffer, 3)); \ + } + +#define SM4_GCM_CLEAR_LEN(p_len) \ + { \ + sm4_gcm_clear_buffer(p_len); \ + } + +/* Constants */ + +/* GCM polynomials for reduction */ +static __ALIGN64 const int64u gcm_poly[] = { 0x0000000000000001, 0xC200000000000000, 0x0000000000000001, 0xC200000000000000, + 0x0000000000000001, 0xC200000000000000, 0x0000000000000001, 0xC200000000000000 }; + +static __ALIGN64 const int64u gcm_poly2[] = { 0x00000001C2000000, 0xC200000000000000, 0x00000001C2000000, 0xC200000000000000, + 0x00000001C2000000, 0xC200000000000000, 0x00000001C2000000, 0xC200000000000000 }; + +/* */ +static __ALIGN64 const int64u two_one[] = { 0x0000000000000001, 0x0000000100000000, 0x0000000000000001, 0x0000000100000000, + 0x0000000000000001, 0x0000000100000000, 0x0000000000000001, 0x0000000100000000 }; + +/* Constant for IV of 12 bytes size finalization */ +static __ALIGN64 const int64u one_f[] = { 0x0000000000000000, 0x0100000000000000, 0x0000000000000000, 0x0100000000000000, + 0x0000000000000000, 0x0100000000000000, 0x0000000000000000, 0x0100000000000000 }; + +static __ALIGN64 const int64u bytes_to_bits_shift[] = { 0x0000000000000003, 0x0000000000000000 }; + +static const int rearrangeOrder[] = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 }; + +/* Need to rearrange input pointers and lengths to keep it in the same layout with hashkeys */ +#define rearrange(to, from) \ + to[0] = from[0]; \ + to[1] = from[4]; \ + to[2] = from[8]; \ + to[3] = from[12]; \ + to[4] = from[1]; \ + to[5] = from[5]; \ + to[6] = from[9]; \ + to[7] = from[13]; \ + to[8] = from[2]; \ + to[9] = from[6]; \ + to[10] = from[10]; \ + to[11] = from[14]; \ + to[12] = from[3]; \ + to[13] = from[7]; \ + to[14] = from[11]; \ + to[15] = from[15]; + +__INLINE __m512i inc_block32(__m512i x, const int8u *increment) { return mask_add_epi32(x, 0x1111, x, M512(increment)); } + +static __ALIGN64 const int8u initialInc[] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +#endif // SM4_GCM_MB_H diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_mb.h b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_mb.h new file mode 100644 index 000000000..7d5ca8240 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/include/internal/sm4/sm4_mb.h @@ -0,0 +1,858 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_SM4_GFNI_MB_H) +#define _SM4_GFNI_MB_H + +#include +#include + +#include + +#ifndef M128 +#define M128(mem) (*((__m128i*)(mem))) +#endif +#ifndef M256 +#define M256(mem) (*((__m256i*)(mem))) +#endif +#ifndef M512 +#define M512(mem) (*((__m512i*)(mem))) +#endif + +#define loadu _mm512_loadu_si512 +#define storeu _mm512_storeu_si512 + +#define mask_storeu_epi64 _mm512_mask_storeu_epi64 +#define maskz_expandloadu_epi32 _mm512_maskz_expandloadu_epi32 + +#define mask_storeu_epi8 _mm512_mask_storeu_epi8 +#define maskz_loadu_epi8 _mm512_maskz_loadu_epi8 + +#define srli_epi64 _mm512_srli_epi64 +#define slli_epi64 _mm512_slli_epi64 +#define bsrli_epi128 _mm512_bsrli_epi128 +#define bslli_epi128 _mm512_bslli_epi128 + +#define shuffle_epi8 _mm512_shuffle_epi8 +#define shuffle_epi32 _mm512_shuffle_epi32 + +#define set1_epi32 _mm512_set1_epi32 +#define set1_epi64 _mm512_set1_epi64 +#define setzero _mm512_setzero_si512 + +#define cmpeq_epi32_mask _mm512_cmpeq_epi32_mask +#define cmp_epi32_mask _mm512_cmp_epi32_mask +#define cmp_epi64_mask _mm512_cmp_epi64_mask + +#define mask_set1_epi32 _mm512_mask_set1_epi32 + +#define mask_sub_epi32 _mm512_mask_sub_epi32 +#define mask_add_epi32 _mm512_mask_add_epi32 +#define mask_add_epi64 _mm512_mask_add_epi64 +#define add_epi32 _mm512_add_epi32 +#define sub_epi32 _mm512_sub_epi32 +#define add_epi64 _mm512_add_epi64 + +#define or _mm512_or_si512 +#define and _mm512_and_si512 +#define xor _mm512_xor_si512 + +#define clmul _mm512_clmulepi64_epi128 + +#define unpacklo_epi32 _mm512_unpacklo_epi32 +#define unpackhi_epi32 _mm512_unpackhi_epi32 +#define unpacklo_epi64 _mm512_unpacklo_epi64 +#define unpackhi_epi64 _mm512_unpackhi_epi64 + +#define insert32x4 _mm512_inserti32x4 +#define sll_epi32 _mm512_sll_epi32 +#define srli_epi32 _mm512_srli_epi32 +#define mask_cmp_epi32_mask _mm512_mask_cmp_epi32_mask +#define broadcast_i64x2 _mm512_broadcast_i64x2 + +/* +// Constants +*/ + +static __ALIGN64 const int8u permMask_in[] = { + 0,0x00,0x00,0x00, 4,0x00,0x00,0x00, 8,0x00,0x00,0x00, 12,0x00,0x00,0x00, + 1,0x00,0x00,0x00, 5,0x00,0x00,0x00, 9,0x00,0x00,0x00, 13,0x00,0x00,0x00, + 2,0x00,0x00,0x00, 6,0x00,0x00,0x00, 10,0x00,0x00,0x00, 14,0x00,0x00,0x00, + 3,0x00,0x00,0x00, 7,0x00,0x00,0x00, 11,0x00,0x00,0x00, 15,0x00,0x00,0x00 +}; + +static __ALIGN64 const int8u permMask_out[] = { + 12,0x00,0x00,0x00, 8,0x00,0x00,0x00, 4,0x00,0x00,0x00, 0,0x00,0x00,0x00, + 13,0x00,0x00,0x00, 9,0x00,0x00,0x00, 5,0x00,0x00,0x00, 1,0x00,0x00,0x00, + 14,0x00,0x00,0x00, 10,0x00,0x00,0x00, 6,0x00,0x00,0x00, 2,0x00,0x00,0x00, + 15,0x00,0x00,0x00, 11,0x00,0x00,0x00, 7,0x00,0x00,0x00, 3,0x00,0x00,0x00 +}; + +static __ALIGN64 const int8u affineIn[] = { + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34 +}; + +static __ALIGN64 const int8u affineOut[] = { + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7 +}; +// Constant for swapping the bytes inside the words +static __ALIGN64 const int8u swapBytes[] = { + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 +}; +// Constant for swapping the endianness +static __ALIGN64 const int8u swapEndianness[] = { + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0, + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0, + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0, + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0 +}; +// Constant for swapping the order of words +static __ALIGN64 const int8u swapWordsOrder[] = { + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3, + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3, + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3, + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3 +}; + +static __ALIGN64 const int64u idx_0_3[] = { + 0x0000000000000000, 0x0000000000000000, 0x0000000100000001, 0x0000000100000001, + 0x0000000200000002, 0x0000000200000002, 0x0000000300000003, 0x0000000300000003 +}; +static __ALIGN64 const int64u idx_4_7[] = { + 0x0000000400000004, 0x0000000400000004, 0x0000000500000005, 0x0000000500000005, + 0x0000000600000006, 0x0000000600000006, 0x0000000700000007, 0x0000000700000007 +}; +static __ALIGN64 const int64u idx_8_b[] = { + 0x0000000800000008, 0x0000000800000008, 0x0000000900000009, 0x0000000900000009, + 0x0000000a0000000a, 0x0000000a0000000a, 0x0000000b0000000b, 0x0000000b0000000b +}; +static __ALIGN64 const int64u idx_c_f[] = { + 0x0000000c0000000c, 0x0000000c0000000c, 0x0000000d0000000d, 0x0000000d0000000d, + 0x0000000e0000000e, 0x0000000e0000000e, 0x0000000f0000000f, 0x0000000f0000000f +}; + + +static __ALIGN64 const int8u firstInc[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static __ALIGN64 const int8u nextInc[] = { + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +static __ALIGN64 const int8u shuf8[] = { + 0x01, 0x02, 0x03, 0x00, 0x05, 0x06, 0x07, 0x04, + 0x09, 0x0A, 0x0B, 0x08, 0x0D, 0x0E, 0x0F, 0x0C, + 0x01, 0x02, 0x03, 0x00, 0x05, 0x06, 0x07, 0x04, + 0x09, 0x0A, 0x0B, 0x08, 0x0D, 0x0E, 0x0F, 0x0C, + 0x01, 0x02, 0x03, 0x00, 0x05, 0x06, 0x07, 0x04, + 0x09, 0x0A, 0x0B, 0x08, 0x0D, 0x0E, 0x0F, 0x0C, + 0x01, 0x02, 0x03, 0x00, 0x05, 0x06, 0x07, 0x04, + 0x09, 0x0A, 0x0B, 0x08, 0x0D, 0x0E, 0x0F, 0x0C, +}; + +/* For SM4-XTS */ +static __ALIGN64 const int64u xts_poly[] = { + 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87 +}; + +static __ALIGN64 const int8u xts_shuf_mask[] = { + 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +static __ALIGN64 const int64u xts_const_dq3210[] = { + 0, 0, 1, 1, 2, 2, 3, 3 +}; + +static __ALIGN64 const int64u xts_const_dq5678[] = { + 8, 8, 7, 7, 6, 6, 5, 5 +}; + +static __ALIGN64 const int32u xts_full_block_mask[] = { + 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, + 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0 +}; + +static __ALIGN64 const int32u xts_partial_block_mask[] = { + 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, + 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f +}; + +static __ALIGN64 const int32u xts_dw0_7_to_qw_idx[] = { + 0, 0xFF, 1, 0xFF, 2, 0xFF, 3, 0xFF, + 4, 0xFF, 5, 0xFF, 6, 0xFF, 7, 0xFF +}; + +static __ALIGN64 const int32u xts_dw8_15_to_qw_idx[] = { + 8, 0xFF, 9, 0xFF, 10, 0xFF, 11, 0xFF, + 12, 0xFF, 13, 0xFF, 14, 0xFF, 15, 0xFF +}; + +static __ALIGN64 const int64u xts_tweak_permq[] = { + 2, 3, 0, 1, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 2, 3, 0xFF, 0xFF, + 0, 1, 2, 3, 6, 7, 4, 5, + 0, 1, 2, 3, 4, 5, 10, 11 /* for vpermi2q */ +}; + +static __ALIGN64 const int64u xts_next_tweak_permq[] = { + 0, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 14, 15, 0, 1, 0xFF, 0xFF, 0xFF, 0xFF /* for vpermi2q */ +}; + +static __ALIGN64 const int64u xts_next_tweak_permq_enc[] = { + 2, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +#define SM4_ONE_ROUND(X0, X1, X2, X3, TMP, RK) { \ + /* (Xi+1 ^ Xi+2 ^ Xi+3 ^ rki) */ \ + TMP = _mm512_ternarylogic_epi32 (X1, X2, X3, 0x96); \ + TMP = _mm512_xor_epi32(TMP, _mm512_loadu_si512(RK)); \ + /* T(Xi+1 ^ Xi+2 ^ Xi+3 ^ rki) */ \ + TMP = sBox512(TMP); \ + X0 = _mm512_ternarylogic_epi64 (X0, TMP, Lblock512(TMP), 0x96); \ +} + +#define SM4_FOUR_ROUNDS(X0, X1, X2, X3, TMP, RK, sign) { \ + SM4_ONE_ROUND(X0, X1, X2, X3, TMP, RK); \ + SM4_ONE_ROUND(X1, X2, X3, X0, TMP, (RK + sign * 1)); \ + SM4_ONE_ROUND(X2, X3, X0, X1, TMP, (RK + sign * 2)); \ + SM4_ONE_ROUND(X3, X0, X1, X2, TMP, (RK + sign * 3)); \ +} + +#define SM4_ONE_ROUND_MASKED(X0, X1, X2, X3, TMP, MASK, RK) { \ + /* (Xi+1 ^ Xi+2 ^ Xi+3 ^ rki) */ \ + TMP = _mm512_xor_epi32(_mm512_xor_epi32(_mm512_xor_epi32(X1, X2), X3), _mm512_loadu_si512(RK)); \ + /* T(Xi+1 ^ Xi+2 ^ Xi+3 ^ rki) */ \ + TMP = sBox512(TMP); \ + TMP = _mm512_xor_epi32(TMP, Lblock512(TMP)); \ + /* Xi+4 = Xi ^ T(Xi+1 ^ Xi+2 ^ Xi+3 ^ rki) */ \ + X0 = _mm512_mask_xor_epi32(X0, MASK, X0, TMP); \ +} + +#define SM4_FOUR_ROUNDS_MASKED(X0, X1, X2, X3, TMP, MASK, RK, sign) { \ + SM4_ONE_ROUND_MASKED(X0, X1, X2, X3, TMP, MASK, RK); \ + SM4_ONE_ROUND_MASKED(X1, X2, X3, X0, TMP, MASK, (RK + sign * 1)); \ + SM4_ONE_ROUND_MASKED(X2, X3, X0, X1, TMP, MASK, (RK + sign * 2)); \ + SM4_ONE_ROUND_MASKED(X3, X0, X1, X2, TMP, MASK, (RK + sign * 3)); \ +} + +#define EXPAND_ONE_RKEY(X, p_rk) { \ + X[0] = _mm512_permutexvar_epi32(M512(idx_0_3), _mm512_loadu_si512(p_rk)); \ + X[1] = _mm512_permutexvar_epi32(M512(idx_4_7), _mm512_loadu_si512(p_rk)); \ + X[2] = _mm512_permutexvar_epi32(M512(idx_8_b), _mm512_loadu_si512(p_rk)); \ + X[3] = _mm512_permutexvar_epi32(M512(idx_c_f), _mm512_loadu_si512(p_rk)); \ +} + +#define ENDIANNESS_16x32(x) _mm512_shuffle_epi8((x), M512(swapBytes)); +#define CHANGE_ORDER_BLOCKS(x) _mm512_shuffle_epi8((x), M512(swapEndianness)); + +/* Workaround for gcc91, got the error: implicit declaration of function ‘_mm512_div_epi32’ */ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +#define GET_NUM_BLOCKS(OUT, LEN, BLOCK_SIZE) \ + { \ + int32u blocks[SM4_LINES]; \ + for (int i = 0; i < SM4_LINES; i++) \ + blocks[i] = (LEN)[i] / (BLOCK_SIZE); \ + (OUT) = _mm512_loadu_si512(blocks); \ + } +#else +#define GET_NUM_BLOCKS(OUT, LEN, BLOCK_SIZE) (OUT) = _mm512_div_epi32(_mm512_loadu_si512(LEN), _mm512_set1_epi32(BLOCK_SIZE)) +#endif + +#define UPDATE_STREAM_MASK_16(MASK, p_len) \ + MASK = *p_len < (16) ? (*p_len <= 0 ? 0 : ((int64u)1 << *p_len) - 1) : (__mmask64)(0xFFFF); p_len++; +#define UPDATE_STREAM_MASK_64(MASK, p_len) MASK = *p_len < (4 * 16) ? (*p_len <= 0 ? 0 : ((int64u)1 << *p_len) - 1) : (__mmask64)(-1); p_len++; + +#define SM4_ENC (1) +#define SM4_DEC (-1) + +/* +// Internal functions +*/ + +EXTERN_C void sm4_ecb_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, int operation); +EXTERN_C void sm4_cbc_enc_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, const int8u* pa_iv[SM4_LINES]); +EXTERN_C void sm4_cbc_dec_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, const int8u* pa_iv[SM4_LINES]); +EXTERN_C void sm4_cbc_mac_kernel_mb16(__m128i pa_out[SM4_LINES], const int8u *const pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, const int8u* pa_iv[SM4_LINES]); +EXTERN_C void sm4_ctr128_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, int8u* pa_ctr[SM4_LINES]); +EXTERN_C void sm4_ofb_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, int8u* pa_iv[SM4_LINES]); +EXTERN_C void sm4_cfb128_enc_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], const int8u* pa_iv[SM4_LINES], __mmask16 mb_mask); +EXTERN_C void sm4_cfb128_dec_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], const int8u* pa_iv[SM4_LINES], __mmask16 mb_mask); +EXTERN_C void sm4_set_round_keys_mb16(int32u* key_sched[SM4_ROUNDS], const int8u* pa_inp_key[SM4_LINES], __mmask16 mb_mask); +EXTERN_C void sm4_xts_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], + const int32u* key_sched1[SM4_ROUNDS], const int32u* key_sched2[SM4_ROUNDS], + const int8u* pa_tweak[SM4_LINES], __mmask16 mb_mask, const int dir); + +// The transformation based on SM4 sbox algebraic structure, parameters were computed manually +__INLINE __m512i sBox512(__m512i block) +{ + block = _mm512_gf2p8affine_epi64_epi8(block, M512(affineIn), 0x65); + block = _mm512_gf2p8affineinv_epi64_epi8(block, M512(affineOut), 0xd3); + return block; +} + +__INLINE __m512i Lblock512(__m512i x) +{ + return _mm512_ternarylogic_epi32(_mm512_xor_si512(_mm512_rol_epi32(x, 2), _mm512_rol_epi32(x, 10)), _mm512_rol_epi32(x, 18), + _mm512_shuffle_epi8 (x, _mm512_loadu_si512(shuf8)), 0x96); +} + +__INLINE __m512i Lkey512(__m512i x) +{ + return _mm512_xor_epi32(_mm512_rol_epi32(x, 13), _mm512_rol_epi32(x, 23)); +} + +__INLINE __m512i IncBlock512(__m512i x, const int8u* increment) +{ + __m512i t = _mm512_add_epi64(x, M512(increment)); + __mmask8 carryMask = _mm512_cmplt_epu64_mask(t, x); + carryMask = (__mmask8)(carryMask << 1); + t = _mm512_add_epi64(t, _mm512_mask_set1_epi64(_mm512_setzero_si512(), carryMask, 1)); + + return t; +} + +#define SM4_KERNEL(TMP, p_rk, iterator) \ + for (int itr = 0, j = 0; itr < 8; itr++, j++) { \ + /* initial xors */ \ + EXPAND_ONE_RKEY(TMP, p_rk); p_rk+=iterator; \ + TMP[0] = _mm512_ternarylogic_epi32 (TMP[0], TMP[5], TMP[6], 0x96); \ + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); \ + TMP[1] = _mm512_ternarylogic_epi32 (TMP[1], TMP[9], TMP[10], 0x96); \ + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); \ + TMP[2] = _mm512_ternarylogic_epi32 (TMP[2], TMP[13], TMP[14], 0x96); \ + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); \ + TMP[3] = _mm512_ternarylogic_epi32 (TMP[3], TMP[17], TMP[18], 0x96); \ + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); \ + /* Sbox */ \ + TMP[0] = sBox512(TMP[0]); \ + TMP[1] = sBox512(TMP[1]); \ + TMP[2] = sBox512(TMP[2]); \ + TMP[3] = sBox512(TMP[3]); \ + /* Sbox done, now L */ \ + TMP[4] = _mm512_ternarylogic_epi32(TMP[4], TMP[0], Lblock512(TMP[0]), 0x96); \ + TMP[8] = _mm512_ternarylogic_epi32(TMP[8], TMP[1], Lblock512(TMP[1]), 0x96); \ + TMP[12] = _mm512_ternarylogic_epi32(TMP[12], TMP[2], Lblock512(TMP[2]), 0x96); \ + TMP[16] = _mm512_ternarylogic_epi32(TMP[16], TMP[3], Lblock512(TMP[3]), 0x96); \ + /* initial xors */ \ + EXPAND_ONE_RKEY(TMP, p_rk); p_rk+=iterator; \ + TMP[0] = _mm512_ternarylogic_epi32 (TMP[0], TMP[6], TMP[7], 0x96); \ + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); \ + TMP[1] = _mm512_ternarylogic_epi32 (TMP[1], TMP[10], TMP[11], 0x96); \ + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); \ + TMP[2] = _mm512_ternarylogic_epi32 (TMP[2], TMP[14], TMP[15], 0x96); \ + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); \ + TMP[3] = _mm512_ternarylogic_epi32 (TMP[3], TMP[18], TMP[19], 0x96); \ + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); \ + /* Sbox */ \ + TMP[0] = sBox512(TMP[0]); \ + TMP[1] = sBox512(TMP[1]); \ + TMP[2] = sBox512(TMP[2]); \ + TMP[3] = sBox512(TMP[3]); \ + /* Sbox done, now L */ \ + TMP[5] = _mm512_ternarylogic_epi32(TMP[5], TMP[0], Lblock512(TMP[0]), 0x96); \ + TMP[9] = _mm512_ternarylogic_epi32(TMP[9], TMP[1], Lblock512(TMP[1]), 0x96); \ + TMP[13] = _mm512_ternarylogic_epi32(TMP[13], TMP[2], Lblock512(TMP[2]), 0x96); \ + TMP[17] = _mm512_ternarylogic_epi32(TMP[17], TMP[3], Lblock512(TMP[3]), 0x96); \ + \ + /* initial xors */ \ + EXPAND_ONE_RKEY(TMP, p_rk); p_rk+=iterator; \ + TMP[0] = _mm512_ternarylogic_epi32 (TMP[0], TMP[7], TMP[4], 0x96); \ + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); \ + TMP[1] = _mm512_ternarylogic_epi32 (TMP[1], TMP[11], TMP[8], 0x96); \ + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); \ + TMP[2] = _mm512_ternarylogic_epi32 (TMP[2], TMP[15], TMP[12], 0x96); \ + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); \ + TMP[3] = _mm512_ternarylogic_epi32 (TMP[3], TMP[19], TMP[16], 0x96); \ + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); \ + /* Sbox */ \ + TMP[0] = sBox512(TMP[0]); \ + TMP[1] = sBox512(TMP[1]); \ + TMP[2] = sBox512(TMP[2]); \ + TMP[3] = sBox512(TMP[3]); \ + /* Sbox done, now L */ \ + TMP[6] = _mm512_ternarylogic_epi32(TMP[6], TMP[0], Lblock512(TMP[0]), 0x96); \ + TMP[10] = _mm512_ternarylogic_epi32(TMP[10], TMP[1], Lblock512(TMP[1]), 0x96); \ + TMP[14] = _mm512_ternarylogic_epi32(TMP[14], TMP[2], Lblock512(TMP[2]), 0x96); \ + TMP[18] = _mm512_ternarylogic_epi32(TMP[18], TMP[3], Lblock512(TMP[3]), 0x96); \ + \ + /* initial xors */ \ + EXPAND_ONE_RKEY(TMP, p_rk); p_rk+=iterator; \ + TMP[0] = _mm512_ternarylogic_epi32 (TMP[0], TMP[4], TMP[5], 0x96); \ + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); \ + TMP[1] = _mm512_ternarylogic_epi32 (TMP[1], TMP[8], TMP[9], 0x96); \ + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); \ + TMP[2] = _mm512_ternarylogic_epi32 (TMP[2], TMP[12], TMP[13], 0x96); \ + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); \ + TMP[3] = _mm512_ternarylogic_epi32 (TMP[3], TMP[16], TMP[17], 0x96); \ + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); \ + /* Sbox */ \ + TMP[0] = sBox512(TMP[0]); \ + TMP[1] = sBox512(TMP[1]); \ + TMP[2] = sBox512(TMP[2]); \ + TMP[3] = sBox512(TMP[3]); \ + /* Sbox done, now L */ \ + TMP[7] = _mm512_ternarylogic_epi32(TMP[7], TMP[0], Lblock512(TMP[0]), 0x96); \ + TMP[11] = _mm512_ternarylogic_epi32(TMP[11], TMP[1], Lblock512(TMP[1]), 0x96); \ + TMP[15] = _mm512_ternarylogic_epi32(TMP[15], TMP[2], Lblock512(TMP[2]), 0x96); \ + TMP[19] = _mm512_ternarylogic_epi32(TMP[19], TMP[3], Lblock512(TMP[3]), 0x96); \ + } + +/* +// Transpose functions +*/ + +#define TRANSPOSE_INP_512(K0,K1,K2,K3, T0,T1,T2,T3) \ + K0 = _mm512_unpacklo_epi32(T0, T1); \ + K1 = _mm512_unpacklo_epi32(T2, T3); \ + K2 = _mm512_unpackhi_epi32(T0, T1); \ + K3 = _mm512_unpackhi_epi32(T2, T3); \ + \ + T0 = _mm512_unpacklo_epi64(K0, K1); \ + T1 = _mm512_unpacklo_epi64(K2, K3); \ + T2 = _mm512_unpackhi_epi64(K0, K1); \ + T3 = _mm512_unpackhi_epi64(K2, K3); \ + \ + K2 = _mm512_permutexvar_epi32(M512(permMask_in), T1); \ + K1 = _mm512_permutexvar_epi32(M512(permMask_in), T2); \ + K3 = _mm512_permutexvar_epi32(M512(permMask_in), T3); \ + K0 = _mm512_permutexvar_epi32(M512(permMask_in), T0) + +#define TRANSPOSE_OUT_512(T0,T1,T2,T3, K0,K1,K2,K3) \ + T0 = _mm512_shuffle_i32x4(K0, K1, 0x44); \ + T1 = _mm512_shuffle_i32x4(K0, K1, 0xee); \ + T2 = _mm512_shuffle_i32x4(K2, K3, 0x44); \ + T3 = _mm512_shuffle_i32x4(K2, K3, 0xee); \ + \ + K0 = _mm512_shuffle_i32x4(T0, T2, 0x88); \ + K1 = _mm512_shuffle_i32x4(T0, T2, 0xdd); \ + K2 = _mm512_shuffle_i32x4(T1, T3, 0x88); \ + K3 = _mm512_shuffle_i32x4(T1, T3, 0xdd); \ + \ + K0 = _mm512_permutexvar_epi32(M512(permMask_out), K0);\ + K1 = _mm512_permutexvar_epi32(M512(permMask_out), K1);\ + K2 = _mm512_permutexvar_epi32(M512(permMask_out), K2);\ + K3 = _mm512_permutexvar_epi32(M512(permMask_out), K3);\ + \ + T0=K0,T1=K1,T2=K2,T3=K3 + +__INLINE void TRANSPOSE_16x4_I32_EPI32(__m512i* t0, __m512i* t1, __m512i* t2, __m512i* t3, const int8u* p_inp[16], __mmask16 mb_mask) { + __mmask16 loc_mb_mask = mb_mask; + + // L0 - L3 + __m512i z0 = _mm512_maskz_loadu_epi32(0x000F * (0x1&loc_mb_mask), p_inp[0]); loc_mb_mask >>= 1; + __m512i z1 = _mm512_maskz_loadu_epi32(0x000F * (0x1&loc_mb_mask), p_inp[1]); loc_mb_mask >>= 1; + __m512i z2 = _mm512_maskz_loadu_epi32(0x000F * (0x1&loc_mb_mask), p_inp[2]); loc_mb_mask >>= 1; + __m512i z3 = _mm512_maskz_loadu_epi32(0x000F * (0x1&loc_mb_mask), p_inp[3]); loc_mb_mask >>= 1; + + // L4 - L7 + z0 = _mm512_mask_loadu_epi32(z0, 0x00F0 * (0x1&loc_mb_mask), (__m128i*)p_inp[4] - 1); loc_mb_mask >>= 1; + z1 = _mm512_mask_loadu_epi32(z1, 0x00F0 * (0x1&loc_mb_mask), (__m128i*)p_inp[5] - 1); loc_mb_mask >>= 1; + z2 = _mm512_mask_loadu_epi32(z2, 0x00F0 * (0x1&loc_mb_mask), (__m128i*)p_inp[6] - 1); loc_mb_mask >>= 1; + z3 = _mm512_mask_loadu_epi32(z3, 0x00F0 * (0x1&loc_mb_mask), (__m128i*)p_inp[7] - 1); loc_mb_mask >>= 1; + + // L8 - Lb + z0 = _mm512_mask_loadu_epi32(z0, 0x0F00 * (0x1&loc_mb_mask), (__m128i*)p_inp[8] - 2); loc_mb_mask >>= 1; + z1 = _mm512_mask_loadu_epi32(z1, 0x0F00 * (0x1&loc_mb_mask), (__m128i*)p_inp[9] - 2); loc_mb_mask >>= 1; + z2 = _mm512_mask_loadu_epi32(z2, 0x0F00 * (0x1&loc_mb_mask), (__m128i*)p_inp[10] - 2); loc_mb_mask >>= 1; + z3 = _mm512_mask_loadu_epi32(z3, 0x0F00 * (0x1&loc_mb_mask), (__m128i*)p_inp[11] - 2); loc_mb_mask >>= 1; + + // Lc - Lf + *t0 = ENDIANNESS_16x32(_mm512_mask_loadu_epi32(z0, 0xF000 * (0x1&loc_mb_mask), (__m128i*)p_inp[12] - 3)); loc_mb_mask >>= 1; + *t1 = ENDIANNESS_16x32(_mm512_mask_loadu_epi32(z1, 0xF000 * (0x1&loc_mb_mask), (__m128i*)p_inp[13] - 3)); loc_mb_mask >>= 1; + *t2 = ENDIANNESS_16x32(_mm512_mask_loadu_epi32(z2, 0xF000 * (0x1&loc_mb_mask), (__m128i*)p_inp[14] - 3)); loc_mb_mask >>= 1; + *t3 = ENDIANNESS_16x32(_mm512_mask_loadu_epi32(z3, 0xF000 * (0x1&loc_mb_mask), (__m128i*)p_inp[15] - 3)); loc_mb_mask >>= 1; + + z0 = _mm512_unpacklo_epi32(*t0, *t1); + z1 = _mm512_unpackhi_epi32(*t0, *t1); + z2 = _mm512_unpacklo_epi32(*t2, *t3); + z3 = _mm512_unpackhi_epi32(*t2, *t3); + + *t0 = _mm512_unpacklo_epi64(z0, z2); + *t1 = _mm512_unpackhi_epi64(z0, z2); + *t2 = _mm512_unpacklo_epi64(z1, z3); + *t3 = _mm512_unpackhi_epi64(z1, z3); +} + +__INLINE void TRANSPOSE_16x4_I32_XMM_EPI32(__m512i* t0, __m512i* t1, __m512i* t2, __m512i* t3, const __m128i in[16]) { + // L0 - L3 + __m512i z0 = _mm512_castsi128_si512(in[0]); + __m512i z1 = _mm512_castsi128_si512(in[1]); + __m512i z2 = _mm512_castsi128_si512(in[2]); + __m512i z3 = _mm512_castsi128_si512(in[3]); + + // L4 - L7 + z0 = _mm512_inserti64x2(z0, in[4], 1); + z1 = _mm512_inserti64x2(z1, in[5], 1); + z2 = _mm512_inserti64x2(z2, in[6], 1); + z3 = _mm512_inserti64x2(z3, in[7], 1); + + // L8 - Lb + z0 = _mm512_inserti64x2(z0, in[8], 2); + z1 = _mm512_inserti64x2(z1, in[9], 2); + z2 = _mm512_inserti64x2(z2, in[10], 2); + z3 = _mm512_inserti64x2(z3, in[11], 2); + + // Lc - Lf + *t0 = ENDIANNESS_16x32(_mm512_inserti64x2(z0, in[12], 3)); + *t1 = ENDIANNESS_16x32(_mm512_inserti64x2(z1, in[13], 3)); + *t2 = ENDIANNESS_16x32(_mm512_inserti64x2(z2, in[14], 3)); + *t3 = ENDIANNESS_16x32(_mm512_inserti64x2(z3, in[15], 3)); + + z0 = _mm512_unpacklo_epi32(*t0, *t1); + z1 = _mm512_unpackhi_epi32(*t0, *t1); + z2 = _mm512_unpacklo_epi32(*t2, *t3); + z3 = _mm512_unpackhi_epi32(*t2, *t3); + + *t0 = _mm512_unpacklo_epi64(z0, z2); + *t1 = _mm512_unpackhi_epi64(z0, z2); + *t2 = _mm512_unpacklo_epi64(z1, z3); + *t3 = _mm512_unpackhi_epi64(z1, z3); +} + +__INLINE void TRANSPOSE_4x16_I32_EPI32(__m512i* t0, __m512i* t1, __m512i* t2, __m512i* t3, int8u* p_out[16], __mmask16 mb_mask) { + + #define STORE_RESULT(OUT, store_mask, loc_mb_mask, Ti) \ + _mm512_mask_storeu_epi32(OUT, store_mask * (0x1&loc_mb_mask), Ti); \ + loc_mb_mask >>= 1; + + __mmask16 loc_mb_mask = mb_mask; + + __m512i z0 = _mm512_unpacklo_epi32(*t0, *t1); + __m512i z1 = _mm512_unpackhi_epi32(*t0, *t1); + __m512i z2 = _mm512_unpacklo_epi32(*t2, *t3); + __m512i z3 = _mm512_unpackhi_epi32(*t2, *t3); + + /* Get the right endianness and do (Y0, Y1, Y2, Y3) = R(X32, X33, X34, X35) = (X35, X34, X33, X32) */ + *t0 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z0, z2)); + *t1 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z0, z2)); + *t2 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z1, z3)); + *t3 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z1, z3)); + + // L0 - L3 + STORE_RESULT(p_out[0], 0x000F, loc_mb_mask, *t0); + STORE_RESULT(p_out[1], 0x000F, loc_mb_mask, *t1); + STORE_RESULT(p_out[2], 0x000F, loc_mb_mask, *t2); + STORE_RESULT(p_out[3], 0x000F, loc_mb_mask, *t3); + + // L4 - L7 + STORE_RESULT((__m128i*)p_out[4] - 1, 0x00F0, loc_mb_mask, *t0); + STORE_RESULT((__m128i*)p_out[5] - 1, 0x00F0, loc_mb_mask, *t1); + STORE_RESULT((__m128i*)p_out[6] - 1, 0x00F0, loc_mb_mask, *t2); + STORE_RESULT((__m128i*)p_out[7] - 1, 0x00F0, loc_mb_mask, *t3); + + // L8 - Lb + STORE_RESULT((__m128i*)p_out[8] - 2, 0x0F00, loc_mb_mask, *t0); + STORE_RESULT((__m128i*)p_out[9] - 2, 0x0F00, loc_mb_mask, *t1); + STORE_RESULT((__m128i*)p_out[10] - 2, 0x0F00, loc_mb_mask, *t2); + STORE_RESULT((__m128i*)p_out[11] - 2, 0x0F00, loc_mb_mask, *t3); + + // Lc - Lf + STORE_RESULT((__m128i*)p_out[12] - 3, 0xF000, loc_mb_mask, *t0); + STORE_RESULT((__m128i*)p_out[13] - 3, 0xF000, loc_mb_mask, *t1); + STORE_RESULT((__m128i*)p_out[14] - 3, 0xF000, loc_mb_mask, *t2); + STORE_RESULT((__m128i*)p_out[15] - 3, 0xF000, loc_mb_mask, *t3); + +} + +__INLINE void TRANSPOSE_4x16_I32_XMM_EPI32(__m512i* t0, __m512i* t1, __m512i* t2, __m512i* t3, __m128i out[16]) { + + __m512i z0 = _mm512_unpacklo_epi32(*t0, *t1); + __m512i z1 = _mm512_unpackhi_epi32(*t0, *t1); + __m512i z2 = _mm512_unpacklo_epi32(*t2, *t3); + __m512i z3 = _mm512_unpackhi_epi32(*t2, *t3); + + /* Get the right endianness and do (Y0, Y1, Y2, Y3) = R(X32, X33, X34, X35) = (X35, X34, X33, X32) */ + *t0 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z0, z2)); + *t1 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z0, z2)); + *t2 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z1, z3)); + *t3 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z1, z3)); + + // L0 - L3 + out[0] = _mm512_extracti64x2_epi64(*t0, 0); + out[1] = _mm512_extracti64x2_epi64(*t1, 0); + out[2] = _mm512_extracti64x2_epi64(*t2, 0); + out[3] = _mm512_extracti64x2_epi64(*t3, 0); + + // L4 - L7 + out[4] = _mm512_extracti64x2_epi64(*t0, 1); + out[5] = _mm512_extracti64x2_epi64(*t1, 1); + out[6] = _mm512_extracti64x2_epi64(*t2, 1); + out[7] = _mm512_extracti64x2_epi64(*t3, 1); + + // L8 - Lb + out[8] = _mm512_extracti64x2_epi64(*t0, 2); + out[9] = _mm512_extracti64x2_epi64(*t1, 2); + out[10] = _mm512_extracti64x2_epi64(*t2, 2); + out[11] = _mm512_extracti64x2_epi64(*t3, 2); + + // Lc - Lf + out[12] = _mm512_extracti64x2_epi64(*t0, 3); + out[13] = _mm512_extracti64x2_epi64(*t1, 3); + out[14] = _mm512_extracti64x2_epi64(*t2, 3); + out[15] = _mm512_extracti64x2_epi64(*t3, 3); + +} + +__INLINE void TRANSPOSE_4x16_I32_O128_EPI32(__m512i* t0, __m512i* t1, __m512i* t2, __m512i* t3, __m128i p_out[16], __mmask16 mb_mask) { + + #define STORE_RESULT(OUT, store_mask, loc_mb_mask, Ti) \ + _mm512_mask_storeu_epi32(OUT, store_mask * (0x1&loc_mb_mask), Ti); \ + loc_mb_mask >>= 1; + + __mmask16 loc_mb_mask = mb_mask; + + __m512i z0 = _mm512_unpacklo_epi32(*t0, *t1); + __m512i z1 = _mm512_unpackhi_epi32(*t0, *t1); + __m512i z2 = _mm512_unpacklo_epi32(*t2, *t3); + __m512i z3 = _mm512_unpackhi_epi32(*t2, *t3); + + /* Get the right endianness and do (Y0, Y1, Y2, Y3) = R(X32, X33, X34, X35) = (X35, X34, X33, X32) */ + *t0 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z0, z2)); + *t1 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z0, z2)); + *t2 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z1, z3)); + *t3 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z1, z3)); + + // L0 - L3 + STORE_RESULT(&p_out[0], 0x000F, loc_mb_mask, *t0); + STORE_RESULT(&p_out[1], 0x000F, loc_mb_mask, *t1); + STORE_RESULT(&p_out[2], 0x000F, loc_mb_mask, *t2); + STORE_RESULT(&p_out[3], 0x000F, loc_mb_mask, *t3); + + // L4 - L7 + STORE_RESULT(&p_out[4] - 1, 0x00F0, loc_mb_mask, *t0); + STORE_RESULT(&p_out[5] - 1, 0x00F0, loc_mb_mask, *t1); + STORE_RESULT(&p_out[6] - 1, 0x00F0, loc_mb_mask, *t2); + STORE_RESULT(&p_out[7] - 1, 0x00F0, loc_mb_mask, *t3); + + // L8 - Lb + STORE_RESULT(&p_out[8] - 2, 0x0F00, loc_mb_mask, *t0); + STORE_RESULT(&p_out[9] - 2, 0x0F00, loc_mb_mask, *t1); + STORE_RESULT(&p_out[10] - 2, 0x0F00, loc_mb_mask, *t2); + STORE_RESULT(&p_out[11] - 2, 0x0F00, loc_mb_mask, *t3); + + // Lc - Lf + STORE_RESULT(&p_out[12] - 3, 0xF000, loc_mb_mask, *t0); + STORE_RESULT(&p_out[13] - 3, 0xF000, loc_mb_mask, *t1); + STORE_RESULT(&p_out[14] - 3, 0xF000, loc_mb_mask, *t2); + STORE_RESULT(&p_out[15] - 3, 0xF000, loc_mb_mask, *t3); + +} + +__INLINE void TRANSPOSE_4x16_I32_EPI8(__m512i t0, __m512i t1, __m512i t2, __m512i t3, int8u* p_out[16], int* p_loc_len, __mmask16 mb_mask) { + + #define STORE_RESULT_EPI8(OUT, store_mask, loc_mb_mask, Ti) \ + _mm512_mask_storeu_epi8(OUT, store_mask * (0x1&loc_mb_mask), Ti); \ + loc_mb_mask >>= 1; + + __mmask16 loc_mb_mask = mb_mask; + /* Mask for data loading */ + __mmask64 stream_mask; + + __m512i z0 = _mm512_unpacklo_epi32(t0, t1); + __m512i z1 = _mm512_unpackhi_epi32(t0, t1); + __m512i z2 = _mm512_unpacklo_epi32(t2, t3); + __m512i z3 = _mm512_unpackhi_epi32(t2, t3); + + /* Get the right endianness */ + t0 = ENDIANNESS_16x32(_mm512_unpacklo_epi64(z0, z2)); + t1 = ENDIANNESS_16x32(_mm512_unpackhi_epi64(z0, z2)); + t2 = ENDIANNESS_16x32(_mm512_unpacklo_epi64(z1, z3)); + t3 = ENDIANNESS_16x32(_mm512_unpackhi_epi64(z1, z3)); + + // L0 - L3 + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8(p_out[0], stream_mask, loc_mb_mask, t0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8(p_out[1], stream_mask, loc_mb_mask, t1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8(p_out[2], stream_mask, loc_mb_mask, t2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8(p_out[3], stream_mask, loc_mb_mask, t3); + + // L4 - L7 + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[4] - 1, stream_mask << 16, loc_mb_mask, t0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[5] - 1, stream_mask << 16, loc_mb_mask, t1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[6] - 1, stream_mask << 16, loc_mb_mask, t2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[7] - 1, stream_mask << 16, loc_mb_mask, t3); + + // L8 - Lb + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[8] - 2, stream_mask << 32, loc_mb_mask, t0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[9] - 2, stream_mask << 32, loc_mb_mask, t1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[10] - 2, stream_mask << 32, loc_mb_mask, t2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[11] - 2, stream_mask << 32, loc_mb_mask, t3); + + // Lc - Lf + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[12] - 3, stream_mask << 48, loc_mb_mask, t0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[13] - 3, stream_mask << 48, loc_mb_mask, t1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[14] - 3, stream_mask << 48, loc_mb_mask, t2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + STORE_RESULT_EPI8((__m128i*)p_out[15] - 3, stream_mask << 48, loc_mb_mask, t3); +} + +__INLINE void TRANSPOSE_AND_XOR_4x16_I32_EPI32(__m512i* t0, __m512i* t1, __m512i* t2, __m512i* t3, int8u* p_out[16], const int8u* p_iv[16], __mmask16 mb_mask) { + + #define XOR_AND_STORE_RESULT(OUT, store_mask, loc_mb_mask, Ti, IV, TMP) \ + TMP = _mm512_maskz_loadu_epi32(store_mask * (0x1&loc_mb_mask), IV); \ + _mm512_mask_storeu_epi32(OUT, store_mask * (0x1&loc_mb_mask), _mm512_xor_epi32(Ti, TMP)); \ + loc_mb_mask >>= 1; + + __m512i z0 = _mm512_setzero_si512(); + __m512i z1 = _mm512_setzero_si512(); + __m512i z2 = _mm512_setzero_si512(); + __m512i z3 = _mm512_setzero_si512(); + + __mmask16 loc_mb_mask = mb_mask; + + z0 = _mm512_unpacklo_epi32(*t0, *t1); + z1 = _mm512_unpackhi_epi32(*t0, *t1); + z2 = _mm512_unpacklo_epi32(*t2, *t3); + z3 = _mm512_unpackhi_epi32(*t2, *t3); + + /* Get the right endianness and do (Y0, Y1, Y2, Y3) = R(X32, X33, X34, X35) = (X35, X34, X33, X32) */ + *t0 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z0, z2)); + *t1 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z0, z2)); + *t2 = CHANGE_ORDER_BLOCKS(_mm512_unpacklo_epi64(z1, z3)); + *t3 = CHANGE_ORDER_BLOCKS(_mm512_unpackhi_epi64(z1, z3)); + + // L0 - L3 + XOR_AND_STORE_RESULT(p_out[0], 0x000F, loc_mb_mask, *t0, p_iv[0], z0); + XOR_AND_STORE_RESULT(p_out[1], 0x000F, loc_mb_mask, *t1, p_iv[1], z1); + XOR_AND_STORE_RESULT(p_out[2], 0x000F, loc_mb_mask, *t2, p_iv[2], z2); + XOR_AND_STORE_RESULT(p_out[3], 0x000F, loc_mb_mask, *t3, p_iv[3], z3); + + // L4 - L7 + XOR_AND_STORE_RESULT((__m128i*)p_out[4] - 1, 0x00F0, loc_mb_mask, *t0, (__m128i*)p_iv[4] - 1, z0); + XOR_AND_STORE_RESULT((__m128i*)p_out[5] - 1, 0x00F0, loc_mb_mask, *t1, (__m128i*)p_iv[5] - 1, z1); + XOR_AND_STORE_RESULT((__m128i*)p_out[6] - 1, 0x00F0, loc_mb_mask, *t2, (__m128i*)p_iv[6] - 1, z2); + XOR_AND_STORE_RESULT((__m128i*)p_out[7] - 1, 0x00F0, loc_mb_mask, *t3, (__m128i*)p_iv[7] - 1, z3); + + // L8 - Lb + XOR_AND_STORE_RESULT((__m128i*)p_out[8] - 2, 0x0F00, loc_mb_mask, *t0, (__m128i*)p_iv[8] - 2, z0); + XOR_AND_STORE_RESULT((__m128i*)p_out[9] - 2, 0x0F00, loc_mb_mask, *t1, (__m128i*)p_iv[9] - 2, z1); + XOR_AND_STORE_RESULT((__m128i*)p_out[10] - 2, 0x0F00, loc_mb_mask, *t2, (__m128i*)p_iv[10] - 2, z2); + XOR_AND_STORE_RESULT((__m128i*)p_out[11] - 2, 0x0F00, loc_mb_mask, *t3, (__m128i*)p_iv[11] - 2, z3); + + // Lc - Lf + XOR_AND_STORE_RESULT((__m128i*)p_out[12] - 3, 0xF000, loc_mb_mask, *t0, (__m128i*)p_iv[12] - 3, z0); + XOR_AND_STORE_RESULT((__m128i*)p_out[13] - 3, 0xF000, loc_mb_mask, *t1, (__m128i*)p_iv[13] - 3, z1); + XOR_AND_STORE_RESULT((__m128i*)p_out[14] - 3, 0xF000, loc_mb_mask, *t2, (__m128i*)p_iv[14] - 3, z2); + XOR_AND_STORE_RESULT((__m128i*)p_out[15] - 3, 0xF000, loc_mb_mask, *t3, (__m128i*)p_iv[15] - 3, z3); +} + +__INLINE void TRANSPOSE_AND_XOR_4x16_I32_EPI8(__m512i t0, __m512i t1, __m512i t2, __m512i t3, int8u* p_out[16], const int8u* p_iv[16], int* p_loc_len, __mmask16 mb_mask) { + + #define XOR_AND_STORE_RESULT_EPI8(OUT, store_mask, loc_mb_mask, Ti, IV, TMP) \ + TMP = _mm512_maskz_loadu_epi8(store_mask * (0x1&loc_mb_mask), IV); \ + _mm512_mask_storeu_epi8(OUT, store_mask * (0x1&loc_mb_mask), _mm512_xor_epi32(Ti, TMP)); \ + loc_mb_mask >>= 1; + + __m512i z0 = _mm512_setzero_si512(); + __m512i z1 = _mm512_setzero_si512(); + __m512i z2 = _mm512_setzero_si512(); + __m512i z3 = _mm512_setzero_si512(); + + __mmask16 loc_mb_mask = mb_mask; + /* Mask for data loading */ + __mmask64 stream_mask; + + z0 = _mm512_unpacklo_epi32(t0, t1); + z1 = _mm512_unpackhi_epi32(t0, t1); + z2 = _mm512_unpacklo_epi32(t2, t3); + z3 = _mm512_unpackhi_epi32(t2, t3); + + /* Get the right endianness */ + t0 = ENDIANNESS_16x32(_mm512_unpacklo_epi64(z0, z2)); + t1 = ENDIANNESS_16x32(_mm512_unpackhi_epi64(z0, z2)); + t2 = ENDIANNESS_16x32(_mm512_unpacklo_epi64(z1, z3)); + t3 = ENDIANNESS_16x32(_mm512_unpackhi_epi64(z1, z3)); + + // L0 - L3 + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8(p_out[0], stream_mask, loc_mb_mask, t0, p_iv[0], z0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8(p_out[1], stream_mask, loc_mb_mask, t1, p_iv[1], z1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8(p_out[2], stream_mask, loc_mb_mask, t2, p_iv[2], z2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8(p_out[3], stream_mask, loc_mb_mask, t3, p_iv[3], z3); + + // L4 - L7 + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[4] - 1, stream_mask << 16, loc_mb_mask, t0, (__m128i*)p_iv[4] - 1, z0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[5] - 1, stream_mask << 16, loc_mb_mask, t1, (__m128i*)p_iv[5] - 1, z1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[6] - 1, stream_mask << 16, loc_mb_mask, t2, (__m128i*)p_iv[6] - 1, z2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[7] - 1, stream_mask << 16, loc_mb_mask, t3, (__m128i*)p_iv[7] - 1, z3); + + // L8 - Lb + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[8] - 2, stream_mask << 32, loc_mb_mask, t0, (__m128i*)p_iv[8] - 2, z0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[9] - 2, stream_mask << 32, loc_mb_mask, t1, (__m128i*)p_iv[9] - 2, z1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[10] - 2, stream_mask << 32, loc_mb_mask, t2, (__m128i*)p_iv[10] - 2, z2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[11] - 2, stream_mask << 32, loc_mb_mask, t3, (__m128i*)p_iv[11] - 2, z3); + + // Lc - Lf + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[12] - 3, stream_mask << 48, loc_mb_mask, t0, (__m128i*)p_iv[12] - 3, z0); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[13] - 3, stream_mask << 48, loc_mb_mask, t1, (__m128i*)p_iv[13] - 3, z1); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[14] - 3, stream_mask << 48, loc_mb_mask, t2, (__m128i*)p_iv[14] - 3, z2); + UPDATE_STREAM_MASK_16(stream_mask, p_loc_len) + XOR_AND_STORE_RESULT_EPI8((__m128i*)p_out[15] - 3, stream_mask << 48, loc_mb_mask, t3, (__m128i*)p_iv[15] - 3, z3); +} +#endif /* _SM4_GFNI_MB_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/CMakeLists.txt b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/CMakeLists.txt new file mode 100644 index 000000000..c9cad0634 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/CMakeLists.txt @@ -0,0 +1,163 @@ +#=============================================================================== +# Copyright (C) 2019 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions +# and limitations under the License. +# +#=============================================================================== + +# Define defaults for every supported compiler +set(DEFAULT_GNU_COMPILER_VER 8.2.0) +set(DEFAULT_CLANG_COMPILER_VER 9.0.0) +set(DEFAULT_Intel_COMPILER_VER 19.0.0) + +# Check compiler version +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") AND (CMAKE_C_COMPILER_VERSION VERSION_LESS DEFAULT_GNU_COMPILER_VER)) + message(FATAL_ERROR "GNU C Compiler version must be 8.2 or higher") +endif() +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") AND (CMAKE_C_COMPILER_VERSION VERSION_LESS DEFAULT_CLANG_COMPILER_VER)) + message(FATAL_ERROR "Clang C Compiler version must be 9.0 or higher") +endif() +if(("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel") AND (CMAKE_C_COMPILER_VERSION VERSION_LESS DEFAULT_Intel_COMPILER_VER)) + message(FATAL_ERROR "Compiler version must be 19.0 or higher") +endif() + +include("${CRYPTO_MB_SOURCES_DIR}/cmake/common.cmake") +include(${COMPILER_OPTIONS_FILE}) # Get ${CMAKE_C_FLAGS}, ${CMAKE_CXX_FLAGS} and ${AVX512_CFLAGS} + +set(AVX512_LIBRARY_DEFINES "${AVX512_LIBRARY_DEFINES}" "${MB_LIBRARIES_DEFINES}" "USE_AMS_5x" "SIMD_LEN=512") + +# Sources +file(GLOB RSA_AVX512_SOURCES "${CRYPTO_MB_SOURCES_DIR}/rsa/*.c" + "${CRYPTO_MB_SOURCES_DIR}/rsa/avx512_primitives/*.c") +file(GLOB COMMON_SOURCES "${CRYPTO_MB_SOURCES_DIR}/common/*.c") +file(GLOB X25519_SOURCES "${CRYPTO_MB_SOURCES_DIR}/x25519/*.c") +file(GLOB ECNIST_SOURCES "${CRYPTO_MB_SOURCES_DIR}/ecnist/*.c") +file(GLOB SM2_SOURCES "${CRYPTO_MB_SOURCES_DIR}/sm2/*.c") +file(GLOB SM3_SOURCES "${CRYPTO_MB_SOURCES_DIR}/sm3/*.c") + +# SM4 Sources +file(GLOB SM4_SOURCES "${CRYPTO_MB_SOURCES_DIR}/sm4/*.c") +file(GLOB SM4_SOURCES ${SM4_SOURCES} "${CRYPTO_MB_SOURCES_DIR}/sm4/gcm/*.c") +file(GLOB SM4_SOURCES ${SM4_SOURCES} "${CRYPTO_MB_SOURCES_DIR}/sm4/gcm/internal/*.c") +file(GLOB SM4_SOURCES ${SM4_SOURCES} "${CRYPTO_MB_SOURCES_DIR}/sm4/ccm/*.c") +file(GLOB SM4_SOURCES ${SM4_SOURCES} "${CRYPTO_MB_SOURCES_DIR}/sm4/ccm/internal/*.c") + +file(GLOB ED25519_SOURCES "${CRYPTO_MB_SOURCES_DIR}/ed25519/*.c") +file(GLOB EXP_SOURCES "${CRYPTO_MB_SOURCES_DIR}/exp/*.c") + +# Headers +file(GLOB PUBLIC_HEADERS "${CRYPTO_MB_INCLUDE_DIR}/crypto_mb/*.h") +file(GLOB PRIVATE_HEADERS "${CRYPTO_MB_INCLUDE_DIR}/internal/common/*.h" + "${CRYPTO_MB_INCLUDE_DIR}/internal/ecnist/*.h" + "${CRYPTO_MB_INCLUDE_DIR}/internal/rsa/*.h" + "${CRYPTO_MB_INCLUDE_DIR}/internal/sm2/*.h" + "${CRYPTO_MB_INCLUDE_DIR}/internal/sm3/*.h" + "${CRYPTO_MB_INCLUDE_DIR}/internal/sm4/*.h" + "${CRYPTO_MB_INCLUDE_DIR}/internal/ed25519/*.h" + "${CRYPTO_MB_INCLUDE_DIR}/internal/exp/*.h") +file(GLOB OPENSSL_HEADERS "${OPENSSL_INCLUDE_DIR}/openssl/*.h") + +set(CRYPTO_MB_SOURCES ${RSA_AVX512_SOURCES} ${COMMON_SOURCES} ${X25519_SOURCES} ${ECNIST_SOURCES} ${SM2_SOURCES} ${SM3_SOURCES} ${SM4_SOURCES} ${ED25519_SOURCES} ${EXP_SOURCES}) +set(CRYPTO_MB_HEADERS ${PUBLIC_HEADERS} ${PRIVATE_HEADERS} ${OPENSSL_HEADERS}) + +set(WIN_RESOURCE_FILE ${CRYPTO_MB_SOURCES_DIR}/common/crypto_mb_ver.rc) +set(CPU_FEATURES_FILE ${CRYPTO_MB_SOURCES_DIR}/common/cpu_features.c) + +# Disable compiler optimizations for this file, as compiler adds some ISA specific code +# which is unwanted for functions that are aimed to work on any CPU +list(REMOVE_ITEM CRYPTO_MB_SOURCES ${CPU_FEATURES_FILE}) +if("${OS_STRING}" STREQUAL "windows") + set_source_files_properties(${CPU_FEATURES_FILE} PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS_SECURITY} /Od") +else() + set_source_files_properties(${CPU_FEATURES_FILE} PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS_SECURITY} -O0") +endif() + +if(BN_OPENSSL_PATCH) # Off by default + list(APPEND AVX512_LIBRARY_DEFINES "BN_OPENSSL_PATCH") +endif() + +set(MB_LIB_TARGET ${MB_DYN_LIB_TARGET}) + +set_source_files_properties(${CRYPTO_MB_SOURCES} PROPERTIES COMPILE_DEFINITIONS "${AVX512_LIBRARY_DEFINES}" + COMPILE_FLAGS "${AVX512_CFLAGS} ${CMAKE_ASM_FLAGS} ${CMAKE_C_FLAGS_SECURITY}") + +# Don't specify architectural flags for the assembler for this sources, because of the bug in Intel® C Compiler under MacOS: error: invalid instruction mnemonic 'vkmovb' +# The bug has been fixed since version 2021.3. This is a workaround to support older versions of Intel® C Compiler. +if(CMAKE_C_COMPILER_VERSION VERSION_LESS 20.2.3) + set_source_files_properties(${X25519_SOURCES} PROPERTIES COMPILE_DEFINITIONS "${AVX512_LIBRARY_DEFINES}" + COMPILE_FLAGS "${AVX512_CFLAGS} ${CMAKE_C_FLAGS_SECURITY}") +endif() + +# Create shared library +if(DYNAMIC_LIB OR MB_STANDALONE) + if(WIN32) + add_library(${MB_DYN_LIB_TARGET} SHARED ${CRYPTO_MB_HEADERS} ${CRYPTO_MB_SOURCES} ${CPU_FEATURES_FILE} ${WIN_RESOURCE_FILE}) + else() + add_library(${MB_DYN_LIB_TARGET} SHARED ${CRYPTO_MB_HEADERS} ${CRYPTO_MB_SOURCES} ${CPU_FEATURES_FILE}) + endif() + + set_target_properties(${MB_DYN_LIB_TARGET} PROPERTIES C_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + LINK_FLAGS "${LINK_FLAGS_DYNAMIC} ${LINK_FLAG_SECURITY}" + PUBLIC_HEADER "${PUBLIC_HEADERS}" + ) + + if(UNIX) + set_target_properties(${MB_DYN_LIB_TARGET} PROPERTIES VERSION ${MBX_INTERFACE_VERSION} + SOVERSION ${MBX_INTERFACE_VERSION_MAJOR}) + endif() + + target_link_libraries(${MB_DYN_LIB_TARGET} OpenSSL::Crypto) +endif(DYNAMIC_LIB OR MB_STANDALONE) + +# Installation of the shared library +if (MB_STANDALONE) # standalone crypto_mb's cmake run + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib" + RUNTIME DESTINATION "lib" + PUBLIC_HEADER DESTINATION "include/crypto_mb") +elseif (DYNAMIC_LIB) # build from ippcp's cmake + install(TARGETS ${MB_DYN_LIB_TARGET} + LIBRARY DESTINATION "lib/intel64" + RUNTIME DESTINATION "lib/intel64" + PUBLIC_HEADER DESTINATION "include/crypto_mb") +endif() + +# Static library +if(WIN32) + add_library(${MB_STATIC_LIB_TARGET} STATIC ${CRYPTO_MB_HEADERS} ${CRYPTO_MB_SOURCES} ${CPU_FEATURES_FILE} ${WIN_RESOURCE_FILE}) +else() + add_library(${MB_STATIC_LIB_TARGET} STATIC ${CRYPTO_MB_HEADERS} ${CRYPTO_MB_SOURCES} ${CPU_FEATURES_FILE}) +endif() + +set_target_properties(${MB_STATIC_LIB_TARGET} PROPERTIES C_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + PUBLIC_HEADER "${PUBLIC_HEADERS}") + +target_link_libraries(${MB_STATIC_LIB_TARGET} OpenSSL::Crypto) +if(WIN32) + set_target_properties(${MB_STATIC_LIB_TARGET} PROPERTIES OUTPUT_NAME "${MB_LIB_TARGET}mt") +else() + set_target_properties(${MB_STATIC_LIB_TARGET} PROPERTIES OUTPUT_NAME "${MB_LIB_TARGET}") +endif() + +# Static lib installation +if(MB_STANDALONE) + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib" + PUBLIC_HEADER DESTINATION "include/crypto_mb") +else() + install(TARGETS ${MB_STATIC_LIB_TARGET} + ARCHIVE DESTINATION "lib/intel64" + PUBLIC_HEADER DESTINATION "include/crypto_mb") +endif() diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.defs b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.defs new file mode 100644 index 000000000..1faf7a1e9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.defs @@ -0,0 +1,131 @@ +EXPORTS + +mbx_getversion + +mbx_get_cpu_features +mbx_is_crypto_mb_applicable +mbx_get_algo_info + +mbx_rsa_public_mb8 +mbx_rsa_private_mb8 +mbx_rsa_private_crt_mb8 + +mbx_rsa_public_ssl_mb8 +mbx_rsa_private_ssl_mb8 +mbx_rsa_private_crt_ssl_mb8 + +mbx_x25519_public_key_mb8 +mbx_x25519_mb8 +mbx_ed25519_public_key_mb8 +mbx_ed25519_sign_mb8 +mbx_ed25519_verify_mb8 + +mbx_exp_BufferSize +mbx_exp1024_mb8 +mbx_exp2048_mb8 +mbx_exp3072_mb8 +mbx_exp4096_mb8 +mbx_exp_mb8 + +mbx_nistp256_ecdh_mb8 +mbx_nistp256_ecdsa_sign_setup_mb8 +mbx_nistp256_ecdsa_sign_complete_mb8 +mbx_nistp256_ecdsa_sign_mb8 +mbx_nistp256_ecdsa_verify_mb8 +mbx_nistp256_ecpublic_key_mb8 + +mbx_nistp256_ecdh_ssl_mb8 +mbx_nistp256_ecdsa_sign_setup_ssl_mb8 +mbx_nistp256_ecdsa_sign_complete_ssl_mb8 +mbx_nistp256_ecdsa_sign_ssl_mb8 +mbx_nistp256_ecdsa_verify_ssl_mb8 +mbx_nistp256_ecpublic_key_ssl_mb8 + +mbx_nistp384_ecdh_mb8 +mbx_nistp384_ecdsa_sign_setup_mb8 +mbx_nistp384_ecdsa_sign_complete_mb8 +mbx_nistp384_ecdsa_sign_mb8 +mbx_nistp384_ecdsa_verify_mb8 +mbx_nistp384_ecpublic_key_mb8 + +mbx_nistp384_ecdh_ssl_mb8 +mbx_nistp384_ecdsa_sign_setup_ssl_mb8 +mbx_nistp384_ecdsa_sign_complete_ssl_mb8 +mbx_nistp384_ecdsa_sign_ssl_mb8 +mbx_nistp384_ecdsa_verify_ssl_mb8 +mbx_nistp384_ecpublic_key_ssl_mb8 + +mbx_nistp521_ecdh_mb8 +mbx_nistp521_ecdsa_sign_setup_mb8 +mbx_nistp521_ecdsa_sign_complete_mb8 +mbx_nistp521_ecdsa_sign_mb8 +mbx_nistp521_ecdsa_verify_mb8 +mbx_nistp521_ecpublic_key_mb8 + +mbx_nistp521_ecdh_ssl_mb8 +mbx_nistp521_ecdsa_sign_setup_ssl_mb8 +mbx_nistp521_ecdsa_sign_complete_ssl_mb8 +mbx_nistp521_ecdsa_sign_ssl_mb8 +mbx_nistp521_ecdsa_verify_ssl_mb8 +mbx_nistp521_ecpublic_key_ssl_mb8 + +mbx_sm2_ecdh_mb8 +mbx_sm2_ecdsa_sign_mb8 +mbx_sm2_ecdsa_verify_mb8 +mbx_sm2_ecpublic_key_mb8 + +mbx_sm2_ecdh_ssl_mb8 +mbx_sm2_ecdsa_sign_ssl_mb8 +mbx_sm2_ecdsa_verify_ssl_mb8 +mbx_sm2_ecpublic_key_ssl_mb8 + +mbx_RSA1K_pub65537_Method +mbx_RSA2K_pub65537_Method +mbx_RSA3K_pub65537_Method +mbx_RSA4K_pub65537_Method +mbx_RSA_pub65537_Method +mbx_RSA1K_private_Method +mbx_RSA2K_private_Method +mbx_RSA3K_private_Method +mbx_RSA4K_private_Method +mbx_RSA_private_Method +mbx_RSA1K_private_crt_Method +mbx_RSA2K_private_crt_Method +mbx_RSA3K_private_crt_Method +mbx_RSA4K_private_crt_Method +mbx_RSA_private_crt_Method +mbx_RSA_Method_BufSize + +mbx_sm3_init_mb16 +mbx_sm3_update_mb16 +mbx_sm3_final_mb16 +mbx_sm3_msg_digest_mb16 + +mbx_sm4_set_key_mb16 +mbx_sm4_encrypt_ecb_mb16 +mbx_sm4_decrypt_ecb_mb16 +mbx_sm4_encrypt_cbc_mb16 +mbx_sm4_decrypt_cbc_mb16 +mbx_sm4_encrypt_ctr128_mb16 +mbx_sm4_decrypt_ctr128_mb16 +mbx_sm4_encrypt_ofb_mb16 +mbx_sm4_decrypt_ofb_mb16 +mbx_sm4_encrypt_cfb128_mb16 +mbx_sm4_decrypt_cfb128_mb16 + +mbx_sm4_gcm_init_mb16 +mbx_sm4_gcm_update_iv_mb16 +mbx_sm4_gcm_update_aad_mb16 +mbx_sm4_gcm_encrypt_mb16 +mbx_sm4_gcm_decrypt_mb16 +mbx_sm4_gcm_get_tag_mb16 + +mbx_sm4_ccm_init_mb16 +mbx_sm4_ccm_update_aad_mb16 +mbx_sm4_ccm_encrypt_mb16 +mbx_sm4_ccm_decrypt_mb16 +mbx_sm4_ccm_get_tag_mb16 + +mbx_sm4_xts_set_keys_mb16 +mbx_sm4_xts_encrypt_mb16 +mbx_sm4_xts_decrypt_mb16 diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.linux.lib-export b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.linux.lib-export new file mode 100644 index 000000000..5bbea8903 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.linux.lib-export @@ -0,0 +1,129 @@ +EXTERN (mbx_getversion) + +EXTERN (mbx_get_cpu_features) +EXTERN (mbx_is_crypto_mb_applicable) +EXTERN (mbx_get_algo_info) + +EXTERN (mbx_rsa_public_mb8) +EXTERN (mbx_rsa_private_mb8) +EXTERN (mbx_rsa_private_crt_mb8) + +EXTERN (mbx_rsa_public_ssl_mb8) +EXTERN (mbx_rsa_private_ssl_mb8) +EXTERN (mbx_rsa_private_crt_ssl_mb8) + +EXTERN (mbx_x25519_public_key_mb8) +EXTERN (mbx_x25519_mb8) +EXTERN (mbx_ed25519_public_key_mb8) +EXTERN (mbx_ed25519_sign_mb8) +EXTERN (mbx_ed25519_verify_mb8) + +EXTERN (mbx_exp_BufferSize) +EXTERN (mbx_exp1024_mb8) +EXTERN (mbx_exp2048_mb8) +EXTERN (mbx_exp3072_mb8) +EXTERN (mbx_exp4096_mb8) +EXTERN (mbx_exp_mb8) + +EXTERN (mbx_nistp256_ecdh_mb8) +EXTERN (mbx_nistp256_ecdsa_sign_setup_mb8) +EXTERN (mbx_nistp256_ecdsa_sign_complete_mb8) +EXTERN (mbx_nistp256_ecdsa_sign_mb8) +EXTERN (mbx_nistp256_ecdsa_verify_mb8) +EXTERN (mbx_nistp256_ecpublic_key_mb8) + +EXTERN (mbx_nistp256_ecdh_ssl_mb8) +EXTERN (mbx_nistp256_ecdsa_sign_setup_ssl_mb8) +EXTERN (mbx_nistp256_ecdsa_sign_complete_ssl_mb8) +EXTERN (mbx_nistp256_ecdsa_sign_ssl_mb8) +EXTERN (mbx_nistp256_ecdsa_verify_ssl_mb8) +EXTERN (mbx_nistp256_ecpublic_key_ssl_mb8) + +EXTERN (mbx_nistp384_ecdh_mb8) +EXTERN (mbx_nistp384_ecdsa_sign_setup_mb8) +EXTERN (mbx_nistp384_ecdsa_sign_complete_mb8) +EXTERN (mbx_nistp384_ecdsa_sign_mb8) +EXTERN (mbx_nistp384_ecdsa_verify_mb8) +EXTERN (mbx_nistp384_ecpublic_key_mb8) + +EXTERN (mbx_nistp384_ecdh_ssl_mb8) +EXTERN (mbx_nistp384_ecdsa_sign_setup_ssl_mb8) +EXTERN (mbx_nistp384_ecdsa_sign_complete_ssl_mb8) +EXTERN (mbx_nistp384_ecdsa_sign_ssl_mb8) +EXTERN (mbx_nistp384_ecdsa_verify_ssl_mb8) +EXTERN (mbx_nistp384_ecpublic_key_ssl_mb8) + +EXTERN (mbx_nistp521_ecdh_mb8) +EXTERN (mbx_nistp521_ecdsa_sign_setup_mb8) +EXTERN (mbx_nistp521_ecdsa_sign_complete_mb8) +EXTERN (mbx_nistp521_ecdsa_sign_mb8) +EXTERN (mbx_nistp521_ecdsa_verify_mb8) +EXTERN (mbx_nistp521_ecpublic_key_mb8) + +EXTERN (mbx_nistp521_ecdh_ssl_mb8) +EXTERN (mbx_nistp521_ecdsa_sign_setup_ssl_mb8) +EXTERN (mbx_nistp521_ecdsa_sign_complete_ssl_mb8) +EXTERN (mbx_nistp521_ecdsa_sign_ssl_mb8) +EXTERN (mbx_nistp521_ecdsa_verify_ssl_mb8) +EXTERN (mbx_nistp521_ecpublic_key_ssl_mb8) + +EXTERN (mbx_sm2_ecdh_mb8) +EXTERN (mbx_sm2_ecdsa_sign_mb8) +EXTERN (mbx_sm2_ecdsa_verify_mb8) +EXTERN (mbx_sm2_ecpublic_key_mb8) + +EXTERN (mbx_sm2_ecdh_ssl_mb8) +EXTERN (mbx_sm2_ecdsa_sign_ssl_mb8) +EXTERN (mbx_sm2_ecdsa_verify_ssl_mb8) +EXTERN (mbx_sm2_ecpublic_key_ssl_mb8) + +EXTERN (mbx_RSA1K_pub65537_Method) +EXTERN (mbx_RSA2K_pub65537_Method) +EXTERN (mbx_RSA3K_pub65537_Method) +EXTERN (mbx_RSA4K_pub65537_Method) +EXTERN (mbx_RSA_pub65537_Method) +EXTERN (mbx_RSA1K_private_Method) +EXTERN (mbx_RSA2K_private_Method) +EXTERN (mbx_RSA3K_private_Method) +EXTERN (mbx_RSA4K_private_Method) +EXTERN (mbx_RSA_private_Method) +EXTERN (mbx_RSA1K_private_crt_Method) +EXTERN (mbx_RSA2K_private_crt_Method) +EXTERN (mbx_RSA3K_private_crt_Method) +EXTERN (mbx_RSA4K_private_crt_Method) +EXTERN (mbx_RSA_private_crt_Method) +EXTERN (mbx_RSA_Method_BufSize) + +EXTERN (mbx_sm3_init_mb16) +EXTERN (mbx_sm3_update_mb16) +EXTERN (mbx_sm3_final_mb16) +EXTERN (mbx_sm3_msg_digest_mb16) + +EXTERN (mbx_sm4_set_key_mb16) +EXTERN (mbx_sm4_encrypt_ecb_mb16) +EXTERN (mbx_sm4_decrypt_ecb_mb16) +EXTERN (mbx_sm4_encrypt_cbc_mb16) +EXTERN (mbx_sm4_decrypt_cbc_mb16) +EXTERN (mbx_sm4_encrypt_ctr128_mb16) +EXTERN (mbx_sm4_decrypt_ctr128_mb16) +EXTERN (mbx_sm4_encrypt_ofb_mb16) +EXTERN (mbx_sm4_decrypt_ofb_mb16) +EXTERN (mbx_sm4_encrypt_cfb128_mb16) +EXTERN (mbx_sm4_decrypt_cfb128_mb16) + +EXTERN (mbx_sm4_gcm_init_mb16) +EXTERN (mbx_sm4_gcm_update_iv_mb16) +EXTERN (mbx_sm4_gcm_update_aad_mb16) +EXTERN (mbx_sm4_gcm_encrypt_mb16) +EXTERN (mbx_sm4_gcm_decrypt_mb16) +EXTERN (mbx_sm4_gcm_get_tag_mb16) + +EXTERN (mbx_sm4_ccm_init_mb16) +EXTERN (mbx_sm4_ccm_update_aad_mb16) +EXTERN (mbx_sm4_ccm_encrypt_mb16) +EXTERN (mbx_sm4_ccm_decrypt_mb16) +EXTERN (mbx_sm4_ccm_get_tag_mb16) + +EXTERN (mbx_sm4_xts_set_keys_mb16) +EXTERN (mbx_sm4_xts_encrypt_mb16) +EXTERN (mbx_sm4_xts_decrypt_mb16) diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.macosx.lib-export b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.macosx.lib-export new file mode 100644 index 000000000..b090a284e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/cmake/dll_export/crypto_mb.macosx.lib-export @@ -0,0 +1,129 @@ +_mbx_getversion + +_mbx_get_cpu_features +_mbx_is_crypto_mb_applicable +_mbx_get_algo_info + +_mbx_rsa_public_mb8 +_mbx_rsa_private_mb8 +_mbx_rsa_private_crt_mb8 + +_mbx_rsa_public_ssl_mb8 +_mbx_rsa_private_ssl_mb8 +_mbx_rsa_private_crt_ssl_mb8 + +_mbx_x25519_public_key_mb8 +_mbx_x25519_mb8 +_mbx_ed25519_public_key_mb8 +_mbx_ed25519_sign_mb8 +_mbx_ed25519_verify_mb8 + +_mbx_exp_BufferSize +_mbx_exp1024_mb8 +_mbx_exp2048_mb8 +_mbx_exp3072_mb8 +_mbx_exp4096_mb8 +_mbx_exp_mb8 + +_mbx_nistp256_ecdh_mb8 +_mbx_nistp256_ecdsa_sign_setup_mb8 +_mbx_nistp256_ecdsa_sign_complete_mb8 +_mbx_nistp256_ecdsa_sign_mb8 +_mbx_nistp256_ecdsa_verify_mb8 +_mbx_nistp256_ecpublic_key_mb8 + +_mbx_nistp256_ecdh_ssl_mb8 +_mbx_nistp256_ecdsa_sign_setup_ssl_mb8 +_mbx_nistp256_ecdsa_sign_complete_ssl_mb8 +_mbx_nistp256_ecdsa_sign_ssl_mb8 +_mbx_nistp256_ecdsa_verify_ssl_mb8 +_mbx_nistp256_ecpublic_key_ssl_mb8 + +_mbx_nistp384_ecdh_mb8 +_mbx_nistp384_ecdsa_sign_setup_mb8 +_mbx_nistp384_ecdsa_sign_complete_mb8 +_mbx_nistp384_ecdsa_sign_mb8 +_mbx_nistp384_ecdsa_verify_mb8 +_mbx_nistp384_ecpublic_key_mb8 + +_mbx_nistp384_ecdh_ssl_mb8 +_mbx_nistp384_ecdsa_sign_setup_ssl_mb8 +_mbx_nistp384_ecdsa_sign_complete_ssl_mb8 +_mbx_nistp384_ecdsa_sign_ssl_mb8 +_mbx_nistp384_ecdsa_verify_ssl_mb8 +_mbx_nistp384_ecpublic_key_ssl_mb8 + +_mbx_nistp521_ecdh_mb8 +_mbx_nistp521_ecdsa_sign_setup_mb8 +_mbx_nistp521_ecdsa_sign_complete_mb8 +_mbx_nistp521_ecdsa_sign_mb8 +_mbx_nistp521_ecdsa_verify_mb8 +_mbx_nistp521_ecpublic_key_mb8 + +_mbx_nistp521_ecdh_ssl_mb8 +_mbx_nistp521_ecdsa_sign_setup_ssl_mb8 +_mbx_nistp521_ecdsa_sign_complete_ssl_mb8 +_mbx_nistp521_ecdsa_sign_ssl_mb8 +_mbx_nistp521_ecdsa_verify_ssl_mb8 +_mbx_nistp521_ecpublic_key_ssl_mb8 + +_mbx_sm2_ecdh_mb8 +_mbx_sm2_ecdsa_sign_mb8 +_mbx_sm2_ecdsa_verify_mb8 +_mbx_sm2_ecpublic_key_mb8 + +_mbx_sm2_ecdh_ssl_mb8 +_mbx_sm2_ecdsa_sign_ssl_mb8 +_mbx_sm2_ecdsa_verify_ssl_mb8 +_mbx_sm2_ecpublic_key_ssl_mb8 + +_mbx_RSA1K_pub65537_Method +_mbx_RSA2K_pub65537_Method +_mbx_RSA3K_pub65537_Method +_mbx_RSA4K_pub65537_Method +_mbx_RSA_pub65537_Method +_mbx_RSA1K_private_Method +_mbx_RSA2K_private_Method +_mbx_RSA3K_private_Method +_mbx_RSA4K_private_Method +_mbx_RSA_private_Method +_mbx_RSA1K_private_crt_Method +_mbx_RSA2K_private_crt_Method +_mbx_RSA3K_private_crt_Method +_mbx_RSA4K_private_crt_Method +_mbx_RSA_private_crt_Method +_mbx_RSA_Method_BufSize + +_mbx_sm3_init_mb16 +_mbx_sm3_update_mb16 +_mbx_sm3_final_mb16 +_mbx_sm3_msg_digest_mb16 + +_mbx_sm4_set_key_mb16 +_mbx_sm4_encrypt_ecb_mb16 +_mbx_sm4_decrypt_ecb_mb16 +_mbx_sm4_encrypt_cbc_mb16 +_mbx_sm4_decrypt_cbc_mb16 +_mbx_sm4_encrypt_ctr128_mb16 +_mbx_sm4_decrypt_ctr128_mb16 +_mbx_sm4_encrypt_ofb_mb16 +_mbx_sm4_decrypt_ofb_mb16 +_mbx_sm4_encrypt_cfb128_mb16 +_mbx_sm4_decrypt_cfb128_mb16 + +_mbx_sm4_gcm_init_mb16 +_mbx_sm4_gcm_update_iv_mb16 +_mbx_sm4_gcm_update_aad_mb16 +_mbx_sm4_gcm_encrypt_mb16 +_mbx_sm4_gcm_decrypt_mb16 +_mbx_sm4_gcm_get_tag_mb16 + +_mbx_sm4_ccm_init_mb16 +_mbx_sm4_ccm_update_aad_mb16 +_mbx_sm4_ccm_encrypt_mb16 +_mbx_sm4_ccm_decrypt_mb16 +_mbx_sm4_ccm_get_tag_mb16 + +_mbx_sm4_xts_set_keys_mb16 +_mbx_sm4_xts_encrypt_mb16 +_mbx_sm4_xts_decrypt_mb16 diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/cpu_features.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/cpu_features.c new file mode 100644 index 000000000..c4265a893 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/cpu_features.c @@ -0,0 +1,290 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +/* masks of bits */ +#define BIT00 0x00000001 +#define BIT01 0x00000002 +#define BIT02 0x00000004 +#define BIT03 0x00000008 +#define BIT04 0x00000010 +#define BIT05 0x00000020 +#define BIT06 0x00000040 +#define BIT07 0x00000080 +#define BIT08 0x00000100 +#define BIT09 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +/* index inside cpu_info[4] */ +#define eax_ (0) +#define ebx_ (1) +#define ecx_ (2) +#define edx_ (3) + + +__INLINE void _mbcp_cpuid(int32u buf[4], int32u leaf, int32u subleaf) +{ + #ifdef __GNUC__ + __asm__ ("cpuid" : "=a" (buf[0]), "=b" (buf[1]), "=c" (buf[2]), "=d" (buf[3]) : "a" (leaf), "c" (subleaf)); + #else + __cpuidex(buf,leaf, subleaf); + #endif +} + +static int32u _mbcp_max_cpuid_main_leaf_number(void) +{ + int32u buf[4]; + _mbcp_cpuid(buf, 0, 0); + return buf[0]; +} + +#if 0 +static int32u _mbcp_max_cpuid_extd_leaf_number(void) +{ + int32u buf[4]; + _mbcp_cpuid(buf, 0x80000000, 0); + return buf[0]; +} +#endif + +#define XSAVE_OSXSAVE (BIT26|BIT27) +static int32u _mbcp_xsave_support(int32u bits) +{ + int32u buf[4]; + _mbcp_cpuid(buf, 1, 0); + + if(XSAVE_OSXSAVE != (buf[ecx_] & XSAVE_OSXSAVE)) + return 0; + + int32u xcr0; + + #ifdef __GNUC__ + //asm volatile("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx"); + __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx"); + #else + xcr0 = (int32u)_xgetbv(0); + #endif + + return (xcr0 & bits) == bits; +} + +typedef struct { + int32u info_idx; + int32u info_idx_bit; + int64u cpu_feature; +} cpu_feature_map; + +/* +// Intel(r) Architecture Instruction Set Extension and Future Features. +// Programming Reference. 319433-038, March 2020 +// see Table 1-5, Table 1-6 +*/ +static const cpu_feature_map cpu_feature_detector_1_0[] = { + {ecx_, BIT00, mbcpCPUID_SSE3}, + {ecx_, BIT01, mbcpCPUID_CLMUL}, + {ecx_, BIT09, mbcpCPUID_SSSE3}, + //{ecx_, BIT12, mbcpCPUID_FMA}, /* supported FMA extensions using YMM*/ + //{ecx_, BIT13, mbcpCPUID_CMPXCHG16B}, + {ecx_, BIT19, mbcpCPUID_SSE41}, + {ecx_, BIT20, mbcpCPUID_SSE42}, + {ecx_, BIT22, mbcpCPUID_MOVBE}, + //{ecx_, BIT23, mbcpCPUID_POPCNT}, + {ecx_, BIT25, mbcpCPUID_AES}, + {ecx_, BIT28, mbcpCPUID_AVX}, + {ecx_, BIT29, mbcpCPUID_F16C}, + {ecx_, BIT30, mbcpCPUID_RDRAND}, + + {edx_, BIT23, mbcpCPUID_MMX}, + {edx_, BIT25, mbcpCPUID_SSE}, + {edx_, BIT26, mbcpCPUID_SSE2}, +}; + +static const cpu_feature_map cpu_feature_detector_7_0[] = { + {ebx_, BIT03, mbcpCPUID_BMI1}, + {ebx_, BIT05, mbcpCPUID_AVX2}, + {ebx_, BIT08, mbcpCPUID_BMI2}, + {ebx_, BIT14, mbcpCPUID_MPX}, + {ebx_, BIT16, mbcpCPUID_AVX512F}, + {ebx_, BIT17, mbcpCPUID_AVX512DQ}, + {ebx_, BIT18, mbcpCPUID_RDSEED}, + {ebx_, BIT19, mbcpCPUID_ADX}, + {ebx_, BIT21, mbcpCPUID_AVX512IFMA}, + {ebx_, BIT26, mbcpCPUID_AVX512PF}, + {ebx_, BIT27, mbcpCPUID_AVX512ER}, + {ebx_, BIT28, mbcpCPUID_AVX512CD}, + {ebx_, BIT29, mbcpCPUID_SHA}, + {ebx_, BIT30, mbcpCPUID_AVX512BW}, + {ebx_, BIT31, mbcpCPUID_AVX512VL}, + + {ecx_, BIT01, mbcpCPUID_AVX512VBMI}, + {ecx_, BIT06, mbcpCPUID_AVX512VBMI2}, + {ecx_, BIT08, mbcpCPUID_AVX512GFNI}, + {ecx_, BIT09, mbcpCPUID_AVX512VAES}, + {ecx_, BIT10, mbcpCPUID_AVX512VCLMUL}, + //{ecx_, BIT11, mbcpCPUID_AVX512VNNI}, + //{ecx_, BIT12, mbcpCPUID_AVX512BITALG}, + + {edx_, BIT02, mbcpCPUID_AVX512_4VNNIW}, + {edx_, BIT03, mbcpCPUID_AVX512_4FMADDPS}, +}; + +#undef eax_ +#undef ebx_ +#undef ecx_ +#undef edx_ + + +static int64u _mbcp_cpu_feature_detector(const int32u cpuinfo[4], const cpu_feature_map* tbl, int32u tbl_len) +{ + int64u features = 0; + int32u n; + for(n=0; n=7) { + /* cpuid info: cpuid_7_0 */ + _mbcp_cpuid(cpu_info, 7, 0); + features |= _mbcp_cpu_feature_detector(cpu_info, + cpu_feature_detector_7_0, + sizeof(cpu_feature_detector_7_0)/sizeof(cpu_feature_map)); + if((features & mbcpCPUID_AVX512F) && _mbcp_xsave_support(XSAVE_AVX512_SUPPORT)) + features |= mbcpAVX512_ENABLEDBYOS; + } + } + + return features; +} + + +// based on c-flags: -mavx512dq -mavx512ifma -mavx512f -mavx512vbmi2 -mavx512cd -mavx512bw -mbmi2 +#define CRYPTO_MB_REQUIRED_CPU_FEATURES ( \ + mbcpCPUID_BMI2 \ + | mbcpCPUID_AVX512F \ + | mbcpCPUID_AVX512DQ \ + | mbcpCPUID_AVX512BW \ + | mbcpCPUID_AVX512IFMA \ + | mbcpCPUID_AVX512VBMI2 \ + | mbcpAVX512_ENABLEDBYOS) + +DLL_PUBLIC +int mbx_is_crypto_mb_applicable(int64u cpu_features) +{ + int64u features = cpu_features; + if(0 == features) + features = mbx_get_cpu_features(); + return (CRYPTO_MB_REQUIRED_CPU_FEATURES == (features & CRYPTO_MB_REQUIRED_CPU_FEATURES)); +} + +/* structure for determining the number of buffers(WIDTH) for the algorithm */ +typedef struct { + enum MBX_ALGO algo; + enum MBX_WIDTH width; +} algo_width_map; + +/* clang-config off */ +static const algo_width_map arr_algo_width[] = { + { MBX_ALGO_RSA_1K, MBX_WIDTH_MB8 }, + { MBX_ALGO_RSA_2K, MBX_WIDTH_MB8 }, + { MBX_ALGO_RSA_3K, MBX_WIDTH_MB8 }, + { MBX_ALGO_RSA_4K, MBX_WIDTH_MB8 }, + { MBX_ALGO_X25519, MBX_WIDTH_MB8 }, + { MBX_ALGO_EC_NIST_P256, MBX_WIDTH_MB8 }, + { MBX_ALGO_EC_NIST_P384, MBX_WIDTH_MB8 }, + { MBX_ALGO_EC_NIST_P521, MBX_WIDTH_MB8 }, + { MBX_ALGO_EC_SM2, MBX_WIDTH_MB8 }, + { MBX_ALGO_SM3, MBX_WIDTH_MB16 }, + { MBX_ALGO_SM4, MBX_WIDTH_MB16 } +}; +/* clang-config on */ + +DLL_PUBLIC +MBX_ALGO_INFO mbx_get_algo_info(enum MBX_ALGO algo) +{ + const int mbx_mb_applicable = mbx_is_crypto_mb_applicable(0); + + int num_width = 0; + /* check CPU feature */ + if (0 == mbx_mb_applicable) { + return num_width; + } + const int num_tbl = sizeof(arr_algo_width) / sizeof(algo_width_map); + + const algo_width_map *tbl = arr_algo_width; + /* loop determining the number of buffers to process */ + for (int i = 0; i < num_tbl; ++i, ++tbl) { + if (algo == (*tbl).algo) { + num_width = (*tbl).width; + break; + } + } + + return num_width; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/crypto_mb_res.gen b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/crypto_mb_res.gen new file mode 100644 index 000000000..e8bb87482 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/crypto_mb_res.gen @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 1999 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include "winres.h" + +#define STR2(x) #x +#define STR(x) STR2(x) + +VS_VERSION_INFO VERSIONINFO + FILEVERSION MBX_VERSION() + PRODUCTVERSION MBX_VERSION() + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Intel Corporation.\0" + VALUE "FileVersion", STR( MBX_VERSION() ) "\0" + VALUE "ProductName", MBX_LIB_SHORTNAME() ". Intel(R) Integrated Performance Primitives. " MBX_LIB_LONGNAME() ".\0" + VALUE "ProductVersion", CRYPTO_MB_STR_VERSION() "\0" + VALUE "LegalCopyright", "Copyright (C) 1999-2021, Intel Corporation. All rights reserved.\0" + + VALUE "Comments", "Intel(R) Integrated Performance Primitives. " MBX_LIB_LONGNAME() ".\0" + VALUE "FileDescription", MBX_LIB_SHORTNAME() ".dll is the intel64 " MBX_LIB_SHORTNAME() " dynamic library\0" + VALUE "InternalName", MBX_LIB_SHORTNAME() ".dll\0" + VALUE "OriginalFilename", MBX_LIB_SHORTNAME() ".dll\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/crypto_mb_ver.rc b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/crypto_mb_ver.rc new file mode 100644 index 000000000..df21efce2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/crypto_mb_ver.rc @@ -0,0 +1,22 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include "crypto_mb_res.gen" + +/* ////////////////////////////// End of file /////////////////////////////// */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma52_mb8_template.cxx b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma52_mb8_template.cxx new file mode 100644 index 000000000..d09a5dc51 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma52_mb8_template.cxx @@ -0,0 +1,29 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "ifma_math.h" +#include "ifma_internal.h" + +{typedef} +{functions} + +void {function_name} ({parameters}) +{ + // Main code goes here + +{code} +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma_cvt52.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma_cvt52.c new file mode 100644 index 000000000..1099518c6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma_cvt52.c @@ -0,0 +1,525 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include + +#if defined(_MSC_VER) && (_MSC_VER < 1920) + // Disable optimization for VS2017 due to AVX512 masking bug + #define DISABLE_OPTIMIZATION __pragma(optimize( "", off )) +#else + #define DISABLE_OPTIMIZATION +#endif + +#define PROC_LEN (52) + +#define BYTES_REV (1) +#define RADIX_CVT (2) + +#define MIN(a, b) ( ((a) < (b)) ? a : b ) + +__INLINE __mmask8 MB_MASK(int L) { + return (L > 0) ? (__mmask8)0xFF : (__mmask8)0; +} + +__INLINE __mmask64 SB_MASK1(int L, int REV) +{ + if (L <= 0) + return (__mmask64)0x0; + if (L > PROC_LEN) + L = PROC_LEN; + if (REV) + return (__mmask64)(0xFFFFFFFFFFFFFFFFULL << ((int)sizeof(__m512i) - L)); + return (__mmask64)(0xFFFFFFFFFFFFFFFFULL >> ((int)sizeof(__m512i) - L)); +} + + + #ifndef BN_OPENSSL_DISABLE + #include + #if BN_OPENSSL_PATCH + extern BN_ULONG* bn_get_words(const BIGNUM* bn); + #endif + #endif /* BN_OPENSSL_DISABLE */ + +/* +// transpose 8 SB into MB including (reverse bytes and) radix 2^64 => 2^52 conversion +// +// covers: +// - 8 BIGNUM -> mb8 +// - 8 BNU -> mb8 +// - 8 hex strings -> mb8 +*/ +DISABLE_OPTIMIZATION +__INLINE void transform_8sb_to_mb8(U64 out_mb8[], int bitLen, int8u *inp[8], int inpLen[8], int flag) { + // inverse bytes (reverse=1) + const __m512i bswap_mask = _mm512_set_epi64( + 0x0001020304050607, 0x08090a0b0c0d0e0f, + 0x1011121314151617, 0x18191a1b1c1d1e1f, + 0x2021222324252627, 0x28292a2b2c2d2e2f, + 0x3031323334353637, 0x38393a3b3c3d3e3f); + // repeat words + const __m512i idx16 = _mm512_set_epi64( + 0x0019001800170016, + 0x0016001500140013, + 0x0013001200110010, + 0x0010000f000e000d, + 0x000c000b000a0009, + 0x0009000800070006, + 0x0006000500040003, + 0x0003000200010000); + // shift right + const __m512i shiftR = _mm512_set_epi64( + 12, 8, 4, 0, 12, 8, 4, 0); + // radix 2^52 mask of digits + __m512i digMask = _mm512_set1_epi64(DIGIT_MASK); + + int bytesRev = flag & BYTES_REV; /* reverse flag */ + int radixCvt = flag & RADIX_CVT; /* radix (64->52) conversion assumed*/ + + int inpBytes = NUMBER_OF_DIGITS(bitLen, 8); /* bytes */ + int outDigits = NUMBER_OF_DIGITS(bitLen, DIGIT_SIZE); /* digits */ + + int i; + for (i = 0; inpBytes > 0; i += PROC_LEN, inpBytes -= PROC_LEN, out_mb8 += 8) { + int sbidx = bytesRev ? inpBytes - (int)sizeof(__m512i) : i; + + __m512i X0 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[0] - i, bytesRev), (__m512i*)&inp[0][sbidx]); + __m512i X1 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[1] - i, bytesRev), (__m512i*)&inp[1][sbidx]); + __m512i X2 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[2] - i, bytesRev), (__m512i*)&inp[2][sbidx]); + __m512i X3 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[3] - i, bytesRev), (__m512i*)&inp[3][sbidx]); + __m512i X4 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[4] - i, bytesRev), (__m512i*)&inp[4][sbidx]); + __m512i X5 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[5] - i, bytesRev), (__m512i*)&inp[5][sbidx]); + __m512i X6 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[6] - i, bytesRev), (__m512i*)&inp[6][sbidx]); + __m512i X7 = _mm512_maskz_loadu_epi8(SB_MASK1(inpLen[7] - i, bytesRev), (__m512i*)&inp[7][sbidx]); + + if (bytesRev) { + X0 = _mm512_permutexvar_epi8(bswap_mask, X0); + X1 = _mm512_permutexvar_epi8(bswap_mask, X1); + X2 = _mm512_permutexvar_epi8(bswap_mask, X2); + X3 = _mm512_permutexvar_epi8(bswap_mask, X3); + X4 = _mm512_permutexvar_epi8(bswap_mask, X4); + X5 = _mm512_permutexvar_epi8(bswap_mask, X5); + X6 = _mm512_permutexvar_epi8(bswap_mask, X6); + X7 = _mm512_permutexvar_epi8(bswap_mask, X7); + } + + if (radixCvt) { + X0 = _mm512_permutexvar_epi16(idx16, X0); + X0 = _mm512_srlv_epi64(X0, shiftR); + X0 = _mm512_and_si512(X0, digMask); /* probably exceeded instruction */ + + X1 = _mm512_permutexvar_epi16(idx16, X1); + X1 = _mm512_srlv_epi64(X1, shiftR); + X1 = _mm512_and_si512(X1, digMask); + + X2 = _mm512_permutexvar_epi16(idx16, X2); + X2 = _mm512_srlv_epi64(X2, shiftR); + X2 = _mm512_and_si512(X2, digMask); + + X3 = _mm512_permutexvar_epi16(idx16, X3); + X3 = _mm512_srlv_epi64(X3, shiftR); + X3 = _mm512_and_si512(X3, digMask); + + X4 = _mm512_permutexvar_epi16(idx16, X4); + X4 = _mm512_srlv_epi64(X4, shiftR); + X4 = _mm512_and_si512(X4, digMask); + + X5 = _mm512_permutexvar_epi16(idx16, X5); + X5 = _mm512_srlv_epi64(X5, shiftR); + X5 = _mm512_and_si512(X5, digMask); + + X6 = _mm512_permutexvar_epi16(idx16, X6); + X6 = _mm512_srlv_epi64(X6, shiftR); + X6 = _mm512_and_si512(X6, digMask); + + X7 = _mm512_permutexvar_epi16(idx16, X7); + X7 = _mm512_srlv_epi64(X7, shiftR); + X7 = _mm512_and_si512(X7, digMask); + } + + // transpose 8 digits at a time + TRANSPOSE_8xI64x8(X0, X1, X2, X3, X4, X5, X6, X7); + + // store transposed digits + _mm512_mask_storeu_epi64(&out_mb8[0], MB_MASK(outDigits--), X0); + _mm512_mask_storeu_epi64(&out_mb8[1], MB_MASK(outDigits--), X1); + _mm512_mask_storeu_epi64(&out_mb8[2], MB_MASK(outDigits--), X2); + _mm512_mask_storeu_epi64(&out_mb8[3], MB_MASK(outDigits--), X3); + _mm512_mask_storeu_epi64(&out_mb8[4], MB_MASK(outDigits--), X4); + _mm512_mask_storeu_epi64(&out_mb8[5], MB_MASK(outDigits--), X5); + _mm512_mask_storeu_epi64(&out_mb8[6], MB_MASK(outDigits--), X6); + _mm512_mask_storeu_epi64(&out_mb8[7], MB_MASK(outDigits--), X7); + } +} + +#ifdef OPENSSL_IS_BORINGSSL +static int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) { + return BN_bn2le_padded(to, tolen, a); +} +#endif + +#ifndef BN_OPENSSL_DISABLE +// Convert BIGNUM into MB8(Radix=2^52) format +// Returns bitmask of succesfully converted values +// Accepts NULLs as BIGNUM inputs +// Null or wrong length +int8u ifma_BN_to_mb8(int64u out_mb8[][8], const BIGNUM* const bn[8], int bitLen) +{ + // check input input length + assert((0 0); + + int byteLens[8]; + int byteLen = NUMBER_OF_DIGITS(bitLen, 8); + int i; + for (i = 0; i < 8; ++i) + byteLens[i] = (NULL != bn[i]) ? byteLen : 0; + + transform_8sb_to_mb8((U64*)out_mb8, bitLen, (int8u**)bn, byteLens, RADIX_CVT); + + return _mm512_cmpneq_epi64_mask(_mm512_loadu_si512((__m512i*)bn), _mm512_setzero_si512()); +} + +int8u ifma_HexStr8_to_mb8(int64u out_mb8[][8], const int8u* const pStr[8], int bitLen) +{ + // check input parameters + assert(bitLen > 0); + + int byteLens[8]; + int byteLen = NUMBER_OF_DIGITS(bitLen, 8); + int i; + for (i = 0; i < 8; i++) + byteLens[i] = (NULL != pStr[i]) ? byteLen : 0; + + transform_8sb_to_mb8((U64*)out_mb8, bitLen, (int8u**)pStr, byteLens, RADIX_CVT | BYTES_REV); + + return _mm512_cmpneq_epi64_mask(_mm512_loadu_si512((__m512i*)pStr), _mm512_setzero_si512()); +} +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +// transpose MB into 8 SB including (reverse bytes and) radix 2^52 => 2^64 conversion +// +// covers: +// - mb8 -> 8 BNU +// - mb8 -> 8 hex strings +*/ +DISABLE_OPTIMIZATION +__INLINE void transform_mb8_to_8sb(int8u* out[8], int outLen[8], const U64 inp_mb8[], int bitLen, int flag) +{ + // inverse bytes (reverse=1) + const __m512i bswap_mask = _mm512_set_epi64( + 0x0001020304050607, 0x08090a0b0c0d0e0f, + 0x1011121314151617, 0x18191a1b1c1d1e1f, + 0x2021222324252627, 0x28292a2b2c2d2e2f, + 0x3031323334353637, 0x38393a3b3c3d3e3f); + + const __m512i shiftL = _mm512_set_epi64(4, 0, 4, 0, 4, 0, 4, 0); + + const __m512i permutation1 = _mm512_set_epi64(0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3e3d3c3b, // {63,63,63,63,62,61,60,59} + 0x3737363534333231, // {55,55,54,53,52,51,50,49} + 0x302e2d2c2b2a2928, // {48,46,45,44,43,42,41,40} + 0x1f1f1f1f1f1f1e1d, // {31,31,31,31,31,31,30,29} + 0x1717171716151413, // {23,23,23,23,22,21,20,19} + 0x0f0f0f0e0d0c0b0a, // {15,15,15,14,13,12,11,10} + 0x0706050403020100); // { 7, 6, 5, 4, 3, 2, 1, 0} + + const __m512i permutation2 = _mm512_set_epi64(0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3a39383737373737, // {58,57,56,55,55,55,55,55} + 0x2727272727272726, // {39,39,39,39,39,39,39,38} + 0x2524232221201f1f, // {37,36,35,34,33,32,31,31} + 0x1c1b1a1918171717, // {28,27,26,25,24,23,23,23} + 0x1211100f0f0f0f0f, // {18,17,16,15,15,15,15,15} + 0x0908070707070707); // { 9, 8, 7, 7, 7, 7, 7, 7} + int bytesRev = flag & BYTES_REV; /* reverse flag */ + int radixCvt = flag & RADIX_CVT; /* radix (52->64) conversion assumed */ + + int inpDigits = NUMBER_OF_DIGITS(bitLen, DIGIT_SIZE); /* digits */ + int outBytes = NUMBER_OF_DIGITS(bitLen, 8); /* bytes */ + + int i; + for (i = 0; outBytes > 0; i += PROC_LEN, outBytes -= PROC_LEN, inp_mb8 += 8) { + int sbidx = bytesRev ? outBytes - (int)sizeof(__m512i) : i; + + __m512i X0 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[0]); + __m512i X1 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[1]); + __m512i X2 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[2]); + __m512i X3 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[3]); + __m512i X4 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[4]); + __m512i X5 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[5]); + __m512i X6 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[6]); + __m512i X7 = _mm512_maskz_loadu_epi64(MB_MASK(inpDigits--), &inp_mb8[7]); + + // transpose 8 digits at a time + TRANSPOSE_8xI64x8(X0, X1, X2, X3, X4, X5, X6, X7); + + if (radixCvt) { + __m512i T; + X0 = _mm512_sllv_epi64(X0, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X0); + X0 = _mm512_permutexvar_epi8(permutation2, X0); + X0 = _mm512_or_si512(X0, T); + + X1 = _mm512_sllv_epi64(X1, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X1); + X1 = _mm512_permutexvar_epi8(permutation2, X1); + X1 = _mm512_or_si512(X1, T); + + X2 = _mm512_sllv_epi64(X2, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X2); + X2 = _mm512_permutexvar_epi8(permutation2, X2); + X2 = _mm512_or_si512(X2, T); + + X3 = _mm512_sllv_epi64(X3, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X3); + X3 = _mm512_permutexvar_epi8(permutation2, X3); + X3 = _mm512_or_si512(X3, T); + + X4 = _mm512_sllv_epi64(X4, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X4); + X4 = _mm512_permutexvar_epi8(permutation2, X4); + X4 = _mm512_or_si512(X4, T); + + X5 = _mm512_sllv_epi64(X5, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X5); + X5 = _mm512_permutexvar_epi8(permutation2, X5); + X5 = _mm512_or_si512(X5, T); + + X6 = _mm512_sllv_epi64(X6, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X6); + X6 = _mm512_permutexvar_epi8(permutation2, X6); + X6 = _mm512_or_si512(X6, T); + + X7 = _mm512_sllv_epi64(X7, shiftL); + T = _mm512_permutexvar_epi8(permutation1, X7); + X7 = _mm512_permutexvar_epi8(permutation2, X7); + X7 = _mm512_or_si512(X7, T); + } + + if (bytesRev) { + X0 = _mm512_permutexvar_epi8(bswap_mask, X0); + X1 = _mm512_permutexvar_epi8(bswap_mask, X1); + X2 = _mm512_permutexvar_epi8(bswap_mask, X2); + X3 = _mm512_permutexvar_epi8(bswap_mask, X3); + X4 = _mm512_permutexvar_epi8(bswap_mask, X4); + X5 = _mm512_permutexvar_epi8(bswap_mask, X5); + X6 = _mm512_permutexvar_epi8(bswap_mask, X6); + X7 = _mm512_permutexvar_epi8(bswap_mask, X7); + } + + // store transposed digits + _mm512_mask_storeu_epi8(out[0] + sbidx, SB_MASK1(outLen[0] - i, bytesRev), X0); + _mm512_mask_storeu_epi8(out[1] + sbidx, SB_MASK1(outLen[1] - i, bytesRev), X1); + _mm512_mask_storeu_epi8(out[2] + sbidx, SB_MASK1(outLen[2] - i, bytesRev), X2); + _mm512_mask_storeu_epi8(out[3] + sbidx, SB_MASK1(outLen[3] - i, bytesRev), X3); + _mm512_mask_storeu_epi8(out[4] + sbidx, SB_MASK1(outLen[4] - i, bytesRev), X4); + _mm512_mask_storeu_epi8(out[5] + sbidx, SB_MASK1(outLen[5] - i, bytesRev), X5); + _mm512_mask_storeu_epi8(out[6] + sbidx, SB_MASK1(outLen[6] - i, bytesRev), X6); + _mm512_mask_storeu_epi8(out[7] + sbidx, SB_MASK1(outLen[7] - i, bytesRev), X7); + } + +} + +int8u ifma_mb8_to_BNU(int64u* const out_bn[8], const int64u inp_mb8[][8], const int bitLen) +{ + // Check input parameters + assert(bitLen > 0); + + int bnu_bitlen = NUMBER_OF_DIGITS(bitLen, 64) * 64; // gres: output length is multiple 64 + int byteLens[8]; + int i; + for (i = 0; i < 8; ++i) + //gres: byteLens[i] = (NULL != out_bn[i]) ? NUMBER_OF_DIGITS(bitLen, 8) : 0; + byteLens[i] = (NULL != out_bn[i]) ? NUMBER_OF_DIGITS(bnu_bitlen, 8) : 0; + + transform_mb8_to_8sb((int8u**)out_bn, byteLens, (U64*)inp_mb8, bitLen, RADIX_CVT); + + return _mm512_cmpneq_epi64_mask(_mm512_loadu_si512((__m512i*)out_bn), _mm512_setzero_si512()); +} + +int8u ifma_mb8_to_HexStr8(int8u* const pStr[8], const int64u inp_mb8[][8], int bitLen) +{ + // check input parameters + assert(bitLen > 0); + + int byteLens[8]; + int byteLen = NUMBER_OF_DIGITS(bitLen, 8); + int i; + for (i = 0; i < 8; i++) + byteLens[i] = (NULL != pStr[i]) ? byteLen : 0; + + transform_mb8_to_8sb((int8u**)pStr, byteLens, (U64*)inp_mb8, bitLen, RADIX_CVT | BYTES_REV); + + return _mm512_cmpneq_epi64_mask(_mm512_loadu_si512((__m512i*)pStr), _mm512_setzero_si512()); +} +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +// transpose 8 SB into MB without radix conversion +// +// covers: +// - mb8 -> 8 BNU +// - mb8 -> 8 hex strings +*/ +DISABLE_OPTIMIZATION +int8u ifma_BNU_transpose_copy(int64u out_mb8[][8], const int64u* const bn[8], int bitLen) +{ + // Check input parameters + assert(bitLen > 0); + + __mmask8 kbn[8]; + int i; + for (i = 0; i < 8; ++i) + kbn[i] = (NULL == bn[i]) ? (__mmask8)0 : (__mmask8)0xFF; + + int len = NUMBER_OF_DIGITS(bitLen, 64); + int n; + for (n = 0; len > 0; n += 8, out_mb8 += 8) { + __mmask8 kread = (len >= 8) ? 0xFF : (__mmask8)((1 << len) - 1); + + __m512i X0 = _mm512_maskz_loadu_epi64(kread & kbn[0], bn[0] + n); + __m512i X1 = _mm512_maskz_loadu_epi64(kread & kbn[1], bn[1] + n); + __m512i X2 = _mm512_maskz_loadu_epi64(kread & kbn[2], bn[2] + n); + __m512i X3 = _mm512_maskz_loadu_epi64(kread & kbn[3], bn[3] + n); + __m512i X4 = _mm512_maskz_loadu_epi64(kread & kbn[4], bn[4] + n); + __m512i X5 = _mm512_maskz_loadu_epi64(kread & kbn[5], bn[5] + n); + __m512i X6 = _mm512_maskz_loadu_epi64(kread & kbn[6], bn[6] + n); + __m512i X7 = _mm512_maskz_loadu_epi64(kread & kbn[7], bn[7] + n); + + TRANSPOSE_8xI64x8(X0, X1, X2, X3, X4, X5, X6, X7); + + _mm512_mask_storeu_epi64(&out_mb8[0], MB_MASK(len--), X0); + _mm512_mask_storeu_epi64(&out_mb8[1], MB_MASK(len--), X1); + _mm512_mask_storeu_epi64(&out_mb8[2], MB_MASK(len--), X2); + _mm512_mask_storeu_epi64(&out_mb8[3], MB_MASK(len--), X3); + _mm512_mask_storeu_epi64(&out_mb8[4], MB_MASK(len--), X4); + _mm512_mask_storeu_epi64(&out_mb8[5], MB_MASK(len--), X5); + _mm512_mask_storeu_epi64(&out_mb8[6], MB_MASK(len--), X6); + _mm512_mask_storeu_epi64(&out_mb8[7], MB_MASK(len--), X7); + } + + return _mm512_cmpneq_epi64_mask(_mm512_loadu_si512((__m512i*)bn), _mm512_setzero_si512()); +} + +#ifndef BN_OPENSSL_DISABLE + +DISABLE_OPTIMIZATION +int8u ifma_BN_transpose_copy(int64u out_mb8[][8], const BIGNUM* const bn[8], int bitLen) +{ + // check input length + assert((0 0; n += 8, out_mb8 += 8) { + __mmask8 k = (len >= 8) ? 0xFF : (1 << len) - 1; + + __m512i X0 = _mm512_maskz_loadu_epi64(k & kbn[0], inp[0]+n); + __m512i X1 = _mm512_maskz_loadu_epi64(k & kbn[1], inp[1]+n); + __m512i X2 = _mm512_maskz_loadu_epi64(k & kbn[2], inp[2]+n); + __m512i X3 = _mm512_maskz_loadu_epi64(k & kbn[3], inp[3]+n); + __m512i X4 = _mm512_maskz_loadu_epi64(k & kbn[4], inp[4]+n); + __m512i X5 = _mm512_maskz_loadu_epi64(k & kbn[5], inp[5]+n); + __m512i X6 = _mm512_maskz_loadu_epi64(k & kbn[6], inp[6]+n); + __m512i X7 = _mm512_maskz_loadu_epi64(k & kbn[7], inp[7]+n); + + TRANSPOSE_8xI64x8(X0, X1, X2, X3, X4, X5, X6, X7); + + _mm512_mask_storeu_epi64(&out_mb8[0], MB_MASK(len--), X0); + _mm512_mask_storeu_epi64(&out_mb8[1], MB_MASK(len--), X1); + _mm512_mask_storeu_epi64(&out_mb8[2], MB_MASK(len--), X2); + _mm512_mask_storeu_epi64(&out_mb8[3], MB_MASK(len--), X3); + _mm512_mask_storeu_epi64(&out_mb8[4], MB_MASK(len--), X4); + _mm512_mask_storeu_epi64(&out_mb8[5], MB_MASK(len--), X5); + _mm512_mask_storeu_epi64(&out_mb8[6], MB_MASK(len--), X6); + _mm512_mask_storeu_epi64(&out_mb8[7], MB_MASK(len--), X7); + } + + return _mm512_cmpneq_epi64_mask(_mm512_loadu_si512((__m512i*)bn), _mm512_setzero_si512()); +} +#endif /* BN_OPENSSL_DISABLE */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma_version.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma_version.c new file mode 100644 index 000000000..86cbb1a53 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/common/ifma_version.c @@ -0,0 +1,42 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#define MBX_LIB_VERSION() MBX_VER_MAJOR,MBX_VER_MINOR,MBX_VER_REV +#define MBX_LIB_BUILD() __DATE__ + +#define STR2(x) #x +#define STR(x) STR2(x) +#define MBX_STR_VERSION() MBX_LIB_NAME() \ + " (ver: " STR(MBX_VER_MAJOR) "." STR(MBX_VER_MINOR) "." STR(MBX_VER_REV) " (" STR(MBX_INTERFACE_VERSION_MAJOR)"."STR(MBX_INTERFACE_VERSION_MINOR)")" \ + " build: " MBX_LIB_BUILD()")" + +/* version info */ +static const mbxVersion mbxLibVer = { + MBX_LIB_VERSION(), /* major, minor, revision */ + MBX_LIB_NAME(), /* lib name */ + MBX_LIB_BUILD(), /* build date */ + MBX_STR_VERSION() /* version str */ +}; + +DLL_PUBLIC +const mbxVersion* mbx_getversion(void) +{ + return &mbxLibVer; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_m256.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_m256.c new file mode 100644 index 000000000..8c7410b7d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_m256.c @@ -0,0 +1,368 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + + +/*===================================================================== + + General 256-bit operations - sqr & mul + +=====================================================================*/ + +void MB_FUNC_NAME(ifma_amm52x5_)(U64 R[], const U64 inpA[], const U64 inpB[], const U64 inpM[], const int64u* k0_mb) +{ + U64 res00, res01, res02, res03, res04; + U64 K = loadu64(k0_mb); /* k0[] */ + int itr; + + res00 = res01 = res02 = res03 = res04 = get_zero64(); + + for (itr = 0; itr < P256_LEN52; itr++) { + U64 Yi; + U64 Bi = loadu64(inpB); + inpB++; + + res00 = fma52lo(res00, Bi, inpA[0]); + res01 = fma52lo(res01, Bi, inpA[1]); + res02 = fma52lo(res02, Bi, inpA[2]); + res03 = fma52lo(res03, Bi, inpA[3]); + res04 = fma52lo(res04, Bi, inpA[4]); + + Yi = fma52lo(get_zero64(), res00, K); + + res00 = fma52lo(res00, Yi, inpM[0]); + res01 = fma52lo(res01, Yi, inpM[1]); + res02 = fma52lo(res02, Yi, inpM[2]); + res03 = fma52lo(res03, Yi, inpM[3]); + res04 = fma52lo(res04, Yi, inpM[4]); + + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64 (res01, res00); + + res00 = fma52hi(res01, Bi, inpA[0]); + res01 = fma52hi(res02, Bi, inpA[1]); + res02 = fma52hi(res03, Bi, inpA[2]); + res03 = fma52hi(res04, Bi, inpA[3]); + res04 = fma52hi(get_zero64(), Bi, inpA[4]); + + res00 = fma52hi(res00, Yi, inpM[0]); + res01 = fma52hi(res01, Yi, inpM[1]); + res02 = fma52hi(res02, Yi, inpM[2]); + res03 = fma52hi(res03, Yi, inpM[3]); + res04 = fma52hi(res04, Yi, inpM[4]); + } + + // normalization + NORM_LSHIFTR(res0, 0, 1) + NORM_LSHIFTR(res0, 1, 2) + NORM_LSHIFTR(res0, 2, 3) + NORM_LSHIFTR(res0, 3, 4) + +#if 0 + // t = res -modulus and normalize + U64 t0 = sub64(res00, inpM[0]); + U64 t1 = sub64(res01, inpM[1]); + U64 t2 = sub64(res02, inpM[2]); + U64 t3 = sub64(res03, inpM[3]); + U64 t4 = sub64(res04, inpM[4]); + NORM_ASHIFTR(t, 0,1) + NORM_ASHIFTR(t, 1,2) + NORM_ASHIFTR(t, 2,3) + NORM_ASHIFTR(t, 3,4) + + /* condition mov R[] = (t4>=0)? t : res */ + __mb_mask cmask = cmp64_mask(t4, get_zero64(), _MM_CMPINT_GE); + R[0] = cmov_U64(res00, t0, cmask); + R[1] = cmov_U64(res01, t1, cmask); + R[2] = cmov_U64(res02, t2, cmask); + R[3] = cmov_U64(res03, t3, cmask); + R[4] = cmov_U64(res04, t4, cmask); +#endif + R[0] = res00; + R[1] = res01; + R[2] = res02; + R[3] = res03; + R[4] = res04; +} + +void MB_FUNC_NAME(ifma_ams52x5_)(U64 r[], const U64 a[], const U64 m[], const int64u* k0_mb) +{ + U64 k = loadu64((U64*)k0_mb); + U64 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; + res0 = res1 = res2 = res3 = res4 = res5 = res6 = res7 = res8 = res9 = get_zero64(); + + // Calculate full square + res1 = fma52lo(res1, a[0], a[1]); // Sum(1) + res2 = fma52hi(res2, a[0], a[1]); // Sum(1) + res2 = fma52lo(res2, a[0], a[2]); // Sum(2) + res3 = fma52hi(res3, a[0], a[2]); // Sum(2) + res3 = fma52lo(res3, a[1], a[2]); // Sum(3) + res4 = fma52hi(res4, a[1], a[2]); // Sum(3) + res3 = fma52lo(res3, a[0], a[3]); // Sum(3) + res4 = fma52hi(res4, a[0], a[3]); // Sum(3) + res4 = fma52lo(res4, a[1], a[3]); // Sum(4) + res5 = fma52hi(res5, a[1], a[3]); // Sum(4) + res5 = fma52lo(res5, a[2], a[3]); // Sum(5) + res6 = fma52hi(res6, a[2], a[3]); // Sum(5) + res4 = fma52lo(res4, a[0], a[4]); // Sum(4) + res5 = fma52hi(res5, a[0], a[4]); // Sum(4) + res5 = fma52lo(res5, a[1], a[4]); // Sum(5) + res6 = fma52hi(res6, a[1], a[4]); // Sum(5) + res6 = fma52lo(res6, a[2], a[4]); // Sum(6) + res7 = fma52hi(res7, a[2], a[4]); // Sum(6) + res7 = fma52lo(res7, a[3], a[4]); // Sum(7) + res8 = fma52hi(res8, a[3], a[4]); // Sum(7) + { + res0 = add64(res0, res0); // Double(0) + res1 = add64(res1, res1); // Double(1) + res2 = add64(res2, res2); // Double(2) + res3 = add64(res3, res3); // Double(3) + res4 = add64(res4, res4); // Double(4) + res5 = add64(res5, res5); // Double(5) + res6 = add64(res6, res6); // Double(6) + res7 = add64(res7, res7); // Double(7) + res8 = add64(res8, res8); // Double(8) + { + res0 = fma52lo(res0, a[0], a[0]); // Add sqr(0) + res1 = fma52hi(res1, a[0], a[0]); // Add sqr(0) + res2 = fma52lo(res2, a[1], a[1]); // Add sqr(2) + res3 = fma52hi(res3, a[1], a[1]); // Add sqr(2) + res4 = fma52lo(res4, a[2], a[2]); // Add sqr(4) + res5 = fma52hi(res5, a[2], a[2]); // Add sqr(4) + res6 = fma52lo(res6, a[3], a[3]); // Add sqr(6) + res7 = fma52hi(res7, a[3], a[3]); // Add sqr(6) + res8 = fma52lo(res8, a[4], a[4]); // Add sqr(8) + res9 = fma52hi(res9, a[4], a[4]); // Add sqr(8) + } + } + + // Reduction + U64 u0 = mul52lo(res0,k); + + // Create u0 + res0 = fma52lo(res0, u0, m[0]); + res1 = fma52hi(res1, u0, m[0]); + res1 = fma52lo(res1, u0, m[1]); + res2 = fma52hi(res2, u0, m[1]); + res1 = add64(res1, srli64(res0, DIGIT_SIZE)); + U64 u1 = mul52lo(res1,k); + res2 = fma52lo(res2, u0, m[2]); + res3 = fma52hi(res3, u0, m[2]); + res3 = fma52lo(res3, u0, m[3]); + res4 = fma52hi(res4, u0, m[3]); + res4 = fma52lo(res4, u0, m[4]); + res5 = fma52hi(res5, u0, m[4]); + + // Create u1 + res1 = fma52lo(res1, u1, m[0]); + res2 = fma52hi(res2, u1, m[0]); + res2 = fma52lo(res2, u1, m[1]); + res3 = fma52hi(res3, u1, m[1]); + res2 = add64(res2, srli64(res1, DIGIT_SIZE)); + U64 u2 = mul52lo(res2,k); + res3 = fma52lo(res3, u1, m[2]); + res4 = fma52hi(res4, u1, m[2]); + res4 = fma52lo(res4, u1, m[3]); + res5 = fma52hi(res5, u1, m[3]); + res5 = fma52lo(res5, u1, m[4]); + res6 = fma52hi(res6, u1, m[4]); + + // Create u2 + res2 = fma52lo(res2, u2, m[0]); + res3 = fma52hi(res3, u2, m[0]); + res3 = fma52lo(res3, u2, m[1]); + res4 = fma52hi(res4, u2, m[1]); + res3 = add64(res3, srli64(res2, DIGIT_SIZE)); + U64 u3 = mul52lo(res3,k); + res4 = fma52lo(res4, u2, m[2]); + res5 = fma52hi(res5, u2, m[2]); + res5 = fma52lo(res5, u2, m[3]); + res6 = fma52hi(res6, u2, m[3]); + res6 = fma52lo(res6, u2, m[4]); + res7 = fma52hi(res7, u2, m[4]); + + // Create u3 + res3 = fma52lo(res3, u3, m[0]); + res4 = fma52hi(res4, u3, m[0]); + res4 = fma52lo(res4, u3, m[1]); + res5 = fma52hi(res5, u3, m[1]); + res4 = add64(res4, srli64(res3, DIGIT_SIZE)); + U64 u4 = mul52lo(res4,k); + res5 = fma52lo(res5, u3, m[2]); + res6 = fma52hi(res6, u3, m[2]); + res6 = fma52lo(res6, u3, m[3]); + res7 = fma52hi(res7, u3, m[3]); + res7 = fma52lo(res7, u3, m[4]); + res8 = fma52hi(res8, u3, m[4]); + + // Create u4 + res4 = fma52lo(res4, u4, m[0]); + res5 = fma52hi(res5, u4, m[0]); + res5 = fma52lo(res5, u4, m[1]); + res6 = fma52hi(res6, u4, m[1]); + res5 = add64(res5, srli64(res4, DIGIT_SIZE)); + res6 = fma52lo(res6, u4, m[2]); + res7 = fma52hi(res7, u4, m[2]); + res7 = fma52lo(res7, u4, m[3]); + res8 = fma52hi(res8, u4, m[3]); + res8 = fma52lo(res8, u4, m[4]); + res9 = fma52hi(res9, u4, m[4]); + + // normalization + NORM_LSHIFTR(res, 5, 6) + NORM_LSHIFTR(res, 6, 7) + NORM_LSHIFTR(res, 7, 8) + NORM_LSHIFTR(res, 8, 9) +#if 0 + // {res0-4) = (res5-9) -modulus and normalize + res0 = sub64(res5, m[0]); + res1 = sub64(res6, m[1]); + res2 = sub64(res7, m[2]); + res3 = sub64(res8, m[3]); + res4 = sub64(res9, m[4]); + NORM_ASHIFTR(res, 0,1) + NORM_ASHIFTR(res, 1,2) + NORM_ASHIFTR(res, 2,3) + NORM_ASHIFTR(res, 3,4) + + /* condition mov r[] = (res4>=0)? res(5 - 9) : res(0 - 4) */ + __mb_mask cmask = cmp64_mask(res4, get_zero64(), _MM_CMPINT_GE); + r[0] = cmov_U64(res5, res0, cmask); + r[1] = cmov_U64(res6, res1, cmask); + r[2] = cmov_U64(res7, res2, cmask); + r[3] = cmov_U64(res8, res3, cmask); + r[4] = cmov_U64(res9, res4, cmask); +#endif + + r[0] = res5; + r[1] = res6; + r[2] = res7; + r[3] = res8; + r[4] = res9; +} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +/* R = (A+B) mod M */ +void MB_FUNC_NAME(ifma_add52x5_)(U64 R[], const U64 A[], const U64 B[], const U64 M[]) +{ + /* r = a + b */ + U64 r0 = add64(A[0], B[0]); + U64 r1 = add64(A[1], B[1]); + U64 r2 = add64(A[2], B[2]); + U64 r3 = add64(A[3], B[3]); + U64 r4 = add64(A[4], B[4]); + + /* t = r - M */ + U64 t0 = sub64(r0, M[0]); + U64 t1 = sub64(r1, M[1]); + U64 t2 = sub64(r2, M[2]); + U64 t3 = sub64(r3, M[3]); + U64 t4 = sub64(r4, M[4]); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_LSHIFTR(r, 0,1) + NORM_LSHIFTR(r, 1,2) + NORM_LSHIFTR(r, 2,3) + NORM_LSHIFTR(r, 3,4) + + /* normalize t0, t1, t2, t3, t4 */ + NORM_ASHIFTR(t, 0,1) + NORM_ASHIFTR(t, 1,2) + NORM_ASHIFTR(t, 2,3) + NORM_ASHIFTR(t, 3,4) + + /* condition mask t4<0? (-1) : 0 */ + __mb_mask cmask = cmp64_mask(t4, get_zero64(), _MM_CMPINT_LT); + + R[0] = cmov_U64(t0, r0, cmask); + R[1] = cmov_U64(t1, r1, cmask); + R[2] = cmov_U64(t2, r2, cmask); + R[3] = cmov_U64(t3, r3, cmask); + R[4] = cmov_U64(t4, r4, cmask); +} + + +/* R = (A-B) mod M */ +void MB_FUNC_NAME(ifma_sub52x5_)(U64 R[], const U64 A[], const U64 B[], const U64 M[]) +{ + /* r = a-b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + + /* t = r + M */ + U64 t0 = add64(r0, M[0]); + U64 t1 = add64(r1, M[1]); + U64 t2 = add64(r2, M[2]); + U64 t3 = add64(r3, M[3]); + U64 t4 = add64(r4, M[4]); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + + /* normalize t0, t1, t2, t3, t4 */ + NORM_ASHIFTR(t, 0,1) + NORM_ASHIFTR(t, 1,2) + NORM_ASHIFTR(t, 2,3) + NORM_ASHIFTR(t, 3,4) + + /* condition mask t4<0? (-1) : 0 */ + __mb_mask cmask = cmp64_mask(r4, get_zero64(), _MM_CMPINT_LT); + + R[0] = cmov_U64(r0, t0, cmask); + R[1] = cmov_U64(r1, t1, cmask); + R[2] = cmov_U64(r2, t2, cmask); + R[3] = cmov_U64(r3, t3, cmask); + R[4] = cmov_U64(r4, t4, cmask); +} + +/* R = (-A) mod M */ +void MB_FUNC_NAME(ifma_neg52x5_)(U64 R[], const U64 A[], const U64 M[]) +{ + /* mask = a[]!=0? 1 : 0 */ + U64 t = _mm512_or_epi64(A[0], A[1]); + t = _mm512_or_epi64(t, A[2]); + t = _mm512_or_epi64(t, A[3]); + t = _mm512_or_epi64(t, A[4]); + __mb_mask mask = cmp64_mask(t, get_zero64(), _MM_CMPINT_NE); + + /* r = M - A */ + U64 r0 = _mm512_maskz_sub_epi64(mask, M[0], A[0]); + U64 r1 = _mm512_maskz_sub_epi64(mask, M[1], A[1]); + U64 r2 = _mm512_maskz_sub_epi64(mask, M[2], A[2]); + U64 r3 = _mm512_maskz_sub_epi64(mask, M[3], A[3]); + U64 r4 = _mm512_maskz_sub_epi64(mask, M[4], A[4]); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n256.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n256.c new file mode 100644 index 000000000..f37f4a80f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n256.c @@ -0,0 +1,219 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Constants */ +#define LEN52 NUMBER_OF_DIGITS(256,DIGIT_SIZE) + +/* +// EC NIST-P256 prime base point order +// in 2^52 radix +*/ +__ALIGN64 static const int64u n256_mb[LEN52][8] = { + {0x9cac2fc632551, 0x9cac2fc632551, 0x9cac2fc632551, 0x9cac2fc632551, 0x9cac2fc632551, 0x9cac2fc632551, 0x9cac2fc632551, 0x9cac2fc632551}, + {0xada7179e84f3b, 0xada7179e84f3b, 0xada7179e84f3b, 0xada7179e84f3b, 0xada7179e84f3b, 0xada7179e84f3b, 0xada7179e84f3b, 0xada7179e84f3b}, + {0xfffffffbce6fa, 0xfffffffbce6fa, 0xfffffffbce6fa, 0xfffffffbce6fa, 0xfffffffbce6fa, 0xfffffffbce6fa, 0xfffffffbce6fa, 0xfffffffbce6fa}, + {0x0000fffffffff, 0x0000fffffffff, 0x0000fffffffff, 0x0000fffffffff, 0x0000fffffffff, 0x0000fffffffff, 0x0000fffffffff, 0x0000fffffffff}, + {0x0ffffffff0000, 0x0ffffffff0000, 0x0ffffffff0000, 0x0ffffffff0000, 0x0ffffffff0000, 0x0ffffffff0000, 0x0ffffffff0000, 0x0ffffffff0000} +}; + +__ALIGN64 static const int64u n256x2_mb[LEN52][8] = { + {0x39585f8c64aa2, 0x39585f8c64aa2, 0x39585f8c64aa2, 0x39585f8c64aa2, 0x39585f8c64aa2, 0x39585f8c64aa2, 0x39585f8c64aa2, 0x39585f8c64aa2}, + {0x5b4e2f3d09e77, 0x5b4e2f3d09e77, 0x5b4e2f3d09e77, 0x5b4e2f3d09e77, 0x5b4e2f3d09e77, 0x5b4e2f3d09e77, 0x5b4e2f3d09e77, 0x5b4e2f3d09e77}, + {0xfffffff79cdf5, 0xfffffff79cdf5, 0xfffffff79cdf5, 0xfffffff79cdf5, 0xfffffff79cdf5, 0xfffffff79cdf5, 0xfffffff79cdf5, 0xfffffff79cdf5}, + {0x0001fffffffff, 0x0001fffffffff, 0x0001fffffffff, 0x0001fffffffff, 0x0001fffffffff, 0x0001fffffffff, 0x0001fffffffff, 0x0001fffffffff}, + {0x1fffffffe0000, 0x1fffffffe0000, 0x1fffffffe0000, 0x1fffffffe0000, 0x1fffffffe0000, 0x1fffffffe0000, 0x1fffffffe0000, 0x1fffffffe0000} +}; + +/* k0 = -( (1/n256 mod 2^DIGIT_SIZE) ) mod 2^DIGIT_SIZE */ +__ALIGN64 static const int64u n256_k0_mb[8] = { + 0x1c8aaee00bc4f, 0x1c8aaee00bc4f, 0x1c8aaee00bc4f, 0x1c8aaee00bc4f, 0x1c8aaee00bc4f, 0x1c8aaee00bc4f, 0x1c8aaee00bc4f, 0x1c8aaee00bc4f +}; + +/* to Montgomery conversion constant +// rr = 2^((LEN52*DIGIT_SIZE)*2) mod n256 +*/ +__ALIGN64 static const int64u n256_rr_mb[LEN52][8] = { + {0x0005cc0dea6dc3ba,0x0005cc0dea6dc3ba,0x0005cc0dea6dc3ba,0x0005cc0dea6dc3ba,0x0005cc0dea6dc3ba,0x0005cc0dea6dc3ba,0x0005cc0dea6dc3ba,0x0005cc0dea6dc3ba}, + {0x000192a067d8a084,0x000192a067d8a084,0x000192a067d8a084,0x000192a067d8a084,0x000192a067d8a084,0x000192a067d8a084,0x000192a067d8a084,0x000192a067d8a084}, + {0x000bec59615571bb,0x000bec59615571bb,0x000bec59615571bb,0x000bec59615571bb,0x000bec59615571bb,0x000bec59615571bb,0x000bec59615571bb,0x000bec59615571bb}, + {0x0001fc245b2392b6,0x0001fc245b2392b6,0x0001fc245b2392b6,0x0001fc245b2392b6,0x0001fc245b2392b6,0x0001fc245b2392b6,0x0001fc245b2392b6,0x0001fc245b2392b6}, + {0x0000e12d9559d956,0x0000e12d9559d956,0x0000e12d9559d956,0x0000e12d9559d956,0x0000e12d9559d956,0x0000e12d9559d956,0x0000e12d9559d956,0x0000e12d9559d956} +}; + + +/*===================================================================== + + Specialized single operations in n256 - sqr & mul + +=====================================================================*/ +EXTERN_C U64* MB_FUNC_NAME(ifma_n256_)(void) +{ + return (U64*)n256_mb; +} + +void MB_FUNC_NAME(ifma_ams52_n256_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_ams52x5_)(r, a, (U64*)n256_mb, n256_k0_mb); +} + +void MB_FUNC_NAME(ifma_amm52_n256_)(U64 r[], const U64 a[], const U64 b[]) +{ + MB_FUNC_NAME(ifma_amm52x5_)(r, a, b, (U64*)n256_mb, n256_k0_mb); +} + +void MB_FUNC_NAME(ifma_tomont52_n256_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52x5_)(r, a, (U64*)n256_rr_mb, (U64*)n256_mb, n256_k0_mb); +} + +void MB_FUNC_NAME(ifma_frommont52_n256_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52_n256_)(r, a, (U64*)ones); +} + +/* +// computes r = 1/z = z^(n256-2) mod n256 +// +// note: z in in Montgomery domain (as soon mul() and sqr() below are amm-functions +// r in Montgomery domain too +*/ +#define sqr_n256 MB_FUNC_NAME(ifma_ams52_n256_) +#define mul_n256 MB_FUNC_NAME(ifma_amm52_n256_) + +void MB_FUNC_NAME(ifma_aminv52_n256_)(U64 r[], const U64 z[]) +{ + int i; + + // pwr_z_Tbl[i][] = z^i, i=0,..,15 + __ALIGN64 U64 pwr_z_Tbl[16][LEN52]; + + MB_FUNC_NAME(ifma_tomont52_n256_)(pwr_z_Tbl[0], (U64*)ones); + MB_FUNC_NAME(mov_FE256_)(pwr_z_Tbl[1], z); + + for(i=2; i<16; i+=2) { + sqr_n256(pwr_z_Tbl[i], pwr_z_Tbl[i/2]); + mul_n256(pwr_z_Tbl[i+1], pwr_z_Tbl[i], z); + } + + // pwr = (n256-2) in big endian + int8u pwr[] = "\xFF\xFF\xFF\xFF\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84" + "\xF3\xB9\xCA\xC2\xFC\x63\x25\x4F"; + // init r = 1 + MB_FUNC_NAME(mov_FE256_)(r, pwr_z_Tbl[0]); + + for(i=0; i<32; i++) { + int v = pwr[i]; + int hi = (v>>4) &0xF; + int lo = v & 0xF; + + sqr_n256(r, r); + sqr_n256(r, r); + sqr_n256(r, r); + sqr_n256(r, r); + if(hi) + mul_n256(r, r, pwr_z_Tbl[hi]); + sqr_n256(r, r); + sqr_n256(r, r); + sqr_n256(r, r); + sqr_n256(r, r); + if(lo) + mul_n256(r, r, pwr_z_Tbl[lo]); + } +} + +/*===================================================================== + + Specialized single operations in n256 - add, sub & neg + +=====================================================================*/ + +void MB_FUNC_NAME(ifma_add52_n256_)(U64 r[], const U64 a[], const U64 b[]) +{ + MB_FUNC_NAME(ifma_add52x5_)(r, a, b, (U64*)n256x2_mb); +} + +void MB_FUNC_NAME(ifma_sub52_n256_)(U64 r[], const U64 a[], const U64 b[]) +{ + MB_FUNC_NAME(ifma_sub52x5_)(r, a, b, (U64*)n256x2_mb); +} + +void MB_FUNC_NAME(ifma_neg52_n256_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_neg52x5_)(r, a, (U64*)n256x2_mb); +} + +__mb_mask MB_FUNC_NAME(lt_mbx_digit_)(const U64 a, const U64 b, const __mb_mask lt_mask) +{ + U64 d = mask_sub64(sub64(a, b), lt_mask, sub64(a, b), set1(1)); + return cmp64_mask(d, get_zero64(), _MM_CMPINT_LT); +} + +/* r = (a>=n256)? a-n256 : a */ +void MB_FUNC_NAME(ifma_fastred52_pn256_)(U64 R[], const U64 A[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], ((U64*)(n256_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(n256_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(n256_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(n256_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(n256_mb))[4]); + + /* lt = {r0 - r4} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + + r0 = mask_mov64(A[0], ~lt, r0); + r1 = mask_mov64(A[1], ~lt, r1); + r2 = mask_mov64(A[2], ~lt, r2); + r3 = mask_mov64(A[3], ~lt, r3); + r4 = mask_mov64(A[4], ~lt, r4); + + /* normalize r0 - r4 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; +} + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_n256_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FE256_)(a,(const U64 (*))n256_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_n256_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FE256_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_n256_)(A); + + return mask; +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n384.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n384.c new file mode 100644 index 000000000..4dfe28c19 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n384.c @@ -0,0 +1,620 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Constants */ + +/* +// EC NIST-P384 prime base point order +// in 2^52 radix +*/ +__ALIGN64 static const int64u n384_mb[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000c196accc52973) }, + { REP8_DECL(0x000b248b0a77aece) }, + { REP8_DECL(0x0004372ddf581a0d) }, + { REP8_DECL(0x000ffffc7634d81f) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x00000000000fffff) } +}; + +/* 2*n384 */ +__ALIGN64 static const int64u n384_x2[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000832d5998a52e6) }, + { REP8_DECL(0x0006491614ef5d9d) }, + { REP8_DECL(0x00086e5bbeb0341b) }, + { REP8_DECL(0x000ffff8ec69b03e) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x00000000001fffff) } +}; + +/* k0 = -( (1/n384 mod 2^DIGIT_SIZE) ) mod 2^DIGIT_SIZE */ +__ALIGN64 static const int64u n384_k0_mb[sizeof(U64)/sizeof(int64u)] = { + REP8_DECL(0x00046089e88fdc45) +}; + +/* to Montgomery conversion constant +// rr = 2^((P384_LEN52*DIGIT_SIZE)*2) mod n384 +*/ +__ALIGN64 static const int64u n384_rr_mb[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x00034124f50ddb2d) }, + { REP8_DECL(0x000c974971bd0d8d) }, + { REP8_DECL(0x0002118942bfd3cc) }, + { REP8_DECL(0x0009f43be8072178) }, + { REP8_DECL(0x0005bf030606de60) }, + { REP8_DECL(0x0000d49174aab1cc) }, + { REP8_DECL(0x000b7a28266895d4) }, + { REP8_DECL(0x000000000003fb05) } +}; + +/* ifma_tomont52_n384_(1) */ +__ALIGN64 static const int64u n384_r_mb[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000ad68d00000000) }, + { REP8_DECL(0x000851313e695333) }, + { REP8_DECL(0x0007e5f24db74f58) }, + { REP8_DECL(0x000b27e0bc8d220a) }, + { REP8_DECL(0x000000000000389c) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) } +}; + +/*===================================================================== + + Specialized single operations over n384: sqr & mul + +=====================================================================*/ +void MB_FUNC_NAME(ifma_amm52_n384_)(U64 r[], const U64 va[], const U64 vb[]) +{ + U64 K = loadu64(n384_k0_mb); + + U64 r0, r1, r2, r3, r4, r5, r6, r7; + int itr; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = get_zero64(); + + for(itr=0; itr < P384_LEN52; itr++) { + U64 Yi, T, LO, HI; + U64 Bi = loadu64(vb); + vb++; + + fma52lo_mem(r0, r0, Bi, va, SIMD_BYTES * 0); + Yi = fma52lo(get_zero64(), r0, K); + T = sub64(get_zero64(), Yi); + LO = and64(T, loadu64(VMASK52)); + HI = add64(Yi, srai64(T,63)); + fma52lo_mem(r1, r1, Bi, va, SIMD_BYTES * 1); + fma52lo_mem(r2, r2, Bi, va, SIMD_BYTES * 2); + fma52lo_mem(r3, r3, Bi, va, SIMD_BYTES * 3); + fma52lo_mem(r4, r4, Bi, va, SIMD_BYTES * 4); + fma52lo_mem(r5, r5, Bi, va, SIMD_BYTES * 5); + fma52lo_mem(r6, r6, Bi, va, SIMD_BYTES * 6); + fma52lo_mem(r7, r7, Bi, va, SIMD_BYTES * 7); + + fma52lo_mem(r0, r0, Yi, n384_mb, SIMD_BYTES * 0); + fma52lo_mem(r1, r1, Yi, n384_mb, SIMD_BYTES * 1); + fma52lo_mem(r2, r2, Yi, n384_mb, SIMD_BYTES * 2); + fma52lo_mem(r3, r3, Yi, n384_mb, SIMD_BYTES * 3); + r1 = add64(r1, srli64(r0, DIGIT_SIZE)); /* carry propagation */ + r4 = add64(r4, LO); /* fma52lo_mem(r4, r4, Yi, n384_mb, SIMD_BYTES * 4); */ + r5 = add64(r5, LO); /* fma52lo_mem(r5, r5, Yi, n384_mb, SIMD_BYTES * 5); */ + r6 = add64(r6, LO); /* fma52lo_mem(r6, r6, Yi, n384_mb, SIMD_BYTES * 6); */ + fma52lo_mem(r7, r7, Yi, n384_mb, SIMD_BYTES * 7); + + fma52hi_mem(r0, r1, Bi, va, SIMD_BYTES * 0); + fma52hi_mem(r1, r2, Bi, va, SIMD_BYTES * 1); + fma52hi_mem(r2, r3, Bi, va, SIMD_BYTES * 2); + fma52hi_mem(r3, r4, Bi, va, SIMD_BYTES * 3); + fma52hi_mem(r4, r5, Bi, va, SIMD_BYTES * 4); + fma52hi_mem(r5, r6, Bi, va, SIMD_BYTES * 5); + fma52hi_mem(r6, r7, Bi, va, SIMD_BYTES * 6); + fma52hi_mem(r7, get_zero64(), Bi, va, SIMD_BYTES * 7); + + fma52hi_mem(r0, r0, Yi, n384_mb, SIMD_BYTES * 0); + fma52hi_mem(r1, r1, Yi, n384_mb, SIMD_BYTES * 1); + fma52hi_mem(r2, r2, Yi, n384_mb, SIMD_BYTES * 2); + fma52hi_mem(r3, r3, Yi, n384_mb, SIMD_BYTES * 3); + r4 = add64(r4, HI); /* fma52hi_mem(r4, r4, Yi, n384_mb, SIMD_BYTES * 4); */ + r5 = add64(r5, HI); /* fma52hi_mem(r5, r5, Yi, n384_mb, SIMD_BYTES * 5); */ + r6 = add64(r6, HI); /* fma52hi_mem(r6, r6, Yi, n384_mb, SIMD_BYTES * 6); */ + fma52hi_mem(r7, r7, Yi, n384_mb, SIMD_BYTES * 7); + } + + // normalization + NORM_LSHIFTR(r, 0, 1) + NORM_LSHIFTR(r, 1, 2) + NORM_LSHIFTR(r, 2, 3) + NORM_LSHIFTR(r, 3, 4) + NORM_LSHIFTR(r, 4, 5) + NORM_LSHIFTR(r, 5, 6) + NORM_LSHIFTR(r, 6, 7) + + r[0] = r0; + r[1] = r1; + r[2] = r2; + r[3] = r3; + r[4] = r4; + r[5] = r5; + r[6] = r6; + r[7] = r7; +} + +#define ROUND_MUL(I, J, R_LO, R_HI) \ + R_LO = fma52lo(R_LO, va[I], vb[J]); \ + R_HI = fma52hi(R_HI, va[I], vb[J]); + +#define N384_REDUCTION_ROUND(u, r0, r1, r2, r3, r4, r5, r6, r7, r8, modulus, k) \ +{ \ + U64 t = sub64(get_zero64(), u); \ + U64 lo = and64(t, loadu64(VMASK52)); \ + U64 hi = add64(u, srai64(t,63)); \ + \ + r0 = fma52lo(r0, u, modulus[0]); \ + r1 = fma52lo(r1, u, modulus[1]); \ + r2 = fma52lo(r2, u, modulus[2]); \ + r3 = fma52lo(r3, u, modulus[3]); \ + r7 = fma52lo(r7, u, modulus[7]); \ + r1 = add64(r1, srli64(r0, DIGIT_SIZE)); /* carry propagation */ \ + r4 = add64(r4, lo); /*r4 = fma52lo(r4, u, modulus[4]); */ \ + r5 = add64(r5, lo); /*r5 = fma52lo(r5, u, modulus[5]); */ \ + r6 = add64(r6, lo); /*r6 = fma52lo(r6, u, modulus[6]); */ \ + \ + r1 = fma52hi(r1, u, modulus[0]); \ + r2 = fma52hi(r2, u, modulus[1]); \ + r3 = fma52hi(r3, u, modulus[2]); \ + r4 = fma52hi(r4, u, modulus[3]); \ + r8 = fma52hi(r8, u, modulus[7]); \ + u = fma52lo(get_zero64(), r1, k); /* update u = r1*k */ \ + r5 = add64(r5, hi); /*r5 = fma52hi(r5, u, modulus[4]); */ \ + r6 = add64(r6, hi); /*r6 = fma52hi(r6, u, modulus[5]); */ \ + r7 = add64(r7, hi); /*r7 = fma52hi(r7, u, modulus[6]); */ \ +} + +void MB_FUNC_NAME(ifma_ams52_n384_)(U64 r[], const U64 va[]) +{ + U64 K = loadu64(n384_k0_mb); + + const U64* vb = va; + U64* modulus = (U64*)n384_mb; + + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; + U64 u; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = + r10 = r11 = r12 = r13 = r14 = r15 = get_zero64(); + + // full square + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(0, 5, r5, r6) + ROUND_MUL(0, 6, r6, r7) + ROUND_MUL(0, 7, r7, r8) + + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(1, 5, r6, r7) + ROUND_MUL(1, 6, r7, r8) + ROUND_MUL(1, 7, r8, r9) + + ROUND_MUL(2, 3, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(2, 5, r7, r8) + ROUND_MUL(2, 6, r8, r9) + ROUND_MUL(2, 7, r9, r10) + + ROUND_MUL(3, 4, r7, r8) + ROUND_MUL(3, 5, r8, r9) + ROUND_MUL(3, 6, r9, r10) + ROUND_MUL(3, 7, r10,r11) + + ROUND_MUL(4, 5, r9, r10) + ROUND_MUL(4, 6, r10,r11) + ROUND_MUL(4, 7, r11,r12) + + ROUND_MUL(5, 6, r11,r12) + ROUND_MUL(5, 7, r12,r13) + + ROUND_MUL(6, 7, r13,r14) + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + r9 = add64(r9, r9); + r10 = add64(r10, r10); + r11 = add64(r11, r11); + r12 = add64(r12, r12); + r13 = add64(r13, r13); + r14 = add64(r14, r14); + + ROUND_MUL(0, 0, r0, r1) + u = fma52lo(get_zero64(), r0, K); + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 4, r8, r9) + ROUND_MUL(5, 5, r10, r11) + ROUND_MUL(6, 6, r12, r13) + ROUND_MUL(7, 7, r14, r15) + + // reduction + N384_REDUCTION_ROUND(u, r0, r1, r2, r3, r4, r5, r6, r7, r8, modulus, K); + N384_REDUCTION_ROUND(u, r1, r2, r3, r4, r5, r6, r7, r8, r9, modulus, K); + N384_REDUCTION_ROUND(u, r2, r3, r4, r5, r6, r7, r8, r9, r10, modulus, K); + N384_REDUCTION_ROUND(u, r3, r4, r5, r6, r7, r8, r9, r10,r11, modulus, K); + N384_REDUCTION_ROUND(u, r4, r5, r6, r7, r8, r9, r10,r11,r12, modulus, K); + N384_REDUCTION_ROUND(u, r5, r6, r7, r8, r9, r10,r11,r12,r13, modulus, K); + N384_REDUCTION_ROUND(u, r6, r7, r8, r9, r10,r11,r12,r13,r14, modulus, K); + N384_REDUCTION_ROUND(u, r7, r8, r9, r10,r11,r12,r13,r14,r15, modulus, K); + + // normalization + NORM_LSHIFTR(r, 8, 9) + NORM_LSHIFTR(r, 9, 10) + NORM_LSHIFTR(r, 10, 11) + NORM_LSHIFTR(r, 11, 12) + NORM_LSHIFTR(r, 12, 13) + NORM_LSHIFTR(r, 13, 14) + NORM_LSHIFTR(r, 14, 15) + + r[0] = r8; + r[1] = r9; + r[2] = r10; + r[3] = r11; + r[4] = r12; + r[5] = r13; + r[6] = r14; + r[7] = r15; +} + +void MB_FUNC_NAME(ifma_tomont52_n384_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52_n384_)(r, a, (U64*)n384_rr_mb); +} + +void MB_FUNC_NAME(ifma_frommont52_n384_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52_n384_)(r, a, (U64*)ones); +} + +/* +// computes r = 1/z = z^(n384-2) mod n384 +// +// note: z in in Montgomery domain (as soon mul() and sqr() below are amm-functions +// r in Montgomery domain too +*/ +#define fe52_sqr MB_FUNC_NAME(ifma_ams52_n384_) +#define fe52_mul MB_FUNC_NAME(ifma_amm52_n384_) + +/* r = base^(2^n) */ +__INLINE void fe52_sqr_pwr(U64 r[], const U64 base[], int n) +{ + if(r!=base) { + fe52_sqr(r,base); + n--; + } + for(; n>0; n--) + fe52_sqr(r,r); +} + +void MB_FUNC_NAME(ifma_aminv52_n384_)(U64 r[], const U64 z[]) +{ + int i; + + // pwr_z_Tbl[i][] = z^i, i=0,..,15 + __ALIGN64 U64 pwr_z_Tbl[16][P384_LEN52]; + __ALIGN64 U64 lexp[P384_LEN52]; + + MB_FUNC_NAME(mov_FE384_)(pwr_z_Tbl[0], (U64*)n384_r_mb); + MB_FUNC_NAME(mov_FE384_)(pwr_z_Tbl[1], z); + + for(i=2; i<16; i+=2) { + fe52_sqr(pwr_z_Tbl[i], pwr_z_Tbl[i/2]); + fe52_mul(pwr_z_Tbl[i+1], pwr_z_Tbl[i], z); + } + + // pwr = (n384-2) in big endian + int8u pwr[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC7\x63\x4D\x81\xF4\x37\x2D\xDF" + "\x58\x1A\x0D\xB2\x48\xB0\xA7\x7A" + "\xEC\xEC\x19\x6A\xCC\xC5\x29\x71"; + + /* + // process low part of the exponent: "0xc7634d81f4372ddf 0x581a0db248b0a77a 0xecec196accc52973" + */ + /* init result */ + MB_FUNC_NAME(mov_FE384_)(lexp, (U64*)n384_r_mb); + + for(i=24; i>4) &0xF; + int lo = v & 0xF; + + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + if(hi) + fe52_mul(lexp, lexp, pwr_z_Tbl[hi]); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + if(lo) + fe52_mul(lexp, lexp, pwr_z_Tbl[lo]); + } + + /* + // process high part of the exponent: "0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff" + */ + __ALIGN64 U64 u[P384_LEN52]; + __ALIGN64 U64 v[P384_LEN52]; + + fe52_sqr(v, z); /* v = z^2 */ + fe52_mul(u, v, z); /* u = z^2 * z = z^3 */ + + fe52_sqr_pwr(v, u, 2); /* v= (z^3)^(2^2) = z^12 */ + fe52_mul(u, v, u); /* u = z^12 * z^3 = z^15 = z^(0xF) */ + + fe52_sqr_pwr(v, u, 4); /* v= (z^0xF)^(2^4) = z^(0xF0) */ + fe52_mul(u, v, u); /* u = z^0xF0 * z^(0xF) = z^(0xFF) */ + + fe52_sqr_pwr(v, u, 8); /* v= (z^0xFF)^(2^8) = z^(0xFF00) */ + fe52_mul(u, v, u); /* u = z^0xFF00 * z^(0xFF) = z^(0xFFFF) */ + + fe52_sqr_pwr(v, u, 16); /* v= (z^0xFFFF)^(2^16) = z^(0xFFFF0000) */ + fe52_mul(u, v, u); /* u = z^0xFFFF0000 * z^(0xFFFF) = z^(0xFFFFFFFF) */ + + fe52_sqr_pwr(v, u, 32); /* v= (z^0xFFFFFFFF)^(2^32) = z^(0xFFFFFFFF00000000) */ + fe52_mul(u, v, u); /* u = z^0xFFFFFFFF00000000 * z^(0xFFFFFFFF) = z^(0xFFFFFFFFFFFFFFFF) */ + + fe52_sqr_pwr(v, u, 64); + fe52_mul(v, v, u); /* v = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, u); /* v = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + + /* combine low and high results */ + fe52_sqr_pwr(v, v, 64*3); /* u = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000.0000000000000000.0000000000000000) */ + fe52_mul(r, v, lexp); /* r = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.c7634d81f4372ddf.581a0db248b0a77a.ecec196accc52973) */ +} + +/*===================================================================== + + Specialized single operations over n384 add, sub, neg + +=====================================================================*/ +static __mb_mask MB_FUNC_NAME(lt_mbx_digit_)(const U64 a, const U64 b, const __mb_mask lt_mask) +{ + U64 d = mask_sub64(sub64(a, b), lt_mask, sub64(a, b), set1(1)); + return cmp64_mask(d, get_zero64(), _MM_CMPINT_LT); +} + +void MB_FUNC_NAME(ifma_add52_n384_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a + b */ + U64 r0 = add64(A[0], B[0]); + U64 r1 = add64(A[1], B[1]); + U64 r2 = add64(A[2], B[2]); + U64 r3 = add64(A[3], B[3]); + U64 r4 = add64(A[4], B[4]); + U64 r5 = add64(A[5], B[5]); + U64 r6 = add64(A[6], B[6]); + U64 r7 = add64(A[7], B[7]); + + /* lt = {r0 - r7} < 2*n */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)( r0, ((U64*)(n384_x2))[0], 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r1, ((U64*)(n384_x2))[1], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r2, ((U64*)(n384_x2))[2], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r3, ((U64*)(n384_x2))[3], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r4, ((U64*)(n384_x2))[4], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r5, ((U64*)(n384_x2))[5], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r6, ((U64*)(n384_x2))[6], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r7, ((U64*)(n384_x2))[7], lt); + + /* {r0 - r7} -= 2*n */ + r0 = mask_sub64(r0, ~lt, r0, ((U64*)(n384_x2))[0]); + r1 = mask_sub64(r1, ~lt, r1, ((U64*)(n384_x2))[1]); + r2 = mask_sub64(r2, ~lt, r2, ((U64*)(n384_x2))[2]); + r3 = mask_sub64(r3, ~lt, r3, ((U64*)(n384_x2))[3]); + r4 = mask_sub64(r4, ~lt, r4, ((U64*)(n384_x2))[4]); + r5 = mask_sub64(r5, ~lt, r5, ((U64*)(n384_x2))[5]); + r6 = mask_sub64(r6, ~lt, r6, ((U64*)(n384_x2))[6]); + r7 = mask_sub64(r7, ~lt, r7, ((U64*)(n384_x2))[7]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + NORM_ASHIFTR(r, 4,5) + NORM_ASHIFTR(r, 5,6) + NORM_ASHIFTR(r, 6,7) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; +} + +void MB_FUNC_NAME(ifma_sub52_n384_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + U64 r5 = sub64(A[5], B[5]); + U64 r6 = sub64(A[6], B[6]); + U64 r7 = sub64(A[7], B[7]); + + /* lt = {r0 - r7} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r5, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r6, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r7, get_zero64(), lt); + + r0 = mask_add64(r0, lt, r0, ((U64*)(n384_x2))[0]); + r1 = mask_add64(r1, lt, r1, ((U64*)(n384_x2))[1]); + r2 = mask_add64(r2, lt, r2, ((U64*)(n384_x2))[2]); + r3 = mask_add64(r3, lt, r3, ((U64*)(n384_x2))[3]); + r4 = mask_add64(r4, lt, r4, ((U64*)(n384_x2))[4]); + r5 = mask_add64(r5, lt, r5, ((U64*)(n384_x2))[5]); + r6 = mask_add64(r6, lt, r6, ((U64*)(n384_x2))[6]); + r7 = mask_add64(r7, lt, r7, ((U64*)(n384_x2))[7]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + NORM_ASHIFTR(r, 4,5) + NORM_ASHIFTR(r, 5,6) + NORM_ASHIFTR(r, 6,7) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; +} + +void MB_FUNC_NAME(ifma_neg52_n384_)(U64 R[], const U64 A[]) +{ + __mb_mask nz_mask = ~MB_FUNC_NAME(is_zero_FE384_)(A); + + /* {r0 - r7} = 2*n - A */ + U64 r0 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[0], A[0] ); + U64 r1 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[1], A[1] ); + U64 r2 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[2], A[2] ); + U64 r3 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[3], A[3] ); + U64 r4 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[4], A[4] ); + U64 r5 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[5], A[5] ); + U64 r6 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[6], A[6] ); + U64 r7 = mask_sub64( A[0], nz_mask, ((U64*)(n384_x2))[7], A[7] ); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + NORM_ASHIFTR(r, 4,5) + NORM_ASHIFTR(r, 5,6) + NORM_ASHIFTR(r, 6,7) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; +} + + +/* r = (a>=n384)? a-n384 : a */ +void MB_FUNC_NAME(ifma_fastred52_pn384_)(U64 R[], const U64 A[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], ((U64*)(n384_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(n384_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(n384_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(n384_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(n384_mb))[4]); + U64 r5 = sub64(A[5], ((U64*)(n384_mb))[5]); + U64 r6 = sub64(A[6], ((U64*)(n384_mb))[6]); + U64 r7 = sub64(A[7], ((U64*)(n384_mb))[7]); + + /* lt = {r0 - r7} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r5, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r6, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r7, get_zero64(), lt); + + r0 = mask_mov64(A[0], ~lt, r0); + r1 = mask_mov64(A[1], ~lt, r1); + r2 = mask_mov64(A[2], ~lt, r2); + r3 = mask_mov64(A[3], ~lt, r3); + r4 = mask_mov64(A[4], ~lt, r4); + r5 = mask_mov64(A[5], ~lt, r5); + r6 = mask_mov64(A[6], ~lt, r6); + r7 = mask_mov64(A[7], ~lt, r7); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + NORM_ASHIFTR(r, 4,5) + NORM_ASHIFTR(r, 5,6) + NORM_ASHIFTR(r, 6,7) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; +} + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_n384_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FE384_)(a,(const U64 (*))n384_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_n384_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FE384_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_n384_)(A); + + return mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n521.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n521.c new file mode 100644 index 000000000..90f0637a2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_n521.c @@ -0,0 +1,777 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Constants */ + +/* +// EC NIST-P521 prime base point order +// in 2^52 radix +*/ +__ALIGN64 static const int64u n521_mb[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000fb71e91386409) }, + { REP8_DECL(0x000b8899c47aebb6) }, + { REP8_DECL(0x000709a5d03bb5c9) }, + { REP8_DECL(0x000966b7fcc0148f) }, + { REP8_DECL(0x000a51868783bf2f) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0000000000000001) } +}; + +/* 2*n521 */ +__ALIGN64 static const int64u n521_x2[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000f6e3d2270c812) }, + { REP8_DECL(0x0007113388f5d76d) }, + { REP8_DECL(0x000e134ba0776b93) }, + { REP8_DECL(0x0002cd6ff980291e) }, + { REP8_DECL(0x0004a30d0f077e5f) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0000000000000003) } +}; +/* k0 = -( (1/n521 mod 2^DIGIT_SIZE) ) mod 2^DIGIT_SIZE */ +__ALIGN64 static const int64u n521_k0_mb[sizeof(U64)/sizeof(int64u)] = { + REP8_DECL(0x000f5ccd79a995c7) +}; + +/* to Montgomery conversion constant +// rr = 2^((P521_LEN52*DIGIT_SIZE)*2) mod n521 +*/ +__ALIGN64 static const int64u n521_rr_mb[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0003b4d7a5b140ce) }, + { REP8_DECL(0x000cb0bf26c55bf9) }, + { REP8_DECL(0x00037e5396c67ee9) }, + { REP8_DECL(0x0002bd1c80cf7b13) }, + { REP8_DECL(0x00073cbe28f15e41) }, + { REP8_DECL(0x000dd6e23d82e49c) }, + { REP8_DECL(0x0003d142b7756e3e) }, + { REP8_DECL(0x00061a8e567bccff) }, + { REP8_DECL(0x00092d0d455bcc6d) }, + { REP8_DECL(0x000383d2d8e03d14) }, + { REP8_DECL(0x0000000000000000) } +}; + +/* ifma_tomont52_n521_(1) */ +__ALIGN64 static const int64u n521_r_mb[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0008000000000000) }, + { REP8_DECL(0x00082470b763cdfb) }, + { REP8_DECL(0x00023bb31dc28a24) }, + { REP8_DECL(0x00047b2d17e2251b) }, + { REP8_DECL(0x00034ca4019ff5b8) }, + { REP8_DECL(0x0002d73cbc3e2068) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) } +}; + + +/*===================================================================== + + Specialized single operations over n384: sqr & mul + +=====================================================================*/ + +void MB_FUNC_NAME(ifma_amm52_n521_)(U64 r[], const U64 va[], const U64 vb[]) +{ + U64 K = loadu64(n521_k0_mb); + + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; + int itr; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = r10 = get_zero64(); + + for(itr=0; itr < P521_LEN52; itr++) { + U64 Yi, T, LO, HI; + U64 Bi = loadu64(vb); + vb++; + + fma52lo_mem(r0, r0, Bi, va, SIMD_BYTES * 0); + fma52lo_mem(r1, r1, Bi, va, SIMD_BYTES * 1); + fma52lo_mem(r2, r2, Bi, va, SIMD_BYTES * 2); + fma52lo_mem(r3, r3, Bi, va, SIMD_BYTES * 3); + fma52lo_mem(r4, r4, Bi, va, SIMD_BYTES * 4); + fma52lo_mem(r5, r5, Bi, va, SIMD_BYTES * 5); + fma52lo_mem(r6, r6, Bi, va, SIMD_BYTES * 6); + fma52lo_mem(r7, r7, Bi, va, SIMD_BYTES * 7); + fma52lo_mem(r8, r8, Bi, va, SIMD_BYTES * 8); + fma52lo_mem(r9, r9, Bi, va, SIMD_BYTES * 9); + fma52lo_mem(r10,r10,Bi, va, SIMD_BYTES * 10); + + Yi = fma52lo(get_zero64(), r0, K); + T = sub64(get_zero64(), Yi); + LO = and64(T, loadu64(VMASK52)); + HI = add64(Yi, srai64(T,63)); + + fma52lo_mem(r0, r0, Yi, n521_mb, SIMD_BYTES * 0); + fma52lo_mem(r1, r1, Yi, n521_mb, SIMD_BYTES * 1); + fma52lo_mem(r2, r2, Yi, n521_mb, SIMD_BYTES * 2); + fma52lo_mem(r3, r3, Yi, n521_mb, SIMD_BYTES * 3); + fma52lo_mem(r4, r4, Yi, n521_mb, SIMD_BYTES * 4); + r1 = add64(r1, srli64(r0, DIGIT_SIZE)); /* carry propagation */ + r5 = add64(r5, LO); /* fma52lo_mem(r5, r5, Yi, n521_mb, SIMD_BYTES * 5); */ + r6 = add64(r6, LO); /* fma52lo_mem(r6, r6, Yi, n521_mb, SIMD_BYTES * 6); */ + r7 = add64(r7, LO); /* fma52lo_mem(r7, r7, Yi, n521_mb, SIMD_BYTES * 7); */ + r8 = add64(r8, LO); /* fma52lo_mem(r8, r8, Yi, n521_mb, SIMD_BYTES * 8); */ + r9 = add64(r9, LO); /* fma52lo_mem(r9, r9, Yi, n521_mb, SIMD_BYTES * 9); */ + r10= add64(r10,Yi); /* fma52lo_mem(r10,r10,Yi, n521_mb, SIMD_BYTES * 10); */ + + fma52hi_mem(r0, r1, Bi, va, SIMD_BYTES * 0); + fma52hi_mem(r1, r2, Bi, va, SIMD_BYTES * 1); + fma52hi_mem(r2, r3, Bi, va, SIMD_BYTES * 2); + fma52hi_mem(r3, r4, Bi, va, SIMD_BYTES * 3); + fma52hi_mem(r4, r5, Bi, va, SIMD_BYTES * 4); + fma52hi_mem(r5, r6, Bi, va, SIMD_BYTES * 5); + fma52hi_mem(r6, r7, Bi, va, SIMD_BYTES * 6); + fma52hi_mem(r7, r8, Bi, va, SIMD_BYTES * 7); + fma52hi_mem(r8, r9, Bi, va, SIMD_BYTES * 8); + fma52hi_mem(r9, r10,Bi, va, SIMD_BYTES * 9); + fma52hi_mem(r10,get_zero64(), Bi, va, SIMD_BYTES * 10); + + fma52hi_mem(r0, r0, Yi, n521_mb, SIMD_BYTES * 0); + fma52hi_mem(r1, r1, Yi, n521_mb, SIMD_BYTES * 1); + fma52hi_mem(r2, r2, Yi, n521_mb, SIMD_BYTES * 2); + fma52hi_mem(r3, r3, Yi, n521_mb, SIMD_BYTES * 3); + fma52hi_mem(r4, r4, Yi, n521_mb, SIMD_BYTES * 4); + r5 = add64(r5, HI); /* fma52hi_mem(r5, r5, Yi, n521_mb, SIMD_BYTES * 5); */ + r6 = add64(r6, HI); /* fma52hi_mem(r6, r6, Yi, n521_mb, SIMD_BYTES * 6); */ + r7 = add64(r7, HI); /* fma52hi_mem(r7, r7, Yi, n521_mb, SIMD_BYTES * 7); */ + r8 = add64(r8, HI); /* fma52hi_mem(r8, r8, Yi, n521_mb, SIMD_BYTES * 8); */ + r9 = add64(r9, HI); /* fma52hi_mem(r9, r9, Yi, n521_mb, SIMD_BYTES * 9); */ + /* 0 == hi(Yi, n521_mb[10] */; + } + + // normalization + NORM_LSHIFTR(r, 0, 1) + NORM_LSHIFTR(r, 1, 2) + NORM_LSHIFTR(r, 2, 3) + NORM_LSHIFTR(r, 3, 4) + NORM_LSHIFTR(r, 4, 5) + NORM_LSHIFTR(r, 5, 6) + NORM_LSHIFTR(r, 6, 7) + NORM_LSHIFTR(r, 7, 8) + NORM_LSHIFTR(r, 8, 9) + NORM_LSHIFTR(r, 9, 10) + + r[0] = r0; + r[1] = r1; + r[2] = r2; + r[3] = r3; + r[4] = r4; + r[5] = r5; + r[6] = r6; + r[7] = r7; + r[8] = r8; + r[9] = r9; + r[10]= r10; +} + +#define ROUND_MUL(I, J, R_LO, R_HI) \ + R_LO = fma52lo(R_LO, va[I], vb[J]); \ + R_HI = fma52hi(R_HI, va[I], vb[J]); + +#define N521_REDUCTION_ROUND(u, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, modulus, k) \ +{ \ + U64 t = sub64(get_zero64(), u); \ + U64 lo = and64(t, loadu64(VMASK52)); \ + U64 hi = add64(u, srai64(t,63)); \ + \ + r0 = fma52lo(r0, u, modulus[0]); \ + r1 = fma52lo(r1, u, modulus[1]); \ + r2 = fma52lo(r2, u, modulus[2]); \ + r3 = fma52lo(r3, u, modulus[3]); \ + r4 = fma52lo(r4, u, modulus[4]); \ + r1 = add64(r1, srli64(r0, DIGIT_SIZE)); /* carry propagation */ \ + r5 = add64(r5, lo); \ + r6 = add64(r6, lo); \ + r7 = add64(r7, lo); \ + r8 = add64(r8, lo); \ + r9 = add64(r9, lo); \ + r10 = add64(r10, u); \ + \ + \ + r1 = fma52hi(r1, u, modulus[0]); \ + r2 = fma52hi(r2, u, modulus[1]); \ + r3 = fma52hi(r3, u, modulus[2]); \ + r4 = fma52hi(r4, u, modulus[3]); \ + r5 = fma52hi(r5, u, modulus[4]); \ + u = fma52lo(get_zero64(), r1, k); /* update u = r1*k */ \ + r6 = add64(r6, hi); \ + r7 = add64(r7, hi); \ + r8 = add64(r8, hi); \ + r9 = add64(r9, hi); \ + r10= add64(r10,hi); \ +} + +void MB_FUNC_NAME(ifma_ams52_n521_)(U64 r[], const U64 va[]) +{ + U64 K = loadu64(n521_k0_mb); + + const U64* vb = va; + U64* modulus = (U64*)n521_mb; + + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + U64 r20, r21; + U64 u; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = r10 = + r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19 = r20 = r21 = get_zero64(); + + // full square + ROUND_MUL(0, 1, r1, r2); + ROUND_MUL(0, 2, r2, r3); + ROUND_MUL(0, 3, r3, r4); + ROUND_MUL(0, 4, r4, r5); + ROUND_MUL(0, 5, r5, r6); + ROUND_MUL(0, 6, r6, r7); + ROUND_MUL(0, 7, r7, r8); + ROUND_MUL(0, 8, r8, r9); + ROUND_MUL(0, 9, r9, r10); + ROUND_MUL(0, 10,r10,r11); + + ROUND_MUL(1, 2, r3, r4); + ROUND_MUL(1, 3, r4, r5); + ROUND_MUL(1, 4, r5, r6); + ROUND_MUL(1, 5, r6, r7); + ROUND_MUL(1, 6, r7, r8); + ROUND_MUL(1, 7, r8, r9); + ROUND_MUL(1, 8, r9, r10); + ROUND_MUL(1, 9, r10,r11); + ROUND_MUL(1, 10,r11,r12); + + ROUND_MUL(2, 3, r5, r6); + ROUND_MUL(2, 4, r6, r7); + ROUND_MUL(2, 5, r7, r8); + ROUND_MUL(2, 6, r8, r9); + ROUND_MUL(2, 7, r9, r10); + ROUND_MUL(2, 8, r10,r11); + ROUND_MUL(2, 9, r11,r12); + ROUND_MUL(2, 10,r12,r13); + + ROUND_MUL(3, 4, r7, r8); + ROUND_MUL(3, 5, r8, r9); + ROUND_MUL(3, 6, r9, r10); + ROUND_MUL(3, 7, r10,r11); + ROUND_MUL(3, 8, r11,r12); + ROUND_MUL(3, 9, r12,r13); + ROUND_MUL(3, 10,r13,r14); + + ROUND_MUL(4, 5, r9, r10); + ROUND_MUL(4, 6, r10,r11); + ROUND_MUL(4, 7, r11,r12); + ROUND_MUL(4, 8, r12,r13); + ROUND_MUL(4, 9, r13,r14); + ROUND_MUL(4, 10,r14,r15); + + ROUND_MUL(5, 6, r11,r12); + ROUND_MUL(5, 7, r12,r13); + ROUND_MUL(5, 8, r13,r14); + ROUND_MUL(5, 9, r14,r15); + ROUND_MUL(5, 10,r15,r16); + + ROUND_MUL(6, 7, r13,r14); + ROUND_MUL(6, 8, r14,r15); + ROUND_MUL(6, 9, r15,r16); + ROUND_MUL(6, 10,r16,r17); + + ROUND_MUL(7, 8, r15,r16); + ROUND_MUL(7, 9, r16,r17); + ROUND_MUL(7, 10,r17,r18); + + ROUND_MUL(8, 9, r17,r18); + ROUND_MUL(8, 10,r18,r19); + + ROUND_MUL(9, 10,r19,r20); + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + r9 = add64(r9, r9); + r10 = add64(r10, r10); + r11 = add64(r11, r11); + r12 = add64(r12, r12); + r13 = add64(r13, r13); + r14 = add64(r14, r14); + r15 = add64(r15, r15); + r16 = add64(r16, r16); + r17 = add64(r17, r17); + r18 = add64(r18, r18); + r19 = add64(r19, r19); + r20 = add64(r20, r20); + + ROUND_MUL(0, 0, r0, r1); + u = fma52lo(get_zero64(), r0, K); + ROUND_MUL(1, 1, r2, r3); + ROUND_MUL(2, 2, r4, r5); + ROUND_MUL(3, 3, r6, r7); + ROUND_MUL(4, 4, r8, r9); + ROUND_MUL(5, 5, r10, r11); + ROUND_MUL(6, 6, r12, r13); + ROUND_MUL(7, 7, r14, r15); + ROUND_MUL(8, 8, r16, r17); + ROUND_MUL(9, 9, r18, r19); + ROUND_MUL(10,10,r20, r21); + + // reduction n521 + N521_REDUCTION_ROUND(u, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, modulus, K); + N521_REDUCTION_ROUND(u, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, modulus, K); + N521_REDUCTION_ROUND(u, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, modulus, K); + N521_REDUCTION_ROUND(u, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, modulus, K); + N521_REDUCTION_ROUND(u, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, modulus, K); + N521_REDUCTION_ROUND(u, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, modulus, K); + N521_REDUCTION_ROUND(u, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, modulus, K); + N521_REDUCTION_ROUND(u, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, modulus, K); + N521_REDUCTION_ROUND(u, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, modulus, K); + N521_REDUCTION_ROUND(u, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, modulus, K); + N521_REDUCTION_ROUND(u, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, modulus, K); + + + // normalization + NORM_LSHIFTR(r, 11, 12) + NORM_LSHIFTR(r, 12, 13) + NORM_LSHIFTR(r, 13, 14) + NORM_LSHIFTR(r, 14, 15) + NORM_LSHIFTR(r, 15, 16) + NORM_LSHIFTR(r, 16, 17) + NORM_LSHIFTR(r, 17, 18) + NORM_LSHIFTR(r, 18, 19) + NORM_LSHIFTR(r, 19, 20) + NORM_LSHIFTR(r, 20, 21) + + r[0] = r11; + r[1] = r12; + r[2] = r13; + r[3] = r14; + r[4] = r15; + r[5] = r16; + r[6] = r17; + r[7] = r18; + r[8] = r19; + r[9] = r20; + r[10]= r21; +} + +void MB_FUNC_NAME(ifma_tomont52_n521_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52_n521_)(r, a, (U64*)n521_rr_mb); +} + +void MB_FUNC_NAME(ifma_frommont52_n521_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52_n521_)(r, a, (U64*)ones); +} + +/* +// computes r = 1/z = z^(n384-2) mod n384 +// +// note: z in in Montgomery domain (as soon mul() and sqr() below are amm-functions +// r in Montgomery domain too +*/ +#define fe52_sqr MB_FUNC_NAME(ifma_ams52_n521_) +#define fe52_mul MB_FUNC_NAME(ifma_amm52_n521_) + +/* r = base^(2^n) */ +__INLINE void fe52_sqr_pwr(U64 r[], const U64 base[], int n) +{ + if(r!=base) { + fe52_sqr(r,base); + n--; + } + for(; n>0; n--) + fe52_sqr(r,r); +} + +void MB_FUNC_NAME(ifma_aminv52_n521_)(U64 r[], const U64 z[]) +{ + int i; + + // pwr_z_Tbl[i][] = z^i, i=0,..,15 + __ALIGN64 U64 pwr_z_Tbl[16][P521_LEN52]; + __ALIGN64 U64 lexp[P521_LEN52]; + + MB_FUNC_NAME(mov_FE521_)(pwr_z_Tbl[0], (U64*)n521_r_mb); + MB_FUNC_NAME(mov_FE521_)(pwr_z_Tbl[1], z); + + for(i=2; i<16; i+=2) { + fe52_sqr(pwr_z_Tbl[i], pwr_z_Tbl[i/2]); + fe52_mul(pwr_z_Tbl[i+1], pwr_z_Tbl[i], z); + } + + // pwr = (n521-2) in big endian + int8u pwr[] = "\x1\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFA" + "\x51\x86\x87\x83\xBF\x2F\x96\x6B" + "\x7F\xCC\x01\x48\xF7\x09\xA5\xD0" + "\x3B\xB5\xC9\xB8\x89\x9C\x47\xAE" + "\xBB\x6F\xB7\x1E\x91\x38\x64\x07"; + + /* + // process 25 low bytes of the exponent: :FA 51 86 ... 64 07" + */ + /* init result */ + MB_FUNC_NAME(mov_FE521_)(lexp, (U64*)n521_r_mb); + + for(i=33; i>4) &0xF; + int lo = v & 0xF; + + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + if(hi) + fe52_mul(lexp, lexp, pwr_z_Tbl[hi]); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + fe52_sqr(lexp, lexp); + if(lo) + fe52_mul(lexp, lexp, pwr_z_Tbl[lo]); + } + + /* + // process high part of the exponent: "0x1 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff" + */ + __ALIGN64 U64 u[P521_LEN52]; + __ALIGN64 U64 v[P521_LEN52]; + + MB_FUNC_NAME(mov_FE521_)(u, pwr_z_Tbl[15]); /* u = z^0xF */ + + fe52_sqr_pwr(v, u, 4); /* v= (z^0xF)^(2^4) = z^(0xF0) */ + fe52_mul(u, v, u); /* u = z^0xF0 * z^(0xF) = z^(0xFF) */ + + fe52_sqr_pwr(v, u, 8); /* v= (z^0xFF)^(2^8) = z^(0xFF00) */ + fe52_mul(u, v, u); /* u = z^0xFF00 * z^(0xFF) = z^(0xFFFF) */ + + fe52_sqr_pwr(v, u, 16); /* v= (z^0xFFFF)^(2^16) = z^(0xFFFF0000) */ + fe52_mul(u, v, u); /* u = z^0xFFFF0000 * z^(0xFFFF) = z^(0xFFFFFFFF) */ + + fe52_sqr_pwr(v, u, 32); /* v= (z^0xFFFFFFFF)^(2^32) = z^(0xFFFFFFFF00000000) */ + fe52_mul(u, v, u); /* u = z^0xFFFFFFFF00000000 * z^(0xFFFFFFFF) = z^(0xFFFFFFFFFFFFFFFF) */ + + fe52_sqr_pwr(v, z, 64); + fe52_mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF) */ + + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + + /* combine low and high results */ + fe52_sqr_pwr(v, v, 64*4+8);/* u = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.00.0000000000000000.0000000000000000.0000000000000000.0000000000000000) */ + fe52_mul(r, v, lexp); /* r = z^(0x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFA.51868783BF2F966B.7FCC0148F709A5D0.3BB5C9B8899C47AE.BB6FB71E91386407) */ +} + + +/*===================================================================== + + Specialized single operations over n521 add, sub, neg + +=====================================================================*/ +__INLINE __mb_mask MB_FUNC_NAME(lt_mbx_digit_)(const U64 a, const U64 b, const __mb_mask lt_mask) +{ + U64 d = mask_sub64(sub64(a, b), lt_mask, sub64(a, b), set1(1)); + return cmp64_mask(d, get_zero64(), _MM_CMPINT_LT); +} + +void MB_FUNC_NAME(ifma_add52_n521_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a + b */ + U64 r0 = add64(A[0], B[0]); + U64 r1 = add64(A[1], B[1]); + U64 r2 = add64(A[2], B[2]); + U64 r3 = add64(A[3], B[3]); + U64 r4 = add64(A[4], B[4]); + U64 r5 = add64(A[5], B[5]); + U64 r6 = add64(A[6], B[6]); + U64 r7 = add64(A[7], B[7]); + U64 r8 = add64(A[8], B[8]); + U64 r9 = add64(A[9], B[9]); + U64 r10= add64(A[10],B[10]); + + /* lt = {r0 - r10} < 2*n */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)( r0, ((U64*)(n521_x2))[0], 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r1, ((U64*)(n521_x2))[1], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r2, ((U64*)(n521_x2))[2], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r3, ((U64*)(n521_x2))[3], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r4, ((U64*)(n521_x2))[4], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r5, ((U64*)(n521_x2))[5], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r6, ((U64*)(n521_x2))[6], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r7, ((U64*)(n521_x2))[7], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r8, ((U64*)(n521_x2))[8], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r9, ((U64*)(n521_x2))[9], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r10,((U64*)(n521_x2))[10],lt); + + /* {r0 - r10} -= 2*p */ + r0 = mask_sub64(r0, ~lt, r0, ((U64*)(n521_x2))[0]); + r1 = mask_sub64(r1, ~lt, r1, ((U64*)(n521_x2))[1]); + r2 = mask_sub64(r2, ~lt, r2, ((U64*)(n521_x2))[2]); + r3 = mask_sub64(r3, ~lt, r3, ((U64*)(n521_x2))[3]); + r4 = mask_sub64(r4, ~lt, r4, ((U64*)(n521_x2))[4]); + r5 = mask_sub64(r5, ~lt, r5, ((U64*)(n521_x2))[5]); + r6 = mask_sub64(r6, ~lt, r6, ((U64*)(n521_x2))[6]); + r7 = mask_sub64(r7, ~lt, r7, ((U64*)(n521_x2))[7]); + r8 = mask_sub64(r8, ~lt, r8, ((U64*)(n521_x2))[8]); + r9 = mask_sub64(r9, ~lt, r9, ((U64*)(n521_x2))[9]); + r10= mask_sub64(r10,~lt, r10,((U64*)(n521_x2))[10]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9,10) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; + R[8] = r8; + R[9] = r9; + R[10]= r10; +} + +void MB_FUNC_NAME(ifma_sub52_n521_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + U64 r5 = sub64(A[5], B[5]); + U64 r6 = sub64(A[6], B[6]); + U64 r7 = sub64(A[7], B[7]); + U64 r8 = sub64(A[8], B[8]); + U64 r9 = sub64(A[9], B[9]); + U64 r10= sub64(A[10],B[10]); + + /* lt = {r0 - r10} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r5, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r6, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r7, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r8, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r9, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r10,get_zero64(), lt); + + r0 = mask_add64(r0, lt, r0, ((U64*)(n521_x2))[0]); + r1 = mask_add64(r1, lt, r1, ((U64*)(n521_x2))[1]); + r2 = mask_add64(r2, lt, r2, ((U64*)(n521_x2))[2]); + r3 = mask_add64(r3, lt, r3, ((U64*)(n521_x2))[3]); + r4 = mask_add64(r4, lt, r4, ((U64*)(n521_x2))[4]); + r5 = mask_add64(r5, lt, r5, ((U64*)(n521_x2))[5]); + r6 = mask_add64(r6, lt, r6, ((U64*)(n521_x2))[6]); + r7 = mask_add64(r7, lt, r7, ((U64*)(n521_x2))[7]); + r8 = mask_add64(r8, lt, r8, ((U64*)(n521_x2))[8]); + r9 = mask_add64(r9, lt, r9, ((U64*)(n521_x2))[9]); + r10= mask_add64(r10,lt, r10,((U64*)(n521_x2))[10]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9, 10) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; + R[8] = r8; + R[9] = r9; + R[10]= r10; +} + +void MB_FUNC_NAME(ifma_neg52_n521_)(U64 R[], const U64 A[]) +{ + __mb_mask nz_mask = ~MB_FUNC_NAME(is_zero_FE521_)(A); + + /* {r0 - r10} = 2*p - A */ + U64 r0 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[0], A[0] ); + U64 r1 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[1], A[1] ); + U64 r2 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[2], A[2] ); + U64 r3 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[3], A[3] ); + U64 r4 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[4], A[4] ); + U64 r5 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[5], A[5] ); + U64 r6 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[6], A[6] ); + U64 r7 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[7], A[7] ); + U64 r8 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[8], A[8] ); + U64 r9 = mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[9], A[9] ); + U64 r10= mask_sub64( A[0], nz_mask, ((U64*)(n521_x2))[10],A[10]); + + /* normalize r0 - r10 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9, 10) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; + R[8] = r8; + R[9] = r9; + R[10]= r10; +} + +// Disable optimization for VS17 +#if defined(_MSC_VER) && (_MSC_VER < 1920) && !defined(__INTEL_COMPILER) + #pragma optimize( "", off ) +#endif + +/* r = (a>=n521)? a-n521 : a */ +void MB_FUNC_NAME(ifma_fastred52_pn521_)(U64 R[], const U64 A[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], ((U64*)(n521_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(n521_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(n521_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(n521_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(n521_mb))[4]); + U64 r5 = sub64(A[5], ((U64*)(n521_mb))[5]); + U64 r6 = sub64(A[6], ((U64*)(n521_mb))[6]); + U64 r7 = sub64(A[7], ((U64*)(n521_mb))[7]); + U64 r8 = sub64(A[8], ((U64*)(n521_mb))[8]); + U64 r9 = sub64(A[9], ((U64*)(n521_mb))[9]); + U64 r10= sub64(A[10],((U64*)(n521_mb))[10]); + + /* lt = {r0 - r10} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r5, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r6, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r7, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r8, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r9, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r10,get_zero64(), lt); + + r0 = mask_mov64(A[0], ~lt, r0); + r1 = mask_mov64(A[1], ~lt, r1); + r2 = mask_mov64(A[2], ~lt, r2); + r3 = mask_mov64(A[3], ~lt, r3); + r4 = mask_mov64(A[4], ~lt, r4); + r5 = mask_mov64(A[5], ~lt, r5); + r6 = mask_mov64(A[6], ~lt, r6); + r7 = mask_mov64(A[7], ~lt, r7); + r8 = mask_mov64(A[8], ~lt, r8); + r9 = mask_mov64(A[9], ~lt, r9); + r10= mask_mov64(A[10],~lt, r10); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9,10) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; + R[8] = r8; + R[9] = r9; + R[10]= r10; +} + +#if defined(_MSC_VER) && (_MSC_VER < 1920) && !defined(__INTEL_COMPILER) + #pragma optimize( "", on ) +#endif + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_n521_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FE521_)(a,(const U64 (*))n521_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_n521_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FE521_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_n521_)(A); + + return mask; +} \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p256.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p256.c new file mode 100644 index 000000000..421708ec9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p256.c @@ -0,0 +1,688 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Constants */ +#define LEN52 NUMBER_OF_DIGITS(256,DIGIT_SIZE) + +/* +// prime256 = 2^256 - 2^224 + 2^192 + 2^96 -1 +// in 2^52 radix +*/ +__ALIGN64 static const int64u p256_mb[LEN52][8] = { + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x00000fffffffffff) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000001000000000) }, + { REP8_DECL(0x0000ffffffff0000) } +}; + +__ALIGN64 static const int64u p256x2_mb[LEN52][8] = { + { REP8_DECL(0x000ffffffffffffe) }, + { REP8_DECL(0x00001fffffffffff) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000002000000000) }, + { REP8_DECL(0x0001fffffffe0000) } +}; + +/* +// Note that +// k0 = -(1/p256 mod 2^DIGIT_SIZE) equals 1 +// The implementation takes this fact into account +*/ + +/* to Montgomery conversion constant +// rr = 2^((5*DIGIT_SIZE)*2) mod p256 +*/ +__ALIGN64 static const int64u p256_rr_mb[5][8] = { + { REP8_DECL(0x0000000000000300) }, + { REP8_DECL(0x000ffffffff00000) }, + { REP8_DECL(0x000ffffefffffffb) }, + { REP8_DECL(0x000fdfffffffffff) }, + { REP8_DECL(0x0000000004ffffff) } +}; + + + +/* other constants */ +__ALIGN64 static const int64u VDIGIT_MASK_[8] = + {DIGIT_MASK, DIGIT_MASK, DIGIT_MASK, DIGIT_MASK, + DIGIT_MASK, DIGIT_MASK, DIGIT_MASK, DIGIT_MASK}; +#define VDIGIT_MASK loadu64(VDIGIT_MASK_) + +#define P256_PRIME_TOP_ 0xFFFFFFFF0000LL +__ALIGN64 static const int64u VP256_PRIME_TOP_[8] = + {P256_PRIME_TOP_, P256_PRIME_TOP_, P256_PRIME_TOP_, P256_PRIME_TOP_, + P256_PRIME_TOP_, P256_PRIME_TOP_, P256_PRIME_TOP_, P256_PRIME_TOP_}; +#define VP256_PRIME_TOP loadu64(VP256_PRIME_TOP_) + + +/* Round operations */ + +#define ROUND_MUL_SRC(I, J, S_LO, R_LO, S_HI, R_HI) \ + R_LO = fma52lo(S_LO, va[I], vb[J]); \ + R_HI = fma52hi(S_HI, va[I], vb[J]); + +#define ROUND_MUL(I, J, M0, M1) \ + ROUND_MUL_SRC(I, J, M0, M0, M1, M1) + +/* Reduction round for p256 prime */ + +// Note that k == 1 for p256 curve +#ifdef IFMA_RED + +#define MUL_ADD_P256(u, res0, res1, res2, res3, res4, res5) \ + { \ + U64 u = and64_const(res0, DIGIT_MASK); /* k == 1 */ \ + res0 = fma52lo(res0, u, set64((1ULL<<52) - 1)); \ + res1 = fma52hi(res1, u, set64((1ULL<<52) - 1)); \ + res1 = add64(res1, srli64(res0, 52)); \ + res1 = fma52lo(res1, u, set64((1ULL<<44) - 1)); \ + res2 = fma52hi(res2, u, set64((1ULL<<44) - 1)); \ + res3 = fma52lo(res3, u, set64(1ULL<<36)); \ + res4 = fma52hi(res4, u, set64(1ULL<<36)); \ + res4 = fma52lo(res4, u, set64(0xFFFFFFFF0000LL)); \ + res5 = fma52hi(res5, u, set64(0xFFFFFFFF0000LL)); \ + } + +#else // IFMA_RED + +#define MUL_ADD_P256(u, res0, res1, res2, res3, res4, res5) \ + { \ + /* a * ( 2^96 - 1 ) = -a + a * 2^96 = -a + a * 2^{52+44} */ \ + U64 u = and64(res0, VDIGIT_MASK); /* k == 1 */ \ + /*res0 = sub64(res0, u);*/ /* Zero out low 52 bits */ \ + res1 = add64(res1, srli64(res0, DIGIT_SIZE)); /* Carry propagation */ \ + res1 = add64(res1, and64(slli64(u, 44), VDIGIT_MASK)); \ + res2 = add64(res2, srli64(u, DIGIT_SIZE - 44)); \ + /* ( a * 2^{36} ) * 2^{52*3} */ \ + res3 = add64(res3, and64(slli64(u, 36), VDIGIT_MASK)); \ + res4 = add64(res4, srli64(u, DIGIT_SIZE - 36)); \ + /* ( a * (2^{48} - 1) - a * (2^{16} - 1) ) * 2^{52*4} = */ \ + /* ( a * 2^{48} - a * 2^{16} ) * 2^{52*4} */ \ + res4 = fma52lo(res4, u, VP256_PRIME_TOP); \ + res5 = fma52hi(res5, u, VP256_PRIME_TOP); \ + } + +#endif // IFMA_RED + +/*===================================================================== + + Specialized single and dual operations in p256 - sqr & mul + +=====================================================================*/ + +void MB_FUNC_NAME(ifma_ams52_p256_)(U64 r[], const U64 va[]) +{ + const U64* vb = va; + + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + // Calculate full square + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(3, 4, r7, r8) + + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(2, 3, r5, r6) + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + + ROUND_MUL(0, 0, r0, r1) + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 4, r8, r9) + + // Reduction + MUL_ADD_P256(u0, r0, r1, r2, r3, r4, r5); + MUL_ADD_P256(u1, r1, r2, r3, r4, r5, r6); + MUL_ADD_P256(u2, r2, r3, r4, r5, r6, r7); + MUL_ADD_P256(u3, r3, r4, r5, r6, r7, r8); + MUL_ADD_P256(u4, r4, r5, r6, r7, r8, r9); + + // normalization + NORM_LSHIFTR(r, 5, 6) + NORM_LSHIFTR(r, 6, 7) + NORM_LSHIFTR(r, 7, 8) + NORM_LSHIFTR(r, 8, 9) + + r[0] = r5; + r[1] = r6; + r[2] = r7; + r[3] = r8; + r[4] = r9; +} + +void MB_FUNC_NAME(ifma_amm52_p256_)(U64 r[], const U64 va[], const U64 vb[]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + ROUND_MUL(4, 4, r8, r9) + ROUND_MUL(3, 0, r3, r4) + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(2, 1, r3, r4) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(3, 1, r4, r5) + ROUND_MUL(4, 0, r4, r5) + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(2, 3, r5, r6) + ROUND_MUL(3, 2, r5, r6) + ROUND_MUL(4, 1, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 2, r6, r7) + ROUND_MUL(0, 0, r0, r1) + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(1, 0, r1, r2) + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 0, r2, r3) + ROUND_MUL(3, 4, r7, r8) + ROUND_MUL(4, 3, r7, r8) + + // Reduction + MUL_ADD_P256(u0, r0, r1, r2, r3, r4, r5); + MUL_ADD_P256(u1, r1, r2, r3, r4, r5, r6); + MUL_ADD_P256(u2, r2, r3, r4, r5, r6, r7); + MUL_ADD_P256(u3, r3, r4, r5, r6, r7, r8); + MUL_ADD_P256(u4, r4, r5, r6, r7, r8, r9); + + // normalization + NORM_LSHIFTR(r, 5, 6) + NORM_LSHIFTR(r, 6, 7) + NORM_LSHIFTR(r, 7, 8) + NORM_LSHIFTR(r, 8, 9) + + r[0] = r5; + r[1] = r6; + r[2] = r7; + r[3] = r8; + r[4] = r9; +} + +void MB_FUNC_NAME(ifma_ams52_p256_dual_)(U64 r0[], U64 r1[], + const U64 inp0[], const U64 inp1[]) +{ + U64 *va; // = (U64 *)inp0; + U64 *vb; // = (U64 *)inp0; + + U64 r00, r01, r02, r03, r04, r05, r06, r07, r08, r09; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + r00 = r01 = r02 = r03 = r04 = r05 = r06 = r07 = r08 = r09 = get_zero64(); + r10 = r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19 = get_zero64(); + + /// Calculate full square + va = vb = (U64 *)inp0; + // Multiplication + ROUND_MUL(0, 1, r01, r02) + ROUND_MUL(0, 2, r02, r03) + ROUND_MUL(0, 3, r03, r04) + ROUND_MUL(0, 4, r04, r05) + ROUND_MUL(1, 4, r05, r06) + ROUND_MUL(2, 4, r06, r07) + ROUND_MUL(3, 4, r07, r08) + ROUND_MUL(1, 2, r03, r04) + ROUND_MUL(1, 3, r04, r05) + ROUND_MUL(2, 3, r05, r06) + // Doubling + r01 = add64(r01, r01); + r02 = add64(r02, r02); + r03 = add64(r03, r03); + r04 = add64(r04, r04); + r05 = add64(r05, r05); + r06 = add64(r06, r06); + r07 = add64(r07, r07); + r08 = add64(r08, r08); + // Adding square + ROUND_MUL(0, 0, r00, r01) + ROUND_MUL(1, 1, r02, r03) + ROUND_MUL(2, 2, r04, r05) + ROUND_MUL(3, 3, r06, r07) + ROUND_MUL(4, 4, r08, r09) + + /// Calculate full square + va = vb = (U64 *)inp1; + // Multiplication + ROUND_MUL(0, 1, r11, r12) + ROUND_MUL(0, 2, r12, r13) + ROUND_MUL(0, 3, r13, r14) + ROUND_MUL(0, 4, r14, r15) + ROUND_MUL(1, 4, r15, r16) + ROUND_MUL(2, 4, r16, r17) + ROUND_MUL(3, 4, r17, r18) + ROUND_MUL(1, 2, r13, r14) + ROUND_MUL(1, 3, r14, r15) + ROUND_MUL(2, 3, r15, r16) + // Doubling + r11 = add64(r11, r11); + r12 = add64(r12, r12); + r13 = add64(r13, r13); + r14 = add64(r14, r14); + r15 = add64(r15, r15); + r16 = add64(r16, r16); + r17 = add64(r17, r17); + r18 = add64(r18, r18); + // Adding square + ROUND_MUL(0, 0, r10, r11) + ROUND_MUL(1, 1, r12, r13) + ROUND_MUL(2, 2, r14, r15) + ROUND_MUL(3, 3, r16, r17) + ROUND_MUL(4, 4, r18, r19) + + // Reduction res0 + MUL_ADD_P256(u0, r00, r01, r02, r03, r04, r05); + MUL_ADD_P256(u1, r01, r02, r03, r04, r05, r06); + MUL_ADD_P256(u2, r02, r03, r04, r05, r06, r07); + MUL_ADD_P256(u3, r03, r04, r05, r06, r07, r08); + MUL_ADD_P256(u4, r04, r05, r06, r07, r08, r09); + + // Reduction res1 + MUL_ADD_P256(u0, r10, r11, r12, r13, r14, r15); + MUL_ADD_P256(u1, r11, r12, r13, r14, r15, r16); + MUL_ADD_P256(u2, r12, r13, r14, r15, r16, r17); + MUL_ADD_P256(u3, r13, r14, r15, r16, r17, r18); + MUL_ADD_P256(u4, r14, r15, r16, r17, r18, r19); + + // normalization res0 + NORM_LSHIFTR(r0, 5, 6) + NORM_LSHIFTR(r0, 6, 7) + NORM_LSHIFTR(r0, 7, 8) + NORM_LSHIFTR(r0, 8, 9) + + r0[0] = r05; + r0[1] = r06; + r0[2] = r07; + r0[3] = r08; + r0[4] = r09; + + // normalization res1 + NORM_LSHIFTR(r1, 5, 6) + NORM_LSHIFTR(r1, 6, 7) + NORM_LSHIFTR(r1, 7, 8) + NORM_LSHIFTR(r1, 8, 9) + + r1[0] = r15; + r1[1] = r16; + r1[2] = r17; + r1[3] = r18; + r1[4] = r19; +} + +void MB_FUNC_NAME(ifma_amm52_p256_dual_)(U64 r0[], U64 r1[], + const U64 inp0A[], const U64 inp0B[], + const U64 inp1A[], const U64 inp1B[]) +{ + U64 *va, *vb; + + U64 r00, r01, r02, r03, r04, r05, r06, r07, r08, r09; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + r00 = r01 = r02 = r03 = r04 = r05 = r06 = r07 = r08 = r09 = get_zero64(); + r10 = r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19 = get_zero64(); + + // 5x5 multiplication + va = (U64 *)inp0A; + vb = (U64 *)inp0B; + ROUND_MUL(4, 4, r08, r09) + ROUND_MUL(3, 0, r03, r04) + ROUND_MUL(1, 2, r03, r04) + ROUND_MUL(0, 3, r03, r04) + ROUND_MUL(2, 1, r03, r04) + ROUND_MUL(2, 2, r04, r05) + ROUND_MUL(0, 4, r04, r05) + ROUND_MUL(1, 3, r04, r05) + ROUND_MUL(3, 1, r04, r05) + ROUND_MUL(4, 0, r04, r05) + ROUND_MUL(1, 4, r05, r06) + ROUND_MUL(2, 3, r05, r06) + ROUND_MUL(3, 2, r05, r06) + ROUND_MUL(4, 1, r05, r06) + ROUND_MUL(2, 4, r06, r07) + ROUND_MUL(3, 3, r06, r07) + ROUND_MUL(4, 2, r06, r07) + ROUND_MUL(0, 0, r00, r01) + ROUND_MUL(0, 1, r01, r02) + ROUND_MUL(0, 2, r02, r03) + ROUND_MUL(1, 0, r01, r02) + ROUND_MUL(1, 1, r02, r03) + ROUND_MUL(2, 0, r02, r03) + ROUND_MUL(3, 4, r07, r08) + ROUND_MUL(4, 3, r07, r08) + + // 5x5 multiplication + va = (U64 *)inp1A; + vb = (U64 *)inp1B; + ROUND_MUL(4, 4, r18, r19) + ROUND_MUL(3, 0, r13, r14) + ROUND_MUL(1, 2, r13, r14) + ROUND_MUL(0, 3, r13, r14) + ROUND_MUL(2, 1, r13, r14) + ROUND_MUL(2, 2, r14, r15) + ROUND_MUL(0, 4, r14, r15) + ROUND_MUL(1, 3, r14, r15) + ROUND_MUL(3, 1, r14, r15) + ROUND_MUL(4, 0, r14, r15) + ROUND_MUL(1, 4, r15, r16) + ROUND_MUL(2, 3, r15, r16) + ROUND_MUL(3, 2, r15, r16) + ROUND_MUL(4, 1, r15, r16) + ROUND_MUL(2, 4, r16, r17) + ROUND_MUL(3, 3, r16, r17) + ROUND_MUL(4, 2, r16, r17) + ROUND_MUL(0, 0, r10, r11) + ROUND_MUL(0, 1, r11, r12) + ROUND_MUL(0, 2, r12, r13) + ROUND_MUL(1, 0, r11, r12) + ROUND_MUL(1, 1, r12, r13) + ROUND_MUL(2, 0, r12, r13) + ROUND_MUL(3, 4, r17, r18) + ROUND_MUL(4, 3, r17, r18) + + // Reduction for input 0 + MUL_ADD_P256(u0, r00, r01, r02, r03, r04, r05) + MUL_ADD_P256(u1, r01, r02, r03, r04, r05, r06) + MUL_ADD_P256(u2, r02, r03, r04, r05, r06, r07) + MUL_ADD_P256(u3, r03, r04, r05, r06, r07, r08) + MUL_ADD_P256(u4, r04, r05, r06, r07, r08, r09) + + // Reduction for input 1 + MUL_ADD_P256(u0, r10, r11, r12, r13, r14, r15) + MUL_ADD_P256(u1, r11, r12, r13, r14, r15, r16) + MUL_ADD_P256(u2, r12, r13, r14, r15, r16, r17) + MUL_ADD_P256(u3, r13, r14, r15, r16, r17, r18) + MUL_ADD_P256(u4, r14, r15, r16, r17, r18, r19) + + // normalization res0 + NORM_LSHIFTR(r0, 5, 6) + NORM_LSHIFTR(r0, 6, 7) + NORM_LSHIFTR(r0, 7, 8) + NORM_LSHIFTR(r0, 8, 9) + + r0[0] = r05; + r0[1] = r06; + r0[2] = r07; + r0[3] = r08; + r0[4] = r09; + + // normalization res1 + NORM_LSHIFTR(r1, 5, 6) + NORM_LSHIFTR(r1, 6, 7) + NORM_LSHIFTR(r1, 7, 8) + NORM_LSHIFTR(r1, 8, 9) + + r1[0] = r15; + r1[1] = r16; + r1[2] = r17; + r1[3] = r18; + r1[4] = r19; +} +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define LEN52 NUMBER_OF_DIGITS(256,DIGIT_SIZE) + +void MB_FUNC_NAME(ifma_reduce52_p256_)(U64 R[], const U64 A[]) +{ + /* r = a - p256_mb */ + U64 r0 = sub64(A[0], ((U64*)(p256_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(p256_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(p256_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(p256_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(p256_mb))[4]); + + /* normalize r0 - r4 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + + /* r = a> 1 */ + mask = sub64(get_zero64(), and64(t1, one)); + t0 = add64(t0, and64(base, mask)); + t0 = srli64(t0, 1); + + mask = sub64(get_zero64(), and64(t2, one)); + t1 = add64(t1, and64(base, mask)); + t1 = srli64(t1, 1); + + mask = sub64(get_zero64(), and64(t3, one)); + t2 = add64(t2, and64(base, mask)); + t2 = srli64(t2, 1); + + mask = sub64(get_zero64(), and64(t4, one)); + t3 = add64(t3, and64(base, mask)); + t3 = srli64(t3, 1); + + t4 = srli64(t4, 1); + + /* normalize t0, t1, t2, t3, t4 */ + NORM_LSHIFTR(t, 0,1) + NORM_LSHIFTR(t, 1,2) + NORM_LSHIFTR(t, 2,3) + NORM_LSHIFTR(t, 3,4) + + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; +} + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_p256_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FE256_)(a,(const U64 (*))p256_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_p256_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FE256_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_p256_)(A); + + return mask; +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p384.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p384.c new file mode 100644 index 000000000..95d8a389a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p384.c @@ -0,0 +1,638 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Constants */ + +/* +// p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1 +// in 2^52 radix +*/ +__ALIGN64 static const int64u p384_mb[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x00000000ffffffff) }, + { REP8_DECL(0x000ff00000000000) }, + { REP8_DECL(0x000ffffffeffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x00000000000fffff) } +}; + +/* 2*p384 */ +__ALIGN64 static const int64u p384_x2[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x00000001fffffffe) }, + { REP8_DECL(0x000fe00000000000) }, + { REP8_DECL(0x000ffffffdffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x00000000001fffff) } +}; + +/* +// Note that +// k0 = -(1/p384 mod 2^DIGIT_SIZE) equals 1 +// The implementation takes this fact into account +*/ + +/* to Montgomery conversion constant +// rr = 2^((P384_LEN52*DIGIT_SIZE)*2) mod p384 +*/ +__ALIGN64 static const int64u p384_rr_mb[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x000fe00000001000) }, + { REP8_DECL(0x0000000000ffffff) }, + { REP8_DECL(0x0000000000000020) }, + { REP8_DECL(0x0000fffffffe0000) }, + { REP8_DECL(0x0000000020000000) }, + { REP8_DECL(0x0000000000000100) }, + { REP8_DECL(0x0000000000000000) } +}; + + +/*===================================================================== + + Specialized operations over p384: sqr & mul + +=====================================================================*/ + +#define ROUND_MUL(I, J, R_LO, R_HI) \ + R_LO = fma52lo(R_LO, va[I], vb[J]); \ + R_HI = fma52hi(R_HI, va[I], vb[J]); + +#define P384_REDUCTION_ROUND(u, r0, r1, r2, r3, r4, r5, r6, r7, r8, modulus) \ +{ \ + U64 t = sub64(get_zero64(), u); \ + U64 lo = and64(t, loadu64(VMASK52)); \ + U64 hi = add64(u, srai64(t,63)); \ + \ + r0 = fma52lo(r0, u, modulus[0]); \ + r1 = fma52lo(r1, u, modulus[1]); \ + r2 = fma52lo(r2, u, modulus[2]); \ + r3 = add64(r3, lo); /*r3 = fma52lo(r3, u, modulus[3]); */ \ + r4 = add64(r4, lo); /*r4 = fma52lo(r4, u, modulus[4]); */ \ + r5 = add64(r5, lo); /*r5 = fma52lo(r5, u, modulus[5]); */ \ + r6 = add64(r6, lo); /*r6 = fma52lo(r6, u, modulus[6]); */ \ + r7 = fma52lo(r7, u, modulus[7]); \ + \ + r1 = add64(r1, srli64(r0, DIGIT_SIZE)); /* carry propagation */ \ + \ + r1 = fma52hi(r1, u, modulus[0]); \ + r2 = fma52hi(r2, u, modulus[1]); \ + r3 = fma52hi(r3, u, modulus[2]); \ + r8 = fma52hi(r8, u, modulus[7]); \ + u = and64(add64(r1, slli64(r1, 32)), loadu64(VMASK52)); /* update u = r1*k, k = (2^32 +1) */ \ + r4 = add64(r4, hi); /*r4 = fma52hi(r4, u, modulus[3]); */ \ + r5 = add64(r5, hi); /*r5 = fma52hi(r5, u, modulus[4]); */ \ + r6 = add64(r6, hi); /*r6 = fma52hi(r6, u, modulus[5]); */ \ + r7 = add64(r7, hi); /*r7 = fma52hi(r7, u, modulus[6]); */ \ +} + +void MB_FUNC_NAME(ifma_amm52_p384_)(U64 r[], const U64 va[], const U64 vb[]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7; + int itr; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = get_zero64(); + + for(itr=0; itr < P384_LEN52; itr++) { + U64 Yi, T, LO, HI; + U64 Bi = loadu64(vb); + vb++; + + fma52lo_mem(r0, r0, Bi, va, SIMD_BYTES * 0); + Yi = and64(add64(r0, slli64(r0, 32)), loadu64(VMASK52)); /* k = (2^32 +1) */ + T = sub64(get_zero64(), Yi); + LO = and64(T, loadu64(VMASK52)); + HI = add64(Yi, srai64(T,63)); + fma52lo_mem(r1, r1, Bi, va, SIMD_BYTES * 1); + fma52lo_mem(r2, r2, Bi, va, SIMD_BYTES * 2); + fma52lo_mem(r3, r3, Bi, va, SIMD_BYTES * 3); + fma52lo_mem(r4, r4, Bi, va, SIMD_BYTES * 4); + fma52lo_mem(r5, r5, Bi, va, SIMD_BYTES * 5); + fma52lo_mem(r6, r6, Bi, va, SIMD_BYTES * 6); + fma52lo_mem(r7, r7, Bi, va, SIMD_BYTES * 7); + + fma52lo_mem(r0, r0, Yi, p384_mb, SIMD_BYTES * 0); + fma52lo_mem(r1, r1, Yi, p384_mb, SIMD_BYTES * 1); + r1 = add64(r1, srli64(r0, DIGIT_SIZE)); /* carry propagation */ + fma52lo_mem(r2, r2, Yi, p384_mb, SIMD_BYTES * 2); + r3 = add64(r3, LO); /* fma52lo_mem(r3, r3, Yi, p384_mb, SIMD_BYTES * 3); */ + r4 = add64(r4, LO); /* fma52lo_mem(r4, r4, Yi, p384_mb, SIMD_BYTES * 4); */ + r5 = add64(r5, LO); /* fma52lo_mem(r5, r5, Yi, p384_mb, SIMD_BYTES * 5); */ + r6 = add64(r6, LO); /* fma52lo_mem(r6, r6, Yi, p384_mb, SIMD_BYTES * 6); */ + fma52lo_mem(r7, r7, Yi, p384_mb, SIMD_BYTES * 7); + + fma52hi_mem(r0, r1, Bi, va, SIMD_BYTES * 0); + fma52hi_mem(r1, r2, Bi, va, SIMD_BYTES * 1); + fma52hi_mem(r2, r3, Bi, va, SIMD_BYTES * 2); + fma52hi_mem(r3, r4, Bi, va, SIMD_BYTES * 3); + fma52hi_mem(r4, r5, Bi, va, SIMD_BYTES * 4); + fma52hi_mem(r5, r6, Bi, va, SIMD_BYTES * 5); + fma52hi_mem(r6, r7, Bi, va, SIMD_BYTES * 6); + fma52hi_mem(r7, get_zero64(), Bi, va, SIMD_BYTES * 7); + + fma52hi_mem(r0, r0, Yi, p384_mb, SIMD_BYTES * 0); + fma52hi_mem(r1, r1, Yi, p384_mb, SIMD_BYTES * 1); + fma52hi_mem(r2, r2, Yi, p384_mb, SIMD_BYTES * 2); + r3 = add64(r3, HI); /* fma52hi_mem(r3, r3, Yi, p384_mb, SIMD_BYTES * 3); */ + r4 = add64(r4, HI); /* fma52hi_mem(r4, r4, Yi, p384_mb, SIMD_BYTES * 4); */ + r5 = add64(r5, HI); /* fma52hi_mem(r5, r5, Yi, p384_mb, SIMD_BYTES * 5); */ + r6 = add64(r6, HI); /* fma52hi_mem(r6, r6, Yi, p384_mb, SIMD_BYTES * 6); */ + fma52hi_mem(r7, r7, Yi, p384_mb, SIMD_BYTES * 7); + } + + // normalization + NORM_LSHIFTR(r, 0, 1) + NORM_LSHIFTR(r, 1, 2) + NORM_LSHIFTR(r, 2, 3) + NORM_LSHIFTR(r, 3, 4) + NORM_LSHIFTR(r, 4, 5) + NORM_LSHIFTR(r, 5, 6) + NORM_LSHIFTR(r, 6, 7) + + r[0] = r0; + r[1] = r1; + r[2] = r2; + r[3] = r3; + r[4] = r4; + r[5] = r5; + r[6] = r6; + r[7] = r7; +} + +void MB_FUNC_NAME(ifma_ams52_p384_)(U64 r[], const U64 va[]) +{ + const U64* vb = va; + U64* modulus = (U64*)p384_mb; + + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = + r10 = r11 = r12 = r13 = r14 = r15 = get_zero64(); + + // full square + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(0, 5, r5, r6) + ROUND_MUL(0, 6, r6, r7) + ROUND_MUL(0, 7, r7, r8) + + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(1, 5, r6, r7) + ROUND_MUL(1, 6, r7, r8) + ROUND_MUL(1, 7, r8, r9) + + ROUND_MUL(2, 3, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(2, 5, r7, r8) + ROUND_MUL(2, 6, r8, r9) + ROUND_MUL(2, 7, r9, r10) + + ROUND_MUL(3, 4, r7, r8) + ROUND_MUL(3, 5, r8, r9) + ROUND_MUL(3, 6, r9, r10) + ROUND_MUL(3, 7, r10,r11) + + ROUND_MUL(4, 5, r9, r10) + ROUND_MUL(4, 6, r10,r11) + ROUND_MUL(4, 7, r11,r12) + + ROUND_MUL(5, 6, r11,r12) + ROUND_MUL(5, 7, r12,r13) + + ROUND_MUL(6, 7, r13,r14) + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + r9 = add64(r9, r9); + r10 = add64(r10, r10); + r11 = add64(r11, r11); + r12 = add64(r12, r12); + r13 = add64(r13, r13); + r14 = add64(r14, r14); + + U64 u; + ROUND_MUL(0, 0, r0, r1) + u = and64(add64(r0, slli64(r0, 32)), loadu64(VMASK52)); + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 4, r8, r9) + ROUND_MUL(5, 5, r10, r11) + ROUND_MUL(6, 6, r12, r13) + ROUND_MUL(7, 7, r14, r15) + + // reduction + P384_REDUCTION_ROUND(u, r0, r1, r2, r3, r4, r5, r6, r7, r8, modulus); + P384_REDUCTION_ROUND(u, r1, r2, r3, r4, r5, r6, r7, r8, r9, modulus); + P384_REDUCTION_ROUND(u, r2, r3, r4, r5, r6, r7, r8, r9, r10, modulus); + P384_REDUCTION_ROUND(u, r3, r4, r5, r6, r7, r8, r9, r10,r11, modulus); + P384_REDUCTION_ROUND(u, r4, r5, r6, r7, r8, r9, r10,r11,r12, modulus); + P384_REDUCTION_ROUND(u, r5, r6, r7, r8, r9, r10,r11,r12,r13, modulus); + P384_REDUCTION_ROUND(u, r6, r7, r8, r9, r10,r11,r12,r13,r14, modulus); + P384_REDUCTION_ROUND(u, r7, r8, r9, r10,r11,r12,r13,r14,r15, modulus); + + // normalization + NORM_LSHIFTR(r, 8, 9) + NORM_LSHIFTR(r, 9, 10) + NORM_LSHIFTR(r, 10, 11) + NORM_LSHIFTR(r, 11, 12) + NORM_LSHIFTR(r, 12, 13) + NORM_LSHIFTR(r, 13, 14) + NORM_LSHIFTR(r, 14, 15) + + r[0] = r8; + r[1] = r9; + r[2] = r10; + r[3] = r11; + r[4] = r12; + r[5] = r13; + r[6] = r14; + r[7] = r15; +} + +void MB_FUNC_NAME(ifma_reduce52_p384_)(U64 R[], const U64 A[]) +{ + /* r = a - p384_mb */ + U64 r0 = sub64(A[0], ((U64*)(p384_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(p384_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(p384_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(p384_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(p384_mb))[4]); + U64 r5 = sub64(A[5], ((U64*)(p384_mb))[5]); + U64 r6 = sub64(A[6], ((U64*)(p384_mb))[6]); + U64 r7 = sub64(A[7], ((U64*)(p384_mb))[7]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + + /* r = a r = z^(0xFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFE FFFFFFFF00000000 00000000FFFFFFFD) +// +// note: z in in Montgomery domain (as soon mul() and sqr() below are amm-functions +// r in Montgomery domain too +*/ +#define fe52_sqr MB_FUNC_NAME(ifma_ams52_p384_) +#define fe52_mul MB_FUNC_NAME(ifma_amm52_p384_) + +/* r = base^(2^n) */ +__INLINE void fe52_sqr_pwr(U64 r[], const U64 base[], int n) +{ + if(r!=base) + MB_FUNC_NAME(mov_FE384_)(r, base); + for(; n>0; n--) + fe52_sqr(r,r); +} + +void MB_FUNC_NAME(ifma_aminv52_p384_)(U64 r[], const U64 z[]) +{ + __ALIGN64 U64 u[P384_LEN52]; + __ALIGN64 U64 v[P384_LEN52]; + __ALIGN64 U64 zD[P384_LEN52]; + __ALIGN64 U64 zE[P384_LEN52]; + __ALIGN64 U64 zF[P384_LEN52]; + + fe52_sqr(u, z); /* u = z^2 */ + fe52_mul(v, u, z); /* v = z^2 * z = z^3 */ + fe52_sqr_pwr(zF, v, 2); /* zF= (z^3)^(2^2) = z^12 */ + + fe52_mul(zD, zF, z); /* zD = z^12 * z = z^xD */ + fe52_mul(zE, zF, u); /* zE = z^12 * z^2 = z^xE */ + fe52_mul(zF, zF, v); /* zF = z^12 * z^3 = z^xF */ + + fe52_sqr_pwr(u, zF, 4); /* u = (z^xF)^(2^4) = z^xF0 */ + fe52_mul(zD, u, zD); /* zD = z^xF0 * z^xD = z^xFD */ + fe52_mul(zE, u, zE); /* zE = z^xF0 * z^xE = z^xFE */ + fe52_mul(zF, u, zF); /* zF = z^xF0 * z^xF = z^xFF */ + + fe52_sqr_pwr(u, zF, 8); /* u = (z^xFF)^(2^8) = z^xFF00 */ + fe52_mul(zD, u, zD); /* zD = z^xFF00 * z^xFD = z^xFFFD */ + fe52_mul(zE, u, zE); /* zE = z^xFF00 * z^xFE = z^xFFFE */ + fe52_mul(zF, u, zF); /* zF = z^xFF00 * z^xFF = z^xFFFF */ + + fe52_sqr_pwr(u, zF, 16); /* u = (z^xFFFF)^(2^16) = z^xFFFF0000 */ + fe52_mul(zD, u, zD); /* zD = z^xFFFF0000 * z^xFFFD = z^xFFFFFFFD */ + fe52_mul(zE, u, zE); /* zE = z^xFFFF0000 * z^xFFFE = z^xFFFFFFFE */ + fe52_mul(zF, u, zF); /* zF = z^xFFFF0000 * z^xFFFF = z^xFFFFFFFF */ + + fe52_sqr_pwr(u, zF, 32); /* u = (z^xFFFFFFFF)^(2^32) = z^xFFFFFFFF00000000 */ + fe52_mul(zE, u, zE); /* zE = z^xFFFFFFFF00000000 * z^xFFFFFFFE = z^xFFFFFFFFFFFFFFFE */ + fe52_mul(zF, u, zF); /* zF = z^xFFFFFFFF00000000 * z^xFFFFFFFF = z^xFFFFFFFFFFFFFFFF */ + + /* v = z^xFFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, zF, 64); + fe52_mul(v, v, zF); + /* v = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zF); + /* v = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFE + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zE); + /* v = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.0000000000000000 * z^xFFFFFFFF00000000 + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFF00000000 */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, u); + /* r = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFF00000000.0000000000000000 * z^xFFFFFFFD + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFF00000000.00000000FFFFFFFD */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(r, v, zD); +} + +/*===================================================================== + + Specialized single operations over p384: add, sub, neg + +=====================================================================*/ +__INLINE __mb_mask MB_FUNC_NAME(lt_mbx_digit_)(const U64 a, const U64 b, const __mb_mask lt_mask) +{ + U64 d = mask_sub64(sub64(a, b), lt_mask, sub64(a, b), set1(1)); + return cmp64_mask(d, get_zero64(), _MM_CMPINT_LT); +} + +void MB_FUNC_NAME(ifma_add52_p384_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a + b */ + U64 r0 = add64(A[0], B[0]); + U64 r1 = add64(A[1], B[1]); + U64 r2 = add64(A[2], B[2]); + U64 r3 = add64(A[3], B[3]); + U64 r4 = add64(A[4], B[4]); + U64 r5 = add64(A[5], B[5]); + U64 r6 = add64(A[6], B[6]); + U64 r7 = add64(A[7], B[7]); + + /* lt = {r0 - r7} < 2*p */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)( r0, ((U64*)(p384_x2))[0], 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r1, ((U64*)(p384_x2))[1], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r2, ((U64*)(p384_x2))[2], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r3, ((U64*)(p384_x2))[3], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r4, ((U64*)(p384_x2))[4], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r5, ((U64*)(p384_x2))[5], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r6, ((U64*)(p384_x2))[6], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r7, ((U64*)(p384_x2))[7], lt); + + /* {r0 - r7} -= 2*p */ + r0 = mask_sub64(r0, ~lt, r0, ((U64*)(p384_x2))[0]); + r1 = mask_sub64(r1, ~lt, r1, ((U64*)(p384_x2))[1]); + r2 = mask_sub64(r2, ~lt, r2, ((U64*)(p384_x2))[2]); + r3 = mask_sub64(r3, ~lt, r3, ((U64*)(p384_x2))[3]); + r4 = mask_sub64(r4, ~lt, r4, ((U64*)(p384_x2))[4]); + r5 = mask_sub64(r5, ~lt, r5, ((U64*)(p384_x2))[5]); + r6 = mask_sub64(r6, ~lt, r6, ((U64*)(p384_x2))[6]); + r7 = mask_sub64(r7, ~lt, r7, ((U64*)(p384_x2))[7]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + NORM_ASHIFTR(r, 4,5) + NORM_ASHIFTR(r, 5,6) + NORM_ASHIFTR(r, 6,7) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; +} + +void MB_FUNC_NAME(ifma_sub52_p384_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + U64 r5 = sub64(A[5], B[5]); + U64 r6 = sub64(A[6], B[6]); + U64 r7 = sub64(A[7], B[7]); + + /* lt = {r0 - r7} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r5, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r6, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r7, get_zero64(), lt); + + r0 = mask_add64(r0, lt, r0, ((U64*)(p384_x2))[0]); + r1 = mask_add64(r1, lt, r1, ((U64*)(p384_x2))[1]); + r2 = mask_add64(r2, lt, r2, ((U64*)(p384_x2))[2]); + r3 = mask_add64(r3, lt, r3, ((U64*)(p384_x2))[3]); + r4 = mask_add64(r4, lt, r4, ((U64*)(p384_x2))[4]); + r5 = mask_add64(r5, lt, r5, ((U64*)(p384_x2))[5]); + r6 = mask_add64(r6, lt, r6, ((U64*)(p384_x2))[6]); + r7 = mask_add64(r7, lt, r7, ((U64*)(p384_x2))[7]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + NORM_ASHIFTR(r, 4,5) + NORM_ASHIFTR(r, 5,6) + NORM_ASHIFTR(r, 6,7) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; +} + +void MB_FUNC_NAME(ifma_neg52_p384_)(U64 R[], const U64 A[]) +{ + __mb_mask nz_mask = ~MB_FUNC_NAME(is_zero_FE384_)(A); + + /* {r0 - r7} = 2*p - A */ + U64 r0 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[0], A[0] ); + U64 r1 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[1], A[1] ); + U64 r2 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[2], A[2] ); + U64 r3 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[3], A[3] ); + U64 r4 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[4], A[4] ); + U64 r5 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[5], A[5] ); + U64 r6 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[6], A[6] ); + U64 r7 = mask_sub64( A[0], nz_mask, ((U64*)(p384_x2))[7], A[7] ); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + NORM_ASHIFTR(r, 4,5) + NORM_ASHIFTR(r, 5,6) + NORM_ASHIFTR(r, 6,7) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; +} + +void MB_FUNC_NAME(ifma_double52_p384_)(U64 R[], const U64 A[]) +{ + MB_FUNC_NAME(ifma_add52_p384_)(R, A, A); +} + +void MB_FUNC_NAME(ifma_tripple52_p384_)(U64 R[], const U64 A[]) +{ + U64 T[P384_LEN52]; + MB_FUNC_NAME(ifma_add52_p384_)(T, A, A); + MB_FUNC_NAME(ifma_add52_p384_)(R, T, A); +} + +void MB_FUNC_NAME(ifma_half52_p384_)(U64 R[], const U64 A[]) +{ + U64 one = set1(1); + U64 base = set1(DIGIT_BASE); + + /* res = a + is_odd(a)? p384 : 0 */ + U64 mask = sub64(get_zero64(), and64(A[0], one)); + U64 t0 = add64(A[0], and64(((U64*)p384_mb)[0], mask)); + U64 t1 = add64(A[1], and64(((U64*)p384_mb)[1], mask)); + U64 t2 = add64(A[2], and64(((U64*)p384_mb)[2], mask)); + U64 t3 = add64(A[3], and64(((U64*)p384_mb)[3], mask)); + U64 t4 = add64(A[4], and64(((U64*)p384_mb)[4], mask)); + U64 t5 = add64(A[5], and64(((U64*)p384_mb)[5], mask)); + U64 t6 = add64(A[6], and64(((U64*)p384_mb)[6], mask)); + U64 t7 = add64(A[7], and64(((U64*)p384_mb)[7], mask)); + + /* t =>> 1 */ + mask = sub64(get_zero64(), and64(t1, one)); + t0 = add64(t0, and64(base, mask)); + t0 = srli64(t0, 1); + + mask = sub64(get_zero64(), and64(t2, one)); + t1 = add64(t1, and64(base, mask)); + t1 = srli64(t1, 1); + + mask = sub64(get_zero64(), and64(t3, one)); + t2 = add64(t2, and64(base, mask)); + t2 = srli64(t2, 1); + + mask = sub64(get_zero64(), and64(t4, one)); + t3 = add64(t3, and64(base, mask)); + t3 = srli64(t3, 1); + + mask = sub64(get_zero64(), and64(t5, one)); + t4 = add64(t4, and64(base, mask)); + t4 = srli64(t4, 1); + + mask = sub64(get_zero64(), and64(t6, one)); + t5 = add64(t5, and64(base, mask)); + t5 = srli64(t5, 1); + + mask = sub64(get_zero64(), and64(t7, one)); + t6 = add64(t6, and64(base, mask)); + t6 = srli64(t6, 1); + + t7 = srli64(t7, 1); + + /* normalize t0, t1, t2, t3, t4 */ + NORM_LSHIFTR(t, 0,1) + NORM_LSHIFTR(t, 1,2) + NORM_LSHIFTR(t, 2,3) + NORM_LSHIFTR(t, 3,4) + NORM_LSHIFTR(t, 4,5) + NORM_LSHIFTR(t, 5,6) + NORM_LSHIFTR(t, 6,7) + + R[0] = t0; + R[1] = t1; + R[2] = t2; + R[3] = t3; + R[4] = t4; + R[5] = t5; + R[6] = t6; + R[7] = t7; +} + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_p384_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FE384_)(a,(const U64 (*))p384_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_p384_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FE384_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_p384_)(A); + + return mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p521.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p521.c new file mode 100644 index 000000000..48aca5351 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_arith_p521.c @@ -0,0 +1,870 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Constants */ + +/* +// p521 = 2^521 - 1 +// in 2^52 radix +*/ +__ALIGN64 static const int64u p521_mb[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0000000000000001) } +}; + +/* 2*p521 */ +__ALIGN64 static const int64u p521_x2[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000ffffffffffffe) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0000000000000003) } +}; + +/* +// Note that +// k0 = -(1/p521 mod 2^DIGIT_SIZE) equals 1 +// The implementation takes this fact into account +*/ + +/* to Montgomery conversion constant +// rr = 2^((P521_LEN52*DIGIT_SIZE)*2) mod p521 +*/ +__ALIGN64 static const int64u p521_rr_mb[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0004000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) } +}; + + +/*===================================================================== + + Specialized operations over p521: sqr & mul + +=====================================================================*/ + +#define ROUND_MUL(I, J, LO, HI) \ + LO = fma52lo(LO, va[I], vb[J]); \ + HI = fma52hi(HI, va[I], vb[J]) + +#define RED_P521_STEP(u, r0,r1, r10) { \ + U64 u = and64(r0, loadu64(VMASK52)); /* u = r0*k, k == 1 */ \ + r1 = add64(r1, srli64(r0, DIGIT_SIZE)); /* carry propagation */ \ + /* reduction */ \ + u = add64(u, u); \ + r10 = add64(r10, u); \ +} + +void MB_FUNC_NAME(ifma_amm52_p521_)(U64 r[], const U64 va[], const U64 vb[]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + U64 r20, r21; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = + r10 = r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19= + r20 = r21 = get_zero64(); + + // full multiplication + ROUND_MUL(0, 0, r0, r1); + ROUND_MUL(1, 0, r1, r2); + ROUND_MUL(2, 0, r2, r3); + ROUND_MUL(3, 0, r3, r4); + ROUND_MUL(4, 0, r4, r5); + ROUND_MUL(5, 0, r5, r6); + ROUND_MUL(6, 0, r6, r7); + ROUND_MUL(7, 0, r7, r8); + ROUND_MUL(8, 0, r8, r9); + ROUND_MUL(9, 0, r9, r10); + ROUND_MUL(10,0, r10,r11); + + ROUND_MUL(0, 1, r1, r2); + ROUND_MUL(1, 1, r2, r3); + ROUND_MUL(2, 1, r3, r4); + ROUND_MUL(3, 1, r4, r5); + ROUND_MUL(4, 1, r5, r6); + ROUND_MUL(5, 1, r6, r7); + ROUND_MUL(6, 1, r7, r8); + ROUND_MUL(7, 1, r8, r9); + ROUND_MUL(8, 1, r9, r10); + ROUND_MUL(9, 1, r10,r11); + ROUND_MUL(10,1, r11,r12); + + ROUND_MUL(0, 2, r2, r3); + ROUND_MUL(1, 2, r3, r4); + ROUND_MUL(2, 2, r4, r5); + ROUND_MUL(3, 2, r5, r6); + ROUND_MUL(4, 2, r6, r7); + ROUND_MUL(5, 2, r7, r8); + ROUND_MUL(6, 2, r8, r9); + ROUND_MUL(7, 2, r9, r10); + ROUND_MUL(8, 2, r10,r11); + ROUND_MUL(9, 2, r11,r12); + ROUND_MUL(10,2, r12,r13); + + ROUND_MUL(0, 3, r3, r4); + ROUND_MUL(1, 3, r4, r5); + ROUND_MUL(2, 3, r5, r6); + ROUND_MUL(3, 3, r6, r7); + ROUND_MUL(4, 3, r7, r8); + ROUND_MUL(5, 3, r8, r9); + ROUND_MUL(6, 3, r9, r10); + ROUND_MUL(7, 3, r10,r11); + ROUND_MUL(8, 3, r11,r12); + ROUND_MUL(9, 3, r12,r13); + ROUND_MUL(10,3, r13,r14); + + ROUND_MUL(0, 4, r4, r5); + ROUND_MUL(1, 4, r5, r6); + ROUND_MUL(2, 4, r6, r7); + ROUND_MUL(3, 4, r7, r8); + ROUND_MUL(4, 4, r8, r9); + ROUND_MUL(5, 4, r9, r10); + ROUND_MUL(6, 4, r10,r11); + ROUND_MUL(7, 4, r11,r12); + ROUND_MUL(8, 4, r12,r13); + ROUND_MUL(9, 4, r13,r14); + ROUND_MUL(10,4, r14,r15); + + ROUND_MUL(0, 5, r5, r6); + ROUND_MUL(1, 5, r6, r7); + ROUND_MUL(2, 5, r7, r8); + ROUND_MUL(3, 5, r8, r9); + ROUND_MUL(4, 5, r9, r10); + ROUND_MUL(5, 5, r10,r11); + ROUND_MUL(6, 5, r11,r12); + ROUND_MUL(7, 5, r12,r13); + ROUND_MUL(8, 5, r13,r14); + ROUND_MUL(9, 5, r14,r15); + ROUND_MUL(10,5, r15,r16); + + ROUND_MUL(0, 6, r6, r7); + ROUND_MUL(1, 6, r7, r8); + ROUND_MUL(2, 6, r8, r9); + ROUND_MUL(3, 6, r9, r10); + ROUND_MUL(4, 6, r10,r11); + ROUND_MUL(5, 6, r11,r12); + ROUND_MUL(6, 6, r12,r13); + ROUND_MUL(7, 6, r13,r14); + ROUND_MUL(8, 6, r14,r15); + ROUND_MUL(9, 6, r15,r16); + ROUND_MUL(10,6, r16,r17); + + ROUND_MUL(0, 7, r7, r8); + ROUND_MUL(1, 7, r8, r9); + ROUND_MUL(2, 7, r9, r10); + ROUND_MUL(3, 7, r10,r11); + ROUND_MUL(4, 7, r11,r12); + ROUND_MUL(5, 7, r12,r13); + ROUND_MUL(6, 7, r13,r14); + ROUND_MUL(7, 7, r14,r15); + ROUND_MUL(8, 7, r15,r16); + ROUND_MUL(9, 7, r16,r17); + ROUND_MUL(10,7, r17,r18); + + ROUND_MUL(0, 8, r8, r9); + ROUND_MUL(1, 8, r9, r10); + ROUND_MUL(2, 8, r10,r11); + ROUND_MUL(3, 8, r11,r12); + ROUND_MUL(4, 8, r12,r13); + ROUND_MUL(5, 8, r13,r14); + ROUND_MUL(6, 8, r14,r15); + ROUND_MUL(7, 8, r15,r16); + ROUND_MUL(8, 8, r16,r17); + ROUND_MUL(9, 8, r17,r18); + ROUND_MUL(10,8, r18,r19); + + ROUND_MUL(0, 9, r9, r10); + ROUND_MUL(1, 9, r10,r11); + ROUND_MUL(2, 9, r11,r12); + ROUND_MUL(3, 9, r12,r13); + ROUND_MUL(4, 9, r13,r14); + ROUND_MUL(5, 9, r14,r15); + ROUND_MUL(6, 9, r15,r16); + ROUND_MUL(7, 9, r16,r17); + ROUND_MUL(8, 9, r17,r18); + ROUND_MUL(9, 9, r18,r19); + ROUND_MUL(10,9, r19,r20); + + ROUND_MUL(0, 10, r10,r11); + ROUND_MUL(1, 10, r11,r12); + ROUND_MUL(2, 10, r12,r13); + ROUND_MUL(3, 10, r13,r14); + ROUND_MUL(4, 10, r14,r15); + ROUND_MUL(5, 10, r15,r16); + ROUND_MUL(6, 10, r16,r17); + ROUND_MUL(7, 10, r17,r18); + ROUND_MUL(8, 10, r18,r19); + ROUND_MUL(9, 10, r19,r20); + ROUND_MUL(10,10, r20,r21); + + // reduction p = 2^521 -1 + RED_P521_STEP(u0, r0, r1, r10); + RED_P521_STEP(u1, r1, r2, r11); + RED_P521_STEP(u2, r2, r3, r12); + RED_P521_STEP(u3, r3, r4, r13); + RED_P521_STEP(u4, r4, r5, r14); + RED_P521_STEP(u5, r5, r6, r15); + RED_P521_STEP(u6, r6, r7, r16); + RED_P521_STEP(u7, r7, r8, r17); + RED_P521_STEP(u8, r8, r9, r18); + RED_P521_STEP(u9, r9, r10,r19); + RED_P521_STEP(u10,r10,r11,r20); + + // normalization + NORM_LSHIFTR(r, 11, 12) + NORM_LSHIFTR(r, 12, 13) + NORM_LSHIFTR(r, 13, 14) + NORM_LSHIFTR(r, 14, 15) + NORM_LSHIFTR(r, 15, 16) + NORM_LSHIFTR(r, 16, 17) + NORM_LSHIFTR(r, 17, 18) + NORM_LSHIFTR(r, 18, 19) + NORM_LSHIFTR(r, 19, 20) + NORM_LSHIFTR(r, 20, 21) + + r[0] = r11; + r[1] = r12; + r[2] = r13; + r[3] = r14; + r[4] = r15; + r[5] = r16; + r[6] = r17; + r[7] = r18; + r[8] = r19; + r[9] = r20; + r[10]= r21; +} + +void MB_FUNC_NAME(ifma_ams52_p521_)(U64 r[], const U64 va[]) +{ + const U64* vb = va; + + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + U64 r20, r21; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = r10 = + r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19 = r20 = r21 = get_zero64(); + + // full square + ROUND_MUL(0, 1, r1, r2); + ROUND_MUL(0, 2, r2, r3); + ROUND_MUL(0, 3, r3, r4); + ROUND_MUL(0, 4, r4, r5); + ROUND_MUL(0, 5, r5, r6); + ROUND_MUL(0, 6, r6, r7); + ROUND_MUL(0, 7, r7, r8); + ROUND_MUL(0, 8, r8, r9); + ROUND_MUL(0, 9, r9, r10); + ROUND_MUL(0, 10,r10,r11); + + ROUND_MUL(1, 2, r3, r4); + ROUND_MUL(1, 3, r4, r5); + ROUND_MUL(1, 4, r5, r6); + ROUND_MUL(1, 5, r6, r7); + ROUND_MUL(1, 6, r7, r8); + ROUND_MUL(1, 7, r8, r9); + ROUND_MUL(1, 8, r9, r10); + ROUND_MUL(1, 9, r10,r11); + ROUND_MUL(1, 10,r11,r12); + + ROUND_MUL(2, 3, r5, r6); + ROUND_MUL(2, 4, r6, r7); + ROUND_MUL(2, 5, r7, r8); + ROUND_MUL(2, 6, r8, r9); + ROUND_MUL(2, 7, r9, r10); + ROUND_MUL(2, 8, r10,r11); + ROUND_MUL(2, 9, r11,r12); + ROUND_MUL(2, 10,r12,r13); + + ROUND_MUL(3, 4, r7, r8); + ROUND_MUL(3, 5, r8, r9); + ROUND_MUL(3, 6, r9, r10); + ROUND_MUL(3, 7, r10,r11); + ROUND_MUL(3, 8, r11,r12); + ROUND_MUL(3, 9, r12,r13); + ROUND_MUL(3, 10,r13,r14); + + ROUND_MUL(4, 5, r9, r10); + ROUND_MUL(4, 6, r10,r11); + ROUND_MUL(4, 7, r11,r12); + ROUND_MUL(4, 8, r12,r13); + ROUND_MUL(4, 9, r13,r14); + ROUND_MUL(4, 10,r14,r15); + + ROUND_MUL(5, 6, r11,r12); + ROUND_MUL(5, 7, r12,r13); + ROUND_MUL(5, 8, r13,r14); + ROUND_MUL(5, 9, r14,r15); + ROUND_MUL(5, 10,r15,r16); + + ROUND_MUL(6, 7, r13,r14); + ROUND_MUL(6, 8, r14,r15); + ROUND_MUL(6, 9, r15,r16); + ROUND_MUL(6, 10,r16,r17); + + ROUND_MUL(7, 8, r15,r16); + ROUND_MUL(7, 9, r16,r17); + ROUND_MUL(7, 10,r17,r18); + + ROUND_MUL(8, 9, r17,r18); + ROUND_MUL(8, 10,r18,r19); + + ROUND_MUL(9, 10,r19,r20); + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + r9 = add64(r9, r9); + r10 = add64(r10, r10); + r11 = add64(r11, r11); + r12 = add64(r12, r12); + r13 = add64(r13, r13); + r14 = add64(r14, r14); + r15 = add64(r15, r15); + r16 = add64(r16, r16); + r17 = add64(r17, r17); + r18 = add64(r18, r18); + r19 = add64(r19, r19); + r20 = add64(r20, r20); + + ROUND_MUL(0, 0, r0, r1); + ROUND_MUL(1, 1, r2, r3); + ROUND_MUL(2, 2, r4, r5); + ROUND_MUL(3, 3, r6, r7); + ROUND_MUL(4, 4, r8, r9); + ROUND_MUL(5, 5, r10, r11); + ROUND_MUL(6, 6, r12, r13); + ROUND_MUL(7, 7, r14, r15); + ROUND_MUL(8, 8, r16, r17); + ROUND_MUL(9, 9, r18, r19); + ROUND_MUL(10,10,r20, r21); + + // reduction p = 2^521 -1 + RED_P521_STEP(u0, r0, r1, r10); + RED_P521_STEP(u1, r1, r2, r11); + RED_P521_STEP(u2, r2, r3, r12); + RED_P521_STEP(u3, r3, r4, r13); + RED_P521_STEP(u4, r4, r5, r14); + RED_P521_STEP(u5, r5, r6, r15); + RED_P521_STEP(u6, r6, r7, r16); + RED_P521_STEP(u7, r7, r8, r17); + RED_P521_STEP(u8, r8, r9, r18); + RED_P521_STEP(u9, r9, r10,r19); + RED_P521_STEP(u10,r10,r11,r20); + + // normalization + NORM_LSHIFTR(r, 11, 12) + NORM_LSHIFTR(r, 12, 13) + NORM_LSHIFTR(r, 13, 14) + NORM_LSHIFTR(r, 14, 15) + NORM_LSHIFTR(r, 15, 16) + NORM_LSHIFTR(r, 16, 17) + NORM_LSHIFTR(r, 17, 18) + NORM_LSHIFTR(r, 18, 19) + NORM_LSHIFTR(r, 19, 20) + NORM_LSHIFTR(r, 20, 21) + + r[0] = r11; + r[1] = r12; + r[2] = r13; + r[3] = r14; + r[4] = r15; + r[5] = r16; + r[6] = r17; + r[7] = r18; + r[8] = r19; + r[9] = r20; + r[10]= r21; +} + +void MB_FUNC_NAME(ifma_reduce52_p521_)(U64 R[], const U64 A[]) +{ + /* r = a - p521_mb */ + U64 r0 = sub64(A[0], ((U64*)(p521_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(p521_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(p521_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(p521_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(p521_mb))[4]); + U64 r5 = sub64(A[5], ((U64*)(p521_mb))[5]); + U64 r6 = sub64(A[6], ((U64*)(p521_mb))[6]); + U64 r7 = sub64(A[7], ((U64*)(p521_mb))[7]); + U64 r8 = sub64(A[8], ((U64*)(p521_mb))[8]); + U64 r9 = sub64(A[9], ((U64*)(p521_mb))[9]); + U64 r10= sub64(A[10],((U64*)(p521_mb))[10]); + + /* normalize r0 - r10 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9, 10) + + /* r = a r = z^(0x1FF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFD) +// +// note: z in in Montgomery domain (as soon mul() and sqr() below are amm-functions +// r in Montgomery domain too +*/ +#define fe52_sqr MB_FUNC_NAME(ifma_ams52_p521_) +#define fe52_mul MB_FUNC_NAME(ifma_amm52_p521_) + +/* r = base^(2^n) */ +__INLINE void fe52_sqr_pwr(U64 r[], const U64 base[], int n) +{ + if(r!=base) + MB_FUNC_NAME(mov_FE521_)(r, base); + for(; n>0; n--) + fe52_sqr(r,r); +} + +void MB_FUNC_NAME(ifma_aminv52_p521_)(U64 r[], const U64 z[]) +{ + __ALIGN64 U64 u[P521_LEN52]; + __ALIGN64 U64 v[P521_LEN52]; + __ALIGN64 U64 zD[P521_LEN52]; + __ALIGN64 U64 zF[P521_LEN52]; + __ALIGN64 U64 z1FF[P521_LEN52]; + + fe52_sqr(u, z); /* u = z^2 */ + fe52_mul(v, u, z); /* v = z^2 * z = z^3 */ + fe52_sqr_pwr(zF, v, 2); /* zF= (z^3)^(2^2) = z^12 */ + + fe52_mul(zD, zF, z); /* zD = z^12 * z = z^xD */ + fe52_mul(zF, zF, v); /* zF = z^12 * z^3 = z^xF */ + + fe52_sqr_pwr(u, zF, 4); /* u = (z^xF)^(2^4) = z^xF0 */ + fe52_mul(zD, u, zD); /* zD = z^xF0 * z^xD = z^xFD */ + fe52_mul(zF, u, zF); /* zF = z^xF0 * z^xF = z^xFF */ + + fe52_sqr(z1FF, zF); /* z1FF= (zF^2) = z^x1FE */ + fe52_mul(z1FF, z1FF, z); /* z1FF *= z = z^x1FF */ + + fe52_sqr_pwr(u, zF, 8); /* u = (z^xFF)^(2^8) = z^xFF00 */ + fe52_mul(zD, u, zD); /* zD = z^xFF00 * z^xFD = z^xFFFD */ + fe52_mul(zF, u, zF); /* zF = z^xFF00 * z^xFF = z^xFFFF */ + + fe52_sqr_pwr(u, zF, 16); /* u = (z^xFFFF)^(2^16) = z^xFFFF0000 */ + fe52_mul(zD, u, zD); /* zD = z^xFFFF0000 * z^xFFFD = z^xFFFFFFFD */ + fe52_mul(zF, u, zF); /* zF = z^xFFFF0000 * z^xFFFF = z^xFFFFFFFF */ + + fe52_sqr_pwr(u, zF, 32); /* u = (z^xFFFFFFFF)^(2^32) = z^xFFFFFFFF00000000 */ + fe52_mul(zD, u, zD); /* zD = z^xFFFFFFFF00000000 * z^xFFFFFFFD = z^xFFFFFFFFFFFFFFFD */ + fe52_mul(zF, u, zF); /* zF = z^xFFFFFFFF00000000 * z^xFFFFFFFF = z^xFFFFFFFFFFFFFFFF */ + + /* v = z^x1FF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, z1FF, 64); + fe52_mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFD + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFD */ + fe52_sqr_pwr(v, v, 64); + fe52_mul(r, v, zD); +} + +/*===================================================================== + + Specialized single operations over p521: add, sub, neg + +=====================================================================*/ +__INLINE __mb_mask MB_FUNC_NAME(lt_mbx_digit_)(const U64 a, const U64 b, const __mb_mask lt_mask) +{ + U64 d = mask_sub64(sub64(a, b), lt_mask, sub64(a, b), set1(1)); + return cmp64_mask(d, get_zero64(), _MM_CMPINT_LT); +} + +void MB_FUNC_NAME(ifma_add52_p521_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a + b */ + U64 r0 = add64(A[0], B[0]); + U64 r1 = add64(A[1], B[1]); + U64 r2 = add64(A[2], B[2]); + U64 r3 = add64(A[3], B[3]); + U64 r4 = add64(A[4], B[4]); + U64 r5 = add64(A[5], B[5]); + U64 r6 = add64(A[6], B[6]); + U64 r7 = add64(A[7], B[7]); + U64 r8 = add64(A[8], B[8]); + U64 r9 = add64(A[9], B[9]); + U64 r10= add64(A[10],B[10]); + + /* lt = {r0 - r10} < 2*p */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)( r0, ((U64*)(p521_x2))[0], 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r1, ((U64*)(p521_x2))[1], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r2, ((U64*)(p521_x2))[2], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r3, ((U64*)(p521_x2))[3], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r4, ((U64*)(p521_x2))[4], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r5, ((U64*)(p521_x2))[5], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r6, ((U64*)(p521_x2))[6], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r7, ((U64*)(p521_x2))[7], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r8, ((U64*)(p521_x2))[8], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r9, ((U64*)(p521_x2))[9], lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)( r10,((U64*)(p521_x2))[10],lt); + + /* {r0 - r10} -= 2*p */ + r0 = mask_sub64(r0, ~lt, r0, ((U64*)(p521_x2))[0]); + r1 = mask_sub64(r1, ~lt, r1, ((U64*)(p521_x2))[1]); + r2 = mask_sub64(r2, ~lt, r2, ((U64*)(p521_x2))[2]); + r3 = mask_sub64(r3, ~lt, r3, ((U64*)(p521_x2))[3]); + r4 = mask_sub64(r4, ~lt, r4, ((U64*)(p521_x2))[4]); + r5 = mask_sub64(r5, ~lt, r5, ((U64*)(p521_x2))[5]); + r6 = mask_sub64(r6, ~lt, r6, ((U64*)(p521_x2))[6]); + r7 = mask_sub64(r7, ~lt, r7, ((U64*)(p521_x2))[7]); + r8 = mask_sub64(r8, ~lt, r8, ((U64*)(p521_x2))[8]); + r9 = mask_sub64(r9, ~lt, r9, ((U64*)(p521_x2))[9]); + r10= mask_sub64(r10,~lt, r10,((U64*)(p521_x2))[10]); + + /* normalize r0 - r10 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9,10) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; + R[8] = r8; + R[9] = r9; + R[10]= r10; +} + +void MB_FUNC_NAME(ifma_sub52_p521_)(U64 R[], const U64 A[], const U64 B[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], B[0]); + U64 r1 = sub64(A[1], B[1]); + U64 r2 = sub64(A[2], B[2]); + U64 r3 = sub64(A[3], B[3]); + U64 r4 = sub64(A[4], B[4]); + U64 r5 = sub64(A[5], B[5]); + U64 r6 = sub64(A[6], B[6]); + U64 r7 = sub64(A[7], B[7]); + U64 r8 = sub64(A[8], B[8]); + U64 r9 = sub64(A[9], B[9]); + U64 r10= sub64(A[10],B[10]); + + /* lt = {r0 - r10} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r5, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r6, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r7, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r8, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r9, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r10,get_zero64(), lt); + + r0 = mask_add64(r0, lt, r0, ((U64*)(p521_x2))[0]); + r1 = mask_add64(r1, lt, r1, ((U64*)(p521_x2))[1]); + r2 = mask_add64(r2, lt, r2, ((U64*)(p521_x2))[2]); + r3 = mask_add64(r3, lt, r3, ((U64*)(p521_x2))[3]); + r4 = mask_add64(r4, lt, r4, ((U64*)(p521_x2))[4]); + r5 = mask_add64(r5, lt, r5, ((U64*)(p521_x2))[5]); + r6 = mask_add64(r6, lt, r6, ((U64*)(p521_x2))[6]); + r7 = mask_add64(r7, lt, r7, ((U64*)(p521_x2))[7]); + r8 = mask_add64(r8, lt, r8, ((U64*)(p521_x2))[8]); + r9 = mask_add64(r9, lt, r9, ((U64*)(p521_x2))[9]); + r10= mask_add64(r10,lt, r10,((U64*)(p521_x2))[10]); + + /* normalize r0 - r7 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9, 10) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; + R[8] = r8; + R[9] = r9; + R[10]= r10; +} + +void MB_FUNC_NAME(ifma_neg52_p521_)(U64 R[], const U64 A[]) +{ + __mb_mask nz_mask = ~MB_FUNC_NAME(is_zero_FE521_)(A); + + /* {r0 - r10} = 2*p - A */ + U64 r0 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[0], A[0] ); + U64 r1 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[1], A[1] ); + U64 r2 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[2], A[2] ); + U64 r3 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[3], A[3] ); + U64 r4 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[4], A[4] ); + U64 r5 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[5], A[5] ); + U64 r6 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[6], A[6] ); + U64 r7 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[7], A[7] ); + U64 r8 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[8], A[8] ); + U64 r9 = mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[9], A[9] ); + U64 r10= mask_sub64( A[0], nz_mask, ((U64*)(p521_x2))[10],A[10]); + + /* normalize r0 - r10 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + NORM_ASHIFTR(r, 4, 5) + NORM_ASHIFTR(r, 5, 6) + NORM_ASHIFTR(r, 6, 7) + NORM_ASHIFTR(r, 7, 8) + NORM_ASHIFTR(r, 8, 9) + NORM_ASHIFTR(r, 9, 10) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; + R[5] = r5; + R[6] = r6; + R[7] = r7; + R[8] = r8; + R[9] = r9; + R[10]= r10; +} + +void MB_FUNC_NAME(ifma_double52_p521_)(U64 R[], const U64 A[]) +{ + MB_FUNC_NAME(ifma_add52_p521_)(R, A, A); +} + +void MB_FUNC_NAME(ifma_tripple52_p521_)(U64 R[], const U64 A[]) +{ + U64 T[P521_LEN52]; + MB_FUNC_NAME(ifma_add52_p521_)(T, A, A); + MB_FUNC_NAME(ifma_add52_p521_)(R, T, A); +} + +void MB_FUNC_NAME(ifma_half52_p521_)(U64 R[], const U64 A[]) +{ + U64 one = set1(1); + U64 base = set1(DIGIT_BASE); + + /* res = a + is_odd(a)? p521 : 0 */ + U64 mask = sub64(get_zero64(), and64(A[0], one)); + U64 t0 = add64(A[0], and64(((U64*)p521_mb)[0], mask)); + U64 t1 = add64(A[1], and64(((U64*)p521_mb)[1], mask)); + U64 t2 = add64(A[2], and64(((U64*)p521_mb)[2], mask)); + U64 t3 = add64(A[3], and64(((U64*)p521_mb)[3], mask)); + U64 t4 = add64(A[4], and64(((U64*)p521_mb)[4], mask)); + U64 t5 = add64(A[5], and64(((U64*)p521_mb)[5], mask)); + U64 t6 = add64(A[6], and64(((U64*)p521_mb)[6], mask)); + U64 t7 = add64(A[7], and64(((U64*)p521_mb)[7], mask)); + U64 t8 = add64(A[8], and64(((U64*)p521_mb)[8], mask)); + U64 t9 = add64(A[9], and64(((U64*)p521_mb)[9], mask)); + U64 t10= add64(A[10],and64(((U64*)p521_mb)[10],mask)); + + /* t =>> 1 */ + mask = sub64(get_zero64(), and64(t1, one)); + t0 = add64(t0, and64(base, mask)); + t0 = srli64(t0, 1); + + mask = sub64(get_zero64(), and64(t2, one)); + t1 = add64(t1, and64(base, mask)); + t1 = srli64(t1, 1); + + mask = sub64(get_zero64(), and64(t3, one)); + t2 = add64(t2, and64(base, mask)); + t2 = srli64(t2, 1); + + mask = sub64(get_zero64(), and64(t4, one)); + t3 = add64(t3, and64(base, mask)); + t3 = srli64(t3, 1); + + mask = sub64(get_zero64(), and64(t5, one)); + t4 = add64(t4, and64(base, mask)); + t4 = srli64(t4, 1); + + mask = sub64(get_zero64(), and64(t6, one)); + t5 = add64(t5, and64(base, mask)); + t5 = srli64(t5, 1); + + mask = sub64(get_zero64(), and64(t7, one)); + t6 = add64(t6, and64(base, mask)); + t6 = srli64(t6, 1); + + mask = sub64(get_zero64(), and64(t8, one)); + t7 = add64(t7, and64(base, mask)); + t7 = srli64(t7, 1); + + mask = sub64(get_zero64(), and64(t9, one)); + t8 = add64(t8, and64(base, mask)); + t8 = srli64(t8, 1); + + mask = sub64(get_zero64(), and64(t10, one)); + t9 = add64(t9, and64(base, mask)); + t9 = srli64(t9, 1); + + t10 = srli64(t10, 1); + + /* normalize t0, t1, t2, t3, t4 */ + NORM_LSHIFTR(t, 0, 1) + NORM_LSHIFTR(t, 1, 2) + NORM_LSHIFTR(t, 2, 3) + NORM_LSHIFTR(t, 3, 4) + NORM_LSHIFTR(t, 4, 5) + NORM_LSHIFTR(t, 5, 6) + NORM_LSHIFTR(t, 6, 7) + NORM_LSHIFTR(t, 7, 8) + NORM_LSHIFTR(t, 8, 9) + NORM_LSHIFTR(t, 9,10) + + R[0] = t0; + R[1] = t1; + R[2] = t2; + R[3] = t3; + R[4] = t4; + R[5] = t5; + R[6] = t6; + R[7] = t7; + R[8] = t8; + R[9] = t9; + R[10]= t10; +} + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_p521_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FE521_)(a,(const U64 (*))p521_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_p521_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FE521_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_p521_)(A); + + return mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p256.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p256.c new file mode 100644 index 000000000..b83e082f9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p256.c @@ -0,0 +1,252 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key depends on is pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates +// or +// - in (x:y) affine coordinate +*/ +DLL_PUBLIC +mbx_status mbx_nistp256_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const BIGNUM* skey = pa_skey[buf_no]; + const BIGNUM* pubx = pa_pubx[buf_no]; + const BIGNUM* puby = pa_puby[buf_no]; + const BIGNUM* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey|| NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[P256_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])secretz, (const BIGNUM**)pa_skey, P256_BITSIZE); + secretz[P256_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, P256_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P256_POINT P; + /* set party's public */ + ifma_BN_to_mb8((int64u (*)[8])P.X, (const BIGNUM* (*))pa_pubx, P256_BITSIZE); /* P-> radix 2^52 */ + ifma_BN_to_mb8((int64u (*)[8])P.Y, (const BIGNUM* (*))pa_puby, P256_BITSIZE); + if(use_jproj_coords) + ifma_BN_to_mb8((int64u (*)[8])P.Z, (const BIGNUM* (*))pa_pubz, P256_BITSIZE); + else + MB_FUNC_NAME(mov_FE256_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p256_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_p256_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_p256_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_p256_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P256_POINT R; + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_nistp256_mul_point_)(&R, &P, secretz); + + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[P256_LEN52]; + ifma_aminv52_p256_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_p256_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_p256_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p256_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, P256_BITSIZE); + + /* clear computed shared keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_nistp256_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const int64u* skey = pa_skey[buf_no]; + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey || NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[P256_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])secretz, (const int64u**)pa_skey, P256_BITSIZE); + secretz[P256_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, P256_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P256_POINT P; + /* set party's public */ + ifma_BNU_to_mb8((int64u (*)[8])P.X, (const int64u* (*))pa_pubx, P256_BITSIZE); // P-> crypto_mb radix 2^52 + ifma_BNU_to_mb8((int64u (*)[8])P.Y, (const int64u* (*))pa_puby, P256_BITSIZE); + if(use_jproj_coords) + ifma_BNU_to_mb8((int64u (*)[8])P.Z, (const int64u* (*))pa_pubz, P256_BITSIZE); + else + MB_FUNC_NAME(mov_FE256_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p256_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_p256_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_p256_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_p256_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P256_POINT R; + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_nistp256_mul_point_)(&R, &P, secretz); + + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[P256_LEN52]; + ifma_aminv52_p256_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_p256_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_p256_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p256_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, P256_BITSIZE); + + /* clear computed shared keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p384.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p384.c new file mode 100644 index 000000000..16edf1b2e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p384.c @@ -0,0 +1,252 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key depends on is pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates +// or +// - in (x:y) affine coordinate +*/ +DLL_PUBLIC +mbx_status mbx_nistp384_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const BIGNUM* skey = pa_skey[buf_no]; + const BIGNUM* pubx = pa_pubx[buf_no]; + const BIGNUM* puby = pa_puby[buf_no]; + const BIGNUM* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey || NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[P384_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])secretz, (const BIGNUM**)pa_skey, P384_BITSIZE); + secretz[P384_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, P384_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P384_POINT P; + /* set party's public */ + ifma_BN_to_mb8((int64u (*)[8])P.X, (const BIGNUM* (*))pa_pubx, P384_BITSIZE); /* P-> radix 2^52 */ + ifma_BN_to_mb8((int64u (*)[8])P.Y, (const BIGNUM* (*))pa_puby, P384_BITSIZE); + if(use_jproj_coords) + ifma_BN_to_mb8((int64u (*)[8])P.Z, (const BIGNUM* (*))pa_pubz, P384_BITSIZE); + else + MB_FUNC_NAME(mov_FE384_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p384_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_p384_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_p384_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_p384_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P384_POINT R; + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_nistp384_mul_point_)(&R, &P, secretz); + + /* clear ephemeral secret copy */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[P384_LEN52]; + ifma_aminv52_p384_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_p384_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_p384_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p384_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, P384_BITSIZE); + + /* clear shared secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_nistp384_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const int64u* skey = pa_skey[buf_no]; + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey || NULL==pubx || NULL== puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[P384_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])secretz, (const int64u**)pa_skey, P384_BITSIZE); + secretz[P384_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, P384_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P384_POINT P; + /* set party's public */ + ifma_BNU_to_mb8((int64u (*)[8])P.X, (const int64u* (*))pa_pubx, P384_BITSIZE); // P-> crypto_mb radix 2^52 + ifma_BNU_to_mb8((int64u (*)[8])P.Y, (const int64u* (*))pa_puby, P384_BITSIZE); + if(use_jproj_coords) + ifma_BNU_to_mb8((int64u (*)[8])P.Z, (const int64u* (*))pa_pubz, P384_BITSIZE); + else + MB_FUNC_NAME(mov_FE384_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p384_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_p384_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_p384_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_p384_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P384_POINT R; + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_nistp384_mul_point_)(&R, &P, secretz); + + /* clear ephemeral secret copy */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[P384_LEN52]; + ifma_aminv52_p384_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_p384_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_p384_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p384_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, P384_BITSIZE); + + /* clear shared secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p521.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p521.c new file mode 100644 index 000000000..a5d349471 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdh_p521.c @@ -0,0 +1,252 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key depends on is pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates +// or +// - in (x:y) affine coordinate +*/ +DLL_PUBLIC +mbx_status mbx_nistp521_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const BIGNUM* skey = pa_skey[buf_no]; + const BIGNUM* pubx = pa_pubx[buf_no]; + const BIGNUM* puby = pa_puby[buf_no]; + const BIGNUM* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey || NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[P521_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])secretz, (const BIGNUM**)pa_skey, P521_BITSIZE); + secretz[P521_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, P521_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P521_POINT P; + /* set party's public */ + ifma_BN_to_mb8((int64u (*)[8])P.X, (const BIGNUM* (*))pa_pubx, P521_BITSIZE); /* P-> radix 2^52 */ + ifma_BN_to_mb8((int64u (*)[8])P.Y, (const BIGNUM* (*))pa_puby, P521_BITSIZE); + if(use_jproj_coords) + ifma_BN_to_mb8((int64u (*)[8])P.Z, (const BIGNUM* (*))pa_pubz, P521_BITSIZE); + else + MB_FUNC_NAME(mov_FE521_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p521_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_p521_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_p521_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_p521_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P521_POINT R; + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_nistp521_mul_point_)(&R, &P, secretz); + + /* clear ephemeral secret copy */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[P521_LEN52]; + ifma_aminv52_p521_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_p521_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_p521_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p521_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, P521_BITSIZE); + + /* clear shared secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_nistp521_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const int64u* skey = pa_skey[buf_no]; + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey || NULL==pubx || NULL== puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[P521_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])secretz, (const int64u**)pa_skey, P521_BITSIZE); + secretz[P521_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, P521_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P521_POINT P; + /* set party's public */ + ifma_BNU_to_mb8((int64u (*)[8])P.X, (const int64u* (*))pa_pubx, P521_BITSIZE); // P-> crypto_mb radix 2^52 + ifma_BNU_to_mb8((int64u (*)[8])P.Y, (const int64u* (*))pa_puby, P521_BITSIZE); + if(use_jproj_coords) + ifma_BNU_to_mb8((int64u (*)[8])P.Z, (const int64u* (*))pa_pubz, P521_BITSIZE); + else + MB_FUNC_NAME(mov_FE521_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p521_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_p521_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_p521_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_p521_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + P521_POINT R; + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_nistp521_mul_point_)(&R, &P, secretz); + + /* clear ephemeral secret copy */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[P521_LEN52]; + ifma_aminv52_p521_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_p521_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_p521_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p521_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, P521_BITSIZE); + + /* clear shared secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdsa_p256.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdsa_p256.c new file mode 100644 index 000000000..97a6476d7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecdsa_p256.c @@ -0,0 +1,887 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#include +#ifdef OPENSSL_IS_BORINGSSL +#include +#endif +#endif + +/* +// common functions +*/ + +/* +// compute secret key inversion +// +// inv_skey 1/skey mod n256 +// +// note: pay attention on skey[] presenttaion +// it should be FE element of N256 basef GF +*/ +static void nistp256_ecdsa_inv_keys_mb8(U64 inv_skey[], + const U64 skey[], + int8u pBuffer[]) +{ + /* compute inversion ober n256 of secret keys */ + MB_FUNC_NAME(ifma_tomont52_n256_)(inv_skey, skey); + ifma_aminv52_n256_mb8(inv_skey, inv_skey); /* 1/skeys mod n256 */ + MB_FUNC_NAME(ifma_frommont52_n256_)(inv_skey, inv_skey); +} + +/* +// compute r-component of the ECDSA signature +// +// r = ([skey]*G).x mod n256 +// +// note: pay attention on skey[] presenttaion +// it should be transposed and zero expanded +*/ +static __mb_mask nistp256_ecdsa_sign_r_mb8(U64 sign_r[], + const U64 skey[], + int8u pBuffer[]) +{ + /* compute ephemeral public keys */ + P256_POINT P; + + MB_FUNC_NAME(ifma_ec_nistp256_mul_pointbase_)(&P, skey); + + /* extract affine P.x */ + MB_FUNC_NAME(ifma_aminv52_p256_)(P.Z, P.Z); /* 1/Z */ + MB_FUNC_NAME(ifma_ams52_p256_)(P.Z, P.Z); /* 1/Z^2 */ + MB_FUNC_NAME(ifma_amm52_p256_)(P.X, P.X, P.Z); /* x = (X) * (1/Z^2) */ + + /* convert x-coordinate to regular and then tp Montgomery n256 */ + MB_FUNC_NAME(ifma_frommont52_p256_)(P.X, P.X); + MB_FUNC_NAME(ifma_fastred52_pn256_)(sign_r, P.X); /* fast reduction p => n */ + + return MB_FUNC_NAME(is_zero_FE256_)(sign_r); +} + +/* +// compute s-component of the ECDSA signature +// +// s = (inv_eph) * (msg + prv_skey*sign_r) mod n256 +*/ +static __mb_mask nistp256_ecdsa_sign_s_mb8(U64 sign_s[], + U64 msg[], + const U64 sign_r[], + U64 inv_eph_skey[], + U64 reg_skey[], + int8u pBuffer[]) +{ + __ALIGN64 U64 tmp[P256_LEN52]; + + /* conver to Montgomery over n256 domain */ + MB_FUNC_NAME(ifma_tomont52_n256_)(inv_eph_skey, inv_eph_skey); + MB_FUNC_NAME(ifma_tomont52_n256_)(tmp, sign_r); + MB_FUNC_NAME(ifma_tomont52_n256_)(msg, msg); + MB_FUNC_NAME(ifma_tomont52_n256_)(reg_skey, reg_skey); + + /* s = (inv_eph) * (msg + prv_skey*sign_r) mod n256 */ + MB_FUNC_NAME(ifma_amm52_n256_)(sign_s, reg_skey, tmp); + MB_FUNC_NAME(ifma_add52_n256_)(sign_s, sign_s, msg); + MB_FUNC_NAME(ifma_amm52_n256_)(sign_s, sign_s, inv_eph_skey); + MB_FUNC_NAME(ifma_frommont52_n256_)(sign_s, sign_s); + + return MB_FUNC_NAME(is_zero_FE256_)(sign_s); +} + +/* +// ECDSA signature verification algorithm +*/ +static __mb_mask nistp256_ecdsa_verify_mb8(U64 sign_r[], + U64 sign_s[], + U64 msg[], + P256_POINT* W) +{ + /* convert public key coords to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p256_)(W->X, W->X); + MB_FUNC_NAME(ifma_tomont52_p256_)(W->Y, W->Y); + MB_FUNC_NAME(ifma_tomont52_p256_)(W->Z, W->Z); + + __ALIGN64 U64 h1[P256_LEN52]; + __ALIGN64 U64 h2[P256_LEN52]; + + /* h = (sign_s)^(-1) */ + MB_FUNC_NAME(ifma_tomont52_n256_)(sign_s, sign_s); + MB_FUNC_NAME(ifma_aminv52_n256_)(sign_s, sign_s); + /* h1 = msg * h */ + MB_FUNC_NAME(ifma_tomont52_n256_)(h1, msg); + MB_FUNC_NAME(ifma_amm52_n256_)(h1, h1, sign_s); + MB_FUNC_NAME(ifma_frommont52_n256_)(h1, h1); + /* h2 = sign_r * h */ + MB_FUNC_NAME(ifma_tomont52_n256_)(h2, sign_r); + MB_FUNC_NAME(ifma_amm52_n256_)(h2, h2, sign_s); + MB_FUNC_NAME(ifma_frommont52_n256_)(h2, h2); + + int64u tmp[8][P256_LEN64]; + int64u* pa_tmp[8] = { tmp[0], tmp[1], tmp[2], tmp[3], + tmp[4], tmp[5], tmp[6], tmp[7] }; + + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])h1, P256_BITSIZE); + ifma_BNU_transpose_copy((int64u(*)[8])h1, (const int64u(**))pa_tmp, P256_BITSIZE); + + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])h2, P256_BITSIZE); + ifma_BNU_transpose_copy((int64u(*)[8])h2, (const int64u(**))pa_tmp, P256_BITSIZE); + + h1[P256_LEN64] = get_zero64(); + h2[P256_LEN64] = get_zero64(); + + P256_POINT P; + + // P = h1*G + h2*W + MB_FUNC_NAME(ifma_ec_nistp256_mul_point_)(W, W, h2); + MB_FUNC_NAME(ifma_ec_nistp256_mul_pointbase_)(&P, h1); + MB_FUNC_NAME(ifma_ec_nistp256_add_point_)(&P, &P, W); + + // P != 0 + __mb_mask signature_err_mask = MB_FUNC_NAME(is_zero_point_cordinate_)(P.Z); + + /* sign_r_restored = P.X mod n */ + __ALIGN64 U64 sign_r_restored[P256_LEN52]; + MB_FUNC_NAME(get_nistp256_ec_affine_coords_)(sign_r_restored, NULL, &P); + MB_FUNC_NAME(ifma_frommont52_p256_)(sign_r_restored, sign_r_restored); + MB_FUNC_NAME(ifma_fastred52_pn256_)(sign_r_restored, sign_r_restored); + + /* sign_r_restored != sign_r */ + signature_err_mask |= ~(MB_FUNC_NAME(cmp_eq_FE256_)(sign_r_restored, sign_r)); + + return signature_err_mask; +} + +/* +// ECDSA kernels +*/ + +/* +// pre-computation of ECDSA signature +// +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the r-components of the signatures +// pa_eph_skey[] array of pointers to the ephemeral (nonce) signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +// +// function computes two values that does not depend on the message to be signed +// - inversion of signer's ephemeral (nonce) keys +// - r-component of the signature +// and are later used during the signing process +*/ +DLL_PUBLIC +mbx_status mbx_nistp256_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_inv_eph_skey || NULL==pa_sign_rp || NULL==pa_eph_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* pinv_key = pa_inv_eph_skey[buf_no]; + int64u* psign_rp = pa_sign_rp[buf_no]; + const int64u* pkey = pa_eph_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==pinv_key || NULL==psign_rp || NULL==pkey) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + /* convert keys into FE and compute inversion */ + U64 T[P256_LEN52]; + ifma_BNU_to_mb8((int64u (*)[8])T, pa_eph_skey, P256_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE256_)(T), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear key's inversion */ + MB_FUNC_NAME(zero_)((int64u (*)[8])T, sizeof(T)/sizeof(U64)); + return status; + } + + nistp256_ecdsa_inv_keys_mb8(T, T, 0); + /* return results in suitable format */ + ifma_mb8_to_BNU(pa_inv_eph_skey, (const int64u(*)[8])T, P256_BITSIZE); + + /* clear key's inversion */ + MB_FUNC_NAME(zero_)((int64u (*)[8])T, sizeof(T)/sizeof(U64)); + + /* convert keys into scalars */ + U64 scalarz[P256_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalarz, pa_eph_skey, P256_BITSIZE); + scalarz[P256_LEN64] = get_zero64(); + /* compute r-component of the DSA signature */ + int8u stt_mask = nistp256_ecdsa_sign_r_mb8(T, scalarz, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + /* return results in suitable format */ + ifma_mb8_to_BNU(pa_sign_rp, (const int64u(*)[8])T, P256_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// computes ECDSA signature +// +// pa_sign_r[] array of pointers to the r-components of the signatures +// pa_sign_s[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral (nonce) private keys +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp256_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sign_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_msg || + NULL==pa_sign_rp || NULL==pa_inv_eph_skey || NULL==pa_reg_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* psign_r = pa_sign_r[buf_no]; + int8u* psign_s = pa_sign_s[buf_no]; + const int8u* pmsg = pa_msg[buf_no]; + const int64u* psign_pr = pa_sign_rp[buf_no]; + const int64u* pinv_eph_key = pa_inv_eph_skey[buf_no]; + const int64u* preg_key = pa_reg_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==psign_r || NULL==psign_s || NULL==pmsg || + NULL==psign_pr || NULL==pinv_eph_key || NULL==preg_key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + __ALIGN64 U64 inv_eph[P256_LEN52]; + __ALIGN64 U64 reg_skey[P256_LEN52]; + __ALIGN64 U64 sign_r[P256_LEN52]; + __ALIGN64 U64 sign_s[P256_LEN52]; + __ALIGN64 U64 msg[P256_LEN52]; + + /* convert inv_eph, reg_skey, sign_r and message to mb format */ + + ifma_BNU_to_mb8((int64u (*)[8])inv_eph, pa_inv_eph_skey, P256_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])reg_skey, pa_reg_skey, P256_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])sign_r, pa_sign_rp, P256_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P256_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE256_)(inv_eph), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE256_)(reg_skey), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE256_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n256_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph, sizeof(inv_eph)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + return status; + } + + /* compute s- signature component: s = (inv_eph) * (msg + prv_skey*sign_r) mod n256 */ + nistp256_ecdsa_sign_s_mb8(sign_s, msg, sign_r, inv_eph, reg_skey, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph, sizeof(inv_eph)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + + /* check if sign_r!=0 and sign_s!=0 */ + int8u stt_mask_r = MB_FUNC_NAME(is_zero_FE256_)(sign_r); + int8u stt_mask_s = MB_FUNC_NAME(is_zero_FE256_)(sign_s); + + /* convert sign_r and sing_s to strings */ + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, P256_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, P256_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask_r, MBX_STATUS_SIGNATURE_ERR); + status |= MBX_SET_STS_BY_MASK(status, stt_mask_s, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral (nonce) private keys +// pa_reg_skey[] array of pointers to the signer's regular (long term) private keys +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp256_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_msg || NULL==pa_eph_skey || NULL==pa_reg_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* psign_r = pa_sign_r[buf_no]; + int8u* psign_s = pa_sign_s[buf_no]; + const int8u* pmsg = pa_msg[buf_no]; + const int64u* peph_key = pa_eph_skey[buf_no]; + const int64u* preg_key = pa_reg_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==psign_r || NULL==psign_s || NULL==pmsg || NULL==peph_key || NULL==preg_key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + __ALIGN64 U64 inv_eph_key[P256_LEN52]; + __ALIGN64 U64 reg_key[P256_LEN52]; + __ALIGN64 U64 sign_r[P256_LEN52]; + __ALIGN64 U64 sign_s[P256_LEN52]; + __ALIGN64 U64 scalar[P256_LEN64+1]; + __ALIGN64 U64 msg[P256_LEN52]; + + /* convert ephemeral keys into FE */ + ifma_BNU_to_mb8((int64u (*)[8])inv_eph_key, pa_eph_skey, P256_BITSIZE); + /* convert epphemeral keys into sclar */ + ifma_BNU_transpose_copy((int64u (*)[8])scalar, pa_eph_skey, P256_BITSIZE); + scalar[P256_LEN64] = get_zero64(); + /* convert reg_skey */ + ifma_BNU_to_mb8((int64u (*)[8])reg_key, pa_reg_skey, P256_BITSIZE); + /* convert message */ + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P256_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE256_)(inv_eph_key), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE256_)(reg_key), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n256_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph_key, sizeof(inv_eph_key)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar, sizeof(scalar)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_key, sizeof(reg_key)/sizeof(U64)); + return status; + } + + /* compute inversion */ + nistp256_ecdsa_inv_keys_mb8(inv_eph_key, inv_eph_key, pBuffer); + /* compute r-component */ + nistp256_ecdsa_sign_r_mb8(sign_r, scalar, pBuffer); + /* compute s-component */ + nistp256_ecdsa_sign_s_mb8(sign_s, msg, sign_r, inv_eph_key, reg_key, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph_key, sizeof(inv_eph_key)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar, sizeof(scalar)/sizeof(U64)); + + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_key, sizeof(reg_key)/sizeof(U64)); + + /* check if sign_r!=0 and sign_s!=0 */ + int8u stt_mask_r = MB_FUNC_NAME(is_zero_FE256_)(sign_r); + int8u stt_mask_s = MB_FUNC_NAME(is_zero_FE256_)(sign_s); + + /* convert singnature components to strings */ + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, P256_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, P256_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask_r, MBX_STATUS_SIGNATURE_ERR); + status |= MBX_SET_STS_BY_MASK(status, stt_mask_s, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pBuffer pointer to the scratch buffer*/ +DLL_PUBLIC +mbx_status mbx_nistp256_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_msg || NULL==pa_sign_r || NULL==pa_sign_s) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + const int8u* msg = pa_msg[buf_no]; + const int8u* r = pa_sign_r[buf_no]; + const int8u* s = pa_sign_s[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==pubx || NULL==puby || NULL==msg || NULL== r || NULL==s || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + /* if all pointers NULL exit */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __ALIGN64 U64 msg[P256_LEN52]; + __ALIGN64 U64 sign_r[P256_LEN52]; + __ALIGN64 U64 sign_s[P256_LEN52]; + + /* convert input params */ + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P256_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])sign_r, pa_sign_r, P256_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])sign_s, pa_sign_s, P256_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n256_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n256_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n256_)(sign_s), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + P256_POINT W; + + ifma_BNU_to_mb8((int64u (*)[8])W.X, (const int64u* (*))pa_pubx, P256_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])W.Y, (const int64u* (*))pa_puby, P256_BITSIZE); + if(use_jproj_coords) + ifma_BNU_to_mb8((int64u (*)[8])W.Z, (const int64u* (*))pa_pubz, P256_BITSIZE); + else + MB_FUNC_NAME(mov_FE256_)(W.Z, (U64*)ones); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p256_)(W.X), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p256_)(W.Y), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p256_)(W.Z), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __mb_mask signature_err_mask = nistp256_ecdsa_verify_mb8(sign_r,sign_s,msg, &W); + status |= MBX_SET_STS_BY_MASK(status, signature_err_mask, MBX_STATUS_SIGNATURE_ERR); + + return status; +} + +/* +// OpenSSL's specific implementations +*/ +#ifndef BN_OPENSSL_DISABLE + +static void reverse_inplace(int8u* inpout, int len) +{ + int mudpoint = len/2; + for(int n=0; n + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#include +#ifdef OPENSSL_IS_BORINGSSL +#include +#endif +#endif + +/* +// common functions +*/ + +/* +// compute secret key inversion +// +// inv_skey 1/skey mod n384 +// +// note: pay attention on skey[] presenttaion +// it should be FE element of N384 basef GF +*/ +static void nistp384_ecdsa_inv_keys_mb8(U64 inv_skey[], + const U64 skey[], + int8u pBuffer[]) +{ + /* compute inversion ober n384 of secret keys */ + MB_FUNC_NAME(ifma_tomont52_n384_)(inv_skey, skey); + ifma_aminv52_n384_mb8(inv_skey, inv_skey); /* 1/skeys mod n384 */ + MB_FUNC_NAME(ifma_frommont52_n384_)(inv_skey, inv_skey); +} + +/* +// compute r-component of the ECDSA signature +// +// r = ([skey]*G).x mod n384 +// +// note: pay attention on skey[] presenttaion +// it should be transposed and zero expanded +*/ +static __mb_mask nistp384_ecdsa_sign_r_mb8(U64 sign_r[], + const U64 skey[], + int8u pBuffer[]) +{ + /* compute ephemeral public keys */ + P384_POINT P; + + MB_FUNC_NAME(ifma_ec_nistp384_mul_pointbase_)(&P, skey); + + /* extract affine P.x */ + MB_FUNC_NAME(ifma_aminv52_p384_)(P.Z, P.Z); /* 1/Z */ + MB_FUNC_NAME(ifma_ams52_p384_)(P.Z, P.Z); /* 1/Z^2 */ + MB_FUNC_NAME(ifma_amm52_p384_)(P.X, P.X, P.Z); /* x = (X) * (1/Z^2) */ + + /* convert x-coordinate to regular and then tp Montgomery n384 */ + MB_FUNC_NAME(ifma_frommont52_p384_)(P.X, P.X); + MB_FUNC_NAME(ifma_fastred52_pn384_)(sign_r, P.X); /* fast reduction p => n */ + + return MB_FUNC_NAME(is_zero_FE384_)(sign_r); +} + +/* +// compute s-component of the ECDSA signature +// +// s = (inv_eph) * (msg + prv_skey*sign_r) mod n384 +*/ +static __mb_mask nistp384_ecdsa_sign_s_mb8(U64 sign_s[], + U64 msg[], + const U64 sign_r[], + U64 inv_eph_skey[], + U64 reg_skey[], + int8u pBuffer[]) +{ + __ALIGN64 U64 tmp[P384_LEN52]; + + /* conver to Montgomery over n384 domain */ + MB_FUNC_NAME(ifma_tomont52_n384_)(inv_eph_skey, inv_eph_skey); + MB_FUNC_NAME(ifma_tomont52_n384_)(tmp, sign_r); + MB_FUNC_NAME(ifma_tomont52_n384_)(msg, msg); + MB_FUNC_NAME(ifma_tomont52_n384_)(reg_skey, reg_skey); + + /* s = (inv_eph) * (msg + prv_skey*sign_r) mod n384 */ + MB_FUNC_NAME(ifma_amm52_n384_)(sign_s, reg_skey, tmp); + MB_FUNC_NAME(ifma_add52_n384_)(sign_s, sign_s, msg); + MB_FUNC_NAME(ifma_amm52_n384_)(sign_s, sign_s, inv_eph_skey); + MB_FUNC_NAME(ifma_frommont52_n384_)(sign_s, sign_s); + + return MB_FUNC_NAME(is_zero_FE384_)(sign_s); +} + +/* +// ECDSA signature verification algorithm +*/ +static __mb_mask nistp384_ecdsa_verify_mb8(U64 sign_r[], + U64 sign_s[], + U64 msg[], + P384_POINT* W) +{ + /* convert public key coords to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p384_)(W->X, W->X); + MB_FUNC_NAME(ifma_tomont52_p384_)(W->Y, W->Y); + MB_FUNC_NAME(ifma_tomont52_p384_)(W->Z, W->Z); + + __ALIGN64 U64 h1[P384_LEN52]; + __ALIGN64 U64 h2[P384_LEN52]; + + /* h = (sign_s)^(-1) */ + MB_FUNC_NAME(ifma_tomont52_n384_)(sign_s, sign_s); + MB_FUNC_NAME(ifma_aminv52_n384_)(sign_s, sign_s); + /* h1 = msg * h */ + MB_FUNC_NAME(ifma_tomont52_n384_)(h1, msg); + MB_FUNC_NAME(ifma_amm52_n384_)(h1, h1, sign_s); + MB_FUNC_NAME(ifma_frommont52_n384_)(h1, h1); + /* h2 = sign_r * h */ + MB_FUNC_NAME(ifma_tomont52_n384_)(h2, sign_r); + MB_FUNC_NAME(ifma_amm52_n384_)(h2, h2, sign_s); + MB_FUNC_NAME(ifma_frommont52_n384_)(h2, h2); + + int64u tmp[8][P384_LEN64]; + int64u* pa_tmp[8] = { tmp[0], tmp[1], tmp[2], tmp[3], + tmp[4], tmp[5], tmp[6], tmp[7] }; + + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])h1, P384_BITSIZE); + ifma_BNU_transpose_copy((int64u(*)[8])h1, (const int64u(**))pa_tmp, P384_BITSIZE); + + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])h2, P384_BITSIZE); + ifma_BNU_transpose_copy((int64u(*)[8])h2, (const int64u(**))pa_tmp, P384_BITSIZE); + + h1[P384_LEN64] = get_zero64(); + h2[P384_LEN64] = get_zero64(); + + P384_POINT P; + + // P = h1*G + h2*W + MB_FUNC_NAME(ifma_ec_nistp384_mul_point_)(W, W, h2); + MB_FUNC_NAME(ifma_ec_nistp384_mul_pointbase_)(&P, h1); + MB_FUNC_NAME(ifma_ec_nistp384_add_point_)(&P, &P, W); + + // P != 0 + __mb_mask signature_err_mask = MB_FUNC_NAME(is_zero_point_cordinate_)(P.Z); + + /* sign_r_restored = P.X mod n */ + __ALIGN64 U64 sign_r_restored[P384_LEN52]; + MB_FUNC_NAME(get_nistp384_ec_affine_coords_)(sign_r_restored, NULL, &P); + MB_FUNC_NAME(ifma_frommont52_p384_)(sign_r_restored, sign_r_restored); + MB_FUNC_NAME(ifma_fastred52_pn384_)(sign_r_restored, sign_r_restored); + + /* sign_r_restored != sign_r */ + signature_err_mask |= ~(MB_FUNC_NAME(cmp_eq_FE384_)(sign_r_restored, sign_r)); + + return signature_err_mask; +} + +/* +// ECDSA kernels +*/ + +/* +// pre-computation of ECDSA signature +// +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the r-components of the signatures +// pa_eph_skey[] array of pointers to the ephemeral (nonce) signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +// +// function computes two values that does not depend on the message to be signed +// - inversion of signer's ephemeral (nonce) keys +// - r-component of the signature +// and are later used during the signing process +*/ +DLL_PUBLIC +mbx_status mbx_nistp384_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_inv_eph_skey || NULL==pa_sign_rp || NULL==pa_eph_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* pinv_key = pa_inv_eph_skey[buf_no]; + int64u* psign_rp = pa_sign_rp[buf_no]; + const int64u* pkey = pa_eph_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==pinv_key || NULL==psign_rp || NULL==pkey) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + /* convert keys into FE and compute inversion */ + U64 T[P384_LEN52]; + ifma_BNU_to_mb8((int64u (*)[8])T, pa_eph_skey, P384_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE384_)(T), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear key's inversion */ + MB_FUNC_NAME(zero_)((int64u (*)[8])T, sizeof(T)/sizeof(U64)); + return status; + } + + nistp384_ecdsa_inv_keys_mb8(T, T, 0); + /* return results in suitable format */ + ifma_mb8_to_BNU(pa_inv_eph_skey, (const int64u(*)[8])T, P384_BITSIZE); + + /* clear key's inversion */ + MB_FUNC_NAME(zero_)((int64u (*)[8])T, sizeof(T)/sizeof(U64)); + + /* convert keys into scalars */ + U64 scalarz[P384_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalarz, pa_eph_skey, P384_BITSIZE); + scalarz[P384_LEN64] = get_zero64(); + /* compute r-component of the DSA signature */ + int8u stt_mask = nistp384_ecdsa_sign_r_mb8(T, scalarz, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + /* return results in suitable format */ + ifma_mb8_to_BNU(pa_sign_rp, (const int64u(*)[8])T, P384_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// computes ECDSA signature +// +// pa_sign_r[] array of pointers to the r-components of the signatures +// pa_sign_s[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral (nonce) private keys +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp384_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sign_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_msg || + NULL==pa_sign_rp || NULL==pa_inv_eph_skey || NULL==pa_reg_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* psign_r = pa_sign_r[buf_no]; + int8u* psign_s = pa_sign_s[buf_no]; + const int8u* pmsg = pa_msg[buf_no]; + const int64u* psign_pr = pa_sign_rp[buf_no]; + const int64u* pinv_eph_key = pa_inv_eph_skey[buf_no]; + const int64u* preg_key = pa_reg_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==psign_r || NULL==psign_s || NULL==pmsg || + NULL==psign_pr || NULL==pinv_eph_key || NULL==preg_key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + __ALIGN64 U64 inv_eph[P384_LEN52]; + __ALIGN64 U64 reg_skey[P384_LEN52]; + __ALIGN64 U64 sign_r[P384_LEN52]; + __ALIGN64 U64 sign_s[P384_LEN52]; + __ALIGN64 U64 msg[P384_LEN52]; + + /* convert inv_eph, reg_skey, sign_r and message to mb format */ + ifma_BNU_to_mb8((int64u (*)[8])inv_eph, pa_inv_eph_skey, P384_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])reg_skey, pa_reg_skey, P384_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])sign_r, pa_sign_rp, P384_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P384_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE384_)(inv_eph), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE384_)(reg_skey), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE384_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n384_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph, sizeof(inv_eph)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + return status; + } + + /* compute s- signature component: s = (inv_eph) * (msg + prv_skey*sign_r) mod n384 */ + nistp384_ecdsa_sign_s_mb8(sign_s, msg, sign_r, inv_eph, reg_skey, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph, sizeof(inv_eph)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + + /* check if sign_r!=0 and sign_s!=0 */ + int8u stt_mask_r = MB_FUNC_NAME(is_zero_FE384_)(sign_r); + int8u stt_mask_s = MB_FUNC_NAME(is_zero_FE384_)(sign_s); + + /* convert sign_r and sing_s to strings */ + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, P384_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, P384_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask_r, MBX_STATUS_SIGNATURE_ERR); + status |= MBX_SET_STS_BY_MASK(status, stt_mask_s, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral (nonce) private keys +// pa_reg_skey[] array of pointers to the signer's regular (long term) private keys +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp384_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_msg || NULL==pa_eph_skey || NULL==pa_reg_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* psign_r = pa_sign_r[buf_no]; + int8u* psign_s = pa_sign_s[buf_no]; + const int8u* pmsg = pa_msg[buf_no]; + const int64u* peph_key = pa_eph_skey[buf_no]; + const int64u* preg_key = pa_reg_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==psign_r || NULL==psign_s || NULL==pmsg || NULL==peph_key || NULL==preg_key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + __ALIGN64 U64 inv_eph_key[P384_LEN52]; + __ALIGN64 U64 reg_key[P384_LEN52]; + __ALIGN64 U64 sign_r[P384_LEN52]; + __ALIGN64 U64 sign_s[P384_LEN52]; + __ALIGN64 U64 scalar[P384_LEN64+1]; + __ALIGN64 U64 msg[P384_LEN52]; + + /* convert ephemeral keys into FE */ + ifma_BNU_to_mb8((int64u (*)[8])inv_eph_key, pa_eph_skey, P384_BITSIZE); + /* convert epphemeral keys into sclar*/ + ifma_BNU_transpose_copy((int64u (*)[8])scalar, pa_eph_skey, P384_BITSIZE); + scalar[P384_LEN64] = get_zero64(); + /* convert reg_skey*/ + ifma_BNU_to_mb8((int64u (*)[8])reg_key, pa_reg_skey, P384_BITSIZE); + /* convert message */ + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P384_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE384_)(inv_eph_key), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE384_)(reg_key), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n384_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph_key, sizeof(inv_eph_key)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar, sizeof(scalar)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_key, sizeof(reg_key)/sizeof(U64)); + return status; + } + + /* compute inversion */ + nistp384_ecdsa_inv_keys_mb8(inv_eph_key, inv_eph_key, pBuffer); + /* compute r-component */ + nistp384_ecdsa_sign_r_mb8(sign_r, scalar, pBuffer); + /* compute s-component */ + nistp384_ecdsa_sign_s_mb8(sign_s, msg, sign_r, inv_eph_key, reg_key, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph_key, sizeof(inv_eph_key)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar, sizeof(scalar)/sizeof(U64)); + + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_key, sizeof(reg_key)/sizeof(U64)); + + /* check if sign_r!=0 and sign_s!=0 */ + int8u stt_mask_r = MB_FUNC_NAME(is_zero_FE384_)(sign_r); + int8u stt_mask_s = MB_FUNC_NAME(is_zero_FE384_)(sign_s); + + /* convert singnature components to strings */ + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, P384_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, P384_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask_r, MBX_STATUS_SIGNATURE_ERR); + status |= MBX_SET_STS_BY_MASK(status, stt_mask_s, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// ECDSA signature verification +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the message representatives that have been signed +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp384_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + int use_jproj_coords = NULL != pa_pubz; + + /* test input pointers */ + if (NULL == pa_sign_r || NULL == pa_sign_s || NULL == pa_msg || NULL == pa_pubx || NULL == pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check data pointers */ + for (buf_no = 0; buf_no < 8; buf_no++) { + const int8u* psign_r = pa_sign_r[buf_no]; + const int8u* psign_s = pa_sign_s[buf_no]; + const int8u* pmsg = pa_msg[buf_no]; + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords ? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if (NULL == psign_r || NULL == psign_s || NULL == pmsg || NULL == pubx || NULL == puby || (use_jproj_coords && NULL == pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + /* if all pointers NULL exit */ + if (!MBX_IS_ANY_OK_STS(status)) + return status; + + __ALIGN64 U64 msg[P384_LEN52]; + __ALIGN64 U64 sign_r[P384_LEN52]; + __ALIGN64 U64 sign_s[P384_LEN52]; + + /* convert input params */ + ifma_HexStr8_to_mb8((int64u(*)[8])msg, pa_msg, P384_BITSIZE); + ifma_HexStr8_to_mb8((int64u(*)[8])sign_r, pa_sign_r, P384_BITSIZE); + ifma_HexStr8_to_mb8((int64u(*)[8])sign_s, pa_sign_s, P384_BITSIZE); + + /* + // check, that sign_r and sign_s is in [1, n – 1] + // it's equivalent to sign_ != 0 (because it is unsigned value) and sign_ < n + */ + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n384_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n384_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n384_)(sign_s), MBX_STATUS_MISMATCH_PARAM_ERR); + + if (!MBX_IS_ANY_OK_STS(status)) + return status; + + P384_POINT W; + + ifma_BNU_to_mb8((int64u(*)[8])W.X, (const int64u* (*))pa_pubx, P384_BITSIZE); + ifma_BNU_to_mb8((int64u(*)[8])W.Y, (const int64u* (*))pa_puby, P384_BITSIZE); + if (use_jproj_coords) + ifma_BNU_to_mb8((int64u(*)[8])W.Z, (const int64u* (*))pa_pubz, P384_BITSIZE); + else + MB_FUNC_NAME(mov_FE384_)(W.Z, (U64*)ones); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p384_)(W.X), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p384_)(W.Y), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p384_)(W.Z), MBX_STATUS_MISMATCH_PARAM_ERR); + + if (!MBX_IS_ANY_OK_STS(status)) + return status; + + __mb_mask signature_err_mask = nistp384_ecdsa_verify_mb8(sign_r, sign_s, msg, &W); + status |= MBX_SET_STS_BY_MASK(status, signature_err_mask, MBX_STATUS_SIGNATURE_ERR); + + return status; +} + +/* +// OpenSSL's specific implementations +*/ +#ifndef BN_OPENSSL_DISABLE + +static void reverse_inplace(int8u* inpout, int len) +{ + int mudpoint = len/2; + for(int n=0; n + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#include +#ifdef OPENSSL_IS_BORINGSSL +#include +#endif +#endif + +/* +// common functions +*/ + +/* +// compute secret key inversion +// +// inv_skey 1/skey mod n521 +// +// note: pay attention on skey[] presenttaion +// it should be FE element of N521 basef GF +*/ +static void nistp521_ecdsa_inv_keys_mb8(U64 inv_skey[], + const U64 skey[], + int8u pBuffer[]) +{ + /* compute inversion ober n521 of secret keys */ + MB_FUNC_NAME(ifma_tomont52_n521_)(inv_skey, skey); + ifma_aminv52_n521_mb8(inv_skey, inv_skey); /* 1/skeys mod n521 */ + MB_FUNC_NAME(ifma_frommont52_n521_)(inv_skey, inv_skey); +} + +/* +// compute r-component of the ECDSA signature +// +// r = ([skey]*G).x mod n521 +// +// note: pay attention on skey[] presenttaion +// it should be transposed and zero expanded +*/ +static __mb_mask nistp521_ecdsa_sign_r_mb8(U64 sign_r[], + const U64 skey[], + int8u pBuffer[]) +{ + /* compute ephemeral public keys */ + P521_POINT P; + + MB_FUNC_NAME(ifma_ec_nistp521_mul_pointbase_)(&P, skey); + + /* extract affine P.x */ + MB_FUNC_NAME(ifma_aminv52_p521_)(P.Z, P.Z); /* 1/Z */ + MB_FUNC_NAME(ifma_ams52_p521_)(P.Z, P.Z); /* 1/Z^2 */ + MB_FUNC_NAME(ifma_amm52_p521_)(P.X, P.X, P.Z); /* x = (X) * (1/Z^2) */ + + /* convert x-coordinate to regular and then tp Montgomery n521 */ + MB_FUNC_NAME(ifma_frommont52_p521_)(P.X, P.X); + MB_FUNC_NAME(ifma_fastred52_pn521_)(sign_r, P.X); /* fast reduction p => n */ + + return MB_FUNC_NAME(is_zero_FE521_)(sign_r); +} + +/* +// compute s-component of the ECDSA signature +// +// s = (inv_eph) * (msg + prv_skey*sign_r) mod n521 +*/ +static __mb_mask nistp521_ecdsa_sign_s_mb8(U64 sign_s[], + U64 msg[], + const U64 sign_r[], + U64 inv_eph_skey[], + U64 reg_skey[], + int8u pBuffer[]) +{ + __ALIGN64 U64 tmp[P521_LEN52]; + + /* conver to Montgomery over n521 domain */ + MB_FUNC_NAME(ifma_tomont52_n521_)(inv_eph_skey, inv_eph_skey); + MB_FUNC_NAME(ifma_tomont52_n521_)(tmp, sign_r); + MB_FUNC_NAME(ifma_tomont52_n521_)(msg, msg); + MB_FUNC_NAME(ifma_tomont52_n521_)(reg_skey, reg_skey); + + /* s = (inv_eph) * (msg + prv_skey*sign_r) mod n521 */ + MB_FUNC_NAME(ifma_amm52_n521_)(sign_s, reg_skey, tmp); + MB_FUNC_NAME(ifma_add52_n521_)(sign_s, sign_s, msg); + MB_FUNC_NAME(ifma_amm52_n521_)(sign_s, sign_s, inv_eph_skey); + MB_FUNC_NAME(ifma_frommont52_n521_)(sign_s, sign_s); + + return MB_FUNC_NAME(is_zero_FE521_)(sign_s); +} + +/* +// ECDSA signature verification algorithm +*/ +static __mb_mask nistp521_ecdsa_verify_mb8(U64 sign_r[], + U64 sign_s[], + U64 msg[], + P521_POINT* W) +{ + /* convert public key coords to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_p521_)(W->X, W->X); + MB_FUNC_NAME(ifma_tomont52_p521_)(W->Y, W->Y); + MB_FUNC_NAME(ifma_tomont52_p521_)(W->Z, W->Z); + + __ALIGN64 U64 h1[P521_LEN52]; + __ALIGN64 U64 h2[P521_LEN52]; + + /* h = (sign_s)^(-1) */ + MB_FUNC_NAME(ifma_tomont52_n521_)(sign_s, sign_s); + MB_FUNC_NAME(ifma_aminv52_n521_)(sign_s, sign_s); + /* h1 = msg * h */ + MB_FUNC_NAME(ifma_tomont52_n521_)(h1, msg); + MB_FUNC_NAME(ifma_amm52_n521_)(h1, h1, sign_s); + MB_FUNC_NAME(ifma_frommont52_n521_)(h1,h1); + /* h2 = sign_r * h */ + MB_FUNC_NAME(ifma_tomont52_n521_)(h2, sign_r); + MB_FUNC_NAME(ifma_amm52_n521_)(h2, h2, sign_s); + MB_FUNC_NAME(ifma_frommont52_n521_)(h2,h2); + + int64u tmp[8][P521_LEN64]; + int64u* pa_tmp[8] = {tmp[0], tmp[1], tmp[2], tmp[3], + tmp[4], tmp[5], tmp[6], tmp[7]}; + + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])h1, P521_BITSIZE); + ifma_BNU_transpose_copy((int64u (*)[8])h1, (const int64u(**))pa_tmp, P521_BITSIZE); + + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])h2, P521_BITSIZE); + ifma_BNU_transpose_copy((int64u (*)[8])h2, (const int64u(**))pa_tmp, P521_BITSIZE); + + h1[P521_LEN64] = get_zero64(); + h2[P521_LEN64] = get_zero64(); + + P521_POINT P; + + // P = h1*G + h2*W + MB_FUNC_NAME(ifma_ec_nistp521_mul_point_)(W, W, h2); + MB_FUNC_NAME(ifma_ec_nistp521_mul_pointbase_)(&P, h1); + MB_FUNC_NAME(ifma_ec_nistp521_add_point_)(&P, &P, W); + + // P != 0 + __mb_mask signature_err_mask = MB_FUNC_NAME(is_zero_point_cordinate_)(P.Z); + + /* sign_r_restored = P.X mod n */ + __ALIGN64 U64 sign_r_restored[P521_LEN52]; + MB_FUNC_NAME(get_nistp521_ec_affine_coords_)(sign_r_restored, NULL, &P); + MB_FUNC_NAME(ifma_frommont52_p521_)(sign_r_restored, sign_r_restored); + MB_FUNC_NAME(ifma_fastred52_pn521_)(sign_r_restored, sign_r_restored); + + /* sign_r_restored != sign_r */ + signature_err_mask |= ~(MB_FUNC_NAME(cmp_eq_FE521_)(sign_r_restored, sign_r)); + + return signature_err_mask; +} + +/* +// ECDSA kernels +*/ + +/* +// pre-computation of ECDSA signature +// +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_sign_rp[] array of pointers to the r-components of the signatures +// pa_eph_skey[] array of pointers to the ephemeral (nonce) signer's ephemeral private keys +// pBuffer pointer to the scratch buffer +// +// function computes two values that does not depend on the message to be signed +// - inversion of signer's ephemeral (nonce) keys +// - r-component of the signature +// and are later used during the signing process +*/ +DLL_PUBLIC +mbx_status mbx_nistp521_ecdsa_sign_setup_mb8(int64u* pa_inv_eph_skey[8], + int64u* pa_sign_rp[8], + const int64u* const pa_eph_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_inv_eph_skey || NULL==pa_sign_rp || NULL==pa_eph_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* pinv_key = pa_inv_eph_skey[buf_no]; + int64u* psign_rp = pa_sign_rp[buf_no]; + const int64u* pkey = pa_eph_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==pinv_key || NULL==psign_rp || NULL==pkey) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + /* convert keys into FE and compute inversion */ + U64 T[P521_LEN52]; + ifma_BNU_to_mb8((int64u (*)[8])T, pa_eph_skey, P521_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE521_)(T), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear key's inversion */ + MB_FUNC_NAME(zero_)((int64u (*)[8])T, sizeof(T)/sizeof(U64)); + return status; + } + + nistp521_ecdsa_inv_keys_mb8(T, T, 0); + /* return results in suitable format */ + ifma_mb8_to_BNU(pa_inv_eph_skey, (const int64u(*)[8])T, P521_BITSIZE); + + /* clear key's inversion */ + MB_FUNC_NAME(zero_)((int64u (*)[8])T, sizeof(T)/sizeof(U64)); + + /* convert keys into scalars */ + U64 scalarz[P521_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalarz, pa_eph_skey, P521_BITSIZE); + scalarz[P521_LEN64] = get_zero64(); + /* compute r-component of the DSA signature */ + int8u stt_mask = nistp521_ecdsa_sign_r_mb8(T, scalarz, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + /* return results in suitable format */ + ifma_mb8_to_BNU(pa_sign_rp, (const int64u(*)[8])T, P521_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// computes ECDSA signature +// +// pa_sign_r[] array of pointers to the r-components of the signatures +// pa_sign_s[] array of pointers to the s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_sign_rp[] array of pointers to the pre-computed r-components of the signatures +// pa_inv_eph_skey[] array of pointers to the inversion of signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the regular signer's ephemeral (nonce) private keys +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp521_ecdsa_sign_complete_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_sign_rp[8], + const int64u* const pa_inv_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_msg || + NULL==pa_sign_rp || NULL==pa_inv_eph_skey || NULL==pa_reg_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* psign_r = pa_sign_r[buf_no]; + int8u* psign_s = pa_sign_s[buf_no]; + const int8u* pmsg = pa_msg[buf_no]; + const int64u* psign_pr = pa_sign_rp[buf_no]; + const int64u* pinv_eph_key = pa_inv_eph_skey[buf_no]; + const int64u* preg_key = pa_reg_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==psign_r || NULL==psign_s || NULL==pmsg || + NULL==psign_pr || NULL==pinv_eph_key || NULL==preg_key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + __ALIGN64 U64 inv_eph[P521_LEN52]; + __ALIGN64 U64 reg_skey[P521_LEN52]; + __ALIGN64 U64 sign_r[P521_LEN52]; + __ALIGN64 U64 sign_s[P521_LEN52]; + __ALIGN64 U64 msg[P521_LEN52]; + + /* convert inv_eph, reg_skey, sign_r and message to mb format */ + ifma_BNU_to_mb8((int64u (*)[8])inv_eph, pa_inv_eph_skey, P521_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])reg_skey, pa_reg_skey, P521_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])sign_r, pa_sign_rp, P521_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P521_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE521_)(inv_eph), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE521_)(reg_skey), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE521_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n521_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph, sizeof(inv_eph)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + return status; + } + + /* compute s- signature component: s = (inv_eph) * (msg + prv_skey*sign_r) mod n521 */ + nistp521_ecdsa_sign_s_mb8(sign_s, msg, sign_r, inv_eph, reg_skey, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph, sizeof(inv_eph)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + + /* check if sign_r!=0 and sign_s!=0 */ + int8u stt_mask_r = MB_FUNC_NAME(is_zero_FE521_)(sign_r); + int8u stt_mask_s = MB_FUNC_NAME(is_zero_FE521_)(sign_s); + + /* convert sign_r and sing_s to strings */ + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, P521_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, P521_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask_r, MBX_STATUS_SIGNATURE_ERR); + status |= MBX_SET_STS_BY_MASK(status, stt_mask_s, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// Computes ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_eph_skey[] array of pointers to the signer's ephemeral (nonce) private keys +// pa_reg_skey[] array of pointers to the signer's regular (long term) private keys +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp521_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_msg || NULL==pa_eph_skey || NULL==pa_reg_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* check data pointers */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* psign_r = pa_sign_r[buf_no]; + int8u* psign_s = pa_sign_s[buf_no]; + const int8u* pmsg = pa_msg[buf_no]; + const int64u* peph_key = pa_eph_skey[buf_no]; + const int64u* preg_key = pa_reg_skey[buf_no]; + /* if any of pointer NULL set error status */ + if(NULL==psign_r || NULL==psign_s || NULL==pmsg || NULL==peph_key || NULL==preg_key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + __ALIGN64 U64 inv_eph_key[P521_LEN52]; + __ALIGN64 U64 reg_key[P521_LEN52]; + __ALIGN64 U64 sign_r[P521_LEN52]; + __ALIGN64 U64 sign_s[P521_LEN52]; + __ALIGN64 U64 scalar[P521_LEN64+1]; + __ALIGN64 U64 msg[P521_LEN52]; + + /* convert ephemeral keys into FE */ + ifma_BNU_to_mb8((int64u (*)[8])inv_eph_key, pa_eph_skey, P521_BITSIZE); + /* convert epphemeral keys into sclar*/ + ifma_BNU_transpose_copy((int64u (*)[8])scalar, pa_eph_skey, P521_BITSIZE); + scalar[P521_LEN64] = get_zero64(); + /* convert reg_skey*/ + ifma_BNU_to_mb8((int64u (*)[8])reg_key, pa_reg_skey, P521_BITSIZE); + /* convert message */ + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P521_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE521_)(inv_eph_key), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FE521_)(reg_key), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n521_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph_key, sizeof(inv_eph_key)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar, sizeof(scalar)/sizeof(U64)); + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_key, sizeof(reg_key)/sizeof(U64)); + return status; + } + + /* compute inversion */ + nistp521_ecdsa_inv_keys_mb8(inv_eph_key, inv_eph_key, pBuffer); + /* compute r-component */ + nistp521_ecdsa_sign_r_mb8(sign_r, scalar, pBuffer); + /* compute s-component */ + nistp521_ecdsa_sign_s_mb8(sign_s, msg, sign_r, inv_eph_key, reg_key, pBuffer); + + /* clear copy of the ephemeral secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])inv_eph_key, sizeof(inv_eph_key)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar, sizeof(scalar)/sizeof(U64)); + + /* clear copy of the regular secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_key, sizeof(reg_key)/sizeof(U64)); + + /* check if sign_r!=0 and sign_s!=0 */ + int8u stt_mask_r = MB_FUNC_NAME(is_zero_FE521_)(sign_r); + int8u stt_mask_s = MB_FUNC_NAME(is_zero_FE521_)(sign_s); + + /* convert singnature components to strings */ + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, P521_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, P521_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, stt_mask_r, MBX_STATUS_SIGNATURE_ERR); + status |= MBX_SET_STS_BY_MASK(status, stt_mask_s, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// Verifies ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_nistp521_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_msg[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_msg || NULL==pa_sign_r || NULL==pa_sign_s) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + const int8u* msg = pa_msg[buf_no]; + const int8u* r = pa_sign_r[buf_no]; + const int8u* s = pa_sign_s[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==pubx || NULL==puby || NULL==msg || NULL== r || NULL==s || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + /* if all pointers NULL exit */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __ALIGN64 U64 msg[P521_LEN52]; + __ALIGN64 U64 sign_r[P521_LEN52]; + __ALIGN64 U64 sign_s[P521_LEN52]; + + /* convert input params */ + ifma_HexStr8_to_mb8((int64u (*)[8])msg, pa_msg, P521_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])sign_r, pa_sign_r, P521_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])sign_s, pa_sign_s, P521_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n521_)(msg), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n521_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_n521_)(sign_s), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + P521_POINT W; + + ifma_BNU_to_mb8((int64u (*)[8])W.X, (const int64u* (*))pa_pubx, P521_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])W.Y, (const int64u* (*))pa_puby, P521_BITSIZE); + if(use_jproj_coords) + ifma_BNU_to_mb8((int64u (*)[8])W.Z, (const int64u* (*))pa_pubz, P521_BITSIZE); + else + MB_FUNC_NAME(mov_FE521_)(W.Z, (U64*)ones); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p521_)(W.X), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p521_)(W.Y), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_p521_)(W.Z), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __mb_mask signature_err_mask = nistp521_ecdsa_verify_mb8(sign_r,sign_s,msg, &W); + status |= MBX_SET_STS_BY_MASK(status, signature_err_mask, MBX_STATUS_SIGNATURE_ERR); + + return status; +} + +/* +// OpenSSL's specific implementations +*/ +#ifndef BN_OPENSSL_DISABLE + +static void reverse_inplace(int8u* inpout, int len) +{ + int mudpoint = len/2; + for(int n=0; n +#include + + +/* simplify naming */ +#define sqr MB_FUNC_NAME(ifma_ams52_p256_) +#define mul MB_FUNC_NAME(ifma_amm52_p256_) +#define add MB_FUNC_NAME(ifma_add52_p256_) +#define sub MB_FUNC_NAME(ifma_sub52_p256_) +#define mul2 MB_FUNC_NAME(ifma_double52_p256_) +#define mul3 MB_FUNC_NAME(ifma_tripple52_p256_) +#define div2 MB_FUNC_NAME(ifma_half52_p256_) + + +/* +// Presentation of point at infinity: +// - projective (X : Y : 0) +// - affine (0 : 0) +*/ + +/* +// R(X3:Y3:Z3) = [2]P(X1:Y1:Z1) +// +// formulas: +// A = 4*X1*Y1^2 +// B = 3*(X1^2-Z1^4) +// X3= B^2 -2*A +// Y3= B*(A-X3) -8*Y1^4 +// Z3= 2*Y1*Z1 +// +// cost: 4S+4M+9A +// +*/ +void MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(P256_POINT* r, const P256_POINT* p) +{ + __ALIGN64 U64 T[P256_LEN52]; + __ALIGN64 U64 U[P256_LEN52]; + __ALIGN64 U64 V[P256_LEN52]; + __ALIGN64 U64 A[P256_LEN52]; + __ALIGN64 U64 B[P256_LEN52]; + + const U64* X1 = p->X; /* input point */ + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + U64* X3 = r->X; /* output point */ + U64* Y3 = r->Y; + U64* Z3 = r->Z; + + mul2(T, Y1); /* T = 2*Y1 */ + + sqr(V, T); /* V = 4*Y1^2 */ /* sqr_dual */ + sqr(U, Z1); /* U = Z1^2 */ + + sub(B, X1, U); /* B = X1-Z1^2 */ + add(U, X1, U); /* U = X1+Z1^2 */ + + mul(A, V, X1); /* A = 4*X*Y1^2 */ /* mul_dual */ + mul(B, B, U); /* B = (X1^2-Z1^4) */ + + mul2(X3, A); /* X3 = 2*A */ + mul3(B, B); /* B = 3*(X1^2-Z1^4) */ + + sqr(U, B); /* U = B^2 */ /* sqr_dual */ + sqr(Y3, V); /* Y3= V^2 = 16*Y1^4 */ + + sub(X3, U, X3); /* X3=B^2 - 2*A */ + div2(Y3,Y3); /* Y3=Y3/2 = 8*Y1^4 */ + + sub(U, A, X3); /* U = A-X3 */ + + mul(Z3, T, Z1); /* Z3= 2*Y1*Z1 */ /* mul_dual */ + mul(U, U, B); /* U = B*(A-X3) */ + + sub(Y3, U, Y3); /* Y3 = B*(A-X3) -8*Y1^4 */ +} + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// cost: 4S+12M+7A +// +*/ +void MB_FUNC_NAME(ifma_ec_nistp256_add_point_)(P256_POINT* r, const P256_POINT* p, const P256_POINT* q) +{ + /* coordinates of p */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q */ + const U64* X2 = q->X; + const U64* Y2 = q->Y; + const U64* Z2 = q->Z; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->Z); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[P256_LEN52]; + __ALIGN64 U64 Y3[P256_LEN52]; + __ALIGN64 U64 Z3[P256_LEN52]; + + /* temporary */ + __ALIGN64 U64 U1[P256_LEN52]; + __ALIGN64 U64 U2[P256_LEN52]; + __ALIGN64 U64 S1[P256_LEN52]; + __ALIGN64 U64 S2[P256_LEN52]; + __ALIGN64 U64 H[P256_LEN52]; + __ALIGN64 U64 R[P256_LEN52]; + + mul(S1, Y1, Z2); /* S1 = Y1*Z2 */ + sqr(U1, Z2); /* U1 = Z2^2 */ + + mul(S2, Y2, Z1); /* S2 = Y2*Z1 */ + sqr(U2, Z1); /* U2 = Z1^2 */ + + mul(S1, S1, U1); /* S1 = Y1*Z2^3 */ + mul(S2, S2, U2); /* S2 = Y2*Z1^3 */ + + mul(U1, X1, U1); /* U1 = X1*Z2^2 */ + mul(U2, X2, U2); /* U2 = X2*Z1^2 */ + + sub(R, S2, S1); /* R = S2-S1 */ + sub(H, U2, U1); /* H = U2-U1 */ + + /* check if affine (p.x:p.y) == (q.x:q.y) and and do doubling if this happens */ + __mb_mask x_are_equal = MB_FUNC_NAME(is_zero_FE256_)(H); + __mb_mask y_are_equal = MB_FUNC_NAME(is_zero_FE256_)(R); + __mb_mask points_are_equal = (x_are_equal & y_are_equal & (~p_at_infinity) & (~q_at_infinity)); + + P256_POINT P2; + MB_FUNC_NAME(set_point_to_infinity_)(&P2); + if (points_are_equal) { + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&P2, p); + } + + mul(Z3, Z1, Z2); /* Z3 = Z1*Z2 */ + sqr(U2, H); /* U2 = H^2 */ + mul(Z3, Z3, H); /* Z3 = (Z1*Z2)*H */ + sqr(S2, R); /* S2 = R^2 */ + mul(H, H, U2); /* H = H^3 */ + + mul(U1, U1, U2); /* U1 = U1*H^2 */ + sub(X3, S2, H); /* X3 = R^2 - H^3 */ + mul2(U2, U1); /* U2 = 2*U1*H^2 */ + mul(S1, S1, H); /* S1 = S1*H^3 */ + sub(X3, X3, U2); /* X3 = (R^2 - H^3) -2*U1*H^2 */ + + sub(Y3, U1, X3); /* Y3 = R*(U1*H^2 - X3) -S1*H^3 */ + mul(Y3, Y3, R); + sub(Y3, Y3, S1); + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FE256_)(X3, X3, p_at_infinity, q->X); + MB_FUNC_NAME(mask_mov_FE256_)(Y3, Y3, p_at_infinity, q->Y); + MB_FUNC_NAME(mask_mov_FE256_)(Z3, Z3, p_at_infinity, q->Z); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FE256_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FE256_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FE256_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = points_are_equal? P2 : T */ + MB_FUNC_NAME(mask_mov_FE256_)(r->X, X3, points_are_equal, P2.X); + MB_FUNC_NAME(mask_mov_FE256_)(r->Y, Y3, points_are_equal, P2.Y); + MB_FUNC_NAME(mask_mov_FE256_)(r->Z, Z3, points_are_equal, P2.Z); +} + + +/* to Montgomery conversion constant +// r = 2^(P256_LEN52*DIGIT_SIZE) mod p256 +*/ +__ALIGN64 static const int64u p256_r_mb[P256_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0000000000000010) }, + { REP8_DECL(0x000f000000000000) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000ffeffffffffff) }, + { REP8_DECL(0x00000000000fffff) } +}; +const U64* MB_FUNC_NAME(ifma_ec_nistp256_coord_one_)(void) +{ + return (U64*)p256_r_mb; +} + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2=1) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// if Z2=1, then +// A = X1 B = X2*Z1^2 C = Y1 D = Y2*Z1^3 +// E = B-X1 F = D-Y1 +// X3= -E^3 -2*X1*E^2 + F^2 +// Y3= -Y1*E^3 + F*(X1*E^2 -X3) +// Z3= Z1*E +// +// cost: 3S+8M+7A +*/ +void MB_FUNC_NAME(ifma_ec_nistp256_add_point_affine_)(P256_POINT* r, const P256_POINT* p, const P256_POINT_AFFINE* q) +{ + /* coordinates of p (projective) */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q (affine) */ + const U64* X2 = q->x; + const U64* Y2 = q->y; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->x) + & MB_FUNC_NAME(is_zero_point_cordinate_)(q->y); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[P256_LEN52]; + __ALIGN64 U64 Y3[P256_LEN52]; + __ALIGN64 U64 Z3[P256_LEN52]; + + __ALIGN64 U64 U2[P256_LEN52]; + __ALIGN64 U64 S2[P256_LEN52]; + __ALIGN64 U64 H[P256_LEN52]; + __ALIGN64 U64 R[P256_LEN52]; + + sqr(R, Z1); // R = Z1^2 + mul(S2, Y2, Z1); // S2 = Y2*Z1 + mul(U2, X2, R); // U2 = X2*Z1^2 + mul(S2, S2, R); // S2 = Y2*Z1^3 + + sub(H, U2, X1); // H = U2-X1 + sub(R, S2, Y1); // R = S2-Y1 + + mul(Z3, H, Z1); // Z3 = H*Z1 + + sqr(U2, H); // U2 = H^2 + sqr(S2, R); // S2 = R^2 + mul(H, H, U2); // H = H^3 + + mul(U2, U2, X1); // U2 = X1*H^2 + + mul(Y3, H, Y1); // T = Y1*H^3 + + mul2(X3, U2); // X3 = 2*X1*H^2 + sub(X3, S2, X3); // X3 = R^2 - 2*X1*H^2 + sub(X3, X3, H); // X3 = R^2 - 2*X1*H^2 -H^3 + + sub(U2, U2, X3); // U2 = X1*H^2 - X3 + mul(U2, U2, R); // U2 = R*(X1*H^2 - X3) + sub(Y3, U2, Y3); // Y3 = -Y1*H^3 + R*(X1*H^2 - X3) + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FE256_)(X3, X3, p_at_infinity, q->x); + MB_FUNC_NAME(mask_mov_FE256_)(Y3, Y3, p_at_infinity, q->y); + MB_FUNC_NAME(mask_mov_FE256_)(Z3, Z3, p_at_infinity, (U64*)p256_r_mb); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FE256_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FE256_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FE256_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = T */ + MB_FUNC_NAME(mov_FE256_)(r->X, X3); + MB_FUNC_NAME(mov_FE256_)(r->Y, Y3); + MB_FUNC_NAME(mov_FE256_)(r->Z, Z3); +} + +void MB_FUNC_NAME(get_nistp256_ec_affine_coords_)(U64 x[], U64 y[], const P256_POINT* P) +{ + __ALIGN64 U64 invZ1[P256_LEN52]; + __ALIGN64 U64 invZn[P256_LEN52]; + + /* 1/Z and 1/Z^2 */ + MB_FUNC_NAME(ifma_aminv52_p256_)(invZ1, P->Z); + MB_FUNC_NAME(ifma_ams52_p256_)(invZn, invZ1); + + /* if affine P.x requested */ + if(x) + MB_FUNC_NAME(ifma_amm52_p256_)(x, P->X, invZn); + + /* if affine P.y requested */ + if(y) { + MB_FUNC_NAME(ifma_amm52_p256_)(invZn, invZn, invZ1); + MB_FUNC_NAME(ifma_amm52_p256_)(y, P->Y, invZn); + } +} + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +static __NOINLINE void clear_secret_context(U64* wval, U64* dval, __mb_mask* dsign) +{ + *wval = get_zero64(); + *dval = get_zero64(); + *dsign = 0; + return; +} + +#define WIN_SIZE (4) + +/* + s = (Ipp8u)(~((wvalue >> ws) - 1)); //sign + d = (1 << (ws+1)) - wvalue - 1; // digit, win size "ws" + d = (d & s) | (wvaluen & ~s); + d = (d >> 1) + (d & 1); + *sign = s & 1; + *digit = (Ipp8u)d; +*/ +__INLINE void MB_FUNC_NAME(booth_recode_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract point */ +static void MB_FUNC_NAME(extract_point_)(P256_POINT* r, const P256_POINT tbl[], U64 idx) +{ + /* decrenent index (the table noes not contain [0]*P */ + U64 idx_target = sub64(idx, set1(1)); + + /* assume the point at infinity is what need */ + P256_POINT R; + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + /* find out what we actually need or just keep original infinity */ + int32u n; + for(n=0; n<(1<<(WIN_SIZE-1)); n++) { + U64 idx_curr = set1(n); + __mb_mask k = cmp64_mask(idx_curr, idx_target, _MM_CMPINT_EQ); + + /* R = k? tbl[] : R */ + MB_FUNC_NAME(secure_mask_mov_FE256_)(R.X, R.X, k, tbl[n].X); + MB_FUNC_NAME(secure_mask_mov_FE256_)(R.Y, R.Y, k, tbl[n].Y); + MB_FUNC_NAME(secure_mask_mov_FE256_)(R.Z, R.Z, k, tbl[n].Z); + } + MB_FUNC_NAME(mov_FE256_)(r->X, R.X); + MB_FUNC_NAME(mov_FE256_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE256_)(r->Z, R.Z); +} + +void MB_FUNC_NAME(ifma_ec_nistp256_mul_point_)(P256_POINT* r, const P256_POINT* p, const U64 scalar[]) +{ + /* pre-computed table */ + __ALIGN64 P256_POINT tbl[1<<(WIN_SIZE-1)]; + + /* + // compute tbl[] = [n]P, n=1,..,2^(WIN_SIZE-1): + // + // tbl[2*n] = tbl[2*n-1]+p + // tbl[2*n+1] = [2]*tbl[n] + */ + /* tbl[0] = p */ + MB_FUNC_NAME(mov_FE256_)(tbl[0].X, p->X); + MB_FUNC_NAME(mov_FE256_)(tbl[0].Y, p->Y); + MB_FUNC_NAME(mov_FE256_)(tbl[0].Z, p->Z); + /* tbl[1] = [2]*p */ + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&tbl[1], p); + + int n; + for(n=1; n < (1<<(WIN_SIZE-1))/2; n++) { + MB_FUNC_NAME(ifma_ec_nistp256_add_point_)(&tbl[2*n], &tbl[2*n-1], p); + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&tbl[2*n+1], &tbl[n]); + } + + P256_POINT R; + P256_POINT T; + U64 Ty[P256_LEN52]; + + /* + // point (LR) multiplication + */ + U64 idx_mask = set1( (1<<(WIN_SIZE+1))-1 ); + int bit = P256_BITSIZE-(P256_BITSIZE % WIN_SIZE); + int chunk_no = (bit-1)/64; + int chunk_shift = (bit-1)%64; + + /* first window */ + U64 wvalue = loadu64(&scalar[chunk_no]); + wvalue = and64( srli64(wvalue, chunk_shift), idx_mask); + + U64 dvalue; + __mb_mask dsign; + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&R, tbl, dvalue); + + for(bit-=WIN_SIZE; bit>=WIN_SIZE; bit-=WIN_SIZE) { + /* doubling */ + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + #endif + + /* extract precomputed []P */ + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + /* T = dsign? -T : T */ + MB_FUNC_NAME(ifma_neg52_p256_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FE256_)(T.Y, T.Y, dsign, Ty); + + /* acumulate T */ + MB_FUNC_NAME(ifma_ec_nistp256_add_point_)(&R, &R, &T); + } + + /* last window */ + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_nistp256_dbl_point_)(&R, &R); + #endif + + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + MB_FUNC_NAME(ifma_neg52_p256_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FE256_)(T.Y, T.Y, dsign, Ty); + + MB_FUNC_NAME(ifma_ec_nistp256_add_point_)(&R, &R, &T); + + /* r = R */ + MB_FUNC_NAME(mov_FE256_)(r->X, R.X); + MB_FUNC_NAME(mov_FE256_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE256_)(r->Z, R.Z); + + /* clear r (to fix potential secutity flaw in case of ecdh */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef WIN_SIZE + + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +#include + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE /* defined in the header above */ + +__INLINE void MB_FUNC_NAME(booth_recode_bp_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, BP_WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(BP_WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract affine affine point */ +__INLINE void MB_FUNC_NAME(extract_point_affine_)(P256_POINT_AFFINE* r, const SINGLE_P256_POINT_AFFINE* tbl, U64 idx) +{ + /* decrement index (the table noes not contain [0]*P */ + U64 targIdx = sub64(idx, set1(1)); + + U64 ax0, ax1, ax2, ax3, ax4, ay0, ay1, ay2, ay3, ay4; + + /* assume the point at infinity is what need */ + ax0 = ax1 = ax2 = ax3 = ax4 = ay0 = ay1 = ay2 = ay3 = ay4 = get_zero64(); + + /* find out what we actually need or just keep original infinity */ + int n; + U64 currIdx = get_zero64(); + for(n=0; n<(1<<(BP_WIN_SIZE-1)); n++, tbl++, currIdx = add64(currIdx, set1(1))) { + __mb_mask k = cmp64_mask(currIdx, targIdx, _MM_CMPINT_EQ); + + /* R = k? set1( tbl[] ) : R */ + ax0 = mask_add64(ax0, k, ax0, set1( tbl->x[0] )); + ax1 = mask_add64(ax1, k, ax1, set1( tbl->x[1] )); + ax2 = mask_add64(ax2, k, ax2, set1( tbl->x[2] )); + ax3 = mask_add64(ax3, k, ax3, set1( tbl->x[3] )); + ax4 = mask_add64(ax4, k, ax4, set1( tbl->x[4] )); + + ay0 = mask_add64(ay0, k, ay0, set1( tbl->y[0] )); + ay1 = mask_add64(ay1, k, ay1, set1( tbl->y[1] )); + ay2 = mask_add64(ay2, k, ay2, set1( tbl->y[2] )); + ay3 = mask_add64(ay3, k, ay3, set1( tbl->y[3] )); + ay4 = mask_add64(ay4, k, ay4, set1( tbl->y[4] )); + } + + r->x[0] = ax0; + r->x[1] = ax1; + r->x[2] = ax2; + r->x[3] = ax3; + r->x[4] = ax4; + + r->y[0] = ay0; + r->y[1] = ay1; + r->y[2] = ay2; + r->y[3] = ay3; + r->y[4] = ay4; +} + +void MB_FUNC_NAME(ifma_ec_nistp256_mul_pointbase_)(P256_POINT* r, const U64 scalar[]) +{ + /* pre-computed table of base powers */ + SINGLE_P256_POINT_AFFINE* tbl = &ifma_ec_nistp256_bp_precomp[0][0]; + + P256_POINT R; + P256_POINT_AFFINE A; + U64 Ty[P256_LEN52]; + + /* R = O */ + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + + /* + // base point (RL) multiplication + */ + U64 wvalue, dvalue; + __mb_mask dsign; + + U64 idx_mask = set1( (1<<(BP_WIN_SIZE+1))-1 ); + int bit = 0; + + /* first window - window[0] */ + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_p256_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FE256_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_nistp256_add_point_affine_)(&R, &R, &A); + + int chunk_no; + int chunk_shift; + for(bit+=BP_WIN_SIZE; bit<=P256_BITSIZE; bit+=BP_WIN_SIZE) { + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_p256_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FE256_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_nistp256_add_point_affine_)(&R, &R, &A); + } + + /* r = R */ + MB_FUNC_NAME(mov_FE256_)(r->X, R.X); + MB_FUNC_NAME(mov_FE256_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE256_)(r->Z, R.Z); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef BP_WIN_SIZE + + +/* P256 parameters: mont(a), mont(b) */ +__ALIGN64 static const int64u mont_a_p256_mb[P256_LEN52][8] = { + { REP8_DECL(0x000fffffffffffcf) }, + { REP8_DECL(0x00030fffffffffff) }, + { REP8_DECL(0x000000000000000) }, + { REP8_DECL(0x0000031000000000) }, + { REP8_DECL(0x0000ffffffcf0000) } +}; +__ALIGN64 static const int64u mont_b_p256_mb[P256_LEN52][8] = { + { REP8_DECL(0x000df6229c4bddfd) }, + { REP8_DECL(0x000ca8843090d89c) }, + { REP8_DECL(0x000212ed6acf005c) }, + { REP8_DECL(0x00083415a220abf7) }, + { REP8_DECL(0x0000c30061dd4874) } +}; + +/* +// We have a curve defined by a Weierstrass equation: y^2 = x^3 + a*x + b. +// +// The points are considered in Jacobian projective coordinates +// where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). +// Substituting this and multiplying by Z^6 transforms the above equation into +// Y^2 = X^3 + a*X*Z^4 + b*Z^6 +// To test this, we add up the right-hand side in 'rh'. +*/ +__mb_mask MB_FUNC_NAME(ifma_is_on_curve_p256_)(const P256_POINT* p, int use_jproj_coords) +{ + U64 rh[P256_LEN52]; + U64 Z4[P256_LEN52], Z6[P256_LEN52], tmp[P256_LEN52]; + + /* rh := X^2 */ + MB_FUNC_NAME(ifma_ams52_p256_)(rh, p->X); + + /* if Z!=1, then rh = X^3 + a*X*Z^4 + b*Z^6 = X*(X^2 + a*X*Z^4) + b*Z^6 */ + if(use_jproj_coords) { + MB_FUNC_NAME(ifma_ams52_p256_)(tmp, p->Z); /* tmp = Z^2 */ + MB_FUNC_NAME(ifma_ams52_p256_)(Z4, tmp); /* Z4 = Z^4 */ + MB_FUNC_NAME(ifma_amm52_p256_)(Z6, Z4, tmp); /* Z6 = Z^6 */ + + MB_FUNC_NAME(ifma_add52_p256_)(tmp, Z4, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_add52_p256_)(tmp, tmp, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_sub52_p256_)(rh, rh, tmp); /* rh = X^2 + a*Z^4 */ + MB_FUNC_NAME(ifma_amm52_p256_)(rh, rh, p->X); /* rh = (X^2 + a*Z^4)*X */ + + MB_FUNC_NAME(ifma_amm52_p256_)(tmp, Z6, (U64*)mont_b_p256_mb); + MB_FUNC_NAME(ifma_add52_p256_)(rh, rh, tmp); /* rh = (X^2 + a*Z^4)*X + b*Z^6 */ + } + /* if Z==1, then rh = X^3 + a*X + b = X*(X^2 +a) b */ + else { + MB_FUNC_NAME(ifma_add52_p256_)(rh, rh, (U64*)mont_a_p256_mb); /* rh = X^2+a */ + MB_FUNC_NAME(ifma_amm52_p256_)(rh, rh, p->X); /* rh = (X^2+a)*X */ + MB_FUNC_NAME(ifma_add52_p256_)(rh, rh, (U64*)mont_b_p256_mb); /* rh = (X^2+a)*X + b */ + } + MB_FUNC_NAME(ifma_frommont52_p256_)(rh, rh); + + /* rl = tmp = Y^2 */ + MB_FUNC_NAME(ifma_ams52_p256_)(tmp, p->Y); + MB_FUNC_NAME(ifma_frommont52_p256_)(tmp, tmp); + + /* mask = rl==rh */ + __mb_mask is_on_curve_mask = MB_FUNC_NAME(cmp_eq_FE256_)(tmp, rh); + + return is_on_curve_mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpoint_p384.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpoint_p384.c new file mode 100644 index 000000000..4fdb27f56 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpoint_p384.c @@ -0,0 +1,715 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + + +/* simplify naming */ +#define sqr MB_FUNC_NAME(ifma_ams52_p384_) +#define mul MB_FUNC_NAME(ifma_amm52_p384_) +#define add MB_FUNC_NAME(ifma_add52_p384_) +#define sub MB_FUNC_NAME(ifma_sub52_p384_) +#define mul2 MB_FUNC_NAME(ifma_double52_p384_) +#define mul3 MB_FUNC_NAME(ifma_tripple52_p384_) +#define div2 MB_FUNC_NAME(ifma_half52_p384_) + + +/* +// Presentation of point at infinity: +// - projective (X : Y : 0) +// - affine (0 : 0) +*/ + +/* +// R(X3:Y3:Z3) = [2]P(X1:Y1:Z1) +// +// formulas: +// A = 4*X1*Y1^2 +// B = 3*(X1^2-Z1^4) +// X3= B^2 -2*A +// Y3= B*(A-X3) -8*Y1^4 +// Z3= 2*Y1*Z1 +// +// cost: 4S+4M+9A +// +*/ +void MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(P384_POINT* r, const P384_POINT* p) +{ + __ALIGN64 U64 T[P384_LEN52]; + __ALIGN64 U64 U[P384_LEN52]; + __ALIGN64 U64 V[P384_LEN52]; + __ALIGN64 U64 A[P384_LEN52]; + __ALIGN64 U64 B[P384_LEN52]; + + const U64* X1 = p->X; /* input point */ + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + U64* X3 = r->X; /* output point */ + U64* Y3 = r->Y; + U64* Z3 = r->Z; + + mul2(T, Y1); /* T = 2*Y1 */ + + sqr(V, T); /* V = 4*Y1^2 */ /* sqr_dual */ + sqr(U, Z1); /* U = Z1^2 */ + + sub(B, X1, U); /* B = X1-Z1^2 */ + add(U, X1, U); /* U = X1+Z1^2 */ + + mul(A, V, X1); /* A = 4*X*Y1^2 */ /* mul_dual */ + mul(B, B, U); /* B = (X1^2-Z1^4) */ + + mul2(X3, A); /* X3 = 2*A */ + mul3(B, B); /* B = 3*(X1^2-Z1^4) */ + + sqr(U, B); /* U = B^2 */ /* sqr_dual */ + sqr(Y3, V); /* Y3= V^2 = 16*Y1^4 */ + + sub(X3, U, X3); /* X3=B^2 - 2*A */ + div2(Y3,Y3); /* Y3=Y3/2 = 8*Y1^4 */ + + sub(U, A, X3); /* U = A-X3 */ + + mul(Z3, T, Z1); /* Z3= 2*Y1*Z1 */ /* mul_dual */ + mul(U, U, B); /* U = B*(A-X3) */ + + sub(Y3, U, Y3); /* Y3 = B*(A-X3) -8*Y1^4 */ +} + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// cost: 4S+12M+7A +// +*/ +void MB_FUNC_NAME(ifma_ec_nistp384_add_point_)(P384_POINT* r, const P384_POINT* p, const P384_POINT* q) +{ + /* coordinates of p */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q */ + const U64* X2 = q->X; + const U64* Y2 = q->Y; + const U64* Z2 = q->Z; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->Z); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[P384_LEN52]; + __ALIGN64 U64 Y3[P384_LEN52]; + __ALIGN64 U64 Z3[P384_LEN52]; + + /* temporary */ + __ALIGN64 U64 U1[P384_LEN52]; + __ALIGN64 U64 U2[P384_LEN52]; + __ALIGN64 U64 S1[P384_LEN52]; + __ALIGN64 U64 S2[P384_LEN52]; + __ALIGN64 U64 H[P384_LEN52]; + __ALIGN64 U64 R[P384_LEN52]; + + mul(S1, Y1, Z2); /* S1 = Y1*Z2 */ + sqr(U1, Z2); /* U1 = Z2^2 */ + + mul(S2, Y2, Z1); /* S2 = Y2*Z1 */ + sqr(U2, Z1); /* U2 = Z1^2 */ + + mul(S1, S1, U1); /* S1 = Y1*Z2^3 */ + mul(S2, S2, U2); /* S2 = Y2*Z1^3 */ + + mul(U1, X1, U1); /* U1 = X1*Z2^2 */ + mul(U2, X2, U2); /* U2 = X2*Z1^2 */ + + sub(R, S2, S1); /* R = S2-S1 */ + sub(H, U2, U1); /* H = U2-U1 */ + + /* check if affine (p.x:p.y) == (q.x:q.y) and and do doubling if this happens */ + __mb_mask x_are_equal = MB_FUNC_NAME(is_zero_FE384_)(H); + __mb_mask y_are_equal = MB_FUNC_NAME(is_zero_FE384_)(R); + __mb_mask points_are_equal = (x_are_equal & y_are_equal & (~p_at_infinity) & (~q_at_infinity)); + + P384_POINT P2; + MB_FUNC_NAME(set_point_to_infinity_)(&P2); + if (points_are_equal) { + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&P2, p); + } + + mul(Z3, Z1, Z2); /* Z3 = Z1*Z2 */ + sqr(U2, H); /* U2 = H^2 */ + mul(Z3, Z3, H); /* Z3 = (Z1*Z2)*H */ + sqr(S2, R); /* S2 = R^2 */ + mul(H, H, U2); /* H = H^3 */ + + mul(U1, U1, U2); /* U1 = U1*H^2 */ + sub(X3, S2, H); /* X3 = R^2 - H^3 */ + mul2(U2, U1); /* U2 = 2*U1*H^2 */ + mul(S1, S1, H); /* S1 = S1*H^3 */ + sub(X3, X3, U2); /* X3 = (R^2 - H^3) -2*U1*H^2 */ + + sub(Y3, U1, X3); /* Y3 = R*(U1*H^2 - X3) -S1*H^3 */ + mul(Y3, Y3, R); + sub(Y3, Y3, S1); + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FE384_)(X3, X3, p_at_infinity, q->X); + MB_FUNC_NAME(mask_mov_FE384_)(Y3, Y3, p_at_infinity, q->Y); + MB_FUNC_NAME(mask_mov_FE384_)(Z3, Z3, p_at_infinity, q->Z); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FE384_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FE384_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FE384_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = points_are_equal? P2 : T */ + MB_FUNC_NAME(mask_mov_FE384_)(r->X, X3, points_are_equal, P2.X); + MB_FUNC_NAME(mask_mov_FE384_)(r->Y, Y3, points_are_equal, P2.Y); + MB_FUNC_NAME(mask_mov_FE384_)(r->Z, Z3, points_are_equal, P2.Z); +} + + +/* Montgomery(1) +// r = 2^(P384_LEN52*DIGIT_SIZE) mod p384 +*/ +__ALIGN64 static const int64u p384_r_mb[P384_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0000000100000000) }, + { REP8_DECL(0x000ffffffffff000) }, + { REP8_DECL(0x0000000000ffffff) }, + { REP8_DECL(0x0000000000000010) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) } +}; + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2=1) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// if Z2=1, then +// A = X1 B = X2*Z1^2 C = Y1 D = Y2*Z1^3 +// E = B-X1 F = D-Y1 +// X3= -E^3 -2*X1*E^2 + F^2 +// Y3= -Y1*E^3 + F*(X1*E^2 -X3) +// Z3= Z1*E +// +// cost: 3S+8M+7A +*/ +void MB_FUNC_NAME(ifma_ec_nistp384_add_point_affine_)(P384_POINT* r, const P384_POINT* p, const P384_POINT_AFFINE* q) +{ + /* coordinates of p (projective) */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q (affine) */ + const U64* X2 = q->x; + const U64* Y2 = q->y; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->x) + & MB_FUNC_NAME(is_zero_point_cordinate_)(q->y); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[P384_LEN52]; + __ALIGN64 U64 Y3[P384_LEN52]; + __ALIGN64 U64 Z3[P384_LEN52]; + + __ALIGN64 U64 U2[P384_LEN52]; + __ALIGN64 U64 S2[P384_LEN52]; + __ALIGN64 U64 H[P384_LEN52]; + __ALIGN64 U64 R[P384_LEN52]; + + sqr(R, Z1); // R = Z1^2 + mul(S2, Y2, Z1); // S2 = Y2*Z1 + mul(U2, X2, R); // U2 = X2*Z1^2 + mul(S2, S2, R); // S2 = Y2*Z1^3 + + sub(H, U2, X1); // H = U2-X1 + sub(R, S2, Y1); // R = S2-Y1 + + mul(Z3, H, Z1); // Z3 = H*Z1 + + sqr(U2, H); // U2 = H^2 + sqr(S2, R); // S2 = R^2 + mul(H, H, U2); // H = H^3 + + mul(U2, U2, X1); // U2 = X1*H^2 + + mul(Y3, H, Y1); // T = Y1*H^3 + + mul2(X3, U2); // X3 = 2*X1*H^2 + sub(X3, S2, X3); // X3 = R^2 - 2*X1*H^2 + sub(X3, X3, H); // X3 = R^2 - 2*X1*H^2 -H^3 + + sub(U2, U2, X3); // U2 = X1*H^2 - X3 + mul(U2, U2, R); // U2 = R*(X1*H^2 - X3) + sub(Y3, U2, Y3); // Y3 = -Y1*H^3 + R*(X1*H^2 - X3) + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FE384_)(X3, X3, p_at_infinity, q->x); + MB_FUNC_NAME(mask_mov_FE384_)(Y3, Y3, p_at_infinity, q->y); + MB_FUNC_NAME(mask_mov_FE384_)(Z3, Z3, p_at_infinity, (U64*)p384_r_mb); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FE384_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FE384_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FE384_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = T */ + MB_FUNC_NAME(mov_FE384_)(r->X, X3); + MB_FUNC_NAME(mov_FE384_)(r->Y, Y3); + MB_FUNC_NAME(mov_FE384_)(r->Z, Z3); +} + +void MB_FUNC_NAME(get_nistp384_ec_affine_coords_)(U64 x[], U64 y[], const P384_POINT* P) +{ + __ALIGN64 U64 invZ1[P384_LEN52]; + __ALIGN64 U64 invZn[P384_LEN52]; + + /* 1/Z and 1/Z^2 */ + MB_FUNC_NAME(ifma_aminv52_p384_)(invZ1, P->Z); + MB_FUNC_NAME(ifma_ams52_p384_)(invZn, invZ1); + + /* if affine P.x requested */ + if(x) + MB_FUNC_NAME(ifma_amm52_p384_)(x, P->X, invZn); + + /* if affine P.y requested */ + if(y) { + MB_FUNC_NAME(ifma_amm52_p384_)(invZn, invZn, invZ1); + MB_FUNC_NAME(ifma_amm52_p384_)(y, P->Y, invZn); + } +} + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +static __NOINLINE void clear_secret_context(U64* wval, U64* dval, __mb_mask* dsign) +{ + *wval = get_zero64(); + *dval = get_zero64(); + *dsign = 0; + return; +} + +#define WIN_SIZE (4) + +/* + s = (Ipp8u)(~((wvalue >> ws) - 1)); //sign + d = (1 << (ws+1)) - wvalue - 1; // digit, win size "ws" + d = (d & s) | (wvaluen & ~s); + d = (d >> 1) + (d & 1); + *sign = s & 1; + *digit = (Ipp8u)d; +*/ +__INLINE void MB_FUNC_NAME(booth_recode_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract point */ +static void MB_FUNC_NAME(extract_point_)(P384_POINT* r, const P384_POINT tbl[], U64 idx) +{ + /* decrenent index (the table noes not contain [0]*P */ + U64 idx_target = sub64(idx, set1(1)); + + /* assume the point at infinity is what need */ + P384_POINT R; + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + /* find out what we actually need or just keep original infinity */ + int32u n; + for(n=0; n<(1<<(WIN_SIZE-1)); n++) { + U64 idx_curr = set1(n); + __mb_mask k = cmp64_mask(idx_curr, idx_target, _MM_CMPINT_EQ); + + /* R = k? tbl[] : R */ + MB_FUNC_NAME(secure_mask_mov_FE384_)(R.X, R.X, k, tbl[n].X); + MB_FUNC_NAME(secure_mask_mov_FE384_)(R.Y, R.Y, k, tbl[n].Y); + MB_FUNC_NAME(secure_mask_mov_FE384_)(R.Z, R.Z, k, tbl[n].Z); + } + MB_FUNC_NAME(mov_FE384_)(r->X, R.X); + MB_FUNC_NAME(mov_FE384_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE384_)(r->Z, R.Z); +} + +void MB_FUNC_NAME(ifma_ec_nistp384_mul_point_)(P384_POINT* r, const P384_POINT* p, const U64 scalar[]) +{ + /* pre-computed table */ + __ALIGN64 P384_POINT tbl[1<<(WIN_SIZE-1)]; + + /* + // compute tbl[] = [n]P, n=1,..,2^(WIN_SIZE-1): + // + // tbl[2*n] = tbl[2*n-1]+p + // tbl[2*n+1] = [2]*tbl[n] + */ + /* tbl[0] = p */ + MB_FUNC_NAME(mov_FE384_)(tbl[0].X, p->X); + MB_FUNC_NAME(mov_FE384_)(tbl[0].Y, p->Y); + MB_FUNC_NAME(mov_FE384_)(tbl[0].Z, p->Z); + /* tbl[1] = [2]*p */ + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&tbl[1], p); + + int n; + for(n=1; n < (1<<(WIN_SIZE-1))/2; n++) { + MB_FUNC_NAME(ifma_ec_nistp384_add_point_)(&tbl[2*n], &tbl[2*n-1], p); + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&tbl[2*n+1], &tbl[n]); + } + + P384_POINT R; + P384_POINT T; + U64 Ty[P384_LEN52]; + + /* + // point (LR) multiplication + */ + U64 idx_mask = set1( (1<<(WIN_SIZE+1))-1 ); + int bit = P384_BITSIZE-(P384_BITSIZE % WIN_SIZE); + int chunk_no = (bit-1)/64; + int chunk_shift = (bit-1)%64; + + /* first window */ + U64 wvalue = loadu64(&scalar[chunk_no]); + wvalue = and64( srli64(wvalue, chunk_shift), idx_mask); + + U64 dvalue; + __mb_mask dsign; + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&R, tbl, dvalue); + + for(bit-=WIN_SIZE; bit>=WIN_SIZE; bit-=WIN_SIZE) { + /* doubling */ + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + #endif + + /* extract precomputed []P */ + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + /* T = dsign? -T : T */ + MB_FUNC_NAME(ifma_neg52_p384_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FE384_)(T.Y, T.Y, dsign, Ty); + + /* acumulate T */ + MB_FUNC_NAME(ifma_ec_nistp384_add_point_)(&R, &R, &T); + } + + /* last window */ + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_nistp384_dbl_point_)(&R, &R); + #endif + + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + MB_FUNC_NAME(ifma_neg52_p384_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FE384_)(T.Y, T.Y, dsign, Ty); + + MB_FUNC_NAME(ifma_ec_nistp384_add_point_)(&R, &R, &T); + + /* r = R */ + MB_FUNC_NAME(mov_FE384_)(r->X, R.X); + MB_FUNC_NAME(mov_FE384_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE384_)(r->Z, R.Z); + + /* clear r (to fix potential secutity flaw in case of ecdh */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef WIN_SIZE + + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +#include + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE /* defined in the header above */ + +__INLINE void MB_FUNC_NAME(booth_recode_bp_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, BP_WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(BP_WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract affine affine point */ +__INLINE void MB_FUNC_NAME(extract_point_affine_)(P384_POINT_AFFINE* r, const SINGLE_P384_POINT_AFFINE* tbl, U64 idx) +{ + /* decrement index (the table noes not contain [0]*P */ + U64 targIdx = sub64(idx, set1(1)); + + U64 ax0, ax1, ax2, ax3, ax4, ax5, ax6, ax7; + U64 ay0, ay1, ay2, ay3, ay4, ay5, ay6, ay7; + + /* assume the point at infinity is what need */ + ax0 = ax1 = ax2 = ax3 = ax4 = ax5 = ax6 = ax7= + ay0 = ay1 = ay2 = ay3 = ay4 = ay5 = ay6 = ay7 = get_zero64(); + + /* find out what we actually need or just keep original infinity */ + int n; + U64 currIdx = get_zero64(); + for(n=0; n<(1<<(BP_WIN_SIZE-1)); n++, tbl++, currIdx = add64(currIdx, set1(1))) { + __mb_mask k = cmp64_mask(currIdx, targIdx, _MM_CMPINT_EQ); + + /* R = k? set1( tbl[] ) : R */ + ax0 = mask_add64(ax0, k, ax0, set1( tbl->x[0] )); + ax1 = mask_add64(ax1, k, ax1, set1( tbl->x[1] )); + ax2 = mask_add64(ax2, k, ax2, set1( tbl->x[2] )); + ax3 = mask_add64(ax3, k, ax3, set1( tbl->x[3] )); + ax4 = mask_add64(ax4, k, ax4, set1( tbl->x[4] )); + ax5 = mask_add64(ax5, k, ax5, set1( tbl->x[5] )); + ax6 = mask_add64(ax6, k, ax6, set1( tbl->x[6] )); + ax7 = mask_add64(ax7, k, ax7, set1( tbl->x[7] )); + + ay0 = mask_add64(ay0, k, ay0, set1( tbl->y[0] )); + ay1 = mask_add64(ay1, k, ay1, set1( tbl->y[1] )); + ay2 = mask_add64(ay2, k, ay2, set1( tbl->y[2] )); + ay3 = mask_add64(ay3, k, ay3, set1( tbl->y[3] )); + ay4 = mask_add64(ay4, k, ay4, set1( tbl->y[4] )); + ay5 = mask_add64(ay5, k, ay5, set1( tbl->y[5] )); + ay6 = mask_add64(ay6, k, ay6, set1( tbl->y[6] )); + ay7 = mask_add64(ay7, k, ay7, set1( tbl->y[7] )); + } + + r->x[0] = ax0; + r->x[1] = ax1; + r->x[2] = ax2; + r->x[3] = ax3; + r->x[4] = ax4; + r->x[5] = ax5; + r->x[6] = ax6; + r->x[7] = ax7; + + r->y[0] = ay0; + r->y[1] = ay1; + r->y[2] = ay2; + r->y[3] = ay3; + r->y[4] = ay4; + r->y[5] = ay5; + r->y[6] = ay6; + r->y[7] = ay7; +} + +void MB_FUNC_NAME(ifma_ec_nistp384_mul_pointbase_)(P384_POINT* r, const U64 scalar[]) +{ + /* pre-computed table of base powers */ + SINGLE_P384_POINT_AFFINE* tbl = &ifma_ec_nistp384_bp_precomp[0][0]; + + P384_POINT R; + P384_POINT_AFFINE A; + U64 Ty[P384_LEN52]; + + /* R = O */ + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + + /* + // base point (RL) multiplication + */ + U64 wvalue, dvalue; + __mb_mask dsign; + + U64 idx_mask = set1( (1<<(BP_WIN_SIZE+1))-1 ); + int bit = 0; + + /* first window - window[0] */ + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_p384_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FE384_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_nistp384_add_point_affine_)(&R, &R, &A); + + int chunk_no; + int chunk_shift; + for(bit+=BP_WIN_SIZE; bit<=P384_BITSIZE; bit+=BP_WIN_SIZE) { + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_p384_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FE384_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_nistp384_add_point_affine_)(&R, &R, &A); + } + + /* r = R */ + MB_FUNC_NAME(mov_FE384_)(r->X, R.X); + MB_FUNC_NAME(mov_FE384_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE384_)(r->Z, R.Z); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef BP_WIN_SIZE + + +/* P384 parameters: mont(a), mont(b) */ +__ALIGN64 int64u mont_a_p384_mb[P384_LEN52][8] = { //!!! + { REP8_DECL(0x000ffffdffffffff) }, + { REP8_DECL(0x000ff00000002fff) }, + { REP8_DECL(0x000ffffffbffffff) }, + { REP8_DECL(0x000fffffffffffcf) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x00000000000fffff) } +}; +__ALIGN64 int64u mont_b_p384_mb[P384_LEN52][8] = { //!!!!! + { REP8_DECL(0x00091c81cd08114b) }, + { REP8_DECL(0x0003708118870d03) }, + { REP8_DECL(0x000431bf24475444) }, + { REP8_DECL(0x000209b1920022fc) }, + { REP8_DECL(0x000e94938ae277f2) }, + { REP8_DECL(0x000022094e3374be) }, + { REP8_DECL(0x000ff9b62b21f41f) }, + { REP8_DECL(0x00000000000604fb) }, +}; + +/* +// We have a curve defined by a Weierstrass equation: y^2 = x^3 + a*x + b. +// +// The points are considered in Jacobian projective coordinates +// where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). +// Substituting this and multiplying by Z^6 transforms the above equation into +// Y^2 = X^3 + a*X*Z^4 + b*Z^6 +// To test this, we add up the right-hand side in 'rh'. +*/ +__mb_mask MB_FUNC_NAME(ifma_is_on_curve_p384_)(const P384_POINT* p, int use_jproj_coords) +{ + U64 rh[P384_LEN52]; + U64 Z4[P384_LEN52], Z6[P384_LEN52], tmp[P384_LEN52]; + + /* rh := X^2 */ + MB_FUNC_NAME(ifma_ams52_p384_)(rh, p->X); + + /* if Z!=1, then rh = X^3 + a*X*Z^4 + b*Z^6 = X*(X^2 + a*X*Z^4) + b*Z^6 */ + if(use_jproj_coords) { + MB_FUNC_NAME(ifma_ams52_p384_)(tmp, p->Z); /* tmp = Z^2 */ + MB_FUNC_NAME(ifma_ams52_p384_)(Z4, tmp); /* Z4 = Z^4 */ + MB_FUNC_NAME(ifma_amm52_p384_)(Z6, Z4, tmp); /* Z6 = Z^6 */ + + MB_FUNC_NAME(ifma_add52_p384_)(tmp, Z4, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_add52_p384_)(tmp, tmp, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_sub52_p384_)(rh, rh, tmp); /* rh = X^2 + a*Z^4 */ + MB_FUNC_NAME(ifma_amm52_p384_)(rh, rh, p->X); /* rh = (X^2 + a*Z^4)*X */ + + MB_FUNC_NAME(ifma_amm52_p384_)(tmp, Z6, (U64*)mont_b_p384_mb); + MB_FUNC_NAME(ifma_add52_p384_)(rh, rh, tmp); /* rh = (X^2 + a*Z^4)*X + b*Z^6 */ + } + /* if Z==1, then rh = X^3 + a*X + b = X*(X^2 +a) b */ + else { + MB_FUNC_NAME(ifma_add52_p384_)(rh, rh, (U64*)mont_a_p384_mb); /* rh = X^2+a */ + MB_FUNC_NAME(ifma_amm52_p384_)(rh, rh, p->X); /* rh = (X^2+a)*X */ + MB_FUNC_NAME(ifma_add52_p384_)(rh, rh, (U64*)mont_b_p384_mb); /* rh = (X^2+a)*X + b */ + } + MB_FUNC_NAME(ifma_frommont52_p384_)(rh, rh); + + /* rl = tmp = Y^2 */ + MB_FUNC_NAME(ifma_ams52_p384_)(tmp, p->Y); + MB_FUNC_NAME(ifma_frommont52_p384_)(tmp, tmp); + + /* mask = rl==rh */ + __mb_mask is_on_curve_mask = MB_FUNC_NAME(cmp_eq_FE384_)(tmp, rh); + + return is_on_curve_mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpoint_p521.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpoint_p521.c new file mode 100644 index 000000000..cc5b10e57 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpoint_p521.c @@ -0,0 +1,737 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + + +/* simplify naming */ +#define sqr MB_FUNC_NAME(ifma_ams52_p521_) +#define mul MB_FUNC_NAME(ifma_amm52_p521_) +#define add MB_FUNC_NAME(ifma_add52_p521_) +#define sub MB_FUNC_NAME(ifma_sub52_p521_) +#define mul2 MB_FUNC_NAME(ifma_double52_p521_) +#define mul3 MB_FUNC_NAME(ifma_tripple52_p521_) +#define div2 MB_FUNC_NAME(ifma_half52_p521_) + + +/* +// Presentation of point at infinity: +// - projective (X : Y : 0) +// - affine (0 : 0) +*/ + +/* +// R(X3:Y3:Z3) = [2]P(X1:Y1:Z1) +// +// formulas: +// A = 4*X1*Y1^2 +// B = 3*(X1^2-Z1^4) +// X3= B^2 -2*A +// Y3= B*(A-X3) -8*Y1^4 +// Z3= 2*Y1*Z1 +// +// cost: 4S+4M+9A +// +*/ +void MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(P521_POINT* r, const P521_POINT* p) +{ + __ALIGN64 U64 T[P521_LEN52]; + __ALIGN64 U64 U[P521_LEN52]; + __ALIGN64 U64 V[P521_LEN52]; + __ALIGN64 U64 A[P521_LEN52]; + __ALIGN64 U64 B[P521_LEN52]; + + const U64* X1 = p->X; /* input point */ + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + U64* X3 = r->X; /* output point */ + U64* Y3 = r->Y; + U64* Z3 = r->Z; + + mul2(T, Y1); /* T = 2*Y1 */ + + sqr(V, T); /* V = 4*Y1^2 */ /* sqr_dual */ + sqr(U, Z1); /* U = Z1^2 */ + + sub(B, X1, U); /* B = X1-Z1^2 */ + add(U, X1, U); /* U = X1+Z1^2 */ + + mul(A, V, X1); /* A = 4*X*Y1^2 */ /* mul_dual */ + mul(B, B, U); /* B = (X1^2-Z1^4) */ + + mul2(X3, A); /* X3 = 2*A */ + mul3(B, B); /* B = 3*(X1^2-Z1^4) */ + + sqr(U, B); /* U = B^2 */ /* sqr_dual */ + sqr(Y3, V); /* Y3= V^2 = 16*Y1^4 */ + + sub(X3, U, X3); /* X3=B^2 - 2*A */ + div2(Y3,Y3); /* Y3=Y3/2 = 8*Y1^4 */ + + sub(U, A, X3); /* U = A-X3 */ + + mul(Z3, T, Z1); /* Z3= 2*Y1*Z1 */ /* mul_dual */ + mul(U, U, B); /* U = B*(A-X3) */ + + sub(Y3, U, Y3); /* Y3 = B*(A-X3) -8*Y1^4 */ +} + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// cost: 4S+12M+7A +// +*/ +void MB_FUNC_NAME(ifma_ec_nistp521_add_point_)(P521_POINT* r, const P521_POINT* p, const P521_POINT* q) +{ + /* coordinates of p */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q */ + const U64* X2 = q->X; + const U64* Y2 = q->Y; + const U64* Z2 = q->Z; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->Z); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[P521_LEN52]; + __ALIGN64 U64 Y3[P521_LEN52]; + __ALIGN64 U64 Z3[P521_LEN52]; + + /* temporary */ + __ALIGN64 U64 U1[P521_LEN52]; + __ALIGN64 U64 U2[P521_LEN52]; + __ALIGN64 U64 S1[P521_LEN52]; + __ALIGN64 U64 S2[P521_LEN52]; + __ALIGN64 U64 H[P521_LEN52]; + __ALIGN64 U64 R[P521_LEN52]; + + mul(S1, Y1, Z2); /* S1 = Y1*Z2 */ + sqr(U1, Z2); /* U1 = Z2^2 */ + + mul(S2, Y2, Z1); /* S2 = Y2*Z1 */ + sqr(U2, Z1); /* U2 = Z1^2 */ + + mul(S1, S1, U1); /* S1 = Y1*Z2^3 */ + mul(S2, S2, U2); /* S2 = Y2*Z1^3 */ + + mul(U1, X1, U1); /* U1 = X1*Z2^2 */ + mul(U2, X2, U2); /* U2 = X2*Z1^2 */ + + sub(R, S2, S1); /* R = S2-S1 */ + sub(H, U2, U1); /* H = U2-U1 */ + + /* check if affine (p.x:p.y) == (q.x:q.y) and and do doubling if this happens */ + __mb_mask x_are_equal = MB_FUNC_NAME(is_zero_FE521_)(H); + __mb_mask y_are_equal = MB_FUNC_NAME(is_zero_FE521_)(R); + __mb_mask points_are_equal = (x_are_equal & y_are_equal & (~p_at_infinity) & (~q_at_infinity)); + + P521_POINT P2; + MB_FUNC_NAME(set_point_to_infinity_)(&P2); + if (points_are_equal) { + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&P2, p); + } + + mul(Z3, Z1, Z2); /* Z3 = Z1*Z2 */ + sqr(U2, H); /* U2 = H^2 */ + mul(Z3, Z3, H); /* Z3 = (Z1*Z2)*H */ + sqr(S2, R); /* S2 = R^2 */ + mul(H, H, U2); /* H = H^3 */ + + mul(U1, U1, U2); /* U1 = U1*H^2 */ + sub(X3, S2, H); /* X3 = R^2 - H^3 */ + mul2(U2, U1); /* U2 = 2*U1*H^2 */ + mul(S1, S1, H); /* S1 = S1*H^3 */ + sub(X3, X3, U2); /* X3 = (R^2 - H^3) -2*U1*H^2 */ + + sub(Y3, U1, X3); /* Y3 = R*(U1*H^2 - X3) -S1*H^3 */ + mul(Y3, Y3, R); + sub(Y3, Y3, S1); + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FE521_)(X3, X3, p_at_infinity, q->X); + MB_FUNC_NAME(mask_mov_FE521_)(Y3, Y3, p_at_infinity, q->Y); + MB_FUNC_NAME(mask_mov_FE521_)(Z3, Z3, p_at_infinity, q->Z); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FE521_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FE521_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FE521_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = T */ + /* r = points_are_equal? P2 : T */ + MB_FUNC_NAME(mask_mov_FE521_)(r->X, X3, points_are_equal, P2.X); + MB_FUNC_NAME(mask_mov_FE521_)(r->Y, Y3, points_are_equal, P2.Y); + MB_FUNC_NAME(mask_mov_FE521_)(r->Z, Z3, points_are_equal, P2.Z); +} + + +/* Montgomery(1) +// r = 2^(P521_LEN52*DIGIT_SIZE) mod p521 +*/ +__ALIGN64 static const int64u p521_r_mb[P521_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0008000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) } +}; + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2=1) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// if Z2=1, then +// A = X1 B = X2*Z1^2 C = Y1 D = Y2*Z1^3 +// E = B-X1 F = D-Y1 +// X3= -E^3 -2*X1*E^2 + F^2 +// Y3= -Y1*E^3 + F*(X1*E^2 -X3) +// Z3= Z1*E +// +// cost: 3S+8M+7A +*/ +void MB_FUNC_NAME(ifma_ec_nistp521_add_point_affine_)(P521_POINT* r, const P521_POINT* p, const P521_POINT_AFFINE* q) +{ + /* coordinates of p (projective) */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q (affine) */ + const U64* X2 = q->x; + const U64* Y2 = q->y; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->x) + & MB_FUNC_NAME(is_zero_point_cordinate_)(q->y); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[P521_LEN52]; + __ALIGN64 U64 Y3[P521_LEN52]; + __ALIGN64 U64 Z3[P521_LEN52]; + + __ALIGN64 U64 U2[P521_LEN52]; + __ALIGN64 U64 S2[P521_LEN52]; + __ALIGN64 U64 H[P521_LEN52]; + __ALIGN64 U64 R[P521_LEN52]; + + sqr(R, Z1); // R = Z1^2 + mul(S2, Y2, Z1); // S2 = Y2*Z1 + mul(U2, X2, R); // U2 = X2*Z1^2 + mul(S2, S2, R); // S2 = Y2*Z1^3 + + sub(H, U2, X1); // H = U2-X1 + sub(R, S2, Y1); // R = S2-Y1 + + mul(Z3, H, Z1); // Z3 = H*Z1 + + sqr(U2, H); // U2 = H^2 + sqr(S2, R); // S2 = R^2 + mul(H, H, U2); // H = H^3 + + mul(U2, U2, X1); // U2 = X1*H^2 + + mul(Y3, H, Y1); // T = Y1*H^3 + + mul2(X3, U2); // X3 = 2*X1*H^2 + sub(X3, S2, X3); // X3 = R^2 - 2*X1*H^2 + sub(X3, X3, H); // X3 = R^2 - 2*X1*H^2 -H^3 + + sub(U2, U2, X3); // U2 = X1*H^2 - X3 + mul(U2, U2, R); // U2 = R*(X1*H^2 - X3) + sub(Y3, U2, Y3); // Y3 = -Y1*H^3 + R*(X1*H^2 - X3) + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FE521_)(X3, X3, p_at_infinity, q->x); + MB_FUNC_NAME(mask_mov_FE521_)(Y3, Y3, p_at_infinity, q->y); + MB_FUNC_NAME(mask_mov_FE521_)(Z3, Z3, p_at_infinity, (U64*)p521_r_mb); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FE521_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FE521_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FE521_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = T */ + MB_FUNC_NAME(mov_FE521_)(r->X, X3); + MB_FUNC_NAME(mov_FE521_)(r->Y, Y3); + MB_FUNC_NAME(mov_FE521_)(r->Z, Z3); +} + +void MB_FUNC_NAME(get_nistp521_ec_affine_coords_)(U64 x[], U64 y[], const P521_POINT* P) +{ + __ALIGN64 U64 invZ1[P521_LEN52]; + __ALIGN64 U64 invZn[P521_LEN52]; + + /* 1/Z and 1/Z^2 */ + MB_FUNC_NAME(ifma_aminv52_p521_)(invZ1, P->Z); + MB_FUNC_NAME(ifma_ams52_p521_)(invZn, invZ1); + + /* if affine P.x requested */ + if(x) + MB_FUNC_NAME(ifma_amm52_p521_)(x, P->X, invZn); + + /* if affine P.y requested */ + if(y) { + MB_FUNC_NAME(ifma_amm52_p521_)(invZn, invZn, invZ1); + MB_FUNC_NAME(ifma_amm52_p521_)(y, P->Y, invZn); + } +} + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +static __NOINLINE void clear_secret_context(U64* wval, U64* dval, __mb_mask* dsign) +{ + *wval = get_zero64(); + *dval = get_zero64(); + *dsign = 0; + return; +} + +#define WIN_SIZE (4) + +/* + s = (Ipp8u)(~((wvalue >> ws) - 1)); //sign + d = (1 << (ws+1)) - wvalue - 1; // digit, win size "ws" + d = (d & s) | (wvaluen & ~s); + d = (d >> 1) + (d & 1); + *sign = s & 1; + *digit = (Ipp8u)d; +*/ +__INLINE void MB_FUNC_NAME(booth_recode_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract point */ +static void MB_FUNC_NAME(extract_point_)(P521_POINT* r, const P521_POINT tbl[], U64 idx) +{ + /* decrenent index (the table noes not contain [0]*P */ + U64 idx_target = sub64(idx, set1(1)); + + /* assume the point at infinity is what need */ + P521_POINT R; + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + /* find out what we actually need or just keep original infinity */ + int32u n; + for(n=0; n<(1<<(WIN_SIZE-1)); n++) { + U64 idx_curr = set1(n); + __mb_mask k = cmp64_mask(idx_curr, idx_target, _MM_CMPINT_EQ); + + /* R = k? tbl[] : R */ + MB_FUNC_NAME(secure_mask_mov_FE521_)(R.X, R.X, k, tbl[n].X); + MB_FUNC_NAME(secure_mask_mov_FE521_)(R.Y, R.Y, k, tbl[n].Y); + MB_FUNC_NAME(secure_mask_mov_FE521_)(R.Z, R.Z, k, tbl[n].Z); + } + MB_FUNC_NAME(mov_FE521_)(r->X, R.X); + MB_FUNC_NAME(mov_FE521_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE521_)(r->Z, R.Z); +} + +void MB_FUNC_NAME(ifma_ec_nistp521_mul_point_)(P521_POINT* r, const P521_POINT* p, const U64 scalar[]) +{ + /* pre-computed table */ + __ALIGN64 P521_POINT tbl[1<<(WIN_SIZE-1)]; + + /* + // compute tbl[] = [n]P, n=1,..,2^(WIN_SIZE-1): + // + // tbl[2*n] = tbl[2*n-1]+p + // tbl[2*n+1] = [2]*tbl[n] + */ + /* tbl[0] = p */ + MB_FUNC_NAME(mov_FE521_)(tbl[0].X, p->X); + MB_FUNC_NAME(mov_FE521_)(tbl[0].Y, p->Y); + MB_FUNC_NAME(mov_FE521_)(tbl[0].Z, p->Z); + /* tbl[1] = [2]*p */ + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&tbl[1], p); + + int n; + for(n=1; n < (1<<(WIN_SIZE-1))/2; n++) { + MB_FUNC_NAME(ifma_ec_nistp521_add_point_)(&tbl[2*n], &tbl[2*n-1], p); + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&tbl[2*n+1], &tbl[n]); + } + + P521_POINT R; + P521_POINT T; + U64 Ty[P521_LEN52]; + + /* + // point (LR) multiplication + */ + U64 idx_mask = set1( (1<<(WIN_SIZE+1))-1 ); + int bit = P521_BITSIZE-(P521_BITSIZE % WIN_SIZE); + int chunk_no = (bit-1)/64; + int chunk_shift = (bit-1)%64; + + /* first window */ + U64 wvalue = loadu64(&scalar[chunk_no]); + wvalue = and64( srli64(wvalue, chunk_shift), idx_mask); + + U64 dvalue; + __mb_mask dsign; + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&R, tbl, dvalue); + + for(bit-=WIN_SIZE; bit>=WIN_SIZE; bit-=WIN_SIZE) { + /* doubling */ + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + #endif + + /* extract precomputed []P */ + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + /* T = dsign? -T : T */ + MB_FUNC_NAME(ifma_neg52_p521_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FE521_)(T.Y, T.Y, dsign, Ty); + + /* acumulate T */ + MB_FUNC_NAME(ifma_ec_nistp521_add_point_)(&R, &R, &T); + } + + /* last window */ + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_nistp521_dbl_point_)(&R, &R); + #endif + + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + MB_FUNC_NAME(ifma_neg52_p521_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FE521_)(T.Y, T.Y, dsign, Ty); + + MB_FUNC_NAME(ifma_ec_nistp521_add_point_)(&R, &R, &T); + + /* r = R */ + MB_FUNC_NAME(mov_FE521_)(r->X, R.X); + MB_FUNC_NAME(mov_FE521_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE521_)(r->Z, R.Z); + + /* clear r (to fix potential secutity flaw in case of ecdh */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef WIN_SIZE + + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +#include + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE /* defined in the header above */ + +__INLINE void MB_FUNC_NAME(booth_recode_bp_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, BP_WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(BP_WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract affine affine point */ +__INLINE void MB_FUNC_NAME(extract_point_affine_)(P521_POINT_AFFINE* r, const SINGLE_P521_POINT_AFFINE* tbl, U64 idx) +{ + /* decrement index (the table noes not contain [0]*P */ + U64 targIdx = sub64(idx, set1(1)); + + U64 ax0, ax1, ax2, ax3, ax4, ax5, ax6, ax7, ax8, ax9, ax10; + U64 ay0, ay1, ay2, ay3, ay4, ay5, ay6, ay7, ay8, ay9, ay10; + + /* assume the point at infinity is what need */ + ax0 = ax1 = ax2 = ax3 = ax4 = ax5 = ax6 = ax7 = ax8 = ax9 = ax10 = + ay0 = ay1 = ay2 = ay3 = ay4 = ay5 = ay6 = ay7 = ay8 = ay9 = ay10 = get_zero64(); + + /* find out what we actually need or just keep original infinity */ + int n; + U64 currIdx = get_zero64(); + for(n=0; n<(1<<(BP_WIN_SIZE-1)); n++, tbl++, currIdx = add64(currIdx, set1(1))) { + __mb_mask k = cmp64_mask(currIdx, targIdx, _MM_CMPINT_EQ); + + /* R = k? set1( tbl[] ) : R */ + ax0 = mask_add64(ax0, k, ax0, set1( tbl->x[0] )); + ax1 = mask_add64(ax1, k, ax1, set1( tbl->x[1] )); + ax2 = mask_add64(ax2, k, ax2, set1( tbl->x[2] )); + ax3 = mask_add64(ax3, k, ax3, set1( tbl->x[3] )); + ax4 = mask_add64(ax4, k, ax4, set1( tbl->x[4] )); + ax5 = mask_add64(ax5, k, ax5, set1( tbl->x[5] )); + ax6 = mask_add64(ax6, k, ax6, set1( tbl->x[6] )); + ax7 = mask_add64(ax7, k, ax7, set1( tbl->x[7] )); + ax8 = mask_add64(ax8, k, ax8, set1( tbl->x[8] )); + ax9 = mask_add64(ax9, k, ax9, set1( tbl->x[9] )); + ax10= mask_add64(ax10,k, ax10,set1( tbl->x[10])); + + ay0 = mask_add64(ay0, k, ay0, set1( tbl->y[0] )); + ay1 = mask_add64(ay1, k, ay1, set1( tbl->y[1] )); + ay2 = mask_add64(ay2, k, ay2, set1( tbl->y[2] )); + ay3 = mask_add64(ay3, k, ay3, set1( tbl->y[3] )); + ay4 = mask_add64(ay4, k, ay4, set1( tbl->y[4] )); + ay5 = mask_add64(ay5, k, ay5, set1( tbl->y[5] )); + ay6 = mask_add64(ay6, k, ay6, set1( tbl->y[6] )); + ay7 = mask_add64(ay7, k, ay7, set1( tbl->y[7] )); + ay8 = mask_add64(ay8, k, ay8, set1( tbl->y[8] )); + ay9 = mask_add64(ay9, k, ay9, set1( tbl->y[9] )); + ay10= mask_add64(ay10,k, ay10,set1( tbl->y[10])); + } + + r->x[0] = ax0; + r->x[1] = ax1; + r->x[2] = ax2; + r->x[3] = ax3; + r->x[4] = ax4; + r->x[5] = ax5; + r->x[6] = ax6; + r->x[7] = ax7; + r->x[8] = ax8; + r->x[9] = ax9; + r->x[10]= ax10; + + r->y[0] = ay0; + r->y[1] = ay1; + r->y[2] = ay2; + r->y[3] = ay3; + r->y[4] = ay4; + r->y[5] = ay5; + r->y[6] = ay6; + r->y[7] = ay7; + r->y[8] = ay8; + r->y[9] = ay9; + r->y[10]= ay10; +} + +void MB_FUNC_NAME(ifma_ec_nistp521_mul_pointbase_)(P521_POINT* r, const U64 scalar[]) +{ + /* pre-computed table of base powers */ + SINGLE_P521_POINT_AFFINE* tbl = &ifma_ec_nistp521_bp_precomp[0][0]; + + P521_POINT R; + P521_POINT_AFFINE A; + U64 Ty[P521_LEN52]; + + /* R = O */ + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + + /* + // base point (RL) multiplication + */ + U64 wvalue, dvalue; + __mb_mask dsign; + + U64 idx_mask = set1( (1<<(BP_WIN_SIZE+1))-1 ); + int bit = 0; + + /* first window - window[0] */ + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_p521_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FE521_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_nistp521_add_point_affine_)(&R, &R, &A); + + int chunk_no; + int chunk_shift; + for(bit+=BP_WIN_SIZE; bit<=P521_BITSIZE; bit+=BP_WIN_SIZE) { + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_p521_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FE521_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_nistp521_add_point_affine_)(&R, &R, &A); + } + + /* r = R */ + MB_FUNC_NAME(mov_FE521_)(r->X, R.X); + MB_FUNC_NAME(mov_FE521_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FE521_)(r->Z, R.Z); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef BP_WIN_SIZE + + +/* P521 parameters: mont(a), mont(b) */ +__ALIGN64 int64u mont_a_p521_mb[P521_LEN52][8] = { + { REP8_DECL(0x0007ffffffffffff) }, + { REP8_DECL(0x000ffffffffffffe) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0000000000000001) } +}; +__ALIGN64 int64u mont_b_p521_mb[P521_LEN52][8] = { + { REP8_DECL(0x00014654fae58638) }, + { REP8_DECL(0x00028fea35a81f80) }, + { REP8_DECL(0x000c41e961a78f7a) }, + { REP8_DECL(0x000dd8df839ab9ef) }, + { REP8_DECL(0x00049bd8b29605e9) }, + { REP8_DECL(0x0000ab0c9ca8f63f) }, + { REP8_DECL(0x0005a44c8c77884f) }, + { REP8_DECL(0x00092dccd98af9dc) }, + { REP8_DECL(0x0005b42a077516d3) }, + { REP8_DECL(0x000e4d0fc94d10d0) }, + { REP8_DECL(0x0000000000000000) } +}; + +/* +// We have a curve defined by a Weierstrass equation: y^2 = x^3 + a*x + b. +// +// The points are considered in Jacobian projective coordinates +// where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). +// Substituting this and multiplying by Z^6 transforms the above equation into +// Y^2 = X^3 + a*X*Z^4 + b*Z^6 +// To test this, we add up the right-hand side in 'rh'. +*/ +__mb_mask MB_FUNC_NAME(ifma_is_on_curve_p521_)(const P521_POINT* p, int use_jproj_coords) +{ + U64 rh[P521_LEN52]; + U64 Z4[P521_LEN52], Z6[P521_LEN52], tmp[P521_LEN52]; + + /* rh := X^2 */ + MB_FUNC_NAME(ifma_ams52_p521_)(rh, p->X); + + /* if Z!=1, then rh = X^3 + a*X*Z^4 + b*Z^6 = X*(X^2 + a*X*Z^4) + b*Z^6 */ + if(use_jproj_coords) { + MB_FUNC_NAME(ifma_ams52_p521_)(tmp, p->Z); /* tmp = Z^2 */ + MB_FUNC_NAME(ifma_ams52_p521_)(Z4, tmp); /* Z4 = Z^4 */ + MB_FUNC_NAME(ifma_amm52_p521_)(Z6, Z4, tmp); /* Z6 = Z^6 */ + + MB_FUNC_NAME(ifma_add52_p521_)(tmp, Z4, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_add52_p521_)(tmp, tmp, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_sub52_p521_)(rh, rh, tmp); /* rh = X^2 + a*Z^4 */ + MB_FUNC_NAME(ifma_amm52_p521_)(rh, rh, p->X); /* rh = (X^2 + a*Z^4)*X */ + + MB_FUNC_NAME(ifma_amm52_p521_)(tmp, Z6, (U64*)mont_b_p521_mb); + MB_FUNC_NAME(ifma_add52_p521_)(rh, rh, tmp); /* rh = (X^2 + a*Z^4)*X + b*Z^6 */ + } + /* if Z==1, then rh = X^3 + a*X + b = X*(X^2 +a) b */ + else { + MB_FUNC_NAME(ifma_add52_p521_)(rh, rh, (U64*)mont_a_p521_mb); /* rh = X^2+a */ + MB_FUNC_NAME(ifma_amm52_p521_)(rh, rh, p->X); /* rh = (X^2+a)*X */ + MB_FUNC_NAME(ifma_add52_p521_)(rh, rh, (U64*)mont_b_p521_mb); /* rh = (X^2+a)*X + b */ + } + MB_FUNC_NAME(ifma_frommont52_p521_)(rh, rh); + + /* rl = tmp = Y^2 */ + MB_FUNC_NAME(ifma_ams52_p521_)(tmp, p->Y); + MB_FUNC_NAME(ifma_frommont52_p521_)(tmp, tmp); + + /* mask = rl==rh */ + __mb_mask is_on_curve_mask = MB_FUNC_NAME(cmp_eq_FE521_)(tmp, rh); + + return is_on_curve_mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p256.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p256.c new file mode 100644 index 000000000..64f1055fb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p256.c @@ -0,0 +1,213 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates (or NULL, if affine coordinate requested) +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key depends on pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates if pa_pubz[] != NULL +// or +// - in (x:y) affine coordinate if pa_pubz[] == NULL +*/ +DLL_PUBLIC +mbx_status mbx_nistp256_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + BIGNUM* out_x = pa_pubx[buf_no]; + BIGNUM* out_y = pa_puby[buf_no]; + BIGNUM* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const BIGNUM* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[P256_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])scalarz, pa_skey, P256_BITSIZE); + scalarz[P256_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, P256_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + P256_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_nistp256_mul_pointbase_)(&P, scalarz); + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_nistp256_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p256_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_p256_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_p256_)(P.Z, P.Z); + + /* convert public key and store BIGNUM result */ + int8u tmp[8][NUMBER_OF_DIGITS(P256_BITSIZE,8)]; + int8u* const pa_tmp[8] = {tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5],tmp[6],tmp[7]}; + + /* X */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.X, P256_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P256_BITSIZE,8), pa_pubx[buf_no]); + } + + /* Y */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Y, P256_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P256_BITSIZE,8), pa_puby[buf_no]); + } + + /* Z */ + if(use_jproj_coords) { + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Z, P256_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P256_BITSIZE,8), pa_pubz[buf_no]); + } + } + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_nistp256_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* out_x = pa_pubx[buf_no]; + int64u* out_y = pa_puby[buf_no]; + int64u* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const int64u* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[P256_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalarz, pa_skey, P256_BITSIZE); + scalarz[P256_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, P256_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + P256_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_nistp256_mul_pointbase_)(&P, scalarz); + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_nistp256_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p256_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_p256_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_p256_)(P.Z, P.Z); + + /* store result */ + ifma_mb8_to_BNU(pa_pubx, (const int64u (*)[8])P.X, P256_BITSIZE); + ifma_mb8_to_BNU(pa_puby, (const int64u (*)[8])P.Y, P256_BITSIZE); + if(use_jproj_coords) + ifma_mb8_to_BNU(pa_pubz, (const int64u (*)[8])P.Z, P256_BITSIZE); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p384.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p384.c new file mode 100644 index 000000000..c51d194ae --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p384.c @@ -0,0 +1,213 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates (or NULL, if affine coordinate requested) +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key depends on pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates if pa_pubz[] != NULL +// or +// - in (x:y) affine coordinate if pa_pubz[] == NULL +*/ +DLL_PUBLIC +mbx_status mbx_nistp384_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + BIGNUM* out_x = pa_pubx[buf_no]; + BIGNUM* out_y = pa_puby[buf_no]; + BIGNUM* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const BIGNUM* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[P384_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])scalarz, pa_skey, P384_BITSIZE); + scalarz[P384_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, P384_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + P384_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_nistp384_mul_pointbase_)(&P, scalarz); + /* clear copy of secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_nistp384_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p384_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_p384_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_p384_)(P.Z, P.Z); + + /* convert public key and store BIGNUM result */ + int8u tmp[8][NUMBER_OF_DIGITS(P384_BITSIZE,8)]; + int8u* const pa_tmp[8] = {tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5],tmp[6],tmp[7]}; + + /* X */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.X, P384_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P384_BITSIZE,8), pa_pubx[buf_no]); + } + + /* Y */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Y, P384_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P384_BITSIZE,8), pa_puby[buf_no]); + } + + /* Z */ + if(use_jproj_coords) { + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Z, P384_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P384_BITSIZE,8), pa_pubz[buf_no]); + } + } + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_nistp384_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* out_x = pa_pubx[buf_no]; + int64u* out_y = pa_puby[buf_no]; + int64u* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const int64u* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[P384_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalarz, pa_skey, P384_BITSIZE); + scalarz[P384_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, P384_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + P384_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_nistp384_mul_pointbase_)(&P, scalarz); + /* clear copy of secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_nistp384_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p384_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_p384_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_p384_)(P.Z, P.Z); + + /* store result */ + ifma_mb8_to_BNU(pa_pubx, (const int64u (*)[8])P.X, P384_BITSIZE); + ifma_mb8_to_BNU(pa_puby, (const int64u (*)[8])P.Y, P384_BITSIZE); + if(use_jproj_coords) + ifma_mb8_to_BNU(pa_pubz, (const int64u (*)[8])P.Z, P384_BITSIZE); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p521.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p521.c new file mode 100644 index 000000000..7df5bb44f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ecnist/ifma_ecpubkey_p521.c @@ -0,0 +1,213 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates (or NULL, if affine coordinate requested) +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key depends on pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates if pa_pubz[] != NULL +// or +// - in (x:y) affine coordinate if pa_pubz[] == NULL +*/ +DLL_PUBLIC +mbx_status mbx_nistp521_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + BIGNUM* out_x = pa_pubx[buf_no]; + BIGNUM* out_y = pa_puby[buf_no]; + BIGNUM* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const BIGNUM* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[P521_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])scalarz, pa_skey, P521_BITSIZE); + scalarz[P521_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, P521_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + P521_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_nistp521_mul_pointbase_)(&P, scalarz); + /* clear copy of secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_nistp521_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p521_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_p521_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_p521_)(P.Z, P.Z); + + /* convert public key and store BIGNUM result */ + int8u tmp[8][NUMBER_OF_DIGITS(P521_BITSIZE,8)]; + int8u* const pa_tmp[8] = {tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5],tmp[6],tmp[7]}; + + /* X */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.X, P521_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P521_BITSIZE,8), pa_pubx[buf_no]); + } + + /* Y */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Y, P521_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P521_BITSIZE,8), pa_puby[buf_no]); + } + + /* Z */ + if(use_jproj_coords) { + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Z, P521_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], NUMBER_OF_DIGITS(P521_BITSIZE,8), pa_pubz[buf_no]); + } + } + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_nistp521_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* out_x = pa_pubx[buf_no]; + int64u* out_y = pa_puby[buf_no]; + int64u* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const int64u* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[P521_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalarz, pa_skey, P521_BITSIZE); + scalarz[P521_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, P521_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + P521_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_nistp521_mul_pointbase_)(&P, scalarz); + /* clear copy of secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_nistp521_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_p521_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_p521_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_p521_)(P.Z, P.Z); + + /* store result */ + ifma_mb8_to_BNU(pa_pubx, (const int64u (*)[8])P.X, P521_BITSIZE); + ifma_mb8_to_BNU(pa_puby, (const int64u (*)[8])P.Y, P521_BITSIZE); + if(use_jproj_coords) + ifma_mb8_to_BNU(pa_pubz, (const int64u (*)[8])P.Z, P521_BITSIZE); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_ed25519.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_ed25519.c new file mode 100644 index 000000000..5d0ac4833 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_ed25519.c @@ -0,0 +1,540 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include +#include + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE /* defined in the header above */ + +/* +// Twisted Edwards Curve parameters +*/ + +/* d = -(121665/121666) */ +__ALIGN64 static const int64u ed25519_d[FE_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x000b4dca135978a3) }, + { REP8_DECL(0x0004d4141d8ab75e) }, + { REP8_DECL(0x000779e89800700a) }, + { REP8_DECL(0x000fe738cc740797) }, + { REP8_DECL(0x000052036cee2b6f) } +}; + +/* (2*d) */ +__ALIGN64 static const int64u ed25519_d2[FE_LEN52][sizeof(U64) / sizeof(int64u)] = { + { REP8_DECL(0x00069b9426b2f159) }, + { REP8_DECL(0x0009a8283b156ebd) }, + { REP8_DECL(0x000ef3d13000e014) }, + { REP8_DECL(0x000fce7198e80f2e) }, + { REP8_DECL(0x00002406d9dc56df) } +}; + +/* 2^((p-1)/4) = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0 */ +__ALIGN64 static const int64u ed25519_2_pm1_4[FE_LEN52][sizeof(U64) / sizeof(int64u)] = { + { REP8_DECL(0x000e1b274a0ea0b0) }, + { REP8_DECL(0x00006ad2fe478c4e) }, + { REP8_DECL(0x000dfbd7a72f4318) }, + { REP8_DECL(0x000df0b2b4d00993) }, + { REP8_DECL(0x00002b8324804fc1) } +}; + +/* ext => cached */ +__INLINE void ge_ext_to_cached_mb(ge52_cached_mb *r, const ge52_ext_mb* p) +{ + fe52_add(r->YaddX, p->Y, p->X); + fe52_sub(r->YsubX, p->Y, p->X); + fe52_copy_mb(r->Z, p->Z); + fe52_mul(r->T2d, p->T, (U64*)ed25519_d2); +} + +/* +// r = p + q +*/ +static void ge52_add_precomp(ge52_p1p1_mb *r, const ge52_ext_mb *p, const ge52_precomp_mb *q) +{ + fe52_mb t0; + + fe52_add(r->X, p->Y, p->X); // X3 = Y1+X1 + fe52_sub(r->Y, p->Y, p->X); // Y3 = Y1-X1 + fe52_mul(r->Z, r->X, q->yaddx); // Z3 = X3*yplusx2 + fe52_mul(r->Y, r->Y, q->ysubx); // Y3 = Y3*yminisx2 + fe52_mul(r->T, q->t2d, p->T); // T3 = T1*xy2d2 + fe52_add(t0, p->Z, p->Z); // t0 = Z1+Z1 + fe52_sub(r->X, r->Z, r->Y); // X3 = Z3-Y3 = X3*yplusx2 - Y3*yminisx2 = (Y1+X1)*yplusx2 - (Y1-X1)*yminisx2 + fe52_add(r->Y, r->Z, r->Y); // Y3 = Z3+Y3 = X3*yplusx2 + Y3*yminisx2 = (Y1+X1)*yplusx2 + (Y1-X1)*yminisx2 + fe52_add(r->Z, t0, r->T); // Z3 = 2*Z1 + T1*xy2d2 + fe52_sub(r->T, t0, r->T); // T3 = 2*Z1 - T1*xy2d2 +} + +static void ge_add(ge52_p1p1_mb* r, const ge52_ext_mb* p, const ge52_cached_mb* q) +{ + fe52_mb t0; + + fe52_add(r->X, p->Y, p->X); + fe52_sub(r->Y, p->Y, p->X); + fe52_mul(r->Z, r->X, q->YaddX); + fe52_mul(r->Y, r->Y, q->YsubX); + fe52_mul(r->T, q->T2d, p->T); + fe52_mul(r->X, p->Z, q->Z); + fe52_add(t0, r->X, r->X); + fe52_sub(r->X, r->Z, r->Y); + fe52_add(r->Y, r->Z, r->Y); + fe52_add(r->Z, t0, r->T); + fe52_sub(r->T, t0, r->T); +} + +/* r = 2 * p */ +static void ge_dbl(ge52_p1p1_mb *r, const ge52_homo_mb* p) +{ + fe52_mb t0; + + fe52_sqr(r->X, p->X); + fe52_sqr(r->Z, p->Y); + fe52_sqr(r->T, p->Z); + fe52_add(r->T, r->T, r->T); + fe52_add(r->Y, p->X, p->Y); + fe52_sqr(t0, r->Y); + fe52_add(r->Y, r->Z, r->X); + fe52_sub(r->Z, r->Z, r->X); + fe52_sub(r->X, t0, r->Y); + fe52_sub(r->T, r->T, r->Z); +} + + +#define PARITY_SLOT ((GE25519_COMP_BITSIZE-1)/DIGIT_SIZE) +#define PARITY_BIT (1LL << ((GE25519_COMP_BITSIZE - 1) % DIGIT_SIZE)) + +#define SIGN_FE52(fe) srli64((fe)[PARITY_SLOT], ((GE25519_COMP_BITSIZE - 1) % DIGIT_SIZE)) +#define PARITY_FE52(fe) and64_const((fe)[0], 1) + +/* compress point */ +void ge52_ext_compress(fe52_mb r, const ge52_ext_mb* p) +{ + fe52_mb recip; + fe52_mb x; + fe52_mb y; + + fe52_inv(recip, p->Z); + fe52_mul(x, p->X, recip); + fe52_mul(y, p->Y, recip); + fe52_red(x, x); + fe52_red(y, y); + + __mb_mask is_negative = cmp64_mask(and64_const(x[0], 1), set1(1), _MM_CMPINT_EQ); + y[(GE25519_COMP_BITSIZE-1)/DIGIT_SIZE] = _mm512_mask_or_epi64(y[(GE25519_COMP_BITSIZE-1)/DIGIT_SIZE], is_negative, y[(GE25519_COMP_BITSIZE - 1) / DIGIT_SIZE], set1(1LL << (GE25519_COMP_BITSIZE-1)%DIGIT_SIZE)); + + fe52_copy_mb(r, y); +} + +/* decompress point */ +__mb_mask ge52_ext_decompress(ge52_ext_mb* r, const fe52_mb compressed_point) +{ + fe52_mb x; + fe52_mb y; + + fe52_mb u; + fe52_mb v; + fe52_mb v3; + fe52_mb vxx; + + /* inital values are neutral */ + neutral_ge52_ext_mb(r); + + /* y = fe and clear "x-sign" bit */ + fe52_copy_mb(y, compressed_point); + y[FE_LEN52-1] = and64_const(y[FE_LEN52-1], PRIME25519_HI); + + /* x^2 = (y^2 -1) / (d y^2 +1) = u/v. compute numerator (u) and denumerator (v) */ + fe52_sqr(u, y); + fe52_mul(v, u, (U64*)ed25519_d); + fe52_sub(u, u, r->Z); /* u = y^2-1 */ + fe52_add(v, v, r->Z); /* v = dy^2+1 */ + + /* + // compute candidate x = sqrt(u/v) = uv^3(uv^7)^((p-5)/8) + */ + fe52_sqr(v3, v); + fe52_mul(v3, v3, v); /* v3 = v^3 */ + fe52_sqr(x, v3); + fe52_mul(x, x, v); + fe52_mul(x, x, u); /* x = uv^7 */ + + fe52_p2_252m3(x, x); /* x = (uv^7)^((p-5)/8) */ + fe52_mul(x, x, v3); + fe52_mul(x, x, u); /* x = uv^3(uv^7)^((p-5)/8) */ + + fe52_sqr(vxx, x); + fe52_mul(vxx, vxx, v); /* vxx = v*x^2 */ + + /* case 1: check if v*x^2 == u */ + fe52_sub(v3, vxx, u); /* v*x^2-u */ + __mb_mask k1 = fe52_mb_is_zero(v3); + fe52_cmov_mb(r->X, r->X, k1, x); + + /* case 2: check if v*x^2 == -u */ + fe52_add(v3, vxx, u); + __mb_mask k2 = fe52_mb_is_zero(v3); + fe52_mul(x, x, (U64*)ed25519_2_pm1_4); + fe52_cmov_mb(r->X, r->X, k2, x); + + /* copy y coordinate*/ + __mb_mask k = k1|k2; + fe52_cmov_mb(r->Y, r->Y, k, y); + + /* set x to (-x) if x.parity different with compressed_point.sign */ + k1 = cmp64_mask(SIGN_FE52(compressed_point), PARITY_FE52(r->X), _MM_CMPINT_NE); + fe52_neg(v3, r->X); + fe52_cmov_mb(r->X, r->X, k1, v3); + + /* update T compomemt */ + fe52_mul(r->T, r->X, r->Y); + + return k; +} + + +/* select from the pre-computed table */ +static void extract_precomputed_basepoint_dual(ge52_precomp_mb* p0, + ge52_precomp_mb* p1, + const ge52_precomp* tbl, + U64 idx0, U64 idx1) +{ + /* set h0, h1 to neutral point */ + neutral_ge52_precomp_mb(p0); + neutral_ge52_precomp_mb(p1); + + /* indexes are considered as signed values */ + __mb_mask is_neg_idx0 = cmp64_mask(idx0, get_zero64(), _MM_CMPINT_LT); + __mb_mask is_neg_idx1 = cmp64_mask(idx1, get_zero64(), _MM_CMPINT_LT); + idx0 = mask_sub64(idx0, is_neg_idx0, get_zero64(), idx0); + idx1 = mask_sub64(idx1, is_neg_idx1, get_zero64(), idx1); + + /* select p0, p1 wrt idx0, idx1 indexes */ + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(1), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(1), _MM_CMPINT_EQ), tbl); + tbl++; + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(2), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(2), _MM_CMPINT_EQ), tbl); + tbl++; + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(3), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(3), _MM_CMPINT_EQ), tbl); + tbl++; + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(4), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(4), _MM_CMPINT_EQ), tbl); + tbl++; + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(5), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(5), _MM_CMPINT_EQ), tbl); + tbl++; + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(6), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(6), _MM_CMPINT_EQ), tbl); + tbl++; + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(7), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(7), _MM_CMPINT_EQ), tbl); + tbl++; + ge52_cmov1_precomp_mb(p0, p0, cmp64_mask(idx0, set1(8), _MM_CMPINT_EQ), tbl); + ge52_cmov1_precomp_mb(p1, p1, cmp64_mask(idx1, set1(8), _MM_CMPINT_EQ), tbl); + + /* adjust for sign */ + fe52_mb neg; + fe52_neg(neg, p0->t2d); + fe52_cswap_mb(p0->ysubx, is_neg_idx0, p0->yaddx); + fe52_cmov_mb(p0->t2d, p0->t2d, is_neg_idx0, neg); + + fe52_neg(neg, p1->t2d); + fe52_cswap_mb(p1->ysubx, is_neg_idx1, p1->yaddx); + fe52_cmov_mb(p1->t2d, p1->t2d, is_neg_idx1, neg); +} + +/* +// r = [s]*G +// +// where s = s[0] + 256*s[1] +...+ 256^31*s[31] +// G is the Ed25519 base point (x,4/5) with x positive. +// +// Preconditions: +// s[31] <= 127 +*/ + +/* if msb set */ +__INLINE int32u isMsb_ct(int32u a) +{ return (int32u)0 - (a >> (sizeof(a) * 8 - 1)); } + +/* tests if a==0 */ +__INLINE int32u isZero(int32u a) +{ return isMsb_ct(~a & (a - 1)); } + +/* tests if a==b */ +__INLINE int32u isEqu(int32u a, int32u b) +{ return isZero(a ^ b); } + +void ifma_ed25519_mul_basepoint(ge52_ext_mb* r, const U64 scalar[]) +{ + /* implementation uses scalar representation over base b=16, q[i] are half-bytes */ + __ALIGN64 ge52_ext_mb r0; /* q[0]*16^0 + q[2]*16^2 + q[4]*16^4 + ...+ q[30]*16^30 */ + __ALIGN64 ge52_ext_mb r1; /* q[1]*16^1 + q[3]*16^3 + q[5]*16^5 + ...+ q[31]*16^31 */ + + /* point extracted from the pre-computed table */ + __ALIGN64 ge52_precomp_mb h0; + __ALIGN64 ge52_precomp_mb h1; + + /* temporary */ + __ALIGN64 ge52_p1p1_mb t; + __ALIGN64 ge52_homo_mb s; + + /* inital values are nuetral */ + neutral_ge52_ext_mb(&r0); + neutral_ge52_ext_mb(&r1); + + /* pre-computed basepoint table */ + ge52_precomp* tbl = &ifma_ed25519_bp_precomp[0][0]; + + __mb_mask carry = 0; /* used in convertion to signed value */ + + for(int n=0; n< FE_LEN64; n++) { + /* scalar value*/ + U64 scalarV = loadu64(&scalar[n]); + + for(int m=0; m> ws) - 1)); //sign + d = (1 << (ws+1)) - wvalue - 1; // digit, win size "ws" + d = (d & s) | (wvaluen & ~s); + d = (d >> 1) + (d & 1); + *sign = s & 1; + *digit = (Ipp8u)d; +*/ +__INLINE void booth_recode(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64(sub64(set1(1 << (WIN_SIZE + 1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64(srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract point */ +static void extract_cached_point(ge52_cached_mb* r, const ge52_cached_mb tbl[], U64 idx, __mb_mask sign) +{ + /* decrement index (the table does not contain neutral element) */ + U64 idx_target = sub64(idx, set1(1)); + + neutral_ge52_cached_mb(r); + + /* find out what we actually need or just keep neutral */ + int32u n; + for(n=0; n<(1<<(WIN_SIZE-1)); n++) { + U64 idx_curr = set1(n); + __mb_mask k = cmp64_mask(idx_curr, idx_target, _MM_CMPINT_EQ); + /* r = k? tbl[] : r */ + cmov_ge52_cached_mb(r, r, k, &tbl[n]); + } + + /* adjust for sign */ + fe52_mb neg; + fe52_neg(neg, r->T2d); + fe52_cswap_mb(r->YsubX, sign, r->YaddX); + fe52_cmov_mb(r->T2d, r->T2d, sign, neg); +} + +/* +// r = [s]*P +// +// where s = s[0] + 256*s[1] +...+ 256^31*s[31] +// P is an arbitrary Ed25519 point. +*/ +void ifma_ed25519_mul_point(ge52_ext_mb* r, const ge52_ext_mb* p, const U64 scalar[]) +{ + __ALIGN64 ge52_p1p1_mb p1p1; + __ALIGN64 ge52_homo_mb homo; + __ALIGN64 ge52_cached_mb cached; + __ALIGN64 ge52_ext_mb ext; + + /* generate the table tbl[] = {p, [2]p, [3]p, [4]p, [5]p, [6]p, [7]p, [8]p} */ + __ALIGN64 ge52_cached_mb tbl[1 << (WIN_SIZE-1)]; + int n; + ge_ext_to_cached_mb(&tbl[0], p); /* tbl[0] = p */ + for(n=1; n<(1 << (WIN_SIZE-1)); n++) { + ge_add(&p1p1, p, &tbl[n-1]); /* tbl[n] = p + tbl[n-1] */ + ge52_p1p1_to_ext_mb(&ext, &p1p1); + ge_ext_to_cached_mb(&tbl[n], &ext); + } + + /* ext = neutral */ + neutral_ge52_ext_mb(&ext); + + /* + // point (LR) multiplication, 256-bit scalar + */ + U64 idx_mask = set1((1 << (WIN_SIZE + 1)) - 1); + int bit = SCALAR_BITSIZE - (SCALAR_BITSIZE% WIN_SIZE); + int chunk_no = (bit - 1) / 64; + int chunk_shift = (bit - 1) % 64; + + U64 dvalue; /* digit value */ + __mb_mask dsign; /* digit sign */ + + /* + // first window + */ + U64 wvalue = loadu64(&scalar[chunk_no]); + wvalue = and64(srli64(wvalue, chunk_shift), idx_mask); + + booth_recode(&dsign, &dvalue, wvalue); + extract_cached_point(&cached, tbl, dvalue, dsign); + + /* ext = cached */ + ge_add(&p1p1, &ext, &cached); + ge52_p1p1_to_ext_mb(&ext, &p1p1); + + /* + // other windows + */ + for(bit-=WIN_SIZE; bit>=WIN_SIZE; bit-=WIN_SIZE) { + /* 4-x doubling: ext = [16]ext */ + ge52_ext_to_homo_mb(&homo, &ext); + + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_homo_mb(&homo, &p1p1); + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_homo_mb(&homo, &p1p1); + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_homo_mb(&homo, &p1p1); + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_ext_mb(&ext, &p1p1); + + /* extract precomputed []P */ + chunk_no = (bit - 1) / 64; + chunk_shift = (bit - 1) % 64; + + wvalue = loadu64(&scalar[chunk_no]); + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no + 1]), set1((int32u)chunk_shift)); + wvalue = and64(wvalue, idx_mask); + + booth_recode(&dsign, &dvalue, wvalue); + extract_cached_point(&cached, tbl, dvalue, dsign); + + /* acumulate ext += cached */ + ge_add(&p1p1, &ext, &cached); + ge52_p1p1_to_ext_mb(&ext, &p1p1); + } + + /* + // last window + */ + ge52_ext_to_homo_mb(&homo, &ext); + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_homo_mb(&homo, &p1p1); + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_homo_mb(&homo, &p1p1); + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_homo_mb(&homo, &p1p1); + ge_dbl(&p1p1, &homo); + ge52_p1p1_to_ext_mb(&ext, &p1p1); + + /* extract precomputed []P */ + wvalue = loadu64(&scalar[0]); + wvalue = and64(slli64(wvalue, 1), idx_mask); + booth_recode(&dsign, &dvalue, wvalue); + extract_cached_point(&cached, tbl, dvalue, dsign); + + /* acumulate ext += cached */ + ge_add(&p1p1, &ext, &cached); + ge52_p1p1_to_ext_mb(r, &p1p1); +} +#undef SCALAR_BITSIZE +#undef WIN_SIZE + +/* R = [p]P + [g]G */ +void ifma_ed25519_prod_point(ge52_ext_mb* r, const ge52_ext_mb* p, const U64 scalarP[], const U64 scalarG[]) +{ + __ALIGN64 ge52_ext_mb T_mb; + ifma_ed25519_mul_point(r, p, scalarP); + ifma_ed25519_mul_basepoint(&T_mb, scalarG); + + __ALIGN64 ge52_cached_mb c; + __ALIGN64 ge52_p1p1_mb t; + ge_ext_to_cached_mb(&c, &T_mb); + ge_add(&t, r, &c); + ge52_p1p1_to_ext_mb(r, &t); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_n25519.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_n25519.c new file mode 100644 index 000000000..86dea332a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_n25519.c @@ -0,0 +1,390 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include + +/* +// ED25519 prime base point order +// n = 2^252+27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED +// in 2^52 radix +*/ +__ALIGN64 static const int64u ed25519n_mb[NE_LEN52][sizeof(U64) / sizeof(int64u)] = { + { REP8_DECL(0x0002631A5CF5D3ED) }, + { REP8_DECL(0x000DEA2F79CD6581) }, + { REP8_DECL(0x000000000014DEF9) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000100000000000) } +}; + +/* mu = floor( 2^2*DIGIT_SIZE/n) = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB2106215D086329A7ED9CE5A30A2C131B39 */ +__ALIGN64 static const int64u ed25519mu_mb[NE_LEN52+1][sizeof(U64) / sizeof(int64u)] = { + { REP8_DECL(0x0005A30A2C131B39) }, + { REP8_DECL(0x000086329A7ED9CE) }, + { REP8_DECL(0x000FFFEB2106215D) }, + { REP8_DECL(0x000FFFFFFFFFFFFF) }, + { REP8_DECL(0x000FFFFFFFFFFFFF) }, + { REP8_DECL(0x00000000000000FF) } +}; + +#define ROUND_MUL(R_LO, R_HI, A_I, B_J) \ + (R_LO) = fma52lo((R_LO), (A_I), (B_J)); \ + (R_HI) = fma52hi((R_HI), (A_I), (B_J)); + +__ALIGN64 static const int64u VBASE52[sizeof(U64)/sizeof(int64u)] = { + REP8_DECL(DIGIT_BASE) +}; + +__ALIGN64 static const int64u VMASK52[sizeof(U64)/sizeof(int64u)] = { + REP8_DECL(DIGIT_MASK) +}; + + +#define NORM_LSHIFTR(LO, HI) \ + (HI) = add64((HI), srli64((LO), DIGIT_SIZE)); \ + (LO) = and64((LO), loadu64(VMASK52)); + + +void ifma52_sub_with_borrow(U64 r[], const U64 x[], const U64 y[]) +{ + U64 base = loadu64(VBASE52); + U64 one = set1(1LL); + + U64 subtrahend = get_zero64(); + __mmask8 lt = 0; + + subtrahend = _mm512_mask_add_epi64(y[0], lt, y[0], one); + lt = _mm512_cmp_epu64_mask(x[0], subtrahend, _MM_CMPINT_LT); + r[0] = _mm512_sub_epi64(x[0], subtrahend); + r[0] = _mm512_mask_add_epi64(r[0], lt, r[0], base); + + subtrahend = _mm512_mask_add_epi64(y[1], lt, y[1], one); + lt = _mm512_cmp_epu64_mask(x[1], subtrahend, _MM_CMPINT_LT); + r[1] = _mm512_sub_epi64(x[1], subtrahend); + r[1] = _mm512_mask_add_epi64(r[1], lt, r[1], base); + + subtrahend = _mm512_mask_add_epi64(y[2], lt, y[2], one); + lt = _mm512_cmp_epu64_mask(x[2], subtrahend, _MM_CMPINT_LT); + r[2] = _mm512_sub_epi64(x[2], subtrahend); + r[2] = _mm512_mask_add_epi64(r[2], lt, r[2], base); + + subtrahend = _mm512_mask_add_epi64(y[3], lt, y[3], one); + lt = _mm512_cmp_epu64_mask(x[3], subtrahend, _MM_CMPINT_LT); + r[3] = _mm512_sub_epi64(x[3], subtrahend); + r[3] = _mm512_mask_add_epi64(r[3], lt, r[3], base); + + subtrahend = _mm512_mask_add_epi64(y[4], lt, y[4], one); + lt = _mm512_cmp_epu64_mask(x[4], subtrahend, _MM_CMPINT_LT); + r[4] = _mm512_sub_epi64(x[4], subtrahend); + r[4] = _mm512_mask_add_epi64(r[4], lt, r[4], base); + + /* the latest step is not necessary, bcause Barett algorithms guarantee that + // 0<= (r = r1-r2) <3*modulus + // r[0..4] is enough to keep 3*modulus + */ + #if 0 + subtrahend = _mm512_mask_add_epi64(y[5], lt, y[5], one); + lt = _mm512_cmp_epu64_mask(x[5], subtrahend, _MM_CMPINT_LT); + r[5] = _mm512_sub_epi64(x[5], subtrahend); + r[5] = _mm512_mask_add_epi64(r[5], lt, r[4], base); + #endif +} + +// r = x>DITIT_SIZE*(K+1) +// +// 4. r1 = x mod b^(k+1) +// 5. r2 = q3*n mod b^(k+1) +// 6. r = r1-r2, if r<0 then r+=b^(k+1) +// 7. if r>n then r -=n -- at most 2 final reductions +// r>n then r -=n +*/ +void ifma52_ed25519n_reduce(U64 r[NE_LEN52], const U64 x[NE_LEN52*2]) +{ + /* 1. q1 = x/b^(k-1) -- just (k+1) most significant digits, len(q1) = 2*k - (k-1) = k+1 */ + const U64* q1 = x + (NE_LEN52-1); + + /* + // 2. q2 = q1*mu, len(q2) = (k+1) + (k+1) = 2*k+2 + // 3. q3 = floor(q2 / b^(k+1)), len(q3) = 2*k+2 - (k+1) = k+1 + // => no necessary do compute whole (q1*mu) product, (k+1) most significant digits are enough + // + // code below represents full multiplication + // from which discarded (commented out) computation of the least significant digits + */ + U64* mu = (U64*)ed25519mu_mb; + U64 /*q3_0, q3_1, q3_2, q3_3, q3_4, */ q3_5, q3_6, q3_7, q3_8, q3_9, q3_10, q3_11; + /*q3_0= q3_1= q3_2= q3_3= q3_4= */ q3_5 = q3_6 = q3_7 = q3_8 = q3_9 = q3_10 = q3_11 = get_zero64(); + + //ROUND_MUL(q3_0, q3_1, q1[0], mu[0]); + + //ROUND_MUL(q3_1, q3_2, q1[0], mu[1]); + //ROUND_MUL(q3_1, q3_2, q1[1], mu[0]); + + //ROUND_MUL(q3_2, q3_3, q1[0], mu[2]); + //ROUND_MUL(q3_2, q3_3, q1[1], mu[1]); + //ROUND_MUL(q3_2, q3_3, q1[2], mu[0]); + + //ROUND_MUL(q3_3, q3_4, q1[0], mu[3]); + //ROUND_MUL(q3_3, q3_4, q1[1], mu[2]); + //ROUND_MUL(q3_3, q3_4, q1[2], mu[1]); + //ROUND_MUL(q3_3, q3_4, q1[3], mu[0]); + + //ROUND_MUL(q3_4, q3_5, q1[0], mu[4]); + //ROUND_MUL(q3_4, q3_5, q1[1], mu[3]); + //ROUND_MUL(q3_4, q3_5, q1[2], mu[2]); + //ROUND_MUL(q3_4, q3_5, q1[3], mu[1]); + //ROUND_MUL(q3_4, q3_5, q1[4], mu[0]); + q3_5 = fma52hi(q3_5, q1[0], mu[4]); + q3_5 = fma52hi(q3_5, q1[1], mu[3]); + q3_5 = fma52hi(q3_5, q1[2], mu[2]); + q3_5 = fma52hi(q3_5, q1[3], mu[1]); + q3_5 = fma52hi(q3_5, q1[4], mu[0]); + + ROUND_MUL(q3_5, q3_6, q1[0], mu[5]); + ROUND_MUL(q3_5, q3_6, q1[1], mu[4]); + ROUND_MUL(q3_5, q3_6, q1[2], mu[3]); + ROUND_MUL(q3_5, q3_6, q1[3], mu[2]); + ROUND_MUL(q3_5, q3_6, q1[4], mu[1]); + ROUND_MUL(q3_5, q3_6, q1[5], mu[0]); + + ROUND_MUL(q3_6, q3_7, q1[1], mu[5]); + ROUND_MUL(q3_6, q3_7, q1[2], mu[4]); + ROUND_MUL(q3_6, q3_7, q1[3], mu[3]); + ROUND_MUL(q3_6, q3_7, q1[4], mu[2]); + ROUND_MUL(q3_6, q3_7, q1[5], mu[1]); + + ROUND_MUL(q3_7, q3_8, q1[2], mu[5]); + ROUND_MUL(q3_7, q3_8, q1[3], mu[4]); + ROUND_MUL(q3_7, q3_8, q1[4], mu[3]); + ROUND_MUL(q3_7, q3_8, q1[5], mu[2]); + + ROUND_MUL(q3_8, q3_9, q1[3], mu[5]); + ROUND_MUL(q3_8, q3_9, q1[4], mu[4]); + ROUND_MUL(q3_8, q3_9, q1[5], mu[3]); + + ROUND_MUL(q3_9, q3_10, q1[4], mu[5]); + ROUND_MUL(q3_9, q3_10, q1[5], mu[4]); + + /* note, that the lates (2*k+2) digit will always be 0 (count bits presentation of x and mu) */ + ROUND_MUL(q3_10, q3_11, q1[5], mu[5]); + + /* normalization, q3 = {q3_11, q3_10, q3_9, q3_8, q3_7, q3_6}, note q3_11 is zero */ + NORM_LSHIFTR(q3_5, q3_6); + NORM_LSHIFTR(q3_6, q3_7); + NORM_LSHIFTR(q3_7, q3_8); + NORM_LSHIFTR(q3_8, q3_9); + NORM_LSHIFTR(q3_9, q3_10); + NORM_LSHIFTR(q3_10, q3_11); + + /* 4. r1 = x mod b^(k+1) is just (k+1) least significant digits of x */ + const U64* r1 = x; + + /* 5. r2 = (q3*n) mod b^(k+1) + // => no necessary do compute whole (q3*n) product, (k+1) least significant digits are enough + // + // code below represents full multiplication + // from which discarded (commented out) computation of the most significant digits + */ + U64* n = (U64*)ed25519n_mb; + U64 r2_0, r2_1, r2_2, r2_3, r2_4, r2_5; + r2_0 = r2_1 = r2_2 = r2_3 = r2_4 = r2_5 = q3_11 = get_zero64(); + + ROUND_MUL(r2_0, r2_1, q3_6, n[0]); + + ROUND_MUL(r2_1, r2_2, q3_6, n[1]); + ROUND_MUL(r2_1, r2_2, q3_7, n[0]); + + ROUND_MUL(r2_2, r2_3, q3_6, n[2]); + ROUND_MUL(r2_2, r2_3, q3_7, n[1]); + ROUND_MUL(r2_2, r2_3, q3_8, n[0]); + + ROUND_MUL(r2_3, r2_4, q3_6, n[3]); + ROUND_MUL(r2_3, r2_4, q3_7, n[2]); + ROUND_MUL(r2_3, r2_4, q3_8, n[1]); + ROUND_MUL(r2_3, r2_4, q3_9, n[0]); + + ROUND_MUL(r2_4, r2_5, q3_6, n[4]); + ROUND_MUL(r2_4, r2_5, q3_7, n[3]); + ROUND_MUL(r2_4, r2_5, q3_8, n[2]); + ROUND_MUL(r2_4, r2_5, q3_9, n[1]); + ROUND_MUL(r2_4, r2_5,q3_10, n[0]); + + r2_5 = fma52lo(r2_5, q3_7, n[4]); + r2_5 = fma52lo(r2_5, q3_8, n[3]); + r2_5 = fma52lo(r2_5, q3_9, n[2]); + r2_5 = fma52lo(r2_5,q3_10, n[1]); + r2_5 = fma52lo(r2_5,q3_11, n[0]); + + /* r2[6], r2[7], ... amd other most significal digits of full multiplication are discarded */ + //r2[6] = fma52hi(r2[5], q3_7, n[4]); + //r2[6] = fma52hi(r2[5], q3_8, n[3]); + //r2[6] = fma52hi(r2[5], q3_9, n[2]); + //r2[6] = fma52hi(r2[5],q3_10, n[1]); + //r2[6] = fma52hi(r2[5],q3_11, n[0]); + + /* normalization */ + NORM_LSHIFTR(r2_0, r2_1); + NORM_LSHIFTR(r2_1, r2_2); + NORM_LSHIFTR(r2_2, r2_3); + NORM_LSHIFTR(r2_3, r2_4); + NORM_LSHIFTR(r2_4, r2_5); + NORM_LSHIFTR(r2_5, q3_11); + /* note q3_11 is out of mod b^(k+1) */ + + U64 r2[NE_LEN52+1]; + r2[0] = r2_0; + r2[1] = r2_1; + r2[2] = r2_2; + r2[3] = r2_3; + r2[4] = r2_4; + r2[5] = r2_5; + + /* 6. r = r1-r2 */ + ifma52_sub_with_borrow(r, r1, r2); + + /* 7. reduce modulo twice */ + ifma52_sub_ed25519n(r, r); + ifma52_sub_ed25519n(r, r); +} + +// r = a*b+c %n +void ifma52_ed25519n_madd(U64 r[NE_LEN52], const U64 a[NE_LEN52], const U64 b[NE_LEN52], const U64 c[NE_LEN52]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + /* (a*b) */ + ROUND_MUL(r0, r1, a[0], b[0]); + ROUND_MUL(r1, r2, a[1], b[0]); + ROUND_MUL(r2, r3, a[2], b[0]); + ROUND_MUL(r3, r4, a[3], b[0]); + ROUND_MUL(r4, r5, a[4], b[0]); + + ROUND_MUL(r1, r2, a[0], b[1]); + ROUND_MUL(r2, r3, a[1], b[1]); + ROUND_MUL(r3, r4, a[2], b[1]); + ROUND_MUL(r4, r5, a[3], b[1]); + ROUND_MUL(r5, r6, a[4], b[1]); + + ROUND_MUL(r2, r3, a[0], b[2]); + ROUND_MUL(r3, r4, a[1], b[2]); + ROUND_MUL(r4, r5, a[2], b[2]); + ROUND_MUL(r5, r6, a[3], b[2]); + ROUND_MUL(r6, r7, a[4], b[2]); + + ROUND_MUL(r3, r4, a[0], b[3]); + ROUND_MUL(r4, r5, a[1], b[3]); + ROUND_MUL(r5, r6, a[2], b[3]); + ROUND_MUL(r6, r7, a[3], b[3]); + ROUND_MUL(r7, r8, a[4], b[3]); + + ROUND_MUL(r4, r5, a[0], b[4]); + ROUND_MUL(r5, r6, a[1], b[4]); + ROUND_MUL(r6, r7, a[2], b[4]); + ROUND_MUL(r7, r8, a[3], b[4]); + ROUND_MUL(r8, r9, a[4], b[4]); + + /* (a*b) + c */ + r0 = add64(r0, c[0]); + r1 = add64(r1, c[1]); + r2 = add64(r2, c[2]); + r3 = add64(r3, c[3]); + r4 = add64(r4, c[4]); + + /* normalize result */ + NORM_LSHIFTR(r0, r1); + NORM_LSHIFTR(r1, r2); + NORM_LSHIFTR(r2, r3); + NORM_LSHIFTR(r3, r4); + NORM_LSHIFTR(r4, r5); + NORM_LSHIFTR(r5, r6); + NORM_LSHIFTR(r6, r7); + NORM_LSHIFTR(r7, r8); + NORM_LSHIFTR(r8, r9); + + U64 t[NE_LEN52*2]; + t[0] = r0; + t[1] = r1; + t[2] = r2; + t[3] = r3; + t[4] = r4; + t[5] = r5; + t[6] = r6; + t[7] = r7; + t[8] = r8; + t[9] = r9; + ifma52_ed25519n_reduce(r, t); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_p25519.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_p25519.c new file mode 100644 index 000000000..8412e0d49 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/ifma_arith_p25519.c @@ -0,0 +1,527 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +__ALIGN64 static const int64u VPRIME25519_LO[sizeof(U64) / sizeof(int64u)] = { + REP8_DECL(PRIME25519_LO) +}; +__ALIGN64 static const int64u VPRIME25519_MID[sizeof(U64) / sizeof(int64u)] = { + REP8_DECL(PRIME25519_MID) +}; +__ALIGN64 static const int64u VPRIME25519_HI[sizeof(U64) / sizeof(int64u)] = { + REP8_DECL(PRIME25519_HI) +}; + + +/* normalization macros */ +#define NORM_LSHIFTR(R, I, J) \ + R##J = add64(R##J, srli64(R##I, DIGIT_SIZE)); \ + R##I = and64_const(R##I, DIGIT_MASK); +#define NORM_ASHIFTR(R, I, J) \ + R##J = add64(R##J, srai64(R##I, DIGIT_SIZE)); \ + R##I = and64_const(R##I, DIGIT_MASK); + + +//__INLINE +void fe52_mb_add_mod25519(fe52_mb vr, const fe52_mb va, const fe52_mb vb) +{ + /* r = a+b */ + U64 r0 = add64(va[0], vb[0]); + U64 r1 = add64(va[1], vb[1]); + U64 r2 = add64(va[2], vb[2]); + U64 r3 = add64(va[3], vb[3]); + U64 r4 = add64(va[4], vb[4]); + + /* t = r-modulus (2^255-19) */ + U64 t0 = sub64(r0, loadu64(VPRIME25519_LO)); + U64 t1 = sub64(r1, loadu64(VPRIME25519_MID)); + U64 t2 = sub64(r2, loadu64(VPRIME25519_MID)); + U64 t3 = sub64(r3, loadu64(VPRIME25519_MID)); + U64 t4 = sub64(r4, loadu64(VPRIME25519_HI)); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_LSHIFTR(r, 0, 1) + NORM_LSHIFTR(r, 1, 2) + NORM_LSHIFTR(r, 2, 3) + NORM_LSHIFTR(r, 3, 4) + + /* normalize t0, t1, t2, t3, t4 */ + NORM_ASHIFTR(t, 0, 1) + NORM_ASHIFTR(t, 1, 2) + NORM_ASHIFTR(t, 2, 3) + NORM_ASHIFTR(t, 3, 4) + + /* condition mask t4<0? (-1) : 0 */ + __mb_mask cmask = cmp64_mask(t4, get_zero64(), _MM_CMPINT_LT); + + vr[0] = mask_mov64(t0, cmask, r0); + vr[1] = mask_mov64(t1, cmask, r1); + vr[2] = mask_mov64(t2, cmask, r2); + vr[3] = mask_mov64(t3, cmask, r3); + vr[4] = mask_mov64(t4, cmask, r4); +} + +//__INLINE +void fe52_mb_sub_mod25519(fe52_mb vr, const fe52_mb va, const fe52_mb vb) +{ + /* r = a-b */ + U64 r0 = sub64(va[0], vb[0]); + U64 r1 = sub64(va[1], vb[1]); + U64 r2 = sub64(va[2], vb[2]); + U64 r3 = sub64(va[3], vb[3]); + U64 r4 = sub64(va[4], vb[4]); + + /* t = r+modulus (2^255-19) */ + U64 t0 = add64(r0, loadu64(VPRIME25519_LO)); + U64 t1 = add64(r1, loadu64(VPRIME25519_MID)); + U64 t2 = add64(r2, loadu64(VPRIME25519_MID)); + U64 t3 = add64(r3, loadu64(VPRIME25519_MID)); + U64 t4 = add64(r4, loadu64(VPRIME25519_HI)); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + + /* normalize t0, t1, t2, t3, t4 */ + NORM_ASHIFTR(t, 0, 1) + NORM_ASHIFTR(t, 1, 2) + NORM_ASHIFTR(t, 2, 3) + NORM_ASHIFTR(t, 3, 4) + + /* condition mask r4<0? (-1) : 0 */ + __mb_mask cmask = cmp64_mask(r4, get_zero64(), _MM_CMPINT_LT); + + vr[0] = mask_mov64(r0, cmask, t0); + vr[1] = mask_mov64(r1, cmask, t1); + vr[2] = mask_mov64(r2, cmask, t2); + vr[3] = mask_mov64(r3, cmask, t3); + vr[4] = mask_mov64(r4, cmask, t4); +} + +//__INLINE +void fe52_mb_neg_mod25519(fe52_mb vr, const fe52_mb va) +{ + __mb_mask non_zero = ~fe52_mb_is_zero(va); + + /* r = is_zero? a : p-a */ + U64 r0 = mask_sub64(va[0], non_zero, loadu64(VPRIME25519_LO), va[0]); + U64 r1 = mask_sub64(va[1], non_zero, loadu64(VPRIME25519_MID), va[1]); + U64 r2 = mask_sub64(va[2], non_zero, loadu64(VPRIME25519_MID), va[2]); + U64 r3 = mask_sub64(va[3], non_zero, loadu64(VPRIME25519_MID), va[3]); + U64 r4 = mask_sub64(va[4], non_zero, loadu64(VPRIME25519_HI), va[4]); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + + vr[0] = r0; + vr[1] = r1; + vr[2] = r2; + vr[3] = r3; + vr[4] = r4; +} + +/* +// multiplicative operations +*/ + +/* full multiplication macros */ +#define ROUND_MUL_SRC(I, J, S_LO, R_LO, S_HI, R_HI) \ + R_LO = fma52lo(S_LO, va[I], vb[J]); \ + R_HI = fma52hi(S_HI, va[I], vb[J]); + +#define ROUND_MUL(I, J, M0, M1) \ + ROUND_MUL_SRC(I, J, M0, M0, M1, M1) + +/* reduction constants and macros */ +#define MASK47 ((1ULL << (255 - 52 * 4)) - 1) + +__ALIGN64 static const int64u MASK47_[sizeof(U64) / sizeof(int64u)] = { REP8_DECL(MASK47) }; +__ALIGN64 static const int64u MOD_2_255_[sizeof(U64) / sizeof(int64u)] = { REP8_DECL(19) }; +__ALIGN64 static const int64u MOD_2_260_[sizeof(U64) / sizeof(int64u)] = { REP8_DECL(19*32) }; + +#define MASK_47 loadu64(MASK47_) +#define MOD_2_255 loadu64(MOD_2_255_) +#define MOD_2_260 loadu64(MOD_2_260_) + +#define REDUCE_ROUND(R0, R1, R5) \ + r##R0 = fma52lo(r##R0, r##R5, MOD_2_260); \ + r##R1 = fma52lo( fma52hi(r##R1, r##R5, MOD_2_260), \ + srli64(r##R5, 52), MOD_2_260); + + +//__INLINE +void fe52_mb_mul_mod25519(fe52_mb vr, const fe52_mb va, const fe52_mb vb) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + /* full multiplication */ + ROUND_MUL(4, 4, r8, r9); + ROUND_MUL(3, 0, r3, r4); + ROUND_MUL(1, 2, r3, r4); + ROUND_MUL(0, 3, r3, r4); + ROUND_MUL(2, 1, r3, r4); + ROUND_MUL(2, 2, r4, r5); + ROUND_MUL(0, 4, r4, r5); + ROUND_MUL(1, 3, r4, r5); + ROUND_MUL(3, 1, r4, r5); + ROUND_MUL(4, 0, r4, r5); + + ROUND_MUL(1, 4, r5, r6); + ROUND_MUL(2, 3, r5, r6); + ROUND_MUL(3, 2, r5, r6); + ROUND_MUL(4, 1, r5, r6); + ROUND_MUL(2, 4, r6, r7); + ROUND_MUL(3, 3, r6, r7); + ROUND_MUL(4, 2, r6, r7); + + ROUND_MUL(0, 0, r0, r1); + ROUND_MUL(0, 1, r1, r2); + ROUND_MUL(0, 2, r2, r3); + ROUND_MUL(1, 0, r1, r2); + ROUND_MUL(1, 1, r2, r3); + ROUND_MUL(2, 0, r2, r3); + ROUND_MUL(3, 4, r7, r8); + ROUND_MUL(4, 3, r7, r8); + + /* reduce r4 upper bits */ + r4 = fma52lo(r4, r9, MOD_2_260); + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + r4 = and64(r4, MASK_47); + /* rest of reduction */ + REDUCE_ROUND(0, 1, 5); + REDUCE_ROUND(1, 2, 6); + REDUCE_ROUND(2, 3, 7); + REDUCE_ROUND(3, 4, 8); + + /* normalize result */ + NORM_LSHIFTR(r, 0, 1); + NORM_LSHIFTR(r, 1, 2); + NORM_LSHIFTR(r, 2, 3); + NORM_LSHIFTR(r, 3, 4); + + vr[0] = r0; + vr[1] = r1; + vr[2] = r2; + vr[3] = r3; + vr[4] = r4; +} + +/* SQR +c=0 (0,0) +c=1 (0,1) +c=2 (0,2) (1,1) +c=3 (0,3) (1,2) +c=4 (0,4) (1,3) (2,2) +c=5 (1,4) (2,3) +c=6 (2,4) (3,3) +c=7 (3,4) +c=8 (4,4) +*/ +//__INLINE +void fe52_mb_sqr_mod25519(fe52_mb vr, const fe52_mb va) +{ + U64 *vb = (U64*)va; + + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + // Square + ROUND_MUL(0, 1, r1, r2); + ROUND_MUL(0, 2, r2, r3); + ROUND_MUL(0, 3, r3, r4); + ROUND_MUL(0, 4, r4, r5); + ROUND_MUL(1, 4, r5, r6); + ROUND_MUL(2, 4, r6, r7); + ROUND_MUL(3, 4, r7, r8); + + ROUND_MUL(1, 2, r3, r4); + ROUND_MUL(1, 3, r4, r5); + ROUND_MUL(2, 3, r5, r6); + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + + ROUND_MUL(0, 0, r0, r1); + ROUND_MUL(1, 1, r2, r3); + ROUND_MUL(2, 2, r4, r5); + ROUND_MUL(3, 3, r6, r7); + ROUND_MUL(4, 4, r8, r9); + + /* reduce r4 upper bits */ + r4 = fma52lo(r4, r9, MOD_2_260); + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + r4 = and64(r4, MASK_47); + /* rest of reduction */ + REDUCE_ROUND(0, 1, 5); + REDUCE_ROUND(1, 2, 6); + REDUCE_ROUND(2, 3, 7); + REDUCE_ROUND(3, 4, 8); + + /* normalize result */ + NORM_LSHIFTR(r, 0, 1); + NORM_LSHIFTR(r, 1, 2); + NORM_LSHIFTR(r, 2, 3); + NORM_LSHIFTR(r, 3, 4); + + vr[0] = r0; + vr[1] = r1; + vr[2] = r2; + vr[3] = r3; + vr[4] = r4; +} + + +/* variant of ROUND_MUL_SRC() and ROUND_MUL() macros */ +#define ROUND_MUL_SRC_A(I, J, S_LO, R_LO, S_HI, R_HI) \ + R_LO = fma52lo(S_LO, a##I, a##J); \ + R_HI = fma52hi(S_HI, a##I, a##J); + +#define ROUND_MUL_A(I, J, M0, M1) \ + ROUND_MUL_SRC_A(I, J, M0, M0, M1, M1) + +void fe52_mb_sqr_mod25519_times(fe52_mb vr, const fe52_mb va, int count) +{ + U64 a0 = va[0]; + U64 a1 = va[1]; + U64 a2 = va[2]; + U64 a3 = va[3]; + U64 a4 = va[4]; + + U64 r0, r1, r2, r3, r4_1, r4, r5, r6, r7, r8, r9; + + for(int i=0; i + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* length of SHA512 hash in bits and bytes */ +#define SHA512_HASH_BITLENGTH (512) +#define HASH_LENGTH NUMBER_OF_DIGITS(SHA512_HASH_BITLENGTH, 8) + +static void ed25519_expand_key(int8u* pa_secret_expand[8], const ed25519_private_key* const pa_secret_key[8]) +{ + /* do hash of secret keys in sequence */ + for (int n = 0; n < 8; n++) { + const ed25519_private_key* psecret = pa_secret_key[n]; + if (psecret) { + SHA512MsgDigest(*psecret, sizeof(ed25519_private_key), pa_secret_expand[n]); + /* prune the buffer according to RFC8032 */ + pa_secret_expand[n][0] &= 0xf8; + pa_secret_expand[n][31] &= 0x7f; + pa_secret_expand[n][31] |= 0x40; + } + } +} + +/* +// Computes public key +// pa_public_key[] array of pointers to the public keys X-coordinates +// pa_secret_key[] array of pointers to the public keys Y-coordinates +*/ +DLL_PUBLIC +mbx_status MB_FUNC_NAME(mbx_ed25519_public_key_)(ed25519_public_key* pa_public_key[8], + const ed25519_private_key* const pa_private_key[8]) +{ + mbx_status status = MBX_STATUS_OK; + + /* test input pointers */ + if (NULL == pa_private_key || NULL == pa_public_key) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + int buf_no; + for (buf_no = 0; buf_no < 8; buf_no++) { + const ed25519_private_key* private_key = pa_private_key[buf_no]; + ed25519_public_key* public_key = pa_public_key[buf_no]; + + /* if any of pointer NULL set error status */ + if (NULL == private_key || NULL == public_key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + /* continue processing if there are correct parameters */ + if (MBX_IS_ANY_OK_STS(status)) { + + int8u sha512_digest[8][HASH_LENGTH] = { 0 }; + int64u* pa_sha512_digest[] = { + (int64u*)sha512_digest[0], (int64u*)sha512_digest[1], (int64u*)sha512_digest[2], (int64u*)sha512_digest[3], + (int64u*)sha512_digest[4], (int64u*)sha512_digest[5], (int64u*)sha512_digest[6], (int64u*)sha512_digest[7] + }; + /* expand secret keys */ + ed25519_expand_key((int8u**)pa_sha512_digest, pa_private_key); + + /* convert into mb fromat */ + U64 scalar[FE_LEN64]; + ifma_BNU_transpose_copy((int64u(*)[8])scalar, (const int64u**)pa_sha512_digest, SHA512_HASH_BITLENGTH/2); + + /* r = [scalar]*G */ + ge52_ext_mb r; + ifma_ed25519_mul_basepoint(&r, scalar); + + /* compress point to public */ + fe52_mb packed_point; + ge52_ext_compress(packed_point, &r); + + /* return result */ + ifma_mb8_to_BNU((int64u * const*)pa_public_key, (const int64u(*)[8])packed_point, GE25519_COMP_BITSIZE); + + /* clear memory containing potentially secret data */ + MB_FUNC_NAME(zero_)((int64u(*)[8])scalar, sizeof(scalar)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u(*)[8])sha512_digest, sizeof(sha512_digest)/sizeof(U64)); + } + + return status; +} + +/* +// Computes ED2519 signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages are being signed +// msgLen[] array of messages lengths (in bytes) +// pa_private_key[] array of pointers to the signer's private keys +// pa_public_key[] array of pointers to the signer's public keys +*/ +static void ed25519_nonce(int8u* pa_nonce[8], int8u* pa_az[8], const int8u* const pa_msg[8], const int32u msgLen[8]) +{ + SHA512State pState; + + for(int n=0; n<8; n++) { + int8u* az = pa_az[n] + HASH_LENGTH/2; + const int8u* msg = pa_msg[n]; + int32u mlen = msgLen[n]; + + SHA512Init(&pState); + SHA512Update(az, 32, &pState); + if (msg) + SHA512Update(msg, mlen, &pState); + + SHA512Final(pa_nonce[n], &pState); + } +} + +static void ed25519_hash_r_pub_msg(int8u* pa_hram[8], const ed25519_sign_component* const pa_sign_r[], const ed25519_public_key* const pa_public_key[8], const int8u* const pa_msg[8], const int32u msgLen[8]) +{ + SHA512State pState; + + for (int n = 0; n < 8; n++) { + const ed25519_sign_component* sign_r = pa_sign_r[n]; + const ed25519_public_key* public = pa_public_key[n]; + const int8u* msg = pa_msg[n]; + int32u mlen = msgLen[n]; + SHA512Init(&pState); + + if(sign_r) + SHA512Update((const int8u*)sign_r, NUMBER_OF_DIGITS(GE25519_COMP_BITSIZE, 8), &pState); + if(public) + SHA512Update((const int8u*)public, sizeof(ed25519_public_key), &pState); + if(msg) + SHA512Update(msg, mlen, &pState); + SHA512Final(pa_hram[n], &pState); + } +} + +DLL_PUBLIC +mbx_status MB_FUNC_NAME(mbx_ed25519_sign_)(ed25519_sign_component* pa_sign_r[8], + ed25519_sign_component* pa_sign_s[8], + const int8u* const pa_msg[8], const int32u msgLen[8], + const ed25519_private_key* const pa_private_key[8], + const ed25519_public_key* const pa_public_key[8]) +{ + mbx_status status = MBX_STATUS_OK; + + /* test input pointers */ + if(NULL == pa_sign_r || NULL == pa_sign_s || + NULL == pa_msg || NULL == msgLen || + NULL == pa_private_key || NULL== pa_public_key) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + int buf_no; + for (buf_no = 0; buf_no < 8; buf_no++) { + ed25519_sign_component* sign_r = pa_sign_r[buf_no]; + ed25519_sign_component* sign_s = pa_sign_s[buf_no]; + const int8u* msg = pa_msg[buf_no]; + const ed25519_private_key* secret = pa_private_key[buf_no]; + const ed25519_public_key* public = pa_public_key[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL == sign_r || NULL == sign_s || NULL== msg || + NULL == secret || NULL == public) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + /* continue processing if there are correct parameters */ + if (MBX_IS_ANY_OK_STS(status)) { + //#define HASH_LENGTH NUMBER_OF_DIGITS(SHA512_DIGEST_BITLENGTH, 8) + + /* expanded secret keys */ + int8u az[8][HASH_LENGTH] = { 0 }; + int64u* pa_az[8] = { + (int64u*)az[0], (int64u*)az[1], (int64u*)az[2], (int64u*)az[3], + (int64u*)az[4], (int64u*)az[5], (int64u*)az[6], (int64u*)az[7] + }; + + /* nonce */ + int8u nonce[8][HASH_LENGTH] = { 0 }; + int64u* pa_nonce[8] = { + (int64u*)nonce[0], (int64u*)nonce[1], (int64u*)nonce[2], (int64u*)nonce[3], + (int64u*)nonce[4], (int64u*)nonce[5], (int64u*)nonce[6], (int64u*)nonce[7] + }; + + /* hram */ + int8u hram[8][HASH_LENGTH] = { 0 }; + int64u* pa_hram[8] = { + (int64u*)hram[0], (int64u*)hram[1], (int64u*)hram[2], (int64u*)hram[3], + (int64u*)hram[4], (int64u*)hram[5], (int64u*)hram[6], (int64u*)hram[7] + }; + + /* expands secret key, az = H(private_key) */ + ed25519_expand_key((int8u**)pa_az, pa_private_key); + U64 mb_az[FE_LEN52]; + ifma_BNU_to_mb8((int64u(*)[8])mb_az, (const int64u**)pa_az, SHA512_HASH_BITLENGTH/2); + + /* computes nonce, nonce = H(az+32, msg) */ + /* Note: only a second half of each pa_az[n] item is used in the ed25519_nonce() function */ + ed25519_nonce((int8u**)pa_nonce, (int8u**)pa_az, pa_msg, msgLen); + + /* reduce nonce wrt n */ + U64 mb_nonce[NUMBER_OF_DIGITS(SHA512_HASH_BITLENGTH, DIGIT_SIZE)]; + ifma_BNU_to_mb8((int64u(*)[8])mb_nonce, (const int64u**)pa_nonce, SHA512_HASH_BITLENGTH); + ifma52_ed25519n_reduce(mb_nonce, mb_nonce); + + /* computes r-component of the signature */ + ifma_mb8_to_BNU(pa_nonce, (const int64u(*)[8])mb_nonce, N25519_BITSIZE); + fe52_mb mb_scalar; + ifma_BNU_transpose_copy((int64u(*)[8])mb_scalar, (const int64u**)pa_nonce, N25519_BITSIZE); + + ge52_ext_mb R; + ifma_ed25519_mul_basepoint(&R, mb_scalar); /* R = [scalar]*G */ + fe52_mb mb_sign_r; + ge52_ext_compress(mb_sign_r, &R); /* compress point to r-component */ + + /* store r-component of the signature */ + ifma_mb8_to_BNU((int64u * const*)pa_sign_r, (const int64u(*)[8])mb_sign_r, GE25519_COMP_BITSIZE); + + /* computes hram, hram = H(r_sign, public_key, msg) */ + ed25519_hash_r_pub_msg((int8u**)pa_hram, (const ed25519_sign_component**)pa_sign_r, pa_public_key, pa_msg, msgLen); + + U64 mb_hram[NUMBER_OF_DIGITS(SHA512_HASH_BITLENGTH, DIGIT_SIZE)]; + ifma_BNU_to_mb8((int64u(*)[8])mb_hram, (const int64u**)pa_hram, SHA512_HASH_BITLENGTH); + ifma52_ed25519n_reduce(mb_hram, mb_hram); + + /* s = hram*az + nonce */ + fe52_mb mb_sign_s; + ifma52_ed25519n_madd(mb_sign_s, mb_hram, mb_az, mb_nonce); + + /* store s-component of the signature */ + ifma_mb8_to_BNU((int64u * const*)pa_sign_s, (const int64u(*)[8])mb_sign_s, N25519_BITSIZE); + + /* clear memory containing potentially secret data */ + MB_FUNC_NAME(zero_)((int64u(*)[8])az, sizeof(az)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u(*)[8])nonce, sizeof(nonce)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u(*)[8])mb_scalar, sizeof(mb_scalar)/sizeof(U64)); + } + + return status; +} + +/* +// ED25519 prime base point order +// n = 2^252+27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED +// in 2^64 radix +*/ +__ALIGN64 static int64u ed25519n_mb64[NE_LEN64][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x5812631A5CF5D3ED) }, + { REP8_DECL(0x14DEF9DEA2F79CD6) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x1000000000000000) } +}; + +DLL_PUBLIC +mbx_status MB_FUNC_NAME(mbx_ed25519_verify_)(const ed25519_sign_component* const pa_sign_r[8], + const ed25519_sign_component* const pa_sign_s[8], + const int8u* const pa_msg[8], const int32u msgLen[8], + const ed25519_public_key* const pa_public_key[8]) +{ + mbx_status status = MBX_STATUS_OK; + + /* test input pointers */ + if (NULL == pa_sign_r || NULL == pa_sign_s || + NULL == pa_msg || NULL == msgLen || + NULL == pa_public_key) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + int buf_no; + for (buf_no = 0; buf_no < 8; buf_no++) { + const ed25519_sign_component* sign_r = pa_sign_r[buf_no]; + const ed25519_sign_component* sign_s = pa_sign_s[buf_no]; + const int8u* msg = pa_msg[buf_no]; + const ed25519_public_key* public = pa_public_key[buf_no]; + + /* if any of pointer NULL set error status */ + if (NULL == sign_r || NULL == sign_s || NULL == msg || + NULL == public) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + /* continue processing if there are correct parameters */ + if (MBX_IS_ANY_OK_STS(status)) { + + /* h = SHA512(sign_r || public_key || msg) */ + __ALIGN64 int8u h[8][HASH_LENGTH] = { 0 }; + int64u* pa_h[8] = { + (int64u*)h[0], (int64u*)h[1], (int64u*)h[2], (int64u*)h[3], + (int64u*)h[4], (int64u*)h[5], (int64u*)h[6], (int64u*)h[7] + }; + ed25519_hash_r_pub_msg((int8u**)pa_h, pa_sign_r, pa_public_key, pa_msg, msgLen); + + /* reduce h %= n */ + __ALIGN64 U64 h_mb[NUMBER_OF_DIGITS(SHA512_HASH_BITLENGTH, DIGIT_SIZE)]; + ifma_BNU_to_mb8((int64u(*)[8])h_mb, (const int64u**)pa_h, SHA512_HASH_BITLENGTH); + ifma52_ed25519n_reduce(h_mb, h_mb); + + /* convert h_mb: fe52 => fe64 */ + __ALIGN64 U64 h64_mb[FE_LEN64+1]; + fe52_to_fe64_mb(h64_mb, h_mb); + h64_mb[FE_LEN64] = get_zero64(); + + /* input r-components to mb */ + __ALIGN64 fe52_mb inputR_mb; + ifma_BNU_to_mb8((int64u(*)[8])inputR_mb, (const int64u**)pa_sign_r, GE25519_COMP_BITSIZE); + + /* input s-components to mb */ + __ALIGN64 U64 s_mb[NE_LEN64 + 1]; + ifma_BNU_transpose_copy((int64u(*)[8])s_mb, (const int64u**)pa_sign_s, 256); + s_mb[NE_LEN64] = get_zero64(); + + /* (comppressed) publickey to mb */ + __ALIGN64 fe52_mb pubfe_mb; + ifma_BNU_to_mb8((int64u(*)[8])pubfe_mb, (const int64u**)pa_public_key, P25519_BITSIZE + 1); + + /* check that s0; n--) { + k |= cmp64_mask(n_mb[n - 1], s_mb[n - 1], _MM_CMPINT_NLE); + } + status |= MBX_SET_STS_BY_MASK(status, ~k, MBX_STATUS_MISMATCH_PARAM_ERR); + + /* continue processing if there are correct parameters */ + if (MBX_IS_ANY_OK_STS(status)) { + /* decompress public to ext point A */ + __ALIGN64 ge52_ext_mb pubA_mb; + k = ge52_ext_decompress(&pubA_mb, pubfe_mb); + fe52_neg(pubA_mb.X, pubA_mb.X); + fe52_neg(pubA_mb.T, pubA_mb.T); + status |= MBX_SET_STS_BY_MASK(status, ~k, MBX_STATUS_SIGNATURE_ERR); + + if (MBX_IS_ANY_OK_STS(status)) { + /* R = [h]A + [s]G */ + __ALIGN64 ge52_ext_mb R_mb; + ifma_ed25519_prod_point(&R_mb, &pubA_mb, h64_mb, s_mb); + + /* recovered r-components */ + __ALIGN64 fe52_mb checkR_mb; + ge52_ext_compress(checkR_mb, &R_mb); + + /* check that recovered r- and input r- components are equal each other */ + k = fe52_mb_is_equ(checkR_mb, inputR_mb); + status |= MBX_SET_STS_BY_MASK(status, ~k, MBX_STATUS_SIGNATURE_ERR); + } + } + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/sha512.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/sha512.c new file mode 100644 index 000000000..bac28a215 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/ed25519/sha512.c @@ -0,0 +1,226 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +/* setup init hash value */ +static void sha512_init(int64u* pHash) +{ + pHash[0] = sha512_iv[0]; + pHash[1] = sha512_iv[1]; + pHash[2] = sha512_iv[2]; + pHash[3] = sha512_iv[3]; + pHash[4] = sha512_iv[4]; + pHash[5] = sha512_iv[5]; + pHash[6] = sha512_iv[6]; + pHash[7] = sha512_iv[7]; +} + +static void sha512_update(void* uniHash, const int8u* mblk, int mlen) +{ + int32u* data = (int32u*)mblk; + + int64u* digest = (int64u*)uniHash; + int64u* SHA512_cnt_loc = (int64u*)sha512_cnt; + + for (; mlen >= MBS_SHA512; data += MBS_SHA512 / sizeof(int32u), mlen -= MBS_SHA512) { + int64u wdat[16]; + int j; + + int64u v[8]; + + /* initialize the first 16 words in the array W (remember about endian) */ + for (j = 0; j < 16; j++) { + int32u hiX = data[2 * j]; + int32u loX = data[2 * j + 1]; + wdat[j] = MAKEDWORD(ENDIANNESS(loX), ENDIANNESS(hiX)); + } + + /* copy digest */ + CopyBlock(digest, v, SHA512_DIGEST_BITSIZE / BYTESIZE); + + for (j = 0; j < 80; j += 16) { + SHA512_STEP(0, j); + SHA512_STEP(1, j); + SHA512_STEP(2, j); + SHA512_STEP(3, j); + SHA512_STEP(4, j); + SHA512_STEP(5, j); + SHA512_STEP(6, j); + SHA512_STEP(7, j); + SHA512_STEP(8, j); + SHA512_STEP(9, j); + SHA512_STEP(10, j); + SHA512_STEP(11, j); + SHA512_STEP(12, j); + SHA512_STEP(13, j); + SHA512_STEP(14, j); + SHA512_STEP(15, j); + } + + /* update digest */ + digest[0] += v[0]; + digest[1] += v[1]; + digest[2] += v[2]; + digest[3] += v[3]; + digest[4] += v[4]; + digest[5] += v[5]; + digest[6] += v[6]; + digest[7] += v[7]; + } +} + +static void sha512_final(DigestSHA512 pHash, const int8u* inpBuffer, int inpLen, int64u lenLo, int64u lenHi) +{ + /* local buffer and it length */ + int8u buffer[MBS_SHA512 * 2]; + int bufferLen = inpLen < (MBS_SHA512 - (int)MLR_SHA512) ? MBS_SHA512 : MBS_SHA512 * 2; + + /* copy rest of message into internal buffer */ + CopyBlock(inpBuffer, buffer, inpLen); + + /* padd message */ + buffer[inpLen++] = 0x80; + PadBlock(0, buffer + inpLen, (int)(bufferLen - inpLen - (int)MLR_SHA512)); + + /* message length representation */ + lenHi = LSL64(lenHi, 3) | LSR64(lenLo, 63 - 3); + lenLo = LSL64(lenLo, 3); + ((int64u*)(buffer + bufferLen))[-2] = ENDIANNESS64(lenHi); + ((int64u*)(buffer + bufferLen))[-1] = ENDIANNESS64(lenLo); + + /* copmplete hash computation */ + sha512_update(pHash, buffer, bufferLen); +} + + +void SHA512Init(SHA512State* pState) +{ + /* zeros message length */ + HASH_LENLO(pState) = 0; + HASH_LENHI(pState) = 0; + /* message buffer is free */ + HASH_BUFFIDX(pState) = 0; + /* clear ctx buffer */ + PadBlock(0, HASH_BUFF(pState), MBS_SHA512); + + /* setup initial digest */ + sha512_init(HASH_VALUE(pState)); +} + +void SHA512Update(const int8u* pSrc, int len, SHA512State* pState) +{ + +/* +// handle non empty message +*/ +if (len) { + int procLen; + + int idx = HASH_BUFFIDX(pState); + int8u* pBuffer = HASH_BUFF(pState); + int64u lenLo = HASH_LENLO(pState) + (int64u)len; + int64u lenHi = HASH_LENHI(pState); + if (lenLo < HASH_LENLO(pState)) lenHi++; + + /* if non empty internal buffer filling */ + if (idx) { + /* copy from input stream to the internal buffer as match as possible */ + procLen = MIN(len, (MBS_SHA512 - idx)); + CopyBlock(pSrc, pBuffer + idx, procLen); + + /* update message pointer and length */ + pSrc += procLen; + len -= procLen; + idx += procLen; + + /* update digest if buffer full */ + if (MBS_SHA512 == idx) { + sha512_update(HASH_VALUE(pState), pBuffer, MBS_SHA512); + idx = 0; + } + } + + /* main message part processing */ + procLen = len & ~(MBS_SHA512 - 1); + if (procLen) { + sha512_update(HASH_VALUE(pState), pSrc, procLen); + pSrc += procLen; + len -= procLen; + } + + /* store rest of message into the internal buffer */ + if (len) { + CopyBlock(pSrc, pBuffer, len); + idx += len; + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_LENHI(pState) = lenHi; + HASH_BUFFIDX(pState) = idx; +} +} + +void SHA512Final(int8u* pMD, SHA512State* pState) +{ + sha512_final(HASH_VALUE(pState), + HASH_BUFF(pState), HASH_BUFFIDX(pState), + HASH_LENLO(pState), HASH_LENHI(pState)); + /* convert hash into big endian */ + ((int64u*)pMD)[0] = ENDIANNESS64(HASH_VALUE(pState)[0]); + ((int64u*)pMD)[1] = ENDIANNESS64(HASH_VALUE(pState)[1]); + ((int64u*)pMD)[2] = ENDIANNESS64(HASH_VALUE(pState)[2]); + ((int64u*)pMD)[3] = ENDIANNESS64(HASH_VALUE(pState)[3]); + ((int64u*)pMD)[4] = ENDIANNESS64(HASH_VALUE(pState)[4]); + ((int64u*)pMD)[5] = ENDIANNESS64(HASH_VALUE(pState)[5]); + ((int64u*)pMD)[6] = ENDIANNESS64(HASH_VALUE(pState)[6]); + ((int64u*)pMD)[7] = ENDIANNESS64(HASH_VALUE(pState)[7]); + + /* re-init hash value */ + SHA512Init(pState); +} + +void SHA512MsgDigest(const int8u* pMsg, int len, int8u* pMD) +{ + /* message length in the multiple MBS and the rest */ + int msgLenBlks = len & (-MBS_SHA512); + int msgLenRest = len - msgLenBlks; + DigestSHA512 hash; + + /* init hash */ + sha512_init(hash); + + /* process main part of the message */ + if (msgLenBlks) { + sha512_update(hash, pMsg, msgLenBlks); + pMsg += msgLenBlks; + } + + sha512_final(hash, pMsg, msgLenRest, (int64u)len, 0); + hash[0] = ENDIANNESS64(hash[0]); + hash[1] = ENDIANNESS64(hash[1]); + hash[2] = ENDIANNESS64(hash[2]); + hash[3] = ENDIANNESS64(hash[3]); + hash[4] = ENDIANNESS64(hash[4]); + hash[5] = ENDIANNESS64(hash[5]); + hash[6] = ENDIANNESS64(hash[6]); + hash[7] = ENDIANNESS64(hash[7]); + + CopyBlock(hash, pMD, SHA512_DIGEST_BITSIZE / BYTESIZE); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp1k_mb.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp1k_mb.c new file mode 100644 index 000000000..4faa2cc45 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp1k_mb.c @@ -0,0 +1,227 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x20_mb8(out, Y, mod, k0) \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #ifdef USE_AMS_5x + #define SQUARE_5x52x20_mb8(out, Y, mod, k0) \ + AMS5x52x20_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #else + #define SQUARE_5x52x20_mb8(out, Y, mod, k0) \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); + #endif +#else + #define SQUARE_52x20_mb8(out, Y, mod, k0) \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x20_mb8(out, Y, mod, k0) \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (1024) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //20 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //16 + + +typedef int64u (*arr_pint64u_x8)[LEN52][8]; // pointer to pre-computed table of base powers + +static int64u* extract_multiplier_mb8(int64u out[LEN52][8], int64u tbl[][LEN52][8], const int64u idx_mb8[8]) +{ + // Assume first element is what need + __m512i X0 = _mm512_load_si512(tbl[0][0]); + __m512i X1 = _mm512_load_si512(tbl[0][1]); + __m512i X2 = _mm512_load_si512(tbl[0][2]); + __m512i X3 = _mm512_load_si512(tbl[0][3]); + __m512i X4 = _mm512_load_si512(tbl[0][4]); + __m512i X5 = _mm512_load_si512(tbl[0][5]); + __m512i X6 = _mm512_load_si512(tbl[0][6]); + __m512i X7 = _mm512_load_si512(tbl[0][7]); + __m512i X8 = _mm512_load_si512(tbl[0][8]); + __m512i X9 = _mm512_load_si512(tbl[0][9]); + __m512i X10= _mm512_load_si512(tbl[0][10]); + __m512i X11= _mm512_load_si512(tbl[0][11]); + __m512i X12= _mm512_load_si512(tbl[0][12]); + __m512i X13= _mm512_load_si512(tbl[0][13]); + __m512i X14= _mm512_load_si512(tbl[0][14]); + __m512i X15= _mm512_load_si512(tbl[0][15]); + __m512i X16= _mm512_load_si512(tbl[0][16]); + __m512i X17= _mm512_load_si512(tbl[0][17]); + __m512i X18= _mm512_load_si512(tbl[0][18]); + __m512i X19= _mm512_load_si512(tbl[0][19]); + + __m512i idx_target = _mm512_load_si512(idx_mb8); + + int n; + // Find out what we actually need or just keep original + for(n=1; n<(1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + ifma_extract_amm52x20_mb8 ((int64u*)red_Y, (int64u*)red_Y, red_table, (int64u*)(&red_table_idx), + (int64u*)modulus, (int64u*)k0); + } + } + } + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x20_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + zero_mb8(red_Y, LEN52); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp2k_mb.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp2k_mb.c new file mode 100644 index 000000000..dd63627fc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp2k_mb.c @@ -0,0 +1,288 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x40_mb8(out, Y, mod, k0) \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #ifdef USE_AMS_5x + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + AMS5x52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #else + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); + #endif +#else + #define SQUARE_52x40_mb8(out, Y, mod, k0) \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (2048) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //40 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //32 + + +typedef int64u (*arr_pint64u_x8)[LEN52][8]; // pointer to pre-computed table of base powers + +static int64u* extract_multiplier_mb8(int64u out[LEN52][8], int64u tbl[][LEN52][8], const int64u idx_mb8[8]) +{ + // Assume first element is what need + __m512i X0 = _mm512_load_si512(tbl[0][0]); + __m512i X1 = _mm512_load_si512(tbl[0][1]); + __m512i X2 = _mm512_load_si512(tbl[0][2]); + __m512i X3 = _mm512_load_si512(tbl[0][3]); + __m512i X4 = _mm512_load_si512(tbl[0][4]); + __m512i X5 = _mm512_load_si512(tbl[0][5]); + __m512i X6 = _mm512_load_si512(tbl[0][6]); + __m512i X7 = _mm512_load_si512(tbl[0][7]); + __m512i X8 = _mm512_load_si512(tbl[0][8]); + __m512i X9 = _mm512_load_si512(tbl[0][9]); + __m512i X10= _mm512_load_si512(tbl[0][10]); + __m512i X11= _mm512_load_si512(tbl[0][11]); + __m512i X12= _mm512_load_si512(tbl[0][12]); + __m512i X13= _mm512_load_si512(tbl[0][13]); + __m512i X14= _mm512_load_si512(tbl[0][14]); + __m512i X15= _mm512_load_si512(tbl[0][15]); + __m512i X16= _mm512_load_si512(tbl[0][16]); + __m512i X17= _mm512_load_si512(tbl[0][17]); + __m512i X18= _mm512_load_si512(tbl[0][18]); + __m512i X19= _mm512_load_si512(tbl[0][19]); + __m512i X20= _mm512_load_si512(tbl[0][20]); + __m512i X21= _mm512_load_si512(tbl[0][21]); + __m512i X22= _mm512_load_si512(tbl[0][22]); + __m512i X23= _mm512_load_si512(tbl[0][23]); + __m512i X24= _mm512_load_si512(tbl[0][24]); + __m512i X25= _mm512_load_si512(tbl[0][25]); + __m512i X26= _mm512_load_si512(tbl[0][26]); + __m512i X27= _mm512_load_si512(tbl[0][27]); + __m512i X28= _mm512_load_si512(tbl[0][28]); + __m512i X29= _mm512_load_si512(tbl[0][29]); + __m512i X30= _mm512_load_si512(tbl[0][30]); + __m512i X31= _mm512_load_si512(tbl[0][31]); + __m512i X32= _mm512_load_si512(tbl[0][32]); + __m512i X33= _mm512_load_si512(tbl[0][33]); + __m512i X34= _mm512_load_si512(tbl[0][34]); + __m512i X35= _mm512_load_si512(tbl[0][35]); + __m512i X36= _mm512_load_si512(tbl[0][36]); + __m512i X37= _mm512_load_si512(tbl[0][37]); + __m512i X38= _mm512_load_si512(tbl[0][38]); + __m512i X39= _mm512_load_si512(tbl[0][39]); + + __m512i idx_target = _mm512_load_si512(idx_mb8); + + int n; + // Find out what we actually need or just keep original + for(n=1; n<(1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x40_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + zero_mb8(red_Y, LEN52); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp3k_mb.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp3k_mb.c new file mode 100644 index 000000000..0123c4cb9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp3k_mb.c @@ -0,0 +1,343 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x60_mb8(out, Y, mod, k0) \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #define SQUARE_5x52x60_mb8(out, Y, mod, k0) \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#else + #define SQUARE_52x60_mb8(out, Y, mod, k0) \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x60_mb8(out, Y, mod, k0) \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (3072) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //60 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //48 + + +typedef int64u (*arr_pint64u_x8)[LEN52][8]; // pointer to pre-computed table of base powers + +static int64u* extract_multiplier_mb8(int64u out[LEN52][8], int64u tbl[][LEN52][8], const int64u idx_mb8[8]) +{ + // Assume first element is what need + __m512i X0 = _mm512_load_si512(tbl[0][0]); + __m512i X1 = _mm512_load_si512(tbl[0][1]); + __m512i X2 = _mm512_load_si512(tbl[0][2]); + __m512i X3 = _mm512_load_si512(tbl[0][3]); + __m512i X4 = _mm512_load_si512(tbl[0][4]); + __m512i X5 = _mm512_load_si512(tbl[0][5]); + __m512i X6 = _mm512_load_si512(tbl[0][6]); + __m512i X7 = _mm512_load_si512(tbl[0][7]); + __m512i X8 = _mm512_load_si512(tbl[0][8]); + __m512i X9 = _mm512_load_si512(tbl[0][9]); + __m512i X10= _mm512_load_si512(tbl[0][10]); + __m512i X11= _mm512_load_si512(tbl[0][11]); + __m512i X12= _mm512_load_si512(tbl[0][12]); + __m512i X13= _mm512_load_si512(tbl[0][13]); + __m512i X14= _mm512_load_si512(tbl[0][14]); + __m512i X15= _mm512_load_si512(tbl[0][15]); + __m512i X16= _mm512_load_si512(tbl[0][16]); + __m512i X17= _mm512_load_si512(tbl[0][17]); + __m512i X18= _mm512_load_si512(tbl[0][18]); + __m512i X19= _mm512_load_si512(tbl[0][19]); + __m512i X20= _mm512_load_si512(tbl[0][20]); + __m512i X21= _mm512_load_si512(tbl[0][21]); + __m512i X22= _mm512_load_si512(tbl[0][22]); + __m512i X23= _mm512_load_si512(tbl[0][23]); + __m512i X24= _mm512_load_si512(tbl[0][24]); + __m512i X25= _mm512_load_si512(tbl[0][25]); + __m512i X26= _mm512_load_si512(tbl[0][26]); + __m512i X27= _mm512_load_si512(tbl[0][27]); + __m512i X28= _mm512_load_si512(tbl[0][28]); + __m512i X29= _mm512_load_si512(tbl[0][29]); + __m512i X30= _mm512_load_si512(tbl[0][30]); + __m512i X31= _mm512_load_si512(tbl[0][31]); + __m512i X32= _mm512_load_si512(tbl[0][32]); + __m512i X33= _mm512_load_si512(tbl[0][33]); + __m512i X34= _mm512_load_si512(tbl[0][34]); + __m512i X35= _mm512_load_si512(tbl[0][35]); + __m512i X36= _mm512_load_si512(tbl[0][36]); + __m512i X37= _mm512_load_si512(tbl[0][37]); + __m512i X38= _mm512_load_si512(tbl[0][38]); + __m512i X39= _mm512_load_si512(tbl[0][39]); + __m512i X40= _mm512_load_si512(tbl[0][40]); + __m512i X41= _mm512_load_si512(tbl[0][41]); + __m512i X42= _mm512_load_si512(tbl[0][42]); + __m512i X43= _mm512_load_si512(tbl[0][43]); + __m512i X44= _mm512_load_si512(tbl[0][44]); + __m512i X45= _mm512_load_si512(tbl[0][45]); + __m512i X46= _mm512_load_si512(tbl[0][46]); + __m512i X47= _mm512_load_si512(tbl[0][47]); + __m512i X48= _mm512_load_si512(tbl[0][48]); + __m512i X49= _mm512_load_si512(tbl[0][49]); + __m512i X50= _mm512_load_si512(tbl[0][50]); + __m512i X51= _mm512_load_si512(tbl[0][51]); + __m512i X52= _mm512_load_si512(tbl[0][52]); + __m512i X53= _mm512_load_si512(tbl[0][53]); + __m512i X54= _mm512_load_si512(tbl[0][54]); + __m512i X55= _mm512_load_si512(tbl[0][55]); + __m512i X56= _mm512_load_si512(tbl[0][56]); + __m512i X57= _mm512_load_si512(tbl[0][57]); + __m512i X58= _mm512_load_si512(tbl[0][58]); + __m512i X59= _mm512_load_si512(tbl[0][59]); + + __m512i idx_target = _mm512_load_si512(idx_mb8); + + int n; + // Find out what we actually need or just keep original + for(n=1; n<(1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x60_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + zero_mb8(red_Y, LEN52); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp4k_mb.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp4k_mb.c new file mode 100644 index 000000000..dd17af6f9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp4k_mb.c @@ -0,0 +1,399 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x79_mb8(out, Y, mod, k0) \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #define SQUARE_5x52x79_mb8(out, Y, mod, k0) \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#else + #define SQUARE_52x79_mb8(out, Y, mod, k0) \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x79_mb8(out, Y, mod, k0) \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (4096) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //79 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //64 + + +typedef int64u (*arr_pint64u_x8)[LEN52][8]; // pointer to pre-computed table of base powers + +static int64u* extract_multiplier_mb8(int64u out[LEN52][8], int64u tbl[][LEN52][8], const int64u idx_mb8[8]) +{ + // Assume first element is what need + __m512i X0 = _mm512_load_si512(tbl[0][0]); + __m512i X1 = _mm512_load_si512(tbl[0][1]); + __m512i X2 = _mm512_load_si512(tbl[0][2]); + __m512i X3 = _mm512_load_si512(tbl[0][3]); + __m512i X4 = _mm512_load_si512(tbl[0][4]); + __m512i X5 = _mm512_load_si512(tbl[0][5]); + __m512i X6 = _mm512_load_si512(tbl[0][6]); + __m512i X7 = _mm512_load_si512(tbl[0][7]); + __m512i X8 = _mm512_load_si512(tbl[0][8]); + __m512i X9 = _mm512_load_si512(tbl[0][9]); + __m512i X10= _mm512_load_si512(tbl[0][10]); + __m512i X11= _mm512_load_si512(tbl[0][11]); + __m512i X12= _mm512_load_si512(tbl[0][12]); + __m512i X13= _mm512_load_si512(tbl[0][13]); + __m512i X14= _mm512_load_si512(tbl[0][14]); + __m512i X15= _mm512_load_si512(tbl[0][15]); + __m512i X16= _mm512_load_si512(tbl[0][16]); + __m512i X17= _mm512_load_si512(tbl[0][17]); + __m512i X18= _mm512_load_si512(tbl[0][18]); + __m512i X19= _mm512_load_si512(tbl[0][19]); + __m512i X20= _mm512_load_si512(tbl[0][20]); + __m512i X21= _mm512_load_si512(tbl[0][21]); + __m512i X22= _mm512_load_si512(tbl[0][22]); + __m512i X23= _mm512_load_si512(tbl[0][23]); + __m512i X24= _mm512_load_si512(tbl[0][24]); + __m512i X25= _mm512_load_si512(tbl[0][25]); + __m512i X26= _mm512_load_si512(tbl[0][26]); + __m512i X27= _mm512_load_si512(tbl[0][27]); + __m512i X28= _mm512_load_si512(tbl[0][28]); + __m512i X29= _mm512_load_si512(tbl[0][29]); + __m512i X30= _mm512_load_si512(tbl[0][30]); + __m512i X31= _mm512_load_si512(tbl[0][31]); + __m512i X32= _mm512_load_si512(tbl[0][32]); + __m512i X33= _mm512_load_si512(tbl[0][33]); + __m512i X34= _mm512_load_si512(tbl[0][34]); + __m512i X35= _mm512_load_si512(tbl[0][35]); + __m512i X36= _mm512_load_si512(tbl[0][36]); + __m512i X37= _mm512_load_si512(tbl[0][37]); + __m512i X38= _mm512_load_si512(tbl[0][38]); + __m512i X39= _mm512_load_si512(tbl[0][39]); + __m512i X40= _mm512_load_si512(tbl[0][40]); + __m512i X41= _mm512_load_si512(tbl[0][41]); + __m512i X42= _mm512_load_si512(tbl[0][42]); + __m512i X43= _mm512_load_si512(tbl[0][43]); + __m512i X44= _mm512_load_si512(tbl[0][44]); + __m512i X45= _mm512_load_si512(tbl[0][45]); + __m512i X46= _mm512_load_si512(tbl[0][46]); + __m512i X47= _mm512_load_si512(tbl[0][47]); + __m512i X48= _mm512_load_si512(tbl[0][48]); + __m512i X49= _mm512_load_si512(tbl[0][49]); + __m512i X50= _mm512_load_si512(tbl[0][50]); + __m512i X51= _mm512_load_si512(tbl[0][51]); + __m512i X52= _mm512_load_si512(tbl[0][52]); + __m512i X53= _mm512_load_si512(tbl[0][53]); + __m512i X54= _mm512_load_si512(tbl[0][54]); + __m512i X55= _mm512_load_si512(tbl[0][55]); + __m512i X56= _mm512_load_si512(tbl[0][56]); + __m512i X57= _mm512_load_si512(tbl[0][57]); + __m512i X58= _mm512_load_si512(tbl[0][58]); + __m512i X59= _mm512_load_si512(tbl[0][59]); + __m512i X60= _mm512_load_si512(tbl[0][60]); + __m512i X61= _mm512_load_si512(tbl[0][61]); + __m512i X62= _mm512_load_si512(tbl[0][62]); + __m512i X63= _mm512_load_si512(tbl[0][63]); + __m512i X64= _mm512_load_si512(tbl[0][64]); + __m512i X65= _mm512_load_si512(tbl[0][65]); + __m512i X66= _mm512_load_si512(tbl[0][66]); + __m512i X67= _mm512_load_si512(tbl[0][67]); + __m512i X68= _mm512_load_si512(tbl[0][68]); + __m512i X69= _mm512_load_si512(tbl[0][69]); + __m512i X70= _mm512_load_si512(tbl[0][70]); + __m512i X71= _mm512_load_si512(tbl[0][71]); + __m512i X72= _mm512_load_si512(tbl[0][72]); + __m512i X73= _mm512_load_si512(tbl[0][73]); + __m512i X74= _mm512_load_si512(tbl[0][74]); + __m512i X75= _mm512_load_si512(tbl[0][75]); + __m512i X76= _mm512_load_si512(tbl[0][76]); + __m512i X77= _mm512_load_si512(tbl[0][77]); + __m512i X78= _mm512_load_si512(tbl[0][78]); + + __m512i idx_target = _mm512_load_si512(idx_mb8); + + int n; + // Find out what we actually need or just keep original + for(n=1; n<(1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x79_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + zero_mb8(red_Y, LEN52); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp_mb.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp_mb.c new file mode 100644 index 000000000..044eac557 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp_mb.c @@ -0,0 +1,251 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include +#include + +#include +#include +#include +#include +#include + + +mbx_status ifma_exp_mb(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + exp_mb8 expfunc, + int8u* pBuffer, int bufferLen) +{ + mbx_status status = MBX_STATUS_OK; + + /* test input pointers */ + if (NULL==out_pa || NULL==base_pa || NULL==exp_pa || NULL==mod_pa || NULL==expfunc || NULL== pBuffer) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* test exp length */ + if (exp_bits > mod_bits) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* test length of buffer */ + int bufferMinLen = mbx_exp_BufferSize(mod_bits); + if (bufferLen < bufferMinLen) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* check pointers and values */ + int buf_no; + for (buf_no = 0; buf_no < 8; buf_no++) { + int64u* out = out_pa[buf_no]; + const int64u* base = base_pa[buf_no]; + const int64u* exp = exp_pa[buf_no]; + const int64u* mod = mod_pa[buf_no]; + + /* if any of pointer NULL set error status */ + if (NULL == out || NULL == base || NULL == exp || NULL == mod) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + /* + // processing + */ + if (MBX_IS_ANY_OK_STS(status)) { + int len52 = NUMBER_OF_DIGITS(mod_bits, DIGIT_SIZE); + int len64 = NUMBER_OF_DIGITS(mod_bits, 64); + + /* 64-byte aligned buffer of int64[8] */ + pint64u_x8 pBuffer_x8 = (pint64u_x8)IFMA_ALIGNED_PTR(pBuffer, 64); + + /* allocate mb8 buffers */ + pint64u_x8 k0_mb8 = pBuffer_x8; + pint64u_x8 expz_mb8 = k0_mb8 + 1; + pint64u_x8 rr_mb8 = expz_mb8 + (len64+1); + pint64u_x8 inout_mb8 = rr_mb8 + len52; + pint64u_x8 mod_mb8 = inout_mb8 + len52; + /* MULTIPLE_OF_10 because of AMS5x52x79_diagonal_mb8() implementaion specific */ + pint64u_x8 work_buffer = mod_mb8 + MULTIPLE_OF(len52, 10); + + /* convert modulus to ifma fmt */ + zero_mb8(mod_mb8, MULTIPLE_OF(len52, 10)); + ifma_BNU_to_mb8(mod_mb8, mod_pa, mod_bits); + + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8[0], mod_mb8[0]); + + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, mod_mb8, mod_bits); + + /* convert input to ifma fmt */ + ifma_BNU_to_mb8(inout_mb8, base_pa, mod_bits); + + /* re-arrange exps to ifma */ + zero_mb8(expz_mb8, len64+1); + ifma_BNU_transpose_copy(expz_mb8, exp_pa, exp_bits); + + /* exponentiation */ + expfunc(inout_mb8, + (const int64u(*)[8])inout_mb8, + (const int64u(*)[8])expz_mb8, exp_bits, + (const int64u(*)[8])mod_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8[0], + (int64u(*)[8])work_buffer); + + /* convert result from ifma fmt */ + ifma_mb8_to_BNU(out_pa, (const int64u(*)[8])inout_mb8, mod_bits); + + /* clear exponents */ + zero_mb8(expz_mb8, len64); + } + + return status; +} + +DLL_PUBLIC +mbx_status mbx_exp1024_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen) +{ + mbx_status status = MBX_STATUS_OK; + + /* test exp modulus range */ + if(EXP_MODULUS_1024 != bits_range(mod_bits)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* 1k exponentiation */ + return ifma_exp_mb(out_pa, base_pa, + exp_pa, exp_bits, + mod_pa, mod_bits, + ifma_modexp1024_mb, + pBuffer, bufferLen); +} + +DLL_PUBLIC +mbx_status mbx_exp2048_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen) +{ + mbx_status status = MBX_STATUS_OK; + + /* test exp modulus range */ + if(EXP_MODULUS_2048 != bits_range(mod_bits)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* 2k exponentiation */ + return ifma_exp_mb(out_pa, base_pa, + exp_pa, exp_bits, + mod_pa, mod_bits, + ifma_modexp2048_mb, + pBuffer, bufferLen); +} + +DLL_PUBLIC +mbx_status mbx_exp3072_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen) +{ + mbx_status status = MBX_STATUS_OK; + + /* test exp modulus range */ + if(EXP_MODULUS_3072 != bits_range(mod_bits)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* 3k exponentiation */ + return ifma_exp_mb(out_pa, base_pa, + exp_pa, exp_bits, + mod_pa, mod_bits, + ifma_modexp3072_mb, + pBuffer, bufferLen); +} + +DLL_PUBLIC +mbx_status mbx_exp4096_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen) +{ + mbx_status status = MBX_STATUS_OK; + + /* test exp modulus range */ + if(EXP_MODULUS_4096 != bits_range(mod_bits)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* 4k exponentiation */ + return ifma_exp_mb(out_pa, base_pa, + exp_pa, exp_bits, + mod_pa, mod_bits, + ifma_modexp4096_mb, + pBuffer, bufferLen); +} + +DLL_PUBLIC +mbx_status mbx_exp_mb8(int64u* const out_pa[8], + const int64u* const base_pa[8], + const int64u* const exp_pa[8], int exp_bits, + const int64u* const mod_pa[8], int mod_bits, + int8u* pBuffer, int bufferLen) +{ + mbx_status status = MBX_STATUS_OK; + + /* test exp modulus range */ + int modulus_range = bits_range(mod_bits); + if(0 == modulus_range) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + // + // processing + // + exp_mb8 expfunc = NULL; + switch (modulus_range) { + case EXP_MODULUS_1024: expfunc = ifma_modexp1024_mb; break; + case EXP_MODULUS_2048: expfunc = ifma_modexp2048_mb; break; + case EXP_MODULUS_3072: expfunc = ifma_modexp3072_mb; break; + case EXP_MODULUS_4096: expfunc = ifma_modexp4096_mb; break; + default: break; + } + + return ifma_exp_mb(out_pa, base_pa, + exp_pa, exp_bits, + mod_pa, mod_bits, + expfunc, + pBuffer, bufferLen); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp_method.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp_method.c new file mode 100644 index 000000000..f2cd6ccb5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/exp/ifma_exp_method.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include +#include + +/* map exp modulus bit size to exp modulus range */ +int bits_range(int modulusBits) +{ + int modulusLen = (NUMBER_OF_DIGITS(modulusBits, DIGIT_SIZE)); + int modulusLen_top = (NUMBER_OF_DIGITS(modulusBits+2, DIGIT_SIZE)); + + if(modulusLen != modulusLen_top) + return EXP_MODULUS_UNSUPPORT; + + switch (modulusLen) { + case NUMBER_OF_DIGITS(EXP_MODULUS_1024, DIGIT_SIZE): return EXP_MODULUS_1024; + case NUMBER_OF_DIGITS(EXP_MODULUS_2048, DIGIT_SIZE): return EXP_MODULUS_2048; + case NUMBER_OF_DIGITS(EXP_MODULUS_3072, DIGIT_SIZE): return EXP_MODULUS_3072; + case NUMBER_OF_DIGITS(EXP_MODULUS_4096, DIGIT_SIZE): return EXP_MODULUS_4096; + default: return EXP_MODULUS_UNSUPPORT; + } +} + +/* size of scratch bufer */ +DLL_PUBLIC +int mbx_exp_BufferSize(int modulusBits) +{ + int modulusRange = bits_range(modulusBits); + + if(modulusRange) { + int len52 = NUMBER_OF_DIGITS(modulusRange, DIGIT_SIZE); + int len64 = NUMBER_OF_DIGITS(modulusRange, 64); + int bufferSize = (8 /* alignment*/ + + /* ifma_mont_exp_mb */ + +1*8 /* k0 */ + +(len64+1+1)*8 /* expz */ + +len52*8 /* rr */ + +len52*8 /* inp_out */ + + MULTIPLE_OF(len52, 10)*8 /* modulus */ + + /* ifma_exp1/2/3/4k_mb */ + +len52*8 /* Y */ + +len52*8 /* X */ + +(1 << EXP_WIN_SIZE) * len52*8 /* pre-computed table*/ + + ) * sizeof(int64u); + return bufferSize; + } + else + return 0; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/AMS4x52x20_diagonal_stitched_with_extract_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/AMS4x52x20_diagonal_stitched_with_extract_mb8.c new file mode 100644 index 000000000..58aad0cac --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/AMS4x52x20_diagonal_stitched_with_extract_mb8.c @@ -0,0 +1,2049 @@ +/******************************************************************************* + * Copyright (C) 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +#ifdef __GNUC__ + #define ASM(a) __asm__(a); +#else + #define ASM(a) +#endif + +/* +Two independant functions are stitched: +- 4 squarings +- Extracting values from the precomputed tables MulTbl and MulTblx + + +For squaring, an optimized approach is utilized. As an example, suppose we are multiplying two 4-digit numbers: + | a3 | a2 | a1 | a0 | + | b3 | b2 | b1 | b0 | + X______________________ + + | a3 * b3 | a2 * b2 | a1 * b1 | a0 * b0 | + | a3 * b2 | a2 * b1 | a1 * b0 | + | a2 * b3 | a1 * b2 | a0 * b1 | + | a3 * b1 | a2 * b0 | + | a1 * b3 | a0 * b2 | + | a3 * b0 | + | a0 * b3 | + +This operation is realized with 4x4=16 digit-wise multiplications. When a=b (for squaring), multiplication operation is optimizes as follows: + | a3 | a2 | a1 | a0 | + | a3 | a2 | a1 | a0 | + X______________________ + + | a3 * a3 | a2 * a2 | a1 * a1 | a0 * a0 | + 2* | a3 * a2 | a2 * a1 | a1 * a0 | + + 2* | a3 * a1 | a2 * a0 | + + 2* | a3 * a0 | + +This operation is realized with 10 digit-wise multiplications. For an n-digit squaring operation, (n^2-n)/2 less digit-wise multiplications are +required. The number of digit-wise multiplications for n-digit squaring can be calculated with the following equation: + + n^2 - (n^2-n)/2 + +multiplication by 2 operations are realized with add64 instructions. +*/ +void AMS4x52x20_diagonal_stitched_with_extract_mb8( + int64u* out_mb, U64* mulb, U64* mulbx, const int64u* inpA_mb, + const int64u* inpM_mb, const int64u* k0_mb, int64u MulTbl[][redLen][ 8], + int64u MulTblx[][redLen][ 8], const int64u Idx[ 8]) { + + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, + res20, res21, res22, res23, res24, res25, res26, res27, res28, res29, + res30, res31, res32, res33, res34, res35, res36, res37, res38, res39; + + const U64 mont_constant = loadu64((U64*) k0_mb); + + U64* a = (U64*) inpA_mb; + U64* m = (U64*) inpM_mb; + U64* r = (U64*) out_mb; + + U64 idx_target = loadu64((U64*) Idx); + __mmask8 extract_sel_mask = cmpeq64_mask(set64(0), idx_target); + + for (int iter = 0; iter < 4; ++iter) { + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = res09 = + res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = res18 = res19 = + res20 = res21 = res22 = res23 = res24 = res25 = res26 = res27 = res28 = res29 = + res30 = res31 = res32 = res33 = res34 = res35 = res36 = res37 = res38 = res39 = get_zero64(); + + // Calculate full square + // stitched with extraction code + + //*******BEGIN SQUARING CODE SEGMENT************// + res01 = fma52lo(res01, a[ 0], a[ 1]); // Sum(1) + res02 = fma52hi(res02, a[ 0], a[ 1]); // Sum(1) + res02 = fma52lo(res02, a[ 0], a[ 2]); // Sum(2) + res03 = fma52hi(res03, a[ 0], a[ 2]); // Sum(2) + res03 = fma52lo(res03, a[ 1], a[ 2]); // Sum(3) + res04 = fma52hi(res04, a[ 1], a[ 2]); // Sum(3) + res03 = fma52lo(res03, a[ 0], a[ 3]); // Sum(3) + res04 = fma52hi(res04, a[ 0], a[ 3]); // Sum(3) + res04 = fma52lo(res04, a[ 1], a[ 3]); // Sum(4) + res05 = fma52hi(res05, a[ 1], a[ 3]); // Sum(4) + res05 = fma52lo(res05, a[ 2], a[ 3]); // Sum(5) + res06 = fma52hi(res06, a[ 2], a[ 3]); // Sum(5) + res04 = fma52lo(res04, a[ 0], a[ 4]); // Sum(4) + res05 = fma52hi(res05, a[ 0], a[ 4]); // Sum(4) + res05 = fma52lo(res05, a[ 1], a[ 4]); // Sum(5) + res06 = fma52hi(res06, a[ 1], a[ 4]); // Sum(5) + res06 = fma52lo(res06, a[ 2], a[ 4]); // Sum(6) + res07 = fma52hi(res07, a[ 2], a[ 4]); // Sum(6) + res07 = fma52lo(res07, a[ 3], a[ 4]); // Sum(7) + res08 = fma52hi(res08, a[ 3], a[ 4]); // Sum(7) + res05 = fma52lo(res05, a[ 0], a[ 5]); // Sum(5) + res06 = fma52hi(res06, a[ 0], a[ 5]); // Sum(5) + res06 = fma52lo(res06, a[ 1], a[ 5]); // Sum(6) + res07 = fma52hi(res07, a[ 1], a[ 5]); // Sum(6) + res07 = fma52lo(res07, a[ 2], a[ 5]); // Sum(7) + res08 = fma52hi(res08, a[ 2], a[ 5]); // Sum(7) + res08 = fma52lo(res08, a[ 3], a[ 5]); // Sum(8) + res09 = fma52hi(res09, a[ 3], a[ 5]); // Sum(8) + res09 = fma52lo(res09, a[ 4], a[ 5]); // Sum(9) + res10 = fma52hi(res10, a[ 4], a[ 5]); // Sum(9) + res06 = fma52lo(res06, a[ 0], a[ 6]); // Sum(6) + res07 = fma52hi(res07, a[ 0], a[ 6]); // Sum(6) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + U64 idx_curr = set64(1+4*iter); + __mmask8 extract_sel_mask_next = cmpeq64_mask(idx_curr, idx_target); + U64 temp = loadstream64(MulTbl[0+4*iter][ 0]); + mulb[ 0] = _mm512_mask_mov_epi64(mulb[ 0], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][ 1]); + mulb[ 1] = _mm512_mask_mov_epi64(mulb[ 1], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][ 2]); + mulb[ 2] = _mm512_mask_mov_epi64(mulb[ 2], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][ 3]); + mulb[ 3] = _mm512_mask_mov_epi64(mulb[ 3], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res07 = fma52lo(res07, a[ 1], a[ 6]); // Sum(7) + res08 = fma52hi(res08, a[ 1], a[ 6]); // Sum(7) + res08 = fma52lo(res08, a[ 2], a[ 6]); // Sum(8) + res09 = fma52hi(res09, a[ 2], a[ 6]); // Sum(8) + res09 = fma52lo(res09, a[ 3], a[ 6]); // Sum(9) + res10 = fma52hi(res10, a[ 3], a[ 6]); // Sum(9) + res10 = fma52lo(res10, a[ 4], a[ 6]); // Sum(10) + res11 = fma52hi(res11, a[ 4], a[ 6]); // Sum(10) + res11 = fma52lo(res11, a[ 5], a[ 6]); // Sum(11) + res12 = fma52hi(res12, a[ 5], a[ 6]); // Sum(11) + res07 = fma52lo(res07, a[ 0], a[ 7]); // Sum(7) + res08 = fma52hi(res08, a[ 0], a[ 7]); // Sum(7) + res08 = fma52lo(res08, a[ 1], a[ 7]); // Sum(8) + res09 = fma52hi(res09, a[ 1], a[ 7]); // Sum(8) + res09 = fma52lo(res09, a[ 2], a[ 7]); // Sum(9) + res10 = fma52hi(res10, a[ 2], a[ 7]); // Sum(9) + res10 = fma52lo(res10, a[ 3], a[ 7]); // Sum(10) + res11 = fma52hi(res11, a[ 3], a[ 7]); // Sum(10) + res11 = fma52lo(res11, a[ 4], a[ 7]); // Sum(11) + res12 = fma52hi(res12, a[ 4], a[ 7]); // Sum(11) + res08 = fma52lo(res08, a[ 0], a[ 8]); // Sum(8) + res09 = fma52hi(res09, a[ 0], a[ 8]); // Sum(8) + res09 = fma52lo(res09, a[ 1], a[ 8]); // Sum(9) + res10 = fma52hi(res10, a[ 1], a[ 8]); // Sum(9) + res10 = fma52lo(res10, a[ 2], a[ 8]); // Sum(10) + res11 = fma52hi(res11, a[ 2], a[ 8]); // Sum(10) + res11 = fma52lo(res11, a[ 3], a[ 8]); // Sum(11) + res12 = fma52hi(res12, a[ 3], a[ 8]); // Sum(11) + res09 = fma52lo(res09, a[ 0], a[ 9]); // Sum(9) + res10 = fma52hi(res10, a[ 0], a[ 9]); // Sum(9) + res10 = fma52lo(res10, a[ 1], a[ 9]); // Sum(10) + res11 = fma52hi(res11, a[ 1], a[ 9]); // Sum(10 + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[0+4*iter][ 4]); + mulb[ 4] = _mm512_mask_mov_epi64(mulb[ 4], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][ 5]); + mulb[ 5] = _mm512_mask_mov_epi64(mulb[ 5], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][ 6]); + mulb[ 6] = _mm512_mask_mov_epi64(mulb[ 6], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][ 7]); + mulb[ 7] = _mm512_mask_mov_epi64(mulb[ 7], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res11 = fma52lo(res11, a[ 2], a[ 9]); // Sum(11) + res12 = fma52hi(res12, a[ 2], a[ 9]); // Sum(11) + res10 = fma52lo(res10, a[ 0], a[10]); // Sum(10) + res11 = fma52hi(res11, a[ 0], a[10]); // Sum(10) + res11 = fma52lo(res11, a[ 1], a[10]); // Sum(11) + res12 = fma52hi(res12, a[ 1], a[10]); // Sum(11) + res11 = fma52lo(res11, a[ 0], a[11]); // Sum(11) + res12 = fma52hi(res12, a[ 0], a[11]); // Sum(11) + res01 = add64(res01, res01); // Double(1) + res02 = add64(res02, res02); // Double(2) + res03 = add64(res03, res03); // Double(3) + res04 = add64(res04, res04); // Double(4) + res05 = add64(res05, res05); // Double(5) + res06 = add64(res06, res06); // Double(6) + res07 = add64(res07, res07); // Double(7) + res08 = add64(res08, res08); // Double(8) + res09 = add64(res09, res09); // Double(9) + res10 = add64(res10, res10); // Double(10) + res11 = add64(res11, res11); // Double(11) + res00 = fma52lo(res00, a[ 0], a[ 0]); // Add sqr(0) + res01 = fma52hi(res01, a[ 0], a[ 0]); // Add sqr(0) + res02 = fma52lo(res02, a[ 1], a[ 1]); // Add sqr(2) + res03 = fma52hi(res03, a[ 1], a[ 1]); // Add sqr(2) + res04 = fma52lo(res04, a[ 2], a[ 2]); // Add sqr(4) + res05 = fma52hi(res05, a[ 2], a[ 2]); // Add sqr(4) + res06 = fma52lo(res06, a[ 3], a[ 3]); // Add sqr(6) + res07 = fma52hi(res07, a[ 3], a[ 3]); // Add sqr(6) + res08 = fma52lo(res08, a[ 4], a[ 4]); // Add sqr(8) + res09 = fma52hi(res09, a[ 4], a[ 4]); // Add sqr(8) + res10 = fma52lo(res10, a[ 5], a[ 5]); // Add sqr(10) + res11 = fma52hi(res11, a[ 5], a[ 5]); // Add sqr(10) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[0+4*iter][ 8]); + mulb[ 8] = _mm512_mask_mov_epi64(mulb[ 8], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][ 9]); + mulb[ 9] = _mm512_mask_mov_epi64(mulb[ 9], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][10]); + mulb[10] = _mm512_mask_mov_epi64(mulb[10], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][11]); + mulb[11] = _mm512_mask_mov_epi64(mulb[11], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res12 = fma52lo(res12, a[ 5], a[ 7]); // Sum(12) + res13 = fma52hi(res13, a[ 5], a[ 7]); // Sum(12) + res13 = fma52lo(res13, a[ 6], a[ 7]); // Sum(13) + res14 = fma52hi(res14, a[ 6], a[ 7]); // Sum(13) + res12 = fma52lo(res12, a[ 4], a[ 8]); // Sum(12) + res13 = fma52hi(res13, a[ 4], a[ 8]); // Sum(12) + res13 = fma52lo(res13, a[ 5], a[ 8]); // Sum(13) + res14 = fma52hi(res14, a[ 5], a[ 8]); // Sum(13) + res14 = fma52lo(res14, a[ 6], a[ 8]); // Sum(14) + res15 = fma52hi(res15, a[ 6], a[ 8]); // Sum(14) + res15 = fma52lo(res15, a[ 7], a[ 8]); // Sum(15) + res16 = fma52hi(res16, a[ 7], a[ 8]); // Sum(15) + res12 = fma52lo(res12, a[ 3], a[ 9]); // Sum(12) + res13 = fma52hi(res13, a[ 3], a[ 9]); // Sum(12) + res13 = fma52lo(res13, a[ 4], a[ 9]); // Sum(13) + res14 = fma52hi(res14, a[ 4], a[ 9]); // Sum(13) + res14 = fma52lo(res14, a[ 5], a[ 9]); // Sum(14) + res15 = fma52hi(res15, a[ 5], a[ 9]); // Sum(14) + res15 = fma52lo(res15, a[ 6], a[ 9]); // Sum(15) + res16 = fma52hi(res16, a[ 6], a[ 9]); // Sum(15) + res16 = fma52lo(res16, a[ 7], a[ 9]); // Sum(16) + res17 = fma52hi(res17, a[ 7], a[ 9]); // Sum(16) + res17 = fma52lo(res17, a[ 8], a[ 9]); // Sum(17) + res18 = fma52hi(res18, a[ 8], a[ 9]); // Sum(17) + res12 = fma52lo(res12, a[ 2], a[10]); // Sum(12) + res13 = fma52hi(res13, a[ 2], a[10]); // Sum(12) + res13 = fma52lo(res13, a[ 3], a[10]); // Sum(13) + res14 = fma52hi(res14, a[ 3], a[10]); // Sum(13) + res14 = fma52lo(res14, a[ 4], a[10]); // Sum(14) + res15 = fma52hi(res15, a[ 4], a[10]); // Sum(14) + res15 = fma52lo(res15, a[ 5], a[10]); // Sum(15) + res16 = fma52hi(res16, a[ 5], a[10]); // Sum(15) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[0+4*iter][12]); + mulb[12] = _mm512_mask_mov_epi64(mulb[12], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][13]); + mulb[13] = _mm512_mask_mov_epi64(mulb[13], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][14]); + mulb[14] = _mm512_mask_mov_epi64(mulb[14], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][15]); + mulb[15] = _mm512_mask_mov_epi64(mulb[15], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res16 = fma52lo(res16, a[ 6], a[10]); // Sum(16) + res17 = fma52hi(res17, a[ 6], a[10]); // Sum(16) + res17 = fma52lo(res17, a[ 7], a[10]); // Sum(17) + res18 = fma52hi(res18, a[ 7], a[10]); // Sum(17) + res18 = fma52lo(res18, a[ 8], a[10]); // Sum(18) + res19 = fma52hi(res19, a[ 8], a[10]); // Sum(18) + res19 = fma52lo(res19, a[ 9], a[10]); // Sum(19) + res20 = fma52hi(res20, a[ 9], a[10]); // Sum(19) + res12 = fma52lo(res12, a[ 1], a[11]); // Sum(12) + res13 = fma52hi(res13, a[ 1], a[11]); // Sum(12) + res13 = fma52lo(res13, a[ 2], a[11]); // Sum(13) + res14 = fma52hi(res14, a[ 2], a[11]); // Sum(13) + res14 = fma52lo(res14, a[ 3], a[11]); // Sum(14) + res15 = fma52hi(res15, a[ 3], a[11]); // Sum(14) + res15 = fma52lo(res15, a[ 4], a[11]); // Sum(15) + res16 = fma52hi(res16, a[ 4], a[11]); // Sum(15) + res16 = fma52lo(res16, a[ 5], a[11]); // Sum(16) + res17 = fma52hi(res17, a[ 5], a[11]); // Sum(16) + res17 = fma52lo(res17, a[ 6], a[11]); // Sum(17) + res18 = fma52hi(res18, a[ 6], a[11]); // Sum(17) + res18 = fma52lo(res18, a[ 7], a[11]); // Sum(18) + res19 = fma52hi(res19, a[ 7], a[11]); // Sum(18) + res19 = fma52lo(res19, a[ 8], a[11]); // Sum(19) + res20 = fma52hi(res20, a[ 8], a[11]); // Sum(19) + res20 = fma52lo(res20, a[ 9], a[11]); // Sum(20) + res21 = fma52hi(res21, a[ 9], a[11]); // Sum(20) + res21 = fma52lo(res21, a[10], a[11]); // Sum(21) + res22 = fma52hi(res22, a[10], a[11]); // Sum(21) + res12 = fma52lo(res12, a[ 0], a[12]); // Sum(12) + res13 = fma52hi(res13, a[ 0], a[12]); // Sum(12) + res13 = fma52lo(res13, a[ 1], a[12]); // Sum(13) + res14 = fma52hi(res14, a[ 1], a[12]); // Sum(13) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[0+4*iter][16]); + mulb[16] = _mm512_mask_mov_epi64(mulb[16], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][17]); + mulb[17] = _mm512_mask_mov_epi64(mulb[17], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][18]); + mulb[18] = _mm512_mask_mov_epi64(mulb[18], extract_sel_mask, temp); + temp = loadstream64(MulTbl[0+4*iter][19]); + mulb[19] = _mm512_mask_mov_epi64(mulb[19], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res14 = fma52lo(res14, a[ 2], a[12]); // Sum(14) + res15 = fma52hi(res15, a[ 2], a[12]); // Sum(14) + res15 = fma52lo(res15, a[ 3], a[12]); // Sum(15) + res16 = fma52hi(res16, a[ 3], a[12]); // Sum(15) + res16 = fma52lo(res16, a[ 4], a[12]); // Sum(16) + res17 = fma52hi(res17, a[ 4], a[12]); // Sum(16) + res17 = fma52lo(res17, a[ 5], a[12]); // Sum(17) + res18 = fma52hi(res18, a[ 5], a[12]); // Sum(17) + res18 = fma52lo(res18, a[ 6], a[12]); // Sum(18) + res19 = fma52hi(res19, a[ 6], a[12]); // Sum(18) + res19 = fma52lo(res19, a[ 7], a[12]); // Sum(19) + res20 = fma52hi(res20, a[ 7], a[12]); // Sum(19) + res20 = fma52lo(res20, a[ 8], a[12]); // Sum(20) + res21 = fma52hi(res21, a[ 8], a[12]); // Sum(20) + res21 = fma52lo(res21, a[ 9], a[12]); // Sum(21) + res22 = fma52hi(res22, a[ 9], a[12]); // Sum(21) + res22 = fma52lo(res22, a[10], a[12]); // Sum(22) + res23 = fma52hi(res23, a[10], a[12]); // Sum(22) + res23 = fma52lo(res23, a[11], a[12]); // Sum(23) + res24 = fma52hi(res24, a[11], a[12]); // Sum(23) + res13 = fma52lo(res13, a[ 0], a[13]); // Sum(13) + res14 = fma52hi(res14, a[ 0], a[13]); // Sum(13) + res14 = fma52lo(res14, a[ 1], a[13]); // Sum(14) + res15 = fma52hi(res15, a[ 1], a[13]); // Sum(14) + res15 = fma52lo(res15, a[ 2], a[13]); // Sum(15) + res16 = fma52hi(res16, a[ 2], a[13]); // Sum(15) + res16 = fma52lo(res16, a[ 3], a[13]); // Sum(16) + res17 = fma52hi(res17, a[ 3], a[13]); // Sum(16) + res17 = fma52lo(res17, a[ 4], a[13]); // Sum(17) + res18 = fma52hi(res18, a[ 4], a[13]); // Sum(17) + res18 = fma52lo(res18, a[ 5], a[13]); // Sum(18) + res19 = fma52hi(res19, a[ 5], a[13]); // Sum(18) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + U64 tempx = loadstream64(MulTblx[0+4*iter][ 0]); + mulbx[ 0] = _mm512_mask_mov_epi64(mulbx[ 0], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][ 1]); + mulbx[ 1] = _mm512_mask_mov_epi64(mulbx[ 1], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][ 2]); + mulbx[ 2] = _mm512_mask_mov_epi64(mulbx[ 2], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][ 3]); + mulbx[ 3] = _mm512_mask_mov_epi64(mulbx[ 3], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res19 = fma52lo(res19, a[ 6], a[13]); // Sum(19) + res20 = fma52hi(res20, a[ 6], a[13]); // Sum(19) + res20 = fma52lo(res20, a[ 7], a[13]); // Sum(20) + res21 = fma52hi(res21, a[ 7], a[13]); // Sum(20) + res21 = fma52lo(res21, a[ 8], a[13]); // Sum(21) + res22 = fma52hi(res22, a[ 8], a[13]); // Sum(21) + res22 = fma52lo(res22, a[ 9], a[13]); // Sum(22) + res23 = fma52hi(res23, a[ 9], a[13]); // Sum(22) + res23 = fma52lo(res23, a[10], a[13]); // Sum(23) + res24 = fma52hi(res24, a[10], a[13]); // Sum(23) + res14 = fma52lo(res14, a[ 0], a[14]); // Sum(14) + res15 = fma52hi(res15, a[ 0], a[14]); // Sum(14) + res15 = fma52lo(res15, a[ 1], a[14]); // Sum(15) + res16 = fma52hi(res16, a[ 1], a[14]); // Sum(15) + res16 = fma52lo(res16, a[ 2], a[14]); // Sum(16) + res17 = fma52hi(res17, a[ 2], a[14]); // Sum(16) + res17 = fma52lo(res17, a[ 3], a[14]); // Sum(17) + res18 = fma52hi(res18, a[ 3], a[14]); // Sum(17) + res18 = fma52lo(res18, a[ 4], a[14]); // Sum(18) + res19 = fma52hi(res19, a[ 4], a[14]); // Sum(18) + res19 = fma52lo(res19, a[ 5], a[14]); // Sum(19) + res20 = fma52hi(res20, a[ 5], a[14]); // Sum(19) + res20 = fma52lo(res20, a[ 6], a[14]); // Sum(20) + res21 = fma52hi(res21, a[ 6], a[14]); // Sum(20) + res21 = fma52lo(res21, a[ 7], a[14]); // Sum(21) + res22 = fma52hi(res22, a[ 7], a[14]); // Sum(21) + res22 = fma52lo(res22, a[ 8], a[14]); // Sum(22) + res23 = fma52hi(res23, a[ 8], a[14]); // Sum(22) + res23 = fma52lo(res23, a[ 9], a[14]); // Sum(23) + res24 = fma52hi(res24, a[ 9], a[14]); // Sum(23) + res15 = fma52lo(res15, a[ 0], a[15]); // Sum(15) + res16 = fma52hi(res16, a[ 0], a[15]); // Sum(15) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[0+4*iter][ 4]); + mulbx[ 4] = _mm512_mask_mov_epi64(mulbx[ 4], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][ 5]); + mulbx[ 5] = _mm512_mask_mov_epi64(mulbx[ 5], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][ 6]); + mulbx[ 6] = _mm512_mask_mov_epi64(mulbx[ 6], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][ 7]); + mulbx[ 7] = _mm512_mask_mov_epi64(mulbx[ 7], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res16 = fma52lo(res16, a[ 1], a[15]); // Sum(16) + res17 = fma52hi(res17, a[ 1], a[15]); // Sum(16) + res17 = fma52lo(res17, a[ 2], a[15]); // Sum(17) + res18 = fma52hi(res18, a[ 2], a[15]); // Sum(17) + res18 = fma52lo(res18, a[ 3], a[15]); // Sum(18) + res19 = fma52hi(res19, a[ 3], a[15]); // Sum(18) + res19 = fma52lo(res19, a[ 4], a[15]); // Sum(19) + res20 = fma52hi(res20, a[ 4], a[15]); // Sum(19) + res20 = fma52lo(res20, a[ 5], a[15]); // Sum(20) + res21 = fma52hi(res21, a[ 5], a[15]); // Sum(20) + res21 = fma52lo(res21, a[ 6], a[15]); // Sum(21) + res22 = fma52hi(res22, a[ 6], a[15]); // Sum(21) + res22 = fma52lo(res22, a[ 7], a[15]); // Sum(22) + res23 = fma52hi(res23, a[ 7], a[15]); // Sum(22) + res23 = fma52lo(res23, a[ 8], a[15]); // Sum(23) + res24 = fma52hi(res24, a[ 8], a[15]); // Sum(23) + res16 = fma52lo(res16, a[ 0], a[16]); // Sum(16) + res17 = fma52hi(res17, a[ 0], a[16]); // Sum(16) + res17 = fma52lo(res17, a[ 1], a[16]); // Sum(17) + res18 = fma52hi(res18, a[ 1], a[16]); // Sum(17) + res18 = fma52lo(res18, a[ 2], a[16]); // Sum(18) + res19 = fma52hi(res19, a[ 2], a[16]); // Sum(18) + res19 = fma52lo(res19, a[ 3], a[16]); // Sum(19) + res20 = fma52hi(res20, a[ 3], a[16]); // Sum(19) + res20 = fma52lo(res20, a[ 4], a[16]); // Sum(20) + res21 = fma52hi(res21, a[ 4], a[16]); // Sum(20) + res21 = fma52lo(res21, a[ 5], a[16]); // Sum(21) + res22 = fma52hi(res22, a[ 5], a[16]); // Sum(21) + res22 = fma52lo(res22, a[ 6], a[16]); // Sum(22) + res23 = fma52hi(res23, a[ 6], a[16]); // Sum(22) + res23 = fma52lo(res23, a[ 7], a[16]); // Sum(23) + res24 = fma52hi(res24, a[ 7], a[16]); // Sum(23) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[0+4*iter][ 8]); + mulbx[ 8] = _mm512_mask_mov_epi64(mulbx[ 8], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][ 9]); + mulbx[ 9] = _mm512_mask_mov_epi64(mulbx[ 9], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][10]); + mulbx[10] = _mm512_mask_mov_epi64(mulbx[10], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][11]); + mulbx[11] = _mm512_mask_mov_epi64(mulbx[11], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res17 = fma52lo(res17, a[ 0], a[17]); // Sum(17) + res18 = fma52hi(res18, a[ 0], a[17]); // Sum(17) + res18 = fma52lo(res18, a[ 1], a[17]); // Sum(18) + res19 = fma52hi(res19, a[ 1], a[17]); // Sum(18) + res19 = fma52lo(res19, a[ 2], a[17]); // Sum(19) + res20 = fma52hi(res20, a[ 2], a[17]); // Sum(19) + res20 = fma52lo(res20, a[ 3], a[17]); // Sum(20) + res21 = fma52hi(res21, a[ 3], a[17]); // Sum(20) + res21 = fma52lo(res21, a[ 4], a[17]); // Sum(21) + res22 = fma52hi(res22, a[ 4], a[17]); // Sum(21) + res22 = fma52lo(res22, a[ 5], a[17]); // Sum(22) + res23 = fma52hi(res23, a[ 5], a[17]); // Sum(22) + res23 = fma52lo(res23, a[ 6], a[17]); // Sum(23) + res24 = fma52hi(res24, a[ 6], a[17]); // Sum(23) + res18 = fma52lo(res18, a[ 0], a[18]); // Sum(18) + res19 = fma52hi(res19, a[ 0], a[18]); // Sum(18) + res19 = fma52lo(res19, a[ 1], a[18]); // Sum(19) + res20 = fma52hi(res20, a[ 1], a[18]); // Sum(19) + res20 = fma52lo(res20, a[ 2], a[18]); // Sum(20) + res21 = fma52hi(res21, a[ 2], a[18]); // Sum(20) + res21 = fma52lo(res21, a[ 3], a[18]); // Sum(21) + res22 = fma52hi(res22, a[ 3], a[18]); // Sum(21) + res22 = fma52lo(res22, a[ 4], a[18]); // Sum(22) + res23 = fma52hi(res23, a[ 4], a[18]); // Sum(22) + res23 = fma52lo(res23, a[ 5], a[18]); // Sum(23) + res24 = fma52hi(res24, a[ 5], a[18]); // Sum(23) + res19 = fma52lo(res19, a[ 0], a[19]); // Sum(19) + res20 = fma52hi(res20, a[ 0], a[19]); // Sum(19) + res20 = fma52lo(res20, a[ 1], a[19]); // Sum(20) + res21 = fma52hi(res21, a[ 1], a[19]); // Sum(20) + res21 = fma52lo(res21, a[ 2], a[19]); // Sum(21) + res22 = fma52hi(res22, a[ 2], a[19]); // Sum(21) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[0+4*iter][12]); + mulbx[12] = _mm512_mask_mov_epi64(mulbx[12], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][13]); + mulbx[13] = _mm512_mask_mov_epi64(mulbx[13], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][14]); + mulbx[14] = _mm512_mask_mov_epi64(mulbx[14], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][15]); + mulbx[15] = _mm512_mask_mov_epi64(mulbx[15], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res22 = fma52lo(res22, a[ 3], a[19]); // Sum(22) + res23 = fma52hi(res23, a[ 3], a[19]); // Sum(22) + res23 = fma52lo(res23, a[ 4], a[19]); // Sum(23) + res24 = fma52hi(res24, a[ 4], a[19]); // Sum(23) + res12 = add64(res12, res12); // Double(12) + res13 = add64(res13, res13); // Double(13) + res14 = add64(res14, res14); // Double(14) + res15 = add64(res15, res15); // Double(15) + res16 = add64(res16, res16); // Double(16) + res17 = add64(res17, res17); // Double(17) + res18 = add64(res18, res18); // Double(18) + res19 = add64(res19, res19); // Double(19) + res20 = add64(res20, res20); // Double(20) + res21 = add64(res21, res21); // Double(21) + res22 = add64(res22, res22); // Double(22) + res23 = add64(res23, res23); // Double(23) + res12 = fma52lo(res12, a[ 6], a[ 6]); // Add sqr(12) + res13 = fma52hi(res13, a[ 6], a[ 6]); // Add sqr(12) + res14 = fma52lo(res14, a[ 7], a[ 7]); // Add sqr(14) + res15 = fma52hi(res15, a[ 7], a[ 7]); // Add sqr(14) + res16 = fma52lo(res16, a[ 8], a[ 8]); // Add sqr(16) + res17 = fma52hi(res17, a[ 8], a[ 8]); // Add sqr(16) + res18 = fma52lo(res18, a[ 9], a[ 9]); // Add sqr(18) + res19 = fma52hi(res19, a[ 9], a[ 9]); // Add sqr(18) + res20 = fma52lo(res20, a[10], a[10]); // Add sqr(20) + res21 = fma52hi(res21, a[10], a[10]); // Add sqr(20) + res22 = fma52lo(res22, a[11], a[11]); // Add sqr(22) + res23 = fma52hi(res23, a[11], a[11]); // Add sqr(22) + res24 = fma52lo(res24, a[11], a[13]); // Sum(24) + res25 = fma52hi(res25, a[11], a[13]); // Sum(24) + res25 = fma52lo(res25, a[12], a[13]); // Sum(25) + res26 = fma52hi(res26, a[12], a[13]); // Sum(25) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[0+4*iter][16]); + mulbx[16] = _mm512_mask_mov_epi64(mulbx[16], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][17]); + mulbx[17] = _mm512_mask_mov_epi64(mulbx[17], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][18]); + mulbx[18] = _mm512_mask_mov_epi64(mulbx[18], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[0+4*iter][19]); + mulbx[19] = _mm512_mask_mov_epi64(mulbx[19], extract_sel_mask, tempx); + extract_sel_mask = extract_sel_mask_next; + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res24 = fma52lo(res24, a[10], a[14]); // Sum(24) + res25 = fma52hi(res25, a[10], a[14]); // Sum(24) + res25 = fma52lo(res25, a[11], a[14]); // Sum(25) + res26 = fma52hi(res26, a[11], a[14]); // Sum(25) + res26 = fma52lo(res26, a[12], a[14]); // Sum(26) + res27 = fma52hi(res27, a[12], a[14]); // Sum(26) + res27 = fma52lo(res27, a[13], a[14]); // Sum(27) + res28 = fma52hi(res28, a[13], a[14]); // Sum(27) + res24 = fma52lo(res24, a[ 9], a[15]); // Sum(24) + res25 = fma52hi(res25, a[ 9], a[15]); // Sum(24) + res25 = fma52lo(res25, a[10], a[15]); // Sum(25) + res26 = fma52hi(res26, a[10], a[15]); // Sum(25) + res26 = fma52lo(res26, a[11], a[15]); // Sum(26) + res27 = fma52hi(res27, a[11], a[15]); // Sum(26) + res27 = fma52lo(res27, a[12], a[15]); // Sum(27) + res28 = fma52hi(res28, a[12], a[15]); // Sum(27) + res28 = fma52lo(res28, a[13], a[15]); // Sum(28) + res29 = fma52hi(res29, a[13], a[15]); // Sum(28) + res29 = fma52lo(res29, a[14], a[15]); // Sum(29) + res30 = fma52hi(res30, a[14], a[15]); // Sum(29) + res24 = fma52lo(res24, a[ 8], a[16]); // Sum(24) + res25 = fma52hi(res25, a[ 8], a[16]); // Sum(24) + res25 = fma52lo(res25, a[ 9], a[16]); // Sum(25) + res26 = fma52hi(res26, a[ 9], a[16]); // Sum(25) + res26 = fma52lo(res26, a[10], a[16]); // Sum(26) + res27 = fma52hi(res27, a[10], a[16]); // Sum(26) + res27 = fma52lo(res27, a[11], a[16]); // Sum(27) + res28 = fma52hi(res28, a[11], a[16]); // Sum(27) + res28 = fma52lo(res28, a[12], a[16]); // Sum(28) + res29 = fma52hi(res29, a[12], a[16]); // Sum(28) + res29 = fma52lo(res29, a[13], a[16]); // Sum(29) + res30 = fma52hi(res30, a[13], a[16]); // Sum(29) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + idx_curr = set64(2+4*iter); + extract_sel_mask_next = cmpeq64_mask(idx_curr, idx_target); + temp = loadstream64(MulTbl[1+4*iter][ 0]); + mulb[ 0] = _mm512_mask_mov_epi64(mulb[ 0], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][ 1]); + mulb[ 1] = _mm512_mask_mov_epi64(mulb[ 1], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][ 2]); + mulb[ 2] = _mm512_mask_mov_epi64(mulb[ 2], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][ 3]); + mulb[ 3] = _mm512_mask_mov_epi64(mulb[ 3], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res30 = fma52lo(res30, a[14], a[16]); // Sum(30) + res31 = fma52hi(res31, a[14], a[16]); // Sum(30) + res31 = fma52lo(res31, a[15], a[16]); // Sum(31) + res32 = fma52hi(res32, a[15], a[16]); // Sum(31) + res24 = fma52lo(res24, a[ 7], a[17]); // Sum(24) + res25 = fma52hi(res25, a[ 7], a[17]); // Sum(24) + res25 = fma52lo(res25, a[ 8], a[17]); // Sum(25) + res26 = fma52hi(res26, a[ 8], a[17]); // Sum(25) + res26 = fma52lo(res26, a[ 9], a[17]); // Sum(26) + res27 = fma52hi(res27, a[ 9], a[17]); // Sum(26) + res27 = fma52lo(res27, a[10], a[17]); // Sum(27) + res28 = fma52hi(res28, a[10], a[17]); // Sum(27) + res28 = fma52lo(res28, a[11], a[17]); // Sum(28) + res29 = fma52hi(res29, a[11], a[17]); // Sum(28) + res29 = fma52lo(res29, a[12], a[17]); // Sum(29) + res30 = fma52hi(res30, a[12], a[17]); // Sum(29) + res30 = fma52lo(res30, a[13], a[17]); // Sum(30) + res31 = fma52hi(res31, a[13], a[17]); // Sum(30) + res31 = fma52lo(res31, a[14], a[17]); // Sum(31) + res32 = fma52hi(res32, a[14], a[17]); // Sum(31) + res32 = fma52lo(res32, a[15], a[17]); // Sum(32) + res33 = fma52hi(res33, a[15], a[17]); // Sum(32) + res33 = fma52lo(res33, a[16], a[17]); // Sum(33) + res34 = fma52hi(res34, a[16], a[17]); // Sum(33) + res24 = fma52lo(res24, a[ 6], a[18]); // Sum(24) + res25 = fma52hi(res25, a[ 6], a[18]); // Sum(24) + res25 = fma52lo(res25, a[ 7], a[18]); // Sum(25) + res26 = fma52hi(res26, a[ 7], a[18]); // Sum(25) + res26 = fma52lo(res26, a[ 8], a[18]); // Sum(26) + res27 = fma52hi(res27, a[ 8], a[18]); // Sum(26) + res27 = fma52lo(res27, a[ 9], a[18]); // Sum(27) + res28 = fma52hi(res28, a[ 9], a[18]); // Sum(27) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[1+4*iter][ 4]); + mulb[ 4] = _mm512_mask_mov_epi64(mulb[ 4], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][ 5]); + mulb[ 5] = _mm512_mask_mov_epi64(mulb[ 5], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][ 6]); + mulb[ 6] = _mm512_mask_mov_epi64(mulb[ 6], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][ 7]); + mulb[ 7] = _mm512_mask_mov_epi64(mulb[ 7], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res28 = fma52lo(res28, a[10], a[18]); // Sum(28) + res29 = fma52hi(res29, a[10], a[18]); // Sum(28) + res29 = fma52lo(res29, a[11], a[18]); // Sum(29) + res30 = fma52hi(res30, a[11], a[18]); // Sum(29) + res30 = fma52lo(res30, a[12], a[18]); // Sum(30) + res31 = fma52hi(res31, a[12], a[18]); // Sum(30) + res31 = fma52lo(res31, a[13], a[18]); // Sum(31) + res32 = fma52hi(res32, a[13], a[18]); // Sum(31) + res32 = fma52lo(res32, a[14], a[18]); // Sum(32) + res33 = fma52hi(res33, a[14], a[18]); // Sum(32) + res33 = fma52lo(res33, a[15], a[18]); // Sum(33) + res34 = fma52hi(res34, a[15], a[18]); // Sum(33) + res34 = fma52lo(res34, a[16], a[18]); // Sum(34) + res35 = fma52hi(res35, a[16], a[18]); // Sum(34) + res35 = fma52lo(res35, a[17], a[18]); // Sum(35) + res36 = fma52hi(res36, a[17], a[18]); // Sum(35) + res24 = fma52lo(res24, a[ 5], a[19]); // Sum(24) + res25 = fma52hi(res25, a[ 5], a[19]); // Sum(24) + res25 = fma52lo(res25, a[ 6], a[19]); // Sum(25) + res26 = fma52hi(res26, a[ 6], a[19]); // Sum(25) + res26 = fma52lo(res26, a[ 7], a[19]); // Sum(26) + res27 = fma52hi(res27, a[ 7], a[19]); // Sum(26) + res27 = fma52lo(res27, a[ 8], a[19]); // Sum(27) + res28 = fma52hi(res28, a[ 8], a[19]); // Sum(27) + res28 = fma52lo(res28, a[ 9], a[19]); // Sum(28) + res29 = fma52hi(res29, a[ 9], a[19]); // Sum(28) + res29 = fma52lo(res29, a[10], a[19]); // Sum(29) + res30 = fma52hi(res30, a[10], a[19]); // Sum(29) + res30 = fma52lo(res30, a[11], a[19]); // Sum(30) + res31 = fma52hi(res31, a[11], a[19]); // Sum(30) + res31 = fma52lo(res31, a[12], a[19]); // Sum(31) + res32 = fma52hi(res32, a[12], a[19]); // Sum(31) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[1+4*iter][ 8]); + mulb[ 8] = _mm512_mask_mov_epi64(mulb[ 8], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][ 9]); + mulb[ 9] = _mm512_mask_mov_epi64(mulb[ 9], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][10]); + mulb[10] = _mm512_mask_mov_epi64(mulb[10], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][11]); + mulb[11] = _mm512_mask_mov_epi64(mulb[11], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res32 = fma52lo(res32, a[13], a[19]); // Sum(32) + res33 = fma52hi(res33, a[13], a[19]); // Sum(32) + res33 = fma52lo(res33, a[14], a[19]); // Sum(33) + res34 = fma52hi(res34, a[14], a[19]); // Sum(33) + res34 = fma52lo(res34, a[15], a[19]); // Sum(34) + res35 = fma52hi(res35, a[15], a[19]); // Sum(34) + res35 = fma52lo(res35, a[16], a[19]); // Sum(35) + res36 = fma52hi(res36, a[16], a[19]); // Sum(35) + res24 = add64(res24, res24); // Double(24) + res25 = add64(res25, res25); // Double(25) + res26 = add64(res26, res26); // Double(26) + res27 = add64(res27, res27); // Double(27) + res28 = add64(res28, res28); // Double(28) + res29 = add64(res29, res29); // Double(29) + res30 = add64(res30, res30); // Double(30) + res31 = add64(res31, res31); // Double(31) + res32 = add64(res32, res32); // Double(32) + res33 = add64(res33, res33); // Double(33) + res34 = add64(res34, res34); // Double(34) + res35 = add64(res35, res35); // Double(35) + res24 = fma52lo(res24, a[12], a[12]); // Add sqr(24) + res25 = fma52hi(res25, a[12], a[12]); // Add sqr(24) + res26 = fma52lo(res26, a[13], a[13]); // Add sqr(26) + res27 = fma52hi(res27, a[13], a[13]); // Add sqr(26) + res28 = fma52lo(res28, a[14], a[14]); // Add sqr(28) + res29 = fma52hi(res29, a[14], a[14]); // Add sqr(28) + res30 = fma52lo(res30, a[15], a[15]); // Add sqr(30) + res31 = fma52hi(res31, a[15], a[15]); // Add sqr(30) + res32 = fma52lo(res32, a[16], a[16]); // Add sqr(32) + res33 = fma52hi(res33, a[16], a[16]); // Add sqr(32) + res34 = fma52lo(res34, a[17], a[17]); // Add sqr(34) + res35 = fma52hi(res35, a[17], a[17]); // Add sqr(34) + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[1+4*iter][12]); + mulb[12] = _mm512_mask_mov_epi64(mulb[12], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][13]); + mulb[13] = _mm512_mask_mov_epi64(mulb[13], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][14]); + mulb[14] = _mm512_mask_mov_epi64(mulb[14], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][15]); + mulb[15] = _mm512_mask_mov_epi64(mulb[15], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res36 = fma52lo(res36, a[17], a[19]); // Sum(36) + res37 = fma52hi(res37, a[17], a[19]); // Sum(36) + res37 = fma52lo(res37, a[18], a[19]); // Sum(37) + res38 = fma52hi(res38, a[18], a[19]); // Sum(37) + res36 = add64(res36, res36); // Double(36) + res37 = add64(res37, res37); // Double(37) + res38 = add64(res38, res38); // Double(38) + res36 = fma52lo(res36, a[18], a[18]); // Add sqr(36) + res37 = fma52hi(res37, a[18], a[18]); // Add sqr(36) + res38 = fma52lo(res38, a[19], a[19]); // Add sqr(38) + res39 = fma52hi(res39, a[19], a[19]); // Add sqr(38) + + // Begin Reduction + U64 u0 = mul52lo(res00, mont_constant); + + res00 = fma52lo(res00, u0, m[ 0]); + res01 = fma52hi(res01, u0, m[ 0]); + res01 = fma52lo(res01, u0, m[ 1]); + res02 = fma52hi(res02, u0, m[ 1]); + + res01 = add64(res01, srli64(res00, DIGIT_SIZE)); + U64 u1 = mul52lo(res01, mont_constant); // early multiplication for the reduction of res01 + + res02 = fma52lo(res02, u0, m[ 2]); + res03 = fma52hi(res03, u0, m[ 2]); + res03 = fma52lo(res03, u0, m[ 3]); + res04 = fma52hi(res04, u0, m[ 3]); + res04 = fma52lo(res04, u0, m[ 4]); + res05 = fma52hi(res05, u0, m[ 4]); + res05 = fma52lo(res05, u0, m[ 5]); + res06 = fma52hi(res06, u0, m[ 5]); + res06 = fma52lo(res06, u0, m[ 6]); + res07 = fma52hi(res07, u0, m[ 6]); + res07 = fma52lo(res07, u0, m[ 7]); + res08 = fma52hi(res08, u0, m[ 7]); + res08 = fma52lo(res08, u0, m[ 8]); + res09 = fma52hi(res09, u0, m[ 8]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[1+4*iter][16]); + mulb[16] = _mm512_mask_mov_epi64(mulb[16], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][17]); + mulb[17] = _mm512_mask_mov_epi64(mulb[17], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][18]); + mulb[18] = _mm512_mask_mov_epi64(mulb[18], extract_sel_mask, temp); + temp = loadstream64(MulTbl[1+4*iter][19]); + mulb[19] = _mm512_mask_mov_epi64(mulb[19], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res09 = fma52lo(res09, u0, m[ 9]); + res10 = fma52hi(res10, u0, m[ 9]); + res10 = fma52lo(res10, u0, m[10]); + res11 = fma52hi(res11, u0, m[10]); + res11 = fma52lo(res11, u0, m[11]); + res12 = fma52hi(res12, u0, m[11]); + res12 = fma52lo(res12, u0, m[12]); + res13 = fma52hi(res13, u0, m[12]); + res13 = fma52lo(res13, u0, m[13]); + res14 = fma52hi(res14, u0, m[13]); + res14 = fma52lo(res14, u0, m[14]); + res15 = fma52hi(res15, u0, m[14]); + res15 = fma52lo(res15, u0, m[15]); + res16 = fma52hi(res16, u0, m[15]); + res16 = fma52lo(res16, u0, m[16]); + res17 = fma52hi(res17, u0, m[16]); + res17 = fma52lo(res17, u0, m[17]); + res18 = fma52hi(res18, u0, m[17]); + res18 = fma52lo(res18, u0, m[18]); + res19 = fma52hi(res19, u0, m[18]); + res19 = fma52lo(res19, u0, m[19]); + res20 = fma52hi(res20, u0, m[19]); + res01 = fma52lo(res01, u1, m[ 0]); + res02 = fma52hi(res02, u1, m[ 0]); + res02 = fma52lo(res02, u1, m[ 1]); + res03 = fma52hi(res03, u1, m[ 1]); + + res02 = add64(res02, srli64(res01, DIGIT_SIZE)); + U64 u2 = mul52lo(res02, mont_constant); // early multiplication for the reduction of res02 + + res03 = fma52lo(res03, u1, m[ 2]); + res04 = fma52hi(res04, u1, m[ 2]); + res04 = fma52lo(res04, u1, m[ 3]); + res05 = fma52hi(res05, u1, m[ 3]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[1+4*iter][ 0]); + mulbx[ 0] = _mm512_mask_mov_epi64(mulbx[ 0], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][ 1]); + mulbx[ 1] = _mm512_mask_mov_epi64(mulbx[ 1], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][ 2]); + mulbx[ 2] = _mm512_mask_mov_epi64(mulbx[ 2], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][ 3]); + mulbx[ 3] = _mm512_mask_mov_epi64(mulbx[ 3], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res05 = fma52lo(res05, u1, m[ 4]); + res06 = fma52hi(res06, u1, m[ 4]); + res06 = fma52lo(res06, u1, m[ 5]); + res07 = fma52hi(res07, u1, m[ 5]); + res07 = fma52lo(res07, u1, m[ 6]); + res08 = fma52hi(res08, u1, m[ 6]); + res08 = fma52lo(res08, u1, m[ 7]); + res09 = fma52hi(res09, u1, m[ 7]); + res09 = fma52lo(res09, u1, m[ 8]); + res10 = fma52hi(res10, u1, m[ 8]); + res10 = fma52lo(res10, u1, m[ 9]); + res11 = fma52hi(res11, u1, m[ 9]); + res11 = fma52lo(res11, u1, m[10]); + res12 = fma52hi(res12, u1, m[10]); + res12 = fma52lo(res12, u1, m[11]); + res13 = fma52hi(res13, u1, m[11]); + res13 = fma52lo(res13, u1, m[12]); + res14 = fma52hi(res14, u1, m[12]); + res14 = fma52lo(res14, u1, m[13]); + res15 = fma52hi(res15, u1, m[13]); + res15 = fma52lo(res15, u1, m[14]); + res16 = fma52hi(res16, u1, m[14]); + res16 = fma52lo(res16, u1, m[15]); + res17 = fma52hi(res17, u1, m[15]); + res17 = fma52lo(res17, u1, m[16]); + res18 = fma52hi(res18, u1, m[16]); + res18 = fma52lo(res18, u1, m[17]); + res19 = fma52hi(res19, u1, m[17]); + res19 = fma52lo(res19, u1, m[18]); + res20 = fma52hi(res20, u1, m[18]); + res20 = fma52lo(res20, u1, m[19]); + res21 = fma52hi(res21, u1, m[19]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[1+4*iter][ 4]); + mulbx[ 4] = _mm512_mask_mov_epi64(mulbx[ 4], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][ 5]); + mulbx[ 5] = _mm512_mask_mov_epi64(mulbx[ 5], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][ 6]); + mulbx[ 6] = _mm512_mask_mov_epi64(mulbx[ 6], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][ 7]); + mulbx[ 7] = _mm512_mask_mov_epi64(mulbx[ 7], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res02 = fma52lo(res02, u2, m[ 0]); + res03 = fma52hi(res03, u2, m[ 0]); + res03 = fma52lo(res03, u2, m[ 1]); + res04 = fma52hi(res04, u2, m[ 1]); + + res03 = add64(res03, srli64(res02, DIGIT_SIZE)); + U64 u3 = mul52lo(res03, mont_constant); // early multiplication for the reduction of res03 + + res04 = fma52lo(res04, u2, m[ 2]); + res05 = fma52hi(res05, u2, m[ 2]); + res05 = fma52lo(res05, u2, m[ 3]); + res06 = fma52hi(res06, u2, m[ 3]); + res06 = fma52lo(res06, u2, m[ 4]); + res07 = fma52hi(res07, u2, m[ 4]); + res07 = fma52lo(res07, u2, m[ 5]); + res08 = fma52hi(res08, u2, m[ 5]); + res08 = fma52lo(res08, u2, m[ 6]); + res09 = fma52hi(res09, u2, m[ 6]); + res09 = fma52lo(res09, u2, m[ 7]); + res10 = fma52hi(res10, u2, m[ 7]); + res10 = fma52lo(res10, u2, m[ 8]); + res11 = fma52hi(res11, u2, m[ 8]); + res11 = fma52lo(res11, u2, m[ 9]); + res12 = fma52hi(res12, u2, m[ 9]); + res12 = fma52lo(res12, u2, m[10]); + res13 = fma52hi(res13, u2, m[10]); + res13 = fma52lo(res13, u2, m[11]); + res14 = fma52hi(res14, u2, m[11]); + res14 = fma52lo(res14, u2, m[12]); + res15 = fma52hi(res15, u2, m[12]); + res15 = fma52lo(res15, u2, m[13]); + res16 = fma52hi(res16, u2, m[13]); + res16 = fma52lo(res16, u2, m[14]); + res17 = fma52hi(res17, u2, m[14]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[1+4*iter][ 8]); + mulbx[ 8] = _mm512_mask_mov_epi64(mulbx[ 8], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][ 9]); + mulbx[ 9] = _mm512_mask_mov_epi64(mulbx[ 9], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][10]); + mulbx[10] = _mm512_mask_mov_epi64(mulbx[10], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][11]); + mulbx[11] = _mm512_mask_mov_epi64(mulbx[11], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res17 = fma52lo(res17, u2, m[15]); + res18 = fma52hi(res18, u2, m[15]); + res18 = fma52lo(res18, u2, m[16]); + res19 = fma52hi(res19, u2, m[16]); + res19 = fma52lo(res19, u2, m[17]); + res20 = fma52hi(res20, u2, m[17]); + res20 = fma52lo(res20, u2, m[18]); + res21 = fma52hi(res21, u2, m[18]); + res21 = fma52lo(res21, u2, m[19]); + res22 = fma52hi(res22, u2, m[19]); + res03 = fma52lo(res03, u3, m[ 0]); + res04 = fma52hi(res04, u3, m[ 0]); + res04 = fma52lo(res04, u3, m[ 1]); + res05 = fma52hi(res05, u3, m[ 1]); + + res04 = add64(res04, srli64(res03, DIGIT_SIZE)); + U64 u4 = mul52lo(res04, mont_constant); // early multiplication for the reduction of res04 + + res05 = fma52lo(res05, u3, m[ 2]); + res06 = fma52hi(res06, u3, m[ 2]); + res06 = fma52lo(res06, u3, m[ 3]); + res07 = fma52hi(res07, u3, m[ 3]); + res07 = fma52lo(res07, u3, m[ 4]); + res08 = fma52hi(res08, u3, m[ 4]); + res08 = fma52lo(res08, u3, m[ 5]); + res09 = fma52hi(res09, u3, m[ 5]); + res09 = fma52lo(res09, u3, m[ 6]); + res10 = fma52hi(res10, u3, m[ 6]); + res10 = fma52lo(res10, u3, m[ 7]); + res11 = fma52hi(res11, u3, m[ 7]); + res11 = fma52lo(res11, u3, m[ 8]); + res12 = fma52hi(res12, u3, m[ 8]); + res12 = fma52lo(res12, u3, m[ 9]); + res13 = fma52hi(res13, u3, m[ 9]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[1+4*iter][12]); + mulbx[12] = _mm512_mask_mov_epi64(mulbx[12], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][13]); + mulbx[13] = _mm512_mask_mov_epi64(mulbx[13], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][14]); + mulbx[14] = _mm512_mask_mov_epi64(mulbx[14], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][15]); + mulbx[15] = _mm512_mask_mov_epi64(mulbx[15], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res13 = fma52lo(res13, u3, m[10]); + res14 = fma52hi(res14, u3, m[10]); + res14 = fma52lo(res14, u3, m[11]); + res15 = fma52hi(res15, u3, m[11]); + res15 = fma52lo(res15, u3, m[12]); + res16 = fma52hi(res16, u3, m[12]); + res16 = fma52lo(res16, u3, m[13]); + res17 = fma52hi(res17, u3, m[13]); + res17 = fma52lo(res17, u3, m[14]); + res18 = fma52hi(res18, u3, m[14]); + res18 = fma52lo(res18, u3, m[15]); + res19 = fma52hi(res19, u3, m[15]); + res19 = fma52lo(res19, u3, m[16]); + res20 = fma52hi(res20, u3, m[16]); + res20 = fma52lo(res20, u3, m[17]); + res21 = fma52hi(res21, u3, m[17]); + res21 = fma52lo(res21, u3, m[18]); + res22 = fma52hi(res22, u3, m[18]); + res22 = fma52lo(res22, u3, m[19]); + res23 = fma52hi(res23, u3, m[19]); + res04 = fma52lo(res04, u4, m[ 0]); + res05 = fma52hi(res05, u4, m[ 0]); + res05 = fma52lo(res05, u4, m[ 1]); + res06 = fma52hi(res06, u4, m[ 1]); + + res05 = add64(res05, srli64(res04, DIGIT_SIZE)); + U64 u5 = mul52lo(res05, mont_constant); // early multiplication for the reduction of res05 + + res06 = fma52lo(res06, u4, m[ 2]); + res07 = fma52hi(res07, u4, m[ 2]); + res07 = fma52lo(res07, u4, m[ 3]); + res08 = fma52hi(res08, u4, m[ 3]); + res08 = fma52lo(res08, u4, m[ 4]); + res09 = fma52hi(res09, u4, m[ 4]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[1+4*iter][16]); + mulbx[16] = _mm512_mask_mov_epi64(mulbx[16], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][17]); + mulbx[17] = _mm512_mask_mov_epi64(mulbx[17], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][18]); + mulbx[18] = _mm512_mask_mov_epi64(mulbx[18], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[1+4*iter][19]); + mulbx[19] = _mm512_mask_mov_epi64(mulbx[19], extract_sel_mask, tempx); + extract_sel_mask = extract_sel_mask_next; + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res09 = fma52lo(res09, u4, m[ 5]); + res10 = fma52hi(res10, u4, m[ 5]); + res10 = fma52lo(res10, u4, m[ 6]); + res11 = fma52hi(res11, u4, m[ 6]); + res11 = fma52lo(res11, u4, m[ 7]); + res12 = fma52hi(res12, u4, m[ 7]); + res12 = fma52lo(res12, u4, m[ 8]); + res13 = fma52hi(res13, u4, m[ 8]); + res13 = fma52lo(res13, u4, m[ 9]); + res14 = fma52hi(res14, u4, m[ 9]); + res14 = fma52lo(res14, u4, m[10]); + res15 = fma52hi(res15, u4, m[10]); + res15 = fma52lo(res15, u4, m[11]); + res16 = fma52hi(res16, u4, m[11]); + res16 = fma52lo(res16, u4, m[12]); + res17 = fma52hi(res17, u4, m[12]); + res17 = fma52lo(res17, u4, m[13]); + res18 = fma52hi(res18, u4, m[13]); + res18 = fma52lo(res18, u4, m[14]); + res19 = fma52hi(res19, u4, m[14]); + res19 = fma52lo(res19, u4, m[15]); + res20 = fma52hi(res20, u4, m[15]); + res20 = fma52lo(res20, u4, m[16]); + res21 = fma52hi(res21, u4, m[16]); + res21 = fma52lo(res21, u4, m[17]); + res22 = fma52hi(res22, u4, m[17]); + res22 = fma52lo(res22, u4, m[18]); + res23 = fma52hi(res23, u4, m[18]); + res23 = fma52lo(res23, u4, m[19]); + res24 = fma52hi(res24, u4, m[19]); + res05 = fma52lo(res05, u5, m[ 0]); + res06 = fma52hi(res06, u5, m[ 0]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + idx_curr = set64(3+4*iter); + extract_sel_mask_next = cmpeq64_mask(idx_curr, idx_target); + temp = loadstream64(MulTbl[2+4*iter][ 0]); + mulb[ 0] = _mm512_mask_mov_epi64(mulb[ 0], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][ 1]); + mulb[ 1] = _mm512_mask_mov_epi64(mulb[ 1], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][ 2]); + mulb[ 2] = _mm512_mask_mov_epi64(mulb[ 2], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][ 3]); + mulb[ 3] = _mm512_mask_mov_epi64(mulb[ 3], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res06 = fma52lo(res06, u5, m[ 1]); + res07 = fma52hi(res07, u5, m[ 1]); + + res06 = add64(res06, srli64(res05, DIGIT_SIZE)); + U64 u6 = mul52lo(res06, mont_constant); // early multiplication for the reduction of res06 + + res07 = fma52lo(res07, u5, m[ 2]); + res08 = fma52hi(res08, u5, m[ 2]); + res08 = fma52lo(res08, u5, m[ 3]); + res09 = fma52hi(res09, u5, m[ 3]); + res09 = fma52lo(res09, u5, m[ 4]); + res10 = fma52hi(res10, u5, m[ 4]); + res10 = fma52lo(res10, u5, m[ 5]); + res11 = fma52hi(res11, u5, m[ 5]); + res11 = fma52lo(res11, u5, m[ 6]); + res12 = fma52hi(res12, u5, m[ 6]); + res12 = fma52lo(res12, u5, m[ 7]); + res13 = fma52hi(res13, u5, m[ 7]); + res13 = fma52lo(res13, u5, m[ 8]); + res14 = fma52hi(res14, u5, m[ 8]); + res14 = fma52lo(res14, u5, m[ 9]); + res15 = fma52hi(res15, u5, m[ 9]); + res15 = fma52lo(res15, u5, m[10]); + res16 = fma52hi(res16, u5, m[10]); + res16 = fma52lo(res16, u5, m[11]); + res17 = fma52hi(res17, u5, m[11]); + res17 = fma52lo(res17, u5, m[12]); + res18 = fma52hi(res18, u5, m[12]); + res18 = fma52lo(res18, u5, m[13]); + res19 = fma52hi(res19, u5, m[13]); + res19 = fma52lo(res19, u5, m[14]); + res20 = fma52hi(res20, u5, m[14]); + res20 = fma52lo(res20, u5, m[15]); + res21 = fma52hi(res21, u5, m[15]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[2+4*iter][ 4]); + mulb[ 4] = _mm512_mask_mov_epi64(mulb[ 4], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][ 5]); + mulb[ 5] = _mm512_mask_mov_epi64(mulb[ 5], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][ 6]); + mulb[ 6] = _mm512_mask_mov_epi64(mulb[ 6], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][ 7]); + mulb[ 7] = _mm512_mask_mov_epi64(mulb[ 7], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res21 = fma52lo(res21, u5, m[16]); + res22 = fma52hi(res22, u5, m[16]); + res22 = fma52lo(res22, u5, m[17]); + res23 = fma52hi(res23, u5, m[17]); + res23 = fma52lo(res23, u5, m[18]); + res24 = fma52hi(res24, u5, m[18]); + res24 = fma52lo(res24, u5, m[19]); + res25 = fma52hi(res25, u5, m[19]); + res06 = fma52lo(res06, u6, m[ 0]); + res07 = fma52hi(res07, u6, m[ 0]); + res07 = fma52lo(res07, u6, m[ 1]); + res08 = fma52hi(res08, u6, m[ 1]); + + res07 = add64(res07, srli64(res06, DIGIT_SIZE)); + U64 u7 = mul52lo(res07, mont_constant); // early multiplication for the reduction of res07 + + res08 = fma52lo(res08, u6, m[ 2]); + res09 = fma52hi(res09, u6, m[ 2]); + res09 = fma52lo(res09, u6, m[ 3]); + res10 = fma52hi(res10, u6, m[ 3]); + res10 = fma52lo(res10, u6, m[ 4]); + res11 = fma52hi(res11, u6, m[ 4]); + res11 = fma52lo(res11, u6, m[ 5]); + res12 = fma52hi(res12, u6, m[ 5]); + res12 = fma52lo(res12, u6, m[ 6]); + res13 = fma52hi(res13, u6, m[ 6]); + res13 = fma52lo(res13, u6, m[ 7]); + res14 = fma52hi(res14, u6, m[ 7]); + res14 = fma52lo(res14, u6, m[ 8]); + res15 = fma52hi(res15, u6, m[ 8]); + res15 = fma52lo(res15, u6, m[ 9]); + res16 = fma52hi(res16, u6, m[ 9]); + res16 = fma52lo(res16, u6, m[10]); + res17 = fma52hi(res17, u6, m[10]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[2+4*iter][ 8]); + mulb[ 8] = _mm512_mask_mov_epi64(mulb[ 8], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][ 9]); + mulb[ 9] = _mm512_mask_mov_epi64(mulb[ 9], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][10]); + mulb[10] = _mm512_mask_mov_epi64(mulb[10], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][11]); + mulb[11] = _mm512_mask_mov_epi64(mulb[11], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res17 = fma52lo(res17, u6, m[11]); + res18 = fma52hi(res18, u6, m[11]); + res18 = fma52lo(res18, u6, m[12]); + res19 = fma52hi(res19, u6, m[12]); + res19 = fma52lo(res19, u6, m[13]); + res20 = fma52hi(res20, u6, m[13]); + res20 = fma52lo(res20, u6, m[14]); + res21 = fma52hi(res21, u6, m[14]); + res21 = fma52lo(res21, u6, m[15]); + res22 = fma52hi(res22, u6, m[15]); + res22 = fma52lo(res22, u6, m[16]); + res23 = fma52hi(res23, u6, m[16]); + res23 = fma52lo(res23, u6, m[17]); + res24 = fma52hi(res24, u6, m[17]); + res24 = fma52lo(res24, u6, m[18]); + res25 = fma52hi(res25, u6, m[18]); + res25 = fma52lo(res25, u6, m[19]); + res26 = fma52hi(res26, u6, m[19]); + res07 = fma52lo(res07, u7, m[ 0]); + res08 = fma52hi(res08, u7, m[ 0]); + res08 = fma52lo(res08, u7, m[ 1]); + res09 = fma52hi(res09, u7, m[ 1]); + + res08 = add64(res08, srli64(res07, DIGIT_SIZE)); + U64 u8 = mul52lo(res08, mont_constant); // early multiplication for the reduction of res08 + + res09 = fma52lo(res09, u7, m[ 2]); + res10 = fma52hi(res10, u7, m[ 2]); + res10 = fma52lo(res10, u7, m[ 3]); + res11 = fma52hi(res11, u7, m[ 3]); + res11 = fma52lo(res11, u7, m[ 4]); + res12 = fma52hi(res12, u7, m[ 4]); + res12 = fma52lo(res12, u7, m[ 5]); + res13 = fma52hi(res13, u7, m[ 5]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[2+4*iter][12]); + mulb[12] = _mm512_mask_mov_epi64(mulb[12], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][13]); + mulb[13] = _mm512_mask_mov_epi64(mulb[13], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][14]); + mulb[14] = _mm512_mask_mov_epi64(mulb[14], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][15]); + mulb[15] = _mm512_mask_mov_epi64(mulb[15], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res13 = fma52lo(res13, u7, m[ 6]); + res14 = fma52hi(res14, u7, m[ 6]); + res14 = fma52lo(res14, u7, m[ 7]); + res15 = fma52hi(res15, u7, m[ 7]); + res15 = fma52lo(res15, u7, m[ 8]); + res16 = fma52hi(res16, u7, m[ 8]); + res16 = fma52lo(res16, u7, m[ 9]); + res17 = fma52hi(res17, u7, m[ 9]); + res17 = fma52lo(res17, u7, m[10]); + res18 = fma52hi(res18, u7, m[10]); + res18 = fma52lo(res18, u7, m[11]); + res19 = fma52hi(res19, u7, m[11]); + res19 = fma52lo(res19, u7, m[12]); + res20 = fma52hi(res20, u7, m[12]); + res20 = fma52lo(res20, u7, m[13]); + res21 = fma52hi(res21, u7, m[13]); + res21 = fma52lo(res21, u7, m[14]); + res22 = fma52hi(res22, u7, m[14]); + res22 = fma52lo(res22, u7, m[15]); + res23 = fma52hi(res23, u7, m[15]); + res23 = fma52lo(res23, u7, m[16]); + res24 = fma52hi(res24, u7, m[16]); + res24 = fma52lo(res24, u7, m[17]); + res25 = fma52hi(res25, u7, m[17]); + res25 = fma52lo(res25, u7, m[18]); + res26 = fma52hi(res26, u7, m[18]); + res26 = fma52lo(res26, u7, m[19]); + res27 = fma52hi(res27, u7, m[19]); + res08 = fma52lo(res08, u8, m[ 0]); + res09 = fma52hi(res09, u8, m[ 0]); + res09 = fma52lo(res09, u8, m[ 1]); + res10 = fma52hi(res10, u8, m[ 1]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[2+4*iter][16]); + mulb[16] = _mm512_mask_mov_epi64(mulb[16], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][17]); + mulb[17] = _mm512_mask_mov_epi64(mulb[17], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][18]); + mulb[18] = _mm512_mask_mov_epi64(mulb[18], extract_sel_mask, temp); + temp = loadstream64(MulTbl[2+4*iter][19]); + mulb[19] = _mm512_mask_mov_epi64(mulb[19], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res09 = add64(res09, srli64(res08, DIGIT_SIZE)); + U64 u9 = mul52lo(res09, mont_constant); // early multiplication for the reduction of res09 + + res10 = fma52lo(res10, u8, m[ 2]); + res11 = fma52hi(res11, u8, m[ 2]); + res11 = fma52lo(res11, u8, m[ 3]); + res12 = fma52hi(res12, u8, m[ 3]); + res12 = fma52lo(res12, u8, m[ 4]); + res13 = fma52hi(res13, u8, m[ 4]); + res13 = fma52lo(res13, u8, m[ 5]); + res14 = fma52hi(res14, u8, m[ 5]); + res14 = fma52lo(res14, u8, m[ 6]); + res15 = fma52hi(res15, u8, m[ 6]); + res15 = fma52lo(res15, u8, m[ 7]); + res16 = fma52hi(res16, u8, m[ 7]); + res16 = fma52lo(res16, u8, m[ 8]); + res17 = fma52hi(res17, u8, m[ 8]); + res17 = fma52lo(res17, u8, m[ 9]); + res18 = fma52hi(res18, u8, m[ 9]); + res18 = fma52lo(res18, u8, m[10]); + res19 = fma52hi(res19, u8, m[10]); + res19 = fma52lo(res19, u8, m[11]); + res20 = fma52hi(res20, u8, m[11]); + res20 = fma52lo(res20, u8, m[12]); + res21 = fma52hi(res21, u8, m[12]); + res21 = fma52lo(res21, u8, m[13]); + res22 = fma52hi(res22, u8, m[13]); + res22 = fma52lo(res22, u8, m[14]); + res23 = fma52hi(res23, u8, m[14]); + res23 = fma52lo(res23, u8, m[15]); + res24 = fma52hi(res24, u8, m[15]); + res24 = fma52lo(res24, u8, m[16]); + res25 = fma52hi(res25, u8, m[16]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[2+4*iter][ 0]); + mulbx[ 0] = _mm512_mask_mov_epi64(mulbx[ 0], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][ 1]); + mulbx[ 1] = _mm512_mask_mov_epi64(mulbx[ 1], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][ 2]); + mulbx[ 2] = _mm512_mask_mov_epi64(mulbx[ 2], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][ 3]); + mulbx[ 3] = _mm512_mask_mov_epi64(mulbx[ 3], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res25 = fma52lo(res25, u8, m[17]); + res26 = fma52hi(res26, u8, m[17]); + res26 = fma52lo(res26, u8, m[18]); + res27 = fma52hi(res27, u8, m[18]); + res27 = fma52lo(res27, u8, m[19]); + res28 = fma52hi(res28, u8, m[19]); + res09 = fma52lo(res09, u9, m[ 0]); + res10 = fma52hi(res10, u9, m[ 0]); + res10 = fma52lo(res10, u9, m[ 1]); + res11 = fma52hi(res11, u9, m[ 1]); + + res10 = add64(res10, srli64(res09, DIGIT_SIZE)); + U64 u10 = mul52lo(res10, mont_constant); // early multiplication for the reduction of res10 + + res11 = fma52lo(res11, u9, m[ 2]); + res12 = fma52hi(res12, u9, m[ 2]); + res12 = fma52lo(res12, u9, m[ 3]); + res13 = fma52hi(res13, u9, m[ 3]); + res13 = fma52lo(res13, u9, m[ 4]); + res14 = fma52hi(res14, u9, m[ 4]); + res14 = fma52lo(res14, u9, m[ 5]); + res15 = fma52hi(res15, u9, m[ 5]); + res15 = fma52lo(res15, u9, m[ 6]); + res16 = fma52hi(res16, u9, m[ 6]); + res16 = fma52lo(res16, u9, m[ 7]); + res17 = fma52hi(res17, u9, m[ 7]); + res17 = fma52lo(res17, u9, m[ 8]); + res18 = fma52hi(res18, u9, m[ 8]); + res18 = fma52lo(res18, u9, m[ 9]); + res19 = fma52hi(res19, u9, m[ 9]); + res19 = fma52lo(res19, u9, m[10]); + res20 = fma52hi(res20, u9, m[10]); + res20 = fma52lo(res20, u9, m[11]); + res21 = fma52hi(res21, u9, m[11]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[2+4*iter][ 4]); + mulbx[ 4] = _mm512_mask_mov_epi64(mulbx[ 4], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][ 5]); + mulbx[ 5] = _mm512_mask_mov_epi64(mulbx[ 5], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][ 6]); + mulbx[ 6] = _mm512_mask_mov_epi64(mulbx[ 6], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][ 7]); + mulbx[ 7] = _mm512_mask_mov_epi64(mulbx[ 7], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res21 = fma52lo(res21, u9, m[12]); + res22 = fma52hi(res22, u9, m[12]); + res22 = fma52lo(res22, u9, m[13]); + res23 = fma52hi(res23, u9, m[13]); + res23 = fma52lo(res23, u9, m[14]); + res24 = fma52hi(res24, u9, m[14]); + res24 = fma52lo(res24, u9, m[15]); + res25 = fma52hi(res25, u9, m[15]); + res25 = fma52lo(res25, u9, m[16]); + res26 = fma52hi(res26, u9, m[16]); + res26 = fma52lo(res26, u9, m[17]); + res27 = fma52hi(res27, u9, m[17]); + res27 = fma52lo(res27, u9, m[18]); + res28 = fma52hi(res28, u9, m[18]); + res28 = fma52lo(res28, u9, m[19]); + res29 = fma52hi(res29, u9, m[19]); + res10 = fma52lo(res10, u10, m[ 0]); + res11 = fma52hi(res11, u10, m[ 0]); + res11 = fma52lo(res11, u10, m[ 1]); + res12 = fma52hi(res12, u10, m[ 1]); + + res11 = add64(res11, srli64(res10, DIGIT_SIZE)); + U64 u11 = mul52lo(res11, mont_constant); // early multiplication for the reduction of res11 + + res12 = fma52lo(res12, u10, m[ 2]); + res13 = fma52hi(res13, u10, m[ 2]); + res13 = fma52lo(res13, u10, m[ 3]); + res14 = fma52hi(res14, u10, m[ 3]); + res14 = fma52lo(res14, u10, m[ 4]); + res15 = fma52hi(res15, u10, m[ 4]); + res15 = fma52lo(res15, u10, m[ 5]); + res16 = fma52hi(res16, u10, m[ 5]); + res16 = fma52lo(res16, u10, m[ 6]); + res17 = fma52hi(res17, u10, m[ 6]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[2+4*iter][ 8]); + mulbx[ 8] = _mm512_mask_mov_epi64(mulbx[ 8], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][ 9]); + mulbx[ 9] = _mm512_mask_mov_epi64(mulbx[ 9], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][10]); + mulbx[10] = _mm512_mask_mov_epi64(mulbx[10], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][11]); + mulbx[11] = _mm512_mask_mov_epi64(mulbx[11], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res17 = fma52lo(res17, u10, m[ 7]); + res18 = fma52hi(res18, u10, m[ 7]); + res18 = fma52lo(res18, u10, m[ 8]); + res19 = fma52hi(res19, u10, m[ 8]); + res19 = fma52lo(res19, u10, m[ 9]); + res20 = fma52hi(res20, u10, m[ 9]); + res20 = fma52lo(res20, u10, m[10]); + res21 = fma52hi(res21, u10, m[10]); + res21 = fma52lo(res21, u10, m[11]); + res22 = fma52hi(res22, u10, m[11]); + res22 = fma52lo(res22, u10, m[12]); + res23 = fma52hi(res23, u10, m[12]); + res23 = fma52lo(res23, u10, m[13]); + res24 = fma52hi(res24, u10, m[13]); + res24 = fma52lo(res24, u10, m[14]); + res25 = fma52hi(res25, u10, m[14]); + res25 = fma52lo(res25, u10, m[15]); + res26 = fma52hi(res26, u10, m[15]); + res26 = fma52lo(res26, u10, m[16]); + res27 = fma52hi(res27, u10, m[16]); + res27 = fma52lo(res27, u10, m[17]); + res28 = fma52hi(res28, u10, m[17]); + res28 = fma52lo(res28, u10, m[18]); + res29 = fma52hi(res29, u10, m[18]); + res29 = fma52lo(res29, u10, m[19]); + res30 = fma52hi(res30, u10, m[19]); + res11 = fma52lo(res11, u11, m[ 0]); + res12 = fma52hi(res12, u11, m[ 0]); + res12 = fma52lo(res12, u11, m[ 1]); + res13 = fma52hi(res13, u11, m[ 1]); + + res12 = add64(res12, srli64(res11, DIGIT_SIZE)); + U64 u12 = mul52lo(res12, mont_constant); // early multiplication for the reduction of res12 + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[2+4*iter][12]); + mulbx[12] = _mm512_mask_mov_epi64(mulbx[12], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][13]); + mulbx[13] = _mm512_mask_mov_epi64(mulbx[13], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][14]); + mulbx[14] = _mm512_mask_mov_epi64(mulbx[14], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][15]); + mulbx[15] = _mm512_mask_mov_epi64(mulbx[15], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res13 = fma52lo(res13, u11, m[ 2]); + res14 = fma52hi(res14, u11, m[ 2]); + res14 = fma52lo(res14, u11, m[ 3]); + res15 = fma52hi(res15, u11, m[ 3]); + res15 = fma52lo(res15, u11, m[ 4]); + res16 = fma52hi(res16, u11, m[ 4]); + res16 = fma52lo(res16, u11, m[ 5]); + res17 = fma52hi(res17, u11, m[ 5]); + res17 = fma52lo(res17, u11, m[ 6]); + res18 = fma52hi(res18, u11, m[ 6]); + res18 = fma52lo(res18, u11, m[ 7]); + res19 = fma52hi(res19, u11, m[ 7]); + res19 = fma52lo(res19, u11, m[ 8]); + res20 = fma52hi(res20, u11, m[ 8]); + res20 = fma52lo(res20, u11, m[ 9]); + res21 = fma52hi(res21, u11, m[ 9]); + res21 = fma52lo(res21, u11, m[10]); + res22 = fma52hi(res22, u11, m[10]); + res22 = fma52lo(res22, u11, m[11]); + res23 = fma52hi(res23, u11, m[11]); + res23 = fma52lo(res23, u11, m[12]); + res24 = fma52hi(res24, u11, m[12]); + res24 = fma52lo(res24, u11, m[13]); + res25 = fma52hi(res25, u11, m[13]); + res25 = fma52lo(res25, u11, m[14]); + res26 = fma52hi(res26, u11, m[14]); + res26 = fma52lo(res26, u11, m[15]); + res27 = fma52hi(res27, u11, m[15]); + res27 = fma52lo(res27, u11, m[16]); + res28 = fma52hi(res28, u11, m[16]); + res28 = fma52lo(res28, u11, m[17]); + res29 = fma52hi(res29, u11, m[17]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[2+4*iter][16]); + mulbx[16] = _mm512_mask_mov_epi64(mulbx[16], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][17]); + mulbx[17] = _mm512_mask_mov_epi64(mulbx[17], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][18]); + mulbx[18] = _mm512_mask_mov_epi64(mulbx[18], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[2+4*iter][19]); + mulbx[19] = _mm512_mask_mov_epi64(mulbx[19], extract_sel_mask, tempx); + extract_sel_mask = extract_sel_mask_next; + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res29 = fma52lo(res29, u11, m[18]); + res30 = fma52hi(res30, u11, m[18]); + res30 = fma52lo(res30, u11, m[19]); + res31 = fma52hi(res31, u11, m[19]); + res12 = fma52lo(res12, u12, m[ 0]); + res13 = fma52hi(res13, u12, m[ 0]); + res13 = fma52lo(res13, u12, m[ 1]); + res14 = fma52hi(res14, u12, m[ 1]); + + res13 = add64(res13, srli64(res12, DIGIT_SIZE)); + U64 u13 = mul52lo(res13, mont_constant); // early multiplication for the reduction of res13 + + res14 = fma52lo(res14, u12, m[ 2]); + res15 = fma52hi(res15, u12, m[ 2]); + res15 = fma52lo(res15, u12, m[ 3]); + res16 = fma52hi(res16, u12, m[ 3]); + res16 = fma52lo(res16, u12, m[ 4]); + res17 = fma52hi(res17, u12, m[ 4]); + res17 = fma52lo(res17, u12, m[ 5]); + res18 = fma52hi(res18, u12, m[ 5]); + res18 = fma52lo(res18, u12, m[ 6]); + res19 = fma52hi(res19, u12, m[ 6]); + res19 = fma52lo(res19, u12, m[ 7]); + res20 = fma52hi(res20, u12, m[ 7]); + res20 = fma52lo(res20, u12, m[ 8]); + res21 = fma52hi(res21, u12, m[ 8]); + res21 = fma52lo(res21, u12, m[ 9]); + res22 = fma52hi(res22, u12, m[ 9]); + res22 = fma52lo(res22, u12, m[10]); + res23 = fma52hi(res23, u12, m[10]); + res23 = fma52lo(res23, u12, m[11]); + res24 = fma52hi(res24, u12, m[11]); + res24 = fma52lo(res24, u12, m[12]); + res25 = fma52hi(res25, u12, m[12]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + idx_curr = set64(4+4*iter); + extract_sel_mask_next = cmpeq64_mask(idx_curr, idx_target); + temp = loadstream64(MulTbl[3+4*iter][ 0]); + mulb[ 0] = _mm512_mask_mov_epi64(mulb[ 0], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][ 1]); + mulb[ 1] = _mm512_mask_mov_epi64(mulb[ 1], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][ 2]); + mulb[ 2] = _mm512_mask_mov_epi64(mulb[ 2], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][ 3]); + mulb[ 3] = _mm512_mask_mov_epi64(mulb[ 3], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res25 = fma52lo(res25, u12, m[13]); + res26 = fma52hi(res26, u12, m[13]); + res26 = fma52lo(res26, u12, m[14]); + res27 = fma52hi(res27, u12, m[14]); + res27 = fma52lo(res27, u12, m[15]); + res28 = fma52hi(res28, u12, m[15]); + res28 = fma52lo(res28, u12, m[16]); + res29 = fma52hi(res29, u12, m[16]); + res29 = fma52lo(res29, u12, m[17]); + res30 = fma52hi(res30, u12, m[17]); + res30 = fma52lo(res30, u12, m[18]); + res31 = fma52hi(res31, u12, m[18]); + res31 = fma52lo(res31, u12, m[19]); + res32 = fma52hi(res32, u12, m[19]); + res13 = fma52lo(res13, u13, m[ 0]); + res14 = fma52hi(res14, u13, m[ 0]); + res14 = fma52lo(res14, u13, m[ 1]); + res15 = fma52hi(res15, u13, m[ 1]); + + res14 = add64(res14, srli64(res13, DIGIT_SIZE)); + U64 u14 = mul52lo(res14, mont_constant); // early multiplication for the reduction of res14 + + res15 = fma52lo(res15, u13, m[ 2]); + res16 = fma52hi(res16, u13, m[ 2]); + res16 = fma52lo(res16, u13, m[ 3]); + res17 = fma52hi(res17, u13, m[ 3]); + res17 = fma52lo(res17, u13, m[ 4]); + res18 = fma52hi(res18, u13, m[ 4]); + res18 = fma52lo(res18, u13, m[ 5]); + res19 = fma52hi(res19, u13, m[ 5]); + res19 = fma52lo(res19, u13, m[ 6]); + res20 = fma52hi(res20, u13, m[ 6]); + res20 = fma52lo(res20, u13, m[ 7]); + res21 = fma52hi(res21, u13, m[ 7]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[3+4*iter][ 4]); + mulb[ 4] = _mm512_mask_mov_epi64(mulb[ 4], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][ 5]); + mulb[ 5] = _mm512_mask_mov_epi64(mulb[ 5], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][ 6]); + mulb[ 6] = _mm512_mask_mov_epi64(mulb[ 6], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][ 7]); + mulb[ 7] = _mm512_mask_mov_epi64(mulb[ 7], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res21 = fma52lo(res21, u13, m[ 8]); + res22 = fma52hi(res22, u13, m[ 8]); + res22 = fma52lo(res22, u13, m[ 9]); + res23 = fma52hi(res23, u13, m[ 9]); + res23 = fma52lo(res23, u13, m[10]); + res24 = fma52hi(res24, u13, m[10]); + res24 = fma52lo(res24, u13, m[11]); + res25 = fma52hi(res25, u13, m[11]); + res25 = fma52lo(res25, u13, m[12]); + res26 = fma52hi(res26, u13, m[12]); + res26 = fma52lo(res26, u13, m[13]); + res27 = fma52hi(res27, u13, m[13]); + res27 = fma52lo(res27, u13, m[14]); + res28 = fma52hi(res28, u13, m[14]); + res28 = fma52lo(res28, u13, m[15]); + res29 = fma52hi(res29, u13, m[15]); + res29 = fma52lo(res29, u13, m[16]); + res30 = fma52hi(res30, u13, m[16]); + res30 = fma52lo(res30, u13, m[17]); + res31 = fma52hi(res31, u13, m[17]); + res31 = fma52lo(res31, u13, m[18]); + res32 = fma52hi(res32, u13, m[18]); + res32 = fma52lo(res32, u13, m[19]); + res33 = fma52hi(res33, u13, m[19]); + res14 = fma52lo(res14, u14, m[ 0]); + res15 = fma52hi(res15, u14, m[ 0]); + res15 = fma52lo(res15, u14, m[ 1]); + res16 = fma52hi(res16, u14, m[ 1]); + + res15 = add64(res15, srli64(res14, DIGIT_SIZE)); + U64 u15 = mul52lo(res15, mont_constant); // early multiplication for the reduction of res15 + + res16 = fma52lo(res16, u14, m[ 2]); + res17 = fma52hi(res17, u14, m[ 2]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[3+4*iter][ 8]); + mulb[ 8] = _mm512_mask_mov_epi64(mulb[ 8], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][ 9]); + mulb[ 9] = _mm512_mask_mov_epi64(mulb[ 9], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][10]); + mulb[10] = _mm512_mask_mov_epi64(mulb[10], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][11]); + mulb[11] = _mm512_mask_mov_epi64(mulb[11], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res17 = fma52lo(res17, u14, m[ 3]); + res18 = fma52hi(res18, u14, m[ 3]); + res18 = fma52lo(res18, u14, m[ 4]); + res19 = fma52hi(res19, u14, m[ 4]); + res19 = fma52lo(res19, u14, m[ 5]); + res20 = fma52hi(res20, u14, m[ 5]); + res20 = fma52lo(res20, u14, m[ 6]); + res21 = fma52hi(res21, u14, m[ 6]); + res21 = fma52lo(res21, u14, m[ 7]); + res22 = fma52hi(res22, u14, m[ 7]); + res22 = fma52lo(res22, u14, m[ 8]); + res23 = fma52hi(res23, u14, m[ 8]); + res23 = fma52lo(res23, u14, m[ 9]); + res24 = fma52hi(res24, u14, m[ 9]); + res24 = fma52lo(res24, u14, m[10]); + res25 = fma52hi(res25, u14, m[10]); + res25 = fma52lo(res25, u14, m[11]); + res26 = fma52hi(res26, u14, m[11]); + res26 = fma52lo(res26, u14, m[12]); + res27 = fma52hi(res27, u14, m[12]); + res27 = fma52lo(res27, u14, m[13]); + res28 = fma52hi(res28, u14, m[13]); + res28 = fma52lo(res28, u14, m[14]); + res29 = fma52hi(res29, u14, m[14]); + res29 = fma52lo(res29, u14, m[15]); + res30 = fma52hi(res30, u14, m[15]); + res30 = fma52lo(res30, u14, m[16]); + res31 = fma52hi(res31, u14, m[16]); + res31 = fma52lo(res31, u14, m[17]); + res32 = fma52hi(res32, u14, m[17]); + res32 = fma52lo(res32, u14, m[18]); + res33 = fma52hi(res33, u14, m[18]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[3+4*iter][12]); + mulb[12] = _mm512_mask_mov_epi64(mulb[12], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][13]); + mulb[13] = _mm512_mask_mov_epi64(mulb[13], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][14]); + mulb[14] = _mm512_mask_mov_epi64(mulb[14], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][15]); + mulb[15] = _mm512_mask_mov_epi64(mulb[15], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res33 = fma52lo(res33, u14, m[19]); + res34 = fma52hi(res34, u14, m[19]); + res15 = fma52lo(res15, u15, m[ 0]); + res16 = fma52hi(res16, u15, m[ 0]); + res16 = fma52lo(res16, u15, m[ 1]); + res17 = fma52hi(res17, u15, m[ 1]); + + res16 = add64(res16, srli64(res15, DIGIT_SIZE)); + U64 u16 = mul52lo(res16, mont_constant); // early multiplication for the reduction of res16 + + res17 = fma52lo(res17, u15, m[ 2]); + res18 = fma52hi(res18, u15, m[ 2]); + res18 = fma52lo(res18, u15, m[ 3]); + res19 = fma52hi(res19, u15, m[ 3]); + res19 = fma52lo(res19, u15, m[ 4]); + res20 = fma52hi(res20, u15, m[ 4]); + res20 = fma52lo(res20, u15, m[ 5]); + res21 = fma52hi(res21, u15, m[ 5]); + res21 = fma52lo(res21, u15, m[ 6]); + res22 = fma52hi(res22, u15, m[ 6]); + res22 = fma52lo(res22, u15, m[ 7]); + res23 = fma52hi(res23, u15, m[ 7]); + res23 = fma52lo(res23, u15, m[ 8]); + res24 = fma52hi(res24, u15, m[ 8]); + res24 = fma52lo(res24, u15, m[ 9]); + res25 = fma52hi(res25, u15, m[ 9]); + res25 = fma52lo(res25, u15, m[10]); + res26 = fma52hi(res26, u15, m[10]); + res26 = fma52lo(res26, u15, m[11]); + res27 = fma52hi(res27, u15, m[11]); + res27 = fma52lo(res27, u15, m[12]); + res28 = fma52hi(res28, u15, m[12]); + res28 = fma52lo(res28, u15, m[13]); + res29 = fma52hi(res29, u15, m[13]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + temp = loadstream64(MulTbl[3+4*iter][16]); + mulb[16] = _mm512_mask_mov_epi64(mulb[16], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][17]); + mulb[17] = _mm512_mask_mov_epi64(mulb[17], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][18]); + mulb[18] = _mm512_mask_mov_epi64(mulb[18], extract_sel_mask, temp); + temp = loadstream64(MulTbl[3+4*iter][19]); + mulb[19] = _mm512_mask_mov_epi64(mulb[19], extract_sel_mask, temp); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res29 = fma52lo(res29, u15, m[14]); + res30 = fma52hi(res30, u15, m[14]); + res30 = fma52lo(res30, u15, m[15]); + res31 = fma52hi(res31, u15, m[15]); + res31 = fma52lo(res31, u15, m[16]); + res32 = fma52hi(res32, u15, m[16]); + res32 = fma52lo(res32, u15, m[17]); + res33 = fma52hi(res33, u15, m[17]); + res33 = fma52lo(res33, u15, m[18]); + res34 = fma52hi(res34, u15, m[18]); + res34 = fma52lo(res34, u15, m[19]); + res35 = fma52hi(res35, u15, m[19]); + res16 = fma52lo(res16, u16, m[ 0]); + res17 = fma52hi(res17, u16, m[ 0]); + res17 = fma52lo(res17, u16, m[ 1]); + res18 = fma52hi(res18, u16, m[ 1]); + + res17 = add64(res17, srli64(res16, DIGIT_SIZE)); + U64 u17 = mul52lo(res17, mont_constant); // early multiplication for the reduction of res17 + + res18 = fma52lo(res18, u16, m[ 2]); + res19 = fma52hi(res19, u16, m[ 2]); + res19 = fma52lo(res19, u16, m[ 3]); + res20 = fma52hi(res20, u16, m[ 3]); + res20 = fma52lo(res20, u16, m[ 4]); + res21 = fma52hi(res21, u16, m[ 4]); + res21 = fma52lo(res21, u16, m[ 5]); + res22 = fma52hi(res22, u16, m[ 5]); + res22 = fma52lo(res22, u16, m[ 6]); + res23 = fma52hi(res23, u16, m[ 6]); + res23 = fma52lo(res23, u16, m[ 7]); + res24 = fma52hi(res24, u16, m[ 7]); + res24 = fma52lo(res24, u16, m[ 8]); + res25 = fma52hi(res25, u16, m[ 8]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[3+4*iter][ 0]); + mulbx[ 0] = _mm512_mask_mov_epi64(mulbx[ 0], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][ 1]); + mulbx[ 1] = _mm512_mask_mov_epi64(mulbx[ 1], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][ 2]); + mulbx[ 2] = _mm512_mask_mov_epi64(mulbx[ 2], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][ 3]); + mulbx[ 3] = _mm512_mask_mov_epi64(mulbx[ 3], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res25 = fma52lo(res25, u16, m[ 9]); + res26 = fma52hi(res26, u16, m[ 9]); + res26 = fma52lo(res26, u16, m[10]); + res27 = fma52hi(res27, u16, m[10]); + res27 = fma52lo(res27, u16, m[11]); + res28 = fma52hi(res28, u16, m[11]); + res28 = fma52lo(res28, u16, m[12]); + res29 = fma52hi(res29, u16, m[12]); + res29 = fma52lo(res29, u16, m[13]); + res30 = fma52hi(res30, u16, m[13]); + res30 = fma52lo(res30, u16, m[14]); + res31 = fma52hi(res31, u16, m[14]); + res31 = fma52lo(res31, u16, m[15]); + res32 = fma52hi(res32, u16, m[15]); + res32 = fma52lo(res32, u16, m[16]); + res33 = fma52hi(res33, u16, m[16]); + res33 = fma52lo(res33, u16, m[17]); + res34 = fma52hi(res34, u16, m[17]); + res34 = fma52lo(res34, u16, m[18]); + res35 = fma52hi(res35, u16, m[18]); + res35 = fma52lo(res35, u16, m[19]); + res36 = fma52hi(res36, u16, m[19]); + res17 = fma52lo(res17, u17, m[ 0]); + res18 = fma52hi(res18, u17, m[ 0]); + res18 = fma52lo(res18, u17, m[ 1]); + res19 = fma52hi(res19, u17, m[ 1]); + + res18 = add64(res18, srli64(res17, DIGIT_SIZE)); + U64 u18 = mul52lo(res18, mont_constant); // early multiplication for the reduction of res18 + + res19 = fma52lo(res19, u17, m[ 2]); + res20 = fma52hi(res20, u17, m[ 2]); + res20 = fma52lo(res20, u17, m[ 3]); + res21 = fma52hi(res21, u17, m[ 3]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[3+4*iter][ 4]); + mulbx[ 4] = _mm512_mask_mov_epi64(mulbx[ 4], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][ 5]); + mulbx[ 5] = _mm512_mask_mov_epi64(mulbx[ 5], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][ 6]); + mulbx[ 6] = _mm512_mask_mov_epi64(mulbx[ 6], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][ 7]); + mulbx[ 7] = _mm512_mask_mov_epi64(mulbx[ 7], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res21 = fma52lo(res21, u17, m[ 4]); + res22 = fma52hi(res22, u17, m[ 4]); + res22 = fma52lo(res22, u17, m[ 5]); + res23 = fma52hi(res23, u17, m[ 5]); + res23 = fma52lo(res23, u17, m[ 6]); + res24 = fma52hi(res24, u17, m[ 6]); + res24 = fma52lo(res24, u17, m[ 7]); + res25 = fma52hi(res25, u17, m[ 7]); + res25 = fma52lo(res25, u17, m[ 8]); + res26 = fma52hi(res26, u17, m[ 8]); + res26 = fma52lo(res26, u17, m[ 9]); + res27 = fma52hi(res27, u17, m[ 9]); + res27 = fma52lo(res27, u17, m[10]); + res28 = fma52hi(res28, u17, m[10]); + res28 = fma52lo(res28, u17, m[11]); + res29 = fma52hi(res29, u17, m[11]); + res29 = fma52lo(res29, u17, m[12]); + res30 = fma52hi(res30, u17, m[12]); + res30 = fma52lo(res30, u17, m[13]); + res31 = fma52hi(res31, u17, m[13]); + res31 = fma52lo(res31, u17, m[14]); + res32 = fma52hi(res32, u17, m[14]); + res32 = fma52lo(res32, u17, m[15]); + res33 = fma52hi(res33, u17, m[15]); + res33 = fma52lo(res33, u17, m[16]); + res34 = fma52hi(res34, u17, m[16]); + res34 = fma52lo(res34, u17, m[17]); + res35 = fma52hi(res35, u17, m[17]); + res35 = fma52lo(res35, u17, m[18]); + res36 = fma52hi(res36, u17, m[18]); + res36 = fma52lo(res36, u17, m[19]); + res37 = fma52hi(res37, u17, m[19]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[3+4*iter][ 8]); + mulbx[ 8] = _mm512_mask_mov_epi64(mulbx[ 8], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][ 9]); + mulbx[ 9] = _mm512_mask_mov_epi64(mulbx[ 9], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][10]); + mulbx[10] = _mm512_mask_mov_epi64(mulbx[10], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][11]); + mulbx[11] = _mm512_mask_mov_epi64(mulbx[11], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res18 = fma52lo(res18, u18, m[ 0]); + res19 = fma52hi(res19, u18, m[ 0]); + res19 = fma52lo(res19, u18, m[ 1]); + res20 = fma52hi(res20, u18, m[ 1]); + + res19 = add64(res19, srli64(res18, DIGIT_SIZE)); + U64 u19 = mul52lo(res19, mont_constant); // early multiplication for the reduction of res19 + + res20 = fma52lo(res20, u18, m[ 2]); + res21 = fma52hi(res21, u18, m[ 2]); + res21 = fma52lo(res21, u18, m[ 3]); + res22 = fma52hi(res22, u18, m[ 3]); + res22 = fma52lo(res22, u18, m[ 4]); + res23 = fma52hi(res23, u18, m[ 4]); + res23 = fma52lo(res23, u18, m[ 5]); + res24 = fma52hi(res24, u18, m[ 5]); + res24 = fma52lo(res24, u18, m[ 6]); + res25 = fma52hi(res25, u18, m[ 6]); + res25 = fma52lo(res25, u18, m[ 7]); + res26 = fma52hi(res26, u18, m[ 7]); + res26 = fma52lo(res26, u18, m[ 8]); + res27 = fma52hi(res27, u18, m[ 8]); + res27 = fma52lo(res27, u18, m[ 9]); + res28 = fma52hi(res28, u18, m[ 9]); + res28 = fma52lo(res28, u18, m[10]); + res29 = fma52hi(res29, u18, m[10]); + res29 = fma52lo(res29, u18, m[11]); + res30 = fma52hi(res30, u18, m[11]); + res30 = fma52lo(res30, u18, m[12]); + res31 = fma52hi(res31, u18, m[12]); + res31 = fma52lo(res31, u18, m[13]); + res32 = fma52hi(res32, u18, m[13]); + res32 = fma52lo(res32, u18, m[14]); + res33 = fma52hi(res33, u18, m[14]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[3+4*iter][12]); + mulbx[12] = _mm512_mask_mov_epi64(mulbx[12], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][13]); + mulbx[13] = _mm512_mask_mov_epi64(mulbx[13], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][14]); + mulbx[14] = _mm512_mask_mov_epi64(mulbx[14], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][15]); + mulbx[15] = _mm512_mask_mov_epi64(mulbx[15], extract_sel_mask, tempx); + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res33 = fma52lo(res33, u18, m[15]); + res34 = fma52hi(res34, u18, m[15]); + res34 = fma52lo(res34, u18, m[16]); + res35 = fma52hi(res35, u18, m[16]); + res35 = fma52lo(res35, u18, m[17]); + res36 = fma52hi(res36, u18, m[17]); + res36 = fma52lo(res36, u18, m[18]); + res37 = fma52hi(res37, u18, m[18]); + res37 = fma52lo(res37, u18, m[19]); + res38 = fma52hi(res38, u18, m[19]); + res19 = fma52lo(res19, u19, m[ 0]); + res20 = fma52hi(res20, u19, m[ 0]); + res20 = fma52lo(res20, u19, m[ 1]); + res21 = fma52hi(res21, u19, m[ 1]); + res20 = add64(res20, srli64(res19, DIGIT_SIZE)); + res21 = fma52lo(res21, u19, m[ 2]); + res22 = fma52hi(res22, u19, m[ 2]); + res22 = fma52lo(res22, u19, m[ 3]); + res23 = fma52hi(res23, u19, m[ 3]); + res23 = fma52lo(res23, u19, m[ 4]); + res24 = fma52hi(res24, u19, m[ 4]); + res24 = fma52lo(res24, u19, m[ 5]); + res25 = fma52hi(res25, u19, m[ 5]); + res25 = fma52lo(res25, u19, m[ 6]); + res26 = fma52hi(res26, u19, m[ 6]); + res26 = fma52lo(res26, u19, m[ 7]); + res27 = fma52hi(res27, u19, m[ 7]); + res27 = fma52lo(res27, u19, m[ 8]); + res28 = fma52hi(res28, u19, m[ 8]); + res28 = fma52lo(res28, u19, m[ 9]); + res29 = fma52hi(res29, u19, m[ 9]); + res29 = fma52lo(res29, u19, m[10]); + //*******END SQUARING CODE SEGMENT**************// + + //*******BEGIN EXTRACTION CODE SEGMENT****************************// + tempx = loadstream64(MulTblx[3+4*iter][16]); + mulbx[16] = _mm512_mask_mov_epi64(mulbx[16], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][17]); + mulbx[17] = _mm512_mask_mov_epi64(mulbx[17], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][18]); + mulbx[18] = _mm512_mask_mov_epi64(mulbx[18], extract_sel_mask, tempx); + tempx = loadstream64(MulTblx[3+4*iter][19]); + mulbx[19] = _mm512_mask_mov_epi64(mulbx[19], extract_sel_mask, tempx); + extract_sel_mask = extract_sel_mask_next; + //*******END EXTRACTION CODE SEGMENT******************************// + + //*******BEGIN SQUARING CODE SEGMENT************// + res30 = fma52hi(res30, u19, m[10]); + res30 = fma52lo(res30, u19, m[11]); + res31 = fma52hi(res31, u19, m[11]); + res31 = fma52lo(res31, u19, m[12]); + res32 = fma52hi(res32, u19, m[12]); + res32 = fma52lo(res32, u19, m[13]); + res33 = fma52hi(res33, u19, m[13]); + res33 = fma52lo(res33, u19, m[14]); + res34 = fma52hi(res34, u19, m[14]); + res34 = fma52lo(res34, u19, m[15]); + res35 = fma52hi(res35, u19, m[15]); + res35 = fma52lo(res35, u19, m[16]); + res36 = fma52hi(res36, u19, m[16]); + res36 = fma52lo(res36, u19, m[17]); + res37 = fma52hi(res37, u19, m[17]); + res37 = fma52lo(res37, u19, m[18]); + res38 = fma52hi(res38, u19, m[18]); + res38 = fma52lo(res38, u19, m[19]); + res39 = fma52hi(res39, u19, m[19]); + + // Normalization + // We do not need to zero out the top bits + // They will not be used by the fma53lo/hi instructios + r[ 0] = res20; + res21 = add64(res21, srli64(res20, DIGIT_SIZE)); + r[ 1] = res21; + res22 = add64(res22, srli64(res21, DIGIT_SIZE)); + r[ 2] = res22; + res23 = add64(res23, srli64(res22, DIGIT_SIZE)); + r[ 3] = res23; + res24 = add64(res24, srli64(res23, DIGIT_SIZE)); + r[ 4] = res24; + res25 = add64(res25, srli64(res24, DIGIT_SIZE)); + r[ 5] = res25; + res26 = add64(res26, srli64(res25, DIGIT_SIZE)); + r[ 6] = res26; + res27 = add64(res27, srli64(res26, DIGIT_SIZE)); + r[ 7] = res27; + res28 = add64(res28, srli64(res27, DIGIT_SIZE)); + r[ 8] = res28; + res29 = add64(res29, srli64(res28, DIGIT_SIZE)); + r[ 9] = res29; + res30 = add64(res30, srli64(res29, DIGIT_SIZE)); + r[10] = res30; + res31 = add64(res31, srli64(res30, DIGIT_SIZE)); + r[11] = res31; + res32 = add64(res32, srli64(res31, DIGIT_SIZE)); + r[12] = res32; + res33 = add64(res33, srli64(res32, DIGIT_SIZE)); + r[13] = res33; + res34 = add64(res34, srli64(res33, DIGIT_SIZE)); + r[14] = res34; + res35 = add64(res35, srli64(res34, DIGIT_SIZE)); + r[15] = res35; + res36 = add64(res36, srli64(res35, DIGIT_SIZE)); + r[16] = res36; + res37 = add64(res37, srli64(res36, DIGIT_SIZE)); + r[17] = res37; + res38 = add64(res38, srli64(res37, DIGIT_SIZE)); + r[18] = res38; + res39 = add64(res39, srli64(res38, DIGIT_SIZE)); + r[19] = res39; + a = (U64*) out_mb; + //*******END SQUARING CODE SEGMENT**************// + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ahmm52x20_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ahmm52x20_mb8.c new file mode 100644 index 000000000..c221f94f2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ahmm52x20_mb8.c @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (C) 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +/* +Almost Half Montgomery Multiplication (AHMM) + +Output: + out_mb : c = A*B*(2^(-20*52)) mod M +Inputs: + inpA_mb : A + inpB_mb : B + inpBx_mb : K = B*(2^(-10*52)) mod M + inpM_mb : M + k0_mb : mont_constant = (-M^(-1) mod 2^(52)) + + AL=A[ 9: 0] + AH=A[19:10] + + C=0 + for i from 0 to 9: + C=C+AL[i]*K+AH[i]*B + T=C[0]*mu // discard T[1] + C=C+T[0]*M // C[0] is zero + C=C>>52 // at each step of the for loop, divide the result by 2^52 + return C +*/ + +void ifma_ahmm52x20_mb8( + int64u *out_mb, const int64u *inpA_mb, const int64u* inpB_mb, const int64u* inpBx_mb, + const int64u* inpM_mb, const int64u* k0_mb) { + + // Temporary Registers to hold 20 52-bit intermediate results + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, + res20; + + // Precomputed Montgomery constant (-M^(-1) mod 2^(52)) + const U64 mont_constant = loadu64(k0_mb); + + // C = 0 + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = res09 = + res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = res18 = res19 = + res20 = get_zero64(); + + U64* A = (U64*) inpA_mb; + U64* M = (U64*) inpM_mb; + U64* mulb = (U64*) inpB_mb; + U64* mulbx = (U64*) inpBx_mb; + + for (int itr = 0; itr < 10; itr++) { + //****************************************************** + // C=C+AL[i]*K+AH[i]*B + //****************************************************** + + // C=C+AH[i]*B + // load AH[i] + const U64 AHi = A[itr+10]; // AH=A[19:10] + res00 = fma52lo(res00, AHi, mulb[ 0]); + res01 = fma52hi(res01, AHi, mulb[ 0]); + res01 = fma52lo(res01, AHi, mulb[ 1]); + res02 = fma52hi(res02, AHi, mulb[ 1]); + res02 = fma52lo(res02, AHi, mulb[ 2]); + res03 = fma52hi(res03, AHi, mulb[ 2]); + res03 = fma52lo(res03, AHi, mulb[ 3]); + res04 = fma52hi(res04, AHi, mulb[ 3]); + res04 = fma52lo(res04, AHi, mulb[ 4]); + res05 = fma52hi(res05, AHi, mulb[ 4]); + res05 = fma52lo(res05, AHi, mulb[ 5]); + res06 = fma52hi(res06, AHi, mulb[ 5]); + res06 = fma52lo(res06, AHi, mulb[ 6]); + res07 = fma52hi(res07, AHi, mulb[ 6]); + res07 = fma52lo(res07, AHi, mulb[ 7]); + res08 = fma52hi(res08, AHi, mulb[ 7]); + res08 = fma52lo(res08, AHi, mulb[ 8]); + res09 = fma52hi(res09, AHi, mulb[ 8]); + res09 = fma52lo(res09, AHi, mulb[ 9]); + res10 = fma52hi(res10, AHi, mulb[ 9]); + res10 = fma52lo(res10, AHi, mulb[10]); + res11 = fma52hi(res11, AHi, mulb[10]); + res11 = fma52lo(res11, AHi, mulb[11]); + res12 = fma52hi(res12, AHi, mulb[11]); + res12 = fma52lo(res12, AHi, mulb[12]); + res13 = fma52hi(res13, AHi, mulb[12]); + res13 = fma52lo(res13, AHi, mulb[13]); + res14 = fma52hi(res14, AHi, mulb[13]); + res14 = fma52lo(res14, AHi, mulb[14]); + res15 = fma52hi(res15, AHi, mulb[14]); + res15 = fma52lo(res15, AHi, mulb[15]); + res16 = fma52hi(res16, AHi, mulb[15]); + res16 = fma52lo(res16, AHi, mulb[16]); + res17 = fma52hi(res17, AHi, mulb[16]); + res17 = fma52lo(res17, AHi, mulb[17]); + res18 = fma52hi(res18, AHi, mulb[17]); + res18 = fma52lo(res18, AHi, mulb[18]); + res19 = fma52hi(res19, AHi, mulb[18]); + res19 = fma52lo(res19, AHi, mulb[19]); + res20 = fma52hi(get_zero64(), AHi, mulb[19]); + + // C=C+AL[i]*K (low part) + // load AL[i] + const U64 ALi = A[itr]; // AL=A[ 9: 0] + res00 = fma52lo(res00, ALi, mulbx[ 0]); + res01 = fma52hi(res01, ALi, mulbx[ 0]); + res01 = fma52lo(res01, ALi, mulbx[ 1]); + res02 = fma52hi(res02, ALi, mulbx[ 1]); + res02 = fma52lo(res02, ALi, mulbx[ 2]); + res03 = fma52hi(res03, ALi, mulbx[ 2]); + res03 = fma52lo(res03, ALi, mulbx[ 3]); + res04 = fma52hi(res04, ALi, mulbx[ 3]); + res04 = fma52lo(res04, ALi, mulbx[ 4]); + res05 = fma52hi(res05, ALi, mulbx[ 4]); + res05 = fma52lo(res05, ALi, mulbx[ 5]); + res06 = fma52hi(res06, ALi, mulbx[ 5]); + res06 = fma52lo(res06, ALi, mulbx[ 6]); + res07 = fma52hi(res07, ALi, mulbx[ 6]); + res07 = fma52lo(res07, ALi, mulbx[ 7]); + res08 = fma52hi(res08, ALi, mulbx[ 7]); + res08 = fma52lo(res08, ALi, mulbx[ 8]); + res09 = fma52hi(res09, ALi, mulbx[ 8]); + res09 = fma52lo(res09, ALi, mulbx[ 9]); + res10 = fma52hi(res10, ALi, mulbx[ 9]); + res10 = fma52lo(res10, ALi, mulbx[10]); + res11 = fma52hi(res11, ALi, mulbx[10]); + res11 = fma52lo(res11, ALi, mulbx[11]); + res12 = fma52hi(res12, ALi, mulbx[11]); + res12 = fma52lo(res12, ALi, mulbx[12]); + res13 = fma52hi(res13, ALi, mulbx[12]); + res13 = fma52lo(res13, ALi, mulbx[13]); + res14 = fma52hi(res14, ALi, mulbx[13]); + res14 = fma52lo(res14, ALi, mulbx[14]); + res15 = fma52hi(res15, ALi, mulbx[14]); + res15 = fma52lo(res15, ALi, mulbx[15]); + res16 = fma52hi(res16, ALi, mulbx[15]); + res16 = fma52lo(res16, ALi, mulbx[16]); + res17 = fma52hi(res17, ALi, mulbx[16]); + res17 = fma52lo(res17, ALi, mulbx[17]); + res18 = fma52hi(res18, ALi, mulbx[17]); + res18 = fma52lo(res18, ALi, mulbx[18]); + res19 = fma52hi(res19, ALi, mulbx[18]); + res19 = fma52lo(res19, ALi, mulbx[19]); + res20 = fma52hi(res20, ALi, mulbx[19]); + // done: C=C+AL[i]*K+AH[i]*B + //****************************************************** + + // T=C[0]*mu + U64 T = fma52lo(get_zero64(), res00, mont_constant); + + // C=C+T[0]*M (low part) + res00 = fma52lo(res00, T, M[ 0]); + + // low 52 (DIGIT_SIZE) bits of res00 are 0 + // high 12 bits are accumulated to res01 (same bit-weight) + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + + res01 = fma52lo(res01, T, M[ 1]); + res00 = fma52hi(res01, T, M[ 0]); + res02 = fma52lo(res02, T, M[ 2]); + res01 = fma52hi(res02, T, M[ 1]); + res03 = fma52lo(res03, T, M[ 3]); + res02 = fma52hi(res03, T, M[ 2]); + res04 = fma52lo(res04, T, M[ 4]); + res03 = fma52hi(res04, T, M[ 3]); + res05 = fma52lo(res05, T, M[ 5]); + res04 = fma52hi(res05, T, M[ 4]); + res06 = fma52lo(res06, T, M[ 6]); + res05 = fma52hi(res06, T, M[ 5]); + res07 = fma52lo(res07, T, M[ 7]); + res06 = fma52hi(res07, T, M[ 6]); + res08 = fma52lo(res08, T, M[ 8]); + res07 = fma52hi(res08, T, M[ 7]); + res09 = fma52lo(res09, T, M[ 9]); + res08 = fma52hi(res09, T, M[ 8]); + res10 = fma52lo(res10, T, M[10]); + res09 = fma52hi(res10, T, M[ 9]); + res11 = fma52lo(res11, T, M[11]); + res10 = fma52hi(res11, T, M[10]); + res12 = fma52lo(res12, T, M[12]); + res11 = fma52hi(res12, T, M[11]); + res13 = fma52lo(res13, T, M[13]); + res12 = fma52hi(res13, T, M[12]); + res14 = fma52lo(res14, T, M[14]); + res13 = fma52hi(res14, T, M[13]); + res15 = fma52lo(res15, T, M[15]); + res14 = fma52hi(res15, T, M[14]); + res16 = fma52lo(res16, T, M[16]); + res15 = fma52hi(res16, T, M[15]); + res17 = fma52lo(res17, T, M[17]); + res16 = fma52hi(res17, T, M[16]); + res18 = fma52lo(res18, T, M[18]); + res17 = fma52hi(res18, T, M[17]); + res19 = fma52lo(res19, T, M[19]); + res18 = fma52hi(res19, T, M[18]); + res19 = fma52hi(res20, T, M[19]); + } + + // Normalization + U64 High_Extra_Bits = srli64(res00, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 0, res00); + + res01 = add64(res01, High_Extra_Bits); + High_Extra_Bits = srli64(res01, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 1, res01); + + res02 = add64(res02, High_Extra_Bits); + High_Extra_Bits = srli64(res02, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 2, res02); + + res03 = add64(res03, High_Extra_Bits); + High_Extra_Bits = srli64(res03, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 3, res03); + + res04 = add64(res04, High_Extra_Bits); + High_Extra_Bits = srli64(res04, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 4, res04); + + res05 = add64(res05, High_Extra_Bits); + High_Extra_Bits = srli64(res05, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 5, res05); + + res06 = add64(res06, High_Extra_Bits); + High_Extra_Bits = srli64(res06, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 6, res06); + + res07 = add64(res07, High_Extra_Bits); + High_Extra_Bits = srli64(res07, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 7, res07); + + res08 = add64(res08, High_Extra_Bits); + High_Extra_Bits = srli64(res08, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 8, res08); + + res09 = add64(res09, High_Extra_Bits); + High_Extra_Bits = srli64(res09, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 9, res09); + + res10 = add64(res10, High_Extra_Bits); + High_Extra_Bits = srli64(res10, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 10, res10); + + res11 = add64(res11, High_Extra_Bits); + High_Extra_Bits = srli64(res11, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 11, res11); + + res12 = add64(res12, High_Extra_Bits); + High_Extra_Bits = srli64(res12, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 12, res12); + + res13 = add64(res13, High_Extra_Bits); + High_Extra_Bits = srli64(res13, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 13, res13); + + res14 = add64(res14, High_Extra_Bits); + High_Extra_Bits = srli64(res14, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 14, res14); + + res15 = add64(res15, High_Extra_Bits); + High_Extra_Bits = srli64(res15, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 15, res15); + + res16 = add64(res16, High_Extra_Bits); + High_Extra_Bits = srli64(res16, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 16, res16); + + res17 = add64(res17, High_Extra_Bits); + High_Extra_Bits = srli64(res17, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 17, res17); + + res18 = add64(res18, High_Extra_Bits); + High_Extra_Bits = srli64(res18, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 18, res18); + + res19 = add64(res19, High_Extra_Bits); + storeu64(out_mb + MB_WIDTH * 19, res19); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ahmr52x20_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ahmr52x20_mb8.c new file mode 100644 index 000000000..6f166f109 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ahmr52x20_mb8.c @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (C) 2023 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +/* +Almost Half Montgomery Reduction (AHMR) + +Output: + out_mb : C = A*(2^(-10*52)) mod M +Inputs: + inpA_mb : A + inpM_mb : M + k0_mb : mont_constant = (-M^(-1) mod 2^(52)) + + C=A + for i from 0 to 9: + T=C[0]*mu // discard T[1] + C=C+T[0]*M // C[0] is zero + C=C>>52 // at each step of the for loop, divide the result by 2^52 + return C +*/ + + +#include + +void ifma_ahmr52x20_mb8( + int64u* out_mb, const int64u* inpA_mb, const int64u* inpM_mb, const int64u* k0_mb) { + + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19; + + const U64 mont_constant = loadu64(k0_mb); + + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = res09 = + res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = res18 = res19 = get_zero64(); + + // top 12 bits of 64-bit digits of the input A are junk data + // they need to be masked out before the reduction operation + const U64 MASK52 = set64(DIGIT_MASK); + + U64* M = (U64*) inpM_mb; + + // C=A + // res00:res19 are temporary registers holding intermediate result C + res00 = loadu64(inpA_mb + 0*MB_WIDTH); + res00 = and64(res00, MASK52); + res01 = loadu64(inpA_mb + 1*MB_WIDTH); + res01 = and64(res01, MASK52); + res02 = loadu64(inpA_mb + 2*MB_WIDTH); + res02 = and64(res02, MASK52); + res03 = loadu64(inpA_mb + 3*MB_WIDTH); + res03 = and64(res03, MASK52); + res04 = loadu64(inpA_mb + 4*MB_WIDTH); + res04 = and64(res04, MASK52); + res05 = loadu64(inpA_mb + 5*MB_WIDTH); + res05 = and64(res05, MASK52); + res06 = loadu64(inpA_mb + 6*MB_WIDTH); + res06 = and64(res06, MASK52); + res07 = loadu64(inpA_mb + 7*MB_WIDTH); + res07 = and64(res07, MASK52); + res08 = loadu64(inpA_mb + 8*MB_WIDTH); + res08 = and64(res08, MASK52); + res09 = loadu64(inpA_mb + 9*MB_WIDTH); + res09 = and64(res09, MASK52); + res10 = loadu64(inpA_mb +10*MB_WIDTH); + res10 = and64(res10, MASK52); + res11 = loadu64(inpA_mb +11*MB_WIDTH); + res11 = and64(res11, MASK52); + res12 = loadu64(inpA_mb +12*MB_WIDTH); + res12 = and64(res12, MASK52); + res13 = loadu64(inpA_mb +13*MB_WIDTH); + res13 = and64(res13, MASK52); + res14 = loadu64(inpA_mb +14*MB_WIDTH); + res14 = and64(res14, MASK52); + res15 = loadu64(inpA_mb +15*MB_WIDTH); + res15 = and64(res15, MASK52); + res16 = loadu64(inpA_mb +16*MB_WIDTH); + res16 = and64(res16, MASK52); + res17 = loadu64(inpA_mb +17*MB_WIDTH); + res17 = and64(res17, MASK52); + res18 = loadu64(inpA_mb +18*MB_WIDTH); + res18 = and64(res18, MASK52); + res19 = loadu64(inpA_mb +19*MB_WIDTH); + res19 = and64(res19, MASK52); + + for (int itr = 0; itr < 10; itr++) { + // T=C[0]*mu + const U64 T = fma52lo(get_zero64(), res00, mont_constant); + + // C=C+T[0]*M (low part) + res00 = fma52lo(res00, T, M[ 0]); + + // low 52 (DIGIT_SIZE) bits of res00 are 0 + // high 12 bits are accumulated to res01 (same bit-weight) + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + + res01 = fma52lo(res01, T, M[ 1]); + res00 = fma52hi(res01, T, M[ 0]); + res02 = fma52lo(res02, T, M[ 2]); + res01 = fma52hi(res02, T, M[ 1]); + res03 = fma52lo(res03, T, M[ 3]); + res02 = fma52hi(res03, T, M[ 2]); + res04 = fma52lo(res04, T, M[ 4]); + res03 = fma52hi(res04, T, M[ 3]); + res05 = fma52lo(res05, T, M[ 5]); + res04 = fma52hi(res05, T, M[ 4]); + res06 = fma52lo(res06, T, M[ 6]); + res05 = fma52hi(res06, T, M[ 5]); + res07 = fma52lo(res07, T, M[ 7]); + res06 = fma52hi(res07, T, M[ 6]); + res08 = fma52lo(res08, T, M[ 8]); + res07 = fma52hi(res08, T, M[ 7]); + res09 = fma52lo(res09, T, M[ 9]); + res08 = fma52hi(res09, T, M[ 8]); + res10 = fma52lo(res10, T, M[10]); + res09 = fma52hi(res10, T, M[ 9]); + res11 = fma52lo(res11, T, M[11]); + res10 = fma52hi(res11, T, M[10]); + res12 = fma52lo(res12, T, M[12]); + res11 = fma52hi(res12, T, M[11]); + res13 = fma52lo(res13, T, M[13]); + res12 = fma52hi(res13, T, M[12]); + res14 = fma52lo(res14, T, M[14]); + res13 = fma52hi(res14, T, M[13]); + res15 = fma52lo(res15, T, M[15]); + res14 = fma52hi(res15, T, M[14]); + res16 = fma52lo(res16, T, M[16]); + res15 = fma52hi(res16, T, M[15]); + res17 = fma52lo(res17, T, M[17]); + res16 = fma52hi(res17, T, M[16]); + res18 = fma52lo(res18, T, M[18]); + res17 = fma52hi(res18, T, M[17]); + res19 = fma52lo(res19, T, M[19]); + res18 = fma52hi(res19, T, M[18]); + res19 = fma52hi(get_zero64(), T, M[19]); + } + // Normalization + U64 High_Extra_Bits = srli64(res00, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 0, res00); + + res01 = add64(res01, High_Extra_Bits); + High_Extra_Bits = srli64(res01, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 1, res01); + + res02 = add64(res02, High_Extra_Bits); + High_Extra_Bits = srli64(res02, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 2, res02); + + res03 = add64(res03, High_Extra_Bits); + High_Extra_Bits = srli64(res03, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 3, res03); + + res04 = add64(res04, High_Extra_Bits); + High_Extra_Bits = srli64(res04, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 4, res04); + + res05 = add64(res05, High_Extra_Bits); + High_Extra_Bits = srli64(res05, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 5, res05); + + res06 = add64(res06, High_Extra_Bits); + High_Extra_Bits = srli64(res06, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 6, res06); + + res07 = add64(res07, High_Extra_Bits); + High_Extra_Bits = srli64(res07, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 7, res07); + + res08 = add64(res08, High_Extra_Bits); + High_Extra_Bits = srli64(res08, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 8, res08); + + res09 = add64(res09, High_Extra_Bits); + High_Extra_Bits = srli64(res09, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 9, res09); + + res10 = add64(res10, High_Extra_Bits); + High_Extra_Bits = srli64(res10, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 10, res10); + + res11 = add64(res11, High_Extra_Bits); + High_Extra_Bits = srli64(res11, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 11, res11); + + res12 = add64(res12, High_Extra_Bits); + High_Extra_Bits = srli64(res12, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 12, res12); + + res13 = add64(res13, High_Extra_Bits); + High_Extra_Bits = srli64(res13, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 13, res13); + + res14 = add64(res14, High_Extra_Bits); + High_Extra_Bits = srli64(res14, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 14, res14); + + res15 = add64(res15, High_Extra_Bits); + High_Extra_Bits = srli64(res15, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 15, res15); + + res16 = add64(res16, High_Extra_Bits); + High_Extra_Bits = srli64(res16, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 16, res16); + + res17 = add64(res17, High_Extra_Bits); + High_Extra_Bits = srli64(res17, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 17, res17); + + res18 = add64(res18, High_Extra_Bits); + High_Extra_Bits = srli64(res18, DIGIT_SIZE); + storeu64(out_mb + MB_WIDTH * 18, res18); + + res19 = add64(res19, High_Extra_Bits); + storeu64(out_mb + MB_WIDTH * 19, res19); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x10_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x10_mb8.c new file mode 100644 index 000000000..e97ecf50b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x10_mb8.c @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void ifma_amm52x10_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpB_mb, const int64u *inpM_mb, + const int64u *k0_mb) { + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09; + U64 K = loadu64(k0_mb); + int itr; + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = + res09 = get_zero64(); + + for (itr = 0; itr < 10; itr++) { + U64 Yi; + U64 Bi = loadu64(inpB_mb); + inpB_mb += MB_WIDTH; + fma52lo_mem(res00, res00, Bi, inpA_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Bi, inpA_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Bi, inpA_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Bi, inpA_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Bi, inpA_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Bi, inpA_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Bi, inpA_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Bi, inpA_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Bi, inpA_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Bi, inpA_mb, SIMD_BYTES * 9); + Yi = fma52lo(get_zero64(), res00, K); + fma52lo_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + fma52hi_mem(res00, res01, Bi, inpA_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res02, Bi, inpA_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res03, Bi, inpA_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res04, Bi, inpA_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res05, Bi, inpA_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res06, Bi, inpA_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res07, Bi, inpA_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res08, Bi, inpA_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res09, Bi, inpA_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, get_zero64(), Bi, inpA_mb, SIMD_BYTES * 9); + fma52hi_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + } + // Normalization + { + U64 T = get_zero64(); + U64 MASK = set64(DIGIT_MASK); + T = srli64(res00, DIGIT_SIZE); + res00 = and64(res00, MASK); + storeu64(out_mb + MB_WIDTH * 0, res00); + res01 = add64(res01, T); + T = srli64(res01, DIGIT_SIZE); + res01 = and64(res01, MASK); + storeu64(out_mb + MB_WIDTH * 1, res01); + res02 = add64(res02, T); + T = srli64(res02, DIGIT_SIZE); + res02 = and64(res02, MASK); + storeu64(out_mb + MB_WIDTH * 2, res02); + res03 = add64(res03, T); + T = srli64(res03, DIGIT_SIZE); + res03 = and64(res03, MASK); + storeu64(out_mb + MB_WIDTH * 3, res03); + res04 = add64(res04, T); + T = srli64(res04, DIGIT_SIZE); + res04 = and64(res04, MASK); + storeu64(out_mb + MB_WIDTH * 4, res04); + res05 = add64(res05, T); + T = srli64(res05, DIGIT_SIZE); + res05 = and64(res05, MASK); + storeu64(out_mb + MB_WIDTH * 5, res05); + res06 = add64(res06, T); + T = srli64(res06, DIGIT_SIZE); + res06 = and64(res06, MASK); + storeu64(out_mb + MB_WIDTH * 6, res06); + res07 = add64(res07, T); + T = srli64(res07, DIGIT_SIZE); + res07 = and64(res07, MASK); + storeu64(out_mb + MB_WIDTH * 7, res07); + res08 = add64(res08, T); + T = srli64(res08, DIGIT_SIZE); + res08 = and64(res08, MASK); + storeu64(out_mb + MB_WIDTH * 8, res08); + res09 = add64(res09, T); + res09 = and64(res09, MASK); + storeu64(out_mb + MB_WIDTH * 9, res09); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x20_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x20_mb8.c new file mode 100644 index 000000000..7a513c97a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x20_mb8.c @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void ifma_amm52x20_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpB_mb, const int64u *inpM_mb, + const int64u *k0_mb) { + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19; + U64 K = loadu64(k0_mb); + int itr; + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = + res09 = res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = + res18 = res19 = get_zero64(); + + for (itr = 0; itr < 20; itr++) { + U64 Yi; + U64 Bi = loadu64(inpB_mb); + inpB_mb += MB_WIDTH; + fma52lo_mem(res00, res00, Bi, inpA_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Bi, inpA_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Bi, inpA_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Bi, inpA_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Bi, inpA_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Bi, inpA_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Bi, inpA_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Bi, inpA_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Bi, inpA_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Bi, inpA_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Bi, inpA_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Bi, inpA_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Bi, inpA_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Bi, inpA_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Bi, inpA_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Bi, inpA_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Bi, inpA_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Bi, inpA_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Bi, inpA_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Bi, inpA_mb, SIMD_BYTES * 19); + Yi = fma52lo(get_zero64(), res00, K); + fma52lo_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + fma52hi_mem(res00, res01, Bi, inpA_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res02, Bi, inpA_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res03, Bi, inpA_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res04, Bi, inpA_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res05, Bi, inpA_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res06, Bi, inpA_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res07, Bi, inpA_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res08, Bi, inpA_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res09, Bi, inpA_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res10, Bi, inpA_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res11, Bi, inpA_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res12, Bi, inpA_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res13, Bi, inpA_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res14, Bi, inpA_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res15, Bi, inpA_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res16, Bi, inpA_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res17, Bi, inpA_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res18, Bi, inpA_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res19, Bi, inpA_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, get_zero64(), Bi, inpA_mb, SIMD_BYTES * 19); + fma52hi_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + } + // Normalization + { + U64 T = get_zero64(); + U64 MASK = set64(DIGIT_MASK); + T = srli64(res00, DIGIT_SIZE); + res00 = and64(res00, MASK); + storeu64(out_mb + MB_WIDTH * 0, res00); + res01 = add64(res01, T); + T = srli64(res01, DIGIT_SIZE); + res01 = and64(res01, MASK); + storeu64(out_mb + MB_WIDTH * 1, res01); + res02 = add64(res02, T); + T = srli64(res02, DIGIT_SIZE); + res02 = and64(res02, MASK); + storeu64(out_mb + MB_WIDTH * 2, res02); + res03 = add64(res03, T); + T = srli64(res03, DIGIT_SIZE); + res03 = and64(res03, MASK); + storeu64(out_mb + MB_WIDTH * 3, res03); + res04 = add64(res04, T); + T = srli64(res04, DIGIT_SIZE); + res04 = and64(res04, MASK); + storeu64(out_mb + MB_WIDTH * 4, res04); + res05 = add64(res05, T); + T = srli64(res05, DIGIT_SIZE); + res05 = and64(res05, MASK); + storeu64(out_mb + MB_WIDTH * 5, res05); + res06 = add64(res06, T); + T = srli64(res06, DIGIT_SIZE); + res06 = and64(res06, MASK); + storeu64(out_mb + MB_WIDTH * 6, res06); + res07 = add64(res07, T); + T = srli64(res07, DIGIT_SIZE); + res07 = and64(res07, MASK); + storeu64(out_mb + MB_WIDTH * 7, res07); + res08 = add64(res08, T); + T = srli64(res08, DIGIT_SIZE); + res08 = and64(res08, MASK); + storeu64(out_mb + MB_WIDTH * 8, res08); + res09 = add64(res09, T); + T = srli64(res09, DIGIT_SIZE); + res09 = and64(res09, MASK); + storeu64(out_mb + MB_WIDTH * 9, res09); + res10 = add64(res10, T); + T = srli64(res10, DIGIT_SIZE); + res10 = and64(res10, MASK); + storeu64(out_mb + MB_WIDTH * 10, res10); + res11 = add64(res11, T); + T = srli64(res11, DIGIT_SIZE); + res11 = and64(res11, MASK); + storeu64(out_mb + MB_WIDTH * 11, res11); + res12 = add64(res12, T); + T = srli64(res12, DIGIT_SIZE); + res12 = and64(res12, MASK); + storeu64(out_mb + MB_WIDTH * 12, res12); + res13 = add64(res13, T); + T = srli64(res13, DIGIT_SIZE); + res13 = and64(res13, MASK); + storeu64(out_mb + MB_WIDTH * 13, res13); + res14 = add64(res14, T); + T = srli64(res14, DIGIT_SIZE); + res14 = and64(res14, MASK); + storeu64(out_mb + MB_WIDTH * 14, res14); + res15 = add64(res15, T); + T = srli64(res15, DIGIT_SIZE); + res15 = and64(res15, MASK); + storeu64(out_mb + MB_WIDTH * 15, res15); + res16 = add64(res16, T); + T = srli64(res16, DIGIT_SIZE); + res16 = and64(res16, MASK); + storeu64(out_mb + MB_WIDTH * 16, res16); + res17 = add64(res17, T); + T = srli64(res17, DIGIT_SIZE); + res17 = and64(res17, MASK); + storeu64(out_mb + MB_WIDTH * 17, res17); + res18 = add64(res18, T); + T = srli64(res18, DIGIT_SIZE); + res18 = and64(res18, MASK); + storeu64(out_mb + MB_WIDTH * 18, res18); + res19 = add64(res19, T); + res19 = and64(res19, MASK); + storeu64(out_mb + MB_WIDTH * 19, res19); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x30_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x30_mb8.c new file mode 100644 index 000000000..2f94c67be --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x30_mb8.c @@ -0,0 +1,284 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void ifma_amm52x30_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpB_mb, const int64u *inpM_mb, + const int64u *k0_mb) { + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, + res20, res21, res22, res23, res24, res25, res26, res27, res28, res29; + U64 K = loadu64(k0_mb); + int itr; + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = + res09 = res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = + res18 = res19 = res20 = res21 = res22 = res23 = res24 = res25 = + res26 = res27 = res28 = res29 = get_zero64(); + + for (itr = 0; itr < 30; itr++) { + U64 Yi; + U64 Bi = loadu64(inpB_mb); + inpB_mb += MB_WIDTH; + fma52lo_mem(res00, res00, Bi, inpA_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Bi, inpA_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Bi, inpA_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Bi, inpA_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Bi, inpA_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Bi, inpA_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Bi, inpA_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Bi, inpA_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Bi, inpA_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Bi, inpA_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Bi, inpA_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Bi, inpA_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Bi, inpA_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Bi, inpA_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Bi, inpA_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Bi, inpA_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Bi, inpA_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Bi, inpA_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Bi, inpA_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Bi, inpA_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Bi, inpA_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Bi, inpA_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Bi, inpA_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Bi, inpA_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Bi, inpA_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Bi, inpA_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Bi, inpA_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Bi, inpA_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Bi, inpA_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Bi, inpA_mb, SIMD_BYTES * 29); + Yi = fma52lo(get_zero64(), res00, K); + fma52lo_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + fma52hi_mem(res00, res01, Bi, inpA_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res02, Bi, inpA_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res03, Bi, inpA_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res04, Bi, inpA_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res05, Bi, inpA_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res06, Bi, inpA_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res07, Bi, inpA_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res08, Bi, inpA_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res09, Bi, inpA_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res10, Bi, inpA_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res11, Bi, inpA_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res12, Bi, inpA_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res13, Bi, inpA_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res14, Bi, inpA_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res15, Bi, inpA_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res16, Bi, inpA_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res17, Bi, inpA_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res18, Bi, inpA_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res19, Bi, inpA_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res20, Bi, inpA_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res21, Bi, inpA_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res22, Bi, inpA_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res23, Bi, inpA_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res24, Bi, inpA_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res25, Bi, inpA_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res26, Bi, inpA_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res27, Bi, inpA_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res28, Bi, inpA_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res29, Bi, inpA_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, get_zero64(), Bi, inpA_mb, SIMD_BYTES * 29); + fma52hi_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + } + // Normalization + { + U64 T = get_zero64(); + U64 MASK = set64(DIGIT_MASK); + T = srli64(res00, DIGIT_SIZE); + res00 = and64(res00, MASK); + storeu64(out_mb + MB_WIDTH * 0, res00); + res01 = add64(res01, T); + T = srli64(res01, DIGIT_SIZE); + res01 = and64(res01, MASK); + storeu64(out_mb + MB_WIDTH * 1, res01); + res02 = add64(res02, T); + T = srli64(res02, DIGIT_SIZE); + res02 = and64(res02, MASK); + storeu64(out_mb + MB_WIDTH * 2, res02); + res03 = add64(res03, T); + T = srli64(res03, DIGIT_SIZE); + res03 = and64(res03, MASK); + storeu64(out_mb + MB_WIDTH * 3, res03); + res04 = add64(res04, T); + T = srli64(res04, DIGIT_SIZE); + res04 = and64(res04, MASK); + storeu64(out_mb + MB_WIDTH * 4, res04); + res05 = add64(res05, T); + T = srli64(res05, DIGIT_SIZE); + res05 = and64(res05, MASK); + storeu64(out_mb + MB_WIDTH * 5, res05); + res06 = add64(res06, T); + T = srli64(res06, DIGIT_SIZE); + res06 = and64(res06, MASK); + storeu64(out_mb + MB_WIDTH * 6, res06); + res07 = add64(res07, T); + T = srli64(res07, DIGIT_SIZE); + res07 = and64(res07, MASK); + storeu64(out_mb + MB_WIDTH * 7, res07); + res08 = add64(res08, T); + T = srli64(res08, DIGIT_SIZE); + res08 = and64(res08, MASK); + storeu64(out_mb + MB_WIDTH * 8, res08); + res09 = add64(res09, T); + T = srli64(res09, DIGIT_SIZE); + res09 = and64(res09, MASK); + storeu64(out_mb + MB_WIDTH * 9, res09); + res10 = add64(res10, T); + T = srli64(res10, DIGIT_SIZE); + res10 = and64(res10, MASK); + storeu64(out_mb + MB_WIDTH * 10, res10); + res11 = add64(res11, T); + T = srli64(res11, DIGIT_SIZE); + res11 = and64(res11, MASK); + storeu64(out_mb + MB_WIDTH * 11, res11); + res12 = add64(res12, T); + T = srli64(res12, DIGIT_SIZE); + res12 = and64(res12, MASK); + storeu64(out_mb + MB_WIDTH * 12, res12); + res13 = add64(res13, T); + T = srli64(res13, DIGIT_SIZE); + res13 = and64(res13, MASK); + storeu64(out_mb + MB_WIDTH * 13, res13); + res14 = add64(res14, T); + T = srli64(res14, DIGIT_SIZE); + res14 = and64(res14, MASK); + storeu64(out_mb + MB_WIDTH * 14, res14); + res15 = add64(res15, T); + T = srli64(res15, DIGIT_SIZE); + res15 = and64(res15, MASK); + storeu64(out_mb + MB_WIDTH * 15, res15); + res16 = add64(res16, T); + T = srli64(res16, DIGIT_SIZE); + res16 = and64(res16, MASK); + storeu64(out_mb + MB_WIDTH * 16, res16); + res17 = add64(res17, T); + T = srli64(res17, DIGIT_SIZE); + res17 = and64(res17, MASK); + storeu64(out_mb + MB_WIDTH * 17, res17); + res18 = add64(res18, T); + T = srli64(res18, DIGIT_SIZE); + res18 = and64(res18, MASK); + storeu64(out_mb + MB_WIDTH * 18, res18); + res19 = add64(res19, T); + T = srli64(res19, DIGIT_SIZE); + res19 = and64(res19, MASK); + storeu64(out_mb + MB_WIDTH * 19, res19); + res20 = add64(res20, T); + T = srli64(res20, DIGIT_SIZE); + res20 = and64(res20, MASK); + storeu64(out_mb + MB_WIDTH * 20, res20); + res21 = add64(res21, T); + T = srli64(res21, DIGIT_SIZE); + res21 = and64(res21, MASK); + storeu64(out_mb + MB_WIDTH * 21, res21); + res22 = add64(res22, T); + T = srli64(res22, DIGIT_SIZE); + res22 = and64(res22, MASK); + storeu64(out_mb + MB_WIDTH * 22, res22); + res23 = add64(res23, T); + T = srli64(res23, DIGIT_SIZE); + res23 = and64(res23, MASK); + storeu64(out_mb + MB_WIDTH * 23, res23); + res24 = add64(res24, T); + T = srli64(res24, DIGIT_SIZE); + res24 = and64(res24, MASK); + storeu64(out_mb + MB_WIDTH * 24, res24); + res25 = add64(res25, T); + T = srli64(res25, DIGIT_SIZE); + res25 = and64(res25, MASK); + storeu64(out_mb + MB_WIDTH * 25, res25); + res26 = add64(res26, T); + T = srli64(res26, DIGIT_SIZE); + res26 = and64(res26, MASK); + storeu64(out_mb + MB_WIDTH * 26, res26); + res27 = add64(res27, T); + T = srli64(res27, DIGIT_SIZE); + res27 = and64(res27, MASK); + storeu64(out_mb + MB_WIDTH * 27, res27); + res28 = add64(res28, T); + T = srli64(res28, DIGIT_SIZE); + res28 = and64(res28, MASK); + storeu64(out_mb + MB_WIDTH * 28, res28); + res29 = add64(res29, T); + res29 = and64(res29, MASK); + storeu64(out_mb + MB_WIDTH * 29, res29); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x40_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x40_mb8.c new file mode 100644 index 000000000..9812ec665 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x40_mb8.c @@ -0,0 +1,366 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void ifma_amm52x40_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpB_mb, const int64u *inpM_mb, + const int64u *k0_mb) { + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, + res20, res21, res22, res23, res24, res25, res26, res27, res28, res29, + res30, res31, res32, res33, res34, res35, res36, res37, res38, res39; + U64 K = loadu64(k0_mb); + int itr; + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = + res09 = res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = + res18 = res19 = res20 = res21 = res22 = res23 = res24 = res25 = + res26 = res27 = res28 = res29 = res30 = res31 = res32 = res33 = + res34 = res35 = res36 = res37 = res38 = res39 = get_zero64(); + + for (itr = 0; itr < 40; itr++) { + U64 Yi; + U64 Bi = loadu64(inpB_mb); + inpB_mb += MB_WIDTH; + fma52lo_mem(res00, res00, Bi, inpA_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Bi, inpA_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Bi, inpA_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Bi, inpA_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Bi, inpA_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Bi, inpA_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Bi, inpA_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Bi, inpA_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Bi, inpA_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Bi, inpA_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Bi, inpA_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Bi, inpA_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Bi, inpA_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Bi, inpA_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Bi, inpA_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Bi, inpA_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Bi, inpA_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Bi, inpA_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Bi, inpA_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Bi, inpA_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Bi, inpA_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Bi, inpA_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Bi, inpA_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Bi, inpA_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Bi, inpA_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Bi, inpA_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Bi, inpA_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Bi, inpA_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Bi, inpA_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Bi, inpA_mb, SIMD_BYTES * 29); + fma52lo_mem(res30, res30, Bi, inpA_mb, SIMD_BYTES * 30); + fma52lo_mem(res31, res31, Bi, inpA_mb, SIMD_BYTES * 31); + fma52lo_mem(res32, res32, Bi, inpA_mb, SIMD_BYTES * 32); + fma52lo_mem(res33, res33, Bi, inpA_mb, SIMD_BYTES * 33); + fma52lo_mem(res34, res34, Bi, inpA_mb, SIMD_BYTES * 34); + fma52lo_mem(res35, res35, Bi, inpA_mb, SIMD_BYTES * 35); + fma52lo_mem(res36, res36, Bi, inpA_mb, SIMD_BYTES * 36); + fma52lo_mem(res37, res37, Bi, inpA_mb, SIMD_BYTES * 37); + fma52lo_mem(res38, res38, Bi, inpA_mb, SIMD_BYTES * 38); + fma52lo_mem(res39, res39, Bi, inpA_mb, SIMD_BYTES * 39); + Yi = fma52lo(get_zero64(), res00, K); + fma52lo_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + fma52lo_mem(res30, res30, Yi, inpM_mb, SIMD_BYTES * 30); + fma52lo_mem(res31, res31, Yi, inpM_mb, SIMD_BYTES * 31); + fma52lo_mem(res32, res32, Yi, inpM_mb, SIMD_BYTES * 32); + fma52lo_mem(res33, res33, Yi, inpM_mb, SIMD_BYTES * 33); + fma52lo_mem(res34, res34, Yi, inpM_mb, SIMD_BYTES * 34); + fma52lo_mem(res35, res35, Yi, inpM_mb, SIMD_BYTES * 35); + fma52lo_mem(res36, res36, Yi, inpM_mb, SIMD_BYTES * 36); + fma52lo_mem(res37, res37, Yi, inpM_mb, SIMD_BYTES * 37); + fma52lo_mem(res38, res38, Yi, inpM_mb, SIMD_BYTES * 38); + fma52lo_mem(res39, res39, Yi, inpM_mb, SIMD_BYTES * 39); + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + fma52hi_mem(res00, res01, Bi, inpA_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res02, Bi, inpA_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res03, Bi, inpA_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res04, Bi, inpA_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res05, Bi, inpA_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res06, Bi, inpA_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res07, Bi, inpA_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res08, Bi, inpA_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res09, Bi, inpA_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res10, Bi, inpA_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res11, Bi, inpA_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res12, Bi, inpA_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res13, Bi, inpA_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res14, Bi, inpA_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res15, Bi, inpA_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res16, Bi, inpA_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res17, Bi, inpA_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res18, Bi, inpA_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res19, Bi, inpA_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res20, Bi, inpA_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res21, Bi, inpA_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res22, Bi, inpA_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res23, Bi, inpA_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res24, Bi, inpA_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res25, Bi, inpA_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res26, Bi, inpA_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res27, Bi, inpA_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res28, Bi, inpA_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res29, Bi, inpA_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, res30, Bi, inpA_mb, SIMD_BYTES * 29); + fma52hi_mem(res30, res31, Bi, inpA_mb, SIMD_BYTES * 30); + fma52hi_mem(res31, res32, Bi, inpA_mb, SIMD_BYTES * 31); + fma52hi_mem(res32, res33, Bi, inpA_mb, SIMD_BYTES * 32); + fma52hi_mem(res33, res34, Bi, inpA_mb, SIMD_BYTES * 33); + fma52hi_mem(res34, res35, Bi, inpA_mb, SIMD_BYTES * 34); + fma52hi_mem(res35, res36, Bi, inpA_mb, SIMD_BYTES * 35); + fma52hi_mem(res36, res37, Bi, inpA_mb, SIMD_BYTES * 36); + fma52hi_mem(res37, res38, Bi, inpA_mb, SIMD_BYTES * 37); + fma52hi_mem(res38, res39, Bi, inpA_mb, SIMD_BYTES * 38); + fma52hi_mem(res39, get_zero64(), Bi, inpA_mb, SIMD_BYTES * 39); + fma52hi_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + fma52hi_mem(res30, res30, Yi, inpM_mb, SIMD_BYTES * 30); + fma52hi_mem(res31, res31, Yi, inpM_mb, SIMD_BYTES * 31); + fma52hi_mem(res32, res32, Yi, inpM_mb, SIMD_BYTES * 32); + fma52hi_mem(res33, res33, Yi, inpM_mb, SIMD_BYTES * 33); + fma52hi_mem(res34, res34, Yi, inpM_mb, SIMD_BYTES * 34); + fma52hi_mem(res35, res35, Yi, inpM_mb, SIMD_BYTES * 35); + fma52hi_mem(res36, res36, Yi, inpM_mb, SIMD_BYTES * 36); + fma52hi_mem(res37, res37, Yi, inpM_mb, SIMD_BYTES * 37); + fma52hi_mem(res38, res38, Yi, inpM_mb, SIMD_BYTES * 38); + fma52hi_mem(res39, res39, Yi, inpM_mb, SIMD_BYTES * 39); + } + // Normalization + { + U64 T = get_zero64(); + U64 MASK = set64(DIGIT_MASK); + T = srli64(res00, DIGIT_SIZE); + res00 = and64(res00, MASK); + storeu64(out_mb + MB_WIDTH * 0, res00); + res01 = add64(res01, T); + T = srli64(res01, DIGIT_SIZE); + res01 = and64(res01, MASK); + storeu64(out_mb + MB_WIDTH * 1, res01); + res02 = add64(res02, T); + T = srli64(res02, DIGIT_SIZE); + res02 = and64(res02, MASK); + storeu64(out_mb + MB_WIDTH * 2, res02); + res03 = add64(res03, T); + T = srli64(res03, DIGIT_SIZE); + res03 = and64(res03, MASK); + storeu64(out_mb + MB_WIDTH * 3, res03); + res04 = add64(res04, T); + T = srli64(res04, DIGIT_SIZE); + res04 = and64(res04, MASK); + storeu64(out_mb + MB_WIDTH * 4, res04); + res05 = add64(res05, T); + T = srli64(res05, DIGIT_SIZE); + res05 = and64(res05, MASK); + storeu64(out_mb + MB_WIDTH * 5, res05); + res06 = add64(res06, T); + T = srli64(res06, DIGIT_SIZE); + res06 = and64(res06, MASK); + storeu64(out_mb + MB_WIDTH * 6, res06); + res07 = add64(res07, T); + T = srli64(res07, DIGIT_SIZE); + res07 = and64(res07, MASK); + storeu64(out_mb + MB_WIDTH * 7, res07); + res08 = add64(res08, T); + T = srli64(res08, DIGIT_SIZE); + res08 = and64(res08, MASK); + storeu64(out_mb + MB_WIDTH * 8, res08); + res09 = add64(res09, T); + T = srli64(res09, DIGIT_SIZE); + res09 = and64(res09, MASK); + storeu64(out_mb + MB_WIDTH * 9, res09); + res10 = add64(res10, T); + T = srli64(res10, DIGIT_SIZE); + res10 = and64(res10, MASK); + storeu64(out_mb + MB_WIDTH * 10, res10); + res11 = add64(res11, T); + T = srli64(res11, DIGIT_SIZE); + res11 = and64(res11, MASK); + storeu64(out_mb + MB_WIDTH * 11, res11); + res12 = add64(res12, T); + T = srli64(res12, DIGIT_SIZE); + res12 = and64(res12, MASK); + storeu64(out_mb + MB_WIDTH * 12, res12); + res13 = add64(res13, T); + T = srli64(res13, DIGIT_SIZE); + res13 = and64(res13, MASK); + storeu64(out_mb + MB_WIDTH * 13, res13); + res14 = add64(res14, T); + T = srli64(res14, DIGIT_SIZE); + res14 = and64(res14, MASK); + storeu64(out_mb + MB_WIDTH * 14, res14); + res15 = add64(res15, T); + T = srli64(res15, DIGIT_SIZE); + res15 = and64(res15, MASK); + storeu64(out_mb + MB_WIDTH * 15, res15); + res16 = add64(res16, T); + T = srli64(res16, DIGIT_SIZE); + res16 = and64(res16, MASK); + storeu64(out_mb + MB_WIDTH * 16, res16); + res17 = add64(res17, T); + T = srli64(res17, DIGIT_SIZE); + res17 = and64(res17, MASK); + storeu64(out_mb + MB_WIDTH * 17, res17); + res18 = add64(res18, T); + T = srli64(res18, DIGIT_SIZE); + res18 = and64(res18, MASK); + storeu64(out_mb + MB_WIDTH * 18, res18); + res19 = add64(res19, T); + T = srli64(res19, DIGIT_SIZE); + res19 = and64(res19, MASK); + storeu64(out_mb + MB_WIDTH * 19, res19); + res20 = add64(res20, T); + T = srli64(res20, DIGIT_SIZE); + res20 = and64(res20, MASK); + storeu64(out_mb + MB_WIDTH * 20, res20); + res21 = add64(res21, T); + T = srli64(res21, DIGIT_SIZE); + res21 = and64(res21, MASK); + storeu64(out_mb + MB_WIDTH * 21, res21); + res22 = add64(res22, T); + T = srli64(res22, DIGIT_SIZE); + res22 = and64(res22, MASK); + storeu64(out_mb + MB_WIDTH * 22, res22); + res23 = add64(res23, T); + T = srli64(res23, DIGIT_SIZE); + res23 = and64(res23, MASK); + storeu64(out_mb + MB_WIDTH * 23, res23); + res24 = add64(res24, T); + T = srli64(res24, DIGIT_SIZE); + res24 = and64(res24, MASK); + storeu64(out_mb + MB_WIDTH * 24, res24); + res25 = add64(res25, T); + T = srli64(res25, DIGIT_SIZE); + res25 = and64(res25, MASK); + storeu64(out_mb + MB_WIDTH * 25, res25); + res26 = add64(res26, T); + T = srli64(res26, DIGIT_SIZE); + res26 = and64(res26, MASK); + storeu64(out_mb + MB_WIDTH * 26, res26); + res27 = add64(res27, T); + T = srli64(res27, DIGIT_SIZE); + res27 = and64(res27, MASK); + storeu64(out_mb + MB_WIDTH * 27, res27); + res28 = add64(res28, T); + T = srli64(res28, DIGIT_SIZE); + res28 = and64(res28, MASK); + storeu64(out_mb + MB_WIDTH * 28, res28); + res29 = add64(res29, T); + T = srli64(res29, DIGIT_SIZE); + res29 = and64(res29, MASK); + storeu64(out_mb + MB_WIDTH * 29, res29); + res30 = add64(res30, T); + T = srli64(res30, DIGIT_SIZE); + res30 = and64(res30, MASK); + storeu64(out_mb + MB_WIDTH * 30, res30); + res31 = add64(res31, T); + T = srli64(res31, DIGIT_SIZE); + res31 = and64(res31, MASK); + storeu64(out_mb + MB_WIDTH * 31, res31); + res32 = add64(res32, T); + T = srli64(res32, DIGIT_SIZE); + res32 = and64(res32, MASK); + storeu64(out_mb + MB_WIDTH * 32, res32); + res33 = add64(res33, T); + T = srli64(res33, DIGIT_SIZE); + res33 = and64(res33, MASK); + storeu64(out_mb + MB_WIDTH * 33, res33); + res34 = add64(res34, T); + T = srli64(res34, DIGIT_SIZE); + res34 = and64(res34, MASK); + storeu64(out_mb + MB_WIDTH * 34, res34); + res35 = add64(res35, T); + T = srli64(res35, DIGIT_SIZE); + res35 = and64(res35, MASK); + storeu64(out_mb + MB_WIDTH * 35, res35); + res36 = add64(res36, T); + T = srli64(res36, DIGIT_SIZE); + res36 = and64(res36, MASK); + storeu64(out_mb + MB_WIDTH * 36, res36); + res37 = add64(res37, T); + T = srli64(res37, DIGIT_SIZE); + res37 = and64(res37, MASK); + storeu64(out_mb + MB_WIDTH * 37, res37); + res38 = add64(res38, T); + T = srli64(res38, DIGIT_SIZE); + res38 = and64(res38, MASK); + storeu64(out_mb + MB_WIDTH * 38, res38); + res39 = add64(res39, T); + res39 = and64(res39, MASK); + storeu64(out_mb + MB_WIDTH * 39, res39); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x60_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x60_mb8.c new file mode 100644 index 000000000..2b6f9fbf1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x60_mb8.c @@ -0,0 +1,532 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void ifma_amm52x60_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpB_mb, const int64u *inpM_mb, + const int64u *k0_mb) { + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, + res20, res21, res22, res23, res24, res25, res26, res27, res28, res29, + res30, res31, res32, res33, res34, res35, res36, res37, res38, res39, + res40, res41, res42, res43, res44, res45, res46, res47, res48, res49, + res50, res51, res52, res53, res54, res55, res56, res57, res58, res59; + U64 K = loadu64(k0_mb); + int itr; + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = + res09 = res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = + res18 = res19 = res20 = res21 = res22 = res23 = res24 = res25 = + res26 = res27 = res28 = res29 = res30 = res31 = res32 = res33 = + res34 = res35 = res36 = res37 = res38 = res39 = res40 = + res41 = res42 = res43 = res44 = res45 = res46 = res47 = + res48 = res49 = res50 = res51 = res52 = res53 = + res54 = res55 = res56 = res57 = res58 = res59 = + get_zero64(); + + for (itr = 0; itr < 60; itr++) { + U64 Yi; + U64 Bi = loadu64(inpB_mb); + inpB_mb += MB_WIDTH; + fma52lo_mem(res00, res00, Bi, inpA_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Bi, inpA_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Bi, inpA_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Bi, inpA_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Bi, inpA_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Bi, inpA_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Bi, inpA_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Bi, inpA_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Bi, inpA_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Bi, inpA_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Bi, inpA_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Bi, inpA_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Bi, inpA_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Bi, inpA_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Bi, inpA_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Bi, inpA_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Bi, inpA_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Bi, inpA_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Bi, inpA_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Bi, inpA_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Bi, inpA_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Bi, inpA_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Bi, inpA_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Bi, inpA_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Bi, inpA_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Bi, inpA_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Bi, inpA_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Bi, inpA_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Bi, inpA_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Bi, inpA_mb, SIMD_BYTES * 29); + fma52lo_mem(res30, res30, Bi, inpA_mb, SIMD_BYTES * 30); + fma52lo_mem(res31, res31, Bi, inpA_mb, SIMD_BYTES * 31); + fma52lo_mem(res32, res32, Bi, inpA_mb, SIMD_BYTES * 32); + fma52lo_mem(res33, res33, Bi, inpA_mb, SIMD_BYTES * 33); + fma52lo_mem(res34, res34, Bi, inpA_mb, SIMD_BYTES * 34); + fma52lo_mem(res35, res35, Bi, inpA_mb, SIMD_BYTES * 35); + fma52lo_mem(res36, res36, Bi, inpA_mb, SIMD_BYTES * 36); + fma52lo_mem(res37, res37, Bi, inpA_mb, SIMD_BYTES * 37); + fma52lo_mem(res38, res38, Bi, inpA_mb, SIMD_BYTES * 38); + fma52lo_mem(res39, res39, Bi, inpA_mb, SIMD_BYTES * 39); + fma52lo_mem(res40, res40, Bi, inpA_mb, SIMD_BYTES * 40); + fma52lo_mem(res41, res41, Bi, inpA_mb, SIMD_BYTES * 41); + fma52lo_mem(res42, res42, Bi, inpA_mb, SIMD_BYTES * 42); + fma52lo_mem(res43, res43, Bi, inpA_mb, SIMD_BYTES * 43); + fma52lo_mem(res44, res44, Bi, inpA_mb, SIMD_BYTES * 44); + fma52lo_mem(res45, res45, Bi, inpA_mb, SIMD_BYTES * 45); + fma52lo_mem(res46, res46, Bi, inpA_mb, SIMD_BYTES * 46); + fma52lo_mem(res47, res47, Bi, inpA_mb, SIMD_BYTES * 47); + fma52lo_mem(res48, res48, Bi, inpA_mb, SIMD_BYTES * 48); + fma52lo_mem(res49, res49, Bi, inpA_mb, SIMD_BYTES * 49); + fma52lo_mem(res50, res50, Bi, inpA_mb, SIMD_BYTES * 50); + fma52lo_mem(res51, res51, Bi, inpA_mb, SIMD_BYTES * 51); + fma52lo_mem(res52, res52, Bi, inpA_mb, SIMD_BYTES * 52); + fma52lo_mem(res53, res53, Bi, inpA_mb, SIMD_BYTES * 53); + fma52lo_mem(res54, res54, Bi, inpA_mb, SIMD_BYTES * 54); + fma52lo_mem(res55, res55, Bi, inpA_mb, SIMD_BYTES * 55); + fma52lo_mem(res56, res56, Bi, inpA_mb, SIMD_BYTES * 56); + fma52lo_mem(res57, res57, Bi, inpA_mb, SIMD_BYTES * 57); + fma52lo_mem(res58, res58, Bi, inpA_mb, SIMD_BYTES * 58); + fma52lo_mem(res59, res59, Bi, inpA_mb, SIMD_BYTES * 59); + Yi = fma52lo(get_zero64(), res00, K); + fma52lo_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + fma52lo_mem(res30, res30, Yi, inpM_mb, SIMD_BYTES * 30); + fma52lo_mem(res31, res31, Yi, inpM_mb, SIMD_BYTES * 31); + fma52lo_mem(res32, res32, Yi, inpM_mb, SIMD_BYTES * 32); + fma52lo_mem(res33, res33, Yi, inpM_mb, SIMD_BYTES * 33); + fma52lo_mem(res34, res34, Yi, inpM_mb, SIMD_BYTES * 34); + fma52lo_mem(res35, res35, Yi, inpM_mb, SIMD_BYTES * 35); + fma52lo_mem(res36, res36, Yi, inpM_mb, SIMD_BYTES * 36); + fma52lo_mem(res37, res37, Yi, inpM_mb, SIMD_BYTES * 37); + fma52lo_mem(res38, res38, Yi, inpM_mb, SIMD_BYTES * 38); + fma52lo_mem(res39, res39, Yi, inpM_mb, SIMD_BYTES * 39); + fma52lo_mem(res40, res40, Yi, inpM_mb, SIMD_BYTES * 40); + fma52lo_mem(res41, res41, Yi, inpM_mb, SIMD_BYTES * 41); + fma52lo_mem(res42, res42, Yi, inpM_mb, SIMD_BYTES * 42); + fma52lo_mem(res43, res43, Yi, inpM_mb, SIMD_BYTES * 43); + fma52lo_mem(res44, res44, Yi, inpM_mb, SIMD_BYTES * 44); + fma52lo_mem(res45, res45, Yi, inpM_mb, SIMD_BYTES * 45); + fma52lo_mem(res46, res46, Yi, inpM_mb, SIMD_BYTES * 46); + fma52lo_mem(res47, res47, Yi, inpM_mb, SIMD_BYTES * 47); + fma52lo_mem(res48, res48, Yi, inpM_mb, SIMD_BYTES * 48); + fma52lo_mem(res49, res49, Yi, inpM_mb, SIMD_BYTES * 49); + fma52lo_mem(res50, res50, Yi, inpM_mb, SIMD_BYTES * 50); + fma52lo_mem(res51, res51, Yi, inpM_mb, SIMD_BYTES * 51); + fma52lo_mem(res52, res52, Yi, inpM_mb, SIMD_BYTES * 52); + fma52lo_mem(res53, res53, Yi, inpM_mb, SIMD_BYTES * 53); + fma52lo_mem(res54, res54, Yi, inpM_mb, SIMD_BYTES * 54); + fma52lo_mem(res55, res55, Yi, inpM_mb, SIMD_BYTES * 55); + fma52lo_mem(res56, res56, Yi, inpM_mb, SIMD_BYTES * 56); + fma52lo_mem(res57, res57, Yi, inpM_mb, SIMD_BYTES * 57); + fma52lo_mem(res58, res58, Yi, inpM_mb, SIMD_BYTES * 58); + fma52lo_mem(res59, res59, Yi, inpM_mb, SIMD_BYTES * 59); + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + fma52hi_mem(res00, res01, Bi, inpA_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res02, Bi, inpA_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res03, Bi, inpA_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res04, Bi, inpA_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res05, Bi, inpA_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res06, Bi, inpA_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res07, Bi, inpA_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res08, Bi, inpA_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res09, Bi, inpA_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res10, Bi, inpA_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res11, Bi, inpA_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res12, Bi, inpA_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res13, Bi, inpA_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res14, Bi, inpA_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res15, Bi, inpA_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res16, Bi, inpA_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res17, Bi, inpA_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res18, Bi, inpA_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res19, Bi, inpA_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res20, Bi, inpA_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res21, Bi, inpA_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res22, Bi, inpA_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res23, Bi, inpA_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res24, Bi, inpA_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res25, Bi, inpA_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res26, Bi, inpA_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res27, Bi, inpA_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res28, Bi, inpA_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res29, Bi, inpA_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, res30, Bi, inpA_mb, SIMD_BYTES * 29); + fma52hi_mem(res30, res31, Bi, inpA_mb, SIMD_BYTES * 30); + fma52hi_mem(res31, res32, Bi, inpA_mb, SIMD_BYTES * 31); + fma52hi_mem(res32, res33, Bi, inpA_mb, SIMD_BYTES * 32); + fma52hi_mem(res33, res34, Bi, inpA_mb, SIMD_BYTES * 33); + fma52hi_mem(res34, res35, Bi, inpA_mb, SIMD_BYTES * 34); + fma52hi_mem(res35, res36, Bi, inpA_mb, SIMD_BYTES * 35); + fma52hi_mem(res36, res37, Bi, inpA_mb, SIMD_BYTES * 36); + fma52hi_mem(res37, res38, Bi, inpA_mb, SIMD_BYTES * 37); + fma52hi_mem(res38, res39, Bi, inpA_mb, SIMD_BYTES * 38); + fma52hi_mem(res39, res40, Bi, inpA_mb, SIMD_BYTES * 39); + fma52hi_mem(res40, res41, Bi, inpA_mb, SIMD_BYTES * 40); + fma52hi_mem(res41, res42, Bi, inpA_mb, SIMD_BYTES * 41); + fma52hi_mem(res42, res43, Bi, inpA_mb, SIMD_BYTES * 42); + fma52hi_mem(res43, res44, Bi, inpA_mb, SIMD_BYTES * 43); + fma52hi_mem(res44, res45, Bi, inpA_mb, SIMD_BYTES * 44); + fma52hi_mem(res45, res46, Bi, inpA_mb, SIMD_BYTES * 45); + fma52hi_mem(res46, res47, Bi, inpA_mb, SIMD_BYTES * 46); + fma52hi_mem(res47, res48, Bi, inpA_mb, SIMD_BYTES * 47); + fma52hi_mem(res48, res49, Bi, inpA_mb, SIMD_BYTES * 48); + fma52hi_mem(res49, res50, Bi, inpA_mb, SIMD_BYTES * 49); + fma52hi_mem(res50, res51, Bi, inpA_mb, SIMD_BYTES * 50); + fma52hi_mem(res51, res52, Bi, inpA_mb, SIMD_BYTES * 51); + fma52hi_mem(res52, res53, Bi, inpA_mb, SIMD_BYTES * 52); + fma52hi_mem(res53, res54, Bi, inpA_mb, SIMD_BYTES * 53); + fma52hi_mem(res54, res55, Bi, inpA_mb, SIMD_BYTES * 54); + fma52hi_mem(res55, res56, Bi, inpA_mb, SIMD_BYTES * 55); + fma52hi_mem(res56, res57, Bi, inpA_mb, SIMD_BYTES * 56); + fma52hi_mem(res57, res58, Bi, inpA_mb, SIMD_BYTES * 57); + fma52hi_mem(res58, res59, Bi, inpA_mb, SIMD_BYTES * 58); + fma52hi_mem(res59, get_zero64(), Bi, inpA_mb, SIMD_BYTES * 59); + fma52hi_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + fma52hi_mem(res30, res30, Yi, inpM_mb, SIMD_BYTES * 30); + fma52hi_mem(res31, res31, Yi, inpM_mb, SIMD_BYTES * 31); + fma52hi_mem(res32, res32, Yi, inpM_mb, SIMD_BYTES * 32); + fma52hi_mem(res33, res33, Yi, inpM_mb, SIMD_BYTES * 33); + fma52hi_mem(res34, res34, Yi, inpM_mb, SIMD_BYTES * 34); + fma52hi_mem(res35, res35, Yi, inpM_mb, SIMD_BYTES * 35); + fma52hi_mem(res36, res36, Yi, inpM_mb, SIMD_BYTES * 36); + fma52hi_mem(res37, res37, Yi, inpM_mb, SIMD_BYTES * 37); + fma52hi_mem(res38, res38, Yi, inpM_mb, SIMD_BYTES * 38); + fma52hi_mem(res39, res39, Yi, inpM_mb, SIMD_BYTES * 39); + fma52hi_mem(res40, res40, Yi, inpM_mb, SIMD_BYTES * 40); + fma52hi_mem(res41, res41, Yi, inpM_mb, SIMD_BYTES * 41); + fma52hi_mem(res42, res42, Yi, inpM_mb, SIMD_BYTES * 42); + fma52hi_mem(res43, res43, Yi, inpM_mb, SIMD_BYTES * 43); + fma52hi_mem(res44, res44, Yi, inpM_mb, SIMD_BYTES * 44); + fma52hi_mem(res45, res45, Yi, inpM_mb, SIMD_BYTES * 45); + fma52hi_mem(res46, res46, Yi, inpM_mb, SIMD_BYTES * 46); + fma52hi_mem(res47, res47, Yi, inpM_mb, SIMD_BYTES * 47); + fma52hi_mem(res48, res48, Yi, inpM_mb, SIMD_BYTES * 48); + fma52hi_mem(res49, res49, Yi, inpM_mb, SIMD_BYTES * 49); + fma52hi_mem(res50, res50, Yi, inpM_mb, SIMD_BYTES * 50); + fma52hi_mem(res51, res51, Yi, inpM_mb, SIMD_BYTES * 51); + fma52hi_mem(res52, res52, Yi, inpM_mb, SIMD_BYTES * 52); + fma52hi_mem(res53, res53, Yi, inpM_mb, SIMD_BYTES * 53); + fma52hi_mem(res54, res54, Yi, inpM_mb, SIMD_BYTES * 54); + fma52hi_mem(res55, res55, Yi, inpM_mb, SIMD_BYTES * 55); + fma52hi_mem(res56, res56, Yi, inpM_mb, SIMD_BYTES * 56); + fma52hi_mem(res57, res57, Yi, inpM_mb, SIMD_BYTES * 57); + fma52hi_mem(res58, res58, Yi, inpM_mb, SIMD_BYTES * 58); + fma52hi_mem(res59, res59, Yi, inpM_mb, SIMD_BYTES * 59); + } + // Normalization + { + U64 T = get_zero64(); + U64 MASK = set64(DIGIT_MASK); + T = srli64(res00, DIGIT_SIZE); + res00 = and64(res00, MASK); + storeu64(out_mb + MB_WIDTH * 0, res00); + res01 = add64(res01, T); + T = srli64(res01, DIGIT_SIZE); + res01 = and64(res01, MASK); + storeu64(out_mb + MB_WIDTH * 1, res01); + res02 = add64(res02, T); + T = srli64(res02, DIGIT_SIZE); + res02 = and64(res02, MASK); + storeu64(out_mb + MB_WIDTH * 2, res02); + res03 = add64(res03, T); + T = srli64(res03, DIGIT_SIZE); + res03 = and64(res03, MASK); + storeu64(out_mb + MB_WIDTH * 3, res03); + res04 = add64(res04, T); + T = srli64(res04, DIGIT_SIZE); + res04 = and64(res04, MASK); + storeu64(out_mb + MB_WIDTH * 4, res04); + res05 = add64(res05, T); + T = srli64(res05, DIGIT_SIZE); + res05 = and64(res05, MASK); + storeu64(out_mb + MB_WIDTH * 5, res05); + res06 = add64(res06, T); + T = srli64(res06, DIGIT_SIZE); + res06 = and64(res06, MASK); + storeu64(out_mb + MB_WIDTH * 6, res06); + res07 = add64(res07, T); + T = srli64(res07, DIGIT_SIZE); + res07 = and64(res07, MASK); + storeu64(out_mb + MB_WIDTH * 7, res07); + res08 = add64(res08, T); + T = srli64(res08, DIGIT_SIZE); + res08 = and64(res08, MASK); + storeu64(out_mb + MB_WIDTH * 8, res08); + res09 = add64(res09, T); + T = srli64(res09, DIGIT_SIZE); + res09 = and64(res09, MASK); + storeu64(out_mb + MB_WIDTH * 9, res09); + res10 = add64(res10, T); + T = srli64(res10, DIGIT_SIZE); + res10 = and64(res10, MASK); + storeu64(out_mb + MB_WIDTH * 10, res10); + res11 = add64(res11, T); + T = srli64(res11, DIGIT_SIZE); + res11 = and64(res11, MASK); + storeu64(out_mb + MB_WIDTH * 11, res11); + res12 = add64(res12, T); + T = srli64(res12, DIGIT_SIZE); + res12 = and64(res12, MASK); + storeu64(out_mb + MB_WIDTH * 12, res12); + res13 = add64(res13, T); + T = srli64(res13, DIGIT_SIZE); + res13 = and64(res13, MASK); + storeu64(out_mb + MB_WIDTH * 13, res13); + res14 = add64(res14, T); + T = srli64(res14, DIGIT_SIZE); + res14 = and64(res14, MASK); + storeu64(out_mb + MB_WIDTH * 14, res14); + res15 = add64(res15, T); + T = srli64(res15, DIGIT_SIZE); + res15 = and64(res15, MASK); + storeu64(out_mb + MB_WIDTH * 15, res15); + res16 = add64(res16, T); + T = srli64(res16, DIGIT_SIZE); + res16 = and64(res16, MASK); + storeu64(out_mb + MB_WIDTH * 16, res16); + res17 = add64(res17, T); + T = srli64(res17, DIGIT_SIZE); + res17 = and64(res17, MASK); + storeu64(out_mb + MB_WIDTH * 17, res17); + res18 = add64(res18, T); + T = srli64(res18, DIGIT_SIZE); + res18 = and64(res18, MASK); + storeu64(out_mb + MB_WIDTH * 18, res18); + res19 = add64(res19, T); + T = srli64(res19, DIGIT_SIZE); + res19 = and64(res19, MASK); + storeu64(out_mb + MB_WIDTH * 19, res19); + res20 = add64(res20, T); + T = srli64(res20, DIGIT_SIZE); + res20 = and64(res20, MASK); + storeu64(out_mb + MB_WIDTH * 20, res20); + res21 = add64(res21, T); + T = srli64(res21, DIGIT_SIZE); + res21 = and64(res21, MASK); + storeu64(out_mb + MB_WIDTH * 21, res21); + res22 = add64(res22, T); + T = srli64(res22, DIGIT_SIZE); + res22 = and64(res22, MASK); + storeu64(out_mb + MB_WIDTH * 22, res22); + res23 = add64(res23, T); + T = srli64(res23, DIGIT_SIZE); + res23 = and64(res23, MASK); + storeu64(out_mb + MB_WIDTH * 23, res23); + res24 = add64(res24, T); + T = srli64(res24, DIGIT_SIZE); + res24 = and64(res24, MASK); + storeu64(out_mb + MB_WIDTH * 24, res24); + res25 = add64(res25, T); + T = srli64(res25, DIGIT_SIZE); + res25 = and64(res25, MASK); + storeu64(out_mb + MB_WIDTH * 25, res25); + res26 = add64(res26, T); + T = srli64(res26, DIGIT_SIZE); + res26 = and64(res26, MASK); + storeu64(out_mb + MB_WIDTH * 26, res26); + res27 = add64(res27, T); + T = srli64(res27, DIGIT_SIZE); + res27 = and64(res27, MASK); + storeu64(out_mb + MB_WIDTH * 27, res27); + res28 = add64(res28, T); + T = srli64(res28, DIGIT_SIZE); + res28 = and64(res28, MASK); + storeu64(out_mb + MB_WIDTH * 28, res28); + res29 = add64(res29, T); + T = srli64(res29, DIGIT_SIZE); + res29 = and64(res29, MASK); + storeu64(out_mb + MB_WIDTH * 29, res29); + res30 = add64(res30, T); + T = srli64(res30, DIGIT_SIZE); + res30 = and64(res30, MASK); + storeu64(out_mb + MB_WIDTH * 30, res30); + res31 = add64(res31, T); + T = srli64(res31, DIGIT_SIZE); + res31 = and64(res31, MASK); + storeu64(out_mb + MB_WIDTH * 31, res31); + res32 = add64(res32, T); + T = srli64(res32, DIGIT_SIZE); + res32 = and64(res32, MASK); + storeu64(out_mb + MB_WIDTH * 32, res32); + res33 = add64(res33, T); + T = srli64(res33, DIGIT_SIZE); + res33 = and64(res33, MASK); + storeu64(out_mb + MB_WIDTH * 33, res33); + res34 = add64(res34, T); + T = srli64(res34, DIGIT_SIZE); + res34 = and64(res34, MASK); + storeu64(out_mb + MB_WIDTH * 34, res34); + res35 = add64(res35, T); + T = srli64(res35, DIGIT_SIZE); + res35 = and64(res35, MASK); + storeu64(out_mb + MB_WIDTH * 35, res35); + res36 = add64(res36, T); + T = srli64(res36, DIGIT_SIZE); + res36 = and64(res36, MASK); + storeu64(out_mb + MB_WIDTH * 36, res36); + res37 = add64(res37, T); + T = srli64(res37, DIGIT_SIZE); + res37 = and64(res37, MASK); + storeu64(out_mb + MB_WIDTH * 37, res37); + res38 = add64(res38, T); + T = srli64(res38, DIGIT_SIZE); + res38 = and64(res38, MASK); + storeu64(out_mb + MB_WIDTH * 38, res38); + res39 = add64(res39, T); + T = srli64(res39, DIGIT_SIZE); + res39 = and64(res39, MASK); + storeu64(out_mb + MB_WIDTH * 39, res39); + res40 = add64(res40, T); + T = srli64(res40, DIGIT_SIZE); + res40 = and64(res40, MASK); + storeu64(out_mb + MB_WIDTH * 40, res40); + res41 = add64(res41, T); + T = srli64(res41, DIGIT_SIZE); + res41 = and64(res41, MASK); + storeu64(out_mb + MB_WIDTH * 41, res41); + res42 = add64(res42, T); + T = srli64(res42, DIGIT_SIZE); + res42 = and64(res42, MASK); + storeu64(out_mb + MB_WIDTH * 42, res42); + res43 = add64(res43, T); + T = srli64(res43, DIGIT_SIZE); + res43 = and64(res43, MASK); + storeu64(out_mb + MB_WIDTH * 43, res43); + res44 = add64(res44, T); + T = srli64(res44, DIGIT_SIZE); + res44 = and64(res44, MASK); + storeu64(out_mb + MB_WIDTH * 44, res44); + res45 = add64(res45, T); + T = srli64(res45, DIGIT_SIZE); + res45 = and64(res45, MASK); + storeu64(out_mb + MB_WIDTH * 45, res45); + res46 = add64(res46, T); + T = srli64(res46, DIGIT_SIZE); + res46 = and64(res46, MASK); + storeu64(out_mb + MB_WIDTH * 46, res46); + res47 = add64(res47, T); + T = srli64(res47, DIGIT_SIZE); + res47 = and64(res47, MASK); + storeu64(out_mb + MB_WIDTH * 47, res47); + res48 = add64(res48, T); + T = srli64(res48, DIGIT_SIZE); + res48 = and64(res48, MASK); + storeu64(out_mb + MB_WIDTH * 48, res48); + res49 = add64(res49, T); + T = srli64(res49, DIGIT_SIZE); + res49 = and64(res49, MASK); + storeu64(out_mb + MB_WIDTH * 49, res49); + res50 = add64(res50, T); + T = srli64(res50, DIGIT_SIZE); + res50 = and64(res50, MASK); + storeu64(out_mb + MB_WIDTH * 50, res50); + res51 = add64(res51, T); + T = srli64(res51, DIGIT_SIZE); + res51 = and64(res51, MASK); + storeu64(out_mb + MB_WIDTH * 51, res51); + res52 = add64(res52, T); + T = srli64(res52, DIGIT_SIZE); + res52 = and64(res52, MASK); + storeu64(out_mb + MB_WIDTH * 52, res52); + res53 = add64(res53, T); + T = srli64(res53, DIGIT_SIZE); + res53 = and64(res53, MASK); + storeu64(out_mb + MB_WIDTH * 53, res53); + res54 = add64(res54, T); + T = srli64(res54, DIGIT_SIZE); + res54 = and64(res54, MASK); + storeu64(out_mb + MB_WIDTH * 54, res54); + res55 = add64(res55, T); + T = srli64(res55, DIGIT_SIZE); + res55 = and64(res55, MASK); + storeu64(out_mb + MB_WIDTH * 55, res55); + res56 = add64(res56, T); + T = srli64(res56, DIGIT_SIZE); + res56 = and64(res56, MASK); + storeu64(out_mb + MB_WIDTH * 56, res56); + res57 = add64(res57, T); + T = srli64(res57, DIGIT_SIZE); + res57 = and64(res57, MASK); + storeu64(out_mb + MB_WIDTH * 57, res57); + res58 = add64(res58, T); + T = srli64(res58, DIGIT_SIZE); + res58 = and64(res58, MASK); + storeu64(out_mb + MB_WIDTH * 58, res58); + res59 = add64(res59, T); + res59 = and64(res59, MASK); + storeu64(out_mb + MB_WIDTH * 59, res59); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x79_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x79_mb8.c new file mode 100644 index 000000000..d0a7e5982 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_amm52x79_mb8.c @@ -0,0 +1,690 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void ifma_amm52x79_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpB_mb, const int64u *inpM_mb, + const int64u *k0_mb) { + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, + res20, res21, res22, res23, res24, res25, res26, res27, res28, res29, + res30, res31, res32, res33, res34, res35, res36, res37, res38, res39, + res40, res41, res42, res43, res44, res45, res46, res47, res48, res49, + res50, res51, res52, res53, res54, res55, res56, res57, res58, res59, + res60, res61, res62, res63, res64, res65, res66, res67, res68, res69, + res70, res71, res72, res73, res74, res75, res76, res77, res78; + U64 K = loadu64(k0_mb); + int itr; + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = + res09 = res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = + res18 = res19 = res20 = res21 = res22 = res23 = res24 = res25 = + res26 = res27 = res28 = res29 = res30 = res31 = res32 = res33 = + res34 = res35 = res36 = res37 = res38 = res39 = res40 = + res41 = res42 = res43 = res44 = res45 = res46 = res47 = + res48 = res49 = res50 = res51 = res52 = res53 = + res54 = res55 = res56 = res57 = res58 = res59 = + res60 = res61 = res62 = res63 = res64 = + res65 = res66 = res67 = res68 = res69 = + res70 = res71 = res72 = res73 = + res74 = res75 = res76 = res77 = + res78 = get_zero64(); + + for (itr = 0; itr < 79; itr++) { + U64 Yi; + U64 Bi = loadu64(inpB_mb); + inpB_mb += MB_WIDTH; + fma52lo_mem(res00, res00, Bi, inpA_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Bi, inpA_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Bi, inpA_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Bi, inpA_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Bi, inpA_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Bi, inpA_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Bi, inpA_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Bi, inpA_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Bi, inpA_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Bi, inpA_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Bi, inpA_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Bi, inpA_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Bi, inpA_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Bi, inpA_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Bi, inpA_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Bi, inpA_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Bi, inpA_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Bi, inpA_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Bi, inpA_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Bi, inpA_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Bi, inpA_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Bi, inpA_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Bi, inpA_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Bi, inpA_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Bi, inpA_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Bi, inpA_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Bi, inpA_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Bi, inpA_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Bi, inpA_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Bi, inpA_mb, SIMD_BYTES * 29); + fma52lo_mem(res30, res30, Bi, inpA_mb, SIMD_BYTES * 30); + fma52lo_mem(res31, res31, Bi, inpA_mb, SIMD_BYTES * 31); + fma52lo_mem(res32, res32, Bi, inpA_mb, SIMD_BYTES * 32); + fma52lo_mem(res33, res33, Bi, inpA_mb, SIMD_BYTES * 33); + fma52lo_mem(res34, res34, Bi, inpA_mb, SIMD_BYTES * 34); + fma52lo_mem(res35, res35, Bi, inpA_mb, SIMD_BYTES * 35); + fma52lo_mem(res36, res36, Bi, inpA_mb, SIMD_BYTES * 36); + fma52lo_mem(res37, res37, Bi, inpA_mb, SIMD_BYTES * 37); + fma52lo_mem(res38, res38, Bi, inpA_mb, SIMD_BYTES * 38); + fma52lo_mem(res39, res39, Bi, inpA_mb, SIMD_BYTES * 39); + fma52lo_mem(res40, res40, Bi, inpA_mb, SIMD_BYTES * 40); + fma52lo_mem(res41, res41, Bi, inpA_mb, SIMD_BYTES * 41); + fma52lo_mem(res42, res42, Bi, inpA_mb, SIMD_BYTES * 42); + fma52lo_mem(res43, res43, Bi, inpA_mb, SIMD_BYTES * 43); + fma52lo_mem(res44, res44, Bi, inpA_mb, SIMD_BYTES * 44); + fma52lo_mem(res45, res45, Bi, inpA_mb, SIMD_BYTES * 45); + fma52lo_mem(res46, res46, Bi, inpA_mb, SIMD_BYTES * 46); + fma52lo_mem(res47, res47, Bi, inpA_mb, SIMD_BYTES * 47); + fma52lo_mem(res48, res48, Bi, inpA_mb, SIMD_BYTES * 48); + fma52lo_mem(res49, res49, Bi, inpA_mb, SIMD_BYTES * 49); + fma52lo_mem(res50, res50, Bi, inpA_mb, SIMD_BYTES * 50); + fma52lo_mem(res51, res51, Bi, inpA_mb, SIMD_BYTES * 51); + fma52lo_mem(res52, res52, Bi, inpA_mb, SIMD_BYTES * 52); + fma52lo_mem(res53, res53, Bi, inpA_mb, SIMD_BYTES * 53); + fma52lo_mem(res54, res54, Bi, inpA_mb, SIMD_BYTES * 54); + fma52lo_mem(res55, res55, Bi, inpA_mb, SIMD_BYTES * 55); + fma52lo_mem(res56, res56, Bi, inpA_mb, SIMD_BYTES * 56); + fma52lo_mem(res57, res57, Bi, inpA_mb, SIMD_BYTES * 57); + fma52lo_mem(res58, res58, Bi, inpA_mb, SIMD_BYTES * 58); + fma52lo_mem(res59, res59, Bi, inpA_mb, SIMD_BYTES * 59); + fma52lo_mem(res60, res60, Bi, inpA_mb, SIMD_BYTES * 60); + fma52lo_mem(res61, res61, Bi, inpA_mb, SIMD_BYTES * 61); + fma52lo_mem(res62, res62, Bi, inpA_mb, SIMD_BYTES * 62); + fma52lo_mem(res63, res63, Bi, inpA_mb, SIMD_BYTES * 63); + fma52lo_mem(res64, res64, Bi, inpA_mb, SIMD_BYTES * 64); + fma52lo_mem(res65, res65, Bi, inpA_mb, SIMD_BYTES * 65); + fma52lo_mem(res66, res66, Bi, inpA_mb, SIMD_BYTES * 66); + fma52lo_mem(res67, res67, Bi, inpA_mb, SIMD_BYTES * 67); + fma52lo_mem(res68, res68, Bi, inpA_mb, SIMD_BYTES * 68); + fma52lo_mem(res69, res69, Bi, inpA_mb, SIMD_BYTES * 69); + fma52lo_mem(res70, res70, Bi, inpA_mb, SIMD_BYTES * 70); + fma52lo_mem(res71, res71, Bi, inpA_mb, SIMD_BYTES * 71); + fma52lo_mem(res72, res72, Bi, inpA_mb, SIMD_BYTES * 72); + fma52lo_mem(res73, res73, Bi, inpA_mb, SIMD_BYTES * 73); + fma52lo_mem(res74, res74, Bi, inpA_mb, SIMD_BYTES * 74); + fma52lo_mem(res75, res75, Bi, inpA_mb, SIMD_BYTES * 75); + fma52lo_mem(res76, res76, Bi, inpA_mb, SIMD_BYTES * 76); + fma52lo_mem(res77, res77, Bi, inpA_mb, SIMD_BYTES * 77); + fma52lo_mem(res78, res78, Bi, inpA_mb, SIMD_BYTES * 78); + Yi = fma52lo(get_zero64(), res00, K); + fma52lo_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52lo_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52lo_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52lo_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52lo_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52lo_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52lo_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52lo_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52lo_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52lo_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52lo_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52lo_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52lo_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52lo_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52lo_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52lo_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52lo_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52lo_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52lo_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52lo_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52lo_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52lo_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52lo_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52lo_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52lo_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52lo_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52lo_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52lo_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52lo_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52lo_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + fma52lo_mem(res30, res30, Yi, inpM_mb, SIMD_BYTES * 30); + fma52lo_mem(res31, res31, Yi, inpM_mb, SIMD_BYTES * 31); + fma52lo_mem(res32, res32, Yi, inpM_mb, SIMD_BYTES * 32); + fma52lo_mem(res33, res33, Yi, inpM_mb, SIMD_BYTES * 33); + fma52lo_mem(res34, res34, Yi, inpM_mb, SIMD_BYTES * 34); + fma52lo_mem(res35, res35, Yi, inpM_mb, SIMD_BYTES * 35); + fma52lo_mem(res36, res36, Yi, inpM_mb, SIMD_BYTES * 36); + fma52lo_mem(res37, res37, Yi, inpM_mb, SIMD_BYTES * 37); + fma52lo_mem(res38, res38, Yi, inpM_mb, SIMD_BYTES * 38); + fma52lo_mem(res39, res39, Yi, inpM_mb, SIMD_BYTES * 39); + fma52lo_mem(res40, res40, Yi, inpM_mb, SIMD_BYTES * 40); + fma52lo_mem(res41, res41, Yi, inpM_mb, SIMD_BYTES * 41); + fma52lo_mem(res42, res42, Yi, inpM_mb, SIMD_BYTES * 42); + fma52lo_mem(res43, res43, Yi, inpM_mb, SIMD_BYTES * 43); + fma52lo_mem(res44, res44, Yi, inpM_mb, SIMD_BYTES * 44); + fma52lo_mem(res45, res45, Yi, inpM_mb, SIMD_BYTES * 45); + fma52lo_mem(res46, res46, Yi, inpM_mb, SIMD_BYTES * 46); + fma52lo_mem(res47, res47, Yi, inpM_mb, SIMD_BYTES * 47); + fma52lo_mem(res48, res48, Yi, inpM_mb, SIMD_BYTES * 48); + fma52lo_mem(res49, res49, Yi, inpM_mb, SIMD_BYTES * 49); + fma52lo_mem(res50, res50, Yi, inpM_mb, SIMD_BYTES * 50); + fma52lo_mem(res51, res51, Yi, inpM_mb, SIMD_BYTES * 51); + fma52lo_mem(res52, res52, Yi, inpM_mb, SIMD_BYTES * 52); + fma52lo_mem(res53, res53, Yi, inpM_mb, SIMD_BYTES * 53); + fma52lo_mem(res54, res54, Yi, inpM_mb, SIMD_BYTES * 54); + fma52lo_mem(res55, res55, Yi, inpM_mb, SIMD_BYTES * 55); + fma52lo_mem(res56, res56, Yi, inpM_mb, SIMD_BYTES * 56); + fma52lo_mem(res57, res57, Yi, inpM_mb, SIMD_BYTES * 57); + fma52lo_mem(res58, res58, Yi, inpM_mb, SIMD_BYTES * 58); + fma52lo_mem(res59, res59, Yi, inpM_mb, SIMD_BYTES * 59); + fma52lo_mem(res60, res60, Yi, inpM_mb, SIMD_BYTES * 60); + fma52lo_mem(res61, res61, Yi, inpM_mb, SIMD_BYTES * 61); + fma52lo_mem(res62, res62, Yi, inpM_mb, SIMD_BYTES * 62); + fma52lo_mem(res63, res63, Yi, inpM_mb, SIMD_BYTES * 63); + fma52lo_mem(res64, res64, Yi, inpM_mb, SIMD_BYTES * 64); + fma52lo_mem(res65, res65, Yi, inpM_mb, SIMD_BYTES * 65); + fma52lo_mem(res66, res66, Yi, inpM_mb, SIMD_BYTES * 66); + fma52lo_mem(res67, res67, Yi, inpM_mb, SIMD_BYTES * 67); + fma52lo_mem(res68, res68, Yi, inpM_mb, SIMD_BYTES * 68); + fma52lo_mem(res69, res69, Yi, inpM_mb, SIMD_BYTES * 69); + fma52lo_mem(res70, res70, Yi, inpM_mb, SIMD_BYTES * 70); + fma52lo_mem(res71, res71, Yi, inpM_mb, SIMD_BYTES * 71); + fma52lo_mem(res72, res72, Yi, inpM_mb, SIMD_BYTES * 72); + fma52lo_mem(res73, res73, Yi, inpM_mb, SIMD_BYTES * 73); + fma52lo_mem(res74, res74, Yi, inpM_mb, SIMD_BYTES * 74); + fma52lo_mem(res75, res75, Yi, inpM_mb, SIMD_BYTES * 75); + fma52lo_mem(res76, res76, Yi, inpM_mb, SIMD_BYTES * 76); + fma52lo_mem(res77, res77, Yi, inpM_mb, SIMD_BYTES * 77); + fma52lo_mem(res78, res78, Yi, inpM_mb, SIMD_BYTES * 78); + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + fma52hi_mem(res00, res01, Bi, inpA_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res02, Bi, inpA_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res03, Bi, inpA_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res04, Bi, inpA_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res05, Bi, inpA_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res06, Bi, inpA_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res07, Bi, inpA_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res08, Bi, inpA_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res09, Bi, inpA_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res10, Bi, inpA_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res11, Bi, inpA_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res12, Bi, inpA_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res13, Bi, inpA_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res14, Bi, inpA_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res15, Bi, inpA_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res16, Bi, inpA_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res17, Bi, inpA_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res18, Bi, inpA_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res19, Bi, inpA_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res20, Bi, inpA_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res21, Bi, inpA_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res22, Bi, inpA_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res23, Bi, inpA_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res24, Bi, inpA_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res25, Bi, inpA_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res26, Bi, inpA_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res27, Bi, inpA_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res28, Bi, inpA_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res29, Bi, inpA_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, res30, Bi, inpA_mb, SIMD_BYTES * 29); + fma52hi_mem(res30, res31, Bi, inpA_mb, SIMD_BYTES * 30); + fma52hi_mem(res31, res32, Bi, inpA_mb, SIMD_BYTES * 31); + fma52hi_mem(res32, res33, Bi, inpA_mb, SIMD_BYTES * 32); + fma52hi_mem(res33, res34, Bi, inpA_mb, SIMD_BYTES * 33); + fma52hi_mem(res34, res35, Bi, inpA_mb, SIMD_BYTES * 34); + fma52hi_mem(res35, res36, Bi, inpA_mb, SIMD_BYTES * 35); + fma52hi_mem(res36, res37, Bi, inpA_mb, SIMD_BYTES * 36); + fma52hi_mem(res37, res38, Bi, inpA_mb, SIMD_BYTES * 37); + fma52hi_mem(res38, res39, Bi, inpA_mb, SIMD_BYTES * 38); + fma52hi_mem(res39, res40, Bi, inpA_mb, SIMD_BYTES * 39); + fma52hi_mem(res40, res41, Bi, inpA_mb, SIMD_BYTES * 40); + fma52hi_mem(res41, res42, Bi, inpA_mb, SIMD_BYTES * 41); + fma52hi_mem(res42, res43, Bi, inpA_mb, SIMD_BYTES * 42); + fma52hi_mem(res43, res44, Bi, inpA_mb, SIMD_BYTES * 43); + fma52hi_mem(res44, res45, Bi, inpA_mb, SIMD_BYTES * 44); + fma52hi_mem(res45, res46, Bi, inpA_mb, SIMD_BYTES * 45); + fma52hi_mem(res46, res47, Bi, inpA_mb, SIMD_BYTES * 46); + fma52hi_mem(res47, res48, Bi, inpA_mb, SIMD_BYTES * 47); + fma52hi_mem(res48, res49, Bi, inpA_mb, SIMD_BYTES * 48); + fma52hi_mem(res49, res50, Bi, inpA_mb, SIMD_BYTES * 49); + fma52hi_mem(res50, res51, Bi, inpA_mb, SIMD_BYTES * 50); + fma52hi_mem(res51, res52, Bi, inpA_mb, SIMD_BYTES * 51); + fma52hi_mem(res52, res53, Bi, inpA_mb, SIMD_BYTES * 52); + fma52hi_mem(res53, res54, Bi, inpA_mb, SIMD_BYTES * 53); + fma52hi_mem(res54, res55, Bi, inpA_mb, SIMD_BYTES * 54); + fma52hi_mem(res55, res56, Bi, inpA_mb, SIMD_BYTES * 55); + fma52hi_mem(res56, res57, Bi, inpA_mb, SIMD_BYTES * 56); + fma52hi_mem(res57, res58, Bi, inpA_mb, SIMD_BYTES * 57); + fma52hi_mem(res58, res59, Bi, inpA_mb, SIMD_BYTES * 58); + fma52hi_mem(res59, res60, Bi, inpA_mb, SIMD_BYTES * 59); + fma52hi_mem(res60, res61, Bi, inpA_mb, SIMD_BYTES * 60); + fma52hi_mem(res61, res62, Bi, inpA_mb, SIMD_BYTES * 61); + fma52hi_mem(res62, res63, Bi, inpA_mb, SIMD_BYTES * 62); + fma52hi_mem(res63, res64, Bi, inpA_mb, SIMD_BYTES * 63); + fma52hi_mem(res64, res65, Bi, inpA_mb, SIMD_BYTES * 64); + fma52hi_mem(res65, res66, Bi, inpA_mb, SIMD_BYTES * 65); + fma52hi_mem(res66, res67, Bi, inpA_mb, SIMD_BYTES * 66); + fma52hi_mem(res67, res68, Bi, inpA_mb, SIMD_BYTES * 67); + fma52hi_mem(res68, res69, Bi, inpA_mb, SIMD_BYTES * 68); + fma52hi_mem(res69, res70, Bi, inpA_mb, SIMD_BYTES * 69); + fma52hi_mem(res70, res71, Bi, inpA_mb, SIMD_BYTES * 70); + fma52hi_mem(res71, res72, Bi, inpA_mb, SIMD_BYTES * 71); + fma52hi_mem(res72, res73, Bi, inpA_mb, SIMD_BYTES * 72); + fma52hi_mem(res73, res74, Bi, inpA_mb, SIMD_BYTES * 73); + fma52hi_mem(res74, res75, Bi, inpA_mb, SIMD_BYTES * 74); + fma52hi_mem(res75, res76, Bi, inpA_mb, SIMD_BYTES * 75); + fma52hi_mem(res76, res77, Bi, inpA_mb, SIMD_BYTES * 76); + fma52hi_mem(res77, res78, Bi, inpA_mb, SIMD_BYTES * 77); + fma52hi_mem(res78, get_zero64(), Bi, inpA_mb, SIMD_BYTES * 78); + fma52hi_mem(res00, res00, Yi, inpM_mb, SIMD_BYTES * 0); + fma52hi_mem(res01, res01, Yi, inpM_mb, SIMD_BYTES * 1); + fma52hi_mem(res02, res02, Yi, inpM_mb, SIMD_BYTES * 2); + fma52hi_mem(res03, res03, Yi, inpM_mb, SIMD_BYTES * 3); + fma52hi_mem(res04, res04, Yi, inpM_mb, SIMD_BYTES * 4); + fma52hi_mem(res05, res05, Yi, inpM_mb, SIMD_BYTES * 5); + fma52hi_mem(res06, res06, Yi, inpM_mb, SIMD_BYTES * 6); + fma52hi_mem(res07, res07, Yi, inpM_mb, SIMD_BYTES * 7); + fma52hi_mem(res08, res08, Yi, inpM_mb, SIMD_BYTES * 8); + fma52hi_mem(res09, res09, Yi, inpM_mb, SIMD_BYTES * 9); + fma52hi_mem(res10, res10, Yi, inpM_mb, SIMD_BYTES * 10); + fma52hi_mem(res11, res11, Yi, inpM_mb, SIMD_BYTES * 11); + fma52hi_mem(res12, res12, Yi, inpM_mb, SIMD_BYTES * 12); + fma52hi_mem(res13, res13, Yi, inpM_mb, SIMD_BYTES * 13); + fma52hi_mem(res14, res14, Yi, inpM_mb, SIMD_BYTES * 14); + fma52hi_mem(res15, res15, Yi, inpM_mb, SIMD_BYTES * 15); + fma52hi_mem(res16, res16, Yi, inpM_mb, SIMD_BYTES * 16); + fma52hi_mem(res17, res17, Yi, inpM_mb, SIMD_BYTES * 17); + fma52hi_mem(res18, res18, Yi, inpM_mb, SIMD_BYTES * 18); + fma52hi_mem(res19, res19, Yi, inpM_mb, SIMD_BYTES * 19); + fma52hi_mem(res20, res20, Yi, inpM_mb, SIMD_BYTES * 20); + fma52hi_mem(res21, res21, Yi, inpM_mb, SIMD_BYTES * 21); + fma52hi_mem(res22, res22, Yi, inpM_mb, SIMD_BYTES * 22); + fma52hi_mem(res23, res23, Yi, inpM_mb, SIMD_BYTES * 23); + fma52hi_mem(res24, res24, Yi, inpM_mb, SIMD_BYTES * 24); + fma52hi_mem(res25, res25, Yi, inpM_mb, SIMD_BYTES * 25); + fma52hi_mem(res26, res26, Yi, inpM_mb, SIMD_BYTES * 26); + fma52hi_mem(res27, res27, Yi, inpM_mb, SIMD_BYTES * 27); + fma52hi_mem(res28, res28, Yi, inpM_mb, SIMD_BYTES * 28); + fma52hi_mem(res29, res29, Yi, inpM_mb, SIMD_BYTES * 29); + fma52hi_mem(res30, res30, Yi, inpM_mb, SIMD_BYTES * 30); + fma52hi_mem(res31, res31, Yi, inpM_mb, SIMD_BYTES * 31); + fma52hi_mem(res32, res32, Yi, inpM_mb, SIMD_BYTES * 32); + fma52hi_mem(res33, res33, Yi, inpM_mb, SIMD_BYTES * 33); + fma52hi_mem(res34, res34, Yi, inpM_mb, SIMD_BYTES * 34); + fma52hi_mem(res35, res35, Yi, inpM_mb, SIMD_BYTES * 35); + fma52hi_mem(res36, res36, Yi, inpM_mb, SIMD_BYTES * 36); + fma52hi_mem(res37, res37, Yi, inpM_mb, SIMD_BYTES * 37); + fma52hi_mem(res38, res38, Yi, inpM_mb, SIMD_BYTES * 38); + fma52hi_mem(res39, res39, Yi, inpM_mb, SIMD_BYTES * 39); + fma52hi_mem(res40, res40, Yi, inpM_mb, SIMD_BYTES * 40); + fma52hi_mem(res41, res41, Yi, inpM_mb, SIMD_BYTES * 41); + fma52hi_mem(res42, res42, Yi, inpM_mb, SIMD_BYTES * 42); + fma52hi_mem(res43, res43, Yi, inpM_mb, SIMD_BYTES * 43); + fma52hi_mem(res44, res44, Yi, inpM_mb, SIMD_BYTES * 44); + fma52hi_mem(res45, res45, Yi, inpM_mb, SIMD_BYTES * 45); + fma52hi_mem(res46, res46, Yi, inpM_mb, SIMD_BYTES * 46); + fma52hi_mem(res47, res47, Yi, inpM_mb, SIMD_BYTES * 47); + fma52hi_mem(res48, res48, Yi, inpM_mb, SIMD_BYTES * 48); + fma52hi_mem(res49, res49, Yi, inpM_mb, SIMD_BYTES * 49); + fma52hi_mem(res50, res50, Yi, inpM_mb, SIMD_BYTES * 50); + fma52hi_mem(res51, res51, Yi, inpM_mb, SIMD_BYTES * 51); + fma52hi_mem(res52, res52, Yi, inpM_mb, SIMD_BYTES * 52); + fma52hi_mem(res53, res53, Yi, inpM_mb, SIMD_BYTES * 53); + fma52hi_mem(res54, res54, Yi, inpM_mb, SIMD_BYTES * 54); + fma52hi_mem(res55, res55, Yi, inpM_mb, SIMD_BYTES * 55); + fma52hi_mem(res56, res56, Yi, inpM_mb, SIMD_BYTES * 56); + fma52hi_mem(res57, res57, Yi, inpM_mb, SIMD_BYTES * 57); + fma52hi_mem(res58, res58, Yi, inpM_mb, SIMD_BYTES * 58); + fma52hi_mem(res59, res59, Yi, inpM_mb, SIMD_BYTES * 59); + fma52hi_mem(res60, res60, Yi, inpM_mb, SIMD_BYTES * 60); + fma52hi_mem(res61, res61, Yi, inpM_mb, SIMD_BYTES * 61); + fma52hi_mem(res62, res62, Yi, inpM_mb, SIMD_BYTES * 62); + fma52hi_mem(res63, res63, Yi, inpM_mb, SIMD_BYTES * 63); + fma52hi_mem(res64, res64, Yi, inpM_mb, SIMD_BYTES * 64); + fma52hi_mem(res65, res65, Yi, inpM_mb, SIMD_BYTES * 65); + fma52hi_mem(res66, res66, Yi, inpM_mb, SIMD_BYTES * 66); + fma52hi_mem(res67, res67, Yi, inpM_mb, SIMD_BYTES * 67); + fma52hi_mem(res68, res68, Yi, inpM_mb, SIMD_BYTES * 68); + fma52hi_mem(res69, res69, Yi, inpM_mb, SIMD_BYTES * 69); + fma52hi_mem(res70, res70, Yi, inpM_mb, SIMD_BYTES * 70); + fma52hi_mem(res71, res71, Yi, inpM_mb, SIMD_BYTES * 71); + fma52hi_mem(res72, res72, Yi, inpM_mb, SIMD_BYTES * 72); + fma52hi_mem(res73, res73, Yi, inpM_mb, SIMD_BYTES * 73); + fma52hi_mem(res74, res74, Yi, inpM_mb, SIMD_BYTES * 74); + fma52hi_mem(res75, res75, Yi, inpM_mb, SIMD_BYTES * 75); + fma52hi_mem(res76, res76, Yi, inpM_mb, SIMD_BYTES * 76); + fma52hi_mem(res77, res77, Yi, inpM_mb, SIMD_BYTES * 77); + fma52hi_mem(res78, res78, Yi, inpM_mb, SIMD_BYTES * 78); + } + // Normalization + { + U64 T = get_zero64(); + U64 MASK = set64(DIGIT_MASK); + T = srli64(res00, DIGIT_SIZE); + res00 = and64(res00, MASK); + storeu64(out_mb + MB_WIDTH * 0, res00); + res01 = add64(res01, T); + T = srli64(res01, DIGIT_SIZE); + res01 = and64(res01, MASK); + storeu64(out_mb + MB_WIDTH * 1, res01); + res02 = add64(res02, T); + T = srli64(res02, DIGIT_SIZE); + res02 = and64(res02, MASK); + storeu64(out_mb + MB_WIDTH * 2, res02); + res03 = add64(res03, T); + T = srli64(res03, DIGIT_SIZE); + res03 = and64(res03, MASK); + storeu64(out_mb + MB_WIDTH * 3, res03); + res04 = add64(res04, T); + T = srli64(res04, DIGIT_SIZE); + res04 = and64(res04, MASK); + storeu64(out_mb + MB_WIDTH * 4, res04); + res05 = add64(res05, T); + T = srli64(res05, DIGIT_SIZE); + res05 = and64(res05, MASK); + storeu64(out_mb + MB_WIDTH * 5, res05); + res06 = add64(res06, T); + T = srli64(res06, DIGIT_SIZE); + res06 = and64(res06, MASK); + storeu64(out_mb + MB_WIDTH * 6, res06); + res07 = add64(res07, T); + T = srli64(res07, DIGIT_SIZE); + res07 = and64(res07, MASK); + storeu64(out_mb + MB_WIDTH * 7, res07); + res08 = add64(res08, T); + T = srli64(res08, DIGIT_SIZE); + res08 = and64(res08, MASK); + storeu64(out_mb + MB_WIDTH * 8, res08); + res09 = add64(res09, T); + T = srli64(res09, DIGIT_SIZE); + res09 = and64(res09, MASK); + storeu64(out_mb + MB_WIDTH * 9, res09); + res10 = add64(res10, T); + T = srli64(res10, DIGIT_SIZE); + res10 = and64(res10, MASK); + storeu64(out_mb + MB_WIDTH * 10, res10); + res11 = add64(res11, T); + T = srli64(res11, DIGIT_SIZE); + res11 = and64(res11, MASK); + storeu64(out_mb + MB_WIDTH * 11, res11); + res12 = add64(res12, T); + T = srli64(res12, DIGIT_SIZE); + res12 = and64(res12, MASK); + storeu64(out_mb + MB_WIDTH * 12, res12); + res13 = add64(res13, T); + T = srli64(res13, DIGIT_SIZE); + res13 = and64(res13, MASK); + storeu64(out_mb + MB_WIDTH * 13, res13); + res14 = add64(res14, T); + T = srli64(res14, DIGIT_SIZE); + res14 = and64(res14, MASK); + storeu64(out_mb + MB_WIDTH * 14, res14); + res15 = add64(res15, T); + T = srli64(res15, DIGIT_SIZE); + res15 = and64(res15, MASK); + storeu64(out_mb + MB_WIDTH * 15, res15); + res16 = add64(res16, T); + T = srli64(res16, DIGIT_SIZE); + res16 = and64(res16, MASK); + storeu64(out_mb + MB_WIDTH * 16, res16); + res17 = add64(res17, T); + T = srli64(res17, DIGIT_SIZE); + res17 = and64(res17, MASK); + storeu64(out_mb + MB_WIDTH * 17, res17); + res18 = add64(res18, T); + T = srli64(res18, DIGIT_SIZE); + res18 = and64(res18, MASK); + storeu64(out_mb + MB_WIDTH * 18, res18); + res19 = add64(res19, T); + T = srli64(res19, DIGIT_SIZE); + res19 = and64(res19, MASK); + storeu64(out_mb + MB_WIDTH * 19, res19); + res20 = add64(res20, T); + T = srli64(res20, DIGIT_SIZE); + res20 = and64(res20, MASK); + storeu64(out_mb + MB_WIDTH * 20, res20); + res21 = add64(res21, T); + T = srli64(res21, DIGIT_SIZE); + res21 = and64(res21, MASK); + storeu64(out_mb + MB_WIDTH * 21, res21); + res22 = add64(res22, T); + T = srli64(res22, DIGIT_SIZE); + res22 = and64(res22, MASK); + storeu64(out_mb + MB_WIDTH * 22, res22); + res23 = add64(res23, T); + T = srli64(res23, DIGIT_SIZE); + res23 = and64(res23, MASK); + storeu64(out_mb + MB_WIDTH * 23, res23); + res24 = add64(res24, T); + T = srli64(res24, DIGIT_SIZE); + res24 = and64(res24, MASK); + storeu64(out_mb + MB_WIDTH * 24, res24); + res25 = add64(res25, T); + T = srli64(res25, DIGIT_SIZE); + res25 = and64(res25, MASK); + storeu64(out_mb + MB_WIDTH * 25, res25); + res26 = add64(res26, T); + T = srli64(res26, DIGIT_SIZE); + res26 = and64(res26, MASK); + storeu64(out_mb + MB_WIDTH * 26, res26); + res27 = add64(res27, T); + T = srli64(res27, DIGIT_SIZE); + res27 = and64(res27, MASK); + storeu64(out_mb + MB_WIDTH * 27, res27); + res28 = add64(res28, T); + T = srli64(res28, DIGIT_SIZE); + res28 = and64(res28, MASK); + storeu64(out_mb + MB_WIDTH * 28, res28); + res29 = add64(res29, T); + T = srli64(res29, DIGIT_SIZE); + res29 = and64(res29, MASK); + storeu64(out_mb + MB_WIDTH * 29, res29); + res30 = add64(res30, T); + T = srli64(res30, DIGIT_SIZE); + res30 = and64(res30, MASK); + storeu64(out_mb + MB_WIDTH * 30, res30); + res31 = add64(res31, T); + T = srli64(res31, DIGIT_SIZE); + res31 = and64(res31, MASK); + storeu64(out_mb + MB_WIDTH * 31, res31); + res32 = add64(res32, T); + T = srli64(res32, DIGIT_SIZE); + res32 = and64(res32, MASK); + storeu64(out_mb + MB_WIDTH * 32, res32); + res33 = add64(res33, T); + T = srli64(res33, DIGIT_SIZE); + res33 = and64(res33, MASK); + storeu64(out_mb + MB_WIDTH * 33, res33); + res34 = add64(res34, T); + T = srli64(res34, DIGIT_SIZE); + res34 = and64(res34, MASK); + storeu64(out_mb + MB_WIDTH * 34, res34); + res35 = add64(res35, T); + T = srli64(res35, DIGIT_SIZE); + res35 = and64(res35, MASK); + storeu64(out_mb + MB_WIDTH * 35, res35); + res36 = add64(res36, T); + T = srli64(res36, DIGIT_SIZE); + res36 = and64(res36, MASK); + storeu64(out_mb + MB_WIDTH * 36, res36); + res37 = add64(res37, T); + T = srli64(res37, DIGIT_SIZE); + res37 = and64(res37, MASK); + storeu64(out_mb + MB_WIDTH * 37, res37); + res38 = add64(res38, T); + T = srli64(res38, DIGIT_SIZE); + res38 = and64(res38, MASK); + storeu64(out_mb + MB_WIDTH * 38, res38); + res39 = add64(res39, T); + T = srli64(res39, DIGIT_SIZE); + res39 = and64(res39, MASK); + storeu64(out_mb + MB_WIDTH * 39, res39); + res40 = add64(res40, T); + T = srli64(res40, DIGIT_SIZE); + res40 = and64(res40, MASK); + storeu64(out_mb + MB_WIDTH * 40, res40); + res41 = add64(res41, T); + T = srli64(res41, DIGIT_SIZE); + res41 = and64(res41, MASK); + storeu64(out_mb + MB_WIDTH * 41, res41); + res42 = add64(res42, T); + T = srli64(res42, DIGIT_SIZE); + res42 = and64(res42, MASK); + storeu64(out_mb + MB_WIDTH * 42, res42); + res43 = add64(res43, T); + T = srli64(res43, DIGIT_SIZE); + res43 = and64(res43, MASK); + storeu64(out_mb + MB_WIDTH * 43, res43); + res44 = add64(res44, T); + T = srli64(res44, DIGIT_SIZE); + res44 = and64(res44, MASK); + storeu64(out_mb + MB_WIDTH * 44, res44); + res45 = add64(res45, T); + T = srli64(res45, DIGIT_SIZE); + res45 = and64(res45, MASK); + storeu64(out_mb + MB_WIDTH * 45, res45); + res46 = add64(res46, T); + T = srli64(res46, DIGIT_SIZE); + res46 = and64(res46, MASK); + storeu64(out_mb + MB_WIDTH * 46, res46); + res47 = add64(res47, T); + T = srli64(res47, DIGIT_SIZE); + res47 = and64(res47, MASK); + storeu64(out_mb + MB_WIDTH * 47, res47); + res48 = add64(res48, T); + T = srli64(res48, DIGIT_SIZE); + res48 = and64(res48, MASK); + storeu64(out_mb + MB_WIDTH * 48, res48); + res49 = add64(res49, T); + T = srli64(res49, DIGIT_SIZE); + res49 = and64(res49, MASK); + storeu64(out_mb + MB_WIDTH * 49, res49); + res50 = add64(res50, T); + T = srli64(res50, DIGIT_SIZE); + res50 = and64(res50, MASK); + storeu64(out_mb + MB_WIDTH * 50, res50); + res51 = add64(res51, T); + T = srli64(res51, DIGIT_SIZE); + res51 = and64(res51, MASK); + storeu64(out_mb + MB_WIDTH * 51, res51); + res52 = add64(res52, T); + T = srli64(res52, DIGIT_SIZE); + res52 = and64(res52, MASK); + storeu64(out_mb + MB_WIDTH * 52, res52); + res53 = add64(res53, T); + T = srli64(res53, DIGIT_SIZE); + res53 = and64(res53, MASK); + storeu64(out_mb + MB_WIDTH * 53, res53); + res54 = add64(res54, T); + T = srli64(res54, DIGIT_SIZE); + res54 = and64(res54, MASK); + storeu64(out_mb + MB_WIDTH * 54, res54); + res55 = add64(res55, T); + T = srli64(res55, DIGIT_SIZE); + res55 = and64(res55, MASK); + storeu64(out_mb + MB_WIDTH * 55, res55); + res56 = add64(res56, T); + T = srli64(res56, DIGIT_SIZE); + res56 = and64(res56, MASK); + storeu64(out_mb + MB_WIDTH * 56, res56); + res57 = add64(res57, T); + T = srli64(res57, DIGIT_SIZE); + res57 = and64(res57, MASK); + storeu64(out_mb + MB_WIDTH * 57, res57); + res58 = add64(res58, T); + T = srli64(res58, DIGIT_SIZE); + res58 = and64(res58, MASK); + storeu64(out_mb + MB_WIDTH * 58, res58); + res59 = add64(res59, T); + T = srli64(res59, DIGIT_SIZE); + res59 = and64(res59, MASK); + storeu64(out_mb + MB_WIDTH * 59, res59); + res60 = add64(res60, T); + T = srli64(res60, DIGIT_SIZE); + res60 = and64(res60, MASK); + storeu64(out_mb + MB_WIDTH * 60, res60); + res61 = add64(res61, T); + T = srli64(res61, DIGIT_SIZE); + res61 = and64(res61, MASK); + storeu64(out_mb + MB_WIDTH * 61, res61); + res62 = add64(res62, T); + T = srli64(res62, DIGIT_SIZE); + res62 = and64(res62, MASK); + storeu64(out_mb + MB_WIDTH * 62, res62); + res63 = add64(res63, T); + T = srli64(res63, DIGIT_SIZE); + res63 = and64(res63, MASK); + storeu64(out_mb + MB_WIDTH * 63, res63); + res64 = add64(res64, T); + T = srli64(res64, DIGIT_SIZE); + res64 = and64(res64, MASK); + storeu64(out_mb + MB_WIDTH * 64, res64); + res65 = add64(res65, T); + T = srli64(res65, DIGIT_SIZE); + res65 = and64(res65, MASK); + storeu64(out_mb + MB_WIDTH * 65, res65); + res66 = add64(res66, T); + T = srli64(res66, DIGIT_SIZE); + res66 = and64(res66, MASK); + storeu64(out_mb + MB_WIDTH * 66, res66); + res67 = add64(res67, T); + T = srli64(res67, DIGIT_SIZE); + res67 = and64(res67, MASK); + storeu64(out_mb + MB_WIDTH * 67, res67); + res68 = add64(res68, T); + T = srli64(res68, DIGIT_SIZE); + res68 = and64(res68, MASK); + storeu64(out_mb + MB_WIDTH * 68, res68); + res69 = add64(res69, T); + T = srli64(res69, DIGIT_SIZE); + res69 = and64(res69, MASK); + storeu64(out_mb + MB_WIDTH * 69, res69); + res70 = add64(res70, T); + T = srli64(res70, DIGIT_SIZE); + res70 = and64(res70, MASK); + storeu64(out_mb + MB_WIDTH * 70, res70); + res71 = add64(res71, T); + T = srli64(res71, DIGIT_SIZE); + res71 = and64(res71, MASK); + storeu64(out_mb + MB_WIDTH * 71, res71); + res72 = add64(res72, T); + T = srli64(res72, DIGIT_SIZE); + res72 = and64(res72, MASK); + storeu64(out_mb + MB_WIDTH * 72, res72); + res73 = add64(res73, T); + T = srli64(res73, DIGIT_SIZE); + res73 = and64(res73, MASK); + storeu64(out_mb + MB_WIDTH * 73, res73); + res74 = add64(res74, T); + T = srli64(res74, DIGIT_SIZE); + res74 = and64(res74, MASK); + storeu64(out_mb + MB_WIDTH * 74, res74); + res75 = add64(res75, T); + T = srli64(res75, DIGIT_SIZE); + res75 = and64(res75, MASK); + storeu64(out_mb + MB_WIDTH * 75, res75); + res76 = add64(res76, T); + T = srli64(res76, DIGIT_SIZE); + res76 = and64(res76, MASK); + storeu64(out_mb + MB_WIDTH * 76, res76); + res77 = add64(res77, T); + T = srli64(res77, DIGIT_SIZE); + res77 = and64(res77, MASK); + storeu64(out_mb + MB_WIDTH * 77, res77); + res78 = add64(res78, T); + res78 = and64(res78, MASK); + storeu64(out_mb + MB_WIDTH * 78, res78); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x10_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x10_diagonal_mb8.c new file mode 100644 index 000000000..a25ae6df4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x10_diagonal_mb8.c @@ -0,0 +1,436 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS52x10_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + U64 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9, res10, res11, + res12, res13, res14, res15, res16, res17, res18, res19; + + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + U64 k = loadu64((U64 *)k0_mb); + + res0 = res1 = res2 = res3 = res4 = res5 = res6 = res7 = res8 = res9 = res10 = + res11 = res12 = res13 = res14 = res15 = res16 = res17 = res18 = res19 = + get_zero64(); + res1 = fma52lo(res1, a[0], a[1]); // Sum(1) + res2 = fma52hi(res2, a[0], a[1]); // Sum(1) + res2 = fma52lo(res2, a[0], a[2]); // Sum(2) + res3 = fma52hi(res3, a[0], a[2]); // Sum(2) + res3 = fma52lo(res3, a[1], a[2]); // Sum(3) + res4 = fma52hi(res4, a[1], a[2]); // Sum(3) + res3 = fma52lo(res3, a[0], a[3]); // Sum(3) + res4 = fma52hi(res4, a[0], a[3]); // Sum(3) + res4 = fma52lo(res4, a[1], a[3]); // Sum(4) + res5 = fma52hi(res5, a[1], a[3]); // Sum(4) + res5 = fma52lo(res5, a[2], a[3]); // Sum(5) + res6 = fma52hi(res6, a[2], a[3]); // Sum(5) + res4 = fma52lo(res4, a[0], a[4]); // Sum(4) + res5 = fma52hi(res5, a[0], a[4]); // Sum(4) + res5 = fma52lo(res5, a[1], a[4]); // Sum(5) + res6 = fma52hi(res6, a[1], a[4]); // Sum(5) + res6 = fma52lo(res6, a[2], a[4]); // Sum(6) + res7 = fma52hi(res7, a[2], a[4]); // Sum(6) + res7 = fma52lo(res7, a[3], a[4]); // Sum(7) + res8 = fma52hi(res8, a[3], a[4]); // Sum(7) + res5 = fma52lo(res5, a[0], a[5]); // Sum(5) + res6 = fma52hi(res6, a[0], a[5]); // Sum(5) + res6 = fma52lo(res6, a[1], a[5]); // Sum(6) + res7 = fma52hi(res7, a[1], a[5]); // Sum(6) + res7 = fma52lo(res7, a[2], a[5]); // Sum(7) + res8 = fma52hi(res8, a[2], a[5]); // Sum(7) + res8 = fma52lo(res8, a[3], a[5]); // Sum(8) + res9 = fma52hi(res9, a[3], a[5]); // Sum(8) + res9 = fma52lo(res9, a[4], a[5]); // Sum(9) + res10 = fma52hi(res10, a[4], a[5]); // Sum(9) + res6 = fma52lo(res6, a[0], a[6]); // Sum(6) + res7 = fma52hi(res7, a[0], a[6]); // Sum(6) + res7 = fma52lo(res7, a[1], a[6]); // Sum(7) + res8 = fma52hi(res8, a[1], a[6]); // Sum(7) + res8 = fma52lo(res8, a[2], a[6]); // Sum(8) + res9 = fma52hi(res9, a[2], a[6]); // Sum(8) + res9 = fma52lo(res9, a[3], a[6]); // Sum(9) + res10 = fma52hi(res10, a[3], a[6]); // Sum(9) + res10 = fma52lo(res10, a[4], a[6]); // Sum(10) + res11 = fma52hi(res11, a[4], a[6]); // Sum(10) + res11 = fma52lo(res11, a[5], a[6]); // Sum(11) + res12 = fma52hi(res12, a[5], a[6]); // Sum(11) + res7 = fma52lo(res7, a[0], a[7]); // Sum(7) + res8 = fma52hi(res8, a[0], a[7]); // Sum(7) + res8 = fma52lo(res8, a[1], a[7]); // Sum(8) + res9 = fma52hi(res9, a[1], a[7]); // Sum(8) + res9 = fma52lo(res9, a[2], a[7]); // Sum(9) + res10 = fma52hi(res10, a[2], a[7]); // Sum(9) + res10 = fma52lo(res10, a[3], a[7]); // Sum(10) + res11 = fma52hi(res11, a[3], a[7]); // Sum(10) + res11 = fma52lo(res11, a[4], a[7]); // Sum(11) + res12 = fma52hi(res12, a[4], a[7]); // Sum(11) + res8 = fma52lo(res8, a[0], a[8]); // Sum(8) + res9 = fma52hi(res9, a[0], a[8]); // Sum(8) + res9 = fma52lo(res9, a[1], a[8]); // Sum(9) + res10 = fma52hi(res10, a[1], a[8]); // Sum(9) + res10 = fma52lo(res10, a[2], a[8]); // Sum(10) + res11 = fma52hi(res11, a[2], a[8]); // Sum(10) + res11 = fma52lo(res11, a[3], a[8]); // Sum(11) + res12 = fma52hi(res12, a[3], a[8]); // Sum(11) + res9 = fma52lo(res9, a[0], a[9]); // Sum(9) + res10 = fma52hi(res10, a[0], a[9]); // Sum(9) + res10 = fma52lo(res10, a[1], a[9]); // Sum(10) + res11 = fma52hi(res11, a[1], a[9]); // Sum(10) + res11 = fma52lo(res11, a[2], a[9]); // Sum(11) + res12 = fma52hi(res12, a[2], a[9]); // Sum(11) + res0 = add64(res0, res0); // Double(0) + res1 = add64(res1, res1); // Double(1) + res2 = add64(res2, res2); // Double(2) + res3 = add64(res3, res3); // Double(3) + res4 = add64(res4, res4); // Double(4) + res5 = add64(res5, res5); // Double(5) + res6 = add64(res6, res6); // Double(6) + res7 = add64(res7, res7); // Double(7) + res8 = add64(res8, res8); // Double(8) + res9 = add64(res9, res9); // Double(9) + res10 = add64(res10, res10); // Double(10) + res11 = add64(res11, res11); // Double(11) + res0 = fma52lo(res0, a[0], a[0]); // Add sqr(0) + res1 = fma52hi(res1, a[0], a[0]); // Add sqr(0) + res2 = fma52lo(res2, a[1], a[1]); // Add sqr(2) + res3 = fma52hi(res3, a[1], a[1]); // Add sqr(2) + res4 = fma52lo(res4, a[2], a[2]); // Add sqr(4) + res5 = fma52hi(res5, a[2], a[2]); // Add sqr(4) + res6 = fma52lo(res6, a[3], a[3]); // Add sqr(6) + res7 = fma52hi(res7, a[3], a[3]); // Add sqr(6) + res8 = fma52lo(res8, a[4], a[4]); // Add sqr(8) + res9 = fma52hi(res9, a[4], a[4]); // Add sqr(8) + res10 = fma52lo(res10, a[5], a[5]); // Add sqr(10) + res11 = fma52hi(res11, a[5], a[5]); // Add sqr(10) + res12 = fma52lo(res12, a[5], a[7]); // Sum(12) + res13 = fma52hi(res13, a[5], a[7]); // Sum(12) + res13 = fma52lo(res13, a[6], a[7]); // Sum(13) + res14 = fma52hi(res14, a[6], a[7]); // Sum(13) + res12 = fma52lo(res12, a[4], a[8]); // Sum(12) + res13 = fma52hi(res13, a[4], a[8]); // Sum(12) + res13 = fma52lo(res13, a[5], a[8]); // Sum(13) + res14 = fma52hi(res14, a[5], a[8]); // Sum(13) + res14 = fma52lo(res14, a[6], a[8]); // Sum(14) + res15 = fma52hi(res15, a[6], a[8]); // Sum(14) + res15 = fma52lo(res15, a[7], a[8]); // Sum(15) + res16 = fma52hi(res16, a[7], a[8]); // Sum(15) + res12 = fma52lo(res12, a[3], a[9]); // Sum(12) + res13 = fma52hi(res13, a[3], a[9]); // Sum(12) + res13 = fma52lo(res13, a[4], a[9]); // Sum(13) + res14 = fma52hi(res14, a[4], a[9]); // Sum(13) + res14 = fma52lo(res14, a[5], a[9]); // Sum(14) + res15 = fma52hi(res15, a[5], a[9]); // Sum(14) + res15 = fma52lo(res15, a[6], a[9]); // Sum(15) + res16 = fma52hi(res16, a[6], a[9]); // Sum(15) + res16 = fma52lo(res16, a[7], a[9]); // Sum(16) + res17 = fma52hi(res17, a[7], a[9]); // Sum(16) + res17 = fma52lo(res17, a[8], a[9]); // Sum(17) + res18 = fma52hi(res18, a[8], a[9]); // Sum(17) + res12 = add64(res12, res12); // Double(12) + res13 = add64(res13, res13); // Double(13) + res14 = add64(res14, res14); // Double(14) + res15 = add64(res15, res15); // Double(15) + res16 = add64(res16, res16); // Double(16) + res17 = add64(res17, res17); // Double(17) + res18 = add64(res18, res18); // Double(18) + res12 = fma52lo(res12, a[6], a[6]); // Add sqr(12) + res13 = fma52hi(res13, a[6], a[6]); // Add sqr(12) + res14 = fma52lo(res14, a[7], a[7]); // Add sqr(14) + res15 = fma52hi(res15, a[7], a[7]); // Add sqr(14) + res16 = fma52lo(res16, a[8], a[8]); // Add sqr(16) + res17 = fma52hi(res17, a[8], a[8]); // Add sqr(16) + res18 = fma52lo(res18, a[9], a[9]); // Add sqr(18) + res19 = fma52hi(res19, a[9], a[9]); // Add sqr(18) + + // Generate u_i + U64 u0 = mul52lo(res0, k); + ASM("jmp l0\nl0:\n"); + + // Create u0 + fma52lo_mem(res0, res0, u0, m, SIMD_BYTES * 0); + fma52hi_mem(res1, res1, u0, m, SIMD_BYTES * 0); + res1 = fma52lo(res1, u0, m[1]); + res2 = fma52hi(res2, u0, m[1]); + res1 = add64(res1, srli64(res0, DIGIT_SIZE)); + U64 u1 = mul52lo(res1, k); + fma52lo_mem(res2, res2, u0, m, SIMD_BYTES * 2); + fma52hi_mem(res3, res3, u0, m, SIMD_BYTES * 2); + res3 = fma52lo(res3, u0, m[3]); + res4 = fma52hi(res4, u0, m[3]); + fma52lo_mem(res4, res4, u0, m, SIMD_BYTES * 4); + fma52hi_mem(res5, res5, u0, m, SIMD_BYTES * 4); + res5 = fma52lo(res5, u0, m[5]); + res6 = fma52hi(res6, u0, m[5]); + fma52lo_mem(res6, res6, u0, m, SIMD_BYTES * 6); + fma52hi_mem(res7, res7, u0, m, SIMD_BYTES * 6); + res7 = fma52lo(res7, u0, m[7]); + res8 = fma52hi(res8, u0, m[7]); + fma52lo_mem(res8, res8, u0, m, SIMD_BYTES * 8); + fma52hi_mem(res9, res9, u0, m, SIMD_BYTES * 8); + res9 = fma52lo(res9, u0, m[9]); + res10 = fma52hi(res10, u0, m[9]); + + // Create u1 + fma52lo_mem(res1, res1, u1, m, SIMD_BYTES * 0); + fma52hi_mem(res2, res2, u1, m, SIMD_BYTES * 0); + res2 = fma52lo(res2, u1, m[1]); + res3 = fma52hi(res3, u1, m[1]); + res2 = add64(res2, srli64(res1, DIGIT_SIZE)); + U64 u2 = mul52lo(res2, k); + fma52lo_mem(res3, res3, u1, m, SIMD_BYTES * 2); + fma52hi_mem(res4, res4, u1, m, SIMD_BYTES * 2); + res4 = fma52lo(res4, u1, m[3]); + res5 = fma52hi(res5, u1, m[3]); + fma52lo_mem(res5, res5, u1, m, SIMD_BYTES * 4); + fma52hi_mem(res6, res6, u1, m, SIMD_BYTES * 4); + res6 = fma52lo(res6, u1, m[5]); + res7 = fma52hi(res7, u1, m[5]); + fma52lo_mem(res7, res7, u1, m, SIMD_BYTES * 6); + fma52hi_mem(res8, res8, u1, m, SIMD_BYTES * 6); + res8 = fma52lo(res8, u1, m[7]); + res9 = fma52hi(res9, u1, m[7]); + fma52lo_mem(res9, res9, u1, m, SIMD_BYTES * 8); + fma52hi_mem(res10, res10, u1, m, SIMD_BYTES * 8); + res10 = fma52lo(res10, u1, m[9]); + res11 = fma52hi(res11, u1, m[9]); + ASM("jmp l2\nl2:\n"); + + // Create u2 + fma52lo_mem(res2, res2, u2, m, SIMD_BYTES * 0); + fma52hi_mem(res3, res3, u2, m, SIMD_BYTES * 0); + res3 = fma52lo(res3, u2, m[1]); + res4 = fma52hi(res4, u2, m[1]); + res3 = add64(res3, srli64(res2, DIGIT_SIZE)); + U64 u3 = mul52lo(res3, k); + fma52lo_mem(res4, res4, u2, m, SIMD_BYTES * 2); + fma52hi_mem(res5, res5, u2, m, SIMD_BYTES * 2); + res5 = fma52lo(res5, u2, m[3]); + res6 = fma52hi(res6, u2, m[3]); + fma52lo_mem(res6, res6, u2, m, SIMD_BYTES * 4); + fma52hi_mem(res7, res7, u2, m, SIMD_BYTES * 4); + res7 = fma52lo(res7, u2, m[5]); + res8 = fma52hi(res8, u2, m[5]); + fma52lo_mem(res8, res8, u2, m, SIMD_BYTES * 6); + fma52hi_mem(res9, res9, u2, m, SIMD_BYTES * 6); + res9 = fma52lo(res9, u2, m[7]); + res10 = fma52hi(res10, u2, m[7]); + fma52lo_mem(res10, res10, u2, m, SIMD_BYTES * 8); + fma52hi_mem(res11, res11, u2, m, SIMD_BYTES * 8); + res11 = fma52lo(res11, u2, m[9]); + res12 = fma52hi(res12, u2, m[9]); + + // Create u3 + fma52lo_mem(res3, res3, u3, m, SIMD_BYTES * 0); + fma52hi_mem(res4, res4, u3, m, SIMD_BYTES * 0); + res4 = fma52lo(res4, u3, m[1]); + res5 = fma52hi(res5, u3, m[1]); + res4 = add64(res4, srli64(res3, DIGIT_SIZE)); + U64 u4 = mul52lo(res4, k); + fma52lo_mem(res5, res5, u3, m, SIMD_BYTES * 2); + fma52hi_mem(res6, res6, u3, m, SIMD_BYTES * 2); + res6 = fma52lo(res6, u3, m[3]); + res7 = fma52hi(res7, u3, m[3]); + fma52lo_mem(res7, res7, u3, m, SIMD_BYTES * 4); + fma52hi_mem(res8, res8, u3, m, SIMD_BYTES * 4); + res8 = fma52lo(res8, u3, m[5]); + res9 = fma52hi(res9, u3, m[5]); + fma52lo_mem(res9, res9, u3, m, SIMD_BYTES * 6); + fma52hi_mem(res10, res10, u3, m, SIMD_BYTES * 6); + res10 = fma52lo(res10, u3, m[7]); + res11 = fma52hi(res11, u3, m[7]); + fma52lo_mem(res11, res11, u3, m, SIMD_BYTES * 8); + fma52hi_mem(res12, res12, u3, m, SIMD_BYTES * 8); + res12 = fma52lo(res12, u3, m[9]); + res13 = fma52hi(res13, u3, m[9]); + ASM("jmp l4\nl4:\n"); + + // Create u4 + fma52lo_mem(res4, res4, u4, m, SIMD_BYTES * 0); + fma52hi_mem(res5, res5, u4, m, SIMD_BYTES * 0); + res5 = fma52lo(res5, u4, m[1]); + res6 = fma52hi(res6, u4, m[1]); + res5 = add64(res5, srli64(res4, DIGIT_SIZE)); + U64 u5 = mul52lo(res5, k); + fma52lo_mem(res6, res6, u4, m, SIMD_BYTES * 2); + fma52hi_mem(res7, res7, u4, m, SIMD_BYTES * 2); + res7 = fma52lo(res7, u4, m[3]); + res8 = fma52hi(res8, u4, m[3]); + fma52lo_mem(res8, res8, u4, m, SIMD_BYTES * 4); + fma52hi_mem(res9, res9, u4, m, SIMD_BYTES * 4); + res9 = fma52lo(res9, u4, m[5]); + res10 = fma52hi(res10, u4, m[5]); + fma52lo_mem(res10, res10, u4, m, SIMD_BYTES * 6); + fma52hi_mem(res11, res11, u4, m, SIMD_BYTES * 6); + res11 = fma52lo(res11, u4, m[7]); + res12 = fma52hi(res12, u4, m[7]); + fma52lo_mem(res12, res12, u4, m, SIMD_BYTES * 8); + fma52hi_mem(res13, res13, u4, m, SIMD_BYTES * 8); + res13 = fma52lo(res13, u4, m[9]); + res14 = fma52hi(res14, u4, m[9]); + + // Create u5 + fma52lo_mem(res5, res5, u5, m, SIMD_BYTES * 0); + fma52hi_mem(res6, res6, u5, m, SIMD_BYTES * 0); + res6 = fma52lo(res6, u5, m[1]); + res7 = fma52hi(res7, u5, m[1]); + res6 = add64(res6, srli64(res5, DIGIT_SIZE)); + U64 u6 = mul52lo(res6, k); + fma52lo_mem(res7, res7, u5, m, SIMD_BYTES * 2); + fma52hi_mem(res8, res8, u5, m, SIMD_BYTES * 2); + res8 = fma52lo(res8, u5, m[3]); + res9 = fma52hi(res9, u5, m[3]); + fma52lo_mem(res9, res9, u5, m, SIMD_BYTES * 4); + fma52hi_mem(res10, res10, u5, m, SIMD_BYTES * 4); + res10 = fma52lo(res10, u5, m[5]); + res11 = fma52hi(res11, u5, m[5]); + fma52lo_mem(res11, res11, u5, m, SIMD_BYTES * 6); + fma52hi_mem(res12, res12, u5, m, SIMD_BYTES * 6); + res12 = fma52lo(res12, u5, m[7]); + res13 = fma52hi(res13, u5, m[7]); + fma52lo_mem(res13, res13, u5, m, SIMD_BYTES * 8); + fma52hi_mem(res14, res14, u5, m, SIMD_BYTES * 8); + res14 = fma52lo(res14, u5, m[9]); + res15 = fma52hi(res15, u5, m[9]); + ASM("jmp l6\nl6:\n"); + + // Create u6 + fma52lo_mem(res6, res6, u6, m, SIMD_BYTES * 0); + fma52hi_mem(res7, res7, u6, m, SIMD_BYTES * 0); + res7 = fma52lo(res7, u6, m[1]); + res8 = fma52hi(res8, u6, m[1]); + res7 = add64(res7, srli64(res6, DIGIT_SIZE)); + U64 u7 = mul52lo(res7, k); + fma52lo_mem(res8, res8, u6, m, SIMD_BYTES * 2); + fma52hi_mem(res9, res9, u6, m, SIMD_BYTES * 2); + res9 = fma52lo(res9, u6, m[3]); + res10 = fma52hi(res10, u6, m[3]); + fma52lo_mem(res10, res10, u6, m, SIMD_BYTES * 4); + fma52hi_mem(res11, res11, u6, m, SIMD_BYTES * 4); + res11 = fma52lo(res11, u6, m[5]); + res12 = fma52hi(res12, u6, m[5]); + fma52lo_mem(res12, res12, u6, m, SIMD_BYTES * 6); + fma52hi_mem(res13, res13, u6, m, SIMD_BYTES * 6); + res13 = fma52lo(res13, u6, m[7]); + res14 = fma52hi(res14, u6, m[7]); + fma52lo_mem(res14, res14, u6, m, SIMD_BYTES * 8); + fma52hi_mem(res15, res15, u6, m, SIMD_BYTES * 8); + res15 = fma52lo(res15, u6, m[9]); + res16 = fma52hi(res16, u6, m[9]); + + // Create u7 + fma52lo_mem(res7, res7, u7, m, SIMD_BYTES * 0); + fma52hi_mem(res8, res8, u7, m, SIMD_BYTES * 0); + res8 = fma52lo(res8, u7, m[1]); + res9 = fma52hi(res9, u7, m[1]); + res8 = add64(res8, srli64(res7, DIGIT_SIZE)); + U64 u8 = mul52lo(res8, k); + fma52lo_mem(res9, res9, u7, m, SIMD_BYTES * 2); + fma52hi_mem(res10, res10, u7, m, SIMD_BYTES * 2); + res10 = fma52lo(res10, u7, m[3]); + res11 = fma52hi(res11, u7, m[3]); + fma52lo_mem(res11, res11, u7, m, SIMD_BYTES * 4); + fma52hi_mem(res12, res12, u7, m, SIMD_BYTES * 4); + res12 = fma52lo(res12, u7, m[5]); + res13 = fma52hi(res13, u7, m[5]); + fma52lo_mem(res13, res13, u7, m, SIMD_BYTES * 6); + fma52hi_mem(res14, res14, u7, m, SIMD_BYTES * 6); + res14 = fma52lo(res14, u7, m[7]); + res15 = fma52hi(res15, u7, m[7]); + fma52lo_mem(res15, res15, u7, m, SIMD_BYTES * 8); + fma52hi_mem(res16, res16, u7, m, SIMD_BYTES * 8); + res16 = fma52lo(res16, u7, m[9]); + res17 = fma52hi(res17, u7, m[9]); + ASM("jmp l8\nl8:\n"); + + // Create u8 + fma52lo_mem(res8, res8, u8, m, SIMD_BYTES * 0); + fma52hi_mem(res9, res9, u8, m, SIMD_BYTES * 0); + res9 = fma52lo(res9, u8, m[1]); + res10 = fma52hi(res10, u8, m[1]); + res9 = add64(res9, srli64(res8, DIGIT_SIZE)); + U64 u9 = mul52lo(res9, k); + fma52lo_mem(res10, res10, u8, m, SIMD_BYTES * 2); + fma52hi_mem(res11, res11, u8, m, SIMD_BYTES * 2); + res11 = fma52lo(res11, u8, m[3]); + res12 = fma52hi(res12, u8, m[3]); + fma52lo_mem(res12, res12, u8, m, SIMD_BYTES * 4); + fma52hi_mem(res13, res13, u8, m, SIMD_BYTES * 4); + res13 = fma52lo(res13, u8, m[5]); + res14 = fma52hi(res14, u8, m[5]); + fma52lo_mem(res14, res14, u8, m, SIMD_BYTES * 6); + fma52hi_mem(res15, res15, u8, m, SIMD_BYTES * 6); + res15 = fma52lo(res15, u8, m[7]); + res16 = fma52hi(res16, u8, m[7]); + fma52lo_mem(res16, res16, u8, m, SIMD_BYTES * 8); + fma52hi_mem(res17, res17, u8, m, SIMD_BYTES * 8); + res17 = fma52lo(res17, u8, m[9]); + res18 = fma52hi(res18, u8, m[9]); + + // Create u9 + fma52lo_mem(res9, res9, u9, m, SIMD_BYTES * 0); + fma52hi_mem(res10, res10, u9, m, SIMD_BYTES * 0); + res10 = fma52lo(res10, u9, m[1]); + res11 = fma52hi(res11, u9, m[1]); + res10 = add64(res10, srli64(res9, DIGIT_SIZE)); + fma52lo_mem(res11, res11, u9, m, SIMD_BYTES * 2); + fma52hi_mem(res12, res12, u9, m, SIMD_BYTES * 2); + res12 = fma52lo(res12, u9, m[3]); + res13 = fma52hi(res13, u9, m[3]); + fma52lo_mem(res13, res13, u9, m, SIMD_BYTES * 4); + fma52hi_mem(res14, res14, u9, m, SIMD_BYTES * 4); + res14 = fma52lo(res14, u9, m[5]); + res15 = fma52hi(res15, u9, m[5]); + fma52lo_mem(res15, res15, u9, m, SIMD_BYTES * 6); + fma52hi_mem(res16, res16, u9, m, SIMD_BYTES * 6); + res16 = fma52lo(res16, u9, m[7]); + res17 = fma52hi(res17, u9, m[7]); + fma52lo_mem(res17, res17, u9, m, SIMD_BYTES * 8); + fma52hi_mem(res18, res18, u9, m, SIMD_BYTES * 8); + res18 = fma52lo(res18, u9, m[9]); + res19 = fma52hi(res19, u9, m[9]); + + // Normalization + r[0] = and64_const(res10, DIGIT_MASK); + res11 = add64(res11, srli64(res10, DIGIT_SIZE)); + r[1] = and64_const(res11, DIGIT_MASK); + res12 = add64(res12, srli64(res11, DIGIT_SIZE)); + r[2] = and64_const(res12, DIGIT_MASK); + res13 = add64(res13, srli64(res12, DIGIT_SIZE)); + r[3] = and64_const(res13, DIGIT_MASK); + res14 = add64(res14, srli64(res13, DIGIT_SIZE)); + r[4] = and64_const(res14, DIGIT_MASK); + res15 = add64(res15, srli64(res14, DIGIT_SIZE)); + r[5] = and64_const(res15, DIGIT_MASK); + res16 = add64(res16, srli64(res15, DIGIT_SIZE)); + r[6] = and64_const(res16, DIGIT_MASK); + res17 = add64(res17, srli64(res16, DIGIT_SIZE)); + r[7] = and64_const(res17, DIGIT_MASK); + res18 = add64(res18, srli64(res17, DIGIT_SIZE)); + r[8] = and64_const(res18, DIGIT_MASK); + res19 = add64(res19, srli64(res18, DIGIT_SIZE)); + r[9] = and64_const(res19, DIGIT_MASK); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x20_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x20_diagonal_mb8.c new file mode 100644 index 000000000..2f7bf77de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x20_diagonal_mb8.c @@ -0,0 +1,1435 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS52x20_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + U64 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9, res10, res11, + res12, res13, res14, res15, res16, res17, res18, res19, res20, res21, + res22, res23, res24, res25, res26, res27, res28, res29, res30, res31, + res32, res33, res34, res35, res36, res37, res38, res39; + + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + U64 k = loadu64((U64 *)k0_mb); + + res0 = res1 = res2 = res3 = res4 = res5 = res6 = res7 = res8 = res9 = res10 = + res11 = res12 = res13 = res14 = res15 = res16 = res17 = res18 = res19 = + res20 = res21 = res22 = res23 = res24 = res25 = res26 = res27 = + res28 = res29 = res30 = res31 = res32 = res33 = res34 = res35 = + res36 = res37 = res38 = res39 = get_zero64(); + res1 = fma52lo(res1, a[0], a[1]); // Sum(1) + res2 = fma52hi(res2, a[0], a[1]); // Sum(1) + res2 = fma52lo(res2, a[0], a[2]); // Sum(2) + res3 = fma52hi(res3, a[0], a[2]); // Sum(2) + res3 = fma52lo(res3, a[1], a[2]); // Sum(3) + res4 = fma52hi(res4, a[1], a[2]); // Sum(3) + res3 = fma52lo(res3, a[0], a[3]); // Sum(3) + res4 = fma52hi(res4, a[0], a[3]); // Sum(3) + res4 = fma52lo(res4, a[1], a[3]); // Sum(4) + res5 = fma52hi(res5, a[1], a[3]); // Sum(4) + res5 = fma52lo(res5, a[2], a[3]); // Sum(5) + res6 = fma52hi(res6, a[2], a[3]); // Sum(5) + res4 = fma52lo(res4, a[0], a[4]); // Sum(4) + res5 = fma52hi(res5, a[0], a[4]); // Sum(4) + res5 = fma52lo(res5, a[1], a[4]); // Sum(5) + res6 = fma52hi(res6, a[1], a[4]); // Sum(5) + res6 = fma52lo(res6, a[2], a[4]); // Sum(6) + res7 = fma52hi(res7, a[2], a[4]); // Sum(6) + res7 = fma52lo(res7, a[3], a[4]); // Sum(7) + res8 = fma52hi(res8, a[3], a[4]); // Sum(7) + res5 = fma52lo(res5, a[0], a[5]); // Sum(5) + res6 = fma52hi(res6, a[0], a[5]); // Sum(5) + res6 = fma52lo(res6, a[1], a[5]); // Sum(6) + res7 = fma52hi(res7, a[1], a[5]); // Sum(6) + res7 = fma52lo(res7, a[2], a[5]); // Sum(7) + res8 = fma52hi(res8, a[2], a[5]); // Sum(7) + res8 = fma52lo(res8, a[3], a[5]); // Sum(8) + res9 = fma52hi(res9, a[3], a[5]); // Sum(8) + res9 = fma52lo(res9, a[4], a[5]); // Sum(9) + res10 = fma52hi(res10, a[4], a[5]); // Sum(9) + res6 = fma52lo(res6, a[0], a[6]); // Sum(6) + res7 = fma52hi(res7, a[0], a[6]); // Sum(6) + res7 = fma52lo(res7, a[1], a[6]); // Sum(7) + res8 = fma52hi(res8, a[1], a[6]); // Sum(7) + res8 = fma52lo(res8, a[2], a[6]); // Sum(8) + res9 = fma52hi(res9, a[2], a[6]); // Sum(8) + res9 = fma52lo(res9, a[3], a[6]); // Sum(9) + res10 = fma52hi(res10, a[3], a[6]); // Sum(9) + res10 = fma52lo(res10, a[4], a[6]); // Sum(10) + res11 = fma52hi(res11, a[4], a[6]); // Sum(10) + res11 = fma52lo(res11, a[5], a[6]); // Sum(11) + res12 = fma52hi(res12, a[5], a[6]); // Sum(11) + res7 = fma52lo(res7, a[0], a[7]); // Sum(7) + res8 = fma52hi(res8, a[0], a[7]); // Sum(7) + res8 = fma52lo(res8, a[1], a[7]); // Sum(8) + res9 = fma52hi(res9, a[1], a[7]); // Sum(8) + res9 = fma52lo(res9, a[2], a[7]); // Sum(9) + res10 = fma52hi(res10, a[2], a[7]); // Sum(9) + res10 = fma52lo(res10, a[3], a[7]); // Sum(10) + res11 = fma52hi(res11, a[3], a[7]); // Sum(10) + res11 = fma52lo(res11, a[4], a[7]); // Sum(11) + res12 = fma52hi(res12, a[4], a[7]); // Sum(11) + res8 = fma52lo(res8, a[0], a[8]); // Sum(8) + res9 = fma52hi(res9, a[0], a[8]); // Sum(8) + res9 = fma52lo(res9, a[1], a[8]); // Sum(9) + res10 = fma52hi(res10, a[1], a[8]); // Sum(9) + res10 = fma52lo(res10, a[2], a[8]); // Sum(10) + res11 = fma52hi(res11, a[2], a[8]); // Sum(10) + res11 = fma52lo(res11, a[3], a[8]); // Sum(11) + res12 = fma52hi(res12, a[3], a[8]); // Sum(11) + res9 = fma52lo(res9, a[0], a[9]); // Sum(9) + res10 = fma52hi(res10, a[0], a[9]); // Sum(9) + res10 = fma52lo(res10, a[1], a[9]); // Sum(10) + res11 = fma52hi(res11, a[1], a[9]); // Sum(10) + res11 = fma52lo(res11, a[2], a[9]); // Sum(11) + res12 = fma52hi(res12, a[2], a[9]); // Sum(11) + res10 = fma52lo(res10, a[0], a[10]); // Sum(10) + res11 = fma52hi(res11, a[0], a[10]); // Sum(10) + res11 = fma52lo(res11, a[1], a[10]); // Sum(11) + res12 = fma52hi(res12, a[1], a[10]); // Sum(11) + res11 = fma52lo(res11, a[0], a[11]); // Sum(11) + res12 = fma52hi(res12, a[0], a[11]); // Sum(11) + res0 = add64(res0, res0); // Double(0) + res1 = add64(res1, res1); // Double(1) + res2 = add64(res2, res2); // Double(2) + res3 = add64(res3, res3); // Double(3) + res4 = add64(res4, res4); // Double(4) + res5 = add64(res5, res5); // Double(5) + res6 = add64(res6, res6); // Double(6) + res7 = add64(res7, res7); // Double(7) + res8 = add64(res8, res8); // Double(8) + res9 = add64(res9, res9); // Double(9) + res10 = add64(res10, res10); // Double(10) + res11 = add64(res11, res11); // Double(11) + res0 = fma52lo(res0, a[0], a[0]); // Add sqr(0) + res1 = fma52hi(res1, a[0], a[0]); // Add sqr(0) + res2 = fma52lo(res2, a[1], a[1]); // Add sqr(2) + res3 = fma52hi(res3, a[1], a[1]); // Add sqr(2) + res4 = fma52lo(res4, a[2], a[2]); // Add sqr(4) + res5 = fma52hi(res5, a[2], a[2]); // Add sqr(4) + res6 = fma52lo(res6, a[3], a[3]); // Add sqr(6) + res7 = fma52hi(res7, a[3], a[3]); // Add sqr(6) + res8 = fma52lo(res8, a[4], a[4]); // Add sqr(8) + res9 = fma52hi(res9, a[4], a[4]); // Add sqr(8) + res10 = fma52lo(res10, a[5], a[5]); // Add sqr(10) + res11 = fma52hi(res11, a[5], a[5]); // Add sqr(10) + res12 = fma52lo(res12, a[5], a[7]); // Sum(12) + res13 = fma52hi(res13, a[5], a[7]); // Sum(12) + res13 = fma52lo(res13, a[6], a[7]); // Sum(13) + res14 = fma52hi(res14, a[6], a[7]); // Sum(13) + res12 = fma52lo(res12, a[4], a[8]); // Sum(12) + res13 = fma52hi(res13, a[4], a[8]); // Sum(12) + res13 = fma52lo(res13, a[5], a[8]); // Sum(13) + res14 = fma52hi(res14, a[5], a[8]); // Sum(13) + res14 = fma52lo(res14, a[6], a[8]); // Sum(14) + res15 = fma52hi(res15, a[6], a[8]); // Sum(14) + res15 = fma52lo(res15, a[7], a[8]); // Sum(15) + res16 = fma52hi(res16, a[7], a[8]); // Sum(15) + res12 = fma52lo(res12, a[3], a[9]); // Sum(12) + res13 = fma52hi(res13, a[3], a[9]); // Sum(12) + res13 = fma52lo(res13, a[4], a[9]); // Sum(13) + res14 = fma52hi(res14, a[4], a[9]); // Sum(13) + res14 = fma52lo(res14, a[5], a[9]); // Sum(14) + res15 = fma52hi(res15, a[5], a[9]); // Sum(14) + res15 = fma52lo(res15, a[6], a[9]); // Sum(15) + res16 = fma52hi(res16, a[6], a[9]); // Sum(15) + res16 = fma52lo(res16, a[7], a[9]); // Sum(16) + res17 = fma52hi(res17, a[7], a[9]); // Sum(16) + res17 = fma52lo(res17, a[8], a[9]); // Sum(17) + res18 = fma52hi(res18, a[8], a[9]); // Sum(17) + res12 = fma52lo(res12, a[2], a[10]); // Sum(12) + res13 = fma52hi(res13, a[2], a[10]); // Sum(12) + res13 = fma52lo(res13, a[3], a[10]); // Sum(13) + res14 = fma52hi(res14, a[3], a[10]); // Sum(13) + res14 = fma52lo(res14, a[4], a[10]); // Sum(14) + res15 = fma52hi(res15, a[4], a[10]); // Sum(14) + res15 = fma52lo(res15, a[5], a[10]); // Sum(15) + res16 = fma52hi(res16, a[5], a[10]); // Sum(15) + res16 = fma52lo(res16, a[6], a[10]); // Sum(16) + res17 = fma52hi(res17, a[6], a[10]); // Sum(16) + res17 = fma52lo(res17, a[7], a[10]); // Sum(17) + res18 = fma52hi(res18, a[7], a[10]); // Sum(17) + res18 = fma52lo(res18, a[8], a[10]); // Sum(18) + res19 = fma52hi(res19, a[8], a[10]); // Sum(18) + res19 = fma52lo(res19, a[9], a[10]); // Sum(19) + res20 = fma52hi(res20, a[9], a[10]); // Sum(19) + res12 = fma52lo(res12, a[1], a[11]); // Sum(12) + res13 = fma52hi(res13, a[1], a[11]); // Sum(12) + res13 = fma52lo(res13, a[2], a[11]); // Sum(13) + res14 = fma52hi(res14, a[2], a[11]); // Sum(13) + res14 = fma52lo(res14, a[3], a[11]); // Sum(14) + res15 = fma52hi(res15, a[3], a[11]); // Sum(14) + res15 = fma52lo(res15, a[4], a[11]); // Sum(15) + res16 = fma52hi(res16, a[4], a[11]); // Sum(15) + res16 = fma52lo(res16, a[5], a[11]); // Sum(16) + res17 = fma52hi(res17, a[5], a[11]); // Sum(16) + res17 = fma52lo(res17, a[6], a[11]); // Sum(17) + res18 = fma52hi(res18, a[6], a[11]); // Sum(17) + res18 = fma52lo(res18, a[7], a[11]); // Sum(18) + res19 = fma52hi(res19, a[7], a[11]); // Sum(18) + res19 = fma52lo(res19, a[8], a[11]); // Sum(19) + res20 = fma52hi(res20, a[8], a[11]); // Sum(19) + res20 = fma52lo(res20, a[9], a[11]); // Sum(20) + res21 = fma52hi(res21, a[9], a[11]); // Sum(20) + res21 = fma52lo(res21, a[10], a[11]); // Sum(21) + res22 = fma52hi(res22, a[10], a[11]); // Sum(21) + res12 = fma52lo(res12, a[0], a[12]); // Sum(12) + res13 = fma52hi(res13, a[0], a[12]); // Sum(12) + res13 = fma52lo(res13, a[1], a[12]); // Sum(13) + res14 = fma52hi(res14, a[1], a[12]); // Sum(13) + res14 = fma52lo(res14, a[2], a[12]); // Sum(14) + res15 = fma52hi(res15, a[2], a[12]); // Sum(14) + res15 = fma52lo(res15, a[3], a[12]); // Sum(15) + res16 = fma52hi(res16, a[3], a[12]); // Sum(15) + res16 = fma52lo(res16, a[4], a[12]); // Sum(16) + res17 = fma52hi(res17, a[4], a[12]); // Sum(16) + res17 = fma52lo(res17, a[5], a[12]); // Sum(17) + res18 = fma52hi(res18, a[5], a[12]); // Sum(17) + res18 = fma52lo(res18, a[6], a[12]); // Sum(18) + res19 = fma52hi(res19, a[6], a[12]); // Sum(18) + res19 = fma52lo(res19, a[7], a[12]); // Sum(19) + res20 = fma52hi(res20, a[7], a[12]); // Sum(19) + res20 = fma52lo(res20, a[8], a[12]); // Sum(20) + res21 = fma52hi(res21, a[8], a[12]); // Sum(20) + res21 = fma52lo(res21, a[9], a[12]); // Sum(21) + res22 = fma52hi(res22, a[9], a[12]); // Sum(21) + res22 = fma52lo(res22, a[10], a[12]); // Sum(22) + res23 = fma52hi(res23, a[10], a[12]); // Sum(22) + res23 = fma52lo(res23, a[11], a[12]); // Sum(23) + res24 = fma52hi(res24, a[11], a[12]); // Sum(23) + res13 = fma52lo(res13, a[0], a[13]); // Sum(13) + res14 = fma52hi(res14, a[0], a[13]); // Sum(13) + res14 = fma52lo(res14, a[1], a[13]); // Sum(14) + res15 = fma52hi(res15, a[1], a[13]); // Sum(14) + res15 = fma52lo(res15, a[2], a[13]); // Sum(15) + res16 = fma52hi(res16, a[2], a[13]); // Sum(15) + res16 = fma52lo(res16, a[3], a[13]); // Sum(16) + res17 = fma52hi(res17, a[3], a[13]); // Sum(16) + res17 = fma52lo(res17, a[4], a[13]); // Sum(17) + res18 = fma52hi(res18, a[4], a[13]); // Sum(17) + res18 = fma52lo(res18, a[5], a[13]); // Sum(18) + res19 = fma52hi(res19, a[5], a[13]); // Sum(18) + res19 = fma52lo(res19, a[6], a[13]); // Sum(19) + res20 = fma52hi(res20, a[6], a[13]); // Sum(19) + res20 = fma52lo(res20, a[7], a[13]); // Sum(20) + res21 = fma52hi(res21, a[7], a[13]); // Sum(20) + res21 = fma52lo(res21, a[8], a[13]); // Sum(21) + res22 = fma52hi(res22, a[8], a[13]); // Sum(21) + res22 = fma52lo(res22, a[9], a[13]); // Sum(22) + res23 = fma52hi(res23, a[9], a[13]); // Sum(22) + res23 = fma52lo(res23, a[10], a[13]); // Sum(23) + res24 = fma52hi(res24, a[10], a[13]); // Sum(23) + res14 = fma52lo(res14, a[0], a[14]); // Sum(14) + res15 = fma52hi(res15, a[0], a[14]); // Sum(14) + res15 = fma52lo(res15, a[1], a[14]); // Sum(15) + res16 = fma52hi(res16, a[1], a[14]); // Sum(15) + res16 = fma52lo(res16, a[2], a[14]); // Sum(16) + res17 = fma52hi(res17, a[2], a[14]); // Sum(16) + res17 = fma52lo(res17, a[3], a[14]); // Sum(17) + res18 = fma52hi(res18, a[3], a[14]); // Sum(17) + res18 = fma52lo(res18, a[4], a[14]); // Sum(18) + res19 = fma52hi(res19, a[4], a[14]); // Sum(18) + res19 = fma52lo(res19, a[5], a[14]); // Sum(19) + res20 = fma52hi(res20, a[5], a[14]); // Sum(19) + res20 = fma52lo(res20, a[6], a[14]); // Sum(20) + res21 = fma52hi(res21, a[6], a[14]); // Sum(20) + res21 = fma52lo(res21, a[7], a[14]); // Sum(21) + res22 = fma52hi(res22, a[7], a[14]); // Sum(21) + res22 = fma52lo(res22, a[8], a[14]); // Sum(22) + res23 = fma52hi(res23, a[8], a[14]); // Sum(22) + res23 = fma52lo(res23, a[9], a[14]); // Sum(23) + res24 = fma52hi(res24, a[9], a[14]); // Sum(23) + res15 = fma52lo(res15, a[0], a[15]); // Sum(15) + res16 = fma52hi(res16, a[0], a[15]); // Sum(15) + res16 = fma52lo(res16, a[1], a[15]); // Sum(16) + res17 = fma52hi(res17, a[1], a[15]); // Sum(16) + res17 = fma52lo(res17, a[2], a[15]); // Sum(17) + res18 = fma52hi(res18, a[2], a[15]); // Sum(17) + res18 = fma52lo(res18, a[3], a[15]); // Sum(18) + res19 = fma52hi(res19, a[3], a[15]); // Sum(18) + res19 = fma52lo(res19, a[4], a[15]); // Sum(19) + res20 = fma52hi(res20, a[4], a[15]); // Sum(19) + res20 = fma52lo(res20, a[5], a[15]); // Sum(20) + res21 = fma52hi(res21, a[5], a[15]); // Sum(20) + res21 = fma52lo(res21, a[6], a[15]); // Sum(21) + res22 = fma52hi(res22, a[6], a[15]); // Sum(21) + res22 = fma52lo(res22, a[7], a[15]); // Sum(22) + res23 = fma52hi(res23, a[7], a[15]); // Sum(22) + res23 = fma52lo(res23, a[8], a[15]); // Sum(23) + res24 = fma52hi(res24, a[8], a[15]); // Sum(23) + res16 = fma52lo(res16, a[0], a[16]); // Sum(16) + res17 = fma52hi(res17, a[0], a[16]); // Sum(16) + res17 = fma52lo(res17, a[1], a[16]); // Sum(17) + res18 = fma52hi(res18, a[1], a[16]); // Sum(17) + res18 = fma52lo(res18, a[2], a[16]); // Sum(18) + res19 = fma52hi(res19, a[2], a[16]); // Sum(18) + res19 = fma52lo(res19, a[3], a[16]); // Sum(19) + res20 = fma52hi(res20, a[3], a[16]); // Sum(19) + res20 = fma52lo(res20, a[4], a[16]); // Sum(20) + res21 = fma52hi(res21, a[4], a[16]); // Sum(20) + res21 = fma52lo(res21, a[5], a[16]); // Sum(21) + res22 = fma52hi(res22, a[5], a[16]); // Sum(21) + res22 = fma52lo(res22, a[6], a[16]); // Sum(22) + res23 = fma52hi(res23, a[6], a[16]); // Sum(22) + res23 = fma52lo(res23, a[7], a[16]); // Sum(23) + res24 = fma52hi(res24, a[7], a[16]); // Sum(23) + res17 = fma52lo(res17, a[0], a[17]); // Sum(17) + res18 = fma52hi(res18, a[0], a[17]); // Sum(17) + res18 = fma52lo(res18, a[1], a[17]); // Sum(18) + res19 = fma52hi(res19, a[1], a[17]); // Sum(18) + res19 = fma52lo(res19, a[2], a[17]); // Sum(19) + res20 = fma52hi(res20, a[2], a[17]); // Sum(19) + res20 = fma52lo(res20, a[3], a[17]); // Sum(20) + res21 = fma52hi(res21, a[3], a[17]); // Sum(20) + res21 = fma52lo(res21, a[4], a[17]); // Sum(21) + res22 = fma52hi(res22, a[4], a[17]); // Sum(21) + res22 = fma52lo(res22, a[5], a[17]); // Sum(22) + res23 = fma52hi(res23, a[5], a[17]); // Sum(22) + res23 = fma52lo(res23, a[6], a[17]); // Sum(23) + res24 = fma52hi(res24, a[6], a[17]); // Sum(23) + res18 = fma52lo(res18, a[0], a[18]); // Sum(18) + res19 = fma52hi(res19, a[0], a[18]); // Sum(18) + res19 = fma52lo(res19, a[1], a[18]); // Sum(19) + res20 = fma52hi(res20, a[1], a[18]); // Sum(19) + res20 = fma52lo(res20, a[2], a[18]); // Sum(20) + res21 = fma52hi(res21, a[2], a[18]); // Sum(20) + res21 = fma52lo(res21, a[3], a[18]); // Sum(21) + res22 = fma52hi(res22, a[3], a[18]); // Sum(21) + res22 = fma52lo(res22, a[4], a[18]); // Sum(22) + res23 = fma52hi(res23, a[4], a[18]); // Sum(22) + res23 = fma52lo(res23, a[5], a[18]); // Sum(23) + res24 = fma52hi(res24, a[5], a[18]); // Sum(23) + res19 = fma52lo(res19, a[0], a[19]); // Sum(19) + res20 = fma52hi(res20, a[0], a[19]); // Sum(19) + res20 = fma52lo(res20, a[1], a[19]); // Sum(20) + res21 = fma52hi(res21, a[1], a[19]); // Sum(20) + res21 = fma52lo(res21, a[2], a[19]); // Sum(21) + res22 = fma52hi(res22, a[2], a[19]); // Sum(21) + res22 = fma52lo(res22, a[3], a[19]); // Sum(22) + res23 = fma52hi(res23, a[3], a[19]); // Sum(22) + res23 = fma52lo(res23, a[4], a[19]); // Sum(23) + res24 = fma52hi(res24, a[4], a[19]); // Sum(23) + res12 = add64(res12, res12); // Double(12) + res13 = add64(res13, res13); // Double(13) + res14 = add64(res14, res14); // Double(14) + res15 = add64(res15, res15); // Double(15) + res16 = add64(res16, res16); // Double(16) + res17 = add64(res17, res17); // Double(17) + res18 = add64(res18, res18); // Double(18) + res19 = add64(res19, res19); // Double(19) + res20 = add64(res20, res20); // Double(20) + res21 = add64(res21, res21); // Double(21) + res22 = add64(res22, res22); // Double(22) + res23 = add64(res23, res23); // Double(23) + res12 = fma52lo(res12, a[6], a[6]); // Add sqr(12) + res13 = fma52hi(res13, a[6], a[6]); // Add sqr(12) + res14 = fma52lo(res14, a[7], a[7]); // Add sqr(14) + res15 = fma52hi(res15, a[7], a[7]); // Add sqr(14) + res16 = fma52lo(res16, a[8], a[8]); // Add sqr(16) + res17 = fma52hi(res17, a[8], a[8]); // Add sqr(16) + res18 = fma52lo(res18, a[9], a[9]); // Add sqr(18) + res19 = fma52hi(res19, a[9], a[9]); // Add sqr(18) + res20 = fma52lo(res20, a[10], a[10]); // Add sqr(20) + res21 = fma52hi(res21, a[10], a[10]); // Add sqr(20) + res22 = fma52lo(res22, a[11], a[11]); // Add sqr(22) + res23 = fma52hi(res23, a[11], a[11]); // Add sqr(22) + res24 = fma52lo(res24, a[11], a[13]); // Sum(24) + res25 = fma52hi(res25, a[11], a[13]); // Sum(24) + res25 = fma52lo(res25, a[12], a[13]); // Sum(25) + res26 = fma52hi(res26, a[12], a[13]); // Sum(25) + res24 = fma52lo(res24, a[10], a[14]); // Sum(24) + res25 = fma52hi(res25, a[10], a[14]); // Sum(24) + res25 = fma52lo(res25, a[11], a[14]); // Sum(25) + res26 = fma52hi(res26, a[11], a[14]); // Sum(25) + res26 = fma52lo(res26, a[12], a[14]); // Sum(26) + res27 = fma52hi(res27, a[12], a[14]); // Sum(26) + res27 = fma52lo(res27, a[13], a[14]); // Sum(27) + res28 = fma52hi(res28, a[13], a[14]); // Sum(27) + res24 = fma52lo(res24, a[9], a[15]); // Sum(24) + res25 = fma52hi(res25, a[9], a[15]); // Sum(24) + res25 = fma52lo(res25, a[10], a[15]); // Sum(25) + res26 = fma52hi(res26, a[10], a[15]); // Sum(25) + res26 = fma52lo(res26, a[11], a[15]); // Sum(26) + res27 = fma52hi(res27, a[11], a[15]); // Sum(26) + res27 = fma52lo(res27, a[12], a[15]); // Sum(27) + res28 = fma52hi(res28, a[12], a[15]); // Sum(27) + res28 = fma52lo(res28, a[13], a[15]); // Sum(28) + res29 = fma52hi(res29, a[13], a[15]); // Sum(28) + res29 = fma52lo(res29, a[14], a[15]); // Sum(29) + res30 = fma52hi(res30, a[14], a[15]); // Sum(29) + res24 = fma52lo(res24, a[8], a[16]); // Sum(24) + res25 = fma52hi(res25, a[8], a[16]); // Sum(24) + res25 = fma52lo(res25, a[9], a[16]); // Sum(25) + res26 = fma52hi(res26, a[9], a[16]); // Sum(25) + res26 = fma52lo(res26, a[10], a[16]); // Sum(26) + res27 = fma52hi(res27, a[10], a[16]); // Sum(26) + res27 = fma52lo(res27, a[11], a[16]); // Sum(27) + res28 = fma52hi(res28, a[11], a[16]); // Sum(27) + res28 = fma52lo(res28, a[12], a[16]); // Sum(28) + res29 = fma52hi(res29, a[12], a[16]); // Sum(28) + res29 = fma52lo(res29, a[13], a[16]); // Sum(29) + res30 = fma52hi(res30, a[13], a[16]); // Sum(29) + res30 = fma52lo(res30, a[14], a[16]); // Sum(30) + res31 = fma52hi(res31, a[14], a[16]); // Sum(30) + res31 = fma52lo(res31, a[15], a[16]); // Sum(31) + res32 = fma52hi(res32, a[15], a[16]); // Sum(31) + res24 = fma52lo(res24, a[7], a[17]); // Sum(24) + res25 = fma52hi(res25, a[7], a[17]); // Sum(24) + res25 = fma52lo(res25, a[8], a[17]); // Sum(25) + res26 = fma52hi(res26, a[8], a[17]); // Sum(25) + res26 = fma52lo(res26, a[9], a[17]); // Sum(26) + res27 = fma52hi(res27, a[9], a[17]); // Sum(26) + res27 = fma52lo(res27, a[10], a[17]); // Sum(27) + res28 = fma52hi(res28, a[10], a[17]); // Sum(27) + res28 = fma52lo(res28, a[11], a[17]); // Sum(28) + res29 = fma52hi(res29, a[11], a[17]); // Sum(28) + res29 = fma52lo(res29, a[12], a[17]); // Sum(29) + res30 = fma52hi(res30, a[12], a[17]); // Sum(29) + res30 = fma52lo(res30, a[13], a[17]); // Sum(30) + res31 = fma52hi(res31, a[13], a[17]); // Sum(30) + res31 = fma52lo(res31, a[14], a[17]); // Sum(31) + res32 = fma52hi(res32, a[14], a[17]); // Sum(31) + res32 = fma52lo(res32, a[15], a[17]); // Sum(32) + res33 = fma52hi(res33, a[15], a[17]); // Sum(32) + res33 = fma52lo(res33, a[16], a[17]); // Sum(33) + res34 = fma52hi(res34, a[16], a[17]); // Sum(33) + res24 = fma52lo(res24, a[6], a[18]); // Sum(24) + res25 = fma52hi(res25, a[6], a[18]); // Sum(24) + res25 = fma52lo(res25, a[7], a[18]); // Sum(25) + res26 = fma52hi(res26, a[7], a[18]); // Sum(25) + res26 = fma52lo(res26, a[8], a[18]); // Sum(26) + res27 = fma52hi(res27, a[8], a[18]); // Sum(26) + res27 = fma52lo(res27, a[9], a[18]); // Sum(27) + res28 = fma52hi(res28, a[9], a[18]); // Sum(27) + res28 = fma52lo(res28, a[10], a[18]); // Sum(28) + res29 = fma52hi(res29, a[10], a[18]); // Sum(28) + res29 = fma52lo(res29, a[11], a[18]); // Sum(29) + res30 = fma52hi(res30, a[11], a[18]); // Sum(29) + res30 = fma52lo(res30, a[12], a[18]); // Sum(30) + res31 = fma52hi(res31, a[12], a[18]); // Sum(30) + res31 = fma52lo(res31, a[13], a[18]); // Sum(31) + res32 = fma52hi(res32, a[13], a[18]); // Sum(31) + res32 = fma52lo(res32, a[14], a[18]); // Sum(32) + res33 = fma52hi(res33, a[14], a[18]); // Sum(32) + res33 = fma52lo(res33, a[15], a[18]); // Sum(33) + res34 = fma52hi(res34, a[15], a[18]); // Sum(33) + res34 = fma52lo(res34, a[16], a[18]); // Sum(34) + res35 = fma52hi(res35, a[16], a[18]); // Sum(34) + res35 = fma52lo(res35, a[17], a[18]); // Sum(35) + res36 = fma52hi(res36, a[17], a[18]); // Sum(35) + res24 = fma52lo(res24, a[5], a[19]); // Sum(24) + res25 = fma52hi(res25, a[5], a[19]); // Sum(24) + res25 = fma52lo(res25, a[6], a[19]); // Sum(25) + res26 = fma52hi(res26, a[6], a[19]); // Sum(25) + res26 = fma52lo(res26, a[7], a[19]); // Sum(26) + res27 = fma52hi(res27, a[7], a[19]); // Sum(26) + res27 = fma52lo(res27, a[8], a[19]); // Sum(27) + res28 = fma52hi(res28, a[8], a[19]); // Sum(27) + res28 = fma52lo(res28, a[9], a[19]); // Sum(28) + res29 = fma52hi(res29, a[9], a[19]); // Sum(28) + res29 = fma52lo(res29, a[10], a[19]); // Sum(29) + res30 = fma52hi(res30, a[10], a[19]); // Sum(29) + res30 = fma52lo(res30, a[11], a[19]); // Sum(30) + res31 = fma52hi(res31, a[11], a[19]); // Sum(30) + res31 = fma52lo(res31, a[12], a[19]); // Sum(31) + res32 = fma52hi(res32, a[12], a[19]); // Sum(31) + res32 = fma52lo(res32, a[13], a[19]); // Sum(32) + res33 = fma52hi(res33, a[13], a[19]); // Sum(32) + res33 = fma52lo(res33, a[14], a[19]); // Sum(33) + res34 = fma52hi(res34, a[14], a[19]); // Sum(33) + res34 = fma52lo(res34, a[15], a[19]); // Sum(34) + res35 = fma52hi(res35, a[15], a[19]); // Sum(34) + res35 = fma52lo(res35, a[16], a[19]); // Sum(35) + res36 = fma52hi(res36, a[16], a[19]); // Sum(35) + res24 = add64(res24, res24); // Double(24) + res25 = add64(res25, res25); // Double(25) + res26 = add64(res26, res26); // Double(26) + res27 = add64(res27, res27); // Double(27) + res28 = add64(res28, res28); // Double(28) + res29 = add64(res29, res29); // Double(29) + res30 = add64(res30, res30); // Double(30) + res31 = add64(res31, res31); // Double(31) + res32 = add64(res32, res32); // Double(32) + res33 = add64(res33, res33); // Double(33) + res34 = add64(res34, res34); // Double(34) + res35 = add64(res35, res35); // Double(35) + res24 = fma52lo(res24, a[12], a[12]); // Add sqr(24) + res25 = fma52hi(res25, a[12], a[12]); // Add sqr(24) + res26 = fma52lo(res26, a[13], a[13]); // Add sqr(26) + res27 = fma52hi(res27, a[13], a[13]); // Add sqr(26) + res28 = fma52lo(res28, a[14], a[14]); // Add sqr(28) + res29 = fma52hi(res29, a[14], a[14]); // Add sqr(28) + res30 = fma52lo(res30, a[15], a[15]); // Add sqr(30) + res31 = fma52hi(res31, a[15], a[15]); // Add sqr(30) + res32 = fma52lo(res32, a[16], a[16]); // Add sqr(32) + res33 = fma52hi(res33, a[16], a[16]); // Add sqr(32) + res34 = fma52lo(res34, a[17], a[17]); // Add sqr(34) + res35 = fma52hi(res35, a[17], a[17]); // Add sqr(34) + res36 = fma52lo(res36, a[17], a[19]); // Sum(36) + res37 = fma52hi(res37, a[17], a[19]); // Sum(36) + res37 = fma52lo(res37, a[18], a[19]); // Sum(37) + res38 = fma52hi(res38, a[18], a[19]); // Sum(37) + res36 = add64(res36, res36); // Double(36) + res37 = add64(res37, res37); // Double(37) + res38 = add64(res38, res38); // Double(38) + res36 = fma52lo(res36, a[18], a[18]); // Add sqr(36) + res37 = fma52hi(res37, a[18], a[18]); // Add sqr(36) + res38 = fma52lo(res38, a[19], a[19]); // Add sqr(38) + res39 = fma52hi(res39, a[19], a[19]); // Add sqr(38) + + // Generate u_i + U64 u0 = mul52lo(res0, k); + ASM("jmp l0\nl0:\n"); + + // Create u0 + fma52lo_mem(res0, res0, u0, m, SIMD_BYTES * 0); + fma52hi_mem(res1, res1, u0, m, SIMD_BYTES * 0); + res1 = fma52lo(res1, u0, m[1]); + res2 = fma52hi(res2, u0, m[1]); + res1 = add64(res1, srli64(res0, DIGIT_SIZE)); + U64 u1 = mul52lo(res1, k); + fma52lo_mem(res2, res2, u0, m, SIMD_BYTES * 2); + fma52hi_mem(res3, res3, u0, m, SIMD_BYTES * 2); + res3 = fma52lo(res3, u0, m[3]); + res4 = fma52hi(res4, u0, m[3]); + fma52lo_mem(res4, res4, u0, m, SIMD_BYTES * 4); + fma52hi_mem(res5, res5, u0, m, SIMD_BYTES * 4); + res5 = fma52lo(res5, u0, m[5]); + res6 = fma52hi(res6, u0, m[5]); + fma52lo_mem(res6, res6, u0, m, SIMD_BYTES * 6); + fma52hi_mem(res7, res7, u0, m, SIMD_BYTES * 6); + res7 = fma52lo(res7, u0, m[7]); + res8 = fma52hi(res8, u0, m[7]); + fma52lo_mem(res8, res8, u0, m, SIMD_BYTES * 8); + fma52hi_mem(res9, res9, u0, m, SIMD_BYTES * 8); + res9 = fma52lo(res9, u0, m[9]); + res10 = fma52hi(res10, u0, m[9]); + fma52lo_mem(res10, res10, u0, m, SIMD_BYTES * 10); + fma52hi_mem(res11, res11, u0, m, SIMD_BYTES * 10); + res11 = fma52lo(res11, u0, m[11]); + res12 = fma52hi(res12, u0, m[11]); + fma52lo_mem(res12, res12, u0, m, SIMD_BYTES * 12); + fma52hi_mem(res13, res13, u0, m, SIMD_BYTES * 12); + res13 = fma52lo(res13, u0, m[13]); + res14 = fma52hi(res14, u0, m[13]); + fma52lo_mem(res14, res14, u0, m, SIMD_BYTES * 14); + fma52hi_mem(res15, res15, u0, m, SIMD_BYTES * 14); + res15 = fma52lo(res15, u0, m[15]); + res16 = fma52hi(res16, u0, m[15]); + fma52lo_mem(res16, res16, u0, m, SIMD_BYTES * 16); + fma52hi_mem(res17, res17, u0, m, SIMD_BYTES * 16); + res17 = fma52lo(res17, u0, m[17]); + res18 = fma52hi(res18, u0, m[17]); + fma52lo_mem(res18, res18, u0, m, SIMD_BYTES * 18); + fma52hi_mem(res19, res19, u0, m, SIMD_BYTES * 18); + res19 = fma52lo(res19, u0, m[19]); + res20 = fma52hi(res20, u0, m[19]); + + // Create u1 + fma52lo_mem(res1, res1, u1, m, SIMD_BYTES * 0); + fma52hi_mem(res2, res2, u1, m, SIMD_BYTES * 0); + res2 = fma52lo(res2, u1, m[1]); + res3 = fma52hi(res3, u1, m[1]); + res2 = add64(res2, srli64(res1, DIGIT_SIZE)); + U64 u2 = mul52lo(res2, k); + fma52lo_mem(res3, res3, u1, m, SIMD_BYTES * 2); + fma52hi_mem(res4, res4, u1, m, SIMD_BYTES * 2); + res4 = fma52lo(res4, u1, m[3]); + res5 = fma52hi(res5, u1, m[3]); + fma52lo_mem(res5, res5, u1, m, SIMD_BYTES * 4); + fma52hi_mem(res6, res6, u1, m, SIMD_BYTES * 4); + res6 = fma52lo(res6, u1, m[5]); + res7 = fma52hi(res7, u1, m[5]); + fma52lo_mem(res7, res7, u1, m, SIMD_BYTES * 6); + fma52hi_mem(res8, res8, u1, m, SIMD_BYTES * 6); + res8 = fma52lo(res8, u1, m[7]); + res9 = fma52hi(res9, u1, m[7]); + fma52lo_mem(res9, res9, u1, m, SIMD_BYTES * 8); + fma52hi_mem(res10, res10, u1, m, SIMD_BYTES * 8); + res10 = fma52lo(res10, u1, m[9]); + res11 = fma52hi(res11, u1, m[9]); + fma52lo_mem(res11, res11, u1, m, SIMD_BYTES * 10); + fma52hi_mem(res12, res12, u1, m, SIMD_BYTES * 10); + res12 = fma52lo(res12, u1, m[11]); + res13 = fma52hi(res13, u1, m[11]); + fma52lo_mem(res13, res13, u1, m, SIMD_BYTES * 12); + fma52hi_mem(res14, res14, u1, m, SIMD_BYTES * 12); + res14 = fma52lo(res14, u1, m[13]); + res15 = fma52hi(res15, u1, m[13]); + fma52lo_mem(res15, res15, u1, m, SIMD_BYTES * 14); + fma52hi_mem(res16, res16, u1, m, SIMD_BYTES * 14); + res16 = fma52lo(res16, u1, m[15]); + res17 = fma52hi(res17, u1, m[15]); + fma52lo_mem(res17, res17, u1, m, SIMD_BYTES * 16); + fma52hi_mem(res18, res18, u1, m, SIMD_BYTES * 16); + res18 = fma52lo(res18, u1, m[17]); + res19 = fma52hi(res19, u1, m[17]); + fma52lo_mem(res19, res19, u1, m, SIMD_BYTES * 18); + fma52hi_mem(res20, res20, u1, m, SIMD_BYTES * 18); + res20 = fma52lo(res20, u1, m[19]); + res21 = fma52hi(res21, u1, m[19]); + ASM("jmp l2\nl2:\n"); + + // Create u2 + fma52lo_mem(res2, res2, u2, m, SIMD_BYTES * 0); + fma52hi_mem(res3, res3, u2, m, SIMD_BYTES * 0); + res3 = fma52lo(res3, u2, m[1]); + res4 = fma52hi(res4, u2, m[1]); + res3 = add64(res3, srli64(res2, DIGIT_SIZE)); + U64 u3 = mul52lo(res3, k); + fma52lo_mem(res4, res4, u2, m, SIMD_BYTES * 2); + fma52hi_mem(res5, res5, u2, m, SIMD_BYTES * 2); + res5 = fma52lo(res5, u2, m[3]); + res6 = fma52hi(res6, u2, m[3]); + fma52lo_mem(res6, res6, u2, m, SIMD_BYTES * 4); + fma52hi_mem(res7, res7, u2, m, SIMD_BYTES * 4); + res7 = fma52lo(res7, u2, m[5]); + res8 = fma52hi(res8, u2, m[5]); + fma52lo_mem(res8, res8, u2, m, SIMD_BYTES * 6); + fma52hi_mem(res9, res9, u2, m, SIMD_BYTES * 6); + res9 = fma52lo(res9, u2, m[7]); + res10 = fma52hi(res10, u2, m[7]); + fma52lo_mem(res10, res10, u2, m, SIMD_BYTES * 8); + fma52hi_mem(res11, res11, u2, m, SIMD_BYTES * 8); + res11 = fma52lo(res11, u2, m[9]); + res12 = fma52hi(res12, u2, m[9]); + fma52lo_mem(res12, res12, u2, m, SIMD_BYTES * 10); + fma52hi_mem(res13, res13, u2, m, SIMD_BYTES * 10); + res13 = fma52lo(res13, u2, m[11]); + res14 = fma52hi(res14, u2, m[11]); + fma52lo_mem(res14, res14, u2, m, SIMD_BYTES * 12); + fma52hi_mem(res15, res15, u2, m, SIMD_BYTES * 12); + res15 = fma52lo(res15, u2, m[13]); + res16 = fma52hi(res16, u2, m[13]); + fma52lo_mem(res16, res16, u2, m, SIMD_BYTES * 14); + fma52hi_mem(res17, res17, u2, m, SIMD_BYTES * 14); + res17 = fma52lo(res17, u2, m[15]); + res18 = fma52hi(res18, u2, m[15]); + fma52lo_mem(res18, res18, u2, m, SIMD_BYTES * 16); + fma52hi_mem(res19, res19, u2, m, SIMD_BYTES * 16); + res19 = fma52lo(res19, u2, m[17]); + res20 = fma52hi(res20, u2, m[17]); + fma52lo_mem(res20, res20, u2, m, SIMD_BYTES * 18); + fma52hi_mem(res21, res21, u2, m, SIMD_BYTES * 18); + res21 = fma52lo(res21, u2, m[19]); + res22 = fma52hi(res22, u2, m[19]); + + // Create u3 + fma52lo_mem(res3, res3, u3, m, SIMD_BYTES * 0); + fma52hi_mem(res4, res4, u3, m, SIMD_BYTES * 0); + res4 = fma52lo(res4, u3, m[1]); + res5 = fma52hi(res5, u3, m[1]); + res4 = add64(res4, srli64(res3, DIGIT_SIZE)); + U64 u4 = mul52lo(res4, k); + fma52lo_mem(res5, res5, u3, m, SIMD_BYTES * 2); + fma52hi_mem(res6, res6, u3, m, SIMD_BYTES * 2); + res6 = fma52lo(res6, u3, m[3]); + res7 = fma52hi(res7, u3, m[3]); + fma52lo_mem(res7, res7, u3, m, SIMD_BYTES * 4); + fma52hi_mem(res8, res8, u3, m, SIMD_BYTES * 4); + res8 = fma52lo(res8, u3, m[5]); + res9 = fma52hi(res9, u3, m[5]); + fma52lo_mem(res9, res9, u3, m, SIMD_BYTES * 6); + fma52hi_mem(res10, res10, u3, m, SIMD_BYTES * 6); + res10 = fma52lo(res10, u3, m[7]); + res11 = fma52hi(res11, u3, m[7]); + fma52lo_mem(res11, res11, u3, m, SIMD_BYTES * 8); + fma52hi_mem(res12, res12, u3, m, SIMD_BYTES * 8); + res12 = fma52lo(res12, u3, m[9]); + res13 = fma52hi(res13, u3, m[9]); + fma52lo_mem(res13, res13, u3, m, SIMD_BYTES * 10); + fma52hi_mem(res14, res14, u3, m, SIMD_BYTES * 10); + res14 = fma52lo(res14, u3, m[11]); + res15 = fma52hi(res15, u3, m[11]); + fma52lo_mem(res15, res15, u3, m, SIMD_BYTES * 12); + fma52hi_mem(res16, res16, u3, m, SIMD_BYTES * 12); + res16 = fma52lo(res16, u3, m[13]); + res17 = fma52hi(res17, u3, m[13]); + fma52lo_mem(res17, res17, u3, m, SIMD_BYTES * 14); + fma52hi_mem(res18, res18, u3, m, SIMD_BYTES * 14); + res18 = fma52lo(res18, u3, m[15]); + res19 = fma52hi(res19, u3, m[15]); + fma52lo_mem(res19, res19, u3, m, SIMD_BYTES * 16); + fma52hi_mem(res20, res20, u3, m, SIMD_BYTES * 16); + res20 = fma52lo(res20, u3, m[17]); + res21 = fma52hi(res21, u3, m[17]); + fma52lo_mem(res21, res21, u3, m, SIMD_BYTES * 18); + fma52hi_mem(res22, res22, u3, m, SIMD_BYTES * 18); + res22 = fma52lo(res22, u3, m[19]); + res23 = fma52hi(res23, u3, m[19]); + ASM("jmp l4\nl4:\n"); + + // Create u4 + fma52lo_mem(res4, res4, u4, m, SIMD_BYTES * 0); + fma52hi_mem(res5, res5, u4, m, SIMD_BYTES * 0); + res5 = fma52lo(res5, u4, m[1]); + res6 = fma52hi(res6, u4, m[1]); + res5 = add64(res5, srli64(res4, DIGIT_SIZE)); + U64 u5 = mul52lo(res5, k); + fma52lo_mem(res6, res6, u4, m, SIMD_BYTES * 2); + fma52hi_mem(res7, res7, u4, m, SIMD_BYTES * 2); + res7 = fma52lo(res7, u4, m[3]); + res8 = fma52hi(res8, u4, m[3]); + fma52lo_mem(res8, res8, u4, m, SIMD_BYTES * 4); + fma52hi_mem(res9, res9, u4, m, SIMD_BYTES * 4); + res9 = fma52lo(res9, u4, m[5]); + res10 = fma52hi(res10, u4, m[5]); + fma52lo_mem(res10, res10, u4, m, SIMD_BYTES * 6); + fma52hi_mem(res11, res11, u4, m, SIMD_BYTES * 6); + res11 = fma52lo(res11, u4, m[7]); + res12 = fma52hi(res12, u4, m[7]); + fma52lo_mem(res12, res12, u4, m, SIMD_BYTES * 8); + fma52hi_mem(res13, res13, u4, m, SIMD_BYTES * 8); + res13 = fma52lo(res13, u4, m[9]); + res14 = fma52hi(res14, u4, m[9]); + fma52lo_mem(res14, res14, u4, m, SIMD_BYTES * 10); + fma52hi_mem(res15, res15, u4, m, SIMD_BYTES * 10); + res15 = fma52lo(res15, u4, m[11]); + res16 = fma52hi(res16, u4, m[11]); + fma52lo_mem(res16, res16, u4, m, SIMD_BYTES * 12); + fma52hi_mem(res17, res17, u4, m, SIMD_BYTES * 12); + res17 = fma52lo(res17, u4, m[13]); + res18 = fma52hi(res18, u4, m[13]); + fma52lo_mem(res18, res18, u4, m, SIMD_BYTES * 14); + fma52hi_mem(res19, res19, u4, m, SIMD_BYTES * 14); + res19 = fma52lo(res19, u4, m[15]); + res20 = fma52hi(res20, u4, m[15]); + fma52lo_mem(res20, res20, u4, m, SIMD_BYTES * 16); + fma52hi_mem(res21, res21, u4, m, SIMD_BYTES * 16); + res21 = fma52lo(res21, u4, m[17]); + res22 = fma52hi(res22, u4, m[17]); + fma52lo_mem(res22, res22, u4, m, SIMD_BYTES * 18); + fma52hi_mem(res23, res23, u4, m, SIMD_BYTES * 18); + res23 = fma52lo(res23, u4, m[19]); + res24 = fma52hi(res24, u4, m[19]); + + // Create u5 + fma52lo_mem(res5, res5, u5, m, SIMD_BYTES * 0); + fma52hi_mem(res6, res6, u5, m, SIMD_BYTES * 0); + res6 = fma52lo(res6, u5, m[1]); + res7 = fma52hi(res7, u5, m[1]); + res6 = add64(res6, srli64(res5, DIGIT_SIZE)); + U64 u6 = mul52lo(res6, k); + fma52lo_mem(res7, res7, u5, m, SIMD_BYTES * 2); + fma52hi_mem(res8, res8, u5, m, SIMD_BYTES * 2); + res8 = fma52lo(res8, u5, m[3]); + res9 = fma52hi(res9, u5, m[3]); + fma52lo_mem(res9, res9, u5, m, SIMD_BYTES * 4); + fma52hi_mem(res10, res10, u5, m, SIMD_BYTES * 4); + res10 = fma52lo(res10, u5, m[5]); + res11 = fma52hi(res11, u5, m[5]); + fma52lo_mem(res11, res11, u5, m, SIMD_BYTES * 6); + fma52hi_mem(res12, res12, u5, m, SIMD_BYTES * 6); + res12 = fma52lo(res12, u5, m[7]); + res13 = fma52hi(res13, u5, m[7]); + fma52lo_mem(res13, res13, u5, m, SIMD_BYTES * 8); + fma52hi_mem(res14, res14, u5, m, SIMD_BYTES * 8); + res14 = fma52lo(res14, u5, m[9]); + res15 = fma52hi(res15, u5, m[9]); + fma52lo_mem(res15, res15, u5, m, SIMD_BYTES * 10); + fma52hi_mem(res16, res16, u5, m, SIMD_BYTES * 10); + res16 = fma52lo(res16, u5, m[11]); + res17 = fma52hi(res17, u5, m[11]); + fma52lo_mem(res17, res17, u5, m, SIMD_BYTES * 12); + fma52hi_mem(res18, res18, u5, m, SIMD_BYTES * 12); + res18 = fma52lo(res18, u5, m[13]); + res19 = fma52hi(res19, u5, m[13]); + fma52lo_mem(res19, res19, u5, m, SIMD_BYTES * 14); + fma52hi_mem(res20, res20, u5, m, SIMD_BYTES * 14); + res20 = fma52lo(res20, u5, m[15]); + res21 = fma52hi(res21, u5, m[15]); + fma52lo_mem(res21, res21, u5, m, SIMD_BYTES * 16); + fma52hi_mem(res22, res22, u5, m, SIMD_BYTES * 16); + res22 = fma52lo(res22, u5, m[17]); + res23 = fma52hi(res23, u5, m[17]); + fma52lo_mem(res23, res23, u5, m, SIMD_BYTES * 18); + fma52hi_mem(res24, res24, u5, m, SIMD_BYTES * 18); + res24 = fma52lo(res24, u5, m[19]); + res25 = fma52hi(res25, u5, m[19]); + ASM("jmp l6\nl6:\n"); + + // Create u6 + fma52lo_mem(res6, res6, u6, m, SIMD_BYTES * 0); + fma52hi_mem(res7, res7, u6, m, SIMD_BYTES * 0); + res7 = fma52lo(res7, u6, m[1]); + res8 = fma52hi(res8, u6, m[1]); + res7 = add64(res7, srli64(res6, DIGIT_SIZE)); + U64 u7 = mul52lo(res7, k); + fma52lo_mem(res8, res8, u6, m, SIMD_BYTES * 2); + fma52hi_mem(res9, res9, u6, m, SIMD_BYTES * 2); + res9 = fma52lo(res9, u6, m[3]); + res10 = fma52hi(res10, u6, m[3]); + fma52lo_mem(res10, res10, u6, m, SIMD_BYTES * 4); + fma52hi_mem(res11, res11, u6, m, SIMD_BYTES * 4); + res11 = fma52lo(res11, u6, m[5]); + res12 = fma52hi(res12, u6, m[5]); + fma52lo_mem(res12, res12, u6, m, SIMD_BYTES * 6); + fma52hi_mem(res13, res13, u6, m, SIMD_BYTES * 6); + res13 = fma52lo(res13, u6, m[7]); + res14 = fma52hi(res14, u6, m[7]); + fma52lo_mem(res14, res14, u6, m, SIMD_BYTES * 8); + fma52hi_mem(res15, res15, u6, m, SIMD_BYTES * 8); + res15 = fma52lo(res15, u6, m[9]); + res16 = fma52hi(res16, u6, m[9]); + fma52lo_mem(res16, res16, u6, m, SIMD_BYTES * 10); + fma52hi_mem(res17, res17, u6, m, SIMD_BYTES * 10); + res17 = fma52lo(res17, u6, m[11]); + res18 = fma52hi(res18, u6, m[11]); + fma52lo_mem(res18, res18, u6, m, SIMD_BYTES * 12); + fma52hi_mem(res19, res19, u6, m, SIMD_BYTES * 12); + res19 = fma52lo(res19, u6, m[13]); + res20 = fma52hi(res20, u6, m[13]); + fma52lo_mem(res20, res20, u6, m, SIMD_BYTES * 14); + fma52hi_mem(res21, res21, u6, m, SIMD_BYTES * 14); + res21 = fma52lo(res21, u6, m[15]); + res22 = fma52hi(res22, u6, m[15]); + fma52lo_mem(res22, res22, u6, m, SIMD_BYTES * 16); + fma52hi_mem(res23, res23, u6, m, SIMD_BYTES * 16); + res23 = fma52lo(res23, u6, m[17]); + res24 = fma52hi(res24, u6, m[17]); + fma52lo_mem(res24, res24, u6, m, SIMD_BYTES * 18); + fma52hi_mem(res25, res25, u6, m, SIMD_BYTES * 18); + res25 = fma52lo(res25, u6, m[19]); + res26 = fma52hi(res26, u6, m[19]); + + // Create u7 + fma52lo_mem(res7, res7, u7, m, SIMD_BYTES * 0); + fma52hi_mem(res8, res8, u7, m, SIMD_BYTES * 0); + res8 = fma52lo(res8, u7, m[1]); + res9 = fma52hi(res9, u7, m[1]); + res8 = add64(res8, srli64(res7, DIGIT_SIZE)); + U64 u8 = mul52lo(res8, k); + fma52lo_mem(res9, res9, u7, m, SIMD_BYTES * 2); + fma52hi_mem(res10, res10, u7, m, SIMD_BYTES * 2); + res10 = fma52lo(res10, u7, m[3]); + res11 = fma52hi(res11, u7, m[3]); + fma52lo_mem(res11, res11, u7, m, SIMD_BYTES * 4); + fma52hi_mem(res12, res12, u7, m, SIMD_BYTES * 4); + res12 = fma52lo(res12, u7, m[5]); + res13 = fma52hi(res13, u7, m[5]); + fma52lo_mem(res13, res13, u7, m, SIMD_BYTES * 6); + fma52hi_mem(res14, res14, u7, m, SIMD_BYTES * 6); + res14 = fma52lo(res14, u7, m[7]); + res15 = fma52hi(res15, u7, m[7]); + fma52lo_mem(res15, res15, u7, m, SIMD_BYTES * 8); + fma52hi_mem(res16, res16, u7, m, SIMD_BYTES * 8); + res16 = fma52lo(res16, u7, m[9]); + res17 = fma52hi(res17, u7, m[9]); + fma52lo_mem(res17, res17, u7, m, SIMD_BYTES * 10); + fma52hi_mem(res18, res18, u7, m, SIMD_BYTES * 10); + res18 = fma52lo(res18, u7, m[11]); + res19 = fma52hi(res19, u7, m[11]); + fma52lo_mem(res19, res19, u7, m, SIMD_BYTES * 12); + fma52hi_mem(res20, res20, u7, m, SIMD_BYTES * 12); + res20 = fma52lo(res20, u7, m[13]); + res21 = fma52hi(res21, u7, m[13]); + fma52lo_mem(res21, res21, u7, m, SIMD_BYTES * 14); + fma52hi_mem(res22, res22, u7, m, SIMD_BYTES * 14); + res22 = fma52lo(res22, u7, m[15]); + res23 = fma52hi(res23, u7, m[15]); + fma52lo_mem(res23, res23, u7, m, SIMD_BYTES * 16); + fma52hi_mem(res24, res24, u7, m, SIMD_BYTES * 16); + res24 = fma52lo(res24, u7, m[17]); + res25 = fma52hi(res25, u7, m[17]); + fma52lo_mem(res25, res25, u7, m, SIMD_BYTES * 18); + fma52hi_mem(res26, res26, u7, m, SIMD_BYTES * 18); + res26 = fma52lo(res26, u7, m[19]); + res27 = fma52hi(res27, u7, m[19]); + ASM("jmp l8\nl8:\n"); + + // Create u8 + fma52lo_mem(res8, res8, u8, m, SIMD_BYTES * 0); + fma52hi_mem(res9, res9, u8, m, SIMD_BYTES * 0); + res9 = fma52lo(res9, u8, m[1]); + res10 = fma52hi(res10, u8, m[1]); + res9 = add64(res9, srli64(res8, DIGIT_SIZE)); + U64 u9 = mul52lo(res9, k); + fma52lo_mem(res10, res10, u8, m, SIMD_BYTES * 2); + fma52hi_mem(res11, res11, u8, m, SIMD_BYTES * 2); + res11 = fma52lo(res11, u8, m[3]); + res12 = fma52hi(res12, u8, m[3]); + fma52lo_mem(res12, res12, u8, m, SIMD_BYTES * 4); + fma52hi_mem(res13, res13, u8, m, SIMD_BYTES * 4); + res13 = fma52lo(res13, u8, m[5]); + res14 = fma52hi(res14, u8, m[5]); + fma52lo_mem(res14, res14, u8, m, SIMD_BYTES * 6); + fma52hi_mem(res15, res15, u8, m, SIMD_BYTES * 6); + res15 = fma52lo(res15, u8, m[7]); + res16 = fma52hi(res16, u8, m[7]); + fma52lo_mem(res16, res16, u8, m, SIMD_BYTES * 8); + fma52hi_mem(res17, res17, u8, m, SIMD_BYTES * 8); + res17 = fma52lo(res17, u8, m[9]); + res18 = fma52hi(res18, u8, m[9]); + fma52lo_mem(res18, res18, u8, m, SIMD_BYTES * 10); + fma52hi_mem(res19, res19, u8, m, SIMD_BYTES * 10); + res19 = fma52lo(res19, u8, m[11]); + res20 = fma52hi(res20, u8, m[11]); + fma52lo_mem(res20, res20, u8, m, SIMD_BYTES * 12); + fma52hi_mem(res21, res21, u8, m, SIMD_BYTES * 12); + res21 = fma52lo(res21, u8, m[13]); + res22 = fma52hi(res22, u8, m[13]); + fma52lo_mem(res22, res22, u8, m, SIMD_BYTES * 14); + fma52hi_mem(res23, res23, u8, m, SIMD_BYTES * 14); + res23 = fma52lo(res23, u8, m[15]); + res24 = fma52hi(res24, u8, m[15]); + fma52lo_mem(res24, res24, u8, m, SIMD_BYTES * 16); + fma52hi_mem(res25, res25, u8, m, SIMD_BYTES * 16); + res25 = fma52lo(res25, u8, m[17]); + res26 = fma52hi(res26, u8, m[17]); + fma52lo_mem(res26, res26, u8, m, SIMD_BYTES * 18); + fma52hi_mem(res27, res27, u8, m, SIMD_BYTES * 18); + res27 = fma52lo(res27, u8, m[19]); + res28 = fma52hi(res28, u8, m[19]); + + // Create u9 + fma52lo_mem(res9, res9, u9, m, SIMD_BYTES * 0); + fma52hi_mem(res10, res10, u9, m, SIMD_BYTES * 0); + res10 = fma52lo(res10, u9, m[1]); + res11 = fma52hi(res11, u9, m[1]); + res10 = add64(res10, srli64(res9, DIGIT_SIZE)); + U64 u10 = mul52lo(res10, k); + fma52lo_mem(res11, res11, u9, m, SIMD_BYTES * 2); + fma52hi_mem(res12, res12, u9, m, SIMD_BYTES * 2); + res12 = fma52lo(res12, u9, m[3]); + res13 = fma52hi(res13, u9, m[3]); + fma52lo_mem(res13, res13, u9, m, SIMD_BYTES * 4); + fma52hi_mem(res14, res14, u9, m, SIMD_BYTES * 4); + res14 = fma52lo(res14, u9, m[5]); + res15 = fma52hi(res15, u9, m[5]); + fma52lo_mem(res15, res15, u9, m, SIMD_BYTES * 6); + fma52hi_mem(res16, res16, u9, m, SIMD_BYTES * 6); + res16 = fma52lo(res16, u9, m[7]); + res17 = fma52hi(res17, u9, m[7]); + fma52lo_mem(res17, res17, u9, m, SIMD_BYTES * 8); + fma52hi_mem(res18, res18, u9, m, SIMD_BYTES * 8); + res18 = fma52lo(res18, u9, m[9]); + res19 = fma52hi(res19, u9, m[9]); + fma52lo_mem(res19, res19, u9, m, SIMD_BYTES * 10); + fma52hi_mem(res20, res20, u9, m, SIMD_BYTES * 10); + res20 = fma52lo(res20, u9, m[11]); + res21 = fma52hi(res21, u9, m[11]); + fma52lo_mem(res21, res21, u9, m, SIMD_BYTES * 12); + fma52hi_mem(res22, res22, u9, m, SIMD_BYTES * 12); + res22 = fma52lo(res22, u9, m[13]); + res23 = fma52hi(res23, u9, m[13]); + fma52lo_mem(res23, res23, u9, m, SIMD_BYTES * 14); + fma52hi_mem(res24, res24, u9, m, SIMD_BYTES * 14); + res24 = fma52lo(res24, u9, m[15]); + res25 = fma52hi(res25, u9, m[15]); + fma52lo_mem(res25, res25, u9, m, SIMD_BYTES * 16); + fma52hi_mem(res26, res26, u9, m, SIMD_BYTES * 16); + res26 = fma52lo(res26, u9, m[17]); + res27 = fma52hi(res27, u9, m[17]); + fma52lo_mem(res27, res27, u9, m, SIMD_BYTES * 18); + fma52hi_mem(res28, res28, u9, m, SIMD_BYTES * 18); + res28 = fma52lo(res28, u9, m[19]); + res29 = fma52hi(res29, u9, m[19]); + ASM("jmp l10\nl10:\n"); + + // Create u10 + fma52lo_mem(res10, res10, u10, m, SIMD_BYTES * 0); + fma52hi_mem(res11, res11, u10, m, SIMD_BYTES * 0); + res11 = fma52lo(res11, u10, m[1]); + res12 = fma52hi(res12, u10, m[1]); + res11 = add64(res11, srli64(res10, DIGIT_SIZE)); + U64 u11 = mul52lo(res11, k); + fma52lo_mem(res12, res12, u10, m, SIMD_BYTES * 2); + fma52hi_mem(res13, res13, u10, m, SIMD_BYTES * 2); + res13 = fma52lo(res13, u10, m[3]); + res14 = fma52hi(res14, u10, m[3]); + fma52lo_mem(res14, res14, u10, m, SIMD_BYTES * 4); + fma52hi_mem(res15, res15, u10, m, SIMD_BYTES * 4); + res15 = fma52lo(res15, u10, m[5]); + res16 = fma52hi(res16, u10, m[5]); + fma52lo_mem(res16, res16, u10, m, SIMD_BYTES * 6); + fma52hi_mem(res17, res17, u10, m, SIMD_BYTES * 6); + res17 = fma52lo(res17, u10, m[7]); + res18 = fma52hi(res18, u10, m[7]); + fma52lo_mem(res18, res18, u10, m, SIMD_BYTES * 8); + fma52hi_mem(res19, res19, u10, m, SIMD_BYTES * 8); + res19 = fma52lo(res19, u10, m[9]); + res20 = fma52hi(res20, u10, m[9]); + fma52lo_mem(res20, res20, u10, m, SIMD_BYTES * 10); + fma52hi_mem(res21, res21, u10, m, SIMD_BYTES * 10); + res21 = fma52lo(res21, u10, m[11]); + res22 = fma52hi(res22, u10, m[11]); + fma52lo_mem(res22, res22, u10, m, SIMD_BYTES * 12); + fma52hi_mem(res23, res23, u10, m, SIMD_BYTES * 12); + res23 = fma52lo(res23, u10, m[13]); + res24 = fma52hi(res24, u10, m[13]); + fma52lo_mem(res24, res24, u10, m, SIMD_BYTES * 14); + fma52hi_mem(res25, res25, u10, m, SIMD_BYTES * 14); + res25 = fma52lo(res25, u10, m[15]); + res26 = fma52hi(res26, u10, m[15]); + fma52lo_mem(res26, res26, u10, m, SIMD_BYTES * 16); + fma52hi_mem(res27, res27, u10, m, SIMD_BYTES * 16); + res27 = fma52lo(res27, u10, m[17]); + res28 = fma52hi(res28, u10, m[17]); + fma52lo_mem(res28, res28, u10, m, SIMD_BYTES * 18); + fma52hi_mem(res29, res29, u10, m, SIMD_BYTES * 18); + res29 = fma52lo(res29, u10, m[19]); + res30 = fma52hi(res30, u10, m[19]); + + // Create u11 + fma52lo_mem(res11, res11, u11, m, SIMD_BYTES * 0); + fma52hi_mem(res12, res12, u11, m, SIMD_BYTES * 0); + res12 = fma52lo(res12, u11, m[1]); + res13 = fma52hi(res13, u11, m[1]); + res12 = add64(res12, srli64(res11, DIGIT_SIZE)); + U64 u12 = mul52lo(res12, k); + fma52lo_mem(res13, res13, u11, m, SIMD_BYTES * 2); + fma52hi_mem(res14, res14, u11, m, SIMD_BYTES * 2); + res14 = fma52lo(res14, u11, m[3]); + res15 = fma52hi(res15, u11, m[3]); + fma52lo_mem(res15, res15, u11, m, SIMD_BYTES * 4); + fma52hi_mem(res16, res16, u11, m, SIMD_BYTES * 4); + res16 = fma52lo(res16, u11, m[5]); + res17 = fma52hi(res17, u11, m[5]); + fma52lo_mem(res17, res17, u11, m, SIMD_BYTES * 6); + fma52hi_mem(res18, res18, u11, m, SIMD_BYTES * 6); + res18 = fma52lo(res18, u11, m[7]); + res19 = fma52hi(res19, u11, m[7]); + fma52lo_mem(res19, res19, u11, m, SIMD_BYTES * 8); + fma52hi_mem(res20, res20, u11, m, SIMD_BYTES * 8); + res20 = fma52lo(res20, u11, m[9]); + res21 = fma52hi(res21, u11, m[9]); + fma52lo_mem(res21, res21, u11, m, SIMD_BYTES * 10); + fma52hi_mem(res22, res22, u11, m, SIMD_BYTES * 10); + res22 = fma52lo(res22, u11, m[11]); + res23 = fma52hi(res23, u11, m[11]); + fma52lo_mem(res23, res23, u11, m, SIMD_BYTES * 12); + fma52hi_mem(res24, res24, u11, m, SIMD_BYTES * 12); + res24 = fma52lo(res24, u11, m[13]); + res25 = fma52hi(res25, u11, m[13]); + fma52lo_mem(res25, res25, u11, m, SIMD_BYTES * 14); + fma52hi_mem(res26, res26, u11, m, SIMD_BYTES * 14); + res26 = fma52lo(res26, u11, m[15]); + res27 = fma52hi(res27, u11, m[15]); + fma52lo_mem(res27, res27, u11, m, SIMD_BYTES * 16); + fma52hi_mem(res28, res28, u11, m, SIMD_BYTES * 16); + res28 = fma52lo(res28, u11, m[17]); + res29 = fma52hi(res29, u11, m[17]); + fma52lo_mem(res29, res29, u11, m, SIMD_BYTES * 18); + fma52hi_mem(res30, res30, u11, m, SIMD_BYTES * 18); + res30 = fma52lo(res30, u11, m[19]); + res31 = fma52hi(res31, u11, m[19]); + ASM("jmp l12\nl12:\n"); + + // Create u12 + fma52lo_mem(res12, res12, u12, m, SIMD_BYTES * 0); + fma52hi_mem(res13, res13, u12, m, SIMD_BYTES * 0); + res13 = fma52lo(res13, u12, m[1]); + res14 = fma52hi(res14, u12, m[1]); + res13 = add64(res13, srli64(res12, DIGIT_SIZE)); + U64 u13 = mul52lo(res13, k); + fma52lo_mem(res14, res14, u12, m, SIMD_BYTES * 2); + fma52hi_mem(res15, res15, u12, m, SIMD_BYTES * 2); + res15 = fma52lo(res15, u12, m[3]); + res16 = fma52hi(res16, u12, m[3]); + fma52lo_mem(res16, res16, u12, m, SIMD_BYTES * 4); + fma52hi_mem(res17, res17, u12, m, SIMD_BYTES * 4); + res17 = fma52lo(res17, u12, m[5]); + res18 = fma52hi(res18, u12, m[5]); + fma52lo_mem(res18, res18, u12, m, SIMD_BYTES * 6); + fma52hi_mem(res19, res19, u12, m, SIMD_BYTES * 6); + res19 = fma52lo(res19, u12, m[7]); + res20 = fma52hi(res20, u12, m[7]); + fma52lo_mem(res20, res20, u12, m, SIMD_BYTES * 8); + fma52hi_mem(res21, res21, u12, m, SIMD_BYTES * 8); + res21 = fma52lo(res21, u12, m[9]); + res22 = fma52hi(res22, u12, m[9]); + fma52lo_mem(res22, res22, u12, m, SIMD_BYTES * 10); + fma52hi_mem(res23, res23, u12, m, SIMD_BYTES * 10); + res23 = fma52lo(res23, u12, m[11]); + res24 = fma52hi(res24, u12, m[11]); + fma52lo_mem(res24, res24, u12, m, SIMD_BYTES * 12); + fma52hi_mem(res25, res25, u12, m, SIMD_BYTES * 12); + res25 = fma52lo(res25, u12, m[13]); + res26 = fma52hi(res26, u12, m[13]); + fma52lo_mem(res26, res26, u12, m, SIMD_BYTES * 14); + fma52hi_mem(res27, res27, u12, m, SIMD_BYTES * 14); + res27 = fma52lo(res27, u12, m[15]); + res28 = fma52hi(res28, u12, m[15]); + fma52lo_mem(res28, res28, u12, m, SIMD_BYTES * 16); + fma52hi_mem(res29, res29, u12, m, SIMD_BYTES * 16); + res29 = fma52lo(res29, u12, m[17]); + res30 = fma52hi(res30, u12, m[17]); + fma52lo_mem(res30, res30, u12, m, SIMD_BYTES * 18); + fma52hi_mem(res31, res31, u12, m, SIMD_BYTES * 18); + res31 = fma52lo(res31, u12, m[19]); + res32 = fma52hi(res32, u12, m[19]); + + // Create u13 + fma52lo_mem(res13, res13, u13, m, SIMD_BYTES * 0); + fma52hi_mem(res14, res14, u13, m, SIMD_BYTES * 0); + res14 = fma52lo(res14, u13, m[1]); + res15 = fma52hi(res15, u13, m[1]); + res14 = add64(res14, srli64(res13, DIGIT_SIZE)); + U64 u14 = mul52lo(res14, k); + fma52lo_mem(res15, res15, u13, m, SIMD_BYTES * 2); + fma52hi_mem(res16, res16, u13, m, SIMD_BYTES * 2); + res16 = fma52lo(res16, u13, m[3]); + res17 = fma52hi(res17, u13, m[3]); + fma52lo_mem(res17, res17, u13, m, SIMD_BYTES * 4); + fma52hi_mem(res18, res18, u13, m, SIMD_BYTES * 4); + res18 = fma52lo(res18, u13, m[5]); + res19 = fma52hi(res19, u13, m[5]); + fma52lo_mem(res19, res19, u13, m, SIMD_BYTES * 6); + fma52hi_mem(res20, res20, u13, m, SIMD_BYTES * 6); + res20 = fma52lo(res20, u13, m[7]); + res21 = fma52hi(res21, u13, m[7]); + fma52lo_mem(res21, res21, u13, m, SIMD_BYTES * 8); + fma52hi_mem(res22, res22, u13, m, SIMD_BYTES * 8); + res22 = fma52lo(res22, u13, m[9]); + res23 = fma52hi(res23, u13, m[9]); + fma52lo_mem(res23, res23, u13, m, SIMD_BYTES * 10); + fma52hi_mem(res24, res24, u13, m, SIMD_BYTES * 10); + res24 = fma52lo(res24, u13, m[11]); + res25 = fma52hi(res25, u13, m[11]); + fma52lo_mem(res25, res25, u13, m, SIMD_BYTES * 12); + fma52hi_mem(res26, res26, u13, m, SIMD_BYTES * 12); + res26 = fma52lo(res26, u13, m[13]); + res27 = fma52hi(res27, u13, m[13]); + fma52lo_mem(res27, res27, u13, m, SIMD_BYTES * 14); + fma52hi_mem(res28, res28, u13, m, SIMD_BYTES * 14); + res28 = fma52lo(res28, u13, m[15]); + res29 = fma52hi(res29, u13, m[15]); + fma52lo_mem(res29, res29, u13, m, SIMD_BYTES * 16); + fma52hi_mem(res30, res30, u13, m, SIMD_BYTES * 16); + res30 = fma52lo(res30, u13, m[17]); + res31 = fma52hi(res31, u13, m[17]); + fma52lo_mem(res31, res31, u13, m, SIMD_BYTES * 18); + fma52hi_mem(res32, res32, u13, m, SIMD_BYTES * 18); + res32 = fma52lo(res32, u13, m[19]); + res33 = fma52hi(res33, u13, m[19]); + ASM("jmp l14\nl14:\n"); + + // Create u14 + fma52lo_mem(res14, res14, u14, m, SIMD_BYTES * 0); + fma52hi_mem(res15, res15, u14, m, SIMD_BYTES * 0); + res15 = fma52lo(res15, u14, m[1]); + res16 = fma52hi(res16, u14, m[1]); + res15 = add64(res15, srli64(res14, DIGIT_SIZE)); + U64 u15 = mul52lo(res15, k); + fma52lo_mem(res16, res16, u14, m, SIMD_BYTES * 2); + fma52hi_mem(res17, res17, u14, m, SIMD_BYTES * 2); + res17 = fma52lo(res17, u14, m[3]); + res18 = fma52hi(res18, u14, m[3]); + fma52lo_mem(res18, res18, u14, m, SIMD_BYTES * 4); + fma52hi_mem(res19, res19, u14, m, SIMD_BYTES * 4); + res19 = fma52lo(res19, u14, m[5]); + res20 = fma52hi(res20, u14, m[5]); + fma52lo_mem(res20, res20, u14, m, SIMD_BYTES * 6); + fma52hi_mem(res21, res21, u14, m, SIMD_BYTES * 6); + res21 = fma52lo(res21, u14, m[7]); + res22 = fma52hi(res22, u14, m[7]); + fma52lo_mem(res22, res22, u14, m, SIMD_BYTES * 8); + fma52hi_mem(res23, res23, u14, m, SIMD_BYTES * 8); + res23 = fma52lo(res23, u14, m[9]); + res24 = fma52hi(res24, u14, m[9]); + fma52lo_mem(res24, res24, u14, m, SIMD_BYTES * 10); + fma52hi_mem(res25, res25, u14, m, SIMD_BYTES * 10); + res25 = fma52lo(res25, u14, m[11]); + res26 = fma52hi(res26, u14, m[11]); + fma52lo_mem(res26, res26, u14, m, SIMD_BYTES * 12); + fma52hi_mem(res27, res27, u14, m, SIMD_BYTES * 12); + res27 = fma52lo(res27, u14, m[13]); + res28 = fma52hi(res28, u14, m[13]); + fma52lo_mem(res28, res28, u14, m, SIMD_BYTES * 14); + fma52hi_mem(res29, res29, u14, m, SIMD_BYTES * 14); + res29 = fma52lo(res29, u14, m[15]); + res30 = fma52hi(res30, u14, m[15]); + fma52lo_mem(res30, res30, u14, m, SIMD_BYTES * 16); + fma52hi_mem(res31, res31, u14, m, SIMD_BYTES * 16); + res31 = fma52lo(res31, u14, m[17]); + res32 = fma52hi(res32, u14, m[17]); + fma52lo_mem(res32, res32, u14, m, SIMD_BYTES * 18); + fma52hi_mem(res33, res33, u14, m, SIMD_BYTES * 18); + res33 = fma52lo(res33, u14, m[19]); + res34 = fma52hi(res34, u14, m[19]); + + // Create u15 + fma52lo_mem(res15, res15, u15, m, SIMD_BYTES * 0); + fma52hi_mem(res16, res16, u15, m, SIMD_BYTES * 0); + res16 = fma52lo(res16, u15, m[1]); + res17 = fma52hi(res17, u15, m[1]); + res16 = add64(res16, srli64(res15, DIGIT_SIZE)); + U64 u16 = mul52lo(res16, k); + fma52lo_mem(res17, res17, u15, m, SIMD_BYTES * 2); + fma52hi_mem(res18, res18, u15, m, SIMD_BYTES * 2); + res18 = fma52lo(res18, u15, m[3]); + res19 = fma52hi(res19, u15, m[3]); + fma52lo_mem(res19, res19, u15, m, SIMD_BYTES * 4); + fma52hi_mem(res20, res20, u15, m, SIMD_BYTES * 4); + res20 = fma52lo(res20, u15, m[5]); + res21 = fma52hi(res21, u15, m[5]); + fma52lo_mem(res21, res21, u15, m, SIMD_BYTES * 6); + fma52hi_mem(res22, res22, u15, m, SIMD_BYTES * 6); + res22 = fma52lo(res22, u15, m[7]); + res23 = fma52hi(res23, u15, m[7]); + fma52lo_mem(res23, res23, u15, m, SIMD_BYTES * 8); + fma52hi_mem(res24, res24, u15, m, SIMD_BYTES * 8); + res24 = fma52lo(res24, u15, m[9]); + res25 = fma52hi(res25, u15, m[9]); + fma52lo_mem(res25, res25, u15, m, SIMD_BYTES * 10); + fma52hi_mem(res26, res26, u15, m, SIMD_BYTES * 10); + res26 = fma52lo(res26, u15, m[11]); + res27 = fma52hi(res27, u15, m[11]); + fma52lo_mem(res27, res27, u15, m, SIMD_BYTES * 12); + fma52hi_mem(res28, res28, u15, m, SIMD_BYTES * 12); + res28 = fma52lo(res28, u15, m[13]); + res29 = fma52hi(res29, u15, m[13]); + fma52lo_mem(res29, res29, u15, m, SIMD_BYTES * 14); + fma52hi_mem(res30, res30, u15, m, SIMD_BYTES * 14); + res30 = fma52lo(res30, u15, m[15]); + res31 = fma52hi(res31, u15, m[15]); + fma52lo_mem(res31, res31, u15, m, SIMD_BYTES * 16); + fma52hi_mem(res32, res32, u15, m, SIMD_BYTES * 16); + res32 = fma52lo(res32, u15, m[17]); + res33 = fma52hi(res33, u15, m[17]); + fma52lo_mem(res33, res33, u15, m, SIMD_BYTES * 18); + fma52hi_mem(res34, res34, u15, m, SIMD_BYTES * 18); + res34 = fma52lo(res34, u15, m[19]); + res35 = fma52hi(res35, u15, m[19]); + ASM("jmp l16\nl16:\n"); + + // Create u16 + fma52lo_mem(res16, res16, u16, m, SIMD_BYTES * 0); + fma52hi_mem(res17, res17, u16, m, SIMD_BYTES * 0); + res17 = fma52lo(res17, u16, m[1]); + res18 = fma52hi(res18, u16, m[1]); + res17 = add64(res17, srli64(res16, DIGIT_SIZE)); + U64 u17 = mul52lo(res17, k); + fma52lo_mem(res18, res18, u16, m, SIMD_BYTES * 2); + fma52hi_mem(res19, res19, u16, m, SIMD_BYTES * 2); + res19 = fma52lo(res19, u16, m[3]); + res20 = fma52hi(res20, u16, m[3]); + fma52lo_mem(res20, res20, u16, m, SIMD_BYTES * 4); + fma52hi_mem(res21, res21, u16, m, SIMD_BYTES * 4); + res21 = fma52lo(res21, u16, m[5]); + res22 = fma52hi(res22, u16, m[5]); + fma52lo_mem(res22, res22, u16, m, SIMD_BYTES * 6); + fma52hi_mem(res23, res23, u16, m, SIMD_BYTES * 6); + res23 = fma52lo(res23, u16, m[7]); + res24 = fma52hi(res24, u16, m[7]); + fma52lo_mem(res24, res24, u16, m, SIMD_BYTES * 8); + fma52hi_mem(res25, res25, u16, m, SIMD_BYTES * 8); + res25 = fma52lo(res25, u16, m[9]); + res26 = fma52hi(res26, u16, m[9]); + fma52lo_mem(res26, res26, u16, m, SIMD_BYTES * 10); + fma52hi_mem(res27, res27, u16, m, SIMD_BYTES * 10); + res27 = fma52lo(res27, u16, m[11]); + res28 = fma52hi(res28, u16, m[11]); + fma52lo_mem(res28, res28, u16, m, SIMD_BYTES * 12); + fma52hi_mem(res29, res29, u16, m, SIMD_BYTES * 12); + res29 = fma52lo(res29, u16, m[13]); + res30 = fma52hi(res30, u16, m[13]); + fma52lo_mem(res30, res30, u16, m, SIMD_BYTES * 14); + fma52hi_mem(res31, res31, u16, m, SIMD_BYTES * 14); + res31 = fma52lo(res31, u16, m[15]); + res32 = fma52hi(res32, u16, m[15]); + fma52lo_mem(res32, res32, u16, m, SIMD_BYTES * 16); + fma52hi_mem(res33, res33, u16, m, SIMD_BYTES * 16); + res33 = fma52lo(res33, u16, m[17]); + res34 = fma52hi(res34, u16, m[17]); + fma52lo_mem(res34, res34, u16, m, SIMD_BYTES * 18); + fma52hi_mem(res35, res35, u16, m, SIMD_BYTES * 18); + res35 = fma52lo(res35, u16, m[19]); + res36 = fma52hi(res36, u16, m[19]); + + // Create u17 + fma52lo_mem(res17, res17, u17, m, SIMD_BYTES * 0); + fma52hi_mem(res18, res18, u17, m, SIMD_BYTES * 0); + res18 = fma52lo(res18, u17, m[1]); + res19 = fma52hi(res19, u17, m[1]); + res18 = add64(res18, srli64(res17, DIGIT_SIZE)); + U64 u18 = mul52lo(res18, k); + fma52lo_mem(res19, res19, u17, m, SIMD_BYTES * 2); + fma52hi_mem(res20, res20, u17, m, SIMD_BYTES * 2); + res20 = fma52lo(res20, u17, m[3]); + res21 = fma52hi(res21, u17, m[3]); + fma52lo_mem(res21, res21, u17, m, SIMD_BYTES * 4); + fma52hi_mem(res22, res22, u17, m, SIMD_BYTES * 4); + res22 = fma52lo(res22, u17, m[5]); + res23 = fma52hi(res23, u17, m[5]); + fma52lo_mem(res23, res23, u17, m, SIMD_BYTES * 6); + fma52hi_mem(res24, res24, u17, m, SIMD_BYTES * 6); + res24 = fma52lo(res24, u17, m[7]); + res25 = fma52hi(res25, u17, m[7]); + fma52lo_mem(res25, res25, u17, m, SIMD_BYTES * 8); + fma52hi_mem(res26, res26, u17, m, SIMD_BYTES * 8); + res26 = fma52lo(res26, u17, m[9]); + res27 = fma52hi(res27, u17, m[9]); + fma52lo_mem(res27, res27, u17, m, SIMD_BYTES * 10); + fma52hi_mem(res28, res28, u17, m, SIMD_BYTES * 10); + res28 = fma52lo(res28, u17, m[11]); + res29 = fma52hi(res29, u17, m[11]); + fma52lo_mem(res29, res29, u17, m, SIMD_BYTES * 12); + fma52hi_mem(res30, res30, u17, m, SIMD_BYTES * 12); + res30 = fma52lo(res30, u17, m[13]); + res31 = fma52hi(res31, u17, m[13]); + fma52lo_mem(res31, res31, u17, m, SIMD_BYTES * 14); + fma52hi_mem(res32, res32, u17, m, SIMD_BYTES * 14); + res32 = fma52lo(res32, u17, m[15]); + res33 = fma52hi(res33, u17, m[15]); + fma52lo_mem(res33, res33, u17, m, SIMD_BYTES * 16); + fma52hi_mem(res34, res34, u17, m, SIMD_BYTES * 16); + res34 = fma52lo(res34, u17, m[17]); + res35 = fma52hi(res35, u17, m[17]); + fma52lo_mem(res35, res35, u17, m, SIMD_BYTES * 18); + fma52hi_mem(res36, res36, u17, m, SIMD_BYTES * 18); + res36 = fma52lo(res36, u17, m[19]); + res37 = fma52hi(res37, u17, m[19]); + ASM("jmp l18\nl18:\n"); + + // Create u18 + fma52lo_mem(res18, res18, u18, m, SIMD_BYTES * 0); + fma52hi_mem(res19, res19, u18, m, SIMD_BYTES * 0); + res19 = fma52lo(res19, u18, m[1]); + res20 = fma52hi(res20, u18, m[1]); + res19 = add64(res19, srli64(res18, DIGIT_SIZE)); + U64 u19 = mul52lo(res19, k); + fma52lo_mem(res20, res20, u18, m, SIMD_BYTES * 2); + fma52hi_mem(res21, res21, u18, m, SIMD_BYTES * 2); + res21 = fma52lo(res21, u18, m[3]); + res22 = fma52hi(res22, u18, m[3]); + fma52lo_mem(res22, res22, u18, m, SIMD_BYTES * 4); + fma52hi_mem(res23, res23, u18, m, SIMD_BYTES * 4); + res23 = fma52lo(res23, u18, m[5]); + res24 = fma52hi(res24, u18, m[5]); + fma52lo_mem(res24, res24, u18, m, SIMD_BYTES * 6); + fma52hi_mem(res25, res25, u18, m, SIMD_BYTES * 6); + res25 = fma52lo(res25, u18, m[7]); + res26 = fma52hi(res26, u18, m[7]); + fma52lo_mem(res26, res26, u18, m, SIMD_BYTES * 8); + fma52hi_mem(res27, res27, u18, m, SIMD_BYTES * 8); + res27 = fma52lo(res27, u18, m[9]); + res28 = fma52hi(res28, u18, m[9]); + fma52lo_mem(res28, res28, u18, m, SIMD_BYTES * 10); + fma52hi_mem(res29, res29, u18, m, SIMD_BYTES * 10); + res29 = fma52lo(res29, u18, m[11]); + res30 = fma52hi(res30, u18, m[11]); + fma52lo_mem(res30, res30, u18, m, SIMD_BYTES * 12); + fma52hi_mem(res31, res31, u18, m, SIMD_BYTES * 12); + res31 = fma52lo(res31, u18, m[13]); + res32 = fma52hi(res32, u18, m[13]); + fma52lo_mem(res32, res32, u18, m, SIMD_BYTES * 14); + fma52hi_mem(res33, res33, u18, m, SIMD_BYTES * 14); + res33 = fma52lo(res33, u18, m[15]); + res34 = fma52hi(res34, u18, m[15]); + fma52lo_mem(res34, res34, u18, m, SIMD_BYTES * 16); + fma52hi_mem(res35, res35, u18, m, SIMD_BYTES * 16); + res35 = fma52lo(res35, u18, m[17]); + res36 = fma52hi(res36, u18, m[17]); + fma52lo_mem(res36, res36, u18, m, SIMD_BYTES * 18); + fma52hi_mem(res37, res37, u18, m, SIMD_BYTES * 18); + res37 = fma52lo(res37, u18, m[19]); + res38 = fma52hi(res38, u18, m[19]); + + // Create u19 + fma52lo_mem(res19, res19, u19, m, SIMD_BYTES * 0); + fma52hi_mem(res20, res20, u19, m, SIMD_BYTES * 0); + res20 = fma52lo(res20, u19, m[1]); + res21 = fma52hi(res21, u19, m[1]); + res20 = add64(res20, srli64(res19, DIGIT_SIZE)); + fma52lo_mem(res21, res21, u19, m, SIMD_BYTES * 2); + fma52hi_mem(res22, res22, u19, m, SIMD_BYTES * 2); + res22 = fma52lo(res22, u19, m[3]); + res23 = fma52hi(res23, u19, m[3]); + fma52lo_mem(res23, res23, u19, m, SIMD_BYTES * 4); + fma52hi_mem(res24, res24, u19, m, SIMD_BYTES * 4); + res24 = fma52lo(res24, u19, m[5]); + res25 = fma52hi(res25, u19, m[5]); + fma52lo_mem(res25, res25, u19, m, SIMD_BYTES * 6); + fma52hi_mem(res26, res26, u19, m, SIMD_BYTES * 6); + res26 = fma52lo(res26, u19, m[7]); + res27 = fma52hi(res27, u19, m[7]); + fma52lo_mem(res27, res27, u19, m, SIMD_BYTES * 8); + fma52hi_mem(res28, res28, u19, m, SIMD_BYTES * 8); + res28 = fma52lo(res28, u19, m[9]); + res29 = fma52hi(res29, u19, m[9]); + fma52lo_mem(res29, res29, u19, m, SIMD_BYTES * 10); + fma52hi_mem(res30, res30, u19, m, SIMD_BYTES * 10); + res30 = fma52lo(res30, u19, m[11]); + res31 = fma52hi(res31, u19, m[11]); + fma52lo_mem(res31, res31, u19, m, SIMD_BYTES * 12); + fma52hi_mem(res32, res32, u19, m, SIMD_BYTES * 12); + res32 = fma52lo(res32, u19, m[13]); + res33 = fma52hi(res33, u19, m[13]); + fma52lo_mem(res33, res33, u19, m, SIMD_BYTES * 14); + fma52hi_mem(res34, res34, u19, m, SIMD_BYTES * 14); + res34 = fma52lo(res34, u19, m[15]); + res35 = fma52hi(res35, u19, m[15]); + fma52lo_mem(res35, res35, u19, m, SIMD_BYTES * 16); + fma52hi_mem(res36, res36, u19, m, SIMD_BYTES * 16); + res36 = fma52lo(res36, u19, m[17]); + res37 = fma52hi(res37, u19, m[17]); + fma52lo_mem(res37, res37, u19, m, SIMD_BYTES * 18); + fma52hi_mem(res38, res38, u19, m, SIMD_BYTES * 18); + res38 = fma52lo(res38, u19, m[19]); + res39 = fma52hi(res39, u19, m[19]); + + // Normalization + r[0] = and64_const(res20, DIGIT_MASK); + res21 = add64(res21, srli64(res20, DIGIT_SIZE)); + r[1] = and64_const(res21, DIGIT_MASK); + res22 = add64(res22, srli64(res21, DIGIT_SIZE)); + r[2] = and64_const(res22, DIGIT_MASK); + res23 = add64(res23, srli64(res22, DIGIT_SIZE)); + r[3] = and64_const(res23, DIGIT_MASK); + res24 = add64(res24, srli64(res23, DIGIT_SIZE)); + r[4] = and64_const(res24, DIGIT_MASK); + res25 = add64(res25, srli64(res24, DIGIT_SIZE)); + r[5] = and64_const(res25, DIGIT_MASK); + res26 = add64(res26, srli64(res25, DIGIT_SIZE)); + r[6] = and64_const(res26, DIGIT_MASK); + res27 = add64(res27, srli64(res26, DIGIT_SIZE)); + r[7] = and64_const(res27, DIGIT_MASK); + res28 = add64(res28, srli64(res27, DIGIT_SIZE)); + r[8] = and64_const(res28, DIGIT_MASK); + res29 = add64(res29, srli64(res28, DIGIT_SIZE)); + r[9] = and64_const(res29, DIGIT_MASK); + res30 = add64(res30, srli64(res29, DIGIT_SIZE)); + r[10] = and64_const(res30, DIGIT_MASK); + res31 = add64(res31, srli64(res30, DIGIT_SIZE)); + r[11] = and64_const(res31, DIGIT_MASK); + res32 = add64(res32, srli64(res31, DIGIT_SIZE)); + r[12] = and64_const(res32, DIGIT_MASK); + res33 = add64(res33, srli64(res32, DIGIT_SIZE)); + r[13] = and64_const(res33, DIGIT_MASK); + res34 = add64(res34, srli64(res33, DIGIT_SIZE)); + r[14] = and64_const(res34, DIGIT_MASK); + res35 = add64(res35, srli64(res34, DIGIT_SIZE)); + r[15] = and64_const(res35, DIGIT_MASK); + res36 = add64(res36, srli64(res35, DIGIT_SIZE)); + r[16] = and64_const(res36, DIGIT_MASK); + res37 = add64(res37, srli64(res36, DIGIT_SIZE)); + r[17] = and64_const(res37, DIGIT_MASK); + res38 = add64(res38, srli64(res37, DIGIT_SIZE)); + r[18] = and64_const(res38, DIGIT_MASK); + res39 = add64(res39, srli64(res38, DIGIT_SIZE)); + r[19] = and64_const(res39, DIGIT_MASK); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x30_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x30_diagonal_mb8.c new file mode 100644 index 000000000..9a51a8279 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x30_diagonal_mb8.c @@ -0,0 +1,1522 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS52x30_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + + __ALIGN64 U64 res[60]; + __ALIGN64 U64 u[30]; + U64 k; + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + + k = loadu64((U64 *)k0_mb); + int i; + for (i = 0; i < 60; ++i) + res[i] = get_zero64(); + + res[1] = fma52lo(res[1], a[0], a[1]); // Sum(1) + res[2] = fma52hi(res[2], a[0], a[1]); // Sum(1) + res[2] = fma52lo(res[2], a[0], a[2]); // Sum(2) + res[3] = fma52hi(res[3], a[0], a[2]); // Sum(2) + res[3] = fma52lo(res[3], a[1], a[2]); // Sum(3) + res[4] = fma52hi(res[4], a[1], a[2]); // Sum(3) + res[3] = fma52lo(res[3], a[0], a[3]); // Sum(3) + res[4] = fma52hi(res[4], a[0], a[3]); // Sum(3) + res[4] = fma52lo(res[4], a[1], a[3]); // Sum(4) + res[5] = fma52hi(res[5], a[1], a[3]); // Sum(4) + res[5] = fma52lo(res[5], a[2], a[3]); // Sum(5) + res[6] = fma52hi(res[6], a[2], a[3]); // Sum(5) + res[4] = fma52lo(res[4], a[0], a[4]); // Sum(4) + res[5] = fma52hi(res[5], a[0], a[4]); // Sum(4) + res[5] = fma52lo(res[5], a[1], a[4]); // Sum(5) + res[6] = fma52hi(res[6], a[1], a[4]); // Sum(5) + res[6] = fma52lo(res[6], a[2], a[4]); // Sum(6) + res[7] = fma52hi(res[7], a[2], a[4]); // Sum(6) + res[7] = fma52lo(res[7], a[3], a[4]); // Sum(7) + res[8] = fma52hi(res[8], a[3], a[4]); // Sum(7) + res[5] = fma52lo(res[5], a[0], a[5]); // Sum(5) + res[6] = fma52hi(res[6], a[0], a[5]); // Sum(5) + res[6] = fma52lo(res[6], a[1], a[5]); // Sum(6) + res[7] = fma52hi(res[7], a[1], a[5]); // Sum(6) + res[7] = fma52lo(res[7], a[2], a[5]); // Sum(7) + res[8] = fma52hi(res[8], a[2], a[5]); // Sum(7) + res[8] = fma52lo(res[8], a[3], a[5]); // Sum(8) + res[9] = fma52hi(res[9], a[3], a[5]); // Sum(8) + res[9] = fma52lo(res[9], a[4], a[5]); // Sum(9) + res[10] = fma52hi(res[10], a[4], a[5]); // Sum(9) + res[6] = fma52lo(res[6], a[0], a[6]); // Sum(6) + res[7] = fma52hi(res[7], a[0], a[6]); // Sum(6) + res[7] = fma52lo(res[7], a[1], a[6]); // Sum(7) + res[8] = fma52hi(res[8], a[1], a[6]); // Sum(7) + res[8] = fma52lo(res[8], a[2], a[6]); // Sum(8) + res[9] = fma52hi(res[9], a[2], a[6]); // Sum(8) + res[9] = fma52lo(res[9], a[3], a[6]); // Sum(9) + res[10] = fma52hi(res[10], a[3], a[6]); // Sum(9) + res[10] = fma52lo(res[10], a[4], a[6]); // Sum(10) + res[11] = fma52hi(res[11], a[4], a[6]); // Sum(10) + res[11] = fma52lo(res[11], a[5], a[6]); // Sum(11) + res[12] = fma52hi(res[12], a[5], a[6]); // Sum(11) + res[7] = fma52lo(res[7], a[0], a[7]); // Sum(7) + res[8] = fma52hi(res[8], a[0], a[7]); // Sum(7) + res[8] = fma52lo(res[8], a[1], a[7]); // Sum(8) + res[9] = fma52hi(res[9], a[1], a[7]); // Sum(8) + res[9] = fma52lo(res[9], a[2], a[7]); // Sum(9) + res[10] = fma52hi(res[10], a[2], a[7]); // Sum(9) + res[10] = fma52lo(res[10], a[3], a[7]); // Sum(10) + res[11] = fma52hi(res[11], a[3], a[7]); // Sum(10) + res[11] = fma52lo(res[11], a[4], a[7]); // Sum(11) + res[12] = fma52hi(res[12], a[4], a[7]); // Sum(11) + res[8] = fma52lo(res[8], a[0], a[8]); // Sum(8) + res[9] = fma52hi(res[9], a[0], a[8]); // Sum(8) + res[9] = fma52lo(res[9], a[1], a[8]); // Sum(9) + res[10] = fma52hi(res[10], a[1], a[8]); // Sum(9) + res[10] = fma52lo(res[10], a[2], a[8]); // Sum(10) + res[11] = fma52hi(res[11], a[2], a[8]); // Sum(10) + res[11] = fma52lo(res[11], a[3], a[8]); // Sum(11) + res[12] = fma52hi(res[12], a[3], a[8]); // Sum(11) + res[9] = fma52lo(res[9], a[0], a[9]); // Sum(9) + res[10] = fma52hi(res[10], a[0], a[9]); // Sum(9) + res[10] = fma52lo(res[10], a[1], a[9]); // Sum(10) + res[11] = fma52hi(res[11], a[1], a[9]); // Sum(10) + res[11] = fma52lo(res[11], a[2], a[9]); // Sum(11) + res[12] = fma52hi(res[12], a[2], a[9]); // Sum(11) + res[10] = fma52lo(res[10], a[0], a[10]); // Sum(10) + res[11] = fma52hi(res[11], a[0], a[10]); // Sum(10) + res[11] = fma52lo(res[11], a[1], a[10]); // Sum(11) + res[12] = fma52hi(res[12], a[1], a[10]); // Sum(11) + res[11] = fma52lo(res[11], a[0], a[11]); // Sum(11) + res[12] = fma52hi(res[12], a[0], a[11]); // Sum(11) + res[0] = add64(res[0], res[0]); // Double(0) + res[1] = add64(res[1], res[1]); // Double(1) + res[2] = add64(res[2], res[2]); // Double(2) + res[3] = add64(res[3], res[3]); // Double(3) + res[4] = add64(res[4], res[4]); // Double(4) + res[5] = add64(res[5], res[5]); // Double(5) + res[6] = add64(res[6], res[6]); // Double(6) + res[7] = add64(res[7], res[7]); // Double(7) + res[8] = add64(res[8], res[8]); // Double(8) + res[9] = add64(res[9], res[9]); // Double(9) + res[10] = add64(res[10], res[10]); // Double(10) + res[11] = add64(res[11], res[11]); // Double(11) + res[0] = fma52lo(res[0], a[0], a[0]); // Add sqr(0) + res[1] = fma52hi(res[1], a[0], a[0]); // Add sqr(0) + res[2] = fma52lo(res[2], a[1], a[1]); // Add sqr(2) + res[3] = fma52hi(res[3], a[1], a[1]); // Add sqr(2) + res[4] = fma52lo(res[4], a[2], a[2]); // Add sqr(4) + res[5] = fma52hi(res[5], a[2], a[2]); // Add sqr(4) + res[6] = fma52lo(res[6], a[3], a[3]); // Add sqr(6) + res[7] = fma52hi(res[7], a[3], a[3]); // Add sqr(6) + res[8] = fma52lo(res[8], a[4], a[4]); // Add sqr(8) + res[9] = fma52hi(res[9], a[4], a[4]); // Add sqr(8) + res[10] = fma52lo(res[10], a[5], a[5]); // Add sqr(10) + res[11] = fma52hi(res[11], a[5], a[5]); // Add sqr(10) + res[12] = fma52lo(res[12], a[5], a[7]); // Sum(12) + res[13] = fma52hi(res[13], a[5], a[7]); // Sum(12) + res[13] = fma52lo(res[13], a[6], a[7]); // Sum(13) + res[14] = fma52hi(res[14], a[6], a[7]); // Sum(13) + res[12] = fma52lo(res[12], a[4], a[8]); // Sum(12) + res[13] = fma52hi(res[13], a[4], a[8]); // Sum(12) + res[13] = fma52lo(res[13], a[5], a[8]); // Sum(13) + res[14] = fma52hi(res[14], a[5], a[8]); // Sum(13) + res[14] = fma52lo(res[14], a[6], a[8]); // Sum(14) + res[15] = fma52hi(res[15], a[6], a[8]); // Sum(14) + res[15] = fma52lo(res[15], a[7], a[8]); // Sum(15) + res[16] = fma52hi(res[16], a[7], a[8]); // Sum(15) + res[12] = fma52lo(res[12], a[3], a[9]); // Sum(12) + res[13] = fma52hi(res[13], a[3], a[9]); // Sum(12) + res[13] = fma52lo(res[13], a[4], a[9]); // Sum(13) + res[14] = fma52hi(res[14], a[4], a[9]); // Sum(13) + res[14] = fma52lo(res[14], a[5], a[9]); // Sum(14) + res[15] = fma52hi(res[15], a[5], a[9]); // Sum(14) + res[15] = fma52lo(res[15], a[6], a[9]); // Sum(15) + res[16] = fma52hi(res[16], a[6], a[9]); // Sum(15) + res[16] = fma52lo(res[16], a[7], a[9]); // Sum(16) + res[17] = fma52hi(res[17], a[7], a[9]); // Sum(16) + res[17] = fma52lo(res[17], a[8], a[9]); // Sum(17) + res[18] = fma52hi(res[18], a[8], a[9]); // Sum(17) + res[12] = fma52lo(res[12], a[2], a[10]); // Sum(12) + res[13] = fma52hi(res[13], a[2], a[10]); // Sum(12) + res[13] = fma52lo(res[13], a[3], a[10]); // Sum(13) + res[14] = fma52hi(res[14], a[3], a[10]); // Sum(13) + res[14] = fma52lo(res[14], a[4], a[10]); // Sum(14) + res[15] = fma52hi(res[15], a[4], a[10]); // Sum(14) + res[15] = fma52lo(res[15], a[5], a[10]); // Sum(15) + res[16] = fma52hi(res[16], a[5], a[10]); // Sum(15) + res[16] = fma52lo(res[16], a[6], a[10]); // Sum(16) + res[17] = fma52hi(res[17], a[6], a[10]); // Sum(16) + res[17] = fma52lo(res[17], a[7], a[10]); // Sum(17) + res[18] = fma52hi(res[18], a[7], a[10]); // Sum(17) + res[18] = fma52lo(res[18], a[8], a[10]); // Sum(18) + res[19] = fma52hi(res[19], a[8], a[10]); // Sum(18) + res[19] = fma52lo(res[19], a[9], a[10]); // Sum(19) + res[20] = fma52hi(res[20], a[9], a[10]); // Sum(19) + res[12] = fma52lo(res[12], a[1], a[11]); // Sum(12) + res[13] = fma52hi(res[13], a[1], a[11]); // Sum(12) + res[13] = fma52lo(res[13], a[2], a[11]); // Sum(13) + res[14] = fma52hi(res[14], a[2], a[11]); // Sum(13) + res[14] = fma52lo(res[14], a[3], a[11]); // Sum(14) + res[15] = fma52hi(res[15], a[3], a[11]); // Sum(14) + res[15] = fma52lo(res[15], a[4], a[11]); // Sum(15) + res[16] = fma52hi(res[16], a[4], a[11]); // Sum(15) + res[16] = fma52lo(res[16], a[5], a[11]); // Sum(16) + res[17] = fma52hi(res[17], a[5], a[11]); // Sum(16) + res[17] = fma52lo(res[17], a[6], a[11]); // Sum(17) + res[18] = fma52hi(res[18], a[6], a[11]); // Sum(17) + res[18] = fma52lo(res[18], a[7], a[11]); // Sum(18) + res[19] = fma52hi(res[19], a[7], a[11]); // Sum(18) + res[19] = fma52lo(res[19], a[8], a[11]); // Sum(19) + res[20] = fma52hi(res[20], a[8], a[11]); // Sum(19) + res[20] = fma52lo(res[20], a[9], a[11]); // Sum(20) + res[21] = fma52hi(res[21], a[9], a[11]); // Sum(20) + res[21] = fma52lo(res[21], a[10], a[11]); // Sum(21) + res[22] = fma52hi(res[22], a[10], a[11]); // Sum(21) + res[12] = fma52lo(res[12], a[0], a[12]); // Sum(12) + res[13] = fma52hi(res[13], a[0], a[12]); // Sum(12) + res[13] = fma52lo(res[13], a[1], a[12]); // Sum(13) + res[14] = fma52hi(res[14], a[1], a[12]); // Sum(13) + res[14] = fma52lo(res[14], a[2], a[12]); // Sum(14) + res[15] = fma52hi(res[15], a[2], a[12]); // Sum(14) + res[15] = fma52lo(res[15], a[3], a[12]); // Sum(15) + res[16] = fma52hi(res[16], a[3], a[12]); // Sum(15) + res[16] = fma52lo(res[16], a[4], a[12]); // Sum(16) + res[17] = fma52hi(res[17], a[4], a[12]); // Sum(16) + res[17] = fma52lo(res[17], a[5], a[12]); // Sum(17) + res[18] = fma52hi(res[18], a[5], a[12]); // Sum(17) + res[18] = fma52lo(res[18], a[6], a[12]); // Sum(18) + res[19] = fma52hi(res[19], a[6], a[12]); // Sum(18) + res[19] = fma52lo(res[19], a[7], a[12]); // Sum(19) + res[20] = fma52hi(res[20], a[7], a[12]); // Sum(19) + res[20] = fma52lo(res[20], a[8], a[12]); // Sum(20) + res[21] = fma52hi(res[21], a[8], a[12]); // Sum(20) + res[21] = fma52lo(res[21], a[9], a[12]); // Sum(21) + res[22] = fma52hi(res[22], a[9], a[12]); // Sum(21) + res[22] = fma52lo(res[22], a[10], a[12]); // Sum(22) + res[23] = fma52hi(res[23], a[10], a[12]); // Sum(22) + res[23] = fma52lo(res[23], a[11], a[12]); // Sum(23) + res[24] = fma52hi(res[24], a[11], a[12]); // Sum(23) + res[13] = fma52lo(res[13], a[0], a[13]); // Sum(13) + res[14] = fma52hi(res[14], a[0], a[13]); // Sum(13) + res[14] = fma52lo(res[14], a[1], a[13]); // Sum(14) + res[15] = fma52hi(res[15], a[1], a[13]); // Sum(14) + res[15] = fma52lo(res[15], a[2], a[13]); // Sum(15) + res[16] = fma52hi(res[16], a[2], a[13]); // Sum(15) + res[16] = fma52lo(res[16], a[3], a[13]); // Sum(16) + res[17] = fma52hi(res[17], a[3], a[13]); // Sum(16) + res[17] = fma52lo(res[17], a[4], a[13]); // Sum(17) + res[18] = fma52hi(res[18], a[4], a[13]); // Sum(17) + res[18] = fma52lo(res[18], a[5], a[13]); // Sum(18) + res[19] = fma52hi(res[19], a[5], a[13]); // Sum(18) + res[19] = fma52lo(res[19], a[6], a[13]); // Sum(19) + res[20] = fma52hi(res[20], a[6], a[13]); // Sum(19) + res[20] = fma52lo(res[20], a[7], a[13]); // Sum(20) + res[21] = fma52hi(res[21], a[7], a[13]); // Sum(20) + res[21] = fma52lo(res[21], a[8], a[13]); // Sum(21) + res[22] = fma52hi(res[22], a[8], a[13]); // Sum(21) + res[22] = fma52lo(res[22], a[9], a[13]); // Sum(22) + res[23] = fma52hi(res[23], a[9], a[13]); // Sum(22) + res[23] = fma52lo(res[23], a[10], a[13]); // Sum(23) + res[24] = fma52hi(res[24], a[10], a[13]); // Sum(23) + res[14] = fma52lo(res[14], a[0], a[14]); // Sum(14) + res[15] = fma52hi(res[15], a[0], a[14]); // Sum(14) + res[15] = fma52lo(res[15], a[1], a[14]); // Sum(15) + res[16] = fma52hi(res[16], a[1], a[14]); // Sum(15) + res[16] = fma52lo(res[16], a[2], a[14]); // Sum(16) + res[17] = fma52hi(res[17], a[2], a[14]); // Sum(16) + res[17] = fma52lo(res[17], a[3], a[14]); // Sum(17) + res[18] = fma52hi(res[18], a[3], a[14]); // Sum(17) + res[18] = fma52lo(res[18], a[4], a[14]); // Sum(18) + res[19] = fma52hi(res[19], a[4], a[14]); // Sum(18) + res[19] = fma52lo(res[19], a[5], a[14]); // Sum(19) + res[20] = fma52hi(res[20], a[5], a[14]); // Sum(19) + res[20] = fma52lo(res[20], a[6], a[14]); // Sum(20) + res[21] = fma52hi(res[21], a[6], a[14]); // Sum(20) + res[21] = fma52lo(res[21], a[7], a[14]); // Sum(21) + res[22] = fma52hi(res[22], a[7], a[14]); // Sum(21) + res[22] = fma52lo(res[22], a[8], a[14]); // Sum(22) + res[23] = fma52hi(res[23], a[8], a[14]); // Sum(22) + res[23] = fma52lo(res[23], a[9], a[14]); // Sum(23) + res[24] = fma52hi(res[24], a[9], a[14]); // Sum(23) + res[15] = fma52lo(res[15], a[0], a[15]); // Sum(15) + res[16] = fma52hi(res[16], a[0], a[15]); // Sum(15) + res[16] = fma52lo(res[16], a[1], a[15]); // Sum(16) + res[17] = fma52hi(res[17], a[1], a[15]); // Sum(16) + res[17] = fma52lo(res[17], a[2], a[15]); // Sum(17) + res[18] = fma52hi(res[18], a[2], a[15]); // Sum(17) + res[18] = fma52lo(res[18], a[3], a[15]); // Sum(18) + res[19] = fma52hi(res[19], a[3], a[15]); // Sum(18) + res[19] = fma52lo(res[19], a[4], a[15]); // Sum(19) + res[20] = fma52hi(res[20], a[4], a[15]); // Sum(19) + res[20] = fma52lo(res[20], a[5], a[15]); // Sum(20) + res[21] = fma52hi(res[21], a[5], a[15]); // Sum(20) + res[21] = fma52lo(res[21], a[6], a[15]); // Sum(21) + res[22] = fma52hi(res[22], a[6], a[15]); // Sum(21) + res[22] = fma52lo(res[22], a[7], a[15]); // Sum(22) + res[23] = fma52hi(res[23], a[7], a[15]); // Sum(22) + res[23] = fma52lo(res[23], a[8], a[15]); // Sum(23) + res[24] = fma52hi(res[24], a[8], a[15]); // Sum(23) + res[16] = fma52lo(res[16], a[0], a[16]); // Sum(16) + res[17] = fma52hi(res[17], a[0], a[16]); // Sum(16) + res[17] = fma52lo(res[17], a[1], a[16]); // Sum(17) + res[18] = fma52hi(res[18], a[1], a[16]); // Sum(17) + res[18] = fma52lo(res[18], a[2], a[16]); // Sum(18) + res[19] = fma52hi(res[19], a[2], a[16]); // Sum(18) + res[19] = fma52lo(res[19], a[3], a[16]); // Sum(19) + res[20] = fma52hi(res[20], a[3], a[16]); // Sum(19) + res[20] = fma52lo(res[20], a[4], a[16]); // Sum(20) + res[21] = fma52hi(res[21], a[4], a[16]); // Sum(20) + res[21] = fma52lo(res[21], a[5], a[16]); // Sum(21) + res[22] = fma52hi(res[22], a[5], a[16]); // Sum(21) + res[22] = fma52lo(res[22], a[6], a[16]); // Sum(22) + res[23] = fma52hi(res[23], a[6], a[16]); // Sum(22) + res[23] = fma52lo(res[23], a[7], a[16]); // Sum(23) + res[24] = fma52hi(res[24], a[7], a[16]); // Sum(23) + res[17] = fma52lo(res[17], a[0], a[17]); // Sum(17) + res[18] = fma52hi(res[18], a[0], a[17]); // Sum(17) + res[18] = fma52lo(res[18], a[1], a[17]); // Sum(18) + res[19] = fma52hi(res[19], a[1], a[17]); // Sum(18) + res[19] = fma52lo(res[19], a[2], a[17]); // Sum(19) + res[20] = fma52hi(res[20], a[2], a[17]); // Sum(19) + res[20] = fma52lo(res[20], a[3], a[17]); // Sum(20) + res[21] = fma52hi(res[21], a[3], a[17]); // Sum(20) + res[21] = fma52lo(res[21], a[4], a[17]); // Sum(21) + res[22] = fma52hi(res[22], a[4], a[17]); // Sum(21) + res[22] = fma52lo(res[22], a[5], a[17]); // Sum(22) + res[23] = fma52hi(res[23], a[5], a[17]); // Sum(22) + res[23] = fma52lo(res[23], a[6], a[17]); // Sum(23) + res[24] = fma52hi(res[24], a[6], a[17]); // Sum(23) + res[18] = fma52lo(res[18], a[0], a[18]); // Sum(18) + res[19] = fma52hi(res[19], a[0], a[18]); // Sum(18) + res[19] = fma52lo(res[19], a[1], a[18]); // Sum(19) + res[20] = fma52hi(res[20], a[1], a[18]); // Sum(19) + res[20] = fma52lo(res[20], a[2], a[18]); // Sum(20) + res[21] = fma52hi(res[21], a[2], a[18]); // Sum(20) + res[21] = fma52lo(res[21], a[3], a[18]); // Sum(21) + res[22] = fma52hi(res[22], a[3], a[18]); // Sum(21) + res[22] = fma52lo(res[22], a[4], a[18]); // Sum(22) + res[23] = fma52hi(res[23], a[4], a[18]); // Sum(22) + res[23] = fma52lo(res[23], a[5], a[18]); // Sum(23) + res[24] = fma52hi(res[24], a[5], a[18]); // Sum(23) + res[19] = fma52lo(res[19], a[0], a[19]); // Sum(19) + res[20] = fma52hi(res[20], a[0], a[19]); // Sum(19) + res[20] = fma52lo(res[20], a[1], a[19]); // Sum(20) + res[21] = fma52hi(res[21], a[1], a[19]); // Sum(20) + res[21] = fma52lo(res[21], a[2], a[19]); // Sum(21) + res[22] = fma52hi(res[22], a[2], a[19]); // Sum(21) + res[22] = fma52lo(res[22], a[3], a[19]); // Sum(22) + res[23] = fma52hi(res[23], a[3], a[19]); // Sum(22) + res[23] = fma52lo(res[23], a[4], a[19]); // Sum(23) + res[24] = fma52hi(res[24], a[4], a[19]); // Sum(23) + res[20] = fma52lo(res[20], a[0], a[20]); // Sum(20) + res[21] = fma52hi(res[21], a[0], a[20]); // Sum(20) + res[21] = fma52lo(res[21], a[1], a[20]); // Sum(21) + res[22] = fma52hi(res[22], a[1], a[20]); // Sum(21) + res[22] = fma52lo(res[22], a[2], a[20]); // Sum(22) + res[23] = fma52hi(res[23], a[2], a[20]); // Sum(22) + res[23] = fma52lo(res[23], a[3], a[20]); // Sum(23) + res[24] = fma52hi(res[24], a[3], a[20]); // Sum(23) + res[21] = fma52lo(res[21], a[0], a[21]); // Sum(21) + res[22] = fma52hi(res[22], a[0], a[21]); // Sum(21) + res[22] = fma52lo(res[22], a[1], a[21]); // Sum(22) + res[23] = fma52hi(res[23], a[1], a[21]); // Sum(22) + res[23] = fma52lo(res[23], a[2], a[21]); // Sum(23) + res[24] = fma52hi(res[24], a[2], a[21]); // Sum(23) + res[22] = fma52lo(res[22], a[0], a[22]); // Sum(22) + res[23] = fma52hi(res[23], a[0], a[22]); // Sum(22) + res[23] = fma52lo(res[23], a[1], a[22]); // Sum(23) + res[24] = fma52hi(res[24], a[1], a[22]); // Sum(23) + res[23] = fma52lo(res[23], a[0], a[23]); // Sum(23) + res[24] = fma52hi(res[24], a[0], a[23]); // Sum(23) + res[12] = add64(res[12], res[12]); // Double(12) + res[13] = add64(res[13], res[13]); // Double(13) + res[14] = add64(res[14], res[14]); // Double(14) + res[15] = add64(res[15], res[15]); // Double(15) + res[16] = add64(res[16], res[16]); // Double(16) + res[17] = add64(res[17], res[17]); // Double(17) + res[18] = add64(res[18], res[18]); // Double(18) + res[19] = add64(res[19], res[19]); // Double(19) + res[20] = add64(res[20], res[20]); // Double(20) + res[21] = add64(res[21], res[21]); // Double(21) + res[22] = add64(res[22], res[22]); // Double(22) + res[23] = add64(res[23], res[23]); // Double(23) + res[12] = fma52lo(res[12], a[6], a[6]); // Add sqr(12) + res[13] = fma52hi(res[13], a[6], a[6]); // Add sqr(12) + res[14] = fma52lo(res[14], a[7], a[7]); // Add sqr(14) + res[15] = fma52hi(res[15], a[7], a[7]); // Add sqr(14) + res[16] = fma52lo(res[16], a[8], a[8]); // Add sqr(16) + res[17] = fma52hi(res[17], a[8], a[8]); // Add sqr(16) + res[18] = fma52lo(res[18], a[9], a[9]); // Add sqr(18) + res[19] = fma52hi(res[19], a[9], a[9]); // Add sqr(18) + res[20] = fma52lo(res[20], a[10], a[10]); // Add sqr(20) + res[21] = fma52hi(res[21], a[10], a[10]); // Add sqr(20) + res[22] = fma52lo(res[22], a[11], a[11]); // Add sqr(22) + res[23] = fma52hi(res[23], a[11], a[11]); // Add sqr(22) + res[24] = fma52lo(res[24], a[11], a[13]); // Sum(24) + res[25] = fma52hi(res[25], a[11], a[13]); // Sum(24) + res[25] = fma52lo(res[25], a[12], a[13]); // Sum(25) + res[26] = fma52hi(res[26], a[12], a[13]); // Sum(25) + res[24] = fma52lo(res[24], a[10], a[14]); // Sum(24) + res[25] = fma52hi(res[25], a[10], a[14]); // Sum(24) + res[25] = fma52lo(res[25], a[11], a[14]); // Sum(25) + res[26] = fma52hi(res[26], a[11], a[14]); // Sum(25) + res[26] = fma52lo(res[26], a[12], a[14]); // Sum(26) + res[27] = fma52hi(res[27], a[12], a[14]); // Sum(26) + res[27] = fma52lo(res[27], a[13], a[14]); // Sum(27) + res[28] = fma52hi(res[28], a[13], a[14]); // Sum(27) + res[24] = fma52lo(res[24], a[9], a[15]); // Sum(24) + res[25] = fma52hi(res[25], a[9], a[15]); // Sum(24) + res[25] = fma52lo(res[25], a[10], a[15]); // Sum(25) + res[26] = fma52hi(res[26], a[10], a[15]); // Sum(25) + res[26] = fma52lo(res[26], a[11], a[15]); // Sum(26) + res[27] = fma52hi(res[27], a[11], a[15]); // Sum(26) + res[27] = fma52lo(res[27], a[12], a[15]); // Sum(27) + res[28] = fma52hi(res[28], a[12], a[15]); // Sum(27) + res[28] = fma52lo(res[28], a[13], a[15]); // Sum(28) + res[29] = fma52hi(res[29], a[13], a[15]); // Sum(28) + res[29] = fma52lo(res[29], a[14], a[15]); // Sum(29) + res[30] = fma52hi(res[30], a[14], a[15]); // Sum(29) + res[24] = fma52lo(res[24], a[8], a[16]); // Sum(24) + res[25] = fma52hi(res[25], a[8], a[16]); // Sum(24) + res[25] = fma52lo(res[25], a[9], a[16]); // Sum(25) + res[26] = fma52hi(res[26], a[9], a[16]); // Sum(25) + res[26] = fma52lo(res[26], a[10], a[16]); // Sum(26) + res[27] = fma52hi(res[27], a[10], a[16]); // Sum(26) + res[27] = fma52lo(res[27], a[11], a[16]); // Sum(27) + res[28] = fma52hi(res[28], a[11], a[16]); // Sum(27) + res[28] = fma52lo(res[28], a[12], a[16]); // Sum(28) + res[29] = fma52hi(res[29], a[12], a[16]); // Sum(28) + res[29] = fma52lo(res[29], a[13], a[16]); // Sum(29) + res[30] = fma52hi(res[30], a[13], a[16]); // Sum(29) + res[30] = fma52lo(res[30], a[14], a[16]); // Sum(30) + res[31] = fma52hi(res[31], a[14], a[16]); // Sum(30) + res[31] = fma52lo(res[31], a[15], a[16]); // Sum(31) + res[32] = fma52hi(res[32], a[15], a[16]); // Sum(31) + res[24] = fma52lo(res[24], a[7], a[17]); // Sum(24) + res[25] = fma52hi(res[25], a[7], a[17]); // Sum(24) + res[25] = fma52lo(res[25], a[8], a[17]); // Sum(25) + res[26] = fma52hi(res[26], a[8], a[17]); // Sum(25) + res[26] = fma52lo(res[26], a[9], a[17]); // Sum(26) + res[27] = fma52hi(res[27], a[9], a[17]); // Sum(26) + res[27] = fma52lo(res[27], a[10], a[17]); // Sum(27) + res[28] = fma52hi(res[28], a[10], a[17]); // Sum(27) + res[28] = fma52lo(res[28], a[11], a[17]); // Sum(28) + res[29] = fma52hi(res[29], a[11], a[17]); // Sum(28) + res[29] = fma52lo(res[29], a[12], a[17]); // Sum(29) + res[30] = fma52hi(res[30], a[12], a[17]); // Sum(29) + res[30] = fma52lo(res[30], a[13], a[17]); // Sum(30) + res[31] = fma52hi(res[31], a[13], a[17]); // Sum(30) + res[31] = fma52lo(res[31], a[14], a[17]); // Sum(31) + res[32] = fma52hi(res[32], a[14], a[17]); // Sum(31) + res[32] = fma52lo(res[32], a[15], a[17]); // Sum(32) + res[33] = fma52hi(res[33], a[15], a[17]); // Sum(32) + res[33] = fma52lo(res[33], a[16], a[17]); // Sum(33) + res[34] = fma52hi(res[34], a[16], a[17]); // Sum(33) + res[24] = fma52lo(res[24], a[6], a[18]); // Sum(24) + res[25] = fma52hi(res[25], a[6], a[18]); // Sum(24) + res[25] = fma52lo(res[25], a[7], a[18]); // Sum(25) + res[26] = fma52hi(res[26], a[7], a[18]); // Sum(25) + res[26] = fma52lo(res[26], a[8], a[18]); // Sum(26) + res[27] = fma52hi(res[27], a[8], a[18]); // Sum(26) + res[27] = fma52lo(res[27], a[9], a[18]); // Sum(27) + res[28] = fma52hi(res[28], a[9], a[18]); // Sum(27) + res[28] = fma52lo(res[28], a[10], a[18]); // Sum(28) + res[29] = fma52hi(res[29], a[10], a[18]); // Sum(28) + res[29] = fma52lo(res[29], a[11], a[18]); // Sum(29) + res[30] = fma52hi(res[30], a[11], a[18]); // Sum(29) + res[30] = fma52lo(res[30], a[12], a[18]); // Sum(30) + res[31] = fma52hi(res[31], a[12], a[18]); // Sum(30) + res[31] = fma52lo(res[31], a[13], a[18]); // Sum(31) + res[32] = fma52hi(res[32], a[13], a[18]); // Sum(31) + res[32] = fma52lo(res[32], a[14], a[18]); // Sum(32) + res[33] = fma52hi(res[33], a[14], a[18]); // Sum(32) + res[33] = fma52lo(res[33], a[15], a[18]); // Sum(33) + res[34] = fma52hi(res[34], a[15], a[18]); // Sum(33) + res[34] = fma52lo(res[34], a[16], a[18]); // Sum(34) + res[35] = fma52hi(res[35], a[16], a[18]); // Sum(34) + res[35] = fma52lo(res[35], a[17], a[18]); // Sum(35) + res[36] = fma52hi(res[36], a[17], a[18]); // Sum(35) + res[24] = fma52lo(res[24], a[5], a[19]); // Sum(24) + res[25] = fma52hi(res[25], a[5], a[19]); // Sum(24) + res[25] = fma52lo(res[25], a[6], a[19]); // Sum(25) + res[26] = fma52hi(res[26], a[6], a[19]); // Sum(25) + res[26] = fma52lo(res[26], a[7], a[19]); // Sum(26) + res[27] = fma52hi(res[27], a[7], a[19]); // Sum(26) + res[27] = fma52lo(res[27], a[8], a[19]); // Sum(27) + res[28] = fma52hi(res[28], a[8], a[19]); // Sum(27) + res[28] = fma52lo(res[28], a[9], a[19]); // Sum(28) + res[29] = fma52hi(res[29], a[9], a[19]); // Sum(28) + res[29] = fma52lo(res[29], a[10], a[19]); // Sum(29) + res[30] = fma52hi(res[30], a[10], a[19]); // Sum(29) + res[30] = fma52lo(res[30], a[11], a[19]); // Sum(30) + res[31] = fma52hi(res[31], a[11], a[19]); // Sum(30) + res[31] = fma52lo(res[31], a[12], a[19]); // Sum(31) + res[32] = fma52hi(res[32], a[12], a[19]); // Sum(31) + res[32] = fma52lo(res[32], a[13], a[19]); // Sum(32) + res[33] = fma52hi(res[33], a[13], a[19]); // Sum(32) + res[33] = fma52lo(res[33], a[14], a[19]); // Sum(33) + res[34] = fma52hi(res[34], a[14], a[19]); // Sum(33) + res[34] = fma52lo(res[34], a[15], a[19]); // Sum(34) + res[35] = fma52hi(res[35], a[15], a[19]); // Sum(34) + res[35] = fma52lo(res[35], a[16], a[19]); // Sum(35) + res[36] = fma52hi(res[36], a[16], a[19]); // Sum(35) + res[24] = fma52lo(res[24], a[4], a[20]); // Sum(24) + res[25] = fma52hi(res[25], a[4], a[20]); // Sum(24) + res[25] = fma52lo(res[25], a[5], a[20]); // Sum(25) + res[26] = fma52hi(res[26], a[5], a[20]); // Sum(25) + res[26] = fma52lo(res[26], a[6], a[20]); // Sum(26) + res[27] = fma52hi(res[27], a[6], a[20]); // Sum(26) + res[27] = fma52lo(res[27], a[7], a[20]); // Sum(27) + res[28] = fma52hi(res[28], a[7], a[20]); // Sum(27) + res[28] = fma52lo(res[28], a[8], a[20]); // Sum(28) + res[29] = fma52hi(res[29], a[8], a[20]); // Sum(28) + res[29] = fma52lo(res[29], a[9], a[20]); // Sum(29) + res[30] = fma52hi(res[30], a[9], a[20]); // Sum(29) + res[30] = fma52lo(res[30], a[10], a[20]); // Sum(30) + res[31] = fma52hi(res[31], a[10], a[20]); // Sum(30) + res[31] = fma52lo(res[31], a[11], a[20]); // Sum(31) + res[32] = fma52hi(res[32], a[11], a[20]); // Sum(31) + res[32] = fma52lo(res[32], a[12], a[20]); // Sum(32) + res[33] = fma52hi(res[33], a[12], a[20]); // Sum(32) + res[33] = fma52lo(res[33], a[13], a[20]); // Sum(33) + res[34] = fma52hi(res[34], a[13], a[20]); // Sum(33) + res[34] = fma52lo(res[34], a[14], a[20]); // Sum(34) + res[35] = fma52hi(res[35], a[14], a[20]); // Sum(34) + res[35] = fma52lo(res[35], a[15], a[20]); // Sum(35) + res[36] = fma52hi(res[36], a[15], a[20]); // Sum(35) + res[24] = fma52lo(res[24], a[3], a[21]); // Sum(24) + res[25] = fma52hi(res[25], a[3], a[21]); // Sum(24) + res[25] = fma52lo(res[25], a[4], a[21]); // Sum(25) + res[26] = fma52hi(res[26], a[4], a[21]); // Sum(25) + res[26] = fma52lo(res[26], a[5], a[21]); // Sum(26) + res[27] = fma52hi(res[27], a[5], a[21]); // Sum(26) + res[27] = fma52lo(res[27], a[6], a[21]); // Sum(27) + res[28] = fma52hi(res[28], a[6], a[21]); // Sum(27) + res[28] = fma52lo(res[28], a[7], a[21]); // Sum(28) + res[29] = fma52hi(res[29], a[7], a[21]); // Sum(28) + res[29] = fma52lo(res[29], a[8], a[21]); // Sum(29) + res[30] = fma52hi(res[30], a[8], a[21]); // Sum(29) + res[30] = fma52lo(res[30], a[9], a[21]); // Sum(30) + res[31] = fma52hi(res[31], a[9], a[21]); // Sum(30) + res[31] = fma52lo(res[31], a[10], a[21]); // Sum(31) + res[32] = fma52hi(res[32], a[10], a[21]); // Sum(31) + res[32] = fma52lo(res[32], a[11], a[21]); // Sum(32) + res[33] = fma52hi(res[33], a[11], a[21]); // Sum(32) + res[33] = fma52lo(res[33], a[12], a[21]); // Sum(33) + res[34] = fma52hi(res[34], a[12], a[21]); // Sum(33) + res[34] = fma52lo(res[34], a[13], a[21]); // Sum(34) + res[35] = fma52hi(res[35], a[13], a[21]); // Sum(34) + res[35] = fma52lo(res[35], a[14], a[21]); // Sum(35) + res[36] = fma52hi(res[36], a[14], a[21]); // Sum(35) + res[24] = fma52lo(res[24], a[2], a[22]); // Sum(24) + res[25] = fma52hi(res[25], a[2], a[22]); // Sum(24) + res[25] = fma52lo(res[25], a[3], a[22]); // Sum(25) + res[26] = fma52hi(res[26], a[3], a[22]); // Sum(25) + res[26] = fma52lo(res[26], a[4], a[22]); // Sum(26) + res[27] = fma52hi(res[27], a[4], a[22]); // Sum(26) + res[27] = fma52lo(res[27], a[5], a[22]); // Sum(27) + res[28] = fma52hi(res[28], a[5], a[22]); // Sum(27) + res[28] = fma52lo(res[28], a[6], a[22]); // Sum(28) + res[29] = fma52hi(res[29], a[6], a[22]); // Sum(28) + res[29] = fma52lo(res[29], a[7], a[22]); // Sum(29) + res[30] = fma52hi(res[30], a[7], a[22]); // Sum(29) + res[30] = fma52lo(res[30], a[8], a[22]); // Sum(30) + res[31] = fma52hi(res[31], a[8], a[22]); // Sum(30) + res[31] = fma52lo(res[31], a[9], a[22]); // Sum(31) + res[32] = fma52hi(res[32], a[9], a[22]); // Sum(31) + res[32] = fma52lo(res[32], a[10], a[22]); // Sum(32) + res[33] = fma52hi(res[33], a[10], a[22]); // Sum(32) + res[33] = fma52lo(res[33], a[11], a[22]); // Sum(33) + res[34] = fma52hi(res[34], a[11], a[22]); // Sum(33) + res[34] = fma52lo(res[34], a[12], a[22]); // Sum(34) + res[35] = fma52hi(res[35], a[12], a[22]); // Sum(34) + res[35] = fma52lo(res[35], a[13], a[22]); // Sum(35) + res[36] = fma52hi(res[36], a[13], a[22]); // Sum(35) + res[24] = fma52lo(res[24], a[1], a[23]); // Sum(24) + res[25] = fma52hi(res[25], a[1], a[23]); // Sum(24) + res[25] = fma52lo(res[25], a[2], a[23]); // Sum(25) + res[26] = fma52hi(res[26], a[2], a[23]); // Sum(25) + res[26] = fma52lo(res[26], a[3], a[23]); // Sum(26) + res[27] = fma52hi(res[27], a[3], a[23]); // Sum(26) + res[27] = fma52lo(res[27], a[4], a[23]); // Sum(27) + res[28] = fma52hi(res[28], a[4], a[23]); // Sum(27) + res[28] = fma52lo(res[28], a[5], a[23]); // Sum(28) + res[29] = fma52hi(res[29], a[5], a[23]); // Sum(28) + res[29] = fma52lo(res[29], a[6], a[23]); // Sum(29) + res[30] = fma52hi(res[30], a[6], a[23]); // Sum(29) + res[30] = fma52lo(res[30], a[7], a[23]); // Sum(30) + res[31] = fma52hi(res[31], a[7], a[23]); // Sum(30) + res[31] = fma52lo(res[31], a[8], a[23]); // Sum(31) + res[32] = fma52hi(res[32], a[8], a[23]); // Sum(31) + res[32] = fma52lo(res[32], a[9], a[23]); // Sum(32) + res[33] = fma52hi(res[33], a[9], a[23]); // Sum(32) + res[33] = fma52lo(res[33], a[10], a[23]); // Sum(33) + res[34] = fma52hi(res[34], a[10], a[23]); // Sum(33) + res[34] = fma52lo(res[34], a[11], a[23]); // Sum(34) + res[35] = fma52hi(res[35], a[11], a[23]); // Sum(34) + res[35] = fma52lo(res[35], a[12], a[23]); // Sum(35) + res[36] = fma52hi(res[36], a[12], a[23]); // Sum(35) + res[24] = fma52lo(res[24], a[0], a[24]); // Sum(24) + res[25] = fma52hi(res[25], a[0], a[24]); // Sum(24) + res[25] = fma52lo(res[25], a[1], a[24]); // Sum(25) + res[26] = fma52hi(res[26], a[1], a[24]); // Sum(25) + res[26] = fma52lo(res[26], a[2], a[24]); // Sum(26) + res[27] = fma52hi(res[27], a[2], a[24]); // Sum(26) + res[27] = fma52lo(res[27], a[3], a[24]); // Sum(27) + res[28] = fma52hi(res[28], a[3], a[24]); // Sum(27) + res[28] = fma52lo(res[28], a[4], a[24]); // Sum(28) + res[29] = fma52hi(res[29], a[4], a[24]); // Sum(28) + res[29] = fma52lo(res[29], a[5], a[24]); // Sum(29) + res[30] = fma52hi(res[30], a[5], a[24]); // Sum(29) + res[30] = fma52lo(res[30], a[6], a[24]); // Sum(30) + res[31] = fma52hi(res[31], a[6], a[24]); // Sum(30) + res[31] = fma52lo(res[31], a[7], a[24]); // Sum(31) + res[32] = fma52hi(res[32], a[7], a[24]); // Sum(31) + res[32] = fma52lo(res[32], a[8], a[24]); // Sum(32) + res[33] = fma52hi(res[33], a[8], a[24]); // Sum(32) + res[33] = fma52lo(res[33], a[9], a[24]); // Sum(33) + res[34] = fma52hi(res[34], a[9], a[24]); // Sum(33) + res[34] = fma52lo(res[34], a[10], a[24]); // Sum(34) + res[35] = fma52hi(res[35], a[10], a[24]); // Sum(34) + res[35] = fma52lo(res[35], a[11], a[24]); // Sum(35) + res[36] = fma52hi(res[36], a[11], a[24]); // Sum(35) + res[25] = fma52lo(res[25], a[0], a[25]); // Sum(25) + res[26] = fma52hi(res[26], a[0], a[25]); // Sum(25) + res[26] = fma52lo(res[26], a[1], a[25]); // Sum(26) + res[27] = fma52hi(res[27], a[1], a[25]); // Sum(26) + res[27] = fma52lo(res[27], a[2], a[25]); // Sum(27) + res[28] = fma52hi(res[28], a[2], a[25]); // Sum(27) + res[28] = fma52lo(res[28], a[3], a[25]); // Sum(28) + res[29] = fma52hi(res[29], a[3], a[25]); // Sum(28) + res[29] = fma52lo(res[29], a[4], a[25]); // Sum(29) + res[30] = fma52hi(res[30], a[4], a[25]); // Sum(29) + res[30] = fma52lo(res[30], a[5], a[25]); // Sum(30) + res[31] = fma52hi(res[31], a[5], a[25]); // Sum(30) + res[31] = fma52lo(res[31], a[6], a[25]); // Sum(31) + res[32] = fma52hi(res[32], a[6], a[25]); // Sum(31) + res[32] = fma52lo(res[32], a[7], a[25]); // Sum(32) + res[33] = fma52hi(res[33], a[7], a[25]); // Sum(32) + res[33] = fma52lo(res[33], a[8], a[25]); // Sum(33) + res[34] = fma52hi(res[34], a[8], a[25]); // Sum(33) + res[34] = fma52lo(res[34], a[9], a[25]); // Sum(34) + res[35] = fma52hi(res[35], a[9], a[25]); // Sum(34) + res[35] = fma52lo(res[35], a[10], a[25]); // Sum(35) + res[36] = fma52hi(res[36], a[10], a[25]); // Sum(35) + res[26] = fma52lo(res[26], a[0], a[26]); // Sum(26) + res[27] = fma52hi(res[27], a[0], a[26]); // Sum(26) + res[27] = fma52lo(res[27], a[1], a[26]); // Sum(27) + res[28] = fma52hi(res[28], a[1], a[26]); // Sum(27) + res[28] = fma52lo(res[28], a[2], a[26]); // Sum(28) + res[29] = fma52hi(res[29], a[2], a[26]); // Sum(28) + res[29] = fma52lo(res[29], a[3], a[26]); // Sum(29) + res[30] = fma52hi(res[30], a[3], a[26]); // Sum(29) + res[30] = fma52lo(res[30], a[4], a[26]); // Sum(30) + res[31] = fma52hi(res[31], a[4], a[26]); // Sum(30) + res[31] = fma52lo(res[31], a[5], a[26]); // Sum(31) + res[32] = fma52hi(res[32], a[5], a[26]); // Sum(31) + res[32] = fma52lo(res[32], a[6], a[26]); // Sum(32) + res[33] = fma52hi(res[33], a[6], a[26]); // Sum(32) + res[33] = fma52lo(res[33], a[7], a[26]); // Sum(33) + res[34] = fma52hi(res[34], a[7], a[26]); // Sum(33) + res[34] = fma52lo(res[34], a[8], a[26]); // Sum(34) + res[35] = fma52hi(res[35], a[8], a[26]); // Sum(34) + res[35] = fma52lo(res[35], a[9], a[26]); // Sum(35) + res[36] = fma52hi(res[36], a[9], a[26]); // Sum(35) + res[27] = fma52lo(res[27], a[0], a[27]); // Sum(27) + res[28] = fma52hi(res[28], a[0], a[27]); // Sum(27) + res[28] = fma52lo(res[28], a[1], a[27]); // Sum(28) + res[29] = fma52hi(res[29], a[1], a[27]); // Sum(28) + res[29] = fma52lo(res[29], a[2], a[27]); // Sum(29) + res[30] = fma52hi(res[30], a[2], a[27]); // Sum(29) + res[30] = fma52lo(res[30], a[3], a[27]); // Sum(30) + res[31] = fma52hi(res[31], a[3], a[27]); // Sum(30) + res[31] = fma52lo(res[31], a[4], a[27]); // Sum(31) + res[32] = fma52hi(res[32], a[4], a[27]); // Sum(31) + res[32] = fma52lo(res[32], a[5], a[27]); // Sum(32) + res[33] = fma52hi(res[33], a[5], a[27]); // Sum(32) + res[33] = fma52lo(res[33], a[6], a[27]); // Sum(33) + res[34] = fma52hi(res[34], a[6], a[27]); // Sum(33) + res[34] = fma52lo(res[34], a[7], a[27]); // Sum(34) + res[35] = fma52hi(res[35], a[7], a[27]); // Sum(34) + res[35] = fma52lo(res[35], a[8], a[27]); // Sum(35) + res[36] = fma52hi(res[36], a[8], a[27]); // Sum(35) + res[28] = fma52lo(res[28], a[0], a[28]); // Sum(28) + res[29] = fma52hi(res[29], a[0], a[28]); // Sum(28) + res[29] = fma52lo(res[29], a[1], a[28]); // Sum(29) + res[30] = fma52hi(res[30], a[1], a[28]); // Sum(29) + res[30] = fma52lo(res[30], a[2], a[28]); // Sum(30) + res[31] = fma52hi(res[31], a[2], a[28]); // Sum(30) + res[31] = fma52lo(res[31], a[3], a[28]); // Sum(31) + res[32] = fma52hi(res[32], a[3], a[28]); // Sum(31) + res[32] = fma52lo(res[32], a[4], a[28]); // Sum(32) + res[33] = fma52hi(res[33], a[4], a[28]); // Sum(32) + res[33] = fma52lo(res[33], a[5], a[28]); // Sum(33) + res[34] = fma52hi(res[34], a[5], a[28]); // Sum(33) + res[34] = fma52lo(res[34], a[6], a[28]); // Sum(34) + res[35] = fma52hi(res[35], a[6], a[28]); // Sum(34) + res[35] = fma52lo(res[35], a[7], a[28]); // Sum(35) + res[36] = fma52hi(res[36], a[7], a[28]); // Sum(35) + res[29] = fma52lo(res[29], a[0], a[29]); // Sum(29) + res[30] = fma52hi(res[30], a[0], a[29]); // Sum(29) + res[30] = fma52lo(res[30], a[1], a[29]); // Sum(30) + res[31] = fma52hi(res[31], a[1], a[29]); // Sum(30) + res[31] = fma52lo(res[31], a[2], a[29]); // Sum(31) + res[32] = fma52hi(res[32], a[2], a[29]); // Sum(31) + res[32] = fma52lo(res[32], a[3], a[29]); // Sum(32) + res[33] = fma52hi(res[33], a[3], a[29]); // Sum(32) + res[33] = fma52lo(res[33], a[4], a[29]); // Sum(33) + res[34] = fma52hi(res[34], a[4], a[29]); // Sum(33) + res[34] = fma52lo(res[34], a[5], a[29]); // Sum(34) + res[35] = fma52hi(res[35], a[5], a[29]); // Sum(34) + res[35] = fma52lo(res[35], a[6], a[29]); // Sum(35) + res[36] = fma52hi(res[36], a[6], a[29]); // Sum(35) + res[24] = add64(res[24], res[24]); // Double(24) + res[25] = add64(res[25], res[25]); // Double(25) + res[26] = add64(res[26], res[26]); // Double(26) + res[27] = add64(res[27], res[27]); // Double(27) + res[28] = add64(res[28], res[28]); // Double(28) + res[29] = add64(res[29], res[29]); // Double(29) + res[30] = add64(res[30], res[30]); // Double(30) + res[31] = add64(res[31], res[31]); // Double(31) + res[32] = add64(res[32], res[32]); // Double(32) + res[33] = add64(res[33], res[33]); // Double(33) + res[34] = add64(res[34], res[34]); // Double(34) + res[35] = add64(res[35], res[35]); // Double(35) + res[24] = fma52lo(res[24], a[12], a[12]); // Add sqr(24) + res[25] = fma52hi(res[25], a[12], a[12]); // Add sqr(24) + res[26] = fma52lo(res[26], a[13], a[13]); // Add sqr(26) + res[27] = fma52hi(res[27], a[13], a[13]); // Add sqr(26) + res[28] = fma52lo(res[28], a[14], a[14]); // Add sqr(28) + res[29] = fma52hi(res[29], a[14], a[14]); // Add sqr(28) + res[30] = fma52lo(res[30], a[15], a[15]); // Add sqr(30) + res[31] = fma52hi(res[31], a[15], a[15]); // Add sqr(30) + res[32] = fma52lo(res[32], a[16], a[16]); // Add sqr(32) + res[33] = fma52hi(res[33], a[16], a[16]); // Add sqr(32) + res[34] = fma52lo(res[34], a[17], a[17]); // Add sqr(34) + res[35] = fma52hi(res[35], a[17], a[17]); // Add sqr(34) + res[36] = fma52lo(res[36], a[17], a[19]); // Sum(36) + res[37] = fma52hi(res[37], a[17], a[19]); // Sum(36) + res[37] = fma52lo(res[37], a[18], a[19]); // Sum(37) + res[38] = fma52hi(res[38], a[18], a[19]); // Sum(37) + res[36] = fma52lo(res[36], a[16], a[20]); // Sum(36) + res[37] = fma52hi(res[37], a[16], a[20]); // Sum(36) + res[37] = fma52lo(res[37], a[17], a[20]); // Sum(37) + res[38] = fma52hi(res[38], a[17], a[20]); // Sum(37) + res[38] = fma52lo(res[38], a[18], a[20]); // Sum(38) + res[39] = fma52hi(res[39], a[18], a[20]); // Sum(38) + res[39] = fma52lo(res[39], a[19], a[20]); // Sum(39) + res[40] = fma52hi(res[40], a[19], a[20]); // Sum(39) + res[36] = fma52lo(res[36], a[15], a[21]); // Sum(36) + res[37] = fma52hi(res[37], a[15], a[21]); // Sum(36) + res[37] = fma52lo(res[37], a[16], a[21]); // Sum(37) + res[38] = fma52hi(res[38], a[16], a[21]); // Sum(37) + res[38] = fma52lo(res[38], a[17], a[21]); // Sum(38) + res[39] = fma52hi(res[39], a[17], a[21]); // Sum(38) + res[39] = fma52lo(res[39], a[18], a[21]); // Sum(39) + res[40] = fma52hi(res[40], a[18], a[21]); // Sum(39) + res[40] = fma52lo(res[40], a[19], a[21]); // Sum(40) + res[41] = fma52hi(res[41], a[19], a[21]); // Sum(40) + res[41] = fma52lo(res[41], a[20], a[21]); // Sum(41) + res[42] = fma52hi(res[42], a[20], a[21]); // Sum(41) + res[36] = fma52lo(res[36], a[14], a[22]); // Sum(36) + res[37] = fma52hi(res[37], a[14], a[22]); // Sum(36) + res[37] = fma52lo(res[37], a[15], a[22]); // Sum(37) + res[38] = fma52hi(res[38], a[15], a[22]); // Sum(37) + res[38] = fma52lo(res[38], a[16], a[22]); // Sum(38) + res[39] = fma52hi(res[39], a[16], a[22]); // Sum(38) + res[39] = fma52lo(res[39], a[17], a[22]); // Sum(39) + res[40] = fma52hi(res[40], a[17], a[22]); // Sum(39) + res[40] = fma52lo(res[40], a[18], a[22]); // Sum(40) + res[41] = fma52hi(res[41], a[18], a[22]); // Sum(40) + res[41] = fma52lo(res[41], a[19], a[22]); // Sum(41) + res[42] = fma52hi(res[42], a[19], a[22]); // Sum(41) + res[42] = fma52lo(res[42], a[20], a[22]); // Sum(42) + res[43] = fma52hi(res[43], a[20], a[22]); // Sum(42) + res[43] = fma52lo(res[43], a[21], a[22]); // Sum(43) + res[44] = fma52hi(res[44], a[21], a[22]); // Sum(43) + res[36] = fma52lo(res[36], a[13], a[23]); // Sum(36) + res[37] = fma52hi(res[37], a[13], a[23]); // Sum(36) + res[37] = fma52lo(res[37], a[14], a[23]); // Sum(37) + res[38] = fma52hi(res[38], a[14], a[23]); // Sum(37) + res[38] = fma52lo(res[38], a[15], a[23]); // Sum(38) + res[39] = fma52hi(res[39], a[15], a[23]); // Sum(38) + res[39] = fma52lo(res[39], a[16], a[23]); // Sum(39) + res[40] = fma52hi(res[40], a[16], a[23]); // Sum(39) + res[40] = fma52lo(res[40], a[17], a[23]); // Sum(40) + res[41] = fma52hi(res[41], a[17], a[23]); // Sum(40) + res[41] = fma52lo(res[41], a[18], a[23]); // Sum(41) + res[42] = fma52hi(res[42], a[18], a[23]); // Sum(41) + res[42] = fma52lo(res[42], a[19], a[23]); // Sum(42) + res[43] = fma52hi(res[43], a[19], a[23]); // Sum(42) + res[43] = fma52lo(res[43], a[20], a[23]); // Sum(43) + res[44] = fma52hi(res[44], a[20], a[23]); // Sum(43) + res[44] = fma52lo(res[44], a[21], a[23]); // Sum(44) + res[45] = fma52hi(res[45], a[21], a[23]); // Sum(44) + res[45] = fma52lo(res[45], a[22], a[23]); // Sum(45) + res[46] = fma52hi(res[46], a[22], a[23]); // Sum(45) + res[36] = fma52lo(res[36], a[12], a[24]); // Sum(36) + res[37] = fma52hi(res[37], a[12], a[24]); // Sum(36) + res[37] = fma52lo(res[37], a[13], a[24]); // Sum(37) + res[38] = fma52hi(res[38], a[13], a[24]); // Sum(37) + res[38] = fma52lo(res[38], a[14], a[24]); // Sum(38) + res[39] = fma52hi(res[39], a[14], a[24]); // Sum(38) + res[39] = fma52lo(res[39], a[15], a[24]); // Sum(39) + res[40] = fma52hi(res[40], a[15], a[24]); // Sum(39) + res[40] = fma52lo(res[40], a[16], a[24]); // Sum(40) + res[41] = fma52hi(res[41], a[16], a[24]); // Sum(40) + res[41] = fma52lo(res[41], a[17], a[24]); // Sum(41) + res[42] = fma52hi(res[42], a[17], a[24]); // Sum(41) + res[42] = fma52lo(res[42], a[18], a[24]); // Sum(42) + res[43] = fma52hi(res[43], a[18], a[24]); // Sum(42) + res[43] = fma52lo(res[43], a[19], a[24]); // Sum(43) + res[44] = fma52hi(res[44], a[19], a[24]); // Sum(43) + res[44] = fma52lo(res[44], a[20], a[24]); // Sum(44) + res[45] = fma52hi(res[45], a[20], a[24]); // Sum(44) + res[45] = fma52lo(res[45], a[21], a[24]); // Sum(45) + res[46] = fma52hi(res[46], a[21], a[24]); // Sum(45) + res[46] = fma52lo(res[46], a[22], a[24]); // Sum(46) + res[47] = fma52hi(res[47], a[22], a[24]); // Sum(46) + res[47] = fma52lo(res[47], a[23], a[24]); // Sum(47) + res[48] = fma52hi(res[48], a[23], a[24]); // Sum(47) + res[36] = fma52lo(res[36], a[11], a[25]); // Sum(36) + res[37] = fma52hi(res[37], a[11], a[25]); // Sum(36) + res[37] = fma52lo(res[37], a[12], a[25]); // Sum(37) + res[38] = fma52hi(res[38], a[12], a[25]); // Sum(37) + res[38] = fma52lo(res[38], a[13], a[25]); // Sum(38) + res[39] = fma52hi(res[39], a[13], a[25]); // Sum(38) + res[39] = fma52lo(res[39], a[14], a[25]); // Sum(39) + res[40] = fma52hi(res[40], a[14], a[25]); // Sum(39) + res[40] = fma52lo(res[40], a[15], a[25]); // Sum(40) + res[41] = fma52hi(res[41], a[15], a[25]); // Sum(40) + res[41] = fma52lo(res[41], a[16], a[25]); // Sum(41) + res[42] = fma52hi(res[42], a[16], a[25]); // Sum(41) + res[42] = fma52lo(res[42], a[17], a[25]); // Sum(42) + res[43] = fma52hi(res[43], a[17], a[25]); // Sum(42) + res[43] = fma52lo(res[43], a[18], a[25]); // Sum(43) + res[44] = fma52hi(res[44], a[18], a[25]); // Sum(43) + res[44] = fma52lo(res[44], a[19], a[25]); // Sum(44) + res[45] = fma52hi(res[45], a[19], a[25]); // Sum(44) + res[45] = fma52lo(res[45], a[20], a[25]); // Sum(45) + res[46] = fma52hi(res[46], a[20], a[25]); // Sum(45) + res[46] = fma52lo(res[46], a[21], a[25]); // Sum(46) + res[47] = fma52hi(res[47], a[21], a[25]); // Sum(46) + res[47] = fma52lo(res[47], a[22], a[25]); // Sum(47) + res[48] = fma52hi(res[48], a[22], a[25]); // Sum(47) + res[36] = fma52lo(res[36], a[10], a[26]); // Sum(36) + res[37] = fma52hi(res[37], a[10], a[26]); // Sum(36) + res[37] = fma52lo(res[37], a[11], a[26]); // Sum(37) + res[38] = fma52hi(res[38], a[11], a[26]); // Sum(37) + res[38] = fma52lo(res[38], a[12], a[26]); // Sum(38) + res[39] = fma52hi(res[39], a[12], a[26]); // Sum(38) + res[39] = fma52lo(res[39], a[13], a[26]); // Sum(39) + res[40] = fma52hi(res[40], a[13], a[26]); // Sum(39) + res[40] = fma52lo(res[40], a[14], a[26]); // Sum(40) + res[41] = fma52hi(res[41], a[14], a[26]); // Sum(40) + res[41] = fma52lo(res[41], a[15], a[26]); // Sum(41) + res[42] = fma52hi(res[42], a[15], a[26]); // Sum(41) + res[42] = fma52lo(res[42], a[16], a[26]); // Sum(42) + res[43] = fma52hi(res[43], a[16], a[26]); // Sum(42) + res[43] = fma52lo(res[43], a[17], a[26]); // Sum(43) + res[44] = fma52hi(res[44], a[17], a[26]); // Sum(43) + res[44] = fma52lo(res[44], a[18], a[26]); // Sum(44) + res[45] = fma52hi(res[45], a[18], a[26]); // Sum(44) + res[45] = fma52lo(res[45], a[19], a[26]); // Sum(45) + res[46] = fma52hi(res[46], a[19], a[26]); // Sum(45) + res[46] = fma52lo(res[46], a[20], a[26]); // Sum(46) + res[47] = fma52hi(res[47], a[20], a[26]); // Sum(46) + res[47] = fma52lo(res[47], a[21], a[26]); // Sum(47) + res[48] = fma52hi(res[48], a[21], a[26]); // Sum(47) + res[36] = fma52lo(res[36], a[9], a[27]); // Sum(36) + res[37] = fma52hi(res[37], a[9], a[27]); // Sum(36) + res[37] = fma52lo(res[37], a[10], a[27]); // Sum(37) + res[38] = fma52hi(res[38], a[10], a[27]); // Sum(37) + res[38] = fma52lo(res[38], a[11], a[27]); // Sum(38) + res[39] = fma52hi(res[39], a[11], a[27]); // Sum(38) + res[39] = fma52lo(res[39], a[12], a[27]); // Sum(39) + res[40] = fma52hi(res[40], a[12], a[27]); // Sum(39) + res[40] = fma52lo(res[40], a[13], a[27]); // Sum(40) + res[41] = fma52hi(res[41], a[13], a[27]); // Sum(40) + res[41] = fma52lo(res[41], a[14], a[27]); // Sum(41) + res[42] = fma52hi(res[42], a[14], a[27]); // Sum(41) + res[42] = fma52lo(res[42], a[15], a[27]); // Sum(42) + res[43] = fma52hi(res[43], a[15], a[27]); // Sum(42) + res[43] = fma52lo(res[43], a[16], a[27]); // Sum(43) + res[44] = fma52hi(res[44], a[16], a[27]); // Sum(43) + res[44] = fma52lo(res[44], a[17], a[27]); // Sum(44) + res[45] = fma52hi(res[45], a[17], a[27]); // Sum(44) + res[45] = fma52lo(res[45], a[18], a[27]); // Sum(45) + res[46] = fma52hi(res[46], a[18], a[27]); // Sum(45) + res[46] = fma52lo(res[46], a[19], a[27]); // Sum(46) + res[47] = fma52hi(res[47], a[19], a[27]); // Sum(46) + res[47] = fma52lo(res[47], a[20], a[27]); // Sum(47) + res[48] = fma52hi(res[48], a[20], a[27]); // Sum(47) + res[36] = fma52lo(res[36], a[8], a[28]); // Sum(36) + res[37] = fma52hi(res[37], a[8], a[28]); // Sum(36) + res[37] = fma52lo(res[37], a[9], a[28]); // Sum(37) + res[38] = fma52hi(res[38], a[9], a[28]); // Sum(37) + res[38] = fma52lo(res[38], a[10], a[28]); // Sum(38) + res[39] = fma52hi(res[39], a[10], a[28]); // Sum(38) + res[39] = fma52lo(res[39], a[11], a[28]); // Sum(39) + res[40] = fma52hi(res[40], a[11], a[28]); // Sum(39) + res[40] = fma52lo(res[40], a[12], a[28]); // Sum(40) + res[41] = fma52hi(res[41], a[12], a[28]); // Sum(40) + res[41] = fma52lo(res[41], a[13], a[28]); // Sum(41) + res[42] = fma52hi(res[42], a[13], a[28]); // Sum(41) + res[42] = fma52lo(res[42], a[14], a[28]); // Sum(42) + res[43] = fma52hi(res[43], a[14], a[28]); // Sum(42) + res[43] = fma52lo(res[43], a[15], a[28]); // Sum(43) + res[44] = fma52hi(res[44], a[15], a[28]); // Sum(43) + res[44] = fma52lo(res[44], a[16], a[28]); // Sum(44) + res[45] = fma52hi(res[45], a[16], a[28]); // Sum(44) + res[45] = fma52lo(res[45], a[17], a[28]); // Sum(45) + res[46] = fma52hi(res[46], a[17], a[28]); // Sum(45) + res[46] = fma52lo(res[46], a[18], a[28]); // Sum(46) + res[47] = fma52hi(res[47], a[18], a[28]); // Sum(46) + res[47] = fma52lo(res[47], a[19], a[28]); // Sum(47) + res[48] = fma52hi(res[48], a[19], a[28]); // Sum(47) + res[36] = fma52lo(res[36], a[7], a[29]); // Sum(36) + res[37] = fma52hi(res[37], a[7], a[29]); // Sum(36) + res[37] = fma52lo(res[37], a[8], a[29]); // Sum(37) + res[38] = fma52hi(res[38], a[8], a[29]); // Sum(37) + res[38] = fma52lo(res[38], a[9], a[29]); // Sum(38) + res[39] = fma52hi(res[39], a[9], a[29]); // Sum(38) + res[39] = fma52lo(res[39], a[10], a[29]); // Sum(39) + res[40] = fma52hi(res[40], a[10], a[29]); // Sum(39) + res[40] = fma52lo(res[40], a[11], a[29]); // Sum(40) + res[41] = fma52hi(res[41], a[11], a[29]); // Sum(40) + res[41] = fma52lo(res[41], a[12], a[29]); // Sum(41) + res[42] = fma52hi(res[42], a[12], a[29]); // Sum(41) + res[42] = fma52lo(res[42], a[13], a[29]); // Sum(42) + res[43] = fma52hi(res[43], a[13], a[29]); // Sum(42) + res[43] = fma52lo(res[43], a[14], a[29]); // Sum(43) + res[44] = fma52hi(res[44], a[14], a[29]); // Sum(43) + res[44] = fma52lo(res[44], a[15], a[29]); // Sum(44) + res[45] = fma52hi(res[45], a[15], a[29]); // Sum(44) + res[45] = fma52lo(res[45], a[16], a[29]); // Sum(45) + res[46] = fma52hi(res[46], a[16], a[29]); // Sum(45) + res[46] = fma52lo(res[46], a[17], a[29]); // Sum(46) + res[47] = fma52hi(res[47], a[17], a[29]); // Sum(46) + res[47] = fma52lo(res[47], a[18], a[29]); // Sum(47) + res[48] = fma52hi(res[48], a[18], a[29]); // Sum(47) + res[36] = add64(res[36], res[36]); // Double(36) + res[37] = add64(res[37], res[37]); // Double(37) + res[38] = add64(res[38], res[38]); // Double(38) + res[39] = add64(res[39], res[39]); // Double(39) + res[40] = add64(res[40], res[40]); // Double(40) + res[41] = add64(res[41], res[41]); // Double(41) + res[42] = add64(res[42], res[42]); // Double(42) + res[43] = add64(res[43], res[43]); // Double(43) + res[44] = add64(res[44], res[44]); // Double(44) + res[45] = add64(res[45], res[45]); // Double(45) + res[46] = add64(res[46], res[46]); // Double(46) + res[47] = add64(res[47], res[47]); // Double(47) + res[36] = fma52lo(res[36], a[18], a[18]); // Add sqr(36) + res[37] = fma52hi(res[37], a[18], a[18]); // Add sqr(36) + res[38] = fma52lo(res[38], a[19], a[19]); // Add sqr(38) + res[39] = fma52hi(res[39], a[19], a[19]); // Add sqr(38) + res[40] = fma52lo(res[40], a[20], a[20]); // Add sqr(40) + res[41] = fma52hi(res[41], a[20], a[20]); // Add sqr(40) + res[42] = fma52lo(res[42], a[21], a[21]); // Add sqr(42) + res[43] = fma52hi(res[43], a[21], a[21]); // Add sqr(42) + res[44] = fma52lo(res[44], a[22], a[22]); // Add sqr(44) + res[45] = fma52hi(res[45], a[22], a[22]); // Add sqr(44) + res[46] = fma52lo(res[46], a[23], a[23]); // Add sqr(46) + res[47] = fma52hi(res[47], a[23], a[23]); // Add sqr(46) + res[48] = fma52lo(res[48], a[23], a[25]); // Sum(48) + res[49] = fma52hi(res[49], a[23], a[25]); // Sum(48) + res[49] = fma52lo(res[49], a[24], a[25]); // Sum(49) + res[50] = fma52hi(res[50], a[24], a[25]); // Sum(49) + res[48] = fma52lo(res[48], a[22], a[26]); // Sum(48) + res[49] = fma52hi(res[49], a[22], a[26]); // Sum(48) + res[49] = fma52lo(res[49], a[23], a[26]); // Sum(49) + res[50] = fma52hi(res[50], a[23], a[26]); // Sum(49) + res[50] = fma52lo(res[50], a[24], a[26]); // Sum(50) + res[51] = fma52hi(res[51], a[24], a[26]); // Sum(50) + res[51] = fma52lo(res[51], a[25], a[26]); // Sum(51) + res[52] = fma52hi(res[52], a[25], a[26]); // Sum(51) + res[48] = fma52lo(res[48], a[21], a[27]); // Sum(48) + res[49] = fma52hi(res[49], a[21], a[27]); // Sum(48) + res[49] = fma52lo(res[49], a[22], a[27]); // Sum(49) + res[50] = fma52hi(res[50], a[22], a[27]); // Sum(49) + res[50] = fma52lo(res[50], a[23], a[27]); // Sum(50) + res[51] = fma52hi(res[51], a[23], a[27]); // Sum(50) + res[51] = fma52lo(res[51], a[24], a[27]); // Sum(51) + res[52] = fma52hi(res[52], a[24], a[27]); // Sum(51) + res[52] = fma52lo(res[52], a[25], a[27]); // Sum(52) + res[53] = fma52hi(res[53], a[25], a[27]); // Sum(52) + res[53] = fma52lo(res[53], a[26], a[27]); // Sum(53) + res[54] = fma52hi(res[54], a[26], a[27]); // Sum(53) + res[48] = fma52lo(res[48], a[20], a[28]); // Sum(48) + res[49] = fma52hi(res[49], a[20], a[28]); // Sum(48) + res[49] = fma52lo(res[49], a[21], a[28]); // Sum(49) + res[50] = fma52hi(res[50], a[21], a[28]); // Sum(49) + res[50] = fma52lo(res[50], a[22], a[28]); // Sum(50) + res[51] = fma52hi(res[51], a[22], a[28]); // Sum(50) + res[51] = fma52lo(res[51], a[23], a[28]); // Sum(51) + res[52] = fma52hi(res[52], a[23], a[28]); // Sum(51) + res[52] = fma52lo(res[52], a[24], a[28]); // Sum(52) + res[53] = fma52hi(res[53], a[24], a[28]); // Sum(52) + res[53] = fma52lo(res[53], a[25], a[28]); // Sum(53) + res[54] = fma52hi(res[54], a[25], a[28]); // Sum(53) + res[54] = fma52lo(res[54], a[26], a[28]); // Sum(54) + res[55] = fma52hi(res[55], a[26], a[28]); // Sum(54) + res[55] = fma52lo(res[55], a[27], a[28]); // Sum(55) + res[56] = fma52hi(res[56], a[27], a[28]); // Sum(55) + res[48] = fma52lo(res[48], a[19], a[29]); // Sum(48) + res[49] = fma52hi(res[49], a[19], a[29]); // Sum(48) + res[49] = fma52lo(res[49], a[20], a[29]); // Sum(49) + res[50] = fma52hi(res[50], a[20], a[29]); // Sum(49) + res[50] = fma52lo(res[50], a[21], a[29]); // Sum(50) + res[51] = fma52hi(res[51], a[21], a[29]); // Sum(50) + res[51] = fma52lo(res[51], a[22], a[29]); // Sum(51) + res[52] = fma52hi(res[52], a[22], a[29]); // Sum(51) + res[52] = fma52lo(res[52], a[23], a[29]); // Sum(52) + res[53] = fma52hi(res[53], a[23], a[29]); // Sum(52) + res[53] = fma52lo(res[53], a[24], a[29]); // Sum(53) + res[54] = fma52hi(res[54], a[24], a[29]); // Sum(53) + res[54] = fma52lo(res[54], a[25], a[29]); // Sum(54) + res[55] = fma52hi(res[55], a[25], a[29]); // Sum(54) + res[55] = fma52lo(res[55], a[26], a[29]); // Sum(55) + res[56] = fma52hi(res[56], a[26], a[29]); // Sum(55) + res[56] = fma52lo(res[56], a[27], a[29]); // Sum(56) + res[57] = fma52hi(res[57], a[27], a[29]); // Sum(56) + res[57] = fma52lo(res[57], a[28], a[29]); // Sum(57) + res[58] = fma52hi(res[58], a[28], a[29]); // Sum(57) + res[48] = add64(res[48], res[48]); // Double(48) + res[49] = add64(res[49], res[49]); // Double(49) + res[50] = add64(res[50], res[50]); // Double(50) + res[51] = add64(res[51], res[51]); // Double(51) + res[52] = add64(res[52], res[52]); // Double(52) + res[53] = add64(res[53], res[53]); // Double(53) + res[54] = add64(res[54], res[54]); // Double(54) + res[55] = add64(res[55], res[55]); // Double(55) + res[56] = add64(res[56], res[56]); // Double(56) + res[57] = add64(res[57], res[57]); // Double(57) + res[58] = add64(res[58], res[58]); // Double(58) + res[48] = fma52lo(res[48], a[24], a[24]); // Add sqr(48) + res[49] = fma52hi(res[49], a[24], a[24]); // Add sqr(48) + res[50] = fma52lo(res[50], a[25], a[25]); // Add sqr(50) + res[51] = fma52hi(res[51], a[25], a[25]); // Add sqr(50) + res[52] = fma52lo(res[52], a[26], a[26]); // Add sqr(52) + res[53] = fma52hi(res[53], a[26], a[26]); // Add sqr(52) + res[54] = fma52lo(res[54], a[27], a[27]); // Add sqr(54) + res[55] = fma52hi(res[55], a[27], a[27]); // Add sqr(54) + res[56] = fma52lo(res[56], a[28], a[28]); // Add sqr(56) + res[57] = fma52hi(res[57], a[28], a[28]); // Add sqr(56) + res[58] = fma52lo(res[58], a[29], a[29]); // Add sqr(58) + res[59] = fma52hi(res[59], a[29], a[29]); // Add sqr(58) + + // Montgomery Reduction + int it; + for (it = 0; it < 30; it += 10) { // Reduction step + int jt = 0; + if ((it + 0) > 0) + res[it + 0] = add64(res[it + 0], srli64(res[it + -1], DIGIT_SIZE)); + u[it + 0] = mul52lo(res[it + 0], k); + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + 1] = add64(res[it + 1], srli64(res[it + 0], DIGIT_SIZE)); + u[it + 1] = mul52lo(res[it + 1], k); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + 2] = add64(res[it + 2], srli64(res[it + 1], DIGIT_SIZE)); + u[it + 2] = mul52lo(res[it + 2], k); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + 3] = add64(res[it + 3], srli64(res[it + 2], DIGIT_SIZE)); + u[it + 3] = mul52lo(res[it + 3], k); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + 4] = add64(res[it + 4], srli64(res[it + 3], DIGIT_SIZE)); + u[it + 4] = mul52lo(res[it + 4], k); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + 5] = add64(res[it + 5], srli64(res[it + 4], DIGIT_SIZE)); + u[it + 5] = mul52lo(res[it + 5], k); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + 6] = add64(res[it + 6], srli64(res[it + 5], DIGIT_SIZE)); + u[it + 6] = mul52lo(res[it + 6], k); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + 7] = add64(res[it + 7], srli64(res[it + 6], DIGIT_SIZE)); + u[it + 7] = mul52lo(res[it + 7], k); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + 8] = add64(res[it + 8], srli64(res[it + 7], DIGIT_SIZE)); + u[it + 8] = mul52lo(res[it + 8], k); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + 9] = add64(res[it + 9], srli64(res[it + 8], DIGIT_SIZE)); + u[it + 9] = mul52lo(res[it + 9], k); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + + for (jt = 10; jt < 30; jt += 10) { // Poly tile + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + } + } + + // Normalization + res[30] = add64(res[30], srli64(res[29], DIGIT_SIZE)); + r[0] = and64_const(res[30], DIGIT_MASK); + res[31] = add64(res[31], srli64(res[30], DIGIT_SIZE)); + r[1] = and64_const(res[31], DIGIT_MASK); + res[32] = add64(res[32], srli64(res[31], DIGIT_SIZE)); + r[2] = and64_const(res[32], DIGIT_MASK); + res[33] = add64(res[33], srli64(res[32], DIGIT_SIZE)); + r[3] = and64_const(res[33], DIGIT_MASK); + res[34] = add64(res[34], srli64(res[33], DIGIT_SIZE)); + r[4] = and64_const(res[34], DIGIT_MASK); + res[35] = add64(res[35], srli64(res[34], DIGIT_SIZE)); + r[5] = and64_const(res[35], DIGIT_MASK); + res[36] = add64(res[36], srli64(res[35], DIGIT_SIZE)); + r[6] = and64_const(res[36], DIGIT_MASK); + res[37] = add64(res[37], srli64(res[36], DIGIT_SIZE)); + r[7] = and64_const(res[37], DIGIT_MASK); + res[38] = add64(res[38], srli64(res[37], DIGIT_SIZE)); + r[8] = and64_const(res[38], DIGIT_MASK); + res[39] = add64(res[39], srli64(res[38], DIGIT_SIZE)); + r[9] = and64_const(res[39], DIGIT_MASK); + res[40] = add64(res[40], srli64(res[39], DIGIT_SIZE)); + r[10] = and64_const(res[40], DIGIT_MASK); + res[41] = add64(res[41], srli64(res[40], DIGIT_SIZE)); + r[11] = and64_const(res[41], DIGIT_MASK); + res[42] = add64(res[42], srli64(res[41], DIGIT_SIZE)); + r[12] = and64_const(res[42], DIGIT_MASK); + res[43] = add64(res[43], srli64(res[42], DIGIT_SIZE)); + r[13] = and64_const(res[43], DIGIT_MASK); + res[44] = add64(res[44], srli64(res[43], DIGIT_SIZE)); + r[14] = and64_const(res[44], DIGIT_MASK); + res[45] = add64(res[45], srli64(res[44], DIGIT_SIZE)); + r[15] = and64_const(res[45], DIGIT_MASK); + res[46] = add64(res[46], srli64(res[45], DIGIT_SIZE)); + r[16] = and64_const(res[46], DIGIT_MASK); + res[47] = add64(res[47], srli64(res[46], DIGIT_SIZE)); + r[17] = and64_const(res[47], DIGIT_MASK); + res[48] = add64(res[48], srli64(res[47], DIGIT_SIZE)); + r[18] = and64_const(res[48], DIGIT_MASK); + res[49] = add64(res[49], srli64(res[48], DIGIT_SIZE)); + r[19] = and64_const(res[49], DIGIT_MASK); + res[50] = add64(res[50], srli64(res[49], DIGIT_SIZE)); + r[20] = and64_const(res[50], DIGIT_MASK); + res[51] = add64(res[51], srli64(res[50], DIGIT_SIZE)); + r[21] = and64_const(res[51], DIGIT_MASK); + res[52] = add64(res[52], srli64(res[51], DIGIT_SIZE)); + r[22] = and64_const(res[52], DIGIT_MASK); + res[53] = add64(res[53], srli64(res[52], DIGIT_SIZE)); + r[23] = and64_const(res[53], DIGIT_MASK); + res[54] = add64(res[54], srli64(res[53], DIGIT_SIZE)); + r[24] = and64_const(res[54], DIGIT_MASK); + res[55] = add64(res[55], srli64(res[54], DIGIT_SIZE)); + r[25] = and64_const(res[55], DIGIT_MASK); + res[56] = add64(res[56], srli64(res[55], DIGIT_SIZE)); + r[26] = and64_const(res[56], DIGIT_MASK); + res[57] = add64(res[57], srli64(res[56], DIGIT_SIZE)); + r[27] = and64_const(res[57], DIGIT_MASK); + res[58] = add64(res[58], srli64(res[57], DIGIT_SIZE)); + r[28] = and64_const(res[58], DIGIT_MASK); + res[59] = add64(res[59], srli64(res[58], DIGIT_SIZE)); + r[29] = and64_const(res[59], DIGIT_MASK); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x40_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x40_diagonal_mb8.c new file mode 100644 index 000000000..c75b627f2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x40_diagonal_mb8.c @@ -0,0 +1,2271 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS52x40_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + __ALIGN64 U64 res[80]; + __ALIGN64 U64 u[40]; + U64 k; + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + + k = loadu64((U64 *)k0_mb); + int i; + for (i = 0; i < 80; ++i) + res[i] = get_zero64(); + + res[1] = fma52lo(res[1], a[0], a[1]); // Sum(1) + res[2] = fma52hi(res[2], a[0], a[1]); // Sum(1) + res[2] = fma52lo(res[2], a[0], a[2]); // Sum(2) + res[3] = fma52hi(res[3], a[0], a[2]); // Sum(2) + res[3] = fma52lo(res[3], a[1], a[2]); // Sum(3) + res[4] = fma52hi(res[4], a[1], a[2]); // Sum(3) + res[3] = fma52lo(res[3], a[0], a[3]); // Sum(3) + res[4] = fma52hi(res[4], a[0], a[3]); // Sum(3) + res[4] = fma52lo(res[4], a[1], a[3]); // Sum(4) + res[5] = fma52hi(res[5], a[1], a[3]); // Sum(4) + res[5] = fma52lo(res[5], a[2], a[3]); // Sum(5) + res[6] = fma52hi(res[6], a[2], a[3]); // Sum(5) + res[4] = fma52lo(res[4], a[0], a[4]); // Sum(4) + res[5] = fma52hi(res[5], a[0], a[4]); // Sum(4) + res[5] = fma52lo(res[5], a[1], a[4]); // Sum(5) + res[6] = fma52hi(res[6], a[1], a[4]); // Sum(5) + res[6] = fma52lo(res[6], a[2], a[4]); // Sum(6) + res[7] = fma52hi(res[7], a[2], a[4]); // Sum(6) + res[7] = fma52lo(res[7], a[3], a[4]); // Sum(7) + res[8] = fma52hi(res[8], a[3], a[4]); // Sum(7) + res[5] = fma52lo(res[5], a[0], a[5]); // Sum(5) + res[6] = fma52hi(res[6], a[0], a[5]); // Sum(5) + res[6] = fma52lo(res[6], a[1], a[5]); // Sum(6) + res[7] = fma52hi(res[7], a[1], a[5]); // Sum(6) + res[7] = fma52lo(res[7], a[2], a[5]); // Sum(7) + res[8] = fma52hi(res[8], a[2], a[5]); // Sum(7) + res[8] = fma52lo(res[8], a[3], a[5]); // Sum(8) + res[9] = fma52hi(res[9], a[3], a[5]); // Sum(8) + res[9] = fma52lo(res[9], a[4], a[5]); // Sum(9) + res[10] = fma52hi(res[10], a[4], a[5]); // Sum(9) + res[6] = fma52lo(res[6], a[0], a[6]); // Sum(6) + res[7] = fma52hi(res[7], a[0], a[6]); // Sum(6) + res[7] = fma52lo(res[7], a[1], a[6]); // Sum(7) + res[8] = fma52hi(res[8], a[1], a[6]); // Sum(7) + res[8] = fma52lo(res[8], a[2], a[6]); // Sum(8) + res[9] = fma52hi(res[9], a[2], a[6]); // Sum(8) + res[9] = fma52lo(res[9], a[3], a[6]); // Sum(9) + res[10] = fma52hi(res[10], a[3], a[6]); // Sum(9) + res[10] = fma52lo(res[10], a[4], a[6]); // Sum(10) + res[11] = fma52hi(res[11], a[4], a[6]); // Sum(10) + res[11] = fma52lo(res[11], a[5], a[6]); // Sum(11) + res[12] = fma52hi(res[12], a[5], a[6]); // Sum(11) + res[7] = fma52lo(res[7], a[0], a[7]); // Sum(7) + res[8] = fma52hi(res[8], a[0], a[7]); // Sum(7) + res[8] = fma52lo(res[8], a[1], a[7]); // Sum(8) + res[9] = fma52hi(res[9], a[1], a[7]); // Sum(8) + res[9] = fma52lo(res[9], a[2], a[7]); // Sum(9) + res[10] = fma52hi(res[10], a[2], a[7]); // Sum(9) + res[10] = fma52lo(res[10], a[3], a[7]); // Sum(10) + res[11] = fma52hi(res[11], a[3], a[7]); // Sum(10) + res[11] = fma52lo(res[11], a[4], a[7]); // Sum(11) + res[12] = fma52hi(res[12], a[4], a[7]); // Sum(11) + res[8] = fma52lo(res[8], a[0], a[8]); // Sum(8) + res[9] = fma52hi(res[9], a[0], a[8]); // Sum(8) + res[9] = fma52lo(res[9], a[1], a[8]); // Sum(9) + res[10] = fma52hi(res[10], a[1], a[8]); // Sum(9) + res[10] = fma52lo(res[10], a[2], a[8]); // Sum(10) + res[11] = fma52hi(res[11], a[2], a[8]); // Sum(10) + res[11] = fma52lo(res[11], a[3], a[8]); // Sum(11) + res[12] = fma52hi(res[12], a[3], a[8]); // Sum(11) + res[9] = fma52lo(res[9], a[0], a[9]); // Sum(9) + res[10] = fma52hi(res[10], a[0], a[9]); // Sum(9) + res[10] = fma52lo(res[10], a[1], a[9]); // Sum(10) + res[11] = fma52hi(res[11], a[1], a[9]); // Sum(10) + res[11] = fma52lo(res[11], a[2], a[9]); // Sum(11) + res[12] = fma52hi(res[12], a[2], a[9]); // Sum(11) + res[10] = fma52lo(res[10], a[0], a[10]); // Sum(10) + res[11] = fma52hi(res[11], a[0], a[10]); // Sum(10) + res[11] = fma52lo(res[11], a[1], a[10]); // Sum(11) + res[12] = fma52hi(res[12], a[1], a[10]); // Sum(11) + res[11] = fma52lo(res[11], a[0], a[11]); // Sum(11) + res[12] = fma52hi(res[12], a[0], a[11]); // Sum(11) + res[0] = add64(res[0], res[0]); // Double(0) + res[1] = add64(res[1], res[1]); // Double(1) + res[2] = add64(res[2], res[2]); // Double(2) + res[3] = add64(res[3], res[3]); // Double(3) + res[4] = add64(res[4], res[4]); // Double(4) + res[5] = add64(res[5], res[5]); // Double(5) + res[6] = add64(res[6], res[6]); // Double(6) + res[7] = add64(res[7], res[7]); // Double(7) + res[8] = add64(res[8], res[8]); // Double(8) + res[9] = add64(res[9], res[9]); // Double(9) + res[10] = add64(res[10], res[10]); // Double(10) + res[11] = add64(res[11], res[11]); // Double(11) + res[0] = fma52lo(res[0], a[0], a[0]); // Add sqr(0) + res[1] = fma52hi(res[1], a[0], a[0]); // Add sqr(0) + res[2] = fma52lo(res[2], a[1], a[1]); // Add sqr(2) + res[3] = fma52hi(res[3], a[1], a[1]); // Add sqr(2) + res[4] = fma52lo(res[4], a[2], a[2]); // Add sqr(4) + res[5] = fma52hi(res[5], a[2], a[2]); // Add sqr(4) + res[6] = fma52lo(res[6], a[3], a[3]); // Add sqr(6) + res[7] = fma52hi(res[7], a[3], a[3]); // Add sqr(6) + res[8] = fma52lo(res[8], a[4], a[4]); // Add sqr(8) + res[9] = fma52hi(res[9], a[4], a[4]); // Add sqr(8) + res[10] = fma52lo(res[10], a[5], a[5]); // Add sqr(10) + res[11] = fma52hi(res[11], a[5], a[5]); // Add sqr(10) + res[12] = fma52lo(res[12], a[5], a[7]); // Sum(12) + res[13] = fma52hi(res[13], a[5], a[7]); // Sum(12) + res[13] = fma52lo(res[13], a[6], a[7]); // Sum(13) + res[14] = fma52hi(res[14], a[6], a[7]); // Sum(13) + res[12] = fma52lo(res[12], a[4], a[8]); // Sum(12) + res[13] = fma52hi(res[13], a[4], a[8]); // Sum(12) + res[13] = fma52lo(res[13], a[5], a[8]); // Sum(13) + res[14] = fma52hi(res[14], a[5], a[8]); // Sum(13) + res[14] = fma52lo(res[14], a[6], a[8]); // Sum(14) + res[15] = fma52hi(res[15], a[6], a[8]); // Sum(14) + res[15] = fma52lo(res[15], a[7], a[8]); // Sum(15) + res[16] = fma52hi(res[16], a[7], a[8]); // Sum(15) + res[12] = fma52lo(res[12], a[3], a[9]); // Sum(12) + res[13] = fma52hi(res[13], a[3], a[9]); // Sum(12) + res[13] = fma52lo(res[13], a[4], a[9]); // Sum(13) + res[14] = fma52hi(res[14], a[4], a[9]); // Sum(13) + res[14] = fma52lo(res[14], a[5], a[9]); // Sum(14) + res[15] = fma52hi(res[15], a[5], a[9]); // Sum(14) + res[15] = fma52lo(res[15], a[6], a[9]); // Sum(15) + res[16] = fma52hi(res[16], a[6], a[9]); // Sum(15) + res[16] = fma52lo(res[16], a[7], a[9]); // Sum(16) + res[17] = fma52hi(res[17], a[7], a[9]); // Sum(16) + res[17] = fma52lo(res[17], a[8], a[9]); // Sum(17) + res[18] = fma52hi(res[18], a[8], a[9]); // Sum(17) + res[12] = fma52lo(res[12], a[2], a[10]); // Sum(12) + res[13] = fma52hi(res[13], a[2], a[10]); // Sum(12) + res[13] = fma52lo(res[13], a[3], a[10]); // Sum(13) + res[14] = fma52hi(res[14], a[3], a[10]); // Sum(13) + res[14] = fma52lo(res[14], a[4], a[10]); // Sum(14) + res[15] = fma52hi(res[15], a[4], a[10]); // Sum(14) + res[15] = fma52lo(res[15], a[5], a[10]); // Sum(15) + res[16] = fma52hi(res[16], a[5], a[10]); // Sum(15) + res[16] = fma52lo(res[16], a[6], a[10]); // Sum(16) + res[17] = fma52hi(res[17], a[6], a[10]); // Sum(16) + res[17] = fma52lo(res[17], a[7], a[10]); // Sum(17) + res[18] = fma52hi(res[18], a[7], a[10]); // Sum(17) + res[18] = fma52lo(res[18], a[8], a[10]); // Sum(18) + res[19] = fma52hi(res[19], a[8], a[10]); // Sum(18) + res[19] = fma52lo(res[19], a[9], a[10]); // Sum(19) + res[20] = fma52hi(res[20], a[9], a[10]); // Sum(19) + res[12] = fma52lo(res[12], a[1], a[11]); // Sum(12) + res[13] = fma52hi(res[13], a[1], a[11]); // Sum(12) + res[13] = fma52lo(res[13], a[2], a[11]); // Sum(13) + res[14] = fma52hi(res[14], a[2], a[11]); // Sum(13) + res[14] = fma52lo(res[14], a[3], a[11]); // Sum(14) + res[15] = fma52hi(res[15], a[3], a[11]); // Sum(14) + res[15] = fma52lo(res[15], a[4], a[11]); // Sum(15) + res[16] = fma52hi(res[16], a[4], a[11]); // Sum(15) + res[16] = fma52lo(res[16], a[5], a[11]); // Sum(16) + res[17] = fma52hi(res[17], a[5], a[11]); // Sum(16) + res[17] = fma52lo(res[17], a[6], a[11]); // Sum(17) + res[18] = fma52hi(res[18], a[6], a[11]); // Sum(17) + res[18] = fma52lo(res[18], a[7], a[11]); // Sum(18) + res[19] = fma52hi(res[19], a[7], a[11]); // Sum(18) + res[19] = fma52lo(res[19], a[8], a[11]); // Sum(19) + res[20] = fma52hi(res[20], a[8], a[11]); // Sum(19) + res[20] = fma52lo(res[20], a[9], a[11]); // Sum(20) + res[21] = fma52hi(res[21], a[9], a[11]); // Sum(20) + res[21] = fma52lo(res[21], a[10], a[11]); // Sum(21) + res[22] = fma52hi(res[22], a[10], a[11]); // Sum(21) + res[12] = fma52lo(res[12], a[0], a[12]); // Sum(12) + res[13] = fma52hi(res[13], a[0], a[12]); // Sum(12) + res[13] = fma52lo(res[13], a[1], a[12]); // Sum(13) + res[14] = fma52hi(res[14], a[1], a[12]); // Sum(13) + res[14] = fma52lo(res[14], a[2], a[12]); // Sum(14) + res[15] = fma52hi(res[15], a[2], a[12]); // Sum(14) + res[15] = fma52lo(res[15], a[3], a[12]); // Sum(15) + res[16] = fma52hi(res[16], a[3], a[12]); // Sum(15) + res[16] = fma52lo(res[16], a[4], a[12]); // Sum(16) + res[17] = fma52hi(res[17], a[4], a[12]); // Sum(16) + res[17] = fma52lo(res[17], a[5], a[12]); // Sum(17) + res[18] = fma52hi(res[18], a[5], a[12]); // Sum(17) + res[18] = fma52lo(res[18], a[6], a[12]); // Sum(18) + res[19] = fma52hi(res[19], a[6], a[12]); // Sum(18) + res[19] = fma52lo(res[19], a[7], a[12]); // Sum(19) + res[20] = fma52hi(res[20], a[7], a[12]); // Sum(19) + res[20] = fma52lo(res[20], a[8], a[12]); // Sum(20) + res[21] = fma52hi(res[21], a[8], a[12]); // Sum(20) + res[21] = fma52lo(res[21], a[9], a[12]); // Sum(21) + res[22] = fma52hi(res[22], a[9], a[12]); // Sum(21) + res[22] = fma52lo(res[22], a[10], a[12]); // Sum(22) + res[23] = fma52hi(res[23], a[10], a[12]); // Sum(22) + res[23] = fma52lo(res[23], a[11], a[12]); // Sum(23) + res[24] = fma52hi(res[24], a[11], a[12]); // Sum(23) + res[13] = fma52lo(res[13], a[0], a[13]); // Sum(13) + res[14] = fma52hi(res[14], a[0], a[13]); // Sum(13) + res[14] = fma52lo(res[14], a[1], a[13]); // Sum(14) + res[15] = fma52hi(res[15], a[1], a[13]); // Sum(14) + res[15] = fma52lo(res[15], a[2], a[13]); // Sum(15) + res[16] = fma52hi(res[16], a[2], a[13]); // Sum(15) + res[16] = fma52lo(res[16], a[3], a[13]); // Sum(16) + res[17] = fma52hi(res[17], a[3], a[13]); // Sum(16) + res[17] = fma52lo(res[17], a[4], a[13]); // Sum(17) + res[18] = fma52hi(res[18], a[4], a[13]); // Sum(17) + res[18] = fma52lo(res[18], a[5], a[13]); // Sum(18) + res[19] = fma52hi(res[19], a[5], a[13]); // Sum(18) + res[19] = fma52lo(res[19], a[6], a[13]); // Sum(19) + res[20] = fma52hi(res[20], a[6], a[13]); // Sum(19) + res[20] = fma52lo(res[20], a[7], a[13]); // Sum(20) + res[21] = fma52hi(res[21], a[7], a[13]); // Sum(20) + res[21] = fma52lo(res[21], a[8], a[13]); // Sum(21) + res[22] = fma52hi(res[22], a[8], a[13]); // Sum(21) + res[22] = fma52lo(res[22], a[9], a[13]); // Sum(22) + res[23] = fma52hi(res[23], a[9], a[13]); // Sum(22) + res[23] = fma52lo(res[23], a[10], a[13]); // Sum(23) + res[24] = fma52hi(res[24], a[10], a[13]); // Sum(23) + res[14] = fma52lo(res[14], a[0], a[14]); // Sum(14) + res[15] = fma52hi(res[15], a[0], a[14]); // Sum(14) + res[15] = fma52lo(res[15], a[1], a[14]); // Sum(15) + res[16] = fma52hi(res[16], a[1], a[14]); // Sum(15) + res[16] = fma52lo(res[16], a[2], a[14]); // Sum(16) + res[17] = fma52hi(res[17], a[2], a[14]); // Sum(16) + res[17] = fma52lo(res[17], a[3], a[14]); // Sum(17) + res[18] = fma52hi(res[18], a[3], a[14]); // Sum(17) + res[18] = fma52lo(res[18], a[4], a[14]); // Sum(18) + res[19] = fma52hi(res[19], a[4], a[14]); // Sum(18) + res[19] = fma52lo(res[19], a[5], a[14]); // Sum(19) + res[20] = fma52hi(res[20], a[5], a[14]); // Sum(19) + res[20] = fma52lo(res[20], a[6], a[14]); // Sum(20) + res[21] = fma52hi(res[21], a[6], a[14]); // Sum(20) + res[21] = fma52lo(res[21], a[7], a[14]); // Sum(21) + res[22] = fma52hi(res[22], a[7], a[14]); // Sum(21) + res[22] = fma52lo(res[22], a[8], a[14]); // Sum(22) + res[23] = fma52hi(res[23], a[8], a[14]); // Sum(22) + res[23] = fma52lo(res[23], a[9], a[14]); // Sum(23) + res[24] = fma52hi(res[24], a[9], a[14]); // Sum(23) + res[15] = fma52lo(res[15], a[0], a[15]); // Sum(15) + res[16] = fma52hi(res[16], a[0], a[15]); // Sum(15) + res[16] = fma52lo(res[16], a[1], a[15]); // Sum(16) + res[17] = fma52hi(res[17], a[1], a[15]); // Sum(16) + res[17] = fma52lo(res[17], a[2], a[15]); // Sum(17) + res[18] = fma52hi(res[18], a[2], a[15]); // Sum(17) + res[18] = fma52lo(res[18], a[3], a[15]); // Sum(18) + res[19] = fma52hi(res[19], a[3], a[15]); // Sum(18) + res[19] = fma52lo(res[19], a[4], a[15]); // Sum(19) + res[20] = fma52hi(res[20], a[4], a[15]); // Sum(19) + res[20] = fma52lo(res[20], a[5], a[15]); // Sum(20) + res[21] = fma52hi(res[21], a[5], a[15]); // Sum(20) + res[21] = fma52lo(res[21], a[6], a[15]); // Sum(21) + res[22] = fma52hi(res[22], a[6], a[15]); // Sum(21) + res[22] = fma52lo(res[22], a[7], a[15]); // Sum(22) + res[23] = fma52hi(res[23], a[7], a[15]); // Sum(22) + res[23] = fma52lo(res[23], a[8], a[15]); // Sum(23) + res[24] = fma52hi(res[24], a[8], a[15]); // Sum(23) + res[16] = fma52lo(res[16], a[0], a[16]); // Sum(16) + res[17] = fma52hi(res[17], a[0], a[16]); // Sum(16) + res[17] = fma52lo(res[17], a[1], a[16]); // Sum(17) + res[18] = fma52hi(res[18], a[1], a[16]); // Sum(17) + res[18] = fma52lo(res[18], a[2], a[16]); // Sum(18) + res[19] = fma52hi(res[19], a[2], a[16]); // Sum(18) + res[19] = fma52lo(res[19], a[3], a[16]); // Sum(19) + res[20] = fma52hi(res[20], a[3], a[16]); // Sum(19) + res[20] = fma52lo(res[20], a[4], a[16]); // Sum(20) + res[21] = fma52hi(res[21], a[4], a[16]); // Sum(20) + res[21] = fma52lo(res[21], a[5], a[16]); // Sum(21) + res[22] = fma52hi(res[22], a[5], a[16]); // Sum(21) + res[22] = fma52lo(res[22], a[6], a[16]); // Sum(22) + res[23] = fma52hi(res[23], a[6], a[16]); // Sum(22) + res[23] = fma52lo(res[23], a[7], a[16]); // Sum(23) + res[24] = fma52hi(res[24], a[7], a[16]); // Sum(23) + res[17] = fma52lo(res[17], a[0], a[17]); // Sum(17) + res[18] = fma52hi(res[18], a[0], a[17]); // Sum(17) + res[18] = fma52lo(res[18], a[1], a[17]); // Sum(18) + res[19] = fma52hi(res[19], a[1], a[17]); // Sum(18) + res[19] = fma52lo(res[19], a[2], a[17]); // Sum(19) + res[20] = fma52hi(res[20], a[2], a[17]); // Sum(19) + res[20] = fma52lo(res[20], a[3], a[17]); // Sum(20) + res[21] = fma52hi(res[21], a[3], a[17]); // Sum(20) + res[21] = fma52lo(res[21], a[4], a[17]); // Sum(21) + res[22] = fma52hi(res[22], a[4], a[17]); // Sum(21) + res[22] = fma52lo(res[22], a[5], a[17]); // Sum(22) + res[23] = fma52hi(res[23], a[5], a[17]); // Sum(22) + res[23] = fma52lo(res[23], a[6], a[17]); // Sum(23) + res[24] = fma52hi(res[24], a[6], a[17]); // Sum(23) + res[18] = fma52lo(res[18], a[0], a[18]); // Sum(18) + res[19] = fma52hi(res[19], a[0], a[18]); // Sum(18) + res[19] = fma52lo(res[19], a[1], a[18]); // Sum(19) + res[20] = fma52hi(res[20], a[1], a[18]); // Sum(19) + res[20] = fma52lo(res[20], a[2], a[18]); // Sum(20) + res[21] = fma52hi(res[21], a[2], a[18]); // Sum(20) + res[21] = fma52lo(res[21], a[3], a[18]); // Sum(21) + res[22] = fma52hi(res[22], a[3], a[18]); // Sum(21) + res[22] = fma52lo(res[22], a[4], a[18]); // Sum(22) + res[23] = fma52hi(res[23], a[4], a[18]); // Sum(22) + res[23] = fma52lo(res[23], a[5], a[18]); // Sum(23) + res[24] = fma52hi(res[24], a[5], a[18]); // Sum(23) + res[19] = fma52lo(res[19], a[0], a[19]); // Sum(19) + res[20] = fma52hi(res[20], a[0], a[19]); // Sum(19) + res[20] = fma52lo(res[20], a[1], a[19]); // Sum(20) + res[21] = fma52hi(res[21], a[1], a[19]); // Sum(20) + res[21] = fma52lo(res[21], a[2], a[19]); // Sum(21) + res[22] = fma52hi(res[22], a[2], a[19]); // Sum(21) + res[22] = fma52lo(res[22], a[3], a[19]); // Sum(22) + res[23] = fma52hi(res[23], a[3], a[19]); // Sum(22) + res[23] = fma52lo(res[23], a[4], a[19]); // Sum(23) + res[24] = fma52hi(res[24], a[4], a[19]); // Sum(23) + res[20] = fma52lo(res[20], a[0], a[20]); // Sum(20) + res[21] = fma52hi(res[21], a[0], a[20]); // Sum(20) + res[21] = fma52lo(res[21], a[1], a[20]); // Sum(21) + res[22] = fma52hi(res[22], a[1], a[20]); // Sum(21) + res[22] = fma52lo(res[22], a[2], a[20]); // Sum(22) + res[23] = fma52hi(res[23], a[2], a[20]); // Sum(22) + res[23] = fma52lo(res[23], a[3], a[20]); // Sum(23) + res[24] = fma52hi(res[24], a[3], a[20]); // Sum(23) + res[21] = fma52lo(res[21], a[0], a[21]); // Sum(21) + res[22] = fma52hi(res[22], a[0], a[21]); // Sum(21) + res[22] = fma52lo(res[22], a[1], a[21]); // Sum(22) + res[23] = fma52hi(res[23], a[1], a[21]); // Sum(22) + res[23] = fma52lo(res[23], a[2], a[21]); // Sum(23) + res[24] = fma52hi(res[24], a[2], a[21]); // Sum(23) + res[22] = fma52lo(res[22], a[0], a[22]); // Sum(22) + res[23] = fma52hi(res[23], a[0], a[22]); // Sum(22) + res[23] = fma52lo(res[23], a[1], a[22]); // Sum(23) + res[24] = fma52hi(res[24], a[1], a[22]); // Sum(23) + res[23] = fma52lo(res[23], a[0], a[23]); // Sum(23) + res[24] = fma52hi(res[24], a[0], a[23]); // Sum(23) + res[12] = add64(res[12], res[12]); // Double(12) + res[13] = add64(res[13], res[13]); // Double(13) + res[14] = add64(res[14], res[14]); // Double(14) + res[15] = add64(res[15], res[15]); // Double(15) + res[16] = add64(res[16], res[16]); // Double(16) + res[17] = add64(res[17], res[17]); // Double(17) + res[18] = add64(res[18], res[18]); // Double(18) + res[19] = add64(res[19], res[19]); // Double(19) + res[20] = add64(res[20], res[20]); // Double(20) + res[21] = add64(res[21], res[21]); // Double(21) + res[22] = add64(res[22], res[22]); // Double(22) + res[23] = add64(res[23], res[23]); // Double(23) + res[12] = fma52lo(res[12], a[6], a[6]); // Add sqr(12) + res[13] = fma52hi(res[13], a[6], a[6]); // Add sqr(12) + res[14] = fma52lo(res[14], a[7], a[7]); // Add sqr(14) + res[15] = fma52hi(res[15], a[7], a[7]); // Add sqr(14) + res[16] = fma52lo(res[16], a[8], a[8]); // Add sqr(16) + res[17] = fma52hi(res[17], a[8], a[8]); // Add sqr(16) + res[18] = fma52lo(res[18], a[9], a[9]); // Add sqr(18) + res[19] = fma52hi(res[19], a[9], a[9]); // Add sqr(18) + res[20] = fma52lo(res[20], a[10], a[10]); // Add sqr(20) + res[21] = fma52hi(res[21], a[10], a[10]); // Add sqr(20) + res[22] = fma52lo(res[22], a[11], a[11]); // Add sqr(22) + res[23] = fma52hi(res[23], a[11], a[11]); // Add sqr(22) + res[24] = fma52lo(res[24], a[11], a[13]); // Sum(24) + res[25] = fma52hi(res[25], a[11], a[13]); // Sum(24) + res[25] = fma52lo(res[25], a[12], a[13]); // Sum(25) + res[26] = fma52hi(res[26], a[12], a[13]); // Sum(25) + res[24] = fma52lo(res[24], a[10], a[14]); // Sum(24) + res[25] = fma52hi(res[25], a[10], a[14]); // Sum(24) + res[25] = fma52lo(res[25], a[11], a[14]); // Sum(25) + res[26] = fma52hi(res[26], a[11], a[14]); // Sum(25) + res[26] = fma52lo(res[26], a[12], a[14]); // Sum(26) + res[27] = fma52hi(res[27], a[12], a[14]); // Sum(26) + res[27] = fma52lo(res[27], a[13], a[14]); // Sum(27) + res[28] = fma52hi(res[28], a[13], a[14]); // Sum(27) + res[24] = fma52lo(res[24], a[9], a[15]); // Sum(24) + res[25] = fma52hi(res[25], a[9], a[15]); // Sum(24) + res[25] = fma52lo(res[25], a[10], a[15]); // Sum(25) + res[26] = fma52hi(res[26], a[10], a[15]); // Sum(25) + res[26] = fma52lo(res[26], a[11], a[15]); // Sum(26) + res[27] = fma52hi(res[27], a[11], a[15]); // Sum(26) + res[27] = fma52lo(res[27], a[12], a[15]); // Sum(27) + res[28] = fma52hi(res[28], a[12], a[15]); // Sum(27) + res[28] = fma52lo(res[28], a[13], a[15]); // Sum(28) + res[29] = fma52hi(res[29], a[13], a[15]); // Sum(28) + res[29] = fma52lo(res[29], a[14], a[15]); // Sum(29) + res[30] = fma52hi(res[30], a[14], a[15]); // Sum(29) + res[24] = fma52lo(res[24], a[8], a[16]); // Sum(24) + res[25] = fma52hi(res[25], a[8], a[16]); // Sum(24) + res[25] = fma52lo(res[25], a[9], a[16]); // Sum(25) + res[26] = fma52hi(res[26], a[9], a[16]); // Sum(25) + res[26] = fma52lo(res[26], a[10], a[16]); // Sum(26) + res[27] = fma52hi(res[27], a[10], a[16]); // Sum(26) + res[27] = fma52lo(res[27], a[11], a[16]); // Sum(27) + res[28] = fma52hi(res[28], a[11], a[16]); // Sum(27) + res[28] = fma52lo(res[28], a[12], a[16]); // Sum(28) + res[29] = fma52hi(res[29], a[12], a[16]); // Sum(28) + res[29] = fma52lo(res[29], a[13], a[16]); // Sum(29) + res[30] = fma52hi(res[30], a[13], a[16]); // Sum(29) + res[30] = fma52lo(res[30], a[14], a[16]); // Sum(30) + res[31] = fma52hi(res[31], a[14], a[16]); // Sum(30) + res[31] = fma52lo(res[31], a[15], a[16]); // Sum(31) + res[32] = fma52hi(res[32], a[15], a[16]); // Sum(31) + res[24] = fma52lo(res[24], a[7], a[17]); // Sum(24) + res[25] = fma52hi(res[25], a[7], a[17]); // Sum(24) + res[25] = fma52lo(res[25], a[8], a[17]); // Sum(25) + res[26] = fma52hi(res[26], a[8], a[17]); // Sum(25) + res[26] = fma52lo(res[26], a[9], a[17]); // Sum(26) + res[27] = fma52hi(res[27], a[9], a[17]); // Sum(26) + res[27] = fma52lo(res[27], a[10], a[17]); // Sum(27) + res[28] = fma52hi(res[28], a[10], a[17]); // Sum(27) + res[28] = fma52lo(res[28], a[11], a[17]); // Sum(28) + res[29] = fma52hi(res[29], a[11], a[17]); // Sum(28) + res[29] = fma52lo(res[29], a[12], a[17]); // Sum(29) + res[30] = fma52hi(res[30], a[12], a[17]); // Sum(29) + res[30] = fma52lo(res[30], a[13], a[17]); // Sum(30) + res[31] = fma52hi(res[31], a[13], a[17]); // Sum(30) + res[31] = fma52lo(res[31], a[14], a[17]); // Sum(31) + res[32] = fma52hi(res[32], a[14], a[17]); // Sum(31) + res[32] = fma52lo(res[32], a[15], a[17]); // Sum(32) + res[33] = fma52hi(res[33], a[15], a[17]); // Sum(32) + res[33] = fma52lo(res[33], a[16], a[17]); // Sum(33) + res[34] = fma52hi(res[34], a[16], a[17]); // Sum(33) + res[24] = fma52lo(res[24], a[6], a[18]); // Sum(24) + res[25] = fma52hi(res[25], a[6], a[18]); // Sum(24) + res[25] = fma52lo(res[25], a[7], a[18]); // Sum(25) + res[26] = fma52hi(res[26], a[7], a[18]); // Sum(25) + res[26] = fma52lo(res[26], a[8], a[18]); // Sum(26) + res[27] = fma52hi(res[27], a[8], a[18]); // Sum(26) + res[27] = fma52lo(res[27], a[9], a[18]); // Sum(27) + res[28] = fma52hi(res[28], a[9], a[18]); // Sum(27) + res[28] = fma52lo(res[28], a[10], a[18]); // Sum(28) + res[29] = fma52hi(res[29], a[10], a[18]); // Sum(28) + res[29] = fma52lo(res[29], a[11], a[18]); // Sum(29) + res[30] = fma52hi(res[30], a[11], a[18]); // Sum(29) + res[30] = fma52lo(res[30], a[12], a[18]); // Sum(30) + res[31] = fma52hi(res[31], a[12], a[18]); // Sum(30) + res[31] = fma52lo(res[31], a[13], a[18]); // Sum(31) + res[32] = fma52hi(res[32], a[13], a[18]); // Sum(31) + res[32] = fma52lo(res[32], a[14], a[18]); // Sum(32) + res[33] = fma52hi(res[33], a[14], a[18]); // Sum(32) + res[33] = fma52lo(res[33], a[15], a[18]); // Sum(33) + res[34] = fma52hi(res[34], a[15], a[18]); // Sum(33) + res[34] = fma52lo(res[34], a[16], a[18]); // Sum(34) + res[35] = fma52hi(res[35], a[16], a[18]); // Sum(34) + res[35] = fma52lo(res[35], a[17], a[18]); // Sum(35) + res[36] = fma52hi(res[36], a[17], a[18]); // Sum(35) + res[24] = fma52lo(res[24], a[5], a[19]); // Sum(24) + res[25] = fma52hi(res[25], a[5], a[19]); // Sum(24) + res[25] = fma52lo(res[25], a[6], a[19]); // Sum(25) + res[26] = fma52hi(res[26], a[6], a[19]); // Sum(25) + res[26] = fma52lo(res[26], a[7], a[19]); // Sum(26) + res[27] = fma52hi(res[27], a[7], a[19]); // Sum(26) + res[27] = fma52lo(res[27], a[8], a[19]); // Sum(27) + res[28] = fma52hi(res[28], a[8], a[19]); // Sum(27) + res[28] = fma52lo(res[28], a[9], a[19]); // Sum(28) + res[29] = fma52hi(res[29], a[9], a[19]); // Sum(28) + res[29] = fma52lo(res[29], a[10], a[19]); // Sum(29) + res[30] = fma52hi(res[30], a[10], a[19]); // Sum(29) + res[30] = fma52lo(res[30], a[11], a[19]); // Sum(30) + res[31] = fma52hi(res[31], a[11], a[19]); // Sum(30) + res[31] = fma52lo(res[31], a[12], a[19]); // Sum(31) + res[32] = fma52hi(res[32], a[12], a[19]); // Sum(31) + res[32] = fma52lo(res[32], a[13], a[19]); // Sum(32) + res[33] = fma52hi(res[33], a[13], a[19]); // Sum(32) + res[33] = fma52lo(res[33], a[14], a[19]); // Sum(33) + res[34] = fma52hi(res[34], a[14], a[19]); // Sum(33) + res[34] = fma52lo(res[34], a[15], a[19]); // Sum(34) + res[35] = fma52hi(res[35], a[15], a[19]); // Sum(34) + res[35] = fma52lo(res[35], a[16], a[19]); // Sum(35) + res[36] = fma52hi(res[36], a[16], a[19]); // Sum(35) + res[24] = fma52lo(res[24], a[4], a[20]); // Sum(24) + res[25] = fma52hi(res[25], a[4], a[20]); // Sum(24) + res[25] = fma52lo(res[25], a[5], a[20]); // Sum(25) + res[26] = fma52hi(res[26], a[5], a[20]); // Sum(25) + res[26] = fma52lo(res[26], a[6], a[20]); // Sum(26) + res[27] = fma52hi(res[27], a[6], a[20]); // Sum(26) + res[27] = fma52lo(res[27], a[7], a[20]); // Sum(27) + res[28] = fma52hi(res[28], a[7], a[20]); // Sum(27) + res[28] = fma52lo(res[28], a[8], a[20]); // Sum(28) + res[29] = fma52hi(res[29], a[8], a[20]); // Sum(28) + res[29] = fma52lo(res[29], a[9], a[20]); // Sum(29) + res[30] = fma52hi(res[30], a[9], a[20]); // Sum(29) + res[30] = fma52lo(res[30], a[10], a[20]); // Sum(30) + res[31] = fma52hi(res[31], a[10], a[20]); // Sum(30) + res[31] = fma52lo(res[31], a[11], a[20]); // Sum(31) + res[32] = fma52hi(res[32], a[11], a[20]); // Sum(31) + res[32] = fma52lo(res[32], a[12], a[20]); // Sum(32) + res[33] = fma52hi(res[33], a[12], a[20]); // Sum(32) + res[33] = fma52lo(res[33], a[13], a[20]); // Sum(33) + res[34] = fma52hi(res[34], a[13], a[20]); // Sum(33) + res[34] = fma52lo(res[34], a[14], a[20]); // Sum(34) + res[35] = fma52hi(res[35], a[14], a[20]); // Sum(34) + res[35] = fma52lo(res[35], a[15], a[20]); // Sum(35) + res[36] = fma52hi(res[36], a[15], a[20]); // Sum(35) + res[24] = fma52lo(res[24], a[3], a[21]); // Sum(24) + res[25] = fma52hi(res[25], a[3], a[21]); // Sum(24) + res[25] = fma52lo(res[25], a[4], a[21]); // Sum(25) + res[26] = fma52hi(res[26], a[4], a[21]); // Sum(25) + res[26] = fma52lo(res[26], a[5], a[21]); // Sum(26) + res[27] = fma52hi(res[27], a[5], a[21]); // Sum(26) + res[27] = fma52lo(res[27], a[6], a[21]); // Sum(27) + res[28] = fma52hi(res[28], a[6], a[21]); // Sum(27) + res[28] = fma52lo(res[28], a[7], a[21]); // Sum(28) + res[29] = fma52hi(res[29], a[7], a[21]); // Sum(28) + res[29] = fma52lo(res[29], a[8], a[21]); // Sum(29) + res[30] = fma52hi(res[30], a[8], a[21]); // Sum(29) + res[30] = fma52lo(res[30], a[9], a[21]); // Sum(30) + res[31] = fma52hi(res[31], a[9], a[21]); // Sum(30) + res[31] = fma52lo(res[31], a[10], a[21]); // Sum(31) + res[32] = fma52hi(res[32], a[10], a[21]); // Sum(31) + res[32] = fma52lo(res[32], a[11], a[21]); // Sum(32) + res[33] = fma52hi(res[33], a[11], a[21]); // Sum(32) + res[33] = fma52lo(res[33], a[12], a[21]); // Sum(33) + res[34] = fma52hi(res[34], a[12], a[21]); // Sum(33) + res[34] = fma52lo(res[34], a[13], a[21]); // Sum(34) + res[35] = fma52hi(res[35], a[13], a[21]); // Sum(34) + res[35] = fma52lo(res[35], a[14], a[21]); // Sum(35) + res[36] = fma52hi(res[36], a[14], a[21]); // Sum(35) + res[24] = fma52lo(res[24], a[2], a[22]); // Sum(24) + res[25] = fma52hi(res[25], a[2], a[22]); // Sum(24) + res[25] = fma52lo(res[25], a[3], a[22]); // Sum(25) + res[26] = fma52hi(res[26], a[3], a[22]); // Sum(25) + res[26] = fma52lo(res[26], a[4], a[22]); // Sum(26) + res[27] = fma52hi(res[27], a[4], a[22]); // Sum(26) + res[27] = fma52lo(res[27], a[5], a[22]); // Sum(27) + res[28] = fma52hi(res[28], a[5], a[22]); // Sum(27) + res[28] = fma52lo(res[28], a[6], a[22]); // Sum(28) + res[29] = fma52hi(res[29], a[6], a[22]); // Sum(28) + res[29] = fma52lo(res[29], a[7], a[22]); // Sum(29) + res[30] = fma52hi(res[30], a[7], a[22]); // Sum(29) + res[30] = fma52lo(res[30], a[8], a[22]); // Sum(30) + res[31] = fma52hi(res[31], a[8], a[22]); // Sum(30) + res[31] = fma52lo(res[31], a[9], a[22]); // Sum(31) + res[32] = fma52hi(res[32], a[9], a[22]); // Sum(31) + res[32] = fma52lo(res[32], a[10], a[22]); // Sum(32) + res[33] = fma52hi(res[33], a[10], a[22]); // Sum(32) + res[33] = fma52lo(res[33], a[11], a[22]); // Sum(33) + res[34] = fma52hi(res[34], a[11], a[22]); // Sum(33) + res[34] = fma52lo(res[34], a[12], a[22]); // Sum(34) + res[35] = fma52hi(res[35], a[12], a[22]); // Sum(34) + res[35] = fma52lo(res[35], a[13], a[22]); // Sum(35) + res[36] = fma52hi(res[36], a[13], a[22]); // Sum(35) + res[24] = fma52lo(res[24], a[1], a[23]); // Sum(24) + res[25] = fma52hi(res[25], a[1], a[23]); // Sum(24) + res[25] = fma52lo(res[25], a[2], a[23]); // Sum(25) + res[26] = fma52hi(res[26], a[2], a[23]); // Sum(25) + res[26] = fma52lo(res[26], a[3], a[23]); // Sum(26) + res[27] = fma52hi(res[27], a[3], a[23]); // Sum(26) + res[27] = fma52lo(res[27], a[4], a[23]); // Sum(27) + res[28] = fma52hi(res[28], a[4], a[23]); // Sum(27) + res[28] = fma52lo(res[28], a[5], a[23]); // Sum(28) + res[29] = fma52hi(res[29], a[5], a[23]); // Sum(28) + res[29] = fma52lo(res[29], a[6], a[23]); // Sum(29) + res[30] = fma52hi(res[30], a[6], a[23]); // Sum(29) + res[30] = fma52lo(res[30], a[7], a[23]); // Sum(30) + res[31] = fma52hi(res[31], a[7], a[23]); // Sum(30) + res[31] = fma52lo(res[31], a[8], a[23]); // Sum(31) + res[32] = fma52hi(res[32], a[8], a[23]); // Sum(31) + res[32] = fma52lo(res[32], a[9], a[23]); // Sum(32) + res[33] = fma52hi(res[33], a[9], a[23]); // Sum(32) + res[33] = fma52lo(res[33], a[10], a[23]); // Sum(33) + res[34] = fma52hi(res[34], a[10], a[23]); // Sum(33) + res[34] = fma52lo(res[34], a[11], a[23]); // Sum(34) + res[35] = fma52hi(res[35], a[11], a[23]); // Sum(34) + res[35] = fma52lo(res[35], a[12], a[23]); // Sum(35) + res[36] = fma52hi(res[36], a[12], a[23]); // Sum(35) + res[24] = fma52lo(res[24], a[0], a[24]); // Sum(24) + res[25] = fma52hi(res[25], a[0], a[24]); // Sum(24) + res[25] = fma52lo(res[25], a[1], a[24]); // Sum(25) + res[26] = fma52hi(res[26], a[1], a[24]); // Sum(25) + res[26] = fma52lo(res[26], a[2], a[24]); // Sum(26) + res[27] = fma52hi(res[27], a[2], a[24]); // Sum(26) + res[27] = fma52lo(res[27], a[3], a[24]); // Sum(27) + res[28] = fma52hi(res[28], a[3], a[24]); // Sum(27) + res[28] = fma52lo(res[28], a[4], a[24]); // Sum(28) + res[29] = fma52hi(res[29], a[4], a[24]); // Sum(28) + res[29] = fma52lo(res[29], a[5], a[24]); // Sum(29) + res[30] = fma52hi(res[30], a[5], a[24]); // Sum(29) + res[30] = fma52lo(res[30], a[6], a[24]); // Sum(30) + res[31] = fma52hi(res[31], a[6], a[24]); // Sum(30) + res[31] = fma52lo(res[31], a[7], a[24]); // Sum(31) + res[32] = fma52hi(res[32], a[7], a[24]); // Sum(31) + res[32] = fma52lo(res[32], a[8], a[24]); // Sum(32) + res[33] = fma52hi(res[33], a[8], a[24]); // Sum(32) + res[33] = fma52lo(res[33], a[9], a[24]); // Sum(33) + res[34] = fma52hi(res[34], a[9], a[24]); // Sum(33) + res[34] = fma52lo(res[34], a[10], a[24]); // Sum(34) + res[35] = fma52hi(res[35], a[10], a[24]); // Sum(34) + res[35] = fma52lo(res[35], a[11], a[24]); // Sum(35) + res[36] = fma52hi(res[36], a[11], a[24]); // Sum(35) + res[25] = fma52lo(res[25], a[0], a[25]); // Sum(25) + res[26] = fma52hi(res[26], a[0], a[25]); // Sum(25) + res[26] = fma52lo(res[26], a[1], a[25]); // Sum(26) + res[27] = fma52hi(res[27], a[1], a[25]); // Sum(26) + res[27] = fma52lo(res[27], a[2], a[25]); // Sum(27) + res[28] = fma52hi(res[28], a[2], a[25]); // Sum(27) + res[28] = fma52lo(res[28], a[3], a[25]); // Sum(28) + res[29] = fma52hi(res[29], a[3], a[25]); // Sum(28) + res[29] = fma52lo(res[29], a[4], a[25]); // Sum(29) + res[30] = fma52hi(res[30], a[4], a[25]); // Sum(29) + res[30] = fma52lo(res[30], a[5], a[25]); // Sum(30) + res[31] = fma52hi(res[31], a[5], a[25]); // Sum(30) + res[31] = fma52lo(res[31], a[6], a[25]); // Sum(31) + res[32] = fma52hi(res[32], a[6], a[25]); // Sum(31) + res[32] = fma52lo(res[32], a[7], a[25]); // Sum(32) + res[33] = fma52hi(res[33], a[7], a[25]); // Sum(32) + res[33] = fma52lo(res[33], a[8], a[25]); // Sum(33) + res[34] = fma52hi(res[34], a[8], a[25]); // Sum(33) + res[34] = fma52lo(res[34], a[9], a[25]); // Sum(34) + res[35] = fma52hi(res[35], a[9], a[25]); // Sum(34) + res[35] = fma52lo(res[35], a[10], a[25]); // Sum(35) + res[36] = fma52hi(res[36], a[10], a[25]); // Sum(35) + res[26] = fma52lo(res[26], a[0], a[26]); // Sum(26) + res[27] = fma52hi(res[27], a[0], a[26]); // Sum(26) + res[27] = fma52lo(res[27], a[1], a[26]); // Sum(27) + res[28] = fma52hi(res[28], a[1], a[26]); // Sum(27) + res[28] = fma52lo(res[28], a[2], a[26]); // Sum(28) + res[29] = fma52hi(res[29], a[2], a[26]); // Sum(28) + res[29] = fma52lo(res[29], a[3], a[26]); // Sum(29) + res[30] = fma52hi(res[30], a[3], a[26]); // Sum(29) + res[30] = fma52lo(res[30], a[4], a[26]); // Sum(30) + res[31] = fma52hi(res[31], a[4], a[26]); // Sum(30) + res[31] = fma52lo(res[31], a[5], a[26]); // Sum(31) + res[32] = fma52hi(res[32], a[5], a[26]); // Sum(31) + res[32] = fma52lo(res[32], a[6], a[26]); // Sum(32) + res[33] = fma52hi(res[33], a[6], a[26]); // Sum(32) + res[33] = fma52lo(res[33], a[7], a[26]); // Sum(33) + res[34] = fma52hi(res[34], a[7], a[26]); // Sum(33) + res[34] = fma52lo(res[34], a[8], a[26]); // Sum(34) + res[35] = fma52hi(res[35], a[8], a[26]); // Sum(34) + res[35] = fma52lo(res[35], a[9], a[26]); // Sum(35) + res[36] = fma52hi(res[36], a[9], a[26]); // Sum(35) + res[27] = fma52lo(res[27], a[0], a[27]); // Sum(27) + res[28] = fma52hi(res[28], a[0], a[27]); // Sum(27) + res[28] = fma52lo(res[28], a[1], a[27]); // Sum(28) + res[29] = fma52hi(res[29], a[1], a[27]); // Sum(28) + res[29] = fma52lo(res[29], a[2], a[27]); // Sum(29) + res[30] = fma52hi(res[30], a[2], a[27]); // Sum(29) + res[30] = fma52lo(res[30], a[3], a[27]); // Sum(30) + res[31] = fma52hi(res[31], a[3], a[27]); // Sum(30) + res[31] = fma52lo(res[31], a[4], a[27]); // Sum(31) + res[32] = fma52hi(res[32], a[4], a[27]); // Sum(31) + res[32] = fma52lo(res[32], a[5], a[27]); // Sum(32) + res[33] = fma52hi(res[33], a[5], a[27]); // Sum(32) + res[33] = fma52lo(res[33], a[6], a[27]); // Sum(33) + res[34] = fma52hi(res[34], a[6], a[27]); // Sum(33) + res[34] = fma52lo(res[34], a[7], a[27]); // Sum(34) + res[35] = fma52hi(res[35], a[7], a[27]); // Sum(34) + res[35] = fma52lo(res[35], a[8], a[27]); // Sum(35) + res[36] = fma52hi(res[36], a[8], a[27]); // Sum(35) + res[28] = fma52lo(res[28], a[0], a[28]); // Sum(28) + res[29] = fma52hi(res[29], a[0], a[28]); // Sum(28) + res[29] = fma52lo(res[29], a[1], a[28]); // Sum(29) + res[30] = fma52hi(res[30], a[1], a[28]); // Sum(29) + res[30] = fma52lo(res[30], a[2], a[28]); // Sum(30) + res[31] = fma52hi(res[31], a[2], a[28]); // Sum(30) + res[31] = fma52lo(res[31], a[3], a[28]); // Sum(31) + res[32] = fma52hi(res[32], a[3], a[28]); // Sum(31) + res[32] = fma52lo(res[32], a[4], a[28]); // Sum(32) + res[33] = fma52hi(res[33], a[4], a[28]); // Sum(32) + res[33] = fma52lo(res[33], a[5], a[28]); // Sum(33) + res[34] = fma52hi(res[34], a[5], a[28]); // Sum(33) + res[34] = fma52lo(res[34], a[6], a[28]); // Sum(34) + res[35] = fma52hi(res[35], a[6], a[28]); // Sum(34) + res[35] = fma52lo(res[35], a[7], a[28]); // Sum(35) + res[36] = fma52hi(res[36], a[7], a[28]); // Sum(35) + res[29] = fma52lo(res[29], a[0], a[29]); // Sum(29) + res[30] = fma52hi(res[30], a[0], a[29]); // Sum(29) + res[30] = fma52lo(res[30], a[1], a[29]); // Sum(30) + res[31] = fma52hi(res[31], a[1], a[29]); // Sum(30) + res[31] = fma52lo(res[31], a[2], a[29]); // Sum(31) + res[32] = fma52hi(res[32], a[2], a[29]); // Sum(31) + res[32] = fma52lo(res[32], a[3], a[29]); // Sum(32) + res[33] = fma52hi(res[33], a[3], a[29]); // Sum(32) + res[33] = fma52lo(res[33], a[4], a[29]); // Sum(33) + res[34] = fma52hi(res[34], a[4], a[29]); // Sum(33) + res[34] = fma52lo(res[34], a[5], a[29]); // Sum(34) + res[35] = fma52hi(res[35], a[5], a[29]); // Sum(34) + res[35] = fma52lo(res[35], a[6], a[29]); // Sum(35) + res[36] = fma52hi(res[36], a[6], a[29]); // Sum(35) + res[30] = fma52lo(res[30], a[0], a[30]); // Sum(30) + res[31] = fma52hi(res[31], a[0], a[30]); // Sum(30) + res[31] = fma52lo(res[31], a[1], a[30]); // Sum(31) + res[32] = fma52hi(res[32], a[1], a[30]); // Sum(31) + res[32] = fma52lo(res[32], a[2], a[30]); // Sum(32) + res[33] = fma52hi(res[33], a[2], a[30]); // Sum(32) + res[33] = fma52lo(res[33], a[3], a[30]); // Sum(33) + res[34] = fma52hi(res[34], a[3], a[30]); // Sum(33) + res[34] = fma52lo(res[34], a[4], a[30]); // Sum(34) + res[35] = fma52hi(res[35], a[4], a[30]); // Sum(34) + res[35] = fma52lo(res[35], a[5], a[30]); // Sum(35) + res[36] = fma52hi(res[36], a[5], a[30]); // Sum(35) + res[31] = fma52lo(res[31], a[0], a[31]); // Sum(31) + res[32] = fma52hi(res[32], a[0], a[31]); // Sum(31) + res[32] = fma52lo(res[32], a[1], a[31]); // Sum(32) + res[33] = fma52hi(res[33], a[1], a[31]); // Sum(32) + res[33] = fma52lo(res[33], a[2], a[31]); // Sum(33) + res[34] = fma52hi(res[34], a[2], a[31]); // Sum(33) + res[34] = fma52lo(res[34], a[3], a[31]); // Sum(34) + res[35] = fma52hi(res[35], a[3], a[31]); // Sum(34) + res[35] = fma52lo(res[35], a[4], a[31]); // Sum(35) + res[36] = fma52hi(res[36], a[4], a[31]); // Sum(35) + res[32] = fma52lo(res[32], a[0], a[32]); // Sum(32) + res[33] = fma52hi(res[33], a[0], a[32]); // Sum(32) + res[33] = fma52lo(res[33], a[1], a[32]); // Sum(33) + res[34] = fma52hi(res[34], a[1], a[32]); // Sum(33) + res[34] = fma52lo(res[34], a[2], a[32]); // Sum(34) + res[35] = fma52hi(res[35], a[2], a[32]); // Sum(34) + res[35] = fma52lo(res[35], a[3], a[32]); // Sum(35) + res[36] = fma52hi(res[36], a[3], a[32]); // Sum(35) + res[33] = fma52lo(res[33], a[0], a[33]); // Sum(33) + res[34] = fma52hi(res[34], a[0], a[33]); // Sum(33) + res[34] = fma52lo(res[34], a[1], a[33]); // Sum(34) + res[35] = fma52hi(res[35], a[1], a[33]); // Sum(34) + res[35] = fma52lo(res[35], a[2], a[33]); // Sum(35) + res[36] = fma52hi(res[36], a[2], a[33]); // Sum(35) + res[34] = fma52lo(res[34], a[0], a[34]); // Sum(34) + res[35] = fma52hi(res[35], a[0], a[34]); // Sum(34) + res[35] = fma52lo(res[35], a[1], a[34]); // Sum(35) + res[36] = fma52hi(res[36], a[1], a[34]); // Sum(35) + res[35] = fma52lo(res[35], a[0], a[35]); // Sum(35) + res[36] = fma52hi(res[36], a[0], a[35]); // Sum(35) + res[24] = add64(res[24], res[24]); // Double(24) + res[25] = add64(res[25], res[25]); // Double(25) + res[26] = add64(res[26], res[26]); // Double(26) + res[27] = add64(res[27], res[27]); // Double(27) + res[28] = add64(res[28], res[28]); // Double(28) + res[29] = add64(res[29], res[29]); // Double(29) + res[30] = add64(res[30], res[30]); // Double(30) + res[31] = add64(res[31], res[31]); // Double(31) + res[32] = add64(res[32], res[32]); // Double(32) + res[33] = add64(res[33], res[33]); // Double(33) + res[34] = add64(res[34], res[34]); // Double(34) + res[35] = add64(res[35], res[35]); // Double(35) + res[24] = fma52lo(res[24], a[12], a[12]); // Add sqr(24) + res[25] = fma52hi(res[25], a[12], a[12]); // Add sqr(24) + res[26] = fma52lo(res[26], a[13], a[13]); // Add sqr(26) + res[27] = fma52hi(res[27], a[13], a[13]); // Add sqr(26) + res[28] = fma52lo(res[28], a[14], a[14]); // Add sqr(28) + res[29] = fma52hi(res[29], a[14], a[14]); // Add sqr(28) + res[30] = fma52lo(res[30], a[15], a[15]); // Add sqr(30) + res[31] = fma52hi(res[31], a[15], a[15]); // Add sqr(30) + res[32] = fma52lo(res[32], a[16], a[16]); // Add sqr(32) + res[33] = fma52hi(res[33], a[16], a[16]); // Add sqr(32) + res[34] = fma52lo(res[34], a[17], a[17]); // Add sqr(34) + res[35] = fma52hi(res[35], a[17], a[17]); // Add sqr(34) + res[36] = fma52lo(res[36], a[17], a[19]); // Sum(36) + res[37] = fma52hi(res[37], a[17], a[19]); // Sum(36) + res[37] = fma52lo(res[37], a[18], a[19]); // Sum(37) + res[38] = fma52hi(res[38], a[18], a[19]); // Sum(37) + res[36] = fma52lo(res[36], a[16], a[20]); // Sum(36) + res[37] = fma52hi(res[37], a[16], a[20]); // Sum(36) + res[37] = fma52lo(res[37], a[17], a[20]); // Sum(37) + res[38] = fma52hi(res[38], a[17], a[20]); // Sum(37) + res[38] = fma52lo(res[38], a[18], a[20]); // Sum(38) + res[39] = fma52hi(res[39], a[18], a[20]); // Sum(38) + res[39] = fma52lo(res[39], a[19], a[20]); // Sum(39) + res[40] = fma52hi(res[40], a[19], a[20]); // Sum(39) + res[36] = fma52lo(res[36], a[15], a[21]); // Sum(36) + res[37] = fma52hi(res[37], a[15], a[21]); // Sum(36) + res[37] = fma52lo(res[37], a[16], a[21]); // Sum(37) + res[38] = fma52hi(res[38], a[16], a[21]); // Sum(37) + res[38] = fma52lo(res[38], a[17], a[21]); // Sum(38) + res[39] = fma52hi(res[39], a[17], a[21]); // Sum(38) + res[39] = fma52lo(res[39], a[18], a[21]); // Sum(39) + res[40] = fma52hi(res[40], a[18], a[21]); // Sum(39) + res[40] = fma52lo(res[40], a[19], a[21]); // Sum(40) + res[41] = fma52hi(res[41], a[19], a[21]); // Sum(40) + res[41] = fma52lo(res[41], a[20], a[21]); // Sum(41) + res[42] = fma52hi(res[42], a[20], a[21]); // Sum(41) + res[36] = fma52lo(res[36], a[14], a[22]); // Sum(36) + res[37] = fma52hi(res[37], a[14], a[22]); // Sum(36) + res[37] = fma52lo(res[37], a[15], a[22]); // Sum(37) + res[38] = fma52hi(res[38], a[15], a[22]); // Sum(37) + res[38] = fma52lo(res[38], a[16], a[22]); // Sum(38) + res[39] = fma52hi(res[39], a[16], a[22]); // Sum(38) + res[39] = fma52lo(res[39], a[17], a[22]); // Sum(39) + res[40] = fma52hi(res[40], a[17], a[22]); // Sum(39) + res[40] = fma52lo(res[40], a[18], a[22]); // Sum(40) + res[41] = fma52hi(res[41], a[18], a[22]); // Sum(40) + res[41] = fma52lo(res[41], a[19], a[22]); // Sum(41) + res[42] = fma52hi(res[42], a[19], a[22]); // Sum(41) + res[42] = fma52lo(res[42], a[20], a[22]); // Sum(42) + res[43] = fma52hi(res[43], a[20], a[22]); // Sum(42) + res[43] = fma52lo(res[43], a[21], a[22]); // Sum(43) + res[44] = fma52hi(res[44], a[21], a[22]); // Sum(43) + res[36] = fma52lo(res[36], a[13], a[23]); // Sum(36) + res[37] = fma52hi(res[37], a[13], a[23]); // Sum(36) + res[37] = fma52lo(res[37], a[14], a[23]); // Sum(37) + res[38] = fma52hi(res[38], a[14], a[23]); // Sum(37) + res[38] = fma52lo(res[38], a[15], a[23]); // Sum(38) + res[39] = fma52hi(res[39], a[15], a[23]); // Sum(38) + res[39] = fma52lo(res[39], a[16], a[23]); // Sum(39) + res[40] = fma52hi(res[40], a[16], a[23]); // Sum(39) + res[40] = fma52lo(res[40], a[17], a[23]); // Sum(40) + res[41] = fma52hi(res[41], a[17], a[23]); // Sum(40) + res[41] = fma52lo(res[41], a[18], a[23]); // Sum(41) + res[42] = fma52hi(res[42], a[18], a[23]); // Sum(41) + res[42] = fma52lo(res[42], a[19], a[23]); // Sum(42) + res[43] = fma52hi(res[43], a[19], a[23]); // Sum(42) + res[43] = fma52lo(res[43], a[20], a[23]); // Sum(43) + res[44] = fma52hi(res[44], a[20], a[23]); // Sum(43) + res[44] = fma52lo(res[44], a[21], a[23]); // Sum(44) + res[45] = fma52hi(res[45], a[21], a[23]); // Sum(44) + res[45] = fma52lo(res[45], a[22], a[23]); // Sum(45) + res[46] = fma52hi(res[46], a[22], a[23]); // Sum(45) + res[36] = fma52lo(res[36], a[12], a[24]); // Sum(36) + res[37] = fma52hi(res[37], a[12], a[24]); // Sum(36) + res[37] = fma52lo(res[37], a[13], a[24]); // Sum(37) + res[38] = fma52hi(res[38], a[13], a[24]); // Sum(37) + res[38] = fma52lo(res[38], a[14], a[24]); // Sum(38) + res[39] = fma52hi(res[39], a[14], a[24]); // Sum(38) + res[39] = fma52lo(res[39], a[15], a[24]); // Sum(39) + res[40] = fma52hi(res[40], a[15], a[24]); // Sum(39) + res[40] = fma52lo(res[40], a[16], a[24]); // Sum(40) + res[41] = fma52hi(res[41], a[16], a[24]); // Sum(40) + res[41] = fma52lo(res[41], a[17], a[24]); // Sum(41) + res[42] = fma52hi(res[42], a[17], a[24]); // Sum(41) + res[42] = fma52lo(res[42], a[18], a[24]); // Sum(42) + res[43] = fma52hi(res[43], a[18], a[24]); // Sum(42) + res[43] = fma52lo(res[43], a[19], a[24]); // Sum(43) + res[44] = fma52hi(res[44], a[19], a[24]); // Sum(43) + res[44] = fma52lo(res[44], a[20], a[24]); // Sum(44) + res[45] = fma52hi(res[45], a[20], a[24]); // Sum(44) + res[45] = fma52lo(res[45], a[21], a[24]); // Sum(45) + res[46] = fma52hi(res[46], a[21], a[24]); // Sum(45) + res[46] = fma52lo(res[46], a[22], a[24]); // Sum(46) + res[47] = fma52hi(res[47], a[22], a[24]); // Sum(46) + res[47] = fma52lo(res[47], a[23], a[24]); // Sum(47) + res[48] = fma52hi(res[48], a[23], a[24]); // Sum(47) + res[36] = fma52lo(res[36], a[11], a[25]); // Sum(36) + res[37] = fma52hi(res[37], a[11], a[25]); // Sum(36) + res[37] = fma52lo(res[37], a[12], a[25]); // Sum(37) + res[38] = fma52hi(res[38], a[12], a[25]); // Sum(37) + res[38] = fma52lo(res[38], a[13], a[25]); // Sum(38) + res[39] = fma52hi(res[39], a[13], a[25]); // Sum(38) + res[39] = fma52lo(res[39], a[14], a[25]); // Sum(39) + res[40] = fma52hi(res[40], a[14], a[25]); // Sum(39) + res[40] = fma52lo(res[40], a[15], a[25]); // Sum(40) + res[41] = fma52hi(res[41], a[15], a[25]); // Sum(40) + res[41] = fma52lo(res[41], a[16], a[25]); // Sum(41) + res[42] = fma52hi(res[42], a[16], a[25]); // Sum(41) + res[42] = fma52lo(res[42], a[17], a[25]); // Sum(42) + res[43] = fma52hi(res[43], a[17], a[25]); // Sum(42) + res[43] = fma52lo(res[43], a[18], a[25]); // Sum(43) + res[44] = fma52hi(res[44], a[18], a[25]); // Sum(43) + res[44] = fma52lo(res[44], a[19], a[25]); // Sum(44) + res[45] = fma52hi(res[45], a[19], a[25]); // Sum(44) + res[45] = fma52lo(res[45], a[20], a[25]); // Sum(45) + res[46] = fma52hi(res[46], a[20], a[25]); // Sum(45) + res[46] = fma52lo(res[46], a[21], a[25]); // Sum(46) + res[47] = fma52hi(res[47], a[21], a[25]); // Sum(46) + res[47] = fma52lo(res[47], a[22], a[25]); // Sum(47) + res[48] = fma52hi(res[48], a[22], a[25]); // Sum(47) + res[36] = fma52lo(res[36], a[10], a[26]); // Sum(36) + res[37] = fma52hi(res[37], a[10], a[26]); // Sum(36) + res[37] = fma52lo(res[37], a[11], a[26]); // Sum(37) + res[38] = fma52hi(res[38], a[11], a[26]); // Sum(37) + res[38] = fma52lo(res[38], a[12], a[26]); // Sum(38) + res[39] = fma52hi(res[39], a[12], a[26]); // Sum(38) + res[39] = fma52lo(res[39], a[13], a[26]); // Sum(39) + res[40] = fma52hi(res[40], a[13], a[26]); // Sum(39) + res[40] = fma52lo(res[40], a[14], a[26]); // Sum(40) + res[41] = fma52hi(res[41], a[14], a[26]); // Sum(40) + res[41] = fma52lo(res[41], a[15], a[26]); // Sum(41) + res[42] = fma52hi(res[42], a[15], a[26]); // Sum(41) + res[42] = fma52lo(res[42], a[16], a[26]); // Sum(42) + res[43] = fma52hi(res[43], a[16], a[26]); // Sum(42) + res[43] = fma52lo(res[43], a[17], a[26]); // Sum(43) + res[44] = fma52hi(res[44], a[17], a[26]); // Sum(43) + res[44] = fma52lo(res[44], a[18], a[26]); // Sum(44) + res[45] = fma52hi(res[45], a[18], a[26]); // Sum(44) + res[45] = fma52lo(res[45], a[19], a[26]); // Sum(45) + res[46] = fma52hi(res[46], a[19], a[26]); // Sum(45) + res[46] = fma52lo(res[46], a[20], a[26]); // Sum(46) + res[47] = fma52hi(res[47], a[20], a[26]); // Sum(46) + res[47] = fma52lo(res[47], a[21], a[26]); // Sum(47) + res[48] = fma52hi(res[48], a[21], a[26]); // Sum(47) + res[36] = fma52lo(res[36], a[9], a[27]); // Sum(36) + res[37] = fma52hi(res[37], a[9], a[27]); // Sum(36) + res[37] = fma52lo(res[37], a[10], a[27]); // Sum(37) + res[38] = fma52hi(res[38], a[10], a[27]); // Sum(37) + res[38] = fma52lo(res[38], a[11], a[27]); // Sum(38) + res[39] = fma52hi(res[39], a[11], a[27]); // Sum(38) + res[39] = fma52lo(res[39], a[12], a[27]); // Sum(39) + res[40] = fma52hi(res[40], a[12], a[27]); // Sum(39) + res[40] = fma52lo(res[40], a[13], a[27]); // Sum(40) + res[41] = fma52hi(res[41], a[13], a[27]); // Sum(40) + res[41] = fma52lo(res[41], a[14], a[27]); // Sum(41) + res[42] = fma52hi(res[42], a[14], a[27]); // Sum(41) + res[42] = fma52lo(res[42], a[15], a[27]); // Sum(42) + res[43] = fma52hi(res[43], a[15], a[27]); // Sum(42) + res[43] = fma52lo(res[43], a[16], a[27]); // Sum(43) + res[44] = fma52hi(res[44], a[16], a[27]); // Sum(43) + res[44] = fma52lo(res[44], a[17], a[27]); // Sum(44) + res[45] = fma52hi(res[45], a[17], a[27]); // Sum(44) + res[45] = fma52lo(res[45], a[18], a[27]); // Sum(45) + res[46] = fma52hi(res[46], a[18], a[27]); // Sum(45) + res[46] = fma52lo(res[46], a[19], a[27]); // Sum(46) + res[47] = fma52hi(res[47], a[19], a[27]); // Sum(46) + res[47] = fma52lo(res[47], a[20], a[27]); // Sum(47) + res[48] = fma52hi(res[48], a[20], a[27]); // Sum(47) + res[36] = fma52lo(res[36], a[8], a[28]); // Sum(36) + res[37] = fma52hi(res[37], a[8], a[28]); // Sum(36) + res[37] = fma52lo(res[37], a[9], a[28]); // Sum(37) + res[38] = fma52hi(res[38], a[9], a[28]); // Sum(37) + res[38] = fma52lo(res[38], a[10], a[28]); // Sum(38) + res[39] = fma52hi(res[39], a[10], a[28]); // Sum(38) + res[39] = fma52lo(res[39], a[11], a[28]); // Sum(39) + res[40] = fma52hi(res[40], a[11], a[28]); // Sum(39) + res[40] = fma52lo(res[40], a[12], a[28]); // Sum(40) + res[41] = fma52hi(res[41], a[12], a[28]); // Sum(40) + res[41] = fma52lo(res[41], a[13], a[28]); // Sum(41) + res[42] = fma52hi(res[42], a[13], a[28]); // Sum(41) + res[42] = fma52lo(res[42], a[14], a[28]); // Sum(42) + res[43] = fma52hi(res[43], a[14], a[28]); // Sum(42) + res[43] = fma52lo(res[43], a[15], a[28]); // Sum(43) + res[44] = fma52hi(res[44], a[15], a[28]); // Sum(43) + res[44] = fma52lo(res[44], a[16], a[28]); // Sum(44) + res[45] = fma52hi(res[45], a[16], a[28]); // Sum(44) + res[45] = fma52lo(res[45], a[17], a[28]); // Sum(45) + res[46] = fma52hi(res[46], a[17], a[28]); // Sum(45) + res[46] = fma52lo(res[46], a[18], a[28]); // Sum(46) + res[47] = fma52hi(res[47], a[18], a[28]); // Sum(46) + res[47] = fma52lo(res[47], a[19], a[28]); // Sum(47) + res[48] = fma52hi(res[48], a[19], a[28]); // Sum(47) + res[36] = fma52lo(res[36], a[7], a[29]); // Sum(36) + res[37] = fma52hi(res[37], a[7], a[29]); // Sum(36) + res[37] = fma52lo(res[37], a[8], a[29]); // Sum(37) + res[38] = fma52hi(res[38], a[8], a[29]); // Sum(37) + res[38] = fma52lo(res[38], a[9], a[29]); // Sum(38) + res[39] = fma52hi(res[39], a[9], a[29]); // Sum(38) + res[39] = fma52lo(res[39], a[10], a[29]); // Sum(39) + res[40] = fma52hi(res[40], a[10], a[29]); // Sum(39) + res[40] = fma52lo(res[40], a[11], a[29]); // Sum(40) + res[41] = fma52hi(res[41], a[11], a[29]); // Sum(40) + res[41] = fma52lo(res[41], a[12], a[29]); // Sum(41) + res[42] = fma52hi(res[42], a[12], a[29]); // Sum(41) + res[42] = fma52lo(res[42], a[13], a[29]); // Sum(42) + res[43] = fma52hi(res[43], a[13], a[29]); // Sum(42) + res[43] = fma52lo(res[43], a[14], a[29]); // Sum(43) + res[44] = fma52hi(res[44], a[14], a[29]); // Sum(43) + res[44] = fma52lo(res[44], a[15], a[29]); // Sum(44) + res[45] = fma52hi(res[45], a[15], a[29]); // Sum(44) + res[45] = fma52lo(res[45], a[16], a[29]); // Sum(45) + res[46] = fma52hi(res[46], a[16], a[29]); // Sum(45) + res[46] = fma52lo(res[46], a[17], a[29]); // Sum(46) + res[47] = fma52hi(res[47], a[17], a[29]); // Sum(46) + res[47] = fma52lo(res[47], a[18], a[29]); // Sum(47) + res[48] = fma52hi(res[48], a[18], a[29]); // Sum(47) + res[36] = fma52lo(res[36], a[6], a[30]); // Sum(36) + res[37] = fma52hi(res[37], a[6], a[30]); // Sum(36) + res[37] = fma52lo(res[37], a[7], a[30]); // Sum(37) + res[38] = fma52hi(res[38], a[7], a[30]); // Sum(37) + res[38] = fma52lo(res[38], a[8], a[30]); // Sum(38) + res[39] = fma52hi(res[39], a[8], a[30]); // Sum(38) + res[39] = fma52lo(res[39], a[9], a[30]); // Sum(39) + res[40] = fma52hi(res[40], a[9], a[30]); // Sum(39) + res[40] = fma52lo(res[40], a[10], a[30]); // Sum(40) + res[41] = fma52hi(res[41], a[10], a[30]); // Sum(40) + res[41] = fma52lo(res[41], a[11], a[30]); // Sum(41) + res[42] = fma52hi(res[42], a[11], a[30]); // Sum(41) + res[42] = fma52lo(res[42], a[12], a[30]); // Sum(42) + res[43] = fma52hi(res[43], a[12], a[30]); // Sum(42) + res[43] = fma52lo(res[43], a[13], a[30]); // Sum(43) + res[44] = fma52hi(res[44], a[13], a[30]); // Sum(43) + res[44] = fma52lo(res[44], a[14], a[30]); // Sum(44) + res[45] = fma52hi(res[45], a[14], a[30]); // Sum(44) + res[45] = fma52lo(res[45], a[15], a[30]); // Sum(45) + res[46] = fma52hi(res[46], a[15], a[30]); // Sum(45) + res[46] = fma52lo(res[46], a[16], a[30]); // Sum(46) + res[47] = fma52hi(res[47], a[16], a[30]); // Sum(46) + res[47] = fma52lo(res[47], a[17], a[30]); // Sum(47) + res[48] = fma52hi(res[48], a[17], a[30]); // Sum(47) + res[36] = fma52lo(res[36], a[5], a[31]); // Sum(36) + res[37] = fma52hi(res[37], a[5], a[31]); // Sum(36) + res[37] = fma52lo(res[37], a[6], a[31]); // Sum(37) + res[38] = fma52hi(res[38], a[6], a[31]); // Sum(37) + res[38] = fma52lo(res[38], a[7], a[31]); // Sum(38) + res[39] = fma52hi(res[39], a[7], a[31]); // Sum(38) + res[39] = fma52lo(res[39], a[8], a[31]); // Sum(39) + res[40] = fma52hi(res[40], a[8], a[31]); // Sum(39) + res[40] = fma52lo(res[40], a[9], a[31]); // Sum(40) + res[41] = fma52hi(res[41], a[9], a[31]); // Sum(40) + res[41] = fma52lo(res[41], a[10], a[31]); // Sum(41) + res[42] = fma52hi(res[42], a[10], a[31]); // Sum(41) + res[42] = fma52lo(res[42], a[11], a[31]); // Sum(42) + res[43] = fma52hi(res[43], a[11], a[31]); // Sum(42) + res[43] = fma52lo(res[43], a[12], a[31]); // Sum(43) + res[44] = fma52hi(res[44], a[12], a[31]); // Sum(43) + res[44] = fma52lo(res[44], a[13], a[31]); // Sum(44) + res[45] = fma52hi(res[45], a[13], a[31]); // Sum(44) + res[45] = fma52lo(res[45], a[14], a[31]); // Sum(45) + res[46] = fma52hi(res[46], a[14], a[31]); // Sum(45) + res[46] = fma52lo(res[46], a[15], a[31]); // Sum(46) + res[47] = fma52hi(res[47], a[15], a[31]); // Sum(46) + res[47] = fma52lo(res[47], a[16], a[31]); // Sum(47) + res[48] = fma52hi(res[48], a[16], a[31]); // Sum(47) + res[36] = fma52lo(res[36], a[4], a[32]); // Sum(36) + res[37] = fma52hi(res[37], a[4], a[32]); // Sum(36) + res[37] = fma52lo(res[37], a[5], a[32]); // Sum(37) + res[38] = fma52hi(res[38], a[5], a[32]); // Sum(37) + res[38] = fma52lo(res[38], a[6], a[32]); // Sum(38) + res[39] = fma52hi(res[39], a[6], a[32]); // Sum(38) + res[39] = fma52lo(res[39], a[7], a[32]); // Sum(39) + res[40] = fma52hi(res[40], a[7], a[32]); // Sum(39) + res[40] = fma52lo(res[40], a[8], a[32]); // Sum(40) + res[41] = fma52hi(res[41], a[8], a[32]); // Sum(40) + res[41] = fma52lo(res[41], a[9], a[32]); // Sum(41) + res[42] = fma52hi(res[42], a[9], a[32]); // Sum(41) + res[42] = fma52lo(res[42], a[10], a[32]); // Sum(42) + res[43] = fma52hi(res[43], a[10], a[32]); // Sum(42) + res[43] = fma52lo(res[43], a[11], a[32]); // Sum(43) + res[44] = fma52hi(res[44], a[11], a[32]); // Sum(43) + res[44] = fma52lo(res[44], a[12], a[32]); // Sum(44) + res[45] = fma52hi(res[45], a[12], a[32]); // Sum(44) + res[45] = fma52lo(res[45], a[13], a[32]); // Sum(45) + res[46] = fma52hi(res[46], a[13], a[32]); // Sum(45) + res[46] = fma52lo(res[46], a[14], a[32]); // Sum(46) + res[47] = fma52hi(res[47], a[14], a[32]); // Sum(46) + res[47] = fma52lo(res[47], a[15], a[32]); // Sum(47) + res[48] = fma52hi(res[48], a[15], a[32]); // Sum(47) + res[36] = fma52lo(res[36], a[3], a[33]); // Sum(36) + res[37] = fma52hi(res[37], a[3], a[33]); // Sum(36) + res[37] = fma52lo(res[37], a[4], a[33]); // Sum(37) + res[38] = fma52hi(res[38], a[4], a[33]); // Sum(37) + res[38] = fma52lo(res[38], a[5], a[33]); // Sum(38) + res[39] = fma52hi(res[39], a[5], a[33]); // Sum(38) + res[39] = fma52lo(res[39], a[6], a[33]); // Sum(39) + res[40] = fma52hi(res[40], a[6], a[33]); // Sum(39) + res[40] = fma52lo(res[40], a[7], a[33]); // Sum(40) + res[41] = fma52hi(res[41], a[7], a[33]); // Sum(40) + res[41] = fma52lo(res[41], a[8], a[33]); // Sum(41) + res[42] = fma52hi(res[42], a[8], a[33]); // Sum(41) + res[42] = fma52lo(res[42], a[9], a[33]); // Sum(42) + res[43] = fma52hi(res[43], a[9], a[33]); // Sum(42) + res[43] = fma52lo(res[43], a[10], a[33]); // Sum(43) + res[44] = fma52hi(res[44], a[10], a[33]); // Sum(43) + res[44] = fma52lo(res[44], a[11], a[33]); // Sum(44) + res[45] = fma52hi(res[45], a[11], a[33]); // Sum(44) + res[45] = fma52lo(res[45], a[12], a[33]); // Sum(45) + res[46] = fma52hi(res[46], a[12], a[33]); // Sum(45) + res[46] = fma52lo(res[46], a[13], a[33]); // Sum(46) + res[47] = fma52hi(res[47], a[13], a[33]); // Sum(46) + res[47] = fma52lo(res[47], a[14], a[33]); // Sum(47) + res[48] = fma52hi(res[48], a[14], a[33]); // Sum(47) + res[36] = fma52lo(res[36], a[2], a[34]); // Sum(36) + res[37] = fma52hi(res[37], a[2], a[34]); // Sum(36) + res[37] = fma52lo(res[37], a[3], a[34]); // Sum(37) + res[38] = fma52hi(res[38], a[3], a[34]); // Sum(37) + res[38] = fma52lo(res[38], a[4], a[34]); // Sum(38) + res[39] = fma52hi(res[39], a[4], a[34]); // Sum(38) + res[39] = fma52lo(res[39], a[5], a[34]); // Sum(39) + res[40] = fma52hi(res[40], a[5], a[34]); // Sum(39) + res[40] = fma52lo(res[40], a[6], a[34]); // Sum(40) + res[41] = fma52hi(res[41], a[6], a[34]); // Sum(40) + res[41] = fma52lo(res[41], a[7], a[34]); // Sum(41) + res[42] = fma52hi(res[42], a[7], a[34]); // Sum(41) + res[42] = fma52lo(res[42], a[8], a[34]); // Sum(42) + res[43] = fma52hi(res[43], a[8], a[34]); // Sum(42) + res[43] = fma52lo(res[43], a[9], a[34]); // Sum(43) + res[44] = fma52hi(res[44], a[9], a[34]); // Sum(43) + res[44] = fma52lo(res[44], a[10], a[34]); // Sum(44) + res[45] = fma52hi(res[45], a[10], a[34]); // Sum(44) + res[45] = fma52lo(res[45], a[11], a[34]); // Sum(45) + res[46] = fma52hi(res[46], a[11], a[34]); // Sum(45) + res[46] = fma52lo(res[46], a[12], a[34]); // Sum(46) + res[47] = fma52hi(res[47], a[12], a[34]); // Sum(46) + res[47] = fma52lo(res[47], a[13], a[34]); // Sum(47) + res[48] = fma52hi(res[48], a[13], a[34]); // Sum(47) + res[36] = fma52lo(res[36], a[1], a[35]); // Sum(36) + res[37] = fma52hi(res[37], a[1], a[35]); // Sum(36) + res[37] = fma52lo(res[37], a[2], a[35]); // Sum(37) + res[38] = fma52hi(res[38], a[2], a[35]); // Sum(37) + res[38] = fma52lo(res[38], a[3], a[35]); // Sum(38) + res[39] = fma52hi(res[39], a[3], a[35]); // Sum(38) + res[39] = fma52lo(res[39], a[4], a[35]); // Sum(39) + res[40] = fma52hi(res[40], a[4], a[35]); // Sum(39) + res[40] = fma52lo(res[40], a[5], a[35]); // Sum(40) + res[41] = fma52hi(res[41], a[5], a[35]); // Sum(40) + res[41] = fma52lo(res[41], a[6], a[35]); // Sum(41) + res[42] = fma52hi(res[42], a[6], a[35]); // Sum(41) + res[42] = fma52lo(res[42], a[7], a[35]); // Sum(42) + res[43] = fma52hi(res[43], a[7], a[35]); // Sum(42) + res[43] = fma52lo(res[43], a[8], a[35]); // Sum(43) + res[44] = fma52hi(res[44], a[8], a[35]); // Sum(43) + res[44] = fma52lo(res[44], a[9], a[35]); // Sum(44) + res[45] = fma52hi(res[45], a[9], a[35]); // Sum(44) + res[45] = fma52lo(res[45], a[10], a[35]); // Sum(45) + res[46] = fma52hi(res[46], a[10], a[35]); // Sum(45) + res[46] = fma52lo(res[46], a[11], a[35]); // Sum(46) + res[47] = fma52hi(res[47], a[11], a[35]); // Sum(46) + res[47] = fma52lo(res[47], a[12], a[35]); // Sum(47) + res[48] = fma52hi(res[48], a[12], a[35]); // Sum(47) + res[36] = fma52lo(res[36], a[0], a[36]); // Sum(36) + res[37] = fma52hi(res[37], a[0], a[36]); // Sum(36) + res[37] = fma52lo(res[37], a[1], a[36]); // Sum(37) + res[38] = fma52hi(res[38], a[1], a[36]); // Sum(37) + res[38] = fma52lo(res[38], a[2], a[36]); // Sum(38) + res[39] = fma52hi(res[39], a[2], a[36]); // Sum(38) + res[39] = fma52lo(res[39], a[3], a[36]); // Sum(39) + res[40] = fma52hi(res[40], a[3], a[36]); // Sum(39) + res[40] = fma52lo(res[40], a[4], a[36]); // Sum(40) + res[41] = fma52hi(res[41], a[4], a[36]); // Sum(40) + res[41] = fma52lo(res[41], a[5], a[36]); // Sum(41) + res[42] = fma52hi(res[42], a[5], a[36]); // Sum(41) + res[42] = fma52lo(res[42], a[6], a[36]); // Sum(42) + res[43] = fma52hi(res[43], a[6], a[36]); // Sum(42) + res[43] = fma52lo(res[43], a[7], a[36]); // Sum(43) + res[44] = fma52hi(res[44], a[7], a[36]); // Sum(43) + res[44] = fma52lo(res[44], a[8], a[36]); // Sum(44) + res[45] = fma52hi(res[45], a[8], a[36]); // Sum(44) + res[45] = fma52lo(res[45], a[9], a[36]); // Sum(45) + res[46] = fma52hi(res[46], a[9], a[36]); // Sum(45) + res[46] = fma52lo(res[46], a[10], a[36]); // Sum(46) + res[47] = fma52hi(res[47], a[10], a[36]); // Sum(46) + res[47] = fma52lo(res[47], a[11], a[36]); // Sum(47) + res[48] = fma52hi(res[48], a[11], a[36]); // Sum(47) + res[37] = fma52lo(res[37], a[0], a[37]); // Sum(37) + res[38] = fma52hi(res[38], a[0], a[37]); // Sum(37) + res[38] = fma52lo(res[38], a[1], a[37]); // Sum(38) + res[39] = fma52hi(res[39], a[1], a[37]); // Sum(38) + res[39] = fma52lo(res[39], a[2], a[37]); // Sum(39) + res[40] = fma52hi(res[40], a[2], a[37]); // Sum(39) + res[40] = fma52lo(res[40], a[3], a[37]); // Sum(40) + res[41] = fma52hi(res[41], a[3], a[37]); // Sum(40) + res[41] = fma52lo(res[41], a[4], a[37]); // Sum(41) + res[42] = fma52hi(res[42], a[4], a[37]); // Sum(41) + res[42] = fma52lo(res[42], a[5], a[37]); // Sum(42) + res[43] = fma52hi(res[43], a[5], a[37]); // Sum(42) + res[43] = fma52lo(res[43], a[6], a[37]); // Sum(43) + res[44] = fma52hi(res[44], a[6], a[37]); // Sum(43) + res[44] = fma52lo(res[44], a[7], a[37]); // Sum(44) + res[45] = fma52hi(res[45], a[7], a[37]); // Sum(44) + res[45] = fma52lo(res[45], a[8], a[37]); // Sum(45) + res[46] = fma52hi(res[46], a[8], a[37]); // Sum(45) + res[46] = fma52lo(res[46], a[9], a[37]); // Sum(46) + res[47] = fma52hi(res[47], a[9], a[37]); // Sum(46) + res[47] = fma52lo(res[47], a[10], a[37]); // Sum(47) + res[48] = fma52hi(res[48], a[10], a[37]); // Sum(47) + res[38] = fma52lo(res[38], a[0], a[38]); // Sum(38) + res[39] = fma52hi(res[39], a[0], a[38]); // Sum(38) + res[39] = fma52lo(res[39], a[1], a[38]); // Sum(39) + res[40] = fma52hi(res[40], a[1], a[38]); // Sum(39) + res[40] = fma52lo(res[40], a[2], a[38]); // Sum(40) + res[41] = fma52hi(res[41], a[2], a[38]); // Sum(40) + res[41] = fma52lo(res[41], a[3], a[38]); // Sum(41) + res[42] = fma52hi(res[42], a[3], a[38]); // Sum(41) + res[42] = fma52lo(res[42], a[4], a[38]); // Sum(42) + res[43] = fma52hi(res[43], a[4], a[38]); // Sum(42) + res[43] = fma52lo(res[43], a[5], a[38]); // Sum(43) + res[44] = fma52hi(res[44], a[5], a[38]); // Sum(43) + res[44] = fma52lo(res[44], a[6], a[38]); // Sum(44) + res[45] = fma52hi(res[45], a[6], a[38]); // Sum(44) + res[45] = fma52lo(res[45], a[7], a[38]); // Sum(45) + res[46] = fma52hi(res[46], a[7], a[38]); // Sum(45) + res[46] = fma52lo(res[46], a[8], a[38]); // Sum(46) + res[47] = fma52hi(res[47], a[8], a[38]); // Sum(46) + res[47] = fma52lo(res[47], a[9], a[38]); // Sum(47) + res[48] = fma52hi(res[48], a[9], a[38]); // Sum(47) + res[39] = fma52lo(res[39], a[0], a[39]); // Sum(39) + res[40] = fma52hi(res[40], a[0], a[39]); // Sum(39) + res[40] = fma52lo(res[40], a[1], a[39]); // Sum(40) + res[41] = fma52hi(res[41], a[1], a[39]); // Sum(40) + res[41] = fma52lo(res[41], a[2], a[39]); // Sum(41) + res[42] = fma52hi(res[42], a[2], a[39]); // Sum(41) + res[42] = fma52lo(res[42], a[3], a[39]); // Sum(42) + res[43] = fma52hi(res[43], a[3], a[39]); // Sum(42) + res[43] = fma52lo(res[43], a[4], a[39]); // Sum(43) + res[44] = fma52hi(res[44], a[4], a[39]); // Sum(43) + res[44] = fma52lo(res[44], a[5], a[39]); // Sum(44) + res[45] = fma52hi(res[45], a[5], a[39]); // Sum(44) + res[45] = fma52lo(res[45], a[6], a[39]); // Sum(45) + res[46] = fma52hi(res[46], a[6], a[39]); // Sum(45) + res[46] = fma52lo(res[46], a[7], a[39]); // Sum(46) + res[47] = fma52hi(res[47], a[7], a[39]); // Sum(46) + res[47] = fma52lo(res[47], a[8], a[39]); // Sum(47) + res[48] = fma52hi(res[48], a[8], a[39]); // Sum(47) + res[36] = add64(res[36], res[36]); // Double(36) + res[37] = add64(res[37], res[37]); // Double(37) + res[38] = add64(res[38], res[38]); // Double(38) + res[39] = add64(res[39], res[39]); // Double(39) + res[40] = add64(res[40], res[40]); // Double(40) + res[41] = add64(res[41], res[41]); // Double(41) + res[42] = add64(res[42], res[42]); // Double(42) + res[43] = add64(res[43], res[43]); // Double(43) + res[44] = add64(res[44], res[44]); // Double(44) + res[45] = add64(res[45], res[45]); // Double(45) + res[46] = add64(res[46], res[46]); // Double(46) + res[47] = add64(res[47], res[47]); // Double(47) + res[36] = fma52lo(res[36], a[18], a[18]); // Add sqr(36) + res[37] = fma52hi(res[37], a[18], a[18]); // Add sqr(36) + res[38] = fma52lo(res[38], a[19], a[19]); // Add sqr(38) + res[39] = fma52hi(res[39], a[19], a[19]); // Add sqr(38) + res[40] = fma52lo(res[40], a[20], a[20]); // Add sqr(40) + res[41] = fma52hi(res[41], a[20], a[20]); // Add sqr(40) + res[42] = fma52lo(res[42], a[21], a[21]); // Add sqr(42) + res[43] = fma52hi(res[43], a[21], a[21]); // Add sqr(42) + res[44] = fma52lo(res[44], a[22], a[22]); // Add sqr(44) + res[45] = fma52hi(res[45], a[22], a[22]); // Add sqr(44) + res[46] = fma52lo(res[46], a[23], a[23]); // Add sqr(46) + res[47] = fma52hi(res[47], a[23], a[23]); // Add sqr(46) + res[48] = fma52lo(res[48], a[23], a[25]); // Sum(48) + res[49] = fma52hi(res[49], a[23], a[25]); // Sum(48) + res[49] = fma52lo(res[49], a[24], a[25]); // Sum(49) + res[50] = fma52hi(res[50], a[24], a[25]); // Sum(49) + res[48] = fma52lo(res[48], a[22], a[26]); // Sum(48) + res[49] = fma52hi(res[49], a[22], a[26]); // Sum(48) + res[49] = fma52lo(res[49], a[23], a[26]); // Sum(49) + res[50] = fma52hi(res[50], a[23], a[26]); // Sum(49) + res[50] = fma52lo(res[50], a[24], a[26]); // Sum(50) + res[51] = fma52hi(res[51], a[24], a[26]); // Sum(50) + res[51] = fma52lo(res[51], a[25], a[26]); // Sum(51) + res[52] = fma52hi(res[52], a[25], a[26]); // Sum(51) + res[48] = fma52lo(res[48], a[21], a[27]); // Sum(48) + res[49] = fma52hi(res[49], a[21], a[27]); // Sum(48) + res[49] = fma52lo(res[49], a[22], a[27]); // Sum(49) + res[50] = fma52hi(res[50], a[22], a[27]); // Sum(49) + res[50] = fma52lo(res[50], a[23], a[27]); // Sum(50) + res[51] = fma52hi(res[51], a[23], a[27]); // Sum(50) + res[51] = fma52lo(res[51], a[24], a[27]); // Sum(51) + res[52] = fma52hi(res[52], a[24], a[27]); // Sum(51) + res[52] = fma52lo(res[52], a[25], a[27]); // Sum(52) + res[53] = fma52hi(res[53], a[25], a[27]); // Sum(52) + res[53] = fma52lo(res[53], a[26], a[27]); // Sum(53) + res[54] = fma52hi(res[54], a[26], a[27]); // Sum(53) + res[48] = fma52lo(res[48], a[20], a[28]); // Sum(48) + res[49] = fma52hi(res[49], a[20], a[28]); // Sum(48) + res[49] = fma52lo(res[49], a[21], a[28]); // Sum(49) + res[50] = fma52hi(res[50], a[21], a[28]); // Sum(49) + res[50] = fma52lo(res[50], a[22], a[28]); // Sum(50) + res[51] = fma52hi(res[51], a[22], a[28]); // Sum(50) + res[51] = fma52lo(res[51], a[23], a[28]); // Sum(51) + res[52] = fma52hi(res[52], a[23], a[28]); // Sum(51) + res[52] = fma52lo(res[52], a[24], a[28]); // Sum(52) + res[53] = fma52hi(res[53], a[24], a[28]); // Sum(52) + res[53] = fma52lo(res[53], a[25], a[28]); // Sum(53) + res[54] = fma52hi(res[54], a[25], a[28]); // Sum(53) + res[54] = fma52lo(res[54], a[26], a[28]); // Sum(54) + res[55] = fma52hi(res[55], a[26], a[28]); // Sum(54) + res[55] = fma52lo(res[55], a[27], a[28]); // Sum(55) + res[56] = fma52hi(res[56], a[27], a[28]); // Sum(55) + res[48] = fma52lo(res[48], a[19], a[29]); // Sum(48) + res[49] = fma52hi(res[49], a[19], a[29]); // Sum(48) + res[49] = fma52lo(res[49], a[20], a[29]); // Sum(49) + res[50] = fma52hi(res[50], a[20], a[29]); // Sum(49) + res[50] = fma52lo(res[50], a[21], a[29]); // Sum(50) + res[51] = fma52hi(res[51], a[21], a[29]); // Sum(50) + res[51] = fma52lo(res[51], a[22], a[29]); // Sum(51) + res[52] = fma52hi(res[52], a[22], a[29]); // Sum(51) + res[52] = fma52lo(res[52], a[23], a[29]); // Sum(52) + res[53] = fma52hi(res[53], a[23], a[29]); // Sum(52) + res[53] = fma52lo(res[53], a[24], a[29]); // Sum(53) + res[54] = fma52hi(res[54], a[24], a[29]); // Sum(53) + res[54] = fma52lo(res[54], a[25], a[29]); // Sum(54) + res[55] = fma52hi(res[55], a[25], a[29]); // Sum(54) + res[55] = fma52lo(res[55], a[26], a[29]); // Sum(55) + res[56] = fma52hi(res[56], a[26], a[29]); // Sum(55) + res[56] = fma52lo(res[56], a[27], a[29]); // Sum(56) + res[57] = fma52hi(res[57], a[27], a[29]); // Sum(56) + res[57] = fma52lo(res[57], a[28], a[29]); // Sum(57) + res[58] = fma52hi(res[58], a[28], a[29]); // Sum(57) + res[48] = fma52lo(res[48], a[18], a[30]); // Sum(48) + res[49] = fma52hi(res[49], a[18], a[30]); // Sum(48) + res[49] = fma52lo(res[49], a[19], a[30]); // Sum(49) + res[50] = fma52hi(res[50], a[19], a[30]); // Sum(49) + res[50] = fma52lo(res[50], a[20], a[30]); // Sum(50) + res[51] = fma52hi(res[51], a[20], a[30]); // Sum(50) + res[51] = fma52lo(res[51], a[21], a[30]); // Sum(51) + res[52] = fma52hi(res[52], a[21], a[30]); // Sum(51) + res[52] = fma52lo(res[52], a[22], a[30]); // Sum(52) + res[53] = fma52hi(res[53], a[22], a[30]); // Sum(52) + res[53] = fma52lo(res[53], a[23], a[30]); // Sum(53) + res[54] = fma52hi(res[54], a[23], a[30]); // Sum(53) + res[54] = fma52lo(res[54], a[24], a[30]); // Sum(54) + res[55] = fma52hi(res[55], a[24], a[30]); // Sum(54) + res[55] = fma52lo(res[55], a[25], a[30]); // Sum(55) + res[56] = fma52hi(res[56], a[25], a[30]); // Sum(55) + res[56] = fma52lo(res[56], a[26], a[30]); // Sum(56) + res[57] = fma52hi(res[57], a[26], a[30]); // Sum(56) + res[57] = fma52lo(res[57], a[27], a[30]); // Sum(57) + res[58] = fma52hi(res[58], a[27], a[30]); // Sum(57) + res[58] = fma52lo(res[58], a[28], a[30]); // Sum(58) + res[59] = fma52hi(res[59], a[28], a[30]); // Sum(58) + res[59] = fma52lo(res[59], a[29], a[30]); // Sum(59) + res[60] = fma52hi(res[60], a[29], a[30]); // Sum(59) + res[48] = fma52lo(res[48], a[17], a[31]); // Sum(48) + res[49] = fma52hi(res[49], a[17], a[31]); // Sum(48) + res[49] = fma52lo(res[49], a[18], a[31]); // Sum(49) + res[50] = fma52hi(res[50], a[18], a[31]); // Sum(49) + res[50] = fma52lo(res[50], a[19], a[31]); // Sum(50) + res[51] = fma52hi(res[51], a[19], a[31]); // Sum(50) + res[51] = fma52lo(res[51], a[20], a[31]); // Sum(51) + res[52] = fma52hi(res[52], a[20], a[31]); // Sum(51) + res[52] = fma52lo(res[52], a[21], a[31]); // Sum(52) + res[53] = fma52hi(res[53], a[21], a[31]); // Sum(52) + res[53] = fma52lo(res[53], a[22], a[31]); // Sum(53) + res[54] = fma52hi(res[54], a[22], a[31]); // Sum(53) + res[54] = fma52lo(res[54], a[23], a[31]); // Sum(54) + res[55] = fma52hi(res[55], a[23], a[31]); // Sum(54) + res[55] = fma52lo(res[55], a[24], a[31]); // Sum(55) + res[56] = fma52hi(res[56], a[24], a[31]); // Sum(55) + res[56] = fma52lo(res[56], a[25], a[31]); // Sum(56) + res[57] = fma52hi(res[57], a[25], a[31]); // Sum(56) + res[57] = fma52lo(res[57], a[26], a[31]); // Sum(57) + res[58] = fma52hi(res[58], a[26], a[31]); // Sum(57) + res[58] = fma52lo(res[58], a[27], a[31]); // Sum(58) + res[59] = fma52hi(res[59], a[27], a[31]); // Sum(58) + res[59] = fma52lo(res[59], a[28], a[31]); // Sum(59) + res[60] = fma52hi(res[60], a[28], a[31]); // Sum(59) + res[48] = fma52lo(res[48], a[16], a[32]); // Sum(48) + res[49] = fma52hi(res[49], a[16], a[32]); // Sum(48) + res[49] = fma52lo(res[49], a[17], a[32]); // Sum(49) + res[50] = fma52hi(res[50], a[17], a[32]); // Sum(49) + res[50] = fma52lo(res[50], a[18], a[32]); // Sum(50) + res[51] = fma52hi(res[51], a[18], a[32]); // Sum(50) + res[51] = fma52lo(res[51], a[19], a[32]); // Sum(51) + res[52] = fma52hi(res[52], a[19], a[32]); // Sum(51) + res[52] = fma52lo(res[52], a[20], a[32]); // Sum(52) + res[53] = fma52hi(res[53], a[20], a[32]); // Sum(52) + res[53] = fma52lo(res[53], a[21], a[32]); // Sum(53) + res[54] = fma52hi(res[54], a[21], a[32]); // Sum(53) + res[54] = fma52lo(res[54], a[22], a[32]); // Sum(54) + res[55] = fma52hi(res[55], a[22], a[32]); // Sum(54) + res[55] = fma52lo(res[55], a[23], a[32]); // Sum(55) + res[56] = fma52hi(res[56], a[23], a[32]); // Sum(55) + res[56] = fma52lo(res[56], a[24], a[32]); // Sum(56) + res[57] = fma52hi(res[57], a[24], a[32]); // Sum(56) + res[57] = fma52lo(res[57], a[25], a[32]); // Sum(57) + res[58] = fma52hi(res[58], a[25], a[32]); // Sum(57) + res[58] = fma52lo(res[58], a[26], a[32]); // Sum(58) + res[59] = fma52hi(res[59], a[26], a[32]); // Sum(58) + res[59] = fma52lo(res[59], a[27], a[32]); // Sum(59) + res[60] = fma52hi(res[60], a[27], a[32]); // Sum(59) + res[48] = fma52lo(res[48], a[15], a[33]); // Sum(48) + res[49] = fma52hi(res[49], a[15], a[33]); // Sum(48) + res[49] = fma52lo(res[49], a[16], a[33]); // Sum(49) + res[50] = fma52hi(res[50], a[16], a[33]); // Sum(49) + res[50] = fma52lo(res[50], a[17], a[33]); // Sum(50) + res[51] = fma52hi(res[51], a[17], a[33]); // Sum(50) + res[51] = fma52lo(res[51], a[18], a[33]); // Sum(51) + res[52] = fma52hi(res[52], a[18], a[33]); // Sum(51) + res[52] = fma52lo(res[52], a[19], a[33]); // Sum(52) + res[53] = fma52hi(res[53], a[19], a[33]); // Sum(52) + res[53] = fma52lo(res[53], a[20], a[33]); // Sum(53) + res[54] = fma52hi(res[54], a[20], a[33]); // Sum(53) + res[54] = fma52lo(res[54], a[21], a[33]); // Sum(54) + res[55] = fma52hi(res[55], a[21], a[33]); // Sum(54) + res[55] = fma52lo(res[55], a[22], a[33]); // Sum(55) + res[56] = fma52hi(res[56], a[22], a[33]); // Sum(55) + res[56] = fma52lo(res[56], a[23], a[33]); // Sum(56) + res[57] = fma52hi(res[57], a[23], a[33]); // Sum(56) + res[57] = fma52lo(res[57], a[24], a[33]); // Sum(57) + res[58] = fma52hi(res[58], a[24], a[33]); // Sum(57) + res[58] = fma52lo(res[58], a[25], a[33]); // Sum(58) + res[59] = fma52hi(res[59], a[25], a[33]); // Sum(58) + res[59] = fma52lo(res[59], a[26], a[33]); // Sum(59) + res[60] = fma52hi(res[60], a[26], a[33]); // Sum(59) + res[48] = fma52lo(res[48], a[14], a[34]); // Sum(48) + res[49] = fma52hi(res[49], a[14], a[34]); // Sum(48) + res[49] = fma52lo(res[49], a[15], a[34]); // Sum(49) + res[50] = fma52hi(res[50], a[15], a[34]); // Sum(49) + res[50] = fma52lo(res[50], a[16], a[34]); // Sum(50) + res[51] = fma52hi(res[51], a[16], a[34]); // Sum(50) + res[51] = fma52lo(res[51], a[17], a[34]); // Sum(51) + res[52] = fma52hi(res[52], a[17], a[34]); // Sum(51) + res[52] = fma52lo(res[52], a[18], a[34]); // Sum(52) + res[53] = fma52hi(res[53], a[18], a[34]); // Sum(52) + res[53] = fma52lo(res[53], a[19], a[34]); // Sum(53) + res[54] = fma52hi(res[54], a[19], a[34]); // Sum(53) + res[54] = fma52lo(res[54], a[20], a[34]); // Sum(54) + res[55] = fma52hi(res[55], a[20], a[34]); // Sum(54) + res[55] = fma52lo(res[55], a[21], a[34]); // Sum(55) + res[56] = fma52hi(res[56], a[21], a[34]); // Sum(55) + res[56] = fma52lo(res[56], a[22], a[34]); // Sum(56) + res[57] = fma52hi(res[57], a[22], a[34]); // Sum(56) + res[57] = fma52lo(res[57], a[23], a[34]); // Sum(57) + res[58] = fma52hi(res[58], a[23], a[34]); // Sum(57) + res[58] = fma52lo(res[58], a[24], a[34]); // Sum(58) + res[59] = fma52hi(res[59], a[24], a[34]); // Sum(58) + res[59] = fma52lo(res[59], a[25], a[34]); // Sum(59) + res[60] = fma52hi(res[60], a[25], a[34]); // Sum(59) + res[48] = fma52lo(res[48], a[13], a[35]); // Sum(48) + res[49] = fma52hi(res[49], a[13], a[35]); // Sum(48) + res[49] = fma52lo(res[49], a[14], a[35]); // Sum(49) + res[50] = fma52hi(res[50], a[14], a[35]); // Sum(49) + res[50] = fma52lo(res[50], a[15], a[35]); // Sum(50) + res[51] = fma52hi(res[51], a[15], a[35]); // Sum(50) + res[51] = fma52lo(res[51], a[16], a[35]); // Sum(51) + res[52] = fma52hi(res[52], a[16], a[35]); // Sum(51) + res[52] = fma52lo(res[52], a[17], a[35]); // Sum(52) + res[53] = fma52hi(res[53], a[17], a[35]); // Sum(52) + res[53] = fma52lo(res[53], a[18], a[35]); // Sum(53) + res[54] = fma52hi(res[54], a[18], a[35]); // Sum(53) + res[54] = fma52lo(res[54], a[19], a[35]); // Sum(54) + res[55] = fma52hi(res[55], a[19], a[35]); // Sum(54) + res[55] = fma52lo(res[55], a[20], a[35]); // Sum(55) + res[56] = fma52hi(res[56], a[20], a[35]); // Sum(55) + res[56] = fma52lo(res[56], a[21], a[35]); // Sum(56) + res[57] = fma52hi(res[57], a[21], a[35]); // Sum(56) + res[57] = fma52lo(res[57], a[22], a[35]); // Sum(57) + res[58] = fma52hi(res[58], a[22], a[35]); // Sum(57) + res[58] = fma52lo(res[58], a[23], a[35]); // Sum(58) + res[59] = fma52hi(res[59], a[23], a[35]); // Sum(58) + res[59] = fma52lo(res[59], a[24], a[35]); // Sum(59) + res[60] = fma52hi(res[60], a[24], a[35]); // Sum(59) + res[48] = fma52lo(res[48], a[12], a[36]); // Sum(48) + res[49] = fma52hi(res[49], a[12], a[36]); // Sum(48) + res[49] = fma52lo(res[49], a[13], a[36]); // Sum(49) + res[50] = fma52hi(res[50], a[13], a[36]); // Sum(49) + res[50] = fma52lo(res[50], a[14], a[36]); // Sum(50) + res[51] = fma52hi(res[51], a[14], a[36]); // Sum(50) + res[51] = fma52lo(res[51], a[15], a[36]); // Sum(51) + res[52] = fma52hi(res[52], a[15], a[36]); // Sum(51) + res[52] = fma52lo(res[52], a[16], a[36]); // Sum(52) + res[53] = fma52hi(res[53], a[16], a[36]); // Sum(52) + res[53] = fma52lo(res[53], a[17], a[36]); // Sum(53) + res[54] = fma52hi(res[54], a[17], a[36]); // Sum(53) + res[54] = fma52lo(res[54], a[18], a[36]); // Sum(54) + res[55] = fma52hi(res[55], a[18], a[36]); // Sum(54) + res[55] = fma52lo(res[55], a[19], a[36]); // Sum(55) + res[56] = fma52hi(res[56], a[19], a[36]); // Sum(55) + res[56] = fma52lo(res[56], a[20], a[36]); // Sum(56) + res[57] = fma52hi(res[57], a[20], a[36]); // Sum(56) + res[57] = fma52lo(res[57], a[21], a[36]); // Sum(57) + res[58] = fma52hi(res[58], a[21], a[36]); // Sum(57) + res[58] = fma52lo(res[58], a[22], a[36]); // Sum(58) + res[59] = fma52hi(res[59], a[22], a[36]); // Sum(58) + res[59] = fma52lo(res[59], a[23], a[36]); // Sum(59) + res[60] = fma52hi(res[60], a[23], a[36]); // Sum(59) + res[48] = fma52lo(res[48], a[11], a[37]); // Sum(48) + res[49] = fma52hi(res[49], a[11], a[37]); // Sum(48) + res[49] = fma52lo(res[49], a[12], a[37]); // Sum(49) + res[50] = fma52hi(res[50], a[12], a[37]); // Sum(49) + res[50] = fma52lo(res[50], a[13], a[37]); // Sum(50) + res[51] = fma52hi(res[51], a[13], a[37]); // Sum(50) + res[51] = fma52lo(res[51], a[14], a[37]); // Sum(51) + res[52] = fma52hi(res[52], a[14], a[37]); // Sum(51) + res[52] = fma52lo(res[52], a[15], a[37]); // Sum(52) + res[53] = fma52hi(res[53], a[15], a[37]); // Sum(52) + res[53] = fma52lo(res[53], a[16], a[37]); // Sum(53) + res[54] = fma52hi(res[54], a[16], a[37]); // Sum(53) + res[54] = fma52lo(res[54], a[17], a[37]); // Sum(54) + res[55] = fma52hi(res[55], a[17], a[37]); // Sum(54) + res[55] = fma52lo(res[55], a[18], a[37]); // Sum(55) + res[56] = fma52hi(res[56], a[18], a[37]); // Sum(55) + res[56] = fma52lo(res[56], a[19], a[37]); // Sum(56) + res[57] = fma52hi(res[57], a[19], a[37]); // Sum(56) + res[57] = fma52lo(res[57], a[20], a[37]); // Sum(57) + res[58] = fma52hi(res[58], a[20], a[37]); // Sum(57) + res[58] = fma52lo(res[58], a[21], a[37]); // Sum(58) + res[59] = fma52hi(res[59], a[21], a[37]); // Sum(58) + res[59] = fma52lo(res[59], a[22], a[37]); // Sum(59) + res[60] = fma52hi(res[60], a[22], a[37]); // Sum(59) + res[48] = fma52lo(res[48], a[10], a[38]); // Sum(48) + res[49] = fma52hi(res[49], a[10], a[38]); // Sum(48) + res[49] = fma52lo(res[49], a[11], a[38]); // Sum(49) + res[50] = fma52hi(res[50], a[11], a[38]); // Sum(49) + res[50] = fma52lo(res[50], a[12], a[38]); // Sum(50) + res[51] = fma52hi(res[51], a[12], a[38]); // Sum(50) + res[51] = fma52lo(res[51], a[13], a[38]); // Sum(51) + res[52] = fma52hi(res[52], a[13], a[38]); // Sum(51) + res[52] = fma52lo(res[52], a[14], a[38]); // Sum(52) + res[53] = fma52hi(res[53], a[14], a[38]); // Sum(52) + res[53] = fma52lo(res[53], a[15], a[38]); // Sum(53) + res[54] = fma52hi(res[54], a[15], a[38]); // Sum(53) + res[54] = fma52lo(res[54], a[16], a[38]); // Sum(54) + res[55] = fma52hi(res[55], a[16], a[38]); // Sum(54) + res[55] = fma52lo(res[55], a[17], a[38]); // Sum(55) + res[56] = fma52hi(res[56], a[17], a[38]); // Sum(55) + res[56] = fma52lo(res[56], a[18], a[38]); // Sum(56) + res[57] = fma52hi(res[57], a[18], a[38]); // Sum(56) + res[57] = fma52lo(res[57], a[19], a[38]); // Sum(57) + res[58] = fma52hi(res[58], a[19], a[38]); // Sum(57) + res[58] = fma52lo(res[58], a[20], a[38]); // Sum(58) + res[59] = fma52hi(res[59], a[20], a[38]); // Sum(58) + res[59] = fma52lo(res[59], a[21], a[38]); // Sum(59) + res[60] = fma52hi(res[60], a[21], a[38]); // Sum(59) + res[48] = fma52lo(res[48], a[9], a[39]); // Sum(48) + res[49] = fma52hi(res[49], a[9], a[39]); // Sum(48) + res[49] = fma52lo(res[49], a[10], a[39]); // Sum(49) + res[50] = fma52hi(res[50], a[10], a[39]); // Sum(49) + res[50] = fma52lo(res[50], a[11], a[39]); // Sum(50) + res[51] = fma52hi(res[51], a[11], a[39]); // Sum(50) + res[51] = fma52lo(res[51], a[12], a[39]); // Sum(51) + res[52] = fma52hi(res[52], a[12], a[39]); // Sum(51) + res[52] = fma52lo(res[52], a[13], a[39]); // Sum(52) + res[53] = fma52hi(res[53], a[13], a[39]); // Sum(52) + res[53] = fma52lo(res[53], a[14], a[39]); // Sum(53) + res[54] = fma52hi(res[54], a[14], a[39]); // Sum(53) + res[54] = fma52lo(res[54], a[15], a[39]); // Sum(54) + res[55] = fma52hi(res[55], a[15], a[39]); // Sum(54) + res[55] = fma52lo(res[55], a[16], a[39]); // Sum(55) + res[56] = fma52hi(res[56], a[16], a[39]); // Sum(55) + res[56] = fma52lo(res[56], a[17], a[39]); // Sum(56) + res[57] = fma52hi(res[57], a[17], a[39]); // Sum(56) + res[57] = fma52lo(res[57], a[18], a[39]); // Sum(57) + res[58] = fma52hi(res[58], a[18], a[39]); // Sum(57) + res[58] = fma52lo(res[58], a[19], a[39]); // Sum(58) + res[59] = fma52hi(res[59], a[19], a[39]); // Sum(58) + res[59] = fma52lo(res[59], a[20], a[39]); // Sum(59) + res[60] = fma52hi(res[60], a[20], a[39]); // Sum(59) + res[48] = add64(res[48], res[48]); // Double(48) + res[49] = add64(res[49], res[49]); // Double(49) + res[50] = add64(res[50], res[50]); // Double(50) + res[51] = add64(res[51], res[51]); // Double(51) + res[52] = add64(res[52], res[52]); // Double(52) + res[53] = add64(res[53], res[53]); // Double(53) + res[54] = add64(res[54], res[54]); // Double(54) + res[55] = add64(res[55], res[55]); // Double(55) + res[56] = add64(res[56], res[56]); // Double(56) + res[57] = add64(res[57], res[57]); // Double(57) + res[58] = add64(res[58], res[58]); // Double(58) + res[59] = add64(res[59], res[59]); // Double(59) + res[48] = fma52lo(res[48], a[24], a[24]); // Add sqr(48) + res[49] = fma52hi(res[49], a[24], a[24]); // Add sqr(48) + res[50] = fma52lo(res[50], a[25], a[25]); // Add sqr(50) + res[51] = fma52hi(res[51], a[25], a[25]); // Add sqr(50) + res[52] = fma52lo(res[52], a[26], a[26]); // Add sqr(52) + res[53] = fma52hi(res[53], a[26], a[26]); // Add sqr(52) + res[54] = fma52lo(res[54], a[27], a[27]); // Add sqr(54) + res[55] = fma52hi(res[55], a[27], a[27]); // Add sqr(54) + res[56] = fma52lo(res[56], a[28], a[28]); // Add sqr(56) + res[57] = fma52hi(res[57], a[28], a[28]); // Add sqr(56) + res[58] = fma52lo(res[58], a[29], a[29]); // Add sqr(58) + res[59] = fma52hi(res[59], a[29], a[29]); // Add sqr(58) + res[60] = fma52lo(res[60], a[29], a[31]); // Sum(60) + res[61] = fma52hi(res[61], a[29], a[31]); // Sum(60) + res[61] = fma52lo(res[61], a[30], a[31]); // Sum(61) + res[62] = fma52hi(res[62], a[30], a[31]); // Sum(61) + res[60] = fma52lo(res[60], a[28], a[32]); // Sum(60) + res[61] = fma52hi(res[61], a[28], a[32]); // Sum(60) + res[61] = fma52lo(res[61], a[29], a[32]); // Sum(61) + res[62] = fma52hi(res[62], a[29], a[32]); // Sum(61) + res[62] = fma52lo(res[62], a[30], a[32]); // Sum(62) + res[63] = fma52hi(res[63], a[30], a[32]); // Sum(62) + res[63] = fma52lo(res[63], a[31], a[32]); // Sum(63) + res[64] = fma52hi(res[64], a[31], a[32]); // Sum(63) + res[60] = fma52lo(res[60], a[27], a[33]); // Sum(60) + res[61] = fma52hi(res[61], a[27], a[33]); // Sum(60) + res[61] = fma52lo(res[61], a[28], a[33]); // Sum(61) + res[62] = fma52hi(res[62], a[28], a[33]); // Sum(61) + res[62] = fma52lo(res[62], a[29], a[33]); // Sum(62) + res[63] = fma52hi(res[63], a[29], a[33]); // Sum(62) + res[63] = fma52lo(res[63], a[30], a[33]); // Sum(63) + res[64] = fma52hi(res[64], a[30], a[33]); // Sum(63) + res[64] = fma52lo(res[64], a[31], a[33]); // Sum(64) + res[65] = fma52hi(res[65], a[31], a[33]); // Sum(64) + res[65] = fma52lo(res[65], a[32], a[33]); // Sum(65) + res[66] = fma52hi(res[66], a[32], a[33]); // Sum(65) + res[60] = fma52lo(res[60], a[26], a[34]); // Sum(60) + res[61] = fma52hi(res[61], a[26], a[34]); // Sum(60) + res[61] = fma52lo(res[61], a[27], a[34]); // Sum(61) + res[62] = fma52hi(res[62], a[27], a[34]); // Sum(61) + res[62] = fma52lo(res[62], a[28], a[34]); // Sum(62) + res[63] = fma52hi(res[63], a[28], a[34]); // Sum(62) + res[63] = fma52lo(res[63], a[29], a[34]); // Sum(63) + res[64] = fma52hi(res[64], a[29], a[34]); // Sum(63) + res[64] = fma52lo(res[64], a[30], a[34]); // Sum(64) + res[65] = fma52hi(res[65], a[30], a[34]); // Sum(64) + res[65] = fma52lo(res[65], a[31], a[34]); // Sum(65) + res[66] = fma52hi(res[66], a[31], a[34]); // Sum(65) + res[66] = fma52lo(res[66], a[32], a[34]); // Sum(66) + res[67] = fma52hi(res[67], a[32], a[34]); // Sum(66) + res[67] = fma52lo(res[67], a[33], a[34]); // Sum(67) + res[68] = fma52hi(res[68], a[33], a[34]); // Sum(67) + res[60] = fma52lo(res[60], a[25], a[35]); // Sum(60) + res[61] = fma52hi(res[61], a[25], a[35]); // Sum(60) + res[61] = fma52lo(res[61], a[26], a[35]); // Sum(61) + res[62] = fma52hi(res[62], a[26], a[35]); // Sum(61) + res[62] = fma52lo(res[62], a[27], a[35]); // Sum(62) + res[63] = fma52hi(res[63], a[27], a[35]); // Sum(62) + res[63] = fma52lo(res[63], a[28], a[35]); // Sum(63) + res[64] = fma52hi(res[64], a[28], a[35]); // Sum(63) + res[64] = fma52lo(res[64], a[29], a[35]); // Sum(64) + res[65] = fma52hi(res[65], a[29], a[35]); // Sum(64) + res[65] = fma52lo(res[65], a[30], a[35]); // Sum(65) + res[66] = fma52hi(res[66], a[30], a[35]); // Sum(65) + res[66] = fma52lo(res[66], a[31], a[35]); // Sum(66) + res[67] = fma52hi(res[67], a[31], a[35]); // Sum(66) + res[67] = fma52lo(res[67], a[32], a[35]); // Sum(67) + res[68] = fma52hi(res[68], a[32], a[35]); // Sum(67) + res[68] = fma52lo(res[68], a[33], a[35]); // Sum(68) + res[69] = fma52hi(res[69], a[33], a[35]); // Sum(68) + res[69] = fma52lo(res[69], a[34], a[35]); // Sum(69) + res[70] = fma52hi(res[70], a[34], a[35]); // Sum(69) + res[60] = fma52lo(res[60], a[24], a[36]); // Sum(60) + res[61] = fma52hi(res[61], a[24], a[36]); // Sum(60) + res[61] = fma52lo(res[61], a[25], a[36]); // Sum(61) + res[62] = fma52hi(res[62], a[25], a[36]); // Sum(61) + res[62] = fma52lo(res[62], a[26], a[36]); // Sum(62) + res[63] = fma52hi(res[63], a[26], a[36]); // Sum(62) + res[63] = fma52lo(res[63], a[27], a[36]); // Sum(63) + res[64] = fma52hi(res[64], a[27], a[36]); // Sum(63) + res[64] = fma52lo(res[64], a[28], a[36]); // Sum(64) + res[65] = fma52hi(res[65], a[28], a[36]); // Sum(64) + res[65] = fma52lo(res[65], a[29], a[36]); // Sum(65) + res[66] = fma52hi(res[66], a[29], a[36]); // Sum(65) + res[66] = fma52lo(res[66], a[30], a[36]); // Sum(66) + res[67] = fma52hi(res[67], a[30], a[36]); // Sum(66) + res[67] = fma52lo(res[67], a[31], a[36]); // Sum(67) + res[68] = fma52hi(res[68], a[31], a[36]); // Sum(67) + res[68] = fma52lo(res[68], a[32], a[36]); // Sum(68) + res[69] = fma52hi(res[69], a[32], a[36]); // Sum(68) + res[69] = fma52lo(res[69], a[33], a[36]); // Sum(69) + res[70] = fma52hi(res[70], a[33], a[36]); // Sum(69) + res[70] = fma52lo(res[70], a[34], a[36]); // Sum(70) + res[71] = fma52hi(res[71], a[34], a[36]); // Sum(70) + res[71] = fma52lo(res[71], a[35], a[36]); // Sum(71) + res[72] = fma52hi(res[72], a[35], a[36]); // Sum(71) + res[60] = fma52lo(res[60], a[23], a[37]); // Sum(60) + res[61] = fma52hi(res[61], a[23], a[37]); // Sum(60) + res[61] = fma52lo(res[61], a[24], a[37]); // Sum(61) + res[62] = fma52hi(res[62], a[24], a[37]); // Sum(61) + res[62] = fma52lo(res[62], a[25], a[37]); // Sum(62) + res[63] = fma52hi(res[63], a[25], a[37]); // Sum(62) + res[63] = fma52lo(res[63], a[26], a[37]); // Sum(63) + res[64] = fma52hi(res[64], a[26], a[37]); // Sum(63) + res[64] = fma52lo(res[64], a[27], a[37]); // Sum(64) + res[65] = fma52hi(res[65], a[27], a[37]); // Sum(64) + res[65] = fma52lo(res[65], a[28], a[37]); // Sum(65) + res[66] = fma52hi(res[66], a[28], a[37]); // Sum(65) + res[66] = fma52lo(res[66], a[29], a[37]); // Sum(66) + res[67] = fma52hi(res[67], a[29], a[37]); // Sum(66) + res[67] = fma52lo(res[67], a[30], a[37]); // Sum(67) + res[68] = fma52hi(res[68], a[30], a[37]); // Sum(67) + res[68] = fma52lo(res[68], a[31], a[37]); // Sum(68) + res[69] = fma52hi(res[69], a[31], a[37]); // Sum(68) + res[69] = fma52lo(res[69], a[32], a[37]); // Sum(69) + res[70] = fma52hi(res[70], a[32], a[37]); // Sum(69) + res[70] = fma52lo(res[70], a[33], a[37]); // Sum(70) + res[71] = fma52hi(res[71], a[33], a[37]); // Sum(70) + res[71] = fma52lo(res[71], a[34], a[37]); // Sum(71) + res[72] = fma52hi(res[72], a[34], a[37]); // Sum(71) + res[60] = fma52lo(res[60], a[22], a[38]); // Sum(60) + res[61] = fma52hi(res[61], a[22], a[38]); // Sum(60) + res[61] = fma52lo(res[61], a[23], a[38]); // Sum(61) + res[62] = fma52hi(res[62], a[23], a[38]); // Sum(61) + res[62] = fma52lo(res[62], a[24], a[38]); // Sum(62) + res[63] = fma52hi(res[63], a[24], a[38]); // Sum(62) + res[63] = fma52lo(res[63], a[25], a[38]); // Sum(63) + res[64] = fma52hi(res[64], a[25], a[38]); // Sum(63) + res[64] = fma52lo(res[64], a[26], a[38]); // Sum(64) + res[65] = fma52hi(res[65], a[26], a[38]); // Sum(64) + res[65] = fma52lo(res[65], a[27], a[38]); // Sum(65) + res[66] = fma52hi(res[66], a[27], a[38]); // Sum(65) + res[66] = fma52lo(res[66], a[28], a[38]); // Sum(66) + res[67] = fma52hi(res[67], a[28], a[38]); // Sum(66) + res[67] = fma52lo(res[67], a[29], a[38]); // Sum(67) + res[68] = fma52hi(res[68], a[29], a[38]); // Sum(67) + res[68] = fma52lo(res[68], a[30], a[38]); // Sum(68) + res[69] = fma52hi(res[69], a[30], a[38]); // Sum(68) + res[69] = fma52lo(res[69], a[31], a[38]); // Sum(69) + res[70] = fma52hi(res[70], a[31], a[38]); // Sum(69) + res[70] = fma52lo(res[70], a[32], a[38]); // Sum(70) + res[71] = fma52hi(res[71], a[32], a[38]); // Sum(70) + res[71] = fma52lo(res[71], a[33], a[38]); // Sum(71) + res[72] = fma52hi(res[72], a[33], a[38]); // Sum(71) + res[60] = fma52lo(res[60], a[21], a[39]); // Sum(60) + res[61] = fma52hi(res[61], a[21], a[39]); // Sum(60) + res[61] = fma52lo(res[61], a[22], a[39]); // Sum(61) + res[62] = fma52hi(res[62], a[22], a[39]); // Sum(61) + res[62] = fma52lo(res[62], a[23], a[39]); // Sum(62) + res[63] = fma52hi(res[63], a[23], a[39]); // Sum(62) + res[63] = fma52lo(res[63], a[24], a[39]); // Sum(63) + res[64] = fma52hi(res[64], a[24], a[39]); // Sum(63) + res[64] = fma52lo(res[64], a[25], a[39]); // Sum(64) + res[65] = fma52hi(res[65], a[25], a[39]); // Sum(64) + res[65] = fma52lo(res[65], a[26], a[39]); // Sum(65) + res[66] = fma52hi(res[66], a[26], a[39]); // Sum(65) + res[66] = fma52lo(res[66], a[27], a[39]); // Sum(66) + res[67] = fma52hi(res[67], a[27], a[39]); // Sum(66) + res[67] = fma52lo(res[67], a[28], a[39]); // Sum(67) + res[68] = fma52hi(res[68], a[28], a[39]); // Sum(67) + res[68] = fma52lo(res[68], a[29], a[39]); // Sum(68) + res[69] = fma52hi(res[69], a[29], a[39]); // Sum(68) + res[69] = fma52lo(res[69], a[30], a[39]); // Sum(69) + res[70] = fma52hi(res[70], a[30], a[39]); // Sum(69) + res[70] = fma52lo(res[70], a[31], a[39]); // Sum(70) + res[71] = fma52hi(res[71], a[31], a[39]); // Sum(70) + res[71] = fma52lo(res[71], a[32], a[39]); // Sum(71) + res[72] = fma52hi(res[72], a[32], a[39]); // Sum(71) + res[60] = add64(res[60], res[60]); // Double(60) + res[61] = add64(res[61], res[61]); // Double(61) + res[62] = add64(res[62], res[62]); // Double(62) + res[63] = add64(res[63], res[63]); // Double(63) + res[64] = add64(res[64], res[64]); // Double(64) + res[65] = add64(res[65], res[65]); // Double(65) + res[66] = add64(res[66], res[66]); // Double(66) + res[67] = add64(res[67], res[67]); // Double(67) + res[68] = add64(res[68], res[68]); // Double(68) + res[69] = add64(res[69], res[69]); // Double(69) + res[70] = add64(res[70], res[70]); // Double(70) + res[71] = add64(res[71], res[71]); // Double(71) + res[60] = fma52lo(res[60], a[30], a[30]); // Add sqr(60) + res[61] = fma52hi(res[61], a[30], a[30]); // Add sqr(60) + res[62] = fma52lo(res[62], a[31], a[31]); // Add sqr(62) + res[63] = fma52hi(res[63], a[31], a[31]); // Add sqr(62) + res[64] = fma52lo(res[64], a[32], a[32]); // Add sqr(64) + res[65] = fma52hi(res[65], a[32], a[32]); // Add sqr(64) + res[66] = fma52lo(res[66], a[33], a[33]); // Add sqr(66) + res[67] = fma52hi(res[67], a[33], a[33]); // Add sqr(66) + res[68] = fma52lo(res[68], a[34], a[34]); // Add sqr(68) + res[69] = fma52hi(res[69], a[34], a[34]); // Add sqr(68) + res[70] = fma52lo(res[70], a[35], a[35]); // Add sqr(70) + res[71] = fma52hi(res[71], a[35], a[35]); // Add sqr(70) + res[72] = fma52lo(res[72], a[35], a[37]); // Sum(72) + res[73] = fma52hi(res[73], a[35], a[37]); // Sum(72) + res[73] = fma52lo(res[73], a[36], a[37]); // Sum(73) + res[74] = fma52hi(res[74], a[36], a[37]); // Sum(73) + res[72] = fma52lo(res[72], a[34], a[38]); // Sum(72) + res[73] = fma52hi(res[73], a[34], a[38]); // Sum(72) + res[73] = fma52lo(res[73], a[35], a[38]); // Sum(73) + res[74] = fma52hi(res[74], a[35], a[38]); // Sum(73) + res[74] = fma52lo(res[74], a[36], a[38]); // Sum(74) + res[75] = fma52hi(res[75], a[36], a[38]); // Sum(74) + res[75] = fma52lo(res[75], a[37], a[38]); // Sum(75) + res[76] = fma52hi(res[76], a[37], a[38]); // Sum(75) + res[72] = fma52lo(res[72], a[33], a[39]); // Sum(72) + res[73] = fma52hi(res[73], a[33], a[39]); // Sum(72) + res[73] = fma52lo(res[73], a[34], a[39]); // Sum(73) + res[74] = fma52hi(res[74], a[34], a[39]); // Sum(73) + res[74] = fma52lo(res[74], a[35], a[39]); // Sum(74) + res[75] = fma52hi(res[75], a[35], a[39]); // Sum(74) + res[75] = fma52lo(res[75], a[36], a[39]); // Sum(75) + res[76] = fma52hi(res[76], a[36], a[39]); // Sum(75) + res[76] = fma52lo(res[76], a[37], a[39]); // Sum(76) + res[77] = fma52hi(res[77], a[37], a[39]); // Sum(76) + res[77] = fma52lo(res[77], a[38], a[39]); // Sum(77) + res[78] = fma52hi(res[78], a[38], a[39]); // Sum(77) + res[72] = add64(res[72], res[72]); // Double(72) + res[73] = add64(res[73], res[73]); // Double(73) + res[74] = add64(res[74], res[74]); // Double(74) + res[75] = add64(res[75], res[75]); // Double(75) + res[76] = add64(res[76], res[76]); // Double(76) + res[77] = add64(res[77], res[77]); // Double(77) + res[78] = add64(res[78], res[78]); // Double(78) + res[72] = fma52lo(res[72], a[36], a[36]); // Add sqr(72) + res[73] = fma52hi(res[73], a[36], a[36]); // Add sqr(72) + res[74] = fma52lo(res[74], a[37], a[37]); // Add sqr(74) + res[75] = fma52hi(res[75], a[37], a[37]); // Add sqr(74) + res[76] = fma52lo(res[76], a[38], a[38]); // Add sqr(76) + res[77] = fma52hi(res[77], a[38], a[38]); // Add sqr(76) + res[78] = fma52lo(res[78], a[39], a[39]); // Add sqr(78) + res[79] = fma52hi(res[79], a[39], a[39]); // Add sqr(78) + + // Montgomery Reduction + int it; + for (it = 0; it < 40; it += 10) { // Reduction step + int jt = 0; + if ((it + 0) > 0) + res[it + 0] = add64(res[it + 0], srli64(res[it + -1], DIGIT_SIZE)); + u[it + 0] = mul52lo(res[it + 0], k); + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + 1] = add64(res[it + 1], srli64(res[it + 0], DIGIT_SIZE)); + u[it + 1] = mul52lo(res[it + 1], k); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + 2] = add64(res[it + 2], srli64(res[it + 1], DIGIT_SIZE)); + u[it + 2] = mul52lo(res[it + 2], k); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + 3] = add64(res[it + 3], srli64(res[it + 2], DIGIT_SIZE)); + u[it + 3] = mul52lo(res[it + 3], k); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + 4] = add64(res[it + 4], srli64(res[it + 3], DIGIT_SIZE)); + u[it + 4] = mul52lo(res[it + 4], k); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + 5] = add64(res[it + 5], srli64(res[it + 4], DIGIT_SIZE)); + u[it + 5] = mul52lo(res[it + 5], k); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + 6] = add64(res[it + 6], srli64(res[it + 5], DIGIT_SIZE)); + u[it + 6] = mul52lo(res[it + 6], k); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + 7] = add64(res[it + 7], srli64(res[it + 6], DIGIT_SIZE)); + u[it + 7] = mul52lo(res[it + 7], k); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + 8] = add64(res[it + 8], srli64(res[it + 7], DIGIT_SIZE)); + u[it + 8] = mul52lo(res[it + 8], k); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + 9] = add64(res[it + 9], srli64(res[it + 8], DIGIT_SIZE)); + u[it + 9] = mul52lo(res[it + 9], k); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + + for (jt = 10; jt < 40; jt += 10) { // Poly tile + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + } + } + + // Normalization + res[40] = add64(res[40], srli64(res[39], DIGIT_SIZE)); + r[0] = and64_const(res[40], DIGIT_MASK); + res[41] = add64(res[41], srli64(res[40], DIGIT_SIZE)); + r[1] = and64_const(res[41], DIGIT_MASK); + res[42] = add64(res[42], srli64(res[41], DIGIT_SIZE)); + r[2] = and64_const(res[42], DIGIT_MASK); + res[43] = add64(res[43], srli64(res[42], DIGIT_SIZE)); + r[3] = and64_const(res[43], DIGIT_MASK); + res[44] = add64(res[44], srli64(res[43], DIGIT_SIZE)); + r[4] = and64_const(res[44], DIGIT_MASK); + res[45] = add64(res[45], srli64(res[44], DIGIT_SIZE)); + r[5] = and64_const(res[45], DIGIT_MASK); + res[46] = add64(res[46], srli64(res[45], DIGIT_SIZE)); + r[6] = and64_const(res[46], DIGIT_MASK); + res[47] = add64(res[47], srli64(res[46], DIGIT_SIZE)); + r[7] = and64_const(res[47], DIGIT_MASK); + res[48] = add64(res[48], srli64(res[47], DIGIT_SIZE)); + r[8] = and64_const(res[48], DIGIT_MASK); + res[49] = add64(res[49], srli64(res[48], DIGIT_SIZE)); + r[9] = and64_const(res[49], DIGIT_MASK); + res[50] = add64(res[50], srli64(res[49], DIGIT_SIZE)); + r[10] = and64_const(res[50], DIGIT_MASK); + res[51] = add64(res[51], srli64(res[50], DIGIT_SIZE)); + r[11] = and64_const(res[51], DIGIT_MASK); + res[52] = add64(res[52], srli64(res[51], DIGIT_SIZE)); + r[12] = and64_const(res[52], DIGIT_MASK); + res[53] = add64(res[53], srli64(res[52], DIGIT_SIZE)); + r[13] = and64_const(res[53], DIGIT_MASK); + res[54] = add64(res[54], srli64(res[53], DIGIT_SIZE)); + r[14] = and64_const(res[54], DIGIT_MASK); + res[55] = add64(res[55], srli64(res[54], DIGIT_SIZE)); + r[15] = and64_const(res[55], DIGIT_MASK); + res[56] = add64(res[56], srli64(res[55], DIGIT_SIZE)); + r[16] = and64_const(res[56], DIGIT_MASK); + res[57] = add64(res[57], srli64(res[56], DIGIT_SIZE)); + r[17] = and64_const(res[57], DIGIT_MASK); + res[58] = add64(res[58], srli64(res[57], DIGIT_SIZE)); + r[18] = and64_const(res[58], DIGIT_MASK); + res[59] = add64(res[59], srli64(res[58], DIGIT_SIZE)); + r[19] = and64_const(res[59], DIGIT_MASK); + res[60] = add64(res[60], srli64(res[59], DIGIT_SIZE)); + r[20] = and64_const(res[60], DIGIT_MASK); + res[61] = add64(res[61], srli64(res[60], DIGIT_SIZE)); + r[21] = and64_const(res[61], DIGIT_MASK); + res[62] = add64(res[62], srli64(res[61], DIGIT_SIZE)); + r[22] = and64_const(res[62], DIGIT_MASK); + res[63] = add64(res[63], srli64(res[62], DIGIT_SIZE)); + r[23] = and64_const(res[63], DIGIT_MASK); + res[64] = add64(res[64], srli64(res[63], DIGIT_SIZE)); + r[24] = and64_const(res[64], DIGIT_MASK); + res[65] = add64(res[65], srli64(res[64], DIGIT_SIZE)); + r[25] = and64_const(res[65], DIGIT_MASK); + res[66] = add64(res[66], srli64(res[65], DIGIT_SIZE)); + r[26] = and64_const(res[66], DIGIT_MASK); + res[67] = add64(res[67], srli64(res[66], DIGIT_SIZE)); + r[27] = and64_const(res[67], DIGIT_MASK); + res[68] = add64(res[68], srli64(res[67], DIGIT_SIZE)); + r[28] = and64_const(res[68], DIGIT_MASK); + res[69] = add64(res[69], srli64(res[68], DIGIT_SIZE)); + r[29] = and64_const(res[69], DIGIT_MASK); + res[70] = add64(res[70], srli64(res[69], DIGIT_SIZE)); + r[30] = and64_const(res[70], DIGIT_MASK); + res[71] = add64(res[71], srli64(res[70], DIGIT_SIZE)); + r[31] = and64_const(res[71], DIGIT_MASK); + res[72] = add64(res[72], srli64(res[71], DIGIT_SIZE)); + r[32] = and64_const(res[72], DIGIT_MASK); + res[73] = add64(res[73], srli64(res[72], DIGIT_SIZE)); + r[33] = and64_const(res[73], DIGIT_MASK); + res[74] = add64(res[74], srli64(res[73], DIGIT_SIZE)); + r[34] = and64_const(res[74], DIGIT_MASK); + res[75] = add64(res[75], srli64(res[74], DIGIT_SIZE)); + r[35] = and64_const(res[75], DIGIT_MASK); + res[76] = add64(res[76], srli64(res[75], DIGIT_SIZE)); + r[36] = and64_const(res[76], DIGIT_MASK); + res[77] = add64(res[77], srli64(res[76], DIGIT_SIZE)); + r[37] = and64_const(res[77], DIGIT_MASK); + res[78] = add64(res[78], srli64(res[77], DIGIT_SIZE)); + r[38] = and64_const(res[78], DIGIT_MASK); + res[79] = add64(res[79], srli64(res[78], DIGIT_SIZE)); + r[39] = and64_const(res[79], DIGIT_MASK); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x60_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x60_diagonal_mb8.c new file mode 100644 index 000000000..9b2643947 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x60_diagonal_mb8.c @@ -0,0 +1,4371 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS52x60_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + __ALIGN64 U64 res[120]; + __ALIGN64 U64 u[60]; + U64 k; + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + + k = loadu64((U64 *)k0_mb); + int i; + for (i = 0; i < 120; ++i) + res[i] = get_zero64(); + + res[1] = fma52lo(res[1], a[0], a[1]); // Sum(1) + res[2] = fma52hi(res[2], a[0], a[1]); // Sum(1) + res[2] = fma52lo(res[2], a[0], a[2]); // Sum(2) + res[3] = fma52hi(res[3], a[0], a[2]); // Sum(2) + res[3] = fma52lo(res[3], a[1], a[2]); // Sum(3) + res[4] = fma52hi(res[4], a[1], a[2]); // Sum(3) + res[3] = fma52lo(res[3], a[0], a[3]); // Sum(3) + res[4] = fma52hi(res[4], a[0], a[3]); // Sum(3) + res[4] = fma52lo(res[4], a[1], a[3]); // Sum(4) + res[5] = fma52hi(res[5], a[1], a[3]); // Sum(4) + res[5] = fma52lo(res[5], a[2], a[3]); // Sum(5) + res[6] = fma52hi(res[6], a[2], a[3]); // Sum(5) + res[4] = fma52lo(res[4], a[0], a[4]); // Sum(4) + res[5] = fma52hi(res[5], a[0], a[4]); // Sum(4) + res[5] = fma52lo(res[5], a[1], a[4]); // Sum(5) + res[6] = fma52hi(res[6], a[1], a[4]); // Sum(5) + res[6] = fma52lo(res[6], a[2], a[4]); // Sum(6) + res[7] = fma52hi(res[7], a[2], a[4]); // Sum(6) + res[7] = fma52lo(res[7], a[3], a[4]); // Sum(7) + res[8] = fma52hi(res[8], a[3], a[4]); // Sum(7) + res[5] = fma52lo(res[5], a[0], a[5]); // Sum(5) + res[6] = fma52hi(res[6], a[0], a[5]); // Sum(5) + res[6] = fma52lo(res[6], a[1], a[5]); // Sum(6) + res[7] = fma52hi(res[7], a[1], a[5]); // Sum(6) + res[7] = fma52lo(res[7], a[2], a[5]); // Sum(7) + res[8] = fma52hi(res[8], a[2], a[5]); // Sum(7) + res[8] = fma52lo(res[8], a[3], a[5]); // Sum(8) + res[9] = fma52hi(res[9], a[3], a[5]); // Sum(8) + res[9] = fma52lo(res[9], a[4], a[5]); // Sum(9) + res[10] = fma52hi(res[10], a[4], a[5]); // Sum(9) + res[6] = fma52lo(res[6], a[0], a[6]); // Sum(6) + res[7] = fma52hi(res[7], a[0], a[6]); // Sum(6) + res[7] = fma52lo(res[7], a[1], a[6]); // Sum(7) + res[8] = fma52hi(res[8], a[1], a[6]); // Sum(7) + res[8] = fma52lo(res[8], a[2], a[6]); // Sum(8) + res[9] = fma52hi(res[9], a[2], a[6]); // Sum(8) + res[9] = fma52lo(res[9], a[3], a[6]); // Sum(9) + res[10] = fma52hi(res[10], a[3], a[6]); // Sum(9) + res[10] = fma52lo(res[10], a[4], a[6]); // Sum(10) + res[11] = fma52hi(res[11], a[4], a[6]); // Sum(10) + res[11] = fma52lo(res[11], a[5], a[6]); // Sum(11) + res[12] = fma52hi(res[12], a[5], a[6]); // Sum(11) + res[7] = fma52lo(res[7], a[0], a[7]); // Sum(7) + res[8] = fma52hi(res[8], a[0], a[7]); // Sum(7) + res[8] = fma52lo(res[8], a[1], a[7]); // Sum(8) + res[9] = fma52hi(res[9], a[1], a[7]); // Sum(8) + res[9] = fma52lo(res[9], a[2], a[7]); // Sum(9) + res[10] = fma52hi(res[10], a[2], a[7]); // Sum(9) + res[10] = fma52lo(res[10], a[3], a[7]); // Sum(10) + res[11] = fma52hi(res[11], a[3], a[7]); // Sum(10) + res[11] = fma52lo(res[11], a[4], a[7]); // Sum(11) + res[12] = fma52hi(res[12], a[4], a[7]); // Sum(11) + res[8] = fma52lo(res[8], a[0], a[8]); // Sum(8) + res[9] = fma52hi(res[9], a[0], a[8]); // Sum(8) + res[9] = fma52lo(res[9], a[1], a[8]); // Sum(9) + res[10] = fma52hi(res[10], a[1], a[8]); // Sum(9) + res[10] = fma52lo(res[10], a[2], a[8]); // Sum(10) + res[11] = fma52hi(res[11], a[2], a[8]); // Sum(10) + res[11] = fma52lo(res[11], a[3], a[8]); // Sum(11) + res[12] = fma52hi(res[12], a[3], a[8]); // Sum(11) + res[9] = fma52lo(res[9], a[0], a[9]); // Sum(9) + res[10] = fma52hi(res[10], a[0], a[9]); // Sum(9) + res[10] = fma52lo(res[10], a[1], a[9]); // Sum(10) + res[11] = fma52hi(res[11], a[1], a[9]); // Sum(10) + res[11] = fma52lo(res[11], a[2], a[9]); // Sum(11) + res[12] = fma52hi(res[12], a[2], a[9]); // Sum(11) + res[10] = fma52lo(res[10], a[0], a[10]); // Sum(10) + res[11] = fma52hi(res[11], a[0], a[10]); // Sum(10) + res[11] = fma52lo(res[11], a[1], a[10]); // Sum(11) + res[12] = fma52hi(res[12], a[1], a[10]); // Sum(11) + res[11] = fma52lo(res[11], a[0], a[11]); // Sum(11) + res[12] = fma52hi(res[12], a[0], a[11]); // Sum(11) + res[0] = add64(res[0], res[0]); // Double(0) + res[1] = add64(res[1], res[1]); // Double(1) + res[2] = add64(res[2], res[2]); // Double(2) + res[3] = add64(res[3], res[3]); // Double(3) + res[4] = add64(res[4], res[4]); // Double(4) + res[5] = add64(res[5], res[5]); // Double(5) + res[6] = add64(res[6], res[6]); // Double(6) + res[7] = add64(res[7], res[7]); // Double(7) + res[8] = add64(res[8], res[8]); // Double(8) + res[9] = add64(res[9], res[9]); // Double(9) + res[10] = add64(res[10], res[10]); // Double(10) + res[11] = add64(res[11], res[11]); // Double(11) + res[0] = fma52lo(res[0], a[0], a[0]); // Add sqr(0) + res[1] = fma52hi(res[1], a[0], a[0]); // Add sqr(0) + res[2] = fma52lo(res[2], a[1], a[1]); // Add sqr(2) + res[3] = fma52hi(res[3], a[1], a[1]); // Add sqr(2) + res[4] = fma52lo(res[4], a[2], a[2]); // Add sqr(4) + res[5] = fma52hi(res[5], a[2], a[2]); // Add sqr(4) + res[6] = fma52lo(res[6], a[3], a[3]); // Add sqr(6) + res[7] = fma52hi(res[7], a[3], a[3]); // Add sqr(6) + res[8] = fma52lo(res[8], a[4], a[4]); // Add sqr(8) + res[9] = fma52hi(res[9], a[4], a[4]); // Add sqr(8) + res[10] = fma52lo(res[10], a[5], a[5]); // Add sqr(10) + res[11] = fma52hi(res[11], a[5], a[5]); // Add sqr(10) + res[12] = fma52lo(res[12], a[5], a[7]); // Sum(12) + res[13] = fma52hi(res[13], a[5], a[7]); // Sum(12) + res[13] = fma52lo(res[13], a[6], a[7]); // Sum(13) + res[14] = fma52hi(res[14], a[6], a[7]); // Sum(13) + res[12] = fma52lo(res[12], a[4], a[8]); // Sum(12) + res[13] = fma52hi(res[13], a[4], a[8]); // Sum(12) + res[13] = fma52lo(res[13], a[5], a[8]); // Sum(13) + res[14] = fma52hi(res[14], a[5], a[8]); // Sum(13) + res[14] = fma52lo(res[14], a[6], a[8]); // Sum(14) + res[15] = fma52hi(res[15], a[6], a[8]); // Sum(14) + res[15] = fma52lo(res[15], a[7], a[8]); // Sum(15) + res[16] = fma52hi(res[16], a[7], a[8]); // Sum(15) + res[12] = fma52lo(res[12], a[3], a[9]); // Sum(12) + res[13] = fma52hi(res[13], a[3], a[9]); // Sum(12) + res[13] = fma52lo(res[13], a[4], a[9]); // Sum(13) + res[14] = fma52hi(res[14], a[4], a[9]); // Sum(13) + res[14] = fma52lo(res[14], a[5], a[9]); // Sum(14) + res[15] = fma52hi(res[15], a[5], a[9]); // Sum(14) + res[15] = fma52lo(res[15], a[6], a[9]); // Sum(15) + res[16] = fma52hi(res[16], a[6], a[9]); // Sum(15) + res[16] = fma52lo(res[16], a[7], a[9]); // Sum(16) + res[17] = fma52hi(res[17], a[7], a[9]); // Sum(16) + res[17] = fma52lo(res[17], a[8], a[9]); // Sum(17) + res[18] = fma52hi(res[18], a[8], a[9]); // Sum(17) + res[12] = fma52lo(res[12], a[2], a[10]); // Sum(12) + res[13] = fma52hi(res[13], a[2], a[10]); // Sum(12) + res[13] = fma52lo(res[13], a[3], a[10]); // Sum(13) + res[14] = fma52hi(res[14], a[3], a[10]); // Sum(13) + res[14] = fma52lo(res[14], a[4], a[10]); // Sum(14) + res[15] = fma52hi(res[15], a[4], a[10]); // Sum(14) + res[15] = fma52lo(res[15], a[5], a[10]); // Sum(15) + res[16] = fma52hi(res[16], a[5], a[10]); // Sum(15) + res[16] = fma52lo(res[16], a[6], a[10]); // Sum(16) + res[17] = fma52hi(res[17], a[6], a[10]); // Sum(16) + res[17] = fma52lo(res[17], a[7], a[10]); // Sum(17) + res[18] = fma52hi(res[18], a[7], a[10]); // Sum(17) + res[18] = fma52lo(res[18], a[8], a[10]); // Sum(18) + res[19] = fma52hi(res[19], a[8], a[10]); // Sum(18) + res[19] = fma52lo(res[19], a[9], a[10]); // Sum(19) + res[20] = fma52hi(res[20], a[9], a[10]); // Sum(19) + res[12] = fma52lo(res[12], a[1], a[11]); // Sum(12) + res[13] = fma52hi(res[13], a[1], a[11]); // Sum(12) + res[13] = fma52lo(res[13], a[2], a[11]); // Sum(13) + res[14] = fma52hi(res[14], a[2], a[11]); // Sum(13) + res[14] = fma52lo(res[14], a[3], a[11]); // Sum(14) + res[15] = fma52hi(res[15], a[3], a[11]); // Sum(14) + res[15] = fma52lo(res[15], a[4], a[11]); // Sum(15) + res[16] = fma52hi(res[16], a[4], a[11]); // Sum(15) + res[16] = fma52lo(res[16], a[5], a[11]); // Sum(16) + res[17] = fma52hi(res[17], a[5], a[11]); // Sum(16) + res[17] = fma52lo(res[17], a[6], a[11]); // Sum(17) + res[18] = fma52hi(res[18], a[6], a[11]); // Sum(17) + res[18] = fma52lo(res[18], a[7], a[11]); // Sum(18) + res[19] = fma52hi(res[19], a[7], a[11]); // Sum(18) + res[19] = fma52lo(res[19], a[8], a[11]); // Sum(19) + res[20] = fma52hi(res[20], a[8], a[11]); // Sum(19) + res[20] = fma52lo(res[20], a[9], a[11]); // Sum(20) + res[21] = fma52hi(res[21], a[9], a[11]); // Sum(20) + res[21] = fma52lo(res[21], a[10], a[11]); // Sum(21) + res[22] = fma52hi(res[22], a[10], a[11]); // Sum(21) + res[12] = fma52lo(res[12], a[0], a[12]); // Sum(12) + res[13] = fma52hi(res[13], a[0], a[12]); // Sum(12) + res[13] = fma52lo(res[13], a[1], a[12]); // Sum(13) + res[14] = fma52hi(res[14], a[1], a[12]); // Sum(13) + res[14] = fma52lo(res[14], a[2], a[12]); // Sum(14) + res[15] = fma52hi(res[15], a[2], a[12]); // Sum(14) + res[15] = fma52lo(res[15], a[3], a[12]); // Sum(15) + res[16] = fma52hi(res[16], a[3], a[12]); // Sum(15) + res[16] = fma52lo(res[16], a[4], a[12]); // Sum(16) + res[17] = fma52hi(res[17], a[4], a[12]); // Sum(16) + res[17] = fma52lo(res[17], a[5], a[12]); // Sum(17) + res[18] = fma52hi(res[18], a[5], a[12]); // Sum(17) + res[18] = fma52lo(res[18], a[6], a[12]); // Sum(18) + res[19] = fma52hi(res[19], a[6], a[12]); // Sum(18) + res[19] = fma52lo(res[19], a[7], a[12]); // Sum(19) + res[20] = fma52hi(res[20], a[7], a[12]); // Sum(19) + res[20] = fma52lo(res[20], a[8], a[12]); // Sum(20) + res[21] = fma52hi(res[21], a[8], a[12]); // Sum(20) + res[21] = fma52lo(res[21], a[9], a[12]); // Sum(21) + res[22] = fma52hi(res[22], a[9], a[12]); // Sum(21) + res[22] = fma52lo(res[22], a[10], a[12]); // Sum(22) + res[23] = fma52hi(res[23], a[10], a[12]); // Sum(22) + res[23] = fma52lo(res[23], a[11], a[12]); // Sum(23) + res[24] = fma52hi(res[24], a[11], a[12]); // Sum(23) + res[13] = fma52lo(res[13], a[0], a[13]); // Sum(13) + res[14] = fma52hi(res[14], a[0], a[13]); // Sum(13) + res[14] = fma52lo(res[14], a[1], a[13]); // Sum(14) + res[15] = fma52hi(res[15], a[1], a[13]); // Sum(14) + res[15] = fma52lo(res[15], a[2], a[13]); // Sum(15) + res[16] = fma52hi(res[16], a[2], a[13]); // Sum(15) + res[16] = fma52lo(res[16], a[3], a[13]); // Sum(16) + res[17] = fma52hi(res[17], a[3], a[13]); // Sum(16) + res[17] = fma52lo(res[17], a[4], a[13]); // Sum(17) + res[18] = fma52hi(res[18], a[4], a[13]); // Sum(17) + res[18] = fma52lo(res[18], a[5], a[13]); // Sum(18) + res[19] = fma52hi(res[19], a[5], a[13]); // Sum(18) + res[19] = fma52lo(res[19], a[6], a[13]); // Sum(19) + res[20] = fma52hi(res[20], a[6], a[13]); // Sum(19) + res[20] = fma52lo(res[20], a[7], a[13]); // Sum(20) + res[21] = fma52hi(res[21], a[7], a[13]); // Sum(20) + res[21] = fma52lo(res[21], a[8], a[13]); // Sum(21) + res[22] = fma52hi(res[22], a[8], a[13]); // Sum(21) + res[22] = fma52lo(res[22], a[9], a[13]); // Sum(22) + res[23] = fma52hi(res[23], a[9], a[13]); // Sum(22) + res[23] = fma52lo(res[23], a[10], a[13]); // Sum(23) + res[24] = fma52hi(res[24], a[10], a[13]); // Sum(23) + res[14] = fma52lo(res[14], a[0], a[14]); // Sum(14) + res[15] = fma52hi(res[15], a[0], a[14]); // Sum(14) + res[15] = fma52lo(res[15], a[1], a[14]); // Sum(15) + res[16] = fma52hi(res[16], a[1], a[14]); // Sum(15) + res[16] = fma52lo(res[16], a[2], a[14]); // Sum(16) + res[17] = fma52hi(res[17], a[2], a[14]); // Sum(16) + res[17] = fma52lo(res[17], a[3], a[14]); // Sum(17) + res[18] = fma52hi(res[18], a[3], a[14]); // Sum(17) + res[18] = fma52lo(res[18], a[4], a[14]); // Sum(18) + res[19] = fma52hi(res[19], a[4], a[14]); // Sum(18) + res[19] = fma52lo(res[19], a[5], a[14]); // Sum(19) + res[20] = fma52hi(res[20], a[5], a[14]); // Sum(19) + res[20] = fma52lo(res[20], a[6], a[14]); // Sum(20) + res[21] = fma52hi(res[21], a[6], a[14]); // Sum(20) + res[21] = fma52lo(res[21], a[7], a[14]); // Sum(21) + res[22] = fma52hi(res[22], a[7], a[14]); // Sum(21) + res[22] = fma52lo(res[22], a[8], a[14]); // Sum(22) + res[23] = fma52hi(res[23], a[8], a[14]); // Sum(22) + res[23] = fma52lo(res[23], a[9], a[14]); // Sum(23) + res[24] = fma52hi(res[24], a[9], a[14]); // Sum(23) + res[15] = fma52lo(res[15], a[0], a[15]); // Sum(15) + res[16] = fma52hi(res[16], a[0], a[15]); // Sum(15) + res[16] = fma52lo(res[16], a[1], a[15]); // Sum(16) + res[17] = fma52hi(res[17], a[1], a[15]); // Sum(16) + res[17] = fma52lo(res[17], a[2], a[15]); // Sum(17) + res[18] = fma52hi(res[18], a[2], a[15]); // Sum(17) + res[18] = fma52lo(res[18], a[3], a[15]); // Sum(18) + res[19] = fma52hi(res[19], a[3], a[15]); // Sum(18) + res[19] = fma52lo(res[19], a[4], a[15]); // Sum(19) + res[20] = fma52hi(res[20], a[4], a[15]); // Sum(19) + res[20] = fma52lo(res[20], a[5], a[15]); // Sum(20) + res[21] = fma52hi(res[21], a[5], a[15]); // Sum(20) + res[21] = fma52lo(res[21], a[6], a[15]); // Sum(21) + res[22] = fma52hi(res[22], a[6], a[15]); // Sum(21) + res[22] = fma52lo(res[22], a[7], a[15]); // Sum(22) + res[23] = fma52hi(res[23], a[7], a[15]); // Sum(22) + res[23] = fma52lo(res[23], a[8], a[15]); // Sum(23) + res[24] = fma52hi(res[24], a[8], a[15]); // Sum(23) + res[16] = fma52lo(res[16], a[0], a[16]); // Sum(16) + res[17] = fma52hi(res[17], a[0], a[16]); // Sum(16) + res[17] = fma52lo(res[17], a[1], a[16]); // Sum(17) + res[18] = fma52hi(res[18], a[1], a[16]); // Sum(17) + res[18] = fma52lo(res[18], a[2], a[16]); // Sum(18) + res[19] = fma52hi(res[19], a[2], a[16]); // Sum(18) + res[19] = fma52lo(res[19], a[3], a[16]); // Sum(19) + res[20] = fma52hi(res[20], a[3], a[16]); // Sum(19) + res[20] = fma52lo(res[20], a[4], a[16]); // Sum(20) + res[21] = fma52hi(res[21], a[4], a[16]); // Sum(20) + res[21] = fma52lo(res[21], a[5], a[16]); // Sum(21) + res[22] = fma52hi(res[22], a[5], a[16]); // Sum(21) + res[22] = fma52lo(res[22], a[6], a[16]); // Sum(22) + res[23] = fma52hi(res[23], a[6], a[16]); // Sum(22) + res[23] = fma52lo(res[23], a[7], a[16]); // Sum(23) + res[24] = fma52hi(res[24], a[7], a[16]); // Sum(23) + res[17] = fma52lo(res[17], a[0], a[17]); // Sum(17) + res[18] = fma52hi(res[18], a[0], a[17]); // Sum(17) + res[18] = fma52lo(res[18], a[1], a[17]); // Sum(18) + res[19] = fma52hi(res[19], a[1], a[17]); // Sum(18) + res[19] = fma52lo(res[19], a[2], a[17]); // Sum(19) + res[20] = fma52hi(res[20], a[2], a[17]); // Sum(19) + res[20] = fma52lo(res[20], a[3], a[17]); // Sum(20) + res[21] = fma52hi(res[21], a[3], a[17]); // Sum(20) + res[21] = fma52lo(res[21], a[4], a[17]); // Sum(21) + res[22] = fma52hi(res[22], a[4], a[17]); // Sum(21) + res[22] = fma52lo(res[22], a[5], a[17]); // Sum(22) + res[23] = fma52hi(res[23], a[5], a[17]); // Sum(22) + res[23] = fma52lo(res[23], a[6], a[17]); // Sum(23) + res[24] = fma52hi(res[24], a[6], a[17]); // Sum(23) + res[18] = fma52lo(res[18], a[0], a[18]); // Sum(18) + res[19] = fma52hi(res[19], a[0], a[18]); // Sum(18) + res[19] = fma52lo(res[19], a[1], a[18]); // Sum(19) + res[20] = fma52hi(res[20], a[1], a[18]); // Sum(19) + res[20] = fma52lo(res[20], a[2], a[18]); // Sum(20) + res[21] = fma52hi(res[21], a[2], a[18]); // Sum(20) + res[21] = fma52lo(res[21], a[3], a[18]); // Sum(21) + res[22] = fma52hi(res[22], a[3], a[18]); // Sum(21) + res[22] = fma52lo(res[22], a[4], a[18]); // Sum(22) + res[23] = fma52hi(res[23], a[4], a[18]); // Sum(22) + res[23] = fma52lo(res[23], a[5], a[18]); // Sum(23) + res[24] = fma52hi(res[24], a[5], a[18]); // Sum(23) + res[19] = fma52lo(res[19], a[0], a[19]); // Sum(19) + res[20] = fma52hi(res[20], a[0], a[19]); // Sum(19) + res[20] = fma52lo(res[20], a[1], a[19]); // Sum(20) + res[21] = fma52hi(res[21], a[1], a[19]); // Sum(20) + res[21] = fma52lo(res[21], a[2], a[19]); // Sum(21) + res[22] = fma52hi(res[22], a[2], a[19]); // Sum(21) + res[22] = fma52lo(res[22], a[3], a[19]); // Sum(22) + res[23] = fma52hi(res[23], a[3], a[19]); // Sum(22) + res[23] = fma52lo(res[23], a[4], a[19]); // Sum(23) + res[24] = fma52hi(res[24], a[4], a[19]); // Sum(23) + res[20] = fma52lo(res[20], a[0], a[20]); // Sum(20) + res[21] = fma52hi(res[21], a[0], a[20]); // Sum(20) + res[21] = fma52lo(res[21], a[1], a[20]); // Sum(21) + res[22] = fma52hi(res[22], a[1], a[20]); // Sum(21) + res[22] = fma52lo(res[22], a[2], a[20]); // Sum(22) + res[23] = fma52hi(res[23], a[2], a[20]); // Sum(22) + res[23] = fma52lo(res[23], a[3], a[20]); // Sum(23) + res[24] = fma52hi(res[24], a[3], a[20]); // Sum(23) + res[21] = fma52lo(res[21], a[0], a[21]); // Sum(21) + res[22] = fma52hi(res[22], a[0], a[21]); // Sum(21) + res[22] = fma52lo(res[22], a[1], a[21]); // Sum(22) + res[23] = fma52hi(res[23], a[1], a[21]); // Sum(22) + res[23] = fma52lo(res[23], a[2], a[21]); // Sum(23) + res[24] = fma52hi(res[24], a[2], a[21]); // Sum(23) + res[22] = fma52lo(res[22], a[0], a[22]); // Sum(22) + res[23] = fma52hi(res[23], a[0], a[22]); // Sum(22) + res[23] = fma52lo(res[23], a[1], a[22]); // Sum(23) + res[24] = fma52hi(res[24], a[1], a[22]); // Sum(23) + res[23] = fma52lo(res[23], a[0], a[23]); // Sum(23) + res[24] = fma52hi(res[24], a[0], a[23]); // Sum(23) + res[12] = add64(res[12], res[12]); // Double(12) + res[13] = add64(res[13], res[13]); // Double(13) + res[14] = add64(res[14], res[14]); // Double(14) + res[15] = add64(res[15], res[15]); // Double(15) + res[16] = add64(res[16], res[16]); // Double(16) + res[17] = add64(res[17], res[17]); // Double(17) + res[18] = add64(res[18], res[18]); // Double(18) + res[19] = add64(res[19], res[19]); // Double(19) + res[20] = add64(res[20], res[20]); // Double(20) + res[21] = add64(res[21], res[21]); // Double(21) + res[22] = add64(res[22], res[22]); // Double(22) + res[23] = add64(res[23], res[23]); // Double(23) + res[12] = fma52lo(res[12], a[6], a[6]); // Add sqr(12) + res[13] = fma52hi(res[13], a[6], a[6]); // Add sqr(12) + res[14] = fma52lo(res[14], a[7], a[7]); // Add sqr(14) + res[15] = fma52hi(res[15], a[7], a[7]); // Add sqr(14) + res[16] = fma52lo(res[16], a[8], a[8]); // Add sqr(16) + res[17] = fma52hi(res[17], a[8], a[8]); // Add sqr(16) + res[18] = fma52lo(res[18], a[9], a[9]); // Add sqr(18) + res[19] = fma52hi(res[19], a[9], a[9]); // Add sqr(18) + res[20] = fma52lo(res[20], a[10], a[10]); // Add sqr(20) + res[21] = fma52hi(res[21], a[10], a[10]); // Add sqr(20) + res[22] = fma52lo(res[22], a[11], a[11]); // Add sqr(22) + res[23] = fma52hi(res[23], a[11], a[11]); // Add sqr(22) + res[24] = fma52lo(res[24], a[11], a[13]); // Sum(24) + res[25] = fma52hi(res[25], a[11], a[13]); // Sum(24) + res[25] = fma52lo(res[25], a[12], a[13]); // Sum(25) + res[26] = fma52hi(res[26], a[12], a[13]); // Sum(25) + res[24] = fma52lo(res[24], a[10], a[14]); // Sum(24) + res[25] = fma52hi(res[25], a[10], a[14]); // Sum(24) + res[25] = fma52lo(res[25], a[11], a[14]); // Sum(25) + res[26] = fma52hi(res[26], a[11], a[14]); // Sum(25) + res[26] = fma52lo(res[26], a[12], a[14]); // Sum(26) + res[27] = fma52hi(res[27], a[12], a[14]); // Sum(26) + res[27] = fma52lo(res[27], a[13], a[14]); // Sum(27) + res[28] = fma52hi(res[28], a[13], a[14]); // Sum(27) + res[24] = fma52lo(res[24], a[9], a[15]); // Sum(24) + res[25] = fma52hi(res[25], a[9], a[15]); // Sum(24) + res[25] = fma52lo(res[25], a[10], a[15]); // Sum(25) + res[26] = fma52hi(res[26], a[10], a[15]); // Sum(25) + res[26] = fma52lo(res[26], a[11], a[15]); // Sum(26) + res[27] = fma52hi(res[27], a[11], a[15]); // Sum(26) + res[27] = fma52lo(res[27], a[12], a[15]); // Sum(27) + res[28] = fma52hi(res[28], a[12], a[15]); // Sum(27) + res[28] = fma52lo(res[28], a[13], a[15]); // Sum(28) + res[29] = fma52hi(res[29], a[13], a[15]); // Sum(28) + res[29] = fma52lo(res[29], a[14], a[15]); // Sum(29) + res[30] = fma52hi(res[30], a[14], a[15]); // Sum(29) + res[24] = fma52lo(res[24], a[8], a[16]); // Sum(24) + res[25] = fma52hi(res[25], a[8], a[16]); // Sum(24) + res[25] = fma52lo(res[25], a[9], a[16]); // Sum(25) + res[26] = fma52hi(res[26], a[9], a[16]); // Sum(25) + res[26] = fma52lo(res[26], a[10], a[16]); // Sum(26) + res[27] = fma52hi(res[27], a[10], a[16]); // Sum(26) + res[27] = fma52lo(res[27], a[11], a[16]); // Sum(27) + res[28] = fma52hi(res[28], a[11], a[16]); // Sum(27) + res[28] = fma52lo(res[28], a[12], a[16]); // Sum(28) + res[29] = fma52hi(res[29], a[12], a[16]); // Sum(28) + res[29] = fma52lo(res[29], a[13], a[16]); // Sum(29) + res[30] = fma52hi(res[30], a[13], a[16]); // Sum(29) + res[30] = fma52lo(res[30], a[14], a[16]); // Sum(30) + res[31] = fma52hi(res[31], a[14], a[16]); // Sum(30) + res[31] = fma52lo(res[31], a[15], a[16]); // Sum(31) + res[32] = fma52hi(res[32], a[15], a[16]); // Sum(31) + res[24] = fma52lo(res[24], a[7], a[17]); // Sum(24) + res[25] = fma52hi(res[25], a[7], a[17]); // Sum(24) + res[25] = fma52lo(res[25], a[8], a[17]); // Sum(25) + res[26] = fma52hi(res[26], a[8], a[17]); // Sum(25) + res[26] = fma52lo(res[26], a[9], a[17]); // Sum(26) + res[27] = fma52hi(res[27], a[9], a[17]); // Sum(26) + res[27] = fma52lo(res[27], a[10], a[17]); // Sum(27) + res[28] = fma52hi(res[28], a[10], a[17]); // Sum(27) + res[28] = fma52lo(res[28], a[11], a[17]); // Sum(28) + res[29] = fma52hi(res[29], a[11], a[17]); // Sum(28) + res[29] = fma52lo(res[29], a[12], a[17]); // Sum(29) + res[30] = fma52hi(res[30], a[12], a[17]); // Sum(29) + res[30] = fma52lo(res[30], a[13], a[17]); // Sum(30) + res[31] = fma52hi(res[31], a[13], a[17]); // Sum(30) + res[31] = fma52lo(res[31], a[14], a[17]); // Sum(31) + res[32] = fma52hi(res[32], a[14], a[17]); // Sum(31) + res[32] = fma52lo(res[32], a[15], a[17]); // Sum(32) + res[33] = fma52hi(res[33], a[15], a[17]); // Sum(32) + res[33] = fma52lo(res[33], a[16], a[17]); // Sum(33) + res[34] = fma52hi(res[34], a[16], a[17]); // Sum(33) + res[24] = fma52lo(res[24], a[6], a[18]); // Sum(24) + res[25] = fma52hi(res[25], a[6], a[18]); // Sum(24) + res[25] = fma52lo(res[25], a[7], a[18]); // Sum(25) + res[26] = fma52hi(res[26], a[7], a[18]); // Sum(25) + res[26] = fma52lo(res[26], a[8], a[18]); // Sum(26) + res[27] = fma52hi(res[27], a[8], a[18]); // Sum(26) + res[27] = fma52lo(res[27], a[9], a[18]); // Sum(27) + res[28] = fma52hi(res[28], a[9], a[18]); // Sum(27) + res[28] = fma52lo(res[28], a[10], a[18]); // Sum(28) + res[29] = fma52hi(res[29], a[10], a[18]); // Sum(28) + res[29] = fma52lo(res[29], a[11], a[18]); // Sum(29) + res[30] = fma52hi(res[30], a[11], a[18]); // Sum(29) + res[30] = fma52lo(res[30], a[12], a[18]); // Sum(30) + res[31] = fma52hi(res[31], a[12], a[18]); // Sum(30) + res[31] = fma52lo(res[31], a[13], a[18]); // Sum(31) + res[32] = fma52hi(res[32], a[13], a[18]); // Sum(31) + res[32] = fma52lo(res[32], a[14], a[18]); // Sum(32) + res[33] = fma52hi(res[33], a[14], a[18]); // Sum(32) + res[33] = fma52lo(res[33], a[15], a[18]); // Sum(33) + res[34] = fma52hi(res[34], a[15], a[18]); // Sum(33) + res[34] = fma52lo(res[34], a[16], a[18]); // Sum(34) + res[35] = fma52hi(res[35], a[16], a[18]); // Sum(34) + res[35] = fma52lo(res[35], a[17], a[18]); // Sum(35) + res[36] = fma52hi(res[36], a[17], a[18]); // Sum(35) + res[24] = fma52lo(res[24], a[5], a[19]); // Sum(24) + res[25] = fma52hi(res[25], a[5], a[19]); // Sum(24) + res[25] = fma52lo(res[25], a[6], a[19]); // Sum(25) + res[26] = fma52hi(res[26], a[6], a[19]); // Sum(25) + res[26] = fma52lo(res[26], a[7], a[19]); // Sum(26) + res[27] = fma52hi(res[27], a[7], a[19]); // Sum(26) + res[27] = fma52lo(res[27], a[8], a[19]); // Sum(27) + res[28] = fma52hi(res[28], a[8], a[19]); // Sum(27) + res[28] = fma52lo(res[28], a[9], a[19]); // Sum(28) + res[29] = fma52hi(res[29], a[9], a[19]); // Sum(28) + res[29] = fma52lo(res[29], a[10], a[19]); // Sum(29) + res[30] = fma52hi(res[30], a[10], a[19]); // Sum(29) + res[30] = fma52lo(res[30], a[11], a[19]); // Sum(30) + res[31] = fma52hi(res[31], a[11], a[19]); // Sum(30) + res[31] = fma52lo(res[31], a[12], a[19]); // Sum(31) + res[32] = fma52hi(res[32], a[12], a[19]); // Sum(31) + res[32] = fma52lo(res[32], a[13], a[19]); // Sum(32) + res[33] = fma52hi(res[33], a[13], a[19]); // Sum(32) + res[33] = fma52lo(res[33], a[14], a[19]); // Sum(33) + res[34] = fma52hi(res[34], a[14], a[19]); // Sum(33) + res[34] = fma52lo(res[34], a[15], a[19]); // Sum(34) + res[35] = fma52hi(res[35], a[15], a[19]); // Sum(34) + res[35] = fma52lo(res[35], a[16], a[19]); // Sum(35) + res[36] = fma52hi(res[36], a[16], a[19]); // Sum(35) + res[24] = fma52lo(res[24], a[4], a[20]); // Sum(24) + res[25] = fma52hi(res[25], a[4], a[20]); // Sum(24) + res[25] = fma52lo(res[25], a[5], a[20]); // Sum(25) + res[26] = fma52hi(res[26], a[5], a[20]); // Sum(25) + res[26] = fma52lo(res[26], a[6], a[20]); // Sum(26) + res[27] = fma52hi(res[27], a[6], a[20]); // Sum(26) + res[27] = fma52lo(res[27], a[7], a[20]); // Sum(27) + res[28] = fma52hi(res[28], a[7], a[20]); // Sum(27) + res[28] = fma52lo(res[28], a[8], a[20]); // Sum(28) + res[29] = fma52hi(res[29], a[8], a[20]); // Sum(28) + res[29] = fma52lo(res[29], a[9], a[20]); // Sum(29) + res[30] = fma52hi(res[30], a[9], a[20]); // Sum(29) + res[30] = fma52lo(res[30], a[10], a[20]); // Sum(30) + res[31] = fma52hi(res[31], a[10], a[20]); // Sum(30) + res[31] = fma52lo(res[31], a[11], a[20]); // Sum(31) + res[32] = fma52hi(res[32], a[11], a[20]); // Sum(31) + res[32] = fma52lo(res[32], a[12], a[20]); // Sum(32) + res[33] = fma52hi(res[33], a[12], a[20]); // Sum(32) + res[33] = fma52lo(res[33], a[13], a[20]); // Sum(33) + res[34] = fma52hi(res[34], a[13], a[20]); // Sum(33) + res[34] = fma52lo(res[34], a[14], a[20]); // Sum(34) + res[35] = fma52hi(res[35], a[14], a[20]); // Sum(34) + res[35] = fma52lo(res[35], a[15], a[20]); // Sum(35) + res[36] = fma52hi(res[36], a[15], a[20]); // Sum(35) + res[24] = fma52lo(res[24], a[3], a[21]); // Sum(24) + res[25] = fma52hi(res[25], a[3], a[21]); // Sum(24) + res[25] = fma52lo(res[25], a[4], a[21]); // Sum(25) + res[26] = fma52hi(res[26], a[4], a[21]); // Sum(25) + res[26] = fma52lo(res[26], a[5], a[21]); // Sum(26) + res[27] = fma52hi(res[27], a[5], a[21]); // Sum(26) + res[27] = fma52lo(res[27], a[6], a[21]); // Sum(27) + res[28] = fma52hi(res[28], a[6], a[21]); // Sum(27) + res[28] = fma52lo(res[28], a[7], a[21]); // Sum(28) + res[29] = fma52hi(res[29], a[7], a[21]); // Sum(28) + res[29] = fma52lo(res[29], a[8], a[21]); // Sum(29) + res[30] = fma52hi(res[30], a[8], a[21]); // Sum(29) + res[30] = fma52lo(res[30], a[9], a[21]); // Sum(30) + res[31] = fma52hi(res[31], a[9], a[21]); // Sum(30) + res[31] = fma52lo(res[31], a[10], a[21]); // Sum(31) + res[32] = fma52hi(res[32], a[10], a[21]); // Sum(31) + res[32] = fma52lo(res[32], a[11], a[21]); // Sum(32) + res[33] = fma52hi(res[33], a[11], a[21]); // Sum(32) + res[33] = fma52lo(res[33], a[12], a[21]); // Sum(33) + res[34] = fma52hi(res[34], a[12], a[21]); // Sum(33) + res[34] = fma52lo(res[34], a[13], a[21]); // Sum(34) + res[35] = fma52hi(res[35], a[13], a[21]); // Sum(34) + res[35] = fma52lo(res[35], a[14], a[21]); // Sum(35) + res[36] = fma52hi(res[36], a[14], a[21]); // Sum(35) + res[24] = fma52lo(res[24], a[2], a[22]); // Sum(24) + res[25] = fma52hi(res[25], a[2], a[22]); // Sum(24) + res[25] = fma52lo(res[25], a[3], a[22]); // Sum(25) + res[26] = fma52hi(res[26], a[3], a[22]); // Sum(25) + res[26] = fma52lo(res[26], a[4], a[22]); // Sum(26) + res[27] = fma52hi(res[27], a[4], a[22]); // Sum(26) + res[27] = fma52lo(res[27], a[5], a[22]); // Sum(27) + res[28] = fma52hi(res[28], a[5], a[22]); // Sum(27) + res[28] = fma52lo(res[28], a[6], a[22]); // Sum(28) + res[29] = fma52hi(res[29], a[6], a[22]); // Sum(28) + res[29] = fma52lo(res[29], a[7], a[22]); // Sum(29) + res[30] = fma52hi(res[30], a[7], a[22]); // Sum(29) + res[30] = fma52lo(res[30], a[8], a[22]); // Sum(30) + res[31] = fma52hi(res[31], a[8], a[22]); // Sum(30) + res[31] = fma52lo(res[31], a[9], a[22]); // Sum(31) + res[32] = fma52hi(res[32], a[9], a[22]); // Sum(31) + res[32] = fma52lo(res[32], a[10], a[22]); // Sum(32) + res[33] = fma52hi(res[33], a[10], a[22]); // Sum(32) + res[33] = fma52lo(res[33], a[11], a[22]); // Sum(33) + res[34] = fma52hi(res[34], a[11], a[22]); // Sum(33) + res[34] = fma52lo(res[34], a[12], a[22]); // Sum(34) + res[35] = fma52hi(res[35], a[12], a[22]); // Sum(34) + res[35] = fma52lo(res[35], a[13], a[22]); // Sum(35) + res[36] = fma52hi(res[36], a[13], a[22]); // Sum(35) + res[24] = fma52lo(res[24], a[1], a[23]); // Sum(24) + res[25] = fma52hi(res[25], a[1], a[23]); // Sum(24) + res[25] = fma52lo(res[25], a[2], a[23]); // Sum(25) + res[26] = fma52hi(res[26], a[2], a[23]); // Sum(25) + res[26] = fma52lo(res[26], a[3], a[23]); // Sum(26) + res[27] = fma52hi(res[27], a[3], a[23]); // Sum(26) + res[27] = fma52lo(res[27], a[4], a[23]); // Sum(27) + res[28] = fma52hi(res[28], a[4], a[23]); // Sum(27) + res[28] = fma52lo(res[28], a[5], a[23]); // Sum(28) + res[29] = fma52hi(res[29], a[5], a[23]); // Sum(28) + res[29] = fma52lo(res[29], a[6], a[23]); // Sum(29) + res[30] = fma52hi(res[30], a[6], a[23]); // Sum(29) + res[30] = fma52lo(res[30], a[7], a[23]); // Sum(30) + res[31] = fma52hi(res[31], a[7], a[23]); // Sum(30) + res[31] = fma52lo(res[31], a[8], a[23]); // Sum(31) + res[32] = fma52hi(res[32], a[8], a[23]); // Sum(31) + res[32] = fma52lo(res[32], a[9], a[23]); // Sum(32) + res[33] = fma52hi(res[33], a[9], a[23]); // Sum(32) + res[33] = fma52lo(res[33], a[10], a[23]); // Sum(33) + res[34] = fma52hi(res[34], a[10], a[23]); // Sum(33) + res[34] = fma52lo(res[34], a[11], a[23]); // Sum(34) + res[35] = fma52hi(res[35], a[11], a[23]); // Sum(34) + res[35] = fma52lo(res[35], a[12], a[23]); // Sum(35) + res[36] = fma52hi(res[36], a[12], a[23]); // Sum(35) + res[24] = fma52lo(res[24], a[0], a[24]); // Sum(24) + res[25] = fma52hi(res[25], a[0], a[24]); // Sum(24) + res[25] = fma52lo(res[25], a[1], a[24]); // Sum(25) + res[26] = fma52hi(res[26], a[1], a[24]); // Sum(25) + res[26] = fma52lo(res[26], a[2], a[24]); // Sum(26) + res[27] = fma52hi(res[27], a[2], a[24]); // Sum(26) + res[27] = fma52lo(res[27], a[3], a[24]); // Sum(27) + res[28] = fma52hi(res[28], a[3], a[24]); // Sum(27) + res[28] = fma52lo(res[28], a[4], a[24]); // Sum(28) + res[29] = fma52hi(res[29], a[4], a[24]); // Sum(28) + res[29] = fma52lo(res[29], a[5], a[24]); // Sum(29) + res[30] = fma52hi(res[30], a[5], a[24]); // Sum(29) + res[30] = fma52lo(res[30], a[6], a[24]); // Sum(30) + res[31] = fma52hi(res[31], a[6], a[24]); // Sum(30) + res[31] = fma52lo(res[31], a[7], a[24]); // Sum(31) + res[32] = fma52hi(res[32], a[7], a[24]); // Sum(31) + res[32] = fma52lo(res[32], a[8], a[24]); // Sum(32) + res[33] = fma52hi(res[33], a[8], a[24]); // Sum(32) + res[33] = fma52lo(res[33], a[9], a[24]); // Sum(33) + res[34] = fma52hi(res[34], a[9], a[24]); // Sum(33) + res[34] = fma52lo(res[34], a[10], a[24]); // Sum(34) + res[35] = fma52hi(res[35], a[10], a[24]); // Sum(34) + res[35] = fma52lo(res[35], a[11], a[24]); // Sum(35) + res[36] = fma52hi(res[36], a[11], a[24]); // Sum(35) + res[25] = fma52lo(res[25], a[0], a[25]); // Sum(25) + res[26] = fma52hi(res[26], a[0], a[25]); // Sum(25) + res[26] = fma52lo(res[26], a[1], a[25]); // Sum(26) + res[27] = fma52hi(res[27], a[1], a[25]); // Sum(26) + res[27] = fma52lo(res[27], a[2], a[25]); // Sum(27) + res[28] = fma52hi(res[28], a[2], a[25]); // Sum(27) + res[28] = fma52lo(res[28], a[3], a[25]); // Sum(28) + res[29] = fma52hi(res[29], a[3], a[25]); // Sum(28) + res[29] = fma52lo(res[29], a[4], a[25]); // Sum(29) + res[30] = fma52hi(res[30], a[4], a[25]); // Sum(29) + res[30] = fma52lo(res[30], a[5], a[25]); // Sum(30) + res[31] = fma52hi(res[31], a[5], a[25]); // Sum(30) + res[31] = fma52lo(res[31], a[6], a[25]); // Sum(31) + res[32] = fma52hi(res[32], a[6], a[25]); // Sum(31) + res[32] = fma52lo(res[32], a[7], a[25]); // Sum(32) + res[33] = fma52hi(res[33], a[7], a[25]); // Sum(32) + res[33] = fma52lo(res[33], a[8], a[25]); // Sum(33) + res[34] = fma52hi(res[34], a[8], a[25]); // Sum(33) + res[34] = fma52lo(res[34], a[9], a[25]); // Sum(34) + res[35] = fma52hi(res[35], a[9], a[25]); // Sum(34) + res[35] = fma52lo(res[35], a[10], a[25]); // Sum(35) + res[36] = fma52hi(res[36], a[10], a[25]); // Sum(35) + res[26] = fma52lo(res[26], a[0], a[26]); // Sum(26) + res[27] = fma52hi(res[27], a[0], a[26]); // Sum(26) + res[27] = fma52lo(res[27], a[1], a[26]); // Sum(27) + res[28] = fma52hi(res[28], a[1], a[26]); // Sum(27) + res[28] = fma52lo(res[28], a[2], a[26]); // Sum(28) + res[29] = fma52hi(res[29], a[2], a[26]); // Sum(28) + res[29] = fma52lo(res[29], a[3], a[26]); // Sum(29) + res[30] = fma52hi(res[30], a[3], a[26]); // Sum(29) + res[30] = fma52lo(res[30], a[4], a[26]); // Sum(30) + res[31] = fma52hi(res[31], a[4], a[26]); // Sum(30) + res[31] = fma52lo(res[31], a[5], a[26]); // Sum(31) + res[32] = fma52hi(res[32], a[5], a[26]); // Sum(31) + res[32] = fma52lo(res[32], a[6], a[26]); // Sum(32) + res[33] = fma52hi(res[33], a[6], a[26]); // Sum(32) + res[33] = fma52lo(res[33], a[7], a[26]); // Sum(33) + res[34] = fma52hi(res[34], a[7], a[26]); // Sum(33) + res[34] = fma52lo(res[34], a[8], a[26]); // Sum(34) + res[35] = fma52hi(res[35], a[8], a[26]); // Sum(34) + res[35] = fma52lo(res[35], a[9], a[26]); // Sum(35) + res[36] = fma52hi(res[36], a[9], a[26]); // Sum(35) + res[27] = fma52lo(res[27], a[0], a[27]); // Sum(27) + res[28] = fma52hi(res[28], a[0], a[27]); // Sum(27) + res[28] = fma52lo(res[28], a[1], a[27]); // Sum(28) + res[29] = fma52hi(res[29], a[1], a[27]); // Sum(28) + res[29] = fma52lo(res[29], a[2], a[27]); // Sum(29) + res[30] = fma52hi(res[30], a[2], a[27]); // Sum(29) + res[30] = fma52lo(res[30], a[3], a[27]); // Sum(30) + res[31] = fma52hi(res[31], a[3], a[27]); // Sum(30) + res[31] = fma52lo(res[31], a[4], a[27]); // Sum(31) + res[32] = fma52hi(res[32], a[4], a[27]); // Sum(31) + res[32] = fma52lo(res[32], a[5], a[27]); // Sum(32) + res[33] = fma52hi(res[33], a[5], a[27]); // Sum(32) + res[33] = fma52lo(res[33], a[6], a[27]); // Sum(33) + res[34] = fma52hi(res[34], a[6], a[27]); // Sum(33) + res[34] = fma52lo(res[34], a[7], a[27]); // Sum(34) + res[35] = fma52hi(res[35], a[7], a[27]); // Sum(34) + res[35] = fma52lo(res[35], a[8], a[27]); // Sum(35) + res[36] = fma52hi(res[36], a[8], a[27]); // Sum(35) + res[28] = fma52lo(res[28], a[0], a[28]); // Sum(28) + res[29] = fma52hi(res[29], a[0], a[28]); // Sum(28) + res[29] = fma52lo(res[29], a[1], a[28]); // Sum(29) + res[30] = fma52hi(res[30], a[1], a[28]); // Sum(29) + res[30] = fma52lo(res[30], a[2], a[28]); // Sum(30) + res[31] = fma52hi(res[31], a[2], a[28]); // Sum(30) + res[31] = fma52lo(res[31], a[3], a[28]); // Sum(31) + res[32] = fma52hi(res[32], a[3], a[28]); // Sum(31) + res[32] = fma52lo(res[32], a[4], a[28]); // Sum(32) + res[33] = fma52hi(res[33], a[4], a[28]); // Sum(32) + res[33] = fma52lo(res[33], a[5], a[28]); // Sum(33) + res[34] = fma52hi(res[34], a[5], a[28]); // Sum(33) + res[34] = fma52lo(res[34], a[6], a[28]); // Sum(34) + res[35] = fma52hi(res[35], a[6], a[28]); // Sum(34) + res[35] = fma52lo(res[35], a[7], a[28]); // Sum(35) + res[36] = fma52hi(res[36], a[7], a[28]); // Sum(35) + res[29] = fma52lo(res[29], a[0], a[29]); // Sum(29) + res[30] = fma52hi(res[30], a[0], a[29]); // Sum(29) + res[30] = fma52lo(res[30], a[1], a[29]); // Sum(30) + res[31] = fma52hi(res[31], a[1], a[29]); // Sum(30) + res[31] = fma52lo(res[31], a[2], a[29]); // Sum(31) + res[32] = fma52hi(res[32], a[2], a[29]); // Sum(31) + res[32] = fma52lo(res[32], a[3], a[29]); // Sum(32) + res[33] = fma52hi(res[33], a[3], a[29]); // Sum(32) + res[33] = fma52lo(res[33], a[4], a[29]); // Sum(33) + res[34] = fma52hi(res[34], a[4], a[29]); // Sum(33) + res[34] = fma52lo(res[34], a[5], a[29]); // Sum(34) + res[35] = fma52hi(res[35], a[5], a[29]); // Sum(34) + res[35] = fma52lo(res[35], a[6], a[29]); // Sum(35) + res[36] = fma52hi(res[36], a[6], a[29]); // Sum(35) + res[30] = fma52lo(res[30], a[0], a[30]); // Sum(30) + res[31] = fma52hi(res[31], a[0], a[30]); // Sum(30) + res[31] = fma52lo(res[31], a[1], a[30]); // Sum(31) + res[32] = fma52hi(res[32], a[1], a[30]); // Sum(31) + res[32] = fma52lo(res[32], a[2], a[30]); // Sum(32) + res[33] = fma52hi(res[33], a[2], a[30]); // Sum(32) + res[33] = fma52lo(res[33], a[3], a[30]); // Sum(33) + res[34] = fma52hi(res[34], a[3], a[30]); // Sum(33) + res[34] = fma52lo(res[34], a[4], a[30]); // Sum(34) + res[35] = fma52hi(res[35], a[4], a[30]); // Sum(34) + res[35] = fma52lo(res[35], a[5], a[30]); // Sum(35) + res[36] = fma52hi(res[36], a[5], a[30]); // Sum(35) + res[31] = fma52lo(res[31], a[0], a[31]); // Sum(31) + res[32] = fma52hi(res[32], a[0], a[31]); // Sum(31) + res[32] = fma52lo(res[32], a[1], a[31]); // Sum(32) + res[33] = fma52hi(res[33], a[1], a[31]); // Sum(32) + res[33] = fma52lo(res[33], a[2], a[31]); // Sum(33) + res[34] = fma52hi(res[34], a[2], a[31]); // Sum(33) + res[34] = fma52lo(res[34], a[3], a[31]); // Sum(34) + res[35] = fma52hi(res[35], a[3], a[31]); // Sum(34) + res[35] = fma52lo(res[35], a[4], a[31]); // Sum(35) + res[36] = fma52hi(res[36], a[4], a[31]); // Sum(35) + res[32] = fma52lo(res[32], a[0], a[32]); // Sum(32) + res[33] = fma52hi(res[33], a[0], a[32]); // Sum(32) + res[33] = fma52lo(res[33], a[1], a[32]); // Sum(33) + res[34] = fma52hi(res[34], a[1], a[32]); // Sum(33) + res[34] = fma52lo(res[34], a[2], a[32]); // Sum(34) + res[35] = fma52hi(res[35], a[2], a[32]); // Sum(34) + res[35] = fma52lo(res[35], a[3], a[32]); // Sum(35) + res[36] = fma52hi(res[36], a[3], a[32]); // Sum(35) + res[33] = fma52lo(res[33], a[0], a[33]); // Sum(33) + res[34] = fma52hi(res[34], a[0], a[33]); // Sum(33) + res[34] = fma52lo(res[34], a[1], a[33]); // Sum(34) + res[35] = fma52hi(res[35], a[1], a[33]); // Sum(34) + res[35] = fma52lo(res[35], a[2], a[33]); // Sum(35) + res[36] = fma52hi(res[36], a[2], a[33]); // Sum(35) + res[34] = fma52lo(res[34], a[0], a[34]); // Sum(34) + res[35] = fma52hi(res[35], a[0], a[34]); // Sum(34) + res[35] = fma52lo(res[35], a[1], a[34]); // Sum(35) + res[36] = fma52hi(res[36], a[1], a[34]); // Sum(35) + res[35] = fma52lo(res[35], a[0], a[35]); // Sum(35) + res[36] = fma52hi(res[36], a[0], a[35]); // Sum(35) + res[24] = add64(res[24], res[24]); // Double(24) + res[25] = add64(res[25], res[25]); // Double(25) + res[26] = add64(res[26], res[26]); // Double(26) + res[27] = add64(res[27], res[27]); // Double(27) + res[28] = add64(res[28], res[28]); // Double(28) + res[29] = add64(res[29], res[29]); // Double(29) + res[30] = add64(res[30], res[30]); // Double(30) + res[31] = add64(res[31], res[31]); // Double(31) + res[32] = add64(res[32], res[32]); // Double(32) + res[33] = add64(res[33], res[33]); // Double(33) + res[34] = add64(res[34], res[34]); // Double(34) + res[35] = add64(res[35], res[35]); // Double(35) + res[24] = fma52lo(res[24], a[12], a[12]); // Add sqr(24) + res[25] = fma52hi(res[25], a[12], a[12]); // Add sqr(24) + res[26] = fma52lo(res[26], a[13], a[13]); // Add sqr(26) + res[27] = fma52hi(res[27], a[13], a[13]); // Add sqr(26) + res[28] = fma52lo(res[28], a[14], a[14]); // Add sqr(28) + res[29] = fma52hi(res[29], a[14], a[14]); // Add sqr(28) + res[30] = fma52lo(res[30], a[15], a[15]); // Add sqr(30) + res[31] = fma52hi(res[31], a[15], a[15]); // Add sqr(30) + res[32] = fma52lo(res[32], a[16], a[16]); // Add sqr(32) + res[33] = fma52hi(res[33], a[16], a[16]); // Add sqr(32) + res[34] = fma52lo(res[34], a[17], a[17]); // Add sqr(34) + res[35] = fma52hi(res[35], a[17], a[17]); // Add sqr(34) + res[36] = fma52lo(res[36], a[17], a[19]); // Sum(36) + res[37] = fma52hi(res[37], a[17], a[19]); // Sum(36) + res[37] = fma52lo(res[37], a[18], a[19]); // Sum(37) + res[38] = fma52hi(res[38], a[18], a[19]); // Sum(37) + res[36] = fma52lo(res[36], a[16], a[20]); // Sum(36) + res[37] = fma52hi(res[37], a[16], a[20]); // Sum(36) + res[37] = fma52lo(res[37], a[17], a[20]); // Sum(37) + res[38] = fma52hi(res[38], a[17], a[20]); // Sum(37) + res[38] = fma52lo(res[38], a[18], a[20]); // Sum(38) + res[39] = fma52hi(res[39], a[18], a[20]); // Sum(38) + res[39] = fma52lo(res[39], a[19], a[20]); // Sum(39) + res[40] = fma52hi(res[40], a[19], a[20]); // Sum(39) + res[36] = fma52lo(res[36], a[15], a[21]); // Sum(36) + res[37] = fma52hi(res[37], a[15], a[21]); // Sum(36) + res[37] = fma52lo(res[37], a[16], a[21]); // Sum(37) + res[38] = fma52hi(res[38], a[16], a[21]); // Sum(37) + res[38] = fma52lo(res[38], a[17], a[21]); // Sum(38) + res[39] = fma52hi(res[39], a[17], a[21]); // Sum(38) + res[39] = fma52lo(res[39], a[18], a[21]); // Sum(39) + res[40] = fma52hi(res[40], a[18], a[21]); // Sum(39) + res[40] = fma52lo(res[40], a[19], a[21]); // Sum(40) + res[41] = fma52hi(res[41], a[19], a[21]); // Sum(40) + res[41] = fma52lo(res[41], a[20], a[21]); // Sum(41) + res[42] = fma52hi(res[42], a[20], a[21]); // Sum(41) + res[36] = fma52lo(res[36], a[14], a[22]); // Sum(36) + res[37] = fma52hi(res[37], a[14], a[22]); // Sum(36) + res[37] = fma52lo(res[37], a[15], a[22]); // Sum(37) + res[38] = fma52hi(res[38], a[15], a[22]); // Sum(37) + res[38] = fma52lo(res[38], a[16], a[22]); // Sum(38) + res[39] = fma52hi(res[39], a[16], a[22]); // Sum(38) + res[39] = fma52lo(res[39], a[17], a[22]); // Sum(39) + res[40] = fma52hi(res[40], a[17], a[22]); // Sum(39) + res[40] = fma52lo(res[40], a[18], a[22]); // Sum(40) + res[41] = fma52hi(res[41], a[18], a[22]); // Sum(40) + res[41] = fma52lo(res[41], a[19], a[22]); // Sum(41) + res[42] = fma52hi(res[42], a[19], a[22]); // Sum(41) + res[42] = fma52lo(res[42], a[20], a[22]); // Sum(42) + res[43] = fma52hi(res[43], a[20], a[22]); // Sum(42) + res[43] = fma52lo(res[43], a[21], a[22]); // Sum(43) + res[44] = fma52hi(res[44], a[21], a[22]); // Sum(43) + res[36] = fma52lo(res[36], a[13], a[23]); // Sum(36) + res[37] = fma52hi(res[37], a[13], a[23]); // Sum(36) + res[37] = fma52lo(res[37], a[14], a[23]); // Sum(37) + res[38] = fma52hi(res[38], a[14], a[23]); // Sum(37) + res[38] = fma52lo(res[38], a[15], a[23]); // Sum(38) + res[39] = fma52hi(res[39], a[15], a[23]); // Sum(38) + res[39] = fma52lo(res[39], a[16], a[23]); // Sum(39) + res[40] = fma52hi(res[40], a[16], a[23]); // Sum(39) + res[40] = fma52lo(res[40], a[17], a[23]); // Sum(40) + res[41] = fma52hi(res[41], a[17], a[23]); // Sum(40) + res[41] = fma52lo(res[41], a[18], a[23]); // Sum(41) + res[42] = fma52hi(res[42], a[18], a[23]); // Sum(41) + res[42] = fma52lo(res[42], a[19], a[23]); // Sum(42) + res[43] = fma52hi(res[43], a[19], a[23]); // Sum(42) + res[43] = fma52lo(res[43], a[20], a[23]); // Sum(43) + res[44] = fma52hi(res[44], a[20], a[23]); // Sum(43) + res[44] = fma52lo(res[44], a[21], a[23]); // Sum(44) + res[45] = fma52hi(res[45], a[21], a[23]); // Sum(44) + res[45] = fma52lo(res[45], a[22], a[23]); // Sum(45) + res[46] = fma52hi(res[46], a[22], a[23]); // Sum(45) + res[36] = fma52lo(res[36], a[12], a[24]); // Sum(36) + res[37] = fma52hi(res[37], a[12], a[24]); // Sum(36) + res[37] = fma52lo(res[37], a[13], a[24]); // Sum(37) + res[38] = fma52hi(res[38], a[13], a[24]); // Sum(37) + res[38] = fma52lo(res[38], a[14], a[24]); // Sum(38) + res[39] = fma52hi(res[39], a[14], a[24]); // Sum(38) + res[39] = fma52lo(res[39], a[15], a[24]); // Sum(39) + res[40] = fma52hi(res[40], a[15], a[24]); // Sum(39) + res[40] = fma52lo(res[40], a[16], a[24]); // Sum(40) + res[41] = fma52hi(res[41], a[16], a[24]); // Sum(40) + res[41] = fma52lo(res[41], a[17], a[24]); // Sum(41) + res[42] = fma52hi(res[42], a[17], a[24]); // Sum(41) + res[42] = fma52lo(res[42], a[18], a[24]); // Sum(42) + res[43] = fma52hi(res[43], a[18], a[24]); // Sum(42) + res[43] = fma52lo(res[43], a[19], a[24]); // Sum(43) + res[44] = fma52hi(res[44], a[19], a[24]); // Sum(43) + res[44] = fma52lo(res[44], a[20], a[24]); // Sum(44) + res[45] = fma52hi(res[45], a[20], a[24]); // Sum(44) + res[45] = fma52lo(res[45], a[21], a[24]); // Sum(45) + res[46] = fma52hi(res[46], a[21], a[24]); // Sum(45) + res[46] = fma52lo(res[46], a[22], a[24]); // Sum(46) + res[47] = fma52hi(res[47], a[22], a[24]); // Sum(46) + res[47] = fma52lo(res[47], a[23], a[24]); // Sum(47) + res[48] = fma52hi(res[48], a[23], a[24]); // Sum(47) + res[36] = fma52lo(res[36], a[11], a[25]); // Sum(36) + res[37] = fma52hi(res[37], a[11], a[25]); // Sum(36) + res[37] = fma52lo(res[37], a[12], a[25]); // Sum(37) + res[38] = fma52hi(res[38], a[12], a[25]); // Sum(37) + res[38] = fma52lo(res[38], a[13], a[25]); // Sum(38) + res[39] = fma52hi(res[39], a[13], a[25]); // Sum(38) + res[39] = fma52lo(res[39], a[14], a[25]); // Sum(39) + res[40] = fma52hi(res[40], a[14], a[25]); // Sum(39) + res[40] = fma52lo(res[40], a[15], a[25]); // Sum(40) + res[41] = fma52hi(res[41], a[15], a[25]); // Sum(40) + res[41] = fma52lo(res[41], a[16], a[25]); // Sum(41) + res[42] = fma52hi(res[42], a[16], a[25]); // Sum(41) + res[42] = fma52lo(res[42], a[17], a[25]); // Sum(42) + res[43] = fma52hi(res[43], a[17], a[25]); // Sum(42) + res[43] = fma52lo(res[43], a[18], a[25]); // Sum(43) + res[44] = fma52hi(res[44], a[18], a[25]); // Sum(43) + res[44] = fma52lo(res[44], a[19], a[25]); // Sum(44) + res[45] = fma52hi(res[45], a[19], a[25]); // Sum(44) + res[45] = fma52lo(res[45], a[20], a[25]); // Sum(45) + res[46] = fma52hi(res[46], a[20], a[25]); // Sum(45) + res[46] = fma52lo(res[46], a[21], a[25]); // Sum(46) + res[47] = fma52hi(res[47], a[21], a[25]); // Sum(46) + res[47] = fma52lo(res[47], a[22], a[25]); // Sum(47) + res[48] = fma52hi(res[48], a[22], a[25]); // Sum(47) + res[36] = fma52lo(res[36], a[10], a[26]); // Sum(36) + res[37] = fma52hi(res[37], a[10], a[26]); // Sum(36) + res[37] = fma52lo(res[37], a[11], a[26]); // Sum(37) + res[38] = fma52hi(res[38], a[11], a[26]); // Sum(37) + res[38] = fma52lo(res[38], a[12], a[26]); // Sum(38) + res[39] = fma52hi(res[39], a[12], a[26]); // Sum(38) + res[39] = fma52lo(res[39], a[13], a[26]); // Sum(39) + res[40] = fma52hi(res[40], a[13], a[26]); // Sum(39) + res[40] = fma52lo(res[40], a[14], a[26]); // Sum(40) + res[41] = fma52hi(res[41], a[14], a[26]); // Sum(40) + res[41] = fma52lo(res[41], a[15], a[26]); // Sum(41) + res[42] = fma52hi(res[42], a[15], a[26]); // Sum(41) + res[42] = fma52lo(res[42], a[16], a[26]); // Sum(42) + res[43] = fma52hi(res[43], a[16], a[26]); // Sum(42) + res[43] = fma52lo(res[43], a[17], a[26]); // Sum(43) + res[44] = fma52hi(res[44], a[17], a[26]); // Sum(43) + res[44] = fma52lo(res[44], a[18], a[26]); // Sum(44) + res[45] = fma52hi(res[45], a[18], a[26]); // Sum(44) + res[45] = fma52lo(res[45], a[19], a[26]); // Sum(45) + res[46] = fma52hi(res[46], a[19], a[26]); // Sum(45) + res[46] = fma52lo(res[46], a[20], a[26]); // Sum(46) + res[47] = fma52hi(res[47], a[20], a[26]); // Sum(46) + res[47] = fma52lo(res[47], a[21], a[26]); // Sum(47) + res[48] = fma52hi(res[48], a[21], a[26]); // Sum(47) + res[36] = fma52lo(res[36], a[9], a[27]); // Sum(36) + res[37] = fma52hi(res[37], a[9], a[27]); // Sum(36) + res[37] = fma52lo(res[37], a[10], a[27]); // Sum(37) + res[38] = fma52hi(res[38], a[10], a[27]); // Sum(37) + res[38] = fma52lo(res[38], a[11], a[27]); // Sum(38) + res[39] = fma52hi(res[39], a[11], a[27]); // Sum(38) + res[39] = fma52lo(res[39], a[12], a[27]); // Sum(39) + res[40] = fma52hi(res[40], a[12], a[27]); // Sum(39) + res[40] = fma52lo(res[40], a[13], a[27]); // Sum(40) + res[41] = fma52hi(res[41], a[13], a[27]); // Sum(40) + res[41] = fma52lo(res[41], a[14], a[27]); // Sum(41) + res[42] = fma52hi(res[42], a[14], a[27]); // Sum(41) + res[42] = fma52lo(res[42], a[15], a[27]); // Sum(42) + res[43] = fma52hi(res[43], a[15], a[27]); // Sum(42) + res[43] = fma52lo(res[43], a[16], a[27]); // Sum(43) + res[44] = fma52hi(res[44], a[16], a[27]); // Sum(43) + res[44] = fma52lo(res[44], a[17], a[27]); // Sum(44) + res[45] = fma52hi(res[45], a[17], a[27]); // Sum(44) + res[45] = fma52lo(res[45], a[18], a[27]); // Sum(45) + res[46] = fma52hi(res[46], a[18], a[27]); // Sum(45) + res[46] = fma52lo(res[46], a[19], a[27]); // Sum(46) + res[47] = fma52hi(res[47], a[19], a[27]); // Sum(46) + res[47] = fma52lo(res[47], a[20], a[27]); // Sum(47) + res[48] = fma52hi(res[48], a[20], a[27]); // Sum(47) + res[36] = fma52lo(res[36], a[8], a[28]); // Sum(36) + res[37] = fma52hi(res[37], a[8], a[28]); // Sum(36) + res[37] = fma52lo(res[37], a[9], a[28]); // Sum(37) + res[38] = fma52hi(res[38], a[9], a[28]); // Sum(37) + res[38] = fma52lo(res[38], a[10], a[28]); // Sum(38) + res[39] = fma52hi(res[39], a[10], a[28]); // Sum(38) + res[39] = fma52lo(res[39], a[11], a[28]); // Sum(39) + res[40] = fma52hi(res[40], a[11], a[28]); // Sum(39) + res[40] = fma52lo(res[40], a[12], a[28]); // Sum(40) + res[41] = fma52hi(res[41], a[12], a[28]); // Sum(40) + res[41] = fma52lo(res[41], a[13], a[28]); // Sum(41) + res[42] = fma52hi(res[42], a[13], a[28]); // Sum(41) + res[42] = fma52lo(res[42], a[14], a[28]); // Sum(42) + res[43] = fma52hi(res[43], a[14], a[28]); // Sum(42) + res[43] = fma52lo(res[43], a[15], a[28]); // Sum(43) + res[44] = fma52hi(res[44], a[15], a[28]); // Sum(43) + res[44] = fma52lo(res[44], a[16], a[28]); // Sum(44) + res[45] = fma52hi(res[45], a[16], a[28]); // Sum(44) + res[45] = fma52lo(res[45], a[17], a[28]); // Sum(45) + res[46] = fma52hi(res[46], a[17], a[28]); // Sum(45) + res[46] = fma52lo(res[46], a[18], a[28]); // Sum(46) + res[47] = fma52hi(res[47], a[18], a[28]); // Sum(46) + res[47] = fma52lo(res[47], a[19], a[28]); // Sum(47) + res[48] = fma52hi(res[48], a[19], a[28]); // Sum(47) + res[36] = fma52lo(res[36], a[7], a[29]); // Sum(36) + res[37] = fma52hi(res[37], a[7], a[29]); // Sum(36) + res[37] = fma52lo(res[37], a[8], a[29]); // Sum(37) + res[38] = fma52hi(res[38], a[8], a[29]); // Sum(37) + res[38] = fma52lo(res[38], a[9], a[29]); // Sum(38) + res[39] = fma52hi(res[39], a[9], a[29]); // Sum(38) + res[39] = fma52lo(res[39], a[10], a[29]); // Sum(39) + res[40] = fma52hi(res[40], a[10], a[29]); // Sum(39) + res[40] = fma52lo(res[40], a[11], a[29]); // Sum(40) + res[41] = fma52hi(res[41], a[11], a[29]); // Sum(40) + res[41] = fma52lo(res[41], a[12], a[29]); // Sum(41) + res[42] = fma52hi(res[42], a[12], a[29]); // Sum(41) + res[42] = fma52lo(res[42], a[13], a[29]); // Sum(42) + res[43] = fma52hi(res[43], a[13], a[29]); // Sum(42) + res[43] = fma52lo(res[43], a[14], a[29]); // Sum(43) + res[44] = fma52hi(res[44], a[14], a[29]); // Sum(43) + res[44] = fma52lo(res[44], a[15], a[29]); // Sum(44) + res[45] = fma52hi(res[45], a[15], a[29]); // Sum(44) + res[45] = fma52lo(res[45], a[16], a[29]); // Sum(45) + res[46] = fma52hi(res[46], a[16], a[29]); // Sum(45) + res[46] = fma52lo(res[46], a[17], a[29]); // Sum(46) + res[47] = fma52hi(res[47], a[17], a[29]); // Sum(46) + res[47] = fma52lo(res[47], a[18], a[29]); // Sum(47) + res[48] = fma52hi(res[48], a[18], a[29]); // Sum(47) + res[36] = fma52lo(res[36], a[6], a[30]); // Sum(36) + res[37] = fma52hi(res[37], a[6], a[30]); // Sum(36) + res[37] = fma52lo(res[37], a[7], a[30]); // Sum(37) + res[38] = fma52hi(res[38], a[7], a[30]); // Sum(37) + res[38] = fma52lo(res[38], a[8], a[30]); // Sum(38) + res[39] = fma52hi(res[39], a[8], a[30]); // Sum(38) + res[39] = fma52lo(res[39], a[9], a[30]); // Sum(39) + res[40] = fma52hi(res[40], a[9], a[30]); // Sum(39) + res[40] = fma52lo(res[40], a[10], a[30]); // Sum(40) + res[41] = fma52hi(res[41], a[10], a[30]); // Sum(40) + res[41] = fma52lo(res[41], a[11], a[30]); // Sum(41) + res[42] = fma52hi(res[42], a[11], a[30]); // Sum(41) + res[42] = fma52lo(res[42], a[12], a[30]); // Sum(42) + res[43] = fma52hi(res[43], a[12], a[30]); // Sum(42) + res[43] = fma52lo(res[43], a[13], a[30]); // Sum(43) + res[44] = fma52hi(res[44], a[13], a[30]); // Sum(43) + res[44] = fma52lo(res[44], a[14], a[30]); // Sum(44) + res[45] = fma52hi(res[45], a[14], a[30]); // Sum(44) + res[45] = fma52lo(res[45], a[15], a[30]); // Sum(45) + res[46] = fma52hi(res[46], a[15], a[30]); // Sum(45) + res[46] = fma52lo(res[46], a[16], a[30]); // Sum(46) + res[47] = fma52hi(res[47], a[16], a[30]); // Sum(46) + res[47] = fma52lo(res[47], a[17], a[30]); // Sum(47) + res[48] = fma52hi(res[48], a[17], a[30]); // Sum(47) + res[36] = fma52lo(res[36], a[5], a[31]); // Sum(36) + res[37] = fma52hi(res[37], a[5], a[31]); // Sum(36) + res[37] = fma52lo(res[37], a[6], a[31]); // Sum(37) + res[38] = fma52hi(res[38], a[6], a[31]); // Sum(37) + res[38] = fma52lo(res[38], a[7], a[31]); // Sum(38) + res[39] = fma52hi(res[39], a[7], a[31]); // Sum(38) + res[39] = fma52lo(res[39], a[8], a[31]); // Sum(39) + res[40] = fma52hi(res[40], a[8], a[31]); // Sum(39) + res[40] = fma52lo(res[40], a[9], a[31]); // Sum(40) + res[41] = fma52hi(res[41], a[9], a[31]); // Sum(40) + res[41] = fma52lo(res[41], a[10], a[31]); // Sum(41) + res[42] = fma52hi(res[42], a[10], a[31]); // Sum(41) + res[42] = fma52lo(res[42], a[11], a[31]); // Sum(42) + res[43] = fma52hi(res[43], a[11], a[31]); // Sum(42) + res[43] = fma52lo(res[43], a[12], a[31]); // Sum(43) + res[44] = fma52hi(res[44], a[12], a[31]); // Sum(43) + res[44] = fma52lo(res[44], a[13], a[31]); // Sum(44) + res[45] = fma52hi(res[45], a[13], a[31]); // Sum(44) + res[45] = fma52lo(res[45], a[14], a[31]); // Sum(45) + res[46] = fma52hi(res[46], a[14], a[31]); // Sum(45) + res[46] = fma52lo(res[46], a[15], a[31]); // Sum(46) + res[47] = fma52hi(res[47], a[15], a[31]); // Sum(46) + res[47] = fma52lo(res[47], a[16], a[31]); // Sum(47) + res[48] = fma52hi(res[48], a[16], a[31]); // Sum(47) + res[36] = fma52lo(res[36], a[4], a[32]); // Sum(36) + res[37] = fma52hi(res[37], a[4], a[32]); // Sum(36) + res[37] = fma52lo(res[37], a[5], a[32]); // Sum(37) + res[38] = fma52hi(res[38], a[5], a[32]); // Sum(37) + res[38] = fma52lo(res[38], a[6], a[32]); // Sum(38) + res[39] = fma52hi(res[39], a[6], a[32]); // Sum(38) + res[39] = fma52lo(res[39], a[7], a[32]); // Sum(39) + res[40] = fma52hi(res[40], a[7], a[32]); // Sum(39) + res[40] = fma52lo(res[40], a[8], a[32]); // Sum(40) + res[41] = fma52hi(res[41], a[8], a[32]); // Sum(40) + res[41] = fma52lo(res[41], a[9], a[32]); // Sum(41) + res[42] = fma52hi(res[42], a[9], a[32]); // Sum(41) + res[42] = fma52lo(res[42], a[10], a[32]); // Sum(42) + res[43] = fma52hi(res[43], a[10], a[32]); // Sum(42) + res[43] = fma52lo(res[43], a[11], a[32]); // Sum(43) + res[44] = fma52hi(res[44], a[11], a[32]); // Sum(43) + res[44] = fma52lo(res[44], a[12], a[32]); // Sum(44) + res[45] = fma52hi(res[45], a[12], a[32]); // Sum(44) + res[45] = fma52lo(res[45], a[13], a[32]); // Sum(45) + res[46] = fma52hi(res[46], a[13], a[32]); // Sum(45) + res[46] = fma52lo(res[46], a[14], a[32]); // Sum(46) + res[47] = fma52hi(res[47], a[14], a[32]); // Sum(46) + res[47] = fma52lo(res[47], a[15], a[32]); // Sum(47) + res[48] = fma52hi(res[48], a[15], a[32]); // Sum(47) + res[36] = fma52lo(res[36], a[3], a[33]); // Sum(36) + res[37] = fma52hi(res[37], a[3], a[33]); // Sum(36) + res[37] = fma52lo(res[37], a[4], a[33]); // Sum(37) + res[38] = fma52hi(res[38], a[4], a[33]); // Sum(37) + res[38] = fma52lo(res[38], a[5], a[33]); // Sum(38) + res[39] = fma52hi(res[39], a[5], a[33]); // Sum(38) + res[39] = fma52lo(res[39], a[6], a[33]); // Sum(39) + res[40] = fma52hi(res[40], a[6], a[33]); // Sum(39) + res[40] = fma52lo(res[40], a[7], a[33]); // Sum(40) + res[41] = fma52hi(res[41], a[7], a[33]); // Sum(40) + res[41] = fma52lo(res[41], a[8], a[33]); // Sum(41) + res[42] = fma52hi(res[42], a[8], a[33]); // Sum(41) + res[42] = fma52lo(res[42], a[9], a[33]); // Sum(42) + res[43] = fma52hi(res[43], a[9], a[33]); // Sum(42) + res[43] = fma52lo(res[43], a[10], a[33]); // Sum(43) + res[44] = fma52hi(res[44], a[10], a[33]); // Sum(43) + res[44] = fma52lo(res[44], a[11], a[33]); // Sum(44) + res[45] = fma52hi(res[45], a[11], a[33]); // Sum(44) + res[45] = fma52lo(res[45], a[12], a[33]); // Sum(45) + res[46] = fma52hi(res[46], a[12], a[33]); // Sum(45) + res[46] = fma52lo(res[46], a[13], a[33]); // Sum(46) + res[47] = fma52hi(res[47], a[13], a[33]); // Sum(46) + res[47] = fma52lo(res[47], a[14], a[33]); // Sum(47) + res[48] = fma52hi(res[48], a[14], a[33]); // Sum(47) + res[36] = fma52lo(res[36], a[2], a[34]); // Sum(36) + res[37] = fma52hi(res[37], a[2], a[34]); // Sum(36) + res[37] = fma52lo(res[37], a[3], a[34]); // Sum(37) + res[38] = fma52hi(res[38], a[3], a[34]); // Sum(37) + res[38] = fma52lo(res[38], a[4], a[34]); // Sum(38) + res[39] = fma52hi(res[39], a[4], a[34]); // Sum(38) + res[39] = fma52lo(res[39], a[5], a[34]); // Sum(39) + res[40] = fma52hi(res[40], a[5], a[34]); // Sum(39) + res[40] = fma52lo(res[40], a[6], a[34]); // Sum(40) + res[41] = fma52hi(res[41], a[6], a[34]); // Sum(40) + res[41] = fma52lo(res[41], a[7], a[34]); // Sum(41) + res[42] = fma52hi(res[42], a[7], a[34]); // Sum(41) + res[42] = fma52lo(res[42], a[8], a[34]); // Sum(42) + res[43] = fma52hi(res[43], a[8], a[34]); // Sum(42) + res[43] = fma52lo(res[43], a[9], a[34]); // Sum(43) + res[44] = fma52hi(res[44], a[9], a[34]); // Sum(43) + res[44] = fma52lo(res[44], a[10], a[34]); // Sum(44) + res[45] = fma52hi(res[45], a[10], a[34]); // Sum(44) + res[45] = fma52lo(res[45], a[11], a[34]); // Sum(45) + res[46] = fma52hi(res[46], a[11], a[34]); // Sum(45) + res[46] = fma52lo(res[46], a[12], a[34]); // Sum(46) + res[47] = fma52hi(res[47], a[12], a[34]); // Sum(46) + res[47] = fma52lo(res[47], a[13], a[34]); // Sum(47) + res[48] = fma52hi(res[48], a[13], a[34]); // Sum(47) + res[36] = fma52lo(res[36], a[1], a[35]); // Sum(36) + res[37] = fma52hi(res[37], a[1], a[35]); // Sum(36) + res[37] = fma52lo(res[37], a[2], a[35]); // Sum(37) + res[38] = fma52hi(res[38], a[2], a[35]); // Sum(37) + res[38] = fma52lo(res[38], a[3], a[35]); // Sum(38) + res[39] = fma52hi(res[39], a[3], a[35]); // Sum(38) + res[39] = fma52lo(res[39], a[4], a[35]); // Sum(39) + res[40] = fma52hi(res[40], a[4], a[35]); // Sum(39) + res[40] = fma52lo(res[40], a[5], a[35]); // Sum(40) + res[41] = fma52hi(res[41], a[5], a[35]); // Sum(40) + res[41] = fma52lo(res[41], a[6], a[35]); // Sum(41) + res[42] = fma52hi(res[42], a[6], a[35]); // Sum(41) + res[42] = fma52lo(res[42], a[7], a[35]); // Sum(42) + res[43] = fma52hi(res[43], a[7], a[35]); // Sum(42) + res[43] = fma52lo(res[43], a[8], a[35]); // Sum(43) + res[44] = fma52hi(res[44], a[8], a[35]); // Sum(43) + res[44] = fma52lo(res[44], a[9], a[35]); // Sum(44) + res[45] = fma52hi(res[45], a[9], a[35]); // Sum(44) + res[45] = fma52lo(res[45], a[10], a[35]); // Sum(45) + res[46] = fma52hi(res[46], a[10], a[35]); // Sum(45) + res[46] = fma52lo(res[46], a[11], a[35]); // Sum(46) + res[47] = fma52hi(res[47], a[11], a[35]); // Sum(46) + res[47] = fma52lo(res[47], a[12], a[35]); // Sum(47) + res[48] = fma52hi(res[48], a[12], a[35]); // Sum(47) + res[36] = fma52lo(res[36], a[0], a[36]); // Sum(36) + res[37] = fma52hi(res[37], a[0], a[36]); // Sum(36) + res[37] = fma52lo(res[37], a[1], a[36]); // Sum(37) + res[38] = fma52hi(res[38], a[1], a[36]); // Sum(37) + res[38] = fma52lo(res[38], a[2], a[36]); // Sum(38) + res[39] = fma52hi(res[39], a[2], a[36]); // Sum(38) + res[39] = fma52lo(res[39], a[3], a[36]); // Sum(39) + res[40] = fma52hi(res[40], a[3], a[36]); // Sum(39) + res[40] = fma52lo(res[40], a[4], a[36]); // Sum(40) + res[41] = fma52hi(res[41], a[4], a[36]); // Sum(40) + res[41] = fma52lo(res[41], a[5], a[36]); // Sum(41) + res[42] = fma52hi(res[42], a[5], a[36]); // Sum(41) + res[42] = fma52lo(res[42], a[6], a[36]); // Sum(42) + res[43] = fma52hi(res[43], a[6], a[36]); // Sum(42) + res[43] = fma52lo(res[43], a[7], a[36]); // Sum(43) + res[44] = fma52hi(res[44], a[7], a[36]); // Sum(43) + res[44] = fma52lo(res[44], a[8], a[36]); // Sum(44) + res[45] = fma52hi(res[45], a[8], a[36]); // Sum(44) + res[45] = fma52lo(res[45], a[9], a[36]); // Sum(45) + res[46] = fma52hi(res[46], a[9], a[36]); // Sum(45) + res[46] = fma52lo(res[46], a[10], a[36]); // Sum(46) + res[47] = fma52hi(res[47], a[10], a[36]); // Sum(46) + res[47] = fma52lo(res[47], a[11], a[36]); // Sum(47) + res[48] = fma52hi(res[48], a[11], a[36]); // Sum(47) + res[37] = fma52lo(res[37], a[0], a[37]); // Sum(37) + res[38] = fma52hi(res[38], a[0], a[37]); // Sum(37) + res[38] = fma52lo(res[38], a[1], a[37]); // Sum(38) + res[39] = fma52hi(res[39], a[1], a[37]); // Sum(38) + res[39] = fma52lo(res[39], a[2], a[37]); // Sum(39) + res[40] = fma52hi(res[40], a[2], a[37]); // Sum(39) + res[40] = fma52lo(res[40], a[3], a[37]); // Sum(40) + res[41] = fma52hi(res[41], a[3], a[37]); // Sum(40) + res[41] = fma52lo(res[41], a[4], a[37]); // Sum(41) + res[42] = fma52hi(res[42], a[4], a[37]); // Sum(41) + res[42] = fma52lo(res[42], a[5], a[37]); // Sum(42) + res[43] = fma52hi(res[43], a[5], a[37]); // Sum(42) + res[43] = fma52lo(res[43], a[6], a[37]); // Sum(43) + res[44] = fma52hi(res[44], a[6], a[37]); // Sum(43) + res[44] = fma52lo(res[44], a[7], a[37]); // Sum(44) + res[45] = fma52hi(res[45], a[7], a[37]); // Sum(44) + res[45] = fma52lo(res[45], a[8], a[37]); // Sum(45) + res[46] = fma52hi(res[46], a[8], a[37]); // Sum(45) + res[46] = fma52lo(res[46], a[9], a[37]); // Sum(46) + res[47] = fma52hi(res[47], a[9], a[37]); // Sum(46) + res[47] = fma52lo(res[47], a[10], a[37]); // Sum(47) + res[48] = fma52hi(res[48], a[10], a[37]); // Sum(47) + res[38] = fma52lo(res[38], a[0], a[38]); // Sum(38) + res[39] = fma52hi(res[39], a[0], a[38]); // Sum(38) + res[39] = fma52lo(res[39], a[1], a[38]); // Sum(39) + res[40] = fma52hi(res[40], a[1], a[38]); // Sum(39) + res[40] = fma52lo(res[40], a[2], a[38]); // Sum(40) + res[41] = fma52hi(res[41], a[2], a[38]); // Sum(40) + res[41] = fma52lo(res[41], a[3], a[38]); // Sum(41) + res[42] = fma52hi(res[42], a[3], a[38]); // Sum(41) + res[42] = fma52lo(res[42], a[4], a[38]); // Sum(42) + res[43] = fma52hi(res[43], a[4], a[38]); // Sum(42) + res[43] = fma52lo(res[43], a[5], a[38]); // Sum(43) + res[44] = fma52hi(res[44], a[5], a[38]); // Sum(43) + res[44] = fma52lo(res[44], a[6], a[38]); // Sum(44) + res[45] = fma52hi(res[45], a[6], a[38]); // Sum(44) + res[45] = fma52lo(res[45], a[7], a[38]); // Sum(45) + res[46] = fma52hi(res[46], a[7], a[38]); // Sum(45) + res[46] = fma52lo(res[46], a[8], a[38]); // Sum(46) + res[47] = fma52hi(res[47], a[8], a[38]); // Sum(46) + res[47] = fma52lo(res[47], a[9], a[38]); // Sum(47) + res[48] = fma52hi(res[48], a[9], a[38]); // Sum(47) + res[39] = fma52lo(res[39], a[0], a[39]); // Sum(39) + res[40] = fma52hi(res[40], a[0], a[39]); // Sum(39) + res[40] = fma52lo(res[40], a[1], a[39]); // Sum(40) + res[41] = fma52hi(res[41], a[1], a[39]); // Sum(40) + res[41] = fma52lo(res[41], a[2], a[39]); // Sum(41) + res[42] = fma52hi(res[42], a[2], a[39]); // Sum(41) + res[42] = fma52lo(res[42], a[3], a[39]); // Sum(42) + res[43] = fma52hi(res[43], a[3], a[39]); // Sum(42) + res[43] = fma52lo(res[43], a[4], a[39]); // Sum(43) + res[44] = fma52hi(res[44], a[4], a[39]); // Sum(43) + res[44] = fma52lo(res[44], a[5], a[39]); // Sum(44) + res[45] = fma52hi(res[45], a[5], a[39]); // Sum(44) + res[45] = fma52lo(res[45], a[6], a[39]); // Sum(45) + res[46] = fma52hi(res[46], a[6], a[39]); // Sum(45) + res[46] = fma52lo(res[46], a[7], a[39]); // Sum(46) + res[47] = fma52hi(res[47], a[7], a[39]); // Sum(46) + res[47] = fma52lo(res[47], a[8], a[39]); // Sum(47) + res[48] = fma52hi(res[48], a[8], a[39]); // Sum(47) + res[40] = fma52lo(res[40], a[0], a[40]); // Sum(40) + res[41] = fma52hi(res[41], a[0], a[40]); // Sum(40) + res[41] = fma52lo(res[41], a[1], a[40]); // Sum(41) + res[42] = fma52hi(res[42], a[1], a[40]); // Sum(41) + res[42] = fma52lo(res[42], a[2], a[40]); // Sum(42) + res[43] = fma52hi(res[43], a[2], a[40]); // Sum(42) + res[43] = fma52lo(res[43], a[3], a[40]); // Sum(43) + res[44] = fma52hi(res[44], a[3], a[40]); // Sum(43) + res[44] = fma52lo(res[44], a[4], a[40]); // Sum(44) + res[45] = fma52hi(res[45], a[4], a[40]); // Sum(44) + res[45] = fma52lo(res[45], a[5], a[40]); // Sum(45) + res[46] = fma52hi(res[46], a[5], a[40]); // Sum(45) + res[46] = fma52lo(res[46], a[6], a[40]); // Sum(46) + res[47] = fma52hi(res[47], a[6], a[40]); // Sum(46) + res[47] = fma52lo(res[47], a[7], a[40]); // Sum(47) + res[48] = fma52hi(res[48], a[7], a[40]); // Sum(47) + res[41] = fma52lo(res[41], a[0], a[41]); // Sum(41) + res[42] = fma52hi(res[42], a[0], a[41]); // Sum(41) + res[42] = fma52lo(res[42], a[1], a[41]); // Sum(42) + res[43] = fma52hi(res[43], a[1], a[41]); // Sum(42) + res[43] = fma52lo(res[43], a[2], a[41]); // Sum(43) + res[44] = fma52hi(res[44], a[2], a[41]); // Sum(43) + res[44] = fma52lo(res[44], a[3], a[41]); // Sum(44) + res[45] = fma52hi(res[45], a[3], a[41]); // Sum(44) + res[45] = fma52lo(res[45], a[4], a[41]); // Sum(45) + res[46] = fma52hi(res[46], a[4], a[41]); // Sum(45) + res[46] = fma52lo(res[46], a[5], a[41]); // Sum(46) + res[47] = fma52hi(res[47], a[5], a[41]); // Sum(46) + res[47] = fma52lo(res[47], a[6], a[41]); // Sum(47) + res[48] = fma52hi(res[48], a[6], a[41]); // Sum(47) + res[42] = fma52lo(res[42], a[0], a[42]); // Sum(42) + res[43] = fma52hi(res[43], a[0], a[42]); // Sum(42) + res[43] = fma52lo(res[43], a[1], a[42]); // Sum(43) + res[44] = fma52hi(res[44], a[1], a[42]); // Sum(43) + res[44] = fma52lo(res[44], a[2], a[42]); // Sum(44) + res[45] = fma52hi(res[45], a[2], a[42]); // Sum(44) + res[45] = fma52lo(res[45], a[3], a[42]); // Sum(45) + res[46] = fma52hi(res[46], a[3], a[42]); // Sum(45) + res[46] = fma52lo(res[46], a[4], a[42]); // Sum(46) + res[47] = fma52hi(res[47], a[4], a[42]); // Sum(46) + res[47] = fma52lo(res[47], a[5], a[42]); // Sum(47) + res[48] = fma52hi(res[48], a[5], a[42]); // Sum(47) + res[43] = fma52lo(res[43], a[0], a[43]); // Sum(43) + res[44] = fma52hi(res[44], a[0], a[43]); // Sum(43) + res[44] = fma52lo(res[44], a[1], a[43]); // Sum(44) + res[45] = fma52hi(res[45], a[1], a[43]); // Sum(44) + res[45] = fma52lo(res[45], a[2], a[43]); // Sum(45) + res[46] = fma52hi(res[46], a[2], a[43]); // Sum(45) + res[46] = fma52lo(res[46], a[3], a[43]); // Sum(46) + res[47] = fma52hi(res[47], a[3], a[43]); // Sum(46) + res[47] = fma52lo(res[47], a[4], a[43]); // Sum(47) + res[48] = fma52hi(res[48], a[4], a[43]); // Sum(47) + res[44] = fma52lo(res[44], a[0], a[44]); // Sum(44) + res[45] = fma52hi(res[45], a[0], a[44]); // Sum(44) + res[45] = fma52lo(res[45], a[1], a[44]); // Sum(45) + res[46] = fma52hi(res[46], a[1], a[44]); // Sum(45) + res[46] = fma52lo(res[46], a[2], a[44]); // Sum(46) + res[47] = fma52hi(res[47], a[2], a[44]); // Sum(46) + res[47] = fma52lo(res[47], a[3], a[44]); // Sum(47) + res[48] = fma52hi(res[48], a[3], a[44]); // Sum(47) + res[45] = fma52lo(res[45], a[0], a[45]); // Sum(45) + res[46] = fma52hi(res[46], a[0], a[45]); // Sum(45) + res[46] = fma52lo(res[46], a[1], a[45]); // Sum(46) + res[47] = fma52hi(res[47], a[1], a[45]); // Sum(46) + res[47] = fma52lo(res[47], a[2], a[45]); // Sum(47) + res[48] = fma52hi(res[48], a[2], a[45]); // Sum(47) + res[46] = fma52lo(res[46], a[0], a[46]); // Sum(46) + res[47] = fma52hi(res[47], a[0], a[46]); // Sum(46) + res[47] = fma52lo(res[47], a[1], a[46]); // Sum(47) + res[48] = fma52hi(res[48], a[1], a[46]); // Sum(47) + res[47] = fma52lo(res[47], a[0], a[47]); // Sum(47) + res[48] = fma52hi(res[48], a[0], a[47]); // Sum(47) + res[36] = add64(res[36], res[36]); // Double(36) + res[37] = add64(res[37], res[37]); // Double(37) + res[38] = add64(res[38], res[38]); // Double(38) + res[39] = add64(res[39], res[39]); // Double(39) + res[40] = add64(res[40], res[40]); // Double(40) + res[41] = add64(res[41], res[41]); // Double(41) + res[42] = add64(res[42], res[42]); // Double(42) + res[43] = add64(res[43], res[43]); // Double(43) + res[44] = add64(res[44], res[44]); // Double(44) + res[45] = add64(res[45], res[45]); // Double(45) + res[46] = add64(res[46], res[46]); // Double(46) + res[47] = add64(res[47], res[47]); // Double(47) + res[36] = fma52lo(res[36], a[18], a[18]); // Add sqr(36) + res[37] = fma52hi(res[37], a[18], a[18]); // Add sqr(36) + res[38] = fma52lo(res[38], a[19], a[19]); // Add sqr(38) + res[39] = fma52hi(res[39], a[19], a[19]); // Add sqr(38) + res[40] = fma52lo(res[40], a[20], a[20]); // Add sqr(40) + res[41] = fma52hi(res[41], a[20], a[20]); // Add sqr(40) + res[42] = fma52lo(res[42], a[21], a[21]); // Add sqr(42) + res[43] = fma52hi(res[43], a[21], a[21]); // Add sqr(42) + res[44] = fma52lo(res[44], a[22], a[22]); // Add sqr(44) + res[45] = fma52hi(res[45], a[22], a[22]); // Add sqr(44) + res[46] = fma52lo(res[46], a[23], a[23]); // Add sqr(46) + res[47] = fma52hi(res[47], a[23], a[23]); // Add sqr(46) + res[48] = fma52lo(res[48], a[23], a[25]); // Sum(48) + res[49] = fma52hi(res[49], a[23], a[25]); // Sum(48) + res[49] = fma52lo(res[49], a[24], a[25]); // Sum(49) + res[50] = fma52hi(res[50], a[24], a[25]); // Sum(49) + res[48] = fma52lo(res[48], a[22], a[26]); // Sum(48) + res[49] = fma52hi(res[49], a[22], a[26]); // Sum(48) + res[49] = fma52lo(res[49], a[23], a[26]); // Sum(49) + res[50] = fma52hi(res[50], a[23], a[26]); // Sum(49) + res[50] = fma52lo(res[50], a[24], a[26]); // Sum(50) + res[51] = fma52hi(res[51], a[24], a[26]); // Sum(50) + res[51] = fma52lo(res[51], a[25], a[26]); // Sum(51) + res[52] = fma52hi(res[52], a[25], a[26]); // Sum(51) + res[48] = fma52lo(res[48], a[21], a[27]); // Sum(48) + res[49] = fma52hi(res[49], a[21], a[27]); // Sum(48) + res[49] = fma52lo(res[49], a[22], a[27]); // Sum(49) + res[50] = fma52hi(res[50], a[22], a[27]); // Sum(49) + res[50] = fma52lo(res[50], a[23], a[27]); // Sum(50) + res[51] = fma52hi(res[51], a[23], a[27]); // Sum(50) + res[51] = fma52lo(res[51], a[24], a[27]); // Sum(51) + res[52] = fma52hi(res[52], a[24], a[27]); // Sum(51) + res[52] = fma52lo(res[52], a[25], a[27]); // Sum(52) + res[53] = fma52hi(res[53], a[25], a[27]); // Sum(52) + res[53] = fma52lo(res[53], a[26], a[27]); // Sum(53) + res[54] = fma52hi(res[54], a[26], a[27]); // Sum(53) + res[48] = fma52lo(res[48], a[20], a[28]); // Sum(48) + res[49] = fma52hi(res[49], a[20], a[28]); // Sum(48) + res[49] = fma52lo(res[49], a[21], a[28]); // Sum(49) + res[50] = fma52hi(res[50], a[21], a[28]); // Sum(49) + res[50] = fma52lo(res[50], a[22], a[28]); // Sum(50) + res[51] = fma52hi(res[51], a[22], a[28]); // Sum(50) + res[51] = fma52lo(res[51], a[23], a[28]); // Sum(51) + res[52] = fma52hi(res[52], a[23], a[28]); // Sum(51) + res[52] = fma52lo(res[52], a[24], a[28]); // Sum(52) + res[53] = fma52hi(res[53], a[24], a[28]); // Sum(52) + res[53] = fma52lo(res[53], a[25], a[28]); // Sum(53) + res[54] = fma52hi(res[54], a[25], a[28]); // Sum(53) + res[54] = fma52lo(res[54], a[26], a[28]); // Sum(54) + res[55] = fma52hi(res[55], a[26], a[28]); // Sum(54) + res[55] = fma52lo(res[55], a[27], a[28]); // Sum(55) + res[56] = fma52hi(res[56], a[27], a[28]); // Sum(55) + res[48] = fma52lo(res[48], a[19], a[29]); // Sum(48) + res[49] = fma52hi(res[49], a[19], a[29]); // Sum(48) + res[49] = fma52lo(res[49], a[20], a[29]); // Sum(49) + res[50] = fma52hi(res[50], a[20], a[29]); // Sum(49) + res[50] = fma52lo(res[50], a[21], a[29]); // Sum(50) + res[51] = fma52hi(res[51], a[21], a[29]); // Sum(50) + res[51] = fma52lo(res[51], a[22], a[29]); // Sum(51) + res[52] = fma52hi(res[52], a[22], a[29]); // Sum(51) + res[52] = fma52lo(res[52], a[23], a[29]); // Sum(52) + res[53] = fma52hi(res[53], a[23], a[29]); // Sum(52) + res[53] = fma52lo(res[53], a[24], a[29]); // Sum(53) + res[54] = fma52hi(res[54], a[24], a[29]); // Sum(53) + res[54] = fma52lo(res[54], a[25], a[29]); // Sum(54) + res[55] = fma52hi(res[55], a[25], a[29]); // Sum(54) + res[55] = fma52lo(res[55], a[26], a[29]); // Sum(55) + res[56] = fma52hi(res[56], a[26], a[29]); // Sum(55) + res[56] = fma52lo(res[56], a[27], a[29]); // Sum(56) + res[57] = fma52hi(res[57], a[27], a[29]); // Sum(56) + res[57] = fma52lo(res[57], a[28], a[29]); // Sum(57) + res[58] = fma52hi(res[58], a[28], a[29]); // Sum(57) + res[48] = fma52lo(res[48], a[18], a[30]); // Sum(48) + res[49] = fma52hi(res[49], a[18], a[30]); // Sum(48) + res[49] = fma52lo(res[49], a[19], a[30]); // Sum(49) + res[50] = fma52hi(res[50], a[19], a[30]); // Sum(49) + res[50] = fma52lo(res[50], a[20], a[30]); // Sum(50) + res[51] = fma52hi(res[51], a[20], a[30]); // Sum(50) + res[51] = fma52lo(res[51], a[21], a[30]); // Sum(51) + res[52] = fma52hi(res[52], a[21], a[30]); // Sum(51) + res[52] = fma52lo(res[52], a[22], a[30]); // Sum(52) + res[53] = fma52hi(res[53], a[22], a[30]); // Sum(52) + res[53] = fma52lo(res[53], a[23], a[30]); // Sum(53) + res[54] = fma52hi(res[54], a[23], a[30]); // Sum(53) + res[54] = fma52lo(res[54], a[24], a[30]); // Sum(54) + res[55] = fma52hi(res[55], a[24], a[30]); // Sum(54) + res[55] = fma52lo(res[55], a[25], a[30]); // Sum(55) + res[56] = fma52hi(res[56], a[25], a[30]); // Sum(55) + res[56] = fma52lo(res[56], a[26], a[30]); // Sum(56) + res[57] = fma52hi(res[57], a[26], a[30]); // Sum(56) + res[57] = fma52lo(res[57], a[27], a[30]); // Sum(57) + res[58] = fma52hi(res[58], a[27], a[30]); // Sum(57) + res[58] = fma52lo(res[58], a[28], a[30]); // Sum(58) + res[59] = fma52hi(res[59], a[28], a[30]); // Sum(58) + res[59] = fma52lo(res[59], a[29], a[30]); // Sum(59) + res[60] = fma52hi(res[60], a[29], a[30]); // Sum(59) + res[48] = fma52lo(res[48], a[17], a[31]); // Sum(48) + res[49] = fma52hi(res[49], a[17], a[31]); // Sum(48) + res[49] = fma52lo(res[49], a[18], a[31]); // Sum(49) + res[50] = fma52hi(res[50], a[18], a[31]); // Sum(49) + res[50] = fma52lo(res[50], a[19], a[31]); // Sum(50) + res[51] = fma52hi(res[51], a[19], a[31]); // Sum(50) + res[51] = fma52lo(res[51], a[20], a[31]); // Sum(51) + res[52] = fma52hi(res[52], a[20], a[31]); // Sum(51) + res[52] = fma52lo(res[52], a[21], a[31]); // Sum(52) + res[53] = fma52hi(res[53], a[21], a[31]); // Sum(52) + res[53] = fma52lo(res[53], a[22], a[31]); // Sum(53) + res[54] = fma52hi(res[54], a[22], a[31]); // Sum(53) + res[54] = fma52lo(res[54], a[23], a[31]); // Sum(54) + res[55] = fma52hi(res[55], a[23], a[31]); // Sum(54) + res[55] = fma52lo(res[55], a[24], a[31]); // Sum(55) + res[56] = fma52hi(res[56], a[24], a[31]); // Sum(55) + res[56] = fma52lo(res[56], a[25], a[31]); // Sum(56) + res[57] = fma52hi(res[57], a[25], a[31]); // Sum(56) + res[57] = fma52lo(res[57], a[26], a[31]); // Sum(57) + res[58] = fma52hi(res[58], a[26], a[31]); // Sum(57) + res[58] = fma52lo(res[58], a[27], a[31]); // Sum(58) + res[59] = fma52hi(res[59], a[27], a[31]); // Sum(58) + res[59] = fma52lo(res[59], a[28], a[31]); // Sum(59) + res[60] = fma52hi(res[60], a[28], a[31]); // Sum(59) + res[48] = fma52lo(res[48], a[16], a[32]); // Sum(48) + res[49] = fma52hi(res[49], a[16], a[32]); // Sum(48) + res[49] = fma52lo(res[49], a[17], a[32]); // Sum(49) + res[50] = fma52hi(res[50], a[17], a[32]); // Sum(49) + res[50] = fma52lo(res[50], a[18], a[32]); // Sum(50) + res[51] = fma52hi(res[51], a[18], a[32]); // Sum(50) + res[51] = fma52lo(res[51], a[19], a[32]); // Sum(51) + res[52] = fma52hi(res[52], a[19], a[32]); // Sum(51) + res[52] = fma52lo(res[52], a[20], a[32]); // Sum(52) + res[53] = fma52hi(res[53], a[20], a[32]); // Sum(52) + res[53] = fma52lo(res[53], a[21], a[32]); // Sum(53) + res[54] = fma52hi(res[54], a[21], a[32]); // Sum(53) + res[54] = fma52lo(res[54], a[22], a[32]); // Sum(54) + res[55] = fma52hi(res[55], a[22], a[32]); // Sum(54) + res[55] = fma52lo(res[55], a[23], a[32]); // Sum(55) + res[56] = fma52hi(res[56], a[23], a[32]); // Sum(55) + res[56] = fma52lo(res[56], a[24], a[32]); // Sum(56) + res[57] = fma52hi(res[57], a[24], a[32]); // Sum(56) + res[57] = fma52lo(res[57], a[25], a[32]); // Sum(57) + res[58] = fma52hi(res[58], a[25], a[32]); // Sum(57) + res[58] = fma52lo(res[58], a[26], a[32]); // Sum(58) + res[59] = fma52hi(res[59], a[26], a[32]); // Sum(58) + res[59] = fma52lo(res[59], a[27], a[32]); // Sum(59) + res[60] = fma52hi(res[60], a[27], a[32]); // Sum(59) + res[48] = fma52lo(res[48], a[15], a[33]); // Sum(48) + res[49] = fma52hi(res[49], a[15], a[33]); // Sum(48) + res[49] = fma52lo(res[49], a[16], a[33]); // Sum(49) + res[50] = fma52hi(res[50], a[16], a[33]); // Sum(49) + res[50] = fma52lo(res[50], a[17], a[33]); // Sum(50) + res[51] = fma52hi(res[51], a[17], a[33]); // Sum(50) + res[51] = fma52lo(res[51], a[18], a[33]); // Sum(51) + res[52] = fma52hi(res[52], a[18], a[33]); // Sum(51) + res[52] = fma52lo(res[52], a[19], a[33]); // Sum(52) + res[53] = fma52hi(res[53], a[19], a[33]); // Sum(52) + res[53] = fma52lo(res[53], a[20], a[33]); // Sum(53) + res[54] = fma52hi(res[54], a[20], a[33]); // Sum(53) + res[54] = fma52lo(res[54], a[21], a[33]); // Sum(54) + res[55] = fma52hi(res[55], a[21], a[33]); // Sum(54) + res[55] = fma52lo(res[55], a[22], a[33]); // Sum(55) + res[56] = fma52hi(res[56], a[22], a[33]); // Sum(55) + res[56] = fma52lo(res[56], a[23], a[33]); // Sum(56) + res[57] = fma52hi(res[57], a[23], a[33]); // Sum(56) + res[57] = fma52lo(res[57], a[24], a[33]); // Sum(57) + res[58] = fma52hi(res[58], a[24], a[33]); // Sum(57) + res[58] = fma52lo(res[58], a[25], a[33]); // Sum(58) + res[59] = fma52hi(res[59], a[25], a[33]); // Sum(58) + res[59] = fma52lo(res[59], a[26], a[33]); // Sum(59) + res[60] = fma52hi(res[60], a[26], a[33]); // Sum(59) + res[48] = fma52lo(res[48], a[14], a[34]); // Sum(48) + res[49] = fma52hi(res[49], a[14], a[34]); // Sum(48) + res[49] = fma52lo(res[49], a[15], a[34]); // Sum(49) + res[50] = fma52hi(res[50], a[15], a[34]); // Sum(49) + res[50] = fma52lo(res[50], a[16], a[34]); // Sum(50) + res[51] = fma52hi(res[51], a[16], a[34]); // Sum(50) + res[51] = fma52lo(res[51], a[17], a[34]); // Sum(51) + res[52] = fma52hi(res[52], a[17], a[34]); // Sum(51) + res[52] = fma52lo(res[52], a[18], a[34]); // Sum(52) + res[53] = fma52hi(res[53], a[18], a[34]); // Sum(52) + res[53] = fma52lo(res[53], a[19], a[34]); // Sum(53) + res[54] = fma52hi(res[54], a[19], a[34]); // Sum(53) + res[54] = fma52lo(res[54], a[20], a[34]); // Sum(54) + res[55] = fma52hi(res[55], a[20], a[34]); // Sum(54) + res[55] = fma52lo(res[55], a[21], a[34]); // Sum(55) + res[56] = fma52hi(res[56], a[21], a[34]); // Sum(55) + res[56] = fma52lo(res[56], a[22], a[34]); // Sum(56) + res[57] = fma52hi(res[57], a[22], a[34]); // Sum(56) + res[57] = fma52lo(res[57], a[23], a[34]); // Sum(57) + res[58] = fma52hi(res[58], a[23], a[34]); // Sum(57) + res[58] = fma52lo(res[58], a[24], a[34]); // Sum(58) + res[59] = fma52hi(res[59], a[24], a[34]); // Sum(58) + res[59] = fma52lo(res[59], a[25], a[34]); // Sum(59) + res[60] = fma52hi(res[60], a[25], a[34]); // Sum(59) + res[48] = fma52lo(res[48], a[13], a[35]); // Sum(48) + res[49] = fma52hi(res[49], a[13], a[35]); // Sum(48) + res[49] = fma52lo(res[49], a[14], a[35]); // Sum(49) + res[50] = fma52hi(res[50], a[14], a[35]); // Sum(49) + res[50] = fma52lo(res[50], a[15], a[35]); // Sum(50) + res[51] = fma52hi(res[51], a[15], a[35]); // Sum(50) + res[51] = fma52lo(res[51], a[16], a[35]); // Sum(51) + res[52] = fma52hi(res[52], a[16], a[35]); // Sum(51) + res[52] = fma52lo(res[52], a[17], a[35]); // Sum(52) + res[53] = fma52hi(res[53], a[17], a[35]); // Sum(52) + res[53] = fma52lo(res[53], a[18], a[35]); // Sum(53) + res[54] = fma52hi(res[54], a[18], a[35]); // Sum(53) + res[54] = fma52lo(res[54], a[19], a[35]); // Sum(54) + res[55] = fma52hi(res[55], a[19], a[35]); // Sum(54) + res[55] = fma52lo(res[55], a[20], a[35]); // Sum(55) + res[56] = fma52hi(res[56], a[20], a[35]); // Sum(55) + res[56] = fma52lo(res[56], a[21], a[35]); // Sum(56) + res[57] = fma52hi(res[57], a[21], a[35]); // Sum(56) + res[57] = fma52lo(res[57], a[22], a[35]); // Sum(57) + res[58] = fma52hi(res[58], a[22], a[35]); // Sum(57) + res[58] = fma52lo(res[58], a[23], a[35]); // Sum(58) + res[59] = fma52hi(res[59], a[23], a[35]); // Sum(58) + res[59] = fma52lo(res[59], a[24], a[35]); // Sum(59) + res[60] = fma52hi(res[60], a[24], a[35]); // Sum(59) + res[48] = fma52lo(res[48], a[12], a[36]); // Sum(48) + res[49] = fma52hi(res[49], a[12], a[36]); // Sum(48) + res[49] = fma52lo(res[49], a[13], a[36]); // Sum(49) + res[50] = fma52hi(res[50], a[13], a[36]); // Sum(49) + res[50] = fma52lo(res[50], a[14], a[36]); // Sum(50) + res[51] = fma52hi(res[51], a[14], a[36]); // Sum(50) + res[51] = fma52lo(res[51], a[15], a[36]); // Sum(51) + res[52] = fma52hi(res[52], a[15], a[36]); // Sum(51) + res[52] = fma52lo(res[52], a[16], a[36]); // Sum(52) + res[53] = fma52hi(res[53], a[16], a[36]); // Sum(52) + res[53] = fma52lo(res[53], a[17], a[36]); // Sum(53) + res[54] = fma52hi(res[54], a[17], a[36]); // Sum(53) + res[54] = fma52lo(res[54], a[18], a[36]); // Sum(54) + res[55] = fma52hi(res[55], a[18], a[36]); // Sum(54) + res[55] = fma52lo(res[55], a[19], a[36]); // Sum(55) + res[56] = fma52hi(res[56], a[19], a[36]); // Sum(55) + res[56] = fma52lo(res[56], a[20], a[36]); // Sum(56) + res[57] = fma52hi(res[57], a[20], a[36]); // Sum(56) + res[57] = fma52lo(res[57], a[21], a[36]); // Sum(57) + res[58] = fma52hi(res[58], a[21], a[36]); // Sum(57) + res[58] = fma52lo(res[58], a[22], a[36]); // Sum(58) + res[59] = fma52hi(res[59], a[22], a[36]); // Sum(58) + res[59] = fma52lo(res[59], a[23], a[36]); // Sum(59) + res[60] = fma52hi(res[60], a[23], a[36]); // Sum(59) + res[48] = fma52lo(res[48], a[11], a[37]); // Sum(48) + res[49] = fma52hi(res[49], a[11], a[37]); // Sum(48) + res[49] = fma52lo(res[49], a[12], a[37]); // Sum(49) + res[50] = fma52hi(res[50], a[12], a[37]); // Sum(49) + res[50] = fma52lo(res[50], a[13], a[37]); // Sum(50) + res[51] = fma52hi(res[51], a[13], a[37]); // Sum(50) + res[51] = fma52lo(res[51], a[14], a[37]); // Sum(51) + res[52] = fma52hi(res[52], a[14], a[37]); // Sum(51) + res[52] = fma52lo(res[52], a[15], a[37]); // Sum(52) + res[53] = fma52hi(res[53], a[15], a[37]); // Sum(52) + res[53] = fma52lo(res[53], a[16], a[37]); // Sum(53) + res[54] = fma52hi(res[54], a[16], a[37]); // Sum(53) + res[54] = fma52lo(res[54], a[17], a[37]); // Sum(54) + res[55] = fma52hi(res[55], a[17], a[37]); // Sum(54) + res[55] = fma52lo(res[55], a[18], a[37]); // Sum(55) + res[56] = fma52hi(res[56], a[18], a[37]); // Sum(55) + res[56] = fma52lo(res[56], a[19], a[37]); // Sum(56) + res[57] = fma52hi(res[57], a[19], a[37]); // Sum(56) + res[57] = fma52lo(res[57], a[20], a[37]); // Sum(57) + res[58] = fma52hi(res[58], a[20], a[37]); // Sum(57) + res[58] = fma52lo(res[58], a[21], a[37]); // Sum(58) + res[59] = fma52hi(res[59], a[21], a[37]); // Sum(58) + res[59] = fma52lo(res[59], a[22], a[37]); // Sum(59) + res[60] = fma52hi(res[60], a[22], a[37]); // Sum(59) + res[48] = fma52lo(res[48], a[10], a[38]); // Sum(48) + res[49] = fma52hi(res[49], a[10], a[38]); // Sum(48) + res[49] = fma52lo(res[49], a[11], a[38]); // Sum(49) + res[50] = fma52hi(res[50], a[11], a[38]); // Sum(49) + res[50] = fma52lo(res[50], a[12], a[38]); // Sum(50) + res[51] = fma52hi(res[51], a[12], a[38]); // Sum(50) + res[51] = fma52lo(res[51], a[13], a[38]); // Sum(51) + res[52] = fma52hi(res[52], a[13], a[38]); // Sum(51) + res[52] = fma52lo(res[52], a[14], a[38]); // Sum(52) + res[53] = fma52hi(res[53], a[14], a[38]); // Sum(52) + res[53] = fma52lo(res[53], a[15], a[38]); // Sum(53) + res[54] = fma52hi(res[54], a[15], a[38]); // Sum(53) + res[54] = fma52lo(res[54], a[16], a[38]); // Sum(54) + res[55] = fma52hi(res[55], a[16], a[38]); // Sum(54) + res[55] = fma52lo(res[55], a[17], a[38]); // Sum(55) + res[56] = fma52hi(res[56], a[17], a[38]); // Sum(55) + res[56] = fma52lo(res[56], a[18], a[38]); // Sum(56) + res[57] = fma52hi(res[57], a[18], a[38]); // Sum(56) + res[57] = fma52lo(res[57], a[19], a[38]); // Sum(57) + res[58] = fma52hi(res[58], a[19], a[38]); // Sum(57) + res[58] = fma52lo(res[58], a[20], a[38]); // Sum(58) + res[59] = fma52hi(res[59], a[20], a[38]); // Sum(58) + res[59] = fma52lo(res[59], a[21], a[38]); // Sum(59) + res[60] = fma52hi(res[60], a[21], a[38]); // Sum(59) + res[48] = fma52lo(res[48], a[9], a[39]); // Sum(48) + res[49] = fma52hi(res[49], a[9], a[39]); // Sum(48) + res[49] = fma52lo(res[49], a[10], a[39]); // Sum(49) + res[50] = fma52hi(res[50], a[10], a[39]); // Sum(49) + res[50] = fma52lo(res[50], a[11], a[39]); // Sum(50) + res[51] = fma52hi(res[51], a[11], a[39]); // Sum(50) + res[51] = fma52lo(res[51], a[12], a[39]); // Sum(51) + res[52] = fma52hi(res[52], a[12], a[39]); // Sum(51) + res[52] = fma52lo(res[52], a[13], a[39]); // Sum(52) + res[53] = fma52hi(res[53], a[13], a[39]); // Sum(52) + res[53] = fma52lo(res[53], a[14], a[39]); // Sum(53) + res[54] = fma52hi(res[54], a[14], a[39]); // Sum(53) + res[54] = fma52lo(res[54], a[15], a[39]); // Sum(54) + res[55] = fma52hi(res[55], a[15], a[39]); // Sum(54) + res[55] = fma52lo(res[55], a[16], a[39]); // Sum(55) + res[56] = fma52hi(res[56], a[16], a[39]); // Sum(55) + res[56] = fma52lo(res[56], a[17], a[39]); // Sum(56) + res[57] = fma52hi(res[57], a[17], a[39]); // Sum(56) + res[57] = fma52lo(res[57], a[18], a[39]); // Sum(57) + res[58] = fma52hi(res[58], a[18], a[39]); // Sum(57) + res[58] = fma52lo(res[58], a[19], a[39]); // Sum(58) + res[59] = fma52hi(res[59], a[19], a[39]); // Sum(58) + res[59] = fma52lo(res[59], a[20], a[39]); // Sum(59) + res[60] = fma52hi(res[60], a[20], a[39]); // Sum(59) + res[48] = fma52lo(res[48], a[8], a[40]); // Sum(48) + res[49] = fma52hi(res[49], a[8], a[40]); // Sum(48) + res[49] = fma52lo(res[49], a[9], a[40]); // Sum(49) + res[50] = fma52hi(res[50], a[9], a[40]); // Sum(49) + res[50] = fma52lo(res[50], a[10], a[40]); // Sum(50) + res[51] = fma52hi(res[51], a[10], a[40]); // Sum(50) + res[51] = fma52lo(res[51], a[11], a[40]); // Sum(51) + res[52] = fma52hi(res[52], a[11], a[40]); // Sum(51) + res[52] = fma52lo(res[52], a[12], a[40]); // Sum(52) + res[53] = fma52hi(res[53], a[12], a[40]); // Sum(52) + res[53] = fma52lo(res[53], a[13], a[40]); // Sum(53) + res[54] = fma52hi(res[54], a[13], a[40]); // Sum(53) + res[54] = fma52lo(res[54], a[14], a[40]); // Sum(54) + res[55] = fma52hi(res[55], a[14], a[40]); // Sum(54) + res[55] = fma52lo(res[55], a[15], a[40]); // Sum(55) + res[56] = fma52hi(res[56], a[15], a[40]); // Sum(55) + res[56] = fma52lo(res[56], a[16], a[40]); // Sum(56) + res[57] = fma52hi(res[57], a[16], a[40]); // Sum(56) + res[57] = fma52lo(res[57], a[17], a[40]); // Sum(57) + res[58] = fma52hi(res[58], a[17], a[40]); // Sum(57) + res[58] = fma52lo(res[58], a[18], a[40]); // Sum(58) + res[59] = fma52hi(res[59], a[18], a[40]); // Sum(58) + res[59] = fma52lo(res[59], a[19], a[40]); // Sum(59) + res[60] = fma52hi(res[60], a[19], a[40]); // Sum(59) + res[48] = fma52lo(res[48], a[7], a[41]); // Sum(48) + res[49] = fma52hi(res[49], a[7], a[41]); // Sum(48) + res[49] = fma52lo(res[49], a[8], a[41]); // Sum(49) + res[50] = fma52hi(res[50], a[8], a[41]); // Sum(49) + res[50] = fma52lo(res[50], a[9], a[41]); // Sum(50) + res[51] = fma52hi(res[51], a[9], a[41]); // Sum(50) + res[51] = fma52lo(res[51], a[10], a[41]); // Sum(51) + res[52] = fma52hi(res[52], a[10], a[41]); // Sum(51) + res[52] = fma52lo(res[52], a[11], a[41]); // Sum(52) + res[53] = fma52hi(res[53], a[11], a[41]); // Sum(52) + res[53] = fma52lo(res[53], a[12], a[41]); // Sum(53) + res[54] = fma52hi(res[54], a[12], a[41]); // Sum(53) + res[54] = fma52lo(res[54], a[13], a[41]); // Sum(54) + res[55] = fma52hi(res[55], a[13], a[41]); // Sum(54) + res[55] = fma52lo(res[55], a[14], a[41]); // Sum(55) + res[56] = fma52hi(res[56], a[14], a[41]); // Sum(55) + res[56] = fma52lo(res[56], a[15], a[41]); // Sum(56) + res[57] = fma52hi(res[57], a[15], a[41]); // Sum(56) + res[57] = fma52lo(res[57], a[16], a[41]); // Sum(57) + res[58] = fma52hi(res[58], a[16], a[41]); // Sum(57) + res[58] = fma52lo(res[58], a[17], a[41]); // Sum(58) + res[59] = fma52hi(res[59], a[17], a[41]); // Sum(58) + res[59] = fma52lo(res[59], a[18], a[41]); // Sum(59) + res[60] = fma52hi(res[60], a[18], a[41]); // Sum(59) + res[48] = fma52lo(res[48], a[6], a[42]); // Sum(48) + res[49] = fma52hi(res[49], a[6], a[42]); // Sum(48) + res[49] = fma52lo(res[49], a[7], a[42]); // Sum(49) + res[50] = fma52hi(res[50], a[7], a[42]); // Sum(49) + res[50] = fma52lo(res[50], a[8], a[42]); // Sum(50) + res[51] = fma52hi(res[51], a[8], a[42]); // Sum(50) + res[51] = fma52lo(res[51], a[9], a[42]); // Sum(51) + res[52] = fma52hi(res[52], a[9], a[42]); // Sum(51) + res[52] = fma52lo(res[52], a[10], a[42]); // Sum(52) + res[53] = fma52hi(res[53], a[10], a[42]); // Sum(52) + res[53] = fma52lo(res[53], a[11], a[42]); // Sum(53) + res[54] = fma52hi(res[54], a[11], a[42]); // Sum(53) + res[54] = fma52lo(res[54], a[12], a[42]); // Sum(54) + res[55] = fma52hi(res[55], a[12], a[42]); // Sum(54) + res[55] = fma52lo(res[55], a[13], a[42]); // Sum(55) + res[56] = fma52hi(res[56], a[13], a[42]); // Sum(55) + res[56] = fma52lo(res[56], a[14], a[42]); // Sum(56) + res[57] = fma52hi(res[57], a[14], a[42]); // Sum(56) + res[57] = fma52lo(res[57], a[15], a[42]); // Sum(57) + res[58] = fma52hi(res[58], a[15], a[42]); // Sum(57) + res[58] = fma52lo(res[58], a[16], a[42]); // Sum(58) + res[59] = fma52hi(res[59], a[16], a[42]); // Sum(58) + res[59] = fma52lo(res[59], a[17], a[42]); // Sum(59) + res[60] = fma52hi(res[60], a[17], a[42]); // Sum(59) + res[48] = fma52lo(res[48], a[5], a[43]); // Sum(48) + res[49] = fma52hi(res[49], a[5], a[43]); // Sum(48) + res[49] = fma52lo(res[49], a[6], a[43]); // Sum(49) + res[50] = fma52hi(res[50], a[6], a[43]); // Sum(49) + res[50] = fma52lo(res[50], a[7], a[43]); // Sum(50) + res[51] = fma52hi(res[51], a[7], a[43]); // Sum(50) + res[51] = fma52lo(res[51], a[8], a[43]); // Sum(51) + res[52] = fma52hi(res[52], a[8], a[43]); // Sum(51) + res[52] = fma52lo(res[52], a[9], a[43]); // Sum(52) + res[53] = fma52hi(res[53], a[9], a[43]); // Sum(52) + res[53] = fma52lo(res[53], a[10], a[43]); // Sum(53) + res[54] = fma52hi(res[54], a[10], a[43]); // Sum(53) + res[54] = fma52lo(res[54], a[11], a[43]); // Sum(54) + res[55] = fma52hi(res[55], a[11], a[43]); // Sum(54) + res[55] = fma52lo(res[55], a[12], a[43]); // Sum(55) + res[56] = fma52hi(res[56], a[12], a[43]); // Sum(55) + res[56] = fma52lo(res[56], a[13], a[43]); // Sum(56) + res[57] = fma52hi(res[57], a[13], a[43]); // Sum(56) + res[57] = fma52lo(res[57], a[14], a[43]); // Sum(57) + res[58] = fma52hi(res[58], a[14], a[43]); // Sum(57) + res[58] = fma52lo(res[58], a[15], a[43]); // Sum(58) + res[59] = fma52hi(res[59], a[15], a[43]); // Sum(58) + res[59] = fma52lo(res[59], a[16], a[43]); // Sum(59) + res[60] = fma52hi(res[60], a[16], a[43]); // Sum(59) + res[48] = fma52lo(res[48], a[4], a[44]); // Sum(48) + res[49] = fma52hi(res[49], a[4], a[44]); // Sum(48) + res[49] = fma52lo(res[49], a[5], a[44]); // Sum(49) + res[50] = fma52hi(res[50], a[5], a[44]); // Sum(49) + res[50] = fma52lo(res[50], a[6], a[44]); // Sum(50) + res[51] = fma52hi(res[51], a[6], a[44]); // Sum(50) + res[51] = fma52lo(res[51], a[7], a[44]); // Sum(51) + res[52] = fma52hi(res[52], a[7], a[44]); // Sum(51) + res[52] = fma52lo(res[52], a[8], a[44]); // Sum(52) + res[53] = fma52hi(res[53], a[8], a[44]); // Sum(52) + res[53] = fma52lo(res[53], a[9], a[44]); // Sum(53) + res[54] = fma52hi(res[54], a[9], a[44]); // Sum(53) + res[54] = fma52lo(res[54], a[10], a[44]); // Sum(54) + res[55] = fma52hi(res[55], a[10], a[44]); // Sum(54) + res[55] = fma52lo(res[55], a[11], a[44]); // Sum(55) + res[56] = fma52hi(res[56], a[11], a[44]); // Sum(55) + res[56] = fma52lo(res[56], a[12], a[44]); // Sum(56) + res[57] = fma52hi(res[57], a[12], a[44]); // Sum(56) + res[57] = fma52lo(res[57], a[13], a[44]); // Sum(57) + res[58] = fma52hi(res[58], a[13], a[44]); // Sum(57) + res[58] = fma52lo(res[58], a[14], a[44]); // Sum(58) + res[59] = fma52hi(res[59], a[14], a[44]); // Sum(58) + res[59] = fma52lo(res[59], a[15], a[44]); // Sum(59) + res[60] = fma52hi(res[60], a[15], a[44]); // Sum(59) + res[48] = fma52lo(res[48], a[3], a[45]); // Sum(48) + res[49] = fma52hi(res[49], a[3], a[45]); // Sum(48) + res[49] = fma52lo(res[49], a[4], a[45]); // Sum(49) + res[50] = fma52hi(res[50], a[4], a[45]); // Sum(49) + res[50] = fma52lo(res[50], a[5], a[45]); // Sum(50) + res[51] = fma52hi(res[51], a[5], a[45]); // Sum(50) + res[51] = fma52lo(res[51], a[6], a[45]); // Sum(51) + res[52] = fma52hi(res[52], a[6], a[45]); // Sum(51) + res[52] = fma52lo(res[52], a[7], a[45]); // Sum(52) + res[53] = fma52hi(res[53], a[7], a[45]); // Sum(52) + res[53] = fma52lo(res[53], a[8], a[45]); // Sum(53) + res[54] = fma52hi(res[54], a[8], a[45]); // Sum(53) + res[54] = fma52lo(res[54], a[9], a[45]); // Sum(54) + res[55] = fma52hi(res[55], a[9], a[45]); // Sum(54) + res[55] = fma52lo(res[55], a[10], a[45]); // Sum(55) + res[56] = fma52hi(res[56], a[10], a[45]); // Sum(55) + res[56] = fma52lo(res[56], a[11], a[45]); // Sum(56) + res[57] = fma52hi(res[57], a[11], a[45]); // Sum(56) + res[57] = fma52lo(res[57], a[12], a[45]); // Sum(57) + res[58] = fma52hi(res[58], a[12], a[45]); // Sum(57) + res[58] = fma52lo(res[58], a[13], a[45]); // Sum(58) + res[59] = fma52hi(res[59], a[13], a[45]); // Sum(58) + res[59] = fma52lo(res[59], a[14], a[45]); // Sum(59) + res[60] = fma52hi(res[60], a[14], a[45]); // Sum(59) + res[48] = fma52lo(res[48], a[2], a[46]); // Sum(48) + res[49] = fma52hi(res[49], a[2], a[46]); // Sum(48) + res[49] = fma52lo(res[49], a[3], a[46]); // Sum(49) + res[50] = fma52hi(res[50], a[3], a[46]); // Sum(49) + res[50] = fma52lo(res[50], a[4], a[46]); // Sum(50) + res[51] = fma52hi(res[51], a[4], a[46]); // Sum(50) + res[51] = fma52lo(res[51], a[5], a[46]); // Sum(51) + res[52] = fma52hi(res[52], a[5], a[46]); // Sum(51) + res[52] = fma52lo(res[52], a[6], a[46]); // Sum(52) + res[53] = fma52hi(res[53], a[6], a[46]); // Sum(52) + res[53] = fma52lo(res[53], a[7], a[46]); // Sum(53) + res[54] = fma52hi(res[54], a[7], a[46]); // Sum(53) + res[54] = fma52lo(res[54], a[8], a[46]); // Sum(54) + res[55] = fma52hi(res[55], a[8], a[46]); // Sum(54) + res[55] = fma52lo(res[55], a[9], a[46]); // Sum(55) + res[56] = fma52hi(res[56], a[9], a[46]); // Sum(55) + res[56] = fma52lo(res[56], a[10], a[46]); // Sum(56) + res[57] = fma52hi(res[57], a[10], a[46]); // Sum(56) + res[57] = fma52lo(res[57], a[11], a[46]); // Sum(57) + res[58] = fma52hi(res[58], a[11], a[46]); // Sum(57) + res[58] = fma52lo(res[58], a[12], a[46]); // Sum(58) + res[59] = fma52hi(res[59], a[12], a[46]); // Sum(58) + res[59] = fma52lo(res[59], a[13], a[46]); // Sum(59) + res[60] = fma52hi(res[60], a[13], a[46]); // Sum(59) + res[48] = fma52lo(res[48], a[1], a[47]); // Sum(48) + res[49] = fma52hi(res[49], a[1], a[47]); // Sum(48) + res[49] = fma52lo(res[49], a[2], a[47]); // Sum(49) + res[50] = fma52hi(res[50], a[2], a[47]); // Sum(49) + res[50] = fma52lo(res[50], a[3], a[47]); // Sum(50) + res[51] = fma52hi(res[51], a[3], a[47]); // Sum(50) + res[51] = fma52lo(res[51], a[4], a[47]); // Sum(51) + res[52] = fma52hi(res[52], a[4], a[47]); // Sum(51) + res[52] = fma52lo(res[52], a[5], a[47]); // Sum(52) + res[53] = fma52hi(res[53], a[5], a[47]); // Sum(52) + res[53] = fma52lo(res[53], a[6], a[47]); // Sum(53) + res[54] = fma52hi(res[54], a[6], a[47]); // Sum(53) + res[54] = fma52lo(res[54], a[7], a[47]); // Sum(54) + res[55] = fma52hi(res[55], a[7], a[47]); // Sum(54) + res[55] = fma52lo(res[55], a[8], a[47]); // Sum(55) + res[56] = fma52hi(res[56], a[8], a[47]); // Sum(55) + res[56] = fma52lo(res[56], a[9], a[47]); // Sum(56) + res[57] = fma52hi(res[57], a[9], a[47]); // Sum(56) + res[57] = fma52lo(res[57], a[10], a[47]); // Sum(57) + res[58] = fma52hi(res[58], a[10], a[47]); // Sum(57) + res[58] = fma52lo(res[58], a[11], a[47]); // Sum(58) + res[59] = fma52hi(res[59], a[11], a[47]); // Sum(58) + res[59] = fma52lo(res[59], a[12], a[47]); // Sum(59) + res[60] = fma52hi(res[60], a[12], a[47]); // Sum(59) + res[48] = fma52lo(res[48], a[0], a[48]); // Sum(48) + res[49] = fma52hi(res[49], a[0], a[48]); // Sum(48) + res[49] = fma52lo(res[49], a[1], a[48]); // Sum(49) + res[50] = fma52hi(res[50], a[1], a[48]); // Sum(49) + res[50] = fma52lo(res[50], a[2], a[48]); // Sum(50) + res[51] = fma52hi(res[51], a[2], a[48]); // Sum(50) + res[51] = fma52lo(res[51], a[3], a[48]); // Sum(51) + res[52] = fma52hi(res[52], a[3], a[48]); // Sum(51) + res[52] = fma52lo(res[52], a[4], a[48]); // Sum(52) + res[53] = fma52hi(res[53], a[4], a[48]); // Sum(52) + res[53] = fma52lo(res[53], a[5], a[48]); // Sum(53) + res[54] = fma52hi(res[54], a[5], a[48]); // Sum(53) + res[54] = fma52lo(res[54], a[6], a[48]); // Sum(54) + res[55] = fma52hi(res[55], a[6], a[48]); // Sum(54) + res[55] = fma52lo(res[55], a[7], a[48]); // Sum(55) + res[56] = fma52hi(res[56], a[7], a[48]); // Sum(55) + res[56] = fma52lo(res[56], a[8], a[48]); // Sum(56) + res[57] = fma52hi(res[57], a[8], a[48]); // Sum(56) + res[57] = fma52lo(res[57], a[9], a[48]); // Sum(57) + res[58] = fma52hi(res[58], a[9], a[48]); // Sum(57) + res[58] = fma52lo(res[58], a[10], a[48]); // Sum(58) + res[59] = fma52hi(res[59], a[10], a[48]); // Sum(58) + res[59] = fma52lo(res[59], a[11], a[48]); // Sum(59) + res[60] = fma52hi(res[60], a[11], a[48]); // Sum(59) + res[49] = fma52lo(res[49], a[0], a[49]); // Sum(49) + res[50] = fma52hi(res[50], a[0], a[49]); // Sum(49) + res[50] = fma52lo(res[50], a[1], a[49]); // Sum(50) + res[51] = fma52hi(res[51], a[1], a[49]); // Sum(50) + res[51] = fma52lo(res[51], a[2], a[49]); // Sum(51) + res[52] = fma52hi(res[52], a[2], a[49]); // Sum(51) + res[52] = fma52lo(res[52], a[3], a[49]); // Sum(52) + res[53] = fma52hi(res[53], a[3], a[49]); // Sum(52) + res[53] = fma52lo(res[53], a[4], a[49]); // Sum(53) + res[54] = fma52hi(res[54], a[4], a[49]); // Sum(53) + res[54] = fma52lo(res[54], a[5], a[49]); // Sum(54) + res[55] = fma52hi(res[55], a[5], a[49]); // Sum(54) + res[55] = fma52lo(res[55], a[6], a[49]); // Sum(55) + res[56] = fma52hi(res[56], a[6], a[49]); // Sum(55) + res[56] = fma52lo(res[56], a[7], a[49]); // Sum(56) + res[57] = fma52hi(res[57], a[7], a[49]); // Sum(56) + res[57] = fma52lo(res[57], a[8], a[49]); // Sum(57) + res[58] = fma52hi(res[58], a[8], a[49]); // Sum(57) + res[58] = fma52lo(res[58], a[9], a[49]); // Sum(58) + res[59] = fma52hi(res[59], a[9], a[49]); // Sum(58) + res[59] = fma52lo(res[59], a[10], a[49]); // Sum(59) + res[60] = fma52hi(res[60], a[10], a[49]); // Sum(59) + res[50] = fma52lo(res[50], a[0], a[50]); // Sum(50) + res[51] = fma52hi(res[51], a[0], a[50]); // Sum(50) + res[51] = fma52lo(res[51], a[1], a[50]); // Sum(51) + res[52] = fma52hi(res[52], a[1], a[50]); // Sum(51) + res[52] = fma52lo(res[52], a[2], a[50]); // Sum(52) + res[53] = fma52hi(res[53], a[2], a[50]); // Sum(52) + res[53] = fma52lo(res[53], a[3], a[50]); // Sum(53) + res[54] = fma52hi(res[54], a[3], a[50]); // Sum(53) + res[54] = fma52lo(res[54], a[4], a[50]); // Sum(54) + res[55] = fma52hi(res[55], a[4], a[50]); // Sum(54) + res[55] = fma52lo(res[55], a[5], a[50]); // Sum(55) + res[56] = fma52hi(res[56], a[5], a[50]); // Sum(55) + res[56] = fma52lo(res[56], a[6], a[50]); // Sum(56) + res[57] = fma52hi(res[57], a[6], a[50]); // Sum(56) + res[57] = fma52lo(res[57], a[7], a[50]); // Sum(57) + res[58] = fma52hi(res[58], a[7], a[50]); // Sum(57) + res[58] = fma52lo(res[58], a[8], a[50]); // Sum(58) + res[59] = fma52hi(res[59], a[8], a[50]); // Sum(58) + res[59] = fma52lo(res[59], a[9], a[50]); // Sum(59) + res[60] = fma52hi(res[60], a[9], a[50]); // Sum(59) + res[51] = fma52lo(res[51], a[0], a[51]); // Sum(51) + res[52] = fma52hi(res[52], a[0], a[51]); // Sum(51) + res[52] = fma52lo(res[52], a[1], a[51]); // Sum(52) + res[53] = fma52hi(res[53], a[1], a[51]); // Sum(52) + res[53] = fma52lo(res[53], a[2], a[51]); // Sum(53) + res[54] = fma52hi(res[54], a[2], a[51]); // Sum(53) + res[54] = fma52lo(res[54], a[3], a[51]); // Sum(54) + res[55] = fma52hi(res[55], a[3], a[51]); // Sum(54) + res[55] = fma52lo(res[55], a[4], a[51]); // Sum(55) + res[56] = fma52hi(res[56], a[4], a[51]); // Sum(55) + res[56] = fma52lo(res[56], a[5], a[51]); // Sum(56) + res[57] = fma52hi(res[57], a[5], a[51]); // Sum(56) + res[57] = fma52lo(res[57], a[6], a[51]); // Sum(57) + res[58] = fma52hi(res[58], a[6], a[51]); // Sum(57) + res[58] = fma52lo(res[58], a[7], a[51]); // Sum(58) + res[59] = fma52hi(res[59], a[7], a[51]); // Sum(58) + res[59] = fma52lo(res[59], a[8], a[51]); // Sum(59) + res[60] = fma52hi(res[60], a[8], a[51]); // Sum(59) + res[52] = fma52lo(res[52], a[0], a[52]); // Sum(52) + res[53] = fma52hi(res[53], a[0], a[52]); // Sum(52) + res[53] = fma52lo(res[53], a[1], a[52]); // Sum(53) + res[54] = fma52hi(res[54], a[1], a[52]); // Sum(53) + res[54] = fma52lo(res[54], a[2], a[52]); // Sum(54) + res[55] = fma52hi(res[55], a[2], a[52]); // Sum(54) + res[55] = fma52lo(res[55], a[3], a[52]); // Sum(55) + res[56] = fma52hi(res[56], a[3], a[52]); // Sum(55) + res[56] = fma52lo(res[56], a[4], a[52]); // Sum(56) + res[57] = fma52hi(res[57], a[4], a[52]); // Sum(56) + res[57] = fma52lo(res[57], a[5], a[52]); // Sum(57) + res[58] = fma52hi(res[58], a[5], a[52]); // Sum(57) + res[58] = fma52lo(res[58], a[6], a[52]); // Sum(58) + res[59] = fma52hi(res[59], a[6], a[52]); // Sum(58) + res[59] = fma52lo(res[59], a[7], a[52]); // Sum(59) + res[60] = fma52hi(res[60], a[7], a[52]); // Sum(59) + res[53] = fma52lo(res[53], a[0], a[53]); // Sum(53) + res[54] = fma52hi(res[54], a[0], a[53]); // Sum(53) + res[54] = fma52lo(res[54], a[1], a[53]); // Sum(54) + res[55] = fma52hi(res[55], a[1], a[53]); // Sum(54) + res[55] = fma52lo(res[55], a[2], a[53]); // Sum(55) + res[56] = fma52hi(res[56], a[2], a[53]); // Sum(55) + res[56] = fma52lo(res[56], a[3], a[53]); // Sum(56) + res[57] = fma52hi(res[57], a[3], a[53]); // Sum(56) + res[57] = fma52lo(res[57], a[4], a[53]); // Sum(57) + res[58] = fma52hi(res[58], a[4], a[53]); // Sum(57) + res[58] = fma52lo(res[58], a[5], a[53]); // Sum(58) + res[59] = fma52hi(res[59], a[5], a[53]); // Sum(58) + res[59] = fma52lo(res[59], a[6], a[53]); // Sum(59) + res[60] = fma52hi(res[60], a[6], a[53]); // Sum(59) + res[54] = fma52lo(res[54], a[0], a[54]); // Sum(54) + res[55] = fma52hi(res[55], a[0], a[54]); // Sum(54) + res[55] = fma52lo(res[55], a[1], a[54]); // Sum(55) + res[56] = fma52hi(res[56], a[1], a[54]); // Sum(55) + res[56] = fma52lo(res[56], a[2], a[54]); // Sum(56) + res[57] = fma52hi(res[57], a[2], a[54]); // Sum(56) + res[57] = fma52lo(res[57], a[3], a[54]); // Sum(57) + res[58] = fma52hi(res[58], a[3], a[54]); // Sum(57) + res[58] = fma52lo(res[58], a[4], a[54]); // Sum(58) + res[59] = fma52hi(res[59], a[4], a[54]); // Sum(58) + res[59] = fma52lo(res[59], a[5], a[54]); // Sum(59) + res[60] = fma52hi(res[60], a[5], a[54]); // Sum(59) + res[55] = fma52lo(res[55], a[0], a[55]); // Sum(55) + res[56] = fma52hi(res[56], a[0], a[55]); // Sum(55) + res[56] = fma52lo(res[56], a[1], a[55]); // Sum(56) + res[57] = fma52hi(res[57], a[1], a[55]); // Sum(56) + res[57] = fma52lo(res[57], a[2], a[55]); // Sum(57) + res[58] = fma52hi(res[58], a[2], a[55]); // Sum(57) + res[58] = fma52lo(res[58], a[3], a[55]); // Sum(58) + res[59] = fma52hi(res[59], a[3], a[55]); // Sum(58) + res[59] = fma52lo(res[59], a[4], a[55]); // Sum(59) + res[60] = fma52hi(res[60], a[4], a[55]); // Sum(59) + res[56] = fma52lo(res[56], a[0], a[56]); // Sum(56) + res[57] = fma52hi(res[57], a[0], a[56]); // Sum(56) + res[57] = fma52lo(res[57], a[1], a[56]); // Sum(57) + res[58] = fma52hi(res[58], a[1], a[56]); // Sum(57) + res[58] = fma52lo(res[58], a[2], a[56]); // Sum(58) + res[59] = fma52hi(res[59], a[2], a[56]); // Sum(58) + res[59] = fma52lo(res[59], a[3], a[56]); // Sum(59) + res[60] = fma52hi(res[60], a[3], a[56]); // Sum(59) + res[57] = fma52lo(res[57], a[0], a[57]); // Sum(57) + res[58] = fma52hi(res[58], a[0], a[57]); // Sum(57) + res[58] = fma52lo(res[58], a[1], a[57]); // Sum(58) + res[59] = fma52hi(res[59], a[1], a[57]); // Sum(58) + res[59] = fma52lo(res[59], a[2], a[57]); // Sum(59) + res[60] = fma52hi(res[60], a[2], a[57]); // Sum(59) + res[58] = fma52lo(res[58], a[0], a[58]); // Sum(58) + res[59] = fma52hi(res[59], a[0], a[58]); // Sum(58) + res[59] = fma52lo(res[59], a[1], a[58]); // Sum(59) + res[60] = fma52hi(res[60], a[1], a[58]); // Sum(59) + res[59] = fma52lo(res[59], a[0], a[59]); // Sum(59) + res[60] = fma52hi(res[60], a[0], a[59]); // Sum(59) + res[48] = add64(res[48], res[48]); // Double(48) + res[49] = add64(res[49], res[49]); // Double(49) + res[50] = add64(res[50], res[50]); // Double(50) + res[51] = add64(res[51], res[51]); // Double(51) + res[52] = add64(res[52], res[52]); // Double(52) + res[53] = add64(res[53], res[53]); // Double(53) + res[54] = add64(res[54], res[54]); // Double(54) + res[55] = add64(res[55], res[55]); // Double(55) + res[56] = add64(res[56], res[56]); // Double(56) + res[57] = add64(res[57], res[57]); // Double(57) + res[58] = add64(res[58], res[58]); // Double(58) + res[59] = add64(res[59], res[59]); // Double(59) + res[48] = fma52lo(res[48], a[24], a[24]); // Add sqr(48) + res[49] = fma52hi(res[49], a[24], a[24]); // Add sqr(48) + res[50] = fma52lo(res[50], a[25], a[25]); // Add sqr(50) + res[51] = fma52hi(res[51], a[25], a[25]); // Add sqr(50) + res[52] = fma52lo(res[52], a[26], a[26]); // Add sqr(52) + res[53] = fma52hi(res[53], a[26], a[26]); // Add sqr(52) + res[54] = fma52lo(res[54], a[27], a[27]); // Add sqr(54) + res[55] = fma52hi(res[55], a[27], a[27]); // Add sqr(54) + res[56] = fma52lo(res[56], a[28], a[28]); // Add sqr(56) + res[57] = fma52hi(res[57], a[28], a[28]); // Add sqr(56) + res[58] = fma52lo(res[58], a[29], a[29]); // Add sqr(58) + res[59] = fma52hi(res[59], a[29], a[29]); // Add sqr(58) + res[60] = fma52lo(res[60], a[29], a[31]); // Sum(60) + res[61] = fma52hi(res[61], a[29], a[31]); // Sum(60) + res[61] = fma52lo(res[61], a[30], a[31]); // Sum(61) + res[62] = fma52hi(res[62], a[30], a[31]); // Sum(61) + res[60] = fma52lo(res[60], a[28], a[32]); // Sum(60) + res[61] = fma52hi(res[61], a[28], a[32]); // Sum(60) + res[61] = fma52lo(res[61], a[29], a[32]); // Sum(61) + res[62] = fma52hi(res[62], a[29], a[32]); // Sum(61) + res[62] = fma52lo(res[62], a[30], a[32]); // Sum(62) + res[63] = fma52hi(res[63], a[30], a[32]); // Sum(62) + res[63] = fma52lo(res[63], a[31], a[32]); // Sum(63) + res[64] = fma52hi(res[64], a[31], a[32]); // Sum(63) + res[60] = fma52lo(res[60], a[27], a[33]); // Sum(60) + res[61] = fma52hi(res[61], a[27], a[33]); // Sum(60) + res[61] = fma52lo(res[61], a[28], a[33]); // Sum(61) + res[62] = fma52hi(res[62], a[28], a[33]); // Sum(61) + res[62] = fma52lo(res[62], a[29], a[33]); // Sum(62) + res[63] = fma52hi(res[63], a[29], a[33]); // Sum(62) + res[63] = fma52lo(res[63], a[30], a[33]); // Sum(63) + res[64] = fma52hi(res[64], a[30], a[33]); // Sum(63) + res[64] = fma52lo(res[64], a[31], a[33]); // Sum(64) + res[65] = fma52hi(res[65], a[31], a[33]); // Sum(64) + res[65] = fma52lo(res[65], a[32], a[33]); // Sum(65) + res[66] = fma52hi(res[66], a[32], a[33]); // Sum(65) + res[60] = fma52lo(res[60], a[26], a[34]); // Sum(60) + res[61] = fma52hi(res[61], a[26], a[34]); // Sum(60) + res[61] = fma52lo(res[61], a[27], a[34]); // Sum(61) + res[62] = fma52hi(res[62], a[27], a[34]); // Sum(61) + res[62] = fma52lo(res[62], a[28], a[34]); // Sum(62) + res[63] = fma52hi(res[63], a[28], a[34]); // Sum(62) + res[63] = fma52lo(res[63], a[29], a[34]); // Sum(63) + res[64] = fma52hi(res[64], a[29], a[34]); // Sum(63) + res[64] = fma52lo(res[64], a[30], a[34]); // Sum(64) + res[65] = fma52hi(res[65], a[30], a[34]); // Sum(64) + res[65] = fma52lo(res[65], a[31], a[34]); // Sum(65) + res[66] = fma52hi(res[66], a[31], a[34]); // Sum(65) + res[66] = fma52lo(res[66], a[32], a[34]); // Sum(66) + res[67] = fma52hi(res[67], a[32], a[34]); // Sum(66) + res[67] = fma52lo(res[67], a[33], a[34]); // Sum(67) + res[68] = fma52hi(res[68], a[33], a[34]); // Sum(67) + res[60] = fma52lo(res[60], a[25], a[35]); // Sum(60) + res[61] = fma52hi(res[61], a[25], a[35]); // Sum(60) + res[61] = fma52lo(res[61], a[26], a[35]); // Sum(61) + res[62] = fma52hi(res[62], a[26], a[35]); // Sum(61) + res[62] = fma52lo(res[62], a[27], a[35]); // Sum(62) + res[63] = fma52hi(res[63], a[27], a[35]); // Sum(62) + res[63] = fma52lo(res[63], a[28], a[35]); // Sum(63) + res[64] = fma52hi(res[64], a[28], a[35]); // Sum(63) + res[64] = fma52lo(res[64], a[29], a[35]); // Sum(64) + res[65] = fma52hi(res[65], a[29], a[35]); // Sum(64) + res[65] = fma52lo(res[65], a[30], a[35]); // Sum(65) + res[66] = fma52hi(res[66], a[30], a[35]); // Sum(65) + res[66] = fma52lo(res[66], a[31], a[35]); // Sum(66) + res[67] = fma52hi(res[67], a[31], a[35]); // Sum(66) + res[67] = fma52lo(res[67], a[32], a[35]); // Sum(67) + res[68] = fma52hi(res[68], a[32], a[35]); // Sum(67) + res[68] = fma52lo(res[68], a[33], a[35]); // Sum(68) + res[69] = fma52hi(res[69], a[33], a[35]); // Sum(68) + res[69] = fma52lo(res[69], a[34], a[35]); // Sum(69) + res[70] = fma52hi(res[70], a[34], a[35]); // Sum(69) + res[60] = fma52lo(res[60], a[24], a[36]); // Sum(60) + res[61] = fma52hi(res[61], a[24], a[36]); // Sum(60) + res[61] = fma52lo(res[61], a[25], a[36]); // Sum(61) + res[62] = fma52hi(res[62], a[25], a[36]); // Sum(61) + res[62] = fma52lo(res[62], a[26], a[36]); // Sum(62) + res[63] = fma52hi(res[63], a[26], a[36]); // Sum(62) + res[63] = fma52lo(res[63], a[27], a[36]); // Sum(63) + res[64] = fma52hi(res[64], a[27], a[36]); // Sum(63) + res[64] = fma52lo(res[64], a[28], a[36]); // Sum(64) + res[65] = fma52hi(res[65], a[28], a[36]); // Sum(64) + res[65] = fma52lo(res[65], a[29], a[36]); // Sum(65) + res[66] = fma52hi(res[66], a[29], a[36]); // Sum(65) + res[66] = fma52lo(res[66], a[30], a[36]); // Sum(66) + res[67] = fma52hi(res[67], a[30], a[36]); // Sum(66) + res[67] = fma52lo(res[67], a[31], a[36]); // Sum(67) + res[68] = fma52hi(res[68], a[31], a[36]); // Sum(67) + res[68] = fma52lo(res[68], a[32], a[36]); // Sum(68) + res[69] = fma52hi(res[69], a[32], a[36]); // Sum(68) + res[69] = fma52lo(res[69], a[33], a[36]); // Sum(69) + res[70] = fma52hi(res[70], a[33], a[36]); // Sum(69) + res[70] = fma52lo(res[70], a[34], a[36]); // Sum(70) + res[71] = fma52hi(res[71], a[34], a[36]); // Sum(70) + res[71] = fma52lo(res[71], a[35], a[36]); // Sum(71) + res[72] = fma52hi(res[72], a[35], a[36]); // Sum(71) + res[60] = fma52lo(res[60], a[23], a[37]); // Sum(60) + res[61] = fma52hi(res[61], a[23], a[37]); // Sum(60) + res[61] = fma52lo(res[61], a[24], a[37]); // Sum(61) + res[62] = fma52hi(res[62], a[24], a[37]); // Sum(61) + res[62] = fma52lo(res[62], a[25], a[37]); // Sum(62) + res[63] = fma52hi(res[63], a[25], a[37]); // Sum(62) + res[63] = fma52lo(res[63], a[26], a[37]); // Sum(63) + res[64] = fma52hi(res[64], a[26], a[37]); // Sum(63) + res[64] = fma52lo(res[64], a[27], a[37]); // Sum(64) + res[65] = fma52hi(res[65], a[27], a[37]); // Sum(64) + res[65] = fma52lo(res[65], a[28], a[37]); // Sum(65) + res[66] = fma52hi(res[66], a[28], a[37]); // Sum(65) + res[66] = fma52lo(res[66], a[29], a[37]); // Sum(66) + res[67] = fma52hi(res[67], a[29], a[37]); // Sum(66) + res[67] = fma52lo(res[67], a[30], a[37]); // Sum(67) + res[68] = fma52hi(res[68], a[30], a[37]); // Sum(67) + res[68] = fma52lo(res[68], a[31], a[37]); // Sum(68) + res[69] = fma52hi(res[69], a[31], a[37]); // Sum(68) + res[69] = fma52lo(res[69], a[32], a[37]); // Sum(69) + res[70] = fma52hi(res[70], a[32], a[37]); // Sum(69) + res[70] = fma52lo(res[70], a[33], a[37]); // Sum(70) + res[71] = fma52hi(res[71], a[33], a[37]); // Sum(70) + res[71] = fma52lo(res[71], a[34], a[37]); // Sum(71) + res[72] = fma52hi(res[72], a[34], a[37]); // Sum(71) + res[60] = fma52lo(res[60], a[22], a[38]); // Sum(60) + res[61] = fma52hi(res[61], a[22], a[38]); // Sum(60) + res[61] = fma52lo(res[61], a[23], a[38]); // Sum(61) + res[62] = fma52hi(res[62], a[23], a[38]); // Sum(61) + res[62] = fma52lo(res[62], a[24], a[38]); // Sum(62) + res[63] = fma52hi(res[63], a[24], a[38]); // Sum(62) + res[63] = fma52lo(res[63], a[25], a[38]); // Sum(63) + res[64] = fma52hi(res[64], a[25], a[38]); // Sum(63) + res[64] = fma52lo(res[64], a[26], a[38]); // Sum(64) + res[65] = fma52hi(res[65], a[26], a[38]); // Sum(64) + res[65] = fma52lo(res[65], a[27], a[38]); // Sum(65) + res[66] = fma52hi(res[66], a[27], a[38]); // Sum(65) + res[66] = fma52lo(res[66], a[28], a[38]); // Sum(66) + res[67] = fma52hi(res[67], a[28], a[38]); // Sum(66) + res[67] = fma52lo(res[67], a[29], a[38]); // Sum(67) + res[68] = fma52hi(res[68], a[29], a[38]); // Sum(67) + res[68] = fma52lo(res[68], a[30], a[38]); // Sum(68) + res[69] = fma52hi(res[69], a[30], a[38]); // Sum(68) + res[69] = fma52lo(res[69], a[31], a[38]); // Sum(69) + res[70] = fma52hi(res[70], a[31], a[38]); // Sum(69) + res[70] = fma52lo(res[70], a[32], a[38]); // Sum(70) + res[71] = fma52hi(res[71], a[32], a[38]); // Sum(70) + res[71] = fma52lo(res[71], a[33], a[38]); // Sum(71) + res[72] = fma52hi(res[72], a[33], a[38]); // Sum(71) + res[60] = fma52lo(res[60], a[21], a[39]); // Sum(60) + res[61] = fma52hi(res[61], a[21], a[39]); // Sum(60) + res[61] = fma52lo(res[61], a[22], a[39]); // Sum(61) + res[62] = fma52hi(res[62], a[22], a[39]); // Sum(61) + res[62] = fma52lo(res[62], a[23], a[39]); // Sum(62) + res[63] = fma52hi(res[63], a[23], a[39]); // Sum(62) + res[63] = fma52lo(res[63], a[24], a[39]); // Sum(63) + res[64] = fma52hi(res[64], a[24], a[39]); // Sum(63) + res[64] = fma52lo(res[64], a[25], a[39]); // Sum(64) + res[65] = fma52hi(res[65], a[25], a[39]); // Sum(64) + res[65] = fma52lo(res[65], a[26], a[39]); // Sum(65) + res[66] = fma52hi(res[66], a[26], a[39]); // Sum(65) + res[66] = fma52lo(res[66], a[27], a[39]); // Sum(66) + res[67] = fma52hi(res[67], a[27], a[39]); // Sum(66) + res[67] = fma52lo(res[67], a[28], a[39]); // Sum(67) + res[68] = fma52hi(res[68], a[28], a[39]); // Sum(67) + res[68] = fma52lo(res[68], a[29], a[39]); // Sum(68) + res[69] = fma52hi(res[69], a[29], a[39]); // Sum(68) + res[69] = fma52lo(res[69], a[30], a[39]); // Sum(69) + res[70] = fma52hi(res[70], a[30], a[39]); // Sum(69) + res[70] = fma52lo(res[70], a[31], a[39]); // Sum(70) + res[71] = fma52hi(res[71], a[31], a[39]); // Sum(70) + res[71] = fma52lo(res[71], a[32], a[39]); // Sum(71) + res[72] = fma52hi(res[72], a[32], a[39]); // Sum(71) + res[60] = fma52lo(res[60], a[20], a[40]); // Sum(60) + res[61] = fma52hi(res[61], a[20], a[40]); // Sum(60) + res[61] = fma52lo(res[61], a[21], a[40]); // Sum(61) + res[62] = fma52hi(res[62], a[21], a[40]); // Sum(61) + res[62] = fma52lo(res[62], a[22], a[40]); // Sum(62) + res[63] = fma52hi(res[63], a[22], a[40]); // Sum(62) + res[63] = fma52lo(res[63], a[23], a[40]); // Sum(63) + res[64] = fma52hi(res[64], a[23], a[40]); // Sum(63) + res[64] = fma52lo(res[64], a[24], a[40]); // Sum(64) + res[65] = fma52hi(res[65], a[24], a[40]); // Sum(64) + res[65] = fma52lo(res[65], a[25], a[40]); // Sum(65) + res[66] = fma52hi(res[66], a[25], a[40]); // Sum(65) + res[66] = fma52lo(res[66], a[26], a[40]); // Sum(66) + res[67] = fma52hi(res[67], a[26], a[40]); // Sum(66) + res[67] = fma52lo(res[67], a[27], a[40]); // Sum(67) + res[68] = fma52hi(res[68], a[27], a[40]); // Sum(67) + res[68] = fma52lo(res[68], a[28], a[40]); // Sum(68) + res[69] = fma52hi(res[69], a[28], a[40]); // Sum(68) + res[69] = fma52lo(res[69], a[29], a[40]); // Sum(69) + res[70] = fma52hi(res[70], a[29], a[40]); // Sum(69) + res[70] = fma52lo(res[70], a[30], a[40]); // Sum(70) + res[71] = fma52hi(res[71], a[30], a[40]); // Sum(70) + res[71] = fma52lo(res[71], a[31], a[40]); // Sum(71) + res[72] = fma52hi(res[72], a[31], a[40]); // Sum(71) + res[60] = fma52lo(res[60], a[19], a[41]); // Sum(60) + res[61] = fma52hi(res[61], a[19], a[41]); // Sum(60) + res[61] = fma52lo(res[61], a[20], a[41]); // Sum(61) + res[62] = fma52hi(res[62], a[20], a[41]); // Sum(61) + res[62] = fma52lo(res[62], a[21], a[41]); // Sum(62) + res[63] = fma52hi(res[63], a[21], a[41]); // Sum(62) + res[63] = fma52lo(res[63], a[22], a[41]); // Sum(63) + res[64] = fma52hi(res[64], a[22], a[41]); // Sum(63) + res[64] = fma52lo(res[64], a[23], a[41]); // Sum(64) + res[65] = fma52hi(res[65], a[23], a[41]); // Sum(64) + res[65] = fma52lo(res[65], a[24], a[41]); // Sum(65) + res[66] = fma52hi(res[66], a[24], a[41]); // Sum(65) + res[66] = fma52lo(res[66], a[25], a[41]); // Sum(66) + res[67] = fma52hi(res[67], a[25], a[41]); // Sum(66) + res[67] = fma52lo(res[67], a[26], a[41]); // Sum(67) + res[68] = fma52hi(res[68], a[26], a[41]); // Sum(67) + res[68] = fma52lo(res[68], a[27], a[41]); // Sum(68) + res[69] = fma52hi(res[69], a[27], a[41]); // Sum(68) + res[69] = fma52lo(res[69], a[28], a[41]); // Sum(69) + res[70] = fma52hi(res[70], a[28], a[41]); // Sum(69) + res[70] = fma52lo(res[70], a[29], a[41]); // Sum(70) + res[71] = fma52hi(res[71], a[29], a[41]); // Sum(70) + res[71] = fma52lo(res[71], a[30], a[41]); // Sum(71) + res[72] = fma52hi(res[72], a[30], a[41]); // Sum(71) + res[60] = fma52lo(res[60], a[18], a[42]); // Sum(60) + res[61] = fma52hi(res[61], a[18], a[42]); // Sum(60) + res[61] = fma52lo(res[61], a[19], a[42]); // Sum(61) + res[62] = fma52hi(res[62], a[19], a[42]); // Sum(61) + res[62] = fma52lo(res[62], a[20], a[42]); // Sum(62) + res[63] = fma52hi(res[63], a[20], a[42]); // Sum(62) + res[63] = fma52lo(res[63], a[21], a[42]); // Sum(63) + res[64] = fma52hi(res[64], a[21], a[42]); // Sum(63) + res[64] = fma52lo(res[64], a[22], a[42]); // Sum(64) + res[65] = fma52hi(res[65], a[22], a[42]); // Sum(64) + res[65] = fma52lo(res[65], a[23], a[42]); // Sum(65) + res[66] = fma52hi(res[66], a[23], a[42]); // Sum(65) + res[66] = fma52lo(res[66], a[24], a[42]); // Sum(66) + res[67] = fma52hi(res[67], a[24], a[42]); // Sum(66) + res[67] = fma52lo(res[67], a[25], a[42]); // Sum(67) + res[68] = fma52hi(res[68], a[25], a[42]); // Sum(67) + res[68] = fma52lo(res[68], a[26], a[42]); // Sum(68) + res[69] = fma52hi(res[69], a[26], a[42]); // Sum(68) + res[69] = fma52lo(res[69], a[27], a[42]); // Sum(69) + res[70] = fma52hi(res[70], a[27], a[42]); // Sum(69) + res[70] = fma52lo(res[70], a[28], a[42]); // Sum(70) + res[71] = fma52hi(res[71], a[28], a[42]); // Sum(70) + res[71] = fma52lo(res[71], a[29], a[42]); // Sum(71) + res[72] = fma52hi(res[72], a[29], a[42]); // Sum(71) + res[60] = fma52lo(res[60], a[17], a[43]); // Sum(60) + res[61] = fma52hi(res[61], a[17], a[43]); // Sum(60) + res[61] = fma52lo(res[61], a[18], a[43]); // Sum(61) + res[62] = fma52hi(res[62], a[18], a[43]); // Sum(61) + res[62] = fma52lo(res[62], a[19], a[43]); // Sum(62) + res[63] = fma52hi(res[63], a[19], a[43]); // Sum(62) + res[63] = fma52lo(res[63], a[20], a[43]); // Sum(63) + res[64] = fma52hi(res[64], a[20], a[43]); // Sum(63) + res[64] = fma52lo(res[64], a[21], a[43]); // Sum(64) + res[65] = fma52hi(res[65], a[21], a[43]); // Sum(64) + res[65] = fma52lo(res[65], a[22], a[43]); // Sum(65) + res[66] = fma52hi(res[66], a[22], a[43]); // Sum(65) + res[66] = fma52lo(res[66], a[23], a[43]); // Sum(66) + res[67] = fma52hi(res[67], a[23], a[43]); // Sum(66) + res[67] = fma52lo(res[67], a[24], a[43]); // Sum(67) + res[68] = fma52hi(res[68], a[24], a[43]); // Sum(67) + res[68] = fma52lo(res[68], a[25], a[43]); // Sum(68) + res[69] = fma52hi(res[69], a[25], a[43]); // Sum(68) + res[69] = fma52lo(res[69], a[26], a[43]); // Sum(69) + res[70] = fma52hi(res[70], a[26], a[43]); // Sum(69) + res[70] = fma52lo(res[70], a[27], a[43]); // Sum(70) + res[71] = fma52hi(res[71], a[27], a[43]); // Sum(70) + res[71] = fma52lo(res[71], a[28], a[43]); // Sum(71) + res[72] = fma52hi(res[72], a[28], a[43]); // Sum(71) + res[60] = fma52lo(res[60], a[16], a[44]); // Sum(60) + res[61] = fma52hi(res[61], a[16], a[44]); // Sum(60) + res[61] = fma52lo(res[61], a[17], a[44]); // Sum(61) + res[62] = fma52hi(res[62], a[17], a[44]); // Sum(61) + res[62] = fma52lo(res[62], a[18], a[44]); // Sum(62) + res[63] = fma52hi(res[63], a[18], a[44]); // Sum(62) + res[63] = fma52lo(res[63], a[19], a[44]); // Sum(63) + res[64] = fma52hi(res[64], a[19], a[44]); // Sum(63) + res[64] = fma52lo(res[64], a[20], a[44]); // Sum(64) + res[65] = fma52hi(res[65], a[20], a[44]); // Sum(64) + res[65] = fma52lo(res[65], a[21], a[44]); // Sum(65) + res[66] = fma52hi(res[66], a[21], a[44]); // Sum(65) + res[66] = fma52lo(res[66], a[22], a[44]); // Sum(66) + res[67] = fma52hi(res[67], a[22], a[44]); // Sum(66) + res[67] = fma52lo(res[67], a[23], a[44]); // Sum(67) + res[68] = fma52hi(res[68], a[23], a[44]); // Sum(67) + res[68] = fma52lo(res[68], a[24], a[44]); // Sum(68) + res[69] = fma52hi(res[69], a[24], a[44]); // Sum(68) + res[69] = fma52lo(res[69], a[25], a[44]); // Sum(69) + res[70] = fma52hi(res[70], a[25], a[44]); // Sum(69) + res[70] = fma52lo(res[70], a[26], a[44]); // Sum(70) + res[71] = fma52hi(res[71], a[26], a[44]); // Sum(70) + res[71] = fma52lo(res[71], a[27], a[44]); // Sum(71) + res[72] = fma52hi(res[72], a[27], a[44]); // Sum(71) + res[60] = fma52lo(res[60], a[15], a[45]); // Sum(60) + res[61] = fma52hi(res[61], a[15], a[45]); // Sum(60) + res[61] = fma52lo(res[61], a[16], a[45]); // Sum(61) + res[62] = fma52hi(res[62], a[16], a[45]); // Sum(61) + res[62] = fma52lo(res[62], a[17], a[45]); // Sum(62) + res[63] = fma52hi(res[63], a[17], a[45]); // Sum(62) + res[63] = fma52lo(res[63], a[18], a[45]); // Sum(63) + res[64] = fma52hi(res[64], a[18], a[45]); // Sum(63) + res[64] = fma52lo(res[64], a[19], a[45]); // Sum(64) + res[65] = fma52hi(res[65], a[19], a[45]); // Sum(64) + res[65] = fma52lo(res[65], a[20], a[45]); // Sum(65) + res[66] = fma52hi(res[66], a[20], a[45]); // Sum(65) + res[66] = fma52lo(res[66], a[21], a[45]); // Sum(66) + res[67] = fma52hi(res[67], a[21], a[45]); // Sum(66) + res[67] = fma52lo(res[67], a[22], a[45]); // Sum(67) + res[68] = fma52hi(res[68], a[22], a[45]); // Sum(67) + res[68] = fma52lo(res[68], a[23], a[45]); // Sum(68) + res[69] = fma52hi(res[69], a[23], a[45]); // Sum(68) + res[69] = fma52lo(res[69], a[24], a[45]); // Sum(69) + res[70] = fma52hi(res[70], a[24], a[45]); // Sum(69) + res[70] = fma52lo(res[70], a[25], a[45]); // Sum(70) + res[71] = fma52hi(res[71], a[25], a[45]); // Sum(70) + res[71] = fma52lo(res[71], a[26], a[45]); // Sum(71) + res[72] = fma52hi(res[72], a[26], a[45]); // Sum(71) + res[60] = fma52lo(res[60], a[14], a[46]); // Sum(60) + res[61] = fma52hi(res[61], a[14], a[46]); // Sum(60) + res[61] = fma52lo(res[61], a[15], a[46]); // Sum(61) + res[62] = fma52hi(res[62], a[15], a[46]); // Sum(61) + res[62] = fma52lo(res[62], a[16], a[46]); // Sum(62) + res[63] = fma52hi(res[63], a[16], a[46]); // Sum(62) + res[63] = fma52lo(res[63], a[17], a[46]); // Sum(63) + res[64] = fma52hi(res[64], a[17], a[46]); // Sum(63) + res[64] = fma52lo(res[64], a[18], a[46]); // Sum(64) + res[65] = fma52hi(res[65], a[18], a[46]); // Sum(64) + res[65] = fma52lo(res[65], a[19], a[46]); // Sum(65) + res[66] = fma52hi(res[66], a[19], a[46]); // Sum(65) + res[66] = fma52lo(res[66], a[20], a[46]); // Sum(66) + res[67] = fma52hi(res[67], a[20], a[46]); // Sum(66) + res[67] = fma52lo(res[67], a[21], a[46]); // Sum(67) + res[68] = fma52hi(res[68], a[21], a[46]); // Sum(67) + res[68] = fma52lo(res[68], a[22], a[46]); // Sum(68) + res[69] = fma52hi(res[69], a[22], a[46]); // Sum(68) + res[69] = fma52lo(res[69], a[23], a[46]); // Sum(69) + res[70] = fma52hi(res[70], a[23], a[46]); // Sum(69) + res[70] = fma52lo(res[70], a[24], a[46]); // Sum(70) + res[71] = fma52hi(res[71], a[24], a[46]); // Sum(70) + res[71] = fma52lo(res[71], a[25], a[46]); // Sum(71) + res[72] = fma52hi(res[72], a[25], a[46]); // Sum(71) + res[60] = fma52lo(res[60], a[13], a[47]); // Sum(60) + res[61] = fma52hi(res[61], a[13], a[47]); // Sum(60) + res[61] = fma52lo(res[61], a[14], a[47]); // Sum(61) + res[62] = fma52hi(res[62], a[14], a[47]); // Sum(61) + res[62] = fma52lo(res[62], a[15], a[47]); // Sum(62) + res[63] = fma52hi(res[63], a[15], a[47]); // Sum(62) + res[63] = fma52lo(res[63], a[16], a[47]); // Sum(63) + res[64] = fma52hi(res[64], a[16], a[47]); // Sum(63) + res[64] = fma52lo(res[64], a[17], a[47]); // Sum(64) + res[65] = fma52hi(res[65], a[17], a[47]); // Sum(64) + res[65] = fma52lo(res[65], a[18], a[47]); // Sum(65) + res[66] = fma52hi(res[66], a[18], a[47]); // Sum(65) + res[66] = fma52lo(res[66], a[19], a[47]); // Sum(66) + res[67] = fma52hi(res[67], a[19], a[47]); // Sum(66) + res[67] = fma52lo(res[67], a[20], a[47]); // Sum(67) + res[68] = fma52hi(res[68], a[20], a[47]); // Sum(67) + res[68] = fma52lo(res[68], a[21], a[47]); // Sum(68) + res[69] = fma52hi(res[69], a[21], a[47]); // Sum(68) + res[69] = fma52lo(res[69], a[22], a[47]); // Sum(69) + res[70] = fma52hi(res[70], a[22], a[47]); // Sum(69) + res[70] = fma52lo(res[70], a[23], a[47]); // Sum(70) + res[71] = fma52hi(res[71], a[23], a[47]); // Sum(70) + res[71] = fma52lo(res[71], a[24], a[47]); // Sum(71) + res[72] = fma52hi(res[72], a[24], a[47]); // Sum(71) + res[60] = fma52lo(res[60], a[12], a[48]); // Sum(60) + res[61] = fma52hi(res[61], a[12], a[48]); // Sum(60) + res[61] = fma52lo(res[61], a[13], a[48]); // Sum(61) + res[62] = fma52hi(res[62], a[13], a[48]); // Sum(61) + res[62] = fma52lo(res[62], a[14], a[48]); // Sum(62) + res[63] = fma52hi(res[63], a[14], a[48]); // Sum(62) + res[63] = fma52lo(res[63], a[15], a[48]); // Sum(63) + res[64] = fma52hi(res[64], a[15], a[48]); // Sum(63) + res[64] = fma52lo(res[64], a[16], a[48]); // Sum(64) + res[65] = fma52hi(res[65], a[16], a[48]); // Sum(64) + res[65] = fma52lo(res[65], a[17], a[48]); // Sum(65) + res[66] = fma52hi(res[66], a[17], a[48]); // Sum(65) + res[66] = fma52lo(res[66], a[18], a[48]); // Sum(66) + res[67] = fma52hi(res[67], a[18], a[48]); // Sum(66) + res[67] = fma52lo(res[67], a[19], a[48]); // Sum(67) + res[68] = fma52hi(res[68], a[19], a[48]); // Sum(67) + res[68] = fma52lo(res[68], a[20], a[48]); // Sum(68) + res[69] = fma52hi(res[69], a[20], a[48]); // Sum(68) + res[69] = fma52lo(res[69], a[21], a[48]); // Sum(69) + res[70] = fma52hi(res[70], a[21], a[48]); // Sum(69) + res[70] = fma52lo(res[70], a[22], a[48]); // Sum(70) + res[71] = fma52hi(res[71], a[22], a[48]); // Sum(70) + res[71] = fma52lo(res[71], a[23], a[48]); // Sum(71) + res[72] = fma52hi(res[72], a[23], a[48]); // Sum(71) + res[60] = fma52lo(res[60], a[11], a[49]); // Sum(60) + res[61] = fma52hi(res[61], a[11], a[49]); // Sum(60) + res[61] = fma52lo(res[61], a[12], a[49]); // Sum(61) + res[62] = fma52hi(res[62], a[12], a[49]); // Sum(61) + res[62] = fma52lo(res[62], a[13], a[49]); // Sum(62) + res[63] = fma52hi(res[63], a[13], a[49]); // Sum(62) + res[63] = fma52lo(res[63], a[14], a[49]); // Sum(63) + res[64] = fma52hi(res[64], a[14], a[49]); // Sum(63) + res[64] = fma52lo(res[64], a[15], a[49]); // Sum(64) + res[65] = fma52hi(res[65], a[15], a[49]); // Sum(64) + res[65] = fma52lo(res[65], a[16], a[49]); // Sum(65) + res[66] = fma52hi(res[66], a[16], a[49]); // Sum(65) + res[66] = fma52lo(res[66], a[17], a[49]); // Sum(66) + res[67] = fma52hi(res[67], a[17], a[49]); // Sum(66) + res[67] = fma52lo(res[67], a[18], a[49]); // Sum(67) + res[68] = fma52hi(res[68], a[18], a[49]); // Sum(67) + res[68] = fma52lo(res[68], a[19], a[49]); // Sum(68) + res[69] = fma52hi(res[69], a[19], a[49]); // Sum(68) + res[69] = fma52lo(res[69], a[20], a[49]); // Sum(69) + res[70] = fma52hi(res[70], a[20], a[49]); // Sum(69) + res[70] = fma52lo(res[70], a[21], a[49]); // Sum(70) + res[71] = fma52hi(res[71], a[21], a[49]); // Sum(70) + res[71] = fma52lo(res[71], a[22], a[49]); // Sum(71) + res[72] = fma52hi(res[72], a[22], a[49]); // Sum(71) + res[60] = fma52lo(res[60], a[10], a[50]); // Sum(60) + res[61] = fma52hi(res[61], a[10], a[50]); // Sum(60) + res[61] = fma52lo(res[61], a[11], a[50]); // Sum(61) + res[62] = fma52hi(res[62], a[11], a[50]); // Sum(61) + res[62] = fma52lo(res[62], a[12], a[50]); // Sum(62) + res[63] = fma52hi(res[63], a[12], a[50]); // Sum(62) + res[63] = fma52lo(res[63], a[13], a[50]); // Sum(63) + res[64] = fma52hi(res[64], a[13], a[50]); // Sum(63) + res[64] = fma52lo(res[64], a[14], a[50]); // Sum(64) + res[65] = fma52hi(res[65], a[14], a[50]); // Sum(64) + res[65] = fma52lo(res[65], a[15], a[50]); // Sum(65) + res[66] = fma52hi(res[66], a[15], a[50]); // Sum(65) + res[66] = fma52lo(res[66], a[16], a[50]); // Sum(66) + res[67] = fma52hi(res[67], a[16], a[50]); // Sum(66) + res[67] = fma52lo(res[67], a[17], a[50]); // Sum(67) + res[68] = fma52hi(res[68], a[17], a[50]); // Sum(67) + res[68] = fma52lo(res[68], a[18], a[50]); // Sum(68) + res[69] = fma52hi(res[69], a[18], a[50]); // Sum(68) + res[69] = fma52lo(res[69], a[19], a[50]); // Sum(69) + res[70] = fma52hi(res[70], a[19], a[50]); // Sum(69) + res[70] = fma52lo(res[70], a[20], a[50]); // Sum(70) + res[71] = fma52hi(res[71], a[20], a[50]); // Sum(70) + res[71] = fma52lo(res[71], a[21], a[50]); // Sum(71) + res[72] = fma52hi(res[72], a[21], a[50]); // Sum(71) + res[60] = fma52lo(res[60], a[9], a[51]); // Sum(60) + res[61] = fma52hi(res[61], a[9], a[51]); // Sum(60) + res[61] = fma52lo(res[61], a[10], a[51]); // Sum(61) + res[62] = fma52hi(res[62], a[10], a[51]); // Sum(61) + res[62] = fma52lo(res[62], a[11], a[51]); // Sum(62) + res[63] = fma52hi(res[63], a[11], a[51]); // Sum(62) + res[63] = fma52lo(res[63], a[12], a[51]); // Sum(63) + res[64] = fma52hi(res[64], a[12], a[51]); // Sum(63) + res[64] = fma52lo(res[64], a[13], a[51]); // Sum(64) + res[65] = fma52hi(res[65], a[13], a[51]); // Sum(64) + res[65] = fma52lo(res[65], a[14], a[51]); // Sum(65) + res[66] = fma52hi(res[66], a[14], a[51]); // Sum(65) + res[66] = fma52lo(res[66], a[15], a[51]); // Sum(66) + res[67] = fma52hi(res[67], a[15], a[51]); // Sum(66) + res[67] = fma52lo(res[67], a[16], a[51]); // Sum(67) + res[68] = fma52hi(res[68], a[16], a[51]); // Sum(67) + res[68] = fma52lo(res[68], a[17], a[51]); // Sum(68) + res[69] = fma52hi(res[69], a[17], a[51]); // Sum(68) + res[69] = fma52lo(res[69], a[18], a[51]); // Sum(69) + res[70] = fma52hi(res[70], a[18], a[51]); // Sum(69) + res[70] = fma52lo(res[70], a[19], a[51]); // Sum(70) + res[71] = fma52hi(res[71], a[19], a[51]); // Sum(70) + res[71] = fma52lo(res[71], a[20], a[51]); // Sum(71) + res[72] = fma52hi(res[72], a[20], a[51]); // Sum(71) + res[60] = fma52lo(res[60], a[8], a[52]); // Sum(60) + res[61] = fma52hi(res[61], a[8], a[52]); // Sum(60) + res[61] = fma52lo(res[61], a[9], a[52]); // Sum(61) + res[62] = fma52hi(res[62], a[9], a[52]); // Sum(61) + res[62] = fma52lo(res[62], a[10], a[52]); // Sum(62) + res[63] = fma52hi(res[63], a[10], a[52]); // Sum(62) + res[63] = fma52lo(res[63], a[11], a[52]); // Sum(63) + res[64] = fma52hi(res[64], a[11], a[52]); // Sum(63) + res[64] = fma52lo(res[64], a[12], a[52]); // Sum(64) + res[65] = fma52hi(res[65], a[12], a[52]); // Sum(64) + res[65] = fma52lo(res[65], a[13], a[52]); // Sum(65) + res[66] = fma52hi(res[66], a[13], a[52]); // Sum(65) + res[66] = fma52lo(res[66], a[14], a[52]); // Sum(66) + res[67] = fma52hi(res[67], a[14], a[52]); // Sum(66) + res[67] = fma52lo(res[67], a[15], a[52]); // Sum(67) + res[68] = fma52hi(res[68], a[15], a[52]); // Sum(67) + res[68] = fma52lo(res[68], a[16], a[52]); // Sum(68) + res[69] = fma52hi(res[69], a[16], a[52]); // Sum(68) + res[69] = fma52lo(res[69], a[17], a[52]); // Sum(69) + res[70] = fma52hi(res[70], a[17], a[52]); // Sum(69) + res[70] = fma52lo(res[70], a[18], a[52]); // Sum(70) + res[71] = fma52hi(res[71], a[18], a[52]); // Sum(70) + res[71] = fma52lo(res[71], a[19], a[52]); // Sum(71) + res[72] = fma52hi(res[72], a[19], a[52]); // Sum(71) + res[60] = fma52lo(res[60], a[7], a[53]); // Sum(60) + res[61] = fma52hi(res[61], a[7], a[53]); // Sum(60) + res[61] = fma52lo(res[61], a[8], a[53]); // Sum(61) + res[62] = fma52hi(res[62], a[8], a[53]); // Sum(61) + res[62] = fma52lo(res[62], a[9], a[53]); // Sum(62) + res[63] = fma52hi(res[63], a[9], a[53]); // Sum(62) + res[63] = fma52lo(res[63], a[10], a[53]); // Sum(63) + res[64] = fma52hi(res[64], a[10], a[53]); // Sum(63) + res[64] = fma52lo(res[64], a[11], a[53]); // Sum(64) + res[65] = fma52hi(res[65], a[11], a[53]); // Sum(64) + res[65] = fma52lo(res[65], a[12], a[53]); // Sum(65) + res[66] = fma52hi(res[66], a[12], a[53]); // Sum(65) + res[66] = fma52lo(res[66], a[13], a[53]); // Sum(66) + res[67] = fma52hi(res[67], a[13], a[53]); // Sum(66) + res[67] = fma52lo(res[67], a[14], a[53]); // Sum(67) + res[68] = fma52hi(res[68], a[14], a[53]); // Sum(67) + res[68] = fma52lo(res[68], a[15], a[53]); // Sum(68) + res[69] = fma52hi(res[69], a[15], a[53]); // Sum(68) + res[69] = fma52lo(res[69], a[16], a[53]); // Sum(69) + res[70] = fma52hi(res[70], a[16], a[53]); // Sum(69) + res[70] = fma52lo(res[70], a[17], a[53]); // Sum(70) + res[71] = fma52hi(res[71], a[17], a[53]); // Sum(70) + res[71] = fma52lo(res[71], a[18], a[53]); // Sum(71) + res[72] = fma52hi(res[72], a[18], a[53]); // Sum(71) + res[60] = fma52lo(res[60], a[6], a[54]); // Sum(60) + res[61] = fma52hi(res[61], a[6], a[54]); // Sum(60) + res[61] = fma52lo(res[61], a[7], a[54]); // Sum(61) + res[62] = fma52hi(res[62], a[7], a[54]); // Sum(61) + res[62] = fma52lo(res[62], a[8], a[54]); // Sum(62) + res[63] = fma52hi(res[63], a[8], a[54]); // Sum(62) + res[63] = fma52lo(res[63], a[9], a[54]); // Sum(63) + res[64] = fma52hi(res[64], a[9], a[54]); // Sum(63) + res[64] = fma52lo(res[64], a[10], a[54]); // Sum(64) + res[65] = fma52hi(res[65], a[10], a[54]); // Sum(64) + res[65] = fma52lo(res[65], a[11], a[54]); // Sum(65) + res[66] = fma52hi(res[66], a[11], a[54]); // Sum(65) + res[66] = fma52lo(res[66], a[12], a[54]); // Sum(66) + res[67] = fma52hi(res[67], a[12], a[54]); // Sum(66) + res[67] = fma52lo(res[67], a[13], a[54]); // Sum(67) + res[68] = fma52hi(res[68], a[13], a[54]); // Sum(67) + res[68] = fma52lo(res[68], a[14], a[54]); // Sum(68) + res[69] = fma52hi(res[69], a[14], a[54]); // Sum(68) + res[69] = fma52lo(res[69], a[15], a[54]); // Sum(69) + res[70] = fma52hi(res[70], a[15], a[54]); // Sum(69) + res[70] = fma52lo(res[70], a[16], a[54]); // Sum(70) + res[71] = fma52hi(res[71], a[16], a[54]); // Sum(70) + res[71] = fma52lo(res[71], a[17], a[54]); // Sum(71) + res[72] = fma52hi(res[72], a[17], a[54]); // Sum(71) + res[60] = fma52lo(res[60], a[5], a[55]); // Sum(60) + res[61] = fma52hi(res[61], a[5], a[55]); // Sum(60) + res[61] = fma52lo(res[61], a[6], a[55]); // Sum(61) + res[62] = fma52hi(res[62], a[6], a[55]); // Sum(61) + res[62] = fma52lo(res[62], a[7], a[55]); // Sum(62) + res[63] = fma52hi(res[63], a[7], a[55]); // Sum(62) + res[63] = fma52lo(res[63], a[8], a[55]); // Sum(63) + res[64] = fma52hi(res[64], a[8], a[55]); // Sum(63) + res[64] = fma52lo(res[64], a[9], a[55]); // Sum(64) + res[65] = fma52hi(res[65], a[9], a[55]); // Sum(64) + res[65] = fma52lo(res[65], a[10], a[55]); // Sum(65) + res[66] = fma52hi(res[66], a[10], a[55]); // Sum(65) + res[66] = fma52lo(res[66], a[11], a[55]); // Sum(66) + res[67] = fma52hi(res[67], a[11], a[55]); // Sum(66) + res[67] = fma52lo(res[67], a[12], a[55]); // Sum(67) + res[68] = fma52hi(res[68], a[12], a[55]); // Sum(67) + res[68] = fma52lo(res[68], a[13], a[55]); // Sum(68) + res[69] = fma52hi(res[69], a[13], a[55]); // Sum(68) + res[69] = fma52lo(res[69], a[14], a[55]); // Sum(69) + res[70] = fma52hi(res[70], a[14], a[55]); // Sum(69) + res[70] = fma52lo(res[70], a[15], a[55]); // Sum(70) + res[71] = fma52hi(res[71], a[15], a[55]); // Sum(70) + res[71] = fma52lo(res[71], a[16], a[55]); // Sum(71) + res[72] = fma52hi(res[72], a[16], a[55]); // Sum(71) + res[60] = fma52lo(res[60], a[4], a[56]); // Sum(60) + res[61] = fma52hi(res[61], a[4], a[56]); // Sum(60) + res[61] = fma52lo(res[61], a[5], a[56]); // Sum(61) + res[62] = fma52hi(res[62], a[5], a[56]); // Sum(61) + res[62] = fma52lo(res[62], a[6], a[56]); // Sum(62) + res[63] = fma52hi(res[63], a[6], a[56]); // Sum(62) + res[63] = fma52lo(res[63], a[7], a[56]); // Sum(63) + res[64] = fma52hi(res[64], a[7], a[56]); // Sum(63) + res[64] = fma52lo(res[64], a[8], a[56]); // Sum(64) + res[65] = fma52hi(res[65], a[8], a[56]); // Sum(64) + res[65] = fma52lo(res[65], a[9], a[56]); // Sum(65) + res[66] = fma52hi(res[66], a[9], a[56]); // Sum(65) + res[66] = fma52lo(res[66], a[10], a[56]); // Sum(66) + res[67] = fma52hi(res[67], a[10], a[56]); // Sum(66) + res[67] = fma52lo(res[67], a[11], a[56]); // Sum(67) + res[68] = fma52hi(res[68], a[11], a[56]); // Sum(67) + res[68] = fma52lo(res[68], a[12], a[56]); // Sum(68) + res[69] = fma52hi(res[69], a[12], a[56]); // Sum(68) + res[69] = fma52lo(res[69], a[13], a[56]); // Sum(69) + res[70] = fma52hi(res[70], a[13], a[56]); // Sum(69) + res[70] = fma52lo(res[70], a[14], a[56]); // Sum(70) + res[71] = fma52hi(res[71], a[14], a[56]); // Sum(70) + res[71] = fma52lo(res[71], a[15], a[56]); // Sum(71) + res[72] = fma52hi(res[72], a[15], a[56]); // Sum(71) + res[60] = fma52lo(res[60], a[3], a[57]); // Sum(60) + res[61] = fma52hi(res[61], a[3], a[57]); // Sum(60) + res[61] = fma52lo(res[61], a[4], a[57]); // Sum(61) + res[62] = fma52hi(res[62], a[4], a[57]); // Sum(61) + res[62] = fma52lo(res[62], a[5], a[57]); // Sum(62) + res[63] = fma52hi(res[63], a[5], a[57]); // Sum(62) + res[63] = fma52lo(res[63], a[6], a[57]); // Sum(63) + res[64] = fma52hi(res[64], a[6], a[57]); // Sum(63) + res[64] = fma52lo(res[64], a[7], a[57]); // Sum(64) + res[65] = fma52hi(res[65], a[7], a[57]); // Sum(64) + res[65] = fma52lo(res[65], a[8], a[57]); // Sum(65) + res[66] = fma52hi(res[66], a[8], a[57]); // Sum(65) + res[66] = fma52lo(res[66], a[9], a[57]); // Sum(66) + res[67] = fma52hi(res[67], a[9], a[57]); // Sum(66) + res[67] = fma52lo(res[67], a[10], a[57]); // Sum(67) + res[68] = fma52hi(res[68], a[10], a[57]); // Sum(67) + res[68] = fma52lo(res[68], a[11], a[57]); // Sum(68) + res[69] = fma52hi(res[69], a[11], a[57]); // Sum(68) + res[69] = fma52lo(res[69], a[12], a[57]); // Sum(69) + res[70] = fma52hi(res[70], a[12], a[57]); // Sum(69) + res[70] = fma52lo(res[70], a[13], a[57]); // Sum(70) + res[71] = fma52hi(res[71], a[13], a[57]); // Sum(70) + res[71] = fma52lo(res[71], a[14], a[57]); // Sum(71) + res[72] = fma52hi(res[72], a[14], a[57]); // Sum(71) + res[60] = fma52lo(res[60], a[2], a[58]); // Sum(60) + res[61] = fma52hi(res[61], a[2], a[58]); // Sum(60) + res[61] = fma52lo(res[61], a[3], a[58]); // Sum(61) + res[62] = fma52hi(res[62], a[3], a[58]); // Sum(61) + res[62] = fma52lo(res[62], a[4], a[58]); // Sum(62) + res[63] = fma52hi(res[63], a[4], a[58]); // Sum(62) + res[63] = fma52lo(res[63], a[5], a[58]); // Sum(63) + res[64] = fma52hi(res[64], a[5], a[58]); // Sum(63) + res[64] = fma52lo(res[64], a[6], a[58]); // Sum(64) + res[65] = fma52hi(res[65], a[6], a[58]); // Sum(64) + res[65] = fma52lo(res[65], a[7], a[58]); // Sum(65) + res[66] = fma52hi(res[66], a[7], a[58]); // Sum(65) + res[66] = fma52lo(res[66], a[8], a[58]); // Sum(66) + res[67] = fma52hi(res[67], a[8], a[58]); // Sum(66) + res[67] = fma52lo(res[67], a[9], a[58]); // Sum(67) + res[68] = fma52hi(res[68], a[9], a[58]); // Sum(67) + res[68] = fma52lo(res[68], a[10], a[58]); // Sum(68) + res[69] = fma52hi(res[69], a[10], a[58]); // Sum(68) + res[69] = fma52lo(res[69], a[11], a[58]); // Sum(69) + res[70] = fma52hi(res[70], a[11], a[58]); // Sum(69) + res[70] = fma52lo(res[70], a[12], a[58]); // Sum(70) + res[71] = fma52hi(res[71], a[12], a[58]); // Sum(70) + res[71] = fma52lo(res[71], a[13], a[58]); // Sum(71) + res[72] = fma52hi(res[72], a[13], a[58]); // Sum(71) + res[60] = fma52lo(res[60], a[1], a[59]); // Sum(60) + res[61] = fma52hi(res[61], a[1], a[59]); // Sum(60) + res[61] = fma52lo(res[61], a[2], a[59]); // Sum(61) + res[62] = fma52hi(res[62], a[2], a[59]); // Sum(61) + res[62] = fma52lo(res[62], a[3], a[59]); // Sum(62) + res[63] = fma52hi(res[63], a[3], a[59]); // Sum(62) + res[63] = fma52lo(res[63], a[4], a[59]); // Sum(63) + res[64] = fma52hi(res[64], a[4], a[59]); // Sum(63) + res[64] = fma52lo(res[64], a[5], a[59]); // Sum(64) + res[65] = fma52hi(res[65], a[5], a[59]); // Sum(64) + res[65] = fma52lo(res[65], a[6], a[59]); // Sum(65) + res[66] = fma52hi(res[66], a[6], a[59]); // Sum(65) + res[66] = fma52lo(res[66], a[7], a[59]); // Sum(66) + res[67] = fma52hi(res[67], a[7], a[59]); // Sum(66) + res[67] = fma52lo(res[67], a[8], a[59]); // Sum(67) + res[68] = fma52hi(res[68], a[8], a[59]); // Sum(67) + res[68] = fma52lo(res[68], a[9], a[59]); // Sum(68) + res[69] = fma52hi(res[69], a[9], a[59]); // Sum(68) + res[69] = fma52lo(res[69], a[10], a[59]); // Sum(69) + res[70] = fma52hi(res[70], a[10], a[59]); // Sum(69) + res[70] = fma52lo(res[70], a[11], a[59]); // Sum(70) + res[71] = fma52hi(res[71], a[11], a[59]); // Sum(70) + res[71] = fma52lo(res[71], a[12], a[59]); // Sum(71) + res[72] = fma52hi(res[72], a[12], a[59]); // Sum(71) + res[60] = add64(res[60], res[60]); // Double(60) + res[61] = add64(res[61], res[61]); // Double(61) + res[62] = add64(res[62], res[62]); // Double(62) + res[63] = add64(res[63], res[63]); // Double(63) + res[64] = add64(res[64], res[64]); // Double(64) + res[65] = add64(res[65], res[65]); // Double(65) + res[66] = add64(res[66], res[66]); // Double(66) + res[67] = add64(res[67], res[67]); // Double(67) + res[68] = add64(res[68], res[68]); // Double(68) + res[69] = add64(res[69], res[69]); // Double(69) + res[70] = add64(res[70], res[70]); // Double(70) + res[71] = add64(res[71], res[71]); // Double(71) + res[60] = fma52lo(res[60], a[30], a[30]); // Add sqr(60) + res[61] = fma52hi(res[61], a[30], a[30]); // Add sqr(60) + res[62] = fma52lo(res[62], a[31], a[31]); // Add sqr(62) + res[63] = fma52hi(res[63], a[31], a[31]); // Add sqr(62) + res[64] = fma52lo(res[64], a[32], a[32]); // Add sqr(64) + res[65] = fma52hi(res[65], a[32], a[32]); // Add sqr(64) + res[66] = fma52lo(res[66], a[33], a[33]); // Add sqr(66) + res[67] = fma52hi(res[67], a[33], a[33]); // Add sqr(66) + res[68] = fma52lo(res[68], a[34], a[34]); // Add sqr(68) + res[69] = fma52hi(res[69], a[34], a[34]); // Add sqr(68) + res[70] = fma52lo(res[70], a[35], a[35]); // Add sqr(70) + res[71] = fma52hi(res[71], a[35], a[35]); // Add sqr(70) + res[72] = fma52lo(res[72], a[35], a[37]); // Sum(72) + res[73] = fma52hi(res[73], a[35], a[37]); // Sum(72) + res[73] = fma52lo(res[73], a[36], a[37]); // Sum(73) + res[74] = fma52hi(res[74], a[36], a[37]); // Sum(73) + res[72] = fma52lo(res[72], a[34], a[38]); // Sum(72) + res[73] = fma52hi(res[73], a[34], a[38]); // Sum(72) + res[73] = fma52lo(res[73], a[35], a[38]); // Sum(73) + res[74] = fma52hi(res[74], a[35], a[38]); // Sum(73) + res[74] = fma52lo(res[74], a[36], a[38]); // Sum(74) + res[75] = fma52hi(res[75], a[36], a[38]); // Sum(74) + res[75] = fma52lo(res[75], a[37], a[38]); // Sum(75) + res[76] = fma52hi(res[76], a[37], a[38]); // Sum(75) + res[72] = fma52lo(res[72], a[33], a[39]); // Sum(72) + res[73] = fma52hi(res[73], a[33], a[39]); // Sum(72) + res[73] = fma52lo(res[73], a[34], a[39]); // Sum(73) + res[74] = fma52hi(res[74], a[34], a[39]); // Sum(73) + res[74] = fma52lo(res[74], a[35], a[39]); // Sum(74) + res[75] = fma52hi(res[75], a[35], a[39]); // Sum(74) + res[75] = fma52lo(res[75], a[36], a[39]); // Sum(75) + res[76] = fma52hi(res[76], a[36], a[39]); // Sum(75) + res[76] = fma52lo(res[76], a[37], a[39]); // Sum(76) + res[77] = fma52hi(res[77], a[37], a[39]); // Sum(76) + res[77] = fma52lo(res[77], a[38], a[39]); // Sum(77) + res[78] = fma52hi(res[78], a[38], a[39]); // Sum(77) + res[72] = fma52lo(res[72], a[32], a[40]); // Sum(72) + res[73] = fma52hi(res[73], a[32], a[40]); // Sum(72) + res[73] = fma52lo(res[73], a[33], a[40]); // Sum(73) + res[74] = fma52hi(res[74], a[33], a[40]); // Sum(73) + res[74] = fma52lo(res[74], a[34], a[40]); // Sum(74) + res[75] = fma52hi(res[75], a[34], a[40]); // Sum(74) + res[75] = fma52lo(res[75], a[35], a[40]); // Sum(75) + res[76] = fma52hi(res[76], a[35], a[40]); // Sum(75) + res[76] = fma52lo(res[76], a[36], a[40]); // Sum(76) + res[77] = fma52hi(res[77], a[36], a[40]); // Sum(76) + res[77] = fma52lo(res[77], a[37], a[40]); // Sum(77) + res[78] = fma52hi(res[78], a[37], a[40]); // Sum(77) + res[78] = fma52lo(res[78], a[38], a[40]); // Sum(78) + res[79] = fma52hi(res[79], a[38], a[40]); // Sum(78) + res[79] = fma52lo(res[79], a[39], a[40]); // Sum(79) + res[80] = fma52hi(res[80], a[39], a[40]); // Sum(79) + res[72] = fma52lo(res[72], a[31], a[41]); // Sum(72) + res[73] = fma52hi(res[73], a[31], a[41]); // Sum(72) + res[73] = fma52lo(res[73], a[32], a[41]); // Sum(73) + res[74] = fma52hi(res[74], a[32], a[41]); // Sum(73) + res[74] = fma52lo(res[74], a[33], a[41]); // Sum(74) + res[75] = fma52hi(res[75], a[33], a[41]); // Sum(74) + res[75] = fma52lo(res[75], a[34], a[41]); // Sum(75) + res[76] = fma52hi(res[76], a[34], a[41]); // Sum(75) + res[76] = fma52lo(res[76], a[35], a[41]); // Sum(76) + res[77] = fma52hi(res[77], a[35], a[41]); // Sum(76) + res[77] = fma52lo(res[77], a[36], a[41]); // Sum(77) + res[78] = fma52hi(res[78], a[36], a[41]); // Sum(77) + res[78] = fma52lo(res[78], a[37], a[41]); // Sum(78) + res[79] = fma52hi(res[79], a[37], a[41]); // Sum(78) + res[79] = fma52lo(res[79], a[38], a[41]); // Sum(79) + res[80] = fma52hi(res[80], a[38], a[41]); // Sum(79) + res[80] = fma52lo(res[80], a[39], a[41]); // Sum(80) + res[81] = fma52hi(res[81], a[39], a[41]); // Sum(80) + res[81] = fma52lo(res[81], a[40], a[41]); // Sum(81) + res[82] = fma52hi(res[82], a[40], a[41]); // Sum(81) + res[72] = fma52lo(res[72], a[30], a[42]); // Sum(72) + res[73] = fma52hi(res[73], a[30], a[42]); // Sum(72) + res[73] = fma52lo(res[73], a[31], a[42]); // Sum(73) + res[74] = fma52hi(res[74], a[31], a[42]); // Sum(73) + res[74] = fma52lo(res[74], a[32], a[42]); // Sum(74) + res[75] = fma52hi(res[75], a[32], a[42]); // Sum(74) + res[75] = fma52lo(res[75], a[33], a[42]); // Sum(75) + res[76] = fma52hi(res[76], a[33], a[42]); // Sum(75) + res[76] = fma52lo(res[76], a[34], a[42]); // Sum(76) + res[77] = fma52hi(res[77], a[34], a[42]); // Sum(76) + res[77] = fma52lo(res[77], a[35], a[42]); // Sum(77) + res[78] = fma52hi(res[78], a[35], a[42]); // Sum(77) + res[78] = fma52lo(res[78], a[36], a[42]); // Sum(78) + res[79] = fma52hi(res[79], a[36], a[42]); // Sum(78) + res[79] = fma52lo(res[79], a[37], a[42]); // Sum(79) + res[80] = fma52hi(res[80], a[37], a[42]); // Sum(79) + res[80] = fma52lo(res[80], a[38], a[42]); // Sum(80) + res[81] = fma52hi(res[81], a[38], a[42]); // Sum(80) + res[81] = fma52lo(res[81], a[39], a[42]); // Sum(81) + res[82] = fma52hi(res[82], a[39], a[42]); // Sum(81) + res[82] = fma52lo(res[82], a[40], a[42]); // Sum(82) + res[83] = fma52hi(res[83], a[40], a[42]); // Sum(82) + res[83] = fma52lo(res[83], a[41], a[42]); // Sum(83) + res[84] = fma52hi(res[84], a[41], a[42]); // Sum(83) + res[72] = fma52lo(res[72], a[29], a[43]); // Sum(72) + res[73] = fma52hi(res[73], a[29], a[43]); // Sum(72) + res[73] = fma52lo(res[73], a[30], a[43]); // Sum(73) + res[74] = fma52hi(res[74], a[30], a[43]); // Sum(73) + res[74] = fma52lo(res[74], a[31], a[43]); // Sum(74) + res[75] = fma52hi(res[75], a[31], a[43]); // Sum(74) + res[75] = fma52lo(res[75], a[32], a[43]); // Sum(75) + res[76] = fma52hi(res[76], a[32], a[43]); // Sum(75) + res[76] = fma52lo(res[76], a[33], a[43]); // Sum(76) + res[77] = fma52hi(res[77], a[33], a[43]); // Sum(76) + res[77] = fma52lo(res[77], a[34], a[43]); // Sum(77) + res[78] = fma52hi(res[78], a[34], a[43]); // Sum(77) + res[78] = fma52lo(res[78], a[35], a[43]); // Sum(78) + res[79] = fma52hi(res[79], a[35], a[43]); // Sum(78) + res[79] = fma52lo(res[79], a[36], a[43]); // Sum(79) + res[80] = fma52hi(res[80], a[36], a[43]); // Sum(79) + res[80] = fma52lo(res[80], a[37], a[43]); // Sum(80) + res[81] = fma52hi(res[81], a[37], a[43]); // Sum(80) + res[81] = fma52lo(res[81], a[38], a[43]); // Sum(81) + res[82] = fma52hi(res[82], a[38], a[43]); // Sum(81) + res[82] = fma52lo(res[82], a[39], a[43]); // Sum(82) + res[83] = fma52hi(res[83], a[39], a[43]); // Sum(82) + res[83] = fma52lo(res[83], a[40], a[43]); // Sum(83) + res[84] = fma52hi(res[84], a[40], a[43]); // Sum(83) + res[72] = fma52lo(res[72], a[28], a[44]); // Sum(72) + res[73] = fma52hi(res[73], a[28], a[44]); // Sum(72) + res[73] = fma52lo(res[73], a[29], a[44]); // Sum(73) + res[74] = fma52hi(res[74], a[29], a[44]); // Sum(73) + res[74] = fma52lo(res[74], a[30], a[44]); // Sum(74) + res[75] = fma52hi(res[75], a[30], a[44]); // Sum(74) + res[75] = fma52lo(res[75], a[31], a[44]); // Sum(75) + res[76] = fma52hi(res[76], a[31], a[44]); // Sum(75) + res[76] = fma52lo(res[76], a[32], a[44]); // Sum(76) + res[77] = fma52hi(res[77], a[32], a[44]); // Sum(76) + res[77] = fma52lo(res[77], a[33], a[44]); // Sum(77) + res[78] = fma52hi(res[78], a[33], a[44]); // Sum(77) + res[78] = fma52lo(res[78], a[34], a[44]); // Sum(78) + res[79] = fma52hi(res[79], a[34], a[44]); // Sum(78) + res[79] = fma52lo(res[79], a[35], a[44]); // Sum(79) + res[80] = fma52hi(res[80], a[35], a[44]); // Sum(79) + res[80] = fma52lo(res[80], a[36], a[44]); // Sum(80) + res[81] = fma52hi(res[81], a[36], a[44]); // Sum(80) + res[81] = fma52lo(res[81], a[37], a[44]); // Sum(81) + res[82] = fma52hi(res[82], a[37], a[44]); // Sum(81) + res[82] = fma52lo(res[82], a[38], a[44]); // Sum(82) + res[83] = fma52hi(res[83], a[38], a[44]); // Sum(82) + res[83] = fma52lo(res[83], a[39], a[44]); // Sum(83) + res[84] = fma52hi(res[84], a[39], a[44]); // Sum(83) + res[72] = fma52lo(res[72], a[27], a[45]); // Sum(72) + res[73] = fma52hi(res[73], a[27], a[45]); // Sum(72) + res[73] = fma52lo(res[73], a[28], a[45]); // Sum(73) + res[74] = fma52hi(res[74], a[28], a[45]); // Sum(73) + res[74] = fma52lo(res[74], a[29], a[45]); // Sum(74) + res[75] = fma52hi(res[75], a[29], a[45]); // Sum(74) + res[75] = fma52lo(res[75], a[30], a[45]); // Sum(75) + res[76] = fma52hi(res[76], a[30], a[45]); // Sum(75) + res[76] = fma52lo(res[76], a[31], a[45]); // Sum(76) + res[77] = fma52hi(res[77], a[31], a[45]); // Sum(76) + res[77] = fma52lo(res[77], a[32], a[45]); // Sum(77) + res[78] = fma52hi(res[78], a[32], a[45]); // Sum(77) + res[78] = fma52lo(res[78], a[33], a[45]); // Sum(78) + res[79] = fma52hi(res[79], a[33], a[45]); // Sum(78) + res[79] = fma52lo(res[79], a[34], a[45]); // Sum(79) + res[80] = fma52hi(res[80], a[34], a[45]); // Sum(79) + res[80] = fma52lo(res[80], a[35], a[45]); // Sum(80) + res[81] = fma52hi(res[81], a[35], a[45]); // Sum(80) + res[81] = fma52lo(res[81], a[36], a[45]); // Sum(81) + res[82] = fma52hi(res[82], a[36], a[45]); // Sum(81) + res[82] = fma52lo(res[82], a[37], a[45]); // Sum(82) + res[83] = fma52hi(res[83], a[37], a[45]); // Sum(82) + res[83] = fma52lo(res[83], a[38], a[45]); // Sum(83) + res[84] = fma52hi(res[84], a[38], a[45]); // Sum(83) + res[72] = fma52lo(res[72], a[26], a[46]); // Sum(72) + res[73] = fma52hi(res[73], a[26], a[46]); // Sum(72) + res[73] = fma52lo(res[73], a[27], a[46]); // Sum(73) + res[74] = fma52hi(res[74], a[27], a[46]); // Sum(73) + res[74] = fma52lo(res[74], a[28], a[46]); // Sum(74) + res[75] = fma52hi(res[75], a[28], a[46]); // Sum(74) + res[75] = fma52lo(res[75], a[29], a[46]); // Sum(75) + res[76] = fma52hi(res[76], a[29], a[46]); // Sum(75) + res[76] = fma52lo(res[76], a[30], a[46]); // Sum(76) + res[77] = fma52hi(res[77], a[30], a[46]); // Sum(76) + res[77] = fma52lo(res[77], a[31], a[46]); // Sum(77) + res[78] = fma52hi(res[78], a[31], a[46]); // Sum(77) + res[78] = fma52lo(res[78], a[32], a[46]); // Sum(78) + res[79] = fma52hi(res[79], a[32], a[46]); // Sum(78) + res[79] = fma52lo(res[79], a[33], a[46]); // Sum(79) + res[80] = fma52hi(res[80], a[33], a[46]); // Sum(79) + res[80] = fma52lo(res[80], a[34], a[46]); // Sum(80) + res[81] = fma52hi(res[81], a[34], a[46]); // Sum(80) + res[81] = fma52lo(res[81], a[35], a[46]); // Sum(81) + res[82] = fma52hi(res[82], a[35], a[46]); // Sum(81) + res[82] = fma52lo(res[82], a[36], a[46]); // Sum(82) + res[83] = fma52hi(res[83], a[36], a[46]); // Sum(82) + res[83] = fma52lo(res[83], a[37], a[46]); // Sum(83) + res[84] = fma52hi(res[84], a[37], a[46]); // Sum(83) + res[72] = fma52lo(res[72], a[25], a[47]); // Sum(72) + res[73] = fma52hi(res[73], a[25], a[47]); // Sum(72) + res[73] = fma52lo(res[73], a[26], a[47]); // Sum(73) + res[74] = fma52hi(res[74], a[26], a[47]); // Sum(73) + res[74] = fma52lo(res[74], a[27], a[47]); // Sum(74) + res[75] = fma52hi(res[75], a[27], a[47]); // Sum(74) + res[75] = fma52lo(res[75], a[28], a[47]); // Sum(75) + res[76] = fma52hi(res[76], a[28], a[47]); // Sum(75) + res[76] = fma52lo(res[76], a[29], a[47]); // Sum(76) + res[77] = fma52hi(res[77], a[29], a[47]); // Sum(76) + res[77] = fma52lo(res[77], a[30], a[47]); // Sum(77) + res[78] = fma52hi(res[78], a[30], a[47]); // Sum(77) + res[78] = fma52lo(res[78], a[31], a[47]); // Sum(78) + res[79] = fma52hi(res[79], a[31], a[47]); // Sum(78) + res[79] = fma52lo(res[79], a[32], a[47]); // Sum(79) + res[80] = fma52hi(res[80], a[32], a[47]); // Sum(79) + res[80] = fma52lo(res[80], a[33], a[47]); // Sum(80) + res[81] = fma52hi(res[81], a[33], a[47]); // Sum(80) + res[81] = fma52lo(res[81], a[34], a[47]); // Sum(81) + res[82] = fma52hi(res[82], a[34], a[47]); // Sum(81) + res[82] = fma52lo(res[82], a[35], a[47]); // Sum(82) + res[83] = fma52hi(res[83], a[35], a[47]); // Sum(82) + res[83] = fma52lo(res[83], a[36], a[47]); // Sum(83) + res[84] = fma52hi(res[84], a[36], a[47]); // Sum(83) + res[72] = fma52lo(res[72], a[24], a[48]); // Sum(72) + res[73] = fma52hi(res[73], a[24], a[48]); // Sum(72) + res[73] = fma52lo(res[73], a[25], a[48]); // Sum(73) + res[74] = fma52hi(res[74], a[25], a[48]); // Sum(73) + res[74] = fma52lo(res[74], a[26], a[48]); // Sum(74) + res[75] = fma52hi(res[75], a[26], a[48]); // Sum(74) + res[75] = fma52lo(res[75], a[27], a[48]); // Sum(75) + res[76] = fma52hi(res[76], a[27], a[48]); // Sum(75) + res[76] = fma52lo(res[76], a[28], a[48]); // Sum(76) + res[77] = fma52hi(res[77], a[28], a[48]); // Sum(76) + res[77] = fma52lo(res[77], a[29], a[48]); // Sum(77) + res[78] = fma52hi(res[78], a[29], a[48]); // Sum(77) + res[78] = fma52lo(res[78], a[30], a[48]); // Sum(78) + res[79] = fma52hi(res[79], a[30], a[48]); // Sum(78) + res[79] = fma52lo(res[79], a[31], a[48]); // Sum(79) + res[80] = fma52hi(res[80], a[31], a[48]); // Sum(79) + res[80] = fma52lo(res[80], a[32], a[48]); // Sum(80) + res[81] = fma52hi(res[81], a[32], a[48]); // Sum(80) + res[81] = fma52lo(res[81], a[33], a[48]); // Sum(81) + res[82] = fma52hi(res[82], a[33], a[48]); // Sum(81) + res[82] = fma52lo(res[82], a[34], a[48]); // Sum(82) + res[83] = fma52hi(res[83], a[34], a[48]); // Sum(82) + res[83] = fma52lo(res[83], a[35], a[48]); // Sum(83) + res[84] = fma52hi(res[84], a[35], a[48]); // Sum(83) + res[72] = fma52lo(res[72], a[23], a[49]); // Sum(72) + res[73] = fma52hi(res[73], a[23], a[49]); // Sum(72) + res[73] = fma52lo(res[73], a[24], a[49]); // Sum(73) + res[74] = fma52hi(res[74], a[24], a[49]); // Sum(73) + res[74] = fma52lo(res[74], a[25], a[49]); // Sum(74) + res[75] = fma52hi(res[75], a[25], a[49]); // Sum(74) + res[75] = fma52lo(res[75], a[26], a[49]); // Sum(75) + res[76] = fma52hi(res[76], a[26], a[49]); // Sum(75) + res[76] = fma52lo(res[76], a[27], a[49]); // Sum(76) + res[77] = fma52hi(res[77], a[27], a[49]); // Sum(76) + res[77] = fma52lo(res[77], a[28], a[49]); // Sum(77) + res[78] = fma52hi(res[78], a[28], a[49]); // Sum(77) + res[78] = fma52lo(res[78], a[29], a[49]); // Sum(78) + res[79] = fma52hi(res[79], a[29], a[49]); // Sum(78) + res[79] = fma52lo(res[79], a[30], a[49]); // Sum(79) + res[80] = fma52hi(res[80], a[30], a[49]); // Sum(79) + res[80] = fma52lo(res[80], a[31], a[49]); // Sum(80) + res[81] = fma52hi(res[81], a[31], a[49]); // Sum(80) + res[81] = fma52lo(res[81], a[32], a[49]); // Sum(81) + res[82] = fma52hi(res[82], a[32], a[49]); // Sum(81) + res[82] = fma52lo(res[82], a[33], a[49]); // Sum(82) + res[83] = fma52hi(res[83], a[33], a[49]); // Sum(82) + res[83] = fma52lo(res[83], a[34], a[49]); // Sum(83) + res[84] = fma52hi(res[84], a[34], a[49]); // Sum(83) + res[72] = fma52lo(res[72], a[22], a[50]); // Sum(72) + res[73] = fma52hi(res[73], a[22], a[50]); // Sum(72) + res[73] = fma52lo(res[73], a[23], a[50]); // Sum(73) + res[74] = fma52hi(res[74], a[23], a[50]); // Sum(73) + res[74] = fma52lo(res[74], a[24], a[50]); // Sum(74) + res[75] = fma52hi(res[75], a[24], a[50]); // Sum(74) + res[75] = fma52lo(res[75], a[25], a[50]); // Sum(75) + res[76] = fma52hi(res[76], a[25], a[50]); // Sum(75) + res[76] = fma52lo(res[76], a[26], a[50]); // Sum(76) + res[77] = fma52hi(res[77], a[26], a[50]); // Sum(76) + res[77] = fma52lo(res[77], a[27], a[50]); // Sum(77) + res[78] = fma52hi(res[78], a[27], a[50]); // Sum(77) + res[78] = fma52lo(res[78], a[28], a[50]); // Sum(78) + res[79] = fma52hi(res[79], a[28], a[50]); // Sum(78) + res[79] = fma52lo(res[79], a[29], a[50]); // Sum(79) + res[80] = fma52hi(res[80], a[29], a[50]); // Sum(79) + res[80] = fma52lo(res[80], a[30], a[50]); // Sum(80) + res[81] = fma52hi(res[81], a[30], a[50]); // Sum(80) + res[81] = fma52lo(res[81], a[31], a[50]); // Sum(81) + res[82] = fma52hi(res[82], a[31], a[50]); // Sum(81) + res[82] = fma52lo(res[82], a[32], a[50]); // Sum(82) + res[83] = fma52hi(res[83], a[32], a[50]); // Sum(82) + res[83] = fma52lo(res[83], a[33], a[50]); // Sum(83) + res[84] = fma52hi(res[84], a[33], a[50]); // Sum(83) + res[72] = fma52lo(res[72], a[21], a[51]); // Sum(72) + res[73] = fma52hi(res[73], a[21], a[51]); // Sum(72) + res[73] = fma52lo(res[73], a[22], a[51]); // Sum(73) + res[74] = fma52hi(res[74], a[22], a[51]); // Sum(73) + res[74] = fma52lo(res[74], a[23], a[51]); // Sum(74) + res[75] = fma52hi(res[75], a[23], a[51]); // Sum(74) + res[75] = fma52lo(res[75], a[24], a[51]); // Sum(75) + res[76] = fma52hi(res[76], a[24], a[51]); // Sum(75) + res[76] = fma52lo(res[76], a[25], a[51]); // Sum(76) + res[77] = fma52hi(res[77], a[25], a[51]); // Sum(76) + res[77] = fma52lo(res[77], a[26], a[51]); // Sum(77) + res[78] = fma52hi(res[78], a[26], a[51]); // Sum(77) + res[78] = fma52lo(res[78], a[27], a[51]); // Sum(78) + res[79] = fma52hi(res[79], a[27], a[51]); // Sum(78) + res[79] = fma52lo(res[79], a[28], a[51]); // Sum(79) + res[80] = fma52hi(res[80], a[28], a[51]); // Sum(79) + res[80] = fma52lo(res[80], a[29], a[51]); // Sum(80) + res[81] = fma52hi(res[81], a[29], a[51]); // Sum(80) + res[81] = fma52lo(res[81], a[30], a[51]); // Sum(81) + res[82] = fma52hi(res[82], a[30], a[51]); // Sum(81) + res[82] = fma52lo(res[82], a[31], a[51]); // Sum(82) + res[83] = fma52hi(res[83], a[31], a[51]); // Sum(82) + res[83] = fma52lo(res[83], a[32], a[51]); // Sum(83) + res[84] = fma52hi(res[84], a[32], a[51]); // Sum(83) + res[72] = fma52lo(res[72], a[20], a[52]); // Sum(72) + res[73] = fma52hi(res[73], a[20], a[52]); // Sum(72) + res[73] = fma52lo(res[73], a[21], a[52]); // Sum(73) + res[74] = fma52hi(res[74], a[21], a[52]); // Sum(73) + res[74] = fma52lo(res[74], a[22], a[52]); // Sum(74) + res[75] = fma52hi(res[75], a[22], a[52]); // Sum(74) + res[75] = fma52lo(res[75], a[23], a[52]); // Sum(75) + res[76] = fma52hi(res[76], a[23], a[52]); // Sum(75) + res[76] = fma52lo(res[76], a[24], a[52]); // Sum(76) + res[77] = fma52hi(res[77], a[24], a[52]); // Sum(76) + res[77] = fma52lo(res[77], a[25], a[52]); // Sum(77) + res[78] = fma52hi(res[78], a[25], a[52]); // Sum(77) + res[78] = fma52lo(res[78], a[26], a[52]); // Sum(78) + res[79] = fma52hi(res[79], a[26], a[52]); // Sum(78) + res[79] = fma52lo(res[79], a[27], a[52]); // Sum(79) + res[80] = fma52hi(res[80], a[27], a[52]); // Sum(79) + res[80] = fma52lo(res[80], a[28], a[52]); // Sum(80) + res[81] = fma52hi(res[81], a[28], a[52]); // Sum(80) + res[81] = fma52lo(res[81], a[29], a[52]); // Sum(81) + res[82] = fma52hi(res[82], a[29], a[52]); // Sum(81) + res[82] = fma52lo(res[82], a[30], a[52]); // Sum(82) + res[83] = fma52hi(res[83], a[30], a[52]); // Sum(82) + res[83] = fma52lo(res[83], a[31], a[52]); // Sum(83) + res[84] = fma52hi(res[84], a[31], a[52]); // Sum(83) + res[72] = fma52lo(res[72], a[19], a[53]); // Sum(72) + res[73] = fma52hi(res[73], a[19], a[53]); // Sum(72) + res[73] = fma52lo(res[73], a[20], a[53]); // Sum(73) + res[74] = fma52hi(res[74], a[20], a[53]); // Sum(73) + res[74] = fma52lo(res[74], a[21], a[53]); // Sum(74) + res[75] = fma52hi(res[75], a[21], a[53]); // Sum(74) + res[75] = fma52lo(res[75], a[22], a[53]); // Sum(75) + res[76] = fma52hi(res[76], a[22], a[53]); // Sum(75) + res[76] = fma52lo(res[76], a[23], a[53]); // Sum(76) + res[77] = fma52hi(res[77], a[23], a[53]); // Sum(76) + res[77] = fma52lo(res[77], a[24], a[53]); // Sum(77) + res[78] = fma52hi(res[78], a[24], a[53]); // Sum(77) + res[78] = fma52lo(res[78], a[25], a[53]); // Sum(78) + res[79] = fma52hi(res[79], a[25], a[53]); // Sum(78) + res[79] = fma52lo(res[79], a[26], a[53]); // Sum(79) + res[80] = fma52hi(res[80], a[26], a[53]); // Sum(79) + res[80] = fma52lo(res[80], a[27], a[53]); // Sum(80) + res[81] = fma52hi(res[81], a[27], a[53]); // Sum(80) + res[81] = fma52lo(res[81], a[28], a[53]); // Sum(81) + res[82] = fma52hi(res[82], a[28], a[53]); // Sum(81) + res[82] = fma52lo(res[82], a[29], a[53]); // Sum(82) + res[83] = fma52hi(res[83], a[29], a[53]); // Sum(82) + res[83] = fma52lo(res[83], a[30], a[53]); // Sum(83) + res[84] = fma52hi(res[84], a[30], a[53]); // Sum(83) + res[72] = fma52lo(res[72], a[18], a[54]); // Sum(72) + res[73] = fma52hi(res[73], a[18], a[54]); // Sum(72) + res[73] = fma52lo(res[73], a[19], a[54]); // Sum(73) + res[74] = fma52hi(res[74], a[19], a[54]); // Sum(73) + res[74] = fma52lo(res[74], a[20], a[54]); // Sum(74) + res[75] = fma52hi(res[75], a[20], a[54]); // Sum(74) + res[75] = fma52lo(res[75], a[21], a[54]); // Sum(75) + res[76] = fma52hi(res[76], a[21], a[54]); // Sum(75) + res[76] = fma52lo(res[76], a[22], a[54]); // Sum(76) + res[77] = fma52hi(res[77], a[22], a[54]); // Sum(76) + res[77] = fma52lo(res[77], a[23], a[54]); // Sum(77) + res[78] = fma52hi(res[78], a[23], a[54]); // Sum(77) + res[78] = fma52lo(res[78], a[24], a[54]); // Sum(78) + res[79] = fma52hi(res[79], a[24], a[54]); // Sum(78) + res[79] = fma52lo(res[79], a[25], a[54]); // Sum(79) + res[80] = fma52hi(res[80], a[25], a[54]); // Sum(79) + res[80] = fma52lo(res[80], a[26], a[54]); // Sum(80) + res[81] = fma52hi(res[81], a[26], a[54]); // Sum(80) + res[81] = fma52lo(res[81], a[27], a[54]); // Sum(81) + res[82] = fma52hi(res[82], a[27], a[54]); // Sum(81) + res[82] = fma52lo(res[82], a[28], a[54]); // Sum(82) + res[83] = fma52hi(res[83], a[28], a[54]); // Sum(82) + res[83] = fma52lo(res[83], a[29], a[54]); // Sum(83) + res[84] = fma52hi(res[84], a[29], a[54]); // Sum(83) + res[72] = fma52lo(res[72], a[17], a[55]); // Sum(72) + res[73] = fma52hi(res[73], a[17], a[55]); // Sum(72) + res[73] = fma52lo(res[73], a[18], a[55]); // Sum(73) + res[74] = fma52hi(res[74], a[18], a[55]); // Sum(73) + res[74] = fma52lo(res[74], a[19], a[55]); // Sum(74) + res[75] = fma52hi(res[75], a[19], a[55]); // Sum(74) + res[75] = fma52lo(res[75], a[20], a[55]); // Sum(75) + res[76] = fma52hi(res[76], a[20], a[55]); // Sum(75) + res[76] = fma52lo(res[76], a[21], a[55]); // Sum(76) + res[77] = fma52hi(res[77], a[21], a[55]); // Sum(76) + res[77] = fma52lo(res[77], a[22], a[55]); // Sum(77) + res[78] = fma52hi(res[78], a[22], a[55]); // Sum(77) + res[78] = fma52lo(res[78], a[23], a[55]); // Sum(78) + res[79] = fma52hi(res[79], a[23], a[55]); // Sum(78) + res[79] = fma52lo(res[79], a[24], a[55]); // Sum(79) + res[80] = fma52hi(res[80], a[24], a[55]); // Sum(79) + res[80] = fma52lo(res[80], a[25], a[55]); // Sum(80) + res[81] = fma52hi(res[81], a[25], a[55]); // Sum(80) + res[81] = fma52lo(res[81], a[26], a[55]); // Sum(81) + res[82] = fma52hi(res[82], a[26], a[55]); // Sum(81) + res[82] = fma52lo(res[82], a[27], a[55]); // Sum(82) + res[83] = fma52hi(res[83], a[27], a[55]); // Sum(82) + res[83] = fma52lo(res[83], a[28], a[55]); // Sum(83) + res[84] = fma52hi(res[84], a[28], a[55]); // Sum(83) + res[72] = fma52lo(res[72], a[16], a[56]); // Sum(72) + res[73] = fma52hi(res[73], a[16], a[56]); // Sum(72) + res[73] = fma52lo(res[73], a[17], a[56]); // Sum(73) + res[74] = fma52hi(res[74], a[17], a[56]); // Sum(73) + res[74] = fma52lo(res[74], a[18], a[56]); // Sum(74) + res[75] = fma52hi(res[75], a[18], a[56]); // Sum(74) + res[75] = fma52lo(res[75], a[19], a[56]); // Sum(75) + res[76] = fma52hi(res[76], a[19], a[56]); // Sum(75) + res[76] = fma52lo(res[76], a[20], a[56]); // Sum(76) + res[77] = fma52hi(res[77], a[20], a[56]); // Sum(76) + res[77] = fma52lo(res[77], a[21], a[56]); // Sum(77) + res[78] = fma52hi(res[78], a[21], a[56]); // Sum(77) + res[78] = fma52lo(res[78], a[22], a[56]); // Sum(78) + res[79] = fma52hi(res[79], a[22], a[56]); // Sum(78) + res[79] = fma52lo(res[79], a[23], a[56]); // Sum(79) + res[80] = fma52hi(res[80], a[23], a[56]); // Sum(79) + res[80] = fma52lo(res[80], a[24], a[56]); // Sum(80) + res[81] = fma52hi(res[81], a[24], a[56]); // Sum(80) + res[81] = fma52lo(res[81], a[25], a[56]); // Sum(81) + res[82] = fma52hi(res[82], a[25], a[56]); // Sum(81) + res[82] = fma52lo(res[82], a[26], a[56]); // Sum(82) + res[83] = fma52hi(res[83], a[26], a[56]); // Sum(82) + res[83] = fma52lo(res[83], a[27], a[56]); // Sum(83) + res[84] = fma52hi(res[84], a[27], a[56]); // Sum(83) + res[72] = fma52lo(res[72], a[15], a[57]); // Sum(72) + res[73] = fma52hi(res[73], a[15], a[57]); // Sum(72) + res[73] = fma52lo(res[73], a[16], a[57]); // Sum(73) + res[74] = fma52hi(res[74], a[16], a[57]); // Sum(73) + res[74] = fma52lo(res[74], a[17], a[57]); // Sum(74) + res[75] = fma52hi(res[75], a[17], a[57]); // Sum(74) + res[75] = fma52lo(res[75], a[18], a[57]); // Sum(75) + res[76] = fma52hi(res[76], a[18], a[57]); // Sum(75) + res[76] = fma52lo(res[76], a[19], a[57]); // Sum(76) + res[77] = fma52hi(res[77], a[19], a[57]); // Sum(76) + res[77] = fma52lo(res[77], a[20], a[57]); // Sum(77) + res[78] = fma52hi(res[78], a[20], a[57]); // Sum(77) + res[78] = fma52lo(res[78], a[21], a[57]); // Sum(78) + res[79] = fma52hi(res[79], a[21], a[57]); // Sum(78) + res[79] = fma52lo(res[79], a[22], a[57]); // Sum(79) + res[80] = fma52hi(res[80], a[22], a[57]); // Sum(79) + res[80] = fma52lo(res[80], a[23], a[57]); // Sum(80) + res[81] = fma52hi(res[81], a[23], a[57]); // Sum(80) + res[81] = fma52lo(res[81], a[24], a[57]); // Sum(81) + res[82] = fma52hi(res[82], a[24], a[57]); // Sum(81) + res[82] = fma52lo(res[82], a[25], a[57]); // Sum(82) + res[83] = fma52hi(res[83], a[25], a[57]); // Sum(82) + res[83] = fma52lo(res[83], a[26], a[57]); // Sum(83) + res[84] = fma52hi(res[84], a[26], a[57]); // Sum(83) + res[72] = fma52lo(res[72], a[14], a[58]); // Sum(72) + res[73] = fma52hi(res[73], a[14], a[58]); // Sum(72) + res[73] = fma52lo(res[73], a[15], a[58]); // Sum(73) + res[74] = fma52hi(res[74], a[15], a[58]); // Sum(73) + res[74] = fma52lo(res[74], a[16], a[58]); // Sum(74) + res[75] = fma52hi(res[75], a[16], a[58]); // Sum(74) + res[75] = fma52lo(res[75], a[17], a[58]); // Sum(75) + res[76] = fma52hi(res[76], a[17], a[58]); // Sum(75) + res[76] = fma52lo(res[76], a[18], a[58]); // Sum(76) + res[77] = fma52hi(res[77], a[18], a[58]); // Sum(76) + res[77] = fma52lo(res[77], a[19], a[58]); // Sum(77) + res[78] = fma52hi(res[78], a[19], a[58]); // Sum(77) + res[78] = fma52lo(res[78], a[20], a[58]); // Sum(78) + res[79] = fma52hi(res[79], a[20], a[58]); // Sum(78) + res[79] = fma52lo(res[79], a[21], a[58]); // Sum(79) + res[80] = fma52hi(res[80], a[21], a[58]); // Sum(79) + res[80] = fma52lo(res[80], a[22], a[58]); // Sum(80) + res[81] = fma52hi(res[81], a[22], a[58]); // Sum(80) + res[81] = fma52lo(res[81], a[23], a[58]); // Sum(81) + res[82] = fma52hi(res[82], a[23], a[58]); // Sum(81) + res[82] = fma52lo(res[82], a[24], a[58]); // Sum(82) + res[83] = fma52hi(res[83], a[24], a[58]); // Sum(82) + res[83] = fma52lo(res[83], a[25], a[58]); // Sum(83) + res[84] = fma52hi(res[84], a[25], a[58]); // Sum(83) + res[72] = fma52lo(res[72], a[13], a[59]); // Sum(72) + res[73] = fma52hi(res[73], a[13], a[59]); // Sum(72) + res[73] = fma52lo(res[73], a[14], a[59]); // Sum(73) + res[74] = fma52hi(res[74], a[14], a[59]); // Sum(73) + res[74] = fma52lo(res[74], a[15], a[59]); // Sum(74) + res[75] = fma52hi(res[75], a[15], a[59]); // Sum(74) + res[75] = fma52lo(res[75], a[16], a[59]); // Sum(75) + res[76] = fma52hi(res[76], a[16], a[59]); // Sum(75) + res[76] = fma52lo(res[76], a[17], a[59]); // Sum(76) + res[77] = fma52hi(res[77], a[17], a[59]); // Sum(76) + res[77] = fma52lo(res[77], a[18], a[59]); // Sum(77) + res[78] = fma52hi(res[78], a[18], a[59]); // Sum(77) + res[78] = fma52lo(res[78], a[19], a[59]); // Sum(78) + res[79] = fma52hi(res[79], a[19], a[59]); // Sum(78) + res[79] = fma52lo(res[79], a[20], a[59]); // Sum(79) + res[80] = fma52hi(res[80], a[20], a[59]); // Sum(79) + res[80] = fma52lo(res[80], a[21], a[59]); // Sum(80) + res[81] = fma52hi(res[81], a[21], a[59]); // Sum(80) + res[81] = fma52lo(res[81], a[22], a[59]); // Sum(81) + res[82] = fma52hi(res[82], a[22], a[59]); // Sum(81) + res[82] = fma52lo(res[82], a[23], a[59]); // Sum(82) + res[83] = fma52hi(res[83], a[23], a[59]); // Sum(82) + res[83] = fma52lo(res[83], a[24], a[59]); // Sum(83) + res[84] = fma52hi(res[84], a[24], a[59]); // Sum(83) + res[72] = add64(res[72], res[72]); // Double(72) + res[73] = add64(res[73], res[73]); // Double(73) + res[74] = add64(res[74], res[74]); // Double(74) + res[75] = add64(res[75], res[75]); // Double(75) + res[76] = add64(res[76], res[76]); // Double(76) + res[77] = add64(res[77], res[77]); // Double(77) + res[78] = add64(res[78], res[78]); // Double(78) + res[79] = add64(res[79], res[79]); // Double(79) + res[80] = add64(res[80], res[80]); // Double(80) + res[81] = add64(res[81], res[81]); // Double(81) + res[82] = add64(res[82], res[82]); // Double(82) + res[83] = add64(res[83], res[83]); // Double(83) + res[72] = fma52lo(res[72], a[36], a[36]); // Add sqr(72) + res[73] = fma52hi(res[73], a[36], a[36]); // Add sqr(72) + res[74] = fma52lo(res[74], a[37], a[37]); // Add sqr(74) + res[75] = fma52hi(res[75], a[37], a[37]); // Add sqr(74) + res[76] = fma52lo(res[76], a[38], a[38]); // Add sqr(76) + res[77] = fma52hi(res[77], a[38], a[38]); // Add sqr(76) + res[78] = fma52lo(res[78], a[39], a[39]); // Add sqr(78) + res[79] = fma52hi(res[79], a[39], a[39]); // Add sqr(78) + res[80] = fma52lo(res[80], a[40], a[40]); // Add sqr(80) + res[81] = fma52hi(res[81], a[40], a[40]); // Add sqr(80) + res[82] = fma52lo(res[82], a[41], a[41]); // Add sqr(82) + res[83] = fma52hi(res[83], a[41], a[41]); // Add sqr(82) + res[84] = fma52lo(res[84], a[41], a[43]); // Sum(84) + res[85] = fma52hi(res[85], a[41], a[43]); // Sum(84) + res[85] = fma52lo(res[85], a[42], a[43]); // Sum(85) + res[86] = fma52hi(res[86], a[42], a[43]); // Sum(85) + res[84] = fma52lo(res[84], a[40], a[44]); // Sum(84) + res[85] = fma52hi(res[85], a[40], a[44]); // Sum(84) + res[85] = fma52lo(res[85], a[41], a[44]); // Sum(85) + res[86] = fma52hi(res[86], a[41], a[44]); // Sum(85) + res[86] = fma52lo(res[86], a[42], a[44]); // Sum(86) + res[87] = fma52hi(res[87], a[42], a[44]); // Sum(86) + res[87] = fma52lo(res[87], a[43], a[44]); // Sum(87) + res[88] = fma52hi(res[88], a[43], a[44]); // Sum(87) + res[84] = fma52lo(res[84], a[39], a[45]); // Sum(84) + res[85] = fma52hi(res[85], a[39], a[45]); // Sum(84) + res[85] = fma52lo(res[85], a[40], a[45]); // Sum(85) + res[86] = fma52hi(res[86], a[40], a[45]); // Sum(85) + res[86] = fma52lo(res[86], a[41], a[45]); // Sum(86) + res[87] = fma52hi(res[87], a[41], a[45]); // Sum(86) + res[87] = fma52lo(res[87], a[42], a[45]); // Sum(87) + res[88] = fma52hi(res[88], a[42], a[45]); // Sum(87) + res[88] = fma52lo(res[88], a[43], a[45]); // Sum(88) + res[89] = fma52hi(res[89], a[43], a[45]); // Sum(88) + res[89] = fma52lo(res[89], a[44], a[45]); // Sum(89) + res[90] = fma52hi(res[90], a[44], a[45]); // Sum(89) + res[84] = fma52lo(res[84], a[38], a[46]); // Sum(84) + res[85] = fma52hi(res[85], a[38], a[46]); // Sum(84) + res[85] = fma52lo(res[85], a[39], a[46]); // Sum(85) + res[86] = fma52hi(res[86], a[39], a[46]); // Sum(85) + res[86] = fma52lo(res[86], a[40], a[46]); // Sum(86) + res[87] = fma52hi(res[87], a[40], a[46]); // Sum(86) + res[87] = fma52lo(res[87], a[41], a[46]); // Sum(87) + res[88] = fma52hi(res[88], a[41], a[46]); // Sum(87) + res[88] = fma52lo(res[88], a[42], a[46]); // Sum(88) + res[89] = fma52hi(res[89], a[42], a[46]); // Sum(88) + res[89] = fma52lo(res[89], a[43], a[46]); // Sum(89) + res[90] = fma52hi(res[90], a[43], a[46]); // Sum(89) + res[90] = fma52lo(res[90], a[44], a[46]); // Sum(90) + res[91] = fma52hi(res[91], a[44], a[46]); // Sum(90) + res[91] = fma52lo(res[91], a[45], a[46]); // Sum(91) + res[92] = fma52hi(res[92], a[45], a[46]); // Sum(91) + res[84] = fma52lo(res[84], a[37], a[47]); // Sum(84) + res[85] = fma52hi(res[85], a[37], a[47]); // Sum(84) + res[85] = fma52lo(res[85], a[38], a[47]); // Sum(85) + res[86] = fma52hi(res[86], a[38], a[47]); // Sum(85) + res[86] = fma52lo(res[86], a[39], a[47]); // Sum(86) + res[87] = fma52hi(res[87], a[39], a[47]); // Sum(86) + res[87] = fma52lo(res[87], a[40], a[47]); // Sum(87) + res[88] = fma52hi(res[88], a[40], a[47]); // Sum(87) + res[88] = fma52lo(res[88], a[41], a[47]); // Sum(88) + res[89] = fma52hi(res[89], a[41], a[47]); // Sum(88) + res[89] = fma52lo(res[89], a[42], a[47]); // Sum(89) + res[90] = fma52hi(res[90], a[42], a[47]); // Sum(89) + res[90] = fma52lo(res[90], a[43], a[47]); // Sum(90) + res[91] = fma52hi(res[91], a[43], a[47]); // Sum(90) + res[91] = fma52lo(res[91], a[44], a[47]); // Sum(91) + res[92] = fma52hi(res[92], a[44], a[47]); // Sum(91) + res[92] = fma52lo(res[92], a[45], a[47]); // Sum(92) + res[93] = fma52hi(res[93], a[45], a[47]); // Sum(92) + res[93] = fma52lo(res[93], a[46], a[47]); // Sum(93) + res[94] = fma52hi(res[94], a[46], a[47]); // Sum(93) + res[84] = fma52lo(res[84], a[36], a[48]); // Sum(84) + res[85] = fma52hi(res[85], a[36], a[48]); // Sum(84) + res[85] = fma52lo(res[85], a[37], a[48]); // Sum(85) + res[86] = fma52hi(res[86], a[37], a[48]); // Sum(85) + res[86] = fma52lo(res[86], a[38], a[48]); // Sum(86) + res[87] = fma52hi(res[87], a[38], a[48]); // Sum(86) + res[87] = fma52lo(res[87], a[39], a[48]); // Sum(87) + res[88] = fma52hi(res[88], a[39], a[48]); // Sum(87) + res[88] = fma52lo(res[88], a[40], a[48]); // Sum(88) + res[89] = fma52hi(res[89], a[40], a[48]); // Sum(88) + res[89] = fma52lo(res[89], a[41], a[48]); // Sum(89) + res[90] = fma52hi(res[90], a[41], a[48]); // Sum(89) + res[90] = fma52lo(res[90], a[42], a[48]); // Sum(90) + res[91] = fma52hi(res[91], a[42], a[48]); // Sum(90) + res[91] = fma52lo(res[91], a[43], a[48]); // Sum(91) + res[92] = fma52hi(res[92], a[43], a[48]); // Sum(91) + res[92] = fma52lo(res[92], a[44], a[48]); // Sum(92) + res[93] = fma52hi(res[93], a[44], a[48]); // Sum(92) + res[93] = fma52lo(res[93], a[45], a[48]); // Sum(93) + res[94] = fma52hi(res[94], a[45], a[48]); // Sum(93) + res[94] = fma52lo(res[94], a[46], a[48]); // Sum(94) + res[95] = fma52hi(res[95], a[46], a[48]); // Sum(94) + res[95] = fma52lo(res[95], a[47], a[48]); // Sum(95) + res[96] = fma52hi(res[96], a[47], a[48]); // Sum(95) + res[84] = fma52lo(res[84], a[35], a[49]); // Sum(84) + res[85] = fma52hi(res[85], a[35], a[49]); // Sum(84) + res[85] = fma52lo(res[85], a[36], a[49]); // Sum(85) + res[86] = fma52hi(res[86], a[36], a[49]); // Sum(85) + res[86] = fma52lo(res[86], a[37], a[49]); // Sum(86) + res[87] = fma52hi(res[87], a[37], a[49]); // Sum(86) + res[87] = fma52lo(res[87], a[38], a[49]); // Sum(87) + res[88] = fma52hi(res[88], a[38], a[49]); // Sum(87) + res[88] = fma52lo(res[88], a[39], a[49]); // Sum(88) + res[89] = fma52hi(res[89], a[39], a[49]); // Sum(88) + res[89] = fma52lo(res[89], a[40], a[49]); // Sum(89) + res[90] = fma52hi(res[90], a[40], a[49]); // Sum(89) + res[90] = fma52lo(res[90], a[41], a[49]); // Sum(90) + res[91] = fma52hi(res[91], a[41], a[49]); // Sum(90) + res[91] = fma52lo(res[91], a[42], a[49]); // Sum(91) + res[92] = fma52hi(res[92], a[42], a[49]); // Sum(91) + res[92] = fma52lo(res[92], a[43], a[49]); // Sum(92) + res[93] = fma52hi(res[93], a[43], a[49]); // Sum(92) + res[93] = fma52lo(res[93], a[44], a[49]); // Sum(93) + res[94] = fma52hi(res[94], a[44], a[49]); // Sum(93) + res[94] = fma52lo(res[94], a[45], a[49]); // Sum(94) + res[95] = fma52hi(res[95], a[45], a[49]); // Sum(94) + res[95] = fma52lo(res[95], a[46], a[49]); // Sum(95) + res[96] = fma52hi(res[96], a[46], a[49]); // Sum(95) + res[84] = fma52lo(res[84], a[34], a[50]); // Sum(84) + res[85] = fma52hi(res[85], a[34], a[50]); // Sum(84) + res[85] = fma52lo(res[85], a[35], a[50]); // Sum(85) + res[86] = fma52hi(res[86], a[35], a[50]); // Sum(85) + res[86] = fma52lo(res[86], a[36], a[50]); // Sum(86) + res[87] = fma52hi(res[87], a[36], a[50]); // Sum(86) + res[87] = fma52lo(res[87], a[37], a[50]); // Sum(87) + res[88] = fma52hi(res[88], a[37], a[50]); // Sum(87) + res[88] = fma52lo(res[88], a[38], a[50]); // Sum(88) + res[89] = fma52hi(res[89], a[38], a[50]); // Sum(88) + res[89] = fma52lo(res[89], a[39], a[50]); // Sum(89) + res[90] = fma52hi(res[90], a[39], a[50]); // Sum(89) + res[90] = fma52lo(res[90], a[40], a[50]); // Sum(90) + res[91] = fma52hi(res[91], a[40], a[50]); // Sum(90) + res[91] = fma52lo(res[91], a[41], a[50]); // Sum(91) + res[92] = fma52hi(res[92], a[41], a[50]); // Sum(91) + res[92] = fma52lo(res[92], a[42], a[50]); // Sum(92) + res[93] = fma52hi(res[93], a[42], a[50]); // Sum(92) + res[93] = fma52lo(res[93], a[43], a[50]); // Sum(93) + res[94] = fma52hi(res[94], a[43], a[50]); // Sum(93) + res[94] = fma52lo(res[94], a[44], a[50]); // Sum(94) + res[95] = fma52hi(res[95], a[44], a[50]); // Sum(94) + res[95] = fma52lo(res[95], a[45], a[50]); // Sum(95) + res[96] = fma52hi(res[96], a[45], a[50]); // Sum(95) + res[84] = fma52lo(res[84], a[33], a[51]); // Sum(84) + res[85] = fma52hi(res[85], a[33], a[51]); // Sum(84) + res[85] = fma52lo(res[85], a[34], a[51]); // Sum(85) + res[86] = fma52hi(res[86], a[34], a[51]); // Sum(85) + res[86] = fma52lo(res[86], a[35], a[51]); // Sum(86) + res[87] = fma52hi(res[87], a[35], a[51]); // Sum(86) + res[87] = fma52lo(res[87], a[36], a[51]); // Sum(87) + res[88] = fma52hi(res[88], a[36], a[51]); // Sum(87) + res[88] = fma52lo(res[88], a[37], a[51]); // Sum(88) + res[89] = fma52hi(res[89], a[37], a[51]); // Sum(88) + res[89] = fma52lo(res[89], a[38], a[51]); // Sum(89) + res[90] = fma52hi(res[90], a[38], a[51]); // Sum(89) + res[90] = fma52lo(res[90], a[39], a[51]); // Sum(90) + res[91] = fma52hi(res[91], a[39], a[51]); // Sum(90) + res[91] = fma52lo(res[91], a[40], a[51]); // Sum(91) + res[92] = fma52hi(res[92], a[40], a[51]); // Sum(91) + res[92] = fma52lo(res[92], a[41], a[51]); // Sum(92) + res[93] = fma52hi(res[93], a[41], a[51]); // Sum(92) + res[93] = fma52lo(res[93], a[42], a[51]); // Sum(93) + res[94] = fma52hi(res[94], a[42], a[51]); // Sum(93) + res[94] = fma52lo(res[94], a[43], a[51]); // Sum(94) + res[95] = fma52hi(res[95], a[43], a[51]); // Sum(94) + res[95] = fma52lo(res[95], a[44], a[51]); // Sum(95) + res[96] = fma52hi(res[96], a[44], a[51]); // Sum(95) + res[84] = fma52lo(res[84], a[32], a[52]); // Sum(84) + res[85] = fma52hi(res[85], a[32], a[52]); // Sum(84) + res[85] = fma52lo(res[85], a[33], a[52]); // Sum(85) + res[86] = fma52hi(res[86], a[33], a[52]); // Sum(85) + res[86] = fma52lo(res[86], a[34], a[52]); // Sum(86) + res[87] = fma52hi(res[87], a[34], a[52]); // Sum(86) + res[87] = fma52lo(res[87], a[35], a[52]); // Sum(87) + res[88] = fma52hi(res[88], a[35], a[52]); // Sum(87) + res[88] = fma52lo(res[88], a[36], a[52]); // Sum(88) + res[89] = fma52hi(res[89], a[36], a[52]); // Sum(88) + res[89] = fma52lo(res[89], a[37], a[52]); // Sum(89) + res[90] = fma52hi(res[90], a[37], a[52]); // Sum(89) + res[90] = fma52lo(res[90], a[38], a[52]); // Sum(90) + res[91] = fma52hi(res[91], a[38], a[52]); // Sum(90) + res[91] = fma52lo(res[91], a[39], a[52]); // Sum(91) + res[92] = fma52hi(res[92], a[39], a[52]); // Sum(91) + res[92] = fma52lo(res[92], a[40], a[52]); // Sum(92) + res[93] = fma52hi(res[93], a[40], a[52]); // Sum(92) + res[93] = fma52lo(res[93], a[41], a[52]); // Sum(93) + res[94] = fma52hi(res[94], a[41], a[52]); // Sum(93) + res[94] = fma52lo(res[94], a[42], a[52]); // Sum(94) + res[95] = fma52hi(res[95], a[42], a[52]); // Sum(94) + res[95] = fma52lo(res[95], a[43], a[52]); // Sum(95) + res[96] = fma52hi(res[96], a[43], a[52]); // Sum(95) + res[84] = fma52lo(res[84], a[31], a[53]); // Sum(84) + res[85] = fma52hi(res[85], a[31], a[53]); // Sum(84) + res[85] = fma52lo(res[85], a[32], a[53]); // Sum(85) + res[86] = fma52hi(res[86], a[32], a[53]); // Sum(85) + res[86] = fma52lo(res[86], a[33], a[53]); // Sum(86) + res[87] = fma52hi(res[87], a[33], a[53]); // Sum(86) + res[87] = fma52lo(res[87], a[34], a[53]); // Sum(87) + res[88] = fma52hi(res[88], a[34], a[53]); // Sum(87) + res[88] = fma52lo(res[88], a[35], a[53]); // Sum(88) + res[89] = fma52hi(res[89], a[35], a[53]); // Sum(88) + res[89] = fma52lo(res[89], a[36], a[53]); // Sum(89) + res[90] = fma52hi(res[90], a[36], a[53]); // Sum(89) + res[90] = fma52lo(res[90], a[37], a[53]); // Sum(90) + res[91] = fma52hi(res[91], a[37], a[53]); // Sum(90) + res[91] = fma52lo(res[91], a[38], a[53]); // Sum(91) + res[92] = fma52hi(res[92], a[38], a[53]); // Sum(91) + res[92] = fma52lo(res[92], a[39], a[53]); // Sum(92) + res[93] = fma52hi(res[93], a[39], a[53]); // Sum(92) + res[93] = fma52lo(res[93], a[40], a[53]); // Sum(93) + res[94] = fma52hi(res[94], a[40], a[53]); // Sum(93) + res[94] = fma52lo(res[94], a[41], a[53]); // Sum(94) + res[95] = fma52hi(res[95], a[41], a[53]); // Sum(94) + res[95] = fma52lo(res[95], a[42], a[53]); // Sum(95) + res[96] = fma52hi(res[96], a[42], a[53]); // Sum(95) + res[84] = fma52lo(res[84], a[30], a[54]); // Sum(84) + res[85] = fma52hi(res[85], a[30], a[54]); // Sum(84) + res[85] = fma52lo(res[85], a[31], a[54]); // Sum(85) + res[86] = fma52hi(res[86], a[31], a[54]); // Sum(85) + res[86] = fma52lo(res[86], a[32], a[54]); // Sum(86) + res[87] = fma52hi(res[87], a[32], a[54]); // Sum(86) + res[87] = fma52lo(res[87], a[33], a[54]); // Sum(87) + res[88] = fma52hi(res[88], a[33], a[54]); // Sum(87) + res[88] = fma52lo(res[88], a[34], a[54]); // Sum(88) + res[89] = fma52hi(res[89], a[34], a[54]); // Sum(88) + res[89] = fma52lo(res[89], a[35], a[54]); // Sum(89) + res[90] = fma52hi(res[90], a[35], a[54]); // Sum(89) + res[90] = fma52lo(res[90], a[36], a[54]); // Sum(90) + res[91] = fma52hi(res[91], a[36], a[54]); // Sum(90) + res[91] = fma52lo(res[91], a[37], a[54]); // Sum(91) + res[92] = fma52hi(res[92], a[37], a[54]); // Sum(91) + res[92] = fma52lo(res[92], a[38], a[54]); // Sum(92) + res[93] = fma52hi(res[93], a[38], a[54]); // Sum(92) + res[93] = fma52lo(res[93], a[39], a[54]); // Sum(93) + res[94] = fma52hi(res[94], a[39], a[54]); // Sum(93) + res[94] = fma52lo(res[94], a[40], a[54]); // Sum(94) + res[95] = fma52hi(res[95], a[40], a[54]); // Sum(94) + res[95] = fma52lo(res[95], a[41], a[54]); // Sum(95) + res[96] = fma52hi(res[96], a[41], a[54]); // Sum(95) + res[84] = fma52lo(res[84], a[29], a[55]); // Sum(84) + res[85] = fma52hi(res[85], a[29], a[55]); // Sum(84) + res[85] = fma52lo(res[85], a[30], a[55]); // Sum(85) + res[86] = fma52hi(res[86], a[30], a[55]); // Sum(85) + res[86] = fma52lo(res[86], a[31], a[55]); // Sum(86) + res[87] = fma52hi(res[87], a[31], a[55]); // Sum(86) + res[87] = fma52lo(res[87], a[32], a[55]); // Sum(87) + res[88] = fma52hi(res[88], a[32], a[55]); // Sum(87) + res[88] = fma52lo(res[88], a[33], a[55]); // Sum(88) + res[89] = fma52hi(res[89], a[33], a[55]); // Sum(88) + res[89] = fma52lo(res[89], a[34], a[55]); // Sum(89) + res[90] = fma52hi(res[90], a[34], a[55]); // Sum(89) + res[90] = fma52lo(res[90], a[35], a[55]); // Sum(90) + res[91] = fma52hi(res[91], a[35], a[55]); // Sum(90) + res[91] = fma52lo(res[91], a[36], a[55]); // Sum(91) + res[92] = fma52hi(res[92], a[36], a[55]); // Sum(91) + res[92] = fma52lo(res[92], a[37], a[55]); // Sum(92) + res[93] = fma52hi(res[93], a[37], a[55]); // Sum(92) + res[93] = fma52lo(res[93], a[38], a[55]); // Sum(93) + res[94] = fma52hi(res[94], a[38], a[55]); // Sum(93) + res[94] = fma52lo(res[94], a[39], a[55]); // Sum(94) + res[95] = fma52hi(res[95], a[39], a[55]); // Sum(94) + res[95] = fma52lo(res[95], a[40], a[55]); // Sum(95) + res[96] = fma52hi(res[96], a[40], a[55]); // Sum(95) + res[84] = fma52lo(res[84], a[28], a[56]); // Sum(84) + res[85] = fma52hi(res[85], a[28], a[56]); // Sum(84) + res[85] = fma52lo(res[85], a[29], a[56]); // Sum(85) + res[86] = fma52hi(res[86], a[29], a[56]); // Sum(85) + res[86] = fma52lo(res[86], a[30], a[56]); // Sum(86) + res[87] = fma52hi(res[87], a[30], a[56]); // Sum(86) + res[87] = fma52lo(res[87], a[31], a[56]); // Sum(87) + res[88] = fma52hi(res[88], a[31], a[56]); // Sum(87) + res[88] = fma52lo(res[88], a[32], a[56]); // Sum(88) + res[89] = fma52hi(res[89], a[32], a[56]); // Sum(88) + res[89] = fma52lo(res[89], a[33], a[56]); // Sum(89) + res[90] = fma52hi(res[90], a[33], a[56]); // Sum(89) + res[90] = fma52lo(res[90], a[34], a[56]); // Sum(90) + res[91] = fma52hi(res[91], a[34], a[56]); // Sum(90) + res[91] = fma52lo(res[91], a[35], a[56]); // Sum(91) + res[92] = fma52hi(res[92], a[35], a[56]); // Sum(91) + res[92] = fma52lo(res[92], a[36], a[56]); // Sum(92) + res[93] = fma52hi(res[93], a[36], a[56]); // Sum(92) + res[93] = fma52lo(res[93], a[37], a[56]); // Sum(93) + res[94] = fma52hi(res[94], a[37], a[56]); // Sum(93) + res[94] = fma52lo(res[94], a[38], a[56]); // Sum(94) + res[95] = fma52hi(res[95], a[38], a[56]); // Sum(94) + res[95] = fma52lo(res[95], a[39], a[56]); // Sum(95) + res[96] = fma52hi(res[96], a[39], a[56]); // Sum(95) + res[84] = fma52lo(res[84], a[27], a[57]); // Sum(84) + res[85] = fma52hi(res[85], a[27], a[57]); // Sum(84) + res[85] = fma52lo(res[85], a[28], a[57]); // Sum(85) + res[86] = fma52hi(res[86], a[28], a[57]); // Sum(85) + res[86] = fma52lo(res[86], a[29], a[57]); // Sum(86) + res[87] = fma52hi(res[87], a[29], a[57]); // Sum(86) + res[87] = fma52lo(res[87], a[30], a[57]); // Sum(87) + res[88] = fma52hi(res[88], a[30], a[57]); // Sum(87) + res[88] = fma52lo(res[88], a[31], a[57]); // Sum(88) + res[89] = fma52hi(res[89], a[31], a[57]); // Sum(88) + res[89] = fma52lo(res[89], a[32], a[57]); // Sum(89) + res[90] = fma52hi(res[90], a[32], a[57]); // Sum(89) + res[90] = fma52lo(res[90], a[33], a[57]); // Sum(90) + res[91] = fma52hi(res[91], a[33], a[57]); // Sum(90) + res[91] = fma52lo(res[91], a[34], a[57]); // Sum(91) + res[92] = fma52hi(res[92], a[34], a[57]); // Sum(91) + res[92] = fma52lo(res[92], a[35], a[57]); // Sum(92) + res[93] = fma52hi(res[93], a[35], a[57]); // Sum(92) + res[93] = fma52lo(res[93], a[36], a[57]); // Sum(93) + res[94] = fma52hi(res[94], a[36], a[57]); // Sum(93) + res[94] = fma52lo(res[94], a[37], a[57]); // Sum(94) + res[95] = fma52hi(res[95], a[37], a[57]); // Sum(94) + res[95] = fma52lo(res[95], a[38], a[57]); // Sum(95) + res[96] = fma52hi(res[96], a[38], a[57]); // Sum(95) + res[84] = fma52lo(res[84], a[26], a[58]); // Sum(84) + res[85] = fma52hi(res[85], a[26], a[58]); // Sum(84) + res[85] = fma52lo(res[85], a[27], a[58]); // Sum(85) + res[86] = fma52hi(res[86], a[27], a[58]); // Sum(85) + res[86] = fma52lo(res[86], a[28], a[58]); // Sum(86) + res[87] = fma52hi(res[87], a[28], a[58]); // Sum(86) + res[87] = fma52lo(res[87], a[29], a[58]); // Sum(87) + res[88] = fma52hi(res[88], a[29], a[58]); // Sum(87) + res[88] = fma52lo(res[88], a[30], a[58]); // Sum(88) + res[89] = fma52hi(res[89], a[30], a[58]); // Sum(88) + res[89] = fma52lo(res[89], a[31], a[58]); // Sum(89) + res[90] = fma52hi(res[90], a[31], a[58]); // Sum(89) + res[90] = fma52lo(res[90], a[32], a[58]); // Sum(90) + res[91] = fma52hi(res[91], a[32], a[58]); // Sum(90) + res[91] = fma52lo(res[91], a[33], a[58]); // Sum(91) + res[92] = fma52hi(res[92], a[33], a[58]); // Sum(91) + res[92] = fma52lo(res[92], a[34], a[58]); // Sum(92) + res[93] = fma52hi(res[93], a[34], a[58]); // Sum(92) + res[93] = fma52lo(res[93], a[35], a[58]); // Sum(93) + res[94] = fma52hi(res[94], a[35], a[58]); // Sum(93) + res[94] = fma52lo(res[94], a[36], a[58]); // Sum(94) + res[95] = fma52hi(res[95], a[36], a[58]); // Sum(94) + res[95] = fma52lo(res[95], a[37], a[58]); // Sum(95) + res[96] = fma52hi(res[96], a[37], a[58]); // Sum(95) + res[84] = fma52lo(res[84], a[25], a[59]); // Sum(84) + res[85] = fma52hi(res[85], a[25], a[59]); // Sum(84) + res[85] = fma52lo(res[85], a[26], a[59]); // Sum(85) + res[86] = fma52hi(res[86], a[26], a[59]); // Sum(85) + res[86] = fma52lo(res[86], a[27], a[59]); // Sum(86) + res[87] = fma52hi(res[87], a[27], a[59]); // Sum(86) + res[87] = fma52lo(res[87], a[28], a[59]); // Sum(87) + res[88] = fma52hi(res[88], a[28], a[59]); // Sum(87) + res[88] = fma52lo(res[88], a[29], a[59]); // Sum(88) + res[89] = fma52hi(res[89], a[29], a[59]); // Sum(88) + res[89] = fma52lo(res[89], a[30], a[59]); // Sum(89) + res[90] = fma52hi(res[90], a[30], a[59]); // Sum(89) + res[90] = fma52lo(res[90], a[31], a[59]); // Sum(90) + res[91] = fma52hi(res[91], a[31], a[59]); // Sum(90) + res[91] = fma52lo(res[91], a[32], a[59]); // Sum(91) + res[92] = fma52hi(res[92], a[32], a[59]); // Sum(91) + res[92] = fma52lo(res[92], a[33], a[59]); // Sum(92) + res[93] = fma52hi(res[93], a[33], a[59]); // Sum(92) + res[93] = fma52lo(res[93], a[34], a[59]); // Sum(93) + res[94] = fma52hi(res[94], a[34], a[59]); // Sum(93) + res[94] = fma52lo(res[94], a[35], a[59]); // Sum(94) + res[95] = fma52hi(res[95], a[35], a[59]); // Sum(94) + res[95] = fma52lo(res[95], a[36], a[59]); // Sum(95) + res[96] = fma52hi(res[96], a[36], a[59]); // Sum(95) + res[84] = add64(res[84], res[84]); // Double(84) + res[85] = add64(res[85], res[85]); // Double(85) + res[86] = add64(res[86], res[86]); // Double(86) + res[87] = add64(res[87], res[87]); // Double(87) + res[88] = add64(res[88], res[88]); // Double(88) + res[89] = add64(res[89], res[89]); // Double(89) + res[90] = add64(res[90], res[90]); // Double(90) + res[91] = add64(res[91], res[91]); // Double(91) + res[92] = add64(res[92], res[92]); // Double(92) + res[93] = add64(res[93], res[93]); // Double(93) + res[94] = add64(res[94], res[94]); // Double(94) + res[95] = add64(res[95], res[95]); // Double(95) + res[84] = fma52lo(res[84], a[42], a[42]); // Add sqr(84) + res[85] = fma52hi(res[85], a[42], a[42]); // Add sqr(84) + res[86] = fma52lo(res[86], a[43], a[43]); // Add sqr(86) + res[87] = fma52hi(res[87], a[43], a[43]); // Add sqr(86) + res[88] = fma52lo(res[88], a[44], a[44]); // Add sqr(88) + res[89] = fma52hi(res[89], a[44], a[44]); // Add sqr(88) + res[90] = fma52lo(res[90], a[45], a[45]); // Add sqr(90) + res[91] = fma52hi(res[91], a[45], a[45]); // Add sqr(90) + res[92] = fma52lo(res[92], a[46], a[46]); // Add sqr(92) + res[93] = fma52hi(res[93], a[46], a[46]); // Add sqr(92) + res[94] = fma52lo(res[94], a[47], a[47]); // Add sqr(94) + res[95] = fma52hi(res[95], a[47], a[47]); // Add sqr(94) + res[96] = fma52lo(res[96], a[47], a[49]); // Sum(96) + res[97] = fma52hi(res[97], a[47], a[49]); // Sum(96) + res[97] = fma52lo(res[97], a[48], a[49]); // Sum(97) + res[98] = fma52hi(res[98], a[48], a[49]); // Sum(97) + res[96] = fma52lo(res[96], a[46], a[50]); // Sum(96) + res[97] = fma52hi(res[97], a[46], a[50]); // Sum(96) + res[97] = fma52lo(res[97], a[47], a[50]); // Sum(97) + res[98] = fma52hi(res[98], a[47], a[50]); // Sum(97) + res[98] = fma52lo(res[98], a[48], a[50]); // Sum(98) + res[99] = fma52hi(res[99], a[48], a[50]); // Sum(98) + res[99] = fma52lo(res[99], a[49], a[50]); // Sum(99) + res[100] = fma52hi(res[100], a[49], a[50]); // Sum(99) + res[96] = fma52lo(res[96], a[45], a[51]); // Sum(96) + res[97] = fma52hi(res[97], a[45], a[51]); // Sum(96) + res[97] = fma52lo(res[97], a[46], a[51]); // Sum(97) + res[98] = fma52hi(res[98], a[46], a[51]); // Sum(97) + res[98] = fma52lo(res[98], a[47], a[51]); // Sum(98) + res[99] = fma52hi(res[99], a[47], a[51]); // Sum(98) + res[99] = fma52lo(res[99], a[48], a[51]); // Sum(99) + res[100] = fma52hi(res[100], a[48], a[51]); // Sum(99) + res[100] = fma52lo(res[100], a[49], a[51]); // Sum(100) + res[101] = fma52hi(res[101], a[49], a[51]); // Sum(100) + res[101] = fma52lo(res[101], a[50], a[51]); // Sum(101) + res[102] = fma52hi(res[102], a[50], a[51]); // Sum(101) + res[96] = fma52lo(res[96], a[44], a[52]); // Sum(96) + res[97] = fma52hi(res[97], a[44], a[52]); // Sum(96) + res[97] = fma52lo(res[97], a[45], a[52]); // Sum(97) + res[98] = fma52hi(res[98], a[45], a[52]); // Sum(97) + res[98] = fma52lo(res[98], a[46], a[52]); // Sum(98) + res[99] = fma52hi(res[99], a[46], a[52]); // Sum(98) + res[99] = fma52lo(res[99], a[47], a[52]); // Sum(99) + res[100] = fma52hi(res[100], a[47], a[52]); // Sum(99) + res[100] = fma52lo(res[100], a[48], a[52]); // Sum(100) + res[101] = fma52hi(res[101], a[48], a[52]); // Sum(100) + res[101] = fma52lo(res[101], a[49], a[52]); // Sum(101) + res[102] = fma52hi(res[102], a[49], a[52]); // Sum(101) + res[102] = fma52lo(res[102], a[50], a[52]); // Sum(102) + res[103] = fma52hi(res[103], a[50], a[52]); // Sum(102) + res[103] = fma52lo(res[103], a[51], a[52]); // Sum(103) + res[104] = fma52hi(res[104], a[51], a[52]); // Sum(103) + res[96] = fma52lo(res[96], a[43], a[53]); // Sum(96) + res[97] = fma52hi(res[97], a[43], a[53]); // Sum(96) + res[97] = fma52lo(res[97], a[44], a[53]); // Sum(97) + res[98] = fma52hi(res[98], a[44], a[53]); // Sum(97) + res[98] = fma52lo(res[98], a[45], a[53]); // Sum(98) + res[99] = fma52hi(res[99], a[45], a[53]); // Sum(98) + res[99] = fma52lo(res[99], a[46], a[53]); // Sum(99) + res[100] = fma52hi(res[100], a[46], a[53]); // Sum(99) + res[100] = fma52lo(res[100], a[47], a[53]); // Sum(100) + res[101] = fma52hi(res[101], a[47], a[53]); // Sum(100) + res[101] = fma52lo(res[101], a[48], a[53]); // Sum(101) + res[102] = fma52hi(res[102], a[48], a[53]); // Sum(101) + res[102] = fma52lo(res[102], a[49], a[53]); // Sum(102) + res[103] = fma52hi(res[103], a[49], a[53]); // Sum(102) + res[103] = fma52lo(res[103], a[50], a[53]); // Sum(103) + res[104] = fma52hi(res[104], a[50], a[53]); // Sum(103) + res[104] = fma52lo(res[104], a[51], a[53]); // Sum(104) + res[105] = fma52hi(res[105], a[51], a[53]); // Sum(104) + res[105] = fma52lo(res[105], a[52], a[53]); // Sum(105) + res[106] = fma52hi(res[106], a[52], a[53]); // Sum(105) + res[96] = fma52lo(res[96], a[42], a[54]); // Sum(96) + res[97] = fma52hi(res[97], a[42], a[54]); // Sum(96) + res[97] = fma52lo(res[97], a[43], a[54]); // Sum(97) + res[98] = fma52hi(res[98], a[43], a[54]); // Sum(97) + res[98] = fma52lo(res[98], a[44], a[54]); // Sum(98) + res[99] = fma52hi(res[99], a[44], a[54]); // Sum(98) + res[99] = fma52lo(res[99], a[45], a[54]); // Sum(99) + res[100] = fma52hi(res[100], a[45], a[54]); // Sum(99) + res[100] = fma52lo(res[100], a[46], a[54]); // Sum(100) + res[101] = fma52hi(res[101], a[46], a[54]); // Sum(100) + res[101] = fma52lo(res[101], a[47], a[54]); // Sum(101) + res[102] = fma52hi(res[102], a[47], a[54]); // Sum(101) + res[102] = fma52lo(res[102], a[48], a[54]); // Sum(102) + res[103] = fma52hi(res[103], a[48], a[54]); // Sum(102) + res[103] = fma52lo(res[103], a[49], a[54]); // Sum(103) + res[104] = fma52hi(res[104], a[49], a[54]); // Sum(103) + res[104] = fma52lo(res[104], a[50], a[54]); // Sum(104) + res[105] = fma52hi(res[105], a[50], a[54]); // Sum(104) + res[105] = fma52lo(res[105], a[51], a[54]); // Sum(105) + res[106] = fma52hi(res[106], a[51], a[54]); // Sum(105) + res[106] = fma52lo(res[106], a[52], a[54]); // Sum(106) + res[107] = fma52hi(res[107], a[52], a[54]); // Sum(106) + res[107] = fma52lo(res[107], a[53], a[54]); // Sum(107) + res[108] = fma52hi(res[108], a[53], a[54]); // Sum(107) + res[96] = fma52lo(res[96], a[41], a[55]); // Sum(96) + res[97] = fma52hi(res[97], a[41], a[55]); // Sum(96) + res[97] = fma52lo(res[97], a[42], a[55]); // Sum(97) + res[98] = fma52hi(res[98], a[42], a[55]); // Sum(97) + res[98] = fma52lo(res[98], a[43], a[55]); // Sum(98) + res[99] = fma52hi(res[99], a[43], a[55]); // Sum(98) + res[99] = fma52lo(res[99], a[44], a[55]); // Sum(99) + res[100] = fma52hi(res[100], a[44], a[55]); // Sum(99) + res[100] = fma52lo(res[100], a[45], a[55]); // Sum(100) + res[101] = fma52hi(res[101], a[45], a[55]); // Sum(100) + res[101] = fma52lo(res[101], a[46], a[55]); // Sum(101) + res[102] = fma52hi(res[102], a[46], a[55]); // Sum(101) + res[102] = fma52lo(res[102], a[47], a[55]); // Sum(102) + res[103] = fma52hi(res[103], a[47], a[55]); // Sum(102) + res[103] = fma52lo(res[103], a[48], a[55]); // Sum(103) + res[104] = fma52hi(res[104], a[48], a[55]); // Sum(103) + res[104] = fma52lo(res[104], a[49], a[55]); // Sum(104) + res[105] = fma52hi(res[105], a[49], a[55]); // Sum(104) + res[105] = fma52lo(res[105], a[50], a[55]); // Sum(105) + res[106] = fma52hi(res[106], a[50], a[55]); // Sum(105) + res[106] = fma52lo(res[106], a[51], a[55]); // Sum(106) + res[107] = fma52hi(res[107], a[51], a[55]); // Sum(106) + res[107] = fma52lo(res[107], a[52], a[55]); // Sum(107) + res[108] = fma52hi(res[108], a[52], a[55]); // Sum(107) + res[96] = fma52lo(res[96], a[40], a[56]); // Sum(96) + res[97] = fma52hi(res[97], a[40], a[56]); // Sum(96) + res[97] = fma52lo(res[97], a[41], a[56]); // Sum(97) + res[98] = fma52hi(res[98], a[41], a[56]); // Sum(97) + res[98] = fma52lo(res[98], a[42], a[56]); // Sum(98) + res[99] = fma52hi(res[99], a[42], a[56]); // Sum(98) + res[99] = fma52lo(res[99], a[43], a[56]); // Sum(99) + res[100] = fma52hi(res[100], a[43], a[56]); // Sum(99) + res[100] = fma52lo(res[100], a[44], a[56]); // Sum(100) + res[101] = fma52hi(res[101], a[44], a[56]); // Sum(100) + res[101] = fma52lo(res[101], a[45], a[56]); // Sum(101) + res[102] = fma52hi(res[102], a[45], a[56]); // Sum(101) + res[102] = fma52lo(res[102], a[46], a[56]); // Sum(102) + res[103] = fma52hi(res[103], a[46], a[56]); // Sum(102) + res[103] = fma52lo(res[103], a[47], a[56]); // Sum(103) + res[104] = fma52hi(res[104], a[47], a[56]); // Sum(103) + res[104] = fma52lo(res[104], a[48], a[56]); // Sum(104) + res[105] = fma52hi(res[105], a[48], a[56]); // Sum(104) + res[105] = fma52lo(res[105], a[49], a[56]); // Sum(105) + res[106] = fma52hi(res[106], a[49], a[56]); // Sum(105) + res[106] = fma52lo(res[106], a[50], a[56]); // Sum(106) + res[107] = fma52hi(res[107], a[50], a[56]); // Sum(106) + res[107] = fma52lo(res[107], a[51], a[56]); // Sum(107) + res[108] = fma52hi(res[108], a[51], a[56]); // Sum(107) + res[96] = fma52lo(res[96], a[39], a[57]); // Sum(96) + res[97] = fma52hi(res[97], a[39], a[57]); // Sum(96) + res[97] = fma52lo(res[97], a[40], a[57]); // Sum(97) + res[98] = fma52hi(res[98], a[40], a[57]); // Sum(97) + res[98] = fma52lo(res[98], a[41], a[57]); // Sum(98) + res[99] = fma52hi(res[99], a[41], a[57]); // Sum(98) + res[99] = fma52lo(res[99], a[42], a[57]); // Sum(99) + res[100] = fma52hi(res[100], a[42], a[57]); // Sum(99) + res[100] = fma52lo(res[100], a[43], a[57]); // Sum(100) + res[101] = fma52hi(res[101], a[43], a[57]); // Sum(100) + res[101] = fma52lo(res[101], a[44], a[57]); // Sum(101) + res[102] = fma52hi(res[102], a[44], a[57]); // Sum(101) + res[102] = fma52lo(res[102], a[45], a[57]); // Sum(102) + res[103] = fma52hi(res[103], a[45], a[57]); // Sum(102) + res[103] = fma52lo(res[103], a[46], a[57]); // Sum(103) + res[104] = fma52hi(res[104], a[46], a[57]); // Sum(103) + res[104] = fma52lo(res[104], a[47], a[57]); // Sum(104) + res[105] = fma52hi(res[105], a[47], a[57]); // Sum(104) + res[105] = fma52lo(res[105], a[48], a[57]); // Sum(105) + res[106] = fma52hi(res[106], a[48], a[57]); // Sum(105) + res[106] = fma52lo(res[106], a[49], a[57]); // Sum(106) + res[107] = fma52hi(res[107], a[49], a[57]); // Sum(106) + res[107] = fma52lo(res[107], a[50], a[57]); // Sum(107) + res[108] = fma52hi(res[108], a[50], a[57]); // Sum(107) + res[96] = fma52lo(res[96], a[38], a[58]); // Sum(96) + res[97] = fma52hi(res[97], a[38], a[58]); // Sum(96) + res[97] = fma52lo(res[97], a[39], a[58]); // Sum(97) + res[98] = fma52hi(res[98], a[39], a[58]); // Sum(97) + res[98] = fma52lo(res[98], a[40], a[58]); // Sum(98) + res[99] = fma52hi(res[99], a[40], a[58]); // Sum(98) + res[99] = fma52lo(res[99], a[41], a[58]); // Sum(99) + res[100] = fma52hi(res[100], a[41], a[58]); // Sum(99) + res[100] = fma52lo(res[100], a[42], a[58]); // Sum(100) + res[101] = fma52hi(res[101], a[42], a[58]); // Sum(100) + res[101] = fma52lo(res[101], a[43], a[58]); // Sum(101) + res[102] = fma52hi(res[102], a[43], a[58]); // Sum(101) + res[102] = fma52lo(res[102], a[44], a[58]); // Sum(102) + res[103] = fma52hi(res[103], a[44], a[58]); // Sum(102) + res[103] = fma52lo(res[103], a[45], a[58]); // Sum(103) + res[104] = fma52hi(res[104], a[45], a[58]); // Sum(103) + res[104] = fma52lo(res[104], a[46], a[58]); // Sum(104) + res[105] = fma52hi(res[105], a[46], a[58]); // Sum(104) + res[105] = fma52lo(res[105], a[47], a[58]); // Sum(105) + res[106] = fma52hi(res[106], a[47], a[58]); // Sum(105) + res[106] = fma52lo(res[106], a[48], a[58]); // Sum(106) + res[107] = fma52hi(res[107], a[48], a[58]); // Sum(106) + res[107] = fma52lo(res[107], a[49], a[58]); // Sum(107) + res[108] = fma52hi(res[108], a[49], a[58]); // Sum(107) + res[96] = fma52lo(res[96], a[37], a[59]); // Sum(96) + res[97] = fma52hi(res[97], a[37], a[59]); // Sum(96) + res[97] = fma52lo(res[97], a[38], a[59]); // Sum(97) + res[98] = fma52hi(res[98], a[38], a[59]); // Sum(97) + res[98] = fma52lo(res[98], a[39], a[59]); // Sum(98) + res[99] = fma52hi(res[99], a[39], a[59]); // Sum(98) + res[99] = fma52lo(res[99], a[40], a[59]); // Sum(99) + res[100] = fma52hi(res[100], a[40], a[59]); // Sum(99) + res[100] = fma52lo(res[100], a[41], a[59]); // Sum(100) + res[101] = fma52hi(res[101], a[41], a[59]); // Sum(100) + res[101] = fma52lo(res[101], a[42], a[59]); // Sum(101) + res[102] = fma52hi(res[102], a[42], a[59]); // Sum(101) + res[102] = fma52lo(res[102], a[43], a[59]); // Sum(102) + res[103] = fma52hi(res[103], a[43], a[59]); // Sum(102) + res[103] = fma52lo(res[103], a[44], a[59]); // Sum(103) + res[104] = fma52hi(res[104], a[44], a[59]); // Sum(103) + res[104] = fma52lo(res[104], a[45], a[59]); // Sum(104) + res[105] = fma52hi(res[105], a[45], a[59]); // Sum(104) + res[105] = fma52lo(res[105], a[46], a[59]); // Sum(105) + res[106] = fma52hi(res[106], a[46], a[59]); // Sum(105) + res[106] = fma52lo(res[106], a[47], a[59]); // Sum(106) + res[107] = fma52hi(res[107], a[47], a[59]); // Sum(106) + res[107] = fma52lo(res[107], a[48], a[59]); // Sum(107) + res[108] = fma52hi(res[108], a[48], a[59]); // Sum(107) + res[96] = add64(res[96], res[96]); // Double(96) + res[97] = add64(res[97], res[97]); // Double(97) + res[98] = add64(res[98], res[98]); // Double(98) + res[99] = add64(res[99], res[99]); // Double(99) + res[100] = add64(res[100], res[100]); // Double(100) + res[101] = add64(res[101], res[101]); // Double(101) + res[102] = add64(res[102], res[102]); // Double(102) + res[103] = add64(res[103], res[103]); // Double(103) + res[104] = add64(res[104], res[104]); // Double(104) + res[105] = add64(res[105], res[105]); // Double(105) + res[106] = add64(res[106], res[106]); // Double(106) + res[107] = add64(res[107], res[107]); // Double(107) + res[96] = fma52lo(res[96], a[48], a[48]); // Add sqr(96) + res[97] = fma52hi(res[97], a[48], a[48]); // Add sqr(96) + res[98] = fma52lo(res[98], a[49], a[49]); // Add sqr(98) + res[99] = fma52hi(res[99], a[49], a[49]); // Add sqr(98) + res[100] = fma52lo(res[100], a[50], a[50]); // Add sqr(100) + res[101] = fma52hi(res[101], a[50], a[50]); // Add sqr(100) + res[102] = fma52lo(res[102], a[51], a[51]); // Add sqr(102) + res[103] = fma52hi(res[103], a[51], a[51]); // Add sqr(102) + res[104] = fma52lo(res[104], a[52], a[52]); // Add sqr(104) + res[105] = fma52hi(res[105], a[52], a[52]); // Add sqr(104) + res[106] = fma52lo(res[106], a[53], a[53]); // Add sqr(106) + res[107] = fma52hi(res[107], a[53], a[53]); // Add sqr(106) + res[108] = fma52lo(res[108], a[53], a[55]); // Sum(108) + res[109] = fma52hi(res[109], a[53], a[55]); // Sum(108) + res[109] = fma52lo(res[109], a[54], a[55]); // Sum(109) + res[110] = fma52hi(res[110], a[54], a[55]); // Sum(109) + res[108] = fma52lo(res[108], a[52], a[56]); // Sum(108) + res[109] = fma52hi(res[109], a[52], a[56]); // Sum(108) + res[109] = fma52lo(res[109], a[53], a[56]); // Sum(109) + res[110] = fma52hi(res[110], a[53], a[56]); // Sum(109) + res[110] = fma52lo(res[110], a[54], a[56]); // Sum(110) + res[111] = fma52hi(res[111], a[54], a[56]); // Sum(110) + res[111] = fma52lo(res[111], a[55], a[56]); // Sum(111) + res[112] = fma52hi(res[112], a[55], a[56]); // Sum(111) + res[108] = fma52lo(res[108], a[51], a[57]); // Sum(108) + res[109] = fma52hi(res[109], a[51], a[57]); // Sum(108) + res[109] = fma52lo(res[109], a[52], a[57]); // Sum(109) + res[110] = fma52hi(res[110], a[52], a[57]); // Sum(109) + res[110] = fma52lo(res[110], a[53], a[57]); // Sum(110) + res[111] = fma52hi(res[111], a[53], a[57]); // Sum(110) + res[111] = fma52lo(res[111], a[54], a[57]); // Sum(111) + res[112] = fma52hi(res[112], a[54], a[57]); // Sum(111) + res[112] = fma52lo(res[112], a[55], a[57]); // Sum(112) + res[113] = fma52hi(res[113], a[55], a[57]); // Sum(112) + res[113] = fma52lo(res[113], a[56], a[57]); // Sum(113) + res[114] = fma52hi(res[114], a[56], a[57]); // Sum(113) + res[108] = fma52lo(res[108], a[50], a[58]); // Sum(108) + res[109] = fma52hi(res[109], a[50], a[58]); // Sum(108) + res[109] = fma52lo(res[109], a[51], a[58]); // Sum(109) + res[110] = fma52hi(res[110], a[51], a[58]); // Sum(109) + res[110] = fma52lo(res[110], a[52], a[58]); // Sum(110) + res[111] = fma52hi(res[111], a[52], a[58]); // Sum(110) + res[111] = fma52lo(res[111], a[53], a[58]); // Sum(111) + res[112] = fma52hi(res[112], a[53], a[58]); // Sum(111) + res[112] = fma52lo(res[112], a[54], a[58]); // Sum(112) + res[113] = fma52hi(res[113], a[54], a[58]); // Sum(112) + res[113] = fma52lo(res[113], a[55], a[58]); // Sum(113) + res[114] = fma52hi(res[114], a[55], a[58]); // Sum(113) + res[114] = fma52lo(res[114], a[56], a[58]); // Sum(114) + res[115] = fma52hi(res[115], a[56], a[58]); // Sum(114) + res[115] = fma52lo(res[115], a[57], a[58]); // Sum(115) + res[116] = fma52hi(res[116], a[57], a[58]); // Sum(115) + res[108] = fma52lo(res[108], a[49], a[59]); // Sum(108) + res[109] = fma52hi(res[109], a[49], a[59]); // Sum(108) + res[109] = fma52lo(res[109], a[50], a[59]); // Sum(109) + res[110] = fma52hi(res[110], a[50], a[59]); // Sum(109) + res[110] = fma52lo(res[110], a[51], a[59]); // Sum(110) + res[111] = fma52hi(res[111], a[51], a[59]); // Sum(110) + res[111] = fma52lo(res[111], a[52], a[59]); // Sum(111) + res[112] = fma52hi(res[112], a[52], a[59]); // Sum(111) + res[112] = fma52lo(res[112], a[53], a[59]); // Sum(112) + res[113] = fma52hi(res[113], a[53], a[59]); // Sum(112) + res[113] = fma52lo(res[113], a[54], a[59]); // Sum(113) + res[114] = fma52hi(res[114], a[54], a[59]); // Sum(113) + res[114] = fma52lo(res[114], a[55], a[59]); // Sum(114) + res[115] = fma52hi(res[115], a[55], a[59]); // Sum(114) + res[115] = fma52lo(res[115], a[56], a[59]); // Sum(115) + res[116] = fma52hi(res[116], a[56], a[59]); // Sum(115) + res[116] = fma52lo(res[116], a[57], a[59]); // Sum(116) + res[117] = fma52hi(res[117], a[57], a[59]); // Sum(116) + res[117] = fma52lo(res[117], a[58], a[59]); // Sum(117) + res[118] = fma52hi(res[118], a[58], a[59]); // Sum(117) + res[108] = add64(res[108], res[108]); // Double(108) + res[109] = add64(res[109], res[109]); // Double(109) + res[110] = add64(res[110], res[110]); // Double(110) + res[111] = add64(res[111], res[111]); // Double(111) + res[112] = add64(res[112], res[112]); // Double(112) + res[113] = add64(res[113], res[113]); // Double(113) + res[114] = add64(res[114], res[114]); // Double(114) + res[115] = add64(res[115], res[115]); // Double(115) + res[116] = add64(res[116], res[116]); // Double(116) + res[117] = add64(res[117], res[117]); // Double(117) + res[118] = add64(res[118], res[118]); // Double(118) + res[108] = fma52lo(res[108], a[54], a[54]); // Add sqr(108) + res[109] = fma52hi(res[109], a[54], a[54]); // Add sqr(108) + res[110] = fma52lo(res[110], a[55], a[55]); // Add sqr(110) + res[111] = fma52hi(res[111], a[55], a[55]); // Add sqr(110) + res[112] = fma52lo(res[112], a[56], a[56]); // Add sqr(112) + res[113] = fma52hi(res[113], a[56], a[56]); // Add sqr(112) + res[114] = fma52lo(res[114], a[57], a[57]); // Add sqr(114) + res[115] = fma52hi(res[115], a[57], a[57]); // Add sqr(114) + res[116] = fma52lo(res[116], a[58], a[58]); // Add sqr(116) + res[117] = fma52hi(res[117], a[58], a[58]); // Add sqr(116) + res[118] = fma52lo(res[118], a[59], a[59]); // Add sqr(118) + res[119] = fma52hi(res[119], a[59], a[59]); // Add sqr(118) + + // Montgomery Reduction + int it; + for (it = 0; it < 60; it += 10) { // Reduction step + int jt = 0; + if ((it + 0) > 0) + res[it + 0] = add64(res[it + 0], srli64(res[it + -1], DIGIT_SIZE)); + u[it + 0] = mul52lo(res[it + 0], k); + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + 1] = add64(res[it + 1], srli64(res[it + 0], DIGIT_SIZE)); + u[it + 1] = mul52lo(res[it + 1], k); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + 2] = add64(res[it + 2], srli64(res[it + 1], DIGIT_SIZE)); + u[it + 2] = mul52lo(res[it + 2], k); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + 3] = add64(res[it + 3], srli64(res[it + 2], DIGIT_SIZE)); + u[it + 3] = mul52lo(res[it + 3], k); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + 4] = add64(res[it + 4], srli64(res[it + 3], DIGIT_SIZE)); + u[it + 4] = mul52lo(res[it + 4], k); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + 5] = add64(res[it + 5], srli64(res[it + 4], DIGIT_SIZE)); + u[it + 5] = mul52lo(res[it + 5], k); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + 6] = add64(res[it + 6], srli64(res[it + 5], DIGIT_SIZE)); + u[it + 6] = mul52lo(res[it + 6], k); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + 7] = add64(res[it + 7], srli64(res[it + 6], DIGIT_SIZE)); + u[it + 7] = mul52lo(res[it + 7], k); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + 8] = add64(res[it + 8], srli64(res[it + 7], DIGIT_SIZE)); + u[it + 8] = mul52lo(res[it + 8], k); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + 9] = add64(res[it + 9], srli64(res[it + 8], DIGIT_SIZE)); + u[it + 9] = mul52lo(res[it + 9], k); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + + for (jt = 10; jt < 60; jt += 10) { // Poly tile + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + } + } + + // Normalization + res[60] = add64(res[60], srli64(res[59], DIGIT_SIZE)); + r[0] = and64_const(res[60], DIGIT_MASK); + res[61] = add64(res[61], srli64(res[60], DIGIT_SIZE)); + r[1] = and64_const(res[61], DIGIT_MASK); + res[62] = add64(res[62], srli64(res[61], DIGIT_SIZE)); + r[2] = and64_const(res[62], DIGIT_MASK); + res[63] = add64(res[63], srli64(res[62], DIGIT_SIZE)); + r[3] = and64_const(res[63], DIGIT_MASK); + res[64] = add64(res[64], srli64(res[63], DIGIT_SIZE)); + r[4] = and64_const(res[64], DIGIT_MASK); + res[65] = add64(res[65], srli64(res[64], DIGIT_SIZE)); + r[5] = and64_const(res[65], DIGIT_MASK); + res[66] = add64(res[66], srli64(res[65], DIGIT_SIZE)); + r[6] = and64_const(res[66], DIGIT_MASK); + res[67] = add64(res[67], srli64(res[66], DIGIT_SIZE)); + r[7] = and64_const(res[67], DIGIT_MASK); + res[68] = add64(res[68], srli64(res[67], DIGIT_SIZE)); + r[8] = and64_const(res[68], DIGIT_MASK); + res[69] = add64(res[69], srli64(res[68], DIGIT_SIZE)); + r[9] = and64_const(res[69], DIGIT_MASK); + res[70] = add64(res[70], srli64(res[69], DIGIT_SIZE)); + r[10] = and64_const(res[70], DIGIT_MASK); + res[71] = add64(res[71], srli64(res[70], DIGIT_SIZE)); + r[11] = and64_const(res[71], DIGIT_MASK); + res[72] = add64(res[72], srli64(res[71], DIGIT_SIZE)); + r[12] = and64_const(res[72], DIGIT_MASK); + res[73] = add64(res[73], srli64(res[72], DIGIT_SIZE)); + r[13] = and64_const(res[73], DIGIT_MASK); + res[74] = add64(res[74], srli64(res[73], DIGIT_SIZE)); + r[14] = and64_const(res[74], DIGIT_MASK); + res[75] = add64(res[75], srli64(res[74], DIGIT_SIZE)); + r[15] = and64_const(res[75], DIGIT_MASK); + res[76] = add64(res[76], srli64(res[75], DIGIT_SIZE)); + r[16] = and64_const(res[76], DIGIT_MASK); + res[77] = add64(res[77], srli64(res[76], DIGIT_SIZE)); + r[17] = and64_const(res[77], DIGIT_MASK); + res[78] = add64(res[78], srli64(res[77], DIGIT_SIZE)); + r[18] = and64_const(res[78], DIGIT_MASK); + res[79] = add64(res[79], srli64(res[78], DIGIT_SIZE)); + r[19] = and64_const(res[79], DIGIT_MASK); + res[80] = add64(res[80], srli64(res[79], DIGIT_SIZE)); + r[20] = and64_const(res[80], DIGIT_MASK); + res[81] = add64(res[81], srli64(res[80], DIGIT_SIZE)); + r[21] = and64_const(res[81], DIGIT_MASK); + res[82] = add64(res[82], srli64(res[81], DIGIT_SIZE)); + r[22] = and64_const(res[82], DIGIT_MASK); + res[83] = add64(res[83], srli64(res[82], DIGIT_SIZE)); + r[23] = and64_const(res[83], DIGIT_MASK); + res[84] = add64(res[84], srli64(res[83], DIGIT_SIZE)); + r[24] = and64_const(res[84], DIGIT_MASK); + res[85] = add64(res[85], srli64(res[84], DIGIT_SIZE)); + r[25] = and64_const(res[85], DIGIT_MASK); + res[86] = add64(res[86], srli64(res[85], DIGIT_SIZE)); + r[26] = and64_const(res[86], DIGIT_MASK); + res[87] = add64(res[87], srli64(res[86], DIGIT_SIZE)); + r[27] = and64_const(res[87], DIGIT_MASK); + res[88] = add64(res[88], srli64(res[87], DIGIT_SIZE)); + r[28] = and64_const(res[88], DIGIT_MASK); + res[89] = add64(res[89], srli64(res[88], DIGIT_SIZE)); + r[29] = and64_const(res[89], DIGIT_MASK); + res[90] = add64(res[90], srli64(res[89], DIGIT_SIZE)); + r[30] = and64_const(res[90], DIGIT_MASK); + res[91] = add64(res[91], srli64(res[90], DIGIT_SIZE)); + r[31] = and64_const(res[91], DIGIT_MASK); + res[92] = add64(res[92], srli64(res[91], DIGIT_SIZE)); + r[32] = and64_const(res[92], DIGIT_MASK); + res[93] = add64(res[93], srli64(res[92], DIGIT_SIZE)); + r[33] = and64_const(res[93], DIGIT_MASK); + res[94] = add64(res[94], srli64(res[93], DIGIT_SIZE)); + r[34] = and64_const(res[94], DIGIT_MASK); + res[95] = add64(res[95], srli64(res[94], DIGIT_SIZE)); + r[35] = and64_const(res[95], DIGIT_MASK); + res[96] = add64(res[96], srli64(res[95], DIGIT_SIZE)); + r[36] = and64_const(res[96], DIGIT_MASK); + res[97] = add64(res[97], srli64(res[96], DIGIT_SIZE)); + r[37] = and64_const(res[97], DIGIT_MASK); + res[98] = add64(res[98], srli64(res[97], DIGIT_SIZE)); + r[38] = and64_const(res[98], DIGIT_MASK); + res[99] = add64(res[99], srli64(res[98], DIGIT_SIZE)); + r[39] = and64_const(res[99], DIGIT_MASK); + res[100] = add64(res[100], srli64(res[99], DIGIT_SIZE)); + r[40] = and64_const(res[100], DIGIT_MASK); + res[101] = add64(res[101], srli64(res[100], DIGIT_SIZE)); + r[41] = and64_const(res[101], DIGIT_MASK); + res[102] = add64(res[102], srli64(res[101], DIGIT_SIZE)); + r[42] = and64_const(res[102], DIGIT_MASK); + res[103] = add64(res[103], srli64(res[102], DIGIT_SIZE)); + r[43] = and64_const(res[103], DIGIT_MASK); + res[104] = add64(res[104], srli64(res[103], DIGIT_SIZE)); + r[44] = and64_const(res[104], DIGIT_MASK); + res[105] = add64(res[105], srli64(res[104], DIGIT_SIZE)); + r[45] = and64_const(res[105], DIGIT_MASK); + res[106] = add64(res[106], srli64(res[105], DIGIT_SIZE)); + r[46] = and64_const(res[106], DIGIT_MASK); + res[107] = add64(res[107], srli64(res[106], DIGIT_SIZE)); + r[47] = and64_const(res[107], DIGIT_MASK); + res[108] = add64(res[108], srli64(res[107], DIGIT_SIZE)); + r[48] = and64_const(res[108], DIGIT_MASK); + res[109] = add64(res[109], srli64(res[108], DIGIT_SIZE)); + r[49] = and64_const(res[109], DIGIT_MASK); + res[110] = add64(res[110], srli64(res[109], DIGIT_SIZE)); + r[50] = and64_const(res[110], DIGIT_MASK); + res[111] = add64(res[111], srli64(res[110], DIGIT_SIZE)); + r[51] = and64_const(res[111], DIGIT_MASK); + res[112] = add64(res[112], srli64(res[111], DIGIT_SIZE)); + r[52] = and64_const(res[112], DIGIT_MASK); + res[113] = add64(res[113], srli64(res[112], DIGIT_SIZE)); + r[53] = and64_const(res[113], DIGIT_MASK); + res[114] = add64(res[114], srli64(res[113], DIGIT_SIZE)); + r[54] = and64_const(res[114], DIGIT_MASK); + res[115] = add64(res[115], srli64(res[114], DIGIT_SIZE)); + r[55] = and64_const(res[115], DIGIT_MASK); + res[116] = add64(res[116], srli64(res[115], DIGIT_SIZE)); + r[56] = and64_const(res[116], DIGIT_MASK); + res[117] = add64(res[117], srli64(res[116], DIGIT_SIZE)); + r[57] = and64_const(res[117], DIGIT_MASK); + res[118] = add64(res[118], srli64(res[117], DIGIT_SIZE)); + r[58] = and64_const(res[118], DIGIT_MASK); + res[119] = add64(res[119], srli64(res[118], DIGIT_SIZE)); + r[59] = and64_const(res[119], DIGIT_MASK); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x79_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x79_diagonal_mb8.c new file mode 100644 index 000000000..dbcc66452 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams52x79_diagonal_mb8.c @@ -0,0 +1,7108 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS52x79_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + + __ALIGN64 U64 res[160]; + __ALIGN64 U64 u[80]; + U64 k; + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + + k = loadu64((U64 *)k0_mb); + int i; + for (i = 0; i < 160; ++i) + res[i] = get_zero64(); + + // Calculate full square + res[1] = fma52lo(res[1], a[0], a[1]); // Sum(1) + res[2] = fma52hi(res[2], a[0], a[1]); // Sum(1) + res[2] = fma52lo(res[2], a[0], a[2]); // Sum(2) + res[3] = fma52hi(res[3], a[0], a[2]); // Sum(2) + res[3] = fma52lo(res[3], a[1], a[2]); // Sum(3) + res[4] = fma52hi(res[4], a[1], a[2]); // Sum(3) + res[3] = fma52lo(res[3], a[0], a[3]); // Sum(3) + res[4] = fma52hi(res[4], a[0], a[3]); // Sum(3) + res[4] = fma52lo(res[4], a[1], a[3]); // Sum(4) + res[5] = fma52hi(res[5], a[1], a[3]); // Sum(4) + res[5] = fma52lo(res[5], a[2], a[3]); // Sum(5) + res[6] = fma52hi(res[6], a[2], a[3]); // Sum(5) + res[4] = fma52lo(res[4], a[0], a[4]); // Sum(4) + res[5] = fma52hi(res[5], a[0], a[4]); // Sum(4) + res[5] = fma52lo(res[5], a[1], a[4]); // Sum(5) + res[6] = fma52hi(res[6], a[1], a[4]); // Sum(5) + res[6] = fma52lo(res[6], a[2], a[4]); // Sum(6) + res[7] = fma52hi(res[7], a[2], a[4]); // Sum(6) + res[7] = fma52lo(res[7], a[3], a[4]); // Sum(7) + res[8] = fma52hi(res[8], a[3], a[4]); // Sum(7) + res[5] = fma52lo(res[5], a[0], a[5]); // Sum(5) + res[6] = fma52hi(res[6], a[0], a[5]); // Sum(5) + res[6] = fma52lo(res[6], a[1], a[5]); // Sum(6) + res[7] = fma52hi(res[7], a[1], a[5]); // Sum(6) + res[7] = fma52lo(res[7], a[2], a[5]); // Sum(7) + res[8] = fma52hi(res[8], a[2], a[5]); // Sum(7) + res[8] = fma52lo(res[8], a[3], a[5]); // Sum(8) + res[9] = fma52hi(res[9], a[3], a[5]); // Sum(8) + res[9] = fma52lo(res[9], a[4], a[5]); // Sum(9) + res[10] = fma52hi(res[10], a[4], a[5]); // Sum(9) + res[6] = fma52lo(res[6], a[0], a[6]); // Sum(6) + res[7] = fma52hi(res[7], a[0], a[6]); // Sum(6) + res[7] = fma52lo(res[7], a[1], a[6]); // Sum(7) + res[8] = fma52hi(res[8], a[1], a[6]); // Sum(7) + res[8] = fma52lo(res[8], a[2], a[6]); // Sum(8) + res[9] = fma52hi(res[9], a[2], a[6]); // Sum(8) + res[9] = fma52lo(res[9], a[3], a[6]); // Sum(9) + res[10] = fma52hi(res[10], a[3], a[6]); // Sum(9) + res[10] = fma52lo(res[10], a[4], a[6]); // Sum(10) + res[11] = fma52hi(res[11], a[4], a[6]); // Sum(10) + res[11] = fma52lo(res[11], a[5], a[6]); // Sum(11) + res[12] = fma52hi(res[12], a[5], a[6]); // Sum(11) + res[7] = fma52lo(res[7], a[0], a[7]); // Sum(7) + res[8] = fma52hi(res[8], a[0], a[7]); // Sum(7) + res[8] = fma52lo(res[8], a[1], a[7]); // Sum(8) + res[9] = fma52hi(res[9], a[1], a[7]); // Sum(8) + res[9] = fma52lo(res[9], a[2], a[7]); // Sum(9) + res[10] = fma52hi(res[10], a[2], a[7]); // Sum(9) + res[10] = fma52lo(res[10], a[3], a[7]); // Sum(10) + res[11] = fma52hi(res[11], a[3], a[7]); // Sum(10) + res[11] = fma52lo(res[11], a[4], a[7]); // Sum(11) + res[12] = fma52hi(res[12], a[4], a[7]); // Sum(11) + res[8] = fma52lo(res[8], a[0], a[8]); // Sum(8) + res[9] = fma52hi(res[9], a[0], a[8]); // Sum(8) + res[9] = fma52lo(res[9], a[1], a[8]); // Sum(9) + res[10] = fma52hi(res[10], a[1], a[8]); // Sum(9) + res[10] = fma52lo(res[10], a[2], a[8]); // Sum(10) + res[11] = fma52hi(res[11], a[2], a[8]); // Sum(10) + res[11] = fma52lo(res[11], a[3], a[8]); // Sum(11) + res[12] = fma52hi(res[12], a[3], a[8]); // Sum(11) + res[9] = fma52lo(res[9], a[0], a[9]); // Sum(9) + res[10] = fma52hi(res[10], a[0], a[9]); // Sum(9) + res[10] = fma52lo(res[10], a[1], a[9]); // Sum(10) + res[11] = fma52hi(res[11], a[1], a[9]); // Sum(10) + res[11] = fma52lo(res[11], a[2], a[9]); // Sum(11) + res[12] = fma52hi(res[12], a[2], a[9]); // Sum(11) + res[10] = fma52lo(res[10], a[0], a[10]); // Sum(10) + res[11] = fma52hi(res[11], a[0], a[10]); // Sum(10) + res[11] = fma52lo(res[11], a[1], a[10]); // Sum(11) + res[12] = fma52hi(res[12], a[1], a[10]); // Sum(11) + res[11] = fma52lo(res[11], a[0], a[11]); // Sum(11) + res[12] = fma52hi(res[12], a[0], a[11]); // Sum(11) + res[0] = add64(res[0], res[0]); // Double(0) + res[1] = add64(res[1], res[1]); // Double(1) + res[2] = add64(res[2], res[2]); // Double(2) + res[3] = add64(res[3], res[3]); // Double(3) + res[4] = add64(res[4], res[4]); // Double(4) + res[5] = add64(res[5], res[5]); // Double(5) + res[6] = add64(res[6], res[6]); // Double(6) + res[7] = add64(res[7], res[7]); // Double(7) + res[8] = add64(res[8], res[8]); // Double(8) + res[9] = add64(res[9], res[9]); // Double(9) + res[10] = add64(res[10], res[10]); // Double(10) + res[11] = add64(res[11], res[11]); // Double(11) + res[0] = fma52lo(res[0], a[0], a[0]); // Add sqr(0) + res[1] = fma52hi(res[1], a[0], a[0]); // Add sqr(0) + res[2] = fma52lo(res[2], a[1], a[1]); // Add sqr(2) + res[3] = fma52hi(res[3], a[1], a[1]); // Add sqr(2) + res[4] = fma52lo(res[4], a[2], a[2]); // Add sqr(4) + res[5] = fma52hi(res[5], a[2], a[2]); // Add sqr(4) + res[6] = fma52lo(res[6], a[3], a[3]); // Add sqr(6) + res[7] = fma52hi(res[7], a[3], a[3]); // Add sqr(6) + res[8] = fma52lo(res[8], a[4], a[4]); // Add sqr(8) + res[9] = fma52hi(res[9], a[4], a[4]); // Add sqr(8) + res[10] = fma52lo(res[10], a[5], a[5]); // Add sqr(10) + res[11] = fma52hi(res[11], a[5], a[5]); // Add sqr(10) + res[12] = fma52lo(res[12], a[5], a[7]); // Sum(12) + res[13] = fma52hi(res[13], a[5], a[7]); // Sum(12) + res[13] = fma52lo(res[13], a[6], a[7]); // Sum(13) + res[14] = fma52hi(res[14], a[6], a[7]); // Sum(13) + res[12] = fma52lo(res[12], a[4], a[8]); // Sum(12) + res[13] = fma52hi(res[13], a[4], a[8]); // Sum(12) + res[13] = fma52lo(res[13], a[5], a[8]); // Sum(13) + res[14] = fma52hi(res[14], a[5], a[8]); // Sum(13) + res[14] = fma52lo(res[14], a[6], a[8]); // Sum(14) + res[15] = fma52hi(res[15], a[6], a[8]); // Sum(14) + res[15] = fma52lo(res[15], a[7], a[8]); // Sum(15) + res[16] = fma52hi(res[16], a[7], a[8]); // Sum(15) + res[12] = fma52lo(res[12], a[3], a[9]); // Sum(12) + res[13] = fma52hi(res[13], a[3], a[9]); // Sum(12) + res[13] = fma52lo(res[13], a[4], a[9]); // Sum(13) + res[14] = fma52hi(res[14], a[4], a[9]); // Sum(13) + res[14] = fma52lo(res[14], a[5], a[9]); // Sum(14) + res[15] = fma52hi(res[15], a[5], a[9]); // Sum(14) + res[15] = fma52lo(res[15], a[6], a[9]); // Sum(15) + res[16] = fma52hi(res[16], a[6], a[9]); // Sum(15) + res[16] = fma52lo(res[16], a[7], a[9]); // Sum(16) + res[17] = fma52hi(res[17], a[7], a[9]); // Sum(16) + res[17] = fma52lo(res[17], a[8], a[9]); // Sum(17) + res[18] = fma52hi(res[18], a[8], a[9]); // Sum(17) + res[12] = fma52lo(res[12], a[2], a[10]); // Sum(12) + res[13] = fma52hi(res[13], a[2], a[10]); // Sum(12) + res[13] = fma52lo(res[13], a[3], a[10]); // Sum(13) + res[14] = fma52hi(res[14], a[3], a[10]); // Sum(13) + res[14] = fma52lo(res[14], a[4], a[10]); // Sum(14) + res[15] = fma52hi(res[15], a[4], a[10]); // Sum(14) + res[15] = fma52lo(res[15], a[5], a[10]); // Sum(15) + res[16] = fma52hi(res[16], a[5], a[10]); // Sum(15) + res[16] = fma52lo(res[16], a[6], a[10]); // Sum(16) + res[17] = fma52hi(res[17], a[6], a[10]); // Sum(16) + res[17] = fma52lo(res[17], a[7], a[10]); // Sum(17) + res[18] = fma52hi(res[18], a[7], a[10]); // Sum(17) + res[18] = fma52lo(res[18], a[8], a[10]); // Sum(18) + res[19] = fma52hi(res[19], a[8], a[10]); // Sum(18) + res[19] = fma52lo(res[19], a[9], a[10]); // Sum(19) + res[20] = fma52hi(res[20], a[9], a[10]); // Sum(19) + res[12] = fma52lo(res[12], a[1], a[11]); // Sum(12) + res[13] = fma52hi(res[13], a[1], a[11]); // Sum(12) + res[13] = fma52lo(res[13], a[2], a[11]); // Sum(13) + res[14] = fma52hi(res[14], a[2], a[11]); // Sum(13) + res[14] = fma52lo(res[14], a[3], a[11]); // Sum(14) + res[15] = fma52hi(res[15], a[3], a[11]); // Sum(14) + res[15] = fma52lo(res[15], a[4], a[11]); // Sum(15) + res[16] = fma52hi(res[16], a[4], a[11]); // Sum(15) + res[16] = fma52lo(res[16], a[5], a[11]); // Sum(16) + res[17] = fma52hi(res[17], a[5], a[11]); // Sum(16) + res[17] = fma52lo(res[17], a[6], a[11]); // Sum(17) + res[18] = fma52hi(res[18], a[6], a[11]); // Sum(17) + res[18] = fma52lo(res[18], a[7], a[11]); // Sum(18) + res[19] = fma52hi(res[19], a[7], a[11]); // Sum(18) + res[19] = fma52lo(res[19], a[8], a[11]); // Sum(19) + res[20] = fma52hi(res[20], a[8], a[11]); // Sum(19) + res[20] = fma52lo(res[20], a[9], a[11]); // Sum(20) + res[21] = fma52hi(res[21], a[9], a[11]); // Sum(20) + res[21] = fma52lo(res[21], a[10], a[11]); // Sum(21) + res[22] = fma52hi(res[22], a[10], a[11]); // Sum(21) + res[12] = fma52lo(res[12], a[0], a[12]); // Sum(12) + res[13] = fma52hi(res[13], a[0], a[12]); // Sum(12) + res[13] = fma52lo(res[13], a[1], a[12]); // Sum(13) + res[14] = fma52hi(res[14], a[1], a[12]); // Sum(13) + res[14] = fma52lo(res[14], a[2], a[12]); // Sum(14) + res[15] = fma52hi(res[15], a[2], a[12]); // Sum(14) + res[15] = fma52lo(res[15], a[3], a[12]); // Sum(15) + res[16] = fma52hi(res[16], a[3], a[12]); // Sum(15) + res[16] = fma52lo(res[16], a[4], a[12]); // Sum(16) + res[17] = fma52hi(res[17], a[4], a[12]); // Sum(16) + res[17] = fma52lo(res[17], a[5], a[12]); // Sum(17) + res[18] = fma52hi(res[18], a[5], a[12]); // Sum(17) + res[18] = fma52lo(res[18], a[6], a[12]); // Sum(18) + res[19] = fma52hi(res[19], a[6], a[12]); // Sum(18) + res[19] = fma52lo(res[19], a[7], a[12]); // Sum(19) + res[20] = fma52hi(res[20], a[7], a[12]); // Sum(19) + res[20] = fma52lo(res[20], a[8], a[12]); // Sum(20) + res[21] = fma52hi(res[21], a[8], a[12]); // Sum(20) + res[21] = fma52lo(res[21], a[9], a[12]); // Sum(21) + res[22] = fma52hi(res[22], a[9], a[12]); // Sum(21) + res[22] = fma52lo(res[22], a[10], a[12]); // Sum(22) + res[23] = fma52hi(res[23], a[10], a[12]); // Sum(22) + res[23] = fma52lo(res[23], a[11], a[12]); // Sum(23) + res[24] = fma52hi(res[24], a[11], a[12]); // Sum(23) + res[13] = fma52lo(res[13], a[0], a[13]); // Sum(13) + res[14] = fma52hi(res[14], a[0], a[13]); // Sum(13) + res[14] = fma52lo(res[14], a[1], a[13]); // Sum(14) + res[15] = fma52hi(res[15], a[1], a[13]); // Sum(14) + res[15] = fma52lo(res[15], a[2], a[13]); // Sum(15) + res[16] = fma52hi(res[16], a[2], a[13]); // Sum(15) + res[16] = fma52lo(res[16], a[3], a[13]); // Sum(16) + res[17] = fma52hi(res[17], a[3], a[13]); // Sum(16) + res[17] = fma52lo(res[17], a[4], a[13]); // Sum(17) + res[18] = fma52hi(res[18], a[4], a[13]); // Sum(17) + res[18] = fma52lo(res[18], a[5], a[13]); // Sum(18) + res[19] = fma52hi(res[19], a[5], a[13]); // Sum(18) + res[19] = fma52lo(res[19], a[6], a[13]); // Sum(19) + res[20] = fma52hi(res[20], a[6], a[13]); // Sum(19) + res[20] = fma52lo(res[20], a[7], a[13]); // Sum(20) + res[21] = fma52hi(res[21], a[7], a[13]); // Sum(20) + res[21] = fma52lo(res[21], a[8], a[13]); // Sum(21) + res[22] = fma52hi(res[22], a[8], a[13]); // Sum(21) + res[22] = fma52lo(res[22], a[9], a[13]); // Sum(22) + res[23] = fma52hi(res[23], a[9], a[13]); // Sum(22) + res[23] = fma52lo(res[23], a[10], a[13]); // Sum(23) + res[24] = fma52hi(res[24], a[10], a[13]); // Sum(23) + res[14] = fma52lo(res[14], a[0], a[14]); // Sum(14) + res[15] = fma52hi(res[15], a[0], a[14]); // Sum(14) + res[15] = fma52lo(res[15], a[1], a[14]); // Sum(15) + res[16] = fma52hi(res[16], a[1], a[14]); // Sum(15) + res[16] = fma52lo(res[16], a[2], a[14]); // Sum(16) + res[17] = fma52hi(res[17], a[2], a[14]); // Sum(16) + res[17] = fma52lo(res[17], a[3], a[14]); // Sum(17) + res[18] = fma52hi(res[18], a[3], a[14]); // Sum(17) + res[18] = fma52lo(res[18], a[4], a[14]); // Sum(18) + res[19] = fma52hi(res[19], a[4], a[14]); // Sum(18) + res[19] = fma52lo(res[19], a[5], a[14]); // Sum(19) + res[20] = fma52hi(res[20], a[5], a[14]); // Sum(19) + res[20] = fma52lo(res[20], a[6], a[14]); // Sum(20) + res[21] = fma52hi(res[21], a[6], a[14]); // Sum(20) + res[21] = fma52lo(res[21], a[7], a[14]); // Sum(21) + res[22] = fma52hi(res[22], a[7], a[14]); // Sum(21) + res[22] = fma52lo(res[22], a[8], a[14]); // Sum(22) + res[23] = fma52hi(res[23], a[8], a[14]); // Sum(22) + res[23] = fma52lo(res[23], a[9], a[14]); // Sum(23) + res[24] = fma52hi(res[24], a[9], a[14]); // Sum(23) + res[15] = fma52lo(res[15], a[0], a[15]); // Sum(15) + res[16] = fma52hi(res[16], a[0], a[15]); // Sum(15) + res[16] = fma52lo(res[16], a[1], a[15]); // Sum(16) + res[17] = fma52hi(res[17], a[1], a[15]); // Sum(16) + res[17] = fma52lo(res[17], a[2], a[15]); // Sum(17) + res[18] = fma52hi(res[18], a[2], a[15]); // Sum(17) + res[18] = fma52lo(res[18], a[3], a[15]); // Sum(18) + res[19] = fma52hi(res[19], a[3], a[15]); // Sum(18) + res[19] = fma52lo(res[19], a[4], a[15]); // Sum(19) + res[20] = fma52hi(res[20], a[4], a[15]); // Sum(19) + res[20] = fma52lo(res[20], a[5], a[15]); // Sum(20) + res[21] = fma52hi(res[21], a[5], a[15]); // Sum(20) + res[21] = fma52lo(res[21], a[6], a[15]); // Sum(21) + res[22] = fma52hi(res[22], a[6], a[15]); // Sum(21) + res[22] = fma52lo(res[22], a[7], a[15]); // Sum(22) + res[23] = fma52hi(res[23], a[7], a[15]); // Sum(22) + res[23] = fma52lo(res[23], a[8], a[15]); // Sum(23) + res[24] = fma52hi(res[24], a[8], a[15]); // Sum(23) + res[16] = fma52lo(res[16], a[0], a[16]); // Sum(16) + res[17] = fma52hi(res[17], a[0], a[16]); // Sum(16) + res[17] = fma52lo(res[17], a[1], a[16]); // Sum(17) + res[18] = fma52hi(res[18], a[1], a[16]); // Sum(17) + res[18] = fma52lo(res[18], a[2], a[16]); // Sum(18) + res[19] = fma52hi(res[19], a[2], a[16]); // Sum(18) + res[19] = fma52lo(res[19], a[3], a[16]); // Sum(19) + res[20] = fma52hi(res[20], a[3], a[16]); // Sum(19) + res[20] = fma52lo(res[20], a[4], a[16]); // Sum(20) + res[21] = fma52hi(res[21], a[4], a[16]); // Sum(20) + res[21] = fma52lo(res[21], a[5], a[16]); // Sum(21) + res[22] = fma52hi(res[22], a[5], a[16]); // Sum(21) + res[22] = fma52lo(res[22], a[6], a[16]); // Sum(22) + res[23] = fma52hi(res[23], a[6], a[16]); // Sum(22) + res[23] = fma52lo(res[23], a[7], a[16]); // Sum(23) + res[24] = fma52hi(res[24], a[7], a[16]); // Sum(23) + res[17] = fma52lo(res[17], a[0], a[17]); // Sum(17) + res[18] = fma52hi(res[18], a[0], a[17]); // Sum(17) + res[18] = fma52lo(res[18], a[1], a[17]); // Sum(18) + res[19] = fma52hi(res[19], a[1], a[17]); // Sum(18) + res[19] = fma52lo(res[19], a[2], a[17]); // Sum(19) + res[20] = fma52hi(res[20], a[2], a[17]); // Sum(19) + res[20] = fma52lo(res[20], a[3], a[17]); // Sum(20) + res[21] = fma52hi(res[21], a[3], a[17]); // Sum(20) + res[21] = fma52lo(res[21], a[4], a[17]); // Sum(21) + res[22] = fma52hi(res[22], a[4], a[17]); // Sum(21) + res[22] = fma52lo(res[22], a[5], a[17]); // Sum(22) + res[23] = fma52hi(res[23], a[5], a[17]); // Sum(22) + res[23] = fma52lo(res[23], a[6], a[17]); // Sum(23) + res[24] = fma52hi(res[24], a[6], a[17]); // Sum(23) + res[18] = fma52lo(res[18], a[0], a[18]); // Sum(18) + res[19] = fma52hi(res[19], a[0], a[18]); // Sum(18) + res[19] = fma52lo(res[19], a[1], a[18]); // Sum(19) + res[20] = fma52hi(res[20], a[1], a[18]); // Sum(19) + res[20] = fma52lo(res[20], a[2], a[18]); // Sum(20) + res[21] = fma52hi(res[21], a[2], a[18]); // Sum(20) + res[21] = fma52lo(res[21], a[3], a[18]); // Sum(21) + res[22] = fma52hi(res[22], a[3], a[18]); // Sum(21) + res[22] = fma52lo(res[22], a[4], a[18]); // Sum(22) + res[23] = fma52hi(res[23], a[4], a[18]); // Sum(22) + res[23] = fma52lo(res[23], a[5], a[18]); // Sum(23) + res[24] = fma52hi(res[24], a[5], a[18]); // Sum(23) + res[19] = fma52lo(res[19], a[0], a[19]); // Sum(19) + res[20] = fma52hi(res[20], a[0], a[19]); // Sum(19) + res[20] = fma52lo(res[20], a[1], a[19]); // Sum(20) + res[21] = fma52hi(res[21], a[1], a[19]); // Sum(20) + res[21] = fma52lo(res[21], a[2], a[19]); // Sum(21) + res[22] = fma52hi(res[22], a[2], a[19]); // Sum(21) + res[22] = fma52lo(res[22], a[3], a[19]); // Sum(22) + res[23] = fma52hi(res[23], a[3], a[19]); // Sum(22) + res[23] = fma52lo(res[23], a[4], a[19]); // Sum(23) + res[24] = fma52hi(res[24], a[4], a[19]); // Sum(23) + res[20] = fma52lo(res[20], a[0], a[20]); // Sum(20) + res[21] = fma52hi(res[21], a[0], a[20]); // Sum(20) + res[21] = fma52lo(res[21], a[1], a[20]); // Sum(21) + res[22] = fma52hi(res[22], a[1], a[20]); // Sum(21) + res[22] = fma52lo(res[22], a[2], a[20]); // Sum(22) + res[23] = fma52hi(res[23], a[2], a[20]); // Sum(22) + res[23] = fma52lo(res[23], a[3], a[20]); // Sum(23) + res[24] = fma52hi(res[24], a[3], a[20]); // Sum(23) + res[21] = fma52lo(res[21], a[0], a[21]); // Sum(21) + res[22] = fma52hi(res[22], a[0], a[21]); // Sum(21) + res[22] = fma52lo(res[22], a[1], a[21]); // Sum(22) + res[23] = fma52hi(res[23], a[1], a[21]); // Sum(22) + res[23] = fma52lo(res[23], a[2], a[21]); // Sum(23) + res[24] = fma52hi(res[24], a[2], a[21]); // Sum(23) + res[22] = fma52lo(res[22], a[0], a[22]); // Sum(22) + res[23] = fma52hi(res[23], a[0], a[22]); // Sum(22) + res[23] = fma52lo(res[23], a[1], a[22]); // Sum(23) + res[24] = fma52hi(res[24], a[1], a[22]); // Sum(23) + res[23] = fma52lo(res[23], a[0], a[23]); // Sum(23) + res[24] = fma52hi(res[24], a[0], a[23]); // Sum(23) + res[12] = add64(res[12], res[12]); // Double(12) + res[13] = add64(res[13], res[13]); // Double(13) + res[14] = add64(res[14], res[14]); // Double(14) + res[15] = add64(res[15], res[15]); // Double(15) + res[16] = add64(res[16], res[16]); // Double(16) + res[17] = add64(res[17], res[17]); // Double(17) + res[18] = add64(res[18], res[18]); // Double(18) + res[19] = add64(res[19], res[19]); // Double(19) + res[20] = add64(res[20], res[20]); // Double(20) + res[21] = add64(res[21], res[21]); // Double(21) + res[22] = add64(res[22], res[22]); // Double(22) + res[23] = add64(res[23], res[23]); // Double(23) + res[12] = fma52lo(res[12], a[6], a[6]); // Add sqr(12) + res[13] = fma52hi(res[13], a[6], a[6]); // Add sqr(12) + res[14] = fma52lo(res[14], a[7], a[7]); // Add sqr(14) + res[15] = fma52hi(res[15], a[7], a[7]); // Add sqr(14) + res[16] = fma52lo(res[16], a[8], a[8]); // Add sqr(16) + res[17] = fma52hi(res[17], a[8], a[8]); // Add sqr(16) + res[18] = fma52lo(res[18], a[9], a[9]); // Add sqr(18) + res[19] = fma52hi(res[19], a[9], a[9]); // Add sqr(18) + res[20] = fma52lo(res[20], a[10], a[10]); // Add sqr(20) + res[21] = fma52hi(res[21], a[10], a[10]); // Add sqr(20) + res[22] = fma52lo(res[22], a[11], a[11]); // Add sqr(22) + res[23] = fma52hi(res[23], a[11], a[11]); // Add sqr(22) + res[24] = fma52lo(res[24], a[11], a[13]); // Sum(24) + res[25] = fma52hi(res[25], a[11], a[13]); // Sum(24) + res[25] = fma52lo(res[25], a[12], a[13]); // Sum(25) + res[26] = fma52hi(res[26], a[12], a[13]); // Sum(25) + res[24] = fma52lo(res[24], a[10], a[14]); // Sum(24) + res[25] = fma52hi(res[25], a[10], a[14]); // Sum(24) + res[25] = fma52lo(res[25], a[11], a[14]); // Sum(25) + res[26] = fma52hi(res[26], a[11], a[14]); // Sum(25) + res[26] = fma52lo(res[26], a[12], a[14]); // Sum(26) + res[27] = fma52hi(res[27], a[12], a[14]); // Sum(26) + res[27] = fma52lo(res[27], a[13], a[14]); // Sum(27) + res[28] = fma52hi(res[28], a[13], a[14]); // Sum(27) + res[24] = fma52lo(res[24], a[9], a[15]); // Sum(24) + res[25] = fma52hi(res[25], a[9], a[15]); // Sum(24) + res[25] = fma52lo(res[25], a[10], a[15]); // Sum(25) + res[26] = fma52hi(res[26], a[10], a[15]); // Sum(25) + res[26] = fma52lo(res[26], a[11], a[15]); // Sum(26) + res[27] = fma52hi(res[27], a[11], a[15]); // Sum(26) + res[27] = fma52lo(res[27], a[12], a[15]); // Sum(27) + res[28] = fma52hi(res[28], a[12], a[15]); // Sum(27) + res[28] = fma52lo(res[28], a[13], a[15]); // Sum(28) + res[29] = fma52hi(res[29], a[13], a[15]); // Sum(28) + res[29] = fma52lo(res[29], a[14], a[15]); // Sum(29) + res[30] = fma52hi(res[30], a[14], a[15]); // Sum(29) + res[24] = fma52lo(res[24], a[8], a[16]); // Sum(24) + res[25] = fma52hi(res[25], a[8], a[16]); // Sum(24) + res[25] = fma52lo(res[25], a[9], a[16]); // Sum(25) + res[26] = fma52hi(res[26], a[9], a[16]); // Sum(25) + res[26] = fma52lo(res[26], a[10], a[16]); // Sum(26) + res[27] = fma52hi(res[27], a[10], a[16]); // Sum(26) + res[27] = fma52lo(res[27], a[11], a[16]); // Sum(27) + res[28] = fma52hi(res[28], a[11], a[16]); // Sum(27) + res[28] = fma52lo(res[28], a[12], a[16]); // Sum(28) + res[29] = fma52hi(res[29], a[12], a[16]); // Sum(28) + res[29] = fma52lo(res[29], a[13], a[16]); // Sum(29) + res[30] = fma52hi(res[30], a[13], a[16]); // Sum(29) + res[30] = fma52lo(res[30], a[14], a[16]); // Sum(30) + res[31] = fma52hi(res[31], a[14], a[16]); // Sum(30) + res[31] = fma52lo(res[31], a[15], a[16]); // Sum(31) + res[32] = fma52hi(res[32], a[15], a[16]); // Sum(31) + res[24] = fma52lo(res[24], a[7], a[17]); // Sum(24) + res[25] = fma52hi(res[25], a[7], a[17]); // Sum(24) + res[25] = fma52lo(res[25], a[8], a[17]); // Sum(25) + res[26] = fma52hi(res[26], a[8], a[17]); // Sum(25) + res[26] = fma52lo(res[26], a[9], a[17]); // Sum(26) + res[27] = fma52hi(res[27], a[9], a[17]); // Sum(26) + res[27] = fma52lo(res[27], a[10], a[17]); // Sum(27) + res[28] = fma52hi(res[28], a[10], a[17]); // Sum(27) + res[28] = fma52lo(res[28], a[11], a[17]); // Sum(28) + res[29] = fma52hi(res[29], a[11], a[17]); // Sum(28) + res[29] = fma52lo(res[29], a[12], a[17]); // Sum(29) + res[30] = fma52hi(res[30], a[12], a[17]); // Sum(29) + res[30] = fma52lo(res[30], a[13], a[17]); // Sum(30) + res[31] = fma52hi(res[31], a[13], a[17]); // Sum(30) + res[31] = fma52lo(res[31], a[14], a[17]); // Sum(31) + res[32] = fma52hi(res[32], a[14], a[17]); // Sum(31) + res[32] = fma52lo(res[32], a[15], a[17]); // Sum(32) + res[33] = fma52hi(res[33], a[15], a[17]); // Sum(32) + res[33] = fma52lo(res[33], a[16], a[17]); // Sum(33) + res[34] = fma52hi(res[34], a[16], a[17]); // Sum(33) + res[24] = fma52lo(res[24], a[6], a[18]); // Sum(24) + res[25] = fma52hi(res[25], a[6], a[18]); // Sum(24) + res[25] = fma52lo(res[25], a[7], a[18]); // Sum(25) + res[26] = fma52hi(res[26], a[7], a[18]); // Sum(25) + res[26] = fma52lo(res[26], a[8], a[18]); // Sum(26) + res[27] = fma52hi(res[27], a[8], a[18]); // Sum(26) + res[27] = fma52lo(res[27], a[9], a[18]); // Sum(27) + res[28] = fma52hi(res[28], a[9], a[18]); // Sum(27) + res[28] = fma52lo(res[28], a[10], a[18]); // Sum(28) + res[29] = fma52hi(res[29], a[10], a[18]); // Sum(28) + res[29] = fma52lo(res[29], a[11], a[18]); // Sum(29) + res[30] = fma52hi(res[30], a[11], a[18]); // Sum(29) + res[30] = fma52lo(res[30], a[12], a[18]); // Sum(30) + res[31] = fma52hi(res[31], a[12], a[18]); // Sum(30) + res[31] = fma52lo(res[31], a[13], a[18]); // Sum(31) + res[32] = fma52hi(res[32], a[13], a[18]); // Sum(31) + res[32] = fma52lo(res[32], a[14], a[18]); // Sum(32) + res[33] = fma52hi(res[33], a[14], a[18]); // Sum(32) + res[33] = fma52lo(res[33], a[15], a[18]); // Sum(33) + res[34] = fma52hi(res[34], a[15], a[18]); // Sum(33) + res[34] = fma52lo(res[34], a[16], a[18]); // Sum(34) + res[35] = fma52hi(res[35], a[16], a[18]); // Sum(34) + res[35] = fma52lo(res[35], a[17], a[18]); // Sum(35) + res[36] = fma52hi(res[36], a[17], a[18]); // Sum(35) + res[24] = fma52lo(res[24], a[5], a[19]); // Sum(24) + res[25] = fma52hi(res[25], a[5], a[19]); // Sum(24) + res[25] = fma52lo(res[25], a[6], a[19]); // Sum(25) + res[26] = fma52hi(res[26], a[6], a[19]); // Sum(25) + res[26] = fma52lo(res[26], a[7], a[19]); // Sum(26) + res[27] = fma52hi(res[27], a[7], a[19]); // Sum(26) + res[27] = fma52lo(res[27], a[8], a[19]); // Sum(27) + res[28] = fma52hi(res[28], a[8], a[19]); // Sum(27) + res[28] = fma52lo(res[28], a[9], a[19]); // Sum(28) + res[29] = fma52hi(res[29], a[9], a[19]); // Sum(28) + res[29] = fma52lo(res[29], a[10], a[19]); // Sum(29) + res[30] = fma52hi(res[30], a[10], a[19]); // Sum(29) + res[30] = fma52lo(res[30], a[11], a[19]); // Sum(30) + res[31] = fma52hi(res[31], a[11], a[19]); // Sum(30) + res[31] = fma52lo(res[31], a[12], a[19]); // Sum(31) + res[32] = fma52hi(res[32], a[12], a[19]); // Sum(31) + res[32] = fma52lo(res[32], a[13], a[19]); // Sum(32) + res[33] = fma52hi(res[33], a[13], a[19]); // Sum(32) + res[33] = fma52lo(res[33], a[14], a[19]); // Sum(33) + res[34] = fma52hi(res[34], a[14], a[19]); // Sum(33) + res[34] = fma52lo(res[34], a[15], a[19]); // Sum(34) + res[35] = fma52hi(res[35], a[15], a[19]); // Sum(34) + res[35] = fma52lo(res[35], a[16], a[19]); // Sum(35) + res[36] = fma52hi(res[36], a[16], a[19]); // Sum(35) + res[24] = fma52lo(res[24], a[4], a[20]); // Sum(24) + res[25] = fma52hi(res[25], a[4], a[20]); // Sum(24) + res[25] = fma52lo(res[25], a[5], a[20]); // Sum(25) + res[26] = fma52hi(res[26], a[5], a[20]); // Sum(25) + res[26] = fma52lo(res[26], a[6], a[20]); // Sum(26) + res[27] = fma52hi(res[27], a[6], a[20]); // Sum(26) + res[27] = fma52lo(res[27], a[7], a[20]); // Sum(27) + res[28] = fma52hi(res[28], a[7], a[20]); // Sum(27) + res[28] = fma52lo(res[28], a[8], a[20]); // Sum(28) + res[29] = fma52hi(res[29], a[8], a[20]); // Sum(28) + res[29] = fma52lo(res[29], a[9], a[20]); // Sum(29) + res[30] = fma52hi(res[30], a[9], a[20]); // Sum(29) + res[30] = fma52lo(res[30], a[10], a[20]); // Sum(30) + res[31] = fma52hi(res[31], a[10], a[20]); // Sum(30) + res[31] = fma52lo(res[31], a[11], a[20]); // Sum(31) + res[32] = fma52hi(res[32], a[11], a[20]); // Sum(31) + res[32] = fma52lo(res[32], a[12], a[20]); // Sum(32) + res[33] = fma52hi(res[33], a[12], a[20]); // Sum(32) + res[33] = fma52lo(res[33], a[13], a[20]); // Sum(33) + res[34] = fma52hi(res[34], a[13], a[20]); // Sum(33) + res[34] = fma52lo(res[34], a[14], a[20]); // Sum(34) + res[35] = fma52hi(res[35], a[14], a[20]); // Sum(34) + res[35] = fma52lo(res[35], a[15], a[20]); // Sum(35) + res[36] = fma52hi(res[36], a[15], a[20]); // Sum(35) + res[24] = fma52lo(res[24], a[3], a[21]); // Sum(24) + res[25] = fma52hi(res[25], a[3], a[21]); // Sum(24) + res[25] = fma52lo(res[25], a[4], a[21]); // Sum(25) + res[26] = fma52hi(res[26], a[4], a[21]); // Sum(25) + res[26] = fma52lo(res[26], a[5], a[21]); // Sum(26) + res[27] = fma52hi(res[27], a[5], a[21]); // Sum(26) + res[27] = fma52lo(res[27], a[6], a[21]); // Sum(27) + res[28] = fma52hi(res[28], a[6], a[21]); // Sum(27) + res[28] = fma52lo(res[28], a[7], a[21]); // Sum(28) + res[29] = fma52hi(res[29], a[7], a[21]); // Sum(28) + res[29] = fma52lo(res[29], a[8], a[21]); // Sum(29) + res[30] = fma52hi(res[30], a[8], a[21]); // Sum(29) + res[30] = fma52lo(res[30], a[9], a[21]); // Sum(30) + res[31] = fma52hi(res[31], a[9], a[21]); // Sum(30) + res[31] = fma52lo(res[31], a[10], a[21]); // Sum(31) + res[32] = fma52hi(res[32], a[10], a[21]); // Sum(31) + res[32] = fma52lo(res[32], a[11], a[21]); // Sum(32) + res[33] = fma52hi(res[33], a[11], a[21]); // Sum(32) + res[33] = fma52lo(res[33], a[12], a[21]); // Sum(33) + res[34] = fma52hi(res[34], a[12], a[21]); // Sum(33) + res[34] = fma52lo(res[34], a[13], a[21]); // Sum(34) + res[35] = fma52hi(res[35], a[13], a[21]); // Sum(34) + res[35] = fma52lo(res[35], a[14], a[21]); // Sum(35) + res[36] = fma52hi(res[36], a[14], a[21]); // Sum(35) + res[24] = fma52lo(res[24], a[2], a[22]); // Sum(24) + res[25] = fma52hi(res[25], a[2], a[22]); // Sum(24) + res[25] = fma52lo(res[25], a[3], a[22]); // Sum(25) + res[26] = fma52hi(res[26], a[3], a[22]); // Sum(25) + res[26] = fma52lo(res[26], a[4], a[22]); // Sum(26) + res[27] = fma52hi(res[27], a[4], a[22]); // Sum(26) + res[27] = fma52lo(res[27], a[5], a[22]); // Sum(27) + res[28] = fma52hi(res[28], a[5], a[22]); // Sum(27) + res[28] = fma52lo(res[28], a[6], a[22]); // Sum(28) + res[29] = fma52hi(res[29], a[6], a[22]); // Sum(28) + res[29] = fma52lo(res[29], a[7], a[22]); // Sum(29) + res[30] = fma52hi(res[30], a[7], a[22]); // Sum(29) + res[30] = fma52lo(res[30], a[8], a[22]); // Sum(30) + res[31] = fma52hi(res[31], a[8], a[22]); // Sum(30) + res[31] = fma52lo(res[31], a[9], a[22]); // Sum(31) + res[32] = fma52hi(res[32], a[9], a[22]); // Sum(31) + res[32] = fma52lo(res[32], a[10], a[22]); // Sum(32) + res[33] = fma52hi(res[33], a[10], a[22]); // Sum(32) + res[33] = fma52lo(res[33], a[11], a[22]); // Sum(33) + res[34] = fma52hi(res[34], a[11], a[22]); // Sum(33) + res[34] = fma52lo(res[34], a[12], a[22]); // Sum(34) + res[35] = fma52hi(res[35], a[12], a[22]); // Sum(34) + res[35] = fma52lo(res[35], a[13], a[22]); // Sum(35) + res[36] = fma52hi(res[36], a[13], a[22]); // Sum(35) + res[24] = fma52lo(res[24], a[1], a[23]); // Sum(24) + res[25] = fma52hi(res[25], a[1], a[23]); // Sum(24) + res[25] = fma52lo(res[25], a[2], a[23]); // Sum(25) + res[26] = fma52hi(res[26], a[2], a[23]); // Sum(25) + res[26] = fma52lo(res[26], a[3], a[23]); // Sum(26) + res[27] = fma52hi(res[27], a[3], a[23]); // Sum(26) + res[27] = fma52lo(res[27], a[4], a[23]); // Sum(27) + res[28] = fma52hi(res[28], a[4], a[23]); // Sum(27) + res[28] = fma52lo(res[28], a[5], a[23]); // Sum(28) + res[29] = fma52hi(res[29], a[5], a[23]); // Sum(28) + res[29] = fma52lo(res[29], a[6], a[23]); // Sum(29) + res[30] = fma52hi(res[30], a[6], a[23]); // Sum(29) + res[30] = fma52lo(res[30], a[7], a[23]); // Sum(30) + res[31] = fma52hi(res[31], a[7], a[23]); // Sum(30) + res[31] = fma52lo(res[31], a[8], a[23]); // Sum(31) + res[32] = fma52hi(res[32], a[8], a[23]); // Sum(31) + res[32] = fma52lo(res[32], a[9], a[23]); // Sum(32) + res[33] = fma52hi(res[33], a[9], a[23]); // Sum(32) + res[33] = fma52lo(res[33], a[10], a[23]); // Sum(33) + res[34] = fma52hi(res[34], a[10], a[23]); // Sum(33) + res[34] = fma52lo(res[34], a[11], a[23]); // Sum(34) + res[35] = fma52hi(res[35], a[11], a[23]); // Sum(34) + res[35] = fma52lo(res[35], a[12], a[23]); // Sum(35) + res[36] = fma52hi(res[36], a[12], a[23]); // Sum(35) + res[24] = fma52lo(res[24], a[0], a[24]); // Sum(24) + res[25] = fma52hi(res[25], a[0], a[24]); // Sum(24) + res[25] = fma52lo(res[25], a[1], a[24]); // Sum(25) + res[26] = fma52hi(res[26], a[1], a[24]); // Sum(25) + res[26] = fma52lo(res[26], a[2], a[24]); // Sum(26) + res[27] = fma52hi(res[27], a[2], a[24]); // Sum(26) + res[27] = fma52lo(res[27], a[3], a[24]); // Sum(27) + res[28] = fma52hi(res[28], a[3], a[24]); // Sum(27) + res[28] = fma52lo(res[28], a[4], a[24]); // Sum(28) + res[29] = fma52hi(res[29], a[4], a[24]); // Sum(28) + res[29] = fma52lo(res[29], a[5], a[24]); // Sum(29) + res[30] = fma52hi(res[30], a[5], a[24]); // Sum(29) + res[30] = fma52lo(res[30], a[6], a[24]); // Sum(30) + res[31] = fma52hi(res[31], a[6], a[24]); // Sum(30) + res[31] = fma52lo(res[31], a[7], a[24]); // Sum(31) + res[32] = fma52hi(res[32], a[7], a[24]); // Sum(31) + res[32] = fma52lo(res[32], a[8], a[24]); // Sum(32) + res[33] = fma52hi(res[33], a[8], a[24]); // Sum(32) + res[33] = fma52lo(res[33], a[9], a[24]); // Sum(33) + res[34] = fma52hi(res[34], a[9], a[24]); // Sum(33) + res[34] = fma52lo(res[34], a[10], a[24]); // Sum(34) + res[35] = fma52hi(res[35], a[10], a[24]); // Sum(34) + res[35] = fma52lo(res[35], a[11], a[24]); // Sum(35) + res[36] = fma52hi(res[36], a[11], a[24]); // Sum(35) + res[25] = fma52lo(res[25], a[0], a[25]); // Sum(25) + res[26] = fma52hi(res[26], a[0], a[25]); // Sum(25) + res[26] = fma52lo(res[26], a[1], a[25]); // Sum(26) + res[27] = fma52hi(res[27], a[1], a[25]); // Sum(26) + res[27] = fma52lo(res[27], a[2], a[25]); // Sum(27) + res[28] = fma52hi(res[28], a[2], a[25]); // Sum(27) + res[28] = fma52lo(res[28], a[3], a[25]); // Sum(28) + res[29] = fma52hi(res[29], a[3], a[25]); // Sum(28) + res[29] = fma52lo(res[29], a[4], a[25]); // Sum(29) + res[30] = fma52hi(res[30], a[4], a[25]); // Sum(29) + res[30] = fma52lo(res[30], a[5], a[25]); // Sum(30) + res[31] = fma52hi(res[31], a[5], a[25]); // Sum(30) + res[31] = fma52lo(res[31], a[6], a[25]); // Sum(31) + res[32] = fma52hi(res[32], a[6], a[25]); // Sum(31) + res[32] = fma52lo(res[32], a[7], a[25]); // Sum(32) + res[33] = fma52hi(res[33], a[7], a[25]); // Sum(32) + res[33] = fma52lo(res[33], a[8], a[25]); // Sum(33) + res[34] = fma52hi(res[34], a[8], a[25]); // Sum(33) + res[34] = fma52lo(res[34], a[9], a[25]); // Sum(34) + res[35] = fma52hi(res[35], a[9], a[25]); // Sum(34) + res[35] = fma52lo(res[35], a[10], a[25]); // Sum(35) + res[36] = fma52hi(res[36], a[10], a[25]); // Sum(35) + res[26] = fma52lo(res[26], a[0], a[26]); // Sum(26) + res[27] = fma52hi(res[27], a[0], a[26]); // Sum(26) + res[27] = fma52lo(res[27], a[1], a[26]); // Sum(27) + res[28] = fma52hi(res[28], a[1], a[26]); // Sum(27) + res[28] = fma52lo(res[28], a[2], a[26]); // Sum(28) + res[29] = fma52hi(res[29], a[2], a[26]); // Sum(28) + res[29] = fma52lo(res[29], a[3], a[26]); // Sum(29) + res[30] = fma52hi(res[30], a[3], a[26]); // Sum(29) + res[30] = fma52lo(res[30], a[4], a[26]); // Sum(30) + res[31] = fma52hi(res[31], a[4], a[26]); // Sum(30) + res[31] = fma52lo(res[31], a[5], a[26]); // Sum(31) + res[32] = fma52hi(res[32], a[5], a[26]); // Sum(31) + res[32] = fma52lo(res[32], a[6], a[26]); // Sum(32) + res[33] = fma52hi(res[33], a[6], a[26]); // Sum(32) + res[33] = fma52lo(res[33], a[7], a[26]); // Sum(33) + res[34] = fma52hi(res[34], a[7], a[26]); // Sum(33) + res[34] = fma52lo(res[34], a[8], a[26]); // Sum(34) + res[35] = fma52hi(res[35], a[8], a[26]); // Sum(34) + res[35] = fma52lo(res[35], a[9], a[26]); // Sum(35) + res[36] = fma52hi(res[36], a[9], a[26]); // Sum(35) + res[27] = fma52lo(res[27], a[0], a[27]); // Sum(27) + res[28] = fma52hi(res[28], a[0], a[27]); // Sum(27) + res[28] = fma52lo(res[28], a[1], a[27]); // Sum(28) + res[29] = fma52hi(res[29], a[1], a[27]); // Sum(28) + res[29] = fma52lo(res[29], a[2], a[27]); // Sum(29) + res[30] = fma52hi(res[30], a[2], a[27]); // Sum(29) + res[30] = fma52lo(res[30], a[3], a[27]); // Sum(30) + res[31] = fma52hi(res[31], a[3], a[27]); // Sum(30) + res[31] = fma52lo(res[31], a[4], a[27]); // Sum(31) + res[32] = fma52hi(res[32], a[4], a[27]); // Sum(31) + res[32] = fma52lo(res[32], a[5], a[27]); // Sum(32) + res[33] = fma52hi(res[33], a[5], a[27]); // Sum(32) + res[33] = fma52lo(res[33], a[6], a[27]); // Sum(33) + res[34] = fma52hi(res[34], a[6], a[27]); // Sum(33) + res[34] = fma52lo(res[34], a[7], a[27]); // Sum(34) + res[35] = fma52hi(res[35], a[7], a[27]); // Sum(34) + res[35] = fma52lo(res[35], a[8], a[27]); // Sum(35) + res[36] = fma52hi(res[36], a[8], a[27]); // Sum(35) + res[28] = fma52lo(res[28], a[0], a[28]); // Sum(28) + res[29] = fma52hi(res[29], a[0], a[28]); // Sum(28) + res[29] = fma52lo(res[29], a[1], a[28]); // Sum(29) + res[30] = fma52hi(res[30], a[1], a[28]); // Sum(29) + res[30] = fma52lo(res[30], a[2], a[28]); // Sum(30) + res[31] = fma52hi(res[31], a[2], a[28]); // Sum(30) + res[31] = fma52lo(res[31], a[3], a[28]); // Sum(31) + res[32] = fma52hi(res[32], a[3], a[28]); // Sum(31) + res[32] = fma52lo(res[32], a[4], a[28]); // Sum(32) + res[33] = fma52hi(res[33], a[4], a[28]); // Sum(32) + res[33] = fma52lo(res[33], a[5], a[28]); // Sum(33) + res[34] = fma52hi(res[34], a[5], a[28]); // Sum(33) + res[34] = fma52lo(res[34], a[6], a[28]); // Sum(34) + res[35] = fma52hi(res[35], a[6], a[28]); // Sum(34) + res[35] = fma52lo(res[35], a[7], a[28]); // Sum(35) + res[36] = fma52hi(res[36], a[7], a[28]); // Sum(35) + res[29] = fma52lo(res[29], a[0], a[29]); // Sum(29) + res[30] = fma52hi(res[30], a[0], a[29]); // Sum(29) + res[30] = fma52lo(res[30], a[1], a[29]); // Sum(30) + res[31] = fma52hi(res[31], a[1], a[29]); // Sum(30) + res[31] = fma52lo(res[31], a[2], a[29]); // Sum(31) + res[32] = fma52hi(res[32], a[2], a[29]); // Sum(31) + res[32] = fma52lo(res[32], a[3], a[29]); // Sum(32) + res[33] = fma52hi(res[33], a[3], a[29]); // Sum(32) + res[33] = fma52lo(res[33], a[4], a[29]); // Sum(33) + res[34] = fma52hi(res[34], a[4], a[29]); // Sum(33) + res[34] = fma52lo(res[34], a[5], a[29]); // Sum(34) + res[35] = fma52hi(res[35], a[5], a[29]); // Sum(34) + res[35] = fma52lo(res[35], a[6], a[29]); // Sum(35) + res[36] = fma52hi(res[36], a[6], a[29]); // Sum(35) + res[30] = fma52lo(res[30], a[0], a[30]); // Sum(30) + res[31] = fma52hi(res[31], a[0], a[30]); // Sum(30) + res[31] = fma52lo(res[31], a[1], a[30]); // Sum(31) + res[32] = fma52hi(res[32], a[1], a[30]); // Sum(31) + res[32] = fma52lo(res[32], a[2], a[30]); // Sum(32) + res[33] = fma52hi(res[33], a[2], a[30]); // Sum(32) + res[33] = fma52lo(res[33], a[3], a[30]); // Sum(33) + res[34] = fma52hi(res[34], a[3], a[30]); // Sum(33) + res[34] = fma52lo(res[34], a[4], a[30]); // Sum(34) + res[35] = fma52hi(res[35], a[4], a[30]); // Sum(34) + res[35] = fma52lo(res[35], a[5], a[30]); // Sum(35) + res[36] = fma52hi(res[36], a[5], a[30]); // Sum(35) + res[31] = fma52lo(res[31], a[0], a[31]); // Sum(31) + res[32] = fma52hi(res[32], a[0], a[31]); // Sum(31) + res[32] = fma52lo(res[32], a[1], a[31]); // Sum(32) + res[33] = fma52hi(res[33], a[1], a[31]); // Sum(32) + res[33] = fma52lo(res[33], a[2], a[31]); // Sum(33) + res[34] = fma52hi(res[34], a[2], a[31]); // Sum(33) + res[34] = fma52lo(res[34], a[3], a[31]); // Sum(34) + res[35] = fma52hi(res[35], a[3], a[31]); // Sum(34) + res[35] = fma52lo(res[35], a[4], a[31]); // Sum(35) + res[36] = fma52hi(res[36], a[4], a[31]); // Sum(35) + res[32] = fma52lo(res[32], a[0], a[32]); // Sum(32) + res[33] = fma52hi(res[33], a[0], a[32]); // Sum(32) + res[33] = fma52lo(res[33], a[1], a[32]); // Sum(33) + res[34] = fma52hi(res[34], a[1], a[32]); // Sum(33) + res[34] = fma52lo(res[34], a[2], a[32]); // Sum(34) + res[35] = fma52hi(res[35], a[2], a[32]); // Sum(34) + res[35] = fma52lo(res[35], a[3], a[32]); // Sum(35) + res[36] = fma52hi(res[36], a[3], a[32]); // Sum(35) + res[33] = fma52lo(res[33], a[0], a[33]); // Sum(33) + res[34] = fma52hi(res[34], a[0], a[33]); // Sum(33) + res[34] = fma52lo(res[34], a[1], a[33]); // Sum(34) + res[35] = fma52hi(res[35], a[1], a[33]); // Sum(34) + res[35] = fma52lo(res[35], a[2], a[33]); // Sum(35) + res[36] = fma52hi(res[36], a[2], a[33]); // Sum(35) + res[34] = fma52lo(res[34], a[0], a[34]); // Sum(34) + res[35] = fma52hi(res[35], a[0], a[34]); // Sum(34) + res[35] = fma52lo(res[35], a[1], a[34]); // Sum(35) + res[36] = fma52hi(res[36], a[1], a[34]); // Sum(35) + res[35] = fma52lo(res[35], a[0], a[35]); // Sum(35) + res[36] = fma52hi(res[36], a[0], a[35]); // Sum(35) + res[24] = add64(res[24], res[24]); // Double(24) + res[25] = add64(res[25], res[25]); // Double(25) + res[26] = add64(res[26], res[26]); // Double(26) + res[27] = add64(res[27], res[27]); // Double(27) + res[28] = add64(res[28], res[28]); // Double(28) + res[29] = add64(res[29], res[29]); // Double(29) + res[30] = add64(res[30], res[30]); // Double(30) + res[31] = add64(res[31], res[31]); // Double(31) + res[32] = add64(res[32], res[32]); // Double(32) + res[33] = add64(res[33], res[33]); // Double(33) + res[34] = add64(res[34], res[34]); // Double(34) + res[35] = add64(res[35], res[35]); // Double(35) + res[24] = fma52lo(res[24], a[12], a[12]); // Add sqr(24) + res[25] = fma52hi(res[25], a[12], a[12]); // Add sqr(24) + res[26] = fma52lo(res[26], a[13], a[13]); // Add sqr(26) + res[27] = fma52hi(res[27], a[13], a[13]); // Add sqr(26) + res[28] = fma52lo(res[28], a[14], a[14]); // Add sqr(28) + res[29] = fma52hi(res[29], a[14], a[14]); // Add sqr(28) + res[30] = fma52lo(res[30], a[15], a[15]); // Add sqr(30) + res[31] = fma52hi(res[31], a[15], a[15]); // Add sqr(30) + res[32] = fma52lo(res[32], a[16], a[16]); // Add sqr(32) + res[33] = fma52hi(res[33], a[16], a[16]); // Add sqr(32) + res[34] = fma52lo(res[34], a[17], a[17]); // Add sqr(34) + res[35] = fma52hi(res[35], a[17], a[17]); // Add sqr(34) + res[36] = fma52lo(res[36], a[17], a[19]); // Sum(36) + res[37] = fma52hi(res[37], a[17], a[19]); // Sum(36) + res[37] = fma52lo(res[37], a[18], a[19]); // Sum(37) + res[38] = fma52hi(res[38], a[18], a[19]); // Sum(37) + res[36] = fma52lo(res[36], a[16], a[20]); // Sum(36) + res[37] = fma52hi(res[37], a[16], a[20]); // Sum(36) + res[37] = fma52lo(res[37], a[17], a[20]); // Sum(37) + res[38] = fma52hi(res[38], a[17], a[20]); // Sum(37) + res[38] = fma52lo(res[38], a[18], a[20]); // Sum(38) + res[39] = fma52hi(res[39], a[18], a[20]); // Sum(38) + res[39] = fma52lo(res[39], a[19], a[20]); // Sum(39) + res[40] = fma52hi(res[40], a[19], a[20]); // Sum(39) + res[36] = fma52lo(res[36], a[15], a[21]); // Sum(36) + res[37] = fma52hi(res[37], a[15], a[21]); // Sum(36) + res[37] = fma52lo(res[37], a[16], a[21]); // Sum(37) + res[38] = fma52hi(res[38], a[16], a[21]); // Sum(37) + res[38] = fma52lo(res[38], a[17], a[21]); // Sum(38) + res[39] = fma52hi(res[39], a[17], a[21]); // Sum(38) + res[39] = fma52lo(res[39], a[18], a[21]); // Sum(39) + res[40] = fma52hi(res[40], a[18], a[21]); // Sum(39) + res[40] = fma52lo(res[40], a[19], a[21]); // Sum(40) + res[41] = fma52hi(res[41], a[19], a[21]); // Sum(40) + res[41] = fma52lo(res[41], a[20], a[21]); // Sum(41) + res[42] = fma52hi(res[42], a[20], a[21]); // Sum(41) + res[36] = fma52lo(res[36], a[14], a[22]); // Sum(36) + res[37] = fma52hi(res[37], a[14], a[22]); // Sum(36) + res[37] = fma52lo(res[37], a[15], a[22]); // Sum(37) + res[38] = fma52hi(res[38], a[15], a[22]); // Sum(37) + res[38] = fma52lo(res[38], a[16], a[22]); // Sum(38) + res[39] = fma52hi(res[39], a[16], a[22]); // Sum(38) + res[39] = fma52lo(res[39], a[17], a[22]); // Sum(39) + res[40] = fma52hi(res[40], a[17], a[22]); // Sum(39) + res[40] = fma52lo(res[40], a[18], a[22]); // Sum(40) + res[41] = fma52hi(res[41], a[18], a[22]); // Sum(40) + res[41] = fma52lo(res[41], a[19], a[22]); // Sum(41) + res[42] = fma52hi(res[42], a[19], a[22]); // Sum(41) + res[42] = fma52lo(res[42], a[20], a[22]); // Sum(42) + res[43] = fma52hi(res[43], a[20], a[22]); // Sum(42) + res[43] = fma52lo(res[43], a[21], a[22]); // Sum(43) + res[44] = fma52hi(res[44], a[21], a[22]); // Sum(43) + res[36] = fma52lo(res[36], a[13], a[23]); // Sum(36) + res[37] = fma52hi(res[37], a[13], a[23]); // Sum(36) + res[37] = fma52lo(res[37], a[14], a[23]); // Sum(37) + res[38] = fma52hi(res[38], a[14], a[23]); // Sum(37) + res[38] = fma52lo(res[38], a[15], a[23]); // Sum(38) + res[39] = fma52hi(res[39], a[15], a[23]); // Sum(38) + res[39] = fma52lo(res[39], a[16], a[23]); // Sum(39) + res[40] = fma52hi(res[40], a[16], a[23]); // Sum(39) + res[40] = fma52lo(res[40], a[17], a[23]); // Sum(40) + res[41] = fma52hi(res[41], a[17], a[23]); // Sum(40) + res[41] = fma52lo(res[41], a[18], a[23]); // Sum(41) + res[42] = fma52hi(res[42], a[18], a[23]); // Sum(41) + res[42] = fma52lo(res[42], a[19], a[23]); // Sum(42) + res[43] = fma52hi(res[43], a[19], a[23]); // Sum(42) + res[43] = fma52lo(res[43], a[20], a[23]); // Sum(43) + res[44] = fma52hi(res[44], a[20], a[23]); // Sum(43) + res[44] = fma52lo(res[44], a[21], a[23]); // Sum(44) + res[45] = fma52hi(res[45], a[21], a[23]); // Sum(44) + res[45] = fma52lo(res[45], a[22], a[23]); // Sum(45) + res[46] = fma52hi(res[46], a[22], a[23]); // Sum(45) + res[36] = fma52lo(res[36], a[12], a[24]); // Sum(36) + res[37] = fma52hi(res[37], a[12], a[24]); // Sum(36) + res[37] = fma52lo(res[37], a[13], a[24]); // Sum(37) + res[38] = fma52hi(res[38], a[13], a[24]); // Sum(37) + res[38] = fma52lo(res[38], a[14], a[24]); // Sum(38) + res[39] = fma52hi(res[39], a[14], a[24]); // Sum(38) + res[39] = fma52lo(res[39], a[15], a[24]); // Sum(39) + res[40] = fma52hi(res[40], a[15], a[24]); // Sum(39) + res[40] = fma52lo(res[40], a[16], a[24]); // Sum(40) + res[41] = fma52hi(res[41], a[16], a[24]); // Sum(40) + res[41] = fma52lo(res[41], a[17], a[24]); // Sum(41) + res[42] = fma52hi(res[42], a[17], a[24]); // Sum(41) + res[42] = fma52lo(res[42], a[18], a[24]); // Sum(42) + res[43] = fma52hi(res[43], a[18], a[24]); // Sum(42) + res[43] = fma52lo(res[43], a[19], a[24]); // Sum(43) + res[44] = fma52hi(res[44], a[19], a[24]); // Sum(43) + res[44] = fma52lo(res[44], a[20], a[24]); // Sum(44) + res[45] = fma52hi(res[45], a[20], a[24]); // Sum(44) + res[45] = fma52lo(res[45], a[21], a[24]); // Sum(45) + res[46] = fma52hi(res[46], a[21], a[24]); // Sum(45) + res[46] = fma52lo(res[46], a[22], a[24]); // Sum(46) + res[47] = fma52hi(res[47], a[22], a[24]); // Sum(46) + res[47] = fma52lo(res[47], a[23], a[24]); // Sum(47) + res[48] = fma52hi(res[48], a[23], a[24]); // Sum(47) + res[36] = fma52lo(res[36], a[11], a[25]); // Sum(36) + res[37] = fma52hi(res[37], a[11], a[25]); // Sum(36) + res[37] = fma52lo(res[37], a[12], a[25]); // Sum(37) + res[38] = fma52hi(res[38], a[12], a[25]); // Sum(37) + res[38] = fma52lo(res[38], a[13], a[25]); // Sum(38) + res[39] = fma52hi(res[39], a[13], a[25]); // Sum(38) + res[39] = fma52lo(res[39], a[14], a[25]); // Sum(39) + res[40] = fma52hi(res[40], a[14], a[25]); // Sum(39) + res[40] = fma52lo(res[40], a[15], a[25]); // Sum(40) + res[41] = fma52hi(res[41], a[15], a[25]); // Sum(40) + res[41] = fma52lo(res[41], a[16], a[25]); // Sum(41) + res[42] = fma52hi(res[42], a[16], a[25]); // Sum(41) + res[42] = fma52lo(res[42], a[17], a[25]); // Sum(42) + res[43] = fma52hi(res[43], a[17], a[25]); // Sum(42) + res[43] = fma52lo(res[43], a[18], a[25]); // Sum(43) + res[44] = fma52hi(res[44], a[18], a[25]); // Sum(43) + res[44] = fma52lo(res[44], a[19], a[25]); // Sum(44) + res[45] = fma52hi(res[45], a[19], a[25]); // Sum(44) + res[45] = fma52lo(res[45], a[20], a[25]); // Sum(45) + res[46] = fma52hi(res[46], a[20], a[25]); // Sum(45) + res[46] = fma52lo(res[46], a[21], a[25]); // Sum(46) + res[47] = fma52hi(res[47], a[21], a[25]); // Sum(46) + res[47] = fma52lo(res[47], a[22], a[25]); // Sum(47) + res[48] = fma52hi(res[48], a[22], a[25]); // Sum(47) + res[36] = fma52lo(res[36], a[10], a[26]); // Sum(36) + res[37] = fma52hi(res[37], a[10], a[26]); // Sum(36) + res[37] = fma52lo(res[37], a[11], a[26]); // Sum(37) + res[38] = fma52hi(res[38], a[11], a[26]); // Sum(37) + res[38] = fma52lo(res[38], a[12], a[26]); // Sum(38) + res[39] = fma52hi(res[39], a[12], a[26]); // Sum(38) + res[39] = fma52lo(res[39], a[13], a[26]); // Sum(39) + res[40] = fma52hi(res[40], a[13], a[26]); // Sum(39) + res[40] = fma52lo(res[40], a[14], a[26]); // Sum(40) + res[41] = fma52hi(res[41], a[14], a[26]); // Sum(40) + res[41] = fma52lo(res[41], a[15], a[26]); // Sum(41) + res[42] = fma52hi(res[42], a[15], a[26]); // Sum(41) + res[42] = fma52lo(res[42], a[16], a[26]); // Sum(42) + res[43] = fma52hi(res[43], a[16], a[26]); // Sum(42) + res[43] = fma52lo(res[43], a[17], a[26]); // Sum(43) + res[44] = fma52hi(res[44], a[17], a[26]); // Sum(43) + res[44] = fma52lo(res[44], a[18], a[26]); // Sum(44) + res[45] = fma52hi(res[45], a[18], a[26]); // Sum(44) + res[45] = fma52lo(res[45], a[19], a[26]); // Sum(45) + res[46] = fma52hi(res[46], a[19], a[26]); // Sum(45) + res[46] = fma52lo(res[46], a[20], a[26]); // Sum(46) + res[47] = fma52hi(res[47], a[20], a[26]); // Sum(46) + res[47] = fma52lo(res[47], a[21], a[26]); // Sum(47) + res[48] = fma52hi(res[48], a[21], a[26]); // Sum(47) + res[36] = fma52lo(res[36], a[9], a[27]); // Sum(36) + res[37] = fma52hi(res[37], a[9], a[27]); // Sum(36) + res[37] = fma52lo(res[37], a[10], a[27]); // Sum(37) + res[38] = fma52hi(res[38], a[10], a[27]); // Sum(37) + res[38] = fma52lo(res[38], a[11], a[27]); // Sum(38) + res[39] = fma52hi(res[39], a[11], a[27]); // Sum(38) + res[39] = fma52lo(res[39], a[12], a[27]); // Sum(39) + res[40] = fma52hi(res[40], a[12], a[27]); // Sum(39) + res[40] = fma52lo(res[40], a[13], a[27]); // Sum(40) + res[41] = fma52hi(res[41], a[13], a[27]); // Sum(40) + res[41] = fma52lo(res[41], a[14], a[27]); // Sum(41) + res[42] = fma52hi(res[42], a[14], a[27]); // Sum(41) + res[42] = fma52lo(res[42], a[15], a[27]); // Sum(42) + res[43] = fma52hi(res[43], a[15], a[27]); // Sum(42) + res[43] = fma52lo(res[43], a[16], a[27]); // Sum(43) + res[44] = fma52hi(res[44], a[16], a[27]); // Sum(43) + res[44] = fma52lo(res[44], a[17], a[27]); // Sum(44) + res[45] = fma52hi(res[45], a[17], a[27]); // Sum(44) + res[45] = fma52lo(res[45], a[18], a[27]); // Sum(45) + res[46] = fma52hi(res[46], a[18], a[27]); // Sum(45) + res[46] = fma52lo(res[46], a[19], a[27]); // Sum(46) + res[47] = fma52hi(res[47], a[19], a[27]); // Sum(46) + res[47] = fma52lo(res[47], a[20], a[27]); // Sum(47) + res[48] = fma52hi(res[48], a[20], a[27]); // Sum(47) + res[36] = fma52lo(res[36], a[8], a[28]); // Sum(36) + res[37] = fma52hi(res[37], a[8], a[28]); // Sum(36) + res[37] = fma52lo(res[37], a[9], a[28]); // Sum(37) + res[38] = fma52hi(res[38], a[9], a[28]); // Sum(37) + res[38] = fma52lo(res[38], a[10], a[28]); // Sum(38) + res[39] = fma52hi(res[39], a[10], a[28]); // Sum(38) + res[39] = fma52lo(res[39], a[11], a[28]); // Sum(39) + res[40] = fma52hi(res[40], a[11], a[28]); // Sum(39) + res[40] = fma52lo(res[40], a[12], a[28]); // Sum(40) + res[41] = fma52hi(res[41], a[12], a[28]); // Sum(40) + res[41] = fma52lo(res[41], a[13], a[28]); // Sum(41) + res[42] = fma52hi(res[42], a[13], a[28]); // Sum(41) + res[42] = fma52lo(res[42], a[14], a[28]); // Sum(42) + res[43] = fma52hi(res[43], a[14], a[28]); // Sum(42) + res[43] = fma52lo(res[43], a[15], a[28]); // Sum(43) + res[44] = fma52hi(res[44], a[15], a[28]); // Sum(43) + res[44] = fma52lo(res[44], a[16], a[28]); // Sum(44) + res[45] = fma52hi(res[45], a[16], a[28]); // Sum(44) + res[45] = fma52lo(res[45], a[17], a[28]); // Sum(45) + res[46] = fma52hi(res[46], a[17], a[28]); // Sum(45) + res[46] = fma52lo(res[46], a[18], a[28]); // Sum(46) + res[47] = fma52hi(res[47], a[18], a[28]); // Sum(46) + res[47] = fma52lo(res[47], a[19], a[28]); // Sum(47) + res[48] = fma52hi(res[48], a[19], a[28]); // Sum(47) + res[36] = fma52lo(res[36], a[7], a[29]); // Sum(36) + res[37] = fma52hi(res[37], a[7], a[29]); // Sum(36) + res[37] = fma52lo(res[37], a[8], a[29]); // Sum(37) + res[38] = fma52hi(res[38], a[8], a[29]); // Sum(37) + res[38] = fma52lo(res[38], a[9], a[29]); // Sum(38) + res[39] = fma52hi(res[39], a[9], a[29]); // Sum(38) + res[39] = fma52lo(res[39], a[10], a[29]); // Sum(39) + res[40] = fma52hi(res[40], a[10], a[29]); // Sum(39) + res[40] = fma52lo(res[40], a[11], a[29]); // Sum(40) + res[41] = fma52hi(res[41], a[11], a[29]); // Sum(40) + res[41] = fma52lo(res[41], a[12], a[29]); // Sum(41) + res[42] = fma52hi(res[42], a[12], a[29]); // Sum(41) + res[42] = fma52lo(res[42], a[13], a[29]); // Sum(42) + res[43] = fma52hi(res[43], a[13], a[29]); // Sum(42) + res[43] = fma52lo(res[43], a[14], a[29]); // Sum(43) + res[44] = fma52hi(res[44], a[14], a[29]); // Sum(43) + res[44] = fma52lo(res[44], a[15], a[29]); // Sum(44) + res[45] = fma52hi(res[45], a[15], a[29]); // Sum(44) + res[45] = fma52lo(res[45], a[16], a[29]); // Sum(45) + res[46] = fma52hi(res[46], a[16], a[29]); // Sum(45) + res[46] = fma52lo(res[46], a[17], a[29]); // Sum(46) + res[47] = fma52hi(res[47], a[17], a[29]); // Sum(46) + res[47] = fma52lo(res[47], a[18], a[29]); // Sum(47) + res[48] = fma52hi(res[48], a[18], a[29]); // Sum(47) + res[36] = fma52lo(res[36], a[6], a[30]); // Sum(36) + res[37] = fma52hi(res[37], a[6], a[30]); // Sum(36) + res[37] = fma52lo(res[37], a[7], a[30]); // Sum(37) + res[38] = fma52hi(res[38], a[7], a[30]); // Sum(37) + res[38] = fma52lo(res[38], a[8], a[30]); // Sum(38) + res[39] = fma52hi(res[39], a[8], a[30]); // Sum(38) + res[39] = fma52lo(res[39], a[9], a[30]); // Sum(39) + res[40] = fma52hi(res[40], a[9], a[30]); // Sum(39) + res[40] = fma52lo(res[40], a[10], a[30]); // Sum(40) + res[41] = fma52hi(res[41], a[10], a[30]); // Sum(40) + res[41] = fma52lo(res[41], a[11], a[30]); // Sum(41) + res[42] = fma52hi(res[42], a[11], a[30]); // Sum(41) + res[42] = fma52lo(res[42], a[12], a[30]); // Sum(42) + res[43] = fma52hi(res[43], a[12], a[30]); // Sum(42) + res[43] = fma52lo(res[43], a[13], a[30]); // Sum(43) + res[44] = fma52hi(res[44], a[13], a[30]); // Sum(43) + res[44] = fma52lo(res[44], a[14], a[30]); // Sum(44) + res[45] = fma52hi(res[45], a[14], a[30]); // Sum(44) + res[45] = fma52lo(res[45], a[15], a[30]); // Sum(45) + res[46] = fma52hi(res[46], a[15], a[30]); // Sum(45) + res[46] = fma52lo(res[46], a[16], a[30]); // Sum(46) + res[47] = fma52hi(res[47], a[16], a[30]); // Sum(46) + res[47] = fma52lo(res[47], a[17], a[30]); // Sum(47) + res[48] = fma52hi(res[48], a[17], a[30]); // Sum(47) + res[36] = fma52lo(res[36], a[5], a[31]); // Sum(36) + res[37] = fma52hi(res[37], a[5], a[31]); // Sum(36) + res[37] = fma52lo(res[37], a[6], a[31]); // Sum(37) + res[38] = fma52hi(res[38], a[6], a[31]); // Sum(37) + res[38] = fma52lo(res[38], a[7], a[31]); // Sum(38) + res[39] = fma52hi(res[39], a[7], a[31]); // Sum(38) + res[39] = fma52lo(res[39], a[8], a[31]); // Sum(39) + res[40] = fma52hi(res[40], a[8], a[31]); // Sum(39) + res[40] = fma52lo(res[40], a[9], a[31]); // Sum(40) + res[41] = fma52hi(res[41], a[9], a[31]); // Sum(40) + res[41] = fma52lo(res[41], a[10], a[31]); // Sum(41) + res[42] = fma52hi(res[42], a[10], a[31]); // Sum(41) + res[42] = fma52lo(res[42], a[11], a[31]); // Sum(42) + res[43] = fma52hi(res[43], a[11], a[31]); // Sum(42) + res[43] = fma52lo(res[43], a[12], a[31]); // Sum(43) + res[44] = fma52hi(res[44], a[12], a[31]); // Sum(43) + res[44] = fma52lo(res[44], a[13], a[31]); // Sum(44) + res[45] = fma52hi(res[45], a[13], a[31]); // Sum(44) + res[45] = fma52lo(res[45], a[14], a[31]); // Sum(45) + res[46] = fma52hi(res[46], a[14], a[31]); // Sum(45) + res[46] = fma52lo(res[46], a[15], a[31]); // Sum(46) + res[47] = fma52hi(res[47], a[15], a[31]); // Sum(46) + res[47] = fma52lo(res[47], a[16], a[31]); // Sum(47) + res[48] = fma52hi(res[48], a[16], a[31]); // Sum(47) + res[36] = fma52lo(res[36], a[4], a[32]); // Sum(36) + res[37] = fma52hi(res[37], a[4], a[32]); // Sum(36) + res[37] = fma52lo(res[37], a[5], a[32]); // Sum(37) + res[38] = fma52hi(res[38], a[5], a[32]); // Sum(37) + res[38] = fma52lo(res[38], a[6], a[32]); // Sum(38) + res[39] = fma52hi(res[39], a[6], a[32]); // Sum(38) + res[39] = fma52lo(res[39], a[7], a[32]); // Sum(39) + res[40] = fma52hi(res[40], a[7], a[32]); // Sum(39) + res[40] = fma52lo(res[40], a[8], a[32]); // Sum(40) + res[41] = fma52hi(res[41], a[8], a[32]); // Sum(40) + res[41] = fma52lo(res[41], a[9], a[32]); // Sum(41) + res[42] = fma52hi(res[42], a[9], a[32]); // Sum(41) + res[42] = fma52lo(res[42], a[10], a[32]); // Sum(42) + res[43] = fma52hi(res[43], a[10], a[32]); // Sum(42) + res[43] = fma52lo(res[43], a[11], a[32]); // Sum(43) + res[44] = fma52hi(res[44], a[11], a[32]); // Sum(43) + res[44] = fma52lo(res[44], a[12], a[32]); // Sum(44) + res[45] = fma52hi(res[45], a[12], a[32]); // Sum(44) + res[45] = fma52lo(res[45], a[13], a[32]); // Sum(45) + res[46] = fma52hi(res[46], a[13], a[32]); // Sum(45) + res[46] = fma52lo(res[46], a[14], a[32]); // Sum(46) + res[47] = fma52hi(res[47], a[14], a[32]); // Sum(46) + res[47] = fma52lo(res[47], a[15], a[32]); // Sum(47) + res[48] = fma52hi(res[48], a[15], a[32]); // Sum(47) + res[36] = fma52lo(res[36], a[3], a[33]); // Sum(36) + res[37] = fma52hi(res[37], a[3], a[33]); // Sum(36) + res[37] = fma52lo(res[37], a[4], a[33]); // Sum(37) + res[38] = fma52hi(res[38], a[4], a[33]); // Sum(37) + res[38] = fma52lo(res[38], a[5], a[33]); // Sum(38) + res[39] = fma52hi(res[39], a[5], a[33]); // Sum(38) + res[39] = fma52lo(res[39], a[6], a[33]); // Sum(39) + res[40] = fma52hi(res[40], a[6], a[33]); // Sum(39) + res[40] = fma52lo(res[40], a[7], a[33]); // Sum(40) + res[41] = fma52hi(res[41], a[7], a[33]); // Sum(40) + res[41] = fma52lo(res[41], a[8], a[33]); // Sum(41) + res[42] = fma52hi(res[42], a[8], a[33]); // Sum(41) + res[42] = fma52lo(res[42], a[9], a[33]); // Sum(42) + res[43] = fma52hi(res[43], a[9], a[33]); // Sum(42) + res[43] = fma52lo(res[43], a[10], a[33]); // Sum(43) + res[44] = fma52hi(res[44], a[10], a[33]); // Sum(43) + res[44] = fma52lo(res[44], a[11], a[33]); // Sum(44) + res[45] = fma52hi(res[45], a[11], a[33]); // Sum(44) + res[45] = fma52lo(res[45], a[12], a[33]); // Sum(45) + res[46] = fma52hi(res[46], a[12], a[33]); // Sum(45) + res[46] = fma52lo(res[46], a[13], a[33]); // Sum(46) + res[47] = fma52hi(res[47], a[13], a[33]); // Sum(46) + res[47] = fma52lo(res[47], a[14], a[33]); // Sum(47) + res[48] = fma52hi(res[48], a[14], a[33]); // Sum(47) + res[36] = fma52lo(res[36], a[2], a[34]); // Sum(36) + res[37] = fma52hi(res[37], a[2], a[34]); // Sum(36) + res[37] = fma52lo(res[37], a[3], a[34]); // Sum(37) + res[38] = fma52hi(res[38], a[3], a[34]); // Sum(37) + res[38] = fma52lo(res[38], a[4], a[34]); // Sum(38) + res[39] = fma52hi(res[39], a[4], a[34]); // Sum(38) + res[39] = fma52lo(res[39], a[5], a[34]); // Sum(39) + res[40] = fma52hi(res[40], a[5], a[34]); // Sum(39) + res[40] = fma52lo(res[40], a[6], a[34]); // Sum(40) + res[41] = fma52hi(res[41], a[6], a[34]); // Sum(40) + res[41] = fma52lo(res[41], a[7], a[34]); // Sum(41) + res[42] = fma52hi(res[42], a[7], a[34]); // Sum(41) + res[42] = fma52lo(res[42], a[8], a[34]); // Sum(42) + res[43] = fma52hi(res[43], a[8], a[34]); // Sum(42) + res[43] = fma52lo(res[43], a[9], a[34]); // Sum(43) + res[44] = fma52hi(res[44], a[9], a[34]); // Sum(43) + res[44] = fma52lo(res[44], a[10], a[34]); // Sum(44) + res[45] = fma52hi(res[45], a[10], a[34]); // Sum(44) + res[45] = fma52lo(res[45], a[11], a[34]); // Sum(45) + res[46] = fma52hi(res[46], a[11], a[34]); // Sum(45) + res[46] = fma52lo(res[46], a[12], a[34]); // Sum(46) + res[47] = fma52hi(res[47], a[12], a[34]); // Sum(46) + res[47] = fma52lo(res[47], a[13], a[34]); // Sum(47) + res[48] = fma52hi(res[48], a[13], a[34]); // Sum(47) + res[36] = fma52lo(res[36], a[1], a[35]); // Sum(36) + res[37] = fma52hi(res[37], a[1], a[35]); // Sum(36) + res[37] = fma52lo(res[37], a[2], a[35]); // Sum(37) + res[38] = fma52hi(res[38], a[2], a[35]); // Sum(37) + res[38] = fma52lo(res[38], a[3], a[35]); // Sum(38) + res[39] = fma52hi(res[39], a[3], a[35]); // Sum(38) + res[39] = fma52lo(res[39], a[4], a[35]); // Sum(39) + res[40] = fma52hi(res[40], a[4], a[35]); // Sum(39) + res[40] = fma52lo(res[40], a[5], a[35]); // Sum(40) + res[41] = fma52hi(res[41], a[5], a[35]); // Sum(40) + res[41] = fma52lo(res[41], a[6], a[35]); // Sum(41) + res[42] = fma52hi(res[42], a[6], a[35]); // Sum(41) + res[42] = fma52lo(res[42], a[7], a[35]); // Sum(42) + res[43] = fma52hi(res[43], a[7], a[35]); // Sum(42) + res[43] = fma52lo(res[43], a[8], a[35]); // Sum(43) + res[44] = fma52hi(res[44], a[8], a[35]); // Sum(43) + res[44] = fma52lo(res[44], a[9], a[35]); // Sum(44) + res[45] = fma52hi(res[45], a[9], a[35]); // Sum(44) + res[45] = fma52lo(res[45], a[10], a[35]); // Sum(45) + res[46] = fma52hi(res[46], a[10], a[35]); // Sum(45) + res[46] = fma52lo(res[46], a[11], a[35]); // Sum(46) + res[47] = fma52hi(res[47], a[11], a[35]); // Sum(46) + res[47] = fma52lo(res[47], a[12], a[35]); // Sum(47) + res[48] = fma52hi(res[48], a[12], a[35]); // Sum(47) + res[36] = fma52lo(res[36], a[0], a[36]); // Sum(36) + res[37] = fma52hi(res[37], a[0], a[36]); // Sum(36) + res[37] = fma52lo(res[37], a[1], a[36]); // Sum(37) + res[38] = fma52hi(res[38], a[1], a[36]); // Sum(37) + res[38] = fma52lo(res[38], a[2], a[36]); // Sum(38) + res[39] = fma52hi(res[39], a[2], a[36]); // Sum(38) + res[39] = fma52lo(res[39], a[3], a[36]); // Sum(39) + res[40] = fma52hi(res[40], a[3], a[36]); // Sum(39) + res[40] = fma52lo(res[40], a[4], a[36]); // Sum(40) + res[41] = fma52hi(res[41], a[4], a[36]); // Sum(40) + res[41] = fma52lo(res[41], a[5], a[36]); // Sum(41) + res[42] = fma52hi(res[42], a[5], a[36]); // Sum(41) + res[42] = fma52lo(res[42], a[6], a[36]); // Sum(42) + res[43] = fma52hi(res[43], a[6], a[36]); // Sum(42) + res[43] = fma52lo(res[43], a[7], a[36]); // Sum(43) + res[44] = fma52hi(res[44], a[7], a[36]); // Sum(43) + res[44] = fma52lo(res[44], a[8], a[36]); // Sum(44) + res[45] = fma52hi(res[45], a[8], a[36]); // Sum(44) + res[45] = fma52lo(res[45], a[9], a[36]); // Sum(45) + res[46] = fma52hi(res[46], a[9], a[36]); // Sum(45) + res[46] = fma52lo(res[46], a[10], a[36]); // Sum(46) + res[47] = fma52hi(res[47], a[10], a[36]); // Sum(46) + res[47] = fma52lo(res[47], a[11], a[36]); // Sum(47) + res[48] = fma52hi(res[48], a[11], a[36]); // Sum(47) + res[37] = fma52lo(res[37], a[0], a[37]); // Sum(37) + res[38] = fma52hi(res[38], a[0], a[37]); // Sum(37) + res[38] = fma52lo(res[38], a[1], a[37]); // Sum(38) + res[39] = fma52hi(res[39], a[1], a[37]); // Sum(38) + res[39] = fma52lo(res[39], a[2], a[37]); // Sum(39) + res[40] = fma52hi(res[40], a[2], a[37]); // Sum(39) + res[40] = fma52lo(res[40], a[3], a[37]); // Sum(40) + res[41] = fma52hi(res[41], a[3], a[37]); // Sum(40) + res[41] = fma52lo(res[41], a[4], a[37]); // Sum(41) + res[42] = fma52hi(res[42], a[4], a[37]); // Sum(41) + res[42] = fma52lo(res[42], a[5], a[37]); // Sum(42) + res[43] = fma52hi(res[43], a[5], a[37]); // Sum(42) + res[43] = fma52lo(res[43], a[6], a[37]); // Sum(43) + res[44] = fma52hi(res[44], a[6], a[37]); // Sum(43) + res[44] = fma52lo(res[44], a[7], a[37]); // Sum(44) + res[45] = fma52hi(res[45], a[7], a[37]); // Sum(44) + res[45] = fma52lo(res[45], a[8], a[37]); // Sum(45) + res[46] = fma52hi(res[46], a[8], a[37]); // Sum(45) + res[46] = fma52lo(res[46], a[9], a[37]); // Sum(46) + res[47] = fma52hi(res[47], a[9], a[37]); // Sum(46) + res[47] = fma52lo(res[47], a[10], a[37]); // Sum(47) + res[48] = fma52hi(res[48], a[10], a[37]); // Sum(47) + res[38] = fma52lo(res[38], a[0], a[38]); // Sum(38) + res[39] = fma52hi(res[39], a[0], a[38]); // Sum(38) + res[39] = fma52lo(res[39], a[1], a[38]); // Sum(39) + res[40] = fma52hi(res[40], a[1], a[38]); // Sum(39) + res[40] = fma52lo(res[40], a[2], a[38]); // Sum(40) + res[41] = fma52hi(res[41], a[2], a[38]); // Sum(40) + res[41] = fma52lo(res[41], a[3], a[38]); // Sum(41) + res[42] = fma52hi(res[42], a[3], a[38]); // Sum(41) + res[42] = fma52lo(res[42], a[4], a[38]); // Sum(42) + res[43] = fma52hi(res[43], a[4], a[38]); // Sum(42) + res[43] = fma52lo(res[43], a[5], a[38]); // Sum(43) + res[44] = fma52hi(res[44], a[5], a[38]); // Sum(43) + res[44] = fma52lo(res[44], a[6], a[38]); // Sum(44) + res[45] = fma52hi(res[45], a[6], a[38]); // Sum(44) + res[45] = fma52lo(res[45], a[7], a[38]); // Sum(45) + res[46] = fma52hi(res[46], a[7], a[38]); // Sum(45) + res[46] = fma52lo(res[46], a[8], a[38]); // Sum(46) + res[47] = fma52hi(res[47], a[8], a[38]); // Sum(46) + res[47] = fma52lo(res[47], a[9], a[38]); // Sum(47) + res[48] = fma52hi(res[48], a[9], a[38]); // Sum(47) + res[39] = fma52lo(res[39], a[0], a[39]); // Sum(39) + res[40] = fma52hi(res[40], a[0], a[39]); // Sum(39) + res[40] = fma52lo(res[40], a[1], a[39]); // Sum(40) + res[41] = fma52hi(res[41], a[1], a[39]); // Sum(40) + res[41] = fma52lo(res[41], a[2], a[39]); // Sum(41) + res[42] = fma52hi(res[42], a[2], a[39]); // Sum(41) + res[42] = fma52lo(res[42], a[3], a[39]); // Sum(42) + res[43] = fma52hi(res[43], a[3], a[39]); // Sum(42) + res[43] = fma52lo(res[43], a[4], a[39]); // Sum(43) + res[44] = fma52hi(res[44], a[4], a[39]); // Sum(43) + res[44] = fma52lo(res[44], a[5], a[39]); // Sum(44) + res[45] = fma52hi(res[45], a[5], a[39]); // Sum(44) + res[45] = fma52lo(res[45], a[6], a[39]); // Sum(45) + res[46] = fma52hi(res[46], a[6], a[39]); // Sum(45) + res[46] = fma52lo(res[46], a[7], a[39]); // Sum(46) + res[47] = fma52hi(res[47], a[7], a[39]); // Sum(46) + res[47] = fma52lo(res[47], a[8], a[39]); // Sum(47) + res[48] = fma52hi(res[48], a[8], a[39]); // Sum(47) + res[40] = fma52lo(res[40], a[0], a[40]); // Sum(40) + res[41] = fma52hi(res[41], a[0], a[40]); // Sum(40) + res[41] = fma52lo(res[41], a[1], a[40]); // Sum(41) + res[42] = fma52hi(res[42], a[1], a[40]); // Sum(41) + res[42] = fma52lo(res[42], a[2], a[40]); // Sum(42) + res[43] = fma52hi(res[43], a[2], a[40]); // Sum(42) + res[43] = fma52lo(res[43], a[3], a[40]); // Sum(43) + res[44] = fma52hi(res[44], a[3], a[40]); // Sum(43) + res[44] = fma52lo(res[44], a[4], a[40]); // Sum(44) + res[45] = fma52hi(res[45], a[4], a[40]); // Sum(44) + res[45] = fma52lo(res[45], a[5], a[40]); // Sum(45) + res[46] = fma52hi(res[46], a[5], a[40]); // Sum(45) + res[46] = fma52lo(res[46], a[6], a[40]); // Sum(46) + res[47] = fma52hi(res[47], a[6], a[40]); // Sum(46) + res[47] = fma52lo(res[47], a[7], a[40]); // Sum(47) + res[48] = fma52hi(res[48], a[7], a[40]); // Sum(47) + res[41] = fma52lo(res[41], a[0], a[41]); // Sum(41) + res[42] = fma52hi(res[42], a[0], a[41]); // Sum(41) + res[42] = fma52lo(res[42], a[1], a[41]); // Sum(42) + res[43] = fma52hi(res[43], a[1], a[41]); // Sum(42) + res[43] = fma52lo(res[43], a[2], a[41]); // Sum(43) + res[44] = fma52hi(res[44], a[2], a[41]); // Sum(43) + res[44] = fma52lo(res[44], a[3], a[41]); // Sum(44) + res[45] = fma52hi(res[45], a[3], a[41]); // Sum(44) + res[45] = fma52lo(res[45], a[4], a[41]); // Sum(45) + res[46] = fma52hi(res[46], a[4], a[41]); // Sum(45) + res[46] = fma52lo(res[46], a[5], a[41]); // Sum(46) + res[47] = fma52hi(res[47], a[5], a[41]); // Sum(46) + res[47] = fma52lo(res[47], a[6], a[41]); // Sum(47) + res[48] = fma52hi(res[48], a[6], a[41]); // Sum(47) + res[42] = fma52lo(res[42], a[0], a[42]); // Sum(42) + res[43] = fma52hi(res[43], a[0], a[42]); // Sum(42) + res[43] = fma52lo(res[43], a[1], a[42]); // Sum(43) + res[44] = fma52hi(res[44], a[1], a[42]); // Sum(43) + res[44] = fma52lo(res[44], a[2], a[42]); // Sum(44) + res[45] = fma52hi(res[45], a[2], a[42]); // Sum(44) + res[45] = fma52lo(res[45], a[3], a[42]); // Sum(45) + res[46] = fma52hi(res[46], a[3], a[42]); // Sum(45) + res[46] = fma52lo(res[46], a[4], a[42]); // Sum(46) + res[47] = fma52hi(res[47], a[4], a[42]); // Sum(46) + res[47] = fma52lo(res[47], a[5], a[42]); // Sum(47) + res[48] = fma52hi(res[48], a[5], a[42]); // Sum(47) + res[43] = fma52lo(res[43], a[0], a[43]); // Sum(43) + res[44] = fma52hi(res[44], a[0], a[43]); // Sum(43) + res[44] = fma52lo(res[44], a[1], a[43]); // Sum(44) + res[45] = fma52hi(res[45], a[1], a[43]); // Sum(44) + res[45] = fma52lo(res[45], a[2], a[43]); // Sum(45) + res[46] = fma52hi(res[46], a[2], a[43]); // Sum(45) + res[46] = fma52lo(res[46], a[3], a[43]); // Sum(46) + res[47] = fma52hi(res[47], a[3], a[43]); // Sum(46) + res[47] = fma52lo(res[47], a[4], a[43]); // Sum(47) + res[48] = fma52hi(res[48], a[4], a[43]); // Sum(47) + res[44] = fma52lo(res[44], a[0], a[44]); // Sum(44) + res[45] = fma52hi(res[45], a[0], a[44]); // Sum(44) + res[45] = fma52lo(res[45], a[1], a[44]); // Sum(45) + res[46] = fma52hi(res[46], a[1], a[44]); // Sum(45) + res[46] = fma52lo(res[46], a[2], a[44]); // Sum(46) + res[47] = fma52hi(res[47], a[2], a[44]); // Sum(46) + res[47] = fma52lo(res[47], a[3], a[44]); // Sum(47) + res[48] = fma52hi(res[48], a[3], a[44]); // Sum(47) + res[45] = fma52lo(res[45], a[0], a[45]); // Sum(45) + res[46] = fma52hi(res[46], a[0], a[45]); // Sum(45) + res[46] = fma52lo(res[46], a[1], a[45]); // Sum(46) + res[47] = fma52hi(res[47], a[1], a[45]); // Sum(46) + res[47] = fma52lo(res[47], a[2], a[45]); // Sum(47) + res[48] = fma52hi(res[48], a[2], a[45]); // Sum(47) + res[46] = fma52lo(res[46], a[0], a[46]); // Sum(46) + res[47] = fma52hi(res[47], a[0], a[46]); // Sum(46) + res[47] = fma52lo(res[47], a[1], a[46]); // Sum(47) + res[48] = fma52hi(res[48], a[1], a[46]); // Sum(47) + res[47] = fma52lo(res[47], a[0], a[47]); // Sum(47) + res[48] = fma52hi(res[48], a[0], a[47]); // Sum(47) + res[36] = add64(res[36], res[36]); // Double(36) + res[37] = add64(res[37], res[37]); // Double(37) + res[38] = add64(res[38], res[38]); // Double(38) + res[39] = add64(res[39], res[39]); // Double(39) + res[40] = add64(res[40], res[40]); // Double(40) + res[41] = add64(res[41], res[41]); // Double(41) + res[42] = add64(res[42], res[42]); // Double(42) + res[43] = add64(res[43], res[43]); // Double(43) + res[44] = add64(res[44], res[44]); // Double(44) + res[45] = add64(res[45], res[45]); // Double(45) + res[46] = add64(res[46], res[46]); // Double(46) + res[47] = add64(res[47], res[47]); // Double(47) + res[36] = fma52lo(res[36], a[18], a[18]); // Add sqr(36) + res[37] = fma52hi(res[37], a[18], a[18]); // Add sqr(36) + res[38] = fma52lo(res[38], a[19], a[19]); // Add sqr(38) + res[39] = fma52hi(res[39], a[19], a[19]); // Add sqr(38) + res[40] = fma52lo(res[40], a[20], a[20]); // Add sqr(40) + res[41] = fma52hi(res[41], a[20], a[20]); // Add sqr(40) + res[42] = fma52lo(res[42], a[21], a[21]); // Add sqr(42) + res[43] = fma52hi(res[43], a[21], a[21]); // Add sqr(42) + res[44] = fma52lo(res[44], a[22], a[22]); // Add sqr(44) + res[45] = fma52hi(res[45], a[22], a[22]); // Add sqr(44) + res[46] = fma52lo(res[46], a[23], a[23]); // Add sqr(46) + res[47] = fma52hi(res[47], a[23], a[23]); // Add sqr(46) + res[48] = fma52lo(res[48], a[23], a[25]); // Sum(48) + res[49] = fma52hi(res[49], a[23], a[25]); // Sum(48) + res[49] = fma52lo(res[49], a[24], a[25]); // Sum(49) + res[50] = fma52hi(res[50], a[24], a[25]); // Sum(49) + res[48] = fma52lo(res[48], a[22], a[26]); // Sum(48) + res[49] = fma52hi(res[49], a[22], a[26]); // Sum(48) + res[49] = fma52lo(res[49], a[23], a[26]); // Sum(49) + res[50] = fma52hi(res[50], a[23], a[26]); // Sum(49) + res[50] = fma52lo(res[50], a[24], a[26]); // Sum(50) + res[51] = fma52hi(res[51], a[24], a[26]); // Sum(50) + res[51] = fma52lo(res[51], a[25], a[26]); // Sum(51) + res[52] = fma52hi(res[52], a[25], a[26]); // Sum(51) + res[48] = fma52lo(res[48], a[21], a[27]); // Sum(48) + res[49] = fma52hi(res[49], a[21], a[27]); // Sum(48) + res[49] = fma52lo(res[49], a[22], a[27]); // Sum(49) + res[50] = fma52hi(res[50], a[22], a[27]); // Sum(49) + res[50] = fma52lo(res[50], a[23], a[27]); // Sum(50) + res[51] = fma52hi(res[51], a[23], a[27]); // Sum(50) + res[51] = fma52lo(res[51], a[24], a[27]); // Sum(51) + res[52] = fma52hi(res[52], a[24], a[27]); // Sum(51) + res[52] = fma52lo(res[52], a[25], a[27]); // Sum(52) + res[53] = fma52hi(res[53], a[25], a[27]); // Sum(52) + res[53] = fma52lo(res[53], a[26], a[27]); // Sum(53) + res[54] = fma52hi(res[54], a[26], a[27]); // Sum(53) + res[48] = fma52lo(res[48], a[20], a[28]); // Sum(48) + res[49] = fma52hi(res[49], a[20], a[28]); // Sum(48) + res[49] = fma52lo(res[49], a[21], a[28]); // Sum(49) + res[50] = fma52hi(res[50], a[21], a[28]); // Sum(49) + res[50] = fma52lo(res[50], a[22], a[28]); // Sum(50) + res[51] = fma52hi(res[51], a[22], a[28]); // Sum(50) + res[51] = fma52lo(res[51], a[23], a[28]); // Sum(51) + res[52] = fma52hi(res[52], a[23], a[28]); // Sum(51) + res[52] = fma52lo(res[52], a[24], a[28]); // Sum(52) + res[53] = fma52hi(res[53], a[24], a[28]); // Sum(52) + res[53] = fma52lo(res[53], a[25], a[28]); // Sum(53) + res[54] = fma52hi(res[54], a[25], a[28]); // Sum(53) + res[54] = fma52lo(res[54], a[26], a[28]); // Sum(54) + res[55] = fma52hi(res[55], a[26], a[28]); // Sum(54) + res[55] = fma52lo(res[55], a[27], a[28]); // Sum(55) + res[56] = fma52hi(res[56], a[27], a[28]); // Sum(55) + res[48] = fma52lo(res[48], a[19], a[29]); // Sum(48) + res[49] = fma52hi(res[49], a[19], a[29]); // Sum(48) + res[49] = fma52lo(res[49], a[20], a[29]); // Sum(49) + res[50] = fma52hi(res[50], a[20], a[29]); // Sum(49) + res[50] = fma52lo(res[50], a[21], a[29]); // Sum(50) + res[51] = fma52hi(res[51], a[21], a[29]); // Sum(50) + res[51] = fma52lo(res[51], a[22], a[29]); // Sum(51) + res[52] = fma52hi(res[52], a[22], a[29]); // Sum(51) + res[52] = fma52lo(res[52], a[23], a[29]); // Sum(52) + res[53] = fma52hi(res[53], a[23], a[29]); // Sum(52) + res[53] = fma52lo(res[53], a[24], a[29]); // Sum(53) + res[54] = fma52hi(res[54], a[24], a[29]); // Sum(53) + res[54] = fma52lo(res[54], a[25], a[29]); // Sum(54) + res[55] = fma52hi(res[55], a[25], a[29]); // Sum(54) + res[55] = fma52lo(res[55], a[26], a[29]); // Sum(55) + res[56] = fma52hi(res[56], a[26], a[29]); // Sum(55) + res[56] = fma52lo(res[56], a[27], a[29]); // Sum(56) + res[57] = fma52hi(res[57], a[27], a[29]); // Sum(56) + res[57] = fma52lo(res[57], a[28], a[29]); // Sum(57) + res[58] = fma52hi(res[58], a[28], a[29]); // Sum(57) + res[48] = fma52lo(res[48], a[18], a[30]); // Sum(48) + res[49] = fma52hi(res[49], a[18], a[30]); // Sum(48) + res[49] = fma52lo(res[49], a[19], a[30]); // Sum(49) + res[50] = fma52hi(res[50], a[19], a[30]); // Sum(49) + res[50] = fma52lo(res[50], a[20], a[30]); // Sum(50) + res[51] = fma52hi(res[51], a[20], a[30]); // Sum(50) + res[51] = fma52lo(res[51], a[21], a[30]); // Sum(51) + res[52] = fma52hi(res[52], a[21], a[30]); // Sum(51) + res[52] = fma52lo(res[52], a[22], a[30]); // Sum(52) + res[53] = fma52hi(res[53], a[22], a[30]); // Sum(52) + res[53] = fma52lo(res[53], a[23], a[30]); // Sum(53) + res[54] = fma52hi(res[54], a[23], a[30]); // Sum(53) + res[54] = fma52lo(res[54], a[24], a[30]); // Sum(54) + res[55] = fma52hi(res[55], a[24], a[30]); // Sum(54) + res[55] = fma52lo(res[55], a[25], a[30]); // Sum(55) + res[56] = fma52hi(res[56], a[25], a[30]); // Sum(55) + res[56] = fma52lo(res[56], a[26], a[30]); // Sum(56) + res[57] = fma52hi(res[57], a[26], a[30]); // Sum(56) + res[57] = fma52lo(res[57], a[27], a[30]); // Sum(57) + res[58] = fma52hi(res[58], a[27], a[30]); // Sum(57) + res[58] = fma52lo(res[58], a[28], a[30]); // Sum(58) + res[59] = fma52hi(res[59], a[28], a[30]); // Sum(58) + res[59] = fma52lo(res[59], a[29], a[30]); // Sum(59) + res[60] = fma52hi(res[60], a[29], a[30]); // Sum(59) + res[48] = fma52lo(res[48], a[17], a[31]); // Sum(48) + res[49] = fma52hi(res[49], a[17], a[31]); // Sum(48) + res[49] = fma52lo(res[49], a[18], a[31]); // Sum(49) + res[50] = fma52hi(res[50], a[18], a[31]); // Sum(49) + res[50] = fma52lo(res[50], a[19], a[31]); // Sum(50) + res[51] = fma52hi(res[51], a[19], a[31]); // Sum(50) + res[51] = fma52lo(res[51], a[20], a[31]); // Sum(51) + res[52] = fma52hi(res[52], a[20], a[31]); // Sum(51) + res[52] = fma52lo(res[52], a[21], a[31]); // Sum(52) + res[53] = fma52hi(res[53], a[21], a[31]); // Sum(52) + res[53] = fma52lo(res[53], a[22], a[31]); // Sum(53) + res[54] = fma52hi(res[54], a[22], a[31]); // Sum(53) + res[54] = fma52lo(res[54], a[23], a[31]); // Sum(54) + res[55] = fma52hi(res[55], a[23], a[31]); // Sum(54) + res[55] = fma52lo(res[55], a[24], a[31]); // Sum(55) + res[56] = fma52hi(res[56], a[24], a[31]); // Sum(55) + res[56] = fma52lo(res[56], a[25], a[31]); // Sum(56) + res[57] = fma52hi(res[57], a[25], a[31]); // Sum(56) + res[57] = fma52lo(res[57], a[26], a[31]); // Sum(57) + res[58] = fma52hi(res[58], a[26], a[31]); // Sum(57) + res[58] = fma52lo(res[58], a[27], a[31]); // Sum(58) + res[59] = fma52hi(res[59], a[27], a[31]); // Sum(58) + res[59] = fma52lo(res[59], a[28], a[31]); // Sum(59) + res[60] = fma52hi(res[60], a[28], a[31]); // Sum(59) + res[48] = fma52lo(res[48], a[16], a[32]); // Sum(48) + res[49] = fma52hi(res[49], a[16], a[32]); // Sum(48) + res[49] = fma52lo(res[49], a[17], a[32]); // Sum(49) + res[50] = fma52hi(res[50], a[17], a[32]); // Sum(49) + res[50] = fma52lo(res[50], a[18], a[32]); // Sum(50) + res[51] = fma52hi(res[51], a[18], a[32]); // Sum(50) + res[51] = fma52lo(res[51], a[19], a[32]); // Sum(51) + res[52] = fma52hi(res[52], a[19], a[32]); // Sum(51) + res[52] = fma52lo(res[52], a[20], a[32]); // Sum(52) + res[53] = fma52hi(res[53], a[20], a[32]); // Sum(52) + res[53] = fma52lo(res[53], a[21], a[32]); // Sum(53) + res[54] = fma52hi(res[54], a[21], a[32]); // Sum(53) + res[54] = fma52lo(res[54], a[22], a[32]); // Sum(54) + res[55] = fma52hi(res[55], a[22], a[32]); // Sum(54) + res[55] = fma52lo(res[55], a[23], a[32]); // Sum(55) + res[56] = fma52hi(res[56], a[23], a[32]); // Sum(55) + res[56] = fma52lo(res[56], a[24], a[32]); // Sum(56) + res[57] = fma52hi(res[57], a[24], a[32]); // Sum(56) + res[57] = fma52lo(res[57], a[25], a[32]); // Sum(57) + res[58] = fma52hi(res[58], a[25], a[32]); // Sum(57) + res[58] = fma52lo(res[58], a[26], a[32]); // Sum(58) + res[59] = fma52hi(res[59], a[26], a[32]); // Sum(58) + res[59] = fma52lo(res[59], a[27], a[32]); // Sum(59) + res[60] = fma52hi(res[60], a[27], a[32]); // Sum(59) + res[48] = fma52lo(res[48], a[15], a[33]); // Sum(48) + res[49] = fma52hi(res[49], a[15], a[33]); // Sum(48) + res[49] = fma52lo(res[49], a[16], a[33]); // Sum(49) + res[50] = fma52hi(res[50], a[16], a[33]); // Sum(49) + res[50] = fma52lo(res[50], a[17], a[33]); // Sum(50) + res[51] = fma52hi(res[51], a[17], a[33]); // Sum(50) + res[51] = fma52lo(res[51], a[18], a[33]); // Sum(51) + res[52] = fma52hi(res[52], a[18], a[33]); // Sum(51) + res[52] = fma52lo(res[52], a[19], a[33]); // Sum(52) + res[53] = fma52hi(res[53], a[19], a[33]); // Sum(52) + res[53] = fma52lo(res[53], a[20], a[33]); // Sum(53) + res[54] = fma52hi(res[54], a[20], a[33]); // Sum(53) + res[54] = fma52lo(res[54], a[21], a[33]); // Sum(54) + res[55] = fma52hi(res[55], a[21], a[33]); // Sum(54) + res[55] = fma52lo(res[55], a[22], a[33]); // Sum(55) + res[56] = fma52hi(res[56], a[22], a[33]); // Sum(55) + res[56] = fma52lo(res[56], a[23], a[33]); // Sum(56) + res[57] = fma52hi(res[57], a[23], a[33]); // Sum(56) + res[57] = fma52lo(res[57], a[24], a[33]); // Sum(57) + res[58] = fma52hi(res[58], a[24], a[33]); // Sum(57) + res[58] = fma52lo(res[58], a[25], a[33]); // Sum(58) + res[59] = fma52hi(res[59], a[25], a[33]); // Sum(58) + res[59] = fma52lo(res[59], a[26], a[33]); // Sum(59) + res[60] = fma52hi(res[60], a[26], a[33]); // Sum(59) + res[48] = fma52lo(res[48], a[14], a[34]); // Sum(48) + res[49] = fma52hi(res[49], a[14], a[34]); // Sum(48) + res[49] = fma52lo(res[49], a[15], a[34]); // Sum(49) + res[50] = fma52hi(res[50], a[15], a[34]); // Sum(49) + res[50] = fma52lo(res[50], a[16], a[34]); // Sum(50) + res[51] = fma52hi(res[51], a[16], a[34]); // Sum(50) + res[51] = fma52lo(res[51], a[17], a[34]); // Sum(51) + res[52] = fma52hi(res[52], a[17], a[34]); // Sum(51) + res[52] = fma52lo(res[52], a[18], a[34]); // Sum(52) + res[53] = fma52hi(res[53], a[18], a[34]); // Sum(52) + res[53] = fma52lo(res[53], a[19], a[34]); // Sum(53) + res[54] = fma52hi(res[54], a[19], a[34]); // Sum(53) + res[54] = fma52lo(res[54], a[20], a[34]); // Sum(54) + res[55] = fma52hi(res[55], a[20], a[34]); // Sum(54) + res[55] = fma52lo(res[55], a[21], a[34]); // Sum(55) + res[56] = fma52hi(res[56], a[21], a[34]); // Sum(55) + res[56] = fma52lo(res[56], a[22], a[34]); // Sum(56) + res[57] = fma52hi(res[57], a[22], a[34]); // Sum(56) + res[57] = fma52lo(res[57], a[23], a[34]); // Sum(57) + res[58] = fma52hi(res[58], a[23], a[34]); // Sum(57) + res[58] = fma52lo(res[58], a[24], a[34]); // Sum(58) + res[59] = fma52hi(res[59], a[24], a[34]); // Sum(58) + res[59] = fma52lo(res[59], a[25], a[34]); // Sum(59) + res[60] = fma52hi(res[60], a[25], a[34]); // Sum(59) + res[48] = fma52lo(res[48], a[13], a[35]); // Sum(48) + res[49] = fma52hi(res[49], a[13], a[35]); // Sum(48) + res[49] = fma52lo(res[49], a[14], a[35]); // Sum(49) + res[50] = fma52hi(res[50], a[14], a[35]); // Sum(49) + res[50] = fma52lo(res[50], a[15], a[35]); // Sum(50) + res[51] = fma52hi(res[51], a[15], a[35]); // Sum(50) + res[51] = fma52lo(res[51], a[16], a[35]); // Sum(51) + res[52] = fma52hi(res[52], a[16], a[35]); // Sum(51) + res[52] = fma52lo(res[52], a[17], a[35]); // Sum(52) + res[53] = fma52hi(res[53], a[17], a[35]); // Sum(52) + res[53] = fma52lo(res[53], a[18], a[35]); // Sum(53) + res[54] = fma52hi(res[54], a[18], a[35]); // Sum(53) + res[54] = fma52lo(res[54], a[19], a[35]); // Sum(54) + res[55] = fma52hi(res[55], a[19], a[35]); // Sum(54) + res[55] = fma52lo(res[55], a[20], a[35]); // Sum(55) + res[56] = fma52hi(res[56], a[20], a[35]); // Sum(55) + res[56] = fma52lo(res[56], a[21], a[35]); // Sum(56) + res[57] = fma52hi(res[57], a[21], a[35]); // Sum(56) + res[57] = fma52lo(res[57], a[22], a[35]); // Sum(57) + res[58] = fma52hi(res[58], a[22], a[35]); // Sum(57) + res[58] = fma52lo(res[58], a[23], a[35]); // Sum(58) + res[59] = fma52hi(res[59], a[23], a[35]); // Sum(58) + res[59] = fma52lo(res[59], a[24], a[35]); // Sum(59) + res[60] = fma52hi(res[60], a[24], a[35]); // Sum(59) + res[48] = fma52lo(res[48], a[12], a[36]); // Sum(48) + res[49] = fma52hi(res[49], a[12], a[36]); // Sum(48) + res[49] = fma52lo(res[49], a[13], a[36]); // Sum(49) + res[50] = fma52hi(res[50], a[13], a[36]); // Sum(49) + res[50] = fma52lo(res[50], a[14], a[36]); // Sum(50) + res[51] = fma52hi(res[51], a[14], a[36]); // Sum(50) + res[51] = fma52lo(res[51], a[15], a[36]); // Sum(51) + res[52] = fma52hi(res[52], a[15], a[36]); // Sum(51) + res[52] = fma52lo(res[52], a[16], a[36]); // Sum(52) + res[53] = fma52hi(res[53], a[16], a[36]); // Sum(52) + res[53] = fma52lo(res[53], a[17], a[36]); // Sum(53) + res[54] = fma52hi(res[54], a[17], a[36]); // Sum(53) + res[54] = fma52lo(res[54], a[18], a[36]); // Sum(54) + res[55] = fma52hi(res[55], a[18], a[36]); // Sum(54) + res[55] = fma52lo(res[55], a[19], a[36]); // Sum(55) + res[56] = fma52hi(res[56], a[19], a[36]); // Sum(55) + res[56] = fma52lo(res[56], a[20], a[36]); // Sum(56) + res[57] = fma52hi(res[57], a[20], a[36]); // Sum(56) + res[57] = fma52lo(res[57], a[21], a[36]); // Sum(57) + res[58] = fma52hi(res[58], a[21], a[36]); // Sum(57) + res[58] = fma52lo(res[58], a[22], a[36]); // Sum(58) + res[59] = fma52hi(res[59], a[22], a[36]); // Sum(58) + res[59] = fma52lo(res[59], a[23], a[36]); // Sum(59) + res[60] = fma52hi(res[60], a[23], a[36]); // Sum(59) + res[48] = fma52lo(res[48], a[11], a[37]); // Sum(48) + res[49] = fma52hi(res[49], a[11], a[37]); // Sum(48) + res[49] = fma52lo(res[49], a[12], a[37]); // Sum(49) + res[50] = fma52hi(res[50], a[12], a[37]); // Sum(49) + res[50] = fma52lo(res[50], a[13], a[37]); // Sum(50) + res[51] = fma52hi(res[51], a[13], a[37]); // Sum(50) + res[51] = fma52lo(res[51], a[14], a[37]); // Sum(51) + res[52] = fma52hi(res[52], a[14], a[37]); // Sum(51) + res[52] = fma52lo(res[52], a[15], a[37]); // Sum(52) + res[53] = fma52hi(res[53], a[15], a[37]); // Sum(52) + res[53] = fma52lo(res[53], a[16], a[37]); // Sum(53) + res[54] = fma52hi(res[54], a[16], a[37]); // Sum(53) + res[54] = fma52lo(res[54], a[17], a[37]); // Sum(54) + res[55] = fma52hi(res[55], a[17], a[37]); // Sum(54) + res[55] = fma52lo(res[55], a[18], a[37]); // Sum(55) + res[56] = fma52hi(res[56], a[18], a[37]); // Sum(55) + res[56] = fma52lo(res[56], a[19], a[37]); // Sum(56) + res[57] = fma52hi(res[57], a[19], a[37]); // Sum(56) + res[57] = fma52lo(res[57], a[20], a[37]); // Sum(57) + res[58] = fma52hi(res[58], a[20], a[37]); // Sum(57) + res[58] = fma52lo(res[58], a[21], a[37]); // Sum(58) + res[59] = fma52hi(res[59], a[21], a[37]); // Sum(58) + res[59] = fma52lo(res[59], a[22], a[37]); // Sum(59) + res[60] = fma52hi(res[60], a[22], a[37]); // Sum(59) + res[48] = fma52lo(res[48], a[10], a[38]); // Sum(48) + res[49] = fma52hi(res[49], a[10], a[38]); // Sum(48) + res[49] = fma52lo(res[49], a[11], a[38]); // Sum(49) + res[50] = fma52hi(res[50], a[11], a[38]); // Sum(49) + res[50] = fma52lo(res[50], a[12], a[38]); // Sum(50) + res[51] = fma52hi(res[51], a[12], a[38]); // Sum(50) + res[51] = fma52lo(res[51], a[13], a[38]); // Sum(51) + res[52] = fma52hi(res[52], a[13], a[38]); // Sum(51) + res[52] = fma52lo(res[52], a[14], a[38]); // Sum(52) + res[53] = fma52hi(res[53], a[14], a[38]); // Sum(52) + res[53] = fma52lo(res[53], a[15], a[38]); // Sum(53) + res[54] = fma52hi(res[54], a[15], a[38]); // Sum(53) + res[54] = fma52lo(res[54], a[16], a[38]); // Sum(54) + res[55] = fma52hi(res[55], a[16], a[38]); // Sum(54) + res[55] = fma52lo(res[55], a[17], a[38]); // Sum(55) + res[56] = fma52hi(res[56], a[17], a[38]); // Sum(55) + res[56] = fma52lo(res[56], a[18], a[38]); // Sum(56) + res[57] = fma52hi(res[57], a[18], a[38]); // Sum(56) + res[57] = fma52lo(res[57], a[19], a[38]); // Sum(57) + res[58] = fma52hi(res[58], a[19], a[38]); // Sum(57) + res[58] = fma52lo(res[58], a[20], a[38]); // Sum(58) + res[59] = fma52hi(res[59], a[20], a[38]); // Sum(58) + res[59] = fma52lo(res[59], a[21], a[38]); // Sum(59) + res[60] = fma52hi(res[60], a[21], a[38]); // Sum(59) + res[48] = fma52lo(res[48], a[9], a[39]); // Sum(48) + res[49] = fma52hi(res[49], a[9], a[39]); // Sum(48) + res[49] = fma52lo(res[49], a[10], a[39]); // Sum(49) + res[50] = fma52hi(res[50], a[10], a[39]); // Sum(49) + res[50] = fma52lo(res[50], a[11], a[39]); // Sum(50) + res[51] = fma52hi(res[51], a[11], a[39]); // Sum(50) + res[51] = fma52lo(res[51], a[12], a[39]); // Sum(51) + res[52] = fma52hi(res[52], a[12], a[39]); // Sum(51) + res[52] = fma52lo(res[52], a[13], a[39]); // Sum(52) + res[53] = fma52hi(res[53], a[13], a[39]); // Sum(52) + res[53] = fma52lo(res[53], a[14], a[39]); // Sum(53) + res[54] = fma52hi(res[54], a[14], a[39]); // Sum(53) + res[54] = fma52lo(res[54], a[15], a[39]); // Sum(54) + res[55] = fma52hi(res[55], a[15], a[39]); // Sum(54) + res[55] = fma52lo(res[55], a[16], a[39]); // Sum(55) + res[56] = fma52hi(res[56], a[16], a[39]); // Sum(55) + res[56] = fma52lo(res[56], a[17], a[39]); // Sum(56) + res[57] = fma52hi(res[57], a[17], a[39]); // Sum(56) + res[57] = fma52lo(res[57], a[18], a[39]); // Sum(57) + res[58] = fma52hi(res[58], a[18], a[39]); // Sum(57) + res[58] = fma52lo(res[58], a[19], a[39]); // Sum(58) + res[59] = fma52hi(res[59], a[19], a[39]); // Sum(58) + res[59] = fma52lo(res[59], a[20], a[39]); // Sum(59) + res[60] = fma52hi(res[60], a[20], a[39]); // Sum(59) + res[48] = fma52lo(res[48], a[8], a[40]); // Sum(48) + res[49] = fma52hi(res[49], a[8], a[40]); // Sum(48) + res[49] = fma52lo(res[49], a[9], a[40]); // Sum(49) + res[50] = fma52hi(res[50], a[9], a[40]); // Sum(49) + res[50] = fma52lo(res[50], a[10], a[40]); // Sum(50) + res[51] = fma52hi(res[51], a[10], a[40]); // Sum(50) + res[51] = fma52lo(res[51], a[11], a[40]); // Sum(51) + res[52] = fma52hi(res[52], a[11], a[40]); // Sum(51) + res[52] = fma52lo(res[52], a[12], a[40]); // Sum(52) + res[53] = fma52hi(res[53], a[12], a[40]); // Sum(52) + res[53] = fma52lo(res[53], a[13], a[40]); // Sum(53) + res[54] = fma52hi(res[54], a[13], a[40]); // Sum(53) + res[54] = fma52lo(res[54], a[14], a[40]); // Sum(54) + res[55] = fma52hi(res[55], a[14], a[40]); // Sum(54) + res[55] = fma52lo(res[55], a[15], a[40]); // Sum(55) + res[56] = fma52hi(res[56], a[15], a[40]); // Sum(55) + res[56] = fma52lo(res[56], a[16], a[40]); // Sum(56) + res[57] = fma52hi(res[57], a[16], a[40]); // Sum(56) + res[57] = fma52lo(res[57], a[17], a[40]); // Sum(57) + res[58] = fma52hi(res[58], a[17], a[40]); // Sum(57) + res[58] = fma52lo(res[58], a[18], a[40]); // Sum(58) + res[59] = fma52hi(res[59], a[18], a[40]); // Sum(58) + res[59] = fma52lo(res[59], a[19], a[40]); // Sum(59) + res[60] = fma52hi(res[60], a[19], a[40]); // Sum(59) + res[48] = fma52lo(res[48], a[7], a[41]); // Sum(48) + res[49] = fma52hi(res[49], a[7], a[41]); // Sum(48) + res[49] = fma52lo(res[49], a[8], a[41]); // Sum(49) + res[50] = fma52hi(res[50], a[8], a[41]); // Sum(49) + res[50] = fma52lo(res[50], a[9], a[41]); // Sum(50) + res[51] = fma52hi(res[51], a[9], a[41]); // Sum(50) + res[51] = fma52lo(res[51], a[10], a[41]); // Sum(51) + res[52] = fma52hi(res[52], a[10], a[41]); // Sum(51) + res[52] = fma52lo(res[52], a[11], a[41]); // Sum(52) + res[53] = fma52hi(res[53], a[11], a[41]); // Sum(52) + res[53] = fma52lo(res[53], a[12], a[41]); // Sum(53) + res[54] = fma52hi(res[54], a[12], a[41]); // Sum(53) + res[54] = fma52lo(res[54], a[13], a[41]); // Sum(54) + res[55] = fma52hi(res[55], a[13], a[41]); // Sum(54) + res[55] = fma52lo(res[55], a[14], a[41]); // Sum(55) + res[56] = fma52hi(res[56], a[14], a[41]); // Sum(55) + res[56] = fma52lo(res[56], a[15], a[41]); // Sum(56) + res[57] = fma52hi(res[57], a[15], a[41]); // Sum(56) + res[57] = fma52lo(res[57], a[16], a[41]); // Sum(57) + res[58] = fma52hi(res[58], a[16], a[41]); // Sum(57) + res[58] = fma52lo(res[58], a[17], a[41]); // Sum(58) + res[59] = fma52hi(res[59], a[17], a[41]); // Sum(58) + res[59] = fma52lo(res[59], a[18], a[41]); // Sum(59) + res[60] = fma52hi(res[60], a[18], a[41]); // Sum(59) + res[48] = fma52lo(res[48], a[6], a[42]); // Sum(48) + res[49] = fma52hi(res[49], a[6], a[42]); // Sum(48) + res[49] = fma52lo(res[49], a[7], a[42]); // Sum(49) + res[50] = fma52hi(res[50], a[7], a[42]); // Sum(49) + res[50] = fma52lo(res[50], a[8], a[42]); // Sum(50) + res[51] = fma52hi(res[51], a[8], a[42]); // Sum(50) + res[51] = fma52lo(res[51], a[9], a[42]); // Sum(51) + res[52] = fma52hi(res[52], a[9], a[42]); // Sum(51) + res[52] = fma52lo(res[52], a[10], a[42]); // Sum(52) + res[53] = fma52hi(res[53], a[10], a[42]); // Sum(52) + res[53] = fma52lo(res[53], a[11], a[42]); // Sum(53) + res[54] = fma52hi(res[54], a[11], a[42]); // Sum(53) + res[54] = fma52lo(res[54], a[12], a[42]); // Sum(54) + res[55] = fma52hi(res[55], a[12], a[42]); // Sum(54) + res[55] = fma52lo(res[55], a[13], a[42]); // Sum(55) + res[56] = fma52hi(res[56], a[13], a[42]); // Sum(55) + res[56] = fma52lo(res[56], a[14], a[42]); // Sum(56) + res[57] = fma52hi(res[57], a[14], a[42]); // Sum(56) + res[57] = fma52lo(res[57], a[15], a[42]); // Sum(57) + res[58] = fma52hi(res[58], a[15], a[42]); // Sum(57) + res[58] = fma52lo(res[58], a[16], a[42]); // Sum(58) + res[59] = fma52hi(res[59], a[16], a[42]); // Sum(58) + res[59] = fma52lo(res[59], a[17], a[42]); // Sum(59) + res[60] = fma52hi(res[60], a[17], a[42]); // Sum(59) + res[48] = fma52lo(res[48], a[5], a[43]); // Sum(48) + res[49] = fma52hi(res[49], a[5], a[43]); // Sum(48) + res[49] = fma52lo(res[49], a[6], a[43]); // Sum(49) + res[50] = fma52hi(res[50], a[6], a[43]); // Sum(49) + res[50] = fma52lo(res[50], a[7], a[43]); // Sum(50) + res[51] = fma52hi(res[51], a[7], a[43]); // Sum(50) + res[51] = fma52lo(res[51], a[8], a[43]); // Sum(51) + res[52] = fma52hi(res[52], a[8], a[43]); // Sum(51) + res[52] = fma52lo(res[52], a[9], a[43]); // Sum(52) + res[53] = fma52hi(res[53], a[9], a[43]); // Sum(52) + res[53] = fma52lo(res[53], a[10], a[43]); // Sum(53) + res[54] = fma52hi(res[54], a[10], a[43]); // Sum(53) + res[54] = fma52lo(res[54], a[11], a[43]); // Sum(54) + res[55] = fma52hi(res[55], a[11], a[43]); // Sum(54) + res[55] = fma52lo(res[55], a[12], a[43]); // Sum(55) + res[56] = fma52hi(res[56], a[12], a[43]); // Sum(55) + res[56] = fma52lo(res[56], a[13], a[43]); // Sum(56) + res[57] = fma52hi(res[57], a[13], a[43]); // Sum(56) + res[57] = fma52lo(res[57], a[14], a[43]); // Sum(57) + res[58] = fma52hi(res[58], a[14], a[43]); // Sum(57) + res[58] = fma52lo(res[58], a[15], a[43]); // Sum(58) + res[59] = fma52hi(res[59], a[15], a[43]); // Sum(58) + res[59] = fma52lo(res[59], a[16], a[43]); // Sum(59) + res[60] = fma52hi(res[60], a[16], a[43]); // Sum(59) + res[48] = fma52lo(res[48], a[4], a[44]); // Sum(48) + res[49] = fma52hi(res[49], a[4], a[44]); // Sum(48) + res[49] = fma52lo(res[49], a[5], a[44]); // Sum(49) + res[50] = fma52hi(res[50], a[5], a[44]); // Sum(49) + res[50] = fma52lo(res[50], a[6], a[44]); // Sum(50) + res[51] = fma52hi(res[51], a[6], a[44]); // Sum(50) + res[51] = fma52lo(res[51], a[7], a[44]); // Sum(51) + res[52] = fma52hi(res[52], a[7], a[44]); // Sum(51) + res[52] = fma52lo(res[52], a[8], a[44]); // Sum(52) + res[53] = fma52hi(res[53], a[8], a[44]); // Sum(52) + res[53] = fma52lo(res[53], a[9], a[44]); // Sum(53) + res[54] = fma52hi(res[54], a[9], a[44]); // Sum(53) + res[54] = fma52lo(res[54], a[10], a[44]); // Sum(54) + res[55] = fma52hi(res[55], a[10], a[44]); // Sum(54) + res[55] = fma52lo(res[55], a[11], a[44]); // Sum(55) + res[56] = fma52hi(res[56], a[11], a[44]); // Sum(55) + res[56] = fma52lo(res[56], a[12], a[44]); // Sum(56) + res[57] = fma52hi(res[57], a[12], a[44]); // Sum(56) + res[57] = fma52lo(res[57], a[13], a[44]); // Sum(57) + res[58] = fma52hi(res[58], a[13], a[44]); // Sum(57) + res[58] = fma52lo(res[58], a[14], a[44]); // Sum(58) + res[59] = fma52hi(res[59], a[14], a[44]); // Sum(58) + res[59] = fma52lo(res[59], a[15], a[44]); // Sum(59) + res[60] = fma52hi(res[60], a[15], a[44]); // Sum(59) + res[48] = fma52lo(res[48], a[3], a[45]); // Sum(48) + res[49] = fma52hi(res[49], a[3], a[45]); // Sum(48) + res[49] = fma52lo(res[49], a[4], a[45]); // Sum(49) + res[50] = fma52hi(res[50], a[4], a[45]); // Sum(49) + res[50] = fma52lo(res[50], a[5], a[45]); // Sum(50) + res[51] = fma52hi(res[51], a[5], a[45]); // Sum(50) + res[51] = fma52lo(res[51], a[6], a[45]); // Sum(51) + res[52] = fma52hi(res[52], a[6], a[45]); // Sum(51) + res[52] = fma52lo(res[52], a[7], a[45]); // Sum(52) + res[53] = fma52hi(res[53], a[7], a[45]); // Sum(52) + res[53] = fma52lo(res[53], a[8], a[45]); // Sum(53) + res[54] = fma52hi(res[54], a[8], a[45]); // Sum(53) + res[54] = fma52lo(res[54], a[9], a[45]); // Sum(54) + res[55] = fma52hi(res[55], a[9], a[45]); // Sum(54) + res[55] = fma52lo(res[55], a[10], a[45]); // Sum(55) + res[56] = fma52hi(res[56], a[10], a[45]); // Sum(55) + res[56] = fma52lo(res[56], a[11], a[45]); // Sum(56) + res[57] = fma52hi(res[57], a[11], a[45]); // Sum(56) + res[57] = fma52lo(res[57], a[12], a[45]); // Sum(57) + res[58] = fma52hi(res[58], a[12], a[45]); // Sum(57) + res[58] = fma52lo(res[58], a[13], a[45]); // Sum(58) + res[59] = fma52hi(res[59], a[13], a[45]); // Sum(58) + res[59] = fma52lo(res[59], a[14], a[45]); // Sum(59) + res[60] = fma52hi(res[60], a[14], a[45]); // Sum(59) + res[48] = fma52lo(res[48], a[2], a[46]); // Sum(48) + res[49] = fma52hi(res[49], a[2], a[46]); // Sum(48) + res[49] = fma52lo(res[49], a[3], a[46]); // Sum(49) + res[50] = fma52hi(res[50], a[3], a[46]); // Sum(49) + res[50] = fma52lo(res[50], a[4], a[46]); // Sum(50) + res[51] = fma52hi(res[51], a[4], a[46]); // Sum(50) + res[51] = fma52lo(res[51], a[5], a[46]); // Sum(51) + res[52] = fma52hi(res[52], a[5], a[46]); // Sum(51) + res[52] = fma52lo(res[52], a[6], a[46]); // Sum(52) + res[53] = fma52hi(res[53], a[6], a[46]); // Sum(52) + res[53] = fma52lo(res[53], a[7], a[46]); // Sum(53) + res[54] = fma52hi(res[54], a[7], a[46]); // Sum(53) + res[54] = fma52lo(res[54], a[8], a[46]); // Sum(54) + res[55] = fma52hi(res[55], a[8], a[46]); // Sum(54) + res[55] = fma52lo(res[55], a[9], a[46]); // Sum(55) + res[56] = fma52hi(res[56], a[9], a[46]); // Sum(55) + res[56] = fma52lo(res[56], a[10], a[46]); // Sum(56) + res[57] = fma52hi(res[57], a[10], a[46]); // Sum(56) + res[57] = fma52lo(res[57], a[11], a[46]); // Sum(57) + res[58] = fma52hi(res[58], a[11], a[46]); // Sum(57) + res[58] = fma52lo(res[58], a[12], a[46]); // Sum(58) + res[59] = fma52hi(res[59], a[12], a[46]); // Sum(58) + res[59] = fma52lo(res[59], a[13], a[46]); // Sum(59) + res[60] = fma52hi(res[60], a[13], a[46]); // Sum(59) + res[48] = fma52lo(res[48], a[1], a[47]); // Sum(48) + res[49] = fma52hi(res[49], a[1], a[47]); // Sum(48) + res[49] = fma52lo(res[49], a[2], a[47]); // Sum(49) + res[50] = fma52hi(res[50], a[2], a[47]); // Sum(49) + res[50] = fma52lo(res[50], a[3], a[47]); // Sum(50) + res[51] = fma52hi(res[51], a[3], a[47]); // Sum(50) + res[51] = fma52lo(res[51], a[4], a[47]); // Sum(51) + res[52] = fma52hi(res[52], a[4], a[47]); // Sum(51) + res[52] = fma52lo(res[52], a[5], a[47]); // Sum(52) + res[53] = fma52hi(res[53], a[5], a[47]); // Sum(52) + res[53] = fma52lo(res[53], a[6], a[47]); // Sum(53) + res[54] = fma52hi(res[54], a[6], a[47]); // Sum(53) + res[54] = fma52lo(res[54], a[7], a[47]); // Sum(54) + res[55] = fma52hi(res[55], a[7], a[47]); // Sum(54) + res[55] = fma52lo(res[55], a[8], a[47]); // Sum(55) + res[56] = fma52hi(res[56], a[8], a[47]); // Sum(55) + res[56] = fma52lo(res[56], a[9], a[47]); // Sum(56) + res[57] = fma52hi(res[57], a[9], a[47]); // Sum(56) + res[57] = fma52lo(res[57], a[10], a[47]); // Sum(57) + res[58] = fma52hi(res[58], a[10], a[47]); // Sum(57) + res[58] = fma52lo(res[58], a[11], a[47]); // Sum(58) + res[59] = fma52hi(res[59], a[11], a[47]); // Sum(58) + res[59] = fma52lo(res[59], a[12], a[47]); // Sum(59) + res[60] = fma52hi(res[60], a[12], a[47]); // Sum(59) + res[48] = fma52lo(res[48], a[0], a[48]); // Sum(48) + res[49] = fma52hi(res[49], a[0], a[48]); // Sum(48) + res[49] = fma52lo(res[49], a[1], a[48]); // Sum(49) + res[50] = fma52hi(res[50], a[1], a[48]); // Sum(49) + res[50] = fma52lo(res[50], a[2], a[48]); // Sum(50) + res[51] = fma52hi(res[51], a[2], a[48]); // Sum(50) + res[51] = fma52lo(res[51], a[3], a[48]); // Sum(51) + res[52] = fma52hi(res[52], a[3], a[48]); // Sum(51) + res[52] = fma52lo(res[52], a[4], a[48]); // Sum(52) + res[53] = fma52hi(res[53], a[4], a[48]); // Sum(52) + res[53] = fma52lo(res[53], a[5], a[48]); // Sum(53) + res[54] = fma52hi(res[54], a[5], a[48]); // Sum(53) + res[54] = fma52lo(res[54], a[6], a[48]); // Sum(54) + res[55] = fma52hi(res[55], a[6], a[48]); // Sum(54) + res[55] = fma52lo(res[55], a[7], a[48]); // Sum(55) + res[56] = fma52hi(res[56], a[7], a[48]); // Sum(55) + res[56] = fma52lo(res[56], a[8], a[48]); // Sum(56) + res[57] = fma52hi(res[57], a[8], a[48]); // Sum(56) + res[57] = fma52lo(res[57], a[9], a[48]); // Sum(57) + res[58] = fma52hi(res[58], a[9], a[48]); // Sum(57) + res[58] = fma52lo(res[58], a[10], a[48]); // Sum(58) + res[59] = fma52hi(res[59], a[10], a[48]); // Sum(58) + res[59] = fma52lo(res[59], a[11], a[48]); // Sum(59) + res[60] = fma52hi(res[60], a[11], a[48]); // Sum(59) + res[49] = fma52lo(res[49], a[0], a[49]); // Sum(49) + res[50] = fma52hi(res[50], a[0], a[49]); // Sum(49) + res[50] = fma52lo(res[50], a[1], a[49]); // Sum(50) + res[51] = fma52hi(res[51], a[1], a[49]); // Sum(50) + res[51] = fma52lo(res[51], a[2], a[49]); // Sum(51) + res[52] = fma52hi(res[52], a[2], a[49]); // Sum(51) + res[52] = fma52lo(res[52], a[3], a[49]); // Sum(52) + res[53] = fma52hi(res[53], a[3], a[49]); // Sum(52) + res[53] = fma52lo(res[53], a[4], a[49]); // Sum(53) + res[54] = fma52hi(res[54], a[4], a[49]); // Sum(53) + res[54] = fma52lo(res[54], a[5], a[49]); // Sum(54) + res[55] = fma52hi(res[55], a[5], a[49]); // Sum(54) + res[55] = fma52lo(res[55], a[6], a[49]); // Sum(55) + res[56] = fma52hi(res[56], a[6], a[49]); // Sum(55) + res[56] = fma52lo(res[56], a[7], a[49]); // Sum(56) + res[57] = fma52hi(res[57], a[7], a[49]); // Sum(56) + res[57] = fma52lo(res[57], a[8], a[49]); // Sum(57) + res[58] = fma52hi(res[58], a[8], a[49]); // Sum(57) + res[58] = fma52lo(res[58], a[9], a[49]); // Sum(58) + res[59] = fma52hi(res[59], a[9], a[49]); // Sum(58) + res[59] = fma52lo(res[59], a[10], a[49]); // Sum(59) + res[60] = fma52hi(res[60], a[10], a[49]); // Sum(59) + res[50] = fma52lo(res[50], a[0], a[50]); // Sum(50) + res[51] = fma52hi(res[51], a[0], a[50]); // Sum(50) + res[51] = fma52lo(res[51], a[1], a[50]); // Sum(51) + res[52] = fma52hi(res[52], a[1], a[50]); // Sum(51) + res[52] = fma52lo(res[52], a[2], a[50]); // Sum(52) + res[53] = fma52hi(res[53], a[2], a[50]); // Sum(52) + res[53] = fma52lo(res[53], a[3], a[50]); // Sum(53) + res[54] = fma52hi(res[54], a[3], a[50]); // Sum(53) + res[54] = fma52lo(res[54], a[4], a[50]); // Sum(54) + res[55] = fma52hi(res[55], a[4], a[50]); // Sum(54) + res[55] = fma52lo(res[55], a[5], a[50]); // Sum(55) + res[56] = fma52hi(res[56], a[5], a[50]); // Sum(55) + res[56] = fma52lo(res[56], a[6], a[50]); // Sum(56) + res[57] = fma52hi(res[57], a[6], a[50]); // Sum(56) + res[57] = fma52lo(res[57], a[7], a[50]); // Sum(57) + res[58] = fma52hi(res[58], a[7], a[50]); // Sum(57) + res[58] = fma52lo(res[58], a[8], a[50]); // Sum(58) + res[59] = fma52hi(res[59], a[8], a[50]); // Sum(58) + res[59] = fma52lo(res[59], a[9], a[50]); // Sum(59) + res[60] = fma52hi(res[60], a[9], a[50]); // Sum(59) + res[51] = fma52lo(res[51], a[0], a[51]); // Sum(51) + res[52] = fma52hi(res[52], a[0], a[51]); // Sum(51) + res[52] = fma52lo(res[52], a[1], a[51]); // Sum(52) + res[53] = fma52hi(res[53], a[1], a[51]); // Sum(52) + res[53] = fma52lo(res[53], a[2], a[51]); // Sum(53) + res[54] = fma52hi(res[54], a[2], a[51]); // Sum(53) + res[54] = fma52lo(res[54], a[3], a[51]); // Sum(54) + res[55] = fma52hi(res[55], a[3], a[51]); // Sum(54) + res[55] = fma52lo(res[55], a[4], a[51]); // Sum(55) + res[56] = fma52hi(res[56], a[4], a[51]); // Sum(55) + res[56] = fma52lo(res[56], a[5], a[51]); // Sum(56) + res[57] = fma52hi(res[57], a[5], a[51]); // Sum(56) + res[57] = fma52lo(res[57], a[6], a[51]); // Sum(57) + res[58] = fma52hi(res[58], a[6], a[51]); // Sum(57) + res[58] = fma52lo(res[58], a[7], a[51]); // Sum(58) + res[59] = fma52hi(res[59], a[7], a[51]); // Sum(58) + res[59] = fma52lo(res[59], a[8], a[51]); // Sum(59) + res[60] = fma52hi(res[60], a[8], a[51]); // Sum(59) + res[52] = fma52lo(res[52], a[0], a[52]); // Sum(52) + res[53] = fma52hi(res[53], a[0], a[52]); // Sum(52) + res[53] = fma52lo(res[53], a[1], a[52]); // Sum(53) + res[54] = fma52hi(res[54], a[1], a[52]); // Sum(53) + res[54] = fma52lo(res[54], a[2], a[52]); // Sum(54) + res[55] = fma52hi(res[55], a[2], a[52]); // Sum(54) + res[55] = fma52lo(res[55], a[3], a[52]); // Sum(55) + res[56] = fma52hi(res[56], a[3], a[52]); // Sum(55) + res[56] = fma52lo(res[56], a[4], a[52]); // Sum(56) + res[57] = fma52hi(res[57], a[4], a[52]); // Sum(56) + res[57] = fma52lo(res[57], a[5], a[52]); // Sum(57) + res[58] = fma52hi(res[58], a[5], a[52]); // Sum(57) + res[58] = fma52lo(res[58], a[6], a[52]); // Sum(58) + res[59] = fma52hi(res[59], a[6], a[52]); // Sum(58) + res[59] = fma52lo(res[59], a[7], a[52]); // Sum(59) + res[60] = fma52hi(res[60], a[7], a[52]); // Sum(59) + res[53] = fma52lo(res[53], a[0], a[53]); // Sum(53) + res[54] = fma52hi(res[54], a[0], a[53]); // Sum(53) + res[54] = fma52lo(res[54], a[1], a[53]); // Sum(54) + res[55] = fma52hi(res[55], a[1], a[53]); // Sum(54) + res[55] = fma52lo(res[55], a[2], a[53]); // Sum(55) + res[56] = fma52hi(res[56], a[2], a[53]); // Sum(55) + res[56] = fma52lo(res[56], a[3], a[53]); // Sum(56) + res[57] = fma52hi(res[57], a[3], a[53]); // Sum(56) + res[57] = fma52lo(res[57], a[4], a[53]); // Sum(57) + res[58] = fma52hi(res[58], a[4], a[53]); // Sum(57) + res[58] = fma52lo(res[58], a[5], a[53]); // Sum(58) + res[59] = fma52hi(res[59], a[5], a[53]); // Sum(58) + res[59] = fma52lo(res[59], a[6], a[53]); // Sum(59) + res[60] = fma52hi(res[60], a[6], a[53]); // Sum(59) + res[54] = fma52lo(res[54], a[0], a[54]); // Sum(54) + res[55] = fma52hi(res[55], a[0], a[54]); // Sum(54) + res[55] = fma52lo(res[55], a[1], a[54]); // Sum(55) + res[56] = fma52hi(res[56], a[1], a[54]); // Sum(55) + res[56] = fma52lo(res[56], a[2], a[54]); // Sum(56) + res[57] = fma52hi(res[57], a[2], a[54]); // Sum(56) + res[57] = fma52lo(res[57], a[3], a[54]); // Sum(57) + res[58] = fma52hi(res[58], a[3], a[54]); // Sum(57) + res[58] = fma52lo(res[58], a[4], a[54]); // Sum(58) + res[59] = fma52hi(res[59], a[4], a[54]); // Sum(58) + res[59] = fma52lo(res[59], a[5], a[54]); // Sum(59) + res[60] = fma52hi(res[60], a[5], a[54]); // Sum(59) + res[55] = fma52lo(res[55], a[0], a[55]); // Sum(55) + res[56] = fma52hi(res[56], a[0], a[55]); // Sum(55) + res[56] = fma52lo(res[56], a[1], a[55]); // Sum(56) + res[57] = fma52hi(res[57], a[1], a[55]); // Sum(56) + res[57] = fma52lo(res[57], a[2], a[55]); // Sum(57) + res[58] = fma52hi(res[58], a[2], a[55]); // Sum(57) + res[58] = fma52lo(res[58], a[3], a[55]); // Sum(58) + res[59] = fma52hi(res[59], a[3], a[55]); // Sum(58) + res[59] = fma52lo(res[59], a[4], a[55]); // Sum(59) + res[60] = fma52hi(res[60], a[4], a[55]); // Sum(59) + res[56] = fma52lo(res[56], a[0], a[56]); // Sum(56) + res[57] = fma52hi(res[57], a[0], a[56]); // Sum(56) + res[57] = fma52lo(res[57], a[1], a[56]); // Sum(57) + res[58] = fma52hi(res[58], a[1], a[56]); // Sum(57) + res[58] = fma52lo(res[58], a[2], a[56]); // Sum(58) + res[59] = fma52hi(res[59], a[2], a[56]); // Sum(58) + res[59] = fma52lo(res[59], a[3], a[56]); // Sum(59) + res[60] = fma52hi(res[60], a[3], a[56]); // Sum(59) + res[57] = fma52lo(res[57], a[0], a[57]); // Sum(57) + res[58] = fma52hi(res[58], a[0], a[57]); // Sum(57) + res[58] = fma52lo(res[58], a[1], a[57]); // Sum(58) + res[59] = fma52hi(res[59], a[1], a[57]); // Sum(58) + res[59] = fma52lo(res[59], a[2], a[57]); // Sum(59) + res[60] = fma52hi(res[60], a[2], a[57]); // Sum(59) + res[58] = fma52lo(res[58], a[0], a[58]); // Sum(58) + res[59] = fma52hi(res[59], a[0], a[58]); // Sum(58) + res[59] = fma52lo(res[59], a[1], a[58]); // Sum(59) + res[60] = fma52hi(res[60], a[1], a[58]); // Sum(59) + res[59] = fma52lo(res[59], a[0], a[59]); // Sum(59) + res[60] = fma52hi(res[60], a[0], a[59]); // Sum(59) + res[48] = add64(res[48], res[48]); // Double(48) + res[49] = add64(res[49], res[49]); // Double(49) + res[50] = add64(res[50], res[50]); // Double(50) + res[51] = add64(res[51], res[51]); // Double(51) + res[52] = add64(res[52], res[52]); // Double(52) + res[53] = add64(res[53], res[53]); // Double(53) + res[54] = add64(res[54], res[54]); // Double(54) + res[55] = add64(res[55], res[55]); // Double(55) + res[56] = add64(res[56], res[56]); // Double(56) + res[57] = add64(res[57], res[57]); // Double(57) + res[58] = add64(res[58], res[58]); // Double(58) + res[59] = add64(res[59], res[59]); // Double(59) + res[48] = fma52lo(res[48], a[24], a[24]); // Add sqr(48) + res[49] = fma52hi(res[49], a[24], a[24]); // Add sqr(48) + res[50] = fma52lo(res[50], a[25], a[25]); // Add sqr(50) + res[51] = fma52hi(res[51], a[25], a[25]); // Add sqr(50) + res[52] = fma52lo(res[52], a[26], a[26]); // Add sqr(52) + res[53] = fma52hi(res[53], a[26], a[26]); // Add sqr(52) + res[54] = fma52lo(res[54], a[27], a[27]); // Add sqr(54) + res[55] = fma52hi(res[55], a[27], a[27]); // Add sqr(54) + res[56] = fma52lo(res[56], a[28], a[28]); // Add sqr(56) + res[57] = fma52hi(res[57], a[28], a[28]); // Add sqr(56) + res[58] = fma52lo(res[58], a[29], a[29]); // Add sqr(58) + res[59] = fma52hi(res[59], a[29], a[29]); // Add sqr(58) + res[60] = fma52lo(res[60], a[29], a[31]); // Sum(60) + res[61] = fma52hi(res[61], a[29], a[31]); // Sum(60) + res[61] = fma52lo(res[61], a[30], a[31]); // Sum(61) + res[62] = fma52hi(res[62], a[30], a[31]); // Sum(61) + res[60] = fma52lo(res[60], a[28], a[32]); // Sum(60) + res[61] = fma52hi(res[61], a[28], a[32]); // Sum(60) + res[61] = fma52lo(res[61], a[29], a[32]); // Sum(61) + res[62] = fma52hi(res[62], a[29], a[32]); // Sum(61) + res[62] = fma52lo(res[62], a[30], a[32]); // Sum(62) + res[63] = fma52hi(res[63], a[30], a[32]); // Sum(62) + res[63] = fma52lo(res[63], a[31], a[32]); // Sum(63) + res[64] = fma52hi(res[64], a[31], a[32]); // Sum(63) + res[60] = fma52lo(res[60], a[27], a[33]); // Sum(60) + res[61] = fma52hi(res[61], a[27], a[33]); // Sum(60) + res[61] = fma52lo(res[61], a[28], a[33]); // Sum(61) + res[62] = fma52hi(res[62], a[28], a[33]); // Sum(61) + res[62] = fma52lo(res[62], a[29], a[33]); // Sum(62) + res[63] = fma52hi(res[63], a[29], a[33]); // Sum(62) + res[63] = fma52lo(res[63], a[30], a[33]); // Sum(63) + res[64] = fma52hi(res[64], a[30], a[33]); // Sum(63) + res[64] = fma52lo(res[64], a[31], a[33]); // Sum(64) + res[65] = fma52hi(res[65], a[31], a[33]); // Sum(64) + res[65] = fma52lo(res[65], a[32], a[33]); // Sum(65) + res[66] = fma52hi(res[66], a[32], a[33]); // Sum(65) + res[60] = fma52lo(res[60], a[26], a[34]); // Sum(60) + res[61] = fma52hi(res[61], a[26], a[34]); // Sum(60) + res[61] = fma52lo(res[61], a[27], a[34]); // Sum(61) + res[62] = fma52hi(res[62], a[27], a[34]); // Sum(61) + res[62] = fma52lo(res[62], a[28], a[34]); // Sum(62) + res[63] = fma52hi(res[63], a[28], a[34]); // Sum(62) + res[63] = fma52lo(res[63], a[29], a[34]); // Sum(63) + res[64] = fma52hi(res[64], a[29], a[34]); // Sum(63) + res[64] = fma52lo(res[64], a[30], a[34]); // Sum(64) + res[65] = fma52hi(res[65], a[30], a[34]); // Sum(64) + res[65] = fma52lo(res[65], a[31], a[34]); // Sum(65) + res[66] = fma52hi(res[66], a[31], a[34]); // Sum(65) + res[66] = fma52lo(res[66], a[32], a[34]); // Sum(66) + res[67] = fma52hi(res[67], a[32], a[34]); // Sum(66) + res[67] = fma52lo(res[67], a[33], a[34]); // Sum(67) + res[68] = fma52hi(res[68], a[33], a[34]); // Sum(67) + res[60] = fma52lo(res[60], a[25], a[35]); // Sum(60) + res[61] = fma52hi(res[61], a[25], a[35]); // Sum(60) + res[61] = fma52lo(res[61], a[26], a[35]); // Sum(61) + res[62] = fma52hi(res[62], a[26], a[35]); // Sum(61) + res[62] = fma52lo(res[62], a[27], a[35]); // Sum(62) + res[63] = fma52hi(res[63], a[27], a[35]); // Sum(62) + res[63] = fma52lo(res[63], a[28], a[35]); // Sum(63) + res[64] = fma52hi(res[64], a[28], a[35]); // Sum(63) + res[64] = fma52lo(res[64], a[29], a[35]); // Sum(64) + res[65] = fma52hi(res[65], a[29], a[35]); // Sum(64) + res[65] = fma52lo(res[65], a[30], a[35]); // Sum(65) + res[66] = fma52hi(res[66], a[30], a[35]); // Sum(65) + res[66] = fma52lo(res[66], a[31], a[35]); // Sum(66) + res[67] = fma52hi(res[67], a[31], a[35]); // Sum(66) + res[67] = fma52lo(res[67], a[32], a[35]); // Sum(67) + res[68] = fma52hi(res[68], a[32], a[35]); // Sum(67) + res[68] = fma52lo(res[68], a[33], a[35]); // Sum(68) + res[69] = fma52hi(res[69], a[33], a[35]); // Sum(68) + res[69] = fma52lo(res[69], a[34], a[35]); // Sum(69) + res[70] = fma52hi(res[70], a[34], a[35]); // Sum(69) + res[60] = fma52lo(res[60], a[24], a[36]); // Sum(60) + res[61] = fma52hi(res[61], a[24], a[36]); // Sum(60) + res[61] = fma52lo(res[61], a[25], a[36]); // Sum(61) + res[62] = fma52hi(res[62], a[25], a[36]); // Sum(61) + res[62] = fma52lo(res[62], a[26], a[36]); // Sum(62) + res[63] = fma52hi(res[63], a[26], a[36]); // Sum(62) + res[63] = fma52lo(res[63], a[27], a[36]); // Sum(63) + res[64] = fma52hi(res[64], a[27], a[36]); // Sum(63) + res[64] = fma52lo(res[64], a[28], a[36]); // Sum(64) + res[65] = fma52hi(res[65], a[28], a[36]); // Sum(64) + res[65] = fma52lo(res[65], a[29], a[36]); // Sum(65) + res[66] = fma52hi(res[66], a[29], a[36]); // Sum(65) + res[66] = fma52lo(res[66], a[30], a[36]); // Sum(66) + res[67] = fma52hi(res[67], a[30], a[36]); // Sum(66) + res[67] = fma52lo(res[67], a[31], a[36]); // Sum(67) + res[68] = fma52hi(res[68], a[31], a[36]); // Sum(67) + res[68] = fma52lo(res[68], a[32], a[36]); // Sum(68) + res[69] = fma52hi(res[69], a[32], a[36]); // Sum(68) + res[69] = fma52lo(res[69], a[33], a[36]); // Sum(69) + res[70] = fma52hi(res[70], a[33], a[36]); // Sum(69) + res[70] = fma52lo(res[70], a[34], a[36]); // Sum(70) + res[71] = fma52hi(res[71], a[34], a[36]); // Sum(70) + res[71] = fma52lo(res[71], a[35], a[36]); // Sum(71) + res[72] = fma52hi(res[72], a[35], a[36]); // Sum(71) + res[60] = fma52lo(res[60], a[23], a[37]); // Sum(60) + res[61] = fma52hi(res[61], a[23], a[37]); // Sum(60) + res[61] = fma52lo(res[61], a[24], a[37]); // Sum(61) + res[62] = fma52hi(res[62], a[24], a[37]); // Sum(61) + res[62] = fma52lo(res[62], a[25], a[37]); // Sum(62) + res[63] = fma52hi(res[63], a[25], a[37]); // Sum(62) + res[63] = fma52lo(res[63], a[26], a[37]); // Sum(63) + res[64] = fma52hi(res[64], a[26], a[37]); // Sum(63) + res[64] = fma52lo(res[64], a[27], a[37]); // Sum(64) + res[65] = fma52hi(res[65], a[27], a[37]); // Sum(64) + res[65] = fma52lo(res[65], a[28], a[37]); // Sum(65) + res[66] = fma52hi(res[66], a[28], a[37]); // Sum(65) + res[66] = fma52lo(res[66], a[29], a[37]); // Sum(66) + res[67] = fma52hi(res[67], a[29], a[37]); // Sum(66) + res[67] = fma52lo(res[67], a[30], a[37]); // Sum(67) + res[68] = fma52hi(res[68], a[30], a[37]); // Sum(67) + res[68] = fma52lo(res[68], a[31], a[37]); // Sum(68) + res[69] = fma52hi(res[69], a[31], a[37]); // Sum(68) + res[69] = fma52lo(res[69], a[32], a[37]); // Sum(69) + res[70] = fma52hi(res[70], a[32], a[37]); // Sum(69) + res[70] = fma52lo(res[70], a[33], a[37]); // Sum(70) + res[71] = fma52hi(res[71], a[33], a[37]); // Sum(70) + res[71] = fma52lo(res[71], a[34], a[37]); // Sum(71) + res[72] = fma52hi(res[72], a[34], a[37]); // Sum(71) + res[60] = fma52lo(res[60], a[22], a[38]); // Sum(60) + res[61] = fma52hi(res[61], a[22], a[38]); // Sum(60) + res[61] = fma52lo(res[61], a[23], a[38]); // Sum(61) + res[62] = fma52hi(res[62], a[23], a[38]); // Sum(61) + res[62] = fma52lo(res[62], a[24], a[38]); // Sum(62) + res[63] = fma52hi(res[63], a[24], a[38]); // Sum(62) + res[63] = fma52lo(res[63], a[25], a[38]); // Sum(63) + res[64] = fma52hi(res[64], a[25], a[38]); // Sum(63) + res[64] = fma52lo(res[64], a[26], a[38]); // Sum(64) + res[65] = fma52hi(res[65], a[26], a[38]); // Sum(64) + res[65] = fma52lo(res[65], a[27], a[38]); // Sum(65) + res[66] = fma52hi(res[66], a[27], a[38]); // Sum(65) + res[66] = fma52lo(res[66], a[28], a[38]); // Sum(66) + res[67] = fma52hi(res[67], a[28], a[38]); // Sum(66) + res[67] = fma52lo(res[67], a[29], a[38]); // Sum(67) + res[68] = fma52hi(res[68], a[29], a[38]); // Sum(67) + res[68] = fma52lo(res[68], a[30], a[38]); // Sum(68) + res[69] = fma52hi(res[69], a[30], a[38]); // Sum(68) + res[69] = fma52lo(res[69], a[31], a[38]); // Sum(69) + res[70] = fma52hi(res[70], a[31], a[38]); // Sum(69) + res[70] = fma52lo(res[70], a[32], a[38]); // Sum(70) + res[71] = fma52hi(res[71], a[32], a[38]); // Sum(70) + res[71] = fma52lo(res[71], a[33], a[38]); // Sum(71) + res[72] = fma52hi(res[72], a[33], a[38]); // Sum(71) + res[60] = fma52lo(res[60], a[21], a[39]); // Sum(60) + res[61] = fma52hi(res[61], a[21], a[39]); // Sum(60) + res[61] = fma52lo(res[61], a[22], a[39]); // Sum(61) + res[62] = fma52hi(res[62], a[22], a[39]); // Sum(61) + res[62] = fma52lo(res[62], a[23], a[39]); // Sum(62) + res[63] = fma52hi(res[63], a[23], a[39]); // Sum(62) + res[63] = fma52lo(res[63], a[24], a[39]); // Sum(63) + res[64] = fma52hi(res[64], a[24], a[39]); // Sum(63) + res[64] = fma52lo(res[64], a[25], a[39]); // Sum(64) + res[65] = fma52hi(res[65], a[25], a[39]); // Sum(64) + res[65] = fma52lo(res[65], a[26], a[39]); // Sum(65) + res[66] = fma52hi(res[66], a[26], a[39]); // Sum(65) + res[66] = fma52lo(res[66], a[27], a[39]); // Sum(66) + res[67] = fma52hi(res[67], a[27], a[39]); // Sum(66) + res[67] = fma52lo(res[67], a[28], a[39]); // Sum(67) + res[68] = fma52hi(res[68], a[28], a[39]); // Sum(67) + res[68] = fma52lo(res[68], a[29], a[39]); // Sum(68) + res[69] = fma52hi(res[69], a[29], a[39]); // Sum(68) + res[69] = fma52lo(res[69], a[30], a[39]); // Sum(69) + res[70] = fma52hi(res[70], a[30], a[39]); // Sum(69) + res[70] = fma52lo(res[70], a[31], a[39]); // Sum(70) + res[71] = fma52hi(res[71], a[31], a[39]); // Sum(70) + res[71] = fma52lo(res[71], a[32], a[39]); // Sum(71) + res[72] = fma52hi(res[72], a[32], a[39]); // Sum(71) + res[60] = fma52lo(res[60], a[20], a[40]); // Sum(60) + res[61] = fma52hi(res[61], a[20], a[40]); // Sum(60) + res[61] = fma52lo(res[61], a[21], a[40]); // Sum(61) + res[62] = fma52hi(res[62], a[21], a[40]); // Sum(61) + res[62] = fma52lo(res[62], a[22], a[40]); // Sum(62) + res[63] = fma52hi(res[63], a[22], a[40]); // Sum(62) + res[63] = fma52lo(res[63], a[23], a[40]); // Sum(63) + res[64] = fma52hi(res[64], a[23], a[40]); // Sum(63) + res[64] = fma52lo(res[64], a[24], a[40]); // Sum(64) + res[65] = fma52hi(res[65], a[24], a[40]); // Sum(64) + res[65] = fma52lo(res[65], a[25], a[40]); // Sum(65) + res[66] = fma52hi(res[66], a[25], a[40]); // Sum(65) + res[66] = fma52lo(res[66], a[26], a[40]); // Sum(66) + res[67] = fma52hi(res[67], a[26], a[40]); // Sum(66) + res[67] = fma52lo(res[67], a[27], a[40]); // Sum(67) + res[68] = fma52hi(res[68], a[27], a[40]); // Sum(67) + res[68] = fma52lo(res[68], a[28], a[40]); // Sum(68) + res[69] = fma52hi(res[69], a[28], a[40]); // Sum(68) + res[69] = fma52lo(res[69], a[29], a[40]); // Sum(69) + res[70] = fma52hi(res[70], a[29], a[40]); // Sum(69) + res[70] = fma52lo(res[70], a[30], a[40]); // Sum(70) + res[71] = fma52hi(res[71], a[30], a[40]); // Sum(70) + res[71] = fma52lo(res[71], a[31], a[40]); // Sum(71) + res[72] = fma52hi(res[72], a[31], a[40]); // Sum(71) + res[60] = fma52lo(res[60], a[19], a[41]); // Sum(60) + res[61] = fma52hi(res[61], a[19], a[41]); // Sum(60) + res[61] = fma52lo(res[61], a[20], a[41]); // Sum(61) + res[62] = fma52hi(res[62], a[20], a[41]); // Sum(61) + res[62] = fma52lo(res[62], a[21], a[41]); // Sum(62) + res[63] = fma52hi(res[63], a[21], a[41]); // Sum(62) + res[63] = fma52lo(res[63], a[22], a[41]); // Sum(63) + res[64] = fma52hi(res[64], a[22], a[41]); // Sum(63) + res[64] = fma52lo(res[64], a[23], a[41]); // Sum(64) + res[65] = fma52hi(res[65], a[23], a[41]); // Sum(64) + res[65] = fma52lo(res[65], a[24], a[41]); // Sum(65) + res[66] = fma52hi(res[66], a[24], a[41]); // Sum(65) + res[66] = fma52lo(res[66], a[25], a[41]); // Sum(66) + res[67] = fma52hi(res[67], a[25], a[41]); // Sum(66) + res[67] = fma52lo(res[67], a[26], a[41]); // Sum(67) + res[68] = fma52hi(res[68], a[26], a[41]); // Sum(67) + res[68] = fma52lo(res[68], a[27], a[41]); // Sum(68) + res[69] = fma52hi(res[69], a[27], a[41]); // Sum(68) + res[69] = fma52lo(res[69], a[28], a[41]); // Sum(69) + res[70] = fma52hi(res[70], a[28], a[41]); // Sum(69) + res[70] = fma52lo(res[70], a[29], a[41]); // Sum(70) + res[71] = fma52hi(res[71], a[29], a[41]); // Sum(70) + res[71] = fma52lo(res[71], a[30], a[41]); // Sum(71) + res[72] = fma52hi(res[72], a[30], a[41]); // Sum(71) + res[60] = fma52lo(res[60], a[18], a[42]); // Sum(60) + res[61] = fma52hi(res[61], a[18], a[42]); // Sum(60) + res[61] = fma52lo(res[61], a[19], a[42]); // Sum(61) + res[62] = fma52hi(res[62], a[19], a[42]); // Sum(61) + res[62] = fma52lo(res[62], a[20], a[42]); // Sum(62) + res[63] = fma52hi(res[63], a[20], a[42]); // Sum(62) + res[63] = fma52lo(res[63], a[21], a[42]); // Sum(63) + res[64] = fma52hi(res[64], a[21], a[42]); // Sum(63) + res[64] = fma52lo(res[64], a[22], a[42]); // Sum(64) + res[65] = fma52hi(res[65], a[22], a[42]); // Sum(64) + res[65] = fma52lo(res[65], a[23], a[42]); // Sum(65) + res[66] = fma52hi(res[66], a[23], a[42]); // Sum(65) + res[66] = fma52lo(res[66], a[24], a[42]); // Sum(66) + res[67] = fma52hi(res[67], a[24], a[42]); // Sum(66) + res[67] = fma52lo(res[67], a[25], a[42]); // Sum(67) + res[68] = fma52hi(res[68], a[25], a[42]); // Sum(67) + res[68] = fma52lo(res[68], a[26], a[42]); // Sum(68) + res[69] = fma52hi(res[69], a[26], a[42]); // Sum(68) + res[69] = fma52lo(res[69], a[27], a[42]); // Sum(69) + res[70] = fma52hi(res[70], a[27], a[42]); // Sum(69) + res[70] = fma52lo(res[70], a[28], a[42]); // Sum(70) + res[71] = fma52hi(res[71], a[28], a[42]); // Sum(70) + res[71] = fma52lo(res[71], a[29], a[42]); // Sum(71) + res[72] = fma52hi(res[72], a[29], a[42]); // Sum(71) + res[60] = fma52lo(res[60], a[17], a[43]); // Sum(60) + res[61] = fma52hi(res[61], a[17], a[43]); // Sum(60) + res[61] = fma52lo(res[61], a[18], a[43]); // Sum(61) + res[62] = fma52hi(res[62], a[18], a[43]); // Sum(61) + res[62] = fma52lo(res[62], a[19], a[43]); // Sum(62) + res[63] = fma52hi(res[63], a[19], a[43]); // Sum(62) + res[63] = fma52lo(res[63], a[20], a[43]); // Sum(63) + res[64] = fma52hi(res[64], a[20], a[43]); // Sum(63) + res[64] = fma52lo(res[64], a[21], a[43]); // Sum(64) + res[65] = fma52hi(res[65], a[21], a[43]); // Sum(64) + res[65] = fma52lo(res[65], a[22], a[43]); // Sum(65) + res[66] = fma52hi(res[66], a[22], a[43]); // Sum(65) + res[66] = fma52lo(res[66], a[23], a[43]); // Sum(66) + res[67] = fma52hi(res[67], a[23], a[43]); // Sum(66) + res[67] = fma52lo(res[67], a[24], a[43]); // Sum(67) + res[68] = fma52hi(res[68], a[24], a[43]); // Sum(67) + res[68] = fma52lo(res[68], a[25], a[43]); // Sum(68) + res[69] = fma52hi(res[69], a[25], a[43]); // Sum(68) + res[69] = fma52lo(res[69], a[26], a[43]); // Sum(69) + res[70] = fma52hi(res[70], a[26], a[43]); // Sum(69) + res[70] = fma52lo(res[70], a[27], a[43]); // Sum(70) + res[71] = fma52hi(res[71], a[27], a[43]); // Sum(70) + res[71] = fma52lo(res[71], a[28], a[43]); // Sum(71) + res[72] = fma52hi(res[72], a[28], a[43]); // Sum(71) + res[60] = fma52lo(res[60], a[16], a[44]); // Sum(60) + res[61] = fma52hi(res[61], a[16], a[44]); // Sum(60) + res[61] = fma52lo(res[61], a[17], a[44]); // Sum(61) + res[62] = fma52hi(res[62], a[17], a[44]); // Sum(61) + res[62] = fma52lo(res[62], a[18], a[44]); // Sum(62) + res[63] = fma52hi(res[63], a[18], a[44]); // Sum(62) + res[63] = fma52lo(res[63], a[19], a[44]); // Sum(63) + res[64] = fma52hi(res[64], a[19], a[44]); // Sum(63) + res[64] = fma52lo(res[64], a[20], a[44]); // Sum(64) + res[65] = fma52hi(res[65], a[20], a[44]); // Sum(64) + res[65] = fma52lo(res[65], a[21], a[44]); // Sum(65) + res[66] = fma52hi(res[66], a[21], a[44]); // Sum(65) + res[66] = fma52lo(res[66], a[22], a[44]); // Sum(66) + res[67] = fma52hi(res[67], a[22], a[44]); // Sum(66) + res[67] = fma52lo(res[67], a[23], a[44]); // Sum(67) + res[68] = fma52hi(res[68], a[23], a[44]); // Sum(67) + res[68] = fma52lo(res[68], a[24], a[44]); // Sum(68) + res[69] = fma52hi(res[69], a[24], a[44]); // Sum(68) + res[69] = fma52lo(res[69], a[25], a[44]); // Sum(69) + res[70] = fma52hi(res[70], a[25], a[44]); // Sum(69) + res[70] = fma52lo(res[70], a[26], a[44]); // Sum(70) + res[71] = fma52hi(res[71], a[26], a[44]); // Sum(70) + res[71] = fma52lo(res[71], a[27], a[44]); // Sum(71) + res[72] = fma52hi(res[72], a[27], a[44]); // Sum(71) + res[60] = fma52lo(res[60], a[15], a[45]); // Sum(60) + res[61] = fma52hi(res[61], a[15], a[45]); // Sum(60) + res[61] = fma52lo(res[61], a[16], a[45]); // Sum(61) + res[62] = fma52hi(res[62], a[16], a[45]); // Sum(61) + res[62] = fma52lo(res[62], a[17], a[45]); // Sum(62) + res[63] = fma52hi(res[63], a[17], a[45]); // Sum(62) + res[63] = fma52lo(res[63], a[18], a[45]); // Sum(63) + res[64] = fma52hi(res[64], a[18], a[45]); // Sum(63) + res[64] = fma52lo(res[64], a[19], a[45]); // Sum(64) + res[65] = fma52hi(res[65], a[19], a[45]); // Sum(64) + res[65] = fma52lo(res[65], a[20], a[45]); // Sum(65) + res[66] = fma52hi(res[66], a[20], a[45]); // Sum(65) + res[66] = fma52lo(res[66], a[21], a[45]); // Sum(66) + res[67] = fma52hi(res[67], a[21], a[45]); // Sum(66) + res[67] = fma52lo(res[67], a[22], a[45]); // Sum(67) + res[68] = fma52hi(res[68], a[22], a[45]); // Sum(67) + res[68] = fma52lo(res[68], a[23], a[45]); // Sum(68) + res[69] = fma52hi(res[69], a[23], a[45]); // Sum(68) + res[69] = fma52lo(res[69], a[24], a[45]); // Sum(69) + res[70] = fma52hi(res[70], a[24], a[45]); // Sum(69) + res[70] = fma52lo(res[70], a[25], a[45]); // Sum(70) + res[71] = fma52hi(res[71], a[25], a[45]); // Sum(70) + res[71] = fma52lo(res[71], a[26], a[45]); // Sum(71) + res[72] = fma52hi(res[72], a[26], a[45]); // Sum(71) + res[60] = fma52lo(res[60], a[14], a[46]); // Sum(60) + res[61] = fma52hi(res[61], a[14], a[46]); // Sum(60) + res[61] = fma52lo(res[61], a[15], a[46]); // Sum(61) + res[62] = fma52hi(res[62], a[15], a[46]); // Sum(61) + res[62] = fma52lo(res[62], a[16], a[46]); // Sum(62) + res[63] = fma52hi(res[63], a[16], a[46]); // Sum(62) + res[63] = fma52lo(res[63], a[17], a[46]); // Sum(63) + res[64] = fma52hi(res[64], a[17], a[46]); // Sum(63) + res[64] = fma52lo(res[64], a[18], a[46]); // Sum(64) + res[65] = fma52hi(res[65], a[18], a[46]); // Sum(64) + res[65] = fma52lo(res[65], a[19], a[46]); // Sum(65) + res[66] = fma52hi(res[66], a[19], a[46]); // Sum(65) + res[66] = fma52lo(res[66], a[20], a[46]); // Sum(66) + res[67] = fma52hi(res[67], a[20], a[46]); // Sum(66) + res[67] = fma52lo(res[67], a[21], a[46]); // Sum(67) + res[68] = fma52hi(res[68], a[21], a[46]); // Sum(67) + res[68] = fma52lo(res[68], a[22], a[46]); // Sum(68) + res[69] = fma52hi(res[69], a[22], a[46]); // Sum(68) + res[69] = fma52lo(res[69], a[23], a[46]); // Sum(69) + res[70] = fma52hi(res[70], a[23], a[46]); // Sum(69) + res[70] = fma52lo(res[70], a[24], a[46]); // Sum(70) + res[71] = fma52hi(res[71], a[24], a[46]); // Sum(70) + res[71] = fma52lo(res[71], a[25], a[46]); // Sum(71) + res[72] = fma52hi(res[72], a[25], a[46]); // Sum(71) + res[60] = fma52lo(res[60], a[13], a[47]); // Sum(60) + res[61] = fma52hi(res[61], a[13], a[47]); // Sum(60) + res[61] = fma52lo(res[61], a[14], a[47]); // Sum(61) + res[62] = fma52hi(res[62], a[14], a[47]); // Sum(61) + res[62] = fma52lo(res[62], a[15], a[47]); // Sum(62) + res[63] = fma52hi(res[63], a[15], a[47]); // Sum(62) + res[63] = fma52lo(res[63], a[16], a[47]); // Sum(63) + res[64] = fma52hi(res[64], a[16], a[47]); // Sum(63) + res[64] = fma52lo(res[64], a[17], a[47]); // Sum(64) + res[65] = fma52hi(res[65], a[17], a[47]); // Sum(64) + res[65] = fma52lo(res[65], a[18], a[47]); // Sum(65) + res[66] = fma52hi(res[66], a[18], a[47]); // Sum(65) + res[66] = fma52lo(res[66], a[19], a[47]); // Sum(66) + res[67] = fma52hi(res[67], a[19], a[47]); // Sum(66) + res[67] = fma52lo(res[67], a[20], a[47]); // Sum(67) + res[68] = fma52hi(res[68], a[20], a[47]); // Sum(67) + res[68] = fma52lo(res[68], a[21], a[47]); // Sum(68) + res[69] = fma52hi(res[69], a[21], a[47]); // Sum(68) + res[69] = fma52lo(res[69], a[22], a[47]); // Sum(69) + res[70] = fma52hi(res[70], a[22], a[47]); // Sum(69) + res[70] = fma52lo(res[70], a[23], a[47]); // Sum(70) + res[71] = fma52hi(res[71], a[23], a[47]); // Sum(70) + res[71] = fma52lo(res[71], a[24], a[47]); // Sum(71) + res[72] = fma52hi(res[72], a[24], a[47]); // Sum(71) + res[60] = fma52lo(res[60], a[12], a[48]); // Sum(60) + res[61] = fma52hi(res[61], a[12], a[48]); // Sum(60) + res[61] = fma52lo(res[61], a[13], a[48]); // Sum(61) + res[62] = fma52hi(res[62], a[13], a[48]); // Sum(61) + res[62] = fma52lo(res[62], a[14], a[48]); // Sum(62) + res[63] = fma52hi(res[63], a[14], a[48]); // Sum(62) + res[63] = fma52lo(res[63], a[15], a[48]); // Sum(63) + res[64] = fma52hi(res[64], a[15], a[48]); // Sum(63) + res[64] = fma52lo(res[64], a[16], a[48]); // Sum(64) + res[65] = fma52hi(res[65], a[16], a[48]); // Sum(64) + res[65] = fma52lo(res[65], a[17], a[48]); // Sum(65) + res[66] = fma52hi(res[66], a[17], a[48]); // Sum(65) + res[66] = fma52lo(res[66], a[18], a[48]); // Sum(66) + res[67] = fma52hi(res[67], a[18], a[48]); // Sum(66) + res[67] = fma52lo(res[67], a[19], a[48]); // Sum(67) + res[68] = fma52hi(res[68], a[19], a[48]); // Sum(67) + res[68] = fma52lo(res[68], a[20], a[48]); // Sum(68) + res[69] = fma52hi(res[69], a[20], a[48]); // Sum(68) + res[69] = fma52lo(res[69], a[21], a[48]); // Sum(69) + res[70] = fma52hi(res[70], a[21], a[48]); // Sum(69) + res[70] = fma52lo(res[70], a[22], a[48]); // Sum(70) + res[71] = fma52hi(res[71], a[22], a[48]); // Sum(70) + res[71] = fma52lo(res[71], a[23], a[48]); // Sum(71) + res[72] = fma52hi(res[72], a[23], a[48]); // Sum(71) + res[60] = fma52lo(res[60], a[11], a[49]); // Sum(60) + res[61] = fma52hi(res[61], a[11], a[49]); // Sum(60) + res[61] = fma52lo(res[61], a[12], a[49]); // Sum(61) + res[62] = fma52hi(res[62], a[12], a[49]); // Sum(61) + res[62] = fma52lo(res[62], a[13], a[49]); // Sum(62) + res[63] = fma52hi(res[63], a[13], a[49]); // Sum(62) + res[63] = fma52lo(res[63], a[14], a[49]); // Sum(63) + res[64] = fma52hi(res[64], a[14], a[49]); // Sum(63) + res[64] = fma52lo(res[64], a[15], a[49]); // Sum(64) + res[65] = fma52hi(res[65], a[15], a[49]); // Sum(64) + res[65] = fma52lo(res[65], a[16], a[49]); // Sum(65) + res[66] = fma52hi(res[66], a[16], a[49]); // Sum(65) + res[66] = fma52lo(res[66], a[17], a[49]); // Sum(66) + res[67] = fma52hi(res[67], a[17], a[49]); // Sum(66) + res[67] = fma52lo(res[67], a[18], a[49]); // Sum(67) + res[68] = fma52hi(res[68], a[18], a[49]); // Sum(67) + res[68] = fma52lo(res[68], a[19], a[49]); // Sum(68) + res[69] = fma52hi(res[69], a[19], a[49]); // Sum(68) + res[69] = fma52lo(res[69], a[20], a[49]); // Sum(69) + res[70] = fma52hi(res[70], a[20], a[49]); // Sum(69) + res[70] = fma52lo(res[70], a[21], a[49]); // Sum(70) + res[71] = fma52hi(res[71], a[21], a[49]); // Sum(70) + res[71] = fma52lo(res[71], a[22], a[49]); // Sum(71) + res[72] = fma52hi(res[72], a[22], a[49]); // Sum(71) + res[60] = fma52lo(res[60], a[10], a[50]); // Sum(60) + res[61] = fma52hi(res[61], a[10], a[50]); // Sum(60) + res[61] = fma52lo(res[61], a[11], a[50]); // Sum(61) + res[62] = fma52hi(res[62], a[11], a[50]); // Sum(61) + res[62] = fma52lo(res[62], a[12], a[50]); // Sum(62) + res[63] = fma52hi(res[63], a[12], a[50]); // Sum(62) + res[63] = fma52lo(res[63], a[13], a[50]); // Sum(63) + res[64] = fma52hi(res[64], a[13], a[50]); // Sum(63) + res[64] = fma52lo(res[64], a[14], a[50]); // Sum(64) + res[65] = fma52hi(res[65], a[14], a[50]); // Sum(64) + res[65] = fma52lo(res[65], a[15], a[50]); // Sum(65) + res[66] = fma52hi(res[66], a[15], a[50]); // Sum(65) + res[66] = fma52lo(res[66], a[16], a[50]); // Sum(66) + res[67] = fma52hi(res[67], a[16], a[50]); // Sum(66) + res[67] = fma52lo(res[67], a[17], a[50]); // Sum(67) + res[68] = fma52hi(res[68], a[17], a[50]); // Sum(67) + res[68] = fma52lo(res[68], a[18], a[50]); // Sum(68) + res[69] = fma52hi(res[69], a[18], a[50]); // Sum(68) + res[69] = fma52lo(res[69], a[19], a[50]); // Sum(69) + res[70] = fma52hi(res[70], a[19], a[50]); // Sum(69) + res[70] = fma52lo(res[70], a[20], a[50]); // Sum(70) + res[71] = fma52hi(res[71], a[20], a[50]); // Sum(70) + res[71] = fma52lo(res[71], a[21], a[50]); // Sum(71) + res[72] = fma52hi(res[72], a[21], a[50]); // Sum(71) + res[60] = fma52lo(res[60], a[9], a[51]); // Sum(60) + res[61] = fma52hi(res[61], a[9], a[51]); // Sum(60) + res[61] = fma52lo(res[61], a[10], a[51]); // Sum(61) + res[62] = fma52hi(res[62], a[10], a[51]); // Sum(61) + res[62] = fma52lo(res[62], a[11], a[51]); // Sum(62) + res[63] = fma52hi(res[63], a[11], a[51]); // Sum(62) + res[63] = fma52lo(res[63], a[12], a[51]); // Sum(63) + res[64] = fma52hi(res[64], a[12], a[51]); // Sum(63) + res[64] = fma52lo(res[64], a[13], a[51]); // Sum(64) + res[65] = fma52hi(res[65], a[13], a[51]); // Sum(64) + res[65] = fma52lo(res[65], a[14], a[51]); // Sum(65) + res[66] = fma52hi(res[66], a[14], a[51]); // Sum(65) + res[66] = fma52lo(res[66], a[15], a[51]); // Sum(66) + res[67] = fma52hi(res[67], a[15], a[51]); // Sum(66) + res[67] = fma52lo(res[67], a[16], a[51]); // Sum(67) + res[68] = fma52hi(res[68], a[16], a[51]); // Sum(67) + res[68] = fma52lo(res[68], a[17], a[51]); // Sum(68) + res[69] = fma52hi(res[69], a[17], a[51]); // Sum(68) + res[69] = fma52lo(res[69], a[18], a[51]); // Sum(69) + res[70] = fma52hi(res[70], a[18], a[51]); // Sum(69) + res[70] = fma52lo(res[70], a[19], a[51]); // Sum(70) + res[71] = fma52hi(res[71], a[19], a[51]); // Sum(70) + res[71] = fma52lo(res[71], a[20], a[51]); // Sum(71) + res[72] = fma52hi(res[72], a[20], a[51]); // Sum(71) + res[60] = fma52lo(res[60], a[8], a[52]); // Sum(60) + res[61] = fma52hi(res[61], a[8], a[52]); // Sum(60) + res[61] = fma52lo(res[61], a[9], a[52]); // Sum(61) + res[62] = fma52hi(res[62], a[9], a[52]); // Sum(61) + res[62] = fma52lo(res[62], a[10], a[52]); // Sum(62) + res[63] = fma52hi(res[63], a[10], a[52]); // Sum(62) + res[63] = fma52lo(res[63], a[11], a[52]); // Sum(63) + res[64] = fma52hi(res[64], a[11], a[52]); // Sum(63) + res[64] = fma52lo(res[64], a[12], a[52]); // Sum(64) + res[65] = fma52hi(res[65], a[12], a[52]); // Sum(64) + res[65] = fma52lo(res[65], a[13], a[52]); // Sum(65) + res[66] = fma52hi(res[66], a[13], a[52]); // Sum(65) + res[66] = fma52lo(res[66], a[14], a[52]); // Sum(66) + res[67] = fma52hi(res[67], a[14], a[52]); // Sum(66) + res[67] = fma52lo(res[67], a[15], a[52]); // Sum(67) + res[68] = fma52hi(res[68], a[15], a[52]); // Sum(67) + res[68] = fma52lo(res[68], a[16], a[52]); // Sum(68) + res[69] = fma52hi(res[69], a[16], a[52]); // Sum(68) + res[69] = fma52lo(res[69], a[17], a[52]); // Sum(69) + res[70] = fma52hi(res[70], a[17], a[52]); // Sum(69) + res[70] = fma52lo(res[70], a[18], a[52]); // Sum(70) + res[71] = fma52hi(res[71], a[18], a[52]); // Sum(70) + res[71] = fma52lo(res[71], a[19], a[52]); // Sum(71) + res[72] = fma52hi(res[72], a[19], a[52]); // Sum(71) + res[60] = fma52lo(res[60], a[7], a[53]); // Sum(60) + res[61] = fma52hi(res[61], a[7], a[53]); // Sum(60) + res[61] = fma52lo(res[61], a[8], a[53]); // Sum(61) + res[62] = fma52hi(res[62], a[8], a[53]); // Sum(61) + res[62] = fma52lo(res[62], a[9], a[53]); // Sum(62) + res[63] = fma52hi(res[63], a[9], a[53]); // Sum(62) + res[63] = fma52lo(res[63], a[10], a[53]); // Sum(63) + res[64] = fma52hi(res[64], a[10], a[53]); // Sum(63) + res[64] = fma52lo(res[64], a[11], a[53]); // Sum(64) + res[65] = fma52hi(res[65], a[11], a[53]); // Sum(64) + res[65] = fma52lo(res[65], a[12], a[53]); // Sum(65) + res[66] = fma52hi(res[66], a[12], a[53]); // Sum(65) + res[66] = fma52lo(res[66], a[13], a[53]); // Sum(66) + res[67] = fma52hi(res[67], a[13], a[53]); // Sum(66) + res[67] = fma52lo(res[67], a[14], a[53]); // Sum(67) + res[68] = fma52hi(res[68], a[14], a[53]); // Sum(67) + res[68] = fma52lo(res[68], a[15], a[53]); // Sum(68) + res[69] = fma52hi(res[69], a[15], a[53]); // Sum(68) + res[69] = fma52lo(res[69], a[16], a[53]); // Sum(69) + res[70] = fma52hi(res[70], a[16], a[53]); // Sum(69) + res[70] = fma52lo(res[70], a[17], a[53]); // Sum(70) + res[71] = fma52hi(res[71], a[17], a[53]); // Sum(70) + res[71] = fma52lo(res[71], a[18], a[53]); // Sum(71) + res[72] = fma52hi(res[72], a[18], a[53]); // Sum(71) + res[60] = fma52lo(res[60], a[6], a[54]); // Sum(60) + res[61] = fma52hi(res[61], a[6], a[54]); // Sum(60) + res[61] = fma52lo(res[61], a[7], a[54]); // Sum(61) + res[62] = fma52hi(res[62], a[7], a[54]); // Sum(61) + res[62] = fma52lo(res[62], a[8], a[54]); // Sum(62) + res[63] = fma52hi(res[63], a[8], a[54]); // Sum(62) + res[63] = fma52lo(res[63], a[9], a[54]); // Sum(63) + res[64] = fma52hi(res[64], a[9], a[54]); // Sum(63) + res[64] = fma52lo(res[64], a[10], a[54]); // Sum(64) + res[65] = fma52hi(res[65], a[10], a[54]); // Sum(64) + res[65] = fma52lo(res[65], a[11], a[54]); // Sum(65) + res[66] = fma52hi(res[66], a[11], a[54]); // Sum(65) + res[66] = fma52lo(res[66], a[12], a[54]); // Sum(66) + res[67] = fma52hi(res[67], a[12], a[54]); // Sum(66) + res[67] = fma52lo(res[67], a[13], a[54]); // Sum(67) + res[68] = fma52hi(res[68], a[13], a[54]); // Sum(67) + res[68] = fma52lo(res[68], a[14], a[54]); // Sum(68) + res[69] = fma52hi(res[69], a[14], a[54]); // Sum(68) + res[69] = fma52lo(res[69], a[15], a[54]); // Sum(69) + res[70] = fma52hi(res[70], a[15], a[54]); // Sum(69) + res[70] = fma52lo(res[70], a[16], a[54]); // Sum(70) + res[71] = fma52hi(res[71], a[16], a[54]); // Sum(70) + res[71] = fma52lo(res[71], a[17], a[54]); // Sum(71) + res[72] = fma52hi(res[72], a[17], a[54]); // Sum(71) + res[60] = fma52lo(res[60], a[5], a[55]); // Sum(60) + res[61] = fma52hi(res[61], a[5], a[55]); // Sum(60) + res[61] = fma52lo(res[61], a[6], a[55]); // Sum(61) + res[62] = fma52hi(res[62], a[6], a[55]); // Sum(61) + res[62] = fma52lo(res[62], a[7], a[55]); // Sum(62) + res[63] = fma52hi(res[63], a[7], a[55]); // Sum(62) + res[63] = fma52lo(res[63], a[8], a[55]); // Sum(63) + res[64] = fma52hi(res[64], a[8], a[55]); // Sum(63) + res[64] = fma52lo(res[64], a[9], a[55]); // Sum(64) + res[65] = fma52hi(res[65], a[9], a[55]); // Sum(64) + res[65] = fma52lo(res[65], a[10], a[55]); // Sum(65) + res[66] = fma52hi(res[66], a[10], a[55]); // Sum(65) + res[66] = fma52lo(res[66], a[11], a[55]); // Sum(66) + res[67] = fma52hi(res[67], a[11], a[55]); // Sum(66) + res[67] = fma52lo(res[67], a[12], a[55]); // Sum(67) + res[68] = fma52hi(res[68], a[12], a[55]); // Sum(67) + res[68] = fma52lo(res[68], a[13], a[55]); // Sum(68) + res[69] = fma52hi(res[69], a[13], a[55]); // Sum(68) + res[69] = fma52lo(res[69], a[14], a[55]); // Sum(69) + res[70] = fma52hi(res[70], a[14], a[55]); // Sum(69) + res[70] = fma52lo(res[70], a[15], a[55]); // Sum(70) + res[71] = fma52hi(res[71], a[15], a[55]); // Sum(70) + res[71] = fma52lo(res[71], a[16], a[55]); // Sum(71) + res[72] = fma52hi(res[72], a[16], a[55]); // Sum(71) + res[60] = fma52lo(res[60], a[4], a[56]); // Sum(60) + res[61] = fma52hi(res[61], a[4], a[56]); // Sum(60) + res[61] = fma52lo(res[61], a[5], a[56]); // Sum(61) + res[62] = fma52hi(res[62], a[5], a[56]); // Sum(61) + res[62] = fma52lo(res[62], a[6], a[56]); // Sum(62) + res[63] = fma52hi(res[63], a[6], a[56]); // Sum(62) + res[63] = fma52lo(res[63], a[7], a[56]); // Sum(63) + res[64] = fma52hi(res[64], a[7], a[56]); // Sum(63) + res[64] = fma52lo(res[64], a[8], a[56]); // Sum(64) + res[65] = fma52hi(res[65], a[8], a[56]); // Sum(64) + res[65] = fma52lo(res[65], a[9], a[56]); // Sum(65) + res[66] = fma52hi(res[66], a[9], a[56]); // Sum(65) + res[66] = fma52lo(res[66], a[10], a[56]); // Sum(66) + res[67] = fma52hi(res[67], a[10], a[56]); // Sum(66) + res[67] = fma52lo(res[67], a[11], a[56]); // Sum(67) + res[68] = fma52hi(res[68], a[11], a[56]); // Sum(67) + res[68] = fma52lo(res[68], a[12], a[56]); // Sum(68) + res[69] = fma52hi(res[69], a[12], a[56]); // Sum(68) + res[69] = fma52lo(res[69], a[13], a[56]); // Sum(69) + res[70] = fma52hi(res[70], a[13], a[56]); // Sum(69) + res[70] = fma52lo(res[70], a[14], a[56]); // Sum(70) + res[71] = fma52hi(res[71], a[14], a[56]); // Sum(70) + res[71] = fma52lo(res[71], a[15], a[56]); // Sum(71) + res[72] = fma52hi(res[72], a[15], a[56]); // Sum(71) + res[60] = fma52lo(res[60], a[3], a[57]); // Sum(60) + res[61] = fma52hi(res[61], a[3], a[57]); // Sum(60) + res[61] = fma52lo(res[61], a[4], a[57]); // Sum(61) + res[62] = fma52hi(res[62], a[4], a[57]); // Sum(61) + res[62] = fma52lo(res[62], a[5], a[57]); // Sum(62) + res[63] = fma52hi(res[63], a[5], a[57]); // Sum(62) + res[63] = fma52lo(res[63], a[6], a[57]); // Sum(63) + res[64] = fma52hi(res[64], a[6], a[57]); // Sum(63) + res[64] = fma52lo(res[64], a[7], a[57]); // Sum(64) + res[65] = fma52hi(res[65], a[7], a[57]); // Sum(64) + res[65] = fma52lo(res[65], a[8], a[57]); // Sum(65) + res[66] = fma52hi(res[66], a[8], a[57]); // Sum(65) + res[66] = fma52lo(res[66], a[9], a[57]); // Sum(66) + res[67] = fma52hi(res[67], a[9], a[57]); // Sum(66) + res[67] = fma52lo(res[67], a[10], a[57]); // Sum(67) + res[68] = fma52hi(res[68], a[10], a[57]); // Sum(67) + res[68] = fma52lo(res[68], a[11], a[57]); // Sum(68) + res[69] = fma52hi(res[69], a[11], a[57]); // Sum(68) + res[69] = fma52lo(res[69], a[12], a[57]); // Sum(69) + res[70] = fma52hi(res[70], a[12], a[57]); // Sum(69) + res[70] = fma52lo(res[70], a[13], a[57]); // Sum(70) + res[71] = fma52hi(res[71], a[13], a[57]); // Sum(70) + res[71] = fma52lo(res[71], a[14], a[57]); // Sum(71) + res[72] = fma52hi(res[72], a[14], a[57]); // Sum(71) + res[60] = fma52lo(res[60], a[2], a[58]); // Sum(60) + res[61] = fma52hi(res[61], a[2], a[58]); // Sum(60) + res[61] = fma52lo(res[61], a[3], a[58]); // Sum(61) + res[62] = fma52hi(res[62], a[3], a[58]); // Sum(61) + res[62] = fma52lo(res[62], a[4], a[58]); // Sum(62) + res[63] = fma52hi(res[63], a[4], a[58]); // Sum(62) + res[63] = fma52lo(res[63], a[5], a[58]); // Sum(63) + res[64] = fma52hi(res[64], a[5], a[58]); // Sum(63) + res[64] = fma52lo(res[64], a[6], a[58]); // Sum(64) + res[65] = fma52hi(res[65], a[6], a[58]); // Sum(64) + res[65] = fma52lo(res[65], a[7], a[58]); // Sum(65) + res[66] = fma52hi(res[66], a[7], a[58]); // Sum(65) + res[66] = fma52lo(res[66], a[8], a[58]); // Sum(66) + res[67] = fma52hi(res[67], a[8], a[58]); // Sum(66) + res[67] = fma52lo(res[67], a[9], a[58]); // Sum(67) + res[68] = fma52hi(res[68], a[9], a[58]); // Sum(67) + res[68] = fma52lo(res[68], a[10], a[58]); // Sum(68) + res[69] = fma52hi(res[69], a[10], a[58]); // Sum(68) + res[69] = fma52lo(res[69], a[11], a[58]); // Sum(69) + res[70] = fma52hi(res[70], a[11], a[58]); // Sum(69) + res[70] = fma52lo(res[70], a[12], a[58]); // Sum(70) + res[71] = fma52hi(res[71], a[12], a[58]); // Sum(70) + res[71] = fma52lo(res[71], a[13], a[58]); // Sum(71) + res[72] = fma52hi(res[72], a[13], a[58]); // Sum(71) + res[60] = fma52lo(res[60], a[1], a[59]); // Sum(60) + res[61] = fma52hi(res[61], a[1], a[59]); // Sum(60) + res[61] = fma52lo(res[61], a[2], a[59]); // Sum(61) + res[62] = fma52hi(res[62], a[2], a[59]); // Sum(61) + res[62] = fma52lo(res[62], a[3], a[59]); // Sum(62) + res[63] = fma52hi(res[63], a[3], a[59]); // Sum(62) + res[63] = fma52lo(res[63], a[4], a[59]); // Sum(63) + res[64] = fma52hi(res[64], a[4], a[59]); // Sum(63) + res[64] = fma52lo(res[64], a[5], a[59]); // Sum(64) + res[65] = fma52hi(res[65], a[5], a[59]); // Sum(64) + res[65] = fma52lo(res[65], a[6], a[59]); // Sum(65) + res[66] = fma52hi(res[66], a[6], a[59]); // Sum(65) + res[66] = fma52lo(res[66], a[7], a[59]); // Sum(66) + res[67] = fma52hi(res[67], a[7], a[59]); // Sum(66) + res[67] = fma52lo(res[67], a[8], a[59]); // Sum(67) + res[68] = fma52hi(res[68], a[8], a[59]); // Sum(67) + res[68] = fma52lo(res[68], a[9], a[59]); // Sum(68) + res[69] = fma52hi(res[69], a[9], a[59]); // Sum(68) + res[69] = fma52lo(res[69], a[10], a[59]); // Sum(69) + res[70] = fma52hi(res[70], a[10], a[59]); // Sum(69) + res[70] = fma52lo(res[70], a[11], a[59]); // Sum(70) + res[71] = fma52hi(res[71], a[11], a[59]); // Sum(70) + res[71] = fma52lo(res[71], a[12], a[59]); // Sum(71) + res[72] = fma52hi(res[72], a[12], a[59]); // Sum(71) + res[60] = fma52lo(res[60], a[0], a[60]); // Sum(60) + res[61] = fma52hi(res[61], a[0], a[60]); // Sum(60) + res[61] = fma52lo(res[61], a[1], a[60]); // Sum(61) + res[62] = fma52hi(res[62], a[1], a[60]); // Sum(61) + res[62] = fma52lo(res[62], a[2], a[60]); // Sum(62) + res[63] = fma52hi(res[63], a[2], a[60]); // Sum(62) + res[63] = fma52lo(res[63], a[3], a[60]); // Sum(63) + res[64] = fma52hi(res[64], a[3], a[60]); // Sum(63) + res[64] = fma52lo(res[64], a[4], a[60]); // Sum(64) + res[65] = fma52hi(res[65], a[4], a[60]); // Sum(64) + res[65] = fma52lo(res[65], a[5], a[60]); // Sum(65) + res[66] = fma52hi(res[66], a[5], a[60]); // Sum(65) + res[66] = fma52lo(res[66], a[6], a[60]); // Sum(66) + res[67] = fma52hi(res[67], a[6], a[60]); // Sum(66) + res[67] = fma52lo(res[67], a[7], a[60]); // Sum(67) + res[68] = fma52hi(res[68], a[7], a[60]); // Sum(67) + res[68] = fma52lo(res[68], a[8], a[60]); // Sum(68) + res[69] = fma52hi(res[69], a[8], a[60]); // Sum(68) + res[69] = fma52lo(res[69], a[9], a[60]); // Sum(69) + res[70] = fma52hi(res[70], a[9], a[60]); // Sum(69) + res[70] = fma52lo(res[70], a[10], a[60]); // Sum(70) + res[71] = fma52hi(res[71], a[10], a[60]); // Sum(70) + res[71] = fma52lo(res[71], a[11], a[60]); // Sum(71) + res[72] = fma52hi(res[72], a[11], a[60]); // Sum(71) + res[61] = fma52lo(res[61], a[0], a[61]); // Sum(61) + res[62] = fma52hi(res[62], a[0], a[61]); // Sum(61) + res[62] = fma52lo(res[62], a[1], a[61]); // Sum(62) + res[63] = fma52hi(res[63], a[1], a[61]); // Sum(62) + res[63] = fma52lo(res[63], a[2], a[61]); // Sum(63) + res[64] = fma52hi(res[64], a[2], a[61]); // Sum(63) + res[64] = fma52lo(res[64], a[3], a[61]); // Sum(64) + res[65] = fma52hi(res[65], a[3], a[61]); // Sum(64) + res[65] = fma52lo(res[65], a[4], a[61]); // Sum(65) + res[66] = fma52hi(res[66], a[4], a[61]); // Sum(65) + res[66] = fma52lo(res[66], a[5], a[61]); // Sum(66) + res[67] = fma52hi(res[67], a[5], a[61]); // Sum(66) + res[67] = fma52lo(res[67], a[6], a[61]); // Sum(67) + res[68] = fma52hi(res[68], a[6], a[61]); // Sum(67) + res[68] = fma52lo(res[68], a[7], a[61]); // Sum(68) + res[69] = fma52hi(res[69], a[7], a[61]); // Sum(68) + res[69] = fma52lo(res[69], a[8], a[61]); // Sum(69) + res[70] = fma52hi(res[70], a[8], a[61]); // Sum(69) + res[70] = fma52lo(res[70], a[9], a[61]); // Sum(70) + res[71] = fma52hi(res[71], a[9], a[61]); // Sum(70) + res[71] = fma52lo(res[71], a[10], a[61]); // Sum(71) + res[72] = fma52hi(res[72], a[10], a[61]); // Sum(71) + res[62] = fma52lo(res[62], a[0], a[62]); // Sum(62) + res[63] = fma52hi(res[63], a[0], a[62]); // Sum(62) + res[63] = fma52lo(res[63], a[1], a[62]); // Sum(63) + res[64] = fma52hi(res[64], a[1], a[62]); // Sum(63) + res[64] = fma52lo(res[64], a[2], a[62]); // Sum(64) + res[65] = fma52hi(res[65], a[2], a[62]); // Sum(64) + res[65] = fma52lo(res[65], a[3], a[62]); // Sum(65) + res[66] = fma52hi(res[66], a[3], a[62]); // Sum(65) + res[66] = fma52lo(res[66], a[4], a[62]); // Sum(66) + res[67] = fma52hi(res[67], a[4], a[62]); // Sum(66) + res[67] = fma52lo(res[67], a[5], a[62]); // Sum(67) + res[68] = fma52hi(res[68], a[5], a[62]); // Sum(67) + res[68] = fma52lo(res[68], a[6], a[62]); // Sum(68) + res[69] = fma52hi(res[69], a[6], a[62]); // Sum(68) + res[69] = fma52lo(res[69], a[7], a[62]); // Sum(69) + res[70] = fma52hi(res[70], a[7], a[62]); // Sum(69) + res[70] = fma52lo(res[70], a[8], a[62]); // Sum(70) + res[71] = fma52hi(res[71], a[8], a[62]); // Sum(70) + res[71] = fma52lo(res[71], a[9], a[62]); // Sum(71) + res[72] = fma52hi(res[72], a[9], a[62]); // Sum(71) + res[63] = fma52lo(res[63], a[0], a[63]); // Sum(63) + res[64] = fma52hi(res[64], a[0], a[63]); // Sum(63) + res[64] = fma52lo(res[64], a[1], a[63]); // Sum(64) + res[65] = fma52hi(res[65], a[1], a[63]); // Sum(64) + res[65] = fma52lo(res[65], a[2], a[63]); // Sum(65) + res[66] = fma52hi(res[66], a[2], a[63]); // Sum(65) + res[66] = fma52lo(res[66], a[3], a[63]); // Sum(66) + res[67] = fma52hi(res[67], a[3], a[63]); // Sum(66) + res[67] = fma52lo(res[67], a[4], a[63]); // Sum(67) + res[68] = fma52hi(res[68], a[4], a[63]); // Sum(67) + res[68] = fma52lo(res[68], a[5], a[63]); // Sum(68) + res[69] = fma52hi(res[69], a[5], a[63]); // Sum(68) + res[69] = fma52lo(res[69], a[6], a[63]); // Sum(69) + res[70] = fma52hi(res[70], a[6], a[63]); // Sum(69) + res[70] = fma52lo(res[70], a[7], a[63]); // Sum(70) + res[71] = fma52hi(res[71], a[7], a[63]); // Sum(70) + res[71] = fma52lo(res[71], a[8], a[63]); // Sum(71) + res[72] = fma52hi(res[72], a[8], a[63]); // Sum(71) + res[64] = fma52lo(res[64], a[0], a[64]); // Sum(64) + res[65] = fma52hi(res[65], a[0], a[64]); // Sum(64) + res[65] = fma52lo(res[65], a[1], a[64]); // Sum(65) + res[66] = fma52hi(res[66], a[1], a[64]); // Sum(65) + res[66] = fma52lo(res[66], a[2], a[64]); // Sum(66) + res[67] = fma52hi(res[67], a[2], a[64]); // Sum(66) + res[67] = fma52lo(res[67], a[3], a[64]); // Sum(67) + res[68] = fma52hi(res[68], a[3], a[64]); // Sum(67) + res[68] = fma52lo(res[68], a[4], a[64]); // Sum(68) + res[69] = fma52hi(res[69], a[4], a[64]); // Sum(68) + res[69] = fma52lo(res[69], a[5], a[64]); // Sum(69) + res[70] = fma52hi(res[70], a[5], a[64]); // Sum(69) + res[70] = fma52lo(res[70], a[6], a[64]); // Sum(70) + res[71] = fma52hi(res[71], a[6], a[64]); // Sum(70) + res[71] = fma52lo(res[71], a[7], a[64]); // Sum(71) + res[72] = fma52hi(res[72], a[7], a[64]); // Sum(71) + res[65] = fma52lo(res[65], a[0], a[65]); // Sum(65) + res[66] = fma52hi(res[66], a[0], a[65]); // Sum(65) + res[66] = fma52lo(res[66], a[1], a[65]); // Sum(66) + res[67] = fma52hi(res[67], a[1], a[65]); // Sum(66) + res[67] = fma52lo(res[67], a[2], a[65]); // Sum(67) + res[68] = fma52hi(res[68], a[2], a[65]); // Sum(67) + res[68] = fma52lo(res[68], a[3], a[65]); // Sum(68) + res[69] = fma52hi(res[69], a[3], a[65]); // Sum(68) + res[69] = fma52lo(res[69], a[4], a[65]); // Sum(69) + res[70] = fma52hi(res[70], a[4], a[65]); // Sum(69) + res[70] = fma52lo(res[70], a[5], a[65]); // Sum(70) + res[71] = fma52hi(res[71], a[5], a[65]); // Sum(70) + res[71] = fma52lo(res[71], a[6], a[65]); // Sum(71) + res[72] = fma52hi(res[72], a[6], a[65]); // Sum(71) + res[66] = fma52lo(res[66], a[0], a[66]); // Sum(66) + res[67] = fma52hi(res[67], a[0], a[66]); // Sum(66) + res[67] = fma52lo(res[67], a[1], a[66]); // Sum(67) + res[68] = fma52hi(res[68], a[1], a[66]); // Sum(67) + res[68] = fma52lo(res[68], a[2], a[66]); // Sum(68) + res[69] = fma52hi(res[69], a[2], a[66]); // Sum(68) + res[69] = fma52lo(res[69], a[3], a[66]); // Sum(69) + res[70] = fma52hi(res[70], a[3], a[66]); // Sum(69) + res[70] = fma52lo(res[70], a[4], a[66]); // Sum(70) + res[71] = fma52hi(res[71], a[4], a[66]); // Sum(70) + res[71] = fma52lo(res[71], a[5], a[66]); // Sum(71) + res[72] = fma52hi(res[72], a[5], a[66]); // Sum(71) + res[67] = fma52lo(res[67], a[0], a[67]); // Sum(67) + res[68] = fma52hi(res[68], a[0], a[67]); // Sum(67) + res[68] = fma52lo(res[68], a[1], a[67]); // Sum(68) + res[69] = fma52hi(res[69], a[1], a[67]); // Sum(68) + res[69] = fma52lo(res[69], a[2], a[67]); // Sum(69) + res[70] = fma52hi(res[70], a[2], a[67]); // Sum(69) + res[70] = fma52lo(res[70], a[3], a[67]); // Sum(70) + res[71] = fma52hi(res[71], a[3], a[67]); // Sum(70) + res[71] = fma52lo(res[71], a[4], a[67]); // Sum(71) + res[72] = fma52hi(res[72], a[4], a[67]); // Sum(71) + res[68] = fma52lo(res[68], a[0], a[68]); // Sum(68) + res[69] = fma52hi(res[69], a[0], a[68]); // Sum(68) + res[69] = fma52lo(res[69], a[1], a[68]); // Sum(69) + res[70] = fma52hi(res[70], a[1], a[68]); // Sum(69) + res[70] = fma52lo(res[70], a[2], a[68]); // Sum(70) + res[71] = fma52hi(res[71], a[2], a[68]); // Sum(70) + res[71] = fma52lo(res[71], a[3], a[68]); // Sum(71) + res[72] = fma52hi(res[72], a[3], a[68]); // Sum(71) + res[69] = fma52lo(res[69], a[0], a[69]); // Sum(69) + res[70] = fma52hi(res[70], a[0], a[69]); // Sum(69) + res[70] = fma52lo(res[70], a[1], a[69]); // Sum(70) + res[71] = fma52hi(res[71], a[1], a[69]); // Sum(70) + res[71] = fma52lo(res[71], a[2], a[69]); // Sum(71) + res[72] = fma52hi(res[72], a[2], a[69]); // Sum(71) + res[70] = fma52lo(res[70], a[0], a[70]); // Sum(70) + res[71] = fma52hi(res[71], a[0], a[70]); // Sum(70) + res[71] = fma52lo(res[71], a[1], a[70]); // Sum(71) + res[72] = fma52hi(res[72], a[1], a[70]); // Sum(71) + res[71] = fma52lo(res[71], a[0], a[71]); // Sum(71) + res[72] = fma52hi(res[72], a[0], a[71]); // Sum(71) + res[60] = add64(res[60], res[60]); // Double(60) + res[61] = add64(res[61], res[61]); // Double(61) + res[62] = add64(res[62], res[62]); // Double(62) + res[63] = add64(res[63], res[63]); // Double(63) + res[64] = add64(res[64], res[64]); // Double(64) + res[65] = add64(res[65], res[65]); // Double(65) + res[66] = add64(res[66], res[66]); // Double(66) + res[67] = add64(res[67], res[67]); // Double(67) + res[68] = add64(res[68], res[68]); // Double(68) + res[69] = add64(res[69], res[69]); // Double(69) + res[70] = add64(res[70], res[70]); // Double(70) + res[71] = add64(res[71], res[71]); // Double(71) + res[60] = fma52lo(res[60], a[30], a[30]); // Add sqr(60) + res[61] = fma52hi(res[61], a[30], a[30]); // Add sqr(60) + res[62] = fma52lo(res[62], a[31], a[31]); // Add sqr(62) + res[63] = fma52hi(res[63], a[31], a[31]); // Add sqr(62) + res[64] = fma52lo(res[64], a[32], a[32]); // Add sqr(64) + res[65] = fma52hi(res[65], a[32], a[32]); // Add sqr(64) + res[66] = fma52lo(res[66], a[33], a[33]); // Add sqr(66) + res[67] = fma52hi(res[67], a[33], a[33]); // Add sqr(66) + res[68] = fma52lo(res[68], a[34], a[34]); // Add sqr(68) + res[69] = fma52hi(res[69], a[34], a[34]); // Add sqr(68) + res[70] = fma52lo(res[70], a[35], a[35]); // Add sqr(70) + res[71] = fma52hi(res[71], a[35], a[35]); // Add sqr(70) + res[72] = fma52lo(res[72], a[35], a[37]); // Sum(72) + res[73] = fma52hi(res[73], a[35], a[37]); // Sum(72) + res[73] = fma52lo(res[73], a[36], a[37]); // Sum(73) + res[74] = fma52hi(res[74], a[36], a[37]); // Sum(73) + res[72] = fma52lo(res[72], a[34], a[38]); // Sum(72) + res[73] = fma52hi(res[73], a[34], a[38]); // Sum(72) + res[73] = fma52lo(res[73], a[35], a[38]); // Sum(73) + res[74] = fma52hi(res[74], a[35], a[38]); // Sum(73) + res[74] = fma52lo(res[74], a[36], a[38]); // Sum(74) + res[75] = fma52hi(res[75], a[36], a[38]); // Sum(74) + res[75] = fma52lo(res[75], a[37], a[38]); // Sum(75) + res[76] = fma52hi(res[76], a[37], a[38]); // Sum(75) + res[72] = fma52lo(res[72], a[33], a[39]); // Sum(72) + res[73] = fma52hi(res[73], a[33], a[39]); // Sum(72) + res[73] = fma52lo(res[73], a[34], a[39]); // Sum(73) + res[74] = fma52hi(res[74], a[34], a[39]); // Sum(73) + res[74] = fma52lo(res[74], a[35], a[39]); // Sum(74) + res[75] = fma52hi(res[75], a[35], a[39]); // Sum(74) + res[75] = fma52lo(res[75], a[36], a[39]); // Sum(75) + res[76] = fma52hi(res[76], a[36], a[39]); // Sum(75) + res[76] = fma52lo(res[76], a[37], a[39]); // Sum(76) + res[77] = fma52hi(res[77], a[37], a[39]); // Sum(76) + res[77] = fma52lo(res[77], a[38], a[39]); // Sum(77) + res[78] = fma52hi(res[78], a[38], a[39]); // Sum(77) + res[72] = fma52lo(res[72], a[32], a[40]); // Sum(72) + res[73] = fma52hi(res[73], a[32], a[40]); // Sum(72) + res[73] = fma52lo(res[73], a[33], a[40]); // Sum(73) + res[74] = fma52hi(res[74], a[33], a[40]); // Sum(73) + res[74] = fma52lo(res[74], a[34], a[40]); // Sum(74) + res[75] = fma52hi(res[75], a[34], a[40]); // Sum(74) + res[75] = fma52lo(res[75], a[35], a[40]); // Sum(75) + res[76] = fma52hi(res[76], a[35], a[40]); // Sum(75) + res[76] = fma52lo(res[76], a[36], a[40]); // Sum(76) + res[77] = fma52hi(res[77], a[36], a[40]); // Sum(76) + res[77] = fma52lo(res[77], a[37], a[40]); // Sum(77) + res[78] = fma52hi(res[78], a[37], a[40]); // Sum(77) + res[78] = fma52lo(res[78], a[38], a[40]); // Sum(78) + res[79] = fma52hi(res[79], a[38], a[40]); // Sum(78) + res[79] = fma52lo(res[79], a[39], a[40]); // Sum(79) + res[80] = fma52hi(res[80], a[39], a[40]); // Sum(79) + res[72] = fma52lo(res[72], a[31], a[41]); // Sum(72) + res[73] = fma52hi(res[73], a[31], a[41]); // Sum(72) + res[73] = fma52lo(res[73], a[32], a[41]); // Sum(73) + res[74] = fma52hi(res[74], a[32], a[41]); // Sum(73) + res[74] = fma52lo(res[74], a[33], a[41]); // Sum(74) + res[75] = fma52hi(res[75], a[33], a[41]); // Sum(74) + res[75] = fma52lo(res[75], a[34], a[41]); // Sum(75) + res[76] = fma52hi(res[76], a[34], a[41]); // Sum(75) + res[76] = fma52lo(res[76], a[35], a[41]); // Sum(76) + res[77] = fma52hi(res[77], a[35], a[41]); // Sum(76) + res[77] = fma52lo(res[77], a[36], a[41]); // Sum(77) + res[78] = fma52hi(res[78], a[36], a[41]); // Sum(77) + res[78] = fma52lo(res[78], a[37], a[41]); // Sum(78) + res[79] = fma52hi(res[79], a[37], a[41]); // Sum(78) + res[79] = fma52lo(res[79], a[38], a[41]); // Sum(79) + res[80] = fma52hi(res[80], a[38], a[41]); // Sum(79) + res[80] = fma52lo(res[80], a[39], a[41]); // Sum(80) + res[81] = fma52hi(res[81], a[39], a[41]); // Sum(80) + res[81] = fma52lo(res[81], a[40], a[41]); // Sum(81) + res[82] = fma52hi(res[82], a[40], a[41]); // Sum(81) + res[72] = fma52lo(res[72], a[30], a[42]); // Sum(72) + res[73] = fma52hi(res[73], a[30], a[42]); // Sum(72) + res[73] = fma52lo(res[73], a[31], a[42]); // Sum(73) + res[74] = fma52hi(res[74], a[31], a[42]); // Sum(73) + res[74] = fma52lo(res[74], a[32], a[42]); // Sum(74) + res[75] = fma52hi(res[75], a[32], a[42]); // Sum(74) + res[75] = fma52lo(res[75], a[33], a[42]); // Sum(75) + res[76] = fma52hi(res[76], a[33], a[42]); // Sum(75) + res[76] = fma52lo(res[76], a[34], a[42]); // Sum(76) + res[77] = fma52hi(res[77], a[34], a[42]); // Sum(76) + res[77] = fma52lo(res[77], a[35], a[42]); // Sum(77) + res[78] = fma52hi(res[78], a[35], a[42]); // Sum(77) + res[78] = fma52lo(res[78], a[36], a[42]); // Sum(78) + res[79] = fma52hi(res[79], a[36], a[42]); // Sum(78) + res[79] = fma52lo(res[79], a[37], a[42]); // Sum(79) + res[80] = fma52hi(res[80], a[37], a[42]); // Sum(79) + res[80] = fma52lo(res[80], a[38], a[42]); // Sum(80) + res[81] = fma52hi(res[81], a[38], a[42]); // Sum(80) + res[81] = fma52lo(res[81], a[39], a[42]); // Sum(81) + res[82] = fma52hi(res[82], a[39], a[42]); // Sum(81) + res[82] = fma52lo(res[82], a[40], a[42]); // Sum(82) + res[83] = fma52hi(res[83], a[40], a[42]); // Sum(82) + res[83] = fma52lo(res[83], a[41], a[42]); // Sum(83) + res[84] = fma52hi(res[84], a[41], a[42]); // Sum(83) + res[72] = fma52lo(res[72], a[29], a[43]); // Sum(72) + res[73] = fma52hi(res[73], a[29], a[43]); // Sum(72) + res[73] = fma52lo(res[73], a[30], a[43]); // Sum(73) + res[74] = fma52hi(res[74], a[30], a[43]); // Sum(73) + res[74] = fma52lo(res[74], a[31], a[43]); // Sum(74) + res[75] = fma52hi(res[75], a[31], a[43]); // Sum(74) + res[75] = fma52lo(res[75], a[32], a[43]); // Sum(75) + res[76] = fma52hi(res[76], a[32], a[43]); // Sum(75) + res[76] = fma52lo(res[76], a[33], a[43]); // Sum(76) + res[77] = fma52hi(res[77], a[33], a[43]); // Sum(76) + res[77] = fma52lo(res[77], a[34], a[43]); // Sum(77) + res[78] = fma52hi(res[78], a[34], a[43]); // Sum(77) + res[78] = fma52lo(res[78], a[35], a[43]); // Sum(78) + res[79] = fma52hi(res[79], a[35], a[43]); // Sum(78) + res[79] = fma52lo(res[79], a[36], a[43]); // Sum(79) + res[80] = fma52hi(res[80], a[36], a[43]); // Sum(79) + res[80] = fma52lo(res[80], a[37], a[43]); // Sum(80) + res[81] = fma52hi(res[81], a[37], a[43]); // Sum(80) + res[81] = fma52lo(res[81], a[38], a[43]); // Sum(81) + res[82] = fma52hi(res[82], a[38], a[43]); // Sum(81) + res[82] = fma52lo(res[82], a[39], a[43]); // Sum(82) + res[83] = fma52hi(res[83], a[39], a[43]); // Sum(82) + res[83] = fma52lo(res[83], a[40], a[43]); // Sum(83) + res[84] = fma52hi(res[84], a[40], a[43]); // Sum(83) + res[72] = fma52lo(res[72], a[28], a[44]); // Sum(72) + res[73] = fma52hi(res[73], a[28], a[44]); // Sum(72) + res[73] = fma52lo(res[73], a[29], a[44]); // Sum(73) + res[74] = fma52hi(res[74], a[29], a[44]); // Sum(73) + res[74] = fma52lo(res[74], a[30], a[44]); // Sum(74) + res[75] = fma52hi(res[75], a[30], a[44]); // Sum(74) + res[75] = fma52lo(res[75], a[31], a[44]); // Sum(75) + res[76] = fma52hi(res[76], a[31], a[44]); // Sum(75) + res[76] = fma52lo(res[76], a[32], a[44]); // Sum(76) + res[77] = fma52hi(res[77], a[32], a[44]); // Sum(76) + res[77] = fma52lo(res[77], a[33], a[44]); // Sum(77) + res[78] = fma52hi(res[78], a[33], a[44]); // Sum(77) + res[78] = fma52lo(res[78], a[34], a[44]); // Sum(78) + res[79] = fma52hi(res[79], a[34], a[44]); // Sum(78) + res[79] = fma52lo(res[79], a[35], a[44]); // Sum(79) + res[80] = fma52hi(res[80], a[35], a[44]); // Sum(79) + res[80] = fma52lo(res[80], a[36], a[44]); // Sum(80) + res[81] = fma52hi(res[81], a[36], a[44]); // Sum(80) + res[81] = fma52lo(res[81], a[37], a[44]); // Sum(81) + res[82] = fma52hi(res[82], a[37], a[44]); // Sum(81) + res[82] = fma52lo(res[82], a[38], a[44]); // Sum(82) + res[83] = fma52hi(res[83], a[38], a[44]); // Sum(82) + res[83] = fma52lo(res[83], a[39], a[44]); // Sum(83) + res[84] = fma52hi(res[84], a[39], a[44]); // Sum(83) + res[72] = fma52lo(res[72], a[27], a[45]); // Sum(72) + res[73] = fma52hi(res[73], a[27], a[45]); // Sum(72) + res[73] = fma52lo(res[73], a[28], a[45]); // Sum(73) + res[74] = fma52hi(res[74], a[28], a[45]); // Sum(73) + res[74] = fma52lo(res[74], a[29], a[45]); // Sum(74) + res[75] = fma52hi(res[75], a[29], a[45]); // Sum(74) + res[75] = fma52lo(res[75], a[30], a[45]); // Sum(75) + res[76] = fma52hi(res[76], a[30], a[45]); // Sum(75) + res[76] = fma52lo(res[76], a[31], a[45]); // Sum(76) + res[77] = fma52hi(res[77], a[31], a[45]); // Sum(76) + res[77] = fma52lo(res[77], a[32], a[45]); // Sum(77) + res[78] = fma52hi(res[78], a[32], a[45]); // Sum(77) + res[78] = fma52lo(res[78], a[33], a[45]); // Sum(78) + res[79] = fma52hi(res[79], a[33], a[45]); // Sum(78) + res[79] = fma52lo(res[79], a[34], a[45]); // Sum(79) + res[80] = fma52hi(res[80], a[34], a[45]); // Sum(79) + res[80] = fma52lo(res[80], a[35], a[45]); // Sum(80) + res[81] = fma52hi(res[81], a[35], a[45]); // Sum(80) + res[81] = fma52lo(res[81], a[36], a[45]); // Sum(81) + res[82] = fma52hi(res[82], a[36], a[45]); // Sum(81) + res[82] = fma52lo(res[82], a[37], a[45]); // Sum(82) + res[83] = fma52hi(res[83], a[37], a[45]); // Sum(82) + res[83] = fma52lo(res[83], a[38], a[45]); // Sum(83) + res[84] = fma52hi(res[84], a[38], a[45]); // Sum(83) + res[72] = fma52lo(res[72], a[26], a[46]); // Sum(72) + res[73] = fma52hi(res[73], a[26], a[46]); // Sum(72) + res[73] = fma52lo(res[73], a[27], a[46]); // Sum(73) + res[74] = fma52hi(res[74], a[27], a[46]); // Sum(73) + res[74] = fma52lo(res[74], a[28], a[46]); // Sum(74) + res[75] = fma52hi(res[75], a[28], a[46]); // Sum(74) + res[75] = fma52lo(res[75], a[29], a[46]); // Sum(75) + res[76] = fma52hi(res[76], a[29], a[46]); // Sum(75) + res[76] = fma52lo(res[76], a[30], a[46]); // Sum(76) + res[77] = fma52hi(res[77], a[30], a[46]); // Sum(76) + res[77] = fma52lo(res[77], a[31], a[46]); // Sum(77) + res[78] = fma52hi(res[78], a[31], a[46]); // Sum(77) + res[78] = fma52lo(res[78], a[32], a[46]); // Sum(78) + res[79] = fma52hi(res[79], a[32], a[46]); // Sum(78) + res[79] = fma52lo(res[79], a[33], a[46]); // Sum(79) + res[80] = fma52hi(res[80], a[33], a[46]); // Sum(79) + res[80] = fma52lo(res[80], a[34], a[46]); // Sum(80) + res[81] = fma52hi(res[81], a[34], a[46]); // Sum(80) + res[81] = fma52lo(res[81], a[35], a[46]); // Sum(81) + res[82] = fma52hi(res[82], a[35], a[46]); // Sum(81) + res[82] = fma52lo(res[82], a[36], a[46]); // Sum(82) + res[83] = fma52hi(res[83], a[36], a[46]); // Sum(82) + res[83] = fma52lo(res[83], a[37], a[46]); // Sum(83) + res[84] = fma52hi(res[84], a[37], a[46]); // Sum(83) + res[72] = fma52lo(res[72], a[25], a[47]); // Sum(72) + res[73] = fma52hi(res[73], a[25], a[47]); // Sum(72) + res[73] = fma52lo(res[73], a[26], a[47]); // Sum(73) + res[74] = fma52hi(res[74], a[26], a[47]); // Sum(73) + res[74] = fma52lo(res[74], a[27], a[47]); // Sum(74) + res[75] = fma52hi(res[75], a[27], a[47]); // Sum(74) + res[75] = fma52lo(res[75], a[28], a[47]); // Sum(75) + res[76] = fma52hi(res[76], a[28], a[47]); // Sum(75) + res[76] = fma52lo(res[76], a[29], a[47]); // Sum(76) + res[77] = fma52hi(res[77], a[29], a[47]); // Sum(76) + res[77] = fma52lo(res[77], a[30], a[47]); // Sum(77) + res[78] = fma52hi(res[78], a[30], a[47]); // Sum(77) + res[78] = fma52lo(res[78], a[31], a[47]); // Sum(78) + res[79] = fma52hi(res[79], a[31], a[47]); // Sum(78) + res[79] = fma52lo(res[79], a[32], a[47]); // Sum(79) + res[80] = fma52hi(res[80], a[32], a[47]); // Sum(79) + res[80] = fma52lo(res[80], a[33], a[47]); // Sum(80) + res[81] = fma52hi(res[81], a[33], a[47]); // Sum(80) + res[81] = fma52lo(res[81], a[34], a[47]); // Sum(81) + res[82] = fma52hi(res[82], a[34], a[47]); // Sum(81) + res[82] = fma52lo(res[82], a[35], a[47]); // Sum(82) + res[83] = fma52hi(res[83], a[35], a[47]); // Sum(82) + res[83] = fma52lo(res[83], a[36], a[47]); // Sum(83) + res[84] = fma52hi(res[84], a[36], a[47]); // Sum(83) + res[72] = fma52lo(res[72], a[24], a[48]); // Sum(72) + res[73] = fma52hi(res[73], a[24], a[48]); // Sum(72) + res[73] = fma52lo(res[73], a[25], a[48]); // Sum(73) + res[74] = fma52hi(res[74], a[25], a[48]); // Sum(73) + res[74] = fma52lo(res[74], a[26], a[48]); // Sum(74) + res[75] = fma52hi(res[75], a[26], a[48]); // Sum(74) + res[75] = fma52lo(res[75], a[27], a[48]); // Sum(75) + res[76] = fma52hi(res[76], a[27], a[48]); // Sum(75) + res[76] = fma52lo(res[76], a[28], a[48]); // Sum(76) + res[77] = fma52hi(res[77], a[28], a[48]); // Sum(76) + res[77] = fma52lo(res[77], a[29], a[48]); // Sum(77) + res[78] = fma52hi(res[78], a[29], a[48]); // Sum(77) + res[78] = fma52lo(res[78], a[30], a[48]); // Sum(78) + res[79] = fma52hi(res[79], a[30], a[48]); // Sum(78) + res[79] = fma52lo(res[79], a[31], a[48]); // Sum(79) + res[80] = fma52hi(res[80], a[31], a[48]); // Sum(79) + res[80] = fma52lo(res[80], a[32], a[48]); // Sum(80) + res[81] = fma52hi(res[81], a[32], a[48]); // Sum(80) + res[81] = fma52lo(res[81], a[33], a[48]); // Sum(81) + res[82] = fma52hi(res[82], a[33], a[48]); // Sum(81) + res[82] = fma52lo(res[82], a[34], a[48]); // Sum(82) + res[83] = fma52hi(res[83], a[34], a[48]); // Sum(82) + res[83] = fma52lo(res[83], a[35], a[48]); // Sum(83) + res[84] = fma52hi(res[84], a[35], a[48]); // Sum(83) + res[72] = fma52lo(res[72], a[23], a[49]); // Sum(72) + res[73] = fma52hi(res[73], a[23], a[49]); // Sum(72) + res[73] = fma52lo(res[73], a[24], a[49]); // Sum(73) + res[74] = fma52hi(res[74], a[24], a[49]); // Sum(73) + res[74] = fma52lo(res[74], a[25], a[49]); // Sum(74) + res[75] = fma52hi(res[75], a[25], a[49]); // Sum(74) + res[75] = fma52lo(res[75], a[26], a[49]); // Sum(75) + res[76] = fma52hi(res[76], a[26], a[49]); // Sum(75) + res[76] = fma52lo(res[76], a[27], a[49]); // Sum(76) + res[77] = fma52hi(res[77], a[27], a[49]); // Sum(76) + res[77] = fma52lo(res[77], a[28], a[49]); // Sum(77) + res[78] = fma52hi(res[78], a[28], a[49]); // Sum(77) + res[78] = fma52lo(res[78], a[29], a[49]); // Sum(78) + res[79] = fma52hi(res[79], a[29], a[49]); // Sum(78) + res[79] = fma52lo(res[79], a[30], a[49]); // Sum(79) + res[80] = fma52hi(res[80], a[30], a[49]); // Sum(79) + res[80] = fma52lo(res[80], a[31], a[49]); // Sum(80) + res[81] = fma52hi(res[81], a[31], a[49]); // Sum(80) + res[81] = fma52lo(res[81], a[32], a[49]); // Sum(81) + res[82] = fma52hi(res[82], a[32], a[49]); // Sum(81) + res[82] = fma52lo(res[82], a[33], a[49]); // Sum(82) + res[83] = fma52hi(res[83], a[33], a[49]); // Sum(82) + res[83] = fma52lo(res[83], a[34], a[49]); // Sum(83) + res[84] = fma52hi(res[84], a[34], a[49]); // Sum(83) + res[72] = fma52lo(res[72], a[22], a[50]); // Sum(72) + res[73] = fma52hi(res[73], a[22], a[50]); // Sum(72) + res[73] = fma52lo(res[73], a[23], a[50]); // Sum(73) + res[74] = fma52hi(res[74], a[23], a[50]); // Sum(73) + res[74] = fma52lo(res[74], a[24], a[50]); // Sum(74) + res[75] = fma52hi(res[75], a[24], a[50]); // Sum(74) + res[75] = fma52lo(res[75], a[25], a[50]); // Sum(75) + res[76] = fma52hi(res[76], a[25], a[50]); // Sum(75) + res[76] = fma52lo(res[76], a[26], a[50]); // Sum(76) + res[77] = fma52hi(res[77], a[26], a[50]); // Sum(76) + res[77] = fma52lo(res[77], a[27], a[50]); // Sum(77) + res[78] = fma52hi(res[78], a[27], a[50]); // Sum(77) + res[78] = fma52lo(res[78], a[28], a[50]); // Sum(78) + res[79] = fma52hi(res[79], a[28], a[50]); // Sum(78) + res[79] = fma52lo(res[79], a[29], a[50]); // Sum(79) + res[80] = fma52hi(res[80], a[29], a[50]); // Sum(79) + res[80] = fma52lo(res[80], a[30], a[50]); // Sum(80) + res[81] = fma52hi(res[81], a[30], a[50]); // Sum(80) + res[81] = fma52lo(res[81], a[31], a[50]); // Sum(81) + res[82] = fma52hi(res[82], a[31], a[50]); // Sum(81) + res[82] = fma52lo(res[82], a[32], a[50]); // Sum(82) + res[83] = fma52hi(res[83], a[32], a[50]); // Sum(82) + res[83] = fma52lo(res[83], a[33], a[50]); // Sum(83) + res[84] = fma52hi(res[84], a[33], a[50]); // Sum(83) + res[72] = fma52lo(res[72], a[21], a[51]); // Sum(72) + res[73] = fma52hi(res[73], a[21], a[51]); // Sum(72) + res[73] = fma52lo(res[73], a[22], a[51]); // Sum(73) + res[74] = fma52hi(res[74], a[22], a[51]); // Sum(73) + res[74] = fma52lo(res[74], a[23], a[51]); // Sum(74) + res[75] = fma52hi(res[75], a[23], a[51]); // Sum(74) + res[75] = fma52lo(res[75], a[24], a[51]); // Sum(75) + res[76] = fma52hi(res[76], a[24], a[51]); // Sum(75) + res[76] = fma52lo(res[76], a[25], a[51]); // Sum(76) + res[77] = fma52hi(res[77], a[25], a[51]); // Sum(76) + res[77] = fma52lo(res[77], a[26], a[51]); // Sum(77) + res[78] = fma52hi(res[78], a[26], a[51]); // Sum(77) + res[78] = fma52lo(res[78], a[27], a[51]); // Sum(78) + res[79] = fma52hi(res[79], a[27], a[51]); // Sum(78) + res[79] = fma52lo(res[79], a[28], a[51]); // Sum(79) + res[80] = fma52hi(res[80], a[28], a[51]); // Sum(79) + res[80] = fma52lo(res[80], a[29], a[51]); // Sum(80) + res[81] = fma52hi(res[81], a[29], a[51]); // Sum(80) + res[81] = fma52lo(res[81], a[30], a[51]); // Sum(81) + res[82] = fma52hi(res[82], a[30], a[51]); // Sum(81) + res[82] = fma52lo(res[82], a[31], a[51]); // Sum(82) + res[83] = fma52hi(res[83], a[31], a[51]); // Sum(82) + res[83] = fma52lo(res[83], a[32], a[51]); // Sum(83) + res[84] = fma52hi(res[84], a[32], a[51]); // Sum(83) + res[72] = fma52lo(res[72], a[20], a[52]); // Sum(72) + res[73] = fma52hi(res[73], a[20], a[52]); // Sum(72) + res[73] = fma52lo(res[73], a[21], a[52]); // Sum(73) + res[74] = fma52hi(res[74], a[21], a[52]); // Sum(73) + res[74] = fma52lo(res[74], a[22], a[52]); // Sum(74) + res[75] = fma52hi(res[75], a[22], a[52]); // Sum(74) + res[75] = fma52lo(res[75], a[23], a[52]); // Sum(75) + res[76] = fma52hi(res[76], a[23], a[52]); // Sum(75) + res[76] = fma52lo(res[76], a[24], a[52]); // Sum(76) + res[77] = fma52hi(res[77], a[24], a[52]); // Sum(76) + res[77] = fma52lo(res[77], a[25], a[52]); // Sum(77) + res[78] = fma52hi(res[78], a[25], a[52]); // Sum(77) + res[78] = fma52lo(res[78], a[26], a[52]); // Sum(78) + res[79] = fma52hi(res[79], a[26], a[52]); // Sum(78) + res[79] = fma52lo(res[79], a[27], a[52]); // Sum(79) + res[80] = fma52hi(res[80], a[27], a[52]); // Sum(79) + res[80] = fma52lo(res[80], a[28], a[52]); // Sum(80) + res[81] = fma52hi(res[81], a[28], a[52]); // Sum(80) + res[81] = fma52lo(res[81], a[29], a[52]); // Sum(81) + res[82] = fma52hi(res[82], a[29], a[52]); // Sum(81) + res[82] = fma52lo(res[82], a[30], a[52]); // Sum(82) + res[83] = fma52hi(res[83], a[30], a[52]); // Sum(82) + res[83] = fma52lo(res[83], a[31], a[52]); // Sum(83) + res[84] = fma52hi(res[84], a[31], a[52]); // Sum(83) + res[72] = fma52lo(res[72], a[19], a[53]); // Sum(72) + res[73] = fma52hi(res[73], a[19], a[53]); // Sum(72) + res[73] = fma52lo(res[73], a[20], a[53]); // Sum(73) + res[74] = fma52hi(res[74], a[20], a[53]); // Sum(73) + res[74] = fma52lo(res[74], a[21], a[53]); // Sum(74) + res[75] = fma52hi(res[75], a[21], a[53]); // Sum(74) + res[75] = fma52lo(res[75], a[22], a[53]); // Sum(75) + res[76] = fma52hi(res[76], a[22], a[53]); // Sum(75) + res[76] = fma52lo(res[76], a[23], a[53]); // Sum(76) + res[77] = fma52hi(res[77], a[23], a[53]); // Sum(76) + res[77] = fma52lo(res[77], a[24], a[53]); // Sum(77) + res[78] = fma52hi(res[78], a[24], a[53]); // Sum(77) + res[78] = fma52lo(res[78], a[25], a[53]); // Sum(78) + res[79] = fma52hi(res[79], a[25], a[53]); // Sum(78) + res[79] = fma52lo(res[79], a[26], a[53]); // Sum(79) + res[80] = fma52hi(res[80], a[26], a[53]); // Sum(79) + res[80] = fma52lo(res[80], a[27], a[53]); // Sum(80) + res[81] = fma52hi(res[81], a[27], a[53]); // Sum(80) + res[81] = fma52lo(res[81], a[28], a[53]); // Sum(81) + res[82] = fma52hi(res[82], a[28], a[53]); // Sum(81) + res[82] = fma52lo(res[82], a[29], a[53]); // Sum(82) + res[83] = fma52hi(res[83], a[29], a[53]); // Sum(82) + res[83] = fma52lo(res[83], a[30], a[53]); // Sum(83) + res[84] = fma52hi(res[84], a[30], a[53]); // Sum(83) + res[72] = fma52lo(res[72], a[18], a[54]); // Sum(72) + res[73] = fma52hi(res[73], a[18], a[54]); // Sum(72) + res[73] = fma52lo(res[73], a[19], a[54]); // Sum(73) + res[74] = fma52hi(res[74], a[19], a[54]); // Sum(73) + res[74] = fma52lo(res[74], a[20], a[54]); // Sum(74) + res[75] = fma52hi(res[75], a[20], a[54]); // Sum(74) + res[75] = fma52lo(res[75], a[21], a[54]); // Sum(75) + res[76] = fma52hi(res[76], a[21], a[54]); // Sum(75) + res[76] = fma52lo(res[76], a[22], a[54]); // Sum(76) + res[77] = fma52hi(res[77], a[22], a[54]); // Sum(76) + res[77] = fma52lo(res[77], a[23], a[54]); // Sum(77) + res[78] = fma52hi(res[78], a[23], a[54]); // Sum(77) + res[78] = fma52lo(res[78], a[24], a[54]); // Sum(78) + res[79] = fma52hi(res[79], a[24], a[54]); // Sum(78) + res[79] = fma52lo(res[79], a[25], a[54]); // Sum(79) + res[80] = fma52hi(res[80], a[25], a[54]); // Sum(79) + res[80] = fma52lo(res[80], a[26], a[54]); // Sum(80) + res[81] = fma52hi(res[81], a[26], a[54]); // Sum(80) + res[81] = fma52lo(res[81], a[27], a[54]); // Sum(81) + res[82] = fma52hi(res[82], a[27], a[54]); // Sum(81) + res[82] = fma52lo(res[82], a[28], a[54]); // Sum(82) + res[83] = fma52hi(res[83], a[28], a[54]); // Sum(82) + res[83] = fma52lo(res[83], a[29], a[54]); // Sum(83) + res[84] = fma52hi(res[84], a[29], a[54]); // Sum(83) + res[72] = fma52lo(res[72], a[17], a[55]); // Sum(72) + res[73] = fma52hi(res[73], a[17], a[55]); // Sum(72) + res[73] = fma52lo(res[73], a[18], a[55]); // Sum(73) + res[74] = fma52hi(res[74], a[18], a[55]); // Sum(73) + res[74] = fma52lo(res[74], a[19], a[55]); // Sum(74) + res[75] = fma52hi(res[75], a[19], a[55]); // Sum(74) + res[75] = fma52lo(res[75], a[20], a[55]); // Sum(75) + res[76] = fma52hi(res[76], a[20], a[55]); // Sum(75) + res[76] = fma52lo(res[76], a[21], a[55]); // Sum(76) + res[77] = fma52hi(res[77], a[21], a[55]); // Sum(76) + res[77] = fma52lo(res[77], a[22], a[55]); // Sum(77) + res[78] = fma52hi(res[78], a[22], a[55]); // Sum(77) + res[78] = fma52lo(res[78], a[23], a[55]); // Sum(78) + res[79] = fma52hi(res[79], a[23], a[55]); // Sum(78) + res[79] = fma52lo(res[79], a[24], a[55]); // Sum(79) + res[80] = fma52hi(res[80], a[24], a[55]); // Sum(79) + res[80] = fma52lo(res[80], a[25], a[55]); // Sum(80) + res[81] = fma52hi(res[81], a[25], a[55]); // Sum(80) + res[81] = fma52lo(res[81], a[26], a[55]); // Sum(81) + res[82] = fma52hi(res[82], a[26], a[55]); // Sum(81) + res[82] = fma52lo(res[82], a[27], a[55]); // Sum(82) + res[83] = fma52hi(res[83], a[27], a[55]); // Sum(82) + res[83] = fma52lo(res[83], a[28], a[55]); // Sum(83) + res[84] = fma52hi(res[84], a[28], a[55]); // Sum(83) + res[72] = fma52lo(res[72], a[16], a[56]); // Sum(72) + res[73] = fma52hi(res[73], a[16], a[56]); // Sum(72) + res[73] = fma52lo(res[73], a[17], a[56]); // Sum(73) + res[74] = fma52hi(res[74], a[17], a[56]); // Sum(73) + res[74] = fma52lo(res[74], a[18], a[56]); // Sum(74) + res[75] = fma52hi(res[75], a[18], a[56]); // Sum(74) + res[75] = fma52lo(res[75], a[19], a[56]); // Sum(75) + res[76] = fma52hi(res[76], a[19], a[56]); // Sum(75) + res[76] = fma52lo(res[76], a[20], a[56]); // Sum(76) + res[77] = fma52hi(res[77], a[20], a[56]); // Sum(76) + res[77] = fma52lo(res[77], a[21], a[56]); // Sum(77) + res[78] = fma52hi(res[78], a[21], a[56]); // Sum(77) + res[78] = fma52lo(res[78], a[22], a[56]); // Sum(78) + res[79] = fma52hi(res[79], a[22], a[56]); // Sum(78) + res[79] = fma52lo(res[79], a[23], a[56]); // Sum(79) + res[80] = fma52hi(res[80], a[23], a[56]); // Sum(79) + res[80] = fma52lo(res[80], a[24], a[56]); // Sum(80) + res[81] = fma52hi(res[81], a[24], a[56]); // Sum(80) + res[81] = fma52lo(res[81], a[25], a[56]); // Sum(81) + res[82] = fma52hi(res[82], a[25], a[56]); // Sum(81) + res[82] = fma52lo(res[82], a[26], a[56]); // Sum(82) + res[83] = fma52hi(res[83], a[26], a[56]); // Sum(82) + res[83] = fma52lo(res[83], a[27], a[56]); // Sum(83) + res[84] = fma52hi(res[84], a[27], a[56]); // Sum(83) + res[72] = fma52lo(res[72], a[15], a[57]); // Sum(72) + res[73] = fma52hi(res[73], a[15], a[57]); // Sum(72) + res[73] = fma52lo(res[73], a[16], a[57]); // Sum(73) + res[74] = fma52hi(res[74], a[16], a[57]); // Sum(73) + res[74] = fma52lo(res[74], a[17], a[57]); // Sum(74) + res[75] = fma52hi(res[75], a[17], a[57]); // Sum(74) + res[75] = fma52lo(res[75], a[18], a[57]); // Sum(75) + res[76] = fma52hi(res[76], a[18], a[57]); // Sum(75) + res[76] = fma52lo(res[76], a[19], a[57]); // Sum(76) + res[77] = fma52hi(res[77], a[19], a[57]); // Sum(76) + res[77] = fma52lo(res[77], a[20], a[57]); // Sum(77) + res[78] = fma52hi(res[78], a[20], a[57]); // Sum(77) + res[78] = fma52lo(res[78], a[21], a[57]); // Sum(78) + res[79] = fma52hi(res[79], a[21], a[57]); // Sum(78) + res[79] = fma52lo(res[79], a[22], a[57]); // Sum(79) + res[80] = fma52hi(res[80], a[22], a[57]); // Sum(79) + res[80] = fma52lo(res[80], a[23], a[57]); // Sum(80) + res[81] = fma52hi(res[81], a[23], a[57]); // Sum(80) + res[81] = fma52lo(res[81], a[24], a[57]); // Sum(81) + res[82] = fma52hi(res[82], a[24], a[57]); // Sum(81) + res[82] = fma52lo(res[82], a[25], a[57]); // Sum(82) + res[83] = fma52hi(res[83], a[25], a[57]); // Sum(82) + res[83] = fma52lo(res[83], a[26], a[57]); // Sum(83) + res[84] = fma52hi(res[84], a[26], a[57]); // Sum(83) + res[72] = fma52lo(res[72], a[14], a[58]); // Sum(72) + res[73] = fma52hi(res[73], a[14], a[58]); // Sum(72) + res[73] = fma52lo(res[73], a[15], a[58]); // Sum(73) + res[74] = fma52hi(res[74], a[15], a[58]); // Sum(73) + res[74] = fma52lo(res[74], a[16], a[58]); // Sum(74) + res[75] = fma52hi(res[75], a[16], a[58]); // Sum(74) + res[75] = fma52lo(res[75], a[17], a[58]); // Sum(75) + res[76] = fma52hi(res[76], a[17], a[58]); // Sum(75) + res[76] = fma52lo(res[76], a[18], a[58]); // Sum(76) + res[77] = fma52hi(res[77], a[18], a[58]); // Sum(76) + res[77] = fma52lo(res[77], a[19], a[58]); // Sum(77) + res[78] = fma52hi(res[78], a[19], a[58]); // Sum(77) + res[78] = fma52lo(res[78], a[20], a[58]); // Sum(78) + res[79] = fma52hi(res[79], a[20], a[58]); // Sum(78) + res[79] = fma52lo(res[79], a[21], a[58]); // Sum(79) + res[80] = fma52hi(res[80], a[21], a[58]); // Sum(79) + res[80] = fma52lo(res[80], a[22], a[58]); // Sum(80) + res[81] = fma52hi(res[81], a[22], a[58]); // Sum(80) + res[81] = fma52lo(res[81], a[23], a[58]); // Sum(81) + res[82] = fma52hi(res[82], a[23], a[58]); // Sum(81) + res[82] = fma52lo(res[82], a[24], a[58]); // Sum(82) + res[83] = fma52hi(res[83], a[24], a[58]); // Sum(82) + res[83] = fma52lo(res[83], a[25], a[58]); // Sum(83) + res[84] = fma52hi(res[84], a[25], a[58]); // Sum(83) + res[72] = fma52lo(res[72], a[13], a[59]); // Sum(72) + res[73] = fma52hi(res[73], a[13], a[59]); // Sum(72) + res[73] = fma52lo(res[73], a[14], a[59]); // Sum(73) + res[74] = fma52hi(res[74], a[14], a[59]); // Sum(73) + res[74] = fma52lo(res[74], a[15], a[59]); // Sum(74) + res[75] = fma52hi(res[75], a[15], a[59]); // Sum(74) + res[75] = fma52lo(res[75], a[16], a[59]); // Sum(75) + res[76] = fma52hi(res[76], a[16], a[59]); // Sum(75) + res[76] = fma52lo(res[76], a[17], a[59]); // Sum(76) + res[77] = fma52hi(res[77], a[17], a[59]); // Sum(76) + res[77] = fma52lo(res[77], a[18], a[59]); // Sum(77) + res[78] = fma52hi(res[78], a[18], a[59]); // Sum(77) + res[78] = fma52lo(res[78], a[19], a[59]); // Sum(78) + res[79] = fma52hi(res[79], a[19], a[59]); // Sum(78) + res[79] = fma52lo(res[79], a[20], a[59]); // Sum(79) + res[80] = fma52hi(res[80], a[20], a[59]); // Sum(79) + res[80] = fma52lo(res[80], a[21], a[59]); // Sum(80) + res[81] = fma52hi(res[81], a[21], a[59]); // Sum(80) + res[81] = fma52lo(res[81], a[22], a[59]); // Sum(81) + res[82] = fma52hi(res[82], a[22], a[59]); // Sum(81) + res[82] = fma52lo(res[82], a[23], a[59]); // Sum(82) + res[83] = fma52hi(res[83], a[23], a[59]); // Sum(82) + res[83] = fma52lo(res[83], a[24], a[59]); // Sum(83) + res[84] = fma52hi(res[84], a[24], a[59]); // Sum(83) + res[72] = fma52lo(res[72], a[12], a[60]); // Sum(72) + res[73] = fma52hi(res[73], a[12], a[60]); // Sum(72) + res[73] = fma52lo(res[73], a[13], a[60]); // Sum(73) + res[74] = fma52hi(res[74], a[13], a[60]); // Sum(73) + res[74] = fma52lo(res[74], a[14], a[60]); // Sum(74) + res[75] = fma52hi(res[75], a[14], a[60]); // Sum(74) + res[75] = fma52lo(res[75], a[15], a[60]); // Sum(75) + res[76] = fma52hi(res[76], a[15], a[60]); // Sum(75) + res[76] = fma52lo(res[76], a[16], a[60]); // Sum(76) + res[77] = fma52hi(res[77], a[16], a[60]); // Sum(76) + res[77] = fma52lo(res[77], a[17], a[60]); // Sum(77) + res[78] = fma52hi(res[78], a[17], a[60]); // Sum(77) + res[78] = fma52lo(res[78], a[18], a[60]); // Sum(78) + res[79] = fma52hi(res[79], a[18], a[60]); // Sum(78) + res[79] = fma52lo(res[79], a[19], a[60]); // Sum(79) + res[80] = fma52hi(res[80], a[19], a[60]); // Sum(79) + res[80] = fma52lo(res[80], a[20], a[60]); // Sum(80) + res[81] = fma52hi(res[81], a[20], a[60]); // Sum(80) + res[81] = fma52lo(res[81], a[21], a[60]); // Sum(81) + res[82] = fma52hi(res[82], a[21], a[60]); // Sum(81) + res[82] = fma52lo(res[82], a[22], a[60]); // Sum(82) + res[83] = fma52hi(res[83], a[22], a[60]); // Sum(82) + res[83] = fma52lo(res[83], a[23], a[60]); // Sum(83) + res[84] = fma52hi(res[84], a[23], a[60]); // Sum(83) + res[72] = fma52lo(res[72], a[11], a[61]); // Sum(72) + res[73] = fma52hi(res[73], a[11], a[61]); // Sum(72) + res[73] = fma52lo(res[73], a[12], a[61]); // Sum(73) + res[74] = fma52hi(res[74], a[12], a[61]); // Sum(73) + res[74] = fma52lo(res[74], a[13], a[61]); // Sum(74) + res[75] = fma52hi(res[75], a[13], a[61]); // Sum(74) + res[75] = fma52lo(res[75], a[14], a[61]); // Sum(75) + res[76] = fma52hi(res[76], a[14], a[61]); // Sum(75) + res[76] = fma52lo(res[76], a[15], a[61]); // Sum(76) + res[77] = fma52hi(res[77], a[15], a[61]); // Sum(76) + res[77] = fma52lo(res[77], a[16], a[61]); // Sum(77) + res[78] = fma52hi(res[78], a[16], a[61]); // Sum(77) + res[78] = fma52lo(res[78], a[17], a[61]); // Sum(78) + res[79] = fma52hi(res[79], a[17], a[61]); // Sum(78) + res[79] = fma52lo(res[79], a[18], a[61]); // Sum(79) + res[80] = fma52hi(res[80], a[18], a[61]); // Sum(79) + res[80] = fma52lo(res[80], a[19], a[61]); // Sum(80) + res[81] = fma52hi(res[81], a[19], a[61]); // Sum(80) + res[81] = fma52lo(res[81], a[20], a[61]); // Sum(81) + res[82] = fma52hi(res[82], a[20], a[61]); // Sum(81) + res[82] = fma52lo(res[82], a[21], a[61]); // Sum(82) + res[83] = fma52hi(res[83], a[21], a[61]); // Sum(82) + res[83] = fma52lo(res[83], a[22], a[61]); // Sum(83) + res[84] = fma52hi(res[84], a[22], a[61]); // Sum(83) + res[72] = fma52lo(res[72], a[10], a[62]); // Sum(72) + res[73] = fma52hi(res[73], a[10], a[62]); // Sum(72) + res[73] = fma52lo(res[73], a[11], a[62]); // Sum(73) + res[74] = fma52hi(res[74], a[11], a[62]); // Sum(73) + res[74] = fma52lo(res[74], a[12], a[62]); // Sum(74) + res[75] = fma52hi(res[75], a[12], a[62]); // Sum(74) + res[75] = fma52lo(res[75], a[13], a[62]); // Sum(75) + res[76] = fma52hi(res[76], a[13], a[62]); // Sum(75) + res[76] = fma52lo(res[76], a[14], a[62]); // Sum(76) + res[77] = fma52hi(res[77], a[14], a[62]); // Sum(76) + res[77] = fma52lo(res[77], a[15], a[62]); // Sum(77) + res[78] = fma52hi(res[78], a[15], a[62]); // Sum(77) + res[78] = fma52lo(res[78], a[16], a[62]); // Sum(78) + res[79] = fma52hi(res[79], a[16], a[62]); // Sum(78) + res[79] = fma52lo(res[79], a[17], a[62]); // Sum(79) + res[80] = fma52hi(res[80], a[17], a[62]); // Sum(79) + res[80] = fma52lo(res[80], a[18], a[62]); // Sum(80) + res[81] = fma52hi(res[81], a[18], a[62]); // Sum(80) + res[81] = fma52lo(res[81], a[19], a[62]); // Sum(81) + res[82] = fma52hi(res[82], a[19], a[62]); // Sum(81) + res[82] = fma52lo(res[82], a[20], a[62]); // Sum(82) + res[83] = fma52hi(res[83], a[20], a[62]); // Sum(82) + res[83] = fma52lo(res[83], a[21], a[62]); // Sum(83) + res[84] = fma52hi(res[84], a[21], a[62]); // Sum(83) + res[72] = fma52lo(res[72], a[9], a[63]); // Sum(72) + res[73] = fma52hi(res[73], a[9], a[63]); // Sum(72) + res[73] = fma52lo(res[73], a[10], a[63]); // Sum(73) + res[74] = fma52hi(res[74], a[10], a[63]); // Sum(73) + res[74] = fma52lo(res[74], a[11], a[63]); // Sum(74) + res[75] = fma52hi(res[75], a[11], a[63]); // Sum(74) + res[75] = fma52lo(res[75], a[12], a[63]); // Sum(75) + res[76] = fma52hi(res[76], a[12], a[63]); // Sum(75) + res[76] = fma52lo(res[76], a[13], a[63]); // Sum(76) + res[77] = fma52hi(res[77], a[13], a[63]); // Sum(76) + res[77] = fma52lo(res[77], a[14], a[63]); // Sum(77) + res[78] = fma52hi(res[78], a[14], a[63]); // Sum(77) + res[78] = fma52lo(res[78], a[15], a[63]); // Sum(78) + res[79] = fma52hi(res[79], a[15], a[63]); // Sum(78) + res[79] = fma52lo(res[79], a[16], a[63]); // Sum(79) + res[80] = fma52hi(res[80], a[16], a[63]); // Sum(79) + res[80] = fma52lo(res[80], a[17], a[63]); // Sum(80) + res[81] = fma52hi(res[81], a[17], a[63]); // Sum(80) + res[81] = fma52lo(res[81], a[18], a[63]); // Sum(81) + res[82] = fma52hi(res[82], a[18], a[63]); // Sum(81) + res[82] = fma52lo(res[82], a[19], a[63]); // Sum(82) + res[83] = fma52hi(res[83], a[19], a[63]); // Sum(82) + res[83] = fma52lo(res[83], a[20], a[63]); // Sum(83) + res[84] = fma52hi(res[84], a[20], a[63]); // Sum(83) + res[72] = fma52lo(res[72], a[8], a[64]); // Sum(72) + res[73] = fma52hi(res[73], a[8], a[64]); // Sum(72) + res[73] = fma52lo(res[73], a[9], a[64]); // Sum(73) + res[74] = fma52hi(res[74], a[9], a[64]); // Sum(73) + res[74] = fma52lo(res[74], a[10], a[64]); // Sum(74) + res[75] = fma52hi(res[75], a[10], a[64]); // Sum(74) + res[75] = fma52lo(res[75], a[11], a[64]); // Sum(75) + res[76] = fma52hi(res[76], a[11], a[64]); // Sum(75) + res[76] = fma52lo(res[76], a[12], a[64]); // Sum(76) + res[77] = fma52hi(res[77], a[12], a[64]); // Sum(76) + res[77] = fma52lo(res[77], a[13], a[64]); // Sum(77) + res[78] = fma52hi(res[78], a[13], a[64]); // Sum(77) + res[78] = fma52lo(res[78], a[14], a[64]); // Sum(78) + res[79] = fma52hi(res[79], a[14], a[64]); // Sum(78) + res[79] = fma52lo(res[79], a[15], a[64]); // Sum(79) + res[80] = fma52hi(res[80], a[15], a[64]); // Sum(79) + res[80] = fma52lo(res[80], a[16], a[64]); // Sum(80) + res[81] = fma52hi(res[81], a[16], a[64]); // Sum(80) + res[81] = fma52lo(res[81], a[17], a[64]); // Sum(81) + res[82] = fma52hi(res[82], a[17], a[64]); // Sum(81) + res[82] = fma52lo(res[82], a[18], a[64]); // Sum(82) + res[83] = fma52hi(res[83], a[18], a[64]); // Sum(82) + res[83] = fma52lo(res[83], a[19], a[64]); // Sum(83) + res[84] = fma52hi(res[84], a[19], a[64]); // Sum(83) + res[72] = fma52lo(res[72], a[7], a[65]); // Sum(72) + res[73] = fma52hi(res[73], a[7], a[65]); // Sum(72) + res[73] = fma52lo(res[73], a[8], a[65]); // Sum(73) + res[74] = fma52hi(res[74], a[8], a[65]); // Sum(73) + res[74] = fma52lo(res[74], a[9], a[65]); // Sum(74) + res[75] = fma52hi(res[75], a[9], a[65]); // Sum(74) + res[75] = fma52lo(res[75], a[10], a[65]); // Sum(75) + res[76] = fma52hi(res[76], a[10], a[65]); // Sum(75) + res[76] = fma52lo(res[76], a[11], a[65]); // Sum(76) + res[77] = fma52hi(res[77], a[11], a[65]); // Sum(76) + res[77] = fma52lo(res[77], a[12], a[65]); // Sum(77) + res[78] = fma52hi(res[78], a[12], a[65]); // Sum(77) + res[78] = fma52lo(res[78], a[13], a[65]); // Sum(78) + res[79] = fma52hi(res[79], a[13], a[65]); // Sum(78) + res[79] = fma52lo(res[79], a[14], a[65]); // Sum(79) + res[80] = fma52hi(res[80], a[14], a[65]); // Sum(79) + res[80] = fma52lo(res[80], a[15], a[65]); // Sum(80) + res[81] = fma52hi(res[81], a[15], a[65]); // Sum(80) + res[81] = fma52lo(res[81], a[16], a[65]); // Sum(81) + res[82] = fma52hi(res[82], a[16], a[65]); // Sum(81) + res[82] = fma52lo(res[82], a[17], a[65]); // Sum(82) + res[83] = fma52hi(res[83], a[17], a[65]); // Sum(82) + res[83] = fma52lo(res[83], a[18], a[65]); // Sum(83) + res[84] = fma52hi(res[84], a[18], a[65]); // Sum(83) + res[72] = fma52lo(res[72], a[6], a[66]); // Sum(72) + res[73] = fma52hi(res[73], a[6], a[66]); // Sum(72) + res[73] = fma52lo(res[73], a[7], a[66]); // Sum(73) + res[74] = fma52hi(res[74], a[7], a[66]); // Sum(73) + res[74] = fma52lo(res[74], a[8], a[66]); // Sum(74) + res[75] = fma52hi(res[75], a[8], a[66]); // Sum(74) + res[75] = fma52lo(res[75], a[9], a[66]); // Sum(75) + res[76] = fma52hi(res[76], a[9], a[66]); // Sum(75) + res[76] = fma52lo(res[76], a[10], a[66]); // Sum(76) + res[77] = fma52hi(res[77], a[10], a[66]); // Sum(76) + res[77] = fma52lo(res[77], a[11], a[66]); // Sum(77) + res[78] = fma52hi(res[78], a[11], a[66]); // Sum(77) + res[78] = fma52lo(res[78], a[12], a[66]); // Sum(78) + res[79] = fma52hi(res[79], a[12], a[66]); // Sum(78) + res[79] = fma52lo(res[79], a[13], a[66]); // Sum(79) + res[80] = fma52hi(res[80], a[13], a[66]); // Sum(79) + res[80] = fma52lo(res[80], a[14], a[66]); // Sum(80) + res[81] = fma52hi(res[81], a[14], a[66]); // Sum(80) + res[81] = fma52lo(res[81], a[15], a[66]); // Sum(81) + res[82] = fma52hi(res[82], a[15], a[66]); // Sum(81) + res[82] = fma52lo(res[82], a[16], a[66]); // Sum(82) + res[83] = fma52hi(res[83], a[16], a[66]); // Sum(82) + res[83] = fma52lo(res[83], a[17], a[66]); // Sum(83) + res[84] = fma52hi(res[84], a[17], a[66]); // Sum(83) + res[72] = fma52lo(res[72], a[5], a[67]); // Sum(72) + res[73] = fma52hi(res[73], a[5], a[67]); // Sum(72) + res[73] = fma52lo(res[73], a[6], a[67]); // Sum(73) + res[74] = fma52hi(res[74], a[6], a[67]); // Sum(73) + res[74] = fma52lo(res[74], a[7], a[67]); // Sum(74) + res[75] = fma52hi(res[75], a[7], a[67]); // Sum(74) + res[75] = fma52lo(res[75], a[8], a[67]); // Sum(75) + res[76] = fma52hi(res[76], a[8], a[67]); // Sum(75) + res[76] = fma52lo(res[76], a[9], a[67]); // Sum(76) + res[77] = fma52hi(res[77], a[9], a[67]); // Sum(76) + res[77] = fma52lo(res[77], a[10], a[67]); // Sum(77) + res[78] = fma52hi(res[78], a[10], a[67]); // Sum(77) + res[78] = fma52lo(res[78], a[11], a[67]); // Sum(78) + res[79] = fma52hi(res[79], a[11], a[67]); // Sum(78) + res[79] = fma52lo(res[79], a[12], a[67]); // Sum(79) + res[80] = fma52hi(res[80], a[12], a[67]); // Sum(79) + res[80] = fma52lo(res[80], a[13], a[67]); // Sum(80) + res[81] = fma52hi(res[81], a[13], a[67]); // Sum(80) + res[81] = fma52lo(res[81], a[14], a[67]); // Sum(81) + res[82] = fma52hi(res[82], a[14], a[67]); // Sum(81) + res[82] = fma52lo(res[82], a[15], a[67]); // Sum(82) + res[83] = fma52hi(res[83], a[15], a[67]); // Sum(82) + res[83] = fma52lo(res[83], a[16], a[67]); // Sum(83) + res[84] = fma52hi(res[84], a[16], a[67]); // Sum(83) + res[72] = fma52lo(res[72], a[4], a[68]); // Sum(72) + res[73] = fma52hi(res[73], a[4], a[68]); // Sum(72) + res[73] = fma52lo(res[73], a[5], a[68]); // Sum(73) + res[74] = fma52hi(res[74], a[5], a[68]); // Sum(73) + res[74] = fma52lo(res[74], a[6], a[68]); // Sum(74) + res[75] = fma52hi(res[75], a[6], a[68]); // Sum(74) + res[75] = fma52lo(res[75], a[7], a[68]); // Sum(75) + res[76] = fma52hi(res[76], a[7], a[68]); // Sum(75) + res[76] = fma52lo(res[76], a[8], a[68]); // Sum(76) + res[77] = fma52hi(res[77], a[8], a[68]); // Sum(76) + res[77] = fma52lo(res[77], a[9], a[68]); // Sum(77) + res[78] = fma52hi(res[78], a[9], a[68]); // Sum(77) + res[78] = fma52lo(res[78], a[10], a[68]); // Sum(78) + res[79] = fma52hi(res[79], a[10], a[68]); // Sum(78) + res[79] = fma52lo(res[79], a[11], a[68]); // Sum(79) + res[80] = fma52hi(res[80], a[11], a[68]); // Sum(79) + res[80] = fma52lo(res[80], a[12], a[68]); // Sum(80) + res[81] = fma52hi(res[81], a[12], a[68]); // Sum(80) + res[81] = fma52lo(res[81], a[13], a[68]); // Sum(81) + res[82] = fma52hi(res[82], a[13], a[68]); // Sum(81) + res[82] = fma52lo(res[82], a[14], a[68]); // Sum(82) + res[83] = fma52hi(res[83], a[14], a[68]); // Sum(82) + res[83] = fma52lo(res[83], a[15], a[68]); // Sum(83) + res[84] = fma52hi(res[84], a[15], a[68]); // Sum(83) + res[72] = fma52lo(res[72], a[3], a[69]); // Sum(72) + res[73] = fma52hi(res[73], a[3], a[69]); // Sum(72) + res[73] = fma52lo(res[73], a[4], a[69]); // Sum(73) + res[74] = fma52hi(res[74], a[4], a[69]); // Sum(73) + res[74] = fma52lo(res[74], a[5], a[69]); // Sum(74) + res[75] = fma52hi(res[75], a[5], a[69]); // Sum(74) + res[75] = fma52lo(res[75], a[6], a[69]); // Sum(75) + res[76] = fma52hi(res[76], a[6], a[69]); // Sum(75) + res[76] = fma52lo(res[76], a[7], a[69]); // Sum(76) + res[77] = fma52hi(res[77], a[7], a[69]); // Sum(76) + res[77] = fma52lo(res[77], a[8], a[69]); // Sum(77) + res[78] = fma52hi(res[78], a[8], a[69]); // Sum(77) + res[78] = fma52lo(res[78], a[9], a[69]); // Sum(78) + res[79] = fma52hi(res[79], a[9], a[69]); // Sum(78) + res[79] = fma52lo(res[79], a[10], a[69]); // Sum(79) + res[80] = fma52hi(res[80], a[10], a[69]); // Sum(79) + res[80] = fma52lo(res[80], a[11], a[69]); // Sum(80) + res[81] = fma52hi(res[81], a[11], a[69]); // Sum(80) + res[81] = fma52lo(res[81], a[12], a[69]); // Sum(81) + res[82] = fma52hi(res[82], a[12], a[69]); // Sum(81) + res[82] = fma52lo(res[82], a[13], a[69]); // Sum(82) + res[83] = fma52hi(res[83], a[13], a[69]); // Sum(82) + res[83] = fma52lo(res[83], a[14], a[69]); // Sum(83) + res[84] = fma52hi(res[84], a[14], a[69]); // Sum(83) + res[72] = fma52lo(res[72], a[2], a[70]); // Sum(72) + res[73] = fma52hi(res[73], a[2], a[70]); // Sum(72) + res[73] = fma52lo(res[73], a[3], a[70]); // Sum(73) + res[74] = fma52hi(res[74], a[3], a[70]); // Sum(73) + res[74] = fma52lo(res[74], a[4], a[70]); // Sum(74) + res[75] = fma52hi(res[75], a[4], a[70]); // Sum(74) + res[75] = fma52lo(res[75], a[5], a[70]); // Sum(75) + res[76] = fma52hi(res[76], a[5], a[70]); // Sum(75) + res[76] = fma52lo(res[76], a[6], a[70]); // Sum(76) + res[77] = fma52hi(res[77], a[6], a[70]); // Sum(76) + res[77] = fma52lo(res[77], a[7], a[70]); // Sum(77) + res[78] = fma52hi(res[78], a[7], a[70]); // Sum(77) + res[78] = fma52lo(res[78], a[8], a[70]); // Sum(78) + res[79] = fma52hi(res[79], a[8], a[70]); // Sum(78) + res[79] = fma52lo(res[79], a[9], a[70]); // Sum(79) + res[80] = fma52hi(res[80], a[9], a[70]); // Sum(79) + res[80] = fma52lo(res[80], a[10], a[70]); // Sum(80) + res[81] = fma52hi(res[81], a[10], a[70]); // Sum(80) + res[81] = fma52lo(res[81], a[11], a[70]); // Sum(81) + res[82] = fma52hi(res[82], a[11], a[70]); // Sum(81) + res[82] = fma52lo(res[82], a[12], a[70]); // Sum(82) + res[83] = fma52hi(res[83], a[12], a[70]); // Sum(82) + res[83] = fma52lo(res[83], a[13], a[70]); // Sum(83) + res[84] = fma52hi(res[84], a[13], a[70]); // Sum(83) + res[72] = fma52lo(res[72], a[1], a[71]); // Sum(72) + res[73] = fma52hi(res[73], a[1], a[71]); // Sum(72) + res[73] = fma52lo(res[73], a[2], a[71]); // Sum(73) + res[74] = fma52hi(res[74], a[2], a[71]); // Sum(73) + res[74] = fma52lo(res[74], a[3], a[71]); // Sum(74) + res[75] = fma52hi(res[75], a[3], a[71]); // Sum(74) + res[75] = fma52lo(res[75], a[4], a[71]); // Sum(75) + res[76] = fma52hi(res[76], a[4], a[71]); // Sum(75) + res[76] = fma52lo(res[76], a[5], a[71]); // Sum(76) + res[77] = fma52hi(res[77], a[5], a[71]); // Sum(76) + res[77] = fma52lo(res[77], a[6], a[71]); // Sum(77) + res[78] = fma52hi(res[78], a[6], a[71]); // Sum(77) + res[78] = fma52lo(res[78], a[7], a[71]); // Sum(78) + res[79] = fma52hi(res[79], a[7], a[71]); // Sum(78) + res[79] = fma52lo(res[79], a[8], a[71]); // Sum(79) + res[80] = fma52hi(res[80], a[8], a[71]); // Sum(79) + res[80] = fma52lo(res[80], a[9], a[71]); // Sum(80) + res[81] = fma52hi(res[81], a[9], a[71]); // Sum(80) + res[81] = fma52lo(res[81], a[10], a[71]); // Sum(81) + res[82] = fma52hi(res[82], a[10], a[71]); // Sum(81) + res[82] = fma52lo(res[82], a[11], a[71]); // Sum(82) + res[83] = fma52hi(res[83], a[11], a[71]); // Sum(82) + res[83] = fma52lo(res[83], a[12], a[71]); // Sum(83) + res[84] = fma52hi(res[84], a[12], a[71]); // Sum(83) + res[72] = fma52lo(res[72], a[0], a[72]); // Sum(72) + res[73] = fma52hi(res[73], a[0], a[72]); // Sum(72) + res[73] = fma52lo(res[73], a[1], a[72]); // Sum(73) + res[74] = fma52hi(res[74], a[1], a[72]); // Sum(73) + res[74] = fma52lo(res[74], a[2], a[72]); // Sum(74) + res[75] = fma52hi(res[75], a[2], a[72]); // Sum(74) + res[75] = fma52lo(res[75], a[3], a[72]); // Sum(75) + res[76] = fma52hi(res[76], a[3], a[72]); // Sum(75) + res[76] = fma52lo(res[76], a[4], a[72]); // Sum(76) + res[77] = fma52hi(res[77], a[4], a[72]); // Sum(76) + res[77] = fma52lo(res[77], a[5], a[72]); // Sum(77) + res[78] = fma52hi(res[78], a[5], a[72]); // Sum(77) + res[78] = fma52lo(res[78], a[6], a[72]); // Sum(78) + res[79] = fma52hi(res[79], a[6], a[72]); // Sum(78) + res[79] = fma52lo(res[79], a[7], a[72]); // Sum(79) + res[80] = fma52hi(res[80], a[7], a[72]); // Sum(79) + res[80] = fma52lo(res[80], a[8], a[72]); // Sum(80) + res[81] = fma52hi(res[81], a[8], a[72]); // Sum(80) + res[81] = fma52lo(res[81], a[9], a[72]); // Sum(81) + res[82] = fma52hi(res[82], a[9], a[72]); // Sum(81) + res[82] = fma52lo(res[82], a[10], a[72]); // Sum(82) + res[83] = fma52hi(res[83], a[10], a[72]); // Sum(82) + res[83] = fma52lo(res[83], a[11], a[72]); // Sum(83) + res[84] = fma52hi(res[84], a[11], a[72]); // Sum(83) + res[73] = fma52lo(res[73], a[0], a[73]); // Sum(73) + res[74] = fma52hi(res[74], a[0], a[73]); // Sum(73) + res[74] = fma52lo(res[74], a[1], a[73]); // Sum(74) + res[75] = fma52hi(res[75], a[1], a[73]); // Sum(74) + res[75] = fma52lo(res[75], a[2], a[73]); // Sum(75) + res[76] = fma52hi(res[76], a[2], a[73]); // Sum(75) + res[76] = fma52lo(res[76], a[3], a[73]); // Sum(76) + res[77] = fma52hi(res[77], a[3], a[73]); // Sum(76) + res[77] = fma52lo(res[77], a[4], a[73]); // Sum(77) + res[78] = fma52hi(res[78], a[4], a[73]); // Sum(77) + res[78] = fma52lo(res[78], a[5], a[73]); // Sum(78) + res[79] = fma52hi(res[79], a[5], a[73]); // Sum(78) + res[79] = fma52lo(res[79], a[6], a[73]); // Sum(79) + res[80] = fma52hi(res[80], a[6], a[73]); // Sum(79) + res[80] = fma52lo(res[80], a[7], a[73]); // Sum(80) + res[81] = fma52hi(res[81], a[7], a[73]); // Sum(80) + res[81] = fma52lo(res[81], a[8], a[73]); // Sum(81) + res[82] = fma52hi(res[82], a[8], a[73]); // Sum(81) + res[82] = fma52lo(res[82], a[9], a[73]); // Sum(82) + res[83] = fma52hi(res[83], a[9], a[73]); // Sum(82) + res[83] = fma52lo(res[83], a[10], a[73]); // Sum(83) + res[84] = fma52hi(res[84], a[10], a[73]); // Sum(83) + res[74] = fma52lo(res[74], a[0], a[74]); // Sum(74) + res[75] = fma52hi(res[75], a[0], a[74]); // Sum(74) + res[75] = fma52lo(res[75], a[1], a[74]); // Sum(75) + res[76] = fma52hi(res[76], a[1], a[74]); // Sum(75) + res[76] = fma52lo(res[76], a[2], a[74]); // Sum(76) + res[77] = fma52hi(res[77], a[2], a[74]); // Sum(76) + res[77] = fma52lo(res[77], a[3], a[74]); // Sum(77) + res[78] = fma52hi(res[78], a[3], a[74]); // Sum(77) + res[78] = fma52lo(res[78], a[4], a[74]); // Sum(78) + res[79] = fma52hi(res[79], a[4], a[74]); // Sum(78) + res[79] = fma52lo(res[79], a[5], a[74]); // Sum(79) + res[80] = fma52hi(res[80], a[5], a[74]); // Sum(79) + res[80] = fma52lo(res[80], a[6], a[74]); // Sum(80) + res[81] = fma52hi(res[81], a[6], a[74]); // Sum(80) + res[81] = fma52lo(res[81], a[7], a[74]); // Sum(81) + res[82] = fma52hi(res[82], a[7], a[74]); // Sum(81) + res[82] = fma52lo(res[82], a[8], a[74]); // Sum(82) + res[83] = fma52hi(res[83], a[8], a[74]); // Sum(82) + res[83] = fma52lo(res[83], a[9], a[74]); // Sum(83) + res[84] = fma52hi(res[84], a[9], a[74]); // Sum(83) + res[75] = fma52lo(res[75], a[0], a[75]); // Sum(75) + res[76] = fma52hi(res[76], a[0], a[75]); // Sum(75) + res[76] = fma52lo(res[76], a[1], a[75]); // Sum(76) + res[77] = fma52hi(res[77], a[1], a[75]); // Sum(76) + res[77] = fma52lo(res[77], a[2], a[75]); // Sum(77) + res[78] = fma52hi(res[78], a[2], a[75]); // Sum(77) + res[78] = fma52lo(res[78], a[3], a[75]); // Sum(78) + res[79] = fma52hi(res[79], a[3], a[75]); // Sum(78) + res[79] = fma52lo(res[79], a[4], a[75]); // Sum(79) + res[80] = fma52hi(res[80], a[4], a[75]); // Sum(79) + res[80] = fma52lo(res[80], a[5], a[75]); // Sum(80) + res[81] = fma52hi(res[81], a[5], a[75]); // Sum(80) + res[81] = fma52lo(res[81], a[6], a[75]); // Sum(81) + res[82] = fma52hi(res[82], a[6], a[75]); // Sum(81) + res[82] = fma52lo(res[82], a[7], a[75]); // Sum(82) + res[83] = fma52hi(res[83], a[7], a[75]); // Sum(82) + res[83] = fma52lo(res[83], a[8], a[75]); // Sum(83) + res[84] = fma52hi(res[84], a[8], a[75]); // Sum(83) + res[76] = fma52lo(res[76], a[0], a[76]); // Sum(76) + res[77] = fma52hi(res[77], a[0], a[76]); // Sum(76) + res[77] = fma52lo(res[77], a[1], a[76]); // Sum(77) + res[78] = fma52hi(res[78], a[1], a[76]); // Sum(77) + res[78] = fma52lo(res[78], a[2], a[76]); // Sum(78) + res[79] = fma52hi(res[79], a[2], a[76]); // Sum(78) + res[79] = fma52lo(res[79], a[3], a[76]); // Sum(79) + res[80] = fma52hi(res[80], a[3], a[76]); // Sum(79) + res[80] = fma52lo(res[80], a[4], a[76]); // Sum(80) + res[81] = fma52hi(res[81], a[4], a[76]); // Sum(80) + res[81] = fma52lo(res[81], a[5], a[76]); // Sum(81) + res[82] = fma52hi(res[82], a[5], a[76]); // Sum(81) + res[82] = fma52lo(res[82], a[6], a[76]); // Sum(82) + res[83] = fma52hi(res[83], a[6], a[76]); // Sum(82) + res[83] = fma52lo(res[83], a[7], a[76]); // Sum(83) + res[84] = fma52hi(res[84], a[7], a[76]); // Sum(83) + res[77] = fma52lo(res[77], a[0], a[77]); // Sum(77) + res[78] = fma52hi(res[78], a[0], a[77]); // Sum(77) + res[78] = fma52lo(res[78], a[1], a[77]); // Sum(78) + res[79] = fma52hi(res[79], a[1], a[77]); // Sum(78) + res[79] = fma52lo(res[79], a[2], a[77]); // Sum(79) + res[80] = fma52hi(res[80], a[2], a[77]); // Sum(79) + res[80] = fma52lo(res[80], a[3], a[77]); // Sum(80) + res[81] = fma52hi(res[81], a[3], a[77]); // Sum(80) + res[81] = fma52lo(res[81], a[4], a[77]); // Sum(81) + res[82] = fma52hi(res[82], a[4], a[77]); // Sum(81) + res[82] = fma52lo(res[82], a[5], a[77]); // Sum(82) + res[83] = fma52hi(res[83], a[5], a[77]); // Sum(82) + res[83] = fma52lo(res[83], a[6], a[77]); // Sum(83) + res[84] = fma52hi(res[84], a[6], a[77]); // Sum(83) + res[78] = fma52lo(res[78], a[0], a[78]); // Sum(78) + res[79] = fma52hi(res[79], a[0], a[78]); // Sum(78) + res[79] = fma52lo(res[79], a[1], a[78]); // Sum(79) + res[80] = fma52hi(res[80], a[1], a[78]); // Sum(79) + res[80] = fma52lo(res[80], a[2], a[78]); // Sum(80) + res[81] = fma52hi(res[81], a[2], a[78]); // Sum(80) + res[81] = fma52lo(res[81], a[3], a[78]); // Sum(81) + res[82] = fma52hi(res[82], a[3], a[78]); // Sum(81) + res[82] = fma52lo(res[82], a[4], a[78]); // Sum(82) + res[83] = fma52hi(res[83], a[4], a[78]); // Sum(82) + res[83] = fma52lo(res[83], a[5], a[78]); // Sum(83) + res[84] = fma52hi(res[84], a[5], a[78]); // Sum(83) + res[72] = add64(res[72], res[72]); // Double(72) + res[73] = add64(res[73], res[73]); // Double(73) + res[74] = add64(res[74], res[74]); // Double(74) + res[75] = add64(res[75], res[75]); // Double(75) + res[76] = add64(res[76], res[76]); // Double(76) + res[77] = add64(res[77], res[77]); // Double(77) + res[78] = add64(res[78], res[78]); // Double(78) + res[79] = add64(res[79], res[79]); // Double(79) + res[80] = add64(res[80], res[80]); // Double(80) + res[81] = add64(res[81], res[81]); // Double(81) + res[82] = add64(res[82], res[82]); // Double(82) + res[83] = add64(res[83], res[83]); // Double(83) + res[72] = fma52lo(res[72], a[36], a[36]); // Add sqr(72) + res[73] = fma52hi(res[73], a[36], a[36]); // Add sqr(72) + res[74] = fma52lo(res[74], a[37], a[37]); // Add sqr(74) + res[75] = fma52hi(res[75], a[37], a[37]); // Add sqr(74) + res[76] = fma52lo(res[76], a[38], a[38]); // Add sqr(76) + res[77] = fma52hi(res[77], a[38], a[38]); // Add sqr(76) + res[78] = fma52lo(res[78], a[39], a[39]); // Add sqr(78) + res[79] = fma52hi(res[79], a[39], a[39]); // Add sqr(78) + res[80] = fma52lo(res[80], a[40], a[40]); // Add sqr(80) + res[81] = fma52hi(res[81], a[40], a[40]); // Add sqr(80) + res[82] = fma52lo(res[82], a[41], a[41]); // Add sqr(82) + res[83] = fma52hi(res[83], a[41], a[41]); // Add sqr(82) + res[84] = fma52lo(res[84], a[41], a[43]); // Sum(84) + res[85] = fma52hi(res[85], a[41], a[43]); // Sum(84) + res[85] = fma52lo(res[85], a[42], a[43]); // Sum(85) + res[86] = fma52hi(res[86], a[42], a[43]); // Sum(85) + res[84] = fma52lo(res[84], a[40], a[44]); // Sum(84) + res[85] = fma52hi(res[85], a[40], a[44]); // Sum(84) + res[85] = fma52lo(res[85], a[41], a[44]); // Sum(85) + res[86] = fma52hi(res[86], a[41], a[44]); // Sum(85) + res[86] = fma52lo(res[86], a[42], a[44]); // Sum(86) + res[87] = fma52hi(res[87], a[42], a[44]); // Sum(86) + res[87] = fma52lo(res[87], a[43], a[44]); // Sum(87) + res[88] = fma52hi(res[88], a[43], a[44]); // Sum(87) + res[84] = fma52lo(res[84], a[39], a[45]); // Sum(84) + res[85] = fma52hi(res[85], a[39], a[45]); // Sum(84) + res[85] = fma52lo(res[85], a[40], a[45]); // Sum(85) + res[86] = fma52hi(res[86], a[40], a[45]); // Sum(85) + res[86] = fma52lo(res[86], a[41], a[45]); // Sum(86) + res[87] = fma52hi(res[87], a[41], a[45]); // Sum(86) + res[87] = fma52lo(res[87], a[42], a[45]); // Sum(87) + res[88] = fma52hi(res[88], a[42], a[45]); // Sum(87) + res[88] = fma52lo(res[88], a[43], a[45]); // Sum(88) + res[89] = fma52hi(res[89], a[43], a[45]); // Sum(88) + res[89] = fma52lo(res[89], a[44], a[45]); // Sum(89) + res[90] = fma52hi(res[90], a[44], a[45]); // Sum(89) + res[84] = fma52lo(res[84], a[38], a[46]); // Sum(84) + res[85] = fma52hi(res[85], a[38], a[46]); // Sum(84) + res[85] = fma52lo(res[85], a[39], a[46]); // Sum(85) + res[86] = fma52hi(res[86], a[39], a[46]); // Sum(85) + res[86] = fma52lo(res[86], a[40], a[46]); // Sum(86) + res[87] = fma52hi(res[87], a[40], a[46]); // Sum(86) + res[87] = fma52lo(res[87], a[41], a[46]); // Sum(87) + res[88] = fma52hi(res[88], a[41], a[46]); // Sum(87) + res[88] = fma52lo(res[88], a[42], a[46]); // Sum(88) + res[89] = fma52hi(res[89], a[42], a[46]); // Sum(88) + res[89] = fma52lo(res[89], a[43], a[46]); // Sum(89) + res[90] = fma52hi(res[90], a[43], a[46]); // Sum(89) + res[90] = fma52lo(res[90], a[44], a[46]); // Sum(90) + res[91] = fma52hi(res[91], a[44], a[46]); // Sum(90) + res[91] = fma52lo(res[91], a[45], a[46]); // Sum(91) + res[92] = fma52hi(res[92], a[45], a[46]); // Sum(91) + res[84] = fma52lo(res[84], a[37], a[47]); // Sum(84) + res[85] = fma52hi(res[85], a[37], a[47]); // Sum(84) + res[85] = fma52lo(res[85], a[38], a[47]); // Sum(85) + res[86] = fma52hi(res[86], a[38], a[47]); // Sum(85) + res[86] = fma52lo(res[86], a[39], a[47]); // Sum(86) + res[87] = fma52hi(res[87], a[39], a[47]); // Sum(86) + res[87] = fma52lo(res[87], a[40], a[47]); // Sum(87) + res[88] = fma52hi(res[88], a[40], a[47]); // Sum(87) + res[88] = fma52lo(res[88], a[41], a[47]); // Sum(88) + res[89] = fma52hi(res[89], a[41], a[47]); // Sum(88) + res[89] = fma52lo(res[89], a[42], a[47]); // Sum(89) + res[90] = fma52hi(res[90], a[42], a[47]); // Sum(89) + res[90] = fma52lo(res[90], a[43], a[47]); // Sum(90) + res[91] = fma52hi(res[91], a[43], a[47]); // Sum(90) + res[91] = fma52lo(res[91], a[44], a[47]); // Sum(91) + res[92] = fma52hi(res[92], a[44], a[47]); // Sum(91) + res[92] = fma52lo(res[92], a[45], a[47]); // Sum(92) + res[93] = fma52hi(res[93], a[45], a[47]); // Sum(92) + res[93] = fma52lo(res[93], a[46], a[47]); // Sum(93) + res[94] = fma52hi(res[94], a[46], a[47]); // Sum(93) + res[84] = fma52lo(res[84], a[36], a[48]); // Sum(84) + res[85] = fma52hi(res[85], a[36], a[48]); // Sum(84) + res[85] = fma52lo(res[85], a[37], a[48]); // Sum(85) + res[86] = fma52hi(res[86], a[37], a[48]); // Sum(85) + res[86] = fma52lo(res[86], a[38], a[48]); // Sum(86) + res[87] = fma52hi(res[87], a[38], a[48]); // Sum(86) + res[87] = fma52lo(res[87], a[39], a[48]); // Sum(87) + res[88] = fma52hi(res[88], a[39], a[48]); // Sum(87) + res[88] = fma52lo(res[88], a[40], a[48]); // Sum(88) + res[89] = fma52hi(res[89], a[40], a[48]); // Sum(88) + res[89] = fma52lo(res[89], a[41], a[48]); // Sum(89) + res[90] = fma52hi(res[90], a[41], a[48]); // Sum(89) + res[90] = fma52lo(res[90], a[42], a[48]); // Sum(90) + res[91] = fma52hi(res[91], a[42], a[48]); // Sum(90) + res[91] = fma52lo(res[91], a[43], a[48]); // Sum(91) + res[92] = fma52hi(res[92], a[43], a[48]); // Sum(91) + res[92] = fma52lo(res[92], a[44], a[48]); // Sum(92) + res[93] = fma52hi(res[93], a[44], a[48]); // Sum(92) + res[93] = fma52lo(res[93], a[45], a[48]); // Sum(93) + res[94] = fma52hi(res[94], a[45], a[48]); // Sum(93) + res[94] = fma52lo(res[94], a[46], a[48]); // Sum(94) + res[95] = fma52hi(res[95], a[46], a[48]); // Sum(94) + res[95] = fma52lo(res[95], a[47], a[48]); // Sum(95) + res[96] = fma52hi(res[96], a[47], a[48]); // Sum(95) + res[84] = fma52lo(res[84], a[35], a[49]); // Sum(84) + res[85] = fma52hi(res[85], a[35], a[49]); // Sum(84) + res[85] = fma52lo(res[85], a[36], a[49]); // Sum(85) + res[86] = fma52hi(res[86], a[36], a[49]); // Sum(85) + res[86] = fma52lo(res[86], a[37], a[49]); // Sum(86) + res[87] = fma52hi(res[87], a[37], a[49]); // Sum(86) + res[87] = fma52lo(res[87], a[38], a[49]); // Sum(87) + res[88] = fma52hi(res[88], a[38], a[49]); // Sum(87) + res[88] = fma52lo(res[88], a[39], a[49]); // Sum(88) + res[89] = fma52hi(res[89], a[39], a[49]); // Sum(88) + res[89] = fma52lo(res[89], a[40], a[49]); // Sum(89) + res[90] = fma52hi(res[90], a[40], a[49]); // Sum(89) + res[90] = fma52lo(res[90], a[41], a[49]); // Sum(90) + res[91] = fma52hi(res[91], a[41], a[49]); // Sum(90) + res[91] = fma52lo(res[91], a[42], a[49]); // Sum(91) + res[92] = fma52hi(res[92], a[42], a[49]); // Sum(91) + res[92] = fma52lo(res[92], a[43], a[49]); // Sum(92) + res[93] = fma52hi(res[93], a[43], a[49]); // Sum(92) + res[93] = fma52lo(res[93], a[44], a[49]); // Sum(93) + res[94] = fma52hi(res[94], a[44], a[49]); // Sum(93) + res[94] = fma52lo(res[94], a[45], a[49]); // Sum(94) + res[95] = fma52hi(res[95], a[45], a[49]); // Sum(94) + res[95] = fma52lo(res[95], a[46], a[49]); // Sum(95) + res[96] = fma52hi(res[96], a[46], a[49]); // Sum(95) + res[84] = fma52lo(res[84], a[34], a[50]); // Sum(84) + res[85] = fma52hi(res[85], a[34], a[50]); // Sum(84) + res[85] = fma52lo(res[85], a[35], a[50]); // Sum(85) + res[86] = fma52hi(res[86], a[35], a[50]); // Sum(85) + res[86] = fma52lo(res[86], a[36], a[50]); // Sum(86) + res[87] = fma52hi(res[87], a[36], a[50]); // Sum(86) + res[87] = fma52lo(res[87], a[37], a[50]); // Sum(87) + res[88] = fma52hi(res[88], a[37], a[50]); // Sum(87) + res[88] = fma52lo(res[88], a[38], a[50]); // Sum(88) + res[89] = fma52hi(res[89], a[38], a[50]); // Sum(88) + res[89] = fma52lo(res[89], a[39], a[50]); // Sum(89) + res[90] = fma52hi(res[90], a[39], a[50]); // Sum(89) + res[90] = fma52lo(res[90], a[40], a[50]); // Sum(90) + res[91] = fma52hi(res[91], a[40], a[50]); // Sum(90) + res[91] = fma52lo(res[91], a[41], a[50]); // Sum(91) + res[92] = fma52hi(res[92], a[41], a[50]); // Sum(91) + res[92] = fma52lo(res[92], a[42], a[50]); // Sum(92) + res[93] = fma52hi(res[93], a[42], a[50]); // Sum(92) + res[93] = fma52lo(res[93], a[43], a[50]); // Sum(93) + res[94] = fma52hi(res[94], a[43], a[50]); // Sum(93) + res[94] = fma52lo(res[94], a[44], a[50]); // Sum(94) + res[95] = fma52hi(res[95], a[44], a[50]); // Sum(94) + res[95] = fma52lo(res[95], a[45], a[50]); // Sum(95) + res[96] = fma52hi(res[96], a[45], a[50]); // Sum(95) + res[84] = fma52lo(res[84], a[33], a[51]); // Sum(84) + res[85] = fma52hi(res[85], a[33], a[51]); // Sum(84) + res[85] = fma52lo(res[85], a[34], a[51]); // Sum(85) + res[86] = fma52hi(res[86], a[34], a[51]); // Sum(85) + res[86] = fma52lo(res[86], a[35], a[51]); // Sum(86) + res[87] = fma52hi(res[87], a[35], a[51]); // Sum(86) + res[87] = fma52lo(res[87], a[36], a[51]); // Sum(87) + res[88] = fma52hi(res[88], a[36], a[51]); // Sum(87) + res[88] = fma52lo(res[88], a[37], a[51]); // Sum(88) + res[89] = fma52hi(res[89], a[37], a[51]); // Sum(88) + res[89] = fma52lo(res[89], a[38], a[51]); // Sum(89) + res[90] = fma52hi(res[90], a[38], a[51]); // Sum(89) + res[90] = fma52lo(res[90], a[39], a[51]); // Sum(90) + res[91] = fma52hi(res[91], a[39], a[51]); // Sum(90) + res[91] = fma52lo(res[91], a[40], a[51]); // Sum(91) + res[92] = fma52hi(res[92], a[40], a[51]); // Sum(91) + res[92] = fma52lo(res[92], a[41], a[51]); // Sum(92) + res[93] = fma52hi(res[93], a[41], a[51]); // Sum(92) + res[93] = fma52lo(res[93], a[42], a[51]); // Sum(93) + res[94] = fma52hi(res[94], a[42], a[51]); // Sum(93) + res[94] = fma52lo(res[94], a[43], a[51]); // Sum(94) + res[95] = fma52hi(res[95], a[43], a[51]); // Sum(94) + res[95] = fma52lo(res[95], a[44], a[51]); // Sum(95) + res[96] = fma52hi(res[96], a[44], a[51]); // Sum(95) + res[84] = fma52lo(res[84], a[32], a[52]); // Sum(84) + res[85] = fma52hi(res[85], a[32], a[52]); // Sum(84) + res[85] = fma52lo(res[85], a[33], a[52]); // Sum(85) + res[86] = fma52hi(res[86], a[33], a[52]); // Sum(85) + res[86] = fma52lo(res[86], a[34], a[52]); // Sum(86) + res[87] = fma52hi(res[87], a[34], a[52]); // Sum(86) + res[87] = fma52lo(res[87], a[35], a[52]); // Sum(87) + res[88] = fma52hi(res[88], a[35], a[52]); // Sum(87) + res[88] = fma52lo(res[88], a[36], a[52]); // Sum(88) + res[89] = fma52hi(res[89], a[36], a[52]); // Sum(88) + res[89] = fma52lo(res[89], a[37], a[52]); // Sum(89) + res[90] = fma52hi(res[90], a[37], a[52]); // Sum(89) + res[90] = fma52lo(res[90], a[38], a[52]); // Sum(90) + res[91] = fma52hi(res[91], a[38], a[52]); // Sum(90) + res[91] = fma52lo(res[91], a[39], a[52]); // Sum(91) + res[92] = fma52hi(res[92], a[39], a[52]); // Sum(91) + res[92] = fma52lo(res[92], a[40], a[52]); // Sum(92) + res[93] = fma52hi(res[93], a[40], a[52]); // Sum(92) + res[93] = fma52lo(res[93], a[41], a[52]); // Sum(93) + res[94] = fma52hi(res[94], a[41], a[52]); // Sum(93) + res[94] = fma52lo(res[94], a[42], a[52]); // Sum(94) + res[95] = fma52hi(res[95], a[42], a[52]); // Sum(94) + res[95] = fma52lo(res[95], a[43], a[52]); // Sum(95) + res[96] = fma52hi(res[96], a[43], a[52]); // Sum(95) + res[84] = fma52lo(res[84], a[31], a[53]); // Sum(84) + res[85] = fma52hi(res[85], a[31], a[53]); // Sum(84) + res[85] = fma52lo(res[85], a[32], a[53]); // Sum(85) + res[86] = fma52hi(res[86], a[32], a[53]); // Sum(85) + res[86] = fma52lo(res[86], a[33], a[53]); // Sum(86) + res[87] = fma52hi(res[87], a[33], a[53]); // Sum(86) + res[87] = fma52lo(res[87], a[34], a[53]); // Sum(87) + res[88] = fma52hi(res[88], a[34], a[53]); // Sum(87) + res[88] = fma52lo(res[88], a[35], a[53]); // Sum(88) + res[89] = fma52hi(res[89], a[35], a[53]); // Sum(88) + res[89] = fma52lo(res[89], a[36], a[53]); // Sum(89) + res[90] = fma52hi(res[90], a[36], a[53]); // Sum(89) + res[90] = fma52lo(res[90], a[37], a[53]); // Sum(90) + res[91] = fma52hi(res[91], a[37], a[53]); // Sum(90) + res[91] = fma52lo(res[91], a[38], a[53]); // Sum(91) + res[92] = fma52hi(res[92], a[38], a[53]); // Sum(91) + res[92] = fma52lo(res[92], a[39], a[53]); // Sum(92) + res[93] = fma52hi(res[93], a[39], a[53]); // Sum(92) + res[93] = fma52lo(res[93], a[40], a[53]); // Sum(93) + res[94] = fma52hi(res[94], a[40], a[53]); // Sum(93) + res[94] = fma52lo(res[94], a[41], a[53]); // Sum(94) + res[95] = fma52hi(res[95], a[41], a[53]); // Sum(94) + res[95] = fma52lo(res[95], a[42], a[53]); // Sum(95) + res[96] = fma52hi(res[96], a[42], a[53]); // Sum(95) + res[84] = fma52lo(res[84], a[30], a[54]); // Sum(84) + res[85] = fma52hi(res[85], a[30], a[54]); // Sum(84) + res[85] = fma52lo(res[85], a[31], a[54]); // Sum(85) + res[86] = fma52hi(res[86], a[31], a[54]); // Sum(85) + res[86] = fma52lo(res[86], a[32], a[54]); // Sum(86) + res[87] = fma52hi(res[87], a[32], a[54]); // Sum(86) + res[87] = fma52lo(res[87], a[33], a[54]); // Sum(87) + res[88] = fma52hi(res[88], a[33], a[54]); // Sum(87) + res[88] = fma52lo(res[88], a[34], a[54]); // Sum(88) + res[89] = fma52hi(res[89], a[34], a[54]); // Sum(88) + res[89] = fma52lo(res[89], a[35], a[54]); // Sum(89) + res[90] = fma52hi(res[90], a[35], a[54]); // Sum(89) + res[90] = fma52lo(res[90], a[36], a[54]); // Sum(90) + res[91] = fma52hi(res[91], a[36], a[54]); // Sum(90) + res[91] = fma52lo(res[91], a[37], a[54]); // Sum(91) + res[92] = fma52hi(res[92], a[37], a[54]); // Sum(91) + res[92] = fma52lo(res[92], a[38], a[54]); // Sum(92) + res[93] = fma52hi(res[93], a[38], a[54]); // Sum(92) + res[93] = fma52lo(res[93], a[39], a[54]); // Sum(93) + res[94] = fma52hi(res[94], a[39], a[54]); // Sum(93) + res[94] = fma52lo(res[94], a[40], a[54]); // Sum(94) + res[95] = fma52hi(res[95], a[40], a[54]); // Sum(94) + res[95] = fma52lo(res[95], a[41], a[54]); // Sum(95) + res[96] = fma52hi(res[96], a[41], a[54]); // Sum(95) + res[84] = fma52lo(res[84], a[29], a[55]); // Sum(84) + res[85] = fma52hi(res[85], a[29], a[55]); // Sum(84) + res[85] = fma52lo(res[85], a[30], a[55]); // Sum(85) + res[86] = fma52hi(res[86], a[30], a[55]); // Sum(85) + res[86] = fma52lo(res[86], a[31], a[55]); // Sum(86) + res[87] = fma52hi(res[87], a[31], a[55]); // Sum(86) + res[87] = fma52lo(res[87], a[32], a[55]); // Sum(87) + res[88] = fma52hi(res[88], a[32], a[55]); // Sum(87) + res[88] = fma52lo(res[88], a[33], a[55]); // Sum(88) + res[89] = fma52hi(res[89], a[33], a[55]); // Sum(88) + res[89] = fma52lo(res[89], a[34], a[55]); // Sum(89) + res[90] = fma52hi(res[90], a[34], a[55]); // Sum(89) + res[90] = fma52lo(res[90], a[35], a[55]); // Sum(90) + res[91] = fma52hi(res[91], a[35], a[55]); // Sum(90) + res[91] = fma52lo(res[91], a[36], a[55]); // Sum(91) + res[92] = fma52hi(res[92], a[36], a[55]); // Sum(91) + res[92] = fma52lo(res[92], a[37], a[55]); // Sum(92) + res[93] = fma52hi(res[93], a[37], a[55]); // Sum(92) + res[93] = fma52lo(res[93], a[38], a[55]); // Sum(93) + res[94] = fma52hi(res[94], a[38], a[55]); // Sum(93) + res[94] = fma52lo(res[94], a[39], a[55]); // Sum(94) + res[95] = fma52hi(res[95], a[39], a[55]); // Sum(94) + res[95] = fma52lo(res[95], a[40], a[55]); // Sum(95) + res[96] = fma52hi(res[96], a[40], a[55]); // Sum(95) + res[84] = fma52lo(res[84], a[28], a[56]); // Sum(84) + res[85] = fma52hi(res[85], a[28], a[56]); // Sum(84) + res[85] = fma52lo(res[85], a[29], a[56]); // Sum(85) + res[86] = fma52hi(res[86], a[29], a[56]); // Sum(85) + res[86] = fma52lo(res[86], a[30], a[56]); // Sum(86) + res[87] = fma52hi(res[87], a[30], a[56]); // Sum(86) + res[87] = fma52lo(res[87], a[31], a[56]); // Sum(87) + res[88] = fma52hi(res[88], a[31], a[56]); // Sum(87) + res[88] = fma52lo(res[88], a[32], a[56]); // Sum(88) + res[89] = fma52hi(res[89], a[32], a[56]); // Sum(88) + res[89] = fma52lo(res[89], a[33], a[56]); // Sum(89) + res[90] = fma52hi(res[90], a[33], a[56]); // Sum(89) + res[90] = fma52lo(res[90], a[34], a[56]); // Sum(90) + res[91] = fma52hi(res[91], a[34], a[56]); // Sum(90) + res[91] = fma52lo(res[91], a[35], a[56]); // Sum(91) + res[92] = fma52hi(res[92], a[35], a[56]); // Sum(91) + res[92] = fma52lo(res[92], a[36], a[56]); // Sum(92) + res[93] = fma52hi(res[93], a[36], a[56]); // Sum(92) + res[93] = fma52lo(res[93], a[37], a[56]); // Sum(93) + res[94] = fma52hi(res[94], a[37], a[56]); // Sum(93) + res[94] = fma52lo(res[94], a[38], a[56]); // Sum(94) + res[95] = fma52hi(res[95], a[38], a[56]); // Sum(94) + res[95] = fma52lo(res[95], a[39], a[56]); // Sum(95) + res[96] = fma52hi(res[96], a[39], a[56]); // Sum(95) + res[84] = fma52lo(res[84], a[27], a[57]); // Sum(84) + res[85] = fma52hi(res[85], a[27], a[57]); // Sum(84) + res[85] = fma52lo(res[85], a[28], a[57]); // Sum(85) + res[86] = fma52hi(res[86], a[28], a[57]); // Sum(85) + res[86] = fma52lo(res[86], a[29], a[57]); // Sum(86) + res[87] = fma52hi(res[87], a[29], a[57]); // Sum(86) + res[87] = fma52lo(res[87], a[30], a[57]); // Sum(87) + res[88] = fma52hi(res[88], a[30], a[57]); // Sum(87) + res[88] = fma52lo(res[88], a[31], a[57]); // Sum(88) + res[89] = fma52hi(res[89], a[31], a[57]); // Sum(88) + res[89] = fma52lo(res[89], a[32], a[57]); // Sum(89) + res[90] = fma52hi(res[90], a[32], a[57]); // Sum(89) + res[90] = fma52lo(res[90], a[33], a[57]); // Sum(90) + res[91] = fma52hi(res[91], a[33], a[57]); // Sum(90) + res[91] = fma52lo(res[91], a[34], a[57]); // Sum(91) + res[92] = fma52hi(res[92], a[34], a[57]); // Sum(91) + res[92] = fma52lo(res[92], a[35], a[57]); // Sum(92) + res[93] = fma52hi(res[93], a[35], a[57]); // Sum(92) + res[93] = fma52lo(res[93], a[36], a[57]); // Sum(93) + res[94] = fma52hi(res[94], a[36], a[57]); // Sum(93) + res[94] = fma52lo(res[94], a[37], a[57]); // Sum(94) + res[95] = fma52hi(res[95], a[37], a[57]); // Sum(94) + res[95] = fma52lo(res[95], a[38], a[57]); // Sum(95) + res[96] = fma52hi(res[96], a[38], a[57]); // Sum(95) + res[84] = fma52lo(res[84], a[26], a[58]); // Sum(84) + res[85] = fma52hi(res[85], a[26], a[58]); // Sum(84) + res[85] = fma52lo(res[85], a[27], a[58]); // Sum(85) + res[86] = fma52hi(res[86], a[27], a[58]); // Sum(85) + res[86] = fma52lo(res[86], a[28], a[58]); // Sum(86) + res[87] = fma52hi(res[87], a[28], a[58]); // Sum(86) + res[87] = fma52lo(res[87], a[29], a[58]); // Sum(87) + res[88] = fma52hi(res[88], a[29], a[58]); // Sum(87) + res[88] = fma52lo(res[88], a[30], a[58]); // Sum(88) + res[89] = fma52hi(res[89], a[30], a[58]); // Sum(88) + res[89] = fma52lo(res[89], a[31], a[58]); // Sum(89) + res[90] = fma52hi(res[90], a[31], a[58]); // Sum(89) + res[90] = fma52lo(res[90], a[32], a[58]); // Sum(90) + res[91] = fma52hi(res[91], a[32], a[58]); // Sum(90) + res[91] = fma52lo(res[91], a[33], a[58]); // Sum(91) + res[92] = fma52hi(res[92], a[33], a[58]); // Sum(91) + res[92] = fma52lo(res[92], a[34], a[58]); // Sum(92) + res[93] = fma52hi(res[93], a[34], a[58]); // Sum(92) + res[93] = fma52lo(res[93], a[35], a[58]); // Sum(93) + res[94] = fma52hi(res[94], a[35], a[58]); // Sum(93) + res[94] = fma52lo(res[94], a[36], a[58]); // Sum(94) + res[95] = fma52hi(res[95], a[36], a[58]); // Sum(94) + res[95] = fma52lo(res[95], a[37], a[58]); // Sum(95) + res[96] = fma52hi(res[96], a[37], a[58]); // Sum(95) + res[84] = fma52lo(res[84], a[25], a[59]); // Sum(84) + res[85] = fma52hi(res[85], a[25], a[59]); // Sum(84) + res[85] = fma52lo(res[85], a[26], a[59]); // Sum(85) + res[86] = fma52hi(res[86], a[26], a[59]); // Sum(85) + res[86] = fma52lo(res[86], a[27], a[59]); // Sum(86) + res[87] = fma52hi(res[87], a[27], a[59]); // Sum(86) + res[87] = fma52lo(res[87], a[28], a[59]); // Sum(87) + res[88] = fma52hi(res[88], a[28], a[59]); // Sum(87) + res[88] = fma52lo(res[88], a[29], a[59]); // Sum(88) + res[89] = fma52hi(res[89], a[29], a[59]); // Sum(88) + res[89] = fma52lo(res[89], a[30], a[59]); // Sum(89) + res[90] = fma52hi(res[90], a[30], a[59]); // Sum(89) + res[90] = fma52lo(res[90], a[31], a[59]); // Sum(90) + res[91] = fma52hi(res[91], a[31], a[59]); // Sum(90) + res[91] = fma52lo(res[91], a[32], a[59]); // Sum(91) + res[92] = fma52hi(res[92], a[32], a[59]); // Sum(91) + res[92] = fma52lo(res[92], a[33], a[59]); // Sum(92) + res[93] = fma52hi(res[93], a[33], a[59]); // Sum(92) + res[93] = fma52lo(res[93], a[34], a[59]); // Sum(93) + res[94] = fma52hi(res[94], a[34], a[59]); // Sum(93) + res[94] = fma52lo(res[94], a[35], a[59]); // Sum(94) + res[95] = fma52hi(res[95], a[35], a[59]); // Sum(94) + res[95] = fma52lo(res[95], a[36], a[59]); // Sum(95) + res[96] = fma52hi(res[96], a[36], a[59]); // Sum(95) + res[84] = fma52lo(res[84], a[24], a[60]); // Sum(84) + res[85] = fma52hi(res[85], a[24], a[60]); // Sum(84) + res[85] = fma52lo(res[85], a[25], a[60]); // Sum(85) + res[86] = fma52hi(res[86], a[25], a[60]); // Sum(85) + res[86] = fma52lo(res[86], a[26], a[60]); // Sum(86) + res[87] = fma52hi(res[87], a[26], a[60]); // Sum(86) + res[87] = fma52lo(res[87], a[27], a[60]); // Sum(87) + res[88] = fma52hi(res[88], a[27], a[60]); // Sum(87) + res[88] = fma52lo(res[88], a[28], a[60]); // Sum(88) + res[89] = fma52hi(res[89], a[28], a[60]); // Sum(88) + res[89] = fma52lo(res[89], a[29], a[60]); // Sum(89) + res[90] = fma52hi(res[90], a[29], a[60]); // Sum(89) + res[90] = fma52lo(res[90], a[30], a[60]); // Sum(90) + res[91] = fma52hi(res[91], a[30], a[60]); // Sum(90) + res[91] = fma52lo(res[91], a[31], a[60]); // Sum(91) + res[92] = fma52hi(res[92], a[31], a[60]); // Sum(91) + res[92] = fma52lo(res[92], a[32], a[60]); // Sum(92) + res[93] = fma52hi(res[93], a[32], a[60]); // Sum(92) + res[93] = fma52lo(res[93], a[33], a[60]); // Sum(93) + res[94] = fma52hi(res[94], a[33], a[60]); // Sum(93) + res[94] = fma52lo(res[94], a[34], a[60]); // Sum(94) + res[95] = fma52hi(res[95], a[34], a[60]); // Sum(94) + res[95] = fma52lo(res[95], a[35], a[60]); // Sum(95) + res[96] = fma52hi(res[96], a[35], a[60]); // Sum(95) + res[84] = fma52lo(res[84], a[23], a[61]); // Sum(84) + res[85] = fma52hi(res[85], a[23], a[61]); // Sum(84) + res[85] = fma52lo(res[85], a[24], a[61]); // Sum(85) + res[86] = fma52hi(res[86], a[24], a[61]); // Sum(85) + res[86] = fma52lo(res[86], a[25], a[61]); // Sum(86) + res[87] = fma52hi(res[87], a[25], a[61]); // Sum(86) + res[87] = fma52lo(res[87], a[26], a[61]); // Sum(87) + res[88] = fma52hi(res[88], a[26], a[61]); // Sum(87) + res[88] = fma52lo(res[88], a[27], a[61]); // Sum(88) + res[89] = fma52hi(res[89], a[27], a[61]); // Sum(88) + res[89] = fma52lo(res[89], a[28], a[61]); // Sum(89) + res[90] = fma52hi(res[90], a[28], a[61]); // Sum(89) + res[90] = fma52lo(res[90], a[29], a[61]); // Sum(90) + res[91] = fma52hi(res[91], a[29], a[61]); // Sum(90) + res[91] = fma52lo(res[91], a[30], a[61]); // Sum(91) + res[92] = fma52hi(res[92], a[30], a[61]); // Sum(91) + res[92] = fma52lo(res[92], a[31], a[61]); // Sum(92) + res[93] = fma52hi(res[93], a[31], a[61]); // Sum(92) + res[93] = fma52lo(res[93], a[32], a[61]); // Sum(93) + res[94] = fma52hi(res[94], a[32], a[61]); // Sum(93) + res[94] = fma52lo(res[94], a[33], a[61]); // Sum(94) + res[95] = fma52hi(res[95], a[33], a[61]); // Sum(94) + res[95] = fma52lo(res[95], a[34], a[61]); // Sum(95) + res[96] = fma52hi(res[96], a[34], a[61]); // Sum(95) + res[84] = fma52lo(res[84], a[22], a[62]); // Sum(84) + res[85] = fma52hi(res[85], a[22], a[62]); // Sum(84) + res[85] = fma52lo(res[85], a[23], a[62]); // Sum(85) + res[86] = fma52hi(res[86], a[23], a[62]); // Sum(85) + res[86] = fma52lo(res[86], a[24], a[62]); // Sum(86) + res[87] = fma52hi(res[87], a[24], a[62]); // Sum(86) + res[87] = fma52lo(res[87], a[25], a[62]); // Sum(87) + res[88] = fma52hi(res[88], a[25], a[62]); // Sum(87) + res[88] = fma52lo(res[88], a[26], a[62]); // Sum(88) + res[89] = fma52hi(res[89], a[26], a[62]); // Sum(88) + res[89] = fma52lo(res[89], a[27], a[62]); // Sum(89) + res[90] = fma52hi(res[90], a[27], a[62]); // Sum(89) + res[90] = fma52lo(res[90], a[28], a[62]); // Sum(90) + res[91] = fma52hi(res[91], a[28], a[62]); // Sum(90) + res[91] = fma52lo(res[91], a[29], a[62]); // Sum(91) + res[92] = fma52hi(res[92], a[29], a[62]); // Sum(91) + res[92] = fma52lo(res[92], a[30], a[62]); // Sum(92) + res[93] = fma52hi(res[93], a[30], a[62]); // Sum(92) + res[93] = fma52lo(res[93], a[31], a[62]); // Sum(93) + res[94] = fma52hi(res[94], a[31], a[62]); // Sum(93) + res[94] = fma52lo(res[94], a[32], a[62]); // Sum(94) + res[95] = fma52hi(res[95], a[32], a[62]); // Sum(94) + res[95] = fma52lo(res[95], a[33], a[62]); // Sum(95) + res[96] = fma52hi(res[96], a[33], a[62]); // Sum(95) + res[84] = fma52lo(res[84], a[21], a[63]); // Sum(84) + res[85] = fma52hi(res[85], a[21], a[63]); // Sum(84) + res[85] = fma52lo(res[85], a[22], a[63]); // Sum(85) + res[86] = fma52hi(res[86], a[22], a[63]); // Sum(85) + res[86] = fma52lo(res[86], a[23], a[63]); // Sum(86) + res[87] = fma52hi(res[87], a[23], a[63]); // Sum(86) + res[87] = fma52lo(res[87], a[24], a[63]); // Sum(87) + res[88] = fma52hi(res[88], a[24], a[63]); // Sum(87) + res[88] = fma52lo(res[88], a[25], a[63]); // Sum(88) + res[89] = fma52hi(res[89], a[25], a[63]); // Sum(88) + res[89] = fma52lo(res[89], a[26], a[63]); // Sum(89) + res[90] = fma52hi(res[90], a[26], a[63]); // Sum(89) + res[90] = fma52lo(res[90], a[27], a[63]); // Sum(90) + res[91] = fma52hi(res[91], a[27], a[63]); // Sum(90) + res[91] = fma52lo(res[91], a[28], a[63]); // Sum(91) + res[92] = fma52hi(res[92], a[28], a[63]); // Sum(91) + res[92] = fma52lo(res[92], a[29], a[63]); // Sum(92) + res[93] = fma52hi(res[93], a[29], a[63]); // Sum(92) + res[93] = fma52lo(res[93], a[30], a[63]); // Sum(93) + res[94] = fma52hi(res[94], a[30], a[63]); // Sum(93) + res[94] = fma52lo(res[94], a[31], a[63]); // Sum(94) + res[95] = fma52hi(res[95], a[31], a[63]); // Sum(94) + res[95] = fma52lo(res[95], a[32], a[63]); // Sum(95) + res[96] = fma52hi(res[96], a[32], a[63]); // Sum(95) + res[84] = fma52lo(res[84], a[20], a[64]); // Sum(84) + res[85] = fma52hi(res[85], a[20], a[64]); // Sum(84) + res[85] = fma52lo(res[85], a[21], a[64]); // Sum(85) + res[86] = fma52hi(res[86], a[21], a[64]); // Sum(85) + res[86] = fma52lo(res[86], a[22], a[64]); // Sum(86) + res[87] = fma52hi(res[87], a[22], a[64]); // Sum(86) + res[87] = fma52lo(res[87], a[23], a[64]); // Sum(87) + res[88] = fma52hi(res[88], a[23], a[64]); // Sum(87) + res[88] = fma52lo(res[88], a[24], a[64]); // Sum(88) + res[89] = fma52hi(res[89], a[24], a[64]); // Sum(88) + res[89] = fma52lo(res[89], a[25], a[64]); // Sum(89) + res[90] = fma52hi(res[90], a[25], a[64]); // Sum(89) + res[90] = fma52lo(res[90], a[26], a[64]); // Sum(90) + res[91] = fma52hi(res[91], a[26], a[64]); // Sum(90) + res[91] = fma52lo(res[91], a[27], a[64]); // Sum(91) + res[92] = fma52hi(res[92], a[27], a[64]); // Sum(91) + res[92] = fma52lo(res[92], a[28], a[64]); // Sum(92) + res[93] = fma52hi(res[93], a[28], a[64]); // Sum(92) + res[93] = fma52lo(res[93], a[29], a[64]); // Sum(93) + res[94] = fma52hi(res[94], a[29], a[64]); // Sum(93) + res[94] = fma52lo(res[94], a[30], a[64]); // Sum(94) + res[95] = fma52hi(res[95], a[30], a[64]); // Sum(94) + res[95] = fma52lo(res[95], a[31], a[64]); // Sum(95) + res[96] = fma52hi(res[96], a[31], a[64]); // Sum(95) + res[84] = fma52lo(res[84], a[19], a[65]); // Sum(84) + res[85] = fma52hi(res[85], a[19], a[65]); // Sum(84) + res[85] = fma52lo(res[85], a[20], a[65]); // Sum(85) + res[86] = fma52hi(res[86], a[20], a[65]); // Sum(85) + res[86] = fma52lo(res[86], a[21], a[65]); // Sum(86) + res[87] = fma52hi(res[87], a[21], a[65]); // Sum(86) + res[87] = fma52lo(res[87], a[22], a[65]); // Sum(87) + res[88] = fma52hi(res[88], a[22], a[65]); // Sum(87) + res[88] = fma52lo(res[88], a[23], a[65]); // Sum(88) + res[89] = fma52hi(res[89], a[23], a[65]); // Sum(88) + res[89] = fma52lo(res[89], a[24], a[65]); // Sum(89) + res[90] = fma52hi(res[90], a[24], a[65]); // Sum(89) + res[90] = fma52lo(res[90], a[25], a[65]); // Sum(90) + res[91] = fma52hi(res[91], a[25], a[65]); // Sum(90) + res[91] = fma52lo(res[91], a[26], a[65]); // Sum(91) + res[92] = fma52hi(res[92], a[26], a[65]); // Sum(91) + res[92] = fma52lo(res[92], a[27], a[65]); // Sum(92) + res[93] = fma52hi(res[93], a[27], a[65]); // Sum(92) + res[93] = fma52lo(res[93], a[28], a[65]); // Sum(93) + res[94] = fma52hi(res[94], a[28], a[65]); // Sum(93) + res[94] = fma52lo(res[94], a[29], a[65]); // Sum(94) + res[95] = fma52hi(res[95], a[29], a[65]); // Sum(94) + res[95] = fma52lo(res[95], a[30], a[65]); // Sum(95) + res[96] = fma52hi(res[96], a[30], a[65]); // Sum(95) + res[84] = fma52lo(res[84], a[18], a[66]); // Sum(84) + res[85] = fma52hi(res[85], a[18], a[66]); // Sum(84) + res[85] = fma52lo(res[85], a[19], a[66]); // Sum(85) + res[86] = fma52hi(res[86], a[19], a[66]); // Sum(85) + res[86] = fma52lo(res[86], a[20], a[66]); // Sum(86) + res[87] = fma52hi(res[87], a[20], a[66]); // Sum(86) + res[87] = fma52lo(res[87], a[21], a[66]); // Sum(87) + res[88] = fma52hi(res[88], a[21], a[66]); // Sum(87) + res[88] = fma52lo(res[88], a[22], a[66]); // Sum(88) + res[89] = fma52hi(res[89], a[22], a[66]); // Sum(88) + res[89] = fma52lo(res[89], a[23], a[66]); // Sum(89) + res[90] = fma52hi(res[90], a[23], a[66]); // Sum(89) + res[90] = fma52lo(res[90], a[24], a[66]); // Sum(90) + res[91] = fma52hi(res[91], a[24], a[66]); // Sum(90) + res[91] = fma52lo(res[91], a[25], a[66]); // Sum(91) + res[92] = fma52hi(res[92], a[25], a[66]); // Sum(91) + res[92] = fma52lo(res[92], a[26], a[66]); // Sum(92) + res[93] = fma52hi(res[93], a[26], a[66]); // Sum(92) + res[93] = fma52lo(res[93], a[27], a[66]); // Sum(93) + res[94] = fma52hi(res[94], a[27], a[66]); // Sum(93) + res[94] = fma52lo(res[94], a[28], a[66]); // Sum(94) + res[95] = fma52hi(res[95], a[28], a[66]); // Sum(94) + res[95] = fma52lo(res[95], a[29], a[66]); // Sum(95) + res[96] = fma52hi(res[96], a[29], a[66]); // Sum(95) + res[84] = fma52lo(res[84], a[17], a[67]); // Sum(84) + res[85] = fma52hi(res[85], a[17], a[67]); // Sum(84) + res[85] = fma52lo(res[85], a[18], a[67]); // Sum(85) + res[86] = fma52hi(res[86], a[18], a[67]); // Sum(85) + res[86] = fma52lo(res[86], a[19], a[67]); // Sum(86) + res[87] = fma52hi(res[87], a[19], a[67]); // Sum(86) + res[87] = fma52lo(res[87], a[20], a[67]); // Sum(87) + res[88] = fma52hi(res[88], a[20], a[67]); // Sum(87) + res[88] = fma52lo(res[88], a[21], a[67]); // Sum(88) + res[89] = fma52hi(res[89], a[21], a[67]); // Sum(88) + res[89] = fma52lo(res[89], a[22], a[67]); // Sum(89) + res[90] = fma52hi(res[90], a[22], a[67]); // Sum(89) + res[90] = fma52lo(res[90], a[23], a[67]); // Sum(90) + res[91] = fma52hi(res[91], a[23], a[67]); // Sum(90) + res[91] = fma52lo(res[91], a[24], a[67]); // Sum(91) + res[92] = fma52hi(res[92], a[24], a[67]); // Sum(91) + res[92] = fma52lo(res[92], a[25], a[67]); // Sum(92) + res[93] = fma52hi(res[93], a[25], a[67]); // Sum(92) + res[93] = fma52lo(res[93], a[26], a[67]); // Sum(93) + res[94] = fma52hi(res[94], a[26], a[67]); // Sum(93) + res[94] = fma52lo(res[94], a[27], a[67]); // Sum(94) + res[95] = fma52hi(res[95], a[27], a[67]); // Sum(94) + res[95] = fma52lo(res[95], a[28], a[67]); // Sum(95) + res[96] = fma52hi(res[96], a[28], a[67]); // Sum(95) + res[84] = fma52lo(res[84], a[16], a[68]); // Sum(84) + res[85] = fma52hi(res[85], a[16], a[68]); // Sum(84) + res[85] = fma52lo(res[85], a[17], a[68]); // Sum(85) + res[86] = fma52hi(res[86], a[17], a[68]); // Sum(85) + res[86] = fma52lo(res[86], a[18], a[68]); // Sum(86) + res[87] = fma52hi(res[87], a[18], a[68]); // Sum(86) + res[87] = fma52lo(res[87], a[19], a[68]); // Sum(87) + res[88] = fma52hi(res[88], a[19], a[68]); // Sum(87) + res[88] = fma52lo(res[88], a[20], a[68]); // Sum(88) + res[89] = fma52hi(res[89], a[20], a[68]); // Sum(88) + res[89] = fma52lo(res[89], a[21], a[68]); // Sum(89) + res[90] = fma52hi(res[90], a[21], a[68]); // Sum(89) + res[90] = fma52lo(res[90], a[22], a[68]); // Sum(90) + res[91] = fma52hi(res[91], a[22], a[68]); // Sum(90) + res[91] = fma52lo(res[91], a[23], a[68]); // Sum(91) + res[92] = fma52hi(res[92], a[23], a[68]); // Sum(91) + res[92] = fma52lo(res[92], a[24], a[68]); // Sum(92) + res[93] = fma52hi(res[93], a[24], a[68]); // Sum(92) + res[93] = fma52lo(res[93], a[25], a[68]); // Sum(93) + res[94] = fma52hi(res[94], a[25], a[68]); // Sum(93) + res[94] = fma52lo(res[94], a[26], a[68]); // Sum(94) + res[95] = fma52hi(res[95], a[26], a[68]); // Sum(94) + res[95] = fma52lo(res[95], a[27], a[68]); // Sum(95) + res[96] = fma52hi(res[96], a[27], a[68]); // Sum(95) + res[84] = fma52lo(res[84], a[15], a[69]); // Sum(84) + res[85] = fma52hi(res[85], a[15], a[69]); // Sum(84) + res[85] = fma52lo(res[85], a[16], a[69]); // Sum(85) + res[86] = fma52hi(res[86], a[16], a[69]); // Sum(85) + res[86] = fma52lo(res[86], a[17], a[69]); // Sum(86) + res[87] = fma52hi(res[87], a[17], a[69]); // Sum(86) + res[87] = fma52lo(res[87], a[18], a[69]); // Sum(87) + res[88] = fma52hi(res[88], a[18], a[69]); // Sum(87) + res[88] = fma52lo(res[88], a[19], a[69]); // Sum(88) + res[89] = fma52hi(res[89], a[19], a[69]); // Sum(88) + res[89] = fma52lo(res[89], a[20], a[69]); // Sum(89) + res[90] = fma52hi(res[90], a[20], a[69]); // Sum(89) + res[90] = fma52lo(res[90], a[21], a[69]); // Sum(90) + res[91] = fma52hi(res[91], a[21], a[69]); // Sum(90) + res[91] = fma52lo(res[91], a[22], a[69]); // Sum(91) + res[92] = fma52hi(res[92], a[22], a[69]); // Sum(91) + res[92] = fma52lo(res[92], a[23], a[69]); // Sum(92) + res[93] = fma52hi(res[93], a[23], a[69]); // Sum(92) + res[93] = fma52lo(res[93], a[24], a[69]); // Sum(93) + res[94] = fma52hi(res[94], a[24], a[69]); // Sum(93) + res[94] = fma52lo(res[94], a[25], a[69]); // Sum(94) + res[95] = fma52hi(res[95], a[25], a[69]); // Sum(94) + res[95] = fma52lo(res[95], a[26], a[69]); // Sum(95) + res[96] = fma52hi(res[96], a[26], a[69]); // Sum(95) + res[84] = fma52lo(res[84], a[14], a[70]); // Sum(84) + res[85] = fma52hi(res[85], a[14], a[70]); // Sum(84) + res[85] = fma52lo(res[85], a[15], a[70]); // Sum(85) + res[86] = fma52hi(res[86], a[15], a[70]); // Sum(85) + res[86] = fma52lo(res[86], a[16], a[70]); // Sum(86) + res[87] = fma52hi(res[87], a[16], a[70]); // Sum(86) + res[87] = fma52lo(res[87], a[17], a[70]); // Sum(87) + res[88] = fma52hi(res[88], a[17], a[70]); // Sum(87) + res[88] = fma52lo(res[88], a[18], a[70]); // Sum(88) + res[89] = fma52hi(res[89], a[18], a[70]); // Sum(88) + res[89] = fma52lo(res[89], a[19], a[70]); // Sum(89) + res[90] = fma52hi(res[90], a[19], a[70]); // Sum(89) + res[90] = fma52lo(res[90], a[20], a[70]); // Sum(90) + res[91] = fma52hi(res[91], a[20], a[70]); // Sum(90) + res[91] = fma52lo(res[91], a[21], a[70]); // Sum(91) + res[92] = fma52hi(res[92], a[21], a[70]); // Sum(91) + res[92] = fma52lo(res[92], a[22], a[70]); // Sum(92) + res[93] = fma52hi(res[93], a[22], a[70]); // Sum(92) + res[93] = fma52lo(res[93], a[23], a[70]); // Sum(93) + res[94] = fma52hi(res[94], a[23], a[70]); // Sum(93) + res[94] = fma52lo(res[94], a[24], a[70]); // Sum(94) + res[95] = fma52hi(res[95], a[24], a[70]); // Sum(94) + res[95] = fma52lo(res[95], a[25], a[70]); // Sum(95) + res[96] = fma52hi(res[96], a[25], a[70]); // Sum(95) + res[84] = fma52lo(res[84], a[13], a[71]); // Sum(84) + res[85] = fma52hi(res[85], a[13], a[71]); // Sum(84) + res[85] = fma52lo(res[85], a[14], a[71]); // Sum(85) + res[86] = fma52hi(res[86], a[14], a[71]); // Sum(85) + res[86] = fma52lo(res[86], a[15], a[71]); // Sum(86) + res[87] = fma52hi(res[87], a[15], a[71]); // Sum(86) + res[87] = fma52lo(res[87], a[16], a[71]); // Sum(87) + res[88] = fma52hi(res[88], a[16], a[71]); // Sum(87) + res[88] = fma52lo(res[88], a[17], a[71]); // Sum(88) + res[89] = fma52hi(res[89], a[17], a[71]); // Sum(88) + res[89] = fma52lo(res[89], a[18], a[71]); // Sum(89) + res[90] = fma52hi(res[90], a[18], a[71]); // Sum(89) + res[90] = fma52lo(res[90], a[19], a[71]); // Sum(90) + res[91] = fma52hi(res[91], a[19], a[71]); // Sum(90) + res[91] = fma52lo(res[91], a[20], a[71]); // Sum(91) + res[92] = fma52hi(res[92], a[20], a[71]); // Sum(91) + res[92] = fma52lo(res[92], a[21], a[71]); // Sum(92) + res[93] = fma52hi(res[93], a[21], a[71]); // Sum(92) + res[93] = fma52lo(res[93], a[22], a[71]); // Sum(93) + res[94] = fma52hi(res[94], a[22], a[71]); // Sum(93) + res[94] = fma52lo(res[94], a[23], a[71]); // Sum(94) + res[95] = fma52hi(res[95], a[23], a[71]); // Sum(94) + res[95] = fma52lo(res[95], a[24], a[71]); // Sum(95) + res[96] = fma52hi(res[96], a[24], a[71]); // Sum(95) + res[84] = fma52lo(res[84], a[12], a[72]); // Sum(84) + res[85] = fma52hi(res[85], a[12], a[72]); // Sum(84) + res[85] = fma52lo(res[85], a[13], a[72]); // Sum(85) + res[86] = fma52hi(res[86], a[13], a[72]); // Sum(85) + res[86] = fma52lo(res[86], a[14], a[72]); // Sum(86) + res[87] = fma52hi(res[87], a[14], a[72]); // Sum(86) + res[87] = fma52lo(res[87], a[15], a[72]); // Sum(87) + res[88] = fma52hi(res[88], a[15], a[72]); // Sum(87) + res[88] = fma52lo(res[88], a[16], a[72]); // Sum(88) + res[89] = fma52hi(res[89], a[16], a[72]); // Sum(88) + res[89] = fma52lo(res[89], a[17], a[72]); // Sum(89) + res[90] = fma52hi(res[90], a[17], a[72]); // Sum(89) + res[90] = fma52lo(res[90], a[18], a[72]); // Sum(90) + res[91] = fma52hi(res[91], a[18], a[72]); // Sum(90) + res[91] = fma52lo(res[91], a[19], a[72]); // Sum(91) + res[92] = fma52hi(res[92], a[19], a[72]); // Sum(91) + res[92] = fma52lo(res[92], a[20], a[72]); // Sum(92) + res[93] = fma52hi(res[93], a[20], a[72]); // Sum(92) + res[93] = fma52lo(res[93], a[21], a[72]); // Sum(93) + res[94] = fma52hi(res[94], a[21], a[72]); // Sum(93) + res[94] = fma52lo(res[94], a[22], a[72]); // Sum(94) + res[95] = fma52hi(res[95], a[22], a[72]); // Sum(94) + res[95] = fma52lo(res[95], a[23], a[72]); // Sum(95) + res[96] = fma52hi(res[96], a[23], a[72]); // Sum(95) + res[84] = fma52lo(res[84], a[11], a[73]); // Sum(84) + res[85] = fma52hi(res[85], a[11], a[73]); // Sum(84) + res[85] = fma52lo(res[85], a[12], a[73]); // Sum(85) + res[86] = fma52hi(res[86], a[12], a[73]); // Sum(85) + res[86] = fma52lo(res[86], a[13], a[73]); // Sum(86) + res[87] = fma52hi(res[87], a[13], a[73]); // Sum(86) + res[87] = fma52lo(res[87], a[14], a[73]); // Sum(87) + res[88] = fma52hi(res[88], a[14], a[73]); // Sum(87) + res[88] = fma52lo(res[88], a[15], a[73]); // Sum(88) + res[89] = fma52hi(res[89], a[15], a[73]); // Sum(88) + res[89] = fma52lo(res[89], a[16], a[73]); // Sum(89) + res[90] = fma52hi(res[90], a[16], a[73]); // Sum(89) + res[90] = fma52lo(res[90], a[17], a[73]); // Sum(90) + res[91] = fma52hi(res[91], a[17], a[73]); // Sum(90) + res[91] = fma52lo(res[91], a[18], a[73]); // Sum(91) + res[92] = fma52hi(res[92], a[18], a[73]); // Sum(91) + res[92] = fma52lo(res[92], a[19], a[73]); // Sum(92) + res[93] = fma52hi(res[93], a[19], a[73]); // Sum(92) + res[93] = fma52lo(res[93], a[20], a[73]); // Sum(93) + res[94] = fma52hi(res[94], a[20], a[73]); // Sum(93) + res[94] = fma52lo(res[94], a[21], a[73]); // Sum(94) + res[95] = fma52hi(res[95], a[21], a[73]); // Sum(94) + res[95] = fma52lo(res[95], a[22], a[73]); // Sum(95) + res[96] = fma52hi(res[96], a[22], a[73]); // Sum(95) + res[84] = fma52lo(res[84], a[10], a[74]); // Sum(84) + res[85] = fma52hi(res[85], a[10], a[74]); // Sum(84) + res[85] = fma52lo(res[85], a[11], a[74]); // Sum(85) + res[86] = fma52hi(res[86], a[11], a[74]); // Sum(85) + res[86] = fma52lo(res[86], a[12], a[74]); // Sum(86) + res[87] = fma52hi(res[87], a[12], a[74]); // Sum(86) + res[87] = fma52lo(res[87], a[13], a[74]); // Sum(87) + res[88] = fma52hi(res[88], a[13], a[74]); // Sum(87) + res[88] = fma52lo(res[88], a[14], a[74]); // Sum(88) + res[89] = fma52hi(res[89], a[14], a[74]); // Sum(88) + res[89] = fma52lo(res[89], a[15], a[74]); // Sum(89) + res[90] = fma52hi(res[90], a[15], a[74]); // Sum(89) + res[90] = fma52lo(res[90], a[16], a[74]); // Sum(90) + res[91] = fma52hi(res[91], a[16], a[74]); // Sum(90) + res[91] = fma52lo(res[91], a[17], a[74]); // Sum(91) + res[92] = fma52hi(res[92], a[17], a[74]); // Sum(91) + res[92] = fma52lo(res[92], a[18], a[74]); // Sum(92) + res[93] = fma52hi(res[93], a[18], a[74]); // Sum(92) + res[93] = fma52lo(res[93], a[19], a[74]); // Sum(93) + res[94] = fma52hi(res[94], a[19], a[74]); // Sum(93) + res[94] = fma52lo(res[94], a[20], a[74]); // Sum(94) + res[95] = fma52hi(res[95], a[20], a[74]); // Sum(94) + res[95] = fma52lo(res[95], a[21], a[74]); // Sum(95) + res[96] = fma52hi(res[96], a[21], a[74]); // Sum(95) + res[84] = fma52lo(res[84], a[9], a[75]); // Sum(84) + res[85] = fma52hi(res[85], a[9], a[75]); // Sum(84) + res[85] = fma52lo(res[85], a[10], a[75]); // Sum(85) + res[86] = fma52hi(res[86], a[10], a[75]); // Sum(85) + res[86] = fma52lo(res[86], a[11], a[75]); // Sum(86) + res[87] = fma52hi(res[87], a[11], a[75]); // Sum(86) + res[87] = fma52lo(res[87], a[12], a[75]); // Sum(87) + res[88] = fma52hi(res[88], a[12], a[75]); // Sum(87) + res[88] = fma52lo(res[88], a[13], a[75]); // Sum(88) + res[89] = fma52hi(res[89], a[13], a[75]); // Sum(88) + res[89] = fma52lo(res[89], a[14], a[75]); // Sum(89) + res[90] = fma52hi(res[90], a[14], a[75]); // Sum(89) + res[90] = fma52lo(res[90], a[15], a[75]); // Sum(90) + res[91] = fma52hi(res[91], a[15], a[75]); // Sum(90) + res[91] = fma52lo(res[91], a[16], a[75]); // Sum(91) + res[92] = fma52hi(res[92], a[16], a[75]); // Sum(91) + res[92] = fma52lo(res[92], a[17], a[75]); // Sum(92) + res[93] = fma52hi(res[93], a[17], a[75]); // Sum(92) + res[93] = fma52lo(res[93], a[18], a[75]); // Sum(93) + res[94] = fma52hi(res[94], a[18], a[75]); // Sum(93) + res[94] = fma52lo(res[94], a[19], a[75]); // Sum(94) + res[95] = fma52hi(res[95], a[19], a[75]); // Sum(94) + res[95] = fma52lo(res[95], a[20], a[75]); // Sum(95) + res[96] = fma52hi(res[96], a[20], a[75]); // Sum(95) + res[84] = fma52lo(res[84], a[8], a[76]); // Sum(84) + res[85] = fma52hi(res[85], a[8], a[76]); // Sum(84) + res[85] = fma52lo(res[85], a[9], a[76]); // Sum(85) + res[86] = fma52hi(res[86], a[9], a[76]); // Sum(85) + res[86] = fma52lo(res[86], a[10], a[76]); // Sum(86) + res[87] = fma52hi(res[87], a[10], a[76]); // Sum(86) + res[87] = fma52lo(res[87], a[11], a[76]); // Sum(87) + res[88] = fma52hi(res[88], a[11], a[76]); // Sum(87) + res[88] = fma52lo(res[88], a[12], a[76]); // Sum(88) + res[89] = fma52hi(res[89], a[12], a[76]); // Sum(88) + res[89] = fma52lo(res[89], a[13], a[76]); // Sum(89) + res[90] = fma52hi(res[90], a[13], a[76]); // Sum(89) + res[90] = fma52lo(res[90], a[14], a[76]); // Sum(90) + res[91] = fma52hi(res[91], a[14], a[76]); // Sum(90) + res[91] = fma52lo(res[91], a[15], a[76]); // Sum(91) + res[92] = fma52hi(res[92], a[15], a[76]); // Sum(91) + res[92] = fma52lo(res[92], a[16], a[76]); // Sum(92) + res[93] = fma52hi(res[93], a[16], a[76]); // Sum(92) + res[93] = fma52lo(res[93], a[17], a[76]); // Sum(93) + res[94] = fma52hi(res[94], a[17], a[76]); // Sum(93) + res[94] = fma52lo(res[94], a[18], a[76]); // Sum(94) + res[95] = fma52hi(res[95], a[18], a[76]); // Sum(94) + res[95] = fma52lo(res[95], a[19], a[76]); // Sum(95) + res[96] = fma52hi(res[96], a[19], a[76]); // Sum(95) + res[84] = fma52lo(res[84], a[7], a[77]); // Sum(84) + res[85] = fma52hi(res[85], a[7], a[77]); // Sum(84) + res[85] = fma52lo(res[85], a[8], a[77]); // Sum(85) + res[86] = fma52hi(res[86], a[8], a[77]); // Sum(85) + res[86] = fma52lo(res[86], a[9], a[77]); // Sum(86) + res[87] = fma52hi(res[87], a[9], a[77]); // Sum(86) + res[87] = fma52lo(res[87], a[10], a[77]); // Sum(87) + res[88] = fma52hi(res[88], a[10], a[77]); // Sum(87) + res[88] = fma52lo(res[88], a[11], a[77]); // Sum(88) + res[89] = fma52hi(res[89], a[11], a[77]); // Sum(88) + res[89] = fma52lo(res[89], a[12], a[77]); // Sum(89) + res[90] = fma52hi(res[90], a[12], a[77]); // Sum(89) + res[90] = fma52lo(res[90], a[13], a[77]); // Sum(90) + res[91] = fma52hi(res[91], a[13], a[77]); // Sum(90) + res[91] = fma52lo(res[91], a[14], a[77]); // Sum(91) + res[92] = fma52hi(res[92], a[14], a[77]); // Sum(91) + res[92] = fma52lo(res[92], a[15], a[77]); // Sum(92) + res[93] = fma52hi(res[93], a[15], a[77]); // Sum(92) + res[93] = fma52lo(res[93], a[16], a[77]); // Sum(93) + res[94] = fma52hi(res[94], a[16], a[77]); // Sum(93) + res[94] = fma52lo(res[94], a[17], a[77]); // Sum(94) + res[95] = fma52hi(res[95], a[17], a[77]); // Sum(94) + res[95] = fma52lo(res[95], a[18], a[77]); // Sum(95) + res[96] = fma52hi(res[96], a[18], a[77]); // Sum(95) + res[84] = fma52lo(res[84], a[6], a[78]); // Sum(84) + res[85] = fma52hi(res[85], a[6], a[78]); // Sum(84) + res[85] = fma52lo(res[85], a[7], a[78]); // Sum(85) + res[86] = fma52hi(res[86], a[7], a[78]); // Sum(85) + res[86] = fma52lo(res[86], a[8], a[78]); // Sum(86) + res[87] = fma52hi(res[87], a[8], a[78]); // Sum(86) + res[87] = fma52lo(res[87], a[9], a[78]); // Sum(87) + res[88] = fma52hi(res[88], a[9], a[78]); // Sum(87) + res[88] = fma52lo(res[88], a[10], a[78]); // Sum(88) + res[89] = fma52hi(res[89], a[10], a[78]); // Sum(88) + res[89] = fma52lo(res[89], a[11], a[78]); // Sum(89) + res[90] = fma52hi(res[90], a[11], a[78]); // Sum(89) + res[90] = fma52lo(res[90], a[12], a[78]); // Sum(90) + res[91] = fma52hi(res[91], a[12], a[78]); // Sum(90) + res[91] = fma52lo(res[91], a[13], a[78]); // Sum(91) + res[92] = fma52hi(res[92], a[13], a[78]); // Sum(91) + res[92] = fma52lo(res[92], a[14], a[78]); // Sum(92) + res[93] = fma52hi(res[93], a[14], a[78]); // Sum(92) + res[93] = fma52lo(res[93], a[15], a[78]); // Sum(93) + res[94] = fma52hi(res[94], a[15], a[78]); // Sum(93) + res[94] = fma52lo(res[94], a[16], a[78]); // Sum(94) + res[95] = fma52hi(res[95], a[16], a[78]); // Sum(94) + res[95] = fma52lo(res[95], a[17], a[78]); // Sum(95) + res[96] = fma52hi(res[96], a[17], a[78]); // Sum(95) + res[84] = add64(res[84], res[84]); // Double(84) + res[85] = add64(res[85], res[85]); // Double(85) + res[86] = add64(res[86], res[86]); // Double(86) + res[87] = add64(res[87], res[87]); // Double(87) + res[88] = add64(res[88], res[88]); // Double(88) + res[89] = add64(res[89], res[89]); // Double(89) + res[90] = add64(res[90], res[90]); // Double(90) + res[91] = add64(res[91], res[91]); // Double(91) + res[92] = add64(res[92], res[92]); // Double(92) + res[93] = add64(res[93], res[93]); // Double(93) + res[94] = add64(res[94], res[94]); // Double(94) + res[95] = add64(res[95], res[95]); // Double(95) + res[84] = fma52lo(res[84], a[42], a[42]); // Add sqr(84) + res[85] = fma52hi(res[85], a[42], a[42]); // Add sqr(84) + res[86] = fma52lo(res[86], a[43], a[43]); // Add sqr(86) + res[87] = fma52hi(res[87], a[43], a[43]); // Add sqr(86) + res[88] = fma52lo(res[88], a[44], a[44]); // Add sqr(88) + res[89] = fma52hi(res[89], a[44], a[44]); // Add sqr(88) + res[90] = fma52lo(res[90], a[45], a[45]); // Add sqr(90) + res[91] = fma52hi(res[91], a[45], a[45]); // Add sqr(90) + res[92] = fma52lo(res[92], a[46], a[46]); // Add sqr(92) + res[93] = fma52hi(res[93], a[46], a[46]); // Add sqr(92) + res[94] = fma52lo(res[94], a[47], a[47]); // Add sqr(94) + res[95] = fma52hi(res[95], a[47], a[47]); // Add sqr(94) + res[96] = fma52lo(res[96], a[47], a[49]); // Sum(96) + res[97] = fma52hi(res[97], a[47], a[49]); // Sum(96) + res[97] = fma52lo(res[97], a[48], a[49]); // Sum(97) + res[98] = fma52hi(res[98], a[48], a[49]); // Sum(97) + res[96] = fma52lo(res[96], a[46], a[50]); // Sum(96) + res[97] = fma52hi(res[97], a[46], a[50]); // Sum(96) + res[97] = fma52lo(res[97], a[47], a[50]); // Sum(97) + res[98] = fma52hi(res[98], a[47], a[50]); // Sum(97) + res[98] = fma52lo(res[98], a[48], a[50]); // Sum(98) + res[99] = fma52hi(res[99], a[48], a[50]); // Sum(98) + res[99] = fma52lo(res[99], a[49], a[50]); // Sum(99) + res[100] = fma52hi(res[100], a[49], a[50]); // Sum(99) + res[96] = fma52lo(res[96], a[45], a[51]); // Sum(96) + res[97] = fma52hi(res[97], a[45], a[51]); // Sum(96) + res[97] = fma52lo(res[97], a[46], a[51]); // Sum(97) + res[98] = fma52hi(res[98], a[46], a[51]); // Sum(97) + res[98] = fma52lo(res[98], a[47], a[51]); // Sum(98) + res[99] = fma52hi(res[99], a[47], a[51]); // Sum(98) + res[99] = fma52lo(res[99], a[48], a[51]); // Sum(99) + res[100] = fma52hi(res[100], a[48], a[51]); // Sum(99) + res[100] = fma52lo(res[100], a[49], a[51]); // Sum(100) + res[101] = fma52hi(res[101], a[49], a[51]); // Sum(100) + res[101] = fma52lo(res[101], a[50], a[51]); // Sum(101) + res[102] = fma52hi(res[102], a[50], a[51]); // Sum(101) + res[96] = fma52lo(res[96], a[44], a[52]); // Sum(96) + res[97] = fma52hi(res[97], a[44], a[52]); // Sum(96) + res[97] = fma52lo(res[97], a[45], a[52]); // Sum(97) + res[98] = fma52hi(res[98], a[45], a[52]); // Sum(97) + res[98] = fma52lo(res[98], a[46], a[52]); // Sum(98) + res[99] = fma52hi(res[99], a[46], a[52]); // Sum(98) + res[99] = fma52lo(res[99], a[47], a[52]); // Sum(99) + res[100] = fma52hi(res[100], a[47], a[52]); // Sum(99) + res[100] = fma52lo(res[100], a[48], a[52]); // Sum(100) + res[101] = fma52hi(res[101], a[48], a[52]); // Sum(100) + res[101] = fma52lo(res[101], a[49], a[52]); // Sum(101) + res[102] = fma52hi(res[102], a[49], a[52]); // Sum(101) + res[102] = fma52lo(res[102], a[50], a[52]); // Sum(102) + res[103] = fma52hi(res[103], a[50], a[52]); // Sum(102) + res[103] = fma52lo(res[103], a[51], a[52]); // Sum(103) + res[104] = fma52hi(res[104], a[51], a[52]); // Sum(103) + res[96] = fma52lo(res[96], a[43], a[53]); // Sum(96) + res[97] = fma52hi(res[97], a[43], a[53]); // Sum(96) + res[97] = fma52lo(res[97], a[44], a[53]); // Sum(97) + res[98] = fma52hi(res[98], a[44], a[53]); // Sum(97) + res[98] = fma52lo(res[98], a[45], a[53]); // Sum(98) + res[99] = fma52hi(res[99], a[45], a[53]); // Sum(98) + res[99] = fma52lo(res[99], a[46], a[53]); // Sum(99) + res[100] = fma52hi(res[100], a[46], a[53]); // Sum(99) + res[100] = fma52lo(res[100], a[47], a[53]); // Sum(100) + res[101] = fma52hi(res[101], a[47], a[53]); // Sum(100) + res[101] = fma52lo(res[101], a[48], a[53]); // Sum(101) + res[102] = fma52hi(res[102], a[48], a[53]); // Sum(101) + res[102] = fma52lo(res[102], a[49], a[53]); // Sum(102) + res[103] = fma52hi(res[103], a[49], a[53]); // Sum(102) + res[103] = fma52lo(res[103], a[50], a[53]); // Sum(103) + res[104] = fma52hi(res[104], a[50], a[53]); // Sum(103) + res[104] = fma52lo(res[104], a[51], a[53]); // Sum(104) + res[105] = fma52hi(res[105], a[51], a[53]); // Sum(104) + res[105] = fma52lo(res[105], a[52], a[53]); // Sum(105) + res[106] = fma52hi(res[106], a[52], a[53]); // Sum(105) + res[96] = fma52lo(res[96], a[42], a[54]); // Sum(96) + res[97] = fma52hi(res[97], a[42], a[54]); // Sum(96) + res[97] = fma52lo(res[97], a[43], a[54]); // Sum(97) + res[98] = fma52hi(res[98], a[43], a[54]); // Sum(97) + res[98] = fma52lo(res[98], a[44], a[54]); // Sum(98) + res[99] = fma52hi(res[99], a[44], a[54]); // Sum(98) + res[99] = fma52lo(res[99], a[45], a[54]); // Sum(99) + res[100] = fma52hi(res[100], a[45], a[54]); // Sum(99) + res[100] = fma52lo(res[100], a[46], a[54]); // Sum(100) + res[101] = fma52hi(res[101], a[46], a[54]); // Sum(100) + res[101] = fma52lo(res[101], a[47], a[54]); // Sum(101) + res[102] = fma52hi(res[102], a[47], a[54]); // Sum(101) + res[102] = fma52lo(res[102], a[48], a[54]); // Sum(102) + res[103] = fma52hi(res[103], a[48], a[54]); // Sum(102) + res[103] = fma52lo(res[103], a[49], a[54]); // Sum(103) + res[104] = fma52hi(res[104], a[49], a[54]); // Sum(103) + res[104] = fma52lo(res[104], a[50], a[54]); // Sum(104) + res[105] = fma52hi(res[105], a[50], a[54]); // Sum(104) + res[105] = fma52lo(res[105], a[51], a[54]); // Sum(105) + res[106] = fma52hi(res[106], a[51], a[54]); // Sum(105) + res[106] = fma52lo(res[106], a[52], a[54]); // Sum(106) + res[107] = fma52hi(res[107], a[52], a[54]); // Sum(106) + res[107] = fma52lo(res[107], a[53], a[54]); // Sum(107) + res[108] = fma52hi(res[108], a[53], a[54]); // Sum(107) + res[96] = fma52lo(res[96], a[41], a[55]); // Sum(96) + res[97] = fma52hi(res[97], a[41], a[55]); // Sum(96) + res[97] = fma52lo(res[97], a[42], a[55]); // Sum(97) + res[98] = fma52hi(res[98], a[42], a[55]); // Sum(97) + res[98] = fma52lo(res[98], a[43], a[55]); // Sum(98) + res[99] = fma52hi(res[99], a[43], a[55]); // Sum(98) + res[99] = fma52lo(res[99], a[44], a[55]); // Sum(99) + res[100] = fma52hi(res[100], a[44], a[55]); // Sum(99) + res[100] = fma52lo(res[100], a[45], a[55]); // Sum(100) + res[101] = fma52hi(res[101], a[45], a[55]); // Sum(100) + res[101] = fma52lo(res[101], a[46], a[55]); // Sum(101) + res[102] = fma52hi(res[102], a[46], a[55]); // Sum(101) + res[102] = fma52lo(res[102], a[47], a[55]); // Sum(102) + res[103] = fma52hi(res[103], a[47], a[55]); // Sum(102) + res[103] = fma52lo(res[103], a[48], a[55]); // Sum(103) + res[104] = fma52hi(res[104], a[48], a[55]); // Sum(103) + res[104] = fma52lo(res[104], a[49], a[55]); // Sum(104) + res[105] = fma52hi(res[105], a[49], a[55]); // Sum(104) + res[105] = fma52lo(res[105], a[50], a[55]); // Sum(105) + res[106] = fma52hi(res[106], a[50], a[55]); // Sum(105) + res[106] = fma52lo(res[106], a[51], a[55]); // Sum(106) + res[107] = fma52hi(res[107], a[51], a[55]); // Sum(106) + res[107] = fma52lo(res[107], a[52], a[55]); // Sum(107) + res[108] = fma52hi(res[108], a[52], a[55]); // Sum(107) + res[96] = fma52lo(res[96], a[40], a[56]); // Sum(96) + res[97] = fma52hi(res[97], a[40], a[56]); // Sum(96) + res[97] = fma52lo(res[97], a[41], a[56]); // Sum(97) + res[98] = fma52hi(res[98], a[41], a[56]); // Sum(97) + res[98] = fma52lo(res[98], a[42], a[56]); // Sum(98) + res[99] = fma52hi(res[99], a[42], a[56]); // Sum(98) + res[99] = fma52lo(res[99], a[43], a[56]); // Sum(99) + res[100] = fma52hi(res[100], a[43], a[56]); // Sum(99) + res[100] = fma52lo(res[100], a[44], a[56]); // Sum(100) + res[101] = fma52hi(res[101], a[44], a[56]); // Sum(100) + res[101] = fma52lo(res[101], a[45], a[56]); // Sum(101) + res[102] = fma52hi(res[102], a[45], a[56]); // Sum(101) + res[102] = fma52lo(res[102], a[46], a[56]); // Sum(102) + res[103] = fma52hi(res[103], a[46], a[56]); // Sum(102) + res[103] = fma52lo(res[103], a[47], a[56]); // Sum(103) + res[104] = fma52hi(res[104], a[47], a[56]); // Sum(103) + res[104] = fma52lo(res[104], a[48], a[56]); // Sum(104) + res[105] = fma52hi(res[105], a[48], a[56]); // Sum(104) + res[105] = fma52lo(res[105], a[49], a[56]); // Sum(105) + res[106] = fma52hi(res[106], a[49], a[56]); // Sum(105) + res[106] = fma52lo(res[106], a[50], a[56]); // Sum(106) + res[107] = fma52hi(res[107], a[50], a[56]); // Sum(106) + res[107] = fma52lo(res[107], a[51], a[56]); // Sum(107) + res[108] = fma52hi(res[108], a[51], a[56]); // Sum(107) + res[96] = fma52lo(res[96], a[39], a[57]); // Sum(96) + res[97] = fma52hi(res[97], a[39], a[57]); // Sum(96) + res[97] = fma52lo(res[97], a[40], a[57]); // Sum(97) + res[98] = fma52hi(res[98], a[40], a[57]); // Sum(97) + res[98] = fma52lo(res[98], a[41], a[57]); // Sum(98) + res[99] = fma52hi(res[99], a[41], a[57]); // Sum(98) + res[99] = fma52lo(res[99], a[42], a[57]); // Sum(99) + res[100] = fma52hi(res[100], a[42], a[57]); // Sum(99) + res[100] = fma52lo(res[100], a[43], a[57]); // Sum(100) + res[101] = fma52hi(res[101], a[43], a[57]); // Sum(100) + res[101] = fma52lo(res[101], a[44], a[57]); // Sum(101) + res[102] = fma52hi(res[102], a[44], a[57]); // Sum(101) + res[102] = fma52lo(res[102], a[45], a[57]); // Sum(102) + res[103] = fma52hi(res[103], a[45], a[57]); // Sum(102) + res[103] = fma52lo(res[103], a[46], a[57]); // Sum(103) + res[104] = fma52hi(res[104], a[46], a[57]); // Sum(103) + res[104] = fma52lo(res[104], a[47], a[57]); // Sum(104) + res[105] = fma52hi(res[105], a[47], a[57]); // Sum(104) + res[105] = fma52lo(res[105], a[48], a[57]); // Sum(105) + res[106] = fma52hi(res[106], a[48], a[57]); // Sum(105) + res[106] = fma52lo(res[106], a[49], a[57]); // Sum(106) + res[107] = fma52hi(res[107], a[49], a[57]); // Sum(106) + res[107] = fma52lo(res[107], a[50], a[57]); // Sum(107) + res[108] = fma52hi(res[108], a[50], a[57]); // Sum(107) + res[96] = fma52lo(res[96], a[38], a[58]); // Sum(96) + res[97] = fma52hi(res[97], a[38], a[58]); // Sum(96) + res[97] = fma52lo(res[97], a[39], a[58]); // Sum(97) + res[98] = fma52hi(res[98], a[39], a[58]); // Sum(97) + res[98] = fma52lo(res[98], a[40], a[58]); // Sum(98) + res[99] = fma52hi(res[99], a[40], a[58]); // Sum(98) + res[99] = fma52lo(res[99], a[41], a[58]); // Sum(99) + res[100] = fma52hi(res[100], a[41], a[58]); // Sum(99) + res[100] = fma52lo(res[100], a[42], a[58]); // Sum(100) + res[101] = fma52hi(res[101], a[42], a[58]); // Sum(100) + res[101] = fma52lo(res[101], a[43], a[58]); // Sum(101) + res[102] = fma52hi(res[102], a[43], a[58]); // Sum(101) + res[102] = fma52lo(res[102], a[44], a[58]); // Sum(102) + res[103] = fma52hi(res[103], a[44], a[58]); // Sum(102) + res[103] = fma52lo(res[103], a[45], a[58]); // Sum(103) + res[104] = fma52hi(res[104], a[45], a[58]); // Sum(103) + res[104] = fma52lo(res[104], a[46], a[58]); // Sum(104) + res[105] = fma52hi(res[105], a[46], a[58]); // Sum(104) + res[105] = fma52lo(res[105], a[47], a[58]); // Sum(105) + res[106] = fma52hi(res[106], a[47], a[58]); // Sum(105) + res[106] = fma52lo(res[106], a[48], a[58]); // Sum(106) + res[107] = fma52hi(res[107], a[48], a[58]); // Sum(106) + res[107] = fma52lo(res[107], a[49], a[58]); // Sum(107) + res[108] = fma52hi(res[108], a[49], a[58]); // Sum(107) + res[96] = fma52lo(res[96], a[37], a[59]); // Sum(96) + res[97] = fma52hi(res[97], a[37], a[59]); // Sum(96) + res[97] = fma52lo(res[97], a[38], a[59]); // Sum(97) + res[98] = fma52hi(res[98], a[38], a[59]); // Sum(97) + res[98] = fma52lo(res[98], a[39], a[59]); // Sum(98) + res[99] = fma52hi(res[99], a[39], a[59]); // Sum(98) + res[99] = fma52lo(res[99], a[40], a[59]); // Sum(99) + res[100] = fma52hi(res[100], a[40], a[59]); // Sum(99) + res[100] = fma52lo(res[100], a[41], a[59]); // Sum(100) + res[101] = fma52hi(res[101], a[41], a[59]); // Sum(100) + res[101] = fma52lo(res[101], a[42], a[59]); // Sum(101) + res[102] = fma52hi(res[102], a[42], a[59]); // Sum(101) + res[102] = fma52lo(res[102], a[43], a[59]); // Sum(102) + res[103] = fma52hi(res[103], a[43], a[59]); // Sum(102) + res[103] = fma52lo(res[103], a[44], a[59]); // Sum(103) + res[104] = fma52hi(res[104], a[44], a[59]); // Sum(103) + res[104] = fma52lo(res[104], a[45], a[59]); // Sum(104) + res[105] = fma52hi(res[105], a[45], a[59]); // Sum(104) + res[105] = fma52lo(res[105], a[46], a[59]); // Sum(105) + res[106] = fma52hi(res[106], a[46], a[59]); // Sum(105) + res[106] = fma52lo(res[106], a[47], a[59]); // Sum(106) + res[107] = fma52hi(res[107], a[47], a[59]); // Sum(106) + res[107] = fma52lo(res[107], a[48], a[59]); // Sum(107) + res[108] = fma52hi(res[108], a[48], a[59]); // Sum(107) + res[96] = fma52lo(res[96], a[36], a[60]); // Sum(96) + res[97] = fma52hi(res[97], a[36], a[60]); // Sum(96) + res[97] = fma52lo(res[97], a[37], a[60]); // Sum(97) + res[98] = fma52hi(res[98], a[37], a[60]); // Sum(97) + res[98] = fma52lo(res[98], a[38], a[60]); // Sum(98) + res[99] = fma52hi(res[99], a[38], a[60]); // Sum(98) + res[99] = fma52lo(res[99], a[39], a[60]); // Sum(99) + res[100] = fma52hi(res[100], a[39], a[60]); // Sum(99) + res[100] = fma52lo(res[100], a[40], a[60]); // Sum(100) + res[101] = fma52hi(res[101], a[40], a[60]); // Sum(100) + res[101] = fma52lo(res[101], a[41], a[60]); // Sum(101) + res[102] = fma52hi(res[102], a[41], a[60]); // Sum(101) + res[102] = fma52lo(res[102], a[42], a[60]); // Sum(102) + res[103] = fma52hi(res[103], a[42], a[60]); // Sum(102) + res[103] = fma52lo(res[103], a[43], a[60]); // Sum(103) + res[104] = fma52hi(res[104], a[43], a[60]); // Sum(103) + res[104] = fma52lo(res[104], a[44], a[60]); // Sum(104) + res[105] = fma52hi(res[105], a[44], a[60]); // Sum(104) + res[105] = fma52lo(res[105], a[45], a[60]); // Sum(105) + res[106] = fma52hi(res[106], a[45], a[60]); // Sum(105) + res[106] = fma52lo(res[106], a[46], a[60]); // Sum(106) + res[107] = fma52hi(res[107], a[46], a[60]); // Sum(106) + res[107] = fma52lo(res[107], a[47], a[60]); // Sum(107) + res[108] = fma52hi(res[108], a[47], a[60]); // Sum(107) + res[96] = fma52lo(res[96], a[35], a[61]); // Sum(96) + res[97] = fma52hi(res[97], a[35], a[61]); // Sum(96) + res[97] = fma52lo(res[97], a[36], a[61]); // Sum(97) + res[98] = fma52hi(res[98], a[36], a[61]); // Sum(97) + res[98] = fma52lo(res[98], a[37], a[61]); // Sum(98) + res[99] = fma52hi(res[99], a[37], a[61]); // Sum(98) + res[99] = fma52lo(res[99], a[38], a[61]); // Sum(99) + res[100] = fma52hi(res[100], a[38], a[61]); // Sum(99) + res[100] = fma52lo(res[100], a[39], a[61]); // Sum(100) + res[101] = fma52hi(res[101], a[39], a[61]); // Sum(100) + res[101] = fma52lo(res[101], a[40], a[61]); // Sum(101) + res[102] = fma52hi(res[102], a[40], a[61]); // Sum(101) + res[102] = fma52lo(res[102], a[41], a[61]); // Sum(102) + res[103] = fma52hi(res[103], a[41], a[61]); // Sum(102) + res[103] = fma52lo(res[103], a[42], a[61]); // Sum(103) + res[104] = fma52hi(res[104], a[42], a[61]); // Sum(103) + res[104] = fma52lo(res[104], a[43], a[61]); // Sum(104) + res[105] = fma52hi(res[105], a[43], a[61]); // Sum(104) + res[105] = fma52lo(res[105], a[44], a[61]); // Sum(105) + res[106] = fma52hi(res[106], a[44], a[61]); // Sum(105) + res[106] = fma52lo(res[106], a[45], a[61]); // Sum(106) + res[107] = fma52hi(res[107], a[45], a[61]); // Sum(106) + res[107] = fma52lo(res[107], a[46], a[61]); // Sum(107) + res[108] = fma52hi(res[108], a[46], a[61]); // Sum(107) + res[96] = fma52lo(res[96], a[34], a[62]); // Sum(96) + res[97] = fma52hi(res[97], a[34], a[62]); // Sum(96) + res[97] = fma52lo(res[97], a[35], a[62]); // Sum(97) + res[98] = fma52hi(res[98], a[35], a[62]); // Sum(97) + res[98] = fma52lo(res[98], a[36], a[62]); // Sum(98) + res[99] = fma52hi(res[99], a[36], a[62]); // Sum(98) + res[99] = fma52lo(res[99], a[37], a[62]); // Sum(99) + res[100] = fma52hi(res[100], a[37], a[62]); // Sum(99) + res[100] = fma52lo(res[100], a[38], a[62]); // Sum(100) + res[101] = fma52hi(res[101], a[38], a[62]); // Sum(100) + res[101] = fma52lo(res[101], a[39], a[62]); // Sum(101) + res[102] = fma52hi(res[102], a[39], a[62]); // Sum(101) + res[102] = fma52lo(res[102], a[40], a[62]); // Sum(102) + res[103] = fma52hi(res[103], a[40], a[62]); // Sum(102) + res[103] = fma52lo(res[103], a[41], a[62]); // Sum(103) + res[104] = fma52hi(res[104], a[41], a[62]); // Sum(103) + res[104] = fma52lo(res[104], a[42], a[62]); // Sum(104) + res[105] = fma52hi(res[105], a[42], a[62]); // Sum(104) + res[105] = fma52lo(res[105], a[43], a[62]); // Sum(105) + res[106] = fma52hi(res[106], a[43], a[62]); // Sum(105) + res[106] = fma52lo(res[106], a[44], a[62]); // Sum(106) + res[107] = fma52hi(res[107], a[44], a[62]); // Sum(106) + res[107] = fma52lo(res[107], a[45], a[62]); // Sum(107) + res[108] = fma52hi(res[108], a[45], a[62]); // Sum(107) + res[96] = fma52lo(res[96], a[33], a[63]); // Sum(96) + res[97] = fma52hi(res[97], a[33], a[63]); // Sum(96) + res[97] = fma52lo(res[97], a[34], a[63]); // Sum(97) + res[98] = fma52hi(res[98], a[34], a[63]); // Sum(97) + res[98] = fma52lo(res[98], a[35], a[63]); // Sum(98) + res[99] = fma52hi(res[99], a[35], a[63]); // Sum(98) + res[99] = fma52lo(res[99], a[36], a[63]); // Sum(99) + res[100] = fma52hi(res[100], a[36], a[63]); // Sum(99) + res[100] = fma52lo(res[100], a[37], a[63]); // Sum(100) + res[101] = fma52hi(res[101], a[37], a[63]); // Sum(100) + res[101] = fma52lo(res[101], a[38], a[63]); // Sum(101) + res[102] = fma52hi(res[102], a[38], a[63]); // Sum(101) + res[102] = fma52lo(res[102], a[39], a[63]); // Sum(102) + res[103] = fma52hi(res[103], a[39], a[63]); // Sum(102) + res[103] = fma52lo(res[103], a[40], a[63]); // Sum(103) + res[104] = fma52hi(res[104], a[40], a[63]); // Sum(103) + res[104] = fma52lo(res[104], a[41], a[63]); // Sum(104) + res[105] = fma52hi(res[105], a[41], a[63]); // Sum(104) + res[105] = fma52lo(res[105], a[42], a[63]); // Sum(105) + res[106] = fma52hi(res[106], a[42], a[63]); // Sum(105) + res[106] = fma52lo(res[106], a[43], a[63]); // Sum(106) + res[107] = fma52hi(res[107], a[43], a[63]); // Sum(106) + res[107] = fma52lo(res[107], a[44], a[63]); // Sum(107) + res[108] = fma52hi(res[108], a[44], a[63]); // Sum(107) + res[96] = fma52lo(res[96], a[32], a[64]); // Sum(96) + res[97] = fma52hi(res[97], a[32], a[64]); // Sum(96) + res[97] = fma52lo(res[97], a[33], a[64]); // Sum(97) + res[98] = fma52hi(res[98], a[33], a[64]); // Sum(97) + res[98] = fma52lo(res[98], a[34], a[64]); // Sum(98) + res[99] = fma52hi(res[99], a[34], a[64]); // Sum(98) + res[99] = fma52lo(res[99], a[35], a[64]); // Sum(99) + res[100] = fma52hi(res[100], a[35], a[64]); // Sum(99) + res[100] = fma52lo(res[100], a[36], a[64]); // Sum(100) + res[101] = fma52hi(res[101], a[36], a[64]); // Sum(100) + res[101] = fma52lo(res[101], a[37], a[64]); // Sum(101) + res[102] = fma52hi(res[102], a[37], a[64]); // Sum(101) + res[102] = fma52lo(res[102], a[38], a[64]); // Sum(102) + res[103] = fma52hi(res[103], a[38], a[64]); // Sum(102) + res[103] = fma52lo(res[103], a[39], a[64]); // Sum(103) + res[104] = fma52hi(res[104], a[39], a[64]); // Sum(103) + res[104] = fma52lo(res[104], a[40], a[64]); // Sum(104) + res[105] = fma52hi(res[105], a[40], a[64]); // Sum(104) + res[105] = fma52lo(res[105], a[41], a[64]); // Sum(105) + res[106] = fma52hi(res[106], a[41], a[64]); // Sum(105) + res[106] = fma52lo(res[106], a[42], a[64]); // Sum(106) + res[107] = fma52hi(res[107], a[42], a[64]); // Sum(106) + res[107] = fma52lo(res[107], a[43], a[64]); // Sum(107) + res[108] = fma52hi(res[108], a[43], a[64]); // Sum(107) + res[96] = fma52lo(res[96], a[31], a[65]); // Sum(96) + res[97] = fma52hi(res[97], a[31], a[65]); // Sum(96) + res[97] = fma52lo(res[97], a[32], a[65]); // Sum(97) + res[98] = fma52hi(res[98], a[32], a[65]); // Sum(97) + res[98] = fma52lo(res[98], a[33], a[65]); // Sum(98) + res[99] = fma52hi(res[99], a[33], a[65]); // Sum(98) + res[99] = fma52lo(res[99], a[34], a[65]); // Sum(99) + res[100] = fma52hi(res[100], a[34], a[65]); // Sum(99) + res[100] = fma52lo(res[100], a[35], a[65]); // Sum(100) + res[101] = fma52hi(res[101], a[35], a[65]); // Sum(100) + res[101] = fma52lo(res[101], a[36], a[65]); // Sum(101) + res[102] = fma52hi(res[102], a[36], a[65]); // Sum(101) + res[102] = fma52lo(res[102], a[37], a[65]); // Sum(102) + res[103] = fma52hi(res[103], a[37], a[65]); // Sum(102) + res[103] = fma52lo(res[103], a[38], a[65]); // Sum(103) + res[104] = fma52hi(res[104], a[38], a[65]); // Sum(103) + res[104] = fma52lo(res[104], a[39], a[65]); // Sum(104) + res[105] = fma52hi(res[105], a[39], a[65]); // Sum(104) + res[105] = fma52lo(res[105], a[40], a[65]); // Sum(105) + res[106] = fma52hi(res[106], a[40], a[65]); // Sum(105) + res[106] = fma52lo(res[106], a[41], a[65]); // Sum(106) + res[107] = fma52hi(res[107], a[41], a[65]); // Sum(106) + res[107] = fma52lo(res[107], a[42], a[65]); // Sum(107) + res[108] = fma52hi(res[108], a[42], a[65]); // Sum(107) + res[96] = fma52lo(res[96], a[30], a[66]); // Sum(96) + res[97] = fma52hi(res[97], a[30], a[66]); // Sum(96) + res[97] = fma52lo(res[97], a[31], a[66]); // Sum(97) + res[98] = fma52hi(res[98], a[31], a[66]); // Sum(97) + res[98] = fma52lo(res[98], a[32], a[66]); // Sum(98) + res[99] = fma52hi(res[99], a[32], a[66]); // Sum(98) + res[99] = fma52lo(res[99], a[33], a[66]); // Sum(99) + res[100] = fma52hi(res[100], a[33], a[66]); // Sum(99) + res[100] = fma52lo(res[100], a[34], a[66]); // Sum(100) + res[101] = fma52hi(res[101], a[34], a[66]); // Sum(100) + res[101] = fma52lo(res[101], a[35], a[66]); // Sum(101) + res[102] = fma52hi(res[102], a[35], a[66]); // Sum(101) + res[102] = fma52lo(res[102], a[36], a[66]); // Sum(102) + res[103] = fma52hi(res[103], a[36], a[66]); // Sum(102) + res[103] = fma52lo(res[103], a[37], a[66]); // Sum(103) + res[104] = fma52hi(res[104], a[37], a[66]); // Sum(103) + res[104] = fma52lo(res[104], a[38], a[66]); // Sum(104) + res[105] = fma52hi(res[105], a[38], a[66]); // Sum(104) + res[105] = fma52lo(res[105], a[39], a[66]); // Sum(105) + res[106] = fma52hi(res[106], a[39], a[66]); // Sum(105) + res[106] = fma52lo(res[106], a[40], a[66]); // Sum(106) + res[107] = fma52hi(res[107], a[40], a[66]); // Sum(106) + res[107] = fma52lo(res[107], a[41], a[66]); // Sum(107) + res[108] = fma52hi(res[108], a[41], a[66]); // Sum(107) + res[96] = fma52lo(res[96], a[29], a[67]); // Sum(96) + res[97] = fma52hi(res[97], a[29], a[67]); // Sum(96) + res[97] = fma52lo(res[97], a[30], a[67]); // Sum(97) + res[98] = fma52hi(res[98], a[30], a[67]); // Sum(97) + res[98] = fma52lo(res[98], a[31], a[67]); // Sum(98) + res[99] = fma52hi(res[99], a[31], a[67]); // Sum(98) + res[99] = fma52lo(res[99], a[32], a[67]); // Sum(99) + res[100] = fma52hi(res[100], a[32], a[67]); // Sum(99) + res[100] = fma52lo(res[100], a[33], a[67]); // Sum(100) + res[101] = fma52hi(res[101], a[33], a[67]); // Sum(100) + res[101] = fma52lo(res[101], a[34], a[67]); // Sum(101) + res[102] = fma52hi(res[102], a[34], a[67]); // Sum(101) + res[102] = fma52lo(res[102], a[35], a[67]); // Sum(102) + res[103] = fma52hi(res[103], a[35], a[67]); // Sum(102) + res[103] = fma52lo(res[103], a[36], a[67]); // Sum(103) + res[104] = fma52hi(res[104], a[36], a[67]); // Sum(103) + res[104] = fma52lo(res[104], a[37], a[67]); // Sum(104) + res[105] = fma52hi(res[105], a[37], a[67]); // Sum(104) + res[105] = fma52lo(res[105], a[38], a[67]); // Sum(105) + res[106] = fma52hi(res[106], a[38], a[67]); // Sum(105) + res[106] = fma52lo(res[106], a[39], a[67]); // Sum(106) + res[107] = fma52hi(res[107], a[39], a[67]); // Sum(106) + res[107] = fma52lo(res[107], a[40], a[67]); // Sum(107) + res[108] = fma52hi(res[108], a[40], a[67]); // Sum(107) + res[96] = fma52lo(res[96], a[28], a[68]); // Sum(96) + res[97] = fma52hi(res[97], a[28], a[68]); // Sum(96) + res[97] = fma52lo(res[97], a[29], a[68]); // Sum(97) + res[98] = fma52hi(res[98], a[29], a[68]); // Sum(97) + res[98] = fma52lo(res[98], a[30], a[68]); // Sum(98) + res[99] = fma52hi(res[99], a[30], a[68]); // Sum(98) + res[99] = fma52lo(res[99], a[31], a[68]); // Sum(99) + res[100] = fma52hi(res[100], a[31], a[68]); // Sum(99) + res[100] = fma52lo(res[100], a[32], a[68]); // Sum(100) + res[101] = fma52hi(res[101], a[32], a[68]); // Sum(100) + res[101] = fma52lo(res[101], a[33], a[68]); // Sum(101) + res[102] = fma52hi(res[102], a[33], a[68]); // Sum(101) + res[102] = fma52lo(res[102], a[34], a[68]); // Sum(102) + res[103] = fma52hi(res[103], a[34], a[68]); // Sum(102) + res[103] = fma52lo(res[103], a[35], a[68]); // Sum(103) + res[104] = fma52hi(res[104], a[35], a[68]); // Sum(103) + res[104] = fma52lo(res[104], a[36], a[68]); // Sum(104) + res[105] = fma52hi(res[105], a[36], a[68]); // Sum(104) + res[105] = fma52lo(res[105], a[37], a[68]); // Sum(105) + res[106] = fma52hi(res[106], a[37], a[68]); // Sum(105) + res[106] = fma52lo(res[106], a[38], a[68]); // Sum(106) + res[107] = fma52hi(res[107], a[38], a[68]); // Sum(106) + res[107] = fma52lo(res[107], a[39], a[68]); // Sum(107) + res[108] = fma52hi(res[108], a[39], a[68]); // Sum(107) + res[96] = fma52lo(res[96], a[27], a[69]); // Sum(96) + res[97] = fma52hi(res[97], a[27], a[69]); // Sum(96) + res[97] = fma52lo(res[97], a[28], a[69]); // Sum(97) + res[98] = fma52hi(res[98], a[28], a[69]); // Sum(97) + res[98] = fma52lo(res[98], a[29], a[69]); // Sum(98) + res[99] = fma52hi(res[99], a[29], a[69]); // Sum(98) + res[99] = fma52lo(res[99], a[30], a[69]); // Sum(99) + res[100] = fma52hi(res[100], a[30], a[69]); // Sum(99) + res[100] = fma52lo(res[100], a[31], a[69]); // Sum(100) + res[101] = fma52hi(res[101], a[31], a[69]); // Sum(100) + res[101] = fma52lo(res[101], a[32], a[69]); // Sum(101) + res[102] = fma52hi(res[102], a[32], a[69]); // Sum(101) + res[102] = fma52lo(res[102], a[33], a[69]); // Sum(102) + res[103] = fma52hi(res[103], a[33], a[69]); // Sum(102) + res[103] = fma52lo(res[103], a[34], a[69]); // Sum(103) + res[104] = fma52hi(res[104], a[34], a[69]); // Sum(103) + res[104] = fma52lo(res[104], a[35], a[69]); // Sum(104) + res[105] = fma52hi(res[105], a[35], a[69]); // Sum(104) + res[105] = fma52lo(res[105], a[36], a[69]); // Sum(105) + res[106] = fma52hi(res[106], a[36], a[69]); // Sum(105) + res[106] = fma52lo(res[106], a[37], a[69]); // Sum(106) + res[107] = fma52hi(res[107], a[37], a[69]); // Sum(106) + res[107] = fma52lo(res[107], a[38], a[69]); // Sum(107) + res[108] = fma52hi(res[108], a[38], a[69]); // Sum(107) + res[96] = fma52lo(res[96], a[26], a[70]); // Sum(96) + res[97] = fma52hi(res[97], a[26], a[70]); // Sum(96) + res[97] = fma52lo(res[97], a[27], a[70]); // Sum(97) + res[98] = fma52hi(res[98], a[27], a[70]); // Sum(97) + res[98] = fma52lo(res[98], a[28], a[70]); // Sum(98) + res[99] = fma52hi(res[99], a[28], a[70]); // Sum(98) + res[99] = fma52lo(res[99], a[29], a[70]); // Sum(99) + res[100] = fma52hi(res[100], a[29], a[70]); // Sum(99) + res[100] = fma52lo(res[100], a[30], a[70]); // Sum(100) + res[101] = fma52hi(res[101], a[30], a[70]); // Sum(100) + res[101] = fma52lo(res[101], a[31], a[70]); // Sum(101) + res[102] = fma52hi(res[102], a[31], a[70]); // Sum(101) + res[102] = fma52lo(res[102], a[32], a[70]); // Sum(102) + res[103] = fma52hi(res[103], a[32], a[70]); // Sum(102) + res[103] = fma52lo(res[103], a[33], a[70]); // Sum(103) + res[104] = fma52hi(res[104], a[33], a[70]); // Sum(103) + res[104] = fma52lo(res[104], a[34], a[70]); // Sum(104) + res[105] = fma52hi(res[105], a[34], a[70]); // Sum(104) + res[105] = fma52lo(res[105], a[35], a[70]); // Sum(105) + res[106] = fma52hi(res[106], a[35], a[70]); // Sum(105) + res[106] = fma52lo(res[106], a[36], a[70]); // Sum(106) + res[107] = fma52hi(res[107], a[36], a[70]); // Sum(106) + res[107] = fma52lo(res[107], a[37], a[70]); // Sum(107) + res[108] = fma52hi(res[108], a[37], a[70]); // Sum(107) + res[96] = fma52lo(res[96], a[25], a[71]); // Sum(96) + res[97] = fma52hi(res[97], a[25], a[71]); // Sum(96) + res[97] = fma52lo(res[97], a[26], a[71]); // Sum(97) + res[98] = fma52hi(res[98], a[26], a[71]); // Sum(97) + res[98] = fma52lo(res[98], a[27], a[71]); // Sum(98) + res[99] = fma52hi(res[99], a[27], a[71]); // Sum(98) + res[99] = fma52lo(res[99], a[28], a[71]); // Sum(99) + res[100] = fma52hi(res[100], a[28], a[71]); // Sum(99) + res[100] = fma52lo(res[100], a[29], a[71]); // Sum(100) + res[101] = fma52hi(res[101], a[29], a[71]); // Sum(100) + res[101] = fma52lo(res[101], a[30], a[71]); // Sum(101) + res[102] = fma52hi(res[102], a[30], a[71]); // Sum(101) + res[102] = fma52lo(res[102], a[31], a[71]); // Sum(102) + res[103] = fma52hi(res[103], a[31], a[71]); // Sum(102) + res[103] = fma52lo(res[103], a[32], a[71]); // Sum(103) + res[104] = fma52hi(res[104], a[32], a[71]); // Sum(103) + res[104] = fma52lo(res[104], a[33], a[71]); // Sum(104) + res[105] = fma52hi(res[105], a[33], a[71]); // Sum(104) + res[105] = fma52lo(res[105], a[34], a[71]); // Sum(105) + res[106] = fma52hi(res[106], a[34], a[71]); // Sum(105) + res[106] = fma52lo(res[106], a[35], a[71]); // Sum(106) + res[107] = fma52hi(res[107], a[35], a[71]); // Sum(106) + res[107] = fma52lo(res[107], a[36], a[71]); // Sum(107) + res[108] = fma52hi(res[108], a[36], a[71]); // Sum(107) + res[96] = fma52lo(res[96], a[24], a[72]); // Sum(96) + res[97] = fma52hi(res[97], a[24], a[72]); // Sum(96) + res[97] = fma52lo(res[97], a[25], a[72]); // Sum(97) + res[98] = fma52hi(res[98], a[25], a[72]); // Sum(97) + res[98] = fma52lo(res[98], a[26], a[72]); // Sum(98) + res[99] = fma52hi(res[99], a[26], a[72]); // Sum(98) + res[99] = fma52lo(res[99], a[27], a[72]); // Sum(99) + res[100] = fma52hi(res[100], a[27], a[72]); // Sum(99) + res[100] = fma52lo(res[100], a[28], a[72]); // Sum(100) + res[101] = fma52hi(res[101], a[28], a[72]); // Sum(100) + res[101] = fma52lo(res[101], a[29], a[72]); // Sum(101) + res[102] = fma52hi(res[102], a[29], a[72]); // Sum(101) + res[102] = fma52lo(res[102], a[30], a[72]); // Sum(102) + res[103] = fma52hi(res[103], a[30], a[72]); // Sum(102) + res[103] = fma52lo(res[103], a[31], a[72]); // Sum(103) + res[104] = fma52hi(res[104], a[31], a[72]); // Sum(103) + res[104] = fma52lo(res[104], a[32], a[72]); // Sum(104) + res[105] = fma52hi(res[105], a[32], a[72]); // Sum(104) + res[105] = fma52lo(res[105], a[33], a[72]); // Sum(105) + res[106] = fma52hi(res[106], a[33], a[72]); // Sum(105) + res[106] = fma52lo(res[106], a[34], a[72]); // Sum(106) + res[107] = fma52hi(res[107], a[34], a[72]); // Sum(106) + res[107] = fma52lo(res[107], a[35], a[72]); // Sum(107) + res[108] = fma52hi(res[108], a[35], a[72]); // Sum(107) + res[96] = fma52lo(res[96], a[23], a[73]); // Sum(96) + res[97] = fma52hi(res[97], a[23], a[73]); // Sum(96) + res[97] = fma52lo(res[97], a[24], a[73]); // Sum(97) + res[98] = fma52hi(res[98], a[24], a[73]); // Sum(97) + res[98] = fma52lo(res[98], a[25], a[73]); // Sum(98) + res[99] = fma52hi(res[99], a[25], a[73]); // Sum(98) + res[99] = fma52lo(res[99], a[26], a[73]); // Sum(99) + res[100] = fma52hi(res[100], a[26], a[73]); // Sum(99) + res[100] = fma52lo(res[100], a[27], a[73]); // Sum(100) + res[101] = fma52hi(res[101], a[27], a[73]); // Sum(100) + res[101] = fma52lo(res[101], a[28], a[73]); // Sum(101) + res[102] = fma52hi(res[102], a[28], a[73]); // Sum(101) + res[102] = fma52lo(res[102], a[29], a[73]); // Sum(102) + res[103] = fma52hi(res[103], a[29], a[73]); // Sum(102) + res[103] = fma52lo(res[103], a[30], a[73]); // Sum(103) + res[104] = fma52hi(res[104], a[30], a[73]); // Sum(103) + res[104] = fma52lo(res[104], a[31], a[73]); // Sum(104) + res[105] = fma52hi(res[105], a[31], a[73]); // Sum(104) + res[105] = fma52lo(res[105], a[32], a[73]); // Sum(105) + res[106] = fma52hi(res[106], a[32], a[73]); // Sum(105) + res[106] = fma52lo(res[106], a[33], a[73]); // Sum(106) + res[107] = fma52hi(res[107], a[33], a[73]); // Sum(106) + res[107] = fma52lo(res[107], a[34], a[73]); // Sum(107) + res[108] = fma52hi(res[108], a[34], a[73]); // Sum(107) + res[96] = fma52lo(res[96], a[22], a[74]); // Sum(96) + res[97] = fma52hi(res[97], a[22], a[74]); // Sum(96) + res[97] = fma52lo(res[97], a[23], a[74]); // Sum(97) + res[98] = fma52hi(res[98], a[23], a[74]); // Sum(97) + res[98] = fma52lo(res[98], a[24], a[74]); // Sum(98) + res[99] = fma52hi(res[99], a[24], a[74]); // Sum(98) + res[99] = fma52lo(res[99], a[25], a[74]); // Sum(99) + res[100] = fma52hi(res[100], a[25], a[74]); // Sum(99) + res[100] = fma52lo(res[100], a[26], a[74]); // Sum(100) + res[101] = fma52hi(res[101], a[26], a[74]); // Sum(100) + res[101] = fma52lo(res[101], a[27], a[74]); // Sum(101) + res[102] = fma52hi(res[102], a[27], a[74]); // Sum(101) + res[102] = fma52lo(res[102], a[28], a[74]); // Sum(102) + res[103] = fma52hi(res[103], a[28], a[74]); // Sum(102) + res[103] = fma52lo(res[103], a[29], a[74]); // Sum(103) + res[104] = fma52hi(res[104], a[29], a[74]); // Sum(103) + res[104] = fma52lo(res[104], a[30], a[74]); // Sum(104) + res[105] = fma52hi(res[105], a[30], a[74]); // Sum(104) + res[105] = fma52lo(res[105], a[31], a[74]); // Sum(105) + res[106] = fma52hi(res[106], a[31], a[74]); // Sum(105) + res[106] = fma52lo(res[106], a[32], a[74]); // Sum(106) + res[107] = fma52hi(res[107], a[32], a[74]); // Sum(106) + res[107] = fma52lo(res[107], a[33], a[74]); // Sum(107) + res[108] = fma52hi(res[108], a[33], a[74]); // Sum(107) + res[96] = fma52lo(res[96], a[21], a[75]); // Sum(96) + res[97] = fma52hi(res[97], a[21], a[75]); // Sum(96) + res[97] = fma52lo(res[97], a[22], a[75]); // Sum(97) + res[98] = fma52hi(res[98], a[22], a[75]); // Sum(97) + res[98] = fma52lo(res[98], a[23], a[75]); // Sum(98) + res[99] = fma52hi(res[99], a[23], a[75]); // Sum(98) + res[99] = fma52lo(res[99], a[24], a[75]); // Sum(99) + res[100] = fma52hi(res[100], a[24], a[75]); // Sum(99) + res[100] = fma52lo(res[100], a[25], a[75]); // Sum(100) + res[101] = fma52hi(res[101], a[25], a[75]); // Sum(100) + res[101] = fma52lo(res[101], a[26], a[75]); // Sum(101) + res[102] = fma52hi(res[102], a[26], a[75]); // Sum(101) + res[102] = fma52lo(res[102], a[27], a[75]); // Sum(102) + res[103] = fma52hi(res[103], a[27], a[75]); // Sum(102) + res[103] = fma52lo(res[103], a[28], a[75]); // Sum(103) + res[104] = fma52hi(res[104], a[28], a[75]); // Sum(103) + res[104] = fma52lo(res[104], a[29], a[75]); // Sum(104) + res[105] = fma52hi(res[105], a[29], a[75]); // Sum(104) + res[105] = fma52lo(res[105], a[30], a[75]); // Sum(105) + res[106] = fma52hi(res[106], a[30], a[75]); // Sum(105) + res[106] = fma52lo(res[106], a[31], a[75]); // Sum(106) + res[107] = fma52hi(res[107], a[31], a[75]); // Sum(106) + res[107] = fma52lo(res[107], a[32], a[75]); // Sum(107) + res[108] = fma52hi(res[108], a[32], a[75]); // Sum(107) + res[96] = fma52lo(res[96], a[20], a[76]); // Sum(96) + res[97] = fma52hi(res[97], a[20], a[76]); // Sum(96) + res[97] = fma52lo(res[97], a[21], a[76]); // Sum(97) + res[98] = fma52hi(res[98], a[21], a[76]); // Sum(97) + res[98] = fma52lo(res[98], a[22], a[76]); // Sum(98) + res[99] = fma52hi(res[99], a[22], a[76]); // Sum(98) + res[99] = fma52lo(res[99], a[23], a[76]); // Sum(99) + res[100] = fma52hi(res[100], a[23], a[76]); // Sum(99) + res[100] = fma52lo(res[100], a[24], a[76]); // Sum(100) + res[101] = fma52hi(res[101], a[24], a[76]); // Sum(100) + res[101] = fma52lo(res[101], a[25], a[76]); // Sum(101) + res[102] = fma52hi(res[102], a[25], a[76]); // Sum(101) + res[102] = fma52lo(res[102], a[26], a[76]); // Sum(102) + res[103] = fma52hi(res[103], a[26], a[76]); // Sum(102) + res[103] = fma52lo(res[103], a[27], a[76]); // Sum(103) + res[104] = fma52hi(res[104], a[27], a[76]); // Sum(103) + res[104] = fma52lo(res[104], a[28], a[76]); // Sum(104) + res[105] = fma52hi(res[105], a[28], a[76]); // Sum(104) + res[105] = fma52lo(res[105], a[29], a[76]); // Sum(105) + res[106] = fma52hi(res[106], a[29], a[76]); // Sum(105) + res[106] = fma52lo(res[106], a[30], a[76]); // Sum(106) + res[107] = fma52hi(res[107], a[30], a[76]); // Sum(106) + res[107] = fma52lo(res[107], a[31], a[76]); // Sum(107) + res[108] = fma52hi(res[108], a[31], a[76]); // Sum(107) + res[96] = fma52lo(res[96], a[19], a[77]); // Sum(96) + res[97] = fma52hi(res[97], a[19], a[77]); // Sum(96) + res[97] = fma52lo(res[97], a[20], a[77]); // Sum(97) + res[98] = fma52hi(res[98], a[20], a[77]); // Sum(97) + res[98] = fma52lo(res[98], a[21], a[77]); // Sum(98) + res[99] = fma52hi(res[99], a[21], a[77]); // Sum(98) + res[99] = fma52lo(res[99], a[22], a[77]); // Sum(99) + res[100] = fma52hi(res[100], a[22], a[77]); // Sum(99) + res[100] = fma52lo(res[100], a[23], a[77]); // Sum(100) + res[101] = fma52hi(res[101], a[23], a[77]); // Sum(100) + res[101] = fma52lo(res[101], a[24], a[77]); // Sum(101) + res[102] = fma52hi(res[102], a[24], a[77]); // Sum(101) + res[102] = fma52lo(res[102], a[25], a[77]); // Sum(102) + res[103] = fma52hi(res[103], a[25], a[77]); // Sum(102) + res[103] = fma52lo(res[103], a[26], a[77]); // Sum(103) + res[104] = fma52hi(res[104], a[26], a[77]); // Sum(103) + res[104] = fma52lo(res[104], a[27], a[77]); // Sum(104) + res[105] = fma52hi(res[105], a[27], a[77]); // Sum(104) + res[105] = fma52lo(res[105], a[28], a[77]); // Sum(105) + res[106] = fma52hi(res[106], a[28], a[77]); // Sum(105) + res[106] = fma52lo(res[106], a[29], a[77]); // Sum(106) + res[107] = fma52hi(res[107], a[29], a[77]); // Sum(106) + res[107] = fma52lo(res[107], a[30], a[77]); // Sum(107) + res[108] = fma52hi(res[108], a[30], a[77]); // Sum(107) + res[96] = fma52lo(res[96], a[18], a[78]); // Sum(96) + res[97] = fma52hi(res[97], a[18], a[78]); // Sum(96) + res[97] = fma52lo(res[97], a[19], a[78]); // Sum(97) + res[98] = fma52hi(res[98], a[19], a[78]); // Sum(97) + res[98] = fma52lo(res[98], a[20], a[78]); // Sum(98) + res[99] = fma52hi(res[99], a[20], a[78]); // Sum(98) + res[99] = fma52lo(res[99], a[21], a[78]); // Sum(99) + res[100] = fma52hi(res[100], a[21], a[78]); // Sum(99) + res[100] = fma52lo(res[100], a[22], a[78]); // Sum(100) + res[101] = fma52hi(res[101], a[22], a[78]); // Sum(100) + res[101] = fma52lo(res[101], a[23], a[78]); // Sum(101) + res[102] = fma52hi(res[102], a[23], a[78]); // Sum(101) + res[102] = fma52lo(res[102], a[24], a[78]); // Sum(102) + res[103] = fma52hi(res[103], a[24], a[78]); // Sum(102) + res[103] = fma52lo(res[103], a[25], a[78]); // Sum(103) + res[104] = fma52hi(res[104], a[25], a[78]); // Sum(103) + res[104] = fma52lo(res[104], a[26], a[78]); // Sum(104) + res[105] = fma52hi(res[105], a[26], a[78]); // Sum(104) + res[105] = fma52lo(res[105], a[27], a[78]); // Sum(105) + res[106] = fma52hi(res[106], a[27], a[78]); // Sum(105) + res[106] = fma52lo(res[106], a[28], a[78]); // Sum(106) + res[107] = fma52hi(res[107], a[28], a[78]); // Sum(106) + res[107] = fma52lo(res[107], a[29], a[78]); // Sum(107) + res[108] = fma52hi(res[108], a[29], a[78]); // Sum(107) + res[96] = add64(res[96], res[96]); // Double(96) + res[97] = add64(res[97], res[97]); // Double(97) + res[98] = add64(res[98], res[98]); // Double(98) + res[99] = add64(res[99], res[99]); // Double(99) + res[100] = add64(res[100], res[100]); // Double(100) + res[101] = add64(res[101], res[101]); // Double(101) + res[102] = add64(res[102], res[102]); // Double(102) + res[103] = add64(res[103], res[103]); // Double(103) + res[104] = add64(res[104], res[104]); // Double(104) + res[105] = add64(res[105], res[105]); // Double(105) + res[106] = add64(res[106], res[106]); // Double(106) + res[107] = add64(res[107], res[107]); // Double(107) + res[96] = fma52lo(res[96], a[48], a[48]); // Add sqr(96) + res[97] = fma52hi(res[97], a[48], a[48]); // Add sqr(96) + res[98] = fma52lo(res[98], a[49], a[49]); // Add sqr(98) + res[99] = fma52hi(res[99], a[49], a[49]); // Add sqr(98) + res[100] = fma52lo(res[100], a[50], a[50]); // Add sqr(100) + res[101] = fma52hi(res[101], a[50], a[50]); // Add sqr(100) + res[102] = fma52lo(res[102], a[51], a[51]); // Add sqr(102) + res[103] = fma52hi(res[103], a[51], a[51]); // Add sqr(102) + res[104] = fma52lo(res[104], a[52], a[52]); // Add sqr(104) + res[105] = fma52hi(res[105], a[52], a[52]); // Add sqr(104) + res[106] = fma52lo(res[106], a[53], a[53]); // Add sqr(106) + res[107] = fma52hi(res[107], a[53], a[53]); // Add sqr(106) + res[108] = fma52lo(res[108], a[53], a[55]); // Sum(108) + res[109] = fma52hi(res[109], a[53], a[55]); // Sum(108) + res[109] = fma52lo(res[109], a[54], a[55]); // Sum(109) + res[110] = fma52hi(res[110], a[54], a[55]); // Sum(109) + res[108] = fma52lo(res[108], a[52], a[56]); // Sum(108) + res[109] = fma52hi(res[109], a[52], a[56]); // Sum(108) + res[109] = fma52lo(res[109], a[53], a[56]); // Sum(109) + res[110] = fma52hi(res[110], a[53], a[56]); // Sum(109) + res[110] = fma52lo(res[110], a[54], a[56]); // Sum(110) + res[111] = fma52hi(res[111], a[54], a[56]); // Sum(110) + res[111] = fma52lo(res[111], a[55], a[56]); // Sum(111) + res[112] = fma52hi(res[112], a[55], a[56]); // Sum(111) + res[108] = fma52lo(res[108], a[51], a[57]); // Sum(108) + res[109] = fma52hi(res[109], a[51], a[57]); // Sum(108) + res[109] = fma52lo(res[109], a[52], a[57]); // Sum(109) + res[110] = fma52hi(res[110], a[52], a[57]); // Sum(109) + res[110] = fma52lo(res[110], a[53], a[57]); // Sum(110) + res[111] = fma52hi(res[111], a[53], a[57]); // Sum(110) + res[111] = fma52lo(res[111], a[54], a[57]); // Sum(111) + res[112] = fma52hi(res[112], a[54], a[57]); // Sum(111) + res[112] = fma52lo(res[112], a[55], a[57]); // Sum(112) + res[113] = fma52hi(res[113], a[55], a[57]); // Sum(112) + res[113] = fma52lo(res[113], a[56], a[57]); // Sum(113) + res[114] = fma52hi(res[114], a[56], a[57]); // Sum(113) + res[108] = fma52lo(res[108], a[50], a[58]); // Sum(108) + res[109] = fma52hi(res[109], a[50], a[58]); // Sum(108) + res[109] = fma52lo(res[109], a[51], a[58]); // Sum(109) + res[110] = fma52hi(res[110], a[51], a[58]); // Sum(109) + res[110] = fma52lo(res[110], a[52], a[58]); // Sum(110) + res[111] = fma52hi(res[111], a[52], a[58]); // Sum(110) + res[111] = fma52lo(res[111], a[53], a[58]); // Sum(111) + res[112] = fma52hi(res[112], a[53], a[58]); // Sum(111) + res[112] = fma52lo(res[112], a[54], a[58]); // Sum(112) + res[113] = fma52hi(res[113], a[54], a[58]); // Sum(112) + res[113] = fma52lo(res[113], a[55], a[58]); // Sum(113) + res[114] = fma52hi(res[114], a[55], a[58]); // Sum(113) + res[114] = fma52lo(res[114], a[56], a[58]); // Sum(114) + res[115] = fma52hi(res[115], a[56], a[58]); // Sum(114) + res[115] = fma52lo(res[115], a[57], a[58]); // Sum(115) + res[116] = fma52hi(res[116], a[57], a[58]); // Sum(115) + res[108] = fma52lo(res[108], a[49], a[59]); // Sum(108) + res[109] = fma52hi(res[109], a[49], a[59]); // Sum(108) + res[109] = fma52lo(res[109], a[50], a[59]); // Sum(109) + res[110] = fma52hi(res[110], a[50], a[59]); // Sum(109) + res[110] = fma52lo(res[110], a[51], a[59]); // Sum(110) + res[111] = fma52hi(res[111], a[51], a[59]); // Sum(110) + res[111] = fma52lo(res[111], a[52], a[59]); // Sum(111) + res[112] = fma52hi(res[112], a[52], a[59]); // Sum(111) + res[112] = fma52lo(res[112], a[53], a[59]); // Sum(112) + res[113] = fma52hi(res[113], a[53], a[59]); // Sum(112) + res[113] = fma52lo(res[113], a[54], a[59]); // Sum(113) + res[114] = fma52hi(res[114], a[54], a[59]); // Sum(113) + res[114] = fma52lo(res[114], a[55], a[59]); // Sum(114) + res[115] = fma52hi(res[115], a[55], a[59]); // Sum(114) + res[115] = fma52lo(res[115], a[56], a[59]); // Sum(115) + res[116] = fma52hi(res[116], a[56], a[59]); // Sum(115) + res[116] = fma52lo(res[116], a[57], a[59]); // Sum(116) + res[117] = fma52hi(res[117], a[57], a[59]); // Sum(116) + res[117] = fma52lo(res[117], a[58], a[59]); // Sum(117) + res[118] = fma52hi(res[118], a[58], a[59]); // Sum(117) + res[108] = fma52lo(res[108], a[48], a[60]); // Sum(108) + res[109] = fma52hi(res[109], a[48], a[60]); // Sum(108) + res[109] = fma52lo(res[109], a[49], a[60]); // Sum(109) + res[110] = fma52hi(res[110], a[49], a[60]); // Sum(109) + res[110] = fma52lo(res[110], a[50], a[60]); // Sum(110) + res[111] = fma52hi(res[111], a[50], a[60]); // Sum(110) + res[111] = fma52lo(res[111], a[51], a[60]); // Sum(111) + res[112] = fma52hi(res[112], a[51], a[60]); // Sum(111) + res[112] = fma52lo(res[112], a[52], a[60]); // Sum(112) + res[113] = fma52hi(res[113], a[52], a[60]); // Sum(112) + res[113] = fma52lo(res[113], a[53], a[60]); // Sum(113) + res[114] = fma52hi(res[114], a[53], a[60]); // Sum(113) + res[114] = fma52lo(res[114], a[54], a[60]); // Sum(114) + res[115] = fma52hi(res[115], a[54], a[60]); // Sum(114) + res[115] = fma52lo(res[115], a[55], a[60]); // Sum(115) + res[116] = fma52hi(res[116], a[55], a[60]); // Sum(115) + res[116] = fma52lo(res[116], a[56], a[60]); // Sum(116) + res[117] = fma52hi(res[117], a[56], a[60]); // Sum(116) + res[117] = fma52lo(res[117], a[57], a[60]); // Sum(117) + res[118] = fma52hi(res[118], a[57], a[60]); // Sum(117) + res[118] = fma52lo(res[118], a[58], a[60]); // Sum(118) + res[119] = fma52hi(res[119], a[58], a[60]); // Sum(118) + res[119] = fma52lo(res[119], a[59], a[60]); // Sum(119) + res[120] = fma52hi(res[120], a[59], a[60]); // Sum(119) + res[108] = fma52lo(res[108], a[47], a[61]); // Sum(108) + res[109] = fma52hi(res[109], a[47], a[61]); // Sum(108) + res[109] = fma52lo(res[109], a[48], a[61]); // Sum(109) + res[110] = fma52hi(res[110], a[48], a[61]); // Sum(109) + res[110] = fma52lo(res[110], a[49], a[61]); // Sum(110) + res[111] = fma52hi(res[111], a[49], a[61]); // Sum(110) + res[111] = fma52lo(res[111], a[50], a[61]); // Sum(111) + res[112] = fma52hi(res[112], a[50], a[61]); // Sum(111) + res[112] = fma52lo(res[112], a[51], a[61]); // Sum(112) + res[113] = fma52hi(res[113], a[51], a[61]); // Sum(112) + res[113] = fma52lo(res[113], a[52], a[61]); // Sum(113) + res[114] = fma52hi(res[114], a[52], a[61]); // Sum(113) + res[114] = fma52lo(res[114], a[53], a[61]); // Sum(114) + res[115] = fma52hi(res[115], a[53], a[61]); // Sum(114) + res[115] = fma52lo(res[115], a[54], a[61]); // Sum(115) + res[116] = fma52hi(res[116], a[54], a[61]); // Sum(115) + res[116] = fma52lo(res[116], a[55], a[61]); // Sum(116) + res[117] = fma52hi(res[117], a[55], a[61]); // Sum(116) + res[117] = fma52lo(res[117], a[56], a[61]); // Sum(117) + res[118] = fma52hi(res[118], a[56], a[61]); // Sum(117) + res[118] = fma52lo(res[118], a[57], a[61]); // Sum(118) + res[119] = fma52hi(res[119], a[57], a[61]); // Sum(118) + res[119] = fma52lo(res[119], a[58], a[61]); // Sum(119) + res[120] = fma52hi(res[120], a[58], a[61]); // Sum(119) + res[108] = fma52lo(res[108], a[46], a[62]); // Sum(108) + res[109] = fma52hi(res[109], a[46], a[62]); // Sum(108) + res[109] = fma52lo(res[109], a[47], a[62]); // Sum(109) + res[110] = fma52hi(res[110], a[47], a[62]); // Sum(109) + res[110] = fma52lo(res[110], a[48], a[62]); // Sum(110) + res[111] = fma52hi(res[111], a[48], a[62]); // Sum(110) + res[111] = fma52lo(res[111], a[49], a[62]); // Sum(111) + res[112] = fma52hi(res[112], a[49], a[62]); // Sum(111) + res[112] = fma52lo(res[112], a[50], a[62]); // Sum(112) + res[113] = fma52hi(res[113], a[50], a[62]); // Sum(112) + res[113] = fma52lo(res[113], a[51], a[62]); // Sum(113) + res[114] = fma52hi(res[114], a[51], a[62]); // Sum(113) + res[114] = fma52lo(res[114], a[52], a[62]); // Sum(114) + res[115] = fma52hi(res[115], a[52], a[62]); // Sum(114) + res[115] = fma52lo(res[115], a[53], a[62]); // Sum(115) + res[116] = fma52hi(res[116], a[53], a[62]); // Sum(115) + res[116] = fma52lo(res[116], a[54], a[62]); // Sum(116) + res[117] = fma52hi(res[117], a[54], a[62]); // Sum(116) + res[117] = fma52lo(res[117], a[55], a[62]); // Sum(117) + res[118] = fma52hi(res[118], a[55], a[62]); // Sum(117) + res[118] = fma52lo(res[118], a[56], a[62]); // Sum(118) + res[119] = fma52hi(res[119], a[56], a[62]); // Sum(118) + res[119] = fma52lo(res[119], a[57], a[62]); // Sum(119) + res[120] = fma52hi(res[120], a[57], a[62]); // Sum(119) + res[108] = fma52lo(res[108], a[45], a[63]); // Sum(108) + res[109] = fma52hi(res[109], a[45], a[63]); // Sum(108) + res[109] = fma52lo(res[109], a[46], a[63]); // Sum(109) + res[110] = fma52hi(res[110], a[46], a[63]); // Sum(109) + res[110] = fma52lo(res[110], a[47], a[63]); // Sum(110) + res[111] = fma52hi(res[111], a[47], a[63]); // Sum(110) + res[111] = fma52lo(res[111], a[48], a[63]); // Sum(111) + res[112] = fma52hi(res[112], a[48], a[63]); // Sum(111) + res[112] = fma52lo(res[112], a[49], a[63]); // Sum(112) + res[113] = fma52hi(res[113], a[49], a[63]); // Sum(112) + res[113] = fma52lo(res[113], a[50], a[63]); // Sum(113) + res[114] = fma52hi(res[114], a[50], a[63]); // Sum(113) + res[114] = fma52lo(res[114], a[51], a[63]); // Sum(114) + res[115] = fma52hi(res[115], a[51], a[63]); // Sum(114) + res[115] = fma52lo(res[115], a[52], a[63]); // Sum(115) + res[116] = fma52hi(res[116], a[52], a[63]); // Sum(115) + res[116] = fma52lo(res[116], a[53], a[63]); // Sum(116) + res[117] = fma52hi(res[117], a[53], a[63]); // Sum(116) + res[117] = fma52lo(res[117], a[54], a[63]); // Sum(117) + res[118] = fma52hi(res[118], a[54], a[63]); // Sum(117) + res[118] = fma52lo(res[118], a[55], a[63]); // Sum(118) + res[119] = fma52hi(res[119], a[55], a[63]); // Sum(118) + res[119] = fma52lo(res[119], a[56], a[63]); // Sum(119) + res[120] = fma52hi(res[120], a[56], a[63]); // Sum(119) + res[108] = fma52lo(res[108], a[44], a[64]); // Sum(108) + res[109] = fma52hi(res[109], a[44], a[64]); // Sum(108) + res[109] = fma52lo(res[109], a[45], a[64]); // Sum(109) + res[110] = fma52hi(res[110], a[45], a[64]); // Sum(109) + res[110] = fma52lo(res[110], a[46], a[64]); // Sum(110) + res[111] = fma52hi(res[111], a[46], a[64]); // Sum(110) + res[111] = fma52lo(res[111], a[47], a[64]); // Sum(111) + res[112] = fma52hi(res[112], a[47], a[64]); // Sum(111) + res[112] = fma52lo(res[112], a[48], a[64]); // Sum(112) + res[113] = fma52hi(res[113], a[48], a[64]); // Sum(112) + res[113] = fma52lo(res[113], a[49], a[64]); // Sum(113) + res[114] = fma52hi(res[114], a[49], a[64]); // Sum(113) + res[114] = fma52lo(res[114], a[50], a[64]); // Sum(114) + res[115] = fma52hi(res[115], a[50], a[64]); // Sum(114) + res[115] = fma52lo(res[115], a[51], a[64]); // Sum(115) + res[116] = fma52hi(res[116], a[51], a[64]); // Sum(115) + res[116] = fma52lo(res[116], a[52], a[64]); // Sum(116) + res[117] = fma52hi(res[117], a[52], a[64]); // Sum(116) + res[117] = fma52lo(res[117], a[53], a[64]); // Sum(117) + res[118] = fma52hi(res[118], a[53], a[64]); // Sum(117) + res[118] = fma52lo(res[118], a[54], a[64]); // Sum(118) + res[119] = fma52hi(res[119], a[54], a[64]); // Sum(118) + res[119] = fma52lo(res[119], a[55], a[64]); // Sum(119) + res[120] = fma52hi(res[120], a[55], a[64]); // Sum(119) + res[108] = fma52lo(res[108], a[43], a[65]); // Sum(108) + res[109] = fma52hi(res[109], a[43], a[65]); // Sum(108) + res[109] = fma52lo(res[109], a[44], a[65]); // Sum(109) + res[110] = fma52hi(res[110], a[44], a[65]); // Sum(109) + res[110] = fma52lo(res[110], a[45], a[65]); // Sum(110) + res[111] = fma52hi(res[111], a[45], a[65]); // Sum(110) + res[111] = fma52lo(res[111], a[46], a[65]); // Sum(111) + res[112] = fma52hi(res[112], a[46], a[65]); // Sum(111) + res[112] = fma52lo(res[112], a[47], a[65]); // Sum(112) + res[113] = fma52hi(res[113], a[47], a[65]); // Sum(112) + res[113] = fma52lo(res[113], a[48], a[65]); // Sum(113) + res[114] = fma52hi(res[114], a[48], a[65]); // Sum(113) + res[114] = fma52lo(res[114], a[49], a[65]); // Sum(114) + res[115] = fma52hi(res[115], a[49], a[65]); // Sum(114) + res[115] = fma52lo(res[115], a[50], a[65]); // Sum(115) + res[116] = fma52hi(res[116], a[50], a[65]); // Sum(115) + res[116] = fma52lo(res[116], a[51], a[65]); // Sum(116) + res[117] = fma52hi(res[117], a[51], a[65]); // Sum(116) + res[117] = fma52lo(res[117], a[52], a[65]); // Sum(117) + res[118] = fma52hi(res[118], a[52], a[65]); // Sum(117) + res[118] = fma52lo(res[118], a[53], a[65]); // Sum(118) + res[119] = fma52hi(res[119], a[53], a[65]); // Sum(118) + res[119] = fma52lo(res[119], a[54], a[65]); // Sum(119) + res[120] = fma52hi(res[120], a[54], a[65]); // Sum(119) + res[108] = fma52lo(res[108], a[42], a[66]); // Sum(108) + res[109] = fma52hi(res[109], a[42], a[66]); // Sum(108) + res[109] = fma52lo(res[109], a[43], a[66]); // Sum(109) + res[110] = fma52hi(res[110], a[43], a[66]); // Sum(109) + res[110] = fma52lo(res[110], a[44], a[66]); // Sum(110) + res[111] = fma52hi(res[111], a[44], a[66]); // Sum(110) + res[111] = fma52lo(res[111], a[45], a[66]); // Sum(111) + res[112] = fma52hi(res[112], a[45], a[66]); // Sum(111) + res[112] = fma52lo(res[112], a[46], a[66]); // Sum(112) + res[113] = fma52hi(res[113], a[46], a[66]); // Sum(112) + res[113] = fma52lo(res[113], a[47], a[66]); // Sum(113) + res[114] = fma52hi(res[114], a[47], a[66]); // Sum(113) + res[114] = fma52lo(res[114], a[48], a[66]); // Sum(114) + res[115] = fma52hi(res[115], a[48], a[66]); // Sum(114) + res[115] = fma52lo(res[115], a[49], a[66]); // Sum(115) + res[116] = fma52hi(res[116], a[49], a[66]); // Sum(115) + res[116] = fma52lo(res[116], a[50], a[66]); // Sum(116) + res[117] = fma52hi(res[117], a[50], a[66]); // Sum(116) + res[117] = fma52lo(res[117], a[51], a[66]); // Sum(117) + res[118] = fma52hi(res[118], a[51], a[66]); // Sum(117) + res[118] = fma52lo(res[118], a[52], a[66]); // Sum(118) + res[119] = fma52hi(res[119], a[52], a[66]); // Sum(118) + res[119] = fma52lo(res[119], a[53], a[66]); // Sum(119) + res[120] = fma52hi(res[120], a[53], a[66]); // Sum(119) + res[108] = fma52lo(res[108], a[41], a[67]); // Sum(108) + res[109] = fma52hi(res[109], a[41], a[67]); // Sum(108) + res[109] = fma52lo(res[109], a[42], a[67]); // Sum(109) + res[110] = fma52hi(res[110], a[42], a[67]); // Sum(109) + res[110] = fma52lo(res[110], a[43], a[67]); // Sum(110) + res[111] = fma52hi(res[111], a[43], a[67]); // Sum(110) + res[111] = fma52lo(res[111], a[44], a[67]); // Sum(111) + res[112] = fma52hi(res[112], a[44], a[67]); // Sum(111) + res[112] = fma52lo(res[112], a[45], a[67]); // Sum(112) + res[113] = fma52hi(res[113], a[45], a[67]); // Sum(112) + res[113] = fma52lo(res[113], a[46], a[67]); // Sum(113) + res[114] = fma52hi(res[114], a[46], a[67]); // Sum(113) + res[114] = fma52lo(res[114], a[47], a[67]); // Sum(114) + res[115] = fma52hi(res[115], a[47], a[67]); // Sum(114) + res[115] = fma52lo(res[115], a[48], a[67]); // Sum(115) + res[116] = fma52hi(res[116], a[48], a[67]); // Sum(115) + res[116] = fma52lo(res[116], a[49], a[67]); // Sum(116) + res[117] = fma52hi(res[117], a[49], a[67]); // Sum(116) + res[117] = fma52lo(res[117], a[50], a[67]); // Sum(117) + res[118] = fma52hi(res[118], a[50], a[67]); // Sum(117) + res[118] = fma52lo(res[118], a[51], a[67]); // Sum(118) + res[119] = fma52hi(res[119], a[51], a[67]); // Sum(118) + res[119] = fma52lo(res[119], a[52], a[67]); // Sum(119) + res[120] = fma52hi(res[120], a[52], a[67]); // Sum(119) + res[108] = fma52lo(res[108], a[40], a[68]); // Sum(108) + res[109] = fma52hi(res[109], a[40], a[68]); // Sum(108) + res[109] = fma52lo(res[109], a[41], a[68]); // Sum(109) + res[110] = fma52hi(res[110], a[41], a[68]); // Sum(109) + res[110] = fma52lo(res[110], a[42], a[68]); // Sum(110) + res[111] = fma52hi(res[111], a[42], a[68]); // Sum(110) + res[111] = fma52lo(res[111], a[43], a[68]); // Sum(111) + res[112] = fma52hi(res[112], a[43], a[68]); // Sum(111) + res[112] = fma52lo(res[112], a[44], a[68]); // Sum(112) + res[113] = fma52hi(res[113], a[44], a[68]); // Sum(112) + res[113] = fma52lo(res[113], a[45], a[68]); // Sum(113) + res[114] = fma52hi(res[114], a[45], a[68]); // Sum(113) + res[114] = fma52lo(res[114], a[46], a[68]); // Sum(114) + res[115] = fma52hi(res[115], a[46], a[68]); // Sum(114) + res[115] = fma52lo(res[115], a[47], a[68]); // Sum(115) + res[116] = fma52hi(res[116], a[47], a[68]); // Sum(115) + res[116] = fma52lo(res[116], a[48], a[68]); // Sum(116) + res[117] = fma52hi(res[117], a[48], a[68]); // Sum(116) + res[117] = fma52lo(res[117], a[49], a[68]); // Sum(117) + res[118] = fma52hi(res[118], a[49], a[68]); // Sum(117) + res[118] = fma52lo(res[118], a[50], a[68]); // Sum(118) + res[119] = fma52hi(res[119], a[50], a[68]); // Sum(118) + res[119] = fma52lo(res[119], a[51], a[68]); // Sum(119) + res[120] = fma52hi(res[120], a[51], a[68]); // Sum(119) + res[108] = fma52lo(res[108], a[39], a[69]); // Sum(108) + res[109] = fma52hi(res[109], a[39], a[69]); // Sum(108) + res[109] = fma52lo(res[109], a[40], a[69]); // Sum(109) + res[110] = fma52hi(res[110], a[40], a[69]); // Sum(109) + res[110] = fma52lo(res[110], a[41], a[69]); // Sum(110) + res[111] = fma52hi(res[111], a[41], a[69]); // Sum(110) + res[111] = fma52lo(res[111], a[42], a[69]); // Sum(111) + res[112] = fma52hi(res[112], a[42], a[69]); // Sum(111) + res[112] = fma52lo(res[112], a[43], a[69]); // Sum(112) + res[113] = fma52hi(res[113], a[43], a[69]); // Sum(112) + res[113] = fma52lo(res[113], a[44], a[69]); // Sum(113) + res[114] = fma52hi(res[114], a[44], a[69]); // Sum(113) + res[114] = fma52lo(res[114], a[45], a[69]); // Sum(114) + res[115] = fma52hi(res[115], a[45], a[69]); // Sum(114) + res[115] = fma52lo(res[115], a[46], a[69]); // Sum(115) + res[116] = fma52hi(res[116], a[46], a[69]); // Sum(115) + res[116] = fma52lo(res[116], a[47], a[69]); // Sum(116) + res[117] = fma52hi(res[117], a[47], a[69]); // Sum(116) + res[117] = fma52lo(res[117], a[48], a[69]); // Sum(117) + res[118] = fma52hi(res[118], a[48], a[69]); // Sum(117) + res[118] = fma52lo(res[118], a[49], a[69]); // Sum(118) + res[119] = fma52hi(res[119], a[49], a[69]); // Sum(118) + res[119] = fma52lo(res[119], a[50], a[69]); // Sum(119) + res[120] = fma52hi(res[120], a[50], a[69]); // Sum(119) + res[108] = fma52lo(res[108], a[38], a[70]); // Sum(108) + res[109] = fma52hi(res[109], a[38], a[70]); // Sum(108) + res[109] = fma52lo(res[109], a[39], a[70]); // Sum(109) + res[110] = fma52hi(res[110], a[39], a[70]); // Sum(109) + res[110] = fma52lo(res[110], a[40], a[70]); // Sum(110) + res[111] = fma52hi(res[111], a[40], a[70]); // Sum(110) + res[111] = fma52lo(res[111], a[41], a[70]); // Sum(111) + res[112] = fma52hi(res[112], a[41], a[70]); // Sum(111) + res[112] = fma52lo(res[112], a[42], a[70]); // Sum(112) + res[113] = fma52hi(res[113], a[42], a[70]); // Sum(112) + res[113] = fma52lo(res[113], a[43], a[70]); // Sum(113) + res[114] = fma52hi(res[114], a[43], a[70]); // Sum(113) + res[114] = fma52lo(res[114], a[44], a[70]); // Sum(114) + res[115] = fma52hi(res[115], a[44], a[70]); // Sum(114) + res[115] = fma52lo(res[115], a[45], a[70]); // Sum(115) + res[116] = fma52hi(res[116], a[45], a[70]); // Sum(115) + res[116] = fma52lo(res[116], a[46], a[70]); // Sum(116) + res[117] = fma52hi(res[117], a[46], a[70]); // Sum(116) + res[117] = fma52lo(res[117], a[47], a[70]); // Sum(117) + res[118] = fma52hi(res[118], a[47], a[70]); // Sum(117) + res[118] = fma52lo(res[118], a[48], a[70]); // Sum(118) + res[119] = fma52hi(res[119], a[48], a[70]); // Sum(118) + res[119] = fma52lo(res[119], a[49], a[70]); // Sum(119) + res[120] = fma52hi(res[120], a[49], a[70]); // Sum(119) + res[108] = fma52lo(res[108], a[37], a[71]); // Sum(108) + res[109] = fma52hi(res[109], a[37], a[71]); // Sum(108) + res[109] = fma52lo(res[109], a[38], a[71]); // Sum(109) + res[110] = fma52hi(res[110], a[38], a[71]); // Sum(109) + res[110] = fma52lo(res[110], a[39], a[71]); // Sum(110) + res[111] = fma52hi(res[111], a[39], a[71]); // Sum(110) + res[111] = fma52lo(res[111], a[40], a[71]); // Sum(111) + res[112] = fma52hi(res[112], a[40], a[71]); // Sum(111) + res[112] = fma52lo(res[112], a[41], a[71]); // Sum(112) + res[113] = fma52hi(res[113], a[41], a[71]); // Sum(112) + res[113] = fma52lo(res[113], a[42], a[71]); // Sum(113) + res[114] = fma52hi(res[114], a[42], a[71]); // Sum(113) + res[114] = fma52lo(res[114], a[43], a[71]); // Sum(114) + res[115] = fma52hi(res[115], a[43], a[71]); // Sum(114) + res[115] = fma52lo(res[115], a[44], a[71]); // Sum(115) + res[116] = fma52hi(res[116], a[44], a[71]); // Sum(115) + res[116] = fma52lo(res[116], a[45], a[71]); // Sum(116) + res[117] = fma52hi(res[117], a[45], a[71]); // Sum(116) + res[117] = fma52lo(res[117], a[46], a[71]); // Sum(117) + res[118] = fma52hi(res[118], a[46], a[71]); // Sum(117) + res[118] = fma52lo(res[118], a[47], a[71]); // Sum(118) + res[119] = fma52hi(res[119], a[47], a[71]); // Sum(118) + res[119] = fma52lo(res[119], a[48], a[71]); // Sum(119) + res[120] = fma52hi(res[120], a[48], a[71]); // Sum(119) + res[108] = fma52lo(res[108], a[36], a[72]); // Sum(108) + res[109] = fma52hi(res[109], a[36], a[72]); // Sum(108) + res[109] = fma52lo(res[109], a[37], a[72]); // Sum(109) + res[110] = fma52hi(res[110], a[37], a[72]); // Sum(109) + res[110] = fma52lo(res[110], a[38], a[72]); // Sum(110) + res[111] = fma52hi(res[111], a[38], a[72]); // Sum(110) + res[111] = fma52lo(res[111], a[39], a[72]); // Sum(111) + res[112] = fma52hi(res[112], a[39], a[72]); // Sum(111) + res[112] = fma52lo(res[112], a[40], a[72]); // Sum(112) + res[113] = fma52hi(res[113], a[40], a[72]); // Sum(112) + res[113] = fma52lo(res[113], a[41], a[72]); // Sum(113) + res[114] = fma52hi(res[114], a[41], a[72]); // Sum(113) + res[114] = fma52lo(res[114], a[42], a[72]); // Sum(114) + res[115] = fma52hi(res[115], a[42], a[72]); // Sum(114) + res[115] = fma52lo(res[115], a[43], a[72]); // Sum(115) + res[116] = fma52hi(res[116], a[43], a[72]); // Sum(115) + res[116] = fma52lo(res[116], a[44], a[72]); // Sum(116) + res[117] = fma52hi(res[117], a[44], a[72]); // Sum(116) + res[117] = fma52lo(res[117], a[45], a[72]); // Sum(117) + res[118] = fma52hi(res[118], a[45], a[72]); // Sum(117) + res[118] = fma52lo(res[118], a[46], a[72]); // Sum(118) + res[119] = fma52hi(res[119], a[46], a[72]); // Sum(118) + res[119] = fma52lo(res[119], a[47], a[72]); // Sum(119) + res[120] = fma52hi(res[120], a[47], a[72]); // Sum(119) + res[108] = fma52lo(res[108], a[35], a[73]); // Sum(108) + res[109] = fma52hi(res[109], a[35], a[73]); // Sum(108) + res[109] = fma52lo(res[109], a[36], a[73]); // Sum(109) + res[110] = fma52hi(res[110], a[36], a[73]); // Sum(109) + res[110] = fma52lo(res[110], a[37], a[73]); // Sum(110) + res[111] = fma52hi(res[111], a[37], a[73]); // Sum(110) + res[111] = fma52lo(res[111], a[38], a[73]); // Sum(111) + res[112] = fma52hi(res[112], a[38], a[73]); // Sum(111) + res[112] = fma52lo(res[112], a[39], a[73]); // Sum(112) + res[113] = fma52hi(res[113], a[39], a[73]); // Sum(112) + res[113] = fma52lo(res[113], a[40], a[73]); // Sum(113) + res[114] = fma52hi(res[114], a[40], a[73]); // Sum(113) + res[114] = fma52lo(res[114], a[41], a[73]); // Sum(114) + res[115] = fma52hi(res[115], a[41], a[73]); // Sum(114) + res[115] = fma52lo(res[115], a[42], a[73]); // Sum(115) + res[116] = fma52hi(res[116], a[42], a[73]); // Sum(115) + res[116] = fma52lo(res[116], a[43], a[73]); // Sum(116) + res[117] = fma52hi(res[117], a[43], a[73]); // Sum(116) + res[117] = fma52lo(res[117], a[44], a[73]); // Sum(117) + res[118] = fma52hi(res[118], a[44], a[73]); // Sum(117) + res[118] = fma52lo(res[118], a[45], a[73]); // Sum(118) + res[119] = fma52hi(res[119], a[45], a[73]); // Sum(118) + res[119] = fma52lo(res[119], a[46], a[73]); // Sum(119) + res[120] = fma52hi(res[120], a[46], a[73]); // Sum(119) + res[108] = fma52lo(res[108], a[34], a[74]); // Sum(108) + res[109] = fma52hi(res[109], a[34], a[74]); // Sum(108) + res[109] = fma52lo(res[109], a[35], a[74]); // Sum(109) + res[110] = fma52hi(res[110], a[35], a[74]); // Sum(109) + res[110] = fma52lo(res[110], a[36], a[74]); // Sum(110) + res[111] = fma52hi(res[111], a[36], a[74]); // Sum(110) + res[111] = fma52lo(res[111], a[37], a[74]); // Sum(111) + res[112] = fma52hi(res[112], a[37], a[74]); // Sum(111) + res[112] = fma52lo(res[112], a[38], a[74]); // Sum(112) + res[113] = fma52hi(res[113], a[38], a[74]); // Sum(112) + res[113] = fma52lo(res[113], a[39], a[74]); // Sum(113) + res[114] = fma52hi(res[114], a[39], a[74]); // Sum(113) + res[114] = fma52lo(res[114], a[40], a[74]); // Sum(114) + res[115] = fma52hi(res[115], a[40], a[74]); // Sum(114) + res[115] = fma52lo(res[115], a[41], a[74]); // Sum(115) + res[116] = fma52hi(res[116], a[41], a[74]); // Sum(115) + res[116] = fma52lo(res[116], a[42], a[74]); // Sum(116) + res[117] = fma52hi(res[117], a[42], a[74]); // Sum(116) + res[117] = fma52lo(res[117], a[43], a[74]); // Sum(117) + res[118] = fma52hi(res[118], a[43], a[74]); // Sum(117) + res[118] = fma52lo(res[118], a[44], a[74]); // Sum(118) + res[119] = fma52hi(res[119], a[44], a[74]); // Sum(118) + res[119] = fma52lo(res[119], a[45], a[74]); // Sum(119) + res[120] = fma52hi(res[120], a[45], a[74]); // Sum(119) + res[108] = fma52lo(res[108], a[33], a[75]); // Sum(108) + res[109] = fma52hi(res[109], a[33], a[75]); // Sum(108) + res[109] = fma52lo(res[109], a[34], a[75]); // Sum(109) + res[110] = fma52hi(res[110], a[34], a[75]); // Sum(109) + res[110] = fma52lo(res[110], a[35], a[75]); // Sum(110) + res[111] = fma52hi(res[111], a[35], a[75]); // Sum(110) + res[111] = fma52lo(res[111], a[36], a[75]); // Sum(111) + res[112] = fma52hi(res[112], a[36], a[75]); // Sum(111) + res[112] = fma52lo(res[112], a[37], a[75]); // Sum(112) + res[113] = fma52hi(res[113], a[37], a[75]); // Sum(112) + res[113] = fma52lo(res[113], a[38], a[75]); // Sum(113) + res[114] = fma52hi(res[114], a[38], a[75]); // Sum(113) + res[114] = fma52lo(res[114], a[39], a[75]); // Sum(114) + res[115] = fma52hi(res[115], a[39], a[75]); // Sum(114) + res[115] = fma52lo(res[115], a[40], a[75]); // Sum(115) + res[116] = fma52hi(res[116], a[40], a[75]); // Sum(115) + res[116] = fma52lo(res[116], a[41], a[75]); // Sum(116) + res[117] = fma52hi(res[117], a[41], a[75]); // Sum(116) + res[117] = fma52lo(res[117], a[42], a[75]); // Sum(117) + res[118] = fma52hi(res[118], a[42], a[75]); // Sum(117) + res[118] = fma52lo(res[118], a[43], a[75]); // Sum(118) + res[119] = fma52hi(res[119], a[43], a[75]); // Sum(118) + res[119] = fma52lo(res[119], a[44], a[75]); // Sum(119) + res[120] = fma52hi(res[120], a[44], a[75]); // Sum(119) + res[108] = fma52lo(res[108], a[32], a[76]); // Sum(108) + res[109] = fma52hi(res[109], a[32], a[76]); // Sum(108) + res[109] = fma52lo(res[109], a[33], a[76]); // Sum(109) + res[110] = fma52hi(res[110], a[33], a[76]); // Sum(109) + res[110] = fma52lo(res[110], a[34], a[76]); // Sum(110) + res[111] = fma52hi(res[111], a[34], a[76]); // Sum(110) + res[111] = fma52lo(res[111], a[35], a[76]); // Sum(111) + res[112] = fma52hi(res[112], a[35], a[76]); // Sum(111) + res[112] = fma52lo(res[112], a[36], a[76]); // Sum(112) + res[113] = fma52hi(res[113], a[36], a[76]); // Sum(112) + res[113] = fma52lo(res[113], a[37], a[76]); // Sum(113) + res[114] = fma52hi(res[114], a[37], a[76]); // Sum(113) + res[114] = fma52lo(res[114], a[38], a[76]); // Sum(114) + res[115] = fma52hi(res[115], a[38], a[76]); // Sum(114) + res[115] = fma52lo(res[115], a[39], a[76]); // Sum(115) + res[116] = fma52hi(res[116], a[39], a[76]); // Sum(115) + res[116] = fma52lo(res[116], a[40], a[76]); // Sum(116) + res[117] = fma52hi(res[117], a[40], a[76]); // Sum(116) + res[117] = fma52lo(res[117], a[41], a[76]); // Sum(117) + res[118] = fma52hi(res[118], a[41], a[76]); // Sum(117) + res[118] = fma52lo(res[118], a[42], a[76]); // Sum(118) + res[119] = fma52hi(res[119], a[42], a[76]); // Sum(118) + res[119] = fma52lo(res[119], a[43], a[76]); // Sum(119) + res[120] = fma52hi(res[120], a[43], a[76]); // Sum(119) + res[108] = fma52lo(res[108], a[31], a[77]); // Sum(108) + res[109] = fma52hi(res[109], a[31], a[77]); // Sum(108) + res[109] = fma52lo(res[109], a[32], a[77]); // Sum(109) + res[110] = fma52hi(res[110], a[32], a[77]); // Sum(109) + res[110] = fma52lo(res[110], a[33], a[77]); // Sum(110) + res[111] = fma52hi(res[111], a[33], a[77]); // Sum(110) + res[111] = fma52lo(res[111], a[34], a[77]); // Sum(111) + res[112] = fma52hi(res[112], a[34], a[77]); // Sum(111) + res[112] = fma52lo(res[112], a[35], a[77]); // Sum(112) + res[113] = fma52hi(res[113], a[35], a[77]); // Sum(112) + res[113] = fma52lo(res[113], a[36], a[77]); // Sum(113) + res[114] = fma52hi(res[114], a[36], a[77]); // Sum(113) + res[114] = fma52lo(res[114], a[37], a[77]); // Sum(114) + res[115] = fma52hi(res[115], a[37], a[77]); // Sum(114) + res[115] = fma52lo(res[115], a[38], a[77]); // Sum(115) + res[116] = fma52hi(res[116], a[38], a[77]); // Sum(115) + res[116] = fma52lo(res[116], a[39], a[77]); // Sum(116) + res[117] = fma52hi(res[117], a[39], a[77]); // Sum(116) + res[117] = fma52lo(res[117], a[40], a[77]); // Sum(117) + res[118] = fma52hi(res[118], a[40], a[77]); // Sum(117) + res[118] = fma52lo(res[118], a[41], a[77]); // Sum(118) + res[119] = fma52hi(res[119], a[41], a[77]); // Sum(118) + res[119] = fma52lo(res[119], a[42], a[77]); // Sum(119) + res[120] = fma52hi(res[120], a[42], a[77]); // Sum(119) + res[108] = fma52lo(res[108], a[30], a[78]); // Sum(108) + res[109] = fma52hi(res[109], a[30], a[78]); // Sum(108) + res[109] = fma52lo(res[109], a[31], a[78]); // Sum(109) + res[110] = fma52hi(res[110], a[31], a[78]); // Sum(109) + res[110] = fma52lo(res[110], a[32], a[78]); // Sum(110) + res[111] = fma52hi(res[111], a[32], a[78]); // Sum(110) + res[111] = fma52lo(res[111], a[33], a[78]); // Sum(111) + res[112] = fma52hi(res[112], a[33], a[78]); // Sum(111) + res[112] = fma52lo(res[112], a[34], a[78]); // Sum(112) + res[113] = fma52hi(res[113], a[34], a[78]); // Sum(112) + res[113] = fma52lo(res[113], a[35], a[78]); // Sum(113) + res[114] = fma52hi(res[114], a[35], a[78]); // Sum(113) + res[114] = fma52lo(res[114], a[36], a[78]); // Sum(114) + res[115] = fma52hi(res[115], a[36], a[78]); // Sum(114) + res[115] = fma52lo(res[115], a[37], a[78]); // Sum(115) + res[116] = fma52hi(res[116], a[37], a[78]); // Sum(115) + res[116] = fma52lo(res[116], a[38], a[78]); // Sum(116) + res[117] = fma52hi(res[117], a[38], a[78]); // Sum(116) + res[117] = fma52lo(res[117], a[39], a[78]); // Sum(117) + res[118] = fma52hi(res[118], a[39], a[78]); // Sum(117) + res[118] = fma52lo(res[118], a[40], a[78]); // Sum(118) + res[119] = fma52hi(res[119], a[40], a[78]); // Sum(118) + res[119] = fma52lo(res[119], a[41], a[78]); // Sum(119) + res[120] = fma52hi(res[120], a[41], a[78]); // Sum(119) + res[108] = add64(res[108], res[108]); // Double(108) + res[109] = add64(res[109], res[109]); // Double(109) + res[110] = add64(res[110], res[110]); // Double(110) + res[111] = add64(res[111], res[111]); // Double(111) + res[112] = add64(res[112], res[112]); // Double(112) + res[113] = add64(res[113], res[113]); // Double(113) + res[114] = add64(res[114], res[114]); // Double(114) + res[115] = add64(res[115], res[115]); // Double(115) + res[116] = add64(res[116], res[116]); // Double(116) + res[117] = add64(res[117], res[117]); // Double(117) + res[118] = add64(res[118], res[118]); // Double(118) + res[119] = add64(res[119], res[119]); // Double(119) + res[108] = fma52lo(res[108], a[54], a[54]); // Add sqr(108) + res[109] = fma52hi(res[109], a[54], a[54]); // Add sqr(108) + res[110] = fma52lo(res[110], a[55], a[55]); // Add sqr(110) + res[111] = fma52hi(res[111], a[55], a[55]); // Add sqr(110) + res[112] = fma52lo(res[112], a[56], a[56]); // Add sqr(112) + res[113] = fma52hi(res[113], a[56], a[56]); // Add sqr(112) + res[114] = fma52lo(res[114], a[57], a[57]); // Add sqr(114) + res[115] = fma52hi(res[115], a[57], a[57]); // Add sqr(114) + res[116] = fma52lo(res[116], a[58], a[58]); // Add sqr(116) + res[117] = fma52hi(res[117], a[58], a[58]); // Add sqr(116) + res[118] = fma52lo(res[118], a[59], a[59]); // Add sqr(118) + res[119] = fma52hi(res[119], a[59], a[59]); // Add sqr(118) + res[120] = fma52lo(res[120], a[59], a[61]); // Sum(120) + res[121] = fma52hi(res[121], a[59], a[61]); // Sum(120) + res[121] = fma52lo(res[121], a[60], a[61]); // Sum(121) + res[122] = fma52hi(res[122], a[60], a[61]); // Sum(121) + res[120] = fma52lo(res[120], a[58], a[62]); // Sum(120) + res[121] = fma52hi(res[121], a[58], a[62]); // Sum(120) + res[121] = fma52lo(res[121], a[59], a[62]); // Sum(121) + res[122] = fma52hi(res[122], a[59], a[62]); // Sum(121) + res[122] = fma52lo(res[122], a[60], a[62]); // Sum(122) + res[123] = fma52hi(res[123], a[60], a[62]); // Sum(122) + res[123] = fma52lo(res[123], a[61], a[62]); // Sum(123) + res[124] = fma52hi(res[124], a[61], a[62]); // Sum(123) + res[120] = fma52lo(res[120], a[57], a[63]); // Sum(120) + res[121] = fma52hi(res[121], a[57], a[63]); // Sum(120) + res[121] = fma52lo(res[121], a[58], a[63]); // Sum(121) + res[122] = fma52hi(res[122], a[58], a[63]); // Sum(121) + res[122] = fma52lo(res[122], a[59], a[63]); // Sum(122) + res[123] = fma52hi(res[123], a[59], a[63]); // Sum(122) + res[123] = fma52lo(res[123], a[60], a[63]); // Sum(123) + res[124] = fma52hi(res[124], a[60], a[63]); // Sum(123) + res[124] = fma52lo(res[124], a[61], a[63]); // Sum(124) + res[125] = fma52hi(res[125], a[61], a[63]); // Sum(124) + res[125] = fma52lo(res[125], a[62], a[63]); // Sum(125) + res[126] = fma52hi(res[126], a[62], a[63]); // Sum(125) + res[120] = fma52lo(res[120], a[56], a[64]); // Sum(120) + res[121] = fma52hi(res[121], a[56], a[64]); // Sum(120) + res[121] = fma52lo(res[121], a[57], a[64]); // Sum(121) + res[122] = fma52hi(res[122], a[57], a[64]); // Sum(121) + res[122] = fma52lo(res[122], a[58], a[64]); // Sum(122) + res[123] = fma52hi(res[123], a[58], a[64]); // Sum(122) + res[123] = fma52lo(res[123], a[59], a[64]); // Sum(123) + res[124] = fma52hi(res[124], a[59], a[64]); // Sum(123) + res[124] = fma52lo(res[124], a[60], a[64]); // Sum(124) + res[125] = fma52hi(res[125], a[60], a[64]); // Sum(124) + res[125] = fma52lo(res[125], a[61], a[64]); // Sum(125) + res[126] = fma52hi(res[126], a[61], a[64]); // Sum(125) + res[126] = fma52lo(res[126], a[62], a[64]); // Sum(126) + res[127] = fma52hi(res[127], a[62], a[64]); // Sum(126) + res[127] = fma52lo(res[127], a[63], a[64]); // Sum(127) + res[128] = fma52hi(res[128], a[63], a[64]); // Sum(127) + res[120] = fma52lo(res[120], a[55], a[65]); // Sum(120) + res[121] = fma52hi(res[121], a[55], a[65]); // Sum(120) + res[121] = fma52lo(res[121], a[56], a[65]); // Sum(121) + res[122] = fma52hi(res[122], a[56], a[65]); // Sum(121) + res[122] = fma52lo(res[122], a[57], a[65]); // Sum(122) + res[123] = fma52hi(res[123], a[57], a[65]); // Sum(122) + res[123] = fma52lo(res[123], a[58], a[65]); // Sum(123) + res[124] = fma52hi(res[124], a[58], a[65]); // Sum(123) + res[124] = fma52lo(res[124], a[59], a[65]); // Sum(124) + res[125] = fma52hi(res[125], a[59], a[65]); // Sum(124) + res[125] = fma52lo(res[125], a[60], a[65]); // Sum(125) + res[126] = fma52hi(res[126], a[60], a[65]); // Sum(125) + res[126] = fma52lo(res[126], a[61], a[65]); // Sum(126) + res[127] = fma52hi(res[127], a[61], a[65]); // Sum(126) + res[127] = fma52lo(res[127], a[62], a[65]); // Sum(127) + res[128] = fma52hi(res[128], a[62], a[65]); // Sum(127) + res[128] = fma52lo(res[128], a[63], a[65]); // Sum(128) + res[129] = fma52hi(res[129], a[63], a[65]); // Sum(128) + res[129] = fma52lo(res[129], a[64], a[65]); // Sum(129) + res[130] = fma52hi(res[130], a[64], a[65]); // Sum(129) + res[120] = fma52lo(res[120], a[54], a[66]); // Sum(120) + res[121] = fma52hi(res[121], a[54], a[66]); // Sum(120) + res[121] = fma52lo(res[121], a[55], a[66]); // Sum(121) + res[122] = fma52hi(res[122], a[55], a[66]); // Sum(121) + res[122] = fma52lo(res[122], a[56], a[66]); // Sum(122) + res[123] = fma52hi(res[123], a[56], a[66]); // Sum(122) + res[123] = fma52lo(res[123], a[57], a[66]); // Sum(123) + res[124] = fma52hi(res[124], a[57], a[66]); // Sum(123) + res[124] = fma52lo(res[124], a[58], a[66]); // Sum(124) + res[125] = fma52hi(res[125], a[58], a[66]); // Sum(124) + res[125] = fma52lo(res[125], a[59], a[66]); // Sum(125) + res[126] = fma52hi(res[126], a[59], a[66]); // Sum(125) + res[126] = fma52lo(res[126], a[60], a[66]); // Sum(126) + res[127] = fma52hi(res[127], a[60], a[66]); // Sum(126) + res[127] = fma52lo(res[127], a[61], a[66]); // Sum(127) + res[128] = fma52hi(res[128], a[61], a[66]); // Sum(127) + res[128] = fma52lo(res[128], a[62], a[66]); // Sum(128) + res[129] = fma52hi(res[129], a[62], a[66]); // Sum(128) + res[129] = fma52lo(res[129], a[63], a[66]); // Sum(129) + res[130] = fma52hi(res[130], a[63], a[66]); // Sum(129) + res[130] = fma52lo(res[130], a[64], a[66]); // Sum(130) + res[131] = fma52hi(res[131], a[64], a[66]); // Sum(130) + res[131] = fma52lo(res[131], a[65], a[66]); // Sum(131) + res[132] = fma52hi(res[132], a[65], a[66]); // Sum(131) + res[120] = fma52lo(res[120], a[53], a[67]); // Sum(120) + res[121] = fma52hi(res[121], a[53], a[67]); // Sum(120) + res[121] = fma52lo(res[121], a[54], a[67]); // Sum(121) + res[122] = fma52hi(res[122], a[54], a[67]); // Sum(121) + res[122] = fma52lo(res[122], a[55], a[67]); // Sum(122) + res[123] = fma52hi(res[123], a[55], a[67]); // Sum(122) + res[123] = fma52lo(res[123], a[56], a[67]); // Sum(123) + res[124] = fma52hi(res[124], a[56], a[67]); // Sum(123) + res[124] = fma52lo(res[124], a[57], a[67]); // Sum(124) + res[125] = fma52hi(res[125], a[57], a[67]); // Sum(124) + res[125] = fma52lo(res[125], a[58], a[67]); // Sum(125) + res[126] = fma52hi(res[126], a[58], a[67]); // Sum(125) + res[126] = fma52lo(res[126], a[59], a[67]); // Sum(126) + res[127] = fma52hi(res[127], a[59], a[67]); // Sum(126) + res[127] = fma52lo(res[127], a[60], a[67]); // Sum(127) + res[128] = fma52hi(res[128], a[60], a[67]); // Sum(127) + res[128] = fma52lo(res[128], a[61], a[67]); // Sum(128) + res[129] = fma52hi(res[129], a[61], a[67]); // Sum(128) + res[129] = fma52lo(res[129], a[62], a[67]); // Sum(129) + res[130] = fma52hi(res[130], a[62], a[67]); // Sum(129) + res[130] = fma52lo(res[130], a[63], a[67]); // Sum(130) + res[131] = fma52hi(res[131], a[63], a[67]); // Sum(130) + res[131] = fma52lo(res[131], a[64], a[67]); // Sum(131) + res[132] = fma52hi(res[132], a[64], a[67]); // Sum(131) + res[120] = fma52lo(res[120], a[52], a[68]); // Sum(120) + res[121] = fma52hi(res[121], a[52], a[68]); // Sum(120) + res[121] = fma52lo(res[121], a[53], a[68]); // Sum(121) + res[122] = fma52hi(res[122], a[53], a[68]); // Sum(121) + res[122] = fma52lo(res[122], a[54], a[68]); // Sum(122) + res[123] = fma52hi(res[123], a[54], a[68]); // Sum(122) + res[123] = fma52lo(res[123], a[55], a[68]); // Sum(123) + res[124] = fma52hi(res[124], a[55], a[68]); // Sum(123) + res[124] = fma52lo(res[124], a[56], a[68]); // Sum(124) + res[125] = fma52hi(res[125], a[56], a[68]); // Sum(124) + res[125] = fma52lo(res[125], a[57], a[68]); // Sum(125) + res[126] = fma52hi(res[126], a[57], a[68]); // Sum(125) + res[126] = fma52lo(res[126], a[58], a[68]); // Sum(126) + res[127] = fma52hi(res[127], a[58], a[68]); // Sum(126) + res[127] = fma52lo(res[127], a[59], a[68]); // Sum(127) + res[128] = fma52hi(res[128], a[59], a[68]); // Sum(127) + res[128] = fma52lo(res[128], a[60], a[68]); // Sum(128) + res[129] = fma52hi(res[129], a[60], a[68]); // Sum(128) + res[129] = fma52lo(res[129], a[61], a[68]); // Sum(129) + res[130] = fma52hi(res[130], a[61], a[68]); // Sum(129) + res[130] = fma52lo(res[130], a[62], a[68]); // Sum(130) + res[131] = fma52hi(res[131], a[62], a[68]); // Sum(130) + res[131] = fma52lo(res[131], a[63], a[68]); // Sum(131) + res[132] = fma52hi(res[132], a[63], a[68]); // Sum(131) + res[120] = fma52lo(res[120], a[51], a[69]); // Sum(120) + res[121] = fma52hi(res[121], a[51], a[69]); // Sum(120) + res[121] = fma52lo(res[121], a[52], a[69]); // Sum(121) + res[122] = fma52hi(res[122], a[52], a[69]); // Sum(121) + res[122] = fma52lo(res[122], a[53], a[69]); // Sum(122) + res[123] = fma52hi(res[123], a[53], a[69]); // Sum(122) + res[123] = fma52lo(res[123], a[54], a[69]); // Sum(123) + res[124] = fma52hi(res[124], a[54], a[69]); // Sum(123) + res[124] = fma52lo(res[124], a[55], a[69]); // Sum(124) + res[125] = fma52hi(res[125], a[55], a[69]); // Sum(124) + res[125] = fma52lo(res[125], a[56], a[69]); // Sum(125) + res[126] = fma52hi(res[126], a[56], a[69]); // Sum(125) + res[126] = fma52lo(res[126], a[57], a[69]); // Sum(126) + res[127] = fma52hi(res[127], a[57], a[69]); // Sum(126) + res[127] = fma52lo(res[127], a[58], a[69]); // Sum(127) + res[128] = fma52hi(res[128], a[58], a[69]); // Sum(127) + res[128] = fma52lo(res[128], a[59], a[69]); // Sum(128) + res[129] = fma52hi(res[129], a[59], a[69]); // Sum(128) + res[129] = fma52lo(res[129], a[60], a[69]); // Sum(129) + res[130] = fma52hi(res[130], a[60], a[69]); // Sum(129) + res[130] = fma52lo(res[130], a[61], a[69]); // Sum(130) + res[131] = fma52hi(res[131], a[61], a[69]); // Sum(130) + res[131] = fma52lo(res[131], a[62], a[69]); // Sum(131) + res[132] = fma52hi(res[132], a[62], a[69]); // Sum(131) + res[120] = fma52lo(res[120], a[50], a[70]); // Sum(120) + res[121] = fma52hi(res[121], a[50], a[70]); // Sum(120) + res[121] = fma52lo(res[121], a[51], a[70]); // Sum(121) + res[122] = fma52hi(res[122], a[51], a[70]); // Sum(121) + res[122] = fma52lo(res[122], a[52], a[70]); // Sum(122) + res[123] = fma52hi(res[123], a[52], a[70]); // Sum(122) + res[123] = fma52lo(res[123], a[53], a[70]); // Sum(123) + res[124] = fma52hi(res[124], a[53], a[70]); // Sum(123) + res[124] = fma52lo(res[124], a[54], a[70]); // Sum(124) + res[125] = fma52hi(res[125], a[54], a[70]); // Sum(124) + res[125] = fma52lo(res[125], a[55], a[70]); // Sum(125) + res[126] = fma52hi(res[126], a[55], a[70]); // Sum(125) + res[126] = fma52lo(res[126], a[56], a[70]); // Sum(126) + res[127] = fma52hi(res[127], a[56], a[70]); // Sum(126) + res[127] = fma52lo(res[127], a[57], a[70]); // Sum(127) + res[128] = fma52hi(res[128], a[57], a[70]); // Sum(127) + res[128] = fma52lo(res[128], a[58], a[70]); // Sum(128) + res[129] = fma52hi(res[129], a[58], a[70]); // Sum(128) + res[129] = fma52lo(res[129], a[59], a[70]); // Sum(129) + res[130] = fma52hi(res[130], a[59], a[70]); // Sum(129) + res[130] = fma52lo(res[130], a[60], a[70]); // Sum(130) + res[131] = fma52hi(res[131], a[60], a[70]); // Sum(130) + res[131] = fma52lo(res[131], a[61], a[70]); // Sum(131) + res[132] = fma52hi(res[132], a[61], a[70]); // Sum(131) + res[120] = fma52lo(res[120], a[49], a[71]); // Sum(120) + res[121] = fma52hi(res[121], a[49], a[71]); // Sum(120) + res[121] = fma52lo(res[121], a[50], a[71]); // Sum(121) + res[122] = fma52hi(res[122], a[50], a[71]); // Sum(121) + res[122] = fma52lo(res[122], a[51], a[71]); // Sum(122) + res[123] = fma52hi(res[123], a[51], a[71]); // Sum(122) + res[123] = fma52lo(res[123], a[52], a[71]); // Sum(123) + res[124] = fma52hi(res[124], a[52], a[71]); // Sum(123) + res[124] = fma52lo(res[124], a[53], a[71]); // Sum(124) + res[125] = fma52hi(res[125], a[53], a[71]); // Sum(124) + res[125] = fma52lo(res[125], a[54], a[71]); // Sum(125) + res[126] = fma52hi(res[126], a[54], a[71]); // Sum(125) + res[126] = fma52lo(res[126], a[55], a[71]); // Sum(126) + res[127] = fma52hi(res[127], a[55], a[71]); // Sum(126) + res[127] = fma52lo(res[127], a[56], a[71]); // Sum(127) + res[128] = fma52hi(res[128], a[56], a[71]); // Sum(127) + res[128] = fma52lo(res[128], a[57], a[71]); // Sum(128) + res[129] = fma52hi(res[129], a[57], a[71]); // Sum(128) + res[129] = fma52lo(res[129], a[58], a[71]); // Sum(129) + res[130] = fma52hi(res[130], a[58], a[71]); // Sum(129) + res[130] = fma52lo(res[130], a[59], a[71]); // Sum(130) + res[131] = fma52hi(res[131], a[59], a[71]); // Sum(130) + res[131] = fma52lo(res[131], a[60], a[71]); // Sum(131) + res[132] = fma52hi(res[132], a[60], a[71]); // Sum(131) + res[120] = fma52lo(res[120], a[48], a[72]); // Sum(120) + res[121] = fma52hi(res[121], a[48], a[72]); // Sum(120) + res[121] = fma52lo(res[121], a[49], a[72]); // Sum(121) + res[122] = fma52hi(res[122], a[49], a[72]); // Sum(121) + res[122] = fma52lo(res[122], a[50], a[72]); // Sum(122) + res[123] = fma52hi(res[123], a[50], a[72]); // Sum(122) + res[123] = fma52lo(res[123], a[51], a[72]); // Sum(123) + res[124] = fma52hi(res[124], a[51], a[72]); // Sum(123) + res[124] = fma52lo(res[124], a[52], a[72]); // Sum(124) + res[125] = fma52hi(res[125], a[52], a[72]); // Sum(124) + res[125] = fma52lo(res[125], a[53], a[72]); // Sum(125) + res[126] = fma52hi(res[126], a[53], a[72]); // Sum(125) + res[126] = fma52lo(res[126], a[54], a[72]); // Sum(126) + res[127] = fma52hi(res[127], a[54], a[72]); // Sum(126) + res[127] = fma52lo(res[127], a[55], a[72]); // Sum(127) + res[128] = fma52hi(res[128], a[55], a[72]); // Sum(127) + res[128] = fma52lo(res[128], a[56], a[72]); // Sum(128) + res[129] = fma52hi(res[129], a[56], a[72]); // Sum(128) + res[129] = fma52lo(res[129], a[57], a[72]); // Sum(129) + res[130] = fma52hi(res[130], a[57], a[72]); // Sum(129) + res[130] = fma52lo(res[130], a[58], a[72]); // Sum(130) + res[131] = fma52hi(res[131], a[58], a[72]); // Sum(130) + res[131] = fma52lo(res[131], a[59], a[72]); // Sum(131) + res[132] = fma52hi(res[132], a[59], a[72]); // Sum(131) + res[120] = fma52lo(res[120], a[47], a[73]); // Sum(120) + res[121] = fma52hi(res[121], a[47], a[73]); // Sum(120) + res[121] = fma52lo(res[121], a[48], a[73]); // Sum(121) + res[122] = fma52hi(res[122], a[48], a[73]); // Sum(121) + res[122] = fma52lo(res[122], a[49], a[73]); // Sum(122) + res[123] = fma52hi(res[123], a[49], a[73]); // Sum(122) + res[123] = fma52lo(res[123], a[50], a[73]); // Sum(123) + res[124] = fma52hi(res[124], a[50], a[73]); // Sum(123) + res[124] = fma52lo(res[124], a[51], a[73]); // Sum(124) + res[125] = fma52hi(res[125], a[51], a[73]); // Sum(124) + res[125] = fma52lo(res[125], a[52], a[73]); // Sum(125) + res[126] = fma52hi(res[126], a[52], a[73]); // Sum(125) + res[126] = fma52lo(res[126], a[53], a[73]); // Sum(126) + res[127] = fma52hi(res[127], a[53], a[73]); // Sum(126) + res[127] = fma52lo(res[127], a[54], a[73]); // Sum(127) + res[128] = fma52hi(res[128], a[54], a[73]); // Sum(127) + res[128] = fma52lo(res[128], a[55], a[73]); // Sum(128) + res[129] = fma52hi(res[129], a[55], a[73]); // Sum(128) + res[129] = fma52lo(res[129], a[56], a[73]); // Sum(129) + res[130] = fma52hi(res[130], a[56], a[73]); // Sum(129) + res[130] = fma52lo(res[130], a[57], a[73]); // Sum(130) + res[131] = fma52hi(res[131], a[57], a[73]); // Sum(130) + res[131] = fma52lo(res[131], a[58], a[73]); // Sum(131) + res[132] = fma52hi(res[132], a[58], a[73]); // Sum(131) + res[120] = fma52lo(res[120], a[46], a[74]); // Sum(120) + res[121] = fma52hi(res[121], a[46], a[74]); // Sum(120) + res[121] = fma52lo(res[121], a[47], a[74]); // Sum(121) + res[122] = fma52hi(res[122], a[47], a[74]); // Sum(121) + res[122] = fma52lo(res[122], a[48], a[74]); // Sum(122) + res[123] = fma52hi(res[123], a[48], a[74]); // Sum(122) + res[123] = fma52lo(res[123], a[49], a[74]); // Sum(123) + res[124] = fma52hi(res[124], a[49], a[74]); // Sum(123) + res[124] = fma52lo(res[124], a[50], a[74]); // Sum(124) + res[125] = fma52hi(res[125], a[50], a[74]); // Sum(124) + res[125] = fma52lo(res[125], a[51], a[74]); // Sum(125) + res[126] = fma52hi(res[126], a[51], a[74]); // Sum(125) + res[126] = fma52lo(res[126], a[52], a[74]); // Sum(126) + res[127] = fma52hi(res[127], a[52], a[74]); // Sum(126) + res[127] = fma52lo(res[127], a[53], a[74]); // Sum(127) + res[128] = fma52hi(res[128], a[53], a[74]); // Sum(127) + res[128] = fma52lo(res[128], a[54], a[74]); // Sum(128) + res[129] = fma52hi(res[129], a[54], a[74]); // Sum(128) + res[129] = fma52lo(res[129], a[55], a[74]); // Sum(129) + res[130] = fma52hi(res[130], a[55], a[74]); // Sum(129) + res[130] = fma52lo(res[130], a[56], a[74]); // Sum(130) + res[131] = fma52hi(res[131], a[56], a[74]); // Sum(130) + res[131] = fma52lo(res[131], a[57], a[74]); // Sum(131) + res[132] = fma52hi(res[132], a[57], a[74]); // Sum(131) + res[120] = fma52lo(res[120], a[45], a[75]); // Sum(120) + res[121] = fma52hi(res[121], a[45], a[75]); // Sum(120) + res[121] = fma52lo(res[121], a[46], a[75]); // Sum(121) + res[122] = fma52hi(res[122], a[46], a[75]); // Sum(121) + res[122] = fma52lo(res[122], a[47], a[75]); // Sum(122) + res[123] = fma52hi(res[123], a[47], a[75]); // Sum(122) + res[123] = fma52lo(res[123], a[48], a[75]); // Sum(123) + res[124] = fma52hi(res[124], a[48], a[75]); // Sum(123) + res[124] = fma52lo(res[124], a[49], a[75]); // Sum(124) + res[125] = fma52hi(res[125], a[49], a[75]); // Sum(124) + res[125] = fma52lo(res[125], a[50], a[75]); // Sum(125) + res[126] = fma52hi(res[126], a[50], a[75]); // Sum(125) + res[126] = fma52lo(res[126], a[51], a[75]); // Sum(126) + res[127] = fma52hi(res[127], a[51], a[75]); // Sum(126) + res[127] = fma52lo(res[127], a[52], a[75]); // Sum(127) + res[128] = fma52hi(res[128], a[52], a[75]); // Sum(127) + res[128] = fma52lo(res[128], a[53], a[75]); // Sum(128) + res[129] = fma52hi(res[129], a[53], a[75]); // Sum(128) + res[129] = fma52lo(res[129], a[54], a[75]); // Sum(129) + res[130] = fma52hi(res[130], a[54], a[75]); // Sum(129) + res[130] = fma52lo(res[130], a[55], a[75]); // Sum(130) + res[131] = fma52hi(res[131], a[55], a[75]); // Sum(130) + res[131] = fma52lo(res[131], a[56], a[75]); // Sum(131) + res[132] = fma52hi(res[132], a[56], a[75]); // Sum(131) + res[120] = fma52lo(res[120], a[44], a[76]); // Sum(120) + res[121] = fma52hi(res[121], a[44], a[76]); // Sum(120) + res[121] = fma52lo(res[121], a[45], a[76]); // Sum(121) + res[122] = fma52hi(res[122], a[45], a[76]); // Sum(121) + res[122] = fma52lo(res[122], a[46], a[76]); // Sum(122) + res[123] = fma52hi(res[123], a[46], a[76]); // Sum(122) + res[123] = fma52lo(res[123], a[47], a[76]); // Sum(123) + res[124] = fma52hi(res[124], a[47], a[76]); // Sum(123) + res[124] = fma52lo(res[124], a[48], a[76]); // Sum(124) + res[125] = fma52hi(res[125], a[48], a[76]); // Sum(124) + res[125] = fma52lo(res[125], a[49], a[76]); // Sum(125) + res[126] = fma52hi(res[126], a[49], a[76]); // Sum(125) + res[126] = fma52lo(res[126], a[50], a[76]); // Sum(126) + res[127] = fma52hi(res[127], a[50], a[76]); // Sum(126) + res[127] = fma52lo(res[127], a[51], a[76]); // Sum(127) + res[128] = fma52hi(res[128], a[51], a[76]); // Sum(127) + res[128] = fma52lo(res[128], a[52], a[76]); // Sum(128) + res[129] = fma52hi(res[129], a[52], a[76]); // Sum(128) + res[129] = fma52lo(res[129], a[53], a[76]); // Sum(129) + res[130] = fma52hi(res[130], a[53], a[76]); // Sum(129) + res[130] = fma52lo(res[130], a[54], a[76]); // Sum(130) + res[131] = fma52hi(res[131], a[54], a[76]); // Sum(130) + res[131] = fma52lo(res[131], a[55], a[76]); // Sum(131) + res[132] = fma52hi(res[132], a[55], a[76]); // Sum(131) + res[120] = fma52lo(res[120], a[43], a[77]); // Sum(120) + res[121] = fma52hi(res[121], a[43], a[77]); // Sum(120) + res[121] = fma52lo(res[121], a[44], a[77]); // Sum(121) + res[122] = fma52hi(res[122], a[44], a[77]); // Sum(121) + res[122] = fma52lo(res[122], a[45], a[77]); // Sum(122) + res[123] = fma52hi(res[123], a[45], a[77]); // Sum(122) + res[123] = fma52lo(res[123], a[46], a[77]); // Sum(123) + res[124] = fma52hi(res[124], a[46], a[77]); // Sum(123) + res[124] = fma52lo(res[124], a[47], a[77]); // Sum(124) + res[125] = fma52hi(res[125], a[47], a[77]); // Sum(124) + res[125] = fma52lo(res[125], a[48], a[77]); // Sum(125) + res[126] = fma52hi(res[126], a[48], a[77]); // Sum(125) + res[126] = fma52lo(res[126], a[49], a[77]); // Sum(126) + res[127] = fma52hi(res[127], a[49], a[77]); // Sum(126) + res[127] = fma52lo(res[127], a[50], a[77]); // Sum(127) + res[128] = fma52hi(res[128], a[50], a[77]); // Sum(127) + res[128] = fma52lo(res[128], a[51], a[77]); // Sum(128) + res[129] = fma52hi(res[129], a[51], a[77]); // Sum(128) + res[129] = fma52lo(res[129], a[52], a[77]); // Sum(129) + res[130] = fma52hi(res[130], a[52], a[77]); // Sum(129) + res[130] = fma52lo(res[130], a[53], a[77]); // Sum(130) + res[131] = fma52hi(res[131], a[53], a[77]); // Sum(130) + res[131] = fma52lo(res[131], a[54], a[77]); // Sum(131) + res[132] = fma52hi(res[132], a[54], a[77]); // Sum(131) + res[120] = fma52lo(res[120], a[42], a[78]); // Sum(120) + res[121] = fma52hi(res[121], a[42], a[78]); // Sum(120) + res[121] = fma52lo(res[121], a[43], a[78]); // Sum(121) + res[122] = fma52hi(res[122], a[43], a[78]); // Sum(121) + res[122] = fma52lo(res[122], a[44], a[78]); // Sum(122) + res[123] = fma52hi(res[123], a[44], a[78]); // Sum(122) + res[123] = fma52lo(res[123], a[45], a[78]); // Sum(123) + res[124] = fma52hi(res[124], a[45], a[78]); // Sum(123) + res[124] = fma52lo(res[124], a[46], a[78]); // Sum(124) + res[125] = fma52hi(res[125], a[46], a[78]); // Sum(124) + res[125] = fma52lo(res[125], a[47], a[78]); // Sum(125) + res[126] = fma52hi(res[126], a[47], a[78]); // Sum(125) + res[126] = fma52lo(res[126], a[48], a[78]); // Sum(126) + res[127] = fma52hi(res[127], a[48], a[78]); // Sum(126) + res[127] = fma52lo(res[127], a[49], a[78]); // Sum(127) + res[128] = fma52hi(res[128], a[49], a[78]); // Sum(127) + res[128] = fma52lo(res[128], a[50], a[78]); // Sum(128) + res[129] = fma52hi(res[129], a[50], a[78]); // Sum(128) + res[129] = fma52lo(res[129], a[51], a[78]); // Sum(129) + res[130] = fma52hi(res[130], a[51], a[78]); // Sum(129) + res[130] = fma52lo(res[130], a[52], a[78]); // Sum(130) + res[131] = fma52hi(res[131], a[52], a[78]); // Sum(130) + res[131] = fma52lo(res[131], a[53], a[78]); // Sum(131) + res[132] = fma52hi(res[132], a[53], a[78]); // Sum(131) + res[120] = add64(res[120], res[120]); // Double(120) + res[121] = add64(res[121], res[121]); // Double(121) + res[122] = add64(res[122], res[122]); // Double(122) + res[123] = add64(res[123], res[123]); // Double(123) + res[124] = add64(res[124], res[124]); // Double(124) + res[125] = add64(res[125], res[125]); // Double(125) + res[126] = add64(res[126], res[126]); // Double(126) + res[127] = add64(res[127], res[127]); // Double(127) + res[128] = add64(res[128], res[128]); // Double(128) + res[129] = add64(res[129], res[129]); // Double(129) + res[130] = add64(res[130], res[130]); // Double(130) + res[131] = add64(res[131], res[131]); // Double(131) + res[120] = fma52lo(res[120], a[60], a[60]); // Add sqr(120) + res[121] = fma52hi(res[121], a[60], a[60]); // Add sqr(120) + res[122] = fma52lo(res[122], a[61], a[61]); // Add sqr(122) + res[123] = fma52hi(res[123], a[61], a[61]); // Add sqr(122) + res[124] = fma52lo(res[124], a[62], a[62]); // Add sqr(124) + res[125] = fma52hi(res[125], a[62], a[62]); // Add sqr(124) + res[126] = fma52lo(res[126], a[63], a[63]); // Add sqr(126) + res[127] = fma52hi(res[127], a[63], a[63]); // Add sqr(126) + res[128] = fma52lo(res[128], a[64], a[64]); // Add sqr(128) + res[129] = fma52hi(res[129], a[64], a[64]); // Add sqr(128) + res[130] = fma52lo(res[130], a[65], a[65]); // Add sqr(130) + res[131] = fma52hi(res[131], a[65], a[65]); // Add sqr(130) + res[132] = fma52lo(res[132], a[65], a[67]); // Sum(132) + res[133] = fma52hi(res[133], a[65], a[67]); // Sum(132) + res[133] = fma52lo(res[133], a[66], a[67]); // Sum(133) + res[134] = fma52hi(res[134], a[66], a[67]); // Sum(133) + res[132] = fma52lo(res[132], a[64], a[68]); // Sum(132) + res[133] = fma52hi(res[133], a[64], a[68]); // Sum(132) + res[133] = fma52lo(res[133], a[65], a[68]); // Sum(133) + res[134] = fma52hi(res[134], a[65], a[68]); // Sum(133) + res[134] = fma52lo(res[134], a[66], a[68]); // Sum(134) + res[135] = fma52hi(res[135], a[66], a[68]); // Sum(134) + res[135] = fma52lo(res[135], a[67], a[68]); // Sum(135) + res[136] = fma52hi(res[136], a[67], a[68]); // Sum(135) + res[132] = fma52lo(res[132], a[63], a[69]); // Sum(132) + res[133] = fma52hi(res[133], a[63], a[69]); // Sum(132) + res[133] = fma52lo(res[133], a[64], a[69]); // Sum(133) + res[134] = fma52hi(res[134], a[64], a[69]); // Sum(133) + res[134] = fma52lo(res[134], a[65], a[69]); // Sum(134) + res[135] = fma52hi(res[135], a[65], a[69]); // Sum(134) + res[135] = fma52lo(res[135], a[66], a[69]); // Sum(135) + res[136] = fma52hi(res[136], a[66], a[69]); // Sum(135) + res[136] = fma52lo(res[136], a[67], a[69]); // Sum(136) + res[137] = fma52hi(res[137], a[67], a[69]); // Sum(136) + res[137] = fma52lo(res[137], a[68], a[69]); // Sum(137) + res[138] = fma52hi(res[138], a[68], a[69]); // Sum(137) + res[132] = fma52lo(res[132], a[62], a[70]); // Sum(132) + res[133] = fma52hi(res[133], a[62], a[70]); // Sum(132) + res[133] = fma52lo(res[133], a[63], a[70]); // Sum(133) + res[134] = fma52hi(res[134], a[63], a[70]); // Sum(133) + res[134] = fma52lo(res[134], a[64], a[70]); // Sum(134) + res[135] = fma52hi(res[135], a[64], a[70]); // Sum(134) + res[135] = fma52lo(res[135], a[65], a[70]); // Sum(135) + res[136] = fma52hi(res[136], a[65], a[70]); // Sum(135) + res[136] = fma52lo(res[136], a[66], a[70]); // Sum(136) + res[137] = fma52hi(res[137], a[66], a[70]); // Sum(136) + res[137] = fma52lo(res[137], a[67], a[70]); // Sum(137) + res[138] = fma52hi(res[138], a[67], a[70]); // Sum(137) + res[138] = fma52lo(res[138], a[68], a[70]); // Sum(138) + res[139] = fma52hi(res[139], a[68], a[70]); // Sum(138) + res[139] = fma52lo(res[139], a[69], a[70]); // Sum(139) + res[140] = fma52hi(res[140], a[69], a[70]); // Sum(139) + res[132] = fma52lo(res[132], a[61], a[71]); // Sum(132) + res[133] = fma52hi(res[133], a[61], a[71]); // Sum(132) + res[133] = fma52lo(res[133], a[62], a[71]); // Sum(133) + res[134] = fma52hi(res[134], a[62], a[71]); // Sum(133) + res[134] = fma52lo(res[134], a[63], a[71]); // Sum(134) + res[135] = fma52hi(res[135], a[63], a[71]); // Sum(134) + res[135] = fma52lo(res[135], a[64], a[71]); // Sum(135) + res[136] = fma52hi(res[136], a[64], a[71]); // Sum(135) + res[136] = fma52lo(res[136], a[65], a[71]); // Sum(136) + res[137] = fma52hi(res[137], a[65], a[71]); // Sum(136) + res[137] = fma52lo(res[137], a[66], a[71]); // Sum(137) + res[138] = fma52hi(res[138], a[66], a[71]); // Sum(137) + res[138] = fma52lo(res[138], a[67], a[71]); // Sum(138) + res[139] = fma52hi(res[139], a[67], a[71]); // Sum(138) + res[139] = fma52lo(res[139], a[68], a[71]); // Sum(139) + res[140] = fma52hi(res[140], a[68], a[71]); // Sum(139) + res[140] = fma52lo(res[140], a[69], a[71]); // Sum(140) + res[141] = fma52hi(res[141], a[69], a[71]); // Sum(140) + res[141] = fma52lo(res[141], a[70], a[71]); // Sum(141) + res[142] = fma52hi(res[142], a[70], a[71]); // Sum(141) + res[132] = fma52lo(res[132], a[60], a[72]); // Sum(132) + res[133] = fma52hi(res[133], a[60], a[72]); // Sum(132) + res[133] = fma52lo(res[133], a[61], a[72]); // Sum(133) + res[134] = fma52hi(res[134], a[61], a[72]); // Sum(133) + res[134] = fma52lo(res[134], a[62], a[72]); // Sum(134) + res[135] = fma52hi(res[135], a[62], a[72]); // Sum(134) + res[135] = fma52lo(res[135], a[63], a[72]); // Sum(135) + res[136] = fma52hi(res[136], a[63], a[72]); // Sum(135) + res[136] = fma52lo(res[136], a[64], a[72]); // Sum(136) + res[137] = fma52hi(res[137], a[64], a[72]); // Sum(136) + res[137] = fma52lo(res[137], a[65], a[72]); // Sum(137) + res[138] = fma52hi(res[138], a[65], a[72]); // Sum(137) + res[138] = fma52lo(res[138], a[66], a[72]); // Sum(138) + res[139] = fma52hi(res[139], a[66], a[72]); // Sum(138) + res[139] = fma52lo(res[139], a[67], a[72]); // Sum(139) + res[140] = fma52hi(res[140], a[67], a[72]); // Sum(139) + res[140] = fma52lo(res[140], a[68], a[72]); // Sum(140) + res[141] = fma52hi(res[141], a[68], a[72]); // Sum(140) + res[141] = fma52lo(res[141], a[69], a[72]); // Sum(141) + res[142] = fma52hi(res[142], a[69], a[72]); // Sum(141) + res[142] = fma52lo(res[142], a[70], a[72]); // Sum(142) + res[143] = fma52hi(res[143], a[70], a[72]); // Sum(142) + res[143] = fma52lo(res[143], a[71], a[72]); // Sum(143) + res[144] = fma52hi(res[144], a[71], a[72]); // Sum(143) + res[132] = fma52lo(res[132], a[59], a[73]); // Sum(132) + res[133] = fma52hi(res[133], a[59], a[73]); // Sum(132) + res[133] = fma52lo(res[133], a[60], a[73]); // Sum(133) + res[134] = fma52hi(res[134], a[60], a[73]); // Sum(133) + res[134] = fma52lo(res[134], a[61], a[73]); // Sum(134) + res[135] = fma52hi(res[135], a[61], a[73]); // Sum(134) + res[135] = fma52lo(res[135], a[62], a[73]); // Sum(135) + res[136] = fma52hi(res[136], a[62], a[73]); // Sum(135) + res[136] = fma52lo(res[136], a[63], a[73]); // Sum(136) + res[137] = fma52hi(res[137], a[63], a[73]); // Sum(136) + res[137] = fma52lo(res[137], a[64], a[73]); // Sum(137) + res[138] = fma52hi(res[138], a[64], a[73]); // Sum(137) + res[138] = fma52lo(res[138], a[65], a[73]); // Sum(138) + res[139] = fma52hi(res[139], a[65], a[73]); // Sum(138) + res[139] = fma52lo(res[139], a[66], a[73]); // Sum(139) + res[140] = fma52hi(res[140], a[66], a[73]); // Sum(139) + res[140] = fma52lo(res[140], a[67], a[73]); // Sum(140) + res[141] = fma52hi(res[141], a[67], a[73]); // Sum(140) + res[141] = fma52lo(res[141], a[68], a[73]); // Sum(141) + res[142] = fma52hi(res[142], a[68], a[73]); // Sum(141) + res[142] = fma52lo(res[142], a[69], a[73]); // Sum(142) + res[143] = fma52hi(res[143], a[69], a[73]); // Sum(142) + res[143] = fma52lo(res[143], a[70], a[73]); // Sum(143) + res[144] = fma52hi(res[144], a[70], a[73]); // Sum(143) + res[132] = fma52lo(res[132], a[58], a[74]); // Sum(132) + res[133] = fma52hi(res[133], a[58], a[74]); // Sum(132) + res[133] = fma52lo(res[133], a[59], a[74]); // Sum(133) + res[134] = fma52hi(res[134], a[59], a[74]); // Sum(133) + res[134] = fma52lo(res[134], a[60], a[74]); // Sum(134) + res[135] = fma52hi(res[135], a[60], a[74]); // Sum(134) + res[135] = fma52lo(res[135], a[61], a[74]); // Sum(135) + res[136] = fma52hi(res[136], a[61], a[74]); // Sum(135) + res[136] = fma52lo(res[136], a[62], a[74]); // Sum(136) + res[137] = fma52hi(res[137], a[62], a[74]); // Sum(136) + res[137] = fma52lo(res[137], a[63], a[74]); // Sum(137) + res[138] = fma52hi(res[138], a[63], a[74]); // Sum(137) + res[138] = fma52lo(res[138], a[64], a[74]); // Sum(138) + res[139] = fma52hi(res[139], a[64], a[74]); // Sum(138) + res[139] = fma52lo(res[139], a[65], a[74]); // Sum(139) + res[140] = fma52hi(res[140], a[65], a[74]); // Sum(139) + res[140] = fma52lo(res[140], a[66], a[74]); // Sum(140) + res[141] = fma52hi(res[141], a[66], a[74]); // Sum(140) + res[141] = fma52lo(res[141], a[67], a[74]); // Sum(141) + res[142] = fma52hi(res[142], a[67], a[74]); // Sum(141) + res[142] = fma52lo(res[142], a[68], a[74]); // Sum(142) + res[143] = fma52hi(res[143], a[68], a[74]); // Sum(142) + res[143] = fma52lo(res[143], a[69], a[74]); // Sum(143) + res[144] = fma52hi(res[144], a[69], a[74]); // Sum(143) + res[132] = fma52lo(res[132], a[57], a[75]); // Sum(132) + res[133] = fma52hi(res[133], a[57], a[75]); // Sum(132) + res[133] = fma52lo(res[133], a[58], a[75]); // Sum(133) + res[134] = fma52hi(res[134], a[58], a[75]); // Sum(133) + res[134] = fma52lo(res[134], a[59], a[75]); // Sum(134) + res[135] = fma52hi(res[135], a[59], a[75]); // Sum(134) + res[135] = fma52lo(res[135], a[60], a[75]); // Sum(135) + res[136] = fma52hi(res[136], a[60], a[75]); // Sum(135) + res[136] = fma52lo(res[136], a[61], a[75]); // Sum(136) + res[137] = fma52hi(res[137], a[61], a[75]); // Sum(136) + res[137] = fma52lo(res[137], a[62], a[75]); // Sum(137) + res[138] = fma52hi(res[138], a[62], a[75]); // Sum(137) + res[138] = fma52lo(res[138], a[63], a[75]); // Sum(138) + res[139] = fma52hi(res[139], a[63], a[75]); // Sum(138) + res[139] = fma52lo(res[139], a[64], a[75]); // Sum(139) + res[140] = fma52hi(res[140], a[64], a[75]); // Sum(139) + res[140] = fma52lo(res[140], a[65], a[75]); // Sum(140) + res[141] = fma52hi(res[141], a[65], a[75]); // Sum(140) + res[141] = fma52lo(res[141], a[66], a[75]); // Sum(141) + res[142] = fma52hi(res[142], a[66], a[75]); // Sum(141) + res[142] = fma52lo(res[142], a[67], a[75]); // Sum(142) + res[143] = fma52hi(res[143], a[67], a[75]); // Sum(142) + res[143] = fma52lo(res[143], a[68], a[75]); // Sum(143) + res[144] = fma52hi(res[144], a[68], a[75]); // Sum(143) + res[132] = fma52lo(res[132], a[56], a[76]); // Sum(132) + res[133] = fma52hi(res[133], a[56], a[76]); // Sum(132) + res[133] = fma52lo(res[133], a[57], a[76]); // Sum(133) + res[134] = fma52hi(res[134], a[57], a[76]); // Sum(133) + res[134] = fma52lo(res[134], a[58], a[76]); // Sum(134) + res[135] = fma52hi(res[135], a[58], a[76]); // Sum(134) + res[135] = fma52lo(res[135], a[59], a[76]); // Sum(135) + res[136] = fma52hi(res[136], a[59], a[76]); // Sum(135) + res[136] = fma52lo(res[136], a[60], a[76]); // Sum(136) + res[137] = fma52hi(res[137], a[60], a[76]); // Sum(136) + res[137] = fma52lo(res[137], a[61], a[76]); // Sum(137) + res[138] = fma52hi(res[138], a[61], a[76]); // Sum(137) + res[138] = fma52lo(res[138], a[62], a[76]); // Sum(138) + res[139] = fma52hi(res[139], a[62], a[76]); // Sum(138) + res[139] = fma52lo(res[139], a[63], a[76]); // Sum(139) + res[140] = fma52hi(res[140], a[63], a[76]); // Sum(139) + res[140] = fma52lo(res[140], a[64], a[76]); // Sum(140) + res[141] = fma52hi(res[141], a[64], a[76]); // Sum(140) + res[141] = fma52lo(res[141], a[65], a[76]); // Sum(141) + res[142] = fma52hi(res[142], a[65], a[76]); // Sum(141) + res[142] = fma52lo(res[142], a[66], a[76]); // Sum(142) + res[143] = fma52hi(res[143], a[66], a[76]); // Sum(142) + res[143] = fma52lo(res[143], a[67], a[76]); // Sum(143) + res[144] = fma52hi(res[144], a[67], a[76]); // Sum(143) + res[132] = fma52lo(res[132], a[55], a[77]); // Sum(132) + res[133] = fma52hi(res[133], a[55], a[77]); // Sum(132) + res[133] = fma52lo(res[133], a[56], a[77]); // Sum(133) + res[134] = fma52hi(res[134], a[56], a[77]); // Sum(133) + res[134] = fma52lo(res[134], a[57], a[77]); // Sum(134) + res[135] = fma52hi(res[135], a[57], a[77]); // Sum(134) + res[135] = fma52lo(res[135], a[58], a[77]); // Sum(135) + res[136] = fma52hi(res[136], a[58], a[77]); // Sum(135) + res[136] = fma52lo(res[136], a[59], a[77]); // Sum(136) + res[137] = fma52hi(res[137], a[59], a[77]); // Sum(136) + res[137] = fma52lo(res[137], a[60], a[77]); // Sum(137) + res[138] = fma52hi(res[138], a[60], a[77]); // Sum(137) + res[138] = fma52lo(res[138], a[61], a[77]); // Sum(138) + res[139] = fma52hi(res[139], a[61], a[77]); // Sum(138) + res[139] = fma52lo(res[139], a[62], a[77]); // Sum(139) + res[140] = fma52hi(res[140], a[62], a[77]); // Sum(139) + res[140] = fma52lo(res[140], a[63], a[77]); // Sum(140) + res[141] = fma52hi(res[141], a[63], a[77]); // Sum(140) + res[141] = fma52lo(res[141], a[64], a[77]); // Sum(141) + res[142] = fma52hi(res[142], a[64], a[77]); // Sum(141) + res[142] = fma52lo(res[142], a[65], a[77]); // Sum(142) + res[143] = fma52hi(res[143], a[65], a[77]); // Sum(142) + res[143] = fma52lo(res[143], a[66], a[77]); // Sum(143) + res[144] = fma52hi(res[144], a[66], a[77]); // Sum(143) + res[132] = fma52lo(res[132], a[54], a[78]); // Sum(132) + res[133] = fma52hi(res[133], a[54], a[78]); // Sum(132) + res[133] = fma52lo(res[133], a[55], a[78]); // Sum(133) + res[134] = fma52hi(res[134], a[55], a[78]); // Sum(133) + res[134] = fma52lo(res[134], a[56], a[78]); // Sum(134) + res[135] = fma52hi(res[135], a[56], a[78]); // Sum(134) + res[135] = fma52lo(res[135], a[57], a[78]); // Sum(135) + res[136] = fma52hi(res[136], a[57], a[78]); // Sum(135) + res[136] = fma52lo(res[136], a[58], a[78]); // Sum(136) + res[137] = fma52hi(res[137], a[58], a[78]); // Sum(136) + res[137] = fma52lo(res[137], a[59], a[78]); // Sum(137) + res[138] = fma52hi(res[138], a[59], a[78]); // Sum(137) + res[138] = fma52lo(res[138], a[60], a[78]); // Sum(138) + res[139] = fma52hi(res[139], a[60], a[78]); // Sum(138) + res[139] = fma52lo(res[139], a[61], a[78]); // Sum(139) + res[140] = fma52hi(res[140], a[61], a[78]); // Sum(139) + res[140] = fma52lo(res[140], a[62], a[78]); // Sum(140) + res[141] = fma52hi(res[141], a[62], a[78]); // Sum(140) + res[141] = fma52lo(res[141], a[63], a[78]); // Sum(141) + res[142] = fma52hi(res[142], a[63], a[78]); // Sum(141) + res[142] = fma52lo(res[142], a[64], a[78]); // Sum(142) + res[143] = fma52hi(res[143], a[64], a[78]); // Sum(142) + res[143] = fma52lo(res[143], a[65], a[78]); // Sum(143) + res[144] = fma52hi(res[144], a[65], a[78]); // Sum(143) + res[132] = add64(res[132], res[132]); // Double(132) + res[133] = add64(res[133], res[133]); // Double(133) + res[134] = add64(res[134], res[134]); // Double(134) + res[135] = add64(res[135], res[135]); // Double(135) + res[136] = add64(res[136], res[136]); // Double(136) + res[137] = add64(res[137], res[137]); // Double(137) + res[138] = add64(res[138], res[138]); // Double(138) + res[139] = add64(res[139], res[139]); // Double(139) + res[140] = add64(res[140], res[140]); // Double(140) + res[141] = add64(res[141], res[141]); // Double(141) + res[142] = add64(res[142], res[142]); // Double(142) + res[143] = add64(res[143], res[143]); // Double(143) + res[132] = fma52lo(res[132], a[66], a[66]); // Add sqr(132) + res[133] = fma52hi(res[133], a[66], a[66]); // Add sqr(132) + res[134] = fma52lo(res[134], a[67], a[67]); // Add sqr(134) + res[135] = fma52hi(res[135], a[67], a[67]); // Add sqr(134) + res[136] = fma52lo(res[136], a[68], a[68]); // Add sqr(136) + res[137] = fma52hi(res[137], a[68], a[68]); // Add sqr(136) + res[138] = fma52lo(res[138], a[69], a[69]); // Add sqr(138) + res[139] = fma52hi(res[139], a[69], a[69]); // Add sqr(138) + res[140] = fma52lo(res[140], a[70], a[70]); // Add sqr(140) + res[141] = fma52hi(res[141], a[70], a[70]); // Add sqr(140) + res[142] = fma52lo(res[142], a[71], a[71]); // Add sqr(142) + res[143] = fma52hi(res[143], a[71], a[71]); // Add sqr(142) + res[144] = fma52lo(res[144], a[71], a[73]); // Sum(144) + res[145] = fma52hi(res[145], a[71], a[73]); // Sum(144) + res[145] = fma52lo(res[145], a[72], a[73]); // Sum(145) + res[146] = fma52hi(res[146], a[72], a[73]); // Sum(145) + res[144] = fma52lo(res[144], a[70], a[74]); // Sum(144) + res[145] = fma52hi(res[145], a[70], a[74]); // Sum(144) + res[145] = fma52lo(res[145], a[71], a[74]); // Sum(145) + res[146] = fma52hi(res[146], a[71], a[74]); // Sum(145) + res[146] = fma52lo(res[146], a[72], a[74]); // Sum(146) + res[147] = fma52hi(res[147], a[72], a[74]); // Sum(146) + res[147] = fma52lo(res[147], a[73], a[74]); // Sum(147) + res[148] = fma52hi(res[148], a[73], a[74]); // Sum(147) + res[144] = fma52lo(res[144], a[69], a[75]); // Sum(144) + res[145] = fma52hi(res[145], a[69], a[75]); // Sum(144) + res[145] = fma52lo(res[145], a[70], a[75]); // Sum(145) + res[146] = fma52hi(res[146], a[70], a[75]); // Sum(145) + res[146] = fma52lo(res[146], a[71], a[75]); // Sum(146) + res[147] = fma52hi(res[147], a[71], a[75]); // Sum(146) + res[147] = fma52lo(res[147], a[72], a[75]); // Sum(147) + res[148] = fma52hi(res[148], a[72], a[75]); // Sum(147) + res[148] = fma52lo(res[148], a[73], a[75]); // Sum(148) + res[149] = fma52hi(res[149], a[73], a[75]); // Sum(148) + res[149] = fma52lo(res[149], a[74], a[75]); // Sum(149) + res[150] = fma52hi(res[150], a[74], a[75]); // Sum(149) + res[144] = fma52lo(res[144], a[68], a[76]); // Sum(144) + res[145] = fma52hi(res[145], a[68], a[76]); // Sum(144) + res[145] = fma52lo(res[145], a[69], a[76]); // Sum(145) + res[146] = fma52hi(res[146], a[69], a[76]); // Sum(145) + res[146] = fma52lo(res[146], a[70], a[76]); // Sum(146) + res[147] = fma52hi(res[147], a[70], a[76]); // Sum(146) + res[147] = fma52lo(res[147], a[71], a[76]); // Sum(147) + res[148] = fma52hi(res[148], a[71], a[76]); // Sum(147) + res[148] = fma52lo(res[148], a[72], a[76]); // Sum(148) + res[149] = fma52hi(res[149], a[72], a[76]); // Sum(148) + res[149] = fma52lo(res[149], a[73], a[76]); // Sum(149) + res[150] = fma52hi(res[150], a[73], a[76]); // Sum(149) + res[150] = fma52lo(res[150], a[74], a[76]); // Sum(150) + res[151] = fma52hi(res[151], a[74], a[76]); // Sum(150) + res[151] = fma52lo(res[151], a[75], a[76]); // Sum(151) + res[152] = fma52hi(res[152], a[75], a[76]); // Sum(151) + res[144] = fma52lo(res[144], a[67], a[77]); // Sum(144) + res[145] = fma52hi(res[145], a[67], a[77]); // Sum(144) + res[145] = fma52lo(res[145], a[68], a[77]); // Sum(145) + res[146] = fma52hi(res[146], a[68], a[77]); // Sum(145) + res[146] = fma52lo(res[146], a[69], a[77]); // Sum(146) + res[147] = fma52hi(res[147], a[69], a[77]); // Sum(146) + res[147] = fma52lo(res[147], a[70], a[77]); // Sum(147) + res[148] = fma52hi(res[148], a[70], a[77]); // Sum(147) + res[148] = fma52lo(res[148], a[71], a[77]); // Sum(148) + res[149] = fma52hi(res[149], a[71], a[77]); // Sum(148) + res[149] = fma52lo(res[149], a[72], a[77]); // Sum(149) + res[150] = fma52hi(res[150], a[72], a[77]); // Sum(149) + res[150] = fma52lo(res[150], a[73], a[77]); // Sum(150) + res[151] = fma52hi(res[151], a[73], a[77]); // Sum(150) + res[151] = fma52lo(res[151], a[74], a[77]); // Sum(151) + res[152] = fma52hi(res[152], a[74], a[77]); // Sum(151) + res[152] = fma52lo(res[152], a[75], a[77]); // Sum(152) + res[153] = fma52hi(res[153], a[75], a[77]); // Sum(152) + res[153] = fma52lo(res[153], a[76], a[77]); // Sum(153) + res[154] = fma52hi(res[154], a[76], a[77]); // Sum(153) + res[144] = fma52lo(res[144], a[66], a[78]); // Sum(144) + res[145] = fma52hi(res[145], a[66], a[78]); // Sum(144) + res[145] = fma52lo(res[145], a[67], a[78]); // Sum(145) + res[146] = fma52hi(res[146], a[67], a[78]); // Sum(145) + res[146] = fma52lo(res[146], a[68], a[78]); // Sum(146) + res[147] = fma52hi(res[147], a[68], a[78]); // Sum(146) + res[147] = fma52lo(res[147], a[69], a[78]); // Sum(147) + res[148] = fma52hi(res[148], a[69], a[78]); // Sum(147) + res[148] = fma52lo(res[148], a[70], a[78]); // Sum(148) + res[149] = fma52hi(res[149], a[70], a[78]); // Sum(148) + res[149] = fma52lo(res[149], a[71], a[78]); // Sum(149) + res[150] = fma52hi(res[150], a[71], a[78]); // Sum(149) + res[150] = fma52lo(res[150], a[72], a[78]); // Sum(150) + res[151] = fma52hi(res[151], a[72], a[78]); // Sum(150) + res[151] = fma52lo(res[151], a[73], a[78]); // Sum(151) + res[152] = fma52hi(res[152], a[73], a[78]); // Sum(151) + res[152] = fma52lo(res[152], a[74], a[78]); // Sum(152) + res[153] = fma52hi(res[153], a[74], a[78]); // Sum(152) + res[153] = fma52lo(res[153], a[75], a[78]); // Sum(153) + res[154] = fma52hi(res[154], a[75], a[78]); // Sum(153) + res[154] = fma52lo(res[154], a[76], a[78]); // Sum(154) + res[155] = fma52hi(res[155], a[76], a[78]); // Sum(154) + res[155] = fma52lo(res[155], a[77], a[78]); // Sum(155) + res[156] = fma52hi(res[156], a[77], a[78]); // Sum(155) + res[144] = add64(res[144], res[144]); // Double(144) + res[145] = add64(res[145], res[145]); // Double(145) + res[146] = add64(res[146], res[146]); // Double(146) + res[147] = add64(res[147], res[147]); // Double(147) + res[148] = add64(res[148], res[148]); // Double(148) + res[149] = add64(res[149], res[149]); // Double(149) + res[150] = add64(res[150], res[150]); // Double(150) + res[151] = add64(res[151], res[151]); // Double(151) + res[152] = add64(res[152], res[152]); // Double(152) + res[153] = add64(res[153], res[153]); // Double(153) + res[154] = add64(res[154], res[154]); // Double(154) + res[155] = add64(res[155], res[155]); // Double(155) + res[144] = fma52lo(res[144], a[72], a[72]); // Add sqr(144) + res[145] = fma52hi(res[145], a[72], a[72]); // Add sqr(144) + res[146] = fma52lo(res[146], a[73], a[73]); // Add sqr(146) + res[147] = fma52hi(res[147], a[73], a[73]); // Add sqr(146) + res[148] = fma52lo(res[148], a[74], a[74]); // Add sqr(148) + res[149] = fma52hi(res[149], a[74], a[74]); // Add sqr(148) + res[150] = fma52lo(res[150], a[75], a[75]); // Add sqr(150) + res[151] = fma52hi(res[151], a[75], a[75]); // Add sqr(150) + res[152] = fma52lo(res[152], a[76], a[76]); // Add sqr(152) + res[153] = fma52hi(res[153], a[76], a[76]); // Add sqr(152) + res[154] = fma52lo(res[154], a[77], a[77]); // Add sqr(154) + res[155] = fma52hi(res[155], a[77], a[77]); // Add sqr(154) + res[156] = add64(res[156], res[156]); // Double(156) + res[156] = fma52lo(res[156], a[78], a[78]); // Add sqr(156) + res[157] = fma52hi(res[157], a[78], a[78]); // Add sqr(156) + + // Montgomery Reduction + int it; + for (it = 0; it < 80; it += 10) { // Reduction step + int jt = 0; + if ((it + 0) > 0) + res[it + 0] = add64(res[it + 0], srli64(res[it + -1], DIGIT_SIZE)); + u[it + 0] = mul52lo(res[it + 0], k); + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + 1] = add64(res[it + 1], srli64(res[it + 0], DIGIT_SIZE)); + u[it + 1] = mul52lo(res[it + 1], k); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + 2] = add64(res[it + 2], srli64(res[it + 1], DIGIT_SIZE)); + u[it + 2] = mul52lo(res[it + 2], k); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + 3] = add64(res[it + 3], srli64(res[it + 2], DIGIT_SIZE)); + u[it + 3] = mul52lo(res[it + 3], k); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + 4] = add64(res[it + 4], srli64(res[it + 3], DIGIT_SIZE)); + u[it + 4] = mul52lo(res[it + 4], k); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + 5] = add64(res[it + 5], srli64(res[it + 4], DIGIT_SIZE)); + u[it + 5] = mul52lo(res[it + 5], k); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + 6] = add64(res[it + 6], srli64(res[it + 5], DIGIT_SIZE)); + u[it + 6] = mul52lo(res[it + 6], k); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + 7] = add64(res[it + 7], srli64(res[it + 6], DIGIT_SIZE)); + u[it + 7] = mul52lo(res[it + 7], k); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + 8] = add64(res[it + 8], srli64(res[it + 7], DIGIT_SIZE)); + u[it + 8] = mul52lo(res[it + 8], k); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + 9] = add64(res[it + 9], srli64(res[it + 8], DIGIT_SIZE)); + u[it + 9] = (it + 9 < 79) ? mul52lo(res[it + 9], k) : get_zero64(); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + + for (jt = 10; jt < 80; jt += 10) { // Poly tile + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + } + } + + // Normalization + r[0] = and64_const(res[79], DIGIT_MASK); + res[80] = add64(res[80], srli64(res[79], DIGIT_SIZE)); + r[1] = and64_const(res[80], DIGIT_MASK); + res[81] = add64(res[81], srli64(res[80], DIGIT_SIZE)); + r[2] = and64_const(res[81], DIGIT_MASK); + res[82] = add64(res[82], srli64(res[81], DIGIT_SIZE)); + r[3] = and64_const(res[82], DIGIT_MASK); + res[83] = add64(res[83], srli64(res[82], DIGIT_SIZE)); + r[4] = and64_const(res[83], DIGIT_MASK); + res[84] = add64(res[84], srli64(res[83], DIGIT_SIZE)); + r[5] = and64_const(res[84], DIGIT_MASK); + res[85] = add64(res[85], srli64(res[84], DIGIT_SIZE)); + r[6] = and64_const(res[85], DIGIT_MASK); + res[86] = add64(res[86], srli64(res[85], DIGIT_SIZE)); + r[7] = and64_const(res[86], DIGIT_MASK); + res[87] = add64(res[87], srli64(res[86], DIGIT_SIZE)); + r[8] = and64_const(res[87], DIGIT_MASK); + res[88] = add64(res[88], srli64(res[87], DIGIT_SIZE)); + r[9] = and64_const(res[88], DIGIT_MASK); + res[89] = add64(res[89], srli64(res[88], DIGIT_SIZE)); + r[10] = and64_const(res[89], DIGIT_MASK); + res[90] = add64(res[90], srli64(res[89], DIGIT_SIZE)); + r[11] = and64_const(res[90], DIGIT_MASK); + res[91] = add64(res[91], srli64(res[90], DIGIT_SIZE)); + r[12] = and64_const(res[91], DIGIT_MASK); + res[92] = add64(res[92], srli64(res[91], DIGIT_SIZE)); + r[13] = and64_const(res[92], DIGIT_MASK); + res[93] = add64(res[93], srli64(res[92], DIGIT_SIZE)); + r[14] = and64_const(res[93], DIGIT_MASK); + res[94] = add64(res[94], srli64(res[93], DIGIT_SIZE)); + r[15] = and64_const(res[94], DIGIT_MASK); + res[95] = add64(res[95], srli64(res[94], DIGIT_SIZE)); + r[16] = and64_const(res[95], DIGIT_MASK); + res[96] = add64(res[96], srli64(res[95], DIGIT_SIZE)); + r[17] = and64_const(res[96], DIGIT_MASK); + res[97] = add64(res[97], srli64(res[96], DIGIT_SIZE)); + r[18] = and64_const(res[97], DIGIT_MASK); + res[98] = add64(res[98], srli64(res[97], DIGIT_SIZE)); + r[19] = and64_const(res[98], DIGIT_MASK); + res[99] = add64(res[99], srli64(res[98], DIGIT_SIZE)); + r[20] = and64_const(res[99], DIGIT_MASK); + res[100] = add64(res[100], srli64(res[99], DIGIT_SIZE)); + r[21] = and64_const(res[100], DIGIT_MASK); + res[101] = add64(res[101], srli64(res[100], DIGIT_SIZE)); + r[22] = and64_const(res[101], DIGIT_MASK); + res[102] = add64(res[102], srli64(res[101], DIGIT_SIZE)); + r[23] = and64_const(res[102], DIGIT_MASK); + res[103] = add64(res[103], srli64(res[102], DIGIT_SIZE)); + r[24] = and64_const(res[103], DIGIT_MASK); + res[104] = add64(res[104], srli64(res[103], DIGIT_SIZE)); + r[25] = and64_const(res[104], DIGIT_MASK); + res[105] = add64(res[105], srli64(res[104], DIGIT_SIZE)); + r[26] = and64_const(res[105], DIGIT_MASK); + res[106] = add64(res[106], srli64(res[105], DIGIT_SIZE)); + r[27] = and64_const(res[106], DIGIT_MASK); + res[107] = add64(res[107], srli64(res[106], DIGIT_SIZE)); + r[28] = and64_const(res[107], DIGIT_MASK); + res[108] = add64(res[108], srli64(res[107], DIGIT_SIZE)); + r[29] = and64_const(res[108], DIGIT_MASK); + res[109] = add64(res[109], srli64(res[108], DIGIT_SIZE)); + r[30] = and64_const(res[109], DIGIT_MASK); + res[110] = add64(res[110], srli64(res[109], DIGIT_SIZE)); + r[31] = and64_const(res[110], DIGIT_MASK); + res[111] = add64(res[111], srli64(res[110], DIGIT_SIZE)); + r[32] = and64_const(res[111], DIGIT_MASK); + res[112] = add64(res[112], srli64(res[111], DIGIT_SIZE)); + r[33] = and64_const(res[112], DIGIT_MASK); + res[113] = add64(res[113], srli64(res[112], DIGIT_SIZE)); + r[34] = and64_const(res[113], DIGIT_MASK); + res[114] = add64(res[114], srli64(res[113], DIGIT_SIZE)); + r[35] = and64_const(res[114], DIGIT_MASK); + res[115] = add64(res[115], srli64(res[114], DIGIT_SIZE)); + r[36] = and64_const(res[115], DIGIT_MASK); + res[116] = add64(res[116], srli64(res[115], DIGIT_SIZE)); + r[37] = and64_const(res[116], DIGIT_MASK); + res[117] = add64(res[117], srli64(res[116], DIGIT_SIZE)); + r[38] = and64_const(res[117], DIGIT_MASK); + res[118] = add64(res[118], srli64(res[117], DIGIT_SIZE)); + r[39] = and64_const(res[118], DIGIT_MASK); + res[119] = add64(res[119], srli64(res[118], DIGIT_SIZE)); + r[40] = and64_const(res[119], DIGIT_MASK); + res[120] = add64(res[120], srli64(res[119], DIGIT_SIZE)); + r[41] = and64_const(res[120], DIGIT_MASK); + res[121] = add64(res[121], srli64(res[120], DIGIT_SIZE)); + r[42] = and64_const(res[121], DIGIT_MASK); + res[122] = add64(res[122], srli64(res[121], DIGIT_SIZE)); + r[43] = and64_const(res[122], DIGIT_MASK); + res[123] = add64(res[123], srli64(res[122], DIGIT_SIZE)); + r[44] = and64_const(res[123], DIGIT_MASK); + res[124] = add64(res[124], srli64(res[123], DIGIT_SIZE)); + r[45] = and64_const(res[124], DIGIT_MASK); + res[125] = add64(res[125], srli64(res[124], DIGIT_SIZE)); + r[46] = and64_const(res[125], DIGIT_MASK); + res[126] = add64(res[126], srli64(res[125], DIGIT_SIZE)); + r[47] = and64_const(res[126], DIGIT_MASK); + res[127] = add64(res[127], srli64(res[126], DIGIT_SIZE)); + r[48] = and64_const(res[127], DIGIT_MASK); + res[128] = add64(res[128], srli64(res[127], DIGIT_SIZE)); + r[49] = and64_const(res[128], DIGIT_MASK); + res[129] = add64(res[129], srli64(res[128], DIGIT_SIZE)); + r[50] = and64_const(res[129], DIGIT_MASK); + res[130] = add64(res[130], srli64(res[129], DIGIT_SIZE)); + r[51] = and64_const(res[130], DIGIT_MASK); + res[131] = add64(res[131], srli64(res[130], DIGIT_SIZE)); + r[52] = and64_const(res[131], DIGIT_MASK); + res[132] = add64(res[132], srli64(res[131], DIGIT_SIZE)); + r[53] = and64_const(res[132], DIGIT_MASK); + res[133] = add64(res[133], srli64(res[132], DIGIT_SIZE)); + r[54] = and64_const(res[133], DIGIT_MASK); + res[134] = add64(res[134], srli64(res[133], DIGIT_SIZE)); + r[55] = and64_const(res[134], DIGIT_MASK); + res[135] = add64(res[135], srli64(res[134], DIGIT_SIZE)); + r[56] = and64_const(res[135], DIGIT_MASK); + res[136] = add64(res[136], srli64(res[135], DIGIT_SIZE)); + r[57] = and64_const(res[136], DIGIT_MASK); + res[137] = add64(res[137], srli64(res[136], DIGIT_SIZE)); + r[58] = and64_const(res[137], DIGIT_MASK); + res[138] = add64(res[138], srli64(res[137], DIGIT_SIZE)); + r[59] = and64_const(res[138], DIGIT_MASK); + res[139] = add64(res[139], srli64(res[138], DIGIT_SIZE)); + r[60] = and64_const(res[139], DIGIT_MASK); + res[140] = add64(res[140], srli64(res[139], DIGIT_SIZE)); + r[61] = and64_const(res[140], DIGIT_MASK); + res[141] = add64(res[141], srli64(res[140], DIGIT_SIZE)); + r[62] = and64_const(res[141], DIGIT_MASK); + res[142] = add64(res[142], srli64(res[141], DIGIT_SIZE)); + r[63] = and64_const(res[142], DIGIT_MASK); + res[143] = add64(res[143], srli64(res[142], DIGIT_SIZE)); + r[64] = and64_const(res[143], DIGIT_MASK); + res[144] = add64(res[144], srli64(res[143], DIGIT_SIZE)); + r[65] = and64_const(res[144], DIGIT_MASK); + res[145] = add64(res[145], srli64(res[144], DIGIT_SIZE)); + r[66] = and64_const(res[145], DIGIT_MASK); + res[146] = add64(res[146], srli64(res[145], DIGIT_SIZE)); + r[67] = and64_const(res[146], DIGIT_MASK); + res[147] = add64(res[147], srli64(res[146], DIGIT_SIZE)); + r[68] = and64_const(res[147], DIGIT_MASK); + res[148] = add64(res[148], srli64(res[147], DIGIT_SIZE)); + r[69] = and64_const(res[148], DIGIT_MASK); + res[149] = add64(res[149], srli64(res[148], DIGIT_SIZE)); + r[70] = and64_const(res[149], DIGIT_MASK); + res[150] = add64(res[150], srli64(res[149], DIGIT_SIZE)); + r[71] = and64_const(res[150], DIGIT_MASK); + res[151] = add64(res[151], srli64(res[150], DIGIT_SIZE)); + r[72] = and64_const(res[151], DIGIT_MASK); + res[152] = add64(res[152], srli64(res[151], DIGIT_SIZE)); + r[73] = and64_const(res[152], DIGIT_MASK); + res[153] = add64(res[153], srli64(res[152], DIGIT_SIZE)); + r[74] = and64_const(res[153], DIGIT_MASK); + res[154] = add64(res[154], srli64(res[153], DIGIT_SIZE)); + r[75] = and64_const(res[154], DIGIT_MASK); + res[155] = add64(res[155], srli64(res[154], DIGIT_SIZE)); + r[76] = and64_const(res[155], DIGIT_MASK); + res[156] = add64(res[156], srli64(res[155], DIGIT_SIZE)); + r[77] = and64_const(res[156], DIGIT_MASK); + res[157] = add64(res[157], srli64(res[156], DIGIT_SIZE)); + r[78] = and64_const(res[157], DIGIT_MASK); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x10_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x10_diagonal_mb8.c new file mode 100644 index 000000000..08ea97944 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x10_diagonal_mb8.c @@ -0,0 +1,442 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS5x52x10_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + U64 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9, res10, res11, + res12, res13, res14, res15, res16, res17, res18, res19; + U64 k; + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + int iter; + const int iters = 5; + + k = loadu64((U64 *)k0_mb); + for (iter = 0; iter < iters; ++iter) { + res0 = res1 = res2 = res3 = res4 = res5 = res6 = res7 = res8 = res9 = + res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = res18 = + res19 = get_zero64(); + // Calculate full square + res1 = fma52lo(res1, a[0], a[1]); // Sum(1) + res2 = fma52hi(res2, a[0], a[1]); // Sum(1) + res2 = fma52lo(res2, a[0], a[2]); // Sum(2) + res3 = fma52hi(res3, a[0], a[2]); // Sum(2) + res3 = fma52lo(res3, a[1], a[2]); // Sum(3) + res4 = fma52hi(res4, a[1], a[2]); // Sum(3) + res3 = fma52lo(res3, a[0], a[3]); // Sum(3) + res4 = fma52hi(res4, a[0], a[3]); // Sum(3) + res4 = fma52lo(res4, a[1], a[3]); // Sum(4) + res5 = fma52hi(res5, a[1], a[3]); // Sum(4) + res5 = fma52lo(res5, a[2], a[3]); // Sum(5) + res6 = fma52hi(res6, a[2], a[3]); // Sum(5) + res4 = fma52lo(res4, a[0], a[4]); // Sum(4) + res5 = fma52hi(res5, a[0], a[4]); // Sum(4) + res5 = fma52lo(res5, a[1], a[4]); // Sum(5) + res6 = fma52hi(res6, a[1], a[4]); // Sum(5) + res6 = fma52lo(res6, a[2], a[4]); // Sum(6) + res7 = fma52hi(res7, a[2], a[4]); // Sum(6) + res7 = fma52lo(res7, a[3], a[4]); // Sum(7) + res8 = fma52hi(res8, a[3], a[4]); // Sum(7) + res5 = fma52lo(res5, a[0], a[5]); // Sum(5) + res6 = fma52hi(res6, a[0], a[5]); // Sum(5) + res6 = fma52lo(res6, a[1], a[5]); // Sum(6) + res7 = fma52hi(res7, a[1], a[5]); // Sum(6) + res7 = fma52lo(res7, a[2], a[5]); // Sum(7) + res8 = fma52hi(res8, a[2], a[5]); // Sum(7) + res8 = fma52lo(res8, a[3], a[5]); // Sum(8) + res9 = fma52hi(res9, a[3], a[5]); // Sum(8) + res9 = fma52lo(res9, a[4], a[5]); // Sum(9) + res10 = fma52hi(res10, a[4], a[5]); // Sum(9) + res6 = fma52lo(res6, a[0], a[6]); // Sum(6) + res7 = fma52hi(res7, a[0], a[6]); // Sum(6) + res7 = fma52lo(res7, a[1], a[6]); // Sum(7) + res8 = fma52hi(res8, a[1], a[6]); // Sum(7) + res8 = fma52lo(res8, a[2], a[6]); // Sum(8) + res9 = fma52hi(res9, a[2], a[6]); // Sum(8) + res9 = fma52lo(res9, a[3], a[6]); // Sum(9) + res10 = fma52hi(res10, a[3], a[6]); // Sum(9) + res10 = fma52lo(res10, a[4], a[6]); // Sum(10) + res11 = fma52hi(res11, a[4], a[6]); // Sum(10) + res11 = fma52lo(res11, a[5], a[6]); // Sum(11) + res12 = fma52hi(res12, a[5], a[6]); // Sum(11) + res7 = fma52lo(res7, a[0], a[7]); // Sum(7) + res8 = fma52hi(res8, a[0], a[7]); // Sum(7) + res8 = fma52lo(res8, a[1], a[7]); // Sum(8) + res9 = fma52hi(res9, a[1], a[7]); // Sum(8) + res9 = fma52lo(res9, a[2], a[7]); // Sum(9) + res10 = fma52hi(res10, a[2], a[7]); // Sum(9) + res10 = fma52lo(res10, a[3], a[7]); // Sum(10) + res11 = fma52hi(res11, a[3], a[7]); // Sum(10) + res11 = fma52lo(res11, a[4], a[7]); // Sum(11) + res12 = fma52hi(res12, a[4], a[7]); // Sum(11) + res8 = fma52lo(res8, a[0], a[8]); // Sum(8) + res9 = fma52hi(res9, a[0], a[8]); // Sum(8) + res9 = fma52lo(res9, a[1], a[8]); // Sum(9) + res10 = fma52hi(res10, a[1], a[8]); // Sum(9) + res10 = fma52lo(res10, a[2], a[8]); // Sum(10) + res11 = fma52hi(res11, a[2], a[8]); // Sum(10) + res11 = fma52lo(res11, a[3], a[8]); // Sum(11) + res12 = fma52hi(res12, a[3], a[8]); // Sum(11) + res9 = fma52lo(res9, a[0], a[9]); // Sum(9) + res10 = fma52hi(res10, a[0], a[9]); // Sum(9) + res10 = fma52lo(res10, a[1], a[9]); // Sum(10) + res11 = fma52hi(res11, a[1], a[9]); // Sum(10) + res11 = fma52lo(res11, a[2], a[9]); // Sum(11) + res12 = fma52hi(res12, a[2], a[9]); // Sum(11) + res0 = add64(res0, res0); // Double(0) + res1 = add64(res1, res1); // Double(1) + res2 = add64(res2, res2); // Double(2) + res3 = add64(res3, res3); // Double(3) + res4 = add64(res4, res4); // Double(4) + res5 = add64(res5, res5); // Double(5) + res6 = add64(res6, res6); // Double(6) + res7 = add64(res7, res7); // Double(7) + res8 = add64(res8, res8); // Double(8) + res9 = add64(res9, res9); // Double(9) + res10 = add64(res10, res10); // Double(10) + res11 = add64(res11, res11); // Double(11) + res0 = fma52lo(res0, a[0], a[0]); // Add sqr(0) + res1 = fma52hi(res1, a[0], a[0]); // Add sqr(0) + res2 = fma52lo(res2, a[1], a[1]); // Add sqr(2) + res3 = fma52hi(res3, a[1], a[1]); // Add sqr(2) + res4 = fma52lo(res4, a[2], a[2]); // Add sqr(4) + res5 = fma52hi(res5, a[2], a[2]); // Add sqr(4) + res6 = fma52lo(res6, a[3], a[3]); // Add sqr(6) + res7 = fma52hi(res7, a[3], a[3]); // Add sqr(6) + res8 = fma52lo(res8, a[4], a[4]); // Add sqr(8) + res9 = fma52hi(res9, a[4], a[4]); // Add sqr(8) + res10 = fma52lo(res10, a[5], a[5]); // Add sqr(10) + res11 = fma52hi(res11, a[5], a[5]); // Add sqr(10) + res12 = fma52lo(res12, a[5], a[7]); // Sum(12) + res13 = fma52hi(res13, a[5], a[7]); // Sum(12) + res13 = fma52lo(res13, a[6], a[7]); // Sum(13) + res14 = fma52hi(res14, a[6], a[7]); // Sum(13) + res12 = fma52lo(res12, a[4], a[8]); // Sum(12) + res13 = fma52hi(res13, a[4], a[8]); // Sum(12) + res13 = fma52lo(res13, a[5], a[8]); // Sum(13) + res14 = fma52hi(res14, a[5], a[8]); // Sum(13) + res14 = fma52lo(res14, a[6], a[8]); // Sum(14) + res15 = fma52hi(res15, a[6], a[8]); // Sum(14) + res15 = fma52lo(res15, a[7], a[8]); // Sum(15) + res16 = fma52hi(res16, a[7], a[8]); // Sum(15) + res12 = fma52lo(res12, a[3], a[9]); // Sum(12) + res13 = fma52hi(res13, a[3], a[9]); // Sum(12) + res13 = fma52lo(res13, a[4], a[9]); // Sum(13) + res14 = fma52hi(res14, a[4], a[9]); // Sum(13) + res14 = fma52lo(res14, a[5], a[9]); // Sum(14) + res15 = fma52hi(res15, a[5], a[9]); // Sum(14) + res15 = fma52lo(res15, a[6], a[9]); // Sum(15) + res16 = fma52hi(res16, a[6], a[9]); // Sum(15) + res16 = fma52lo(res16, a[7], a[9]); // Sum(16) + res17 = fma52hi(res17, a[7], a[9]); // Sum(16) + res17 = fma52lo(res17, a[8], a[9]); // Sum(17) + res18 = fma52hi(res18, a[8], a[9]); // Sum(17) + res12 = add64(res12, res12); // Double(12) + res13 = add64(res13, res13); // Double(13) + res14 = add64(res14, res14); // Double(14) + res15 = add64(res15, res15); // Double(15) + res16 = add64(res16, res16); // Double(16) + res17 = add64(res17, res17); // Double(17) + res18 = add64(res18, res18); // Double(18) + res12 = fma52lo(res12, a[6], a[6]); // Add sqr(12) + res13 = fma52hi(res13, a[6], a[6]); // Add sqr(12) + res14 = fma52lo(res14, a[7], a[7]); // Add sqr(14) + res15 = fma52hi(res15, a[7], a[7]); // Add sqr(14) + res16 = fma52lo(res16, a[8], a[8]); // Add sqr(16) + res17 = fma52hi(res17, a[8], a[8]); // Add sqr(16) + res18 = fma52lo(res18, a[9], a[9]); // Add sqr(18) + res19 = fma52hi(res19, a[9], a[9]); // Add sqr(18) + + // Generate u_i + U64 u0 = mul52lo(res0, k); + ASM("jmp l0\nl0:\n"); + + // Create u0 + fma52lo_mem(res0, res0, u0, m, SIMD_BYTES * 0); + fma52hi_mem(res1, res1, u0, m, SIMD_BYTES * 0); + res1 = fma52lo(res1, u0, m[1]); + res2 = fma52hi(res2, u0, m[1]); + res1 = add64(res1, srli64(res0, DIGIT_SIZE)); + U64 u1 = mul52lo(res1, k); + fma52lo_mem(res2, res2, u0, m, SIMD_BYTES * 2); + fma52hi_mem(res3, res3, u0, m, SIMD_BYTES * 2); + res3 = fma52lo(res3, u0, m[3]); + res4 = fma52hi(res4, u0, m[3]); + fma52lo_mem(res4, res4, u0, m, SIMD_BYTES * 4); + fma52hi_mem(res5, res5, u0, m, SIMD_BYTES * 4); + res5 = fma52lo(res5, u0, m[5]); + res6 = fma52hi(res6, u0, m[5]); + fma52lo_mem(res6, res6, u0, m, SIMD_BYTES * 6); + fma52hi_mem(res7, res7, u0, m, SIMD_BYTES * 6); + res7 = fma52lo(res7, u0, m[7]); + res8 = fma52hi(res8, u0, m[7]); + fma52lo_mem(res8, res8, u0, m, SIMD_BYTES * 8); + fma52hi_mem(res9, res9, u0, m, SIMD_BYTES * 8); + res9 = fma52lo(res9, u0, m[9]); + res10 = fma52hi(res10, u0, m[9]); + + // Create u1 + fma52lo_mem(res1, res1, u1, m, SIMD_BYTES * 0); + fma52hi_mem(res2, res2, u1, m, SIMD_BYTES * 0); + res2 = fma52lo(res2, u1, m[1]); + res3 = fma52hi(res3, u1, m[1]); + res2 = add64(res2, srli64(res1, DIGIT_SIZE)); + U64 u2 = mul52lo(res2, k); + fma52lo_mem(res3, res3, u1, m, SIMD_BYTES * 2); + fma52hi_mem(res4, res4, u1, m, SIMD_BYTES * 2); + res4 = fma52lo(res4, u1, m[3]); + res5 = fma52hi(res5, u1, m[3]); + fma52lo_mem(res5, res5, u1, m, SIMD_BYTES * 4); + fma52hi_mem(res6, res6, u1, m, SIMD_BYTES * 4); + res6 = fma52lo(res6, u1, m[5]); + res7 = fma52hi(res7, u1, m[5]); + fma52lo_mem(res7, res7, u1, m, SIMD_BYTES * 6); + fma52hi_mem(res8, res8, u1, m, SIMD_BYTES * 6); + res8 = fma52lo(res8, u1, m[7]); + res9 = fma52hi(res9, u1, m[7]); + fma52lo_mem(res9, res9, u1, m, SIMD_BYTES * 8); + fma52hi_mem(res10, res10, u1, m, SIMD_BYTES * 8); + res10 = fma52lo(res10, u1, m[9]); + res11 = fma52hi(res11, u1, m[9]); + ASM("jmp l2\nl2:\n"); + + // Create u2 + fma52lo_mem(res2, res2, u2, m, SIMD_BYTES * 0); + fma52hi_mem(res3, res3, u2, m, SIMD_BYTES * 0); + res3 = fma52lo(res3, u2, m[1]); + res4 = fma52hi(res4, u2, m[1]); + res3 = add64(res3, srli64(res2, DIGIT_SIZE)); + U64 u3 = mul52lo(res3, k); + fma52lo_mem(res4, res4, u2, m, SIMD_BYTES * 2); + fma52hi_mem(res5, res5, u2, m, SIMD_BYTES * 2); + res5 = fma52lo(res5, u2, m[3]); + res6 = fma52hi(res6, u2, m[3]); + fma52lo_mem(res6, res6, u2, m, SIMD_BYTES * 4); + fma52hi_mem(res7, res7, u2, m, SIMD_BYTES * 4); + res7 = fma52lo(res7, u2, m[5]); + res8 = fma52hi(res8, u2, m[5]); + fma52lo_mem(res8, res8, u2, m, SIMD_BYTES * 6); + fma52hi_mem(res9, res9, u2, m, SIMD_BYTES * 6); + res9 = fma52lo(res9, u2, m[7]); + res10 = fma52hi(res10, u2, m[7]); + fma52lo_mem(res10, res10, u2, m, SIMD_BYTES * 8); + fma52hi_mem(res11, res11, u2, m, SIMD_BYTES * 8); + res11 = fma52lo(res11, u2, m[9]); + res12 = fma52hi(res12, u2, m[9]); + + // Create u3 + fma52lo_mem(res3, res3, u3, m, SIMD_BYTES * 0); + fma52hi_mem(res4, res4, u3, m, SIMD_BYTES * 0); + res4 = fma52lo(res4, u3, m[1]); + res5 = fma52hi(res5, u3, m[1]); + res4 = add64(res4, srli64(res3, DIGIT_SIZE)); + U64 u4 = mul52lo(res4, k); + fma52lo_mem(res5, res5, u3, m, SIMD_BYTES * 2); + fma52hi_mem(res6, res6, u3, m, SIMD_BYTES * 2); + res6 = fma52lo(res6, u3, m[3]); + res7 = fma52hi(res7, u3, m[3]); + fma52lo_mem(res7, res7, u3, m, SIMD_BYTES * 4); + fma52hi_mem(res8, res8, u3, m, SIMD_BYTES * 4); + res8 = fma52lo(res8, u3, m[5]); + res9 = fma52hi(res9, u3, m[5]); + fma52lo_mem(res9, res9, u3, m, SIMD_BYTES * 6); + fma52hi_mem(res10, res10, u3, m, SIMD_BYTES * 6); + res10 = fma52lo(res10, u3, m[7]); + res11 = fma52hi(res11, u3, m[7]); + fma52lo_mem(res11, res11, u3, m, SIMD_BYTES * 8); + fma52hi_mem(res12, res12, u3, m, SIMD_BYTES * 8); + res12 = fma52lo(res12, u3, m[9]); + res13 = fma52hi(res13, u3, m[9]); + ASM("jmp l4\nl4:\n"); + + // Create u4 + fma52lo_mem(res4, res4, u4, m, SIMD_BYTES * 0); + fma52hi_mem(res5, res5, u4, m, SIMD_BYTES * 0); + res5 = fma52lo(res5, u4, m[1]); + res6 = fma52hi(res6, u4, m[1]); + res5 = add64(res5, srli64(res4, DIGIT_SIZE)); + U64 u5 = mul52lo(res5, k); + fma52lo_mem(res6, res6, u4, m, SIMD_BYTES * 2); + fma52hi_mem(res7, res7, u4, m, SIMD_BYTES * 2); + res7 = fma52lo(res7, u4, m[3]); + res8 = fma52hi(res8, u4, m[3]); + fma52lo_mem(res8, res8, u4, m, SIMD_BYTES * 4); + fma52hi_mem(res9, res9, u4, m, SIMD_BYTES * 4); + res9 = fma52lo(res9, u4, m[5]); + res10 = fma52hi(res10, u4, m[5]); + fma52lo_mem(res10, res10, u4, m, SIMD_BYTES * 6); + fma52hi_mem(res11, res11, u4, m, SIMD_BYTES * 6); + res11 = fma52lo(res11, u4, m[7]); + res12 = fma52hi(res12, u4, m[7]); + fma52lo_mem(res12, res12, u4, m, SIMD_BYTES * 8); + fma52hi_mem(res13, res13, u4, m, SIMD_BYTES * 8); + res13 = fma52lo(res13, u4, m[9]); + res14 = fma52hi(res14, u4, m[9]); + + // Create u5 + fma52lo_mem(res5, res5, u5, m, SIMD_BYTES * 0); + fma52hi_mem(res6, res6, u5, m, SIMD_BYTES * 0); + res6 = fma52lo(res6, u5, m[1]); + res7 = fma52hi(res7, u5, m[1]); + res6 = add64(res6, srli64(res5, DIGIT_SIZE)); + U64 u6 = mul52lo(res6, k); + fma52lo_mem(res7, res7, u5, m, SIMD_BYTES * 2); + fma52hi_mem(res8, res8, u5, m, SIMD_BYTES * 2); + res8 = fma52lo(res8, u5, m[3]); + res9 = fma52hi(res9, u5, m[3]); + fma52lo_mem(res9, res9, u5, m, SIMD_BYTES * 4); + fma52hi_mem(res10, res10, u5, m, SIMD_BYTES * 4); + res10 = fma52lo(res10, u5, m[5]); + res11 = fma52hi(res11, u5, m[5]); + fma52lo_mem(res11, res11, u5, m, SIMD_BYTES * 6); + fma52hi_mem(res12, res12, u5, m, SIMD_BYTES * 6); + res12 = fma52lo(res12, u5, m[7]); + res13 = fma52hi(res13, u5, m[7]); + fma52lo_mem(res13, res13, u5, m, SIMD_BYTES * 8); + fma52hi_mem(res14, res14, u5, m, SIMD_BYTES * 8); + res14 = fma52lo(res14, u5, m[9]); + res15 = fma52hi(res15, u5, m[9]); + ASM("jmp l6\nl6:\n"); + + // Create u6 + fma52lo_mem(res6, res6, u6, m, SIMD_BYTES * 0); + fma52hi_mem(res7, res7, u6, m, SIMD_BYTES * 0); + res7 = fma52lo(res7, u6, m[1]); + res8 = fma52hi(res8, u6, m[1]); + res7 = add64(res7, srli64(res6, DIGIT_SIZE)); + U64 u7 = mul52lo(res7, k); + fma52lo_mem(res8, res8, u6, m, SIMD_BYTES * 2); + fma52hi_mem(res9, res9, u6, m, SIMD_BYTES * 2); + res9 = fma52lo(res9, u6, m[3]); + res10 = fma52hi(res10, u6, m[3]); + fma52lo_mem(res10, res10, u6, m, SIMD_BYTES * 4); + fma52hi_mem(res11, res11, u6, m, SIMD_BYTES * 4); + res11 = fma52lo(res11, u6, m[5]); + res12 = fma52hi(res12, u6, m[5]); + fma52lo_mem(res12, res12, u6, m, SIMD_BYTES * 6); + fma52hi_mem(res13, res13, u6, m, SIMD_BYTES * 6); + res13 = fma52lo(res13, u6, m[7]); + res14 = fma52hi(res14, u6, m[7]); + fma52lo_mem(res14, res14, u6, m, SIMD_BYTES * 8); + fma52hi_mem(res15, res15, u6, m, SIMD_BYTES * 8); + res15 = fma52lo(res15, u6, m[9]); + res16 = fma52hi(res16, u6, m[9]); + + // Create u7 + fma52lo_mem(res7, res7, u7, m, SIMD_BYTES * 0); + fma52hi_mem(res8, res8, u7, m, SIMD_BYTES * 0); + res8 = fma52lo(res8, u7, m[1]); + res9 = fma52hi(res9, u7, m[1]); + res8 = add64(res8, srli64(res7, DIGIT_SIZE)); + U64 u8 = mul52lo(res8, k); + fma52lo_mem(res9, res9, u7, m, SIMD_BYTES * 2); + fma52hi_mem(res10, res10, u7, m, SIMD_BYTES * 2); + res10 = fma52lo(res10, u7, m[3]); + res11 = fma52hi(res11, u7, m[3]); + fma52lo_mem(res11, res11, u7, m, SIMD_BYTES * 4); + fma52hi_mem(res12, res12, u7, m, SIMD_BYTES * 4); + res12 = fma52lo(res12, u7, m[5]); + res13 = fma52hi(res13, u7, m[5]); + fma52lo_mem(res13, res13, u7, m, SIMD_BYTES * 6); + fma52hi_mem(res14, res14, u7, m, SIMD_BYTES * 6); + res14 = fma52lo(res14, u7, m[7]); + res15 = fma52hi(res15, u7, m[7]); + fma52lo_mem(res15, res15, u7, m, SIMD_BYTES * 8); + fma52hi_mem(res16, res16, u7, m, SIMD_BYTES * 8); + res16 = fma52lo(res16, u7, m[9]); + res17 = fma52hi(res17, u7, m[9]); + ASM("jmp l8\nl8:\n"); + + // Create u8 + fma52lo_mem(res8, res8, u8, m, SIMD_BYTES * 0); + fma52hi_mem(res9, res9, u8, m, SIMD_BYTES * 0); + res9 = fma52lo(res9, u8, m[1]); + res10 = fma52hi(res10, u8, m[1]); + res9 = add64(res9, srli64(res8, DIGIT_SIZE)); + U64 u9 = mul52lo(res9, k); + fma52lo_mem(res10, res10, u8, m, SIMD_BYTES * 2); + fma52hi_mem(res11, res11, u8, m, SIMD_BYTES * 2); + res11 = fma52lo(res11, u8, m[3]); + res12 = fma52hi(res12, u8, m[3]); + fma52lo_mem(res12, res12, u8, m, SIMD_BYTES * 4); + fma52hi_mem(res13, res13, u8, m, SIMD_BYTES * 4); + res13 = fma52lo(res13, u8, m[5]); + res14 = fma52hi(res14, u8, m[5]); + fma52lo_mem(res14, res14, u8, m, SIMD_BYTES * 6); + fma52hi_mem(res15, res15, u8, m, SIMD_BYTES * 6); + res15 = fma52lo(res15, u8, m[7]); + res16 = fma52hi(res16, u8, m[7]); + fma52lo_mem(res16, res16, u8, m, SIMD_BYTES * 8); + fma52hi_mem(res17, res17, u8, m, SIMD_BYTES * 8); + res17 = fma52lo(res17, u8, m[9]); + res18 = fma52hi(res18, u8, m[9]); + + // Create u9 + fma52lo_mem(res9, res9, u9, m, SIMD_BYTES * 0); + fma52hi_mem(res10, res10, u9, m, SIMD_BYTES * 0); + res10 = fma52lo(res10, u9, m[1]); + res11 = fma52hi(res11, u9, m[1]); + res10 = add64(res10, srli64(res9, DIGIT_SIZE)); + fma52lo_mem(res11, res11, u9, m, SIMD_BYTES * 2); + fma52hi_mem(res12, res12, u9, m, SIMD_BYTES * 2); + res12 = fma52lo(res12, u9, m[3]); + res13 = fma52hi(res13, u9, m[3]); + fma52lo_mem(res13, res13, u9, m, SIMD_BYTES * 4); + fma52hi_mem(res14, res14, u9, m, SIMD_BYTES * 4); + res14 = fma52lo(res14, u9, m[5]); + res15 = fma52hi(res15, u9, m[5]); + fma52lo_mem(res15, res15, u9, m, SIMD_BYTES * 6); + fma52hi_mem(res16, res16, u9, m, SIMD_BYTES * 6); + res16 = fma52lo(res16, u9, m[7]); + res17 = fma52hi(res17, u9, m[7]); + fma52lo_mem(res17, res17, u9, m, SIMD_BYTES * 8); + fma52hi_mem(res18, res18, u9, m, SIMD_BYTES * 8); + res18 = fma52lo(res18, u9, m[9]); + res19 = fma52hi(res19, u9, m[9]); + + // Normalization + r[0] = res10; + res11 = add64(res11, srli64(res10, DIGIT_SIZE)); + r[1] = res11; + res12 = add64(res12, srli64(res11, DIGIT_SIZE)); + r[2] = res12; + res13 = add64(res13, srli64(res12, DIGIT_SIZE)); + r[3] = res13; + res14 = add64(res14, srli64(res13, DIGIT_SIZE)); + r[4] = res14; + res15 = add64(res15, srli64(res14, DIGIT_SIZE)); + r[5] = res15; + res16 = add64(res16, srli64(res15, DIGIT_SIZE)); + r[6] = res16; + res17 = add64(res17, srli64(res16, DIGIT_SIZE)); + r[7] = res17; + res18 = add64(res18, srli64(res17, DIGIT_SIZE)); + r[8] = res18; + res19 = add64(res19, srli64(res18, DIGIT_SIZE)); + r[9] = res19; + a = (U64 *)out_mb; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x20_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x20_diagonal_mb8.c new file mode 100644 index 000000000..90d23e26b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x20_diagonal_mb8.c @@ -0,0 +1,1441 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS5x52x20_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + U64 res0, res1, res2, res3, res4, res5, res6, res7, res8, res9, res10, res11, + res12, res13, res14, res15, res16, res17, res18, res19, res20, res21, + res22, res23, res24, res25, res26, res27, res28, res29, res30, res31, + res32, res33, res34, res35, res36, res37, res38, res39; + U64 k; + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + int iter; + const int iters = 5; + + k = loadu64((U64 *)k0_mb); + for (iter = 0; iter < iters; ++iter) { + res0 = res1 = res2 = res3 = res4 = res5 = res6 = res7 = res8 = res9 = + res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = res18 = + res19 = res20 = res21 = res22 = res23 = res24 = res25 = res26 = + res27 = res28 = res29 = res30 = res31 = res32 = res33 = res34 = + res35 = res36 = res37 = res38 = res39 = get_zero64(); + // Calculate full square + res1 = fma52lo(res1, a[0], a[1]); // Sum(1) + res2 = fma52hi(res2, a[0], a[1]); // Sum(1) + res2 = fma52lo(res2, a[0], a[2]); // Sum(2) + res3 = fma52hi(res3, a[0], a[2]); // Sum(2) + res3 = fma52lo(res3, a[1], a[2]); // Sum(3) + res4 = fma52hi(res4, a[1], a[2]); // Sum(3) + res3 = fma52lo(res3, a[0], a[3]); // Sum(3) + res4 = fma52hi(res4, a[0], a[3]); // Sum(3) + res4 = fma52lo(res4, a[1], a[3]); // Sum(4) + res5 = fma52hi(res5, a[1], a[3]); // Sum(4) + res5 = fma52lo(res5, a[2], a[3]); // Sum(5) + res6 = fma52hi(res6, a[2], a[3]); // Sum(5) + res4 = fma52lo(res4, a[0], a[4]); // Sum(4) + res5 = fma52hi(res5, a[0], a[4]); // Sum(4) + res5 = fma52lo(res5, a[1], a[4]); // Sum(5) + res6 = fma52hi(res6, a[1], a[4]); // Sum(5) + res6 = fma52lo(res6, a[2], a[4]); // Sum(6) + res7 = fma52hi(res7, a[2], a[4]); // Sum(6) + res7 = fma52lo(res7, a[3], a[4]); // Sum(7) + res8 = fma52hi(res8, a[3], a[4]); // Sum(7) + res5 = fma52lo(res5, a[0], a[5]); // Sum(5) + res6 = fma52hi(res6, a[0], a[5]); // Sum(5) + res6 = fma52lo(res6, a[1], a[5]); // Sum(6) + res7 = fma52hi(res7, a[1], a[5]); // Sum(6) + res7 = fma52lo(res7, a[2], a[5]); // Sum(7) + res8 = fma52hi(res8, a[2], a[5]); // Sum(7) + res8 = fma52lo(res8, a[3], a[5]); // Sum(8) + res9 = fma52hi(res9, a[3], a[5]); // Sum(8) + res9 = fma52lo(res9, a[4], a[5]); // Sum(9) + res10 = fma52hi(res10, a[4], a[5]); // Sum(9) + res6 = fma52lo(res6, a[0], a[6]); // Sum(6) + res7 = fma52hi(res7, a[0], a[6]); // Sum(6) + res7 = fma52lo(res7, a[1], a[6]); // Sum(7) + res8 = fma52hi(res8, a[1], a[6]); // Sum(7) + res8 = fma52lo(res8, a[2], a[6]); // Sum(8) + res9 = fma52hi(res9, a[2], a[6]); // Sum(8) + res9 = fma52lo(res9, a[3], a[6]); // Sum(9) + res10 = fma52hi(res10, a[3], a[6]); // Sum(9) + res10 = fma52lo(res10, a[4], a[6]); // Sum(10) + res11 = fma52hi(res11, a[4], a[6]); // Sum(10) + res11 = fma52lo(res11, a[5], a[6]); // Sum(11) + res12 = fma52hi(res12, a[5], a[6]); // Sum(11) + res7 = fma52lo(res7, a[0], a[7]); // Sum(7) + res8 = fma52hi(res8, a[0], a[7]); // Sum(7) + res8 = fma52lo(res8, a[1], a[7]); // Sum(8) + res9 = fma52hi(res9, a[1], a[7]); // Sum(8) + res9 = fma52lo(res9, a[2], a[7]); // Sum(9) + res10 = fma52hi(res10, a[2], a[7]); // Sum(9) + res10 = fma52lo(res10, a[3], a[7]); // Sum(10) + res11 = fma52hi(res11, a[3], a[7]); // Sum(10) + res11 = fma52lo(res11, a[4], a[7]); // Sum(11) + res12 = fma52hi(res12, a[4], a[7]); // Sum(11) + res8 = fma52lo(res8, a[0], a[8]); // Sum(8) + res9 = fma52hi(res9, a[0], a[8]); // Sum(8) + res9 = fma52lo(res9, a[1], a[8]); // Sum(9) + res10 = fma52hi(res10, a[1], a[8]); // Sum(9) + res10 = fma52lo(res10, a[2], a[8]); // Sum(10) + res11 = fma52hi(res11, a[2], a[8]); // Sum(10) + res11 = fma52lo(res11, a[3], a[8]); // Sum(11) + res12 = fma52hi(res12, a[3], a[8]); // Sum(11) + res9 = fma52lo(res9, a[0], a[9]); // Sum(9) + res10 = fma52hi(res10, a[0], a[9]); // Sum(9) + res10 = fma52lo(res10, a[1], a[9]); // Sum(10) + res11 = fma52hi(res11, a[1], a[9]); // Sum(10) + res11 = fma52lo(res11, a[2], a[9]); // Sum(11) + res12 = fma52hi(res12, a[2], a[9]); // Sum(11) + res10 = fma52lo(res10, a[0], a[10]); // Sum(10) + res11 = fma52hi(res11, a[0], a[10]); // Sum(10) + res11 = fma52lo(res11, a[1], a[10]); // Sum(11) + res12 = fma52hi(res12, a[1], a[10]); // Sum(11) + res11 = fma52lo(res11, a[0], a[11]); // Sum(11) + res12 = fma52hi(res12, a[0], a[11]); // Sum(11) + res0 = add64(res0, res0); // Double(0) + res1 = add64(res1, res1); // Double(1) + res2 = add64(res2, res2); // Double(2) + res3 = add64(res3, res3); // Double(3) + res4 = add64(res4, res4); // Double(4) + res5 = add64(res5, res5); // Double(5) + res6 = add64(res6, res6); // Double(6) + res7 = add64(res7, res7); // Double(7) + res8 = add64(res8, res8); // Double(8) + res9 = add64(res9, res9); // Double(9) + res10 = add64(res10, res10); // Double(10) + res11 = add64(res11, res11); // Double(11) + res0 = fma52lo(res0, a[0], a[0]); // Add sqr(0) + res1 = fma52hi(res1, a[0], a[0]); // Add sqr(0) + res2 = fma52lo(res2, a[1], a[1]); // Add sqr(2) + res3 = fma52hi(res3, a[1], a[1]); // Add sqr(2) + res4 = fma52lo(res4, a[2], a[2]); // Add sqr(4) + res5 = fma52hi(res5, a[2], a[2]); // Add sqr(4) + res6 = fma52lo(res6, a[3], a[3]); // Add sqr(6) + res7 = fma52hi(res7, a[3], a[3]); // Add sqr(6) + res8 = fma52lo(res8, a[4], a[4]); // Add sqr(8) + res9 = fma52hi(res9, a[4], a[4]); // Add sqr(8) + res10 = fma52lo(res10, a[5], a[5]); // Add sqr(10) + res11 = fma52hi(res11, a[5], a[5]); // Add sqr(10) + res12 = fma52lo(res12, a[5], a[7]); // Sum(12) + res13 = fma52hi(res13, a[5], a[7]); // Sum(12) + res13 = fma52lo(res13, a[6], a[7]); // Sum(13) + res14 = fma52hi(res14, a[6], a[7]); // Sum(13) + res12 = fma52lo(res12, a[4], a[8]); // Sum(12) + res13 = fma52hi(res13, a[4], a[8]); // Sum(12) + res13 = fma52lo(res13, a[5], a[8]); // Sum(13) + res14 = fma52hi(res14, a[5], a[8]); // Sum(13) + res14 = fma52lo(res14, a[6], a[8]); // Sum(14) + res15 = fma52hi(res15, a[6], a[8]); // Sum(14) + res15 = fma52lo(res15, a[7], a[8]); // Sum(15) + res16 = fma52hi(res16, a[7], a[8]); // Sum(15) + res12 = fma52lo(res12, a[3], a[9]); // Sum(12) + res13 = fma52hi(res13, a[3], a[9]); // Sum(12) + res13 = fma52lo(res13, a[4], a[9]); // Sum(13) + res14 = fma52hi(res14, a[4], a[9]); // Sum(13) + res14 = fma52lo(res14, a[5], a[9]); // Sum(14) + res15 = fma52hi(res15, a[5], a[9]); // Sum(14) + res15 = fma52lo(res15, a[6], a[9]); // Sum(15) + res16 = fma52hi(res16, a[6], a[9]); // Sum(15) + res16 = fma52lo(res16, a[7], a[9]); // Sum(16) + res17 = fma52hi(res17, a[7], a[9]); // Sum(16) + res17 = fma52lo(res17, a[8], a[9]); // Sum(17) + res18 = fma52hi(res18, a[8], a[9]); // Sum(17) + res12 = fma52lo(res12, a[2], a[10]); // Sum(12) + res13 = fma52hi(res13, a[2], a[10]); // Sum(12) + res13 = fma52lo(res13, a[3], a[10]); // Sum(13) + res14 = fma52hi(res14, a[3], a[10]); // Sum(13) + res14 = fma52lo(res14, a[4], a[10]); // Sum(14) + res15 = fma52hi(res15, a[4], a[10]); // Sum(14) + res15 = fma52lo(res15, a[5], a[10]); // Sum(15) + res16 = fma52hi(res16, a[5], a[10]); // Sum(15) + res16 = fma52lo(res16, a[6], a[10]); // Sum(16) + res17 = fma52hi(res17, a[6], a[10]); // Sum(16) + res17 = fma52lo(res17, a[7], a[10]); // Sum(17) + res18 = fma52hi(res18, a[7], a[10]); // Sum(17) + res18 = fma52lo(res18, a[8], a[10]); // Sum(18) + res19 = fma52hi(res19, a[8], a[10]); // Sum(18) + res19 = fma52lo(res19, a[9], a[10]); // Sum(19) + res20 = fma52hi(res20, a[9], a[10]); // Sum(19) + res12 = fma52lo(res12, a[1], a[11]); // Sum(12) + res13 = fma52hi(res13, a[1], a[11]); // Sum(12) + res13 = fma52lo(res13, a[2], a[11]); // Sum(13) + res14 = fma52hi(res14, a[2], a[11]); // Sum(13) + res14 = fma52lo(res14, a[3], a[11]); // Sum(14) + res15 = fma52hi(res15, a[3], a[11]); // Sum(14) + res15 = fma52lo(res15, a[4], a[11]); // Sum(15) + res16 = fma52hi(res16, a[4], a[11]); // Sum(15) + res16 = fma52lo(res16, a[5], a[11]); // Sum(16) + res17 = fma52hi(res17, a[5], a[11]); // Sum(16) + res17 = fma52lo(res17, a[6], a[11]); // Sum(17) + res18 = fma52hi(res18, a[6], a[11]); // Sum(17) + res18 = fma52lo(res18, a[7], a[11]); // Sum(18) + res19 = fma52hi(res19, a[7], a[11]); // Sum(18) + res19 = fma52lo(res19, a[8], a[11]); // Sum(19) + res20 = fma52hi(res20, a[8], a[11]); // Sum(19) + res20 = fma52lo(res20, a[9], a[11]); // Sum(20) + res21 = fma52hi(res21, a[9], a[11]); // Sum(20) + res21 = fma52lo(res21, a[10], a[11]); // Sum(21) + res22 = fma52hi(res22, a[10], a[11]); // Sum(21) + res12 = fma52lo(res12, a[0], a[12]); // Sum(12) + res13 = fma52hi(res13, a[0], a[12]); // Sum(12) + res13 = fma52lo(res13, a[1], a[12]); // Sum(13) + res14 = fma52hi(res14, a[1], a[12]); // Sum(13) + res14 = fma52lo(res14, a[2], a[12]); // Sum(14) + res15 = fma52hi(res15, a[2], a[12]); // Sum(14) + res15 = fma52lo(res15, a[3], a[12]); // Sum(15) + res16 = fma52hi(res16, a[3], a[12]); // Sum(15) + res16 = fma52lo(res16, a[4], a[12]); // Sum(16) + res17 = fma52hi(res17, a[4], a[12]); // Sum(16) + res17 = fma52lo(res17, a[5], a[12]); // Sum(17) + res18 = fma52hi(res18, a[5], a[12]); // Sum(17) + res18 = fma52lo(res18, a[6], a[12]); // Sum(18) + res19 = fma52hi(res19, a[6], a[12]); // Sum(18) + res19 = fma52lo(res19, a[7], a[12]); // Sum(19) + res20 = fma52hi(res20, a[7], a[12]); // Sum(19) + res20 = fma52lo(res20, a[8], a[12]); // Sum(20) + res21 = fma52hi(res21, a[8], a[12]); // Sum(20) + res21 = fma52lo(res21, a[9], a[12]); // Sum(21) + res22 = fma52hi(res22, a[9], a[12]); // Sum(21) + res22 = fma52lo(res22, a[10], a[12]); // Sum(22) + res23 = fma52hi(res23, a[10], a[12]); // Sum(22) + res23 = fma52lo(res23, a[11], a[12]); // Sum(23) + res24 = fma52hi(res24, a[11], a[12]); // Sum(23) + res13 = fma52lo(res13, a[0], a[13]); // Sum(13) + res14 = fma52hi(res14, a[0], a[13]); // Sum(13) + res14 = fma52lo(res14, a[1], a[13]); // Sum(14) + res15 = fma52hi(res15, a[1], a[13]); // Sum(14) + res15 = fma52lo(res15, a[2], a[13]); // Sum(15) + res16 = fma52hi(res16, a[2], a[13]); // Sum(15) + res16 = fma52lo(res16, a[3], a[13]); // Sum(16) + res17 = fma52hi(res17, a[3], a[13]); // Sum(16) + res17 = fma52lo(res17, a[4], a[13]); // Sum(17) + res18 = fma52hi(res18, a[4], a[13]); // Sum(17) + res18 = fma52lo(res18, a[5], a[13]); // Sum(18) + res19 = fma52hi(res19, a[5], a[13]); // Sum(18) + res19 = fma52lo(res19, a[6], a[13]); // Sum(19) + res20 = fma52hi(res20, a[6], a[13]); // Sum(19) + res20 = fma52lo(res20, a[7], a[13]); // Sum(20) + res21 = fma52hi(res21, a[7], a[13]); // Sum(20) + res21 = fma52lo(res21, a[8], a[13]); // Sum(21) + res22 = fma52hi(res22, a[8], a[13]); // Sum(21) + res22 = fma52lo(res22, a[9], a[13]); // Sum(22) + res23 = fma52hi(res23, a[9], a[13]); // Sum(22) + res23 = fma52lo(res23, a[10], a[13]); // Sum(23) + res24 = fma52hi(res24, a[10], a[13]); // Sum(23) + res14 = fma52lo(res14, a[0], a[14]); // Sum(14) + res15 = fma52hi(res15, a[0], a[14]); // Sum(14) + res15 = fma52lo(res15, a[1], a[14]); // Sum(15) + res16 = fma52hi(res16, a[1], a[14]); // Sum(15) + res16 = fma52lo(res16, a[2], a[14]); // Sum(16) + res17 = fma52hi(res17, a[2], a[14]); // Sum(16) + res17 = fma52lo(res17, a[3], a[14]); // Sum(17) + res18 = fma52hi(res18, a[3], a[14]); // Sum(17) + res18 = fma52lo(res18, a[4], a[14]); // Sum(18) + res19 = fma52hi(res19, a[4], a[14]); // Sum(18) + res19 = fma52lo(res19, a[5], a[14]); // Sum(19) + res20 = fma52hi(res20, a[5], a[14]); // Sum(19) + res20 = fma52lo(res20, a[6], a[14]); // Sum(20) + res21 = fma52hi(res21, a[6], a[14]); // Sum(20) + res21 = fma52lo(res21, a[7], a[14]); // Sum(21) + res22 = fma52hi(res22, a[7], a[14]); // Sum(21) + res22 = fma52lo(res22, a[8], a[14]); // Sum(22) + res23 = fma52hi(res23, a[8], a[14]); // Sum(22) + res23 = fma52lo(res23, a[9], a[14]); // Sum(23) + res24 = fma52hi(res24, a[9], a[14]); // Sum(23) + res15 = fma52lo(res15, a[0], a[15]); // Sum(15) + res16 = fma52hi(res16, a[0], a[15]); // Sum(15) + res16 = fma52lo(res16, a[1], a[15]); // Sum(16) + res17 = fma52hi(res17, a[1], a[15]); // Sum(16) + res17 = fma52lo(res17, a[2], a[15]); // Sum(17) + res18 = fma52hi(res18, a[2], a[15]); // Sum(17) + res18 = fma52lo(res18, a[3], a[15]); // Sum(18) + res19 = fma52hi(res19, a[3], a[15]); // Sum(18) + res19 = fma52lo(res19, a[4], a[15]); // Sum(19) + res20 = fma52hi(res20, a[4], a[15]); // Sum(19) + res20 = fma52lo(res20, a[5], a[15]); // Sum(20) + res21 = fma52hi(res21, a[5], a[15]); // Sum(20) + res21 = fma52lo(res21, a[6], a[15]); // Sum(21) + res22 = fma52hi(res22, a[6], a[15]); // Sum(21) + res22 = fma52lo(res22, a[7], a[15]); // Sum(22) + res23 = fma52hi(res23, a[7], a[15]); // Sum(22) + res23 = fma52lo(res23, a[8], a[15]); // Sum(23) + res24 = fma52hi(res24, a[8], a[15]); // Sum(23) + res16 = fma52lo(res16, a[0], a[16]); // Sum(16) + res17 = fma52hi(res17, a[0], a[16]); // Sum(16) + res17 = fma52lo(res17, a[1], a[16]); // Sum(17) + res18 = fma52hi(res18, a[1], a[16]); // Sum(17) + res18 = fma52lo(res18, a[2], a[16]); // Sum(18) + res19 = fma52hi(res19, a[2], a[16]); // Sum(18) + res19 = fma52lo(res19, a[3], a[16]); // Sum(19) + res20 = fma52hi(res20, a[3], a[16]); // Sum(19) + res20 = fma52lo(res20, a[4], a[16]); // Sum(20) + res21 = fma52hi(res21, a[4], a[16]); // Sum(20) + res21 = fma52lo(res21, a[5], a[16]); // Sum(21) + res22 = fma52hi(res22, a[5], a[16]); // Sum(21) + res22 = fma52lo(res22, a[6], a[16]); // Sum(22) + res23 = fma52hi(res23, a[6], a[16]); // Sum(22) + res23 = fma52lo(res23, a[7], a[16]); // Sum(23) + res24 = fma52hi(res24, a[7], a[16]); // Sum(23) + res17 = fma52lo(res17, a[0], a[17]); // Sum(17) + res18 = fma52hi(res18, a[0], a[17]); // Sum(17) + res18 = fma52lo(res18, a[1], a[17]); // Sum(18) + res19 = fma52hi(res19, a[1], a[17]); // Sum(18) + res19 = fma52lo(res19, a[2], a[17]); // Sum(19) + res20 = fma52hi(res20, a[2], a[17]); // Sum(19) + res20 = fma52lo(res20, a[3], a[17]); // Sum(20) + res21 = fma52hi(res21, a[3], a[17]); // Sum(20) + res21 = fma52lo(res21, a[4], a[17]); // Sum(21) + res22 = fma52hi(res22, a[4], a[17]); // Sum(21) + res22 = fma52lo(res22, a[5], a[17]); // Sum(22) + res23 = fma52hi(res23, a[5], a[17]); // Sum(22) + res23 = fma52lo(res23, a[6], a[17]); // Sum(23) + res24 = fma52hi(res24, a[6], a[17]); // Sum(23) + res18 = fma52lo(res18, a[0], a[18]); // Sum(18) + res19 = fma52hi(res19, a[0], a[18]); // Sum(18) + res19 = fma52lo(res19, a[1], a[18]); // Sum(19) + res20 = fma52hi(res20, a[1], a[18]); // Sum(19) + res20 = fma52lo(res20, a[2], a[18]); // Sum(20) + res21 = fma52hi(res21, a[2], a[18]); // Sum(20) + res21 = fma52lo(res21, a[3], a[18]); // Sum(21) + res22 = fma52hi(res22, a[3], a[18]); // Sum(21) + res22 = fma52lo(res22, a[4], a[18]); // Sum(22) + res23 = fma52hi(res23, a[4], a[18]); // Sum(22) + res23 = fma52lo(res23, a[5], a[18]); // Sum(23) + res24 = fma52hi(res24, a[5], a[18]); // Sum(23) + res19 = fma52lo(res19, a[0], a[19]); // Sum(19) + res20 = fma52hi(res20, a[0], a[19]); // Sum(19) + res20 = fma52lo(res20, a[1], a[19]); // Sum(20) + res21 = fma52hi(res21, a[1], a[19]); // Sum(20) + res21 = fma52lo(res21, a[2], a[19]); // Sum(21) + res22 = fma52hi(res22, a[2], a[19]); // Sum(21) + res22 = fma52lo(res22, a[3], a[19]); // Sum(22) + res23 = fma52hi(res23, a[3], a[19]); // Sum(22) + res23 = fma52lo(res23, a[4], a[19]); // Sum(23) + res24 = fma52hi(res24, a[4], a[19]); // Sum(23) + res12 = add64(res12, res12); // Double(12) + res13 = add64(res13, res13); // Double(13) + res14 = add64(res14, res14); // Double(14) + res15 = add64(res15, res15); // Double(15) + res16 = add64(res16, res16); // Double(16) + res17 = add64(res17, res17); // Double(17) + res18 = add64(res18, res18); // Double(18) + res19 = add64(res19, res19); // Double(19) + res20 = add64(res20, res20); // Double(20) + res21 = add64(res21, res21); // Double(21) + res22 = add64(res22, res22); // Double(22) + res23 = add64(res23, res23); // Double(23) + res12 = fma52lo(res12, a[6], a[6]); // Add sqr(12) + res13 = fma52hi(res13, a[6], a[6]); // Add sqr(12) + res14 = fma52lo(res14, a[7], a[7]); // Add sqr(14) + res15 = fma52hi(res15, a[7], a[7]); // Add sqr(14) + res16 = fma52lo(res16, a[8], a[8]); // Add sqr(16) + res17 = fma52hi(res17, a[8], a[8]); // Add sqr(16) + res18 = fma52lo(res18, a[9], a[9]); // Add sqr(18) + res19 = fma52hi(res19, a[9], a[9]); // Add sqr(18) + res20 = fma52lo(res20, a[10], a[10]); // Add sqr(20) + res21 = fma52hi(res21, a[10], a[10]); // Add sqr(20) + res22 = fma52lo(res22, a[11], a[11]); // Add sqr(22) + res23 = fma52hi(res23, a[11], a[11]); // Add sqr(22) + res24 = fma52lo(res24, a[11], a[13]); // Sum(24) + res25 = fma52hi(res25, a[11], a[13]); // Sum(24) + res25 = fma52lo(res25, a[12], a[13]); // Sum(25) + res26 = fma52hi(res26, a[12], a[13]); // Sum(25) + res24 = fma52lo(res24, a[10], a[14]); // Sum(24) + res25 = fma52hi(res25, a[10], a[14]); // Sum(24) + res25 = fma52lo(res25, a[11], a[14]); // Sum(25) + res26 = fma52hi(res26, a[11], a[14]); // Sum(25) + res26 = fma52lo(res26, a[12], a[14]); // Sum(26) + res27 = fma52hi(res27, a[12], a[14]); // Sum(26) + res27 = fma52lo(res27, a[13], a[14]); // Sum(27) + res28 = fma52hi(res28, a[13], a[14]); // Sum(27) + res24 = fma52lo(res24, a[9], a[15]); // Sum(24) + res25 = fma52hi(res25, a[9], a[15]); // Sum(24) + res25 = fma52lo(res25, a[10], a[15]); // Sum(25) + res26 = fma52hi(res26, a[10], a[15]); // Sum(25) + res26 = fma52lo(res26, a[11], a[15]); // Sum(26) + res27 = fma52hi(res27, a[11], a[15]); // Sum(26) + res27 = fma52lo(res27, a[12], a[15]); // Sum(27) + res28 = fma52hi(res28, a[12], a[15]); // Sum(27) + res28 = fma52lo(res28, a[13], a[15]); // Sum(28) + res29 = fma52hi(res29, a[13], a[15]); // Sum(28) + res29 = fma52lo(res29, a[14], a[15]); // Sum(29) + res30 = fma52hi(res30, a[14], a[15]); // Sum(29) + res24 = fma52lo(res24, a[8], a[16]); // Sum(24) + res25 = fma52hi(res25, a[8], a[16]); // Sum(24) + res25 = fma52lo(res25, a[9], a[16]); // Sum(25) + res26 = fma52hi(res26, a[9], a[16]); // Sum(25) + res26 = fma52lo(res26, a[10], a[16]); // Sum(26) + res27 = fma52hi(res27, a[10], a[16]); // Sum(26) + res27 = fma52lo(res27, a[11], a[16]); // Sum(27) + res28 = fma52hi(res28, a[11], a[16]); // Sum(27) + res28 = fma52lo(res28, a[12], a[16]); // Sum(28) + res29 = fma52hi(res29, a[12], a[16]); // Sum(28) + res29 = fma52lo(res29, a[13], a[16]); // Sum(29) + res30 = fma52hi(res30, a[13], a[16]); // Sum(29) + res30 = fma52lo(res30, a[14], a[16]); // Sum(30) + res31 = fma52hi(res31, a[14], a[16]); // Sum(30) + res31 = fma52lo(res31, a[15], a[16]); // Sum(31) + res32 = fma52hi(res32, a[15], a[16]); // Sum(31) + res24 = fma52lo(res24, a[7], a[17]); // Sum(24) + res25 = fma52hi(res25, a[7], a[17]); // Sum(24) + res25 = fma52lo(res25, a[8], a[17]); // Sum(25) + res26 = fma52hi(res26, a[8], a[17]); // Sum(25) + res26 = fma52lo(res26, a[9], a[17]); // Sum(26) + res27 = fma52hi(res27, a[9], a[17]); // Sum(26) + res27 = fma52lo(res27, a[10], a[17]); // Sum(27) + res28 = fma52hi(res28, a[10], a[17]); // Sum(27) + res28 = fma52lo(res28, a[11], a[17]); // Sum(28) + res29 = fma52hi(res29, a[11], a[17]); // Sum(28) + res29 = fma52lo(res29, a[12], a[17]); // Sum(29) + res30 = fma52hi(res30, a[12], a[17]); // Sum(29) + res30 = fma52lo(res30, a[13], a[17]); // Sum(30) + res31 = fma52hi(res31, a[13], a[17]); // Sum(30) + res31 = fma52lo(res31, a[14], a[17]); // Sum(31) + res32 = fma52hi(res32, a[14], a[17]); // Sum(31) + res32 = fma52lo(res32, a[15], a[17]); // Sum(32) + res33 = fma52hi(res33, a[15], a[17]); // Sum(32) + res33 = fma52lo(res33, a[16], a[17]); // Sum(33) + res34 = fma52hi(res34, a[16], a[17]); // Sum(33) + res24 = fma52lo(res24, a[6], a[18]); // Sum(24) + res25 = fma52hi(res25, a[6], a[18]); // Sum(24) + res25 = fma52lo(res25, a[7], a[18]); // Sum(25) + res26 = fma52hi(res26, a[7], a[18]); // Sum(25) + res26 = fma52lo(res26, a[8], a[18]); // Sum(26) + res27 = fma52hi(res27, a[8], a[18]); // Sum(26) + res27 = fma52lo(res27, a[9], a[18]); // Sum(27) + res28 = fma52hi(res28, a[9], a[18]); // Sum(27) + res28 = fma52lo(res28, a[10], a[18]); // Sum(28) + res29 = fma52hi(res29, a[10], a[18]); // Sum(28) + res29 = fma52lo(res29, a[11], a[18]); // Sum(29) + res30 = fma52hi(res30, a[11], a[18]); // Sum(29) + res30 = fma52lo(res30, a[12], a[18]); // Sum(30) + res31 = fma52hi(res31, a[12], a[18]); // Sum(30) + res31 = fma52lo(res31, a[13], a[18]); // Sum(31) + res32 = fma52hi(res32, a[13], a[18]); // Sum(31) + res32 = fma52lo(res32, a[14], a[18]); // Sum(32) + res33 = fma52hi(res33, a[14], a[18]); // Sum(32) + res33 = fma52lo(res33, a[15], a[18]); // Sum(33) + res34 = fma52hi(res34, a[15], a[18]); // Sum(33) + res34 = fma52lo(res34, a[16], a[18]); // Sum(34) + res35 = fma52hi(res35, a[16], a[18]); // Sum(34) + res35 = fma52lo(res35, a[17], a[18]); // Sum(35) + res36 = fma52hi(res36, a[17], a[18]); // Sum(35) + res24 = fma52lo(res24, a[5], a[19]); // Sum(24) + res25 = fma52hi(res25, a[5], a[19]); // Sum(24) + res25 = fma52lo(res25, a[6], a[19]); // Sum(25) + res26 = fma52hi(res26, a[6], a[19]); // Sum(25) + res26 = fma52lo(res26, a[7], a[19]); // Sum(26) + res27 = fma52hi(res27, a[7], a[19]); // Sum(26) + res27 = fma52lo(res27, a[8], a[19]); // Sum(27) + res28 = fma52hi(res28, a[8], a[19]); // Sum(27) + res28 = fma52lo(res28, a[9], a[19]); // Sum(28) + res29 = fma52hi(res29, a[9], a[19]); // Sum(28) + res29 = fma52lo(res29, a[10], a[19]); // Sum(29) + res30 = fma52hi(res30, a[10], a[19]); // Sum(29) + res30 = fma52lo(res30, a[11], a[19]); // Sum(30) + res31 = fma52hi(res31, a[11], a[19]); // Sum(30) + res31 = fma52lo(res31, a[12], a[19]); // Sum(31) + res32 = fma52hi(res32, a[12], a[19]); // Sum(31) + res32 = fma52lo(res32, a[13], a[19]); // Sum(32) + res33 = fma52hi(res33, a[13], a[19]); // Sum(32) + res33 = fma52lo(res33, a[14], a[19]); // Sum(33) + res34 = fma52hi(res34, a[14], a[19]); // Sum(33) + res34 = fma52lo(res34, a[15], a[19]); // Sum(34) + res35 = fma52hi(res35, a[15], a[19]); // Sum(34) + res35 = fma52lo(res35, a[16], a[19]); // Sum(35) + res36 = fma52hi(res36, a[16], a[19]); // Sum(35) + res24 = add64(res24, res24); // Double(24) + res25 = add64(res25, res25); // Double(25) + res26 = add64(res26, res26); // Double(26) + res27 = add64(res27, res27); // Double(27) + res28 = add64(res28, res28); // Double(28) + res29 = add64(res29, res29); // Double(29) + res30 = add64(res30, res30); // Double(30) + res31 = add64(res31, res31); // Double(31) + res32 = add64(res32, res32); // Double(32) + res33 = add64(res33, res33); // Double(33) + res34 = add64(res34, res34); // Double(34) + res35 = add64(res35, res35); // Double(35) + res24 = fma52lo(res24, a[12], a[12]); // Add sqr(24) + res25 = fma52hi(res25, a[12], a[12]); // Add sqr(24) + res26 = fma52lo(res26, a[13], a[13]); // Add sqr(26) + res27 = fma52hi(res27, a[13], a[13]); // Add sqr(26) + res28 = fma52lo(res28, a[14], a[14]); // Add sqr(28) + res29 = fma52hi(res29, a[14], a[14]); // Add sqr(28) + res30 = fma52lo(res30, a[15], a[15]); // Add sqr(30) + res31 = fma52hi(res31, a[15], a[15]); // Add sqr(30) + res32 = fma52lo(res32, a[16], a[16]); // Add sqr(32) + res33 = fma52hi(res33, a[16], a[16]); // Add sqr(32) + res34 = fma52lo(res34, a[17], a[17]); // Add sqr(34) + res35 = fma52hi(res35, a[17], a[17]); // Add sqr(34) + res36 = fma52lo(res36, a[17], a[19]); // Sum(36) + res37 = fma52hi(res37, a[17], a[19]); // Sum(36) + res37 = fma52lo(res37, a[18], a[19]); // Sum(37) + res38 = fma52hi(res38, a[18], a[19]); // Sum(37) + res36 = add64(res36, res36); // Double(36) + res37 = add64(res37, res37); // Double(37) + res38 = add64(res38, res38); // Double(38) + res36 = fma52lo(res36, a[18], a[18]); // Add sqr(36) + res37 = fma52hi(res37, a[18], a[18]); // Add sqr(36) + res38 = fma52lo(res38, a[19], a[19]); // Add sqr(38) + res39 = fma52hi(res39, a[19], a[19]); // Add sqr(38) + + // Generate u_i + U64 u0 = mul52lo(res0, k); + ASM("jmp l0\nl0:\n"); + + // Create u0 + fma52lo_mem(res0, res0, u0, m, SIMD_BYTES * 0); + fma52hi_mem(res1, res1, u0, m, SIMD_BYTES * 0); + res1 = fma52lo(res1, u0, m[1]); + res2 = fma52hi(res2, u0, m[1]); + res1 = add64(res1, srli64(res0, DIGIT_SIZE)); + U64 u1 = mul52lo(res1, k); + fma52lo_mem(res2, res2, u0, m, SIMD_BYTES * 2); + fma52hi_mem(res3, res3, u0, m, SIMD_BYTES * 2); + res3 = fma52lo(res3, u0, m[3]); + res4 = fma52hi(res4, u0, m[3]); + fma52lo_mem(res4, res4, u0, m, SIMD_BYTES * 4); + fma52hi_mem(res5, res5, u0, m, SIMD_BYTES * 4); + res5 = fma52lo(res5, u0, m[5]); + res6 = fma52hi(res6, u0, m[5]); + fma52lo_mem(res6, res6, u0, m, SIMD_BYTES * 6); + fma52hi_mem(res7, res7, u0, m, SIMD_BYTES * 6); + res7 = fma52lo(res7, u0, m[7]); + res8 = fma52hi(res8, u0, m[7]); + fma52lo_mem(res8, res8, u0, m, SIMD_BYTES * 8); + fma52hi_mem(res9, res9, u0, m, SIMD_BYTES * 8); + res9 = fma52lo(res9, u0, m[9]); + res10 = fma52hi(res10, u0, m[9]); + fma52lo_mem(res10, res10, u0, m, SIMD_BYTES * 10); + fma52hi_mem(res11, res11, u0, m, SIMD_BYTES * 10); + res11 = fma52lo(res11, u0, m[11]); + res12 = fma52hi(res12, u0, m[11]); + fma52lo_mem(res12, res12, u0, m, SIMD_BYTES * 12); + fma52hi_mem(res13, res13, u0, m, SIMD_BYTES * 12); + res13 = fma52lo(res13, u0, m[13]); + res14 = fma52hi(res14, u0, m[13]); + fma52lo_mem(res14, res14, u0, m, SIMD_BYTES * 14); + fma52hi_mem(res15, res15, u0, m, SIMD_BYTES * 14); + res15 = fma52lo(res15, u0, m[15]); + res16 = fma52hi(res16, u0, m[15]); + fma52lo_mem(res16, res16, u0, m, SIMD_BYTES * 16); + fma52hi_mem(res17, res17, u0, m, SIMD_BYTES * 16); + res17 = fma52lo(res17, u0, m[17]); + res18 = fma52hi(res18, u0, m[17]); + fma52lo_mem(res18, res18, u0, m, SIMD_BYTES * 18); + fma52hi_mem(res19, res19, u0, m, SIMD_BYTES * 18); + res19 = fma52lo(res19, u0, m[19]); + res20 = fma52hi(res20, u0, m[19]); + + // Create u1 + fma52lo_mem(res1, res1, u1, m, SIMD_BYTES * 0); + fma52hi_mem(res2, res2, u1, m, SIMD_BYTES * 0); + res2 = fma52lo(res2, u1, m[1]); + res3 = fma52hi(res3, u1, m[1]); + res2 = add64(res2, srli64(res1, DIGIT_SIZE)); + U64 u2 = mul52lo(res2, k); + fma52lo_mem(res3, res3, u1, m, SIMD_BYTES * 2); + fma52hi_mem(res4, res4, u1, m, SIMD_BYTES * 2); + res4 = fma52lo(res4, u1, m[3]); + res5 = fma52hi(res5, u1, m[3]); + fma52lo_mem(res5, res5, u1, m, SIMD_BYTES * 4); + fma52hi_mem(res6, res6, u1, m, SIMD_BYTES * 4); + res6 = fma52lo(res6, u1, m[5]); + res7 = fma52hi(res7, u1, m[5]); + fma52lo_mem(res7, res7, u1, m, SIMD_BYTES * 6); + fma52hi_mem(res8, res8, u1, m, SIMD_BYTES * 6); + res8 = fma52lo(res8, u1, m[7]); + res9 = fma52hi(res9, u1, m[7]); + fma52lo_mem(res9, res9, u1, m, SIMD_BYTES * 8); + fma52hi_mem(res10, res10, u1, m, SIMD_BYTES * 8); + res10 = fma52lo(res10, u1, m[9]); + res11 = fma52hi(res11, u1, m[9]); + fma52lo_mem(res11, res11, u1, m, SIMD_BYTES * 10); + fma52hi_mem(res12, res12, u1, m, SIMD_BYTES * 10); + res12 = fma52lo(res12, u1, m[11]); + res13 = fma52hi(res13, u1, m[11]); + fma52lo_mem(res13, res13, u1, m, SIMD_BYTES * 12); + fma52hi_mem(res14, res14, u1, m, SIMD_BYTES * 12); + res14 = fma52lo(res14, u1, m[13]); + res15 = fma52hi(res15, u1, m[13]); + fma52lo_mem(res15, res15, u1, m, SIMD_BYTES * 14); + fma52hi_mem(res16, res16, u1, m, SIMD_BYTES * 14); + res16 = fma52lo(res16, u1, m[15]); + res17 = fma52hi(res17, u1, m[15]); + fma52lo_mem(res17, res17, u1, m, SIMD_BYTES * 16); + fma52hi_mem(res18, res18, u1, m, SIMD_BYTES * 16); + res18 = fma52lo(res18, u1, m[17]); + res19 = fma52hi(res19, u1, m[17]); + fma52lo_mem(res19, res19, u1, m, SIMD_BYTES * 18); + fma52hi_mem(res20, res20, u1, m, SIMD_BYTES * 18); + res20 = fma52lo(res20, u1, m[19]); + res21 = fma52hi(res21, u1, m[19]); + ASM("jmp l2\nl2:\n"); + + // Create u2 + fma52lo_mem(res2, res2, u2, m, SIMD_BYTES * 0); + fma52hi_mem(res3, res3, u2, m, SIMD_BYTES * 0); + res3 = fma52lo(res3, u2, m[1]); + res4 = fma52hi(res4, u2, m[1]); + res3 = add64(res3, srli64(res2, DIGIT_SIZE)); + U64 u3 = mul52lo(res3, k); + fma52lo_mem(res4, res4, u2, m, SIMD_BYTES * 2); + fma52hi_mem(res5, res5, u2, m, SIMD_BYTES * 2); + res5 = fma52lo(res5, u2, m[3]); + res6 = fma52hi(res6, u2, m[3]); + fma52lo_mem(res6, res6, u2, m, SIMD_BYTES * 4); + fma52hi_mem(res7, res7, u2, m, SIMD_BYTES * 4); + res7 = fma52lo(res7, u2, m[5]); + res8 = fma52hi(res8, u2, m[5]); + fma52lo_mem(res8, res8, u2, m, SIMD_BYTES * 6); + fma52hi_mem(res9, res9, u2, m, SIMD_BYTES * 6); + res9 = fma52lo(res9, u2, m[7]); + res10 = fma52hi(res10, u2, m[7]); + fma52lo_mem(res10, res10, u2, m, SIMD_BYTES * 8); + fma52hi_mem(res11, res11, u2, m, SIMD_BYTES * 8); + res11 = fma52lo(res11, u2, m[9]); + res12 = fma52hi(res12, u2, m[9]); + fma52lo_mem(res12, res12, u2, m, SIMD_BYTES * 10); + fma52hi_mem(res13, res13, u2, m, SIMD_BYTES * 10); + res13 = fma52lo(res13, u2, m[11]); + res14 = fma52hi(res14, u2, m[11]); + fma52lo_mem(res14, res14, u2, m, SIMD_BYTES * 12); + fma52hi_mem(res15, res15, u2, m, SIMD_BYTES * 12); + res15 = fma52lo(res15, u2, m[13]); + res16 = fma52hi(res16, u2, m[13]); + fma52lo_mem(res16, res16, u2, m, SIMD_BYTES * 14); + fma52hi_mem(res17, res17, u2, m, SIMD_BYTES * 14); + res17 = fma52lo(res17, u2, m[15]); + res18 = fma52hi(res18, u2, m[15]); + fma52lo_mem(res18, res18, u2, m, SIMD_BYTES * 16); + fma52hi_mem(res19, res19, u2, m, SIMD_BYTES * 16); + res19 = fma52lo(res19, u2, m[17]); + res20 = fma52hi(res20, u2, m[17]); + fma52lo_mem(res20, res20, u2, m, SIMD_BYTES * 18); + fma52hi_mem(res21, res21, u2, m, SIMD_BYTES * 18); + res21 = fma52lo(res21, u2, m[19]); + res22 = fma52hi(res22, u2, m[19]); + + // Create u3 + fma52lo_mem(res3, res3, u3, m, SIMD_BYTES * 0); + fma52hi_mem(res4, res4, u3, m, SIMD_BYTES * 0); + res4 = fma52lo(res4, u3, m[1]); + res5 = fma52hi(res5, u3, m[1]); + res4 = add64(res4, srli64(res3, DIGIT_SIZE)); + U64 u4 = mul52lo(res4, k); + fma52lo_mem(res5, res5, u3, m, SIMD_BYTES * 2); + fma52hi_mem(res6, res6, u3, m, SIMD_BYTES * 2); + res6 = fma52lo(res6, u3, m[3]); + res7 = fma52hi(res7, u3, m[3]); + fma52lo_mem(res7, res7, u3, m, SIMD_BYTES * 4); + fma52hi_mem(res8, res8, u3, m, SIMD_BYTES * 4); + res8 = fma52lo(res8, u3, m[5]); + res9 = fma52hi(res9, u3, m[5]); + fma52lo_mem(res9, res9, u3, m, SIMD_BYTES * 6); + fma52hi_mem(res10, res10, u3, m, SIMD_BYTES * 6); + res10 = fma52lo(res10, u3, m[7]); + res11 = fma52hi(res11, u3, m[7]); + fma52lo_mem(res11, res11, u3, m, SIMD_BYTES * 8); + fma52hi_mem(res12, res12, u3, m, SIMD_BYTES * 8); + res12 = fma52lo(res12, u3, m[9]); + res13 = fma52hi(res13, u3, m[9]); + fma52lo_mem(res13, res13, u3, m, SIMD_BYTES * 10); + fma52hi_mem(res14, res14, u3, m, SIMD_BYTES * 10); + res14 = fma52lo(res14, u3, m[11]); + res15 = fma52hi(res15, u3, m[11]); + fma52lo_mem(res15, res15, u3, m, SIMD_BYTES * 12); + fma52hi_mem(res16, res16, u3, m, SIMD_BYTES * 12); + res16 = fma52lo(res16, u3, m[13]); + res17 = fma52hi(res17, u3, m[13]); + fma52lo_mem(res17, res17, u3, m, SIMD_BYTES * 14); + fma52hi_mem(res18, res18, u3, m, SIMD_BYTES * 14); + res18 = fma52lo(res18, u3, m[15]); + res19 = fma52hi(res19, u3, m[15]); + fma52lo_mem(res19, res19, u3, m, SIMD_BYTES * 16); + fma52hi_mem(res20, res20, u3, m, SIMD_BYTES * 16); + res20 = fma52lo(res20, u3, m[17]); + res21 = fma52hi(res21, u3, m[17]); + fma52lo_mem(res21, res21, u3, m, SIMD_BYTES * 18); + fma52hi_mem(res22, res22, u3, m, SIMD_BYTES * 18); + res22 = fma52lo(res22, u3, m[19]); + res23 = fma52hi(res23, u3, m[19]); + ASM("jmp l4\nl4:\n"); + + // Create u4 + fma52lo_mem(res4, res4, u4, m, SIMD_BYTES * 0); + fma52hi_mem(res5, res5, u4, m, SIMD_BYTES * 0); + res5 = fma52lo(res5, u4, m[1]); + res6 = fma52hi(res6, u4, m[1]); + res5 = add64(res5, srli64(res4, DIGIT_SIZE)); + U64 u5 = mul52lo(res5, k); + fma52lo_mem(res6, res6, u4, m, SIMD_BYTES * 2); + fma52hi_mem(res7, res7, u4, m, SIMD_BYTES * 2); + res7 = fma52lo(res7, u4, m[3]); + res8 = fma52hi(res8, u4, m[3]); + fma52lo_mem(res8, res8, u4, m, SIMD_BYTES * 4); + fma52hi_mem(res9, res9, u4, m, SIMD_BYTES * 4); + res9 = fma52lo(res9, u4, m[5]); + res10 = fma52hi(res10, u4, m[5]); + fma52lo_mem(res10, res10, u4, m, SIMD_BYTES * 6); + fma52hi_mem(res11, res11, u4, m, SIMD_BYTES * 6); + res11 = fma52lo(res11, u4, m[7]); + res12 = fma52hi(res12, u4, m[7]); + fma52lo_mem(res12, res12, u4, m, SIMD_BYTES * 8); + fma52hi_mem(res13, res13, u4, m, SIMD_BYTES * 8); + res13 = fma52lo(res13, u4, m[9]); + res14 = fma52hi(res14, u4, m[9]); + fma52lo_mem(res14, res14, u4, m, SIMD_BYTES * 10); + fma52hi_mem(res15, res15, u4, m, SIMD_BYTES * 10); + res15 = fma52lo(res15, u4, m[11]); + res16 = fma52hi(res16, u4, m[11]); + fma52lo_mem(res16, res16, u4, m, SIMD_BYTES * 12); + fma52hi_mem(res17, res17, u4, m, SIMD_BYTES * 12); + res17 = fma52lo(res17, u4, m[13]); + res18 = fma52hi(res18, u4, m[13]); + fma52lo_mem(res18, res18, u4, m, SIMD_BYTES * 14); + fma52hi_mem(res19, res19, u4, m, SIMD_BYTES * 14); + res19 = fma52lo(res19, u4, m[15]); + res20 = fma52hi(res20, u4, m[15]); + fma52lo_mem(res20, res20, u4, m, SIMD_BYTES * 16); + fma52hi_mem(res21, res21, u4, m, SIMD_BYTES * 16); + res21 = fma52lo(res21, u4, m[17]); + res22 = fma52hi(res22, u4, m[17]); + fma52lo_mem(res22, res22, u4, m, SIMD_BYTES * 18); + fma52hi_mem(res23, res23, u4, m, SIMD_BYTES * 18); + res23 = fma52lo(res23, u4, m[19]); + res24 = fma52hi(res24, u4, m[19]); + + // Create u5 + fma52lo_mem(res5, res5, u5, m, SIMD_BYTES * 0); + fma52hi_mem(res6, res6, u5, m, SIMD_BYTES * 0); + res6 = fma52lo(res6, u5, m[1]); + res7 = fma52hi(res7, u5, m[1]); + res6 = add64(res6, srli64(res5, DIGIT_SIZE)); + U64 u6 = mul52lo(res6, k); + fma52lo_mem(res7, res7, u5, m, SIMD_BYTES * 2); + fma52hi_mem(res8, res8, u5, m, SIMD_BYTES * 2); + res8 = fma52lo(res8, u5, m[3]); + res9 = fma52hi(res9, u5, m[3]); + fma52lo_mem(res9, res9, u5, m, SIMD_BYTES * 4); + fma52hi_mem(res10, res10, u5, m, SIMD_BYTES * 4); + res10 = fma52lo(res10, u5, m[5]); + res11 = fma52hi(res11, u5, m[5]); + fma52lo_mem(res11, res11, u5, m, SIMD_BYTES * 6); + fma52hi_mem(res12, res12, u5, m, SIMD_BYTES * 6); + res12 = fma52lo(res12, u5, m[7]); + res13 = fma52hi(res13, u5, m[7]); + fma52lo_mem(res13, res13, u5, m, SIMD_BYTES * 8); + fma52hi_mem(res14, res14, u5, m, SIMD_BYTES * 8); + res14 = fma52lo(res14, u5, m[9]); + res15 = fma52hi(res15, u5, m[9]); + fma52lo_mem(res15, res15, u5, m, SIMD_BYTES * 10); + fma52hi_mem(res16, res16, u5, m, SIMD_BYTES * 10); + res16 = fma52lo(res16, u5, m[11]); + res17 = fma52hi(res17, u5, m[11]); + fma52lo_mem(res17, res17, u5, m, SIMD_BYTES * 12); + fma52hi_mem(res18, res18, u5, m, SIMD_BYTES * 12); + res18 = fma52lo(res18, u5, m[13]); + res19 = fma52hi(res19, u5, m[13]); + fma52lo_mem(res19, res19, u5, m, SIMD_BYTES * 14); + fma52hi_mem(res20, res20, u5, m, SIMD_BYTES * 14); + res20 = fma52lo(res20, u5, m[15]); + res21 = fma52hi(res21, u5, m[15]); + fma52lo_mem(res21, res21, u5, m, SIMD_BYTES * 16); + fma52hi_mem(res22, res22, u5, m, SIMD_BYTES * 16); + res22 = fma52lo(res22, u5, m[17]); + res23 = fma52hi(res23, u5, m[17]); + fma52lo_mem(res23, res23, u5, m, SIMD_BYTES * 18); + fma52hi_mem(res24, res24, u5, m, SIMD_BYTES * 18); + res24 = fma52lo(res24, u5, m[19]); + res25 = fma52hi(res25, u5, m[19]); + ASM("jmp l6\nl6:\n"); + + // Create u6 + fma52lo_mem(res6, res6, u6, m, SIMD_BYTES * 0); + fma52hi_mem(res7, res7, u6, m, SIMD_BYTES * 0); + res7 = fma52lo(res7, u6, m[1]); + res8 = fma52hi(res8, u6, m[1]); + res7 = add64(res7, srli64(res6, DIGIT_SIZE)); + U64 u7 = mul52lo(res7, k); + fma52lo_mem(res8, res8, u6, m, SIMD_BYTES * 2); + fma52hi_mem(res9, res9, u6, m, SIMD_BYTES * 2); + res9 = fma52lo(res9, u6, m[3]); + res10 = fma52hi(res10, u6, m[3]); + fma52lo_mem(res10, res10, u6, m, SIMD_BYTES * 4); + fma52hi_mem(res11, res11, u6, m, SIMD_BYTES * 4); + res11 = fma52lo(res11, u6, m[5]); + res12 = fma52hi(res12, u6, m[5]); + fma52lo_mem(res12, res12, u6, m, SIMD_BYTES * 6); + fma52hi_mem(res13, res13, u6, m, SIMD_BYTES * 6); + res13 = fma52lo(res13, u6, m[7]); + res14 = fma52hi(res14, u6, m[7]); + fma52lo_mem(res14, res14, u6, m, SIMD_BYTES * 8); + fma52hi_mem(res15, res15, u6, m, SIMD_BYTES * 8); + res15 = fma52lo(res15, u6, m[9]); + res16 = fma52hi(res16, u6, m[9]); + fma52lo_mem(res16, res16, u6, m, SIMD_BYTES * 10); + fma52hi_mem(res17, res17, u6, m, SIMD_BYTES * 10); + res17 = fma52lo(res17, u6, m[11]); + res18 = fma52hi(res18, u6, m[11]); + fma52lo_mem(res18, res18, u6, m, SIMD_BYTES * 12); + fma52hi_mem(res19, res19, u6, m, SIMD_BYTES * 12); + res19 = fma52lo(res19, u6, m[13]); + res20 = fma52hi(res20, u6, m[13]); + fma52lo_mem(res20, res20, u6, m, SIMD_BYTES * 14); + fma52hi_mem(res21, res21, u6, m, SIMD_BYTES * 14); + res21 = fma52lo(res21, u6, m[15]); + res22 = fma52hi(res22, u6, m[15]); + fma52lo_mem(res22, res22, u6, m, SIMD_BYTES * 16); + fma52hi_mem(res23, res23, u6, m, SIMD_BYTES * 16); + res23 = fma52lo(res23, u6, m[17]); + res24 = fma52hi(res24, u6, m[17]); + fma52lo_mem(res24, res24, u6, m, SIMD_BYTES * 18); + fma52hi_mem(res25, res25, u6, m, SIMD_BYTES * 18); + res25 = fma52lo(res25, u6, m[19]); + res26 = fma52hi(res26, u6, m[19]); + + // Create u7 + fma52lo_mem(res7, res7, u7, m, SIMD_BYTES * 0); + fma52hi_mem(res8, res8, u7, m, SIMD_BYTES * 0); + res8 = fma52lo(res8, u7, m[1]); + res9 = fma52hi(res9, u7, m[1]); + res8 = add64(res8, srli64(res7, DIGIT_SIZE)); + U64 u8 = mul52lo(res8, k); + fma52lo_mem(res9, res9, u7, m, SIMD_BYTES * 2); + fma52hi_mem(res10, res10, u7, m, SIMD_BYTES * 2); + res10 = fma52lo(res10, u7, m[3]); + res11 = fma52hi(res11, u7, m[3]); + fma52lo_mem(res11, res11, u7, m, SIMD_BYTES * 4); + fma52hi_mem(res12, res12, u7, m, SIMD_BYTES * 4); + res12 = fma52lo(res12, u7, m[5]); + res13 = fma52hi(res13, u7, m[5]); + fma52lo_mem(res13, res13, u7, m, SIMD_BYTES * 6); + fma52hi_mem(res14, res14, u7, m, SIMD_BYTES * 6); + res14 = fma52lo(res14, u7, m[7]); + res15 = fma52hi(res15, u7, m[7]); + fma52lo_mem(res15, res15, u7, m, SIMD_BYTES * 8); + fma52hi_mem(res16, res16, u7, m, SIMD_BYTES * 8); + res16 = fma52lo(res16, u7, m[9]); + res17 = fma52hi(res17, u7, m[9]); + fma52lo_mem(res17, res17, u7, m, SIMD_BYTES * 10); + fma52hi_mem(res18, res18, u7, m, SIMD_BYTES * 10); + res18 = fma52lo(res18, u7, m[11]); + res19 = fma52hi(res19, u7, m[11]); + fma52lo_mem(res19, res19, u7, m, SIMD_BYTES * 12); + fma52hi_mem(res20, res20, u7, m, SIMD_BYTES * 12); + res20 = fma52lo(res20, u7, m[13]); + res21 = fma52hi(res21, u7, m[13]); + fma52lo_mem(res21, res21, u7, m, SIMD_BYTES * 14); + fma52hi_mem(res22, res22, u7, m, SIMD_BYTES * 14); + res22 = fma52lo(res22, u7, m[15]); + res23 = fma52hi(res23, u7, m[15]); + fma52lo_mem(res23, res23, u7, m, SIMD_BYTES * 16); + fma52hi_mem(res24, res24, u7, m, SIMD_BYTES * 16); + res24 = fma52lo(res24, u7, m[17]); + res25 = fma52hi(res25, u7, m[17]); + fma52lo_mem(res25, res25, u7, m, SIMD_BYTES * 18); + fma52hi_mem(res26, res26, u7, m, SIMD_BYTES * 18); + res26 = fma52lo(res26, u7, m[19]); + res27 = fma52hi(res27, u7, m[19]); + ASM("jmp l8\nl8:\n"); + + // Create u8 + fma52lo_mem(res8, res8, u8, m, SIMD_BYTES * 0); + fma52hi_mem(res9, res9, u8, m, SIMD_BYTES * 0); + res9 = fma52lo(res9, u8, m[1]); + res10 = fma52hi(res10, u8, m[1]); + res9 = add64(res9, srli64(res8, DIGIT_SIZE)); + U64 u9 = mul52lo(res9, k); + fma52lo_mem(res10, res10, u8, m, SIMD_BYTES * 2); + fma52hi_mem(res11, res11, u8, m, SIMD_BYTES * 2); + res11 = fma52lo(res11, u8, m[3]); + res12 = fma52hi(res12, u8, m[3]); + fma52lo_mem(res12, res12, u8, m, SIMD_BYTES * 4); + fma52hi_mem(res13, res13, u8, m, SIMD_BYTES * 4); + res13 = fma52lo(res13, u8, m[5]); + res14 = fma52hi(res14, u8, m[5]); + fma52lo_mem(res14, res14, u8, m, SIMD_BYTES * 6); + fma52hi_mem(res15, res15, u8, m, SIMD_BYTES * 6); + res15 = fma52lo(res15, u8, m[7]); + res16 = fma52hi(res16, u8, m[7]); + fma52lo_mem(res16, res16, u8, m, SIMD_BYTES * 8); + fma52hi_mem(res17, res17, u8, m, SIMD_BYTES * 8); + res17 = fma52lo(res17, u8, m[9]); + res18 = fma52hi(res18, u8, m[9]); + fma52lo_mem(res18, res18, u8, m, SIMD_BYTES * 10); + fma52hi_mem(res19, res19, u8, m, SIMD_BYTES * 10); + res19 = fma52lo(res19, u8, m[11]); + res20 = fma52hi(res20, u8, m[11]); + fma52lo_mem(res20, res20, u8, m, SIMD_BYTES * 12); + fma52hi_mem(res21, res21, u8, m, SIMD_BYTES * 12); + res21 = fma52lo(res21, u8, m[13]); + res22 = fma52hi(res22, u8, m[13]); + fma52lo_mem(res22, res22, u8, m, SIMD_BYTES * 14); + fma52hi_mem(res23, res23, u8, m, SIMD_BYTES * 14); + res23 = fma52lo(res23, u8, m[15]); + res24 = fma52hi(res24, u8, m[15]); + fma52lo_mem(res24, res24, u8, m, SIMD_BYTES * 16); + fma52hi_mem(res25, res25, u8, m, SIMD_BYTES * 16); + res25 = fma52lo(res25, u8, m[17]); + res26 = fma52hi(res26, u8, m[17]); + fma52lo_mem(res26, res26, u8, m, SIMD_BYTES * 18); + fma52hi_mem(res27, res27, u8, m, SIMD_BYTES * 18); + res27 = fma52lo(res27, u8, m[19]); + res28 = fma52hi(res28, u8, m[19]); + + // Create u9 + fma52lo_mem(res9, res9, u9, m, SIMD_BYTES * 0); + fma52hi_mem(res10, res10, u9, m, SIMD_BYTES * 0); + res10 = fma52lo(res10, u9, m[1]); + res11 = fma52hi(res11, u9, m[1]); + res10 = add64(res10, srli64(res9, DIGIT_SIZE)); + U64 u10 = mul52lo(res10, k); + fma52lo_mem(res11, res11, u9, m, SIMD_BYTES * 2); + fma52hi_mem(res12, res12, u9, m, SIMD_BYTES * 2); + res12 = fma52lo(res12, u9, m[3]); + res13 = fma52hi(res13, u9, m[3]); + fma52lo_mem(res13, res13, u9, m, SIMD_BYTES * 4); + fma52hi_mem(res14, res14, u9, m, SIMD_BYTES * 4); + res14 = fma52lo(res14, u9, m[5]); + res15 = fma52hi(res15, u9, m[5]); + fma52lo_mem(res15, res15, u9, m, SIMD_BYTES * 6); + fma52hi_mem(res16, res16, u9, m, SIMD_BYTES * 6); + res16 = fma52lo(res16, u9, m[7]); + res17 = fma52hi(res17, u9, m[7]); + fma52lo_mem(res17, res17, u9, m, SIMD_BYTES * 8); + fma52hi_mem(res18, res18, u9, m, SIMD_BYTES * 8); + res18 = fma52lo(res18, u9, m[9]); + res19 = fma52hi(res19, u9, m[9]); + fma52lo_mem(res19, res19, u9, m, SIMD_BYTES * 10); + fma52hi_mem(res20, res20, u9, m, SIMD_BYTES * 10); + res20 = fma52lo(res20, u9, m[11]); + res21 = fma52hi(res21, u9, m[11]); + fma52lo_mem(res21, res21, u9, m, SIMD_BYTES * 12); + fma52hi_mem(res22, res22, u9, m, SIMD_BYTES * 12); + res22 = fma52lo(res22, u9, m[13]); + res23 = fma52hi(res23, u9, m[13]); + fma52lo_mem(res23, res23, u9, m, SIMD_BYTES * 14); + fma52hi_mem(res24, res24, u9, m, SIMD_BYTES * 14); + res24 = fma52lo(res24, u9, m[15]); + res25 = fma52hi(res25, u9, m[15]); + fma52lo_mem(res25, res25, u9, m, SIMD_BYTES * 16); + fma52hi_mem(res26, res26, u9, m, SIMD_BYTES * 16); + res26 = fma52lo(res26, u9, m[17]); + res27 = fma52hi(res27, u9, m[17]); + fma52lo_mem(res27, res27, u9, m, SIMD_BYTES * 18); + fma52hi_mem(res28, res28, u9, m, SIMD_BYTES * 18); + res28 = fma52lo(res28, u9, m[19]); + res29 = fma52hi(res29, u9, m[19]); + ASM("jmp l10\nl10:\n"); + + // Create u10 + fma52lo_mem(res10, res10, u10, m, SIMD_BYTES * 0); + fma52hi_mem(res11, res11, u10, m, SIMD_BYTES * 0); + res11 = fma52lo(res11, u10, m[1]); + res12 = fma52hi(res12, u10, m[1]); + res11 = add64(res11, srli64(res10, DIGIT_SIZE)); + U64 u11 = mul52lo(res11, k); + fma52lo_mem(res12, res12, u10, m, SIMD_BYTES * 2); + fma52hi_mem(res13, res13, u10, m, SIMD_BYTES * 2); + res13 = fma52lo(res13, u10, m[3]); + res14 = fma52hi(res14, u10, m[3]); + fma52lo_mem(res14, res14, u10, m, SIMD_BYTES * 4); + fma52hi_mem(res15, res15, u10, m, SIMD_BYTES * 4); + res15 = fma52lo(res15, u10, m[5]); + res16 = fma52hi(res16, u10, m[5]); + fma52lo_mem(res16, res16, u10, m, SIMD_BYTES * 6); + fma52hi_mem(res17, res17, u10, m, SIMD_BYTES * 6); + res17 = fma52lo(res17, u10, m[7]); + res18 = fma52hi(res18, u10, m[7]); + fma52lo_mem(res18, res18, u10, m, SIMD_BYTES * 8); + fma52hi_mem(res19, res19, u10, m, SIMD_BYTES * 8); + res19 = fma52lo(res19, u10, m[9]); + res20 = fma52hi(res20, u10, m[9]); + fma52lo_mem(res20, res20, u10, m, SIMD_BYTES * 10); + fma52hi_mem(res21, res21, u10, m, SIMD_BYTES * 10); + res21 = fma52lo(res21, u10, m[11]); + res22 = fma52hi(res22, u10, m[11]); + fma52lo_mem(res22, res22, u10, m, SIMD_BYTES * 12); + fma52hi_mem(res23, res23, u10, m, SIMD_BYTES * 12); + res23 = fma52lo(res23, u10, m[13]); + res24 = fma52hi(res24, u10, m[13]); + fma52lo_mem(res24, res24, u10, m, SIMD_BYTES * 14); + fma52hi_mem(res25, res25, u10, m, SIMD_BYTES * 14); + res25 = fma52lo(res25, u10, m[15]); + res26 = fma52hi(res26, u10, m[15]); + fma52lo_mem(res26, res26, u10, m, SIMD_BYTES * 16); + fma52hi_mem(res27, res27, u10, m, SIMD_BYTES * 16); + res27 = fma52lo(res27, u10, m[17]); + res28 = fma52hi(res28, u10, m[17]); + fma52lo_mem(res28, res28, u10, m, SIMD_BYTES * 18); + fma52hi_mem(res29, res29, u10, m, SIMD_BYTES * 18); + res29 = fma52lo(res29, u10, m[19]); + res30 = fma52hi(res30, u10, m[19]); + + // Create u11 + fma52lo_mem(res11, res11, u11, m, SIMD_BYTES * 0); + fma52hi_mem(res12, res12, u11, m, SIMD_BYTES * 0); + res12 = fma52lo(res12, u11, m[1]); + res13 = fma52hi(res13, u11, m[1]); + res12 = add64(res12, srli64(res11, DIGIT_SIZE)); + U64 u12 = mul52lo(res12, k); + fma52lo_mem(res13, res13, u11, m, SIMD_BYTES * 2); + fma52hi_mem(res14, res14, u11, m, SIMD_BYTES * 2); + res14 = fma52lo(res14, u11, m[3]); + res15 = fma52hi(res15, u11, m[3]); + fma52lo_mem(res15, res15, u11, m, SIMD_BYTES * 4); + fma52hi_mem(res16, res16, u11, m, SIMD_BYTES * 4); + res16 = fma52lo(res16, u11, m[5]); + res17 = fma52hi(res17, u11, m[5]); + fma52lo_mem(res17, res17, u11, m, SIMD_BYTES * 6); + fma52hi_mem(res18, res18, u11, m, SIMD_BYTES * 6); + res18 = fma52lo(res18, u11, m[7]); + res19 = fma52hi(res19, u11, m[7]); + fma52lo_mem(res19, res19, u11, m, SIMD_BYTES * 8); + fma52hi_mem(res20, res20, u11, m, SIMD_BYTES * 8); + res20 = fma52lo(res20, u11, m[9]); + res21 = fma52hi(res21, u11, m[9]); + fma52lo_mem(res21, res21, u11, m, SIMD_BYTES * 10); + fma52hi_mem(res22, res22, u11, m, SIMD_BYTES * 10); + res22 = fma52lo(res22, u11, m[11]); + res23 = fma52hi(res23, u11, m[11]); + fma52lo_mem(res23, res23, u11, m, SIMD_BYTES * 12); + fma52hi_mem(res24, res24, u11, m, SIMD_BYTES * 12); + res24 = fma52lo(res24, u11, m[13]); + res25 = fma52hi(res25, u11, m[13]); + fma52lo_mem(res25, res25, u11, m, SIMD_BYTES * 14); + fma52hi_mem(res26, res26, u11, m, SIMD_BYTES * 14); + res26 = fma52lo(res26, u11, m[15]); + res27 = fma52hi(res27, u11, m[15]); + fma52lo_mem(res27, res27, u11, m, SIMD_BYTES * 16); + fma52hi_mem(res28, res28, u11, m, SIMD_BYTES * 16); + res28 = fma52lo(res28, u11, m[17]); + res29 = fma52hi(res29, u11, m[17]); + fma52lo_mem(res29, res29, u11, m, SIMD_BYTES * 18); + fma52hi_mem(res30, res30, u11, m, SIMD_BYTES * 18); + res30 = fma52lo(res30, u11, m[19]); + res31 = fma52hi(res31, u11, m[19]); + ASM("jmp l12\nl12:\n"); + + // Create u12 + fma52lo_mem(res12, res12, u12, m, SIMD_BYTES * 0); + fma52hi_mem(res13, res13, u12, m, SIMD_BYTES * 0); + res13 = fma52lo(res13, u12, m[1]); + res14 = fma52hi(res14, u12, m[1]); + res13 = add64(res13, srli64(res12, DIGIT_SIZE)); + U64 u13 = mul52lo(res13, k); + fma52lo_mem(res14, res14, u12, m, SIMD_BYTES * 2); + fma52hi_mem(res15, res15, u12, m, SIMD_BYTES * 2); + res15 = fma52lo(res15, u12, m[3]); + res16 = fma52hi(res16, u12, m[3]); + fma52lo_mem(res16, res16, u12, m, SIMD_BYTES * 4); + fma52hi_mem(res17, res17, u12, m, SIMD_BYTES * 4); + res17 = fma52lo(res17, u12, m[5]); + res18 = fma52hi(res18, u12, m[5]); + fma52lo_mem(res18, res18, u12, m, SIMD_BYTES * 6); + fma52hi_mem(res19, res19, u12, m, SIMD_BYTES * 6); + res19 = fma52lo(res19, u12, m[7]); + res20 = fma52hi(res20, u12, m[7]); + fma52lo_mem(res20, res20, u12, m, SIMD_BYTES * 8); + fma52hi_mem(res21, res21, u12, m, SIMD_BYTES * 8); + res21 = fma52lo(res21, u12, m[9]); + res22 = fma52hi(res22, u12, m[9]); + fma52lo_mem(res22, res22, u12, m, SIMD_BYTES * 10); + fma52hi_mem(res23, res23, u12, m, SIMD_BYTES * 10); + res23 = fma52lo(res23, u12, m[11]); + res24 = fma52hi(res24, u12, m[11]); + fma52lo_mem(res24, res24, u12, m, SIMD_BYTES * 12); + fma52hi_mem(res25, res25, u12, m, SIMD_BYTES * 12); + res25 = fma52lo(res25, u12, m[13]); + res26 = fma52hi(res26, u12, m[13]); + fma52lo_mem(res26, res26, u12, m, SIMD_BYTES * 14); + fma52hi_mem(res27, res27, u12, m, SIMD_BYTES * 14); + res27 = fma52lo(res27, u12, m[15]); + res28 = fma52hi(res28, u12, m[15]); + fma52lo_mem(res28, res28, u12, m, SIMD_BYTES * 16); + fma52hi_mem(res29, res29, u12, m, SIMD_BYTES * 16); + res29 = fma52lo(res29, u12, m[17]); + res30 = fma52hi(res30, u12, m[17]); + fma52lo_mem(res30, res30, u12, m, SIMD_BYTES * 18); + fma52hi_mem(res31, res31, u12, m, SIMD_BYTES * 18); + res31 = fma52lo(res31, u12, m[19]); + res32 = fma52hi(res32, u12, m[19]); + + // Create u13 + fma52lo_mem(res13, res13, u13, m, SIMD_BYTES * 0); + fma52hi_mem(res14, res14, u13, m, SIMD_BYTES * 0); + res14 = fma52lo(res14, u13, m[1]); + res15 = fma52hi(res15, u13, m[1]); + res14 = add64(res14, srli64(res13, DIGIT_SIZE)); + U64 u14 = mul52lo(res14, k); + fma52lo_mem(res15, res15, u13, m, SIMD_BYTES * 2); + fma52hi_mem(res16, res16, u13, m, SIMD_BYTES * 2); + res16 = fma52lo(res16, u13, m[3]); + res17 = fma52hi(res17, u13, m[3]); + fma52lo_mem(res17, res17, u13, m, SIMD_BYTES * 4); + fma52hi_mem(res18, res18, u13, m, SIMD_BYTES * 4); + res18 = fma52lo(res18, u13, m[5]); + res19 = fma52hi(res19, u13, m[5]); + fma52lo_mem(res19, res19, u13, m, SIMD_BYTES * 6); + fma52hi_mem(res20, res20, u13, m, SIMD_BYTES * 6); + res20 = fma52lo(res20, u13, m[7]); + res21 = fma52hi(res21, u13, m[7]); + fma52lo_mem(res21, res21, u13, m, SIMD_BYTES * 8); + fma52hi_mem(res22, res22, u13, m, SIMD_BYTES * 8); + res22 = fma52lo(res22, u13, m[9]); + res23 = fma52hi(res23, u13, m[9]); + fma52lo_mem(res23, res23, u13, m, SIMD_BYTES * 10); + fma52hi_mem(res24, res24, u13, m, SIMD_BYTES * 10); + res24 = fma52lo(res24, u13, m[11]); + res25 = fma52hi(res25, u13, m[11]); + fma52lo_mem(res25, res25, u13, m, SIMD_BYTES * 12); + fma52hi_mem(res26, res26, u13, m, SIMD_BYTES * 12); + res26 = fma52lo(res26, u13, m[13]); + res27 = fma52hi(res27, u13, m[13]); + fma52lo_mem(res27, res27, u13, m, SIMD_BYTES * 14); + fma52hi_mem(res28, res28, u13, m, SIMD_BYTES * 14); + res28 = fma52lo(res28, u13, m[15]); + res29 = fma52hi(res29, u13, m[15]); + fma52lo_mem(res29, res29, u13, m, SIMD_BYTES * 16); + fma52hi_mem(res30, res30, u13, m, SIMD_BYTES * 16); + res30 = fma52lo(res30, u13, m[17]); + res31 = fma52hi(res31, u13, m[17]); + fma52lo_mem(res31, res31, u13, m, SIMD_BYTES * 18); + fma52hi_mem(res32, res32, u13, m, SIMD_BYTES * 18); + res32 = fma52lo(res32, u13, m[19]); + res33 = fma52hi(res33, u13, m[19]); + ASM("jmp l14\nl14:\n"); + + // Create u14 + fma52lo_mem(res14, res14, u14, m, SIMD_BYTES * 0); + fma52hi_mem(res15, res15, u14, m, SIMD_BYTES * 0); + res15 = fma52lo(res15, u14, m[1]); + res16 = fma52hi(res16, u14, m[1]); + res15 = add64(res15, srli64(res14, DIGIT_SIZE)); + U64 u15 = mul52lo(res15, k); + fma52lo_mem(res16, res16, u14, m, SIMD_BYTES * 2); + fma52hi_mem(res17, res17, u14, m, SIMD_BYTES * 2); + res17 = fma52lo(res17, u14, m[3]); + res18 = fma52hi(res18, u14, m[3]); + fma52lo_mem(res18, res18, u14, m, SIMD_BYTES * 4); + fma52hi_mem(res19, res19, u14, m, SIMD_BYTES * 4); + res19 = fma52lo(res19, u14, m[5]); + res20 = fma52hi(res20, u14, m[5]); + fma52lo_mem(res20, res20, u14, m, SIMD_BYTES * 6); + fma52hi_mem(res21, res21, u14, m, SIMD_BYTES * 6); + res21 = fma52lo(res21, u14, m[7]); + res22 = fma52hi(res22, u14, m[7]); + fma52lo_mem(res22, res22, u14, m, SIMD_BYTES * 8); + fma52hi_mem(res23, res23, u14, m, SIMD_BYTES * 8); + res23 = fma52lo(res23, u14, m[9]); + res24 = fma52hi(res24, u14, m[9]); + fma52lo_mem(res24, res24, u14, m, SIMD_BYTES * 10); + fma52hi_mem(res25, res25, u14, m, SIMD_BYTES * 10); + res25 = fma52lo(res25, u14, m[11]); + res26 = fma52hi(res26, u14, m[11]); + fma52lo_mem(res26, res26, u14, m, SIMD_BYTES * 12); + fma52hi_mem(res27, res27, u14, m, SIMD_BYTES * 12); + res27 = fma52lo(res27, u14, m[13]); + res28 = fma52hi(res28, u14, m[13]); + fma52lo_mem(res28, res28, u14, m, SIMD_BYTES * 14); + fma52hi_mem(res29, res29, u14, m, SIMD_BYTES * 14); + res29 = fma52lo(res29, u14, m[15]); + res30 = fma52hi(res30, u14, m[15]); + fma52lo_mem(res30, res30, u14, m, SIMD_BYTES * 16); + fma52hi_mem(res31, res31, u14, m, SIMD_BYTES * 16); + res31 = fma52lo(res31, u14, m[17]); + res32 = fma52hi(res32, u14, m[17]); + fma52lo_mem(res32, res32, u14, m, SIMD_BYTES * 18); + fma52hi_mem(res33, res33, u14, m, SIMD_BYTES * 18); + res33 = fma52lo(res33, u14, m[19]); + res34 = fma52hi(res34, u14, m[19]); + + // Create u15 + fma52lo_mem(res15, res15, u15, m, SIMD_BYTES * 0); + fma52hi_mem(res16, res16, u15, m, SIMD_BYTES * 0); + res16 = fma52lo(res16, u15, m[1]); + res17 = fma52hi(res17, u15, m[1]); + res16 = add64(res16, srli64(res15, DIGIT_SIZE)); + U64 u16 = mul52lo(res16, k); + fma52lo_mem(res17, res17, u15, m, SIMD_BYTES * 2); + fma52hi_mem(res18, res18, u15, m, SIMD_BYTES * 2); + res18 = fma52lo(res18, u15, m[3]); + res19 = fma52hi(res19, u15, m[3]); + fma52lo_mem(res19, res19, u15, m, SIMD_BYTES * 4); + fma52hi_mem(res20, res20, u15, m, SIMD_BYTES * 4); + res20 = fma52lo(res20, u15, m[5]); + res21 = fma52hi(res21, u15, m[5]); + fma52lo_mem(res21, res21, u15, m, SIMD_BYTES * 6); + fma52hi_mem(res22, res22, u15, m, SIMD_BYTES * 6); + res22 = fma52lo(res22, u15, m[7]); + res23 = fma52hi(res23, u15, m[7]); + fma52lo_mem(res23, res23, u15, m, SIMD_BYTES * 8); + fma52hi_mem(res24, res24, u15, m, SIMD_BYTES * 8); + res24 = fma52lo(res24, u15, m[9]); + res25 = fma52hi(res25, u15, m[9]); + fma52lo_mem(res25, res25, u15, m, SIMD_BYTES * 10); + fma52hi_mem(res26, res26, u15, m, SIMD_BYTES * 10); + res26 = fma52lo(res26, u15, m[11]); + res27 = fma52hi(res27, u15, m[11]); + fma52lo_mem(res27, res27, u15, m, SIMD_BYTES * 12); + fma52hi_mem(res28, res28, u15, m, SIMD_BYTES * 12); + res28 = fma52lo(res28, u15, m[13]); + res29 = fma52hi(res29, u15, m[13]); + fma52lo_mem(res29, res29, u15, m, SIMD_BYTES * 14); + fma52hi_mem(res30, res30, u15, m, SIMD_BYTES * 14); + res30 = fma52lo(res30, u15, m[15]); + res31 = fma52hi(res31, u15, m[15]); + fma52lo_mem(res31, res31, u15, m, SIMD_BYTES * 16); + fma52hi_mem(res32, res32, u15, m, SIMD_BYTES * 16); + res32 = fma52lo(res32, u15, m[17]); + res33 = fma52hi(res33, u15, m[17]); + fma52lo_mem(res33, res33, u15, m, SIMD_BYTES * 18); + fma52hi_mem(res34, res34, u15, m, SIMD_BYTES * 18); + res34 = fma52lo(res34, u15, m[19]); + res35 = fma52hi(res35, u15, m[19]); + ASM("jmp l16\nl16:\n"); + + // Create u16 + fma52lo_mem(res16, res16, u16, m, SIMD_BYTES * 0); + fma52hi_mem(res17, res17, u16, m, SIMD_BYTES * 0); + res17 = fma52lo(res17, u16, m[1]); + res18 = fma52hi(res18, u16, m[1]); + res17 = add64(res17, srli64(res16, DIGIT_SIZE)); + U64 u17 = mul52lo(res17, k); + fma52lo_mem(res18, res18, u16, m, SIMD_BYTES * 2); + fma52hi_mem(res19, res19, u16, m, SIMD_BYTES * 2); + res19 = fma52lo(res19, u16, m[3]); + res20 = fma52hi(res20, u16, m[3]); + fma52lo_mem(res20, res20, u16, m, SIMD_BYTES * 4); + fma52hi_mem(res21, res21, u16, m, SIMD_BYTES * 4); + res21 = fma52lo(res21, u16, m[5]); + res22 = fma52hi(res22, u16, m[5]); + fma52lo_mem(res22, res22, u16, m, SIMD_BYTES * 6); + fma52hi_mem(res23, res23, u16, m, SIMD_BYTES * 6); + res23 = fma52lo(res23, u16, m[7]); + res24 = fma52hi(res24, u16, m[7]); + fma52lo_mem(res24, res24, u16, m, SIMD_BYTES * 8); + fma52hi_mem(res25, res25, u16, m, SIMD_BYTES * 8); + res25 = fma52lo(res25, u16, m[9]); + res26 = fma52hi(res26, u16, m[9]); + fma52lo_mem(res26, res26, u16, m, SIMD_BYTES * 10); + fma52hi_mem(res27, res27, u16, m, SIMD_BYTES * 10); + res27 = fma52lo(res27, u16, m[11]); + res28 = fma52hi(res28, u16, m[11]); + fma52lo_mem(res28, res28, u16, m, SIMD_BYTES * 12); + fma52hi_mem(res29, res29, u16, m, SIMD_BYTES * 12); + res29 = fma52lo(res29, u16, m[13]); + res30 = fma52hi(res30, u16, m[13]); + fma52lo_mem(res30, res30, u16, m, SIMD_BYTES * 14); + fma52hi_mem(res31, res31, u16, m, SIMD_BYTES * 14); + res31 = fma52lo(res31, u16, m[15]); + res32 = fma52hi(res32, u16, m[15]); + fma52lo_mem(res32, res32, u16, m, SIMD_BYTES * 16); + fma52hi_mem(res33, res33, u16, m, SIMD_BYTES * 16); + res33 = fma52lo(res33, u16, m[17]); + res34 = fma52hi(res34, u16, m[17]); + fma52lo_mem(res34, res34, u16, m, SIMD_BYTES * 18); + fma52hi_mem(res35, res35, u16, m, SIMD_BYTES * 18); + res35 = fma52lo(res35, u16, m[19]); + res36 = fma52hi(res36, u16, m[19]); + + // Create u17 + fma52lo_mem(res17, res17, u17, m, SIMD_BYTES * 0); + fma52hi_mem(res18, res18, u17, m, SIMD_BYTES * 0); + res18 = fma52lo(res18, u17, m[1]); + res19 = fma52hi(res19, u17, m[1]); + res18 = add64(res18, srli64(res17, DIGIT_SIZE)); + U64 u18 = mul52lo(res18, k); + fma52lo_mem(res19, res19, u17, m, SIMD_BYTES * 2); + fma52hi_mem(res20, res20, u17, m, SIMD_BYTES * 2); + res20 = fma52lo(res20, u17, m[3]); + res21 = fma52hi(res21, u17, m[3]); + fma52lo_mem(res21, res21, u17, m, SIMD_BYTES * 4); + fma52hi_mem(res22, res22, u17, m, SIMD_BYTES * 4); + res22 = fma52lo(res22, u17, m[5]); + res23 = fma52hi(res23, u17, m[5]); + fma52lo_mem(res23, res23, u17, m, SIMD_BYTES * 6); + fma52hi_mem(res24, res24, u17, m, SIMD_BYTES * 6); + res24 = fma52lo(res24, u17, m[7]); + res25 = fma52hi(res25, u17, m[7]); + fma52lo_mem(res25, res25, u17, m, SIMD_BYTES * 8); + fma52hi_mem(res26, res26, u17, m, SIMD_BYTES * 8); + res26 = fma52lo(res26, u17, m[9]); + res27 = fma52hi(res27, u17, m[9]); + fma52lo_mem(res27, res27, u17, m, SIMD_BYTES * 10); + fma52hi_mem(res28, res28, u17, m, SIMD_BYTES * 10); + res28 = fma52lo(res28, u17, m[11]); + res29 = fma52hi(res29, u17, m[11]); + fma52lo_mem(res29, res29, u17, m, SIMD_BYTES * 12); + fma52hi_mem(res30, res30, u17, m, SIMD_BYTES * 12); + res30 = fma52lo(res30, u17, m[13]); + res31 = fma52hi(res31, u17, m[13]); + fma52lo_mem(res31, res31, u17, m, SIMD_BYTES * 14); + fma52hi_mem(res32, res32, u17, m, SIMD_BYTES * 14); + res32 = fma52lo(res32, u17, m[15]); + res33 = fma52hi(res33, u17, m[15]); + fma52lo_mem(res33, res33, u17, m, SIMD_BYTES * 16); + fma52hi_mem(res34, res34, u17, m, SIMD_BYTES * 16); + res34 = fma52lo(res34, u17, m[17]); + res35 = fma52hi(res35, u17, m[17]); + fma52lo_mem(res35, res35, u17, m, SIMD_BYTES * 18); + fma52hi_mem(res36, res36, u17, m, SIMD_BYTES * 18); + res36 = fma52lo(res36, u17, m[19]); + res37 = fma52hi(res37, u17, m[19]); + ASM("jmp l18\nl18:\n"); + + // Create u18 + fma52lo_mem(res18, res18, u18, m, SIMD_BYTES * 0); + fma52hi_mem(res19, res19, u18, m, SIMD_BYTES * 0); + res19 = fma52lo(res19, u18, m[1]); + res20 = fma52hi(res20, u18, m[1]); + res19 = add64(res19, srli64(res18, DIGIT_SIZE)); + U64 u19 = mul52lo(res19, k); + fma52lo_mem(res20, res20, u18, m, SIMD_BYTES * 2); + fma52hi_mem(res21, res21, u18, m, SIMD_BYTES * 2); + res21 = fma52lo(res21, u18, m[3]); + res22 = fma52hi(res22, u18, m[3]); + fma52lo_mem(res22, res22, u18, m, SIMD_BYTES * 4); + fma52hi_mem(res23, res23, u18, m, SIMD_BYTES * 4); + res23 = fma52lo(res23, u18, m[5]); + res24 = fma52hi(res24, u18, m[5]); + fma52lo_mem(res24, res24, u18, m, SIMD_BYTES * 6); + fma52hi_mem(res25, res25, u18, m, SIMD_BYTES * 6); + res25 = fma52lo(res25, u18, m[7]); + res26 = fma52hi(res26, u18, m[7]); + fma52lo_mem(res26, res26, u18, m, SIMD_BYTES * 8); + fma52hi_mem(res27, res27, u18, m, SIMD_BYTES * 8); + res27 = fma52lo(res27, u18, m[9]); + res28 = fma52hi(res28, u18, m[9]); + fma52lo_mem(res28, res28, u18, m, SIMD_BYTES * 10); + fma52hi_mem(res29, res29, u18, m, SIMD_BYTES * 10); + res29 = fma52lo(res29, u18, m[11]); + res30 = fma52hi(res30, u18, m[11]); + fma52lo_mem(res30, res30, u18, m, SIMD_BYTES * 12); + fma52hi_mem(res31, res31, u18, m, SIMD_BYTES * 12); + res31 = fma52lo(res31, u18, m[13]); + res32 = fma52hi(res32, u18, m[13]); + fma52lo_mem(res32, res32, u18, m, SIMD_BYTES * 14); + fma52hi_mem(res33, res33, u18, m, SIMD_BYTES * 14); + res33 = fma52lo(res33, u18, m[15]); + res34 = fma52hi(res34, u18, m[15]); + fma52lo_mem(res34, res34, u18, m, SIMD_BYTES * 16); + fma52hi_mem(res35, res35, u18, m, SIMD_BYTES * 16); + res35 = fma52lo(res35, u18, m[17]); + res36 = fma52hi(res36, u18, m[17]); + fma52lo_mem(res36, res36, u18, m, SIMD_BYTES * 18); + fma52hi_mem(res37, res37, u18, m, SIMD_BYTES * 18); + res37 = fma52lo(res37, u18, m[19]); + res38 = fma52hi(res38, u18, m[19]); + + // Create u19 + fma52lo_mem(res19, res19, u19, m, SIMD_BYTES * 0); + fma52hi_mem(res20, res20, u19, m, SIMD_BYTES * 0); + res20 = fma52lo(res20, u19, m[1]); + res21 = fma52hi(res21, u19, m[1]); + res20 = add64(res20, srli64(res19, DIGIT_SIZE)); + fma52lo_mem(res21, res21, u19, m, SIMD_BYTES * 2); + fma52hi_mem(res22, res22, u19, m, SIMD_BYTES * 2); + res22 = fma52lo(res22, u19, m[3]); + res23 = fma52hi(res23, u19, m[3]); + fma52lo_mem(res23, res23, u19, m, SIMD_BYTES * 4); + fma52hi_mem(res24, res24, u19, m, SIMD_BYTES * 4); + res24 = fma52lo(res24, u19, m[5]); + res25 = fma52hi(res25, u19, m[5]); + fma52lo_mem(res25, res25, u19, m, SIMD_BYTES * 6); + fma52hi_mem(res26, res26, u19, m, SIMD_BYTES * 6); + res26 = fma52lo(res26, u19, m[7]); + res27 = fma52hi(res27, u19, m[7]); + fma52lo_mem(res27, res27, u19, m, SIMD_BYTES * 8); + fma52hi_mem(res28, res28, u19, m, SIMD_BYTES * 8); + res28 = fma52lo(res28, u19, m[9]); + res29 = fma52hi(res29, u19, m[9]); + fma52lo_mem(res29, res29, u19, m, SIMD_BYTES * 10); + fma52hi_mem(res30, res30, u19, m, SIMD_BYTES * 10); + res30 = fma52lo(res30, u19, m[11]); + res31 = fma52hi(res31, u19, m[11]); + fma52lo_mem(res31, res31, u19, m, SIMD_BYTES * 12); + fma52hi_mem(res32, res32, u19, m, SIMD_BYTES * 12); + res32 = fma52lo(res32, u19, m[13]); + res33 = fma52hi(res33, u19, m[13]); + fma52lo_mem(res33, res33, u19, m, SIMD_BYTES * 14); + fma52hi_mem(res34, res34, u19, m, SIMD_BYTES * 14); + res34 = fma52lo(res34, u19, m[15]); + res35 = fma52hi(res35, u19, m[15]); + fma52lo_mem(res35, res35, u19, m, SIMD_BYTES * 16); + fma52hi_mem(res36, res36, u19, m, SIMD_BYTES * 16); + res36 = fma52lo(res36, u19, m[17]); + res37 = fma52hi(res37, u19, m[17]); + fma52lo_mem(res37, res37, u19, m, SIMD_BYTES * 18); + fma52hi_mem(res38, res38, u19, m, SIMD_BYTES * 18); + res38 = fma52lo(res38, u19, m[19]); + res39 = fma52hi(res39, u19, m[19]); + + // Normalization + r[0] = res20; + res21 = add64(res21, srli64(res20, DIGIT_SIZE)); + r[1] = res21; + res22 = add64(res22, srli64(res21, DIGIT_SIZE)); + r[2] = res22; + res23 = add64(res23, srli64(res22, DIGIT_SIZE)); + r[3] = res23; + res24 = add64(res24, srli64(res23, DIGIT_SIZE)); + r[4] = res24; + res25 = add64(res25, srli64(res24, DIGIT_SIZE)); + r[5] = res25; + res26 = add64(res26, srli64(res25, DIGIT_SIZE)); + r[6] = res26; + res27 = add64(res27, srli64(res26, DIGIT_SIZE)); + r[7] = res27; + res28 = add64(res28, srli64(res27, DIGIT_SIZE)); + r[8] = res28; + res29 = add64(res29, srli64(res28, DIGIT_SIZE)); + r[9] = res29; + res30 = add64(res30, srli64(res29, DIGIT_SIZE)); + r[10] = res30; + res31 = add64(res31, srli64(res30, DIGIT_SIZE)); + r[11] = res31; + res32 = add64(res32, srli64(res31, DIGIT_SIZE)); + r[12] = res32; + res33 = add64(res33, srli64(res32, DIGIT_SIZE)); + r[13] = res33; + res34 = add64(res34, srli64(res33, DIGIT_SIZE)); + r[14] = res34; + res35 = add64(res35, srli64(res34, DIGIT_SIZE)); + r[15] = res35; + res36 = add64(res36, srli64(res35, DIGIT_SIZE)); + r[16] = res36; + res37 = add64(res37, srli64(res36, DIGIT_SIZE)); + r[17] = res37; + res38 = add64(res38, srli64(res37, DIGIT_SIZE)); + r[18] = res38; + res39 = add64(res39, srli64(res38, DIGIT_SIZE)); + r[19] = res39; + a = (U64 *)out_mb; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x40_diagonal_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x40_diagonal_mb8.c new file mode 100644 index 000000000..7434c094c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_ams5x52x40_diagonal_mb8.c @@ -0,0 +1,2277 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +void AMS5x52x40_diagonal_mb8(int64u *out_mb, const int64u *inpA_mb, + const int64u *inpM_mb, const int64u *k0_mb) { + __ALIGN64 U64 res[80]; + __ALIGN64 U64 u[40]; + U64 k; + U64 *a = (U64 *)inpA_mb; + U64 *m = (U64 *)inpM_mb; + U64 *r = (U64 *)out_mb; + int iter; + const int iters = 5; + + k = loadu64((U64 *)k0_mb); + for (iter = 0; iter < iters; ++iter) { + int i; + for (i = 0; i < 80; ++i) + res[i] = get_zero64(); + + // Calculate full square + res[1] = fma52lo(res[1], a[0], a[1]); // Sum(1) + res[2] = fma52hi(res[2], a[0], a[1]); // Sum(1) + res[2] = fma52lo(res[2], a[0], a[2]); // Sum(2) + res[3] = fma52hi(res[3], a[0], a[2]); // Sum(2) + res[3] = fma52lo(res[3], a[1], a[2]); // Sum(3) + res[4] = fma52hi(res[4], a[1], a[2]); // Sum(3) + res[3] = fma52lo(res[3], a[0], a[3]); // Sum(3) + res[4] = fma52hi(res[4], a[0], a[3]); // Sum(3) + res[4] = fma52lo(res[4], a[1], a[3]); // Sum(4) + res[5] = fma52hi(res[5], a[1], a[3]); // Sum(4) + res[5] = fma52lo(res[5], a[2], a[3]); // Sum(5) + res[6] = fma52hi(res[6], a[2], a[3]); // Sum(5) + res[4] = fma52lo(res[4], a[0], a[4]); // Sum(4) + res[5] = fma52hi(res[5], a[0], a[4]); // Sum(4) + res[5] = fma52lo(res[5], a[1], a[4]); // Sum(5) + res[6] = fma52hi(res[6], a[1], a[4]); // Sum(5) + res[6] = fma52lo(res[6], a[2], a[4]); // Sum(6) + res[7] = fma52hi(res[7], a[2], a[4]); // Sum(6) + res[7] = fma52lo(res[7], a[3], a[4]); // Sum(7) + res[8] = fma52hi(res[8], a[3], a[4]); // Sum(7) + res[5] = fma52lo(res[5], a[0], a[5]); // Sum(5) + res[6] = fma52hi(res[6], a[0], a[5]); // Sum(5) + res[6] = fma52lo(res[6], a[1], a[5]); // Sum(6) + res[7] = fma52hi(res[7], a[1], a[5]); // Sum(6) + res[7] = fma52lo(res[7], a[2], a[5]); // Sum(7) + res[8] = fma52hi(res[8], a[2], a[5]); // Sum(7) + res[8] = fma52lo(res[8], a[3], a[5]); // Sum(8) + res[9] = fma52hi(res[9], a[3], a[5]); // Sum(8) + res[9] = fma52lo(res[9], a[4], a[5]); // Sum(9) + res[10] = fma52hi(res[10], a[4], a[5]); // Sum(9) + res[6] = fma52lo(res[6], a[0], a[6]); // Sum(6) + res[7] = fma52hi(res[7], a[0], a[6]); // Sum(6) + res[7] = fma52lo(res[7], a[1], a[6]); // Sum(7) + res[8] = fma52hi(res[8], a[1], a[6]); // Sum(7) + res[8] = fma52lo(res[8], a[2], a[6]); // Sum(8) + res[9] = fma52hi(res[9], a[2], a[6]); // Sum(8) + res[9] = fma52lo(res[9], a[3], a[6]); // Sum(9) + res[10] = fma52hi(res[10], a[3], a[6]); // Sum(9) + res[10] = fma52lo(res[10], a[4], a[6]); // Sum(10) + res[11] = fma52hi(res[11], a[4], a[6]); // Sum(10) + res[11] = fma52lo(res[11], a[5], a[6]); // Sum(11) + res[12] = fma52hi(res[12], a[5], a[6]); // Sum(11) + res[7] = fma52lo(res[7], a[0], a[7]); // Sum(7) + res[8] = fma52hi(res[8], a[0], a[7]); // Sum(7) + res[8] = fma52lo(res[8], a[1], a[7]); // Sum(8) + res[9] = fma52hi(res[9], a[1], a[7]); // Sum(8) + res[9] = fma52lo(res[9], a[2], a[7]); // Sum(9) + res[10] = fma52hi(res[10], a[2], a[7]); // Sum(9) + res[10] = fma52lo(res[10], a[3], a[7]); // Sum(10) + res[11] = fma52hi(res[11], a[3], a[7]); // Sum(10) + res[11] = fma52lo(res[11], a[4], a[7]); // Sum(11) + res[12] = fma52hi(res[12], a[4], a[7]); // Sum(11) + res[8] = fma52lo(res[8], a[0], a[8]); // Sum(8) + res[9] = fma52hi(res[9], a[0], a[8]); // Sum(8) + res[9] = fma52lo(res[9], a[1], a[8]); // Sum(9) + res[10] = fma52hi(res[10], a[1], a[8]); // Sum(9) + res[10] = fma52lo(res[10], a[2], a[8]); // Sum(10) + res[11] = fma52hi(res[11], a[2], a[8]); // Sum(10) + res[11] = fma52lo(res[11], a[3], a[8]); // Sum(11) + res[12] = fma52hi(res[12], a[3], a[8]); // Sum(11) + res[9] = fma52lo(res[9], a[0], a[9]); // Sum(9) + res[10] = fma52hi(res[10], a[0], a[9]); // Sum(9) + res[10] = fma52lo(res[10], a[1], a[9]); // Sum(10) + res[11] = fma52hi(res[11], a[1], a[9]); // Sum(10) + res[11] = fma52lo(res[11], a[2], a[9]); // Sum(11) + res[12] = fma52hi(res[12], a[2], a[9]); // Sum(11) + res[10] = fma52lo(res[10], a[0], a[10]); // Sum(10) + res[11] = fma52hi(res[11], a[0], a[10]); // Sum(10) + res[11] = fma52lo(res[11], a[1], a[10]); // Sum(11) + res[12] = fma52hi(res[12], a[1], a[10]); // Sum(11) + res[11] = fma52lo(res[11], a[0], a[11]); // Sum(11) + res[12] = fma52hi(res[12], a[0], a[11]); // Sum(11) + res[0] = add64(res[0], res[0]); // Double(0) + res[1] = add64(res[1], res[1]); // Double(1) + res[2] = add64(res[2], res[2]); // Double(2) + res[3] = add64(res[3], res[3]); // Double(3) + res[4] = add64(res[4], res[4]); // Double(4) + res[5] = add64(res[5], res[5]); // Double(5) + res[6] = add64(res[6], res[6]); // Double(6) + res[7] = add64(res[7], res[7]); // Double(7) + res[8] = add64(res[8], res[8]); // Double(8) + res[9] = add64(res[9], res[9]); // Double(9) + res[10] = add64(res[10], res[10]); // Double(10) + res[11] = add64(res[11], res[11]); // Double(11) + res[0] = fma52lo(res[0], a[0], a[0]); // Add sqr(0) + res[1] = fma52hi(res[1], a[0], a[0]); // Add sqr(0) + res[2] = fma52lo(res[2], a[1], a[1]); // Add sqr(2) + res[3] = fma52hi(res[3], a[1], a[1]); // Add sqr(2) + res[4] = fma52lo(res[4], a[2], a[2]); // Add sqr(4) + res[5] = fma52hi(res[5], a[2], a[2]); // Add sqr(4) + res[6] = fma52lo(res[6], a[3], a[3]); // Add sqr(6) + res[7] = fma52hi(res[7], a[3], a[3]); // Add sqr(6) + res[8] = fma52lo(res[8], a[4], a[4]); // Add sqr(8) + res[9] = fma52hi(res[9], a[4], a[4]); // Add sqr(8) + res[10] = fma52lo(res[10], a[5], a[5]); // Add sqr(10) + res[11] = fma52hi(res[11], a[5], a[5]); // Add sqr(10) + res[12] = fma52lo(res[12], a[5], a[7]); // Sum(12) + res[13] = fma52hi(res[13], a[5], a[7]); // Sum(12) + res[13] = fma52lo(res[13], a[6], a[7]); // Sum(13) + res[14] = fma52hi(res[14], a[6], a[7]); // Sum(13) + res[12] = fma52lo(res[12], a[4], a[8]); // Sum(12) + res[13] = fma52hi(res[13], a[4], a[8]); // Sum(12) + res[13] = fma52lo(res[13], a[5], a[8]); // Sum(13) + res[14] = fma52hi(res[14], a[5], a[8]); // Sum(13) + res[14] = fma52lo(res[14], a[6], a[8]); // Sum(14) + res[15] = fma52hi(res[15], a[6], a[8]); // Sum(14) + res[15] = fma52lo(res[15], a[7], a[8]); // Sum(15) + res[16] = fma52hi(res[16], a[7], a[8]); // Sum(15) + res[12] = fma52lo(res[12], a[3], a[9]); // Sum(12) + res[13] = fma52hi(res[13], a[3], a[9]); // Sum(12) + res[13] = fma52lo(res[13], a[4], a[9]); // Sum(13) + res[14] = fma52hi(res[14], a[4], a[9]); // Sum(13) + res[14] = fma52lo(res[14], a[5], a[9]); // Sum(14) + res[15] = fma52hi(res[15], a[5], a[9]); // Sum(14) + res[15] = fma52lo(res[15], a[6], a[9]); // Sum(15) + res[16] = fma52hi(res[16], a[6], a[9]); // Sum(15) + res[16] = fma52lo(res[16], a[7], a[9]); // Sum(16) + res[17] = fma52hi(res[17], a[7], a[9]); // Sum(16) + res[17] = fma52lo(res[17], a[8], a[9]); // Sum(17) + res[18] = fma52hi(res[18], a[8], a[9]); // Sum(17) + res[12] = fma52lo(res[12], a[2], a[10]); // Sum(12) + res[13] = fma52hi(res[13], a[2], a[10]); // Sum(12) + res[13] = fma52lo(res[13], a[3], a[10]); // Sum(13) + res[14] = fma52hi(res[14], a[3], a[10]); // Sum(13) + res[14] = fma52lo(res[14], a[4], a[10]); // Sum(14) + res[15] = fma52hi(res[15], a[4], a[10]); // Sum(14) + res[15] = fma52lo(res[15], a[5], a[10]); // Sum(15) + res[16] = fma52hi(res[16], a[5], a[10]); // Sum(15) + res[16] = fma52lo(res[16], a[6], a[10]); // Sum(16) + res[17] = fma52hi(res[17], a[6], a[10]); // Sum(16) + res[17] = fma52lo(res[17], a[7], a[10]); // Sum(17) + res[18] = fma52hi(res[18], a[7], a[10]); // Sum(17) + res[18] = fma52lo(res[18], a[8], a[10]); // Sum(18) + res[19] = fma52hi(res[19], a[8], a[10]); // Sum(18) + res[19] = fma52lo(res[19], a[9], a[10]); // Sum(19) + res[20] = fma52hi(res[20], a[9], a[10]); // Sum(19) + res[12] = fma52lo(res[12], a[1], a[11]); // Sum(12) + res[13] = fma52hi(res[13], a[1], a[11]); // Sum(12) + res[13] = fma52lo(res[13], a[2], a[11]); // Sum(13) + res[14] = fma52hi(res[14], a[2], a[11]); // Sum(13) + res[14] = fma52lo(res[14], a[3], a[11]); // Sum(14) + res[15] = fma52hi(res[15], a[3], a[11]); // Sum(14) + res[15] = fma52lo(res[15], a[4], a[11]); // Sum(15) + res[16] = fma52hi(res[16], a[4], a[11]); // Sum(15) + res[16] = fma52lo(res[16], a[5], a[11]); // Sum(16) + res[17] = fma52hi(res[17], a[5], a[11]); // Sum(16) + res[17] = fma52lo(res[17], a[6], a[11]); // Sum(17) + res[18] = fma52hi(res[18], a[6], a[11]); // Sum(17) + res[18] = fma52lo(res[18], a[7], a[11]); // Sum(18) + res[19] = fma52hi(res[19], a[7], a[11]); // Sum(18) + res[19] = fma52lo(res[19], a[8], a[11]); // Sum(19) + res[20] = fma52hi(res[20], a[8], a[11]); // Sum(19) + res[20] = fma52lo(res[20], a[9], a[11]); // Sum(20) + res[21] = fma52hi(res[21], a[9], a[11]); // Sum(20) + res[21] = fma52lo(res[21], a[10], a[11]); // Sum(21) + res[22] = fma52hi(res[22], a[10], a[11]); // Sum(21) + res[12] = fma52lo(res[12], a[0], a[12]); // Sum(12) + res[13] = fma52hi(res[13], a[0], a[12]); // Sum(12) + res[13] = fma52lo(res[13], a[1], a[12]); // Sum(13) + res[14] = fma52hi(res[14], a[1], a[12]); // Sum(13) + res[14] = fma52lo(res[14], a[2], a[12]); // Sum(14) + res[15] = fma52hi(res[15], a[2], a[12]); // Sum(14) + res[15] = fma52lo(res[15], a[3], a[12]); // Sum(15) + res[16] = fma52hi(res[16], a[3], a[12]); // Sum(15) + res[16] = fma52lo(res[16], a[4], a[12]); // Sum(16) + res[17] = fma52hi(res[17], a[4], a[12]); // Sum(16) + res[17] = fma52lo(res[17], a[5], a[12]); // Sum(17) + res[18] = fma52hi(res[18], a[5], a[12]); // Sum(17) + res[18] = fma52lo(res[18], a[6], a[12]); // Sum(18) + res[19] = fma52hi(res[19], a[6], a[12]); // Sum(18) + res[19] = fma52lo(res[19], a[7], a[12]); // Sum(19) + res[20] = fma52hi(res[20], a[7], a[12]); // Sum(19) + res[20] = fma52lo(res[20], a[8], a[12]); // Sum(20) + res[21] = fma52hi(res[21], a[8], a[12]); // Sum(20) + res[21] = fma52lo(res[21], a[9], a[12]); // Sum(21) + res[22] = fma52hi(res[22], a[9], a[12]); // Sum(21) + res[22] = fma52lo(res[22], a[10], a[12]); // Sum(22) + res[23] = fma52hi(res[23], a[10], a[12]); // Sum(22) + res[23] = fma52lo(res[23], a[11], a[12]); // Sum(23) + res[24] = fma52hi(res[24], a[11], a[12]); // Sum(23) + res[13] = fma52lo(res[13], a[0], a[13]); // Sum(13) + res[14] = fma52hi(res[14], a[0], a[13]); // Sum(13) + res[14] = fma52lo(res[14], a[1], a[13]); // Sum(14) + res[15] = fma52hi(res[15], a[1], a[13]); // Sum(14) + res[15] = fma52lo(res[15], a[2], a[13]); // Sum(15) + res[16] = fma52hi(res[16], a[2], a[13]); // Sum(15) + res[16] = fma52lo(res[16], a[3], a[13]); // Sum(16) + res[17] = fma52hi(res[17], a[3], a[13]); // Sum(16) + res[17] = fma52lo(res[17], a[4], a[13]); // Sum(17) + res[18] = fma52hi(res[18], a[4], a[13]); // Sum(17) + res[18] = fma52lo(res[18], a[5], a[13]); // Sum(18) + res[19] = fma52hi(res[19], a[5], a[13]); // Sum(18) + res[19] = fma52lo(res[19], a[6], a[13]); // Sum(19) + res[20] = fma52hi(res[20], a[6], a[13]); // Sum(19) + res[20] = fma52lo(res[20], a[7], a[13]); // Sum(20) + res[21] = fma52hi(res[21], a[7], a[13]); // Sum(20) + res[21] = fma52lo(res[21], a[8], a[13]); // Sum(21) + res[22] = fma52hi(res[22], a[8], a[13]); // Sum(21) + res[22] = fma52lo(res[22], a[9], a[13]); // Sum(22) + res[23] = fma52hi(res[23], a[9], a[13]); // Sum(22) + res[23] = fma52lo(res[23], a[10], a[13]); // Sum(23) + res[24] = fma52hi(res[24], a[10], a[13]); // Sum(23) + res[14] = fma52lo(res[14], a[0], a[14]); // Sum(14) + res[15] = fma52hi(res[15], a[0], a[14]); // Sum(14) + res[15] = fma52lo(res[15], a[1], a[14]); // Sum(15) + res[16] = fma52hi(res[16], a[1], a[14]); // Sum(15) + res[16] = fma52lo(res[16], a[2], a[14]); // Sum(16) + res[17] = fma52hi(res[17], a[2], a[14]); // Sum(16) + res[17] = fma52lo(res[17], a[3], a[14]); // Sum(17) + res[18] = fma52hi(res[18], a[3], a[14]); // Sum(17) + res[18] = fma52lo(res[18], a[4], a[14]); // Sum(18) + res[19] = fma52hi(res[19], a[4], a[14]); // Sum(18) + res[19] = fma52lo(res[19], a[5], a[14]); // Sum(19) + res[20] = fma52hi(res[20], a[5], a[14]); // Sum(19) + res[20] = fma52lo(res[20], a[6], a[14]); // Sum(20) + res[21] = fma52hi(res[21], a[6], a[14]); // Sum(20) + res[21] = fma52lo(res[21], a[7], a[14]); // Sum(21) + res[22] = fma52hi(res[22], a[7], a[14]); // Sum(21) + res[22] = fma52lo(res[22], a[8], a[14]); // Sum(22) + res[23] = fma52hi(res[23], a[8], a[14]); // Sum(22) + res[23] = fma52lo(res[23], a[9], a[14]); // Sum(23) + res[24] = fma52hi(res[24], a[9], a[14]); // Sum(23) + res[15] = fma52lo(res[15], a[0], a[15]); // Sum(15) + res[16] = fma52hi(res[16], a[0], a[15]); // Sum(15) + res[16] = fma52lo(res[16], a[1], a[15]); // Sum(16) + res[17] = fma52hi(res[17], a[1], a[15]); // Sum(16) + res[17] = fma52lo(res[17], a[2], a[15]); // Sum(17) + res[18] = fma52hi(res[18], a[2], a[15]); // Sum(17) + res[18] = fma52lo(res[18], a[3], a[15]); // Sum(18) + res[19] = fma52hi(res[19], a[3], a[15]); // Sum(18) + res[19] = fma52lo(res[19], a[4], a[15]); // Sum(19) + res[20] = fma52hi(res[20], a[4], a[15]); // Sum(19) + res[20] = fma52lo(res[20], a[5], a[15]); // Sum(20) + res[21] = fma52hi(res[21], a[5], a[15]); // Sum(20) + res[21] = fma52lo(res[21], a[6], a[15]); // Sum(21) + res[22] = fma52hi(res[22], a[6], a[15]); // Sum(21) + res[22] = fma52lo(res[22], a[7], a[15]); // Sum(22) + res[23] = fma52hi(res[23], a[7], a[15]); // Sum(22) + res[23] = fma52lo(res[23], a[8], a[15]); // Sum(23) + res[24] = fma52hi(res[24], a[8], a[15]); // Sum(23) + res[16] = fma52lo(res[16], a[0], a[16]); // Sum(16) + res[17] = fma52hi(res[17], a[0], a[16]); // Sum(16) + res[17] = fma52lo(res[17], a[1], a[16]); // Sum(17) + res[18] = fma52hi(res[18], a[1], a[16]); // Sum(17) + res[18] = fma52lo(res[18], a[2], a[16]); // Sum(18) + res[19] = fma52hi(res[19], a[2], a[16]); // Sum(18) + res[19] = fma52lo(res[19], a[3], a[16]); // Sum(19) + res[20] = fma52hi(res[20], a[3], a[16]); // Sum(19) + res[20] = fma52lo(res[20], a[4], a[16]); // Sum(20) + res[21] = fma52hi(res[21], a[4], a[16]); // Sum(20) + res[21] = fma52lo(res[21], a[5], a[16]); // Sum(21) + res[22] = fma52hi(res[22], a[5], a[16]); // Sum(21) + res[22] = fma52lo(res[22], a[6], a[16]); // Sum(22) + res[23] = fma52hi(res[23], a[6], a[16]); // Sum(22) + res[23] = fma52lo(res[23], a[7], a[16]); // Sum(23) + res[24] = fma52hi(res[24], a[7], a[16]); // Sum(23) + res[17] = fma52lo(res[17], a[0], a[17]); // Sum(17) + res[18] = fma52hi(res[18], a[0], a[17]); // Sum(17) + res[18] = fma52lo(res[18], a[1], a[17]); // Sum(18) + res[19] = fma52hi(res[19], a[1], a[17]); // Sum(18) + res[19] = fma52lo(res[19], a[2], a[17]); // Sum(19) + res[20] = fma52hi(res[20], a[2], a[17]); // Sum(19) + res[20] = fma52lo(res[20], a[3], a[17]); // Sum(20) + res[21] = fma52hi(res[21], a[3], a[17]); // Sum(20) + res[21] = fma52lo(res[21], a[4], a[17]); // Sum(21) + res[22] = fma52hi(res[22], a[4], a[17]); // Sum(21) + res[22] = fma52lo(res[22], a[5], a[17]); // Sum(22) + res[23] = fma52hi(res[23], a[5], a[17]); // Sum(22) + res[23] = fma52lo(res[23], a[6], a[17]); // Sum(23) + res[24] = fma52hi(res[24], a[6], a[17]); // Sum(23) + res[18] = fma52lo(res[18], a[0], a[18]); // Sum(18) + res[19] = fma52hi(res[19], a[0], a[18]); // Sum(18) + res[19] = fma52lo(res[19], a[1], a[18]); // Sum(19) + res[20] = fma52hi(res[20], a[1], a[18]); // Sum(19) + res[20] = fma52lo(res[20], a[2], a[18]); // Sum(20) + res[21] = fma52hi(res[21], a[2], a[18]); // Sum(20) + res[21] = fma52lo(res[21], a[3], a[18]); // Sum(21) + res[22] = fma52hi(res[22], a[3], a[18]); // Sum(21) + res[22] = fma52lo(res[22], a[4], a[18]); // Sum(22) + res[23] = fma52hi(res[23], a[4], a[18]); // Sum(22) + res[23] = fma52lo(res[23], a[5], a[18]); // Sum(23) + res[24] = fma52hi(res[24], a[5], a[18]); // Sum(23) + res[19] = fma52lo(res[19], a[0], a[19]); // Sum(19) + res[20] = fma52hi(res[20], a[0], a[19]); // Sum(19) + res[20] = fma52lo(res[20], a[1], a[19]); // Sum(20) + res[21] = fma52hi(res[21], a[1], a[19]); // Sum(20) + res[21] = fma52lo(res[21], a[2], a[19]); // Sum(21) + res[22] = fma52hi(res[22], a[2], a[19]); // Sum(21) + res[22] = fma52lo(res[22], a[3], a[19]); // Sum(22) + res[23] = fma52hi(res[23], a[3], a[19]); // Sum(22) + res[23] = fma52lo(res[23], a[4], a[19]); // Sum(23) + res[24] = fma52hi(res[24], a[4], a[19]); // Sum(23) + res[20] = fma52lo(res[20], a[0], a[20]); // Sum(20) + res[21] = fma52hi(res[21], a[0], a[20]); // Sum(20) + res[21] = fma52lo(res[21], a[1], a[20]); // Sum(21) + res[22] = fma52hi(res[22], a[1], a[20]); // Sum(21) + res[22] = fma52lo(res[22], a[2], a[20]); // Sum(22) + res[23] = fma52hi(res[23], a[2], a[20]); // Sum(22) + res[23] = fma52lo(res[23], a[3], a[20]); // Sum(23) + res[24] = fma52hi(res[24], a[3], a[20]); // Sum(23) + res[21] = fma52lo(res[21], a[0], a[21]); // Sum(21) + res[22] = fma52hi(res[22], a[0], a[21]); // Sum(21) + res[22] = fma52lo(res[22], a[1], a[21]); // Sum(22) + res[23] = fma52hi(res[23], a[1], a[21]); // Sum(22) + res[23] = fma52lo(res[23], a[2], a[21]); // Sum(23) + res[24] = fma52hi(res[24], a[2], a[21]); // Sum(23) + res[22] = fma52lo(res[22], a[0], a[22]); // Sum(22) + res[23] = fma52hi(res[23], a[0], a[22]); // Sum(22) + res[23] = fma52lo(res[23], a[1], a[22]); // Sum(23) + res[24] = fma52hi(res[24], a[1], a[22]); // Sum(23) + res[23] = fma52lo(res[23], a[0], a[23]); // Sum(23) + res[24] = fma52hi(res[24], a[0], a[23]); // Sum(23) + res[12] = add64(res[12], res[12]); // Double(12) + res[13] = add64(res[13], res[13]); // Double(13) + res[14] = add64(res[14], res[14]); // Double(14) + res[15] = add64(res[15], res[15]); // Double(15) + res[16] = add64(res[16], res[16]); // Double(16) + res[17] = add64(res[17], res[17]); // Double(17) + res[18] = add64(res[18], res[18]); // Double(18) + res[19] = add64(res[19], res[19]); // Double(19) + res[20] = add64(res[20], res[20]); // Double(20) + res[21] = add64(res[21], res[21]); // Double(21) + res[22] = add64(res[22], res[22]); // Double(22) + res[23] = add64(res[23], res[23]); // Double(23) + res[12] = fma52lo(res[12], a[6], a[6]); // Add sqr(12) + res[13] = fma52hi(res[13], a[6], a[6]); // Add sqr(12) + res[14] = fma52lo(res[14], a[7], a[7]); // Add sqr(14) + res[15] = fma52hi(res[15], a[7], a[7]); // Add sqr(14) + res[16] = fma52lo(res[16], a[8], a[8]); // Add sqr(16) + res[17] = fma52hi(res[17], a[8], a[8]); // Add sqr(16) + res[18] = fma52lo(res[18], a[9], a[9]); // Add sqr(18) + res[19] = fma52hi(res[19], a[9], a[9]); // Add sqr(18) + res[20] = fma52lo(res[20], a[10], a[10]); // Add sqr(20) + res[21] = fma52hi(res[21], a[10], a[10]); // Add sqr(20) + res[22] = fma52lo(res[22], a[11], a[11]); // Add sqr(22) + res[23] = fma52hi(res[23], a[11], a[11]); // Add sqr(22) + res[24] = fma52lo(res[24], a[11], a[13]); // Sum(24) + res[25] = fma52hi(res[25], a[11], a[13]); // Sum(24) + res[25] = fma52lo(res[25], a[12], a[13]); // Sum(25) + res[26] = fma52hi(res[26], a[12], a[13]); // Sum(25) + res[24] = fma52lo(res[24], a[10], a[14]); // Sum(24) + res[25] = fma52hi(res[25], a[10], a[14]); // Sum(24) + res[25] = fma52lo(res[25], a[11], a[14]); // Sum(25) + res[26] = fma52hi(res[26], a[11], a[14]); // Sum(25) + res[26] = fma52lo(res[26], a[12], a[14]); // Sum(26) + res[27] = fma52hi(res[27], a[12], a[14]); // Sum(26) + res[27] = fma52lo(res[27], a[13], a[14]); // Sum(27) + res[28] = fma52hi(res[28], a[13], a[14]); // Sum(27) + res[24] = fma52lo(res[24], a[9], a[15]); // Sum(24) + res[25] = fma52hi(res[25], a[9], a[15]); // Sum(24) + res[25] = fma52lo(res[25], a[10], a[15]); // Sum(25) + res[26] = fma52hi(res[26], a[10], a[15]); // Sum(25) + res[26] = fma52lo(res[26], a[11], a[15]); // Sum(26) + res[27] = fma52hi(res[27], a[11], a[15]); // Sum(26) + res[27] = fma52lo(res[27], a[12], a[15]); // Sum(27) + res[28] = fma52hi(res[28], a[12], a[15]); // Sum(27) + res[28] = fma52lo(res[28], a[13], a[15]); // Sum(28) + res[29] = fma52hi(res[29], a[13], a[15]); // Sum(28) + res[29] = fma52lo(res[29], a[14], a[15]); // Sum(29) + res[30] = fma52hi(res[30], a[14], a[15]); // Sum(29) + res[24] = fma52lo(res[24], a[8], a[16]); // Sum(24) + res[25] = fma52hi(res[25], a[8], a[16]); // Sum(24) + res[25] = fma52lo(res[25], a[9], a[16]); // Sum(25) + res[26] = fma52hi(res[26], a[9], a[16]); // Sum(25) + res[26] = fma52lo(res[26], a[10], a[16]); // Sum(26) + res[27] = fma52hi(res[27], a[10], a[16]); // Sum(26) + res[27] = fma52lo(res[27], a[11], a[16]); // Sum(27) + res[28] = fma52hi(res[28], a[11], a[16]); // Sum(27) + res[28] = fma52lo(res[28], a[12], a[16]); // Sum(28) + res[29] = fma52hi(res[29], a[12], a[16]); // Sum(28) + res[29] = fma52lo(res[29], a[13], a[16]); // Sum(29) + res[30] = fma52hi(res[30], a[13], a[16]); // Sum(29) + res[30] = fma52lo(res[30], a[14], a[16]); // Sum(30) + res[31] = fma52hi(res[31], a[14], a[16]); // Sum(30) + res[31] = fma52lo(res[31], a[15], a[16]); // Sum(31) + res[32] = fma52hi(res[32], a[15], a[16]); // Sum(31) + res[24] = fma52lo(res[24], a[7], a[17]); // Sum(24) + res[25] = fma52hi(res[25], a[7], a[17]); // Sum(24) + res[25] = fma52lo(res[25], a[8], a[17]); // Sum(25) + res[26] = fma52hi(res[26], a[8], a[17]); // Sum(25) + res[26] = fma52lo(res[26], a[9], a[17]); // Sum(26) + res[27] = fma52hi(res[27], a[9], a[17]); // Sum(26) + res[27] = fma52lo(res[27], a[10], a[17]); // Sum(27) + res[28] = fma52hi(res[28], a[10], a[17]); // Sum(27) + res[28] = fma52lo(res[28], a[11], a[17]); // Sum(28) + res[29] = fma52hi(res[29], a[11], a[17]); // Sum(28) + res[29] = fma52lo(res[29], a[12], a[17]); // Sum(29) + res[30] = fma52hi(res[30], a[12], a[17]); // Sum(29) + res[30] = fma52lo(res[30], a[13], a[17]); // Sum(30) + res[31] = fma52hi(res[31], a[13], a[17]); // Sum(30) + res[31] = fma52lo(res[31], a[14], a[17]); // Sum(31) + res[32] = fma52hi(res[32], a[14], a[17]); // Sum(31) + res[32] = fma52lo(res[32], a[15], a[17]); // Sum(32) + res[33] = fma52hi(res[33], a[15], a[17]); // Sum(32) + res[33] = fma52lo(res[33], a[16], a[17]); // Sum(33) + res[34] = fma52hi(res[34], a[16], a[17]); // Sum(33) + res[24] = fma52lo(res[24], a[6], a[18]); // Sum(24) + res[25] = fma52hi(res[25], a[6], a[18]); // Sum(24) + res[25] = fma52lo(res[25], a[7], a[18]); // Sum(25) + res[26] = fma52hi(res[26], a[7], a[18]); // Sum(25) + res[26] = fma52lo(res[26], a[8], a[18]); // Sum(26) + res[27] = fma52hi(res[27], a[8], a[18]); // Sum(26) + res[27] = fma52lo(res[27], a[9], a[18]); // Sum(27) + res[28] = fma52hi(res[28], a[9], a[18]); // Sum(27) + res[28] = fma52lo(res[28], a[10], a[18]); // Sum(28) + res[29] = fma52hi(res[29], a[10], a[18]); // Sum(28) + res[29] = fma52lo(res[29], a[11], a[18]); // Sum(29) + res[30] = fma52hi(res[30], a[11], a[18]); // Sum(29) + res[30] = fma52lo(res[30], a[12], a[18]); // Sum(30) + res[31] = fma52hi(res[31], a[12], a[18]); // Sum(30) + res[31] = fma52lo(res[31], a[13], a[18]); // Sum(31) + res[32] = fma52hi(res[32], a[13], a[18]); // Sum(31) + res[32] = fma52lo(res[32], a[14], a[18]); // Sum(32) + res[33] = fma52hi(res[33], a[14], a[18]); // Sum(32) + res[33] = fma52lo(res[33], a[15], a[18]); // Sum(33) + res[34] = fma52hi(res[34], a[15], a[18]); // Sum(33) + res[34] = fma52lo(res[34], a[16], a[18]); // Sum(34) + res[35] = fma52hi(res[35], a[16], a[18]); // Sum(34) + res[35] = fma52lo(res[35], a[17], a[18]); // Sum(35) + res[36] = fma52hi(res[36], a[17], a[18]); // Sum(35) + res[24] = fma52lo(res[24], a[5], a[19]); // Sum(24) + res[25] = fma52hi(res[25], a[5], a[19]); // Sum(24) + res[25] = fma52lo(res[25], a[6], a[19]); // Sum(25) + res[26] = fma52hi(res[26], a[6], a[19]); // Sum(25) + res[26] = fma52lo(res[26], a[7], a[19]); // Sum(26) + res[27] = fma52hi(res[27], a[7], a[19]); // Sum(26) + res[27] = fma52lo(res[27], a[8], a[19]); // Sum(27) + res[28] = fma52hi(res[28], a[8], a[19]); // Sum(27) + res[28] = fma52lo(res[28], a[9], a[19]); // Sum(28) + res[29] = fma52hi(res[29], a[9], a[19]); // Sum(28) + res[29] = fma52lo(res[29], a[10], a[19]); // Sum(29) + res[30] = fma52hi(res[30], a[10], a[19]); // Sum(29) + res[30] = fma52lo(res[30], a[11], a[19]); // Sum(30) + res[31] = fma52hi(res[31], a[11], a[19]); // Sum(30) + res[31] = fma52lo(res[31], a[12], a[19]); // Sum(31) + res[32] = fma52hi(res[32], a[12], a[19]); // Sum(31) + res[32] = fma52lo(res[32], a[13], a[19]); // Sum(32) + res[33] = fma52hi(res[33], a[13], a[19]); // Sum(32) + res[33] = fma52lo(res[33], a[14], a[19]); // Sum(33) + res[34] = fma52hi(res[34], a[14], a[19]); // Sum(33) + res[34] = fma52lo(res[34], a[15], a[19]); // Sum(34) + res[35] = fma52hi(res[35], a[15], a[19]); // Sum(34) + res[35] = fma52lo(res[35], a[16], a[19]); // Sum(35) + res[36] = fma52hi(res[36], a[16], a[19]); // Sum(35) + res[24] = fma52lo(res[24], a[4], a[20]); // Sum(24) + res[25] = fma52hi(res[25], a[4], a[20]); // Sum(24) + res[25] = fma52lo(res[25], a[5], a[20]); // Sum(25) + res[26] = fma52hi(res[26], a[5], a[20]); // Sum(25) + res[26] = fma52lo(res[26], a[6], a[20]); // Sum(26) + res[27] = fma52hi(res[27], a[6], a[20]); // Sum(26) + res[27] = fma52lo(res[27], a[7], a[20]); // Sum(27) + res[28] = fma52hi(res[28], a[7], a[20]); // Sum(27) + res[28] = fma52lo(res[28], a[8], a[20]); // Sum(28) + res[29] = fma52hi(res[29], a[8], a[20]); // Sum(28) + res[29] = fma52lo(res[29], a[9], a[20]); // Sum(29) + res[30] = fma52hi(res[30], a[9], a[20]); // Sum(29) + res[30] = fma52lo(res[30], a[10], a[20]); // Sum(30) + res[31] = fma52hi(res[31], a[10], a[20]); // Sum(30) + res[31] = fma52lo(res[31], a[11], a[20]); // Sum(31) + res[32] = fma52hi(res[32], a[11], a[20]); // Sum(31) + res[32] = fma52lo(res[32], a[12], a[20]); // Sum(32) + res[33] = fma52hi(res[33], a[12], a[20]); // Sum(32) + res[33] = fma52lo(res[33], a[13], a[20]); // Sum(33) + res[34] = fma52hi(res[34], a[13], a[20]); // Sum(33) + res[34] = fma52lo(res[34], a[14], a[20]); // Sum(34) + res[35] = fma52hi(res[35], a[14], a[20]); // Sum(34) + res[35] = fma52lo(res[35], a[15], a[20]); // Sum(35) + res[36] = fma52hi(res[36], a[15], a[20]); // Sum(35) + res[24] = fma52lo(res[24], a[3], a[21]); // Sum(24) + res[25] = fma52hi(res[25], a[3], a[21]); // Sum(24) + res[25] = fma52lo(res[25], a[4], a[21]); // Sum(25) + res[26] = fma52hi(res[26], a[4], a[21]); // Sum(25) + res[26] = fma52lo(res[26], a[5], a[21]); // Sum(26) + res[27] = fma52hi(res[27], a[5], a[21]); // Sum(26) + res[27] = fma52lo(res[27], a[6], a[21]); // Sum(27) + res[28] = fma52hi(res[28], a[6], a[21]); // Sum(27) + res[28] = fma52lo(res[28], a[7], a[21]); // Sum(28) + res[29] = fma52hi(res[29], a[7], a[21]); // Sum(28) + res[29] = fma52lo(res[29], a[8], a[21]); // Sum(29) + res[30] = fma52hi(res[30], a[8], a[21]); // Sum(29) + res[30] = fma52lo(res[30], a[9], a[21]); // Sum(30) + res[31] = fma52hi(res[31], a[9], a[21]); // Sum(30) + res[31] = fma52lo(res[31], a[10], a[21]); // Sum(31) + res[32] = fma52hi(res[32], a[10], a[21]); // Sum(31) + res[32] = fma52lo(res[32], a[11], a[21]); // Sum(32) + res[33] = fma52hi(res[33], a[11], a[21]); // Sum(32) + res[33] = fma52lo(res[33], a[12], a[21]); // Sum(33) + res[34] = fma52hi(res[34], a[12], a[21]); // Sum(33) + res[34] = fma52lo(res[34], a[13], a[21]); // Sum(34) + res[35] = fma52hi(res[35], a[13], a[21]); // Sum(34) + res[35] = fma52lo(res[35], a[14], a[21]); // Sum(35) + res[36] = fma52hi(res[36], a[14], a[21]); // Sum(35) + res[24] = fma52lo(res[24], a[2], a[22]); // Sum(24) + res[25] = fma52hi(res[25], a[2], a[22]); // Sum(24) + res[25] = fma52lo(res[25], a[3], a[22]); // Sum(25) + res[26] = fma52hi(res[26], a[3], a[22]); // Sum(25) + res[26] = fma52lo(res[26], a[4], a[22]); // Sum(26) + res[27] = fma52hi(res[27], a[4], a[22]); // Sum(26) + res[27] = fma52lo(res[27], a[5], a[22]); // Sum(27) + res[28] = fma52hi(res[28], a[5], a[22]); // Sum(27) + res[28] = fma52lo(res[28], a[6], a[22]); // Sum(28) + res[29] = fma52hi(res[29], a[6], a[22]); // Sum(28) + res[29] = fma52lo(res[29], a[7], a[22]); // Sum(29) + res[30] = fma52hi(res[30], a[7], a[22]); // Sum(29) + res[30] = fma52lo(res[30], a[8], a[22]); // Sum(30) + res[31] = fma52hi(res[31], a[8], a[22]); // Sum(30) + res[31] = fma52lo(res[31], a[9], a[22]); // Sum(31) + res[32] = fma52hi(res[32], a[9], a[22]); // Sum(31) + res[32] = fma52lo(res[32], a[10], a[22]); // Sum(32) + res[33] = fma52hi(res[33], a[10], a[22]); // Sum(32) + res[33] = fma52lo(res[33], a[11], a[22]); // Sum(33) + res[34] = fma52hi(res[34], a[11], a[22]); // Sum(33) + res[34] = fma52lo(res[34], a[12], a[22]); // Sum(34) + res[35] = fma52hi(res[35], a[12], a[22]); // Sum(34) + res[35] = fma52lo(res[35], a[13], a[22]); // Sum(35) + res[36] = fma52hi(res[36], a[13], a[22]); // Sum(35) + res[24] = fma52lo(res[24], a[1], a[23]); // Sum(24) + res[25] = fma52hi(res[25], a[1], a[23]); // Sum(24) + res[25] = fma52lo(res[25], a[2], a[23]); // Sum(25) + res[26] = fma52hi(res[26], a[2], a[23]); // Sum(25) + res[26] = fma52lo(res[26], a[3], a[23]); // Sum(26) + res[27] = fma52hi(res[27], a[3], a[23]); // Sum(26) + res[27] = fma52lo(res[27], a[4], a[23]); // Sum(27) + res[28] = fma52hi(res[28], a[4], a[23]); // Sum(27) + res[28] = fma52lo(res[28], a[5], a[23]); // Sum(28) + res[29] = fma52hi(res[29], a[5], a[23]); // Sum(28) + res[29] = fma52lo(res[29], a[6], a[23]); // Sum(29) + res[30] = fma52hi(res[30], a[6], a[23]); // Sum(29) + res[30] = fma52lo(res[30], a[7], a[23]); // Sum(30) + res[31] = fma52hi(res[31], a[7], a[23]); // Sum(30) + res[31] = fma52lo(res[31], a[8], a[23]); // Sum(31) + res[32] = fma52hi(res[32], a[8], a[23]); // Sum(31) + res[32] = fma52lo(res[32], a[9], a[23]); // Sum(32) + res[33] = fma52hi(res[33], a[9], a[23]); // Sum(32) + res[33] = fma52lo(res[33], a[10], a[23]); // Sum(33) + res[34] = fma52hi(res[34], a[10], a[23]); // Sum(33) + res[34] = fma52lo(res[34], a[11], a[23]); // Sum(34) + res[35] = fma52hi(res[35], a[11], a[23]); // Sum(34) + res[35] = fma52lo(res[35], a[12], a[23]); // Sum(35) + res[36] = fma52hi(res[36], a[12], a[23]); // Sum(35) + res[24] = fma52lo(res[24], a[0], a[24]); // Sum(24) + res[25] = fma52hi(res[25], a[0], a[24]); // Sum(24) + res[25] = fma52lo(res[25], a[1], a[24]); // Sum(25) + res[26] = fma52hi(res[26], a[1], a[24]); // Sum(25) + res[26] = fma52lo(res[26], a[2], a[24]); // Sum(26) + res[27] = fma52hi(res[27], a[2], a[24]); // Sum(26) + res[27] = fma52lo(res[27], a[3], a[24]); // Sum(27) + res[28] = fma52hi(res[28], a[3], a[24]); // Sum(27) + res[28] = fma52lo(res[28], a[4], a[24]); // Sum(28) + res[29] = fma52hi(res[29], a[4], a[24]); // Sum(28) + res[29] = fma52lo(res[29], a[5], a[24]); // Sum(29) + res[30] = fma52hi(res[30], a[5], a[24]); // Sum(29) + res[30] = fma52lo(res[30], a[6], a[24]); // Sum(30) + res[31] = fma52hi(res[31], a[6], a[24]); // Sum(30) + res[31] = fma52lo(res[31], a[7], a[24]); // Sum(31) + res[32] = fma52hi(res[32], a[7], a[24]); // Sum(31) + res[32] = fma52lo(res[32], a[8], a[24]); // Sum(32) + res[33] = fma52hi(res[33], a[8], a[24]); // Sum(32) + res[33] = fma52lo(res[33], a[9], a[24]); // Sum(33) + res[34] = fma52hi(res[34], a[9], a[24]); // Sum(33) + res[34] = fma52lo(res[34], a[10], a[24]); // Sum(34) + res[35] = fma52hi(res[35], a[10], a[24]); // Sum(34) + res[35] = fma52lo(res[35], a[11], a[24]); // Sum(35) + res[36] = fma52hi(res[36], a[11], a[24]); // Sum(35) + res[25] = fma52lo(res[25], a[0], a[25]); // Sum(25) + res[26] = fma52hi(res[26], a[0], a[25]); // Sum(25) + res[26] = fma52lo(res[26], a[1], a[25]); // Sum(26) + res[27] = fma52hi(res[27], a[1], a[25]); // Sum(26) + res[27] = fma52lo(res[27], a[2], a[25]); // Sum(27) + res[28] = fma52hi(res[28], a[2], a[25]); // Sum(27) + res[28] = fma52lo(res[28], a[3], a[25]); // Sum(28) + res[29] = fma52hi(res[29], a[3], a[25]); // Sum(28) + res[29] = fma52lo(res[29], a[4], a[25]); // Sum(29) + res[30] = fma52hi(res[30], a[4], a[25]); // Sum(29) + res[30] = fma52lo(res[30], a[5], a[25]); // Sum(30) + res[31] = fma52hi(res[31], a[5], a[25]); // Sum(30) + res[31] = fma52lo(res[31], a[6], a[25]); // Sum(31) + res[32] = fma52hi(res[32], a[6], a[25]); // Sum(31) + res[32] = fma52lo(res[32], a[7], a[25]); // Sum(32) + res[33] = fma52hi(res[33], a[7], a[25]); // Sum(32) + res[33] = fma52lo(res[33], a[8], a[25]); // Sum(33) + res[34] = fma52hi(res[34], a[8], a[25]); // Sum(33) + res[34] = fma52lo(res[34], a[9], a[25]); // Sum(34) + res[35] = fma52hi(res[35], a[9], a[25]); // Sum(34) + res[35] = fma52lo(res[35], a[10], a[25]); // Sum(35) + res[36] = fma52hi(res[36], a[10], a[25]); // Sum(35) + res[26] = fma52lo(res[26], a[0], a[26]); // Sum(26) + res[27] = fma52hi(res[27], a[0], a[26]); // Sum(26) + res[27] = fma52lo(res[27], a[1], a[26]); // Sum(27) + res[28] = fma52hi(res[28], a[1], a[26]); // Sum(27) + res[28] = fma52lo(res[28], a[2], a[26]); // Sum(28) + res[29] = fma52hi(res[29], a[2], a[26]); // Sum(28) + res[29] = fma52lo(res[29], a[3], a[26]); // Sum(29) + res[30] = fma52hi(res[30], a[3], a[26]); // Sum(29) + res[30] = fma52lo(res[30], a[4], a[26]); // Sum(30) + res[31] = fma52hi(res[31], a[4], a[26]); // Sum(30) + res[31] = fma52lo(res[31], a[5], a[26]); // Sum(31) + res[32] = fma52hi(res[32], a[5], a[26]); // Sum(31) + res[32] = fma52lo(res[32], a[6], a[26]); // Sum(32) + res[33] = fma52hi(res[33], a[6], a[26]); // Sum(32) + res[33] = fma52lo(res[33], a[7], a[26]); // Sum(33) + res[34] = fma52hi(res[34], a[7], a[26]); // Sum(33) + res[34] = fma52lo(res[34], a[8], a[26]); // Sum(34) + res[35] = fma52hi(res[35], a[8], a[26]); // Sum(34) + res[35] = fma52lo(res[35], a[9], a[26]); // Sum(35) + res[36] = fma52hi(res[36], a[9], a[26]); // Sum(35) + res[27] = fma52lo(res[27], a[0], a[27]); // Sum(27) + res[28] = fma52hi(res[28], a[0], a[27]); // Sum(27) + res[28] = fma52lo(res[28], a[1], a[27]); // Sum(28) + res[29] = fma52hi(res[29], a[1], a[27]); // Sum(28) + res[29] = fma52lo(res[29], a[2], a[27]); // Sum(29) + res[30] = fma52hi(res[30], a[2], a[27]); // Sum(29) + res[30] = fma52lo(res[30], a[3], a[27]); // Sum(30) + res[31] = fma52hi(res[31], a[3], a[27]); // Sum(30) + res[31] = fma52lo(res[31], a[4], a[27]); // Sum(31) + res[32] = fma52hi(res[32], a[4], a[27]); // Sum(31) + res[32] = fma52lo(res[32], a[5], a[27]); // Sum(32) + res[33] = fma52hi(res[33], a[5], a[27]); // Sum(32) + res[33] = fma52lo(res[33], a[6], a[27]); // Sum(33) + res[34] = fma52hi(res[34], a[6], a[27]); // Sum(33) + res[34] = fma52lo(res[34], a[7], a[27]); // Sum(34) + res[35] = fma52hi(res[35], a[7], a[27]); // Sum(34) + res[35] = fma52lo(res[35], a[8], a[27]); // Sum(35) + res[36] = fma52hi(res[36], a[8], a[27]); // Sum(35) + res[28] = fma52lo(res[28], a[0], a[28]); // Sum(28) + res[29] = fma52hi(res[29], a[0], a[28]); // Sum(28) + res[29] = fma52lo(res[29], a[1], a[28]); // Sum(29) + res[30] = fma52hi(res[30], a[1], a[28]); // Sum(29) + res[30] = fma52lo(res[30], a[2], a[28]); // Sum(30) + res[31] = fma52hi(res[31], a[2], a[28]); // Sum(30) + res[31] = fma52lo(res[31], a[3], a[28]); // Sum(31) + res[32] = fma52hi(res[32], a[3], a[28]); // Sum(31) + res[32] = fma52lo(res[32], a[4], a[28]); // Sum(32) + res[33] = fma52hi(res[33], a[4], a[28]); // Sum(32) + res[33] = fma52lo(res[33], a[5], a[28]); // Sum(33) + res[34] = fma52hi(res[34], a[5], a[28]); // Sum(33) + res[34] = fma52lo(res[34], a[6], a[28]); // Sum(34) + res[35] = fma52hi(res[35], a[6], a[28]); // Sum(34) + res[35] = fma52lo(res[35], a[7], a[28]); // Sum(35) + res[36] = fma52hi(res[36], a[7], a[28]); // Sum(35) + res[29] = fma52lo(res[29], a[0], a[29]); // Sum(29) + res[30] = fma52hi(res[30], a[0], a[29]); // Sum(29) + res[30] = fma52lo(res[30], a[1], a[29]); // Sum(30) + res[31] = fma52hi(res[31], a[1], a[29]); // Sum(30) + res[31] = fma52lo(res[31], a[2], a[29]); // Sum(31) + res[32] = fma52hi(res[32], a[2], a[29]); // Sum(31) + res[32] = fma52lo(res[32], a[3], a[29]); // Sum(32) + res[33] = fma52hi(res[33], a[3], a[29]); // Sum(32) + res[33] = fma52lo(res[33], a[4], a[29]); // Sum(33) + res[34] = fma52hi(res[34], a[4], a[29]); // Sum(33) + res[34] = fma52lo(res[34], a[5], a[29]); // Sum(34) + res[35] = fma52hi(res[35], a[5], a[29]); // Sum(34) + res[35] = fma52lo(res[35], a[6], a[29]); // Sum(35) + res[36] = fma52hi(res[36], a[6], a[29]); // Sum(35) + res[30] = fma52lo(res[30], a[0], a[30]); // Sum(30) + res[31] = fma52hi(res[31], a[0], a[30]); // Sum(30) + res[31] = fma52lo(res[31], a[1], a[30]); // Sum(31) + res[32] = fma52hi(res[32], a[1], a[30]); // Sum(31) + res[32] = fma52lo(res[32], a[2], a[30]); // Sum(32) + res[33] = fma52hi(res[33], a[2], a[30]); // Sum(32) + res[33] = fma52lo(res[33], a[3], a[30]); // Sum(33) + res[34] = fma52hi(res[34], a[3], a[30]); // Sum(33) + res[34] = fma52lo(res[34], a[4], a[30]); // Sum(34) + res[35] = fma52hi(res[35], a[4], a[30]); // Sum(34) + res[35] = fma52lo(res[35], a[5], a[30]); // Sum(35) + res[36] = fma52hi(res[36], a[5], a[30]); // Sum(35) + res[31] = fma52lo(res[31], a[0], a[31]); // Sum(31) + res[32] = fma52hi(res[32], a[0], a[31]); // Sum(31) + res[32] = fma52lo(res[32], a[1], a[31]); // Sum(32) + res[33] = fma52hi(res[33], a[1], a[31]); // Sum(32) + res[33] = fma52lo(res[33], a[2], a[31]); // Sum(33) + res[34] = fma52hi(res[34], a[2], a[31]); // Sum(33) + res[34] = fma52lo(res[34], a[3], a[31]); // Sum(34) + res[35] = fma52hi(res[35], a[3], a[31]); // Sum(34) + res[35] = fma52lo(res[35], a[4], a[31]); // Sum(35) + res[36] = fma52hi(res[36], a[4], a[31]); // Sum(35) + res[32] = fma52lo(res[32], a[0], a[32]); // Sum(32) + res[33] = fma52hi(res[33], a[0], a[32]); // Sum(32) + res[33] = fma52lo(res[33], a[1], a[32]); // Sum(33) + res[34] = fma52hi(res[34], a[1], a[32]); // Sum(33) + res[34] = fma52lo(res[34], a[2], a[32]); // Sum(34) + res[35] = fma52hi(res[35], a[2], a[32]); // Sum(34) + res[35] = fma52lo(res[35], a[3], a[32]); // Sum(35) + res[36] = fma52hi(res[36], a[3], a[32]); // Sum(35) + res[33] = fma52lo(res[33], a[0], a[33]); // Sum(33) + res[34] = fma52hi(res[34], a[0], a[33]); // Sum(33) + res[34] = fma52lo(res[34], a[1], a[33]); // Sum(34) + res[35] = fma52hi(res[35], a[1], a[33]); // Sum(34) + res[35] = fma52lo(res[35], a[2], a[33]); // Sum(35) + res[36] = fma52hi(res[36], a[2], a[33]); // Sum(35) + res[34] = fma52lo(res[34], a[0], a[34]); // Sum(34) + res[35] = fma52hi(res[35], a[0], a[34]); // Sum(34) + res[35] = fma52lo(res[35], a[1], a[34]); // Sum(35) + res[36] = fma52hi(res[36], a[1], a[34]); // Sum(35) + res[35] = fma52lo(res[35], a[0], a[35]); // Sum(35) + res[36] = fma52hi(res[36], a[0], a[35]); // Sum(35) + res[24] = add64(res[24], res[24]); // Double(24) + res[25] = add64(res[25], res[25]); // Double(25) + res[26] = add64(res[26], res[26]); // Double(26) + res[27] = add64(res[27], res[27]); // Double(27) + res[28] = add64(res[28], res[28]); // Double(28) + res[29] = add64(res[29], res[29]); // Double(29) + res[30] = add64(res[30], res[30]); // Double(30) + res[31] = add64(res[31], res[31]); // Double(31) + res[32] = add64(res[32], res[32]); // Double(32) + res[33] = add64(res[33], res[33]); // Double(33) + res[34] = add64(res[34], res[34]); // Double(34) + res[35] = add64(res[35], res[35]); // Double(35) + res[24] = fma52lo(res[24], a[12], a[12]); // Add sqr(24) + res[25] = fma52hi(res[25], a[12], a[12]); // Add sqr(24) + res[26] = fma52lo(res[26], a[13], a[13]); // Add sqr(26) + res[27] = fma52hi(res[27], a[13], a[13]); // Add sqr(26) + res[28] = fma52lo(res[28], a[14], a[14]); // Add sqr(28) + res[29] = fma52hi(res[29], a[14], a[14]); // Add sqr(28) + res[30] = fma52lo(res[30], a[15], a[15]); // Add sqr(30) + res[31] = fma52hi(res[31], a[15], a[15]); // Add sqr(30) + res[32] = fma52lo(res[32], a[16], a[16]); // Add sqr(32) + res[33] = fma52hi(res[33], a[16], a[16]); // Add sqr(32) + res[34] = fma52lo(res[34], a[17], a[17]); // Add sqr(34) + res[35] = fma52hi(res[35], a[17], a[17]); // Add sqr(34) + res[36] = fma52lo(res[36], a[17], a[19]); // Sum(36) + res[37] = fma52hi(res[37], a[17], a[19]); // Sum(36) + res[37] = fma52lo(res[37], a[18], a[19]); // Sum(37) + res[38] = fma52hi(res[38], a[18], a[19]); // Sum(37) + res[36] = fma52lo(res[36], a[16], a[20]); // Sum(36) + res[37] = fma52hi(res[37], a[16], a[20]); // Sum(36) + res[37] = fma52lo(res[37], a[17], a[20]); // Sum(37) + res[38] = fma52hi(res[38], a[17], a[20]); // Sum(37) + res[38] = fma52lo(res[38], a[18], a[20]); // Sum(38) + res[39] = fma52hi(res[39], a[18], a[20]); // Sum(38) + res[39] = fma52lo(res[39], a[19], a[20]); // Sum(39) + res[40] = fma52hi(res[40], a[19], a[20]); // Sum(39) + res[36] = fma52lo(res[36], a[15], a[21]); // Sum(36) + res[37] = fma52hi(res[37], a[15], a[21]); // Sum(36) + res[37] = fma52lo(res[37], a[16], a[21]); // Sum(37) + res[38] = fma52hi(res[38], a[16], a[21]); // Sum(37) + res[38] = fma52lo(res[38], a[17], a[21]); // Sum(38) + res[39] = fma52hi(res[39], a[17], a[21]); // Sum(38) + res[39] = fma52lo(res[39], a[18], a[21]); // Sum(39) + res[40] = fma52hi(res[40], a[18], a[21]); // Sum(39) + res[40] = fma52lo(res[40], a[19], a[21]); // Sum(40) + res[41] = fma52hi(res[41], a[19], a[21]); // Sum(40) + res[41] = fma52lo(res[41], a[20], a[21]); // Sum(41) + res[42] = fma52hi(res[42], a[20], a[21]); // Sum(41) + res[36] = fma52lo(res[36], a[14], a[22]); // Sum(36) + res[37] = fma52hi(res[37], a[14], a[22]); // Sum(36) + res[37] = fma52lo(res[37], a[15], a[22]); // Sum(37) + res[38] = fma52hi(res[38], a[15], a[22]); // Sum(37) + res[38] = fma52lo(res[38], a[16], a[22]); // Sum(38) + res[39] = fma52hi(res[39], a[16], a[22]); // Sum(38) + res[39] = fma52lo(res[39], a[17], a[22]); // Sum(39) + res[40] = fma52hi(res[40], a[17], a[22]); // Sum(39) + res[40] = fma52lo(res[40], a[18], a[22]); // Sum(40) + res[41] = fma52hi(res[41], a[18], a[22]); // Sum(40) + res[41] = fma52lo(res[41], a[19], a[22]); // Sum(41) + res[42] = fma52hi(res[42], a[19], a[22]); // Sum(41) + res[42] = fma52lo(res[42], a[20], a[22]); // Sum(42) + res[43] = fma52hi(res[43], a[20], a[22]); // Sum(42) + res[43] = fma52lo(res[43], a[21], a[22]); // Sum(43) + res[44] = fma52hi(res[44], a[21], a[22]); // Sum(43) + res[36] = fma52lo(res[36], a[13], a[23]); // Sum(36) + res[37] = fma52hi(res[37], a[13], a[23]); // Sum(36) + res[37] = fma52lo(res[37], a[14], a[23]); // Sum(37) + res[38] = fma52hi(res[38], a[14], a[23]); // Sum(37) + res[38] = fma52lo(res[38], a[15], a[23]); // Sum(38) + res[39] = fma52hi(res[39], a[15], a[23]); // Sum(38) + res[39] = fma52lo(res[39], a[16], a[23]); // Sum(39) + res[40] = fma52hi(res[40], a[16], a[23]); // Sum(39) + res[40] = fma52lo(res[40], a[17], a[23]); // Sum(40) + res[41] = fma52hi(res[41], a[17], a[23]); // Sum(40) + res[41] = fma52lo(res[41], a[18], a[23]); // Sum(41) + res[42] = fma52hi(res[42], a[18], a[23]); // Sum(41) + res[42] = fma52lo(res[42], a[19], a[23]); // Sum(42) + res[43] = fma52hi(res[43], a[19], a[23]); // Sum(42) + res[43] = fma52lo(res[43], a[20], a[23]); // Sum(43) + res[44] = fma52hi(res[44], a[20], a[23]); // Sum(43) + res[44] = fma52lo(res[44], a[21], a[23]); // Sum(44) + res[45] = fma52hi(res[45], a[21], a[23]); // Sum(44) + res[45] = fma52lo(res[45], a[22], a[23]); // Sum(45) + res[46] = fma52hi(res[46], a[22], a[23]); // Sum(45) + res[36] = fma52lo(res[36], a[12], a[24]); // Sum(36) + res[37] = fma52hi(res[37], a[12], a[24]); // Sum(36) + res[37] = fma52lo(res[37], a[13], a[24]); // Sum(37) + res[38] = fma52hi(res[38], a[13], a[24]); // Sum(37) + res[38] = fma52lo(res[38], a[14], a[24]); // Sum(38) + res[39] = fma52hi(res[39], a[14], a[24]); // Sum(38) + res[39] = fma52lo(res[39], a[15], a[24]); // Sum(39) + res[40] = fma52hi(res[40], a[15], a[24]); // Sum(39) + res[40] = fma52lo(res[40], a[16], a[24]); // Sum(40) + res[41] = fma52hi(res[41], a[16], a[24]); // Sum(40) + res[41] = fma52lo(res[41], a[17], a[24]); // Sum(41) + res[42] = fma52hi(res[42], a[17], a[24]); // Sum(41) + res[42] = fma52lo(res[42], a[18], a[24]); // Sum(42) + res[43] = fma52hi(res[43], a[18], a[24]); // Sum(42) + res[43] = fma52lo(res[43], a[19], a[24]); // Sum(43) + res[44] = fma52hi(res[44], a[19], a[24]); // Sum(43) + res[44] = fma52lo(res[44], a[20], a[24]); // Sum(44) + res[45] = fma52hi(res[45], a[20], a[24]); // Sum(44) + res[45] = fma52lo(res[45], a[21], a[24]); // Sum(45) + res[46] = fma52hi(res[46], a[21], a[24]); // Sum(45) + res[46] = fma52lo(res[46], a[22], a[24]); // Sum(46) + res[47] = fma52hi(res[47], a[22], a[24]); // Sum(46) + res[47] = fma52lo(res[47], a[23], a[24]); // Sum(47) + res[48] = fma52hi(res[48], a[23], a[24]); // Sum(47) + res[36] = fma52lo(res[36], a[11], a[25]); // Sum(36) + res[37] = fma52hi(res[37], a[11], a[25]); // Sum(36) + res[37] = fma52lo(res[37], a[12], a[25]); // Sum(37) + res[38] = fma52hi(res[38], a[12], a[25]); // Sum(37) + res[38] = fma52lo(res[38], a[13], a[25]); // Sum(38) + res[39] = fma52hi(res[39], a[13], a[25]); // Sum(38) + res[39] = fma52lo(res[39], a[14], a[25]); // Sum(39) + res[40] = fma52hi(res[40], a[14], a[25]); // Sum(39) + res[40] = fma52lo(res[40], a[15], a[25]); // Sum(40) + res[41] = fma52hi(res[41], a[15], a[25]); // Sum(40) + res[41] = fma52lo(res[41], a[16], a[25]); // Sum(41) + res[42] = fma52hi(res[42], a[16], a[25]); // Sum(41) + res[42] = fma52lo(res[42], a[17], a[25]); // Sum(42) + res[43] = fma52hi(res[43], a[17], a[25]); // Sum(42) + res[43] = fma52lo(res[43], a[18], a[25]); // Sum(43) + res[44] = fma52hi(res[44], a[18], a[25]); // Sum(43) + res[44] = fma52lo(res[44], a[19], a[25]); // Sum(44) + res[45] = fma52hi(res[45], a[19], a[25]); // Sum(44) + res[45] = fma52lo(res[45], a[20], a[25]); // Sum(45) + res[46] = fma52hi(res[46], a[20], a[25]); // Sum(45) + res[46] = fma52lo(res[46], a[21], a[25]); // Sum(46) + res[47] = fma52hi(res[47], a[21], a[25]); // Sum(46) + res[47] = fma52lo(res[47], a[22], a[25]); // Sum(47) + res[48] = fma52hi(res[48], a[22], a[25]); // Sum(47) + res[36] = fma52lo(res[36], a[10], a[26]); // Sum(36) + res[37] = fma52hi(res[37], a[10], a[26]); // Sum(36) + res[37] = fma52lo(res[37], a[11], a[26]); // Sum(37) + res[38] = fma52hi(res[38], a[11], a[26]); // Sum(37) + res[38] = fma52lo(res[38], a[12], a[26]); // Sum(38) + res[39] = fma52hi(res[39], a[12], a[26]); // Sum(38) + res[39] = fma52lo(res[39], a[13], a[26]); // Sum(39) + res[40] = fma52hi(res[40], a[13], a[26]); // Sum(39) + res[40] = fma52lo(res[40], a[14], a[26]); // Sum(40) + res[41] = fma52hi(res[41], a[14], a[26]); // Sum(40) + res[41] = fma52lo(res[41], a[15], a[26]); // Sum(41) + res[42] = fma52hi(res[42], a[15], a[26]); // Sum(41) + res[42] = fma52lo(res[42], a[16], a[26]); // Sum(42) + res[43] = fma52hi(res[43], a[16], a[26]); // Sum(42) + res[43] = fma52lo(res[43], a[17], a[26]); // Sum(43) + res[44] = fma52hi(res[44], a[17], a[26]); // Sum(43) + res[44] = fma52lo(res[44], a[18], a[26]); // Sum(44) + res[45] = fma52hi(res[45], a[18], a[26]); // Sum(44) + res[45] = fma52lo(res[45], a[19], a[26]); // Sum(45) + res[46] = fma52hi(res[46], a[19], a[26]); // Sum(45) + res[46] = fma52lo(res[46], a[20], a[26]); // Sum(46) + res[47] = fma52hi(res[47], a[20], a[26]); // Sum(46) + res[47] = fma52lo(res[47], a[21], a[26]); // Sum(47) + res[48] = fma52hi(res[48], a[21], a[26]); // Sum(47) + res[36] = fma52lo(res[36], a[9], a[27]); // Sum(36) + res[37] = fma52hi(res[37], a[9], a[27]); // Sum(36) + res[37] = fma52lo(res[37], a[10], a[27]); // Sum(37) + res[38] = fma52hi(res[38], a[10], a[27]); // Sum(37) + res[38] = fma52lo(res[38], a[11], a[27]); // Sum(38) + res[39] = fma52hi(res[39], a[11], a[27]); // Sum(38) + res[39] = fma52lo(res[39], a[12], a[27]); // Sum(39) + res[40] = fma52hi(res[40], a[12], a[27]); // Sum(39) + res[40] = fma52lo(res[40], a[13], a[27]); // Sum(40) + res[41] = fma52hi(res[41], a[13], a[27]); // Sum(40) + res[41] = fma52lo(res[41], a[14], a[27]); // Sum(41) + res[42] = fma52hi(res[42], a[14], a[27]); // Sum(41) + res[42] = fma52lo(res[42], a[15], a[27]); // Sum(42) + res[43] = fma52hi(res[43], a[15], a[27]); // Sum(42) + res[43] = fma52lo(res[43], a[16], a[27]); // Sum(43) + res[44] = fma52hi(res[44], a[16], a[27]); // Sum(43) + res[44] = fma52lo(res[44], a[17], a[27]); // Sum(44) + res[45] = fma52hi(res[45], a[17], a[27]); // Sum(44) + res[45] = fma52lo(res[45], a[18], a[27]); // Sum(45) + res[46] = fma52hi(res[46], a[18], a[27]); // Sum(45) + res[46] = fma52lo(res[46], a[19], a[27]); // Sum(46) + res[47] = fma52hi(res[47], a[19], a[27]); // Sum(46) + res[47] = fma52lo(res[47], a[20], a[27]); // Sum(47) + res[48] = fma52hi(res[48], a[20], a[27]); // Sum(47) + res[36] = fma52lo(res[36], a[8], a[28]); // Sum(36) + res[37] = fma52hi(res[37], a[8], a[28]); // Sum(36) + res[37] = fma52lo(res[37], a[9], a[28]); // Sum(37) + res[38] = fma52hi(res[38], a[9], a[28]); // Sum(37) + res[38] = fma52lo(res[38], a[10], a[28]); // Sum(38) + res[39] = fma52hi(res[39], a[10], a[28]); // Sum(38) + res[39] = fma52lo(res[39], a[11], a[28]); // Sum(39) + res[40] = fma52hi(res[40], a[11], a[28]); // Sum(39) + res[40] = fma52lo(res[40], a[12], a[28]); // Sum(40) + res[41] = fma52hi(res[41], a[12], a[28]); // Sum(40) + res[41] = fma52lo(res[41], a[13], a[28]); // Sum(41) + res[42] = fma52hi(res[42], a[13], a[28]); // Sum(41) + res[42] = fma52lo(res[42], a[14], a[28]); // Sum(42) + res[43] = fma52hi(res[43], a[14], a[28]); // Sum(42) + res[43] = fma52lo(res[43], a[15], a[28]); // Sum(43) + res[44] = fma52hi(res[44], a[15], a[28]); // Sum(43) + res[44] = fma52lo(res[44], a[16], a[28]); // Sum(44) + res[45] = fma52hi(res[45], a[16], a[28]); // Sum(44) + res[45] = fma52lo(res[45], a[17], a[28]); // Sum(45) + res[46] = fma52hi(res[46], a[17], a[28]); // Sum(45) + res[46] = fma52lo(res[46], a[18], a[28]); // Sum(46) + res[47] = fma52hi(res[47], a[18], a[28]); // Sum(46) + res[47] = fma52lo(res[47], a[19], a[28]); // Sum(47) + res[48] = fma52hi(res[48], a[19], a[28]); // Sum(47) + res[36] = fma52lo(res[36], a[7], a[29]); // Sum(36) + res[37] = fma52hi(res[37], a[7], a[29]); // Sum(36) + res[37] = fma52lo(res[37], a[8], a[29]); // Sum(37) + res[38] = fma52hi(res[38], a[8], a[29]); // Sum(37) + res[38] = fma52lo(res[38], a[9], a[29]); // Sum(38) + res[39] = fma52hi(res[39], a[9], a[29]); // Sum(38) + res[39] = fma52lo(res[39], a[10], a[29]); // Sum(39) + res[40] = fma52hi(res[40], a[10], a[29]); // Sum(39) + res[40] = fma52lo(res[40], a[11], a[29]); // Sum(40) + res[41] = fma52hi(res[41], a[11], a[29]); // Sum(40) + res[41] = fma52lo(res[41], a[12], a[29]); // Sum(41) + res[42] = fma52hi(res[42], a[12], a[29]); // Sum(41) + res[42] = fma52lo(res[42], a[13], a[29]); // Sum(42) + res[43] = fma52hi(res[43], a[13], a[29]); // Sum(42) + res[43] = fma52lo(res[43], a[14], a[29]); // Sum(43) + res[44] = fma52hi(res[44], a[14], a[29]); // Sum(43) + res[44] = fma52lo(res[44], a[15], a[29]); // Sum(44) + res[45] = fma52hi(res[45], a[15], a[29]); // Sum(44) + res[45] = fma52lo(res[45], a[16], a[29]); // Sum(45) + res[46] = fma52hi(res[46], a[16], a[29]); // Sum(45) + res[46] = fma52lo(res[46], a[17], a[29]); // Sum(46) + res[47] = fma52hi(res[47], a[17], a[29]); // Sum(46) + res[47] = fma52lo(res[47], a[18], a[29]); // Sum(47) + res[48] = fma52hi(res[48], a[18], a[29]); // Sum(47) + res[36] = fma52lo(res[36], a[6], a[30]); // Sum(36) + res[37] = fma52hi(res[37], a[6], a[30]); // Sum(36) + res[37] = fma52lo(res[37], a[7], a[30]); // Sum(37) + res[38] = fma52hi(res[38], a[7], a[30]); // Sum(37) + res[38] = fma52lo(res[38], a[8], a[30]); // Sum(38) + res[39] = fma52hi(res[39], a[8], a[30]); // Sum(38) + res[39] = fma52lo(res[39], a[9], a[30]); // Sum(39) + res[40] = fma52hi(res[40], a[9], a[30]); // Sum(39) + res[40] = fma52lo(res[40], a[10], a[30]); // Sum(40) + res[41] = fma52hi(res[41], a[10], a[30]); // Sum(40) + res[41] = fma52lo(res[41], a[11], a[30]); // Sum(41) + res[42] = fma52hi(res[42], a[11], a[30]); // Sum(41) + res[42] = fma52lo(res[42], a[12], a[30]); // Sum(42) + res[43] = fma52hi(res[43], a[12], a[30]); // Sum(42) + res[43] = fma52lo(res[43], a[13], a[30]); // Sum(43) + res[44] = fma52hi(res[44], a[13], a[30]); // Sum(43) + res[44] = fma52lo(res[44], a[14], a[30]); // Sum(44) + res[45] = fma52hi(res[45], a[14], a[30]); // Sum(44) + res[45] = fma52lo(res[45], a[15], a[30]); // Sum(45) + res[46] = fma52hi(res[46], a[15], a[30]); // Sum(45) + res[46] = fma52lo(res[46], a[16], a[30]); // Sum(46) + res[47] = fma52hi(res[47], a[16], a[30]); // Sum(46) + res[47] = fma52lo(res[47], a[17], a[30]); // Sum(47) + res[48] = fma52hi(res[48], a[17], a[30]); // Sum(47) + res[36] = fma52lo(res[36], a[5], a[31]); // Sum(36) + res[37] = fma52hi(res[37], a[5], a[31]); // Sum(36) + res[37] = fma52lo(res[37], a[6], a[31]); // Sum(37) + res[38] = fma52hi(res[38], a[6], a[31]); // Sum(37) + res[38] = fma52lo(res[38], a[7], a[31]); // Sum(38) + res[39] = fma52hi(res[39], a[7], a[31]); // Sum(38) + res[39] = fma52lo(res[39], a[8], a[31]); // Sum(39) + res[40] = fma52hi(res[40], a[8], a[31]); // Sum(39) + res[40] = fma52lo(res[40], a[9], a[31]); // Sum(40) + res[41] = fma52hi(res[41], a[9], a[31]); // Sum(40) + res[41] = fma52lo(res[41], a[10], a[31]); // Sum(41) + res[42] = fma52hi(res[42], a[10], a[31]); // Sum(41) + res[42] = fma52lo(res[42], a[11], a[31]); // Sum(42) + res[43] = fma52hi(res[43], a[11], a[31]); // Sum(42) + res[43] = fma52lo(res[43], a[12], a[31]); // Sum(43) + res[44] = fma52hi(res[44], a[12], a[31]); // Sum(43) + res[44] = fma52lo(res[44], a[13], a[31]); // Sum(44) + res[45] = fma52hi(res[45], a[13], a[31]); // Sum(44) + res[45] = fma52lo(res[45], a[14], a[31]); // Sum(45) + res[46] = fma52hi(res[46], a[14], a[31]); // Sum(45) + res[46] = fma52lo(res[46], a[15], a[31]); // Sum(46) + res[47] = fma52hi(res[47], a[15], a[31]); // Sum(46) + res[47] = fma52lo(res[47], a[16], a[31]); // Sum(47) + res[48] = fma52hi(res[48], a[16], a[31]); // Sum(47) + res[36] = fma52lo(res[36], a[4], a[32]); // Sum(36) + res[37] = fma52hi(res[37], a[4], a[32]); // Sum(36) + res[37] = fma52lo(res[37], a[5], a[32]); // Sum(37) + res[38] = fma52hi(res[38], a[5], a[32]); // Sum(37) + res[38] = fma52lo(res[38], a[6], a[32]); // Sum(38) + res[39] = fma52hi(res[39], a[6], a[32]); // Sum(38) + res[39] = fma52lo(res[39], a[7], a[32]); // Sum(39) + res[40] = fma52hi(res[40], a[7], a[32]); // Sum(39) + res[40] = fma52lo(res[40], a[8], a[32]); // Sum(40) + res[41] = fma52hi(res[41], a[8], a[32]); // Sum(40) + res[41] = fma52lo(res[41], a[9], a[32]); // Sum(41) + res[42] = fma52hi(res[42], a[9], a[32]); // Sum(41) + res[42] = fma52lo(res[42], a[10], a[32]); // Sum(42) + res[43] = fma52hi(res[43], a[10], a[32]); // Sum(42) + res[43] = fma52lo(res[43], a[11], a[32]); // Sum(43) + res[44] = fma52hi(res[44], a[11], a[32]); // Sum(43) + res[44] = fma52lo(res[44], a[12], a[32]); // Sum(44) + res[45] = fma52hi(res[45], a[12], a[32]); // Sum(44) + res[45] = fma52lo(res[45], a[13], a[32]); // Sum(45) + res[46] = fma52hi(res[46], a[13], a[32]); // Sum(45) + res[46] = fma52lo(res[46], a[14], a[32]); // Sum(46) + res[47] = fma52hi(res[47], a[14], a[32]); // Sum(46) + res[47] = fma52lo(res[47], a[15], a[32]); // Sum(47) + res[48] = fma52hi(res[48], a[15], a[32]); // Sum(47) + res[36] = fma52lo(res[36], a[3], a[33]); // Sum(36) + res[37] = fma52hi(res[37], a[3], a[33]); // Sum(36) + res[37] = fma52lo(res[37], a[4], a[33]); // Sum(37) + res[38] = fma52hi(res[38], a[4], a[33]); // Sum(37) + res[38] = fma52lo(res[38], a[5], a[33]); // Sum(38) + res[39] = fma52hi(res[39], a[5], a[33]); // Sum(38) + res[39] = fma52lo(res[39], a[6], a[33]); // Sum(39) + res[40] = fma52hi(res[40], a[6], a[33]); // Sum(39) + res[40] = fma52lo(res[40], a[7], a[33]); // Sum(40) + res[41] = fma52hi(res[41], a[7], a[33]); // Sum(40) + res[41] = fma52lo(res[41], a[8], a[33]); // Sum(41) + res[42] = fma52hi(res[42], a[8], a[33]); // Sum(41) + res[42] = fma52lo(res[42], a[9], a[33]); // Sum(42) + res[43] = fma52hi(res[43], a[9], a[33]); // Sum(42) + res[43] = fma52lo(res[43], a[10], a[33]); // Sum(43) + res[44] = fma52hi(res[44], a[10], a[33]); // Sum(43) + res[44] = fma52lo(res[44], a[11], a[33]); // Sum(44) + res[45] = fma52hi(res[45], a[11], a[33]); // Sum(44) + res[45] = fma52lo(res[45], a[12], a[33]); // Sum(45) + res[46] = fma52hi(res[46], a[12], a[33]); // Sum(45) + res[46] = fma52lo(res[46], a[13], a[33]); // Sum(46) + res[47] = fma52hi(res[47], a[13], a[33]); // Sum(46) + res[47] = fma52lo(res[47], a[14], a[33]); // Sum(47) + res[48] = fma52hi(res[48], a[14], a[33]); // Sum(47) + res[36] = fma52lo(res[36], a[2], a[34]); // Sum(36) + res[37] = fma52hi(res[37], a[2], a[34]); // Sum(36) + res[37] = fma52lo(res[37], a[3], a[34]); // Sum(37) + res[38] = fma52hi(res[38], a[3], a[34]); // Sum(37) + res[38] = fma52lo(res[38], a[4], a[34]); // Sum(38) + res[39] = fma52hi(res[39], a[4], a[34]); // Sum(38) + res[39] = fma52lo(res[39], a[5], a[34]); // Sum(39) + res[40] = fma52hi(res[40], a[5], a[34]); // Sum(39) + res[40] = fma52lo(res[40], a[6], a[34]); // Sum(40) + res[41] = fma52hi(res[41], a[6], a[34]); // Sum(40) + res[41] = fma52lo(res[41], a[7], a[34]); // Sum(41) + res[42] = fma52hi(res[42], a[7], a[34]); // Sum(41) + res[42] = fma52lo(res[42], a[8], a[34]); // Sum(42) + res[43] = fma52hi(res[43], a[8], a[34]); // Sum(42) + res[43] = fma52lo(res[43], a[9], a[34]); // Sum(43) + res[44] = fma52hi(res[44], a[9], a[34]); // Sum(43) + res[44] = fma52lo(res[44], a[10], a[34]); // Sum(44) + res[45] = fma52hi(res[45], a[10], a[34]); // Sum(44) + res[45] = fma52lo(res[45], a[11], a[34]); // Sum(45) + res[46] = fma52hi(res[46], a[11], a[34]); // Sum(45) + res[46] = fma52lo(res[46], a[12], a[34]); // Sum(46) + res[47] = fma52hi(res[47], a[12], a[34]); // Sum(46) + res[47] = fma52lo(res[47], a[13], a[34]); // Sum(47) + res[48] = fma52hi(res[48], a[13], a[34]); // Sum(47) + res[36] = fma52lo(res[36], a[1], a[35]); // Sum(36) + res[37] = fma52hi(res[37], a[1], a[35]); // Sum(36) + res[37] = fma52lo(res[37], a[2], a[35]); // Sum(37) + res[38] = fma52hi(res[38], a[2], a[35]); // Sum(37) + res[38] = fma52lo(res[38], a[3], a[35]); // Sum(38) + res[39] = fma52hi(res[39], a[3], a[35]); // Sum(38) + res[39] = fma52lo(res[39], a[4], a[35]); // Sum(39) + res[40] = fma52hi(res[40], a[4], a[35]); // Sum(39) + res[40] = fma52lo(res[40], a[5], a[35]); // Sum(40) + res[41] = fma52hi(res[41], a[5], a[35]); // Sum(40) + res[41] = fma52lo(res[41], a[6], a[35]); // Sum(41) + res[42] = fma52hi(res[42], a[6], a[35]); // Sum(41) + res[42] = fma52lo(res[42], a[7], a[35]); // Sum(42) + res[43] = fma52hi(res[43], a[7], a[35]); // Sum(42) + res[43] = fma52lo(res[43], a[8], a[35]); // Sum(43) + res[44] = fma52hi(res[44], a[8], a[35]); // Sum(43) + res[44] = fma52lo(res[44], a[9], a[35]); // Sum(44) + res[45] = fma52hi(res[45], a[9], a[35]); // Sum(44) + res[45] = fma52lo(res[45], a[10], a[35]); // Sum(45) + res[46] = fma52hi(res[46], a[10], a[35]); // Sum(45) + res[46] = fma52lo(res[46], a[11], a[35]); // Sum(46) + res[47] = fma52hi(res[47], a[11], a[35]); // Sum(46) + res[47] = fma52lo(res[47], a[12], a[35]); // Sum(47) + res[48] = fma52hi(res[48], a[12], a[35]); // Sum(47) + res[36] = fma52lo(res[36], a[0], a[36]); // Sum(36) + res[37] = fma52hi(res[37], a[0], a[36]); // Sum(36) + res[37] = fma52lo(res[37], a[1], a[36]); // Sum(37) + res[38] = fma52hi(res[38], a[1], a[36]); // Sum(37) + res[38] = fma52lo(res[38], a[2], a[36]); // Sum(38) + res[39] = fma52hi(res[39], a[2], a[36]); // Sum(38) + res[39] = fma52lo(res[39], a[3], a[36]); // Sum(39) + res[40] = fma52hi(res[40], a[3], a[36]); // Sum(39) + res[40] = fma52lo(res[40], a[4], a[36]); // Sum(40) + res[41] = fma52hi(res[41], a[4], a[36]); // Sum(40) + res[41] = fma52lo(res[41], a[5], a[36]); // Sum(41) + res[42] = fma52hi(res[42], a[5], a[36]); // Sum(41) + res[42] = fma52lo(res[42], a[6], a[36]); // Sum(42) + res[43] = fma52hi(res[43], a[6], a[36]); // Sum(42) + res[43] = fma52lo(res[43], a[7], a[36]); // Sum(43) + res[44] = fma52hi(res[44], a[7], a[36]); // Sum(43) + res[44] = fma52lo(res[44], a[8], a[36]); // Sum(44) + res[45] = fma52hi(res[45], a[8], a[36]); // Sum(44) + res[45] = fma52lo(res[45], a[9], a[36]); // Sum(45) + res[46] = fma52hi(res[46], a[9], a[36]); // Sum(45) + res[46] = fma52lo(res[46], a[10], a[36]); // Sum(46) + res[47] = fma52hi(res[47], a[10], a[36]); // Sum(46) + res[47] = fma52lo(res[47], a[11], a[36]); // Sum(47) + res[48] = fma52hi(res[48], a[11], a[36]); // Sum(47) + res[37] = fma52lo(res[37], a[0], a[37]); // Sum(37) + res[38] = fma52hi(res[38], a[0], a[37]); // Sum(37) + res[38] = fma52lo(res[38], a[1], a[37]); // Sum(38) + res[39] = fma52hi(res[39], a[1], a[37]); // Sum(38) + res[39] = fma52lo(res[39], a[2], a[37]); // Sum(39) + res[40] = fma52hi(res[40], a[2], a[37]); // Sum(39) + res[40] = fma52lo(res[40], a[3], a[37]); // Sum(40) + res[41] = fma52hi(res[41], a[3], a[37]); // Sum(40) + res[41] = fma52lo(res[41], a[4], a[37]); // Sum(41) + res[42] = fma52hi(res[42], a[4], a[37]); // Sum(41) + res[42] = fma52lo(res[42], a[5], a[37]); // Sum(42) + res[43] = fma52hi(res[43], a[5], a[37]); // Sum(42) + res[43] = fma52lo(res[43], a[6], a[37]); // Sum(43) + res[44] = fma52hi(res[44], a[6], a[37]); // Sum(43) + res[44] = fma52lo(res[44], a[7], a[37]); // Sum(44) + res[45] = fma52hi(res[45], a[7], a[37]); // Sum(44) + res[45] = fma52lo(res[45], a[8], a[37]); // Sum(45) + res[46] = fma52hi(res[46], a[8], a[37]); // Sum(45) + res[46] = fma52lo(res[46], a[9], a[37]); // Sum(46) + res[47] = fma52hi(res[47], a[9], a[37]); // Sum(46) + res[47] = fma52lo(res[47], a[10], a[37]); // Sum(47) + res[48] = fma52hi(res[48], a[10], a[37]); // Sum(47) + res[38] = fma52lo(res[38], a[0], a[38]); // Sum(38) + res[39] = fma52hi(res[39], a[0], a[38]); // Sum(38) + res[39] = fma52lo(res[39], a[1], a[38]); // Sum(39) + res[40] = fma52hi(res[40], a[1], a[38]); // Sum(39) + res[40] = fma52lo(res[40], a[2], a[38]); // Sum(40) + res[41] = fma52hi(res[41], a[2], a[38]); // Sum(40) + res[41] = fma52lo(res[41], a[3], a[38]); // Sum(41) + res[42] = fma52hi(res[42], a[3], a[38]); // Sum(41) + res[42] = fma52lo(res[42], a[4], a[38]); // Sum(42) + res[43] = fma52hi(res[43], a[4], a[38]); // Sum(42) + res[43] = fma52lo(res[43], a[5], a[38]); // Sum(43) + res[44] = fma52hi(res[44], a[5], a[38]); // Sum(43) + res[44] = fma52lo(res[44], a[6], a[38]); // Sum(44) + res[45] = fma52hi(res[45], a[6], a[38]); // Sum(44) + res[45] = fma52lo(res[45], a[7], a[38]); // Sum(45) + res[46] = fma52hi(res[46], a[7], a[38]); // Sum(45) + res[46] = fma52lo(res[46], a[8], a[38]); // Sum(46) + res[47] = fma52hi(res[47], a[8], a[38]); // Sum(46) + res[47] = fma52lo(res[47], a[9], a[38]); // Sum(47) + res[48] = fma52hi(res[48], a[9], a[38]); // Sum(47) + res[39] = fma52lo(res[39], a[0], a[39]); // Sum(39) + res[40] = fma52hi(res[40], a[0], a[39]); // Sum(39) + res[40] = fma52lo(res[40], a[1], a[39]); // Sum(40) + res[41] = fma52hi(res[41], a[1], a[39]); // Sum(40) + res[41] = fma52lo(res[41], a[2], a[39]); // Sum(41) + res[42] = fma52hi(res[42], a[2], a[39]); // Sum(41) + res[42] = fma52lo(res[42], a[3], a[39]); // Sum(42) + res[43] = fma52hi(res[43], a[3], a[39]); // Sum(42) + res[43] = fma52lo(res[43], a[4], a[39]); // Sum(43) + res[44] = fma52hi(res[44], a[4], a[39]); // Sum(43) + res[44] = fma52lo(res[44], a[5], a[39]); // Sum(44) + res[45] = fma52hi(res[45], a[5], a[39]); // Sum(44) + res[45] = fma52lo(res[45], a[6], a[39]); // Sum(45) + res[46] = fma52hi(res[46], a[6], a[39]); // Sum(45) + res[46] = fma52lo(res[46], a[7], a[39]); // Sum(46) + res[47] = fma52hi(res[47], a[7], a[39]); // Sum(46) + res[47] = fma52lo(res[47], a[8], a[39]); // Sum(47) + res[48] = fma52hi(res[48], a[8], a[39]); // Sum(47) + res[36] = add64(res[36], res[36]); // Double(36) + res[37] = add64(res[37], res[37]); // Double(37) + res[38] = add64(res[38], res[38]); // Double(38) + res[39] = add64(res[39], res[39]); // Double(39) + res[40] = add64(res[40], res[40]); // Double(40) + res[41] = add64(res[41], res[41]); // Double(41) + res[42] = add64(res[42], res[42]); // Double(42) + res[43] = add64(res[43], res[43]); // Double(43) + res[44] = add64(res[44], res[44]); // Double(44) + res[45] = add64(res[45], res[45]); // Double(45) + res[46] = add64(res[46], res[46]); // Double(46) + res[47] = add64(res[47], res[47]); // Double(47) + res[36] = fma52lo(res[36], a[18], a[18]); // Add sqr(36) + res[37] = fma52hi(res[37], a[18], a[18]); // Add sqr(36) + res[38] = fma52lo(res[38], a[19], a[19]); // Add sqr(38) + res[39] = fma52hi(res[39], a[19], a[19]); // Add sqr(38) + res[40] = fma52lo(res[40], a[20], a[20]); // Add sqr(40) + res[41] = fma52hi(res[41], a[20], a[20]); // Add sqr(40) + res[42] = fma52lo(res[42], a[21], a[21]); // Add sqr(42) + res[43] = fma52hi(res[43], a[21], a[21]); // Add sqr(42) + res[44] = fma52lo(res[44], a[22], a[22]); // Add sqr(44) + res[45] = fma52hi(res[45], a[22], a[22]); // Add sqr(44) + res[46] = fma52lo(res[46], a[23], a[23]); // Add sqr(46) + res[47] = fma52hi(res[47], a[23], a[23]); // Add sqr(46) + res[48] = fma52lo(res[48], a[23], a[25]); // Sum(48) + res[49] = fma52hi(res[49], a[23], a[25]); // Sum(48) + res[49] = fma52lo(res[49], a[24], a[25]); // Sum(49) + res[50] = fma52hi(res[50], a[24], a[25]); // Sum(49) + res[48] = fma52lo(res[48], a[22], a[26]); // Sum(48) + res[49] = fma52hi(res[49], a[22], a[26]); // Sum(48) + res[49] = fma52lo(res[49], a[23], a[26]); // Sum(49) + res[50] = fma52hi(res[50], a[23], a[26]); // Sum(49) + res[50] = fma52lo(res[50], a[24], a[26]); // Sum(50) + res[51] = fma52hi(res[51], a[24], a[26]); // Sum(50) + res[51] = fma52lo(res[51], a[25], a[26]); // Sum(51) + res[52] = fma52hi(res[52], a[25], a[26]); // Sum(51) + res[48] = fma52lo(res[48], a[21], a[27]); // Sum(48) + res[49] = fma52hi(res[49], a[21], a[27]); // Sum(48) + res[49] = fma52lo(res[49], a[22], a[27]); // Sum(49) + res[50] = fma52hi(res[50], a[22], a[27]); // Sum(49) + res[50] = fma52lo(res[50], a[23], a[27]); // Sum(50) + res[51] = fma52hi(res[51], a[23], a[27]); // Sum(50) + res[51] = fma52lo(res[51], a[24], a[27]); // Sum(51) + res[52] = fma52hi(res[52], a[24], a[27]); // Sum(51) + res[52] = fma52lo(res[52], a[25], a[27]); // Sum(52) + res[53] = fma52hi(res[53], a[25], a[27]); // Sum(52) + res[53] = fma52lo(res[53], a[26], a[27]); // Sum(53) + res[54] = fma52hi(res[54], a[26], a[27]); // Sum(53) + res[48] = fma52lo(res[48], a[20], a[28]); // Sum(48) + res[49] = fma52hi(res[49], a[20], a[28]); // Sum(48) + res[49] = fma52lo(res[49], a[21], a[28]); // Sum(49) + res[50] = fma52hi(res[50], a[21], a[28]); // Sum(49) + res[50] = fma52lo(res[50], a[22], a[28]); // Sum(50) + res[51] = fma52hi(res[51], a[22], a[28]); // Sum(50) + res[51] = fma52lo(res[51], a[23], a[28]); // Sum(51) + res[52] = fma52hi(res[52], a[23], a[28]); // Sum(51) + res[52] = fma52lo(res[52], a[24], a[28]); // Sum(52) + res[53] = fma52hi(res[53], a[24], a[28]); // Sum(52) + res[53] = fma52lo(res[53], a[25], a[28]); // Sum(53) + res[54] = fma52hi(res[54], a[25], a[28]); // Sum(53) + res[54] = fma52lo(res[54], a[26], a[28]); // Sum(54) + res[55] = fma52hi(res[55], a[26], a[28]); // Sum(54) + res[55] = fma52lo(res[55], a[27], a[28]); // Sum(55) + res[56] = fma52hi(res[56], a[27], a[28]); // Sum(55) + res[48] = fma52lo(res[48], a[19], a[29]); // Sum(48) + res[49] = fma52hi(res[49], a[19], a[29]); // Sum(48) + res[49] = fma52lo(res[49], a[20], a[29]); // Sum(49) + res[50] = fma52hi(res[50], a[20], a[29]); // Sum(49) + res[50] = fma52lo(res[50], a[21], a[29]); // Sum(50) + res[51] = fma52hi(res[51], a[21], a[29]); // Sum(50) + res[51] = fma52lo(res[51], a[22], a[29]); // Sum(51) + res[52] = fma52hi(res[52], a[22], a[29]); // Sum(51) + res[52] = fma52lo(res[52], a[23], a[29]); // Sum(52) + res[53] = fma52hi(res[53], a[23], a[29]); // Sum(52) + res[53] = fma52lo(res[53], a[24], a[29]); // Sum(53) + res[54] = fma52hi(res[54], a[24], a[29]); // Sum(53) + res[54] = fma52lo(res[54], a[25], a[29]); // Sum(54) + res[55] = fma52hi(res[55], a[25], a[29]); // Sum(54) + res[55] = fma52lo(res[55], a[26], a[29]); // Sum(55) + res[56] = fma52hi(res[56], a[26], a[29]); // Sum(55) + res[56] = fma52lo(res[56], a[27], a[29]); // Sum(56) + res[57] = fma52hi(res[57], a[27], a[29]); // Sum(56) + res[57] = fma52lo(res[57], a[28], a[29]); // Sum(57) + res[58] = fma52hi(res[58], a[28], a[29]); // Sum(57) + res[48] = fma52lo(res[48], a[18], a[30]); // Sum(48) + res[49] = fma52hi(res[49], a[18], a[30]); // Sum(48) + res[49] = fma52lo(res[49], a[19], a[30]); // Sum(49) + res[50] = fma52hi(res[50], a[19], a[30]); // Sum(49) + res[50] = fma52lo(res[50], a[20], a[30]); // Sum(50) + res[51] = fma52hi(res[51], a[20], a[30]); // Sum(50) + res[51] = fma52lo(res[51], a[21], a[30]); // Sum(51) + res[52] = fma52hi(res[52], a[21], a[30]); // Sum(51) + res[52] = fma52lo(res[52], a[22], a[30]); // Sum(52) + res[53] = fma52hi(res[53], a[22], a[30]); // Sum(52) + res[53] = fma52lo(res[53], a[23], a[30]); // Sum(53) + res[54] = fma52hi(res[54], a[23], a[30]); // Sum(53) + res[54] = fma52lo(res[54], a[24], a[30]); // Sum(54) + res[55] = fma52hi(res[55], a[24], a[30]); // Sum(54) + res[55] = fma52lo(res[55], a[25], a[30]); // Sum(55) + res[56] = fma52hi(res[56], a[25], a[30]); // Sum(55) + res[56] = fma52lo(res[56], a[26], a[30]); // Sum(56) + res[57] = fma52hi(res[57], a[26], a[30]); // Sum(56) + res[57] = fma52lo(res[57], a[27], a[30]); // Sum(57) + res[58] = fma52hi(res[58], a[27], a[30]); // Sum(57) + res[58] = fma52lo(res[58], a[28], a[30]); // Sum(58) + res[59] = fma52hi(res[59], a[28], a[30]); // Sum(58) + res[59] = fma52lo(res[59], a[29], a[30]); // Sum(59) + res[60] = fma52hi(res[60], a[29], a[30]); // Sum(59) + res[48] = fma52lo(res[48], a[17], a[31]); // Sum(48) + res[49] = fma52hi(res[49], a[17], a[31]); // Sum(48) + res[49] = fma52lo(res[49], a[18], a[31]); // Sum(49) + res[50] = fma52hi(res[50], a[18], a[31]); // Sum(49) + res[50] = fma52lo(res[50], a[19], a[31]); // Sum(50) + res[51] = fma52hi(res[51], a[19], a[31]); // Sum(50) + res[51] = fma52lo(res[51], a[20], a[31]); // Sum(51) + res[52] = fma52hi(res[52], a[20], a[31]); // Sum(51) + res[52] = fma52lo(res[52], a[21], a[31]); // Sum(52) + res[53] = fma52hi(res[53], a[21], a[31]); // Sum(52) + res[53] = fma52lo(res[53], a[22], a[31]); // Sum(53) + res[54] = fma52hi(res[54], a[22], a[31]); // Sum(53) + res[54] = fma52lo(res[54], a[23], a[31]); // Sum(54) + res[55] = fma52hi(res[55], a[23], a[31]); // Sum(54) + res[55] = fma52lo(res[55], a[24], a[31]); // Sum(55) + res[56] = fma52hi(res[56], a[24], a[31]); // Sum(55) + res[56] = fma52lo(res[56], a[25], a[31]); // Sum(56) + res[57] = fma52hi(res[57], a[25], a[31]); // Sum(56) + res[57] = fma52lo(res[57], a[26], a[31]); // Sum(57) + res[58] = fma52hi(res[58], a[26], a[31]); // Sum(57) + res[58] = fma52lo(res[58], a[27], a[31]); // Sum(58) + res[59] = fma52hi(res[59], a[27], a[31]); // Sum(58) + res[59] = fma52lo(res[59], a[28], a[31]); // Sum(59) + res[60] = fma52hi(res[60], a[28], a[31]); // Sum(59) + res[48] = fma52lo(res[48], a[16], a[32]); // Sum(48) + res[49] = fma52hi(res[49], a[16], a[32]); // Sum(48) + res[49] = fma52lo(res[49], a[17], a[32]); // Sum(49) + res[50] = fma52hi(res[50], a[17], a[32]); // Sum(49) + res[50] = fma52lo(res[50], a[18], a[32]); // Sum(50) + res[51] = fma52hi(res[51], a[18], a[32]); // Sum(50) + res[51] = fma52lo(res[51], a[19], a[32]); // Sum(51) + res[52] = fma52hi(res[52], a[19], a[32]); // Sum(51) + res[52] = fma52lo(res[52], a[20], a[32]); // Sum(52) + res[53] = fma52hi(res[53], a[20], a[32]); // Sum(52) + res[53] = fma52lo(res[53], a[21], a[32]); // Sum(53) + res[54] = fma52hi(res[54], a[21], a[32]); // Sum(53) + res[54] = fma52lo(res[54], a[22], a[32]); // Sum(54) + res[55] = fma52hi(res[55], a[22], a[32]); // Sum(54) + res[55] = fma52lo(res[55], a[23], a[32]); // Sum(55) + res[56] = fma52hi(res[56], a[23], a[32]); // Sum(55) + res[56] = fma52lo(res[56], a[24], a[32]); // Sum(56) + res[57] = fma52hi(res[57], a[24], a[32]); // Sum(56) + res[57] = fma52lo(res[57], a[25], a[32]); // Sum(57) + res[58] = fma52hi(res[58], a[25], a[32]); // Sum(57) + res[58] = fma52lo(res[58], a[26], a[32]); // Sum(58) + res[59] = fma52hi(res[59], a[26], a[32]); // Sum(58) + res[59] = fma52lo(res[59], a[27], a[32]); // Sum(59) + res[60] = fma52hi(res[60], a[27], a[32]); // Sum(59) + res[48] = fma52lo(res[48], a[15], a[33]); // Sum(48) + res[49] = fma52hi(res[49], a[15], a[33]); // Sum(48) + res[49] = fma52lo(res[49], a[16], a[33]); // Sum(49) + res[50] = fma52hi(res[50], a[16], a[33]); // Sum(49) + res[50] = fma52lo(res[50], a[17], a[33]); // Sum(50) + res[51] = fma52hi(res[51], a[17], a[33]); // Sum(50) + res[51] = fma52lo(res[51], a[18], a[33]); // Sum(51) + res[52] = fma52hi(res[52], a[18], a[33]); // Sum(51) + res[52] = fma52lo(res[52], a[19], a[33]); // Sum(52) + res[53] = fma52hi(res[53], a[19], a[33]); // Sum(52) + res[53] = fma52lo(res[53], a[20], a[33]); // Sum(53) + res[54] = fma52hi(res[54], a[20], a[33]); // Sum(53) + res[54] = fma52lo(res[54], a[21], a[33]); // Sum(54) + res[55] = fma52hi(res[55], a[21], a[33]); // Sum(54) + res[55] = fma52lo(res[55], a[22], a[33]); // Sum(55) + res[56] = fma52hi(res[56], a[22], a[33]); // Sum(55) + res[56] = fma52lo(res[56], a[23], a[33]); // Sum(56) + res[57] = fma52hi(res[57], a[23], a[33]); // Sum(56) + res[57] = fma52lo(res[57], a[24], a[33]); // Sum(57) + res[58] = fma52hi(res[58], a[24], a[33]); // Sum(57) + res[58] = fma52lo(res[58], a[25], a[33]); // Sum(58) + res[59] = fma52hi(res[59], a[25], a[33]); // Sum(58) + res[59] = fma52lo(res[59], a[26], a[33]); // Sum(59) + res[60] = fma52hi(res[60], a[26], a[33]); // Sum(59) + res[48] = fma52lo(res[48], a[14], a[34]); // Sum(48) + res[49] = fma52hi(res[49], a[14], a[34]); // Sum(48) + res[49] = fma52lo(res[49], a[15], a[34]); // Sum(49) + res[50] = fma52hi(res[50], a[15], a[34]); // Sum(49) + res[50] = fma52lo(res[50], a[16], a[34]); // Sum(50) + res[51] = fma52hi(res[51], a[16], a[34]); // Sum(50) + res[51] = fma52lo(res[51], a[17], a[34]); // Sum(51) + res[52] = fma52hi(res[52], a[17], a[34]); // Sum(51) + res[52] = fma52lo(res[52], a[18], a[34]); // Sum(52) + res[53] = fma52hi(res[53], a[18], a[34]); // Sum(52) + res[53] = fma52lo(res[53], a[19], a[34]); // Sum(53) + res[54] = fma52hi(res[54], a[19], a[34]); // Sum(53) + res[54] = fma52lo(res[54], a[20], a[34]); // Sum(54) + res[55] = fma52hi(res[55], a[20], a[34]); // Sum(54) + res[55] = fma52lo(res[55], a[21], a[34]); // Sum(55) + res[56] = fma52hi(res[56], a[21], a[34]); // Sum(55) + res[56] = fma52lo(res[56], a[22], a[34]); // Sum(56) + res[57] = fma52hi(res[57], a[22], a[34]); // Sum(56) + res[57] = fma52lo(res[57], a[23], a[34]); // Sum(57) + res[58] = fma52hi(res[58], a[23], a[34]); // Sum(57) + res[58] = fma52lo(res[58], a[24], a[34]); // Sum(58) + res[59] = fma52hi(res[59], a[24], a[34]); // Sum(58) + res[59] = fma52lo(res[59], a[25], a[34]); // Sum(59) + res[60] = fma52hi(res[60], a[25], a[34]); // Sum(59) + res[48] = fma52lo(res[48], a[13], a[35]); // Sum(48) + res[49] = fma52hi(res[49], a[13], a[35]); // Sum(48) + res[49] = fma52lo(res[49], a[14], a[35]); // Sum(49) + res[50] = fma52hi(res[50], a[14], a[35]); // Sum(49) + res[50] = fma52lo(res[50], a[15], a[35]); // Sum(50) + res[51] = fma52hi(res[51], a[15], a[35]); // Sum(50) + res[51] = fma52lo(res[51], a[16], a[35]); // Sum(51) + res[52] = fma52hi(res[52], a[16], a[35]); // Sum(51) + res[52] = fma52lo(res[52], a[17], a[35]); // Sum(52) + res[53] = fma52hi(res[53], a[17], a[35]); // Sum(52) + res[53] = fma52lo(res[53], a[18], a[35]); // Sum(53) + res[54] = fma52hi(res[54], a[18], a[35]); // Sum(53) + res[54] = fma52lo(res[54], a[19], a[35]); // Sum(54) + res[55] = fma52hi(res[55], a[19], a[35]); // Sum(54) + res[55] = fma52lo(res[55], a[20], a[35]); // Sum(55) + res[56] = fma52hi(res[56], a[20], a[35]); // Sum(55) + res[56] = fma52lo(res[56], a[21], a[35]); // Sum(56) + res[57] = fma52hi(res[57], a[21], a[35]); // Sum(56) + res[57] = fma52lo(res[57], a[22], a[35]); // Sum(57) + res[58] = fma52hi(res[58], a[22], a[35]); // Sum(57) + res[58] = fma52lo(res[58], a[23], a[35]); // Sum(58) + res[59] = fma52hi(res[59], a[23], a[35]); // Sum(58) + res[59] = fma52lo(res[59], a[24], a[35]); // Sum(59) + res[60] = fma52hi(res[60], a[24], a[35]); // Sum(59) + res[48] = fma52lo(res[48], a[12], a[36]); // Sum(48) + res[49] = fma52hi(res[49], a[12], a[36]); // Sum(48) + res[49] = fma52lo(res[49], a[13], a[36]); // Sum(49) + res[50] = fma52hi(res[50], a[13], a[36]); // Sum(49) + res[50] = fma52lo(res[50], a[14], a[36]); // Sum(50) + res[51] = fma52hi(res[51], a[14], a[36]); // Sum(50) + res[51] = fma52lo(res[51], a[15], a[36]); // Sum(51) + res[52] = fma52hi(res[52], a[15], a[36]); // Sum(51) + res[52] = fma52lo(res[52], a[16], a[36]); // Sum(52) + res[53] = fma52hi(res[53], a[16], a[36]); // Sum(52) + res[53] = fma52lo(res[53], a[17], a[36]); // Sum(53) + res[54] = fma52hi(res[54], a[17], a[36]); // Sum(53) + res[54] = fma52lo(res[54], a[18], a[36]); // Sum(54) + res[55] = fma52hi(res[55], a[18], a[36]); // Sum(54) + res[55] = fma52lo(res[55], a[19], a[36]); // Sum(55) + res[56] = fma52hi(res[56], a[19], a[36]); // Sum(55) + res[56] = fma52lo(res[56], a[20], a[36]); // Sum(56) + res[57] = fma52hi(res[57], a[20], a[36]); // Sum(56) + res[57] = fma52lo(res[57], a[21], a[36]); // Sum(57) + res[58] = fma52hi(res[58], a[21], a[36]); // Sum(57) + res[58] = fma52lo(res[58], a[22], a[36]); // Sum(58) + res[59] = fma52hi(res[59], a[22], a[36]); // Sum(58) + res[59] = fma52lo(res[59], a[23], a[36]); // Sum(59) + res[60] = fma52hi(res[60], a[23], a[36]); // Sum(59) + res[48] = fma52lo(res[48], a[11], a[37]); // Sum(48) + res[49] = fma52hi(res[49], a[11], a[37]); // Sum(48) + res[49] = fma52lo(res[49], a[12], a[37]); // Sum(49) + res[50] = fma52hi(res[50], a[12], a[37]); // Sum(49) + res[50] = fma52lo(res[50], a[13], a[37]); // Sum(50) + res[51] = fma52hi(res[51], a[13], a[37]); // Sum(50) + res[51] = fma52lo(res[51], a[14], a[37]); // Sum(51) + res[52] = fma52hi(res[52], a[14], a[37]); // Sum(51) + res[52] = fma52lo(res[52], a[15], a[37]); // Sum(52) + res[53] = fma52hi(res[53], a[15], a[37]); // Sum(52) + res[53] = fma52lo(res[53], a[16], a[37]); // Sum(53) + res[54] = fma52hi(res[54], a[16], a[37]); // Sum(53) + res[54] = fma52lo(res[54], a[17], a[37]); // Sum(54) + res[55] = fma52hi(res[55], a[17], a[37]); // Sum(54) + res[55] = fma52lo(res[55], a[18], a[37]); // Sum(55) + res[56] = fma52hi(res[56], a[18], a[37]); // Sum(55) + res[56] = fma52lo(res[56], a[19], a[37]); // Sum(56) + res[57] = fma52hi(res[57], a[19], a[37]); // Sum(56) + res[57] = fma52lo(res[57], a[20], a[37]); // Sum(57) + res[58] = fma52hi(res[58], a[20], a[37]); // Sum(57) + res[58] = fma52lo(res[58], a[21], a[37]); // Sum(58) + res[59] = fma52hi(res[59], a[21], a[37]); // Sum(58) + res[59] = fma52lo(res[59], a[22], a[37]); // Sum(59) + res[60] = fma52hi(res[60], a[22], a[37]); // Sum(59) + res[48] = fma52lo(res[48], a[10], a[38]); // Sum(48) + res[49] = fma52hi(res[49], a[10], a[38]); // Sum(48) + res[49] = fma52lo(res[49], a[11], a[38]); // Sum(49) + res[50] = fma52hi(res[50], a[11], a[38]); // Sum(49) + res[50] = fma52lo(res[50], a[12], a[38]); // Sum(50) + res[51] = fma52hi(res[51], a[12], a[38]); // Sum(50) + res[51] = fma52lo(res[51], a[13], a[38]); // Sum(51) + res[52] = fma52hi(res[52], a[13], a[38]); // Sum(51) + res[52] = fma52lo(res[52], a[14], a[38]); // Sum(52) + res[53] = fma52hi(res[53], a[14], a[38]); // Sum(52) + res[53] = fma52lo(res[53], a[15], a[38]); // Sum(53) + res[54] = fma52hi(res[54], a[15], a[38]); // Sum(53) + res[54] = fma52lo(res[54], a[16], a[38]); // Sum(54) + res[55] = fma52hi(res[55], a[16], a[38]); // Sum(54) + res[55] = fma52lo(res[55], a[17], a[38]); // Sum(55) + res[56] = fma52hi(res[56], a[17], a[38]); // Sum(55) + res[56] = fma52lo(res[56], a[18], a[38]); // Sum(56) + res[57] = fma52hi(res[57], a[18], a[38]); // Sum(56) + res[57] = fma52lo(res[57], a[19], a[38]); // Sum(57) + res[58] = fma52hi(res[58], a[19], a[38]); // Sum(57) + res[58] = fma52lo(res[58], a[20], a[38]); // Sum(58) + res[59] = fma52hi(res[59], a[20], a[38]); // Sum(58) + res[59] = fma52lo(res[59], a[21], a[38]); // Sum(59) + res[60] = fma52hi(res[60], a[21], a[38]); // Sum(59) + res[48] = fma52lo(res[48], a[9], a[39]); // Sum(48) + res[49] = fma52hi(res[49], a[9], a[39]); // Sum(48) + res[49] = fma52lo(res[49], a[10], a[39]); // Sum(49) + res[50] = fma52hi(res[50], a[10], a[39]); // Sum(49) + res[50] = fma52lo(res[50], a[11], a[39]); // Sum(50) + res[51] = fma52hi(res[51], a[11], a[39]); // Sum(50) + res[51] = fma52lo(res[51], a[12], a[39]); // Sum(51) + res[52] = fma52hi(res[52], a[12], a[39]); // Sum(51) + res[52] = fma52lo(res[52], a[13], a[39]); // Sum(52) + res[53] = fma52hi(res[53], a[13], a[39]); // Sum(52) + res[53] = fma52lo(res[53], a[14], a[39]); // Sum(53) + res[54] = fma52hi(res[54], a[14], a[39]); // Sum(53) + res[54] = fma52lo(res[54], a[15], a[39]); // Sum(54) + res[55] = fma52hi(res[55], a[15], a[39]); // Sum(54) + res[55] = fma52lo(res[55], a[16], a[39]); // Sum(55) + res[56] = fma52hi(res[56], a[16], a[39]); // Sum(55) + res[56] = fma52lo(res[56], a[17], a[39]); // Sum(56) + res[57] = fma52hi(res[57], a[17], a[39]); // Sum(56) + res[57] = fma52lo(res[57], a[18], a[39]); // Sum(57) + res[58] = fma52hi(res[58], a[18], a[39]); // Sum(57) + res[58] = fma52lo(res[58], a[19], a[39]); // Sum(58) + res[59] = fma52hi(res[59], a[19], a[39]); // Sum(58) + res[59] = fma52lo(res[59], a[20], a[39]); // Sum(59) + res[60] = fma52hi(res[60], a[20], a[39]); // Sum(59) + res[48] = add64(res[48], res[48]); // Double(48) + res[49] = add64(res[49], res[49]); // Double(49) + res[50] = add64(res[50], res[50]); // Double(50) + res[51] = add64(res[51], res[51]); // Double(51) + res[52] = add64(res[52], res[52]); // Double(52) + res[53] = add64(res[53], res[53]); // Double(53) + res[54] = add64(res[54], res[54]); // Double(54) + res[55] = add64(res[55], res[55]); // Double(55) + res[56] = add64(res[56], res[56]); // Double(56) + res[57] = add64(res[57], res[57]); // Double(57) + res[58] = add64(res[58], res[58]); // Double(58) + res[59] = add64(res[59], res[59]); // Double(59) + res[48] = fma52lo(res[48], a[24], a[24]); // Add sqr(48) + res[49] = fma52hi(res[49], a[24], a[24]); // Add sqr(48) + res[50] = fma52lo(res[50], a[25], a[25]); // Add sqr(50) + res[51] = fma52hi(res[51], a[25], a[25]); // Add sqr(50) + res[52] = fma52lo(res[52], a[26], a[26]); // Add sqr(52) + res[53] = fma52hi(res[53], a[26], a[26]); // Add sqr(52) + res[54] = fma52lo(res[54], a[27], a[27]); // Add sqr(54) + res[55] = fma52hi(res[55], a[27], a[27]); // Add sqr(54) + res[56] = fma52lo(res[56], a[28], a[28]); // Add sqr(56) + res[57] = fma52hi(res[57], a[28], a[28]); // Add sqr(56) + res[58] = fma52lo(res[58], a[29], a[29]); // Add sqr(58) + res[59] = fma52hi(res[59], a[29], a[29]); // Add sqr(58) + res[60] = fma52lo(res[60], a[29], a[31]); // Sum(60) + res[61] = fma52hi(res[61], a[29], a[31]); // Sum(60) + res[61] = fma52lo(res[61], a[30], a[31]); // Sum(61) + res[62] = fma52hi(res[62], a[30], a[31]); // Sum(61) + res[60] = fma52lo(res[60], a[28], a[32]); // Sum(60) + res[61] = fma52hi(res[61], a[28], a[32]); // Sum(60) + res[61] = fma52lo(res[61], a[29], a[32]); // Sum(61) + res[62] = fma52hi(res[62], a[29], a[32]); // Sum(61) + res[62] = fma52lo(res[62], a[30], a[32]); // Sum(62) + res[63] = fma52hi(res[63], a[30], a[32]); // Sum(62) + res[63] = fma52lo(res[63], a[31], a[32]); // Sum(63) + res[64] = fma52hi(res[64], a[31], a[32]); // Sum(63) + res[60] = fma52lo(res[60], a[27], a[33]); // Sum(60) + res[61] = fma52hi(res[61], a[27], a[33]); // Sum(60) + res[61] = fma52lo(res[61], a[28], a[33]); // Sum(61) + res[62] = fma52hi(res[62], a[28], a[33]); // Sum(61) + res[62] = fma52lo(res[62], a[29], a[33]); // Sum(62) + res[63] = fma52hi(res[63], a[29], a[33]); // Sum(62) + res[63] = fma52lo(res[63], a[30], a[33]); // Sum(63) + res[64] = fma52hi(res[64], a[30], a[33]); // Sum(63) + res[64] = fma52lo(res[64], a[31], a[33]); // Sum(64) + res[65] = fma52hi(res[65], a[31], a[33]); // Sum(64) + res[65] = fma52lo(res[65], a[32], a[33]); // Sum(65) + res[66] = fma52hi(res[66], a[32], a[33]); // Sum(65) + res[60] = fma52lo(res[60], a[26], a[34]); // Sum(60) + res[61] = fma52hi(res[61], a[26], a[34]); // Sum(60) + res[61] = fma52lo(res[61], a[27], a[34]); // Sum(61) + res[62] = fma52hi(res[62], a[27], a[34]); // Sum(61) + res[62] = fma52lo(res[62], a[28], a[34]); // Sum(62) + res[63] = fma52hi(res[63], a[28], a[34]); // Sum(62) + res[63] = fma52lo(res[63], a[29], a[34]); // Sum(63) + res[64] = fma52hi(res[64], a[29], a[34]); // Sum(63) + res[64] = fma52lo(res[64], a[30], a[34]); // Sum(64) + res[65] = fma52hi(res[65], a[30], a[34]); // Sum(64) + res[65] = fma52lo(res[65], a[31], a[34]); // Sum(65) + res[66] = fma52hi(res[66], a[31], a[34]); // Sum(65) + res[66] = fma52lo(res[66], a[32], a[34]); // Sum(66) + res[67] = fma52hi(res[67], a[32], a[34]); // Sum(66) + res[67] = fma52lo(res[67], a[33], a[34]); // Sum(67) + res[68] = fma52hi(res[68], a[33], a[34]); // Sum(67) + res[60] = fma52lo(res[60], a[25], a[35]); // Sum(60) + res[61] = fma52hi(res[61], a[25], a[35]); // Sum(60) + res[61] = fma52lo(res[61], a[26], a[35]); // Sum(61) + res[62] = fma52hi(res[62], a[26], a[35]); // Sum(61) + res[62] = fma52lo(res[62], a[27], a[35]); // Sum(62) + res[63] = fma52hi(res[63], a[27], a[35]); // Sum(62) + res[63] = fma52lo(res[63], a[28], a[35]); // Sum(63) + res[64] = fma52hi(res[64], a[28], a[35]); // Sum(63) + res[64] = fma52lo(res[64], a[29], a[35]); // Sum(64) + res[65] = fma52hi(res[65], a[29], a[35]); // Sum(64) + res[65] = fma52lo(res[65], a[30], a[35]); // Sum(65) + res[66] = fma52hi(res[66], a[30], a[35]); // Sum(65) + res[66] = fma52lo(res[66], a[31], a[35]); // Sum(66) + res[67] = fma52hi(res[67], a[31], a[35]); // Sum(66) + res[67] = fma52lo(res[67], a[32], a[35]); // Sum(67) + res[68] = fma52hi(res[68], a[32], a[35]); // Sum(67) + res[68] = fma52lo(res[68], a[33], a[35]); // Sum(68) + res[69] = fma52hi(res[69], a[33], a[35]); // Sum(68) + res[69] = fma52lo(res[69], a[34], a[35]); // Sum(69) + res[70] = fma52hi(res[70], a[34], a[35]); // Sum(69) + res[60] = fma52lo(res[60], a[24], a[36]); // Sum(60) + res[61] = fma52hi(res[61], a[24], a[36]); // Sum(60) + res[61] = fma52lo(res[61], a[25], a[36]); // Sum(61) + res[62] = fma52hi(res[62], a[25], a[36]); // Sum(61) + res[62] = fma52lo(res[62], a[26], a[36]); // Sum(62) + res[63] = fma52hi(res[63], a[26], a[36]); // Sum(62) + res[63] = fma52lo(res[63], a[27], a[36]); // Sum(63) + res[64] = fma52hi(res[64], a[27], a[36]); // Sum(63) + res[64] = fma52lo(res[64], a[28], a[36]); // Sum(64) + res[65] = fma52hi(res[65], a[28], a[36]); // Sum(64) + res[65] = fma52lo(res[65], a[29], a[36]); // Sum(65) + res[66] = fma52hi(res[66], a[29], a[36]); // Sum(65) + res[66] = fma52lo(res[66], a[30], a[36]); // Sum(66) + res[67] = fma52hi(res[67], a[30], a[36]); // Sum(66) + res[67] = fma52lo(res[67], a[31], a[36]); // Sum(67) + res[68] = fma52hi(res[68], a[31], a[36]); // Sum(67) + res[68] = fma52lo(res[68], a[32], a[36]); // Sum(68) + res[69] = fma52hi(res[69], a[32], a[36]); // Sum(68) + res[69] = fma52lo(res[69], a[33], a[36]); // Sum(69) + res[70] = fma52hi(res[70], a[33], a[36]); // Sum(69) + res[70] = fma52lo(res[70], a[34], a[36]); // Sum(70) + res[71] = fma52hi(res[71], a[34], a[36]); // Sum(70) + res[71] = fma52lo(res[71], a[35], a[36]); // Sum(71) + res[72] = fma52hi(res[72], a[35], a[36]); // Sum(71) + res[60] = fma52lo(res[60], a[23], a[37]); // Sum(60) + res[61] = fma52hi(res[61], a[23], a[37]); // Sum(60) + res[61] = fma52lo(res[61], a[24], a[37]); // Sum(61) + res[62] = fma52hi(res[62], a[24], a[37]); // Sum(61) + res[62] = fma52lo(res[62], a[25], a[37]); // Sum(62) + res[63] = fma52hi(res[63], a[25], a[37]); // Sum(62) + res[63] = fma52lo(res[63], a[26], a[37]); // Sum(63) + res[64] = fma52hi(res[64], a[26], a[37]); // Sum(63) + res[64] = fma52lo(res[64], a[27], a[37]); // Sum(64) + res[65] = fma52hi(res[65], a[27], a[37]); // Sum(64) + res[65] = fma52lo(res[65], a[28], a[37]); // Sum(65) + res[66] = fma52hi(res[66], a[28], a[37]); // Sum(65) + res[66] = fma52lo(res[66], a[29], a[37]); // Sum(66) + res[67] = fma52hi(res[67], a[29], a[37]); // Sum(66) + res[67] = fma52lo(res[67], a[30], a[37]); // Sum(67) + res[68] = fma52hi(res[68], a[30], a[37]); // Sum(67) + res[68] = fma52lo(res[68], a[31], a[37]); // Sum(68) + res[69] = fma52hi(res[69], a[31], a[37]); // Sum(68) + res[69] = fma52lo(res[69], a[32], a[37]); // Sum(69) + res[70] = fma52hi(res[70], a[32], a[37]); // Sum(69) + res[70] = fma52lo(res[70], a[33], a[37]); // Sum(70) + res[71] = fma52hi(res[71], a[33], a[37]); // Sum(70) + res[71] = fma52lo(res[71], a[34], a[37]); // Sum(71) + res[72] = fma52hi(res[72], a[34], a[37]); // Sum(71) + res[60] = fma52lo(res[60], a[22], a[38]); // Sum(60) + res[61] = fma52hi(res[61], a[22], a[38]); // Sum(60) + res[61] = fma52lo(res[61], a[23], a[38]); // Sum(61) + res[62] = fma52hi(res[62], a[23], a[38]); // Sum(61) + res[62] = fma52lo(res[62], a[24], a[38]); // Sum(62) + res[63] = fma52hi(res[63], a[24], a[38]); // Sum(62) + res[63] = fma52lo(res[63], a[25], a[38]); // Sum(63) + res[64] = fma52hi(res[64], a[25], a[38]); // Sum(63) + res[64] = fma52lo(res[64], a[26], a[38]); // Sum(64) + res[65] = fma52hi(res[65], a[26], a[38]); // Sum(64) + res[65] = fma52lo(res[65], a[27], a[38]); // Sum(65) + res[66] = fma52hi(res[66], a[27], a[38]); // Sum(65) + res[66] = fma52lo(res[66], a[28], a[38]); // Sum(66) + res[67] = fma52hi(res[67], a[28], a[38]); // Sum(66) + res[67] = fma52lo(res[67], a[29], a[38]); // Sum(67) + res[68] = fma52hi(res[68], a[29], a[38]); // Sum(67) + res[68] = fma52lo(res[68], a[30], a[38]); // Sum(68) + res[69] = fma52hi(res[69], a[30], a[38]); // Sum(68) + res[69] = fma52lo(res[69], a[31], a[38]); // Sum(69) + res[70] = fma52hi(res[70], a[31], a[38]); // Sum(69) + res[70] = fma52lo(res[70], a[32], a[38]); // Sum(70) + res[71] = fma52hi(res[71], a[32], a[38]); // Sum(70) + res[71] = fma52lo(res[71], a[33], a[38]); // Sum(71) + res[72] = fma52hi(res[72], a[33], a[38]); // Sum(71) + res[60] = fma52lo(res[60], a[21], a[39]); // Sum(60) + res[61] = fma52hi(res[61], a[21], a[39]); // Sum(60) + res[61] = fma52lo(res[61], a[22], a[39]); // Sum(61) + res[62] = fma52hi(res[62], a[22], a[39]); // Sum(61) + res[62] = fma52lo(res[62], a[23], a[39]); // Sum(62) + res[63] = fma52hi(res[63], a[23], a[39]); // Sum(62) + res[63] = fma52lo(res[63], a[24], a[39]); // Sum(63) + res[64] = fma52hi(res[64], a[24], a[39]); // Sum(63) + res[64] = fma52lo(res[64], a[25], a[39]); // Sum(64) + res[65] = fma52hi(res[65], a[25], a[39]); // Sum(64) + res[65] = fma52lo(res[65], a[26], a[39]); // Sum(65) + res[66] = fma52hi(res[66], a[26], a[39]); // Sum(65) + res[66] = fma52lo(res[66], a[27], a[39]); // Sum(66) + res[67] = fma52hi(res[67], a[27], a[39]); // Sum(66) + res[67] = fma52lo(res[67], a[28], a[39]); // Sum(67) + res[68] = fma52hi(res[68], a[28], a[39]); // Sum(67) + res[68] = fma52lo(res[68], a[29], a[39]); // Sum(68) + res[69] = fma52hi(res[69], a[29], a[39]); // Sum(68) + res[69] = fma52lo(res[69], a[30], a[39]); // Sum(69) + res[70] = fma52hi(res[70], a[30], a[39]); // Sum(69) + res[70] = fma52lo(res[70], a[31], a[39]); // Sum(70) + res[71] = fma52hi(res[71], a[31], a[39]); // Sum(70) + res[71] = fma52lo(res[71], a[32], a[39]); // Sum(71) + res[72] = fma52hi(res[72], a[32], a[39]); // Sum(71) + res[60] = add64(res[60], res[60]); // Double(60) + res[61] = add64(res[61], res[61]); // Double(61) + res[62] = add64(res[62], res[62]); // Double(62) + res[63] = add64(res[63], res[63]); // Double(63) + res[64] = add64(res[64], res[64]); // Double(64) + res[65] = add64(res[65], res[65]); // Double(65) + res[66] = add64(res[66], res[66]); // Double(66) + res[67] = add64(res[67], res[67]); // Double(67) + res[68] = add64(res[68], res[68]); // Double(68) + res[69] = add64(res[69], res[69]); // Double(69) + res[70] = add64(res[70], res[70]); // Double(70) + res[71] = add64(res[71], res[71]); // Double(71) + res[60] = fma52lo(res[60], a[30], a[30]); // Add sqr(60) + res[61] = fma52hi(res[61], a[30], a[30]); // Add sqr(60) + res[62] = fma52lo(res[62], a[31], a[31]); // Add sqr(62) + res[63] = fma52hi(res[63], a[31], a[31]); // Add sqr(62) + res[64] = fma52lo(res[64], a[32], a[32]); // Add sqr(64) + res[65] = fma52hi(res[65], a[32], a[32]); // Add sqr(64) + res[66] = fma52lo(res[66], a[33], a[33]); // Add sqr(66) + res[67] = fma52hi(res[67], a[33], a[33]); // Add sqr(66) + res[68] = fma52lo(res[68], a[34], a[34]); // Add sqr(68) + res[69] = fma52hi(res[69], a[34], a[34]); // Add sqr(68) + res[70] = fma52lo(res[70], a[35], a[35]); // Add sqr(70) + res[71] = fma52hi(res[71], a[35], a[35]); // Add sqr(70) + res[72] = fma52lo(res[72], a[35], a[37]); // Sum(72) + res[73] = fma52hi(res[73], a[35], a[37]); // Sum(72) + res[73] = fma52lo(res[73], a[36], a[37]); // Sum(73) + res[74] = fma52hi(res[74], a[36], a[37]); // Sum(73) + res[72] = fma52lo(res[72], a[34], a[38]); // Sum(72) + res[73] = fma52hi(res[73], a[34], a[38]); // Sum(72) + res[73] = fma52lo(res[73], a[35], a[38]); // Sum(73) + res[74] = fma52hi(res[74], a[35], a[38]); // Sum(73) + res[74] = fma52lo(res[74], a[36], a[38]); // Sum(74) + res[75] = fma52hi(res[75], a[36], a[38]); // Sum(74) + res[75] = fma52lo(res[75], a[37], a[38]); // Sum(75) + res[76] = fma52hi(res[76], a[37], a[38]); // Sum(75) + res[72] = fma52lo(res[72], a[33], a[39]); // Sum(72) + res[73] = fma52hi(res[73], a[33], a[39]); // Sum(72) + res[73] = fma52lo(res[73], a[34], a[39]); // Sum(73) + res[74] = fma52hi(res[74], a[34], a[39]); // Sum(73) + res[74] = fma52lo(res[74], a[35], a[39]); // Sum(74) + res[75] = fma52hi(res[75], a[35], a[39]); // Sum(74) + res[75] = fma52lo(res[75], a[36], a[39]); // Sum(75) + res[76] = fma52hi(res[76], a[36], a[39]); // Sum(75) + res[76] = fma52lo(res[76], a[37], a[39]); // Sum(76) + res[77] = fma52hi(res[77], a[37], a[39]); // Sum(76) + res[77] = fma52lo(res[77], a[38], a[39]); // Sum(77) + res[78] = fma52hi(res[78], a[38], a[39]); // Sum(77) + res[72] = add64(res[72], res[72]); // Double(72) + res[73] = add64(res[73], res[73]); // Double(73) + res[74] = add64(res[74], res[74]); // Double(74) + res[75] = add64(res[75], res[75]); // Double(75) + res[76] = add64(res[76], res[76]); // Double(76) + res[77] = add64(res[77], res[77]); // Double(77) + res[78] = add64(res[78], res[78]); // Double(78) + res[72] = fma52lo(res[72], a[36], a[36]); // Add sqr(72) + res[73] = fma52hi(res[73], a[36], a[36]); // Add sqr(72) + res[74] = fma52lo(res[74], a[37], a[37]); // Add sqr(74) + res[75] = fma52hi(res[75], a[37], a[37]); // Add sqr(74) + res[76] = fma52lo(res[76], a[38], a[38]); // Add sqr(76) + res[77] = fma52hi(res[77], a[38], a[38]); // Add sqr(76) + res[78] = fma52lo(res[78], a[39], a[39]); // Add sqr(78) + res[79] = fma52hi(res[79], a[39], a[39]); // Add sqr(78) + + // Montgomery Reduction + int it; + for (it = 0; it < 40; it += 10) { // Reduction step + int jt = 0; + if ((it + 0) > 0) + res[it + 0] = add64(res[it + 0], srli64(res[it + -1], DIGIT_SIZE)); + u[it + 0] = mul52lo(res[it + 0], k); + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + 1] = add64(res[it + 1], srli64(res[it + 0], DIGIT_SIZE)); + u[it + 1] = mul52lo(res[it + 1], k); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + 2] = add64(res[it + 2], srli64(res[it + 1], DIGIT_SIZE)); + u[it + 2] = mul52lo(res[it + 2], k); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + 3] = add64(res[it + 3], srli64(res[it + 2], DIGIT_SIZE)); + u[it + 3] = mul52lo(res[it + 3], k); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + 4] = add64(res[it + 4], srli64(res[it + 3], DIGIT_SIZE)); + u[it + 4] = mul52lo(res[it + 4], k); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + 5] = add64(res[it + 5], srli64(res[it + 4], DIGIT_SIZE)); + u[it + 5] = mul52lo(res[it + 5], k); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + 6] = add64(res[it + 6], srli64(res[it + 5], DIGIT_SIZE)); + u[it + 6] = mul52lo(res[it + 6], k); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + 7] = add64(res[it + 7], srli64(res[it + 6], DIGIT_SIZE)); + u[it + 7] = mul52lo(res[it + 7], k); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + 8] = add64(res[it + 8], srli64(res[it + 7], DIGIT_SIZE)); + u[it + 8] = mul52lo(res[it + 8], k); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + 9] = add64(res[it + 9], srli64(res[it + 8], DIGIT_SIZE)); + u[it + 9] = mul52lo(res[it + 9], k); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + + for (jt = 10; jt < 40; jt += 10) { // Poly tile + res[it + jt + 0] = fma52lo(res[it + jt + 0], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52hi(res[it + jt + 1], u[it + 0], m[jt + 0]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 0], m[jt + 1]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 0], m[jt + 2]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 0], m[jt + 3]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 0], m[jt + 4]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 0], m[jt + 5]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 0], m[jt + 6]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 0], m[jt + 7]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 0], m[jt + 8]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 0], m[jt + 9]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 0], m[jt + 9]); + res[it + jt + 1] = fma52lo(res[it + jt + 1], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52hi(res[it + jt + 2], u[it + 1], m[jt + 0]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 1], m[jt + 1]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 1], m[jt + 2]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 1], m[jt + 3]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 1], m[jt + 4]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 1], m[jt + 5]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 1], m[jt + 6]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 1], m[jt + 7]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 1], m[jt + 8]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 1], m[jt + 9]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 1], m[jt + 9]); + res[it + jt + 2] = fma52lo(res[it + jt + 2], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52hi(res[it + jt + 3], u[it + 2], m[jt + 0]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 2], m[jt + 1]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 2], m[jt + 2]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 2], m[jt + 3]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 2], m[jt + 4]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 2], m[jt + 5]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 2], m[jt + 6]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 2], m[jt + 7]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 2], m[jt + 8]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 2], m[jt + 9]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 2], m[jt + 9]); + res[it + jt + 3] = fma52lo(res[it + jt + 3], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52hi(res[it + jt + 4], u[it + 3], m[jt + 0]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 3], m[jt + 1]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 3], m[jt + 2]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 3], m[jt + 3]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 3], m[jt + 4]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 3], m[jt + 5]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 3], m[jt + 6]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 3], m[jt + 7]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 3], m[jt + 8]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 3], m[jt + 9]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 3], m[jt + 9]); + res[it + jt + 4] = fma52lo(res[it + jt + 4], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52hi(res[it + jt + 5], u[it + 4], m[jt + 0]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 4], m[jt + 1]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 4], m[jt + 2]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 4], m[jt + 3]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 4], m[jt + 4]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 4], m[jt + 5]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 4], m[jt + 6]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 4], m[jt + 7]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 4], m[jt + 8]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 4], m[jt + 9]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 4], m[jt + 9]); + res[it + jt + 5] = fma52lo(res[it + jt + 5], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52hi(res[it + jt + 6], u[it + 5], m[jt + 0]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 5], m[jt + 1]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 5], m[jt + 2]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 5], m[jt + 3]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 5], m[jt + 4]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 5], m[jt + 5]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 5], m[jt + 6]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 5], m[jt + 7]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 5], m[jt + 8]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 5], m[jt + 9]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 5], m[jt + 9]); + res[it + jt + 6] = fma52lo(res[it + jt + 6], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52hi(res[it + jt + 7], u[it + 6], m[jt + 0]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 6], m[jt + 1]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 6], m[jt + 2]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 6], m[jt + 3]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 6], m[jt + 4]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 6], m[jt + 5]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 6], m[jt + 6]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 6], m[jt + 7]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 6], m[jt + 8]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 6], m[jt + 9]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 6], m[jt + 9]); + res[it + jt + 7] = fma52lo(res[it + jt + 7], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52hi(res[it + jt + 8], u[it + 7], m[jt + 0]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 7], m[jt + 1]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 7], m[jt + 2]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 7], m[jt + 3]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 7], m[jt + 4]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 7], m[jt + 5]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 7], m[jt + 6]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 7], m[jt + 7]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 7], m[jt + 8]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 7], m[jt + 9]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 7], m[jt + 9]); + res[it + jt + 8] = fma52lo(res[it + jt + 8], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52hi(res[it + jt + 9], u[it + 8], m[jt + 0]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 8], m[jt + 1]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 8], m[jt + 2]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 8], m[jt + 3]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 8], m[jt + 4]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 8], m[jt + 5]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 8], m[jt + 6]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 8], m[jt + 7]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 8], m[jt + 8]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 8], m[jt + 9]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 8], m[jt + 9]); + res[it + jt + 9] = fma52lo(res[it + jt + 9], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52hi(res[it + jt + 10], u[it + 9], m[jt + 0]); + res[it + jt + 10] = fma52lo(res[it + jt + 10], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52hi(res[it + jt + 11], u[it + 9], m[jt + 1]); + res[it + jt + 11] = fma52lo(res[it + jt + 11], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52hi(res[it + jt + 12], u[it + 9], m[jt + 2]); + res[it + jt + 12] = fma52lo(res[it + jt + 12], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52hi(res[it + jt + 13], u[it + 9], m[jt + 3]); + res[it + jt + 13] = fma52lo(res[it + jt + 13], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52hi(res[it + jt + 14], u[it + 9], m[jt + 4]); + res[it + jt + 14] = fma52lo(res[it + jt + 14], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52hi(res[it + jt + 15], u[it + 9], m[jt + 5]); + res[it + jt + 15] = fma52lo(res[it + jt + 15], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52hi(res[it + jt + 16], u[it + 9], m[jt + 6]); + res[it + jt + 16] = fma52lo(res[it + jt + 16], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52hi(res[it + jt + 17], u[it + 9], m[jt + 7]); + res[it + jt + 17] = fma52lo(res[it + jt + 17], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52hi(res[it + jt + 18], u[it + 9], m[jt + 8]); + res[it + jt + 18] = fma52lo(res[it + jt + 18], u[it + 9], m[jt + 9]); + res[it + jt + 19] = fma52hi(res[it + jt + 19], u[it + 9], m[jt + 9]); + } + } + + // Normalization + res[40] = add64(res[40], srli64(res[39], DIGIT_SIZE)); + r[0] = res[40]; + res[41] = add64(res[41], srli64(res[40], DIGIT_SIZE)); + r[1] = res[41]; + res[42] = add64(res[42], srli64(res[41], DIGIT_SIZE)); + r[2] = res[42]; + res[43] = add64(res[43], srli64(res[42], DIGIT_SIZE)); + r[3] = res[43]; + res[44] = add64(res[44], srli64(res[43], DIGIT_SIZE)); + r[4] = res[44]; + res[45] = add64(res[45], srli64(res[44], DIGIT_SIZE)); + r[5] = res[45]; + res[46] = add64(res[46], srli64(res[45], DIGIT_SIZE)); + r[6] = res[46]; + res[47] = add64(res[47], srli64(res[46], DIGIT_SIZE)); + r[7] = res[47]; + res[48] = add64(res[48], srli64(res[47], DIGIT_SIZE)); + r[8] = res[48]; + res[49] = add64(res[49], srli64(res[48], DIGIT_SIZE)); + r[9] = res[49]; + res[50] = add64(res[50], srli64(res[49], DIGIT_SIZE)); + r[10] = res[50]; + res[51] = add64(res[51], srli64(res[50], DIGIT_SIZE)); + r[11] = res[51]; + res[52] = add64(res[52], srli64(res[51], DIGIT_SIZE)); + r[12] = res[52]; + res[53] = add64(res[53], srli64(res[52], DIGIT_SIZE)); + r[13] = res[53]; + res[54] = add64(res[54], srli64(res[53], DIGIT_SIZE)); + r[14] = res[54]; + res[55] = add64(res[55], srli64(res[54], DIGIT_SIZE)); + r[15] = res[55]; + res[56] = add64(res[56], srli64(res[55], DIGIT_SIZE)); + r[16] = res[56]; + res[57] = add64(res[57], srli64(res[56], DIGIT_SIZE)); + r[17] = res[57]; + res[58] = add64(res[58], srli64(res[57], DIGIT_SIZE)); + r[18] = res[58]; + res[59] = add64(res[59], srli64(res[58], DIGIT_SIZE)); + r[19] = res[59]; + res[60] = add64(res[60], srli64(res[59], DIGIT_SIZE)); + r[20] = res[60]; + res[61] = add64(res[61], srli64(res[60], DIGIT_SIZE)); + r[21] = res[61]; + res[62] = add64(res[62], srli64(res[61], DIGIT_SIZE)); + r[22] = res[62]; + res[63] = add64(res[63], srli64(res[62], DIGIT_SIZE)); + r[23] = res[63]; + res[64] = add64(res[64], srli64(res[63], DIGIT_SIZE)); + r[24] = res[64]; + res[65] = add64(res[65], srli64(res[64], DIGIT_SIZE)); + r[25] = res[65]; + res[66] = add64(res[66], srli64(res[65], DIGIT_SIZE)); + r[26] = res[66]; + res[67] = add64(res[67], srli64(res[66], DIGIT_SIZE)); + r[27] = res[67]; + res[68] = add64(res[68], srli64(res[67], DIGIT_SIZE)); + r[28] = res[68]; + res[69] = add64(res[69], srli64(res[68], DIGIT_SIZE)); + r[29] = res[69]; + res[70] = add64(res[70], srli64(res[69], DIGIT_SIZE)); + r[30] = res[70]; + res[71] = add64(res[71], srli64(res[70], DIGIT_SIZE)); + r[31] = res[71]; + res[72] = add64(res[72], srli64(res[71], DIGIT_SIZE)); + r[32] = res[72]; + res[73] = add64(res[73], srli64(res[72], DIGIT_SIZE)); + r[33] = res[73]; + res[74] = add64(res[74], srli64(res[73], DIGIT_SIZE)); + r[34] = res[74]; + res[75] = add64(res[75], srli64(res[74], DIGIT_SIZE)); + r[35] = res[75]; + res[76] = add64(res[76], srli64(res[75], DIGIT_SIZE)); + r[36] = res[76]; + res[77] = add64(res[77], srli64(res[76], DIGIT_SIZE)); + r[37] = res[77]; + res[78] = add64(res[78], srli64(res[77], DIGIT_SIZE)); + r[38] = res[78]; + res[79] = add64(res[79], srli64(res[78], DIGIT_SIZE)); + r[39] = res[79]; + a = (U64 *)out_mb; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_extract_amm52x20_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_extract_amm52x20_mb8.c new file mode 100644 index 000000000..ad481b00c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/avx512_primitives/ifma_extract_amm52x20_mb8.c @@ -0,0 +1,255 @@ +/******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +void ifma_extract_amm52x20_mb8(int64u *out_mb8, const int64u *inpA_mb8, + int64u MulTbl[][redLen][8], const int64u Idx[8], + const int64u *inpM_mb8, const int64u *k0_mb8) { + U64 res00, res01, res02, res03, res04, res05, res06, res07, res08, res09, + res10, res11, res12, res13, res14, res15, res16, res17, res18, res19; + U64 mulB00, mulB01, mulB02, mulB03, mulB04, mulB05, mulB06, mulB07, mulB08, + mulB09, mulB10, mulB11, mulB12, mulB13, mulB14, mulB15, mulB16, mulB17, + mulB18, mulB19; + U64 K = loadu64(k0_mb8); /* k0[] */ + __mmask8 k; + __ALIGN64 U64 inpB_mb8[20]; + int itr; + res00 = res01 = res02 = res03 = res04 = res05 = res06 = res07 = res08 = + res09 = res10 = res11 = res12 = res13 = res14 = res15 = res16 = res17 = + res18 = res19 = get_zero64(); + + U64 idx_target = loadu64((U64 *)Idx); + k = cmpeq64_mask(set64(1), idx_target); + mulB00 = loadu64(MulTbl[0][0]); + mulB01 = loadu64(MulTbl[0][1]); + mulB02 = loadu64(MulTbl[0][2]); + mulB03 = loadu64(MulTbl[0][3]); + mulB04 = loadu64(MulTbl[0][4]); + mulB05 = loadu64(MulTbl[0][5]); + mulB06 = loadu64(MulTbl[0][6]); + mulB07 = loadu64(MulTbl[0][7]); + mulB08 = loadu64(MulTbl[0][8]); + mulB09 = loadu64(MulTbl[0][9]); + mulB10 = loadu64(MulTbl[0][10]); + mulB11 = loadu64(MulTbl[0][11]); + mulB12 = loadu64(MulTbl[0][12]); + mulB13 = loadu64(MulTbl[0][13]); + mulB14 = loadu64(MulTbl[0][14]); + mulB15 = loadu64(MulTbl[0][15]); + mulB16 = loadu64(MulTbl[0][16]); + mulB17 = loadu64(MulTbl[0][17]); + mulB18 = loadu64(MulTbl[0][18]); + mulB19 = loadu64(MulTbl[0][19]); + for (itr = 1; itr < (1 << 5); ++itr) { + U64 idx_curr = set64(itr + 1); + __mmask8 k_new = cmpeq64_mask(idx_curr, idx_target); + mulB00 = select64(k, mulB00, (U64 *) MulTbl[itr][0]); + mulB01 = select64(k, mulB01, (U64 *) MulTbl[itr][1]); + mulB02 = select64(k, mulB02, (U64 *) MulTbl[itr][2]); + mulB03 = select64(k, mulB03, (U64 *) MulTbl[itr][3]); + mulB04 = select64(k, mulB04, (U64 *) MulTbl[itr][4]); + mulB05 = select64(k, mulB05, (U64 *) MulTbl[itr][5]); + mulB06 = select64(k, mulB06, (U64 *) MulTbl[itr][6]); + mulB07 = select64(k, mulB07, (U64 *) MulTbl[itr][7]); + mulB08 = select64(k, mulB08, (U64 *) MulTbl[itr][8]); + mulB09 = select64(k, mulB09, (U64 *) MulTbl[itr][9]); + mulB10 = select64(k, mulB10, (U64 *) MulTbl[itr][10]); + mulB11 = select64(k, mulB11, (U64 *) MulTbl[itr][11]); + mulB12 = select64(k, mulB12, (U64 *) MulTbl[itr][12]); + mulB13 = select64(k, mulB13, (U64 *) MulTbl[itr][13]); + mulB14 = select64(k, mulB14, (U64 *) MulTbl[itr][14]); + mulB15 = select64(k, mulB15, (U64 *) MulTbl[itr][15]); + mulB16 = select64(k, mulB16, (U64 *) MulTbl[itr][16]); + mulB17 = select64(k, mulB17, (U64 *) MulTbl[itr][17]); + mulB18 = select64(k, mulB18, (U64 *) MulTbl[itr][18]); + mulB19 = select64(k, mulB19, (U64 *) MulTbl[itr][19]); + k = k_new; + } + inpB_mb8[0] = mulB00; + inpB_mb8[1] = mulB01; + inpB_mb8[2] = mulB02; + inpB_mb8[3] = mulB03; + inpB_mb8[4] = mulB04; + inpB_mb8[5] = mulB05; + inpB_mb8[6] = mulB06; + inpB_mb8[7] = mulB07; + inpB_mb8[8] = mulB08; + inpB_mb8[9] = mulB09; + inpB_mb8[10] = mulB10; + inpB_mb8[11] = mulB11; + inpB_mb8[12] = mulB12; + inpB_mb8[13] = mulB13; + inpB_mb8[14] = mulB14; + inpB_mb8[15] = mulB15; + inpB_mb8[16] = mulB16; + inpB_mb8[17] = mulB17; + inpB_mb8[18] = mulB18; + inpB_mb8[19] = mulB19; + + for (itr = 0; itr < 20; itr++) { + U64 Yi; + U64 Bi = inpB_mb8[itr]; + fma52lo_mem(res00, res00, Bi, inpA_mb8, 64 * 0); + fma52lo_mem(res01, res01, Bi, inpA_mb8, 64 * 1); + fma52lo_mem(res02, res02, Bi, inpA_mb8, 64 * 2); + fma52lo_mem(res03, res03, Bi, inpA_mb8, 64 * 3); + fma52lo_mem(res04, res04, Bi, inpA_mb8, 64 * 4); + fma52lo_mem(res05, res05, Bi, inpA_mb8, 64 * 5); + fma52lo_mem(res06, res06, Bi, inpA_mb8, 64 * 6); + fma52lo_mem(res07, res07, Bi, inpA_mb8, 64 * 7); + fma52lo_mem(res08, res08, Bi, inpA_mb8, 64 * 8); + fma52lo_mem(res09, res09, Bi, inpA_mb8, 64 * 9); + fma52lo_mem(res10, res10, Bi, inpA_mb8, 64 * 10); + fma52lo_mem(res11, res11, Bi, inpA_mb8, 64 * 11); + fma52lo_mem(res12, res12, Bi, inpA_mb8, 64 * 12); + fma52lo_mem(res13, res13, Bi, inpA_mb8, 64 * 13); + fma52lo_mem(res14, res14, Bi, inpA_mb8, 64 * 14); + fma52lo_mem(res15, res15, Bi, inpA_mb8, 64 * 15); + fma52lo_mem(res16, res16, Bi, inpA_mb8, 64 * 16); + fma52lo_mem(res17, res17, Bi, inpA_mb8, 64 * 17); + fma52lo_mem(res18, res18, Bi, inpA_mb8, 64 * 18); + fma52lo_mem(res19, res19, Bi, inpA_mb8, 64 * 19); + Yi = fma52lo(get_zero64(), res00, K); + fma52lo_mem(res00, res00, Yi, inpM_mb8, 64 * 0); + fma52lo_mem(res01, res01, Yi, inpM_mb8, 64 * 1); + fma52lo_mem(res02, res02, Yi, inpM_mb8, 64 * 2); + fma52lo_mem(res03, res03, Yi, inpM_mb8, 64 * 3); + fma52lo_mem(res04, res04, Yi, inpM_mb8, 64 * 4); + fma52lo_mem(res05, res05, Yi, inpM_mb8, 64 * 5); + fma52lo_mem(res06, res06, Yi, inpM_mb8, 64 * 6); + fma52lo_mem(res07, res07, Yi, inpM_mb8, 64 * 7); + fma52lo_mem(res08, res08, Yi, inpM_mb8, 64 * 8); + fma52lo_mem(res09, res09, Yi, inpM_mb8, 64 * 9); + fma52lo_mem(res10, res10, Yi, inpM_mb8, 64 * 10); + fma52lo_mem(res11, res11, Yi, inpM_mb8, 64 * 11); + fma52lo_mem(res12, res12, Yi, inpM_mb8, 64 * 12); + fma52lo_mem(res13, res13, Yi, inpM_mb8, 64 * 13); + fma52lo_mem(res14, res14, Yi, inpM_mb8, 64 * 14); + fma52lo_mem(res15, res15, Yi, inpM_mb8, 64 * 15); + fma52lo_mem(res16, res16, Yi, inpM_mb8, 64 * 16); + fma52lo_mem(res17, res17, Yi, inpM_mb8, 64 * 17); + fma52lo_mem(res18, res18, Yi, inpM_mb8, 64 * 18); + fma52lo_mem(res19, res19, Yi, inpM_mb8, 64 * 19); + res00 = srli64(res00, DIGIT_SIZE); + res01 = add64(res01, res00); + fma52hi_mem(res00, res01, Bi, inpA_mb8, 64 * 0); + fma52hi_mem(res01, res02, Bi, inpA_mb8, 64 * 1); + fma52hi_mem(res02, res03, Bi, inpA_mb8, 64 * 2); + fma52hi_mem(res03, res04, Bi, inpA_mb8, 64 * 3); + fma52hi_mem(res04, res05, Bi, inpA_mb8, 64 * 4); + fma52hi_mem(res05, res06, Bi, inpA_mb8, 64 * 5); + fma52hi_mem(res06, res07, Bi, inpA_mb8, 64 * 6); + fma52hi_mem(res07, res08, Bi, inpA_mb8, 64 * 7); + fma52hi_mem(res08, res09, Bi, inpA_mb8, 64 * 8); + fma52hi_mem(res09, res10, Bi, inpA_mb8, 64 * 9); + fma52hi_mem(res10, res11, Bi, inpA_mb8, 64 * 10); + fma52hi_mem(res11, res12, Bi, inpA_mb8, 64 * 11); + fma52hi_mem(res12, res13, Bi, inpA_mb8, 64 * 12); + fma52hi_mem(res13, res14, Bi, inpA_mb8, 64 * 13); + fma52hi_mem(res14, res15, Bi, inpA_mb8, 64 * 14); + fma52hi_mem(res15, res16, Bi, inpA_mb8, 64 * 15); + fma52hi_mem(res16, res17, Bi, inpA_mb8, 64 * 16); + fma52hi_mem(res17, res18, Bi, inpA_mb8, 64 * 17); + fma52hi_mem(res18, res19, Bi, inpA_mb8, 64 * 18); + fma52hi_mem(res19, get_zero64(), Bi, inpA_mb8, 64 * 19); + fma52hi_mem(res00, res00, Yi, inpM_mb8, 64 * 0); + fma52hi_mem(res01, res01, Yi, inpM_mb8, 64 * 1); + fma52hi_mem(res02, res02, Yi, inpM_mb8, 64 * 2); + fma52hi_mem(res03, res03, Yi, inpM_mb8, 64 * 3); + fma52hi_mem(res04, res04, Yi, inpM_mb8, 64 * 4); + fma52hi_mem(res05, res05, Yi, inpM_mb8, 64 * 5); + fma52hi_mem(res06, res06, Yi, inpM_mb8, 64 * 6); + fma52hi_mem(res07, res07, Yi, inpM_mb8, 64 * 7); + fma52hi_mem(res08, res08, Yi, inpM_mb8, 64 * 8); + fma52hi_mem(res09, res09, Yi, inpM_mb8, 64 * 9); + fma52hi_mem(res10, res10, Yi, inpM_mb8, 64 * 10); + fma52hi_mem(res11, res11, Yi, inpM_mb8, 64 * 11); + fma52hi_mem(res12, res12, Yi, inpM_mb8, 64 * 12); + fma52hi_mem(res13, res13, Yi, inpM_mb8, 64 * 13); + fma52hi_mem(res14, res14, Yi, inpM_mb8, 64 * 14); + fma52hi_mem(res15, res15, Yi, inpM_mb8, 64 * 15); + fma52hi_mem(res16, res16, Yi, inpM_mb8, 64 * 16); + fma52hi_mem(res17, res17, Yi, inpM_mb8, 64 * 17); + fma52hi_mem(res18, res18, Yi, inpM_mb8, 64 * 18); + fma52hi_mem(res19, res19, Yi, inpM_mb8, 64 * 19); + } + // Normalization + { + U64 T = get_zero64(); + //U64 MASK = set64(DIGIT_MASK); + T = srli64(res00, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 0, res00); + res01 = add64(res01, T); + T = srli64(res01, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 1, res01); + res02 = add64(res02, T); + T = srli64(res02, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 2, res02); + res03 = add64(res03, T); + T = srli64(res03, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 3, res03); + res04 = add64(res04, T); + T = srli64(res04, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 4, res04); + res05 = add64(res05, T); + T = srli64(res05, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 5, res05); + res06 = add64(res06, T); + T = srli64(res06, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 6, res06); + res07 = add64(res07, T); + T = srli64(res07, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 7, res07); + res08 = add64(res08, T); + T = srli64(res08, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 8, res08); + res09 = add64(res09, T); + T = srli64(res09, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 9, res09); + res10 = add64(res10, T); + T = srli64(res10, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 10, res10); + res11 = add64(res11, T); + T = srli64(res11, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 11, res11); + res12 = add64(res12, T); + T = srli64(res12, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 12, res12); + res13 = add64(res13, T); + T = srli64(res13, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 13, res13); + res14 = add64(res14, T); + T = srli64(res14, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 14, res14); + res15 = add64(res15, T); + T = srli64(res15, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 15, res15); + res16 = add64(res16, T); + T = srli64(res16, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 16, res16); + res17 = add64(res17, T); + T = srli64(res17, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 17, res17); + res18 = add64(res18, T); + T = srli64(res18, DIGIT_SIZE); + storeu64(out_mb8 + 8 * 18, res18); + res19 = add64(res19, T); + storeu64(out_mb8 + 8 * 19, res19); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_div_104_by_52.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_div_104_by_52.c new file mode 100644 index 000000000..842eb24f6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_div_104_by_52.c @@ -0,0 +1,124 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + + +static ALIGNSPEC const UINT64 __mask52[] = { DUP8_DECL(0x00ffffffffffffffull) }; +static ALIGNSPEC const UINT64 __one[] = { DUP8_DECL(0x3ff0000000000000ull) }; +static ALIGNSPEC const UINT64 __two52[] = { DUP8_DECL(0x4330000000000000ull) }; +//static ALIGNSPEC const UINT64 __zero[] = { DUP8_DECL(0x0000000000000000ull) }; +static ALIGNSPEC const UINT64 __one_l[] = { DUP8_DECL(0x0000000000000001ull) }; + + + +// each 64-bit SIMD element should be in the [0, 2^52) range +// perform division of (Ah[k]*2^52 + Al[k])/B[k], k=0..7 +// Return quotients (as well as remainders via pointer) +// Note: There is no checking for B==0 +VUINT64 __div_104_by_52(VUINT64 Ah, VUINT64 Al, VUINT64 B, VUINT64* prem) +{ + VUINT64 msk52, Rem, one; + VUINT64 sgn_mask, B_corr, Qh, Ql; + VDOUBLE db, dah, dal, dbr, d_one; + VDOUBLE dqh, dql, two52, dqh2; + VMASK_L corr_gt_mask; + + // limit range of Ah, Al, B inputs to 52 bits (optional?) + msk52 = VLOAD_L(__mask52); + B = VAND_L(B, msk52); + Ah = VAND_L(Ah, msk52); + Al = VAND_L(Al, msk52); + + // convert inputs to double precision + // conversion will be exact + db = VCVT_L2D(B); + dah = VCVT_L2D(Ah); + dal = VCVT_L2D(Al); + + d_one = VLOAD_D(__one); + // get reciprocal of B, RZ mode + dbr = VDIV_RU_D(d_one, db); + + // estimate quotient Qh = (dah*dbr)_RZ ~ Ah/B + dqh = VMUL_RZ_D(dah, dbr); + // truncate dqh to integral + dqh = VROUND_RZ_D(dqh); + // get remainder term: dah_new -= dqh*dbh + // 0 <= dah_new <= B (due to rounding direction and rounding error magnitude in dbr, dqh) + dah = VQFMR_D(db, dqh, dah); + + // estimate quotient Ql = (dal*dbr)_RZ ~ Al/B + dql = VMUL_RZ_D(dal, dbr); + // truncate dqh to integral + dql = VROUND_RZ_D(dql); + // get remainder term: dal_new -= dql*dbh + // 0 <= dal_new <= B (similar to above) + dal = VQFMR_D(db, dql, dal); + // convert remainder term back to (signed) 64-bit integer + Al = VCVT_D2L(dal); + + // scale dah by 2^52 + two52 = VLOAD_D(__two52); + dah = VMUL_D(dah, two52); + // estimate quotient Qh2 = ((2^52)*dah)_RU/db + dqh2 = VMUL_RZ_D(dah, dbr); + // truncate dqh2 to integral + dqh2 = VROUND_RZ_D(dqh2); + // remainder term: dah_new2 = dah - db*dqh2 + // dah_new2 in (-B, 2B) + dah = VQFMR_D(db, dqh2, dah); + // convert remainder term back to (signed) 64-bit integer + Ah = VCVT_D2L(dah); + + // add and convert low quotients: Qh2+Ql + dql = VADD_D(dql, dqh2); + Ql = VCVT_D2L(dql); + // convert high quotient + Qh = VCVT_D2L(dqh); + + // remainder term in (-B, 3B) + Rem = VADD_L(Ah, Al); + + // Rem < 0? + sgn_mask = VSAR_L(Rem, 63); + // Rem > B? + corr_gt_mask = VCMP_GE_L(Rem, B); + B_corr = VAND_L(B, sgn_mask); + // apply correction if B<0 + Rem = VADD_L(Rem, B_corr); + Ql = VADD_L(Ql, sgn_mask); + + // if Rem> B, apply correction + Rem = VMSUB_L(corr_gt_mask, Rem, B); + one = VLOAD_L(__one_l); + Ql = VMADD_L(corr_gt_mask, Ql, one); + + // Rem > B? + corr_gt_mask = VCMP_GE_L(Rem, B); + // if Rem> B, apply correction + // this is the final remainder + *prem = VMSUB_L(corr_gt_mask, Rem, B); + Ql = VMADD_L(corr_gt_mask, Ql, one); + + // now add the high part of the quotient + Qh = VSHL_L(Qh, 52); + Ql = VADD_L(Ql, Qh); + + return Ql; + +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x10_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x10_mb8.c new file mode 100644 index 000000000..7baa2b1ae --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x10_mb8.c @@ -0,0 +1,198 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include +#include + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x10_mb8(out, Y, mod, k0) \ + AMS52x10_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #ifdef USE_AMS_5x + #define SQUARE_5x52x10_mb8(out, Y, mod, k0) \ + AMS5x52x10_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #else + #define SQUARE_5x52x10_mb8(out, Y, mod, k0) \ + AMS52x10_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x10_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x10_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x10_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x10_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); + #endif +#else + #define SQUARE_52x10_mb8(out, Y, mod, k0) \ + ifma_amm52x10_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x10_mb8(out, Y, mod, k0) \ + ifma_amm52x10_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x10_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x10_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x10_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x10_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (512) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //10 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //8 + +#define EXP_WIN_SIZE (5) //(4) +#define EXP_WIN_MASK ((1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x10_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x10_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x10_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x10_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x10_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + __m512i T; + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x10_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* clear exponents */ + zero_mb8(expz, LEN64); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x10_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x20_65537_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x20_65537_mb8.c new file mode 100644 index 000000000..a3a95ed07 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x20_65537_mb8.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x20_mb8(out, Y, mod, k0) \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #ifdef USE_AMS_5x + #define SQUARE_5x52x20_mb8(out, Y, mod, k0) \ + AMS5x52x20_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #else + #define SQUARE_5x52x20_mb8(out, Y, mod, k0) \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); + #endif +#else + #define SQUARE_52x20_mb8(out, Y, mod, k0) \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x20_mb8(out, Y, mod, k0) \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (RSA_1K) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //20 + +void EXP52x20_pub65537_mb8(int64u out[][8], + const int64u base[][8], // already in ifma fmt + const int64u modulus[][8], // already in ifma fmt + const int64u toMont[][8], // already in ifma fmt + const int64u k0[8], + int64u work_buffer[][8]) +{ + /* allocate red(undant) result Y and multiplier X */ + pint64u_x8 red_Y = (pint64u_x8)work_buffer; + pint64u_x8 red_X = (pint64u_x8)(red_Y + LEN52); + + /* convert base into redundant Montgomery domain */ + ifma_amm52x20_mb8((int64u*)red_X, (int64u*)base, (int64u*)toMont, (int64u*)modulus, (int64u*)k0); + + /* exponentition 65537 = 0x10001 */ + SQUARE_52x20_mb8((int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + ifma_amm52x20_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x20_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x20_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x20_mb8.c new file mode 100644 index 000000000..e7ab45901 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x20_mb8.c @@ -0,0 +1,217 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include +#include + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x20_mb8(out, Y, mod, k0) \ + AMS52x20_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*) k0); +#else + #define SQUARE_52x20_mb8(out, Y, mod, k0) \ + ifma_amm52x20_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*) k0); +#endif + +#define BITSIZE_MODULUS (1024) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //20 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //16 + +// only valid value is 4 +// not removed to make code more readable +#define EXP_WIN_SIZE (4) +#define EXP_WIN_MASK ((1<=0; exp_bit_no-=EXP_WIN_SIZE) { + __m512i T; + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + /* 4 squarings stitched with extracting pre-computed multiplier from the table */ + AMS4x52x20_diagonal_stitched_with_extract_mb8((int64u*) red_Y, (U64*) mulb, (U64*) mulbx, (int64u*)red_Y, (int64u*) modulus, (int64u*) k0, red_table, redx_table, (int64u*) (&red_table_idx)); + + ifma_ahmm52x20_mb8((int64u*) red_Y, (int64u*) red_Y, (int64u*) mulb, (int64u*) mulbx, (int64u*) modulus, (int64u*) k0); + } + + /* clear exponents */ + zero_mb8(expz, LEN64); + + /* convert result back in regular 2^DIGIT_SIZE domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x20_mb8((int64u*) out, (int64u*) red_Y, (int64u*) red_X, (int64u*) modulus, (int64u*) k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x30_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x30_mb8.c new file mode 100644 index 000000000..83c1c6de0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x30_mb8.c @@ -0,0 +1,251 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x30_mb8(out, Y, mod, k0) \ + AMS52x30_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #define SQUARE_5x52x30_mb8(out, Y, mod, k0) \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#else + #define SQUARE_52x30_mb8(out, Y, mod, k0) \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x30_mb8(out, Y, mod, k0) \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x30_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (1536) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //30 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //24 + +#define EXP_WIN_SIZE (5) //(4) +#define EXP_WIN_MASK ((1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x30_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x30_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x30_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x30_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x30_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + __m512i T; + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x30_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* clear exponents */ + zero_mb8(expz, LEN64); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x30_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x40_65537_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x40_65537_mb8.c new file mode 100644 index 000000000..d7955ebc8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x40_65537_mb8.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x40_mb8(out, Y, mod, k0) \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #ifdef USE_AMS_5x + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + AMS5x52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #else + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); + #endif +#else + #define SQUARE_52x40_mb8(out, Y, mod, k0) \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (RSA_2K) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //40 + +void EXP52x40_pub65537_mb8(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]) +{ + /* allocate red(undant) result Y and multiplier X */ + pint64u_x8 red_Y = (pint64u_x8)work_buffer; + pint64u_x8 red_X = (pint64u_x8)(work_buffer + LEN52); + + /* convert base into redundant domain */ + ifma_amm52x40_mb8((int64u*)red_X, (int64u*)base, (int64u*)toMont, (int64u*)modulus, (int64u*)k0); + + /* exponentition 65537 = 0x10001 */ + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + ifma_amm52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x40_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x40_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x40_mb8.c new file mode 100644 index 000000000..8e96cdf11 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x40_mb8.c @@ -0,0 +1,287 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x40_mb8(out, Y, mod, k0) \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #ifdef USE_AMS_5x + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + AMS5x52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #else + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x40_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); + #endif +#else + #define SQUARE_52x40_mb8(out, Y, mod, k0) \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x40_mb8(out, Y, mod, k0) \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x40_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (2048) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //40 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //32 + +#define EXP_WIN_SIZE (5) //(4) +#define EXP_WIN_MASK ((1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + __m512i T; + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x40_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* clear exponents */ + zero_mb8(expz, LEN64); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x40_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x60_65537_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x60_65537_mb8.c new file mode 100644 index 000000000..7089b5237 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x60_65537_mb8.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x60_mb8(out, Y, mod, k0) \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #define SQUARE_5x52x60_mb8(out, Y, mod, k0) \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#else + #define SQUARE_52x60_mb8(out, Y, mod, k0) \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x60_mb8(out, Y, mod, k0) \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (RSA_3K) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //60 + +void EXP52x60_pub65537_mb8(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]) +{ + /* allocate red(undant) result Y and multiplier X */ + pint64u_x8 red_Y = (pint64u_x8)work_buffer; + pint64u_x8 red_X = (pint64u_x8)(work_buffer + LEN52); + + /* convert base into redundant domain */ + ifma_amm52x60_mb8((int64u*)red_X, (int64u*)base, (int64u*)toMont, (int64u*)modulus, (int64u*)k0); + + /* exponentition 65537 = 0x10001 */ + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + ifma_amm52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x60_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x60_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x60_mb8.c new file mode 100644 index 000000000..0aa575294 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x60_mb8.c @@ -0,0 +1,342 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x60_mb8(out, Y, mod, k0) \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #define SQUARE_5x52x60_mb8(out, Y, mod, k0) \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x60_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#else + #define SQUARE_52x60_mb8(out, Y, mod, k0) \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x60_mb8(out, Y, mod, k0) \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x60_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (3072) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //60 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //48 + +#define EXP_WIN_SIZE (5) //(4) +#define EXP_WIN_MASK ((1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + __m512i T; + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x60_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* clear exponents */ + zero_mb8(expz, LEN64); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x60_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x79_65537_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x79_65537_mb8.c new file mode 100644 index 000000000..c9b9a7064 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x79_65537_mb8.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x79_mb8(out, Y, mod, k0) \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #define SQUARE_5x52x79_mb8(out, Y, mod, k0) \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#else + #define SQUARE_52x79_mb8(out, Y, mod, k0) \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x79_mb8(out, Y, mod, k0) \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (RSA_4K) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //79 + +void EXP52x79_pub65537_mb8(int64u out[][8], + const int64u base[][8], + const int64u modulus[][8], + const int64u toMont[][8], + const int64u k0[8], + int64u work_buffer[][8]) +{ + /* allocate red(undant) result Y and multiplier X */ + pint64u_x8 red_Y = (pint64u_x8)(work_buffer + 1); + pint64u_x8 red_X = (pint64u_x8)(red_Y + LEN52); + + /* convert base into redundant domain */ + zero_mb8(red_X, LEN52); + ifma_amm52x79_mb8((int64u*)red_X, (int64u*)base, (int64u*)toMont, (int64u*)modulus, (int64u*)k0); + + /* exponentition 65537 = 0x10001 */ + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_5x52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + ifma_amm52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x79_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x79_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x79_mb8.c new file mode 100644 index 000000000..99b18b789 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_exp52x79_mb8.c @@ -0,0 +1,398 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#define USE_AMS +#ifdef USE_AMS + #define SQUARE_52x79_mb8(out, Y, mod, k0) \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); + + #define SQUARE_5x52x79_mb8(out, Y, mod, k0) \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + AMS52x79_diagonal_mb8((int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#else + #define SQUARE_52x79_mb8(out, Y, mod, k0) \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); + #define SQUARE_5x52x79_mb8(out, Y, mod, k0) \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)Y, (int64u*)Y, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); \ + ifma_amm52x79_mb8((int64u*)out, (int64u*)out, (int64u*)out, (int64u*)mod, (int64u*)k0); +#endif + +#define BITSIZE_MODULUS (4096) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,DIGIT_SIZE)) //79 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) //64 + +#define EXP_WIN_SIZE (5) //(4) +#define EXP_WIN_MASK ((1<=0; exp_bit_no-=EXP_WIN_SIZE) { + /* series of squaring */ + #if EXP_WIN_SIZE==5 + SQUARE_5x52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #else + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + SQUARE_52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)modulus, (int64u*)k0); + #endif + + /* extract pre-computed multiplier from the table */ + { + __m512i T; + exp_chunk_no = exp_bit_no/64; + exp_chunk_shift = exp_bit_no%64; + + red_table_idx = _mm512_load_si512(expz[exp_chunk_no]); + T = _mm512_load_si512(expz[exp_chunk_no+1]); + + red_table_idx = _mm512_srl_epi64(red_table_idx, _mm_set1_epi64x(exp_chunk_shift)); + T = _mm512_sll_epi64(T, _mm_set1_epi64x(64-exp_chunk_shift)); + red_table_idx = _mm512_and_si512( _mm512_xor_si512(red_table_idx, T), table_idx_mask); + + extract_multiplier_mb8(red_X, red_table, (int64u*)(&red_table_idx)); + } + /* and multiply */ + ifma_amm52x79_mb8((int64u*)red_Y, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); + } + } + + /* clear exponents */ + zero_mb8(expz, LEN64); + + /* convert result back in regular 2^52 domain */ + zero_mb8(red_X, LEN52); + _mm512_store_si512(red_X, _mm512_set1_epi64(1)); + ifma_amm52x79_mb8((int64u*)out, (int64u*)red_Y, (int64u*)red_X, (int64u*)modulus, (int64u*)k0); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_method.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_method.c new file mode 100644 index 000000000..d1992ee38 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_method.c @@ -0,0 +1,377 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include +#include + +#define EXP_WIN_SIZE (5) //(4) + +/* +// rsa public key methods +*/ +DLL_PUBLIC +const mbx_RSA_Method* mbx_RSA1K_pub65537_Method(void) +{ + #define RSA_BITLEN (RSA_1K) + #define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + static mbx_RSA_Method m = { + RSA_ID(RSA_PUB_KEY,RSA_BITLEN), + RSA_BITLEN, + 64 + (8 + LEN52*8 + LEN52*8 + MULTIPLE_OF(LEN52,10)*8 + (LEN52*8)*2) * sizeof(int64u), /* buffer */ + //ifma_BNU_to_mb8, + //NULL, + EXP52x20_pub65537_mb8, + NULL, + NULL, + NULL, + NULL, + NULL + }; + return &m; + #undef RSA_BITLEN + #undef LEN52 +} + +DLL_PUBLIC +const mbx_RSA_Method* mbx_RSA2K_pub65537_Method(void) +{ +#define RSA_BITLEN (RSA_2K) +#define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + static mbx_RSA_Method m = { + RSA_ID(RSA_PUB_KEY,RSA_BITLEN), + RSA_BITLEN, + 64 + (8 + LEN52*8 + LEN52*8 + MULTIPLE_OF(LEN52,10)*8 + (LEN52*8)*2) * sizeof(int64u), /* buffer */ + //ifma_BNU_to_mb8, + //NULL, + EXP52x40_pub65537_mb8, + NULL, + NULL, + NULL, + NULL, + NULL + }; + return &m; +#undef RSA_BITLEN +#undef LEN52 +} + +DLL_PUBLIC +const mbx_RSA_Method* mbx_RSA3K_pub65537_Method(void) +{ +#define RSA_BITLEN (RSA_3K) +#define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + static mbx_RSA_Method m = { + RSA_ID(RSA_PUB_KEY,RSA_BITLEN), + RSA_BITLEN, + 64 + (8 + LEN52*8 + LEN52*8 + MULTIPLE_OF(LEN52,10)*8 + (LEN52*8)*2) * sizeof(int64u), /* buffer */ + //ifma_BNU_to_mb8, + //NULL, + EXP52x60_pub65537_mb8, + NULL, + NULL, + NULL, + NULL, + NULL + }; + return &m; +#undef RSA_BITLEN +#undef LEN52 +} + +DLL_PUBLIC +const mbx_RSA_Method* mbx_RSA4K_pub65537_Method(void) +{ +#define RSA_BITLEN (RSA_4K) +#define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + static mbx_RSA_Method m = { + RSA_ID(RSA_PUB_KEY,RSA_BITLEN), + RSA_BITLEN, + 64 + (8 + LEN52*8 + LEN52*8 + MULTIPLE_OF(LEN52,10)*8 + (LEN52*8)*2 + 1) * sizeof(int64u), /* buffer */ + //ifma_BNU_to_mb8, + //NULL, + EXP52x79_pub65537_mb8, + NULL, + NULL, + NULL, + NULL, + NULL + }; + return &m; +#undef RSA_BITLEN +#undef LEN52 +} + +DLL_PUBLIC +const mbx_RSA_Method* mbx_RSA_pub65537_Method(int rsaBitsize) +{ + switch (rsaBitsize) { + case RSA_1K: return mbx_RSA1K_pub65537_Method(); + case RSA_2K: return mbx_RSA2K_pub65537_Method(); + case RSA_3K: return mbx_RSA3K_pub65537_Method(); + case RSA_4K: return mbx_RSA4K_pub65537_Method(); + default: return NULL; + } +} + + +/* +// rsa private key methods +*/ +DLL_PUBLIC +const mbx_RSA_Method* mbx_RSA1K_private_Method(void) +{ + #define RSA_BITLEN (RSA_1K) + #define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + #define LEN64 (NUMBER_OF_DIGITS(RSA_BITLEN, 64)) + static mbx_RSA_Method m = { + RSA_ID(RSA_PRV2_KEY,RSA_BITLEN), + RSA_BITLEN, + 64 + (8 + LEN64*8 + LEN52*8 + LEN52*8 + MULTIPLE_OF(LEN52,10)*8 + (LEN52*8)*2 + (LEN64+1)*8 + (1<buffSize : 0; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_other52x_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_other52x_mb8.c new file mode 100644 index 000000000..5bf5a5195 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_other52x_mb8.c @@ -0,0 +1,2399 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include + +#ifdef __GNUC__ +#define ASM(a) __asm__(a); +#else +#define ASM(a) +#endif + +__NOINLINE +void zero_mb8(int64u (*out)[8], int len) +{ +#if defined(__GNUC__) + // Avoid dead code elimination for GNU compilers + ASM(""); +#endif + __m512i T = _mm512_setzero_si512(); + int i; + for(i=0; i x < ((m0*y) mod (2*x)) */ + y = _mm512_mask_add_epi64(y, k, y,x); /* y+=x */ + /* mask = 2*x-1 */ + x = nx; + nx = _mm512_add_epi64(nx, nx); + mask = _mm512_sub_epi64(nx, _mm512_set1_epi64(1)); + } + y = _mm512_sub_epi64(_mm512_setzero_si512(), y); /* return (0-y) */ + y = _mm512_and_si512(y, _mm512_set1_epi64(DIGIT_MASK)); + + _mm512_storeu_si512(k0_mb8, y); +} + +/* r = (a-b) mod m */ +void ifma_modsub52x10_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]) +{ +#define BITSIZE (512) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) +#define MSD_MSK (MS_DIGIT_MASK(BITSIZE,52)) + + __m512i* pr = (__m512i*)res; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + __m512i* pm = (__m512i*)inpM; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + __m512i MSD_MASK = _mm512_set1_epi64(MSD_MSK); + + __m512i T[LEN52]; + __m512i R, CARRY, BORROW; + int n; + + /* T[] = a[] - b[] */ + BORROW = _mm512_setzero_si512(); + + for (n = 0; n < LEN52; n++) { + R = _mm512_sub_epi64(pa[n], pb[n]); + R = _mm512_sub_epi64(R, BORROW); + BORROW = _mm512_srli_epi64(R, (64 - 1)); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(T + n, R); + } + + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(T + LEN52 - 1, R); + + /* masked modulus add: r[] = T[] + BORROW? m[] : 0 */ + CARRY = _mm512_setzero_si512(); + BORROW = _mm512_sub_epi64(CARRY, BORROW); /* RORROW -> mask */ + + for (n = 0; n < LEN52; n++) { + R = _mm512_and_epi64(BORROW, pm[n]); + R = _mm512_add_epi64(R, T[n]); + R = _mm512_add_epi64(R, CARRY); + CARRY = _mm512_srli_epi64(R, DIGIT_SIZE); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(pr + n, R); + } + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(pr + LEN52 - 1, R); + +#undef BITSIZE +#undef LEN52 +#undef MSD_MSK +} + +void ifma_modsub52x20_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]) +{ +#define BITSIZE (1024) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) +#define MSD_MSK (MS_DIGIT_MASK(BITSIZE,52)) + + __m512i* pr = (__m512i*)res; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + __m512i* pm = (__m512i*)inpM; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + __m512i MSD_MASK = _mm512_set1_epi64(MSD_MSK); + + __m512i T[LEN52]; + __m512i R, CARRY, BORROW; + int n; + + /* T[] = a[] - b[] */ + BORROW = _mm512_setzero_si512(); + + for (n = 0; n < LEN52; n++) { + R = _mm512_sub_epi64(pa[n], pb[n]); + R = _mm512_sub_epi64(R, BORROW); + BORROW = _mm512_srli_epi64(R, (64 - 1)); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(T + n, R); + } + + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(T + LEN52 - 1, R); + + /* masked modulus add: r[] = T[] + BORROW? m[] : 0 */ + CARRY = _mm512_setzero_si512(); + BORROW = _mm512_sub_epi64(CARRY, BORROW); /* RORROW -> mask */ + + for (n = 0; n < LEN52; n++) { + R = _mm512_and_epi64(BORROW, pm[n]); + R = _mm512_add_epi64(R, T[n]); + R = _mm512_add_epi64(R, CARRY); + CARRY = _mm512_srli_epi64(R, DIGIT_SIZE); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(pr + n, R); + } + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(pr + LEN52 - 1, R); + + #undef BITSIZE + #undef LEN52 + #undef MSD_MSK +} + +void ifma_modsub52x30_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]) +{ + #define BITSIZE (1536) + #define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) + #define MSD_MSK (MS_DIGIT_MASK(BITSIZE,52)) + + __m512i* pr = (__m512i*)res; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + __m512i* pm = (__m512i*)inpM; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + __m512i MSD_MASK = _mm512_set1_epi64(MSD_MSK); + + __m512i T[LEN52]; + __m512i R, CARRY, BORROW; + int n; + + /* T[] = a[] - b[] */ + BORROW = _mm512_setzero_si512(); + + for (n = 0; n < LEN52; n++) { + R = _mm512_sub_epi64(pa[n], pb[n]); + R = _mm512_sub_epi64(R, BORROW); + BORROW = _mm512_srli_epi64(R, (64 - 1)); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(T + n, R); + } + + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(T + LEN52 - 1, R); + + /* masked modulus add: r[] = T[] + BORROW? m[] : 0 */ + CARRY = _mm512_setzero_si512(); + BORROW = _mm512_sub_epi64(CARRY, BORROW); /* RORROW -> mask */ + + for (n = 0; n < LEN52; n++) { + R = _mm512_and_epi64(BORROW, pm[n]); + R = _mm512_add_epi64(R, T[n]); + R = _mm512_add_epi64(R, CARRY); + CARRY = _mm512_srli_epi64(R, DIGIT_SIZE); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(pr + n, R); + } + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(pr + LEN52 - 1, R); + + #undef BITSIZE + #undef LEN52 + #undef MSD_MSK +} + +void ifma_modsub52x40_mb8(int64u res[][8], const int64u inpA[][8], const int64u inpB[][8], const int64u inpM[][8]) +{ +#define BITSIZE (2048) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) +#define MSD_MSK (MS_DIGIT_MASK(BITSIZE,52)) + + __m512i* pr = (__m512i*)res; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + __m512i* pm = (__m512i*)inpM; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + __m512i MSD_MASK = _mm512_set1_epi64(MSD_MSK); + + __m512i T[LEN52]; + __m512i R, CARRY, BORROW; + int n; + + /* T[] = a[] - b[] */ + BORROW = _mm512_setzero_si512(); + + for (n = 0; n < LEN52; n++) { + R = _mm512_sub_epi64(pa[n], pb[n]); + R = _mm512_sub_epi64(R, BORROW); + BORROW = _mm512_srli_epi64(R, (64 - 1)); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(T + n, R); + } + + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(T + LEN52 - 1, R); + + /* masked modulus add: r[] = T[] + BORROW? m[] : 0 */ + CARRY = _mm512_setzero_si512(); + BORROW = _mm512_sub_epi64(CARRY, BORROW); /* RORROW -> mask */ + + for (n = 0; n < LEN52; n++) { + R = _mm512_and_epi64(BORROW, pm[n]); + R = _mm512_add_epi64(R, T[n]); + R = _mm512_add_epi64(R, CARRY); + CARRY = _mm512_srli_epi64(R, DIGIT_SIZE); + R = _mm512_and_epi64(R, DIG_MASK); + _mm512_store_si512(pr + n, R); + } + /* correct last digit */ + R = _mm512_and_epi64(R, MSD_MASK); + _mm512_store_si512(pr + LEN52 - 1, R); + +#undef BITSIZE +#undef LEN52 +#undef MSD_MSK +} + + +/* r += a*b */ +void ifma_addmul52x10_mb8(int64u pRes[][8], const int64u inpA[][8], const int64u inpB[][8]) +{ +#define BITSIZE (RSA_1K/2) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) +#define MSD_MSK (MS_DIGIT_MASK(RSA_2K,52)) + + __m512i* pr = (__m512i*)pRes; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + + __m512i R00 = _mm512_load_si512(pr + 0); /* load pr[nsM-1],...,R[0] */ + __m512i R01 = _mm512_load_si512(pr + 1); + __m512i R02 = _mm512_load_si512(pr + 2); + __m512i R03 = _mm512_load_si512(pr + 3); + __m512i R04 = _mm512_load_si512(pr + 4); + __m512i R05 = _mm512_load_si512(pr + 5); + __m512i R06 = _mm512_load_si512(pr + 6); + __m512i R07 = _mm512_load_si512(pr + 7); + __m512i R08 = _mm512_load_si512(pr + 8); + __m512i R09 = _mm512_load_si512(pr + 9); + + int itr; + for (itr = 0; itr < LEN52; itr++) { + __m512i Bi = _mm512_load_si512(pb); + __m512i nxtR = _mm512_load_si512(pr + LEN52); + pb++; + + _mm512_madd52lo_epu64_(R00, R00, Bi, pa, 64 * 0); + _mm512_madd52lo_epu64_(R01, R01, Bi, pa, 64 * 1); + _mm512_madd52lo_epu64_(R02, R02, Bi, pa, 64 * 2); + _mm512_madd52lo_epu64_(R03, R03, Bi, pa, 64 * 3); + _mm512_madd52lo_epu64_(R04, R04, Bi, pa, 64 * 4); + _mm512_madd52lo_epu64_(R05, R05, Bi, pa, 64 * 5); + _mm512_madd52lo_epu64_(R06, R06, Bi, pa, 64 * 6); + _mm512_madd52lo_epu64_(R07, R07, Bi, pa, 64 * 7); + _mm512_madd52lo_epu64_(R08, R08, Bi, pa, 64 * 8); + _mm512_madd52lo_epu64_(R09, R09, Bi, pa, 64 * 9); + + _mm512_store_si512(pr, _mm512_and_epi64(R00, DIG_MASK)); /* store normalized result */ + pr++; + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Bi, pa, 64 * 0); + _mm512_madd52hi_epu64_(R01, R02, Bi, pa, 64 * 1); + _mm512_madd52hi_epu64_(R02, R03, Bi, pa, 64 * 2); + _mm512_madd52hi_epu64_(R03, R04, Bi, pa, 64 * 3); + _mm512_madd52hi_epu64_(R04, R05, Bi, pa, 64 * 4); + _mm512_madd52hi_epu64_(R05, R06, Bi, pa, 64 * 5); + _mm512_madd52hi_epu64_(R06, R07, Bi, pa, 64 * 6); + _mm512_madd52hi_epu64_(R07, R08, Bi, pa, 64 * 7); + _mm512_madd52hi_epu64_(R08, R09, Bi, pa, 64 * 8); + _mm512_madd52hi_epu64_(R09, nxtR, Bi, pa, 64 * 9); + } + /* normalization */ + { + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, DIG_MASK); + _mm512_store_si512(pr + 0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, DIG_MASK); + _mm512_store_si512(pr + 1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, DIG_MASK); + _mm512_store_si512(pr + 2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, DIG_MASK); + _mm512_store_si512(pr + 3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, DIG_MASK); + _mm512_store_si512(pr + 4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, DIG_MASK); + _mm512_store_si512(pr + 5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, DIG_MASK); + _mm512_store_si512(pr + 6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, DIG_MASK); + _mm512_store_si512(pr + 7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, DIG_MASK); + _mm512_store_si512(pr + 8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, DIG_MASK); + _mm512_store_si512(pr + 9, R09); + } + +#undef BITSIZE +#undef LEN52 +#undef MSD_MSK +} + +void ifma_addmul52x20_mb8(int64u pRes[][8], const int64u inpA[][8], const int64u inpB[][8]) +{ + #define BITSIZE (RSA_2K/2) + #define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) + #define MSD_MSK (MS_DIGIT_MASK(RSA_2K,52)) + + __m512i* pr = (__m512i*)pRes; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + __m512i MS_DIG_MASK = _mm512_set1_epi64(MSD_MSK); + + __m512i R00 = _mm512_load_si512(pr + 0); /* load pr[nsM-1],...,R[0] */ + __m512i R01 = _mm512_load_si512(pr + 1); + __m512i R02 = _mm512_load_si512(pr + 2); + __m512i R03 = _mm512_load_si512(pr + 3); + __m512i R04 = _mm512_load_si512(pr + 4); + __m512i R05 = _mm512_load_si512(pr + 5); + __m512i R06 = _mm512_load_si512(pr + 6); + __m512i R07 = _mm512_load_si512(pr + 7); + __m512i R08 = _mm512_load_si512(pr + 8); + __m512i R09 = _mm512_load_si512(pr + 9); + __m512i R10 = _mm512_load_si512(pr + 10); + __m512i R11 = _mm512_load_si512(pr + 11); + __m512i R12 = _mm512_load_si512(pr + 12); + __m512i R13 = _mm512_load_si512(pr + 13); + __m512i R14 = _mm512_load_si512(pr + 14); + __m512i R15 = _mm512_load_si512(pr + 15); + __m512i R16 = _mm512_load_si512(pr + 16); + __m512i R17 = _mm512_load_si512(pr + 17); + __m512i R18 = _mm512_load_si512(pr + 18); + __m512i R19 = _mm512_load_si512(pr + 19); + + int itr; + for (itr = 0; itr < LEN52; itr++) { + __m512i Bi = _mm512_load_si512(pb); + __m512i nxtR = _mm512_load_si512(pr + LEN52); + pb++; + + _mm512_madd52lo_epu64_(R00, R00, Bi, pa, 64 * 0); + _mm512_madd52lo_epu64_(R01, R01, Bi, pa, 64 * 1); + _mm512_madd52lo_epu64_(R02, R02, Bi, pa, 64 * 2); + _mm512_madd52lo_epu64_(R03, R03, Bi, pa, 64 * 3); + _mm512_madd52lo_epu64_(R04, R04, Bi, pa, 64 * 4); + _mm512_madd52lo_epu64_(R05, R05, Bi, pa, 64 * 5); + _mm512_madd52lo_epu64_(R06, R06, Bi, pa, 64 * 6); + _mm512_madd52lo_epu64_(R07, R07, Bi, pa, 64 * 7); + _mm512_madd52lo_epu64_(R08, R08, Bi, pa, 64 * 8); + _mm512_madd52lo_epu64_(R09, R09, Bi, pa, 64 * 9); + _mm512_madd52lo_epu64_(R10, R10, Bi, pa, 64 * 10); + _mm512_madd52lo_epu64_(R11, R11, Bi, pa, 64 * 11); + _mm512_madd52lo_epu64_(R12, R12, Bi, pa, 64 * 12); + _mm512_madd52lo_epu64_(R13, R13, Bi, pa, 64 * 13); + _mm512_madd52lo_epu64_(R14, R14, Bi, pa, 64 * 14); + _mm512_madd52lo_epu64_(R15, R15, Bi, pa, 64 * 15); + _mm512_madd52lo_epu64_(R16, R16, Bi, pa, 64 * 16); + _mm512_madd52lo_epu64_(R17, R17, Bi, pa, 64 * 17); + _mm512_madd52lo_epu64_(R18, R18, Bi, pa, 64 * 18); + _mm512_madd52lo_epu64_(R19, R19, Bi, pa, 64 * 19); + + _mm512_store_si512(pr, _mm512_and_epi64(R00, DIG_MASK)); /* store normalized result */ + pr++; + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Bi, pa, 64 * 0); + _mm512_madd52hi_epu64_(R01, R02, Bi, pa, 64 * 1); + _mm512_madd52hi_epu64_(R02, R03, Bi, pa, 64 * 2); + _mm512_madd52hi_epu64_(R03, R04, Bi, pa, 64 * 3); + _mm512_madd52hi_epu64_(R04, R05, Bi, pa, 64 * 4); + _mm512_madd52hi_epu64_(R05, R06, Bi, pa, 64 * 5); + _mm512_madd52hi_epu64_(R06, R07, Bi, pa, 64 * 6); + _mm512_madd52hi_epu64_(R07, R08, Bi, pa, 64 * 7); + _mm512_madd52hi_epu64_(R08, R09, Bi, pa, 64 * 8); + _mm512_madd52hi_epu64_(R09, R10, Bi, pa, 64 * 9); + _mm512_madd52hi_epu64_(R10, R11, Bi, pa, 64 * 10); + _mm512_madd52hi_epu64_(R11, R12, Bi, pa, 64 * 11); + _mm512_madd52hi_epu64_(R12, R13, Bi, pa, 64 * 12); + _mm512_madd52hi_epu64_(R13, R14, Bi, pa, 64 * 13); + _mm512_madd52hi_epu64_(R14, R15, Bi, pa, 64 * 14); + _mm512_madd52hi_epu64_(R15, R16, Bi, pa, 64 * 15); + _mm512_madd52hi_epu64_(R16, R17, Bi, pa, 64 * 16); + _mm512_madd52hi_epu64_(R17, R18, Bi, pa, 64 * 17); + _mm512_madd52hi_epu64_(R18, R19, Bi, pa, 64 * 18); + _mm512_madd52hi_epu64_(R19, nxtR, Bi, pa, 64 * 19); + } + /* normalization */ + { + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, DIG_MASK); + _mm512_store_si512(pr + 0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, DIG_MASK); + _mm512_store_si512(pr + 1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, DIG_MASK); + _mm512_store_si512(pr + 2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, DIG_MASK); + _mm512_store_si512(pr + 3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, DIG_MASK); + _mm512_store_si512(pr + 4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, DIG_MASK); + _mm512_store_si512(pr + 5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, DIG_MASK); + _mm512_store_si512(pr + 6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, DIG_MASK); + _mm512_store_si512(pr + 7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, DIG_MASK); + _mm512_store_si512(pr + 8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, DIG_MASK); + _mm512_store_si512(pr + 9, R09); + + R10 = _mm512_add_epi64(R10, T); + T = _mm512_srli_epi64(R10, DIGIT_SIZE); + R10 = _mm512_and_epi64(R10, DIG_MASK); + _mm512_store_si512(pr + 10, R10); + + R11 = _mm512_add_epi64(R11, T); + T = _mm512_srli_epi64(R11, DIGIT_SIZE); + R11 = _mm512_and_epi64(R11, DIG_MASK); + _mm512_store_si512(pr + 11, R11); + + R12 = _mm512_add_epi64(R12, T); + T = _mm512_srli_epi64(R12, DIGIT_SIZE); + R12 = _mm512_and_epi64(R12, DIG_MASK); + _mm512_store_si512(pr + 12, R12); + + R13 = _mm512_add_epi64(R13, T); + T = _mm512_srli_epi64(R13, DIGIT_SIZE); + R13 = _mm512_and_epi64(R13, DIG_MASK); + _mm512_store_si512(pr + 13, R13); + + R14 = _mm512_add_epi64(R14, T); + T = _mm512_srli_epi64(R14, DIGIT_SIZE); + R14 = _mm512_and_epi64(R14, DIG_MASK); + _mm512_store_si512(pr + 14, R14); + + R15 = _mm512_add_epi64(R15, T); + T = _mm512_srli_epi64(R15, DIGIT_SIZE); + R15 = _mm512_and_epi64(R15, DIG_MASK); + _mm512_store_si512(pr + 15, R15); + + R16 = _mm512_add_epi64(R16, T); + T = _mm512_srli_epi64(R16, DIGIT_SIZE); + R16 = _mm512_and_epi64(R16, DIG_MASK); + _mm512_store_si512(pr + 16, R16); + + R17 = _mm512_add_epi64(R17, T); + T = _mm512_srli_epi64(R17, DIGIT_SIZE); + R17 = _mm512_and_epi64(R17, DIG_MASK); + _mm512_store_si512(pr + 17, R17); + + R18 = _mm512_add_epi64(R18, T); + T = _mm512_srli_epi64(R18, DIGIT_SIZE); + R18 = _mm512_and_epi64(R18, DIG_MASK); + _mm512_store_si512(pr + 18, R18); + + R19 = _mm512_add_epi64(R19, T); + T = _mm512_srli_epi64(R19, DIGIT_SIZE); + R19 = _mm512_and_epi64(R19, MS_DIG_MASK); + _mm512_store_si512(pr + 19, R19); + } + + #undef BITSIZE + #undef LEN52 + #undef MSD_MSK +} + +void ifma_addmul52x30_mb8(int64u pRes[][8], const int64u inpA[][8], const int64u inpB[][8]) +{ +#define BITSIZE (RSA_3K/2) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) +#define MSD_MSK (MS_DIGIT_MASK(RSA_3K,52)) + + __m512i* pr = (__m512i*)pRes; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + __m512i MS_DIG_MASK = _mm512_set1_epi64(MSD_MSK); + + __m512i R00 = _mm512_load_si512(pr + 0); /* load pr[nsM-1],...,R[0] */ + __m512i R01 = _mm512_load_si512(pr + 1); + __m512i R02 = _mm512_load_si512(pr + 2); + __m512i R03 = _mm512_load_si512(pr + 3); + __m512i R04 = _mm512_load_si512(pr + 4); + __m512i R05 = _mm512_load_si512(pr + 5); + __m512i R06 = _mm512_load_si512(pr + 6); + __m512i R07 = _mm512_load_si512(pr + 7); + __m512i R08 = _mm512_load_si512(pr + 8); + __m512i R09 = _mm512_load_si512(pr + 9); + __m512i R10 = _mm512_load_si512(pr + 10); + __m512i R11 = _mm512_load_si512(pr + 11); + __m512i R12 = _mm512_load_si512(pr + 12); + __m512i R13 = _mm512_load_si512(pr + 13); + __m512i R14 = _mm512_load_si512(pr + 14); + __m512i R15 = _mm512_load_si512(pr + 15); + __m512i R16 = _mm512_load_si512(pr + 16); + __m512i R17 = _mm512_load_si512(pr + 17); + __m512i R18 = _mm512_load_si512(pr + 18); + __m512i R19 = _mm512_load_si512(pr + 19); + __m512i R20 = _mm512_load_si512(pr + 20); + __m512i R21 = _mm512_load_si512(pr + 21); + __m512i R22 = _mm512_load_si512(pr + 22); + __m512i R23 = _mm512_load_si512(pr + 23); + __m512i R24 = _mm512_load_si512(pr + 24); + __m512i R25 = _mm512_load_si512(pr + 25); + __m512i R26 = _mm512_load_si512(pr + 26); + __m512i R27 = _mm512_load_si512(pr + 27); + __m512i R28 = _mm512_load_si512(pr + 28); + __m512i R29 = _mm512_load_si512(pr + 29); + + int itr; + for (itr = 0; itr < LEN52; itr++) { + __m512i Bi = _mm512_load_si512(pb); + __m512i nxtR = _mm512_load_si512(pr + LEN52); + pb++; + + _mm512_madd52lo_epu64_(R00, R00, Bi, pa, 64 * 0); + _mm512_madd52lo_epu64_(R01, R01, Bi, pa, 64 * 1); + _mm512_madd52lo_epu64_(R02, R02, Bi, pa, 64 * 2); + _mm512_madd52lo_epu64_(R03, R03, Bi, pa, 64 * 3); + _mm512_madd52lo_epu64_(R04, R04, Bi, pa, 64 * 4); + _mm512_madd52lo_epu64_(R05, R05, Bi, pa, 64 * 5); + _mm512_madd52lo_epu64_(R06, R06, Bi, pa, 64 * 6); + _mm512_madd52lo_epu64_(R07, R07, Bi, pa, 64 * 7); + _mm512_madd52lo_epu64_(R08, R08, Bi, pa, 64 * 8); + _mm512_madd52lo_epu64_(R09, R09, Bi, pa, 64 * 9); + _mm512_madd52lo_epu64_(R10, R10, Bi, pa, 64 * 10); + _mm512_madd52lo_epu64_(R11, R11, Bi, pa, 64 * 11); + _mm512_madd52lo_epu64_(R12, R12, Bi, pa, 64 * 12); + _mm512_madd52lo_epu64_(R13, R13, Bi, pa, 64 * 13); + _mm512_madd52lo_epu64_(R14, R14, Bi, pa, 64 * 14); + _mm512_madd52lo_epu64_(R15, R15, Bi, pa, 64 * 15); + _mm512_madd52lo_epu64_(R16, R16, Bi, pa, 64 * 16); + _mm512_madd52lo_epu64_(R17, R17, Bi, pa, 64 * 17); + _mm512_madd52lo_epu64_(R18, R18, Bi, pa, 64 * 18); + _mm512_madd52lo_epu64_(R19, R19, Bi, pa, 64 * 19); + _mm512_madd52lo_epu64_(R20, R20, Bi, pa, 64 * 20); + _mm512_madd52lo_epu64_(R21, R21, Bi, pa, 64 * 21); + _mm512_madd52lo_epu64_(R22, R22, Bi, pa, 64 * 22); + _mm512_madd52lo_epu64_(R23, R23, Bi, pa, 64 * 23); + _mm512_madd52lo_epu64_(R24, R24, Bi, pa, 64 * 24); + _mm512_madd52lo_epu64_(R25, R25, Bi, pa, 64 * 25); + _mm512_madd52lo_epu64_(R26, R26, Bi, pa, 64 * 26); + _mm512_madd52lo_epu64_(R27, R27, Bi, pa, 64 * 27); + _mm512_madd52lo_epu64_(R28, R28, Bi, pa, 64 * 28); + _mm512_madd52lo_epu64_(R29, R29, Bi, pa, 64 * 29); + + _mm512_store_si512(pr, _mm512_and_epi64(R00, DIG_MASK)); /* store normalized result */ + pr++; + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Bi, pa, 64 * 0); + _mm512_madd52hi_epu64_(R01, R02, Bi, pa, 64 * 1); + _mm512_madd52hi_epu64_(R02, R03, Bi, pa, 64 * 2); + _mm512_madd52hi_epu64_(R03, R04, Bi, pa, 64 * 3); + _mm512_madd52hi_epu64_(R04, R05, Bi, pa, 64 * 4); + _mm512_madd52hi_epu64_(R05, R06, Bi, pa, 64 * 5); + _mm512_madd52hi_epu64_(R06, R07, Bi, pa, 64 * 6); + _mm512_madd52hi_epu64_(R07, R08, Bi, pa, 64 * 7); + _mm512_madd52hi_epu64_(R08, R09, Bi, pa, 64 * 8); + _mm512_madd52hi_epu64_(R09, R10, Bi, pa, 64 * 9); + _mm512_madd52hi_epu64_(R10, R11, Bi, pa, 64 * 10); + _mm512_madd52hi_epu64_(R11, R12, Bi, pa, 64 * 11); + _mm512_madd52hi_epu64_(R12, R13, Bi, pa, 64 * 12); + _mm512_madd52hi_epu64_(R13, R14, Bi, pa, 64 * 13); + _mm512_madd52hi_epu64_(R14, R15, Bi, pa, 64 * 14); + _mm512_madd52hi_epu64_(R15, R16, Bi, pa, 64 * 15); + _mm512_madd52hi_epu64_(R16, R17, Bi, pa, 64 * 16); + _mm512_madd52hi_epu64_(R17, R18, Bi, pa, 64 * 17); + _mm512_madd52hi_epu64_(R18, R19, Bi, pa, 64 * 18); + _mm512_madd52hi_epu64_(R19, R20, Bi, pa, 64 * 19); + _mm512_madd52hi_epu64_(R20, R21, Bi, pa, 64 * 20); + _mm512_madd52hi_epu64_(R21, R22, Bi, pa, 64 * 21); + _mm512_madd52hi_epu64_(R22, R23, Bi, pa, 64 * 22); + _mm512_madd52hi_epu64_(R23, R24, Bi, pa, 64 * 23); + _mm512_madd52hi_epu64_(R24, R25, Bi, pa, 64 * 24); + _mm512_madd52hi_epu64_(R25, R26, Bi, pa, 64 * 25); + _mm512_madd52hi_epu64_(R26, R27, Bi, pa, 64 * 26); + _mm512_madd52hi_epu64_(R27, R28, Bi, pa, 64 * 27); + _mm512_madd52hi_epu64_(R28, R29, Bi, pa, 64 * 28); + _mm512_madd52hi_epu64_(R29, nxtR, Bi, pa, 64 * 29); + } + /* normalization */ + { + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, DIG_MASK); + _mm512_store_si512(pr + 0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, DIG_MASK); + _mm512_store_si512(pr + 1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, DIG_MASK); + _mm512_store_si512(pr + 2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, DIG_MASK); + _mm512_store_si512(pr + 3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, DIG_MASK); + _mm512_store_si512(pr + 4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, DIG_MASK); + _mm512_store_si512(pr + 5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, DIG_MASK); + _mm512_store_si512(pr + 6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, DIG_MASK); + _mm512_store_si512(pr + 7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, DIG_MASK); + _mm512_store_si512(pr + 8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, DIG_MASK); + _mm512_store_si512(pr + 9, R09); + + R10 = _mm512_add_epi64(R10, T); + T = _mm512_srli_epi64(R10, DIGIT_SIZE); + R10 = _mm512_and_epi64(R10, DIG_MASK); + _mm512_store_si512(pr + 10, R10); + + R11 = _mm512_add_epi64(R11, T); + T = _mm512_srli_epi64(R11, DIGIT_SIZE); + R11 = _mm512_and_epi64(R11, DIG_MASK); + _mm512_store_si512(pr + 11, R11); + + R12 = _mm512_add_epi64(R12, T); + T = _mm512_srli_epi64(R12, DIGIT_SIZE); + R12 = _mm512_and_epi64(R12, DIG_MASK); + _mm512_store_si512(pr + 12, R12); + + R13 = _mm512_add_epi64(R13, T); + T = _mm512_srli_epi64(R13, DIGIT_SIZE); + R13 = _mm512_and_epi64(R13, DIG_MASK); + _mm512_store_si512(pr + 13, R13); + + R14 = _mm512_add_epi64(R14, T); + T = _mm512_srli_epi64(R14, DIGIT_SIZE); + R14 = _mm512_and_epi64(R14, DIG_MASK); + _mm512_store_si512(pr + 14, R14); + + R15 = _mm512_add_epi64(R15, T); + T = _mm512_srli_epi64(R15, DIGIT_SIZE); + R15 = _mm512_and_epi64(R15, DIG_MASK); + _mm512_store_si512(pr + 15, R15); + + R16 = _mm512_add_epi64(R16, T); + T = _mm512_srli_epi64(R16, DIGIT_SIZE); + R16 = _mm512_and_epi64(R16, DIG_MASK); + _mm512_store_si512(pr + 16, R16); + + R17 = _mm512_add_epi64(R17, T); + T = _mm512_srli_epi64(R17, DIGIT_SIZE); + R17 = _mm512_and_epi64(R17, DIG_MASK); + _mm512_store_si512(pr + 17, R17); + + R18 = _mm512_add_epi64(R18, T); + T = _mm512_srli_epi64(R18, DIGIT_SIZE); + R18 = _mm512_and_epi64(R18, DIG_MASK); + _mm512_store_si512(pr + 18, R18); + + R19 = _mm512_add_epi64(R19, T); + T = _mm512_srli_epi64(R19, DIGIT_SIZE); + R19 = _mm512_and_epi64(R19, DIG_MASK); + _mm512_store_si512(pr + 19, R19); + + R20 = _mm512_add_epi64(R20, T); + T = _mm512_srli_epi64(R20, DIGIT_SIZE); + R20 = _mm512_and_epi64(R20, DIG_MASK); + _mm512_store_si512(pr + 20, R20); + + R21 = _mm512_add_epi64(R21, T); + T = _mm512_srli_epi64(R21, DIGIT_SIZE); + R21 = _mm512_and_epi64(R21, DIG_MASK); + _mm512_store_si512(pr + 21, R21); + + R22 = _mm512_add_epi64(R22, T); + T = _mm512_srli_epi64(R22, DIGIT_SIZE); + R22 = _mm512_and_epi64(R22, DIG_MASK); + _mm512_store_si512(pr + 22, R22); + + R23 = _mm512_add_epi64(R23, T); + T = _mm512_srli_epi64(R23, DIGIT_SIZE); + R23 = _mm512_and_epi64(R23, DIG_MASK); + _mm512_store_si512(pr + 23, R23); + + R24 = _mm512_add_epi64(R24, T); + T = _mm512_srli_epi64(R24, DIGIT_SIZE); + R24 = _mm512_and_epi64(R24, DIG_MASK); + _mm512_store_si512(pr + 24, R24); + + R25 = _mm512_add_epi64(R25, T); + T = _mm512_srli_epi64(R25, DIGIT_SIZE); + R25 = _mm512_and_epi64(R25, DIG_MASK); + _mm512_store_si512(pr + 25, R25); + + R26 = _mm512_add_epi64(R26, T); + T = _mm512_srli_epi64(R26, DIGIT_SIZE); + R26 = _mm512_and_epi64(R26, DIG_MASK); + _mm512_store_si512(pr + 26, R26); + + R27 = _mm512_add_epi64(R27, T); + T = _mm512_srli_epi64(R27, DIGIT_SIZE); + R27 = _mm512_and_epi64(R27, DIG_MASK); + _mm512_store_si512(pr + 27, R27); + + R28 = _mm512_add_epi64(R28, T); + T = _mm512_srli_epi64(R28, DIGIT_SIZE); + R28 = _mm512_and_epi64(R28, DIG_MASK); + _mm512_store_si512(pr + 28, R28); + + R29 = _mm512_add_epi64(R29, T); + T = _mm512_srli_epi64(R29, DIGIT_SIZE); + R29 = _mm512_and_epi64(R29, MS_DIG_MASK); + _mm512_store_si512(pr + 29, R29); + } + + #undef BITSIZE + #undef LEN52 + #undef MSD_MSK +} + + +void ifma_addmul52x40_mb8(int64u pRes[][8], const int64u inpA[][8], const int64u inpB[][8]) +{ +#define BITSIZE (RSA_4K/2) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE,52)) +#define MSD_MSK (MS_DIGIT_MASK(RSA_4K,52)) + + __m512i* pr = (__m512i*)pRes; + __m512i* pa = (__m512i*)inpA; + __m512i* pb = (__m512i*)inpB; + + __m512i DIG_MASK = _mm512_set1_epi64(DIGIT_MASK); + __m512i MS_DIG_MASK = _mm512_set1_epi64(MSD_MSK); + + __m512i R00 = _mm512_load_si512(pr + 0); /* load pr[nsM-1],...,R[0] */ + __m512i R01 = _mm512_load_si512(pr + 1); + __m512i R02 = _mm512_load_si512(pr + 2); + __m512i R03 = _mm512_load_si512(pr + 3); + __m512i R04 = _mm512_load_si512(pr + 4); + __m512i R05 = _mm512_load_si512(pr + 5); + __m512i R06 = _mm512_load_si512(pr + 6); + __m512i R07 = _mm512_load_si512(pr + 7); + __m512i R08 = _mm512_load_si512(pr + 8); + __m512i R09 = _mm512_load_si512(pr + 9); + __m512i R10 = _mm512_load_si512(pr + 10); + __m512i R11 = _mm512_load_si512(pr + 11); + __m512i R12 = _mm512_load_si512(pr + 12); + __m512i R13 = _mm512_load_si512(pr + 13); + __m512i R14 = _mm512_load_si512(pr + 14); + __m512i R15 = _mm512_load_si512(pr + 15); + __m512i R16 = _mm512_load_si512(pr + 16); + __m512i R17 = _mm512_load_si512(pr + 17); + __m512i R18 = _mm512_load_si512(pr + 18); + __m512i R19 = _mm512_load_si512(pr + 19); + __m512i R20 = _mm512_load_si512(pr + 20); + __m512i R21 = _mm512_load_si512(pr + 21); + __m512i R22 = _mm512_load_si512(pr + 22); + __m512i R23 = _mm512_load_si512(pr + 23); + __m512i R24 = _mm512_load_si512(pr + 24); + __m512i R25 = _mm512_load_si512(pr + 25); + __m512i R26 = _mm512_load_si512(pr + 26); + __m512i R27 = _mm512_load_si512(pr + 27); + __m512i R28 = _mm512_load_si512(pr + 28); + __m512i R29 = _mm512_load_si512(pr + 29); + __m512i R30 = _mm512_load_si512(pr + 30); + __m512i R31 = _mm512_load_si512(pr + 31); + __m512i R32 = _mm512_load_si512(pr + 32); + __m512i R33 = _mm512_load_si512(pr + 33); + __m512i R34 = _mm512_load_si512(pr + 34); + __m512i R35 = _mm512_load_si512(pr + 35); + __m512i R36 = _mm512_load_si512(pr + 36); + __m512i R37 = _mm512_load_si512(pr + 37); + __m512i R38 = _mm512_load_si512(pr + 38); + __m512i R39 = _mm512_load_si512(pr + 39); + + int itr; + for (itr = 0; itr < LEN52; itr++) { + __m512i Bi = _mm512_load_si512(pb); + __m512i nxtR = _mm512_load_si512(pr + LEN52); + pb++; + + _mm512_madd52lo_epu64_(R00, R00, Bi, pa, 64 * 0); + _mm512_madd52lo_epu64_(R01, R01, Bi, pa, 64 * 1); + _mm512_madd52lo_epu64_(R02, R02, Bi, pa, 64 * 2); + _mm512_madd52lo_epu64_(R03, R03, Bi, pa, 64 * 3); + _mm512_madd52lo_epu64_(R04, R04, Bi, pa, 64 * 4); + _mm512_madd52lo_epu64_(R05, R05, Bi, pa, 64 * 5); + _mm512_madd52lo_epu64_(R06, R06, Bi, pa, 64 * 6); + _mm512_madd52lo_epu64_(R07, R07, Bi, pa, 64 * 7); + _mm512_madd52lo_epu64_(R08, R08, Bi, pa, 64 * 8); + _mm512_madd52lo_epu64_(R09, R09, Bi, pa, 64 * 9); + _mm512_madd52lo_epu64_(R10, R10, Bi, pa, 64 * 10); + _mm512_madd52lo_epu64_(R11, R11, Bi, pa, 64 * 11); + _mm512_madd52lo_epu64_(R12, R12, Bi, pa, 64 * 12); + _mm512_madd52lo_epu64_(R13, R13, Bi, pa, 64 * 13); + _mm512_madd52lo_epu64_(R14, R14, Bi, pa, 64 * 14); + _mm512_madd52lo_epu64_(R15, R15, Bi, pa, 64 * 15); + _mm512_madd52lo_epu64_(R16, R16, Bi, pa, 64 * 16); + _mm512_madd52lo_epu64_(R17, R17, Bi, pa, 64 * 17); + _mm512_madd52lo_epu64_(R18, R18, Bi, pa, 64 * 18); + _mm512_madd52lo_epu64_(R19, R19, Bi, pa, 64 * 19); + _mm512_madd52lo_epu64_(R20, R20, Bi, pa, 64 * 20); + _mm512_madd52lo_epu64_(R21, R21, Bi, pa, 64 * 21); + _mm512_madd52lo_epu64_(R22, R22, Bi, pa, 64 * 22); + _mm512_madd52lo_epu64_(R23, R23, Bi, pa, 64 * 23); + _mm512_madd52lo_epu64_(R24, R24, Bi, pa, 64 * 24); + _mm512_madd52lo_epu64_(R25, R25, Bi, pa, 64 * 25); + _mm512_madd52lo_epu64_(R26, R26, Bi, pa, 64 * 26); + _mm512_madd52lo_epu64_(R27, R27, Bi, pa, 64 * 27); + _mm512_madd52lo_epu64_(R28, R28, Bi, pa, 64 * 28); + _mm512_madd52lo_epu64_(R29, R29, Bi, pa, 64 * 29); + _mm512_madd52lo_epu64_(R30, R30, Bi, pa, 64 * 30); + _mm512_madd52lo_epu64_(R31, R31, Bi, pa, 64 * 31); + _mm512_madd52lo_epu64_(R32, R32, Bi, pa, 64 * 32); + _mm512_madd52lo_epu64_(R33, R33, Bi, pa, 64 * 33); + _mm512_madd52lo_epu64_(R34, R34, Bi, pa, 64 * 34); + _mm512_madd52lo_epu64_(R35, R35, Bi, pa, 64 * 35); + _mm512_madd52lo_epu64_(R36, R36, Bi, pa, 64 * 36); + _mm512_madd52lo_epu64_(R37, R37, Bi, pa, 64 * 37); + _mm512_madd52lo_epu64_(R38, R38, Bi, pa, 64 * 38); + _mm512_madd52lo_epu64_(R39, R39, Bi, pa, 64 * 39); + + _mm512_store_si512(pr, _mm512_and_epi64(R00, DIG_MASK)); /* store normalized result */ + pr++; + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Bi, pa, 64 * 0); + _mm512_madd52hi_epu64_(R01, R02, Bi, pa, 64 * 1); + _mm512_madd52hi_epu64_(R02, R03, Bi, pa, 64 * 2); + _mm512_madd52hi_epu64_(R03, R04, Bi, pa, 64 * 3); + _mm512_madd52hi_epu64_(R04, R05, Bi, pa, 64 * 4); + _mm512_madd52hi_epu64_(R05, R06, Bi, pa, 64 * 5); + _mm512_madd52hi_epu64_(R06, R07, Bi, pa, 64 * 6); + _mm512_madd52hi_epu64_(R07, R08, Bi, pa, 64 * 7); + _mm512_madd52hi_epu64_(R08, R09, Bi, pa, 64 * 8); + _mm512_madd52hi_epu64_(R09, R10, Bi, pa, 64 * 9); + _mm512_madd52hi_epu64_(R10, R11, Bi, pa, 64 * 10); + _mm512_madd52hi_epu64_(R11, R12, Bi, pa, 64 * 11); + _mm512_madd52hi_epu64_(R12, R13, Bi, pa, 64 * 12); + _mm512_madd52hi_epu64_(R13, R14, Bi, pa, 64 * 13); + _mm512_madd52hi_epu64_(R14, R15, Bi, pa, 64 * 14); + _mm512_madd52hi_epu64_(R15, R16, Bi, pa, 64 * 15); + _mm512_madd52hi_epu64_(R16, R17, Bi, pa, 64 * 16); + _mm512_madd52hi_epu64_(R17, R18, Bi, pa, 64 * 17); + _mm512_madd52hi_epu64_(R18, R19, Bi, pa, 64 * 18); + _mm512_madd52hi_epu64_(R19, R20, Bi, pa, 64 * 19); + _mm512_madd52hi_epu64_(R20, R21, Bi, pa, 64 * 20); + _mm512_madd52hi_epu64_(R21, R22, Bi, pa, 64 * 21); + _mm512_madd52hi_epu64_(R22, R23, Bi, pa, 64 * 22); + _mm512_madd52hi_epu64_(R23, R24, Bi, pa, 64 * 23); + _mm512_madd52hi_epu64_(R24, R25, Bi, pa, 64 * 24); + _mm512_madd52hi_epu64_(R25, R26, Bi, pa, 64 * 25); + _mm512_madd52hi_epu64_(R26, R27, Bi, pa, 64 * 26); + _mm512_madd52hi_epu64_(R27, R28, Bi, pa, 64 * 27); + _mm512_madd52hi_epu64_(R28, R29, Bi, pa, 64 * 28); + _mm512_madd52hi_epu64_(R29, R30, Bi, pa, 64 * 29); + _mm512_madd52hi_epu64_(R30, R31, Bi, pa, 64 * 30); + _mm512_madd52hi_epu64_(R31, R32, Bi, pa, 64 * 31); + _mm512_madd52hi_epu64_(R32, R33, Bi, pa, 64 * 32); + _mm512_madd52hi_epu64_(R33, R34, Bi, pa, 64 * 33); + _mm512_madd52hi_epu64_(R34, R35, Bi, pa, 64 * 34); + _mm512_madd52hi_epu64_(R35, R36, Bi, pa, 64 * 35); + _mm512_madd52hi_epu64_(R36, R37, Bi, pa, 64 * 36); + _mm512_madd52hi_epu64_(R37, R38, Bi, pa, 64 * 37); + _mm512_madd52hi_epu64_(R38, R39, Bi, pa, 64 * 38); + _mm512_madd52hi_epu64_(R39, nxtR, Bi, pa, 64 * 39); + + } + /* normalization */ + { + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, DIG_MASK); + _mm512_store_si512(pr + 0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, DIG_MASK); + _mm512_store_si512(pr + 1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, DIG_MASK); + _mm512_store_si512(pr + 2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, DIG_MASK); + _mm512_store_si512(pr + 3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, DIG_MASK); + _mm512_store_si512(pr + 4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, DIG_MASK); + _mm512_store_si512(pr + 5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, DIG_MASK); + _mm512_store_si512(pr + 6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, DIG_MASK); + _mm512_store_si512(pr + 7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, DIG_MASK); + _mm512_store_si512(pr + 8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, DIG_MASK); + _mm512_store_si512(pr + 9, R09); + + R10 = _mm512_add_epi64(R10, T); + T = _mm512_srli_epi64(R10, DIGIT_SIZE); + R10 = _mm512_and_epi64(R10, DIG_MASK); + _mm512_store_si512(pr + 10, R10); + + R11 = _mm512_add_epi64(R11, T); + T = _mm512_srli_epi64(R11, DIGIT_SIZE); + R11 = _mm512_and_epi64(R11, DIG_MASK); + _mm512_store_si512(pr + 11, R11); + + R12 = _mm512_add_epi64(R12, T); + T = _mm512_srli_epi64(R12, DIGIT_SIZE); + R12 = _mm512_and_epi64(R12, DIG_MASK); + _mm512_store_si512(pr + 12, R12); + + R13 = _mm512_add_epi64(R13, T); + T = _mm512_srli_epi64(R13, DIGIT_SIZE); + R13 = _mm512_and_epi64(R13, DIG_MASK); + _mm512_store_si512(pr + 13, R13); + + R14 = _mm512_add_epi64(R14, T); + T = _mm512_srli_epi64(R14, DIGIT_SIZE); + R14 = _mm512_and_epi64(R14, DIG_MASK); + _mm512_store_si512(pr + 14, R14); + + R15 = _mm512_add_epi64(R15, T); + T = _mm512_srli_epi64(R15, DIGIT_SIZE); + R15 = _mm512_and_epi64(R15, DIG_MASK); + _mm512_store_si512(pr + 15, R15); + + R16 = _mm512_add_epi64(R16, T); + T = _mm512_srli_epi64(R16, DIGIT_SIZE); + R16 = _mm512_and_epi64(R16, DIG_MASK); + _mm512_store_si512(pr + 16, R16); + + R17 = _mm512_add_epi64(R17, T); + T = _mm512_srli_epi64(R17, DIGIT_SIZE); + R17 = _mm512_and_epi64(R17, DIG_MASK); + _mm512_store_si512(pr + 17, R17); + + R18 = _mm512_add_epi64(R18, T); + T = _mm512_srli_epi64(R18, DIGIT_SIZE); + R18 = _mm512_and_epi64(R18, DIG_MASK); + _mm512_store_si512(pr + 18, R18); + + R19 = _mm512_add_epi64(R19, T); + T = _mm512_srli_epi64(R19, DIGIT_SIZE); + R19 = _mm512_and_epi64(R19, DIG_MASK); + _mm512_store_si512(pr + 19, R19); + + R20 = _mm512_add_epi64(R20, T); + T = _mm512_srli_epi64(R20, DIGIT_SIZE); + R20 = _mm512_and_epi64(R20, DIG_MASK); + _mm512_store_si512(pr + 20, R20); + + R21 = _mm512_add_epi64(R21, T); + T = _mm512_srli_epi64(R21, DIGIT_SIZE); + R21 = _mm512_and_epi64(R21, DIG_MASK); + _mm512_store_si512(pr + 21, R21); + + R22 = _mm512_add_epi64(R22, T); + T = _mm512_srli_epi64(R22, DIGIT_SIZE); + R22 = _mm512_and_epi64(R22, DIG_MASK); + _mm512_store_si512(pr + 22, R22); + + R23 = _mm512_add_epi64(R23, T); + T = _mm512_srli_epi64(R23, DIGIT_SIZE); + R23 = _mm512_and_epi64(R23, DIG_MASK); + _mm512_store_si512(pr + 23, R23); + + R24 = _mm512_add_epi64(R24, T); + T = _mm512_srli_epi64(R24, DIGIT_SIZE); + R24 = _mm512_and_epi64(R24, DIG_MASK); + _mm512_store_si512(pr + 24, R24); + + R25 = _mm512_add_epi64(R25, T); + T = _mm512_srli_epi64(R25, DIGIT_SIZE); + R25 = _mm512_and_epi64(R25, DIG_MASK); + _mm512_store_si512(pr + 25, R25); + + R26 = _mm512_add_epi64(R26, T); + T = _mm512_srli_epi64(R26, DIGIT_SIZE); + R26 = _mm512_and_epi64(R26, DIG_MASK); + _mm512_store_si512(pr + 26, R26); + + R27 = _mm512_add_epi64(R27, T); + T = _mm512_srli_epi64(R27, DIGIT_SIZE); + R27 = _mm512_and_epi64(R27, DIG_MASK); + _mm512_store_si512(pr + 27, R27); + + R28 = _mm512_add_epi64(R28, T); + T = _mm512_srli_epi64(R28, DIGIT_SIZE); + R28 = _mm512_and_epi64(R28, DIG_MASK); + _mm512_store_si512(pr + 28, R28); + + R29 = _mm512_add_epi64(R29, T); + T = _mm512_srli_epi64(R29, DIGIT_SIZE); + R29 = _mm512_and_epi64(R29, DIG_MASK); + _mm512_store_si512(pr + 29, R29); + + R30 = _mm512_add_epi64(R30, T); + T = _mm512_srli_epi64(R30, DIGIT_SIZE); + R30 = _mm512_and_epi64(R30, DIG_MASK); + _mm512_store_si512(pr + 30, R30); + + R31 = _mm512_add_epi64(R31, T); + T = _mm512_srli_epi64(R31, DIGIT_SIZE); + R31 = _mm512_and_epi64(R31, DIG_MASK); + _mm512_store_si512(pr + 31, R31); + + R32 = _mm512_add_epi64(R32, T); + T = _mm512_srli_epi64(R32, DIGIT_SIZE); + R32 = _mm512_and_epi64(R32, DIG_MASK); + _mm512_store_si512(pr + 32, R32); + + R33 = _mm512_add_epi64(R33, T); + T = _mm512_srli_epi64(R33, DIGIT_SIZE); + R33 = _mm512_and_epi64(R33, DIG_MASK); + _mm512_store_si512(pr + 33, R33); + + R34 = _mm512_add_epi64(R34, T); + T = _mm512_srli_epi64(R34, DIGIT_SIZE); + R34 = _mm512_and_epi64(R34, DIG_MASK); + _mm512_store_si512(pr + 34, R34); + + R35 = _mm512_add_epi64(R35, T); + T = _mm512_srli_epi64(R35, DIGIT_SIZE); + R35 = _mm512_and_epi64(R35, DIG_MASK); + _mm512_store_si512(pr + 35, R35); + + R36 = _mm512_add_epi64(R36, T); + T = _mm512_srli_epi64(R36, DIGIT_SIZE); + R36 = _mm512_and_epi64(R36, DIG_MASK); + _mm512_store_si512(pr + 36, R36); + + R37 = _mm512_add_epi64(R37, T); + T = _mm512_srli_epi64(R37, DIGIT_SIZE); + R37 = _mm512_and_epi64(R37, DIG_MASK); + _mm512_store_si512(pr + 37, R37); + + R38 = _mm512_add_epi64(R38, T); + T = _mm512_srli_epi64(R38, DIGIT_SIZE); + R38 = _mm512_and_epi64(R38, MS_DIG_MASK); + _mm512_store_si512(pr + 38, R38); + } + + #undef BITSIZE + #undef LEN52 + #undef MSD_MSK +} + + +/* r = x * (R^-1) mod q */ +void ifma_amred52x10_mb8(int64u res[][8], + const int64u inpA[][8], /* int nsA == 2*nsM */ + const int64u inpM[][8], /* int nsM ==10 */ + const int64u k0[8]) +{ + int64u* pA = (int64u*)inpA; + int64u* pM = (int64u*)inpM; + int64u* pR = (int64u*)res; + + __m512i K = _mm512_load_si512(k0); /* k0[] */ + + __m512i R00 = _mm512_load_si512(pA + 8 * 0); /* load A[nsM-1],...,A[0] */ + __m512i R01 = _mm512_load_si512(pA + 8 * 1); + __m512i R02 = _mm512_load_si512(pA + 8 * 2); + __m512i R03 = _mm512_load_si512(pA + 8 * 3); + __m512i R04 = _mm512_load_si512(pA + 8 * 4); + __m512i R05 = _mm512_load_si512(pA + 8 * 5); + __m512i R06 = _mm512_load_si512(pA + 8 * 6); + __m512i R07 = _mm512_load_si512(pA + 8 * 7); + __m512i R08 = _mm512_load_si512(pA + 8 * 8); + __m512i R09 = _mm512_load_si512(pA + 8 * 9); + + int itr; + for (itr = 0, pA += 8 * 10; itr < 10; itr++, pA += 8) { + __m512i Yi = _mm512_madd52lo_epu64(_mm512_setzero_si512(), R00, K); + __m512i nxtA = _mm512_load_si512(pA); + + _mm512_madd52lo_epu64_(R00, R00, Yi, pM, 64 * 0); + _mm512_madd52lo_epu64_(R01, R01, Yi, pM, 64 * 1); + _mm512_madd52lo_epu64_(R02, R02, Yi, pM, 64 * 2); + _mm512_madd52lo_epu64_(R03, R03, Yi, pM, 64 * 3); + _mm512_madd52lo_epu64_(R04, R04, Yi, pM, 64 * 4); + _mm512_madd52lo_epu64_(R05, R05, Yi, pM, 64 * 5); + _mm512_madd52lo_epu64_(R06, R06, Yi, pM, 64 * 6); + _mm512_madd52lo_epu64_(R07, R07, Yi, pM, 64 * 7); + _mm512_madd52lo_epu64_(R08, R08, Yi, pM, 64 * 8); + _mm512_madd52lo_epu64_(R09, R09, Yi, pM, 64 * 9); + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Yi, pM, 64 * 0); + _mm512_madd52hi_epu64_(R01, R02, Yi, pM, 64 * 1); + _mm512_madd52hi_epu64_(R02, R03, Yi, pM, 64 * 2); + _mm512_madd52hi_epu64_(R03, R04, Yi, pM, 64 * 3); + _mm512_madd52hi_epu64_(R04, R05, Yi, pM, 64 * 4); + _mm512_madd52hi_epu64_(R05, R06, Yi, pM, 64 * 5); + _mm512_madd52hi_epu64_(R06, R07, Yi, pM, 64 * 6); + _mm512_madd52hi_epu64_(R07, R08, Yi, pM, 64 * 7); + _mm512_madd52hi_epu64_(R08, R09, Yi, pM, 64 * 8); + _mm512_madd52hi_epu64_(R09, nxtA, Yi, pM, 64 * 9); + } + + /* normalization */ + { + __m512i MASK = _mm512_set1_epi64(DIGIT_MASK); + + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, MASK); + _mm512_store_si512(pR + 8 * 0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, MASK); + _mm512_store_si512(pR + 8 * 1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, MASK); + _mm512_store_si512(pR + 8 * 2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, MASK); + _mm512_store_si512(pR + 8 * 3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, MASK); + _mm512_store_si512(pR + 8 * 4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, MASK); + _mm512_store_si512(pR + 8 * 5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, MASK); + _mm512_store_si512(pR + 8 * 6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, MASK); + _mm512_store_si512(pR + 8 * 7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, MASK); + _mm512_store_si512(pR + 8 * 8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, MASK); + _mm512_store_si512(pR + 8 * 9, R09); + } +} + +void ifma_amred52x20_mb8(int64u res[][8], + const int64u inpA[][8], /* int nsA == 2*nsM */ + const int64u inpM[][8], /* int nsM ==20 */ + const int64u k0[8]) +{ + int64u* pA = (int64u*)inpA; + int64u* pM = (int64u*)inpM; + int64u* pR = (int64u*)res; + + __m512i K = _mm512_load_si512(k0); /* k0[] */ + + __m512i R00 = _mm512_load_si512(pA+8*0); /* load A[nsM-1],...,A[0] */ + __m512i R01 = _mm512_load_si512(pA+8*1); + __m512i R02 = _mm512_load_si512(pA+8*2); + __m512i R03 = _mm512_load_si512(pA+8*3); + __m512i R04 = _mm512_load_si512(pA+8*4); + __m512i R05 = _mm512_load_si512(pA+8*5); + __m512i R06 = _mm512_load_si512(pA+8*6); + __m512i R07 = _mm512_load_si512(pA+8*7); + __m512i R08 = _mm512_load_si512(pA+8*8); + __m512i R09 = _mm512_load_si512(pA+8*9); + __m512i R10 = _mm512_load_si512(pA+8*10); + __m512i R11 = _mm512_load_si512(pA+8*11); + __m512i R12 = _mm512_load_si512(pA+8*12); + __m512i R13 = _mm512_load_si512(pA+8*13); + __m512i R14 = _mm512_load_si512(pA+8*14); + __m512i R15 = _mm512_load_si512(pA+8*15); + __m512i R16 = _mm512_load_si512(pA+8*16); + __m512i R17 = _mm512_load_si512(pA+8*17); + __m512i R18 = _mm512_load_si512(pA+8*18); + __m512i R19 = _mm512_load_si512(pA+8*19); + + int itr; + for(itr=0, pA+=8*20; itr<20; itr++, pA+=8) { + __m512i Yi = _mm512_madd52lo_epu64(_mm512_setzero_si512(), R00, K); + __m512i nxtA = _mm512_load_si512(pA); + + _mm512_madd52lo_epu64_(R00, R00, Yi, pM, 64*0); + _mm512_madd52lo_epu64_(R01, R01, Yi, pM, 64*1); + _mm512_madd52lo_epu64_(R02, R02, Yi, pM, 64*2); + _mm512_madd52lo_epu64_(R03, R03, Yi, pM, 64*3); + _mm512_madd52lo_epu64_(R04, R04, Yi, pM, 64*4); + _mm512_madd52lo_epu64_(R05, R05, Yi, pM, 64*5); + _mm512_madd52lo_epu64_(R06, R06, Yi, pM, 64*6); + _mm512_madd52lo_epu64_(R07, R07, Yi, pM, 64*7); + _mm512_madd52lo_epu64_(R08, R08, Yi, pM, 64*8); + _mm512_madd52lo_epu64_(R09, R09, Yi, pM, 64*9); + _mm512_madd52lo_epu64_(R10, R10, Yi, pM, 64*10); + _mm512_madd52lo_epu64_(R11, R11, Yi, pM, 64*11); + _mm512_madd52lo_epu64_(R12, R12, Yi, pM, 64*12); + _mm512_madd52lo_epu64_(R13, R13, Yi, pM, 64*13); + _mm512_madd52lo_epu64_(R14, R14, Yi, pM, 64*14); + _mm512_madd52lo_epu64_(R15, R15, Yi, pM, 64*15); + _mm512_madd52lo_epu64_(R16, R16, Yi, pM, 64*16); + _mm512_madd52lo_epu64_(R17, R17, Yi, pM, 64*17); + _mm512_madd52lo_epu64_(R18, R18, Yi, pM, 64*18); + _mm512_madd52lo_epu64_(R19, R19, Yi, pM, 64*19); + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Yi, pM, 64*0); + _mm512_madd52hi_epu64_(R01, R02, Yi, pM, 64*1); + _mm512_madd52hi_epu64_(R02, R03, Yi, pM, 64*2); + _mm512_madd52hi_epu64_(R03, R04, Yi, pM, 64*3); + _mm512_madd52hi_epu64_(R04, R05, Yi, pM, 64*4); + _mm512_madd52hi_epu64_(R05, R06, Yi, pM, 64*5); + _mm512_madd52hi_epu64_(R06, R07, Yi, pM, 64*6); + _mm512_madd52hi_epu64_(R07, R08, Yi, pM, 64*7); + _mm512_madd52hi_epu64_(R08, R09, Yi, pM, 64*8); + _mm512_madd52hi_epu64_(R09, R10, Yi, pM, 64*9); + _mm512_madd52hi_epu64_(R10, R11, Yi, pM, 64*10); + _mm512_madd52hi_epu64_(R11, R12, Yi, pM, 64*11); + _mm512_madd52hi_epu64_(R12, R13, Yi, pM, 64*12); + _mm512_madd52hi_epu64_(R13, R14, Yi, pM, 64*13); + _mm512_madd52hi_epu64_(R14, R15, Yi, pM, 64*14); + _mm512_madd52hi_epu64_(R15, R16, Yi, pM, 64*15); + _mm512_madd52hi_epu64_(R16, R17, Yi, pM, 64*16); + _mm512_madd52hi_epu64_(R17, R18, Yi, pM, 64*17); + _mm512_madd52hi_epu64_(R18, R19, Yi, pM, 64*18); + _mm512_madd52hi_epu64_(R19, nxtA,Yi, pM, 64*19); + } + + /* normalization */ + { + __m512i MASK = _mm512_set1_epi64(DIGIT_MASK); + + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, MASK); + _mm512_store_si512(pR+8*0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, MASK); + _mm512_store_si512(pR+8*1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, MASK); + _mm512_store_si512(pR+8*2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, MASK); + _mm512_store_si512(pR+8*3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, MASK); + _mm512_store_si512(pR+8*4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, MASK); + _mm512_store_si512(pR+8*5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, MASK); + _mm512_store_si512(pR+8*6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, MASK); + _mm512_store_si512(pR+8*7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, MASK); + _mm512_store_si512(pR+8*8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, MASK); + _mm512_store_si512(pR+8*9, R09); + + R10 = _mm512_add_epi64(R10, T); + T = _mm512_srli_epi64(R10, DIGIT_SIZE); + R10 = _mm512_and_epi64(R10, MASK); + _mm512_store_si512(pR+8*10, R10); + + R11 = _mm512_add_epi64(R11, T); + T = _mm512_srli_epi64(R11, DIGIT_SIZE); + R11 = _mm512_and_epi64(R11, MASK); + _mm512_store_si512(pR+8*11, R11); + + R12 = _mm512_add_epi64(R12, T); + T = _mm512_srli_epi64(R12, DIGIT_SIZE); + R12 = _mm512_and_epi64(R12, MASK); + _mm512_store_si512(pR+8*12, R12); + + R13 = _mm512_add_epi64(R13, T); + T = _mm512_srli_epi64(R13, DIGIT_SIZE); + R13 = _mm512_and_epi64(R13, MASK); + _mm512_store_si512(pR+8*13, R13); + + R14 = _mm512_add_epi64(R14, T); + T = _mm512_srli_epi64(R14, DIGIT_SIZE); + R14 = _mm512_and_epi64(R14, MASK); + _mm512_store_si512(pR+8*14, R14); + + R15 = _mm512_add_epi64(R15, T); + T = _mm512_srli_epi64(R15, DIGIT_SIZE); + R15 = _mm512_and_epi64(R15, MASK); + _mm512_store_si512(pR+8*15, R15); + + R16 = _mm512_add_epi64(R16, T); + T = _mm512_srli_epi64(R16, DIGIT_SIZE); + R16 = _mm512_and_epi64(R16, MASK); + _mm512_store_si512(pR+8*16, R16); + + R17 = _mm512_add_epi64(R17, T); + T = _mm512_srli_epi64(R17, DIGIT_SIZE); + R17 = _mm512_and_epi64(R17, MASK); + _mm512_store_si512(pR+8*17, R17); + + R18 = _mm512_add_epi64(R18, T); + T = _mm512_srli_epi64(R18, DIGIT_SIZE); + R18 = _mm512_and_epi64(R18, MASK); + _mm512_store_si512(pR+8*18, R18); + + R19 = _mm512_add_epi64(R19, T); + T = _mm512_srli_epi64(R19, DIGIT_SIZE); + R19 = _mm512_and_epi64(R19, MASK); + _mm512_store_si512(pR+8*19, R19); + } +} + +void ifma_amred52x30_mb8(int64u res[][8], + const int64u inpA[][8], /* int nsA == 2*nsM */ + const int64u inpM[][8], /* int nsM ==20 */ + const int64u k0[8]) +{ + int64u* pA = (int64u*)inpA; + int64u* pM = (int64u*)inpM; + int64u* pR = (int64u*)res; + + __m512i K = _mm512_load_si512(k0); /* k0[] */ + + __m512i R00 = _mm512_load_si512(pA + 8 * 0); /* load A[nsM-1],...,A[0] */ + __m512i R01 = _mm512_load_si512(pA + 8 * 1); + __m512i R02 = _mm512_load_si512(pA + 8 * 2); + __m512i R03 = _mm512_load_si512(pA + 8 * 3); + __m512i R04 = _mm512_load_si512(pA + 8 * 4); + __m512i R05 = _mm512_load_si512(pA + 8 * 5); + __m512i R06 = _mm512_load_si512(pA + 8 * 6); + __m512i R07 = _mm512_load_si512(pA + 8 * 7); + __m512i R08 = _mm512_load_si512(pA + 8 * 8); + __m512i R09 = _mm512_load_si512(pA + 8 * 9); + __m512i R10 = _mm512_load_si512(pA + 8 * 10); + __m512i R11 = _mm512_load_si512(pA + 8 * 11); + __m512i R12 = _mm512_load_si512(pA + 8 * 12); + __m512i R13 = _mm512_load_si512(pA + 8 * 13); + __m512i R14 = _mm512_load_si512(pA + 8 * 14); + __m512i R15 = _mm512_load_si512(pA + 8 * 15); + __m512i R16 = _mm512_load_si512(pA + 8 * 16); + __m512i R17 = _mm512_load_si512(pA + 8 * 17); + __m512i R18 = _mm512_load_si512(pA + 8 * 18); + __m512i R19 = _mm512_load_si512(pA + 8 * 19); + __m512i R20 = _mm512_load_si512(pA + 8 * 20); + __m512i R21 = _mm512_load_si512(pA + 8 * 21); + __m512i R22 = _mm512_load_si512(pA + 8 * 22); + __m512i R23 = _mm512_load_si512(pA + 8 * 23); + __m512i R24 = _mm512_load_si512(pA + 8 * 24); + __m512i R25 = _mm512_load_si512(pA + 8 * 25); + __m512i R26 = _mm512_load_si512(pA + 8 * 26); + __m512i R27 = _mm512_load_si512(pA + 8 * 27); + __m512i R28 = _mm512_load_si512(pA + 8 * 28); + __m512i R29 = _mm512_load_si512(pA + 8 * 29); + + int itr; + for (itr = 0, pA += 8 * 30; itr < 30; itr++, pA += 8) { + __m512i Yi = _mm512_madd52lo_epu64(_mm512_setzero_si512(), R00, K); + __m512i nxtA = _mm512_load_si512(pA); + + _mm512_madd52lo_epu64_(R00, R00, Yi, pM, 64 * 0); + _mm512_madd52lo_epu64_(R01, R01, Yi, pM, 64 * 1); + _mm512_madd52lo_epu64_(R02, R02, Yi, pM, 64 * 2); + _mm512_madd52lo_epu64_(R03, R03, Yi, pM, 64 * 3); + _mm512_madd52lo_epu64_(R04, R04, Yi, pM, 64 * 4); + _mm512_madd52lo_epu64_(R05, R05, Yi, pM, 64 * 5); + _mm512_madd52lo_epu64_(R06, R06, Yi, pM, 64 * 6); + _mm512_madd52lo_epu64_(R07, R07, Yi, pM, 64 * 7); + _mm512_madd52lo_epu64_(R08, R08, Yi, pM, 64 * 8); + _mm512_madd52lo_epu64_(R09, R09, Yi, pM, 64 * 9); + _mm512_madd52lo_epu64_(R10, R10, Yi, pM, 64 * 10); + _mm512_madd52lo_epu64_(R11, R11, Yi, pM, 64 * 11); + _mm512_madd52lo_epu64_(R12, R12, Yi, pM, 64 * 12); + _mm512_madd52lo_epu64_(R13, R13, Yi, pM, 64 * 13); + _mm512_madd52lo_epu64_(R14, R14, Yi, pM, 64 * 14); + _mm512_madd52lo_epu64_(R15, R15, Yi, pM, 64 * 15); + _mm512_madd52lo_epu64_(R16, R16, Yi, pM, 64 * 16); + _mm512_madd52lo_epu64_(R17, R17, Yi, pM, 64 * 17); + _mm512_madd52lo_epu64_(R18, R18, Yi, pM, 64 * 18); + _mm512_madd52lo_epu64_(R19, R19, Yi, pM, 64 * 19); + _mm512_madd52lo_epu64_(R20, R20, Yi, pM, 64 * 20); + _mm512_madd52lo_epu64_(R21, R21, Yi, pM, 64 * 21); + _mm512_madd52lo_epu64_(R22, R22, Yi, pM, 64 * 22); + _mm512_madd52lo_epu64_(R23, R23, Yi, pM, 64 * 23); + _mm512_madd52lo_epu64_(R24, R24, Yi, pM, 64 * 24); + _mm512_madd52lo_epu64_(R25, R25, Yi, pM, 64 * 25); + _mm512_madd52lo_epu64_(R26, R26, Yi, pM, 64 * 26); + _mm512_madd52lo_epu64_(R27, R27, Yi, pM, 64 * 27); + _mm512_madd52lo_epu64_(R28, R28, Yi, pM, 64 * 28); + _mm512_madd52lo_epu64_(R29, R29, Yi, pM, 64 * 29); + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Yi, pM, 64 * 0); + _mm512_madd52hi_epu64_(R01, R02, Yi, pM, 64 * 1); + _mm512_madd52hi_epu64_(R02, R03, Yi, pM, 64 * 2); + _mm512_madd52hi_epu64_(R03, R04, Yi, pM, 64 * 3); + _mm512_madd52hi_epu64_(R04, R05, Yi, pM, 64 * 4); + _mm512_madd52hi_epu64_(R05, R06, Yi, pM, 64 * 5); + _mm512_madd52hi_epu64_(R06, R07, Yi, pM, 64 * 6); + _mm512_madd52hi_epu64_(R07, R08, Yi, pM, 64 * 7); + _mm512_madd52hi_epu64_(R08, R09, Yi, pM, 64 * 8); + _mm512_madd52hi_epu64_(R09, R10, Yi, pM, 64 * 9); + _mm512_madd52hi_epu64_(R10, R11, Yi, pM, 64 * 10); + _mm512_madd52hi_epu64_(R11, R12, Yi, pM, 64 * 11); + _mm512_madd52hi_epu64_(R12, R13, Yi, pM, 64 * 12); + _mm512_madd52hi_epu64_(R13, R14, Yi, pM, 64 * 13); + _mm512_madd52hi_epu64_(R14, R15, Yi, pM, 64 * 14); + _mm512_madd52hi_epu64_(R15, R16, Yi, pM, 64 * 15); + _mm512_madd52hi_epu64_(R16, R17, Yi, pM, 64 * 16); + _mm512_madd52hi_epu64_(R17, R18, Yi, pM, 64 * 17); + _mm512_madd52hi_epu64_(R18, R19, Yi, pM, 64 * 18); + _mm512_madd52hi_epu64_(R19, R20, Yi, pM, 64 * 19); + _mm512_madd52hi_epu64_(R20, R21, Yi, pM, 64 * 20); + _mm512_madd52hi_epu64_(R21, R22, Yi, pM, 64 * 21); + _mm512_madd52hi_epu64_(R22, R23, Yi, pM, 64 * 22); + _mm512_madd52hi_epu64_(R23, R24, Yi, pM, 64 * 23); + _mm512_madd52hi_epu64_(R24, R25, Yi, pM, 64 * 24); + _mm512_madd52hi_epu64_(R25, R26, Yi, pM, 64 * 25); + _mm512_madd52hi_epu64_(R26, R27, Yi, pM, 64 * 26); + _mm512_madd52hi_epu64_(R27, R28, Yi, pM, 64 * 27); + _mm512_madd52hi_epu64_(R28, R29, Yi, pM, 64 * 28); + _mm512_madd52hi_epu64_(R29, nxtA, Yi, pM, 64 * 29); + } + + /* normalization */ + { + __m512i MASK = _mm512_set1_epi64(DIGIT_MASK); + + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, MASK); + _mm512_store_si512(pR + 8 * 0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, MASK); + _mm512_store_si512(pR + 8 * 1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, MASK); + _mm512_store_si512(pR + 8 * 2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, MASK); + _mm512_store_si512(pR + 8 * 3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, MASK); + _mm512_store_si512(pR + 8 * 4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, MASK); + _mm512_store_si512(pR + 8 * 5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, MASK); + _mm512_store_si512(pR + 8 * 6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, MASK); + _mm512_store_si512(pR + 8 * 7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, MASK); + _mm512_store_si512(pR + 8 * 8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, MASK); + _mm512_store_si512(pR + 8 * 9, R09); + + R10 = _mm512_add_epi64(R10, T); + T = _mm512_srli_epi64(R10, DIGIT_SIZE); + R10 = _mm512_and_epi64(R10, MASK); + _mm512_store_si512(pR + 8 * 10, R10); + + R11 = _mm512_add_epi64(R11, T); + T = _mm512_srli_epi64(R11, DIGIT_SIZE); + R11 = _mm512_and_epi64(R11, MASK); + _mm512_store_si512(pR + 8 * 11, R11); + + R12 = _mm512_add_epi64(R12, T); + T = _mm512_srli_epi64(R12, DIGIT_SIZE); + R12 = _mm512_and_epi64(R12, MASK); + _mm512_store_si512(pR + 8 * 12, R12); + + R13 = _mm512_add_epi64(R13, T); + T = _mm512_srli_epi64(R13, DIGIT_SIZE); + R13 = _mm512_and_epi64(R13, MASK); + _mm512_store_si512(pR + 8 * 13, R13); + + R14 = _mm512_add_epi64(R14, T); + T = _mm512_srli_epi64(R14, DIGIT_SIZE); + R14 = _mm512_and_epi64(R14, MASK); + _mm512_store_si512(pR + 8 * 14, R14); + + R15 = _mm512_add_epi64(R15, T); + T = _mm512_srli_epi64(R15, DIGIT_SIZE); + R15 = _mm512_and_epi64(R15, MASK); + _mm512_store_si512(pR + 8 * 15, R15); + + R16 = _mm512_add_epi64(R16, T); + T = _mm512_srli_epi64(R16, DIGIT_SIZE); + R16 = _mm512_and_epi64(R16, MASK); + _mm512_store_si512(pR + 8 * 16, R16); + + R17 = _mm512_add_epi64(R17, T); + T = _mm512_srli_epi64(R17, DIGIT_SIZE); + R17 = _mm512_and_epi64(R17, MASK); + _mm512_store_si512(pR + 8 * 17, R17); + + R18 = _mm512_add_epi64(R18, T); + T = _mm512_srli_epi64(R18, DIGIT_SIZE); + R18 = _mm512_and_epi64(R18, MASK); + _mm512_store_si512(pR + 8 * 18, R18); + + R19 = _mm512_add_epi64(R19, T); + T = _mm512_srli_epi64(R19, DIGIT_SIZE); + R19 = _mm512_and_epi64(R19, MASK); + _mm512_store_si512(pR + 8 * 19, R19); + + R20 = _mm512_add_epi64(R20, T); + T = _mm512_srli_epi64(R20, DIGIT_SIZE); + R20 = _mm512_and_epi64(R20, MASK); + _mm512_store_si512(pR + 8 * 20, R20); + + R21 = _mm512_add_epi64(R21, T); + T = _mm512_srli_epi64(R21, DIGIT_SIZE); + R21 = _mm512_and_epi64(R21, MASK); + _mm512_store_si512(pR + 8 * 21, R21); + + R22 = _mm512_add_epi64(R22, T); + T = _mm512_srli_epi64(R22, DIGIT_SIZE); + R22 = _mm512_and_epi64(R22, MASK); + _mm512_store_si512(pR + 8 * 22, R22); + + R23 = _mm512_add_epi64(R23, T); + T = _mm512_srli_epi64(R23, DIGIT_SIZE); + R23 = _mm512_and_epi64(R23, MASK); + _mm512_store_si512(pR + 8 * 23, R23); + + R24 = _mm512_add_epi64(R24, T); + T = _mm512_srli_epi64(R24, DIGIT_SIZE); + R24 = _mm512_and_epi64(R24, MASK); + _mm512_store_si512(pR + 8 * 24, R24); + + R25 = _mm512_add_epi64(R25, T); + T = _mm512_srli_epi64(R25, DIGIT_SIZE); + R25 = _mm512_and_epi64(R25, MASK); + _mm512_store_si512(pR + 8 * 25, R25); + + R26 = _mm512_add_epi64(R26, T); + T = _mm512_srli_epi64(R26, DIGIT_SIZE); + R26 = _mm512_and_epi64(R26, MASK); + _mm512_store_si512(pR + 8 * 26, R26); + + R27 = _mm512_add_epi64(R27, T); + T = _mm512_srli_epi64(R27, DIGIT_SIZE); + R27 = _mm512_and_epi64(R27, MASK); + _mm512_store_si512(pR + 8 * 27, R27); + + R28 = _mm512_add_epi64(R28, T); + T = _mm512_srli_epi64(R28, DIGIT_SIZE); + R28 = _mm512_and_epi64(R28, MASK); + _mm512_store_si512(pR + 8 * 28, R28); + + R29 = _mm512_add_epi64(R29, T); + T = _mm512_srli_epi64(R29, DIGIT_SIZE); + R29 = _mm512_and_epi64(R29, MASK); + _mm512_store_si512(pR + 8 * 29, R29); + } +} + +void ifma_amred52x40_mb8(int64u res[][8], + const int64u inpA[][8], /* int nsA == 2*nsM */ + const int64u inpM[][8], /* int nsM ==20 */ + const int64u k0[8]) +{ + int64u* pA = (int64u*)inpA; + int64u* pM = (int64u*)inpM; + int64u* pR = (int64u*)res; + + __m512i K = _mm512_load_si512(k0); /* k0[] */ + + __m512i R00 = _mm512_load_si512(pA + 8 * 0); /* load A[nsM-1],...,A[0] */ + __m512i R01 = _mm512_load_si512(pA + 8 * 1); + __m512i R02 = _mm512_load_si512(pA + 8 * 2); + __m512i R03 = _mm512_load_si512(pA + 8 * 3); + __m512i R04 = _mm512_load_si512(pA + 8 * 4); + __m512i R05 = _mm512_load_si512(pA + 8 * 5); + __m512i R06 = _mm512_load_si512(pA + 8 * 6); + __m512i R07 = _mm512_load_si512(pA + 8 * 7); + __m512i R08 = _mm512_load_si512(pA + 8 * 8); + __m512i R09 = _mm512_load_si512(pA + 8 * 9); + __m512i R10 = _mm512_load_si512(pA + 8 * 10); + __m512i R11 = _mm512_load_si512(pA + 8 * 11); + __m512i R12 = _mm512_load_si512(pA + 8 * 12); + __m512i R13 = _mm512_load_si512(pA + 8 * 13); + __m512i R14 = _mm512_load_si512(pA + 8 * 14); + __m512i R15 = _mm512_load_si512(pA + 8 * 15); + __m512i R16 = _mm512_load_si512(pA + 8 * 16); + __m512i R17 = _mm512_load_si512(pA + 8 * 17); + __m512i R18 = _mm512_load_si512(pA + 8 * 18); + __m512i R19 = _mm512_load_si512(pA + 8 * 19); + __m512i R20 = _mm512_load_si512(pA + 8 * 20); + __m512i R21 = _mm512_load_si512(pA + 8 * 21); + __m512i R22 = _mm512_load_si512(pA + 8 * 22); + __m512i R23 = _mm512_load_si512(pA + 8 * 23); + __m512i R24 = _mm512_load_si512(pA + 8 * 24); + __m512i R25 = _mm512_load_si512(pA + 8 * 25); + __m512i R26 = _mm512_load_si512(pA + 8 * 26); + __m512i R27 = _mm512_load_si512(pA + 8 * 27); + __m512i R28 = _mm512_load_si512(pA + 8 * 28); + __m512i R29 = _mm512_load_si512(pA + 8 * 29); + __m512i R30 = _mm512_load_si512(pA + 8 * 30); + __m512i R31 = _mm512_load_si512(pA + 8 * 31); + __m512i R32 = _mm512_load_si512(pA + 8 * 32); + __m512i R33 = _mm512_load_si512(pA + 8 * 33); + __m512i R34 = _mm512_load_si512(pA + 8 * 34); + __m512i R35 = _mm512_load_si512(pA + 8 * 35); + __m512i R36 = _mm512_load_si512(pA + 8 * 36); + __m512i R37 = _mm512_load_si512(pA + 8 * 37); + __m512i R38 = _mm512_load_si512(pA + 8 * 38); + __m512i R39 = _mm512_load_si512(pA + 8 * 39); + + int itr; + for (itr = 0, pA += 8 * 40; itr < 40; itr++, pA += 8) { + __m512i Yi = _mm512_madd52lo_epu64(_mm512_setzero_si512(), R00, K); + __m512i nxtA = _mm512_load_si512(pA); + + _mm512_madd52lo_epu64_(R00, R00, Yi, pM, 64 * 0); + _mm512_madd52lo_epu64_(R01, R01, Yi, pM, 64 * 1); + _mm512_madd52lo_epu64_(R02, R02, Yi, pM, 64 * 2); + _mm512_madd52lo_epu64_(R03, R03, Yi, pM, 64 * 3); + _mm512_madd52lo_epu64_(R04, R04, Yi, pM, 64 * 4); + _mm512_madd52lo_epu64_(R05, R05, Yi, pM, 64 * 5); + _mm512_madd52lo_epu64_(R06, R06, Yi, pM, 64 * 6); + _mm512_madd52lo_epu64_(R07, R07, Yi, pM, 64 * 7); + _mm512_madd52lo_epu64_(R08, R08, Yi, pM, 64 * 8); + _mm512_madd52lo_epu64_(R09, R09, Yi, pM, 64 * 9); + _mm512_madd52lo_epu64_(R10, R10, Yi, pM, 64 * 10); + _mm512_madd52lo_epu64_(R11, R11, Yi, pM, 64 * 11); + _mm512_madd52lo_epu64_(R12, R12, Yi, pM, 64 * 12); + _mm512_madd52lo_epu64_(R13, R13, Yi, pM, 64 * 13); + _mm512_madd52lo_epu64_(R14, R14, Yi, pM, 64 * 14); + _mm512_madd52lo_epu64_(R15, R15, Yi, pM, 64 * 15); + _mm512_madd52lo_epu64_(R16, R16, Yi, pM, 64 * 16); + _mm512_madd52lo_epu64_(R17, R17, Yi, pM, 64 * 17); + _mm512_madd52lo_epu64_(R18, R18, Yi, pM, 64 * 18); + _mm512_madd52lo_epu64_(R19, R19, Yi, pM, 64 * 19); + _mm512_madd52lo_epu64_(R20, R20, Yi, pM, 64 * 20); + _mm512_madd52lo_epu64_(R21, R21, Yi, pM, 64 * 21); + _mm512_madd52lo_epu64_(R22, R22, Yi, pM, 64 * 22); + _mm512_madd52lo_epu64_(R23, R23, Yi, pM, 64 * 23); + _mm512_madd52lo_epu64_(R24, R24, Yi, pM, 64 * 24); + _mm512_madd52lo_epu64_(R25, R25, Yi, pM, 64 * 25); + _mm512_madd52lo_epu64_(R26, R26, Yi, pM, 64 * 26); + _mm512_madd52lo_epu64_(R27, R27, Yi, pM, 64 * 27); + _mm512_madd52lo_epu64_(R28, R28, Yi, pM, 64 * 28); + _mm512_madd52lo_epu64_(R29, R29, Yi, pM, 64 * 29); + _mm512_madd52lo_epu64_(R30, R30, Yi, pM, 64 * 30); + _mm512_madd52lo_epu64_(R31, R31, Yi, pM, 64 * 31); + _mm512_madd52lo_epu64_(R32, R32, Yi, pM, 64 * 32); + _mm512_madd52lo_epu64_(R33, R33, Yi, pM, 64 * 33); + _mm512_madd52lo_epu64_(R34, R34, Yi, pM, 64 * 34); + _mm512_madd52lo_epu64_(R35, R35, Yi, pM, 64 * 35); + _mm512_madd52lo_epu64_(R36, R36, Yi, pM, 64 * 36); + _mm512_madd52lo_epu64_(R37, R37, Yi, pM, 64 * 37); + _mm512_madd52lo_epu64_(R38, R38, Yi, pM, 64 * 38); + _mm512_madd52lo_epu64_(R39, R39, Yi, pM, 64 * 39); + + R00 = _mm512_srli_epi64(R00, DIGIT_SIZE); + R01 = _mm512_add_epi64(R01, R00); + + _mm512_madd52hi_epu64_(R00, R01, Yi, pM, 64 * 0); + _mm512_madd52hi_epu64_(R01, R02, Yi, pM, 64 * 1); + _mm512_madd52hi_epu64_(R02, R03, Yi, pM, 64 * 2); + _mm512_madd52hi_epu64_(R03, R04, Yi, pM, 64 * 3); + _mm512_madd52hi_epu64_(R04, R05, Yi, pM, 64 * 4); + _mm512_madd52hi_epu64_(R05, R06, Yi, pM, 64 * 5); + _mm512_madd52hi_epu64_(R06, R07, Yi, pM, 64 * 6); + _mm512_madd52hi_epu64_(R07, R08, Yi, pM, 64 * 7); + _mm512_madd52hi_epu64_(R08, R09, Yi, pM, 64 * 8); + _mm512_madd52hi_epu64_(R09, R10, Yi, pM, 64 * 9); + _mm512_madd52hi_epu64_(R10, R11, Yi, pM, 64 * 10); + _mm512_madd52hi_epu64_(R11, R12, Yi, pM, 64 * 11); + _mm512_madd52hi_epu64_(R12, R13, Yi, pM, 64 * 12); + _mm512_madd52hi_epu64_(R13, R14, Yi, pM, 64 * 13); + _mm512_madd52hi_epu64_(R14, R15, Yi, pM, 64 * 14); + _mm512_madd52hi_epu64_(R15, R16, Yi, pM, 64 * 15); + _mm512_madd52hi_epu64_(R16, R17, Yi, pM, 64 * 16); + _mm512_madd52hi_epu64_(R17, R18, Yi, pM, 64 * 17); + _mm512_madd52hi_epu64_(R18, R19, Yi, pM, 64 * 18); + _mm512_madd52hi_epu64_(R19, R20, Yi, pM, 64 * 19); + _mm512_madd52hi_epu64_(R20, R21, Yi, pM, 64 * 20); + _mm512_madd52hi_epu64_(R21, R22, Yi, pM, 64 * 21); + _mm512_madd52hi_epu64_(R22, R23, Yi, pM, 64 * 22); + _mm512_madd52hi_epu64_(R23, R24, Yi, pM, 64 * 23); + _mm512_madd52hi_epu64_(R24, R25, Yi, pM, 64 * 24); + _mm512_madd52hi_epu64_(R25, R26, Yi, pM, 64 * 25); + _mm512_madd52hi_epu64_(R26, R27, Yi, pM, 64 * 26); + _mm512_madd52hi_epu64_(R27, R28, Yi, pM, 64 * 27); + _mm512_madd52hi_epu64_(R28, R29, Yi, pM, 64 * 28); + _mm512_madd52hi_epu64_(R29, R30, Yi, pM, 64 * 29); + _mm512_madd52hi_epu64_(R30, R31, Yi, pM, 64 * 30); + _mm512_madd52hi_epu64_(R31, R32, Yi, pM, 64 * 31); + _mm512_madd52hi_epu64_(R32, R33, Yi, pM, 64 * 32); + _mm512_madd52hi_epu64_(R33, R34, Yi, pM, 64 * 33); + _mm512_madd52hi_epu64_(R34, R35, Yi, pM, 64 * 34); + _mm512_madd52hi_epu64_(R35, R36, Yi, pM, 64 * 35); + _mm512_madd52hi_epu64_(R36, R37, Yi, pM, 64 * 36); + _mm512_madd52hi_epu64_(R37, R38, Yi, pM, 64 * 37); + _mm512_madd52hi_epu64_(R38, R39, Yi, pM, 64 * 38); + _mm512_madd52hi_epu64_(R39, nxtA, Yi, pM, 64 * 39); + } + + /* normalization */ + { + __m512i MASK = _mm512_set1_epi64(DIGIT_MASK); + + __m512i + T = _mm512_srli_epi64(R00, DIGIT_SIZE); + R00 = _mm512_and_epi64(R00, MASK); + _mm512_store_si512(pR + 8 * 0, R00); + + R01 = _mm512_add_epi64(R01, T); + T = _mm512_srli_epi64(R01, DIGIT_SIZE); + R01 = _mm512_and_epi64(R01, MASK); + _mm512_store_si512(pR + 8 * 1, R01); + + R02 = _mm512_add_epi64(R02, T); + T = _mm512_srli_epi64(R02, DIGIT_SIZE); + R02 = _mm512_and_epi64(R02, MASK); + _mm512_store_si512(pR + 8 * 2, R02); + + R03 = _mm512_add_epi64(R03, T); + T = _mm512_srli_epi64(R03, DIGIT_SIZE); + R03 = _mm512_and_epi64(R03, MASK); + _mm512_store_si512(pR + 8 * 3, R03); + + R04 = _mm512_add_epi64(R04, T); + T = _mm512_srli_epi64(R04, DIGIT_SIZE); + R04 = _mm512_and_epi64(R04, MASK); + _mm512_store_si512(pR + 8 * 4, R04); + + R05 = _mm512_add_epi64(R05, T); + T = _mm512_srli_epi64(R05, DIGIT_SIZE); + R05 = _mm512_and_epi64(R05, MASK); + _mm512_store_si512(pR + 8 * 5, R05); + + R06 = _mm512_add_epi64(R06, T); + T = _mm512_srli_epi64(R06, DIGIT_SIZE); + R06 = _mm512_and_epi64(R06, MASK); + _mm512_store_si512(pR + 8 * 6, R06); + + R07 = _mm512_add_epi64(R07, T); + T = _mm512_srli_epi64(R07, DIGIT_SIZE); + R07 = _mm512_and_epi64(R07, MASK); + _mm512_store_si512(pR + 8 * 7, R07); + + R08 = _mm512_add_epi64(R08, T); + T = _mm512_srli_epi64(R08, DIGIT_SIZE); + R08 = _mm512_and_epi64(R08, MASK); + _mm512_store_si512(pR + 8 * 8, R08); + + R09 = _mm512_add_epi64(R09, T); + T = _mm512_srli_epi64(R09, DIGIT_SIZE); + R09 = _mm512_and_epi64(R09, MASK); + _mm512_store_si512(pR + 8 * 9, R09); + + R10 = _mm512_add_epi64(R10, T); + T = _mm512_srli_epi64(R10, DIGIT_SIZE); + R10 = _mm512_and_epi64(R10, MASK); + _mm512_store_si512(pR + 8 * 10, R10); + + R11 = _mm512_add_epi64(R11, T); + T = _mm512_srli_epi64(R11, DIGIT_SIZE); + R11 = _mm512_and_epi64(R11, MASK); + _mm512_store_si512(pR + 8 * 11, R11); + + R12 = _mm512_add_epi64(R12, T); + T = _mm512_srli_epi64(R12, DIGIT_SIZE); + R12 = _mm512_and_epi64(R12, MASK); + _mm512_store_si512(pR + 8 * 12, R12); + + R13 = _mm512_add_epi64(R13, T); + T = _mm512_srli_epi64(R13, DIGIT_SIZE); + R13 = _mm512_and_epi64(R13, MASK); + _mm512_store_si512(pR + 8 * 13, R13); + + R14 = _mm512_add_epi64(R14, T); + T = _mm512_srli_epi64(R14, DIGIT_SIZE); + R14 = _mm512_and_epi64(R14, MASK); + _mm512_store_si512(pR + 8 * 14, R14); + + R15 = _mm512_add_epi64(R15, T); + T = _mm512_srli_epi64(R15, DIGIT_SIZE); + R15 = _mm512_and_epi64(R15, MASK); + _mm512_store_si512(pR + 8 * 15, R15); + + R16 = _mm512_add_epi64(R16, T); + T = _mm512_srli_epi64(R16, DIGIT_SIZE); + R16 = _mm512_and_epi64(R16, MASK); + _mm512_store_si512(pR + 8 * 16, R16); + + R17 = _mm512_add_epi64(R17, T); + T = _mm512_srli_epi64(R17, DIGIT_SIZE); + R17 = _mm512_and_epi64(R17, MASK); + _mm512_store_si512(pR + 8 * 17, R17); + + R18 = _mm512_add_epi64(R18, T); + T = _mm512_srli_epi64(R18, DIGIT_SIZE); + R18 = _mm512_and_epi64(R18, MASK); + _mm512_store_si512(pR + 8 * 18, R18); + + R19 = _mm512_add_epi64(R19, T); + T = _mm512_srli_epi64(R19, DIGIT_SIZE); + R19 = _mm512_and_epi64(R19, MASK); + _mm512_store_si512(pR + 8 * 19, R19); + + R20 = _mm512_add_epi64(R20, T); + T = _mm512_srli_epi64(R20, DIGIT_SIZE); + R20 = _mm512_and_epi64(R20, MASK); + _mm512_store_si512(pR + 8 * 20, R20); + + R21 = _mm512_add_epi64(R21, T); + T = _mm512_srli_epi64(R21, DIGIT_SIZE); + R21 = _mm512_and_epi64(R21, MASK); + _mm512_store_si512(pR + 8 * 21, R21); + + R22 = _mm512_add_epi64(R22, T); + T = _mm512_srli_epi64(R22, DIGIT_SIZE); + R22 = _mm512_and_epi64(R22, MASK); + _mm512_store_si512(pR + 8 * 22, R22); + + R23 = _mm512_add_epi64(R23, T); + T = _mm512_srli_epi64(R23, DIGIT_SIZE); + R23 = _mm512_and_epi64(R23, MASK); + _mm512_store_si512(pR + 8 * 23, R23); + + R24 = _mm512_add_epi64(R24, T); + T = _mm512_srli_epi64(R24, DIGIT_SIZE); + R24 = _mm512_and_epi64(R24, MASK); + _mm512_store_si512(pR + 8 * 24, R24); + + R25 = _mm512_add_epi64(R25, T); + T = _mm512_srli_epi64(R25, DIGIT_SIZE); + R25 = _mm512_and_epi64(R25, MASK); + _mm512_store_si512(pR + 8 * 25, R25); + + R26 = _mm512_add_epi64(R26, T); + T = _mm512_srli_epi64(R26, DIGIT_SIZE); + R26 = _mm512_and_epi64(R26, MASK); + _mm512_store_si512(pR + 8 * 26, R26); + + R27 = _mm512_add_epi64(R27, T); + T = _mm512_srli_epi64(R27, DIGIT_SIZE); + R27 = _mm512_and_epi64(R27, MASK); + _mm512_store_si512(pR + 8 * 27, R27); + + R28 = _mm512_add_epi64(R28, T); + T = _mm512_srli_epi64(R28, DIGIT_SIZE); + R28 = _mm512_and_epi64(R28, MASK); + _mm512_store_si512(pR + 8 * 28, R28); + + R29 = _mm512_add_epi64(R29, T); + T = _mm512_srli_epi64(R29, DIGIT_SIZE); + R29 = _mm512_and_epi64(R29, MASK); + _mm512_store_si512(pR + 8 * 29, R29); + + R30 = _mm512_add_epi64(R30, T); + T = _mm512_srli_epi64(R30, DIGIT_SIZE); + R30 = _mm512_and_epi64(R30, MASK); + _mm512_store_si512(pR + 8 * 30, R30); + + R31 = _mm512_add_epi64(R31, T); + T = _mm512_srli_epi64(R31, DIGIT_SIZE); + R31 = _mm512_and_epi64(R31, MASK); + _mm512_store_si512(pR + 8 * 31, R31); + + R32 = _mm512_add_epi64(R32, T); + T = _mm512_srli_epi64(R32, DIGIT_SIZE); + R32 = _mm512_and_epi64(R32, MASK); + _mm512_store_si512(pR + 8 * 32, R32); + + R33 = _mm512_add_epi64(R33, T); + T = _mm512_srli_epi64(R33, DIGIT_SIZE); + R33 = _mm512_and_epi64(R33, MASK); + _mm512_store_si512(pR + 8 * 33, R33); + + R34 = _mm512_add_epi64(R34, T); + T = _mm512_srli_epi64(R34, DIGIT_SIZE); + R34 = _mm512_and_epi64(R34, MASK); + _mm512_store_si512(pR + 8 * 34, R34); + + R35 = _mm512_add_epi64(R35, T); + T = _mm512_srli_epi64(R35, DIGIT_SIZE); + R35 = _mm512_and_epi64(R35, MASK); + _mm512_store_si512(pR + 8 * 35, R35); + + R36 = _mm512_add_epi64(R36, T); + T = _mm512_srli_epi64(R36, DIGIT_SIZE); + R36 = _mm512_and_epi64(R36, MASK); + _mm512_store_si512(pR + 8 * 36, R36); + + R37 = _mm512_add_epi64(R37, T); + T = _mm512_srli_epi64(R37, DIGIT_SIZE); + R37 = _mm512_and_epi64(R37, MASK); + _mm512_store_si512(pR + 8 * 37, R37); + + R38 = _mm512_add_epi64(R38, T); + T = _mm512_srli_epi64(R38, DIGIT_SIZE); + R38 = _mm512_and_epi64(R38, MASK); + _mm512_store_si512(pR + 8 * 38, R38); + + R39 = _mm512_add_epi64(R39, T); + T = _mm512_srli_epi64(R39, DIGIT_SIZE); + R39 = _mm512_and_epi64(R39, MASK); + _mm512_store_si512(pR + 8 * 39, R39); + } +} +////////////////////////////////////////////////////////////////////// + +/* +// out[] = inp[] <>nbit */ +static void rshift52x_mb8(int64u pOut[][8], int64u pInp[][8], int ns, __m512i sbiR) +{ + __m512i sbiL = _mm512_sub_epi64(_mm512_set1_epi64(DIGIT_SIZE), sbiR); + __m512i digMask = _mm512_set1_epi64(DIGIT_MASK); + + __m512i shiftedL = _mm512_setzero_si512(); + int n; + for(n=ns; n>0; n--) { + __m512i inp = _mm512_load_si512(pInp[n-1]); + __m512i out = _mm512_and_si512(_mm512_or_si512(shiftedL, _mm512_srlv_epi64(inp,sbiR)), digMask); + _mm512_store_si512(pOut[n-1], out); + shiftedL = _mm512_sllv_epi64(inp, sbiL); + } +} + +/* +// believe the following works: +// +// right = {r1:r0} - high and low +// left = {l1:l0} - high and low +// +// if(r1!=l1) +// return r1>l1; +// else +// return r0>l0; +*/ +static __mmask8 left_gt_right_mb8(__m512i left_hi, __m512i left_lo, __m512i right_hi, __m512i right_lo) +{ + __mmask8 k0 = _mm512_cmpneq_epi64_mask(left_hi, right_hi); + __mmask8 k1 = ( k0 & _mm512_cmpgt_epu64_mask(left_hi, right_hi)) + | (~k0 & _mm512_cmpgt_epu64_mask(left_lo, right_lo)); + return k1; +} + +__m512i tz; + +/* sub multiplied_by_digit +// maskk8 reports whether addition performed inside +*/ +static __mmask8 ifma_sub_muldig52x_mb8(__m512i* pRes, const __m512i* pM, int nsM, __m512i dig) +{ + __m512i MASK = _mm512_set1_epi64(DIGIT_MASK); + + __m512i prodLO = _mm512_setzero_si512(); + __m512i prodHI = _mm512_setzero_si512(); + __m512i cf = _mm512_setzero_si512(); + __m512i T; + __mmask8 k1; + + int n; + + /* multiply dig*pM[] and sub from pRes[] */ + for(n=0; n pair of digits {r:x2} + + // k1 = left>right + k1 = left_gt_right_mb8(left_hi, left_lo, rem, x2); + + // if(left>right) + quo = _mm512_mask_sub_epi64(quo, k1, quo, one); // quo -= 1 + rem = _mm512_mask_add_epi64(rem, k1, rem, y0); // rem += y0 , note "right" increased at the same time + + k0 = _mm512_mask_cmpgt_epu64_mask(k1, y1, left_lo); // k0 = left_lo < y1 + left_lo = _mm512_mask_sub_epi64(left_lo, k1, left_lo, y1); // left -= y1 + left_hi = _mm512_mask_sub_epi64(left_hi, (k1&k0), left_hi, one); + + // k0 = rem < B + k0 = _mm512_cmplt_epu64_mask(rem, base52); + // k1 = left>right + k1 = k0 & left_gt_right_mb8(left_hi, left_lo, rem, x2); + + quo = _mm512_mask_sub_epi64(quo, k1, quo, one); // quo -= 1 + + return quo; +} + +/* x = x % m */ +void ifma_mreduce52x_mb8(int64u pX[][8], int nsX, int64u pM[][8], int nsM) +{ + /* usually divider have to be normilized */ + __m512i* pMtop = (__m512i*)(pM[nsM-1]); /* top of M */ + __m512i normBits = _mm512_sub_epi64( + _mm512_lzcnt_epi64(pMtop[0]), + _mm512_set1_epi64(64-DIGIT_SIZE) + ); + tz = _mm512_setzero_si512(); + /* normalize both divisor and shift dividentr */ + lshift52x_mb8(pM, pM, nsM, normBits); + /* expand and shift X */ + _mm512_store_si512(pX[nsX], _mm512_setzero_si512()); + lshift52x_mb8(pX, pX, nsX+1, normBits); + + // division + { + __m512i* pXtop = (__m512i*)(pX[nsX]); /* top of X (zero value) -- &X[nsX] */ + __m512i* pXbot = (__m512i*)(pX[nsX-nsM]); /* bot of X -- &X[nsQ-1] */ + + while(pXbot>=(__m512i*)pX) { + /* compute estimation of quotient digit q */ + __m512i q = estimateq_mb8(pXtop, pMtop); + + /* multiply and sub */ + ifma_sub_muldig52x_mb8(pXbot, (__m512i*)pM, nsM, q); + + pXtop--; + pXbot--; + } + } + + rshift52x_mb8(pX, pX, nsM, normBits); + rshift52x_mb8(pM, pM, nsM, normBits); +} + +/* bitsize of 2^64 representation => bitsize of 2^52 representation */ +#define BASE52_BITSIZE(b64bitsize) ((b64bitsize) + ((DIGIT_SIZE - ((b64bitsize) % DIGIT_SIZE)) % DIGIT_SIZE)) + +/* rr = 2^(2*ifmaBitLen) mod m */ +void ifma_montRR52x_mb8 (int64u pRR[][8], int64u pM[][8], int convBitLen) +{ + #define MAX_IFMA_MODULUS_BITLEN BASE52_BITSIZE(RSA_4K) + + /* buffer to hold 2^(2*MAX_IFMA_MODULUS_BITLEN) */ + __ALIGN64 int64u pwr2_mb8[(NUMBER_OF_DIGITS(2 * MAX_IFMA_MODULUS_BITLEN + 1, DIGIT_SIZE)) + 1][8]; /* +1 is necessary extension for ifma_mreduce52x_mb8() purpose */ + + int ifmaBitLen = BASE52_BITSIZE(convBitLen); + int ifmaLen = NUMBER_OF_DIGITS(ifmaBitLen, DIGIT_SIZE); + + int pwr = 2*ifmaBitLen; + int s = pwr - ((pwr/DIGIT_SIZE) * DIGIT_SIZE); + int pwrLen = NUMBER_OF_DIGITS(pwr + 1, DIGIT_SIZE); + + /* set 2^(ifmaBitLen*2) */ + zero_mb8(pwr2_mb8, pwrLen); + _mm512_store_si512(pwr2_mb8[pwrLen-1], _mm512_slli_epi64(_mm512_set1_epi64(1), s) ); + + /* 2^(ifmaBitLen*2) mod M */ + ifma_mreduce52x_mb8(pwr2_mb8, pwrLen, pM, ifmaLen); + + /* copy result */ + for(s=0; s +#include +#include +#include + +/* +// public exponent e=65537 implied +*/ +void ifma_cp_rsa_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer) +{ + int len52 = NUMBER_OF_DIGITS(rsaBitlen, DIGIT_SIZE); + + /* 64-byte aligned buffer of int64[8] */ + pint64u_x8 pBuffer_x8 = (pint64u_x8)IFMA_ALIGNED_PTR(pBuffer,64); + + /* allocate mb8 buffers */ + pint64u_x8 k0_mb8 = pBuffer_x8; + pint64u_x8 rr_mb8 = k0_mb8 +1; + pint64u_x8 inout_mb8 = rr_mb8 +len52; + pint64u_x8 n_mb8 = inout_mb8 +len52; + pint64u_x8 work_buffer = n_mb8 + len52; + + /* convert modulus to ifma fmt */ + zero_mb8(n_mb8, MULTIPLE_OF(len52, 10)); + ifma_BNU_to_mb8(n_mb8, n_pa, rsaBitlen); + + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8[0], n_mb8[0]); + + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, n_mb8, rsaBitlen); + + /* convert input to ifma fmt */ + ifma_HexStr8_to_mb8(inout_mb8, from_pa, rsaBitlen); + + /* exponentiation */ + m->expfunc65537(inout_mb8, + (const int64u (*)[8])inout_mb8, + (const int64u (*)[8])n_mb8, + (const int64u (*)[8])rr_mb8, + k0_mb8[0], + (int64u (*)[8])work_buffer); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inout_mb8, rsaBitlen); +} + +/* +// private key +*/ +void ifma_cp_rsa_prv2_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const d_pa[8], + const int64u* const n_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer) + +{ + int len52 = NUMBER_OF_DIGITS(rsaBitlen, DIGIT_SIZE); + int len64 = NUMBER_OF_DIGITS(rsaBitlen, 64); + + /* 64-byte aligned buffer of int64[8] */ + pint64u_x8 pBuffer_x8 = (pint64u_x8)IFMA_ALIGNED_PTR(pBuffer,64); + + /* allocate mb8 buffers */ + pint64u_x8 k0_mb8 = pBuffer_x8; + pint64u_x8 d_mb8 = k0_mb8 +1; + pint64u_x8 rr_mb8 = d_mb8 +len64; + pint64u_x8 inout_mb8 = rr_mb8 +len52; + pint64u_x8 n_mb8 = inout_mb8 +len52; + pint64u_x8 work_buffer = n_mb8 + len52; + + /* convert modulus to ifma fmt */ + zero_mb8(n_mb8, MULTIPLE_OF(len52, 10)); + ifma_BNU_to_mb8(n_mb8, n_pa, rsaBitlen); + + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8[0], n_mb8[0]); + + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, n_mb8, rsaBitlen); + + /* convert input to ifma fmt */ + ifma_HexStr8_to_mb8(inout_mb8, from_pa, rsaBitlen); + + /* re-arrange exps to ifma */ + ifma_BNU_transpose_copy(d_mb8, d_pa, rsaBitlen); + + /* exponentiation */ + m->expfun(inout_mb8, + (const int64u(*)[8])inout_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])n_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8[0], + (int64u (*)[8])work_buffer); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inout_mb8, rsaBitlen); + + /* clear exponents */ + zero_mb8(d_mb8, len64); +} + +/* +// private key (ctr) +*/ +void ifma_cp_rsa_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const p_pa[8], + const int64u* const q_pa[8], + const int64u* const dp_pa[8], + const int64u* const dq_pa[8], + const int64u* const iq_pa[8], + int rsaBitlen, + const mbx_RSA_Method* m, + int8u* pBuffer) + +{ + int factorBitlen = rsaBitlen/2; + int len52 = NUMBER_OF_DIGITS(factorBitlen, DIGIT_SIZE); + int len64 = NUMBER_OF_DIGITS(factorBitlen, 64); + + /* 64-byte aligned buffer of int64[8] */ + pint64u_x8 pBuffer_x8 = (pint64u_x8)IFMA_ALIGNED_PTR(pBuffer,64); + + /* allocate mb8 buffers */ + pint64u_x8 k0_mb8 = pBuffer_x8; + pint64u_x8 p_mb8 = k0_mb8 +1; + pint64u_x8 q_mb8 = p_mb8 +len52; + pint64u_x8 d_mb8 = q_mb8 +len52; + pint64u_x8 rr_mb8 = d_mb8 +len64; + pint64u_x8 xp_mb8 = rr_mb8 +len52; + pint64u_x8 xq_mb8 = xp_mb8 +len52; + pint64u_x8 inp_mb8 = xq_mb8 +len52; + pint64u_x8 work_buffer = inp_mb8 + len52*2; + + /* convert input to ifma fmt */ + zero_mb8(inp_mb8, len52*2); + ifma_HexStr8_to_mb8(inp_mb8, from_pa, rsaBitlen); + + /* + // q exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BNU_to_mb8(q_mb8, q_pa, factorBitlen); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8[0], q_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, q_mb8, factorBitlen); + /* xq = x mod q */ + m->amred52x(xq_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])q_mb8, k0_mb8[0]); + m->ammul52x((int64u*)xq_mb8, (int64u*)xq_mb8, (int64u*)rr_mb8, (int64u*)q_mb8, k0_mb8[0]); + m->modsub52x(xq_mb8, (const int64u(*)[8])xq_mb8, (const int64u(*)[8])q_mb8, (const int64u(*)[8])q_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BNU_transpose_copy(d_mb8, dq_pa, factorBitlen); + + m->expfun(xq_mb8, + (const int64u(*)[8])xq_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])q_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8[0], + (int64u (*)[8])work_buffer); + + /* + // p exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BNU_to_mb8(p_mb8, p_pa, factorBitlen); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8[0], p_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, p_mb8, factorBitlen); + /* xq = x mod q */ + m->amred52x(xp_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])p_mb8, k0_mb8[0]); + m->ammul52x((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)rr_mb8, (int64u*)p_mb8, k0_mb8[0]); + m->modsub52x(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BNU_transpose_copy(d_mb8, dp_pa, factorBitlen); + + m->expfun(xp_mb8, + (const int64u(*)[8])xp_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])p_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8[0], + (int64u (*)[8])work_buffer); + + /* + // crt recombination + */ + + /* xp = (xp-xq) mod p */ + m->modsub52x(inp_mb8,(const int64u(*)[8])xq_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); /* for specific case pmodsub52x(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])p_mb8); + + /* xp = (xp*coef) mod p */ + ifma_BNU_to_mb8(inp_mb8, iq_pa, factorBitlen); /* coef */ + m->ammul52x((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)rr_mb8, (int64u*)p_mb8, k0_mb8[0]); /* -> mont domain */ + m->ammul52x((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)inp_mb8, (int64u*)p_mb8, k0_mb8[0]); /* mmul */ + m->modsub52x(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8);/* correction */ + + /* xp = (xp*q + xq) */ + zero_mb8(inp_mb8, len52*2); + copy_mb8(inp_mb8, (const int64u(*)[8])xq_mb8, len52); + m->mla52x(inp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])q_mb8); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inp_mb8, rsaBitlen); + + /* clear exponents, p, q */ + zero_mb8(d_mb8, len64); + zero_mb8(q_mb8, len52); + zero_mb8(p_mb8, len52); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_mb8.c new file mode 100644 index 000000000..ff1a574a0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_mb8.c @@ -0,0 +1,314 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + + +#include +#include + +#include +#include +#include +#include + +#if !defined(NO_USE_MALLOC) +#include +#endif + +// y = x^65537 mod n +DLL_PUBLIC +mbx_status mbx_rsa_public_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const n_pa[8], + int expected_rsa_bitsize, + const mbx_RSA_Method* m, + int8u* pBuffer) +{ + const mbx_RSA_Method* meth = m; + + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==from_pa || NULL==to_pa || NULL==n_pa) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* test rsa modulus size */ + if(RSA_1K != expected_rsa_bitsize && RSA_2K != expected_rsa_bitsize && + RSA_3K != expected_rsa_bitsize && RSA_4K != expected_rsa_bitsize) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int8u* inp = from_pa[buf_no]; + int8u* out = to_pa[buf_no]; + const int64u* n = n_pa[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==inp || NULL==out || NULL==n) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + } + + /* test method */ + if(NULL==meth) { + meth = mbx_RSA_pub65537_Method(expected_rsa_bitsize); + if(NULL==meth) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + } + /* check if requested operation matched to method's */ + if(RSA_PUB_KEY != OP_RSA_ID(meth->id)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + /* check if requested RSA matched to method's */ + if(expected_rsa_bitsize != BISIZE_RSA_ID(meth->id)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* + // processing + */ + if( MBX_IS_ANY_OK_STS(status) ) { + int8u* buffer = pBuffer; + + #if !defined(NO_USE_MALLOC) + int allocated_buf = 0; + + /* check if allocated buffer) */ + if(NULL==buffer) { + buffer = (int8u*)( malloc(meth->buffSize) ); + if(NULL==buffer) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + allocated_buf = 1; + } + #endif + + ifma_cp_rsa_pub_layer_mb8(from_pa, to_pa, n_pa, + expected_rsa_bitsize, meth, + buffer); + + #if !defined(NO_USE_MALLOC) + /* release buffer */ + if(allocated_buf) + free(buffer); + #endif + } + + return status; +} + +DLL_PUBLIC +mbx_status mbx_rsa_private_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const d_pa[8], + const int64u* const n_pa[8], + int expected_rsa_bitsize, + const mbx_RSA_Method* m, + int8u* pBuffer) +{ + const mbx_RSA_Method* meth = m; + + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==from_pa || NULL==to_pa || NULL==d_pa || NULL==n_pa) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* test rsa modulus size */ + if(RSA_1K != expected_rsa_bitsize && RSA_2K != expected_rsa_bitsize && + RSA_3K != expected_rsa_bitsize && RSA_4K != expected_rsa_bitsize) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int8u* inp = from_pa[buf_no]; + int8u* out = to_pa[buf_no]; + const int64u* d = d_pa[buf_no]; + const int64u* n = n_pa[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==inp || NULL==out || NULL==d || NULL==n) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + } + + /* test method */ + if(NULL==meth) { + meth = mbx_RSA_private_Method(expected_rsa_bitsize); + if(NULL==meth) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + } + /* check if requested operation matched to method's */ + if(RSA_PRV2_KEY != OP_RSA_ID(meth->id)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + /* check if requested RSA matched to method's */ + if(expected_rsa_bitsize != BISIZE_RSA_ID(meth->id)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* + // processing + */ + if( MBX_IS_ANY_OK_STS(status) ) { + int8u* buffer = pBuffer; + + #if !defined(NO_USE_MALLOC) + int allocated_buf = 0; + + /* check if allocated buffer) */ + if(NULL==buffer) { + buffer = (int8u*)( malloc(meth->buffSize) ); + if(NULL==buffer) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + allocated_buf = 1; + } + #endif + + ifma_cp_rsa_prv2_layer_mb8(from_pa, to_pa, d_pa, n_pa, + expected_rsa_bitsize, meth, + buffer); + + #if !defined(NO_USE_MALLOC) + /* release buffer */ + if(allocated_buf) + free(buffer); + #endif + } + + return status; +} + +DLL_PUBLIC +mbx_status mbx_rsa_private_crt_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const int64u* const p_pa[8], + const int64u* const q_pa[8], + const int64u* const dp_pa[8], + const int64u* const dq_pa[8], + const int64u* const iq_pa[8], + int expected_rsa_bitsize, + const mbx_RSA_Method* m, + int8u* pBuffer) +{ + const mbx_RSA_Method* meth = m; + + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==from_pa || NULL==to_pa || + NULL==p_pa || NULL==q_pa || NULL==dp_pa || NULL==dq_pa || NULL==iq_pa) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* test rsa modulus size */ + if(RSA_1K != expected_rsa_bitsize && RSA_2K != expected_rsa_bitsize && + RSA_3K != expected_rsa_bitsize && RSA_4K != expected_rsa_bitsize) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int8u* inp = from_pa[buf_no]; + int8u* out = to_pa[buf_no]; + const int64u* p = p_pa[buf_no]; + const int64u* q = q_pa[buf_no]; + const int64u* dp = dp_pa[buf_no]; + const int64u* dq = dq_pa[buf_no]; + const int64u* iq = iq_pa[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==inp || NULL==out || NULL==q || NULL==p || NULL==dq || NULL==dp || NULL==iq) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + } + + /* test method */ + if(NULL==meth) { + meth = mbx_RSA_private_crt_Method(expected_rsa_bitsize); + if(NULL==meth) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + } + /* check if requested operation matched to method's */ + if(RSA_PRV5_KEY != OP_RSA_ID(meth->id)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + /* check if requested RSA matched to method's */ + if(expected_rsa_bitsize != BISIZE_RSA_ID(meth->id)) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* + // processing + */ + if( MBX_IS_ANY_OK_STS(status) ) { + int8u* buffer = pBuffer; + + #if !defined(NO_USE_MALLOC) + int allocated_buf = 0; + + /* check if allocated buffer) */ + if(NULL==buffer) { + buffer = (int8u*)( malloc(meth->buffSize) ); + if(NULL==buffer) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + allocated_buf = 1; + } + #endif + + ifma_cp_rsa_prv5_layer_mb8(from_pa, to_pa, p_pa, q_pa, dp_pa, dq_pa, iq_pa, + expected_rsa_bitsize, meth, + buffer); + + #if !defined(NO_USE_MALLOC) + /* release buffer */ + if(allocated_buf) + free(buffer); + #endif + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv2_layer_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv2_layer_mb8.c new file mode 100644 index 000000000..e15814f01 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv2_layer_mb8.c @@ -0,0 +1,258 @@ +typedef int to_avoid_translation_unit_is_empty_warning; + +#ifndef BN_OPENSSL_DISABLE + +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include + +#define EXP_WIN_SIZE (5) //(4) +#define EXP_WIN_MASK ((1< + +#include + +#include +#include +#include + + +// y = x^d mod n +DLL_PUBLIC +mbx_status mbx_rsa_private_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const d_pa[8], + const BIGNUM* const n_pa[8], + int expected_rsa_bitsize) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==from_pa || NULL==to_pa || NULL==d_pa || NULL==n_pa) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* test rsa modulus size */ + if(RSA_1K != expected_rsa_bitsize && RSA_2K != expected_rsa_bitsize && + RSA_3K != expected_rsa_bitsize && RSA_4K != expected_rsa_bitsize) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int8u* inp = from_pa[buf_no]; + int8u* out = to_pa[buf_no]; + const BIGNUM* d = d_pa[buf_no]; + const BIGNUM* n = n_pa[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==inp || NULL==out || NULL==d || NULL==n) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + + /* check rsa size */ + if(expected_rsa_bitsize != BN_num_bits(n)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + continue; + } + } + + /* continue processing if there are correct parameters */ + if( MBX_IS_ANY_OK_STS(status) ) { + /* select exponentiation */ + switch (expected_rsa_bitsize) { + case RSA_1K: ifma_ssl_rsa1K_prv2_layer_mb8(from_pa, to_pa, d_pa, n_pa); break; + case RSA_2K: ifma_ssl_rsa2K_prv2_layer_mb8(from_pa, to_pa, d_pa, n_pa); break; + case RSA_3K: ifma_ssl_rsa3K_prv2_layer_mb8(from_pa, to_pa, d_pa, n_pa); break; + case RSA_4K: ifma_ssl_rsa4K_prv2_layer_mb8(from_pa, to_pa, d_pa, n_pa); break; + } + } + + return status; +} + +#endif /* BN_OPENSSL_DISABLE */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv5_layer_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv5_layer_mb8.c new file mode 100644 index 000000000..4e7db9ad6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv5_layer_mb8.c @@ -0,0 +1,486 @@ +typedef int to_avoid_translation_unit_is_empty_warning; + +#ifndef BN_OPENSSL_DISABLE + +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include + +#define EXP_WIN_SIZE (5) //(4) +#define EXP_WIN_MASK ((1< mont domain */ + ifma_amm52x10_mb8((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)inp_mb8, (int64u*)p_mb8, k0_mb8); /* mmul */ + ifma_modsub52x10_mb8(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8);/* correction */ + + /* xp = (xp*q + xq) */ + zero_mb8(inp_mb8, LEN52*2); + copy_mb8(inp_mb8, (const int64u(*)[8])xq_mb8, LEN52); + ifma_addmul52x10_mb8(inp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])q_mb8); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inp_mb8, RSA_BITLEN); + + /* clear exponents, p, q */ + zero_mb8(d_mb8, LEN64); + zero_mb8(q_mb8, LEN52); + zero_mb8(p_mb8, LEN52); + + #undef RSA_BITLEN + #undef FACTOR_BITLEN + #undef LEN52 + #undef LEN64 +} + + +void ifma_ssl_rsa2K_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8]) +{ + #define RSA_BITLEN (RSA_2K) + #define FACTOR_BITLEN (RSA_BITLEN/2) + #define LEN52 (NUMBER_OF_DIGITS(FACTOR_BITLEN, DIGIT_SIZE)) + #define LEN64 (NUMBER_OF_DIGITS(FACTOR_BITLEN, 64)) + + /* allocate mb8 buffers */ + __ALIGN64 int64u k0_mb8[8]; + __ALIGN64 int64u p_mb8[LEN52][8]; + __ALIGN64 int64u q_mb8[LEN52][8]; + __ALIGN64 int64u d_mb8[LEN64][8]; + __ALIGN64 int64u rr_mb8[LEN52][8]; + __ALIGN64 int64u xp_mb8[LEN52][8]; + __ALIGN64 int64u xq_mb8[LEN52][8]; + __ALIGN64 int64u inp_mb8[LEN52*2][8]; + /* allocate stack for red(undant) result, multiplier, for exponent X and for pre-computed table of base powers */ + __ALIGN64 int64u work_buffer[LEN52*2 + 1 + (LEN64 + 1) + (1 << EXP_WIN_SIZE)*LEN52][8]; + + /* convert input to ifma fmt */ + zero_mb8(inp_mb8, LEN52*2); + ifma_HexStr8_to_mb8(inp_mb8, from_pa, RSA_BITLEN); + + /* + // q exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BN_to_mb8(q_mb8, q_pa, FACTOR_BITLEN); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, q_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, q_mb8, FACTOR_BITLEN); + /* xq = x mod q */ + ifma_amred52x20_mb8(xq_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])q_mb8, k0_mb8); + ifma_amm52x20_mb8((int64u*)xq_mb8, (int64u*)xq_mb8, (int64u*)rr_mb8, (int64u*)q_mb8, k0_mb8); + ifma_modsub52x20_mb8(xq_mb8, (const int64u(*)[8])xq_mb8, (const int64u(*)[8])q_mb8, (const int64u(*)[8])q_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BN_transpose_copy(d_mb8, dq_pa, FACTOR_BITLEN); + + EXP52x20_mb8(xq_mb8, + (const int64u(*)[8])xq_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])q_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* + // p exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BN_to_mb8(p_mb8, p_pa, FACTOR_BITLEN); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, p_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, p_mb8, FACTOR_BITLEN); + /* xp = x mod p */ + ifma_amred52x20_mb8(xp_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])p_mb8, k0_mb8); + ifma_amm52x20_mb8((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)rr_mb8, (int64u*)p_mb8, k0_mb8); + ifma_modsub52x20_mb8(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BN_transpose_copy(d_mb8, dp_pa, FACTOR_BITLEN); + + EXP52x20_mb8(xp_mb8, + (const int64u(*)[8])xp_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])p_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* + // crt recombination + */ + + /* xp = (xp-xq) mod p */ + ifma_modsub52x20_mb8(inp_mb8,(const int64u(*)[8])xq_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); /* for specific case p mont domain */ + ifma_amm52x20_mb8((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)inp_mb8, (int64u*)p_mb8, k0_mb8); /* mmul */ + ifma_modsub52x20_mb8(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8);/* correction */ + + /* xp = (xp*q + xq) */ + zero_mb8(inp_mb8, LEN52*2); + copy_mb8(inp_mb8, (const int64u(*)[8])xq_mb8, LEN52); + ifma_addmul52x20_mb8(inp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])q_mb8); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inp_mb8, RSA_BITLEN); + + /* clear exponents, p, q */ + zero_mb8(d_mb8, LEN64); + zero_mb8(q_mb8, LEN52); + zero_mb8(p_mb8, LEN52); + + #undef RSA_BITLEN + #undef FACTOR_BITLEN + #undef LEN52 + #undef LEN64 +} + + +void ifma_ssl_rsa3K_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8]) +{ + #define RSA_BITLEN (RSA_3K) + #define FACTOR_BITLEN (RSA_BITLEN/2) + #define LEN52 (NUMBER_OF_DIGITS(FACTOR_BITLEN, DIGIT_SIZE)) + #define LEN64 (NUMBER_OF_DIGITS(FACTOR_BITLEN, 64)) + + /* allocate mb8 buffers */ + __ALIGN64 int64u k0_mb8[8]; + __ALIGN64 int64u p_mb8[LEN52][8]; + __ALIGN64 int64u q_mb8[LEN52][8]; + __ALIGN64 int64u d_mb8[LEN64][8]; + __ALIGN64 int64u rr_mb8[LEN52][8]; + __ALIGN64 int64u xp_mb8[LEN52][8]; + __ALIGN64 int64u xq_mb8[LEN52][8]; + __ALIGN64 int64u inp_mb8[LEN52 * 2][8]; + /* allocate stack for red(undant) result, multiplier, for exponent X and for pre-computed table of base powers */ + __ALIGN64 int64u work_buffer[LEN52*2 + 1 + (LEN64 + 1) + (1 << EXP_WIN_SIZE)*LEN52][8]; + + /* convert input to ifma fmt */ + zero_mb8(inp_mb8, LEN52 * 2); + ifma_HexStr8_to_mb8(inp_mb8, from_pa, RSA_BITLEN); + + /* + // q exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BN_to_mb8(q_mb8, q_pa, FACTOR_BITLEN); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, q_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, q_mb8, FACTOR_BITLEN); + /* xq = x mod q */ + ifma_amred52x30_mb8(xq_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])q_mb8, k0_mb8); + ifma_amm52x30_mb8((int64u*)xq_mb8, (int64u*)xq_mb8, (int64u*)rr_mb8, (int64u*)q_mb8, k0_mb8); + ifma_modsub52x30_mb8(xq_mb8, (const int64u(*)[8])xq_mb8, (const int64u(*)[8])q_mb8, (const int64u(*)[8])q_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BN_transpose_copy(d_mb8, dq_pa, FACTOR_BITLEN); + + EXP52x30_mb8(xq_mb8, + (const int64u(*)[8])xq_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])q_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* + // p exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BN_to_mb8(p_mb8, p_pa, FACTOR_BITLEN); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, p_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, p_mb8, FACTOR_BITLEN); + /* xp = x mod p */ + ifma_amred52x30_mb8(xp_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])p_mb8, k0_mb8); + ifma_amm52x30_mb8((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)rr_mb8, (int64u*)p_mb8, k0_mb8); + ifma_modsub52x30_mb8(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BN_transpose_copy(d_mb8, dp_pa, FACTOR_BITLEN); + + EXP52x30_mb8(xp_mb8, + (const int64u(*)[8])xp_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])p_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* + // crt recombination + */ + + /* xp = (xp-xq) mod p */ + ifma_modsub52x30_mb8(inp_mb8,(const int64u(*)[8])xq_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); /* for specific case p mont domain */ + ifma_amm52x30_mb8((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)inp_mb8, (int64u*)p_mb8, k0_mb8); /* mmul */ + ifma_modsub52x30_mb8(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8);/* correction */ + + /* xp = (xp*q + xq) */ + zero_mb8(inp_mb8, LEN52 * 2); + copy_mb8(inp_mb8, (const int64u(*)[8])xq_mb8, LEN52); + ifma_addmul52x30_mb8(inp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])q_mb8); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inp_mb8, RSA_BITLEN); + + /* clear exponents, p, q */ + zero_mb8(d_mb8, LEN64); + zero_mb8(q_mb8, LEN52); + zero_mb8(p_mb8, LEN52); + + #undef RSA_BITLEN + #undef FACTOR_BITLEN + #undef LEN52 + #undef LEN64 +} + + +void ifma_ssl_rsa4K_prv5_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8]) +{ + #define RSA_BITLEN (RSA_4K) + #define FACTOR_BITLEN (RSA_BITLEN/2) + #define LEN52 (NUMBER_OF_DIGITS(FACTOR_BITLEN, DIGIT_SIZE)) + #define LEN64 (NUMBER_OF_DIGITS(FACTOR_BITLEN, 64)) + + /* allocate mb8 buffers */ + __ALIGN64 int64u k0_mb8[8]; + __ALIGN64 int64u p_mb8[LEN52][8]; + __ALIGN64 int64u q_mb8[LEN52][8]; + __ALIGN64 int64u d_mb8[LEN64][8]; + __ALIGN64 int64u rr_mb8[LEN52][8]; + __ALIGN64 int64u xp_mb8[LEN52][8]; + __ALIGN64 int64u xq_mb8[LEN52][8]; + __ALIGN64 int64u inp_mb8[LEN52*2][8]; + /* allocate stack for red(undant) result, multiplier, for exponent X and for pre-computed table of base powers */ + __ALIGN64 int64u work_buffer[LEN52*2 + 1 + (LEN64 + 1) + (1 << EXP_WIN_SIZE)*LEN52][8]; + + /* convert input to ifma fmt */ + zero_mb8(inp_mb8, LEN52 * 2); + ifma_HexStr8_to_mb8(inp_mb8, from_pa, RSA_BITLEN); + + /* + // q exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BN_to_mb8(q_mb8, q_pa, FACTOR_BITLEN); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, q_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, q_mb8, FACTOR_BITLEN); + /* xq = x mod q */ + ifma_amred52x40_mb8(xq_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])q_mb8, k0_mb8); + ifma_amm52x40_mb8((int64u*)xq_mb8, (int64u*)xq_mb8, (int64u*)rr_mb8, (int64u*)q_mb8, k0_mb8); + ifma_modsub52x40_mb8(xq_mb8, (const int64u(*)[8])xq_mb8, (const int64u(*)[8])q_mb8, (const int64u(*)[8])q_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BN_transpose_copy(d_mb8, dq_pa, FACTOR_BITLEN); + + EXP52x40_mb8(xq_mb8, + (const int64u(*)[8])xq_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])q_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* + // p exponentiation + */ + + /* convert modulus to ifma fmt */ + ifma_BN_to_mb8(p_mb8, p_pa, FACTOR_BITLEN); + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, p_mb8[0]); + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, p_mb8, FACTOR_BITLEN); + /* xp = x mod p */ + ifma_amred52x40_mb8(xp_mb8, (const int64u(*)[8])inp_mb8, (const int64u(*)[8])p_mb8, k0_mb8); + ifma_amm52x40_mb8((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)rr_mb8, (int64u*)p_mb8, k0_mb8); + ifma_modsub52x40_mb8(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); // ?? + /* re-arrange exps to ifma */ + ifma_BN_transpose_copy(d_mb8, dp_pa, FACTOR_BITLEN); + + EXP52x40_mb8(xp_mb8, + (const int64u(*)[8])xp_mb8, + (const int64u(*)[8])d_mb8, + (const int64u(*)[8])p_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* + // crt recombination + */ + + /* xp = (xp-xq) mod p */ + ifma_modsub52x40_mb8(inp_mb8,(const int64u(*)[8])xq_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8); /* for specific case p mont domain */ + ifma_amm52x40_mb8((int64u*)xp_mb8, (int64u*)xp_mb8, (int64u*)inp_mb8, (int64u*)p_mb8, k0_mb8); /* mmul */ + ifma_modsub52x40_mb8(xp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])p_mb8, (const int64u(*)[8])p_mb8);/* correction */ + + /* xp = (xp*q + xq) */ + zero_mb8(inp_mb8, LEN52 * 2); + copy_mb8(inp_mb8, (const int64u(*)[8])xq_mb8, LEN52); + ifma_addmul52x40_mb8(inp_mb8, (const int64u(*)[8])xp_mb8, (const int64u(*)[8])q_mb8); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inp_mb8, RSA_BITLEN); + + /* clear exponents, p, q */ + zero_mb8(d_mb8, LEN64); + zero_mb8(q_mb8, LEN52); + zero_mb8(p_mb8, LEN52); + + #undef RSA_BITLEN + #undef FACTOR_BITLEN + #undef LEN52 + #undef LEN64 +} + +#endif /* BN_OPENSSL_DISABLE */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv5_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv5_mb8.c new file mode 100644 index 000000000..e3fb0ae9b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_prv5_mb8.c @@ -0,0 +1,97 @@ +typedef int to_avoid_translation_unit_is_empty_warning; + +#ifndef BN_OPENSSL_DISABLE + +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include + +#include +#include +#include + + +// y = x^d mod n (crt) +DLL_PUBLIC +mbx_status mbx_rsa_private_crt_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const p_pa[8], + const BIGNUM* const q_pa[8], + const BIGNUM* const dp_pa[8], + const BIGNUM* const dq_pa[8], + const BIGNUM* const iq_pa[8], + int expected_rsa_bitsize) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==from_pa || NULL==to_pa || + NULL==p_pa || NULL==q_pa || NULL==dp_pa || NULL==dq_pa || NULL==iq_pa) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* test rsa modulus size */ + if(RSA_1K != expected_rsa_bitsize && RSA_2K != expected_rsa_bitsize && + RSA_3K != expected_rsa_bitsize && RSA_4K != expected_rsa_bitsize) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int8u* inp = from_pa[buf_no]; + int8u* out = to_pa[buf_no]; + const BIGNUM* q = q_pa[buf_no]; + const BIGNUM* p = p_pa[buf_no]; + const BIGNUM* dq = dq_pa[buf_no]; + const BIGNUM* dp = dp_pa[buf_no]; + const BIGNUM* iq = iq_pa[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==inp || NULL==out || NULL==q || NULL==p || NULL==dq || NULL==dp || NULL==iq) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + + /* check rsa's factors */ + if(((expected_rsa_bitsize/2) != BN_num_bits(p)) || ((expected_rsa_bitsize/2) != BN_num_bits(q))) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + continue; + } + } + + /* continue processing if there are correct parameters */ + if( MBX_IS_ANY_OK_STS(status) ) { + //int factor_bitsize = expected_rsa_bitsize/2; + + /* select exponentiation and other functions */ + switch (expected_rsa_bitsize) { + case RSA_1K: ifma_ssl_rsa1K_prv5_layer_mb8(from_pa, to_pa, p_pa, q_pa, dp_pa, dq_pa, iq_pa); break; + case RSA_2K: ifma_ssl_rsa2K_prv5_layer_mb8(from_pa, to_pa, p_pa, q_pa, dp_pa, dq_pa, iq_pa); break; + case RSA_3K: ifma_ssl_rsa3K_prv5_layer_mb8(from_pa, to_pa, p_pa, q_pa, dp_pa, dq_pa, iq_pa); break; + case RSA_4K: ifma_ssl_rsa4K_prv5_layer_mb8(from_pa, to_pa, p_pa, q_pa, dp_pa, dq_pa, iq_pa); break; + } + } + + return status; +} + +#endif /* BN_OPENSSL_DISABLE */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_pub65537_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_pub65537_mb8.c new file mode 100644 index 000000000..20348857c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_pub65537_mb8.c @@ -0,0 +1,97 @@ +typedef int to_avoid_translation_unit_is_empty_warning; + +#ifndef BN_OPENSSL_DISABLE + +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include + +#include +#include +#include + + +// y = x^65537 mod n +DLL_PUBLIC +mbx_status mbx_rsa_public_ssl_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const e_pa[8], + const BIGNUM* const n_pa[8], + int expected_rsa_bitsize) +{ + /* check pointers and values */ + const int64u expected_pub_exp = 65537; + + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==from_pa || NULL==to_pa || NULL==e_pa || NULL==n_pa) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + /* test rsa modulus size */ + if(RSA_1K!=expected_rsa_bitsize && RSA_2K!=expected_rsa_bitsize && + RSA_3K != expected_rsa_bitsize && RSA_4K != expected_rsa_bitsize) { + status = MBX_SET_STS_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + const int8u* inp = from_pa[buf_no]; + int8u* out = to_pa[buf_no]; + const BIGNUM* e = e_pa[buf_no]; + const BIGNUM* n = n_pa[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==inp || NULL==out || NULL==e || NULL==n) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + + /* check public exponent */ + if(!BN_is_word(e, expected_pub_exp)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + continue; + } + + /* check rsa size */ + if(expected_rsa_bitsize != BN_num_bits(n)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + continue; + } + } + + /* continue processing if there are correct parameters */ + if( MBX_IS_ANY_OK_STS(status) ) { + /* use suitable implementation */ + switch(expected_rsa_bitsize) { + case RSA_1K: ifma_ssl_rsa1K_pub_layer_mb8(from_pa, to_pa, n_pa); break; + case RSA_2K: ifma_ssl_rsa2K_pub_layer_mb8(from_pa, to_pa, n_pa); break; + case RSA_3K: ifma_ssl_rsa3K_pub_layer_mb8(from_pa, to_pa, n_pa); break; + case RSA_4K: ifma_ssl_rsa4K_pub_layer_mb8(from_pa, to_pa, n_pa); break; + } + } + + return status; +} + +#endif /* BN_OPENSSL_DISABLE */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_pub_layer_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_pub_layer_mb8.c new file mode 100644 index 000000000..dc68fc760 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/rsa/ifma_rsa_ssl_pub_layer_mb8.c @@ -0,0 +1,212 @@ +typedef int to_avoid_translation_unit_is_empty_warning; + +#ifndef BN_OPENSSL_DISABLE + +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include + + +/* +// public exponent e=65537 implied +*/ + +void ifma_ssl_rsa1K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]) +{ + #define RSA_BITLEN (RSA_1K) + #define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + + /* allocate mb8 buffers */ + __ALIGN64 int64u k0_mb8[8]; + __ALIGN64 int64u rr_mb8[LEN52][8]; + __ALIGN64 int64u inout_mb8[LEN52][8]; + /* MULTIPLE_OF_10 because of AMS5x52x79_diagonal_mb8() implementaion specific */ + __ALIGN64 int64u n_mb8[MULTIPLE_OF(LEN52, 10)][8]; + /* allocate stack for red(undant) result and multiplier */ + __ALIGN64 int64u work_buffer[LEN52*2][8]; + + /* convert modulus to ifma fmt */ + zero_mb8(n_mb8, MULTIPLE_OF(LEN52, 10)); + ifma_BN_to_mb8(n_mb8, n_pa, RSA_BITLEN); + + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, n_mb8[0]); + + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, n_mb8, RSA_BITLEN); + + /* convert input to ifma fmt */ + ifma_HexStr8_to_mb8(inout_mb8, from_pa, RSA_BITLEN); + + /* exponentiation */ + EXP52x20_pub65537_mb8(inout_mb8, + (const int64u (*)[8])inout_mb8, + (const int64u (*)[8])n_mb8, + (const int64u (*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inout_mb8, RSA_BITLEN); + + #undef RSA_BITLEN + #undef LEN52 +} + + +void ifma_ssl_rsa2K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]) +{ + #define RSA_BITLEN (RSA_2K) + #define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + + /* allocate mb8 buffers */ + __ALIGN64 int64u k0_mb8[8]; + __ALIGN64 int64u rr_mb8[LEN52][8]; + __ALIGN64 int64u inout_mb8[LEN52][8]; + /* MULTIPLE_OF_10 because of AMS5x52x79_diagonal_mb8() implementaion specific */ + __ALIGN64 int64u n_mb8[MULTIPLE_OF(LEN52, 10)][8]; + /* allocate stack for red(undant) result and multiplier */ + __ALIGN64 int64u work_buffer[LEN52*2][8]; + + /* convert modulus to ifma fmt */ + zero_mb8(n_mb8, MULTIPLE_OF(LEN52, 10)); + ifma_BN_to_mb8(n_mb8, n_pa, RSA_BITLEN); + + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, n_mb8[0]); + + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, n_mb8, RSA_BITLEN); + + /* convert input to ifma fmt */ + ifma_HexStr8_to_mb8(inout_mb8, from_pa, RSA_BITLEN); + + /* exponentiation */ + EXP52x40_pub65537_mb8(inout_mb8, + (const int64u(*)[8])inout_mb8, + (const int64u(*)[8])n_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inout_mb8, RSA_BITLEN); + + #undef RSA_BITLEN + #undef LEN52 +} + + +void ifma_ssl_rsa3K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]) +{ + #define RSA_BITLEN (RSA_3K) + #define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + + /* allocate mb8 buffers */ + __ALIGN64 int64u k0_mb8[8]; + __ALIGN64 int64u rr_mb8[LEN52][8]; + __ALIGN64 int64u inout_mb8[LEN52][8]; + /* MULTIPLE_OF_10 because of AMS5x52x79_diagonal_mb8() implementaion specific */ + __ALIGN64 int64u n_mb8[MULTIPLE_OF(LEN52, 10)][8]; + /* allocate stack for red(undant) result and multiplier */ + __ALIGN64 int64u work_buffer[LEN52*2][8]; + + /* convert modulus to ifma fmt */ + zero_mb8(n_mb8, MULTIPLE_OF(LEN52, 10)); + ifma_BN_to_mb8(n_mb8, n_pa, RSA_BITLEN); + + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, n_mb8[0]); + + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, n_mb8, RSA_BITLEN); + + /* convert input to ifma fmt */ + ifma_HexStr8_to_mb8(inout_mb8, from_pa, RSA_BITLEN); + + /* exponentiation */ + EXP52x60_pub65537_mb8(inout_mb8, + (const int64u(*)[8])inout_mb8, + (const int64u(*)[8])n_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inout_mb8, RSA_BITLEN); + + #undef RSA_BITLEN + #undef LEN52 +} + + +void ifma_ssl_rsa4K_pub_layer_mb8(const int8u* const from_pa[8], + int8u* const to_pa[8], + const BIGNUM* const n_pa[8]) +{ + #define RSA_BITLEN (RSA_4K) + #define LEN52 (NUMBER_OF_DIGITS(RSA_BITLEN, DIGIT_SIZE)) + + /* allocate mb8 buffers */ + __ALIGN64 int64u k0_mb8[8]; + __ALIGN64 int64u rr_mb8[LEN52][8]; + __ALIGN64 int64u inout_mb8[LEN52][8]; + /* MULTIPLE_OF_10 because of AMS5x52x79_diagonal_mb8() implementaion specific */ + __ALIGN64 int64u n_mb8[MULTIPLE_OF(LEN52, 10)][8]; + /* allocate stack for red(undant) result and multiplier */ + __ALIGN64 int64u work_buffer[LEN52*2+1][8]; + + /* convert modulus to ifma fmt */ + zero_mb8(n_mb8, MULTIPLE_OF(LEN52, 10)); + ifma_BN_to_mb8(n_mb8, n_pa, RSA_BITLEN); + + /* compute k0[] */ + ifma_montFactor52_mb8(k0_mb8, n_mb8[0]); + + /* compute to_Montgomery domain converters */ + ifma_montRR52x_mb8(rr_mb8, n_mb8, RSA_BITLEN); + + /* convert input to ifma fmt */ + ifma_HexStr8_to_mb8(inout_mb8, from_pa, RSA_BITLEN); + + /* exponentiation */ + EXP52x79_pub65537_mb8(inout_mb8, + (const int64u(*)[8])inout_mb8, + (const int64u(*)[8])n_mb8, + (const int64u(*)[8])rr_mb8, + k0_mb8, + (int64u(*)[8])work_buffer); + + /* convert result from ifma fmt */ + ifma_mb8_to_HexStr8(to_pa, (const int64u(*)[8])inout_mb8, RSA_BITLEN); + + #undef RSA_BITLEN + #undef LEN52 +} + +#endif /* BN_OPENSSL_DISABLE */ diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_arith_nsm2.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_arith_nsm2.c new file mode 100644 index 000000000..964d77930 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_arith_nsm2.c @@ -0,0 +1,219 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Constants */ +#define LEN52 NUMBER_OF_DIGITS(256,DIGIT_SIZE) + +/* +// EC SM2 prime base point order +// in 2^52 radix +*/ +__ALIGN64 static const int64u nsm2_mb[LEN52][8] = { + { REP8_DECL(0x000bf40939d54123) }, + { REP8_DECL(0x0006b21c6052b53b) }, + { REP8_DECL(0x000fffffff7203df) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0000fffffffeffff) } +}; + +__ALIGN64 static const int64u nsm2x2_mb[LEN52][8] = { + { REP8_DECL(0x0007e81273aa8246) }, + { REP8_DECL(0x000d6438c0a56a77) }, + { REP8_DECL(0x000ffffffee407be) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0001fffffffdffff) } +}; + +/* k0 = -( (1/nsm2 mod 2^DIGIT_SIZE) ) mod 2^DIGIT_SIZE */ +__ALIGN64 static const int64u nsm2_k0_mb[8] = { + REP8_DECL(0x000f9e8872350975) +}; + +/* to Montgomery conversion constant +// rr = 2^((LEN52*DIGIT_SIZE)*2) mod nsm2 +*/ +__ALIGN64 static const int64u nsm2_rr_mb[LEN52][8] = { + { REP8_DECL(0x000c16674a517de6) }, + { REP8_DECL(0x000507a6e5f7c418) }, + { REP8_DECL(0x000fe0d44507dc1c) }, + { REP8_DECL(0x0003b620fc84c3af) }, + { REP8_DECL(0x0000b5e412c02b3d) } +}; + +/*===================================================================== + + Specialized single operations in nsm2 - sqr & mul + +=====================================================================*/ +EXTERN_C U64* MB_FUNC_NAME(ifma_nsm2_)(void) +{ + return (U64*)nsm2_mb; +} + +void MB_FUNC_NAME(ifma_ams52_nsm2_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_ams52x5_)(r, a, (U64*)nsm2_mb, nsm2_k0_mb); +} + +void MB_FUNC_NAME(ifma_amm52_nsm2_)(U64 r[], const U64 a[], const U64 b[]) +{ + MB_FUNC_NAME(ifma_amm52x5_)(r, a, b, (U64*)nsm2_mb, nsm2_k0_mb); +} + +void MB_FUNC_NAME(ifma_tomont52_nsm2_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52x5_)(r, a, (U64*)nsm2_rr_mb, (U64*)nsm2_mb, nsm2_k0_mb); +} + +void MB_FUNC_NAME(ifma_frommont52_nsm2_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_amm52_nsm2_)(r, a, (U64*)ones); + MB_FUNC_NAME(ifma_fastred52_pnsm2_)(r, r); +} + +/* +// computes r = 1/z = z^(nsm2-2) mod nsm2 +// +// note: z in in Montgomery domain (as soon mul() and sqr() below are amm-functions +// r in Montgomery domain too +*/ +#define sqr_nsm2 MB_FUNC_NAME(ifma_ams52_nsm2_) +#define mul_nsm2 MB_FUNC_NAME(ifma_amm52_nsm2_) + +void MB_FUNC_NAME(ifma_aminv52_nsm2_)(U64 r[], const U64 z[]) +{ + int i; + + // pwr_z_Tbl[i][] = z^i, i=0,..,15 + __ALIGN64 U64 pwr_z_Tbl[16][LEN52]; + + MB_FUNC_NAME(ifma_tomont52_nsm2_)(pwr_z_Tbl[0], (U64*)ones); + MB_FUNC_NAME(mov_FESM2_)(pwr_z_Tbl[1], z); + + for(i=2; i<16; i+=2) { + sqr_nsm2(pwr_z_Tbl[i], pwr_z_Tbl[i/2]); + mul_nsm2(pwr_z_Tbl[i+1], pwr_z_Tbl[i], z); + } + + // pwr = (nsm2-2) in big endian + int8u pwr[] = "\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x72\x03\xDF\x6B\x21\xC6\x05\x2B" + "\x53\xBB\xF4\x09\x39\xD5\x41\x21"; + // init r = 1 + MB_FUNC_NAME(mov_FESM2_)(r, pwr_z_Tbl[0]); + + for(i=0; i<32; i++) { + int v = pwr[i]; + int hi = (v>>4) &0xF; + int lo = v & 0xF; + + sqr_nsm2(r, r); + sqr_nsm2(r, r); + sqr_nsm2(r, r); + sqr_nsm2(r, r); + if(hi) + mul_nsm2(r, r, pwr_z_Tbl[hi]); + sqr_nsm2(r, r); + sqr_nsm2(r, r); + sqr_nsm2(r, r); + sqr_nsm2(r, r); + if(lo) + mul_nsm2(r, r, pwr_z_Tbl[lo]); + } +} + +/*===================================================================== + + Specialized single operations in nsm2 - add, sub & neg + +=====================================================================*/ + +void MB_FUNC_NAME(ifma_add52_nsm2_)(U64 r[], const U64 a[], const U64 b[]) +{ + MB_FUNC_NAME(ifma_add52x5_)(r, a, b, (U64*)nsm2x2_mb); +} + +void MB_FUNC_NAME(ifma_sub52_nsm2_)(U64 r[], const U64 a[], const U64 b[]) +{ + MB_FUNC_NAME(ifma_sub52x5_)(r, a, b, (U64*)nsm2x2_mb); +} + +void MB_FUNC_NAME(ifma_neg52_nsm2_)(U64 r[], const U64 a[]) +{ + MB_FUNC_NAME(ifma_neg52x5_)(r, a, (U64*)nsm2x2_mb); +} + +static __mb_mask MB_FUNC_NAME(lt_mbx_digit_)(const U64 a, const U64 b, const __mb_mask lt_mask) +{ + U64 d = mask_sub64(sub64(a, b), lt_mask, sub64(a, b), set1(1)); + return cmp64_mask(d, get_zero64(), _MM_CMPINT_LT); +} + +/* r = (a>=nsm2)? a-nsm2 : a */ +void MB_FUNC_NAME(ifma_fastred52_pnsm2_)(U64 R[], const U64 A[]) +{ + /* r = a - b */ + U64 r0 = sub64(A[0], ((U64*)(nsm2_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(nsm2_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(nsm2_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(nsm2_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(nsm2_mb))[4]); + + /* lt = {r0 - r4} < 0 */ + __mb_mask + lt = MB_FUNC_NAME(lt_mbx_digit_)(r0, get_zero64(), 0); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r1, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r2, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r3, get_zero64(), lt); + lt = MB_FUNC_NAME(lt_mbx_digit_)(r4, get_zero64(), lt); + + r0 = mask_mov64(A[0], ~lt, r0); + r1 = mask_mov64(A[1], ~lt, r1); + r2 = mask_mov64(A[2], ~lt, r2); + r3 = mask_mov64(A[3], ~lt, r3); + r4 = mask_mov64(A[4], ~lt, r4); + + /* normalize r0 - r4 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + + R[0] = r0; + R[1] = r1; + R[2] = r2; + R[3] = r3; + R[4] = r4; +} + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_nsm2_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FESM2_)(a,(const U64 (*))nsm2_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_nsm2_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FESM2_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_nsm2_)(A); + + return mask; +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_arith_psm2.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_arith_psm2.c new file mode 100644 index 000000000..f51d5a049 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_arith_psm2.c @@ -0,0 +1,503 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* +// prime256 = 2^256 - 2^224 - 2^96 + 2^64 - 1 +// in 2^52 radix +*/ +__ALIGN64 static const int64u psm2_mb[PSM2_LEN52][8] = { + { REP8_DECL(0xfffffffffffff) }, + { REP8_DECL(0xff00000000fff) }, + { REP8_DECL(0xfffffffffffff) }, + { REP8_DECL(0xfffffffffffff) }, + { REP8_DECL(0x0fffffffeffff) } +}; + +__ALIGN64 static const int64u psm2x2_mb[PSM2_LEN52][8] = { + { REP8_DECL(0xffffffffffffe) }, + { REP8_DECL(0xfe00000001fff) }, + { REP8_DECL(0xfffffffffffff) }, + { REP8_DECL(0xfffffffffffff) }, + { REP8_DECL(0x1fffffffdffff) } +}; + +/* to Montgomery conversion constant +// rr = 2^((PSM2_LEN52*DIGIT_SIZE)*2) mod psm2 +*/ +__ALIGN64 static const int64u psm2_rr_mb[PSM2_LEN52][8] = { + { REP8_DECL(0x0020000000300) }, + { REP8_DECL(0xffffffff00000) }, + { REP8_DECL(0x0000100000002) }, + { REP8_DECL(0x0200000001000) }, + { REP8_DECL(0x0000004000000) } +}; + +/* other constants */ +__ALIGN64 static const int64u VDIGIT_MASK_[8] = + {DIGIT_MASK, DIGIT_MASK, DIGIT_MASK, DIGIT_MASK, + DIGIT_MASK, DIGIT_MASK, DIGIT_MASK, DIGIT_MASK}; +#define VDIGIT_MASK loadu64(VDIGIT_MASK_) + +#define ROUND_MUL(I, J, LO, HI) \ + LO = fma52lo(LO, va[I], vb[J]); \ + HI = fma52hi(HI, va[I], vb[J]) + + +//TODO: reduction +#define MUL_ADD_PSM2(u, res0, res1, res2, res3, res4, res5) \ +{ \ + /* a * ( 2^52 - 1 ) = 2^52 * a - a */ \ + U64 u = and64(res0, VDIGIT_MASK); \ + /* res0 = sub64(res0, u); */ /* Zero out low 52 bits */ \ + res1 = add64(res1, srli64(res0, DIGIT_SIZE)); /* Carry propagation */ \ + res1 = add64(res1, u); \ + res1 = fma52lo(res1, u, ((U64*)psm2_mb)[1]); \ + res2 = fma52hi(res2, u, ((U64*)psm2_mb)[1]); \ + res2 = sub64(res2, u); \ + res4 = add64(res4, u); \ + res4 = fma52lo(res4, u, ((U64*)psm2_mb)[4]); \ + res5 = fma52hi(res5, u, ((U64*)psm2_mb)[4]); \ +} + +void MB_FUNC_NAME(ifma_amm52_psm2_)(U64 r[], const U64 va[], const U64 vb[]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + // full multiplication + ROUND_MUL(0, 0, r0, r1); + ROUND_MUL(1, 0, r1, r2); + ROUND_MUL(2, 0, r2, r3); + ROUND_MUL(3, 0, r3, r4); + ROUND_MUL(4, 0, r4, r5); + + ROUND_MUL(0, 1, r1, r2); + ROUND_MUL(1, 1, r2, r3); + ROUND_MUL(2, 1, r3, r4); + ROUND_MUL(3, 1, r4, r5); + ROUND_MUL(4, 1, r5, r6); + + ROUND_MUL(0, 2, r2, r3); + ROUND_MUL(1, 2, r3, r4); + ROUND_MUL(2, 2, r4, r5); + ROUND_MUL(3, 2, r5, r6); + ROUND_MUL(4, 2, r6, r7); + + ROUND_MUL(0, 3, r3, r4); + ROUND_MUL(1, 3, r4, r5); + ROUND_MUL(2, 3, r5, r6); + ROUND_MUL(3, 3, r6, r7); + ROUND_MUL(4, 3, r7, r8); + + ROUND_MUL(0, 4, r4, r5); + ROUND_MUL(1, 4, r5, r6); + ROUND_MUL(2, 4, r6, r7); + ROUND_MUL(3, 4, r7, r8); + ROUND_MUL(4, 4, r8, r9); + + //reduction + MUL_ADD_PSM2(u0, r0, r1, r2, r3, r4, r5); + MUL_ADD_PSM2(u1, r1, r2, r3, r4, r5, r6); + MUL_ADD_PSM2(u2, r2, r3, r4, r5, r6, r7); + MUL_ADD_PSM2(u3, r3, r4, r5, r6, r7, r8); + MUL_ADD_PSM2(u4, r4, r5, r6, r7, r8, r9); + + NORM_LSHIFTR(r, 5, 6) + NORM_LSHIFTR(r, 6, 7) + NORM_LSHIFTR(r, 7, 8) + NORM_LSHIFTR(r, 8, 9) + + r[0] = r5; + r[1] = r6; + r[2] = r7; + r[3] = r8; + r[4] = r9; +} + +void MB_FUNC_NAME(ifma_ams52_psm2_)(U64 r[], const U64 va[]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + const U64* vb = va; + + ROUND_MUL(0, 1, r1, r2); + ROUND_MUL(0, 2, r2, r3); + ROUND_MUL(0, 3, r3, r4); + ROUND_MUL(0, 4, r4, r5); + ROUND_MUL(1, 4, r5, r6); + ROUND_MUL(2, 4, r6, r7); + ROUND_MUL(3, 4, r7, r8); + + ROUND_MUL(1, 2, r3, r4); + ROUND_MUL(1, 3, r4, r5); + + ROUND_MUL(2, 3, r5, r6); + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + + ROUND_MUL(0, 0, r0, r1); + ROUND_MUL(1, 1, r2, r3); + ROUND_MUL(2, 2, r4, r5); + ROUND_MUL(3, 3, r6, r7); + ROUND_MUL(4, 4, r8, r9); + + //reduction + MUL_ADD_PSM2(u0, r0, r1, r2, r3, r4, r5); + MUL_ADD_PSM2(u1, r1, r2, r3, r4, r5, r6); + MUL_ADD_PSM2(u2, r2, r3, r4, r5, r6, r7); + MUL_ADD_PSM2(u3, r3, r4, r5, r6, r7, r8); + MUL_ADD_PSM2(u4, r4, r5, r6, r7, r8, r9); + + NORM_LSHIFTR(r, 5, 6) + NORM_LSHIFTR(r, 6, 7) + NORM_LSHIFTR(r, 7, 8) + NORM_LSHIFTR(r, 8, 9) + + r[0] = r5; + r[1] = r6; + r[2] = r7; + r[3] = r8; + r[4] = r9; + +} + +#define sqr_psm2 MB_FUNC_NAME(ifma_ams52_psm2_) +#define mul_psm2 MB_FUNC_NAME(ifma_amm52_psm2_) + +#define sqr_psm2_x2(res,target) \ +{ \ + sqr_psm2(res,target); \ + sqr_psm2(res,res); \ +} + +#define sqr_psm2_x4(res,target) \ +{ \ + sqr_psm2_x2(res,target); \ + sqr_psm2_x2(res,res); \ +} + +#define sqr_psm2_x8(res,target) \ +{ \ + sqr_psm2_x4(res,target); \ + sqr_psm2_x4(res,res); \ +} + +#define sqr_psm2_x16(res,target) \ +{ \ + sqr_psm2_x8(res,target); \ + sqr_psm2_x8(res,res); \ +} + +#define sqr_psm2_x32(res,target) \ +{ \ + sqr_psm2_x16(res,target); \ + sqr_psm2_x16(res,res); \ +} + +#define sqr_psm2_x64(res,target) \ +{ \ + sqr_psm2_x32(res,target); \ + sqr_psm2_x32(res,res); \ +} + +void MB_FUNC_NAME(ifma_aminv52_psm2_)(U64 r[], const U64 z[]) +{ + __ALIGN64 U64 tmp1[PSM2_LEN52]; + __ALIGN64 U64 tmp2[PSM2_LEN52]; + + __ALIGN64 U64 D[PSM2_LEN52]; + __ALIGN64 U64 E[PSM2_LEN52]; + __ALIGN64 U64 F[PSM2_LEN52]; + + sqr_psm2(tmp1,z); + mul_psm2(F,tmp1,z); /* F = z^3 */ + + /* tmp2 = z^0xC */ + sqr_psm2_x2(tmp2,F); + + mul_psm2(D, tmp2, z); /* D = z^0xD */ + mul_psm2(E, tmp2, tmp1); /* E = z^0xE */ + mul_psm2(F, tmp2, F); /* F = z^0xF */ + + /* tmp2 = z^0xF0 */ + sqr_psm2_x4(tmp2,F); + + mul_psm2(D, tmp2, D); /* D = z^0xFD */ + mul_psm2(E, tmp2, E); /* E = z^0xFE */ + mul_psm2(F, tmp2, F); /* F = z^0xFF */ + + /* tmp2 = z^0xFF00 */ + sqr_psm2_x8(tmp2,F); + + mul_psm2(D, tmp2, D); /* D = z^0xFFFD */ + mul_psm2(E, tmp2, E); /* E = z^0xFFFE */ + mul_psm2(F, tmp2, F); /* F = z^0xFFFF */ + + /* tmp2 = z^0xFFFF0000 */ + sqr_psm2_x16(tmp2,F); + + mul_psm2(D, tmp2, D); /* D = z^0xFFFFFFFD */ + mul_psm2(E, tmp2, E); /* E = z^0xFFFFFFFE */ + mul_psm2(F, tmp2, F); /* F = z^0xFFFFFFFF */ + + /* z ^ FFFFFFFE 00000000 */ + sqr_psm2_x32(r,E); + /* z ^ FFFFFFFE FFFFFFFF */ + mul_psm2(r,r,F); + /* z ^ FFFFFFFE FFFFFFFF 00000000 */ + sqr_psm2_x32(r,r); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF */ + mul_psm2(r,r,F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF 00000000 */ + sqr_psm2_x32(r,r); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF */ + mul_psm2(r,r,F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 00000000 */ + sqr_psm2_x32(r,r); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF */ + mul_psm2(r,r,F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 00000000 */ + sqr_psm2_x64(r,r); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF */ + mul_psm2(r,r,F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF 00000000 */ + sqr_psm2_x32(r,r); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFD */ + mul_psm2(r,r,D); + +} + +void MB_FUNC_NAME(ifma_reduce52_psm2_)(U64 R[], const U64 A[]) +{ + /* r = a - p384_mb */ + U64 r0 = sub64(A[0], ((U64*)(psm2_mb))[0]); + U64 r1 = sub64(A[1], ((U64*)(psm2_mb))[1]); + U64 r2 = sub64(A[2], ((U64*)(psm2_mb))[2]); + U64 r3 = sub64(A[3], ((U64*)(psm2_mb))[3]); + U64 r4 = sub64(A[4], ((U64*)(psm2_mb))[4]); + + /* normalize r0 - r4 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + + /* r = a> 1 */ + mask = sub64(get_zero64(), and64(t1, one)); + t0 = add64(t0, and64(base, mask)); + t0 = srli64(t0, 1); + + mask = sub64(get_zero64(), and64(t2, one)); + t1 = add64(t1, and64(base, mask)); + t1 = srli64(t1, 1); + + mask = sub64(get_zero64(), and64(t3, one)); + t2 = add64(t2, and64(base, mask)); + t2 = srli64(t2, 1); + + mask = sub64(get_zero64(), and64(t4, one)); + t3 = add64(t3, and64(base, mask)); + t3 = srli64(t3, 1); + + t4 = srli64(t4, 1); + + /* normalize t0, t1, t2, t3, t4 */ + NORM_LSHIFTR(t, 0,1) + NORM_LSHIFTR(t, 1,2) + NORM_LSHIFTR(t, 2,3) + NORM_LSHIFTR(t, 3,4) + + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; +} + +__mb_mask MB_FUNC_NAME(ifma_cmp_lt_psm2_)(const U64 a[]) +{ + return MB_FUNC_NAME(cmp_lt_FESM2_)(a,(const U64 (*))psm2_mb); +} + +__mb_mask MB_FUNC_NAME(ifma_check_range_psm2_)(const U64 A[]) +{ + __mb_mask + mask = MB_FUNC_NAME(is_zero_FESM2_)(A); + mask |= ~MB_FUNC_NAME(ifma_cmp_lt_psm2_)(A); + + return mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecdh_sm2.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecdh_sm2.c new file mode 100644 index 000000000..0637fd197 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecdh_sm2.c @@ -0,0 +1,256 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes shared key +// pa_shared_key[] array of pointers to the shared keys +// pa_skey[] array of pointers to the own (ephemeral) private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +// +// Note: +// input party's public key depends on is pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates +// or +// - in (x:y) affine coordinate +*/ +DLL_PUBLIC +mbx_status mbx_sm2_ecdh_ssl_mb8(int8u* pa_shared_key[8], + const BIGNUM* const pa_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const BIGNUM* skey = pa_skey[buf_no]; + const BIGNUM* pubx = pa_pubx[buf_no]; + const BIGNUM* puby = pa_puby[buf_no]; + const BIGNUM* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey|| NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[PSM2_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])secretz, (const BIGNUM**)pa_skey, PSM2_BITSIZE); + secretz[PSM2_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, PSM2_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + SM2_POINT P; + + /* set party's public */ + ifma_BN_to_mb8((int64u (*)[8])P.X, (const BIGNUM* (*))pa_pubx, PSM2_BITSIZE); /* P-> radix 2^52 */ + ifma_BN_to_mb8((int64u (*)[8])P.Y, (const BIGNUM* (*))pa_puby, PSM2_BITSIZE); + if(use_jproj_coords) + ifma_BN_to_mb8((int64u (*)[8])P.Z, (const BIGNUM* (*))pa_pubz, PSM2_BITSIZE); + else + MB_FUNC_NAME(mov_FESM2_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_psm2_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_psm2_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + SM2_POINT R; + + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_sm2_mul_point_)(&R, &P, secretz); + + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[PSM2_LEN52]; + ifma_aminv52_psm2_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_psm2_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_psm2_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_psm2_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, PSM2_BITSIZE); + + /* clear computed shared keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_sm2_ecdh_mb8(int8u* pa_shared_key[8], + const int64u* const pa_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_pubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int8u* shared = pa_shared_key[buf_no]; + const int64u* skey = pa_skey[buf_no]; + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==skey || NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded private keys */ + U64 secretz[PSM2_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])secretz, (const int64u**)pa_skey, PSM2_BITSIZE); + secretz[PSM2_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(secretz, PSM2_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + SM2_POINT P; + + /* set party's public */ + ifma_BNU_to_mb8((int64u (*)[8])P.X, (const int64u* (*))pa_pubx, PSM2_BITSIZE); // P-> crypto_mb radix 2^52 + ifma_BNU_to_mb8((int64u (*)[8])P.Y, (const int64u* (*))pa_puby, PSM2_BITSIZE); + if(use_jproj_coords) + ifma_BNU_to_mb8((int64u (*)[8])P.Z, (const int64u* (*))pa_pubz, PSM2_BITSIZE); + else + MB_FUNC_NAME(mov_FESM2_)(P.Z, (U64*)ones); + /* convert to Montgomery */ + MB_FUNC_NAME(ifma_tomont52_psm2_)(P.X, P.X); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P.Y, P.Y); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P.Z, P.Z); + + /* check if P does not belong to EC */ + __mb_mask not_on_curve_mask = ~MB_FUNC_NAME(ifma_is_on_curve_psm2_)(&P, use_jproj_coords); + /* set points out of EC to infinity */ + MB_FUNC_NAME(mask_set_point_to_infinity_)(&P, not_on_curve_mask); + /* update status */ + status |= MBX_SET_STS_BY_MASK(status, not_on_curve_mask, MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + return status; + } + + SM2_POINT R; + + /* compute R = [secretz]*P */ + MB_FUNC_NAME(ifma_ec_sm2_mul_point_)(&R, &P, secretz); + + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])secretz, sizeof(secretz)/sizeof(U64)); + + /* return affine R.x */ + __ALIGN64 U64 Z2[PSM2_LEN52]; + ifma_aminv52_psm2_mb8(Z2, R.Z); /* 1/Z */ + ifma_ams52_psm2_mb8(Z2, Z2); /* 1/Z^2 */ + ifma_amm52_psm2_mb8(R.X, R.X, Z2); /* x = (X) * (1/Z^2) */ + /* to regular domain */ + MB_FUNC_NAME(ifma_frommont52_psm2_)(R.X, R.X); + + /* store result */ + ifma_mb8_to_HexStr8(pa_shared_key, (const int64u (*)[8])R.X, PSM2_BITSIZE); + + /* clear computed shared keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecdsa_sm2.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecdsa_sm2.c new file mode 100755 index 000000000..a7c8d7127 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecdsa_sm2.c @@ -0,0 +1,884 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#include +#ifdef OPENSSL_IS_BORINGSSL +#include +#endif +#endif + +/* constants for Z digest computation */ +/* EC SM2 equation coeficient a, big endian */ +static const int8u a[] = "\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC"; +/* EC SM2 equation coeficient b, big endian */ +static const int8u b[] = "\x28\xE9\xFA\x9E\x9D\x9F\x5E\x34\x4D\x5A\x9E\x4B\xCF\x65\x09\xA7\xF3\x97\x89\xF5\x15\xAB\x8F\x92\xDD\xBC\xBD\x41\x4D\x94\x0E\x93"; +/* x coordinate of the EC SM2 generator point in affine coordinates, big endian */ +static const int8u xG[] = "\x32\xC4\xAE\x2C\x1F\x19\x81\x19\x5F\x99\x04\x46\x6A\x39\xC9\x94\x8F\xE3\x0B\xBF\xF2\x66\x0B\xE1\x71\x5A\x45\x89\x33\x4C\x74\xC7"; +/* y coordinate of the EC SM2 generator point in affine coordinates, big endian */ +static const int8u yG[] = "\xBC\x37\x36\xA2\xF4\xF6\x77\x9C\x59\xBD\xCE\xE3\x6B\x69\x21\x53\xD0\xA9\x87\x7C\xC6\x2A\x47\x40\x02\xDF\x32\xE5\x21\x39\xF0\xA0"; + +static const int8u * pa_a[] = {REP8_DECL( a)}; +static const int8u * pa_b[] = {REP8_DECL( b)}; +static const int8u * pa_xG[] = {REP8_DECL(xG)}; +static const int8u * pa_yG[] = {REP8_DECL(yG)}; + +static int len_2[8] = {REP8_DECL( 2)}; +static int len_32[8] = {REP8_DECL(32)}; + +/* +// common functions +*/ + +/* compute Z digest = SM3( ENTL || ID || a || b ||xG || yG || xA || yA ) */ +static void sm2_ecdsa_compute_z_digest(int8u* pa_z_digest[8], + const int8u* pa_user_id[8], + const int user_id_len[8], + const int8u* pa_pubx[8], + const int8u* pa_puby[8]) +{ + SM3_CTX_mb8 ctx; + SM3_CTX_mb8* p_ctx = &ctx; + + sm3_init_mb8(p_ctx); + + int8u entl_data[8][2]; + const int8u* pa_entl[8]; + + for (int i = 0; i < 8; ++i) + { + int entl = ((user_id_len[i] * 8) & 0xFFFF); + + entl_data[i][1] = entl & 0xFF; + entl_data[i][0] = entl >> 8; + + pa_entl[i] = &(entl_data[i][0]); + } + + sm3_update_mb8(pa_entl, len_2, p_ctx); + + sm3_update_mb8(pa_user_id, (int *)user_id_len, p_ctx); + + sm3_update_mb8(pa_a, len_32, p_ctx); + sm3_update_mb8(pa_b, len_32, p_ctx); + sm3_update_mb8(pa_xG, len_32, p_ctx); + sm3_update_mb8(pa_yG, len_32, p_ctx); + + sm3_update_mb8(pa_pubx, len_32, p_ctx); + sm3_update_mb8(pa_puby, len_32, p_ctx); + + sm3_final_mb8(pa_z_digest, p_ctx); + return; +} + +static void sm2_ecdsa_compute_msg_digest(int8u* pa_msg_digest[8], + const int8u* pa_z_digest[8], + const int8u* pa_msg[8], + const int msg_len[8]) +{ + SM3_CTX_mb8 ctx; + SM3_CTX_mb8* p_ctx = &ctx; + + sm3_init_mb8(p_ctx); + + sm3_update_mb8(pa_z_digest, len_32, p_ctx); + sm3_update_mb8(pa_msg, (int*)msg_len, p_ctx); + + sm3_final_mb8(pa_msg_digest, p_ctx); + return; +} + +static void reverse_inplace(int8u* inp, int len) +{ + for(int i = 0; i < len/2; ++i) { + int8u a = inp[i]; + inp[i] = inp[len - 1 - i]; + inp[len - 1 - i] = a; + } + return; +} + +/* +// SM2_POINT* P - Public key in Jacobian projective coordinates, coordinates are in Montgomery over p +// int64u* pa_rev_bytes_pubX[8] - X coordinate (affine), bytes reversed for future hashing +// int64u* pa_rev_bytes_pubY[8] - Y coordinate (affine), bytes reversed for future hashing +*/ +static mbx_status sm2_ecdsa_process_pubkeys(SM2_POINT* P, + int64u* pa_rev_bytes_pubX[8], + int64u* pa_rev_bytes_pubY[8], + int use_jproj_coords, + mbx_status current_status) +{ + mbx_status status = current_status; + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_psm2_)(P->X), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_psm2_)(P->Y), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(use_jproj_coords) { + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_psm2_)(P->Z), MBX_STATUS_MISMATCH_PARAM_ERR); + + MB_FUNC_NAME(ifma_tomont52_psm2_)(P->X, P->X); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P->Y, P->Y); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P->Z, P->Z); + + __ALIGN64 U64 X[PSM2_LEN52]; + __ALIGN64 U64 Y[PSM2_LEN52]; + + MB_FUNC_NAME(get_sm2_ec_affine_coords_)(X, Y, P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_psm2_)(X, X); + MB_FUNC_NAME(ifma_frommont52_psm2_)(Y, Y); + + /* convert P coordinates to radix 64 */ + ifma_mb8_to_BNU(pa_rev_bytes_pubX, (const int64u (*)[8])X, PSM2_BITSIZE); + ifma_mb8_to_BNU(pa_rev_bytes_pubY, (const int64u (*)[8])Y, PSM2_BITSIZE); + } else { + ifma_mb8_to_BNU(pa_rev_bytes_pubX, (const int64u (*)[8])P->X, PSM2_BITSIZE); + ifma_mb8_to_BNU(pa_rev_bytes_pubY, (const int64u (*)[8])P->Y, PSM2_BITSIZE); + + MB_FUNC_NAME(ifma_tomont52_psm2_)(P->X, P->X); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P->Y, P->Y); + MB_FUNC_NAME(ifma_tomont52_psm2_)(P->Z, (U64*)ones); + } + + for(int i = 0; i < 8; ++i) { + reverse_inplace((int8u*)pa_rev_bytes_pubX[i], PSM2_LEN8); + reverse_inplace((int8u*)pa_rev_bytes_pubY[i], PSM2_LEN8); + } + + return status; +} + +/* compute and check signature components */ +static mbx_status sm2_ecdsa_sign_mb8(U64 sign_r[], + U64 sign_s[], + U64 msg_digest[], + U64 scalar_eph_skey[], + U64 eph_skey[], + U64 reg_skey[], + mbx_status current_status) +{ + mbx_status status = current_status; + + /* compute public keys from ephemeral private keys */ + SM2_POINT P_eph; + + /* (x1, y1) = [k]G */ + MB_FUNC_NAME(ifma_ec_sm2_mul_pointbase_)(&P_eph, scalar_eph_skey); + + /* extract affine P.x */ + MB_FUNC_NAME(get_sm2_ec_affine_coords_)(/* x = */ P_eph.X, /* y = */ NULL, &P_eph); + + MB_FUNC_NAME(ifma_frommont52_psm2_)(P_eph.X, P_eph.X); + /* x = x mod n */ + MB_FUNC_NAME(ifma_fastred52_pnsm2_)(P_eph.X, P_eph.X); + + /* r = (e + x1) mod n */ + MB_FUNC_NAME(ifma_tomont52_nsm2_)(sign_r, P_eph.X); + MB_FUNC_NAME(ifma_tomont52_nsm2_)(msg_digest, msg_digest); + + MB_FUNC_NAME(ifma_add52_nsm2_)(sign_r, sign_r, msg_digest); /* sign_r = (e + x1) */ + + /* check r component */ + MB_FUNC_NAME(ifma_tomont52_nsm2_)(eph_skey, eph_skey); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FESM2_)(sign_r), MBX_STATUS_SIGNATURE_ERR); + + __ALIGN64 U64 tmp[PSM2_LEN52]; + + /* sign_r + eph_skey == n */ + MB_FUNC_NAME(ifma_add52_nsm2_)(tmp, sign_r, eph_skey); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FESM2_)(tmp), MBX_STATUS_SIGNATURE_ERR); + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + MB_FUNC_NAME(zero_)((int64u (*)[8])tmp, sizeof(tmp)/sizeof(U64)); + + /* s = ( (1 + da)^-(1) * (k - r*da) ) */ + MB_FUNC_NAME(ifma_tomont52_nsm2_)(tmp, (U64*)ones); + MB_FUNC_NAME(ifma_tomont52_nsm2_)(reg_skey, reg_skey); + + MB_FUNC_NAME(ifma_amm52_nsm2_)(sign_s, sign_r, reg_skey); /* sign_s = r * da */ + MB_FUNC_NAME(ifma_add52_nsm2_)(reg_skey, reg_skey, tmp); /* reg_skey = 1 + da */ + MB_FUNC_NAME(ifma_aminv52_nsm2_)(reg_skey, reg_skey); /* reg_skey = (1 + da)^(-1) */ + MB_FUNC_NAME(ifma_sub52_nsm2_)(sign_s, eph_skey, sign_s); /* sign_s = k - r * da */ + MB_FUNC_NAME(ifma_amm52_nsm2_)(sign_s, sign_s, reg_skey); /* sign_s = ( (1 + da)^-(1) * (k - r*da) ) */ + + MB_FUNC_NAME(ifma_frommont52_nsm2_)(sign_r, sign_r); + MB_FUNC_NAME(ifma_frommont52_nsm2_)(sign_s, sign_s); + + /* check s component */ + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FESM2_)(sign_s), MBX_STATUS_SIGNATURE_ERR); + + return status; +} + +/* verify signature components */ +static mbx_status sm2_ecdsa_verify_mb8(U64 sign_r[], + U64 sign_s[], + U64 msg_digest[], + SM2_POINT* P, + mbx_status current_status) +{ + mbx_status status = current_status; + + __ALIGN64 U64 t[PSM2_LEN52]; + __ALIGN64 U64 h[PSM2_LEN52]; + /* t = (r + s) mod n */ + MB_FUNC_NAME(ifma_tomont52_nsm2_)(t, sign_r); + MB_FUNC_NAME(ifma_tomont52_nsm2_)(h, sign_s); + + MB_FUNC_NAME(ifma_add52_nsm2_)(t, h, t); /* t = (r + s) */ + + MB_FUNC_NAME(ifma_frommont52_nsm2_)(t, t); + + /* check t != 0 */ + __mb_mask signature_err_mask = MB_FUNC_NAME(is_zero_FE256_)(t); + + __ALIGN64 int64u tmp[8][PSM2_LEN64]; + int64u* pa_tmp[8] = {tmp[0], tmp[1], tmp[2], tmp[3], + tmp[4], tmp[5], tmp[6], tmp[7]}; + + /* (x1`, y1`) = [s]G + [t]P */ + /* convert sign_s to scalar - s */ + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])sign_s, PSM2_BITSIZE); + ifma_BNU_transpose_copy((int64u (*)[8])sign_s, (const int64u(**))pa_tmp, PSM2_BITSIZE); + sign_s[PSM2_LEN64] = get_zero64(); + + SM2_POINT sG; + MB_FUNC_NAME(ifma_ec_sm2_mul_pointbase_)(&sG, sign_s); /* [s]G */ + + /* convert t to scalar - t */ + ifma_mb8_to_BNU(pa_tmp, (const int64u(*)[8])t, PSM2_BITSIZE); + ifma_BNU_transpose_copy((int64u(*)[8])t, (const int64u(**))pa_tmp, PSM2_BITSIZE); + t[PSM2_LEN64] = get_zero64(); + + MB_FUNC_NAME(ifma_ec_sm2_mul_point_)(P, P, t); /* [t]P */ + MB_FUNC_NAME(ifma_ec_sm2_add_point_)(P, P, &sG); /* P = [s]G + [t]P */ + + __ALIGN64 U64 sign_r_restored[PSM2_LEN52]; + + /* extract affine P.x */ + MB_FUNC_NAME(get_sm2_ec_affine_coords_)(/* x = */ sign_r_restored, /* y = */ NULL, P); + + /* form Montgomery domain | x = x mod n */ + MB_FUNC_NAME(ifma_frommont52_psm2_)(sign_r_restored, sign_r_restored); + MB_FUNC_NAME(ifma_fastred52_pnsm2_)(sign_r_restored, sign_r_restored); + + /* r = (e + x1) mod n */ + MB_FUNC_NAME(ifma_tomont52_nsm2_)(sign_r_restored, sign_r_restored); + MB_FUNC_NAME(ifma_tomont52_nsm2_)(msg_digest, msg_digest); + + MB_FUNC_NAME(ifma_add52_nsm2_)(sign_r_restored, sign_r_restored, msg_digest); + + MB_FUNC_NAME(ifma_frommont52_nsm2_)(sign_r_restored, sign_r_restored); + + /* check equal */ + signature_err_mask |= ~(MB_FUNC_NAME(cmp_eq_FESM2_)(sign_r_restored, sign_r)); + + status |= MBX_SET_STS_BY_MASK(status, signature_err_mask, MBX_STATUS_SIGNATURE_ERR); + return status; +} + +/* +// Computes SM2 ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_user_id[] array of pointers to the users ID +// user_id_len[] array of users ID length +// pa_msg[] array of pointers to the messages are being signed +// msg_len[] array of messages length +// pa_eph_skey[] array of pointers to the signer's ephemeral private keys +// pa_reg_skey[] array of pointers to the signer's regular private keys +// pa_pubx[] array of pointers to the party's public keys X-coordinates +// pa_puby[] array of pointers to the party's public keys Y-coordinates +// pa_pubz[] array of pointers to the party's public keys Z-coordinates +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_sm2_ecdsa_sign_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const int64u* const pa_eph_skey[8], + const int64u* const pa_reg_skey[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_user_id || NULL==user_id_len || NULL==pa_msg || + NULL==msg_len || NULL==pa_eph_skey || NULL==pa_reg_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + int user_id_len_checked[8]; + + /* check pointers and values */ + for(int buf_no=0; buf_no<8; buf_no++) { + const int8u* r = pa_sign_r[buf_no]; + const int8u* s = pa_sign_s[buf_no]; + const int8u* id = pa_user_id[buf_no]; + const int8u* msg = pa_msg[buf_no]; + const int64u* eph_key = pa_eph_skey[buf_no]; + const int64u* reg_key = pa_reg_skey[buf_no]; + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + user_id_len_checked[buf_no] = user_id_len[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==r || NULL==s || NULL==id || NULL==msg || NULL==eph_key || + NULL==reg_key || NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + if (msg_len[buf_no] < 0) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + if ((user_id_len[buf_no] > 0xFFFF) || (user_id_len[buf_no] < 0)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + user_id_len_checked[buf_no] = 0; + } + } + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + /* load and check secret keys */ + + __ALIGN64 U64 reg_skey[PSM2_LEN52]; + __ALIGN64 U64 eph_skey[PSM2_LEN52]; + + ifma_BNU_to_mb8((int64u (*)[8])reg_skey, pa_reg_skey, PSM2_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])eph_skey, pa_eph_skey, PSM2_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FESM2_)(reg_skey), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FESM2_)(eph_skey), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])eph_skey, sizeof(eph_skey)/sizeof(U64)); + return status; + } + + __ALIGN64 int64u rev_bytes_pubX[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubX[8] = {rev_bytes_pubX[0], rev_bytes_pubX[1], rev_bytes_pubX[2], rev_bytes_pubX[3], rev_bytes_pubX[4], rev_bytes_pubX[5], rev_bytes_pubX[6], rev_bytes_pubX[7]}; + + __ALIGN64 int64u rev_bytes_pubY[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubY[8] = {rev_bytes_pubY[0], rev_bytes_pubY[1], rev_bytes_pubY[2], rev_bytes_pubY[3], rev_bytes_pubY[4], rev_bytes_pubY[5], rev_bytes_pubY[6], rev_bytes_pubY[7]}; + + SM2_POINT P; + + ifma_BNU_to_mb8((int64u (*)[8])P.X, (const int64u* (*))pa_pubx, PSM2_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])P.Y, (const int64u* (*))pa_puby, PSM2_BITSIZE); + + if(use_jproj_coords) { + ifma_BNU_to_mb8((int64u (*)[8])P.Z, (const int64u* (*))pa_pubz, PSM2_BITSIZE); + } + + status = sm2_ecdsa_process_pubkeys(&P, + pa_rev_bytes_pubX, + pa_rev_bytes_pubY, + use_jproj_coords, + status); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])eph_skey, sizeof(eph_skey)/sizeof(U64)); + return status; + } + + __ALIGN64 int8u msg_digest[8][PSM2_LEN8]; + int8u* pa_msg_digest[8] = {msg_digest[0], msg_digest[1], msg_digest[2], msg_digest[3], msg_digest[4], msg_digest[5], msg_digest[6], msg_digest[7]}; + + /* compute z digest */ + sm2_ecdsa_compute_z_digest(pa_msg_digest, + (const int8u **)pa_user_id, + (const int *)user_id_len_checked, + (const int8u **)pa_rev_bytes_pubX, + (const int8u **)pa_rev_bytes_pubY); + + /* compute msg digest */ + sm2_ecdsa_compute_msg_digest(pa_msg_digest, + (const int8u **)pa_msg_digest, + (const int8u **)pa_msg, + (const int *)msg_len); + + /* zero padded keys */ + U64 scalar_eph_skey[PSM2_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalar_eph_skey, pa_eph_skey, PSM2_BITSIZE); + scalar_eph_skey[PSM2_LEN64] = get_zero64(); + + __ALIGN64 U64 sign_r[PSM2_LEN52]; + __ALIGN64 U64 sign_s[PSM2_LEN52]; + + __ALIGN64 U64 msg[PSM2_LEN52]; + ifma_HexStr8_to_mb8((int64u (*)[8])msg, (const int8u* const*)pa_msg_digest, PSM2_BITSIZE); + + /* compute and check signature components */ + status = sm2_ecdsa_sign_mb8(sign_r, + sign_s, + msg, + scalar_eph_skey, + eph_skey, + reg_skey, + status); + + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar_eph_skey, sizeof(scalar_eph_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])eph_skey, sizeof(eph_skey)/sizeof(U64)); + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, PSM2_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, PSM2_BITSIZE); + + return status; +} + +/* +// Verifies SM2 ECDSA signature +// pa_sign_r[] array of pointers to the computed r-components of the signatures +// pa_sign_s[] array of pointers to the computed s-components of the signatures +// pa_msg[] array of pointers to the messages that have been signed +// pa_user_id[] array of pointers to the users ID +// user_id_len[] array of users ID length +// pa_msg[] array of pointers to the messages are being signed +// msg_len[] array of messages length +// pa_pubx[] array of pointers to the signer's public keys X-coordinates +// pa_puby[] array of pointers to the signer's public keys Y-coordinates +// pa_pubz[] array of pointers to the signer's public keys Z-coordinates (or NULL, if affine coordinate requested) +// pBuffer pointer to the scratch buffer +*/ +DLL_PUBLIC +mbx_status mbx_sm2_ecdsa_verify_mb8(const int8u* const pa_sign_r[8], + const int8u* const pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const int64u* const pa_pubx[8], + const int64u* const pa_puby[8], + const int64u* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_user_id || NULL==user_id_len || + NULL==pa_msg || NULL==msg_len || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + int user_id_len_checked[8]; + + /* check pointers and values */ + for(int buf_no=0; buf_no<8; buf_no++) { + const int8u* r = pa_sign_r[buf_no]; + const int8u* s = pa_sign_s[buf_no]; + const int8u* id = pa_user_id[buf_no]; + const int8u* msg = pa_msg[buf_no]; + const int64u* pubx = pa_pubx[buf_no]; + const int64u* puby = pa_puby[buf_no]; + const int64u* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + user_id_len_checked[buf_no] = user_id_len[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==r || NULL==s || NULL==id || NULL==msg || + NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + if (msg_len[buf_no] < 0) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + if ((user_id_len[buf_no] > 0xFFFF) || (user_id_len[buf_no] < 0)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + user_id_len_checked[buf_no] = 0; + } + } + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + __ALIGN64 U64 sign_r[PSM2_LEN52]; + __ALIGN64 U64 sign_s[PSM2_LEN52]; + + ifma_HexStr8_to_mb8((int64u (*)[8])sign_r, (const int8u* const*)pa_sign_r, PSM2_BITSIZE); + ifma_HexStr8_to_mb8((int64u (*)[8])sign_s, (const int8u* const*)pa_sign_s, PSM2_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_nsm2_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_nsm2_)(sign_s), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __ALIGN64 int64u rev_bytes_pubX[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubX[8] = {rev_bytes_pubX[0], rev_bytes_pubX[1], rev_bytes_pubX[2], rev_bytes_pubX[3], rev_bytes_pubX[4], rev_bytes_pubX[5], rev_bytes_pubX[6], rev_bytes_pubX[7]}; + + __ALIGN64 int64u rev_bytes_pubY[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubY[8] = {rev_bytes_pubY[0], rev_bytes_pubY[1], rev_bytes_pubY[2], rev_bytes_pubY[3], rev_bytes_pubY[4], rev_bytes_pubY[5], rev_bytes_pubY[6], rev_bytes_pubY[7]}; + + SM2_POINT P; + + ifma_BNU_to_mb8((int64u (*)[8])P.X, (const int64u* (*))pa_pubx, PSM2_BITSIZE); + ifma_BNU_to_mb8((int64u (*)[8])P.Y, (const int64u* (*))pa_puby, PSM2_BITSIZE); + + if(use_jproj_coords) { + ifma_BNU_to_mb8((int64u (*)[8])P.Z, (const int64u* (*))pa_pubz, PSM2_BITSIZE); + } + + status = sm2_ecdsa_process_pubkeys(&P, + pa_rev_bytes_pubX, + pa_rev_bytes_pubY, + use_jproj_coords, + status); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __ALIGN64 int8u msg_digest[8][PSM2_LEN8]; + int8u* pa_msg_digest[8] = {msg_digest[0], msg_digest[1], msg_digest[2], msg_digest[3], msg_digest[4], msg_digest[5], msg_digest[6], msg_digest[7]}; + + /* compute z digest */ + sm2_ecdsa_compute_z_digest(pa_msg_digest, + (const int8u **)pa_user_id, + (const int *)user_id_len_checked, + (const int8u **)pa_rev_bytes_pubX, + (const int8u **)pa_rev_bytes_pubY); + + /* compute msg digest */ + sm2_ecdsa_compute_msg_digest(pa_msg_digest, + (const int8u **)pa_msg_digest, + (const int8u **)pa_msg, + (const int *)msg_len); + + __ALIGN64 U64 msg[PSM2_LEN52]; + ifma_HexStr8_to_mb8((int64u (*)[8])msg, (const int8u* const*)pa_msg_digest, PSM2_BITSIZE); + + status = sm2_ecdsa_verify_mb8(sign_r, sign_s, msg, &P, status); + + return status; +} + +/* +// OpenSSL's specific implementations +*/ +#ifndef BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_sm2_ecdsa_sign_ssl_mb8(int8u* pa_sign_r[8], + int8u* pa_sign_s[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const BIGNUM* const pa_eph_skey[8], + const BIGNUM* const pa_reg_skey[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_sign_r || NULL==pa_sign_s || NULL==pa_user_id || NULL==user_id_len || NULL==pa_msg || + NULL==msg_len || NULL==pa_eph_skey || NULL==pa_reg_skey || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + int user_id_len_checked[8]; + + /* check pointers and values */ + for(int buf_no=0; buf_no<8; buf_no++) { + const int8u* r = pa_sign_r[buf_no]; + const int8u* s = pa_sign_s[buf_no]; + const int8u* id = pa_user_id[buf_no]; + const int8u* msg = pa_msg[buf_no]; + const BIGNUM* eph_key = pa_eph_skey[buf_no]; + const BIGNUM* reg_key = pa_reg_skey[buf_no]; + const BIGNUM* pubx = pa_pubx[buf_no]; + const BIGNUM* puby = pa_puby[buf_no]; + const BIGNUM* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + user_id_len_checked[buf_no] = user_id_len[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==r || NULL==s || NULL==id || NULL==msg || NULL==eph_key || + NULL==reg_key || NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + if (msg_len[buf_no] < 0) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + if ((user_id_len[buf_no] > 0xFFFF) || (user_id_len[buf_no] < 0)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + user_id_len_checked[buf_no] = 0; + } + } + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + /* load and check secret keys */ + + __ALIGN64 U64 reg_skey[PSM2_LEN52]; + __ALIGN64 U64 eph_skey[PSM2_LEN52]; + + ifma_BN_to_mb8((int64u (*)[8])reg_skey, pa_reg_skey, PSM2_BITSIZE); + ifma_BN_to_mb8((int64u (*)[8])eph_skey, pa_eph_skey, PSM2_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FESM2_)(reg_skey), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(is_zero_FESM2_)(eph_skey), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])eph_skey, sizeof(eph_skey)/sizeof(U64)); + return status; + } + + __ALIGN64 int64u rev_bytes_pubX[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubX[8] = {rev_bytes_pubX[0], rev_bytes_pubX[1], rev_bytes_pubX[2], rev_bytes_pubX[3], rev_bytes_pubX[4], rev_bytes_pubX[5], rev_bytes_pubX[6], rev_bytes_pubX[7]}; + + __ALIGN64 int64u rev_bytes_pubY[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubY[8] = {rev_bytes_pubY[0], rev_bytes_pubY[1], rev_bytes_pubY[2], rev_bytes_pubY[3], rev_bytes_pubY[4], rev_bytes_pubY[5], rev_bytes_pubY[6], rev_bytes_pubY[7]}; + + SM2_POINT P; + + ifma_BN_to_mb8((int64u (*)[8])P.X, pa_pubx, PSM2_BITSIZE); + ifma_BN_to_mb8((int64u (*)[8])P.Y, pa_puby, PSM2_BITSIZE); + + if(use_jproj_coords) { + ifma_BN_to_mb8((int64u (*)[8])P.Z, pa_pubz, PSM2_BITSIZE); + } + + status = sm2_ecdsa_process_pubkeys(&P, + pa_rev_bytes_pubX, + pa_rev_bytes_pubY, + use_jproj_coords, + status); + + if(!MBX_IS_ANY_OK_STS(status)) { + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])eph_skey, sizeof(eph_skey)/sizeof(U64)); + return status; + } + + __ALIGN64 int8u msg_digest[8][PSM2_LEN8]; + int8u* pa_msg_digest[8] = {msg_digest[0], msg_digest[1], msg_digest[2], msg_digest[3], msg_digest[4], msg_digest[5], msg_digest[6], msg_digest[7]}; + + /* compute z digest */ + sm2_ecdsa_compute_z_digest(pa_msg_digest, + (const int8u **)pa_user_id, + (const int *)user_id_len_checked, + (const int8u **)pa_rev_bytes_pubX, + (const int8u **)pa_rev_bytes_pubY); + + /* compute msg digest */ + sm2_ecdsa_compute_msg_digest(pa_msg_digest, + (const int8u **)pa_msg_digest, + (const int8u **)pa_msg, + (const int *)msg_len); + + /* zero padded keys */ + U64 scalar_eph_skey[PSM2_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])scalar_eph_skey, pa_eph_skey, PSM2_BITSIZE); + scalar_eph_skey[PSM2_LEN64] = get_zero64(); + + __ALIGN64 U64 sign_r[PSM2_LEN52]; + __ALIGN64 U64 sign_s[PSM2_LEN52]; + + __ALIGN64 U64 msg[PSM2_LEN52]; + ifma_HexStr8_to_mb8((int64u (*)[8])msg, (const int8u* const*)pa_msg_digest, PSM2_BITSIZE); + + /* compute and check signature components */ + status = sm2_ecdsa_sign_mb8(sign_r, + sign_s, + msg, + scalar_eph_skey, + eph_skey, + reg_skey, + status); + + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar_eph_skey, sizeof(scalar_eph_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])reg_skey, sizeof(reg_skey)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])eph_skey, sizeof(eph_skey)/sizeof(U64)); + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + ifma_mb8_to_HexStr8(pa_sign_r, (const int64u(*)[8])sign_r, PSM2_BITSIZE); + ifma_mb8_to_HexStr8(pa_sign_s, (const int64u(*)[8])sign_s, PSM2_BITSIZE); + + return status; +} + +DLL_PUBLIC +mbx_status mbx_sm2_ecdsa_verify_ssl_mb8(const ECDSA_SIG* const pa_sig[8], + const int8u* const pa_user_id[8], + const int user_id_len[8], + const int8u* const pa_msg[8], + const int msg_len[8], + const BIGNUM* const pa_pubx[8], + const BIGNUM* const pa_puby[8], + const BIGNUM* const pa_pubz[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_sig || NULL==pa_user_id || NULL==user_id_len || NULL==pa_msg || + NULL==msg_len || NULL==pa_pubx || NULL==pa_puby) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + int user_id_len_checked[8]; + + /* check pointers and values */ + for(int buf_no=0; buf_no<8; buf_no++) { + const ECDSA_SIG* sig = pa_sig[buf_no]; + const int8u* id = pa_user_id[buf_no]; + const int8u* msg = pa_msg[buf_no]; + const BIGNUM* pubx = pa_pubx[buf_no]; + const BIGNUM* puby = pa_puby[buf_no]; + const BIGNUM* pubz = use_jproj_coords? pa_pubz[buf_no] : NULL; + + user_id_len_checked[buf_no] = user_id_len[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==sig || NULL==id || NULL==msg || + NULL==pubx || NULL==puby || (use_jproj_coords && NULL==pubz)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + if (msg_len[buf_no] < 0) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + if ((user_id_len[buf_no] > 0xFFFF) || (user_id_len[buf_no] < 0)) { + status |= MBX_SET_STS(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + user_id_len_checked[buf_no] = 0; + } + } + + if(!MBX_IS_ANY_OK_STS(status) ) + return status; + + BIGNUM* pa_sign_r[8] = { 0,0,0,0,0,0,0,0 }; + BIGNUM* pa_sign_s[8] = { 0,0,0,0,0,0,0,0 }; + + for (int buf_no = 0; buf_no < 8; buf_no++) + { + if(pa_sig[buf_no] != NULL) + { + ECDSA_SIG_get0(pa_sig[buf_no], (const BIGNUM(**))pa_sign_r + buf_no, + (const BIGNUM(**))pa_sign_s + buf_no); + } + } + + __ALIGN64 U64 sign_r[PSM2_LEN52]; + __ALIGN64 U64 sign_s[PSM2_LEN52]; + + ifma_BN_to_mb8((int64u (*)[8])sign_r, (const BIGNUM(**))pa_sign_r, PSM2_BITSIZE); + ifma_BN_to_mb8((int64u (*)[8])sign_s, (const BIGNUM(**))pa_sign_s, PSM2_BITSIZE); + + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_nsm2_)(sign_r), MBX_STATUS_MISMATCH_PARAM_ERR); + status |= MBX_SET_STS_BY_MASK(status, MB_FUNC_NAME(ifma_check_range_nsm2_)(sign_s), MBX_STATUS_MISMATCH_PARAM_ERR); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __ALIGN64 int64u rev_bytes_pubX[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubX[8] = {rev_bytes_pubX[0], rev_bytes_pubX[1], rev_bytes_pubX[2], rev_bytes_pubX[3], rev_bytes_pubX[4], rev_bytes_pubX[5], rev_bytes_pubX[6], rev_bytes_pubX[7]}; + + __ALIGN64 int64u rev_bytes_pubY[8][PSM2_LEN64]; + int64u* pa_rev_bytes_pubY[8] = {rev_bytes_pubY[0], rev_bytes_pubY[1], rev_bytes_pubY[2], rev_bytes_pubY[3], rev_bytes_pubY[4], rev_bytes_pubY[5], rev_bytes_pubY[6], rev_bytes_pubY[7]}; + + SM2_POINT P; + + ifma_BN_to_mb8((int64u (*)[8])P.X, pa_pubx, PSM2_BITSIZE); + ifma_BN_to_mb8((int64u (*)[8])P.Y, pa_puby, PSM2_BITSIZE); + + if(use_jproj_coords) { + ifma_BN_to_mb8((int64u (*)[8])P.Z, pa_pubz, PSM2_BITSIZE); + } + + status = sm2_ecdsa_process_pubkeys(&P, + pa_rev_bytes_pubX, + pa_rev_bytes_pubY, + use_jproj_coords, + status); + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + __ALIGN64 int8u msg_digest[8][PSM2_LEN8]; + int8u* pa_msg_digest[8] = {msg_digest[0], msg_digest[1], msg_digest[2], msg_digest[3], msg_digest[4], msg_digest[5], msg_digest[6], msg_digest[7]}; + + /* compute z digest */ + sm2_ecdsa_compute_z_digest(pa_msg_digest, + (const int8u **)pa_user_id, + (const int *)user_id_len_checked, + (const int8u **)pa_rev_bytes_pubX, + (const int8u **)pa_rev_bytes_pubY); + + /* compute msg digest */ + sm2_ecdsa_compute_msg_digest(pa_msg_digest, + (const int8u **)pa_msg_digest, + (const int8u **)pa_msg, + (const int *)msg_len); + + __ALIGN64 U64 msg[PSM2_LEN52]; + ifma_HexStr8_to_mb8((int64u (*)[8])msg, (const int8u* const*)pa_msg_digest, PSM2_BITSIZE); + + status = sm2_ecdsa_verify_mb8(sign_r, sign_s, msg, &P, status); + + return status; +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecpoint_sm2.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecpoint_sm2.c new file mode 100644 index 000000000..65dc22877 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecpoint_sm2.c @@ -0,0 +1,695 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include + +/* simplify naming */ +#define sqr MB_FUNC_NAME(ifma_ams52_psm2_) +#define mul MB_FUNC_NAME(ifma_amm52_psm2_) +#define add MB_FUNC_NAME(ifma_add52_psm2_) +#define sub MB_FUNC_NAME(ifma_sub52_psm2_) +#define mul2 MB_FUNC_NAME(ifma_double52_psm2_) +#define mul3 MB_FUNC_NAME(ifma_tripple52_psm2_) +#define div2 MB_FUNC_NAME(ifma_half52_psm2_) + +/* +// Presentation of point at infinity: +// - projective (X : Y : 0) +// - affine (0 : 0) +*/ + +/* +// R(X3:Y3:Z3) = [2]P(X1:Y1:Z1) +// +// formulas: +// A = 4*X1*Y1^2 +// B = 3*(X1^2-Z1^4) +// X3= B^2 -2*A +// Y3= B*(A-X3) -8*Y1^4 +// Z3= 2*Y1*Z1 +// +// cost: 4S+4M+9A +// +*/ +void MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(SM2_POINT* r, const SM2_POINT* p) +{ + __ALIGN64 U64 T[PSM2_LEN52]; + __ALIGN64 U64 U[PSM2_LEN52]; + __ALIGN64 U64 V[PSM2_LEN52]; + __ALIGN64 U64 A[PSM2_LEN52]; + __ALIGN64 U64 B[PSM2_LEN52]; + + const U64* X1 = p->X; /* input point */ + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + U64* X3 = r->X; /* output point */ + U64* Y3 = r->Y; + U64* Z3 = r->Z; + + mul2(T, Y1); /* T = 2*Y1 */ + + sqr(V, T); /* V = 4*Y1^2 */ /* sqr_dual */ + sqr(U, Z1); /* U = Z1^2 */ + + sub(B, X1, U); /* B = X1-Z1^2 */ + add(U, X1, U); /* U = X1+Z1^2 */ + + mul(A, V, X1); /* A = 4*X*Y1^2 */ /* mul_dual */ + mul(B, B, U); /* B = (X1^2-Z1^4) */ + + mul2(X3, A); /* X3 = 2*A */ + mul3(B, B); /* B = 3*(X1^2-Z1^4) */ + + sqr(U, B); /* U = B^2 */ /* sqr_dual */ + sqr(Y3, V); /* Y3= V^2 = 16*Y1^4 */ + + sub(X3, U, X3); /* X3=B^2 - 2*A */ + div2(Y3,Y3); /* Y3=Y3/2 = 8*Y1^4 */ + + sub(U, A, X3); /* U = A-X3 */ + + mul(Z3, T, Z1); /* Z3= 2*Y1*Z1 */ /* mul_dual */ + mul(U, U, B); /* U = B*(A-X3) */ + + sub(Y3, U, Y3); /* Y3 = B*(A-X3) -8*Y1^4 */ +} + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// cost: 4S+12M+7A +// +*/ +void MB_FUNC_NAME(ifma_ec_sm2_add_point_)(SM2_POINT* r, const SM2_POINT* p, const SM2_POINT* q) +{ + /* coordinates of p */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q */ + const U64* X2 = q->X; + const U64* Y2 = q->Y; + const U64* Z2 = q->Z; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->Z); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[PSM2_LEN52]; + __ALIGN64 U64 Y3[PSM2_LEN52]; + __ALIGN64 U64 Z3[PSM2_LEN52]; + + /* temporary */ + __ALIGN64 U64 U1[PSM2_LEN52]; + __ALIGN64 U64 U2[PSM2_LEN52]; + __ALIGN64 U64 S1[PSM2_LEN52]; + __ALIGN64 U64 S2[PSM2_LEN52]; + __ALIGN64 U64 H[PSM2_LEN52]; + __ALIGN64 U64 R[PSM2_LEN52]; + + mul(S1, Y1, Z2); /* S1 = Y1*Z2 */ + sqr(U1, Z2); /* U1 = Z2^2 */ + + mul(S2, Y2, Z1); /* S2 = Y2*Z1 */ + sqr(U2, Z1); /* U2 = Z1^2 */ + + mul(S1, S1, U1); /* S1 = Y1*Z2^3 */ + mul(S2, S2, U2); /* S2 = Y2*Z1^3 */ + + mul(U1, X1, U1); /* U1 = X1*Z2^2 */ + mul(U2, X2, U2); /* U2 = X2*Z1^2 */ + + sub(R, S2, S1); /* R = S2-S1 */ + sub(H, U2, U1); /* H = U2-U1 */ + + + /* check if affine (p.x:p.y) == (q.x:q.y) and and do doubling if this happens */ + __mb_mask x_are_equal = MB_FUNC_NAME(is_zero_FESM2_)(H); + __mb_mask y_are_equal = MB_FUNC_NAME(is_zero_FESM2_)(R); + __mb_mask points_are_equal = (x_are_equal & y_are_equal & (~p_at_infinity) & (~q_at_infinity)); + + SM2_POINT P2; + MB_FUNC_NAME(set_point_to_infinity_)(&P2); + if (points_are_equal) { + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&P2, p); + } + + mul(Z3, Z1, Z2); /* Z3 = Z1*Z2 */ + sqr(U2, H); /* U2 = H^2 */ + mul(Z3, Z3, H); /* Z3 = (Z1*Z2)*H */ + sqr(S2, R); /* S2 = R^2 */ + mul(H, H, U2); /* H = H^3 */ + + mul(U1, U1, U2); /* U1 = U1*H^2 */ + sub(X3, S2, H); /* X3 = R^2 - H^3 */ + mul2(U2, U1); /* U2 = 2*U1*H^2 */ + mul(S1, S1, H); /* S1 = S1*H^3 */ + sub(X3, X3, U2); /* X3 = (R^2 - H^3) -2*U1*H^2 */ + + sub(Y3, U1, X3); /* Y3 = R*(U1*H^2 - X3) -S1*H^3 */ + mul(Y3, Y3, R); + sub(Y3, Y3, S1); + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FESM2_)(X3, X3, p_at_infinity, q->X); + MB_FUNC_NAME(mask_mov_FESM2_)(Y3, Y3, p_at_infinity, q->Y); + MB_FUNC_NAME(mask_mov_FESM2_)(Z3, Z3, p_at_infinity, q->Z); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FESM2_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FESM2_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FESM2_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = points_are_equal? P2 : T */ + MB_FUNC_NAME(mask_mov_FESM2_)(r->X, X3, points_are_equal, P2.X); + MB_FUNC_NAME(mask_mov_FESM2_)(r->Y, Y3, points_are_equal, P2.Y); + MB_FUNC_NAME(mask_mov_FESM2_)(r->Z, Z3, points_are_equal, P2.Z); +} + + +/* to Montgomery conversion constant +// r = 2^(PSM2_LEN52*DIGIT_SIZE) mod psm2 +*/ +__ALIGN64 static const int64u psm2_r_mb[PSM2_LEN52][sizeof(U64)/sizeof(int64u)] = { + { REP8_DECL(0x0000000000000010) }, + { REP8_DECL(0x0000ffffffff0000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000000000) }, + { REP8_DECL(0x0000000000100000) } +}; +const U64* MB_FUNC_NAME(ifma_ec_sm2_coord_one_)(void) +{ + return (U64*)psm2_r_mb; +} + + +/* +// R(X3:Y3:Z3) = P(X1:Y1:Z1) + Q(X2:Y2:Z2=1) +// +// formulas: +// A = X1*Z2^2 B = X2*Z1^2 C = Y1*Z2^3 D = Y2*Z1^3 +// E = B-A F = D-C +// X3= -E^3 -2*A*E^2 + F^2 +// Y3= -C*E^3 + F*(A*E^2 -X3) +// Z3= Z1*Z2*E +// +// if Z2=1, then +// A = X1 B = X2*Z1^2 C = Y1 D = Y2*Z1^3 +// E = B-X1 F = D-Y1 +// X3= -E^3 -2*X1*E^2 + F^2 +// Y3= -Y1*E^3 + F*(X1*E^2 -X3) +// Z3= Z1*E +// +// cost: 3S+8M+7A +*/ +void MB_FUNC_NAME(ifma_ec_sm2_add_point_affine_)(SM2_POINT* r, const SM2_POINT* p, const SM2_POINT_AFFINE* q) +{ + /* coordinates of p (projective) */ + const U64* X1 = p->X; + const U64* Y1 = p->Y; + const U64* Z1 = p->Z; + __mb_mask p_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(p->Z); + + /* coordinates of q (affine) */ + const U64* X2 = q->x; + const U64* Y2 = q->y; + __mb_mask q_at_infinity = MB_FUNC_NAME(is_zero_point_cordinate_)(q->x) + & MB_FUNC_NAME(is_zero_point_cordinate_)(q->y); + + /* coordinates of temp point T(X3:Y3:Z3) */ + __ALIGN64 U64 X3[PSM2_LEN52]; + __ALIGN64 U64 Y3[PSM2_LEN52]; + __ALIGN64 U64 Z3[PSM2_LEN52]; + + __ALIGN64 U64 U2[PSM2_LEN52]; + __ALIGN64 U64 S2[PSM2_LEN52]; + __ALIGN64 U64 H[PSM2_LEN52]; + __ALIGN64 U64 R[PSM2_LEN52]; + + sqr(R, Z1); // R = Z1^2 + mul(S2, Y2, Z1); // S2 = Y2*Z1 + mul(U2, X2, R); // U2 = X2*Z1^2 + mul(S2, S2, R); // S2 = Y2*Z1^3 + + sub(H, U2, X1); // H = U2-X1 + sub(R, S2, Y1); // R = S2-Y1 + + mul(Z3, H, Z1); // Z3 = H*Z1 + + sqr(U2, H); // U2 = H^2 + sqr(S2, R); // S2 = R^2 + mul(H, H, U2); // H = H^3 + + mul(U2, U2, X1); // U2 = X1*H^2 + + mul(Y3, H, Y1); // T = Y1*H^3 + + mul2(X3, U2); // X3 = 2*X1*H^2 + sub(X3, S2, X3); // X3 = R^2 - 2*X1*H^2 + sub(X3, X3, H); // X3 = R^2 - 2*X1*H^2 -H^3 + + sub(U2, U2, X3); // U2 = X1*H^2 - X3 + mul(U2, U2, R); // U2 = R*(X1*H^2 - X3) + sub(Y3, U2, Y3); // Y3 = -Y1*H^3 + R*(X1*H^2 - X3) + + /* T = p_at_infinity? q : T */ + MB_FUNC_NAME(mask_mov_FESM2_)(X3, X3, p_at_infinity, q->x); + MB_FUNC_NAME(mask_mov_FESM2_)(Y3, Y3, p_at_infinity, q->y); + MB_FUNC_NAME(mask_mov_FESM2_)(Z3, Z3, p_at_infinity, (U64*)psm2_r_mb); + /* T = q_at_infinity? p : T */ + MB_FUNC_NAME(mask_mov_FESM2_)(X3, X3, q_at_infinity, p->X); + MB_FUNC_NAME(mask_mov_FESM2_)(Y3, Y3, q_at_infinity, p->Y); + MB_FUNC_NAME(mask_mov_FESM2_)(Z3, Z3, q_at_infinity, p->Z); + + /* r = T */ + MB_FUNC_NAME(mov_FESM2_)(r->X, X3); + MB_FUNC_NAME(mov_FESM2_)(r->Y, Y3); + MB_FUNC_NAME(mov_FESM2_)(r->Z, Z3); +} + +void MB_FUNC_NAME(get_sm2_ec_affine_coords_)(U64 x[], U64 y[], const SM2_POINT* P) +{ + __ALIGN64 U64 invZ1[PSM2_LEN52]; + __ALIGN64 U64 invZn[PSM2_LEN52]; + + /* 1/Z and 1/Z^2 */ + MB_FUNC_NAME(ifma_aminv52_psm2_)(invZ1, P->Z); + MB_FUNC_NAME(ifma_ams52_psm2_)(invZn, invZ1); + + /* if affine P.x requested */ + if(x) + MB_FUNC_NAME(ifma_amm52_psm2_)(x, P->X, invZn); + + /* if affine P.y requested */ + if(y) { + MB_FUNC_NAME(ifma_amm52_psm2_)(invZn, invZn, invZ1); + MB_FUNC_NAME(ifma_amm52_psm2_)(y, P->Y, invZn); + } +} + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +static __NOINLINE void clear_secret_context(U64* wval, U64* dval, __mb_mask* dsign) +{ + *wval = get_zero64(); + *dval = get_zero64(); + *dsign = 0; + return; +} + +#define WIN_SIZE (4) + +/* + s = (Ipp8u)(~((wvalue >> ws) - 1)); //sign + d = (1 << (ws+1)) - wvalue - 1; // digit, win size "ws" + d = (d & s) | (wvaluen & ~s); + d = (d >> 1) + (d & 1); + *sign = s & 1; + *digit = (Ipp8u)d; +*/ +__INLINE void MB_FUNC_NAME(booth_recode_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract point */ +static void MB_FUNC_NAME(extract_point_)(SM2_POINT* r, const SM2_POINT tbl[], U64 idx) +{ + /* decrenent index (the table noes not contain [0]*P */ + U64 idx_target = sub64(idx, set1(1)); + + /* assume the point at infinity is what need */ + SM2_POINT R; + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + /* find out what we actually need or just keep original infinity */ + int32u n; + for(n=0; n<(1<<(WIN_SIZE-1)); n++) { + U64 idx_curr = set1(n); + __mb_mask k = cmp64_mask(idx_curr, idx_target, _MM_CMPINT_EQ); + + /* R = k? tbl[] : R */ + MB_FUNC_NAME(secure_mask_mov_FESM2_)(R.X, R.X, k, tbl[n].X); + MB_FUNC_NAME(secure_mask_mov_FESM2_)(R.Y, R.Y, k, tbl[n].Y); + MB_FUNC_NAME(secure_mask_mov_FESM2_)(R.Z, R.Z, k, tbl[n].Z); + } + MB_FUNC_NAME(mov_FESM2_)(r->X, R.X); + MB_FUNC_NAME(mov_FESM2_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FESM2_)(r->Z, R.Z); +} + +void MB_FUNC_NAME(ifma_ec_sm2_mul_point_)(SM2_POINT* r, const SM2_POINT* p, const U64 scalar[]) +{ + /* pre-computed table */ + __ALIGN64 SM2_POINT tbl[1<<(WIN_SIZE-1)]; + + /* + // compute tbl[] = [n]P, n=1,..,2^(WIN_SIZE-1): + // + // tbl[2*n] = tbl[2*n-1]+p + // tbl[2*n+1] = [2]*tbl[n] + */ + /* tbl[0] = p */ + MB_FUNC_NAME(mov_FESM2_)(tbl[0].X, p->X); + MB_FUNC_NAME(mov_FESM2_)(tbl[0].Y, p->Y); + MB_FUNC_NAME(mov_FESM2_)(tbl[0].Z, p->Z); + /* tbl[1] = [2]*p */ + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&tbl[1], p); + + int n; + for(n=1; n < (1<<(WIN_SIZE-1))/2; n++) { + MB_FUNC_NAME(ifma_ec_sm2_add_point_)(&tbl[2*n], &tbl[2*n-1], p); + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&tbl[2*n+1], &tbl[n]); + } + + SM2_POINT R; + SM2_POINT T; + U64 Ty[PSM2_LEN52]; + + /* + // point (LR) multiplication + */ + U64 idx_mask = set1( (1<<(WIN_SIZE+1))-1 ); + int bit = PSM2_BITSIZE-(PSM2_BITSIZE % WIN_SIZE); + int chunk_no = (bit-1)/64; + int chunk_shift = (bit-1)%64; + + /* first window */ + U64 wvalue = loadu64(&scalar[chunk_no]); + wvalue = and64( srli64(wvalue, chunk_shift), idx_mask); + + U64 dvalue; + __mb_mask dsign; + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&R, tbl, dvalue); + + for(bit-=WIN_SIZE; bit>=WIN_SIZE; bit-=WIN_SIZE) { + /* doubling */ + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + #endif + + /* extract precomputed []P */ + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + /* T = dsign? -T : T */ + MB_FUNC_NAME(ifma_neg52_psm2_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FESM2_)(T.Y, T.Y, dsign, Ty); + + /* acumulate T */ + MB_FUNC_NAME(ifma_ec_sm2_add_point_)(&R, &R, &T); + } + + /* last window */ + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + #if (WIN_SIZE==5) + MB_FUNC_NAME(ifma_ec_sm2_dbl_point_)(&R, &R); + #endif + + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_)(&T, tbl, dvalue); + + MB_FUNC_NAME(ifma_neg52_psm2_)(Ty, T.Y); + MB_FUNC_NAME(secure_mask_mov_FESM2_)(T.Y, T.Y, dsign, Ty); + + MB_FUNC_NAME(ifma_ec_sm2_add_point_)(&R, &R, &T); + + /* r = R */ + MB_FUNC_NAME(mov_FESM2_)(r->X, R.X); + MB_FUNC_NAME(mov_FESM2_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FESM2_)(r->Z, R.Z); + + /* clear r (to fix potential secutity flaw in case of ecdh */ + MB_FUNC_NAME(zero_)((int64u (*)[8])&R, sizeof(R)/sizeof(U64)); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef WIN_SIZE + + +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +#include + +#define BP_WIN_SIZE MUL_BASEPOINT_WIN_SIZE /* defined in the header above */ + +__INLINE void MB_FUNC_NAME(booth_recode_bp_)(__mb_mask* sign, U64* dvalue, U64 wvalue) +{ + U64 one = set1(1); + U64 zero = get_zero64(); + U64 t = srli64(wvalue, BP_WIN_SIZE); + __mb_mask s = cmp64_mask(t, zero, _MM_CMPINT_NE); + U64 d = sub64( sub64(set1(1<<(BP_WIN_SIZE+1)), wvalue), one); + d = mask_mov64(wvalue, s, d); + U64 odd = and64(d, one); + d = add64( srli64(d, 1), odd); + + *sign = s; + *dvalue = d; +} + +/* extract affine affine point */ +__INLINE void MB_FUNC_NAME(extract_point_affine_)(SM2_POINT_AFFINE* r, const SINGLE_SM2_POINT_AFFINE* tbl, U64 idx) +{ + /* decrement index (the table noes not contain [0]*P */ + U64 targIdx = sub64(idx, set1(1)); + + U64 ax0, ax1, ax2, ax3, ax4, ay0, ay1, ay2, ay3, ay4; + + /* assume the point at infinity is what need */ + ax0 = ax1 = ax2 = ax3 = ax4 = ay0 = ay1 = ay2 = ay3 = ay4 = get_zero64(); + + /* find out what we actually need or just keep original infinity */ + int n; + U64 currIdx = get_zero64(); + for(n=0; n<(1<<(BP_WIN_SIZE-1)); n++, tbl++, currIdx = add64(currIdx, set1(1))) { + __mb_mask k = cmp64_mask(currIdx, targIdx, _MM_CMPINT_EQ); + + /* R = k? set1( tbl[] ) : R */ + ax0 = mask_add64(ax0, k, ax0, set1( tbl->x[0] )); + ax1 = mask_add64(ax1, k, ax1, set1( tbl->x[1] )); + ax2 = mask_add64(ax2, k, ax2, set1( tbl->x[2] )); + ax3 = mask_add64(ax3, k, ax3, set1( tbl->x[3] )); + ax4 = mask_add64(ax4, k, ax4, set1( tbl->x[4] )); + + ay0 = mask_add64(ay0, k, ay0, set1( tbl->y[0] )); + ay1 = mask_add64(ay1, k, ay1, set1( tbl->y[1] )); + ay2 = mask_add64(ay2, k, ay2, set1( tbl->y[2] )); + ay3 = mask_add64(ay3, k, ay3, set1( tbl->y[3] )); + ay4 = mask_add64(ay4, k, ay4, set1( tbl->y[4] )); + } + + r->x[0] = ax0; + r->x[1] = ax1; + r->x[2] = ax2; + r->x[3] = ax3; + r->x[4] = ax4; + + r->y[0] = ay0; + r->y[1] = ay1; + r->y[2] = ay2; + r->y[3] = ay3; + r->y[4] = ay4; +} + +void MB_FUNC_NAME(ifma_ec_sm2_mul_pointbase_)(SM2_POINT* r, const U64 scalar[]) +{ + /* pre-computed table of base powers */ + SINGLE_SM2_POINT_AFFINE* tbl = &ifma_ec_sm2_bp_precomp[0][0]; + + SM2_POINT R; + SM2_POINT_AFFINE A; + U64 Ty[PSM2_LEN52]; + + /* R = O */ + MB_FUNC_NAME(set_point_to_infinity_)(&R); + + + /* + // base point (RL) multiplication + */ + U64 wvalue, dvalue; + __mb_mask dsign; + + U64 idx_mask = set1( (1<<(BP_WIN_SIZE+1))-1 ); + int bit = 0; + + /* first window - window[0] */ + wvalue = loadu64(&scalar[0]); + wvalue = and64( slli64(wvalue, 1), idx_mask); + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_psm2_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FESM2_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_sm2_add_point_affine_)(&R, &R, &A); + + int chunk_no; + int chunk_shift; + for(bit+=BP_WIN_SIZE; bit<=PSM2_BITSIZE; bit+=BP_WIN_SIZE) { + chunk_no = (bit-1)/64; + chunk_shift = (bit-1)%64; + + wvalue = loadu64(&scalar[chunk_no]); + #if (_MSC_VER <= 1916) /* VS 2017 not supported _mm512_shrdv_epi64 */ + { + __m512i t_lo_ = _mm512_srlv_epi64(wvalue, set64(chunk_shift)); + __m512i t_hi_ = _mm512_sllv_epi64(loadu64(&scalar[chunk_no+1]), set64(64-chunk_shift)); + wvalue = or64(t_lo_, t_hi_); + } + #else + wvalue = _mm512_shrdv_epi64(wvalue, loadu64(&scalar[chunk_no+1]), set1((int32u)chunk_shift)); + #endif + wvalue = and64(wvalue, idx_mask); + + MB_FUNC_NAME(booth_recode_bp_)(&dsign, &dvalue, wvalue); + MB_FUNC_NAME(extract_point_affine_)(&A, tbl, dvalue); + tbl+=BP_N_ENTRY; + + /* A = dsign? -A : A */ + MB_FUNC_NAME(ifma_neg52_psm2_)(Ty, A.y); + MB_FUNC_NAME(secure_mask_mov_FESM2_)(A.y, A.y, dsign, Ty); + + /* R += A */ + MB_FUNC_NAME(ifma_ec_sm2_add_point_affine_)(&R, &R, &A); + } + + /* r = R */ + MB_FUNC_NAME(mov_FESM2_)(r->X, R.X); + MB_FUNC_NAME(mov_FESM2_)(r->Y, R.Y); + MB_FUNC_NAME(mov_FESM2_)(r->Z, R.Z); + + /* clear stubs of secret scalar */ + clear_secret_context(&wvalue, &dvalue, &dsign); +} +#undef BP_WIN_SIZE + +/* SM2 parameters: mont(a), mont(b) */ +__ALIGN64 static const int64u mont_a_psm2_mb[PSM2_LEN52][8] = { + { REP8_DECL(0x000fffffffffffcf) }, + { REP8_DECL(0x000cf00000030fff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x000fffffffffffff) }, + { REP8_DECL(0x0000ffffffceffff) } +}; +__ALIGN64 static const int64u mont_b_psm2_mb[PSM2_LEN52][8] = { + { REP8_DECL(0x00030632bc0dd422) }, + { REP8_DECL(0x000b09b537ab70d2) }, + { REP8_DECL(0x000a51c3c71cf379) }, + { REP8_DECL(0x0002c8527981505e) }, + { REP8_DECL(0x000040fe188da20e) } +}; + +/* +// We have a curve defined by a Weierstrass equation: y^2 = x^3 + a*x + b. +// +// The points are considered in Jacobian projective coordinates +// where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). +// Substituting this and multiplying by Z^6 transforms the above equation into +// Y^2 = X^3 + a*X*Z^4 + b*Z^6 +// To test this, we add up the right-hand side in 'rh'. +*/ +__mb_mask MB_FUNC_NAME(ifma_is_on_curve_psm2_)(const SM2_POINT* p, int use_jproj_coords) +{ + U64 rh[PSM2_LEN52]; + U64 Z4[PSM2_LEN52], Z6[PSM2_LEN52], tmp[PSM2_LEN52]; + + /* rh := X^2 */ + MB_FUNC_NAME(ifma_ams52_psm2_)(rh, p->X); + + /* if Z!=1, then rh = X^3 + a*X*Z^4 + b*Z^6 = X*(X^2 + a*X*Z^4) + b*Z^6 */ + if(use_jproj_coords) { + MB_FUNC_NAME(ifma_ams52_psm2_)(tmp, p->Z); /* tmp = Z^2 */ + MB_FUNC_NAME(ifma_ams52_psm2_)(Z4, tmp); /* Z4 = Z^4 */ + MB_FUNC_NAME(ifma_amm52_psm2_)(Z6, Z4, tmp); /* Z6 = Z^6 */ + + MB_FUNC_NAME(ifma_add52_psm2_)(tmp, Z4, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_add52_psm2_)(tmp, tmp, Z4); /* tmp = 2*Z^4 */ + MB_FUNC_NAME(ifma_sub52_psm2_)(rh, rh, tmp); /* rh = X^2 + a*Z^4 */ + MB_FUNC_NAME(ifma_amm52_psm2_)(rh, rh, p->X); /* rh = (X^2 + a*Z^4)*X */ + + MB_FUNC_NAME(ifma_amm52_psm2_)(tmp, Z6, (U64*)mont_b_psm2_mb); + MB_FUNC_NAME(ifma_add52_psm2_)(rh, rh, tmp); /* rh = (X^2 + a*Z^4)*X + b*Z^6 */ + } + /* if Z==1, then rh = X^3 + a*X + b = X*(X^2 +a) b */ + else { + MB_FUNC_NAME(ifma_add52_psm2_)(rh, rh, (U64*)mont_a_psm2_mb); /* rh = X^2+a */ + MB_FUNC_NAME(ifma_amm52_psm2_)(rh, rh, p->X); /* rh = (X^2+a)*X */ + MB_FUNC_NAME(ifma_add52_psm2_)(rh, rh, (U64*)mont_b_psm2_mb); /* rh = (X^2+a)*X + b */ + } + MB_FUNC_NAME(ifma_frommont52_psm2_)(rh, rh); + + /* rl = tmp = Y^2 */ + MB_FUNC_NAME(ifma_ams52_psm2_)(tmp, p->Y); + MB_FUNC_NAME(ifma_frommont52_psm2_)(tmp, tmp); + + /* mask = rl==rh */ + __mb_mask is_on_curve_mask = MB_FUNC_NAME(cmp_eq_FESM2_)(tmp, rh); + + return is_on_curve_mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecpubkey_sm2.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecpubkey_sm2.c new file mode 100644 index 000000000..36f73c19f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm2/ifma_ecpubkey_sm2.c @@ -0,0 +1,214 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef BN_OPENSSL_DISABLE +#include +#endif + +#ifndef BN_OPENSSL_DISABLE +/* +// Computes public key +// pa_pubx[] array of pointers to the public keys X-coordinates +// pa_puby[] array of pointers to the public keys Y-coordinates +// pa_pubz[] array of pointers to the public keys Z-coordinates (or NULL, if affine coordinate requested) +// pa_skey[] array of pointers to the private keys +// pBuffer pointer to the scratch buffer +// +// Note: +// output public key depends on pa_pubz[] parameter and represented either +// - in (X:Y:Z) projective Jacobian coordinates if pa_pubz[] != NULL +// or +// - in (x:y) affine coordinate if pa_pubz[] == NULL +*/ +DLL_PUBLIC +mbx_status mbx_sm2_ecpublic_key_ssl_mb8(BIGNUM* pa_pubx[8], + BIGNUM* pa_puby[8], + BIGNUM* pa_pubz[8], + const BIGNUM* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + BIGNUM* out_x = pa_pubx[buf_no]; + BIGNUM* out_y = pa_puby[buf_no]; + BIGNUM* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const BIGNUM* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[PSM2_LEN64+1]; + ifma_BN_transpose_copy((int64u (*)[8])scalarz, pa_skey, PSM2_BITSIZE); + scalarz[PSM2_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, PSM2_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + SM2_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_sm2_mul_pointbase_)(&P, scalarz); + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_sm2_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_psm2_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_psm2_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_psm2_)(P.Z, P.Z); + + /* convert public key and store BIGNUM result */ + const int len_coord = NUMBER_OF_DIGITS(PSM2_BITSIZE,8); + int8u tmp[8][NUMBER_OF_DIGITS(PSM2_BITSIZE,8)]; /* need set inplace - MSVC compiler problem */ + int8u* const pa_tmp[8] = {tmp[0],tmp[1],tmp[2],tmp[3],tmp[4],tmp[5],tmp[6],tmp[7]}; + + /* X */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.X, PSM2_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], len_coord, pa_pubx[buf_no]); + } + + /* Y */ + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Y, PSM2_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], len_coord, pa_puby[buf_no]); + } + + /* Z */ + if(use_jproj_coords) { + ifma_mb8_to_HexStr8(pa_tmp, (const int64u (*)[8])P.Z, PSM2_BITSIZE); + for(buf_no=0; (buf_no<8) && (0==MBX_GET_STS(status, buf_no)); buf_no++) { + BN_bin2bn(pa_tmp[buf_no], len_coord, pa_pubz[buf_no]); + } + } + + return status; +} +#endif // BN_OPENSSL_DISABLE + +DLL_PUBLIC +mbx_status mbx_sm2_ecpublic_key_mb8(int64u* pa_pubx[8], + int64u* pa_puby[8], + int64u* pa_pubz[8], + const int64u* const pa_skey[8], + int8u* pBuffer) +{ + mbx_status status = 0; + int buf_no; + + /* pa_bubz!=0 means the output is in Jacobian projective coordinates */ + int use_jproj_coords = NULL!=pa_pubz; + + /* test input pointers */ + if(NULL==pa_pubx || NULL==pa_puby || NULL==pa_skey) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* out_x = pa_pubx[buf_no]; + int64u* out_y = pa_puby[buf_no]; + int64u* out_z = use_jproj_coords? pa_pubz[buf_no] : NULL; + const int64u* key = pa_skey[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==out_x || NULL==out_y || (use_jproj_coords && NULL==out_z) || NULL==key) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + } + } + + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* + // processing + */ + + /* zero padded keys */ + U64 scalarz[PSM2_LEN64+1]; + ifma_BNU_transpose_copy((int64u (*)[8])scalarz, pa_skey, PSM2_BITSIZE); + scalarz[PSM2_LEN64] = get_zero64(); + + status |= MBX_SET_STS_BY_MASK(status, is_zero(scalarz, PSM2_LEN64+1), MBX_STATUS_MISMATCH_PARAM_ERR); + + /* do not need to clear copy of secret keys before this return - all of them is NULL or zero */ + if(!MBX_IS_ANY_OK_STS(status)) + return status; + + /* public key */ + SM2_POINT P; + + /* compute public keys */ + MB_FUNC_NAME(ifma_ec_sm2_mul_pointbase_)(&P, scalarz); + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalarz, sizeof(scalarz)/sizeof(U64)); + + if(!use_jproj_coords) + MB_FUNC_NAME(get_sm2_ec_affine_coords_)(P.X, P.Y, &P); + + /* convert P coordinates to regular domain */ + MB_FUNC_NAME(ifma_frommont52_psm2_)(P.X, P.X); + MB_FUNC_NAME(ifma_frommont52_psm2_)(P.Y, P.Y); + if(use_jproj_coords) + MB_FUNC_NAME(ifma_frommont52_psm2_)(P.Z, P.Z); + + /* store result */ + ifma_mb8_to_BNU(pa_pubx, (const int64u (*)[8])P.X, PSM2_BITSIZE); + ifma_mb8_to_BNU(pa_puby, (const int64u (*)[8])P.Y, PSM2_BITSIZE); + if(use_jproj_coords) + ifma_mb8_to_BNU(pa_pubz, (const int64u (*)[8])P.Z, PSM2_BITSIZE); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_avx512_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_avx512_mb16.c new file mode 100644 index 000000000..f118c0117 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_avx512_mb16.c @@ -0,0 +1,330 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +__INLINE void TRANSPOSE_16X16_I32(int32u out[][16], const int32u* const inp[16]) +{ + __m512i r0 = _mm512_loadu_si512(inp[0]); + __m512i r1 = _mm512_loadu_si512(inp[1]); + __m512i r2 = _mm512_loadu_si512(inp[2]); + __m512i r3 = _mm512_loadu_si512(inp[3]); + __m512i r4 = _mm512_loadu_si512(inp[4]); + __m512i r5 = _mm512_loadu_si512(inp[5]); + __m512i r6 = _mm512_loadu_si512(inp[6]); + __m512i r7 = _mm512_loadu_si512(inp[7]); + __m512i r8 = _mm512_loadu_si512(inp[8]); + __m512i r9 = _mm512_loadu_si512(inp[9]); + __m512i r10 = _mm512_loadu_si512(inp[10]); + __m512i r11 = _mm512_loadu_si512(inp[11]); + __m512i r12 = _mm512_loadu_si512(inp[12]); + __m512i r13 = _mm512_loadu_si512(inp[13]); + __m512i r14 = _mm512_loadu_si512(inp[14]); + __m512i r15 = _mm512_loadu_si512(inp[15]); + + // tansposition + __m512i t0 = _mm512_unpacklo_epi32(r0, r1); // 0 16 1 17 4 20 5 21 8 24 9 25 12 28 13 29 + __m512i t1 = _mm512_unpackhi_epi32(r0, r1); // 2 18 3 19 6 22 7 23 10 26 11 27 14 30 15 31 + __m512i t2 = _mm512_unpacklo_epi32(r2, r3); // 32 48 33 49 ... + __m512i t3 = _mm512_unpackhi_epi32(r2, r3); // 34 50 35 51 ... + __m512i t4 = _mm512_unpacklo_epi32(r4, r5); // 64 80 65 81 ... + __m512i t5 = _mm512_unpackhi_epi32(r4, r5); // 66 82 67 83 ... + __m512i t6 = _mm512_unpacklo_epi32(r6, r7); // 96 112 97 113 ... + __m512i t7 = _mm512_unpackhi_epi32(r6, r7); // 98 114 99 115 ... + __m512i t8 = _mm512_unpacklo_epi32(r8, r9); // 128 ... + __m512i t9 = _mm512_unpackhi_epi32(r8, r9); // 130 ... + __m512i t10 = _mm512_unpacklo_epi32(r10, r11); // 160 ... + __m512i t11 = _mm512_unpackhi_epi32(r10, r11); // 162 ... + __m512i t12 = _mm512_unpacklo_epi32(r12, r13); // 196 ... + __m512i t13 = _mm512_unpackhi_epi32(r12, r13); // 198 ... + __m512i t14 = _mm512_unpacklo_epi32(r14, r15); // 228 ... + __m512i t15 = _mm512_unpackhi_epi32(r14, r15); // 230 ... + + r0 = _mm512_unpacklo_epi64(t0, t2); // 0 16 32 48 ... + r1 = _mm512_unpackhi_epi64(t0, t2); // 1 17 33 49 ... + r2 = _mm512_unpacklo_epi64(t1, t3); // 2 18 34 49 ... + r3 = _mm512_unpackhi_epi64(t1, t3); // 3 19 35 51 ... + r4 = _mm512_unpacklo_epi64(t4, t6); // 64 80 96 112 ... + r5 = _mm512_unpackhi_epi64(t4, t6); // 65 81 97 114 ... + r6 = _mm512_unpacklo_epi64(t5, t7); // 66 82 98 113 ... + r7 = _mm512_unpackhi_epi64(t5, t7); // 67 83 99 115 ... + r8 = _mm512_unpacklo_epi64(t8, t10); // 128 144 160 176 ... + r9 = _mm512_unpackhi_epi64(t8, t10); // 129 145 161 178 ... + r10 = _mm512_unpacklo_epi64(t9, t11); // 130 146 162 177 ... + r11 = _mm512_unpackhi_epi64(t9, t11); // 131 147 163 179 ... + r12 = _mm512_unpacklo_epi64(t12, t14); // 192 208 228 240 ... + r13 = _mm512_unpackhi_epi64(t12, t14); // 193 209 229 241 ... + r14 = _mm512_unpacklo_epi64(t13, t15); // 194 210 230 242 ... + r15 = _mm512_unpackhi_epi64(t13, t15); // 195 211 231 243 ... + + t0 = _mm512_shuffle_i32x4(r0, r4, 0x88); // 0 16 32 48 8 24 40 56 64 80 96 112 ... + t1 = _mm512_shuffle_i32x4(r1, r5, 0x88); // 1 17 33 49 ... + t2 = _mm512_shuffle_i32x4(r2, r6, 0x88); // 2 18 34 50 ... + t3 = _mm512_shuffle_i32x4(r3, r7, 0x88); // 3 19 35 51 ... + t4 = _mm512_shuffle_i32x4(r0, r4, 0xdd); // 4 20 36 52 ... + t5 = _mm512_shuffle_i32x4(r1, r5, 0xdd); // 5 21 37 53 ... + t6 = _mm512_shuffle_i32x4(r2, r6, 0xdd); // 6 22 38 54 ... + t7 = _mm512_shuffle_i32x4(r3, r7, 0xdd); // 7 23 39 55 ... + t8 = _mm512_shuffle_i32x4(r8, r12, 0x88); // 128 144 160 176 ... + t9 = _mm512_shuffle_i32x4(r9, r13, 0x88); // 129 145 161 177 ... + t10 = _mm512_shuffle_i32x4(r10, r14, 0x88); // 130 146 162 178 ... + t11 = _mm512_shuffle_i32x4(r11, r15, 0x88); // 131 147 163 179 ... + t12 = _mm512_shuffle_i32x4(r8, r12, 0xdd); // 132 148 164 180 ... + t13 = _mm512_shuffle_i32x4(r9, r13, 0xdd); // 133 149 165 181 ... + t14 = _mm512_shuffle_i32x4(r10, r14, 0xdd); // 134 150 166 182 ... + t15 = _mm512_shuffle_i32x4(r11, r15, 0xdd); // 135 151 167 183 ... + + r0 = _mm512_shuffle_i32x4(t0, t8, 0x88); // 0 16 32 48 64 80 96 112 ... 240 + r1 = _mm512_shuffle_i32x4(t1, t9, 0x88); // 1 17 33 49 66 81 97 113 ... 241 + r2 = _mm512_shuffle_i32x4(t2, t10, 0x88); // 2 18 34 50 67 82 98 114 ... 242 + r3 = _mm512_shuffle_i32x4(t3, t11, 0x88); // 3 19 35 51 68 83 99 115 ... 243 + r4 = _mm512_shuffle_i32x4(t4, t12, 0x88); // 4 ... + r5 = _mm512_shuffle_i32x4(t5, t13, 0x88); // 5 ... + r6 = _mm512_shuffle_i32x4(t6, t14, 0x88); // 6 ... + r7 = _mm512_shuffle_i32x4(t7, t15, 0x88); // 7 ... + r8 = _mm512_shuffle_i32x4(t0, t8, 0xdd); // 8 ... + r9 = _mm512_shuffle_i32x4(t1, t9, 0xdd); // 9 ... + r10 = _mm512_shuffle_i32x4(t2, t10, 0xdd); // 10 ... + r11 = _mm512_shuffle_i32x4(t3, t11, 0xdd); // 11 ... + r12 = _mm512_shuffle_i32x4(t4, t12, 0xdd); // 12 ... + r13 = _mm512_shuffle_i32x4(t5, t13, 0xdd); // 13 ... + r14 = _mm512_shuffle_i32x4(t6, t14, 0xdd); // 14 ... + r15 = _mm512_shuffle_i32x4(t7, t15, 0xdd); // 15 31 47 63 79 96 111 127 ... 255 + + _mm512_storeu_si512(out[0], r0); + _mm512_storeu_si512(out[1], r1); + _mm512_storeu_si512(out[2], r2); + _mm512_storeu_si512(out[3], r3); + _mm512_storeu_si512(out[4], r4); + _mm512_storeu_si512(out[5], r5); + _mm512_storeu_si512(out[6], r6); + _mm512_storeu_si512(out[7], r7); + _mm512_storeu_si512(out[8], r8); + _mm512_storeu_si512(out[9], r9); + _mm512_storeu_si512(out[10], r10); + _mm512_storeu_si512(out[11], r11); + _mm512_storeu_si512(out[12], r12); + _mm512_storeu_si512(out[13], r13); + _mm512_storeu_si512(out[14], r14); + _mm512_storeu_si512(out[15], r15); +} + +/* Boolean functions (0<=nr<16) */ +#define FF1(X,Y,Z) (_mm512_xor_epi32(_mm512_xor_epi32(X,Y), Z)) +#define GG1(X,Y,Z) (_mm512_xor_epi32(_mm512_xor_epi32(X,Y), Z)) +/* Boolean functions (16<=nr<64) */ +#define FF2(X,Y,Z) (_mm512_or_epi32(_mm512_or_epi32(_mm512_and_epi32(X,Y),_mm512_and_epi32(X,Z)),_mm512_and_epi32(Y,Z))) +#define GG2(X,Y,Z) (_mm512_or_epi32(_mm512_and_epi32(X,Y),_mm512_andnot_epi32(X,Z))) + +/* P0 permutation: */ +#define P0(X) (_mm512_xor_epi32(_mm512_xor_epi32(X, _mm512_rol_epi32 (X, 9)), _mm512_rol_epi32 (X, 17))) +/* P1 permutation: */ +#define P1(X) (_mm512_xor_epi32(_mm512_xor_epi32(X, _mm512_rol_epi32 (X, 15)), _mm512_rol_epi32 (X, 23))) + +/* Update W */ +#define WUPDATE(nr, W) (_mm512_xor_epi32(_mm512_xor_epi32(P1(_mm512_xor_epi32(_mm512_xor_epi32(W[(nr-16)&15], W[(nr-9)&15]), _mm512_rol_epi32 (W[(nr-3)&15], 15))), _mm512_rol_epi32(W[(nr-13)&15],7)), W[(nr-6)&15])) + +// SM3 steps +/* (0<=nr<16) */ +#define STEP1_SM3(nr, A,B,C,D,E,F,G,H, Tj, W) {\ + __m512i SS1 = _mm512_rol_epi32(_mm512_add_epi32(_mm512_add_epi32(_mm512_rol_epi32(A, 12), E), _mm512_set1_epi32((int)Tj)),7);\ + __m512i SS2 = _mm512_xor_epi32(SS1, _mm512_rol_epi32(A, 12));\ + __m512i TT1 = _mm512_add_epi32(_mm512_add_epi32(_mm512_add_epi32(FF1(A, B, C), D), SS2), _mm512_xor_epi32(W[nr&15], W[(nr+4)&15]));\ + __m512i TT2 = _mm512_add_epi32(_mm512_add_epi32(_mm512_add_epi32(GG1(E, F, G), H), SS1), W[nr&15]);\ + D = _mm512_load_epi32((void*)&C); \ + C = _mm512_rol_epi32(B, 9); \ + B = _mm512_load_epi32((void*)&A); \ + A = _mm512_load_epi32((void*)&TT1);\ + H = _mm512_load_epi32((void*)&G); \ + G = _mm512_rol_epi32(F, 19); \ + F = _mm512_load_epi32((void*)&E); \ + E = P0(TT2); \ + W[(nr)&15]=WUPDATE(nr, W); \ +} + +/* (16<=nr<64) */ +#define STEP2_SM3(nr, A,B,C,D,E,F,G,H, Tj, W) {\ + __m512i SS1 = _mm512_rol_epi32(_mm512_add_epi32(_mm512_add_epi32(_mm512_rol_epi32(A, 12), E), _mm512_set1_epi32((int)Tj)),7);\ + __m512i SS2 = _mm512_xor_epi32(SS1, _mm512_rol_epi32(A, 12));\ + __m512i TT1 = _mm512_add_epi32(_mm512_add_epi32(_mm512_add_epi32(FF2(A, B, C), D), SS2), _mm512_xor_epi32(W[nr&15], W[(nr+4)&15]));\ + __m512i TT2 = _mm512_add_epi32(_mm512_add_epi32(_mm512_add_epi32(GG2(E, F, G), H), SS1), W[nr&15]);\ + D = _mm512_load_epi32((void*)&C); \ + C = _mm512_rol_epi32(B, 9); \ + B = _mm512_load_epi32((void*)&A); \ + A = _mm512_load_epi32((void*)&TT1);\ + H = _mm512_load_epi32((void*)&G); \ + G = _mm512_rol_epi32(F, 19); \ + F = _mm512_load_epi32((void*)&E); \ + E = P0(TT2); \ + W[(nr)&15]=WUPDATE(nr, W); \ +} + + +void sm3_avx512_mb16(int32u hash_pa[][16], const int8u* const msg_pa[16], int len[16]) +{ + int i; + + __ALIGN64 int32u* loc_data[SM3_NUM_BUFFERS]; + __ALIGN64 int loc_len[SM3_NUM_BUFFERS]; + + __m512i W[16]; + __m512i Vi[8]; + __m512i A, B, C, D, E, F, G, H; + + /* Allocate memory to handle numBuffers < 16, set data in not valid buffers to zero */ + __m512i zero_buffer = _mm512_setzero_si512(); + + /* Load processing mask */ + __mmask16 mb_mask = _mm512_cmp_epi32_mask(_mm512_loadu_si512(len), zero_buffer, _MM_CMPINT_NLE); + + /* Load data and set the data to zero in not valid buffers */ + M512(loc_len) = _mm512_loadu_si512(len); + + _mm512_storeu_si512(loc_data, _mm512_mask_loadu_epi64(_mm512_set1_epi64((long long)&zero_buffer), (__mmask8)mb_mask, msg_pa)); + _mm512_storeu_si512(loc_data+8, _mm512_mask_loadu_epi64(_mm512_set1_epi64((long long)&zero_buffer), *((__mmask8*)&mb_mask + 1), msg_pa + 8)); + + /* Load hash value */ + A = _mm512_loadu_si512(hash_pa); + B = _mm512_loadu_si512(hash_pa + 1); + C = _mm512_loadu_si512(hash_pa + 2); + D = _mm512_loadu_si512(hash_pa + 3); + E = _mm512_loadu_si512(hash_pa + 4); + F = _mm512_loadu_si512(hash_pa + 5); + G = _mm512_loadu_si512(hash_pa + 6); + H = _mm512_loadu_si512(hash_pa + 7); + + /* Loop over the message */ + while (mb_mask){ + /* Transpose the message data */ + TRANSPOSE_16X16_I32((int32u(*)[16])W, (const int32u**)loc_data); + + /* Init W (remember about endian) */ + for (i = 0; i < 16; i++) { + W[i] = SIMD_ENDIANNESS32(W[i]); + } + + /* Store previous hash for xor operation V(i+1) = ABCDEFGH XOR V(i) */ + Vi[0] = _mm512_load_epi32((void*)&A); + Vi[1] = _mm512_load_epi32((void*)&B); + Vi[2] = _mm512_load_epi32((void*)&C); + Vi[3] = _mm512_load_epi32((void*)&D); + Vi[4] = _mm512_load_epi32((void*)&E); + Vi[5] = _mm512_load_epi32((void*)&F); + Vi[6] = _mm512_load_epi32((void*)&G); + Vi[7] = _mm512_load_epi32((void*)&H); + + /* Compression function */ + { + STEP1_SM3(0, A, B, C, D, E, F, G, H, tj_calculated[0], W); + STEP1_SM3(1, A, B, C, D, E, F, G, H, tj_calculated[1], W); + STEP1_SM3(2, A, B, C, D, E, F, G, H, tj_calculated[2], W); + STEP1_SM3(3, A, B, C, D, E, F, G, H, tj_calculated[3], W); + STEP1_SM3(4, A, B, C, D, E, F, G, H, tj_calculated[4], W); + STEP1_SM3(5, A, B, C, D, E, F, G, H, tj_calculated[5], W); + STEP1_SM3(6, A, B, C, D, E, F, G, H, tj_calculated[6], W); + STEP1_SM3(7, A, B, C, D, E, F, G, H, tj_calculated[7], W); + + STEP1_SM3(8, A, B, C, D, E, F, G, H, tj_calculated[8], W); + STEP1_SM3(9, A, B, C, D, E, F, G, H, tj_calculated[9], W); + STEP1_SM3(10, A, B, C, D, E, F, G, H, tj_calculated[10], W); + STEP1_SM3(11, A, B, C, D, E, F, G, H, tj_calculated[11], W); + STEP1_SM3(12, A, B, C, D, E, F, G, H, tj_calculated[12], W); + STEP1_SM3(13, A, B, C, D, E, F, G, H, tj_calculated[13], W); + STEP1_SM3(14, A, B, C, D, E, F, G, H, tj_calculated[14], W); + STEP1_SM3(15, A, B, C, D, E, F, G, H, tj_calculated[15], W); + + STEP2_SM3(16, A, B, C, D, E, F, G, H, tj_calculated[16], W); + STEP2_SM3(17, A, B, C, D, E, F, G, H, tj_calculated[17], W); + STEP2_SM3(18, A, B, C, D, E, F, G, H, tj_calculated[18], W); + STEP2_SM3(19, A, B, C, D, E, F, G, H, tj_calculated[19], W); + STEP2_SM3(20, A, B, C, D, E, F, G, H, tj_calculated[20], W); + STEP2_SM3(21, A, B, C, D, E, F, G, H, tj_calculated[21], W); + STEP2_SM3(22, A, B, C, D, E, F, G, H, tj_calculated[22], W); + STEP2_SM3(23, A, B, C, D, E, F, G, H, tj_calculated[23], W); + + STEP2_SM3(24, A, B, C, D, E, F, G, H, tj_calculated[24], W); + STEP2_SM3(25, A, B, C, D, E, F, G, H, tj_calculated[25], W); + STEP2_SM3(26, A, B, C, D, E, F, G, H, tj_calculated[26], W); + STEP2_SM3(27, A, B, C, D, E, F, G, H, tj_calculated[27], W); + STEP2_SM3(28, A, B, C, D, E, F, G, H, tj_calculated[28], W); + STEP2_SM3(29, A, B, C, D, E, F, G, H, tj_calculated[29], W); + STEP2_SM3(30, A, B, C, D, E, F, G, H, tj_calculated[30], W); + STEP2_SM3(31, A, B, C, D, E, F, G, H, tj_calculated[31], W); + + STEP2_SM3(32, A, B, C, D, E, F, G, H, tj_calculated[32], W); + STEP2_SM3(33, A, B, C, D, E, F, G, H, tj_calculated[33], W); + STEP2_SM3(34, A, B, C, D, E, F, G, H, tj_calculated[34], W); + STEP2_SM3(35, A, B, C, D, E, F, G, H, tj_calculated[35], W); + STEP2_SM3(36, A, B, C, D, E, F, G, H, tj_calculated[36], W); + STEP2_SM3(37, A, B, C, D, E, F, G, H, tj_calculated[37], W); + STEP2_SM3(38, A, B, C, D, E, F, G, H, tj_calculated[38], W); + STEP2_SM3(39, A, B, C, D, E, F, G, H, tj_calculated[39], W); + + STEP2_SM3(40, A, B, C, D, E, F, G, H, tj_calculated[40], W); + STEP2_SM3(41, A, B, C, D, E, F, G, H, tj_calculated[41], W); + STEP2_SM3(42, A, B, C, D, E, F, G, H, tj_calculated[42], W); + STEP2_SM3(43, A, B, C, D, E, F, G, H, tj_calculated[43], W); + STEP2_SM3(44, A, B, C, D, E, F, G, H, tj_calculated[44], W); + STEP2_SM3(45, A, B, C, D, E, F, G, H, tj_calculated[45], W); + STEP2_SM3(46, A, B, C, D, E, F, G, H, tj_calculated[46], W); + STEP2_SM3(47, A, B, C, D, E, F, G, H, tj_calculated[47], W); + + STEP2_SM3(48, A, B, C, D, E, F, G, H, tj_calculated[16], W); + STEP2_SM3(49, A, B, C, D, E, F, G, H, tj_calculated[17], W); + STEP2_SM3(50, A, B, C, D, E, F, G, H, tj_calculated[18], W); + STEP2_SM3(51, A, B, C, D, E, F, G, H, tj_calculated[19], W); + STEP2_SM3(52, A, B, C, D, E, F, G, H, tj_calculated[20], W); + STEP2_SM3(53, A, B, C, D, E, F, G, H, tj_calculated[21], W); + STEP2_SM3(54, A, B, C, D, E, F, G, H, tj_calculated[22], W); + STEP2_SM3(55, A, B, C, D, E, F, G, H, tj_calculated[23], W); + + STEP2_SM3(56, A, B, C, D, E, F, G, H, tj_calculated[24], W); + STEP2_SM3(57, A, B, C, D, E, F, G, H, tj_calculated[25], W); + STEP2_SM3(58, A, B, C, D, E, F, G, H, tj_calculated[26], W); + STEP2_SM3(59, A, B, C, D, E, F, G, H, tj_calculated[27], W); + STEP2_SM3(60, A, B, C, D, E, F, G, H, tj_calculated[28], W); + STEP2_SM3(61, A, B, C, D, E, F, G, H, tj_calculated[29], W); + STEP2_SM3(62, A, B, C, D, E, F, G, H, tj_calculated[30], W); + STEP2_SM3(63, A, B, C, D, E, F, G, H, tj_calculated[31], W); + } + + A = _mm512_mask_xor_epi32(Vi[0], mb_mask, A, Vi[0]); + B = _mm512_mask_xor_epi32(Vi[1], mb_mask, B, Vi[1]); + C = _mm512_mask_xor_epi32(Vi[2], mb_mask, C, Vi[2]); + D = _mm512_mask_xor_epi32(Vi[3], mb_mask, D, Vi[3]); + E = _mm512_mask_xor_epi32(Vi[4], mb_mask, E, Vi[4]); + F = _mm512_mask_xor_epi32(Vi[5], mb_mask, F, Vi[5]); + G = _mm512_mask_xor_epi32(Vi[6], mb_mask, G, Vi[6]); + H = _mm512_mask_xor_epi32(Vi[7], mb_mask, H, Vi[7]); + + _mm512_storeu_si512(hash_pa, A); + _mm512_storeu_si512(hash_pa + 1, B); + _mm512_storeu_si512(hash_pa + 2, C); + _mm512_storeu_si512(hash_pa + 3, D); + _mm512_storeu_si512(hash_pa + 4, E); + _mm512_storeu_si512(hash_pa + 5, F); + _mm512_storeu_si512(hash_pa + 6, G); + _mm512_storeu_si512(hash_pa + 7, H); + + /* Update pointers to data, local lengths and mask */ + _mm512_storeu_si512(loc_data, _mm512_mask_add_epi64(_mm512_set1_epi64((long long)&zero_buffer), (__mmask8)mb_mask, _mm512_loadu_si512(loc_data), _mm512_set1_epi64(SM3_MSG_BLOCK_SIZE))); + _mm512_storeu_si512(loc_data + 8, _mm512_mask_add_epi64(_mm512_set1_epi64((long long)&zero_buffer), *((__mmask8*)&mb_mask + 1), _mm512_loadu_si512(loc_data+8), _mm512_set1_epi64(SM3_MSG_BLOCK_SIZE))); + + M512(loc_len) = _mm512_mask_sub_epi32(zero_buffer, mb_mask, _mm512_loadu_si512(loc_len), _mm512_set1_epi32(SM3_MSG_BLOCK_SIZE)); + mb_mask = _mm512_cmp_epi32_mask(_mm512_loadu_si512(loc_len), zero_buffer, _MM_CMPINT_NLE); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_avx512_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_avx512_mb8.c new file mode 100644 index 000000000..be8ed61ff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_avx512_mb8.c @@ -0,0 +1,224 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +/* Boolean functions (0<=nr<16) */ +#define FF1(X,Y,Z) (_mm256_xor_si256(_mm256_xor_si256(X,Y), Z)) +#define GG1(X,Y,Z) (_mm256_xor_si256(_mm256_xor_si256(X,Y), Z)) +/* Boolean functions (16<=nr<64) */ +#define FF2(X,Y,Z) (_mm256_or_si256(_mm256_or_si256(_mm256_and_si256(X,Y),_mm256_and_si256(X,Z)),_mm256_and_si256(Y,Z))) +#define GG2(X,Y,Z) (_mm256_or_si256(_mm256_and_si256(X,Y),_mm256_andnot_si256(X,Z))) + +/* P0 permutation: */ +#define P0(X) (_mm256_xor_si256(_mm256_xor_si256(X, _mm256_rol_epi32 (X, 9)), _mm256_rol_epi32 (X, 17))) +/* P1 permutation: */ +#define P1(X) (_mm256_xor_si256(_mm256_xor_si256(X, _mm256_rol_epi32 (X, 15)), _mm256_rol_epi32 (X, 23))) + +/* Update W */ +#define WUPDATE(nr, W) (_mm256_xor_si256(_mm256_xor_si256(P1(_mm256_xor_si256(_mm256_xor_si256(W[(nr-16)&15], W[(nr-9)&15]), _mm256_rol_epi32 (W[(nr-3)&15], 15))), _mm256_rol_epi32(W[(nr-13)&15],7)), W[(nr-6)&15])) + +// SM3 steps +/* (0<=nr<16) */ +#define STEP1_SM3(nr, A,B,C,D,E,F,G,H, Tj, W) {\ + __m256i SS1 = _mm256_rol_epi32(_mm256_add_epi32(_mm256_add_epi32(_mm256_rol_epi32(A, 12), E), _mm256_set1_epi32((int)Tj)),7);\ + __m256i SS2 = _mm256_xor_si256(SS1, _mm256_rol_epi32(A, 12));\ + __m256i TT1 = _mm256_add_epi32(_mm256_add_epi32(_mm256_add_epi32(FF1(A, B, C), D), SS2), _mm256_xor_si256(W[nr&15], W[(nr+4)&15]));\ + __m256i TT2 = _mm256_add_epi32(_mm256_add_epi32(_mm256_add_epi32(GG1(E, F, G), H), SS1), W[nr&15]);\ + D = _mm256_loadu_si256((void*)&C); \ + C = _mm256_rol_epi32(B, 9); \ + B = _mm256_loadu_si256((void*)&A); \ + A = _mm256_loadu_si256((void*)&TT1);\ + H = _mm256_loadu_si256((void*)&G); \ + G = _mm256_rol_epi32(F, 19); \ + F = _mm256_loadu_si256((void*)&E); \ + E = P0(TT2); \ + W[(nr)&15]=WUPDATE(nr, W); \ +} + +/* (16<=nr<64) */ +#define STEP2_SM3(nr, A,B,C,D,E,F,G,H, Tj, W) {\ + __m256i SS1 = _mm256_rol_epi32(_mm256_add_epi32(_mm256_add_epi32(_mm256_rol_epi32(A, 12), E), _mm256_set1_epi32((int)Tj)),7);\ + __m256i SS2 = _mm256_xor_si256(SS1, _mm256_rol_epi32(A, 12));\ + __m256i TT1 = _mm256_add_epi32(_mm256_add_epi32(_mm256_add_epi32(FF2(A, B, C), D), SS2), _mm256_xor_si256(W[nr&15], W[(nr+4)&15]));\ + __m256i TT2 = _mm256_add_epi32(_mm256_add_epi32(_mm256_add_epi32(GG2(E, F, G), H), SS1), W[nr&15]);\ + D = _mm256_loadu_si256((void*)&C); \ + C = _mm256_rol_epi32(B, 9); \ + B = _mm256_loadu_si256((void*)&A); \ + A = _mm256_loadu_si256((void*)&TT1);\ + H = _mm256_loadu_si256((void*)&G); \ + G = _mm256_rol_epi32(F, 19); \ + F = _mm256_loadu_si256((void*)&E); \ + E = P0(TT2); \ + W[(nr)&15]=WUPDATE(nr, W); \ +} + + +void sm3_avx512_mb8(int32u hash_pa[][8], const int8u* const msg_pa[8], int len[8]) +{ + int i; + + __ALIGN64 int32u* loc_data[SM3_NUM_BUFFERS8]; + __ALIGN64 int loc_len[SM3_NUM_BUFFERS8]; + + __m256i W[16]; + int32u* p_W[16] = { (int32u*)&W[0], (int32u*)&W[1], (int32u*)&W[2], (int32u*)&W[3], (int32u*)&W[4], (int32u*)&W[5], (int32u*)&W[6], (int32u*)&W[7], + (int32u*)&W[8], (int32u*)&W[9], (int32u*)&W[10], (int32u*)&W[11], (int32u*)&W[12], (int32u*)&W[13], (int32u*)&W[14], (int32u*)&W[15] }; + + __m256i Vi[8]; + __m256i A, B, C, D, E, F, G, H; + + /* Allocate memory to handle numBuffers < 16, set data in not valid buffers to zero */ + __m512i zero_buffer = _mm512_setzero_si512(); + + /* Load processing mask */ + __mmask8 mb_mask = _mm256_cmp_epi32_mask(_mm256_loadu_si256((__m256i*)len), M256(&zero_buffer), _MM_CMPINT_NE); + + /* Load data and set the data to zero in not valid buffers */ + M256(loc_len) = _mm256_loadu_si256((__m256i*)len); + + _mm512_storeu_si512(loc_data, _mm512_mask_loadu_epi64(_mm512_set1_epi64((long long)&zero_buffer), mb_mask, msg_pa)); + + /* Load hash value */ + A = _mm256_loadu_si256((__m256i*)hash_pa); + B = _mm256_loadu_si256((__m256i*)(hash_pa + 1)); + C = _mm256_loadu_si256((__m256i*)(hash_pa + 2)); + D = _mm256_loadu_si256((__m256i*)(hash_pa + 3)); + E = _mm256_loadu_si256((__m256i*)(hash_pa + 4)); + F = _mm256_loadu_si256((__m256i*)(hash_pa + 5)); + G = _mm256_loadu_si256((__m256i*)(hash_pa + 6)); + H = _mm256_loadu_si256((__m256i*)(hash_pa + 7)); + + /* Loop over the message */ + while (mb_mask){ + /* Transpose the message data */ + TRANSPOSE_8X16_I32(p_W, (const int32u**)loc_data, 0xFFFF); + + /* Init W (remember about endian) */ + for (i = 0; i < 16; i++) { + W[i] = SIMD_ENDIANNESS32(W[i]); + } + + /* Store previous hash for xor operation V(i+1) = ABCDEFGH XOR V(i) */ + Vi[0] = _mm256_loadu_si256((void*)&A); + Vi[1] = _mm256_loadu_si256((void*)&B); + Vi[2] = _mm256_loadu_si256((void*)&C); + Vi[3] = _mm256_loadu_si256((void*)&D); + Vi[4] = _mm256_loadu_si256((void*)&E); + Vi[5] = _mm256_loadu_si256((void*)&F); + Vi[6] = _mm256_loadu_si256((void*)&G); + Vi[7] = _mm256_loadu_si256((void*)&H); + + /* Compression function */ + { + STEP1_SM3(0, A, B, C, D, E, F, G, H, tj_calculated[0], W); + STEP1_SM3(1, A, B, C, D, E, F, G, H, tj_calculated[1], W); + STEP1_SM3(2, A, B, C, D, E, F, G, H, tj_calculated[2], W); + STEP1_SM3(3, A, B, C, D, E, F, G, H, tj_calculated[3], W); + STEP1_SM3(4, A, B, C, D, E, F, G, H, tj_calculated[4], W); + STEP1_SM3(5, A, B, C, D, E, F, G, H, tj_calculated[5], W); + STEP1_SM3(6, A, B, C, D, E, F, G, H, tj_calculated[6], W); + STEP1_SM3(7, A, B, C, D, E, F, G, H, tj_calculated[7], W); + + STEP1_SM3(8, A, B, C, D, E, F, G, H, tj_calculated[8], W); + STEP1_SM3(9, A, B, C, D, E, F, G, H, tj_calculated[9], W); + STEP1_SM3(10, A, B, C, D, E, F, G, H, tj_calculated[10], W); + STEP1_SM3(11, A, B, C, D, E, F, G, H, tj_calculated[11], W); + STEP1_SM3(12, A, B, C, D, E, F, G, H, tj_calculated[12], W); + STEP1_SM3(13, A, B, C, D, E, F, G, H, tj_calculated[13], W); + STEP1_SM3(14, A, B, C, D, E, F, G, H, tj_calculated[14], W); + STEP1_SM3(15, A, B, C, D, E, F, G, H, tj_calculated[15], W); + + STEP2_SM3(16, A, B, C, D, E, F, G, H, tj_calculated[16], W); + STEP2_SM3(17, A, B, C, D, E, F, G, H, tj_calculated[17], W); + STEP2_SM3(18, A, B, C, D, E, F, G, H, tj_calculated[18], W); + STEP2_SM3(19, A, B, C, D, E, F, G, H, tj_calculated[19], W); + STEP2_SM3(20, A, B, C, D, E, F, G, H, tj_calculated[20], W); + STEP2_SM3(21, A, B, C, D, E, F, G, H, tj_calculated[21], W); + STEP2_SM3(22, A, B, C, D, E, F, G, H, tj_calculated[22], W); + STEP2_SM3(23, A, B, C, D, E, F, G, H, tj_calculated[23], W); + + STEP2_SM3(24, A, B, C, D, E, F, G, H, tj_calculated[24], W); + STEP2_SM3(25, A, B, C, D, E, F, G, H, tj_calculated[25], W); + STEP2_SM3(26, A, B, C, D, E, F, G, H, tj_calculated[26], W); + STEP2_SM3(27, A, B, C, D, E, F, G, H, tj_calculated[27], W); + STEP2_SM3(28, A, B, C, D, E, F, G, H, tj_calculated[28], W); + STEP2_SM3(29, A, B, C, D, E, F, G, H, tj_calculated[29], W); + STEP2_SM3(30, A, B, C, D, E, F, G, H, tj_calculated[30], W); + STEP2_SM3(31, A, B, C, D, E, F, G, H, tj_calculated[31], W); + + STEP2_SM3(32, A, B, C, D, E, F, G, H, tj_calculated[32], W); + STEP2_SM3(33, A, B, C, D, E, F, G, H, tj_calculated[33], W); + STEP2_SM3(34, A, B, C, D, E, F, G, H, tj_calculated[34], W); + STEP2_SM3(35, A, B, C, D, E, F, G, H, tj_calculated[35], W); + STEP2_SM3(36, A, B, C, D, E, F, G, H, tj_calculated[36], W); + STEP2_SM3(37, A, B, C, D, E, F, G, H, tj_calculated[37], W); + STEP2_SM3(38, A, B, C, D, E, F, G, H, tj_calculated[38], W); + STEP2_SM3(39, A, B, C, D, E, F, G, H, tj_calculated[39], W); + + STEP2_SM3(40, A, B, C, D, E, F, G, H, tj_calculated[40], W); + STEP2_SM3(41, A, B, C, D, E, F, G, H, tj_calculated[41], W); + STEP2_SM3(42, A, B, C, D, E, F, G, H, tj_calculated[42], W); + STEP2_SM3(43, A, B, C, D, E, F, G, H, tj_calculated[43], W); + STEP2_SM3(44, A, B, C, D, E, F, G, H, tj_calculated[44], W); + STEP2_SM3(45, A, B, C, D, E, F, G, H, tj_calculated[45], W); + STEP2_SM3(46, A, B, C, D, E, F, G, H, tj_calculated[46], W); + STEP2_SM3(47, A, B, C, D, E, F, G, H, tj_calculated[47], W); + + STEP2_SM3(48, A, B, C, D, E, F, G, H, tj_calculated[16], W); + STEP2_SM3(49, A, B, C, D, E, F, G, H, tj_calculated[17], W); + STEP2_SM3(50, A, B, C, D, E, F, G, H, tj_calculated[18], W); + STEP2_SM3(51, A, B, C, D, E, F, G, H, tj_calculated[19], W); + STEP2_SM3(52, A, B, C, D, E, F, G, H, tj_calculated[20], W); + STEP2_SM3(53, A, B, C, D, E, F, G, H, tj_calculated[21], W); + STEP2_SM3(54, A, B, C, D, E, F, G, H, tj_calculated[22], W); + STEP2_SM3(55, A, B, C, D, E, F, G, H, tj_calculated[23], W); + + STEP2_SM3(56, A, B, C, D, E, F, G, H, tj_calculated[24], W); + STEP2_SM3(57, A, B, C, D, E, F, G, H, tj_calculated[25], W); + STEP2_SM3(58, A, B, C, D, E, F, G, H, tj_calculated[26], W); + STEP2_SM3(59, A, B, C, D, E, F, G, H, tj_calculated[27], W); + STEP2_SM3(60, A, B, C, D, E, F, G, H, tj_calculated[28], W); + STEP2_SM3(61, A, B, C, D, E, F, G, H, tj_calculated[29], W); + STEP2_SM3(62, A, B, C, D, E, F, G, H, tj_calculated[30], W); + STEP2_SM3(63, A, B, C, D, E, F, G, H, tj_calculated[31], W); + } + + A = _mm256_mask_xor_epi32(Vi[0], mb_mask, A, Vi[0]); + B = _mm256_mask_xor_epi32(Vi[1], mb_mask, B, Vi[1]); + C = _mm256_mask_xor_epi32(Vi[2], mb_mask, C, Vi[2]); + D = _mm256_mask_xor_epi32(Vi[3], mb_mask, D, Vi[3]); + E = _mm256_mask_xor_epi32(Vi[4], mb_mask, E, Vi[4]); + F = _mm256_mask_xor_epi32(Vi[5], mb_mask, F, Vi[5]); + G = _mm256_mask_xor_epi32(Vi[6], mb_mask, G, Vi[6]); + H = _mm256_mask_xor_epi32(Vi[7], mb_mask, H, Vi[7]); + + _mm256_storeu_si256((__m256i*)hash_pa, A); + _mm256_storeu_si256((__m256i*)(hash_pa + 1), B); + _mm256_storeu_si256((__m256i*)(hash_pa + 2), C); + _mm256_storeu_si256((__m256i*)(hash_pa + 3), D); + _mm256_storeu_si256((__m256i*)(hash_pa + 4), E); + _mm256_storeu_si256((__m256i*)(hash_pa + 5), F); + _mm256_storeu_si256((__m256i*)(hash_pa + 6), G); + _mm256_storeu_si256((__m256i*)(hash_pa + 7), H); + + /* Update pointers to data, local lengths and mask */ + M512(loc_data) = _mm512_mask_add_epi64(_mm512_set1_epi64((long long)&zero_buffer), (__mmask8)mb_mask, _mm512_loadu_si512(loc_data), _mm512_set1_epi64(SM3_MSG_BLOCK_SIZE)); + M256(loc_len) = _mm256_mask_sub_epi32(M256(&zero_buffer), mb_mask, _mm256_loadu_si256((__m256i*)loc_len), _mm256_set1_epi32(SM3_MSG_BLOCK_SIZE)); + mb_mask = _mm256_cmp_epi32_mask(_mm256_loadu_si256((__m256i*)loc_len), M256(&zero_buffer), _MM_CMPINT_NE); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_final_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_final_mb16.c new file mode 100644 index 000000000..bc23819d2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_final_mb16.c @@ -0,0 +1,115 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm3_final_mb16(int8u* hash_pa[16], + SM3_CTX_mb16* p_state) +{ + int i; + mbx_status16 status = 0; + + /* test input pointers */ + if(NULL==hash_pa || NULL==p_state) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + __ALIGN64 int input_len[SM3_NUM_BUFFERS]; + __ALIGN64 int buffer_len[SM3_NUM_BUFFERS]; + __ALIGN64 int64u sum_msg_len[SM3_NUM_BUFFERS]; + + /* allocate local buffer */ + __ALIGN64 int8u loc_buffer[SM3_NUM_BUFFERS][SM3_MSG_BLOCK_SIZE*2]; + const int8u* buffer_pa[SM3_NUM_BUFFERS] = { loc_buffer[0], loc_buffer[1], loc_buffer[2], loc_buffer[3], + loc_buffer[4], loc_buffer[5], loc_buffer[6], loc_buffer[7], + loc_buffer[8], loc_buffer[9], loc_buffer[10], loc_buffer[11], + loc_buffer[12], loc_buffer[13], loc_buffer[14], loc_buffer[15] }; + + __m512i zero_buffer = _mm512_setzero_si512(); + + /* + // create __mmask8 and __mmask16 based on input hash_pa + // corresponding element in mask = 0 if hash_pa[i] = 0 + */ + __mmask8 mb_mask8[2]; + mb_mask8[0] = _mm512_cmp_epi64_mask(_mm512_loadu_si512(hash_pa), zero_buffer, _MM_CMPINT_NE); + mb_mask8[1] = _mm512_cmp_epi64_mask(_mm512_loadu_si512(hash_pa + 8), zero_buffer, _MM_CMPINT_NE); + __mmask16 mb_mask16 = *(__mmask16*)mb_mask8; + + M512(sum_msg_len) = _mm512_maskz_loadu_epi64(mb_mask8[0], MSG_LEN(p_state)); + M512(sum_msg_len + 8) = _mm512_maskz_loadu_epi64(mb_mask8[1], MSG_LEN(p_state) + 8); + + /* put processed message length in bits */ + M512(sum_msg_len) = _mm512_rol_epi64(M512(sum_msg_len), 3); + M512(sum_msg_len + 8) = _mm512_rol_epi64(M512(sum_msg_len+8), 3); + M512(sum_msg_len) = _mm512_shuffle_epi8(M512(sum_msg_len), M512(swapBytes)); + M512(sum_msg_len +8) = _mm512_shuffle_epi8(M512(sum_msg_len +8), M512(swapBytes)); + + M512(input_len) = _mm512_maskz_loadu_epi32(mb_mask16, HASH_BUFFIDX(p_state)); + + __mmask16 tmp_mask = _mm512_cmplt_epi32_mask(M512(input_len), _mm512_set1_epi32(SM3_MSG_BLOCK_SIZE - (int)SM3_MSG_LEN_REPR)); + M512(buffer_len) = _mm512_mask_set1_epi32(_mm512_set1_epi32(SM3_MSG_BLOCK_SIZE * 2), tmp_mask, SM3_MSG_BLOCK_SIZE); + M512(buffer_len) = _mm512_mask_set1_epi32(M512(buffer_len), ~mb_mask16, 0); + M512(buffer_len) = _mm512_mask_set1_epi32(M512(buffer_len), ~mb_mask16, 0); + + for (i = 0; i < SM3_NUM_BUFFERS; i++) { + /* Copy rest of message into internal buffer */ + if ((mb_mask16 >> i) & 0x1) { + __mmask64 mb_mask64 = ~(0xFFFFFFFFFFFFFFFF << input_len[i]); + M512(loc_buffer[i]) = _mm512_maskz_loadu_epi8(mb_mask64, HASH_BUFF(p_state)[i]); + + /* Pad message */ + loc_buffer[i][input_len[i]++] = 0x80; + pad_block(0, loc_buffer[i] + input_len[i], (int)(buffer_len[i] - input_len[i] - (int)SM3_MSG_LEN_REPR)); + ((int64u*)(loc_buffer[i] + buffer_len[i]))[-1] = sum_msg_len[i]; + } + } + + /* Copmplete hash computation */ + sm3_avx512_mb16(HASH_VALUE(p_state), buffer_pa, buffer_len); + + /* Convert hash into big endian */ + __m512i T[8]; + const int32u* p_T[8] = { (int32u*)&T[0], (int32u*)&T[1], (int32u*)&T[2], (int32u*)&T[3], (int32u*)&T[4], (int32u*)&T[5], (int32u*)&T[6], (int32u*)&T[7] }; + + T[0] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[0])); + T[1] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[1])); + T[2] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[2])); + T[3] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[3])); + T[4] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[4])); + T[5] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[5])); + T[6] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[6])); + T[7] = SIMD_ENDIANNESS32(_mm512_loadu_si512(HASH_VALUE(p_state)[7])); + + /* Transpose hash and store in array with pointers to hash values */ + TRANSPOSE_8X16_I32((int32u**)hash_pa, p_T, mb_mask16); + + /* re-init hash value using mb masks */ + _mm512_storeu_si512(MSG_LEN(p_state), _mm512_mask_set1_epi64(_mm512_loadu_si512(MSG_LEN(p_state)), mb_mask8[0], 0)); + _mm512_storeu_si512(MSG_LEN(p_state)+8, _mm512_mask_set1_epi64(_mm512_loadu_si512(MSG_LEN(p_state)+8), mb_mask8[1], 0)); + _mm512_storeu_si512(HASH_BUFFIDX(p_state), _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_BUFFIDX(p_state)), mb_mask16, 0)); + + sm3_mask_init_mb16(p_state, mb_mask16); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_final_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_final_mb8.c new file mode 100644 index 000000000..230a3dc81 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_final_mb8.c @@ -0,0 +1,101 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +mbx_status sm3_final_mb8(int8u* hash_pa[8], SM3_CTX_mb8* p_state) +{ + int i; + mbx_status status = 0; + + /* test input pointers */ + if(NULL==hash_pa || NULL==p_state) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + __ALIGN64 int input_len[SM3_NUM_BUFFERS8]; + __ALIGN64 int buffer_len[SM3_NUM_BUFFERS8]; + __ALIGN64 int64u sum_msg_len[SM3_NUM_BUFFERS8]; + + /* allocate local buffer */ + __ALIGN64 int8u loc_buffer[SM3_NUM_BUFFERS8][SM3_MSG_BLOCK_SIZE*2]; + const int8u* buffer_pa[SM3_NUM_BUFFERS8] = { loc_buffer[0], loc_buffer[1], loc_buffer[2], loc_buffer[3], + loc_buffer[4], loc_buffer[5], loc_buffer[6], loc_buffer[7] }; + + /* + // create __mmask8 based on input hash_pa + // corresponding element in mask = 0 if hash_pa[i] = 0 + */ + __m512i zero_buffer = _mm512_setzero_si512(); + __mmask8 mb_mask8 = _mm512_cmp_epi64_mask(_mm512_loadu_si512(hash_pa), zero_buffer, _MM_CMPINT_NE); + + M512(sum_msg_len) = _mm512_maskz_loadu_epi64(mb_mask8, MSG_LEN(p_state)); + + /* put processed message length in bits */ + M512(sum_msg_len) = _mm512_rol_epi64(M512(sum_msg_len), 3); + M512(sum_msg_len) = _mm512_shuffle_epi8(M512(sum_msg_len), M512(swapBytes)); + + M256(input_len) = _mm256_maskz_loadu_epi32(mb_mask8, HASH_BUFFIDX(p_state)); + + __mmask8 tmp_mask = _mm256_cmplt_epi32_mask(M256(input_len), _mm256_set1_epi32(SM3_MSG_BLOCK_SIZE - (int)SM3_MSG_LEN_REPR)); + M256(buffer_len) = _mm256_mask_set1_epi32(_mm256_set1_epi32(SM3_MSG_BLOCK_SIZE * 2), tmp_mask, SM3_MSG_BLOCK_SIZE); + M256(buffer_len) = _mm256_mask_set1_epi32(M256(buffer_len), ~mb_mask8, 0); + + __mmask64 mb_mask64; + for (i = 0; i < SM3_NUM_BUFFERS8; i++) { + /* Copy rest of message into internal buffer */ + mb_mask64 = ~(0xFFFFFFFFFFFFFFFF << input_len[i]); + M512(loc_buffer[i]) = _mm512_maskz_loadu_epi8(mb_mask64, HASH_BUFF(p_state)[i]); + + /* Padd message */ + loc_buffer[i][input_len[i]++] = 0x80; + pad_block(0, loc_buffer[i] + input_len[i], (int)(buffer_len[i] - input_len[i] - (int)SM3_MSG_LEN_REPR)); + ((int64u*)(loc_buffer[i] + buffer_len[i]))[-1] = sum_msg_len[i]; + } + + /* Copmplete hash computation */ + sm3_avx512_mb8(HASH_VALUE(p_state), buffer_pa, buffer_len); + + /* Convert hash into big endian */ + __m256i T[8]; + const int32u* p_T[8] = { (int32u*)&T[0], (int32u*)&T[1], (int32u*)&T[2], (int32u*)&T[3], (int32u*)&T[4], (int32u*)&T[5], (int32u*)&T[6], (int32u*)&T[7] }; + + T[0] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[0])); + T[1] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[1])); + T[2] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[2])); + T[3] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[3])); + T[4] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[4])); + T[5] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[5])); + T[6] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[6])); + T[7] = SIMD_ENDIANNESS32(_mm256_loadu_si256((__m256i*)HASH_VALUE(p_state)[7])); + + /* Transpose hash and store in array with pointers to hash values */ + MASK_TRANSPOSE_8X8_I32((int32u**)hash_pa, p_T, mb_mask8); + + /* re-init hash value using mb masks */ + _mm512_storeu_si512(MSG_LEN(p_state), _mm512_mask_set1_epi64(_mm512_loadu_si512(MSG_LEN(p_state)), mb_mask8, 0)); + _mm256_storeu_si256((__m256i*)HASH_BUFFIDX(p_state), _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i*)HASH_BUFFIDX(p_state)), mb_mask8, 0)); + + sm3_mask_init_mb8(p_state, mb_mask8); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_init_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_init_mb16.c new file mode 100644 index 000000000..118561d10 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_init_mb16.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +void sm3_mask_init_mb16(SM3_CTX_mb16 * p_state, __mmask16 mb_mask) +{ + __mmask8 mb_mask8[2]; + mb_mask8[0] = (__mmask8)mb_mask; + mb_mask8[1] = *((__mmask8*)&mb_mask + 1); + + /* clear buffer index */ + _mm512_storeu_si512(HASH_BUFFIDX(p_state), _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_BUFFIDX(p_state)), mb_mask, 0)); + + /* clear summary message length */ + _mm512_storeu_si512(MSG_LEN(p_state), _mm512_maskz_loadu_epi64(~mb_mask8[0], MSG_LEN(p_state))); + _mm512_storeu_si512(MSG_LEN(p_state) + 8, _mm512_maskz_loadu_epi64(~mb_mask8[1], MSG_LEN(p_state) + 8)); + + + /* clear buffer */ + for (int i = 0; i < SM3_NUM_BUFFERS; i++) { + if ((mb_mask >> i) & 1) + _mm512_storeu_si512(HASH_BUFF(p_state)[i], _mm512_setzero_si512()); + } + + /* setup initial digest in multi-buffer format */ + _mm512_storeu_si512(HASH_VALUE(p_state)[0], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[0]), mb_mask, (int)sm3_iv[0])); + _mm512_storeu_si512(HASH_VALUE(p_state)[1], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[1]), mb_mask, (int)sm3_iv[1])); + _mm512_storeu_si512(HASH_VALUE(p_state)[2], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[2]), mb_mask, (int)sm3_iv[2])); + _mm512_storeu_si512(HASH_VALUE(p_state)[3], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[3]), mb_mask, (int)sm3_iv[3])); + _mm512_storeu_si512(HASH_VALUE(p_state)[4], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[4]), mb_mask, (int)sm3_iv[4])); + _mm512_storeu_si512(HASH_VALUE(p_state)[5], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[5]), mb_mask, (int)sm3_iv[5])); + _mm512_storeu_si512(HASH_VALUE(p_state)[6], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[6]), mb_mask, (int)sm3_iv[6])); + _mm512_storeu_si512(HASH_VALUE(p_state)[7], _mm512_mask_set1_epi32(_mm512_loadu_si512(HASH_VALUE(p_state)[7]), mb_mask, (int)sm3_iv[7])); +} + + +DLL_PUBLIC +mbx_status16 mbx_sm3_init_mb16(SM3_CTX_mb16 * p_state) +{ + mbx_status16 status = 0; + + /* test state pointer */ + if(NULL==p_state) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + sm3_mask_init_mb16(p_state, 0xFFFF); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_init_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_init_mb8.c new file mode 100644 index 000000000..183550ff5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_init_mb8.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +void sm3_mask_init_mb8(SM3_CTX_mb8* p_state, __mmask8 mb_mask) +{ + /* clear buffer index */ + _mm256_storeu_si256((__m256i *)HASH_BUFFIDX(p_state), _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_BUFFIDX(p_state)), mb_mask, 0)); + + /* clear summary message length */ + _mm512_storeu_si512(MSG_LEN(p_state), _mm512_maskz_loadu_epi64(~mb_mask, MSG_LEN(p_state))); + + /* clear buffer */ + for (int i = 0; i < SM3_NUM_BUFFERS8; i++) { + if ((mb_mask >> i) & 1) + _mm512_storeu_si512(HASH_BUFF(p_state)[i], _mm512_setzero_si512()); + } + + /* setup initial digest in multi-buffer format */ + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[0], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[0]), mb_mask, (int)sm3_iv[0])); + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[1], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[1]), mb_mask, (int)sm3_iv[1])); + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[2], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[2]), mb_mask, (int)sm3_iv[2])); + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[3], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[3]), mb_mask, (int)sm3_iv[3])); + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[4], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[4]), mb_mask, (int)sm3_iv[4])); + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[5], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[5]), mb_mask, (int)sm3_iv[5])); + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[6], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[6]), mb_mask, (int)sm3_iv[6])); + _mm256_storeu_si256((__m256i *)HASH_VALUE(p_state)[7], _mm256_mask_set1_epi32(_mm256_loadu_si256((__m256i *)HASH_VALUE(p_state)[7]), mb_mask, (int)sm3_iv[7])); +} + +mbx_status sm3_init_mb8(SM3_CTX_mb8* p_state) +{ + mbx_status status = 0; + + /* test state pointer */ + if(NULL==p_state) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + sm3_mask_init_mb8(p_state, 0xFF); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_messagedigest_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_messagedigest_mb16.c new file mode 100644 index 000000000..155d3ea8f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_messagedigest_mb16.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm3_msg_digest_mb16(const int8u* const msg_pa[16], + int len[16], + int8u* hash_pa[16]) +{ + int buf_no; + mbx_status16 status = 0; + + /* test input pointers */ + if(NULL==msg_pa || NULL==len || NULL==hash_pa) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + for (buf_no = 0; buf_no < SM3_NUM_BUFFERS; buf_no++) { + if ((len[buf_no] && !hash_pa[buf_no]) || (len[buf_no] && !msg_pa[buf_no])) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + return status; + } + } + + /* initialize the context of SM3 hash */ + SM3_CTX_mb16 p_state; + mbx_sm3_init_mb16(&p_state); + + /* process main part of the message */ + status = mbx_sm3_update_mb16(msg_pa, len, &p_state); + + if(MBX_IS_ANY_OK_STS16(status)) { + /* finalize message processing */ + status = mbx_sm3_final_mb16(hash_pa, &p_state); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_messagedigest_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_messagedigest_mb8.c new file mode 100644 index 000000000..93f3e4635 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_messagedigest_mb8.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +mbx_status sm3_msg_digest_mb8(const int8u* const msg_pa[8], int len[8], int8u* hash_pa[8]) +{ + int buf_no; + mbx_status status = 0; + + /* test input pointers */ + if(NULL==msg_pa || NULL==len || NULL==hash_pa) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + for (buf_no = 0; buf_no < SM3_NUM_BUFFERS8; buf_no++) { + if ((len[buf_no] && !hash_pa[buf_no]) || (len[buf_no] && !msg_pa[buf_no])) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + return status; + } + } + + /* initialize the context of SM3 hash */ + SM3_CTX_mb8 p_state; + sm3_init_mb8(&p_state); + + /* process main part of the message */ + status = sm3_update_mb8(msg_pa, len, &p_state); + + if(MBX_IS_ANY_OK_STS(status)) { + /* finalize message processing */ + status = sm3_final_mb8(hash_pa, &p_state); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_update_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_update_mb16.c new file mode 100644 index 000000000..5d341627f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_update_mb16.c @@ -0,0 +1,150 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +// Disable optimization for VS17 +#if defined(_MSC_VER) && (_MSC_VER < 1920) && !defined(__INTEL_COMPILER) + #pragma optimize( "", off ) +#endif + +DLL_PUBLIC +mbx_status16 mbx_sm3_update_mb16(const int8u* const msg_pa[16], + int len[16], + SM3_CTX_mb16* p_state) +{ + int i; + mbx_status16 status = 0; + + /* test input pointers */ + if (NULL == msg_pa || NULL == len || NULL == p_state) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + __m512i loc_len = _mm512_loadu_si512(len); + int* p_loc_len = (int*)&loc_len; + + /* generate mask based on array with messages lengths */ + __m512i zero_buffer = _mm512_setzero_si512(); + __mmask16 mb_mask16 = _mm512_cmp_epi32_mask(loc_len, zero_buffer, _MM_CMPINT_NE); + + /* generate mask based on array with pointers to messages */ + __mmask8 mb_mask8[2]; + mb_mask8[0] = _mm512_cmp_epi64_mask(_mm512_loadu_si512(msg_pa), zero_buffer, _MM_CMPINT_NE); + mb_mask8[1] = _mm512_cmp_epi64_mask(_mm512_loadu_si512(msg_pa + 8), zero_buffer, _MM_CMPINT_NE); + + /* don't process the data from i buffer if in msg_pa[i] == 0 or len[i] == 0 */ + mb_mask16 &= *(__mmask16*)mb_mask8; + mb_mask8[0] = (__mmask8)mb_mask16; + mb_mask8[1] = *((__mmask8*)&mb_mask16 + 1); + + /* handle non empty request */ + if (mb_mask16) { + __ALIGN64 const int8u* loc_src[SM3_NUM_BUFFERS]; + _mm512_storeu_si512((void*)loc_src, _mm512_mask_loadu_epi64(_mm512_set1_epi64((long long)&zero_buffer), mb_mask8[0], msg_pa)); + _mm512_storeu_si512((void *)(loc_src + 8), _mm512_mask_loadu_epi64(_mm512_set1_epi64((long long)&zero_buffer), mb_mask8[1], msg_pa + 8)); + + __m512i proc_len; + __m512i idx = _mm512_loadu_si512(HASH_BUFFIDX(p_state)); + + int* p_proc_len = (int*)&proc_len; + int* p_idx = (int*)&idx; + + __ALIGN64 + int64u sum_msg_len[SM3_NUM_BUFFERS] = { (int64u)p_loc_len[0], (int64u)p_loc_len[1], (int64u)p_loc_len[2], (int64u)p_loc_len[3], + (int64u)p_loc_len[4], (int64u)p_loc_len[5], (int64u)p_loc_len[6], (int64u)p_loc_len[7], + (int64u)p_loc_len[8], (int64u)p_loc_len[9], (int64u)p_loc_len[10], (int64u)p_loc_len[11], + (int64u)p_loc_len[12], (int64u)p_loc_len[13], (int64u)p_loc_len[14], (int64u)p_loc_len[15] }; + + __ALIGN64 + int8u* p_buffer[SM3_NUM_BUFFERS] = { HASH_BUFF(p_state)[0], HASH_BUFF(p_state)[1], HASH_BUFF(p_state)[2], HASH_BUFF(p_state)[3], + HASH_BUFF(p_state)[4], HASH_BUFF(p_state)[5], HASH_BUFF(p_state)[6], HASH_BUFF(p_state)[7], + HASH_BUFF(p_state)[8], HASH_BUFF(p_state)[9], HASH_BUFF(p_state)[10], HASH_BUFF(p_state)[11], + HASH_BUFF(p_state)[12], HASH_BUFF(p_state)[13], HASH_BUFF(p_state)[14], HASH_BUFF(p_state)[15] }; + + __mmask16 processed_mask = _mm512_cmp_epi32_mask(idx, zero_buffer, _MM_CMPINT_NE); + + M512(sum_msg_len) = _mm512_mask_add_epi64(M512(sum_msg_len), mb_mask8[0], _mm512_loadu_si512(MSG_LEN(p_state)), M512(sum_msg_len)); + M512(sum_msg_len + 8) = _mm512_mask_add_epi64(M512(sum_msg_len + 8), mb_mask8[1], _mm512_loadu_si512(MSG_LEN(p_state) + 8), M512(sum_msg_len + 8)); + + /* if non empty internal buffer filling */ + if (processed_mask) { + /* calculate how many bytes need to be added in the internal buffer */ + __m512i empty_bytes_buffer = _mm512_sub_epi32(_mm512_set1_epi32(SM3_MSG_BLOCK_SIZE), idx); + processed_mask = _mm512_cmp_epi32_mask(_mm512_sub_epi32(loc_len, empty_bytes_buffer), zero_buffer, _MM_CMPINT_LT); + proc_len = _mm512_mask_loadu_epi32(empty_bytes_buffer, processed_mask, p_loc_len); + + /* copy from valid input streams to the internal buffers as much as possible */ + for (i = 0; i < SM3_NUM_BUFFERS; i++) { + if ((mb_mask16 >> i) & 0x1) { + __mmask64 mb_mask64 = 0xFFFFFFFFFFFFFFFF >> (SM3_MSG_BLOCK_SIZE - p_proc_len[i]); + _mm512_storeu_si512(p_buffer[i] + p_idx[i], _mm512_mask_loadu_epi8(_mm512_loadu_si512(p_buffer[i] + p_idx[i]), mb_mask64, loc_src[i])); + } + } + + idx = _mm512_add_epi32(idx, proc_len); + loc_len = _mm512_sub_epi32(loc_len, proc_len); + + M512(loc_src) = _mm512_add_epi64(M512(loc_src), _mm512_cvtepu32_epi64(M256(p_proc_len))); + M512(loc_src+8) = _mm512_add_epi64(M512(loc_src+8), _mm512_cvtepu32_epi64(M256(p_proc_len+8))); + + processed_mask = _mm512_cmp_epi32_mask(idx, _mm512_set1_epi32(SM3_MSG_BLOCK_SIZE), _MM_CMPINT_EQ); + proc_len = _mm512_maskz_set1_epi32(processed_mask, SM3_MSG_BLOCK_SIZE); + + /* update digest if at least one buffer is full */ + if (processed_mask) { + sm3_avx512_mb16(HASH_VALUE(p_state), (const int8u **)p_buffer, p_proc_len); + idx = _mm512_mask_set1_epi32(idx, ~_mm512_cmp_epi32_mask(proc_len, zero_buffer, _MM_CMPINT_LE), 0); + } + } + + /* main message part processing */ + proc_len = _mm512_and_epi32(loc_len, _mm512_set1_epi32(-SM3_MSG_BLOCK_SIZE)); + processed_mask = _mm512_cmp_epi32_mask(proc_len, zero_buffer, _MM_CMPINT_NLT); + + if (processed_mask) + sm3_avx512_mb16(HASH_VALUE(p_state), loc_src, p_proc_len); + + loc_len = _mm512_sub_epi32(loc_len, proc_len); + + M512(loc_src) = _mm512_add_epi64(M512(loc_src), _mm512_cvtepu32_epi64(M256(p_proc_len))); + M512(loc_src + 8) = _mm512_add_epi64(M512(loc_src + 8), _mm512_cvtepu32_epi64(M256(p_proc_len + 8))); + processed_mask = _mm512_cmp_epi32_mask(loc_len, zero_buffer, _MM_CMPINT_NLE); + + /* store rest of message into the internal buffer */ + for (i = 0; i < SM3_NUM_BUFFERS; i++) { + if ((processed_mask >> i) & 0x1) { + __mmask64 mb_mask64 = ~(0xFFFFFFFFFFFFFFFF << *(p_loc_len + i)); + _mm512_storeu_si512(p_buffer[i], _mm512_maskz_loadu_epi8(mb_mask64, loc_src[i])); + } + } + + idx = _mm512_add_epi32(idx, loc_len); + + /* Update length of processed message */ + _mm512_storeu_si512(MSG_LEN(p_state), _mm512_mask_loadu_epi64(_mm512_loadu_si512(MSG_LEN(p_state)), mb_mask8[0], sum_msg_len)); + _mm512_storeu_si512(MSG_LEN(p_state) + 8, _mm512_mask_loadu_epi64(_mm512_loadu_si512(MSG_LEN(p_state) + 8), mb_mask8[1], sum_msg_len + 8)); + _mm512_storeu_si512(HASH_BUFFIDX(p_state), _mm512_mask_loadu_epi32(_mm512_loadu_si512(HASH_BUFFIDX(p_state)), mb_mask16, p_idx)); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_update_mb8.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_update_mb8.c new file mode 100644 index 000000000..b30bbae43 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm3/sm3_update_mb8.c @@ -0,0 +1,136 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +// Disable optimization for VS17 +#if defined(_MSC_VER) && (_MSC_VER < 1920) && !defined(__INTEL_COMPILER) + #pragma optimize( "", off ) +#endif + +mbx_status sm3_update_mb8(const int8u* const msg_pa[8], int len[8], SM3_CTX_mb8* p_state) +{ + int i; + mbx_status status = 0; + + /* test input pointers */ + if (NULL == msg_pa || NULL == len || NULL == p_state) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + __ALIGN64 const int8u* loc_src[SM3_NUM_BUFFERS8]; + + __m256i loc_len = _mm256_loadu_si256((__m256i*)len); + int* p_loc_len = (int*)&loc_len; + + __m512i zero_buffer = _mm512_setzero_si512(); + + /* generate mask based on array with messages lengths */ + __mmask8 mb_mask = _mm256_cmp_epi32_mask(loc_len, M256(&zero_buffer), _MM_CMPINT_NE); + + /* generate mask based on msg_pa[]. Don't process the data from i buffer if in msg_pa[i] == 0 or len[i] == 0 */ + mb_mask &= _mm512_cmp_epi64_mask(_mm512_loadu_si512(msg_pa), zero_buffer, _MM_CMPINT_NE); + + /* handle non empty message */ + if (mb_mask) { + _mm512_storeu_si512((void *)loc_src, _mm512_mask_loadu_epi64(_mm512_set1_epi64((long long)&zero_buffer), mb_mask, msg_pa)); + + __m256i proc_len; + __m256i idx = _mm256_loadu_si256((__m256i*)HASH_BUFFIDX(p_state)); + + int* p_proc_len = (int*)&proc_len; + int* p_idx = (int*)&idx; + + __ALIGN64 + int64u sum_msg_len[SM3_NUM_BUFFERS8] = { (int64u)p_loc_len[0], (int64u)p_loc_len[1], (int64u)p_loc_len[2], (int64u)p_loc_len[3], + (int64u)p_loc_len[4], (int64u)p_loc_len[5], (int64u)p_loc_len[6], (int64u)p_loc_len[7] }; + + __ALIGN64 + int8u* p_buffer[SM3_NUM_BUFFERS8] = { HASH_BUFF(p_state)[0], HASH_BUFF(p_state)[1], HASH_BUFF(p_state)[2], HASH_BUFF(p_state)[3], + HASH_BUFF(p_state)[4], HASH_BUFF(p_state)[5], HASH_BUFF(p_state)[6], HASH_BUFF(p_state)[7] }; + + __mmask8 processed_mask = _mm256_cmp_epi32_mask(idx, M256(&zero_buffer), _MM_CMPINT_NE); + + M512(sum_msg_len) = _mm512_mask_add_epi64(M512(sum_msg_len), mb_mask, _mm512_loadu_si512(MSG_LEN(p_state)), M512(sum_msg_len)); + + /* if non empty internal buffer filling */ + if (processed_mask) { + + __m256i tmp = _mm256_sub_epi32(_mm256_set1_epi32(SM3_MSG_BLOCK_SIZE), idx); + processed_mask = _mm256_cmp_epi32_mask(_mm256_sub_epi32(loc_len, tmp), M256(&zero_buffer), _MM_CMPINT_LT); + + /* p_proc_len[i] = MIN(p_loc_len[i], (SM3_MSG_BLOCK_SIZE - p_idx[i])) */ + proc_len = _mm256_mask_loadu_epi32(tmp, processed_mask, p_loc_len); + + /* copy from input stream to the internal buffer as match as possible */ + for (i = 0; i < SM3_NUM_BUFFERS8; i++) { + /* copy from input stream to the internal buffer as match as possible */ + __mmask64 mb_mask64 = ~(0xFFFFFFFFFFFFFFFF << p_proc_len[i]); + _mm512_storeu_si512(p_buffer[i] + p_idx[i], _mm512_mask_loadu_epi8(_mm512_loadu_si512(p_buffer[i] + p_idx[i]), mb_mask64, loc_src[i])); + } + + idx = _mm256_add_epi32(idx, proc_len); + loc_len = _mm256_sub_epi32(loc_len, proc_len); + + M512(loc_src) = _mm512_add_epi64(M512(loc_src), _mm512_cvtepu32_epi64(M256(p_proc_len))); + + processed_mask = _mm256_cmp_epi32_mask(idx, _mm256_set1_epi32(SM3_MSG_BLOCK_SIZE), _MM_CMPINT_EQ); + proc_len = _mm256_mask_set1_epi32(proc_len, processed_mask, SM3_MSG_BLOCK_SIZE); + + /* update digest if at least one buffer is full */ + if (processed_mask) { + sm3_avx512_mb8(HASH_VALUE(p_state), (const int8u **)p_buffer, p_proc_len); + idx = _mm256_mask_set1_epi32(idx, ~_mm256_cmp_epi32_mask(proc_len, M256(&zero_buffer), 2), _MM_CMPINT_EQ); + } + } + + /* main message part processing */ + proc_len = _mm256_and_si256(loc_len, _mm256_set1_epi32(-SM3_MSG_BLOCK_SIZE)); + processed_mask = _mm256_cmp_epi32_mask(proc_len, M256(&zero_buffer), _MM_CMPINT_NLT); + + if (processed_mask) + sm3_avx512_mb8(HASH_VALUE(p_state), loc_src, p_proc_len); + + loc_len = _mm256_sub_epi32(loc_len, proc_len); + + M512(loc_src) = _mm512_add_epi64(M512(loc_src), _mm512_cvtepu32_epi64(M256(p_proc_len))); + + processed_mask = _mm256_cmp_epi32_mask(loc_len, M256(&zero_buffer), _MM_CMPINT_NLE); + + /* store rest of message into the internal buffer */ + if (processed_mask) { + for (i = 0; i < SM3_NUM_BUFFERS8; i++) { + /* copy from input stream to the internal buffer as match as possible */ + __mmask64 mb_mask64 = ~(0xFFFFFFFFFFFFFFFF << *(p_loc_len + i)); + _mm512_storeu_si512(p_buffer[i], _mm512_maskz_loadu_epi8(mb_mask64, loc_src[i])); + } + + idx = _mm256_maskz_add_epi32(0xFF, idx, loc_len); + } + + /* Update length of processed message */ + _mm512_storeu_si512(MSG_LEN(p_state), _mm512_mask_loadu_epi64(_mm512_loadu_si512(MSG_LEN(p_state)), mb_mask, sum_msg_len)); + _mm512_storeu_si512(HASH_BUFFIDX(p_state), _mm512_mask_loadu_epi32(_mm512_loadu_si512(HASH_BUFFIDX(p_state)), mb_mask, p_idx)); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_decrypt_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_decrypt_mb16.c new file mode 100644 index 000000000..ac84db656 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_decrypt_mb16.c @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include +#include + +/* + * This function performs decryption with CTR and then authentication with CBC-MAC on plaintext. + * Function returns mask where bit is set to 1 if length of given data for buffer is overflowed. +*/ + +void sm4_ccm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context) +{ + __m128i *hash = SM4_CCM_CONTEXT_HASH(p_context); + __m128i *ctr = SM4_CCM_CONTEXT_CTR(p_context); + + const int8u *hash_ptrs[SM4_LINES]; + int8u *pa_ctr[SM4_LINES]; + unsigned i; + int full_hash_len[SM4_LINES]; + int partial_hash_len[SM4_LINES]; + int8u padded_hash[SM4_LINES][SM4_BLOCK_SIZE]; + int8u *pa_padded_hash[SM4_LINES]; + __mmask16 partial_block_mask = 0; + + /* No AAD processed */ + if (SM4_CCM_CONTEXT_STATE(p_context) == sm4_ccm_update_aad) { + int aad_lens[SM4_LINES]; + + PadBlock(0, aad_lens, sizeof(aad_lens)); + sm4_ccm_update_aad_mb16(NULL, aad_lens, 0xFFFF, p_context); + } + + /* Switch context state to decryption */ + SM4_CCM_CONTEXT_STATE(p_context) = sm4_ccm_dec; + + for (i = 0; i < SM4_LINES; i++) { + hash_ptrs[i] = (int8u *) &hash[i]; + pa_ctr[i] = (int8u *) &ctr[i]; + full_hash_len[i] = in_len[i] & 0xFFFFFFF0; + } + + /* Decrypt first */ + sm4_ctr128_kernel_mb16(pa_out, (const int8u **) pa_in, in_len, (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), mb_mask, pa_ctr); + + /* Authenticate the plaintext */ + sm4_cbc_mac_kernel_mb16(hash, (const int8u *const *) pa_out, + full_hash_len, + (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), + mb_mask, + hash_ptrs); + + /* Handle partial blocks of plaintext */ + for (i = 0; i < SM4_LINES; i++) { + partial_hash_len[i] = in_len[i] & 0xF; + if (partial_hash_len[i] == 0) + continue; + pa_padded_hash[i] = padded_hash[i]; + PadBlock(0, pa_padded_hash[i], SM4_BLOCK_SIZE); + CopyBlock(pa_out[i] + full_hash_len[i], pa_padded_hash[i], partial_hash_len[i]); + full_hash_len[i] = SM4_BLOCK_SIZE; + partial_block_mask |= (1 << i); + } + if (partial_block_mask != 0) { + sm4_cbc_mac_kernel_mb16(hash, (const int8u *const *) pa_padded_hash, + full_hash_len, + (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), + partial_block_mask, + hash_ptrs); + SM4_CCM_CONTEXT_STATE(p_context) = sm4_ccm_get_tag; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_encrypt_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_encrypt_mb16.c new file mode 100644 index 000000000..01bd604c6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_encrypt_mb16.c @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include +#include + +/* + * This function performs authentication with CBC-MAC on plaintext and encryption with CTR. +*/ + +void sm4_ccm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context) +{ + __m128i *hash = SM4_CCM_CONTEXT_HASH(p_context); + __m128i *ctr = SM4_CCM_CONTEXT_CTR(p_context); + + const int8u *hash_ptrs[SM4_LINES]; + int8u *pa_ctr[SM4_LINES]; + unsigned i; + int full_hash_len[SM4_LINES]; + int partial_hash_len[SM4_LINES]; + int8u padded_hash[SM4_LINES][SM4_BLOCK_SIZE]; + int8u *pa_padded_hash[SM4_LINES]; + __mmask16 partial_block_mask = 0; + + /* No AAD processed */ + if (SM4_CCM_CONTEXT_STATE(p_context) == sm4_ccm_update_aad) { + int aad_lens[SM4_LINES]; + + PadBlock(0, aad_lens, sizeof(aad_lens)); + sm4_ccm_update_aad_mb16(NULL, aad_lens, 0xFFFF, p_context); + } + + /* Switch context state to encryption */ + SM4_CCM_CONTEXT_STATE(p_context) = sm4_ccm_enc; + + for (i = 0; i < SM4_LINES; i++) { + hash_ptrs[i] = (int8u *) &hash[i]; + pa_ctr[i] = (int8u *) &ctr[i]; + full_hash_len[i] = in_len[i] & 0xFFFFFFF0; /* Get full block lengths */ + } + sm4_cbc_mac_kernel_mb16(hash, (const int8u *const *) pa_in, + full_hash_len, + (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), + mb_mask, + hash_ptrs); + + /* Handle partial blocks of plaintext */ + for (i = 0; i < SM4_LINES; i++) { + partial_hash_len[i] = in_len[i] & 0xF; /* Retrieve partial block lengths */ + if (partial_hash_len[i] == 0) + continue; + pa_padded_hash[i] = padded_hash[i]; + PadBlock(0, pa_padded_hash[i], SM4_BLOCK_SIZE); + CopyBlock(pa_in[i] + full_hash_len[i], pa_padded_hash[i], partial_hash_len[i]); + full_hash_len[i] = SM4_BLOCK_SIZE; + partial_block_mask |= (1 << i); + } + if (partial_block_mask != 0) { + sm4_cbc_mac_kernel_mb16(hash, (const int8u *const *) pa_padded_hash, + full_hash_len, + (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), + partial_block_mask, + hash_ptrs); + SM4_CCM_CONTEXT_STATE(p_context) = sm4_ccm_get_tag; + } + sm4_ctr128_kernel_mb16(pa_out, (const int8u **) pa_in, in_len, (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), mb_mask, pa_ctr); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_get_tag_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_get_tag_mb16.c new file mode 100644 index 000000000..5993fcb7c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_get_tag_mb16.c @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include +#include /* for zero_mb8 */ + +static void sm4_encrypt_ctr0_mb16(SM4_CCM_CTX_mb16 *p_context, __m512i *s0_blocks) +{ + const mbx_sm4_key_schedule *key_sched = (const mbx_sm4_key_schedule *)SM4_CCM_CONTEXT_KEY(p_context); + + __m128i *ctr0 = SM4_CCM_CONTEXT_CTR0(p_context); + + const int8u *pa_inp[SM4_LINES]; + + for (int i = 0; i < SM4_LINES; i++) + pa_inp[i] = (unsigned char *)(ctr0 + i); + + TRANSPOSE_16x4_I32_EPI32(&s0_blocks[0], &s0_blocks[1], &s0_blocks[2], &s0_blocks[3], pa_inp, 0xFFFF); + + const __m512i *p_rk = (const __m512i *)key_sched; + + __m512i tmp; + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) + SM4_FOUR_ROUNDS(s0_blocks[0], s0_blocks[1], s0_blocks[2], s0_blocks[3], tmp, p_rk, 1); + + __m512i T1_0 = unpacklo_epi32(s0_blocks[0], s0_blocks[1]); + __m512i T1_1 = unpackhi_epi32(s0_blocks[0], s0_blocks[1]); + __m512i T1_2 = unpacklo_epi32(s0_blocks[2], s0_blocks[3]); + __m512i T1_3 = unpackhi_epi32(s0_blocks[2], s0_blocks[3]); + + s0_blocks[0] = unpacklo_epi64(T1_0, T1_2); + s0_blocks[1] = unpackhi_epi64(T1_0, T1_2); + s0_blocks[2] = unpacklo_epi64(T1_1, T1_3); + s0_blocks[3] = unpackhi_epi64(T1_1, T1_3); + + s0_blocks[0] = shuffle_epi8(s0_blocks[0], M512(swapEndianness)); + s0_blocks[1] = shuffle_epi8(s0_blocks[1], M512(swapEndianness)); + s0_blocks[2] = shuffle_epi8(s0_blocks[2], M512(swapEndianness)); + s0_blocks[3] = shuffle_epi8(s0_blocks[3], M512(swapEndianness)); + + T1_0 = _mm512_shuffle_i64x2(s0_blocks[0], s0_blocks[1], 0x44); + T1_1 = _mm512_shuffle_i64x2(s0_blocks[0], s0_blocks[1], 0xEE); + T1_2 = _mm512_shuffle_i64x2(s0_blocks[2], s0_blocks[3], 0x44); + T1_3 = _mm512_shuffle_i64x2(s0_blocks[2], s0_blocks[3], 0xEE); + + s0_blocks[0] = _mm512_shuffle_i64x2(T1_0, T1_2, 0x88); + s0_blocks[1] = _mm512_shuffle_i64x2(T1_0, T1_2, 0xDD); + s0_blocks[2] = _mm512_shuffle_i64x2(T1_1, T1_3, 0x88); + s0_blocks[3] = _mm512_shuffle_i64x2(T1_1, T1_3, 0xDD); +} + +void sm4_ccm_get_tag_mb16(int8u *pa_out[SM4_LINES], const int tag_len[SM4_LINES], __mmask16 mb_mask, SM4_CCM_CTX_mb16 *p_context) +{ + __m512i s0_blocks[4]; + __m512i hash_blocks[4]; + + __m128i *hash = SM4_CCM_CONTEXT_HASH(p_context); + + /* Calculate S0 */ + sm4_encrypt_ctr0_mb16(p_context, s0_blocks); + + hash_blocks[0] = loadu(hash); + hash_blocks[1] = loadu(hash + 4); + hash_blocks[2] = loadu(hash + 4*2); + hash_blocks[3] = loadu(hash + 4*3); + + __m512i tag_blocks[4]; + + /* XOR with previously encrypted J0 */ + tag_blocks[0] = xor(hash_blocks[0], s0_blocks[0]); + tag_blocks[1] = xor(hash_blocks[1], s0_blocks[1]); + tag_blocks[2] = xor(hash_blocks[2], s0_blocks[2]); + tag_blocks[3] = xor(hash_blocks[3], s0_blocks[3]); + + /* Store result */ + for (int i = 0; i < SM4_LINES; i++) { + __m128i one_block = M128((__m128i *)tag_blocks + i); + + __mmask16 tagMask = ~(0xFFFF << (tag_len[i])) * ((mb_mask >> i) & 0x1); + _mm_mask_storeu_epi8((void *)(pa_out[i]), tagMask, one_block); + } + + /* Clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])tag_blocks, sizeof(tag_blocks) / sizeof(tag_blocks[0])); + zero_mb8((int64u(*)[8])hash_blocks, sizeof(hash_blocks) / sizeof(hash_blocks[0])); + zero_mb8((int64u(*)[8])s0_blocks, sizeof(s0_blocks) / sizeof(s0_blocks[0])); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_set_msg_len_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_set_msg_len_mb16.c new file mode 100644 index 000000000..644c78a8c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_set_msg_len_mb16.c @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void sm4_ccm_set_msg_len_mb16(const int64u msg_len[SM4_LINES], __mmask16 mb_mask, SM4_CCM_CTX_mb16 *p_context) +{ + int64u *msg_len_ctx = SM4_CCM_CONTEXT_MSG_LEN(p_context); + unsigned i; + + for (i = 0; i < SM4_LINES; i++) + if (mb_mask & (1 << i)) + msg_len_ctx[i] = msg_len[i]; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_set_tag_len_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_set_tag_len_mb16.c new file mode 100644 index 000000000..d0ea49455 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_set_tag_len_mb16.c @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +void sm4_ccm_set_tag_len_mb16(const int tag_len[SM4_LINES], __mmask16 mb_mask, SM4_CCM_CTX_mb16 *p_context) +{ + int *tag_len_ctx = SM4_CCM_CONTEXT_TAG_LEN(p_context); + unsigned i; + + for (i = 0; i < SM4_LINES; i++) { + if (mb_mask & (1 << i)) { + tag_len_ctx[i] = tag_len[i]; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_update_aad_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_update_aad_mb16.c new file mode 100644 index 000000000..fd6f05d9c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_update_aad_mb16.c @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include +#include + +#define MAX_AAD_SIZE_BLOCKS_0_3 46 +/* + * This function process 16 buffers with additional authentication data (AAD), + * up to 2^16 - 2^8 bytes +*/ + +void sm4_ccm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], + const int aad_len[SM4_LINES], + __mmask16 mb_mask, + SM4_CCM_CTX_mb16 *p_context) +{ + __m128i *ctr0 = SM4_CCM_CONTEXT_CTR0(p_context); + int *tag_len = SM4_CCM_CONTEXT_TAG_LEN(p_context); + int *iv_len = SM4_CCM_CONTEXT_IV_LEN(p_context); + int64u *msg_len = SM4_CCM_CONTEXT_MSG_LEN(p_context); + __m128i *hash = SM4_CCM_CONTEXT_HASH(p_context); + /* Scratch memory to construct up to 4 blocks to authenticate (up to 46 byte of AAD) */ + int8u tmp[SM4_LINES][SM4_BLOCK_SIZE*4]; + const int8u *block_ptrs[SM4_LINES]; + const int8u *hash_ptrs[SM4_LINES]; + int auth_lens[SM4_LINES]; + unsigned i, j; + int8u iv[SM4_LINES][SM4_BLOCK_SIZE]; + const int8u *iv_ptrs[SM4_LINES]; + int additional_lens[SM4_LINES]; + + __m512i max_msg16b_len = set1_epi64(0xFFFF); + __mmask16 additional_len_mask = _mm512_cmp_epi32_mask(set1_epi32(MAX_AAD_SIZE_BLOCKS_0_3), loadu(aad_len), _MM_CMPINT_LT); + __mmask8 msg_len_overflow_lo_mask = _mm512_cmp_epi64_mask(max_msg16b_len, loadu(msg_len), _MM_CMPINT_LE); + __mmask8 msg_len_overflow_hi_mask = _mm512_cmp_epi64_mask(max_msg16b_len, loadu(msg_len + 8), _MM_CMPINT_LE); + __mmask16 msg_len_overflow_mask = (__mmask16) msg_len_overflow_hi_mask << 8 | (__mmask16) msg_len_overflow_lo_mask; + + additional_len_mask = _mm512_kand(additional_len_mask, mb_mask); + + PadBlock(0, tmp, sizeof(tmp)); + PadBlock(0, iv, sizeof(iv)); + + for (i = 0; i < SM4_LINES; i++) { + + additional_lens[i] = 0; + + if ((mb_mask & (1 << i)) == 0) { + auth_lens[i] = 0; + block_ptrs[i] = NULL; + hash_ptrs[i] = NULL; + iv_ptrs[i] = NULL; + continue; + } + + CopyBlock(&ctr0[i], tmp[i], SM4_BLOCK_SIZE); + + int8u flags = tmp[i][0]; + + int8u tag_len_enc = (tag_len[i] - 2) >> 1; + + flags |= (tag_len_enc) << 3; + auth_lens[i] = SM4_BLOCK_SIZE; + block_ptrs[i] = tmp[i]; + hash_ptrs[i] = (int8u *) &hash[i]; + iv_ptrs[i] = iv[i]; + if (aad_len[i]) { + int len; + + if (aad_len[i] > MAX_AAD_SIZE_BLOCKS_0_3) { + len = MAX_AAD_SIZE_BLOCKS_0_3; + additional_lens[i] = aad_len[i] - MAX_AAD_SIZE_BLOCKS_0_3; + } else + len = aad_len[i]; + flags |= 1 << 6; + /* Copy AAD length to first 2 bytes of B_1 */ + tmp[i][16] = (int8u) (aad_len[i] >> 8); + tmp[i][17] = (int8u) aad_len[i]; + /* Copy AAD afterwards */ + CopyBlock(pa_aad[i], &tmp[i][18], len); + auth_lens[i] += (2 + 15 + len); + auth_lens[i] &= 0xfff0; /* Multiple of 16 bytes */ + } + tmp[i][0] = flags; + tmp[i][15] = (int8u) msg_len[i]; + tmp[i][14] = (int8u) (msg_len[i] >> 8); + } + + /* Check if message is longer than 2^16 - 1 and set the length appropriately in block 0 */ + if (msg_len_overflow_mask) { + for (i = 0; i < SM4_LINES; i++) { + const unsigned num_bits_msg_len = 15 - iv_len[i]; + const int64u max_len = (num_bits_msg_len == 8) ? 0xFFFFFFFFFFFFFFFF : + (1ULL << (num_bits_msg_len << 3)); + + if (msg_len[i] < max_len) { + for (j = 2; j < num_bits_msg_len; j++) + tmp[i][15-j] = (int8u) (msg_len[i] >> (8*j)); + } + } + } + sm4_cbc_mac_kernel_mb16(hash, (const int8u *const *) block_ptrs, + auth_lens, + (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), + mb_mask, iv_ptrs); + + /* More AAD to process */ + if (additional_len_mask) { + for (i = 0; i < SM4_LINES; i++) { + if (additional_lens[i]) { + block_ptrs[i] = pa_aad[i] + MAX_AAD_SIZE_BLOCKS_0_3; /* First 46 bytes have been processed */ + auth_lens[i] = additional_lens[i] & 0xfff0; /* Multiple of 16 bytes */ + additional_lens[i] -= auth_lens[i]; + if (auth_lens[i] == 0) + additional_len_mask &= ~(1 << i); + } + } + + sm4_cbc_mac_kernel_mb16(hash, (const int8u *const *) block_ptrs, + auth_lens, + (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), + additional_len_mask, hash_ptrs); + + additional_len_mask = _mm512_cmp_epi32_mask(set1_epi32(0), + loadu(additional_lens), + _MM_CMPINT_NE); + /* Process last blocks (up to 15 bytes) */ + for (i = 0; i < SM4_LINES; i++) { + if (additional_lens[i]) { + block_ptrs[i] = tmp[i]; /* First 46 bytes have been processed */ + PadBlock(0, tmp[i], SM4_BLOCK_SIZE); + CopyBlock(pa_aad[i] + MAX_AAD_SIZE_BLOCKS_0_3 + auth_lens[i], tmp[i], + additional_lens[i]); + auth_lens[i] = SM4_BLOCK_SIZE; + } + } + sm4_cbc_mac_kernel_mb16(hash, (const int8u *const *) block_ptrs, + auth_lens, + (const int32u **)SM4_CCM_CONTEXT_KEY(p_context), + additional_len_mask, hash_ptrs); + + } + + if (cmp_epi32_mask(loadu(aad_len), setzero(), _MM_CMPINT_EQ) != 0xFFFF) + SM4_CCM_CONTEXT_STATE(p_context) = sm4_ccm_start_encdec; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_update_iv_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_update_iv_mb16.c new file mode 100644 index 000000000..796441e7c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/internal/sm4_ccm_update_iv_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +/* +// This function process 16 buffers with initialization vector (IV) data +*/ +void sm4_ccm_update_iv_mb16(const int8u *const pa_iv[SM4_LINES], const int iv_len[SM4_LINES], __mmask16 mb_mask, SM4_CCM_CTX_mb16 *p_context) +{ + int *iv_len_ctx = SM4_CCM_CONTEXT_IV_LEN(p_context); + __m128i *ctr0 = SM4_CCM_CONTEXT_CTR0(p_context); + __m128i *ctr = SM4_CCM_CONTEXT_CTR(p_context); + + unsigned i; + + for (i = 0; i < SM4_LINES; i++) { + if (mb_mask & (1 << i)) { + int8u flags; + unsigned L; + int iv_len_i = iv_len[i]; + + L = 15 - iv_len_i; + flags = L - 1; + /* Update CTR0 for each lane */ + int8u *ctr0_nonce_ptr = (int8u *) &(ctr0[i]); + PadBlock(0, ctr0_nonce_ptr, 16); + CopyBlock(pa_iv[i], ctr0_nonce_ptr + 1, iv_len_i); + ctr0_nonce_ptr[0] = flags; + + /* Update CTR for each lane (counter = 1 to start encryption) */ + int8u *ctr_nonce_ptr = (int8u *) &(ctr[i]); + PadBlock(0, ctr_nonce_ptr, 16); + CopyBlock(pa_iv[i], ctr_nonce_ptr + 1, iv_len_i); + ctr_nonce_ptr[0] = flags; + ctr_nonce_ptr[15] = 1; + iv_len_ctx[i] = iv_len[i]; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_decrypt_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_decrypt_mb16_api.c new file mode 100644 index 000000000..ab0251116 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_decrypt_mb16_api.c @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 +mbx_sm4_ccm_decrypt_mb16(int8u *pa_out[SM4_LINES], const int8u *const pa_in[SM4_LINES], const int in_len[SM4_LINES], SM4_CCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + int64u *processed_len = SM4_CCM_CONTEXT_PROCESSED_LEN(p_context); + int64u *msg_len = SM4_CCM_CONTEXT_MSG_LEN(p_context); + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_in || NULL == in_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_ccm_update_aad != SM4_CCM_CONTEXT_STATE(p_context) && + sm4_ccm_start_encdec != SM4_CCM_CONTEXT_STATE(p_context) && + sm4_ccm_dec != SM4_CCM_CONTEXT_STATE(p_context)) { + + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + /* Don't process buffers with NULL pointers or wrong input length */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_in[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + + if (in_len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + processed_len[buf_no] += in_len[buf_no]; + /* Check if total processed length will exceed the total message length passed at init */ + if (processed_len[buf_no] > msg_len[buf_no]) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_ccm_decrypt_mb16(pa_out, pa_in, in_len, mb_mask, p_context); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_encrypt_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_encrypt_mb16_api.c new file mode 100644 index 000000000..c1976a296 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_encrypt_mb16_api.c @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 +mbx_sm4_ccm_encrypt_mb16(int8u *pa_out[SM4_LINES], const int8u *const pa_in[SM4_LINES], const int in_len[SM4_LINES], SM4_CCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + int64u *processed_len = SM4_CCM_CONTEXT_PROCESSED_LEN(p_context); + int64u *msg_len = SM4_CCM_CONTEXT_MSG_LEN(p_context); + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_in || NULL == in_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_ccm_update_aad != SM4_CCM_CONTEXT_STATE(p_context) && + sm4_ccm_start_encdec != SM4_CCM_CONTEXT_STATE(p_context) && + sm4_ccm_enc != SM4_CCM_CONTEXT_STATE(p_context)) { + + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with NULL pointers or invalid lengths */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_in[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + + if (in_len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + + processed_len[buf_no] += in_len[buf_no]; + /* Check if total processed length will exceed the total message length passed at init */ + if (processed_len[buf_no] > msg_len[buf_no]) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_ccm_encrypt_mb16(pa_out, pa_in, in_len, mb_mask, p_context); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_get_tag_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_get_tag_mb16_api.c new file mode 100644 index 000000000..24a9b9515 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_get_tag_mb16_api.c @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_ccm_get_tag_mb16(int8u *pa_tag[SM4_LINES], const int tag_len[SM4_LINES], SM4_CCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + int64u *processed_len = SM4_CCM_CONTEXT_PROCESSED_LEN(p_context); + int64u *msg_len = SM4_CCM_CONTEXT_MSG_LEN(p_context); + + /* Test input pointers */ + if (NULL == pa_tag || NULL == tag_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_ccm_update_aad != SM4_CCM_CONTEXT_STATE(p_context) && sm4_ccm_start_encdec != SM4_CCM_CONTEXT_STATE(p_context) && + sm4_ccm_enc != SM4_CCM_CONTEXT_STATE(p_context) && sm4_ccm_dec != SM4_CCM_CONTEXT_STATE(p_context) && + sm4_ccm_get_tag != SM4_CCM_CONTEXT_STATE(p_context)) { + + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero and set bad status for tags of invalid length */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_tag[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } else { + if (tag_len[buf_no] < 4 || tag_len[buf_no] > 16 || tag_len[buf_no] & 0x1) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } else { + /* Check if total processed length is not equal to total message length passed at init */ + if (processed_len[buf_no] != msg_len[buf_no]) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + } + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + sm4_ccm_get_tag_mb16(pa_tag, tag_len, mb_mask, p_context); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_init_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_init_mb16_api.c new file mode 100644 index 000000000..9da922551 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_init_mb16_api.c @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_ccm_init_mb16(const sm4_key *const pa_key[SM4_LINES], + const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + const int tag_len[SM4_LINES], + const int64u msg_len[SM4_LINES], + SM4_CCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_key || NULL == pa_iv || NULL == iv_len || + NULL == tag_len || NULL == msg_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero and set bad status for IV with zero length */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_key[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + if (pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + if ((iv_len[buf_no] < MIN_CCM_IV_LENGTH || iv_len[buf_no] > MAX_CCM_IV_LENGTH)) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + if ((tag_len[buf_no] < MIN_CCM_TAG_LENGTH) || (tag_len[buf_no] > MAX_CCM_TAG_LENGTH) || + (tag_len[buf_no] & 0x1)) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + + /* Check maximum message length allowed, given the number of bytes to encode message length */ + int q = 15 - iv_len[buf_no]; + int64u max_len = (q == 8) ? 0xFFFFFFFFFFFFFFFF : ((1ULL << (q << 3)) - 1); /* (2^(q * 8) - 1 */ + + if (msg_len[buf_no] > max_len) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + + /* + // Compute SM4 keys + // initialize int32u mbx_sm4_key_schedule[SM4_ROUNDS][SM4_LINES] buffer in context + // keys layout for each round: + // key0 key4 key8 key12 key1 key5 key9 key13 key2 key6 key10 key14 key3 key7 key11 key15 + */ + + sm4_set_round_keys_mb16((int32u **)SM4_CCM_CONTEXT_KEY(p_context), (const int8u **)pa_key, mb_mask); + + /* Process IV */ + sm4_ccm_update_iv_mb16(pa_iv, iv_len, mb_mask, p_context); + + /* Zero initial msg and tag lengths */ + PadBlock(0, SM4_CCM_CONTEXT_MSG_LEN(p_context), sizeof(int64u)*SM4_LINES); + PadBlock(0, SM4_CCM_CONTEXT_PROCESSED_LEN(p_context), sizeof(int64u)*SM4_LINES); + PadBlock(0, SM4_CCM_CONTEXT_TAG_LEN(p_context), sizeof(int)*SM4_LINES); + + /* Process msg and tag lengths */ + sm4_ccm_set_msg_len_mb16(msg_len, mb_mask, p_context); + + sm4_ccm_set_tag_len_mb16(tag_len, mb_mask, p_context); + + /* Zero initial hash values */ + PadBlock(0, SM4_CCM_CONTEXT_HASH(p_context), 16*SM4_LINES); + + SM4_CCM_CONTEXT_STATE(p_context) = sm4_ccm_update_aad; + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_update_aad_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_update_aad_mb16_api.c new file mode 100644 index 000000000..05e60b57e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/ccm/sm4_ccm_update_aad_mb16_api.c @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_ccm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], const int aad_len[SM4_LINES], SM4_CCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_aad || NULL == aad_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_ccm_update_aad != SM4_CCM_CONTEXT_STATE(p_context)) { + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_aad[buf_no] == NULL) { + if (aad_len[buf_no] != 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + continue; + } + } + if (aad_len[buf_no] < 0 || aad_len[buf_no] > MAX_CCM_AAD_LENGTH) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_ccm_update_aad_mb16(pa_aad, aad_len, mb_mask, p_context); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_decrypt_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_decrypt_mb16.c new file mode 100644 index 000000000..8ab502e28 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_decrypt_mb16.c @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +/* +// This function performs decryption of given data and updates ghash with given data. +// Function returns mask where bit is set to 1 if length of given data for buffer is overflowed. +*/ + +__mmask16 sm4_gcm_decrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context) +{ + if (SM4_GCM_CONTEXT_STATE(p_context) == sm4_gcm_update_iv) { + /* Finalize IVs */ + sm4_gcm_finalize_iv_mb16(NULL, mb_mask, p_context); + } + + /* Switch context state to decryption */ + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_dec; + + const int8u *loc_pa_in[SM4_LINES]; + int in_len_rearranged[SM4_LINES]; + + /* Rearrange input pointers and lengths to required layout */ + rearrange(loc_pa_in, pa_in); + rearrange(in_len_rearranged, in_len); + __m512i loc_in_len = loadu(in_len_rearranged); + + __mmask16 overflow_mask = 0x0000; + __m512i max_txt_len = set1_epi64(0xFFFFFFFE0); /* (2^39 - 256) div 8 */ + + /* + // Update txt length + // + // TXT length is passed as 32 bit integer + // TXT length is used to construct last block for ghash computation as follow: + // 64 bits with AAD length | 64 bits with TXT length + // Length of AAD and TXT is stored in context in this form + // + // Code below transforms 32 bit input integers into the following block: + // 64 bits with TXT length | 64 zero bits + // and add it to length stored in context + // + // The whole operation is the following for each buffer: + // 64 bits with AAD len in context | 64 bits with TXT len in context + // + + // 64 zero bits | 32 zero bits | 32 bits with input TXT len + */ + + for (int i = 0; i < 4; i++) { + __m512i len_updade = maskz_expandloadu_epi32(0x1111, (void *)(in_len_rearranged + i * 4)); /* Load txt len to high part of registry */ + __m512i len_context = loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), i)); + + len_context = add_epi64(len_context, len_updade); + + storeu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), i), len_context); + + __mmask8 overflow_mask_part = cmp_epi64_mask(max_txt_len, len_context, _MM_CMPINT_LE); + + overflow_mask_part = + (overflow_mask_part & 0x01) | (overflow_mask_part & 0x04) >> 1 | (overflow_mask_part & 0x10) >> 2 | (overflow_mask_part & 0x40) >> 3; + overflow_mask = overflow_mask | overflow_mask_part << (i * 4); + } + + /* Update intermediate ghash value with full blocks of given data */ + sm4_gcm_update_ghash_full_blocks_mb16(SM4_GCM_CONTEXT_GHASH(p_context), loc_pa_in, &loc_in_len, SM4_GCM_CONTEXT_HASHKEY(p_context), mb_mask); + + if (cmp_epi32_mask(loc_in_len, setzero(), _MM_CMPINT_EQ) != 0xFFFF) { + /* Update intermediate ghash value with partial blocks of given data */ + sm4_gcm_update_ghash_partial_blocks_mb16( + SM4_GCM_CONTEXT_GHASH(p_context), loc_pa_in, &loc_in_len, SM4_GCM_CONTEXT_HASHKEY(p_context)[0], mb_mask); + /* Switch context state to tag computation to prevent decryption after any partial blocks are processed */ + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_get_tag; + } + + const mbx_sm4_key_schedule *key_sched = (const mbx_sm4_key_schedule *)SM4_GCM_CONTEXT_KEY(p_context); + + /* Decrypt */ + sm4_gctr_kernel_mb16(pa_out, pa_in, in_len, (const int32u **)key_sched, mb_mask, p_context); + + return overflow_mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_encrypt_j0_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_encrypt_j0_mb16.c new file mode 100644 index 000000000..2f1c87865 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_encrypt_j0_mb16.c @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + +/* +// This function encrypts J0 to use it for tag computation +// Encrypted J0 value XOR'ed with accumulated GHASH value in function sm4_gcm_get_tag_mb16 +*/ + +void sm4_encrypt_j0_mb16(SM4_GCM_CTX_mb16 *p_context) +{ + const mbx_sm4_key_schedule *key_sched = (const mbx_sm4_key_schedule *)SM4_GCM_CONTEXT_KEY(context); + + __m512i j0_blocks[4]; + __m128i *j0 = SM4_GCM_CONTEXT_J0(p_context); + int tagRearrange[] = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 }; + + const int8u *pa_inp[SM4_LINES]; + + for (int i = 0; i < SM4_LINES; i++) { + pa_inp[i] = (unsigned char *)(j0 + tagRearrange[i]); + } + + TRANSPOSE_16x4_I32_EPI32(&j0_blocks[0], &j0_blocks[1], &j0_blocks[2], &j0_blocks[3], pa_inp, 0xFFFF); + + const __m512i *p_rk = (const __m512i *)key_sched; + + __m512i tmp; + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) { + SM4_FOUR_ROUNDS(j0_blocks[0], j0_blocks[1], j0_blocks[2], j0_blocks[3], tmp, p_rk, 1); + } + + tmp = j0_blocks[0]; + j0_blocks[0] = j0_blocks[3]; + j0_blocks[3] = tmp; + tmp = j0_blocks[1]; + j0_blocks[1] = j0_blocks[2]; + j0_blocks[2] = tmp; + + __m512i T1_0 = unpacklo_epi32(j0_blocks[0], j0_blocks[1]); + __m512i T1_1 = unpackhi_epi32(j0_blocks[0], j0_blocks[1]); + __m512i T1_2 = unpacklo_epi32(j0_blocks[2], j0_blocks[3]); + __m512i T1_3 = unpackhi_epi32(j0_blocks[2], j0_blocks[3]); + + j0_blocks[0] = unpacklo_epi64(T1_0, T1_2); + j0_blocks[1] = unpackhi_epi64(T1_0, T1_2); + j0_blocks[2] = unpacklo_epi64(T1_1, T1_3); + j0_blocks[3] = unpackhi_epi64(T1_1, T1_3); + + j0_blocks[0] = shuffle_epi8(j0_blocks[0], M512(swapBytes)); + j0_blocks[1] = shuffle_epi8(j0_blocks[1], M512(swapBytes)); + j0_blocks[2] = shuffle_epi8(j0_blocks[2], M512(swapBytes)); + j0_blocks[3] = shuffle_epi8(j0_blocks[3], M512(swapBytes)); + + storeu(j0 + 0, j0_blocks[0]); + storeu(j0 + 4, j0_blocks[1]); + storeu(j0 + 8, j0_blocks[2]); + storeu(j0 + 12, j0_blocks[3]); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_encrypt_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_encrypt_mb16.c new file mode 100644 index 000000000..428832396 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_encrypt_mb16.c @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +/* +// This function performs encryption of given data and updates ghash with encrypted data. +// Function returns mask where bit is set to 1 if length of given data for buffer is overflowed. +*/ + +__mmask16 sm4_gcm_encrypt_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_in[SM4_LINES], + const int in_len[SM4_LINES], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context) +{ + if (SM4_GCM_CONTEXT_STATE(p_context) == sm4_gcm_update_iv) { + /* Finalize IVs */ + sm4_gcm_finalize_iv_mb16(NULL, mb_mask, p_context); + } + + /* Switch context state to encryption */ + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_enc; + + const mbx_sm4_key_schedule *key_sched = (const mbx_sm4_key_schedule *)SM4_GCM_CONTEXT_KEY(p_context); + + /* Encrypt */ + sm4_gctr_kernel_mb16(pa_out, pa_in, in_len, (const int32u **)key_sched, mb_mask, p_context); + + int8u *loc_pa_out[SM4_LINES]; + int in_len_rearranged[SM4_LINES]; + + /* Rearrange input pointers and lengths to required layout */ + rearrange(loc_pa_out, pa_out); + rearrange(in_len_rearranged, in_len); + __m512i loc_in_len = loadu(in_len_rearranged); + + __mmask16 overflow_mask = 0x0000; + __m512i max_txt_len = set1_epi64(0xFFFFFFFE0); /* (2^39 - 256) div 8 */ + + /* + // Update txt length + // + // TXT length is passed as 32 bit integer + // TXT length is used to construct last block for ghash computation as follow: + // 64 bits with AAD length | 64 bits with TXT length + // Length of AAD and TXT is stored in context in this form + // + // Code below transforms 32 bit input integers into the following block: + // 64 bits with TXT length | 64 zero bits + // and add it to length stored in context + // + // The whole operation is the following for each buffer: + // 64 bits with AAD len in context | 64 bits with TXT len in context + // + + // 64 zero bits | 32 zero bits | 32 bits with input TXT len + */ + + for (int i = 0; i < 4; i++) { + __m512i len_updade = maskz_expandloadu_epi32(0x1111, (void *)(in_len_rearranged + i * 4)); /* Load txt len to high part of _m512iistry */ + __m512i len_context = loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), i)); + + len_context = add_epi64(len_context, len_updade); + + storeu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), i), len_context); + + __mmask8 overflow_mask_part = cmp_epi64_mask(max_txt_len, len_context, _MM_CMPINT_LE); + + overflow_mask_part = + (overflow_mask_part & 0x01) | (overflow_mask_part & 0x04) >> 1 | (overflow_mask_part & 0x10) >> 2 | (overflow_mask_part & 0x40) >> 3; + overflow_mask = overflow_mask | overflow_mask_part << (i * 4); + } + + /* Update intermediate ghash value with full blocks of encrypted data */ + sm4_gcm_update_ghash_full_blocks_mb16( + SM4_GCM_CONTEXT_GHASH(p_context), (const int8u **)loc_pa_out, &loc_in_len, SM4_GCM_CONTEXT_HASHKEY(p_context), mb_mask); + + if (cmp_epi32_mask(loc_in_len, setzero(), _MM_CMPINT_EQ) != 0xFFFF) { + /* Update intermediate ghash value with partial blocks of encrypted data */ + sm4_gcm_update_ghash_partial_blocks_mb16( + SM4_GCM_CONTEXT_GHASH(p_context), (const int8u **)loc_pa_out, &loc_in_len, SM4_GCM_CONTEXT_HASHKEY(p_context)[0], mb_mask); + /* Switch context state to tag computation to prevent decryption after any partial blocks are processed */ + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_get_tag; + } + + return overflow_mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_finalize_iv_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_finalize_iv_mb16.c new file mode 100644 index 000000000..f76df8902 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_finalize_iv_mb16.c @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +/* +// This function performs IV finalization (computes J0) in the follow way: +// If bitlen(IV) == 96, then let J0 = IV || 0^31 ||1. +// If bitlen(IV) != 96, then let s = 128 * [bitlen(IV) / 128] - bitlen(IV), and let J0 = GHASH(IV || 0^(s+64) || bitlen(IV)). +// +// 0^s means the bit string that consists of s '0' bits here +// [x] means the least integer that is not less than the real number x here +// +// This function also encrypts J0 by calling sm4_encrypt_j0_mb16(), to use it later for tag computation +*/ + +void sm4_gcm_finalize_iv_mb16(const int8u *const pa_iv[SM4_LINES], __mmask16 mb_mask, SM4_GCM_CTX_mb16 *p_context) +{ + __m128i *ctr = SM4_GCM_CONTEXT_CTR(p_context); + __m128i *j0 = SM4_GCM_CONTEXT_J0(p_context); + __m128i *hashkey = SM4_GCM_CONTEXT_HASHKEY(p_context)[0]; + + int64u *iv_len = SM4_GCM_CONTEXT_LEN(p_context); + + __m512i hashkeys_4_0, hashkeys_4_1, hashkeys_4_2, hashkeys_4_3; + __m512i *hashkeys[] = { &hashkeys_4_0, &hashkeys_4_1, &hashkeys_4_2, &hashkeys_4_3 }; + + __m512i iv_blocks_4_0, iv_blocks_4_1, iv_blocks_4_2, iv_blocks_4_3; + __m512i *data_blocks[] = { &iv_blocks_4_0, &iv_blocks_4_1, &iv_blocks_4_2, &iv_blocks_4_3 }; + + __m512i len_hi = loadu(iv_len); + __m512i len_lo = loadu(iv_len + 8); + + __mmask8 eq_12_mask_hi = cmp_epi64_mask(len_hi, set1_epi64(12), _MM_CMPINT_EQ); + __mmask8 eq_12_mask_lo = cmp_epi64_mask(len_lo, set1_epi64(12), _MM_CMPINT_EQ); + + __mmask8 eq_0_mask_hi = cmp_epi64_mask(len_hi, setzero(), _MM_CMPINT_EQ); + __mmask8 eq_0_mask_lo = cmp_epi64_mask(len_lo, setzero(), _MM_CMPINT_EQ); + + __mmask16 eq_12_mask = eq_12_mask_lo << 8 | eq_12_mask_hi; + __mmask16 eq_0_mask = eq_0_mask_lo << 8 | eq_0_mask_hi; + + __mmask16 load_mask = ~eq_12_mask | ~eq_0_mask; + + /* Finalize IVs of length != 96 bit */ + if (load_mask) { + + hashkeys_4_0 = loadu(hashkey + 0); + hashkeys_4_1 = loadu(hashkey + 4); + hashkeys_4_2 = loadu(hashkey + 8); + hashkeys_4_3 = loadu(hashkey + 12); + + iv_blocks_4_0 = setzero(); + iv_blocks_4_1 = setzero(); + iv_blocks_4_2 = setzero(); + iv_blocks_4_3 = setzero(); + + /* + // Loop with 4 iterations here does not unrolled by some compilers + // Unrolled explicitly because insert32x4 require the last parameter to be const + */ + + /* Begin of explicitly unrolled loop */ + __m128i input_block_0 = _mm_maskz_set1_epi64(1, *(iv_len + (0 + 4 * 0)) << 3); + __m128i input_block_1 = _mm_maskz_set1_epi64(1, *(iv_len + (0 + 4 * 1)) << 3); + __m128i input_block_2 = _mm_maskz_set1_epi64(1, *(iv_len + (0 + 4 * 2)) << 3); + __m128i input_block_3 = _mm_maskz_set1_epi64(1, *(iv_len + (0 + 4 * 3)) << 3); + + iv_blocks_4_0 = insert32x4(iv_blocks_4_0, input_block_0, 0); + iv_blocks_4_1 = insert32x4(iv_blocks_4_1, input_block_1, 0); + iv_blocks_4_2 = insert32x4(iv_blocks_4_2, input_block_2, 0); + iv_blocks_4_3 = insert32x4(iv_blocks_4_3, input_block_3, 0); + + input_block_0 = _mm_maskz_set1_epi64(1, *(iv_len + (1 + 4 * 0)) << 3); + input_block_1 = _mm_maskz_set1_epi64(1, *(iv_len + (1 + 4 * 1)) << 3); + input_block_2 = _mm_maskz_set1_epi64(1, *(iv_len + (1 + 4 * 2)) << 3); + input_block_3 = _mm_maskz_set1_epi64(1, *(iv_len + (1 + 4 * 3)) << 3); + + iv_blocks_4_0 = insert32x4(iv_blocks_4_0, input_block_0, 1); + iv_blocks_4_1 = insert32x4(iv_blocks_4_1, input_block_1, 1); + iv_blocks_4_2 = insert32x4(iv_blocks_4_2, input_block_2, 1); + iv_blocks_4_3 = insert32x4(iv_blocks_4_3, input_block_3, 1); + + input_block_0 = _mm_maskz_set1_epi64(1, *(iv_len + (2 + 4 * 0)) << 3); + input_block_1 = _mm_maskz_set1_epi64(1, *(iv_len + (2 + 4 * 1)) << 3); + input_block_2 = _mm_maskz_set1_epi64(1, *(iv_len + (2 + 4 * 2)) << 3); + input_block_3 = _mm_maskz_set1_epi64(1, *(iv_len + (2 + 4 * 3)) << 3); + + iv_blocks_4_0 = insert32x4(iv_blocks_4_0, input_block_0, 2); + iv_blocks_4_1 = insert32x4(iv_blocks_4_1, input_block_1, 2); + iv_blocks_4_2 = insert32x4(iv_blocks_4_2, input_block_2, 2); + iv_blocks_4_3 = insert32x4(iv_blocks_4_3, input_block_3, 2); + + input_block_0 = _mm_maskz_set1_epi64(1, *(iv_len + (3 + 4 * 0)) << 3); + input_block_1 = _mm_maskz_set1_epi64(1, *(iv_len + (3 + 4 * 1)) << 3); + input_block_2 = _mm_maskz_set1_epi64(1, *(iv_len + (3 + 4 * 2)) << 3); + input_block_3 = _mm_maskz_set1_epi64(1, *(iv_len + (3 + 4 * 3)) << 3); + + iv_blocks_4_0 = insert32x4(iv_blocks_4_0, input_block_0, 3); + iv_blocks_4_1 = insert32x4(iv_blocks_4_1, input_block_1, 3); + iv_blocks_4_2 = insert32x4(iv_blocks_4_2, input_block_2, 3); + iv_blocks_4_3 = insert32x4(iv_blocks_4_3, input_block_3, 3); + + /* End of explicitly unrolled loop */ + + iv_blocks_4_0 = xor(iv_blocks_4_0, M512(j0 + 0)); + iv_blocks_4_1 = xor(iv_blocks_4_1, M512(j0 + 4)); + iv_blocks_4_2 = xor(iv_blocks_4_2, M512(j0 + 8)); + iv_blocks_4_3 = xor(iv_blocks_4_3, M512(j0 + 12)); + + sm4_gcm_ghash_mul_single_block_mb16(data_blocks, hashkeys); + + iv_blocks_4_0 = shuffle_epi8(iv_blocks_4_0, M512(swapEndianness)); + iv_blocks_4_1 = shuffle_epi8(iv_blocks_4_1, M512(swapEndianness)); + iv_blocks_4_2 = shuffle_epi8(iv_blocks_4_2, M512(swapEndianness)); + iv_blocks_4_3 = shuffle_epi8(iv_blocks_4_3, M512(swapEndianness)); + + __mmask8 store_mask_0 = 0x03 * (0x1 & ((load_mask >> 0 * 4) >> 0)) | 0x0C * (0x1 & ((load_mask >> 0 * 4) >> 1)) | + 0x30 * (0x1 & ((load_mask >> 0 * 4) >> 2)) | 0xC0 * (0x1 & ((load_mask >> 0 * 4) >> 3)); + + __mmask8 store_mask_1 = 0x03 * (0x1 & ((load_mask >> 1 * 4) >> 0)) | 0x0C * (0x1 & ((load_mask >> 1 * 4) >> 1)) | + 0x30 * (0x1 & ((load_mask >> 1 * 4) >> 2)) | 0xC0 * (0x1 & ((load_mask >> 1 * 4) >> 3)); + + __mmask8 store_mask_2 = 0x03 * (0x1 & ((load_mask >> 2 * 4) >> 0)) | 0x0C * (0x1 & ((load_mask >> 2 * 4) >> 1)) | + 0x30 * (0x1 & ((load_mask >> 2 * 4) >> 2)) | 0xC0 * (0x1 & ((load_mask >> 2 * 4) >> 3)); + + __mmask8 store_mask_3 = 0x03 * (0x1 & ((load_mask >> 3 * 4) >> 0)) | 0x0C * (0x1 & ((load_mask >> 3 * 4) >> 1)) | + 0x30 * (0x1 & ((load_mask >> 3 * 4) >> 2)) | 0xC0 * (0x1 & ((load_mask >> 3 * 4) >> 3)); + + mask_storeu_epi64(j0 + 0, store_mask_0, iv_blocks_4_0); + mask_storeu_epi64(j0 + 4, store_mask_1, iv_blocks_4_1); + mask_storeu_epi64(j0 + 8, store_mask_2, iv_blocks_4_2); + mask_storeu_epi64(j0 + 12, store_mask_3, iv_blocks_4_3); + } + + /* Finalize IVs of length == 96 bit */ + if (eq_12_mask != 0 && pa_iv != NULL) { + __m128i iv_block; + + for (int i = 0; i < SM4_LINES; i++) { + iv_block = _mm_mask_loadu_epi8(M128(one_f), 0x0FFF * (0x1 & eq_12_mask), (void *)pa_iv[i]); + _mm_mask_storeu_epi8(j0 + i, 0xFFFF * (0x1 & eq_12_mask), iv_block); + eq_12_mask >>= 1; + } + } + + /* Store initial counter */ + storeu(ctr + 0, inc_block32(shuffle_epi8(loadu(j0 + 0), M512(swapEndianness)), initialInc)); + storeu(ctr + 4, inc_block32(shuffle_epi8(loadu(j0 + 4), M512(swapEndianness)), initialInc)); + storeu(ctr + 8, inc_block32(shuffle_epi8(loadu(j0 + 8), M512(swapEndianness)), initialInc)); + storeu(ctr + 12, inc_block32(shuffle_epi8(loadu(j0 + 12), M512(swapEndianness)), initialInc)); + + sm4_encrypt_j0_mb16(p_context); + + /* Clear length buffer to reuse it for TXT and AAD length */ + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 0)); + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 1)); + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 2)); + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 3)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_gctr_kernel_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_gctr_kernel_mb16.c new file mode 100644 index 000000000..5ac0765b9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_gctr_kernel_mb16.c @@ -0,0 +1,339 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include +#include /* for zero_mb8 */ + +/* +// These functions performs GCTR encryption/decryption +// Implementation is the same with SM4-CTR +*/ + +__INLINE __m128i IncBlock128(__m128i x, int32u increment) { return _mm_add_epi32(x, _mm_maskz_loadu_epi32(1, &increment)); } + +static void sm4_gctr_mask_kernel_mb16(__m512i *CTR, + const __m512i *p_rk, + __m512i loc_len, + const int8u **loc_inp, + int8u **loc_out, + int8u *inc, + __mmask16 tmp_mask, + __mmask16 mb_mask) +{ + __m512i TMP[20]; + while (tmp_mask) { + *CTR = inc_block32(*CTR, inc); + *(CTR + 1) = inc_block32(*(CTR + 1), inc); + *(CTR + 2) = inc_block32(*(CTR + 2), inc); + *(CTR + 3) = inc_block32(*(CTR + 3), inc); + TMP[0] = shuffle_epi8(*CTR, M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(*(CTR + 1), M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(*(CTR + 2), M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(*(CTR + 3), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + *(CTR + 4) = inc_block32(*(CTR + 4), inc); + *(CTR + 5) = inc_block32(*(CTR + 5), inc); + *(CTR + 6) = inc_block32(*(CTR + 6), inc); + *(CTR + 7) = inc_block32(*(CTR + 7), inc); + TMP[0] = shuffle_epi8(*(CTR + 4), M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(*(CTR + 5), M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(*(CTR + 6), M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(*(CTR + 7), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + *(CTR + 8) = inc_block32(*(CTR + 8), inc); + *(CTR + 9) = inc_block32(*(CTR + 9), inc); + *(CTR + 10) = inc_block32(*(CTR + 10), inc); + *(CTR + 11) = inc_block32(*(CTR + 11), inc); + TMP[0] = shuffle_epi8(*(CTR + 8), M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(*(CTR + 9), M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(*(CTR + 10), M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(*(CTR + 11), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + *(CTR + 12) = inc_block32(*(CTR + 12), inc); + *(CTR + 13) = inc_block32(*(CTR + 13), inc); + *(CTR + 14) = inc_block32(*(CTR + 14), inc); + *(CTR + 15) = inc_block32(*(CTR + 15), inc); + TMP[0] = shuffle_epi8(*(CTR + 12), M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(*(CTR + 13), M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(*(CTR + 14), M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(*(CTR + 15), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, 1); + p_rk -= SM4_ROUNDS; + + /* Mask for data loading */ + __mmask64 stream_mask; + int *p_loc_len = (int *)&loc_len; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[0], stream_mask, xor(TMP[0], maskz_loadu_epi8(stream_mask, loc_inp[0]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[1], stream_mask, xor(TMP[1], maskz_loadu_epi8(stream_mask, loc_inp[1]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[2], stream_mask, xor(TMP[2], maskz_loadu_epi8(stream_mask, loc_inp[2]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[3], stream_mask, xor(TMP[3], maskz_loadu_epi8(stream_mask, loc_inp[3]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[4], stream_mask, xor(TMP[0], maskz_loadu_epi8(stream_mask, loc_inp[4]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[5], stream_mask, xor(TMP[1], maskz_loadu_epi8(stream_mask, loc_inp[5]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[6], stream_mask, xor(TMP[2], maskz_loadu_epi8(stream_mask, loc_inp[6]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[7], stream_mask, xor(TMP[3], maskz_loadu_epi8(stream_mask, loc_inp[7]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[8], stream_mask, xor(TMP[0], maskz_loadu_epi8(stream_mask, loc_inp[8]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[9], stream_mask, xor(TMP[1], maskz_loadu_epi8(stream_mask, loc_inp[9]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[10], stream_mask, xor(TMP[2], maskz_loadu_epi8(stream_mask, loc_inp[10]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[11], stream_mask, xor(TMP[3], maskz_loadu_epi8(stream_mask, loc_inp[11]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[12], stream_mask, xor(TMP[0], maskz_loadu_epi8(stream_mask, loc_inp[12]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[13], stream_mask, xor(TMP[1], maskz_loadu_epi8(stream_mask, loc_inp[13]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[14], stream_mask, xor(TMP[2], maskz_loadu_epi8(stream_mask, loc_inp[14]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + mask_storeu_epi8((__m512i *)loc_out[15], stream_mask, xor(TMP[3], maskz_loadu_epi8(stream_mask, loc_inp[15]))); + + /* Update pointers to data */ + M512(loc_inp) = add_epi64(loadu(loc_inp), set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = add_epi64(loadu(loc_inp + 8), set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = add_epi64(loadu(loc_out), set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = add_epi64(loadu(loc_out + 8), set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = sub_epi32(loc_len, set1_epi32(4 * SM4_BLOCK_SIZE)); + tmp_mask = mask_cmp_epi32_mask(mb_mask, loc_len, set1_epi32(0), _MM_CMPINT_NLE); + inc = (int8u *)nextInc; + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); +} + +void sm4_gctr_kernel_mb16(int8u *pa_out[SM4_LINES], + const int8u *const pa_inp[SM4_LINES], + const int len[SM4_LINES], + const int32u *key_sched[SM4_ROUNDS], + __mmask16 mb_mask, + SM4_GCM_CTX_mb16 *p_context) +{ + __mmask16 loc_mb_mask = 0; + + for (int i = 0; i < SM4_LINES; i++) { + __mmask16 tmp = mb_mask & (0x1 << rearrangeOrder[i]); + tmp = tmp >> rearrangeOrder[i]; + loc_mb_mask = loc_mb_mask | tmp << i; + } + + mb_mask = loc_mb_mask; + + const int8u *loc_inp[SM4_LINES]; + int8u *loc_out[SM4_LINES]; + + /* Create the local copy of the input data length in bytes and set it to zero for non-valid buffers */ + __m512i loc_len; + loc_len = loadu(len); + loc_len = mask_set1_epi32(loc_len, ~mb_mask, 0); + + /* input blocks loc_blks[] = ceil(loc_len[]/SM4_BLOCK_SIZE) */ + int32u loc_blks[SM4_LINES]; + storeu(loc_blks, srli_epi32(add_epi32(loc_len, set1_epi32(SM4_BLOCK_SIZE - 1)), 4)); + + /* Local copies of the pointers to input and output buffers */ + storeu((void *)loc_inp, loadu(pa_inp)); + storeu((void *)(loc_inp + 8), loadu(pa_inp + 8)); + + storeu(loc_out, loadu(pa_out)); + storeu(loc_out + 8, loadu(pa_out + 8)); + + /* Pointer p_rk is set to the beginning of the key schedule */ + const __m512i *p_rk = (const __m512i *)key_sched; + + /* TMP[] - temporary buffer for processing */ + /* CTR - store CTR values */ + __m512i TMP[20]; + __m512i CTR[SM4_LINES]; + __m128i loc_ctr[SM4_LINES]; + + /* Load CTR value from valid buffers and rearrange it */ + mb_mask = mask_cmp_epi32_mask(mb_mask, loc_len, setzero(), _MM_CMPINT_NLE); + int ctrRearrange[] = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 }; + for (int i = 0; i < SM4_LINES; i++) { + if (0x1 & (mb_mask >> i)) { + loc_ctr[i] = _mm_loadu_si128(SM4_GCM_CONTEXT_CTR(p_context) + ctrRearrange[i]); + } else { + loc_ctr[i] = _mm_setzero_si128(); + } + + CTR[i] = broadcast_i64x2(loc_ctr[i]); + } + + /* Generate the mask to process 4 blocks from each buffer */ + __mmask16 tmp_mask = mask_cmp_epi32_mask(mb_mask, loc_len, set1_epi32(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + + int8u *inc = (int8u *)firstInc; + + /* Go to this loop if all 16 buffers contain at least 4 blocks each */ + while (tmp_mask == 0xFFFF) { + CTR[0] = inc_block32(CTR[0], inc); + CTR[1] = inc_block32(CTR[1], inc); + CTR[2] = inc_block32(CTR[2], inc); + CTR[3] = inc_block32(CTR[3], inc); + TMP[0] = shuffle_epi8(CTR[0], M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(CTR[1], M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(CTR[2], M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(CTR[3], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + CTR[4] = inc_block32(CTR[4], inc); + CTR[5] = inc_block32(CTR[5], inc); + CTR[6] = inc_block32(CTR[6], inc); + CTR[7] = inc_block32(CTR[7], inc); + TMP[0] = shuffle_epi8(CTR[4], M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(CTR[5], M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(CTR[6], M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(CTR[7], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + CTR[8] = inc_block32(CTR[8], inc); + CTR[9] = inc_block32(CTR[9], inc); + CTR[10] = inc_block32(CTR[10], inc); + CTR[11] = inc_block32(CTR[11], inc); + TMP[0] = shuffle_epi8(CTR[8], M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(CTR[9], M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(CTR[10], M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(CTR[11], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + CTR[12] = inc_block32(CTR[12], inc); + CTR[13] = inc_block32(CTR[13], inc); + CTR[14] = inc_block32(CTR[14], inc); + CTR[15] = inc_block32(CTR[15], inc); + TMP[0] = shuffle_epi8(CTR[12], M512(swapWordsOrder)); + TMP[1] = shuffle_epi8(CTR[13], M512(swapWordsOrder)); + TMP[2] = shuffle_epi8(CTR[14], M512(swapWordsOrder)); + TMP[3] = shuffle_epi8(CTR[15], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, 1); + p_rk -= SM4_ROUNDS; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + storeu((__m512i *)loc_out[0], xor(TMP[0], loadu(loc_inp[0]))); + storeu((__m512i *)loc_out[1], xor(TMP[1], loadu(loc_inp[1]))); + storeu((__m512i *)loc_out[2], xor(TMP[2], loadu(loc_inp[2]))); + storeu((__m512i *)loc_out[3], xor(TMP[3], loadu(loc_inp[3]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + storeu((__m512i *)loc_out[4], xor(TMP[0], loadu(loc_inp[4]))); + storeu((__m512i *)loc_out[5], xor(TMP[1], loadu(loc_inp[5]))); + storeu((__m512i *)loc_out[6], xor(TMP[2], loadu(loc_inp[6]))); + storeu((__m512i *)loc_out[7], xor(TMP[3], loadu(loc_inp[7]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + storeu((__m512i *)loc_out[8], xor(TMP[0], loadu(loc_inp[8]))); + storeu((__m512i *)loc_out[9], xor(TMP[1], loadu(loc_inp[9]))); + storeu((__m512i *)loc_out[10], xor(TMP[2], loadu(loc_inp[10]))); + storeu((__m512i *)loc_out[11], xor(TMP[3], loadu(loc_inp[11]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = shuffle_epi8(TMP[3], M512(swapBytes)); + storeu((__m512i *)loc_out[12], xor(TMP[0], loadu(loc_inp[12]))); + storeu((__m512i *)loc_out[13], xor(TMP[1], loadu(loc_inp[13]))); + storeu((__m512i *)loc_out[14], xor(TMP[2], loadu(loc_inp[14]))); + storeu((__m512i *)loc_out[15], xor(TMP[3], loadu(loc_inp[15]))); + + /* Update pointers to data */ + M512(loc_inp) = add_epi64(loadu(loc_inp), set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = add_epi64(loadu(loc_inp + 8), set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = add_epi64(loadu(loc_out), set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = add_epi64(loadu(loc_out + 8), set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = sub_epi32(loc_len, set1_epi32(4 * SM4_BLOCK_SIZE)); + tmp_mask = mask_cmp_epi32_mask(mb_mask, loc_len, set1_epi32(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + inc = (int8u *)nextInc; + } + + /* Check if we have any data */ + tmp_mask = mask_cmp_epi32_mask(mb_mask, loc_len, setzero(), _MM_CMPINT_NLE); + if (tmp_mask) { + sm4_gctr_mask_kernel_mb16(CTR, p_rk, loc_len, loc_inp, loc_out, inc, tmp_mask, mb_mask); + } + + /* update and store counters */ + for (int i = 0; i < SM4_LINES; i++) { + if (0x1 & (mb_mask >> i)) { + loc_ctr[i] = IncBlock128(loc_ctr[i], loc_blks[i]); + _mm_storeu_si128(SM4_GCM_CONTEXT_CTR(p_context) + ctrRearrange[i], loc_ctr[i]); + loc_ctr[i] = _mm_setzero_si128(); + } + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); + zero_mb8((int64u(*)[8])CTR, sizeof(CTR) / sizeof(CTR[0])); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_get_tag_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_get_tag_mb16.c new file mode 100644 index 000000000..2c3cbf156 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_get_tag_mb16.c @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include +#include /* for zero_mb8 */ + +/* +// This function performs tag computation as follow: +// v = 128 * [bitlen(AAD) / 128] - bitlen(AAD) +// u = 128 * [bitlen(TXT) / 128] - bitlen(TXT) +// S = GHASH (AAD || 0^v || ciphTXT || 0^u || bitlen(AAD) || bitlen(ciphTXT)). +// tag = S xor J0 +// +// J0 is previously encrypted +// +// 0^s means the bit string that consists of s '0' bits here +// [x] means the least integer that is not less than the real number x here +*/ + +void sm4_gcm_get_tag_mb16(int8u *pa_out[SM4_LINES], const int tag_len[SM4_LINES], __mmask16 mb_mask, SM4_GCM_CTX_mb16 *p_context) +{ + __m512i hashkeys_4_0, hashkeys_4_1, hashkeys_4_2, hashkeys_4_3; + __m512i *hashkeys[] = { &hashkeys_4_0, &hashkeys_4_1, &hashkeys_4_2, &hashkeys_4_3 }; + + __m512i data_len_blocks_4_0, data_len_blocks_4_1, data_len_blocks_4_2, data_len_blocks_4_3; + __m512i *data_blocks[] = { &data_len_blocks_4_0, &data_len_blocks_4_1, &data_len_blocks_4_2, &data_len_blocks_4_3 }; + + __m128i *hashkey = SM4_GCM_CONTEXT_HASHKEY(p_context)[0]; + hashkeys_4_0 = loadu(hashkey + 0); + hashkeys_4_1 = loadu(hashkey + 4); + hashkeys_4_2 = loadu(hashkey + 8); + hashkeys_4_3 = loadu(hashkey + 12); + + /* Convert length in bytes to length in bits */ + data_len_blocks_4_0 = sll_epi32(loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 0)), M128(bytes_to_bits_shift)); + data_len_blocks_4_1 = sll_epi32(loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 1)), M128(bytes_to_bits_shift)); + data_len_blocks_4_2 = sll_epi32(loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 2)), M128(bytes_to_bits_shift)); + data_len_blocks_4_3 = sll_epi32(loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 3)), M128(bytes_to_bits_shift)); + + /* XOR with accumulated GHASH value */ + __m128i *ghash = SM4_GCM_CONTEXT_GHASH(p_context); + + data_len_blocks_4_0 = xor(data_len_blocks_4_0, M512(ghash + 0)); + data_len_blocks_4_1 = xor(data_len_blocks_4_1, M512(ghash + 4)); + data_len_blocks_4_2 = xor(data_len_blocks_4_2, M512(ghash + 8)); + data_len_blocks_4_3 = xor(data_len_blocks_4_3, M512(ghash + 12)); + + /* Update GHASH value */ + sm4_gcm_ghash_mul_single_block_mb16(data_blocks, hashkeys); + + data_len_blocks_4_0 = shuffle_epi8(data_len_blocks_4_0, M512(swapEndianness)); + data_len_blocks_4_1 = shuffle_epi8(data_len_blocks_4_1, M512(swapEndianness)); + data_len_blocks_4_2 = shuffle_epi8(data_len_blocks_4_2, M512(swapEndianness)); + data_len_blocks_4_3 = shuffle_epi8(data_len_blocks_4_3, M512(swapEndianness)); + + __m512i j0_blocks[4]; + + __m128i *j0 = SM4_GCM_CONTEXT_J0(p_context); + + j0_blocks[0] = loadu(j0 + 0); + j0_blocks[1] = loadu(j0 + 4); + j0_blocks[2] = loadu(j0 + 8); + j0_blocks[3] = loadu(j0 + 12); + + __m512i tag_blocks[4]; + + /* XOR with previously encrypted J0 */ + tag_blocks[0] = xor(data_len_blocks_4_0, j0_blocks[0]); + tag_blocks[1] = xor(data_len_blocks_4_1, j0_blocks[1]); + tag_blocks[2] = xor(data_len_blocks_4_2, j0_blocks[2]); + tag_blocks[3] = xor(data_len_blocks_4_3, j0_blocks[3]); + + /* Store result */ + for (int i = 0; i < SM4_LINES; i++) { + __m128i one_block = M128((__m128i *)tag_blocks + i); + + __mmask16 tagMask = ~(0xFFFF << (tag_len[rearrangeOrder[i]])) * ((mb_mask >> i) & 0x1); + _mm_mask_storeu_epi8((void *)(pa_out[rearrangeOrder[i]]), tagMask, one_block); + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])tag_blocks, sizeof(tag_blocks) / sizeof(tag_blocks[0])); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_ghash_mul_single_block_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_ghash_mul_single_block_mb16.c new file mode 100644 index 000000000..35073f3dd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_ghash_mul_single_block_mb16.c @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +/* +// This function performs GHASH multiplication: +// Multiplication operation for the binary Galois (finite) field of 2^128 elements. +// +// Details about this operation can be found in NIST SP 800-38D +// +// This code is a port of GCM part of Intel(R) IPSec AES-GCM code +// Code modified to work with multi-buffer approach +*/ + +void sm4_gcm_ghash_mul_single_block_mb16(__m512i *data_blocks[], __m512i *hashkeys[]) +{ + __m512i T1_0, T2_0, T3_0; + __m512i T1_1, T2_1, T3_1; + __m512i T1_2, T2_2, T3_2; + __m512i T1_3, T2_3, T3_3; + + T1_0 = clmul(*(hashkeys[0]), *(data_blocks[0]), 0x11); // T1 = a1*b1 + T1_1 = clmul(*(hashkeys[1]), *(data_blocks[1]), 0x11); + T1_2 = clmul(*(hashkeys[2]), *(data_blocks[2]), 0x11); + T1_3 = clmul(*(hashkeys[3]), *(data_blocks[3]), 0x11); + + T2_0 = clmul(*(hashkeys[0]), *(data_blocks[0]), 0x00); // T1 = a0*b0 + T2_1 = clmul(*(hashkeys[1]), *(data_blocks[1]), 0x00); + T2_2 = clmul(*(hashkeys[2]), *(data_blocks[2]), 0x00); + T2_3 = clmul(*(hashkeys[3]), *(data_blocks[3]), 0x00); + + T3_0 = clmul(*(hashkeys[0]), *(data_blocks[0]), 0x01); // T3 = a1*b0 + T3_1 = clmul(*(hashkeys[1]), *(data_blocks[1]), 0x01); + T3_2 = clmul(*(hashkeys[2]), *(data_blocks[2]), 0x01); + T3_3 = clmul(*(hashkeys[3]), *(data_blocks[3]), 0x01); + + *(data_blocks[0]) = clmul(*(hashkeys[0]), *(data_blocks[0]), 0x10); // T3 = a0*b1 + *(data_blocks[1]) = clmul(*(hashkeys[1]), *(data_blocks[1]), 0x10); + *(data_blocks[2]) = clmul(*(hashkeys[2]), *(data_blocks[2]), 0x10); + *(data_blocks[3]) = clmul(*(hashkeys[3]), *(data_blocks[3]), 0x10); + + *(data_blocks[0]) = xor(*(data_blocks[0]), T3_0); + *(data_blocks[1]) = xor(*(data_blocks[1]), T3_1); + *(data_blocks[2]) = xor(*(data_blocks[2]), T3_2); + *(data_blocks[3]) = xor(*(data_blocks[3]), T3_3); + + T3_0 = bsrli_epi128(*(data_blocks[0]), 8); + T3_1 = bsrli_epi128(*(data_blocks[1]), 8); + T3_2 = bsrli_epi128(*(data_blocks[2]), 8); + T3_3 = bsrli_epi128(*(data_blocks[3]), 8); + + *(data_blocks[0]) = bslli_epi128(*(data_blocks[0]), 8); + *(data_blocks[1]) = bslli_epi128(*(data_blocks[1]), 8); + *(data_blocks[2]) = bslli_epi128(*(data_blocks[2]), 8); + *(data_blocks[3]) = bslli_epi128(*(data_blocks[3]), 8); + + T1_0 = xor(T1_0, T3_0); + T1_1 = xor(T1_1, T3_1); + T1_2 = xor(T1_2, T3_2); + T1_3 = xor(T1_3, T3_3); + + *(data_blocks[0]) = xor(*(data_blocks[0]), T2_0); + *(data_blocks[1]) = xor(*(data_blocks[1]), T2_1); + *(data_blocks[2]) = xor(*(data_blocks[2]), T2_2); + *(data_blocks[3]) = xor(*(data_blocks[3]), T2_3); + + /* first phase of the reduction */ + + T2_0 = clmul(M512(gcm_poly2), *(data_blocks[0]), 0x01); + T2_1 = clmul(M512(gcm_poly2), *(data_blocks[1]), 0x01); + T2_2 = clmul(M512(gcm_poly2), *(data_blocks[2]), 0x01); + T2_3 = clmul(M512(gcm_poly2), *(data_blocks[3]), 0x01); + + T2_0 = bslli_epi128(T2_0, 8); + T2_1 = bslli_epi128(T2_1, 8); + T2_2 = bslli_epi128(T2_2, 8); + T2_3 = bslli_epi128(T2_3, 8); + + *(data_blocks[0]) = xor(*(data_blocks[0]), T2_0); + *(data_blocks[1]) = xor(*(data_blocks[1]), T2_1); + *(data_blocks[2]) = xor(*(data_blocks[2]), T2_2); + *(data_blocks[3]) = xor(*(data_blocks[3]), T2_3); + + /* second phase of the reduction */ + + T2_0 = clmul(M512(gcm_poly2), *(data_blocks[0]), 0x00); + T2_1 = clmul(M512(gcm_poly2), *(data_blocks[1]), 0x00); + T2_2 = clmul(M512(gcm_poly2), *(data_blocks[2]), 0x00); + T2_3 = clmul(M512(gcm_poly2), *(data_blocks[3]), 0x00); + + T2_0 = bsrli_epi128(T2_0, 4); + T2_1 = bsrli_epi128(T2_1, 4); + T2_2 = bsrli_epi128(T2_2, 4); + T2_3 = bsrli_epi128(T2_3, 4); + + *(data_blocks[0]) = clmul(M512(gcm_poly2), *(data_blocks[0]), 0x10); + *(data_blocks[1]) = clmul(M512(gcm_poly2), *(data_blocks[1]), 0x10); + *(data_blocks[2]) = clmul(M512(gcm_poly2), *(data_blocks[2]), 0x10); + *(data_blocks[3]) = clmul(M512(gcm_poly2), *(data_blocks[3]), 0x10); + + *(data_blocks[0]) = bslli_epi128(*(data_blocks[0]), 4); + *(data_blocks[1]) = bslli_epi128(*(data_blocks[1]), 4); + *(data_blocks[2]) = bslli_epi128(*(data_blocks[2]), 4); + *(data_blocks[3]) = bslli_epi128(*(data_blocks[3]), 4); + + *(data_blocks[0]) = xor(*(data_blocks[0]), T2_0); + *(data_blocks[1]) = xor(*(data_blocks[1]), T2_1); + *(data_blocks[2]) = xor(*(data_blocks[2]), T2_2); + *(data_blocks[3]) = xor(*(data_blocks[3]), T2_3); + + *(data_blocks[0]) = xor(*(data_blocks[0]), T1_0); + *(data_blocks[1]) = xor(*(data_blocks[1]), T1_1); + *(data_blocks[2]) = xor(*(data_blocks[2]), T1_2); + *(data_blocks[3]) = xor(*(data_blocks[3]), T1_3); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_precompute_hashkey_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_precompute_hashkey_mb16.c new file mode 100644 index 000000000..fef770ae1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_precompute_hashkey_mb16.c @@ -0,0 +1,140 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include + + +/* +// This function precomputes haskeys for delayed reduction: +// hashkeys >> 1 mod poly and hashkeys ^ 2 >> 1 mod poly ... hashkeys ^ 7 >> 1 mod poly +// +// This code is a port of GCM part of Intel(R) IPSec AES-GCM code +// Code modified to work with multi-buffer approach +*/ + +void sm4_gcm_precompute_hashkey_mb16(const mbx_sm4_key_schedule *key_sched, SM4_GCM_CTX_mb16 *p_context) +{ + const __m512i *p_rk = (const __m512i *)key_sched; + __m512i tmp; + + /* Encrypt zero blocks */ + __m512i hashkey_blocks_4_0 = setzero(); + __m512i hashkey_blocks_4_1 = setzero(); + __m512i hashkey_blocks_4_2 = setzero(); + __m512i hashkey_blocks_4_3 = setzero(); + + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) { + SM4_FOUR_ROUNDS(hashkey_blocks_4_0, hashkey_blocks_4_1, hashkey_blocks_4_2, hashkey_blocks_4_3, tmp, p_rk, 1); + } + + tmp = hashkey_blocks_4_0; + hashkey_blocks_4_0 = hashkey_blocks_4_3; + hashkey_blocks_4_3 = tmp; + tmp = hashkey_blocks_4_1; + hashkey_blocks_4_1 = hashkey_blocks_4_2; + hashkey_blocks_4_2 = tmp; + + /* Get the right endianness */ + __m512i T1_0 = unpacklo_epi32(hashkey_blocks_4_0, hashkey_blocks_4_1); + __m512i T1_1 = unpackhi_epi32(hashkey_blocks_4_0, hashkey_blocks_4_1); + __m512i T1_2 = unpacklo_epi32(hashkey_blocks_4_2, hashkey_blocks_4_3); + __m512i T1_3 = unpackhi_epi32(hashkey_blocks_4_2, hashkey_blocks_4_3); + + hashkey_blocks_4_0 = unpacklo_epi64(T1_0, T1_2); + hashkey_blocks_4_1 = unpackhi_epi64(T1_0, T1_2); + hashkey_blocks_4_2 = unpacklo_epi64(T1_1, T1_3); + hashkey_blocks_4_3 = unpackhi_epi64(T1_1, T1_3); + + hashkey_blocks_4_0 = shuffle_epi8(hashkey_blocks_4_0, M512(swapWordsOrder)); + hashkey_blocks_4_1 = shuffle_epi8(hashkey_blocks_4_1, M512(swapWordsOrder)); + hashkey_blocks_4_2 = shuffle_epi8(hashkey_blocks_4_2, M512(swapWordsOrder)); + hashkey_blocks_4_3 = shuffle_epi8(hashkey_blocks_4_3, M512(swapWordsOrder)); + + /* compute hashkeys >> 1 mod poly */ + T1_0 = srli_epi64(hashkey_blocks_4_0, 63); + T1_1 = srli_epi64(hashkey_blocks_4_1, 63); + T1_2 = srli_epi64(hashkey_blocks_4_2, 63); + T1_3 = srli_epi64(hashkey_blocks_4_3, 63); + hashkey_blocks_4_0 = slli_epi64(hashkey_blocks_4_0, 1); + hashkey_blocks_4_1 = slli_epi64(hashkey_blocks_4_1, 1); + hashkey_blocks_4_2 = slli_epi64(hashkey_blocks_4_2, 1); + hashkey_blocks_4_3 = slli_epi64(hashkey_blocks_4_3, 1); + + __m512i T2_0 = bsrli_epi128(T1_0, 8); + __m512i T2_1 = bsrli_epi128(T1_1, 8); + __m512i T2_2 = bsrli_epi128(T1_2, 8); + __m512i T2_3 = bsrli_epi128(T1_3, 8); + T1_0 = bslli_epi128(T1_0, 8); + T1_1 = bslli_epi128(T1_1, 8); + T1_2 = bslli_epi128(T1_2, 8); + T1_3 = bslli_epi128(T1_3, 8); + + hashkey_blocks_4_0 = or (hashkey_blocks_4_0, T1_0); + hashkey_blocks_4_1 = or (hashkey_blocks_4_1, T1_1); + hashkey_blocks_4_2 = or (hashkey_blocks_4_2, T1_2); + hashkey_blocks_4_3 = or (hashkey_blocks_4_3, T1_3); + + T1_0 = shuffle_epi32(T2_0, 0b00100100); + T1_1 = shuffle_epi32(T2_1, 0b00100100); + T1_2 = shuffle_epi32(T2_2, 0b00100100); + T1_3 = shuffle_epi32(T2_3, 0b00100100); + + __mmask16 cmp_mask_0 = cmpeq_epi32_mask(T1_0, M512(two_one)); + __mmask16 cmp_mask_1 = cmpeq_epi32_mask(T1_1, M512(two_one)); + __mmask16 cmp_mask_2 = cmpeq_epi32_mask(T1_2, M512(two_one)); + __mmask16 cmp_mask_3 = cmpeq_epi32_mask(T1_3, M512(two_one)); + T1_0 = mask_set1_epi32(T1_0, cmp_mask_0, 0xFFFFFFFF); + T1_1 = mask_set1_epi32(T1_1, cmp_mask_1, 0xFFFFFFFF); + T1_2 = mask_set1_epi32(T1_2, cmp_mask_2, 0xFFFFFFFF); + T1_3 = mask_set1_epi32(T1_3, cmp_mask_3, 0xFFFFFFFF); + + T1_0 = and(T1_0, M512(gcm_poly)); + T1_1 = and(T1_1, M512(gcm_poly)); + T1_2 = and(T1_2, M512(gcm_poly)); + T1_3 = and(T1_3, M512(gcm_poly)); + hashkey_blocks_4_0 = xor(hashkey_blocks_4_0, T1_0); + hashkey_blocks_4_1 = xor(hashkey_blocks_4_1, T1_1); + hashkey_blocks_4_2 = xor(hashkey_blocks_4_2, T1_2); + hashkey_blocks_4_3 = xor(hashkey_blocks_4_3, T1_3); + + __m128i *p_hashkey = (__m128i *)SM4_GCM_CONTEXT_HASHKEY(p_context)[0]; + + storeu(p_hashkey + 0, hashkey_blocks_4_0); + storeu(p_hashkey + 4, hashkey_blocks_4_1); + storeu(p_hashkey + 8, hashkey_blocks_4_2); + storeu(p_hashkey + 12, hashkey_blocks_4_3); + + /* compute hashkeys ^ 2 >> 1 mod poly ... hashkeys ^ 7 >> 1 mod poly */ + __m512i hashkey_pwr_blocks_4_0 = hashkey_blocks_4_0; + __m512i hashkey_pwr_blocks_4_1 = hashkey_blocks_4_1; + __m512i hashkey_pwr_blocks_4_2 = hashkey_blocks_4_2; + __m512i hashkey_pwr_blocks_4_3 = hashkey_blocks_4_3; + + __m512i *hashkey[] = { &hashkey_blocks_4_0, &hashkey_blocks_4_1, &hashkey_blocks_4_2, &hashkey_blocks_4_3 }; + __m512i *hashkey_pwr[] = { &hashkey_pwr_blocks_4_0, &hashkey_pwr_blocks_4_1, &hashkey_pwr_blocks_4_2, &hashkey_pwr_blocks_4_3 }; + + for (int i = 1; i < 8; i++) { + sm4_gcm_ghash_mul_single_block_mb16(hashkey_pwr, hashkey); + + p_hashkey = (__m128i *)SM4_GCM_CONTEXT_HASHKEY(p_context)[i]; + + storeu(p_hashkey + 0, hashkey_pwr_blocks_4_0); + storeu(p_hashkey + 4, hashkey_pwr_blocks_4_1); + storeu(p_hashkey + 8, hashkey_pwr_blocks_4_2); + storeu(p_hashkey + 12, hashkey_pwr_blocks_4_3); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_aad_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_aad_mb16.c new file mode 100644 index 000000000..5dbc8c0f1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_aad_mb16.c @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +/* +// This function process 16 buffers with additional authentication data (AAD) +*/ + +__mmask16 sm4_gcm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], const int aad_len[SM4_LINES], __mmask16 mb_mask, SM4_GCM_CTX_mb16 *p_context) +{ + if (SM4_GCM_CONTEXT_STATE(p_context) == sm4_gcm_update_iv) { + /* Finalize IVs */ + sm4_gcm_finalize_iv_mb16(NULL, mb_mask, p_context); + + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_update_aad; + } + + __m128i *ghash = SM4_GCM_CONTEXT_GHASH(p_context); + + const int8u *loc_pa_aad[SM4_LINES]; + int aad_len_rearranged[SM4_LINES]; + + /* Rearrange pointers and lengths to right layout */ + rearrange(loc_pa_aad, pa_aad); + rearrange(aad_len_rearranged, aad_len); + + __m512i loc_aad_len = loadu(aad_len_rearranged); + + __mmask16 overflow_mask = 0x0000; + __m512i max_aad_len = set1_epi64(0x1FFFFFFFFFFFFFFF); /* (2^64 - 1) div 8 */ + + /* + // Update aad len + // + // AAD length is passed as 32 bit integer + // AAD lenght is used to construct last block for ghahs computation as follow: + // 64 bits with AAD length | 64 bits with TXT length + // Length of AAD and TXT is stored in context in this form + // + // Code below transforms 32 bit input integers into the following block: + // 64 bits with AAD length | 64 zero bits + // and add it to length stored in context + // + // The whole operation is the following for each buffer: + // 64 bits with AAD len in context | 64 bits with TXT len in context + // + + // 32 zero bits | 32 bits with input AAD len | 64 zero bits + */ + + for (int i = 0; i < 4; i++) { + __m512i len_updade = maskz_expandloadu_epi32(0x4444, (void *)(aad_len_rearranged + i * 4)); /* Load aad len to low part of _m512iistry */ + __m512i len_context = loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), i)); + + len_context = add_epi64(len_context, len_updade); + storeu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), i), len_context); + + __mmask8 overflow_mask_part = cmp_epi64_mask(max_aad_len, len_context, _MM_CMPINT_LT); + + overflow_mask_part = + (overflow_mask_part & 0x02) >> 1 | (overflow_mask_part & 0x08) >> 2 | (overflow_mask_part & 0x20) >> 3 | (overflow_mask_part & 0x80) >> 4; + overflow_mask = overflow_mask | overflow_mask_part << (i * 4); + } + + /* Process full blocks of AADs */ + sm4_gcm_update_ghash_full_blocks_mb16(ghash, loc_pa_aad, &loc_aad_len, SM4_GCM_CONTEXT_HASHKEY(p_context), mb_mask); + + if (cmp_epi32_mask(loc_aad_len, setzero(), _MM_CMPINT_EQ) != 0xFFFF) { + /* Process partial blocks of AADs */ + sm4_gcm_update_ghash_partial_blocks_mb16(ghash, loc_pa_aad, &loc_aad_len, SM4_GCM_CONTEXT_HASHKEY(p_context)[0], mb_mask); + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_start_encdec; + } + + return overflow_mask; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_ghash_full_blocks_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_ghash_full_blocks_mb16.c new file mode 100644 index 000000000..415c06541 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_ghash_full_blocks_mb16.c @@ -0,0 +1,691 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +__INLINE void read_first(__m512i *data_blocks[4], const int8u *const pa_input[SM4_LINES], __mmask16 load_mask) +{ + __mmask16 load_mask_0 = load_mask >> 0 * 4; + __mmask16 load_mask_1 = load_mask >> 1 * 4; + __mmask16 load_mask_2 = load_mask >> 2 * 4; + __mmask16 load_mask_3 = load_mask >> 3 * 4; + + *(data_blocks[0]) = setzero(); + *(data_blocks[1]) = setzero(); + *(data_blocks[2]) = setzero(); + *(data_blocks[3]) = setzero(); + + /* + // Loop with 4 iterations here does not unrolled by some compilers + // Unrolled explicitly because insert32x4 require the last parameter to be const + */ + + /* Begin of explicitly unrolled loop */ + + __m128i input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)pa_input[0 + 4 * 0]); + __m128i input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)pa_input[0 + 4 * 1]); + __m128i input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)pa_input[0 + 4 * 2]); + __m128i input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)pa_input[0 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 0); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 0); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 0); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 0); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)pa_input[1 + 4 * 0]); + input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)pa_input[1 + 4 * 1]); + input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)pa_input[1 + 4 * 2]); + input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)pa_input[1 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 1); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 1); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 1); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 1); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)pa_input[2 + 4 * 0]); + input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)pa_input[2 + 4 * 1]); + input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)pa_input[2 + 4 * 2]); + input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)pa_input[2 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 2); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 2); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 2); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 2); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)pa_input[3 + 4 * 0]); + input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)pa_input[3 + 4 * 1]); + input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)pa_input[3 + 4 * 2]); + input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)pa_input[3 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 3); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 3); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 3); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 3); + + /* End of explicitly unrolled loop */ +} + +__INLINE void read_next(__m512i *data_blocks[4], const int8u *const pa_input[SM4_LINES], int block_number, __mmask16 load_mask) +{ + __mmask16 load_mask_0 = load_mask >> 0 * 4; + __mmask16 load_mask_1 = load_mask >> 1 * 4; + __mmask16 load_mask_2 = load_mask >> 2 * 4; + __mmask16 load_mask_3 = load_mask >> 3 * 4; + + *(data_blocks[0]) = setzero(); + *(data_blocks[1]) = setzero(); + *(data_blocks[2]) = setzero(); + *(data_blocks[3]) = setzero(); + + /* + // Loop with 4 iterations here does not unrolled by some compilers + // Unrolled explicitly because insert32x4 require the last parameter to be const + */ + + /* Begin of explicitly unrolled loop */ + + __m128i input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)(pa_input[0 + 4 * 0] + block_number * 16)); + __m128i input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)(pa_input[0 + 4 * 1] + block_number * 16)); + __m128i input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)(pa_input[0 + 4 * 2] + block_number * 16)); + __m128i input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)(pa_input[0 + 4 * 3] + block_number * 16)); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 0); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 0); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 0); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 0); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)(pa_input[1 + 4 * 0] + block_number * 16)); + input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)(pa_input[1 + 4 * 1] + block_number * 16)); + input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)(pa_input[1 + 4 * 2] + block_number * 16)); + input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)(pa_input[1 + 4 * 3] + block_number * 16)); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 1); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 1); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 1); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 1); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)(pa_input[2 + 4 * 0] + block_number * 16)); + input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)(pa_input[2 + 4 * 1] + block_number * 16)); + input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)(pa_input[2 + 4 * 2] + block_number * 16)); + input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)(pa_input[2 + 4 * 3] + block_number * 16)); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 2); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 2); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 2); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 2); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_0), (void *)(pa_input[3 + 4 * 0] + block_number * 16)); + input_block_1 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_1), (void *)(pa_input[3 + 4 * 1] + block_number * 16)); + input_block_2 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_2), (void *)(pa_input[3 + 4 * 2] + block_number * 16)); + input_block_3 = _mm_maskz_loadu_epi8(0xFFFF * (0x1 & load_mask_3), (void *)(pa_input[3 + 4 * 3] + block_number * 16)); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 3); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 3); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 3); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 3); + + /* End of explicitly unrolled loop */ +} + +/* +// This function updates 16 blocks of ghash by processing full blocks (128 bit blocks) of data +// +// This code is a port of GCM part of Intel(R) IPSec AES-GCM code +// Code modified to work with multi-buffer approach +*/ +void sm4_gcm_update_ghash_full_blocks_mb16(__m128i ghash[SM4_LINES], + const int8u *const pa_input[SM4_LINES], + __m512i *input_len, + __m128i hashkey[SM4_GCM_HASHKEY_PWR_NUM][SM4_LINES], + __mmask16 mb_mask) +{ + + int stream_len = 0; + __mmask16 load_mask = 0; + + __m512i hashkeys_4_0, hashkeys_4_1, hashkeys_4_2, hashkeys_4_3; + __m512i data_blocks_4_0, data_blocks_4_1, data_blocks_4_2, data_blocks_4_3; + __m512i *data_blocks[] = { &data_blocks_4_0, &data_blocks_4_1, &data_blocks_4_2, &data_blocks_4_3 }; + + __m512i T1_0, T2_0, T3_0, T4_0; + __m512i T1_1, T2_1, T3_1, T4_1; + __m512i T1_2, T2_2, T3_2, T4_2; + __m512i T1_3, T2_3, T3_3, T4_3; + + stream_len = 8; + cmp_epi32_mask((*input_len), set1_epi32(16 * 8), _MM_CMPINT_GE); + + load_mask &= mb_mask; + + while (load_mask) { + + /* Process first block using hashkey of highest power */ + hashkeys_4_0 = loadu(hashkey[stream_len - 1] + 0); + hashkeys_4_1 = loadu(hashkey[stream_len - 1] + 4); + hashkeys_4_2 = loadu(hashkey[stream_len - 1] + 8); + hashkeys_4_3 = loadu(hashkey[stream_len - 1] + 12); + + read_first(data_blocks, pa_input, load_mask); + + data_blocks_4_0 = xor(data_blocks_4_0, M512(ghash + 0)); + data_blocks_4_1 = xor(data_blocks_4_1, M512(ghash + 4)); + data_blocks_4_2 = xor(data_blocks_4_2, M512(ghash + 8)); + data_blocks_4_3 = xor(data_blocks_4_3, M512(ghash + 12)); + + T1_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x11); + T1_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x11); + T1_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x11); + T1_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x11); + + T2_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x00); + T2_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x00); + T2_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x00); + T2_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x00); + + T3_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x01); + T3_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x01); + T3_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x01); + T3_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x01); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x10); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x10); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x10); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x10); + + T3_0 = xor(T4_0, T3_0); + T3_1 = xor(T4_1, T3_1); + T3_2 = xor(T4_2, T3_2); + T3_3 = xor(T4_3, T3_3); + + /* Process the rest of blocks */ + for (int i = 1; i < stream_len; i++) { + + read_next(data_blocks, pa_input, i, load_mask); + + hashkeys_4_0 = loadu(hashkey[stream_len - i - 1] + 0); + hashkeys_4_1 = loadu(hashkey[stream_len - i - 1] + 4); + hashkeys_4_2 = loadu(hashkey[stream_len - i - 1] + 8); + hashkeys_4_3 = loadu(hashkey[stream_len - i - 1] + 12); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x11); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x11); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x11); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x11); + + T1_0 = xor(T4_0, T1_0); + T1_1 = xor(T4_1, T1_1); + T1_2 = xor(T4_2, T1_2); + T1_3 = xor(T4_3, T1_3); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x00); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x00); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x00); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x00); + + T2_0 = xor(T4_0, T2_0); + T2_1 = xor(T4_1, T2_1); + T2_2 = xor(T4_2, T2_2); + T2_3 = xor(T4_3, T2_3); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x01); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x01); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x01); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x01); + + T3_0 = xor(T4_0, T3_0); + T3_1 = xor(T4_1, T3_1); + T3_2 = xor(T4_2, T3_2); + T3_3 = xor(T4_3, T3_3); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x10); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x10); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x10); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x10); + + T3_0 = xor(T4_0, T3_0); + T3_1 = xor(T4_1, T3_1); + T3_2 = xor(T4_2, T3_2); + T3_3 = xor(T4_3, T3_3); + } + + /* Accumulate non-redused result */ + + T4_0 = bslli_epi128(T3_0, 8); + T4_1 = bslli_epi128(T3_1, 8); + T4_2 = bslli_epi128(T3_2, 8); + T4_3 = bslli_epi128(T3_3, 8); + + T3_0 = bsrli_epi128(T3_0, 8); + T3_1 = bsrli_epi128(T3_1, 8); + T3_2 = bsrli_epi128(T3_2, 8); + T3_3 = bsrli_epi128(T3_3, 8); + + T2_0 = xor(T2_0, T4_0); + T2_1 = xor(T2_1, T4_1); + T2_2 = xor(T2_2, T4_2); + T2_3 = xor(T2_3, T4_3); + + T1_0 = xor(T1_0, T3_0); + T1_1 = xor(T1_1, T3_1); + T1_2 = xor(T1_2, T3_2); + T1_3 = xor(T1_3, T3_3); + + /* First phase of the reduction */ + + T3_0 = clmul(M512(gcm_poly2), T2_0, 0x01); + T3_1 = clmul(M512(gcm_poly2), T2_1, 0x01); + T3_2 = clmul(M512(gcm_poly2), T2_2, 0x01); + T3_3 = clmul(M512(gcm_poly2), T2_3, 0x01); + + T3_0 = bslli_epi128(T3_0, 8); + T3_1 = bslli_epi128(T3_1, 8); + T3_2 = bslli_epi128(T3_2, 8); + T3_3 = bslli_epi128(T3_3, 8); + + T2_0 = xor(T3_0, T2_0); + T2_1 = xor(T3_1, T2_1); + T2_2 = xor(T3_2, T2_2); + T2_3 = xor(T3_3, T2_3); + + /* Second phase of the reduction */ + + T3_0 = clmul(M512(gcm_poly2), T2_0, 0x00); + T3_1 = clmul(M512(gcm_poly2), T2_1, 0x00); + T3_2 = clmul(M512(gcm_poly2), T2_2, 0x00); + T3_3 = clmul(M512(gcm_poly2), T2_3, 0x00); + + T3_0 = bsrli_epi128(T3_0, 4); + T3_1 = bsrli_epi128(T3_1, 4); + T3_2 = bsrli_epi128(T3_2, 4); + T3_3 = bsrli_epi128(T3_3, 4); + + T4_0 = clmul(M512(gcm_poly2), T2_0, 0x10); + T4_1 = clmul(M512(gcm_poly2), T2_1, 0x10); + T4_2 = clmul(M512(gcm_poly2), T2_2, 0x10); + T4_3 = clmul(M512(gcm_poly2), T2_3, 0x10); + + T4_0 = bslli_epi128(T4_0, 4); + T4_1 = bslli_epi128(T4_1, 4); + T4_2 = bslli_epi128(T4_2, 4); + T4_3 = bslli_epi128(T4_3, 4); + + T4_0 = xor(T4_0, T3_0); + T4_1 = xor(T4_1, T3_1); + T4_2 = xor(T4_2, T3_2); + T4_3 = xor(T4_3, T3_3); + + T4_0 = xor(T4_0, T1_0); + T4_1 = xor(T4_1, T1_1); + T4_2 = xor(T4_2, T1_2); + T4_3 = xor(T4_3, T1_3); + + /* Reduction complete, store result */ + + __mmask8 store_mask_0 = 0x03 * (0x1 & ((load_mask >> 0 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 0 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 0 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 0 * 4) >> 3)); // + + __mmask8 store_mask_1 = 0x03 * (0x1 & ((load_mask >> 1 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 1 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 1 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 1 * 4) >> 3)); // + + __mmask8 store_mask_2 = 0x03 * (0x1 & ((load_mask >> 2 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 2 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 2 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 2 * 4) >> 3)); // + + __mmask8 store_mask_3 = 0x03 * (0x1 & ((load_mask >> 3 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 3 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 3 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 3 * 4) >> 3)); // + + mask_storeu_epi64(ghash + 0, store_mask_0, T4_0); + mask_storeu_epi64(ghash + 4, store_mask_1, T4_1); + mask_storeu_epi64(ghash + 8, store_mask_2, T4_2); + mask_storeu_epi64(ghash + 12, store_mask_3, T4_3); + + /* Update pointers and lengths */ + + (*input_len) = mask_sub_epi32((*input_len), load_mask, (*input_len), set1_epi32(16 * stream_len)); + + __mmask8 ptr_update_mask_lo = load_mask & 0xFF; + __mmask8 ptr_update_mask_hi = (load_mask >> 8) & 0xFF; + + __m512i loc_pa_input_lo = loadu(pa_input); + __m512i loc_pa_input_hi = loadu(pa_input + 8); + + loc_pa_input_lo = mask_add_epi64(loc_pa_input_lo, ptr_update_mask_lo, loc_pa_input_lo, set1_epi64(16 * stream_len)); + loc_pa_input_hi = mask_add_epi64(loc_pa_input_hi, ptr_update_mask_hi, loc_pa_input_hi, set1_epi64(16 * stream_len)); + + storeu((void *)pa_input, loc_pa_input_lo); + storeu((void *)(pa_input + 8), loc_pa_input_hi); + + load_mask = cmp_epi32_mask((*input_len), set1_epi32(16 * 8), _MM_CMPINT_GE); + + load_mask &= mb_mask; + } + + stream_len = 0; + load_mask = 0; + + /* Calculate how many blocks can be processed with delayed reduction */ + for (int i = 8; i > 0; i--) { + __mmask16 max_stream_len_mask = cmp_epi32_mask((*input_len), set1_epi32(16 * i), _MM_CMPINT_GE); + __mmask16 less_16_mask = cmp_epi32_mask((*input_len), set1_epi32(16), _MM_CMPINT_LT); + __mmask16 stream_mask = max_stream_len_mask | less_16_mask; + + load_mask = load_mask * (load_mask != 0) | max_stream_len_mask * (stream_mask == 0xFFFF) * (load_mask == 0) * (less_16_mask != 0xFFFF); + stream_len = stream_len + i * (stream_mask == 0xFFFF) * (stream_len == 0) * (less_16_mask != 0xFFFF); + } + + load_mask &= mb_mask; + + while (load_mask) { + + /* Process first block using hashkey of highest power */ + + hashkeys_4_0 = loadu(hashkey[stream_len - 1] + 0); + hashkeys_4_1 = loadu(hashkey[stream_len - 1] + 4); + hashkeys_4_2 = loadu(hashkey[stream_len - 1] + 8); + hashkeys_4_3 = loadu(hashkey[stream_len - 1] + 12); + + read_first(data_blocks, pa_input, load_mask); + + data_blocks_4_0 = xor(data_blocks_4_0, M512(ghash + 0)); + data_blocks_4_1 = xor(data_blocks_4_1, M512(ghash + 4)); + data_blocks_4_2 = xor(data_blocks_4_2, M512(ghash + 8)); + data_blocks_4_3 = xor(data_blocks_4_3, M512(ghash + 12)); + + T1_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x11); + T1_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x11); + T1_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x11); + T1_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x11); + + T2_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x00); + T2_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x00); + T2_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x00); + T2_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x00); + + T3_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x01); + T3_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x01); + T3_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x01); + T3_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x01); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x10); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x10); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x10); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x10); + + T3_0 = xor(T4_0, T3_0); + T3_1 = xor(T4_1, T3_1); + T3_2 = xor(T4_2, T3_2); + T3_3 = xor(T4_3, T3_3); + + /* Process the rest of blocks */ + for (int i = 1; i < stream_len; i++) { + + read_next(data_blocks, pa_input, i, load_mask); + + hashkeys_4_0 = loadu(hashkey[stream_len - i - 1] + 0); + hashkeys_4_1 = loadu(hashkey[stream_len - i - 1] + 4); + hashkeys_4_2 = loadu(hashkey[stream_len - i - 1] + 8); + hashkeys_4_3 = loadu(hashkey[stream_len - i - 1] + 12); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x11); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x11); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x11); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x11); + + T1_0 = xor(T4_0, T1_0); + T1_1 = xor(T4_1, T1_1); + T1_2 = xor(T4_2, T1_2); + T1_3 = xor(T4_3, T1_3); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x00); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x00); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x00); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x00); + + T2_0 = xor(T4_0, T2_0); + T2_1 = xor(T4_1, T2_1); + T2_2 = xor(T4_2, T2_2); + T2_3 = xor(T4_3, T2_3); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x01); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x01); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x01); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x01); + + T3_0 = xor(T4_0, T3_0); + T3_1 = xor(T4_1, T3_1); + T3_2 = xor(T4_2, T3_2); + T3_3 = xor(T4_3, T3_3); + + T4_0 = clmul(hashkeys_4_0, data_blocks_4_0, 0x10); + T4_1 = clmul(hashkeys_4_1, data_blocks_4_1, 0x10); + T4_2 = clmul(hashkeys_4_2, data_blocks_4_2, 0x10); + T4_3 = clmul(hashkeys_4_3, data_blocks_4_3, 0x10); + + T3_0 = xor(T4_0, T3_0); + T3_1 = xor(T4_1, T3_1); + T3_2 = xor(T4_2, T3_2); + T3_3 = xor(T4_3, T3_3); + } + + /* Accumulate non-redused result */ + + T4_0 = bslli_epi128(T3_0, 8); + T4_1 = bslli_epi128(T3_1, 8); + T4_2 = bslli_epi128(T3_2, 8); + T4_3 = bslli_epi128(T3_3, 8); + + T3_0 = bsrli_epi128(T3_0, 8); + T3_1 = bsrli_epi128(T3_1, 8); + T3_2 = bsrli_epi128(T3_2, 8); + T3_3 = bsrli_epi128(T3_3, 8); + + T2_0 = xor(T2_0, T4_0); + T2_1 = xor(T2_1, T4_1); + T2_2 = xor(T2_2, T4_2); + T2_3 = xor(T2_3, T4_3); + + T1_0 = xor(T1_0, T3_0); + T1_1 = xor(T1_1, T3_1); + T1_2 = xor(T1_2, T3_2); + T1_3 = xor(T1_3, T3_3); + + /* First phase of the reduction */ + + T3_0 = clmul(M512(gcm_poly2), T2_0, 0x01); + T3_1 = clmul(M512(gcm_poly2), T2_1, 0x01); + T3_2 = clmul(M512(gcm_poly2), T2_2, 0x01); + T3_3 = clmul(M512(gcm_poly2), T2_3, 0x01); + + T3_0 = bslli_epi128(T3_0, 8); + T3_1 = bslli_epi128(T3_1, 8); + T3_2 = bslli_epi128(T3_2, 8); + T3_3 = bslli_epi128(T3_3, 8); + + T2_0 = xor(T3_0, T2_0); + T2_1 = xor(T3_1, T2_1); + T2_2 = xor(T3_2, T2_2); + T2_3 = xor(T3_3, T2_3); + + /* Second phase of the reduction */ + + T3_0 = clmul(M512(gcm_poly2), T2_0, 0x00); + T3_1 = clmul(M512(gcm_poly2), T2_1, 0x00); + T3_2 = clmul(M512(gcm_poly2), T2_2, 0x00); + T3_3 = clmul(M512(gcm_poly2), T2_3, 0x00); + + T3_0 = bsrli_epi128(T3_0, 4); + T3_1 = bsrli_epi128(T3_1, 4); + T3_2 = bsrli_epi128(T3_2, 4); + T3_3 = bsrli_epi128(T3_3, 4); + + T4_0 = clmul(M512(gcm_poly2), T2_0, 0x10); + T4_1 = clmul(M512(gcm_poly2), T2_1, 0x10); + T4_2 = clmul(M512(gcm_poly2), T2_2, 0x10); + T4_3 = clmul(M512(gcm_poly2), T2_3, 0x10); + + T4_0 = bslli_epi128(T4_0, 4); + T4_1 = bslli_epi128(T4_1, 4); + T4_2 = bslli_epi128(T4_2, 4); + T4_3 = bslli_epi128(T4_3, 4); + + T4_0 = xor(T4_0, T3_0); + T4_1 = xor(T4_1, T3_1); + T4_2 = xor(T4_2, T3_2); + T4_3 = xor(T4_3, T3_3); + + T4_0 = xor(T4_0, T1_0); + T4_1 = xor(T4_1, T1_1); + T4_2 = xor(T4_2, T1_2); + T4_3 = xor(T4_3, T1_3); + + /* Reduction complete, store result */ + + __mmask8 store_mask_0 = 0x03 * (0x1 & ((load_mask >> 0 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 0 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 0 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 0 * 4) >> 3)); // + + __mmask8 store_mask_1 = 0x03 * (0x1 & ((load_mask >> 1 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 1 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 1 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 1 * 4) >> 3)); // + + __mmask8 store_mask_2 = 0x03 * (0x1 & ((load_mask >> 2 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 2 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 2 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 2 * 4) >> 3)); // + + __mmask8 store_mask_3 = 0x03 * (0x1 & ((load_mask >> 3 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 3 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 3 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 3 * 4) >> 3)); // + + mask_storeu_epi64(ghash + 0, store_mask_0, T4_0); + mask_storeu_epi64(ghash + 4, store_mask_1, T4_1); + mask_storeu_epi64(ghash + 8, store_mask_2, T4_2); + mask_storeu_epi64(ghash + 12, store_mask_3, T4_3); + + /* Update pointers and lengths */ + + (*input_len) = mask_sub_epi32((*input_len), load_mask, (*input_len), set1_epi32(16 * stream_len)); + + __mmask8 ptr_update_mask_lo = load_mask & 0xFF; + __mmask8 ptr_update_mask_hi = (load_mask >> 8) & 0xFF; + + __m512i loc_pa_input_lo = loadu(pa_input); + __m512i loc_pa_input_hi = loadu(pa_input + 8); + + loc_pa_input_lo = mask_add_epi64(loc_pa_input_lo, ptr_update_mask_lo, loc_pa_input_lo, set1_epi64(16 * stream_len)); + loc_pa_input_hi = mask_add_epi64(loc_pa_input_hi, ptr_update_mask_hi, loc_pa_input_hi, set1_epi64(16 * stream_len)); + + storeu((void *)pa_input, loc_pa_input_lo); + storeu((void *)(pa_input + 8), loc_pa_input_hi); + + stream_len = 0; + load_mask = 0; + + /* Calculate how many blocks can be processed with delayed reduction */ + for (int i = 8; i > 0; i--) { + __mmask16 max_stream_len_mask = cmp_epi32_mask((*input_len), set1_epi32(16 * i), _MM_CMPINT_GE); + __mmask16 less_16_mask = cmp_epi32_mask((*input_len), set1_epi32(16), _MM_CMPINT_LT); + __mmask16 stream_mask = max_stream_len_mask | less_16_mask; + + load_mask = load_mask * (load_mask != 0) | max_stream_len_mask * (stream_mask == 0xFFFF) * (load_mask == 0) * (less_16_mask != 0xFFFF); + stream_len = stream_len + i * (stream_mask == 0xFFFF) * (stream_len == 0) * (less_16_mask != 0xFFFF); + } + + load_mask &= mb_mask; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_ghash_partial_blocks_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_ghash_partial_blocks_mb16.c new file mode 100644 index 000000000..4d1662e99 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_ghash_partial_blocks_mb16.c @@ -0,0 +1,183 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +__INLINE void read_first(__m512i *data_blocks[4], const int8u *const pa_input[SM4_LINES], __m512i *input_len, __mmask16 load_mask) +{ + __mmask16 load_mask_0 = load_mask >> 0 * 4; + __mmask16 load_mask_1 = load_mask >> 1 * 4; + __mmask16 load_mask_2 = load_mask >> 2 * 4; + __mmask16 load_mask_3 = load_mask >> 3 * 4; + + *(data_blocks[0]) = setzero(); + *(data_blocks[1]) = setzero(); + *(data_blocks[2]) = setzero(); + *(data_blocks[3]) = setzero(); + + /* + // Loop with 4 iterations here does not unrolled by some compilers + // Unrolled explicitly because insert32x4 require the last parameter to be const + */ + + /* Begin of explicitly unrolled loop */ + + __m128i input_block_0 = + _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (0 + 4 * 0)))) * (0x1 & load_mask_0), (void *)pa_input[0 + 4 * 0]); + __m128i input_block_1 = + _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (0 + 4 * 1)))) * (0x1 & load_mask_1), (void *)pa_input[0 + 4 * 1]); + __m128i input_block_2 = + _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (0 + 4 * 2)))) * (0x1 & load_mask_2), (void *)pa_input[0 + 4 * 2]); + __m128i input_block_3 = + _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (0 + 4 * 3)))) * (0x1 & load_mask_3), (void *)pa_input[0 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 0); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 0); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 0); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 0); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (1 + 4 * 0)))) * (0x1 & load_mask_0), (void *)pa_input[1 + 4 * 0]); + input_block_1 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (1 + 4 * 1)))) * (0x1 & load_mask_1), (void *)pa_input[1 + 4 * 1]); + input_block_2 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (1 + 4 * 2)))) * (0x1 & load_mask_2), (void *)pa_input[1 + 4 * 2]); + input_block_3 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (1 + 4 * 3)))) * (0x1 & load_mask_3), (void *)pa_input[1 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 1); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 1); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 1); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 1); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (2 + 4 * 0)))) * (0x1 & load_mask_0), (void *)pa_input[2 + 4 * 0]); + input_block_1 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (2 + 4 * 1)))) * (0x1 & load_mask_1), (void *)pa_input[2 + 4 * 1]); + input_block_2 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (2 + 4 * 2)))) * (0x1 & load_mask_2), (void *)pa_input[2 + 4 * 2]); + input_block_3 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (2 + 4 * 3)))) * (0x1 & load_mask_3), (void *)pa_input[2 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 2); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 2); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 2); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 2); + + load_mask_0 >>= 1; + load_mask_1 >>= 1; + load_mask_2 >>= 1; + load_mask_3 >>= 1; + + input_block_0 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (3 + 4 * 0)))) * (0x1 & load_mask_0), (void *)pa_input[3 + 4 * 0]); + input_block_1 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (3 + 4 * 1)))) * (0x1 & load_mask_1), (void *)pa_input[3 + 4 * 1]); + input_block_2 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (3 + 4 * 2)))) * (0x1 & load_mask_2), (void *)pa_input[3 + 4 * 2]); + input_block_3 = _mm_maskz_loadu_epi8((0xFFFF >> (16 - *((int *)input_len + (3 + 4 * 3)))) * (0x1 & load_mask_3), (void *)pa_input[3 + 4 * 3]); + + input_block_0 = _mm_shuffle_epi8(input_block_0, M128(swapEndianness)); + input_block_1 = _mm_shuffle_epi8(input_block_1, M128(swapEndianness)); + input_block_2 = _mm_shuffle_epi8(input_block_2, M128(swapEndianness)); + input_block_3 = _mm_shuffle_epi8(input_block_3, M128(swapEndianness)); + + *(data_blocks[0]) = insert32x4(*(data_blocks[0]), input_block_0, 3); + *(data_blocks[1]) = insert32x4(*(data_blocks[1]), input_block_1, 3); + *(data_blocks[2]) = insert32x4(*(data_blocks[2]), input_block_2, 3); + *(data_blocks[3]) = insert32x4(*(data_blocks[3]), input_block_3, 3); + + /* End of explicitly unrolled loop */ +} + +/* +// This function updates 16 blocks of ghash by processing partial blocks ( < 128 bit blocks) of data +// +// This code is a port of GCM part of Intel(R) IPSec AES-GCM code +// Code modified to work with multi-buffer approach +*/ +void sm4_gcm_update_ghash_partial_blocks_mb16(__m128i ghash[SM4_LINES], + const int8u *const pa_input[SM4_LINES], + __m512i *input_len, + __m128i hashkey[SM4_LINES], + __mmask16 mb_mask) +{ + __m512i hashkeys_4_0, hashkeys_4_1, hashkeys_4_2, hashkeys_4_3; + __m512i *hashkeys[] = { &hashkeys_4_0, &hashkeys_4_1, &hashkeys_4_2, &hashkeys_4_3 }; + + __m512i data_blocks_4_0, data_blocks_4_1, data_blocks_4_2, data_blocks_4_3; + __m512i *data_blocks[] = { &data_blocks_4_0, &data_blocks_4_1, &data_blocks_4_2, &data_blocks_4_3 }; + + __mmask16 load_mask = ~cmp_epi32_mask((*input_len), setzero(), _MM_CMPINT_EQ) & mb_mask; + + if (load_mask) { + + hashkeys_4_0 = loadu(hashkey + 0); + hashkeys_4_1 = loadu(hashkey + 4); + hashkeys_4_2 = loadu(hashkey + 8); + hashkeys_4_3 = loadu(hashkey + 12); + + read_first(data_blocks, pa_input, input_len, load_mask); + + data_blocks_4_0 = xor(data_blocks_4_0, M512(ghash + 0)); + data_blocks_4_1 = xor(data_blocks_4_1, M512(ghash + 4)); + data_blocks_4_2 = xor(data_blocks_4_2, M512(ghash + 8)); + data_blocks_4_3 = xor(data_blocks_4_3, M512(ghash + 12)); + + sm4_gcm_ghash_mul_single_block_mb16(data_blocks, hashkeys); + + __mmask8 store_mask_0 = 0x03 * (0x1 & ((load_mask >> 0 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 0 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 0 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 0 * 4) >> 3)); // + + __mmask8 store_mask_1 = 0x03 * (0x1 & ((load_mask >> 1 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 1 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 1 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 1 * 4) >> 3)); // + + __mmask8 store_mask_2 = 0x03 * (0x1 & ((load_mask >> 2 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 2 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 2 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 2 * 4) >> 3)); // + + __mmask8 store_mask_3 = 0x03 * (0x1 & ((load_mask >> 3 * 4) >> 0)) | // + 0x0C * (0x1 & ((load_mask >> 3 * 4) >> 1)) | // + 0x30 * (0x1 & ((load_mask >> 3 * 4) >> 2)) | // + 0xC0 * (0x1 & ((load_mask >> 3 * 4) >> 3)); // + + mask_storeu_epi64(ghash + 0, store_mask_0, data_blocks_4_0); + mask_storeu_epi64(ghash + 4, store_mask_1, data_blocks_4_1); + mask_storeu_epi64(ghash + 8, store_mask_2, data_blocks_4_2); + mask_storeu_epi64(ghash + 12, store_mask_3, data_blocks_4_3); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_iv_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_iv_mb16.c new file mode 100644 index 000000000..fb84911f9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/internal/sm4_gcm_update_iv_mb16.c @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +/* +// This function process 16 buffers with initialization vector (IV) data +*/ +__mmask16 sm4_gcm_update_iv_mb16(const int8u *const pa_iv[SM4_LINES], const int iv_len[SM4_LINES], __mmask16 mb_mask, SM4_GCM_CTX_mb16 *p_context) +{ + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_update_iv; + + __m128i *j0 = SM4_GCM_CONTEXT_J0(p_context); + + const int8u *loc_pa_iv[SM4_LINES]; + int iv_len_rearranged[SM4_LINES]; + + /* Rearrange pointers and lengths to right layout */ + rearrange(loc_pa_iv, pa_iv); + rearrange(iv_len_rearranged, iv_len); + + __m512i loc_iv_len = loadu(iv_len_rearranged); + __m512i max_iv_len = set1_epi64(0x1FFFFFFFFFFFFFFF); /* (2^64 - 1) div 8 */ + + /* + // Update full IV length + // + // IV length is passed as 32 bit integer + // IV length is used to construct last block for ghash computation as follow: + // 64 zero bits | 64 IV len bits + // Length of IV is stored in context in 64 bits + // + // Code below transforms 32 bit input integers into the following block: + // 32 zero bits | 32 IV len bits + // and add it to length stored in context + // + // The whole operation is following for each buffer: + // 64 bits with IV len in context + // + + // 32 zero bits | 32 bits with input IV len + // + // Last J0 block is constructed in IV finalization + */ + + __m512i full_iv_len = maskz_expandloadu_epi32(0x5555, iv_len_rearranged); + full_iv_len = add_epi64(full_iv_len, loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 0))); + storeu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 0), full_iv_len); + + __mmask8 mask_overflow_lo = cmp_epi64_mask(max_iv_len, full_iv_len, _MM_CMPINT_LT); + + full_iv_len = maskz_expandloadu_epi32(0x5555, iv_len_rearranged + 8); + full_iv_len = add_epi64(full_iv_len, loadu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 1))); + storeu(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 1), full_iv_len); + + __mmask8 mask_overflow_hi = cmp_epi64_mask(max_iv_len, full_iv_len, _MM_CMPINT_LT); + + __mmask16 mask_overflow = mask_overflow_hi << 8 | mask_overflow_lo; + + /* Process full blocks of IVs */ + sm4_gcm_update_ghash_full_blocks_mb16(j0, loc_pa_iv, &loc_iv_len, SM4_GCM_CONTEXT_HASHKEY(p_context), mb_mask); + + if (cmp_epi32_mask(loc_iv_len, setzero(), _MM_CMPINT_EQ) != 0xFFFF) { + /* Process partial blocks of IVs and finalize IVs */ + sm4_gcm_update_ghash_partial_blocks_mb16(j0, loc_pa_iv, &loc_iv_len, SM4_GCM_CONTEXT_HASHKEY(p_context)[0], mb_mask); + sm4_gcm_finalize_iv_mb16(loc_pa_iv, mb_mask, p_context); + + SM4_GCM_CONTEXT_STATE(p_context) = sm4_gcm_update_aad; + } + + return mask_overflow; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_decrypt_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_decrypt_mb16_api.c new file mode 100644 index 000000000..effcefdac --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_decrypt_mb16_api.c @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 +mbx_sm4_gcm_decrypt_mb16(int8u *pa_out[SM4_LINES], const int8u *const pa_in[SM4_LINES], const int in_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_in || NULL == in_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_gcm_update_iv != SM4_GCM_CONTEXT_STATE(p_context) && sm4_gcm_update_aad != SM4_GCM_CONTEXT_STATE(p_context) && + sm4_gcm_start_encdec != SM4_GCM_CONTEXT_STATE(p_context) && sm4_gcm_dec != SM4_GCM_CONTEXT_STATE(p_context)) { + + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_in[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + if (in_len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + /* We take elements from the SM4_GCM_CONTEXT_LEN(p_context) array by the formula [1+buf_no*2], because of the + layout of length data in the context. Refer to sources/ippcp/crypto_mb/include/crypto_mb/sm4_gcm.h file for details. */ + int length_data_position = 1+buf_no*2; + if( ((int64u)in_len[buf_no] >= MAX_TXT_LEN) || + (SM4_GCM_CONTEXT_LEN(p_context)[length_data_position] >= MAX_TXT_LEN - (int64u)in_len[buf_no]) || + ((SM4_GCM_CONTEXT_LEN(p_context)[length_data_position] + (int64u)in_len[buf_no]) < (int64u)in_len[buf_no])) { + + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + __mmask16 overflow_mask = sm4_gcm_decrypt_mb16(pa_out, pa_in, in_len, mb_mask, p_context); + + /* Set bad status for buffers with overflowed lengths */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (overflow_mask >> buf_no & 1) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + } + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_encrypt_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_encrypt_mb16_api.c new file mode 100644 index 000000000..04baf3591 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_encrypt_mb16_api.c @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 +mbx_sm4_gcm_encrypt_mb16(int8u *pa_out[SM4_LINES], const int8u *const pa_in[SM4_LINES], const int in_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_in || NULL == in_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_gcm_update_iv != SM4_GCM_CONTEXT_STATE(p_context) && sm4_gcm_update_aad != SM4_GCM_CONTEXT_STATE(p_context) && + sm4_gcm_start_encdec != SM4_GCM_CONTEXT_STATE(p_context) && sm4_gcm_enc != SM4_GCM_CONTEXT_STATE(p_context)) { + + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_in[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + if (in_len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + /* We take elements from the SM4_GCM_CONTEXT_LEN(p_context) array by the formula [1+buf_no*2], because of the + layout of length data in the context. Refer to sources/ippcp/crypto_mb/include/crypto_mb/sm4_gcm.h file for details. */ + int length_data_position = 1+buf_no*2; + if( ((int64u)in_len[buf_no] >= MAX_TXT_LEN) || + (SM4_GCM_CONTEXT_LEN(p_context)[length_data_position] >= MAX_TXT_LEN - (int64u)in_len[buf_no]) || + ((SM4_GCM_CONTEXT_LEN(p_context)[length_data_position] + (int64u)in_len[buf_no]) < (int64u)in_len[buf_no])) { + + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + __mmask16 overflow_mask = sm4_gcm_encrypt_mb16(pa_out, pa_in, in_len, mb_mask, p_context); + + /* Set bad status for buffers with overflowed lengths */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (overflow_mask >> buf_no & 1) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + } + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_get_tag_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_get_tag_mb16_api.c new file mode 100644 index 000000000..b385d7da6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_get_tag_mb16_api.c @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_gcm_get_tag_mb16(int8u *pa_tag[SM4_LINES], const int tag_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_tag || NULL == tag_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_gcm_update_aad != SM4_GCM_CONTEXT_STATE(p_context) && sm4_gcm_start_encdec != SM4_GCM_CONTEXT_STATE(p_context) && + sm4_gcm_enc != SM4_GCM_CONTEXT_STATE(p_context) && sm4_gcm_dec != SM4_GCM_CONTEXT_STATE(p_context) && + sm4_gcm_get_tag != SM4_GCM_CONTEXT_STATE(p_context)) { + + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero and set bad status for tags of invalid length */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_tag[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + if (tag_len[buf_no] < 0 || tag_len[buf_no] > 16) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + sm4_gcm_get_tag_mb16(pa_tag, tag_len, mb_mask, p_context); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_init_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_init_mb16_api.c new file mode 100644 index 000000000..8f146ab02 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_init_mb16_api.c @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_gcm_init_mb16(const sm4_key *const pa_key[SM4_LINES], + const int8u *const pa_iv[SM4_LINES], + const int iv_len[SM4_LINES], + SM4_GCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + __mmask16 mb_mask_rearranged = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_key || NULL == pa_iv || NULL == iv_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero and set bad status for IV with zero length */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_key[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + if (pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask_rearranged &= ~(0x1 << rearrangeOrder[buf_no]); + } + if (iv_len[buf_no] <= 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask_rearranged &= ~(0x1 << rearrangeOrder[buf_no]); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + + /* Clear buffers */ + + SM4_GCM_CLEAR_BUFFER((SM4_GCM_CONTEXT_BUFFER_SLOT_TYPE *)SM4_GCM_CONTEXT_J0(p_context)); + SM4_GCM_CLEAR_BUFFER((SM4_GCM_CONTEXT_BUFFER_SLOT_TYPE *)SM4_GCM_CONTEXT_GHASH(p_context)); + + + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 0)); + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 1)); + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 2)); + SM4_GCM_CLEAR_LEN(BUFFER_REG_NUM(SM4_GCM_CONTEXT_LEN(p_context), 3)); + + /* + // Compute SM4 keys + // initialize int32u mbx_sm4_key_schedule[SM4_ROUNDS][SM4_LINES] buffer in context + // keys layout for each round: + // key0 key4 key8 key12 key1 key5 key9 key13 key2 key6 key10 key14 key3 key7 key11 key15 + */ + + sm4_set_round_keys_mb16((int32u **)SM4_GCM_CONTEXT_KEY(p_context), (const int8u **)pa_key, mb_mask); + + /* + // Compute hashkeys + // initialize __m128i hashkey[SM4_GCM_HASHKEY_PWR_NUM][SM4_LINES] buffer in context + // hashkeys layout for each hashkey power: + // hashkey0 hashkey4 hashkey8 hashkey12 hashkey1 hashkey5 hashkey9 hashkey13 hashkey2 hashkey6 hashkey10 hashkey14 hashkey3 hashkey7 hashkey11 + hashkey15 + */ + sm4_gcm_precompute_hashkey_mb16((const mbx_sm4_key_schedule *)SM4_GCM_CONTEXT_KEY(p_context), p_context); + + /* Process IV */ + __mmask16 overflow_mask = sm4_gcm_update_iv_mb16(pa_iv, iv_len, mb_mask_rearranged, p_context); + + /* Set bad status for buffers with overflowed lengths */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (overflow_mask >> buf_no & 1) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + } + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_update_aad_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_update_aad_mb16_api.c new file mode 100644 index 000000000..3c698c8aa --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_update_aad_mb16_api.c @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_gcm_update_aad_mb16(const int8u *const pa_aad[SM4_LINES], const int aad_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_aad || NULL == aad_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_gcm_update_iv != SM4_GCM_CONTEXT_STATE(p_context) && sm4_gcm_update_aad != SM4_GCM_CONTEXT_STATE(p_context)) { + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_aad[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + if (aad_len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + __mmask16 overflow_mask = sm4_gcm_update_aad_mb16(pa_aad, aad_len, mb_mask, p_context); + + /* Set bad status for buffers with overflowed lengths */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (overflow_mask >> buf_no & 1) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + } + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_update_iv_mb16_api.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_update_iv_mb16_api.c new file mode 100644 index 000000000..d190e9000 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/gcm/sm4_gcm_update_iv_mb16_api.c @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_gcm_update_iv_mb16(const int8u *const pa_iv[SM4_LINES], const int iv_len[SM4_LINES], SM4_GCM_CTX_mb16 *p_context) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Check input pointers */ + if (NULL == pa_iv || NULL == iv_len || NULL == p_context) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Check state */ + if (sm4_gcm_update_iv != SM4_GCM_CONTEXT_STATE(p_context)) { + status = MBX_SET_STS16_ALL(MBX_STATUS_MISMATCH_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero and set bad status for IV with zero length */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + if (iv_len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + mb_mask &= ~(0x1 << rearrangeOrder[buf_no]); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + __mmask16 overflow_mask = sm4_gcm_update_iv_mb16(pa_iv, iv_len, mb_mask, p_context); + + /* Set bad status for buffers with overflowed lengths */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (overflow_mask >> buf_no & 1) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + } + } + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_dec_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_dec_mb16.c new file mode 100644 index 000000000..a1c362910 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_dec_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_decrypt_cbc_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched || NULL == pa_iv) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length and integrity for each buffer */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if ((len[buf_no] < 0) || (len[buf_no]&(SM4_BLOCK_SIZE-1))) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_cbc_dec_kernel_mb16(pa_out, pa_inp, len, (const int32u**)key_sched, mb_mask, pa_iv); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_enc_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_enc_mb16.c new file mode 100644 index 000000000..e67820cc5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_enc_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_encrypt_cbc_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched || NULL == pa_iv) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length and integrity for each buffer */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if ((len[buf_no] < 0) || (len[buf_no]&(SM4_BLOCK_SIZE-1))) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_cbc_enc_kernel_mb16(pa_out, pa_inp, len, (const int32u**)key_sched, mb_mask, pa_iv); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_mb16.c new file mode 100644 index 000000000..2f2ac77b0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cbc_mb16.c @@ -0,0 +1,559 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include + +void sm4_cbc_enc_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, const int8u* pa_iv[SM4_LINES]) +{ + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + __ALIGN64 int8u* loc_out[SM4_LINES]; + + /* Length of the input data in 128-bit chunks - number of SM4 blocks */ + __m512i num_blocks; + GET_NUM_BLOCKS(num_blocks, len, SM4_BLOCK_SIZE); + + /* Local copies of the pointers to input and output buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* Set p_rk pointer to the beginning of the key schedule */ + const __m512i* p_rk = (const __m512i*)key_sched; + + /* Check if we have any data */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + + __m512i iv0, iv1, iv2, iv3; + __m512i z0, z1, z2, z3, xi; + + /* Load and transpose iv */ + TRANSPOSE_16x4_I32_EPI32(&iv0, &iv1, &iv2, &iv3, pa_iv, tmp_mask); + + while (tmp_mask) { + /* Transpose input data */ + TRANSPOSE_16x4_I32_EPI32(&z0, &z1, &z2, &z3, loc_inp, tmp_mask); + + z0 = _mm512_xor_epi32(z0, iv0); + z1 = _mm512_xor_epi32(z1, iv1); + z2 = _mm512_xor_epi32(z2, iv2); + z3 = _mm512_xor_epi32(z3, iv3); + + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) + SM4_FOUR_ROUNDS(z0, z1, z2, z3, xi, p_rk, 1); + + p_rk -= SM4_ROUNDS; + + iv0 = z3; + iv1 = z2; + iv2 = z1; + iv3 = z0; + + /* Transpose and store encrypted blocks */ + TRANSPOSE_4x16_I32_EPI32(&z0, &z1, &z2, &z3, loc_out, tmp_mask); + + /* Update pointers to data */ + _mm512_storeu_si512((void*)loc_inp, _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + + _mm512_storeu_si512(loc_out, _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + _mm512_storeu_si512((loc_out + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + + /* Update number of blocks left and processing mask */ + num_blocks = _mm512_sub_epi32(num_blocks, _mm512_set1_epi32(1)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])&z0, 1); + zero_mb8((int64u(*)[8])&z1, 1); + zero_mb8((int64u(*)[8])&z2, 1); + zero_mb8((int64u(*)[8])&z3, 1); + zero_mb8((int64u(*)[8])&xi, 1); +} + +/* + * Perform SM4-CBC-MAC on 16 buffers and generate their authentication tag. + * + * @param[out] pa_out Array of pointers to authentication tag + * @param[in] pa_in Array of pointers to input buffers + * @param[in] len Array of buffer lengths + * @param[in] key_sched Array of SM4 scheduled keys + * @param[in] mb_mask Bitmask selecting which lines to generate tag + * @param[in] pa_iv Array of IV pointers + */ +void sm4_cbc_mac_kernel_mb16(__m128i pa_out[SM4_LINES], const int8u *const pa_inp[SM4_LINES], + const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], + __mmask16 mb_mask, const int8u *pa_iv[SM4_LINES]) +{ + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + + /* Length of the input data in 128-bit chunks - number of SM4 blocks */ + __m512i num_blocks; + GET_NUM_BLOCKS(num_blocks, len, SM4_BLOCK_SIZE); + + /* Local copies of the pointers to input buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + /* Set p_rk pointer to the beginning of the key schedule */ + const __m512i* p_rk = (const __m512i*)key_sched; + + /* Check if we have any data */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + __m512i iv0, iv1, iv2, iv3; + __m512i z0, z1, z2, z3, xi; + __m512i in0, in1, in2, in3; + + mb_mask = tmp_mask; + + z0 = _mm512_setzero_si512(); + z1 = _mm512_setzero_si512(); + z2 = _mm512_setzero_si512(); + z3 = _mm512_setzero_si512(); + + /* Load and transpose iv */ + TRANSPOSE_16x4_I32_EPI32(&iv0, &iv1, &iv2, &iv3, pa_iv, tmp_mask); + + while (tmp_mask) { + /* Transpose input data */ + TRANSPOSE_16x4_I32_EPI32(&in0, &in1, &in2, &in3, loc_inp, tmp_mask); + + z0 = _mm512_mask_xor_epi32(z0, tmp_mask, in0, iv0); + z1 = _mm512_mask_xor_epi32(z1, tmp_mask, in1, iv1); + z2 = _mm512_mask_xor_epi32(z2, tmp_mask, in2, iv2); + z3 = _mm512_mask_xor_epi32(z3, tmp_mask, in3, iv3); + + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) + SM4_FOUR_ROUNDS_MASKED(z0, z1, z2, z3, xi, tmp_mask, p_rk, 1); + + p_rk -= SM4_ROUNDS; + + iv0 = z3; + iv1 = z2; + iv2 = z1; + iv3 = z0; + + /* Update pointers to data */ + _mm512_storeu_si512((void*)loc_inp, _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + + /* Update number of blocks left and processing mask */ + num_blocks = _mm512_sub_epi32(num_blocks, _mm512_set1_epi32(1)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + } + + /* Transpose and store result MAC */ + TRANSPOSE_4x16_I32_O128_EPI32(&z0, &z1, &z2, &z3, pa_out, mb_mask); + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])&z0, 1); + zero_mb8((int64u(*)[8])&z1, 1); + zero_mb8((int64u(*)[8])&z2, 1); + zero_mb8((int64u(*)[8])&z3, 1); + zero_mb8((int64u(*)[8])&xi, 1); +} + +static void sm4_cbc_dec_incomplete_buff_mb16(const int8u* loc_inp[SM4_LINES], int8u* loc_out[SM4_LINES], + __m512i num_blocks, const __m512i* p_rk, + __mmask16 mb_mask, + __m512i TMP[20], __m512i STORED_CT[16]); + +void sm4_cbc_dec_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, const int8u* pa_iv[SM4_LINES]) +{ + const int8u* loc_inp[SM4_LINES]; + int8u* loc_out[SM4_LINES]; + + /* Load the constant value */ + const __m512i swap_m512i = _mm512_loadu_si512(swapBytes); + + /* Registers to store ciphertext blocks to be XOR'ed with output of SM4 cipher stage */ + __m512i STORED_CT[16]; + + /* Length of the input data in 128-bit chunks - number of SM4 blocks */ + __m512i num_blocks; + GET_NUM_BLOCKS(num_blocks, len, SM4_BLOCK_SIZE); + + /* Don't process empty buffers */ + mb_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NE); + + /* Local copies of the pointers to input and output buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* Set p_rk pointer to the end of the key schedule */ + const __m512i* p_rk = (const __m512i*)key_sched + (SM4_ROUNDS - 1); + + __ALIGN64 __m512i TMP[20]; + __mmask16 loc_mb_mask = mb_mask; + + /* Store first ciphertext block for next round */ + for (int i = 0; i < SM4_LINES; i++) { + STORED_CT[i] = _mm512_setzero_epi32(); + __m128i data_block = _mm_maskz_loadu_epi32(0x000F * (0x1&loc_mb_mask), loc_inp[i]); + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], data_block, 3); + loc_mb_mask >>= 1; + } + + /* Process the first block from each buffer, because it contains IV specific */ + /* Load and transpose input data */ + TRANSPOSE_16x4_I32_EPI32(&TMP[0], &TMP[1], &TMP[2], &TMP[3], loc_inp, mb_mask); + + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk -= 4) + SM4_FOUR_ROUNDS(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], p_rk, -1); + p_rk += SM4_ROUNDS; + + /* Transpose and store first encrypted block for each buffer */ + TRANSPOSE_AND_XOR_4x16_I32_EPI32(&TMP[0], &TMP[1], &TMP[2], &TMP[3], loc_out, pa_iv, mb_mask); + + /* Update pointers to data */ + _mm512_storeu_si512((void*)loc_inp, _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + + _mm512_storeu_si512(loc_out, _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + _mm512_storeu_si512((loc_out + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE))); + + num_blocks = _mm512_sub_epi32(num_blocks, _mm512_set1_epi32(1)); + + /* Generate the mask to process 4 blocks from each buffer */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(4), _MM_CMPINT_NLT); + + /* Go to this loop if all 16 buffers contain at least 4 blocks each */ + while (tmp_mask == 0xFFFF) { + TMP[0] = _mm512_loadu_si512(loc_inp[0]); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[1])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[2])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[3])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(loc_inp[4])); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[5])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[6])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[7])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(loc_inp[8])); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[9])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[10])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[11])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(loc_inp[12])); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[13])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[14])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[15])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, -1); + + p_rk += SM4_ROUNDS; + + for (int i = 0; i < SM4_LINES; i++) + STORED_CT[i] = _mm512_alignr_epi64(_mm512_loadu_si512(loc_inp[i]), STORED_CT[i], 6); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[4] = _mm512_xor_si512(TMP[0], STORED_CT[0]); + TMP[5] = _mm512_xor_si512(TMP[1], STORED_CT[1]); + TMP[6] = _mm512_xor_si512(TMP[2], STORED_CT[2]); + TMP[7] = _mm512_xor_si512(TMP[3], STORED_CT[3]); + /* Store last block of ciphertext for next iteration */ + for (int i = 0; i < 4; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[0]), TMP[4]); + _mm512_storeu_si512((__m512i*)(loc_out[1]), TMP[5]); + _mm512_storeu_si512((__m512i*)(loc_out[2]), TMP[6]); + _mm512_storeu_si512((__m512i*)(loc_out[3]), TMP[7]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[8] = _mm512_xor_si512(TMP[0], STORED_CT[4]); + TMP[9] = _mm512_xor_si512(TMP[1], STORED_CT[5]); + TMP[10] = _mm512_xor_si512(TMP[2], STORED_CT[6]); + TMP[11] = _mm512_xor_si512(TMP[3], STORED_CT[7]); + /* Store last block of ciphertext for next iteration */ + for (int i = 4; i < 8; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[4]), TMP[8]); + _mm512_storeu_si512((__m512i*)(loc_out[5]), TMP[9]); + _mm512_storeu_si512((__m512i*)(loc_out[6]), TMP[10]); + _mm512_storeu_si512((__m512i*)(loc_out[7]), TMP[11]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[12] = _mm512_xor_si512(TMP[0], STORED_CT[8]); + TMP[13] = _mm512_xor_si512(TMP[1], STORED_CT[9]); + TMP[14] = _mm512_xor_si512(TMP[2], STORED_CT[10]); + TMP[15] = _mm512_xor_si512(TMP[3], STORED_CT[11]); + /* Store last block of ciphertext for next iteration */ + for (int i = 8; i < 12; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[8]), TMP[12]); + _mm512_storeu_si512((__m512i*)(loc_out[9]), TMP[13]); + _mm512_storeu_si512((__m512i*)(loc_out[10]), TMP[14]); + _mm512_storeu_si512((__m512i*)(loc_out[11]), TMP[15]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[16] = _mm512_xor_si512(TMP[0], STORED_CT[12]); + TMP[17] = _mm512_xor_si512(TMP[1], STORED_CT[13]); + TMP[18] = _mm512_xor_si512(TMP[2], STORED_CT[14]); + TMP[19] = _mm512_xor_si512(TMP[3], STORED_CT[15]); + for (int i = 12; i < SM4_LINES; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[12]), TMP[16]); + _mm512_storeu_si512((__m512i*)(loc_out[13]), TMP[17]); + _mm512_storeu_si512((__m512i*)(loc_out[14]), TMP[18]); + _mm512_storeu_si512((__m512i*)(loc_out[15]), TMP[19]); + + /* Update pointers to data */ + _mm512_storeu_si512((void*)loc_inp, _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + + _mm512_storeu_si512(loc_out, _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + _mm512_storeu_si512((loc_out + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + + /* Update number of blocks left and processing mask */ + num_blocks = _mm512_sub_epi32(num_blocks, _mm512_set1_epi32(4)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(4), _MM_CMPINT_NLT); + } + + /* compute incomplete buffer loading */ + sm4_cbc_dec_incomplete_buff_mb16(loc_inp, loc_out, + num_blocks, p_rk, + mb_mask, + TMP, STORED_CT); + /* clear local copy of sensitive data */ + zero_mb8((int64u (*)[8])TMP, sizeof(TMP)/sizeof(TMP[0])); +} + +// Disable optimization for VS19 (>= 19.27) +OPTIMIZE_OFF_VS19 + +static void sm4_cbc_dec_incomplete_buff_mb16(const int8u* loc_inp[SM4_LINES], int8u* loc_out[SM4_LINES], + __m512i num_blocks, const __m512i* p_rk, + __mmask16 mb_mask, + __m512i TMP[20], + __m512i STORED_CT[16]){ + /* Load the constant value */ + const __m512i swap_m512i = _mm512_loadu_si512(swapBytes); + /* Check if we have any data */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + + while (tmp_mask) { + /* Generate the array of masks for data loading. 0 - 4 blocks will be can load from each buffer - depend on the amount of remaining data */ + __ALIGN64 __mmask8 block_mask[16]; + + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(4), _MM_CMPINT_NLT); + /* Will be loaded 4 blocks of data */ + M128(block_mask) = _mm_maskz_set1_epi8(tmp_mask, 0xFF); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(3), _MM_CMPINT_EQ); + /* Will be loaded 3 blocks of data */ + M128(block_mask) = _mm_mask_set1_epi8(M128(block_mask), tmp_mask, 0x3F); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(2), _MM_CMPINT_EQ); + /* Will be loaded 2 blocks of data */ + M128(block_mask) = _mm_mask_set1_epi8(M128(block_mask), tmp_mask, 0xF); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(1), _MM_CMPINT_EQ); + /* Will be loaded 1 block of data */ + M128(block_mask) = _mm_mask_set1_epi8(M128(block_mask), tmp_mask, 0x3); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[0], loc_inp[0]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[1], loc_inp[1]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[2], loc_inp[2]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[3], loc_inp[3]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[4], loc_inp[4]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[5], loc_inp[5]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[6], loc_inp[6]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[7], loc_inp[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[8], loc_inp[8]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[9], loc_inp[9]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[10], loc_inp[10]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[11], loc_inp[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[12], loc_inp[12]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[13], loc_inp[13]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[14], loc_inp[14]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[15], loc_inp[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, -1); + p_rk += SM4_ROUNDS; + + for (int i = 0; i < SM4_LINES; i++) + STORED_CT[i] = _mm512_alignr_epi64(_mm512_maskz_loadu_epi64(block_mask[i], (__m128i *const)loc_inp[i]), STORED_CT[i], 6); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[4] = _mm512_xor_si512(TMP[0], STORED_CT[0]); + TMP[5] = _mm512_xor_si512(TMP[1], STORED_CT[1]); + TMP[6] = _mm512_xor_si512(TMP[2], STORED_CT[2]); + TMP[7] = _mm512_xor_si512(TMP[3], STORED_CT[3]); + /* Store last block of ciphertext for next iteration */ + for (int i = 0; i < 4; i++) { + __mmask8 write_block_mask = _kshiftri_mask8(block_mask[i], 6); + __m128i data_block = _mm_maskz_loadu_epi64(write_block_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_mask_inserti64x2(STORED_CT[i], block_mask[i], STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi64(loc_out[0], block_mask[0], TMP[4]); + _mm512_mask_storeu_epi64(loc_out[1], block_mask[1], TMP[5]); + _mm512_mask_storeu_epi64(loc_out[2], block_mask[2], TMP[6]); + _mm512_mask_storeu_epi64(loc_out[3], block_mask[3], TMP[7]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[8] = _mm512_xor_si512(TMP[0], STORED_CT[4]); + TMP[9] = _mm512_xor_si512(TMP[1], STORED_CT[5]); + TMP[10] = _mm512_xor_si512(TMP[2], STORED_CT[6]); + TMP[11] = _mm512_xor_si512(TMP[3], STORED_CT[7]); + /* Store last block of ciphertext for next iteration */ + for (int i = 4; i < 8; i++) { + __mmask8 write_block_mask = _kshiftri_mask8(block_mask[i], 6); + __m128i data_block = _mm_maskz_loadu_epi64(write_block_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_mask_inserti64x2(STORED_CT[i], block_mask[i], STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi64(loc_out[4], block_mask[4], TMP[8]); + _mm512_mask_storeu_epi64(loc_out[5], block_mask[5], TMP[9]); + _mm512_mask_storeu_epi64(loc_out[6], block_mask[6], TMP[10]); + _mm512_mask_storeu_epi64(loc_out[7], block_mask[7], TMP[11]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[12] = _mm512_xor_si512(TMP[0], STORED_CT[8]); + TMP[13] = _mm512_xor_si512(TMP[1], STORED_CT[9]); + TMP[14] = _mm512_xor_si512(TMP[2], STORED_CT[10]); + TMP[15] = _mm512_xor_si512(TMP[3], STORED_CT[11]); + /* Store last block of ciphertext for next iteration */ + for (int i = 8; i < 12; i++) { + __mmask8 write_block_mask = _kshiftri_mask8(block_mask[i], 6); + __m128i data_block = _mm_maskz_loadu_epi64(write_block_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_mask_inserti64x2(STORED_CT[i], block_mask[i], STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi64(loc_out[8], block_mask[8], TMP[12]); + _mm512_mask_storeu_epi64(loc_out[9], block_mask[9], TMP[13]); + _mm512_mask_storeu_epi64(loc_out[10], block_mask[10], TMP[14]); + _mm512_mask_storeu_epi64(loc_out[11], block_mask[11], TMP[15]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], swap_m512i); + TMP[1] = _mm512_shuffle_epi8(TMP[1], swap_m512i); + TMP[2] = _mm512_shuffle_epi8(TMP[2], swap_m512i); + TMP[3] = _mm512_shuffle_epi8(TMP[3], swap_m512i); + /* xor with IVs */ + TMP[16] = _mm512_xor_si512(TMP[0], STORED_CT[12]); + TMP[17] = _mm512_xor_si512(TMP[1], STORED_CT[13]); + TMP[18] = _mm512_xor_si512(TMP[2], STORED_CT[14]); + TMP[19] = _mm512_xor_si512(TMP[3], STORED_CT[15]); + /* Store last block of ciphertext for next iteration */ + for (int i = 12; i < SM4_LINES; i++) { + __mmask8 write_block_mask = _kshiftri_mask8(block_mask[i], 6); + __m128i data_block = _mm_maskz_loadu_epi64(write_block_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_mask_inserti64x2(STORED_CT[i], block_mask[i], STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi64(loc_out[12], block_mask[12], TMP[16]); + _mm512_mask_storeu_epi64(loc_out[13], block_mask[13], TMP[17]); + _mm512_mask_storeu_epi64(loc_out[14], block_mask[14], TMP[18]); + _mm512_mask_storeu_epi64(loc_out[15], block_mask[15], TMP[19]); + + /* Update pointers to data */ + _mm512_storeu_si512((void*)loc_inp, _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + + _mm512_storeu_si512(loc_out, _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + _mm512_storeu_si512((loc_out + 8), _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE))); + + /* Update the number of blocks. For some buffers, the value can become zero or a negative number - these buffers will not be processed */ + num_blocks = _mm512_sub_epi32(num_blocks, _mm512_set1_epi32(4)); + + /* Check if we have any data */ + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + } + return; +} + +// Enable optimization for VS19 (>= 19.27) +OPTIMIZE_ON_VS19 diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_dec_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_dec_mb16.c new file mode 100644 index 000000000..2f689ed7a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_dec_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_decrypt_cfb128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched || NULL == pa_iv) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length, input pointers and stream integrity*/ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if ((len[buf_no] < 0) || (len[buf_no] & (SM4_BLOCK_SIZE - 1))) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_cfb128_dec_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, (const int32u**)key_sched, pa_iv, mb_mask); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_enc_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_enc_mb16.c new file mode 100644 index 000000000..3d44efe8e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_enc_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_encrypt_cfb128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, const int8u* pa_iv[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched || NULL == pa_iv) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length, input pointers and stream integrity*/ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if ((len[buf_no] < 0) || (len[buf_no] & (SM4_BLOCK_SIZE - 1))) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_cfb128_enc_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, (const int32u**)key_sched, pa_iv, mb_mask); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_mb16.c new file mode 100644 index 000000000..fcf26b61c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_cfb_mb16.c @@ -0,0 +1,427 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +void sm4_cfb128_enc_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], const int8u* pa_iv[SM4_LINES], __mmask16 mb_mask) +{ + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + __ALIGN64 int8u* loc_out[SM4_LINES]; + + /* Get the copy of input data lengths in bytes */ + __m512i loc_len = _mm512_loadu_si512(len); + int* p_loc_len = (int*)&loc_len; + + /* Local copies of the pointers to input and output buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* Set p_rk pointer to the beginning of the key schedule */ + const __m512i* p_rk = (const __m512i*)key_sched; + + /* Check if we have any data */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + + /* Load and transpose iv */ + __m512i iv0, iv1, iv2, iv3; + TRANSPOSE_16x4_I32_EPI32(&iv0, &iv1, &iv2, &iv3, (const int8u**)pa_iv, tmp_mask); + + /* Main loop */ + __m512i z0, z1, z2, z3, tmp; + while (tmp_mask) { + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) + SM4_FOUR_ROUNDS(iv0, iv1, iv2, iv3, tmp, p_rk, 1); + + p_rk -= SM4_ROUNDS; + + /* Load and transpose plaintext */ + TRANSPOSE_16x4_I32_EPI32(&z0, &z1, &z2, &z3, (const int8u**)loc_inp, tmp_mask); + + /* Change the order of blocks (Y0, Y1, Y2, Y3) = R(X32, X33, X34, X35) = (X35, X34, X33, X32) and xor with plain text */ + tmp = iv0; + iv0 = _mm512_xor_epi32(iv3, z0); + iv3 = _mm512_xor_epi32(tmp, z3); + tmp = iv1; + iv1 = _mm512_xor_epi32(iv2, z1); + iv2 = _mm512_xor_epi32(tmp, z2); + + /* Transpose and store encrypted blocks by bytes */ + TRANSPOSE_4x16_I32_EPI8(iv0, iv1, iv2, iv3, loc_out, p_loc_len, tmp_mask); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(SM4_BLOCK_SIZE)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])&iv0, 1); + zero_mb8((int64u(*)[8])&iv1, 1); + zero_mb8((int64u(*)[8])&iv2, 1); + zero_mb8((int64u(*)[8])&iv3, 1); + + zero_mb8((int64u(*)[8])&z0, 1); + zero_mb8((int64u(*)[8])&z1, 1); + zero_mb8((int64u(*)[8])&z2, 1); + zero_mb8((int64u(*)[8])&z3, 1); + zero_mb8((int64u(*)[8])&tmp, 1); +} + +static void sm4_cfb128_mask_dec_kernel_mb16(const int8u** loc_inp, int8u** loc_out, __m512i loc_len, const __m512i* p_rk, __mmask16 tmp_mask, __m512i STORED_CT[16]) +{ + __m512i TMP[20]; + while (tmp_mask) { + /* Generate the array of masks for data loading */ + __mmask64 stream_mask[16]; + int* p_loc_len = (int*)&loc_len; + for (int i = 0; i < SM4_LINES; i++) { + UPDATE_STREAM_MASK_64(stream_mask[i], p_loc_len); + } + + for (int i = 0; i < SM4_LINES; i++) + STORED_CT[i] = _mm512_alignr_epi64(_mm512_maskz_loadu_epi8(stream_mask[i], (__m128i *const)loc_inp[i]), STORED_CT[i], 6); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[4], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[5], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[6], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[7], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[8], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[9], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[10], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[11], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[12], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[13], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[14], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[15], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, 1); + p_rk -= SM4_ROUNDS; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[4] = _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask[0], loc_inp[0])); + TMP[5] = _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask[1], loc_inp[1])); + TMP[6] = _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask[2], loc_inp[2])); + TMP[7] = _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask[3], loc_inp[3])); + /* Store last block of ciphertext for next iteration */ + for (int i = 0; i < 4; i++) { + __mmask64 write_stream_mask = _kshiftri_mask64(stream_mask[i], 8*6); + __m128i data_block = _mm_maskz_loadu_epi8((__mmask16) write_stream_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi8(loc_out[0], stream_mask[0], TMP[4]); + _mm512_mask_storeu_epi8(loc_out[1], stream_mask[1], TMP[5]); + _mm512_mask_storeu_epi8(loc_out[2], stream_mask[2], TMP[6]); + _mm512_mask_storeu_epi8(loc_out[3], stream_mask[3], TMP[7]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[8] = _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask[4], loc_inp[4])); + TMP[9] = _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask[5], loc_inp[5])); + TMP[10] = _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask[6], loc_inp[6])); + TMP[11] = _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask[7], loc_inp[7])); + /* Store last block of ciphertext for next iteration */ + for (int i = 4; i < 8; i++) { + __mmask64 write_stream_mask = _kshiftri_mask64(stream_mask[i], 8*6); + __m128i data_block = _mm_maskz_loadu_epi8((__mmask16) write_stream_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi8(loc_out[4], stream_mask[4], TMP[8]); + _mm512_mask_storeu_epi8(loc_out[5], stream_mask[5], TMP[9]); + _mm512_mask_storeu_epi8(loc_out[6], stream_mask[6], TMP[10]); + _mm512_mask_storeu_epi8(loc_out[7], stream_mask[7], TMP[11]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[12] = _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask[8], loc_inp[8])); + TMP[13] = _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask[9], loc_inp[9])); + TMP[14] = _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask[10], loc_inp[10])); + TMP[15] = _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask[11], loc_inp[11])); + /* Store last block of ciphertext for next iteration */ + for (int i = 8; i < 12; i++) { + __mmask64 write_stream_mask = _kshiftri_mask64(stream_mask[i], 8*6); + __m128i data_block = _mm_maskz_loadu_epi8((__mmask16) write_stream_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi8(loc_out[8], stream_mask[8], TMP[12]); + _mm512_mask_storeu_epi8(loc_out[9], stream_mask[9], TMP[13]); + _mm512_mask_storeu_epi8(loc_out[10], stream_mask[10], TMP[14]); + _mm512_mask_storeu_epi8(loc_out[11], stream_mask[11], TMP[15]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[16] = _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask[12], loc_inp[12])); + TMP[17] = _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask[13], loc_inp[13])); + TMP[18] = _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask[14], loc_inp[14])); + TMP[19] = _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask[15], loc_inp[15])); + /* Store last block of ciphertext for next iteration */ + for (int i = 12; i < SM4_LINES; i++) { + __mmask64 write_stream_mask = _kshiftri_mask64(stream_mask[i], 8*6); + __m128i data_block = _mm_maskz_loadu_epi8((__mmask16) write_stream_mask, (__m128i const*)loc_inp[i] + 3); + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], data_block, 3); + } + _mm512_mask_storeu_epi8(loc_out[12], stream_mask[12], TMP[16]); + _mm512_mask_storeu_epi8(loc_out[13], stream_mask[13], TMP[17]); + _mm512_mask_storeu_epi8(loc_out[14], stream_mask[14], TMP[18]); + _mm512_mask_storeu_epi8(loc_out[15], stream_mask[15], TMP[19]); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update the number of blocks. For some buffers, the value can become zero or a negative number - these buffers will not be processed */ + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE)); + + /* Check if we have any data */ + tmp_mask = _mm512_mask_cmp_epi32_mask(tmp_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); +} + +void sm4_cfb128_dec_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], const int8u* pa_iv[SM4_LINES], __mmask16 mb_mask) { + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + __ALIGN64 int8u* loc_out[SM4_LINES]; + /* Registers to store ciphertext blocks to be XOR'ed with output of SM4 cipher stage */ + __m512i STORED_CT[16]; + + /* Get the copy of input data lengths in bytes */ + __m512i loc_len = _mm512_loadu_si512(len); + + /* Don't process empty buffers */ + mb_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + + /* Local copies of the pointers to input and output buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* Set p_rk pointer to the beginnig of the key schedule */ + const __m512i* p_rk = (const __m512i*)key_sched; + + __m512i TMP[20]; + __mmask16 loc_mb_mask = mb_mask; + + /* Store first ciphertext block for next round */ + for (int i = 0; i < SM4_LINES; i++) { + STORED_CT[i] = _mm512_setzero_epi32(); + __m128i data_block = _mm_maskz_loadu_epi32(0x000F * (0x1&loc_mb_mask), loc_inp[i]); + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], data_block, 3); + loc_mb_mask >>= 1; + } + + /* Process the first block from each buffer, because it contains IV specific */ + /* Load and transpose iv */ + TRANSPOSE_16x4_I32_EPI32(&TMP[4], &TMP[5], &TMP[6], &TMP[7], (const int8u**)pa_iv, mb_mask); + + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) + SM4_FOUR_ROUNDS(TMP[4], TMP[5], TMP[6], TMP[7], TMP[8], p_rk, 1); + p_rk = (const __m512i*)key_sched; + /* Load and transpose ciphertext */ + TRANSPOSE_16x4_I32_EPI32(&TMP[9], &TMP[10], &TMP[11], &TMP[12], (const int8u**)loc_inp, mb_mask); + + /* Change the order of blocks (Y0, Y1, Y2, Y3) = R(X32, X33, X34, X35) = (X35, X34, X33, X32) and xor with plain text */ + TMP[8] = TMP[4]; + TMP[4] = _mm512_xor_epi32(TMP[7], TMP[9]); + TMP[7] = _mm512_xor_epi32(TMP[8], TMP[12]); + TMP[8] = TMP[5]; + TMP[5] = _mm512_xor_epi32(TMP[6], TMP[10]); + TMP[6] = _mm512_xor_epi32(TMP[8], TMP[11]); + + /* Transpose and store encrypted blocks by bytes */ + int *p_loc_len = (int*)&loc_len; + TRANSPOSE_4x16_I32_EPI8(TMP[4], TMP[5], TMP[6], TMP[7], loc_out, p_loc_len, mb_mask); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(SM4_BLOCK_SIZE)); + + /* Generate the mask to process 4 blocks from each buffer */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + + /* Go to this loop if all 16 buffers contain at least 4 blocks each */ + while (tmp_mask == 0xFFFF) { + for (int i = 0; i < SM4_LINES; i++) + STORED_CT[i] = _mm512_alignr_epi64(_mm512_loadu_si512(loc_inp[i]), STORED_CT[i], 6); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[4], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[5], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[6], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[7], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[8], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[9], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[10], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[11], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_shuffle_epi8(STORED_CT[12], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(STORED_CT[13], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(STORED_CT[14], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(STORED_CT[15], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, 1); + p_rk -= SM4_ROUNDS; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[4] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[0])); + TMP[5] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[1])); + TMP[6] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[2])); + TMP[7] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[3])); + /* Store last block of ciphertext for next iteration */ + for (int i = 0; i < 4; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[0]), TMP[4]); + _mm512_storeu_si512((__m512i*)(loc_out[1]), TMP[5]); + _mm512_storeu_si512((__m512i*)(loc_out[2]), TMP[6]); + _mm512_storeu_si512((__m512i*)(loc_out[3]), TMP[7]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[8] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[4])); + TMP[9] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[5])); + TMP[10] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[6])); + TMP[11] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[7])); + /* Store last block of ciphertext for next iteration */ + for (int i = 4; i < 8; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[4]), TMP[8]); + _mm512_storeu_si512((__m512i*)(loc_out[5]), TMP[9]); + _mm512_storeu_si512((__m512i*)(loc_out[6]), TMP[10]); + _mm512_storeu_si512((__m512i*)(loc_out[7]), TMP[11]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[12] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[8])); + TMP[13] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[9])); + TMP[14] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[10])); + TMP[15] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[11])); + /* Store last block of ciphertext for next iteration */ + for (int i = 8; i < 12; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[8]), TMP[12]); + _mm512_storeu_si512((__m512i*)(loc_out[9]), TMP[13]); + _mm512_storeu_si512((__m512i*)(loc_out[10]), TMP[14]); + _mm512_storeu_si512((__m512i*)(loc_out[11]), TMP[15]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + /* xor with ciphertext */ + TMP[16] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[12])); + TMP[17] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[13])); + TMP[18] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[14])); + TMP[19] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[15])); + for (int i = 12; i < SM4_LINES; i++) + STORED_CT[i] = _mm512_inserti64x2(STORED_CT[i], _mm_loadu_si128((__m128i const*)loc_inp[i] + 3), 3); + _mm512_storeu_si512((__m512i*)(loc_out[12]), TMP[16]); + _mm512_storeu_si512((__m512i*)(loc_out[13]), TMP[17]); + _mm512_storeu_si512((__m512i*)(loc_out[14]), TMP[18]); + _mm512_storeu_si512((__m512i*)(loc_out[15]), TMP[19]); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + } + + /* Check if we have any data */ + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + if (tmp_mask) + sm4_cfb128_mask_dec_kernel_mb16(loc_inp, loc_out, loc_len, p_rk, tmp_mask, STORED_CT); + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_dec_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_dec_mb16.c new file mode 100644 index 000000000..f8bb3364a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_dec_mb16.c @@ -0,0 +1,28 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_decrypt_ctr128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_ctr[SM4_LINES]) +{ + return mbx_sm4_encrypt_ctr128_mb16(pa_out, pa_inp, len, key_sched, pa_ctr); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_enc_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_enc_mb16.c new file mode 100644 index 000000000..30bd59aff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_enc_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_encrypt_ctr128_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_ctr[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched || NULL == pa_ctr) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length and input pointers */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_ctr[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if (len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_ctr128_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, (const int32u**)key_sched, mb_mask, pa_ctr); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_mb16.c new file mode 100644 index 000000000..1a2c3ab19 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ctr_mb16.c @@ -0,0 +1,321 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +static void sm4_ctr128_mask_kernel_mb16(__m512i* CTR, const __m512i* p_rk, __m512i loc_len, const int8u** loc_inp, int8u** loc_out, int8u* inc, __mmask16 tmp_mask, __mmask16 mb_mask) +{ + __m512i TMP[20]; + while (tmp_mask) { + *CTR = IncBlock512(*CTR, inc); + *(CTR + 1) = IncBlock512(*(CTR + 1), inc); + *(CTR + 2) = IncBlock512(*(CTR + 2), inc); + *(CTR + 3) = IncBlock512(*(CTR + 3), inc); + TMP[0] = _mm512_shuffle_epi8(*CTR, M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(*(CTR + 1), M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(*(CTR + 2), M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(*(CTR + 3), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + *(CTR + 4) = IncBlock512(*(CTR + 4), inc); + *(CTR + 5) = IncBlock512(*(CTR + 5), inc); + *(CTR + 6) = IncBlock512(*(CTR + 6), inc); + *(CTR + 7) = IncBlock512(*(CTR + 7), inc); + TMP[0] = _mm512_shuffle_epi8(*(CTR + 4), M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(*(CTR + 5), M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(*(CTR + 6), M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(*(CTR + 7), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + *(CTR + 8) = IncBlock512(*(CTR + 8), inc); + *(CTR + 9) = IncBlock512(*(CTR + 9), inc); + *(CTR + 10) = IncBlock512(*(CTR + 10), inc); + *(CTR + 11) = IncBlock512(*(CTR + 11), inc); + TMP[0] = _mm512_shuffle_epi8(*(CTR + 8), M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(*(CTR + 9), M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(*(CTR + 10), M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(*(CTR + 11), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + *(CTR + 12) = IncBlock512(*(CTR + 12), inc); + *(CTR + 13) = IncBlock512(*(CTR + 13), inc); + *(CTR + 14) = IncBlock512(*(CTR + 14), inc); + *(CTR + 15) = IncBlock512(*(CTR + 15), inc); + TMP[0] = _mm512_shuffle_epi8(*(CTR + 12), M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(*(CTR + 13), M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(*(CTR + 14), M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(*(CTR + 15), M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, 1); + p_rk -= SM4_ROUNDS; + + /* Mask for data loading */ + __mmask64 stream_mask; + int* p_loc_len = (int*)&loc_len; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[0], stream_mask, _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[0]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[1], stream_mask, _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[1]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[2], stream_mask, _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[2]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[3], stream_mask, _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[3]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[4], stream_mask, _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[4]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[5], stream_mask, _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[5]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[6], stream_mask, _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[6]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[7], stream_mask, _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[7]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[8], stream_mask, _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[8]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[9], stream_mask, _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[9]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[10], stream_mask, _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[10]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[11], stream_mask, _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[11]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[12], stream_mask, _mm512_xor_si512(TMP[0], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[12]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[13], stream_mask, _mm512_xor_si512(TMP[1], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[13]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[14], stream_mask, _mm512_xor_si512(TMP[2], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[14]))); + UPDATE_STREAM_MASK_64(stream_mask, p_loc_len) + _mm512_mask_storeu_epi8((__m512i*)loc_out[15], stream_mask, _mm512_xor_si512(TMP[3], _mm512_maskz_loadu_epi8(stream_mask, loc_inp[15]))); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_set1_epi32(0), _MM_CMPINT_NLE); + inc = (int8u*)nextInc; + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); +} + + +__INLINE __m128i IncBlock128(__m128i x, int32u increment) +{ + __m128i t = _mm_add_epi64(x, _mm_maskz_loadu_epi32(1, &increment)); + __mmask8 carryMask = _mm_cmplt_epu64_mask(t, x); + carryMask = (__mmask8)(carryMask << 1); + t = _mm_add_epi64(t, _mm_mask_set1_epi64(_mm_setzero_si128(), carryMask, 1)); + + return t; +} + +void sm4_ctr128_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, int8u* pa_ctr[SM4_LINES]) +{ + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + __ALIGN64 int8u* loc_out[SM4_LINES]; + + /* Create the local copy of the input data length in bytes and set it to zero for non-valid buffers */ + __m512i loc_len; + loc_len = _mm512_loadu_si512(len); + loc_len = _mm512_mask_set1_epi32(loc_len, ~mb_mask, 0); + + /* input blocks loc_blks[] = ceil(loc_len[]/SM4_BLOCK_SIZE) */ + int32u loc_blks[SM4_LINES]; + _mm512_storeu_si512(loc_blks, _mm512_srli_epi32(_mm512_add_epi32(loc_len, _mm512_set1_epi32(SM4_BLOCK_SIZE - 1)), 4)); + + /* Local copies of the pointers to input and otput buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* Pointer p_rk is set to the beginning of the key schedule */ + const __m512i* p_rk = (const __m512i*)key_sched; + + /* TMP[] - temporary buffer for processing */ + /* CTR - store CTR values */ + __m512i TMP[20]; + __m512i CTR[SM4_LINES]; + __m128i loc_ctr[SM4_LINES]; + + /* Load CTR value from valid buffers */ + mb_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + for (int i = 0; i < SM4_LINES; i++) { + if (0x1 & (mb_mask >> i)) { + loc_ctr[i] = _mm_loadu_si128((__m128i*)pa_ctr[i]); + /* Read string counter and convert to numerical */ + loc_ctr[i] = _mm_shuffle_epi8(loc_ctr[i], M128(swapEndianness)); + } + else + loc_ctr[i] = _mm_setzero_si128(); + + CTR[i] = _mm512_broadcast_i64x2(loc_ctr[i]); + } + + /* Generate the mask to process 4 blocks from each buffer */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + + int8u* inc = (int8u*)firstInc; + + /* Go to this loop if all 16 buffers contain at least 4 blocks each */ + while (tmp_mask == 0xFFFF) { + CTR[0] = IncBlock512(CTR[0], inc); + CTR[1] = IncBlock512(CTR[1], inc); + CTR[2] = IncBlock512(CTR[2], inc); + CTR[3] = IncBlock512(CTR[3], inc); + TMP[0] = _mm512_shuffle_epi8(CTR[0], M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(CTR[1], M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(CTR[2], M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(CTR[3], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + CTR[4] = IncBlock512(CTR[4], inc); + CTR[5] = IncBlock512(CTR[5], inc); + CTR[6] = IncBlock512(CTR[6], inc); + CTR[7] = IncBlock512(CTR[7], inc); + TMP[0] = _mm512_shuffle_epi8(CTR[4], M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(CTR[5], M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(CTR[6], M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(CTR[7], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + CTR[8] = IncBlock512(CTR[8], inc); + CTR[9] = IncBlock512(CTR[9], inc); + CTR[10] = IncBlock512(CTR[10], inc); + CTR[11] = IncBlock512(CTR[11], inc); + TMP[0] = _mm512_shuffle_epi8(CTR[8], M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(CTR[9], M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(CTR[10], M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(CTR[11], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + CTR[12] = IncBlock512(CTR[12], inc); + CTR[13] = IncBlock512(CTR[13], inc); + CTR[14] = IncBlock512(CTR[14], inc); + CTR[15] = IncBlock512(CTR[15], inc); + TMP[0] = _mm512_shuffle_epi8(CTR[12], M512(swapWordsOrder)); + TMP[1] = _mm512_shuffle_epi8(CTR[13], M512(swapWordsOrder)); + TMP[2] = _mm512_shuffle_epi8(CTR[14], M512(swapWordsOrder)); + TMP[3] = _mm512_shuffle_epi8(CTR[15], M512(swapWordsOrder)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, 1); + p_rk -= SM4_ROUNDS; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[0], _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[0]))); + _mm512_storeu_si512((__m512i*)loc_out[1], _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[1]))); + _mm512_storeu_si512((__m512i*)loc_out[2], _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[2]))); + _mm512_storeu_si512((__m512i*)loc_out[3], _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[3]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[4], _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[4]))); + _mm512_storeu_si512((__m512i*)loc_out[5], _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[5]))); + _mm512_storeu_si512((__m512i*)loc_out[6], _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[6]))); + _mm512_storeu_si512((__m512i*)loc_out[7], _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[7]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[8], _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[8]))); + _mm512_storeu_si512((__m512i*)loc_out[9], _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[9]))); + _mm512_storeu_si512((__m512i*)loc_out[10], _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[10]))); + _mm512_storeu_si512((__m512i*)loc_out[11], _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[11]))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[12], _mm512_xor_si512(TMP[0], _mm512_loadu_si512(loc_inp[12]))); + _mm512_storeu_si512((__m512i*)loc_out[13], _mm512_xor_si512(TMP[1], _mm512_loadu_si512(loc_inp[13]))); + _mm512_storeu_si512((__m512i*)loc_out[14], _mm512_xor_si512(TMP[2], _mm512_loadu_si512(loc_inp[14]))); + _mm512_storeu_si512((__m512i*)loc_out[15], _mm512_xor_si512(TMP[3], _mm512_loadu_si512(loc_inp[15]))); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + inc = (int8u*)nextInc; + } + + /* Check if we have any data */ + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + if (tmp_mask) + sm4_ctr128_mask_kernel_mb16(CTR, p_rk, loc_len, loc_inp, loc_out, inc, tmp_mask, mb_mask); + + /* update and store counters */ + for (int i = 0; i < SM4_LINES; i++) { + if (0x1 & (mb_mask >> i)) { + loc_ctr[i] = IncBlock128(loc_ctr[i], loc_blks[i]); + loc_ctr[i] = _mm_shuffle_epi8(loc_ctr[i], M128(swapEndianness)); + _mm_storeu_si128((__m128i*)pa_ctr[i], loc_ctr[i]); + loc_ctr[i] = _mm_setzero_si128(); + } + } + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); + zero_mb8((int64u(*)[8])CTR, sizeof(CTR) / sizeof(CTR[0])); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_dec_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_dec_mb16.c new file mode 100644 index 000000000..01847fd72 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_dec_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_decrypt_ecb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length and integrity for each buffer */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if ((len[buf_no] < 0) || (len[buf_no]&(SM4_BLOCK_SIZE-1))) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_ecb_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, (const int32u**)key_sched, mb_mask, SM4_DEC); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_enc_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_enc_mb16.c new file mode 100644 index 000000000..7fcbe05a1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_enc_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_encrypt_ecb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length and integrity for each buffer */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if ((len[buf_no] < 0) || (len[buf_no]&(SM4_BLOCK_SIZE-1))) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_ecb_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, (const int32u**)key_sched, mb_mask, SM4_ENC); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_mb16.c new file mode 100644 index 000000000..298c4a847 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ecb_mb16.c @@ -0,0 +1,284 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include +#include + +static void sm4_ecb_incomplete_buff_mb16(const int8u* loc_inp[SM4_LINES], int8u* loc_out[SM4_LINES], + __m512i num_blocks, const __m512i* p_rk, const int sign, + __mmask16 mb_mask, + __m512i TMP[20]); + +void sm4_ecb_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, int operation) +{ + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + __ALIGN64 int8u* loc_out[SM4_LINES]; + + /* Length of the input data in 128-bit chunks - number of SM4 blocks */ + __m512i num_blocks; + GET_NUM_BLOCKS(num_blocks, len, SM4_BLOCK_SIZE); + + /* Local copies of the pointers to input and output buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* p_rk set to the beginning or to the end of the key schedule */ + const __m512i* p_rk = (operation == SM4_ENC) ? (const __m512i*)key_sched : ((const __m512i*)key_sched + (SM4_ROUNDS - 1)); + + __ALIGN64 __m512i TMP[20]; + + /* Generate the mask to process 4 blocks from each buffer */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(4), _MM_CMPINT_NLT); + + /* Go to this loop if all 16 buffers contain at least 4 blocks each */ + while (tmp_mask == 0xFFFF) { + TMP[0] = _mm512_loadu_si512(loc_inp[0]); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[1])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[2])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[3])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(loc_inp[4])); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[5])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[6])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[7])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(loc_inp[8])); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[9])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[10])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[11])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(loc_inp[12])); + TMP[1] = _mm512_loadu_si512((__m512i*)(loc_inp[13])); + TMP[2] = _mm512_loadu_si512((__m512i*)(loc_inp[14])); + TMP[3] = _mm512_loadu_si512((__m512i*)(loc_inp[15])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, operation); + p_rk -= operation*SM4_ROUNDS; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(loc_out[0]), TMP[0]); + _mm512_storeu_si512((__m512i*)(loc_out[1]), TMP[1]); + _mm512_storeu_si512((__m512i*)(loc_out[2]), TMP[2]); + _mm512_storeu_si512((__m512i*)(loc_out[3]), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(loc_out[4]), TMP[0]); + _mm512_storeu_si512((__m512i*)(loc_out[5]), TMP[1]); + _mm512_storeu_si512((__m512i*)(loc_out[6]), TMP[2]); + _mm512_storeu_si512((__m512i*)(loc_out[7]), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(loc_out[8]), TMP[0]); + _mm512_storeu_si512((__m512i*)(loc_out[9]), TMP[1]); + _mm512_storeu_si512((__m512i*)(loc_out[10]), TMP[2]); + _mm512_storeu_si512((__m512i*)(loc_out[11]), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(loc_out[12]), TMP[0]); + _mm512_storeu_si512((__m512i*)(loc_out[13]), TMP[1]); + _mm512_storeu_si512((__m512i*)(loc_out[14]), TMP[2]); + _mm512_storeu_si512((__m512i*)(loc_out[15]), TMP[3]); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + num_blocks = _mm512_sub_epi32(num_blocks, _mm512_set1_epi32(4)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(4), _MM_CMPINT_NLT); + } + + /* compute incomplete buffer loading */ + sm4_ecb_incomplete_buff_mb16(loc_inp, loc_out, + num_blocks, p_rk, operation, + mb_mask, + TMP); + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); +} + +// Disable optimization for VS19 (>= 19.27) +OPTIMIZE_OFF_VS19 + +static void sm4_ecb_incomplete_buff_mb16(const int8u* loc_inp[SM4_LINES], int8u* loc_out[SM4_LINES], + __m512i num_blocks, const __m512i* p_rk, const int sign, + __mmask16 mb_mask, + __m512i TMP[20]){ + /* Check if we have any data */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + + while (tmp_mask) { + /* Generate the array of masks for data loading. 0 - 4 blocks will be can load from each buffer - depend on the amount of remaining data */ + __ALIGN64 __mmask8 block_mask[SM4_LINES]; + + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(4), _MM_CMPINT_NLT); + /* Will be loaded 4 blocks of data */ + M128(block_mask) = _mm_maskz_set1_epi8(tmp_mask, 0xFF); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(3), _MM_CMPINT_EQ); + /* Will be loaded 3 blocks of data */ + M128(block_mask) = _mm_mask_set1_epi8(M128(block_mask), tmp_mask, 0x3F); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(2), _MM_CMPINT_EQ); + /* Will be loaded 2 blocks of data */ + M128(block_mask) = _mm_mask_set1_epi8(M128(block_mask), tmp_mask, 0xF); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_set1_epi32(1), _MM_CMPINT_EQ); + /* Will be loaded 1 block of data */ + M128(block_mask) = _mm_mask_set1_epi8(M128(block_mask), tmp_mask, 0x3); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[0], loc_inp[0]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[1], loc_inp[1]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[2], loc_inp[2]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[3], loc_inp[3]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[4], loc_inp[4]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[5], loc_inp[5]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[6], loc_inp[6]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[7], loc_inp[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[8], loc_inp[8]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[9], loc_inp[9]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[10], loc_inp[10]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[11], loc_inp[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_maskz_loadu_epi64(block_mask[12], loc_inp[12]); + TMP[1] = _mm512_maskz_loadu_epi64(block_mask[13], loc_inp[13]); + TMP[2] = _mm512_maskz_loadu_epi64(block_mask[14], loc_inp[14]); + TMP[3] = _mm512_maskz_loadu_epi64(block_mask[15], loc_inp[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, sign); + p_rk -= sign*SM4_ROUNDS; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi64(loc_out[0], block_mask[0], TMP[0]); + _mm512_mask_storeu_epi64(loc_out[1], block_mask[1], TMP[1]); + _mm512_mask_storeu_epi64(loc_out[2], block_mask[2], TMP[2]); + _mm512_mask_storeu_epi64(loc_out[3], block_mask[3], TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi64(loc_out[4], block_mask[4], TMP[0]); + _mm512_mask_storeu_epi64(loc_out[5], block_mask[5], TMP[1]); + _mm512_mask_storeu_epi64(loc_out[6], block_mask[6], TMP[2]); + _mm512_mask_storeu_epi64(loc_out[7], block_mask[7], TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi64(loc_out[8], block_mask[8], TMP[0]); + _mm512_mask_storeu_epi64(loc_out[9], block_mask[9], TMP[1]); + _mm512_mask_storeu_epi64(loc_out[10], block_mask[10], TMP[2]); + _mm512_mask_storeu_epi64(loc_out[11], block_mask[11], TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi64(loc_out[12], block_mask[12], TMP[0]); + _mm512_mask_storeu_epi64(loc_out[13], block_mask[13], TMP[1]); + _mm512_mask_storeu_epi64(loc_out[14], block_mask[14], TMP[2]); + _mm512_mask_storeu_epi64(loc_out[15], block_mask[15], TMP[3]); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update the number of blocks. For some buffers, the value can become zero or a negative number - these buffers will not be processed */ + num_blocks = _mm512_sub_epi32(num_blocks, _mm512_set1_epi32(4)); + + /* Check if we have any data */ + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, num_blocks, _mm512_setzero_si512(), _MM_CMPINT_NLE); + } + return; +} + +// Enable optimization for VS19 (>= 19.27) +OPTIMIZE_ON_VS19 diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_dec_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_dec_mb16.c new file mode 100644 index 000000000..0be0161c4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_dec_mb16.c @@ -0,0 +1,28 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_decrypt_ofb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_iv[SM4_LINES]) +{ + return mbx_sm4_encrypt_ofb_mb16(pa_out, pa_inp, len, key_sched, pa_iv); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_enc_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_enc_mb16.c new file mode 100644 index 000000000..5d7835c00 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_enc_mb16.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_encrypt_ofb_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched, int8u* pa_iv[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || NULL == key_sched || NULL == pa_iv) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Test input data length, input pointers and stream integrity*/ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_iv[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if (len[buf_no] < 0) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_ofb_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, (const int32u**)key_sched, mb_mask, pa_iv); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_mb16.c new file mode 100644 index 000000000..c4c924254 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_ofb_mb16.c @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +void sm4_ofb_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], const int32u* key_sched[SM4_ROUNDS], __mmask16 mb_mask, int8u* pa_iv[SM4_LINES]) +{ + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + __ALIGN64 int8u* loc_out[SM4_LINES]; + + /* Get the copy of input data lengths in bytes */ + __m512i loc_len = _mm512_loadu_si512(len); + int* p_loc_len = (int*)&loc_len; + + /* Local copies of the pointers to input and output buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* Set p_rk pointer to the beginning of the key schedule */ + const __m512i* p_rk = (const __m512i*)key_sched; + + /* Check if we have any data */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + + __m512i iv0, iv1, iv2, iv3; + + /* Load and transpose iv */ + TRANSPOSE_16x4_I32_EPI32(&iv0, &iv1, &iv2, &iv3, (const int8u**)pa_iv, tmp_mask); + + /* Main loop */ + __m512i tmp; + while (tmp_mask) { + for (int itr = 0; itr < SM4_ROUNDS; itr += 4, p_rk += 4) + SM4_FOUR_ROUNDS(iv0, iv1, iv2, iv3, tmp, p_rk, 1); + + p_rk -= SM4_ROUNDS; + + /* Change the order of blocks (Y0, Y1, Y2, Y3) = R(X32, X33, X34, X35) = (X35, X34, X33, X32) */ + tmp = iv0; + iv0 = iv3; iv3 = tmp; + tmp = iv1; + iv1 = iv2; iv2 = tmp; + + /* Transpose and store encrypted blocks by bytes */ + TRANSPOSE_AND_XOR_4x16_I32_EPI8(iv0, iv1, iv2, iv3, loc_out, loc_inp, p_loc_len, tmp_mask); + + /* Update pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(SM4_BLOCK_SIZE)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + } + + /* Update ofb values */ + TRANSPOSE_4x16_I32_EPI32(&iv0, &iv1, &iv2, &iv3, pa_iv, tmp_mask); + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])&iv0, 1); + zero_mb8((int64u(*)[8])&iv1, 1); + zero_mb8((int64u(*)[8])&iv2, 1); + zero_mb8((int64u(*)[8])&iv3, 1); + zero_mb8((int64u(*)[8])&tmp, 1); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_setkey_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_setkey_mb16.c new file mode 100644 index 000000000..e61633219 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_setkey_mb16.c @@ -0,0 +1,151 @@ +/******************************************************************************* +* Copyright (C) 2021 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include +#include + +/* FK[] constants */ +static const int32u SM4_FK[4] = { + 0xA3B1BAC6,0x56AA3350,0x677D9197,0xB27022DC +}; + +/* CK[] constants */ +static const int32u SM4_CK[32] = { + 0x00070E15,0x1C232A31,0x383F464D,0x545B6269, + 0x70777E85,0x8C939AA1,0xA8AFB6BD,0xC4CBD2D9, + 0xE0E7EEF5,0xFC030A11,0x181F262D,0x343B4249, + 0x50575E65,0x6C737A81,0x888F969D,0xA4ABB2B9, + 0xC0C7CED5,0xDCE3EAF1,0xF8FF060D,0x141B2229, + 0x30373E45,0x4C535A61,0x686F767D,0x848B9299, + 0xA0A7AEB5,0xBCC3CAD1,0xD8DFE6ED,0xF4FB0209, + 0x10171E25,0x2C333A41,0x484F565D,0x646B7279 +}; + +#define SM4_ONE_RK(K0, K1, K2, K3, TMP, CK, OUT) { \ + /* (Ki+1 ^ Ki+2 ^ Ki+3 ^ CKi) */ \ + TMP = _mm512_xor_epi32(_mm512_xor_epi32(_mm512_xor_epi32(K1, K2), K3), _mm512_set1_epi32(CK)); \ + /* T'(Ki+1 ^ Ki+2 ^ Ki+3 ^ CKi) */ \ + TMP = sBox512(TMP); \ + TMP = _mm512_xor_epi32(TMP, Lkey512(TMP)); \ + /* Ki+4 = Ki ^ T'(Ki+1 ^ Ki+2 ^ Ki+3 ^ CKi) */ \ + K0 = _mm512_xor_epi32(K0, TMP); \ + _mm512_storeu_si512((void*)OUT, K0); \ +} + +#define SM4_FOUR_RK(K0, K1, K2, K3, TMP, CK, OUT) { \ + SM4_ONE_RK(K0, K1, K2, K3, TMP, CK[0], OUT); \ + SM4_ONE_RK(K1, K2, K3, K0, TMP, CK[1], (OUT + 1)); \ + SM4_ONE_RK(K2, K3, K0, K1, TMP, CK[2], (OUT + 2)); \ + SM4_ONE_RK(K3, K0, K1, K2, TMP, CK[3], (OUT + 3)); \ +} + + +void sm4_set_round_keys_mb16(int32u* key_sched[SM4_ROUNDS], const int8u* pa_inp_key[SM4_LINES], __mmask16 mb_mask) +{ + __m512i rki = _mm512_setzero_si512(); + __m512i z0, z1, z2, z3; + + TRANSPOSE_16x4_I32_EPI32(&z0, &z1, &z2, &z3, pa_inp_key, mb_mask); + + /* (K0, K1, K2, K3) = (MK0 ^ FK0, MK1 ^ FK1, MK2 ^ FK2, MK3 ^ FK3) */ + z0 = _mm512_xor_epi32(z0, _mm512_set1_epi32(SM4_FK[0])); + z1 = _mm512_xor_epi32(z1, _mm512_set1_epi32(SM4_FK[1])); + z2 = _mm512_xor_epi32(z2, _mm512_set1_epi32(SM4_FK[2])); + z3 = _mm512_xor_epi32(z3, _mm512_set1_epi32(SM4_FK[3])); + + const int32u* pCK = SM4_CK; + const __m512i* p_rk = (const __m512i*)key_sched; + + int itr; + for (itr = 0; itr < SM4_ROUNDS; itr += 4, pCK += 4, p_rk += 4) + SM4_FOUR_RK(z0, z1, z2, z3, rki, pCK, p_rk); + + /* clear copies of sensitive data and round keys */ + zero_mb8((int64u(*)[8])&z0, 1); + zero_mb8((int64u(*)[8])&z1, 1); + zero_mb8((int64u(*)[8])&z2, 1); + zero_mb8((int64u(*)[8])&z3, 1); + zero_mb8((int64u(*)[8])&rki, 1); +} + +DLL_PUBLIC +mbx_status16 mbx_sm4_set_key_mb16(mbx_sm4_key_schedule* key_sched, const sm4_key* pa_key[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == key_sched || NULL == pa_key) { + status = MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* Don't process buffers with input pointers equal to zero */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_key[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_set_round_keys_mb16((int32u**)key_sched, (const int8u**)pa_key, mb_mask); + + return status; +} + +DLL_PUBLIC +mbx_status16 mbx_sm4_xts_set_keys_mb16(mbx_sm4_key_schedule* key_sched1, + mbx_sm4_key_schedule* key_sched2, + const sm4_xts_key* pa_key[SM4_LINES]) +{ + int buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == key_sched1 || NULL == key_sched2 || NULL == pa_key) + return MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + + /* Don't process buffers with input pointers equal to zero */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_key[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) { + /* Generate round keys for key1 */ + sm4_set_round_keys_mb16((int32u**)key_sched1, (const int8u**)pa_key, mb_mask); + + const sm4_key* pa_key2[SM4_LINES]; + + for (int i = 0; i < SM4_LINES; i++) + pa_key2[i] = (const sm4_key*)&((int8u*)pa_key[i])[16]; + + /* Generate round keys for key2 */ + sm4_set_round_keys_mb16((int32u**)key_sched2, (const int8u**)pa_key2, mb_mask); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_dec_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_dec_mb16.c new file mode 100644 index 000000000..1b1530e59 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_dec_mb16.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_xts_decrypt_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], + const mbx_sm4_key_schedule* key_sched1, + const mbx_sm4_key_schedule* key_sched2, + const int8u* pa_tweak[SM4_LINES]) +{ + unsigned buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || + NULL == key_sched1 || NULL == key_sched2 || NULL == pa_tweak) + return MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + + /* Test input data length and input pointers */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_tweak[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if (len[buf_no] < SM4_BLOCK_SIZE) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if (len[buf_no] > SM4_XTS_MAX_SIZE) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_xts_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, + (const int32u**)key_sched1, (const int32u**)key_sched2, + pa_tweak, mb_mask, SM4_DEC); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_enc_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_enc_mb16.c new file mode 100644 index 000000000..6622b7b41 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_enc_mb16.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#include +#include + +DLL_PUBLIC +mbx_status16 mbx_sm4_xts_encrypt_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], + const int len[SM4_LINES], const mbx_sm4_key_schedule* key_sched1, + const mbx_sm4_key_schedule* key_sched2, + const int8u* pa_tweak[SM4_LINES]) +{ + unsigned buf_no; + mbx_status16 status = 0; + __mmask16 mb_mask = 0xFFFF; + + /* Test input pointers */ + if (NULL == pa_out || NULL == pa_inp || NULL == len || + NULL == key_sched1 || NULL == key_sched2 || NULL == pa_tweak) + return MBX_SET_STS16_ALL(MBX_STATUS_NULL_PARAM_ERR); + + /* Test input data length and input pointers */ + for (buf_no = 0; buf_no < SM4_LINES; buf_no++) { + if (pa_out[buf_no] == NULL || pa_inp[buf_no] == NULL || pa_tweak[buf_no] == NULL) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + /* Do not process empty buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if (len[buf_no] < SM4_BLOCK_SIZE) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + if (len[buf_no] > SM4_XTS_MAX_SIZE) { + status = MBX_SET_STS16(status, buf_no, MBX_STATUS_MISMATCH_PARAM_ERR); + /* Do not process non-valid buffers */ + mb_mask &= ~(0x1 << buf_no); + } + } + + if (MBX_IS_ANY_OK_STS16(status)) + sm4_xts_kernel_mb16(pa_out, (const int8u**)pa_inp, (const int*)len, + (const int32u**)key_sched1, (const int32u**)key_sched2, + pa_tweak, mb_mask, SM4_ENC); + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_mb16.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_mb16.c new file mode 100644 index 000000000..02db4078f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/sm4/sm4_xts_mb16.c @@ -0,0 +1,529 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include +#include + +#define FIRST_TWEAKS 1 +#define NEXT_TWEAKS 0 + +/* Generate the next 4 tweaks for a given buffer */ +static void generate_next_4_tweaks(const __m512i *PREV_TWEAK, __m512i *NEXT_TWEAK, + const __m512i z_shuf_mask, const __m512i z_poly, + const int first_tweaks) +{ + __m512i TMP1, TMP2, TMP3, TMP4; + const __mmask8 xor_mask = _cvtu32_mask8(0xAA); + + TMP1 = _mm512_shuffle_epi8(*PREV_TWEAK, z_shuf_mask); + /* + * In case of the first 4 tweaks, the shifts are variable, + * as we are start from tweak 1 in all 128-bit lanes, to construct + * tweaks 1, 2, 3 and 4 + */ + if (first_tweaks) { + const __m512i z_dq3210 = _mm512_loadu_si512(xts_const_dq3210); + const __m512i z_dq5678 = _mm512_loadu_si512(xts_const_dq5678); + + TMP2 = _mm512_sllv_epi64(*PREV_TWEAK, z_dq3210); + TMP3 = _mm512_srlv_epi64(TMP1, z_dq5678); + /* + * For following tweaks, the shifts are constant, + * as we calculate the next 4 tweaks, parting from tweaks N-4, N-3, N-2 and N, + * to construct tweaks N, N+1, N+2, N+3 + */ + } else { + TMP2 = _mm512_slli_epi64(*PREV_TWEAK, 4); + TMP3 = _mm512_srli_epi64(TMP1, 4); + } + TMP4 = _mm512_clmulepi64_epi128(TMP3, z_poly, 0); + TMP2 = _mm512_mask_xor_epi64(TMP2, xor_mask, TMP2, TMP3); + *NEXT_TWEAK = _mm512_xor_epi32(TMP4, TMP2); +} + +/* Prepare the last tweaks for a given buffer, if it has a partial block */ +static void prepare_last_tweaks(__m512i *TWEAK, __m512i *NEXT_TWEAK, + const int operation, int num_remain_full_blocks) +{ + /* + * For the encryption case, we need to prepare the tweak + * for the partial block to be at the beginning of NEXT_TWEAK, + * so depending on the number of remaining full blocks, its position + * will vary, so the permute mask will be different. In case, there are 4 full blocks, + * the newly generated NEXT_TWEAK will be positioned correctly. + */ + if (operation == SM4_ENC) { + if (num_remain_full_blocks == 1) + *NEXT_TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_next_tweak_permq_enc[0]), *TWEAK); + else if (num_remain_full_blocks == 2) + *NEXT_TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_next_tweak_permq_enc[1*8]), *TWEAK); + else if (num_remain_full_blocks == 3) + *NEXT_TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_next_tweak_permq_enc[2*8]), *TWEAK); + /* + * For the decryption case, it is a bit more complicated. + * In case of a partial block, the last two tweaks (the last tweak of the last full block) + * and the tweak of the last block, need to be interchanged. + * TWEAK will have the tweaks for the last FULL blocks and *NEXT_TWEAK, + * as earlier, will have the tweak for the last partial block. + */ + } else { + if (num_remain_full_blocks == 1) { + *NEXT_TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_next_tweak_permq[0]), *TWEAK); + *TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_tweak_permq[0]), *TWEAK); + } else if (num_remain_full_blocks == 2) { + *NEXT_TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_next_tweak_permq[1*8]), *TWEAK); + *TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_tweak_permq[1*8]), *TWEAK); + } else if (num_remain_full_blocks == 3) { + *NEXT_TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_next_tweak_permq[2*8]), *TWEAK); + *TWEAK = _mm512_permutexvar_epi64(_mm512_loadu_si512(&xts_tweak_permq[2*8]), *TWEAK); + } else if (num_remain_full_blocks == 4) { + *NEXT_TWEAK = _mm512_permutex2var_epi64(*NEXT_TWEAK, _mm512_loadu_si512(&xts_next_tweak_permq[3*8]), *TWEAK); + *TWEAK = _mm512_permutex2var_epi64(*TWEAK, _mm512_loadu_si512(&xts_tweak_permq[3*8]), *NEXT_TWEAK); + } + } +} + +static void sm4_xts_mask_kernel_mb16(__m512i* NEXT_TWEAK, const __m512i* p_rk, __m512i loc_len32, + const int8u** loc_inp, int8u** loc_out, + __mmask16 mb_mask, const int operation) +{ + __m512i TMP[20]; + const __m512i z_poly = _mm512_loadu_si512(xts_poly); + const __m512i z_partial_block_mask = _mm512_loadu_si512(xts_partial_block_mask); + const __m512i z_full_block_mask = _mm512_loadu_si512(xts_full_block_mask); + const __m512i z_shuf_mask = _mm512_loadu_si512(xts_shuf_mask); + /* Length in bytes of partial blocks for all buffers */ + const __m512i partial_len32 = _mm512_and_si512(loc_len32, z_partial_block_mask); + /* Length in bytes of full blocks for all buffers */ + loc_len32 = _mm512_and_si512(loc_len32, z_full_block_mask); + + __mmask16 ge_64_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len32, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + __mmask8 ge_64_mask_0_7 = (__mmask8) ge_64_mask; + __mmask8 ge_64_mask_8_15 = (__mmask8) _kshiftri_mask16(ge_64_mask, 8); + /* Expand 32-bit lengths to 64-bit lengths for 16 buffers */ + const __mmask16 expand_mask = _cvtu32_mask16(0x5555); + __m512i remain_len64_0_7 = _mm512_maskz_permutexvar_epi32(expand_mask, _mm512_loadu_si512(xts_dw0_7_to_qw_idx), loc_len32); + __m512i remain_len64_8_15 = _mm512_maskz_permutexvar_epi32(expand_mask, _mm512_loadu_si512(xts_dw8_15_to_qw_idx), loc_len32); + __m512i processed_len64_0_7; + __m512i processed_len64_8_15; + __m512i TWEAK[SM4_LINES]; + __m512i num_remain_full_blocks = _mm512_srli_epi32(loc_len32, 4); + /* Calculate bitmask of buffers with at least one full block */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len32, _mm512_set1_epi32(0), _MM_CMPINT_NLE); + + /* + * While there is at least one full block in any of the buffer, keep encrypting + * (this loop only handles full blocks, but some buffers will have here + * less than 4 full blocks) + */ + while (tmp_mask) { + /* Mask for data loading */ + __mmask64 stream_mask[16]; + int i; + + int* p_loc_len32 = (int*)&loc_len32; + int* p_num_remain_full_blocks = (int*)&num_remain_full_blocks; + int* p_partial_block = (int*)&partial_len32; + + /* Generate tweaks for next rounds */ + for (i = 0; i < SM4_LINES; i++) { + TWEAK[i] = NEXT_TWEAK[i]; + /* + * If there are at least 4 more full blocks to process, + * at least one more tweak will be needed (for more full blocks or + * for a last partial block) + */ + if (p_num_remain_full_blocks[i] >= 4) + generate_next_4_tweaks(&TWEAK[i], &NEXT_TWEAK[i], z_shuf_mask, z_poly, NEXT_TWEAKS); + + /* If there is a partial block, tweaks need to be rearranged depending on cipher direction */ + if ((p_partial_block[i] > 0) & (p_num_remain_full_blocks[i] <= 4)) + prepare_last_tweaks(&TWEAK[i], &NEXT_TWEAK[i], operation, p_num_remain_full_blocks[i]); + } + + num_remain_full_blocks = _mm512_sub_epi32(num_remain_full_blocks, _mm512_set1_epi32(4)); + + /* + * XOR plaintext from each lane with the 4 tweaks and transpose to prepare for encryption. + * Since some buffers will have less than 4 full blocks, + * a bitmask is required to load less than 64 bytes (stream_mask) + */ + UPDATE_STREAM_MASK_64(stream_mask[0], p_loc_len32) + TMP[0] = _mm512_xor_si512(TWEAK[0], _mm512_maskz_loadu_epi8(stream_mask[0], loc_inp[0])); + UPDATE_STREAM_MASK_64(stream_mask[1], p_loc_len32) + TMP[1] = _mm512_xor_si512(TWEAK[1], _mm512_maskz_loadu_epi8(stream_mask[1], loc_inp[1])); + UPDATE_STREAM_MASK_64(stream_mask[2], p_loc_len32) + TMP[2] = _mm512_xor_si512(TWEAK[2], _mm512_maskz_loadu_epi8(stream_mask[2], loc_inp[2])); + UPDATE_STREAM_MASK_64(stream_mask[3], p_loc_len32) + TMP[3] = _mm512_xor_si512(TWEAK[3], _mm512_maskz_loadu_epi8(stream_mask[3], loc_inp[3])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + UPDATE_STREAM_MASK_64(stream_mask[4], p_loc_len32) + TMP[0] = _mm512_xor_si512(TWEAK[4], _mm512_maskz_loadu_epi8(stream_mask[4], loc_inp[4])); + UPDATE_STREAM_MASK_64(stream_mask[5], p_loc_len32) + TMP[1] = _mm512_xor_si512(TWEAK[5], _mm512_maskz_loadu_epi8(stream_mask[5], loc_inp[5])); + UPDATE_STREAM_MASK_64(stream_mask[6], p_loc_len32) + TMP[2] = _mm512_xor_si512(TWEAK[6], _mm512_maskz_loadu_epi8(stream_mask[6], loc_inp[6])); + UPDATE_STREAM_MASK_64(stream_mask[7], p_loc_len32) + TMP[3] = _mm512_xor_si512(TWEAK[7], _mm512_maskz_loadu_epi8(stream_mask[7], loc_inp[7])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + UPDATE_STREAM_MASK_64(stream_mask[8], p_loc_len32) + TMP[0] = _mm512_xor_si512(TWEAK[8], _mm512_maskz_loadu_epi8(stream_mask[8], loc_inp[8])); + UPDATE_STREAM_MASK_64(stream_mask[9], p_loc_len32) + TMP[1] = _mm512_xor_si512(TWEAK[9], _mm512_maskz_loadu_epi8(stream_mask[9], loc_inp[9])); + UPDATE_STREAM_MASK_64(stream_mask[10], p_loc_len32) + TMP[2] = _mm512_xor_si512(TWEAK[10], _mm512_maskz_loadu_epi8(stream_mask[10], loc_inp[10])); + UPDATE_STREAM_MASK_64(stream_mask[11], p_loc_len32) + TMP[3] = _mm512_xor_si512(TWEAK[11], _mm512_maskz_loadu_epi8(stream_mask[11], loc_inp[11])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + UPDATE_STREAM_MASK_64(stream_mask[12], p_loc_len32) + TMP[0] = _mm512_xor_si512(TWEAK[12], _mm512_maskz_loadu_epi8(stream_mask[12], loc_inp[12])); + UPDATE_STREAM_MASK_64(stream_mask[13], p_loc_len32) + TMP[1] = _mm512_xor_si512(TWEAK[13], _mm512_maskz_loadu_epi8(stream_mask[13], loc_inp[13])); + UPDATE_STREAM_MASK_64(stream_mask[14], p_loc_len32) + TMP[2] = _mm512_xor_si512(TWEAK[14], _mm512_maskz_loadu_epi8(stream_mask[14], loc_inp[14])); + UPDATE_STREAM_MASK_64(stream_mask[15], p_loc_len32) + TMP[3] = _mm512_xor_si512(TWEAK[15], _mm512_maskz_loadu_epi8(stream_mask[15], loc_inp[15])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk, operation); + p_rk -= operation*SM4_ROUNDS; + + /* Transpose, XOR with the tweaks again and write data out */ + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi8((__m512i*)loc_out[0], stream_mask[0], _mm512_xor_si512(TMP[0], TWEAK[0])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[1], stream_mask[1], _mm512_xor_si512(TMP[1], TWEAK[1])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[2], stream_mask[2], _mm512_xor_si512(TMP[2], TWEAK[2])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[3], stream_mask[3], _mm512_xor_si512(TMP[3], TWEAK[3])); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi8((__m512i*)loc_out[4], stream_mask[4], _mm512_xor_si512(TMP[0], TWEAK[4])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[5], stream_mask[5], _mm512_xor_si512(TMP[1], TWEAK[5])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[6], stream_mask[6], _mm512_xor_si512(TMP[2], TWEAK[6])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[7], stream_mask[7], _mm512_xor_si512(TMP[3], TWEAK[7])); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi8((__m512i*)loc_out[8], stream_mask[8], _mm512_xor_si512(TMP[0], TWEAK[8])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[9], stream_mask[9], _mm512_xor_si512(TMP[1], TWEAK[9])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[10], stream_mask[10], _mm512_xor_si512(TMP[2],TWEAK[10])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[11], stream_mask[11], _mm512_xor_si512(TMP[3],TWEAK[11])); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_mask_storeu_epi8((__m512i*)loc_out[12], stream_mask[12], _mm512_xor_si512(TMP[0], TWEAK[12])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[13], stream_mask[13], _mm512_xor_si512(TMP[1], TWEAK[13])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[14], stream_mask[14], _mm512_xor_si512(TMP[2], TWEAK[14])); + _mm512_mask_storeu_epi8((__m512i*)loc_out[15], stream_mask[15], _mm512_xor_si512(TMP[3], TWEAK[15])); + + /* Update input/output pointers to data */ + processed_len64_0_7 = _mm512_mask_blend_epi64(ge_64_mask_0_7, remain_len64_0_7, _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + processed_len64_8_15 = _mm512_mask_blend_epi64(ge_64_mask_8_15, remain_len64_8_15, _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), processed_len64_0_7); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), processed_len64_8_15); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), processed_len64_0_7); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), processed_len64_8_15); + + /* Update number of blocks left and processing mask */ + remain_len64_0_7 = _mm512_sub_epi64(remain_len64_0_7, processed_len64_0_7); + remain_len64_8_15 = _mm512_sub_epi64(remain_len64_8_15, processed_len64_8_15); + loc_len32 = _mm512_sub_epi32(loc_len32, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len32, _mm512_set1_epi32(0), _MM_CMPINT_NLE); + ge_64_mask_0_7 = _mm512_cmp_epi64_mask(remain_len64_0_7, _mm512_set1_epi64(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + ge_64_mask_8_15 = _mm512_cmp_epi64_mask(remain_len64_8_15, _mm512_set1_epi64(4 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + } + + /* At this stage, all buffers have at most 15 bytes (a partial block) */ + + /* Calculate bitmask of buffers with a partial block */ + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, partial_len32, _mm512_set1_epi32(0), _MM_CMPINT_NLE); + + if (tmp_mask) { + /* Encrypt last plaintext using bytes from previous ciphertext block */ + __mmask64 stream_mask[16]; + int* p_loc_len32 = (int*)&partial_len32; + __m128i XTMP[16]; + int i; + + for (i = 0; i < SM4_LINES; i++) { + /* Get right tweak (position tweak in last 16 bytes of ZMM register) */ + UPDATE_STREAM_MASK_64(stream_mask[i], p_loc_len32); + /* Read final bytes of input partial block */ + XTMP[i] = _mm_maskz_loadu_epi8((__mmask16)stream_mask[i], loc_inp[i]); + /* + * Read last bytes of previous output block to form 16 bytes + * (only if there is a partial block at the end of the buffer) + */ + if (stream_mask[i] == 0) + continue; + __m128i XOUT = _mm_maskz_loadu_epi8((__mmask16)~stream_mask[i], (loc_out[i] - 16)); + XTMP[i] = _mm_or_si128(XTMP[i], XOUT); + /* Initial XOR of new constructed input with tweak */ + XTMP[i] = _mm_xor_si128(XTMP[i], _mm512_castsi512_si128(NEXT_TWEAK[i])); + } + + /* Encrypt final block from all lanes, compressing the 16 XMMs into 4 ZMMs */ + TRANSPOSE_16x4_I32_XMM_EPI32(&TMP[0], &TMP[1], &TMP[2], &TMP[3], XTMP); + for (i = 0; i < SM4_ROUNDS; i += 4, p_rk += 4*operation) + SM4_FOUR_ROUNDS(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], p_rk, operation); + + p_rk -= operation*SM4_ROUNDS; + + /* Spread out the 4 ZMMs into 16 XMMs */ + TRANSPOSE_4x16_I32_XMM_EPI32(&TMP[0], &TMP[1], &TMP[2], &TMP[3], XTMP); + for (i = 0; i < SM4_LINES; i++) { + /* Skip the buffer if there is no partial block left */ + if (stream_mask[i] == 0) + continue; + /* + * Final XOR of output with tweak (it will be always + * in the beginning of NEXT_TWEAK, hence the cast) + */ + XTMP[i] = _mm_xor_si128(XTMP[i], _mm512_castsi512_si128(NEXT_TWEAK[i])); + /* Write first bytes of previous output block as the output of the partial block */ + __m128i XOUT = _mm_maskz_loadu_epi8((__mmask16)stream_mask[i], (loc_out[i] - 16)); + _mm_mask_storeu_epi8(loc_out[i], (__mmask16)stream_mask[i], XOUT); + /* Write last output as the output of the previous block */ + _mm_storeu_si128((__m128i*)(loc_out[i] - 16), XTMP[i]); + } + } + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); +} + +void sm4_xts_kernel_mb16(int8u* pa_out[SM4_LINES], const int8u* pa_inp[SM4_LINES], const int len[SM4_LINES], + const int32u* key_sched1[SM4_ROUNDS], const int32u* key_sched2[SM4_ROUNDS], + const int8u* pa_tweak[SM4_LINES], __mmask16 mb_mask, const int operation) +{ + __ALIGN64 const int8u* loc_inp[SM4_LINES]; + __ALIGN64 int8u* loc_out[SM4_LINES]; + + /* Create the local copy of the input data length in bytes and set it to zero for non-valid buffers */ + __m512i loc_len; + loc_len = _mm512_loadu_si512(len); + loc_len = _mm512_mask_set1_epi32(loc_len, ~mb_mask, 0); + + /* Local copies of the pointers to input and otput buffers */ + _mm512_storeu_si512((void*)loc_inp, _mm512_loadu_si512(pa_inp)); + _mm512_storeu_si512((void*)(loc_inp + 8), _mm512_loadu_si512(pa_inp + 8)); + + _mm512_storeu_si512(loc_out, _mm512_loadu_si512(pa_out)); + _mm512_storeu_si512(loc_out + 8, _mm512_loadu_si512(pa_out + 8)); + + /* Depending on the operation(enc or dec): sign allows to go up and down on the key schedule + * p_rk set to the beginning or to the end of the key schedule */ + const __m512i* p_rk1 = (operation == SM4_ENC) ? (const __m512i*)key_sched1 : ((const __m512i*)key_sched1 + (SM4_ROUNDS - 1)); + /* Pointer p_rk2 is set to the beginning of the key schedule, + * as it always encrypts the tweak, regardless the direction */ + const __m512i* p_rk2 = (const __m512i*)key_sched2; + + /* TMP[] - temporary buffer for processing */ + /* TWEAK - tweak values for current blocks (4 blocks per buffer) */ + /* NEXT_TWEAK - tweak values for following blocks (4 blocks per buffer) */ + /* inital_tweak - first tweak for all buffers */ + __m512i TMP[20]; + __m512i TWEAK[SM4_LINES]; + __m512i NEXT_TWEAK[SM4_LINES]; + __m128i initial_tweak[SM4_LINES]; + int i; + + const __m512i z_poly = _mm512_loadu_si512(xts_poly); + const __m512i z_shuf_mask = _mm512_loadu_si512(xts_shuf_mask); + + /* Encrypt initial tweak */ + TRANSPOSE_16x4_I32_EPI32(&TMP[0], &TMP[1], &TMP[2], &TMP[3], pa_tweak, mb_mask); + + for (i = 0; i < SM4_ROUNDS; i += 4, p_rk2 += 4) + SM4_FOUR_ROUNDS(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], p_rk2, SM4_ENC); + + p_rk2 -= SM4_ROUNDS; + + TRANSPOSE_4x16_I32_O128_EPI32(&TMP[0], &TMP[1], &TMP[2], &TMP[3], initial_tweak, mb_mask); + + /* Load TWEAK value from valid buffers and generate first 4 values */ + for (i = 0; i < SM4_LINES; i++) { + TWEAK[i] = _mm512_broadcast_i64x2(initial_tweak[i]); + generate_next_4_tweaks(&TWEAK[i], &NEXT_TWEAK[i], z_shuf_mask, z_poly, FIRST_TWEAKS); + } + + /* + * Generate the mask to process 4 full blocks from each buffer. + * Less than 5 full blocks requires sm4_xts_mask_kernel_mb16 to handle it, + * as it is the function that can handle partial blocks. + */ + __mmask16 tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_set1_epi32(5 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + + /* Go to this loop if all 16 buffers contain at least 5 full blocks each */ + while (tmp_mask == 0xFFFF) { + for (i = 0; i < SM4_LINES; i++) { + TWEAK[i] = NEXT_TWEAK[i]; + + /* Update tweaks for next rounds */ + generate_next_4_tweaks(&TWEAK[i], &NEXT_TWEAK[i], z_shuf_mask, z_poly, NEXT_TWEAKS); + } + + /* XOR plaintext from each lane with the 4 tweaks and transpose to prepare for encryption */ + TMP[0] = _mm512_xor_si512(TWEAK[0], _mm512_loadu_si512(loc_inp[0])); + TMP[1] = _mm512_xor_si512(TWEAK[1], _mm512_loadu_si512(loc_inp[1])); + TMP[2] = _mm512_xor_si512(TWEAK[2], _mm512_loadu_si512(loc_inp[2])); + TMP[3] = _mm512_xor_si512(TWEAK[3], _mm512_loadu_si512(loc_inp[3])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_xor_si512(TWEAK[4], _mm512_loadu_si512(loc_inp[4])); + TMP[1] = _mm512_xor_si512(TWEAK[5], _mm512_loadu_si512(loc_inp[5])); + TMP[2] = _mm512_xor_si512(TWEAK[6], _mm512_loadu_si512(loc_inp[6])); + TMP[3] = _mm512_xor_si512(TWEAK[7], _mm512_loadu_si512(loc_inp[7])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_xor_si512(TWEAK[8], _mm512_loadu_si512(loc_inp[8])); + TMP[1] = _mm512_xor_si512(TWEAK[9], _mm512_loadu_si512(loc_inp[9])); + TMP[2] = _mm512_xor_si512(TWEAK[10], _mm512_loadu_si512(loc_inp[10])); + TMP[3] = _mm512_xor_si512(TWEAK[11], _mm512_loadu_si512(loc_inp[11])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_xor_si512(TWEAK[12], _mm512_loadu_si512(loc_inp[12])); + TMP[1] = _mm512_xor_si512(TWEAK[13], _mm512_loadu_si512(loc_inp[13])); + TMP[2] = _mm512_xor_si512(TWEAK[14], _mm512_loadu_si512(loc_inp[14])); + TMP[3] = _mm512_xor_si512(TWEAK[15], _mm512_loadu_si512(loc_inp[15])); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + SM4_KERNEL(TMP, p_rk1, operation); + p_rk1 -= operation*SM4_ROUNDS; + + /* Transpose, XOR with the tweaks again and write data out */ + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[0], _mm512_xor_si512(TMP[0], TWEAK[0])); + _mm512_storeu_si512((__m512i*)loc_out[1], _mm512_xor_si512(TMP[1], TWEAK[1])); + _mm512_storeu_si512((__m512i*)loc_out[2], _mm512_xor_si512(TMP[2], TWEAK[2])); + _mm512_storeu_si512((__m512i*)loc_out[3], _mm512_xor_si512(TMP[3], TWEAK[3])); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[4], _mm512_xor_si512(TMP[0], TWEAK[4])); + _mm512_storeu_si512((__m512i*)loc_out[5], _mm512_xor_si512(TMP[1], TWEAK[5])); + _mm512_storeu_si512((__m512i*)loc_out[6], _mm512_xor_si512(TMP[2], TWEAK[6])); + _mm512_storeu_si512((__m512i*)loc_out[7], _mm512_xor_si512(TMP[3], TWEAK[7])); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[8], _mm512_xor_si512(TMP[0], TWEAK[8])); + _mm512_storeu_si512((__m512i*)loc_out[9], _mm512_xor_si512(TMP[1], TWEAK[9])); + _mm512_storeu_si512((__m512i*)loc_out[10], _mm512_xor_si512(TMP[2], TWEAK[10])); + _mm512_storeu_si512((__m512i*)loc_out[11], _mm512_xor_si512(TMP[3], TWEAK[11])); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)loc_out[13], _mm512_xor_si512(TMP[1], TWEAK[13])); + _mm512_storeu_si512((__m512i*)loc_out[13], _mm512_xor_si512(TMP[1], TWEAK[13])); + _mm512_storeu_si512((__m512i*)loc_out[14], _mm512_xor_si512(TMP[2], TWEAK[14])); + _mm512_storeu_si512((__m512i*)loc_out[15], _mm512_xor_si512(TMP[3], TWEAK[15])); + + /* Update input/output pointers to data */ + M512(loc_inp) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_inp + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_inp + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + M512(loc_out) = _mm512_add_epi64(_mm512_loadu_si512(loc_out), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + M512(loc_out + 8) = _mm512_add_epi64(_mm512_loadu_si512(loc_out + 8), _mm512_set1_epi64(4 * SM4_BLOCK_SIZE)); + + /* Update number of blocks left and processing mask */ + loc_len = _mm512_sub_epi32(loc_len, _mm512_set1_epi32(4 * SM4_BLOCK_SIZE)); + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_set1_epi32(5 * SM4_BLOCK_SIZE), _MM_CMPINT_NLT); + } + + /* Check if we have any data left on any of the buffers */ + tmp_mask = _mm512_mask_cmp_epi32_mask(mb_mask, loc_len, _mm512_setzero_si512(), _MM_CMPINT_NLE); + /* + * At this point, at least one buffer has less than 5 full blocks, + * so dealing with a partial block might be needed. + */ + if (tmp_mask) + sm4_xts_mask_kernel_mb16(NEXT_TWEAK, p_rk1, loc_len, loc_inp, loc_out, mb_mask, operation); + + /* clear local copy of sensitive data */ + zero_mb8((int64u(*)[8])TMP, sizeof(TMP) / sizeof(TMP[0])); + zero_mb8((int64u(*)[8])TWEAK, sizeof(TWEAK) / sizeof(TWEAK[0])); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/x25519/ifma_x25519.c b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/x25519/ifma_x25519.c new file mode 100644 index 000000000..d837e1bd8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/crypto_mb/src/x25519/ifma_x25519.c @@ -0,0 +1,1713 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include + +#include +#include +#include +#include + +#ifndef __GNUC__ +#pragma warning(disable:4013) +#endif + +#define MASK47 ((1ULL << (255 - 52 * 4)) - 1) + +__ALIGN64 static const int64u MASK47_[8] = {MASK47, MASK47, MASK47, MASK47, + MASK47, MASK47, MASK47, MASK47}; +__ALIGN64 static const int64u MOD_2_255_[8] = {19, 19, 19, 19, 19, 19, 19, 19}; +__ALIGN64 static const int64u MOD_2_260_[8] = {19*32, 19*32, 19*32, 19*32, + 19*32, 19*32, 19*32, 19*32}; +#define MASK_47 loadu64(MASK47_) +#define MOD_2_255 loadu64(MOD_2_255_) +#define MOD_2_260 loadu64(MOD_2_260_) + +#define ROUND_MUL_SRC(I, J, S_LO, R_LO, S_HI, R_HI) \ + R_LO = fma52lo(S_LO, va[I], vb[J]); \ + R_HI = fma52hi(S_HI, va[I], vb[J]); + +#define ROUND_MUL(I, J, M0, M1) \ + ROUND_MUL_SRC(I, J, M0, M0, M1, M1) + +#define REDUCE_ROUND(R0, R1, R5) \ + r##R0 = fma52lo(r##R0, r##R5, MOD_2_260); \ + r##R1 = fma52lo( fma52hi(r##R1, r##R5, MOD_2_260), \ + srli64(r##R5, 52), MOD_2_260); + +#define NORM(I, J) \ + r##J = add64(r##J, srli64(r##I, 52)); \ + r##I = and64_const(r##I, (1ULL << 52) - 1); + +//////////////////////////////////////////////////////////// + +__INLINE void ed25519_mul(U64 out[], const U64 a[], const U64 b[]) { + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + + U64 *va = (U64*) a; + U64 *vb = (U64*) b; + U64 *vr = (U64*) out; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + // Full multiplication + ROUND_MUL(4, 4, r8, r9) + + ROUND_MUL(3, 0, r3, r4) + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(2, 1, r3, r4) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(3, 1, r4, r5) + ROUND_MUL(4, 0, r4, r5) + + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(2, 3, r5, r6) + ROUND_MUL(3, 2, r5, r6) + ROUND_MUL(4, 1, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 2, r6, r7) + + ROUND_MUL(0, 0, r0, r1) + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(1, 0, r1, r2) + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 0, r2, r3) + ROUND_MUL(3, 4, r7, r8) + ROUND_MUL(4, 3, r7, r8) + + r4 = fma52lo(r4, r9, MOD_2_260); + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + r4 = and64(r4, MASK_47); + + REDUCE_ROUND(0, 1, 5); + REDUCE_ROUND(1, 2, 6); + REDUCE_ROUND(2, 3, 7); + REDUCE_ROUND(3, 4, 8); + + // Normalize result + NORM(0,1) + NORM(1,2) + NORM(2,3) + NORM(3,4) + + storeu64(&vr[0], r0); + storeu64(&vr[1], r1); + storeu64(&vr[2], r2); + storeu64(&vr[3], r3); + storeu64(&vr[4], r4); +} + +/* SQR +c=0 (0,0) +c=1 (0,1) +c=2 (0,2) (1,1) +c=3 (0,3) (1,2) +c=4 (0,4) (1,3) (2,2) +c=5 (1,4) (2,3) +c=6 (2,4) (3,3) +c=7 (3,4) +c=8 (4,4) +*/ + +__INLINE void ed25519_sqr(U64 out[], const U64 a[]) { + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + + U64 *va = (U64*) a; + U64 *vb = (U64*) a; + U64 *vr = (U64*) out; + + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + // Square + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(3, 4, r7, r8) + + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(2, 3, r5, r6) + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + r4 = add64(r4, r4); + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + + ROUND_MUL(0, 0, r0, r1) + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 4, r8, r9) + + // Reduce r4 upper bits + r4 = fma52lo(r4, r9, MOD_2_260); + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + r4 = and64(r4, MASK_47); + + REDUCE_ROUND(0, 1, 5); + REDUCE_ROUND(1, 2, 6); + REDUCE_ROUND(2, 3, 7); + REDUCE_ROUND(3, 4, 8); + + // Normalize result + NORM(0,1) + NORM(1,2) + NORM(2,3) + NORM(3,4) + + storeu64(&vr[0], r0); + storeu64(&vr[1], r1); + storeu64(&vr[2], r2); + storeu64(&vr[3], r3); + storeu64(&vr[4], r4); +} + +#define ROUND_MUL_SRC_A(I, J, S_LO, R_LO, S_HI, R_HI) \ + R_LO = fma52lo(S_LO, a##I, a##J); \ + R_HI = fma52hi(S_HI, a##I, a##J); + +#define ROUND_MUL_A(I, J, M0, M1) \ + ROUND_MUL_SRC_A(I, J, M0, M0, M1, M1) + +#define NORM(I, J) \ + r##J = add64(r##J, srli64(r##I, 52)); \ + r##I = and64_const(r##I, (1ULL << 52) - 1); + + +static void MB_FUNC_NAME(ed25519_sqr_latency_)(U64 out[], const U64 a[], int count) { + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + U64 a0, a1, a2, a3, a4; + U64 r4_1; + int i; + + U64 *vr = (U64*) out; + + a0 = a[0]; + a1 = a[1]; + a2 = a[2]; + a3 = a[3]; + a4 = a[4]; + for (i = 0; i < count; ++i) + { + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + r4_1 = get_zero64(); + + // Square + ROUND_MUL_A(0, 1, r1, r2) + ROUND_MUL_A(0, 2, r2, r3) + ROUND_MUL_A(0, 3, r3, r4_1) + ROUND_MUL_A(0, 4, r4_1, r5) + ROUND_MUL_A(1, 4, r5, r6) + ROUND_MUL_A(2, 4, r6, r7) + ROUND_MUL_A(3, 4, r7, r8) + + ROUND_MUL_A(1, 2, r3, r4) + ROUND_MUL_A(1, 3, r4, r5) + ROUND_MUL_A(2, 3, r5, r6) + + r1 = add64(r1, r1); + r2 = add64(r2, r2); + r3 = add64(r3, r3); + + r4 = add64(r4, r4_1); + r4 = add64(r4, r4); + + r5 = add64(r5, r5); + r6 = add64(r6, r6); + r7 = add64(r7, r7); + r8 = add64(r8, r8); + + ROUND_MUL_A(0, 0, r0, r1) + ROUND_MUL_A(1, 1, r2, r3) + ROUND_MUL_A(2, 2, r4, r5) + ROUND_MUL_A(3, 3, r6, r7) + ROUND_MUL_A(4, 4, r8, r9) + + r4 = fma52lo(r4, r9, MOD_2_260); + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + r4 = and64(r4, MASK_47); + + REDUCE_ROUND(0, 1, 5); + REDUCE_ROUND(1, 2, 6); + REDUCE_ROUND(2, 3, 7); + REDUCE_ROUND(3, 4, 8); + + // Normalize result + NORM(0,1) + NORM(1,2) + NORM(2,3) + NORM(3,4) + + a0 = r0; + a1 = r1; + a2 = r2; + a3 = r3; + a4 = r4; + } + + storeu64(&vr[0], r0); + storeu64(&vr[1], r1); + storeu64(&vr[2], r2); + storeu64(&vr[3], r3); + storeu64(&vr[4], r4); +} + +#define MASK_R4 ((1ULL << (255 - 52 * 4)) - 1) +static const int64u VMASK_R4[8] = {MASK_R4, MASK_R4, MASK_R4, MASK_R4, + MASK_R4, MASK_R4, MASK_R4, MASK_R4}; + +#define MASK52 ((1ULL << 52) - 1) +static const int64u VMASK52[8] = {MASK52, MASK52, MASK52, MASK52, + MASK52, MASK52, MASK52, MASK52}; + +#define REDUCE_ROUND_(R, R0, R1, R5) \ + R##R0 = fma52lo(R##R0, R##R5, MOD_2_260); \ + R##R1 = fma52lo( fma52hi(R##R1, R##R5, MOD_2_260), \ + srli64(R##R5, 52), MOD_2_260); + +#define NORM_(R, I, J) \ + R##J = add64(R##J, srli64(R##I, 52)); \ + R##I = and64(R##I, loadu64(VMASK52)); + +#define REDUCE_R4_N_R9(R) \ + R##4 = fma52lo(R##4, R##9, MOD_2_260); \ + R##0 = fma52lo(R##0, srli64(R##4, 47), MOD_2_255); \ + R##4 = and64(R##4, loadu64(VMASK_R4)); + +__INLINE void ed25519_mul_dual(U64 out0[], U64 out1[], + const U64 a0[], const U64 b0[], + const U64 a1[], const U64 b1[]) { + + U64 r00, r01, r02, r03, r04, r05, r06, r07, r08, r09; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + + U64 *vr0 = (U64*) out0; + U64 *vr1 = (U64*) out1; + + r00 = r01 = r02 = r03 = r04 = r05 = r06 = r07 = r08 = r09 = get_zero64(); + r10 = r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19 = get_zero64(); + + // Full multiplication + U64 *va = (U64*) a0; + U64 *vb = (U64*) b0; + ROUND_MUL(4, 4, r08, r09) + ROUND_MUL(3, 0, r03, r04) + ROUND_MUL(1, 2, r03, r04) + ROUND_MUL(0, 3, r03, r04) + ROUND_MUL(2, 1, r03, r04) + ROUND_MUL(2, 2, r04, r05) + ROUND_MUL(0, 4, r04, r05) + ROUND_MUL(1, 3, r04, r05) + ROUND_MUL(3, 1, r04, r05) + ROUND_MUL(4, 0, r04, r05) + ROUND_MUL(1, 4, r05, r06) + ROUND_MUL(2, 3, r05, r06) + ROUND_MUL(3, 2, r05, r06) + ROUND_MUL(4, 1, r05, r06) + ROUND_MUL(2, 4, r06, r07) + ROUND_MUL(3, 3, r06, r07) + ROUND_MUL(4, 2, r06, r07) + ROUND_MUL(0, 0, r00, r01) + ROUND_MUL(0, 1, r01, r02) + ROUND_MUL(0, 2, r02, r03) + ROUND_MUL(1, 0, r01, r02) + ROUND_MUL(1, 1, r02, r03) + ROUND_MUL(2, 0, r02, r03) + ROUND_MUL(3, 4, r07, r08) + ROUND_MUL(4, 3, r07, r08) + + va = (U64*) a1; + vb = (U64*) b1; + ROUND_MUL(4, 4, r18, r19) + ROUND_MUL(3, 0, r13, r14) + ROUND_MUL(1, 2, r13, r14) + ROUND_MUL(0, 3, r13, r14) + ROUND_MUL(2, 1, r13, r14) + ROUND_MUL(2, 2, r14, r15) + ROUND_MUL(0, 4, r14, r15) + ROUND_MUL(1, 3, r14, r15) + ROUND_MUL(3, 1, r14, r15) + ROUND_MUL(4, 0, r14, r15) + ROUND_MUL(1, 4, r15, r16) + ROUND_MUL(2, 3, r15, r16) + ROUND_MUL(3, 2, r15, r16) + ROUND_MUL(4, 1, r15, r16) + ROUND_MUL(2, 4, r16, r17) + ROUND_MUL(3, 3, r16, r17) + ROUND_MUL(4, 2, r16, r17) + ROUND_MUL(0, 0, r10, r11) + ROUND_MUL(0, 1, r11, r12) + ROUND_MUL(0, 2, r12, r13) + ROUND_MUL(1, 0, r11, r12) + ROUND_MUL(1, 1, r12, r13) + ROUND_MUL(2, 0, r12, r13) + ROUND_MUL(3, 4, r17, r18) + ROUND_MUL(4, 3, r17, r18) + + REDUCE_R4_N_R9(r0) + REDUCE_R4_N_R9(r1) + + REDUCE_ROUND_(r0, 0, 1, 5); + REDUCE_ROUND_(r0, 1, 2, 6); + REDUCE_ROUND_(r0, 2, 3, 7); + REDUCE_ROUND_(r0, 3, 4, 8); + + REDUCE_ROUND_(r1, 0, 1, 5); + REDUCE_ROUND_(r1, 1, 2, 6); + REDUCE_ROUND_(r1, 2, 3, 7); + REDUCE_ROUND_(r1, 3, 4, 8); + + // Normalize result + NORM_(r0, 0,1) + NORM_(r0, 1,2) + NORM_(r0, 2,3) + NORM_(r0, 3,4) + + NORM_(r1, 0,1) + NORM_(r1, 1,2) + NORM_(r1, 2,3) + NORM_(r1, 3,4) + + storeu64(&vr0[0], r00); + storeu64(&vr0[1], r01); + storeu64(&vr0[2], r02); + storeu64(&vr0[3], r03); + storeu64(&vr0[4], r04); + + storeu64(&vr1[0], r10); + storeu64(&vr1[1], r11); + storeu64(&vr1[2], r12); + storeu64(&vr1[3], r13); + storeu64(&vr1[4], r14); +} + +__INLINE void ed25519_sqr_dual(U64 out0[], U64 out1[], + const U64 a0[], const U64 a1[]) { + + U64 r00, r01, r02, r03, r04, r05, r06, r07, r08, r09; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + + U64 *vr0 = (U64*) out0; + U64 *vr1 = (U64*) out1; + + r00 = r01 = r02 = r03 = r04 = r05 = r06 = r07 = r08 = r09 = get_zero64(); + r10 = r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19 = get_zero64(); + + // Square + U64 *va = (U64*) a0; + U64 *vb = (U64*) a0; + ROUND_MUL(0, 1, r01, r02) + ROUND_MUL(0, 2, r02, r03) + ROUND_MUL(0, 3, r03, r04) + ROUND_MUL(0, 4, r04, r05) + ROUND_MUL(1, 4, r05, r06) + ROUND_MUL(2, 4, r06, r07) + ROUND_MUL(3, 4, r07, r08) + ROUND_MUL(1, 2, r03, r04) + ROUND_MUL(1, 3, r04, r05) + ROUND_MUL(2, 3, r05, r06) + + r01 = add64(r01, r01); + r02 = add64(r02, r02); + r03 = add64(r03, r03); + r04 = add64(r04, r04); + r05 = add64(r05, r05); + r06 = add64(r06, r06); + r07 = add64(r07, r07); + r08 = add64(r08, r08); + + ROUND_MUL(0, 0, r00, r01) + ROUND_MUL(1, 1, r02, r03) + ROUND_MUL(2, 2, r04, r05) + ROUND_MUL(3, 3, r06, r07) + ROUND_MUL(4, 4, r08, r09) + + va = (U64*) a1; + vb = (U64*) a1; + ROUND_MUL(0, 1, r11, r12) + ROUND_MUL(0, 2, r12, r13) + ROUND_MUL(0, 3, r13, r14) + ROUND_MUL(0, 4, r14, r15) + ROUND_MUL(1, 4, r15, r16) + ROUND_MUL(2, 4, r16, r17) + ROUND_MUL(3, 4, r17, r18) + ROUND_MUL(1, 2, r13, r14) + ROUND_MUL(1, 3, r14, r15) + ROUND_MUL(2, 3, r15, r16) + + r11 = add64(r11, r11); + r12 = add64(r12, r12); + r13 = add64(r13, r13); + r14 = add64(r14, r14); + r15 = add64(r15, r15); + r16 = add64(r16, r16); + r17 = add64(r17, r17); + r18 = add64(r18, r18); + + ROUND_MUL(0, 0, r10, r11) + ROUND_MUL(1, 1, r12, r13) + ROUND_MUL(2, 2, r14, r15) + ROUND_MUL(3, 3, r16, r17) + ROUND_MUL(4, 4, r18, r19) + + REDUCE_R4_N_R9(r0) + REDUCE_R4_N_R9(r1) + + REDUCE_ROUND_(r0, 0, 1, 5); + REDUCE_ROUND_(r0, 1, 2, 6); + REDUCE_ROUND_(r0, 2, 3, 7); + REDUCE_ROUND_(r0, 3, 4, 8); + + REDUCE_ROUND_(r1, 0, 1, 5); + REDUCE_ROUND_(r1, 1, 2, 6); + REDUCE_ROUND_(r1, 2, 3, 7); + REDUCE_ROUND_(r1, 3, 4, 8); + + // Normalize result + NORM_(r0, 0,1) + NORM_(r0, 1,2) + NORM_(r0, 2,3) + NORM_(r0, 3,4) + + NORM_(r1, 0,1) + NORM_(r1, 1,2) + NORM_(r1, 2,3) + NORM_(r1, 3,4) + + storeu64(&vr0[0], r00); + storeu64(&vr0[1], r01); + storeu64(&vr0[2], r02); + storeu64(&vr0[3], r03); + storeu64(&vr0[4], r04); + + storeu64(&vr1[0], r10); + storeu64(&vr1[1], r11); + storeu64(&vr1[2], r12); + storeu64(&vr1[3], r13); + storeu64(&vr1[4], r14); +} +////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////// + +__INLINE void fe52mb8_set(U64 out[], int64u value) +{ + storeu64(&out[0], set64((long long)value)); + storeu64(&out[1], get_zero64()); + storeu64(&out[2], get_zero64()); + storeu64(&out[3], get_zero64()); + storeu64(&out[4], get_zero64()); +} +__INLINE void fe52mb8_copy(U64 out[], const U64 in[]) +{ + storeu64(&out[0], loadu64(&in[0])); + storeu64(&out[1], loadu64(&in[1])); + storeu64(&out[2], loadu64(&in[2])); + storeu64(&out[3], loadu64(&in[3])); + storeu64(&out[4], loadu64(&in[4])); +} + +// Clang warning -Wunused-function +#if(0) +__INLINE void fe52mb8_mul_mod25519(U64 vr[], const U64 va[], const U64 vb[]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + // Full multiplication + ROUND_MUL(4, 4, r8, r9) + + ROUND_MUL(3, 0, r3, r4) + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(2, 1, r3, r4) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(3, 1, r4, r5) + ROUND_MUL(4, 0, r4, r5) + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(2, 3, r5, r6) + + ROUND_MUL(3, 2, r5, r6) + ROUND_MUL(4, 1, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 2, r6, r7) + + ROUND_MUL(0, 0, r0, r1) + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(1, 0, r1, r2) + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 0, r2, r3) + ROUND_MUL(3, 4, r7, r8) + ROUND_MUL(4, 3, r7, r8) + + //REDUCE_ROUND(4, 5, 9); + r4 = fma52lo(r4, r9, MOD_2_260); //r9 always contributes 0 to r5 (if input normalized?) + REDUCE_ROUND(3, 4, 8); + REDUCE_ROUND(2, 3, 7); + REDUCE_ROUND(1, 2, 6); + REDUCE_ROUND(0, 1, 5); + + // Reduce r4 upper bits + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + + // Trim top r4 bits that were already reduced above + r4 = and64(r4, MASK_47); + + // Normalize result + NORM(0,1) + NORM(1,2) + NORM(2,3) + NORM(3,4) + + storeu64(&vr[0], r0); + storeu64(&vr[1], r1); + storeu64(&vr[2], r2); + storeu64(&vr[3], r3); + storeu64(&vr[4], r4); +} + +__INLINE void fe52mb8_sqr_mod25519(U64 out[], const U64 a[]) +{ + fe52mb8_mul_mod25519(out, a, a); +} +#endif + +__INLINE void fe52mb8_mul121666_mod25519(U64 vr[], const U64 va[]) +{ + U64 multiplier = set64(121666); + + U64 r0, r1, r2, r3, r4, r5; + r0 = r1 = r2 = r3 = r4 = r5 = get_zero64(); + + // multiply + r0 = fma52lo(r0, va[0], multiplier); + r1 = fma52lo(r1, va[1], multiplier); + r2 = fma52lo(r2, va[2], multiplier); + r3 = fma52lo(r3, va[3], multiplier); + r4 = fma52lo(r4, va[4], multiplier); + + r5 = fma52hi(r5, va[4], multiplier); + r1 = fma52hi(r1, va[0], multiplier); + r2 = fma52hi(r2, va[1], multiplier); + r3 = fma52hi(r3, va[2], multiplier); + r4 = fma52hi(r4, va[3], multiplier); + + // reduce + REDUCE_ROUND(0, 1, 5); + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + + // trim top r4 bits that were already reduced above + r4 = and64(r4, MASK_47); + + // normalize + NORM(0,1) + NORM(1,2) + NORM(2,3) + NORM(3,4) + + storeu64(&vr[0], r0); + storeu64(&vr[1], r1); + storeu64(&vr[2], r2); + storeu64(&vr[3], r3); + storeu64(&vr[4], r4); +} + +#define PRIME25519_LO 0x000FFFFFFFFFFFED +#define PRIME25519_MID 0x000FFFFFFFFFFFFF +#define PRIME25519_HI 0x00007FFFFFFFFFFF + +// __ALIGN64 static const int64u prime25519[5] = { +// PRIME25519_LO, PRIME25519_MID, PRIME25519_MID, PRIME25519_MID, PRIME25519_HI}; + +__ALIGN64 static const int64u VPRIME25519_LO[8] = + { PRIME25519_LO, PRIME25519_LO, PRIME25519_LO, PRIME25519_LO, + PRIME25519_LO, PRIME25519_LO, PRIME25519_LO, PRIME25519_LO }; + +__ALIGN64 static const int64u VPRIME25519_MID[8] = + { PRIME25519_MID, PRIME25519_MID, PRIME25519_MID, PRIME25519_MID, + PRIME25519_MID, PRIME25519_MID, PRIME25519_MID, PRIME25519_MID }; + +__ALIGN64 static const int64u VPRIME25519_HI[8] = + { PRIME25519_HI, PRIME25519_HI, PRIME25519_HI, PRIME25519_HI, + PRIME25519_HI, PRIME25519_HI, PRIME25519_HI, PRIME25519_HI }; + + +__INLINE U64 cmov_U64(U64 a, U64 b, __mb_mask kmask) +{ return mask_mov64 (a, kmask, b); } + +#define NORM_ASHIFTR(R, I, J) \ + R##J = add64(R##J, srai64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + +#define NORM_LSHIFTR(R, I, J) \ + R##J = add64(R##J, srli64(R##I, DIGIT_SIZE)); \ + R##I = and64(R##I, loadu64(VMASK52)); + +__INLINE void fe52mb8_add_mod25519(U64 vr[], const U64 va[], const U64 vb[]) +{ + /* r = a+b */ + U64 r0 = add64(va[0], vb[0]); + U64 r1 = add64(va[1], vb[1]); + U64 r2 = add64(va[2], vb[2]); + U64 r3 = add64(va[3], vb[3]); + U64 r4 = add64(va[4], vb[4]); + + /* t = r-modulus (2^255-19) */ + U64 t0 = sub64(r0, loadu64(VPRIME25519_LO )); + U64 t1 = sub64(r1, loadu64(VPRIME25519_MID)); + U64 t2 = sub64(r2, loadu64(VPRIME25519_MID)); + U64 t3 = sub64(r3, loadu64(VPRIME25519_MID)); + U64 t4 = sub64(r4, loadu64(VPRIME25519_HI )); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_LSHIFTR(r, 0,1) + NORM_LSHIFTR(r, 1,2) + NORM_LSHIFTR(r, 2,3) + NORM_LSHIFTR(r, 3,4) + + /* normalize t0, t1, t2, t3, t4 */ + NORM_ASHIFTR(t, 0,1) + NORM_ASHIFTR(t, 1,2) + NORM_ASHIFTR(t, 2,3) + NORM_ASHIFTR(t, 3,4) + + /* condition mask t4<0? (-1) : 0 */ + __mb_mask cmask = cmp64_mask(t4, get_zero64(), _MM_CMPINT_LT); + + storeu64(&vr[0], cmov_U64(t0, r0, cmask)); + storeu64(&vr[1], cmov_U64(t1, r1, cmask)); + storeu64(&vr[2], cmov_U64(t2, r2, cmask)); + storeu64(&vr[3], cmov_U64(t3, r3, cmask)); + storeu64(&vr[4], cmov_U64(t4, r4, cmask)); +} + +__INLINE void fe52mb8_sub_mod25519(U64 vr[], const U64 va[], const U64 vb[]) +{ + /* r = a-b */ + U64 r0 = sub64(va[0], vb[0]); + U64 r1 = sub64(va[1], vb[1]); + U64 r2 = sub64(va[2], vb[2]); + U64 r3 = sub64(va[3], vb[3]); + U64 r4 = sub64(va[4], vb[4]); + + /* t = r+modulus (2^255-19) */ + U64 t0 = add64(r0, loadu64(VPRIME25519_LO )); + U64 t1 = add64(r1, loadu64(VPRIME25519_MID)); + U64 t2 = add64(r2, loadu64(VPRIME25519_MID)); + U64 t3 = add64(r3, loadu64(VPRIME25519_MID)); + U64 t4 = add64(r4, loadu64(VPRIME25519_HI )); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_ASHIFTR(r, 0,1) + NORM_ASHIFTR(r, 1,2) + NORM_ASHIFTR(r, 2,3) + NORM_ASHIFTR(r, 3,4) + + /* normalize t0, t1, t2, t3, t4 */ + NORM_ASHIFTR(t, 0,1) + NORM_ASHIFTR(t, 1,2) + NORM_ASHIFTR(t, 2,3) + NORM_ASHIFTR(t, 3,4) + + /* condition mask r4<0? (-1) : 0 */ + __mb_mask cmask = cmp64_mask(r4, get_zero64(), _MM_CMPINT_LT); + + storeu64(&vr[0], cmov_U64(r0, t0, cmask)); + storeu64(&vr[1], cmov_U64(r1, t1, cmask)); + storeu64(&vr[2], cmov_U64(r2, t2, cmask)); + storeu64(&vr[3], cmov_U64(r3, t3, cmask)); + storeu64(&vr[4], cmov_U64(r4, t4, cmask)); +} + +__INLINE void fe52mb8_red_p25519(U64 vr[], const U64 va[]) +{ + /* r = a-p */ + U64 r0 = sub64(va[0], loadu64(VPRIME25519_LO)); + U64 r1 = sub64(va[1], loadu64(VPRIME25519_MID)); + U64 r2 = sub64(va[2], loadu64(VPRIME25519_MID)); + U64 r3 = sub64(va[3], loadu64(VPRIME25519_MID)); + U64 r4 = sub64(va[4], loadu64(VPRIME25519_HI)); + + /* normalize r0, r1, r2, r3, r4 */ + NORM_ASHIFTR(r, 0, 1) + NORM_ASHIFTR(r, 1, 2) + NORM_ASHIFTR(r, 2, 3) + NORM_ASHIFTR(r, 3, 4) + + /* condition mask r4<0? (-1) : 0 */ + __mb_mask cmask = cmp64_mask(r4, get_zero64(), _MM_CMPINT_LT); + + storeu64(&vr[0], cmov_U64(r0, va[0], cmask)); + storeu64(&vr[1], cmov_U64(r1, va[1], cmask)); + storeu64(&vr[2], cmov_U64(r2, va[2], cmask)); + storeu64(&vr[3], cmov_U64(r3, va[3], cmask)); + storeu64(&vr[4], cmov_U64(r4, va[4], cmask)); +} + +// #define USE_DUAL_MUL_SQR +// #define fe52_mul fe52mb8_mul_mod25519 +// #define fe52_sqr fe52mb8_sqr_mod25519 +#define fe52_mul ed25519_mul +#define fe52_sqr ed25519_sqr +#define fe52_add fe52mb8_add_mod25519 +#define fe52_sub fe52mb8_sub_mod25519 +#define fe52_mul121666 fe52mb8_mul121666_mod25519 +#define fe52_sqr_power MB_FUNC_NAME(ed25519_sqr_latency_) + + +/* + Compute 1/z = z^(2^255 - 19 - 2) + considering the exponent as + 2^255 - 21 = (2^5) * (2^250 - 1) + 11. +*/ +__INLINE void fe52mb8_inv_mod25519(U64 out[], const U64 z[]) +{ + __ALIGN64 U64 t0[5]; + __ALIGN64 U64 t1[5]; + __ALIGN64 U64 t2[5]; + __ALIGN64 U64 t3[5]; + + /* t0 = z ** 2 */ + fe52_sqr(t0, z); + + /* t1 = t0 ** (2 ** 2) = z ** 8 */ + fe52_sqr(t1, t0); + fe52_sqr(t1, t1); + + /* t1 = z * t1 = z ** 9 */ + fe52_mul(t1, z, t1); + /* t0 = t0 * t1 = z ** 11 -- stash t0 away for the end. */ + fe52_mul(t0, t0, t1); + + /* t2 = t0 ** 2 = z ** 22 */ + fe52_sqr(t2, t0); + + /* t1 = t1 * t2 = z ** (2 ** 5 - 1) */ + fe52_mul(t1, t1, t2); + + /* t2 = t1 ** (2 ** 5) = z ** ((2 ** 5) * (2 ** 5 - 1)) */ + fe52_sqr_power(t2, t1, 5); + + /* t1 = t1 * t2 = z ** ((2 ** 5 + 1) * (2 ** 5 - 1)) = z ** (2 ** 10 - 1) */ + fe52_mul(t1, t2, t1); + + /* Continuing similarly... */ + + /* t2 = z ** (2 ** 20 - 1) */ + fe52_sqr_power(t2, t1, 10); + + fe52_mul(t2, t2, t1); + + /* t2 = z ** (2 ** 40 - 1) */ + fe52_sqr_power(t3, t2, 20); + + fe52_mul(t2, t3, t2); + + /* t2 = z ** (2 ** 10) * (2 ** 40 - 1) */ + fe52_sqr_power(t2, t2, 10); + + /* t1 = z ** (2 ** 50 - 1) */ + fe52_mul(t1, t2, t1); + + /* t2 = z ** (2 ** 100 - 1) */ + fe52_sqr_power(t2, t1, 50); + + fe52_mul(t2, t2, t1); + + /* t2 = z ** (2 ** 200 - 1) */ + fe52_sqr_power(t3, t2, 100); + + fe52_mul(t2, t3, t2); + + /* t2 = z ** ((2 ** 50) * (2 ** 200 - 1) */ + fe52_sqr_power(t2, t2, 50); + + /* t1 = z ** (2 ** 250 - 1) */ + fe52_mul(t1, t2, t1); + + /* t1 = z ** ((2 ** 5) * (2 ** 250 - 1)) */ + fe52_sqr_power(t1, t1, 5); + + /* Recall t0 = z ** 11; out = z ** (2 ** 255 - 21) */ + fe52_mul(out, t1, t0); +} + +#define cswap_U64(a, b, kmask) { \ + U64 ta = mask_mov64((a), (kmask), (b)); \ + (b) = mask_mov64((b), (kmask), (a)); \ + (a) = ta; \ +} + +static void fe52mb8_cswap(U64 a[], U64 b[], __mb_mask k) +{ + cswap_U64(a[0], b[0], k) + cswap_U64(a[1], b[1], k) + cswap_U64(a[2], b[2], k) + cswap_U64(a[3], b[3], k) + cswap_U64(a[4], b[4], k) +} + +#if 0 +static void x25519_scalar_mul(U64 out[], U64 scalar[], U64 point[]) +{ + __ALIGN64 U64 x1[5], x2[5], x3[5]; + __ALIGN64 U64 z2[5], z3[5]; + __ALIGN64 U64 tmp0[5], tmp1[5]; + + fe52mb8_copy(x1, point); + fe52mb8_set(x2, 1); + fe52mb8_set(z2, 0); + fe52mb8_copy(x3, x1); + fe52mb8_set(z3, 1); + + /* read high and remove (zero) bit 63 */ + U64 e = loadu64(&scalar[3]); + e = slli64(e, 1); + + __mb_mask swap = get_mask(0); + int bitpos; + for (bitpos=254; bitpos>= 0; bitpos--) { + if(63==(bitpos%64)) + e = loadu64(&scalar[bitpos/64]); + + __mb_mask b = cmp64_mask(e, get_zero64(), _MM_CMPINT_LT); + + swap = mask_xor (swap, b); + fe52mb8_cswap(x2, x3, swap); + fe52mb8_cswap(z2, z3, swap); + swap = b; + fe52_sub(tmp0, x3, z3); + fe52_sub(tmp1, x2, z2); + fe52_add(x2, x2, z2); + fe52_add(z2, x3, z3); + + #ifdef USE_DUAL_MUL_SQR + ed25519_mul_dual(z3, z2, x2, tmp0, z2, tmp1); + #else + fe52_mul(z3, x2, tmp0); + fe52_mul(z2, z2, tmp1); + #endif + + #ifdef USE_DUAL_MUL_SQR + ed25519_sqr_dual(tmp0, tmp1, tmp1, x2); + #else + fe52_sqr(tmp0, tmp1); + fe52_sqr(tmp1, x2); + #endif + + fe52_add(x3, z3, z2); + fe52_sub(z2, z3, z2); + fe52_mul(x2, tmp1, tmp0); + fe52_sub(tmp1, tmp1, tmp0); + fe52_sqr(z2, z2); + fe52_mul121666(z3, tmp1); + fe52_sqr(x3, x3); + fe52_add(tmp0, tmp0, z3); + + #ifdef USE_DUAL_MUL_SQR + ed25519_mul_dual(z3, z2, x1, z2, tmp1, tmp0); + #else + fe52_mul(z3, x1, z2); + fe52_mul(z2, tmp1, tmp0); + #endif + + e = slli64(e, 1); + } + + fe52mb8_inv_mod25519(z2, z2); + fe52_mul(out, x2, z2); +} +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// + +__INLINE void ed25519_mul_dual_wonorm(U64 out0[], U64 out1[], + const U64 a0[], const U64 b0[], + const U64 a1[], const U64 b1[]) { + + U64 r00, r01, r02, r03, r04, r05, r06, r07, r08, r09; + U64 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19; + + U64 *vr0 = (U64*) out0; + U64 *vr1 = (U64*) out1; + + r00 = r01 = r02 = r03 = r04 = r05 = r06 = r07 = r08 = r09 = get_zero64(); + r10 = r11 = r12 = r13 = r14 = r15 = r16 = r17 = r18 = r19 = get_zero64(); + + // Full multiplication + U64 *va = (U64*) a0; + U64 *vb = (U64*) b0; + ROUND_MUL(4, 4, r08, r09) + ROUND_MUL(3, 0, r03, r04) + ROUND_MUL(1, 2, r03, r04) + ROUND_MUL(0, 3, r03, r04) + ROUND_MUL(2, 1, r03, r04) + ROUND_MUL(2, 2, r04, r05) + ROUND_MUL(0, 4, r04, r05) + ROUND_MUL(1, 3, r04, r05) + ROUND_MUL(3, 1, r04, r05) + ROUND_MUL(4, 0, r04, r05) + ROUND_MUL(1, 4, r05, r06) + ROUND_MUL(2, 3, r05, r06) + ROUND_MUL(3, 2, r05, r06) + ROUND_MUL(4, 1, r05, r06) + ROUND_MUL(2, 4, r06, r07) + ROUND_MUL(3, 3, r06, r07) + ROUND_MUL(4, 2, r06, r07) + ROUND_MUL(0, 0, r00, r01) + ROUND_MUL(0, 1, r01, r02) + ROUND_MUL(0, 2, r02, r03) + ROUND_MUL(1, 0, r01, r02) + ROUND_MUL(1, 1, r02, r03) + ROUND_MUL(2, 0, r02, r03) + ROUND_MUL(3, 4, r07, r08) + ROUND_MUL(4, 3, r07, r08) + + va = (U64*) a1; + vb = (U64*) b1; + ROUND_MUL(4, 4, r18, r19) + ROUND_MUL(3, 0, r13, r14) + ROUND_MUL(1, 2, r13, r14) + ROUND_MUL(0, 3, r13, r14) + ROUND_MUL(2, 1, r13, r14) + ROUND_MUL(2, 2, r14, r15) + ROUND_MUL(0, 4, r14, r15) + ROUND_MUL(1, 3, r14, r15) + ROUND_MUL(3, 1, r14, r15) + ROUND_MUL(4, 0, r14, r15) + ROUND_MUL(1, 4, r15, r16) + ROUND_MUL(2, 3, r15, r16) + ROUND_MUL(3, 2, r15, r16) + ROUND_MUL(4, 1, r15, r16) + ROUND_MUL(2, 4, r16, r17) + ROUND_MUL(3, 3, r16, r17) + ROUND_MUL(4, 2, r16, r17) + ROUND_MUL(0, 0, r10, r11) + ROUND_MUL(0, 1, r11, r12) + ROUND_MUL(0, 2, r12, r13) + ROUND_MUL(1, 0, r11, r12) + ROUND_MUL(1, 1, r12, r13) + ROUND_MUL(2, 0, r12, r13) + ROUND_MUL(3, 4, r17, r18) + ROUND_MUL(4, 3, r17, r18) + + REDUCE_R4_N_R9(r0) + REDUCE_R4_N_R9(r1) + + REDUCE_ROUND_(r0, 0, 1, 5); + REDUCE_ROUND_(r0, 1, 2, 6); + REDUCE_ROUND_(r0, 2, 3, 7); + REDUCE_ROUND_(r0, 3, 4, 8); + + REDUCE_ROUND_(r1, 0, 1, 5); + REDUCE_ROUND_(r1, 1, 2, 6); + REDUCE_ROUND_(r1, 2, 3, 7); + REDUCE_ROUND_(r1, 3, 4, 8); + + storeu64(&vr0[0], r00); + storeu64(&vr0[1], r01); + storeu64(&vr0[2], r02); + storeu64(&vr0[3], r03); + storeu64(&vr0[4], r04); + + storeu64(&vr1[0], r10); + storeu64(&vr1[1], r11); + storeu64(&vr1[2], r12); + storeu64(&vr1[3], r13); + storeu64(&vr1[4], r14); +} + +__INLINE void fe52mb8_mul_mod25519_wonorm(U64 vr[], const U64 va[], const U64 vb[]) +{ + U64 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9; + r0 = r1 = r2 = r3 = r4 = r5 = r6 = r7 = r8 = r9 = get_zero64(); + + // Full multiplication + ROUND_MUL(4, 4, r8, r9) + + ROUND_MUL(3, 0, r3, r4) + ROUND_MUL(1, 2, r3, r4) + ROUND_MUL(0, 3, r3, r4) + ROUND_MUL(2, 1, r3, r4) + ROUND_MUL(2, 2, r4, r5) + ROUND_MUL(0, 4, r4, r5) + ROUND_MUL(1, 3, r4, r5) + ROUND_MUL(3, 1, r4, r5) + ROUND_MUL(4, 0, r4, r5) + ROUND_MUL(1, 4, r5, r6) + ROUND_MUL(2, 3, r5, r6) + + ROUND_MUL(3, 2, r5, r6) + ROUND_MUL(4, 1, r5, r6) + ROUND_MUL(2, 4, r6, r7) + ROUND_MUL(3, 3, r6, r7) + ROUND_MUL(4, 2, r6, r7) + + ROUND_MUL(0, 0, r0, r1) + ROUND_MUL(0, 1, r1, r2) + ROUND_MUL(0, 2, r2, r3) + ROUND_MUL(1, 0, r1, r2) + ROUND_MUL(1, 1, r2, r3) + ROUND_MUL(2, 0, r2, r3) + ROUND_MUL(3, 4, r7, r8) + ROUND_MUL(4, 3, r7, r8) + + //REDUCE_ROUND(4, 5, 9); + r4 = fma52lo(r4, r9, MOD_2_260); //r9 always contributes 0 to r5 (if input normalized?) + REDUCE_ROUND(3, 4, 8); + REDUCE_ROUND(2, 3, 7); + REDUCE_ROUND(1, 2, 6); + REDUCE_ROUND(0, 1, 5); + + // Reduce r4 upper bits + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + + // Trim top r4 bits that were already reduced above + r4 = and64(r4, MASK_47); + + storeu64(&vr[0], r0); + storeu64(&vr[1], r1); + storeu64(&vr[2], r2); + storeu64(&vr[3], r3); + storeu64(&vr[4], r4); +} + +__INLINE void fe52mb8_mul121666_mod25519_wonorm(U64 vr[], const U64 va[]) +{ + U64 multiplier = set64(121666); + + U64 r0, r1, r2, r3, r4, r5; + r0 = r1 = r2 = r3 = r4 = r5 = get_zero64(); + + // multiply + r0 = fma52lo(r0, va[0], multiplier); + r1 = fma52lo(r1, va[1], multiplier); + r2 = fma52lo(r2, va[2], multiplier); + r3 = fma52lo(r3, va[3], multiplier); + r4 = fma52lo(r4, va[4], multiplier); + + r5 = fma52hi(r5, va[4], multiplier); + r1 = fma52hi(r1, va[0], multiplier); + r2 = fma52hi(r2, va[1], multiplier); + r3 = fma52hi(r3, va[2], multiplier); + r4 = fma52hi(r4, va[3], multiplier); + + // reduce + REDUCE_ROUND(0, 1, 5); + r0 = fma52lo(r0, srli64(r4, 47), MOD_2_255); + + // trim top r4 bits that were already reduced above + r4 = and64(r4, MASK_47); + + storeu64(&vr[0], r0); + storeu64(&vr[1], r1); + storeu64(&vr[2], r2); + storeu64(&vr[3], r3); + storeu64(&vr[4], r4); +} + +__INLINE void x25519_scalar_mul_dual(U64 out[], U64 scalar[], U64 point[]) +{ + __ALIGN64 U64 x1[5], x2[5], x3[5]; + __ALIGN64 U64 z2[5], z3[5]; + __ALIGN64 U64 tmp0[5], tmp1[5]; + + fe52mb8_copy(x1, point); + fe52mb8_set(x2, 1); + fe52mb8_set(z2, 0); + fe52mb8_copy(x3, x1); + fe52mb8_set(z3, 1); + + /* read high and remove (zero) bit 63 */ + U64 e = loadu64(&scalar[3]); + U64 vmask = slli64( + xor64(e, srli64(e, 1)), 1); + __mb_mask swap = cmp64_mask(vmask, get_zero64(), _MM_CMPINT_LT); + + int bitpos; + for (bitpos = 254; bitpos >= 0; bitpos--) { + if (63 == (bitpos % 64)) { + U64 t = e; + e = loadu64(&scalar[bitpos/64]); + vmask = xor64(slli64(t, 63), + xor64(e, srli64(e, 1))); + swap = cmp64_mask(vmask, get_zero64(), _MM_CMPINT_LT); + } + + fe52mb8_cswap(x2, x3, swap); + fe52mb8_cswap(z2, z3, swap); + +#if (defined(linux) && ((SIMD_LEN)==512)) + // Avoid reordering optimization by compiler + U64 Z = get_zero64(); + __asm__ ("vpsllq $1, %0, %0 \n" + "vpcmpq $1, %2, %0, %1\n" + : "+x" (vmask), "=k" (swap): "x" (Z) : ); +#else + vmask = slli64(vmask, 1); + swap = cmp64_mask(vmask, get_zero64(), _MM_CMPINT_LT); +#endif + + fe52_sub(tmp0, x3, z3); + fe52_sub(tmp1, x2, z2); + fe52_add(x2, x2, z2); + fe52_add(z2, x3, z3); + + ed25519_mul_dual_wonorm(z3, z2, x2,tmp0, z2,tmp1); + + ed25519_sqr_dual(tmp0, tmp1, tmp1, x2); + + fe52_add(x3, z3, z2); + fe52_sub(z2, z3, z2); + + fe52mb8_mul_mod25519_wonorm(x2, tmp1, tmp0); + fe52_sub(tmp1, tmp1, tmp0); + + ed25519_sqr_dual(z2, x3, z2, x3); + + fe52mb8_mul121666_mod25519_wonorm(z3, tmp1); + fe52_add(tmp0, tmp0, z3); + + ed25519_mul_dual_wonorm(z3, z2, x1,z2, tmp1,tmp0); + } + + // normalize z2 and x2 before inversion + { + U64 r0 = z2[0]; + U64 r1 = z2[1]; + U64 r2 = z2[2]; + U64 r3 = z2[3]; + U64 r4 = z2[4]; + NORM_(r, 0,1) + NORM_(r, 1,2) + NORM_(r, 2,3) + NORM_(r, 3,4) + storeu64(&z2[0], r0); + storeu64(&z2[1], r1); + storeu64(&z2[2], r2); + storeu64(&z2[3], r3); + storeu64(&z2[4], r4); + + r0 = x2[0]; + r1 = x2[1]; + r2 = x2[2]; + r3 = x2[3]; + r4 = x2[4]; + NORM_(r, 0,1) + NORM_(r, 1,2) + NORM_(r, 2,3) + NORM_(r, 3,4) + storeu64(&x2[0], r0); + storeu64(&x2[1], r1); + storeu64(&x2[2], r2); + storeu64(&x2[3], r3); + storeu64(&x2[4], r4); + } + + fe52mb8_inv_mod25519(z2, z2); + fe52_mul(x2, x2, z2); + fe52mb8_red_p25519(out, x2); +} + +DLL_PUBLIC +mbx_status MB_FUNC_NAME(mbx_x25519_)(int8u* const pa_shared_key[8], + const int8u* const pa_private_key[8], + const int8u* const pa_public_key[8]) +{ + mbx_status status = 0; + int buf_no; + + /* test input pointers */ + if(NULL==pa_shared_key || NULL==pa_private_key || NULL==pa_public_key) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + for(buf_no=0; buf_no<8; buf_no++) { + int64u* shared = (int64u*) pa_shared_key[buf_no]; + const int64u* own_private = (const int64u*) pa_private_key[buf_no]; + const int64u* party_public = (const int64u*) pa_public_key[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==shared || NULL==own_private || NULL==party_public) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + } + + /* continue processing if there are correct parameters */ + if( MBX_IS_ANY_OK_STS(status) ) { + __ALIGN64 U64 private64_mb8[4]; + __ALIGN64 U64 pub52_mb8[5]; + __ALIGN64 U64 shared52_mb8[5]; + + /* get scalars and convert to MB8 */ + ifma_BNU_transpose_copy((int64u (*)[8])private64_mb8, (const int64u * const*)pa_private_key, 256); + /* decode keys into scalars according to RFC7748 */ + private64_mb8[0] = and64_const(private64_mb8[0], 0xfffffffffffffff8); + private64_mb8[3] = and64_const(private64_mb8[3], 0x7fffffffffffffff); + private64_mb8[3] = or64(private64_mb8[3], set64(0x4000000000000000)); + + /* get peer's public keys and convert to MB8 */ + ifma_BNU_to_mb8((int64u (*)[8])pub52_mb8, (const int64u * const*)pa_public_key, 256); + + /* RFC7748: (x25519) ... MUST mask the most significant bit in the final byte. + This is done to preserve compatibility with point formats .. (compact format??) + */ + pub52_mb8[4] = and64(pub52_mb8[4], loadu64(VPRIME25519_HI)); + + /* point multiplication */ + x25519_scalar_mul_dual(shared52_mb8, private64_mb8, pub52_mb8); + + /* test shared secret before return; all-zero output results when the input is a point of small order. */ + __ALIGN64 U64 shared52_sum = shared52_mb8[0]; + shared52_sum = or64(shared52_sum, shared52_mb8[1]); + shared52_sum = or64(shared52_sum, shared52_mb8[2]); + shared52_sum = or64(shared52_sum, shared52_mb8[3]); + shared52_sum = or64(shared52_sum, shared52_mb8[4]); + int8u stt_mask = cmpeq64_mask(shared52_sum, get_zero64()); + status |= MBX_SET_STS_BY_MASK(status, stt_mask, MBX_STATUS_LOW_ORDER_ERR); + + /* convert result back */ + ifma_mb8_to_BNU((int64u* const *)pa_shared_key, (const int64u (*)[8])shared52_mb8, 256); + + /* clear computed shared keys and it sum */ + MB_FUNC_NAME(zero_)((int64u (*)[8])shared52_mb8, sizeof(shared52_mb8)/sizeof(U64)); + MB_FUNC_NAME(zero_)((int64u (*)[8])&shared52_sum, 1); + + /* clear copy of the secret keys */ + MB_FUNC_NAME(zero_)((int64u (*)[8])private64_mb8, sizeof(private64_mb8)/sizeof(U64)); + } + return status; +} + +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////// + +/* the fe64 muTBL52[] table in radix52 */ +__ALIGN64 static int64u muTBL52[255][NUMBER_OF_DIGITS(256,DIGIT_SIZE)] = { + {0x000ffffffffffff3, 0x000fffffffffffff, 0x000fffffffffffff, 0x000fffffffffffff, 0x00005fffffffffff}, + {0x000220f416aafe96, 0x0002b4f566a346b8, 0x0005a5950f82ebeb, 0x00088f4d5a9a5b07, 0x00005142b2cf4b24}, + {0x000ebc750069680c, 0x00020a0f99c416aa, 0x000b56d0f489cf78, 0x00011a42a58d9183, 0x00004b5aca80e360}, + {0x000132348c29745d, 0x00016e1642fd7329, 0x000f67bc34f4a2e6, 0x0009b4a1e45bb03f, 0x0000306912d0f42a}, + {0x00086507e6af7154, 0x00013dfeec82fff8, 0x000abab5ce04f50e, 0x000f222aa512fe82, 0x0000174e251a68d5}, + {0x0006700d82028898, 0x000370a2c02c5cf9, 0x0004e86eaa1743e3, 0x000482e379eec98b, 0x00000c59888a51e0}, + {0x000bf1d699b5d189, 0x000d58e9fdc84fbc, 0x00031f7614acaef0, 0x000f972c1c20d062, 0x00002938218da274}, + {0x000f49beff1d7f18, 0x00022387ac9c2f6a, 0x000015c56bcc541c, 0x00013a996fcc9ef4, 0x000069c1627c6909}, + {0x0006fd2f4733db0e, 0x000f29e087de97a8, 0x000ea2a229fdb8c4, 0x0007a79095e4b1a8, 0x00001ad7a7c829b3}, + {0x000d89cad17ea0c0, 0x000a6cced2051342, 0x000bb42f7467bedd, 0x000acbb19ca31bf2, 0x00003df7b4c84980}, + {0x0006444dc80ad883, 0x0000366e3ab85a8c, 0x000164f6d8b91e44, 0x000e668c215cda00, 0x00003d867c6ef247}, + {0x000d582bcc3e658c, 0x00048ee0e5528c7d, 0x000c9f4f71fd2c47, 0x0005ddfa0fd9b95c, 0x00007529d871b067}, + {0x000568b42d3cbd78, 0x0001b91f3da82b8f, 0x000a7c3b62123301, 0x00086032dce6ccd4, 0x000075e7fc8e9e49}, + {0x000f13f1fcd0b6ec, 0x0001f29ff7a452f4, 0x000981e29bf1a8ca, 0x000b56ac249c1a72, 0x00006ebe0dbb8c83}, + {0x0004fa8d170bb222, 0x000d5bf93935f711, 0x00059c979a65a2dc, 0x0009289bdc41f68b, 0x00002f0eef79a2ce}, + {0x000cbf0c083c37ce, 0x00009ec49632242e, 0x000cfeac0d2930bc, 0x000bb80f294b0c19, 0x00003780aa4bedfa}, + {0x00017d3e7cead929, 0x000eb2e5722c556c, 0x000dbfe15ae7cb4b, 0x00052f80ce931732, 0x000041b883c76210}, + {0x00075ca0c3d25350, 0x000086eb1e351dbf, 0x0004a9b2122936be, 0x00025aac936e03cb, 0x00001d45bf823222}, + {0x000ab1036a024cc5, 0x0001c304c9a72e81, 0x000832b1fce21220, 0x0009581c5d73fba6, 0x000020ffdb5a4d83}, + {0x0003d367be5d0fad, 0x000ca8b164475a28, 0x000caaf22e6c2b25, 0x000ff499d4935467, 0x00005166408eee85}, + {0x0007baa2fab4e361, 0x000c67ef35cef3c6, 0x0001159b1cb3e433, 0x000ab33525972924, 0x00006a621892d5b0}, + {0x00074a387555cdcb, 0x0000e1208923f20b, 0x0002281dd1532aa1, 0x00044bfeaa17b776, 0x000061ab3443f05c}, + {0x000a6c422324def8, 0x0001017e3cf7f257, 0x000630a257131c6c, 0x000858023758739f, 0x0000295a407a01a7}, + {0x000443246d5da8d9, 0x000450c52fa5df8c, 0x00031bf83d19d775, 0x00047002afcfc927, 0x00007d10c8e81b2b}, + {0x0000271f70baa20b, 0x000867ca63957c8e, 0x000b7ed4bb993748, 0x00029755412efb3c, 0x00003196d36173e6}, + {0x000bcad141c7dffc, 0x000d2b395c848de5, 0x00011af3cb47cc8c, 0x000cec2a34cd942e, 0x00000256dbf2d04e}, + {0x000ab7e94b0e667f, 0x00083c0850d10875, 0x000e72c79fcad4dd, 0x000b19b47f12e8f4, 0x00005f1a87bb8c85}, + {0x0009d0b6437f51b8, 0x00055188790657ae, 0x000cf77aee12c7ce, 0x00056272ade09fe5, 0x000023a05a2f7d2c}, + {0x0008e128f17c169a, 0x000dd8ad0852d590, 0x000b102f64f77498, 0x000984574b4c4cea, 0x0000183abadd1013}, + {0x0005ba8daa92aaac, 0x0009599386705b16, 0x0008fc40d1d5c5ef, 0x0004514be2f8f0cf, 0x00002701e635ee20}, + {0x000fa80020156514, 0x0008764a8c1ce629, 0x000b3f060ef22386, 0x000a3fa5b894fff0, 0x000060d9944cf708}, + {0x000a001a1c7a201f, 0x000633ee2ce63aee, 0x000c7a07e1ebf16a, 0x00008cb6f7709594, 0x000079b958150d02}, + {0x00055e5301d410e7, 0x000dff3fdc84d24b, 0x00004032d8e3a34e, 0x000aeecd88768e49, 0x0000131384427b3a}, + {0x0005e51286234f14, 0x00039adb4c529840, 0x0000634ffd14dc47, 0x000ff93b8a2b5b25, 0x00002fe2a94ad8a7}, + {0x000c57efe843fadd, 0x00040f0bb9918ec5, 0x000f3d63052843ce, 0x000777ea4b561d6c, 0x0000743629bde8fb}, + {0x000edd46bbaf738f, 0x00028b101a651343, 0x00082c797aed9818, 0x0008730a401760b8, 0x00001fc223e28dc8}, + {0x00004e91fc0fba0e, 0x0008f052c6fa4486, 0x0009e9239cb637f7, 0x000687c91ccac3d0, 0x000023f7eed4437a}, + {0x0003b1118d9bd800, 0x000b63189d4a7517, 0x0008bbc58629d641, 0x0001df5fdbf17798, 0x00002959894fcad8}, + {0x000c8ef3b4bbc899, 0x0005ab26992b9aeb, 0x0004f92cfb414899, 0x000dee824e20b013, 0x000040d158894a05}, + {0x00000b1185af76f6, 0x0007873187a7946b, 0x000b8fff5f26bac7, 0x00024d73dc0bf95a, 0x00002a608bd89455}, + {0x00049588bd446302, 0x0001c0388439c264, 0x0003bd11b27c4bc2, 0x00076b98e98a4f38, 0x000026218d7bc9d8}, + {0x00081542997c178a, 0x000a86fb6606fe30, 0x000a2793743c2d29, 0x000b1fa5c217736f, 0x00007dde05734afe}, + {0x00010e3906d42bab, 0x0003e1980649c3bf, 0x000595bf7ae4f780, 0x0005530e6053bf89, 0x0000394faf38da24}, + {0x000efb58896928f4, 0x000e9cc6a113c7a8, 0x0000af596ffbc778, 0x0006cf772670ce33, 0x000048f222a81d3d}, + {0x000fce410d72caa7, 0x000c7213b5595f01, 0x0001fa14835a20ec, 0x000a7417bc21165c, 0x000007f89ae31da8}, + {0x0002c2b4c6830ff9, 0x0000fc631629305d, 0x0006d3a904d43e33, 0x00033b6a5a5590a9, 0x0000705edb91a653}, + {0x000ee15e0bb9a5f7, 0x000ca9e0aaf5d048, 0x000dc4a40b3240cf, 0x0004a6d8f4b71cee, 0x0000621c0da3de54}, + {0x00072836a08c4091, 0x000b010c91445928, 0x000f276394ce8375, 0x00036358a72eb524, 0x00002667fcfa7ec8}, + {0x000c173345e8752a, 0x000feee7079a57f4, 0x000f86ff34061b47, 0x000c89c25dd9afa9, 0x00003780cef5425d}, + {0x0006035a513bb4e9, 0x00079ac575ada1a4, 0x000fa24b503e1ef3, 0x0009f22c78c5f1c5, 0x0000321a967634fd}, + {0x000707b8826e27fa, 0x000d64c506fd0946, 0x0005e914363dca84, 0x0008484c18921807, 0x00006d9284169b3b}, + {0x0007e840383f2ddf, 0x000a30c4f9b753a6, 0x000783ef4733eec9, 0x000fbc43ec7c86fa, 0x000026ec449fbac9}, + {0x000f38cba09b9e7d, 0x000c762a3478c5c0, 0x0006fc121c81168c, 0x000dcdd3e23b0d30, 0x00005a238aa0a5ef}, + {0x00026121c4ea43ff, 0x0007f7c8832b51ba, 0x000adcf99a36f8c7, 0x000ebf988fbea0b0, 0x00005ca9938ec25b}, + {0x00036a5e51fccda0, 0x00097c2cd893bd54, 0x0003224a081dbc47, 0x000f46619346a65d, 0x00000f5034e49b9a}, + {0x000c3967a1e0b96e, 0x000fa867a4d88f23, 0x0007341679e58b08, 0x0006946fb2fabc6a, 0x00002a75381eb602}, + {0x000a3be4c19420ac, 0x000c681f2b6dcc80, 0x0001e9338866b1f6, 0x000a4c47cf703676, 0x000025abbbd8a660}, + {0x000a12ba14fd5198, 0x000fc4a3cffa991e, 0x0000f5ad28684950, 0x000a441f82684213, 0x00003ea988f75301}, + {0x0008109a695f8c6f, 0x0004a0530c3f3c97, 0x00044599951746eb, 0x0005cc7444d6d77b, 0x000075952b8c054e}, + {0x00003f7915f4d6aa, 0x000202f2647d8a37, 0x00011d644b66c346, 0x000d71fd01469df8, 0x000077fea47d81a5}, + {0x0009529ef57ca381, 0x000b9ce2f881ac5e, 0x0008009bd66eeeb4, 0x0003fecb6e91a28e, 0x00004b80be3e9afc}, + {0x000773c526aed2c5, 0x000b453c9a49d7e3, 0x000affb24d1b4afc, 0x000400ea920bdd7b, 0x00007c54699f122d}, + {0x0006c8e14fa94bc8, 0x000ce2952ed5eef4, 0x000bd885d5e0b074, 0x000712cbea450e1d, 0x000061b68649320f}, + {0x00085f7309ccbdd1, 0x0000d7d4d1a2d8a4, 0x00022dbef4bd0632, 0x000f770252329733, 0x0000445dc4758c17}, + {0x000434177cc8933c, 0x0002175ea059fdb0, 0x000053db34ed6fe8, 0x000af991efebefdc, 0x00004adbe867c65d}, + {0x000d71a2a90609df, 0x000856dd040503ac, 0x000157c23ce5e991, 0x000fe4d1ec69b688, 0x0000697427f6885c}, + {0x000e7b9b65e1a851, 0x000d522c536ddd7b, 0x000fd2b645a03d28, 0x00041e128399d658, 0x000049e5b7e17c26}, + {0x000c3a98700457a4, 0x000a25ebb67786f8, 0x000382960f5078f0, 0x00084b1d13c3ccbc, 0x00002e003258a7df}, + {0x0001f39be6296a1c, 0x000652a5fbfb28ad, 0x000d26f3cbc1eeaa, 0x0002ccc33ee0673f, 0x000059256173a69d}, + {0x000a07aa4e18fc41, 0x000527c87a51e41e, 0x000831ca6fd9fc19, 0x000694fbdaacb805, 0x0000445b652dc916}, + {0x0002a3a7f2172315, 0x0002de11b9964ce9, 0x00004c314a1edc28, 0x000f586a1823aafe, 0x0000790a2d94437c}, + {0x000447fb93f6e009, 0x000672284527671c, 0x00004f51698922a5, 0x00019febf70903b2, 0x00002f7a89891ba3}, + {0x00008eb577e2140c, 0x000d4427bdcf402a, 0x0004323cd1ed9a4e, 0x000355b5253ec44e, 0x00003e88363c14e9}, + {0x0006c14277110b8c, 0x0001610a23390aa6, 0x00093fc2a21ae039, 0x000c7ab2030bd12c, 0x00003ee141579555}, + {0x0004de3a6d6e7d41, 0x0008607f17efe921, 0x0008e112173ccdd8, 0x00093d0674f1288f, 0x00005682250f329f}, + {0x00000b136d2e396e, 0x0006f1014debf6cf, 0x000fcc4e836e4cf8, 0x00016b65930b1b5b, 0x0000047069b48aba}, + {0x000ce4ab69b20793, 0x0001a97d0fb9e0d4, 0x000e00d01db24db9, 0x000ddb5cdfa50f54, 0x0000221b1085368b}, + {0x00059468b1e3d8d2, 0x00063bd122f93e7e, 0x0000663f0953c565, 0x0003d42eee8a903e, 0x000061efa662cbbe}, + {0x0008ddddde6eab2a, 0x000d51435f2312cf, 0x0009f049739bf80a, 0x0009b275deadacec, 0x000029275b5d41d2}, + {0x000e0f0895ebf14f, 0x0006b054905a7cfd, 0x0001c420fdb9aab9, 0x000bbc7cae80dd9a, 0x00000a63bf2f1673}, + {0x000f6e11958fbc8c, 0x000e804822fad092, 0x0000d52517672a81, 0x00092f8cac835156, 0x00006f3f7722c8f1}, + {0x000a90ccc2e894b7, 0x000a438ff9f0df8b, 0x000ae523592c7557, 0x0003d69894d1d855, 0x000068e122157b74}, + {0x000e5570cfb919f3, 0x000cd95798db9d87, 0x0000c0a2ce3f2cde, 0x000c5b2212115471, 0x00003c66a115246d}, + {0x000dc562294ecb72, 0x000c36a280b16cbe, 0x0004078b67ba7143, 0x0004b1e9610c2efd, 0x00006144735d946a}, + {0x000f111ed75b3350, 0x0008c2041d81b536, 0x000e10413c0211db, 0x0008876f93cb1000, 0x0000149dfd3c039e}, + {0x0009dde46b63155b, 0x000e93c837976d47, 0x000f13e038b66e15, 0x0000b35dafde43b1, 0x00005fafda1a2e4b}, + {0x0000bbdf17197581, 0x0000bbe3cd2c2360, 0x000dd5be86397205, 0x000860f5938906db, 0x000034fce5e43f9b}, + {0x0008a4cd42d14d02, 0x000c53441df6575a, 0x0002e131d3828dab, 0x000d25f33dcabedd, 0x00003ebad76fb814}, + {0x00006f566f70e10f, 0x000aa51690f5ad49, 0x0006cefcf25d12f7, 0x000299945adb16e7, 0x000001f768aead23}, + {0x000cc77b6248febd, 0x00028ec3aaffd2b6, 0x0004ef486a3cd306, 0x0006c23ce1c0b80d, 0x00004c3bff2ea6f6}, + {0x000ec4094aeaeb5f, 0x000286e372ca73f2, 0x000e2a701d61b19b, 0x000e3ef5eefa966d, 0x000023b20565de55}, + {0x0001ca5279d58557, 0x000ce27c2874fe30, 0x000dcf1d6707b2d4, 0x000ff56a532cd8a9, 0x00002a52fee23f2b}, + {0x0004efb37cd8663d, 0x00020ffbd7594862, 0x0002d37445bbc7ac, 0x000ec6657b85e9c8, 0x00007b3052cb86a6}, + {0x0002f0ad2525e91e, 0x00043d28edca0348, 0x000e1b003a2cb680, 0x0001b0aaf4f6d052, 0x0000185f8c252978}, + {0x0001de5bd80ce0d6, 0x000416853e9d6aa4, 0x00057f4c3a9407b2, 0x0007bce563ec36e3, 0x00004cc4b8dd0e29}, + {0x000c1a52ffb8730e, 0x0006e67058e37a2f, 0x000ddf4ee11811f1, 0x000f09910f9a366c, 0x000072f4a0c4a0b9}, + {0x0006c06f663f4ea7, 0x000f74e970fba8c1, 0x00069ec345693b3a, 0x00080892102e7f1d, 0x00000ba53cbc968a}, + {0x000d9dc7fea15537, 0x000bb51536493ca3, 0x00044006b14c6824, 0x000cc60b98863148, 0x000040d2a72ab454}, + {0x0006a1b712570975, 0x00048debda657593, 0x00064330ea91b9d6, 0x00051d03344094bb, 0x0000006ba10d12ee}, + {0x00028468f5de5d58, 0x0004c38cc05b0192, 0x00056019900eb12f, 0x0000e0ba1039f9dd, 0x00004502d4ce4fff}, + {0x000054106837c189, 0x0004c6dd3b93ceb2, 0x000416d74fd0f654, 0x0002ef040727064c, 0x00006e15c6114b50}, + {0x0002a398cfb1a76b, 0x0007419f2f6b14df, 0x00066e604311256c, 0x0005b444a4979620, 0x0000705b3aab4135}, + {0x000ef536d797b1d8, 0x000d622ddf0db365, 0x0000575a8800076b, 0x000ca4d3bbf33b0e, 0x00003777aa05c8e4}, + {0x000745c85578db5f, 0x00049dbae5ae2392, 0x000adc98676fda41, 0x0001da3b1f0b00b8, 0x000009963437d36f}, + {0x00024e90a5dc3853, 0x000641f135cbd7e8, 0x0007ce8fccccb5f6, 0x000249f6736d86c8, 0x0000625f3ce26604}, + {0x000ac8059502f63f, 0x0000a2e351469af8, 0x00064b63050c05e7, 0x0003ac335292e9c7, 0x00001a394360c7e2}, + {0x0006d53251183264, 0x000bd43c2b74fd5c, 0x000b973f9b62065a, 0x0006e5eb5fbf5d03, 0x000013a3da366120}, + {0x000d5837725d94e5, 0x00012205016c5c6b, 0x0000033c6818e309, 0x00079872088ce157, 0x00007fba1f495c83}, + {0x000c7423f2f9079d, 0x0007b34023fc55a8, 0x0002fab351173515, 0x000e33ce4f9b49ad, 0x00006691ff72c878}, + {0x000c2adedc5eff3e, 0x000f1d8956cf4122, 0x000e9e5bdaf8dd4b, 0x000c743eb86205d9, 0x0000049b92b9d975}, + {0x00079730b0f6c05a, 0x000acc6f3a553a53, 0x00020dcd6d72a0ff, 0x000164ab0032c34b, 0x0000470e9dbc88d5}, + {0x000cf10ca237c047, 0x000711f6c81a2b19, 0x000dd80b43b65466, 0x000be8eb3321bd16, 0x000048c14f600c5f}, + {0x00051c264aa6c803, 0x00004a4fa7da6664, 0x0003128395b66e39, 0x000bc10d45f19b0b, 0x000031602627c3c9}, + {0x0000dc4832e4e10d, 0x0006756c717f7312, 0x0007280294eb20c4, 0x000c50900f52e3f6, 0x0000566d4fc14730}, + {0x000a5d40fd837206, 0x000dc7159547a7e3, 0x00068d6095c1e926, 0x000cea7216730fba, 0x000022e8c3843f69}, + {0x000074e8930e4b2b, 0x0000e84d1581633d, 0x0006ba2365b6e435, 0x000f3f35534c26ad, 0x00007773c12f89f1}, + {0x000a404da57962aa, 0x000a81999ce568cb, 0x00021692fc5b9897, 0x000c291508e862f1, 0x00003a81907fa093}, + {0x000ed0ff4725a510, 0x00010673fc5030dd, 0x000f1f4e8910d8cc, 0x000a44c5b9d151c9, 0x000032a5c1d5cb09}, + {0x000aa442b90541fb, 0x0007cc1b485db1e0, 0x000a9df2e55f85eb, 0x0002236bee595ce8, 0x000025e496c72242}, + {0x000f3c46cd0fe5b9, 0x0007ed2a433885ed, 0x000761e35234e75a, 0x000545ce488de11d, 0x00000e878a01a085}, + {0x00093c77e021bb04, 0x00043c7df899aba4, 0x000ae80d672b4d18, 0x00017949ea37a487, 0x000067a9958011e4}, + {0x0008051a6697b065, 0x0007d8d6ba6d44b5, 0x0003ca46c147e33f, 0x000db0dbb4da8d48, 0x000068becaa181c2}, + {0x000980e90b989aa5, 0x0004a2c93c99b8d8, 0x00096e73a2f95eb1, 0x000b56951c6c7c47, 0x00006e228363b5ef}, + {0x000bc0b02dd624c8, 0x0007dec8170eec6b, 0x0004cfafa9777eb4, 0x000bf9b3cde15a00, 0x00001dc6bc087160}, + {0x0007e043eec34002, 0x000677a68dc7f2e0, 0x000bd15b9a18e9fc, 0x0008253d8da03188, 0x000048fbc3bb0056}, + {0x00047d4cfb654ce1, 0x00082a058e2ad575, 0x000f154478d3565b, 0x000bb18f63eaf0bb, 0x000047531ef114df}, + {0x000c630a4278c587, 0x00046ca8e83f3e1e, 0x000adc0c2b5507d5, 0x000844e85e135c63, 0x00000aa7efa85682}, + {0x00091ba8b3e1f615, 0x000701fbe3ffa726, 0x0009bb786832b4e9, 0x00039e897b6d92e3, 0x00002cfe53dea02e}, + {0x000392cd85cd52b0, 0x000c910e29831687, 0x0009832d0627ff66, 0x000f8a097134556a, 0x0000269bb0360a84}, + {0x000e55457643f85c, 0x0008c9b597d1b706, 0x0006efa4723734a4, 0x000d9e07aee91e8c, 0x00005cd6abc198a9}, + {0x0004de06cb3ce41a, 0x000893402e1380e0, 0x00086e3772d8c6eb, 0x000a8c8904659bb6, 0x00007215c371746b}, + {0x0002a97eeae4a2d9, 0x000516394f2c5fd1, 0x000208f2949514b7, 0x00026b9266fd5809, 0x00005c847085619a}, + {0x00085410fed694ea, 0x000934a2ed254529, 0x000d3be4673c905b, 0x000e9e110bb47692, 0x0000063b3d2d69e5}, + {0x000726eedda57deb, 0x000ae10f41891472, 0x000b307614efb6c4, 0x0005b7c2b1641917, 0x0000117c554fc4f4}, + {0x000cf3118f9d8812, 0x0002050017939c07, 0x00071b282701dbd8, 0x00025ead7e803f41, 0x00001015e87487d2}, + {0x000de3fed23acc4d, 0x000c294a7be2dc58, 0x000c9cf45750db91, 0x000524a0b94d43d1, 0x00006b1640fa6e37}, + {0x000f346c5fda0d09, 0x00059fa4d3151692, 0x000777a296200b1c, 0x000fbcfb8c46f760, 0x00004b38395f3ffd}, + {0x00025e00be54d671, 0x00082bec8aba618d, 0x000b78b98260d505, 0x000043287ad8f263, 0x000050fdf64e9cda}, + {0x000567aac578dcf0, 0x0000ef2a3133b90f, 0x0002d9de71ef1e9b, 0x00001c70eebba924, 0x000015473c9bf031}, + {0x0007e8ae56b78095, 0x000666e6f078e7c7, 0x000348ba1fb678e7, 0x0003f0b2da0b9615, 0x00007cf931c1ff73}, + {0x000357f50a0a366c, 0x000f42b87d73226b, 0x00091cb2c0e9708c, 0x000bb4cc13aeea5f, 0x000035d90c991143}, + {0x0001c404a9a0d9dc, 0x000451972d25147c, 0x0003b38c31659e58, 0x0001f243875a8c47, 0x00001fbd9ed37956}, + {0x000abc6fd41ec28d, 0x000e3cd2a2dca11f, 0x000c4045957ef8df, 0x0002f2772e73b5d8, 0x00006135fa4954b7}, + {0x000c32a2de24b69c, 0x0008c1f095d88ccf, 0x000ac3f9293f5569, 0x0007eebbe3350ed5, 0x00005e9bf806ca47}, + {0x000e8fb63c309f68, 0x0003565e1f9f4e9c, 0x000a6393f15376f6, 0x0003506d1afcfb35, 0x00006632a1ede562}, + {0x000d6c390c2ded4c, 0x00081df04cb1f0b7, 0x0009ecc3c756cb32, 0x000a72a66305a124, 0x00005d588b60a38c}, + {0x000cbf78e8e5f42d, 0x0004b3c8a3eeca6e, 0x000bd2160486eeb4, 0x0006731ec219c48f, 0x00001aaf1af517c3}, + {0x0006a2836769bde7, 0x000622b1e2adbc30, 0x000bff94a6208280, 0x000f26b8027f51ff, 0x000076cfa1ce1124}, + {0x000b00562422abb6, 0x000d58f8c29c318e, 0x000531561af377c4, 0x0008a274dbbc207f, 0x00000253b7f08212}, + {0x000f091cb62c17e0, 0x000abd64628a93d1, 0x00009d42534860e1, 0x000e57652d174363, 0x0000356f97e13efa}, + {0x0001e11aa150535b, 0x000bb1dd878ccd35, 0x000ed92c983e6b45, 0x00085b80c776128b, 0x00001d34ae930328}, + {0x0000488ca85ba4c3, 0x000c33c9ce6ce4ba, 0x0007bda770985348, 0x000124a66124c6f9, 0x00000f81a0290654}, + {0x00009ca6569b86fd, 0x000fd18af9a2d9ed, 0x0003d8c20a811009, 0x000f26bff08d03f9, 0x000052a148199fae}, + {0x0003f9dc2d8d1b73, 0x0001873961a703e0, 0x0001a35970420580, 0x000d549c0d987f04, 0x000007aa1f15a1c0}, + {0x00046ce08cd27224, 0x0004f934e4239dfd, 0x0009897b596d0a02, 0x00095a2808a7a639, 0x00000a4556e9e13d}, + {0x000a991fe9c13045, 0x00048fe7751b8d21, 0x000bf300359b0e85, 0x000f7215da643cb4, 0x000077db28d63940}, + {0x000eeb614adc9011, 0x0009ae8c411ebfc5, 0x000d1dcf74522941, 0x0004cb59ec3e7787, 0x0000340d053e216e}, + {0x0007af39b48df2b4, 0x0002871a10a94cac, 0x000ca575edc0faec, 0x0003a4c140a69245, 0x00000cf1c3713427}, + {0x000e306ac224b8a5, 0x0007ccb4930b0c8e, 0x000acbe74f57eaee, 0x000657da1e806bda, 0x00007d9a62742eeb}, + {0x0006b6ef546c4830, 0x0001fddb36e2e9eb, 0x000f0d7105885cca, 0x0000412e6b9f383e, 0x000058654fef9d2e}, + {0x0005c4ffbe0e8e26, 0x000df9b31816ea90, 0x00002e88e1942de5, 0x000408d497d723f8, 0x000030684dea602f}, + {0x0005a278a3e6cb34, 0x0006f5b151dc421e, 0x000d77ca15aefb6e, 0x0008981b30b8e049, 0x000028c3c9cf53b9}, + {0x000fb721556cdd2a, 0x000a897022274287, 0x000a5432580d317c, 0x000642f7468c7423, 0x00004a7f11464eb5}, + {0x0007a4774d193aa6, 0x0006ea92129a1a23, 0x00087c1a88d86598, 0x000f5eb24c515ecf, 0x0000604003575f39}, + {0x0009f189570a9b27, 0x000de465e4b7847b, 0x000bb85c202b98ce, 0x0001901026df551d, 0x000074fcd91047e2}, + {0x0002a90a23c1bfa3, 0x0004e478519f613e, 0x000af6cf440cb007, 0x0002dbe5ff1cbbe3, 0x000067fe5438be81}, + {0x000cf64fa40f05b0, 0x0002f32283787d13, 0x000f0d2aea054dfb, 0x0000d4e4173915b7, 0x0000482f144f1f61}, + {0x00010201b47f8234, 0x000929e70b990f62, 0x000049567c5d0ae1, 0x0006f01dcd7f455b, 0x00007e93d0f1f091}, + {0x0009cbf18a7db4fa, 0x000bf6f74c62fdd7, 0x000b8291bdbe8391, 0x0001705027145d14, 0x0000585a73ea2cbf}, + {0x000ca03e928a0db2, 0x000a5742857e7485, 0x0006d551a710fc01, 0x000db8a2f482edbd, 0x00000f0433b5048f}, + {0x000a2e8dd7dc6247, 0x000d38cd4819a60d, 0x0001f6669788b4c9, 0x0007d7513033ac00, 0x0000273b24fe3b36}, + {0x0008f66a31b3b9d4, 0x000a494df49d5c6e, 0x0008b23da7281514, 0x000e548d1726fdfc, 0x00004b3ae7d103de}, + {0x00056e19ce4b9d7e, 0x000f186e3c61cc62, 0x000b8ec145ff5c5c, 0x0006574acc63ca34, 0x000074621888fee6}, + {0x000f409645290a1e, 0x000e3263a962e956, 0x000ec2647bef0bf8, 0x0007502ed6a50eb5, 0x00000694283a9dca}, + {0x000b963643a2dcd1, 0x000ea09fc5353769, 0x0003397eab42b7c8, 0x000d63a4f002aee1, 0x000063005e2c19b7}, + {0x000736da63023bea, 0x0006db12a99b7ca6, 0x000537c5e1966c7f, 0x00089eeace09390c, 0x00000b696063a1aa}, + {0x00003e97288c56e5, 0x0009f938c8be8ebb, 0x000b717f71432a9f, 0x0009d97a6a5a93d5, 0x00001a5fb4c3e18f}, + {0x0004e7ad1c60cdce, 0x00043fc02c4a01c9, 0x0007c46a20ee202a, 0x0007b588dafe4d86, 0x00000a10263c8ac2}, + {0x000ea9dfe4432a4a, 0x0007bbe9277c5d0d, 0x000212c71a856af8, 0x0001e91ce8472acc, 0x00006f151b6d9bbb}, + {0x00076c527ceed56a, 0x000b7fbf8faec267, 0x000d4609cc7d211c, 0x0000c4237ae66a6f, 0x00001f81b702d277}, + {0x0000b057eac58392, 0x000fe29744e9d2fb, 0x0007beb4f8e1dd89, 0x000d41ec964f8eb1, 0x000029571073c9a2}, + {0x0008a18981c0e254, 0x0009b65b22830a94, 0x000fcfd3c62df636, 0x000a01fa33eb2d75, 0x0000078cd6ec4199}, + {0x00084a41ad900d2f, 0x00078e2c74c524a5, 0x000431c97832142b, 0x0009fc268c4e8338, 0x00007f69ea900868}, + {0x0002c81e46a38265, 0x0002d04a832fd52f, 0x0005359e94fd7807, 0x00029d28cd7d5fa2, 0x00004de71b7454cc}, + {0x000b60ad1eda6ac9, 0x000dfdbc09c3a42e, 0x00033cc1910aad37, 0x000803c81004b71e, 0x000044e6be345122}, + {0x000e8388ba1920db, 0x00032150db00803f, 0x000af60c29f5d57c, 0x0001aee49c8c4281, 0x000021edb518de70}, + {0x00063e418f06dc99, 0x00099c166d7b87fb, 0x000e520a83a4460d, 0x000835824dd5248c, 0x00005ec3ad712b92}, + {0x00022a5fbd17930f, 0x00077d82570e3150, 0x0005783712a4f64a, 0x0000abb12bc8d691, 0x0000498194c0fc62}, + {0x0002d9d255686c82, 0x000d9193e21f038a, 0x00024a5484785c6b, 0x0000989e4d5c81ab, 0x000056307860b2e2}, + {0x000d55f78b4d74c4, 0x0004643350131429, 0x0008c71fff22f183, 0x00083ef1e60c2459, 0x000059f2f0149799}, + {0x00047d56eb494a44, 0x00054d636a18e46a, 0x0004491c3b3e22a8, 0x000cde7b346e1527, 0x00002ceafd4e5390}, + {0x000a8538be0d6675, 0x000bb50818e23ba8, 0x0005d304c34b9074, 0x00092c4cbdab8908, 0x000061a24fe0e561}, + {0x000615e6db525bcb, 0x00035a567e4cacb7, 0x000afcdd69dd7d8c, 0x0009766e6b4153ac, 0x00002d668e097f3c}, + {0x000e7e265ce55ef0, 0x000527cd4b967a57, 0x00092fd1e55d9f4e, 0x000f7aefbc836064, 0x0000090d52beb7c3}, + {0x0009515a1e7b4d7c, 0x0002599da44c009b, 0x0002c555041f266a, 0x00015cca1c49548e, 0x00007ef04287126f}, + {0x0001659dbd30ef15, 0x000eec4e0277bfed, 0x0005df32918b4ab9, 0x000f788884d6236a, 0x00001fd96ea6bf5c}, + {0x000161981f190d9a, 0x000507e6052c142a, 0x00085a2cd561d849, 0x00085d89fe113bf2, 0x00007c22d676dbad}, + {0x000770ed2bfbd27d, 0x000ece996f5a582e, 0x00009001504c05b2, 0x000bf64cd40a9c2b, 0x00005895319213d9}, + {0x000c5d703fea2e08, 0x0001258e2188ce7c, 0x0008205bf0b50c49, 0x0002d62cce30baa4, 0x0000537c659ccfa3}, + {0x0006623a98cfc088, 0x0001fa4d6aca437b, 0x0006a8d1b0fe9bed, 0x000957504d29b8e5, 0x0000725f71c40b51}, + {0x0007f89cd0339ce6, 0x0004469ddc18b28c, 0x0006a1652c8367b1, 0x0006c17883ada83a, 0x0000585f1974034d}, + {0x000fb266f1b19188, 0x00063e7c3521789c, 0x0004c0526ae63b48, 0x0004635d88c9da6b, 0x00003e035c9df095}, + {0x000d5412fb45de9d, 0x00032e4cff40ddd9, 0x00051d671cdd6845, 0x000f6904b5c999b1, 0x00002d8c2cc811e7}, + {0x0004be1d90055d40, 0x000df464aaf407f5, 0x0000e917bea464c5, 0x0006b3033979624f, 0x00002c018dc52735}, + {0x00015024e330b3d4, 0x00096691652d3a54, 0x000f9b59f173ff3d, 0x0008e5a94ec42c4e, 0x00000747201618d0}, + {0x000ca48aca411c53, 0x0002fcfa661194d6, 0x0001e227ff66415f, 0x000f7eb9c4dd4005, 0x000059810bc09a02}, + {0x000eb171b3dc101d, 0x000b99ffef68e2a7, 0x0003b359ea441c5a, 0x000112f32025c9b9, 0x00005e8ce0a71e9d}, + {0x000ccb92429503fd, 0x000752f095d55bfc, 0x00072d091ed271ba, 0x00003ba345ead5e9, 0x000018c8df11a831}, + {0x000d949a9aed0f4c, 0x000cb6660e37e90c, 0x0006c52e0bc5d1f4, 0x0008e0db8cac52d5, 0x00006e42e400c580}, + {0x00046966eeaefd23, 0x0000be39ecdcaa3b, 0x000683a51d0c4f1f, 0x000351b189dc8c9d, 0x000051f27f054c09}, + {0x00087ccd2a320682, 0x0005bb3df1c964c4, 0x00055cb8e8587ea9, 0x000d73dc8ccf79e5, 0x0000547dc829a206}, + {0x0002a6cd80c39b06, 0x000732000d4c6b82, 0x0001463b4de96d54, 0x0006e1d28535b6f9, 0x0000228f4660e248}, + {0x00099538de8d3abf, 0x0000045ebca6e987, 0x000221e7388cd833, 0x000d2bb79952a008, 0x00004322e1a7535c}, + {0x0004c11819d1801c, 0x000d84f3f5ec7b11, 0x0009260f4c2016e4, 0x0007266dd0e2df40, 0x00005ec362c0ae5f}, + {0x00062b18b8b2b4ee, 0x00050274d1afbc04, 0x00036b02d27cc8d9, 0x000ccd3f25f71054, 0x000043bbf8dcbff9}, + {0x000d1767a039e9df, 0x000a8f69d3583b6a, 0x00042931f5b0714d, 0x00009615e55fa18b, 0x00004ed5558f33c6}, + {0x00037901c647a5dd, 0x0001f8081d3571fe, 0x00013fd7a6593ddf, 0x000af610249a4fd8, 0x000069acca274e9c}, + {0x000ba3ea330721c9, 0x000c20e7e1ea0047, 0x0001314a6083423f, 0x00095271df4c0af0, 0x000009a62dab8928}, + {0x000325a49cc6cb00, 0x000c654b56cb6a5b, 0x000dc994a0e94b5d, 0x0004aad3be28779a, 0x00004296e8f8ba3a}, + {0x000689761e451eab, 0x0008bff59594a328, 0x0007a7084a2e4d59, 0x00020a849b96853d, 0x00004980a3196014}, + {0x0005b9e12f552c42, 0x000db7100fe96956, 0x0003add0d78a5318, 0x0004eda05c90b4d4, 0x0000538b4cd66a5d}, + {0x00094fc3e89f039f, 0x000f26f618045f4e, 0x000d4b9550592c9a, 0x000141908a36eb5f, 0x000025fffaf6c2ed}, + {0x00034459cc79d354, 0x000b4b1d5476b344, 0x0001615d99eeecbf, 0x000b773ddeb34a06, 0x00005129cecceb64}, + {0x0003215894993520, 0x0007cf14c0b3bee4, 0x0006bedad5772f9c, 0x0006a97d2e2fce30, 0x0000715f42b546f0}, + {0x000ecdceda5b5f1a, 0x00015a49741a9434, 0x0003edad2e0da171, 0x0009041680bd77c7, 0x0000487c02354edd}, + {0x000feff3a70ed9c4, 0x000a3e857e302b8e, 0x0008a2a5a056a32a, 0x000c444df3a68bd4, 0x000007f650b73176}, + {0x000b9b1626e0ccb1, 0x000c18b09fb36e38, 0x0009f9496479e053, 0x000f5c456d90319c, 0x00001ca941e7ac9f}, + {0x0004df29162fa0bb, 0x0003282b3330549c, 0x000abb437d8488cf, 0x000ad8695dfda14c, 0x00003391f78264d5}, + {0x000ae06ae2b5095d, 0x000d73259a946729, 0x00013921edd58a58, 0x000b592e9834262d, 0x000027fedafaa54b}, + {0x000dc5b829ad48bb, 0x00042499ee260a99, 0x000d7513fd5f0257, 0x000d938802c8ecd5, 0x000078ceb3ef3f6d}, + {0x0002f44f8a135d94, 0x00044828cdda3c34, 0x000537cfe77b9edb, 0x000b4c89436d11a0, 0x00005064b164ec1a}, + {0x0000eccfd37eb2fc, 0x0003ed90d25fc702, 0x000fa1bb341f31ea, 0x00030441b930d7bd, 0x00005344467a4811}, + {0x00073170f25e6dfb, 0x0001a50114cc8700, 0x0008fc4f00e385dc, 0x00040d82348698ac, 0x00002a77a55284dd}, + {0x0006afe0c98c6ce4, 0x00096dddfd6e4fe0, 0x0003bf1ed3c235df, 0x000bdaf1428d01e3, 0x0000785768ec9300}, + {0x0002e57a91deb63b, 0x000bfe5ce8b80970, 0x000d1d58ac61bdb8, 0x00057bc645b426f3, 0x00004804a82227a5}, + {0x0007048ab44d2601, 0x0001a4b3a69358e5, 0x0009e1c29368d650, 0x00063e2c39c9ec3f, 0x00004172f257d4de}, + {0x0008b450330c6401, 0x00017418f2391d36, 0x0000b7d90d040d30, 0x000d51f2c34bb609, 0x000016f649228fdf}, + {0x0006818e2b928ef5, 0x00091cdc11e72bea, 0x00077a36cde28ccf, 0x000fd0f594aaa68e, 0x0000313034806c7f}, + {0x000d27ac2249bd65, 0x00064018e95128a9, 0x0002b37ec719a3b4, 0x0007b21c26ccff35, 0x0000056f68341d79}, + {0x0009d6757efd2327, 0x000b6553afe155e7, 0x000eaf5a60fabdbc, 0x000743bd3e7222c6, 0x00007046c76d4dae}, + {0x000be872b18d4a55, 0x00018574e1496660, 0x00002bdcbb199925, 0x0008e8ec103053a3, 0x00003ed8e9800b21}, + {0x000b9239fa75e03e, 0x000684633c0837b0, 0x00091a7793efe9fb, 0x000fe3498a35fbe3, 0x00006065510fe2d0}, + {0x000b668548abad0c, 0x00048da87e52755c, 0x000107c1ddb45845, 0x000de352c43ecea0, 0x0000526028809372}, + {0x0005c56af9213b1f, 0x0004d017e98db341, 0x0005cf709b5bee1a, 0x0009ab613f6b105b, 0x00005ff20e3482b2}, + {0x00029c75cc2e6c90, 0x000ca3a70e2060aa, 0x0004b5c515fc7d73, 0x000c207899fc38fc, 0x0000250386b124ff}, + {0x000a28d5ae3d2b56, 0x0009dd6de60ce54e, 0x000f06d6c1991314, 0x0008fc716694fc58, 0x000046b23975eb01}, + {0x000a6a0fb4b7b4e2, 0x0005a8f7253de470, 0x000fbd3adb5d9247, 0x0006968abeee5b52, 0x00007fa20801a080}, + {0x0003faf19f7714d2, 0x000c12f4660c376f, 0x000212744eb3e840, 0x0002dd20fb4cd8df, 0x00004b065a251d3a}, + {0x000bde383d77cd4a, 0x000df882c9cb15ce, 0x00009af7596adf39, 0x0006422a2dd242eb, 0x00003147c0e50e5f}, + {0x000ca5101d1350db, 0x00079c33fc962164, 0x0003e5da08f8d134, 0x000f8bae640ce4d1, 0x00004bdee0c45061}, + {0x00046dc1a4edb1c9, 0x000b6437fd98ad7c, 0x0002a1c00b5514d7, 0x000710e58942f6bb, 0x00002dffb2ab1d70}, + {0x000fcf2fc18b6d68, 0x000a8b7806167ccd, 0x000e2937e3a8ebcb, 0x0006e8c980697f95, 0x000002fbba1cd012}, + {0x0008c360adff4565, 0x000d24bdb1519cb9, 0x0005fb15d5447101, 0x000a27d98c4c8747, 0x000005f8c76d6e22}, + {0x0009e5dffeb9f494, 0x0009d18406b75ab6, 0x0004a42d1dae09c7, 0x000fa84199b45fb9, 0x000079710aebae2a}, + {0x000deda7f334d2df, 0x00051af2a57b4a6a, 0x0006dceaa87bde9c, 0x000d07ba98fc64f8, 0x00006bbe0335c20e}, +}; + +__ALIGN64 static const int64u U2_0[8] = + {0x000b1e0137d48290, 0x000b1e0137d48290, 0x000b1e0137d48290, 0x000b1e0137d48290, + 0x000b1e0137d48290, 0x000b1e0137d48290, 0x000b1e0137d48290, 0x000b1e0137d48290}; +__ALIGN64 static const int64u U2_1[8] = + {0x00051eb4d1207816, 0x00051eb4d1207816, 0x00051eb4d1207816, 0x00051eb4d1207816, + 0x00051eb4d1207816, 0x00051eb4d1207816, 0x00051eb4d1207816, 0x00051eb4d1207816}; +__ALIGN64 static const int64u U2_2[8] = + {0x000ca2b71d440f6a, 0x000ca2b71d440f6a, 0x000ca2b71d440f6a, 0x000ca2b71d440f6a, + 0x000ca2b71d440f6a, 0x000ca2b71d440f6a, 0x000ca2b71d440f6a, 0x000ca2b71d440f6a}; +__ALIGN64 static const int64u U2_3[8] = + {0x00054cb52385f46d, 0x00054cb52385f46d, 0x00054cb52385f46d, 0x00054cb52385f46d, + 0x00054cb52385f46d, 0x00054cb52385f46d, 0x00054cb52385f46d, 0x00054cb52385f46d}; +__ALIGN64 static const int64u U2_4[8] = + {0x0000215132111d83, 0x0000215132111d83, 0x0000215132111d83, 0x0000215132111d83, + 0x0000215132111d83, 0x0000215132111d83, 0x0000215132111d83, 0x0000215132111d83}; + +DLL_PUBLIC +mbx_status MB_FUNC_NAME(mbx_x25519_public_key_)(int8u* const pa_public_key[8], + const int8u* const pa_private_key[8]) +{ + mbx_status status = 0; + + /* test input pointers */ + if(NULL==pa_private_key || NULL==pa_public_key) { + status = MBX_SET_STS_ALL(MBX_STATUS_NULL_PARAM_ERR); + return status; + } + + /* check pointers and values */ + int buf_no; + for(buf_no=0; buf_no<8; buf_no++) { + const int64u* own_private = (const int64u*) pa_private_key[buf_no]; + const int64u* party_public = (const int64u*) pa_public_key[buf_no]; + + /* if any of pointer NULL set error status */ + if(NULL==own_private || NULL==party_public) { + status = MBX_SET_STS(status, buf_no, MBX_STATUS_NULL_PARAM_ERR); + continue; + } + } + + /* continue processing if there are correct parameters */ + if( MBX_IS_ANY_OK_STS(status) ) { + + /* convert private to to MB8 and decode */ + __ALIGN64 U64 scalar_mb8[4]; + ifma_BNU_transpose_copy((int64u (*)[8])scalar_mb8, (const int64u * const*)pa_private_key, 256); + /* decode keys into scalars according to RFC4448 */ + scalar_mb8[0] = and64_const(scalar_mb8[0], 0xfffffffffffffff8); + scalar_mb8[3] = and64_const(scalar_mb8[3], 0x7fffffffffffffff); + scalar_mb8[3] = or64(scalar_mb8[3], set64(0x4000000000000000)); + + /* set up: "special" point S = {1:?:1} => {u1:z1} */ + __ALIGN64 U64 U1[5]; + __ALIGN64 U64 Z1[5]; + fe52mb8_set(U1, 1); + fe52mb8_set(Z1, 1); + + /* set up: pre-computed G-S (base and "special") */ + __ALIGN64 U64 Z2[5]; + __ALIGN64 U64 U2[5] = { loadu64(U2_0), loadu64(U2_1), loadu64(U2_2), loadu64(U2_3), loadu64(U2_4) }; + fe52mb8_set(Z2, 1); + + __ALIGN64 U64 A[5], B[5], C[5], D[5]; + + /* + scalar template is usual [01xx..xxx] [xxx..xxx] [xxx..xxx] [xxx..000] + processing scalar in L->R fashion: + - first process scalar' = scalar >>3 + - than 3 doubling + */ + __mb_mask swap = get_mask(0xff); + + /* read low and remove (zero) bits 0,1,2 */ + U64 e = loadu64(&scalar_mb8[0]); + e = srli64(e, 3); + + int bitpos; + for (bitpos=3; bitpos<255; bitpos++) { + if(0==(bitpos%64)) + e = loadu64(&scalar_mb8[bitpos/64]); + + __mb_mask b = cmp64_mask(and64_const(e, 1), get_zero64(), _MM_CMPINT_NE); + + swap = mask_xor (swap, b); + fe52mb8_cswap(U1, U2, swap); + fe52mb8_cswap(Z1, Z2, swap); + swap = b; + + /* load mu = muTBL[bitpos-3] */ + U64 mu[5]; + mu[0] = set64((long long)muTBL52[bitpos-3][0]); + mu[1] = set64((long long)muTBL52[bitpos-3][1]); + mu[2] = set64((long long)muTBL52[bitpos-3][2]); + mu[3] = set64((long long)muTBL52[bitpos-3][3]); + mu[4] = set64((long long)muTBL52[bitpos-3][4]); + + /* diff addition */ + fe52_sub(B, U1, Z1); /* B = U1-Z1 */ + fe52_add(A, U1, Z1); /* A = U1+Z1 */ + fe52_mul(C, mu, B); /* C = mu*B */ + fe52_sub(B, A, C); /* B = (U1+Z1) - mu*(U1-Z1) */ + fe52_add(A, A, C); /* A = (Ur+Z1) + mu*(U1-Z1) */ + ed25519_sqr_dual(A, B, A, B); + ed25519_mul_dual(U1, Z1, Z2, A, U2, B); + + e = srli64(e, 1); + } + + /* 3 doublings */ + for(bitpos=0; bitpos<3; bitpos++) { + fe52_add(A, U1, Z1); /* A = U1+Z1 */ + fe52_sub(B, U1, Z1); /* B = U1-Z1 */ + fe52_sqr(A, A); /* A = A^2 */ + fe52_sqr(B, B); /* B = B^*2 */ + fe52_sub(C, A, B); /* C = A-B */ + fe52_mul121666(D, C); /* D = (A+2)/4 * C*/ + fe52_add(D, D, B); /* D = D+B */ + fe52_mul(U1, A, B); /* U1 = A*B */ + fe52_mul(Z1, C, D); /* Z1 = C*D */ + } + + fe52mb8_inv_mod25519(A, Z1); + fe52_mul(U1, U1, A); + fe52mb8_red_p25519(U1, U1); + + /* convert result back */ + ifma_mb8_to_BNU((int64u * const*)pa_public_key, (const int64u (*)[8])U1, 256); + + /* clear secret */ + MB_FUNC_NAME(zero_)((int64u (*)[8])scalar_mb8, sizeof(scalar_mb8)/sizeof(U64)); + } + + return status; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_alias_avx512.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_alias_avx512.h new file mode 100644 index 000000000..b59534729 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_alias_avx512.h @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_MATH_AVX512_H +#define IFMA_MATH_AVX512_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include + +typedef __m512i m512; +typedef __mmask8 mask8; +typedef __mmask64 mask64; + +/* set */ +#define setzero_i64 _mm512_setzero_si512 +#define set1_i64 _mm512_set1_epi64 + +#if 0 +/* Note: intrinsics below not available in GCC 8.4 */ +#define set_i8 _mm512_set_epi8 +#define set_i16 _mm512_set_epi16 +#endif + +#define set_i64 _mm512_set_epi64 + +/* load/store */ +#define loadu_i64 _mm512_loadu_si512 +#define maskz_loadu_i64 _mm512_maskz_loadu_epi64 +#define storeu_i64 _mm512_storeu_si512 +#define mask_storeu_i64 _mm512_mask_storeu_epi64 + +/* logical shift */ +#define srli_i64 _mm512_srli_epi64 +#define srlv_i64 _mm512_srlv_epi64 +#define slli_i64 _mm512_slli_epi64 +#define sllv_i64 _mm512_sllv_epi64 + +/* arithmetic shift */ +#define srai_i64 _mm512_srai_epi64 +#define maskz_srai_i64 _mm512_maskz_srai_epi64 +#define maskz_srli_i64 _mm512_maskz_srli_epi64 + +/* logical */ +#define and_i64 _mm512_and_epi64 +#define or_i64 _mm512_or_si512 + +/* add */ +#define add_i64 _mm512_add_epi64 +#define mask_add_i64 _mm512_mask_add_epi64 + +/* sub */ +#define sub_i64 _mm512_sub_epi64 +#define mask_sub_i64 _mm512_mask_sub_epi64 + +/* cmp */ +#define cmp_i64_mask _mm512_cmp_epi64_mask +#define cmp_u64_mask _mm512_cmp_epu64_mask + +/* perm */ +#define maskz_permutexvar_i8 _mm512_maskz_permutexvar_epi8 +#define permutexvar_i8 _mm512_permutexvar_epi8 +#define permutexvar_i16 _mm512_permutexvar_epi16 + +/* move */ +#define mask_mov_i64 _mm512_mask_mov_epi64 + +/* ifma */ +#define madd52lo_i64 _mm512_madd52lo_epu64 +#define madd52hi_i64 _mm512_madd52hi_epu64 + +#define alignr_i64 _mm512_alignr_epi64 + +#endif // if (_IPP32E >= _IPP32E_K1) + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_alias_avx512vl.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_alias_avx512vl.h new file mode 100644 index 000000000..e578bf899 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_alias_avx512vl.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_ALIAS_AVX512VL_H +#define IFMA_ALIAS_AVX512VL_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include + +typedef __m256i m256i; +typedef __mmask8 mask8; +typedef __mmask32 mask32; +typedef __mmask64 mask64; + +/* load/store */ +#define m256_loadu_i64(A) _mm256_maskz_loadu_epi64(0xFF, (A)) +#define m256_maskz_loadu_i64 _mm256_maskz_loadu_epi64 +#define m256_storeu_i64(R, A) _mm256_mask_storeu_epi64((R), 0xFF, (A)) +#define m256_mask_storeu_i64 _mm256_mask_storeu_epi64 +/* cmp */ +#define m256_cmp_i64_mask _mm256_cmp_epi64_mask +/* mov */ +#define m256_mask_mov_i64 _mm256_mask_mov_epi64 +/* set */ +#define m256_setzero_i64 _mm256_setzero_si256 +#define m256_set_i8 _mm256_set_epi8 +#define m256_set_i16 _mm256_set_epi16 +#define m256_set_i64 _mm256_set_epi64x +#define m256_set1_i64 _mm256_set1_epi64x +/* shift permutexvar */ +#define m256_permutexvar_i8 _mm256_permutexvar_epi8 +#define m256_permutexvar_i16 _mm256_permutexvar_epi16 +#define m256_maskz_permutexvar_i8 _mm256_maskz_permutexvar_epi8 +/* shift logic/arithmetic */ +#define m256_srli_i64 _mm256_srli_epi64 +#define m256_slli_i64 _mm256_slli_epi64 +#define m256_srlv_i64 _mm256_srlv_epi64 +#define m256_sllv_i64 _mm256_sllv_epi64 +#define m256_srai_i64 _mm256_srai_epi64 +#define m256_maskz_srli_i64 _mm256_maskz_srli_epi64 +#define m256_maskz_srai_i64 _mm256_maskz_srai_epi64 +#define m256_maskz_slli_i64 _mm256_maskz_slli_epi64 +#define m256_alignr_i64 _mm256_alignr_epi64 +/* and/or */ +#define m256_and_i64 _mm256_and_si256 +#define m256_or_i64 _mm256_or_si256 +/* add/sub */ +#define m256_add_i64 _mm256_add_epi64 +#define m256_mask_add_i64 _mm256_mask_add_epi64 +#define m256_maskz_add_i64 _mm256_maskz_add_epi64 +#define m256_sub_i64 _mm256_sub_epi64 +#define m256_mask_sub_i64 _mm256_mask_sub_epi64 +/* ifma */ +#define m256_madd52lo_i64 _mm256_madd52lo_epu64 +#define m256_madd52hi_i64 _mm256_madd52hi_epu64 +#define m256_maskz_madd52lo_i64 _mm256_maskz_madd52lo_epu64 +#define m256_maskz_madd52hi_i64 _mm256_maskz_madd52hi_epu64 + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method.h new file mode 100644 index 000000000..fdf4c88df --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method.h @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_METHOD_H +#define IFMA_ARITH_METHOD_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "owncp.h" +#include "ifma_alias_avx512.h" + +/* Modular arith methods based on 2^52 radix number representation */ +IPP_OWN_FUNPTR(m512, ifma_import, (const Ipp64u *arad64)) +IPP_OWN_FUNPTR(void, ifma_export, (Ipp64u *rrad64, const m512 arad52)) +IPP_OWN_FUNPTR(m512, ifma_encode, (const m512 a)) +IPP_OWN_FUNPTR(m512, ifma_decode, (const m512 a)) +IPP_OWN_FUNPTR(m512, ifma_mul, (const m512 a, const m512 b)) +IPP_OWN_FUNPTR(void, ifma_mul_dual, (m512 *r1, const m512 a1, const m512 b1, m512 *r2, const m512 a2, const m512 b2)) +IPP_OWN_FUNPTR(m512, ifma_sqr, (const m512 a)) +IPP_OWN_FUNPTR(void, ifma_sqr_dual, (m512 * r1, const m512 a1, m512 *r2, const m512 a2)) +IPP_OWN_FUNPTR(m512, ifma_norm, (const m512 a)) +IPP_OWN_FUNPTR(void, ifma_norm_dual, (m512 *r1, const m512 a1, m512 *r2, const m512 a2)) +IPP_OWN_FUNPTR(m512, ifma_lnorm, (const m512 a)) +IPP_OWN_FUNPTR(void, ifma_lnorm_dual, (m512 *r1, const m512 a1, m512 *r2, const m512 a2)) +IPP_OWN_FUNPTR(m512, ifma_add, (const m512 a, const m512 b)) +IPP_OWN_FUNPTR(m512, ifma_sub, (const m512 a, const m512 b)) +IPP_OWN_FUNPTR(m512, ifma_neg, (const m512 a)) +IPP_OWN_FUNPTR(m512, ifma_div2, (const m512 a)) +IPP_OWN_FUNPTR(m512, ifma_inv, (const m512 z)) +IPP_OWN_FUNPTR(m512, ifma_red, (const m512 a)) + +typedef struct _ifmaArithMethod { + ifma_import import_to52; + ifma_export export_to64; + ifma_encode encode; + ifma_decode decode; + ifma_mul mul; + ifma_mul_dual mul_dual; + ifma_sqr sqr; + ifma_sqr_dual sqr_dual; + ifma_norm norm; + ifma_norm_dual norm_dual; + ifma_lnorm lnorm; + ifma_lnorm_dual lnorm_dual; + ifma_add add; + ifma_sub sub; + ifma_neg neg; + ifma_div2 div2; + ifma_inv inv; + ifma_red red; +} ifmaArithMethod; + + +/* Pre-defined AVX512IFMA ISA based methods */ +#define gsArithGF_p256r1_avx512 OWNAPI(gsArithGF_p256r1_avx512) +IPP_OWN_DECL(ifmaArithMethod *, gsArithGF_p256r1_avx512, (void)) + +#define gsArithGF_n256r1_avx512 OWNAPI(gsArithGF_n256r1_avx512) +IPP_OWN_DECL(ifmaArithMethod *, gsArithGF_n256r1_avx512, (void)) + +#define gsArithGF_p384r1_avx512 OWNAPI(gsArithGF_p384r1_avx512) +IPP_OWN_DECL(ifmaArithMethod *, gsArithGF_p384r1_avx512, (void)) + +#define gsArithGF_n384r1_avx512 OWNAPI(gsArithGF_n384r1_avx512) +IPP_OWN_DECL(ifmaArithMethod *, gsArithGF_n384r1_avx512, (void)) + +static __NOINLINE void clear_secrets(m512 *a, m512 *b, m512 *c) +{ + if (NULL != a) + *a = setzero_i64(); + if (NULL != b) + *b = setzero_i64(); + if (NULL != c) + *c = setzero_i64(); +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ + +#endif /* #ifndef IFMA_ARITH_METHOD_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n256.c new file mode 100644 index 000000000..5cfba320b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n256.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_arith_method.h" +#include "ecnist/ifma_arith_p256.h" +#include "ecnist/ifma_arith_n256.h" + +IPP_OWN_DEFN(ifmaArithMethod *, gsArithGF_n256r1_avx512, (void)) +{ + static ifmaArithMethod m = { + /* import_to52 = */ convert_radix_to_52x5, + /* export_to64 = */ convert_radix_to_64x4, + /* encode = */ ifma_tomont52_n256, + /* decode = */ ifma_frommont52_n256, + /* mul = */ ifma_amm52_n256, + /* mul_dual = */ 0, + /* sqr = */ 0, + /* sqr_dual = */ 0, + /* norm = */ 0, + /* norm_dual = */ 0, + /* lnorm = */ 0, + /* lnorm_dual = */ 0, + /* add = */ ifma_add52_n256, + /* sub = */ 0, + /* neg = */ 0, + /* div2 = */ 0, + /* inv = */ ifma_aminv52_n256, + /* red = */ ifma_fastred52_n256 + }; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n384.c new file mode 100644 index 000000000..288b262f5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n384.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_arith_method.h" +#include "ecnist/ifma_arith_p384.h" +#include "ecnist/ifma_arith_n384.h" + +IPP_OWN_DEFN(ifmaArithMethod *, gsArithGF_n384r1_avx512, (void)) +{ + static ifmaArithMethod m = { + /* import_to52 = */ convert_radix_to_52x8, + /* export_to64 = */ convert_radix_to_64x6, + /* encode = */ ifma_tomont52_n384, + /* decode = */ ifma_frommont52_n384, + /* mul = */ ifma_amm52_n384, + /* mul_dual = */ 0, + /* sqr = */ 0, + /* sqr_dual = */ 0, + /* norm = */ 0, + /* norm_dual = */ 0, + /* lnorm = */ 0, + /* lnorm_dual = */ 0, + /* add = */ ifma_add52_n384, + /* sub = */ 0, + /* neg = */ 0, + /* div2 = */ 0, + /* inv = */ ifma_aminv52_n384, + /* red = */ ifma_fastred52_n384 + }; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n521.c new file mode 100644 index 000000000..18ad7bc30 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_n521.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_arith_method_p521.h" +#include "ecnist/ifma_arith_p521.h" +#include "ecnist/ifma_arith_n521.h" + +IPP_OWN_DEFN(ifmaArithMethod_p521 *, gsArithGF_n521r1_avx512, (void)) +{ + static ifmaArithMethod_p521 m = { + convert_radix_to_52_p521, + convert_radix_to_64_p521, + ifma_tomont52_n521, + ifma_frommont52_n521, + ifma_amm52_n521, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ifma_add52_n521, + 0, + 0, + ifma_aminv52_n521, + ifma_fastred52_n521 + }; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p256.c new file mode 100644 index 000000000..75f3cdcd7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p256.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_arith_method.h" +#include "ecnist/ifma_arith_p256.h" + +IPP_OWN_DEFN(ifmaArithMethod *, gsArithGF_p256r1_avx512, (void)) +{ + static ifmaArithMethod m = { + /* import_to52 = */ convert_radix_to_52x5, + /* export_to64 = */ convert_radix_to_64x4, + /* encode = */ ifma_tomont52_p256, + /* decode = */ ifma_frommont52_p256, + /* mul = */ ifma_amm52_p256, + /* mul_dual = */ ifma_amm52_dual_p256, + /* sqr = */ ifma_ams52_p256, + /* sqr_dual = */ ifma_ams52_dual_p256, + /* norm = */ ifma_norm52, + /* norm_dual = */ ifma_norm52_dual, + /* lnorm = */ ifma_lnorm52, + /* lnorm_dual = */ ifma_lnorm52_dual, + /* add = */ 0, + /* sub = */ 0, + /* neg = */ ifma_neg52_p256, + /* div2 = */ ifma_half52_p256, + /* inv = */ ifma_aminv52_p256, + /* red = */ 0 + }; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p384.c new file mode 100644 index 000000000..db462914a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p384.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_arith_method.h" +#include "ecnist/ifma_arith_p384.h" + +IPP_OWN_DEFN(ifmaArithMethod *, gsArithGF_p384r1_avx512, (void)) +{ + static ifmaArithMethod m = { + /* import_to52 = */ convert_radix_to_52x8, + /* export_to64 = */ convert_radix_to_64x6, + /* encode = */ ifma_tomont52_p384, + /* decode = */ ifma_frommont52_p384, + /* mul = */ ifma_amm52_p384, + /* mul_dual = */ ifma_amm52_dual_p384, + /* sqr = */ ifma_ams52_p384, + /* sqr_dual = */ ifma_ams52_dual_p384, + /* norm = */ ifma_norm52, + /* norm_dual = */ ifma_norm52_dual, + /* lnorm = */ ifma_lnorm52, + /* lnorm_dual = */ ifma_lnorm52_dual, + /* add = */ 0, + /* sub = */ 0, + /* neg = */ ifma_neg52_p384, + /* div2 = */ ifma_half52_p384, + /* inv = */ ifma_aminv52_p384, + /* red = */ 0 + }; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p521.c new file mode 100644 index 000000000..9188b9c5d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p521.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_arith_method_p521.h" +#include "ecnist/ifma_arith_p521.h" + +IPP_OWN_DEFN(ifmaArithMethod_p521 *, gsArithGF_p521r1_avx512, (void)) +{ + static ifmaArithMethod_p521 m = { + convert_radix_to_52_p521, + convert_radix_to_64_p521, + ifma_tomont52_p521, + ifma_frommont52_p521, + ifma_amm52_p521, + ifma_amm52_dual_p521, + ifma_ams52_p521, + ifma_ams52_dual_p521, + ifma_norm52_p521, + ifma_norm52_dual_p521, + ifma_lnorm52_p521, + ifma_lnorm52_dual_p521, + 0, + ifma_neg52_p521, + ifma_half52_p521, + ifma_aminv52_p521, + 0 + }; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p521.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p521.h new file mode 100644 index 000000000..83a39a59a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_method_p521.h @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_ARITH_METHOD_P521_H +#define IFMA_ARITH_METHOD_P521_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_defs_p521.h" + +/* Modular arith methods based on 2^52 radix number representation */ +IPP_OWN_FUNPTR(void, ifma_import, (fe521 pr[], const Ipp64u arad64[P521R1_LEN64])) +IPP_OWN_FUNPTR(void, ifma_export, (Ipp64u rrad64[P521R1_LEN64], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_encode, (fe521 pr[], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_decode, (fe521 pr[], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_mul, (fe521 pr[], const fe521 a, const fe521 b)) +IPP_OWN_FUNPTR(void, ifma_mul_dual, (fe521 pr1[], const fe521 a1, const fe521 b1, fe521 pr2[], const fe521 a2, const fe521 b2)) +IPP_OWN_FUNPTR(void, ifma_sqr, (fe521 pr[], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_sqr_dual, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) +IPP_OWN_FUNPTR(void, ifma_norm, (fe521 pr[], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_norm_dual, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) +IPP_OWN_FUNPTR(void, ifma_lnorm, (fe521 pr[], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_lnorm_dual, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) +IPP_OWN_FUNPTR(void, ifma_add, (fe521 pr[], const fe521 a, const fe521 b)) +IPP_OWN_FUNPTR(void, ifma_div2, (fe521 pr[], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_neg, (fe521 pr[], const fe521 a)) +IPP_OWN_FUNPTR(void, ifma_inv, (fe521 pr[], const fe521 z)) +IPP_OWN_FUNPTR(void, ifma_red, (fe521 pr[], const fe521 a)) + +typedef struct _ifmaArithMethod_p521 { + ifma_import import_to52; + ifma_export export_to64; + ifma_encode encode; + ifma_decode decode; + ifma_mul mul; + ifma_mul_dual mul_dual; + ifma_sqr sqr; + ifma_sqr_dual sqr_dual; + ifma_norm norm; + ifma_norm_dual norm_dual; + ifma_lnorm lnorm; + ifma_lnorm_dual lnorm_dual; + ifma_add add; + ifma_neg neg; + ifma_div2 div2; + ifma_inv inv; + ifma_red red; +} ifmaArithMethod_p521; + +/* Pre-defined AVX512IFMA ISA based methods */ +#define gsArithGF_p521r1_avx512 OWNAPI(gsArithGF_p521r1_avx512) +IPP_OWN_DECL(ifmaArithMethod_p521 *, gsArithGF_p521r1_avx512, (void)) + +#define gsArithGF_n521r1_avx512 OWNAPI(gsArithGF_n521r1_avx512) +IPP_OWN_DECL(ifmaArithMethod_p521 *, gsArithGF_n521r1_avx512, (void)) + +static __NOINLINE void clear_secrets(fe521 *a, fe521 *b, fe521 *c) +{ + if (NULL != a) + FE521_SET(*a) = m256_setzero_i64(); + if (NULL != b) + FE521_SET(*b) = m256_setzero_i64(); + if (NULL != c) + FE521_SET(*c) = m256_setzero_i64(); +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ + +#endif /* #ifndef IFMA_ARITH_METHOD_P521_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n256.c new file mode 100644 index 000000000..13e36ac70 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n256.c @@ -0,0 +1,255 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_n256.h" +#include "ifma_arith_p256.h" +#include "ifma_defs.h" + +/* Constants */ +#define LEN52 (5 + 3) /* 5 digits + 3 zero padding */ + +/* + * EC NIST-P256 base point order + * in 2^52 radix + */ +static const __ALIGN64 Ipp64u n256_x1[LEN52] = { + 0x0009cac2fc632551, 0x000ada7179e84f3b, 0x000fffffffbce6fa, 0x0000000fffffffff, 0x0000ffffffff0000, 0x0, 0x0, 0x0 +}; + +static const __ALIGN64 Ipp64u n256_x2[LEN52] = { + 0x00039585f8c64aa2, 0x0005b4e2f3d09e77, 0x000fffffff79cdf5, 0x0000001fffffffff, 0x0001fffffffe0000, 0x0, 0x0, 0x0 +}; + +/* k0 = (-1/n256) mod 2^52 */ +static const __ALIGN64 Ipp64u n256_k0 = 0x1c8aaee00bc4f; + +/* + * r = 2^((52*5)) mod n256 + */ +static const __ALIGN64 Ipp64u n256_r[LEN52] = { + 0x000353d039cdaaf0, 0x000258e8617b0c46, 0x0000000004319055, 0x000fff0000000000, 0x00000000000fffff, 0x0, 0x0, 0x0 +}; + +/* To Montgomery conversion constant + * r = 2^((52*5)*2) mod n256 + */ +static const __ALIGN64 Ipp64u n256_rr[LEN52] = { + 0x0005cc0dea6dc3ba, 0x000192a067d8a084, 0x000bec59615571bb, 0x0001fc245b2392b6, 0x0000e12d9559d956, 0x0, 0x0, 0x0 +}; + +static const __ALIGN64 Ipp64u ones[LEN52] = { + 1, 0, 0, 0, 0, 0, 0, 0 +}; + +#define MUL_RED_ROUND(R, A, B, IDX) \ + { \ + const m512 Bi = permutexvar_i8(idx_b##IDX, (B)); \ + m512 Rlo = madd52lo_i64(zero, (A), Bi); \ + m512 tmp = madd52hi_i64(zero, (A), Bi); \ + \ + (R) = add_i64((R), Rlo); \ + /* broadcast R[0] */ \ + const m512 R0 = permutexvar_i8(idx_b0, (R)); \ + const m512 Yi = madd52lo_i64(zero, k0, R0); \ + (R) = madd52lo_i64((R), N, Yi); \ + tmp = madd52hi_i64(tmp, N, Yi); \ + /* shift */ \ + const m512 carry = maskz_srli_i64(maskone, (R), DIGIT_SIZE); \ + tmp = add_i64(tmp, carry); \ + (R) = maskz_permutexvar_i8(mask_sr64, idx_sr64, (R)); \ + /* hi */ \ + (R) = add_i64((R), tmp); \ + } + +/* R = (A*B) */ +IPP_OWN_DEFN(m512, ifma_amm52_n256, (const m512 a, const m512 b)) +{ + const m512 N = loadu_i64(n256_x1); /* modulus */ + const m512 k0 = set1_i64(n256_k0); /* k0 */ + const m512 zero = setzero_i64(); + const mask8 maskone = 0x1; + + /* Index broadcast */ + const m512 idx_b0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const m512 idx_b1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const m512 idx_b2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const m512 idx_b3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const m512 idx_b4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + + /* Mask to shift zmm register right on 64-bit */ + const mask64 mask_sr64 = 0x00ffffffffffffff; + const m512 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 r = setzero_i64(); + + MUL_RED_ROUND(r, a, b, 0) + MUL_RED_ROUND(r, a, b, 1) + MUL_RED_ROUND(r, a, b, 2) + MUL_RED_ROUND(r, a, b, 3) + MUL_RED_ROUND(r, a, b, 4) + + r = ifma_lnorm52(r); + + return r; +} + +IPP_OWN_DEFN(m512, ifma_add52_n256, (const m512 a, const m512 b)) +{ + const m512 zero = setzero_i64(); + const m512 Nx2 = loadu_i64(n256_x2); + + /* r = a + b */ + m512 r = add_i64(a, b); + r = ifma_lnorm52(r); + + /* t = r - N */ + m512 t = sub_i64(r, Nx2); + t = ifma_norm52(t); + + /* lt = t < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(t, DIGIT_SIZE - 1), _MM_CMPINT_LT); + const mask8 mask = check_bit(lt, 4); // check sign in 5h digit + /* mask != 0 ? r : t */ + r = mask_mov_i64(t, mask, r); + + return r; +} + +static m512 ifma_ams52_n256(const m512 a) +{ + return ifma_amm52_n256(a, a); +} + +IPP_OWN_DEFN(m512, ifma_fastred52_n256, (const m512 a)) +{ + const m512 N = loadu_i64(n256_x1); + const m512 zero = setzero_i64(); + + /* r = a - N */ + m512 r = sub_i64(a, N); + r = ifma_norm52(r); + + /* 1 < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(r, DIGIT_SIZE - 1), _MM_CMPINT_LT); + const mask8 mask = check_bit(lt, 4); // check sign in 5th digit + + /* mask != 0 ? a : r */ + r = mask_mov_i64(r, mask, a); + return r; +} + +IPP_OWN_DEFN(m512, ifma_tomont52_n256, (const m512 a)) +{ + return ifma_amm52_n256(a, loadu_i64(n256_rr)); +} + +IPP_OWN_DEFN(m512, ifma_frommont52_n256, (const m512 a)) +{ + m512 r = ifma_amm52_n256(a, loadu_i64(ones)); + return ifma_fastred52_n256(r); +} + +#define sqr(R, A) (R) = ifma_ams52_n256((A)) +#define mul(R, A, B) (R) = ifma_amm52_n256((A), (B)) + +/* + * computes r = 1/z = z^(n256-2) mod n256 + * + * note: z in in Montgomery domain + * r in Montgomery domain + */ +__INLINE m512 ifma_ams52_n256_ntimes(const m512 a, int n) +{ + m512 r = a; + for (; n > 0; --n) { + sqr(r, r); + } + return r; +} + +#define sqr_ntimes(R, A, N) (R) = ifma_ams52_n256_ntimes((A), (N)) + +/* + * computes r = 1/z = z^(n256-2) mod n256 + * + * note: z is in Montgomery domain + * (as soon mul() and sqr() below are amm-functions, + * the result is in Montgomery domain too) + */ + +IPP_OWN_DEFN(m512, ifma_aminv52_n256, (const m512 z)) +{ + const m512 r_n256 = loadu_i64(n256_r); + int i; + + // pwr_z_Tbl[i][] = z^i, i=0,..,15 + __ALIGN64 m512 pwr_z_tbl[16]; + m512 r; + + pwr_z_tbl[0] = r_n256; + pwr_z_tbl[1] = z; + for (i = 2; i < 16; i += 2) { + sqr(pwr_z_tbl[i], pwr_z_tbl[i / 2]); + mul(pwr_z_tbl[i + 1], pwr_z_tbl[i], z); + } + + // pwr = (n256-2) in big endian + Ipp8u pwr[] = "\xFF\xFF\xFF\xFF\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84" + "\xF3\xB9\xCA\xC2\xFC\x63\x25\x4F"; + // init r = 1 + r = r_n256; + + for (i = 0; i < 32; i++) { + int v = pwr[i]; + int hi = (v >> 4) & 0xF; + int lo = v & 0xF; + + sqr(r, r); + sqr(r, r); + sqr(r, r); + sqr(r, r); + if (hi) + mul(r, r, pwr_z_tbl[hi]); + sqr(r, r); + sqr(r, r); + sqr(r, r); + sqr(r, r); + if (lo) + mul(r, r, pwr_z_tbl[lo]); + } + + return r; +} + +#undef sqr +#undef mul +#undef sqr_ntimes + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n256.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n256.h new file mode 100644 index 000000000..e6d1d3419 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n256.h @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#if !defined(_IFMA_ARITH_N256R1_H_) +#define _IFMA_ARITH_N256R1_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_alias_avx512.h" + +/** + * \brief + * + * Montgomery multiplication + * + * a * b * R mod n, where R = 2^(6*52) mod n + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_amm52_n256, (const m512 a, const m512 b)) + +/** + * \brief + * + * A + B (mod n) + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_add52_n256, (const m512 a, const m512 b)) + +/** + * \brief + * + * Reduction modulo n (subgroup order). + * + * (a >= n256) ? a - n256 : a + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_fastred52_n256, (const m512 a)) + +/** + * \brief + * + * Conversion to Montgomery domain modulo n (subgroup order). + * + * a * R mod n, where R = 2^(6*52) mod n + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_tomont52_n256, (const m512 a)) + +/** + * \brief + * + * Conversion from Montgomery domain modulo n (subgroup order). + * + * a mod n + * + * \param[in] p value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_frommont52_n256, (const m512 a)) + +/** + * \brief + * + * Modular inverse modulo n (subgroup order). + * + * 1/z mod n + * + * \param[in] z value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_aminv52_n256, (const m512 z)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ARITH_N256R1_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n384.c new file mode 100644 index 000000000..bc0cc0371 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n384.c @@ -0,0 +1,299 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_n384.h" +#include "ifma_arith_p384.h" +#include "ifma_defs.h" + +/* Constants */ +#define LEN52 (NUMBER_OF_DIGITS(384, 52)) + +/* + * EC NIST-P384 base point order + * in 2^52 radix + */ +static const __ALIGN64 Ipp64u n384_x1[LEN52] = { + 0x000c196accc52973, 0x000b248b0a77aece, 0x0004372ddf581a0d, 0x000ffffc7634d81f, 0x000fffffffffffff, 0x000fffffffffffff, 0x000fffffffffffff, 0x00000000000fffff +}; + +/* k0 = (-1/n384) mod 2^52 */ +static const __ALIGN64 Ipp64u n384_k0 = 0x00046089e88fdc45; + +/* r = 2^((52*8)) mod n384 */ +static const __ALIGN64 Ipp64u n384_r[LEN52] = { + 0x000ad68d00000000, 0x000851313e695333, 0x0007e5f24db74f58, 0x000b27e0bc8d220a, 0x000000000000389c, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 +}; + +/* To Montgomery conversion constant + * rr = 2^((52*8)*2) mod n384 + */ +static const __ALIGN64 Ipp64u n384_rr[LEN52] = { + 0x00034124f50ddb2d, 0x000c974971bd0d8d, 0x0002118942bfd3cc, 0x0009f43be8072178, 0x0005bf030606de60, 0x0000d49174aab1cc, 0x000b7a28266895d4, 0x000000000003fb05 +}; + +static const __ALIGN64 Ipp64u ones[LEN52] = { + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + +#define MULT_ROUND(R, A, B, IDX) \ + const m512 Bi##R##IDX = permutexvar_i8(idx_b##IDX, (B)); \ + const m512 amBiLo##R##IDX = madd52lo_i64(zero, (A), Bi##R##IDX); \ + m512 tr##R##IDX = madd52hi_i64(zero, (A), Bi##R##IDX); \ + { \ + /* low */ \ + (R) = add_i64((R), amBiLo##R##IDX); \ + const m512 R0 = permutexvar_i8(idx_b0, (R)); \ + const m512 u = madd52lo_i64(zero, K0, R0); \ + tr##R##IDX = madd52hi_i64(tr##R##IDX, N, u); \ + (R) = madd52lo_i64((R), N, u); \ + /* shift */ \ + const m512 carryone = maskz_srai_i64(maskone, (R), DIGIT_SIZE); \ + tr##R##IDX = add_i64(tr##R##IDX, carryone); \ + (R) = maskz_permutexvar_i8(mask_sr64, idx_sr64, (R)); \ + /* hi */ \ + (R) = add_i64((R), tr##R##IDX); \ + } + +/* R = (A*B) - no normalization (in radix 2^52) */ +IPP_OWN_DEFN(m512, ifma_amm52_n384, (const m512 a, const m512 b)) +{ + const m512 N = loadu_i64(n384_x1); /* n */ + const m512 K0 = set1_i64(n384_k0); /* k0 */ + const m512 zero = setzero_i64(); + const mask8 maskone = 0x1; + + /* Index broadcast */ + const m512 idx_b0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const m512 idx_b1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const m512 idx_b2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const m512 idx_b3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const m512 idx_b4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const m512 idx_b5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + const m512 idx_b6 = set_i64(REPL8(0x3736353433323130)); // 55, 54, 53, 52, 51, 50, 49, 48 + const m512 idx_b7 = set_i64(REPL8(0x3f3e3d3c3b3a3938)); // 63, 62, 61, 60, 59, 58, 57, 56 + + /* Mask to shift zmm register right on 64-bit */ + const mask64 mask_sr64 = 0x00ffffffffffffff; + const m512 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 r = setzero_i64(); + /* N384 + * m' mod b = 46089e88fdc45 + * + * Algorithm + * a[] b[] - input data ((in radix 2^52)) m[] - module n384 + * + * where u = R[0]*m' mod b + * 1) R = R + a[] * b[i] (lo) + * 2) R = R + m[] * u (lo) + * 3) R = R >> 64 + * 4) R = R + a[] * b[i] (hi) + * 5) R = R + m[] * u (hi) + */ + /* one round = O(32) */ + MULT_ROUND(r, a, b, 0) + MULT_ROUND(r, a, b, 1) + MULT_ROUND(r, a, b, 2) + MULT_ROUND(r, a, b, 3) + MULT_ROUND(r, a, b, 4) + MULT_ROUND(r, a, b, 5) + MULT_ROUND(r, a, b, 6) + MULT_ROUND(r, a, b, 7) + + r = ifma_lnorm52(r); + + return r; +} + +IPP_OWN_DEFN(m512, ifma_add52_n384, (const m512 a, const m512 b)) +{ + const m512 zero = setzero_i64(); + const m512 N = loadu_i64(n384_x1); + + /* r = a + b */ + m512 r = add_i64(a, b); + r = ifma_lnorm52(r); + + /* t = r - N */ + m512 t = sub_i64(r, N); + t = ifma_norm52(t); + + /* lt = t < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(t, DIGIT_SIZE - 1), _MM_CMPINT_LT); + const mask8 mask = check_bit(lt, 7); + /* mask != 0 ? r : t */ + r = mask_mov_i64(t, mask, r); + + return r; +} + +static m512 ifma_ams52_n384(const m512 a) +{ + return ifma_amm52_n384(a, a); +} + +IPP_OWN_DEFN(m512, ifma_tomont52_n384, (const m512 a)) +{ + const m512 RR = loadu_i64(n384_rr); + return ifma_amm52_n384(a, RR); +} + +IPP_OWN_DEFN(m512, ifma_fastred52_n384, (const m512 a)) +{ + const m512 N = loadu_i64(n384_x1); + const m512 zero = setzero_i64(); + + /* r = a - N */ + m512 r = sub_i64(a, N); + r = ifma_norm52(r); + + /* 1 < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(r, DIGIT_SIZE - 1), _MM_CMPINT_LT); + const mask8 mask = check_bit(lt, 7); + + /* maks != 0 ? a : r */ + r = mask_mov_i64(r, mask, a); + return r; +} + +IPP_OWN_DEFN(m512, ifma_frommont52_n384, (const m512 a)) +{ + const m512 ONE = loadu_i64(ones); + m512 r = ifma_amm52_n384(a, ONE); + return ifma_fastred52_n384(r); +} + +#define sqr(R, A) (R) = ifma_ams52_n384((A)) +#define mul(R, A, B) (R) = ifma_amm52_n384((A), (B)) + +/* + * computes r = 1/z = z^(n384-2) mod n384 + * + * note: z in in Montgomery domain + * r in Montgomery domain + */ +__INLINE m512 ifma_ams52_n384_ntimes(const m512 a, int n) +{ + m512 r = a; + for (; n > 0; --n) { + sqr(r, r); + } + return r; +} + +#define sqr_ntimes(R, A, N) (R) = ifma_ams52_n384_ntimes((A), (N)) + +IPP_OWN_DEFN(m512, ifma_aminv52_n384, (const m512 z)) +{ + + const m512 r_norder = loadu_i64(n384_r); + + /* table pwr_z_Tbl[i] = z^i, i = 0,..,15 */ + __ALIGN64 m512 pwr_z_tbl[16]; + m512 lexp; + lexp = setzero_i64(); + + /* fill table */ + pwr_z_tbl[0] = r_norder; + pwr_z_tbl[1] = z; + for (int i = 2; i < 16; i += 2) { + sqr(pwr_z_tbl[i], pwr_z_tbl[i / 2]); + mul(pwr_z_tbl[i + 1], pwr_z_tbl[i], z); + } + + // pwr = (n384-2) in big endian + const Ipp8u pwr[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xC7\x63\x4D\x81\xF4\x37\x2D\xDF" + "\x58\x1A\x0D\xB2\x48\xB0\xA7\x7A" + "\xEC\xEC\x19\x6A\xCC\xC5\x29\x71"; + + /* + * process low part of the exponent: "0xc7634d81f4372ddf 0x581a0db248b0a77a 0xecec196accc52973" + */ + /* init result */ + lexp = r_norder; + for (Ipp32u i = 24u; i < (sizeof(pwr) - 1u); ++i) { + const int v = (int)(pwr[i]); + const int hi = (v >> 4) & 0xF; + const int lo = v & 0xF; + + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + if (0 != hi) + mul(lexp, lexp, pwr_z_tbl[hi]); + + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + if (0 != lo) + mul(lexp, lexp, pwr_z_tbl[lo]); + } + m512 u, v; + u = v = setzero_i64(); + + sqr(v, z); /* v = z^2 */ + mul(u, v, z); /* u = z^2 * z = z^3 */ + /**/ + sqr_ntimes(v, u, 2); /* v = (z^3)^(2^2) = z^12 */ + mul(u, v, u); /* u = z^12 * z^3 = z^15 = z^(0xF) */ + /**/ + sqr_ntimes(v, u, 4); /* v = (z^0xF)^(2^4) = z^(0xF0) */ + mul(u, v, u); /* u = z^0xF0 * z^(0xF) = z^(0xFF) */ + /**/ + sqr_ntimes(v, u, 8); /* v = (z^0xFF)^(2^8) = z^(0xFF00) */ + mul(u, v, u); /* u = z^0xFF00 * z^(0xFF) = z^(0xFFFF) */ + /**/ + sqr_ntimes(v, u, 16); /* v = (z^0xFFFF)^(2^16) = z^(0xFFFF0000) */ + mul(u, v, u); /* u = z^0xFFFF0000 * z^(0xFFFF) = z^(0xFFFFFFFF) */ + /**/ + sqr_ntimes(v, u, 32); /* v = (z^0xFFFFFFFF)^(2^32) = z^(0xFFFFFFFF00000000) */ + mul(u, v, u); /* u = z^0xFFFFFFFF00000000 * z^(0xFFFFFFFF) = z^(0xFFFFFFFFFFFFFFFF) */ + /**/ + sqr_ntimes(v, u, 64); /**/ + mul(v, v, u); /* v = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + /**/ + sqr_ntimes(v, v, 64); /**/ + mul(v, v, u); /* v = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + + /* combine low and high results */ + sqr_ntimes(v, v, 64 * 3); /* u = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000.0000000000000000.0000000000000000) */ + m512 r = setzero_i64(); /**/ + mul(r, v, lexp); /* r = z^(0xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.c7634d81f4372ddf.581a0db248b0a77a.ecec196accc52973) */ + return r; +} + +#undef sqr +#undef mul +#undef sqr_ntimes + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n384.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n384.h new file mode 100644 index 000000000..a8cc448f1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n384.h @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#if !defined(_IFMA_ARITH_N384R1_H_) +#define _IFMA_ARITH_N384R1_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_alias_avx512.h" + +/** + * \brief + * + * Montgomery multiplication + * + * a * b * R mod n, where R = 2^(5*52) mod n + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_amm52_n384, (const m512 a, const m512 b)) + +/** + * \brief + * + * A + B (in 2^52 radix) + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_add52_n384, (const m512 a, const m512 b)) + +/** + * \brief + * + * Reduction modulo n (subgroup order). + * + * (a >= n384) ? a - n384 : a + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_fastred52_n384, (const m512 a)) + +/** + * \brief + * + * Conversion to Montgomery domain modulo n (subgroup order). + * + * a * R mod n, where R = 2^(5*52) mod n + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_tomont52_n384, (const m512 a)) + +/** + * \brief + * + * Conversion from Montgomery domain modulo n (subgroup order). + * + * a mod n + * + * \param[in] p value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_frommont52_n384, (const m512 a)) + +/** + * \brief + * + * Modular inverse modulo n (subgroup order). + * + * 1/z mod n + * + * \param[in] z value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_aminv52_n384, (const m512 z)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ARITH_N384R1_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n521.c new file mode 100644 index 000000000..f059dd931 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n521.c @@ -0,0 +1,351 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_p521.h" +/* +// EC NIST-P521 prime base point order +// in 2^52 radix +*/ +static const __ALIGN64 Ipp64u n521_x1[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x000fb71e91386409, + 0x000b8899c47aebb6, + 0x000709a5d03bb5c9, + 0x000966b7fcc0148f }, + { 0x000a51868783bf2f, + 0x000fffffffffffff, + 0x000fffffffffffff, + 0x000fffffffffffff }, + { 0x000fffffffffffff, + 0x000fffffffffffff, + 0x0000000000000001, + 0x0000000000000000 } +}; + +static const __ALIGN64 Ipp64u n521_k0 = 0x000f5ccd79a995c7; + +/* to Montgomery conversion constant +// rr = 2^((P521_LEN52*DIGIT_SIZE)*2) mod n521 +*/ +static const __ALIGN64 Ipp64u n521_rr[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x0003b4d7a5b140ce, + 0x000cb0bf26c55bf9, + 0x00037e5396c67ee9, + 0x0002bd1c80cf7b13 }, + { 0x00073cbe28f15e41, + 0x000dd6e23d82e49c, + 0x0003d142b7756e3e, + 0x00061a8e567bccff }, + { 0x00092d0d455bcc6d, + 0x000383d2d8e03d14, + 0x0000000000000000, + 0x0000000000000000 } +}; + +/* ifma_tomont52_n521_(1) */ +static const __ALIGN64 Ipp64u n521_r[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x0008000000000000, + 0x00082470b763cdfb, + 0x00023bb31dc28a24, + 0x00047b2d17e2251b }, + { 0x00034ca4019ff5b8, + 0x0002d73cbc3e2068, + 0x0000000000000000, + 0x0000000000000000 }, + { 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000 } +}; + +#define group_madd52hi_i64(R, A, B, C) \ + FE521_LO(R) = m256_madd52hi_i64(FE521_LO(A), FE521_LO(B), (C)); \ + FE521_MID(R) = m256_madd52hi_i64(FE521_MID(A), FE521_MID(B), (C)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(A), FE521_HI(B), (C)) + +#define group_madd52lo_i64(R, A, B, C) \ + FE521_LO(R) = m256_madd52lo_i64(FE521_LO(A), FE521_LO(B), (C)); \ + FE521_MID(R) = m256_madd52lo_i64(FE521_MID(A), FE521_MID(B), (C)); \ + FE521_HI(R) = m256_madd52lo_i64(FE521_HI(A), FE521_HI(B), (C)) + +#define NEW_MUL_ROUND(R, A, IDX8, B) \ + const m256i Bi##R##IDX8 = m256_permutexvar_i8((IDX8), (B)); \ + fe521 amBiLo##R##IDX8, tr##R##IDX8; \ + /* (lo/hi) a[]*b[i] */ \ + FE521_LO(amBiLo##R##IDX8) = m256_madd52lo_i64(zero, FE521_LO((A)), (Bi##R##IDX8)); \ + FE521_MID(amBiLo##R##IDX8) = m256_madd52lo_i64(zero, FE521_MID((A)), (Bi##R##IDX8)); \ + FE521_HI(amBiLo##R##IDX8) = m256_madd52lo_i64(zero, FE521_HI((A)), (Bi##R##IDX8)); \ + FE521_LO(tr##R##IDX8) = m256_madd52hi_i64(zero, FE521_LO((A)), (Bi##R##IDX8)); \ + FE521_MID(tr##R##IDX8) = m256_madd52hi_i64(zero, FE521_MID((A)), (Bi##R##IDX8)); \ + FE521_HI(tr##R##IDX8) = m256_madd52hi_i64(zero, FE521_HI((A)), (Bi##R##IDX8)); \ + { \ + /* R = R + a[]*b[i](lo) */ \ + fe521_add_no_red(R, R, amBiLo##R##IDX8); \ + /* u = R[0] * 1 */ \ + const m256i R0 = m256_permutexvar_i8(idx0, FE521_LO((R))); \ + const m256i u = m256_madd52lo_i64(zero, R0, K0); \ + /* R = R + m[]*u (lo/hi) */ \ + group_madd52hi_i64(tr##R##IDX8, tr##R##IDX8, N, u); \ + group_madd52lo_i64(R, R, N, u); \ + /* get carry low + add hi compute */ \ + const m256i carryone = m256_maskz_srai_i64(0x1, FE521_LO(R), DIGIT_SIZE_52); \ + FE521_LO(tr##R##IDX8) = m256_add_i64(FE521_LO(tr##R##IDX8), carryone); \ + /* shift */ \ + FE521_LO(R) = m256_alignr_i64(FE521_MID(R), FE521_LO(R), 1); \ + FE521_MID(R) = m256_alignr_i64(FE521_HI(R), FE521_MID(R), 1); \ + FE521_HI(R) = m256_maskz_permutexvar_i8(mask_sr64, idx_sr64, FE521_HI(R)); \ + /* add hi compute */ \ + fe521_add_no_red(R, R, tr##R##IDX8); \ + } + +IPP_OWN_DEFN(void, ifma_amm52_n521, (fe521 pr[], const fe521 a, const fe521 b)) +{ + /* k0 */ + const m256i K0 = m256_set1_i64(n521_k0); + fe521 N; + FE521_LOADU(N, n521_x1); + const m256i zero = m256_setzero_i64(); + /* chunk2 shift bit >> 64 */ + const mask32 mask_sr64 = 0x00FFFFFF; + const m256i idx_sr64 = m256_set_i8(0, 0, 0, 0, 0, 0, 0, 0, + 31, 30, 29, 28, 27, 26, 25, 24, + 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8); + + // IDX + const m256i idx0 = m256_set_i8(REPL4(7, 6, 5, 4, 3, 2, 1, 0)); + const m256i idx1 = m256_set_i8(REPL4(15, 14, 13, 12, 11, 10, 9, 8)); + const m256i idx2 = m256_set_i8(REPL4(23, 22, 21, 20, 19, 18, 17, 16)); + const m256i idx3 = m256_set_i8(REPL4(31, 30, 29, 28, 27, 26, 25, 24)); + + const m256i idx4 = m256_set_i8(REPL4(7, 6, 5, 4, 3, 2, 1, 0)); + const m256i idx5 = m256_set_i8(REPL4(15, 14, 13, 12, 11, 10, 9, 8)); + const m256i idx6 = m256_set_i8(REPL4(23, 22, 21, 20, 19, 18, 17, 16)); + const m256i idx7 = m256_set_i8(REPL4(31, 30, 29, 28, 27, 26, 25, 24)); + + const m256i idx8 = m256_set_i8(REPL4(7, 6, 5, 4, 3, 2, 1, 0)); + const m256i idx9 = m256_set_i8(REPL4(15, 14, 13, 12, 11, 10, 9, 8)); + const m256i idx10 = m256_set_i8(REPL4(23, 22, 21, 20, 19, 18, 17, 16)); + + fe521 r; + FE521_SET(r) = m256_setzero_i64(); + NEW_MUL_ROUND(r, a, idx0, FE521_LO(b)) + NEW_MUL_ROUND(r, a, idx1, FE521_LO(b)) + NEW_MUL_ROUND(r, a, idx2, FE521_LO(b)) + NEW_MUL_ROUND(r, a, idx3, FE521_LO(b)) + NEW_MUL_ROUND(r, a, idx4, FE521_MID(b)) + NEW_MUL_ROUND(r, a, idx5, FE521_MID(b)) + NEW_MUL_ROUND(r, a, idx6, FE521_MID(b)) + NEW_MUL_ROUND(r, a, idx7, FE521_MID(b)) + NEW_MUL_ROUND(r, a, idx8, FE521_HI(b)) + NEW_MUL_ROUND(r, a, idx9, FE521_HI(b)) + NEW_MUL_ROUND(r, a, idx10, FE521_HI(b)) + + ifma_lnorm52_p521(&r, r); + + FE521_COPY(*pr, r); + return; +} + +#undef group_madd52hi_i64 +#undef group_madd52lo_i64 +#undef NEW_MUL_ROUND + +IPP_OWN_DEFN(void, ifma_add52_n521, (fe521 pr[], const fe521 a, const fe521 b)) +{ + const m256i zero = m256_setzero_i64(); + fe521 N; + FE521_LOADU(N, n521_x1); + + /* r = a + b */ + fe521 r; + fe521_add_no_red(r, a, b); + ifma_lnorm52_p521(&r, r); + + /* t = r - N */ + fe521 t; + fe521_sub_no_red(t, r, N); + ifma_norm52_p521(&t, t); + + /* lt = t < 0 */ + const mask8 lt = m256_cmp_i64_mask(zero, m256_srli_i64(FE521_HI(t), DIGIT_SIZE_52 - 1), _MM_CMPINT_LT); + const mask8 mask = (mask8)((mask8)0 - ((lt >> 2) & 1)); + + /* maks != 0 ? a : r */ + FE521_MASK_MOV(r, t, mask, r); + FE521_COPY(*pr, r); + return; +} + +IPP_OWN_DEFN(void, ifma_tomont52_n521, (fe521 pr[], const fe521 a)) +{ + fe521 RR; + FE521_LOADU(RR, n521_rr); + ifma_amm52_n521(pr, a, RR); + return; +} + +IPP_OWN_DEFN(void, ifma_fastred52_n521, (fe521 pr[], const fe521 a)) +{ + fe521 N; + FE521_LOADU(N, n521_x1); + const m256i zero = m256_setzero_i64(); + + fe521 r; + fe521_sub_no_red(r, a, N); + ifma_norm52_p521(&r, r); + + const mask8 lt = m256_cmp_i64_mask(zero, m256_srli_i64(FE521_HI(r), DIGIT_SIZE_52 - 1), _MM_CMPINT_LT); + const mask8 mask = (mask8)((mask8)0 - ((lt >> 2) & 1)); + + /* maks != 0 ? a : r */ + FE521_MASK_MOV(r, r, mask, a); + FE521_COPY(*pr, r); + return; +} + +IPP_OWN_DEFN(void, ifma_frommont52_n521, (fe521 pr[], const fe521 a)) +{ + fe521 ONE; + FE521_LOADU(ONE, P521R1_ONE52); + ifma_amm52_n521(pr, a, ONE); + ifma_fastred52_n521(pr, *pr); + return; +} + +static void ifma_ams52_n521(fe521 pr[], const fe521 a) +{ + ifma_amm52_n521(pr, a, a); +} + +#define mul(R, A, B) ifma_amm52_n521(&(R), (A), (B)) +#define sqr(R, A) ifma_ams52_n521(&(R), (A)) + +/* r = base^(2^n) */ +__INLINE IPP_OWN_DEFN(void, ifma_ams52_p521_ntimes, (fe521 pr[], const fe521 a, int n)) +{ + fe521 r; + FE521_COPY(r, a); + for (; n > 0; --n) + sqr(r, r); + FE521_COPY(*pr, r); + return; +} + +#define sqr_ntimes(R, A, N) ifma_ams52_p521_ntimes(&(R), (A), (N)) + +IPP_OWN_DEFN(void, ifma_aminv52_n521, (fe521 pr[], const fe521 z)) +{ + Ipp32u i; + fe521 n521r1_r; + + FE521_LOADU(n521r1_r, n521_r); + + // pwr_z_Tbl[i][] = z^i, i=0,..,15 + __ALIGN64 fe521 pwr_z_Tbl[16]; + __ALIGN64 fe521 lexp; + + FE521_COPY(pwr_z_Tbl[0], n521r1_r); + FE521_COPY(pwr_z_Tbl[1], z); + + for (i = 2u; i < 16u; i += 2u) { + sqr(pwr_z_Tbl[i], pwr_z_Tbl[i / 2u]); + mul(pwr_z_Tbl[i + 1u], pwr_z_Tbl[i], z); + } + + // pwr = (n521-2) in big endian + const Ipp8u pwr[] = "\x1\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFA" + "\x51\x86\x87\x83\xBF\x2F\x96\x6B" + "\x7F\xCC\x01\x48\xF7\x09\xA5\xD0" + "\x3B\xB5\xC9\xB8\x89\x9C\x47\xAE" + "\xBB\x6F\xB7\x1E\x91\x38\x64\x07"; + + /* + // process 25 low bytes of the exponent: :FA 51 86 ... 64 07" + */ + /* init result */ + FE521_COPY(lexp, n521r1_r); + + for (i = 33u; i < sizeof(pwr) - 1u; ++i) { + const int v = pwr[i]; + const int hi = (v >> 4) & 0xF; + const int lo = v & 0xF; + + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + if (hi) + mul(lexp, lexp, pwr_z_Tbl[hi]); + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + sqr(lexp, lexp); + if (lo) + mul(lexp, lexp, pwr_z_Tbl[lo]); + } + + /* + // process high part of the exponent: "0x1 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff 0xffffffffffffffff" + */ + fe521 u, v; + FE521_SET(u) = FE521_SET(v) = m256_setzero_i64(); + + FE521_COPY(u, pwr_z_Tbl[15]); /* u = z^0xF */ + /**/ + sqr_ntimes(v, u, 4); /* v = (z^0xF)^(2^4) = z^(0xF0) */ + mul(u, v, u); /* u = z^0xF0 * z^(0xF) = z^(0xFF) */ + /**/ + sqr_ntimes(v, u, 8); /* v = (z^0xFF)^(2^8) = z^(0xFF00) */ + mul(u, v, u); /* u = z^0xFF00 * z^(0xFF) = z^(0xFFFF) */ + /**/ + sqr_ntimes(v, u, 16); /* v = (z^0xFFFF)^(2^16) = z^(0xFFFF0000) */ + mul(u, v, u); /* u = z^0xFFFF0000 * z^(0xFFFF) = z^(0xFFFFFFFF) */ + /**/ + sqr_ntimes(v, u, 32); /* v = (z^0xFFFFFFFF)^(2^32) = z^(0xFFFFFFFF00000000) */ + mul(u, v, u); /* u = z^0xFFFFFFFF00000000 * z^(0xFFFFFFFF) = z^(0xFFFFFFFFFFFFFFFF) */ + /**/ + sqr_ntimes(v, z, 64); /**/ + mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF) */ + /**/ + sqr_ntimes(v, v, 64); /**/ + mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + /**/ + sqr_ntimes(v, v, 64); /**/ + mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + /**/ + sqr_ntimes(v, v, 64); /**/ + mul(v, v, u); /* v = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF) */ + + /* combine low and high results */ + sqr_ntimes(v, v, 64 * 4 + 8); /* u = z^(0x1.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.00.0000000000000000.0000000000000000.0000000000000000.0000000000000000) */ + mul(*pr, v, lexp); /* r = z^(0x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFA.51868783BF2F966B.7FCC0148F709A5D0.3BB5C9B8899C47AE.BB6FB71E91386407) */ + return; +} + +#undef mul +#undef sqr +#undef sqr_ntimes + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n521.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n521.h new file mode 100644 index 000000000..027658bf8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_n521.h @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_ARITH_N521_H +#define IFMA_ARITH_N521_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_defs_p521.h" + +/** + * \brief + * R = (A * B) - in domain n521r1 + * \param[out] pr value no normalization + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_amm52_n521, (fe521 pr[], const fe521 a, const fe521 b)) + +/** + * \brief + * R = (A + B) mod n521r1 + * \param[out] pr value (in radix 2^52) + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_add52_n521, (fe521 pr[], const fe521 a, const fe521 b)) + +/** + * \brief + * to Montgomery domain + * \param[out] pr value (in radix 2^52) + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_tomont52_n521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * fast reduction order n521r1 + * \param[out] pr value (in radix 2^52) + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_fastred52_n521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * from Montgomery domain + * \param[out] pr value (in radix 2^52) + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_frommont52_n521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * inverse R = 1/z + * \param[out] pr value (in radix 2^52) + * \param[in] z value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_aminv52_n521, (fe521 pr[], const fe521 z)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p256.c new file mode 100644 index 000000000..a264ee4ff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p256.c @@ -0,0 +1,443 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_p256.h" +#include "ifma_defs.h" + +#define LEN52 (5 + 3) /* 5 digits + 3 zero padding */ + +/* Modulus p256r1 */ +static const __ALIGN64 Ipp64u p256_x1[LEN52] = { + 0x000fffffffffffff, 0x00000fffffffffff, 0x0000000000000000, 0x0000001000000000, 0x0000ffffffff0000, 0x0, 0x0, 0x0 +}; + +/* Scaled modulus 4*p256r1 */ +static const __ALIGN64 Ipp64u p256_x4[LEN52] = { + 0x000ffffffffffffc, 0x00003fffffffffff, 0x0000000000000000, 0x0000004000000000, 0x0003fffffffc0000, 0x0, 0x0, 0x0 +}; + +/* To Montgomery domain conversion constant + * + * The extended Montgomery domain here with R = 2^(6*52) instead of 2^(5*62) is + * choosen to use NRMM field multiplication routine in the sequence of EC group + * operations (point multiplication on scalar / addition) without modulo + * reductions in the field addition (see Chapter 4 in "Enhanced Montgomery + * Multiplication" DOI:10.1155/2008/583926). According to the paper the chosen + * |s| in NRMM^s(a,b) shall be equal to n + 2*kmax, with kmax = 4 for EC group + * operations, so s = 264. 5 digits capacity is only 260 bits, so purely IFMA-based + * implementation shall use 6 digits. + * + * rr = 2^((52*6))*2) mod p256 + */ +static const __ALIGN64 Ipp64u p256_rr6[LEN52] = { + 0x0002fffffffdffff, 0x0000100050000000, 0x000ffd0000000500, 0x0000000fff9fffff, 0x0000fff9fffefffe, 0x0, 0x0, 0x0 +}; + +#if 0 +/* + * rr = 2^((52*5))*2) mod p256 + */ +static const __ALIGN64 Ipp64u p256_rr5[LEN52] = { + 0x0000000000000300, 0x000ffffffff00000, 0x000ffffefffffffb, 0x000fdfffffffffff, 0x0000000004ffffff, 0x0, 0x0, 0x0 +}; +#endif + +static const __ALIGN64 Ipp64u ones[LEN52] = { + 1, 0, 0, 0, 0, 0, 0, 0 +}; + +#define MUL_RED_ROUND(R, A, B, IDX) \ + { \ + const m512 Bi = permutexvar_i8(idx_b##IDX, (B)); \ + m512 Rlo = madd52lo_i64(zero, (A), Bi); \ + m512 tmp = madd52hi_i64(zero, (A), Bi); \ + \ + (R) = add_i64((R), Rlo); \ + /* broadcast R[0] */ \ + const m512 R0 = permutexvar_i8(idx_b0, (R)); \ + (R) = madd52lo_i64((R), M, R0); \ + tmp = madd52hi_i64(tmp, M, R0); \ + /* shift */ \ + const m512 carry = maskz_srli_i64(maskone, (R), DIGIT_SIZE); \ + tmp = add_i64(tmp, carry); \ + (R) = maskz_permutexvar_i8(mask_sr64, idx_sr64, (R)); \ + /* hi */ \ + (R) = add_i64((R), tmp); \ + } + +/* R = (A*B) - no normalization radix 52 */ +IPP_OWN_DEFN(m512, ifma_amm52_p256, (const m512 a, const m512 b)) +{ + const m512 M = loadu_i64(p256_x1); + const m512 zero = setzero_i64(); + const mask8 maskone = 0x1; + + /* Index broadcast */ + const m512 idx_b0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const m512 idx_b1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const m512 idx_b2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const m512 idx_b3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const m512 idx_b4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const m512 idx_b5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + + /* Mask to shift zmm register right on 64-bit */ + const mask64 mask_sr64 = 0x00ffffffffffffff; + const m512 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 r = setzero_i64(); + + MUL_RED_ROUND(r, a, b, 0) + MUL_RED_ROUND(r, a, b, 1) + MUL_RED_ROUND(r, a, b, 2) + MUL_RED_ROUND(r, a, b, 3) + MUL_RED_ROUND(r, a, b, 4) + MUL_RED_ROUND(r, a, b, 5) + + return r; +} + +IPP_OWN_DEFN(void, ifma_amm52_dual_p256, (m512 * r1, const m512 a1, const m512 b1, m512 *r2, const m512 a2, const m512 b2)) +{ + const m512 M = loadu_i64(p256_x1); + const m512 zero = setzero_i64(); + const mask8 maskone = 0x1; + + /* Index broadcast */ + const m512 idx_b0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const m512 idx_b1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const m512 idx_b2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const m512 idx_b3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const m512 idx_b4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const m512 idx_b5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + + /* Mask to shift zmm register right on 64-bit */ + const mask64 mask_sr64 = 0x00ffffffffffffff; + const m512 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 t1 = setzero_i64(); + m512 t2 = setzero_i64(); + + MUL_RED_ROUND(t1, a1, b1, 0) + MUL_RED_ROUND(t2, a2, b2, 0) + + MUL_RED_ROUND(t1, a1, b1, 1) + MUL_RED_ROUND(t2, a2, b2, 1) + + MUL_RED_ROUND(t1, a1, b1, 2) + MUL_RED_ROUND(t2, a2, b2, 2) + + MUL_RED_ROUND(t1, a1, b1, 3) + MUL_RED_ROUND(t2, a2, b2, 3) + + MUL_RED_ROUND(t1, a1, b1, 4) + MUL_RED_ROUND(t2, a2, b2, 4) + + MUL_RED_ROUND(t1, a1, b1, 5) + MUL_RED_ROUND(t2, a2, b2, 5) + + *r1 = t1; + *r2 = t2; +} + +/* R = (A*B) with norm */ +__INLINE m512 ifma_amm52_p256_norm(const m512 a, const m512 b) +{ + m512 r = ifma_amm52_p256(a, b); + return ifma_lnorm52(r); +} + +/* R = (A*A) with norm */ +__INLINE m512 ifma_ams52_p256_norm(const m512 a) +{ + return ifma_amm52_p256_norm(a, a); +} + +/* R = (A/2) */ +IPP_OWN_DEFN(m512, ifma_half52_p256, (const m512 a)) +{ + const m512 M = loadu_i64(p256_x1); + const m512 zero = setzero_i64(); + const m512 one = set1_i64(1LL); + + const mask8 is_last_one = cmp_i64_mask(and_i64(a, one), zero, _MM_CMPINT_EQ); + const mask8 mask = (mask8)((is_last_one & 1) - 1); + + const mask64 mask_shift = 0x00ffffffffffffff; + const m512 idx_shift = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 r = mask_add_i64(a, mask, a, M); + r = ifma_lnorm52(r); + + m512 leftBit = maskz_permutexvar_i8(mask_shift, idx_shift, and_i64(r, one)); + leftBit = slli_i64(leftBit, DIGIT_SIZE - 1); + r = srli_i64(r, 1); + r = add_i64(r, leftBit); + + return r; +} + +IPP_OWN_DEFN(m512, ifma_neg52_p256, (const m512 a)) +{ + const m512 M4 = loadu_i64(p256_x4); + + /* a == 0 ? 0xFF : 0 */ + const mask8 mask_zero = is_zero_i64(a); + + /* r = 4*p - a */ + m512 r = mask_sub_i64(a, ~mask_zero, M4, a); + r = ifma_norm52(r); + return r; +} + + +static m512 mod_reduction_p256(const m512 a) +{ + const m512 M = loadu_i64(p256_x1); + const m512 zero = setzero_i64(); + + /* r = a - M */ + m512 r = sub_i64(a, M); + r = ifma_norm52(r); + + /* 1 < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(r, DIGIT_SIZE - 1), _MM_CMPINT_LT); + const mask8 mask = check_bit(lt, 4); // check sign in 5th digit + + /* maks != 0 ? a : r */ + r = mask_mov_i64(r, mask, a); + return r; +} + +/* to Montgomery domain */ +IPP_OWN_DEFN(m512, ifma_tomont52_p256, (const m512 a)) +{ + return ifma_amm52_p256_norm(a, loadu_i64(p256_rr6)); +} + +/* from Montgomery domain */ +IPP_OWN_DEFN(m512, ifma_frommont52_p256, (const m512 a)) +{ + m512 r = ifma_amm52_p256_norm(a, loadu_i64(ones)); + r = mod_reduction_p256(r); + return r; +} + +#define sqr(R, A) (R) = ifma_ams52_p256_norm((A)) +#define mul(R, A, B) (R) = ifma_amm52_p256_norm((A), (B)); + +__INLINE m512 ifma_ams52_p256_ntimes(m512 a, Ipp32s n) +{ + for (; n > 0; --n) + sqr(a, a); + return a; +} + +#define sqr_ntimes(R, A, N) (R) = ifma_ams52_p256_ntimes((A), (N)) + +/* R = 1/z */ +IPP_OWN_DEFN(m512, ifma_aminv52_p256, (const m512 z)) +{ + __ALIGN64 m512 tmp1; + __ALIGN64 m512 tmp2; + + /* Each eI holds z^(2^I-1) */ + __ALIGN64 m512 e2; + __ALIGN64 m512 e4; + __ALIGN64 m512 e8; + __ALIGN64 m512 e16; + __ALIGN64 m512 e32; + __ALIGN64 m512 e64; + + /* tmp1 = z^(2^1) */ + sqr(tmp1, z); + /* e2 = tmp1 = tmp1 * z = z^(2^2 - 2^0) */ + mul(tmp1, tmp1, z); + e2 = tmp1; + + /* tmp1 = tmp1^2 = z^(2^2 - 2^0)*2 = z^(2^3 - 2^1) */ + sqr(tmp1, tmp1); + /* tmp1 = tmp1^2 = z^(2^3 - 2^1)*2 = z^(2^4 - 2^2) */ + sqr(tmp1, tmp1); + /* e4 = tmp1 = tmp1*e2 = z^(2^4 - 2^2) * z^(2^2 - 2^0) = z^(2^4 - 2^2 + 2^2 - 2^0) = z^(2^4 - 2^0)*/ + mul(tmp1, tmp1, e2); + e4 = tmp1; + + /* tmp1 = tmp1^2 = z^(2^4 - 2^0)*2 = z^(2^5 - 2^1) */ + sqr(tmp1, tmp1); + /* tmp1 = tmp1^2 = z^(2^5 - 2^1)*2 = z^(2^6 - 2^2) */ + sqr(tmp1, tmp1); + /* tmp1 = tmp1^2 = z^(2^6 - 2^2)*2 = z^(2^7 - 2^3) */ + sqr(tmp1, tmp1); + /* tmp1 = tmp1^2 = z^(2^7 - 2^3)*2 = z^(2^8 - 2^4) */ + sqr(tmp1, tmp1); + /* e8 = tmp1 = tmp1*e4 = z^(2^8 - 2^4) * z^(2^4 - 2^0) = z^(2^8 - 2^4 + 2^4 - 2^0) = z^(2^8 - 2^0)*/ + mul(tmp1, tmp1, e4); + e8 = tmp1; + + /* tmp1 = tmp1^(2^8) = z^(2^8 - 2^0)*2^8 = z^(2^16 - 2^8) */ + sqr_ntimes(tmp1, tmp1, 8); + + /* e16 = tmp1 = tmp1*e8 = z^(2^16 - 2^8) * z^(2^8 - 2^0) = z^(2^16 - 2^8 + 2^8 - 2^0) = z^(2^16 - 2^0)*/ + mul(tmp1, tmp1, e8); + e16 = tmp1; + + /* tmp1 = tmp1^(2^16) = z^(2^16 - 2^0)*2^16 = z^(2^32 - 2^16) */ + sqr_ntimes(tmp1, tmp1, 16); + + /* e32 = tmp1 = tmp1*e16 = z^(2^32 - 2^16) * z^(2^16 - 2^0) = z^(2^32 - 2^16 + 2^16 - 2^0) = z^(2^32 - 2^0)*/ + mul(tmp1, tmp1, e16); + e32 = tmp1; + + /* e64 = tmp1 = tmp1^(2^32) = z^(2^32 - 2^0)*2^32 = z^(2^64 - 2^32) */ + sqr_ntimes(tmp1, tmp1, 32); + + e64 = tmp1; + /* tmp1 = tmp1*z = z^(2^64 - 2^32) * z = z^(2^64 - 2^32 + 2^0)*/ + mul(tmp1, tmp1, z); + + /* tmp1 = tmp1^(2^192) = z^(2^64 - 2^32 + 2^0)*2^192 = z^(2^256 - 2^224 + 2^192) */ + sqr_ntimes(tmp1, tmp1, 192); + + /* tmp2 = e64*e32 = z^(2^64 - 2^32) * z^(2^32 - 2^0) = z^(2^64 - 2^32 + 2^32 - 2^0) = z^(2^64 - 2^0)*/ + mul(tmp2, e64, e32); + + /* tmp2 = tmp2^(2^16) = z^(2^64 - 2^0)*2^16 = z^(2^80 - 2^16) */ + sqr_ntimes(tmp2, tmp2, 16); + + /* tmp2 = tmp2*e16 = z^(2^80 - 2^16) * z^(2^16 - 2^0) = z^(2^80 - 2^16 + 2^16 - 2^0) = z^(2^80 - 2^0)*/ + mul(tmp2, tmp2, e16); + + /* tmp2 = tmp2^(2^8) = z^(2^80 - 2^0)*2^8 = z^(2^88 - 2^8) */ + sqr_ntimes(tmp2, tmp2, 8); + + /* tmp2 = tmp2*e8 = z^(2^88 - 2^8) * z^(2^8 - 2^0) = z^(2^88 - 2^8 + 2^8 - 2^0) = z^(2^88 - 2^0)*/ + mul(tmp2, tmp2, e8); + + /* tmp2 = tmp2^(2^4) = z^(2^88 - 2^0)*2^4 = z^(2^92 - 2^4) */ + sqr_ntimes(tmp2, tmp2, 4); + + /* tmp2 = tmp2*e4 = z^(2^92 - 2^4) * z^(2^4 - 2^0) = z^(2^92 - 2^4 + 2^4 - 2^0) = z^(2^92 - 2^0)*/ + mul(tmp2, tmp2, e4); + + /* tmp2 = tmp2^2 = z^(2^92 - 2^0)*2^1 = z^(2^93 - 2^1) */ + sqr(tmp2, tmp2); + /* tmp2 = tmp2^2 = z^(2^93 - 2^1)*2^1 = z^(2^94 - 2^2) */ + sqr(tmp2, tmp2); + /* tmp2 = tmp2*e2 = z^(2^94 - 2^2) * z^(2^2 - 2^0) = z^(2^94 - 2^2 + 2^2 - 2^0) = z^(2^94 - 2^0)*/ + mul(tmp2, tmp2, e2); + /* tmp2 = tmp2^2 = z^(2^94 - 2^0)*2^1 = z^(2^95 - 2^1) */ + sqr(tmp2, tmp2); + /* tmp2 = tmp2^2 = z^(2^95 - 2^1)*2^1 = z^(2^96 - 2^2) */ + sqr(tmp2, tmp2); + /* tmp2 = tmp2*z = z^(2^96 - 2^2) * z = z^(2^96 - 2^2 + 1) = z^(2^96 - 3) */ + mul(tmp2, tmp2, z); + + /* r = tmp1*tmp2 = z^(2^256 - 2^224 + 2^192) * z^(2^96 - 3) = z^(2^256 - 2^224 + 2^192 + 2^96 - 3) */ + m512 r = setzero_i64(); + mul(r, tmp1, tmp2); + + return r; +} + +#undef sqr +#undef mul +#undef sqr_ntimes + +IPP_OWN_DEFN(m512, convert_radix_to_52x5, (const Ipp64u *arad64)) +{ + const m512 mask_rad52 = set1_i64(DIGIT_MASK); + + const m512 idx16 = set_i64( + 0x0019001800170016, // 25, 24, 23, 22, + 0x0016001500140013, // 22, 21, 20, 19, + 0x0013001200110010, // 19, 18, 17, 16, + 0x0010000f000e000d, // 16, 15, 14, 13, + 0x000c000b000a0009, // 12, 11, 10, 9, + 0x0009000800070006, // 9, 8, 7, 6, + 0x0006000500040003, // 6, 5, 4, 3, + 0x0003000200010000); // 3, 2, 1, 0 + + const __m512i shiftR = set_i64( + 12, 8, 4, 0, + 12, 8, 4, 0); + + m512 r = maskz_loadu_i64(0xf, arad64); // load 4 digits + r = permutexvar_i16(idx16, r); + r = srlv_i64(r, shiftR); + r = and_i64(mask_rad52, r); + return r; +} + +IPP_OWN_DEFN(void, convert_radix_to_64x4, (Ipp64u * rrad64, const m512 arad52)) +{ + const m512 shiftL = set_i64( + 4, 0, 4, 0, + 4, 0, 4, 0); + const m512 perm1 = set_i64( + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3e3d3c3b, // {63,63,63,63,62,61,60,59} + 0x3737363534333231, // {55,55,54,53,52,51,50,49} + 0x302e2d2c2b2a2928, // {48,46,45,44,43,42,41,40} + 0x1f1f1f1f1f1f1e1d, // {31,31,31,31,31,31,30,29} + 0x1717171716151413, // {23,23,23,23,22,21,20,19} + 0x0f0f0f0e0d0c0b0a, // {15,15,15,14,13,12,11,10} + 0x0706050403020100); // { 7, 6, 5, 4, 3, 2, 1, 0} + + const m512 perm2 = set_i64( + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3a39383737373737, // {58,57,56,55,55,55,55,55} + 0x2727272727272726, // {39,39,39,39,39,39,39,38} + 0x2524232221201f1f, // {37,36,35,34,33,32,31,31} + 0x1c1b1a1918171717, // {28,27,26,25,24,23,23,23} + 0x1211100f0f0f0f0f, // {18,17,16,15,15,15,15,15} + 0x0908070707070707); // { 9, 8, 7, 7, 7, 7, 7, 7} + + m512 r = arad52; + r = sllv_i64(r, shiftL); + m512 T = permutexvar_i8(perm1, r); + r = permutexvar_i8(perm2, r); + r = or_i64(r, T); + mask_storeu_i64(rrad64, 0xf, r); // store 4 digits +} + +#endif // #if (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p256.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p256.h new file mode 100644 index 000000000..1193ef90b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p256.h @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#if !defined(_IFMA_ARITH_P256R1_H_) +#define _IFMA_ARITH_P256R1_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_alias_avx512.h" +#include + +/** + * \brief + * + * Montgomery multiplication + * + * a * b * r mod n, where r = 2^(6*52) mod n + * + * Note: final normalization to 2^52 radix is not performed and shall be + * handled separately. + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_amm52_p256, (const m512 a, const m512 b)) + +/** + * \brief + * + * Dual variant of ifma_amm52_p256() function. + * + * \param[out] r1 a1 * b1 mod p + * \param[in] a1 first value (in radix 2^52) + * \param[in] b1 second value (in radix 2^52) + * \param[out] r2 a2 * b2 mod p + * \param[in] a2 first value (in radix 2^52) + * \param[in] b2 second value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_amm52_dual_p256, (m512 *r1, const m512 a1, const m512 b1, m512 *r2, const m512 a2, const m512 b2)) + +/** + * \brief + * + * A * A + * + * Note: final normalization to 2^52 radix is not performed and shall be + * handled separately. + * + * \param[in] a value (in radix 2^52) + */ +__INLINE IPP_OWN_DEFN(m512, ifma_ams52_p256, (const m512 a)) +{ + return ifma_amm52_p256(a, a); +} + +/** + * \brief + * + * Dual variant of ifma_ams52_p256() function. + * + * \param[out] r1 + * \param[in] a1 value (in radix 2^52) + * \param[out] r2 + * \param[in] a2 value (in radix 2^52) + */ +__INLINE IPP_OWN_DEFN(void, ifma_ams52_dual_p256, (m512 * r1, const m512 a1, m512 *r2, const m512 a2)) +{ + ifma_amm52_dual_p256(r1, a1, a1, r2, a2, a2); + return; +} + +/** + * \brief + * + * A / 2 + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_half52_p256, (const m512 a)) + +/** + * \brief + * + * Modular inverse modulo p. + * + * 1/z mod p + * + * \param[in] z value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_aminv52_p256, (const m512 z)) + +/** + * \brief + * + * (-A) mod p + * + * \param[in] a input value + */ +IPP_OWN_DECL(m512, ifma_neg52_p256, (const m512 a)) + +/** + * \brief + * + * Conversion to Montgomery domain modulo p. + * + * a * r mod p, where r = 2^(6*52) mod p + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_tomont52_p256, (const m512 a)) + +/** + * \brief + * + * Conversion from Montgomery domain modulo p. + * + * a mod p + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_frommont52_p256, (const m512 a)) + +/* ===================================================================================== */ +/* ===================================================================================== */ + +/** + * \brief + * + * Convert to radix 2^52 from radix 2^64. + * + * \param[in] pa pointer to array of 4 64-bit chunks + */ +IPP_OWN_DECL(m512, convert_radix_to_52x5, (const Ipp64u *pa)) + +/** + * \brief + * + * Convert to radix 2^64 from radix 2^52. + * + * \param[out] pr pointer to array of 4 64-bit chunks + * \param[in] a array of 5 64-bit chunks + */ +IPP_OWN_DECL(void, convert_radix_to_64x4, (Ipp64u * rrad64, const m512 arad52)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ARITH_P256R1_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p384.c new file mode 100644 index 000000000..708cf8440 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p384.c @@ -0,0 +1,432 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_p384.h" +#include "ifma_defs.h" + +#define LEN52 (NUMBER_OF_DIGITS(384, 52)) + +/* p384r1: p = 2^384 - 2^128 - 2^96 + 2^32 - 1 */ +static const __ALIGN64 Ipp64u p384_x1[LEN52] = { + 0x00000000FFFFFFFF, 0x000FF00000000000, 0x000FFFFFFEFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x00000000000FFFFF +}; + +/* modulus 4*p */ +static const __ALIGN64 Ipp64u p384_x4[LEN52] = { + 0x00000003FFFFFFFC, 0x000FC00000000000, 0x000FFFFFFBFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x00000000003FFFFF +}; + +/* to Montgomery conversion constant + * rr = 2^((P384_LEN52*DIGIT_SIZE)*2) mod p384 + */ +static const __ALIGN64 Ipp64u p384_rr[LEN52] = { + 0x0000000000000000, 0x000FE00000001000, 0x0000000000FFFFFF, 0x0000000000000020, 0x0000FFFFFFFE0000, 0x0000000020000000, 0x0000000000000100, 0x0000000000000000 +}; + +static const __ALIGN64 Ipp64u ones[LEN52] = { + 1, 0, 0, 0, 0, 0, 0, 0 +}; + +/* R = (A/2) */ +IPP_OWN_DEFN(m512, ifma_half52_p384, (const m512 a)) +{ + const m512 M = loadu_i64(p384_x1); + const m512 zero = setzero_i64(); + const m512 one = set1_i64(1LL); + + const mask8 is_last_one = cmp_i64_mask(and_i64(a, one), zero, _MM_CMPINT_EQ); + const mask8 mask = (mask8)((is_last_one & 1) - 1); + + m512 r = mask_add_i64(a, mask, a, M); + r = ifma_lnorm52(r); + + /* 1-bit shift right */ + /* extract last bit + >> 64 */ + const mask64 mask_shift = 0x00ffffffffffffff; + const m512 idx_shift = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 shift_right = maskz_permutexvar_i8(mask_shift, idx_shift, and_i64(r, one)); + /* set last bit is first bit (52 radix) */ + shift_right = slli_i64(shift_right, DIGIT_SIZE - 1); + /* join first new bit */ + r = srli_i64(r, 1); /* create slot by first bit 1111 -> 0111 */ + r = add_i64(r, shift_right); /* join first and other bit */ + + return r; +} + +IPP_OWN_DEFN(m512, ifma_neg52_p384, (const m512 a)) +{ + const m512 M4 = loadu_i64(p384_x4); + + /* a == 0 ? 0xFF : 0 */ + const mask8 mask_zero = is_zero_i64(a); + + /* r = 4*p - a */ + m512 r = mask_sub_i64(a, ~mask_zero, M4, a); + r = ifma_norm52(r); + return r; +} + +#define MULT_ROUND(R, A, B, IDX) \ + const m512 Bi##R##IDX = permutexvar_i8(idx_b##IDX, (B)); \ + const m512 amBiLo##R##IDX = madd52lo_i64(zero, (A), Bi##R##IDX); \ + m512 tr##R##IDX = madd52hi_i64(zero, (A), Bi##R##IDX); \ + { \ + /* low */ \ + (R) = add_i64((R), amBiLo##R##IDX); \ + const m512 R0 = permutexvar_i8(idx_b0, (R)); \ + const m512 u = add_i64(slli_i64(R0, 32), R0); \ + tr##R##IDX = madd52hi_i64(tr##R##IDX, M, u); \ + (R) = madd52lo_i64((R), M, u); \ + /* shift */ \ + const m512 carryone = maskz_srai_i64(maskone, (R), DIGIT_SIZE); \ + tr##R##IDX = add_i64(tr##R##IDX, carryone); \ + (R) = maskz_permutexvar_i8(mask_sr64, idx_sr64, (R)); \ + /* hi */ \ + (R) = add_i64((R), tr##R##IDX); \ + } + +/* gueron data */ +/* R = (A*B) - no normalization radix 52 */ +IPP_OWN_DEFN(m512, ifma_amm52_p384, (const m512 a, const m512 b)) +{ + const m512 M = loadu_i64(p384_x1); /* p */ + const m512 zero = setzero_i64(); + const mask8 maskone = 0x1; + + /* Index broadcast */ + const m512 idx_b0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const m512 idx_b1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const m512 idx_b2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const m512 idx_b3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const m512 idx_b4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const m512 idx_b5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + const m512 idx_b6 = set_i64(REPL8(0x3736353433323130)); // 55, 54, 53, 52, 51, 50, 49, 48 + const m512 idx_b7 = set_i64(REPL8(0x3f3e3d3c3b3a3938)); // 63, 62, 61, 60, 59, 58, 57, 56 + + /* Mask to shift zmm register right on 64-bit */ + const mask64 mask_sr64 = 0x00ffffffffffffff; + const m512 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 r = setzero_i64(); + /* P384 + * m' mod b = 2^32 + 1 + * + * Algorithm + * a[] b[] - input data ((in radix 2^52)) m[] - module p384 + * + * when u = R[0]*m' mod b + * 1) R = R + a[] * b[i] (lo) + * 2) R = R + m[] * u (lo) + * 3) R = R >> 64 + * 4) R = R + a[] * b[i] (hi) + * 5) R = R + m[] * u (hi) + */ + /* one round = O(32) */ + MULT_ROUND(r, a, b, 0) + MULT_ROUND(r, a, b, 1) + MULT_ROUND(r, a, b, 2) + MULT_ROUND(r, a, b, 3) + MULT_ROUND(r, a, b, 4) + MULT_ROUND(r, a, b, 5) + MULT_ROUND(r, a, b, 6) + MULT_ROUND(r, a, b, 7) + + return r; +} + +IPP_OWN_DEFN(void, ifma_amm52_dual_p384, (m512 * pr1, const m512 a1, const m512 b1, m512 *pr2, const m512 a2, const m512 b2)) +{ + const m512 M = loadu_i64(p384_x1); /* p */ + const m512 zero = setzero_i64(); + const mask8 maskone = 0x1; + + /* Index broadcast */ + const m512 idx_b0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const m512 idx_b1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const m512 idx_b2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const m512 idx_b3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const m512 idx_b4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const m512 idx_b5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + const m512 idx_b6 = set_i64(REPL8(0x3736353433323130)); // 55, 54, 53, 52, 51, 50, 49, 48 + const m512 idx_b7 = set_i64(REPL8(0x3f3e3d3c3b3a3938)); // 63, 62, 61, 60, 59, 58, 57, 56 + + /* Mask to shift zmm register right on 64-bit */ + const mask64 mask_sr64 = 0x00ffffffffffffff; + const m512 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + m512 r1 = setzero_i64(); + m512 r2 = setzero_i64(); + /* P384 + * m' mod b = 2^32 + 1 + * + * Algorithm + * a[] b[] - input data ((in radix 2^52)) m[] - module p384 + * + * when u = R[0]*m' mod b + * 1) R = R + a[] * b[i] (lo) + * 2) R = R + m[] * u (lo) + * 3) R = R >> 64 + * 4) R = R + a[] * b[i] (hi) + * 5) R = R + m[] * u (hi) + */ + /* one round = O(32) */ + /* 0-1 */ + MULT_ROUND(r1, a1, b1, 0) + MULT_ROUND(r1, a1, b1, 1) + /* 0-1 */ + MULT_ROUND(r2, a2, b2, 0) + MULT_ROUND(r2, a2, b2, 1) + /* 2-3 */ + MULT_ROUND(r1, a1, b1, 2) + MULT_ROUND(r1, a1, b1, 3) + /* 2-3 */ + MULT_ROUND(r2, a2, b2, 2) + MULT_ROUND(r2, a2, b2, 3) + /* 4-5 */ + MULT_ROUND(r1, a1, b1, 4) + MULT_ROUND(r1, a1, b1, 5) + /* 4-5 */ + MULT_ROUND(r2, a2, b2, 4) + MULT_ROUND(r2, a2, b2, 5) + /* 6-7 */ + MULT_ROUND(r1, a1, b1, 6) + MULT_ROUND(r1, a1, b1, 7) + /* 6-7 */ + MULT_ROUND(r2, a2, b2, 6) + MULT_ROUND(r2, a2, b2, 7) + + /* set out */ + *pr1 = r1; + *pr2 = r2; + return; +} + +/* R = (A*B) with norm */ +__INLINE m512 ifma_amm52_p384_norm(const m512 a, const m512 b) +{ + m512 r = ifma_amm52_p384(a, b); + /* normalization */ + return ifma_lnorm52(r); +} + +/* R = (A*A) with norm */ +__INLINE m512 m512_sqr_norm(const m512 a) +{ + return ifma_amm52_p384_norm(a, a); +} + +/* to Montgomery domain */ +IPP_OWN_DEFN(m512, ifma_tomont52_p384, (const m512 a)) +{ + const m512 RR = loadu_i64(p384_rr); + return ifma_amm52_p384_norm(a, RR); +} + +static m512 mod_reduction_p384(const m512 a) +{ + const m512 M = loadu_i64(p384_x1); + const m512 zero = setzero_i64(); + + /* r = a - M */ + m512 r = sub_i64(a, M); + r = ifma_norm52(r); + + /* 1 < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(r, DIGIT_SIZE - 1), _MM_CMPINT_LT); + const mask8 mask = check_bit(lt, 7); + + /* maks != 0 ? a : r */ + r = mask_mov_i64(r, mask, a); + return r; +} + +/* from Montgomery domain */ +IPP_OWN_DEFN(m512, ifma_frommont52_p384, (const m512 a)) +{ + const m512 one = loadu_i64(ones); + + /* from mont */ + m512 r = ifma_amm52_p384_norm(a, one); + r = mod_reduction_p384(r); + return r; +} + +#define sqr(R, A) (R) = m512_sqr_norm((A)) +#define mul(R, A, B) (R) = ifma_amm52_p384_norm((A), (B)); +#define mul_dual(R1, A1, B1, R2, A2, B2) \ + ifma_amm52_dual_p384(&(R1), (A1), (B1), &(R2), (A2), (B2)); \ + ifma_lnorm52_dual(&(R1), (R1), &(R2), (R2)) + +__INLINE m512 ifma_ams52_p384_ntimes(const m512 a, Ipp32s n) +{ + m512 r = a; + for (; n > 0; --n) + sqr(r, r); + return r; +} + +#define sqr_ntimes(R, A, N) (R) = ifma_ams52_p384_ntimes((A), (N)) + +/* R = 1/z */ +IPP_OWN_DEFN(m512, ifma_aminv52_p384, (const m512 z)) +{ + m512 u, v, zD, zE, zF; + u = v = zD = zE = zF = setzero_i64(); + + sqr(u, z); /* u = z^2 */ + mul(v, u, z); /* v = z^2 * z = z^3 */ + sqr_ntimes(zF, v, 2); /* zF = (z^3)^(2^2) = z^12 */ + /**/ + mul(zD, zF, z); /* zD = z^11 * z = z^xD */ + mul_dual(zE, zF, u, /* zE = z^11 * z^2 = z^xE */ + zF, zF, v); /* zF = z^11 * z^3 = z^xF */ + /**/ + sqr_ntimes(u, zF, 4); /* u = (z^xF)^(2^4) = z^xF0 */ + mul_dual(zD, u, zD, /* zD = z^xF0 * z^xD = z^xFD */ + zE, u, zE); /* zE = z^xF0 * z^xE = z^xFE */ + mul(zF, u, zF); /* zF = z^xF0 * z^xF = z^xFF */ + /**/ + sqr_ntimes(u, zF, 8); /* u = (z^xFF)^(2^8) = z^xFF00 */ + mul_dual(zD, u, zD, /* zD = z^xFF00 * z^xFD = z^xFFFD */ + zE, u, zE); /* zE = z^xFF00 * z^xFE = z^xFFFE */ + mul(zF, u, zF); /* zF = z^xFF00 * z^xFF = z^xFFFF */ + /**/ + sqr_ntimes(u, zF, 16); /* u = (z^xFFFF)^(2^16) = z^xFFFF0000 */ + mul_dual(zD, u, zD, /* zD = z^xFFFF0000 * z^xFFFD = z^xFFFFFFFD */ + zE, u, zE); /* zE = z^xFFFF0000 * z^xFFFE = z^xFFFFFFFE */ + mul(zF, u, zF); /* zF = z^xFFFF0000 * z^xFFFF = z^xFFFFFFFF */ + /**/ + sqr_ntimes(u, zF, 32); /* u = (z^xFFFFFFFF)^(2^32) = z^xFFFFFFFF00000000 */ + mul_dual(zE, u, zE, /* zE = z^xFFFFFFFF00000000 * z^xFFFFFFFE = z^xFFFFFFFFFFFFFFFE */ + zF, u, zF); /* zF = z^xFFFFFFFF00000000 * z^xFFFFFFFF = z^xFFFFFFFFFFFFFFFF */ + /* v = z^xFFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, zF, 64); + mul(v, v, zF); + /* v = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF */ + sqr_ntimes(v, v, 64); + mul(v, v, zF); + /* v = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFE + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE */ + sqr_ntimes(v, v, 64); + mul(v, v, zE); + /* v = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.0000000000000000 * z^xFFFFFFFF00000000 + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFF00000000 */ + sqr_ntimes(v, v, 64); + mul(v, v, u); + /* r = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFF00000000.0000000000000000 * z^xFFFFFFFD + = z^xFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFF00000000.00000000FFFFFFFD */ + sqr_ntimes(v, v, 64); + m512 r = setzero_i64(); + mul(r, v, zD); + return r; +} + +#undef sqr +#undef mul +#undef mul_dual +#undef sqr_ntimes + +IPP_OWN_DEFN(m512, convert_radix_to_52x8, (const Ipp64u *arad64)) +{ + /* load mask to register */ + const mask8 mask_load = 0x3f; + const m512 mask_rad52 = set1_i64(DIGIT_MASK); + /* set data */ + const m512 idx16 = set_i64( + 0x0019001800170016, // 25, 24, 23, 22, + 0x0016001500140013, // 22, 21, 20, 19, + 0x0013001200110010, // 19, 18, 17, 16, + 0x0010000f000e000d, // 16, 15, 14, 13, + 0x000c000b000a0009, // 12, 11, 10, 9, + 0x0009000800070006, // 9, 8, 7, 6, + 0x0006000500040003, // 6, 5, 4, 3, + 0x0003000200010000); // 3, 2, 1, 0 + + const m512 shift_right = set_i64(12LL, 8LL, 4LL, 0LL, 12LL, 8LL, 4LL, 0LL); + + m512 r = maskz_loadu_i64(mask_load, arad64); + r = permutexvar_i16(idx16, r); + r = srlv_i64(r, shift_right); + r = and_i64(mask_rad52, r); + return r; +} + +IPP_OWN_DEFN(void, convert_radix_to_64x6, (Ipp64u * rrad64, const m512 arad52)) +{ + /* mask store */ + const mask8 mask_store = 0x3f; + const m512 shift_left = set_i64(4LL, 0LL, 4LL, 0LL, 4LL, 0LL, 4LL, 0LL); + const m512 idx_up8 = set_i64( + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3e3d3c3b, // {63,63,63,63,62,61,60,59} + 0x3737363534333231, // {55,55,54,53,52,51,50,49} + 0x302e2d2c2b2a2928, // {48,46,45,44,43,42,41,40} + 0x1f1f1f1f1f1f1e1d, // {31,31,31,31,31,31,30,29} + 0x1717171716151413, // {23,23,23,23,22,21,20,19} + 0x0f0f0f0e0d0c0b0a, // {15,15,15,14,13,12,11,10} + 0x0706050403020100); // { 7, 6, 5, 4, 3, 2, 1, 0} + + const m512 idx_down8 = set_i64( + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3a39383737373737, // {58,57,56,55,55,55,55,55} + 0x2727272727272726, // {39,39,39,39,39,39,39,38} + 0x2524232221201f1f, // {37,36,35,34,33,32,31,31} + 0x1c1b1a1918171717, // {28,27,26,25,24,23,23,23} + 0x1211100f0f0f0f0f, // {18,17,16,15,15,15,15,15} + 0x0908070707070707); // { 9, 8, 7, 7, 7, 7, 7, 7} + + m512 r = arad52; + + r = sllv_i64(r, shift_left); + m512 T = permutexvar_i8(idx_up8, r); + r = permutexvar_i8(idx_down8, r); + r = or_i64(r, T); + mask_storeu_i64(rrad64, mask_store, r); + return; +} + +#endif // #if (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p384.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p384.h new file mode 100644 index 000000000..849c20646 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p384.h @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#if !defined(_IFMA_ARITH_P384R1_H_) +#define _IFMA_ARITH_P384R1_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_alias_avx512.h" +#include + +/** + * \brief + * + * Montgomery multiplication + * + * a * b * r mod n, where r = 2^(6*52) mod n + * + * Note: final normalization to 2^52 radix is not performed and shall be + * handled separately. + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_amm52_p384, (const m512 a, const m512 b)) + +/** + * \brief + * + * Dual variant of ifma_amm52_p384() function. + * + * \param[out] r1 + * \param[in] a1 first value (in radix 2^52) + * \param[in] b1 second value (in radix 2^52) + * \param[out] r2 + * \param[in] a2 first value (in radix 2^52) + * \param[in] b2 second value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_amm52_dual_p384, (m512 * r1, const m512 a1, const m512 b1, m512 *r2, const m512 a2, const m512 b2)) + +/** + * \brief + * + * A * A + * + * Note: final normalization to 2^52 radix is not performed and shall be + * handled separately. + * + * \param[in] a value (in radix 2^52) + */ +__INLINE IPP_OWN_DEFN(m512, ifma_ams52_p384, (const m512 a)) +{ + return ifma_amm52_p384(a, a); +} + +/** + * \brief + * + * Dual variant of ifma_ams52_p384() function. + * + * \param[out] r1 + * \param[in] a1 value (in radix 2^52) + * \param[out] r2 + * \param[in] a2 value (in radix 2^52) + */ +__INLINE IPP_OWN_DEFN(void, ifma_ams52_dual_p384, (m512 * r1, const m512 a1, m512 *r2, const m512 a2)) +{ + ifma_amm52_dual_p384(r1, a1, a1, r2, a2, a2); + return; +} + +/** + * \brief + * + * A / 2 + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_half52_p384, (const m512 a)) + +/** + * \brief + * + * Modular inverse modulo p. + * + * 1/z mod p + * + * \param[in] z value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_aminv52_p384, (const m512 z)) + +/** + * \brief + * + * (-A) mod p + * + * \param[in] a input value + */ +IPP_OWN_DECL(m512, ifma_neg52_p384, (const m512 a)) + +/** + * \brief + * + * Conversion to Montgomery domain modulo p. + * + * a * r mod p, where r = 2^(6*52) mod p + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_tomont52_p384, (const m512 a)) + +/** + * \brief + * + * Conversion from Montgomery domain modulo p. + * + * a mod p + * + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_frommont52_p384, (const m512 a)) + +/* ===================================================================================== */ + +/** + * \brief + * + * Convert to radix 2^52 from radix 2^64. + * + * \param[in] pa pointer to array of 4 64-bit chunks + */ +IPP_OWN_DECL(m512, convert_radix_to_52x8, (const Ipp64u *pa)) + +/** + * \brief + * + * Convert to radix 2^64 from radix 2^52. + * + * \param[out] pr pointer to array of 4 64-bit chunks + * \param[in] a array of 5 64-bit chunks + */ +IPP_OWN_DECL(void, convert_radix_to_64x6, (Ipp64u * rrad64, const m512 arad52)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ARITH_P384R1_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p521.c new file mode 100644 index 000000000..33640e6ac --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p521.c @@ -0,0 +1,1175 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_p521.h" + +#define NORM_LO_MID_ROUND(CARRY, RLO, RHI) \ + (CARRY) = m256_srai_i64((RLO), DIGIT_SIZE_52); \ + (RLO) = m256_and_i64((RLO), filt_rad52); \ + (CARRY) = m256_permutexvar_i8(idx8_shuffle, (CARRY)); \ + (RHI) = m256_mask_add_i64((RHI), 0x1, (RHI), (CARRY)); \ + (RLO) = m256_mask_add_i64((RLO), 0xE, (RLO), (CARRY)); + +#define NORM_HI_ROUND(CARRY, RHI) \ + (CARRY) = m256_maskz_srai_i64(0x7, (RHI), DIGIT_SIZE_52); \ + (CARRY) = m256_maskz_permutexvar_i8(0xFFFF00, idx8_shuffle, (CARRY)); \ + (RHI) = m256_add_i64(m256_and_i64((RHI), filt_rad52), (CARRY)); + +IPP_OWN_DEFN(void, ifma_norm52_p521, (fe521 pr[], const fe521 a)) +{ + const m256i filt_rad52 = m256_set1_i64(DIGIT_MASK_52); + + fe521 r; + FE521_COPY(r, a); + + const m256i idx8_shuffle = m256_set_i8(23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0, + 31, 30, 29, 28, 27, 26, 25, 24); + m256i carry; + /* shift low carry */ + NORM_LO_MID_ROUND(carry, FE521_LO(r), FE521_MID(r)) + NORM_LO_MID_ROUND(carry, FE521_LO(r), FE521_MID(r)) + NORM_LO_MID_ROUND(carry, FE521_LO(r), FE521_MID(r)) + NORM_LO_MID_ROUND(carry, FE521_LO(r), FE521_MID(r)) + /* shift mid */ + NORM_LO_MID_ROUND(carry, FE521_MID(r), FE521_HI(r)) + NORM_LO_MID_ROUND(carry, FE521_MID(r), FE521_HI(r)) + NORM_LO_MID_ROUND(carry, FE521_MID(r), FE521_HI(r)) + NORM_LO_MID_ROUND(carry, FE521_MID(r), FE521_HI(r)) + /* shift hi */ + NORM_HI_ROUND(carry, FE521_HI(r)) + NORM_HI_ROUND(carry, FE521_HI(r)) + + FE521_COPY(*pr, r); + return; +} + +IPP_OWN_DEFN(void, ifma_norm52_dual_p521, + (fe521 pr1[], const fe521 a1, + fe521 pr2[], const fe521 a2)) +{ + const m256i filt_rad52 = m256_set1_i64(DIGIT_MASK_52); + + fe521 r1, r2; + FE521_COPY(r1, a1); + FE521_COPY(r2, a2); + + const m256i idx8_shuffle = m256_set_i8(23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0, + 31, 30, 29, 28, 27, 26, 25, 24); + m256i carry_1; + m256i carry_2; + /* shift low carry */ + NORM_LO_MID_ROUND(carry_1, FE521_LO(r1), FE521_MID(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_LO(r2), FE521_MID(r2)) + NORM_LO_MID_ROUND(carry_1, FE521_LO(r1), FE521_MID(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_LO(r2), FE521_MID(r2)) + NORM_LO_MID_ROUND(carry_1, FE521_LO(r1), FE521_MID(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_LO(r2), FE521_MID(r2)) + NORM_LO_MID_ROUND(carry_1, FE521_LO(r1), FE521_MID(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_LO(r2), FE521_MID(r2)) + /* shift mid */ + NORM_LO_MID_ROUND(carry_1, FE521_MID(r1), FE521_HI(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_MID(r2), FE521_HI(r2)) + NORM_LO_MID_ROUND(carry_1, FE521_MID(r1), FE521_HI(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_MID(r2), FE521_HI(r2)) + NORM_LO_MID_ROUND(carry_1, FE521_MID(r1), FE521_HI(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_MID(r2), FE521_HI(r2)) + NORM_LO_MID_ROUND(carry_1, FE521_MID(r1), FE521_HI(r1)) + NORM_LO_MID_ROUND(carry_2, FE521_MID(r2), FE521_HI(r2)) + /* shift hi */ + NORM_HI_ROUND(carry_1, FE521_HI(r1)) + NORM_HI_ROUND(carry_2, FE521_HI(r2)) + NORM_HI_ROUND(carry_1, FE521_HI(r1)) + NORM_HI_ROUND(carry_2, FE521_HI(r2)) + + FE521_COPY(*pr1, r1); + FE521_COPY(*pr2, r2); + return; +} + +#define ROUND_LOW_MID_LNORM(RLO, RHI) \ + { \ + m256i carry = m256_srai_i64((RLO), DIGIT_SIZE_52); \ + carry = m256_permutexvar_i8(idx8_shuffle, carry); \ + (RLO) = m256_and_i64((RLO), filt_rad52); \ + (RLO) = m256_mask_add_i64((RLO), 0xE, (RLO), carry); \ + (RHI) = m256_mask_add_i64((RHI), 0x1, (RHI), carry); \ + } + +#define ROUND_HI_LNORM(R) \ + { \ + m256i carry = m256_srai_i64((R), DIGIT_SIZE_52); \ + carry = m256_permutexvar_i8(idx8_shuffle, carry); \ + (R) = m256_and_i64((R), filt_rad52); \ + (R) = m256_mask_add_i64((R), 0xE, (R), carry); \ + } + +#define CREATE_MASK_ONE(OUT, R, MASK_CMP) \ + { \ + const int mk_lo = (int)(m256_cmp_i64_mask(filt_rad52, FE521_LO((R)), (MASK_CMP))); \ + const int mk_mid = (int)(m256_cmp_i64_mask(filt_rad52, FE521_MID((R)), (MASK_CMP))); \ + const int mk_hi = (int)(m256_cmp_i64_mask(filt_rad52, FE521_HI((R)), (MASK_CMP))); \ + \ + (OUT) = (mk_lo & 0xF) | ((mk_mid & 0xF) << 4) | ((mk_hi & 0xF) << 8); \ + } + +#define ADD_VALUE_BY_MASK(R, MASK, VAL) \ + { \ + FE521_LO((R)) = m256_mask_add_i64(FE521_LO((R)), (mask8)((MASK)&0xF), FE521_LO((R)), (VAL)); \ + FE521_MID((R)) = m256_mask_add_i64(FE521_MID((R)), (mask8)(((MASK) >> 4) & 0xF), FE521_MID((R)), (VAL)); \ + FE521_HI((R)) = m256_mask_add_i64(FE521_HI((R)), (mask8)(((MASK) >> 8) & 0x7), FE521_HI((R)), (VAL)); \ + } + +#define FILT_52(R) \ + { \ + FE521_LO((R)) = m256_and_i64(FE521_LO((R)), filt_rad52); \ + FE521_MID((R)) = m256_and_i64(FE521_MID((R)), filt_rad52); \ + FE521_HI((R)) = m256_and_i64(FE521_HI((R)), filt_rad52); \ + } + +IPP_OWN_DEFN(void, ifma_lnorm52_p521, (fe521 pr[], const fe521 a)) +{ + const m256i filt_rad52 = m256_set1_i64(DIGIT_MASK_52); + const m256i one = m256_set1_i64(1ULL); + const m256i idx8_shuffle = m256_set_i8(23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0, + 31, 30, 29, 28, 27, 26, 25, 24); + + fe521 r; + FE521_COPY(r, a); + + /* standart step - first round normalization */ + /* low */ + ROUND_LOW_MID_LNORM(FE521_LO(r), FE521_MID(r)) + /* mid */ + ROUND_LOW_MID_LNORM(FE521_MID(r), FE521_HI(r)) + /* hi */ + ROUND_HI_LNORM(FE521_HI(r)) + + /* create mask add ONE(1) to slot */ + int k1, k2; + /* create k2 (r) == 0xF(13) */ + CREATE_MASK_ONE(k2, r, _MM_CMPINT_EQ) + /* create k1 (r) > 0xF(13) */ + CREATE_MASK_ONE(k1, r, _MM_CMPINT_LT) + + k1 = k2 + (k1 << 1); + k1 ^= k2; + + ADD_VALUE_BY_MASK(r, k1, one) + FILT_52(r) + + FE521_COPY(*pr, r); + return; +} + +IPP_OWN_DEFN(void, ifma_lnorm52_dual_p521, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) +{ + const m256i filt_rad52 = m256_set1_i64(DIGIT_MASK_52); + const m256i one = m256_set1_i64(1ULL); + const m256i idx8_shuffle = m256_set_i8(23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0, + 31, 30, 29, 28, 27, 26, 25, 24); + fe521 r1, r2; + FE521_COPY(r1, a1); + FE521_COPY(r2, a2); + + /* standart step - first round normalization */ + /* low */ + ROUND_LOW_MID_LNORM(FE521_LO(r1), FE521_MID(r1)) + ROUND_LOW_MID_LNORM(FE521_LO(r2), FE521_MID(r2)) + /* mid */ + ROUND_LOW_MID_LNORM(FE521_MID(r1), FE521_HI(r1)) + ROUND_LOW_MID_LNORM(FE521_MID(r2), FE521_HI(r2)) + /* hi */ + ROUND_HI_LNORM(FE521_HI(r1)) + ROUND_HI_LNORM(FE521_HI(r2)) + + /* create mask add ONE(1) to slot */ + int k11, k21; + int k12, k22; + /* create k2 (r) == 0xF(13) */ + CREATE_MASK_ONE(k21, r1, _MM_CMPINT_EQ) + CREATE_MASK_ONE(k22, r2, _MM_CMPINT_EQ) + /* create k1 (r) > 0xF(13) */ + CREATE_MASK_ONE(k11, r1, _MM_CMPINT_LT) + CREATE_MASK_ONE(k12, r2, _MM_CMPINT_LT) + + k11 = k21 + (k11 << 1); + k11 ^= k21; + + k12 = k22 + (k12 << 1); + k12 ^= k22; + + ADD_VALUE_BY_MASK(r1, k11, one) + ADD_VALUE_BY_MASK(r2, k12, one) + + FILT_52(r1) + FILT_52(r2) + + FE521_COPY(*pr1, r1); + FE521_COPY(*pr2, r2); + return; +} + +#define group_madd52hi_i64(R, A, B, C) \ + FE521_LO(R) = m256_madd52hi_i64(FE521_LO(A), FE521_LO(B), (C)); \ + FE521_MID(R) = m256_madd52hi_i64(FE521_MID(A), FE521_MID(B), (C)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(A), FE521_HI(B), (C)) + +#define group_madd52lo_i64(R, A, B, C) \ + FE521_LO(R) = m256_madd52lo_i64(FE521_LO(A), FE521_LO(B), (C)); \ + FE521_MID(R) = m256_madd52lo_i64(FE521_MID(A), FE521_MID(B), (C)); \ + FE521_HI(R) = m256_madd52lo_i64(FE521_HI(A), FE521_HI(B), (C)) + +#define MUL_ROUND(R, A, BI, BJ) \ + FE521_SET((R)) = m256_setzero_i64(); \ + group_madd52hi_i64((R), (R), (A), (BI)); \ + group_madd52lo_i64((R), (R), (A), (BJ)); + +#define REDUCTION(R, U, REDUCT) \ + (U) = m256_permutexvar_i8(idx0, FE521_LO(R)); \ + /* shift */ \ + FE521_LO(R) = m256_alignr_i64(FE521_MID(R), FE521_LO(R), 1); \ + FE521_MID(R) = m256_alignr_i64(FE521_HI(R), FE521_MID(R), 1); \ + FE521_HI(R) = m256_maskz_permutexvar_i8(mask_sr64, idx_sr64, FE521_HI(R)); \ + /* carry chunk 1 */ \ + FE521_LO(REDUCT) = m256_maskz_srai_i64(0x1, (U), DIGIT_SIZE_52); \ + /* carry chunk 2 */ \ + (U) = m256_and_i64((U), filt_rad52); \ + FE521_HI(REDUCT) = m256_maskz_add_i64(0x2, (U), (U)); \ + FE521_LO(R) = m256_add_i64(FE521_LO(R), FE521_LO(REDUCT)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(REDUCT)); + +IPP_OWN_DEFN(void, ifma_amm52_p521, (fe521 pr[], const fe521 a, const fe521 b)) +{ + const Ipp64s *pb_lo = (const Ipp64s *)(&(FE521_LO(b))); + const Ipp64s *pb_mid = (const Ipp64s *)(&(FE521_MID(b))); + const Ipp64s *pb_hi = (const Ipp64s *)(&(FE521_HI(b))); + + const m256i b0 = m256_set1_i64(pb_lo[0]); + const m256i b1 = m256_set1_i64(pb_lo[1]); + const m256i b2 = m256_set1_i64(pb_lo[2]); + const m256i b3 = m256_set1_i64(pb_lo[3]); + const m256i b4 = m256_set1_i64(pb_mid[0]); + const m256i b5 = m256_set1_i64(pb_mid[1]); + const m256i b6 = m256_set1_i64(pb_mid[2]); + const m256i b7 = m256_set1_i64(pb_mid[3]); + const m256i b8 = m256_set1_i64(pb_hi[0]); + const m256i b9 = m256_set1_i64(pb_hi[1]); + const m256i b10 = m256_set1_i64(pb_hi[2]); + + fe521 r0; + fe521 p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10; + + /* first */ + FE521_SET(r0) = m256_setzero_i64(); + group_madd52lo_i64(r0, r0, a, b0); + /* last */ + FE521_SET(p10) = m256_setzero_i64(); + group_madd52hi_i64(p10, p10, a, b10); + /* round mul */ + MUL_ROUND(p0, a, b0, b1) + MUL_ROUND(p1, a, b1, b2) + MUL_ROUND(p2, a, b2, b3) + MUL_ROUND(p3, a, b3, b4) + MUL_ROUND(p4, a, b4, b5) + MUL_ROUND(p5, a, b5, b6) + MUL_ROUND(p6, a, b6, b7) + MUL_ROUND(p7, a, b7, b8) + MUL_ROUND(p8, a, b8, b9) + MUL_ROUND(p9, a, b9, b10) + + const m256i filt_rad52 = m256_set1_i64(DIGIT_MASK_52); + const m256i idx0 = m256_set_i8(REPL4(7, 6, 5, 4, 3, 2, 1, 0)); /* B[ 0] -> chunk1[0] */ + /* chunk2 shift bit >> 64 */ + const mask32 mask_sr64 = 0x00FFFFFF; + const m256i idx_sr64 = m256_set_i8(0, 0, 0, 0, 0, 0, 0, 0, + 31, 30, 29, 28, 27, 26, 25, 24, + 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8); + + fe521 reduct; + FE521_SET(reduct) = m256_setzero_i64(); + m256i u; + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p0); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p1); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p2); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p3); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p4); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p5); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p6); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p7); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p8); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p9); + REDUCTION(r0, u, reduct) + + fe521_add_no_red(r0, r0, p10); + + FE521_COPY(*pr, r0); + return; +} + +#define MUL_LO_ROUND(R, A, \ + AI, MMI, MAI, \ + AJ, MMJ, MAJ) \ + { \ + fe521 tmp; \ + FE521_SET(R) = FE521_SET(tmp) = m256_setzero_i64(); \ + /* high */ \ + FE521_LO(R) = m256_maskz_madd52hi_i64((MMI), FE521_LO(R), FE521_LO(A), (AI)); \ + FE521_MID(R) = m256_madd52hi_i64(FE521_MID(R), FE521_MID(A), (AI)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(R), FE521_HI(A), (AI)); \ + /* lo */ \ + FE521_LO(tmp) = m256_maskz_madd52lo_i64((MMJ), FE521_LO(tmp), FE521_LO(A), (AJ)); \ + FE521_MID(tmp) = m256_madd52lo_i64(FE521_MID(tmp), FE521_MID(A), (AJ)); \ + FE521_HI(tmp) = m256_madd52lo_i64(FE521_HI(tmp), FE521_HI(A), (AJ)); \ + /* double hi */ \ + FE521_LO(R) = m256_mask_add_i64(FE521_LO(R), (MAI), FE521_LO(R), FE521_LO(R)); \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(R)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(R)); \ + /* double lo */ \ + FE521_LO(tmp) = m256_mask_add_i64(FE521_LO(tmp), (MAJ), FE521_LO(tmp), FE521_LO(tmp)); \ + FE521_MID(tmp) = m256_add_i64(FE521_MID(tmp), FE521_MID(tmp)); \ + FE521_HI(tmp) = m256_add_i64(FE521_HI(tmp), FE521_HI(tmp)); \ + /* add lo + hi */ \ + FE521_LO(R) = m256_add_i64(FE521_LO(R), FE521_LO(tmp)); \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(tmp)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(tmp)); \ + } + +#define MUL_LO_LAST_ROUND(R, A, \ + AI, MMI, MAI, \ + AJ, MMJ) \ + { \ + fe521 tmp; \ + FE521_SET(R) = FE521_SET(tmp) = m256_setzero_i64(); \ + /* high */ \ + FE521_LO(R) = m256_maskz_madd52hi_i64((MMI), FE521_LO(R), FE521_LO(A), (AI)); \ + FE521_MID(R) = m256_madd52hi_i64(FE521_MID(R), FE521_MID(A), (AI)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(R), FE521_HI(A), (AI)); \ + /* lo */ \ + FE521_LO(tmp) = m256_maskz_madd52lo_i64((MMJ), FE521_LO(tmp), FE521_LO(A), (AJ)); \ + FE521_MID(tmp) = m256_madd52lo_i64(FE521_MID(tmp), FE521_MID(A), (AJ)); \ + FE521_HI(tmp) = m256_madd52lo_i64(FE521_HI(tmp), FE521_HI(A), (AJ)); \ + /* double hi */ \ + FE521_LO(R) = m256_mask_add_i64(FE521_LO(R), (MAI), FE521_LO(R), FE521_LO(R)); \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(R)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(R)); \ + /* double lo */ \ + FE521_MID(tmp) = m256_add_i64(FE521_MID(tmp), FE521_MID(tmp)); \ + FE521_HI(tmp) = m256_add_i64(FE521_HI(tmp), FE521_HI(tmp)); \ + /* add lo + hi */ \ + FE521_LO(R) = m256_add_i64(FE521_LO(R), FE521_LO(tmp)); \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(tmp)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(tmp)); \ + } + +#define MUL_MID_FIRST_ROUND(R, A, \ + AI, MMI, \ + AJ, MAJ) \ + { \ + fe521 tmp; \ + FE521_SET(R) = FE521_MID(tmp) = FE521_HI(tmp) = m256_setzero_i64(); \ + /* high */ \ + FE521_LO(R) = m256_maskz_madd52hi_i64((MMI), FE521_LO(R), FE521_LO(A), (AI)); \ + FE521_MID(R) = m256_madd52hi_i64(FE521_MID(R), FE521_MID(A), (AI)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(R), FE521_HI(A), (AI)); \ + /* lo */ \ + FE521_MID(tmp) = m256_madd52lo_i64(FE521_MID(tmp), FE521_MID(A), (AJ)); \ + FE521_HI(tmp) = m256_madd52lo_i64(FE521_HI(tmp), FE521_HI(A), (AJ)); \ + /* double hi */ \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(R)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(R)); \ + /* double lo */ \ + FE521_MID(tmp) = m256_mask_add_i64(FE521_MID(tmp), (MAJ), FE521_MID(tmp), FE521_MID(tmp)); \ + FE521_HI(tmp) = m256_add_i64(FE521_HI(tmp), FE521_HI(tmp)); \ + /* add lo + hi */ \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(tmp)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(tmp)); \ + } + +#define MUL_MID_ROUND(R, A, \ + AI, MMI, MAI, \ + AJ, MMJ, MAJ) \ + { \ + fe521 tmp; \ + FE521_MID(R) = FE521_HI(R) = FE521_MID(tmp) = FE521_HI(tmp) = m256_setzero_i64(); \ + /* high */ \ + FE521_MID(R) = m256_maskz_madd52hi_i64((MMI), FE521_MID(R), FE521_MID(A), (AI)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(R), FE521_HI(A), (AI)); \ + /* lo */ \ + FE521_MID(tmp) = m256_maskz_madd52lo_i64((MMJ), FE521_MID(tmp), FE521_MID(A), (AJ)); \ + FE521_HI(tmp) = m256_madd52lo_i64(FE521_HI(tmp), FE521_HI(A), (AJ)); \ + /* double hi */ \ + FE521_MID(R) = m256_mask_add_i64(FE521_MID(R), (MAI), FE521_MID(R), FE521_MID(R)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(R)); \ + /* double lo */ \ + FE521_MID(tmp) = m256_mask_add_i64(FE521_MID(tmp), (MAJ), FE521_MID(tmp), FE521_MID(tmp)); \ + FE521_HI(tmp) = m256_add_i64(FE521_HI(tmp), FE521_HI(tmp)); \ + /* add lo + hi */ \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(tmp)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(tmp)); \ + } + +#define MUL_MID_LAST_ROUND(R, A, \ + AI, MMI, MAI, \ + AJ, MMJ) \ + { \ + fe521 tmp; \ + FE521_MID(R) = FE521_HI(R) = FE521_MID(tmp) = FE521_HI(tmp) = m256_setzero_i64(); \ + /* high */ \ + FE521_MID(R) = m256_maskz_madd52hi_i64((MMI), FE521_MID(R), FE521_MID(A), (AI)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(R), FE521_HI(A), (AI)); \ + /* lo */ \ + FE521_MID(tmp) = m256_maskz_madd52lo_i64((MMJ), FE521_MID(tmp), FE521_MID(A), (AJ)); \ + FE521_HI(tmp) = m256_madd52lo_i64(FE521_HI(tmp), FE521_HI(A), (AJ)); \ + /* double hi */ \ + FE521_MID(R) = m256_mask_add_i64(FE521_MID(R), (MAI), FE521_MID(R), FE521_MID(R)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(R)); \ + /* double lo */ \ + FE521_HI(tmp) = m256_add_i64(FE521_HI(tmp), FE521_HI(tmp)); \ + /* add lo + hi */ \ + FE521_MID(R) = m256_add_i64(FE521_MID(R), FE521_MID(tmp)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(tmp)); \ + } + +#define MUL_HI_FIRST_ROUND(R, A, \ + AI, MMI, \ + AJ, MAJ) \ + { \ + fe521 tmp; \ + FE521_MID(R) = FE521_HI(R) = FE521_HI(tmp) = m256_setzero_i64(); \ + /* high */ \ + FE521_MID(R) = m256_maskz_madd52hi_i64((MMI), FE521_MID(R), FE521_MID(A), (AI)); \ + FE521_HI(R) = m256_madd52hi_i64(FE521_HI(R), FE521_HI(A), (AI)); \ + /* lo */ \ + FE521_HI(tmp) = m256_madd52lo_i64(FE521_HI(tmp), FE521_HI(A), (AJ)); \ + /* double hi */ \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(R)); \ + /* double lo */ \ + FE521_HI(tmp) = m256_mask_add_i64(FE521_HI(tmp), (MAJ), FE521_HI(tmp), FE521_HI(tmp)); \ + /* add lo + hi */ \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(tmp)); \ + } + +#define MUL_HI_ROUND(R, A, \ + AI, MMI, MAI, \ + AJ, MMJ, MAJ) \ + { \ + fe521 tmp; \ + FE521_HI(R) = FE521_HI(tmp) = m256_setzero_i64(); \ + /* high */ \ + FE521_HI(R) = m256_maskz_madd52hi_i64((MMI), FE521_HI(R), FE521_HI(A), (AI)); \ + /* lo */ \ + FE521_HI(tmp) = m256_maskz_madd52lo_i64((MMJ), FE521_HI(tmp), FE521_HI(A), (AJ)); \ + /* double hi */ \ + FE521_HI(R) = m256_mask_add_i64(FE521_HI(R), (MAI), FE521_HI(R), FE521_HI(R)); \ + /* double lo */ \ + FE521_HI(tmp) = m256_mask_add_i64(FE521_HI(tmp), (MAJ), FE521_HI(tmp), FE521_HI(tmp)); \ + /* add lo + hi */ \ + FE521_HI(R) = m256_add_i64(FE521_HI(R), FE521_HI(tmp)); \ + } + +#define ADD_LO(R, A, B) \ + FE521_LO(R) = m256_add_i64(FE521_LO(A), FE521_LO(B)); \ + FE521_MID(R) = m256_add_i64(FE521_MID(A), FE521_MID(B)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(A), FE521_HI(B)); + +#define ADD_MID(R, A, B) \ + FE521_MID(R) = m256_add_i64(FE521_MID(A), FE521_MID(B)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(A), FE521_HI(B)); + +#define ADD_HI(R, A, B) \ + FE521_HI(R) = m256_add_i64(FE521_HI(A), FE521_HI(B)); + +IPP_OWN_DEFN(void, ifma_ams52_p521, (fe521 pr[], const fe521 a)) +{ + const Ipp64s *pa_lo = (const Ipp64s *)(&(FE521_LO(a))); + const Ipp64s *pa_mid = (const Ipp64s *)(&(FE521_MID(a))); + const Ipp64s *pa_hi = (const Ipp64s *)(&(FE521_HI(a))); + + const m256i a0 = m256_set1_i64(pa_lo[0]); + const m256i a1 = m256_set1_i64(pa_lo[1]); + const m256i a2 = m256_set1_i64(pa_lo[2]); + const m256i a3 = m256_set1_i64(pa_lo[3]); + + const m256i a4 = m256_set1_i64(pa_mid[0]); + const m256i a5 = m256_set1_i64(pa_mid[1]); + const m256i a6 = m256_set1_i64(pa_mid[2]); + const m256i a7 = m256_set1_i64(pa_mid[3]); + + const m256i a8 = m256_set1_i64(pa_hi[0]); + const m256i a9 = m256_set1_i64(pa_hi[1]); + const m256i a10 = m256_set1_i64(pa_hi[2]); + + fe521 r0, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9; + + /* start round */ + /* r0 = r0 + a*a[0](lo) */ + FE521_SET(r0) = m256_setzero_i64(); + FE521_LO(r0) = m256_madd52lo_i64(FE521_LO(r0), FE521_LO(a), a0); + FE521_MID(r0) = m256_madd52lo_i64(FE521_MID(r0), FE521_MID(a), a0); + FE521_HI(r0) = m256_madd52lo_i64(FE521_HI(r0), FE521_HI(a), a0); + /* r0 = r0 + r0 (no update r0[0]) */ + FE521_LO(r0) = m256_mask_add_i64(FE521_LO(r0), 0xE, FE521_LO(r0), FE521_LO(r0)); + FE521_MID(r0) = m256_add_i64(FE521_MID(r0), FE521_MID(r0)); + FE521_HI(r0) = m256_add_i64(FE521_HI(r0), FE521_HI(r0)); + /* + * 1111 = 0xF + * 1110 = 0xE + * 1100 = 0xC + * 1000 = 0x8 + * 0000 = 0x0 + */ + /* lower */ + /* p0 = p0 + a*a[0](hi) + a*a[1](lo) */ + MUL_LO_ROUND(/* R = */ p0, /* A = */ a, + /* AI = */ a0, /* MMI = */ 0xF, /* MAI = */ 0xE, + /* AJ = */ a1, /* MMJ = */ 0xE, /* MAJ = */ 0xC) + /* p1 = p1 + a*a[1](hi) + a*a[2](lo) */ + MUL_LO_ROUND(/* R = */ p1, /* A = */ a, + /* AI = */ a1, /* MMI = */ 0xE, /* MAI = */ 0xC, + /* AJ = */ a2, /* MMJ = */ 0xC, /* MAJ = */ 0x8) + /* p2 = p2 + a*a[2](hi) + a*a[3](lo) */ + MUL_LO_LAST_ROUND(/* R = */ p2, /* A = */ a, + /* AI = */ a2, /* MMI = */ 0xC, /* MAI = */ 0x8, + /* AJ = */ a3, /* MMJ = */ 0x8) + /* mid */ + /* p3 = p3 + a*a[3](hi) + a*a[4](lo) */ + MUL_MID_FIRST_ROUND(/* R = */ p3, /* A = */ a, + /* AI = */ a3, /* MMI = */ 0x8, + /* AJ = */ a4, /* MAJ = */ 0xE) + /* p4 = p4 + a*a[4](hi) + a*a[5](lo) */ + MUL_MID_ROUND(/* R = */ p4, /* A = */ a, + /* AI = */ a4, /* MMI = */ 0xF, /* MAI = */ 0xE, + /* AJ = */ a5, /* MMJ = */ 0xE, /* MAJ = */ 0xC) + /* p5 = p5 + a*a[5](hi) + a*a[6](lo) */ + MUL_MID_ROUND(/* R = */ p5, /* A = */ a, + /* AI = */ a5, /* MMI = */ 0xE, /* MAI = */ 0xC, + /* AJ = */ a6, /* MMJ = */ 0xC, /* MAJ = */ 0x8) + /* p6 = p6 + a*a[6](hi) + a*a[7](lo) */ + MUL_MID_LAST_ROUND(/* R = */ p6, /* A = */ a, + /* AI = */ a6, /* MMI = */ 0xC, /* MAI = */ 0x8, + /* AJ = */ a7, /* MMJ = */ 0x8) + /* high */ + /* p7 = p7 + a*a[7](hi) + a*a[8](lo) */ + MUL_HI_FIRST_ROUND(/* R = */ p7, /* A = */ a, + /* AI = */ a7, /* MMI = */ 0x8, + /* AJ = */ a8, /* MAJ = */ 0xE) + /* p8 = p8 + a*a[8](hi) + a*a[9](lo) */ + MUL_HI_ROUND(/* R = */ p8, /* A = */ a, + /* AI = */ a8, /* MMI = */ 0xF, /* MAI = */ 0xE, + /* AJ = */ a9, /* MMJ = */ 0xE, /* MAJ = */ 0xC) + /* p9 = p9 + a*a[9](hi) + a*a[10](lo) */ + MUL_HI_ROUND(/* R = */ p9, /* A = */ a, + /* AI = */ a9, /* MMI = */ 0xE, /* MAI = */ 0xC, + /* AJ = */ a10, /* MMJ = */ 0xC, /* MAJ = */ 0x8) + + fe521 reduct; + FE521_SET(reduct) = m256_setzero_i64(); + m256i u; + const m256i filt_rad52 = m256_set1_i64(DIGIT_MASK_52); + const m256i idx0 = m256_set_i8(REPL4(7, 6, 5, 4, 3, 2, 1, 0)); /* B[ 0] -> chunk1[0] */ + /* chunk2 shift bit >> 64 */ + const mask32 mask_sr64 = 0x00FFFFFF; + const m256i idx_sr64 = m256_set_i8(0, 0, 0, 0, 0, 0, 0, 0, + 31, 30, 29, 28, 27, 26, 25, 24, + 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8); + REDUCTION(r0, u, reduct) + + ADD_LO(r0, r0, p0); + REDUCTION(r0, u, reduct) + + ADD_LO(r0, r0, p1); + REDUCTION(r0, u, reduct) + + ADD_LO(r0, r0, p2); + REDUCTION(r0, u, reduct) + + ADD_LO(r0, r0, p3); + REDUCTION(r0, u, reduct) + + ADD_MID(r0, r0, p4); + REDUCTION(r0, u, reduct) + + ADD_MID(r0, r0, p5); + REDUCTION(r0, u, reduct) + + ADD_MID(r0, r0, p6); + REDUCTION(r0, u, reduct) + + ADD_MID(r0, r0, p7); + REDUCTION(r0, u, reduct) + + ADD_HI(r0, r0, p8); + REDUCTION(r0, u, reduct) + + ADD_HI(r0, r0, p9); + REDUCTION(r0, u, reduct) + + FE521_COPY(*pr, r0); + return; +} + +IPP_OWN_DEFN(void, ifma_ams52_dual_p521, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) +{ + ifma_amm52_dual_p521(pr1, a1, a1, pr2, a2, a2); +} + +IPP_OWN_DEFN(void, ifma_amm52_dual_p521, + (fe521 pr1[], const fe521 a1, const fe521 b1, + fe521 pr2[], const fe521 a2, const fe521 b2)) +{ + const Ipp64s *pb_lo_1 = (const Ipp64s *)(&(FE521_LO(b1))); + const Ipp64s *pb_mid_1 = (const Ipp64s *)(&(FE521_MID(b1))); + const Ipp64s *pb_hi_1 = (const Ipp64s *)(&(FE521_HI(b1))); + const Ipp64s *pb_lo_2 = (const Ipp64s *)(&(FE521_LO(b2))); + const Ipp64s *pb_mid_2 = (const Ipp64s *)(&(FE521_MID(b2))); + const Ipp64s *pb_hi_2 = (const Ipp64s *)(&(FE521_HI(b2))); + + const m256i b0_1 = m256_set1_i64(pb_lo_1[0]); + const m256i b1_1 = m256_set1_i64(pb_lo_1[1]); + const m256i b2_1 = m256_set1_i64(pb_lo_1[2]); + const m256i b3_1 = m256_set1_i64(pb_lo_1[3]); + const m256i b4_1 = m256_set1_i64(pb_mid_1[0]); + const m256i b5_1 = m256_set1_i64(pb_mid_1[1]); + const m256i b6_1 = m256_set1_i64(pb_mid_1[2]); + const m256i b7_1 = m256_set1_i64(pb_mid_1[3]); + const m256i b8_1 = m256_set1_i64(pb_hi_1[0]); + const m256i b9_1 = m256_set1_i64(pb_hi_1[1]); + const m256i b10_1 = m256_set1_i64(pb_hi_1[2]); + + const m256i b0_2 = m256_set1_i64(pb_lo_2[0]); + const m256i b1_2 = m256_set1_i64(pb_lo_2[1]); + const m256i b2_2 = m256_set1_i64(pb_lo_2[2]); + const m256i b3_2 = m256_set1_i64(pb_lo_2[3]); + const m256i b4_2 = m256_set1_i64(pb_mid_2[0]); + const m256i b5_2 = m256_set1_i64(pb_mid_2[1]); + const m256i b6_2 = m256_set1_i64(pb_mid_2[2]); + const m256i b7_2 = m256_set1_i64(pb_mid_2[3]); + const m256i b8_2 = m256_set1_i64(pb_hi_2[0]); + const m256i b9_2 = m256_set1_i64(pb_hi_2[1]); + const m256i b10_2 = m256_set1_i64(pb_hi_2[2]); + + fe521 r0_1; + fe521 p0_1, p1_1, p2_1, p3_1, p4_1, p5_1, p6_1, p7_1, p8_1, p9_1, p10_1; + fe521 r0_2; + fe521 p0_2, p1_2, p2_2, p3_2, p4_2, p5_2, p6_2, p7_2, p8_2, p9_2, p10_2; + + /* first */ + FE521_SET(r0_1) = m256_setzero_i64(); + group_madd52lo_i64(r0_1, r0_1, a1, b0_1); + FE521_SET(r0_2) = m256_setzero_i64(); + group_madd52lo_i64(r0_2, r0_2, a2, b0_2); + /* last */ + FE521_SET(p10_1) = m256_setzero_i64(); + group_madd52hi_i64(p10_1, p10_1, a1, b10_1); + FE521_SET(p10_2) = m256_setzero_i64(); + group_madd52hi_i64(p10_2, p10_2, a2, b10_2); + /* round mul */ + MUL_ROUND(p0_1, a1, b0_1, b1_1) + MUL_ROUND(p0_2, a2, b0_2, b1_2) + + MUL_ROUND(p1_1, a1, b1_1, b2_1) + MUL_ROUND(p1_2, a2, b1_2, b2_2) + + MUL_ROUND(p2_1, a1, b2_1, b3_1) + MUL_ROUND(p2_2, a2, b2_2, b3_2) + + MUL_ROUND(p3_1, a1, b3_1, b4_1) + MUL_ROUND(p3_2, a2, b3_2, b4_2) + + MUL_ROUND(p4_1, a1, b4_1, b5_1) + MUL_ROUND(p4_2, a2, b4_2, b5_2) + + MUL_ROUND(p5_1, a1, b5_1, b6_1) + MUL_ROUND(p5_2, a2, b5_2, b6_2) + + MUL_ROUND(p6_1, a1, b6_1, b7_1) + MUL_ROUND(p6_2, a2, b6_2, b7_2) + + MUL_ROUND(p7_1, a1, b7_1, b8_1) + MUL_ROUND(p7_2, a2, b7_2, b8_2) + + MUL_ROUND(p8_1, a1, b8_1, b9_1) + MUL_ROUND(p8_2, a2, b8_2, b9_2) + + MUL_ROUND(p9_1, a1, b9_1, b10_1) + MUL_ROUND(p9_2, a2, b9_2, b10_2) + + const m256i filt_rad52 = m256_set1_i64(DIGIT_MASK_52); + const m256i idx0 = m256_set_i8(REPL4(7, 6, 5, 4, 3, 2, 1, 0)); /* B[ 0] -> chunk1[0] */ + /* chunk2 shift bit >> 64 */ + const mask32 mask_sr64 = 0x00FFFFFF; + const m256i idx_sr64 = m256_set_i8(0, 0, 0, 0, 0, 0, 0, 0, + 31, 30, 29, 28, 27, 26, 25, 24, + 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8); + + fe521 reduct_1; + FE521_SET(reduct_1) = m256_setzero_i64(); + m256i u_1; + fe521 reduct_2; + FE521_SET(reduct_2) = m256_setzero_i64(); + m256i u_2; + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p0_1); + fe521_add_no_red(r0_2, r0_2, p0_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p1_1); + fe521_add_no_red(r0_2, r0_2, p1_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p2_1); + fe521_add_no_red(r0_2, r0_2, p2_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p3_1); + fe521_add_no_red(r0_2, r0_2, p3_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p4_1); + fe521_add_no_red(r0_2, r0_2, p4_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p5_1); + fe521_add_no_red(r0_2, r0_2, p5_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p6_1); + fe521_add_no_red(r0_2, r0_2, p6_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p7_1); + fe521_add_no_red(r0_2, r0_2, p7_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p8_1); + fe521_add_no_red(r0_2, r0_2, p8_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p9_1); + fe521_add_no_red(r0_2, r0_2, p9_2); + REDUCTION(r0_1, u_1, reduct_1) + REDUCTION(r0_2, u_2, reduct_2) + + fe521_add_no_red(r0_1, r0_1, p10_1); + fe521_add_no_red(r0_2, r0_2, p10_2); + + FE521_COPY(*pr1, r0_1); + FE521_COPY(*pr2, r0_2); + return; +} + +#undef group_madd52hi_i64 +#undef group_madd52lo_i64 + +IPP_OWN_DEFN(void, ifma_half52_p521, (fe521 pr[], const fe521 a)) +{ + fe521 M; + FE521_LOADU(M, p521_x1); + const m256i zero = m256_setzero_i64(); + const m256i one = m256_set1_i64(1LL); + + const mask8 mask_last_bit_one_line = m256_cmp_i64_mask(m256_and_i64(FE521_LO(a), one), zero, _MM_CMPINT_EQ); + const mask8 mask_is_lb_one = (mask8)((mask_last_bit_one_line & 1) - 1); + + fe521 r; + FE521_LO(r) = _mm256_mask_add_epi64(FE521_LO(a), mask_is_lb_one, FE521_LO(a), FE521_LO(M)); + FE521_MID(r) = _mm256_mask_add_epi64(FE521_MID(a), mask_is_lb_one, FE521_MID(a), FE521_MID(M)); + FE521_HI(r) = _mm256_mask_add_epi64(FE521_HI(a), mask_is_lb_one, FE521_HI(a), FE521_HI(M)); + ifma_lnorm52_p521(&r, r); + + /* 1-bit shift right */ + /* chunk2 shift bit >> 64 */ + const mask32 mask_sr64 = 0xFFFF; + const m256i idx_sr64 = m256_set_i8(24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, + 23, 22, 21, 20, 19, 18, 17, 16, + 15, 14, 13, 12, 11, 10, 9, 8); + + fe521 shift_right; + /* shift right */ + FE521_LO(shift_right) = m256_alignr_i64(FE521_MID(r), FE521_LO(r), 1); + FE521_MID(shift_right) = m256_alignr_i64(FE521_HI(r), FE521_MID(r), 1); + FE521_HI(shift_right) = m256_maskz_permutexvar_i8(mask_sr64, idx_sr64, FE521_HI(r)); + /* extract las bit */ + FE521_LO(shift_right) = m256_and_i64(FE521_LO(shift_right), one); + FE521_MID(shift_right) = m256_and_i64(FE521_MID(shift_right), one); + FE521_HI(shift_right) = m256_and_i64(FE521_HI(shift_right), one); + /* set last bit is first byte (52 radix) */ + FE521_LO(shift_right) = m256_slli_i64(FE521_LO(shift_right), DIGIT_SIZE_52 - 1); + FE521_MID(shift_right) = m256_slli_i64(FE521_MID(shift_right), DIGIT_SIZE_52 - 1); + FE521_HI(shift_right) = m256_maskz_slli_i64(0x3, FE521_HI(shift_right), DIGIT_SIZE_52 - 1); + /* join first new bite */ + FE521_LO(r) = m256_srli_i64(FE521_LO(r), 1); + FE521_MID(r) = m256_srli_i64(FE521_MID(r), 1); + FE521_HI(r) = m256_maskz_srli_i64(0x7, FE521_HI(r), 1); + /* join first and other bit */ + FE521_LO(r) = m256_add_i64(FE521_LO(r), FE521_LO(shift_right)); + FE521_MID(r) = m256_add_i64(FE521_MID(r), FE521_MID(shift_right)); + FE521_HI(r) = m256_add_i64(FE521_HI(r), FE521_HI(shift_right)); + + FE521_COPY(*pr, r); + return; +} + +IPP_OWN_DEFN(void, ifma_neg52_p521, (fe521 pr[], const fe521 a)) +{ + fe521 M4; + FE521_LOADU(M4, p521_x4); + + const mask8 mask_is_not_zero = (mask8)(~(FE521_IS_ZERO(a))); + fe521 r; + FE521_LO(r) = m256_mask_sub_i64(FE521_LO(a), mask_is_not_zero, FE521_LO(M4), FE521_LO(a)); + FE521_MID(r) = m256_mask_sub_i64(FE521_MID(a), mask_is_not_zero, FE521_MID(M4), FE521_MID(a)); + FE521_HI(r) = m256_mask_sub_i64(FE521_HI(a), mask_is_not_zero, FE521_HI(M4), FE521_HI(a)); + ifma_norm52_p521(&r, r); + + FE521_COPY(*pr, r); + return; +} + +/* to Montgomery conversion constant + * rr = 2^((P521_LEN52*DIGIT_SIZE)*2) mod p521 + */ +static const __ALIGN64 Ipp64u P521R1_RR52[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { { 0x0000000000000000, + 0x0004000000000000, + 0x0000000000000000, + 0x0000000000000000 }, + { 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000 }, + { 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000 } }; + +IPP_OWN_DEFN(void, ifma_tomont52_p521, (fe521 pr[], const fe521 a)) +{ + fe521 RR; + FE521_LOADU(RR, P521R1_RR52); + ifma_amm52_p521(pr, a, RR); + ifma_lnorm52_p521(pr, *pr); + return; +} + +static IPP_OWN_DEFN(void, ifma_fastred52_p521, (fe521 pr[], const fe521 a)) +{ + fe521 M; + FE521_LOADU(M, p521_x1); + const m256i zero = m256_setzero_i64(); + + fe521 r; + fe521_sub_no_red(r, a, M); + ifma_norm52_p521(&r, r); + + const mask8 lt = m256_cmp_i64_mask(zero, m256_srli_i64(FE521_HI(r), DIGIT_SIZE_52 - 1), _MM_CMPINT_LT); + const mask8 mask = (mask8)((mask8)0 - ((lt >> 2) & 1)); + + /* maks != 0 ? a : r */ + FE521_MASK_MOV(r, r, mask, a); + FE521_COPY(*pr, r); + return; +} + +IPP_OWN_DEFN(void, ifma_frommont52_p521, (fe521 pr[], const fe521 a)) +{ + fe521 ONE; + FE521_LOADU(ONE, P521R1_ONE52); + ifma_amm52_p521(pr, a, ONE); + ifma_lnorm52_p521(pr, *pr); + ifma_fastred52_p521(pr, *pr); + return; +} + +__INLINE IPP_OWN_DEFN(void, ifma_amm52_p521_norm, (fe521 pr[], const fe521 a, const fe521 b)) +{ + ifma_amm52_p521(pr, a, b); + ifma_lnorm52_p521(pr, *pr); + return; +} + +__INLINE IPP_OWN_DEFN(void, ifma_ams52_p521_norm, (fe521 pr[], const fe521 a)) +{ + ifma_ams52_p521(pr, a); + ifma_lnorm52_p521(pr, *pr); + return; +} + +#define mul(R, A, B) ifma_amm52_p521_norm(&(R), (A), (B)) +#define sqr(R, A) ifma_ams52_p521_norm(&(R), (A)) +#define mul_dual(R1, A1, B1, R2, A2, B2) \ + ifma_amm52_dual_p521(&(R1), (A1), (B1), &(R2), (A2), (B2)); \ + ifma_lnorm52_dual_p521(&(R1), (R1), &(R2), (R2)) + +/* r = base^(2^n) */ +__INLINE IPP_OWN_DEFN(void, ifma_ams52_p521_ntimes, (fe521 pr[], const fe521 a, int n)) +{ + fe521 r; + FE521_COPY(r, a); + for (; n > 0; --n) + sqr(r, r); + FE521_COPY(*pr, r); + return; +} + +#define sqr_ntimes(R, A, N) ifma_ams52_p521_ntimes(&(R), (A), (N)) + +IPP_OWN_DEFN(void, ifma_aminv52_p521, (fe521 pr[], const fe521 z)) +{ + fe521 u, v, zD, zF, z1FF; + FE521_SET(u) = FE521_SET(v) = FE521_SET(zD) = FE521_SET(zF) = FE521_SET(z1FF) = m256_setzero_i64(); + + sqr(u, z); /* u = z^2 */ + mul(v, u, z); /* v = z^2 * z = z^3 */ + sqr_ntimes(zF, v, 2); /* zF= (z^3)^(2^2) = z^12 */ + /**/ + mul_dual(zD, zF, z, /* zD = z^12 * z = z^xD */ + zF, zF, v); /* zF = z^12 * z^3 = z^xF */ + /**/ + sqr_ntimes(u, zF, 4); /* u = (z^xF)^(2^4) = z^xF0 */ + mul_dual(zD, u, zD, /* zD = z^xF0 * z^xD = z^xFD */ + zF, u, zF); /* zF = z^xF0 * z^xF = z^xFF */ + /**/ + sqr(z1FF, zF); /* z1FF= (zF^2) = z^x1FE */ + mul(z1FF, z1FF, z); /* z1FF *= z = z^x1FF */ + /**/ + sqr_ntimes(u, zF, 8); /* u = (z^xFF)^(2^8) = z^xFF00 */ + mul_dual(zD, u, zD, /* zD = z^xFF00 * z^xFD = z^xFFFD */ + zF, u, zF); /* zF = z^xFF00 * z^xFF = z^xFFFF */ + /**/ + sqr_ntimes(u, zF, 16); /* u = (z^xFFFF)^(2^16) = z^xFFFF0000 */ + mul_dual(zD, u, zD, /* zD = z^xFFFF0000 * z^xFFFD = z^xFFFFFFFD */ + zF, u, zF); /* zF = z^xFFFF0000 * z^xFFFF = z^xFFFFFFFF */ + /**/ + sqr_ntimes(u, zF, 32); /* u = (z^xFFFFFFFF)^(2^32) = z^xFFFFFFFF00000000 */ + mul_dual(zD, u, zD, /* zD = z^xFFFFFFFF00000000 * z^xFFFFFFFD = z^xFFFFFFFFFFFFFFFD */ + zF, u, zF); /* zF = z^xFFFFFFFF00000000 * z^xFFFFFFFF = z^xFFFFFFFFFFFFFFFF */ + + /* v = z^x1FF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, z1FF, 64); + mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, v, 64); + mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, v, 64); + mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, v, 64); + mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, v, 64); + mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, v, 64); + mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFF + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF */ + sqr_ntimes(v, v, 64); + mul(v, v, zF); + + /* v = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.0000000000000000 * z^xFFFFFFFFFFFFFFFD + = z^x1FF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFE.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFF.FFFFFFFFFFFFFFFD */ + sqr_ntimes(v, v, 64); + mul(*pr, v, zD); + return; +} + +#define ROUND_CONV_64_TO_52(R, A, MASK_LOAD, MASK_RAD52, IDX16) \ + (R) = m256_maskz_loadu_i64((MASK_LOAD), (A)); \ + (R) = m256_permutexvar_i16((IDX16), (R)); \ + (R) = m256_srlv_i64((R), shift_right); \ + (R) = m256_and_i64((MASK_RAD52), (R)); + +IPP_OWN_DEFN(void, convert_radix_to_52_p521, (fe521 pr[], const Ipp64u arad64[P521R1_LEN64])) +{ + + /* chunk 1 */ + const m256i idx16c1 = m256_set_i16(12, 11, 10, 9, + 9, 8, 7, 6, + 6, 5, 4, 3, + 3, 2, 1, 0); + const m256i idx16c2 = m256_set_i16(13, 12, 11, 10, + 10, 9, 8, 7, + 7, 6, 5, 4, + 4, 3, 2, 1); + const m256i idx16c3 = m256_set_i16(12, 12, 12, 12, + 12, 12, 12, 8, + 8, 7, 6, 5, + 5, 4, 3, 2); + + const m256i shift_right = m256_set_i64(12LL, 8LL, 4LL, 0LL); + const m256i mask_rad52c12 = m256_set1_i64(DIGIT_MASK_52); + const m256i mask_rad52c3 = m256_set_i64(0x0, 0x1, DIGIT_MASK_52, DIGIT_MASK_52); + + fe521 r; + FE521_SET(r) = m256_setzero_i64(); + + /* chunk 1 */ + ROUND_CONV_64_TO_52(FE521_LO(r), arad64, 0xF, mask_rad52c12, idx16c1) + /* chunk 2 */ + ROUND_CONV_64_TO_52(FE521_MID(r), arad64 + 3, 0xF, mask_rad52c12, idx16c2) + /* chunk 2 */ + ROUND_CONV_64_TO_52(FE521_HI(r), arad64 + 6, 0x7, mask_rad52c3, idx16c3) + + FE521_COPY(*pr, r); + return; +} + +IPP_OWN_DEFN(void, convert_radix_to_64_p521, (Ipp64u rrad64[P521R1_LEN64], const fe521 a)) +{ + /* filter chunk3 */ + const m256i mask_filtc3 = m256_set_i64(0x0, 0x1, DIGIT_MASK_52, DIGIT_MASK_52); + const m256i shift_left = m256_set_i64(4LL, 0LL, 4LL, 0LL); + /* idx create chunk1 */ + const m256i idx8_upc1c1 = m256_set_i8(31, 31, 31, 31, 31, 31, 31, 31, + 23, 23, 23, 23, 22, 21, 20, 19, + 15, 15, 15, 14, 13, 12, 11, 10, + 7, 6, 5, 4, 3, 2, 1, 0); + const m256i idx8_downc1c1 = m256_set_i8(31, 31, 31, 31, 31, 31, 30, 29, + 28, 27, 26, 25, 24, 23, 23, 23, + 18, 17, 16, 15, 15, 15, 15, 15, + 9, 8, 7, 7, 7, 7, 7, 7); + const m256i idx8_upc2c1 = m256_set_i8(5, 4, 3, 2, 1, 0, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7); + /* idx create chunk 2 */ + const m256i idx8_upc2c2 = m256_set_i8(31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 23, 23, 22, 21, 20, 19, 18, 17, + 16, 7, 7, 7, 7, 7, 7, 6); + const m256i idx8_downc2c2 = m256_set_i8(31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 30, 29, 28, 27, + 26, 25, 24, 23, 23, 23, 23, 23, + 15, 14, 13, 12, 11, 10, 9, 8); + const m256i idx8_upc3c2 = m256_set_i8(13, 12, 11, 10, 9, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7); + const m256i idx8_downc3c2 = m256_set_i8(7, 7, 7, 7, 7, 6, 5, 4, + 3, 2, 1, 0, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7); + /* idx create chunk 3 */ + const m256i idx8_upc3c3 = m256_set_i8(15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 16, 15); + const m256i idx8_downc3c3 = m256_set_i8(15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 14); + + fe521 r; + /* shift left */ + FE521_LO(r) = m256_sllv_i64(FE521_LO(a), shift_left); + FE521_MID(r) = m256_sllv_i64(FE521_MID(a), shift_left); + FE521_HI(r) = m256_and_i64(FE521_HI(a), mask_filtc3); + FE521_HI(r) = m256_sllv_i64(FE521_HI(r), shift_left); + + m256i t1, t2, t3; + /* chunk 1 */ + t1 = m256_permutexvar_i8(idx8_upc1c1, FE521_LO(r)); + t2 = m256_permutexvar_i8(idx8_downc1c1, FE521_LO(r)); + t1 = m256_or_i64(t1, t2); + t3 = m256_permutexvar_i8(idx8_upc2c1, FE521_MID(r)); + + FE521_LO(r) = m256_or_i64(t3, t1); + + /* chunk 2 */ + t1 = m256_permutexvar_i8(idx8_upc2c2, FE521_MID(r)); + t2 = m256_permutexvar_i8(idx8_downc2c2, FE521_MID(r)); + t3 = m256_or_i64(t1, t2); + t1 = m256_permutexvar_i8(idx8_upc3c2, FE521_HI(r)); + t2 = m256_permutexvar_i8(idx8_downc3c2, FE521_HI(r)); + + FE521_MID(r) = m256_or_i64(t3, m256_or_i64(t1, t2)); + + /* chunk 3 */ + t1 = m256_permutexvar_i8(idx8_upc3c3, FE521_HI(r)); + t2 = m256_permutexvar_i8(idx8_downc3c3, FE521_HI(r)); + + FE521_HI(r) = m256_or_i64(t1, t2); + + /* store */ + m256_storeu_i64(rrad64, FE521_LO(r)); + m256_storeu_i64(rrad64 + 4, FE521_MID(r)); + m256_mask_storeu_i64(rrad64 + 8, 0x1, FE521_HI(r)); + + return; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p521.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p521.h new file mode 100644 index 000000000..493384b5b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_arith_p521.h @@ -0,0 +1,266 @@ +/****************************************************************************** + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_ARITH_P521_H +#define IFMA_ARITH_P521_H + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_defs_p521.h" + +/* + * p521 = 2^521 - 1 + * in 2^52 radix + */ +static const __ALIGN64 Ipp64u p521_x1[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x0000000000000001, + 0x0000000000000000 } +}; +/* 2*p */ +static const __ALIGN64 Ipp64u p521_x2[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x000FFFFFFFFFFFFE, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x0000000000000003, + 0x0000000000000000 } +}; +/* 4*p */ +static const __ALIGN64 Ipp64u p521_x4[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x000FFFFFFFFFFFFC, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x0000000000000007, + 0x0000000000000000 } +}; +/* 6*p */ +static const __ALIGN64 Ipp64u p521_x6[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x000FFFFFFFFFFFFA, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000000000000000B, + 0x0000000000000000 } +}; +/* 8*p */ +static const __ALIGN64 Ipp64u p521_x8[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x000FFFFFFFFFFFF8, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000000000000000F, + 0x0000000000000000 } +}; +/* Montgomery(1) + * r = 2^(P521_LEN52*DIGIT_SIZE) mod p521 + */ +static const __ALIGN64 Ipp64u P521R1_R52[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x0008000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000 }, + { 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000 }, + { 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000, + 0x0000000000000000 } +}; + +/** + * \brief + * normalization input fe521 to (in radix 2^52) + * \param[out] pr ptr value (in radix 2^52) + * \param[in] a value (52 radix or more) + */ +IPP_OWN_DECL(void, ifma_norm52_p521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * duplicate normalization input double fe521 to (in radix 2^52) + * \param[out] pr1 ptr first value (in radix 2^52) + * \param[in] a1 value first (52 radix or more) + * \param[out] pr2 ptr second value (in radix 2^52) + * \param[in] a2 value second (52 radix or more) + */ +IPP_OWN_DECL(void, ifma_norm52_dual_p521, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) + +/** + * \brief + * light (mul|add only) normalization input fe521 to (in radix 2^52) + * \param[out] pr ptr value (in radix 2^52) + * \param[in] a value (52 radix or more) + */ +IPP_OWN_DECL(void, ifma_lnorm52_p521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * light (mul|add only) duplicate normalization input double fe521 to (in radix 2^52) + * \param[out] pr1 ptr first value (in radix 2^52) + * \param[in] a1 value first (52 radix or more) + * \param[out] pr2 ptr second value (in radix 2^52) + * \param[in] a2 value second (52 radix or more) + */ +IPP_OWN_DECL(void, ifma_lnorm52_dual_p521, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) + +/** + * \brief + * R = (A * B) - no normalization + * \param[out] pr ptr value + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_amm52_p521, (fe521 pr[], const fe521 a, const fe521 b)) + +/** + * \brief + * duplicate mul (R = A * B - no normalization) input double complect + * \param[out] pr1 ptr first value no normalization + * \param[in] a1 value first (in radix 2^52) + * \param[in] b1 value second (in radix 2^52) + * \param[out] pr2 ptr second value no normalization + * \param[in] a2 value first (in radix 2^52) + * \param[in] b2 value second (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_amm52_dual_p521, (fe521 pr1[], const fe521 a1, const fe521 b1, fe521 pr2[], const fe521 a2, const fe521 b2)) + +/** + * \brief + * R = A/2 - with normalization + * \param[out] pr ptr value (in radix 2^52) + * \param[in] a value (52 radix or more) + */ +IPP_OWN_DECL(void, ifma_half52_p521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * compute R = (-A) enhanced Montgomery (Gueron modification group operation) + * \param[out] pr ptr value (in radix 2^52) + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_neg52_p521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * to Montgomery domain (in radix 2^52) + * \param[out] pr ptr value (in radix 2^52) in Montgomery domain + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_tomont52_p521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * from Montgomery domain (in radix 2^52) + * \param[out] pr ptr value (in radix 2^52) from Montgomery domain + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_frommont52_p521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * R = 1/Z + * \param[out] pr ptr value (in radix 2^52) + * \param[in] z value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_aminv52_p521, (fe521 pr[], const fe521 z)) + +/** + * \brief + * convert radix 64 to (in radix 2^52) + * \param[out] pr ptr value (in radix 2^52) + * \param[in] arad64 ptr array size (9) - 521 bit + */ +IPP_OWN_DECL(void, convert_radix_to_52_p521, (fe521 pr[], const Ipp64u arad64[P521R1_LEN64])) + +/** + * \brief + * convert (in radix 2^52) to radix 64 + * \param[out] rrad64 ptr array size (9) - 521 bit + * \param[in] a value (in radix 2^52) + */ +IPP_OWN_DECL(void, convert_radix_to_64_p521, (Ipp64u rrad64[P521R1_LEN64], const fe521 a)) + +/** + * \brief + * R = (A * A) - no normalization + * \param[out] pr ptr value + * \param[in] a first value (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_ams52_p521, (fe521 pr[], const fe521 a)) + +/** + * \brief + * duplicate sqr (R = A * A - no normalization) input double complect + * \param[out] pr1 ptr first value no normalization + * \param[in] a1 value first (in radix 2^52) + * \param[out] pr2 ptr second value no normalization + * \param[in] a2 value first (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_ams52_dual_p521, (fe521 pr1[], const fe521 a1, fe521 pr2[], const fe521 a2)) + +/* R = (A + B) */ +#define fe521_add_no_red(R, A, B) \ + FE521_LO(R) = m256_add_i64(FE521_LO(A), FE521_LO(B)); \ + FE521_MID(R) = m256_add_i64(FE521_MID(A), FE521_MID(B)); \ + FE521_HI(R) = m256_add_i64(FE521_HI(A), FE521_HI(B)) + +/* R = (A - B) */ +#define fe521_sub_no_red(R, A, B) \ + FE521_LO(R) = m256_sub_i64(FE521_LO(A), FE521_LO(B)); \ + FE521_MID(R) = m256_sub_i64(FE521_MID(A), FE521_MID(B)); \ + FE521_HI(R) = m256_sub_i64(FE521_HI(A), FE521_HI(B)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_defs.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_defs.h new file mode 100644 index 000000000..ab9fe6035 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_defs.h @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#ifndef IFMA_DEFS_H +#define IFMA_DEFS_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_alias_avx512.h" + +/* Internal radix definition */ +#define DIGIT_SIZE (52) +#define DIGIT_BASE ((Ipp64u)1 << DIGIT_SIZE) +#define DIGIT_MASK ((Ipp64u)0xFFFFFFFFFFFFF) + +/* Number of digit in "digsize" representation of "bitsize" value */ +#define NUMBER_OF_DIGITS(bitsize, digsize) (((bitsize) + (digsize)-1) / (digsize)) +/* Mask of most significant digit wrt "digsize" representation */ +#define MS_DIGIT_MASK(bitsize, digsize) (((int64u)1 << ((bitsize) % digsize)) - 1) + + +#define REPL8(e) e, e, e, e, e, e, e, e + +/** + * \brief + * + * Check if bit on corresponding position is 1. + * Position counting starts from zero. + * + * \return 0xFF - if MSB = 1 + * \return 0x00 - if MSB = 0 + */ +__INLINE mask8 check_bit(const mask8 a, int bit) +{ + return (mask8)((mask8)0 - ((a >> bit) & 1u)); +} + +/** + * \brief + * + * Check if ZMM register contains all zeroes. + * + * \param[in] a value + * \return 0xFF - if input value is all zeroes + * \return 0x00 - if input value is not all zeroes + */ +__INLINE mask8 is_zero_i64(const m512 a) +{ + const mask8 mask = cmp_i64_mask(a, setzero_i64(), _MM_CMPINT_NE); + return check_bit((~mask & (mask - 1u)), 7); +} + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // IFMA_DEFS_H diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_defs_p521.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_defs_p521.h new file mode 100644 index 000000000..1d6aa5587 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_defs_p521.h @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_DEFS_P521_H +#define IFMA_DEFS_P521_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_alias_avx512vl.h" + +#define DIGIT_MASK_52 (0xFFFFFFFFFFFFF) +#define DIGIT_SIZE_52 (52) + +#define P521R1_LEN52 (11) +#define P521R1_LEN64 (9) +#define P521R1_LENFE521_52 (4) +#define P521R1_NUM_CHUNK (3) + +typedef m256i fe521[P521R1_NUM_CHUNK]; + +#define REPL4(a1, a2, a3, a4, a5, a6, a7, a8) a1, a2, a3, a4, a5, a6, a7, a8, \ + a1, a2, a3, a4, a5, a6, a7, a8, \ + a1, a2, a3, a4, a5, a6, a7, a8, \ + a1, a2, a3, a4, a5, a6, a7, a8 + +/* one */ +static const __ALIGN64 Ipp64u P521R1_ONE52[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { + { 0x1, 0x0, 0x0, 0x0 }, + { 0x0, 0x0, 0x0, 0x0 }, + { 0x0, 0x0, 0x0, 0x0 } +}; + +#define FE521_LO(A) (A)[0] +#define FE521_MID(A) (A)[1] +#define FE521_HI(A) (A)[2] + +#define FE521_SET(A) FE521_LO(A) = FE521_MID(A) = FE521_HI(A) + +#define FE521_COPY(R, A) \ + FE521_LO(R) = FE521_LO(A); \ + FE521_MID(R) = FE521_MID(A); \ + FE521_HI(R) = FE521_HI(A) + +#define FE521_LOADU(R, A) \ + FE521_LO(R) = m256_loadu_i64(FE521_LO(A)); \ + FE521_MID(R) = m256_loadu_i64(FE521_MID(A)); \ + FE521_HI(R) = m256_loadu_i64(FE521_HI(A)) + +__INLINE mask8 is_msb_m256(const mask8 a) +{ + return ((mask8)0 - (a >> 7)); +} + +__INLINE mask8 is_zero_m256(const m256i a) +{ + const mask8 mask = _mm256_cmp_epi64_mask(a, m256_setzero_i64(), _MM_CMPINT_NE); + return is_msb_m256((~mask & (mask - 1))); +} + +#define FE521_IS_ZERO(A) (is_zero_m256(m256_or_i64(m256_or_i64(FE521_LO(A), FE521_MID(A)), FE521_HI(A)))) + +#define FE521_CMP_MASK(A, B, ENUM_CMP) \ + (m256_cmp_i64_mask(FE521_LO(A), FE521_LO(B), (ENUM_CMP)) & m256_cmp_i64_mask(FE521_MID(A), FE521_MID(B), (ENUM_CMP)) & m256_cmp_i64_mask(FE521_HI(A), FE521_HI(B), (ENUM_CMP))) + +#define FE521_MASK_MOV(R, SRC, MASK, A) \ + FE521_LO(R) = m256_mask_mov_i64(FE521_LO(SRC), (MASK), FE521_LO(A)); \ + FE521_MID(R) = m256_mask_mov_i64(FE521_MID(SRC), (MASK), FE521_MID(A)); \ + FE521_HI(R) = m256_mask_mov_i64(FE521_HI(SRC), (MASK), FE521_HI(A)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _CP_DEFINE_FE521_K1 diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p256.c new file mode 100644 index 000000000..f9fdc4a2d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p256.c @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method.h" +#include "ifma_ecpoint_p256.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_AddPoint_nistp256_avx512, (IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, + const IppsGFpECPoint* pQ, + IppsGFpECState* pEC)) +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + __ALIGN64 P256_POINT_IFMA P, R; + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + if (pP == pQ) { + ifma_ec_nistp256_dbl_point(&R, &P); + } else { + __ALIGN64 P256_POINT_IFMA Q; + + recode_point_to_mont52(&Q, ECP_POINT_DATA(pQ), pPool, pmeth, pME); + + ifma_ec_nistp256_add_point(&R, &P, &Q); + } + + recode_point_to_mont64(pR, &R, pPool, pmeth, pME); + + cpGFpReleasePool(3, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p384.c new file mode 100644 index 000000000..5be4dd315 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p384.c @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method.h" +#include "ifma_ecpoint_p384.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_AddPoint_nistp384_avx512, (IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, + const IppsGFpECPoint* pQ, + IppsGFpECState* pEC)) +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + __ALIGN64 P384_POINT_IFMA P, R; + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + if (pP == pQ) { + ifma_ec_nistp384_dbl_point(&R, &P); + } else { + __ALIGN64 P384_POINT_IFMA Q; + + recode_point_to_mont52(&Q, ECP_POINT_DATA(pQ), pPool, pmeth, pME); + + ifma_ec_nistp384_add_point(&R, &P, &Q); + } + + recode_point_to_mont64(pR, &R, pPool, pmeth, pME); + + cpGFpReleasePool(3, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p521.c new file mode 100644 index 000000000..eb852f589 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_addpoint_p521.c @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method_p521.h" +#include "ifma_ecpoint_p521.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_AddPoint_nistp521_avx512, (IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, + const IppsGFpECPoint* pQ, + IppsGFpECState* pEC)) +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod_p521 *pmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(pME); + + __ALIGN64 P521_POINT_IFMA P, R; + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + if (pP == pQ) { + ifma_ec_nistp521_dbl_point(&R, &P); + } else { + __ALIGN64 P521_POINT_IFMA Q; + + recode_point_to_mont52(&Q, ECP_POINT_DATA(pQ), pPool, pmeth, pME); + + ifma_ec_nistp521_add_point(&R, &P, &Q); + } + + recode_point_to_mont64(pR, &R, pPool, pmeth, pME); + + cpGFpReleasePool(3, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p256.c new file mode 100644 index 000000000..d2d791798 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p256.c @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "ifma_defs.h" +#include "ifma_ecpoint_p256.h" +#include "ifma_arith_method.h" + +IPP_OWN_DEFN(int, gfec_SharedSecretDH_nistp256_avx512, (IppsGFpECPoint * pR, + const IppsGFpECPoint *pP, + const BNU_CHUNK_T *pScalar, + int scalarLen, + IppsGFpECState *pEC, + Ipp8u *pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Copy scalar */ + BNU_CHUNK_T *pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P256_POINT_IFMA P52, R52; + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + /* Convert point coordinates to a new Montgomery domain */ + recode_point_to_mont52(&P52, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + ifma_ec_nistp256_mul_point(&R52, &P52, (Ipp8u *)pExtendedScalar, orderBits); + + + /* Check if the point - point to infinity */ + const mask8 is_zero_z = is_zero_i64(R52.z); + int finite_point = ((mask8)0xFF != is_zero_z); + + /* Get X affine coordinate */ + ifma_ec_nistp256_get_affine_coords(&(R52.x), NULL, &R52); + + R52.x = p_from_mont(R52.x); + from_radix52(ECP_POINT_X(pR), R52.x); + + cpGFpReleasePool(5, pME); + + return finite_point; + } +} + +#endif // IPP32E >= _IPP32E_K1 diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p384.c new file mode 100644 index 000000000..9fd110d9e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p384.c @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "ifma_defs.h" +#include "ifma_ecpoint_p384.h" +#include "ifma_arith_method.h" + +IPP_OWN_DEFN(int, gfec_SharedSecretDH_nistp384_avx512, (IppsGFpECPoint * pR, + const IppsGFpECPoint *pP, + const BNU_CHUNK_T *pScalar, + int scalarLen, + IppsGFpECState *pEC, + Ipp8u *pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Copy scalar */ + BNU_CHUNK_T *pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P384_POINT_IFMA P52, R52; + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + /* Convert point coordinates to a new Montgomery domain */ + recode_point_to_mont52(&P52, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + ifma_ec_nistp384_mul_point(&R52, &P52, (Ipp8u *)pExtendedScalar, orderBits); + + + /* Check if the point - point to infinity */ + const mask8 is_zero_z = is_zero_i64(R52.z); + int finite_point = ((mask8)0xFF != is_zero_z); + + /* Get X affine coordinate */ + ifma_ec_nistp384_get_affine_coords(&(R52.x), NULL, &R52); + + R52.x = p_from_mont(R52.x); + from_radix52(ECP_POINT_X(pR), R52.x); + + cpGFpReleasePool(5, pME); + + return finite_point; + } +} + +#endif // IPP32E >= _IPP32E_K1 diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p521.c new file mode 100644 index 000000000..5d179d6bb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dh_p521.c @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "ifma_ecpoint_p521.h" +#include "ifma_arith_method_p521.h" + +IPP_OWN_DEFN(int, gfec_SharedSecretDH_nistp521_avx512, (IppsGFpECPoint * pR, + const IppsGFpECPoint *pP, + const BNU_CHUNK_T *pScalar, + int scalarLen, + IppsGFpECState *pEC, + Ipp8u *pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod_p521 *pmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(pME); + + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Copy scalar */ + BNU_CHUNK_T *pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P521_POINT_IFMA P52, R52; + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + /* Convert point coordinates to a new Montgomery domain */ + recode_point_to_mont52(&P52, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + ifma_ec_nistp521_mul_point(&R52, &P52, (Ipp8u *)pExtendedScalar, orderBits); + + + /* Check if the point - point to infinity */ + const mask8 is_zero_z = FE521_IS_ZERO(R52.z); + int finite_point = ((mask8)0xFF != is_zero_z); + + /* Get X affine coordinate */ + ifma_ec_nistp521_get_affine_coords(&(R52.x), NULL, &R52); + + p_from_mont(&(R52.x), R52.x); + from_radix52(ECP_POINT_X(pR), R52.x); + + cpGFpReleasePool(5, pME); + + return finite_point; + } +} + +#endif // IPP32E >= _IPP32E_K1 diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p256.c new file mode 100644 index 000000000..18499c73d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p256.c @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "ifma_defs.h" +#include "ifma_ecpoint_p256.h" +#include "ifma_arith_method.h" + +IPP_OWN_DEFN(IppStatus, gfec_SignDSA_nistp256_avx512, (const IppsBigNumState *pMsgDigest, + const IppsBigNumState *pRegPrivate, + IppsBigNumState *pEphPrivate, + IppsBigNumState *pSignR, + IppsBigNumState *pSignS, + IppsGFpECState *pEC, + Ipp8u *pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppStatus sts = ippStsNoErr; + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + ifmaArithMethod *nmeth = (ifmaArithMethod *)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_add n_add = nmeth->add; + ifma_inv n_inv = nmeth->inv; + ifma_red n_red = nmeth->red; + + /* Copy scalar */ + BNU_CHUNK_T *pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + + __ALIGN64 P256_POINT_IFMA P; + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp256_mul_pointbase(&P, (Ipp8u *)pExtendedScalar, orderBits); + } else { + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P256_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool, pmeth, pME); + + ifma_ec_nistp256_mul_point(&P, &G52, (Ipp8u *)pExtendedScalar, orderBits); + + cpGFpReleasePool(3, pME); + } + + /* + // signR = int(ephPublic.x) (mod order) + */ + /* Extract affine P.x */ + ifma_ec_nistp256_get_affine_coords(&(P.x), NULL, &P); + + P.x = p_from_mont(P.x); + P.x = n_red(P.x); + + /* + // signS = (1/ephPrivate)*(pMsgDigest + private*signR) (mod order) + */ + m512 ephPrivateInv = setzero_i64(); + BNU_CHUNK_T *pTmp = cpGFpGetPool(1, pME); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + ephPrivateInv = to_radix52(pTmp); + + ephPrivateInv = n_to_mont(ephPrivateInv); + ephPrivateInv = n_inv(ephPrivateInv); + + /* Message */ + m512 msgDigest = setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + msgDigest = to_radix52(pTmp); + msgDigest = n_red(msgDigest); /* reduce just in case */ + msgDigest = n_to_mont(msgDigest); + + /* Regular private key */ + m512 regPrivate = setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pRegPrivate), BN_SIZE(pRegPrivate)); + regPrivate = to_radix52(pTmp); + regPrivate = n_to_mont(regPrivate); + + m512 signS; + + signS = n_to_mont(P.x); + signS = n_mul(regPrivate, signS); + signS = n_add(signS, msgDigest); + signS = n_mul(signS, ephPrivateInv); + signS = n_from_mont(signS); + + const mask8 isZero = (mask8)(is_zero_i64(signS) | is_zero_i64(P.x)); + if ((mask8)0xFF == isZero) + sts = ippStsEphemeralKeyErr; + + from_radix52((Ipp64u *)pTmp, signS); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pTmp, orderLen); + + from_radix52((Ipp64u *)pTmp, P.x); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pTmp, orderLen); + + /* Clear secret data */ + clear_secrets(®Private, &(P.x), &signS); + + cpGFpReleasePool(3, pME); + + return sts; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p384.c new file mode 100644 index 000000000..d54190354 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p384.c @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "ifma_defs.h" +#include "ifma_ecpoint_p384.h" +#include "ifma_arith_method.h" + +IPP_OWN_DEFN(IppStatus, gfec_SignDSA_nistp384_avx512, (const IppsBigNumState *pMsgDigest, + const IppsBigNumState *pRegPrivate, + IppsBigNumState *pEphPrivate, + IppsBigNumState *pSignR, + IppsBigNumState *pSignS, + IppsGFpECState *pEC, + Ipp8u *pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppStatus sts = ippStsNoErr; + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + ifmaArithMethod *nmeth = (ifmaArithMethod *)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_add n_add = nmeth->add; + ifma_inv n_inv = nmeth->inv; + ifma_red n_red = nmeth->red; + + /* Copy scalar */ + BNU_CHUNK_T *pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + + __ALIGN64 P384_POINT_IFMA P; + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp384_mul_pointbase(&P, (Ipp8u *)pExtendedScalar, orderBits); + } else { + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P384_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool, pmeth, pME); + + ifma_ec_nistp384_mul_point(&P, &G52, (Ipp8u *)pExtendedScalar, orderBits); + + cpGFpReleasePool(3, pME); + } + + /* + // signR = int(ephPublic.x) (mod order) + */ + /* Extract affine P.x */ + ifma_ec_nistp384_get_affine_coords(&(P.x), NULL, &P); + + P.x = p_from_mont(P.x); + P.x = n_red(P.x); + + /* + // signS = (1/ephPrivate)*(pMsgDigest + private*signR) (mod order) + */ + m512 ephPrivateInv = setzero_i64(); + BNU_CHUNK_T *pTmp = cpGFpGetPool(1, pME); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + ephPrivateInv = to_radix52(pTmp); + + ephPrivateInv = n_to_mont(ephPrivateInv); + ephPrivateInv = n_inv(ephPrivateInv); + + /* Message */ + m512 msgDigest = setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + msgDigest = to_radix52(pTmp); + msgDigest = n_red(msgDigest); /* reduce just in case */ + msgDigest = n_to_mont(msgDigest); + + /* Regular private key */ + m512 regPrivate = setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pRegPrivate), BN_SIZE(pRegPrivate)); + regPrivate = to_radix52(pTmp); + regPrivate = n_to_mont(regPrivate); + + m512 signS; + + signS = n_to_mont(P.x); + signS = n_mul(regPrivate, signS); + signS = n_add(signS, msgDigest); + signS = n_mul(signS, ephPrivateInv); + signS = n_from_mont(signS); + + const mask8 isZero = (mask8)(is_zero_i64(signS) | is_zero_i64(P.x)); + if ((mask8)0xFF == isZero) + sts = ippStsEphemeralKeyErr; + + from_radix52((Ipp64u *)pTmp, signS); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pTmp, orderLen); + + from_radix52((Ipp64u *)pTmp, P.x); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pTmp, orderLen); + + /* Clear secret data */ + clear_secrets(®Private, &(P.x), &signS); + + cpGFpReleasePool(3, pME); + + return sts; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p521.c new file mode 100644 index 000000000..345173c30 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsasign_p521.c @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "ifma_ecpoint_p521.h" +#include "ifma_arith_method_p521.h" +#include "ifma_alias_avx512vl.h" + +IPP_OWN_DEFN(IppStatus, gfec_SignDSA_nistp521_avx512, (const IppsBigNumState *pMsgDigest, + const IppsBigNumState *pRegPrivate, + IppsBigNumState *pEphPrivate, + IppsBigNumState *pSignR, + IppsBigNumState *pSignS, + IppsGFpECState *pEC, + Ipp8u *pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppStatus sts = ippStsNoErr; + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod_p521 *pmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(pME); + ifmaArithMethod_p521 *nmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_add n_add = nmeth->add; + ifma_inv n_inv = nmeth->inv; + ifma_red n_red = nmeth->red; + + /* Copy scalar */ + BNU_CHUNK_T *pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + + __ALIGN64 P521_POINT_IFMA P; + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp521_mul_pointbase(&P, (Ipp8u *)pExtendedScalar, orderBits); + } else { + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P521_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool, pmeth, pME); + + ifma_ec_nistp521_mul_point(&P, &G52, (Ipp8u *)pExtendedScalar, orderBits); + + cpGFpReleasePool(3, pME); + } + + /* + // signR = int(ephPublic.x) (mod order) + */ + /* Extract affine P.x */ + ifma_ec_nistp521_get_affine_coords(&(P.x), NULL, &P); + + p_from_mont(&(P.x), P.x); + n_red(&(P.x), P.x); + + /* + // signS = (1/ephPrivate)*(pMsgDigest + private*signR) (mod order) + */ + fe521 ephPrivateInv; + FE521_SET(ephPrivateInv) = m256_setzero_i64(); + BNU_CHUNK_T *pTmp = cpGFpGetPool(1, pME); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + to_radix52(&ephPrivateInv, pTmp); + + n_to_mont(&ephPrivateInv, ephPrivateInv); + n_inv(&ephPrivateInv, ephPrivateInv); + + /* Message */ + fe521 msgDigest; + FE521_SET(msgDigest) = m256_setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + to_radix52(&msgDigest, pTmp); + n_red(&msgDigest, msgDigest); /* reduce just in case */ + n_to_mont(&msgDigest, msgDigest); + + /* Regular private key */ + fe521 regPrivate; + FE521_SET(regPrivate) = m256_setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pRegPrivate), BN_SIZE(pRegPrivate)); + to_radix52(®Private, pTmp); + n_to_mont(®Private, regPrivate); + + fe521 signS; + + n_to_mont(&signS, P.x); + n_mul(&signS, regPrivate, signS); + n_add(&signS, signS, msgDigest); + n_mul(&signS, signS, ephPrivateInv); + n_from_mont(&signS, signS); + + const mask8 isZero = (mask8)(FE521_IS_ZERO(signS) | FE521_IS_ZERO(P.x)); + if ((mask8)0xFF == isZero) + sts = ippStsEphemeralKeyErr; + + from_radix52((Ipp64u *)pTmp, signS); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pTmp, orderLen); + + from_radix52((Ipp64u *)pTmp, P.x); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pTmp, orderLen); + + /* Clear secret data */ + clear_secrets(®Private, &(P.x), &signS); + + cpGFpReleasePool(3, pME); + + return sts; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p256.c new file mode 100644 index 000000000..ac9f21cc5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p256.c @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method.h" +#include "ifma_ecpoint_p256.h" + +IPP_OWN_DEFN(IppECResult, gfec_VerifyDSA_nistp256_avx512, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, + const IppsBigNumState* pSignS, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppECResult verifyResult = ippECInvalidSignature; + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + ifmaArithMethod *nmeth = (ifmaArithMethod *)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_inv n_inv = nmeth->inv; + ifma_red n_red = nmeth->red; + + /* Convert input parameters to 2^52 radix */ + m512 msg, signR, signS; + msg = signR = signS = setzero_i64(); + + const int elemLen = GFP_FELEN(pME); + + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + BNU_CHUNK_T *pBufMsg = pPool; + BNU_CHUNK_T *pBufSignR = pPool + elemLen; + BNU_CHUNK_T *pBufSignS = pPool + 2 * elemLen; + + ZEXPAND_COPY_BNU(pBufMsg, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + ZEXPAND_COPY_BNU(pBufSignR, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + ZEXPAND_COPY_BNU(pBufSignS, orderLen, BN_NUMBER(pSignS), BN_SIZE(pSignS)); + + msg = to_radix52((Ipp64u *)pBufMsg); + msg = n_red(msg); /* reduce just in case */ + signR = to_radix52((Ipp64u *)pBufSignR); + signS = to_radix52((Ipp64u *)pBufSignS); + + /* Convert public point to proper Montgomery domain and 2^52 radix */ + __ALIGN64 P256_POINT_IFMA pubKey; + recode_point_to_mont52(&pubKey, ECP_POINT_DATA(pRegPublic), pPool /* 3 elem */, pmeth, pME); + + m512 h, h1, h2; + + /* h = (signS)^(-1) */ + h = n_to_mont(signS); + h = n_inv(h); + + /* h1 = msg*h, h2 = signR*h */ + h1 = n_to_mont(msg); + h2 = n_to_mont(signR); + + h1 = n_mul(h1, h); + h2 = n_mul(h2, h); + + h1 = n_from_mont(h1); + h2 = n_from_mont(h2); + + BNU_CHUNK_T *pExtendedH1 = cpGFpGetPool(2, pME); + BNU_CHUNK_T *pExtendedH2 = cpGFpGetPool(2, pME); + BNU_CHUNK_T *pH1 = cpGFpGetPool(1, pME); + BNU_CHUNK_T *pH2 = cpGFpGetPool(1, pME); + + from_radix52((Ipp64u *)pH1, h1); + from_radix52((Ipp64u *)pH2, h2); + cpGFpElementCopyPad(pExtendedH1, orderLen + 1, pH1, orderLen); + cpGFpElementCopyPad(pExtendedH2, orderLen + 1, pH2, orderLen); + + cpGFpReleasePool(2, pME); /* pH1, pH2 */ + + __ALIGN64 P256_POINT_IFMA P; + + /* P = h1*basePoint + h2*pubKey */ + ifma_ec_nistp256_mul_point(&pubKey, &pubKey, (Ipp8u *)pExtendedH2, orderBits); + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp256_mul_pointbase(&P, (Ipp8u *)pExtendedH1, orderBits); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P256_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool /* 3 elem */, pmeth, pME); + + ifma_ec_nistp256_mul_point(&P, &G52, (Ipp8u *)pExtendedH1, orderBits); + } + + ifma_ec_nistp256_add_point(&P, &P, &pubKey); + + /* Get X in affine coordinates */ + ifma_ec_nistp256_get_affine_coords(&(P.x), NULL, &P); + + P.x = p_from_mont(P.x); + P.x = n_red(P.x); + + const mask8 mask_ok = cmp_i64_mask(P.x, signR, _MM_CMPINT_EQ); + if ((mask8)0xFF == mask_ok) + verifyResult = ippECValid; + + cpGFpReleasePool(7, pME); + + return verifyResult; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p384.c new file mode 100644 index 000000000..3ab461e4f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p384.c @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method.h" +#include "ifma_ecpoint_p384.h" + +IPP_OWN_DEFN(IppECResult, gfec_VerifyDSA_nistp384_avx512, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, + const IppsBigNumState* pSignS, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppECResult verifyResult = ippECInvalidSignature; + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + ifmaArithMethod *nmeth = (ifmaArithMethod *)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_inv n_inv = nmeth->inv; + ifma_red n_red = nmeth->red; + + /* Convert input parameters to 2^52 radix */ + m512 msg, signR, signS; + msg = signR = signS = setzero_i64(); + + const int elemLen = GFP_FELEN(pME); + + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + BNU_CHUNK_T *pBufMsg = pPool; + BNU_CHUNK_T *pBufSignR = pPool + elemLen; + BNU_CHUNK_T *pBufSignS = pPool + 2 * elemLen; + + ZEXPAND_COPY_BNU(pBufMsg, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + ZEXPAND_COPY_BNU(pBufSignR, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + ZEXPAND_COPY_BNU(pBufSignS, orderLen, BN_NUMBER(pSignS), BN_SIZE(pSignS)); + + msg = to_radix52((Ipp64u *)pBufMsg); + msg = n_red(msg); /* reduce just in case */ + signR = to_radix52((Ipp64u *)pBufSignR); + signS = to_radix52((Ipp64u *)pBufSignS); + + /* Convert public point to proper Montgomery domain and 2^52 radix */ + __ALIGN64 P384_POINT_IFMA pubKey; + recode_point_to_mont52(&pubKey, ECP_POINT_DATA(pRegPublic), pPool /* 3 elem */, pmeth, pME); + + m512 h, h1, h2; + h = h1 = h2 = setzero_i64(); + + /* h = (signS)^(-1) */ + h = n_to_mont(signS); + h = n_inv(h); + + /* h1 = msg*h, h2 = signR*h */ + h1 = n_to_mont(msg); + h2 = n_to_mont(signR); + + h1 = n_mul(h1, h); + h2 = n_mul(h2, h); + + h1 = n_from_mont(h1); + h2 = n_from_mont(h2); + + BNU_CHUNK_T *pExtendedH1 = cpGFpGetPool(2, pME); + BNU_CHUNK_T *pExtendedH2 = cpGFpGetPool(2, pME); + BNU_CHUNK_T *pH1 = cpGFpGetPool(1, pME); + BNU_CHUNK_T *pH2 = cpGFpGetPool(1, pME); + + from_radix52((Ipp64u *)pH1, h1); + from_radix52((Ipp64u *)pH2, h2); + cpGFpElementCopyPad(pExtendedH1, orderLen + 1, pH1, orderLen); + cpGFpElementCopyPad(pExtendedH2, orderLen + 1, pH2, orderLen); + + cpGFpReleasePool(2, pME); /* pH1, pH2 */ + + __ALIGN64 P384_POINT_IFMA P; + P.x = P.y = P.z = setzero_i64(); + + /* P = h1*basePoint + h2*pubKey */ + ifma_ec_nistp384_mul_point(&pubKey, &pubKey, (Ipp8u *)pExtendedH2, orderBits); + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp384_mul_pointbase(&P, (Ipp8u *)pExtendedH1, orderBits); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P384_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool /* 3 elem */, pmeth, pME); + + ifma_ec_nistp384_mul_point(&P, &G52, (Ipp8u *)pExtendedH1, orderBits); + } + + ifma_ec_nistp384_add_point(&P, &P, &pubKey); + + /* Get X in affine coordinates */ + ifma_ec_nistp384_get_affine_coords(&(P.x), NULL, &P); + + P.x = p_from_mont(P.x); + P.x = n_red(P.x); + + const mask8 mask_ok = cmp_i64_mask(P.x, signR, _MM_CMPINT_EQ); + if ((mask8)0xFF == mask_ok) + verifyResult = ippECValid; + + cpGFpReleasePool(7, pME); + + return verifyResult; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p521.c new file mode 100644 index 000000000..b45827c9f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_dsaverify_p521.c @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method_p521.h" +#include "ifma_ecpoint_p521.h" + +IPP_OWN_DEFN(IppECResult, gfec_VerifyDSA_nistp521_avx512, (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, + const IppsBigNumState* pSignS, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppECResult verifyResult = ippECInvalidSignature; + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod_p521 *pmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(pME); + ifmaArithMethod_p521 *nmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_inv n_inv = nmeth->inv; + ifma_red n_red = nmeth->red; + + /* Convert input parameters to 2^52 radix */ + fe521 msg, signR, signS; + FE521_SET(msg) = FE521_SET(signR) = FE521_SET(signS) = m256_setzero_i64(); + + const int elemLen = GFP_FELEN(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + BNU_CHUNK_T *pBufMsg = pPool; + BNU_CHUNK_T *pBufSignR = pPool + elemLen; + BNU_CHUNK_T *pBufSignS = pPool + 2 * elemLen; + + ZEXPAND_COPY_BNU(pBufMsg, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + ZEXPAND_COPY_BNU(pBufSignR, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + ZEXPAND_COPY_BNU(pBufSignS, orderLen, BN_NUMBER(pSignS), BN_SIZE(pSignS)); + + to_radix52(&msg, (Ipp64u *)pBufMsg); + n_red(&msg, msg); /* reduce just in case */ + to_radix52(&signR, (Ipp64u *)pBufSignR); + to_radix52(&signS, (Ipp64u *)pBufSignS); + + /* Convert public point to proper Montgomery domain and 2^52 radix */ + __ALIGN64 P521_POINT_IFMA pubKey; + recode_point_to_mont52(&pubKey, ECP_POINT_DATA(pRegPublic), pPool /* 3 elem */, pmeth, pME); + + fe521 h, h1, h2; + FE521_SET(h) = FE521_SET(h1) = FE521_SET(h2) = m256_setzero_i64(); + + /* h = (signS)^(-1) */ + n_to_mont(&h, signS); + n_inv(&h, h); + + /* h1 = msg*h, h2 = signR*h */ + n_to_mont(&h1, msg); + n_to_mont(&h2, signR); + + n_mul(&h1, h1, h); + n_mul(&h2, h2, h); + + n_from_mont(&h1, h1); + n_from_mont(&h2, h2); + + BNU_CHUNK_T *pExtendedH1 = cpGFpGetPool(2, pME); + BNU_CHUNK_T *pExtendedH2 = cpGFpGetPool(2, pME); + BNU_CHUNK_T *pH1 = cpGFpGetPool(1, pME); + BNU_CHUNK_T *pH2 = cpGFpGetPool(1, pME); + + from_radix52((Ipp64u *)pH1, h1); + from_radix52((Ipp64u *)pH2, h2); + cpGFpElementCopyPad(pExtendedH1, orderLen + 1, pH1, orderLen); + cpGFpElementCopyPad(pExtendedH2, orderLen + 1, pH2, orderLen); + + cpGFpReleasePool(2, pME); /* pH1, pH2 */ + + __ALIGN64 P521_POINT_IFMA P; + FE521_SET(P.x) = FE521_SET(P.y) = FE521_SET(P.z) = m256_setzero_i64(); + + /* P = h1*basePoint + h2*pubKey */ + ifma_ec_nistp521_mul_point(&pubKey, &pubKey, (Ipp8u *)pExtendedH2, orderBits); + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp521_mul_pointbase(&P, (Ipp8u *)pExtendedH1, orderBits); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P521_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool /* 3 elem */, pmeth, pME); + + ifma_ec_nistp521_mul_point(&P, &G52, (Ipp8u *)pExtendedH1, orderBits); + } + + ifma_ec_nistp521_add_point(&P, &P, &pubKey); + + /* Get X in affine coordinates */ + ifma_ec_nistp521_get_affine_coords(&(P.x), NULL, &P); + + p_from_mont(&(P.x), P.x); + n_red(&(P.x), P.x); + + const mask8 mask_ok = FE521_CMP_MASK(P.x, signR, _MM_CMPINT_EQ); + if ((mask8)0xF == mask_ok) + verifyResult = ippECValid; + + cpGFpReleasePool(7, pME); + + return verifyResult; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p256.c new file mode 100644 index 000000000..e7b477abd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p256.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method.h" +#include "ifma_ecpoint_p256.h" + +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_MulPoint_nistp256_avx512, (IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, + const BNU_CHUNK_T* pScalar, + int scalarLen, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + const int elemLen = GFP_PELEN(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(5, pME); + BNU_CHUNK_T *pExtendedScalar = pPool; /* 2 pool elem to hold scalar */ + BNU_CHUNK_T *pPointPool = pPool + 2 * elemLen; /* 3 pool elem to to hold 3 point coordinates */ + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P256_POINT_IFMA P, R; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPointPool, pmeth, pME); + + ifma_ec_nistp256_mul_point(&R, &P, (Ipp8u*)pExtendedScalar, orderBits); + + recode_point_to_mont64(pR, &R, pPointPool, pmeth, pME); + + cpGFpReleasePool(5, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p384.c new file mode 100644 index 000000000..568acdeab --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p384.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method.h" +#include "ifma_ecpoint_p384.h" + +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_MulPoint_nistp384_avx512, (IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, + const BNU_CHUNK_T* pScalar, + int scalarLen, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + const int elemLen = GFP_PELEN(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(5, pME); + BNU_CHUNK_T *pExtendedScalar = pPool; /* 2 pool elem to hold scalar */ + BNU_CHUNK_T *pPointPool = pPool + 2 * elemLen; /* 3 pool elem to to hold 3 point coordinates */ + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P384_POINT_IFMA P, R; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPointPool, pmeth, pME); + + ifma_ec_nistp384_mul_point(&R, &P, (Ipp8u*)pExtendedScalar, orderBits); + + recode_point_to_mont64(pR, &R, pPointPool, pmeth, pME); + + cpGFpReleasePool(5, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p521.c new file mode 100644 index 000000000..e094acb40 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_mulpoint_p521.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_method_p521.h" +#include "ifma_ecpoint_p521.h" + +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_MulPoint_nistp521_avx512, (IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, + const BNU_CHUNK_T* pScalar, + int scalarLen, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod_p521 *pmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(pME); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + const int elemLen = GFP_PELEN(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(5, pME); + BNU_CHUNK_T *pExtendedScalar = pPool; /* 2 pool elem to hold scalar */ + BNU_CHUNK_T *pPointPool = pPool + 2 * elemLen; /* 3 pool elem to to hold 3 point coordinates */ + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P521_POINT_IFMA P, R; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPointPool, pmeth, pME); + + ifma_ec_nistp521_mul_point(&R, &P, (Ipp8u*)pExtendedScalar, orderBits); + + recode_point_to_mont64(pR, &R, pPointPool, pmeth, pME); + + cpGFpReleasePool(5, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p256.c new file mode 100644 index 000000000..c671edf99 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p256.c @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include +#include + +IPP_OWN_DEFN(int, gfec_point_on_curve_nistp256_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + __ALIGN64 P256_POINT_IFMA P; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pPoint), pPool /* 3 elem */, pmeth, pME); + + const int onCurve = ifma_ec_nistp256_is_on_curve(&P, /* use_jproj_coord = */ !IS_ECP_AFFINE_POINT(pPoint)); + + cpGFpReleasePool(3, pME); + return onCurve; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p384.c new file mode 100644 index 000000000..4f53c598d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p384.c @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include +#include + +IPP_OWN_DEFN(int, gfec_point_on_curve_nistp384_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + __ALIGN64 P384_POINT_IFMA P; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pPoint), pPool /* 3 elem */, pmeth, pME); + + const int onCurve = ifma_ec_nistp384_is_on_curve(&P, /* use_jproj_coord = */ !IS_ECP_AFFINE_POINT(pPoint)); + + cpGFpReleasePool(3, pME); + return onCurve; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p521.c new file mode 100644 index 000000000..4e3eed893 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_on_curve_p521.c @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include +#include + +IPP_OWN_DEFN(int, gfec_point_on_curve_nistp521_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod_p521 *pmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + __ALIGN64 P521_POINT_IFMA P; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pPoint), pPool /* 3 elem */, pmeth, pME); + + const int onCurve = ifma_ec_nistp521_is_on_curve(&P, /* use_jproj_coord = */ !IS_ECP_AFFINE_POINT(pPoint)); + + cpGFpReleasePool(3, pME); + return onCurve; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p256.c new file mode 100644 index 000000000..70a97af6e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p256.c @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_ecpoint_p256.h" +#include "ifma_arith_p256.h" +#include "ifma_arith_method.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_PubKey_nist256_avx512, (IppsGFpECPoint * pR, + const BNU_CHUNK_T* pScalar, + int scalarLen, IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(5, nME); + BNU_CHUNK_T *pExtendedScalar = pPool; + BNU_CHUNK_T *pPointPool = pExtendedScalar + 2 * GFP_FELEN(pME); + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P256_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp256_mul_pointbase(&R, (Ipp8u *)pExtendedScalar, orderBits); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P256_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPointPool /* 3 elem */, pmeth, pME); + + ifma_ec_nistp256_mul_point(&R, &G52, (Ipp8u *)pExtendedScalar, orderBits); + } + + recode_point_to_mont64(pR, &R, pPointPool /* 3 elem */, pmeth, pME); + + cpGFpReleasePool(5, nME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; + } +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p384.c new file mode 100644 index 000000000..7c6ff4dc2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p384.c @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_arith_p384.h" +#include "ifma_ecpoint_p384.h" +#include "ifma_arith_method.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_PubKey_nist384_avx512, (IppsGFpECPoint * pR, + const BNU_CHUNK_T* pScalar, + int scalarLen, IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(5, nME); + BNU_CHUNK_T *pExtendedScalar = pPool; + BNU_CHUNK_T *pPointPool = pExtendedScalar + 2 * GFP_FELEN(pME); + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P384_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp384_mul_pointbase(&R, (Ipp8u *)pExtendedScalar, orderBits); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P384_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPointPool /* 3 elem */, pmeth, pME); + + ifma_ec_nistp384_mul_point(&R, &G52, (Ipp8u *)pExtendedScalar, orderBits); + } + + recode_point_to_mont64(pR, &R, pPointPool /* 3 elem */, pmeth, pME); + + cpGFpReleasePool(5, nME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; + } +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p521.c new file mode 100644 index 000000000..5f8d8d1df --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ec_pubkey_p521.c @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "ifma_ecpoint_p521.h" +#include "ifma_arith_p521.h" +#include "ifma_arith_method_p521.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_PubKey_nist521_avx512, (IppsGFpECPoint * pR, + const BNU_CHUNK_T* pScalar, + int scalarLen, IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod_p521 *pmeth = (ifmaArithMethod_p521 *)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(5, nME); + BNU_CHUNK_T *pExtendedScalar = pPool; + BNU_CHUNK_T *pPointPool = pExtendedScalar + 2 * GFP_FELEN(pME); + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 P521_POINT_IFMA R; + FE521_SET(R.x) = FE521_SET(R.y) = FE521_SET(R.z) = m256_setzero_i64(); + + if (ECP_PREMULBP(pEC)) { + ifma_ec_nistp521_mul_pointbase(&R, (Ipp8u *)pExtendedScalar, orderBits); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 P521_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPointPool /* 3 elem */, pmeth, pME); + + ifma_ec_nistp521_mul_point(&R, &G52, (Ipp8u *)pExtendedScalar, orderBits); + } + + recode_point_to_mont64(pR, &R, pPointPool /* 3 elem */, pmeth, pME); + + cpGFpReleasePool(5, nME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; + } +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p256.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p256.c new file mode 100644 index 000000000..9dc88ea6b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p256.c @@ -0,0 +1,766 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +/* Paper referenced in this file: + * + * [1] "Enhanced Montgomery Multiplication" DOI:10.1155/2008/583926 + * + */ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" + +#include "ifma_arith_p256.h" +#include "ifma_defs.h" +#include "ifma_ecpoint_p256.h" + +#define LEN64 (4) +#define LEN52 (5 + 3) /* 5 digits + 3 zero padding */ + +/* Modulus scaled: 2*p */ +static const __ALIGN64 Ipp64u p256_x2[LEN52] = { + 0x000ffffffffffffe, 0x00001fffffffffff, 0x0000000000000000, 0x0000002000000000, 0x0001fffffffe0000, 0x0, 0x0, 0x0 +}; + +/* Modulus scaled: 4*p */ +static const __ALIGN64 Ipp64u p256_x4[LEN52] = { + 0x000ffffffffffffc, 0x00003fffffffffff, 0x0000000000000000, 0x0000004000000000, 0x0003fffffffc0000, 0x0, 0x0, 0x0 +}; + +/* Modulus scaled: 6*p */ +static const __ALIGN64 Ipp64u p256_x6[LEN52] = { + 0x000ffffffffffffa, 0x00005fffffffffff, 0x0000000000000000, 0x0000006000000000, 0x0005fffffffa0000, 0x0, 0x0, 0x0 +}; + +/* Modulus scaled: 8*p */ +static const __ALIGN64 Ipp64u p256_x8[LEN52] = { + 0x000ffffffffffff8, 0x00007fffffffffff, 0x0000000000000000, 0x0000008000000000, 0x0007fffffff80000, 0x0, 0x0, 0x0 +}; + +/* Mont(a) = a*r mod p256, where r = 2^(6*52) mod p256 */ +static const __ALIGN64 Ipp64u p256_a[LEN52] = { + 0x000ffffffd000000, 0x000fffffffffffcf, 0x000300000002ffff, 0x0000000000000000, 0x0000000000000300, 0x0, 0x0, 0x0 +}; + +/* Mont(b) = b*r mod p256, where r = 2^(6*52) mod p256 */ +static const __ALIGN64 Ipp64u p256_b[LEN52] = { + 0x000c30061de0b74e, 0x000916229c4bddfd, 0x000c9c542a72f7e5, 0x00069e0d6acf005c, 0x000051ea29688e16, 0x0, 0x0, 0x0 +}; + +/* + * r = 2^(P256_LEN52*DIGIT_SIZE) mod p256 + */ +static const __ALIGN64 Ipp64u p256_r[LEN52] = { + 0x0000000000ffffff, 0x0000100000000010, 0x000effffffff0000, 0x0000000fffffffff, 0x0000fffffffeff00, 0x0, 0x0, 0x0 +}; + +/* Aliases for operations */ +#define add(R, A, B) (R) = add_i64((A), (B)) +#define sub(R, A, B) (R) = sub_i64((A), (B)) +#define mul(R, A, B) (R) = ifma_amm52_p256((A), (B)) +#define sqr(R, A) (R) = ifma_ams52_p256((A)) +#define div2(R, A) (R) = ifma_half52_p256((A)) +#define inv(R, A) (R) = ifma_aminv52_p256((A)) +#define norm(R, A) (R) = ifma_norm52((A)) +#define lnorm(R, A) (R) = ifma_lnorm52((A)) +#define from_mont(R, A) (R) = ifma_frommont52_p256((A)) + +/* Aliases for dual operations */ +#define mul_dual(R1, A1, B1, R2, A2, B2) ifma_amm52_dual_p256(&(R1), (A1), (B1), &(R2), (A2), (B2)) +#define sqr_dual(R1, A1, R2, A2) ifma_ams52_dual_p256(&(R1), (A1), &(R2), (A2)) +#define norm_dual(R1, A1, R2, A2) ifma_norm52_dual(&(R1), (A1), &(R2), (A2)) +#define lnorm_dual(R1, A1, R2, A2) ifma_lnorm52_dual(&(R1), (A1), &(R2), (A2)) + +/* to affine coordinate */ +IPP_OWN_DEFN(void, ifma_ec_nistp256_get_affine_coords, (m512 * rx, m512 *ry, const P256_POINT_IFMA *a)) +{ + m512 z1, z2, z3; + + inv(z1, a->z); /* 1/z */ + sqr(z2, z1); /* (1/z)^2 */ + lnorm(z2, z2); + + /* x = x/z^2 */ + if (NULL != rx) { + mul(*rx, a->x, z2); /* x = x/z^2 */ + lnorm(*rx, *rx); + } + /* y = y/z^3 */ + if (NULL != ry) { + mul(z3, z1, z2); /* (1/z)^3 */ + lnorm(z3, z3); + mul(*ry, a->y, z3); /* y = y/z^3 */ + lnorm(*ry, *ry); + } +} + +IPP_OWN_DEFN(void, ifma_ec_nistp256_dbl_point, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p)) +{ + /* + * Enhanced Montgomery group algorithm described in [1]. + * + * l1 = 3x^2 + a*z^4 = [a = -3]= 3*(x^2 - z^4) = 3*(x - z^2)*(x + z^2) + * z2 = 2*y*z + * l2 = 4*x*y^2 + * x2 = l1^2 - 2*l2 + * l3 = 8*y^4 + * y2 = l1*(l2 - x2) - l3 + * + */ + const m512 *x1 = &p->x; + const m512 *y1 = &p->y; + const m512 *z1 = &p->z; + + m512 x2; + m512 y2; + m512 z2; + x2 = y2 = z2 = setzero_i64(); + + m512 T, U, V, A, B, H; + T = U = V = A = B = H = setzero_i64(); + + const m512 M2 = loadu_i64(p256_x2); + const m512 M4 = loadu_i64(p256_x4); + const m512 M8 = loadu_i64(p256_x8); + + add(T, *y1, *y1); /* T = 2*y1 */ + lnorm(T, T); + + sqr_dual(V, T, /* V = 4*y1^2 */ + U, *z1); /* U = z1^2 */ + + sub(B, *x1, U); /* B = x1 - z1^2 */ + add(B, B, M2); + add(U, *x1, U); /* U = x1 + z1^2 */ + + lnorm_dual(V, V, + U, U); + norm(B, B); + + mul_dual(A, V, *x1, /* A = 4*x1*y1^2 */ + B, B, U); /* B = (x1 - z1^2)*(x1 + z1^2) */ + + add(x2, A, A); /* x2 = 8*x1*y1^2 */ + add(H, B, B); + add(B, B, H); /* B(l1) = 3*(x1 - z1^2)*(x1 + z1^2) */ + + lnorm(B, B); + + sqr_dual(U, B, /* U = l1^2 */ + y2, V); /* y2 = 16*y^2 */ + + sub(x2, U, x2); /* x2 = l1^2 - 2*l2 */ + add(x2, x2, M4); + div2(y2, y2); + + sub(U, A, x2); /* U = l2 - x2 */ + add(U, U, M8); + + norm(U, U); + + mul_dual(z2, T, *z1, /* z2 = 2*y1*z1 */ + U, U, B); /* U = B(l1)*(A(l2) - x2) */ + + sub(y2, U, y2); /* y2 = B(l1)*(A(l2) - x2) - y2(l3) */ + add(y2, y2, M2); + + norm_dual(r->x, x2, + r->y, y2); + lnorm(r->z, z2); +} + +IPP_OWN_DEFN(void, ifma_ec_nistp256_add_point, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p, const P256_POINT_IFMA *q)) +{ + /* + * Enhanced Montgomery group algorithm described in [1]. + * + * A = x1*z2^2 B = x2*z1^2 C = y1*z2^3 D = y2*z1^3 + * E = B - A F = D - C + * x3 = -E^3 - 2*A*E^2 + F^2 + * y3 = -C*E^3 + F*(A*E^2 - x3) + * z3 = z1*z2*E + */ + const m512 *x1 = &p->x; + const m512 *y1 = &p->y; + const m512 *z1 = &p->z; + const mask8 p_is_inf = is_zero_i64(p->z); + + const m512 *x2 = &q->x; + const m512 *y2 = &q->y; + const m512 *z2 = &q->z; + const mask8 q_is_inf = is_zero_i64(q->z); + + m512 x3; + m512 y3; + m512 z3; + x3 = y3 = z3 = setzero_i64(); + + const m512 M2 = loadu_i64(p256_x2); + const m512 M4 = loadu_i64(p256_x4); + const m512 M8 = loadu_i64(p256_x8); + + m512 U1, U2, S1, S2, H, R; + U1 = U2 = S1 = S2 = H = R = setzero_i64(); + + mul_dual(S1, *y1, *z2, /* s1 = y1*z2 */ + U1, *z2, *z2); /* u1 = z2^2 */ + + lnorm_dual(S1, S1, + U1, U1); + + mul_dual(S2, *y2, *z1, /* s2 = y2*z1 */ + U2, *z1, *z1); /* u2 = z1^2 */ + + lnorm_dual(S2, S2, + U2, U2); + + mul_dual(S1, S1, U1, /* s1 = y1*z2^3 (C) */ + S2, S2, U2); /* s2 = y2*z1^3 (D) */ + + lnorm_dual(S1, S1, + S2, S2); + + mul_dual(U1, *x1, U1, /* u1 = x1*z2^2 (A) */ + U2, *x2, U2); /* u2 = x2*z1^2 (B) */ + + lnorm_dual(U1, U1, + U2, U2); + + sub(R, S2, S1); /* r = D - C (F) */ + sub(H, U2, U1); /* h = B - A (E) */ + + /* checking the equality of X and Y coordinates (D - C == 0) and (B - A == 0) */ + const mask8 f_are_zero = is_zero_i64(R); + const mask8 e_are_zero = is_zero_i64(H); + const mask8 point_is_equal = ((e_are_zero & f_are_zero) & (~p_is_inf) & (~q_is_inf)); + + __ALIGN64 P256_POINT_IFMA r2; + r2.x = r2.y = r2.z = setzero_i64(); + if ((mask8)0xFF == point_is_equal) { + ifma_ec_nistp256_dbl_point(&r2, p); + } + + add(R, R, M2); + add(H, H, M2); + norm_dual(R, R, + H, H); + + mul_dual(z3, *z1, *z2, /* z3 = z1*z2 */ + U2, H, H); /* u2 = E^2 */ + + lnorm_dual(z3, z3, + U2, U2); + + mul_dual(z3, z3, H, /* z3 = (z1*z2)*E */ + S2, R, R); /* s2 = F^2 */ + mul(H, H, U2); /* h = E^3 */ + + lnorm(H, H); + + mul(U1, U1, U2); /* u1 = A*E^2 */ + sub(x3, S2, H); /* x3 = F^2 - E^3 */ + add(x3, x3, M2); + add(U2, U1, U1); /* u2 = 2*A*E^2 */ + mul(S1, S1, H); /* s1 = C*E^3 */ + sub(x3, x3, U2); /* x3 = (F^2 - E^3) -2*A*E^2 */ + add(x3, x3, M4); + + sub(y3, U1, x3); /* y3 = A*E^2 - x3 */ + add(y3, y3, M8); + + norm(y3, y3); + + mul(y3, y3, R); /* y3 = F*(A*E^2 - x3) */ + sub(y3, y3, S1); /* y3 = F*(A*E^2 - x3) - C*E^3 */ + add(y3, y3, M2); + + norm_dual(x3, x3, + y3, y3); + lnorm(z3, z3); + + /* T = p_is_inf ? q : T */ + x3 = mask_mov_i64(x3, p_is_inf, *x2); + y3 = mask_mov_i64(y3, p_is_inf, *y2); + z3 = mask_mov_i64(z3, p_is_inf, *z2); + + /* T = q_is_inf ? p : T */ + x3 = mask_mov_i64(x3, q_is_inf, *x1); + y3 = mask_mov_i64(y3, q_is_inf, *y1); + z3 = mask_mov_i64(z3, q_is_inf, *z1); + + /* r = point_is_equal ? r2 : T */ + x3 = mask_mov_i64(x3, point_is_equal, r2.x); + y3 = mask_mov_i64(y3, point_is_equal, r2.y); + z3 = mask_mov_i64(z3, point_is_equal, r2.z); + + r->x = x3; + r->y = y3; + r->z = z3; +} + +IPP_OWN_DEFN(void, ifma_ec_nistp256_add_point_affine, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p, const P256_POINT_AFFINE_IFMA *q)) +{ + /* + * Enhanced Montgomery group algorithm described in [1]. + * + * A = x1 B = x2*z1^2 C = y1 D = y2*z1^3 + * E = B - A(x1) F = D - C(y1) + * x3 = -E^3 - 2*A(x1)*E^2 + F^2 + * y3 = -C(y1)*E^3 + F*(A(x1)*E^2 - x3) + * z3 = z1*E + */ + + /* Coordinates of p (jacobian projective) */ + const m512 *x1 = &p->x; + const m512 *y1 = &p->y; + const m512 *z1 = &p->z; + const mask8 p_is_inf = is_zero_i64(p->z); + + /* Coodinates of q (affine) */ + const m512 *x2 = &q->x; + const m512 *y2 = &q->y; + const mask8 q_is_inf = (is_zero_i64(q->x) & is_zero_i64(q->y)); + + const m512 M2 = loadu_i64(p256_x2); + const m512 M4 = loadu_i64(p256_x4); + const m512 M8 = loadu_i64(p256_x8); + + m512 x3, y3, z3; + x3 = y3 = z3 = setzero_i64(); + + m512 U2, S2, H, R; + U2 = S2 = H = R = setzero_i64(); + + mul_dual(R, *z1, *z1, /* R = z1^2 */ + S2, *y2, *z1); /* S2 = y2*z1 */ + + lnorm_dual(R, R, + S2, S2); + + mul_dual(U2, *x2, R, /* U2 = x2*z1^2 (B) */ + S2, S2, R); /* S2 = y2*z1^3 (D) */ + + sub(H, U2, *x1); /* H = B - A (E) */ + add(H, H, M8); + sub(R, S2, *y1); /* R = D - C (F) */ + add(R, R, M4); + + norm_dual(H, H, + R, R); + + mul(z3, H, *z1); /* z3 = z1*E */ + + sqr_dual(U2, H, /* U2 = E^2 */ + S2, R); /* S2 = F^2 */ + + lnorm(U2, U2); + + mul(H, H, U2); /* H = E^3 */ + + lnorm(H, H); + + mul_dual(U2, U2, *x1, /* U2 = A*E^2 */ + y3, H, *y1); /* y3 = C*E^3 */ + + add(x3, U2, U2); /* x2 = 2*A*E^2 */ + sub(x3, S2, x3); /* x3 = F^2 - 2*A*E^2 */ + add(x3, x3, M4); + sub(x3, x3, H); /* x3 = F^2 - 2*A*E^2 - E^3 */ + add(x3, x3, M2); + + sub(U2, U2, x3); /* U2 = A*E^2 - x3 */ + add(U2, U2, M8); + norm(U2, U2); + mul(U2, U2, R); /* U2 = F*(A*E^2 - x3) */ + sub(y3, U2, y3); /* y3 = F*(A*E^2 - x3) - C*E^2 */ + add(y3, y3, M2); + + norm_dual(x3, x3, + y3, y3); + lnorm(z3, z3); + + /* T = p_is_inf ? q : T */ + x3 = mask_mov_i64(x3, p_is_inf, *x2); + y3 = mask_mov_i64(y3, p_is_inf, *y2); + z3 = mask_mov_i64(z3, p_is_inf, loadu_i64(p256_r)); + + /* T = q_is_inf ? p : T */ + x3 = mask_mov_i64(x3, q_is_inf, *x1); + y3 = mask_mov_i64(y3, q_is_inf, *y1); + z3 = mask_mov_i64(z3, q_is_inf, *z1); + + r->x = x3; + r->y = y3; + r->z = z3; +} + +IPP_OWN_DEFN(int, ifma_ec_nistp256_is_on_curve, (const P256_POINT_IFMA *p, const int use_jproj_coords)) +{ + /* + * y^2 = x^3 + a*x + b (1) + * + * if input + * * Jacobian projective coordinate (x,y,z) reprepresented by (x/z^2,y/z^3,1) + * * Affine coodinate -> (x/z^2,y/z^3,z/z=1) + * + * Mult (1) by z^6 + * + * y^2 = x^3 + a*x*z^4 + b*z^6 + */ + const m512 M6 = loadu_i64(p256_x6); + const m512 a = loadu_i64(p256_a); + const m512 b = loadu_i64(p256_b); + + m512 rh, Z4, Z6, tmp; + rh = Z4 = Z6 = tmp = setzero_i64(); + + sqr(rh, p->x); /* rh = x^2 */ + + /* rh = x*(x^2 + a*z^4) + b*z^6 = x*(x^2 - 3*z^4) + b*z^6 */ + if (0 != use_jproj_coords) { + sqr(tmp, p->z); /* tmp = z^2 */ + lnorm(tmp, tmp); + + sqr(Z4, tmp); /* z4 = z^4 */ + lnorm(Z4,Z4); /* norm */ + mul(Z6, Z4, tmp); /* z6 = z^6 */ + lnorm(Z6,Z6); /* norm */ + + add(tmp, Z4, Z4); /* tmp = 2*z^4 */ + add(tmp, tmp, Z4); /* tmp = 3*z^4 */ + + sub(rh, rh, tmp); /* rh = x^2 - 3*z^4 */ + add(rh, rh, M6); + norm(rh, rh); + + mul_dual(rh, rh, p->x, /* rh = x*(x^2 - 3*z^4) */ + tmp, Z6, b); /* tmp = b*z^6 */ + + add(rh, rh, tmp); /* rh = x*(x^2 - 3*z^4) + b*z^6 */ + } + + /* rh = x*(x^2 + a) + b */ + else { + add(rh, rh, a); /* rh = x^2 + a */ + lnorm(rh, rh); + mul(rh, rh, p->x); /* rh = x*(x^2 + a) */ + add(rh, rh, b); /* rh = x*(x^2 + a) + b */ + } + + lnorm(rh, rh); + + /* rl = Y^2 */ + sqr(tmp, p->y); /* tmp = y^2 */ + lnorm(tmp, tmp); /**/ + + /* from mont */ + from_mont(tmp, tmp); + from_mont(rh, rh); + + const mask8 mask = cmp_i64_mask(rh, tmp, _MM_CMPINT_EQ); + return (mask == 0xFF) ? 1 : 0; +} + +#undef add +#undef sub +#undef mul +#undef sqr +#undef div2 +#undef norm +#undef from_mont +#undef mul_dual +#undef sqr_dual +#undef norm_dual + +static __NOINLINE void clear_secret_context(Ipp16u *wval, + Ipp32s *chunk_no, Ipp32s *chunk_shift, + Ipp8u *sign, Ipp8u *digit, + P256_POINT_IFMA *R, P256_POINT_IFMA *H, + P256_POINT_AFFINE_IFMA *A) +{ + *wval = 0; + *chunk_no = 0; + *chunk_shift = 0; + *sign = 0; + *digit = 0; + + if (NULL != R) + (*R).x = (*R).y = (*R).z = setzero_i64(); + if (NULL != H) + (*H).x = (*H).y = (*H).z = setzero_i64(); + if (NULL != A) + (*A).x = (*A).y = setzero_i64(); +} + +#define WIN_SIZE (5) + +__INLINE mask8 is_eq_mask(const Ipp32s a, const Ipp32s b) +{ + const Ipp32s eq = a ^ b; + const Ipp32s v = ~eq & (eq - 1); + const Ipp32s msb = 0 - (v >> (sizeof(a) * 8 - 1)); + return (mask8)(0 - msb); +} + +__INLINE void extract_table_point(P256_POINT_IFMA *r, const Ipp32s digit, const P256_POINT_IFMA *tbl) +{ + Ipp32s idx = digit - 1; + + __ALIGN64 P256_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + + for (Ipp32s n = 0; n < (1 << (WIN_SIZE - 1)); ++n) { + const mask8 mask = is_eq_mask(n, idx); + + R.x = mask_mov_i64(R.x, mask, tbl[n].x); + R.y = mask_mov_i64(R.y, mask, tbl[n].y); + R.z = mask_mov_i64(R.z, mask, tbl[n].z); + } + + r->x = R.x; + r->y = R.y; + r->z = R.z; +} + +#define dbl_point ifma_ec_nistp256_dbl_point +#define add_point ifma_ec_nistp256_add_point +#define neg_coord ifma_neg52_p256 +#define add_point_affine ifma_ec_nistp256_add_point_affine + +/* r = n*P = (P + P + ... + P) */ +IPP_OWN_DEFN(void, ifma_ec_nistp256_mul_point, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p, const Ipp8u *pExtendedScalar, const int scalarBitSize)) +{ + /* Precompute table */ + __ALIGN64 P256_POINT_IFMA tbl[(1 << (WIN_SIZE - 1))]; + + __ALIGN64 P256_POINT_IFMA R; + __ALIGN64 P256_POINT_IFMA H; + + R.x = R.y = R.z = setzero_i64(); + H.x = H.y = H.z = setzero_i64(); + m512 negHy = setzero_i64(); + + /* compute tbl[] = [n]P, n = 1, ... , 2^(win_size - 1) + * tbl[2*n] = tbl[2*n - 1] + p + * tbl[2*n + 1] = [2]*tbl[n] + */ + + /* tbl[0] = p */ + tbl[0].x = p->x; + tbl[0].y = p->y; + tbl[0].z = p->z; + + /* tbl[1] = [2]*p */ + dbl_point(/* r = */ (tbl + 1), /* a = */ p); + + for (int n = 1; n < ((1 << (WIN_SIZE - 1)) / 2); ++n) { + add_point((tbl + 2 * n), (tbl + 2 * n - 1), p); + dbl_point((tbl + 2 * n + 1), (tbl + n)); + } + + Ipp16u wval; + Ipp8u digit, sign; + const Ipp32s mask = ((1 << (WIN_SIZE + 1)) - 1); /* mask 0b111111 */ + Ipp32s bit = scalarBitSize - (scalarBitSize % WIN_SIZE); + + Ipp32s chunk_no = (bit - 1) / 8; + Ipp32s chunk_shift = (bit - 1) % 8; + + if (0 != bit) { + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + } else { + wval = 0; + } + + booth_recode(&sign, &digit, (Ipp8u)wval, WIN_SIZE); + extract_table_point(&R, (Ipp32s)digit, tbl); + + for (bit -= WIN_SIZE; bit >= WIN_SIZE; bit -= WIN_SIZE) { + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, WIN_SIZE); + extract_table_point(&H, (Ipp32s)digit, tbl); + + negHy = neg_coord(H.y); + + const mask8 mask_neg = (mask8)(~(sign - 1)); + H.y = mask_mov_i64(H.y, mask_neg, negHy); + + add_point(&R, &R, &H); + } + + /* last window */ + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + + wval = *((Ipp16u *)(pExtendedScalar + 0)); + wval = (Ipp16u)((wval << 1) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, WIN_SIZE); + extract_table_point(&H, (Ipp32s)digit, tbl); + + negHy = neg_coord(H.y); + + const mask8 mask_neg = (mask8)(~(sign - 1)); + H.y = mask_mov_i64(H.y, mask_neg, negHy); + + add_point(&R, &R, &H); + + r->x = R.x; + r->y = R.y; + r->z = R.z; + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, &H, NULL); + + return; +} + +/* #include "ifma_ecprecomp4_p256.h" */ +#include "ifma_ecprecomp7_p256.h" + +/* mul point base */ +#define BP_WIN_SIZE BASE_POINT_WIN_SIZE +#define BP_N_ENTRY BASE_POINT_N_ENTRY + +__INLINE void extract_point_affine(P256_POINT_AFFINE_IFMA *r, + const P256_POINT_AFFINE_IFMA_MEM *tbl, + const Ipp32s digit) +{ + Ipp32s idx = digit - 1; + + m512 x, y; + x = y = setzero_i64(); + + for (Ipp32s n = 0; n < (1 << ((BP_WIN_SIZE)-1)); ++n, ++tbl) { + const mask8 mask = is_eq_mask(n, idx); + + x = mask_mov_i64(x, mask, maskz_loadu_i64(0x1f, tbl->X)); + y = mask_mov_i64(y, mask, maskz_loadu_i64(0x1f, tbl->Y)); + } + + r->x = x; + r->y = y; +} + +IPP_OWN_DEFN(void, p256r1_select_ap_w7_ifma, (BNU_CHUNK_T * pAffinePoint, const BNU_CHUNK_T *pTable, int index)) +{ + __ALIGN64 P256_POINT_AFFINE_IFMA ap; + + extract_point_affine(&ap, (P256_POINT_AFFINE_IFMA_MEM *)pTable, index); + + ap.x = ifma_frommont52_p256(ap.x); + ap.y = ifma_frommont52_p256(ap.y); + + convert_radix_to_64x4(pAffinePoint, ap.x); + convert_radix_to_64x4(pAffinePoint + LEN64, ap.y); +} + +IPP_OWN_DEFN(void, ifma_ec_nistp256_mul_pointbase, (P256_POINT_IFMA * r, const Ipp8u *pExtendedScalar, int scalarBitSize)) +{ + /* precompute table */ + const P256_POINT_AFFINE_IFMA_MEM *tbl = &ifma_ec_nistp256r1_bp_precomp[0][0]; + + __ALIGN64 P256_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + __ALIGN64 P256_POINT_AFFINE_IFMA A; + A.x = A.y = setzero_i64(); + + m512 Ty = setzero_i64(); + + Ipp16u wval; + Ipp8u digit, sign; + const Ipp32s mask = ((1 << (BP_WIN_SIZE + 1)) - 1); /* mask 0b11111 */ + Ipp32s bit = 0; + Ipp32s chunk_no, chunk_shift; + + wval = *((Ipp16u *)(pExtendedScalar + 0)); + wval = (Ipp16u)((wval << 1) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + Ty = neg_coord(A.y); + mask8 mask_neg = (mask8)(~(sign - 1)); + A.y = mask_mov_i64(A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + + for (bit += BP_WIN_SIZE; bit <= scalarBitSize; bit += BP_WIN_SIZE) { + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + Ty = neg_coord(A.y); + mask_neg = (mask8)(~(sign - 1)); + A.y = mask_mov_i64(A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + } + + r->x = R.x; + r->y = R.y; + r->z = R.z; + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, NULL, &A); + return; +} + +#undef dbl_point +#undef add_point +#undef neg_coord +#undef add_point_affine + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p256.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p256.h new file mode 100644 index 000000000..21a320a18 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p256.h @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +/* Paper referenced in this header: + * + * [1] "Enhanced Montgomery Multiplication" DOI:10.1155/2008/583926 + * + */ + +#ifndef IFMA_ECPOINT_P256_H +#define IFMA_ECPOINT_P256_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_p256.h" +#include "pcpbnuimpl.h" + +/* p256 point (x,y,z) */ +typedef struct { + m512 x; + m512 y; + m512 z; +} P256_POINT_IFMA; + +/* p256 affine point(x,y) */ +typedef struct { + m512 x; + m512 y; +} P256_POINT_AFFINE_IFMA; + +/** + * \brief + * + * R = [pExtendedScalar]*P = (P + P + ... + P) + * + * \param[out] r point in radix 2^52 + * \param[in] p point in radix 2^52 + * \param[in] pExtendedScalar pointer to a scalar + * \param[in] scalarBitSize scalar size in bits + */ +IPP_OWN_DECL(void, ifma_ec_nistp256_mul_point, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p, const Ipp8u *pExtendedScalar, const int scalarBitSize)) + +/** + * \brief + * + * R = [pExtendedScalar]*BasePoint + * + * \param[out] r point in radix 2^52 + * \param[in] pExtendedScalar pointer to a scalar + * \param[in] scalarBitSize scalar size in bits + */ +IPP_OWN_DECL(void, ifma_ec_nistp256_mul_pointbase, (P256_POINT_IFMA * r, const Ipp8u *pExtendedScalar, int scalarBitSize)) + +/** + * \brief + * + * Convert point to affine coordinate + * + * \param[out] rx X-affine coordinate + * \param[out] ry Y-affine coordinate + * \param[in] a point in projective coordinates + */ +IPP_OWN_DECL(void, ifma_ec_nistp256_get_affine_coords, (m512 * rx, m512 *ry, const P256_POINT_IFMA *a)) + +/** + * \brief + * + * Check if the point is on curve p256r1 + * + * \param[in] p point in radix 2^52 + * \param[in] use_jproj_coords flag whether coordinates are in Projective of Affine representation + * \return int 1 - true + * 0 - false + */ +IPP_OWN_DECL(int, ifma_ec_nistp256_is_on_curve, (const P256_POINT_IFMA *p, const int use_jproj_coords)) + +/** + * \brief + * + * Point doubling on p256r1 curve (Enhanced Montgomery Algorithm, see [1]) + * + * \param[out] r point in projective coordinates + * \param[in] p point in projective coordinates + */ +IPP_OWN_DECL(void, ifma_ec_nistp256_dbl_point, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p)) + +/** + * \brief + * + * Point addition on p256r1 curve (Enhanced Montgomery Algorithm, see [1]) + * + * \param[out] r result point + * \param[in] p first point + * \param[in] q second point + */ +IPP_OWN_DECL(void, ifma_ec_nistp256_add_point, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p, const P256_POINT_IFMA *q)) + +/** + * \brief + * + * Point addition on p256r1 curve (Enhanced Montgomery Algorithm, see [1]) + * + * \param[out] r point in projective coordinates + * \param[in] p point in projective coordinates + * \param[in] q point in affine coordinates + */ +IPP_OWN_DECL(void, ifma_ec_nistp256_add_point_affine, (P256_POINT_IFMA * r, const P256_POINT_IFMA *p, const P256_POINT_AFFINE_IFMA *q)) + +/** + * \brief + * + * Extracts affine point from the precomputed table. + * + * \param[out] pAffinePoint array of x and y coordinates of affine point in 2^64 radix + * \param[in] pTable pointer to a precomputed table + * \param[in] index index of desired point in the table + */ +IPP_OWN_DECL(void, p256r1_select_ap_w7_ifma, (BNU_CHUNK_T * pAffinePoint, const BNU_CHUNK_T *pTable, int index)) + + +#include "ifma_arith_method.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +__INLINE void recode_point_to_mont52(P256_POINT_IFMA *pR, + const BNU_CHUNK_T *pP, + BNU_CHUNK_T *pPool, + ifmaArithMethod *method, + gsModEngine *pME) +{ + ifma_import to_radix52 = method->import_to52; + ifma_encode p_to_mont = method->encode; + + const int elemLen = GFP_FELEN(pME); + + BNU_CHUNK_T *pX = pPool; + BNU_CHUNK_T *pY = pPool + elemLen; + BNU_CHUNK_T *pZ = pPool + 2 * elemLen; + + GFP_METHOD(pME)->decode(pX, pP, pME); + GFP_METHOD(pME)->decode(pY, pP + elemLen, pME); + GFP_METHOD(pME)->decode(pZ, pP + 2 * elemLen, pME); + + pR->x = to_radix52((Ipp64u *)pX); + pR->y = to_radix52((Ipp64u *)pY); + pR->z = to_radix52((Ipp64u *)pZ); + + pR->x = p_to_mont(pR->x); + pR->y = p_to_mont(pR->y); + pR->z = p_to_mont(pR->z); +} + +__INLINE void recode_point_to_mont64(IppsGFpECPoint *pR, + P256_POINT_IFMA *pP, + BNU_CHUNK_T *pPool, + ifmaArithMethod *method, + gsModEngine *pME) +{ + ifma_export to_radix64 = method->export_to64; + ifma_decode p_from_mont = method->decode; + + const int elemLen = GFP_PELEN(pME); + BNU_CHUNK_T *pX = pPool; + BNU_CHUNK_T *pY = pPool + elemLen; + BNU_CHUNK_T *pZ = pPool + 2 * elemLen; + + pP->x = p_from_mont(pP->x); + pP->y = p_from_mont(pP->y); + pP->z = p_from_mont(pP->z); + + to_radix64((Ipp64u *)pX, pP->x); + to_radix64((Ipp64u *)pY, pP->y); + to_radix64((Ipp64u *)pZ, pP->z); + + GFP_METHOD(pME)->encode(ECP_POINT_X(pR), pX, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Y(pR), pY, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Z(pR), pZ, pME); +} + + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // IFMA_ECPOINT_P256_H diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p384.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p384.c new file mode 100644 index 000000000..7e3b6893c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p384.c @@ -0,0 +1,798 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" + +#include "ifma_arith_p384.h" +#include "ifma_defs.h" +#include "ifma_ecpoint_p384.h" + +#define LEN64 (6) +#define LEN52 (8) + +/* modulus 2*p */ +static const __ALIGN64 Ipp64u p384_x2[LEN52] = { + 0x00000001FFFFFFFE, 0x000FE00000000000, 0x000FFFFFFDFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x00000000001FFFFF +}; +/* modulus 4*p */ +static const __ALIGN64 Ipp64u p384_x4[LEN52] = { + 0x00000003FFFFFFFC, 0x000FC00000000000, 0x000FFFFFFBFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x00000000003FFFFF +}; +/* modulus 6*p */ +static const __ALIGN64 Ipp64u p384_x6[LEN52] = { + 0x00000005FFFFFFFA, 0x000FA00000000000, 0x000FFFFFF9FFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x00000000005FFFFF +}; +/* modulus 8*p */ +static const __ALIGN64 Ipp64u p384_x8[LEN52] = { + 0x00000007FFFFFFF8, 0x000F800000000000, 0x000FFFFFF7FFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x00000000007FFFFF +}; + +/* mont(a) */ +static const __ALIGN64 Ipp64u p384_a[LEN52] = { + 0x000FFFFDFFFFFFFF, 0x000FF00000002FFF, 0x000FFFFFFBFFFFFF, 0x000FFFFFFFFFFFCF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x00000000000FFFFF +}; +/* mont(b) */ +static const __ALIGN64 Ipp64u p384_b[LEN52] = { + 0x00091C81CD08114B, 0x0003708118870D03, 0x000431BF24475444, 0x000209B1920022FC, 0x000E94938AE277F2, 0x000022094E3374BE, 0x000FF9B62B21F41F, 0x00000000000604FB +}; + +/* Montgomery(1) + * r = 2^(P384_LEN52*DIGIT_SIZE) mod p384 + */ +static const __ALIGN64 Ipp64u p384_r[LEN52] = { + 0x0000000100000000, 0x000FFFFFFFFFF000, 0x0000000000FFFFFF, 0x0000000000000010, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 +}; + +#define add(R, A, B) (R) = add_i64((A), (B)) +#define sub(R, A, B) (R) = sub_i64((A), (B)) +#define mul(R, A, B) (R) = ifma_amm52_p384((A), (B)) +#define sqr(R, A) (R) = ifma_ams52_p384((A)) +#define div2(R, A) (R) = ifma_half52_p384((A)) +#define inv(R, A) (R) = ifma_aminv52_p384((A)) +#define norm(R, A) (R) = ifma_norm52((A)) +#define lnorm(R, A) (R) = ifma_lnorm52((A)) +#define from_mont(R, A) (R) = ifma_frommont52_p384((A)) + +/* Dual mult/sqr/norm */ +#define mul_dual(R1, A1, B1, R2, A2, B2) ifma_amm52_dual_p384(&(R1), (A1), (B1), &(R2), (A2), (B2)) +#define sqr_dual(R1, A1, R2, A2) ifma_ams52_dual_p384(&(R1), (A1), &(R2), (A2)) +#define norm_dual(R1, A1, R2, A2) ifma_norm52_dual(&(R1), (A1), &(R2), (A2)) +#define lnorm_dual(R1, A1, R2, A2) ifma_lnorm52_dual(&(R1), (A1), &(R2), (A2)) + +/* to affine coordinate */ +IPP_OWN_DEFN(void, ifma_ec_nistp384_get_affine_coords, (m512 * prx, m512 *pry, const P384_POINT_IFMA *a)) +{ + m512 z1, z2, z3; + z1 = z2 = z3 = setzero_i64(); + + inv(z1, a->z); /* 1/z */ + sqr(z2, z1); /* (1/z)^2 */ + lnorm(z2, z2); /**/ + + /* x = x/z^2 */ + if (NULL != prx) { + mul(*prx, a->x, z2); /* x = x/z^2 */ + lnorm(*prx, *prx); /**/ + } + /* y = y/z^3 */ + if (NULL != pry) { + mul(z3, z1, z2); /* (1/z)^3 */ + lnorm(z3, z3); /**/ + mul(*pry, a->y, z3); /* y = y/z^3 */ + lnorm(*pry, *pry); /**/ + } + + return; +} + +IPP_OWN_DEFN(void, ifma_ec_nistp384_dbl_point, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p)) +{ + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * + * Gueron (2002). Enhanced Montgomery Multiplication. + * In Cryptographic Hardware and Embedded Systems - CHES 2002, + * 4th International Workshop, Redwood Shores, CA, USA, + * August 13-15, 2002, Revised Papers (pp. 46-56) + * [ DOI: 10.1007/3-540-36400-5_5 ] + * + * l1 = 3x^2 + a*z^4 = (if p384 a = -3) = 3*(x^2 - z^4) = 3*(x - z^2)*(x + z^2) + * z2 = 2*y*z + * l2 = 4*x*y^2 + * x2 = l1^2 - 2*l2 + * l3 = 8*y^4 + * y2 = l1*(l2 - x2) - l3 + * + * sum arithmetic: 8 mul; 9 add/sub; 1 div2. + */ + const m512 *x1 = &p->x; + const m512 *y1 = &p->y; + const m512 *z1 = &p->z; + + m512 x2; + m512 y2; + m512 z2; + x2 = y2 = z2 = setzero_i64(); + + m512 T, U, V, A, B, H; + T = U = V = A = B = H = setzero_i64(); + + const m512 M2 = loadu_i64(p384_x2); /* 2*p */ + const m512 M4 = loadu_i64(p384_x4); /* 4*p */ + const m512 M8 = loadu_i64(p384_x8); /* 8*p */ + + add(T, *y1, *y1); /* T = 2*y1 */ + lnorm(T, T); /**/ + /*=====*/ + sqr_dual(V, T, /* V = 4*y1^2 */ + U, *z1); /* U = z1^2 */ + /*=====*/ + sub(B, *x1, U); /* B = x1 - z1^2 */ + add(B, B, M2); /**/ + add(U, *x1, U); /* U = x1 + z1^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(V, V, /**/ + U, U); /**/ + norm(B, B); /**/ + /*=====*/ + mul_dual(A, V, *x1, /* A = 4*x1*y1^2 */ + B, B, U); /* B = (x1 - z1^2)*(x1 + z1^2) */ + /*=====*/ + add(x2, A, A); /* x2 = 8*x1*y1^2 (4p) */ + add(H, B, B); /**/ + add(B, B, H); /* B(l1) = 3*(x1 - z1^2)*(x1 + z1^2) */ + /*=====*/ + /* normalization */ + lnorm(B, B); /**/ + /*=====*/ + sqr_dual(U, B, /* U = l1^2 */ + y2, V); /* y2 = 16*y^2 */ + /*=====*/ + /* normalization */ + /*=====*/ + sub(x2, U, x2); /* x2 = l1^2 - 2*l2 */ + add(x2, x2, M4); /**/ + div2(y2, y2); /**/ + /*=====*/ + sub(U, A, x2); /* U = l2 - x2 */ + add(U, U, M8); /**/ + /*=====*/ + /* normalization */ + norm(U, U); /**/ + /*=====*/ + mul_dual(z2, T, *z1, /* z2 = 2*y1*z1 */ + U, U, B); /* U = B(l1)*(A(l2) - x2) */ + /*=====*/ + sub(y2, U, y2); /* y2 = B(l1)*(A(l2) - x2) - y2(l3) */ + add(y2, y2, M2); /**/ + /*=====*/ + /* normalization */ + norm_dual(r->x, x2, /**/ + r->y, y2); /**/ + lnorm(r->z, z2); /**/ + return; +} + +IPP_OWN_DEFN(void, ifma_ec_nistp384_add_point, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p, const P384_POINT_IFMA *q)) +{ + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * + * Gueron (2002). Enhanced Montgomery Multiplication. + * In Cryptographic Hardware and Embedded Systems - CHES 2002, + * 4th International Workshop, Redwood Shores, CA, USA, + * August 13-15, 2002, Revised Papers (pp. 46-56) + * [ DOI: 10.1007/3-540-36400-5_5 ] + * + * A = x1*z2^2 B = x2*z1^2 C = y1*z2^3 D = y2*z1^3 + * E = B - A F = D - C + * x3 = -E^3 - 2*A*E^2 + F^2 + * y3 = -C*E^3 + F*(A*E^2 - x3) + * z3 = z1*z2*E + */ + const m512 *x1 = &p->x; + const m512 *y1 = &p->y; + const m512 *z1 = &p->z; + const mask8 p_is_inf = is_zero_i64(p->z); + + const m512 *x2 = &q->x; + const m512 *y2 = &q->y; + const m512 *z2 = &q->z; + const mask8 q_is_inf = is_zero_i64(q->z); + + m512 x3; + m512 y3; + m512 z3; + x3 = y3 = z3 = setzero_i64(); + + const m512 M2 = loadu_i64(p384_x2); /* 2*p */ + const m512 M4 = loadu_i64(p384_x4); /* 4*p */ + const m512 M8 = loadu_i64(p384_x8); /* 8*p */ + + m512 U1, U2, S1, S2, H, R; + U1 = U2 = S1 = S2 = H = R = setzero_i64(); + + mul_dual(S1, *y1, *z2, /* s1 = y1*z2 */ + U1, *z2, *z2); /* u1 = z2^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(S1, S1, /**/ + U1, U1); /**/ + /*=====*/ + mul_dual(S2, *y2, *z1, /* s2 = y2*z1 */ + U2, *z1, *z1); /* u2 = z1^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(S2, S2, /**/ + U2, U2); /**/ + /*=====*/ + mul_dual(S1, S1, U1, /* s1 = y1*z2^3 (C) */ + S2, S2, U2); /* s2 = y2*z1^3 (D) */ + /*=====*/ + /* normalization */ + lnorm_dual(S1, S1, /**/ + S2, S2); /* (need by correct compute F = D - C) */ + /*=====*/ + mul_dual(U1, *x1, U1, /* u1 = x1*z2^2 (A) */ + U2, *x2, U2); /* u2 = x2*z1^2 (B) */ + /*=====*/ + /* normalization */ + lnorm_dual(U1, U1, /**/ + U2, U2); /**/ + /*=====*/ + sub(R, S2, S1); /* r = D - C (F) */ + sub(H, U2, U1); /* h = B - A (E) */ + + /* checking the equality of X and Y coordinates (D - C == 0) and (B - A == 0) */ + const mask8 f_are_zero = is_zero_i64(R); + const mask8 e_are_zero = is_zero_i64(H); + const mask8 point_is_equal = ((e_are_zero & f_are_zero) & (~p_is_inf) & (~q_is_inf)); + + __ALIGN64 P384_POINT_IFMA r2; + r2.x = r2.y = r2.z = setzero_i64(); + if ((mask8)0xFF == point_is_equal) { + ifma_ec_nistp384_dbl_point(&r2, p); + } + + add(R, R, M2); /**/ + add(H, H, M2); /**/ + /*=====*/ + /* normalization */ + norm_dual(R, R, /**/ + H, H); /**/ + /**/ + mul_dual(z3, *z1, *z2, /* z3 = z1*z2 */ + U2, H, H); /* u2 = E^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(z3, z3, /**/ + U2, U2); /**/ + /**/ + mul_dual(z3, z3, H, /* z3 = (z1*z2)*E */ + S2, R, R); /* s2 = F^2 */ + mul(H, H, U2); /* h = E^3 */ + /*=====*/ + /* normalization */ + lnorm(H, H); /**/ + /*=====*/ + mul(U1, U1, U2); /* u1 = A*E^2 */ + sub(x3, S2, H); /* x3 = F^2 - E^3 */ + add(x3, x3, M2); /**/ + add(U2, U1, U1); /* u2 = 2*A*E^2 */ + mul(S1, S1, H); /* s1 = C*E^3 */ + sub(x3, x3, U2); /* x3 = (F^2 - E^3) -2*A*E^2 */ + add(x3, x3, M4); /**/ + /*=====*/ + sub(y3, U1, x3); /* y3 = A*E^2 - x3 */ + add(y3, y3, M8); /**/ + /*=====*/ + /* normalization */ + norm(y3, y3); /**/ + /**/ + mul(y3, y3, R); /* y3 = F*(A*E^2 - x3) */ + sub(y3, y3, S1); /* y3 = F*(A*E^2 - x3) - C*E^3 */ + add(y3, y3, M2); + + /* normalization */ + norm_dual(x3, x3, /**/ + y3, y3); /**/ + lnorm(z3, z3); /**/ + + /* T = p_is_inf ? q : T */ + x3 = mask_mov_i64(x3, p_is_inf, *x2); + y3 = mask_mov_i64(y3, p_is_inf, *y2); + z3 = mask_mov_i64(z3, p_is_inf, *z2); + + /* T = q_is_inf ? p : T */ + x3 = mask_mov_i64(x3, q_is_inf, *x1); + y3 = mask_mov_i64(y3, q_is_inf, *y1); + z3 = mask_mov_i64(z3, q_is_inf, *z1); + + /* r = point_is_equal ? r2 : T */ + x3 = mask_mov_i64(x3, point_is_equal, r2.x); + y3 = mask_mov_i64(y3, point_is_equal, r2.y); + z3 = mask_mov_i64(z3, point_is_equal, r2.z); + + r->x = x3; + r->y = y3; + r->z = z3; + + return; +} + +IPP_OWN_DEFN(void, ifma_ec_nistp384_add_point_affine, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p, const P384_POINT_AFFINE_IFMA *q)) +{ + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * + * Gueron (2002). Enhanced Montgomery Multiplication. + * In Cryptographic Hardware and Embedded Systems - CHES 2002, + * 4th International Workshop, Redwood Shores, CA, USA, + * August 13-15, 2002, Revised Papers (pp. 46-56) + * [ DOI: 10.1007/3-540-36400-5_5 ] + * + * A = x1 B = x2*z1^2 C = y1 D = y2*z1^3 + * E = B - A(x1) F = D - C(y1) + * x3 = -E^3 - 2*A(x1)*E^2 + F^2 + * y3 = -C(y1)*E^3 + F*(A(x1)*E^2 - x3) + * z3 = z1*E + */ + /* coordinates of p (jacobian projective) */ + const m512 *x1 = &p->x; + const m512 *y1 = &p->y; + const m512 *z1 = &p->z; + const mask8 p_is_inf = is_zero_i64(p->z); + + /* coodinate of q (affine) */ + const m512 *x2 = &q->x; + const m512 *y2 = &q->y; + const mask8 q_is_inf = (is_zero_i64(q->x) & is_zero_i64(q->y)); + + const m512 M2 = loadu_i64(p384_x2); /* 2*p */ + const m512 M4 = loadu_i64(p384_x4); /* 4*p */ + const m512 M8 = loadu_i64(p384_x8); /* 8*p */ + + m512 x3, y3, z3; + x3 = y3 = z3 = setzero_i64(); + + m512 U2, S2, H, R; + U2 = S2 = H = R = setzero_i64(); + + mul_dual(R, *z1, *z1, /* R = z1^2 */ + S2, *y2, *z1); /* S2 = y2*z1 */ + /*=====*/ + lnorm_dual(R, R, /**/ + S2, S2); /**/ + /*=====*/ + mul_dual(U2, *x2, R, /* U2 = x2*z1^2 (B) */ + S2, S2, R); /* S2 = y2*z1^3 (D) */ + /**/ + sub(H, U2, *x1); /* H = B - A (E) */ + add(H, H, M8); /**/ + sub(R, S2, *y1); /* R = D - C (F) */ + add(R, R, M4); /**/ + /*=====*/ + norm_dual(H, H, /**/ + R, R); /**/ + /**/ + mul(z3, H, *z1); /* z3 = z1*E */ + /**/ + sqr_dual(U2, H, /* U2 = E^2 */ + S2, R); /* S2 = F^2 */ + /**/ + lnorm(U2, U2); /**/ + /**/ + mul(H, H, U2); /* H = E^3 */ + /**/ + lnorm(H, H); /**/ + /**/ + mul_dual(U2, U2, *x1, /* U2 = A*E^2 */ + y3, H, *y1); /* y3 = C*E^3 */ + /**/ + add(x3, U2, U2); /* x2 = 2*A*E^2 */ + sub(x3, S2, x3); /* x3 = F^2 - 2*A*E^2 */ + add(x3, x3, M4); /**/ + sub(x3, x3, H); /* x3 = F^2 - 2*A*E^2 - E^3 */ + add(x3, x3, M2); /**/ + /**/ + sub(U2, U2, x3); /* U2 = A*E^2 - x3 */ + add(U2, U2, M8); /**/ + norm(U2, U2); /**/ + mul(U2, U2, R); /* U2 = F*(A*E^2 - x3) */ + sub(y3, U2, y3); /* y3 = F*(A*E^2 - x3) - C*E^2 */ + add(y3, y3, M2); /**/ + + /* normalization */ + norm_dual(x3, x3, /**/ + y3, y3); /**/ + lnorm(z3, z3); /**/ + + /* T = p_is_inf ? q : T */ + x3 = mask_mov_i64(x3, p_is_inf, *x2); + y3 = mask_mov_i64(y3, p_is_inf, *y2); + z3 = mask_mov_i64(z3, p_is_inf, loadu_i64(p384_r)); + + /* T = q_is_inf ? p : T */ + x3 = mask_mov_i64(x3, q_is_inf, *x1); + y3 = mask_mov_i64(y3, q_is_inf, *y1); + z3 = mask_mov_i64(z3, q_is_inf, *z1); + + r->x = x3; + r->y = y3; + r->z = z3; + return; +} + +IPP_OWN_DEFN(int, ifma_ec_nistp384_is_on_curve, (const P384_POINT_IFMA *p, const int use_jproj_coords)) +{ + /* + * Algorithm + * + * Gueron (2002). Enhanced Montgomery Multiplication. + * In Cryptographic Hardware and Embedded Systems - CHES 2002, + * 4th International Workshop, Redwood Shores, CA, USA, + * August 13-15, 2002, Revised Papers (pp. 46-56) + * [ DOI: 10.1007/3-540-36400-5_5 ] + * + * y^2 = x^3 + a*x + b (1) + * + * if input + * * Jacobian projection coordinate (x,y,z) - represent by (x/z^2,y/z^3,1) + * * Affine coodinate (x/z^2,y/z^3,z/z=1) + * + * mult formala (1) by z^6 + * + * y^2 = x^3 + a*x*z^4 + b*z^6 + */ + const m512 M6 = loadu_i64(p384_x6); + const m512 a = loadu_i64(p384_a); + const m512 b = loadu_i64(p384_b); + + m512 rh, Z4, Z6, tmp; + rh = Z4 = Z6 = tmp = setzero_i64(); + + sqr(rh, p->x); /* rh = x^2 */ + /* rh = x*(x^2 + a*z^4) + b*z^6 = x*(x^2 - 3*z^4) + b*z^6 */ + if (0 != use_jproj_coords) { + sqr(tmp, p->z); /* tmp = z^2 */ + lnorm(tmp, tmp); /**/ + /**/ + sqr(Z4, tmp); /* z4 = z^4 */ + lnorm(Z4, Z4); /**/ + mul(Z6, Z4, tmp); /* z6 = z^6 */ + lnorm(Z6, Z6); /**/ + /**/ + add(tmp, Z4, Z4); /* tmp = 2*z^4 */ + add(tmp, tmp, Z4); /* tmp = 3*z^4 */ + /**/ + sub(rh, rh, tmp); /* rh = x^2 - 3*z^4 */ + add(rh, rh, M6); /**/ + norm(rh, rh); /**/ + /**/ + mul_dual(rh, rh, p->x, /* rh = x*(x^2 - 3*z^4) */ + tmp, Z6, b); /* tmp = b*z^6 */ + /**/ + add(rh, rh, tmp); /* rh = x*(x^2 - 3*z^4) + b*z^6 */ + } + /* rh = x*(x^2 + a) + b */ + else { + add(rh, rh, a); /* rh = x^2 + a */ + lnorm(rh, rh); /**/ + mul(rh, rh, p->x); /* rh = x*(x^2 + a) */ + add(rh, rh, b); /* rh = x*(x^2 + a) + b */ + } + lnorm(rh, rh); /**/ + + /* rl = Y^2 */ + sqr(tmp, p->y); /* tmp = y^2 */ + lnorm(tmp, tmp); /**/ + + /* from mont */ + from_mont(tmp, tmp); + from_mont(rh, rh); + + const mask8 mask = cmp_i64_mask(rh, tmp, _MM_CMPINT_EQ); + return (mask == 0xFF) ? 1 : 0; +} + +#undef add +#undef sub +#undef mul +#undef sqr +#undef div2 +#undef norm +#undef from_mont +#undef mul_dual +#undef sqr_dual +#undef norm_dual + +static __NOINLINE void clear_secret_context(Ipp16u *wval, + Ipp32s *chunk_no, Ipp32s *chunk_shift, + Ipp8u *sign, Ipp8u *digit, + P384_POINT_IFMA *R, P384_POINT_IFMA *H, + P384_POINT_AFFINE_IFMA *A) +{ + *wval = 0; + *chunk_no = 0; + *chunk_shift = 0; + *sign = 0; + *digit = 0; + + if (NULL != R) + (*R).x = (*R).y = (*R).z = setzero_i64(); + if (NULL != H) + (*H).x = (*H).y = (*H).z = setzero_i64(); + if (NULL != A) + (*A).x = (*A).y = setzero_i64(); +} + +#define WIN_SIZE (5) + +__INLINE mask8 is_eq_mask(const Ipp32s a, const Ipp32s b) +{ + const Ipp32s eq = a ^ b; + const Ipp32s v = ~eq & (eq - 1); + const Ipp32s msb = 0 - (v >> (sizeof(a) * 8 - 1)); + return (mask8)(0 - msb); +} + +__INLINE void extract_table_point(P384_POINT_IFMA *r, const Ipp32s digit, const P384_POINT_IFMA *tbl) +{ + Ipp32s idx = digit - 1; + + __ALIGN64 P384_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + + for (Ipp32s n = 0; n < (1 << (WIN_SIZE - 1)); ++n) { + const mask8 mask = is_eq_mask(n, idx); + + R.x = mask_mov_i64(R.x, mask, tbl[n].x); + R.y = mask_mov_i64(R.y, mask, tbl[n].y); + R.z = mask_mov_i64(R.z, mask, tbl[n].z); + } + + r->x = R.x; + r->y = R.y; + r->z = R.z; +} + +#define dbl_point ifma_ec_nistp384_dbl_point +#define add_point ifma_ec_nistp384_add_point +#define neg_coord ifma_neg52_p384 +#define add_point_affine ifma_ec_nistp384_add_point_affine + +/* r = n*P = (P + P + ... + P) */ +IPP_OWN_DEFN(void, ifma_ec_nistp384_mul_point, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p, const Ipp8u *pExtendedScalar, const int scalarBitSize)) +{ + /* default params */ + __ALIGN64 P384_POINT_IFMA tbl[(1 << (WIN_SIZE - 1))]; + + __ALIGN64 P384_POINT_IFMA R; + __ALIGN64 P384_POINT_IFMA H; + + R.x = R.y = R.z = setzero_i64(); + H.x = H.y = H.z = setzero_i64(); + m512 negHy = setzero_i64(); + + /* compute tbl[] = [n]P, n = 1, ... , 2^(win_size - 1) + * tbl[2*n] = tbl[2*n - 1] + p + * tbl[2*n + 1] = [2]*tbl[n] + */ + /* tbl[0] = p */ + tbl[0].x = p->x; + tbl[0].y = p->y; + tbl[0].z = p->z; + /* tbl[1] = [2]*p */ + dbl_point(/* r = */ (tbl + 1), /* a = */ p); + for (int n = 1; n < ((1 << (WIN_SIZE - 1)) / 2); ++n) { + add_point(/* r = */ (tbl + 2 * n), /* a = */ (tbl + 2 * n - 1), /* b = */ p); + dbl_point(/* r = */ (tbl + 2 * n + 1), /* a = */ (tbl + n)); + } + + Ipp16u wval; + Ipp8u digit, sign; + const Ipp32s mask = ((1 << (WIN_SIZE + 1)) - 1); /* mask 0b111111 */ + Ipp32s bit = scalarBitSize - (scalarBitSize % WIN_SIZE); + + Ipp32s chunk_no = (bit - 1) / 8; + Ipp32s chunk_shift = (bit - 1) % 8; + + if (0 != bit) { + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + } else { + wval = 0; + } + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, WIN_SIZE); + extract_table_point(/* r = */ &R, /* digit = */ (Ipp32s)digit, /* tbl = */ tbl); + + for (bit -= WIN_SIZE; bit >= WIN_SIZE; bit -= WIN_SIZE) { + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, WIN_SIZE); + extract_table_point(/* r = */ &H, /* idx = */ (Ipp32s)digit, /* tbl = */ tbl); + + negHy = neg_coord(H.y); + + const mask8 mask_neg = (mask8)(~(sign - 1)); + H.y = mask_mov_i64(H.y, mask_neg, negHy); + + add_point(/* r = */ &R, /* a = */ &R, /* b = */ &H); + } + + /* last window */ + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + + wval = *((Ipp16u *)(pExtendedScalar + 0)); + wval = (Ipp16u)((wval << 1) & mask); + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, WIN_SIZE); + extract_table_point(/* r = */ &H, /* idx = */ (Ipp32s)digit, /* tbl = */ tbl); + + negHy = neg_coord(H.y); + + const mask8 mask_neg = (mask8)(~(sign - 1)); + H.y = mask_mov_i64(H.y, mask_neg, negHy); + + add_point(/* r = */ &R, /* a = */ &R, /* b = */ &H); + + r->x = R.x; + r->y = R.y; + r->z = R.z; + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, &H, NULL); + + return; +} + +#include "ifma_ecprecomp4_p384.h" + +/* mul point base */ +#define BP_WIN_SIZE BASE_POINT_WIN_SIZE +#define BP_N_ENTRY BASE_POINT_N_ENTRY + +__INLINE void extract_point_affine(P384_POINT_AFFINE_IFMA *r, + const P384_POINT_AFFINE_IFMA_MEM *tbl, + const Ipp32s digit) +{ + Ipp32s idx = digit - 1; + + m512 x, y; + x = y = setzero_i64(); + + for (Ipp32s n = 0; n < (1 << ((BP_WIN_SIZE)-1)); ++n, ++tbl) { + const mask8 mask = is_eq_mask(n, idx); + + x = mask_mov_i64(x, mask, loadu_i64(tbl->X)); + y = mask_mov_i64(y, mask, loadu_i64(tbl->Y)); + } + + r->x = x; + r->y = y; +} + +IPP_OWN_DEFN(void, p384r1_select_ap_w4_ifma, (BNU_CHUNK_T * pAffinePoint, const BNU_CHUNK_T *pTable, int index)) +{ + __ALIGN64 P384_POINT_AFFINE_IFMA ap; + + extract_point_affine(&ap, (P384_POINT_AFFINE_IFMA_MEM *)pTable, index); + + ap.x = ifma_frommont52_p384(ap.x); + ap.y = ifma_frommont52_p384(ap.y); + + convert_radix_to_64x6(pAffinePoint, ap.x); + convert_radix_to_64x6(pAffinePoint + LEN64, ap.y); +} + +IPP_OWN_DEFN(void, ifma_ec_nistp384_mul_pointbase, (P384_POINT_IFMA * r, const Ipp8u *pExtendedScalar, int scalarBitSize)) +{ + /* precompute table */ + const P384_POINT_AFFINE_IFMA_MEM *tbl = &ifma_ec_nistp384r1_bp_precomp[0][0]; + + __ALIGN64 P384_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + __ALIGN64 P384_POINT_AFFINE_IFMA A; + A.x = A.y = setzero_i64(); + + m512 Ty = setzero_i64(); + + Ipp16u wval; + Ipp8u digit, sign; + const Ipp32s mask = ((1 << (BP_WIN_SIZE + 1)) - 1); /* mask 0b11111 */ + Ipp32s bit = 0; + Ipp32s chunk_no, chunk_shift; + + wval = *((Ipp16u *)(pExtendedScalar + 0)); + wval = (Ipp16u)((wval << 1) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + Ty = neg_coord(A.y); + mask8 mask_neg = (mask8)(~(sign - 1)); + A.y = mask_mov_i64(A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + + for (bit += BP_WIN_SIZE; bit <= scalarBitSize; bit += BP_WIN_SIZE) { + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + Ty = neg_coord(A.y); + mask_neg = (mask8)(~(sign - 1)); + A.y = mask_mov_i64(A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + } + + r->x = R.x; + r->y = R.y; + r->z = R.z; + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, NULL, &A); + return; +} + +#undef dbl_point +#undef add_point +#undef neg_coord +#undef add_point_affine + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p384.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p384.h new file mode 100644 index 000000000..9dc8b0c60 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p384.h @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +/* Paper referenced in this header: + * + * [1] "Enhanced Montgomery Multiplication" DOI:10.1155/2008/583926 + * + */ + +#ifndef IFMA_ECPOINT_P384_H +#define IFMA_ECPOINT_P384_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_p384.h" +#include "pcpbnuimpl.h" + +/* p384 point (x,y,z) */ +typedef struct { + m512 x; + m512 y; + m512 z; +} P384_POINT_IFMA; + +/* p384 affine point(x,y) */ +typedef struct { + m512 x; + m512 y; +} P384_POINT_AFFINE_IFMA; + +/** + * \brief + * + * R = [pExtendedScalar]*P = (P + P + ... + P) + * + * \param[out] r point in radix 2^52 + * \param[in] p point in radix 2^52 + * \param[in] pExtendedScalar pointer to a scalar + * \param[in] scalarBitSize scalar size in bits + */ +IPP_OWN_DECL(void, ifma_ec_nistp384_mul_point, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p, const Ipp8u *pExtendedScalar, const int scalarBitSize)) + +/** + * \brief + * + * R = [pExtendedScalar]*BasePoint + * + * \param[out] r point in radix 2^52 + * \param[in] pExtendedScalar pointer to a scalar + * \param[in] scalarBitSize scalar size in bits + */ +IPP_OWN_DECL(void, ifma_ec_nistp384_mul_pointbase, (P384_POINT_IFMA * r, const Ipp8u *pExtendedScalar, int scalarBitSize)) + +/** + * \brief + * + * Convert point to affine coordinate + * + * \param[out] rx X-affine coordinate + * \param[out] ry Y-affine coordinate + * \param[in] a point in projective coordinates + */ +IPP_OWN_DECL(void, ifma_ec_nistp384_get_affine_coords, (m512 * rx, m512 *ry, const P384_POINT_IFMA *a)) + +/** + * \brief + * + * Check if the point is on curve p384r1 + * + * \param[in] p point in radix 2^52 + * \param[in] use_jproj_coords flag whether coordinates are in Projective of Affine representation + * \return int 1 - true + * 0 - false + */ +IPP_OWN_DECL(int, ifma_ec_nistp384_is_on_curve, (const P384_POINT_IFMA *p, const int use_jproj_coords)) + +/** + * \brief + * + * Point doubling on p384r1 curve (Enhanced Montgomery Algorithm, see [1]) + * + * \param[out] r point in projective coordinates + * \param[in] p point in projective coordinates + */ +IPP_OWN_DECL(void, ifma_ec_nistp384_dbl_point, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p)) + +/** + * \brief + * + * Point addition on p384r1 curve (Enhanced Montgomery Algorithm, see [1]) + * + * \param[out] r result point + * \param[in] p first point + * \param[in] q second point + */ +IPP_OWN_DECL(void, ifma_ec_nistp384_add_point, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p, const P384_POINT_IFMA *q)) + +/** + * \brief + * + * Point addition on p384r1 curve (Enhanced Montgomery Algorithm, see [1]) + * + * \param[out] r point in projective coordinates + * \param[in] p point in projective coordinates + * \param[in] q point in affine coordinates + */ +IPP_OWN_DECL(void, ifma_ec_nistp384_add_point_affine, (P384_POINT_IFMA * r, const P384_POINT_IFMA *p, const P384_POINT_AFFINE_IFMA *q)) + +/** + * \brief + * + * Extracts affine point from the precomputed table. + * + * \param[out] pAffinePoint array of x and y coordinates of affine point in 2^64 radix + * \param[in] pTable pointer to a precomputed table + * \param[in] index index of desired point in the table + */ +IPP_OWN_DECL(void, p384r1_select_ap_w4_ifma, (BNU_CHUNK_T * pAffinePoint, const BNU_CHUNK_T *pTable, int index)) + + +#include "ifma_arith_method.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +__INLINE void recode_point_to_mont52(P384_POINT_IFMA *pR, + const BNU_CHUNK_T *pP, + BNU_CHUNK_T *pPool, + ifmaArithMethod *method, + gsModEngine *pME) +{ + ifma_import to_radix52 = method->import_to52; + ifma_encode p_to_mont = method->encode; + + const int elemLen = GFP_FELEN(pME); + + BNU_CHUNK_T *pX = pPool; + BNU_CHUNK_T *pY = pPool + elemLen; + BNU_CHUNK_T *pZ = pPool + 2 * elemLen; + + GFP_METHOD(pME)->decode(pX, pP, pME); + GFP_METHOD(pME)->decode(pY, pP + elemLen, pME); + GFP_METHOD(pME)->decode(pZ, pP + 2 * elemLen, pME); + + pR->x = to_radix52((Ipp64u *)pX); + pR->y = to_radix52((Ipp64u *)pY); + pR->z = to_radix52((Ipp64u *)pZ); + + pR->x = p_to_mont(pR->x); + pR->y = p_to_mont(pR->y); + pR->z = p_to_mont(pR->z); +} + +__INLINE void recode_point_to_mont64(const IppsGFpECPoint *pR, + P384_POINT_IFMA *pP, + BNU_CHUNK_T *pPool, + ifmaArithMethod *method, + gsModEngine *pME) +{ + ifma_export to_radix64 = method->export_to64; + ifma_decode p_from_mont = method->decode; + + const int elemLen = GFP_PELEN(pME); + BNU_CHUNK_T *pX = pPool; + BNU_CHUNK_T *pY = pPool + elemLen; + BNU_CHUNK_T *pZ = pPool + 2 * elemLen; + + pP->x = p_from_mont(pP->x); + pP->y = p_from_mont(pP->y); + pP->z = p_from_mont(pP->z); + + to_radix64((Ipp64u *)pX, pP->x); + to_radix64((Ipp64u *)pY, pP->y); + to_radix64((Ipp64u *)pZ, pP->z); + + GFP_METHOD(pME)->encode(ECP_POINT_X(pR), pX, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Y(pR), pY, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Z(pR), pZ, pME); +} + + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // IFMA_ECPOINT_P384_H diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p521.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p521.c new file mode 100644 index 000000000..473c8ad09 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p521.c @@ -0,0 +1,764 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_arith_p521.h" +#include "ifma_ecpoint_p521.h" +#include "pcpgfpecstuff.h" + +#define add(R, A, B) fe521_add_no_red((R), (A), (B)) +#define sub(R, A, B) fe521_sub_no_red((R), (A), (B)) +#define mul(R, A, B) ifma_amm52_p521(&(R), (A), (B)) +#define sqr(R, A) ifma_ams52_p521(&(R), (A)) +#define div2(R, A) ifma_half52_p521(&(R), (A)) +#define norm(R, A) ifma_norm52_p521(&(R), (A)) +#define lnorm(R, A) ifma_lnorm52_p521(&(R), (A)) +#define inv(R, A) ifma_aminv52_p521(&(R), (A)) +#define from_mont(R, A) ifma_frommont52_p521(&(R), (A)) +/* duplicate mult/sqr/norm */ +#define mul_dual(R1, A1, B1, R2, A2, B2) ifma_amm52_dual_p521(&(R1), (A1), (B1), &(R2), (A2), (B2)) +#define sqr_dual(R1, A1, R2, A2) ifma_ams52_dual_p521(&(R1), (A1), &(R2), (A2)) +#define norm_dual(R1, A1, R2, A2) ifma_norm52_dual_p521(&(R1), (A1), &(R2), (A2)) +#define lnorm_dual(R1, A1, R2, A2) ifma_lnorm52_dual_p521(&(R1), (A1), &(R2), (A2)) + +IPP_OWN_DEFN(void, ifma_ec_nistp521_get_affine_coords, (fe521 prx[], fe521 pry[], const P521_POINT_IFMA *a)) +{ + + fe521 z1, z2, z3; + FE521_SET(z1) = FE521_SET(z2) = FE521_SET(z3) = m256_setzero_i64(); + inv(z1, a->z); /* 1/z */ + sqr(z2, z1); /* (1/z)^2 */ + lnorm(z2, z2); /**/ + + /* x = x/z^2 */ + if (NULL != prx) { + mul(*prx, a->x, z2); /* x = x/z^2 */ + lnorm(*prx, *prx); /**/ + } + /* y = y/z^3 */ + if (NULL != pry) { + mul(z3, z1, z2); /* (1/z)^3 */ + lnorm(z3, z3); /**/ + mul(*pry, a->y, z3); /* y = y/z^3 */ + lnorm(*pry, *pry); /**/ + } + + return; +} + +IPP_OWN_DEFN(void, ifma_ec_nistp521_dbl_point, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p)) +{ + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * l1 = 3x^2 + a*z^4 = (if p384 a = -3) = 3*(x^2 - z^4) = 3*(x - z^2)*(x + z^2) + * z2 = 2*y*z + * l2 = 4*x*y^2 + * x2 = l1^2 - 2*l2 + * l3 = 8*y^4 + * y2 = l1*(l2 - x2) - l3 + * + * sum aripmetic: 8 mul; 9 add/sub; 1 div2. + */ + const fe521 *x1 = &p->x; + const fe521 *y1 = &p->y; + const fe521 *z1 = &p->z; + + fe521 x2; + fe521 y2; + fe521 z2; + FE521_SET(x2) = FE521_SET(y2) = FE521_SET(z2) = m256_setzero_i64(); + + fe521 T, U, V, A, B, H; + FE521_SET(T) = FE521_SET(U) = FE521_SET(V) = m256_setzero_i64(); + FE521_SET(A) = FE521_SET(B) = FE521_SET(H) = m256_setzero_i64(); + + fe521 M2, M4, M8; + FE521_LOADU(M2, p521_x2); /* 2*p */ + FE521_LOADU(M4, p521_x4); /* 4*p */ + FE521_LOADU(M8, p521_x8); /* 8*p */ + + add(T, *y1, *y1); /* T = 2*y1 */ + lnorm(T, T); /**/ + /*=====*/ + sqr_dual(V, T, /* V = 4*y1^2 */ + U, *z1); /* U = z1^2 */ + /*=====*/ + sub(B, *x1, U); /* B = 2*p + x1 - z1^2 */ + add(B, B, M2); /**/ + add(U, *x1, U); /* U = x1 + z1^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(V, V, /**/ + U, U); /**/ + norm(B, B); /**/ + /*=====*/ + mul_dual(A, V, *x1, /* A = 4*x1*y1^2 */ + B, B, U); /* B = (x1 - z1^2)*(x1 + z1^2) */ + /*=====*/ + add(x2, A, A); /* x2 = 8*x1*y1^2 (4p) */ + add(H, B, B); /**/ + add(B, B, H); /* B(l1) = 3*(x1 - z1^2)*(x1 + z1^2) */ + /*=====*/ + /* normalization */ + lnorm(B, B); /**/ + /*=====*/ + sqr_dual(U, B, /* U = l1^2 */ + y2, V); /* y2 = 16*y^2 */ + /*=====*/ + sub(x2, U, x2); /* x2 = 4*p + l1^2 - 2*l2 */ + add(x2, x2, M4); /**/ + div2(y2, y2); /**/ + /*=====*/ + sub(U, A, x2); /* U = 8*p + l2 - x2 */ + add(U, U, M8); /**/ + /*=====*/ + /* normalization */ + norm(U, U); /**/ + /*=====*/ + mul_dual(z2, T, *z1, /* z2 = 2*y1*z1 */ + U, U, B); /* U = B(l1)*(A(l2) - x2) */ + /*=====*/ + sub(y2, U, y2); /* y2 = 2*p + B(l1)*(A(l2) - x2) - y2(l3) */ + add(y2, y2, M2); /**/ + /*=====*/ + /* normalization */ + norm_dual(r->x, x2, /**/ + r->y, y2); /**/ + lnorm(r->z, z2); /**/ + return; +} + +IPP_OWN_DEFN(void, ifma_ec_nistp521_add_point, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p, const P521_POINT_IFMA *q)) +{ + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * + * A = x1*z2^2 B = x2*z1^2 C = y1*z2^3 D = y2*z1^3 + * E = B - A F = D - C + * x3 = -E^3 - 2*A*E^2 + F^2 + * y3 = -C*E^3 + F*(A*E^2 - x3) + * z3 = z1*z2*E + */ + const fe521 *x1 = &p->x; + const fe521 *y1 = &p->y; + const fe521 *z1 = &p->z; + const mask8 p_is_inf = FE521_IS_ZERO(p->z); + + const fe521 *x2 = &q->x; + const fe521 *y2 = &q->y; + const fe521 *z2 = &q->z; + const mask8 q_is_inf = FE521_IS_ZERO(q->z); + + fe521 x3; + fe521 y3; + fe521 z3; + FE521_SET(x3) = FE521_SET(y3) = FE521_SET(z3) = m256_setzero_i64(); + + fe521 M2, M4, M8; + FE521_LOADU(M2, p521_x2); /* 2*p */ + FE521_LOADU(M4, p521_x4); /* 4*p */ + FE521_LOADU(M8, p521_x8); /* 8*p */ + + fe521 U1, U2, S1, S2, H, R; + FE521_SET(U1) = FE521_SET(U2) = FE521_SET(S1) = m256_setzero_i64(); + FE521_SET(S2) = FE521_SET(H) = FE521_SET(R) = m256_setzero_i64(); + + mul_dual(S1, *y1, *z2, /* s1 = y1*z2 */ + U1, *z2, *z2); /* u1 = z2^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(S1, S1, /**/ + U1, U1); /**/ + /*=====*/ + mul_dual(S2, *y2, *z1, /* s2 = y2*z1 */ + U2, *z1, *z1); /* u2 = z1^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(S2, S2, /**/ + U2, U2); /**/ + /*=====*/ + mul_dual(S1, S1, U1, /* s1 = y1*z2^3 (C) */ + S2, S2, U2); /* s2 = y2*z1^3 (D) */ + /*=====*/ + /* normalization */ + lnorm_dual(S1, S1, /**/ + S2, S2); /* (need by correct compute F = D - C) */ + /*=====*/ + mul_dual(U1, *x1, U1, /* u1 = x1*z2^2 (A) */ + U2, *x2, U2); /* u2 = x2*z1^2 (B) */ + /*=====*/ + /* normalization */ + lnorm_dual(U1, U1, /**/ + U2, U2); /**/ + /*=====*/ + sub(R, S2, S1); /* r = D - C (F) */ + sub(H, U2, U1); /* h = B - A (E) */ + + /* checking the equality of X and Y coordinates (D - C == 0) and (B - A == 0) */ + const mask8 f_are_zero = FE521_IS_ZERO(R); + const mask8 e_are_zero = FE521_IS_ZERO(H); + const mask8 point_is_equal = ((e_are_zero & f_are_zero) & (~p_is_inf) & (~q_is_inf)); + + __ALIGN64 P521_POINT_IFMA r2; + FE521_SET(r2.x) = FE521_SET(r2.y) = FE521_SET(r2.z) = m256_setzero_i64(); + if ((mask8)0xFF == point_is_equal) { + ifma_ec_nistp521_dbl_point(&r2, p); + } + + add(R, R, M2); /**/ + add(H, H, M2); /**/ + /*=====*/ + /* normalization */ + norm_dual(R, R, /**/ + H, H); /**/ + /**/ + mul_dual(z3, *z1, *z2, /* z3 = z1*z2 */ + U2, H, H); /* u2 = E^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(z3, z3, /**/ + U2, U2); /**/ + /**/ + mul_dual(z3, z3, H, /* z3 = (z1*z2)*E */ + S2, R, R); /* s2 = F^2 */ + mul(H, H, U2); /* h = E^3 */ + /*=====*/ + /* normalization */ + lnorm(H, H); /**/ + /*=====*/ + mul(U1, U1, U2); /* u1 = A*E^2 */ + sub(x3, S2, H); /* x3 = F^2 - E^3 */ + add(x3, x3, M2); /**/ + add(U2, U1, U1); /* u2 = 2*A*E^2 */ + mul(S1, S1, H); /* s1 = C*E^3 */ + sub(x3, x3, U2); /* x3 = (F^2 - E^3) -2*A*E^2 */ + add(x3, x3, M4); /**/ + /*=====*/ + sub(y3, U1, x3); /* y3 = A*E^2 - x3 */ + add(y3, y3, M8); /**/ + /*=====*/ + /* normalization */ + norm(y3, y3); /**/ + /**/ + mul(y3, y3, R); /* y3 = F*(A*E^2 - x3) */ + sub(y3, y3, S1); /* y3 = F*(A*E^2 - x3) - C*E^3 */ + add(y3, y3, M2); + + /* normalization */ + norm_dual(x3, x3, /**/ + y3, y3); /**/ + lnorm(z3, z3); /**/ + + /* T = p_is_inf ? q : T */ + FE521_MASK_MOV(x3, x3, p_is_inf, *x2); + FE521_MASK_MOV(y3, y3, p_is_inf, *y2); + FE521_MASK_MOV(z3, z3, p_is_inf, *z2); + + /* T = q_is_inf ? p : T */ + FE521_MASK_MOV(x3, x3, q_is_inf, *x1); + FE521_MASK_MOV(y3, y3, q_is_inf, *y1); + FE521_MASK_MOV(z3, z3, q_is_inf, *z1); + + /* r = point_is_equal ? r2 : T */ + FE521_MASK_MOV(x3, x3, point_is_equal, r2.x); + FE521_MASK_MOV(y3, y3, point_is_equal, r2.y); + FE521_MASK_MOV(z3, z3, point_is_equal, r2.z); + + FE521_COPY(r->x, x3); + FE521_COPY(r->y, y3); + FE521_COPY(r->z, z3); + + return; +} + +IPP_OWN_DEFN(void, ifma_ec_nistp521_add_point_affine, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p, const P521_POINT_AFFINE_IFMA *q)) +{ + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * + * A = x1 B = x2*z1^2 C = y1 D = y2*z1^3 + * E = B - A(x1) F = D - C(y1) + * x3 = -E^3 - 2*A(x1)*E^2 + F^2 + * y3 = -C(y1)*E^3 + F*(A(x1)*E^2 - x3) + * z3 = z1*E + */ + /* coordinates of p (jacobian projective) */ + const fe521 *x1 = &p->x; + const fe521 *y1 = &p->y; + const fe521 *z1 = &p->z; + const mask8 p_is_inf = FE521_IS_ZERO(p->z); + + /* coodinate of q (affine) */ + const fe521 *x2 = &q->x; + const fe521 *y2 = &q->y; + const mask8 q_is_inf = (FE521_IS_ZERO(q->x) & FE521_IS_ZERO(q->y)); + + fe521 x3; + fe521 y3; + fe521 z3; + FE521_SET(x3) = FE521_SET(y3) = FE521_SET(z3) = m256_setzero_i64(); + + fe521 M2, M4, M8; + FE521_LOADU(M2, p521_x2); /* 2*p */ + FE521_LOADU(M4, p521_x4); /* 4*p */ + FE521_LOADU(M8, p521_x8); /* 8*p */ + + fe521 U2, S2, H, R; + FE521_SET(U2) = FE521_SET(S2) = FE521_SET(H) = FE521_SET(R) = m256_setzero_i64(); + + mul_dual(R, *z1, *z1, /* R = z1^2 */ + S2, *y2, *z1); /* S2 = y2*z1 */ + /*=====*/ + lnorm_dual(R, R, /**/ + S2, S2); /**/ + /*=====*/ + mul_dual(U2, *x2, R, /* U2 = x2*z1^2 (B) */ + S2, S2, R); /* S2 = y2*z1^3 (D) */ + /**/ + sub(H, U2, *x1); /* H = B - A (E) */ + add(H, H, M8); /**/ + sub(R, S2, *y1); /* R = D - C (F) */ + add(R, R, M4); /**/ + /*=====*/ + norm_dual(H, H, /**/ + R, R); /**/ + /**/ + mul(z3, H, *z1); /* z3 = z1*E */ + /**/ + sqr_dual(U2, H, /* U2 = E^2 */ + S2, R); /* S2 = F^2 */ + /**/ + lnorm(U2, U2); /**/ + /**/ + mul(H, H, U2); /* H = E^3 */ + /**/ + lnorm(H, H); /**/ + /**/ + mul_dual(U2, U2, *x1, /* U2 = A*E^2 */ + y3, H, *y1); /* y3 = C*E^3 */ + /**/ + add(x3, U2, U2); /* x2 = 2*A*E^2 */ + sub(x3, S2, x3); /* x3 = F^2 - 2*A*E^2 */ + add(x3, x3, M4); /**/ + sub(x3, x3, H); /* x3 = F^2 - 2*A*E^2 - E^3 */ + add(x3, x3, M2); /**/ + /**/ + sub(U2, U2, x3); /* U2 = A*E^2 - x3 */ + add(U2, U2, M8); /**/ + norm(U2, U2); /**/ + mul(U2, U2, R); /* U2 = F*(A*E^2 - x3) */ + sub(y3, U2, y3); /* y3 = F*(A*E^2 - x3) - C*E^2 */ + add(y3, y3, M2); /**/ + + /* normalization */ + norm_dual(x3, x3, /**/ + y3, y3); /**/ + lnorm(z3, z3); /**/ + + fe521 ONE; + FE521_LOADU(ONE, P521R1_R52); + /* T = p_is_inf ? q : T */ + FE521_MASK_MOV(x3, x3, p_is_inf, *x2); + FE521_MASK_MOV(y3, y3, p_is_inf, *y2); + FE521_MASK_MOV(z3, z3, p_is_inf, ONE); + + /* T = q_is_inf ? p : T */ + FE521_MASK_MOV(x3, x3, q_is_inf, *x1); + FE521_MASK_MOV(y3, y3, q_is_inf, *y1); + FE521_MASK_MOV(z3, z3, q_is_inf, *z1); + + FE521_COPY(r->x, x3); + FE521_COPY(r->y, y3); + FE521_COPY(r->z, z3); + + return; +} + +/* P521 mont(a) */ +const static __ALIGN64 Ipp64u p512_a[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { { 0x0007FFFFFFFFFFFF, + 0x000FFFFFFFFFFFFE, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF }, + { 0x000FFFFFFFFFFFFF, + 0x000FFFFFFFFFFFFF, + 0x0000000000000001, + 0x0000000000000000 } }; +/* P521R1 mont(b) */ +const static __ALIGN64 Ipp64u p512_b[P521R1_NUM_CHUNK][P521R1_LENFE521_52] = { { 0x00014654FAE58638, + 0x00028FEA35A81F80, + 0x000C41E961A78F7A, + 0x000DD8DF839AB9EF }, + { 0x00049BD8B29605E9, + 0x0000AB0C9CA8F63F, + 0x0005A44C8C77884F, + 0x00092DCCD98AF9DC }, + { 0x0005B42A077516D3, + 0x000E4D0FC94D10D0, + 0x0000000000000000, + 0x0000000000000000 } }; + +IPP_OWN_DEFN(int, ifma_ec_nistp521_is_on_curve, (const P521_POINT_IFMA *p, const int use_jproj_coords)) +{ + /* + * Algorithm + * + * y^2 = x^3 + a*x + b (1) + * + * if input + * * Jacobian projection coordinate (x,y,z) - represent by (x/z^2,y/z^3,1) + * * Affine coodinate (x/z^2,y/z^3,z/z=1) + * + * mult formala (1) by z^6 + * + * y^2 = x^3 + a*x*z^4 + b*z^6 + */ + fe521 M6; + FE521_LOADU(M6, p521_x6); + fe521 a, b; + FE521_LOADU(a, p512_a); + FE521_LOADU(b, p512_b); + + fe521 rh, Z4, Z6, tmp; + FE521_SET(rh) = FE521_SET(Z4) = FE521_SET(Z6) = FE521_SET(tmp) = m256_setzero_i64(); + + sqr(rh, p->x); /* rh = x^2 */ + /* rh = x*(x^2 + a*z^4) + b*z^6 = x*(x^2 - 3*z^4) + b*z^6 */ + if (0 != use_jproj_coords) { + sqr(tmp, p->z); /* tmp = z^2 */ + lnorm(tmp, tmp); /**/ + /**/ + sqr(Z4, tmp); /* z4 = z^4 */ + lnorm(Z4, Z4); /**/ + mul(Z6, Z4, tmp); /* z6 = z^6 */ + lnorm(Z6, Z6); /**/ + /**/ + add(tmp, Z4, Z4); /* tmp = 2*z^4 */ + add(tmp, tmp, Z4); /* tmp = 3*z^4 */ + /**/ + sub(rh, rh, tmp); /* rh = x^2 - 3*z^4 */ + add(rh, rh, M6); /**/ + norm(rh, rh); /**/ + /**/ + mul_dual(rh, rh, p->x, /* rh = x*(x^2 - 3*z^4) */ + tmp, Z6, b); /* tmp = b*z^6 */ + /**/ + add(rh, rh, tmp); /* rh = x*(x^2 - 3*z^4) + b*z^6 */ + } + /* rh = x*(x^2 + a) + b */ + else { + add(rh, rh, a); /* rh = x^2 + a */ + lnorm(rh, rh); /**/ + mul(rh, rh, p->x); /* rh = x*(x^2 + a) */ + add(rh, rh, b); /* rh = x*(x^2 + a) + b */ + } + lnorm(rh, rh); /**/ + + /* rl = Y^2 */ + sqr(tmp, p->y); /* tmp = y^2 */ + lnorm(tmp, tmp); /**/ + + /* from mont */ + from_mont(tmp, tmp); + from_mont(rh, rh); + + const mask8 mask = FE521_CMP_MASK(rh, tmp, _MM_CMPINT_EQ); + return (mask == 0xF) ? 1 : 0; +} + +#undef add +#undef sub +#undef mul +#undef sqr +#undef div2 +#undef norm +#undef from_mont +#undef mul_dual +#undef sqr_dual +#undef norm_dual + +static __NOINLINE void clear_secret_context(Ipp16u *wval, + Ipp32s *chunk_no, Ipp32s *chunk_shift, + Ipp8u *sign, Ipp8u *digit, + P521_POINT_IFMA *R, P521_POINT_IFMA *H, + P521_POINT_AFFINE_IFMA *A) +{ + *wval = 0; + *chunk_no = 0; + *chunk_shift = 0; + *sign = 0; + *digit = 0; + + if (NULL != R) + FE521_SET((*R).x) = FE521_SET((*R).y) = FE521_SET((*R).z) = m256_setzero_i64(); + if (NULL != H) + FE521_SET((*H).x) = FE521_SET((*H).y) = FE521_SET((*H).z) = m256_setzero_i64(); + if (NULL != A) + FE521_SET((*A).x) = FE521_SET((*A).y) = m256_setzero_i64(); + return; +} + +#define WIN_SIZE (5) + +__INLINE mask8 is_eq_mask(const Ipp32s a, const Ipp32s b) +{ + const Ipp32s eq = a ^ b; + const Ipp32s v = ~eq & (eq - 1); + const Ipp32s msb = 0 - (v >> (sizeof(a) * 8 - 1)); + return (mask8)(0 - msb); +} + +__INLINE void extract_table_point(P521_POINT_IFMA *r, const Ipp32s digit, const P521_POINT_IFMA tbl[]) +{ + Ipp32s idx = digit - 1; + + __ALIGN64 P521_POINT_IFMA R; + FE521_SET(R.x) = FE521_SET(R.y) = FE521_SET(R.z) = m256_setzero_i64(); + + for (Ipp32s n = 0; n < (1 << (WIN_SIZE - 1)); ++n) { + const mask8 mask = is_eq_mask(n, idx); + + FE521_MASK_MOV(R.x, R.x, mask, tbl[n].x); + FE521_MASK_MOV(R.y, R.y, mask, tbl[n].y); + FE521_MASK_MOV(R.z, R.z, mask, tbl[n].z); + } + + FE521_COPY(r->x, R.x); + FE521_COPY(r->y, R.y); + FE521_COPY(r->z, R.z); +} + +#define dbl_point ifma_ec_nistp521_dbl_point +#define add_point ifma_ec_nistp521_add_point +#define neg_coord(R, A) ifma_neg52_p521(&(R), (A)) +#define add_point_affine ifma_ec_nistp521_add_point_affine + +/* r = n*P = (P + P + ... + P) */ +IPP_OWN_DEFN(void, ifma_ec_nistp521_mul_point, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p, const Ipp8u *pExtendedScalar, const int scalarBitSize)) +{ + /* default params */ + __ALIGN64 P521_POINT_IFMA tbl[(1 << (WIN_SIZE - 1))]; + + __ALIGN64 P521_POINT_IFMA R; + __ALIGN64 P521_POINT_IFMA H; + + fe521 negHy; + FE521_SET(negHy) = m256_setzero_i64(); + FE521_SET(R.x) = FE521_SET(R.y) = FE521_SET(R.z) = m256_setzero_i64(); + FE521_SET(H.x) = FE521_SET(H.y) = FE521_SET(H.z) = m256_setzero_i64(); + + /* compute tbl[] = [n]P, n = 1, ... , 2^(win_size - 1) + * tbl[2*n] = tbl[2*n - 1] + p + * tbl[2*n + 1] = [2]*tbl[n] + */ + /* tbl[0] = p */ + FE521_COPY(tbl[0].x, p->x); + FE521_COPY(tbl[0].y, p->y); + FE521_COPY(tbl[0].z, p->z); + /* tbl[1] = [2]*p */ + dbl_point(/* r = */ (tbl + 1), /* a = */ p); + for (int n = 1; n < ((1 << (WIN_SIZE - 1)) / 2); ++n) { + add_point(/* r = */ (tbl + 2 * n), /* a = */ (tbl + 2 * n - 1), /* b = */ p); + dbl_point(/* r = */ (tbl + 2 * n + 1), /* a = */ (tbl + n)); + } + + Ipp16u wval; + Ipp8u digit, sign; + const Ipp32s mask = ((1 << (WIN_SIZE + 1)) - 1); /* mask 0b111111 */ + Ipp32s bit = scalarBitSize - (scalarBitSize % WIN_SIZE); + + Ipp32s chunk_no = (bit - 1) / 8; + Ipp32s chunk_shift = (bit - 1) % 8; + + if (0 != bit) { + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + } else { + wval = 0; + } + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, WIN_SIZE); + extract_table_point(/* r = */ &R, /* digit = */ (Ipp32s)digit, /* tbl = */ tbl); + + for (bit -= WIN_SIZE; bit >= WIN_SIZE; bit -= WIN_SIZE) { + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, WIN_SIZE); + extract_table_point(/* r = */ &H, /* idx = */ (Ipp32s)digit, /* tbl = */ tbl); + + neg_coord(negHy, H.y); + + const mask8 mask_neg = (mask8)(~(sign - 1)); + FE521_MASK_MOV(H.y, H.y, mask_neg, negHy); + add_point(/* r = */ &R, /* a = */ &R, /* b = */ &H); + } + + /* last window */ + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + + wval = *((Ipp16u *)(pExtendedScalar + 0)); + wval = (wval << 1) & mask; + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, WIN_SIZE); + extract_table_point(/* r = */ &H, /* idx = */ (Ipp32s)digit, /* tbl = */ tbl); + + neg_coord(negHy, H.y); + + const mask8 mask_neg = (mask8)(~(sign - 1)); + FE521_MASK_MOV(H.y, H.y, mask_neg, negHy); + + add_point(/* r = */ &R, /* a = */ &R, /* b = */ &H); + + FE521_COPY(r->x, R.x); + FE521_COPY(r->y, R.y); + FE521_COPY(r->z, R.z); + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, &H, NULL); + + return; +} + +#include "ifma_ecprecomp4_p521.h" + +/* affine */ +#define BP_WIN_SIZE BASE_POINT_WIN_SIZE +#define BP_N_ENTRY BASE_POINT_N_ENTRY + +__INLINE void extract_point_affine(P521_POINT_AFFINE_IFMA *r, + const P521_POINT_AFFINE_IFMA_MEM *tbl, + const Ipp32s digit) +{ + Ipp32s idx = digit - 1; + + fe521 x, y; + FE521_SET(x) = FE521_SET(y) = m256_setzero_i64(); + + for (Ipp32s n = 0; n < (1 << ((BP_WIN_SIZE)-1)); ++n, ++tbl) { + const mask8 mask = is_eq_mask(n, idx); + + /* x */ + FE521_LO(x) = m256_mask_mov_i64(FE521_LO(x), mask, m256_loadu_i64(FE521_LO(tbl->x))); + FE521_MID(x) = m256_mask_mov_i64(FE521_MID(x), mask, m256_loadu_i64(FE521_MID(tbl->x))); + FE521_HI(x) = m256_mask_mov_i64(FE521_HI(x), mask, m256_loadu_i64(FE521_HI(tbl->x))); + /* y */ + FE521_LO(y) = m256_mask_mov_i64(FE521_LO(y), mask, m256_loadu_i64(FE521_LO(tbl->y))); + FE521_MID(y) = m256_mask_mov_i64(FE521_MID(y), mask, m256_loadu_i64(FE521_MID(tbl->y))); + FE521_HI(y) = m256_mask_mov_i64(FE521_HI(y), mask, m256_loadu_i64(FE521_HI(tbl->y))); + } + + FE521_COPY(r->x, x); + FE521_COPY(r->y, y); +} + +IPP_OWN_DEFN(void, ifma_ec_nistp521_mul_pointbase, (P521_POINT_IFMA * r, const Ipp8u *pExtendedScalar, int scalarBitSize)) +{ + /* precompute table */ + const P521_POINT_AFFINE_IFMA_MEM *tbl = &ifma_ec_nistp521r1_bp_precomp[0][0]; + + __ALIGN64 P521_POINT_IFMA R; + __ALIGN64 P521_POINT_AFFINE_IFMA A; + fe521 Ty; + FE521_SET(R.x) = FE521_SET(R.y) = FE521_SET(R.z) = m256_setzero_i64(); + FE521_SET(A.x) = FE521_SET(A.y) = m256_setzero_i64(); + FE521_SET(Ty) = m256_setzero_i64(); + + Ipp16u wval; + Ipp8u digit, sign; + const Ipp32s mask = ((1 << (BP_WIN_SIZE + 1)) - 1); /* mask 0b11111 */ + Ipp32s bit = 0; + Ipp32s chunk_no, chunk_shift; + + wval = *((Ipp16u *)(pExtendedScalar + 0)); + wval = (Ipp16u)((wval << 1) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + neg_coord(Ty, A.y); + mask8 mask_neg = (mask8)(~(sign - 1)); + FE521_MASK_MOV(A.y, A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + + for (bit += BP_WIN_SIZE; bit <= scalarBitSize; bit += BP_WIN_SIZE) { + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u *)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + neg_coord(Ty, A.y); + mask_neg = (mask8)(~(sign - 1)); + FE521_MASK_MOV(A.y, A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + } + + FE521_COPY(r->x, R.x); + FE521_COPY(r->y, R.y); + FE521_COPY(r->z, R.z); + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, NULL, &A); + return; +} + +#undef dbl_point +#undef add_point +#undef neg_coord +#undef add_point_affine + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p521.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p521.h new file mode 100644 index 000000000..6cdb3353a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecpoint_p521.h @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ +#ifndef IFMA_ECPOINT_P521_H +#define IFMA_ECPOINT_P521_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_defs_p521.h" + +typedef struct P521_POINT_IFMA { + fe521 x; + fe521 y; + fe521 z; +} P521_POINT_IFMA; + +typedef struct P521_POINT_AFFINE_IFMA { + fe521 x; + fe521 y; +} P521_POINT_AFFINE_IFMA; + +/** + * \brief + * compute R = [pExtendedScalar]*P = (P + P + ... + P) + * \param[out] r point (in radix 2^52) + * \param[in] p point (in radix 2^52) + * \param[in] pExtendedScalar ptr Extended scalar + * \param[in] scalarBitSize size bits scalar + */ +IPP_OWN_DECL(void, ifma_ec_nistp521_mul_point, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p, const Ipp8u *pExtendedScalar, const int scalarBitSize)) + +/** + * \brief + * compute [pExtendedScalar]*BP + * \param[out] r point (in radix 2^52) + * \param pExtendedScalar ptr scaler (length 384 bits) + */ +IPP_OWN_DECL(void, ifma_ec_nistp521_mul_pointbase, (P521_POINT_IFMA * r, const Ipp8u *pExtendedScalar, int scalarBitSize)) + +/** + * \brief + * convert point to affine coordinate + * \param[out] prx affine X coordinate + * \param[out] pry affine Y coordinate + * \param[in] a point + */ +IPP_OWN_DECL(void, ifma_ec_nistp521_get_affine_coords, (fe521 prx[], fe521 pry[], const P521_POINT_IFMA *a)) + +/** + * \brief + * check point on curve P521R1 + * \param[in] p point (in radix 2^52) + * \param[in] use_jproj_coords is Jacobian Projection coordinate or Affine Coordinate + * \return int 1 - is true | 0 - is false + */ +IPP_OWN_DECL(int, ifma_ec_nistp521_is_on_curve, (const P521_POINT_IFMA *p, const int use_jproj_coords)) + +/** + * \brief + * compute double point P521R1 Enhanced Montgomery Algorithm + * \param[out] r point + * \param[in] p value point (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_ec_nistp521_dbl_point, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p)) + +/** + * \brief + * compute add point P384R1 Enhanced Montgomery Algorithm + * \param[out] r point + * \param[in] p first point (in radix 2^52) + * \param[in] q second point (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_ec_nistp521_add_point, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p, const P521_POINT_IFMA *q)) + +/** + * \brief + * compute add point affine P384R1 Enhanced Montgomery Algorithm + * \param[out] r point + * \param[in] p first point (in radix 2^52) + * \param[in] q second affine point (in radix 2^52) + */ +IPP_OWN_DECL(void, ifma_ec_nistp521_add_point_affine, (P521_POINT_IFMA * r, const P521_POINT_IFMA *p, const P521_POINT_AFFINE_IFMA *q)) + +#include "ifma_arith_method_p521.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +__INLINE void recode_point_to_mont52(P521_POINT_IFMA *pR, + const BNU_CHUNK_T *pP, + BNU_CHUNK_T *pPool, + ifmaArithMethod_p521 *method, + gsModEngine *pME) +{ + ifma_import to_radix52 = method->import_to52; + ifma_encode p_to_mont = method->encode; + + const int elemLen = GFP_FELEN(pME); + + BNU_CHUNK_T *pX = pPool; + BNU_CHUNK_T *pY = pPool + elemLen; + BNU_CHUNK_T *pZ = pPool + 2 * elemLen; + + GFP_METHOD(pME)->decode(pX, pP, pME); + GFP_METHOD(pME)->decode(pY, pP + elemLen, pME); + GFP_METHOD(pME)->decode(pZ, pP + 2 * elemLen, pME); + + to_radix52(&(pR->x), (Ipp64u *)pX); + to_radix52(&(pR->y), (Ipp64u *)pY); + to_radix52(&(pR->z), (Ipp64u *)pZ); + + p_to_mont(&(pR->x), pR->x); + p_to_mont(&(pR->y), pR->y); + p_to_mont(&(pR->z), pR->z); +} + +__INLINE void recode_point_to_mont64(IppsGFpECPoint *pR, + P521_POINT_IFMA *pP, + BNU_CHUNK_T *pPool, + ifmaArithMethod_p521 *method, + gsModEngine *pME) +{ + ifma_export to_radix64 = method->export_to64; + ifma_decode p_from_mont = method->decode; + + const int elemLen = GFP_PELEN(pME); + BNU_CHUNK_T *pX = pPool; + BNU_CHUNK_T *pY = pPool + elemLen; + BNU_CHUNK_T *pZ = pPool + 2 * elemLen; + + p_from_mont(&(pP->x), pP->x); + p_from_mont(&(pP->y), pP->y); + p_from_mont(&(pP->z), pP->z); + + to_radix64((Ipp64u *)pX, pP->x); + to_radix64((Ipp64u *)pY, pP->y); + to_radix64((Ipp64u *)pZ, pP->z); + + GFP_METHOD(pME)->encode(ECP_POINT_X(pR), pX, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Y(pR), pY, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Z(pR), pZ, pME); +} + + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p256.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p256.h new file mode 100644 index 000000000..6d4d9b46a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p256.h @@ -0,0 +1,716 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#if 0 + +#ifndef IFMA_ECPRECOMP4_P256_H +#define IFMA_ECPRECOMP4_P256_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_defs.h" +#include "pcpgfpecstuff.h" + +#define BASE_POINT_WIN_SIZE (4) +#define BASE_POINT_N_ENTRY (1 << ((BASE_POINT_WIN_SIZE)-1)) + +#define OPERAND_BITSIZE (256) +#define LEN52_P256 (NUMBER_OF_DIGITS(OPERAND_BITSIZE, DIGIT_SIZE)) + +/* P256 affine point */ +typedef struct { + BNU_CHUNK_T X[LEN52_P256]; + BNU_CHUNK_T Y[LEN52_P256]; +} P256_POINT_AFFINE_IFMA_MEM; + +extern const __ALIGN64 P256_POINT_AFFINE_IFMA_MEM ifma_ec_nistp256r1_bp_precomp[64][BASE_POINT_N_ENTRY]; + +#if !defined(_DISABLE_ECP_256R1_HARDCODED_BP_TBL_) + +/* Montgomery coefficient R = 2^(6*52) mod p */ +const __ALIGN64 P256_POINT_AFFINE_IFMA_MEM ifma_ec_nistp256r1_bp_precomp[][BASE_POINT_N_ENTRY] = { + { /* digit=0 (1,2,..,8)*(2^{0})*G */ + {{0x0008905f76bdc7b5,0x0007bd418a9143c1,0x000c475d568abc1f,0x0009a701075ba95f,0x00003d1f32c8b4b9},{0x000571ff18aafa5c,0x000f757ce95560a8,0x000434a7e54432f7,0x0002797258b4ab8e,0x00009df870e37032}}, + {{0x0006bb32e5348a6d,0x000d9d410ddd64df,0x0000ad784f985075,0x0008a23d9aa6ae3c,0x00001fb0f13f1e58},{0x0008c57751832101,0x00047d361bee1a57,0x000b725df8a6ac15,0x000e32cbe152cd7c,0x00008c240484bd0e}}, + {{0x0006936a3fdd92de,0x00061904eebc1272,0x0009e1ea17bc2219,0x00038de98b027f84,0x0000be1daceb9daa},{0x0005f06a2abb7836,0x000261fc983a7ebd,0x000c327193eff4d4,0x000b6b38e583e47a,0x0000315e09d4065e}}, + {{0x00077362f599237a,0x0003b0d46918dcc5,0x000d6eb05e7ddb8d,0x000ec90f24650a6e,0x0000604e8ac3b74e},{0x0004b14c39d10c04,0x000ee4ce4cbaba68,0x00017625a80d5c8a,0x000d1ce2e1762847,0x00009cb7c6eea514}}, + {{0x0009079606520cb9,0x000d1aec45c61f5c,0x0009cbb1bd776c0e,0x0006a090c90ec649,0x0000ce1d21d8a47e},{0x0003a076bba1725f,0x0003c4ae7ba4f107,0x000f724b117049be,0x00007c06873c568e,0x0000d1631291cbdd}}, + {{0x0003074b59672881,0x000c6373e77664a1,0x000f2165a2e4d910,0x000ef22ad55ae744,0x0000cd292bcbc0f3},{0x0004c9916deed188,0x000da20d377e44ba,0x000309358347a501,0x000921711299c2b5,0x0000cd3e2ccadf00}}, + {{0x0003ba5119d6cc8f,0x000a64ea0173b4f1,0x0003be81afdd3079,0x000572c082bd2021,0x00001db750e89b35},{0x000aedd9165911e1,0x000ef303f5b9d4de,0x000172b8a2c6cf35,0x000b760956742f2f,0x00007d5db743c61e}}, + {{0x000763891f69c8ac,0x000a0d19499a78fb,0x0004b837ab35be28,0x00064506b462ab5c,0x00002c41f6130b86},{0x0006ec12f2cdf2f2,0x000b1a9532d49775,0x000d78b2a72327aa,0x0006dc9f021e3327,0x00006889435a91f0}}, + }, + { /* digit=1 (1,2,..,8)*(2^{4})*G */ + {{0x0004d63c80e5d9f3,0x00018650bc6fb805,0x0004eb27f1ea9ab1,0x000aa02495882e07,0x0000a466f2e5fb46},{0x0004edf7b266ddd9,0x00042d652a23f9b6,0x0008e61d6dd58c13,0x0007a359e3670c31,0x0000d257b443894a}}, + {{0x0009227077a277a3,0x00059cfc5e3a3d83,0x000c07576f48364e,0x000355e97befd904,0x00001c25c29ce15c},{0x000231d792f7c39a,0x000a46ddbef42f56,0x0003e5d8c175121e,0x000d694407e449b6,0x00003711285e87b5}}, + {{0x00084039030f437c,0x000c53077adc612c,0x0008f397ca9d5bf0,0x0004489bda749652,0x0000af611eeda45e},{0x0005efc7e9c72224,0x0007b66175adff18,0x000b31e8fdcd72d3,0x0007b51e30b26d7f,0x0000abe9a851e48b}}, + {{0x0005fb8394ec96bc,0x000daf305968b809,0x000272a3f024eed6,0x0002f6201380a091,0x00005bd44243eed6},{0x000967204437eb69,0x000fc1280edfe2f2,0x000966478f3e6250,0x00056e2f88f726bb,0x0000b48e94ed5c40}}, + {{0x0000bfffc5132382,0x0005a0752b3e584c,0x0007f5386a673608,0x0005a637335ff9aa,0x0000ee72d7a3789f},{0x000995919cce62b7,0x0000b2a1d49c6052,0x0005898b5a5e55c7,0x000be3d281b037d7,0x0000fcf783c6d6c3}}, + {{0x0001eddf7fe28eb9,0x000d42333e12b701,0x000b07ef531b9d9c,0x0002d7c4d6d490a4,0x00008ce594304c88},{0x000f2a78b36344a4,0x000df28d87fd1d83,0x000cbdd7df5fbadb,0x000e518a2fd2f4f8,0x00002427ceb81118}}, + {{0x0001704d00faa90e,0x000f7760a99cbca7,0x00059333dbf16feb,0x00089ac0c94e258f,0x000067cee41b4c7d},{0x0005000c252c9746,0x000650ef88b8b706,0x000e5b0ea5e2af00,0x0009f378056feb92,0x000066ae9a8c4350}}, + {{0x000d311f2cf406c5,0x00006817a2ad62aa,0x0008ff31e0276fbf,0x000a6d8b57ef2b6b,0x0000437e1f6177bf},{0x000a38d321e63954,0x0002c87c2ff3b6df,0x00023c3f61ddd141,0x0009d5d38b46feaf,0x0000a9e4aaa74b8f}}, + }, + { /* digit=2 (1,2,..,8)*(2^{8})*G */ + {{0x000c3da1963d1b37,0x00058fa696946fc7,0x00083d8e03d70b52,0x000d8231550fbc6d,0x0000c23f1ad7a853},{0x00099d49ebcaeaa8,0x00055b03cfd5d8b3,0x00024f00b2ba1b89,0x000385daa0704b7c,0x00003f881bb6342a}}, + {{0x00042370d35642b3,0x000ce10399492969,0x000aa1fa40e1eea0,0x0002bfcf55b63827,0x00006300726619ca},{0x000dc61f92142820,0x0008f2ee0d985a17,0x000af47364dbdea2,0x0003af2f8192cc64,0x00009a126d8fb59a}}, + {{0x0005d5bbfc230970,0x000353eed4c37174,0x000ef73916a712cd,0x0004acaa59f8240c,0x0000b069410109c2},{0x0004d5e0fcf149d6,0x000f673137fd28e3,0x000f92655f0108ba,0x000ab48f2862ac6e,0x00009efcb3eef840}}, + {{0x000da26e1aec73e6,0x0009be144cc3adda,0x0005da1c14b462fc,0x000697e72d5ffa1d,0x00007dc85a835122},{0x0001c794b1a357c1,0x000661563483caaf,0x00083d98e34b8417,0x000eead3ce6924cd,0x0000cfb7382ae666}}, + {{0x000a786d62a93d0d,0x0002b5c08369a907,0x000a9e9647958a75,0x000519f802990c59,0x000076b05f00e31d},{0x000b2ce9e430d6f9,0x000b4be20ac3a8dd,0x00007f8d434c0323,0x000cdfc6531a2178,0x00009e7647365eaa}}, + {{0x000f3a8f9d8cc3f9,0x00072f38bd7aff18,0x000a8e4721a92651,0x00064b0151b5ee4c,0x00003b792b15a449},{0x000255f53b1b9da9,0x00010c9a0748be7d,0x0004d6d86ce4578c,0x00072ff371d391c9,0x0000702e661ee631}}, + {{0x0008c889de2e32a8,0x000b0d474a861082,0x000fc583d3b1de17,0x0003aa480f8048a8,0x00003ee931e746ba},{0x0001c240230a2d47,0x0001f2eb214a040f,0x0007461ec3244db5,0x0007f2d8ae8c48e9,0x0000149fdf2f3f76}}, + {{0x000c5fe1306bd6ce,0x00056b9eb7926b83,0x0003915e73d8d154,0x00006960bbff88cb,0x000076006a867f79},{0x000daf6b21ea15f4,0x0006ef43764fb3df,0x000733a24b0b851f,0x00086f1f37b5af31,0x000030c22394a5ed}}, + }, + { /* digit=3 (1,2,..,8)*(2^{12})*G */ + {{0x000a20ed2a8c1c6f,0x00041e5ab4b35a24,0x0001abcdbda4db56,0x0003f26801d8b600,0x000004b48afeb9ed},{0x000a24142725a709,0x00053d44fec01e63,0x000c6ddb3c8679c1,0x000868efd3ed7ddc,0x0000203192c73ce6}}, + {{0x00058ae74fac8317,0x0008162d5d721d5b,0x0002a648ba32d37d,0x0001fb6a40c3357a,0x0000d41eebd7ebce},{0x0007312ec0f21311,0x00009812e6dad6be,0x00010d0c3d9a387e,0x00083b3d8de28605,0x00000e56beae8107}}, + {{0x000fb3a0d6a300fe,0x0006afeaae6ee702,0x0005264f0ff2ccae,0x00093072a78f4cc1,0x000056f1807ed1cb},{0x0002f775e441af97,0x000f83bb25a43ba1,0x000106f6b36db209,0x00000ca2a30bf803,0x0000b4aeb7054ee0}}, + {{0x000161957d933aea,0x00028e76e6485b37,0x000b05babd7b6596,0x0000f456d4d3e24d,0x0000ce6abd42c3d5},{0x000aefa7aee9d873,0x0009f83cdb12a6c3,0x0001f36139b52f8a,0x0008e5973bf3fa88,0x0000e7a50e16b447}}, + {{0x000497cd9642f15e,0x000a28037a929a9e,0x000d3566f9270405,0x000ba2d6265601a8,0x000064b1d8ef45cf},{0x000a573239e26ada,0x0005e7f9aa5b2f93,0x000f2d605dae4d62,0x000f28430e5faa3f,0x000025c3e2fb5346}}, + {{0x0009b7e2c88699d1,0x000576bd17c24093,0x0003296e6ad3635b,0x0005cb70f2c4e479,0x00000b645230e891},{0x000c2f42b8f4bf96,0x0005122d096f4a9c,0x000af2a6a3deda09,0x0006383116861aec,0x000032eb61a73777}}, + {{0x000707b18213a914,0x000b751d0a917b49,0x0002b19247af2039,0x000f9e2b6c2cfa3f,0x0000392f6ab1c9d5},{0x00021fa98a0d29bf,0x000e272d5f8b10d2,0x00052db4aaa0a8d8,0x0006faa92fd30783,0x00006bd9fc3c53d0}}, + {{0x0003f63771beff8f,0x0006f623b36f9fd2,0x0003d9eb684ebab1,0x00084f3ef26543b2,0x000096ae77bc2ed6},{0x000fb89d795ff65e,0x0007796b6a1142e5,0x0005d3a20e91b4d9,0x00011bfd55ea6aac,0x0000a386dea94493}}, + }, + { /* digit=4 (1,2,..,8)*(2^{16})*G */ + {{0x000564bade8d111c,0x00049fce3779ee34,0x000d77e4a2bf81f0,0x00017327ae00e7f9,0x0000f7675150c393},{0x0007f7ccb1668c80,0x000b12ac4708e8e4,0x000b5f26ce2e2a59,0x000dbcb9f4f5725f,0x0000c707f408fcd6}}, + {{0x000dbde4ac826d0d,0x0007c0361a341c13,0x000fcf3f7c95b3aa,0x000c6246c3604dc5,0x0000ce46d1be3f02},{0x000f0d1f30affc92,0x0006a5d1c7eef696,0x000562423070d98e,0x0003f8fca5889680,0x00003b45ef942f70}}, + {{0x000c9a9d2168c124,0x000671dbe7a2af37,0x0008d31cad5154da,0x000c67297ec51caa,0x0000f6a5ba0129fa},{0x00003937564cf036,0x000ae4f6ef5f0145,0x000298d331a9ca83,0x00051e01e8abcf41,0x0000803532cecc34}}, + {{0x000688350470c6e0,0x000970977f7195ad,0x0006d7634e8b89f8,0x00088212d8ec8616,0x000043845130a44a},{0x000f5c2ee645cfc9,0x0005bf8309004c28,0x000584a3ba78a88d,0x0005275a4a96e4b7,0x000038c353982c77}}, + {{0x0006877b288e2940,0x000f33959145a65f,0x000803b8e80eaf37,0x0006112a0cd9bc36,0x0000b81a72e0ba9f},{0x00040fa5a0fd54f6,0x0008b9bf5cbdb258,0x000859f95ca88625,0x00044185f2a4fd1d,0x0000bbdb6fce4677}}, + {{0x0000d8b2dae7ca94,0x000fcb36b0cf82eb,0x0005753d030cfdc3,0x000d1805a6438d24,0x0000a53ea3da217e},{0x000afa8c8dcb9f12,0x000c8dbd9184c4d2,0x0005ce430ce88936,0x000756b473dbb18d,0x000096aae294c905}}, + {{0x000dfe0d903a457a,0x0001207e3533d77b,0x000970360f08ec9b,0x000e84aedd7222e6,0x00008819a858ad52},{0x000eb874ec49378f,0x0000bb61d056605f,0x000587efe032d6ae,0x000c3fe8ca9ea9df,0x0000fbcf08ae31fe}}, + {{0x00022a049341c337,0x00033a9bd7638026,0x00000306390eab7d,0x00022f7c4c21486a,0x0000d141475b8b86},{0x000540cb1b1be032,0x000da9dbb7a8ee0d,0x000b96c0e3c063f7,0x000de42ecdc2ed3b,0x0000397c62c0f6ec}}, + }, + { /* digit=5 (1,2,..,8)*(2^{20})*G */ + {{0x000e6e2135aa3e34,0x000406a584c5e205,0x00015b6e4efffd6a,0x00016589b267e4ea,0x000028a50a289a0f},{0x000fef4e6229a8b1,0x0001b6a8c8f936e6,0x000445d2f37ab589,0x000b64a868af84d0,0x00002d1d526d0d0a}}, + {{0x0005c78880bdb670,0x0001f09257226088,0x000a8d556d463880,0x000fe87ac131260d,0x0000a978da1cbb3c},{0x00081d1c0fbab2fc,0x00085ffc3bdf24eb,0x000b3da6a9989162,0x0009b73405bff75c,0x0000d9387ea82fe6}}, + {{0x00091ae46f2b2572,0x000703d442a8ad11,0x000ced9edcf5c7ca,0x000e533e5c3816a7,0x0000d4bbe9bb1cb0},{0x000a4a73efeed78e,0x000f18700611c5bf,0x000704c62558948e,0x00091cb5283171ed,0x00000228300708db}}, + {{0x0002b79aff1b7640,0x0003cc8f43a730f8,0x000bb0f3be0fe168,0x0008ce40be89b6f3,0x0000da60e29a2a91},{0x000b662498ee8663,0x000c556962fe5de3,0x000b255f6d5a6808,0x000a245580c590ad,0x0000e4d2e7887b5b}}, + {{0x00031ec55d438d92,0x000bcd082dd1b6ad,0x000794983e52056e,0x000cfd8aa5783a13,0x00009f94d2983cbc},{0x00042b80509ea4d5,0x000fe3f8e9a76414,0x000cc5621e2a00e9,0x000e39f93625453e,0x0000b6fe3802944d}}, + {{0x000414582cf35827,0x000a80d6c39765a2,0x000d882871de9e8b,0x0003d1450a2db3ac,0x000046f7d2fddbd8},{0x000672303b75f511,0x0007abc60eee9a8a,0x0001cc28700717f7,0x0003de4d554c79f0,0x00009aa79fb6b0ef}}, + {{0x0006940f54c45508,0x000502d3bfab839b,0x000378f6cb89828a,0x0002513c392474e0,0x0000cd44686f1550},{0x000e788bf3109a0c,0x00082f2f2759f255,0x000948a168d333d9,0x000b6b7459dd9578,0x0000c7da7b3800f6}}, + {{0x0004ff052f5917b5,0x000faa8719c05631,0x000ca760c26fde52,0x0005d57d3cd8ad2d,0x0000bd74588b7072},{0x0006ad71d02a024a,0x0003acf3e2d65208,0x00078da16339cd4e,0x000f011987ebdf0f,0x0000079790c922a9}}, + }, + { /* digit=6 (1,2,..,8)*(2^{24})*G */ + {{0x000f5d55f460757a,0x0004ec4868af75df,0x000e466b71f6795b,0x0000c72b0d7325cf,0x0000e10c5f3da26c},{0x00094ad8a7522d79,0x000cc411977a0ee8,0x0004e8d5601f6c03,0x0001e3b955085c4c,0x000028f635d618a7}}, + {{0x00066010689e1641,0x000f3b22c11bb373,0x000db6ec643ab5eb,0x000afb15d2d0366d,0x0000ab615f997250},{0x000b5f7e8a49c22d,0x000402c68d7b6d44,0x0008c124aab7be0b,0x000a684eea8f74f0,0x00006ee0d7c27a2d}}, + {{0x00079739f7318d32,0x00027b21994ef202,0x00093bf3a921a053,0x000dc5e102a653b6,0x0000417acbe360fd},{0x000b40cff123155f,0x000073c8b799336a,0x000c74fb67fa3a8f,0x000c69c2dfdfdf14,0x00008baaad38eb7e}}, + {{0x000984d8c0756da9,0x000f60b879fbbed4,0x000691183fa97cc8,0x00008c6450ff0ae8,0x0000bc7e3aa798e1},{0x0002c0087c8490da,0x000bba6d21008f03,0x0000075a13ccfa3b,0x000db76f329bd54a,0x0000cdfd68fa494d}}, + {{0x00075553bbd18331,0x0005fabfbaf50a55,0x000b10f8b3952494,0x000f37f05df55e76,0x000083667f4aec1f},{0x0001b91149c64f10,0x0006ca3553afa736,0x000beb9cb1077179,0x000ef4d35315f3ff,0x0000724cdc42e0e8}}, + {{0x0009f8db144f77e9,0x000026662b5f3af3,0x0000d0c25c1ff887,0x0007b73b1cefab56,0x0000cd5a1cf3f9ca},{0x000d5a818694755a,0x000725b3c61bfd60,0x000d33c6e57d6b39,0x000d8c2c2a5a4d41,0x0000da06aa84668d}}, + {{0x000633d510319630,0x0000a4956f908239,0x000fdde9a26b1a49,0x000f5c760ba0f507,0x000011a47fccb3c1},{0x00074a4f6a780782,0x0003543b8c9de617,0x0003e69cf7b58be5,0x000c69ab2b475125,0x000059a05b225efc}}, + {{0x00041b32e5ee0cd0,0x000bea601799a527,0x00014451f66c2b00,0x000f25a7ca20cec4,0x00001caa549ccc91},{0x000641caaadc47ea,0x00097814eb57d471,0x0004006d25c11bc5,0x000a4cb887a2d0ed,0x000005cf797f0540}}, + }, + { /* digit=7 (1,2,..,8)*(2^{28})*G */ + {{0x000cf9a2f2b6ddb7,0x000cb4f20151427a,0x0005e5495f13c8bb,0x000336c57206828b,0x0000deb474abe52a},{0x000c630fc54290e0,0x000e9da279153564,0x0006b3bbef1e9949,0x00021a8e27e0734b,0x0000614b2885f690}}, + {{0x0004ab68d7e959ee,0x000227a1ac2703b2,0x0008471ceedd9bdd,0x00080ded1b49258d,0x0000011c8d9a06d3},{0x0000b360f8d06cf6,0x000bfd4734e59d08,0x000843e26b87ae6b,0x000b0c3b35f8740c,0x0000b6d468726158}}, + {{0x000ac1e3e5d6df58,0x000075d5fa067d1d,0x000ebba6b226d7b2,0x000af82ac4134b57,0x00001bb953caf0cd},{0x000cde538c8bc9c2,0x0003669d81fbb26c,0x000be58de047db86,0x0007841e8449ed3e,0x0000d643fef5794d}}, + {{0x0003331d3c69f2bc,0x0000a8da61a76fa3,0x000d96e2379febe3,0x000486b9c598b441,0x0000390a58c27d0d},{0x000cdb9daf4c5417,0x0006d8e298de399d,0x0006c4c6e1a6e0f8,0x000649470cfdb8e7,0x0000690440cf3b0b}}, + {{0x000cd3d0d4027b25,0x000d3c2019f2a596,0x00035e7beba07964,0x000164eddb3ce5bb,0x00000d8037d39488},{0x0000c29968554c2a,0x0009ad6efed021c1,0x000059b49a323da0,0x0003c9c4a09a9f9b,0x0000c0cc53fbad1c}}, + {{0x000c73d2287162dd,0x000c529ed6e82ef1,0x00034977dd25e6f6,0x0004a8aae16f338e,0x0000dc61c21e5eed},{0x00096fe447e4eae7,0x0006a3174a5c8c7d,0x000fa5f9c92267ca,0x0007c117e01cd296,0x000068abc8039604}}, + {{0x00041d6367599350,0x000706e88fbd3813,0x00042818412bda97,0x0005e6bcd02cd4a8,0x0000b40e707676fb},{0x0006fe0a3a3a6e7f,0x000d8fbd238202b9,0x000a1286e09fb174,0x000d4efa0600b4d1,0x00005566cd140a17}}, + {{0x000246780b6116f2,0x00015367f636a38c,0x00064c305dbfeb38,0x0009f998b9f943fb,0x00002a4f058aaf47},{0x000300fadd2ed37d,0x00097156d549fc2b,0x0000ad7686ed0d31,0x00005d713c2953f3,0x0000c01130ae8caa}}, + }, + { /* digit=8 (1,2,..,8)*(2^{32})*G */ + {{0x000953c50eb5331d,0x00069024147519ad,0x000b4d5fade16af5,0x00052cec8d0981ea,0x0000f785b3ffbbf2},{0x00063ebb7f24f144,0x0001dccfd590f8f8,0x000abea80d987872,0x000fa20cf72e9626,0x0000721e8be990fd}}, + {{0x0009fb18a0fee18b,0x000f1f5678a31b0f,0x000d3f9d9d7f8899,0x0002e2896d50301a,0x0000467828ca24c1},{0x000a2f2a98bf1696,0x00042ebe8758851b,0x0005a36a8fac4075,0x000e6fdb71e64e4c,0x00002450761a46be}}, + {{0x000b89a4e82f20ac,0x0005be0e90fb21e5,0x0000601e57b9726e,0x000acbbb500fd2b8,0x0000def3cf863f66},{0x000f548f31add03f,0x0006e3f894407ce5,0x00040ccdd200e1b3,0x00036823ba0025b9,0x000057161113964b}}, + {{0x000379ae15e41fc7,0x0000ca7c35d87949,0x00076fdd0ccf2ac7,0x000135bfd042e655,0x00007cefff827780},{0x000b09f648a49efa,0x000b462fcc9981ea,0x0000c21f3e7dc01a,0x000af6bebaed3d63,0x0000701de9b6b9b9}}, + {{0x000bdcfbd504057f,0x00054d331b85f091,0x000a8cadea75bdae,0x000e6d1fd0f45354,0x00002490dea9fe2b},{0x0000ac8047450e35,0x000f366cd5225391,0x00027062fa6c9f4b,0x000f7bd93fa9d473,0x0000df0d238b6d83}}, + {{0x00004675e9e96a79,0x0009c366d91cd2c0,0x000ada5d7afaf95d,0x000d7678340a2bee,0x000031e43a7d6f3a},{0x000939ae632995b9,0x000f1ff840e446e0,0x000fe0f6e10f4eb2,0x0000641d99f9f258,0x000059714d33363a}}, + {{0x000dac0c56b9c972,0x00003146fc627e20,0x000583ab2dfb01e8,0x000b8d1d5a0569bc,0x0000e9531ed3477b},{0x000c960233998e0f,0x00024b5da590d5fc,0x000311eb725dffaa,0x0003166d0a806780,0x00002e32acfedeb4}}, + {{0x000a823a4160c545,0x000f51222248acc7,0x000eb7e2a9255142,0x00038a9281f6ec0e,0x0000f63c9cc1c2fa},{0x000efe9ed3f2c904,0x0002604e1900a791,0x000aaaefc6a23190,0x00095a14acde09d4,0x00007b2680ab6b58}}, + }, + { /* digit=9 (1,2,..,8)*(2^{36})*G */ + {{0x000c47940a63bdc1,0x000acbe305406dd9,0x000f4115854d7ebc,0x000bf8c8f8eb7dc7,0x0000eebcc0956bd4},{0x00040deabe2974cf,0x0008c5d99b307781,0x00065a6b4bc494d8,0x0005271e325380c5,0x00006c75941c35b1}}, + {{0x0003c3a8ea6b2c0c,0x0005526c49a861ec,0x00051d8b641c7fc2,0x0006ff017024f3b6,0x00006af90c54fe5b},{0x0006848b57a6af77,0x000fe2cb103d4c8d,0x0002bb9428138d50,0x000a1d94a02bc461,0x00005196aa6193cf}}, + {{0x000f0e96b0521716,0x0006bdb1782269b6,0x0008b6894ea0436c,0x000213b53ae34bf7,0x0000f89e64dfb40d},{0x000020f0e5f7aa5e,0x000a41577884456e,0x000b89101dc1c7bf,0x0005074deb3b5688,0x0000322f52afaf0d}}, + {{0x00039b66645c58c8,0x0007a8dbbe5a1a9a,0x000e8d8b5703704b,0x000b790268187fd5,0x000003b8f3f8d5eb},{0x000b2f3a4a4db66a,0x00074ef2d65a8087,0x000f193430cf1f8c,0x000a6ec4c4969044,0x0000c1c8991dfd8f}}, + {{0x000b8888bb33c9a0,0x00038dd0f82b2148,0x0009657b430acfe7,0x0000dfe19460c34f,0x0000b39b6f7347e5},{0x000bf0221449dce2,0x00055dcc07226779,0x0008802bed13455f,0x0001abec610d21be,0x0000f48269445497}}, + {{0x000dd04b97f56424,0x0001d60b7fe7b6e0,0x000a3239f41aa1f1,0x000c4a61e7d16189,0x000064bed27452ed},{0x00079b5499dfb43f,0x000fd9b506db8cc0,0x000ec79d2cb2ca13,0x0009706e65cd47aa,0x00001dff152d73d6}}, + {{0x000aa7cb935a507d,0x000551ae0ac29416,0x0004582b4da3a965,0x0007915d0279b025,0x00008622b071bf70},{0x00035a70c90666d4,0x00051800d37c7a50,0x000730d2e35953b1,0x0006c1b9213380c3,0x00008f95b8909dcf}}, + {{0x0003fba6baaee763,0x000548571ba18615,0x000c7ccd5282a222,0x0004c589348b22d5,0x0000c343e640ecd7},{0x000d50cd542a5f8c,0x000f1f3e5eea7d82,0x00063b79a4045592,0x0000f8e05521c879,0x000038b6e3d1e7a4}}, + }, + { /* digit=10 (1,2,..,8)*(2^{40})*G */ + {{0x0005910a01f9dd2f,0x0003e65533ef2177,0x00044e3924858ec2,0x0004e12677158c7e,0x0000817fb332f9e2},{0x0009f8be4c5579ed,0x000d207cf88577d2,0x0000ba656c829dbc,0x0002850852224525,0x0000a45a5a5d4127}}, + {{0x0006aebf577abd9d,0x00015452133ffd9d,0x0000ac605ac980fc,0x000e4582a39a8b2f,0x00004eec5aa7265a},{0x000045d5cf88aa51,0x00029cb76ccdac60,0x000c15412957a97b,0x000342cd1af4d36e,0x0000e6170f039470}}, + {{0x000f32ef99cc6085,0x000bc4351facc618,0x000d57573622f8bd,0x00097ededbaf2647,0x0000f2cc80070643},{0x00034049491087f9,0x0004f8c7593cbd4c,0x000c3f77e662b98a,0x000634616ed266c5,0x00002b5777286404}}, + {{0x0008c8bf5c4dddf3,0x000e274c005979da,0x0001c17823f45915,0x00004f9f9c2072b4,0x0000aaa1baf4fa40},{0x0001cb9e28458fbd,0x0002855114df14a7,0x000d8bfa4e43521f,0x000189718d4374a4,0x0000a04910e166e7}}, + {{0x000ca7b94abcb8cf,0x0009802094704963,0x000daf2a7eca4d08,0x000247498a489a5e,0x0000e144eefa19d2},{0x0008666e16797254,0x00009682ad636a41,0x0004f075f107c2c6,0x0002fc5436702702,0x0000b46d254bc836}}, + {{0x0002b2a3e2819447,0x000b6350369c8e10,0x0002b729e058e5fe,0x0006e9bab9271aa6,0x00006605f347cecb},{0x000ced0cf5b648e5,0x000fe5f0e2b379be,0x000be9659e2ffbdd,0x0000d1c063d3de39,0x00006c7602acd385}}, + {{0x000aa397878c7fdc,0x000d8ca2a604b3b7,0x0003bfbdcfdab93e,0x0000ba46e56f6518,0x000008070b9ee90b},{0x000ff6976d6bc06b,0x000412a0e01fabc4,0x0004d387028c757f,0x00060b4fe7c6ee8a,0x00005840dd588099}}, + {{0x00032caa306d36d2,0x0007e7903605c397,0x000e2e161f3c1bd9,0x0005b6484f0843d9,0x0000c3ed7e7103a9},{0x0002e9423a811470,0x000527061160170e,0x000b6096786931d4,0x000d933acc32788c,0x000040d7f8af5425}}, + }, + { /* digit=11 (1,2,..,8)*(2^{44})*G */ + {{0x0001682c10b4b42c,0x00049455922ac1c3,0x000c73c31352d93e,0x0002a2bc4a7b3ef5,0x00009c11c3b203bd},{0x000c092172b4577e,0x000a6f04bd55d319,0x00057bacfaff1310,0x0004d8a9db6d1c08,0x0000b14a2965910e}}, + {{0x000910b95bc8d4b3,0x0009d35ea6c39976,0x000a5950529391f9,0x000ac2a3954259aa,0x0000954edcb4e373},{0x000982812f18224f,0x000a61043e09aee6,0x000f3de4d536e4c0,0x000508c61ced56c9,0x000097bf82337dc0}}, + {{0x000fc9cdf0a602a7,0x0000f90768fccfce,0x000cc86be572242c,0x000fb55cef402d37,0x00007fc53399e03c},{0x00038fa2f84181fd,0x0002e72d1669a8bc,0x000b93e529c4e96f,0x000b28a0e33c536b,0x0000c1aea47311b9}}, + {{0x000e413c023b543e,0x000ff931341ed7a4,0x000c597461477da5,0x0006486a44223272,0x0000e62ade1b4548},{0x00073540e59ce025,0x0006c27e17e44ceb,0x00047c7e6d15d0b9,0x000ca71caee86bf7,0x000062dc3b140088}}, + {{0x000bd5ca4b43dca6,0x000b875b2c69dbcc,0x000837ee1021381f,0x000b45c713aa77a2,0x0000a05614cbf186},{0x0006c5c5b213f9f3,0x00065076db476cb9,0x0001c871dd6ccdd0,0x000210116fde15d6,0x00006771cf226ee0}}, + {{0x0001dde5dfbb6e3a,0x000b56c872b4a606,0x0003e4356c3c10e2,0x000cfdbd1ab2a34a,0x0000f1935615b0dc},{0x000bfd9fd4818329,0x000cd219f2275f33,0x0006091fe9776294,0x0002d94aa0750c8b,0x000091bb35d3e4f7}}, + {{0x0009529ca84f2105,0x000db2adb22b94b8,0x0009189807b37871,0x000fd1763993d8ae,0x000032507bd52b7d},{0x0006d1b1faa44f66,0x0007daae572a2530,0x0007fbd06d00887f,0x000f39d58e02b643,0x0000ff4486cf7424}}, + {{0x000977faf2fd74af,0x00010abaf95894c5,0x0006cdf3274ead88,0x00068f58b7b9bdc0,0x0000d28ef6376f5e},{0x000d37fa9f638299,0x000a9ef052c4b5b7,0x0000893d97515b4d,0x0006fb5c79fe87f7,0x0000baaee7122abf}}, + }, + { /* digit=12 (1,2,..,8)*(2^{48})*G */ + {{0x000e4daa4cf03ebf,0x000a5880a750c0f3,0x00031006e436dc3b,0x000d2500539bacfe,0x0000d4ef32a1291b},{0x000a444f665140ba,0x0002db55ffc69ff6,0x000c27c0e1c0d5f3,0x000e2259446f147b,0x0000e26f578ece85}}, + {{0x000392f2ec04cd39,0x0000d5ac3f16ea83,0x000d7f5ede30754d,0x0009b6872115a461,0x00008418a223a967},{0x000fc5ff44240c84,0x00018cde526cdc7f,0x000b22632c3da39d,0x000c70d988e537fd,0x0000709b1f542582}}, + {{0x0007f2ec2dc98f00,0x00016f4bdaedfbdc,0x000fbe8180bfa37c,0x000bc3e1723fd325,0x0000f58d97310235},{0x00064f972387d213,0x0001ff245104b0d2,0x000b879a945ab636,0x00029e80f5f00daf,0x0000fd8b684b4312}}, + {{0x0008d2c9ae428f00,0x0004f7ea90567e6d,0x0006dddb93095522,0x00081903d513257b,0x0000d1ef01808e5c},{0x000ffa707b56bdd1,0x000c2246b29cb44f,0x000c77ce5b30e21c,0x000d3bd42b540a21,0x0000c8f28344b9aa}}, + {{0x000eec41cb82328d,0x00015f3e30bc27ff,0x0009b1972345ec7f,0x000331e0ee5f0c05,0x000087d0ba66f3c7},{0x000ae59616536a6e,0x000025f99d0b09f8,0x000669480fe3c760,0x000e84b31c5d6cc5,0x0000ee121b26c778}}, + {{0x000c41d1ca8f6911,0x000d2f1d4e353b7b,0x00043304ded57d7b,0x000e262fd062d8a1,0x0000c7373014e0c7},{0x000d825d0c68baec,0x000f5e76be77800a,0x000717e2f324cc7d,0x000e0471a71fe8b3,0x00007ed811a51502}}, + {{0x000a2679405d4a59,0x0005c7b39f8868a8,0x0003eba5f06f98ea,0x0008af06ee27f4fd,0x0000bf77a2388b73},{0x000dcc46466ccfdf,0x000bc72fa30f349b,0x0008f8ca8aee594a,0x000b0c7d194c9d9c,0x0000db282f8561eb}}, + {{0x00067b085c91370d,0x000d35b1cb76219d,0x00009adb7621c58b,0x0008dbc100ec0bf9,0x000035a1c37429d0},{0x000539991832fa6f,0x00095595e93a96a9,0x000a66a28b826cbe,0x000e29cb77526c1e,0x0000acab05a94fb9}}, + }, + { /* digit=13 (1,2,..,8)*(2^{52})*G */ + {{0x00096e6d076e5fb1,0x000e067ceca9754a,0x0005a20acc991594,0x000e01fbf426d2cf,0x0000e8ea47274e03},{0x0003439dd70f73cd,0x000dbdd87880e616,0x000581c546fe37f4,0x0004291151554381,0x000076b608169ba2}}, + {{0x000be5a560218c0f,0x0002245983c38b5e,0x000b7795172b6411,0x000736ce6b14f176,0x0000b95d3a653da9},{0x00090806472dd13c,0x000e1cd9f87dc596,0x000392d3ef194f1a,0x00019f6577c595cd,0x000044201d70daf9}}, + {{0x000a4bf3535ca72f,0x000398eadd70482e,0x000990fe5b370e05,0x000e33fef708de92,0x000095e812192018},{0x0004f0f83a164ec7,0x000582c87912868c,0x00052a18313ff9b5,0x000a4bf0ab1b1be9,0x0000846b0bf28b93}}, + {{0x0003043896a03a07,0x0004b381d531696e,0x000fa5c9a5d318fa,0x0004ca8c757201bf,0x00003e9b1ef0bafa},{0x0000bf7978610e72,0x0004fe18555970de,0x0008447619e614fa,0x00020318b8267dfa,0x00002d551502ded1}}, + {{0x00020ab732d47663,0x000a19f16a66e918,0x0000781056db02b9,0x000d5c5eae97f282,0x000094939d8bd05b},{0x000b2c87b6265c14,0x0008af9287144234,0x000a628484fc8c50,0x0002a90cc54ecfff,0x0000ff62b0d3b8d2}}, + {{0x0000f30fee8c3f0a,0x000134286d2e0f86,0x0001ad978fe6de9b,0x0004d1149e592012,0x0000ed2e1530c0e4},{0x0008c9d2519e343d,0x0007006858e6a61a,0x00069709a27ec803,0x00054a1fbce4c776,0x0000b72f3fb5dbd3}}, + {{0x000c5a4b66e99b1a,0x000a6965f5206989,0x000da89d6d7224d3,0x000bf4eb9640631f,0x0000b4e03e0395b9},{0x000436d53d463c5d,0x000f7bf80b6783d1,0x000e25fb34d34e57,0x000cddcb280e701f,0x000018bf1fde0cd3}}, + {{0x0008e7dd3da6ac7a,0x0007068c094dbb56,0x000e7080f6d2bb87,0x00006862db77d062,0x0000957c36387eb2},{0x000c48a3b41f412c,0x0002b40013a5e585,0x0006e05598676e41,0x000588aab2131174,0x0000a5cfa92af35d}}, + }, + { /* digit=14 (1,2,..,8)*(2^{56})*G */ + {{0x000b63b80c17b3a5,0x0009991991724f36,0x000bce681e7aafdd,0x00021571e5eda799,0x0000608a0582bb4c},{0x0001f37958fc7a0f,0x000ed697e5fb5166,0x000a6efe500b7226,0x0002f1da5737708b,0x0000d330af0a0615}}, + {{0x0001d5f271b2ffcd,0x000ce2caa6650728,0x00046dfd327de7f3,0x00027f03178322fa,0x0000216e3f0e2310},{0x00003bbfc59abb34,0x000d842f48027f5b,0x000bd4fb27522c72,0x0007b690faa40cdb,0x0000abded9d9b492}}, + {{0x0002c6f30c43f226,0x0009e180d738ded3,0x0000ae17641d02b6,0x000b5f0756f1a5bb,0x0000e1022d63ad47},{0x000709b3807f334a,0x000c89dd8fffb620,0x0007ad500b84f625,0x000081d766a281b4,0x0000baefeb53ba7b}}, + {{0x000e8143ae4b352e,0x0008432a3326505c,0x00021f9bfe1140f1,0x000adfcfa38d6927,0x000034810d2f90b4},{0x0000bf0d00ef8992,0x0002ffa7e6ab6665,0x000fd1695563a3a5,0x000ad66ed6cd2d22,0x0000bbe464cbfd77}}, + {{0x0000824eeec7168a,0x000ce52877a21ec5,0x0006bed12ba5446b,0x000931ca2300414a,0x0000eeb5b0f5515a},{0x000322d64e381de0,0x0001cecf83cba5d5,0x000840921d7268be,0x000d46dd7f953814,0x00002b466f4b1410}}, + {{0x000bd6a7d881d987,0x000ec843d9325f3b,0x0000379b23abd56a,0x00044afc5a9bef2d,0x00004a3dd4f7b324},{0x00032b0b1e2614cb,0x000de028f61bc0b8,0x000ceba5ab839425,0x00059b798f49085e,0x00003b2eafe5b888}}, + {{0x00020cf3f9601768,0x0005c47f1f0ced18,0x00031285e9324320,0x0008926fa800cc79,0x000017299d89245e},{0x00019c8dbe5b7b2e,0x00054dc1c0f7d133,0x00005341590ca39e,0x0007e40e3ef92196,0x00008544b679b3ea}}, + {{0x0006e673cd25c857,0x000e1717b82b99b6,0x000ce0284257ae21,0x000cd7d6675922d4,0x0000134e48cf8715},{0x00020fa3844dead5,0x00092c4b5f2b89a4,0x0005e6feb94f1d13,0x0001f55da3de9c1e,0x0000bf9802bd31e3}}, + }, + { /* digit=15 (1,2,..,8)*(2^{60})*G */ + {{0x000a6b62d93fdd41,0x00055796424c49b9,0x0007cd56def02492,0x000194a49f888dfe,0x0000f9869f29b9e5},{0x000f96a765fed464,0x0004e6d179483cb7,0x0002157b537c82e0,0x00066411f666f963,0x00007c51bf707ed6}}, + {{0x00083fd5597eef8d,0x000467c051af62b9,0x000a73b96f3d0664,0x000e60da1e9a998e,0x00006cc734074631},{0x000f6191644596a8,0x00018ca65d698049,0x000dcf446dc950da,0x00041ba3b732b22d,0x0000e67d9922451a}}, + {{0x00021487098d3893,0x00021e0bdefdd4f1,0x0005e1525cf8642f,0x000032bc06995846,0x00002ad5c774a21a},{0x00067f595255747a,0x000b83318969006d,0x000e0b7efa7ee217,0x00097c961cb4d73c,0x00007cde45c8bbbd}}, + {{0x00054660dbc8b1ab,0x000d6088cad38c0b,0x000fb6902a066a7d,0x000dc7ca3471b7e8,0x0000e86a1789d644},{0x00095173a8f8b220,0x000fe11a6fd8de44,0x000a5a2626461987,0x000b8a17c44dbffe,0x000097f4a165ced5}}, + {{0x0008066addda0cdd,0x0005a434573eab0b,0x000b19a5f5541137,0x000d0bdfd11570df,0x00000f19e0267d6a},{0x0006506ae95d526b,0x000bfd8f8a3f0b44,0x00099a5c77b8b8a6,0x0006120809e0e489,0x00003bd4cf0ac49d}}, + {{0x000426d74951de36,0x00033f78fca399da,0x00015de0e419f0bc,0x000aabf82fe9e27d,0x0000b79a1cbd8d35},{0x000f1d0d57258a2f,0x0002d02ca81c66da,0x0006f614c6cdf2df,0x0007519ba84fb8d2,0x00009db0a7aaffb9}}, + {{0x000baef6bff2b941,0x0005465352c4b5c2,0x00012d5ccd22674c,0x000b65e5f4926153,0x00005b47a9bf6203},{0x000db83c64adc010,0x000ea6509ed3561b,0x0002da92e6a83a26,0x0008ccc691137023,0x00007a1159393722}}, + {{0x00013e2c380a9bf2,0x000364d391c2a82a,0x00027444dcb0941f,0x00055fbcabcdd486,0x0000ff69ccdcb479},{0x00052b540c86a1b2,0x000a4f04a057a87a,0x000001893b8ba415,0x000c36a44a876550,0x00000e23c958c1e1}}, + }, + { /* digit=16 (1,2,..,8)*(2^{64})*G */ + {{0x000f5e69622c79cf,0x00060c516a0d2bb2,0x000beb03cb372318,0x0004c5d8b0d5cc16,0x0000e18f5d34d82b},{0x000648f91783b808,0x000bf0bf5a01797f,0x000c6a4c687ad85d,0x00067d3523d20b44,0x00009192002a1f83}}, + {{0x0003271e6c831d51,0x00077b8fac61d9a1,0x0002d09fe01d7f5f,0x000a2a4037d25e06,0x000064507e385362},{0x000ea6041214d255,0x00051c0232f76a55,0x000d1178f014410a,0x00037fc788957c32,0x000085a49edcb98c}}, + {{0x000f3338ee1c0299,0x000f84bb5def9961,0x0003040a98f9248d,0x0003ac5761cb69c8,0x000000beb921e57f},{0x00066c038dfaec8c,0x000d10d2f5378a8d,0x00065894c993b6fc,0x000735690acf4c2c,0x00003b9318cab2f0}}, + {{0x000e0341bd6ee336,0x000102bb4d8bc50a,0x0005fb1615b32bf2,0x0005df468181c0b1,0x000049acb4f25f09},{0x0002c9d27e3d254d,0x000f8cf7003e8666,0x000a275ad19d7996,0x00026d7c2f11a6de,0x0000e62e628f9c93}}, + {{0x000a5ff674823c2b,0x0000030614c09004,0x000172a0cbd7525d,0x0008894a1da98d12,0x000030b72f8253fc},{0x000c72e27f2e7888,0x0000eb81d7ea1d7e,0x00029433ef893a49,0x00053356e38cf289,0x0000353f5c728ab5}}, + {{0x000b6b6e1ca760d8,0x0007f19a8afd30bb,0x0007cf16ffb18b25,0x0004823e08679832,0x0000efcafa52751d},{0x0002beaaf58337ec,0x0006f11471f1ff0f,0x0008cb570ffa8731,0x0005ed83ed76c338,0x00004c92081ca03b}}, + {{0x0000aaee181a2a7a,0x000ff32b88756ddc,0x000230d35049ce8e,0x000b74aa4ed4e865,0x0000261c5ca08124},{0x000d55e8ca475a13,0x000dab96c168af3a,0x000f0644ffaace6a,0x00053a1366563c7b,0x00008a47ff05a4d9}}, + {{0x000f835f9d0aad8a,0x000272e523b8bf60,0x000b800dac7dffa3,0x00068eb888009eb5,0x00005af05fd9e53f},{0x00029d4c6fdd401d,0x0000c312afceb620,0x000a13ffebd0185b,0x0006be5b0c797df2,0x00003ac5e2304089}}, + }, + { /* digit=17 (1,2,..,8)*(2^{68})*G */ + {{0x0000b1d093f471bb,0x0006510f5b343bcf,0x000a023f726a643d,0x000ed90df0f2e400,0x00003c3843aa4ab3},{0x0000bb7742e67add,0x0003e95c70816030,0x00093cfe99544825,0x000be16a6e943e4c,0x0000792d7df86acd}}, + {{0x0009c15b35bafc8c,0x000bc1b7bfe71786,0x000dfb7efd32fb77,0x0008ffa7d4e1deba,0x00001f575658ec09},{0x000e07633366d529,0x000ed66368710884,0x000cc4194ecbd474,0x00068764de5e29f5,0x0000a864508101bc}}, + {{0x0002009d82ccc196,0x0002d9731815e696,0x00067adc8a7f6da2,0x000f360af6df9cbd,0x0000fab708e5c748},{0x0008c7c19580ff2a,0x00056d28b898fc75,0x0009d3500789e54e,0x000af3c0972f1eed,0x00002ac6bc3c26f9}}, + {{0x000ff71880242404,0x000f1c7a3e6fced0,0x0005e468a56ae92f,0x0000f9670e8cbbdd,0x0000020c88ed5eef},{0x000f9526f1333efc,0x0008b74bd70437a2,0x00018a76b379190f,0x0004cd66e5fb3289,0x0000132085c0e1be}}, + {{0x000708697faad111,0x000b805a8271d7e9,0x0004c1dd178bfc81,0x000c149eb4735dfa,0x0000d2f552ec6eb2},{0x00048ef153d6518a,0x0004b40bfcc9a0be,0x000c00e5e2afad26,0x0000f1ea67b27e01,0x0000122effb0b8f9}}, + {{0x000484026aa4c38f,0x0009f8c0aeaa3c09,0x000e1764589f8c76,0x000e5ee3a89f46d9,0x000024e2c82b5288},{0x000f97b2a763d952,0x0004d8a87d83b5f4,0x000662574fedee3c,0x000e6c8cfdb2220d,0x00008ad1e213c69f}}, + {{0x000601630c24de4a,0x00030c2c880e5cac,0x000dc7106144a7e1,0x000995cbf8299dbe,0x00009f1a04b80eea},{0x00081b8f5e3ca421,0x00098fb79e7f8ea9,0x00075c1ae32a9ecf,0x00091361be448bba,0x0000009a3ed31173}}, + {{0x000edc4d24ff34d2,0x0005e5192c4d6840,0x00056736a2a84199,0x00067dc208b04d72,0x000091aa355f1170},{0x0000b62c6dbea762,0x00084bf854279005,0x00058b53b37ca64b,0x000f4906c3de8129,0x000017420c7a1978}}, + }, + { /* digit=18 (1,2,..,8)*(2^{72})*G */ + {{0x0004645d0c999206,0x000f55ed005832ae,0x000aac9fd1427420,0x000def2ca5f5efd3,0x0000d8417da6ba53},{0x00015bfe3a91ab48,0x000ad8bc9001d1f8,0x000bccb573cb03eb,0x000ed588452c8f0b,0x0000190d99ea9851}}, + {{0x000f6928ec987520,0x0001acce548b37b2,0x0002556adc5cbc76,0x000befb4fb38e754,0x0000e6f549a164e2},{0x000cbaf6791e178f,0x000242386ce6c413,0x0004d3f2b753e67f,0x0009e6bf901be1c5,0x0000fea1ab006e2d}}, + {{0x000afcbcddc5b4e3,0x0003f6ad7ab9a2d8,0x000cf2fe2c7a8c98,0x0009cf5c29c00090,0x00000a465e1b5bc1},{0x00039efc04140b7d,0x000aa29e99d043b6,0x000b4b1d9836432d,0x0007aac35ef51263,0x00007f50574f8f0c}}, + {{0x0003b25760e88423,0x0009b7d341d81dcf,0x00083e622c18ffb5,0x0007e4badcddb688,0x0000becf33dd410e},{0x0009a60cc895ade5,0x000e3f6a7a73ae65,0x000e082fa7baab21,0x000f729bc83879a5,0x0000c301b48a24ab}}, + {{0x000f2386acf8a72d,0x000604ac3b819900,0x00028ee94251e622,0x0000cfab91cb8372,0x000019e78eaae4da},{0x000f8063ac90f7e0,0x0006d1eb32912137,0x000dda25c7380214,0x00046a9e3a2f82b2,0x00002b889ab4a768}}, + {{0x000a78b173431ac6,0x000037c593710000,0x000074fceaa51d30,0x000c0a565e1c48c7,0x0000087805015262},{0x00044c6adeb5098c,0x000f59dbcc8ad945,0x0006844fc921b6d7,0x000aaf80a70dc04f,0x00009ea6e278d5f1}}, + {{0x000cf86624af5d13,0x000f4cf02ff6072b,0x0008cde126b78788,0x000985309a47d2ca,0x0000c4b1abc9fa46},{0x00028fb8b07c6947,0x000bf87aa9e5cb6d,0x000144b063bc3aa2,0x0003ccd35c98124f,0x0000562b62f1af58}}, + {{0x000915ee22d46e27,0x00009b665c7322db,0x0000faabc5d86f27,0x00004cf85cf12cc0,0x00003fe2633a632d},{0x0000a1c1ed8106c2,0x0002e3ba317db248,0x000897173dd719f7,0x000cd0e5087dec65,0x0000d47fab598e63}}, + }, + { /* digit=19 (1,2,..,8)*(2^{76})*G */ + {{0x0002aabc59c94f12,0x00095b397acf4ec2,0x00003bfdf9e674d3,0x0004780850426c40,0x0000ca04d6eb4c85},{0x0006908d03fd22f0,0x000814c5f5942bc4,0x000db3a0f5e9bc06,0x0001e62ba9a6168b,0x00006bd8a9096113}}, + {{0x00009d21104a01b4,0x00024745a1251fb6,0x0008668a04b75ff4,0x000fe349e967747a,0x00006e02c0c6d4e7},{0x000084a333d89913,0x00059a82fe122271,0x0005f3a1a369f264,0x000fa053caf9b5b9,0x000022f6b350187d}}, + {{0x000f36cba7ccb6b8,0x000008210395755c,0x00038f8b13d90150,0x0003ea696117ce63,0x0000c5fc7ad16c23},{0x000e0dbb58d94e9b,0x00051a9a40ebf884,0x000f65c5c2b999f2,0x0006d5effe6ec1bc,0x0000b7559295f5ad}}, + {{0x00048ff65b341317,0x0008233aed1d1f71,0x00033bc63a356251,0x0001b22cf566eaff,0x00007f53d3789579},{0x00086fa303582c2a,0x0005fd4cf94cf0dc,0x0003899cb5afac02,0x00035800d319bec8,0x0000afb9e2fd22fb}}, + {{0x00033425fb22b5b2,0x000c99c7ea2ee345,0x000bb698147612e7,0x00068f17a3fd0d94,0x0000828ad54f2117},{0x000657e7e87abddd,0x000bcc3810156e0e,0x00034a697c600213,0x000a648420ea020e,0x0000d279bdaf20cf}}, + {{0x000f31d817bed07d,0x00055ab5c8b06d5c,0x00022f1cd42f3db3,0x0009efa79b1a785a,0x00001ca931baa4c5},{0x000b66d8a740682e,0x000d06a15d7dc85d,0x0003d89a928be329,0x000b486c72f132b0,0x0000478e55d53bd7}}, + {{0x000bb6e6b0a9a305,0x000098b593d070f7,0x0005d69e7bacb02a,0x000d6fe994375751,0x00009b830bfbf6b1},{0x000cb4666d9987a2,0x0001462334c0922f,0x000e103fb50bd914,0x0006b82023df631d,0x0000f49e7f2f57df}}, + {{0x000e23139482dcb9,0x0001ee1adc1696fc,0x00023caa5f3be88a,0x0003ebb3598ebe59,0x0000801aabeabc49},{0x000560a9c8a8fda0,0x00082d4db067df91,0x0005b59ef1377a4c,0x0000329c198dda09,0x00005daf596bd7b8}}, + }, + { /* digit=20 (1,2,..,8)*(2^{80})*G */ + {{0x00064232b86345c6,0x000491cf1c367cab,0x000b12cd89c580bf,0x0005b4a329bc85a9,0x000061507757ea7e},{0x0007fbd8ddb9611c,0x00062b0167dad297,0x00011cbbb1d53bf6,0x000c8188b1604f30,0x00001f4d0fd7d22e}}, + {{0x000eb572d99661c4,0x0008402fcf0a7fd8,0x0008c5d33d449b8f,0x000f0f09842fd078,0x0000da7983de9402},{0x00076f6bdb01f785,0x0001f4c4d194a88b,0x00090292128bdeab,0x0009129fcd2b63fd,0x0000ebc377dfedf6}}, + {{0x0009a1904af269a5,0x000ee2c68af43eec,0x000da69b7072b08d,0x00046bcf55502468,0x0000f80ea4ac443d},{0x000a17081f1c5679,0x000da8d470c56a4f,0x000e1f2684ceb758,0x000ba15f3159abc5,0x0000964c76954003}}, + {{0x000943b9b2fa6dc9,0x000e0b2b4b4b67c8,0x00005ebe4c512574,0x000128fd8c1d10df,0x00006e0e8ebb49c2},{0x000b34a5656dfc03,0x000d6143b3def048,0x0001c1b2d09a22f2,0x000c08d4085ab3aa,0x000060432732650d}}, + {{0x000d702cfbe0903e,0x0006ef88e2f7d902,0x00074a4e05d17b88,0x0005b20e9fdbf33d,0x000010bd286ddbf2},{0x000dd0fd8fb34fd8,0x00013db85c88ce89,0x000b8030d8880391,0x000235bac23a3ce3,0x0000fa45c03bfea3}}, + {{0x000be6868dc83e03,0x0005e0798fa7aaac,0x0004248d23c0ea74,0x00098ae9b41209ee,0x00003cedae7fcc2a},{0x0000a5ccc7b9ebec,0x0005fdc32c04dd3e,0x000def4916cf5e80,0x0009ad4cfa6c35fa,0x0000a98de7d24b36}}, + {{0x000fd321053b8bde,0x00015a36fa6110cc,0x00012bc0351a15e4,0x000cb742b74fb1eb,0x0000cad7c54d4248},{0x000d56251a7ec868,0x0001ca2cc80ad571,0x00056953911caea0,0x0002c80cd7c27fc3,0x00000a95d3fdd32f}}, + {{0x0003858b5c81bd3f,0x000d2a9431dd80e8,0x0009efaae17d3682,0x000f67830eb7c7cc,0x00002f1f3290cd4f},{0x000990a639034a2c,0x000a593b6251d5c7,0x000299c23319bc02,0x000b194511cca1fd,0x00006f501add6b8d}}, + }, + { /* digit=21 (1,2,..,8)*(2^{84})*G */ + {{0x0006beb87707b7a2,0x000c72a87dec0e16,0x000d90f4e489ddf2,0x00017feb5010ded8,0x00009f1c146a514d},{0x0002ae989277487f,0x00076313476cd0e8,0x00052ddea0b6d98f,0x000ff20c6a63d0e6,0x0000d40ea3d516db}}, + {{0x00019c667d0d91d1,0x000e8105ca7d8669,0x0001a93ed4b79dc6,0x00058efbc582967e,0x00007205a3aecabf},{0x000187f1f85aef05,0x00012b160f5dcd7b,0x000f2c42bbc43ffd,0x0004562f5ec697b9,0x000026b5000648eb}}, + {{0x0000d41a77c52336,0x000441d214aeb181,0x000c6340187fcbdb,0x0006e6ac41506af3,0x00003b6fa4818220},{0x0006bdb65cf1fb29,0x0003ce4a84bde96b,0x00083b4cb3bfaea2,0x0008473e742f060d,0x0000fba067aea100}}, + {{0x000b6c2d46254ea3,0x00039b6ec7fae9f1,0x0004d44a4114c60f,0x000f5ba52995f271,0x000066e8cbd34843},{0x00062c42a011d210,0x0000c318129d7161,0x0000f32c7f0a2090,0x000229f63b03909f,0x00009687ec5c5909}}, + {{0x000507db0a04df74,0x000af43753b9371c,0x00099a17c1cd2a88,0x00066679629cab45,0x0000a296edbca1ad},{0x000519b397e39c16,0x000e052af036c326,0x00079fe7dac46a92,0x000efcd5086f0cc7,0x0000bf3f8cd63cc7}}, + {{0x00042e43a80c6fad,0x000b1ef9c053df72,0x00078ed2a6c7dc5b,0x000da22fb8de25b3,0x000063c34563eabb},{0x00066648e3f185ac,0x000a5f4dd6f958ec,0x000f2dde11a9f374,0x00087dd496925a77,0x00007412068d6cf7}}, + {{0x00005e399e662c0f,0x0000a57173e460c5,0x0004e0120bf24c7f,0x000f062621bbbce7,0x0000fbd676e31f74},{0x000bef99ec94a32a,0x00023cb57797ab7b,0x0009ae3d0efbd3a0,0x000900cc160ad35b,0x00000124b141f449}}, + {{0x0007c8bdf49d7f19,0x0007df31711ebec8,0x000f46d03fcfcebc,0x00035281f2da40f1,0x0000aacf4dcfdeba},{0x0004907c5d800621,0x00068e3c2eef12d5,0x000ae7e3f5965a34,0x0000ca494de95bb9,0x0000c88b84c6fe58}}, + }, + { /* digit=22 (1,2,..,8)*(2^{88})*G */ + {{0x000cadd1a806623b,0x000e2b6f79588c00,0x0009a8a99724a1aa,0x000f2088afa52fc6,0x0000f705025b0678},{0x0009b5b7e0f923c4,0x000e2b31803dd6fc,0x00048c34f654baea,0x0000a8a16488e4fa,0x000078ce7289743f}}, + {{0x000c047df2f3ac76,0x000c2b67c4a658ad,0x000864e2a38fcd7a,0x000ec6e4fb3c4763,0x000051531fb65393},{0x0005e4fd59db390b,0x000c9c55e59d92d3,0x0005b30150334900,0x000919016cedca47,0x0000584c78dab3ac}}, + {{0x0000d9a50b845667,0x000a70683a7337bd,0x00042f134d3dc726,0x0004c501f1e3416d,0x000077d800d0f3e2},{0x0002ade2f283b9d7,0x000aa506fe28ef7e,0x00054084698d5e5f,0x000e17b633cc5ef1,0x000066c31b2862f2}}, + {{0x000fc8a61448916d,0x000c74f3a29467a3,0x0009855614595002,0x0005455f2de81e94,0x0000c7e3b2cd575d},{0x0001458e271cf38c,0x0006c8f06d0de9fa,0x00049a303fe35dec,0x000c8fbd5bbc11cf,0x0000091b6978a5de}}, + {{0x000d37663e141628,0x000a0c7dacddb7dc,0x0003b0e7766eefa0,0x000f1de3392ed500,0x00000be7c32df13f},{0x000ffd3cfb24917d,0x00007c5f365b7cc3,0x000aa79e7c6214d8,0x0002056c1294e3a2,0x0000f07f35bd7c03}}, + {{0x000ef267775da03f,0x00054e3abb830d13,0x00021d39eaf8a67c,0x000aae69d2ad2353,0x0000cecdaaf36b90},{0x00073f3903ddce42,0x000b5039b0d7d86e,0x000c943f361c4d2a,0x000faa09580f5af2,0x0000f9ac892638f0}}, + {{0x0007e7ed58b7eafb,0x000a211399f9cf33,0x000de654563b6e7c,0x000addff178e7a48,0x0000fb88753b9155},{0x000f8b801c68011b,0x000ffd43c8aae72e,0x0004bce716798b71,0x000c168527878be9,0x00007ce2d9d5e353}}, + {{0x00072002d0deafc1,0x0007568e039c2560,0x000b74f7fa8c3e04,0x000fa452b5f26fb8,0x0000d5c673e4de9a},{0x00094308345d1eb9,0x000e937e84fb7e3e,0x0000233f0b08ef7d,0x0005f8881b401d8a,0x0000861e80d65e10}}, + }, + { /* digit=23 (1,2,..,8)*(2^{92})*G */ + {{0x00076ddafe513028,0x000b231be24319a2,0x000bb927cde9a7fd,0x00047f98503f7d28,0x0000bacef2354247},{0x000e4d52a90363e2,0x00072961d7a64eb7,0x000900d06b997d69,0x000d4f0d5e436088,0x0000deb49837ce80}}, + {{0x000bb2d0d12e52d0,0x0002d9d615faa8f2,0x00006ad2841c4cc3,0x0005178828fa1eb4,0x0000037e5443ad4c},{0x00018eaef0ca0cd3,0x00057646caa6d2f2,0x000e0158862a3d51,0x0004399628eb879d,0x0000cd6553865dd0}}, + {{0x0000a94af9ea7cde,0x00069d83d30a2c5c,0x000e36e136e23569,0x0009d6c9b0857f77,0x0000ee3ba9363a28},{0x00091c4d690c1482,0x000da0bdaa6ec1a9,0x0002efb68a84b025,0x0004cc597ba9fe49,0x00009c2e3b6a4baf}}, + {{0x000f0606c39967da,0x0008ecee978a1d35,0x00031bb32640de50,0x0003dde62e3a68b3,0x0000e08b646ad0ee},{0x0000f5f9d3887578,0x00046276f9326f11,0x0004b608425a9f9f,0x00069fb512f521c1,0x0000178ec5cbaa24}}, + {{0x00019c380abd55aa,0x000a2e43d34a2e3f,0x000dc29f25566282,0x0003bdcc7ee3759c,0x00006455153981a4},{0x000fab2b4f7c81ad,0x00074aade744b1f6,0x000ff14cda1c443c,0x000bd5111a7d222a,0x0000a28194e30835}}, + {{0x000876812dab14b9,0x0007f78a4d32282f,0x000c4f8b89ba0bce,0x00094fe50e36e029,0x00004692f67fcd8c},{0x000d3eea24df7225,0x000ee8ed23a17f08,0x00006374aae9a53a,0x0006455e06d7b448,0x00001b31dbe9cf50}}, + {{0x000a821ab5d22890,0x0001522b99a72cb0,0x00077cdf65604ed9,0x000cad53e06de6e6,0x000000279f3d1814},{0x000490a31fb979cc,0x000d92b7cb0b5a2b,0x000c1473e470c4c5,0x00054393aa7fb121,0x0000cf1f5b79004d}}, + {{0x0007d51e7e42a51e,0x000f444c5f95cd80,0x0000ecd677766dc5,0x00040656dda8c8af,0x00007a567e594477},{0x0001a1b8848c495f,0x000ff6ac2ccbcda6,0x000f23870b5b7597,0x000568bd43bc1923,0x0000956dd9ebf318}}, + }, + { /* digit=24 (1,2,..,8)*(2^{96})*G */ + {{0x000589fb928c5f43,0x000ab31b0e63d348,0x0002245b5418c388,0x0008872a4f460057,0x0000c3c71e7aa249},{0x000bb0696dee0485,0x00070cc6583553ae,0x0009f6a5e077bc6c,0x000ffc1520879094,0x0000bccee4609921}}, + {{0x0005aaf668ac79d7,0x000433ea2dee7a63,0x000c3da02c1bc912,0x00031cfaddcde2f3,0x00001022732669a2},{0x000b89dea0558e1e,0x000e6a9e5aa049a6,0x000d25865fe4287c,0x00021cec3e74083a,0x00001aa8b5c32deb}}, + {{0x00040e7bf97f20a1,0x0006d0399375235e,0x0006d582fd773a7e,0x0002e1f677614c84,0x00001999db61efd3},{0x0003489b6ccfa05d,0x000a931ee4c47744,0x0009f7bbf5dfe5c6,0x000fd75266f03847,0x00006555c655bd0c}}, + {{0x000be00843e7b7e6,0x000b723fe67ba665,0x000037ef26f02671,0x0004513139145076,0x00001e80333c65b0},{0x00067e7cf2b69e56,0x000e805d53ff04d3,0x0003276aa2047eed,0x000006ba0bf7ccdc,0x00008a2d8826cd00}}, + {{0x0003d241c54ab435,0x0009d27cc2338fb4,0x00094d101f8dfc4b,0x00065cb7689ff6fa,0x000074c538fab3e8},{0x00070471a2ea65d5,0x000e47dde9b62a31,0x000489a9bf481367,0x000580a7d6a06e98,0x0000679d2079dd65}}, + {{0x0009f3c5562d73af,0x000f9ae3113655ef,0x000a5dc46c2ad1e7,0x0006d3bbefa2c6e2,0x0000ec4fc810c34a},{0x0006b238915ff4c1,0x000af22a42581cb1,0x00020244d851d41a,0x0003999a8e1de0bc,0x0000d237a6934d96}}, + {{0x000987f8338f6cc0,0x00059e455950cc3a,0x000bad2e7384a6a9,0x0003fad84c71d665,0x000016cfe8130120},{0x000a6c81f092f72a,0x000fd727a79a6a7a,0x00073800ea330d7c,0x0001f541056e5d01,0x00003e66db6185a5}}, + {{0x0009356a79debb8e,0x00065b7b0dc85957,0x000825e834b42de6,0x00021f4a727de460,0x0000c18079e2bfdc},{0x0003b0bfe5e20c23,0x0000045f5f9a0529,0x00087fe98313de54,0x000411dfc1a8b0f8,0x00004e039a515ca2}}, + }, + { /* digit=25 (1,2,..,8)*(2^{100})*G */ + {{0x0009d20f961c2e82,0x000b85dc8de610b8,0x000ade101437f35a,0x0007eebc5e8c515f,0x00002509d1321032},{0x000842e3dac8ba0c,0x000fd66098583ce0,0x00048bafc3fcb163,0x00076414aa2eedb9,0x000007db9f48bc83}}, + {{0x000595c4b3f8dbd9,0x000359d74cd06ff8,0x000f270e29f8a825,0x00087d12b9c17c7d,0x0000b2e80e811f87},{0x000db27ce43a86c1,0x0003fca990f62ccd,0x0002ec59bf016957,0x0000628f5d9bed21,0x000027d55a4ba6a5}}, + {{0x000d03f718913dd5,0x000c2befc15aa1ee,0x0007c847102cc8f2,0x0005c8a1240d1254,0x0000fdffe724edc0},{0x000f68ea1cc2db7d,0x0003e6c4a02c4997,0x000d509587b544b9,0x0005f5faff725083,0x00002c702007fc4c}}, + {{0x000d112927153319,0x0003f1d26ee83821,0x0005188c3a678749,0x000f5953dcf17dcc,0x00006ee6a46384a1},{0x000b8bdb94fd5a59,0x0002b7750491a746,0x00019255042413ef,0x00049dcab687fa76,0x0000d3bdf3fd8d81}}, + {{0x00073eb5de6f16ea,0x000838af7f91d0f2,0x000180eba14a2d69,0x000c07d543b61b0f,0x0000a48e18374f25},{0x0002413c252f7b56,0x00055f77b4e4d538,0x000f5bfedb51fa0d,0x000d51bb3b7ce66b,0x0000bd4cf4850d41}}, + {{0x0005fe87134cd0da,0x000a17e3cc8ac855,0x00078703ee282882,0x00067052f8d725f5,0x000030f3d852516a},{0x000242d3ae1ef785,0x0007fa96ab6b01c8,0x0008fa96637638d6,0x0008ee49b69a02a8,0x0000dfec375d87b0}}, + {{0x000f921d710cc9ab,0x0008a269be47be0e,0x0007db96e1305cfa,0x000a2bce5323b7dd,0x0000b7178cc6492d},{0x0006c2921097b191,0x000d0fc3c4b880ea,0x000df1d178576177,0x0003f6e393f6f914,0x0000ac9a7fe9fa67}}, + {{0x000bc95725aee3d5,0x0002ea553fb2b560,0x0007423c28530356,0x00000bbd96ce141e,0x00009b1c7fa39ddb},{0x0007326ca7661923,0x00044911220fd06a,0x000b99589f2eb8ac,0x000d2c8a9716e3a3,0x000016f0b4225082}}, + }, + { /* digit=26 (1,2,..,8)*(2^{104})*G */ + {{0x000a527e6b978cee,0x000db82cf7d62d27,0x000ca96802e48946,0x000e9519e1f36e29,0x00007265e87b84fa},{0x000802786e991660,0x0003097581a85e38,0x000f541313771b92,0x00067126e1f1a520,0x0000d10aa19b0e7d}}, + {{0x0006f0af00724aea,0x0002a9e36f09ab05,0x0009f3200c5b7d67,0x000971f9803f163c,0x0000abeb83ab4494},{0x000dc4a79b89e736,0x00099ec70880e0de,0x000ed078e9a3f10d,0x000e77ebd7332a66,0x0000efcf0956aef4}}, + {{0x000be864b03d7cc0,0x000d4d1f4c6b6ec2,0x0006eccb68ebb96b,0x00094bfbf526b082,0x0000a5858dadf7d4},{0x00072e6a44328071,0x0001da542099b646,0x0009a026229e5471,0x000dbab9c2770b28,0x000007628b15e3f6}}, + {{0x000dce3782cc4229,0x00054d0c55c44969,0x000687ed744ff73a,0x00095ca63a6a9635,0x00006189f2556fe1},{0x0005e2f1f92bf8e0,0x000c16ab2b91f71a,0x0002b5bd2443b5ec,0x000ec35ade448982,0x0000c8788b8a39ca}}, + {{0x0004a1f390200e56,0x0008cc847c643671,0x000f310d5b30aabe,0x00025ae2c6a496b9,0x00007a3574996340},{0x000eafc1730bb4b0,0x000e3633ef1f5404,0x000a23f7ac20dc45,0x000363451d323b30,0x0000fabcf3b74204}}, + {{0x000392b0b18c6d03,0x00098e7abded5516,0x00086524935ee7e4,0x000a3d6a903d358b,0x00006875db035981},{0x0006fc5d51954294,0x0000e980b75c904f,0x000db1fb9c1ad202,0x000ea6532c305b0a,0x00001aa27478cb82}}, + {{0x00014710f8720b12,0x0004851b3e59b897,0x0004cfec90d17238,0x00000dc591361395,0x0000dc88b86a7ad2},{0x0001febd7319c15d,0x000eeced6c446c96,0x00060a4e95f5a70d,0x000a79f37e0aa7fd,0x0000ca962020a7e2}}, + {{0x0008f862ec09473d,0x0000ac9d64cc78c4,0x000b52744f8f7011,0x00038e5ab6c50621,0x000008c758760cd6},{0x0006d3b2c6ac19b7,0x0007bede1603c166,0x000ef5c6e18a250d,0x0000ffdfc19a80e0,0x0000dc276b838e08}}, + }, + { /* digit=27 (1,2,..,8)*(2^{108})*G */ + {{0x00011cac13161f9c,0x0001bbc453cadd69,0x00072aef15e577c3,0x0008c37af203900a,0x00000e41db5e3490},{0x000b87d44a487f26,0x000dc42ec965469f,0x00012e582d33e4d5,0x0001872850e9f769,0x000038b03659451d}}, + {{0x000da8e4f1aff818,0x000caa2d551ee106,0x000804d524b4b06e,0x00008fc8d87a8f1d,0x0000ef431fbeb97c},{0x0000c0d9b00298e4,0x00033f0cf9a4e718,0x000fbb34f16943d4,0x000ca08c0ff50200,0x0000745ea7a228cd}}, + {{0x000f1e0fa64b9ba1,0x000a4ff1d7aadabe,0x000fe6d896d5ce68,0x00034116f65d3825,0x00007bcae08c6246},{0x000ac54f612c30f9,0x000ceba33db72cdc,0x00092fb725511bb6,0x000d9573c017cbc0,0x0000a29dfebf2fc8}}, + {{0x0000903c4cbe46bc,0x000c0eb1bf4581ca,0x00060c177519da3e,0x0005066ace635e18,0x00005345445cd5a7},{0x0007197ca469b8c0,0x000858948f214029,0x0004225140fdccb5,0x00087719031b49c1,0x0000a2053b8e6576}}, + {{0x0002dda543915e7e,0x0005f5d4b07e2b19,0x000afac0fcdde015,0x000a72d14d144c4c,0x000034e73127607f},{0x0002db773ecd3720,0x0000fa8cf03dce66,0x0004b74758be1c61,0x0007668c48b5ea96,0x00009b6250934072}}, + {{0x000d7803581ab555,0x000eab4820357c72,0x000e419c5554fe07,0x000fef5a1992039a,0x0000d9875b456d0a},{0x0000ee0ea7058063,0x0001b4dc77ad4d4a,0x000858f1411d534f,0x000f0bd5ed49a799,0x000050a8f7fd0e17}}, + {{0x0003cab91b752141,0x000a5e89c92b2350,0x000e676eda85d689,0x0001c8f31a73bbd0,0x00003841c3e8d0f4},{0x000cd61ad4ee96e2,0x000a42f1db3574b2,0x000537e4eb45e77e,0x000813c06485b018,0x00002be90410b3b1}}, + {{0x000add5f69c02408,0x000d61cf3480d4af,0x0006c1ad6fb043be,0x00005529cf0d8edc,0x0000e6b784db99a8},{0x0005a454130bbd68,0x0002fad96f8acb1a,0x0004c17786cf7d98,0x0001fdbf4bddd49d,0x00002c7d15e91516}}, + }, + { /* digit=28 (1,2,..,8)*(2^{112})*G */ + {{0x0003c0440fd7f2f9,0x000bdbfc360e25a8,0x00048399d668b4f6,0x0002439f4e642519,0x000089f1fa0b9870},{0x00097b3d282ee427,0x0008cf1d720281f6,0x000e67baa329978c,0x0002104e72205910,0x000061a43a34e6ac}}, + {{0x00071279a45648bd,0x000de9afb3ff9ed0,0x000b10e3d7b7d810,0x00004e74928c2e0a,0x0000f66bf52858f1},{0x000e9fccc7111eb0,0x0004f6601fbe8556,0x0007f13a84fd868d,0x0003acc0b3ee394e,0x000011bb82692f56}}, + {{0x000f57841f3144bf,0x0001f9314092ebb4,0x000cf3369fecda45,0x0008e3164f17256b,0x000033b176e2d462},{0x000333e4efa6df27,0x0001d05e708d8553,0x0001d0bddee0a802,0x000f8c7d5856aae7,0x0000603c90846016}}, + {{0x0007512e2eb6a7c2,0x000b8dedda492f81,0x000a60d843d6851f,0x000eb594cc11a3ae,0x0000e9fde037b87d},{0x000cf109a400a483,0x000c6f3177bf8b6c,0x00093bd6f59a5d1e,0x0006c915d232ea4b,0x000066d0031672f4}}, + {{0x00008a54ec2b1382,0x000f888a1f258972,0x000f812b7fecbc4a,0x000e06b5c7ac6961,0x0000e7ee6a3486dd},{0x0003eeb9a9acb8ed,0x000811978660710a,0x00067f8f391f11c9,0x000b760a50cf70a9,0x0000a64a54a69740}}, + {{0x000869d0d5ac68e0,0x0008233169bca968,0x0003a53cda259d70,0x0005a1a9404d286d,0x000088e4951616f4},{0x00052a733ab82011,0x00026e5d0150d651,0x00030ee1a18ef179,0x0006e1c49a92e250,0x0000660861970a58}}, + {{0x0001843074252dfe,0x0003f588434a920a,0x0002c09cd3518f04,0x0005fc19ac0af8e9,0x000065ea1ee67b6e},{0x0000581fc169a790,0x00004aa5447ab801,0x0005b7021d9fcb63,0x000998a9ee5e5a32,0x000086ce09c0bdfe}}, + {{0x000b0da855c77138,0x0004d7080eb24a90,0x000d3d8064a79971,0x000e895b87bedfb4,0x0000ff2e824b81fa},{0x000939b48c4a16ef,0x00015dbde314c709,0x000bd2f933b9e136,0x0004c0d9ecdbf1fb,0x000042e460791f67}}, + }, + { /* digit=29 (1,2,..,8)*(2^{116})*G */ + {{0x000c8ac9b3f30faa,0x000821f711b0eb9e,0x00078b7fefa0a379,0x000f7e8dbb905f2c,0x0000d9b3674355ae},{0x000e568622b92879,0x0005fb6b40a24474,0x0001518d75018f42,0x00065c23f60121fc,0x0000b6c0f8efac61}}, + {{0x0002b23a10647092,0x000b4c64a8a3d626,0x000fc1c509c1f5da,0x0008752338469c4c,0x0000592d71f92d24},{0x000e65e5e66ab21c,0x0007ab4a63d1a4c4,0x000a2eb259587d83,0x000fd941c454e7fe,0x00001e808c047aac}}, + {{0x0003840fe88767bf,0x000b8176add85450,0x00066f408b7e5e73,0x000da5e771b71cb6,0x0000d35c39b650e0},{0x000174cced9e5822,0x000b8d51ec699775,0x0008df0a9a391539,0x00071f40cae243fb,0x0000e2156e1d8e4a}}, + {{0x0003c2f435522de5,0x00099b6cbc613e57,0x0004d5bbb1e76fb3,0x00050f9d533131d5,0x0000500dd4c4695d},{0x0006451f5801b985,0x0009f93a4a375fa7,0x000c41eea66a4aeb,0x000b4eccf5f06787,0x0000be0cc26ec73c}}, + {{0x00000b6c75700e6b,0x000408495fe1347f,0x00087f18e3c6eed8,0x00078726bab0f6c3,0x00006a00813e85d4},{0x0004f3ad785966ec,0x0000da6a78629992,0x000c99e4f0adef59,0x0001d2deb85e5a06,0x00008ebb465036e4}}, + {{0x0003d92b271a34e2,0x00021fc6c68d6876,0x000cbc1727a04409,0x0009c8c7a3e732c3,0x00006da92ca67f54},{0x000e2c06175bb538,0x0004abadd44867cb,0x000e3a947ba1a418,0x000b74f85a71b4a9,0x0000e7099fa89017}}, + {{0x0003b5fb75d8727b,0x000f2282bcffbc46,0x0006a334e0047ac4,0x000c33369708817a,0x000053e4b18d8ff4},{0x0005f5e93d863d2a,0x000bf53e7fe08c4a,0x00044f8de0daeb8c,0x000aaf25cb4d8bfd,0x000075bed4b944bf}}, + {{0x000274dcf1b355e8,0x000d5ef694db7e04,0x0007778800d4cda3,0x00062f4e1edca878,0x000092c279274250},{0x000be2b2abb3de8a,0x000b9b86def6d1a2,0x0000bff865bb4348,0x0002de558d25b167,0x0000a14c44f5e051}}, + }, + { /* digit=30 (1,2,..,8)*(2^{120})*G */ + {{0x000da4a7963ed790,0x000cc9dd111f8ec7,0x000d3a203fc9ff36,0x000619a51bcc33f8,0x0000c3316282fb7e},{0x00058ffec2ca8e3f,0x000cbe30bb1151be,0x00071d53238e4f7c,0x000c05f7854febac,0x00007acf3890bf9e}}, + {{0x00066adbf6bb7535,0x000ff9d29c4120ba,0x000f1a65fd1f4042,0x0009b85519f94391,0x000007d911a8b098},{0x0008234499aed7de,0x000763c34bfca38e,0x000fd1be8863128c,0x00048439ce0f2755,0x000013608ea8ba39}}, + {{0x000b6304a752fd49,0x0007c13516e19e45,0x00076a61d0ec2826,0x000e9d5f656e2e84,0x00006c970cc1cc09},{0x000935381bb3523e,0x00069363ab7e433f,0x0000053ef767b2e6,0x0002d839f1adea47,0x0000b39a71be38a8}}, + {{0x000cb10d572b5962,0x000ed9d918e49366,0x000645a02c2b89f6,0x000f43ab965035ef,0x00005fc3fbf56b43},{0x0007c7032b9ad449,0x0000eb7a242da112,0x000d3f646f3cae05,0x0002e606b16a4d3d,0x000066b08ba950ea}}, + {{0x000fa003d16724c1,0x000aa7d5846426f7,0x0008a4dd404bee11,0x0004afe48e7d09e8,0x00004e388ffd7c0c},{0x000d40da8e2b1cbb,0x000a64f17fd95965,0x0000d88abe4cfada,0x00066ec6a49e0e0a,0x000085fa4175ed03}}, + {{0x00089bc84468e031,0x0005ab4a595939dd,0x00084fd839d2cf16,0x000cd45120355647,0x0000a31eb877381b},{0x00012d8643774d44,0x000965d85a9184d6,0x000b3e932a3180a6,0x0003d448e562563b,0x0000bf1cf2a46781}}, + {{0x000d03d7d3318572,0x00049a354530bb24,0x00077e0492176e2e,0x000bd9f63bde3ef7,0x0000086e3e2a72d9},{0x000280da9fc53e22,0x0002d9e43b6a782b,0x0006ea07cbe66e70,0x000c1cbd9216db30,0x0000dfa49ad0403b}}, + {{0x00048234a455944a,0x0003c913e538cd75,0x000c398678aeeffb,0x000c8cbffa7001f6,0x00008153cadc4269},{0x000cbd665cbd5dcd,0x000d02d3d5b40458,0x0005bdd2db3441fc,0x00002b28bb0ffeeb,0x000086864413478b}}, + }, + { /* digit=31 (1,2,..,8)*(2^{124})*G */ + {{0x000d41f01735a335,0x00073f833f6746cb,0x00054167a0b39250,0x0003a7ba921e46f6,0x00006c09c11aae95},{0x000d59e95785f38c,0x000b834426ffb589,0x00057781d8acae7b,0x000a30f7f8055943,0x0000f1dc76c3a6d4}}, + {{0x00097ba641eb7f97,0x00074a9b733aa5fc,0x000b26df4bf350af,0x0002ceba5dece47c,0x0000cc1ae7e7d3b7},{0x0007fab43b1d99a8,0x000ad0409c110608,0x0004beb49cf2a615,0x00058d94656ea2c0,0x0000cf90618174d6}}, + {{0x000a41e9fa25ab62,0x000af5c775d6ece0,0x000bde7efd93c9a3,0x000b19a8169d2e3b,0x000085cb8fc6f6ee},{0x0005f7b3cfc01d0c,0x00027be909a1f0b1,0x0001f4efb7604d75,0x00015af69150a845,0x00001a9458cd6746}}, + {{0x000b433b59bb0813,0x0000341d4c5105f3,0x000e323c820b4e81,0x000deaab01ae80f8,0x0000ba1d2bfa0603},{0x00002fefd81e661f,0x0004eb693e856387,0x000273b996572680,0x000f613ecf7b5925,0x00002889ae807f47}}, + {{0x00070814d5389736,0x00073141339609ae,0x000d572fd5e8361d,0x000f5579c2b627de,0x0000b93bcfa4fc39},{0x000b4a9a9b91c818,0x000435717398d14c,0x0004b4b95c2dbae8,0x000ba7a759d37d25,0x0000ea36d4f85bce}}, + {{0x000489527486828e,0x000dc5c97290293f,0x000bdeff5a4b77f2,0x0000edddabf04a19,0x0000608db4f55ad8},{0x0004f5d47694d29d,0x000e1c32a5923d75,0x000ba8eaeefa4a0d,0x000473bfcc7bc949,0x0000b5fd2de9fe6f}}, + {{0x000e65bcd4111964,0x000a1f7d13fb27da,0x0002be0bd8ecb0f5,0x000e2f2c5c05b30d,0x0000ff05e9764421},{0x000cdc5908086e16,0x00094b8630d99eaf,0x0005e9509364c388,0x00080bcf1164be81,0x00001478d33e9527}}, + {{0x000e89f3d33e658c,0x000bb5d0fefb0c3a,0x000a984dcf89f8ee,0x000d20ca4d48fb56,0x0000b9304c4e5ff7},{0x0003083bb07dcf66,0x00023c86363d14cb,0x0000b4a396cd193c,0x000063a218981752,0x00009e66befec3c7}}, + }, + { /* digit=32 (1,2,..,8)*(2^{128})*G */ + {{0x0001d587d483a8ac,0x0001644bfe209256,0x00032e076092df00,0x0008fc46391c19ac,0x0000ca7c69ca0159},{0x000a11fe134033ed,0x00086a2a37173eaf,0x000759658d52a842,0x00086c73e2384800,0x0000d0571a330ac5}}, + {{0x000617ff6bb8909f,0x000aafeb8a24a205,0x00019f14a5d36b68,0x0006aa95317ebfed,0x0000c8fde1bb5304},{0x000967ce0fa78f8e,0x000a6c5e3c99ebdb,0x000d5e1c475a7c8b,0x000cdd9dffc64242,0x000020302e081fc1}}, + {{0x000418871e270c0b,0x00029a3b23358342,0x000a6cd6e14299eb,0x000d6b00d9526205,0x000018ce7f6af8dd},{0x000fdb3c22d19812,0x00064814082c1576,0x000fb9e6c451057f,0x000efd528cc914ac,0x000020534397c913}}, + {{0x000e205c1544399e,0x000710441c23fa36,0x000053783e19700e,0x00068fea7b4712eb,0x0000a112e4fbfa4f},{0x000514d89ca1abfd,0x0007c57b36416860,0x000d4097b2b1ef2f,0x000a206500432691,0x0000b3a43e7e1054}}, + {{0x0008a5b251a46688,0x000c41c2cf9d7c1c,0x000a25f0335a2815,0x000478f0c1320886,0x0000b3973c66051a},{0x0004dada9450a7b7,0x0005d32c11d23031,0x00020a289c0afe30,0x000abe1287da6691,0x0000967694826933}}, + {{0x000ce5870a0c41fd,0x000faaaf0dcbc49e,0x000883d62d516f72,0x000eaa5e57de551f,0x0000f8ef2d69da92},{0x000ff5e2f5425d4e,0x000c0dd167d79ae1,0x0002da879bcbf034,0x000d36191039df8a,0x00004f16c971cb78}}, + {{0x000aee99a83de201,0x0000551cbae2f701,0x000578bc0f4313d7,0x0003bf399efc4bc0,0x00004db1c0ede19f},{0x000c5f317b20b8d4,0x000b1b9ae8274c57,0x000500d18221751b,0x000091b816c14d44,0x0000685f584b909c}}, + {{0x0003bc3770684e62,0x000ca6bc4fe3c395,0x000318bfb46f7b63,0x0001ad259ba4a815,0x00008206cce146bd},{0x000c2731bc0908f4,0x000d4ab5afc60db8,0x00049492c0e73d3c,0x00006d107aa02235,0x0000a2cf845790c5}}, + }, + { /* digit=33 (1,2,..,8)*(2^{132})*G */ + {{0x00044ed736b966ec,0x000a5c2e48fb8898,0x0002f73bc5cfb109,0x0001bb4e226882c1,0x000063d7619b2c62},{0x0006a413e95e2beb,0x0005c6fd86e27c75,0x0009ae0bdbf2ca03,0x000edf84da04edac,0x00007492ad45d302}}, + {{0x00024f4d696da3cb,0x0003b1d5a74be506,0x00047c52228c154a,0x0001bfda2e41781c,0x000096ec0545b52c},{0x00001059ae4af1e1,0x000735dbdcc9ae4f,0x0005508ac4dfef91,0x000d754392573dbb,0x000045a30ae8165b}}, + {{0x000beab27c67ef12,0x0000c274d559d96d,0x0002dcf0b984d026,0x000aa0faf4f18c0d,0x0000a4d5a80a0707},{0x000bb192b84c56cb,0x000d3aa7040bf3b5,0x0004ba631dd8d7d4,0x000f4e45d39c479e,0x0000fd24341672c1}}, + {{0x000c13673627c363,0x0003c973112795f7,0x00071c3b07ab4999,0x000f308cde824443,0x000024017b4422c4},{0x0007e6782a430857,0x000be955dbec38e2,0x000c10a45929115d,0x000d83e2f51c0782,0x0000d2b6c6a41083}}, + {{0x000a0300c013b50b,0x000b751ec5d7f652,0x000666363fc769d4,0x000b40fb30c8f561,0x0000e14a50273cdc},{0x000989050f53d764,0x000cbadb114faf4d,0x00087892f0c26b7b,0x00024d2de328fc0b,0x00006f37a0582ce8}}, + {{0x000f9b21b06e4d48,0x000483d4ed2dbc25,0x00081ca00bd2f9e2,0x000314b350eba59c,0x0000879d4fee9d2e},{0x000846aa4551a9b0,0x0002394af267bae5,0x000565e76b699192,0x000e51500aa86cc2,0x00009d486efc3818}}, + {{0x0008b841146d2064,0x0005638e7e0c2780,0x000e4fd2ed5afa66,0x0003f8a3a09bf87c,0x0000a8d6a3930dd9},{0x000281d429091c44,0x000e8e029e646294,0x000f8a25ba1a0598,0x000386591adb60e8,0x00000de777e039ad}}, + {{0x00023eed8fe44b7b,0x0001c40e2c2bf152,0x000587aaa9751a65,0x000b04a65627a220,0x000078ae9a0140de},{0x0008dfbb97c7d47d,0x000a883a8363b49a,0x000920e2f50e570e,0x000074b5c1a0b6cb,0x00004368ec853ac9}}, + }, + { /* digit=34 (1,2,..,8)*(2^{136})*G */ + {{0x000c2a360971c31d,0x000066e846e364f6,0x000c727ad6974fa9,0x000639b6d7f33527,0x000015ca19ee6b97},{0x000b4ef351021aa4,0x000ba52f024e9245,0x00044265bc79a45a,0x000687390e0fa07a,0x000026bc8f7f2c64}}, + {{0x0001a05fe05069b5,0x00097050f15dde91,0x0007fbbecba1b4b7,0x0007e7662a47a76a,0x0000cef9eea25012},{0x000d251439c9ff5b,0x000996e9d529b36f,0x0000927929bcb4b0,0x000321b9855ab130,0x0000e6913e2a37cf}}, + {{0x000a22c213a1381c,0x0005998a9d82abfd,0x000b0c9eaee2416b,0x0002e94875f188cc,0x0000ed487d7becaf},{0x000a1bfe43d8e989,0x000d43afbddb4799,0x0003d3555d553c34,0x000ae422e4b606b8,0x0000a98941400820}}, + {{0x000495775835ddea,0x00038f3dbfb894e2,0x0006a991d3c0ab53,0x0007ac0dfbe9b79f,0x0000a996ed108d94},{0x000a1485e6867237,0x000b861bb9390993,0x0009ecbcb0ad8aab,0x00089ee3b1d6a974,0x00004490d265e84d}}, + {{0x0001f9addb3fd772,0x00068b61430c9ab7,0x0002b03f3bbc1b26,0x000a8d0ae0bdd41d,0x0000a6be72385501},{0x00063accbd8fe7a9,0x0001716c52dd907b,0x000c73a737c1e0a9,0x0002868a6d9bdf44,0x000035c09edac28b}}, + {{0x0002ad31f429e92f,0x0007dab4baef62e3,0x000275ae5ff44e2e,0x000fc47109f5a220,0x0000f78da2e8f242},{0x00089cf1ff54aea4,0x0008ca425bcf4d6c,0x000288b364e70dd4,0x000847d56ea95059,0x0000d5e592ce8a8c}}, + {{0x000e70062ee0a4a2,0x000917ac0b7eff35,0x000e6774850d2a32,0x0004c985f8552225,0x0000ed692c26dd93},{0x000068c99ecd36b0,0x000a048e7073969a,0x000922d3ea339e56,0x00093f20f392d2a2,0x0000a61b1d58dd81}}, + {{0x0006e4617f3e69bc,0x000caec1ed66f181,0x000bbf3b6cc4ad74,0x000551b4d225d906,0x00003684306257aa},{0x000516497c9675a0,0x0000addb2fbc3dd3,0x000f55d795decef3,0x000598fadedb5484,0x000015e8ee776bd7}}, + }, + { /* digit=35 (1,2,..,8)*(2^{140})*G */ + {{0x00020f2beb76812c,0x00013ecfa181e695,0x0000dec76ead7889,0x000698d5d9ea02f8,0x00000cd75bcfa2f0},{0x00017a069c2d2cc5,0x0008f0a1df843618,0x0000f08066c134ef,0x000c931ff1203772,0x00008f19ef39b4e2}}, + {{0x0000aecc1c7112bc,0x00073b6b294cda6a,0x00051854d3181244,0x00049ff216ce9bf7,0x0000f5f14402d398},{0x00056e372344bdbd,0x0005f3af02909e50,0x000f436065b91304,0x0002579f8c7d59ec,0x00001766823e2146}}, + {{0x00027d200e7695ba,0x000fb3189e800ca4,0x0006d1d4e8ef137a,0x0007f003750fe0c1,0x0000dad25c5ac540},{0x000807804fa82f49,0x000994fe616e2c00,0x0008e610d4715daf,0x00004e1739c25f4c,0x0000a1ed59eb55e7}}, + {{0x000c966787f80791,0x000d43a4f0d56f34,0x00077d92507dca1a,0x0006bb24b961e404,0x0000a0d775222852},{0x000bb6d594089b2b,0x0004142864fee422,0x000a2f57f8c8c37e,0x000969659c1be93d,0x0000e98561f48eb8}}, + {{0x0003d36eea5a411b,0x00083c9b809b7ceb,0x000b2ef3bd41c883,0x0005fa4368a41486,0x00005327a94036a4},{0x0009d81a294550be,0x000028a328cc987f,0x000b405a4a382a8d,0x000c01dba0a3bcd2,0x0000ecbc7c687492}}, + {{0x000ee9ea4399d83c,0x00029ade4d559419,0x000d914e5643a410,0x000194f9bdedafa5,0x0000ab6a2f9c77b5},{0x00023fc56d6b71dc,0x000ce1637a55a4a5,0x0003af1fce4bba9d,0x0002a5998eb19a51,0x0000fb6b0a026533}}, + {{0x0005384859f3a770,0x000970cb98fe684f,0x00091d11cbfe5c75,0x00014fb3fd60fbe9,0x000024a2c6896e9f},{0x000a7731d1c175f6,0x0007bf7b59e763bd,0x000880e35c8c898c,0x0002e8c923d4606a,0x00001705d921c944}}, + {{0x000bd17983bec34f,0x000e79390d458714,0x000fba44f409e51f,0x000e5b503e976403,0x0000bb28b50bfeca},{0x000460fc77585d24,0x000439ed5d2c53a7,0x0008896e3f104db9,0x0000d454e5ec4bcd,0x00005c92699d9c5e}}, + }, + { /* digit=36 (1,2,..,8)*(2^{144})*G */ + {{0x0000693a18674889,0x00096e1c63c4962c,0x0008d7b6a10d190a,0x00003a26b50541e8,0x0000e282f1e08996},{0x0001ed4e5703fca0,0x000c04e0117f203b,0x000258ac6a79aec7,0x000248c44245f196,0x0000ff00eb7253c2}}, + {{0x000d0301187bc101,0x0000eb6700a1acd0,0x0003f09695693995,0x000f3e0bae823fd7,0x0000bc494f5d06f0},{0x00015737c0a7b0f1,0x000bfc989fca8cdb,0x000b4882d64acc9e,0x00080e66f970d01d,0x00002a01327ea3d1}}, + {{0x0002887ba15c20fd,0x0007d9c6bdf22da8,0x000f0e54073dbcd2,0x0004f3951efbc432,0x0000469ec570ed01},{0x000deaa2e18dbfd8,0x000c5dab920ec1de,0x0002fe53ea59ef2c,0x000e8af47d0d7e8c,0x000015e430f8b3be}}, + {{0x00062dbbba9d84ad,0x0008b4ece53c2d04,0x000d18184b2003a6,0x0006765b0779d897,0x000067fc9538f5d6},{0x000035f7ff931704,0x00005f2cafe37b68,0x000f6c983617d6e7,0x000df03fd273d1eb,0x0000249da2e138a9}}, + {{0x000807b1c5ae6f72,0x0005a0f296c9005d,0x0009a3033a160965,0x0009f56d44b9094f,0x0000c6b826d12c11},{0x00092c2460ebcfff,0x0002ddfbe7133835,0x000e27e80740bd71,0x0003a6cdc435e063,0x00001a2aeff08bc3}}, + {{0x000bb88baca8d454,0x000d95a2093c22a9,0x000139b7af41216f,0x0005e33b6ebd0bd3,0x0000663daaf350bc},{0x000c3aa8010516da,0x000ab3875c1e3b2d,0x000fedd69c7bf698,0x00045728dbd2ac94,0x0000085149b36be5}}, + {{0x000d63c348e3925d,0x0000c0016e23e9d2,0x000b7a687e98afd3,0x00043c75ccb220c6,0x0000b36999ba7a86},{0x000e9f6ec46bda19,0x0002519cdc0bcb5a,0x000ee0c0acd4376d,0x000092de470f18b3,0x00002848124d0362}}, + {{0x0009d1febf2de9a9,0x0008bc77e6c55202,0x000fb2e7eb995763,0x0009cbd6dc27df9e,0x0000444476cdaaa8},{0x000ba7ced0785f36,0x0004b9e93470afed,0x000906fab0ce1fe7,0x000bf2f043e6a966,0x0000d9c1876fd26a}}, + }, + { /* digit=37 (1,2,..,8)*(2^{148})*G */ + {{0x0008d94f6be7acf2,0x0000341338d6e434,0x0002fc6886610503,0x0000f96ca56f7dd7,0x00002f54a7c972af},{0x0003e19d89ed269e,0x00005bb2ef8279cf,0x000a1736ca68762e,0x000fbb351d575465,0x000061e8deb175a7}}, + {{0x0002aae2b99711c5,0x00031ce51efb3108,0x000412e3130475fc,0x00003c959cb5b2eb,0x0000efeaac806f9f},{0x0004837f98bf8cb0,0x000da39411aa636f,0x0004e03d299b3bd8,0x0006376b77152ecc,0x0000b7bc15a5f18a}}, + {{0x00083eca38629302,0x000f164b71698f58,0x0002173c96261574,0x000a82abb6ba418d,0x0000a7d774e7d73d},{0x000c1dd5576a4dbc,0x000283ff3437f24a,0x0001f86ddde594be,0x000503b65e910b43,0x00004e079387d0c8}}, + {{0x00039d3ee2963f2f,0x000233a626332d5d,0x000281c47c620310,0x000452fa27bc3883,0x00006bc300c4cda7},{0x0004c341a09ee9c3,0x0003ad3e7676b0dc,0x000f36ad1e76c678,0x0007b36a8620e35f,0x00009710f4c3af53}}, + {{0x0000e7c2becbd6ac,0x000da1cf405ff065,0x000cf786bfcc5059,0x0009287fcebac86b,0x000006628092b297},{0x0003a21f33a3f231,0x0006f95fa90d7679,0x000b52ce8c481fe2,0x00088d46dae60eb7,0x0000dd27b34c3095}}, + {{0x0007112386fc20ce,0x0005122369b87ada,0x00088beb81cf895b,0x0008f96663c00e5d,0x0000786fe6f72494},{0x0003cd4c08b1b97b,0x00066986d9bd5f51,0x000845f5fa36c27c,0x000c259b22dcc7e3,0x00003a7a6a264018}}, + {{0x00014104124194f3,0x000f16022caf46b4,0x000f5955fa3d17a1,0x000fa544e6a45dd8,0x000027f7e6432277},{0x0001bcd329f0aee1,0x000ac1241de97bff,0x0000cbc3ebca8120,0x0002c1f37b8547b6,0x000028b36f4746d4}}, + {{0x0004a07f82ebea7c,0x000b5769bb816483,0x00053090a14d150d,0x000e04062d69eb48,0x00003488c7727160},{0x00062b085ef31ed0,0x0002787bbfb55541,0x00004cb77b99391c,0x0007343a0b06ed4d,0x00001334165040ae}}, + }, + { /* digit=38 (1,2,..,8)*(2^{152})*G */ + {{0x00027d09f86b87a6,0x000672f7189e71f4,0x00081c5287eec6df,0x000edd421c643874,0x0000dd3e802a5f6f},{0x0005cba1123d99ff,0x000318f38384a7a9,0x00041aa78a8746d0,0x000ea5919aac3acb,0x00001546626df6d9}}, + {{0x000842e7e3646f13,0x000721aaaca5e9b7,0x0000de2e53b43348,0x0009b4ef6518aa52,0x00004c1f8413e3b0},{0x00027091000d9504,0x000ab656868a5489,0x00024df86b81806a,0x000fc7333d963bd8,0x000027dffecf8b57}}, + {{0x000032dd3467eff0,0x0002e48a105fc8eb,0x00097868c757cfb0,0x0002c3180769d754,0x0000bb784982ad6d},{0x0009004e124bcf40,0x000e6db020b0aa69,0x000f6d64792a4968,0x0003db95d05137e7,0x00009c7931f4b21a}}, + {{0x000de8cdd0926a17,0x000b2a7d298c241d,0x00097897af2c8ee1,0x000fad3dbe3b697b,0x000095a39dc131b2},{0x00088519ea3f0b69,0x00087a75a4d2604d,0x000e93901ec55560,0x0004fb6cc27154d7,0x00006bfc52e1469f}}, + {{0x0007c1ff4bc6220d,0x000d7f796ea6ca1f,0x000927b7292549f1,0x000438045567cdc2,0x0000e37c17362496},{0x000832367b234acc,0x000ba574b6cad39a,0x000411ee7dad7e6f,0x0009c31fb3d58d63,0x0000883b19b2637f}}, + {{0x000d28e06912ab7f,0x0000d9f0e4938f75,0x00097f5a913534b6,0x0006ee5cc58d47d6,0x0000cf8cceb8bae1},{0x000d0bd2f66354b5,0x000c029210466f66,0x000f599a7c02757e,0x00079b57a2af1152,0x0000cd4c1d2a65b6}}, + {{0x000d0b153348f81a,0x000e92af416448df,0x000fef6bc43dd5d3,0x0001354ae4a7e8c0,0x0000c6d13c9cd270},{0x00067cecd88b842b,0x000ed48d98b5ca3e,0x000c09bcc716fe72,0x000f7af2ed01fe5f,0x000018e9887155d6}}, + {{0x0002571fa1c005d3,0x0000a1a7cb1282c7,0x00064bef7798f823,0x0000303b2a08d762,0x000094b95e409f27},{0x000cc832f936b83a,0x000392ff22dfd98c,0x000633bedd944ef9,0x000cfe67a87ab01a,0x00004e149b05af22}}, + }, + { /* digit=39 (1,2,..,8)*(2^{156})*G */ + {{0x0005d70b7657b7a1,0x0007085ca8d9d1ae,0x000cf3b0d35bf0d7,0x0000cc024adf2c77,0x000069d110cf7a09},{0x0003a7564e157769,0x0001d506260e70ff,0x000703a97ab76d5e,0x000435a6439d75ea,0x000076aec3e36360}}, + {{0x0002f99d592d4607,0x0009d3e3fcd3efca,0x0004150ef1418504,0x000f73feadd26c03,0x0000c8303bb7708f},{0x00028bb4209cedef,0x000e4552f1da46cd,0x000d486f19b140bd,0x000e6167872c3f8c,0x0000b4a36e89cdf5}}, + {{0x0007709b7b97f8c5,0x000cdd2e7417ce17,0x00011f9e4c798c2e,0x0006edf1eff42bc7,0x0000d3407d05f1c4},{0x000b2930ca06e395,0x000de1dbe217f2cb,0x000ca08df0ad2e70,0x0003a3b592af2a8c,0x000040a4a94b9f52}}, + {{0x000cf60f96d10e48,0x00095daf176f2c08,0x0004556116c14d5c,0x00025e7fb01ca460,0x00006c4e588656b4},{0x0007fb754d3440e4,0x000851cc9071c4aa,0x00038c48b2b6677b,0x0005b2981fd58874,0x0000cc23558b384c}}, + {{0x000981afc00085d1,0x000d0d5af71013f7,0x0004926c19866a71,0x000ed9fa0e68216e,0x00008c7bcfc44bd1},{0x0005694612f9623f,0x0002b679449f0e1f,0x000d14dea79b08e7,0x0009c8b2286cfc4b,0x00000d346cc223b8}}, + {{0x0001287ee355832e,0x000a8715bde48f8d,0x000250613d9a672a,0x00086c08ac970387,0x0000dae19fd8bb71},{0x0005fdcbcf36d30f,0x0007974db1dbf1fd,0x000ac30ebd07464c,0x000637413ea46588,0x00007cc18fa7cb4d}}, + {{0x0008561eaab750ec,0x000fd959890272db,0x0009861b1b6617ec,0x000313bb875f3432,0x0000725d0e14f52b},{0x000a16eb56377ba8,0x000efa08332aafd7,0x0004f969b00c6f26,0x000e75b6f9b0d8bb,0x0000fe905ed9a6d4}}, + {{0x0009badc329d1f15,0x000798a2ac13e274,0x000f04f6cdc35ac5,0x000fff5624494f6d,0x0000234123bdb8fa},{0x0003d01cf2e4388b,0x0001a41004f7571b,0x00002b4c77fb6c86,0x000ef3131bac67d1,0x00001a55a5e1aed2}}, + }, + { /* digit=40 (1,2,..,8)*(2^{160})*G */ + {{0x00010ee253308b7a,0x0006b0f6d3549cf8,0x000f79be840ba3a8,0x0008682b46f33696,0x0000b318d895599d},{0x000485717b66f888,0x00087e17159bb2cd,0x000da105c3fffe4c,0x000a76272f7dfbeb,0x0000bfbd7894f96f}}, + {{0x0005fd5fa205d0f4,0x0004ee8ee36860ce,0x000c5b16628b839b,0x0003f4e13daf04df,0x00008b3aaf4c153e},{0x0004e879df3f3f34,0x00029941a4e0551e,0x000d33e8877228e4,0x0005911236772cfb,0x00007681b72c03ca}}, + {{0x000b1aad44ef0b79,0x00091a9b898fd522,0x0007938044627d81,0x000438af82fb38a5,0x0000b4a5e385644c},{0x0005a947eeafb773,0x000c02e7cf2c0846,0x000e9dbe8a7ea8fd,0x000b6d78d1c57d96,0x0000586ca615cf4a}}, + {{0x000e349a4b31aebd,0x000f2b0285b94916,0x0007b017d6137900,0x0002b0dab01a0be8,0x00008ac2977211f9},{0x0006974d05362415,0x000fd464a1c6a163,0x0005f2a0e55b98f7,0x000493f71d99e6b6,0x0000a0e9ca0b6129}}, + {{0x0008c8ce34c9e3ed,0x000c916fdd5b8549,0x0007be5fa36b2b51,0x000ae2fad592549c,0x00002d134c65513c},{0x000e5adca237cbc0,0x00077e7e9090b363,0x0008cd9cdf14f0ed,0x0000cb97467fc3ab,0x0000a00ba453f572}}, + {{0x000b8f7229523466,0x000e3a1cfe89d80f,0x000cdf0d11487037,0x0009c00d2b42c026,0x0000172110f51188},{0x0009ff21f71bf171,0x00008ecd850935b3,0x000c9c32bfbbecc4,0x00028143434c1a74,0x00001cad52349f90}}, + {{0x000ae1d3d9866434,0x00034a7b3f85ff0f,0x000c1fa6ac6b4768,0x00077b494acd21cd,0x0000ad41f3fb547f},{0x000c5c3baf25baf6,0x000e8ce8a1c5d92d,0x0003fff5cbcfc843,0x000221dedbca01a9,0x00005c09e40eecf1}}, + {{0x000d9cce837c6d61,0x0003d148f9290579,0x0006232b855bab85,0x0007c64ce7a64ae0,0x000028043d63ffdc},{0x000f181a75f69e00,0x00059796e93b7c7b,0x000172a383b1d5d0,0x0000029a0e1e4709,0x0000b9ee91160db4}}, + }, + { /* digit=41 (1,2,..,8)*(2^{164})*G */ + {{0x00026fc9c4cd4abf,0x000e23f1402b9d0c,0x00026a0bfe9f0668,0x000417f6e573441c,0x000042560b13ff8a},{0x0003ef07f65b14ba,0x00061fd7493cea35,0x000ec7090c603bd2,0x00077a68fd05d4b3,0x00006ce1efdc940f}}, + {{0x000f63cfc83f45b8,0x00011d646ac49d20,0x000b73afaae16770,0x000dca23842c77c0,0x0000cf54b1e93428},{0x0004dcfda1adde56,0x0005a1bc6441f959,0x000957b146ed74f3,0x000a15bba7d38f71,0x000080b43552bdca}}, + {{0x00014e77a0de8421,0x000cc45526f09fd2,0x000c5fd9ac6926fb,0x000a7dc8de8a4f10,0x0000d25068992420},{0x000b6cda791fe0f2,0x0007b7314faa40ec,0x000b3679170d12a8,0x000c08f3e767867e,0x00000e1e221077f7}}, + {{0x0000cd9c328d84f2,0x000ec10296c36eff,0x000191f73e449397,0x000f344da7ee8967,0x00003d52cf283e17},{0x000adab3ad961303,0x000c8f7e455fe908,0x000af39881456bea,0x0006ae1ec3fb53cb,0x00007d83567df6b8}}, + {{0x00097128795b26d4,0x000007d53b618c0e,0x000b80b150a9c145,0x0006c0564c424f46,0x00006ae4b9ab6582},{0x0000d841a1380e4e,0x0005832f815561dd,0x000502e81430573a,0x000171a4f85f48ff,0x000063896020863d}}, + {{0x000f7199dc46d818,0x000722b599ff0f94,0x00073193628eba9f,0x0009137f368a923d,0x0000ee5360c30393},{0x0004f710bd7921fc,0x00093f6e46f2a79c,0x000d25010260474b,0x00092d27c08b5dea,0x0000fab67c859c32}}, + {{0x0004828817b2b97d,0x0002c0f0e0b040d2,0x0002217d0167ff6f,0x00040e422baf02d8,0x00006eb8e36ece4e},{0x0001f86203c5e993,0x0008a31113ec3567,0x000da3f78ff4f368,0x000ea84159e48861,0x0000bb7e93050f1a}}, + {{0x000e3d7a82a07312,0x000248b4ed80940f,0x00057c32545a8fa1,0x00024459f67e6d05,0x0000781e5623c72a},{0x0009422f1dd9d9ed,0x00045027e096ae27,0x0006ab7164488446,0x00002f2fcb1f3e1e,0x0000a08771e4d556}}, + }, + { /* digit=42 (1,2,..,8)*(2^{168})*G */ + {{0x000b1adfbccd5f72,0x000bafb9db3b3818,0x000e49c42a8e58da,0x000a5741f9c3a2de,0x0000e1b4d1992caf},{0x000d2ae779d25bd8,0x00001397e053a1bd,0x000689b00f8d9c66,0x000aeefabee2be5c,0x0000ed75eb0e9aae}}, + {{0x00070ef12df3aecb,0x0000e7a205b9d8b0,0x0003fe5865a61087,0x00049560e6eb8f06,0x000018c288645dc3},{0x000c1f205200dec5,0x000d0053bcc876ae,0x0007bb212c914ca5,0x000c3165e12a7533,0x0000fee6eaee8fb7}}, + {{0x000b625175d3e131,0x000ba79b6828f364,0x0007b65b0a28d9d9,0x000a31a0c9d7a025,0x00003f761efd974a},{0x000cea06f50c8e7a,0x00025dd9669b6210,0x0006ea0e74a30782,0x0007f7cbc88a2ca5,0x0000eefdd32a930a}}, + {{0x0006927bdc72fcef,0x00092b5c4e83d33c,0x0008986accaed0f0,0x000ee5e0fd9f3587,0x00006fc2b4d5332a},{0x000bd4c284a559fb,0x00092f79f9e0f036,0x000e91031f24a068,0x000494df12868661,0x000064b67a214c5a}}, + {{0x00038062d4c1e75b,0x0004591289a8619a,0x000fc2f14e9e6431,0x000a96b32ef796e5,0x0000cf84b53f10ce},{0x000e2d93f2a93799,0x000b1200573274eb,0x0003eaf97fa1c33c,0x000a47520d07b67e,0x000099241c28bfc2}}, + {{0x000e16a8fa9459c5,0x00069533f36d1411,0x00042fe5fb485de4,0x000223d3ae84bb3d,0x0000362e47c092d7},{0x00051ac53cf453e0,0x00072adddd472e03,0x0006d8041bea2700,0x0004e95997d405ee,0x000072103589e10b}}, + {{0x000c45b260b78e4a,0x000cab84444896b8,0x000f6cfa759ac76b,0x000f5fe7d64974d2,0x0000fc1b25688826},{0x00018f2e67924f42,0x00079c2d84634875,0x0006ee2d190516ad,0x000a501c0d1b2b3f,0x0000036290195036}}, + {{0x000578dc4ce14fbe,0x000b08c06d75fc1f,0x00063cd0cc5274b3,0x000f629dd2dcf7bb,0x0000f36db3fef100},{0x000304c0d907ee38,0x0005103df2ce7a06,0x00083934eed34414,0x00075ccabaee3628,0x0000f1816df3580c}}, + }, + { /* digit=43 (1,2,..,8)*(2^{172})*G */ + {{0x00065ca49bf70465,0x0002633070d3aab6,0x000b33d03149eda8,0x000f82c732643672,0x0000dae397b7ff25},{0x0005986e7c2b0613,0x000c759b3efb9983,0x000ccf96a4c52f87,0x000f392308a5b922,0x000053a40c602f11}}, + {{0x00003172599604ef,0x000e04fda79e5acb,0x0009d5feaf05bd45,0x00080866e68b83b3,0x00000b424807d53a},{0x0005296e9538c34c,0x000381ac5ccc2c46,0x000ad873e1d42e72,0x0005408bd7d7dc96,0x00006a74e1c17bc4}}, + {{0x000cfc53b4244564,0x0004fedf0290a8fd,0x0005ee4b6fd35ed5,0x00009974fcae8196,0x0000c1f220ef19f4},{0x000bedf5f9d4ef28,0x000ca3c4cb632f9e,0x0005cd318a6d91a9,0x00094f00ac42a1ad,0x0000689a17da238d}}, + {{0x000fd495f78c275c,0x00068cdb30cfb3a6,0x0000fcc91ed14bb9,0x000a17ddf6d09b8c,0x0000645d0ce04a7b},{0x000dc229b0415b16,0x000009f275264daf,0x0005e7bb59b2b9b3,0x000525c2280c2b74,0x00002b3172744708}}, + {{0x000e98378c350e3c,0x000c25a59b0ff628,0x0002b1fc99481f98,0x00035431d25ec81a,0x000068a37387c1fe},{0x000ebf428f4945e2,0x0009bd6f48485983,0x000f243e60db09cd,0x0002efd4687f2c5b,0x0000e57b62bb98a6}}, + {{0x000fa5e9a55e99f0,0x000bc7ad0d350a3a,0x000860b4358a0879,0x0008b504684f6ebf,0x00009bc6954fb2b7},{0x000e47f1dc72cd57,0x000587c1cdd69b63,0x000020a0729886ae,0x0005a9f2a64081a3,0x0000092024e42c9f}}, + {{0x0008186df8037536,0x000287fb7f01d83d,0x000a6db487d36c22,0x000fb5d0f5f1f860,0x0000704dccf6c287},{0x0004aaea176b654e,0x0000fa01720468f0,0x0000fb9b626920a1,0x0001293ca4247726,0x0000473f7f1fa757}}, + {{0x000fc20755e3176b,0x000828452666a58c,0x000016e7bc6ccdba,0x00078f9084bcb6e0,0x0000554faca4c643},{0x00094e142cf0b0d6,0x00046505294dba30,0x0006822fbef1afda,0x0006df474a30ba28,0x0000e6be6e6ae1a8}}, + }, + { /* digit=44 (1,2,..,8)*(2^{176})*G */ + {{0x000b296904664fc3,0x000b53e979f39254,0x000a642320a351cd,0x000cc34fa1efd130,0x0000a26d827b4096},{0x000df088ada01cc1,0x000d534b9db65b69,0x0001656914dd4d71,0x00018a2f335c82e3,0x000058dcd3dda1a0}}, + {{0x00008fc59cde3468,0x000e7124237b64b8,0x0009635d376aaed3,0x0004ff5d8688ebe9,0x0000c1b55d497018},{0x000b143a98f532c8,0x000632ba3585862b,0x000532de58edb3d0,0x000ebfa9bb66825d,0x000060efc436424d}}, + {{0x000f8f66b8a7cdf7,0x000c324f111661eb,0x0003f176844bf6c5,0x00056be78edced48,0x0000217f1b2be94c},{0x000ec85fbc8973e6,0x00067f4d7ed8216f,0x00068f645f12fdb9,0x000735154bf07f37,0x0000c3cd2d5edd0f}}, + {{0x000f53916fc6beae,0x0001122765fa7d04,0x000fce16c2004cf7,0x000c22d9859805be,0x000052df10ff2d7b},{0x00099f450e1f9830,0x000c61f33ddf6269,0x000e06e68bf551b7,0x000e86ee34206238,0x00002aa249bfa9c5}}, + {{0x00047aa4c7ac2b3c,0x00082731a3a93bc2,0x00057da03752d6c3,0x000d7d2fd42bbf46,0x00008348bc06dd42},{0x000825653cf027b6,0x0001032f60c77da5,0x000a69fded019b66,0x0001dc3cf6ffbc26,0x0000333cf94fd444}}, + {{0x000ddab96e59ccf0,0x00077ba4a493b31c,0x0001ce1d36b7f226,0x000c8a14b54f20a5,0x00001a428916f43d},{0x00047a670dede59a,0x0002d0aed25ea138,0x000afd5154d9620d,0x0009faac5fa1d09e,0x000024f267bf7958}}, + {{0x00017e76ea8b4aec,0x000d995d314e7bc2,0x000b24fa2303625b,0x000d3e9d32ee7464,0x0000fd86bbb7517e},{0x000a5817e3ed6c66,0x000681fe7cda917f,0x000a903127323a60,0x0005ae96b12d8016,0x000044afeb2ca0b2}}, + {{0x000b69cbf65aaebc,0x00090c5ac751e7b7,0x000281d845c75cee,0x0002f93c693f9647,0x00005a6bb7c3dc6e},{0x000be7048732b0cf,0x0003da2f4bf94e19,0x00085541905b0af8,0x00067070b1a5325f,0x0000e3a10d49e546}}, + }, + { /* digit=45 (1,2,..,8)*(2^{180})*G */ + {{0x0002dfa557bfa495,0x0000476e1337c262,0x000db45dc38dd4f8,0x00012d3d96faadeb,0x0000c13ada75bd32},{0x000c6ca5801dad5e,0x0007c17be93c6d61,0x000188985039af29,0x000bbefa124866c6,0x0000462261edbc6f}}, + {{0x0002edf52c078d85,0x000c57dd4b79bb87,0x000adfda839ce9d2,0x000ba33e8aee806f,0x00007fc8b3dee585},{0x0003b2818874b38e,0x0001a4e2127015a3,0x000069054d6b7749,0x000ba60c89051d0c,0x0000fcc7ea0acfb4}}, + {{0x0005464d0e55495d,0x00003ed9aed9f40e,0x00006de43f8b680d,0x0007a14ea70ca6ad,0x0000ab349a9bed40},{0x000e0296a877751d,0x00012dfd9e535ef8,0x00070ac681b2a37e,0x0003f0788abf57ea,0x0000a2d6ecfa6e9b}}, + {{0x00063f4153af6dcd,0x000c683171b445fe,0x00029af26bf85199,0x000cbbae89bcf21e,0x0000e2560e6db219},{0x000e1d75ae224a6c,0x000f6a930add43df,0x0002cb637aac5049,0x000bc7d6862ebb14,0x00005e73664b3718}}, + {{0x00093a787b955171,0x000d06e1f017d5eb,0x0005bd3a711ff605,0x000a317a03753339,0x0000d94a848d4553},{0x000d57bd8e1e0fef,0x00062a2dcc99ccc0,0x00038d4cbe8fa59c,0x000cfe9d5c134b41,0x00007c0347ff2191}}, + {{0x000145c114649f08,0x000f3ccf0bcfc46a,0x000e148a3dd22dd7,0x000be895b3a822ac,0x00007ff5e819ea62},{0x0001437bd32a8c35,0x0004c538be17bcdc,0x0002e928c1bccb8e,0x0008a932f01e867c,0x000082bf7d9a8a3a}}, + {{0x000d10ec409dd077,0x0005b006c19d4c7d,0x000704a0fd36352c,0x00021c0e8a0f3c43,0x0000f1b113eab5f7},{0x000cbd604ebce52c,0x0003d6cac7cd3e1f,0x000b62675f9792a4,0x000ca4b06ed3714e,0x00007ff6667d89a2}}, + {{0x00080034798ca4d4,0x000f2c7af8685c8b,0x000d778ecd30d2f0,0x000cf952ad4c1c8c,0x0000e198f05db898},{0x00063d51806a84e5,0x000e1e52eca3cdb7,0x000b75c78219120a,0x000a6e0cfea1db16,0x000052a4a35bae24}}, + }, + { /* digit=46 (1,2,..,8)*(2^{184})*G */ + {{0x0008e13092cf573a,0x0005c3f4c8303203,0x00005750d3512460,0x000db40fb842c7aa,0x0000494598d37817},{0x00077989cb6b3d8b,0x0007062757558f1a,0x000150731ef6087b,0x000f58b273cc3e83,0x0000ffa7db45a98a}}, + {{0x000d84601a040653,0x000c4f4b0166f7a3,0x0007916814ccaa7c,0x00080f8fdfbd3e3f,0x0000bdc4370992dc},{0x000a6279f7786e45,0x000a95c7c1620b02,0x000d01014b0992a4,0x000fa801eba68b4d,0x000052fa0f983aed}}, + {{0x000a03aee51cbd7a,0x0003eb0b796d2197,0x000eba706ef4966f,0x000307cf5c3e95f4,0x00007329daec404c},{0x000aacb62b09eeb6,0x0000d76f53a89aa8,0x000109dd72b102e5,0x0003bfa4f0d8af9b,0x0000584ec8a3c986}}, + {{0x000a4c97a4abc3b1,0x000629f8f5fcda83,0x000483a1c45951ca,0x0007bee77f3e558c,0x00000e48e3d45037},{0x000f9b7025a36d96,0x000524bf6dce6a73,0x0005d44b52ac36ba,0x000ec10e9ff373d9,0x00005254e73f1733}}, + {{0x000f6e149c30d036,0x000786c252bd4796,0x0009a3476ff36be0,0x000f9406305e0f88,0x0000f83a58f41674},{0x000e1a0a8596c4ab,0x000785cde601a897,0x00087559b39a4f3d,0x000826d27d17bbe9,0x00009be39f3ad611}}, + {{0x000e3c3c1d7cda3d,0x00032ea87baa6279,0x000158ee6a629579,0x0004420c958c1fec,0x0000d64ac7b719e3},{0x000792f805f03b27,0x000eb7b2bcfe0b0f,0x0001327ffd07ff8c,0x0003e8c973510710,0x00002665759bab58}}, + {{0x0000291d43fc236f,0x000e82235e6fc06c,0x000e4b14f6918efa,0x0006704723477728,0x0000cd51067b09ae},{0x0009f8b71be82198,0x0002467cec5a196b,0x0003a235d360dea7,0x0004c8451deeb31e,0x000071e8bcc32913}}, + {{0x00005ab8b7207ede,0x000a6911a335cc88,0x0009e9fe5b2d6bb2,0x000344b19563459b,0x000063bbb632aaa7},{0x000b647545ffb149,0x000c9da8d006086c,0x0009f1914bb72b13,0x0006fefd76ca4846,0x000088e4372592ac}}, + }, + { /* digit=47 (1,2,..,8)*(2^{188})*G */ + {{0x000cfd57c06983bb,0x00098e453544774f,0x000b3dde4afbe78c,0x0005fb6f5834d0ec,0x00007bae9c3b3751},{0x000ee4d65bdcce8d,0x000ab3dd6901b1d3,0x00047673a7680203,0x00093d2623b49fbb,0x0000be9b2e57312a}}, + {{0x0009ae30f9bf470b,0x000087d0d63d1fae,0x000118fba7a5a59e,0x000fc5809658fc05,0x00005a1e22227a90},{0x00083acb655ee723,0x000edd1818baf918,0x0006032f40bacfef,0x000334844e27e9e0,0x000040f4d53495bd}}, + {{0x000363b0cc192c11,0x0001d774e6daae2d,0x0002caa668f0d453,0x00082567e7b3ae0e,0x0000eb18f19fbe78},{0x000e6d2a4ad162d6,0x00046cf309ae93b1,0x00071ab3a096ecba,0x0002c0901a3f80be,0x0000db5da2662978}}, + {{0x000ee84e265cd5da,0x000988dc2c6ff707,0x000f46f3d40f2a5f,0x0000c9df979d6122,0x0000ed01e35bdcbd},{0x0002d0793015eb1a,0x00095b063cd880a6,0x0005d2a436307bbd,0x000f365423f3ea7c,0x000081c0177d53ec}}, + {{0x0003403ae96daf9b,0x0005aaabeccefb5d,0x000862e19cddd34e,0x00005dbc1cf56ede,0x00001050a209e4e5},{0x0009710fdf7e6a41,0x000c40de8785a64c,0x0006cd11554ee79f,0x000527d0210f3d64,0x00003c2dab8fffd1}}, + {{0x00065f36c733ecb7,0x00097438a5807cef,0x0002edb163b75a2e,0x000e8e6daad28389,0x00005a009a4a047b},{0x00026231865878db,0x0006b9ea60d32b2d,0x000a6c1f604286b8,0x000e303b5ee93df4,0x0000ae2226c13edc}}, + {{0x000f246cdd4e3845,0x00068e73245980e9,0x0006e1e20523881d,0x000db26e1a6f5965,0x000056940ffbe18c},{0x000cde6b503aafdb,0x0005617f961ac0ef,0x0004eefd32ca8809,0x000b960d1c8a741b,0x00006dc0bf51f631}}, + {{0x000968734e4dd7f6,0x0008df9dec31a21e,0x0002817162256254,0x000a3ed65988c8b2,0x00009bb859066057},{0x000f94739f3adb65,0x000858f5da6309bd,0x0003e25d5a77565c,0x00068a42110f3a62,0x000053d37190038f}}, + }, + { /* digit=48 (1,2,..,8)*(2^{192})*G */ + {{0x00003f3e034d81e9,0x000580ef4f8b16a8,0x000e443be8670976,0x0001a9ec197241af,0x00001dd783168b20},{0x000097440f10fef1,0x00018a804dbec69c,0x00067b238c506e04,0x0008f287fa83b85f,0x0000d016711f649c}}, + {{0x000a1a96613ebed5,0x000aaa0b311898c7,0x000452f4160400b5,0x00055fbbce2a272e,0x000044105e96f0ba},{0x0002280dcf97d62e,0x00039cea1c8cde9a,0x0008d0499e144dcd,0x0003fe7cd9d958ba,0x00007fe9ad9ee6a5}}, + {{0x000320c5cb34fa83,0x000c1a43794f8dcb,0x0009951b966af168,0x000a28da0dcca923,0x0000bdaf4528f40a},{0x00083be9a0dbe4b2,0x00076ff47b50a951,0x0001b6b449d08629,0x0002b4f53933e3b0,0x000077b42a87e4bd}}, + {{0x0000a02b0eaceafd,0x00088c341dca5663,0x000aa7c1ff9509d6,0x0003070fb7de7fed,0x00009716331f83e3},{0x0005f449ec69c78b,0x00092aa2fd3cf36d,0x000709959bb35e00,0x00081dc33d131954,0x0000174691c29863}}, + {{0x0006166b44b3b527,0x000e8abe085116b3,0x00055111e7cb7191,0x0000aae2f04a4337,0x0000b8cbd7d43a2f},{0x000af71e91ff6ddc,0x000673cfd4b322cf,0x0006bf828cbf933f,0x0006d39eb726aa81,0x0000f4fde56a46c2}}, + {{0x00081dcee597d414,0x00087dac97e65165,0x00006a1325b93f7a,0x000a0d6498877936,0x000087e6a262fd86},{0x0009a34fc66e7cce,0x00055918f483f148,0x000c479481754c72,0x000f76c426d2dddf,0x00002d39a7634863}}, + {{0x000cca31c7a57625,0x000ade949dee1686,0x0002d160c071cd59,0x0001de16a1ae0522,0x0000da394a68f678},{0x0007da93fd13da3f,0x000971d9bc499082,0x000cce082821a131,0x0009544ac4a9b4a8,0x000025d76c70fa80}}, + {{0x000e658aedcda8bb,0x00031644cd8f64c3,0x000fe937f063f6ea,0x0001e975658a2d78,0x0000049c304fd752},{0x000473ffef5b241b,0x000792e05da59eb6,0x0002a9683732b03d,0x0000a6487ba3d60a,0x00005d72e137e219}}, + }, + { /* digit=49 (1,2,..,8)*(2^{196})*G */ + {{0x00099ee566eb922a,0x000364f692ac542f,0x000028dcac6c9771,0x00018cfbdf079ffe,0x0000610be982fc2a},{0x00013889ee80e815,0x000511fd62191997,0x000663545a2e0935,0x0008cc4048c883bc,0x00000920149ca0bb}}, + {{0x000eee0c0ea6e1a4,0x0009b8f81a1b3bed,0x0004ef395891f049,0x000e351f74f3ce14,0x000069aac489bd81},{0x00027729a694a1ff,0x000aec0d39e25c35,0x000071f076d9e952,0x0002d5b584061982,0x0000a6863991eccd}}, + {{0x0001ad919aac7231,0x000d837b1b76ba6f,0x00045b7295421df9,0x000677d0a1a2eab8,0x0000c06c35fd7a6d},{0x000314874f18d1ae,0x00031b807ea7b0ef,0x000e4bc5643a1ce2,0x0009b5aabedf5496,0x00007faef00cb014}}, + {{0x000747ea0bede08a,0x000e0753f73f449b,0x0007d5fd126e01d1,0x000e0524d1d1c94f,0x0000db80899bb94d},{0x000c10697e01e74f,0x00074fe228d291e6,0x0004d7b0c0585031,0x000c5761635b804b,0x0000e6909f3f3acf}}, + {{0x000a8f2439972c6b,0x000d88f0876fd4e6,0x00071943cf4a2c61,0x000dcc9cb45f0c30,0x0000274cda09b319},{0x0004426efde75793,0x000b01b65ccde7b6,0x0007c3a4fb720a13,0x000dcf1d741e2cd1,0x0000483cddf39166}}, + {{0x000d32fba5127c0b,0x0008344fc94dea3f,0x000edda3a50b098e,0x0009531ef34c8cdb,0x00009ea6e5479af1},{0x0003173f9743bb5a,0x00036f6795dcfb75,0x000330414c181516,0x0006467c0fef01b0,0x0000608f1137cc86}}, + {{0x000731021c804f19,0x000272aba16f73bc,0x0003c5c8b7dfaace,0x0001fdebf2fb3101,0x000060e66ffcf1c4},{0x00051f55a60c6b7d,0x000ca244fee99d47,0x000685a66c4490cf,0x0007f1df74bca48b,0x0000e008421c6eaf}}, + {{0x0008949a50ad4589,0x0009c1acb452fdbb,0x0004985e6bffc0ea,0x000efbfd931ee696,0x0000aba564d3b7e5},{0x0007a12f75fecfe0,0x000a3263c88f3bd1,0x0000c37c6a1321bb,0x00004ff03ab147c3,0x00003bd493c68746}}, + }, + { /* digit=50 (1,2,..,8)*(2^{200})*G */ + {{0x00032811a7abd874,0x000db7881fdad909,0x00057a04e50379b8,0x0002cd9e5cf638f5,0x0000f7d1bc229820},{0x000dd099becd5a2a,0x00089309bbd11ff0,0x000fa633afb561a6,0x000f7a86676108a6,0x0000803fa54a21da}}, + {{0x0002ede0e2398f58,0x000858a58d6cd461,0x00057b7853efdb37,0x0008c6b289cb633b,0x0000c7e7d1c765be},{0x0009e66e59813ff9,0x000d162065a6f4f9,0x000ccdd7da21b1ec,0x00007f41cc3a47ec,0x00006d5b783c2d8e}}, + {{0x000e4bf888b90c57,0x0004f777b0ac93d1,0x000d5aa9e84f32ca,0x000e8f22ba6e37b0,0x0000c2bfd71f0dbd},{0x00029438c4942ce8,0x00044e04df0ba2b4,0x000d0dcdfb573987,0x0007fc420935d5cf,0x0000d2dbc8e26eee}}, + {{0x000aebfa4044443e,0x000fabe67e573e06,0x0008d598ca0bb6e3,0x0007d84c505891db,0x00008b6a89573352},{0x000fd835db9f7005,0x000d7e9e56e55c19,0x00028cd210f50d2c,0x000afe3eb7148ced,0x0000282da8971416}}, + {{0x000d8c8bc0a17b96,0x000d956c17706169,0x000d6c4e0e6ccae6,0x000f778455351909,0x000039e97d726501},{0x000386493c5aa83e,0x0003ab6056becfd1,0x00038d0a6a30f997,0x0009bf4f933f1325,0x00003ec9cf3e5b1e}}, + {{0x000af546c8a478e5,0x00009fa5abea82a6,0x000929091c0b931c,0x000a611068dc611b,0x000031a3754d6e83},{0x000243fc70d1d9f1,0x00087c7c977ec238,0x000c3b180905907b,0x000f7b3c0a8de294,0x0000453273a39eaa}}, + {{0x000f989c69b6cdd9,0x0001b00b008733a5,0x000cf19582ee2e99,0x00082c3d0cba0697,0x0000f5ec6cff4889},{0x0003404faefb719d,0x0002c724c3c2b2fb,0x00084bc2cff9824d,0x00064341f90e02fa,0x0000ab3d02a9a4d4}}, + {{0x0009d7b51caacc1c,0x0008509081e9387c,0x0006c2bba30bf8a1,0x000749415fb9780d,0x000016b6886a163a},{0x0009d9971a12e8dd,0x000f041d6d9f6711,0x000897c914fde7c4,0x00037415fba6c1e2,0x000044ff79be19da}}, + }, + { /* digit=51 (1,2,..,8)*(2^{204})*G */ + {{0x000a38783edbf56a,0x0008a62060b5f619,0x0003e197df84183c,0x000ec5565a56f46b,0x00003d764abc2d6b},{0x000a0edc3fc096b3,0x00080a9da710718f,0x000633fc0eb6b9c6,0x000931e875a77998,0x000072910f080d6c}}, + {{0x000c351b873ccd50,0x000f849cb198ac73,0x000cd2f12adddfbb,0x00052b678a884a93,0x00006d2e4199685e},{0x000ba6f9e2ce488e,0x000619fe2c4b44b8,0x0006a77f7f29e16a,0x000b9984a580f6c4,0x0000c4fae9993e3c}}, + {{0x00043775095179f6,0x00074b65eb03c0ee,0x00038e84cad4f821,0x000c08ad2f19b795,0x0000a815addc931c},{0x000a6a2475d15354,0x000e250bb3ee8a3e,0x000bc6c7e2e9f012,0x00084e0f675eb14f,0x0000728fb5f890a9}}, + {{0x00079fb23be5ff7d,0x000b7abd3c095f18,0x000e5d17bb3553d9,0x0003eec8404b261b,0x00004c7b8e343501},{0x000f0ac52ff88cf7,0x0007572dfd754907,0x0004e2b22c9118c3,0x000d179073a97d08,0x0000d6bca24f52c6}}, + {{0x00062d8c5230f8f7,0x00029ee4b049136e,0x00014f3cb9c19a54,0x000e78a288b63bf1,0x0000675ced19a43f},{0x0004ac0245017d70,0x000da67379e7896c,0x000206517d607078,0x000c44a6ab25237a,0x0000c32d492b5336}}, + {{0x000e008c5bcdd3fe,0x00003fb319d76820,0x0008fc97a392e47d,0x0008db544b029312,0x00005611953b5d34},{0x000d3a1aadc08c32,0x000ab1c0278ca331,0x0006c870390417da,0x0008770cf666f76a,0x0000e48921cecb9f}}, + {{0x0000ffc1739db82e,0x000d6ff50f75f9cd,0x0002ad7569ae9e9d,0x000e1e3181d8eddf,0x0000eddba8e1699e},{0x00002aac66c37326,0x000c6e3037d90f29,0x0005d02ad905e85e,0x000d947afe3f307d,0x00000675780cc1ba}}, + {{0x000709def8c8c5c7,0x0004c1a567193ec5,0x000a8eed0812adee,0x0005924ddaf3c305,0x00002a0743a5403a},{0x000f431d23ed5fa0,0x000f9830eb2b6692,0x000b5818530569a5,0x000050c164d80ce1,0x0000cf41a7008416}}, + }, + { /* digit=52 (1,2,..,8)*(2^{208})*G */ + {{0x00037dccb38225c9,0x000f315adf7cccff,0x0005ec2414fcf3b3,0x00075f87e81a3e5d,0x0000f61ae1e090a2},{0x00009fa4f71b333a,0x0000e73907fba12d,0x00097997840dbf32,0x000506cc535daa6d,0x0000b54ff864cf47}}, + {{0x0008797e91aea7cc,0x000a480eb6b242d6,0x0002d2f863b4d485,0x00089479dd30bd02,0x0000e4b655e68a0f},{0x000d53005ec1aeb9,0x000290a6b4e185ab,0x000d8586b6a88091,0x00048c81b82f2c67,0x0000bb2a23d0098b}}, + {{0x000933d489d97ae7,0x000bb9e5cfe5c487,0x000e082b0c0ceb9f,0x000cebf8a82c020a,0x0000ded88fbff89b},{0x0000c73ff49bb729,0x000642e67c51e574,0x000a98cd0b0768e2,0x00043b1c60f64020,0x000020d51988ed0c}}, + {{0x0002f4209bf9bcf0,0x00059be9d8e68fd9,0x000288102284ec39,0x000064398db0f053,0x00004a5dc6b917e7},{0x000420b560d4b030,0x0007fcc1a739d4b6,0x000f3e6a037e1521,0x00016c1d009aea75,0x00000584c6da5516}}, + {{0x0005c25bb9b62679,0x00086c75488771a4,0x0001396cc5d8091e,0x000d1f142cb76e3f,0x000053b1fbdb29de},{0x00090a8fd649ba14,0x0008a31f88ce6dce,0x000c62ad1ca78ee8,0x000acf8c7be2becf,0x00000873b8c63e6b}}, + {{0x0003c778da9603b1,0x0004c5696f37750f,0x00069d8907179717,0x0006192ed25dda55,0x0000eacdd235716a},{0x000ba0f75d54c23c,0x000b8463b04938d5,0x0006234e9d1e300a,0x00020e9b53d9dded,0x0000bab7f97bd886}}, + {{0x000760871c2b484f,0x0004c8b4ebd3f02d,0x000caf56e9cde387,0x00059c4cea47acd9,0x0000eae7a0124e02},{0x00098b00ed0b01b8,0x000a0e536e530d74,0x0004cf87ac646f5d,0x0009e6d2a7abc52a,0x00002f3c4af4c323}}, + {{0x00082b921a859ae8,0x000619c6254dc41f,0x00038257ec641913,0x0006a3ca77e29392,0x00000c021e167183},{0x000a3d8c1544aca0,0x000f62e1402cec5e,0x00070ff1a4d2048f,0x0000bd9cb9f17ca1,0x000074174697d3a5}}, + }, + { /* digit=53 (1,2,..,8)*(2^{212})*G */ + {{0x000e0ace9790f135,0x00011e60ebcf7262,0x0001342678767f4b,0x0008aec094482b83,0x000086d2546132b7},{0x000cf8daedabfb38,0x00071d31f8d1f420,0x00014a5069e4864b,0x00083fb4b1b1e83f,0x00006eb2e2034cf9}}, + {{0x0004d5ef9bcae914,0x0000b0d1e935abb5,0x0003c077f3debaf5,0x000b3d7b5defd10b,0x00005a2eed07f66b},{0x000687601569519a,0x000a7ba74f17e266,0x0008123a7dcee411,0x000877efdc0a0e3c,0x000028a9a1af6c1e}}, + {{0x0009432af25a44dc,0x0003c0c207674f17,0x0006ba6b64e961d4,0x00069db1e112e09a,0x0000b97a68266210},{0x00016fbbff8bf955,0x000008fde2ddec64,0x000f11e7b94049f2,0x000e7c08a81392d1,0x000090f2310497ae}}, + {{0x000a995e5dfbc6e3,0x0004fc7904fc3fa4,0x00057d4a050cf2ac,0x000caf6aa14a23f4,0x00009e74b3de65f4},{0x00016c563b4a41b8,0x00083ecf3a5598a7,0x0007407e5359d663,0x000c3283c56534b1,0x0000a377a93e6974}}, + {{0x00064110e3d7be93,0x000db892f3b26e7d,0x00000446416395d6,0x000c44aa3f470986,0x0000d33c4ed3954c},{0x0002e3c7706265bd,0x000d02cfad414e41,0x00081bec63b3b22c,0x0001c5ef12b155f5,0x00004a979c09ab69}}, + {{0x000e709afd4ebe8c,0x000b8ea308780f21,0x000119d55ae78e9a,0x000664ba3dc8de76,0x00001b9c38ab8027},{0x000526074ae5ec7c,0x000c776021704560,0x000ac3d34419af49,0x000944e68bf204b3,0x0000bf2f1a243170}}, + {{0x000a45755beb5e5a,0x0004c3e7882f14f1,0x0004ed815580f741,0x0002464d0c9f6dc3,0x000088180b1213cd},{0x000ca2ca9f747a28,0x00054277c4608cf7,0x0001d9dd48232ab2,0x000f8730e7ccbdf3,0x00005ef4880c3dec}}, + {{0x0006539c7de5db9b,0x00043a7e0f222c2d,0x000b9c92b4c46a68,0x0003b3230309d42a,0x000069a4869c5fac},{0x000331fb46a1f47e,0x000277c432ac7d72,0x00000f4ddec961d1,0x000121ade72692cf,0x0000f86aeb4b1886}}, + }, + { /* digit=54 (1,2,..,8)*(2^{216})*G */ + {{0x000ffdfc7e7c2a09,0x00085eae457a4773,0x000bae6fdf8723eb,0x0009a0d71d19857d,0x0000d6ef525ea59c},{0x000d15002a515a26,0x0002c5426ee7cda3,0x0009a1edc37de8e0,0x000e199c8341b086,0x0000bbb468e51820}}, + {{0x000f6927b0d79bd1,0x000614c85edfa308,0x0003f86bcc29875b,0x000193b862597655,0x00001c7d62051005},{0x000d0721ecd294e3,0x000feba55f2f94c5,0x0008d744240dfdf9,0x00015625d6a996f9,0x0000e456c18ca0d6}}, + {{0x000072c30c9a3e3f,0x000a8e9262a35393,0x000d35fe1292598c,0x00087a2b978a49d1,0x000028a1a98b5727},{0x000912e3eefde708,0x000825277c850e61,0x000f065759f71f40,0x000459fad84f15f8,0x0000a72b7cdf565b}}, + {{0x0004cae01e64c20e,0x0009b2079e5fb67e,0x000a8bdf924006e5,0x00033ca37e1331fe,0x00003ed077fad719},{0x000c957822ca746f,0x000cfe60412a77db,0x000c22af18030eaf,0x0007aeb3106ff7ca,0x0000cacc54eeaa59}}, + {{0x000cfcde2a6c31ad,0x000d386365e668b9,0x000a0dc0c7d17066,0x0002d72beada8dcd,0x0000ed8b493a21b9},{0x000d65adf799777f,0x000c63e7e85d1e48,0x00096bbdaabe1343,0x00090a4ff9ca0967,0x000015220dfe9e8a}}, + {{0x0007e0aa7adc7a48,0x000db0cb0ce1c552,0x0004e3df0b8cb07c,0x0009bee3b5b534d0,0x0000fda2b88e9831},{0x000f7d9eeff2ac2e,0x0007e2d79362c410,0x0000823dcdc0db71,0x00077b12467920c9,0x00001801931c732f}}, + {{0x0001ff32eab51c2a,0x0002df10296f4fd3,0x0003b852814bc239,0x00078de051dca76a,0x0000dc7706867646},{0x000c2397edc895b3,0x000c8f18d2c714bf,0x0008327992dc9ba8,0x000467a2364b5c33,0x000088766fb7dea2}}, + {{0x000f5fa5904e2bd3,0x000209afa8338349,0x000206d2dfd21b18,0x0004529102295172,0x0000fd30a26b44f3},{0x000137b286ed0846,0x0004125e77d9a3b0,0x000a624d3959c964,0x0003d9c4a11235ce,0x000037f27954916b}}, + }, + { /* digit=55 (1,2,..,8)*(2^{220})*G */ + {{0x00061bbb05f9956d,0x000106ac42bd6d29,0x00082503dba8e1c1,0x000ae458e6df8646,0x00004572780d144e},{0x00004d881133b185,0x00070f070a6a26b8,0x000cb240e6288319,0x000ae43d370686c0,0x0000da343e03be55}}, + {{0x0001567f755e516f,0x0002de74462007dd,0x00047b5f76420568,0x0000d6ee7b8ab48a,0x00004f2bc1635d97},{0x000931de26c2af42,0x000d96b0887bcec5,0x000e8847159b8388,0x000b324cb694497c,0x000039c7e289bc5b}}, + {{0x000b15d6243f1091,0x0000ca11f17a34c7,0x0008a8443e31d5d4,0x0003fa53b5420ab3,0x0000927b5e2d1cf0},{0x000424051138a243,0x000fdb1e274e49c4,0x0004528d80f9684c,0x0000da2a45cf5074,0x0000abcad67dae2e}}, + {{0x00084e81ad96c3d5,0x00080021a93507a4,0x000744ed85217d67,0x000286a40b4cd118,0x0000702de63abcfb},{0x00077e27e30a727b,0x0000cb5272e9d6ec,0x0004ff812967789d,0x000a6af8eea1c93e,0x00003caac07df9b9}}, + {{0x000098baf9cb4cd3,0x000b81e48ac28403,0x0004bc21d97de9e8,0x0004798431831129,0x000013750d1196db},{0x000ae9e34b83b95b,0x00066584198da522,0x000be98219cfe30b,0x0007d4e08ab4fc17,0x00008387d9c3f13b}}, + {{0x0009f80d55b0c703,0x0003dec0ccced589,0x000b73ac42429524,0x000510fc625cd4b9,0x0000a65aaf5a02d6},{0x000f34bb38b3eac6,0x0007ac9ce6dc1532,0x0007a93199e8a328,0x0001c3b4d138d511,0x0000ca319150839a}}, + {{0x00061e15b0193f73,0x00026e84a34f239b,0x000c02e5ed252835,0x000fb353215fdb83,0x0000611a80a40f29},{0x00053277336c58d7,0x00082d4a127f89a5,0x000bb2b59fa73e65,0x000bfdf925d541e0,0x000059c1e0662639}}, + {{0x000f9b71b8c0f425,0x00077f2d0c051995,0x00029b4c129bcbe6,0x0007e7c82502fbc2,0x00002b22165d2734},{0x000b6e3e8373047f,0x000bb592b82dd077,0x000519b4c4ab6dee,0x0004bdb327630273,0x0000227777e79e51}}, + }, + { /* digit=56 (1,2,..,8)*(2^{224})*G */ + {{0x000c41114d0d0f0a,0x00071c035d0b34a2,0x000b56e6af5ad632,0x000f458d1440b386,0x00009070851ee09e},{0x0000477abf63470d,0x000c1f1ad95a0b12,0x0008478dc8a2c85e,0x0009d79c9c09b37a,0x00005669d660129e}}, + {{0x000a68df70882277,0x00065b3292a92874,0x00062d47b35717e2,0x000498f05ddc15cf,0x00002045f41bf3f8},{0x000a8b9343580755,0x000f94505bf7dd0a,0x0008e243ec49440b,0x000aea3afa4e63d3,0x00000f5462133be9}}, + {{0x0006113c503cd9d4,0x00061b51e706ad97,0x00044d98af8ed595,0x00086b990b99cebb,0x0000a86e1c215f82},{0x0003cbb144e6b9aa,0x000e4b097e2b5aa3,0x000c2fed61bf9a24,0x000125c6c7e1022c,0x000044eec8aec086}}, + {{0x0004e7b4f75c69c7,0x0009d717af715d2e,0x0003eb2b959f67ad,0x000b50256e2f7f59,0x0000faa39a85f847},{0x000657624d4d6888,0x000779788d5374a6,0x00031a2adb0e9860,0x0008607e22b915e6,0x00009ed17ced0865}}, + {{0x0007e49f538144e9,0x0000801dace5aca9,0x000179c203139436,0x000579d09c4fdbcf,0x0000b8c43e3ced43},{0x000f036040802177,0x0007090937e2ad5c,0x0007636ab7b11bc7,0x0009a49dc846e250,0x000015f05617398b}}, + {{0x000858e1e42fa26a,0x00096e07442f1d58,0x0000de8801c7a755,0x00023d647475607d,0x00002129ca073288},{0x0007cdea3e2c120d,0x000050b8231ee10a,0x000abbbc34902c47,0x0009866a41b80e7e,0x0000ea4fb6751c9a}}, + {{0x0005b9d57b4ca325,0x0009b07f8ae7c38d,0x000b67ba2c17122d,0x0004048b36db07a5,0x0000c13547ebaf13},{0x000fe5a101822457,0x000dbe78eba20f2f,0x000e71d40250d287,0x000744f58ef11ca8,0x000067b29ced3d7d}}, + {{0x000af127793627f3,0x0008811e51732d26,0x0007ba47d495211f,0x00011fbc5dfd6eb2,0x0000d0277a7c5305},{0x00059aba7caa2e14,0x000712d06c425aef,0x000b6687611ec682,0x00054599c6df92f8,0x00003f2120a92224}}, + }, + { /* digit=57 (1,2,..,8)*(2^{228})*G */ + {{0x0006605ecd65db55,0x000d72e421d3aa42,0x000cc1ef49735da2,0x000798f1cf926407,0x0000115826b66fae},{0x000b337ce7ef919a,0x000a7a6d6a5eabf5,0x0003c637e9a63491,0x0006f67021edb84f,0x0000746c950ad014}}, + {{0x000add3db7ec68b8,0x000b386d23ddc820,0x000c732406385f9e,0x000123ac503fd344,0x0000078adedd4745},{0x000755e7ed4c6729,0x000153f8260e01bc,0x00048d4be4a45000,0x0008bbb33fbeb49e,0x0000d816465d0546}}, + {{0x00074a9e86f273ac,0x0003768da9f3804c,0x000dda1996154227,0x000ef0ea5470f07f,0x00007a00585a4292},{0x000a3d7f108e6847,0x000633543471a24c,0x000deddbc6014539,0x000748d4d239446b,0x00003d82eda4eff3}}, + {{0x000157c30c88e767,0x0007447f23206d55,0x000fcbce3e45a30e,0x000a8919a2f6d341,0x0000644f481a46b6},{0x000508455987e93f,0x00086c52d4fb936f,0x000bf1494782ed2e,0x0009b3b64ef22f7a,0x0000e271957d8d37}}, + {{0x000051f896c2e8eb,0x000d7a69b583160e,0x0003d49398fdf12f,0x0009af8ffbe74fcd,0x000031d40fe11379},{0x0003fa86ded14ca8,0x000aa3806ceb84af,0x000ded17778cfed6,0x000b7ad455ace48c,0x0000241e365b6a4a}}, + {{0x000cdf92ebb9f2d2,0x00044fa908ec5b55,0x000d433b1e41dba3,0x0008fdc8a882d661,0x00004a21b29f9689},{0x000b80cdc8345f8c,0x00040425ef6c9c1e,0x00017accb726646f,0x000c62cc4b52d668,0x00004fe7071d103a}}, + {{0x000fc5b114eed902,0x00092c1ec222ba0e,0x000e6278ac333ebe,0x0000b826bc3dff42,0x0000884990265b21},{0x000e3baff2f463ac,0x000065bc6b05e85d,0x00088711208431cd,0x000750c9d0a6d302,0x000019cb19f15c3e}}, + {{0x000595cd1fa2a781,0x000d8d8df7304d44,0x000bb98b416f08ee,0x000983c60b71bcf1,0x0000fe06b3f76c34},{0x0009429622589d67,0x000cb9a4835859dc,0x000cb478d834436f,0x000f5234e4a0f0d2,0x000076555e5f3c86}}, + }, + { /* digit=58 (1,2,..,8)*(2^{232})*G */ + {{0x0004c9b20d431706,0x0002e62f23f2d925,0x000d0bef8e6b4e0a,0x00055d8206cab71b,0x0000c95a2a5e55d4},{0x00031469c615f1a7,0x00031aa9f2ac02f8,0x00069d5a83ea26e1,0x00016bd3403f8e61,0x00007f5ad3cb507d}}, + {{0x0008b75007f2d3e8,0x000b9583ae9c1bde,0x0007fac5923887d3,0x000d750b4e0af6d9,0x0000d1ef5fdad135},{0x0004069ea597b54b,0x0003bafe02358f2b,0x0006368b73835819,0x000671cfc31b8b85,0x0000fde8d8c56c72}}, + {{0x00028ad2a84e6c41,0x0004fcde36d07576,0x00017717c0d9fc24,0x000484cdff722d7b,0x0000ebe7611ea3b6},{0x000c336b09195735,0x0008ab520226040e,0x000064d14bbbb3e8,0x000ac8c886c34ecb,0x0000b85de43f45af}}, + {{0x000dcefcddd2868c,0x000b79e558df0194,0x000a5ea22e49ccca,0x00091ce24230da4b,0x00002dd640a90582},{0x00072d824d931811,0x000feb2a47d4c5ab,0x000efbe07e5114c0,0x000d6c17355ac9ab,0x0000fcd91a520be1}}, + {{0x000b8b3bb657e0d1,0x0002823cbb13d1b0,0x0002507060487a33,0x0003073a998799f4,0x0000a4673e731318},{0x00071b9484805f36,0x000b92e3ecebb211,0x000b1f5665228e4a,0x0000fe71f17cb6c4,0x0000fab132e7caf2}}, + {{0x000e8ef838c9fbc1,0x000c452de7e5c194,0x000973312d33ad9f,0x000d8b33dfab2860,0x000073e06257b5e1},{0x000ec0507e35022e,0x000df264cb1bf3d1,0x0009551e8ee3b962,0x000b4deed4c1f9d0,0x00009cc539a7598a}}, + {{0x00094abebcf27683,0x0008e09a607419d5,0x000262210bc3d71d,0x0004daef3faa71e6,0x000036cd41505615},{0x000a29a36702adec,0x000ba91eb78399f1,0x00052519283d6b50,0x000ce18f048aafb3,0x000081d651ae4804}}, + {{0x000a55b52ea9cdb8,0x000fab5ef7d92893,0x0007df294c2baacf,0x00036dbb62480d4a,0x00005fd14d5bdd1a},{0x000d5e9d7d31477a,0x0000715309eadb09,0x0009f58728a80fa4,0x00022c35adea7de5,0x0000ddf8bf0e739b}}, + }, + { /* digit=59 (1,2,..,8)*(2^{236})*G */ + {{0x0008d2fe5724a2d6,0x0008a411e84e0e5b,0x0002f5d04e3bf4c5,0x000d0d132a5db84d,0x00001765a592c24b},{0x0008b4a422ebc11c,0x0004336f3eb82fab,0x000c454ae73559b6,0x000b3a5108cb20cc,0x0000bc49662e3c97}}, + {{0x000dc9d1ec6f170f,0x000bea3af2ebc2fd,0x000ced852c3855dd,0x000b601b1a0af843,0x0000efe50594d52d},{0x000740f316de5b77,0x00051bb62771deb1,0x000a7a84b76a9d83,0x000c81aae829277a,0x0000e1420c11bfa4}}, + {{0x000d60f8e1cfb95a,0x000af10cab91f1eb,0x00038fbbd9345d96,0x00016c852bedd9e4,0x00005be88d186e1e},{0x000701924533f212,0x000417b9e05614a8,0x000660adcd80a4d5,0x00039c726fd26c76,0x00000cb351353c24}}, + {{0x000fcf57c64d0fe1,0x000089aeeaf8c495,0x000d0e557f623c19,0x0001b346cee7aa73,0x0000e3399090fc9a},{0x0006eb38aad81cf7,0x000a739b6057604e,0x0000db9b5314c754,0x000f3472d7d343c0,0x00004c1dfbe3a0a5}}, + {{0x000701a7d15ac5c0,0x00023520a981b0d0,0x0003b61899d2b0df,0x000d9eb9c1c354cb,0x0000a66e6fc26984},{0x00090a54c87214b2,0x000caefdcf2b9218,0x000333ea2b996b05,0x000111ae66ceef0b,0x0000fbf98e12d06c}}, + {{0x0002d09a5a1d9cdf,0x00039db4f6d01b11,0x00027c414e4622ba,0x000bc3b3be73c6bc,0x00008bb6de003282},{0x000e59669367bb32,0x00042eee7de13f4c,0x000535f66fef6436,0x0008d7d70177e2be,0x00000eff574037b4}}, + {{0x000291aba861ed06,0x000e76c048752a14,0x000e5d81960c63b1,0x000d9aa9241f2702,0x0000cb8d90ea933b},{0x00055408ef3f36fd,0x000ad70a653d61da,0x0003a9daac2f423c,0x00082428fd1b648d,0x0000eccb9ac2171b}}, + {{0x000848949c160154,0x0000e4f8be762b49,0x00006d459f779d3d,0x000d6b1fa2a9ee4d,0x000073144722cd51},{0x000631594e5d8939,0x0009ee5d23a84178,0x000d6db14456f57f,0x000650e1f892f3b1,0x0000d7a0b3f34fe0}}, + }, + { /* digit=60 (1,2,..,8)*(2^{240})*G */ + {{0x000585113ba8dd62,0x00080ea1f095615b,0x00065f617af767a6,0x000aab6be0a28ad7,0x0000085f54531694},{0x00033ed1deec48b1,0x000ae0b30df8aa1c,0x000b877911cd914a,0x000e64fcbaddda07,0x00004abbcd21ba68}}, + {{0x00032b33d4f558d6,0x00037483e07113c9,0x0008ea602fd9386b,0x0000f762b6e4a5d3,0x000040b7b04b7684},{0x000f178169d618d6,0x00020510dbbf08dd,0x000885aab8e91f1c,0x00043069b211d07c,0x0000c105f022a618}}, + {{0x000568d0917c4acb,0x000c55a83cdd60ed,0x0004cbae30f32f9c,0x000d8992a50602fb,0x0000910f7a813c33},{0x000ec2057b354ced,0x00035c70259217fd,0x0008e56f3c6925cc,0x000490b6e93831cd,0x0000a336551d0bd7}}, + {{0x0008835dedbc740c,0x0007d25913cc16df,0x000ce91f116c9a1b,0x000808dae18bc5b6,0x000071a394c1d139},{0x000ce433b9ac0821,0x000ead865a40ab05,0x0008bc6703c50add,0x0000029696559643,0x00009a0bfc436be6}}, + {{0x00066dd6d2079f06,0x0004c3d42e06189e,0x000067cd28417e6e,0x000130050bf07794,0x0000de2c929cf8ba},{0x000333b1e86df344,0x000b967ff99abde3,0x00009477132566ad,0x000536ed7c990355,0x0000973cee61a30e}}, + {{0x0000428dffccb096,0x000cfe784d6365d8,0x000f0f3311b8f429,0x000378330bcb7443,0x0000aa82351ab1ae},{0x00058c1fb6bdb9c6,0x000e9efa4faf8433,0x000dca1d65a933e3,0x0008101ceced8538,0x0000d4a8d9e6e600}}, + {{0x000e6c984782812a,0x000b4f7be42a5821,0x00004697d39f6d6b,0x00067b1a9d3fc608,0x0000472dc3a58087},{0x0006fec314288ecc,0x0007d25d30c31f70,0x000aa52b5e0e12c8,0x000798de7b7eb72b,0x00005698fa1698c6}}, + {{0x0009650f1aafc77c,0x00018b07e50122b3,0x000b118b6d8a8280,0x000784d7bdd744f8,0x0000b7a7039bee26},{0x0003cde18959c8fa,0x0004df71fa38477c,0x0009110e30c5b652,0x000a5bb8a3d815f1,0x00000fab64c70c58}}, + }, + { /* digit=61 (1,2,..,8)*(2^{244})*G */ + {{0x0009c02205f112dc,0x0009e952f41deff1,0x000acc7b67b111a0,0x0002d1d510e44a59,0x0000fa3e8511d623},{0x00051ff946f13b54,0x000dc69c4b7d692e,0x000317f509655586,0x000e6b4462e6392c,0x0000a96c730c5b29}}, + {{0x0000a3933301eb25,0x000a651566c5c43e,0x000854f45d136c9a,0x000a9b44acff9c91,0x0000afb49c7ad947},{0x000a2e067e61d8ad,0x0004dc10dc1eb2bf,0x000135c5137c224f,0x000bda57488cfd8c,0x0000c44a7f8d059f}}, + {{0x00052723d33fd8ae,0x000d77c5b0f7bd45,0x0008bb677dfa7a03,0x000ac19a96990c2c,0x00004b6f2495b079},{0x000fb6607adecf05,0x000bde2919ba0f93,0x00090c3da815b883,0x0000a7d12075a3bd,0x00004310fdce89c8}}, + {{0x0006c13cc1c1b2ba,0x000707f3e5f9f11f,0x0009e009feccf526,0x0004546bd9afe153,0x0000da180beb161c},{0x000f8417a1d44bc5,0x000008e325fc3ee3,0x00006399ac1041ab,0x000580ee77109540,0x0000ceab562965db}}, + {{0x0001872bafa156fb,0x0007a216ce400bb1,0x0007b96951ea5324,0x0007767e0f72919f,0x0000be25883d565f},{0x000a586c9ea652aa,0x00077eb211f7dc69,0x0005ba936a575e48,0x000dacedab8900e5,0x00003e88330c056f}}, + {{0x000fab17514db1c6,0x0008172813b230d7,0x000e97892cd69e71,0x000cdff6a634d0f5,0x0000c7df5b396089},{0x000b9815a106666f,0x000a1a74f7c4f830,0x000416725238afc5,0x000ab9aa0a7d2edc,0x000091170e9acf8b}}, + {{0x000a68529f79ae19,0x0006ae151c3ebe53,0x000797f52949338a,0x000e08fc9db14d5c,0x00004a632a0f71db},{0x0004b14f4695b847,0x0005adc149f75b88,0x000082eb2d6c5560,0x0009f624e9b8946a,0x0000a038b421d27b}}, + {{0x000db6d961011f15,0x000439b319540c33,0x000964ccfd972723,0x0008f8acb18490f5,0x00000165db5b23d9},{0x0003f6e09555115e,0x00005bb146110697,0x000e9391de70734b,0x0006302d2b19436a,0x000046716ed749df}}, + }, + { /* digit=62 (1,2,..,8)*(2^{248})*G */ + {{0x000b8a4cbe978aa8,0x000fbc8ee3c76cb3,0x0003979fd2b05b7b,0x000d941563cf1162,0x0000e542d606a5d0},{0x0005e56df6f115ed,0x0003ca59ce6bb278,0x00017eef4378ebbf,0x0000d8c8dc4afaa5,0x0000a21b92c92f88}}, + {{0x00035dc5396eb247,0x000c8ef4e4ca4631,0x00072209072a4380,0x000c5c200bcef728,0x0000b72cb6549160},{0x000b0c5738b12183,0x000822e27bf1bc68,0x000f7cd34933b26d,0x000119eda10a224e,0x0000c80f888434bc}}, + {{0x000e0efb3b8b1b5d,0x00038959884aaf7a,0x000259a44d6afe4d,0x000f91f87b1959be,0x0000337331701bb0},{0x000b01a0216bb368,0x0000c5eca8c325e7,0x000671fd9f4f814d,0x000e76c1d3c91169,0x000010645e8443c5}}, + {{0x0005b4488b3fb1e8,0x000d26b23a5d8961,0x00056a2fedc3595e,0x00081de771fe19e3,0x00005b981b48385a},{0x0002c4f79da9b17b,0x00017541a1f22bff,0x000fb8bc6c4a7592,0x00033ea8e920a8a6,0x000037f6be35ab5e}}, + {{0x0006210d9e58a61a,0x00029b5224c08dca,0x0003db93fef2cd7b,0x00002ae4f2bbb09b,0x00004673f3e36b54},{0x000acede4893a3e0,0x000167a09cb54d69,0x000fb53a3b5bd9ea,0x0006f485791eef6d,0x0000d389cb15387b}}, + {{0x00078c2ec1e3ed4f,0x00051691416a6a5e,0x00085c63595aa0e1,0x000163b5d8f860c7,0x0000283d923fc854},{0x0005beef7ad3f5b3,0x0007b815ad735813,0x000023a1511c7557,0x0006b79bab4cc9e0,0x0000199d8c4e721f}}, + {{0x000e42f66dd9a70c,0x0000846de6736294,0x000e21f936b36c3b,0x000215cc757f7aa1,0x0000e42c4db111bf},{0x000f78959874b51d,0x00067dc910778965,0x000f6350f2c2eb73,0x000e53487a0d690c,0x00008713f1619ac6}}, + {{0x000bdec2116e9b29,0x000389c76497ee80,0x0006bb3874fd1cc1,0x000343fe15d2b0ac,0x0000a3fadcb3a4e1},{0x00037248e9d64745,0x00087efa63b10110,0x0007dd6bd1db932c,0x000c6c78bf9e3fa9,0x00009e31d0655466}}, + }, + { /* digit=63 (1,2,..,8)*(2^{252})*G */ + {{0x000be5ed0e405bae,0x0007fc91ec34f9e7,0x0004b79b18f54024,0x000b106f3d8772d3,0x000037037c975e12},{0x000aec44147d71ff,0x0003d1931e82b100,0x0007bf1327384e2c,0x0002fb55ec63d285,0x0000df2ba6d3b215}}, + {{0x0007a23f356e3059,0x00041e71e29a3efb,0x000f94f0f0f98de8,0x0007a880ecbe906e,0x00002d869e92df60},{0x000cf0bbf87a34ec,0x00089c2efd2119d3,0x000ebfbd0dd06fa3,0x0006c851303198c6,0x000030a29d4bfdd3}}, + {{0x00089caef387625f,0x000fcb72b7247593,0x00017a38174726e5,0x0001b102c945353e,0x0000fcd0db4d1457},{0x0003429bba3484a4,0x0001753db65ef147,0x000e6a574289160a,0x0006d9c5f2dc2cb7,0x00005d42b1ac334f}}, + {{0x00012c9e1ee0d0a1,0x0003490b01e6e274,0x000da05414bdd548,0x000de03a9047e2cc,0x0000c371569c9623},{0x00078851bc8c9a7d,0x0000d36794075521,0x0006dbaa6726fc38,0x000ce611949c5013,0x000053af2d9b1059}}, + {{0x00035aa24062df0d,0x0002a52fb85fa4ca,0x000d94e1eaa94f02,0x0001840aed61257c,0x0000fb93c2113070},{0x0000d05aabec972c,0x000f75d4421fc835,0x00007292ec8f71dc,0x000b37558f6df8ee,0x0000d9d09ec67e4f}}, + {{0x0000235a102cb4ec,0x000fb35a64785f45,0x000b0f0672f75fa1,0x0002e6467bc56637,0x00008030444d7012},{0x000881065be741fe,0x000b8d8f2c4aa658,0x0000fb14fbdf31d8,0x000b607bac347583,0x00006adf01034a09}}, + {{0x000f12502f6f25d9,0x0000c22cc1b5e838,0x0000f6f93bcc544b,0x0008c7ddfde2d4ad,0x0000c68d49d6c0f8},{0x0003511dcdcef6f9,0x000a7dc7783920a0,0x000dbd6b689c8148,0x0000f52a6e80014a,0x0000730b2f927704}}, + {{0x000211e48a709134,0x000a06d95a7b1a29,0x0005aa515d70a8ec,0x000baface9c4e7ad,0x00001420ee199ed7},{0x0005f92e47355a0e,0x000716ec78ef1f42,0x000fe05e173edf3f,0x000e4dfe82b2c090,0x00005f26894a26e6}}, + }, + { /* digit=64 (1,2,..,8)*(2^{256})*G */ + {{0x0008910bd3c74498,0x000d8af3aeac968f,0x0008cc252692ed9e,0x00067be64e4f7fee,0x000092836060ef1c},{0x000890896b28139e,0x000470cc9c0726e3,0x0009a0eab753f427,0x00046bc1b1530956,0x000038600b6014d5}}, + {{0x000cd15a3cc6fb9b,0x000a19f82e4c6346,0x0003cd730abb95f1,0x000222f258efb831,0x000068413078deb3},{0x0001e7c1ed462bd3,0x000d5fdbfcd8fb51,0x000f5c6d0b354d1b,0x000acc02f31db2ee,0x00009cf8f2c231b2}}, + {{0x000ee3e9bd875a0b,0x00079f5903fa2711,0x00029af6a861120e,0x000561354e6da0fd,0x00000c0f6913abd6},{0x000948148819fd8a,0x0008e1ce27a94979,0x0003f4d9497c8870,0x0002f21ca36d254e,0x00009bc3a89fe40b}}, + {{0x0004af860fe1d658,0x0005c3a43228d831,0x00003626b989c96b,0x000ceba2924ae1c3,0x0000c45b79310a64},{0x0002ceb1de0d0667,0x00088613f714aa18,0x000d68a9c780c9b4,0x000a36f94f51865a,0x0000055e19d4f0d9}}, + {{0x00014fc2a4b59f10,0x0004bfd2f9fd51a3,0x000216cbd55294c7,0x00097be507f2f1fe,0x0000924f1faac4f7},{0x0003541b7a3d4f01,0x0003c8cb55fc5c6d,0x0007ec5dc6c3980a,0x000f63bcee3510ce,0x0000ab63b2a3eef9}}, + {{0x000560910cddf7bd,0x000a825eca445df4,0x0001e77f13b9bb31,0x000af16bcf1af24f,0x0000d48e4c17550d},{0x0005fc863ac98830,0x000ec32093eaa327,0x0009073fe1808aec,0x000fee1100183134,0x0000b88f64b6ab63}}, + {{0x00017535ffca9e3e,0x0004c4176a9f05d0,0x000b8e9c9e88a67d,0x000aa685e06ca4e4,0x0000941d64ce2bd7},{0x0004eb4d5b7fac46,0x0003ece406851d75,0x000f3bfe1359045f,0x0007cb734afa3acd,0x000087d6f48d53f1}}, + {{0x0004ef0fb7992ec5,0x000237355dbd4b3d,0x0007914aabfa41db,0x0003654621f87992,0x00002b7c7dfd2d83},{0x000c21100586c6db,0x000ded8f1bfb12a4,0x0008223d7b6ca10c,0x000b4b5146ab877e,0x000069c991a7978e}}, + } +}; + +#endif /* #if !defined(_DISABLE_ECP_256R1_HARDCODED_BP_TBL_) */ + +IPP_OWN_DEFN(const cpPrecompAP *, gfpec_precom_nistP256r1_radix52_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 4, + /* select function */ p256r1_select_ap_w4_ifma, + /* precomputed data */ (BNU_CHUNK_T *)ifma_ec_nistp256r1_bp_precomp + }; + return &t; +} + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif /* #ifndef IFMA_ECPRECOMP4_P256_H */ + +#endif /* #if 0 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p384.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p384.h new file mode 100644 index 000000000..69dfb3b26 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p384.h @@ -0,0 +1,1129 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_ECPRECOMP4_P384_H +#define IFMA_ECPRECOMP4_P384_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" + +#include "ifma_defs.h" +#include "ifma_ecpoint_p384.h" + +#define BASE_POINT_WIN_SIZE (4) +#define BASE_POINT_N_ENTRY (1 << ((BASE_POINT_WIN_SIZE)-1)) + +#define OPERAND_BITSIZE (384) +#define LEN52_P384 (NUMBER_OF_DIGITS(OPERAND_BITSIZE, DIGIT_SIZE)) + +/* P384 affine point */ +typedef struct { + BNU_CHUNK_T X[LEN52_P384]; + BNU_CHUNK_T Y[LEN52_P384]; +} P384_POINT_AFFINE_IFMA_MEM; + +extern const __ALIGN64 P384_POINT_AFFINE_IFMA_MEM ifma_ec_nistp384r1_bp_precomp[97][BASE_POINT_N_ENTRY]; + +#if !defined(_DISABLE_ECP_384R1_HARDCODED_BP_TBL_) + +const __ALIGN64 P384_POINT_AFFINE_IFMA_MEM ifma_ec_nistp384r1_bp_precomp[][BASE_POINT_N_ENTRY] = { + { + /* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x000607664d3aadc2, 0x000fa3dd07565fc8, 0x000e1e26a4ee117b, 0x0003afc541b4d6e6, 0x000459a30eff879c, 0x0004ede2b6454868, 0x000513812ff72361, 0x00000000000299e1}, {0x000af93c2b78abc2, 0x0006e23043dad1f8, 0x000d385481a72d55, 0x000e7562e83b050c, 0x000968f4ffd98bad, 0x00069a840c6c3521, 0x0005e9dd80022639, 0x000000000005a15c}}, + {{0x000a271bdb93b776, 0x00066c8229e549ca, 0x000a0046a4ddbf0b, 0x000e6f0ff9d48a26, 0x0005f0687f503504, 0x000e4b506da82149, 0x0000c39c90a4fd2d, 0x0000000000042746}, {0x000777e3e34947f7, 0x000cf42ea84624df, 0x000c322ca0a5f414, 0x000f18bdc588259c, 0x00015172bad915e4, 0x000b0e68409f1fe4, 0x0000c2070d430900, 0x00000000000123df}}, + {{0x0008420bd283fe68, 0x0000405e4dbe5ef5, 0x0007d2a868c2d376, 0x00034e9a170ccf19, 0x0002d51c6c3e6b20, 0x0003aa4703a48d73, 0x0003ace36f7e2d26, 0x00000000000e7c1c}, {0x000a7b5b465465fc, 0x000697e28482179f, 0x00092befa3c13549, 0x00063c04ef67446d, 0x000ad2e1d0b41326, 0x00002b33968012d5, 0x0002aff6db68b151, 0x0000000000098329}}, + {{0x0007a84fcfeee6dd, 0x000c00aae84771bc, 0x00004833a9bdf308, 0x000153b0aecac470, 0x0004736400ad2e4f, 0x00085d979078358d, 0x000228fb40f647d6, 0x0000000000034179}, {0x00059b3d50946875, 0x000f354f3e8e74aa, 0x0007e02066cc9331, 0x00061a34c542ad23, 0x00030418c6938e3e, 0x00020017d147162d, 0x000319e607b9e338, 0x00000000000303df}}, + {{0x0006ca2ee1bb26b1, 0x00017bb595eb9873, 0x000340e77dae425b, 0x000b1b5293c703ca, 0x0005aacc05e67f1e, 0x000e8e4c660db2cf, 0x000ffbc676b987e2, 0x000000000001d178}, {0x0002304b4db1c9d6, 0x0003c2b694ba022c, 0x0000733804c0a50f, 0x0001b3101c35b997, 0x000f982c041180b6, 0x000de236d4b237fa, 0x0004a3e6c5944024, 0x00000000000e209e}}, + {{0x0003f94fc482e189, 0x000c37eb5c930b8d, 0x000fa7363cfe5622, 0x000930f580d57f38, 0x00061bdf6015ec52, 0x00002d33b2a33f66, 0x000c404f0f6a962b, 0x00000000000f0430}, {0x000a60b1c9962152, 0x000203f62b16dde1, 0x000d30e7f024d36f, 0x000bffcb79e33b13, 0x00061b546f058bd4, 0x00021559a93c9e5f, 0x000eba586d8ededf, 0x00000000000af2a9}}, + {{0x000c82aa932c9f81, 0x00032df13b9d0ea3, 0x000012e0e11a7414, 0x000dcf8211faa95e, 0x0001659753ed731e, 0x000b2df555f4215d, 0x00025bf893db589d, 0x000000000001c890}, {0x000c8f68d90a16b6, 0x0002f0996b21f9df, 0x000c5d608c816e33, 0x000d76f50130844e, 0x000401fff78065aa, 0x0003b07060ff37c0, 0x000b3ef57f238e69, 0x00000000000af6c9}}, + {{0x0006da365db4f184, 0x000fe23f60a057fe, 0x000be85f6a0c5049, 0x0002e7193d7e30ff, 0x00064f3ddb371c5c, 0x000b664231d9aebd, 0x0009b11c7b5fe116, 0x00000000000349cd}, {0x0008ec6d3c0c6dd7, 0x0005e0d2cfe83aa5, 0x000f7a290df3f1cc, 0x00054bf7d8686e4b, 0x0003a42dbba27017, 0x0008ecf0ee992326, 0x000f617008d943c4, 0x000000000000d27e}}, + }, + { + /* digit=1 [{1,2,3,..,}]*([2^4]*G) */ + {{0x000b56e7a10896aa, 0x00082da6e8a7edb2, 0x000a339205afd669, 0x00065517917652b3, 0x000a2887d5ff37cf, 0x000bdc3fa317b63e, 0x000aa137065f5313, 0x00000000000435ab}, {0x000e15a5659db481, 0x0008e9b21615f8a0, 0x0000a5926b88aaa4, 0x00071dc154d41105, 0x000bc88ee1489148, 0x0002d1967b333bdf, 0x00051351c305c6a7, 0x0000000000081ef2}}, + {{0x0007c0045dd2a4a0, 0x00075ad852b872e3, 0x000b4af19266ca1e, 0x000b9fcc651b1dd6, 0x000612e8dc871896, 0x00031cfb0ba8953d, 0x000d793a9865baa6, 0x00000000000626b3}, {0x000b7328c510ad93, 0x000901148bc71a36, 0x0008838d56b7b5d9, 0x0005f9e9448fd096, 0x00000a2377b67731, 0x0005b4ff04bcb06f, 0x00099f73b42725b3, 0x00000000000aabca}}, + {{0x00077d8466e4794b, 0x000763ccf806a4c7, 0x00041b06944ed785, 0x0004e06ea52bef99, 0x00053a7d2f3c4f50, 0x0003a1bc940d01ff, 0x00040062e5c5d3e7, 0x00000000000ae7d7}, {0x0000b071271e42a1, 0x000923d30625e38e, 0x000c9ea33ece8520, 0x000a10d04bab9856, 0x00009da2a2ca5c3c, 0x000c9462c2605ca0, 0x00058348eab00eb5, 0x000000000002624a}}, + {{0x000c57a24f5d5ab6, 0x000eded4de4f83f2, 0x0004d9f2c578d7f4, 0x0003d30f8a0580de, 0x000dca57b7bde04b, 0x000e44d56a309199, 0x000e5cfc8e87cf3b, 0x00000000000d1b30}, {0x000dc1d0888b708b, 0x0008cb213c69fa81, 0x00085d35b9791d2c, 0x000bbbf1090fede9, 0x000c301fe259fe51, 0x000cd3fe86d97cab, 0x000a513ee127895e, 0x000000000009404c}}, + {{0x0004d8911e8568cc, 0x000c5194924b48e8, 0x00026b2f852cc83a, 0x0006428b12136094, 0x000351fea1dc4906, 0x00015ace6dd2ec6d, 0x00024620fe8c27a7, 0x00000000000a4463}, {0x0003c328530abb42, 0x000b900c213bba9c, 0x000bf43a5f2c2e1e, 0x000903c6484641de, 0x000a1378e68fbc7a, 0x000cd8ae42413063, 0x0006f9b960b5efee, 0x000000000000614a}}, + {{0x0001dedb8bf3dccc, 0x000a0dc529384912, 0x000bc9fafda07c1d, 0x000597e52ce08f71, 0x000581998af2ee21, 0x00041eb4226de4c6, 0x000b96cb4aa43c97, 0x0000000000039c18}, {0x000a9ce2b257fb6c, 0x000a566e1d5da261, 0x0002d61f72303077, 0x000396f305ee4f10, 0x0000c831254b8545, 0x0005680b8f9d19ea, 0x0004a4cee0842f5d, 0x000000000005a443}}, + {{0x00007168b4a67147, 0x000a12e206547853, 0x0001c6a852120cb6, 0x00009d5504c8129c, 0x000c9710b70b2b56, 0x000296a52fb25e37, 0x000dce83f2fd2cd8, 0x0000000000062f45}, {0x0000b128f82bb944, 0x000a8a818b9bda93, 0x000ed2d611039805, 0x000e43a2ec76a180, 0x0007caa846883e7e, 0x000182141473e687, 0x00004db9a19eb57c, 0x0000000000045ed2}}, + {{0x0001e64ba6661cc4, 0x000cee484fd9edbf, 0x0005b5c2b4988114, 0x000449e7c1c3984b, 0x000118eb5195c0dd, 0x0007a16d2f313389, 0x00020a0336aab877, 0x00000000000c2417}, {0x0001e21e239dcab2, 0x00034678db970845, 0x000627331787ffae, 0x000a0e4a022c7a44, 0x000434a02a6b5d85, 0x000791ce3b01f1e0, 0x000c5b2657eedda5, 0x00000000000a277a}}, + }, + { + /* digit=2 [{1,2,3,..,}]*([2^8]*G) */ + {{0x000fa21fa335ab82, 0x000a49a7a5b41c7a, 0x000300862e13765b, 0x000438e3d9f0e627, 0x0009e328c2e27539, 0x000cbf891013c671, 0x000d287f4a706ccc, 0x00000000000735a2}, {0x000a7119424dd00b, 0x0004246694eeffb4, 0x000059afb703b483, 0x000ed8b423d47e45, 0x000bf44c91809d54, 0x000e9b3848075a8c, 0x000c75d4f5b184ab, 0x0000000000041abd}}, + {{0x00093e732cc6e06c, 0x000c65e2cb07faab, 0x0006c10c7767a2e6, 0x000c53fd4de1f262, 0x000c838f7169a296, 0x0008a6ce7d408060, 0x00067168e19d7b2e, 0x0000000000094b58}, {0x000136755dca2adc, 0x0000293d02a07640, 0x000ed9dfab92ca5c, 0x00069f51aa3bc4ef, 0x0000dd09b1426aa0, 0x0002e59450e44fbf, 0x0006ace264f34383, 0x000000000001fc16}}, + {{0x0001b41eba2511e6, 0x0003e9ee4f521f6d, 0x0005af7a840c9880, 0x000396db7edb07d1, 0x000c2e8290630d5f, 0x0003495da09b3457, 0x0009b8f1d28188f8, 0x00000000000cce55}, {0x000f6b035c499b66, 0x0005617cbaf577ca, 0x0007eb3582ad9848, 0x00008995145b8fd9, 0x00081a33b1a72982, 0x0005149e992cb5da, 0x0004c0ca49fe334c, 0x000000000001772b}}, + {{0x000b80038e0f9767, 0x0006756ad758212d, 0x00066af19dfc2941, 0x000c6ffe2c8b0369, 0x0007fcd7336b85f2, 0x000a46acd55c6d35, 0x000ac7b1ecc56d22, 0x0000000000036277}, {0x000330b02f145871, 0x000c1a4ed11e8d27, 0x000297add7ae640e, 0x000ba45266158ab0, 0x000d89e0dff05fda, 0x0006b02d06f0b27f, 0x0006e132ef7ae2eb, 0x00000000000cc1b4}}, + {{0x0008162061985fbc, 0x00005c112733b3ba, 0x00062ae17de90bd5, 0x0008e01810097859, 0x0002bfe16c4fbb7d, 0x000d9f8107640a3e, 0x0005d74e34813ec1, 0x000000000008d260}, {0x00078cdfc58ed763, 0x000f72a544cd81e6, 0x000e167259300b75, 0x00057bacec18a7f0, 0x000511b882d69e61, 0x000f86563a555fc9, 0x00096e4305a4dd04, 0x000000000001d0fd}}, + {{0x00008da90a96090a, 0x00032f04145e8229, 0x000a916fb6ff9132, 0x000ba4e12aa299fb, 0x000991b3b5179ffc, 0x00081c747cc5ec24, 0x0003eb9edcd4616f, 0x0000000000077a88}, {0x000a4909883002a4, 0x0008b9b0bab581a7, 0x000e659d0317cb87, 0x000d81e438a9d43f, 0x000e25ca8b3cfe8c, 0x000bc720cf40e2b5, 0x0006a34254030067, 0x000000000006b244}}, + {{0x00099b58a43c6d42, 0x0005180e1cd16205, 0x000e96620312fe6d, 0x00019d509ddce071, 0x000e70c4b03267a0, 0x0003ba57e52573e3, 0x0004f716d253e14d, 0x0000000000016250}, {0x0003e944594baca0, 0x00013a237bbf8f9b, 0x000a642b05f4171f, 0x000531a1f384daed, 0x0003981251654b13, 0x0002dccc139067f3, 0x0007b5e98fb14167, 0x00000000000a75e2}}, + {{0x0009f542630002ea, 0x00044e65245ce93e, 0x00012350ea59da7e, 0x000c121bad2c8070, 0x0002060fcf245677, 0x00078cccac52dec3, 0x0006fb78d070675d, 0x000000000001bc8b}, {0x000ac9684403d046, 0x000b5c5cb86bea72, 0x00053d522dc955a1, 0x000cdf2c92a70d83, 0x0001f53cd2a1fbb7, 0x0004f11395a9ff1f, 0x0009f1fdbe6b7a98, 0x00000000000a470a}}, + }, + { + /* digit=3 [{1,2,3,..,}]*([2^12]*G) */ + {{0x0006766eb19e084c, 0x00028eb06571b5db, 0x000430cbda13e4c9, 0x000966726eed225a, 0x00046100e387a185, 0x0006298d18d9e56e, 0x000ad0470506b9dc, 0x00000000000f3350}, {0x0009595e79f27f3a, 0x0006683eb62a798b, 0x000ae3d2069c14b3, 0x000e880e1bd4a82e, 0x000fcaf3b3fcb089, 0x000ffd65cd4d1e70, 0x000ebbd0b1ec6395, 0x000000000009b184}}, + {{0x000d72326a677bdc, 0x0001bd4277730e1a, 0x0004e8c2adc8ef98, 0x00046b099f1867d4, 0x0002602dd4cc6b07, 0x0000811201ec73d7, 0x000f2d27fae51538, 0x000000000002f8b2}, {0x000e28e4b1971c05, 0x0001bb924af64246, 0x0005d0fd898e9387, 0x000e9ae068565acc, 0x0005a9a4f1464e88, 0x00093f7348a3dbd2, 0x0003bcdb4a3e483f, 0x000000000008f1d3}}, + {{0x000da9f02128c46a, 0x00049d1de964bafd, 0x0007f571d595c1ce, 0x00055af0de9eb074, 0x0005a60289bfbc4b, 0x000392c619f11b99, 0x0004fc3e59000c52, 0x000000000005ccff}, {0x000c017748720be7, 0x00064b28b306ba1a, 0x0007e101bd3e41b0, 0x000542ce3f824faa, 0x00022f52b71c59b0, 0x000c6d26370f097b, 0x000e5b4483b72604, 0x0000000000034d93}}, + {{0x000b2e0b9f0415b8, 0x000c7721bb8359b7, 0x000a5f46c16031df, 0x000a789348538714, 0x0007af598c4f9cc9, 0x0006f27c878b604a, 0x000ba5d370375e47, 0x000000000000b15c}, {0x00021b9613cec089, 0x000662bcfd9a4c03, 0x000e3ea0c45f94ee, 0x0006464a211b19f3, 0x00019990b504b05a, 0x0004951d3ce059d4, 0x0007b0011c5f87d9, 0x0000000000000d9c}}, + {{0x0002533a1c8fbed1, 0x000ce64e84c28804, 0x000338cbe4f167c9, 0x000d9ed9fbf23cc9, 0x000f5b93118bb77e, 0x0006255cf155fd45, 0x0008941e9f6d7d9c, 0x00000000000c4f64}, {0x00008205c725e2b1, 0x000154bc3a502a87, 0x00030c3fbf39b6ac, 0x0005548d3c862428, 0x0004030f713cc7df, 0x000785cbf9dbfc08, 0x000637f3623326ad, 0x00000000000dd3ad}}, + {{0x00053a3eba12bfa4, 0x000ced8b8b37a274, 0x000ff25533a7ef36, 0x000684bd17d58a93, 0x0002032fda408ac7, 0x0004b49645f9557e, 0x0001097fe128e6ed, 0x00000000000ed02e}, {0x000f765f56c35dab, 0x0008c0052d88eb68, 0x000256931b154329, 0x00010798446a4f6a, 0x0007c99ad35fbf46, 0x0000906073bc4391, 0x0008aada18234dda, 0x000000000005164f}}, + {{0x000f715095892612, 0x0004e02c16c7865e, 0x0009e82bb73222b5, 0x000bbc0795486af0, 0x00070427332d3abe, 0x0005d3cabad858cc, 0x00019c9a1d4b6aa3, 0x00000000000e208c}, {0x000d5b54420318c5, 0x0000afcc14276eea, 0x0008e6c4a86b5358, 0x0007cb4e7706b5bf, 0x000e479e2c750027, 0x0007ad688c01ed42, 0x000626ff1759604d, 0x00000000000c045f}}, + {{0x000e0b227c3a04b7, 0x00029f365419f1ee, 0x00001db5dec2705b, 0x000c165c41880aa9, 0x0007f9712fbd8a91, 0x000c556783eb27a9, 0x0009cfa6587aec76, 0x0000000000002cd7}, {0x000e78bc85d2b5fc, 0x000fefc878f9c549, 0x000d411713959cf3, 0x00084d8caf6df5e8, 0x0002aabcde7509a1, 0x000de597ad32bf23, 0x000858f601d0de03, 0x00000000000c5da2}}, + }, + { + /* digit=4 [{1,2,3,..,}]*([2^16]*G) */ + {{0x000f068a28ea9470, 0x0008bb6029961859, 0x0007d86ade910602, 0x000693b4df3e5b1b, 0x0008a0c3e35782db, 0x000b2f577b513148, 0x000cc3bfb01ff3cc, 0x0000000000027a72}, {0x0000fdf0e7cd346e, 0x000f626170927fbd, 0x000aa1bbda6cc535, 0x0006a634c872d772, 0x0000b14d9c9f0bec, 0x0006c7778a0a7cc9, 0x000a4c8a32d2c44f, 0x000000000003b889}}, + {{0x000f462aea173d82, 0x000a4860ef793767, 0x000a7a5856850902, 0x00083662ee7f523d, 0x000f54122af0322c, 0x000bb2d8058ccd95, 0x0005777454880c2b, 0x0000000000086d8d}, {0x000038487c4c8fb9, 0x00042d5a3057c6dd, 0x000955643c37ff31, 0x000c99ec3c512f97, 0x0006556d891e26aa, 0x0009f6112c3eac03, 0x0007e9866c3aa7bf, 0x00000000000c144f}}, + {{0x00000b161de71555, 0x000aead0d24c7983, 0x0006a55d94bbb854, 0x00034ff7655aa29d, 0x00057a5e217ea551, 0x00021b295a3d1038, 0x00036dfbb9eeb53a, 0x00000000000c84a1}, {0x000aac3258d9db81, 0x000087579398db29, 0x000fa470f6fa27aa, 0x0002e1e464522581, 0x0005479d8f2c99b3, 0x0000b80ef99d5495, 0x00050bc2a8a6a193, 0x00000000000656c8}}, + {{0x000f81f2532800c4, 0x00045171898aa3c4, 0x000ea2712f9cc33b, 0x000835ffdb2c1bad, 0x0001591f5aafbc0e, 0x000272c6a4ee3028, 0x00068afd71de3bcc, 0x000000000006e93f}, {0x000145dbf5847f9b, 0x000bc35ee08038de, 0x0001b04c30c2d081, 0x0007ff5957b2ff76, 0x000e5ec029c049f3, 0x000324c12315d8e7, 0x00057833230602ef, 0x00000000000966b2}}, + {{0x0003e43e11c6c113, 0x0002e86283e21e81, 0x0009c3e50b313030, 0x0009b1bb9784a9a5, 0x000ea0c0acb57d02, 0x0007c682b7c7798b, 0x0002b041241c716d, 0x000000000001d33c}, {0x00079a15b39e351d, 0x000dc5d469ca181c, 0x000ce825406e72f2, 0x0004cc2a13cf4ce5, 0x00069e3ce2793d05, 0x0004beafc13bd216, 0x00087e01bc70e68a, 0x000000000008aba0}}, + {{0x0009cf16a3c4418b, 0x0005884aa863e012, 0x00089c47322b55de, 0x0003206b5c399b2c, 0x00073cc109bd553f, 0x000384088775b921, 0x0003cf25c01263fe, 0x00000000000d5f74}, {0x00057c2efedc75c2, 0x000933d69705ce0b, 0x000359bbe99d9a50, 0x000ab1a2626cebe5, 0x000285b1afe80198, 0x0007e6efdaf8320f, 0x000bb6b9c0968ce1, 0x0000000000090215}}, + {{0x00066543cf4fd691, 0x0000d3ee52d8e909, 0x00094816ee49cd7e, 0x00095c61881a757d, 0x0009c13e370735ce, 0x000d2d3f60a8cf9d, 0x000c0de71258d548, 0x000000000000bbe7}, {0x000476d4cb00031d, 0x000bfbd6496e1309, 0x000c1c69b8768cb6, 0x000501358cfdfb53, 0x000b59275b4acbe8, 0x000f722ba655c902, 0x000aad7e0ff05b20, 0x0000000000042b17}}, + {{0x000b76411fcb09e7, 0x00066da643272cd3, 0x0006802b1cc8eac2, 0x0005a7c35b43943a, 0x00084606bbf22386, 0x00059fb9a6ac0158, 0x0001a59660ab7215, 0x000000000003ce2f}, {0x00083d9ad8b4f172, 0x0006e62af29aaa08, 0x00060fa06813a370, 0x00029b744c110388, 0x0001d36c2571ee9f, 0x000b552b7b2a19cf, 0x0003d4b87d88e265, 0x00000000000beb25}}, + }, + { + /* digit=5 [{1,2,3,..,}]*([2^20]*G) */ + {{0x0002b4a5d3a4b643, 0x0000231bdb4829ee, 0x0006d713dc69c388, 0x00042469b6fc64eb, 0x000a15786b8c18c0, 0x00063da4a0dcc15f, 0x0000fb81acdb068e, 0x00000000000dada7}, {0x0008c1ca45ab6321, 0x0009146361afe98f, 0x0001d88fcfcf648c, 0x000b61b615694e72, 0x0001872951d2f389, 0x0003badc77036def, 0x0008d340fd3bdad9, 0x00000000000380a6}}, + {{0x000d66b2c4fdf4c0, 0x0007ac5cf8997090, 0x000a08d2a2626f49, 0x000681e307b254af, 0x000775cd94d78139, 0x000684954cc87fb5, 0x00099190e7027478, 0x0000000000095ceb}, {0x0004649153ee63bb, 0x0006891bbc0ab337, 0x0001f845e221f84c, 0x0003d704b93d45fb, 0x0004f541da1f1cb8, 0x0007ffd10e229902, 0x000b9a3eef7ce14b, 0x00000000000b3fc1}}, + {{0x00067cf1182bf349, 0x0007f23c1f744697, 0x000288faa5d1b184, 0x0002c9d5afd1bfd3, 0x0004f89d76fea4f8, 0x000702f80a3d1e9a, 0x00089d964f705075, 0x00000000000f56c0}, {0x000478c2e0092e1f, 0x00012e205fa8ede0, 0x0002998cd8ea4a27, 0x0001004356d43961, 0x0001fdbbdfde331a, 0x000a00e7158b7890, 0x000a30a52a15979b, 0x0000000000055497}}, + {{0x000d05d101bb2988, 0x00097e5004e8001a, 0x000e96c63ff7fdd5, 0x00050d1bd869f77c, 0x000de7ebea2c405f, 0x0007620baecffa54, 0x000ff43354dc22d8, 0x00000000000b1c01}, {0x000d9286dd26e577, 0x000c2d9370076043, 0x00025722a20b989f, 0x00076273291e5c62, 0x0007f0a7ca55c0de, 0x000592a305cfebd8, 0x000ce4de1162809e, 0x00000000000a78eb}}, + {{0x000153343d6d3c05, 0x000a15562a856338, 0x00041dfd1ca25266, 0x000317409c75b8cc, 0x000124923f80c19f, 0x0005b291e21c7cc3, 0x000b05e63fe47f8f, 0x000000000000dc08}, {0x000a81ce4831b7d3, 0x0001558ae455ea5d, 0x0000f05c04530b31, 0x000c97f3ee3989cc, 0x0005f38759ae42c7, 0x000f46899c1b03af, 0x000c7d1a673c75bc, 0x000000000008d508}}, + {{0x000fc69642676f12, 0x0008d1e9b23b9bca, 0x000626ac6d6d75ba, 0x00000fe59b7721d0, 0x000c9e2f4cebd4cc, 0x0000af70ed5c36f9, 0x000799deca06bac9, 0x00000000000416ee}, {0x000affe525098c8a, 0x000df0d7afe1b4a6, 0x000083fa6f5ecd29, 0x0003d6ee6eaed183, 0x0002496087e011e4, 0x000a3a66e5baf860, 0x000677f833634fb1, 0x0000000000079398}}, + {{0x000c39f67e66a95e, 0x0005b76512d1b46e, 0x0009e5603da596ca, 0x0003aa8025a5f25a, 0x00095cbd2a40d1c7, 0x0008d61c62aba192, 0x0000f3b53cadc3c8, 0x0000000000009829}, {0x000894e8b1d3bb8b, 0x0003a72800ecafd7, 0x0003c62dea4f99fb, 0x00092a7282ba9d23, 0x0002bd5f1bb214bf, 0x0007c6c969062967, 0x000601362f68eba9, 0x000000000007ea9d}}, + {{0x0004d04ff62d3721, 0x00071e141e762de4, 0x000fa0d592d3e0eb, 0x000cde496131447a, 0x0005cb6c2ef746e6, 0x0002f9fd80458a5d, 0x000457b774763453, 0x0000000000016544}, {0x000adb5cae252cf8, 0x0005abfacb4de24e, 0x000e9db72a61c26c, 0x0003220f22d92e51, 0x0006557232589b54, 0x000ddb8bcaa4590f, 0x0007bdc7b6730e01, 0x0000000000069e1e}}, + }, + { + /* digit=6 [{1,2,3,..,}]*([2^24]*G) */ + {{0x000e98d9a0583230, 0x000f77d27d71f312, 0x000823b17edc1a45, 0x000afeb6075b2d00, 0x0006d93a06f7418c, 0x000d001b9c0d691e, 0x0007b9c16a95259d, 0x00000000000026f1}, {0x000b72219cfa1dea, 0x000984c1041afdb4, 0x00056e257be49c48, 0x000efd62c1758e9c, 0x0007e6c3229a8d08, 0x0002d89249cc6f20, 0x000fe7ec69e90208, 0x00000000000f331d}}, + {{0x00061c722c01a99c, 0x000518ec4335f7fe, 0x000df3425d366c49, 0x0006de001141ab62, 0x000c2eca98a13ff9, 0x000fdf648b21acc2, 0x000e8b6154849010, 0x00000000000d1403}, {0x00097be7041b8df0, 0x0008ff1a35f306b8, 0x000b8cedd3e80c1c, 0x0006c077fc9a752f, 0x000e420d48a089c2, 0x000fe2e738d2535f, 0x000f3980ec5ddd52, 0x0000000000071704}}, + {{0x000259172095dfcf, 0x000a020aa15d95a2, 0x000d85bd292d185e, 0x00005caef579e8f8, 0x000b325981bfe2f2, 0x000438be8ad27e38, 0x0000d9087b8284c3, 0x0000000000042236}, {0x00091bc7ac277af8, 0x000bb87cdf5accaa, 0x000de0f7da8c4a28, 0x00040c1891046669, 0x000c9c1578e8a712, 0x00050ffa2eb5a175, 0x000a28bd66910ad1, 0x0000000000011459}}, + {{0x000f920077501dce, 0x00091498808ed4f0, 0x000dc6c59ac5d089, 0x00025f176c6b964a, 0x000bac474261796e, 0x000a460c11aced64, 0x000e48a62470fc29, 0x000000000005e751}, {0x000842d2c145f36f, 0x0007acc00053aac5, 0x000ca1b81e5b854d, 0x000cc2e3f9ca178e, 0x000a0b80d1b0ddac, 0x000642225ad33f34, 0x00061b6a76df9364, 0x00000000000778e7}}, + {{0x0009eb69fa5f1bc6, 0x0008ed30302342c1, 0x000e3ef7d69039f0, 0x0009b575c4630f26, 0x00008d098d745364, 0x0007f5cbc60197fc, 0x000efc9c295d5464, 0x00000000000c0813}, {0x0001c5999be2ce7e, 0x000e7f6e08007370, 0x000b6019bc473a63, 0x000e08e11d9b388e, 0x000a5db61c657af3, 0x000b4dc4d073ec38, 0x00082a9b480cb89d, 0x00000000000372fa}}, + {{0x0003179049382c1e, 0x00069dffb03ae77d, 0x0002e9528cdd6bd1, 0x0002521b19fe0db8, 0x000f3d5c7fee4c26, 0x000e68e1e0ec1e54, 0x0008a62856510b05, 0x00000000000dc80b}, {0x000ac17897e6fc5d, 0x0000680a509308c8, 0x0000b4dde3197e47, 0x00012ee28235c538, 0x0008301f9653ca61, 0x0001fcdf8d28a0eb, 0x0005f322b11e26e1, 0x00000000000e4d73}}, + {{0x0002a6a91ebadb85, 0x0006346a2a08bc3b, 0x00020e574ba891b2, 0x00056a2b3df9fbc8, 0x000eb121d51228c5, 0x0003bc86c81d3161, 0x0000d14e27ce0b12, 0x00000000000bfb24}, {0x00072db1b86f039c, 0x0005986edb71958e, 0x00011b5a99c9a865, 0x000c6d8067f5870b, 0x00033fe8e5322f6b, 0x000a7997ff558b88, 0x000b9be9433e2321, 0x0000000000087e53}}, + {{0x00084d7bdfada95f, 0x0008b9c66a32b0d1, 0x0004ace9a2f6c763, 0x000fab721e716f0c, 0x000b96ed74e68c6c, 0x000110c8332c8fcc, 0x000efe475890dd0b, 0x000000000005cb4e}, {0x0003947e05207b63, 0x000d29d7b89a68e0, 0x00001e2e33262bf2, 0x000b55bca7a7d527, 0x000655d04585c3f0, 0x00057acc5a6e56a0, 0x00039e818e221c42, 0x00000000000fcb8d}}, + }, + { + /* digit=7 [{1,2,3,..,}]*([2^28]*G) */ + {{0x0007398749666d45, 0x0009c0a74da828f4, 0x00001ff782080bc1, 0x00026bb57c2f5ad1, 0x0002845d45e4896c, 0x0009a7d36981e2f7, 0x000e8fca152b877e, 0x000000000007b582}, {0x000b1649b1810a70, 0x000c3ea3b9bd9987, 0x000d4cd2bb2df2fb, 0x000fc5d5748a6550, 0x0007622665eed346, 0x000f16e277ac2f21, 0x000dc8bb5efe7fb6, 0x00000000000644c9}}, + {{0x000db9a336c7d7d8, 0x0003598d0898164f, 0x00065860354f4784, 0x00018287cfc13dbd, 0x000c8655a658651b, 0x000c91b712d606e4, 0x000090ba64d3c563, 0x00000000000b82a5}, {0x000726397fcaaf5f, 0x0006c2d1dff024ae, 0x00092238373e43a8, 0x000ee6b0ea1fe022, 0x000cd5c1273c1ac2, 0x000e603e7c100b60, 0x000dfb4496084cea, 0x0000000000077c2f}}, + {{0x00064d07c56a20fe, 0x00000a93fec079c4, 0x000155e36a436889, 0x00045a5cce5662fd, 0x000f83a9a4a9c00b, 0x000bbeb632e8a0a7, 0x00080f6e0cdebbc0, 0x0000000000063ccd}, {0x0008f36be2f62c1e, 0x00061fc10fa07d22, 0x000b3e653f03a3be, 0x0009cc66bf53af92, 0x0000f10bb6c9fda6, 0x0007625e1474b744, 0x0003cbcda9db3b1e, 0x000000000001dc7f}}, + {{0x0006fec7b896d97b, 0x0007de8e32259b22, 0x00051ccb0af3cd54, 0x000a4219f42edba4, 0x000d0d411d4df147, 0x000014bb46d4bc00, 0x00066fa1a13a2770, 0x00000000000fa101}, {0x000b6039e0c4cc34, 0x000d8b2a1dfa62b6, 0x000ae98992614f2f, 0x000a3a2f88c7359e, 0x0008347726a08409, 0x000507bb9071f383, 0x000167d18a551c27, 0x00000000000b359b}}, + {{0x000fae4c55d4b2c3, 0x0000aeaaaf45fd46, 0x000aa7e37459675f, 0x0009b673fe123f1e, 0x000dd8fd0129989b, 0x0004982a4e2ca56d, 0x000ec777d6d0cd62, 0x0000000000071e1f}, {0x0001c6bdd9bc3a7f, 0x000043e9a049f5c5, 0x0006deb929a38a20, 0x00008e24fed8f86f, 0x000ce199e8dbac2b, 0x0009cc964a1d1357, 0x00063b7cf06ec8e9, 0x00000000000d85ec}}, + {{0x000ba68a3fc0bcb2, 0x0004e7d111c66c1b, 0x000d9aa66fbcd347, 0x000730c6db857e9e, 0x0009f4b46d124cd8, 0x0008472dc3c9c03e, 0x0001bbd42f0242a7, 0x0000000000026084}, {0x000aac1b65a94c0d, 0x000ea6332b11a21d, 0x000acbe9385d6783, 0x00028eee7e8944ac, 0x00005ab28372402f, 0x0005e1ff33d1bab5, 0x0007296944e82cad, 0x00000000000e8c75}}, + {{0x00058e168fe9a81d, 0x00043a151dcbb9f9, 0x0002eed94828803a, 0x000fc00604d46e1d, 0x000572f3e28c947a, 0x000b1cd1dc3c9d57, 0x000a45ce4c1cbd14, 0x00000000000f80de}, {0x000d8f65d998669e, 0x0003c50920f39bce, 0x000b6be78ee5193f, 0x0008ba13f798e332, 0x0006c5edde471997, 0x000714a1e1294aaa, 0x00003c280002c2be, 0x00000000000f2126}}, + {{0x000493dde1b54616, 0x0002ea44f6ef79f3, 0x000c2b67fffeca1c, 0x0004ed80eaf66728, 0x0008181514a2cb0e, 0x0002927ea2bf485f, 0x00064574670e180a, 0x0000000000012c14}, {0x000339b9a314b3a8, 0x000724068c073875, 0x0004212e0016a517, 0x000651d698b28177, 0x00096da14fa8391b, 0x000a578b1f310d16, 0x000ad7a089be6bd8, 0x0000000000044389}}, + }, + { + /* digit=8 [{1,2,3,..,}]*([2^32]*G) */ + {{0x00024e7304503422, 0x000f0ba86aec16bc, 0x0007f0cf87c57f69, 0x000ff0789df2f808, 0x000d97a773d58978, 0x0003f35f685750cf, 0x0008c9806bb730fc, 0x00000000000fed86}, {0x0006b0ff06192aaf, 0x000eadc0fcde080e, 0x00055bc2901e7a1e, 0x0007d028d3ad6cd9, 0x000997293550fefb, 0x0005cfbba5c652b5, 0x000d2232e12942ed, 0x0000000000098800}}, + {{0x000418b23a7be4e3, 0x000cb162cdf33f48, 0x000c8d04be100c6b, 0x000d114454eb977c, 0x0008dea38a674478, 0x00035728a8ce403d, 0x000504d459633b74, 0x00000000000a63b0}, {0x00010a5f9fdcafdf, 0x000c40c74066a938, 0x000e6c61b766c71e, 0x000b588a99690ede, 0x000c3ad775623398, 0x000bb60ee4949517, 0x000becf9824f09cb, 0x0000000000085660}}, + {{0x00083bb80ede991f, 0x000a02daddb11952, 0x000f09f6c4b181d6, 0x000e82721a6aa89b, 0x0007467506deb73c, 0x0008d8daa1091958, 0x000dfd0927724c42, 0x000000000007c17a}, {0x0009a9bb30e43182, 0x0003a8518dab18e9, 0x000594c3465b3913, 0x000c37f89e7a3983, 0x0008e273f6f35943, 0x000143d228e63f5e, 0x00028ec6d0352b83, 0x00000000000ebd16}}, + {{0x000731dadf48f7e1, 0x000a14074ee26b83, 0x00088243bc9a29c8, 0x000d53972cecb4c8, 0x00079a7dd9c4aa01, 0x000c787cf4b0cf12, 0x00053f3e3e3f165b, 0x00000000000942de}, {0x000bfa5d149fa2b1, 0x000010cc6971941d, 0x0007bdd5c6a1acca, 0x000c1e292314a097, 0x000614a1adcb9fed, 0x00062b86a7547d22, 0x000b7d405561a486, 0x00000000000f5480}}, + {{0x000be69f3af05d97, 0x00082c4e59f2ff48, 0x000865d4a01ec6bd, 0x0000d824464bbbbd, 0x000016f9540dfbc8, 0x000595b5d3bacfa2, 0x00080d1954efb613, 0x000000000007a5cd}, {0x0009c6dbd9d7e6b6, 0x000ac926a54cf784, 0x000f3366624e7b07, 0x000167ccb5c8d4c7, 0x000ff9a21ce20677, 0x0002df8cdc994d22, 0x0009083a25ff6b42, 0x00000000000f68e9}}, + {{0x000a093607905265, 0x000ede544b89ab7b, 0x00017731e314dedd, 0x0000da69a73104b6, 0x00067274b105a6a9, 0x000c61bb65c26021, 0x0005068f9705cf60, 0x000000000003c4d1}, {0x000ed5677f9dc5c6, 0x00020ab5a27accb8, 0x000e0bb2ed27cc25, 0x00036d15a36afae3, 0x00095c455916e68f, 0x000b5d1fa79004b1, 0x00048916ffe6249b, 0x0000000000049338}}, + {{0x000a7603914a9a59, 0x0000b941be86e102, 0x0001a6f35b551149, 0x00095b469d75ec8a, 0x0003db0d4374658f, 0x000fc77053fa79d5, 0x00012885da635c6a, 0x000000000008e7e8}, {0x000f4285c3e56baf, 0x00002558cfa8eed1, 0x0000effdf411ca89, 0x00098b96a32e8849, 0x000e3c45ce1a104f, 0x00085de0268237ef, 0x000de35c820dc22d, 0x000000000007459e}}, + {{0x000a78ec870a31bb, 0x00036923d0b44369, 0x0005db7ea085ecd1, 0x000be009cf5b87e5, 0x000d1d61103d1656, 0x00065239313a37d0, 0x000ed81d705880fb, 0x00000000000ed712}, {0x000ff1a5976c303e, 0x0006f15ad02e6160, 0x00077114865ad858, 0x000376cba2b3ffe8, 0x000f9745443c56aa, 0x000903660c3be2b2, 0x00092d47c8a870eb, 0x000000000006c6c1}}, + }, + { + /* digit=9 [{1,2,3,..,}]*([2^36]*G) */ + {{0x000b550138d02bd3, 0x00038148bd39cbc2, 0x000f6b4c6038c07a, 0x000fbe2ce5484157, 0x000c87fdde9ff397, 0x000e9c179441e5c2, 0x000c716366b49ffe, 0x000000000002938d}, {0x0008a64bcbf3adf9, 0x000d026d450f9f8a, 0x00015da756f71781, 0x000bf4d298fd8771, 0x0007544768b65f68, 0x000491267e86df04, 0x00071a40b69a32f8, 0x00000000000f917c}}, + {{0x0007f3a58f523dab, 0x000a7a66c70349a5, 0x000f8ae356d6f09f, 0x0003e96b5ab54115, 0x000c7c57d123dee3, 0x000d6ad37d068929, 0x0001780839a208f1, 0x00000000000123f8}, {0x000f3c2b5c9dfc15, 0x000f4b3e5e52449d, 0x00055ba373af8955, 0x0000ab7389f2dd3e, 0x0005890bba6f513a, 0x00066bf093197a14, 0x00072261add75b6f, 0x000000000004eef1}}, + {{0x000fbdf154b15bac, 0x00063810b6ab3193, 0x0006da8c3809a3ef, 0x00038dd898977511, 0x000e7a336c9a3cf8, 0x0006f89c03e391e4, 0x000e227014833717, 0x00000000000bc4f1}, {0x000e7d4400e0ab41, 0x0006b32b104f92b2, 0x000d1a7a3b67e3fa, 0x0000437bf178ac12, 0x0005c99370d5b831, 0x0002b93a8722299f, 0x0007190a493cf033, 0x00000000000a420f}}, + {{0x00046acf9a0ee15c, 0x0006a21feb7fb87b, 0x000579369777bef5, 0x000557624b04e704, 0x0006342cb0ad03a6, 0x0004f64262531f18, 0x0003ea088c4d54a2, 0x0000000000006a87}, {0x000f1f11e0fca837, 0x000d5dbe0253ef23, 0x000bcfdbd73eb554, 0x000368173e65902b, 0x0002ccbfa504eaaf, 0x0000e163e71f1fab, 0x000f3bb7b845224b, 0x000000000003c779}}, + {{0x000cf36036019ecd, 0x00029cd7b3c4286b, 0x0005e1ca08cbdeb9, 0x000bcbd24ef5c386, 0x000ce579c309eb66, 0x000f6c9007edcc21, 0x000c2c7b19d49116, 0x00000000000b6317}, {0x000aad793c4e52a3, 0x000e7554ba553558, 0x0002315e3b514170, 0x000e33bffda4032e, 0x00082306675c3d1f, 0x0000c91e75dfec47, 0x000879be59305e00, 0x0000000000025a6b}}, + {{0x0002c6fd041a12fc, 0x0006aa35802f5d21, 0x0000c3d459456256, 0x000991d472b9d211, 0x0006a2f8e875261a, 0x0009b6d63d81a1ed, 0x000758942f213a69, 0x000000000000ae57}, {0x00067bfe08ea2ebd, 0x0007061191c82b48, 0x0000611a48f73652, 0x0003e86525112224, 0x000d30dabb91abe2, 0x000d2742466dd967, 0x00005077650c597e, 0x00000000000ab25a}}, + {{0x000abb01ee5e0194, 0x000bca624ab366b4, 0x0009dc413b0af513, 0x0009c4273aa694c3, 0x0009779288abe822, 0x000575e0e0cc3102, 0x00003ef8eff30f57, 0x000000000007d528}, {0x00093a51fb5fbbe1, 0x0002f32d87e548f1, 0x0004001c13dfb44c, 0x000b8dd16c6e6274, 0x000c2c140452aa2c, 0x0003031b1add098a, 0x000543d25f285d2d, 0x0000000000075b59}}, + {{0x00032a5061a42b94, 0x000dc520b0bb8a42, 0x000466f1305a432b, 0x000c73a73c239760, 0x0009783aabba85c1, 0x0004631556e4dec4, 0x00017b69f0c69bb0, 0x000000000009c97b}, {0x000fbbef3e8375b4, 0x000b155af24a9074, 0x000991d9ad3481f7, 0x000283d708671c48, 0x00035fd9001a4034, 0x0002eaf3b200ddab, 0x0006c4e45f28e434, 0x000000000001ba93}}, + }, + { + /* digit=10 [{1,2,3,..,}]*([2^40]*G) */ + {{0x000e8393cd68c757, 0x000b2b083ba6a1e9, 0x0004638d474c7417, 0x0007a21fc82dc041, 0x000a9d3679d89536, 0x0009724c0227be26, 0x000c0fc70f6d6c7e, 0x00000000000f9ebe}, {0x00075bdec21bc5d4, 0x000b029dde03dcdd, 0x000a669d8fc534ff, 0x00090c90f602f4cb, 0x000849722bc4daf5, 0x0009b22b617c5288, 0x000b90a8df99f008, 0x00000000000e59b9}}, + {{0x00015e6442d15d01, 0x000dc6f5775290ef, 0x000cdd79298e58a8, 0x000842778b96c6d8, 0x00022f59350519a1, 0x0007209d6a674f99, 0x000fff5abeeec46b, 0x0000000000047cf5}, {0x0009d3497d146805, 0x000ede24509b7378, 0x000ed2fba1e0b34e, 0x000af595761e8e3f, 0x0008d420a2887f7d, 0x0000ff696ed5cfcb, 0x000c8f365b29eb7a, 0x0000000000099a1a}}, + {{0x000785db50fa1164, 0x000694936c6a0393, 0x0005ce545ed4b2d3, 0x000e8b45714f2c6a, 0x00023f5ac25a03ae, 0x000b33794139bd69, 0x000ba96a2e42bab5, 0x000000000003ff7b}, {0x00034248c56f7e51, 0x00088b61d8643327, 0x0008d647e582cbe4, 0x0000e1472eb77fae, 0x00013b99c6356211, 0x00074c9f23d5b96f, 0x000250956ecf64f6, 0x00000000000ef2ba}}, + {{0x000a8baf84131eb9, 0x000019ee1ec3a29b, 0x000d9f684960ce84, 0x000737588102ac15, 0x0009c08527f432b9, 0x000e3dfbedd296cf, 0x000c4fb74f8145fa, 0x000000000006cd7c}, {0x000debad8e4205ae, 0x00062a0f2fe7a043, 0x00094ce3fc7d23aa, 0x000f2d40eeb90a7f, 0x0000be4de6846e7d, 0x000dd06bce2f46e2, 0x0009f6cd28feba3f, 0x00000000000e6d6d}}, + {{0x0002283f4c1e03dc, 0x000bc246ffcb6b34, 0x000a382150ba305c, 0x0003ae2250e66766, 0x0000924ce5fab4b4, 0x000d8c77695c1b5f, 0x0009d02555795beb, 0x00000000000acd9d}, {0x000cf0d26acc1b8f, 0x00088e1d74aa6321, 0x00035822f91490d5, 0x000df2795af56df1, 0x000fb331b6f4df74, 0x00059e13724b10c5, 0x0007f2b0a6df9a65, 0x00000000000c0663}}, + {{0x000c55f77d493f59, 0x000089ad73168775, 0x000791ccc3015317, 0x0006c2d30b3a5f4a, 0x0007c89723d59e94, 0x00031f6077bc4ced, 0x00034179f514a1bd, 0x000000000003a274}, {0x0007950f4645c0c2, 0x000e07eb010278e1, 0x000a3d29cb5ab91d, 0x000760f35be21cba, 0x000b7c793331718d, 0x00030d29eba58160, 0x00003afbc0ce1f8d, 0x00000000000c6f4b}}, + {{0x000986e6462b5c9b, 0x0000cbd8c0867ee8, 0x000db80962770b4f, 0x00012de024593896, 0x000fdef840b687ed, 0x0000b56e13f7d98f, 0x000e8771eee0cb5f, 0x00000000000d8d9b}, {0x000f5c1c38b9eff3, 0x000c1e6b50b5a5f4, 0x000fada267894657, 0x0001bd17cb1f9925, 0x000d4ff11827418b, 0x000042c63607818e, 0x000ae3e630d93a9b, 0x000000000008c779}}, + {{0x0000de60ecec558f, 0x000bb35d474260aa, 0x0007deb342712d19, 0x00015e22e91bf5f3, 0x000cc08b6b1abd6a, 0x000b97de8e366a84, 0x000f29759c122f55, 0x0000000000008a03}, {0x0005b54173576b1f, 0x00000dcc9fca2774, 0x00073c06ae128d8b, 0x00039029b59cd052, 0x00006f5e5bd4deae, 0x000099f4df532ede, 0x00005284fbeeb936, 0x00000000000088d2}}, + }, + { + /* digit=11 [{1,2,3,..,}]*([2^44]*G) */ + {{0x000b3d633d0721cb, 0x000732ba8c78fe5a, 0x00016e2c1c57f816, 0x000f36a2fc2451f3, 0x0008bb91e1e36842, 0x000ead762fc5c955, 0x000556035d1dfcc3, 0x00000000000031e5}, {0x000b4359fe8646d5, 0x000383af0cc803c6, 0x00070f15b8bb97ea, 0x000de0a6ade1d137, 0x000d93b2dcb580c3, 0x000a2214de8c3a5b, 0x00048de3adbd7c90, 0x0000000000011929}}, + {{0x000e8783f9b6f97e, 0x0009b65026296c0d, 0x00086ba77888a60e, 0x00063a460c8bbf8b, 0x00078b2a71206237, 0x0005497e7fa8f5ad, 0x000618fd744bdf08, 0x000000000002ba35}, {0x0004df87b45c7eff, 0x000870cebfe9d444, 0x000c034f12ddb3df, 0x00017a3fcf19627f, 0x0007c2f112616558, 0x000f2c85030ab44f, 0x0000c3bb001c9ddd, 0x0000000000007326}}, + {{0x000e365e9f55b0a4, 0x000aeb08fb116bd9, 0x0002cf623c1f798f, 0x000fc7b6f9549671, 0x000f76bd243c73ae, 0x00009d5a8c0fb886, 0x000049871eacc5ce, 0x00000000000e773f}, {0x0001eb3732cb8726, 0x000aa92945c840e9, 0x000022c04533de34, 0x000bc1d0509d7400, 0x00010f1af1754762, 0x0008c160f15cf97f, 0x000f0c1f85569532, 0x000000000003b439}}, + {{0x0004f7c9bedca76f, 0x0006dfa7d1236235, 0x000a7e4930642e7b, 0x0007288beb1282c5, 0x000a07fee8a99ea2, 0x00070fee91c069ef, 0x0006fa5749c7b558, 0x00000000000afcec}, {0x00048441716f41a1, 0x00064a3f8f1b0daf, 0x000b8af2f805e4cc, 0x00029a9b59dc06f1, 0x000b98a92c387533, 0x0002b4662fa8e5f5, 0x0006c66b6f46fd3c, 0x00000000000ec04c}}, + {{0x00054b9f6efe8494, 0x0005eaa16c27a15a, 0x000106292d7b104e, 0x000d193aae87c9d3, 0x0009916d634e7ae2, 0x000a65b4b125ab45, 0x000e2202ded714cf, 0x000000000004e212}, {0x0009494225bd1826, 0x000c097c48a1862b, 0x000bf9e4c3ff8573, 0x000b77b2652f5018, 0x000d078efd386fe8, 0x000cb82991daa602, 0x00062635885364db, 0x00000000000b8240}}, + {{0x000f5a3697f1c244, 0x0000e0430af76c1b, 0x000f0e87f66ce63d, 0x000905f12e919108, 0x000012db9e14e1a7, 0x000baeeac1c689b7, 0x0003196bdd3dc90a, 0x00000000000504f0}, {0x000e18cdf6373284, 0x0003c874afd60b16, 0x000a978150da10ac, 0x000eee1ebf4aab2c, 0x000c1aa49fe60d33, 0x000217cfda3631ca, 0x000e770d8340fbf2, 0x00000000000423b7}}, + {{0x000b3813851ecc4b, 0x0001df8c07372826, 0x000ea9f99e2d35f1, 0x000faf1a6305a291, 0x0007f3e0f93d2b97, 0x000aeb8c15bc61f6, 0x00024b7238583cd7, 0x0000000000039f5f}, {0x0002b746db300ac6, 0x000a11cc8b467be6, 0x000e46954d17b55e, 0x0005f95ba2641ae4, 0x0002ce9d565b1b9a, 0x000eedc6287a0c36, 0x00003d07fb51b2e1, 0x00000000000a9739}}, + {{0x000d77fe5e566bbd, 0x0001978a53b5a370, 0x00081dca6fe505a1, 0x000f427019a6f8e7, 0x0006dc3ad0ba3520, 0x000745b7cde6fcad, 0x0002dcfec96e4f79, 0x00000000000b133f}, {0x000924a225ecf745, 0x0000c50088a2b006, 0x000c145291ebead7, 0x00032ff23ae4b9d3, 0x000e85246712f213, 0x0000b515e8cbc659, 0x0008b727fa9c8df5, 0x00000000000494ac}}, + }, + { + /* digit=12 [{1,2,3,..,}]*([2^48]*G) */ + {{0x000ff6bf222c5c9c, 0x000322986475308d, 0x000309c5ef927cbf, 0x000d6b4216ab9acb, 0x0007be12d76a038c, 0x000347bdb3df9b7b, 0x00048913f4d9785f, 0x0000000000013e94}, {0x000466717b5c75f3, 0x0000a5f8e796eab2, 0x000d6af2aad3919a, 0x0005d8ad10740b88, 0x000b5337dee6254b, 0x000f02247c38b8ef, 0x000c4cf688c2e194, 0x000000000006c25b}}, + {{0x000272cd3b35df41, 0x000d936c9dbbec27, 0x00026ae70fa619c9, 0x0008db696a8f9f19, 0x00056b01e6bc1ab3, 0x000fc4adae031d23, 0x0004e410466ae68a, 0x00000000000ed9c4}, {0x0005ea962547af52, 0x000cb61272c12a27, 0x000f929706a5a2ac, 0x0007a910ecc49eb8, 0x000ccbe84d5cf4c4, 0x000e497d7eb95dfe, 0x000ce443f3b71c8e, 0x000000000004c6fe}}, + {{0x0002d9d94d551889, 0x0006182e5d818574, 0x000101531df0c231, 0x00044261daa2e22b, 0x0000e46f32576b02, 0x00069db38b86a358, 0x00027eacf145bd76, 0x000000000004df27}, {0x000d2ba752047cd9, 0x000c203d9391e25b, 0x0007c9592434b2d4, 0x0007845ec38fa9ac, 0x000a265ad6bbefb7, 0x00054a1b2dd40660, 0x000499a22d988618, 0x00000000000737ea}}, + {{0x000ef1248ca55f15, 0x00028e323ed0c422, 0x0001736a7d35b006, 0x0002f06e8d68e4e9, 0x000ad0742e5d9c09, 0x000d3df92d8f5555, 0x000eabe2d175bf00, 0x000000000004f71a}, {0x000a6a143a42cf09, 0x000c6d1762d7229e, 0x000840a2cbe90735, 0x000cb4c6281f2a74, 0x00003603e53a2caa, 0x000fecf29635ba47, 0x00036194a9811d49, 0x00000000000466bf}}, + {{0x0009fc85048451fa, 0x000fd4737236d065, 0x0005b89cfa755eca, 0x00070306da6e06f0, 0x0006f3838f569da9, 0x00043188730279bd, 0x0005d0fb328c8b94, 0x00000000000be90e}, {0x000859016f87df1b, 0x000843334a6711d3, 0x00078d74e5890358, 0x0007b6e38904b738, 0x000296b588a53493, 0x000577ae391e227c, 0x000c7da599b21544, 0x00000000000214a0}}, + {{0x000fcc62fe159c27, 0x000c9e63fbb0fb71, 0x0007ab3cd12c8947, 0x00030677afd4bf85, 0x000dfd37120d5cea, 0x000d718a74494e39, 0x0005fb8c572c7249, 0x000000000005fa30}, {0x0005abf2e0c1181d, 0x00074751c217ee1b, 0x0005917c5a26a520, 0x0006e6efe7a64872, 0x0000f53b0e479a99, 0x0005fd5931a4f6d1, 0x0009ee651390ecd1, 0x00000000000739ee}}, + {{0x000e27c9677a2151, 0x000ef0b6d37446aa, 0x0007f13e8f2bd87e, 0x000c94fa109847d5, 0x000044944c7712bb, 0x0005a31b874c0d53, 0x0005920d280b18eb, 0x000000000007ef42}, {0x000c07ddca373d80, 0x0004ef11030c77be, 0x000075bee798eeea, 0x0002d013d22f1b04, 0x000cd93ee54dd5e0, 0x00041d4b1b6d66c9, 0x0006ed80b4154faa, 0x00000000000acf8f}}, + {{0x0004ca485f1804e7, 0x000ad0f05710ab2a, 0x00002b0d41da0420, 0x000a67a46b8d0e2d, 0x000c698b78cc137d, 0x0008a9393454b89f, 0x000e69f2a6e1de25, 0x0000000000016488}, {0x000b96b954a8287c, 0x0003d7c6c5501c10, 0x000fb63222050457, 0x000e30e92f152478, 0x000327e70a0a4b9d, 0x00014936309d4ca9, 0x0001379c8b16340d, 0x00000000000ce642}}, + }, + { + /* digit=13 [{1,2,3,..,}]*([2^52]*G) */ + {{0x0003c432161be476, 0x000c0f8a8499b505, 0x000715248b87d78c, 0x0001b1d515e1328e, 0x000ba941e788b85e, 0x0005dd8d888a2636, 0x000350a045241d2b, 0x00000000000332f0}, {0x0008eeabc026bdc0, 0x000f796c4b204e16, 0x000ce54b1f342310, 0x0003fc6d00b602a1, 0x000e89aa3b796fc3, 0x000d4dd0007a914e, 0x00095635353eb7a4, 0x00000000000673e8}}, + {{0x00027e0f6ecb7465, 0x00040f36e83987c1, 0x0002e0c806d929c2, 0x00007464efc5b0d5, 0x000ad316c43436ab, 0x000ccf839b211e59, 0x000a072515ec9f16, 0x0000000000003dc6}, {0x000ec4a69e8d5661, 0x00017842b727527c, 0x00065c4526d40261, 0x000711ccef5255e9, 0x00075108cb92967d, 0x0001b9740cd3bfb0, 0x000308e50c0d8aec, 0x000000000001a9e6}}, + {{0x0002078cea733c1a, 0x0005b283eec25eca, 0x00036d44d991d5b4, 0x00083b827ad302e8, 0x0002bde3fdd0269a, 0x00030b3a6225f2f1, 0x000043046fcf3801, 0x00000000000c3ed9}, {0x00066dedc2439ae4, 0x000eff870f14cae6, 0x000680b39cf67cb8, 0x000d5f4847be7732, 0x0003d0ed73a0f3e1, 0x000b3babba949822, 0x000f706933ccf014, 0x0000000000037f08}}, + {{0x000ba839c8cf3524, 0x000ed1afa6aa5579, 0x000f9ef0d2ddddd9, 0x000920b5d36da502, 0x0009291e774f07fb, 0x0000d87a8144d51f, 0x0001a026c2c134f4, 0x00000000000a932f}, {0x0003544f31a7b78f, 0x0009935bb2a42294, 0x000ea47969f6664d, 0x000cabfaa1838ed8, 0x000fe2855f1f5c40, 0x000525934ea0c05f, 0x000fd4931ebb02fd, 0x0000000000016246}}, + {{0x000bd623cb7fe067, 0x00038ecfabd26775, 0x0008c3832c0a3527, 0x00064ccfe2691ca7, 0x00058347566acf4e, 0x000b8c733e3889e2, 0x000f5748da354885, 0x000000000009d9c9}, {0x000592cc5e5c9fb4, 0x0000e8c26a8d609c, 0x0000459f168ec210, 0x000a70a3f8db9f92, 0x0000e758213e181c, 0x000b2653e25aa645, 0x00003aa4898f9169, 0x00000000000ccd83}}, + {{0x000fac468f3d59db, 0x00099517d13b0e90, 0x000cf2490366b8de, 0x00026866d752aaab, 0x0001cab026676e2e, 0x0003163c395da9fa, 0x0003c9be8d91ad42, 0x00000000000a6995}, {0x0007a57ea4ee9030, 0x0006ef728b1d231f, 0x00013aa7ae93d8f6, 0x00000a82e75d9c30, 0x000e3ad09def97a9, 0x0008a2be8136c6b1, 0x0004474bab14a6dd, 0x0000000000025cf1}}, + {{0x000e1d30e97eb41c, 0x000b411b59f3da92, 0x00020acfcec12d54, 0x000f0a1936595900, 0x000cca0b1b0e5cad, 0x000274a5e8fef04f, 0x00027ebcb4d9fb0c, 0x00000000000ba784}, {0x0008e71ae4477c5e, 0x000fbc49f0bc478a, 0x000ac96d890c62e2, 0x0009e583f796b820, 0x000b17964262200e, 0x000db00395bbea92, 0x0002ba86b3c15756, 0x00000000000ead48}}, + {{0x0007642e08638534, 0x000b5cd92906c650, 0x000ae6db49a06b5d, 0x00029781fdc19156, 0x000c269d611e0d69, 0x00065b00a45d01a8, 0x000388e7bd1e7096, 0x000000000009bcaa}, {0x0007591cdd6ae97d, 0x000ed8f189e87506, 0x000ccf1d10959a9b, 0x000bf16c633b1123, 0x0009d6f1dac8ca65, 0x000c3381dc6adc9c, 0x000d120df2c293a3, 0x000000000008388c}}, + }, + { + /* digit=14 [{1,2,3,..,}]*([2^56]*G) */ + {{0x000653d60a9d872c, 0x0003bffdbd0eb2dc, 0x00061fddaf39f568, 0x000cead35e7a3a29, 0x000c67833028c11a, 0x0004c79764998cf8, 0x000a1c8f3a346b84, 0x00000000000db9b1}, {0x000642a471b701b9, 0x000628735dabc47d, 0x0005300f39a216a2, 0x000dd49d267a01b0, 0x0003ffa20d117c0a, 0x000ab2d4a2b46c91, 0x000080f2acef26d8, 0x000000000003d926}}, + {{0x000ba70a22083784, 0x00084e9d2a98a2f2, 0x00091072e4da23c2, 0x000325dceaf86ae5, 0x00088f161525f399, 0x000211b9d03b17c8, 0x000a48d8ac35c984, 0x000000000009050c}, {0x000bbfa19d5ef891, 0x0006ba818c44b2c9, 0x0005e1b560830da0, 0x000af35f8715b052, 0x00099d8829a9633a, 0x000a820f15463e1b, 0x00075db18df52d84, 0x00000000000d0966}}, + {{0x000ae853a945611a, 0x000bed54e2c7c031, 0x0009b2bf77ae12b1, 0x00005e8e60f7f5a6, 0x0008427483adcb41, 0x000bff383705db30, 0x0006e9f73ba98bf2, 0x000000000000220e}, {0x000231b48f25af77, 0x000e8c01c46b84a3, 0x0004ae472f3bd7a2, 0x000dc0bfa3403e6d, 0x0007d2202896f738, 0x000882e5e098bc68, 0x000b13ec0c217a5f, 0x00000000000a1f4e}}, + {{0x0009208204f520a2, 0x000ed2615c78254f, 0x0002b7a2ee7b484b, 0x0001d771c84a04b5, 0x000fcb9f9e349c3b, 0x0004f7846b6fc203, 0x000248bed65464c6, 0x00000000000eb004}, {0x00040455a574f8cd, 0x0003f5c017726a4e, 0x000b0a7d5066828d, 0x0006666aceb0e3ac, 0x0008fc046f0ab78c, 0x000aa959518d3c18, 0x0004e87f3e2f301b, 0x000000000008a284}}, + {{0x0008a96d207a2eb2, 0x000e3c899eba3614, 0x0002ec9689146ad2, 0x0008629da55568ed, 0x00082b1dc1d9607c, 0x000c001ff6b54722, 0x000b8523232311c9, 0x00000000000488f8}, {0x0000aca655c2cd82, 0x000723867ac9a850, 0x00092fe2557b4773, 0x000c647a74488fff, 0x000fbe0876407398, 0x00019a571f6ed920, 0x000aeb72beddc763, 0x000000000006a244}}, + {{0x0006fe658431a6d6, 0x00064b7da79c5a1c, 0x000fc6b2b6576354, 0x000b7b54aa36d18e, 0x0008ed0e30913481, 0x00093074c6efeaf8, 0x000654eb017bddc9, 0x00000000000529dd}, {0x00089f1ff5fdf666, 0x000fcf5177230c70, 0x000373317732e646, 0x00082d34ca267426, 0x0005adcd1650194d, 0x0007758b7eaeffe1, 0x0008194dcec3d9af, 0x000000000004cc2c}}, + {{0x0003e55601cd21ee, 0x0004794bdc7f4a7b, 0x00080eb7c8f212fa, 0x000dab0d654cb574, 0x00037a49195627e2, 0x000d5d0991d4e1e5, 0x000de7a1ef570c31, 0x00000000000295f3}, {0x000c78902e5817a8, 0x000198681b00d89c, 0x00061b3376c1d033, 0x000e90c6a1b57484, 0x000c1222e5544324, 0x000d53dd044f9324, 0x000ef0e30ba10fff, 0x00000000000b48ee}}, + {{0x0004a14fee68295a, 0x00041a349bb65da9, 0x0006f09eba200d68, 0x000d891c18d37516, 0x000dae8d2bfba6e1, 0x000b330789985aa4, 0x000e948baec9ae31, 0x0000000000098750}, {0x000e6cd5311f8630, 0x0009c0d834bf8a5b, 0x000c536623c88198, 0x000faaa0c51d098d, 0x0002b887a10f0c22, 0x0008bed323240404, 0x00066231f6a61424, 0x000000000001ce0d}}, + }, + { + /* digit=15 [{1,2,3,..,}]*([2^60]*G) */ + {{0x000c2532e44da930, 0x0009eac6dbdf6097, 0x0009dd0474f3e9a9, 0x0004de3dc28e1b18, 0x0002a66477111669, 0x000b08b4b2d039cf, 0x0008cea13bbe6fc5, 0x0000000000010ebd}, {0x0006e345ee3db6d1, 0x000c2cd4720862b2, 0x000fcd0516567c14, 0x0006303929bfa29c, 0x0003818249bfb3f6, 0x0007f7cd97c378e4, 0x000a1676068c8084, 0x00000000000987eb}}, + {{0x000e55f593b72e2d, 0x0008c1238e0971aa, 0x00081a4c08ea4523, 0x00054e7f74c5c514, 0x00028805813b4512, 0x0005e7a6e238b16d, 0x0000bc23987b2892, 0x000000000002a1a1}, {0x000c0e8fa1a83cf0, 0x00010944c784c643, 0x000f1939fa2e366e, 0x000ab2aead457171, 0x000631c042056bf1, 0x0000b8881d5f8f0e, 0x0005a8ac062526a1, 0x00000000000fe550}}, + {{0x000d9597e54c99bb, 0x00076cbbd8575ded, 0x000019092c8277a0, 0x00056202e6b72a58, 0x000e7c024443e5cb, 0x0005368f35738ea0, 0x00044f8ed06170b5, 0x000000000001aeed}, {0x0001a7ce730f30e4, 0x0003a3d90a6b26fd, 0x000480ba5c428a59, 0x00093dcc5612aec9, 0x000f99c1bacc0890, 0x00043eaadc272ef6, 0x00089147db3b43dc, 0x000000000000832d}}, + {{0x0001abaa498687bf, 0x0001bac92ee14ee5, 0x0002ef494748554e, 0x000ca876e7a32661, 0x000a8456c9af29a7, 0x00054326f0f2b7e7, 0x000ec87471824e97, 0x00000000000364d2}, {0x0007a1e32547416e, 0x000f386d8aacd172, 0x000735a9921c3b5f, 0x000fc881d79f7eb2, 0x00040040547d9805, 0x000b4e90b377ac3a, 0x00081bd39215d461, 0x000000000004c5fd}}, + {{0x000bf8e11ac3f3fa, 0x000df9ffe5562f1b, 0x0000905bb11344f5, 0x000f981cbefa3c77, 0x0003667bfd643039, 0x00040e3df2ab0688, 0x0009ca9007a25743, 0x000000000005a3a4}, {0x000a64031de3bcfa, 0x000fd9c7be629ab9, 0x0003fbe0cdc1be9c, 0x000ff39e7380dbb1, 0x00059facc3b8ffe7, 0x000ae422c620bb9b, 0x000c432ddcb8cd31, 0x00000000000d12c3}}, + {{0x00072db65199d9d3, 0x000d703621d34a54, 0x0008bb1d8b92a619, 0x00000f66ca2933b1, 0x0002de1494a2886d, 0x000dcdf82d0a2238, 0x000832b8656c4d0b, 0x00000000000c4a58}, {0x0005f2f5aceb0154, 0x0002fa982c1aa34d, 0x0006b9fce5077d2d, 0x0008de431390c6e9, 0x00018c4fe595fc26, 0x00090d82fea4160e, 0x0009076c427a6367, 0x00000000000fc519}}, + {{0x000775c688e983e3, 0x0003e8c0749464df, 0x000f192d78daad34, 0x000e96904bb2048e, 0x0004d6dc8b606cda, 0x000438bbc6dec959, 0x0005a58d26586954, 0x000000000001b0e9}, {0x0001e04544fa17f3, 0x0005e8189f1141bd, 0x000c131e8abc17dc, 0x00075a227f8ec1ab, 0x0000607e37397757, 0x000793e4e7a12524, 0x000af4afae84e74f, 0x000000000005bf5b}}, + {{0x00039549b6d366af, 0x0000aa10292b850d, 0x000fff80cff6798a, 0x000f18f73ad7a1fd, 0x000c5897b11f7a36, 0x000664c618b2c7b0, 0x00022cf7b9a272cb, 0x000000000008f81e}, {0x000e957ffad5963b, 0x000663b99b210935, 0x000ea3abc7ab4283, 0x000175d001db74bf, 0x00067159cb8a3af1, 0x000de4601526f084, 0x000eac6a3c6e1feb, 0x000000000008c232}}, + }, + { + /* digit=16 [{1,2,3,..,}]*([2^64]*G) */ + {{0x0004c667c92f7888, 0x000aaa54768d9e88, 0x000d1397d0aa7f52, 0x000f203faef6863d, 0x0004bd7471b3774d, 0x0007de2e9f795a03, 0x000cfff0958718b4, 0x00000000000e1160}, {0x0005c7ba07a0ffd6, 0x0005186ded97af9a, 0x0008fa18cb4fab4b, 0x0008920424e84590, 0x0004eecf8b2b0558, 0x00068a6fa3745591, 0x00019fe7d3df1fb9, 0x00000000000bad07}}, + {{0x000b4e8b4136f0e4, 0x000ae2566021f579, 0x000cbf2ef6760188, 0x00047a5d9f51b6a3, 0x000df8efa64634e0, 0x0001f584f0b50d91, 0x00091cc2bbcbb297, 0x000000000000907c}, {0x000fd43610d5f812, 0x0000ca7ebeb0dd65, 0x0008a7b6eef1e9c1, 0x0009a073f5c962ab, 0x00053ff74a2fc04d, 0x000f0749d95c155e, 0x0005d0923c65a53d, 0x0000000000027ae3}}, + {{0x000cd3b33afd62e7, 0x0003c4d37c266037, 0x00042b261375e38f, 0x000a2e928ca9d674, 0x000a79beb236566d, 0x000f801e7a9771c1, 0x000358af6b97a976, 0x0000000000071259}, {0x00004ab4fe03d3c3, 0x000bcc23a5e31cf5, 0x000c506466ff69e3, 0x000233b1911ccf3a, 0x000cfa3b3ace3f3a, 0x0004c5f5c93e4664, 0x0003c04bdc14832d, 0x000000000006abf1}}, + {{0x000832aefb763bd9, 0x000f0d5469c7af17, 0x0000d7bc962f1b04, 0x000ca21a16caa7b0, 0x0002e6cc7f39f881, 0x000378723221de18, 0x00066010d61ab531, 0x00000000000520c9}, {0x000ed27c50cc42c5, 0x000ac145214ccbc9, 0x000ac441f327ce66, 0x00059e30cb1fe6a2, 0x000a3e299fe79fce, 0x000af78cf2e6e77f, 0x0001593a0cf652d5, 0x000000000003e852}}, + {{0x00087e649fa97c56, 0x00029ebbe18b74d8, 0x000417a0e476f2ee, 0x0005a2a0b24f97ba, 0x000262fc61243ddf, 0x00003b73af9a400c, 0x000fde9ad9b0bc6b, 0x00000000000153c8}, {0x0006f3a6ac904b01, 0x000f41b6477d9542, 0x0008ea414bce433e, 0x0007128953069569, 0x000db9e775794428, 0x00005e0d14b5db01, 0x0002f5237edf0bde, 0x0000000000085533}}, + {{0x000e220415482512, 0x000190791dfa1ca2, 0x0007078d88a1aeff, 0x0005b77ccedf4f34, 0x000d5d965c0549f2, 0x0009e672705170cc, 0x00017637d9521bd4, 0x0000000000086a00}, {0x000e53f005b29758, 0x000b5dab44493664, 0x0005df02ede5bef3, 0x0000c3e4c2506ba1, 0x00065ec6f1324366, 0x000ac7691b2fb261, 0x000eb5ccc4221a99, 0x00000000000a576d}}, + {{0x0006b1405a6d6a62, 0x0001e3a17f86cedc, 0x000ffc614b14d0e0, 0x000a3f0927935e2a, 0x000ac04d4fb0a86e, 0x0007694212f43742, 0x00012f32a30bce38, 0x00000000000d8d39}, {0x00091bf3c81523e6, 0x000ed34154b18f9f, 0x0001725c2ac49b1c, 0x000be0f9f7a13c1b, 0x000a531736e526cf, 0x000cfa2c250d50b3, 0x000e5f81849773b2, 0x000000000003ba8a}}, + {{0x0003089126b94126, 0x000854a87307686d, 0x000fced9f497ff98, 0x000042f427ea198a, 0x0001ed259219c1d3, 0x0004850cadc59211, 0x000e8d0abdbd1623, 0x0000000000043b6f}, {0x0004352ff19d9aba, 0x00069d3c79d16450, 0x00090120dc8bc8d6, 0x000535d5a98bf664, 0x000dab2cdb2ba736, 0x000af89eeacb3b7d, 0x00053237d3743ada, 0x000000000000b348}}, + }, + { + /* digit=17 [{1,2,3,..,}]*([2^68]*G) */ + {{0x0006e0a86f5827e3, 0x000e1a68295d9bd5, 0x00032e6b7dcbdf31, 0x000a0cffe0c3df09, 0x000b3cd00a1a8deb, 0x0000f90885b4d037, 0x000ef7e9edc429aa, 0x000000000005847d}, {0x00025d7642f87bf0, 0x000f49739d03ced7, 0x000f63949ff1cd98, 0x00034ff1759060ab, 0x0009a7e94dbbdc3d, 0x000e8b7f3029e9aa, 0x0006f42a3cdfa0f7, 0x00000000000bbd8f}}, + {{0x000178a4d4ad7d87, 0x00040cd8c2ec862e, 0x0003f7b9dc665542, 0x00086d4db83e1ac5, 0x0002bb549bb5e123, 0x00007c0f19a79203, 0x00008eaf81cba628, 0x00000000000abf20}, {0x000001ed540ad4e0, 0x0000a9d7a72302a9, 0x0007110b90df5c50, 0x00024daec9005170, 0x00037193eb3047c3, 0x00015c655408cd0d, 0x000c228f0bcce2d3, 0x00000000000869d6}}, + {{0x000e5354c88a38dc, 0x000717192a26df13, 0x00059c532d5dc6ab, 0x000195620aeab120, 0x00057c2328498938, 0x00079bc39ebe39dd, 0x0000925787970e4f, 0x00000000000143e4}, {0x0006e01b286241f3, 0x0001e5f60303562b, 0x000cf202635ec6b7, 0x000b3a2f1856e619, 0x000bbf77d65c7ec4, 0x00011058fbef7dc4, 0x000945b444d50670, 0x00000000000c33cb}}, + {{0x0000e30b66c01c80, 0x000354b5e753d742, 0x000c1ca06540fdb4, 0x000d75f42fa905c4, 0x000ac33e462b4034, 0x0008de3bb89b85ed, 0x00039131f413c305, 0x000000000006ba75}, {0x00046bc0a659bd1e, 0x000573f50020190e, 0x0006ea7059f1f5a4, 0x000aa10efa2adddf, 0x000e1a6566aa7297, 0x000b4f2143e8ccdb, 0x000ae74dfda07fd7, 0x000000000007cb1c}}, + {{0x0008cb34259001d3, 0x0001d49d1cfcc46a, 0x0008f80188e0d2b9, 0x000d285d2ab0a996, 0x00071df5b6cb8cd5, 0x00003fadd9c5cff6, 0x000c0019f4095a30, 0x00000000000aa463}, {0x0002c2d4a3652c8f, 0x00087f86673b013d, 0x000814cd905b85f4, 0x00075b44cc2cd5ed, 0x0000b0342517b376, 0x000817cd771d5262, 0x0006183af1f31657, 0x0000000000079199}}, + {{0x000066ce8afe9a22, 0x000815600fedffd0, 0x000fa276d4e1e61e, 0x00062674cb08e4e2, 0x00052e9ab52d8f12, 0x0005686adfab0c1f, 0x000e4e090b1ac94c, 0x00000000000bb10d}, {0x000c301d650cbaa8, 0x0003b3383f48546f, 0x00045006d2b6b386, 0x00092fe500058f01, 0x0007f4ce508ac5ab, 0x0007a5166f03c7c9, 0x000d66525ac2cea7, 0x00000000000996ef}}, + {{0x0002ee0f55870dbe, 0x000f522daed9eb3c, 0x0008bd7a619de4ba, 0x0007daa46ec27562, 0x0004df0f7a076593, 0x0006036c14c58eeb, 0x000aa5eb972393fa, 0x000000000004d17f}, {0x0005a44cb91701e0, 0x000a3de29c31e831, 0x0004699fe7072908, 0x000952e2c563ddbf, 0x000e5d6b0b57ac00, 0x000c4728203a767f, 0x000d56e858fdf3a6, 0x00000000000a5213}}, + {{0x000b5ed7b705b7ba, 0x0002631796c22d0c, 0x00099ed65d60e408, 0x000cb716cb0c301b, 0x0007d1702ca94ff0, 0x000a02a90dd0cdbd, 0x000625470a26c8e1, 0x00000000000d7054}, {0x000218ab60af89bd, 0x000e0fadc2e8673f, 0x0000890003c99982, 0x0005ebb2951a8fe7, 0x000364197a76042b, 0x0009c1b5de4af9d0, 0x0002b1dd2c6bb324, 0x00000000000f0193}}, + }, + { + /* digit=18 [{1,2,3,..,}]*([2^72]*G) */ + {{0x0004ea16a709d85d, 0x000329ded9b0ccd4, 0x0002e9bda4d583bd, 0x000aaf5393937290, 0x0002a438413e94f3, 0x0003c7de32213686, 0x000540449286da37, 0x0000000000029aa1}, {0x0001d592acb2cf64, 0x000ef1bd13e4055d, 0x0004681cce9d2c6b, 0x000558f6bcd0cb2e, 0x000e9e610369d43b, 0x0006e0651f5757c0, 0x0000aa15c80b23c1, 0x0000000000000182}}, + {{0x0004d40f93bd737d, 0x0008c10a8aabc8f9, 0x000d5b1177a72237, 0x000df1a076945a2e, 0x000c03861f02a009, 0x000866a3cf869152, 0x000cbbc405226e9f, 0x000000000008b41e}, {0x000cb1b314f36d3a, 0x000bab5c9ed101e9, 0x0005d83bc9ae2498, 0x000f22e57589279a, 0x000d7fe2d6aa1a9e, 0x00073dbfa83ef607, 0x000066f2da845434, 0x0000000000057879}}, + {{0x000f91047abd3166, 0x000593df98ea92d5, 0x0002ec06cefe6ff8, 0x000d1b5ea6d69771, 0x00097e25ffbcc9cb, 0x000a6280e3f9f231, 0x000713bca8e0567d, 0x0000000000035cda}, {0x000fe70b79caf906, 0x0003946ef321cfa3, 0x000b4a657c54ec43, 0x0003b4b51de40452, 0x000cccd9ba8d37b7, 0x000f7045b5bccf3c, 0x000dcca2ca080dd0, 0x0000000000068cf4}}, + {{0x000d265e2cd7626e, 0x0007e3499b44b9a9, 0x000ad7706fd7669e, 0x0000406c1f517d80, 0x000b82a174e83014, 0x0002c9b3ad4b3c8e, 0x0006f4c8835b13af, 0x0000000000044371}, {0x000fa90f05b33562, 0x000c2336c4f4b966, 0x000385e7d9f805d4, 0x000a2dc828c34d3a, 0x000c34d0d1f76ffb, 0x000a4fbce257a345, 0x00049fbc1eff056c, 0x0000000000007683}}, + {{0x000db1540add72ad, 0x0009e5ebdc79cc93, 0x000baaf845cf7653, 0x000efe79c8b7f7df, 0x000ac469aa5793f6, 0x00033c455b2f1e40, 0x00012a882f0e9434, 0x00000000000aea07}, {0x00030f4a7dec8786, 0x000e9b13578c31bc, 0x0001af154c9f03fd, 0x000a2d854e09133c, 0x000cc6ad853283ac, 0x00004f75cae03943, 0x000c37ce0a619171, 0x00000000000f9838}}, + {{0x0004bc7eb2d5ec5c, 0x0007e9db114e2be8, 0x000c421a1f0f05da, 0x000016bd2f3080f0, 0x000fb9b7203704df, 0x0004fe2ab0cb3f7c, 0x000ec1adb877c781, 0x0000000000037761}, {0x00081bf9c70c3c38, 0x0003cb5d6068d8ec, 0x0006b75a387ed168, 0x000aa5457d36d422, 0x0007423cc8cb39b4, 0x000a6566dec1de46, 0x000f55280e02dafd, 0x000000000003ca55}}, + {{0x000e1cebdad8aedb, 0x0006b340d77c218d, 0x000b7391085bcda5, 0x0005b028b74d32db, 0x000a3cc1117e3e91, 0x0006c5939ae7101c, 0x000caa3c36152b52, 0x00000000000d3ec0}, {0x0001039f162ada74, 0x0004534de058e1ef, 0x0005d23a486e5201, 0x00030efc214ac0e4, 0x000cc7100acb27c0, 0x0009097b72a216d1, 0x000aaf3b73004330, 0x000000000007afd8}}, + {{0x000af1b588df6219, 0x0003a5d7afe99881, 0x000b20bd69a8d3f2, 0x000067dc65234936, 0x000527557f5de39a, 0x0000e9f9d3458527, 0x0002d8756b8d8693, 0x00000000000040d5}, {0x0003845ac0bf2beb, 0x000a9606eb60a92a, 0x000238ad785ef768, 0x0005748e068d2949, 0x00022fce158da621, 0x000183c8f73fbdca, 0x000c989cfee07dcb, 0x00000000000a5e03}}, + }, + { + /* digit=19 [{1,2,3,..,}]*([2^76]*G) */ + {{0x0000e52cf2e9b4ad, 0x0003f86230933fe6, 0x000fe37b1c8aab75, 0x00086ba6f595ed40, 0x000de2284a5801e1, 0x0009e5e25d3291c3, 0x000f5303dee2311b, 0x0000000000015cc9}, {0x000f15883981ad15, 0x000444fba15675de, 0x0008ff144b8a465b, 0x0001eb92532d015f, 0x00084e7455de8690, 0x000f811c94396fd7, 0x000b372fbcea8fbc, 0x00000000000ae952}}, + {{0x0007195bc501819f, 0x000f06bd2c54c87b, 0x000c8e0d99fb53f8, 0x0002654e3eee748a, 0x00039598d90727f5, 0x000cb371256f2058, 0x000c5b5f91c2d027, 0x00000000000a3e33}, {0x0002b15fc69c25d9, 0x0003e248490a9884, 0x000516ef1dee14b6, 0x0008b3d74f7d38ca, 0x00002fb602142013, 0x000033d4eae791f6, 0x000f176b4fb300bd, 0x00000000000bdfd1}}, + {{0x000558e7c27dd125, 0x0004d9bd2b68cfc0, 0x0001783c86b4626f, 0x000f35989586da1d, 0x000afd0944ca67e7, 0x000569b5abc04c8a, 0x00046eb8db5424f0, 0x000000000000cc55}, {0x0008ec9be17ec8dc, 0x0009e8f0ef9decbe, 0x000cdc094579a394, 0x000eb644e7329b8f, 0x0007e6896b042ec1, 0x00018b6bf3e0e7f3, 0x000fa6ad2bff11c1, 0x0000000000040f93}}, + {{0x000fa586c442030a, 0x000a30c3d2055f9d, 0x000061ff065411bd, 0x000a98b1fbf56cae, 0x000f396e31cd1b68, 0x00082c03b56fd85f, 0x000917d2ca584443, 0x000000000007d3ef}, {0x000572f96fe58801, 0x000c74129a730d28, 0x000ce4a000ce9071, 0x0004180653f3b241, 0x00049ee066bd9e85, 0x0002ea5fee65a1a1, 0x000e2e3420084e36, 0x00000000000c7911}}, + {{0x00079bb68a21bf45, 0x000b04c3f4f487b8, 0x000f5bdc807ffd5c, 0x0009bad1844be875, 0x000e272afc140fbd, 0x00040a7386b3b80e, 0x000a37d727b0b6aa, 0x000000000004d809}, {0x0001886f07e4e9c3, 0x0004c09fb0640689, 0x000e568c8f4da447, 0x000ff8ad73a211ba, 0x0001d9a6b97da7e5, 0x0009e8f56ccdbf62, 0x000a0938448e2cc8, 0x000000000002126d}}, + {{0x000bfb3f1befeb61, 0x0004c43f0ae67505, 0x0007b68cdb6c3beb, 0x0006c25dbb4492ec, 0x000884bff97fd5be, 0x0002da2e27efc9ee, 0x000c3254fbd9d706, 0x00000000000c6d2a}, {0x000d04af3852eaac, 0x0003e14cf6dc0935, 0x0006b6f8f3aa240c, 0x0006543d9a16800c, 0x0009beb1e28dd056, 0x000e658339cc2ade, 0x000cb2cbfeb45038, 0x00000000000d0f5a}}, + {{0x00014927529fad7a, 0x000714f10299a19b, 0x0007bc14eebc4178, 0x00018bc0cbede41f, 0x000e6b03ac7d024b, 0x0005213be7883c01, 0x000540a7b99e741c, 0x0000000000085a97}, {0x0007979358dabc76, 0x000060b6fe59caa3, 0x000a32d2efcf0218, 0x000969d6ad1891a4, 0x0003ee7761dccaa0, 0x000b12539c47afe1, 0x0005f4cae681fcdf, 0x0000000000002ea6}}, + {{0x00033b53cfd1d032, 0x000865e930d64f49, 0x000e6882e13322aa, 0x0004f7efa08bd4a8, 0x0006a6e10f64cfac, 0x0007ac162277e845, 0x00068b41be306740, 0x0000000000052a9b}, {0x000cf81e872685ed, 0x000e28d8d216a150, 0x000406cac9d54222, 0x0004102c60d54c43, 0x000028815187ad9a, 0x0003b8e59b09420f, 0x000ba1881179c60b, 0x000000000005b09a}}, + }, + { + /* digit=20 [{1,2,3,..,}]*([2^80]*G) */ + {{0x0002bb0ebd1ffa8d, 0x0000c22313ded9b3, 0x000c76c37673c0ae, 0x000eeaea76ec3812, 0x00060275ad3643d6, 0x000095bdaa165513, 0x0004b0e5c1b65adf, 0x00000000000367c4}, {0x000f3876ae1976b5, 0x0007de2b419c1bd2, 0x0005d5344cebbb0b, 0x000e51fa2baff060, 0x00006269b5d0b5fb, 0x000e8d667a0594d7, 0x0006e70b07b70523, 0x0000000000063e01}}, + {{0x00082243f0134f99, 0x000d9022aa09c335, 0x0001e1b9a8966dc5, 0x00044c5b38b417ba, 0x000b436451ec3173, 0x000b1c87629a74cd, 0x000ffdd898eb6ca8, 0x00000000000b74ee}, {0x000187e3675bea14, 0x000410d9eab63bb0, 0x000dd59e68360fb6, 0x00094ce14dbff2ff, 0x00092706528037c8, 0x00029a0cd3704d34, 0x000c4f9ee435d8ba, 0x0000000000009c11}}, + {{0x000414827bc8962c, 0x000552fde4893802, 0x00000bdd0aabfbb8, 0x0008a5b09456ed5c, 0x000925797c6c157b, 0x000c14c0673606a7, 0x0001caa9d0f47c33, 0x00000000000faf97}, {0x00082453cb3879aa, 0x000ec6e763c509a5, 0x0006f45dc5dfe238, 0x0007ecbc49e9efce, 0x0007b38f2b59d95b, 0x000c397db0c31792, 0x000bc797912b53b3, 0x0000000000045c7a}}, + {{0x0002600fe807b0d9, 0x000578b3269a1894, 0x000cd6a11a8caa23, 0x000c714e428865d4, 0x000ffdaba094bc5a, 0x000d657f2531dd17, 0x000bbf86d2405718, 0x000000000002f99d}, {0x00063a9cad22b4ec, 0x000d1c428a80ebb2, 0x000111bbf67dd9f1, 0x000691922a5d2566, 0x000318a18586a752, 0x000f633b3bfe6392, 0x00029828a0c772fc, 0x000000000003f3c5}}, + {{0x000cdc4baa08bf36, 0x00052cd81bdce7a2, 0x0009dbe6198554f1, 0x000228bf8ebe39d1, 0x000eb2cdd8524cb0, 0x000e9b3af496a9dc, 0x000f8a0f115a1ad0, 0x00000000000d8eee}, {0x000de9efc567fd4a, 0x0009b5232a514417, 0x000762e720496fa2, 0x00018b08994b4e8e, 0x000809097a52289d, 0x0004621d0b4e346a, 0x000ab8c641510f32, 0x0000000000095a41}}, + {{0x000c5913c30a847d, 0x00004c8c9b0adae6, 0x000c6088d1ec2259, 0x0007946e62c508f6, 0x0006e9fe2321b03b, 0x000c1d1366042592, 0x000c9c73b10bba80, 0x000000000009d218}, {0x000e72b1483512ee, 0x0006d6ed0c8eed83, 0x0009abfdad8b62ec, 0x000096ab9e96167e, 0x000cc473e3773078, 0x0003a3bc8b28f0e6, 0x000796b44e499568, 0x00000000000d3523}}, + {{0x000ec81c53fdc5cd, 0x00095261578c7817, 0x000dba0eec8c348b, 0x00066b414c803900, 0x0005faa7cc399932, 0x0009b7e27bacad75, 0x000533418c4defd6, 0x00000000000ae751}, {0x000b26e534337f55, 0x000f36f3bd3298fb, 0x000bd59fe7197151, 0x0004f73dc4c54ecd, 0x000d44d3d74eb716, 0x0009ea511ca66290, 0x000c49f77c62424c, 0x000000000001f714}}, + {{0x000343bd88e025df, 0x000b893a62e7c716, 0x0003b75e6fa4a448, 0x0003cbb10cc95456, 0x00062f37154c265e, 0x000f2e08b28cceb0, 0x0000916b79b0713b, 0x000000000003ab39}, {0x00046ae52480b7d8, 0x000a750a8d04cede, 0x000f3c798fdbfa72, 0x000336ac21cc62f0, 0x00036fc004503db4, 0x0004b2d954747f0a, 0x0007a7067cbf1c54, 0x00000000000fd2be}}, + }, + { + /* digit=21 [{1,2,3,..,}]*([2^84]*G) */ + {{0x000f8f632d3f21bf, 0x000880233e423a7e, 0x000fc3a5113e93d2, 0x0009cef6349e35be, 0x0003ded2ec542ca0, 0x000dded3d3b70afc, 0x000ee0c813474d52, 0x0000000000012f00}, {0x0002c304534f52c2, 0x00002a0908f763fa, 0x000cccb3aba1eb57, 0x00010c134b6a8e10, 0x00056e7c163e84ad, 0x00057e0c36f37fd9, 0x0001a27caae8c8d0, 0x0000000000055372}}, + {{0x00086fa76217d20b, 0x00015a354c1de108, 0x000a55c4648be905, 0x00010999d532bbe4, 0x000f520117516766, 0x00059e35eb7c2f4c, 0x000b7b6945d34ff6, 0x00000000000a1303}, {0x000495f21c8085bb, 0x00028a200ddba08f, 0x0003caf84b1e53dc, 0x000445faa82b46fc, 0x000cfccedc1b3018, 0x00053e29fc3e6a3a, 0x000547e86ae87033, 0x00000000000fd7e8}}, + {{0x000683184a93e477, 0x000a4728c8e14128, 0x0003d8bece755c7e, 0x000c2da4796df734, 0x000e00a55efc3016, 0x0006b1cb8f6d79e4, 0x0005a94fced26952, 0x0000000000091f16}, {0x00031165825c7f6e, 0x000cf528b857275f, 0x000d8cb6dce0ced4, 0x0003520e07bb990b, 0x000f4ea8ae6b4f90, 0x000b735bb07ddb97, 0x000d4a29c01e70b3, 0x000000000005000d}}, + {{0x000f814f4e7d6929, 0x0005e306b63e3665, 0x00098d89bb61e0d2, 0x00068898bdeddea9, 0x000d67a329ac36bb, 0x00092ccce9331655, 0x0009b414c7fe26ba, 0x00000000000be051}, {0x00042824d37928be, 0x000830dc39dbc42d, 0x00083d595f84e0c5, 0x0008818fa8682bba, 0x000db60aad97c7f7, 0x0002c64cc43396ea, 0x00043e751784d7ff, 0x00000000000866af}}, + {{0x0007b94e1c1e3bf9, 0x000a53742b61de85, 0x0004d0debb63955e, 0x0006787abce34016, 0x000ea4cb41b4f52c, 0x000ca817e4749711, 0x0000487ce0dfb03f, 0x0000000000096e85}, {0x000c4c6d7efe5c7c, 0x000b6cd65250dc1f, 0x0007ec2aec96d815, 0x0003cb2b4dd561a2, 0x000abb5379f57352, 0x000a847ba15ba773, 0x0002decc5e62d6c0, 0x0000000000004d85}}, + {{0x0003450b4a8e849f, 0x00036f0a69e68100, 0x000d9356a0504fb6, 0x0003ab7cd14af1d4, 0x000d558d555d773a, 0x000e63dd6c0b88ed, 0x000db3eb12d197d2, 0x00000000000bcd9c}, {0x000ed15d1fefd8b7, 0x000fa06432985766, 0x00052d6c3d3a4a47, 0x000f6164171b9bc6, 0x0009bbfcf90abd28, 0x00036084d3778163, 0x000a751f93898f3a, 0x00000000000dd00c}}, + {{0x0000e82da9d478f7, 0x000ae3b8d8e48b47, 0x0000534e09405090, 0x000430c2aad8c684, 0x0006b82c16731d72, 0x0000fb41de8c5d50, 0x00034f989978868a, 0x000000000000f812}, {0x000d9518cbfe70fc, 0x000f1a0c941ce78c, 0x000c323a8cf0aba1, 0x000e296101f89af8, 0x0003ca6a3227aa7d, 0x00064ec0c4cadd8e, 0x000db43b4db51f27, 0x0000000000009256}}, + {{0x000e28a122d0f32b, 0x00022b9207dbc085, 0x000dce5b9cc6b932, 0x0004e5534ba150b8, 0x0001dfec99724992, 0x0006f870d2935ebf, 0x00085c34bf5e94b7, 0x000000000004c203}, {0x000bdbb9ed40b2b9, 0x000c3c78ac1719f8, 0x0008866adbfa0f7d, 0x0007ee4cfb4b8bb6, 0x0002cd8724b676c6, 0x0000bc1efecfaefb, 0x0001b5e9bc3d6734, 0x00000000000ca554}}, + }, + { + /* digit=22 [{1,2,3,..,}]*([2^88]*G) */ + {{0x0004ccdc054842bd, 0x000704f293478100, 0x0000ca74cad5c267, 0x000c94f64d55f6f2, 0x000d725c51251bf7, 0x000b6a0914489b57, 0x0000fa3aa4d43ab1, 0x00000000000cf7a6}, {0x0007fef943134dbd, 0x00038aa918a4ce7d, 0x000eee4d56ef907f, 0x00000a16812a03d0, 0x00070b0a1e4bed0e, 0x00028386bb09acf2, 0x000321c73a41f7ac, 0x00000000000f4cd1}}, + {{0x000b2804db21ede5, 0x000fd10a53b8f9a2, 0x00080087f23a6e5f, 0x000513fabef2b974, 0x000cd3f802fd740d, 0x0000627afff6cc47, 0x0002dc1be6825beb, 0x000000000005886c}, {0x0002ebc44567c313, 0x000afb6cfb2c6b07, 0x000e1dddbc404a5d, 0x00016f53a5a485ba, 0x0002e7b2223e7a1e, 0x000a13a9b16b60b9, 0x0001a2332f33d836, 0x00000000000876cd}}, + {{0x000bcac1cf1b2eda, 0x00095802f495c1f2, 0x000e55ffc912d44b, 0x000b294e9b3f0f6d, 0x000033cbdcd1eaf3, 0x00083fce582cc760, 0x0004cc1a5642278e, 0x00000000000ffa0e}, {0x000dada72c71a95f, 0x000ed7d93e9766ea, 0x00015d2d9c24e57f, 0x000dd79eafe5f361, 0x0000fcaafabbcb53, 0x000053efecbbed8f, 0x000b7a570472705f, 0x000000000001ebfe}}, + {{0x0005f3669cd44c3c, 0x00025a896d28dae1, 0x0002e7c6820a84bb, 0x000fe8c06fb15cd6, 0x00061cdffdad1bba, 0x000119b3a2daab29, 0x0005a3984defc8e1, 0x00000000000de2a2}, {0x0000f914a19c745f, 0x000b3a7f54ecdb35, 0x00041f75def22ce4, 0x0000efc6a3b94437, 0x00076785163b6913, 0x0002b1d0a5d17f12, 0x00093cc019911b17, 0x000000000007e3e0}}, + {{0x00049fc81e69d5e0, 0x00085d307d4279b4, 0x00039a33441f2443, 0x00078371531d6263, 0x0008b42639ecfff7, 0x00099fb76fdd61b0, 0x000f0eca9462e7be, 0x000000000007c3f2}, {0x0008f656f3641bfa, 0x000f85c07066bcc1, 0x0008bd883c4e6617, 0x0001387d93ff4937, 0x000b864eed19b6d3, 0x000fad6382fd7d67, 0x000fe667b707ff5a, 0x00000000000d0206}}, + {{0x000bb568a2a2f3e3, 0x000a9235455295a9, 0x0008072539522964, 0x0006d10c75720aab, 0x0009f6a0df88ac83, 0x0005a9c96ea2c538, 0x0007bedfbf31519e, 0x000000000008cad4}, {0x000d6b001091ce3f, 0x00036dbd5de982e7, 0x000e935fa43e76d4, 0x000fef6324ba9235, 0x000e8f14a2f5a2bd, 0x000880ade8b0f981, 0x000d4a590de1c45f, 0x00000000000107f3}}, + {{0x00091e8b5ebad75d, 0x00009b03d47621b9, 0x000da50c79b05bb6, 0x000ca72548723c56, 0x0007c944e3849da9, 0x000947973a12e40d, 0x0001ea403dbcf2cc, 0x00000000000c6ef4}, {0x000f1cf0966fef48, 0x000d74ccc2856b9a, 0x00011bbeae1e30d2, 0x0007f7e43ee1576e, 0x000a0a894961701a, 0x000396f6e7f061c1, 0x000ca956059fb88f, 0x000000000001a91f}}, + {{0x0000a27b9e3336b7, 0x0000be185bdc20d5, 0x0008a8bb1575f81e, 0x0003397c3fe5695a, 0x000f61f6a04f1f6f, 0x00090a92b6c9f3a5, 0x0004543c0f9d4bb3, 0x000000000004793b}, {0x00055e696b3d9202, 0x000d991ad0c33a93, 0x000c4d967cf46a4f, 0x000d90565d53c83a, 0x00034176007dfa24, 0x000d1623cd63e583, 0x000345741089fd2c, 0x000000000002685d}}, + }, + { + /* digit=23 [{1,2,3,..,}]*([2^92]*G) */ + {{0x000883b867d2fbb5, 0x000271d51015761f, 0x000afd0328ae7e6f, 0x0007e2fc6dde9e2b, 0x000937d5bb1f2ea0, 0x000cc6e28ceed9ad, 0x000fc43121994b98, 0x0000000000067ad8}, {0x000d53a60b81c5b7, 0x000ca34707fb3d11, 0x0005e1e4ff2b5765, 0x0009b8d81ef6cb57, 0x000b1223a9a1fe93, 0x00074cf375c51e8a, 0x0008e18f6d7993db, 0x0000000000097280}}, + {{0x00067952d0358e02, 0x0005b0db3322730d, 0x000098edfd5f000a, 0x00085380e8a38fae, 0x0005769360d86efd, 0x000f27ef5c1812ea, 0x0002e8505723dc76, 0x00000000000f35af}, {0x000764970d5cb557, 0x000849f7bb7fecc3, 0x00052323da5066c3, 0x0007549773eaf7f9, 0x000489d51bda0118, 0x0000ccde605bbbba, 0x00087d52cabb0664, 0x00000000000e7ff3}}, + {{0x000fa071b96c7c7e, 0x0009c70187dfb0a2, 0x0000f19decc5bd43, 0x0008b816a6c0d616, 0x000d6a27e97b3018, 0x000a389aaeaeda67, 0x0002734a5192826b, 0x00000000000a2bf1}, {0x000832bf68c7b455, 0x0000c8ff10656bdb, 0x0008bc56c7023546, 0x000a3e11dc7aed54, 0x000b38853d61e34b, 0x000cbf658c457048, 0x000edde89825db1c, 0x000000000006b255}}, + {{0x00067336ad6a8789, 0x000d0c377b3730db, 0x00063e31dca6f13f, 0x000f2adf39b68951, 0x0006bd6da22ed9c2, 0x00009678e1bbff10, 0x000e783f7e5b8e7e, 0x000000000007ed3e}, {0x000a0e3ab40df97f, 0x00071689e6b30fb8, 0x0000b670f8712d68, 0x000277edda78c55a, 0x000cefb65cb717d3, 0x000a30f0ce686cac, 0x00071e758aa1ab19, 0x00000000000b11f0}}, + {{0x0007d3d2024290f7, 0x0000c0bef2d25159, 0x000b908d7c494e4d, 0x00017cedd4af7aeb, 0x000bc8e88ca42c24, 0x00020d15452b5b3b, 0x000d4bc00328c44f, 0x0000000000030af5}, {0x00053687c2073cc9, 0x000dee8bacbeb2cf, 0x000bf613b57931f9, 0x0001da61d9e70314, 0x000c0e70a331b67d, 0x000e325772ddefcb, 0x0009797d09bc6d61, 0x000000000005b52e}}, + {{0x0000d7a5438e4dd1, 0x000b5d40f36e5e3e, 0x000702a395a7941d, 0x00094d7cc51dbaf1, 0x000f0edf8bf9e340, 0x000b5e16520f93f0, 0x0003a8534b75aa23, 0x00000000000dc1b7}, {0x000196b771cc1d7e, 0x000b09dd48c40ca1, 0x000664851f0b3766, 0x000f8a2a9ffa0db3, 0x0004d94ed9bd4212, 0x00069cb198d5236c, 0x000dfc81bec489f1, 0x000000000006104e}}, + {{0x00076550d0174653, 0x0008d9cb21b56311, 0x000fe59ad5e35eee, 0x000a67100d7b34c9, 0x0001a6c1b0c3e3f3, 0x0003c3e31d4bcb3d, 0x000be86ebd26fb9f, 0x000000000002dc79}, {0x000582f4b4dfea09, 0x0002ae7cf9a0a1f3, 0x000c37b50dcbdab8, 0x000320e69e1f08bd, 0x000b946f83d78b0e, 0x000a399ad2a8caf9, 0x0000866daff0ba98, 0x0000000000038ed6}}, + {{0x000af81ab2009a09, 0x000fc16f3708ae33, 0x000f381b02290f16, 0x00015b227bb71a8b, 0x0004162f8b5597a6, 0x0001e3fb9a8b9a86, 0x000ff680ee8362d9, 0x00000000000f83a4}, {0x0005ffc830c362b9, 0x0009507a7873a90a, 0x0008c2637b53ccc0, 0x000683d860d60ba4, 0x00071f87d32a427f, 0x00050319dea99592, 0x0009ceb2ac69faa0, 0x00000000000d2d0b}}, + }, + { + /* digit=24 [{1,2,3,..,}]*([2^96]*G) */ + {{0x000fbfb66a502f43, 0x0008324480c57881, 0x000d6a55d7a45e41, 0x00002c3273e2bc82, 0x00053ef1ed4c7350, 0x0004948e88c42e9c, 0x000632028babf67f, 0x000000000008a978}, {0x0008edce917c4930, 0x0001bf5f13a4625c, 0x000e9dd4dc6a263a, 0x0006bcc37232768a, 0x0001576e8c1830f3, 0x000bcb766c5317b3, 0x0004dcef1d57a69b, 0x00000000000b3e3d}}, + {{0x000aa97e11eb2f75, 0x0004f53ebbaaea28, 0x000f59d2921161ee, 0x000f25d340986b44, 0x000e3365312a3c15, 0x000641f96c5925d2, 0x0008e4c35d3ee251, 0x0000000000098412}, {0x00032040e2f19c59, 0x00029b41a21a75a1, 0x0005c4225a472860, 0x000f4c0faf5663dd, 0x000a0a62c9dc4ffc, 0x0002d60c5889d285, 0x000be50908665acb, 0x000000000000a131}}, + {{0x0006f87a21caa381, 0x000a6318feb4c006, 0x000ed4b6b2c3b939, 0x000786d5b2386621, 0x0005a722c5911e4a, 0x00006cb0188e0430, 0x00036438eb062af4, 0x00000000000e7216}, {0x0003e9f2fb9e0c73, 0x00093450c1d28f54, 0x00023904331c181f, 0x000a53a6f6c06813, 0x000a25eac032fe46, 0x000c497224553199, 0x000a2941fa659aff, 0x00000000000bbcb7}}, + {{0x000a3dcccc791733, 0x000a8c0de60f43c9, 0x0004454fef6e3630, 0x0002aa8e734e2e0a, 0x0003ef773db6f412, 0x0002d71c508f40f6, 0x0008250a7e9484ce, 0x0000000000078a3f}, {0x0005a99063a64539, 0x000ef0cac7a5b50d, 0x000064e61e079dfa, 0x0009a90d3e181458, 0x000a0aadf689ecf1, 0x000f0acf70d1b062, 0x0002b942299f1ff3, 0x000000000005ac25}}, + {{0x000b4c356075ce0d, 0x000a8a4bfe150fb5, 0x000907dbaf6f1c40, 0x0008260a0ee708f9, 0x0004abc9d5f541e2, 0x000aae99eff4fdff, 0x0004d96ed92241ff, 0x00000000000c04fe}, {0x000731763369357f, 0x000a8f10a173e2a4, 0x00065723921ac826, 0x000823f8ed02e85d, 0x00042e522dc1d2a0, 0x000c939fdffa78cf, 0x000bba07041e4600, 0x000000000003a9a8}}, + {{0x0008012ba5de4e7d, 0x000c7a1fc20f7144, 0x000540a292e6e434, 0x00081c28e2e8e16b, 0x000a4c4562342e55, 0x000e31ad4912c80f, 0x0008117fd61fb9e9, 0x000000000001c19e}, {0x000de815bbe3ce38, 0x0003b6a7ab2cb6d7, 0x000aeaa95e1796a8, 0x0006a85ab06af4e7, 0x00044866378d33f7, 0x000826f8cda387e5, 0x000cb6bb71deb856, 0x00000000000eb64e}}, + {{0x000d7e72d8af89da, 0x000ba0e93593424a, 0x000584230569d130, 0x0003dba8e15d8645, 0x0001cab64644ab77, 0x000fff0619cea4a5, 0x0006a4516754d72e, 0x00000000000cd3a3}, {0x000ee6af7eb6909f, 0x000c6c7d352abc75, 0x00007221eaa0649d, 0x000ed979199938f5, 0x000acd6f34958a8a, 0x0005f93eeeb06789, 0x000851c51d776677, 0x000000000000a8af}}, + {{0x000b089742823cef, 0x000c544bfd166199, 0x0008c58b08cf9fc3, 0x000cf81c39366838, 0x00068b08680fe50f, 0x00032aab0c9b4eb0, 0x000ddaf90882c528, 0x00000000000ecbf5}, {0x0004bc1447794cdc, 0x000f8fd4d51c6fd3, 0x000cc355ce034b68, 0x00053dbfb187c34f, 0x0006f8ed037fb729, 0x0007bad45166f7f2, 0x000808d2b1077a09, 0x00000000000790dd}}, + }, + { + /* digit=25 [{1,2,3,..,}]*([2^100]*G) */ + {{0x000273ed4a6f3c1a, 0x00092a05c751c876, 0x000bdb5d554c8320, 0x000e26cf4c98fee4, 0x0009e7b3a7c79c56, 0x000cc16466084f8b, 0x0000bca0b042f6de, 0x00000000000fbf3a}, {0x000078eb34f9801e, 0x0006694524c2c1cd, 0x0008ad2d5e6f66b7, 0x0002d6e7ce1f9f62, 0x0007fc0c34fa1879, 0x0000a16938ebc2fd, 0x000019032a9f4178, 0x0000000000056a60}}, + {{0x00009be19d72cca6, 0x0009ea4b957d1c55, 0x000c88712c99979c, 0x0005e80a271d9e14, 0x00044b9367e51157, 0x00079779f0fff68d, 0x000f68f55ba67322, 0x00000000000d4d68}, {0x000ebae305d14369, 0x000b401474ab1533, 0x0007e0884a0d1ea6, 0x0003a8336111d25d, 0x000fab531cef6390, 0x0002ed86737342a5, 0x0007e1d3c93fe770, 0x000000000006279f}}, + {{0x000ed609fa3c6148, 0x000beb398290bf69, 0x000b5366c9b47f2a, 0x000aa2956560b89f, 0x000c50e6647b3e71, 0x000be42da80817aa, 0x000a4e35c833ada0, 0x00000000000f1bab}, {0x000a4dc6e615148d, 0x0009ac57be644e77, 0x000de3f8f9ac6cc1, 0x00077310defd9095, 0x000e899cba568300, 0x000effb5a92fe9bc, 0x0004bf48450ec4bc, 0x00000000000f2f5f}}, + {{0x000e1a6a67c12c1b, 0x000e7dccf68bc63e, 0x000af5107f8ecb57, 0x000e199254dd3e41, 0x0006ddce5c84e43a, 0x0000b4258e8526e2, 0x0004c452bad815ea, 0x0000000000009457}, {0x000fc838b5157d7f, 0x000e1a5362fcad0f, 0x0003a5c9b577c868, 0x00012b5eeffc2cdf, 0x000b14de4e5b0f93, 0x000233fa55475657, 0x000ec2746e67d4f0, 0x0000000000035471}}, + {{0x000afd6c233d63fa, 0x0009cf55edabb6d7, 0x000b353b7e2a9194, 0x000822b9bf171614, 0x0003afe808dcf53e, 0x000272f554a5b3b9, 0x0009a1590bbbded7, 0x00000000000eaea7}, {0x000101d093edb837, 0x000b5d7042bea6a3, 0x0006a766d7a462c5, 0x000e69031078aa66, 0x00087e37bc8bd8d1, 0x0000089759e837f1, 0x0008679558ff4f85, 0x00000000000421fe}}, + {{0x00076617121c3ac1, 0x000a13503d9370d0, 0x0006e1d369d53e18, 0x00001ef5b52e0f07, 0x0002f955b5fa67f1, 0x0000e0569b6b5b4c, 0x0003efb5f03d5388, 0x00000000000c9939}, {0x000c81fd72768469, 0x000a690755bd5e4b, 0x000324dbfd474da1, 0x000fd519e9ce792e, 0x000396ccfa14326f, 0x0004a22de1b772d7, 0x000342652710f487, 0x00000000000db210}}, + {{0x0008597293bd01e8, 0x000dfaa6489def01, 0x000dc630321a7c29, 0x00043a95fa2efed7, 0x0003720e1a8c4d89, 0x000a4f8a3c9baae5, 0x00006bc055444b95, 0x00000000000a7c12}, {0x00017016dee8b7c9, 0x000dfd97765b5926, 0x00050b911df827d2, 0x000c35af1503b16b, 0x000fa9fa21f8115c, 0x000fed1f11dd5359, 0x000679197c32996d, 0x00000000000f77f2}}, + {{0x0004d7575fc73ce2, 0x000ce58d6998db75, 0x000d11d5d661c62a, 0x0002a0165739fcf5, 0x000822f7a073420b, 0x000042f005c5db30, 0x0003d9016c547805, 0x00000000000a1241}, {0x0008aac8eaa9ff4f, 0x000fe8ceb2d6ffe8, 0x000f806ab6efe1ae, 0x000d012339c146c9, 0x000628ac05552638, 0x000d46e6302fbb7b, 0x00088e7fcb0c8162, 0x00000000000066d0}}, + }, + { + /* digit=26 [{1,2,3,..,}]*([2^104]*G) */ + {{0x00029831f2b8ed10, 0x0004917e3d0b77e8, 0x00062b9d59b96ed5, 0x0000261d0bb1849e, 0x000ec71a3bbef8ef, 0x0002a88ae9b804ce, 0x000b9e00b7d17154, 0x00000000000e9097}, {0x0001f74d24b8094d, 0x0000cdbad9f12075, 0x000917cb364517bb, 0x000834fb83debf54, 0x000d637e449ba8a4, 0x000b82664c3ee226, 0x0000e8e3070d93ca, 0x00000000000b3732}}, + {{0x000cd133b578c566, 0x0004bb506b7b86f8, 0x000a189da5b723c8, 0x00029ad3789281ee, 0x0001f9af456164b7, 0x000f9186069ae8f8, 0x0000fb007befe156, 0x00000000000edc25}, {0x0003b5e8dc3a9219, 0x000ab1c16d7598b7, 0x0000fdec987e0e87, 0x0007da936881f89e, 0x000103a5b1ea5dc9, 0x000153a0faddb603, 0x000ee27eb515b13e, 0x000000000002b4a1}}, + {{0x000bcceb06f924be, 0x000d4e6b739c7071, 0x0004a4fc7ff778b8, 0x0003acc1b4b45493, 0x0008f6bad44a14e3, 0x000020972d6704b2, 0x00033543cd7e5ddf, 0x00000000000e0d6c}, {0x0008ad0a64850139, 0x000b67d395c3ef6a, 0x00040e40560ce9c8, 0x0009f21efe4a5757, 0x0004f55ea727b626, 0x000450c823f97b37, 0x0005d5b689b4de42, 0x000000000004f5ae}}, + {{0x000bd2a72ae0f683, 0x000d7e7365f9e264, 0x0009dec60e7c539c, 0x00089ac8e611fc3c, 0x0005699c227dbfb3, 0x000f2ef17ce778fd, 0x000ed4dc1f47b63f, 0x0000000000002672}, {0x00013b4caed73e7f, 0x000a551c63805fa1, 0x0002b72b6fe7e133, 0x0003d13e00e12a38, 0x0000bf8df325375b, 0x000f5f21a91f9f75, 0x000584f1ea0e421d, 0x0000000000032c60}}, + {{0x000c6a3d385d54a6, 0x000a26d720050d7c, 0x00008151ff431078, 0x000aee6f1c89ce3d, 0x000b57b2b79d5d1d, 0x000c7ce823f7644b, 0x000b0bb1063f92fc, 0x00000000000c15a9}, {0x0004b892e4ed0e8c, 0x0007865661a5290d, 0x000a266171fca5c3, 0x000dc5d42ecede66, 0x000c8eb0689e0661, 0x000d7ff77be586ca, 0x000c3bc86641a02d, 0x00000000000b9ef4}}, + {{0x0006b862a25bd60b, 0x0005903b07fb53e1, 0x0000603f2bb26df9, 0x0006449356376454, 0x0002a55bcadf272e, 0x00071c6af2b6ad1c, 0x00080686c527765c, 0x00000000000c1678}, {0x000fb64422cb7cb4, 0x000660cae829453e, 0x000b68619a56abb9, 0x000f8337513dfb65, 0x000e1b351dda504d, 0x000af7cd04260ee8, 0x0000fda473c5d9db, 0x0000000000071e39}}, + {{0x000c98e3f8d5e928, 0x000c217544e9789d, 0x00047053e368c072, 0x0000e3937af8cf8c, 0x0009a2f308e2e146, 0x0005060e98b4aa2f, 0x000a7dafa2bdbc3a, 0x00000000000f84dd}, {0x0004961384232a8d, 0x000d53b256b55aeb, 0x00063be03fa9b44c, 0x00010d13c8e52f06, 0x000b38865772c405, 0x000416f1062c1542, 0x000eb54755de7ebf, 0x0000000000097aa2}}, + {{0x0009115b2961da7d, 0x000f01d9aa9f9fd6, 0x0004c642e6501980, 0x000d6a17f167b479, 0x00085bd9153d7ebe, 0x000682ba6324c13f, 0x0006e2e9ea5b734c, 0x000000000007e3ff}, {0x000ac4814edd792c, 0x000361ed2b04fb2c, 0x0001100e4a13806f, 0x000a5d3d68b8ec70, 0x000d1c6ce0d2afce, 0x00019410c21dc058, 0x0005340043de75e7, 0x00000000000e15cf}}, + }, + { + /* digit=27 [{1,2,3,..,}]*([2^108]*G) */ + {{0x000e0e09fdbcad95, 0x0004ef7aaa73197d, 0x000fdf5aa02c7c2e, 0x00017372e0c286f0, 0x00025da3472da1a4, 0x00076f2a23b66850, 0x0007d4bc0d116b75, 0x00000000000a36a2}, {0x000b11735059e67b, 0x0001ecdb3f4744cf, 0x00033adc74dab02a, 0x00011b969d4f1723, 0x00066cca4ef7c70d, 0x000c6afdfdf96d13, 0x0004da570693db2f, 0x0000000000056750}}, + {{0x00080567673bd755, 0x000df02c6b607d3c, 0x00025bebf3a2d95d, 0x000b01d4f57eb0c9, 0x0004d750e515af5a, 0x00089ad6859935b9, 0x000eff32721b408f, 0x00000000000a7e3c}, {0x0009a7a317218bf0, 0x00010bd462fd8d81, 0x000035ae54257b2d, 0x000da619263fa61b, 0x000eb6488eb34162, 0x0005680c42ed1f2d, 0x0007b0b0bd37a872, 0x0000000000029ec2}}, + {{0x000d73368a1e2f2d, 0x00047170f8a745d8, 0x00056c4ca9228944, 0x000bd224b08921af, 0x000de6caca3a5f65, 0x000cb9d5b1017ae3, 0x00099b613f36b626, 0x00000000000ed19d}, {0x00092b03ebebeebf, 0x000c752c915a4d7d, 0x00088621f044eee8, 0x000f7c206a51a132, 0x00066e0197ce2cd7, 0x00071b04cfed60db, 0x000b134e5b2bb7d9, 0x000000000002f45a}}, + {{0x0009fb6e89b64981, 0x00034fb09e755c21, 0x0005804661454c99, 0x0005b01cdb1f4f66, 0x0008f1dd1cf0451c, 0x000687e41b02f906, 0x000bd3d4765e7c0c, 0x00000000000d1967}, {0x000f135de5248a08, 0x000f406a0e4ec0b1, 0x000b70c2868ad046, 0x000d01ac651d8073, 0x00030618a96cc1e9, 0x0004ad8ce5e6ebd8, 0x00090f9ce1aacec5, 0x000000000009953f}}, + {{0x000f6e431dc5b814, 0x00044fa4b66978a6, 0x00032f1c66e89ca4, 0x000ba60986c85001, 0x0004dae014e110aa, 0x000bc0e4649bdfff, 0x000d5fe2a810bd0a, 0x0000000000062d1d}, {0x0007dc411c936920, 0x0002c15d2f2c7072, 0x00075b1f6234ac4c, 0x000b6f94c545f5b7, 0x0002f99241e840c6, 0x0007082935875b6b, 0x000344fa3e88a9d6, 0x00000000000ad6d9}}, + {{0x000edb2b4857e570, 0x000fba8d7901c33b, 0x000ae7d92e8b3979, 0x000d7c504e4bce1a, 0x000e5ab0696fb905, 0x000db9cd5dfbf9c4, 0x0000fe0f4e6e2ab6, 0x00000000000482e4}, {0x000aa1f98e714cdb, 0x000225ccd9b418dc, 0x00058c553b3cc2f6, 0x0000dbe59065754a, 0x000a461c1620cebe, 0x000e541a74d052d3, 0x0002d8396bac422f, 0x0000000000070bf3}}, + {{0x000a0c1fea68e228, 0x0005003c88a847c6, 0x0008f73e5d2fc7c6, 0x0003d393870d90fd, 0x0004f2fdb976d90a, 0x000312a302fd78d1, 0x000f2f9472a6066a, 0x000000000003484a}, {0x000f5efbe46efdf7, 0x0008c7cf25950c82, 0x0006be05e61c118c, 0x0009379e563a2bde, 0x0004b46e93d85d47, 0x00037285ce87b50a, 0x0007e69128fc11f1, 0x000000000007c67d}}, + {{0x0006a0e99182cb3e, 0x00059da2b072529a, 0x0000a5cae364c3e2, 0x000e35a5b132756b, 0x0004fadb6907c721, 0x00083f546e5695e8, 0x0008aebc5a3bf4c2, 0x00000000000dde12}, {0x000842d7630a9d87, 0x0000d179c7fa6028, 0x00016ae518569923, 0x00083bea16bad558, 0x000e9137ecd8af7e, 0x00030d1ab6f41231, 0x000ee8ac87543d8f, 0x00000000000b1ee0}}, + }, + { + /* digit=28 [{1,2,3,..,}]*([2^112]*G) */ + {{0x00021880433d0094, 0x000fe359cbfa01b1, 0x000ccfcddd1c5f17, 0x000e90f630cbcb5a, 0x00006ddbf2382fd5, 0x000f753e62b0f613, 0x0000165070970a3a, 0x0000000000041727}, {0x000724192d1373c9, 0x0003e2eb15b3b70b, 0x000786ed962decdc, 0x00074aee930a75c6, 0x0006849e77270d43, 0x0006a19ff3cd3604, 0x000c049ac3117e33, 0x00000000000433dd}}, + {{0x000b49aee05ae3b9, 0x0005d985dcb4303d, 0x000d13447c8994a2, 0x0007f3055fbf1d6c, 0x000f43fcd98a4059, 0x000ec99cab6d166b, 0x0003705932570915, 0x00000000000c5bdd}, {0x00050b2df8b6890e, 0x000dac18f782613c, 0x000d7472d5468bfb, 0x000a89df478e56c7, 0x000864d290535d50, 0x000cf7e0e242c2f4, 0x000d40cda12c6161, 0x00000000000ac8d1}}, + {{0x0001c7858f5f5373, 0x000027a9a9dd7275, 0x000baba450a60383, 0x000267b6726c3253, 0x000d7f841afb1550, 0x00004643012cfb2f, 0x0006cba41b19052f, 0x00000000000b7d78}, {0x0007d7e12176321a, 0x000667b61b39c512, 0x00091b7379479d0c, 0x000efb84a3489052, 0x000cf2e864b965d6, 0x00096cdb2f377862, 0x0000f63c94000dab, 0x000000000008efef}}, + {{0x0001ea0f696fd259, 0x000ff8c558000585, 0x0007b878d3ed6d3e, 0x000d75ceb7a35cc0, 0x000cf0a93110acf0, 0x000c50c850fbdce4, 0x000d6f82b2d13a9c, 0x00000000000cef70}, {0x000ce46086dea462, 0x0001e1cc9be2dbe9, 0x00043757ada5e365, 0x000479f195a532b9, 0x000a1ab3605c52bd, 0x00024c1e0769fe6c, 0x000d7aba6a63e48a, 0x0000000000099da5}}, + {{0x000ad5fa3c1cbaf9, 0x00066df2a6cec962, 0x0003dc76a0f4995b, 0x0007e4c0de8a6aa7, 0x0004be7b8f5d7c8a, 0x000da3e7e5c806b9, 0x0008e5ccca1c714f, 0x00000000000cff78}, {0x00056778e2279cec, 0x0006e17a081a8743, 0x0007133643f614b8, 0x00090549e4cfac8a, 0x00029d53a2000d7c, 0x000977a8b6fb74c6, 0x0007c465b9ed6d5f, 0x000000000000ba2e}}, + {{0x000a6aa57649a837, 0x0000f8435e295b6f, 0x0009b668270d6cf9, 0x0006e6fece5cb161, 0x00095336f7ffe2fe, 0x0008ee2676f249b0, 0x00017b5801feb990, 0x00000000000fc8f2}, {0x00006b2a4f1b5cde, 0x00053fc1adc3e51d, 0x000e0bc8cae40bdd, 0x0005404cc1d9b726, 0x0001a1f2c5a44afb, 0x00008f19575cabd6, 0x000f492bd797e1cd, 0x00000000000cbea0}}, + {{0x0008ce5f4471b983, 0x000d8e9759aa9a33, 0x0001c65f7f2a0258, 0x00059aa2c80bb617, 0x000230c9b328e49a, 0x0004ebffcdb89e21, 0x0008e4f42b9adb00, 0x0000000000047967}, {0x000c42c02e645b6d, 0x000f20dde5b0e690, 0x000d9a21c0cf9036, 0x0007a5cd8c8285c5, 0x00071d1562069f8d, 0x000e126bcd7cde59, 0x00060bdbe765d7a8, 0x00000000000e3f4e}}, + {{0x000bcd16afac5b0a, 0x00041509abccab5b, 0x000ba67813ffa4bc, 0x00071bd640bc2f7a, 0x00078f546c681ae3, 0x0008b8cbfa155c29, 0x00048b8858cadcc0, 0x000000000001d969}, {0x000da5c95714aa4d, 0x00010919cb2262bc, 0x00085c89980779aa, 0x0000f1ab4abe5612, 0x00069cb75bd125dd, 0x000a778e4c6bbe63, 0x0004b3bb367cf947, 0x00000000000bde52}}, + }, + { + /* digit=29 [{1,2,3,..,}]*([2^116]*G) */ + {{0x000545d771f3d008, 0x00076c6307398a47, 0x00054915c4cf9c72, 0x00026aae3a993222, 0x0006da9308d18e01, 0x00068e5050fbfdf7, 0x0008bd2163ed6b61, 0x000000000007500d}, {0x000f06ed5b023878, 0x000d3f571595fffb, 0x000ccfd2dfb01965, 0x0005f7e53d84c661, 0x0009025029da6b22, 0x000d89aed9c03126, 0x00015054c1edfa17, 0x000000000006b435}}, + {{0x0007c3fb4d5bcba6, 0x0005b009ef80a60c, 0x00017966ca95c6c2, 0x00055ed685add960, 0x000672c7dac8ab44, 0x00072f16818f323f, 0x000a99e7009790e3, 0x00000000000067be}, {0x000c5bcf19664dda, 0x00043f15bdbcc383, 0x0007e49d4e4912df, 0x0002c304bdbec36f, 0x000d1b3ac6c72fd6, 0x0002938898b3ea93, 0x000f8bce1c8e5c9c, 0x0000000000011564}}, + {{0x00098a86761cd6cf, 0x0008477faac22471, 0x0009e917079e4be8, 0x0001dd45fbd35ab8, 0x000a45d6d40e31ad, 0x000749ef67e0de9d, 0x000cf2a16c5f1939, 0x0000000000085691}, {0x00046f38fcf548ca, 0x000e7156536ac506, 0x000b8e250c84b9f9, 0x0001eacd35088fde, 0x000538fb995c165a, 0x00093b3a5ce8a733, 0x000e7934d0d33132, 0x000000000008b570}}, + {{0x0002b3fc481df360, 0x0006d6a3a232752d, 0x0000509b75e73d18, 0x0000c3322a82d404, 0x000a14cbc8351703, 0x000da272724bf18e, 0x000d4a319dc4cab2, 0x000000000006d020}, {0x000398eafd6e92bb, 0x00066aeebdd89825, 0x000a73a882a68cbb, 0x0002978595f361eb, 0x000c1ae8fa3cfc8a, 0x000341575e60dd96, 0x000e4819c2109aa5, 0x0000000000006a0e}}, + {{0x000065dd44a81443, 0x00083443deaaabf2, 0x000c83e66800298b, 0x00018ded51d6acd9, 0x00017d4ec9bef889, 0x000c48a6948c9b2f, 0x000f5478b41104df, 0x0000000000078827}, {0x0003f535562e2f60, 0x0004674ed7948c07, 0x0001ccc08940c103, 0x000449b0d9fe252c, 0x0006c14e825a6fe6, 0x000690f0031743d0, 0x000748d9d4ad8c08, 0x000000000000e65f}}, + {{0x000eaf196980dd99, 0x0009692501ff821f, 0x00072b4a2cc10b2a, 0x0009a05e53038473, 0x000c2543d1a995b9, 0x00080877130a72fd, 0x0001456648126b11, 0x00000000000eefb8}, {0x00041f6a86207b43, 0x000d8d9a87f836b7, 0x00016f9bd17dd926, 0x000e118c40122e4c, 0x000f853b291e3341, 0x000565bade513567, 0x000f77d4f1bbb73b, 0x00000000000a7658}}, + {{0x0007b4a08d152bb9, 0x0007cbab37a630ed, 0x00077618410cb7bb, 0x000086c1d4a8f5be, 0x00046581428269e1, 0x00076cc7d3a87384, 0x0003a0b642dc1626, 0x0000000000097e42}, {0x0008ca2aba5729e1, 0x0005b66ac1b365bb, 0x000e67e449b0ae7e, 0x000debbadcc68242, 0x0004b1536fa18f47, 0x0009e546144e9bf6, 0x000b901cfdd50493, 0x0000000000043bb3}}, + {{0x0005a0a5974046e0, 0x000112e32f89636a, 0x000495f55b511bd6, 0x000b1ad8f8328866, 0x0008adcbd933278d, 0x00064f863271d907, 0x0003652208fae34a, 0x0000000000039c89}, {0x0000e167567c2b6c, 0x00048cb46f2725d5, 0x00086f7986cb61ca, 0x000d316edd504188, 0x0004cabe36ed3421, 0x0002efcdab1d8a06, 0x0003eedb13e56036, 0x00000000000c71eb}}, + }, + { + /* digit=30 [{1,2,3,..,}]*([2^120]*G) */ + {{0x0000e8a3d453ef19, 0x000752af8ed809c8, 0x000017d0798a8632, 0x000726f782193578, 0x0001b87254c44c0e, 0x000e7691a8c1962a, 0x0002ee30796a71c9, 0x00000000000a75a1}, {0x000c339094f215d4, 0x0003e535f42c17eb, 0x000b753210a29b6e, 0x000ef35e39a7a591, 0x0002d459b91ab7f1, 0x000fd429da2789ae, 0x000f57eadbca7f02, 0x0000000000065290}}, + {{0x000ffd02d3a50b87, 0x00027c085500177e, 0x00023ee786608759, 0x0001d964318e861c, 0x000604fe9b85dda7, 0x0005e7e2001d3d39, 0x00081cda4bc065e2, 0x00000000000e076c}, {0x000171ac92e482e8, 0x000095b9f82189f0, 0x000cf8881039863b, 0x00083e4d8dd159bf, 0x000720b18043f526, 0x000a0d8f5ca9c888, 0x0005c473c040fa08, 0x0000000000017952}}, + {{0x00023e634e793b49, 0x0000c37ed2be4ce8, 0x000e92823d3628c0, 0x000ad8ae77c2f00c, 0x000a44de16a8b061, 0x000e490ffe87e1a9, 0x0003eddf4f57c87e, 0x0000000000000599}, {0x00036b9f1b67eda0, 0x00020e1036387a16, 0x000cdc81b1b14889, 0x00020d15ab42f920, 0x000dac0ff03359cb, 0x000c1e7f4a738a18, 0x0006e0da501a2e2a, 0x0000000000084d8a}}, + {{0x0000efaf35b1418f, 0x000173a8289046f2, 0x0004fa8840c897aa, 0x000898ae5fa19d2f, 0x00065e1c5fa4c574, 0x000390fc20b13dbb, 0x000187f11343ba7c, 0x00000000000d7d32}, {0x000b8b2ed2cc734d, 0x00011c92cb1bab11, 0x000e6307a3aa4fd9, 0x000dfe5672f2af7d, 0x000430932441da69, 0x000af02d69c62d7b, 0x000c22165672ad94, 0x00000000000cde81}}, + {{0x0006bff8295a2913, 0x000d91d27efcde72, 0x000bdb7b59692a46, 0x000fb83caa26d18c, 0x0003b82babbe99a3, 0x00083dd60d27e613, 0x000cb861030dfdd7, 0x0000000000073c78}, {0x000a3caf05842de3, 0x0002d8707a2cf633, 0x000f47297bf43775, 0x000d412a2b176b8c, 0x000fc72021017c3f, 0x000a6d536d5b52e2, 0x000ec024a63030f0, 0x0000000000004648}}, + {{0x00024dd131928645, 0x00063d45e3501026, 0x000cd2a97f7d8b99, 0x000a088e302483ae, 0x00082c2485c01532, 0x0009cdbe63475e8b, 0x00073808f9ea5696, 0x00000000000253cd}, {0x0002a544f2d5917a, 0x000581cf323a3b9c, 0x00023a0e49f58c76, 0x000e84fc06f3d0ad, 0x000e39efe6d99a31, 0x000ac4decd326b86, 0x00058277e3e1df14, 0x00000000000f3e0c}}, + {{0x000611e8121168e1, 0x0008967477cdc1e4, 0x0003ef00563660fb, 0x00060b9917eec666, 0x0004d66c5c1d31fd, 0x0009508baacd95bd, 0x0002432e0551f3bf, 0x00000000000688cb}, {0x000033e51fe09e4b, 0x000448c039740256, 0x0004cddb41207f6c, 0x00025e144db62afe, 0x000bc4a030da1918, 0x0000815043ee8aca, 0x000cd08ab154a894, 0x00000000000486c9}}, + {{0x0009bbd8fc757c25, 0x00003e92b56bf065, 0x0003d138d6f390b1, 0x000d0ef50f5c483a, 0x000611fa89fe7754, 0x0004ea7d8850a9ef, 0x000a2e97d74b1bba, 0x00000000000aab7b}, {0x00042e268ab251b7, 0x000af06f30ab067f, 0x000bbd0bcb9d997c, 0x0000bca7a2e053e3, 0x0008dcf0e14c4758, 0x000f553108579559, 0x000e18c3596781d6, 0x000000000004c9b7}}, + }, + { + /* digit=31 [{1,2,3,..,}]*([2^124]*G) */ + {{0x00056db726934b05, 0x000d28db8b78ca20, 0x000efbe1df76bc8b, 0x0000f022dde2e3c8, 0x00038cbf406c67e5, 0x000f7ff602e2461f, 0x00068832182781e1, 0x00000000000e30e2}, {0x00008c8748c4086f, 0x0000895adc204b38, 0x00054339345edf7d, 0x000f060b73417379, 0x000fd128d46cd5ca, 0x000fc1e04ed93187, 0x0000a13f2819cb20, 0x000000000002b7f7}}, + {{0x000424a4cdc9ef0a, 0x0009fd74d09c0410, 0x000c23c8eb2570ac, 0x000cfdce132b9412, 0x000c843d3c66db1c, 0x000cb3ef4a0e5309, 0x0001771fbd03a5f9, 0x0000000000000ea5}, {0x0001bb0b6df68f60, 0x000fa1ebf5a155d8, 0x00046a120ff8039f, 0x000c37aa0d34d161, 0x00050fca43af3256, 0x000841bdeee40efa, 0x000a0bc299bbd4b9, 0x000000000003bef4}}, + {{0x0001fdb0e87d4c69, 0x0008f5bbf8bfdcec, 0x0002c8b1b68f641d, 0x000718bfd3fb74be, 0x00015a085196abd2, 0x000dba2ea03c0150, 0x0008bc147474dc4d, 0x00000000000eaa2c}, {0x000a67e6cbd2f408, 0x000e9bc3dc5c2f94, 0x00045e933f00eed5, 0x000e98325d341410, 0x000406fcbc8e0276, 0x00024ebab9372694, 0x00050b8c4b7f2ca3, 0x000000000007dc3a}}, + {{0x000547a274927d68, 0x00075e01295fd654, 0x0003c43252dc8b6c, 0x000689f9eaf8eb82, 0x0005c622acc52ec9, 0x000757f2a327b96c, 0x00006eae918f81b2, 0x000000000004fd66}, {0x000f52e65907ef2f, 0x000a109bb7fcdbf4, 0x0007ab72ec41ee7a, 0x0006f125fb475125, 0x00018e399520df2a, 0x000b1c3a2be88faa, 0x00081f0166d57e3f, 0x00000000000e525f}}, + {{0x0005132af5b85725, 0x0006e0c64cec623a, 0x000d73b377e49971, 0x00043ae5a8027b17, 0x0007d0a7406ac27a, 0x0002bfeed1c5729c, 0x000357445fc7d34e, 0x00000000000809bc}, {0x000fe2c3577b04e1, 0x000a30598626b6a7, 0x00059236250da683, 0x0009b314294839a7, 0x00093ab9bc662151, 0x000ab597466282da, 0x00012e84c422c25c, 0x0000000000071c0f}}, + {{0x00044dd5af953087, 0x000b3f24fab9aa7e, 0x0007e53a0eea7298, 0x00070e733ac4fb68, 0x0002c8a6976575e3, 0x00030aa0ed8d6164, 0x000637f057f10a5e, 0x000000000004f1e8}, {0x000514c4bb67bcdc, 0x0005e887f06b2b4b, 0x00032e66a34587bd, 0x000f7eb6e6483a19, 0x000f475d4bfd4319, 0x000811fc744f1aaf, 0x000f8ba8ee73b50f, 0x0000000000082916}}, + {{0x000b0ecbb3371c13, 0x0009596495c1e57a, 0x0002216cb93b15bb, 0x000c858fe6e84ffb, 0x000b0b189be26806, 0x00058a7685c215e8, 0x000202ac61577e80, 0x0000000000088e0d}, {0x0004f2a99a53c49a, 0x000de70322e164ce, 0x000973bc42c42efc, 0x0001f014d701ab8e, 0x0004a61df25f8863, 0x000f6dbeb889f10d, 0x000168affec5a9bb, 0x00000000000934ee}}, + {{0x0006f789ccd0fed7, 0x0003cdefe3a7abd6, 0x000569da64526056, 0x000c26a73d1f9b54, 0x0008237ae8b77366, 0x00047825935d5d71, 0x000ee33efb20feb4, 0x00000000000aa545}, {0x000d70972e2560bb, 0x00081750edd05bef, 0x000da581b51c4635, 0x0000f370a9e29dc7, 0x0006bfbec7f616e6, 0x00047e1439cf0a13, 0x0001a9b430a34b2e, 0x00000000000c6cdd}}, + }, + { + /* digit=32 [{1,2,3,..,}]*([2^128]*G) */ + {{0x00056f0266d7e788, 0x00065f186d6bc61b, 0x000e03ac4fb95d1d, 0x000432edfe64dc3e, 0x0002d795ea57c9e7, 0x00045af2bd9fc483, 0x000517f4ffdb81c8, 0x000000000002b670}, {0x0004d8950582c931, 0x0007aa7c1be04d23, 0x00045b4daadb356b, 0x0008aba03f2ef6dc, 0x000420dc701d62ff, 0x000f1011960ecaac, 0x000fd09f4b559f4f, 0x000000000003cd54}}, + {{0x000973c51356e0d2, 0x000aa31954a56667, 0x00047c018911cdb5, 0x0003ec5e37ef1d2d, 0x000575bc3b668c43, 0x0009cd98bcd0f203, 0x0002a33723f14524, 0x00000000000ea3b4}, {0x000998df93db2ed6, 0x0000ff607fee05d9, 0x0005662b349502ed, 0x0005d74cea5417fc, 0x000a10fca22bd47b, 0x000635e8b6891940, 0x000fef5cea41332b, 0x00000000000b5934}}, + {{0x0000bd5aa7cff3d9, 0x0003c365a4a426e6, 0x00069eea0aae5d6c, 0x000c8b4b7205a704, 0x000357df815ca330, 0x000a926744858eab, 0x0005d76e522afaf1, 0x00000000000f4136}, {0x0001a59021cca096, 0x0002a00dd3461384, 0x0008629f956ac671, 0x000103f7c082301c, 0x00076b092b71f427, 0x000037a3314a2a18, 0x000e14210f632130, 0x0000000000039340}}, + {{0x00025fc00f86f9f5, 0x000b5b1f4fead323, 0x000e624d9ef69f8a, 0x0007efe2e28aa2a7, 0x0009b3151d6748b4, 0x0006a346070dad2e, 0x000af787a8178b43, 0x00000000000801f7}, {0x000701583b4bfabc, 0x00034fab462e36e3, 0x000ddd2177064fe4, 0x0006b3fe66812831, 0x000a6a3fdc1db469, 0x000e37dac3bd9910, 0x000fb34409128449, 0x00000000000cf605}}, + {{0x00081f556f82acd9, 0x0006f59470e4953f, 0x000963a40f813b02, 0x0003c1e0fb30ecd3, 0x0003b62892f14761, 0x000eefa161fbeffa, 0x000719ddfeef49f8, 0x00000000000daeff}, {0x0004929822ef7d6f, 0x000dcff1872cd89c, 0x0009edd2dba5c5c9, 0x0003a387695218a2, 0x000720802b8852a6, 0x000f4a473a0d413a, 0x000a4a233f1f3118, 0x00000000000c9d7d}}, + {{0x0006ae71b9b2b784, 0x000ca86737912907, 0x000e250552a02dec, 0x000185ee92c712de, 0x0006c201e3272efe, 0x000f6b0788b908f8, 0x000bf33ab5528894, 0x00000000000ce0a5}, {0x000abf1c0844ab25, 0x000185eab37ac7f5, 0x000c6bca8c37680c, 0x000edff304f1cf97, 0x0008f6fd3e90f3a3, 0x00016e5ed8992ecd, 0x0005c4ff24d7c69f, 0x00000000000def9a}}, + {{0x00054a31e739d50e, 0x0001e2edaaaa9c57, 0x000574cc3b6825a1, 0x000fc42bcb161908, 0x00046709d8513542, 0x000af4ce06c04ec2, 0x000e2e5fe9768ea9, 0x00000000000eb6eb}, {0x0005126ebc807472, 0x000c87b7da4abcae, 0x000d07139021766d, 0x0001c51fd563c816, 0x000926c775e17f69, 0x000b58889ea990d6, 0x000c2c2cd96f1321, 0x000000000000f1aa}}, + {{0x000e697116bc35a7, 0x0002057edf71ec8d, 0x00063f77e7793641, 0x000ba1aa6934160d, 0x000c5e639a54b37a, 0x000bce957d45b3d2, 0x0007f362c6b9ad70, 0x000000000005d7e8}, {0x000a8127f71a285b, 0x00017b02169816f9, 0x000c7a7939056bf2, 0x000692b478e4b92a, 0x0009be3fe25a15aa, 0x000bdd4a8dd67cf2, 0x00027af1ef75b006, 0x0000000000041df6}}, + }, + { + /* digit=33 [{1,2,3,..,}]*([2^132]*G) */ + {{0x000455d88f7fc60e, 0x00091a58a27c4fad, 0x000ee65aa7e47d3c, 0x000826600079a263, 0x000f2606caf52431, 0x000cb28c8113f6fc, 0x000aa6f6ff2be316, 0x000000000003c17c}, {0x000c05f668a9dc76, 0x000798ea577e0148, 0x000c912137590c65, 0x000eff4592a57ef2, 0x000c5e3f67b24b28, 0x00000890276e1f87, 0x000b7e40d7a676fb, 0x000000000004b6e6}}, + {{0x0007f95d338f5fb6, 0x0000076e27519dec, 0x000fefb9477deeec, 0x0002dfb71fba6625, 0x00085e0886af5832, 0x000ee544c228aec0, 0x0006398d83b6276a, 0x00000000000e29f9}, {0x0004808391599977, 0x0006d1ba4cfe02e0, 0x0000441e3d4b3e92, 0x000ed58cee95d92c, 0x000abe5355407e0e, 0x000a9a1f42d29282, 0x000c82866638b607, 0x000000000006ab8d}}, + {{0x000c43ee7094e067, 0x0000b599ece9688c, 0x00025bcbe937baac, 0x0005ba86373ccef5, 0x0003c64f72612afc, 0x0004ce1abe455683, 0x000a77f29ad54041, 0x000000000003ee82}, {0x000e0b1548890be5, 0x00094fa26eaa0940, 0x000c96b0a3e57442, 0x000ade54e1c94bd7, 0x000e20b0ddbe9570, 0x0006eff6ff4a86d8, 0x0007a4967ab653dc, 0x00000000000e8bab}}, + {{0x000de87dcf2f3d8e, 0x00056a16c79cee01, 0x000db47cfbc9e301, 0x0006aa0c2f47e69c, 0x000f2c9b4914b8bd, 0x0007242a8277d590, 0x000512b6d1c81009, 0x0000000000045f75}, {0x00044d25d22dbf16, 0x000f02176162aa27, 0x0001167bcefd598c, 0x000c0d1a503aee8c, 0x00057af4dd78fcf8, 0x000b43be45d1f94a, 0x00071b8f0bc1a62a, 0x00000000000ba9e0}}, + {{0x000adf4d6bef5a3d, 0x000a19a2dc376622, 0x000b08bb2e394780, 0x000e5cf7c0765207, 0x000c4063c3538e70, 0x000baec46c0dbb4a, 0x0001ad3f4550566a, 0x00000000000f9356}, {0x000e15a92e3f32ae, 0x00055d0bc6d91fc6, 0x00092d1d7bd54520, 0x00033424b80c021f, 0x0007af5e458c62a7, 0x000bfde586e1d546, 0x00052c6922574f70, 0x00000000000d19f0}}, + {{0x00077ca19b6937db, 0x000c3bf87f30d9c2, 0x000f3d29bdf61e62, 0x00032bd50ec0ba46, 0x000ae60d1e72d5fd, 0x0004ff2d37de8fe0, 0x0007e452d77fe0e1, 0x0000000000055ca4}, {0x000fd784e6c9781f, 0x0000339e3d19e6d1, 0x00045fa26fa441a0, 0x0000c7afe92c6d07, 0x000869a829043bd7, 0x0006d1d9ea3fbc06, 0x00024be263f00ed9, 0x0000000000075c0c}}, + {{0x0002619f4e7dcc16, 0x00090a1d1a8f0893, 0x000f4151f0e91898, 0x000c39b84ee41fc5, 0x0002e4a019099db2, 0x000a66c12ad292a0, 0x0000f6ee6b26ddfc, 0x00000000000f04f7}, {0x000e18e3a8161ac5, 0x0007f01e66788b92, 0x00099db080ad62ab, 0x000e4542595d5a6c, 0x000bdce965cc3e7c, 0x000ec7931f894a64, 0x0005be12e46952d9, 0x00000000000fb65b}}, + {{0x000d91fc53fa82b7, 0x0007d705bfe3760e, 0x0006eb6118c41a96, 0x00077a9bc4567977, 0x000617081a2f811e, 0x000e1640e4f52c4e, 0x0001d787405d819f, 0x0000000000070771}, {0x00085581b6dc5925, 0x00062dc6fff82580, 0x000af03b55b43c90, 0x00066bea9cf3eae3, 0x000e87139b8b0ecb, 0x00042b4d77418372, 0x00032e6aaccf295e, 0x0000000000031fc9}}, + }, + { + /* digit=34 [{1,2,3,..,}]*([2^136]*G) */ + {{0x000f65dda78f831c, 0x00073fa3b4c8e10f, 0x0006b8117d5cb12e, 0x00039562e8c4d8cc, 0x0005cf89935b06aa, 0x000fa071e4981c3e, 0x0003bebdbd0c4745, 0x0000000000049607}, {0x00004bb91c157448, 0x0007009a7298688d, 0x000867eb798cb22b, 0x000b5b3988f2781c, 0x000d73b1719d9a64, 0x000d2e8076ac9440, 0x00042b58ad54c7e3, 0x000000000008f067}}, + {{0x000489635dd868b5, 0x000ef339521774bb, 0x0001f606d4b5774d, 0x000d61e0a285bd5e, 0x000e71171b1c1084, 0x0009b29f93935a84, 0x0009bd8ac2433cf2, 0x000000000006dd1e}, {0x000f576ac5f0cc26, 0x000f788da0477c71, 0x0007313f812b64cc, 0x000a25f9d5b19e1d, 0x000b6a27fa79a792, 0x000a16a8e9ee015c, 0x000e67ea3bf8b57b, 0x00000000000c15fd}}, + {{0x000f3b091fcd53e3, 0x000c537f50e43695, 0x00003782e79d52fb, 0x000af85e1d111511, 0x000f6785ae1c3916, 0x0006ada8cf56e852, 0x0005b2bf8c72adae, 0x00000000000e1328}, {0x000cbe0d0bda153b, 0x000e35327920cb17, 0x000e7daa3650306d, 0x00028573caf37928, 0x000b550ffe1ca713, 0x0005d4e4fb15ab34, 0x000f9d818980666a, 0x000000000002f854}}, + {{0x0005d9265089916f, 0x000013b623150146, 0x0007ede4f0fb2f49, 0x000c31c56471100e, 0x000b1bae8d2a4bc2, 0x000f1f76a4a0e73b, 0x0006cabfc0770a8d, 0x00000000000a7bb1}, {0x00039cb13d9c4b7d, 0x000f42afe5b1cb58, 0x0008a2ce9b2dade4, 0x000a333a1af2a824, 0x0005dafed6cd97ca, 0x000c3b2e393cb92c, 0x00095609553e7e92, 0x0000000000061af2}}, + {{0x000ea55edca2a058, 0x0003f5559dd3109c, 0x000f7ba60d37c6c8, 0x0000fabcaf57d0dc, 0x000578742ab60d84, 0x0009c1c8e9625866, 0x000167c85482ad40, 0x00000000000adaa6}, {0x000208d39ae67d2a, 0x000dcec26ad9971a, 0x00067a35ccc54689, 0x000a7fc2539986bb, 0x0006a23dee41340a, 0x0001a9837d767487, 0x000da9a948a9292e, 0x0000000000071438}}, + {{0x000778a60c6bd7ad, 0x0007f39038863eb8, 0x000e85efa03ef35f, 0x000682ef3d8310f4, 0x0008f412315338aa, 0x00026310bb52d41e, 0x0006924fbef3dd70, 0x00000000000f6ff5}, {0x000ba50eddf2b7fe, 0x000b63831c6b1cbc, 0x0003bc6684c6c5e0, 0x0006abc6516bba59, 0x0005446d35a876d2, 0x00012a8d0c237f9a, 0x00015bb2b16c0ff0, 0x000000000000ee03}}, + {{0x00014182dba86bd2, 0x0009c817d77b02b0, 0x0006420950654aca, 0x0004107da68b7691, 0x000dbebc4c4dd3ac, 0x0003d39e96904bcd, 0x000950b0d2103ca5, 0x0000000000030a5e}, {0x00028ff31a9f909b, 0x000c7b092568034b, 0x000262a60542e8eb, 0x000ab34c15855ae5, 0x00063017194f2389, 0x00046b838c14dfd9, 0x0006fc420e071911, 0x000000000008fb4b}}, + {{0x0009c78614d38ab4, 0x000d813722ab0651, 0x00088626a03970e0, 0x000f467f76fdaf74, 0x000912ddfd9ad3d0, 0x000bdefd37ce072f, 0x000315ce918a5747, 0x00000000000750e5}, {0x000fa00e65975639, 0x000cd08bbb20dcda, 0x000822e7b86b49be, 0x0005c21ca865ba6a, 0x00002e6e8e6fc8fb, 0x000608b60ee6e41e, 0x0005cdd00ae6214c, 0x000000000006ff68}}, + }, + { + /* digit=35 [{1,2,3,..,}]*([2^140]*G) */ + {{0x000cd00e20fc1fe8, 0x0002bbbccce39826, 0x0009c6cbc7ade77c, 0x00035a5d2252fdaf, 0x000954e7dd499eae, 0x0005100fda8f4f20, 0x000727a56d72a629, 0x0000000000056767}, {0x000898f026420cbb, 0x000adbf60b247e57, 0x000b35db15577b1e, 0x0007ad4b93dab9cc, 0x000022d71f39c2a6, 0x000304db218cd0ed, 0x00082104380c425f, 0x000000000006729c}}, + {{0x0000345995afd46f, 0x0009dca07923b790, 0x000129149d2f3565, 0x00079e83cb025114, 0x0005beb383ef41e3, 0x00076dd0dfabac00, 0x00012724d12d9a10, 0x00000000000b208f}, {0x000d58cd6475c579, 0x000359cc38a604c8, 0x000857e410d47fbc, 0x00060d98ac219eff, 0x000faf284c806f63, 0x0009e366a1edaab3, 0x0007269c3b528101, 0x00000000000bc9e9}}, + {{0x000a386526319283, 0x0008d26bd07d697c, 0x0006e6a9c305333a, 0x000c5466798b96c3, 0x00081d3f3859d831, 0x0001b9ec71d6b410, 0x0001a9501d38ec99, 0x00000000000d7843}, {0x0008f62f7d623e0d, 0x000dd8b85baf6942, 0x0003f90bead64135, 0x000c1107acdcf58c, 0x000c848d5842efc7, 0x000c7fdacd9af415, 0x00019b6b5a06bc0a, 0x00000000000a3443}}, + {{0x000517cc17c08a8e, 0x000a28410d82975c, 0x0000ae8bc362b8a4, 0x0000d0d18c253486, 0x00007eb035a3ae46, 0x0001144145d0279a, 0x000f7987e7c1289a, 0x00000000000c0744}, {0x000ccad1ad801112, 0x00072b7b2b4f054d, 0x0007f502703051c0, 0x0007395b51ee6864, 0x000bf6122422124a, 0x000f1a7fff2937c4, 0x00032eb4ec133207, 0x00000000000f8860}}, + {{0x000daf15d19f8632, 0x000794c0d78053af, 0x000ade8ac0a0ca73, 0x000c453e4b57e236, 0x0005f4172b285217, 0x000f999f8b4669e3, 0x000d41509a3cd049, 0x0000000000087c69}, {0x000ec5ba18211916, 0x00032e14d01e8346, 0x000c499a14031eb7, 0x000bff270dc2bf04, 0x000bc01864000e17, 0x000a4dd3446560b7, 0x000d06e28c7b9c49, 0x000000000000f325}}, + {{0x000161555383d319, 0x000d0dd4eb3d0283, 0x000dca801a8bb250, 0x000285ddc1973c7e, 0x000aa0046b981200, 0x00019a7fcfd342be, 0x000fe5d191734912, 0x00000000000b7caf}, {0x000a5ee9f805422f, 0x00057ea5a0c4d360, 0x0004c8206c9d4abd, 0x00016dc6046eeeb1, 0x000ecc8e64b15b2a, 0x0007fadda1755e1f, 0x000ec251e4946e9e, 0x00000000000fcbf4}}, + {{0x00024bd4d62de244, 0x0001d46d7088801b, 0x0002ae4b99b01f02, 0x0008fca4fbea2725, 0x0005bd80a9dfe494, 0x000871c717d6c776, 0x0005701b470ea6f3, 0x000000000008330a}, {0x0004db08d904e89f, 0x0009bdaecddc0ed5, 0x000f26cdb2e08463, 0x000cd84caeeef145, 0x000fc685a35656c7, 0x000d93ddcc60c910, 0x000895e68bc5c59d, 0x00000000000feb64}}, + {{0x0001bb5474d7445b, 0x0008af877e8c6483, 0x000948d44b23fa45, 0x000269f2b004cfe9, 0x000795450f8b19ff, 0x000a7d4588adc5d7, 0x000fdc688ce8bce2, 0x0000000000097bd7}, {0x00043a2684d27187, 0x0007c1b9f4ad5bd1, 0x000b255e8d74e0bd, 0x0001f7e71d83d86e, 0x000d25ffc219abee, 0x00073f553e693c76, 0x000a551c9a84afc8, 0x0000000000066d77}}, + }, + { + /* digit=36 [{1,2,3,..,}]*([2^144]*G) */ + {{0x000e4a9a609d4f93, 0x000f05584cbb3289, 0x0002a9b59e61225b, 0x000d8267df2d43de, 0x00000109e8014126, 0x000172f1cdd5bbbf, 0x0000d985b92ee338, 0x00000000000f3143}, {0x000ac2d50dd03701, 0x000b11e059a07dd0, 0x000eb68a6d1ce296, 0x0000751560f20e77, 0x000e7aaf3a9ad622, 0x000bae14ea59489a, 0x0002497b70e2f664, 0x0000000000076d08}}, + {{0x0001e7720f69ad57, 0x0004baff47822226, 0x00011f4e0e8fa5c8, 0x0005f8d2ef696aa0, 0x000b4fa94fcabeb8, 0x000d41a438ce5baa, 0x0007720a32f96200, 0x0000000000074f6e}, {0x0005b3ae79f59da9, 0x000a8be0221aef2d, 0x0005793443a4452f, 0x00085d6a7e49f3a4, 0x0009cb5d3c6378ff, 0x000eb65f56300658, 0x000bdfe8e4383596, 0x00000000000ff8ad}}, + {{0x000ec83ab52a5d83, 0x0006cf6fd26cb934, 0x000ee1af72ab19a2, 0x000788be372817f8, 0x000ae8c90c31694a, 0x000aa0ce585f3dc1, 0x0002238c90c6bf15, 0x00000000000f01bb}, {0x00043ef688d7f41f, 0x00075bdae01dd56c, 0x000cf79ad5ecb5f0, 0x000ff4ec2548f251, 0x0008d12802a750dd, 0x0004d924054a4986, 0x000d1acd922fb640, 0x00000000000957f6}}, + {{0x0006a17488184bb0, 0x0004d082ea61c88d, 0x0004b5a68e9c5821, 0x000df962e54f5d00, 0x0006e39dc6ab7d33, 0x000179b13340b0d3, 0x00088cd97a8b848d, 0x00000000000288d3}, {0x000bcf17110adf56, 0x000462237e507d00, 0x000fa28fb932260c, 0x0008bcb42be74594, 0x0004de2176b6645f, 0x000e2f09cce2b0f5, 0x000001af570a09d1, 0x0000000000057fdc}}, + {{0x00009414087acee6, 0x000fc7dd81467f3f, 0x0007997c546fe735, 0x0004e832d2e9fbfb, 0x00061c9d9c7ca2ae, 0x000f27f140f127f6, 0x00029ef06c5a57e6, 0x000000000001f303}, {0x000b431a1206d910, 0x00037a1b2b82f82b, 0x0007312610c2e220, 0x000cb8b039f12bbb, 0x000902b92d6b1cf0, 0x000f649e606ce433, 0x0006eccb5e826869, 0x00000000000e9309}}, + {{0x000f672480aedb22, 0x000c79d21c740037, 0x0001a34fe6cb5f73, 0x000b1a3aae5d701b, 0x000891978d1557f8, 0x000b85b1e477e4f8, 0x000fb42913ffb40f, 0x0000000000058489}, {0x00047efe2cde596c, 0x000a60e1ab266dc3, 0x00073cc3adaf7198, 0x000ccb657ab8d871, 0x0006547f64bdf578, 0x0003e497e339fd79, 0x000706904693943f, 0x000000000001d864}}, + {{0x0009da8454e1979d, 0x00030da92e482d7a, 0x000b666249139a91, 0x000ebb3639c78714, 0x0009d77aac3c8763, 0x0002769a43bf7177, 0x000eda92a5420d3f, 0x00000000000d092e}, {0x000352bd3a0254a9, 0x000b5d7bd8d8f8e8, 0x0009446f6266c164, 0x000fa3ed6b0cf872, 0x00040490a771a5ea, 0x000ff37225255afc, 0x000cdbd40bb0fd15, 0x0000000000079294}}, + {{0x0005908307814aa6, 0x00009158bfe27b53, 0x000df35ce707d624, 0x000153b8e71aca19, 0x000171b11643f07b, 0x0004e2f905e67698, 0x00010977b7dd7dd0, 0x00000000000f0dcf}, {0x000bd23edf0138e0, 0x00071d3bab2a41f1, 0x000facf3129d6b1f, 0x00099afc6f53cda2, 0x000f628039e454fe, 0x00083aa16071f2a4, 0x0006f9f1f44181b1, 0x000000000005010f}}, + }, + { + /* digit=37 [{1,2,3,..,}]*([2^148]*G) */ + {{0x000b28d4d03ca18c, 0x000a0b1e36500cc3, 0x000e44ebafd13e2f, 0x0001d2ca4bfdcedc, 0x000fb29cdcfebf45, 0x000514871d210892, 0x0001e35b12bcd894, 0x000000000001809b}, {0x000c86d0fbcc5e1a, 0x000ce09b243105c8, 0x00037f6b6be14182, 0x000a16b5de334b63, 0x00020b116076cef0, 0x000ae2bf4fe0bd1e, 0x00093754e4b48289, 0x0000000000068c8a}}, + {{0x0007e2c503fdc14e, 0x00049309b1eb33af, 0x000b5e3acfac1d05, 0x000b81ebf8a894ca, 0x000e0d29329387c2, 0x000bf371427a40bc, 0x0008957f4c315be4, 0x0000000000001236}, {0x0002d22bfd1d81d3, 0x000f4319c88f7e2d, 0x000189361ce75d22, 0x000a05df0dd13811, 0x00024acba9fafcc2, 0x00027313ec8d55b0, 0x00094a871358de59, 0x0000000000017ce2}}, + {{0x0002c99cf8ff48b8, 0x0002410777188c8a, 0x00068c821fc35883, 0x000b515120380e77, 0x000fe13577d1261a, 0x000862db1453c858, 0x000e1cb1f6bb58f3, 0x00000000000b9529}, {0x000338bb0bed7b45, 0x0008003f63a416f7, 0x00081208dbc793e6, 0x000048b756e5af2e, 0x00031c984bef8423, 0x000a00f3e4d978ed, 0x0009e7a06242995b, 0x000000000004f4d1}}, + {{0x000e08308825a639, 0x000e8d3797831773, 0x000f79843c567224, 0x000a6a611a4e33a2, 0x00005328043a2ff7, 0x000e9f7dd904f86f, 0x000904e29d31c012, 0x00000000000c0a51}, {0x0002dae695c951e1, 0x00024070c2696563, 0x00060638255bc0fb, 0x0000d0c12c8a1f65, 0x0001ab352a835b97, 0x0005eb0c7572aaaa, 0x00059963df45a90c, 0x00000000000d4977}}, + {{0x000fe53cf0bc7d5d, 0x00073e35daffd3d8, 0x00005ab0f149d24a, 0x0005a40f009a48b1, 0x000d308a81c693f0, 0x000885426a4a801f, 0x000f0575e5dc467e, 0x000000000004629f}, {0x000c6c457ceba67d, 0x000c6356b879b5ee, 0x00084a5c7d7e4e3e, 0x000856eec2dd55b5, 0x000880f0c80411c9, 0x00001b21720f0443, 0x0007b8c0b5e3e218, 0x000000000006ea09}}, + {{0x00042a359a9c02d9, 0x0006601c2df8ca11, 0x0001ea46897d0b3b, 0x000341c8360fa6b2, 0x0002c52bb2d6e198, 0x0002efba5e67f809, 0x00032af944dc63a0, 0x000000000002c123}, {0x000d5d58228e0e7d, 0x000b239684f6c863, 0x000f4f910b494aa3, 0x0008eb646594725d, 0x0005793c32ddb7fb, 0x000f94b55bb4f5f0, 0x0002773ef3c33845, 0x0000000000009eac}}, + {{0x000bc0df5aa0ebff, 0x00046efd26dca17d, 0x000d31eadaba6e9d, 0x0008a89e1830a96b, 0x00013e039a029f10, 0x0006fbb3b7e8e368, 0x0002f11747b3e925, 0x00000000000abb3b}, {0x00023cb577b95e94, 0x000e2cac5818c280, 0x000b36c4a5c24e15, 0x000fd4d7a5485367, 0x0009aa3645074081, 0x0001a5f81fe2d8e7, 0x000db4e86ce00ea8, 0x0000000000077a9b}}, + {{0x000a3bf39d563e4f, 0x000f02c5b0e421f4, 0x000bae31a917643d, 0x00085959aa907285, 0x000af658699bace4, 0x0003b18e632be886, 0x000667ce75d6c6da, 0x0000000000069caf}, {0x000af371b713c401, 0x000f0c17c66ce4f4, 0x0002f4e783050dba, 0x0000041623db4f0b, 0x0002c74762e1ceb8, 0x00071c52fe75615b, 0x0002ecade8a54386, 0x00000000000cacaf}}, + }, + { + /* digit=38 [{1,2,3,..,}]*([2^152]*G) */ + {{0x000ea5d38989c046, 0x000c5a933aaf71af, 0x00084b51a5d47afc, 0x000dff8854de4972, 0x000b247bec1525a9, 0x00061e58da8b31d9, 0x000707468a25c846, 0x00000000000786a0}, {0x000d126f8d197fbf, 0x000be282db8ca2e4, 0x0000d8a3ccd2e3a9, 0x0000faaeaeda06f0, 0x0009add94b47a2c4, 0x0000690766963292, 0x00092cc72354f6b0, 0x000000000007878e}}, + {{0x000456ff7fbc201b, 0x00083854b0583e19, 0x0005b9f9d05986b8, 0x00093894c32fc71b, 0x000c9ec8f90dec82, 0x000c7b9c0882fad4, 0x0005e52d39990dc6, 0x00000000000d71a2}, {0x0003262dabc3b450, 0x000866b852e64a5a, 0x000281968ae95022, 0x00011545857f0497, 0x000c1ccb9bc83700, 0x0002bb853746621f, 0x0004ed97e44e6361, 0x00000000000758da}}, + {{0x000e66dca895aedb, 0x0007e58775856e71, 0x0003edbdf1471e8b, 0x0002e3da62265d35, 0x000672d98b0886a1, 0x0001e9c858ec4278, 0x0004ceb9da8016f6, 0x0000000000080099}, {0x0007a34c46f751da, 0x0004f63d0878c9c9, 0x00077928ee65f2b7, 0x0009e126a1c1efae, 0x000eebd0497a780b, 0x00065231eeed68d0, 0x000127bfeee3d292, 0x0000000000080e03}}, + {{0x000369b381ff008e, 0x00068d25f6507829, 0x000435b503d33f46, 0x000031108b9b08bf, 0x000f3fe92e910b36, 0x000189ddc16477af, 0x00038f6e5f6cb103, 0x00000000000c698a}, {0x000953f049518733, 0x000e102a092187fe, 0x000b4e74068daf16, 0x0005eac8fd6b76cb, 0x000611ef96b455a1, 0x000e433b51e37ec3, 0x0004c3d1b3b3fc30, 0x0000000000051d17}}, + {{0x000c3efd55e9f108, 0x0004ee67813dd55d, 0x000e8b95d557829a, 0x0007b634c8cf1647, 0x000fa3556b4674ea, 0x000db03dff1bde0b, 0x0006b45343f260c1, 0x00000000000e0a1d}, {0x000557bdaa85b25c, 0x000b5af56bed0543, 0x0009694c640e2d2a, 0x000c5892c72fa801, 0x0006a49486e504e0, 0x000f78943812e259, 0x000431d5e0bddb2e, 0x00000000000acdba}}, + {{0x0005b2c1b41a7e30, 0x000e8b6e95494a98, 0x000e156b8fa7f1c3, 0x00012ee2183ce113, 0x0000cc01d1434741, 0x000d0d25f4180ec4, 0x00016ddc5f8f7b8d, 0x00000000000974a6}, {0x00054a8b6ee62d01, 0x00072b9a7f0a96a9, 0x0007a0f1f81abc8f, 0x0000b82bc5671a8c, 0x00000466ffaf50eb, 0x000fdc348fa58667, 0x000299a75ff5aab9, 0x000000000007f784}}, + {{0x00064348b9a55592, 0x0008f24b18ccf351, 0x00046d73b67eefc8, 0x000977c532d340c4, 0x000191002448043a, 0x000960397a2de526, 0x00034e1e11027870, 0x000000000000164e}, {0x00056330f30da4d6, 0x00014cc5f57288f2, 0x000974f0c19f8ace, 0x00020963266aaedd, 0x0002c3ccd59f3b15, 0x000a6dd5dfaea30f, 0x00035a1da2e1fbc9, 0x00000000000ceda8}}, + {{0x0007996f48325ebf, 0x0004f7914213d709, 0x000270acf84435ed, 0x000e5a126a34238c, 0x0000701ce8c76eda, 0x000656e02e566bf5, 0x000fbf3562e87555, 0x00000000000b4e8e}, {0x0008d6657de7885e, 0x0004a5f10a503e86, 0x0006a10baa0b8f13, 0x000fc25cc2f2e415, 0x000caf5718c149d1, 0x000d6b890e973bb1, 0x000f129b8825dad2, 0x00000000000e2f00}}, + }, + { + /* digit=39 [{1,2,3,..,}]*([2^156]*G) */ + {{0x0009cd8cd3edcb0c, 0x00022e37211bdab0, 0x000bfe0383f52218, 0x0007e26a1b9f8b57, 0x000d7d7f72d5fdcd, 0x00049c9205641e45, 0x0002a15377c1bec4, 0x00000000000efc7b}, {0x0007344da1d40eaf, 0x000b6c657a9ff3f7, 0x000acc6777a25729, 0x000d1bcd020eaa96, 0x000a3f6860c76bfc, 0x000c7c80617534b0, 0x00056b8ce5722284, 0x000000000002bd74}}, + {{0x00070f4fca1b2907, 0x000d2aed02b6a844, 0x00048854f708389d, 0x0006ec4654e7c314, 0x0003e7034bfd8222, 0x000d6b555008ac00, 0x000d44e343c5407f, 0x000000000001b429}, {0x0003fda90bb8f0f9, 0x000bce0702a33908, 0x0003c08ba27edf85, 0x00072f6d46524015, 0x000d35f600437e6d, 0x0003e8cc4d92655e, 0x000b40a0dbaac627, 0x000000000003c3ff}}, + {{0x00098d832fcb2cab, 0x00078bc06ecab0e1, 0x0004e7cd0ece1448, 0x0006fa0453c94bf2, 0x0003ed1a6731a6fc, 0x000c3f1fb5460f94, 0x000d4eeb11656a4e, 0x00000000000ff1e7}, {0x000efd2eb43b2558, 0x0009059526466dba, 0x0007bc3cfc024713, 0x000588824fd2ce63, 0x00039f2c29257bdf, 0x000e97f3013df0c8, 0x0006411bf621e6de, 0x00000000000ebea6}}, + {{0x0003b015d907e90a, 0x0004e5906a35b43f, 0x000f32388b4d1260, 0x000ac9136f847648, 0x000bbe0f1dd365c8, 0x000d26c21f73b3de, 0x000ae740358868a2, 0x0000000000076792}, {0x000fc16ec80c7bf1, 0x0008d3ecea1669e7, 0x000b1ce4e42f6130, 0x00091090e0062443, 0x0006dd94681b6db8, 0x0005a3de2d29106e, 0x0006ccb40b8694a8, 0x00000000000936b8}}, + {{0x000fa93eb46c6ed1, 0x0009f28d33e792c1, 0x000af8e666ab1b38, 0x0009f3bce683c5c2, 0x00098371fe755a74, 0x000712c1d717629d, 0x0001aa5e828fc057, 0x000000000007e4c6}, {0x00082c4505e4cd17, 0x000035d927bad55e, 0x000bbbc997dd1436, 0x00099a398591dc25, 0x000a4836664c560a, 0x000d79298c885fe8, 0x0001d7d18acd4226, 0x00000000000185df}}, + {{0x000755a507c76d63, 0x000c69d8a925b591, 0x000ef5ac5d730610, 0x000ca6ddfb534b8b, 0x000c6dd78a324f53, 0x000a146d54e64874, 0x000201336e5b46c2, 0x0000000000098395}, {0x0001a5ef82624226, 0x0004ca4c095220d8, 0x000ae0a7c3b4840e, 0x0002f64c36286ed0, 0x0003c3ebb08c0ff9, 0x000f00c3057b1b90, 0x00036ec6bdc9b665, 0x000000000009a46d}}, + {{0x000c3639d049078f, 0x00048d67dc92ab51, 0x000e52783edc1242, 0x0009baa8b87c0b05, 0x000052760ef4b6f0, 0x00047bf855a8a903, 0x000e742e2ae75610, 0x0000000000085bd4}, {0x00097e1bd11078ed, 0x00093ced11ff7661, 0x000e3244d9aa20e1, 0x00088ff24b3e912a, 0x000a1afd219683d4, 0x0000d21286e166fd, 0x00039c66a912114f, 0x0000000000005c9f}}, + {{0x00070dd4c4f3a35e, 0x0006d913f92069a9, 0x000aaa1c8b2107ab, 0x0004e2c787c35959, 0x000fe7b7b7ddefab, 0x000e28e6aa55d465, 0x0007bc921aaad834, 0x0000000000012d6a}, {0x000d81dd493823d1, 0x00072109803c417d, 0x00095b2d5e30421d, 0x0008bdb99c5bb670, 0x0006bc7c2da71a8c, 0x000927eef1cd1c2b, 0x00041050189c975f, 0x00000000000229f9}}, + }, + { + /* digit=40 [{1,2,3,..,}]*([2^160]*G) */ + {{0x00086c2a1c05c1ca, 0x000a911a8fde5d4c, 0x0008768c091692e8, 0x000c275c74dfe82d, 0x000c38373a506818, 0x000e5f88f2b0294a, 0x00083a584c4061e8, 0x0000000000073423}, {0x0003f61270e03ada, 0x0002d263895b3203, 0x00007b3b0d15f74f, 0x00059da84da7f0d6, 0x000a924a09f21443, 0x0009ad83576e3095, 0x0002af612986e3d6, 0x0000000000039212}}, + {{0x000c342a3198c068, 0x0005d3ee0a31c35b, 0x0003fc2cd3c80f60, 0x0004f4ff0fbfa963, 0x000efafea65a90a6, 0x000f4b9f9513f054, 0x000590796ba7479c, 0x00000000000932a9}, {0x00037547e06b6b4e, 0x0005d93af8a64743, 0x000922627b827de1, 0x00071e9c1a46c909, 0x000f4c9bca7223bc, 0x0008cea30000643a, 0x000ec2b6d967c784, 0x0000000000073312}}, + {{0x000ecb2626cc0655, 0x000eafeb707ee40d, 0x0001edb8dca9d02f, 0x00016459a0d32bae, 0x000a1ffb926626de, 0x000578b4a9a2ff38, 0x0004434e5ad96d8f, 0x00000000000883e7}, {0x00041045bc252635, 0x0002d1d8eecaa72c, 0x000edd696d444309, 0x0002faed758ae41f, 0x00004a85d867e49b, 0x0008cba866a9a229, 0x0009822fb89dcee6, 0x000000000007f09a}}, + {{0x0009f15eb1bbb5c7, 0x000d952ec99556bc, 0x00015795c8a4dc35, 0x000337c6dcc7816c, 0x0009791f7cf1e881, 0x000885a42e4e7b6d, 0x000e41faa717aa59, 0x00000000000f9c01}, {0x000171c4ffe4a6bc, 0x0000ccf208d57a05, 0x00042714fd20944a, 0x000871b264ce04b2, 0x0006cd42026a7261, 0x0009f99fe66be4a8, 0x000e2bc5397b7782, 0x0000000000024578}}, + {{0x000b87e03bf622cc, 0x0002fadc79436506, 0x0000be1fdf9a8888, 0x000aaa40406c1296, 0x000c8b658d3cef9f, 0x000435baff4e6388, 0x000c997262beb41e, 0x00000000000fdaea}, {0x000ba84e0b8f458e, 0x00045d359f7d8428, 0x00016b951ae31b5d, 0x000f03229498ba51, 0x000a85bf35adb18c, 0x000aa4bc8c67388c, 0x00027a8a7a6aa262, 0x0000000000072f46}}, + {{0x0001e4a772f0f152, 0x000520733667a853, 0x000ae90cf08b2488, 0x0009b27a7bc26604, 0x0008eb4f0c7a7ca2, 0x000f276309fefa69, 0x0001337b6f351301, 0x00000000000fcfb1}, {0x00022648d86fc4cc, 0x000979928d9cf841, 0x0009da8838c5ffbb, 0x0001acbe041bef47, 0x000af8d998547fbd, 0x0005a0dc57d25159, 0x0009332ec3a7d8db, 0x0000000000087e3e}}, + {{0x00088fc716a5b4c1, 0x000423fb812eeafe, 0x000a6b9f65779527, 0x00041838fbefbe46, 0x0004a4b24a05e572, 0x0000c0a432b7d49f, 0x0001db23b138d071, 0x00000000000a85ec}, {0x00095de9d8768d19, 0x0006d7cc1f3d657e, 0x000b6e219733e2a8, 0x00023128f56981d2, 0x000eb4080a011bda, 0x000999b7f68663ea, 0x00080c8dd7ba7e9f, 0x00000000000b6865}}, + {{0x000b2ea58bc5b2ba, 0x00008ba8418f2c05, 0x000ab2d74f8719f3, 0x00038d7bce1e82e0, 0x000eb397915b4e64, 0x0004cf6599e489b3, 0x000affa9baea9ffb, 0x0000000000042ef4}, {0x0001f2cfd470aeb9, 0x000eeae3fb532a9f, 0x0001d5334d1ddf3c, 0x0008e28defe047ca, 0x0009d24e60fe8972, 0x0000f710c63a8c67, 0x000d3cadacbf9247, 0x000000000005e198}}, + }, + { + /* digit=41 [{1,2,3,..,}]*([2^164]*G) */ + {{0x0008597cdef10944, 0x000f4294d29542ec, 0x00058a58394c4343, 0x0007f9158f95038b, 0x000164420c94fa1a, 0x0003caea8b137981, 0x0003402b686e1e09, 0x00000000000f9e1c}, {0x00006da6276d2e4f, 0x000cacd1beecf39b, 0x000bd69a9fc92254, 0x000c7192dfc2b165, 0x000dcee7e854cecb, 0x000635cc82cdb955, 0x0007d39fefc321f2, 0x000000000002936f}}, + {{0x000f165eb19500c6, 0x000f54962c020b57, 0x000116eb855d7c76, 0x0009a79dd189c401, 0x000d6ce517a77854, 0x000d6bb9747675cd, 0x0000295102294e32, 0x000000000006ed1a}, {0x000926ef8530f97d, 0x000353efb54e82c3, 0x0002eec5a292f22f, 0x000c2948967fb050, 0x0009be04e909955b, 0x0001efad6373615c, 0x00097af1fcf82011, 0x000000000006fd2e}}, + {{0x000445389cf3da63, 0x0002b85e1e4ab383, 0x0004d8f24163478b, 0x0004da1a717e0356, 0x00080f1bf3dfc0b8, 0x000a6fd41f1a63b2, 0x000cab47b74201ab, 0x000000000003518f}, {0x000a17bf41f156b8, 0x00031e12511fae1c, 0x0005a421fc7a58f4, 0x000fb10db5665c05, 0x0003b99f4d5a20e0, 0x000b7dbceb5448a3, 0x000b87cb1847ad46, 0x00000000000fdcad}}, + {{0x00040c75d27c479b, 0x000823f2b5bd3e20, 0x000298ef45cbe8a6, 0x000f2db94256fe1f, 0x0009318ddb03532e, 0x00024c8e1acbfc45, 0x0003db2375f9fd5f, 0x0000000000037078}, {0x0002335b7531e78b, 0x000251bd461e7e12, 0x000e223c32f4b08c, 0x000777d8845f315e, 0x000697fc92c7c9f8, 0x00092954081aed29, 0x000fe09f2f8d7949, 0x00000000000ff5eb}}, + {{0x0004fbb34790cc07, 0x000a4397049f47ff, 0x00000e7e84e96f9b, 0x0005ec1e7862c0cf, 0x000834350bf1ce6d, 0x000ec8d7417a98db, 0x000aa86ceccd8030, 0x00000000000bcab4}, {0x00032ba3b5c44605, 0x000c04378b1fdff3, 0x0002189e90f61242, 0x0000faa8d60f86df, 0x000a3573271abddf, 0x0008f8032987583d, 0x0003f6b0afe4ec4b, 0x00000000000b69d0}}, + {{0x000f8df0532bb051, 0x000c5bd9a66d6010, 0x000c7470f77e12e7, 0x00051dfef38e9b37, 0x0005754fb3fba751, 0x000069b72a3348ae, 0x000faf1218fa8f13, 0x000000000000835d}, {0x0007a4c220543f04, 0x000c02121a98ebed, 0x0005ec4ceabea5d8, 0x000a4be1a1eb6eea, 0x0002adeb3ae51b23, 0x000ea2b45b5c48b9, 0x0008eaeebd305ded, 0x00000000000c3719}}, + {{0x00055d2a529f419b, 0x00062f73471b59c9, 0x0003ecf010a8f9e8, 0x000497dae082cef5, 0x0005c3e563bc57cb, 0x000125f95dfcbf2b, 0x00001922149c0fd1, 0x00000000000425bc}, {0x000c9ac134356e8b, 0x0000e049476de7aa, 0x0008c62ed440f124, 0x000c62d1256424f6, 0x000541bc66fa56c5, 0x0006ada140a118ee, 0x0008c50d8e9ff829, 0x000000000000134f}}, + {{0x000b2c8bea306a01, 0x000b1d0960bd7257, 0x0002ca4efc9832f7, 0x000cc77a98509175, 0x0001e5f81554975c, 0x000cff2c8b41bd53, 0x000be3bdf8ab57c8, 0x00000000000f5822}, {0x000ad597c5610627, 0x000ae1f0ac0e6f99, 0x000855b71125b2a5, 0x0008b82e3cc86ac3, 0x000d2b2beaee22bd, 0x0002617ffc43bde8, 0x0000968168781e41, 0x00000000000b7ee7}}, + }, + { + /* digit=42 [{1,2,3,..,}]*([2^168]*G) */ + {{0x000956a7f54f949d, 0x00074086945790c5, 0x000771ce236fcb82, 0x000b0c6000575064, 0x00080b09adeb2c04, 0x00081474f468be6e, 0x000cce2f3bf32b6f, 0x00000000000a712c}, {0x000c24bf8b416a6b, 0x0004c292cee41c19, 0x0008e149d7276386, 0x000a66156f47b2ac, 0x0005840b5d1be54d, 0x0006e8cf62ca7683, 0x00053eb52adb6a8a, 0x00000000000dade1}}, + {{0x00026c98ae834331, 0x000b365f7d2c0d6e, 0x0004cfcca31f7dbe, 0x000634c986436f32, 0x000133356165e268, 0x000c7957d6334d8d, 0x000983f17164269e, 0x00000000000b8093}, {0x0008676a1037657d, 0x000d9edb1fe5cc2a, 0x0001cd1de0787da3, 0x0005f4da691b6657, 0x0001e1e2727e746e, 0x00027b0296117129, 0x000197bb4aa8f16f, 0x000000000007f42c}}, + {{0x000a6e4b3ca52862, 0x000cf2af8bdfa5a6, 0x000675c2d00d6d96, 0x000d5ced7046d2e5, 0x0007d545fd33d57f, 0x00061ffd75ea025f, 0x000242e2ccb6f431, 0x0000000000009406}, {0x000194e235777423, 0x00019f3536d60805, 0x0005fe57dd0b2a05, 0x000b06a5cc554450, 0x000f9a9e2a66fd15, 0x0003dfd0261b0feb, 0x00051fdc3c057665, 0x000000000000a8ab}}, + {{0x00014e15511a3745, 0x00067fe19901abc4, 0x0000c6f09a808e87, 0x000012556c4ce5cb, 0x0005938c89ab92fd, 0x000a587b123172d6, 0x000c50a71f8a33aa, 0x00000000000b55c9}, {0x0009dec34d6b29ab, 0x00056ec005f6a241, 0x000b67510d45fff0, 0x000d67f9e26361fb, 0x000321389c2598a4, 0x000ffbcee7f0a2b2, 0x000888d158820795, 0x000000000009f36a}}, + {{0x00065f3227de5d3c, 0x0001e5ffec1d7642, 0x000dceb00d947f3b, 0x000844c649c850b5, 0x000610fa337dfbe3, 0x00080773d450263e, 0x00066c44f7c8f402, 0x00000000000e8969}, {0x0009e0325576575b, 0x000a42587f475435, 0x0002c020daa3c5c5, 0x0002f667071543b1, 0x000e06577b749e90, 0x0000bee1303398aa, 0x000cec030926d691, 0x00000000000ffa92}}, + {{0x000298023770357c, 0x000dae4ee3345cdf, 0x000943bb20278bd9, 0x000ca667ce118490, 0x000dcb69c7ead817, 0x000680afeda222cd, 0x000ca874ac74709d, 0x00000000000d9596}, {0x0002187a0dd3835c, 0x00082dff57da7e9a, 0x0006d7aa1a2ea94a, 0x000ba28b7fbc1b01, 0x000c13d4ed0f71c0, 0x0003a2ef260faab1, 0x000dff6fbe3567ea, 0x000000000004e577}}, + {{0x000b9f236346df15, 0x000f89b758b50c99, 0x00075b638b06df34, 0x000b3c39ee88a784, 0x0001105e1ec04669, 0x00088ea133f36a67, 0x000aadd0f30e5d9e, 0x00000000000baecb}, {0x000d89dcc4fedb34, 0x000d3ec65be650a4, 0x00093dd7d659e073, 0x0005d29942ce52c4, 0x0007d3ce28d4f719, 0x0007fc9041220187, 0x00055e9c962aa1a9, 0x0000000000065c5a}}, + {{0x00095e9750ada30e, 0x00094eccb421e7ff, 0x000dfa5cb406ba75, 0x000da9e05a53972f, 0x00007bc99fead344, 0x000f77bf53a8035e, 0x00078ae0214485c0, 0x00000000000e54df}, {0x00053ac771ed9aaf, 0x00027def45af5dcd, 0x00024afc33d18821, 0x0007db1c337e0181, 0x0006b84671d5a9b1, 0x0007d696d026a4f6, 0x00022a606142343b, 0x0000000000081cfd}}, + }, + { + /* digit=43 [{1,2,3,..,}]*([2^172]*G) */ + {{0x000d2a53b2756567, 0x000f3feb984b33c0, 0x0004e95d9895327d, 0x000f97e3ca0a9a03, 0x000dacc000ac177e, 0x00040f51a76d4796, 0x000810bad0fa6eb1, 0x0000000000006ebc}, {0x000c76db6b103c54, 0x00004f89eb78f367, 0x000ad3bb031162c2, 0x0009cfbb25e9d1c3, 0x000fb4e7aef3e2b2, 0x00067e8459388ea8, 0x0006d7ee606c12e2, 0x000000000009f580}}, + {{0x0008f59540514451, 0x00028cf947c06046, 0x00062665be2e4fbd, 0x00015c05f1835ca3, 0x0002d8c79d90d001, 0x000b5f791df08415, 0x0008cdc0c3a6846d, 0x00000000000749b1}, {0x0000ce2ed12d25c3, 0x000d8d314b7d4a22, 0x000dfaf9b4508139, 0x0005af06855a9438, 0x000ee9d02ab997ed, 0x00038a5d0ea84ae9, 0x000eabb87e903432, 0x00000000000650a0}}, + {{0x000c8f034ea36274, 0x00088357540ab419, 0x0000f5e32c760e57, 0x00073ac14d7fed37, 0x000fd186ee3d33d2, 0x000a7b1d9fef6b9f, 0x000bc2a94c207101, 0x0000000000050bc8}, {0x00013f9560f76983, 0x000e5c68959c999a, 0x000056367228b52b, 0x000a4fce6861310f, 0x0000c828330f7a73, 0x000f74fdb19bcac9, 0x0002f473e3b66f7e, 0x0000000000052d8f}}, + {{0x0008b2d06a3248b0, 0x0008e58225208828, 0x00095368e614a61f, 0x000e45562fe86dbb, 0x00082dc5b2f11224, 0x000096555a8c8a47, 0x0004528a957b8dc3, 0x00000000000b1591}, {0x00063a60dfca11b8, 0x000161e563c57eb9, 0x00024a9e6e7bbb16, 0x0002de99462e7a31, 0x0001c2489214f8f6, 0x00074639c6b3dfe9, 0x0004b56c1d8fc421, 0x00000000000ef88d}}, + {{0x00071f1bee09bff3, 0x0004a6eda384edeb, 0x0001d457a27a9c42, 0x000e6af10e01b58c, 0x000ae1175185c441, 0x0000dfcc6ac962bc, 0x0001b472d34d676f, 0x00000000000a9412}, {0x000f38c043747e7d, 0x000ad77dea14649d, 0x00065b52576e79ef, 0x000c09dd5d17db20, 0x000db45a6e94625a, 0x0001f8caf579edea, 0x000b8ea659282a84, 0x00000000000c11a7}}, + {{0x000f9bf364d3e9eb, 0x000407d0850b3dae, 0x000e31cf311bd53b, 0x000f1f891cb75575, 0x00089d3b6afe68ce, 0x0003b46e427a6ba7, 0x000059f220f9c1f8, 0x00000000000f526e}, {0x0007512e159b9fa5, 0x00094edf3cccac66, 0x0003e3258b2c0e34, 0x000d9e98cc78d3e7, 0x000b5fa48469cc09, 0x000686001391bc40, 0x00073a22bcdcd522, 0x000000000007c599}}, + {{0x0002ae0971dbb084, 0x000bd9de8555bad1, 0x000c9834d42cb891, 0x0000285de654b80c, 0x0008802be80bf17f, 0x000d823bf33998d8, 0x0006b64095923d5a, 0x00000000000e848f}, {0x000fcca2a1ce91f8, 0x00015c6e95017db4, 0x00048a3538b7e8ae, 0x0001be7a70558759, 0x0008441da4770c3f, 0x00048d4c2b652671, 0x0008deaba3b06f9c, 0x00000000000086f1}}, + {{0x000d473962fbc397, 0x000b15a4a5ce3b56, 0x0003f34c786123b8, 0x000388e4efe9a313, 0x000aef9d074bd459, 0x000ab9cb03a45c11, 0x000566f68ab50b93, 0x00000000000ecd9a}, {0x0008303c4d104a42, 0x000f0bfb79b7f7f4, 0x000a0520b1df9755, 0x000aa21877390f14, 0x0005e314cfb54f31, 0x0008eab122de0c64, 0x0004f656d904f623, 0x00000000000ccb4d}}, + }, + { + /* digit=44 [{1,2,3,..,}]*([2^176]*G) */ + {{0x0007aa3a213de299, 0x000c93eb83a8707f, 0x000eb1f52edb04b6, 0x000c77a53abe4e9c, 0x000ebb9feb8257b8, 0x0006f922e0a14673, 0x00026cc0a6cbf7f2, 0x00000000000a32e5}, {0x000ec20f9c4de649, 0x00049ca417e66df1, 0x0009b8c741987bef, 0x0000e7a62e135de2, 0x000ea7ee82c72bae, 0x000776c74962bdca, 0x000feb573d7f6ae5, 0x000000000006ffbe}}, + {{0x000a70e677b6f831, 0x000b9cbc0bb18f0d, 0x00037297c3884bb7, 0x000b350d38064428, 0x000c397a7602f62c, 0x000987d82e4d2f1c, 0x0009faa54bd48e43, 0x000000000004f0a1}, {0x000a1b4997cc48fa, 0x00005fa0c9a44d6a, 0x00012729fa8ce7f0, 0x0002c5b9cbd8d343, 0x000813d979568e24, 0x000da55fa1671eb0, 0x000ce5ccae388f40, 0x00000000000f376d}}, + {{0x000f917fe9a26ae0, 0x0003ae54d92cd055, 0x000e0e9599c7454d, 0x0007fd2849f6143a, 0x000dacd0202d7c90, 0x00092d19abb11dd2, 0x000677a4913a701d, 0x00000000000cf610}, {0x000f3626f0aa0d9f, 0x000a3fff1e1d462d, 0x0009edea6495252f, 0x000f33a92cabf724, 0x000ce329d1adcafc, 0x0009a0e4cd571e13, 0x000f867626ad237a, 0x00000000000130d7}}, + {{0x000f8196d845d3e6, 0x0002f8a89daef137, 0x0004ece7e9ffa3ea, 0x00023775b80bb4b5, 0x0002a45b362648d9, 0x0005bfe910a587c5, 0x0007d7daff503cc7, 0x00000000000116d0}, {0x000600a28d48ec00, 0x000916b5a471517d, 0x0001f4eebe019105, 0x0006cfc595abf8dc, 0x0009ed0391ce8f07, 0x000fcabd3c9de4ce, 0x0009edaaaad03ae1, 0x0000000000087b19}}, + {{0x000b51557a9fd4ff, 0x00034b0641d0941f, 0x00049c97e60548cf, 0x0005b4b00d5ec6f7, 0x00015569d89ad12a, 0x000ac72089be1a11, 0x000df19c0566deff, 0x000000000007034e}, {0x00000817b5f1bb5e, 0x000e5636aeb6adf8, 0x0006c2164b0bbfac, 0x000f898734e9d301, 0x00095ccdc6bcf4e2, 0x0008a4f28daf7421, 0x0002c39d39249f60, 0x000000000008820e}}, + {{0x000d9387d2303055, 0x000ac620248118e0, 0x00080c838dc206ab, 0x000eb38d7f033fdf, 0x000232646d6f86b3, 0x000dae596ee3226b, 0x0008e58c4825f6f1, 0x00000000000a5bcb}, {0x0000edaef1eabcc8, 0x0006f904a53484a2, 0x0007fa1deed27103, 0x000329f21d45f8ad, 0x000a06605546af6a, 0x000a93d14f20ad88, 0x000174cf7a0e9619, 0x0000000000091c97}}, + {{0x000ae272638371ad, 0x0005559edd263abb, 0x000509e662e63add, 0x0000d304e7f07169, 0x000119b88200bf4a, 0x000da801e36fc0e4, 0x0002c791db560240, 0x000000000002c72c}, {0x0006387b3ebbf52c, 0x0000dfe960c2596c, 0x00093166fd89300b, 0x00080febccc1576b, 0x0005c3c88f475a64, 0x0007bd8ec72f4e5e, 0x00055e224e7e749a, 0x0000000000076314}}, + {{0x00073d61157ae785, 0x000ab42c9fad4fc2, 0x0000e5d3107f2d93, 0x000c7fdb149854b8, 0x00002fc359eb0cf4, 0x000ec86034a7d900, 0x000e149ff0c3ea29, 0x000000000009b24e}, {0x000512a0eb94d71b, 0x000e0638c80999de, 0x000012d24a63feaf, 0x000e0f8a07ea5482, 0x0002aecdec3f2fb1, 0x00074025b1e580d3, 0x000164bbf895730f, 0x00000000000dd529}}, + }, + { + /* digit=45 [{1,2,3,..,}]*([2^180]*G) */ + {{0x00051b4cfaf372e5, 0x000b9fa2db519927, 0x000d4edc529b8ffb, 0x000af1d605917201, 0x000e782a09939f88, 0x000c710d31c5fea5, 0x000365e0fb15884e, 0x00000000000d32ce}, {0x00054592dfab29b3, 0x000d7d9f896aa46a, 0x000ce02cec631ef0, 0x000992dca6e73436, 0x000a6fd0c08b1b76, 0x0000f5c2376338fc, 0x00035bc3ea4c65a0, 0x00000000000b316b}}, + {{0x0001e6b975664a84, 0x000aa14f962e38f4, 0x000c4a3248d485a4, 0x00011c079e777bf3, 0x000b4657c31b2c0e, 0x000494de3a1705ef, 0x00071802688fd23c, 0x00000000000412a8}, {0x000b58909626d6fa, 0x00004878fc7ace41, 0x000bfc58da0a4094, 0x0003c4c704b70c17, 0x00087323c0087c81, 0x000089f1a98553da, 0x0002914f63cec663, 0x000000000009655d}}, + {{0x000f1be887dbd011, 0x0008384e5541ec05, 0x0002bbc7edd0f227, 0x0003ad69beaad3d1, 0x0000f51c2714e0a4, 0x000ea5b0c97dd182, 0x0007caac2b4cb457, 0x00000000000d1176}, {0x000327be0b446dbc, 0x000e318ccf36cb48, 0x000fe4f5fd270bff, 0x000ce43d8d292a8d, 0x0008d58c4ee79811, 0x0005c65a772c5fc6, 0x0006695bc0f0bed3, 0x00000000000cbbf9}}, + {{0x00002ac6c24f6061, 0x0003810586ea68e3, 0x0007603f1b64b158, 0x000c4d7dfbfa352d, 0x00021e1c2291a42f, 0x00011760abf38c38, 0x0004d746e40ef60e, 0x00000000000dcb97}, {0x000c4f8f01f54098, 0x000f1755b105ba56, 0x0001f9ffa1baf4e7, 0x000d0b00945db608, 0x000cf2809e1ca630, 0x0006c95c5a160ac9, 0x00074f38fc1113dc, 0x000000000005d525}}, + {{0x0001da84872cc14a, 0x0009a7eba3da615c, 0x000558d3935c6438, 0x0007d982b93d8b2c, 0x000c7cad1f758c91, 0x000ff150aca8fc6a, 0x0007fa5f581f19a0, 0x00000000000e0832}, {0x0005d538d28d5c50, 0x00038c774f18716a, 0x00051c30fd1c0854, 0x0006e9b8ad72b112, 0x000b917986cfce03, 0x00025cf9b463f9eb, 0x000feabe51632813, 0x00000000000dd7e5}}, + {{0x000710a35bbc6ad8, 0x00005a4e9f29eaf6, 0x000a92c5e19e2d59, 0x00084e42993359de, 0x000f224d5aa30e21, 0x000132c484f96ce7, 0x000f5f0862e2003a, 0x000000000000f015}, {0x00066db2ab4fc1aa, 0x0007cab9d51492bc, 0x0009b538d3bdb7a7, 0x000e671c1fd96e3a, 0x000e71a703b24865, 0x0002add107baf4db, 0x000d3083dd6cf914, 0x0000000000098461}}, + {{0x000b2da1393d8e42, 0x00051714c1d1ba41, 0x000ef78ff03cd88b, 0x000ea3a6951ac80b, 0x0000ac00c8377f23, 0x00024cc1b5c59929, 0x00062bf6efa2b3bf, 0x000000000001e844}, {0x0006a668e721edeb, 0x000069bda627d119, 0x000d91ed1a995ffb, 0x0007089c3b94ec3c, 0x000e3031699ad1ee, 0x0002b2453f75dba6, 0x000ed48ff75f7924, 0x00000000000289bf}}, + {{0x000ac44be8741dd1, 0x0002fcda68a7d811, 0x000fb56aeb52d290, 0x000e2dadce20b92a, 0x000cfc69dca6483b, 0x0004f98917de1601, 0x000a564bec17aaac, 0x000000000008d479}, {0x0009255137ea7d35, 0x00025c623cb8d743, 0x0009f513ea4e4bb1, 0x000b7c030dcde621, 0x00073a1733fdda9b, 0x0002fac31f84ea32, 0x000449d7afb6c3e8, 0x00000000000d3897}}, + }, + { + /* digit=46 [{1,2,3,..,}]*([2^184]*G) */ + {{0x0006c80cb0000ec5, 0x0007da189f30f16a, 0x000d675bfc196669, 0x0009ec37d8da76e8, 0x0006c1ea7c10307c, 0x0008c62d4b3e1d00, 0x000b3ac15e20b3b8, 0x000000000000bff3}, {0x000b01f1748ea86b, 0x000e29e330eb12b6, 0x000af2a26953e630, 0x0003cb002e1eb2af, 0x000bf525e4d4157d, 0x000a3dff1638f297, 0x000051a20f833234, 0x0000000000045a9c}}, + {{0x000b35a3033b3940, 0x00007fe9fdde8b8e, 0x0004a1bfc8bd5420, 0x00049acddde6f6e9, 0x00097e54356ca653, 0x00009f73cc53c29c, 0x000277ee15ad9457, 0x00000000000e5429}, {0x000bdd741f2769e6, 0x000d6f52035cdb19, 0x000b835933b3195b, 0x000b0ceca319bd4b, 0x000b6951fd8d26e0, 0x000c34d6f4e7eb67, 0x000b59ac3a6f4395, 0x0000000000000f60}}, + {{0x000d7763c7959780, 0x000c02c47010c514, 0x000f6a495cc56b87, 0x000be509d930f6e7, 0x000d5f56cf045c8a, 0x0002f1fc16bcf875, 0x0007101f6456c006, 0x000000000005304d}, {0x0001668b6ef47661, 0x0006dd76452e46c9, 0x0004266da10fc06f, 0x0009fc89021bde74, 0x000f4babfae0b5ae, 0x000a61fd6505c6b9, 0x00025a99d943c17e, 0x0000000000059bf1}}, + {{0x0003de8a392493e6, 0x0009cbd10b8bfc25, 0x00082fa94d1d5f3e, 0x000be5ec0c907818, 0x00071ad167ce9a18, 0x0008c1c563677f4c, 0x000275ccb254e2a6, 0x00000000000e2c4d}, {0x000250541623e5c3, 0x0003f44958cb1bf9, 0x000db2f9dd62ce34, 0x000a767a2ffdbd52, 0x0009b0b6c22d7445, 0x000c92b2e0e789c9, 0x0007823ff8b6565d, 0x00000000000eca98}}, + {{0x0000ad4fec1eb621, 0x000c36618fcad673, 0x0002540e2f8dc71a, 0x00039947d7ce5530, 0x00095257f24b90ad, 0x00098768cbf8c458, 0x0008305a94992020, 0x00000000000bb6d8}, {0x0007503283325be4, 0x0007dfae8f1616ec, 0x000fc3e0aeb8a2a8, 0x0001ea9139ea0507, 0x00012e39e1d8a72b, 0x0009c7bc282229a9, 0x0008254153bf3e47, 0x00000000000c5541}}, + {{0x000605d76cba7718, 0x000a6fadf9be90b6, 0x000490316f096fe8, 0x00024ec2f9953940, 0x000861203303cbad, 0x00089a4be6236a26, 0x000a82e4bafc3365, 0x000000000005e23f}, {0x000642137e1da447, 0x0005c8ccbc576c76, 0x0003f63011c9e098, 0x0002d5841df8dd26, 0x000914d31fcde6bc, 0x00026010bec24e1d, 0x0002f3acaaf13efc, 0x00000000000e01b9}}, + {{0x0005639fc34e5a27, 0x000c7c52789bb2f8, 0x0006d4ce23fe7231, 0x000f95aacafbbfb9, 0x000dc7f6eb6d8b6d, 0x000b4c9d737afdcb, 0x00045357775bdd6c, 0x0000000000011007}, {0x000bddf07c5f1b9e, 0x000e3903e5ba1399, 0x000d7d2fc919a9a5, 0x00018932d7ac9e4f, 0x000543ce66a8046d, 0x000956410e2fe9d1, 0x000f7244b5beb4d4, 0x00000000000bb147}}, + {{0x0006e03c443812f7, 0x0005c6f6a6104456, 0x00098182647d3e84, 0x0009a6ab51989e5d, 0x000f68f5b16842fd, 0x000f7fe671b60ce0, 0x0005a897324d8756, 0x0000000000067681}, {0x00061f269664533a, 0x0002a265ee993d1f, 0x000a90ce6a02c969, 0x000232334b4adb0c, 0x000e1e5a8d18e909, 0x0004f6456ddcd233, 0x000d9b3dc5b27c5f, 0x000000000007f421}}, + }, + { + /* digit=47 [{1,2,3,..,}]*([2^188]*G) */ + {{0x000b170252588bc8, 0x00099bfc40c30a63, 0x0001ef23d6587c46, 0x000b54dc027511d3, 0x0004cf3484ce4fd7, 0x0009beea5f479928, 0x000280655ab81106, 0x000000000007392e}, {0x000148f913baced2, 0x00084522e7b403b5, 0x000493599cdac0b8, 0x000b95877f3913fd, 0x00067dd525149cf1, 0x00008cbca3e06b92, 0x000529992e920e29, 0x000000000006d6ed}}, + {{0x00097dff92ad4838, 0x0001e8a46c9112d1, 0x0000711ed277a798, 0x00064f15cf8e4ca2, 0x000a01cb3488d4ba, 0x000bd7ded01b3908, 0x000ae169b1fa5d38, 0x0000000000018b2e}, {0x000f3694f52a1f22, 0x00019619324bdbe0, 0x000d1d925851b48d, 0x000f42e925b3f6ab, 0x00095f7e4d11a397, 0x0000d9f0132169a4, 0x0002e5c0fa9a548d, 0x0000000000089d8f}}, + {{0x0000115baf0f7c2d, 0x00040240239ae483, 0x000c7482d351827f, 0x0007151f58ec53e4, 0x000cc080d59ff9ab, 0x000f782f4d397862, 0x000d5873eee88536, 0x000000000006c1d8}, {0x000c16042c611b2f, 0x000f258bed3e5b15, 0x00036e097964eba0, 0x000c8ab8a482af89, 0x0009e746a8549044, 0x000a0548e0065858, 0x000a492538d1b926, 0x0000000000007cdd}}, + {{0x000178ddffec9175, 0x0004c9c0d5230baa, 0x0004bce21493d0f7, 0x00090dd985154559, 0x000c8dbfb46a67df, 0x000757ce3223e8b9, 0x000296f39529a36d, 0x00000000000b4648}, {0x00000562605aa919, 0x000dc330749e8973, 0x000a3ffdafa653e5, 0x0000b3494083aa87, 0x000321e321c68c32, 0x0003e78921161f5a, 0x000ccc0980deedde, 0x000000000006ad76}}, + {{0x0003725fda5a777d, 0x00086af9a69e965a, 0x000a3534516a8b8a, 0x000a77f3e52375ce, 0x0009a019a5932dff, 0x000238091ac65569, 0x000085d402f5c4df, 0x00000000000d3518}, {0x0004a37271e8fafd, 0x00007dcee2db4b54, 0x0006c1d813edf12e, 0x0005b6121bc49990, 0x000e68b9808d9cb1, 0x000d6ac5b40b34f9, 0x000b8a98de63590b, 0x0000000000039766}}, + {{0x00069c8c3d7c7657, 0x0005171191261c8a, 0x000244a0eba69bbd, 0x000344bdda57f44c, 0x000ac4f0cfd2ad4b, 0x000543efd674b758, 0x000d063bc058a077, 0x0000000000056618}, {0x000a82ca14a01b7a, 0x0009d95107c74391, 0x000a3c4cfae47f34, 0x000af35e3f1d63cf, 0x000643ab87265dbe, 0x00056c6fd012029c, 0x000e304f588a4ea2, 0x000000000003e5d2}}, + {{0x00081d2046b48f0f, 0x00043847622b5217, 0x000c2a7014a5d0be, 0x0009da7b82c435cd, 0x00025b73e01114da, 0x0008b37b399c8c43, 0x000ddab978fe55ec, 0x00000000000337d6}, {0x00034bf111412925, 0x00071e0d4ffda16d, 0x0003fc3275d2e3f4, 0x00062872913cddbb, 0x0004f67405be2a7d, 0x000a31060229afd0, 0x0009d6e372202e49, 0x000000000009fc21}}, + {{0x0001a0d511e4c022, 0x0009173fa3508062, 0x000e92c1603f0953, 0x000549f58493d985, 0x000adc79f602f64a, 0x000512b84d9ceae0, 0x0001516569e37bd1, 0x00000000000151c9}, {0x000c6addaeefed36, 0x0004c075678c2066, 0x00015cc88eb8c3b8, 0x000dca3a57fb96a6, 0x0000223dc3ce6334, 0x00011e2770ed9082, 0x0008e274f9c3aebd, 0x0000000000079c0b}}, + }, + { + /* digit=48 [{1,2,3,..,}]*([2^192]*G) */ + {{0x000688b6fc0935b1, 0x000f5378205dd339, 0x0000b901357b7bc3, 0x000c06c682e00f2c, 0x0003114d5423dbce, 0x00052463ef2a145c, 0x000b0aa01d98747a, 0x000000000007d717}, {0x000d2bf78a72f39e, 0x000d29653bc4f4a5, 0x00051b32471fd3a0, 0x00043dcaf8e3f402, 0x0000e86fe16ef779, 0x0009ffdcf70774a1, 0x0005c96b62e6f1bf, 0x0000000000058874}}, + {{0x000b3ac410563249, 0x000bc2a5f8ecef60, 0x000af14f01d834e5, 0x0001cedc59c4301d, 0x00010111d9989de3, 0x0000d5b951e0f40b, 0x000ab8d29d229f96, 0x00000000000d1dab}, {0x00033bacd39b8f1d, 0x000bd7b225cc8ccc, 0x0003c9f7b44c8f47, 0x00052a1f5fb06b38, 0x000f842b9081009b, 0x0002725128a575d3, 0x000cb7fddb48afe9, 0x000000000000b452}}, + {{0x000dcfd459bff4dd, 0x00050ae10069e26c, 0x000e9f25bee973af, 0x000caf27ebaad0bb, 0x00073dd6119cbbe4, 0x000fceefe5907bf3, 0x000c7e0a723dff9d, 0x00000000000f7cff}, {0x0002a3a44c0ca01e, 0x000d17bc95fa21e6, 0x000c0e71f388ad82, 0x0007ecd27b3335bd, 0x00027b8d7d49316a, 0x00019058fbf08e67, 0x0009ea4b209f93c6, 0x0000000000059d8f}}, + {{0x000cfbdc0726f5f2, 0x000ba167ec88a4a8, 0x00009c64d249271a, 0x000e2443877e6342, 0x000603462cb310f2, 0x0003afcee6321bf2, 0x000dcd1dbd10ee9d, 0x000000000002ca17}, {0x000667ac9826886c, 0x000d509465265738, 0x000151279a7a2541, 0x000b0f95e1c59136, 0x0001757d3a630043, 0x000def1e0a09b94d, 0x000d41533956529f, 0x00000000000d4fed}}, + {{0x000c29ae93761a8a, 0x0008a3459097559c, 0x000f79e8fee087bc, 0x0009a286ec406ef0, 0x0006fee5454dcc93, 0x000257f708d21427, 0x00085e66a0e1a56b, 0x00000000000006fb}, {0x0006c4387ea9f222, 0x0000ac44f9df22bc, 0x000c5644721083d5, 0x000a8224fca1a819, 0x0008f3ed85bf5894, 0x000899b5b8586e41, 0x000371d494dfb202, 0x00000000000ecb8e}}, + {{0x00094e8a6ed08358, 0x000cf690c0cfe457, 0x00092e98638a5e98, 0x0008042204d98a6b, 0x0005bad2eb082250, 0x0005823eec87a97f, 0x0003f6d307c59ed2, 0x000000000000df8b}, {0x0002a9b6fd1bc660, 0x000e9280ae343343, 0x00077184e86c10ae, 0x0000e5a24d04e396, 0x0007309830fcea93, 0x000afeebc0269d9a, 0x00002d41dc8f0ae4, 0x00000000000f14ee}}, + {{0x000ef795d8c64486, 0x00026efca7f7acdf, 0x000411f7c32b0a9c, 0x000b87fe57d08e0a, 0x000a7d9a1967c9ea, 0x000c2749248c01c2, 0x00063911c97ed97d, 0x000000000001cf1f}, {0x000b6334379af438, 0x000d1541f8c0d49b, 0x0006f782375b1fd6, 0x000935ba6be190e1, 0x000764494b4e9806, 0x0003c00b6ec6c5de, 0x000f15f04e2d4cb8, 0x00000000000c0b84}}, + {{0x000c9d81a70917bd, 0x000702e75a26e455, 0x0005bf4870175e47, 0x000d057ee7d8e4ba, 0x000d8994f44953df, 0x000538367b959110, 0x00029cb4a16596bb, 0x00000000000ef82f}, {0x000ea0c85d7d05e6, 0x000305a7642ffe63, 0x000b9d7a5d2d391f, 0x000b23803a4184c4, 0x00020f7fcd62c7ea, 0x000a8a0c660c67ef, 0x0002b041e05799df, 0x0000000000004d35}}, + }, + { + /* digit=49 [{1,2,3,..,}]*([2^196]*G) */ + {{0x000ffb708a3b5e85, 0x00030c97c01eab92, 0x0007510b2d7953a7, 0x000ce807fa7d3c2a, 0x000e81060874dba1, 0x0007eeead69e6f96, 0x000f3d6e3e0df74d, 0x00000000000b0c87}, {0x000317c5146f214f, 0x00028c55ae3dbb43, 0x00014b4be1d3dc49, 0x0008c591de7860a7, 0x00066e546731a600, 0x0001e45d48202f8b, 0x00015a652f2d07aa, 0x000000000006df54}}, + {{0x0007d6371007dea2, 0x00049041c706cbe5, 0x000dcf6b55c23258, 0x000cd27839e9d5ae, 0x0003bf3c4c067dc4, 0x000b7bd22dfc9db8, 0x0002da85b8094138, 0x00000000000d0f4c}, {0x0000b16d9a334a33, 0x00092d7b340062c0, 0x0002bb5502deaa2f, 0x000b2c2752366864, 0x00010113a85fa340, 0x000b327045ddd055, 0x0002ff7dfc7ab29c, 0x00000000000dabf2}}, + {{0x000a8373e5c690f8, 0x000ca2fbce9bdf20, 0x00049076d1995e9c, 0x00045939f4cbaf1b, 0x00092574a3bd48ea, 0x00092c39a56c5400, 0x00034384a39630e7, 0x00000000000eef81}, {0x000361503c11fa79, 0x00095f996760edb5, 0x000c1bbc8ea81e13, 0x00012e6966d70279, 0x00052e6f7c63a0ca, 0x000d13ead92a6d5d, 0x00068146809d269b, 0x0000000000067aac}}, + {{0x000cf4e4cd35d7a3, 0x000a13fc9b3cedea, 0x000ac33c871e844f, 0x000a58afe1ad536c, 0x0008cb39149f2003, 0x000edf470cec4be3, 0x0005194d578c99bd, 0x000000000003a356}, {0x0001980c5865f55f, 0x000607a762f2732a, 0x0003ce874c8a141c, 0x000817f270c508e9, 0x00049fdb29c8dc0e, 0x0002711d35a7be20, 0x0000c2fa1a0be3cb, 0x000000000003786a}}, + {{0x00065cdb1cddc024, 0x000c41d0af6b5128, 0x0006106e0f532684, 0x0001951b1ea8fc4c, 0x0004b1fae4826764, 0x00023477bc0b9006, 0x0009ce7012642f66, 0x000000000005bf01}, {0x00001d44438309f3, 0x0007fca1f46757f4, 0x0004d56451db59bb, 0x0004ef2d3868de95, 0x0001044e0c189c03, 0x0005e38c30533d92, 0x000053ba6cf14ecb, 0x00000000000509d7}}, + {{0x000af6aee4d4a85d, 0x000c0e164268de02, 0x0001633ba7cb9816, 0x000979478ab17f45, 0x000e0179ed0e734f, 0x000a2686746d468d, 0x00085d7e68f006df, 0x00000000000e3d04}, {0x00073699ad94d8f6, 0x000c30913a1d74ab, 0x000e2aa1b6d33ea2, 0x000a79e49eadd08e, 0x00017dd8f954eeb1, 0x000bb26d0433f5e4, 0x000e2970a6281430, 0x00000000000ff5e8}}, + {{0x000235f9cfa08aab, 0x000eb6a352b56ce9, 0x0002152b2e478d04, 0x0007c7a240e6dc62, 0x0002d313b4a9ee1f, 0x00001a40585d5be6, 0x000d5a1522c5d25c, 0x00000000000960af}, {0x000459bf66d63a1d, 0x000e4a3cb77f327b, 0x0001a15093d3f2d2, 0x0000c7d3b93fa9e1, 0x00013c0383ad8409, 0x000f7a220c77f1ee, 0x000bfc461c93b776, 0x0000000000004ac0}}, + {{0x000fd3f75cd14c88, 0x0002a3c7d6b63ea7, 0x0002b345f341120e, 0x0005d20aa0eaa1ec, 0x000fc0eab4908ed1, 0x000d9f260e944ad2, 0x000ba371525aa1f6, 0x0000000000016146}, {0x000bd29ab6e83fdb, 0x00068f94019075db, 0x0002a02a4fd970a1, 0x0001c37cab1060af, 0x0000c8cac96f6a4e, 0x0002466ec357fe4d, 0x000e7097a8b8ab6a, 0x000000000009c01b}}, + }, + { + /* digit=50 [{1,2,3,..,}]*([2^200]*G) */ + {{0x0007eae876f30205, 0x000645b0b5d68b38, 0x0002f6471178cf56, 0x0000a4a404a3458c, 0x00059f467b6072ad, 0x0006348091de8e25, 0x000178a4b3570590, 0x00000000000706f0}, {0x0007cba07f8d2545, 0x0006d588d21aac4c, 0x0001bb1a8ee3a06e, 0x000e73d241bcd915, 0x00022facc7ccf4e7, 0x00025d2a0b8d8a1d, 0x000608483c35a71d, 0x000000000001ef9f}}, + {{0x0009cd91f152b14c, 0x00034a704015f319, 0x000a64fabfbdef40, 0x000301f2ccb94180, 0x00046f00d8aa697f, 0x00038a0173ee8776, 0x0005432b5afaf881, 0x00000000000832d7}, {0x0002183eafee3abb, 0x000d627c27ce1884, 0x000735007191c91b, 0x0005ac75b752008f, 0x0001e84fe5f192dc, 0x0005929cecf382e0, 0x000ffa90e034197d, 0x0000000000015ca3}}, + {{0x000596896506329d, 0x00058cb51f038efe, 0x00073c05f41ddada, 0x000fafab41fe1a74, 0x000da719f25493c8, 0x0004f5cde6297701, 0x0005426e9165bc64, 0x000000000000c11c}, {0x000368f61fe7d95a, 0x00098a2564809894, 0x000e829acda88407, 0x000592622b1d1be2, 0x00026ecdd041286a, 0x0009f952486a3d75, 0x000b0f4b867e0a64, 0x000000000000629c}}, + {{0x000259f3facaa9bd, 0x0001d11dd860d21a, 0x000b8c19c604b970, 0x000aff635c019302, 0x0001e3a4a900d4f8, 0x00078c8ba96a727b, 0x0007c41426daffde, 0x000000000008d152}, {0x0001e6f4fd354295, 0x0004a0c0d5233cfd, 0x00066c04a38eba93, 0x000bee43d914fb41, 0x0008f3ba26a64828, 0x0004eb26f8324ea3, 0x0007bf027590f3a9, 0x00000000000acd95}}, + {{0x000a71b96f713d9b, 0x00013f4f668435ae, 0x0008fef0f35f5919, 0x000e86e7365712f9, 0x00088a822bc0f607, 0x0001299b3d588229, 0x000b1a2cfbd63ac6, 0x0000000000067167}, {0x0006f5a47be411d6, 0x000b0750f673f622, 0x00032c38df6a058a, 0x0005bd169123c758, 0x0006eab99b375e6d, 0x000aec6a36a93d1b, 0x0008186ef4f7e68c, 0x00000000000cf3ed}}, + {{0x0006410726f50135, 0x000fd959353be170, 0x000b4de98d5dc91d, 0x00026f799d7a4f4a, 0x000e52fe4b656a48, 0x000038573ab146ec, 0x000e8494fc21d735, 0x00000000000f4d56}, {0x0006901ebf8c490f, 0x00093e15ca04c71d, 0x000ef178dcf47997, 0x00079244f21a9114, 0x0009dcc76132ef7e, 0x000e890482eecb7e, 0x0002c55b484745db, 0x000000000006e43a}}, + {{0x000b8d876ab51a4b, 0x0001af92b3072f8e, 0x000d8f5d67f2d2e3, 0x000d5edc578e3a39, 0x00029587fa22e51b, 0x0002eba85efda70d, 0x000530cfec17089b, 0x00000000000af7ba}, {0x0004893a5eb2bed8, 0x000bb5ac155ae396, 0x0009a3394a2b6335, 0x00086c2c38718a82, 0x0003d63745b7280e, 0x0008a79aa9d12de7, 0x000bf70e8ea855bf, 0x00000000000bd705}}, + {{0x000260c123f30563, 0x000c53ede2484b68, 0x000620a80e97a435, 0x0009e93962a667bd, 0x000b130f2cea5606, 0x000366a66c931266, 0x0003b14bd6a6fca7, 0x00000000000aa5ac}, {0x0004e3f2adddce7d, 0x00044a025d0ef29e, 0x00075ab6560ff06a, 0x000927f2b3057f30, 0x000a1499f8844809, 0x000b9a653b001c10, 0x000d05309d141c30, 0x00000000000bf659}}, + }, + { + /* digit=51 [{1,2,3,..,}]*([2^204]*G) */ + {{0x000d68f9d41abcc8, 0x00016a6c328ffdb0, 0x000797038aa63e5d, 0x0007d39063de7eb8, 0x000710daf9bd691e, 0x0008b5d7a998df4e, 0x0004b8c7085b9e71, 0x0000000000016b3d}, {0x00019da01ecaa2a1, 0x000494dfce693daf, 0x0007011a8e84696a, 0x00004bf4491fb345, 0x00014552451c2c19, 0x0005e5e407c1bf11, 0x0003726562cc2c3c, 0x00000000000fe0e4}}, + {{0x00073ecab0b13cfe, 0x0002484c3630b425, 0x0005d7cee5256fab, 0x000125ff61af001c, 0x000fbfea35255abd, 0x000e0cb6e69bca56, 0x0005a6384af19900, 0x00000000000d0047}, {0x0001438f80a7fcba, 0x00090edafde48dd9, 0x000a30b2135b9aaa, 0x000f97a6c8ffcca5, 0x0003e5a9cc5cf14c, 0x000104e054d6cec2, 0x0007c1b0d678f88a, 0x000000000009fb52}}, + {{0x000cf7bdfab400e3, 0x0009e8618ffa6a37, 0x00041539f0cbda9a, 0x0000d744f61edff9, 0x0009eb7a476f5b1b, 0x0002ee99b33df67d, 0x0002cc7f1a767ea9, 0x000000000002223a}, {0x0004324c9cd0a9f1, 0x000f616f376f2586, 0x000c0794e16b9222, 0x000516ca58765df0, 0x00062260ed6b8dc1, 0x0004b29ba8934082, 0x000bba060eb0afcf, 0x000000000001d252}}, + {{0x000bb25431b5857e, 0x000160d6cadbf906, 0x000790df51943fb8, 0x0003c734ab19507e, 0x0005660086b33b43, 0x000eb0f434fc5340, 0x00058d770ae903a1, 0x00000000000f6b5b}, {0x000dc8bc8bb4bdd2, 0x000d6e206e14147d, 0x00079b5341d6e69b, 0x000ca2f47449e081, 0x000639fef8e1cfbf, 0x0006fc80cebaef25, 0x00061b959e37b8c1, 0x00000000000e911d}}, + {{0x0006b0541df5b61f, 0x000b0014a0907c72, 0x00060742ec5c6420, 0x0007c4dc999acc04, 0x00075e7ab1e3dbbb, 0x0008fb11e01b7710, 0x0005c2a33fefbfcd, 0x00000000000c0b8a}, {0x0004467ba7747f4b, 0x000ec774dc2669d0, 0x0007562d1fca7010, 0x000dc694d9c84626, 0x000a1e772c5f5ac4, 0x00083fe91bf6e002, 0x000dce4922120e0b, 0x000000000003efba}}, + {{0x000263fbc0d157fd, 0x0005bc483d4b1827, 0x00037dfadf4ae121, 0x000df6fcbab1fb10, 0x0000f6cdfc0c5165, 0x0004320fceb28437, 0x000e80ab565c0099, 0x0000000000062133}, {0x0007401414422436, 0x000ee7850cda5472, 0x0007bd0ba094b0ec, 0x000805cc2c82eddf, 0x0006cf244539d14b, 0x000dbe92dcb5468b, 0x000f1e97d43ee825, 0x0000000000089fb8}}, + {{0x000a494639f26e1a, 0x000b5421afbe0092, 0x0004dc6db28bf654, 0x000cf4db1a2705ad, 0x0006d128bcd556ca, 0x000191ad86a3a413, 0x000d242411c4b866, 0x0000000000015b45}, {0x000845fec1268b55, 0x000a74cc82459052, 0x000da0992b42bc3f, 0x000bb1c69f6298e1, 0x00031933fdb59c88, 0x0001308c3fe567b0, 0x000dfa8a6aea7188, 0x00000000000a2f0a}}, + {{0x0006a4d1fcc1ad65, 0x000d2d7bf2ac5a3e, 0x0005e362c26e5671, 0x000abaa9afa97632, 0x0004b62b36ab162f, 0x0006a84e97b7f166, 0x00043d77b9f79729, 0x000000000007dbd8}, {0x000519c3add29e33, 0x000fcc6e9c1e11fa, 0x000ac380a63f4305, 0x000a93d3bfa90c04, 0x0009d050e46afa7f, 0x000c5625655846fe, 0x000a65473b9a0d35, 0x000000000002b656}}, + }, + { + /* digit=52 [{1,2,3,..,}]*([2^208]*G) */ + {{0x000f0e1b25d4e4dc, 0x000a6372798f002b, 0x000537a488c42515, 0x000f9a98a1e25677, 0x000ce70391c85e64, 0x000f024585870254, 0x000bed2def81a341, 0x000000000001d087}, {0x0002a1629bafa8b1, 0x0006d3557d07cb43, 0x0009543a3877e0bb, 0x000c5675f73ba510, 0x000b9c7c670608c8, 0x0009850725309050, 0x000e962ab67da3bd, 0x00000000000e5df4}}, + {{0x00057ab93a62b1b3, 0x0004b7be81fb0ec2, 0x000d385405273506, 0x00040e27a8d16791, 0x000ad520811ebb3d, 0x000f65d231806c67, 0x0003d7add4bb6686, 0x00000000000e20e2}, {0x0008a96c64700a7f, 0x00088208b470000d, 0x000907fb1a1c5c32, 0x00064f8121c37e26, 0x0001a598efbbbd39, 0x000eef966d35ef30, 0x000e46bd76a276c5, 0x000000000000af64}}, + {{0x0007b8ba2901e630, 0x000573f40494a69d, 0x0001d7e86c246f17, 0x0003360c9e634b1f, 0x00096ab166bbacc3, 0x000fdb67e6cf72ff, 0x000736477d8f2db9, 0x00000000000cb644}, {0x0000821b2e82caf8, 0x0007549454e1ad4f, 0x000486f6c48cff7d, 0x0005f0be8e7b06ec, 0x00047dc40b498042, 0x000ed620b862df52, 0x000a648ca7d7c812, 0x000000000003c45b}}, + {{0x000d7620f273aa67, 0x000e1169474a1e10, 0x000056ab42590c74, 0x000de922ede425c9, 0x000a6df8a8908589, 0x000a8b8e350e03fe, 0x00091a0d8a5c1c4b, 0x000000000003fffb}, {0x00026981fafa18b5, 0x000f721cf05437b0, 0x0007e513859293da, 0x0007eaed0962c826, 0x0004213f6004c323, 0x000148b6b43d6ac3, 0x00080a45e619b2d4, 0x00000000000ea5fb}}, + {{0x00014768f5f99aa5, 0x00067314ea217285, 0x000017c8fd29a716, 0x000fb46a63ea8fc5, 0x000890d84e5b0902, 0x000e49b8a925a6dc, 0x000be5e2e74f9c14, 0x0000000000007d45}, {0x000cae18673b6270, 0x000667b768d075ba, 0x00089b2a5deeff6b, 0x000223360d5b216a, 0x00080a7386f475db, 0x000c47746b132b67, 0x00031d7f933fd580, 0x00000000000fbaa6}}, + {{0x000ee5b308cc45e3, 0x0002faba967ac481, 0x000d29b2fe96bd68, 0x000c601ef5f681db, 0x000ffddc580fe033, 0x0007572d85c34f77, 0x0004d0d30f5b66f3, 0x00000000000da20d}, {0x000030e8bcc549d9, 0x0002cdb2310273e6, 0x000ec784d2efa81a, 0x000a33f7899cd7f5, 0x000fda29c3821cce, 0x000e14ecf0f4e0a7, 0x000839c6d7c5f32b, 0x00000000000d9caa}}, + {{0x0003fe55b28c2fec, 0x0007ba884edf1601, 0x000775572e4af6c1, 0x00004152d7852a27, 0x0007f26efb4c66d0, 0x00022f8cb34732d7, 0x000ff518b3ef8e29, 0x0000000000018bcc}, {0x000ec4cab3e21461, 0x00004a219cb1deb6, 0x000868a49e96a154, 0x00099e1d90760ec0, 0x00078a94df2ef0af, 0x000058f89e6fe194, 0x000d9764b5dfcd04, 0x0000000000023d21}}, + {{0x000d7944d758c20d, 0x000209a8580a957a, 0x000f955204f37a28, 0x0000970be07f7827, 0x0000712f7b7cb4da, 0x0006a7b970ac2a26, 0x000f62c9b8ee8443, 0x0000000000011fb2}, {0x000ff5f68230c1a3, 0x0002a5daabed96f3, 0x0003bdf181469c85, 0x000b5b7d96cfb8e8, 0x000344d9e84382d6, 0x000e7da3c4d7d0d9, 0x000253fa2a9ea991, 0x00000000000d531b}}, + }, + { + /* digit=53 [{1,2,3,..,}]*([2^212]*G) */ + {{0x0003b2a8a65e5b7e, 0x000424cc41f278dc, 0x000bf1d7ec4af5a5, 0x00066640fa1ca255, 0x000b91e5edaf7053, 0x000d3de14eeb40f3, 0x000c43cdf98235f1, 0x00000000000ff018}, {0x000927ebce051283, 0x00074aa3228e6dee, 0x00043f750dae9462, 0x0000425650b2dab8, 0x00026d875f1790e9, 0x000e8a46ee4a8cad, 0x000fb5c212029c9c, 0x000000000005ed7c}}, + {{0x0007539a8f390740, 0x0008eadb5966f40b, 0x000e0b7342eb902f, 0x00073e244693a961, 0x00055982bbd3a76e, 0x0002ca13214da743, 0x000e7646e982cd5d, 0x0000000000024938}, {0x000cf856b36cb844, 0x00029749206b2571, 0x0006030c0c47215a, 0x000d1567025bb7cf, 0x000e19555c9ebee3, 0x0001639bae23f0e1, 0x000bd00dec383775, 0x0000000000005d43}}, + {{0x0002c235491635a5, 0x000e4e4e52e86121, 0x000459dc25e36e9d, 0x00051bfb49f2b393, 0x000b3f8097cf73b9, 0x0008fbf057b6cb7d, 0x0002119dfb8d0b32, 0x00000000000ebce6}, {0x000c890c36814c6b, 0x00007a31a15235a7, 0x0009c26d4a535440, 0x000834e6b5638766, 0x000d10ee5a281d22, 0x000aee4eafd91b30, 0x000a763d7a282d59, 0x0000000000073300}}, + {{0x000f6efbfb5bea3a, 0x000f878b5c14b0f6, 0x0005485b973e6dbd, 0x0002ab209e1759fd, 0x000db4b2f68cffa2, 0x0005be7f45a86263, 0x000f6d71e77c516b, 0x0000000000019844}, {0x000dc7fe7c7337ad, 0x0009d2519d0058c1, 0x000edd3b9e6ca5d6, 0x00074a685b3c2a9b, 0x000fc294f4492c6d, 0x00069fb469306f68, 0x000886552e77c22c, 0x0000000000010bb9}}, + {{0x0001ae09a4f32c66, 0x0007beba7daac862, 0x000767fe0f73dc31, 0x00018f885bdbc832, 0x000094d43909985c, 0x0009e108b86555ff, 0x000313b0b1b2b653, 0x00000000000c0bf1}, {0x0003b62754d457e4, 0x00021bd4777c10d3, 0x0007d7f58d2fb40a, 0x00057374a27f1ddc, 0x000eeaaa58ab85bc, 0x00076fac29a8ae24, 0x000377161cb2f5e8, 0x000000000006636e}}, + {{0x0001f89428b5c457, 0x0007f1674b959a73, 0x000b96ebf7106c2e, 0x000a32dc67c36488, 0x000368d720a63962, 0x00057a5b24949617, 0x000c0f4e81df85a9, 0x0000000000053123}, {0x0003624d70103a1a, 0x0003f5091dd340e1, 0x0000c9fe10861f33, 0x00020f52c119dbe8, 0x0006c94d609a5e77, 0x000dccd1fd584ae7, 0x000c6e476c63ba86, 0x0000000000032508}}, + {{0x000df9bca60288d5, 0x000016bbf77cab44, 0x0000fa9d18796041, 0x000eb1a2b9febf8d, 0x0001a25330ce357f, 0x00091799874240a8, 0x000f5c7a9ab575b4, 0x00000000000eda3e}, {0x000c7149276e2420, 0x00036360410d2e37, 0x0006d4d0d5e12db0, 0x000b466cc381b581, 0x0008247a49047bae, 0x000c58130024a98b, 0x0006d26e70b4c3e3, 0x00000000000ae8a5}}, + {{0x000d9a7dd453995c, 0x000393313a9d4705, 0x000fd95bba01fcaa, 0x000ef915e4dd5cea, 0x0003c565dd67c0fd, 0x000ed05ac902a2a9, 0x000ae9d8eba4dc7f, 0x00000000000e157d}, {0x00019071237f3ae4, 0x00006d655d0b3ced, 0x000513db82a990cd, 0x000525a0652872b6, 0x000fe68c0ddb5b7e, 0x0001cb31caf7968e, 0x00071e2ec02930f5, 0x00000000000f2be0}}, + }, + { + /* digit=54 [{1,2,3,..,}]*([2^216]*G) */ + {{0x0003b3ac56ccd2a3, 0x000649b23ab4e3e0, 0x000d023509576972, 0x0009e51e798edf99, 0x0009307675c7dbe9, 0x0008c0fb63854744, 0x00037223ffaf5562, 0x000000000001698c}, {0x000420dd9073adb8, 0x000d039f45a56f2d, 0x00011e9a2cdfa00e, 0x000079e4af138fd7, 0x000a2ee4ecc02a89, 0x000bbf92fb86371e, 0x000c51076d256a06, 0x00000000000ae3c4}}, + {{0x000340cb6908d50e, 0x00092ba2e95430b3, 0x000660e7e985a29e, 0x000b95145bdc19ee, 0x000e382e77bdf94d, 0x00020b29a951d00a, 0x0001f19940a5fbb2, 0x0000000000058fc9}, {0x000d804932dbc0b5, 0x000be682e42eaaa2, 0x000400a2efd4aee0, 0x000810016294d055, 0x00032e326d68be15, 0x000e64fceaea13fe, 0x000a8ac0dfe1ef15, 0x00000000000b8237}}, + {{0x0004480f8fce3f16, 0x000a7e59b80017bf, 0x0006c7396aa46dc8, 0x000172a5af5b47f5, 0x0000160d7e8d8799, 0x000f9a549f72c978, 0x00044a1d1ce972b2, 0x000000000004857b}, {0x000d15fb2758caea, 0x000542545bdd6f77, 0x000984fe91e9b1e2, 0x000343a4e23c0644, 0x00091d1fd9cd5a60, 0x00070b5b3986779f, 0x0005a35bd5611b35, 0x00000000000f9d76}}, + {{0x000b72123cb1cd13, 0x000e76ee65a0886b, 0x00081e4e332045b1, 0x000cc382876e523b, 0x0006d3bf53aac4a2, 0x0007f290cab7aba2, 0x0005bd5bf00871db, 0x000000000001ee6d}, {0x000bcea869ddbc32, 0x000334cafb21874b, 0x000bcaaf9d600f4d, 0x000785520b281cd0, 0x000e64d9c65ea1fe, 0x000a0e67be457198, 0x00068aa3d1a6d0c5, 0x0000000000090cc4}}, + {{0x000450a44e08b4d9, 0x00014cb0a365753f, 0x000b82633a02b2b6, 0x000210997ed887af, 0x000f30d9b2970b85, 0x000fb9c745fec3e1, 0x0007854ce4149f10, 0x000000000008cbff}, {0x000dc4bd785a06f1, 0x0009f81b0d7b3b6a, 0x000116390fc1ac37, 0x00021de2b841eb88, 0x000ad83c22e6aec2, 0x000affe9162c7d86, 0x00081d5504dcf885, 0x00000000000f4454}}, + {{0x000578651af84c0a, 0x000e0d4ee3f7f52b, 0x000cec289c787837, 0x000ee1363ebab5bb, 0x0007005ec2374c0b, 0x0002fb00670e32d7, 0x000899302fc73dc5, 0x000000000008f159}, {0x000ba114d96a8216, 0x0009d42a5478e2d1, 0x000e66d84b639b08, 0x0004970c8378f0e8, 0x00058e2c86c5042c, 0x000c7c76770c1957, 0x0003a861a95e6884, 0x00000000000d6fb4}}, + {{0x0000a2299e18ff96, 0x0001ceaf237a8503, 0x0006d80455ecbada, 0x000fa473f251ad61, 0x0006d828578e5fbf, 0x000e118adc40570f, 0x0005485cc65c0dd4, 0x000000000005da48}, {0x00073e60bf0732eb, 0x0000fe27fc2e7307, 0x0009067267d2e6a8, 0x0002fa55e27fb12d, 0x000810003fae35a3, 0x0009800c17fcfd72, 0x0002e6c74b50a3f4, 0x00000000000dbafb}}, + {{0x0002a6bfc8996b96, 0x000bd0c62fd2c8ba, 0x000a840806b7cf85, 0x000933dcef3f9e43, 0x000d9889ffa276b0, 0x0003c88d251b1ec2, 0x00052f9e84b2ba9a, 0x000000000001913e}, {0x000a4507b899f92f, 0x000e6bafc5e94164, 0x0002238654296051, 0x000cc41bed171099, 0x00036c7a41c84e9b, 0x0005369cd0db5b73, 0x000934d4be07a779, 0x000000000007bd3a}}, + }, + { + /* digit=55 [{1,2,3,..,}]*([2^220]*G) */ + {{0x0006d08f59277dc6, 0x0008a3f2eff5384f, 0x00049c170a3dfb6a, 0x000b18a0dde190dc, 0x000da26b0409af10, 0x000b1d944f491b98, 0x00054166080782a2, 0x0000000000097e8c}, {0x000baebab71369f0, 0x000d1fdbfc5f5495, 0x000a70804cb1f0f5, 0x000263857645ef4f, 0x0006a02583638e5d, 0x0005d250331bcfda, 0x000285f5330ab8d3, 0x00000000000c7cab}}, + {{0x0004a7ee3780eead, 0x0001ef16938f4dd4, 0x0005af2b9dcbcc11, 0x00095530b6490d71, 0x0001a28a296a2d50, 0x00026415c8432fef, 0x0008656f254dd08d, 0x00000000000d50c2}, {0x0005457026e64224, 0x0003c4f5bc4553f7, 0x0006183dc27db1b2, 0x000dd6e65e593411, 0x0002a56dc2eabab8, 0x000a90e05676baca, 0x000da038eea06bea, 0x00000000000174ba}}, + {{0x00021d43da6aa865, 0x0005de6a19dcb664, 0x0006a4c857b63184, 0x0009b9fc6455613f, 0x0004a7390d0eb4d8, 0x000ea135a6cb0fe4, 0x000982ade197a459, 0x0000000000020680}, {0x000776554c3cb5c6, 0x000b803db9be90e0, 0x000e56e339783849, 0x000e8d4753c196c6, 0x00000b7c6ff544de, 0x000a1b14259adcc7, 0x0004f2c6260ec24c, 0x0000000000046cbd}}, + {{0x000c69e90d279f7b, 0x00051a35e411c1f8, 0x000aa4eec7d05943, 0x000859e89a66f2be, 0x000e0def8ecd7c7c, 0x0004947b79908c37, 0x000ce88274124e34, 0x00000000000568b0}, {0x000eb0436a41e1a9, 0x00070e52919611c1, 0x000a98c568a44a8e, 0x00039e156bd3a7e1, 0x0006268f856260fb, 0x000fd8293e56a34d, 0x000fcbb3a1fe1613, 0x0000000000067537}}, + {{0x000d9811d879790e, 0x000da8a15d6fdcb9, 0x0006c38fcc4a52b8, 0x000e38c55bbe733d, 0x00051ff94a9d7a7e, 0x000585ab5eff146a, 0x000a5de572d13edd, 0x0000000000006491}, {0x000a7bbc541e4f72, 0x000a29c84e1c4d63, 0x000bbb62e6c0b1d5, 0x000cd9b385f06c82, 0x00077a7759c3db12, 0x0003bd7060c93eb9, 0x000d50f1f5b0fe68, 0x0000000000085ec3}}, + {{0x000e87011f7cd75e, 0x0006e89e48d8ba73, 0x0007fdc53e3e2631, 0x00033d7302c0daa2, 0x000a048eefe360f0, 0x000a7224415e4578, 0x0009cdfd6dec89b0, 0x0000000000030948}, {0x0003345fd128739e, 0x000ad7cdcc2a0188, 0x0002b63966c3b413, 0x0000a455812b560a, 0x00052ca31d8ca630, 0x0003a5b5a8fa5c41, 0x0004e036aa3c234f, 0x00000000000c86cf}}, + {{0x0004ff5664ce36b2, 0x0005e9a0e15351cb, 0x00019cbdd0d2f66a, 0x00059eafb29777cc, 0x000ae354cafdc170, 0x00007c3717e40e5f, 0x0009459cf594054d, 0x00000000000a71c3}, {0x0007429ea783b1e9, 0x0003469309e95af4, 0x0004f55088c266f7, 0x0004070e25823b6e, 0x000d0bc27359f216, 0x000925094ead851b, 0x000f4e3d21bfe8b0, 0x0000000000034a97}}, + {{0x000a4c18541d03ec, 0x0004ad927282fbf3, 0x0005c034c274cf2b, 0x000207f450db7135, 0x000423e16d9558b9, 0x0000e349cae95338, 0x0002bc4f10c6d4e6, 0x00000000000feb12}, {0x000eced76985b33a, 0x0002f22548cd1c2d, 0x0005b37b87399908, 0x000f912b6167b3cc, 0x00027902d2baa1c6, 0x000de34ba6967bab, 0x00025eebbe0b0836, 0x000000000004b796}}, + }, + { + /* digit=56 [{1,2,3,..,}]*([2^224]*G) */ + {{0x000e99ecf706c6bf, 0x0005c9e857f32800, 0x0001e880e21c15d7, 0x0008d68ff4f65674, 0x0005ac339148f853, 0x000dfc12f35380f1, 0x00093efef0bfdd5d, 0x000000000001387d}, {0x0009274bbe5eb9e6, 0x000aa618ce77c94f, 0x000ef0d12ae1c332, 0x000f06e00dc0da6a, 0x000e07603cc724ea, 0x0006963c7049113b, 0x0003005cf489088f, 0x00000000000ede4a}}, + {{0x000abae3c29bb132, 0x000af77e486f79a6, 0x000ea167f51170e1, 0x00028ab7df36628c, 0x00016704dcd6322b, 0x0009a35672d14d13, 0x0003b6d359977af2, 0x00000000000ec96d}, {0x00053212afaa74ef, 0x000f0fd6e400a371, 0x0003860e13fc28c5, 0x0001c7d9b8533afb, 0x00028de66eb862d8, 0x0006784eeefa638c, 0x0002237405a9d7e8, 0x00000000000a6c22}}, + {{0x000fc1e6b9032350, 0x000a46909994e4c6, 0x0006261c6638f0ac, 0x000ca05884aacaa5, 0x000996995a981505, 0x0002c000ee4b6530, 0x000b0930e00a5ed0, 0x00000000000236e7}, {0x0005ec99c1d0db26, 0x0002ce696f09d532, 0x0002f7914e3f9268, 0x000a7b401e1e2a4e, 0x00069d2d025aa9ad, 0x0004ffeb19630acb, 0x0004f69fab2c6ed8, 0x00000000000ab758}}, + {{0x000c87e27d06e6af, 0x00073f9b2dba43cc, 0x000cbbdd7e7ab099, 0x000a4f33b8104eed, 0x0000e4e1896e7692, 0x000d2aa365da885b, 0x000bcac2a30fec73, 0x0000000000086f60}, {0x000adfed330d989a, 0x00086bc8bf16d541, 0x000f4b7104707db4, 0x000e2f37e35610a9, 0x000482f9d71c8e79, 0x000e62733981139f, 0x000061f8997ec424, 0x00000000000a3518}}, + {{0x000efb4736bf4182, 0x0003f6cf0e6ef64b, 0x000b24ffed39dfee, 0x0007783856111dce, 0x0000c0e9f2b00277, 0x0007fe5073a1d36f, 0x0008f1fcf4f6365e, 0x000000000007fa7c}, {0x000ce2543c17ec02, 0x0005509a02de874d, 0x000cd3e25ee5e59f, 0x000a9654b7f4e35d, 0x0009805b58bd7211, 0x00057860ca6b2ba7, 0x000d58418302c209, 0x00000000000f99f9}}, + {{0x000634f7fb73c6b6, 0x0002e4e6ef40fcf1, 0x000c701a714f0702, 0x0003403fd41d144d, 0x0007e0774c37a4f0, 0x000c7484a3a50717, 0x00066b078e8c568e, 0x00000000000fbb3f}, {0x0000fb0d6daae4e9, 0x0002c169c9474ce5, 0x00027d6aef77ce07, 0x000968508303114b, 0x0008fad0def23e8e, 0x000c1c8da7a9797b, 0x0007210ad14404ef, 0x0000000000021ced}}, + {{0x000169a6e51baf05, 0x00088fde0d1b3e6e, 0x0008e5407b7aa0be, 0x000ad79c9eb9de48, 0x000b0ffbcdac16d3, 0x00020287c2707ec8, 0x00055ad7e6750fa2, 0x000000000009c2e1}, {0x000dcbd856a04522, 0x000e43018c309307, 0x000def4e0648d266, 0x00023aecf15a4af5, 0x000cc1b8cca01aa3, 0x00043a969f085d69, 0x00043047a3eaccb1, 0x00000000000f3a98}}, + {{0x000270a279eabd20, 0x000d5c7e9ddef0ef, 0x00060c66b8938b7d, 0x000746db239bb82a, 0x000b28ea13416bc0, 0x0001309b0c811a8e, 0x000b345f714ca71d, 0x00000000000d4eb9}, {0x000f50441ed062cb, 0x00091e0e5afdcc03, 0x0009d20438aad877, 0x0001e7b843343663, 0x000a0eed1116670e, 0x0009bbd50c8c38f9, 0x00095af914fae261, 0x0000000000051c19}}, + }, + { + /* digit=57 [{1,2,3,..,}]*([2^228]*G) */ + {{0x0001b38ab493e121, 0x0005bde849cd1240, 0x000576b3d2c358dc, 0x0009e3dabe92fbab, 0x00043324900a3fbd, 0x00020904e785414d, 0x000ba8daead1abde, 0x00000000000aa5f1}, {0x0002d0438c4bd099, 0x0002fd60a4f2ce26, 0x000593174efc1656, 0x000c78934efa243c, 0x000f216a8d8c163d, 0x00001617b3067dcc, 0x00051e116b6534a9, 0x00000000000bbabe}}, + {{0x0004b6e85f0076cc, 0x000c1929454f6549, 0x000021b9b8ac3fe0, 0x000a7c5ee25c0b0a, 0x000f2e752295f5b0, 0x000acac687d3372f, 0x000e3cd6dadc7d6e, 0x00000000000a96a8}, {0x0006465e062c14dc, 0x00030ea831db66b4, 0x0000548165c8c6c9, 0x00017e572e3c00c5, 0x000d2a5fb6ba5ff8, 0x000392476b022e25, 0x0005a0b611c5bcbb, 0x0000000000019048}}, + {{0x0000dddcc280d252, 0x000d5efda99d90b9, 0x0002988f9d0202d2, 0x0006cd1ad14ac705, 0x00031f4138808b9e, 0x000dd7fb91239ee3, 0x000b12d98e93d993, 0x00000000000894fc}, {0x000d9440883321ae, 0x000d433a92019c9f, 0x000ee20fd3f674ff, 0x00051280d0a320b4, 0x000b4b607b538450, 0x000228c2ec20551d, 0x00025c6e63c766ea, 0x00000000000ac48f}}, + {{0x000ea4ad3f5b0bfd, 0x000140372678d84b, 0x0008ab3dd6009aeb, 0x000bca4b79594c43, 0x000baf3b75cfebae, 0x0001e09c6e587850, 0x0004cd534183ac2c, 0x00000000000c0820}, {0x00012c542116a023, 0x000a7dac2cf06c18, 0x000f5e79e9f15f10, 0x00009f490b0f6c27, 0x0006c2c62207f6f5, 0x000ff18873ffc3cd, 0x000c6fbb21eb1132, 0x00000000000e62cc}}, + {{0x000a11bec64a35cd, 0x0004f1ca74a30c77, 0x000de3a654c55d5a, 0x00049038d6b4b005, 0x00002f7906ee3709, 0x000452bbb12ba86e, 0x000039aa76f77adc, 0x00000000000f9837}, {0x0000782bfd430ed7, 0x0001841fe306f87d, 0x000ce68ff3cdd73a, 0x00024ccaa7d44b2c, 0x0005d86900f9cffa, 0x0003ecfa022bae39, 0x000980e7a138782e, 0x0000000000086d28}}, + {{0x000489915b0c1e42, 0x0000991b8b685879, 0x0005ba3b38e17597, 0x000d69ea7d9931a2, 0x000c7632a26bcdb0, 0x000ba170f3c8441d, 0x0008adf11a365c62, 0x0000000000034e74}, {0x000d3f6d2f87f536, 0x0009d523ca2d7db2, 0x000b5fe1b40ff204, 0x000c7771d07308bd, 0x0007c291c2ef71af, 0x000b40d1773588d7, 0x00015629baa3b0aa, 0x00000000000eea9f}}, + {{0x000a95a8a249bd36, 0x000f90ae9143a26d, 0x000709bd167b8510, 0x000f7a7f3b4b882d, 0x000de22d9b9923df, 0x0004f02b1b178e73, 0x000c2fa83861afaa, 0x00000000000b9064}, {0x000de7d4573c6d34, 0x00022142eb294574, 0x0006f55c30205aad, 0x000717fe649a8b70, 0x000cad53c9bbd589, 0x000ecd8f7a925c47, 0x000142c339b11a09, 0x000000000001bbf1}}, + {{0x000abd60f6eb49c8, 0x0008c406a7e201fa, 0x0007246dc14c8322, 0x0002eff020748efc, 0x000af39b58dbd440, 0x0008cfb047827442, 0x00078f77e3f2768d, 0x00000000000e45a9}, {0x000ab42dc779cb3d, 0x000229db0829881a, 0x0005eb7284cde06b, 0x000ce47b82775f69, 0x000f63910016e434, 0x00047792fe84995e, 0x000eb9a35e8b971e, 0x000000000007c6aa}}, + }, + { + /* digit=58 [{1,2,3,..,}]*([2^232]*G) */ + {{0x00097b7667d86ea7, 0x0001b1fa064cf475, 0x00026db64fb0c148, 0x00002a1fa9d94539, 0x000bdc6bd7eada81, 0x0002f6044786aeca, 0x000208caf91e3bca, 0x000000000008573f}, {0x00036746e95246de, 0x0006cd309fce8dbb, 0x0001300c9068d932, 0x0001ae0f3d530575, 0x00000d1fd61e5779, 0x0005ebfa626b053f, 0x00097991c962c004, 0x00000000000076ed}}, + {{0x000013c3d6e02921, 0x000c449f2499410e, 0x000e2ab53501cdc4, 0x0009103d5e91bc0f, 0x000bcb404f68897b, 0x000f7fc0263db1ef, 0x0000af70efd9d842, 0x00000000000c6a23}, {0x000a0390300406c6, 0x000308d5b199ee1a, 0x0009868ea4fe37e1, 0x0003d34504dd889f, 0x0001f823686fde58, 0x000fc73dc0375600, 0x000f42f19ab86f95, 0x0000000000093f12}}, + {{0x000b8a18e1e24b49, 0x000143f896ca9186, 0x000d7ce3f5b4c07a, 0x0001632600e4e2b2, 0x000f69e702d5d074, 0x000e0df2b87c7db5, 0x000fba1f5a3b8053, 0x00000000000f443d}, {0x0005af3bc7c98ae2, 0x000deeb90e22f972, 0x00070953899b58fe, 0x0008299a5aa335b5, 0x000d4197b32afb1e, 0x00055918ed78504c, 0x000c720e7a79cc67, 0x00000000000883b1}}, + {{0x0004af5925d66db3, 0x0008dbf66baa58e7, 0x0001c386a0ca25fc, 0x00032abeaaa466ce, 0x0007e5f2733b80bc, 0x000531afa605b789, 0x000369e9e7e3a1a2, 0x000000000003deb8}, {0x000174c1d570e84f, 0x0008d36212ea2dd8, 0x0008479c4475fe18, 0x0004b31444e9ea02, 0x000169530c1befa5, 0x00079bdd19c2229a, 0x000cc368feb9854b, 0x000000000008b984}}, + {{0x000682b315cae64a, 0x000981df8d98c41e, 0x0009fabd7bca288f, 0x00064f91703e1431, 0x000e9de0ab4ca54d, 0x000dc4e0fa12198b, 0x00091f160e06241d, 0x0000000000066958}, {0x000b5c1e9cafc463, 0x0006f808565e66f7, 0x000a9467f76914c8, 0x000cd934bac17690, 0x000ca5be965f6682, 0x000a38e9062e7ac2, 0x00016ed33f6f8ad7, 0x000000000005b8b5}}, + {{0x000509d8741fea0a, 0x000c1f041e421362, 0x000c0d8899228fbc, 0x00093751128ed62b, 0x000acec6eae64fea, 0x000a65dae041a1c1, 0x0008e81f32359415, 0x000000000000154e}, {0x000a9eb331e84371, 0x000ec309e9f286a4, 0x000765936bc21528, 0x0004dd5692420c27, 0x000ec4fa1a6a7bb5, 0x000779e77193a41a, 0x000b8c35f5f3b43d, 0x00000000000046eb}}, + {{0x000b5769d7b9ec0d, 0x000aa3a5a366dc99, 0x0005d073ce2a60d9, 0x000e4aafe5355bee, 0x0003ced676663e16, 0x0003440036d8bac0, 0x00020c403eb33ed9, 0x00000000000333ab}, {0x00094bfc36e2db30, 0x000739fce19869f6, 0x000435b17be8c513, 0x0009611921a58e5d, 0x000620d5c61a8e68, 0x000c81b4e8f5f115, 0x000779b17f612fad, 0x00000000000e562f}}, + {{0x000d75f385d1b0f1, 0x000f0d6a4d25bfe8, 0x0007b705bfa0d54e, 0x00059731cdedfc0f, 0x000603d6502f9420, 0x0005ce8c80c4e385, 0x0000b7981a4fc5e1, 0x000000000007aca3}, {0x000ea22cf2bcfc17, 0x0009ef2037ef684f, 0x0007e5010cdb37dd, 0x000a23c71f3e4e4b, 0x0009f47b504b9c98, 0x0003233aaa73c8b8, 0x000f68b9e33f5402, 0x00000000000f92c9}}, + }, + { + /* digit=59 [{1,2,3,..,}]*([2^236]*G) */ + {{0x000a9e3a73909533, 0x00090ba03ba3b07a, 0x00090d7a3c9c5a5a, 0x0008cfe4f0f60b35, 0x000e6fcccd96f96b, 0x0009dd17ab908d77, 0x0000487208ef7de7, 0x000000000003ec3d}, {0x0006af6a704d4f0e, 0x000d09c5ad2d9a11, 0x000e77d5943d9764, 0x0009449470eb938b, 0x000bee7d772fac99, 0x000b7ad09faaf27f, 0x0000a9fbe402abd0, 0x0000000000057db0}}, + {{0x000ca62ea2a4a457, 0x0001b10c082a59d1, 0x000bdd4313beafb9, 0x000935b4cb291a7f, 0x000313e9ce08785d, 0x000f6f1c4fc2ae15, 0x00024c3146fabf4d, 0x00000000000c87dd}, {0x000f74ecc24bd4cf, 0x0000385fdd8765b9, 0x000dc418405d512e, 0x00005013e7e0297e, 0x000fb92df904c81d, 0x0005ddccbb56ddd1, 0x000f1d4612df9f29, 0x000000000000e27c}}, + {{0x0002069dae7548ac, 0x0002986d9b05f69f, 0x000025ad33463063, 0x0008e7c27d9d64d3, 0x000aba04e6ad9b6e, 0x0008abbbe79bd66b, 0x000d0477e4d0b082, 0x00000000000cc540}, {0x000bdbdb8d90e2e4, 0x00067f5d8a46ef90, 0x00078bfd47c637af, 0x000b852563fe6b52, 0x000997cdd04fb93b, 0x0007de47d06bb3ae, 0x00061c07f011d48b, 0x00000000000de78f}}, + {{0x000eb7904785958b, 0x0007d7830460f8a0, 0x000cf49e72cbbaa0, 0x000e2aa307d9c790, 0x000b5aad8b6c73be, 0x000848db51b02af1, 0x0004765e31882703, 0x00000000000f230f}, {0x000b79128735694b, 0x000bd4ea6535cc84, 0x00008e33135971e8, 0x0007b332fd33cac2, 0x0001c566914f4c19, 0x000952d3b24c7b0b, 0x0005f2956ce3c371, 0x00000000000fabae}}, + {{0x0004121555388dc8, 0x0008b8a95e5c1a8a, 0x000cd5dbd7b0133e, 0x000df6acda40bc0b, 0x00058234471d1859, 0x0003c0100f9097aa, 0x00067caddc0c9b78, 0x00000000000feb70}, {0x000ce59ade26052d, 0x000a6e3805fd0a27, 0x000626ac8acaae6d, 0x00099921943a0a1d, 0x00091dfe627ea459, 0x00006515fb47f061, 0x00073e313d4f09da, 0x000000000001f54a}}, + {{0x000f6dd7137bd615, 0x0007e0db87bc3c53, 0x0002eda89127238c, 0x000e9c4a3fd2a60d, 0x0001c9f017e5ea81, 0x000c75768190c9c7, 0x000de621864180bc, 0x0000000000043dbc}, {0x000fb5dd8276da18, 0x000de5b090c70dac, 0x000cd9057894e345, 0x000d268a918bf24b, 0x0008ae204f49fef3, 0x000d7c356e10c52c, 0x000a17f4be898d86, 0x000000000002fdb5}}, + {{0x0009bfc4aad5cc44, 0x000a20079c69c96d, 0x0008a5713957941d, 0x00086660139685a2, 0x0004946fbeddb8d1, 0x0001aace408590ca, 0x0001b67fecd9b964, 0x000000000002936a}, {0x000267114a49f247, 0x00065925b6235aee, 0x00055e3538cd2015, 0x000663d8c6fb34ac, 0x000c2fc1c10d971e, 0x00042b822543146d, 0x00024d6e4053c706, 0x00000000000492e5}}, + {{0x000d356fb82e9b9f, 0x000beca9872e0a14, 0x000f54683a031c30, 0x0007cb84e05b2811, 0x0006fa234d4596b1, 0x00035a7d89798714, 0x000384ba78949ebb, 0x000000000006fc59}, {0x0001361f78e02fa8, 0x00081a303e549f81, 0x00064be08532a2fa, 0x0002de8ee7220467, 0x000563e27035e57e, 0x000d2fe6fa05c106, 0x000aadaa38e86602, 0x00000000000ee2f6}}, + }, + { + /* digit=60 [{1,2,3,..,}]*([2^240]*G) */ + {{0x00044971cf281b0a, 0x00052c0426b768f1, 0x000ef3f4445c186e, 0x00012e3172c0d3e8, 0x0006ee75473731d3, 0x000a7ee615f49fde, 0x0005fb895530f06d, 0x00000000000e8b3a}, {0x0006345afdc270e9, 0x00019fd14973443f, 0x000f6896912e434e, 0x000ae07653908d03, 0x0006ba02a278e2ba, 0x00021b8f8c3d0143, 0x000297a0d0222e7b, 0x00000000000d7ec1}}, + {{0x000653659b1a252c, 0x000514f120aa7478, 0x000c72dfe03d7757, 0x000ac5ecfe5f7a92, 0x0009bbf3cec6c96b, 0x000361cd5d4e73d5, 0x00044ced8d233560, 0x00000000000562f4}, {0x00045d3e2b7ac684, 0x00022bd37d3cf9b9, 0x000cb601f2d0a968, 0x000535a3d2f41ee1, 0x000ee8b1743e7e35, 0x0005a27650353b52, 0x0008b831d89dfd7b, 0x000000000008d9ea}}, + {{0x000718fb55d90569, 0x000b306a67bd2493, 0x0001471031374c3f, 0x0005d5197bc62d32, 0x000924c51874ee0b, 0x000a1a0d552b1703, 0x0000acfed1f42382, 0x00000000000db627}, {0x0006189cf7edbc97, 0x0006c36be4a9b658, 0x000680236e8f5c91, 0x00036d3b8f8074cb, 0x0009718545c6c174, 0x000757d213bb4d39, 0x0003668e1ea3555c, 0x000000000008c474}}, + {{0x00063be615177c6f, 0x0002773457010af5, 0x0001ce08b2f26f1c, 0x0000e8c9c25fe5be, 0x000182dd0485705b, 0x000ac280540f36ea, 0x000b923d55bc8527, 0x00000000000ad921}, {0x000b6da293461f09, 0x0009551586cd4c76, 0x00086171a05efa67, 0x000605e84f0abcb8, 0x0003772dd0dabb4e, 0x0004e1d41354ef8e, 0x0004917f1a8f795e, 0x00000000000de5d8}}, + {{0x000beb4ebddc46f4, 0x00073ec72c64fb0c, 0x0005bac2d9d9096a, 0x00022001819efb1b, 0x00068cdde8703c5e, 0x000a87aeedf5ab6d, 0x000f1975a44e9d92, 0x00000000000bcf77}, {0x0009407ed3c226cf, 0x0005e8191efbc92d, 0x00064a74c9c1339d, 0x000e58265cf242d2, 0x000180b1d17be62b, 0x000de59a9ae99a3b, 0x000ce248cbb44692, 0x000000000002dcb3}}, + {{0x000a48783de6cfb4, 0x0006bf3899558552, 0x0009d51bfff43e77, 0x0004fd32df8d1a75, 0x000376d3fbbf0b1c, 0x000fd52bcf16bcc2, 0x0001f0d5888916f4, 0x00000000000d5cde}, {0x000f03d1ac917a2c, 0x000ae764ffffd280, 0x000af8be538ef59b, 0x0004762ccd57b860, 0x00032935106234f6, 0x000c642f32233a4c, 0x000f34df076095d9, 0x0000000000059f0d}}, + {{0x00010c66eff8425e, 0x000379580cdfaafe, 0x000d1f7ccb185b5d, 0x0005f77c327f3e8d, 0x000c35353c5f5d3d, 0x000258eb105d5339, 0x000f79c56fb5fe5c, 0x00000000000edce1}, {0x0005bd6f7b6e122d, 0x0007cab7aa141541, 0x0008987b379beb7f, 0x0001491458d9e533, 0x000caa7f0f31e124, 0x000fda7abdd2448c, 0x000a4dec58d3c7f0, 0x00000000000c91bb}}, + {{0x0002f037fabc6138, 0x000b73bd258d77ca, 0x0006aa4d0ec1d1f3, 0x0002512e3f966a14, 0x0007709d0c2d5b43, 0x000658259338bfca, 0x000023d142cc1049, 0x00000000000636b8}, {0x0007458ca547abc1, 0x000cda9ef9400a80, 0x000ad926836a9402, 0x00063c55cb644887, 0x00011cea475bfd2f, 0x00067a25fbae949b, 0x000a6aa45446031e, 0x00000000000dc6a7}}, + }, + { + /* digit=61 [{1,2,3,..,}]*([2^244]*G) */ + {{0x00085fa16820f665, 0x0009fd699ea2d24e, 0x0004f1772a862ed3, 0x0004bad66a8b35ba, 0x00024233fccb4660, 0x000d3cf0c0c779b6, 0x0007af578458acbf, 0x0000000000096bf5}, {0x0008a325d9d68d07, 0x00045a9724244e54, 0x0005b4b1e20150f9, 0x000a5b8c6be8c159, 0x000c774d62c40980, 0x000bde24b6230e3e, 0x000204da1467d84f, 0x00000000000cc862}}, + {{0x000b4d1a75edabf3, 0x0007567c51633fd8, 0x00020dc66cdc521c, 0x000c8dc9ee450d03, 0x0008b41a3e2f77fc, 0x000bf06898dd2b31, 0x000464df6a935e93, 0x00000000000a92e5}, {0x0001e3ee6beb3c9c, 0x000e449afcd9ef46, 0x00031a4b44405106, 0x0008ad2c7ea7810a, 0x000e550822b2cdbd, 0x000606adcfe61571, 0x000110744a4f9386, 0x00000000000d9d4e}}, + {{0x00006ff4ac15d783, 0x0007ef1084276ccf, 0x0009d3b1212d957e, 0x000dcf5bfb4283a4, 0x000db74017eb3752, 0x00078fcf8f6b2214, 0x00039afc1cdf7245, 0x0000000000012265}, {0x000c5dc1b7858cd2, 0x000cdcc0796680d4, 0x000e05b222bc5975, 0x0003a9a504cf7d65, 0x0003c93ed5932027, 0x000303f1b0c7b7e5, 0x0006a4aaf9c36866, 0x00000000000cb013}}, + {{0x000bfa5cdf24bf96, 0x000411fef389c07d, 0x00022753fd218088, 0x0000a1437f04a344, 0x0009d0169369bd77, 0x000377cc3c7438e2, 0x000a4f6b265742e2, 0x00000000000c369f}, {0x000bb384dc3d9a84, 0x00060dfdbcf462e9, 0x000d3f52e65bb342, 0x000a0b82a9c483da, 0x00042de432285574, 0x000d1fabe0563fe9, 0x00096658ca0e8aea, 0x0000000000066023}}, + {{0x000afbbacd3ede36, 0x00007746325d090f, 0x00094f8b4a38ccef, 0x0001c2866c3931a7, 0x000a783a73e7d9f2, 0x000d82d13c12880e, 0x00010e382e1ce28b, 0x00000000000ac023}, {0x000fda6b09a40144, 0x000b69802d06233d, 0x000de8140422422b, 0x000367efd4cf75a0, 0x0000e8f2f6ed38b4, 0x000e72ff4765cdee, 0x00070ae0b4d72b35, 0x00000000000947d4}}, + {{0x000a35bb9d72eb2a, 0x000c5383bda07268, 0x00038c9d09f99c2f, 0x000717d369f39c03, 0x00011a5a39006f3c, 0x000ec6c2b1bb593d, 0x000202d0f07ecc2a, 0x000000000004240b}, {0x00083c5449860db8, 0x0001935342f6c7b8, 0x0009a1541ab519cd, 0x000eb09ccb6a888b, 0x000785aa42c5fcd6, 0x0004e5895abb7a6f, 0x000582952f8824aa, 0x000000000005c406}}, + {{0x0001d7b0f8433a5d, 0x0004359d6e052cda, 0x000fea341e325461, 0x000d07d7907cc890, 0x000dc4ce5d800459, 0x00004f40267d720d, 0x0002a83262028eed, 0x00000000000d7881}, {0x00055f59d844fe29, 0x000fcf735fd6cf7f, 0x0001c0c0179cc733, 0x00006e8e19a43f29, 0x000f19592b76328c, 0x000b836f7b97ef65, 0x000a9981325f3db8, 0x00000000000d6e6c}}, + {{0x000a67318a4b19fa, 0x000a63667a71faf0, 0x0007be6235b29837, 0x000535efc62f7919, 0x000b389faf7fe084, 0x00071b7f65bc1652, 0x00070340cf51683a, 0x00000000000d4f39}, {0x0002b576e30c499d, 0x00099823e7549478, 0x00032769bfa306a4, 0x000ee027225b31ad, 0x0006fc282f165639, 0x0009f61ae7533bc8, 0x000803710009d2c6, 0x00000000000bf65e}}, + }, + { + /* digit=62 [{1,2,3,..,}]*([2^248]*G) */ + {{0x0006c5f4c042c4cd, 0x0001ceb29e44bf59, 0x0004c11cc5ce653f, 0x00004943d2bf689a, 0x000a47428dd2d09c, 0x000aafac83ab7799, 0x0006e0dc558d6be9, 0x0000000000087f9f}, {0x00056bc34f65dad0, 0x000c793842bcd3a9, 0x000241a2ffbfced6, 0x00052687e6d47b5b, 0x000a4c37eeee1645, 0x000c412ceab304b7, 0x0002c8dbb3d4e13f, 0x00000000000a726a}}, + {{0x00059e97675084b3, 0x0008d79d88dffddc, 0x00002dc16c994a53, 0x000000fce7d606f0, 0x000e2fa27fd3b528, 0x0009436afc773557, 0x0004c755b53dd3e1, 0x00000000000e10b6}, {0x00077a15a41de95f, 0x000bfe5832664b2b, 0x000d15e689d49c17, 0x000bf537af3e3dd9, 0x000cf47d298c7b93, 0x00012136994fafa2, 0x000ff694c2ff9a21, 0x0000000000033468}}, + {{0x0001b740495480b0, 0x0003f91e8c991baf, 0x000b4c043871430f, 0x0003f6dd095f5b94, 0x000cddf3cad27c5e, 0x00057aacfed7522f, 0x000f5180bb87056c, 0x000000000000cc5f}, {0x0006cac5a2f35aa0, 0x000e0964def7e61e, 0x000e006a84529a7b, 0x000192584de66a22, 0x000e075f07c5cc75, 0x000eade939acaf7f, 0x00058f6505c2f81e, 0x000000000000e3cf}}, + {{0x0001fb7f00850a1a, 0x0001dbe45d81a1aa, 0x0000ee7897985bd0, 0x000a516b078ea895, 0x0001b446476463c5, 0x0001e52329f3efe4, 0x00022084580e2410, 0x00000000000c8ae8}, {0x000539dde4d08a27, 0x00077bff4077d088, 0x000c1e715cd7b849, 0x000eef207e1c03eb, 0x00096e654d584df4, 0x0006f15964ab3d03, 0x000cd5b20056cd08, 0x000000000008acd7}}, + {{0x0008f4a5a8f26e12, 0x000538caa623c979, 0x000e7d0ec3691999, 0x000f856ee285bfe4, 0x0006d0674ecd089a, 0x0006f661277b461f, 0x0009f8baa9d9b38d, 0x0000000000059066}, {0x000460fe25d6fd2a, 0x000d2b164340c38e, 0x0003981c9e27c186, 0x0003b9176e4346f2, 0x00017caad5fc73c0, 0x00087803d6a678eb, 0x000a94103ff0790a, 0x00000000000f7430}}, + {{0x000dd3174fcc39a0, 0x00094517075af0fd, 0x000fd65c623f7ba2, 0x000e9493b86f6398, 0x00017f296bf4320c, 0x0001082765115657, 0x0009000919607a96, 0x000000000002f035}, {0x0004b29394d28cac, 0x0008f5d13de7c5ae, 0x000ea9b2719ceec5, 0x0008089c0f58697a, 0x00030ca7ca20f1b2, 0x0001e1be52adcd1a, 0x000ba096c07f42c2, 0x00000000000baa0a}}, + {{0x000dc0265a01c54c, 0x000233027c169336, 0x0003342d9c6b202a, 0x0006cd31b8b0179e, 0x000a6dd5a4a7e6eb, 0x000c82f110d2d27e, 0x00002241682c0007, 0x0000000000081075}, {0x000f1169b3430f67, 0x00019f3903f514b2, 0x00091dfa21d2d176, 0x0005eed470bd3b32, 0x0007e85a62931b62, 0x0005ad640a46398a, 0x0003a58ff6ef8c80, 0x0000000000095bfa}}, + {{0x0006e424a5742fd1, 0x0003a8cd6c9f7239, 0x000180484ef81e04, 0x000b0f589b8ad2c9, 0x00070d9c999d9c0d, 0x000f84ab4692a8db, 0x00006ca407fd03c9, 0x00000000000cc9a9}, {0x000b5d757bfbcaf2, 0x000014813a7654ce, 0x0008615f305ee56c, 0x000f2934fa0a23f1, 0x0007cb1f8d7aca6b, 0x000d10c531dfa3af, 0x000c1328036f5498, 0x000000000000e012}}, + }, + { + /* digit=63 [{1,2,3,..,}]*([2^252]*G) */ + {{0x00034e0d2aae29e9, 0x00091a53f1a10241, 0x0004dd23936a5886, 0x000ed8532976d137, 0x00065ee692d130ef, 0x0009e7cc1cf5ada1, 0x0004723ceda69d25, 0x000000000009baab}, {0x00095b8627836d36, 0x000237ee5baef4bf, 0x000e9b1caaa769fb, 0x0008ddacfdaff633, 0x0009cec076939e5c, 0x000fb509d575c8db, 0x0006979afc8ae0fd, 0x0000000000085651}}, + {{0x0000da11d13ab853, 0x00042a7342f9446b, 0x00039f5ef3dbc527, 0x0008bf07471c3856, 0x000130827f3450e4, 0x000779c23729e5ab, 0x000d5817199191ea, 0x000000000009fa9f}, {0x00077a9b9dc5fca3, 0x000827d5799369d5, 0x0003bee46a6f5cc0, 0x0007d51e85417260, 0x000dec720355253f, 0x000a16268107a793, 0x00031b1c14d0566a, 0x000000000008bbb2}}, + {{0x00016132445f3e21, 0x0009ef5689c5dce5, 0x0006397102e2e73d, 0x00079d012eaa5340, 0x0006d9271e941af8, 0x000e63c34dba775e, 0x00024b60f8507310, 0x00000000000a686a}, {0x0006624c82f5c532, 0x000dded5ca8f992c, 0x000b2edebcb9407c, 0x00039426d90a7d51, 0x000bccd37e76e2ee, 0x000412e0fe5b3e4c, 0x0000489013bd08f1, 0x00000000000ce999}}, + {{0x00009cf56d1d974c, 0x0005561d0e01b86e, 0x00046be97f98120d, 0x000e224b362902dd, 0x00029e0a5d16d4a4, 0x000e580e945923c1, 0x0009544fc2bdd495, 0x00000000000a8c3d}, {0x0004daa7a4671003, 0x000a1aeff11352c5, 0x0005a1c5b6c0120c, 0x0007d3eab8f9f31a, 0x00066d566c158090, 0x0002e6fa7af2c121, 0x00003a0082daba95, 0x000000000002df9e}}, + {{0x000fc79dfc540dc4, 0x0004091b379c535c, 0x00090bc691de574f, 0x0004208176b3b828, 0x0008aaba5cd3d0f4, 0x000794f9fd18c211, 0x0008944aed5c9770, 0x00000000000f4c33}, {0x000946afeb1a61f9, 0x000b9b8e67989163, 0x0000523ed92edf12, 0x000ef39ab5573985, 0x0004b71031051b7e, 0x000ac89e4175e393, 0x000db8943abf4a82, 0x0000000000057ffc}}, + {{0x00066f02c7c0f325, 0x000f899c2b4cc9e8, 0x000f2b3e2c2a45ff, 0x000b66b5a352b7b1, 0x00043ec757ed067b, 0x000d36adc3c7d6fc, 0x0003a42f69291cb9, 0x000000000007c914}, {0x0004d853fbc3268f, 0x00006768c3c3f0a6, 0x000dd7feada4c10c, 0x0004b025299ea1bb, 0x00091a2d4005d86e, 0x00017fa60be46b7e, 0x000fbeaf865a1693, 0x00000000000cdce2}}, + {{0x000297083b5951f8, 0x0002b66fcba529da, 0x000a6f9544c17490, 0x000b97241b4305fd, 0x000e25b6af89a371, 0x0005f9e8cb2d858c, 0x000ef8bab07d5327, 0x00000000000d525b}, {0x00073848e93e22c2, 0x00084ebf79e3bb83, 0x0007a079aa9da5d4, 0x0008b66cba1a65a3, 0x00038b1eb8b67dbd, 0x000a6436a88ea401, 0x000e33210ac1b38f, 0x000000000003df40}}, + {{0x0000b48bcae58bd8, 0x000c45f79f0de54f, 0x000db929ac4cc6a4, 0x000a68e11571c5c9, 0x000e2474faf7d631, 0x0002a924a6d072b4, 0x000d7a5e043a6d86, 0x00000000000b0fc8}, {0x000fb0fbc0056e2d, 0x0008bf54bb7f2f12, 0x00058e2455c41895, 0x0009f4c5909ec050, 0x0005abd164608145, 0x000b1c69ed28cda2, 0x0006f4bb676d018d, 0x00000000000ac503}}, + }, + { + /* digit=64 [{1,2,3,..,}]*([2^256]*G) */ + {{0x0005d534448865a4, 0x00079dbe04c30004, 0x000de820bf917110, 0x000b54670911457d, 0x000b3f7a1757dbf8, 0x0007bd62c9e683b5, 0x00097e7b89a08a9c, 0x000000000000b3fc}, {0x000ba720a0047774, 0x000980ac9abfb9ba, 0x00007bd7b6be79d8, 0x000c335d9deed984, 0x000f72603e080aa6, 0x000783bb2e270580, 0x0009ae70857a946c, 0x00000000000caa92}}, + {{0x00008763d38fe0f6, 0x00001f071c986bc1, 0x000413c627ede21a, 0x000b12a61483bc2d, 0x00001caf6dd6845e, 0x000c21b9217471d8, 0x00036d7b603616dd, 0x00000000000b9925}, {0x000a996617818c3e, 0x0007f433f065211f, 0x000b56653ac9464b, 0x0007386a9adf49b1, 0x00092cb2944fdf61, 0x000d9c0764bfeb39, 0x000576bf288427b3, 0x00000000000965b4}}, + {{0x000b333ccbe322d0, 0x000fbce23a199d59, 0x000074dc302e3830, 0x00000121d15a0063, 0x0005f4355a1fc720, 0x0007f780715fde73, 0x0006913849761f60, 0x0000000000018204}, {0x00074bfa03274297, 0x0002575756e4ea63, 0x0009809c9584a1de, 0x00032763d4ce3dc3, 0x000ef1d66e006312, 0x0008829e6a769d2f, 0x0006ef8624ddbac2, 0x00000000000d2df0}}, + {{0x000f606b2db32f32, 0x000b59ec11596f9e, 0x0004a5f37de5fafc, 0x00094e131fca111c, 0x000896076f45acf7, 0x000732588438b917, 0x0000daad71035b51, 0x00000000000a5d91}, {0x000d85cad07f3bba, 0x000a7efaad0e82d9, 0x000f829c6ffe7ff7, 0x0002426474ce3273, 0x000a2aa270da9940, 0x0008fa6ebd53b687, 0x00041196c8bb78d7, 0x000000000006e699}}, + {{0x00044c83de3d28f8, 0x0008b2dfc39e611a, 0x00099024ec940ff4, 0x0002123313aa4788, 0x000b9c6acbd11cf1, 0x000d54177785b025, 0x0001eab4aeb5b8e4, 0x00000000000d943c}, {0x00041945f056ffdc, 0x000097892db846ab, 0x0000f6f8e04921ff, 0x00013c61cbd3232b, 0x000700b6c34ebdee, 0x0003de32b873e0a7, 0x000302b279505ae2, 0x00000000000c5a03}}, + {{0x000395d621a49e0a, 0x000c7430b669fc05, 0x00093c4a448f25c5, 0x000730c4c33493e3, 0x000fca00ed3901ad, 0x0004a55168c882c1, 0x00027dab2e9c89d2, 0x00000000000f5d03}, {0x00020231a1107ea0, 0x000f946488bd7b79, 0x000d5a9d2b183f55, 0x0000e90aecfac7d9, 0x000fac6a9e8cf9f6, 0x0008bcda84afd1f5, 0x00099857a20bf8c9, 0x000000000008b46b}}, + {{0x0005f4b3119ad50d, 0x0006c1f2f6c1efc1, 0x000be8ee71be11e0, 0x000e4a6569c090bd, 0x000adb3986d020dc, 0x000f553eae4f7401, 0x000bff1389799485, 0x0000000000009026}, {0x0003665df6023a4c, 0x000b388067aa6ec6, 0x00069e9d017576cb, 0x0005019459bf26a1, 0x00058b6e76f68416, 0x0000d2434ec125bd, 0x0000b0d636f9321f, 0x000000000008e05e}}, + {{0x00021074c1c07346, 0x00068fe1f11ac76d, 0x000a3e93fcce998e, 0x000015a3c5babf98, 0x000d5929ea0a99d0, 0x000fb7b7e7e795b4, 0x0002e8c9cf68331d, 0x00000000000a6499}, {0x000716aaedb25dc3, 0x0000d0b7e0dd7aad, 0x00064fd90a09f648, 0x0003cf034f02b979, 0x000a5662f0c86402, 0x000058ccaf7dd410, 0x0001eda3bb6088a1, 0x000000000004e780}}, + }, + { + /* digit=65 [{1,2,3,..,}]*([2^260]*G) */ + {{0x0006b5199cfd1ff1, 0x0009d140a0f9f409, 0x0004971fd020b4cb, 0x0007c2304a1f742e, 0x0001195ba34e78ff, 0x0007f78b4c0568f5, 0x000a53e97183603b, 0x00000000000f9efa}, {0x0009e6e1cb2c1b4d, 0x000bae924d2c4efd, 0x0004b415d4c5ceca, 0x000e73f6ee37e106, 0x000a5e5a1dde4b12, 0x000cd64161836fdf, 0x0004d87f1b92259d, 0x0000000000067754}}, + {{0x000befa999003a02, 0x0000e279fd119411, 0x000606c204c4310e, 0x0007da4da44105e5, 0x000a28223fe1d8f5, 0x0006f2d2eb1814b7, 0x000e06cf2fd241e0, 0x0000000000001dfd}, {0x0001563b8cdc2810, 0x000a4876a31af711, 0x000bd72037bc4e78, 0x000d608493a6a0aa, 0x0008a88c03e75117, 0x000916897dcec808, 0x000c57eae1d352ea, 0x000000000006e8b2}}, + {{0x0001a9c4fdcf93d1, 0x000650254486c9e5, 0x0006796f28c8ff02, 0x00058ba000f54926, 0x000934009fb6fb58, 0x0002bde301315bdd, 0x000358b18a8e0ac4, 0x00000000000f1070}, {0x000b8de4d767059a, 0x0004ebeb1db7458b, 0x000305d015a22913, 0x00014d4e4122b217, 0x0002aabccc7b1522, 0x000d07571d3e673f, 0x000f1794c50f64ae, 0x00000000000e66b4}}, + {{0x0004bef0d3847d2e, 0x000aa09f8bb05816, 0x000388d5b381065f, 0x000c7b6076e13ec8, 0x00035d5ac07f26eb, 0x000ab69e6bda0b55, 0x0001fabcb8132248, 0x000000000001c0f2}, {0x0006ceb771ee0889, 0x0007b7a466528564, 0x000e55b024527048, 0x00011864c1d7cb8d, 0x000f2d08130185dd, 0x0005ea0f0096f849, 0x0009b2b4f503dd8a, 0x00000000000d1bf6}}, + {{0x000f0c6218b7c4e9, 0x0008540336b12c41, 0x000f74c446fc6c56, 0x000048d9c841f0d0, 0x00051d617f50c337, 0x00017d3794ce6d02, 0x00024300fef21981, 0x00000000000f95be}, {0x000f7d33fe9f8bcc, 0x000ec98de119d3a3, 0x000e778f8a8c16b8, 0x0005b720f9678bed, 0x000d334ace309412, 0x000e86e04fc5b57c, 0x00003909486527b7, 0x000000000006e552}}, + {{0x0001aa0f2e0127d7, 0x0007b4ab7a22bd4a, 0x00047f417a4172fd, 0x0009f95078de336c, 0x0006f786924520f5, 0x000f1d96ffd28fa3, 0x000f0f1de42581cb, 0x00000000000366e1}, {0x000e183b180aaf06, 0x000febc65fa9d0a4, 0x000739e25cf57814, 0x0004f3a4a0822a93, 0x000bfd05a0aa0638, 0x0005ee3ce1c81332, 0x000d00bfb12361d9, 0x0000000000042016}}, + {{0x000f0b32c63695dc, 0x000143b75c45b10b, 0x00037d16d187f9f5, 0x000227df8e0a114c, 0x000e73ddba245450, 0x000f246455e69f1a, 0x0007412007b80e57, 0x000000000003d159}, {0x0007528fbc79a394, 0x000ffcbe54d2888b, 0x0004e47907e4e2fb, 0x00070594cc39f745, 0x00032b1b8da9e19f, 0x000f68d2680f00ab, 0x000829b765aaf973, 0x00000000000e993f}}, + {{0x0000b5faa7527283, 0x000530a159f61ee6, 0x0008e1f9dcf0213d, 0x000b8ee1661a2405, 0x000ec95c41b36d1a, 0x00051eb56cae7f40, 0x000250bc3d20407c, 0x00000000000e8754}, {0x000ae69a0a837ff0, 0x0000281561056151, 0x00032df2869a92d9, 0x000c1bf6af2a00cc, 0x00042d0a56c0abdb, 0x000c8959ee9a9425, 0x0002f34774a7b77b, 0x0000000000019cef}}, + }, + { + /* digit=66 [{1,2,3,..,}]*([2^264]*G) */ + {{0x00035e2ab65ec55c, 0x000b3114a25c78e3, 0x00036712a123ad50, 0x00068411e7bd7df9, 0x000ad6da54dbc49b, 0x0000da3215b0359f, 0x00087ea6e6e5f93f, 0x00000000000d640a}, {0x0003244eb630ddc0, 0x000f7c1a4f6cdf83, 0x0008137a92bebef0, 0x000eb8e3c0a631d4, 0x000db756445ff44c, 0x000c8880e0205b11, 0x0000d304844e845b, 0x00000000000b85e0}}, + {{0x0005c0fc3837219a, 0x000cee76894c3764, 0x000faaa07cdf021d, 0x000fcfbe55cd1e6b, 0x00023a7ad5b9566d, 0x00087a4ef5421a9f, 0x000423a005838a46, 0x0000000000023a2c}, {0x000326b6922fa665, 0x000ed4b780011f85, 0x00024bae2459585b, 0x00069e937ced8f3d, 0x000d8c1e1eaa2b5f, 0x00089cc4d306b621, 0x0007748acbbe71d3, 0x00000000000f4ab7}}, + {{0x000e8b5d217d418f, 0x0002ee557e7c707f, 0x000dffc8ed3b58d7, 0x000efa4b42b3ab4b, 0x000d8e53b32db9b0, 0x000b1bfbd9d71dc4, 0x000d3fe3a93e4e11, 0x000000000009901b}, {0x0009bf805b79f71c, 0x000b35f3a5304e02, 0x0007d4e3dff75554, 0x0007a7bef469e919, 0x000278f160dcf415, 0x0009189a9f03282f, 0x000f2197e4b7f4c8, 0x00000000000a967e}}, + {{0x00083fb3cef3edcd, 0x000642df6f242046, 0x00054e87770387bc, 0x000232b372bcc88c, 0x00086e428cc59e80, 0x000a1b76326ba13b, 0x0005f32526ef1f13, 0x00000000000dc97c}, {0x0007320a0cda3969, 0x000344954867fb10, 0x0004f1baa6436a30, 0x000fa69be143027a, 0x0003cf54f28b7e39, 0x00097c2da1232946, 0x000099cf0991dc75, 0x0000000000052e07}}, + {{0x0004ba256e3a80b8, 0x0005fbdfea74874f, 0x00090a65af244c4b, 0x0005675aaba39901, 0x0006a12be348d5a6, 0x00018ac5d2250648, 0x0006f9766dd428e8, 0x00000000000fff9b}, {0x000ff89f1b07248b, 0x000174b3b10f3ab0, 0x000ac70bef37c1ca, 0x00011ed5c9e36bef, 0x000364cdfcdd2a61, 0x000462f54a99a302, 0x000b5fdbfbbe7a59, 0x00000000000cc266}}, + {{0x00081f8725c117c2, 0x00037dc9daeefc8d, 0x0009cda216a5b4ef, 0x0002271ca53d53df, 0x00054d1aa50b206d, 0x000001e99b054633, 0x000aa452bca91088, 0x0000000000017fb7}, {0x0007b7c6cf80a17f, 0x0007afff3af9472e, 0x0007c0765e5ecd82, 0x00004be24753989d, 0x0006e90950c6aac0, 0x0008efe5b4a5de2b, 0x0009f9b46af0ab73, 0x00000000000db445}}, + {{0x000c5196b2aa222f, 0x000d15bdb6d3f8f0, 0x000389884e011601, 0x00008a96ddd9e23e, 0x0008467e7577ab50, 0x0007555edac1e974, 0x000d57e74e35b601, 0x000000000009d04f}, {0x00080785cb147efa, 0x000908585c6fc59b, 0x00035ae9e9b63afd, 0x000d1e80b684dd21, 0x0009edbaddcc2739, 0x000c57660e1ba788, 0x00089a464f42059d, 0x00000000000a7cf2}}, + {{0x0002dd131270b84a, 0x000dd412f64a3e09, 0x000b9c94f3cfd9dd, 0x000cdc2c2e964e0f, 0x000d0011cb01fbe6, 0x000228f23e9a3b1f, 0x0009a16c30762dcf, 0x00000000000be919}, {0x000e7d10046b4ea1, 0x000b4732711dfdf5, 0x0008160cd8dd88e3, 0x0008ba0c6eceba7a, 0x0001f3c3d31d8ee0, 0x000716948b171153, 0x000add65060b633c, 0x000000000002ff2c}}, + }, + { + /* digit=67 [{1,2,3,..,}]*([2^268]*G) */ + {{0x00000725d23401df, 0x000096f178dbeb92, 0x000498bead595449, 0x000b4b459b46611d, 0x0007c72b4a58a6e8, 0x0005985adafce826, 0x00073321142175a4, 0x00000000000e649d}, {0x000052db6dbc2445, 0x0003a6bf42fe0182, 0x000384cfd9aea017, 0x000a58acd0291983, 0x0009215492e1b0c8, 0x000b5a5f0a73ff32, 0x00049b895c545eb1, 0x000000000006fcaf}}, + {{0x000a5a0bc1e856f0, 0x000f28baef5de481, 0x000a8b075c84a181, 0x00058d754c8267b1, 0x0005ccf703932685, 0x0008ee021f924f79, 0x000a4be3763f30f6, 0x000000000005c01b}, {0x0006ee7749647d88, 0x0008acc01a3e928c, 0x000c22c3ac36bfb8, 0x000512e6c45e3401, 0x00084ef433f61ab3, 0x00021f5afa978fe4, 0x000a4023e2ea018e, 0x0000000000011524}}, + {{0x000ecc04426e192d, 0x000c692a7fbcd69c, 0x000df4111d9bb7a6, 0x000db2d02a8feb62, 0x0002728cecbe8e45, 0x000837662176c0cb, 0x00082c33fcfbb0d1, 0x00000000000d6f28}, {0x000d967a59df021f, 0x000bc75a0f344b04, 0x0001f4de7fbff391, 0x00090cefa0453b03, 0x000ff54c96fbf4ea, 0x000f77afc5108858, 0x0002fc86b46b5731, 0x000000000006bf7e}}, + {{0x000215c3f055a1c5, 0x0002fe1d42d93e03, 0x000c50c3e0aa63b9, 0x00098e783686967e, 0x000474a30dbf5f66, 0x000d20230bb5e159, 0x000f8bef86bb5bcf, 0x00000000000403b8}, {0x0001c2443b169c63, 0x000fbf249aac89ec, 0x000e2f941f78369d, 0x000960cefca9a90a, 0x00088f449c4b3b80, 0x000cfe09ef28e338, 0x000d260cdfc61bf0, 0x000000000008b22c}}, + {{0x0001733d4c0dd30d, 0x000af7013d596371, 0x00017f590b1fdd3f, 0x000898e35915f523, 0x00039fd967d4bba7, 0x00073558f9fbe5f1, 0x000bea0aba8344d1, 0x00000000000ffeb6}, {0x0009792191976aee, 0x0004e928f68cbbf7, 0x0007210e163722d8, 0x000c4e06abb0ac9a, 0x000a6895762709b5, 0x0004045a401ef3f8, 0x000ac355dbe9f79f, 0x00000000000ef178}}, + {{0x00094c375a95d7b3, 0x000dd7f89c2c3b20, 0x000a45fd88318202, 0x000e48b12d9f811e, 0x000dc7a43dd0be70, 0x00018ca3a703ac1b, 0x000012a4309a2c21, 0x0000000000001943}, {0x0009ce1f49259e54, 0x000e6d9597d8737f, 0x0001541e69df2d37, 0x000760df1561aaa4, 0x000e2d91ee39fcf8, 0x000bbcb6de1e0306, 0x00074699979031e0, 0x00000000000cfcc8}}, + {{0x0005490cc3cc0b27, 0x0002a4073f24615c, 0x0003e0a87e36ac6d, 0x00006c18fcec6a28, 0x0005d75a73f10abb, 0x0008c94883a7d129, 0x00074165fd8700f1, 0x00000000000732f7}, {0x00049117079dd0b3, 0x00098d15d8c801e0, 0x0009200404155fcf, 0x00007c7120e12665, 0x0001f42cc9fd9816, 0x000a888cf0e486b1, 0x000249e606c16c01, 0x000000000001ea23}}, + {{0x00014f7d981a63eb, 0x000cb923e948b882, 0x0000fdde16bb34e4, 0x000011a6df27debf, 0x0001d57f4ca2345a, 0x0004196e9ba6784c, 0x00026df01b370311, 0x000000000001aab4}, {0x000a2240acace9dc, 0x000d82ffdc977a4c, 0x000a7e87839c540c, 0x000c01216f09c1f8, 0x000e5b9cc0b65ca1, 0x000150569612021d, 0x0003ea910e10e95e, 0x00000000000e2ab9}}, + }, + { + /* digit=68 [{1,2,3,..,}]*([2^272]*G) */ + {{0x0008093fcd51c0da, 0x000aaac58c9dfd06, 0x00005aab38065215, 0x0004afc2cc4252aa, 0x000397c2bdf932ef, 0x00049e19a08bd48b, 0x000496ac8a7803a8, 0x0000000000075c31}, {0x000fef0d3072e592, 0x00057733dc7dec06, 0x000d0f9063e4be72, 0x0005b0847be21a8a, 0x00055ebf426f6d9c, 0x0004e9e5bfab0fdc, 0x000089d60748caf9, 0x0000000000069366}}, + {{0x0000e5d6509e91ef, 0x00048b06c17a3a05, 0x0001e37973be9551, 0x000ae990038aeb31, 0x000b58b402ca2440, 0x00077732a83bf711, 0x000932b8763e00b5, 0x00000000000f651a}, {0x000cf91f09ef177f, 0x00070be02ab9cf6b, 0x0005ba59eb97ec90, 0x00072f64283f8100, 0x00072365da5e7ed2, 0x000dc6beb098cf05, 0x000d72d90e6f1805, 0x00000000000cf7b9}}, + {{0x000bed14c2e5c1d5, 0x0009f89b2edba20f, 0x000638f30da8440c, 0x000d9ce8943fce4f, 0x00045a2ff9961dde, 0x0006e87feaaf07ff, 0x00008c69e60f92c9, 0x00000000000b9ee8}, {0x000d99ec41a8cc2a, 0x0005279d6d8c67c9, 0x000b28385a21a71a, 0x0005267350b7fc9c, 0x000d8a2abab0c8a6, 0x0004faf7ce9fcb46, 0x000c8a57c3bfc62c, 0x00000000000a8207}}, + {{0x000f000e371891b6, 0x000b56f101762b79, 0x0004acb33b163eb0, 0x000e2aaac1dc8274, 0x0009f835a1b62c58, 0x0009915a451410e8, 0x00048d981333a762, 0x000000000000c141}, {0x0009810640a6c340, 0x000184d20b3d37fe, 0x000e4eb008d53e3a, 0x000b68c2a2645f81, 0x0007add082eaa664, 0x0005ff2067a6bc85, 0x000fcce7467dc63e, 0x0000000000004e2d}}, + {{0x0000cfcf5d6b5960, 0x000cc57fe04dac14, 0x000998e82d998b8f, 0x000bd40e0a341ea4, 0x000b9c24fdba5128, 0x000c1dea81adf3cb, 0x000ef2b1ce8520f4, 0x00000000000db22e}, {0x000911256ee6f617, 0x000b2e9f05f28713, 0x0000043d1376f349, 0x00052d3f63bfade4, 0x00006cbcc395a2ad, 0x000714bd81b43575, 0x000ca6fd1d7e0666, 0x00000000000a40ea}}, + {{0x0004ca398c06d768, 0x000c23d0efae2846, 0x000878540a1ede95, 0x0005a253f00eeef2, 0x000cd86161cea5cb, 0x0004a389ac2f9258, 0x000159d2b0865f5c, 0x000000000009b1f2}, {0x0008e174cdba2f0b, 0x000245a758a60599, 0x00087073a8d80dcb, 0x0005a4949d301c92, 0x00061c4bb89b8865, 0x00060259c129647e, 0x0007d106f0665ec3, 0x0000000000006619}}, + {{0x000cae6e407127c8, 0x000070262c90bff7, 0x000ca8e9829543e7, 0x000f8fb1577634a8, 0x0004597668ad6514, 0x000ff6ecf4678d63, 0x000dfc90213b637c, 0x000000000007518c}, {0x0005a2999ad1c0e5, 0x00071d006db8f897, 0x0004562511312669, 0x0003aeadf6356731, 0x000f1a366456acc7, 0x000e73aeaaeaa4fa, 0x000a480df51aea1c, 0x000000000009a8e4}}, + {{0x0001074c67a33fda, 0x00086a23545689bd, 0x0009b9de484075b5, 0x000247b132c568a3, 0x000dcc4760bbab0c, 0x000ae821b129a5c9, 0x000f8303eba46726, 0x000000000003df1c}, {0x000f0c5101b30f29, 0x0009f010813cfb68, 0x000cc25f999a807c, 0x00020b31fe4b6007, 0x000398dd32399073, 0x000abb34cda3bfeb, 0x0005f123f1ed1641, 0x00000000000946f8}}, + }, + { + /* digit=69 [{1,2,3,..,}]*([2^276]*G) */ + {{0x000261be9524972c, 0x0005728524830014, 0x000a9e4b0c851ae7, 0x000fa9900e4f78b6, 0x000b54a3f7a33a66, 0x00065a79afd8a65b, 0x00069a505d3f6319, 0x0000000000018914}, {0x000675265cae6514, 0x0008278367cbbd6a, 0x000c906352414281, 0x000b3f6f5af173f1, 0x000a5ca36597e41b, 0x00099f79557cb03c, 0x000ef127f86cb87b, 0x00000000000ad4dc}}, + {{0x00092527cce78878, 0x000b138a49bf4890, 0x00076c4f31c0490e, 0x0009eca01b2f7c2e, 0x00005be8359f5f70, 0x000646b3fc479a65, 0x00011b6b6a22bfd6, 0x00000000000cc5b7}, {0x000c9aa1253a31c2, 0x000d18e7dbc638f0, 0x00085601e946c9b1, 0x0007e04030271eb4, 0x0008e22fb3c72d3a, 0x000e0d46cb08b597, 0x000915860d62789b, 0x000000000001d49a}}, + {{0x000e171e53bdf97e, 0x0008556d65155b11, 0x00013206465d7fcc, 0x000049f10dfaeae2, 0x000ae30b70b8ef9e, 0x000c6a56219750b3, 0x00002611ed860015, 0x0000000000012097}, {0x000714d4a4467bbb, 0x000e279559d04c7c, 0x000363f176594d50, 0x0007323ae8fb3c53, 0x0009a4111f88d6fd, 0x00010a683834639c, 0x000e9afc69a029a3, 0x00000000000255f2}}, + {{0x0006e6e51e1dd6f5, 0x0009766797f569dc, 0x0007480d93f86f88, 0x000f4a531adb034d, 0x000e5d185cfc18ee, 0x00053c27bcf1cb5e, 0x000569f596a59bbd, 0x0000000000069002}, {0x000a4105949da385, 0x00053d9433e78e1e, 0x00022ac847a15a5d, 0x000d7ed65d68ece1, 0x0009fb2aded8233c, 0x0009b750e201bbe0, 0x000f25987f4975ac, 0x00000000000337f7}}, + {{0x0009f8de8126d12d, 0x000626fb6b7bb82e, 0x000f3dc00034e80a, 0x00089d8316ff5318, 0x00079894d65f98ad, 0x0002801704800ee1, 0x000537034ea3c448, 0x00000000000c30be}, {0x00066423e58a8102, 0x0009243c2d27d6b9, 0x000c30559bd3f060, 0x00040105eaef29b7, 0x00017b678fc76545, 0x0003012701d8f07a, 0x00036554bc6f737b, 0x00000000000e9473}}, + {{0x0005ee6b65e3f046, 0x0002a3561b3fe3d4, 0x0003adfe7b57a7b4, 0x000831347fb79d76, 0x0001c48002ed4374, 0x00044dcb0a7f497e, 0x000e0686221cce2c, 0x0000000000043785}, {0x000bdab4ad1119ad, 0x000279ee9061f323, 0x000458b83a9d33ec, 0x000e85b76f7f52c7, 0x00090fd6c65f1d8d, 0x0001f8a3939a713c, 0x00040af74ca06771, 0x000000000008ebc6}}, + {{0x000c37bd5d97c8e0, 0x000841942c2ff6fd, 0x000f5c9ed6475a4f, 0x00052b5771a5972c, 0x0004363c2048f3c1, 0x000db8da24cfb1e7, 0x00043dcd2ce8249d, 0x00000000000a5ee4}, {0x00044b387eb3689d, 0x000606fa84b3cea2, 0x00069e100b1b94b7, 0x00071368e13869e1, 0x000c96f0f8a12e45, 0x000d93dc039ac6a0, 0x000ec9e24458ac42, 0x000000000005f60b}}, + {{0x0001937d698b9991, 0x000c7514cc1dc470, 0x0007f6d12f9a74ce, 0x00022ac2fc9230fb, 0x000d92e23e21f0e4, 0x0006d1ac0aa50a1a, 0x00049370ac46d867, 0x00000000000f9f54}, {0x0006e32302426e7c, 0x0002059a6b86a840, 0x0004338952e5938c, 0x000cff13192968cc, 0x00040b342dd8d3d9, 0x0001da44113e700b, 0x000760fd5dc7bb3b, 0x000000000002c883}}, + }, + { + /* digit=70 [{1,2,3,..,}]*([2^280]*G) */ + {{0x00067944f366244c, 0x000d59e9af31428e, 0x0009cbe9f6c4942e, 0x000bd92582864947, 0x0009b2e09205204a, 0x00056b1017995988, 0x000f260c727a3dfe, 0x000000000008b657}, {0x000fac647b56af7e, 0x0004cde35d954514, 0x000e44c1af2c53f1, 0x000261f36019feec, 0x000966511d8ffa03, 0x0001148b9afda42d, 0x0003e1f63211dd82, 0x000000000006f13a}}, + {{0x000fe40d0b19b4c9, 0x0006a3997900ec16, 0x000abf1980c5bfc2, 0x0005b0a661f3c579, 0x0008aab1292b71bf, 0x000d993f244b1338, 0x000966cbe80cb9d4, 0x000000000002203f}, {0x000fa9a95e9148b0, 0x00053bc82a651a1e, 0x0005a004b90c2827, 0x000c7e7502f0003e, 0x000056a38f73a388, 0x00087d9b09c704ef, 0x0001f393cde8a734, 0x00000000000ec11a}}, + {{0x0004e6a4ec3efae0, 0x000e047fe47986cd, 0x0007fd532d6e5353, 0x000fa8b9a8671744, 0x0000514bf471b76c, 0x000dcf1fc9bc87bf, 0x000fa837392dce71, 0x000000000003ad1e}, {0x0001e59290757ebf, 0x000cebbea5a33841, 0x00075b7402f28c87, 0x0004ecd9b1665aa2, 0x0006e329df225b3d, 0x000aa808de7b0df2, 0x000faf18fb438e0b, 0x00000000000dd516}}, + {{0x000d8d8f4a6b2b66, 0x0002a63f27a255cd, 0x0003341f52773d72, 0x0007cd965f9ce38b, 0x0000635ba3005d31, 0x000343662162c92e, 0x000ac85259f64ffe, 0x000000000008e614}, {0x000a1c59580d5fe2, 0x000e397fb55baa90, 0x000365cc03ff132a, 0x0007325780618255, 0x00086c1e6306a57e, 0x00067b14c892f6b3, 0x0008c5f12e4c0723, 0x00000000000c83a4}}, + {{0x00040eada4657ebb, 0x000e31e6f9a95314, 0x000a04269b290326, 0x00056256e8b41991, 0x000b7a4a53f9365d, 0x0002b9b16e1b9c53, 0x00070155dc1d50e3, 0x00000000000bb6d5}, {0x000b5b1121311bd1, 0x000984c270249c99, 0x000f7b0846375c38, 0x0005b610689902bd, 0x000fa4cfc5a819a9, 0x000e5b424dd5706b, 0x000a87d33bdb7314, 0x00000000000e69eb}}, + {{0x000fd0482abbdf6b, 0x0004f6897401cbf6, 0x000652cc2d40814f, 0x000b32939e2b43ba, 0x0001bf809331e511, 0x00058f8f43952286, 0x000727815f6c1dc9, 0x00000000000c213e}, {0x0009a038bd421fe7, 0x0008ceb09ae59065, 0x000d25d81924ad76, 0x00015a2a20f86c7b, 0x00069aa308078f48, 0x000758878748a176, 0x0003d7f1f46a211b, 0x000000000006f6fc}}, + {{0x0005626ca6bcb860, 0x000ac75ba2f9acbe, 0x000c234135494b93, 0x0009e0b610d080fd, 0x000333a99c2f3c33, 0x000580aff614ac29, 0x000a3aa5e23af2aa, 0x00000000000e1fdb}, {0x000ca5f5b322ee30, 0x00065aa603365011, 0x0001b05f57ab1134, 0x000524456330a336, 0x000b9e025aa3a2b2, 0x000a0d5cfc396b5b, 0x00083babbf77faf8, 0x00000000000ea31c}}, + {{0x00047a49edb97340, 0x0002d300b04831fb, 0x0008ca060cb164c9, 0x000c5420cc10a74f, 0x0004eff9d01017d9, 0x000aa12857f637e8, 0x000114d732aa1e27, 0x00000000000e2a77}, {0x0008fc5f031be351, 0x000d262acf1585bd, 0x0001b0dfbfbd395e, 0x000c5d22e6eb2db2, 0x00028d18263d88be, 0x000bbd6acaec2720, 0x0004c04b687353e4, 0x000000000000ff7e}}, + }, + { + /* digit=71 [{1,2,3,..,}]*([2^284]*G) */ + {{0x0006ecc79d0fef75, 0x000dfa6e19d09c24, 0x000097d1dea89821, 0x00080950ee527a58, 0x000b7c4278a6ef73, 0x0000798ff78b7174, 0x0000cac133d867e7, 0x000000000009e923}, {0x000f7954ffb5e165, 0x000877431eeef1ad, 0x000728c869881eba, 0x000306a8d6af3f83, 0x0000bbec076af7a4, 0x000257ca3633bb5a, 0x0006636d07623e7a, 0x0000000000021c00}}, + {{0x000f8db3d9e25bfd, 0x000ed35ae891ae18, 0x00094f42c82c0dd3, 0x000b3cae63745c4f, 0x0005f218d139c2da, 0x000f3b0e255b8c18, 0x0003fa6ab039c889, 0x00000000000c644c}, {0x0008fe1e4d75d65d, 0x000d9c8496f1ff0b, 0x00010bc25fdaddb7, 0x0008392921149191, 0x000fef73f3455c67, 0x000fcfb22e962e52, 0x0009113818baf354, 0x000000000009d4bc}}, + {{0x000af695e08e48a8, 0x000683a35938698b, 0x0003114a51ff94f2, 0x0000f82899d204cf, 0x0009158780b5fcce, 0x0004edd4f4ca4158, 0x000c34c28f1bb73c, 0x000000000007a6ae}, {0x000b281e555c9d40, 0x000676d4783df7ee, 0x000d1f8a08acdccd, 0x000c2bcdf6d7f923, 0x00000f356ca3b7b8, 0x000b8e964f0a8d47, 0x0000e1229894bfde, 0x00000000000d3aa7}}, + {{0x000d000279a1a838, 0x000b77f1f985b888, 0x000a43ce9b20f9f6, 0x000930a5188fcf70, 0x000ba3a82904b40a, 0x0001510273fad79a, 0x00017b7bee8d22f3, 0x00000000000c2c3e}, {0x0003fdcf0848373a, 0x000041fbe06e92b8, 0x000ae48de4a30594, 0x00090ec2d9cf7a56, 0x000a9bd062c5fff2, 0x000d353815d0deda, 0x000eda080344abd7, 0x00000000000f5cf9}}, + {{0x00012d81fb28e752, 0x00018093526223ac, 0x000d23e13369699e, 0x000d26ee94c9abed, 0x0003a20b52679a62, 0x0003d5fa4425b86b, 0x000fc68164f9c8e7, 0x000000000003b12c}, {0x0006c5fe565db2c2, 0x000be6cc34bad21b, 0x0002901d6245306f, 0x000f50970e4963cb, 0x000cf0813b31f80f, 0x000f1ab8ee403ccc, 0x000b92a72ab5f584, 0x0000000000070f15}}, + {{0x000e213ed814f6f4, 0x00034170098ddc99, 0x000e9c62ee04edbc, 0x000b04b8660d7749, 0x000b5152ad1e35b1, 0x0008e92aa8b4b6c4, 0x000f4e0b0bd1c24a, 0x0000000000088172}, {0x0007445379f53f7e, 0x000d513a76898c7b, 0x000f4e73336bcd42, 0x0004f973dc17e72a, 0x00060a7124b24b39, 0x0008a372c1b0cd16, 0x00003b7549880cce, 0x00000000000e7126}}, + {{0x00055aa45f74a004, 0x0008dc14a3abb979, 0x0004a411c66e9f88, 0x000f1828a4be08cc, 0x0009deca5a89e49b, 0x000fbb36be6e7bf8, 0x000e57a7326cf88e, 0x00000000000c7f6a}, {0x000da2212d19f21a, 0x0005dceced37b724, 0x00062d313930a591, 0x0005b3fb62a62e4c, 0x000793e5c0e1a7e6, 0x000b8d77382cb79a, 0x0002f014c9a99461, 0x000000000000b05f}}, + {{0x000a2dd7deb1dde9, 0x000a831d31f799b5, 0x0008e986349103b0, 0x000362e52f04d685, 0x000921c7b6511793, 0x0006f47f65808e70, 0x00040533fe9123ed, 0x0000000000058f71}, {0x000d5dbe8f1956b4, 0x00061821d30451f3, 0x000e7b4e166f399a, 0x000db145b2048aa2, 0x000ed7811330932d, 0x0008fd85f17d989f, 0x000434032ae4cb12, 0x000000000007d1ef}}, + }, + { + /* digit=72 [{1,2,3,..,}]*([2^288]*G) */ + {{0x000acb4203cc71b2, 0x000a9070d34e112c, 0x00047b523d821ba6, 0x000f9b95eb8ad292, 0x0006a6a45dda269a, 0x000df41e0dde0a03, 0x000f2aa18b528e63, 0x00000000000a260d}, {0x000c22d6a6aefb01, 0x000d424a67709f9b, 0x0002a9971343d570, 0x000e2a1968444330, 0x000d131a6cf073c1, 0x000e794543660558, 0x000dcdb0289c832e, 0x00000000000c6d8d}}, + {{0x000d86ee6f475d5b, 0x000d30ed1082f1a9, 0x000a6711ccf28680, 0x000ef0eece773534, 0x00064bf0c426a35f, 0x00011b2fb76adaa4, 0x0004d3fbab929aa0, 0x000000000009d8cc}, {0x000bb954fd395b2c, 0x000dabe6d7f2076f, 0x000a4cbdfe911e02, 0x000cba5106ceaac2, 0x000a45258697c7e2, 0x0005945b0fe94528, 0x000f7a7109b17d07, 0x00000000000cae17}}, + {{0x000ce6be22a12c0b, 0x0008a6855029961b, 0x000a3c801158be2e, 0x000d2b4a8e92e70b, 0x000f0cc9fca9f601, 0x000bc2e96fd02799, 0x0009b889f99ca013, 0x00000000000ff9db}, {0x0006b1bd37f91ceb, 0x000616ae70849faf, 0x0005d65bd4da44b0, 0x00092a4e0945e8f9, 0x0002ecea36f6394d, 0x00018a069ddab675, 0x000860650b74d60d, 0x00000000000ad650}}, + {{0x000bf5b4a4380ef4, 0x0001cfc1faedb8cc, 0x000e6ba03d77f4c0, 0x00085456416defe8, 0x0000c58653e7f004, 0x000f6f99e75de777, 0x000c07dd2dcbebe2, 0x00000000000d159a}, {0x000c9af1998a9b17, 0x000a045dd713c4a8, 0x000e1c3678ddf502, 0x000756b6b962b38d, 0x000bbffd3f0c3f73, 0x00008ebae3cb9f53, 0x000dbad723c40b7f, 0x000000000000c3cd}}, + {{0x00003107748ef382, 0x00058a804b2f0156, 0x000b319b886fb1eb, 0x000f4fd353970be7, 0x000712854a9131ba, 0x0009713983481c8b, 0x00094ab0424eecf3, 0x000000000000f4ed}, {0x000648ea129bd87a, 0x000a992b74ad013d, 0x000692f5d2444d08, 0x000b28070a5f0c93, 0x000b9f5101ca6741, 0x000d0f81e46c12cf, 0x000288e7014d7901, 0x00000000000d758c}}, + {{0x0000c39f81600214, 0x000686a565269228, 0x000c17ee858626b0, 0x00011a7d8c6ddb92, 0x000b2332347b0bda, 0x0009dff48b7ebfaf, 0x000c83cf791881e9, 0x00000000000dc357}, {0x00082704ffef2257, 0x000fe2a264f8831e, 0x000c9352584eb7a7, 0x0008260bb47d4188, 0x000c3d8170326d47, 0x00005f901544de4e, 0x00063cac7150a9dc, 0x0000000000075c09}}, + {{0x000bcfd07a0f22c4, 0x0007c58805ca858d, 0x000b1c2b2351e4ce, 0x000c9a1349cfed00, 0x00017800a980f9cb, 0x000847e9d67bc7b4, 0x000c48e7e6dbc0f6, 0x00000000000af379}, {0x00047d63263e04cc, 0x0003c80b6fc048b9, 0x000808eb22fe8f7f, 0x0001ed14e9dc24bc, 0x00073fab87e6d2d1, 0x000c630ae48d74f1, 0x00020a1feca5af50, 0x0000000000062d06}}, + {{0x000e56ad2bfbbdbc, 0x0008ff6377e3bcab, 0x000f30b92835c3f0, 0x000ac42c21c0cf1e, 0x0009857d8edb7f85, 0x000b77ed67a3e31c, 0x00010b2eb1076327, 0x0000000000038dae}, {0x00026ce2d0dbce6d, 0x000dced7c6fb0aad, 0x00066cec0d07ac1c, 0x00035504569e7309, 0x0007bedae3ab4dc4, 0x00027e463aa82fb9, 0x000a1106d37bef4f, 0x00000000000f0c35}}, + }, + { + /* digit=73 [{1,2,3,..,}]*([2^292]*G) */ + {{0x00011f784b3a0046, 0x000066edf5561b45, 0x000c8578d54224c1, 0x000ae56d8d66d29a, 0x000ae9d58eb27699, 0x000f9176d5f81602, 0x0003b1d0c04874fa, 0x0000000000052315}, {0x00067980492adf03, 0x000309690930fad0, 0x000146ea47ef3788, 0x000725873bcba90f, 0x000de902e3292d0e, 0x000bc27b957efe72, 0x000c093fcd598676, 0x0000000000093940}}, + {{0x000cdd973668c530, 0x00077c68b641e912, 0x00064e1ee190b62b, 0x0008cbad89ce6688, 0x00006c269d8eeda9, 0x000f3402315f84dc, 0x00034af0eb685ecb, 0x00000000000c0326}, {0x000bc909db075650, 0x000562e3d7fff094, 0x00012e59576050a3, 0x000abcfa3e050e0c, 0x0007c001dcd9f02c, 0x0006d2d52ccd2da6, 0x00041f50aa372306, 0x000000000007224a}}, + {{0x000ec1f1185b9762, 0x0007e4b1f8698c94, 0x000d0af36ed765ea, 0x00049f56536e156a, 0x000109c95a75ba1c, 0x0006d9af131c3163, 0x0008b7268a308f0a, 0x00000000000fa9ca}, {0x000f13b9ac944487, 0x000b1c3b1cbccb86, 0x000446bb4e60be0c, 0x000c7b334396850c, 0x000a048a69431b4e, 0x0005820bf42f21d5, 0x000a580bf948f55b, 0x00000000000b48dc}}, + {{0x000b86ea9a29c966, 0x000cd04418b58cb8, 0x0002d1612a6d4e73, 0x000e22c7c65a6da4, 0x00051dbeffe45f87, 0x0003cc05caac7106, 0x0002c4ff619d64bd, 0x00000000000e65c9}, {0x0002126bd4b5ea52, 0x000d123af2b21062, 0x000e0691b9e9f16b, 0x0007efac6478c561, 0x000af6cd140ec34a, 0x000a0db2e57cde95, 0x000b7664b74575f5, 0x0000000000075d7f}}, + {{0x00078c972345257c, 0x00058a9532cb266c, 0x0002b89ba64976de, 0x000067545b1733a4, 0x0004cc6e65dd74ea, 0x0006ff2aa7f37f02, 0x00079e6612b1425c, 0x0000000000030374}, {0x000f1ac7f7aa2f0c, 0x00097e512bca4fe9, 0x0003049963042b95, 0x000bd29a259d6515, 0x00077373034f5b97, 0x0005aa640215eb65, 0x0008b779da0fc488, 0x000000000007e435}}, + {{0x00041294c6ef7a53, 0x00023ce3cc51372d, 0x0009af7f675a386a, 0x000d981efc9f71b0, 0x000a20bea9baa9e6, 0x000ef7c1fc01ded6, 0x000a5cc4b7e6424f, 0x00000000000f9dec}, {0x000954a122b474b3, 0x0002aa0a43d0a3de, 0x000a0d55c109a592, 0x000a173b5d57bbf3, 0x00056299978197ce, 0x000ca2bb13c3f30f, 0x0002e069a7820a8e, 0x000000000000ff69}}, + {{0x000deeb8201c384c, 0x00029aca3f998176, 0x0001642e9c9fe922, 0x000dbd63d82750be, 0x0002faa3400be031, 0x0005fd54bfb2552a, 0x00030374e9b5d365, 0x0000000000035894}, {0x000839a12661f3f2, 0x000a15a575a4221a, 0x00056e3aabcc078b, 0x000ada596e1e1175, 0x000d0f305dc3ca6f, 0x0008d7af5126e9af, 0x00069391da8d7305, 0x00000000000d8353}}, + {{0x000cb9cfccb5f12c, 0x0002c28405061c1b, 0x000211e4805b5eb0, 0x000944405547f7c3, 0x000d3441e472789d, 0x00044ce877fa445e, 0x000d14feb198254a, 0x00000000000129ae}, {0x00073247d16dc8ed, 0x0008622b05de2de2, 0x000590692ea55dfa, 0x00052caa83f7f094, 0x0006cefaa757fba2, 0x00017d8060f6ad6e, 0x0007ade1ad187165, 0x000000000008e9d9}}, + }, + { + /* digit=74 [{1,2,3,..,}]*([2^296]*G) */ + {{0x000c5ac4350713f2, 0x00062cbb991946e6, 0x00025875bf6be408, 0x00024aab6ab6c041, 0x0000bc41f4b7d50b, 0x0005496cf419d281, 0x000ac0e2e88d7a29, 0x00000000000f2457}, {0x000a357ad05dad34, 0x0008e838e4a3533c, 0x00068ef45f1df4fb, 0x000ab1c7a5c5fdd4, 0x000dde34cb8d9fa3, 0x0009105fe324798c, 0x000249bfa5a9d088, 0x00000000000fd0df}}, + {{0x000b286ea52474ce, 0x000419974759bb2f, 0x00039b1e3f8aef8e, 0x000c58ec64941cb4, 0x000a01d055758afe, 0x000448db52d7c57f, 0x000440c07c74cc5c, 0x0000000000001bb1}, {0x0007977c86a9c43f, 0x0003893162d96796, 0x000ee52587841e45, 0x000c57e6af18dedc, 0x000f174a30894f28, 0x000dd626536faed8, 0x000d7b702dbd64a3, 0x000000000006adc0}}, + {{0x0002a70e7d991630, 0x000854981be688ec, 0x000de0f53a95f8f1, 0x000e05074cff00d2, 0x0001b52c7f9c3168, 0x0001c7986111150a, 0x0002ad0db2ed84a5, 0x00000000000e6127}, {0x000c16b3e4d1fe2a, 0x000897443d935440, 0x0002c51d6c8aaceb, 0x000ef4e866b5e41e, 0x0005b965a67071e0, 0x000e1aa7705c57a4, 0x000e3285bdb58c70, 0x000000000009df3c}}, + {{0x0009a11de31a0e3c, 0x000c6c41e4aed12a, 0x000342590d5103b5, 0x000ab7b8ed812d38, 0x00081afb58b8f5ea, 0x000efcc3a7801fbb, 0x000b91be5cdba671, 0x00000000000cd10c}, {0x000761b96524aa0d, 0x00013882e821e20b, 0x0008d1b11d20578f, 0x000de2bd8a0f0393, 0x000c857fd3a03afe, 0x00060f767e20a117, 0x000da1ebaa2aa430, 0x000000000002b9d1}}, + {{0x000d9fea4e493f3b, 0x000e070e478fb44f, 0x0000254b6a02edec, 0x0002b005be36ea75, 0x000f6717e06aaec8, 0x0008f197782618b8, 0x0000d12db1f6d400, 0x0000000000016b39}, {0x000ddfa794ec9644, 0x000bafe86fd4d041, 0x0006bc15de0d2bf6, 0x00023e70c0491593, 0x0005ed4562356cbb, 0x000d836efd05be7e, 0x000604601374069b, 0x0000000000032e5f}}, + {{0x0001ebab46405b61, 0x000f009db138cd2b, 0x0009fd7df23c53c0, 0x00047794feebab9a, 0x00017fdb1e710bb6, 0x000f1f65dfce4aee, 0x0006cd7d5c0c61a7, 0x000000000008d02d}, {0x000621234d968fad, 0x0005c7cac0485224, 0x0002b8dbf87d2555, 0x0009a59db0aa864d, 0x0008ff94f8b5b587, 0x000c97f8e75f391b, 0x000232a6c994ae49, 0x00000000000d690b}}, + {{0x000e6486f79bfa96, 0x000e507c60c742b4, 0x000d5aa8cb9b07e8, 0x0000a09dcba89982, 0x000a802ce50ca8b0, 0x0002144b0a77f1f3, 0x0000db6c4050df2a, 0x00000000000ab1b1}, {0x000a93fc6ce00720, 0x000e89025d46fd65, 0x000c1e4037fdb9f5, 0x0002d629ae2d5361, 0x0009eff0f6a9bcad, 0x0005fa5a07a15282, 0x00039ce87345cd92, 0x000000000000e840}}, + {{0x000cab548e246919, 0x000d15017e1454d5, 0x0005f67186d3e9b6, 0x000059dfa98234b5, 0x00099985af982541, 0x0005b7b1c4bf344d, 0x0001ad39737ed67b, 0x0000000000087c41}, {0x00069e3ff4c10920, 0x000022fad8cecc3b, 0x0008e45c000ca718, 0x000d856404043f8d, 0x0005863927a11a53, 0x0008921216c1f07a, 0x000c8f38d3a4f4b6, 0x0000000000001976}}, + }, + { + /* digit=75 [{1,2,3,..,}]*([2^300]*G) */ + {{0x000dd4906efe62a1, 0x00063bcc8842253e, 0x0007a247757fdab1, 0x000a1ef2571d6b1e, 0x0001739a956e745d, 0x000bffc16f01c292, 0x00072ceffd8065e4, 0x00000000000f36fe}, {0x000478592361b14b, 0x0003ff49e90d1ebe, 0x0001338e12b047f8, 0x000b583b7240d91d, 0x000c03f8387fcb78, 0x00000f2d92e1a7c3, 0x000a8416566c2232, 0x00000000000aaf80}}, + {{0x000f32d335de93bd, 0x0002d7a1a522aee8, 0x000b425f9e81403f, 0x0004abe3d4ac4abe, 0x000337f996e841bb, 0x000727761c52950b, 0x0007d201d991e679, 0x00000000000978fd}, {0x0006e2e2907ff054, 0x0007486bad5e5c68, 0x00010431aa78725c, 0x000eb7705757453a, 0x00093939df7758ff, 0x00078ea0fbb18612, 0x0001d3bfdd394a6a, 0x000000000006e33e}}, + {{0x000c3ccc7d56f63d, 0x00076db1cffd2381, 0x0002131b488cf4cf, 0x0001e5aa3c1db85a, 0x0001ac55d391a418, 0x000d270d0e5183e5, 0x0005462793d5efef, 0x00000000000c0631}, {0x000c80c1d49264dc, 0x00008ecb40a58378, 0x000aa60ec18fee5f, 0x00014ab6c5830fab, 0x000ca03f201ea89b, 0x0008c54f64dc477d, 0x00066e5604f5dac8, 0x000000000002acfc}}, + {{0x0003e9c742a5516d, 0x0009da7f29531cb5, 0x0007fe865f9eba30, 0x0004ce9efae348cc, 0x000cac52758dd2f5, 0x0002961a45acb931, 0x000fe1287b3e18d2, 0x00000000000748f8}, {0x000f0554bb131f76, 0x0001d1b62b340cc5, 0x000b08ad2a8e1d6a, 0x0008dadbe8da8486, 0x000954f18276bad7, 0x0004bfdad85fa710, 0x000237e2cc9d287c, 0x000000000002c75f}}, + {{0x0004d2c2f1f927d3, 0x00033283dd7ef2a5, 0x000a91f40054b9d9, 0x000c095870282aba, 0x0008f4e36324ba08, 0x0004cecf2b02b00d, 0x00024e53aaddc060, 0x0000000000084ddd}, {0x000a889fa3214142, 0x000ca34bc00a03f8, 0x0000c263c00349e0, 0x000eaaacef68f74d, 0x00023c0293515228, 0x00042e3b740a790d, 0x0001e0e0e9af5c84, 0x00000000000a9f14}}, + {{0x00087ba6916bcaca, 0x0005bcdcdd7d6721, 0x000b58247a460e0a, 0x000c569c00ce5c40, 0x000fc589d0c75923, 0x000fa6fe6099c17f, 0x0008c40335eeea89, 0x00000000000a4e86}, {0x000a7415516e07c0, 0x00024b7037325a9f, 0x000944c467e9c1bd, 0x00032efd5e26d28a, 0x0008de919cbedf31, 0x000bbb18d7ed994b, 0x00050812df67cd6f, 0x000000000006baff}}, + {{0x000c3f58ee594ee5, 0x0008b72f4949e0b4, 0x0001e5bef192dfaf, 0x0004726092a58066, 0x00010f5cdb7271b0, 0x0004bfc49ad5c3c1, 0x000be7d4951f9e55, 0x000000000006131e}, {0x0009f77a3840f92f, 0x0009237da59f303d, 0x000ff0c06b034503, 0x000962a4d89fa660, 0x000e71d824f5d020, 0x000050e312610c61, 0x000bfb9c917da73c, 0x00000000000e6e7e}}, + {{0x0003a9eb85c489f9, 0x0003af2ec9ef5122, 0x000d827990bab108, 0x000b2387d2ac6e41, 0x00020318a3b790e2, 0x00084a7a0cf682b1, 0x000d057fe76089ea, 0x0000000000016546}, {0x000bc6c0a0421345, 0x00041f987118eca7, 0x00079f0cde4a8da9, 0x0007774888a7e8d0, 0x000a63ec5831544c, 0x0002fe985bd2647b, 0x0003e8b479cea3fd, 0x0000000000028d16}}, + }, + { + /* digit=76 [{1,2,3,..,}]*([2^304]*G) */ + {{0x0005b08a8a2a82b4, 0x000fa04baa17598e, 0x0006a0661405c62f, 0x000031dc6cd61096, 0x000030bf87a5c4a6, 0x000e497ccba2534d, 0x0006657ebc6e2131, 0x00000000000851fd}, {0x00018d257f3e221b, 0x000e69ecae010ee2, 0x0009788f9b15d390, 0x000a9c22fa527837, 0x0001236d442e39e8, 0x000c289ce74c9380, 0x0009cf8b21ba23b1, 0x0000000000025c76}}, + {{0x000aafc618669c84, 0x00037761e10e2b1a, 0x000c03aea1a1a99e, 0x0000ff43dbc6fcaf, 0x0006cbe0ba8aa087, 0x000f1ff6a9765128, 0x0005b647d46075c0, 0x000000000003abeb}, {0x000f7f59840e13b0, 0x000af1234c80e297, 0x0000d9f885a37dab, 0x0002d41d82ab780a, 0x000fde426e50399a, 0x0006dde778a03afa, 0x0005eca2bcb109ca, 0x000000000000618f}}, + {{0x000adbd12143606f, 0x0003e0d27500f7d7, 0x000cde21714cb370, 0x00078f8610763e40, 0x000f47ef08feee75, 0x0007d04c06e56078, 0x000aa3a8d03a7f04, 0x0000000000027cc8}, {0x000677d27af9cf4f, 0x000056b08eb37c00, 0x000a4a2b5d3fdd3b, 0x000869ae3f10ba99, 0x0003e500e8466f9b, 0x000171b1a3bfb983, 0x0000456d975557b9, 0x0000000000018fa0}}, + {{0x000e348941e625d9, 0x000fc15d47e52aa7, 0x000dc7038ccf5369, 0x0006a3070cddb11e, 0x00032b5a8db75122, 0x000f37d6563a253d, 0x000b91e8be4d1fbe, 0x00000000000c0920}, {0x00045423a83becc9, 0x0008308b713a8319, 0x000ebb9d576c8cba, 0x0005877917ee393e, 0x00091528cd12a897, 0x000daf6aa294792e, 0x0009b94512dc8c37, 0x00000000000197a9}}, + {{0x000e5d8cfc9c3b49, 0x000e0cfebe026cd6, 0x00010748e4a52d81, 0x0009d16725ebd099, 0x00007a584e8d00f8, 0x0001cab5894c6f2b, 0x0003c8095ac9cc91, 0x000000000009c407}, {0x000462695d0ed83f, 0x00056265919b06a1, 0x0003cfa033d1cd2a, 0x00097f1815a70aa4, 0x00001c5fd35a6db5, 0x000d52a8bdd9e4a1, 0x000fab38b8e35112, 0x000000000002ef20}}, + {{0x000003aa77fd8f2e, 0x000b43b21dc1edb9, 0x000008b1e2380339, 0x000e5d30da87d664, 0x000f0cd999a0f536, 0x000e08f5d4ce10ed, 0x0007e68949181450, 0x0000000000052664}, {0x000bcdd23ee4cc2b, 0x000a3cb207ee8e61, 0x0002ac9dd73c4f6c, 0x00040d225e0cf154, 0x0001067fa0527d49, 0x0008b2e21b688b31, 0x000eab89308326a9, 0x0000000000072311}}, + {{0x000c6c4de58ef59c, 0x000db2a6280408d6, 0x000f4e9cd796cbfa, 0x000daa3c647fcba8, 0x000f4952d3a44a2c, 0x000e2e2c3e1a9e91, 0x00040ebc1b3d8011, 0x0000000000018e43}, {0x00017ee00926dad8, 0x000cceb8696ff13d, 0x000436379cf7b867, 0x000d6ce6c1e905c6, 0x00091ed2e8cba471, 0x0007c8c914e13d60, 0x00084e52951509c7, 0x00000000000e2348}}, + {{0x000a3b1514eda4ba, 0x000ac37be5d3f53e, 0x000cab6203ce338b, 0x00024b59d1569e7a, 0x0009b4e293ab165a, 0x000b7c0a4254aaf5, 0x000b183c751fbd6f, 0x000000000005018c}, {0x0000fe7bbd1e6c72, 0x000eaacb3b8965e4, 0x000a2f2ab6db69d7, 0x0007258621df6d82, 0x0003185f0e2a245d, 0x000ddbd812af0e28, 0x00002a1e7edc818f, 0x00000000000c538d}}, + }, + { + /* digit=77 [{1,2,3,..,}]*([2^308]*G) */ + {{0x00042da90721f8f9, 0x0009f6858b6747d2, 0x00082ecd0813dd9f, 0x000674e29d9194d6, 0x0006dcb30a51324e, 0x0008aa5492dc6fdf, 0x000a923f3ecb7752, 0x0000000000023ffa}, {0x000c7344981b01f4, 0x00090d8efcbd58f8, 0x000d0144b46e312e, 0x000b0b74cf4a1708, 0x000fbbf335fd04f2, 0x000928c36bc0bb49, 0x000d45c6b6e5bd5a, 0x00000000000d893d}}, + {{0x00016a2799bedc34, 0x00022fb083c2a5e5, 0x0000296a1d9c8cea, 0x00030e747a81b965, 0x000658a987376e41, 0x0002829c9cd704dc, 0x000d63842ae32959, 0x00000000000be20d}, {0x000f531daa9bdad7, 0x00053abee8e552a9, 0x00078232300aac8e, 0x00039b2467112ba1, 0x000fbe341038781f, 0x000a2f8be6f06058, 0x00066e5effdca512, 0x00000000000af344}}, + {{0x000afa3ee32c886c, 0x0006d3933b4c0742, 0x000439c40f3f936d, 0x0003c0f0b7e019e4, 0x000fa48715d652fd, 0x00039be537f8e5dd, 0x000cdc0879c5defa, 0x0000000000056f01}, {0x0005bfa2d160b7fa, 0x0004671b2dcba45c, 0x000e0bb6fffdcb60, 0x0004846640b2d753, 0x0000049a2cbe6af9, 0x0002ab0f178a1071, 0x00043841a1ce67ac, 0x00000000000a76d8}}, + {{0x000a317691072fc1, 0x00025ab86639e0b1, 0x0006a85f7a13b8bd, 0x0004418d763f0bbd, 0x000211a9802cb573, 0x000269b8ad2cc332, 0x000355e41d7db881, 0x000000000002ecfa}, {0x0004e57bc1e94af4, 0x0006159d6912442e, 0x000356e842631b03, 0x0008b6b8a7397395, 0x00091cc83ae38447, 0x0007ccd97e86ad7d, 0x0004c6bc9b208479, 0x0000000000069494}}, + {{0x0006d3d1d84bf486, 0x000a4bbb6725a843, 0x000b1260c5ec574a, 0x000dd0664bcb2d64, 0x000a780d5c1bab65, 0x000a61e6e755e848, 0x000b4b84e6f686a3, 0x00000000000bd100}, {0x000cfe4a11d7ea4f, 0x000a3b34fdf84517, 0x000d9afd2967c440, 0x000c881f9a125f0d, 0x00064aeadf8e3c2c, 0x0006bf0c2b1fcce5, 0x0001bebdfc54c0c4, 0x0000000000009d28}}, + {{0x000af84d84069bc1, 0x00010e1aa844a91f, 0x000628bd439b9e84, 0x000aba65ddcb5d25, 0x000a38009c6a3025, 0x000261ee5ac8cdab, 0x000430b9ee07b46e, 0x0000000000006ab8}, {0x0003196ba81697a7, 0x000207a36b461d0a, 0x0005a884d3b0fe10, 0x000f469341275a1d, 0x000f1c7cf858ae4e, 0x00092af3df7cb393, 0x00017683c00eafd1, 0x00000000000a1e15}}, + {{0x000475d9329b61bc, 0x00078687d0980c72, 0x000d109af3ad73e4, 0x00007fabbcde5b3c, 0x00016ed103a56414, 0x000a6ee2212ec9d2, 0x000c11f858c7851f, 0x00000000000818f2}, {0x000247f6c002433a, 0x000a04720d42a19d, 0x000f64099b42a8aa, 0x000f25533723e4ef, 0x0003d3260b6299af, 0x000391c33d6c67ce, 0x00038163a6fc9d86, 0x0000000000031de2}}, + {{0x00092324c0c2dff4, 0x0004f585edee2c89, 0x000820f42406ab00, 0x000924fd85ad3203, 0x00019124bffa3bd7, 0x000c628682e7d8f9, 0x000f5d885397c044, 0x000000000007fda9}, {0x00035c11900b0d2c, 0x000e6d302582e314, 0x0003e1f066fcf73e, 0x0006b5b63653c06e, 0x000d9c70dad4b021, 0x000bba93d8f08a1a, 0x0002b7ccf014aaff, 0x00000000000a33f1}}, + }, + { + /* digit=78 [{1,2,3,..,}]*([2^312]*G) */ + {{0x000cb198f774dfa5, 0x000dd1e347819af2, 0x00020411ce747fbb, 0x0005ccc28af85bb9, 0x000b3ae9ba11fc18, 0x000bdb313c923d78, 0x000b877d494d7ea7, 0x00000000000af8f8}, {0x0004fe8c8323652c, 0x000bdc178ccc093c, 0x00006a94572bacfb, 0x00047cc80a50372b, 0x0000e6f901976087, 0x000c2f2168147aa9, 0x000b514683d4c978, 0x00000000000552f3}}, + {{0x000f8017d10c6b96, 0x0002229d81537326, 0x0007f1980aaaed23, 0x000ce6e8783d1fe4, 0x000df0e3c126aa4a, 0x000ca4b719c14ebd, 0x000f350eb1c08d6e, 0x000000000001c91d}, {0x00013bd5d85a7c75, 0x00064db8119bb0fc, 0x000fdf5036f03e4b, 0x000916835436f82c, 0x000b9b18d212053c, 0x000bc3497eb41ccb, 0x000d8193b3fb43b1, 0x000000000008c1ce}}, + {{0x0007ad7a8ff88fe5, 0x00031521f4af6aed, 0x00033eaf4c7af196, 0x0009ab7ae0377807, 0x000db65f73ffad09, 0x0006059b9541cadc, 0x000f8253430463a8, 0x00000000000043e9}, {0x00061f938516beb2, 0x0001bd515f4c75f1, 0x000d0a9d767932f1, 0x00053567ef1b9007, 0x000f1295b5fe7bed, 0x0009176278782b45, 0x000d9fab54ebaa03, 0x000000000008787e}}, + {{0x0006f626b572390e, 0x000905255508b5c5, 0x000fa6a60258070c, 0x0005eea3095205c4, 0x00002c470ef7d976, 0x00040bf0afea2ed7, 0x000a16f5e8a0fc9c, 0x00000000000e4137}, {0x00055209e40da33c, 0x00003b917537047e, 0x00003ab2893cdb40, 0x000bce9023854871, 0x0008a8bc3a94bea6, 0x000c450444620840, 0x00015164a87a2a3a, 0x000000000007df70}}, + {{0x000cf2f10b0520cd, 0x00004c38d07270c5, 0x000e4dc64fc6cd1a, 0x0001d8f300e953df, 0x00040a7dce63abde, 0x000425847b98b23d, 0x00061b63e51543fc, 0x0000000000043a21}, {0x000d54e8ecf42bd9, 0x000ee2650a1d5920, 0x00086c043a07e5a3, 0x000b7048bd9bd78b, 0x000df89e86bdc15d, 0x000579426bad1dba, 0x0005f8d7d4845024, 0x00000000000287bf}}, + {{0x0006ca98107f85ef, 0x000615fb05303f18, 0x00091aa7ab0bf32f, 0x0000fa47d92132d0, 0x0008994564bf7a0a, 0x00029e066e993faf, 0x000574bf30252517, 0x00000000000d4260}, {0x000990cf5caa4f19, 0x00009f1eecc3d948, 0x000f8dbc962efd6e, 0x0001cf1d1dd88736, 0x0003b6f1aae115fd, 0x0009344b97ce882a, 0x0009ca7efb7ec6da, 0x00000000000cc5b5}}, + {{0x0003c28364de2038, 0x000c48bcbf6cdce6, 0x000e355114722287, 0x000febf92ebe1bcf, 0x00019af24c2e4ee8, 0x000a861d57847829, 0x0007ec618760b094, 0x000000000006bae2}, {0x000de113e64c1ae9, 0x000fc77c174b9e18, 0x00055d1ba670f4b5, 0x0004f6a58a0062c2, 0x00047781acd1db9e, 0x0006d86b03480c9b, 0x000ef52d7c628ef5, 0x00000000000b3e2e}}, + {{0x000ade0c1eab3d7e, 0x0000fee9e25d91a6, 0x00060f30210199eb, 0x0001157d2d91300a, 0x000fffcbe50fd2fc, 0x0001d376ee7597e2, 0x0005624be3814fe1, 0x00000000000dbf14}, {0x000860a341c4b797, 0x0005638a107c07ee, 0x00045c1dbdbe39f3, 0x0004e09caebd481c, 0x000bf9ace60d1801, 0x0001cb8e7b28c331, 0x00065ee8fba04f21, 0x00000000000e42dc}}, + }, + { + /* digit=79 [{1,2,3,..,}]*([2^316]*G) */ + {{0x00060f98795275e8, 0x0009d009dc2f44a9, 0x000392d1d1132d95, 0x000faa2ec5d91fec, 0x0000f160afcbc89b, 0x0007566b5461be9a, 0x0009a2fdd084bb7d, 0x00000000000e4809}, {0x000f69da99c8ac01, 0x000bd1b461fc964c, 0x00012ac0cf0d2b27, 0x000332d9f09a206f, 0x00036941d6ef3246, 0x00087f5f6bde4c0c, 0x00040044ef03fdf3, 0x0000000000057b63}}, + {{0x000b480bf51dac8f, 0x000ea7e485158a07, 0x0002c9e9ee8b46dc, 0x0000dafa6fbabfcb, 0x00038f09fff720de, 0x00006994f04f0158, 0x000d335a0562976a, 0x000000000006e3cc}, {0x000d89d62ca77de2, 0x00045c087ef9c0e4, 0x000f0235509703e4, 0x0004814d916ee937, 0x0008d23d140b4fc0, 0x00062028f3369c97, 0x000adbb0fcd70f16, 0x00000000000e1e28}}, + {{0x0003a6684cfed7ee, 0x00094e3ccfe8dea6, 0x000d721274c869f9, 0x000e2cbb605c4274, 0x0005b0d809923f13, 0x0009913815ee1239, 0x000b6e4dcaea94b9, 0x000000000008c4c4}, {0x000ec88cc6307d53, 0x0004bd7aad54ab94, 0x000859bdd379b119, 0x0001eee68048fd9e, 0x000fd57225fc6eb3, 0x0008dfd3f693842d, 0x000cf13e62cd85a8, 0x00000000000d5462}}, + {{0x000df1c3e7de2ba1, 0x000ff99b5f14f615, 0x000c00e1f8e35232, 0x0003900ff19bf251, 0x0000260925ede749, 0x000ea1eafc82e5b8, 0x00021e3398d340c0, 0x0000000000012871}, {0x000896ddafdbd954, 0x00046ea6dfb0ad7a, 0x00039aa9f60646cc, 0x00078bf1201299a2, 0x000d32e5cebce266, 0x000181e32b5369e4, 0x000add2304eac86d, 0x000000000003d364}}, + {{0x000f357cfbf02e91, 0x000a2f55f868d743, 0x000049d92d19de08, 0x000ff9bbb5ba194e, 0x000957724703bec0, 0x000e0e4fbf7325c4, 0x000d7c5ab8f06323, 0x00000000000ecb0f}, {0x000a0f97049bea9a, 0x00069cc72e8da9e4, 0x000c7a0fc237673e, 0x00046e64252763c4, 0x000eb8d81de3bfa6, 0x000772f007a769ef, 0x000a5ef5ec70031e, 0x000000000002729a}}, + {{0x000cc742f063ab99, 0x0003b51f19bb30d3, 0x000878f139d45b8c, 0x000de2f987112cb9, 0x0008759de2cb5f7c, 0x00049bd98dc51d94, 0x0001fd9d05c410ed, 0x0000000000036434}, {0x00020d69ae77fca8, 0x000a9d7869d68233, 0x00007a8daf0bfe29, 0x0008180c25910747, 0x000a6ebc4ebc7f25, 0x000da1d687b90fc7, 0x0004935565390f3d, 0x00000000000a44e4}}, + {{0x000116432be8131b, 0x000ebb4a2742da3f, 0x0008bb7a8fda7aaf, 0x000adccdd7fcf4fc, 0x000337d4fcc6b15f, 0x0001c7ab70b1fa2b, 0x000cc9242c7b26f0, 0x0000000000050574}, {0x000069eaa2593652, 0x000b76ee50f421b3, 0x000a5035e1a2b7ad, 0x0003af18420501c6, 0x000b1b6e7d2a04d1, 0x000516f80c22e092, 0x0005b5a393be7ee9, 0x00000000000b80bb}}, + {{0x0003f2ad59508de2, 0x000bd9e41b9b6b62, 0x0006d3eb906556a9, 0x0000c8cf272346c8, 0x0005def5749367e5, 0x0002676fcc98a5ef, 0x000659c2dea8afa0, 0x000000000006ace4}, {0x000f1f5cd12db7d7, 0x00090c2b707aa093, 0x000d4cda421d1577, 0x0000fa2a778c20c3, 0x000d57af166b5b58, 0x00078ce62272c3a1, 0x000087e47a64a9ca, 0x0000000000071d35}}, + }, + { + /* digit=80 [{1,2,3,..,}]*([2^320]*G) */ + {{0x000e3ee1ae74a706, 0x00069c20fb9106bc, 0x0005cf0e923045cf, 0x000bc6a5cc0aa89b, 0x000b4fb9f01e12bc, 0x000ae1b895279c6a, 0x00003cbc8e178911, 0x00000000000c2900}, {0x0006736dff18cbd8, 0x000579949d6eb7ac, 0x000931ae3b95e19f, 0x0006ee2dd2275c0b, 0x0008c419f1d568de, 0x0002b5a40a9e4fff, 0x00096dbc759ca4a5, 0x0000000000063b09}}, + {{0x000eafd50b503ff0, 0x00058f682715078f, 0x000b7ec2b450662f, 0x0008f55c51916c40, 0x000b61ee081fa46c, 0x00064872a98c3524, 0x000faa5ab7f2c2ad, 0x000000000007e555}, {0x000425ebf2c1673e, 0x0003c802e0d22c20, 0x0004e9f77f229a7f, 0x00019087af20d270, 0x00016be50784b56d, 0x00072b8518d619e2, 0x00076e10fdbb7213, 0x0000000000049355}}, + {{0x000df2627e9f5583, 0x000e073c57fde593, 0x000f9da9fd5339d4, 0x00071f1cfb9821f2, 0x0009cf6a1d68d25c, 0x000d24e649427e20, 0x0008b5bf3c3916ac, 0x00000000000bda7b}, {0x0001a88dfb057584, 0x000e2e7c5f7c7d49, 0x00071c4b5c378478, 0x000c472e66b277de, 0x0007b2816f1e818d, 0x000383c6d4413fd4, 0x00053740f262af48, 0x000000000004f190}}, + {{0x000aa901e2868cf5, 0x00009d97a9b136f1, 0x000f9d37eb7a3b6c, 0x00060c2548188194, 0x00061d59be44c571, 0x000f2b2474dbdeab, 0x000b33b93a9dad81, 0x00000000000ecbca}, {0x000a766b5fedf0a6, 0x000ce5e1ce82823b, 0x000997bad589b344, 0x000273a2d82b0df8, 0x0006ac8ff52fe716, 0x000ea7ccdb017f5f, 0x00074b7563e79970, 0x000000000003f0e6}}, + {{0x000fda8d824654de, 0x00033487edc06864, 0x00024946c59b50d3, 0x0002bea10fdba0ce, 0x00052c3dbf337fc6, 0x0007d2a46c836bbc, 0x000f714fdfb5c34f, 0x00000000000dca0d}, {0x00024bebc7614440, 0x0007730a0767544c, 0x00067fffd43f5d03, 0x000d49dfacc13dc4, 0x000aae1a261ad307, 0x000d98650148d673, 0x000fdee008f95b52, 0x000000000009f558}}, + {{0x000015df21e067c3, 0x0003dd084564b8db, 0x000d0b4c4a73b501, 0x0004bf63bc7206d7, 0x000ffc3d577224bd, 0x000c4924fdd37b4e, 0x00096e8156d6f635, 0x000000000001d1d3}, {0x000ca9d7511fd3e1, 0x0009d977b3b3982e, 0x000fc4c09646cd37, 0x000f9c4ae811d70c, 0x000ca06c7f0de581, 0x00049d87fe5441d5, 0x0009bb0275c92b19, 0x0000000000078046}}, + {{0x000cdb7d87948ad3, 0x0009117cd6af6151, 0x000e60b294f18979, 0x0005b1d788224330, 0x00031b9745257e49, 0x000f3ce21fed338e, 0x000896527743d386, 0x00000000000b515c}, {0x000e2d7dc921023b, 0x000d19fde7038e85, 0x000c1b9c9ba2d99f, 0x000600b36ff74dd6, 0x00048302c3c95d46, 0x00044b5eb8ea74b0, 0x000402d560f570f7, 0x00000000000fe762}}, + {{0x000cf97b63daba80, 0x000eea7f8501424f, 0x000f397f945052f2, 0x0006b8a2ad5053d9, 0x0003fbcebe43c658, 0x000054f1688c09a4, 0x00047fde7f2a4a20, 0x00000000000bbbb1}, {0x00041659e06114fc, 0x00075087e48f29cd, 0x0009df479d6378c0, 0x00002ff7f27cac87, 0x000c37b1f6e18ae8, 0x0006d1deab01a131, 0x000f803f0d4c2e9a, 0x00000000000e7cee}}, + }, + { + /* digit=81 [{1,2,3,..,}]*([2^324]*G) */ + {{0x000643c3f46ade04, 0x0007aaa03b473d97, 0x00091126d04a500a, 0x000ef86f37b57bd6, 0x000b2a6371d2b286, 0x00077ccbd95b797e, 0x000a6da489ef8940, 0x000000000008e99c}, {0x0007980fdcec94f4, 0x000845cf9e236463, 0x0000b4681fa85d18, 0x00023b6ba7ba4781, 0x000757de30bf3295, 0x00036ca01d406ab8, 0x000ac5aa10e4a215, 0x00000000000dfa7a}}, + {{0x000146df48d94f2a, 0x000a9762a5eebd68, 0x000728ae94bf3482, 0x00034aeaa4f964b4, 0x000ed6526f010fd5, 0x000d71d72cf46648, 0x0008eabc62a54a18, 0x000000000004f848}, {0x000d9dd392598cb3, 0x000a262c40de70e6, 0x00099451ce04b75f, 0x000d7466ab190976, 0x000b2dd1ad3d3a51, 0x000f88078f07bea4, 0x00035d2a0ec4672e, 0x00000000000664e4}}, + {{0x0002f7cfce391389, 0x000d017c563bd4e7, 0x0006d61076868226, 0x00049ac4cd1bfc15, 0x0000d4e53d3b591d, 0x000079a6ed446551, 0x000eb4ca95ccf6ad, 0x00000000000b5ea6}, {0x00099522fba1cf25, 0x000cd600ccc9ba8e, 0x000c729701bdaf25, 0x000edc569c6c6e81, 0x000a586abcdc5f27, 0x000dbc5b6b3fc0f4, 0x000fe0dbfdf3f985, 0x000000000004ea80}}, + {{0x000e7847d76787ae, 0x00083ee6e7005dda, 0x000646f5e7ea8d16, 0x000df7dfc45111c8, 0x0001875c23c8373a, 0x000039d490c7535b, 0x000a062a7e04f897, 0x000000000009afd1}, {0x000cbb06099a2183, 0x000fb049dd385881, 0x0008a6ac539cc7cc, 0x00057b9925498c29, 0x0002da25daa3dce0, 0x000decb7d7b9c9bd, 0x0006ef6d0b70a3d4, 0x0000000000003df7}}, + {{0x000405f3ffe95388, 0x0004eff54e8bb8ae, 0x000ad0d572466c0c, 0x0005bc4ed1fae2ed, 0x0009ea983db1b226, 0x000851454a5e23c2, 0x0005064af5f55909, 0x0000000000036eb4}, {0x00062710e23e547f, 0x000844c72b2d0dfe, 0x0003b7abb313e4c9, 0x0008ad4e19c9c269, 0x00053e8b8004b1aa, 0x000c747fdb9cfea9, 0x000e4107782d788a, 0x00000000000ce9d9}}, + {{0x000aeca3f9d9a2f2, 0x000f8779905b5deb, 0x00064a28a88ba6a4, 0x000f0aa679096dc3, 0x0000f558913cce9a, 0x00024a2e2fdf04f1, 0x000b3505300cb06f, 0x000000000005d581}, {0x000679a2a74abdaf, 0x000aa855c8de8c32, 0x0000f6e26bb556cb, 0x0002a4197740d667, 0x000744c9360d6761, 0x0005cc8807588a52, 0x000188928ac91032, 0x00000000000acdd3}}, + {{0x000ac6fa45a00390, 0x000933774af3674c, 0x000bcfd34179ae6d, 0x000205ec11875399, 0x00018799c22ede45, 0x000b0842ef3b1144, 0x000d64fd53f681e8, 0x0000000000066d36}, {0x0007de25fd86d3c2, 0x0009ca2c3391c37b, 0x000760d08855c7c1, 0x000fa4a6ab8ab4bf, 0x000bd841a6234df1, 0x0000b189a2b0cd34, 0x000da752441d79b1, 0x00000000000fa025}}, + {{0x0009e3af5a1f4313, 0x0000c3c6c56185fb, 0x00083406c1a4afdd, 0x0009c90ae2fb830d, 0x0003ec31a504b325, 0x0006230bdf7cc6e4, 0x000e3a83bb13c612, 0x00000000000ff1da}, {0x000c261cfaa4903f, 0x000010cc6c1a44f0, 0x00029f13aa21ef15, 0x000c75fe604a58e6, 0x00012491f872d454, 0x000e116a5ceadfd9, 0x0004816c5575da9c, 0x00000000000b24a4}}, + }, + { + /* digit=82 [{1,2,3,..,}]*([2^328]*G) */ + {{0x00087efd2e620105, 0x00045c5ad791e85f, 0x000885fe6de88f7b, 0x0009e4998544bc47, 0x0005d273c360673b, 0x000a75a8c934d8f5, 0x000c977fb48d0768, 0x000000000005e0fa}, {0x000ee7923fcfedee, 0x0000dbe01655fb13, 0x0001ed409cde6661, 0x00030de533251391, 0x0001de9f3fc574f8, 0x000e01fa5a724033, 0x0004b496b25206a7, 0x0000000000007eda}}, + {{0x000a5e409b41a55f, 0x000283e6e9380f21, 0x000bd6398225ced2, 0x000c8b4b843ec071, 0x0002af8a23f1f2d7, 0x0007923350055d88, 0x000e74e848010ed3, 0x0000000000055e08}, {0x000839aa213ff6af, 0x0003d956ea8e93ca, 0x000299a04653a35e, 0x0009271cca1b5491, 0x0001f1d0b7f15f7b, 0x0009963fbd41d228, 0x000cd8b187047b5c, 0x0000000000002536}}, + {{0x000a16fe10008718, 0x000fd7138a03f4b5, 0x0008b9afc3d67514, 0x00041fd2a7cbcc17, 0x0005f6073ecba29c, 0x00004fa086014349, 0x00053298b46d3805, 0x00000000000401f9}, {0x000b314f178aa1e6, 0x0009808cc4abc63d, 0x0005190f1545e910, 0x000c8faa75d9af1b, 0x000fc2e5592d6eb2, 0x000468e666f50198, 0x000fc3773b9d55c0, 0x000000000001a2a9}}, + {{0x0004cdf21adad97a, 0x00008e51a956ff23, 0x0002a26288680976, 0x0000fa2f974d2cb8, 0x00074c6a78dec616, 0x000c89d11e00474f, 0x000133ee916e510a, 0x00000000000f826f}, {0x0002a0e3be0ad710, 0x000103fc65d3ecf2, 0x00089ef785c9b19a, 0x000a82e0b9196b29, 0x0000a572b6f55237, 0x000bed2bc4975e68, 0x00025e41ea8b92b9, 0x0000000000098268}}, + {{0x000bc901bf39d0d3, 0x000fae352fb9c164, 0x0000b33959aa5988, 0x000ce6fafcb7de1c, 0x0004f694cad0f9ff, 0x00061d6110e574cf, 0x0005d8adb4671cb7, 0x00000000000c8aa0}, {0x000b2a78a9127846, 0x000a987cd7872df6, 0x00010a813ed5d7a6, 0x000531ec2cb43e23, 0x0004b9e6b89f1c41, 0x000e5d4d262fc310, 0x0001dd7f406a0dc4, 0x00000000000df3f6}}, + {{0x0005300bc3a99814, 0x0008c06f721d246f, 0x0003df2a36c6f8d6, 0x0006b7a5a44ffdab, 0x000915764390c5ca, 0x000747d7dc53e328, 0x0001227f16917459, 0x0000000000061f79}, {0x000965ef8eb0e108, 0x000ae099f4e3a08f, 0x0009b651d265b539, 0x00043576b72f3285, 0x000cc33695bd270a, 0x0002249029d6bb26, 0x00051f60f9202126, 0x00000000000e1b0a}}, + {{0x000bf8353cd33783, 0x00086265d4eff002, 0x00010092c6e845e0, 0x0005c996be6ce254, 0x00096b6056eec399, 0x000a007266fd43e5, 0x000fb1d328c28f28, 0x00000000000f719a}, {0x000f1e2a3462b4c4, 0x000fb75dcabd2f96, 0x0006c939c482a7c5, 0x000a522d764ab7e8, 0x000dcf8a487267c6, 0x000810a449458c96, 0x000786af1af61b78, 0x0000000000073902}}, + {{0x000b7c441c7f3df5, 0x000a88a390dca834, 0x0004f92ea9440c60, 0x000ea69bc5e82f15, 0x000d4628d6f177bb, 0x00068e24071f02e2, 0x0000ee6260790cf9, 0x0000000000066527}, {0x0001df8e5c25d23a, 0x000f233639544be6, 0x000c37cf5bac2371, 0x0000f867807ed557, 0x00019dfa452c6906, 0x000d27c0d1b0ac01, 0x00090cbbdb25fe06, 0x00000000000a60ef}}, + }, + { + /* digit=83 [{1,2,3,..,}]*([2^332]*G) */ + {{0x000957058557b81a, 0x000dc1877dfd042b, 0x000fe0adb79e32df, 0x0009536c78e295f6, 0x000374a04cc59d08, 0x0007f75edcbb5d55, 0x00078ce366600682, 0x0000000000061e73}, {0x000dd46741146ae1, 0x0000a74170170ac0, 0x00052de550198353, 0x00030f8ac1c4a0fc, 0x000d3cd92824d75a, 0x0005e86d4d7e7be0, 0x0005ef5ea0abdb1b, 0x00000000000b3b61}}, + {{0x0003f4e13d621f8b, 0x0005a618ca06b4bf, 0x0002813dfa928efe, 0x00072cca3b6ce7e1, 0x000e5f14bb579813, 0x00073abbbb44a68e, 0x000c0afc1167e963, 0x00000000000767d4}, {0x000277deb88a4f9a, 0x00077c6dcdfeb3e6, 0x000664e1fd3b5c4b, 0x00001aabfcbf2f89, 0x000a67aa82774775, 0x000aab9cd0be7228, 0x000b4a5de7b8331d, 0x00000000000262fe}}, + {{0x000cce85ebd04b7f, 0x0007f7a9623b5682, 0x000f8d813f260bd0, 0x000dec9e0f8e530f, 0x00091d65dcd4f8a5, 0x00039541c88bcbe2, 0x00097a09fe380367, 0x00000000000e716a}, {0x000184fc8c1d72cf, 0x0003bbd8e34de924, 0x000a19b51363e270, 0x000d905351941206, 0x0006f7a3c4830183, 0x0003557396345099, 0x0002f718283cea01, 0x000000000009aaa7}}, + {{0x000a56eb624d0cf2, 0x0006a7b7da0287f4, 0x00087c61d1ede60c, 0x000d83c51f3dbd9c, 0x000fa91d085ac056, 0x00035262de2f4d46, 0x00029e31759c9ceb, 0x000000000000c9dd}, {0x0009a41b82bb0c12, 0x000e8108cf9ba936, 0x0004fc5060b7103d, 0x00016b273d372b32, 0x0007d5415e53f698, 0x0006b8b0e126575a, 0x000a5e546bb4c130, 0x000000000004d54e}}, + {{0x0002c932a7c5abec, 0x000a881dd074d9bd, 0x000f76c734b204ea, 0x000e1f0352b58f62, 0x00029c390eefb5af, 0x0006a8d236d2d948, 0x000be5d073f9a0f3, 0x00000000000466eb}, {0x000118cb3dd8d87a, 0x0004d968c04a5c76, 0x00007c8586d1cdac, 0x00096bb15c0970b9, 0x000370ab8dda98e1, 0x000039fa92af28ea, 0x000ff6b912fbda7a, 0x00000000000cbd02}}, + {{0x000e45ea08b7c4d8, 0x0001d5bcf28785c2, 0x000fc63d7c5e8cf8, 0x0005de6707a7138f, 0x000cfb2041a48868, 0x000db3060a77646d, 0x0006908608695289, 0x00000000000e27a1}, {0x0000f0b051870cd1, 0x000794148d936eb2, 0x000a4e50dd50fda5, 0x0002d4db0391d14a, 0x000462b0373f9d72, 0x000a9992c5683112, 0x000b8487b0363be9, 0x000000000008853d}}, + {{0x0002c578f8f683b4, 0x000576c8e5a2524a, 0x0007522f4370ef9a, 0x0004aad50ad6f3a6, 0x00051f107e269b01, 0x00051bf732a3933c, 0x0006df4b04395cc9, 0x00000000000b0ef5}, {0x00017d2e75e44b21, 0x000cd28c9fcdca32, 0x00061a5012b72649, 0x000f58e53ace23e2, 0x000efe688f02b546, 0x00091406dee5fec4, 0x0004d9d8b43f6d2e, 0x0000000000026176}}, + {{0x0002d2ad73a4790a, 0x00034daa7fcc985a, 0x0000276056234a54, 0x00018c59894edceb, 0x000da9ac29a7fbf9, 0x000372f2c470c45e, 0x000d3fdfd44f6fbc, 0x00000000000a1e38}, {0x00009dd8fe96aa5f, 0x0003923d2400aaad, 0x000c441c1c12013d, 0x000488148baa4ac3, 0x000ebc26e6b0c76a, 0x000ef566273227e4, 0x0002bbe732edcfe8, 0x000000000000c566}}, + }, + { + /* digit=84 [{1,2,3,..,}]*([2^336]*G) */ + {{0x000d5d97020dd4a2, 0x0005087c7dd7d118, 0x000d6556f04f9110, 0x00048789fff00158, 0x000b909eaf1abcbc, 0x000443a788ffcef8, 0x000fed9905f4eef1, 0x00000000000e15cb}, {0x000831894b4ea50c, 0x0006cca2969ec57b, 0x000ae2b1ba048b54, 0x000fab787ea6e3a2, 0x000ff98c4fe567f7, 0x0009cb91e0d0ee10, 0x000ab4c646879ac1, 0x000000000007d1d7}}, + {{0x00092725c84d0435, 0x00013cfbcbc49b56, 0x000166c387130162, 0x000e05622322f91f, 0x000a7662ae23735d, 0x0002be7a6d2590bd, 0x00017263d468fed8, 0x00000000000695ea}, {0x0005986e2611645f, 0x00050c50f4940fa9, 0x0003729def8820a9, 0x000cd041fd257785, 0x00044a3d0808680c, 0x000684cba25ddac4, 0x00088841d8b738c4, 0x0000000000053963}}, + {{0x0003a8028963f3e3, 0x00076b05cb83426c, 0x00074bc4cf79f053, 0x000b5aaefa9e4f0b, 0x000d9bd075ecf023, 0x000a41bfbb8061e5, 0x000d967d2ba50f1a, 0x0000000000090865}, {0x0004ae64b7cf3e16, 0x000d97f221a788f4, 0x00000b032e3ccff2, 0x000eb6af6ab15418, 0x0004dc87cd93085f, 0x00039dbf6fd14102, 0x0003643e196fdb32, 0x00000000000dbcd5}}, + {{0x000d4ecde2fce0e7, 0x000891466c9f4fd3, 0x000b63a0ee692739, 0x0008c75b58655519, 0x0004e65862cc291e, 0x0009971671ddb715, 0x000c19285153bc2b, 0x00000000000954b6}, {0x00039e1aad688b1d, 0x000e0985d4505697, 0x000559cd349baa64, 0x00098dafa5fe5e6a, 0x0006f90f231d39e0, 0x000afd0b53fc2604, 0x000c18de5d5ced32, 0x0000000000060c09}}, + {{0x000b1d0586854e54, 0x000cf3720b17188f, 0x0005eebb9c78a9a7, 0x0006e315b54eefca, 0x000472b0edaa03c4, 0x00077476e387e466, 0x000259fc59b03dee, 0x00000000000607a7}, {0x000e6b356394b5a7, 0x0008b1478bceddaf, 0x000e3cdb4ff0323d, 0x0002f72cf272ee0a, 0x00038bd885cd7127, 0x0006ba31c19e3a4a, 0x000b369af6415b37, 0x00000000000807b2}}, + {{0x0008b39051ba2cdd, 0x00030dbfcfa7593b, 0x00015a46addd3783, 0x000851d67a19b610, 0x000431ae1a67cc6c, 0x000d1e135ace88bf, 0x00090a74554a6193, 0x0000000000042118}, {0x000bd87496a1468e, 0x000277cb3268907e, 0x000047feb42207f2, 0x0002c21766e72f3c, 0x000a880642e30a67, 0x0004d2b3624bb718, 0x0004ab425dc41d18, 0x0000000000089102}}, + {{0x000caa1ac9c2c636, 0x000673180789b5d1, 0x000d386a756090c3, 0x000b895e99e922ea, 0x00003d0bbe807951, 0x000fe79c0987ea25, 0x000d2a6d2f49f0e2, 0x00000000000c2b18}, {0x000ed8226be989ea, 0x000d8707798f36cd, 0x000ebf8dc541b02a, 0x0001e32bc4479412, 0x000938a845f346cf, 0x0005e5d924dfc145, 0x000c3f210083fe45, 0x00000000000a1fed}}, + {{0x000faea0d2bc54ec, 0x000a972fc8198080, 0x00029736c6c3c3d0, 0x00098bbd99e30373, 0x000a0efddfca3691, 0x0009147416b68390, 0x0008078c35f3e4f0, 0x00000000000ca7d7}, {0x0005a76575b0ee6c, 0x000e9564d991dc4d, 0x0003cf033490be81, 0x0000dab5d635893d, 0x0006f944e49a51f3, 0x000233bc00427e34, 0x00093e1e0bf1b56a, 0x00000000000617bf}}, + }, + { + /* digit=85 [{1,2,3,..,}]*([2^340]*G) */ + {{0x000129009060318c, 0x00056d23658c8428, 0x0004596f83a71a5a, 0x00010ec082210f1b, 0x0001bfc364906dab, 0x0004f2d14fb1add9, 0x000443eda8b02f9a, 0x0000000000056560}, {0x0004169ffc0d0413, 0x000986c01479d686, 0x000d5173dbdf44ef, 0x0003c1d718883983, 0x000e13c34fd24dcf, 0x0000c15ac87a9c04, 0x0005d2fe0e08ec51, 0x00000000000c0f49}}, + {{0x00099e97b82e73d1, 0x0005db097b2c50cb, 0x00071fe923d57f3e, 0x00066e9420996453, 0x000eff7290736382, 0x0008c394043d059d, 0x000925eebb5fe114, 0x00000000000daa8e}, {0x000995963e49eb67, 0x00007f43c78d7e6f, 0x000a34a7c03b2d6b, 0x000a7d66b6363576, 0x000be096a954cdd5, 0x000afa2fc8b70a2e, 0x00095a011d5419d0, 0x0000000000004fb0}}, + {{0x00033bb61172fb0c, 0x00008eb05c51603f, 0x0000d435c61a818f, 0x00073cd489576f54, 0x0000535a8d57cfd5, 0x0001436c4e653538, 0x00022d1394731467, 0x000000000005f0a1}, {0x0007992fb047bfc7, 0x00099aecc7ec110e, 0x000e8ab91f3e896f, 0x000f6523d4221aba, 0x000f2851996bdf96, 0x000cfb67efef5649, 0x00005246fb9f26d5, 0x00000000000ef5c4}}, + {{0x00016ebee78befa2, 0x0003188e7ac8d2f0, 0x000b37c50c491499, 0x000d52918be419b3, 0x0004c057621c3b96, 0x000e57e597e75e35, 0x000463cb1b709f5c, 0x00000000000844f2}, {0x00053157dde1a349, 0x0006d53608198549, 0x0000450e27f360c3, 0x000d348e04114157, 0x00004d73eeae6dd0, 0x0000ed85e5b28e95, 0x000b580843923269, 0x000000000006da14}}, + {{0x000ce0f0a89b6284, 0x000735cbdc4424ba, 0x0003b0cbdca1bfb5, 0x0006886c118d02b1, 0x000675aaf27658a2, 0x0005f6ec187ff74e, 0x000d32b133be95f6, 0x000000000004b1b8}, {0x000fda7aaf38358a, 0x0001bdd8a8ef25a8, 0x000eba5b65bc2a4f, 0x000a6db26623fb02, 0x0000bae15453d525, 0x000f89fc9f2368d4, 0x000a3e55d6a84d84, 0x0000000000086021}}, + {{0x0009f5565cd739fd, 0x000f210520b26d6e, 0x0004ac2940ef5ddb, 0x0008ef88948f78bf, 0x000550ad452e1246, 0x000c4847040a9d27, 0x000ace5e382347c1, 0x0000000000033e73}, {0x000c8b4278956db1, 0x000437d83d02e97a, 0x000af99c625baa1b, 0x000d448885679e6a, 0x0005fc95919c6716, 0x000c2194a0e12bdd, 0x000d2d7da4420492, 0x0000000000015ffc}}, + {{0x000c11f07976d090, 0x00025bd048bdc85d, 0x0003c8a142cbe0e8, 0x000a758a985ac100, 0x000cf2c7ace940aa, 0x000ec347d6039bcd, 0x000ab7712092cc6a, 0x000000000006b5ac}, {0x0003db66ec59bab1, 0x000551ebcf80c829, 0x000fffebfb9d4dbf, 0x0003d1ad0b610f09, 0x000498c28ac73fdd, 0x00059750fdd3f6f9, 0x0001ac650b77943a, 0x000000000002d399}}, + {{0x0001cfefd0dbceda, 0x000826cbd2756691, 0x000e925943cf3919, 0x000aa0be4c58c7c2, 0x000f0e488784177e, 0x000916b0f603551e, 0x0002e2c8eba131df, 0x0000000000015973}, {0x00008eec1292bc0e, 0x0000355acca849df, 0x000e7c404ec832b8, 0x0002c703bd3b202e, 0x00056ddd8eba162a, 0x000b1d93d4c5e5d2, 0x000dcf66e7844a77, 0x00000000000110b9}}, + }, + { + /* digit=86 [{1,2,3,..,}]*([2^344]*G) */ + {{0x0003ab751954f075, 0x000f91b66faabe09, 0x0001714e51539902, 0x000f3a0a675f7c8e, 0x000f30313a711a82, 0x000aea9e682884a2, 0x00005d7ac5d7b058, 0x00000000000cd5ff}, {0x000d5d715b7b74ff, 0x000287c29638d05f, 0x0006736db974b38e, 0x0003c47a17ae3a7c, 0x00077009e38ae85e, 0x000f9c52e91b107c, 0x0008a0f3b777d8f1, 0x0000000000011b68}}, + {{0x00072d048b012b70, 0x0009a4ae3d232353, 0x000ebed55756fa98, 0x000c769ec62fd6b0, 0x000f62a4720cba73, 0x000c1f491d586ba7, 0x0005716497cd140c, 0x000000000007b2ac}, {0x0007af894008277c, 0x000b9a65eabb5e68, 0x000cb737865439ae, 0x0001b84231457d7c, 0x0005901645c525b3, 0x000f7b656cab62f7, 0x00095c2377d74db2, 0x000000000002d33c}}, + {{0x000e54e4ebfecf4f, 0x000b310105dfc241, 0x0000ded90576b5a5, 0x00068324e80fc085, 0x000287dc7da6122e, 0x0004728cf3b26e76, 0x0001297bc183de6d, 0x000000000008bcdc}, {0x000bafda0190b71b, 0x0005d8b995cec24c, 0x00099629f2c641a0, 0x0009e6b4da5b77d0, 0x00096caf9161612e, 0x000f45eb68ec048a, 0x0000e9e3628ee2c7, 0x00000000000d8565}}, + {{0x000dc37cf3c258c7, 0x0005aaae2f447f93, 0x000c6f7663c30e3d, 0x000b2f482c1f372f, 0x000d351a5f7f3262, 0x0006c75a85521feb, 0x000fb8f8ec919091, 0x000000000002728d}, {0x000f483180d24d43, 0x0005f5dd4ff4f0a1, 0x0000b042bcddd9b8, 0x0005b98ba8b777b7, 0x0006fb7f8409318b, 0x000fd31dbd971d42, 0x000347ed1465e8b0, 0x0000000000000f66}}, + {{0x000f5311360afd40, 0x000bacea0374a33b, 0x000feb5ded889fab, 0x00002361bb01f474, 0x000a8c328b8bf6ce, 0x00053d6302a5b28b, 0x0005d86991b1d8b2, 0x0000000000085945}, {0x0008eeb3e3866a93, 0x00024f5c6e141989, 0x000231ed9c304f2e, 0x000032f67e76ece0, 0x0002338980594eb4, 0x000001b765bf14aa, 0x0001340804a7c00e, 0x00000000000734cd}}, + {{0x00036d45a9f2195d, 0x0007e5ba5288b70f, 0x000e413923c56371, 0x000a997602f3c65a, 0x000fe08c0223c1a9, 0x0007e6f1dc5c7512, 0x00059748a19c3c36, 0x00000000000fb241}, {0x0001d161a9f86145, 0x000879f674a5f0bc, 0x0001526754b42988, 0x0008c4303d6f13ed, 0x000d917433fb5aeb, 0x000f534900fed575, 0x000616e4a5ef9a59, 0x00000000000f315e}}, + {{0x0008596b7b07e015, 0x0009c7059c585ee9, 0x000cfabffa6395f2, 0x000d9318d9633cd0, 0x000f37bda14896dc, 0x0008964dcb2abc44, 0x00076ce31adb3feb, 0x00000000000e3168}, {0x000ed4ab82ecfd95, 0x000363173288028b, 0x000f24a3fd6c4552, 0x00034c91d6f69add, 0x00022c34e118b5b3, 0x0005984ede613e56, 0x0003a18bbdbf5c5f, 0x00000000000cf4f6}}, + {{0x0008f4401a1165b4, 0x000b4315ad7a4644, 0x000672c1b06e4df0, 0x00097a8baa564733, 0x000446edcfcbe12f, 0x0001a968ef263db4, 0x00087547cf91d53c, 0x00000000000c15db}, {0x0007f5c515f16ba5, 0x000345d35e53a1e8, 0x000a90f359724b01, 0x00011ea246da3d37, 0x000653f068205d3d, 0x00010c00fc1ddfcc, 0x0008c78169d71166, 0x000000000004bddc}}, + }, + { + /* digit=87 [{1,2,3,..,}]*([2^348]*G) */ + {{0x0005418902e018d8, 0x000328002f4583b6, 0x00029b160f5eca39, 0x000d112fb93f735b, 0x0002196e3084a8ce, 0x000e8c74427cb629, 0x0005ff72395bdd77, 0x00000000000ee71f}, {0x00030cc165e06d5c, 0x000ca7cfc14d95b5, 0x000ac1b9673d9545, 0x0000129d213738ef, 0x0001bc0b5ea366e5, 0x000a067007a905d9, 0x00082192cb630afc, 0x00000000000bf3a0}}, + {{0x0009c76f27cbedd6, 0x00086e96c4aebbe2, 0x00087447d6551831, 0x000d2f632f9151d3, 0x0004302b99e2f86a, 0x000fd317105daf87, 0x000c624299dbfa14, 0x00000000000812cf}, {0x000ccd383b8a542c, 0x0001b42e615367ce, 0x000e792323a5de78, 0x0006c70548fffa38, 0x00077b6db825c34c, 0x000f2989e1fbed77, 0x0003ee850bded44e, 0x0000000000081546}}, + {{0x0008bd3d7d2dac19, 0x000ce352e14371a1, 0x000574a96d5757aa, 0x000d9395a7b7719e, 0x000b8544328b64d5, 0x000f9c5934d5197b, 0x00045e5220626522, 0x0000000000074d6a}, {0x000ed277c567a2e7, 0x00003f52c9eeb86b, 0x00037cef0ab9cbea, 0x000b3bfc9ed39349, 0x0007a14c3d70e606, 0x000db5876fc5046d, 0x0007a181cd053e5e, 0x00000000000a3034}}, + {{0x00026a12e217941d, 0x0008a9decf2164e6, 0x000546598e5e9913, 0x0009ce8aeb36b93a, 0x000158fb4dc8d564, 0x0002d60cfab9f77d, 0x00061966b11fb6b5, 0x00000000000eaaa4}, {0x00098700891e3d12, 0x000dbf3522a998ce, 0x00034cf7624bc215, 0x00097c625e387237, 0x00072d4595ee2679, 0x000e5456ced5047b, 0x0006feaaa41e5f55, 0x0000000000078cfc}}, + {{0x000abf51b7538110, 0x000353fd75579f7b, 0x000019e5c13ce4a6, 0x00076854d208bb77, 0x000ac1c9512f4c82, 0x00081e9f3941aeb9, 0x0003396ce0bed5a1, 0x000000000003744a}, {0x000bd7c923f4230a, 0x0006180eaff7a041, 0x000dbb73984381c7, 0x0007c1b0f8e7fd8b, 0x000aaf499630f16e, 0x00080a16856bdddd, 0x00012be8c112df11, 0x000000000002987f}}, + {{0x000b02027989cfc0, 0x000a60ce9ab12f61, 0x000973d1a5ee6cd8, 0x000b3b69a1753a9f, 0x00002bae5685f031, 0x000d3c06632160ba, 0x000f5cdfde9ae80c, 0x00000000000a180c}, {0x000f0a3aff152330, 0x00023e2c194158b5, 0x000e1481b10c0c49, 0x000e7d12ea20322e, 0x00007968c7ff67ea, 0x00027bab93eb507b, 0x0006eaeb300ff9ce, 0x0000000000097575}}, + {{0x000b71b2ec924484, 0x00007325de655ef5, 0x00027d8f4ae5da5e, 0x00026ad89e4c34bb, 0x0000ec5a615fa909, 0x000c770ac8e61adb, 0x000f8a5a2233d43f, 0x00000000000cbb23}, {0x0003b01804f61225, 0x000a4a7e6c5861cf, 0x0004fcae81492249, 0x00040be697e7dc09, 0x000eb6f29135b0f3, 0x000e89899783a7d0, 0x000f55412469b007, 0x000000000001bfaa}}, + {{0x0003c3de6d71b673, 0x000cca438634e69c, 0x000f00cb40863203, 0x000dedfac40dd56f, 0x000e4956a5de2ab4, 0x00013f84d758e95e, 0x00016cfc11e39451, 0x000000000006059f}, {0x0008f87a862c83c5, 0x00038fd8e2236750, 0x000df4ebd7b9092c, 0x000b1538ea13b455, 0x0003013d382702ae, 0x0009ca201de1275d, 0x000351470a7b7e65, 0x000000000005c77b}}, + }, + { + /* digit=88 [{1,2,3,..,}]*([2^352]*G) */ + {{0x000bd58c2fd385c4, 0x000d8281f6e58982, 0x000c3afee2ff7056, 0x000a41afd89abd8e, 0x00007984feefe29f, 0x000d20a64fcb0b0b, 0x000cd50b0928a6d9, 0x000000000006979c}, {0x0008ab27cda5c7bd, 0x0001cce9c34c7521, 0x0006dc0b027875db, 0x000635250946a5c3, 0x0006f39f53b9d464, 0x000bc8b64b09a97c, 0x0000d61d47bc20dc, 0x00000000000d458b}}, + {{0x0004b16a9cc79c48, 0x00075763e36638c9, 0x000ff772bf788245, 0x00011a8c66b40e9f, 0x0008f384b70862ab, 0x0001978760624469, 0x000837e7cdf3bd69, 0x00000000000064f8}, {0x000fbc5f9be69c3f, 0x0007895900a21f89, 0x00053a9326cbd6b2, 0x000fbbddd3e6e471, 0x0006baa2e2a03f65, 0x00085282484f52e0, 0x00032c1dc462a8e3, 0x000000000007e4c0}}, + {{0x0008c150b5ec2626, 0x00094cc580ea6853, 0x000526b13f535e43, 0x000604fb23480cfc, 0x000a344146898665, 0x00010a94595787cb, 0x000c78425d7c6f4d, 0x00000000000b2f1c}, {0x000940b59f5f9db6, 0x000f455da8884e6f, 0x000468b788890b3d, 0x00081d7d99e417f5, 0x000abf28fba2c648, 0x0004eff801eeba5a, 0x000fb720feb7b350, 0x0000000000050deb}}, + {{0x0002dafb4e000df5, 0x0009720ebf79c9aa, 0x000a041b02faa426, 0x00007e78d630d2b3, 0x0007fa605dcb016c, 0x000d0470520021d5, 0x0007e66190f3e942, 0x000000000008974b}, {0x000bb7ed0e0135bf, 0x0003b6710da6c4cb, 0x00011bda556d9709, 0x0004b8ba583089a0, 0x0004ea7dbcdd192c, 0x000df1097171ab8c, 0x0000ed715f60818c, 0x00000000000205d1}}, + {{0x000c0f09863d151a, 0x0004b4a6226f970c, 0x0004a88f8872d167, 0x0002e60a1193cac8, 0x000543dda270b44e, 0x000d647382ce6393, 0x0006751a9e8a2138, 0x000000000009d843}, {0x000abb28a3b6891b, 0x0008a98a1222e3ef, 0x000341bb8ccbdd0d, 0x0005be5555088026, 0x00017b38f0648047, 0x000e249f5c39ccd9, 0x000b74ea31304de8, 0x000000000004d42d}}, + {{0x000330dc4e7217de, 0x0009c39a689bbd9a, 0x00001ce7a86200c3, 0x000108a8d29457b6, 0x000014ed4b4dcf33, 0x00015625f312612e, 0x00063bcbb21f3451, 0x00000000000303a3}, {0x0009f7756d9dff06, 0x00004aeb0c8c0639, 0x000d964999e9958d, 0x0002604683b37dcb, 0x0007862b08477a02, 0x000d69390fa4ced7, 0x0003145a49bdc136, 0x00000000000c0215}}, + {{0x000155abc265f191, 0x000f0544874b6521, 0x0007a036ebfb6d29, 0x000afd631411ba1e, 0x0000466d6415b303, 0x000d4c2de30047aa, 0x0007b13a1b676594, 0x000000000002860c}, {0x0008a20d9745d768, 0x00046fe140a72d14, 0x0007d03c948ac2bf, 0x0006df9f46f144f8, 0x000bc0defbc46c9f, 0x00024c075f7e7b95, 0x000c39fbc9a96978, 0x00000000000d7773}}, + {{0x000f0ec4d363b0b7, 0x000bdd2db4d34f56, 0x0005740dc154bacd, 0x00065cc723a57c02, 0x0007d8ded62c4475, 0x0002f1a9ed98c359, 0x0003b20aeac6d9de, 0x000000000000a98d}, {0x0004a99c9e88ef97, 0x00034d9708f06642, 0x0001bd570d037e70, 0x00032cf49cda0113, 0x000a858467e24993, 0x000748e8e546df74, 0x0000738b84a55093, 0x0000000000006f09}}, + }, + { + /* digit=89 [{1,2,3,..,}]*([2^356]*G) */ + {{0x000f37fe6b03f897, 0x00052c0a40cabe70, 0x00091f1b94fec55b, 0x000898c340187426, 0x000636d9e57a8625, 0x0008aa21169c9f3f, 0x00016869d9d7f337, 0x00000000000e7dca}, {0x000214154225907a, 0x000ba24d49aebb77, 0x000fbddce2036f3c, 0x0001d01576f533f5, 0x00099ef82ece667c, 0x00007c14d372eee1, 0x0007f6577723c0c2, 0x000000000000eed3}}, + {{0x000850ebff25b818, 0x00013c61db976bce, 0x000a1c9cf36381eb, 0x000b8ca060b1adcb, 0x000188e2c178ce89, 0x0003bdd3c41db448, 0x00042cba6339f392, 0x00000000000d29db}, {0x000bbd1437baf649, 0x000f53521116eaf1, 0x0005d6c8cce9ea0c, 0x000c984bd79fe5d8, 0x000e9d45eee49357, 0x00088e01f2eda73b, 0x0008731a50c59f62, 0x0000000000075018}}, + {{0x00038b1bc1ced6c1, 0x0004df323953ab33, 0x000a2512b2fa2401, 0x000dfd9bd32cb8d7, 0x00037ecf35382937, 0x00039941507c4e56, 0x000a06b573960eb6, 0x00000000000dd1a4}, {0x000a33b92253abc1, 0x00050c625f400562, 0x000bec6e4c3f3a23, 0x0001e5b6220f24df, 0x000827d01c6f66c5, 0x00012372d9f97d75, 0x00004860b1572404, 0x0000000000004d55}}, + {{0x000a3b570044f6d8, 0x0005fc552c6c6093, 0x000f9e99da8c0559, 0x000375c19610b0cd, 0x000bb051dad5c9ed, 0x000556643f0e7b4e, 0x0001d87267a304c6, 0x00000000000c96dc}, {0x000cd649696f60dc, 0x000dbf0ed5f9a8b8, 0x00051f0009075842, 0x00066f4af5a4b4c2, 0x000d20644cf2ef5d, 0x000ae23c00b5bed3, 0x000b66f7e4543a75, 0x0000000000041325}}, + {{0x0006798502ee1353, 0x0006c04ef7ad5a7b, 0x000c6878548d78d6, 0x0008a6a47591d88b, 0x00046902edb49ae3, 0x0002b143a27d9125, 0x000df65dae3d8381, 0x0000000000093a2f}, {0x00091ef1ecb7e486, 0x0000807a00388858, 0x000fb3b7ca4398f1, 0x000c17172b1bcba8, 0x00032d0033c73fd6, 0x00016c28aa8d70f9, 0x000ad79ea9eea329, 0x00000000000423ed}}, + {{0x000a6b031af68d65, 0x000b59949b33d112, 0x00063134f5d066ef, 0x00071e788e17f2bf, 0x0002da9c088188ce, 0x000d8c9e9d851baf, 0x0005b6e869c5ba86, 0x00000000000a0142}, {0x0009ab9cc7c38dc7, 0x000eceae8b1c5d3f, 0x000b0c8e79b3cc01, 0x0002910c374bb97b, 0x0007054874831494, 0x000bc6ee13e13c45, 0x00047be0e6fad435, 0x00000000000b54d2}}, + {{0x000e68e47f9ea217, 0x0003c9c85e50a3a1, 0x000b0543d8520966, 0x000ce81807f33dba, 0x000a3db81e06cb78, 0x000638d709d337d8, 0x000babe223eae472, 0x000000000006bf2e}, {0x0006763908bcca20, 0x000662804b59c92a, 0x000900c614fc9957, 0x000ca1e7bc6949c1, 0x00008f051155321e, 0x000539f40bf2906c, 0x000808b802a3289c, 0x00000000000073cd}}, + {{0x000fc3dc90267bca, 0x000956d34bdf61b1, 0x000bd7a38090ba35, 0x00051135a3bfdd10, 0x0005f1296bdd61d0, 0x0002e9a7c4abab57, 0x00003d72da68494d, 0x000000000008d11f}, {0x000319b6e5281755, 0x0002247811121597, 0x000526a929004138, 0x0003ec67521898f7, 0x000996c1da75ec29, 0x000f2c7b3f0cf026, 0x000af8b0dbd4c380, 0x0000000000034e4b}}, + }, + { + /* digit=90 [{1,2,3,..,}]*([2^360]*G) */ + {{0x000c4e9ab57885e4, 0x000f3c32730e8279, 0x00033a83277668a3, 0x000fdbf3f5cd8478, 0x00067272d4dd2bac, 0x000b7577645f3641, 0x000be2dd813a795e, 0x0000000000050997}, {0x0005df7d4526b8ac, 0x00040da054e2b966, 0x00068890ccefdc5e, 0x0008f31026116a38, 0x0000dcd85e914c42, 0x0003adc2d372af9a, 0x0009e6fda6e90367, 0x00000000000a8db5}}, + {{0x00029349f348fe26, 0x0004251a033a4db8, 0x000e0f2d8a80c6e4, 0x000ce49a42a266f1, 0x000b82c4d11e92ee, 0x000bae08a87e037d, 0x00078c875be1416f, 0x00000000000c5394}, {0x000064a55c345b79, 0x0001651f8b907a36, 0x0000a11c59759db6, 0x000bd666c51b9c32, 0x0004ee565de82c74, 0x00082c8c3635d3d2, 0x00093c6bd6566389, 0x00000000000daf6a}}, + {{0x0007ac96ab52d7dc, 0x000dd68fe359d36e, 0x000f3dea99f83698, 0x00052c3fc704935e, 0x000952e4e22d0ec6, 0x0003e3ada1eeff1f, 0x000871ba6777cb08, 0x000000000008befc}, {0x0007324fc4458b0a, 0x000e34ede689e853, 0x000cf3cdc3eb9d08, 0x00080517ab83c288, 0x00052c8c1f48e0f0, 0x000241aac1f3d5f2, 0x0007e057991607af, 0x00000000000b8a33}}, + {{0x000ca2047d1f8f40, 0x00004179c59cea3e, 0x000880cb97b10e4b, 0x0005cfdba0cf3857, 0x000b3a8fbafadda7, 0x000384e0b94081a5, 0x000a45b91de90a33, 0x0000000000027aa2}, {0x00058a31cd3d8717, 0x000220747bcc094c, 0x0000191551c0619d, 0x000e3e9722484f1a, 0x000da62d1dda9c1c, 0x000963bce13a7ee5, 0x00021b77fd79343a, 0x0000000000083d2f}}, + {{0x0009d92935034280, 0x0008b3dbb3fa61cd, 0x000a3f5ecd8961d8, 0x0006574793ce8041, 0x000783dbce4f35ac, 0x0003cf6b0b2697dc, 0x000164e35c5bf2e1, 0x00000000000b0c4a}, {0x0008df1996e7f4a8, 0x00038aa49090842d, 0x0003b655f6623523, 0x000e96c54d504e4c, 0x0001b73310a3f646, 0x000bde5dad74e754, 0x000ef7ead7159618, 0x00000000000aa09a}}, + {{0x0005ac9c05f620d2, 0x000df609deb16279, 0x000a25447b2b8795, 0x0003132b378305ce, 0x000869275f5e4a9f, 0x000b089b5f101799, 0x0000c514be746761, 0x000000000000c81b}, {0x000e2dd3d7fa135b, 0x00030ca90a9bf94b, 0x0006097de4edabc4, 0x000ac9620c71989d, 0x000a390aedd01b25, 0x000d8cd39b971b61, 0x00011a995214d779, 0x0000000000065c6e}}, + {{0x0003855cea5ad9ec, 0x000d4a8393a23731, 0x0006e8588fe37236, 0x0004e0255a202691, 0x0002a446bcc6d882, 0x00051499b9dd9a27, 0x000535c929cded53, 0x00000000000cfe76}, {0x000bc0f428a70f0d, 0x0009626f3d7d9b38, 0x000a6acd906c92a5, 0x000cc06759e6ddb7, 0x0004e302b89191fd, 0x00007e1f7ac2e190, 0x000b4aad25c645c2, 0x00000000000ab3de}}, + {{0x000338669b2cb8c7, 0x00071a13f19b3741, 0x00031ac1789cc21d, 0x0000c997044a6f4f, 0x0008dca1075c00ec, 0x00020ab0caf5665f, 0x000effded5ca3f06, 0x00000000000a896d}, {0x000378285debab1d, 0x000a5032ab2b2a9f, 0x000438bbbc4fc5ea, 0x000b6f725133304f, 0x0001977a45672286, 0x000abae4f0d16d53, 0x00003b00a66036f1, 0x0000000000095f01}}, + }, + { + /* digit=91 [{1,2,3,..,}]*([2^364]*G) */ + {{0x000925dc8a89e47c, 0x00066f2cdae310b9, 0x0002591b317d8ec6, 0x000f25ad750b29bd, 0x0005dba15f3e9d14, 0x0009fe2dd931b9c6, 0x00043334db169ebf, 0x0000000000052663}, {0x000c577396a26bac, 0x000968859a4f76bc, 0x0005596f973fb63a, 0x0008d6a67ac4db88, 0x0002be25d7557463, 0x000db10ee5c8ea7b, 0x000cd38a0f0a8738, 0x00000000000e890b}}, + {{0x000bf56a7de9f2ff, 0x00022883533aee6b, 0x0008916bc1e75ddf, 0x0005fb546d0fcf42, 0x000a4ab05da78f0b, 0x0007b66147e6b0a0, 0x000cf2cd91a869c6, 0x000000000006c6f7}, {0x000593da575680e9, 0x000d7c072a1067a9, 0x0006a216ef99f7a9, 0x000192c8f0ce9469, 0x000fd11494417378, 0x000ccf45adf2e7b9, 0x0005684fa17cb614, 0x0000000000045f03}}, + {{0x000725d8721dd338, 0x000930f4ca77fc15, 0x000b6681d170fa2e, 0x000625b4ef805afc, 0x000fc015c5864873, 0x0001a8c93bddba22, 0x000f427091b50aa4, 0x000000000004c005}, {0x00044f31df11a4ec, 0x0009ff43d3745415, 0x00007d532af636b7, 0x000a10c82770690b, 0x000b77513f003efc, 0x000c3af9bd0c25d7, 0x000adac0015cc12d, 0x0000000000094c6c}}, + {{0x000e8ca221c6ffc6, 0x0008d8b70e94f6d7, 0x000aee261a6327ec, 0x00019ba4d3ef22f4, 0x000a1999f948e222, 0x000fe73027f8a712, 0x000af025575e96ab, 0x00000000000564a1}, {0x000b25cff3d9db0b, 0x000b1045e9c658aa, 0x0003561802f8c969, 0x000b825c3db161be, 0x000aba33a906dd23, 0x0000e41f205fb173, 0x000d1d9a8b5ecb87, 0x00000000000ccc30}}, + {{0x0002aea737bc7de5, 0x000c2bed7d94c6a0, 0x00033bc161f07397, 0x0006af6106834bff, 0x00044c4f74486541, 0x0001dfc06dade8a1, 0x0007bc62227a1d88, 0x000000000008dc2b}, {0x000d41c50320c146, 0x0001c4f1154170fa, 0x0005645ed0c5caa2, 0x00053aba0f1b9617, 0x000d48b0ec8e98cc, 0x00072d0342f68011, 0x000e384bbc34679c, 0x000000000009c576}}, + {{0x000919b377dae55c, 0x000a5d9243926709, 0x000605401369e5f3, 0x000feee0e35f201a, 0x0003196f23f3a1bc, 0x000c1d068d25be5f, 0x00050b298c67f2ff, 0x000000000000c3d9}, {0x000d303412559962, 0x000fa5e15ab9975c, 0x000533c7cf964ba3, 0x0002ec947a7e2696, 0x00022ac22e49a9f8, 0x00006f090f02af9a, 0x000cb0dfb3103fa7, 0x000000000003cf8d}}, + {{0x000298e2791b8ead, 0x000259f5f44f9ed5, 0x000ce416b16e73bb, 0x000f258f9627f9cc, 0x000938fd51bdd7e8, 0x0006a4a7922499dc, 0x000250a9d7497c84, 0x00000000000026ae}, {0x000e3b88b9c7c3db, 0x0009084d47d19214, 0x000f52469be04308, 0x000138806a52e316, 0x00027f08953f9b2f, 0x000fcac083fc8da0, 0x0003fc22d074d292, 0x00000000000701d7}}, + {{0x000b913b1d418177, 0x000cbb7b856256b6, 0x000f3717023b8633, 0x000ddd5c91b8ffd9, 0x000155d38511b4eb, 0x0000da525ef815ae, 0x000bbd98587d551b, 0x0000000000034a9e}, {0x0005ef8ce15a684b, 0x000b8844811fa3d0, 0x000d70ffbd583fff, 0x0008bb4f623789be, 0x000e404980584b26, 0x0002b435ab26ae5b, 0x000eb3b47a5ded3c, 0x000000000008fcec}}, + }, + { + /* digit=92 [{1,2,3,..,}]*([2^368]*G) */ + {{0x00069e40601a7dfa, 0x000cb70765682efa, 0x0003c3be2bc6c542, 0x0005ef0a6db6169b, 0x00012032d5992a93, 0x0006f13160029276, 0x000f51b5babb2d3a, 0x00000000000db26a}, {0x00039e460e4f3b3d, 0x0000200c3401304d, 0x0003ff9e293a0443, 0x000e2ed0f9b36565, 0x000934031d18a1bb, 0x000fe1224e17a5d4, 0x000cf5e3661047f8, 0x00000000000623c6}}, + {{0x000ad46943acea12, 0x000a859367582797, 0x00066c45ce5e5faf, 0x000351af6a27741d, 0x00087f929e0d5d96, 0x0003f1afbeab94db, 0x0001dd865ba01104, 0x000000000005fb63}, {0x00040d1f1e090717, 0x00038192e065294f, 0x0002fb37089941d8, 0x000228db7cae5f66, 0x000d6a828b037bcc, 0x000f301aa02eaecc, 0x000a077c48a2ea91, 0x00000000000f5eb1}}, + {{0x0000bb651b864105, 0x000154dd3bd8408c, 0x0001daf9340de0f6, 0x0006998ba0668966, 0x000cad713bbd1ad4, 0x000ca4fa5b7c679a, 0x000a1cef9389aff7, 0x00000000000d68b6}, {0x0009051030865994, 0x000093acfff601ae, 0x000275b28bea6bfe, 0x0006441c66ad734b, 0x00042fd3eb165e2f, 0x0004e211749f144c, 0x0001a3bd7f22082e, 0x0000000000041791}}, + {{0x0002b76266c69181, 0x0004edf0ae8df2d5, 0x000906801183c79d, 0x00017ca1dd286917, 0x0009709b678ede37, 0x0000acdc60c1db87, 0x00003a0288959a40, 0x000000000005ca2d}, {0x000fd72975fb9eb5, 0x00084e52534b365b, 0x000f103241b3e4c6, 0x00034f873eece315, 0x000d642a67991a9a, 0x000a7e8a80fb0c7b, 0x000238375cc0cfea, 0x00000000000d00ec}}, + {{0x0005a38c81bac32b, 0x000bdb67d88fb498, 0x000506df3f19aea7, 0x000433ede7910791, 0x000a20ec085cc26e, 0x0000eefb30ed8fc0, 0x0008c22684a901b3, 0x00000000000e855e}, {0x0003801582a535c0, 0x000a23d31d6c91c3, 0x00014e8637446682, 0x000380e755f1af17, 0x000a6c985ecfd938, 0x00065084e6a8e434, 0x000ec653bec9c1cb, 0x0000000000070309}}, + {{0x000a18c1c3a6f1f6, 0x000f49a2461c2364, 0x0005b210149e5bc7, 0x000bfea0ae15fd0a, 0x00027ac4d98f2265, 0x000831902d817b35, 0x0001fe9788aa4511, 0x00000000000d4616}, {0x0004b65395df8642, 0x0003d2a7cac2f471, 0x0003af0e90c12844, 0x00048d211070e2f3, 0x000ab769926571a6, 0x000aea1556050d8b, 0x000411cf8f24a040, 0x000000000003522b}}, + {{0x000a6d728de1a709, 0x0002e45d4ed63b83, 0x000803bc165cd24c, 0x00029022b267f598, 0x000fc8446afe76be, 0x0004d6f50791c22a, 0x00077ed6ce8b8859, 0x00000000000e3f1f}, {0x0000a258fb32c514, 0x0006d1a72b16f0c7, 0x0009dc6ac4083dba, 0x000743e1cad2e785, 0x00041e0e640d6a1c, 0x00074648529ff0a5, 0x0001fb4cd519be4b, 0x000000000004584f}}, + {{0x00051eecfb6439ff, 0x000619ca8cc9cbbc, 0x0007f10adb0b792f, 0x0005d53059b2bbb3, 0x0000730e5dc37211, 0x0001d89988fe7ac3, 0x0007a54e67ef6984, 0x00000000000c8ed3}, {0x00004a045edf3ac0, 0x0005e48164b3dc80, 0x0006b3cd6d953b04, 0x0004643beed38ce9, 0x000fa3e30b3db7fd, 0x000ddd484993cfa9, 0x00075ddcc5e7af01, 0x0000000000068401}}, + }, + { + /* digit=93 [{1,2,3,..,}]*([2^372]*G) */ + {{0x0007c9efed4b7222, 0x000ab79768e9e648, 0x000c0eb72891fdba, 0x000821bbe0c67d8d, 0x000a6909fdfcc194, 0x000ccdda7537a6a4, 0x00026cae6d705195, 0x0000000000092b39}, {0x0004e2be194fc116, 0x000ab2c5dd6af51d, 0x000bd2ad4ffd8821, 0x0007388397a3bd3a, 0x000a8baf59c2dd3c, 0x0000ec9589d176c6, 0x000315d5c6219e38, 0x0000000000054e8e}}, + {{0x00045f27ccc6232a, 0x000560683349d797, 0x0004a272721dca0a, 0x000181050663b9f6, 0x00099733dac647c7, 0x0002137c5f327d14, 0x0001c703f55e4a29, 0x00000000000da59e}, {0x000b58d5c8ca43e3, 0x000c7baa8b4dce4f, 0x000e015119c73eca, 0x0008c1db0322dfa0, 0x0007fd69954f99a8, 0x000a29889394440a, 0x00064a9060473da5, 0x000000000002f048}}, + {{0x000df3b38c2a0a79, 0x0000190762c1ecbf, 0x000c4019f47729e5, 0x000849f5c47c645a, 0x00056d72e7487420, 0x000e11773b082319, 0x00050eaeac683b8e, 0x00000000000fb5c5}, {0x000722990680a985, 0x0003e6d986d69658, 0x000da73ac5c10442, 0x000136fd94d52235, 0x0009ed5b01c6d13e, 0x0008fcdcc1aa7541, 0x0005ee7c2014b140, 0x00000000000cffde}}, + {{0x0009c28bf944531a, 0x000bbc7d0abb1f4a, 0x000c2054201bd117, 0x000defca80767df6, 0x000871820908eb67, 0x00074d19a6fa174d, 0x00081a3215df4856, 0x00000000000960a0}, {0x000602066fc6cc5c, 0x0006993ed71807f6, 0x0002dfba1c3883c8, 0x000d56efe787e592, 0x00098fe8b96f0909, 0x000ab68115ae74fc, 0x000e0c8fc342c435, 0x000000000000b991}}, + {{0x00047f2399bf97b6, 0x00021c600dd569b8, 0x000917d84fb94235, 0x0000a27de43c1d70, 0x000e616bdb162d7b, 0x00029795321bf3a9, 0x0008b233ce767c96, 0x000000000009e439}, {0x000800714c3c1216, 0x000934069cced410, 0x000f1cffed0b3d13, 0x000bf89c53942369, 0x0009acb24e389981, 0x000da473507d9c07, 0x000cd9d2e5e904a2, 0x000000000002f1b6}}, + {{0x000ee38595e6d6e3, 0x0003bfeecc6e7a5f, 0x00087ab2bdd62b28, 0x0004e20e81879cac, 0x00089c4a27124845, 0x0000749c3d0ea9cb, 0x000f93ba8b6f3354, 0x00000000000e971d}, {0x0002b66fa9a77846, 0x000b64c2a1b129de, 0x0005071339da6099, 0x0000b53435739873, 0x000a57040c00e6c6, 0x00091a7b4b9f56a6, 0x0002466de6489f62, 0x0000000000053bc3}}, + {{0x000554330abff5cf, 0x000ae828a9dbe5c5, 0x000263a5672326a0, 0x000428089faa5816, 0x00002dba2a1d1558, 0x000197ae62da0922, 0x000abba225f631df, 0x000000000008f4eb}, {0x0005dcc2ee38818c, 0x0001bbbadc9b2cb5, 0x000ab544fb33427b, 0x0006cc2759413f76, 0x000121dd1222072a, 0x000ac2c737b39ea4, 0x000296d6baf9e196, 0x0000000000075d46}}, + {{0x000b2448cce42a48, 0x0001555671128874, 0x0000a30717d307ff, 0x000207ce99ca16c1, 0x00057c7a26b97e21, 0x000c3ab00785fa10, 0x00059f33c28658c2, 0x00000000000d79cd}, {0x0004e804722ed471, 0x0006f9a674db4469, 0x000c9ef186db33b8, 0x000722166bf2c6d5, 0x000abd4c3791990e, 0x000696ee1ba29aff, 0x0006a5d98510cf20, 0x00000000000f93d2}}, + }, + { + /* digit=94 [{1,2,3,..,}]*([2^376]*G) */ + {{0x000bbb4af21bdc49, 0x00065e7cf5babca3, 0x0003f75a29c95b64, 0x000531d04fa84740, 0x00045780efda9c1a, 0x00062cb5a399e848, 0x000f3b6e9c12be4f, 0x0000000000094a5d}, {0x000aeeb34b3f3b9c, 0x0006d3c15fe11c69, 0x0009e05f576f256d, 0x0006da4be294c912, 0x000aa99b83983ef7, 0x0001b9f6a5cf21d5, 0x0007bf50679cf875, 0x0000000000054d0b}}, + {{0x0009b2dd4ee443f9, 0x000fcc84f9171b4d, 0x000ea8b580b8da51, 0x000753ba05068eb1, 0x0004077777efcdc4, 0x0004cf44aa177ad1, 0x00044e0b7f54eb7e, 0x0000000000018601}, {0x000becbcecff7dd7, 0x0002b1279ed4c55b, 0x000e10b5af306b99, 0x00058fab8cdb6cf3, 0x0004a0c7614aebc9, 0x0002c6d8ebc4f93f, 0x00038ac5bd6cde7b, 0x000000000008d65f}}, + {{0x0000f0922779f009, 0x000bb4da7d63a943, 0x00025a4f402efdea, 0x000001668841d1ef, 0x0005b10366f61e8c, 0x000b121e90688f48, 0x000c1e38ee34b005, 0x0000000000014e0d}, {0x000a8eaa6c54d224, 0x000e683c1d44e6fa, 0x000050a1a6ad5a9a, 0x000274453715349d, 0x000dc5ca18f66b73, 0x000ef86e35065bdc, 0x000f5d677313cf2d, 0x0000000000033ebf}}, + {{0x000a3669bab3aa8c, 0x0001fffec66743ba, 0x000af6b2298cee7c, 0x0001365ee61bc95f, 0x000e8948b6e23181, 0x0001644be358bbd6, 0x0007a71cd9c342e3, 0x0000000000060a8a}, {0x000569b8813054fe, 0x0000ae065519f224, 0x000901053fc569ee, 0x000c03b8517ae8b7, 0x000173750d6e8957, 0x000aee6d7c96a040, 0x0001144eb2e364b2, 0x00000000000ed099}}, + {{0x0006635997173f0f, 0x0003b71714896339, 0x00025444ec94256f, 0x0005f33fe56d0905, 0x000638a1b2efb078, 0x0000fc15add43e0f, 0x000d362df35cfb36, 0x0000000000090b3e}, {0x000659873829fac7, 0x0000bd4970bdd7ef, 0x000e315a3dccca14, 0x0008a3e4a43c4f3e, 0x000fd9cb4808c99e, 0x000c3d0948013609, 0x000223f3fef0eaec, 0x000000000008642d}}, + {{0x0005a811304eaea0, 0x00018ffe3104b37f, 0x000808bc57214341, 0x000ed42cca2f1506, 0x0002c421c69415aa, 0x000b87b368618aa0, 0x000d5f4d6a091dfa, 0x000000000000e786}, {0x0009341357580c61, 0x000ee0be97746d4b, 0x000cd6467b049086, 0x000823b7a70d4224, 0x000809de860f6094, 0x000cf60205928791, 0x00086e7f7fca496d, 0x000000000005f460}}, + {{0x0007768861c39ce8, 0x00007b509f7028f0, 0x000fc09189281be1, 0x000832a7f07f3291, 0x000d8fbdcb83853d, 0x000a4650d074fdec, 0x00072080ed8de9d6, 0x00000000000a5d68}, {0x00079ea50cb0600f, 0x0009ae66666d224c, 0x0008a45c66bc5d53, 0x00099510da620fbe, 0x000fdf866f777e2d, 0x000045beb901145f, 0x000008442a37e5db, 0x00000000000beb1b}}, + {{0x00048a2dbd606668, 0x000c9bb39a179bed, 0x0009439710e05c24, 0x000abe3b91f14833, 0x000fbd39a2bc6be6, 0x0001d813ef972804, 0x000d4a06737e54f9, 0x000000000001a87c}, {0x000d0c4b5d0bc923, 0x000b2bf88b2e5982, 0x00052c33a491bb9f, 0x000aedfa58af0431, 0x0006ac0511b07a93, 0x0007e2c198853cdf, 0x000d8a9d7f416d06, 0x00000000000f9671}}, + }, + { + /* digit=95 [{1,2,3,..,}]*([2^380]*G) */ + {{0x000f6957a24c76d1, 0x000222e7d0a157df, 0x0001697f0073308f, 0x000ddc63eb317f9f, 0x00015adf71d715f1, 0x000858bc3f027507, 0x00071a2ce33c2eee, 0x00000000000da73b}, {0x00035cb76cad67cc, 0x000de9ef6a709ffc, 0x000c7c7ed1727cfd, 0x000f5a67502de655, 0x0001a47019739f5b, 0x000ea7b24d11122a, 0x0002e182cfaac2a2, 0x000000000000a458}}, + {{0x0007ab134ebd334b, 0x0005196a1e74f032, 0x00014e69e2323c83, 0x0009c4fbe35109cc, 0x00004521d7e61244, 0x000d002931fad8b3, 0x000229c85eb23d57, 0x0000000000035f68}, {0x0000d113aed4dbde, 0x0000c7c5b86677f2, 0x000189b64d0338ba, 0x0000456757cd5717, 0x000e3a1c866b067b, 0x000ba88c0eaab81b, 0x0007dc72a6af75bb, 0x000000000000ef56}}, + {{0x000ac045af51c5bb, 0x00010597a26ff058, 0x00059bcfafa87a4b, 0x000aff65c27f5f6d, 0x0005d8d544e60b06, 0x000275c32ce5ab66, 0x000e7c92f031be99, 0x00000000000f42e0}, {0x000c8a905adb28dd, 0x000175bb28b05c35, 0x00031ae347df4e7d, 0x000d299f93fb7dcb, 0x00086e2ccad9e73f, 0x0004d4f57fcd999a, 0x000c9bb8c8a6df33, 0x000000000009a2ac}}, + {{0x00030bea7fcf0ecc, 0x0006a3afdee26fd5, 0x000cc01988c78a70, 0x0008ee3ba4a33026, 0x000a2a883b7f340c, 0x000d7412b1a6ea51, 0x000b6e64f27976d5, 0x0000000000091251}, {0x0008bb3d89325d7a, 0x000d25f3f8f40ad2, 0x000216e9116c139b, 0x00073d6ad61b2cbc, 0x0005d542676dde3b, 0x0007d712bf08398d, 0x000023d373931e8e, 0x000000000007f96e}}, + {{0x0004e4e1b942add8, 0x000e15adf3d9957d, 0x0005ba50de0860ba, 0x000ce33a82d3736d, 0x000e718c8aa3f9fb, 0x0006ccf69f307823, 0x00065b860578cf41, 0x000000000001ef84}, {0x0009d5f6cc7a9ceb, 0x000939ee0cf97011, 0x0002f3cbdb7c8fc5, 0x0009a8dc09da90cb, 0x000dcbf3ccb8f99b, 0x000a626321f521c2, 0x0009da6bf6694891, 0x00000000000854fe}}, + {{0x0000917c5016c853, 0x00049e44e3f85fb2, 0x0000e1793eed8bac, 0x000254501c4e171e, 0x000cce52defb1004, 0x00063100ac12df68, 0x00035fb1fae2fbf3, 0x0000000000035732}, {0x0007edc8c1da40d3, 0x000c58d4deb655bb, 0x000bfb14f6d9d28f, 0x00085835a4e118f4, 0x0001308772e93249, 0x0004e48765abfa96, 0x0007b241c7611ff5, 0x000000000001f586}}, + {{0x000782cfada548c3, 0x0001e463031709b7, 0x0005afd4d0d5166c, 0x00097fff172c7d05, 0x000735b193cfd8e4, 0x0009df4bc7f7009d, 0x000e376b9fd3f7f1, 0x00000000000b46f1}, {0x0004c800fedd3a70, 0x0000987c6eaa8c8c, 0x000dff8047ad562a, 0x0001042539eab96e, 0x000779b8f5cc2a12, 0x0007840dc29a6d5d, 0x00030f33803a10b7, 0x0000000000011a6a}}, + {{0x0000457a60ad991e, 0x0005e3c90a59f250, 0x0005eeda9345d42a, 0x000885c1a0d58e29, 0x000d6816b0099aca, 0x000e4718f77b9b6d, 0x000c458e5c12139e, 0x000000000004e4ea}, {0x0005f9c85e9bfc5c, 0x00086c00c3568eed, 0x000b5b4b0eba61f9, 0x000ffc75eaf3eab0, 0x000d42a87e32cba1, 0x0007a882f5f99092, 0x0005122e7b49c76f, 0x0000000000029040}}, + }, + { + /* digit=96 [{1,2,3,..,}]*([2^384]*G) */ + {{0x000dbfc10083fe9c, 0x000bfcf17f9dc084, 0x0005e1e364b063e9, 0x00054ffe437b29cb, 0x0009e27ee9e2a694, 0x0003af03b6628d78, 0x000d6256e3b975ee, 0x000000000002f532}, {0x000e1d6aa4b057a7, 0x00043cae15213418, 0x000003dc9b2b9ddc, 0x000a959fa4d82608, 0x00055ae17566902b, 0x000c82eb4bad700d, 0x000ea716b2c5dc14, 0x0000000000036708}}, + {{0x000e41b4a9c3409a, 0x000849cbd62cd8bb, 0x00047e8c2d4de38c, 0x000bbe98f886eca3, 0x00049b432990b7f3, 0x00030035684860e8, 0x00029ed19a3bafa4, 0x000000000000e209}, {0x000ed539231869f6, 0x00098f15ff660294, 0x00050e66a84ebdc7, 0x000de8d2955612f1, 0x0006ec97a4a53ec6, 0x0000d15fe2d95b4e, 0x00024d868731f0f9, 0x00000000000aefae}}, + {{0x000253f48e5fab58, 0x0006889f97859df6, 0x000dee3f7bba228a, 0x0001d4ea62a5c827, 0x000ea3045da6826e, 0x000d3d237ecba3e4, 0x000358beed1da058, 0x00000000000b8b41}, {0x000293271a9d4293, 0x000d2730e7ac94c3, 0x000f438703e7096b, 0x0004cace8c1c6462, 0x0001055d39de9ba9, 0x000b71db3ec7c382, 0x000a11c89705a82f, 0x00000000000781b6}}, + {{0x000606caa5686427, 0x000cdc1951fb0886, 0x0000daff401d6319, 0x00009bb2754f1d38, 0x000e0e0e2bf19831, 0x0005a3da40f7db33, 0x000197348c4e1937, 0x00000000000840a6}, {0x0008d7f45b2f9769, 0x000d11687a735d22, 0x000434d1e1dee1ff, 0x000773c0aa9e79d1, 0x0009f56de9654a25, 0x000dda7af656f6e2, 0x00063fdf84666df0, 0x000000000003f9e4}}, + {{0x000a9c9951735edd, 0x0006afe9f90d3ad9, 0x000f97a0b45a07d7, 0x0007d6ec36e3b706, 0x000f580c8e6dd513, 0x000bab45c3ea55f4, 0x000d5819398b33e1, 0x00000000000aee76}, {0x000d9c115c469d59, 0x00071e72c8214ce4, 0x0006b3ef7ac6abe3, 0x0001ac198f9553cb, 0x000a1c98ad467fa5, 0x0000ebbb2019ac4e, 0x0000a68942e16e01, 0x00000000000bed3c}}, + {{0x000f13cdd62e69a0, 0x000461a814bf695a, 0x000e4323f4986584, 0x0001bfa2a4dd16f8, 0x000a76fb9f2b33c9, 0x000b1f1114af4d9c, 0x000b45a23635ef75, 0x00000000000a0891}, {0x000bef0dcdd6b903, 0x0005f5d1b87ba5f6, 0x0005d7ac1d6bdae8, 0x000cb4543d4ef435, 0x00064aa784ea70bd, 0x00070e4220ed12d3, 0x000483009cd34901, 0x00000000000280cf}}, + {{0x000bddf9aa596a1d, 0x0008952c04b79c0e, 0x00099a2770f3fa4a, 0x00044bf1911b3184, 0x0006bb897d318407, 0x000e9de5dd13f080, 0x00052b376dc8b81d, 0x00000000000c996b}, {0x00047f465159b51f, 0x00041d91e47b224a, 0x0009b71ad19e642b, 0x000c167eface7572, 0x0001d4805ed6a441, 0x0003fd6654eb9588, 0x0005778fc93daf3f, 0x00000000000cc570}}, + {{0x0000b16f46a35f8c, 0x00065a630c20c4e5, 0x0001f4362772ed03, 0x000aca10c0dec6cd, 0x000ba9e2f55428c8, 0x000bbb1705d34bb5, 0x000f6e8e81b4f732, 0x000000000008363b}, {0x000ca7950547e910, 0x000969603fe028be, 0x00047954fea1ddef, 0x000bb8efc191d12e, 0x0005dba97347c0da, 0x000656aaaf0e463b, 0x000cf0b7f7c207a8, 0x000000000003f08d}}, + }}; + +#endif /* #if !defined(_DISABLE_ECP_384R1_HARDCODED_BP_TBL_) */ + +IPP_OWN_DEFN(const cpPrecompAP *, gfpec_precom_nistP384r1_radix52_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 4, + /* select function */ p384r1_select_ap_w4_ifma, + /* precomputed data */ (BNU_CHUNK_T *)ifma_ec_nistp384r1_bp_precomp + }; + return &t; +} + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif /* #ifndef IFMA_ECPRECOMP4_P384_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p521.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p521.h new file mode 100644 index 000000000..bc6582fc1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp4_p521.h @@ -0,0 +1,1373 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_ECPRECOMP4_P521_H +#define IFMA_ECPRECOMP4_P521_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" + +#include "ifma_defs_p521.h" +#include "ifma_ecpoint_p521.h" + +#define BASE_POINT_WIN_SIZE (4) +#define BASE_POINT_N_ENTRY (1 << ((BASE_POINT_WIN_SIZE)-1)) + +#define OPERAND_BITSIZE (521) +#define LEN52_P521 (NUMBER_OF_DIGITS(OPERAND_BITSIZE, DIGIT_SIZE)) + +/* P521 affine point */ +typedef struct { + BNU_CHUNK_T x[P521R1_NUM_CHUNK][P521R1_LENFE521_52]; + BNU_CHUNK_T y[P521R1_NUM_CHUNK][P521R1_LENFE521_52]; +} P521_POINT_AFFINE_IFMA_MEM; + +extern const __ALIGN64 P521_POINT_AFFINE_IFMA_MEM ifma_ec_nistp521r1_bp_precomp[131][BASE_POINT_N_ENTRY]; + +#if !defined(_DISABLE_ECP_521R1_HARDCODED_BP_TBL_) + +const __ALIGN64 P521_POINT_AFFINE_IFMA_MEM ifma_ec_nistp521r1_bp_precomp[][BASE_POINT_N_ENTRY] = { + {/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{{0x00031a16381adc10,0x000f3f18e172deb3,0x000e0c2b5214dfcb,0x00017fd46f19a459}, {0x000ac947f0ee093d,0x000d50a5af3bf7f3,0x0001457b035a69ed,0x00009c829fda90fc}, {0x00011cada214e324,0x000274e6cf1f65b3,0x0000000000000000,0x0000000000000000}}, {{0x000460e4a5a9e268,0x000f4a3b4fe8b328,0x0004351396120445,0x000fd683b09a9e38}, {0x000132062a85c809,0x00064bf7394caf7a,0x000d7de8b939f331,0x000224abcda2340b}, {0x000163e8deccc7aa,0x000de0022e452fda,0x0000000000000001,0x0000000000000000}}}, + {{{0x00090cf08640909d,0x000f1c99dd36bc1e,0x000b26b07ecb3fa1,0x000ae2d7a0e797d1}, {0x000aa83d508251d1,0x000bd9d9026d377a,0x000372a82ebb4df4,0x0003cd8e66031a96}, {0x000a461413a3a019,0x000f3f3417e59440,0x0000000000000001,0x0000000000000000}}, {{0x0003d2ee331fe1b6,0x0001ab6b30fa0d81,0x0004af6e07a7b8df,0x000d19247a757e5f}, {0x0008fb5c9c9bfd4c,0x000dd9f1bbef4f92,0x00090d14c836216d,0x00083e26d4bba055}, {0x0007769f85ae35a8,0x0009338053f9f677,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e9cf4d4910f78,0x0008ce976f1bd6be,0x0004316197502d2c,0x000acff10dd75a48}, {0x00019028ed35e8b5,0x0008d69f8b251d24,0x000d6bd0896bd46e,0x00072d891ecd5cf2}, {0x0005acaca3cda953,0x00048caeec8eb532,0x0000000000000001,0x0000000000000000}}, {{0x000cfa6c0ee5f7e9,0x000c4650f7436072,0x000de49d2c8212fa,0x000f61e3867882e4}, {0x000bad816ad6768e,0x00061716ea67c6e2,0x0007c558fd1aae77,0x000fd4154e818be9}, {0x000655c0a7978aab,0x00016eeccbcfc363,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008d6d77d92b8ab,0x00043a09438c8179,0x0002d8472d2f17de,0x0003c5783350ea81}, {0x00083a8745c474f8,0x0006432cf1257f1e,0x00062eaaaa0e9e75,0x00048e2ff9cd7e03}, {0x0003e483866e30e4,0x00010261aa5a41a4,0x0000000000000000,0x0000000000000000}}, {{0x000a0825be109849,0x000fa3fe1a372686,0x00078234ce8ecf10,0x0004adc2f75dbfd7}, {0x000c2a029127ba85,0x00093cf941f2a5d1,0x000731ff178cc83f,0x00077b7371970dad}, {0x000585a55db2a90d,0x000ce95b39f00bc7,0x0000000000000001,0x0000000000000000}}}, + {{{0x000194afcf14a49e,0x0005a84b7647983c,0x000f36c498b9c6ad,0x0009bf3cd194ebf0}, {0x0000a11b8897f578,0x00021c1e0636af18,0x00081ed5c78bbd67,0x00077eda9f869267}, {0x000e027585fbd2cb,0x000219639ede19c8,0x0000000000000001,0x0000000000000000}}, {{0x000d6f9bbc6f7598,0x000e61f46f584865,0x00092b9aa7bfc0b9,0x000e7affbce8f803}, {0x00079ba188aa0108,0x0003ddb44be48396,0x000ec0be4d01a384,0x000f4743970028f6}, {0x000a54089488e6c7,0x0000eb764515b988,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fb915a75b36d6,0x00098df6fbc9035c,0x000ab2bf9c05711b,0x000a98df4617b374}, {0x000b9ca70393d11c,0x00092fde650b0a9f,0x0000a8356f25580a,0x00084bbfeb8e79cc}, {0x000a24068cab11e9,0x00090ca9977f9a7c,0x0000000000000000,0x0000000000000000}}, {{0x000f780956b43319,0x000666bc2c6a278b,0x0005aae506d6f0f5,0x00013a79101ee3dc}, {0x000464efcb64c26f,0x000b655b96872b32,0x000205493100d454,0x000db9ed2d404739}, {0x000a371d8889555d,0x0007ac35716e9382,0x0000000000000000,0x0000000000000000}}}, + {{{0x00015b574766756d,0x000756c4140b766a,0x000a87ee130cd00e,0x000e71dde237ca9f}, {0x0004c6c64d36f986,0x000ec61846855fe3,0x0000c69617b88a62,0x0000747aa4191478}, {0x00005839d062f917,0x000fb1a3775b2fed,0x0000000000000001,0x0000000000000000}}, {{0x0008f4b46df66eaa,0x0005c5e48292928d,0x000952eef7e3dae3,0x0008e70d2fcf3b38}, {0x0004f15ca91d1a2c,0x000ab5e87949e6f6,0x000edecc51365ef2,0x0001681412786eb8}, {0x0001ceb423c5ae2c,0x0001508868ec18bd,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000208b103ed8c0,0x000cf52a553c6734,0x000dad37a0202c37,0x00046bcf0d5ab144}, {0x000a4f845acc60de,0x0007adff52dc2bcf,0x000c51d82fc1314c,0x000ec54d801f0545}, {0x0005808712dea714,0x000fb931541a41cb,0x0000000000000000,0x0000000000000000}}, {{0x00058cc64475550b,0x000b21788f8bc00e,0x000a004a389a9c56,0x0002e2bc34cf9dd4}, {0x000da5ff85d06f83,0x0008c4f4e0552c88,0x00041ef30833bd47,0x0006f4f16038ada8}, {0x0003c429dcd227c7,0x000e2410247ed5b7,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=1 [{1,2,3,..,}]*([2^4]*G) */ + {{{0x000f45f44362a272,0x00062847c0d42017,0x0004003ee6e299d3,0x000c2b186f86dfae}, {0x000005072cb2ed3c,0x00094a1ff8c430e5,0x000197c69058c452,0x000b30c97e9f9eeb}, {0x000563a1d859543f,0x0005682eed4bed13,0x0000000000000000,0x0000000000000000}}, {{0x0001e8dcd0f160b5,0x0001397c4de39d5f,0x00069468c3199a97,0x000eccc4294f1802}, {0x000a3d505983ad64,0x0000e0c1709cc6da,0x000e51864a5b5c16,0x000261dc006a8763}, {0x0009e9f34b9099af,0x000b800fe38a58c6,0x0000000000000001,0x0000000000000000}}}, + {{{0x00059ae8d65b4828,0x0008ad5c3b72b54f,0x000ae6b62e3c123c,0x000d2e8fca4e7ba3}, {0x000cb7633eb4deb5,0x000b750251aee39a,0x000d3f677dcf2f5e,0x000b32a703401c6d}, {0x000a5d0ad9a1f1f0,0x000d234a21b83d7c,0x0000000000000001,0x0000000000000000}}, {{0x00011dec3fd34650,0x00054d4c8a50ab55,0x000b2d5cb0b1b4ae,0x0005079b6fe6cc64}, {0x000eb5cdba6f0e3f,0x000ef10266dc0c66,0x000ef80e32e16ebb,0x000c5faff80cb3e0}, {0x000f9f041347fbde,0x00055c088b1af3af,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fecd778ec8555,0x00013eb0956c3cd6,0x0005e90a57516438,0x0007f84773320ba9}, {0x000dfd66f6e10d88,0x000a16d04c079fb7,0x0009e6452c01f397,0x0006b339081619a5}, {0x00076316466573eb,0x000a315640ac72e5,0x0000000000000001,0x0000000000000000}}, {{0x000e34d296b0561e,0x000ac0c9e92b6a35,0x000402420e573d8c,0x000d871e142cb792}, {0x000bf1bdbe0a1707,0x000d7310a6b250ec,0x000894a7b366170d,0x000fe4a684f16643}, {0x00025d9fae0bb793,0x000c96f6d42adcf6,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006ae6a85f73844,0x000ee1c671907ba1,0x000014d027ea0da9,0x0001f3800efad55c}, {0x0001bb9d3e0160b0,0x00038df5e9e2f7ed,0x0000a5ce67c43969,0x000dd40c305dd65b}, {0x000c97f61533f5ed,0x00097668a79ebe01,0x0000000000000000,0x0000000000000000}}, {{0x0009d235c3ae123a,0x0008b82c52fc6fad,0x000edd0329eea2d7,0x0007cac021e0e0d2}, {0x000a5887a53dcf1d,0x0005d60b2dd0a846,0x00031dd1b4f43d5c,0x00064597d8ee0e86}, {0x0002bdcac36cdd8e,0x000902b9d50810be,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002ff15cc9efbda,0x000d0adea1bf15e4,0x000712003c28f70c,0x0009acbb183fe29d}, {0x000e35ff46058b74,0x0000e6fbe9505c1f,0x000949d4ed7c586f,0x0006bc96db22c518}, {0x000e9fa6b4caa767,0x0006b3b723ba4dae,0x0000000000000000,0x0000000000000000}}, {{0x000d4a1dbb01ce30,0x0002733373d1589b,0x000695b9bd79abea,0x00024c417444789b}, {0x000a3e366b3687f5,0x00018eccb8e87edb,0x0007fa4355949d4f,0x0003b1b5225855c5}, {0x00040d600e111ea7,0x0002ca9912224327,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001ccaa77955b13,0x000980cc45066e57,0x00005f6f02b3f9b1,0x000f381f6757639e}, {0x000d14e03775ce84,0x000770c3535ef348,0x0000c573845ff7f4,0x0007edbd50365fb5}, {0x000ae96135b16a31,0x000b1cbda8a1cae0,0x0000000000000000,0x0000000000000000}}, {{0x000fb5af8ac6debc,0x000ccace499e422e,0x000f85f9a34dea5d,0x00099ffe8fc76f8d}, {0x000700f62f621078,0x00048a20afbdb94b,0x000353ffe99ecf56,0x0009d5421253436c}, {0x000d53ffd3fcac92,0x000092a9413337e3,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cc6739bc22034,0x0002d46c578a3cfb,0x00074dd1918f2158,0x000820e4ee32d9c8}, {0x000ee4769c451119,0x000a52dc0b788cd9,0x000ea08ad1dce239,0x000e6c51ce30fbf6}, {0x000c6808b739646f,0x00014612aa8ed807,0x0000000000000000,0x0000000000000000}}, {{0x00084f57ce386096,0x00001bd8dd33a19d,0x0006d6cf7616b3bf,0x000aa0ec8a31fd3f}, {0x0000f33cd7d20cf3,0x000d8c7b490a7ae4,0x0003afd25187398f,0x0001d4b82d520c24}, {0x00008bc63a1c99f6,0x000da20702f937af,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005f3504967c9f8,0x00081372b9b7d4f0,0x00090711a09dabb5,0x00052fc0a79713f3}, {0x0008ebea8efb840b,0x000ba724a4b43b13,0x00089257bae703ec,0x000c5de16b6e9669}, {0x000a9811fd41e4b4,0x000c0fc1b18e0380,0x0000000000000001,0x0000000000000000}}, {{0x0009bdb977d41aa0,0x00084a0964efd898,0x000049a3954725e1,0x0002567309871a1a}, {0x000d6462734e1923,0x0004d24ffa586e4c,0x000a7d5e1d8d7ce5,0x000f69f3efbcb30d}, {0x0007de3d3416e700,0x00041ee729987fef,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=2 [{1,2,3,..,}]*([2^8]*G) */ + {{{0x000757d0283c0ad6,0x000745c834df0056,0x000e5caf285c0d9c,0x000faea391f23599}, {0x000232d4e48a9620,0x0009bdc7a7b74615,0x0002fd4f47934e59,0x000c4f65ada3d4dc}, {0x0000798974c81e39,0x00061064a2c57e3c,0x0000000000000001,0x0000000000000000}}, {{0x000a38d40ea9cd04,0x00060922a435ef3f,0x000a826a53bc247d,0x000e94d33d8a1866}, {0x000de75ac695cced,0x000bcb2e7b2b9c71,0x00016e1d52b9aa78,0x000540f2da2b1a83}, {0x000881db4e2a0769,0x000e217e4c0ddd49,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008396a04a1a9b5,0x00071e1d4dea3fc9,0x000f1b1b60428524,0x000875279e270a42}, {0x00031e46c1327bff,0x000c05c823fe0222,0x0001988e4c1b07ef,0x000346e86dbfa458}, {0x000ea14d7c3803e0,0x0002698c2f4163f3,0x0000000000000001,0x0000000000000000}}, {{0x0004df73f1c64b3b,0x000bae3f77cba047,0x0009fac52f482f0e,0x00046303eabe2a5c}, {0x000605a86c7774d0,0x0006157561d8716f,0x0006dae76cfe4cf1,0x0006f10528e0564b}, {0x0008d8ad69113bb2,0x000c2f933ccc8b87,0x0000000000000000,0x0000000000000000}}}, + {{{0x000963cd234bdeab,0x0005b961fb152043,0x000192d80595fa4f,0x00021e095276439a}, {0x000ab3cdd8200acb,0x000b977cb97a7564,0x000f1ac5e95df534,0x000082ed91f8da63}, {0x0005eeb0ff149253,0x000e11676ac3e35f,0x0000000000000001,0x0000000000000000}}, {{0x0001cccbb8a0782c,0x0008ef764987a4d5,0x000621e7649cd3df,0x0006ca705ffe9912}, {0x000d887d63f6769b,0x000a2f7ad40e5963,0x00074e3b9fc2e426,0x000bd597aa3dacd3}, {0x0000fea916df09cd,0x000c4db4a1b5ffeb,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006312ffff6fab5,0x0006b5b394c36d7c,0x000ae9f8123d8c52,0x0007a4616b7fb3e1}, {0x000a92d9f22f9728,0x00095d4a0fd21b31,0x0002d23d7cbfded8,0x000b5c10574881ff}, {0x000e2bd04e830bd0,0x000fd69dfeb7774f,0x0000000000000000,0x0000000000000000}}, {{0x000b243fcf68f023,0x00066b7e7441cd83,0x0005c91b009a23e1,0x000f85c785f70865}, {0x0002122e7768c122,0x000fb751856db403,0x0001836d6df94b82,0x000098df3edc80b3}, {0x000298e9aeea7ce8,0x0006e6048ecb9605,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cad0b80b053c4,0x000883158e365644,0x0001acd6f66175a4,0x00078eba00f9062c}, {0x0000f302446bdc8b,0x0004ffcc5c874a3b,0x0001cc9e542baabd,0x000ca8d66f56fe73}, {0x000fec6e656e27fc,0x0000e12576ad29e3,0x0000000000000000,0x0000000000000000}}, {{0x000f2114ad6a5008,0x000ff37b5e9ff077,0x000fe609c9e85ddc,0x000612f68cb97937}, {0x00035cc97418d8cb,0x000e6da8506bf5e6,0x0001561e4122e23c,0x00026ba1b08bd010}, {0x0007eb4a708cbd94,0x0000c9d309deaf41,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001bba765fa9bcf,0x0003babdc21b3ff6,0x00025b55117dbb2e,0x000cd85081bffb4d}, {0x00081cb8cbfa61b2,0x000244b920db891a,0x000db06e819df932,0x000532ca257bcc77}, {0x000ade96bb81f698,0x000552846b3d2e5e,0x0000000000000000,0x0000000000000000}}, {{0x000cc4965acbbc52,0x00019fc3317e41d4,0x000a394d289bf4a3,0x000dfcc926b6b451}, {0x00099fdc4795a3bb,0x000fbdeb87e6005a,0x000e9db4adbdc0b3,0x00050e680b14c0a6}, {0x000a1f2811642efe,0x000396ef97cb540f,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005f3ef0a7bd1f0,0x000acae8e898fb4a,0x000ba953fee10eac,0x000ac34b13e74541}, {0x000d80a4f317458b,0x000699b6bc22b700,0x0009d659b3752d47,0x000972beec5644da}, {0x00015e14a99a228f,0x0008731fa64678ce,0x0000000000000000,0x0000000000000000}}, {{0x00076f9ee24a5ff4,0x0001761a3d49abfd,0x000099dc50257cde,0x000182905bef244d}, {0x000f586d9a90e6d1,0x0007ebb4cb4857b6,0x00070d79d0a32ad0,0x0004bfe6c4dca5d6}, {0x0009e03cd5b7b143,0x00028c04a0538f51,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c6fc14a74584c,0x000402292021e48e,0x0009500ecd0a9680,0x00002339ed719b16}, {0x000ebb81e8a19412,0x00040e8e4db85440,0x0002a313f6a53c2d,0x00082796c5c684a1}, {0x000636765497c008,0x00020c751837b791,0x0000000000000000,0x0000000000000000}}, {{0x000740897b89a933,0x000f39feb6c7cfd4,0x0006675504305fd0,0x000708d724da0165}, {0x0003fcde5846c915,0x000cbcc847c7bb1c,0x00035875d5c58a40,0x000f531dd999d009}, {0x000ff3f98178ab52,0x000a7c4485d31888,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=3 [{1,2,3,..,}]*([2^12]*G) */ + {{{0x000bc092fe2354e8,0x000850a2f27fd64d,0x0002ad51407fff03,0x000808402ffc14aa}, {0x0007fbe516b67c4b,0x000f027098449910,0x0009af3715688b40,0x000dbddce7795e2c}, {0x0008a5dc626ec8f7,0x00032acc9e1305cc,0x0000000000000001,0x0000000000000000}}, {{0x00014a5956e30ed0,0x000921ce664e13cd,0x000b7485d5a678ff,0x0001d65fed6fe685}, {0x000152b7d0453dd6,0x0001e48dc7a066d9,0x00012560c3395f08,0x000d6053e587c1cb}, {0x00076afca630f2cd,0x000814f0d70553c7,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a19c3686b1f78,0x0009545540d3da61,0x000fed5fc9dde90b,0x0009be8908cbe546}, {0x0002b931292ec657,0x000e0b221531c8bf,0x0003dcf64709233d,0x0006a91e2913f0e3}, {0x0003880d89929920,0x000d07ab37b02493,0x0000000000000000,0x0000000000000000}}, {{0x000b1d587081c0df,0x00062b5f29f3ee6e,0x00013755e246f468,0x000c2e51e2652ae3}, {0x00046ba6a65e2952,0x000fd1b792013b94,0x00049175e7bffb43,0x000166af7dd896a1}, {0x0003d0d5f68a4101,0x0003a34ff29cf955,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b9e5f2e5de279,0x0006be9e4c557ee8,0x000c510883da6331,0x00016eedfba63955}, {0x000b55eba66cb586,0x000d93dd071f901b,0x0000d11e4c33f467,0x00029c2288bdd752}, {0x000f22d4f3c9b728,0x000416f979cce9a3,0x0000000000000000,0x0000000000000000}}, {{0x000f91fa66b3408c,0x0009041780ab3969,0x0001e17f9e99f2b3,0x0002825a0408a22e}, {0x00013e814b39af10,0x00017c70c14077db,0x000fd91116e8d047,0x00025157bba11642}, {0x0003d53fd072760c,0x000130f596860d22,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ddddf5d1e5c64,0x000b39631d236577,0x0005fc5e812c4b6d,0x000ec807d1cccab0}, {0x0002c8729f1a1c38,0x000999e4061629e9,0x00088f56b4c00d1c,0x000c3cac8f29781d}, {0x000b02141cce3380,0x000920c7e0e0cc16,0x0000000000000001,0x0000000000000000}}, {{0x000234580d88382b,0x000b0ad02da7d076,0x000cc82cf5ae2d27,0x0008a15c3adad7f2}, {0x0004d7009305d2c0,0x000e9e632a55fa7b,0x00011560b55b693d,0x0008b565732e2a82}, {0x000f0adb63788cf9,0x00038e2d1f605489,0x0000000000000001,0x0000000000000000}}}, + {{{0x00007e33611831c8,0x00062ce163c826e6,0x0001c1873d3e07b5,0x000df7813a79a532}, {0x0007451a6bebf65d,0x000789f014abc3f1,0x000cc2aa01512853,0x000bc25e7cee2985}, {0x000dd32f61a13543,0x000f9b061a57a2a5,0x0000000000000000,0x0000000000000000}}, {{0x0003734e520ae3c4,0x00041544fe045295,0x000321b2f9da98d0,0x0004ac066f5c4118}, {0x0004f9ed8d4d338c,0x000c2ea3577c3f4a,0x000a775eee973782,0x000efa3a3176188c}, {0x000aa0ec53f7823f,0x0009b227eec20996,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cab486125bb6b,0x000ce02028378ff0,0x0005e625f7d1c380,0x000dc7cec93bc7c0}, {0x000d0c3b6e1a5a67,0x0001da033baa95ac,0x000e0b126ba3c688,0x0005b900f71e6919}, {0x000cfb69d4bcab68,0x00090d9f859cecf3,0x0000000000000001,0x0000000000000000}}, {{0x00030307c7f8906c,0x0006bf1f14afae02,0x00001d0c8e70d7c3,0x00031fcdd396a945}, {0x00035972de152221,0x0001149c59aa6c9c,0x000e743c53f3251e,0x00072a17186bca64}, {0x000bae52281f6178,0x000c98982b2d35fe,0x0000000000000001,0x0000000000000000}}}, + {{{0x000abaada33bf5eb,0x000334cbe9475074,0x000503921efaf87b,0x0001a3119b05ca55}, {0x000a4fa919940136,0x000a8bd8f158f3c3,0x0002e855587cab4c,0x000fd133003309bc}, {0x000a468f055eab49,0x0008de65f435935f,0x0000000000000001,0x0000000000000000}}, {{0x0005a479ed62ca37,0x00046fb6c0237009,0x000c6558be89daa3,0x000e86cd9c606b6e}, {0x000dcb5426f2b48f,0x0002744bfa702fd9,0x000e9ceab7372571,0x000cd8bef4768a91}, {0x000d361ea2d4f5d1,0x0000ca847b5f94d5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c6a7b65b21bde,0x000fc723a29c73b0,0x000392643c39c3ea,0x0000b213f81be3c4}, {0x000e3ec734fa388c,0x000b26d37a33b98a,0x000332e230742689,0x000e28354ec1687a}, {0x0000d4b7e6935b64,0x000ba79d55aecff6,0x0000000000000000,0x0000000000000000}}, {{0x000073362910afa1,0x0007fb8bcd336bd6,0x000b6c7a7845b5f6,0x000017305633e845}, {0x00076a907be72df6,0x000e65734d2814a5,0x000f113c7084b86f,0x000cd7bad9f20758}, {0x000f6af2a5030c22,0x0001647ff1cabc3e,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=4 [{1,2,3,..,}]*([2^16]*G) */ + {{{0x00084cce9eb37269,0x000406ac65525f61,0x000c9acc4f25051a,0x0007bdd2651c4a44}, {0x00059571fa6bdb63,0x000cf1489d2ae9ce,0x000a821f56bdf324,0x0000e5fa827f61b0}, {0x00046a2449dcea62,0x000c947027c9ed4b,0x0000000000000001,0x0000000000000000}}, {{0x00095f1c50d4d450,0x0002c227a410cd04,0x000bc9ba135ee643,0x0004257073536858}, {0x0000b7e39c350531,0x00016eeb65d0616e,0x000e949a694a0693,0x00069aba0dc455bb}, {0x000d36d721f9d7b7,0x000a041dcb7a1d32,0x0000000000000000,0x0000000000000000}}}, + {{{0x00030d330fc15e51,0x0006a88312448f9b,0x00027c12fd1499ca,0x000b765eaf5a132e}, {0x0008d01b2d2a5c3f,0x000e3517c807951a,0x000936a97c68ed6c,0x000f8cdd161ce67d}, {0x0005d9876ad5eb28,0x0009976496ac4a79,0x0000000000000001,0x0000000000000000}}, {{0x000d912524de7c0e,0x0001e66e4dff627f,0x000a96a9194e4460,0x000ccae884a673b1}, {0x0005d06054966f81,0x00032269452eba8c,0x000ba7677e70b535,0x000298891e5c17de}, {0x000f9a70e2fe55a9,0x0004d48b39032dcc,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009dc9a72f4ff50,0x000df54e86b3f74b,0x000b7fc672cd56a4,0x000ac313c91daa4c}, {0x00053d8b04fac047,0x000047ffb771df8b,0x000a8ad48cf7c44d,0x0008bf663542e196}, {0x000aa68b0ea4fed6,0x000483dbd49e0b45,0x0000000000000001,0x0000000000000000}}, {{0x0007d603e389e5cb,0x000ee233664de2d7,0x000994f96855ef7d,0x000c5bf8c8ab10b1}, {0x000c2f5ab3d235e3,0x000bff37afff2ae5,0x00050de9d0fd0f4d,0x000ca6d91d5250db}, {0x00042da0be2c950f,0x0001c70ec3836fa7,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009b222a53c1578,0x000733b1bb114a22,0x000887f6c13ff59f,0x000d5dfb2679cded}, {0x0001fd35dec8bbba,0x0000930770ea94d4,0x0007da8d4f0a6019,0x000d2142901c2ad0}, {0x0002aaa8648f142e,0x000f42252e455969,0x0000000000000001,0x0000000000000000}}, {{0x0004f335e4753950,0x00010578c42f0d9b,0x000fda89975c2716,0x000761372c49b195}, {0x000583ac76051357,0x000cd0c4d54de0d0,0x000c35f47ffa549f,0x000731f21817e11b}, {0x000ac2b103f57a56,0x000284cde0cd7146,0x0000000000000001,0x0000000000000000}}}, + {{{0x000bb2a3bcba0504,0x00052359d22ba169,0x000ee4d727c18bc1,0x000338aababfd9ca}, {0x000cae35505124c8,0x000599b6e8a9cc3c,0x0003c6415386807e,0x00043919da2fc5ab}, {0x0001a4c6fd2ee43d,0x0007be38ead93480,0x0000000000000000,0x0000000000000000}}, {{0x0008c66b564a97d4,0x0002177834d44e8b,0x000690ef30774807,0x0007151d926feb1c}, {0x0003fbe2f1f3454c,0x00048ce8e6456bd0,0x000270c04a6964dc,0x000fe8febbc7afec}, {0x0000f159a483b3a5,0x000aca96cb139ad3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c0e9763d8a013,0x000baa65d7b1d37f,0x000608a4b87c8c06,0x0008c2592e527b8c}, {0x000aacc19bb3aa2d,0x000ce5b0adb09308,0x000e0f42458761d4,0x0002d73d4f707a6e}, {0x0003867f8d791c44,0x000c943ba7a1a60d,0x0000000000000001,0x0000000000000000}}, {{0x0007ffca3e51b076,0x000d23467af3d90e,0x0009427b9fa60c44,0x00054ce0e4a16358}, {0x0001655e4129aaff,0x000befd5ea275c28,0x0000ce27c03c7fcc,0x0000c97ca421b716}, {0x00069ee6f84bb35f,0x0007ec35e0436eea,0x0000000000000000,0x0000000000000000}}}, + {{{0x00033b8c99430421,0x000e3aa65723117d,0x0001482e2ca3fcee,0x0006dfdb52560262}, {0x00036a105a9eb6d9,0x000c0fd8b7bdc41e,0x000c58ba2f2edd58,0x000c050043d8b271}, {0x0009966a34a51907,0x000aee0fa52e13a7,0x0000000000000000,0x0000000000000000}}, {{0x000c2d7066d5fc91,0x0000d462accbe2da,0x0008397028d0b78e,0x000b525e2c9d107f}, {0x0003dfedd5666711,0x00083957250c9620,0x0006d0f2be094638,0x00026dd96c8ff985}, {0x00098fe829c7a670,0x000dacfc430b6d43,0x0000000000000000,0x0000000000000000}}}, + {{{0x000aba8bae3f0048,0x0006fc5f421abd9f,0x00094ac402ce8227,0x0005bead91f2efc8}, {0x000d28241f32e7d5,0x0008bce170cc1090,0x00050cb19f59df3e,0x00034ac35c2de273}, {0x0003cf90c3e6cfc4,0x0002a784bc2847d1,0x0000000000000001,0x0000000000000000}}, {{0x0003f87f754f1aa3,0x0003382713cbe9fd,0x00034163c334fd8d,0x0004cbe346cada61}, {0x000dd6aa94a54721,0x0007b9235830a042,0x000500be120acf2f,0x000d30c3e8d009be}, {0x000225e2751dc7f0,0x000714b7edd06e6f,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=5 [{1,2,3,..,}]*([2^20]*G) */ + {{{0x000c1256fe47d13c,0x0007012fd1181020,0x000c4a469315aa78,0x000b1163ea26a86c}, {0x000e4be00b905056,0x0002f1dad4a0ac68,0x000e2d8c19c57695,0x0000bbc11daec6fd}, {0x0003baf9c6293f81,0x000d375056fba03a,0x0000000000000000,0x0000000000000000}}, {{0x00073f08bbfc9af7,0x0006c14cc716b559,0x000b5b613b18efce,0x000f005d64d3ad94}, {0x00034ba83b800248,0x0009ee4cf2a375eb,0x0007d29413af2a4c,0x000525ea872268a2}, {0x000c082bd8d12fde,0x0006fa2d233189c9,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f1bef2c1b123b,0x000c9ca73fb5cd85,0x0001a80d76a111a8,0x00025f888d3b7461}, {0x0003f7765b87f2e3,0x0002e36012c8ad9e,0x0009dc42c7cf6c49,0x000d7d5db366bf5a}, {0x0005359f96228a81,0x000772725123cd91,0x0000000000000001,0x0000000000000000}}, {{0x0006c7a0e2cfcba5,0x00097fa38cc5da8b,0x000b43bb38eee14f,0x000f15c0770c4afd}, {0x00093138850f3aa0,0x000658cf7e3953b9,0x0007c8bb70f07792,0x0000d78fd38c1d44}, {0x00023ebe4681177a,0x000c9d704ca7518e,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008fa7e4527a9d3,0x0004db4e9fda74ba,0x000404855f433494,0x000f130f65201753}, {0x000d719a9846d31d,0x000c651ab9661cb9,0x000b653c04c2995b,0x00031b2c3fb591c2}, {0x0000b91d21b65fb3,0x000c1f9233b624c9,0x0000000000000001,0x0000000000000000}}, {{0x000eac108061f9eb,0x000a2e86d9cc5afc,0x0000e2ec8f94cdd0,0x00040675309b7d38}, {0x000320d2223f6f2c,0x0003be480dc1e34e,0x0007b72b364f62ba,0x00063595753dec52}, {0x000283d90f6639f0,0x0001d567ed0c354e,0x0000000000000001,0x0000000000000000}}}, + {{{0x00067e2e3d478324,0x000b9d2b33e93756,0x0005cc9c7d0711cf,0x000aa7c2edf0adb9}, {0x000b6610b704fc5a,0x000107368e770150,0x000cc4ef9af2a471,0x000afe1e566d06e6}, {0x000a67146814dd0c,0x000fd36c67f6637c,0x0000000000000000,0x0000000000000000}}, {{0x000b744b33ca6a46,0x000a2ad960d19dec,0x00099ff41dbc0bcf,0x000977ca933b28a6}, {0x000a7951faf63b97,0x0005168f23ca3752,0x00097d901e0f16b1,0x000105f55f964ea3}, {0x0003c0d403b374a5,0x000d43e408ed3a81,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007586c50a55f86,0x00026583c230d093,0x0009c8f1eaf61062,0x0009876910419f67}, {0x0006e8d67dbad2c6,0x000c3c184d440783,0x000753899fd2f814,0x00037825fefa52a3}, {0x000f0758545a721e,0x000498a4b823d5ff,0x0000000000000000,0x0000000000000000}}, {{0x000e376ebd4ed258,0x00004d6a23fbe496,0x000b69ec3505f765,0x0008fe6b545afc26}, {0x0000e87ed2073fb2,0x0006145047af95f2,0x00053f84d27cd1ba,0x000fa35d865dc4cc}, {0x0007b711a9ee96b7,0x0008ec430aefdeb0,0x0000000000000000,0x0000000000000000}}}, + {{{0x000354ba169146af,0x0008c79fdb88cac7,0x0009f85e2efdc64a,0x0001012d7f3a69d0}, {0x00017d2bed232563,0x0004dfd89cfd4d1f,0x0008288e64d46be0,0x00089f8bf20fd559}, {0x0001d08641f269d1,0x0009fc333e29ffc1,0x0000000000000001,0x0000000000000000}}, {{0x000c7dab1b832059,0x000223bbef8e949c,0x0007f10fed75c714,0x000647b0bb61d266}, {0x000b8e823dbf309c,0x000601c5a1f58db2,0x0009c023a71fa3e4,0x000a0b5cbdd6344f}, {0x000df6a6577b11f1,0x00027e6eb12db5f8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b94e9f2c64c2a,0x000dff9c4cc3460d,0x000339e03c0646b9,0x000ca76c7ae26f18}, {0x000612ba1712f64d,0x0006950e5f2c8040,0x000569eb5bf0fae1,0x0006185858b613d1}, {0x00080b1245b35ba8,0x000d9a3c93740668,0x0000000000000000,0x0000000000000000}}, {{0x0005f1c44e1c9646,0x00061096f83044ee,0x000e69176fe10924,0x000a78875cfb2614}, {0x00007825516a8324,0x000065d69cfbad90,0x0001f873d71727bc,0x000185c81c530662}, {0x000c1471ae21856f,0x00047e68582e4e3a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ce1c67b68f07c,0x000dfa5469124c9a,0x000ccd6db2024f3d,0x0002fc6faadd52b4}, {0x0005124af076574a,0x000510591517b271,0x0000081118a106bb,0x0007cffda2d67e24}, {0x000b3b39fc6925ec,0x00012037b374e288,0x0000000000000000,0x0000000000000000}}, {{0x000d91b81541ec51,0x000c413a683e17ef,0x000952a60eda72b7,0x000b61d80495c130}, {0x000f6bf06a5749c4,0x000c7cbd39872c4b,0x0001a82e01cb7ce0,0x0001726d7547989f}, {0x000742de944906b4,0x00009f2e02ff3752,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=6 [{1,2,3,..,}]*([2^24]*G) */ + {{{0x0000872f1cba7983,0x000a9c28a369cd44,0x00007ce63b6f5daf,0x0009c12dc12c54cd}, {0x000a00a67eec84f7,0x000bc7a4edee7a34,0x000ea82ff4e7f63d,0x000950ab492940f7}, {0x000953027dc3353f,0x000be21b37a3c6cd,0x0000000000000001,0x0000000000000000}}, {{0x0005f758ab77d6e7,0x000bab416ce18f4c,0x000b9e45e70a1adf,0x00038074a53a6ae6}, {0x0005919bbc5eaf8e,0x0006580a40639d33,0x00033f83c3446f86,0x0009f20b5de7abe3}, {0x000a42c48703c063,0x000ed659dbbfadd4,0x0000000000000000,0x0000000000000000}}}, + {{{0x00025b49cc7d0744,0x000d5ca66a4107d0,0x00009a278704a0b9,0x00027e26383562d7}, {0x000c28bfb3e1fb8b,0x0006132452cd156b,0x000d9a249ca82ac0,0x0005a22d3a0e92d3}, {0x000b19aafd34655b,0x00048d36ff20dea2,0x0000000000000000,0x0000000000000000}}, {{0x000f6b3025835a5b,0x0008531143727c86,0x000c5c003858192a,0x0001da9352b2fd4b}, {0x000d25e79d62bdaf,0x0003c74903de7c27,0x000ad4718fc47302,0x00063e48286ed6b3}, {0x0005e2dbee1fb246,0x000857558feb16de,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009f56e96a543bc,0x000d31c6bb399ae7,0x00031b99e11a37bd,0x0006c0e42fdb7dca}, {0x00074aad0723ad0f,0x000aae97e4f8e5ac,0x0000fdee33ad0efe,0x000675078a78e14a}, {0x000909b38b03996b,0x0007469ca609f2ac,0x0000000000000000,0x0000000000000000}}, {{0x000466dcc50132b4,0x000eddd95df5a1fb,0x000a8d9a82cb91aa,0x000178685d056d78}, {0x000f44580cbb5024,0x000b8404125b7ea5,0x000c959397a21279,0x000b3c397b77ec41}, {0x00050358651ee34e,0x000febe48525c5d2,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003aa997f7f37af,0x000bd0399f83a0f3,0x000f152344eac6ee,0x0003cc5d1e36ba58}, {0x00058bcb7b01bb23,0x000e6e01c3b95ccb,0x0003f3cbd70b3470,0x0005471f142928b7}, {0x000f33fe8192a8fa,0x00067751b82a4272,0x0000000000000000,0x0000000000000000}}, {{0x000ea1f801a1be23,0x0000e029d67e2091,0x000355df0fe9219d,0x000069ec86128187}, {0x000e9196ceb57b88,0x000b831fc0c5d6f3,0x000b18561a90e72c,0x0006875cf51476cc}, {0x0009d0fdc775daca,0x000556f11fb0d65e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d755a99415514,0x00085952e4dc0b72,0x000ddaa98f7198b9,0x0002cf0597f96150}, {0x000e7060ed10994b,0x0005df6128c96445,0x000ea5cf35637a95,0x000b47cf25cfbeee}, {0x0003e924da7f8ade,0x000d5d59754f0973,0x0000000000000000,0x0000000000000000}}, {{0x0007794536974a33,0x000bee39625b4887,0x000c916eff917626,0x000c143d7b2fe99a}, {0x0002b42a1f214f15,0x000a92c52323d0ac,0x000fb97a09db1674,0x00097d2bc99da798}, {0x000062e5a6c7b18b,0x000498e32a3a4e9d,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006f0528c6a99de,0x0005f78365a5404f,0x000a6130da7d607f,0x000ce8f385d457a1}, {0x000127a71db8c282,0x00075b1780f22e8e,0x0005f271ed981d16,0x0000879b71615445}, {0x0003f2395d4c8d2d,0x00002ffbb885eae5,0x0000000000000001,0x0000000000000000}}, {{0x0004e8a699830814,0x000f60c1a29f03dd,0x000620f1843d15d6,0x0005370351aa6497}, {0x0003f3bdc3d85b92,0x0005713630b15aa8,0x000b25038bafd76d,0x000aa324c45046f5}, {0x0008ff854c7ef0e3,0x000f873074cd9a42,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a5c1655f0c965,0x000ad8760b75d0c0,0x0002d3b7a7dc8ea4,0x000d9d864941a528}, {0x000eb47e8ca867c6,0x0001a8847066dfb5,0x000249722cfbbbd6,0x000d270c27ad4dec}, {0x000e74307c896550,0x000812fcfddc8f52,0x0000000000000001,0x0000000000000000}}, {{0x0009df50d9240b18,0x000a5431583e94ff,0x00044e5e649470bb,0x000156c0cde5a76d}, {0x000ad9f50c93b508,0x00099e86567b7ad7,0x000e7618f9dede32,0x000b84978d6f1f46}, {0x000aba70858d56a1,0x000626f5aa274be1,0x0000000000000001,0x0000000000000000}}}, + {{{0x00038150eda6a189,0x000d5498edde21db,0x00010e8c4a802c3e,0x000d570892441512}, {0x000a6f9b009f95d3,0x000c80e954785d69,0x0008dbfa197859ea,0x000f9a954ad6166d}, {0x0005360545cac81c,0x00042d01aaa83bd5,0x0000000000000001,0x0000000000000000}}, {{0x0008a0342c362ba4,0x0008202cf6246957,0x0008c4987d0b8dd8,0x000becfec2b48e0f}, {0x000a0d5c621a63b1,0x000668f2b6a90343,0x0008bd4fe098700f,0x0008bd8fa8829c08}, {0x0007948513f0936a,0x000733ae92e72067,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=7 [{1,2,3,..,}]*([2^28]*G) */ + {{{0x000f8517a4c96e5e,0x000b0e039e54c124,0x0001ec83d522549e,0x0008ead8eb02627a}, {0x000ef95771e9618a,0x0004f3a6b4497c2c,0x00055a41c4917c7d,0x000be8babd80080b}, {0x000548c7990585b7,0x000c64dabe54a06c,0x0000000000000001,0x0000000000000000}}, {{0x000269bac978d382,0x000c6bdf9b98b02b,0x0000247e075c4ed8,0x00030716d8e1a299}, {0x0003a019c94edbc8,0x000c1665fb3458f3,0x000e700cd4d82fa9,0x000a2326e507ff63}, {0x000452b8341c9bbf,0x0000dfc9214a3f5b,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001109faf34910d,0x00006e16fb098733,0x000f23db2247dc5b,0x000f53ef62c76a0d}, {0x00018f68431633f2,0x0003cbe6a9413972,0x000253b6d05ffc26,0x00047ed103a8b14a}, {0x00089d6938ee0b45,0x000f4f3310d7c6f3,0x0000000000000001,0x0000000000000000}}, {{0x000ae5ea5e61f0fe,0x000803eba63d9ee3,0x000ff5d7d44281cc,0x0006da525a289454}, {0x000688b5bf3e7fa2,0x0006c91ab88b9a08,0x0009907565a2877f,0x0001737c021210a3}, {0x00031db551223d6a,0x00041419f277aae1,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ab41a098c92a7,0x00072fa6811333e6,0x000851f03fd8fe3b,0x0008e34493163c43}, {0x00028174f0009cb6,0x000db83d4e177695,0x0004d1bfc734499f,0x000c56272647cc55}, {0x000d38b2b770d722,0x000fcea5c023f6ae,0x0000000000000000,0x0000000000000000}}, {{0x000d52df57e5ca52,0x00065ec98ce0bb77,0x0002140495f37162,0x000d03a5ffc6d632}, {0x000f0d0061a4f743,0x000af61ada3e0094,0x0004b70091a92992,0x0003fe83591d84a0}, {0x0008b7e8b2e59f37,0x0006892e459b7561,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005e28d077485e2,0x00020e97a1a0b220,0x0006679b5d8662c1,0x0000da8bd256806d}, {0x000925177882d56f,0x000fd447d9b3a0c2,0x000077e15eb4fc81,0x0000f15d98b7d44b}, {0x00021ac9944ac5bb,0x00096438b1a53927,0x0000000000000001,0x0000000000000000}}, {{0x00015ec8db3161c2,0x000f397c19309926,0x000de0771a46014e,0x00075e027929bb3e}, {0x0009dcd3fad002d9,0x0008c634c3d387bd,0x0009c3f4ebf24793,0x000a2c2da2b50807}, {0x000e85151e2b2209,0x0005f4bb80ad2ed2,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d84a6577d1d88,0x000209b195d9875f,0x0007dc25315ab09e,0x00041e59650e28f1}, {0x000f81b07fd77f04,0x000191d3288a8ccb,0x0001838964e3273f,0x00014aa2bd5786f8}, {0x000d924c29c83190,0x000d240eca2dec17,0x0000000000000001,0x0000000000000000}}, {{0x000c94cf500620a8,0x00017a01ff5bfc59,0x0001d4396ff8b7cb,0x0004fb6ee69226c5}, {0x000565facfed55e4,0x000fa0b30de43edc,0x000b20ea8612b643,0x00056d93e66dab8d}, {0x00098f9a9e46bfc5,0x000537cf26d7b09b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ab3bbacf312ed,0x00003114377687ca,0x000ecbe360e1fdea,0x0000336e644349d4}, {0x000ce9701c97498e,0x000b970f76e36640,0x000d18aeb034f110,0x000d8c04737b96e3}, {0x000b828ff89d3a4a,0x000ceb091b279c08,0x0000000000000000,0x0000000000000000}}, {{0x00002832632c0b79,0x000f06083c30b6b6,0x000d6d46a5784fec,0x00018a1a822c2ef2}, {0x000ffd16846c810e,0x000859c7f32abfb3,0x000410206687e5a6,0x0001a4731948bcab}, {0x0009310e425eab64,0x0006640ebb114d39,0x0000000000000000,0x0000000000000000}}}, + {{{0x000759039c7a9d17,0x000c2d4dd47b8758,0x000c1f2cd883e5fd,0x0007f9cf12cfd22e}, {0x000b330c8103c8b6,0x000fef902907b0c0,0x0008540db26c476e,0x000e726a64472792}, {0x000b090ef761ac1d,0x000f96107e57dd18,0x0000000000000001,0x0000000000000000}}, {{0x0004650aeff40f19,0x000f9022a822976b,0x000a5007e542efc8,0x0007e6336d263df3}, {0x000d3e6b563a86e0,0x000fc14e677c3dd9,0x0001920cf4b81cd1,0x0001cedaf8056af9}, {0x0006ebfcbc28b238,0x000af30ce3975f89,0x0000000000000001,0x0000000000000000}}}, + {{{0x00090c95c3d0b9c7,0x000844b8f686b48f,0x000a746779417d91,0x000bd2f6b498e1e2}, {0x0002adf2e61e9354,0x0000db08d1aea1ed,0x000a497f347f08db,0x000c7871378402cb}, {0x000753c735de0850,0x0001f9ed5b707951,0x0000000000000000,0x0000000000000000}}, {{0x000d045e45f819b7,0x00024591e83186d4,0x0002f07b1add4180,0x00067074059bab68}, {0x000ea2b0f371c1d4,0x0000e5f219b0e391,0x000f844f22e68c28,0x000679b7f960b058}, {0x0002502036ca9899,0x00028a1f63acdbd1,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=8 [{1,2,3,..,}]*([2^32]*G) */ + {{{0x00023b6569acb75b,0x0008bff580463d22,0x000bd3d896f7a55f,0x000bc35819d6f3c8}, {0x000fcf8dfdd32dc1,0x0007477a57a2786c,0x000a3b0ae5589b65,0x000806de5eae9f47}, {0x000782fcd93f2178,0x00096dd9479ee32c,0x0000000000000001,0x0000000000000000}}, {{0x00029435cbeebc5d,0x000d8352a35de209,0x0004ce809af5b11d,0x000a76cf080ab8c3}, {0x0002250478b1ce25,0x00003b3ff7216bfb,0x0004133d87f47621,0x000a4132748099b3}, {0x00029b68995f627a,0x0006fb62b3cf30a7,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009267d43d108b4,0x000b5b0396f4d947,0x000b1e5f7f088692,0x0009c3c1fd9437e3}, {0x0006cb9b9b7fa950,0x000a37b6c115a75e,0x00062d05b42f650b,0x000d5b3cf510dbbc}, {0x000a49bf06d5fe62,0x000049824e6593c6,0x0000000000000000,0x0000000000000000}}, {{0x0007f70f36b1fb53,0x0004a3eb94fc53cc,0x00082c0e60f6a2b3,0x0002888aea4bc9d4}, {0x000d37ab9ed318f4,0x000a505ae0c0fe3e,0x00082c9e94fad3b1,0x000efa0f31285453}, {0x000bd4be69ae4fb8,0x000003a516fe8844,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005e8088591d8c2,0x000c6e24bb4a7ab3,0x000968fd3709e47e,0x000d55e3e7d95582}, {0x000f8783f2538474,0x0003b454e19d35c0,0x000724c4578fbe58,0x000b98f51326114b}, {0x00090d99b97ee546,0x000691801229b8f1,0x0000000000000000,0x0000000000000000}}, {{0x000e4a0a2aa86765,0x000aa08b19b4b67e,0x000c220cb11d4f5f,0x000c7d426ad0862b}, {0x0002dd7a63508ce1,0x000aae47773236a7,0x000cce936cda4ace,0x0000808ba7a0be3f}, {0x000c14a5b972c384,0x000887cda4655c79,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007786aa39096d4,0x000a4070017bccec,0x000926b1ae026576,0x000026855e810d17}, {0x00039def24d306c0,0x0008ac55c7d826c4,0x000b521e40f66cc7,0x000ae26697c9fbf9}, {0x000a75caf01aaaf8,0x0002a9d094aec346,0x0000000000000000,0x0000000000000000}}, {{0x000a161f4c1b67b7,0x000e72cc3c7e5f99,0x000fefa749b88977,0x00063737d6e24cf4}, {0x000ed4607a910568,0x00017686854dcfe4,0x00011acac7bc09c0,0x000cc731394d9ec2}, {0x0009e4dd8ac76909,0x000bc7246fb612d5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d5c2ad970ea88,0x0000eb7dbc22b4be,0x00070d534e1a9e33,0x0004b0eab21921c0}, {0x00071b3a90f4b6c3,0x00015ce8387fd7ac,0x000ec28efad61dad,0x000f792985d577d5}, {0x0009ac313d175e05,0x0002d86582a5f995,0x0000000000000000,0x0000000000000000}}, {{0x000258f797f0af53,0x0006198f53a67607,0x0008e97661c802c3,0x000001f410140442}, {0x0003c270534a9c94,0x000a5333d3d840fe,0x00076ed16f99ddeb,0x00021b94ff80e532}, {0x0002761460189f70,0x00007bce48c909c6,0x0000000000000001,0x0000000000000000}}}, + {{{0x00018e1640843ac0,0x000d435c11720f14,0x00057cebd3881c75,0x00023104876137be}, {0x000da25ae87bc97f,0x000052fc640f68c5,0x00027372b9f14882,0x000b4e854fcb3017}, {0x0009d3406b0f1a39,0x000e653db1df6886,0x0000000000000001,0x0000000000000000}}, {{0x000c416fe50a1e7a,0x000c29b7a99148a5,0x000d660bcfe2e7c6,0x000630309213716a}, {0x0004b63e38c0d1fe,0x00033bb86d3923a4,0x00056213e592fda9,0x00080b360f884315}, {0x000db3b21dcd9fe7,0x000617bc0a7836eb,0x0000000000000000,0x0000000000000000}}}, + {{{0x00035cd63c7c9de3,0x000a91ffca828c02,0x000b3e377bfdd504,0x000496682e625999}, {0x000b8af1c462d519,0x0009570d96676ec9,0x000bf815f3869cb1,0x000b476a8b4fba76}, {0x00057597ce654eda,0x000e2235375a2127,0x0000000000000001,0x0000000000000000}}, {{0x000e9252adfeeb9b,0x000707b233b4a650,0x000ab158faa771d2,0x000df78fbc7a8536}, {0x000be88e5009a864,0x000abbc52635e311,0x0008769bd53cfa60,0x000305e36a566f93}, {0x0000e758e66271c0,0x000b10e12e9cdd0e,0x0000000000000000,0x0000000000000000}}}, + {{{0x00092f38031c9da3,0x000f6f0dd54d0455,0x000298fe24144d05,0x0006274ae2d191b2}, {0x000909113fc1ead4,0x000dea702ccc54c5,0x00008c5763ea8c10,0x000635441e7274f2}, {0x00006b2f2578c573,0x000c3b8134369537,0x0000000000000000,0x0000000000000000}}, {{0x000ada464a85cfcd,0x0006064c2605a588,0x000004bbf31d5464,0x00010805ca04e18d}, {0x00067998cccf9032,0x0008398a6f896278,0x000dacf8d2faed14,0x0002de01ea7eca85}, {0x000eb7d829278474,0x000eb89fe5859b0f,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=9 [{1,2,3,..,}]*([2^36]*G) */ + {{{0x000a73aaf5f01aa9,0x0009abe5e08d9505,0x0009fd8bcd318e91,0x000915895b386f06}, {0x0004a0b5abd07d68,0x00039901b007bc24,0x000ff05c36936913,0x0003179dcef7684c}, {0x000125196e69b799,0x000a2823db7308b0,0x0000000000000001,0x0000000000000000}}, {{0x0008e83616d0d063,0x0003bf0c66e267f8,0x0006d375b822f9f9,0x000dc02109656c0d}, {0x000530c1fc16b6d5,0x0006bf6541ba81db,0x000443cb4caf94b8,0x000a87f59d3c1a6d}, {0x0002afcd60e10fe1,0x000a088d7e1995b7,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005b8daa50517e7,0x000dbed46676160a,0x00016e7a7e78dcdb,0x0008e1fc1b0f5e9c}, {0x000933cb9503e917,0x0006f78b36f2294c,0x0006ec3420442aae,0x000c01e17c7ffb2d}, {0x0007293b87d30fdd,0x00092836bed4739c,0x0000000000000001,0x0000000000000000}}, {{0x00075943e2ebfd04,0x0007b784cf37b849,0x000645eaa02ab285,0x0000b0ace12a0d65}, {0x000ff267c93aa3d3,0x000fa6954230be3e,0x00001e1903aa7ed6,0x000c311ae0c82cdb}, {0x0005f0bd3c5056d4,0x00022094d54a9827,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001c0660a4f2bbd,0x000c3d2fe061f455,0x000a2b6dd7091d40,0x000bf7437cc4883d}, {0x000f258011ddabd2,0x0001bdaba7aee852,0x000195b39f463ce7,0x000efb33b881bd7c}, {0x0007d695aede085f,0x000380f8fa2471bf,0x0000000000000001,0x0000000000000000}}, {{0x0006eeab983554b4,0x000f138a6f5a6dc9,0x000b29f154f07f71,0x0007d1c7242d7a9e}, {0x00042f3c7f1afb70,0x000af2896b44aee8,0x000b55601f569990,0x00061e36ed07c5c5}, {0x0005430facca2678,0x00016ea78eb21424,0x0000000000000000,0x0000000000000000}}}, + {{{0x000aeaaabe68e207,0x00098b6eaee3177d,0x000f5c1267a6e353,0x00092ae2d01bbbbb}, {0x000bf3af1a4f4a2b,0x000532088e5cdfa4,0x000c8ee638a58f55,0x000bbce5e7aa2a0e}, {0x000a1644879c3f50,0x00025e378387c246,0x0000000000000001,0x0000000000000000}}, {{0x00069ee8884e88e1,0x00090f8ec2984b67,0x0001f9e47bd62fea,0x000f9867e7522665}, {0x000cb916cb0493d9,0x000106987f5be2cc,0x000869c71156e1c1,0x0005011576bd7bad}, {0x000b76a6e945007a,0x0000aec18de41f38,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007c59949c6f67a,0x000c897a229d2368,0x000118e3e788aa53,0x000794e3080e973b}, {0x000815a91046f15c,0x000ac04ed530c0f2,0x00078a4fe35eb925,0x0001fe18e7070c54}, {0x000f409ce7d9c57a,0x0008aafcd17edd4b,0x0000000000000001,0x0000000000000000}}, {{0x0002850fe8174557,0x00037e234694753d,0x000c528ec7d2c45c,0x000bdd41f346792a}, {0x00032ca964be2a36,0x000fef3e7911d679,0x0000101c72673a03,0x000653d6358ef0bc}, {0x000f874e2b9caaba,0x00045ebbcc31882b,0x0000000000000001,0x0000000000000000}}}, + {{{0x00090baa505384e0,0x000993148d7d8454,0x000d948464cae379,0x000f46feac4f8ace}, {0x0007268d1b7c8dda,0x0000d4770e6c39b6,0x000c1955967ac571,0x00052098b74830a2}, {0x0008d17fe1904773,0x000191e5071ced85,0x0000000000000000,0x0000000000000000}}, {{0x000b4f003b56551f,0x0000872a7e419344,0x0001262c90a767f8,0x00015a9791770fa4}, {0x0001a4bc5606e253,0x000a665041696dd3,0x000da6d7ec137466,0x000cac07c562bd01}, {0x000c4a92e59de1e2,0x0007068f7d29994b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000172698b05a9bf,0x0000570dde3c4b9d,0x0004dad7e2ab8a86,0x000cc4fe376d08bb}, {0x000df2d396e50709,0x0008138716b38f91,0x0004e9a6a45d9577,0x000feda477817a06}, {0x0007062a4f79bf83,0x000ca12aff8e0103,0x0000000000000000,0x0000000000000000}}, {{0x000748577bd0ea3b,0x00068ca23c2d1e49,0x00079fc968bdb9b4,0x000359089d5d5807}, {0x00037ae7478afb4f,0x000f6ac1a17ffb5a,0x00076fb0ad6d0956,0x0003cc73da4935d0}, {0x000b38ddd4e896c8,0x00091fcd942654f0,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d06bf88e947b1,0x000a0ca717a0accc,0x000b428946c6ceb8,0x000992652bd2594e}, {0x00041806882365c1,0x0004f2f3523a8241,0x0002e27b634a60c7,0x0006f4680f2b83ce}, {0x0005e159f3342680,0x00053718c76ca148,0x0000000000000001,0x0000000000000000}}, {{0x00063dec4e0c9dd7,0x000cb7d74bb74e1f,0x0004a5f09446f95c,0x000f4555c75d0662}, {0x00028d6e7583fd36,0x00083fa30323cc2b,0x00010012c0c49bb7,0x0009907cd3d64f77}, {0x000c79e69ac90f89,0x0006c12cb352bde2,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=10 [{1,2,3,..,}]*([2^40]*G) */ + {{{0x000bc2a7fe05ab80,0x0001a246f49f7a93,0x00091072db7cc0b4,0x00011f97d30ac7ec}, {0x000169de685e7537,0x0008a2ae9aef0acc,0x000e3c46bded4c6b,0x000604789cdc4497}, {0x000a082feb2b2ea2,0x00078fe890cba4fe,0x0000000000000001,0x0000000000000000}}, {{0x000edbc5c5076824,0x000298a472aca466,0x000a80660505ad15,0x0000c1cc1b16ca97}, {0x000dda2937bbf38b,0x0002545fac4d56c3,0x00090f07e35494b7,0x0000903e9ca74b57}, {0x000b43111b0c8bc4,0x0005465923f9e9c4,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008b52bfb73ff4e,0x000a4d6410d489c1,0x000ae318bb528530,0x0004b71f3f7d7028}, {0x000970b21b686b53,0x00001ea2751f5995,0x0001322663379ddf,0x000e77c11915800a}, {0x000261c476db4bea,0x000ae8e89c22a1e3,0x0000000000000000,0x0000000000000000}}, {{0x000e16965a7b1dfa,0x0009afd6426762fc,0x000532ec13f2e53d,0x000fe4131e801ed5}, {0x000c86963e2f9e9e,0x000f46e5098aecc3,0x000faa2b47801a35,0x00043b6f3406c3d8}, {0x000b57971349f37b,0x0007d749ef39f4ad,0x0000000000000000,0x0000000000000000}}}, + {{{0x000dcaceb126ca58,0x00046c5a73dec3f9,0x0000e0ffb30d8879,0x00026935e7e62831}, {0x000f5e074c83b841,0x0008b04291158a7d,0x000f72a08eaada21,0x000a40d05438fa20}, {0x00005e6ac9aa8c4a,0x000b92b755928484,0x0000000000000000,0x0000000000000000}}, {{0x00081326c74e90da,0x000cdbf1a037a879,0x0009887e29013ab2,0x000ffd6598bd3d86}, {0x0003b3c803a95fec,0x000e4c50722fd839,0x0004e70129b699c3,0x0000fa72cdd65e3c}, {0x0000ccbba65f24da,0x0008975325682f6c,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008d8231d21b98b,0x000f46eede07ff72,0x000c57dc8bc52ba3,0x00096a93bbd28782}, {0x000609e0a7a0e49d,0x0009fbe4aa495765,0x0004c5f79dbfb8ae,0x0005e1789960cccb}, {0x000b74da3d25ebfd,0x000c2e56df642b09,0x0000000000000001,0x0000000000000000}}, {{0x0007057a2be83a30,0x00026ba759ce4dd1,0x00057744ef0ab9d2,0x000c9ee2b7115a63}, {0x00000d77f24c2ddd,0x000142ea1adfee89,0x0000f3fa9d5346a2,0x0007a84ecd7e6d50}, {0x00035caeb7a1527e,0x000c8110e6262dae,0x0000000000000001,0x0000000000000000}}}, + {{{0x000457989aea7c3e,0x000a16bd6196a6cd,0x0006f76c2cbdd85c,0x0005840dcfd847e9}, {0x000ec8ea001b3aa2,0x000898be24444e27,0x000397d8a0c53dda,0x0003fa5f98a5b3e4}, {0x0008e197364ea986,0x000bbd922c6bbfbe,0x0000000000000000,0x0000000000000000}}, {{0x00064b7db5084e37,0x0008c954735a1906,0x0007371d65a99056,0x000bdaf052b4c902}, {0x0009ec2cc9668600,0x000adac668469729,0x0002f7ceb4949cfb,0x0001eda14ca03327}, {0x0009270923989fbe,0x0002a80f1714c9d9,0x0000000000000001,0x0000000000000000}}}, + {{{0x000da9fadd2d2e35,0x000ebe39d9c06e00,0x0007878b1c269b9b,0x00045c0350e16aa4}, {0x000d604f7fb31a05,0x000233dc435d57a4,0x0004a59629977c5d,0x000caa747e5387e5}, {0x0006980680cca577,0x000c7f3aa2473480,0x0000000000000000,0x0000000000000000}}, {{0x0006ecf72ff177c1,0x000ea087d84398f4,0x000f8e3dbad5b5e3,0x000793b7c29bdf29}, {0x000d48b4ad4a2c86,0x0004cf9d25337e0d,0x000be01c858ea723,0x000fe90a676bb282}, {0x000306f507590c7b,0x000915155053c47d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000311b42bb970cd,0x00056fa08e6727fa,0x0006285b2f7609fc,0x000807c307ce1a3e}, {0x000d8c9c1df6de94,0x00070b979619a317,0x000fdde052a3379d,0x000baa7d20b3870e}, {0x0006e443d8f7406d,0x000355511beafebb,0x0000000000000000,0x0000000000000000}}, {{0x0002e82c90634dd6,0x0002249d51e499d6,0x000615ca9d89995a,0x00097ac7d99162d9}, {0x0009551034000ab8,0x00070ca9d924f35e,0x000b526853be7dfb,0x000638dc8c8aff11}, {0x00031fb01463b8a6,0x0004e7b55e740433,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008d4f13a03485a,0x0004c5dd3ccf1850,0x000d8ab1776f2552,0x000a54a5e0bf0c9e}, {0x000e81226e24a017,0x0000e5b1ecb9626b,0x0006acb8b7b3bc5b,0x000414da0130f24c}, {0x000b2f1d94673605,0x0003ae73af8b9c7d,0x0000000000000001,0x0000000000000000}}, {{0x0001a4baf806025a,0x00068cf7b99ef6b1,0x000b70549901e9bb,0x000cc5d4a5ca0071}, {0x000b555009f7be57,0x0008dbaab6501aba,0x0005c582d17b21b0,0x000d9921c7bacde3}, {0x00013fb4b9991c48,0x000d72c6f664c93f,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=11 [{1,2,3,..,}]*([2^44]*G) */ + {{{0x00000e09c15f3e5c,0x000f97f45b409fb9,0x000ff4a01087837b,0x000d204b2bcafcbc}, {0x0000a0da165ec6b8,0x00011716978423a6,0x000f2f7f8295351b,0x00081f58e2d13eb1}, {0x000ed84592b66922,0x00025f5f9819aebb,0x0000000000000001,0x0000000000000000}}, {{0x0007ea077d668278,0x000b9653ee2ff77b,0x00098e8334b5b359,0x0005210487baabe1}, {0x0001a95a5886c85a,0x00009649f4c23788,0x00056127f95c6f68,0x000aed6c6419d339}, {0x000be49aa657d29f,0x000da67ae0b376a5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fb32bacbbde73,0x0004f08a721e3545,0x000584020b45c467,0x000fd3a284a774fc}, {0x00004477afffeada,0x0006a2c4ec266e10,0x00066dc326c6652d,0x00070b3a65b94280}, {0x00055b8104c7d5c7,0x000d8c4b6af237e3,0x0000000000000000,0x0000000000000000}}, {{0x0000b97b7ca1cffd,0x000435de1358221c,0x000876cab38cc7ac,0x00054cdc8f30b09e}, {0x0000ccb3a4f5aec6,0x0002ac30ca26a9da,0x00011038e2a6fa3b,0x0004545c20a577ee}, {0x000bff8e2f50fb14,0x00093158359a6d97,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b8fa7bdc8384d,0x000f2859e636e718,0x000ed301cc9c465c,0x000006a5b105b2b7}, {0x0007075698827d1b,0x000fbe7e34565b30,0x0006110c56ecfa0a,0x000be3136324ecec}, {0x000a684fbfe59f06,0x00056bc39bf313cf,0x0000000000000001,0x0000000000000000}}, {{0x0008543e894e8a16,0x0006d339681c386b,0x0001fc0aac97005d,0x000c6eaa38aa9f79}, {0x000a90d6089956c5,0x0005ec33374fdc05,0x0007a4eaa1631484,0x0008df64f8ad9e1c}, {0x0007f44336b984af,0x000859e7ad53b8dd,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c8ba9ccf89d24,0x000874ddf8d1b9b2,0x00027291ffd7f24e,0x0008bd9d563287c7}, {0x00065d01bdb48d02,0x0001b99b973b0c12,0x000050d618319b97,0x00038420d531f686}, {0x000d7c201c411c3a,0x000d97468eb84cae,0x0000000000000000,0x0000000000000000}}, {{0x000eb2fc05bf609a,0x00073e1dab9da1f6,0x00049847c3ac275b,0x0007880554d322f9}, {0x000fedd0cd2b7f05,0x00085bb3e74958ea,0x000fcd8d9061a481,0x0006f9ac370d5c6d}, {0x0004cb188a021786,0x00057aa132c3b5f5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a082d83368da6,0x0009c04ba3a92f9d,0x00018e366fb4a189,0x000dca28f8a4aa8f}, {0x0008c98efdf41b12,0x000e7f6ce11df724,0x0003850179926b22,0x000c0fa0bae8aa29}, {0x0007fa3acc87191b,0x0008222f18a88f29,0x0000000000000001,0x0000000000000000}}, {{0x0009dda00370c8d5,0x000720c0497d2a02,0x000cdb5a6b3dc411,0x00032f0daa73c7c9}, {0x000505d3784e14b1,0x000d7b77b06edb5d,0x000c1f94b45f2c9d,0x0003193f38ea4c8e}, {0x0001706f6af3bbf0,0x000f0df22ed99a0b,0x0000000000000001,0x0000000000000000}}}, + {{{0x00097825d9e0b2bb,0x00096d1340276af1,0x000d82fe6324bbcc,0x0000475ecad6233b}, {0x0009a0cd8d04ac29,0x000e8e067d738cce,0x0004317aa038ad08,0x0009a7ce55aad83e}, {0x0006a1887d5e91f4,0x000a135efeae9285,0x0000000000000001,0x0000000000000000}}, {{0x000fa0b6a035b085,0x0005853d153ead9b,0x000ca7f6fb4ef7bc,0x000bfbb30b798e2a}, {0x0006653595cf1f8a,0x000774e7d1791820,0x00048df862d39281,0x0002db1e40868b45}, {0x000153b336e38fc5,0x00052ce2e4b80e72,0x0000000000000001,0x0000000000000000}}}, + {{{0x000306c918831eac,0x000de7b8556b1913,0x000c579621fb2237,0x0001fa1088e011f5}, {0x0007511558db4265,0x000c63131310e896,0x00029cec356a91fc,0x0004b85a2f85b7d1}, {0x0006bc4404e3b5cc,0x000ac5c4fcc3a6fc,0x0000000000000001,0x0000000000000000}}, {{0x000498b1e054105b,0x000818b7c971dcbb,0x0006cf66f8ee2eea,0x000fa05b49db517f}, {0x00012073a35daeb3,0x000d5bb674f202b9,0x00032d411842792d,0x00076cdcc487632e}, {0x0006568c96ca8dd3,0x000ecdfe1c986f51,0x0000000000000000,0x0000000000000000}}}, + {{{0x000595043dc23233,0x0008d9e1b752f3f5,0x000f6e2b3641b931,0x00064e0f5c02bb70}, {0x000169d8f287038d,0x00062f3a1b075424,0x00001bf3b8c6755a,0x000a2b642127d597}, {0x000c17f0c20fbe8b,0x0005263410177dfa,0x0000000000000000,0x0000000000000000}}, {{0x00008cc560c65efb,0x000ef6706807502b,0x0007a1e8980e532c,0x0007963729a4a8b8}, {0x0007ccb3a4f193b6,0x0002e07ae80043db,0x0005be0346fea839,0x0009ef33f7a00da3}, {0x0001ea778cb41f4e,0x00096ebb760e7727,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=12 [{1,2,3,..,}]*([2^48]*G) */ + {{{0x0009ba658c1f9460,0x000b18b48e1df3f7,0x0005fc03a103eb15,0x0001ad263bed592a}, {0x0000a127b78a3359,0x0000337c7b07e9d8,0x000d2a0349dd74fc,0x0003b1a807c5364e}, {0x000d92cca588d420,0x000d9e772a1716ec,0x0000000000000001,0x0000000000000000}}, {{0x000fc1df3f66f295,0x00015742d25980f6,0x00036f0fdb08922f,0x0001fe47a583206a}, {0x00001c73f88168cc,0x0001b777671d2798,0x00068317ac8979ce,0x0002a98b48363dba}, {0x000f36b7460d4015,0x000da1c3d46c62c7,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001fb046e7fab2a,0x0000e190213473d6,0x000cbb6e9b84f9db,0x0008fb8a36fcff78}, {0x000c47cd5e9d16aa,0x000c2601e9337a00,0x000713efe8445d72,0x00030681fd15bbab}, {0x00051cff90b2dd23,0x00024900ab444b21,0x0000000000000000,0x0000000000000000}}, {{0x000de9a880ca8289,0x000e3bcb8ede5206,0x000e1369e32209ab,0x00036516b711e224}, {0x00025533569db531,0x000419656e59d965,0x000ee21f2d680255,0x0001d59bb004326e}, {0x000bb722c073cca7,0x000866aa784f931c,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d262bb3ca8da3,0x00045288c7563397,0x000d10c59451797d,0x0004e594575ac7f4}, {0x000311006db0bd6b,0x0004d6485bec56e6,0x00089e23442953a9,0x000610efbe7ae598}, {0x000f1a0f166d5639,0x0004e5f91e0ed7d5,0x0000000000000001,0x0000000000000000}}, {{0x000aca95d51d383f,0x0000d23ae1d67e17,0x0001b867b62738a3,0x000907e6a529f72f}, {0x00059335e44e6986,0x0001d5fbd59c1e58,0x00018393e6789776,0x000e5bc878acd1b0}, {0x00059b26328cd9f3,0x000f3d83306eef44,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009313593b1d240,0x0003b3672b4b0a51,0x00078ea42e614acc,0x000784cd22fe0a9a}, {0x000a6c20faf43e72,0x000e49f3038f9c3e,0x000fb914c50987c5,0x00000c76e9b912d1}, {0x000dc2b7b96a89b9,0x0008de238b29a074,0x0000000000000000,0x0000000000000000}}, {{0x00068ea377031f72,0x000e9606adb168ca,0x000e58dde885ecba,0x000177424d422e92}, {0x0008aa609937ceba,0x000f30fc81145199,0x000c9f99eba807b8,0x000e200db6e7a724}, {0x000db2dc7651c126,0x00009cb58e38f0c9,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002dda36b654cc9,0x0008acdfcec83248,0x000164e7c3c6f06e,0x000ff27341f98b3f}, {0x000b145595e7208c,0x000f8fbf6e4d7416,0x000a519d6e691f26,0x00082c10e5fd7be7}, {0x000b1af42c760524,0x000f36238c97dbcb,0x0000000000000000,0x0000000000000000}}, {{0x000a3b8e5e8a7251,0x0006fabc0a713664,0x0004fe41fe20cb31,0x0004067dc2b00d32}, {0x0004fa30d7f12a4e,0x0003f79c759905ca,0x000ef9b323da1724,0x000357ea84efa0af}, {0x00083350488b839e,0x000408f03e5cf22c,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e616991835801,0x00028f75d4e1a857,0x00031b04bb8869ad,0x000fb7737091410d}, {0x000cdd4fad2e164a,0x0004c7cf900934ac,0x0009b433f8948c75,0x00028687541974f6}, {0x0008f0af013f8d2a,0x0000b59eac62d398,0x0000000000000000,0x0000000000000000}}, {{0x0000c23b25d034e1,0x0007d927e7c611fb,0x0007596a05e54d05,0x000f8995596eb4b3}, {0x0005b26be4690555,0x000ae1277dbebe99,0x0006bc99c064aa3f,0x0001128fda3fad13}, {0x000cd244392bf3eb,0x000a481bf8fac406,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d8f6c1e9aa431,0x000e3d32dbe1679d,0x0006391e1828c205,0x00026f450a2821e3}, {0x000a00cf3fc9e32a,0x000a2fc5a7a744f6,0x0006b70facb792c6,0x000e8edf92ab0b29}, {0x000d53faf8f11ba4,0x000b1e87f01ff5b4,0x0000000000000000,0x0000000000000000}}, {{0x000e6fdf30e29338,0x00014840cefab311,0x000c4e092d034ea0,0x000be36bee8c5b8d}, {0x0001f39e2788cf85,0x0008f32c467a702e,0x0005e353cc3b7917,0x000f137377576e06}, {0x0000db55d1c5fcce,0x000d16e9cd523a0e,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e8870b81dfb8c,0x0006908ea654a671,0x000c3eb3660a23dd,0x000daf70673dbdf6}, {0x000c19bbf5d38a5d,0x000fe1371d1e7af5,0x000e30bcc1eff610,0x000f1308bdd31572}, {0x0000db70b20ce33c,0x000e036ab6b3edc6,0x0000000000000000,0x0000000000000000}}, {{0x000357b86d4f22a6,0x000b893ce6e16bae,0x000a3849b8d94e06,0x000e1675b6058ad8}, {0x000ed6add0f99ace,0x0003cd380c39df12,0x000e2335c645ff14,0x000994a0f6180481}, {0x0005a52a4c84b4bf,0x000e9849a710f480,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=13 [{1,2,3,..,}]*([2^52]*G) */ + {{{0x0002ea2996fba378,0x000cf933ae1a32c4,0x000b43b79b9d0dda,0x0002636c30561bd9}, {0x000f9122413700ad,0x0005a779a0d830de,0x000580fda5f65618,0x00067e785d8628b8}, {0x000ce8b188bafa8c,0x0006d2c75df63d48,0x0000000000000001,0x0000000000000000}}, {{0x00090afd2d7e01b7,0x000e57c72b304c5a,0x00040d7dec21b4b2,0x00094cfde0f45d07}, {0x00010aabbfa713eb,0x0007fa8b4fae1b3f,0x00047d2b080d24d3,0x0001142abdb36f64}, {0x000470df72045350,0x00047e76e433f8fd,0x0000000000000001,0x0000000000000000}}}, + {{{0x000081cbd682dd91,0x000d2c1433b543ad,0x00094641d2488d8c,0x00036e702da0394f}, {0x0008248288ca4d8e,0x000112c8a6461fe7,0x0004a486f063613a,0x000f77efb66bb862}, {0x0006e8d41511d90f,0x0009a1ce80969401,0x0000000000000000,0x0000000000000000}}, {{0x000feced91fc3935,0x0002e83ecdac7136,0x000ee8e2857921f4,0x000ef9bbe82b293d}, {0x000bd182b25ab2c3,0x00097ad819ac32f4,0x000916b74b598de2,0x0004d5e666a5dd15}, {0x0007be0b151456a2,0x000b794dc25c5c44,0x0000000000000000,0x0000000000000000}}}, + {{{0x00087c377c23c5aa,0x000d33ca314119f6,0x0002512d0943eacf,0x000f9fd69c0e1850}, {0x000b7c3c6ea7ee55,0x0006291556c20685,0x00053374868b07c6,0x0009f9f339d7b589}, {0x000d6855b9238a10,0x000491ac6af37f75,0x0000000000000000,0x0000000000000000}}, {{0x000b5d5b2f49812c,0x000855e7603bff6e,0x0008f73b087f7552,0x0005c0adc19b7320}, {0x000d355df5442e8f,0x000a4b8876b6aeab,0x000a7378dc2b22b3,0x000c26f89265f8bc}, {0x0006645f23dbb040,0x000f38b09ab1bbfb,0x0000000000000001,0x0000000000000000}}}, + {{{0x00011ca0d8fcc245,0x0008ea92267e1494,0x000bbfcc2abb385c,0x00029656bfd56d29}, {0x000075f2180a734b,0x000dc3400006f728,0x000f754023104376,0x00021bae73e6854a}, {0x000a8d2ddbc75324,0x0003d711770a3406,0x0000000000000001,0x0000000000000000}}, {{0x000476594b8d6365,0x000aedeb8cb49714,0x000c86324ad6ba99,0x00016428c49863ca}, {0x0002a2e5cfc3d8a3,0x0009adc3e0cb62d8,0x000eff79e5f3fda7,0x000eb4f990b6cadd}, {0x000b0e410ae15a98,0x00000aedf394c7b9,0x0000000000000001,0x0000000000000000}}}, + {{{0x00021de1984e2e65,0x000603254887ed1d,0x00087e7535512fa1,0x0006f4ddde7dd7d2}, {0x000fd9cd7f2faac0,0x00009274ea570744,0x000b8cb9c92e3b10,0x000294aa3ad7752d}, {0x0001e25f444d43f5,0x000d6a378f2a4af0,0x0000000000000000,0x0000000000000000}}, {{0x00007294901179cf,0x000fc01f2357da9c,0x0003c6543ad3aafc,0x0004db8aa97c6078}, {0x000dd86b1f882854,0x000e842c5d55c6a1,0x000e30c9aff1c67b,0x000d71107c0af546}, {0x00097038444a87de,0x000d8c2bb6354272,0x0000000000000001,0x0000000000000000}}}, + {{{0x00086f90f323a729,0x00082963dacbf625,0x0004056ab9d5b07c,0x0001d30212e37a0e}, {0x00065da9a3d1070f,0x000445a33677e429,0x000c39a6aee3c700,0x0006b968d6cd0279}, {0x00098776415f9a3e,0x0007bd59dc1684b7,0x0000000000000000,0x0000000000000000}}, {{0x0005cafc1fb833a8,0x000b18657b2cb0ad,0x000af58b0bf123c6,0x000acc1e7ceb4334}, {0x000e5575f0e10ca6,0x000d22916c7bc194,0x00097f735880fd80,0x000604a86980d5b3}, {0x0002f218f0f8d8fa,0x0000806dbeec3ed6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b6c1669c31b94,0x000b37bb5eb33b20,0x000f2f86abcd3194,0x000093b3893ef395}, {0x000d0b48537fd7dc,0x0006863b5109af48,0x000cb076c2fca9e7,0x000fc785f088e6f5}, {0x000c88facfd552fb,0x0001054316685a3b,0x0000000000000001,0x0000000000000000}}, {{0x000b6af5d1972479,0x000ccf45d30e213b,0x000db2b3881288b7,0x0008f7bff9008ba2}, {0x000607009e5be8cf,0x000e10b176da0a78,0x000522cf433a33d0,0x000090924737e4d8}, {0x000cc0a11c296771,0x0001fd3715d11b75,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c391c2f2938b1,0x0006b396d1c5f420,0x0006bb17f5eeaef7,0x0006a57b7feb16a1}, {0x00026cc8015523f1,0x000ded6e6d4aadf1,0x000f602e23393c9c,0x000e2c8dbcb36848}, {0x00011e23c49f3a9a,0x000730c0c1ebfaf8,0x0000000000000000,0x0000000000000000}}, {{0x0001b88cdd5da561,0x0002fcb4c22029af,0x0009624d6d5aa7f2,0x000db935bb120735}, {0x00019a8308449416,0x000467f9f185fd32,0x00057d8b4d3e00fc,0x000e187052a8a69d}, {0x0009e66380528c91,0x0007a42a603bc9b7,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=14 [{1,2,3,..,}]*([2^56]*G) */ + {{{0x00026efe1474fe09,0x00029da3ad38a0ca,0x000ec34abeaf5cd5,0x000847ac94808b1e}, {0x0001587ade96127c,0x000a43fa8cfa6df2,0x000bb39bcfdb5ad6,0x0005dd4d0c9f947f}, {0x000772a4ebca687c,0x0009227d79e215e8,0x0000000000000000,0x0000000000000000}}, {{0x000926e1c81cb032,0x000ffdb04fbc5abf,0x00034707ba5b9c12,0x000a347c4ee8c89b}, {0x00072367a152d81a,0x0004511a3a4cd565,0x000b8f1a66429397,0x000260ea13e9d0e3}, {0x000a19a28ee14ab4,0x000d5dea76ba4c81,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f1e1b3fe2f1a3,0x0006da87421ab9af,0x000a3305ebdbbfcc,0x000cb7784b75a8e1}, {0x0006a4410056f8f4,0x000ff65612b5abdc,0x0004b1cd83f32f54,0x000fb989d25121c4}, {0x00014abed80a7bb1,0x0005ba8f200e1152,0x0000000000000001,0x0000000000000000}}, {{0x000fb8525d63a07f,0x0002a4f5f23c02f4,0x000405911d9aa8e0,0x000dae0345abb8b1}, {0x0007b4834d14e7a6,0x000b31fdc5462195,0x0005dca7cbf9b75e,0x0001ee84304e26ee}, {0x0006a2c7d37349cc,0x000fc85a34c3afcc,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cefac8c58a5d9,0x000939b188506808,0x0005985dd6ee8422,0x00094a64ab14cf0e}, {0x0001ac27af983cda,0x00024f6eafd12785,0x00025d8bab20f8ff,0x0004a549d9c6da3b}, {0x000f18f37ed810bd,0x000655f630e4c95b,0x0000000000000000,0x0000000000000000}}, {{0x00018594e51ad76d,0x000d8952697460ae,0x000aec56660f8de9,0x00093a39294777cd}, {0x000bdf7dc98fde3a,0x0000c53dc363fcc0,0x00091985d2c2708c,0x00093692d05055da}, {0x000c4d312ebcde24,0x0000c18d0017f5cd,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a3f86e5f8496f,0x0007f32df7ec8ea1,0x000d8551991f1f8f,0x0000f4eeb16ec397}, {0x000f5ebe5be1abc8,0x000f8233b8a1e6cb,0x00037675c403702a,0x000cbf97ecb04148}, {0x0006555682899a5c,0x0000280720d39958,0x0000000000000000,0x0000000000000000}}, {{0x000312054dc27af9,0x00074dd550df7288,0x000193eb1e2f87e2,0x00073656a715c43f}, {0x0006ecb67dce2977,0x000aacb5db8a585c,0x000d92a6332fcd10,0x000cdeebccba4f16}, {0x00036c8da2b8001a,0x0007817b62765789,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002d6d084e03d59,0x000c244d84ecf179,0x000c93fa7f1e0110,0x000f695cc72b1bb4}, {0x000921730f1b2908,0x000b0b36b38d0bc6,0x00029c0e4bf469cd,0x000c1d41428da1db}, {0x000d1253d7a577f2,0x00006a23b655222c,0x0000000000000000,0x0000000000000000}}, {{0x000ba5fbd7ebe31e,0x0005209808ec8aa4,0x00049718327a5383,0x000bb2492c210a5f}, {0x0002eef53e1dbdc5,0x0009d3c1717e38e0,0x000d4877b41e983c,0x00012d8aedea3a07}, {0x0007e058b6c0e3ba,0x000fd022c8be6da1,0x0000000000000001,0x0000000000000000}}}, + {{{0x000870ab98aeb123,0x000044a353002cf5,0x0006150f34fa12da,0x0006eea20086b83e}, {0x000a0a2cdf13169e,0x00028616b25e80e0,0x000c5982d13e0cc5,0x00019702e01a4a67}, {0x000b60ef183d6e66,0x000a1f6f9172f815,0x0000000000000001,0x0000000000000000}}, {{0x0002b57766386476,0x0001a0e6acc5477b,0x000ba422b2405581,0x00090991a9873020}, {0x00045310acf2c8c9,0x0008701ea796459d,0x0008c83917c30ec7,0x0009db51be44d168}, {0x000514c3bb42ce9e,0x00048d0b03fd870b,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007edbd640c9bb6,0x0001c6f483d72a01,0x00058a225c5b0849,0x000e8697568a7e71}, {0x00022821bf73d7fd,0x000c765e3aef4bc0,0x0001d2e8d1daf2fe,0x000772d486e7b59a}, {0x000595f951edfc03,0x000ffff1683f882a,0x0000000000000000,0x0000000000000000}}, {{0x000fc53814c4cc13,0x00014196f30cc555,0x00076a3af64c6ce2,0x0009bfff339f5668}, {0x000ffe438adb5544,0x000aa59ae8f3c48d,0x0006c57ce59b5441,0x000eb7bdc7b7c0fd}, {0x0003b8e1d8e51d10,0x000d6a6427d57897,0x0000000000000001,0x0000000000000000}}}, + {{{0x00005519264c8b35,0x00066ff272a08c1d,0x000142d545c343f7,0x000ef117b8bd86e9}, {0x0001c60c69c66860,0x000b54e53cb6de93,0x0000c9b9924f2f51,0x00030b949095878c}, {0x00016f5f1fba7e2a,0x0005817da79c3a69,0x0000000000000000,0x0000000000000000}}, {{0x0006ad6babd55997,0x000be6d551de11e0,0x0006c45d4c33b3cb,0x0009e3dfcc4aa553}, {0x000821bb5c238e3c,0x000dfc012d05a1e3,0x000650684d8d4638,0x000805b7e2413b85}, {0x000718949cdcfd8e,0x0002efc1a85e6627,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=15 [{1,2,3,..,}]*([2^60]*G) */ + {{{0x000f6a9bd09d8e58,0x00004bdca0a6cc0a,0x000d9e6d336fe5f9,0x000c9d8bd87d0339}, {0x0003f4d463bab3b8,0x000203e46dfb629c,0x0000ef34ea62ed4c,0x000564035458998a}, {0x00069592c6278328,0x00081b3c56ebb377,0x0000000000000001,0x0000000000000000}}, {{0x0009a17aab96cc87,0x000f8ed51ce44125,0x000c62b1c658666d,0x000b6999437c7966}, {0x0008f0fecb36474d,0x000f725b1f7c6099,0x000396c71fdafc21,0x0006a547fb5a5b56}, {0x000566ae79d88868,0x0000f4130033ff0f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a6c73f41a4fd1,0x000bf46616431912,0x0009c6ffbd2fe4c8,0x0009e4fd42f313ec}, {0x000b9f8b100ba286,0x000e18229bbae712,0x000550161a1f1da0,0x0000032c80f2ffe5}, {0x000f0b1d53bfaa0e,0x00035fb83c760748,0x0000000000000000,0x0000000000000000}}, {{0x000ed33353cf7a1f,0x00075b8b3c031fa0,0x00053c30e33c1415,0x000945a8fa62217c}, {0x000aa8b667de4f9f,0x000c4952fb889399,0x000b6e3b711abc77,0x000959e7e12fabed}, {0x00057ebfe5a1b2cb,0x0005344206e24318,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005f9c5a301de7d,0x000b800d937115a9,0x0004b1412c82ee0e,0x00039cf3df5a5904}, {0x00016cd50327ee6f,0x000841dfd19a796b,0x0005d79c493ac5c0,0x00097275eb2319d1}, {0x0003b6feb4b9d447,0x000542e1eb10df1a,0x0000000000000000,0x0000000000000000}}, {{0x00051bac56d17f38,0x0007837a907c7875,0x00082e7d67e232dc,0x000c3c225acaf222}, {0x00056e17100c95eb,0x000198b234622502,0x0006b8a4beb3ba23,0x0005492d30351698}, {0x000c0dd28973e413,0x00031b2e1155d6fc,0x0000000000000001,0x0000000000000000}}}, + {{{0x00014d7bc4df6981,0x000c45e951da151f,0x0003964143f3d397,0x00056c9c24be6549}, {0x0000ae1293e252e5,0x000bfda40e3aed33,0x000e72cdf82159a4,0x000f514f7b173b13}, {0x0000684bfa5b859f,0x000fce90812f67e2,0x0000000000000001,0x0000000000000000}}, {{0x000a9abf7e9a0c25,0x000a823b0b3a0fbc,0x00011d2709072194,0x000b7a7f17f5564f}, {0x0007987f0af999bb,0x0009d6201796c014,0x000d35c45cce25a6,0x0009265843370c43}, {0x000a55401cbff6e8,0x0000eab503e2ea19,0x0000000000000001,0x0000000000000000}}}, + {{{0x000caabc4b5cd512,0x00034cdeccde50ae,0x000395d24049ffdf,0x0005918925068e1b}, {0x0003f93fb9ea4405,0x000a60ba95d141ad,0x0005981c42f76f02,0x0005946bf800414a}, {0x000435023138c47b,0x000f3cf314147e38,0x0000000000000001,0x0000000000000000}}, {{0x0008bdcc69ae19e3,0x000ac73cebd917e3,0x000c35337880966b,0x000e6ede2718c3e8}, {0x000fd10236ae833e,0x0004797bb14f5b88,0x0001296485e76bd4,0x000a68194c12b2b3}, {0x000b75dc1e45112b,0x000dd88574000b0c,0x0000000000000001,0x0000000000000000}}}, + {{{0x00037d315eea24bc,0x000160f77a65b38f,0x000de27962237731,0x000bd3346f06ae65}, {0x0007a25b38b1587e,0x00055c6b9f2a1d2c,0x0002f34b1687394a,0x00054f27c66a0ccf}, {0x000866c84ecf3de7,0x000b4da4a0f4aaa9,0x0000000000000001,0x0000000000000000}}, {{0x00066dd8b8dffeb8,0x000121bfeaeff003,0x000a80b5c3bfe941,0x0005b6a4c3fed2fa}, {0x000c623dfdf4718a,0x000b0791d22ef007,0x000949ccec61c6bd,0x0006e328d9cc6d79}, {0x00014a1530d03e69,0x000d45fdb36710aa,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006dcfa61a8d3cd,0x000ff977e2649373,0x000089ee4ac6af49,0x000b86d61720bd71}, {0x0007848d2c5df2f3,0x00078e07afbcc66a,0x0007ceb1f230a9ed,0x0000d2f61bf5077a}, {0x000770c3ffbf99e7,0x0001487ae5f08492,0x0000000000000000,0x0000000000000000}}, {{0x000ee44c464c2996,0x000d8f990f4f03a6,0x000453774274aacb,0x0005c8730ef447b6}, {0x000e5e02e661f55b,0x0009f13f1011e65a,0x000f4c8fe17d3ed9,0x0000dbeb35dd393c}, {0x000a7d1cd2327711,0x0003fb444802cd65,0x0000000000000000,0x0000000000000000}}}, + {{{0x00071a842f621fd7,0x0008594c057a1dea,0x000e1689c80fc8fb,0x00022f52adc9a8e1}, {0x00099c47b816309c,0x0000c495f00a960c,0x0002e200a0f356d9,0x000a87494b798824}, {0x000dcd587b7f9ca6,0x0009c4d76d2c396f,0x0000000000000000,0x0000000000000000}}, {{0x00035970dd6ecf15,0x000449aee47a261e,0x000adfd394c8df13,0x000dfbec67553f2c}, {0x000aca43c615471c,0x000606556ef09db2,0x000a225f2e040114,0x00099dfb28da12ec}, {0x000812bc587a4c83,0x0001ab8cba898428,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=16 [{1,2,3,..,}]*([2^64]*G) */ + {{{0x0006146954276a1b,0x0000c171344edf1e,0x000b30130812b4a5,0x000314a14896c770}, {0x000e796a686592cf,0x00079226d890053f,0x000869a5847ac79d,0x000cf60993a83ada}, {0x000e4b5fe7d156a5,0x000add7850cdf667,0x0000000000000001,0x0000000000000000}}, {{0x0005bcbb35fb3dea,0x0000a34e2d6021f3,0x00090be93989877f,0x000303404d6435bb}, {0x00007e5919257861,0x000c99d1992710c0,0x0001c7987d3586cc,0x0008e8681c58c145}, {0x00059a487fa896da,0x0009a8b1a9e54366,0x0000000000000000,0x0000000000000000}}}, + {{{0x00029533273f3ddc,0x0009580b259ba7fa,0x000a4092fea94f8c,0x000efd38be9d56f6}, {0x000720f2ba425622,0x0007c0adb2a4d25a,0x00018752498a9ea5,0x000d893bbb4d11f1}, {0x00056b02f195ec41,0x000bca2ad72c4b2f,0x0000000000000000,0x0000000000000000}}, {{0x000a4013f1ab7060,0x000f17521f983a0f,0x0005292b2f1ebae7,0x00075002debce289}, {0x00003b6cd203ad6d,0x000c3592c993bfe5,0x0005400a40b351b3,0x000e9b6bafed180f}, {0x000d6a9f0291283a,0x000563036cf95dd4,0x0000000000000001,0x0000000000000000}}}, + {{{0x000efa3e474a5b75,0x000e5a6d55141813,0x00008a31bd3435d9,0x0006a68b3c599425}, {0x000252817b3af9bc,0x0006a695a37f35e7,0x000f06836ac1d6b0,0x000b19a92f525bb2}, {0x000215d9b8e544be,0x00080723f1554fe6,0x0000000000000000,0x0000000000000000}}, {{0x000e709e6109d280,0x000e367fd7bcb2f8,0x000be531b1c6fe21,0x0002d1fc5388b64a}, {0x000c169c0609b0df,0x000cd0fc3d5f664a,0x0003de00815f78ff,0x00049af9ff38956a}, {0x000e62c250aedb30,0x000af977c662b6e7,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cfa5a95db7680,0x000cc333878665a8,0x000809b2a4ba5401,0x0009594f6cdc3f0e}, {0x000e99bbfac6790d,0x000d836074d551d6,0x0009d9ae874e847f,0x000a264b3b0b13f8}, {0x0003ac51f7a6ec5f,0x00021d6dd250c60a,0x0000000000000000,0x0000000000000000}}, {{0x000e14abaa7747bd,0x000f127c3196cad1,0x00078a629241495e,0x000ded5d0cbcf8af}, {0x0005b83d56ec31f4,0x000c6ef029fa54b1,0x000cc516f0a12c6c,0x0000ce830e11ae62}, {0x000747fe9964fd2d,0x000c6756076a3288,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b9a69b333564c,0x000cec5ad994fbe9,0x00091ab4f5d4d95d,0x0004dbde503f2b0d}, {0x0003c8b32fed7498,0x0009fa10339bf799,0x000b1e6b4c7bd908,0x0001c54e64a99794}, {0x000598ef7979d915,0x000f29a322ae1bc8,0x0000000000000000,0x0000000000000000}}, {{0x00042520c237fcf4,0x000303a14c0e24d4,0x000f7ed62c67df4c,0x000ee5dfd3635dff}, {0x00097bcf94654c63,0x000eb529e2ea1f28,0x000969c7cff702bb,0x0003bf0591306903}, {0x000474be25c3afe3,0x000d8f2570e7350c,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003d3d928f89c37,0x0004d9c668cfa4b7,0x00097ee2907da69c,0x000fb743bf4c3402}, {0x000cd4034c59cbf5,0x0009bc4b73d60ae9,0x0007664da82be729,0x0007e3800a84da1f}, {0x000700f12fb007b6,0x000882b546161eb7,0x0000000000000000,0x0000000000000000}}, {{0x000e150bbd0f66b9,0x000122fc5d0def4b,0x0001ba0f43d660c9,0x0004e9263a5b4550}, {0x000ef33c24e5b722,0x000249e1b7ba92b4,0x000aa152b1856c8d,0x00095fe68108b2c9}, {0x000e766ae6e54017,0x000903a379f58c2f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000980153e2aed11,0x000ca0053853a90a,0x00003bf5f23c9661,0x0009061283e91bda}, {0x0006236d967ae1de,0x0004f3d80708ed52,0x000bb014e9c6763d,0x0002f3d82f09bad2}, {0x000f8d828de34c80,0x000187805c46ac1b,0x0000000000000001,0x0000000000000000}}, {{0x00086a0c8fd9feb0,0x000d468bed15d861,0x00036573dedab729,0x000d88e4dce7ee93}, {0x000d9e86caa8e75e,0x000c0d08d6110fe2,0x00082b709f0b0d08,0x000ab3fbb5af39b1}, {0x000c1b7910befecc,0x00062bf43fafb941,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005341f232f3278,0x000c66dff5ad0b4d,0x0006270a82ebb141,0x0002897d7912e413}, {0x0006b6b16ad87fc6,0x000fe7c18f348f2e,0x000a03bae57af6d0,0x000a6d2d6ab02f22}, {0x00017c3e7efa7a28,0x0009c673423958d7,0x0000000000000001,0x0000000000000000}}, {{0x0004f0f2ce49ed5e,0x00055b8c6c92190b,0x000aff1be7fa884b,0x0002c375de74b331}, {0x000f37a676c7d888,0x0001190b6b57c355,0x0009c95180dbbfa7,0x0001d7dc77b1599b}, {0x0007eba118f76648,0x0004aa840229ee22,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=17 [{1,2,3,..,}]*([2^68]*G) */ + {{{0x000507b4b3de6fe0,0x0009064574b533f1,0x00076eaa707b56c3,0x0005e98aa9532376}, {0x00034611c9b6716e,0x000eb6a26112d9a9,0x0006e068430b4789,0x000e50fd96103fab}, {0x000509b62d215cdd,0x0000b7c4da786d1d,0x0000000000000001,0x0000000000000000}}, {{0x0002a0af86e4be0a,0x0008383ebf635e75,0x0009175f3f7680f5,0x000b999d9f1a0d87}, {0x0001f04cce1e2861,0x00086e6afd75ef23,0x0004476af7240e6e,0x0005e887f56c0473}, {0x00094ba352837e09,0x000f469e3dc524c1,0x0000000000000000,0x0000000000000000}}}, + {{{0x000726e7d4a98265,0x000a397d1e874b3c,0x0008c78c755a513d,0x000fef1392677915}, {0x000e1e9e24f3ae62,0x00096cf6213d1cf9,0x00004b1f503d4fcd,0x0000f07e39bb0e12}, {0x000406c607195818,0x00046d3b7b9a617a,0x0000000000000000,0x0000000000000000}}, {{0x000b43a8c35ac9c8,0x000a92f37f3857cd,0x0008ae49b6bed377,0x0000e3380827d789}, {0x000e2deff6865bd5,0x000758e466fdb287,0x0001f3ba0c560a0e,0x000db418a2645432}, {0x000aa26f5d44767f,0x000d36cc7b7f8bfa,0x0000000000000000,0x0000000000000000}}}, + {{{0x000020f87c5aeb2e,0x00035693c551e0d7,0x0004a7f0938f3f98,0x0008d4d829ae419e}, {0x000d8e42f19ee358,0x0004d94560e54e60,0x000ddb20bc96b546,0x00014bfcf64c2c92}, {0x000518fec9517e43,0x000a92773a95b0b8,0x0000000000000001,0x0000000000000000}}, {{0x000c159b5e61b250,0x00070c6538519060,0x000d0372c4dd1c2d,0x000fd8998866b5fd}, {0x000ceccabb79115b,0x0000eee1fb689260,0x000b839fc8378f05,0x000677dee33a7134}, {0x000b9326b080c62a,0x0003ae07e602129a,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000dde02f16a4fb,0x0001ca814d149b58,0x0003cc8c599eaa3b,0x000d833d43a45440}, {0x000afdba29de3c98,0x000b2ff2056e31f2,0x000ab3bf81e95cba,0x000649419f19b530}, {0x000585b648a6e1bb,0x000ff11dfbba1ed0,0x0000000000000001,0x0000000000000000}}, {{0x0004734696bc60cf,0x000199c0250d4a2b,0x000d4759758b9f4e,0x000f68bc326d4e2a}, {0x000cea78113abc32,0x000d248f92840b01,0x000d61ebd87644ac,0x000ae9a32d38a8d8}, {0x0000c706b58a69c2,0x000561f4b942e16a,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002fe7e20769488,0x000a1c068b87a199,0x00032a3459c496fa,0x000e96c391b8839f}, {0x0007f4914cec7211,0x00039756176c58a1,0x000aa63441905f9c,0x0008ea16377fb867}, {0x00042578ce2a2865,0x000cd140c73dd697,0x0000000000000001,0x0000000000000000}}, {{0x00074ef7ab059a14,0x00031e0f7d0f636a,0x000fea67e10b4430,0x0006ef5711a15a06}, {0x000f717856862153,0x0002513381cfd3a9,0x000a8b9906086974,0x000a08521bae079c}, {0x00052ef6a1d4b90c,0x0004f5ad24ad39a3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c2d28a3a30e7c,0x000933949c694069,0x000d1f2a5ed527fa,0x000e2b5573d97d5c}, {0x0006aa892b500798,0x0008ac4418f1419e,0x0007bf2d1e227f12,0x000bc2143f4c8a62}, {0x000ae6ef99da3403,0x000679827f46143c,0x0000000000000001,0x0000000000000000}}, {{0x000a8cba49268935,0x00038ccee58ce9de,0x00061df0ac493218,0x00075eb49225f314}, {0x000073000d3eb206,0x000145d79e65edfa,0x00007b1990aba7cc,0x000c916353a37685}, {0x000854a40d94fba3,0x000cb2e109e1b50c,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000c263771f69c1,0x000d1595543d358f,0x000ef2e3d8a56184,0x0005866bc8c3965a}, {0x00021c100a7748c1,0x00029b46541a4ddf,0x000c5cb49ea744d6,0x0007a3a96b8b1fb0}, {0x0005aa7e85061bd2,0x000163e83c339e28,0x0000000000000000,0x0000000000000000}}, {{0x000102ac6923a672,0x0004153c3e1bd59a,0x0003473bcdaf9384,0x000f589da2a6c958}, {0x0003af0eb1a0311a,0x00041f50baac8d3b,0x000bd2c8728d9afa,0x000fc24b4e16e953}, {0x0003e6d4570ad37f,0x000aac57efaaa8de,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008c7fccb0a85bf,0x0003bdff198eec53,0x00029ee8af84ec04,0x000572ea125b846f}, {0x00025280cfc9ed01,0x000f73f2654ba803,0x000ffbf57e3b7be3,0x0004f83701a26bca}, {0x000d20a251a2d372,0x0003ec410f80b319,0x0000000000000001,0x0000000000000000}}, {{0x000961197dc0e519,0x0003d8c136f93b3b,0x000000ba8d6c2646,0x00084f848d99824e}, {0x0003fcfbb42b20e0,0x00038715f781fef3,0x000bdd048ed10781,0x000042869724ca7d}, {0x000de2c203c66b90,0x00090489fab2c4cf,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=18 [{1,2,3,..,}]*([2^72]*G) */ + {{{0x00038bb0c7aa46ca,0x000d2cad2e37a158,0x00054d33ad65a28c,0x00004b20d4f1caa9}, {0x000b180e4c9d244b,0x00070a13f58c65ce,0x0008816ecff016c3,0x00016ad260aeee75}, {0x000dbb7b595c36fe,0x0002944d06dfe8bb,0x0000000000000000,0x0000000000000000}}, {{0x000c325d67839921,0x0006a5955c2a22f5,0x0001664092579a37,0x0003aac4f8e9390b}, {0x000722a8dbf2236b,0x0007b02d94034f2b,0x000fcd8d5de86b97,0x000fa8bc9f80729c}, {0x000bcbc03be296bc,0x000364ec1469f11d,0x0000000000000001,0x0000000000000000}}}, + {{{0x00048e2fcaa83f58,0x000495fafcc6105f,0x000d34073fc2c5d9,0x00042510321d1a08}, {0x000d83427742e304,0x000ec5f97b8068ff,0x000530da7faa8a52,0x00005d010e52ac14}, {0x000df5701f277a14,0x0000eacdd532283e,0x0000000000000000,0x0000000000000000}}, {{0x000f566cbb172daf,0x00050c51771845f8,0x00066aafeeea7b0e,0x0005258081cf4ee6}, {0x000c71bc2c6ec8fd,0x000790d250232a19,0x00011bed4c06ab26,0x0000acd06e0bdc44}, {0x000734273e0fd2a2,0x0005c1c9fb738a19,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b6ef22ab96e69,0x00026b8cd18dc5dc,0x000563a07bc4111e,0x000f73913482455e}, {0x000edcb5ec4ad0e2,0x0000caacaf21483b,0x0000f16a5a48441c,0x0005bffbf280c9e8}, {0x000f37a7690242b8,0x0002eed954418691,0x0000000000000000,0x0000000000000000}}, {{0x00066d6e31428479,0x000f47fc4b8794a7,0x000a81360ec38293,0x0004d77d31e9f867}, {0x00042db92af31be3,0x000d799976882df8,0x00005ddd34a906cc,0x000b961ddfb3abb5}, {0x000bbb326a3a37b0,0x0005d4f7af85a74f,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006d183b4b1bfc3,0x000143cdd1f50d0b,0x000721cf9d088770,0x000338fad247118a}, {0x0004efa498ee55a8,0x0008d9808733ff45,0x000faa72107a954a,0x000a392986064eae}, {0x0000c503bc385af5,0x00095cfc7e0cec3e,0x0000000000000001,0x0000000000000000}}, {{0x000f6c1133ea5097,0x000685bf161ebfa2,0x000bb087e9c48b5f,0x000987c958eb481e}, {0x0001ea465a54c3b7,0x00081943446e92e0,0x000a8941e66d88ba,0x000d40dc6c71b0c7}, {0x0007f59a3690cafa,0x000130f02679ac05,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c5b4b93b19e8d,0x0001b316df16919e,0x000549bdce1a1a0a,0x0001cc00d06d528f}, {0x000cf17722a1d1b7,0x0009c7821f1ae098,0x00007c6fc2825a3d,0x000f796a6b06d5bd}, {0x0004ca4366a06040,0x00072103b88040d4,0x0000000000000001,0x0000000000000000}}, {{0x00038b6ea0266cec,0x0003d4ff03eab713,0x0008f81bfb033aae,0x0004b58cdd700e03}, {0x0002486b62595d6a,0x00027288e5a75ffb,0x000043649c2c3428,0x00056516d9dc3a87}, {0x000145473b4564bc,0x000f9a0961272b27,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006ad885aea13aa,0x00022fbb0e237052,0x000115fb0a1aa034,0x000ccb8ce398278d}, {0x0004178f8f78a3bc,0x000403be5854a510,0x0006bcde0e2e720a,0x000edf5f632b7fc4}, {0x00038eed71d606d0,0x000d21f92dbc6d75,0x0000000000000000,0x0000000000000000}}, {{0x000631ff7cd8f78c,0x000698475f524849,0x0005eafa796bd6f5,0x000fa7a4ee42bd53}, {0x000b8f8540687776,0x000540f9fdea3095,0x000f5bf17004e5b9,0x000834c440599d47}, {0x00063874f7c8a4ef,0x0006bec9a4f28185,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c12a0297bd390,0x00020c5821857743,0x000e07f2b528d6e4,0x000318df51deafc4}, {0x0009c03086d94e26,0x0004d01fde5e064b,0x00071c1d5855c1d9,0x000cdd2d762cca56}, {0x00022e583500cf8e,0x0003f52279b68b61,0x0000000000000001,0x0000000000000000}}, {{0x000b572837258eb6,0x000b88af33e25ea0,0x000ba976e7082c63,0x0000d0abef5e06ce}, {0x0005c8fda6ac69af,0x000f82b26435f42d,0x0005ef9369e629b7,0x00029491bb2be768}, {0x000ae13ca4da59b7,0x0000f00ce8846bfb,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000079959682d5c,0x00076719e3233b3a,0x000c78c2194cd545,0x000e51d3c744ff86}, {0x00053afacd6dd789,0x00098cb1ba7a5cd2,0x0004fb918b560853,0x0009ff1bce38273c}, {0x000a7efa90ba240c,0x000ba73bb2e372bc,0x0000000000000000,0x0000000000000000}}, {{0x0003a114b353d398,0x000d2df4adbd1d56,0x000e9ad940e90284,0x000fca7fe3af63ef}, {0x000de96feaa4e61f,0x000bf94ff4ba0669,0x0005279d7b8471ad,0x00071dda976e696c}, {0x00066b8800a22911,0x000f5fba44b58815,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=19 [{1,2,3,..,}]*([2^76]*G) */ + {{{0x000b896b5317311c,0x000ccb025efc3b29,0x000bcd9f85c60e34,0x0005f821ae29c1d9}, {0x000293dcc63561e8,0x000f95824c27219e,0x000843c9e01039f3,0x00048ef0f79fd3a9}, {0x000ddb5a3bba44b8,0x000011f0a7f5379c,0x0000000000000001,0x0000000000000000}}, {{0x0000be31597dedd3,0x000aaa0d73669dd4,0x00090c605d60706d,0x0007d62f262a826a}, {0x0005e90997b0e2e6,0x0004dc73225ac29c,0x0008be39728fe4ca,0x00038656b7a746c2}, {0x0008bd5a3cf46a3d,0x00080a0c58ac7031,0x0000000000000001,0x0000000000000000}}}, + {{{0x00070e2b4e96cd1b,0x00023ea39d68ac53,0x000f98a99040b26e,0x000362a9be557ba1}, {0x0003c202765cccef,0x000726d7b5a7731e,0x000faf8cd815e2ba,0x000ba6579cd91c25}, {0x000ec8fb3dafb2e8,0x000af4648049fac5,0x0000000000000000,0x0000000000000000}}, {{0x0004b6251452046e,0x000cb296110b89a0,0x000551f88c9d1ddc,0x000bbb0b0f26d015}, {0x000c2b5bd39d39b8,0x000dc18ef79d52ff,0x000b527ab6d006e2,0x000a804f61d0142f}, {0x000be5992391511f,0x000815a3e717ea9d,0x0000000000000001,0x0000000000000000}}}, + {{{0x00029eaddc553333,0x000212246b16c20f,0x0009da31a639b833,0x0005a63d297cf150}, {0x0003190a2a3a8499,0x0002ca8af6260545,0x00018490cdf918d2,0x0005a5ed4b646253}, {0x0004fec387ca9de6,0x00010b72b35acffa,0x0000000000000000,0x0000000000000000}}, {{0x0006d539b23d78ec,0x000a4b221e3646f9,0x000b6bf83af256f3,0x000d62f0c408a90f}, {0x000fdaefff14a7ab,0x000e41ce0c4069cd,0x0001cba29824953a,0x0007a382ab7eb47d}, {0x0007f64599eb440b,0x00074a4c148b6095,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005a160c85caa71,0x000f0e79edff6be6,0x0007704970c1ae3a,0x000a395f8b957c42}, {0x000c85f0f181eb8a,0x0007d8f529bdf3d6,0x000d3534e626c58e,0x000c770dabfad83f}, {0x0003e65d7e5ada98,0x0005676430730bac,0x0000000000000000,0x0000000000000000}}, {{0x000d0476d73fcec9,0x000d714dcf97c309,0x000a56a3252ab9b5,0x00097fc79648c08c}, {0x0006b897ba609ff2,0x000c446a06ff8430,0x0002d01ddb643744,0x000f97ee1218bc20}, {0x00048db33f9b0f80,0x0005e8b5f54bb8f0,0x0000000000000001,0x0000000000000000}}}, + {{{0x000851bfcfbb80d1,0x00082b51c40077e9,0x00087cd565dbfe09,0x000954bdd372a1cb}, {0x000f6bbff7b4dccd,0x000237c51d294b36,0x00003d64ce0f8798,0x0000569d6e3c2614}, {0x000a6224fb79e0e6,0x0004d7c33dd3b5eb,0x0000000000000001,0x0000000000000000}}, {{0x000f054ad5a9cfa1,0x000bee5f93daceaa,0x0008aa260aa160bb,0x0005025da9f4b722}, {0x00004817d1e67b1b,0x000e00279781308a,0x000c2084afd2f00f,0x000c154f68e6680c}, {0x000c6b0f1d4b7ecc,0x000fe2b89761184c,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007fbeff2b9ea68,0x00035c954c6cefab,0x000062277d67291b,0x000820637553137c}, {0x000e8b75730d8af4,0x00068d2250710c68,0x0007a2fbae3e7c1b,0x000f6b643e1aff63}, {0x000dc46991ef002b,0x00096e38ab4582dc,0x0000000000000000,0x0000000000000000}}, {{0x000bea0d80f3758d,0x0001d6899ee62692,0x000cdd2a79a4d763,0x0002f50f2ee3aea9}, {0x000fb1476eea0816,0x0007c81475c4d433,0x0009d9fe82142372,0x000756c76934dc96}, {0x00033eb086d918c8,0x000e3056d2a89175,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ef0de9496fb55,0x00076806fa762c50,0x000770bcaf6f226f,0x000a0d3e47cff6b0}, {0x0004eb780ef8cec1,0x00034df87449872a,0x000896382a505c84,0x00046b56a94dfc29}, {0x00021c7a5c037f2d,0x000659ef98ff9417,0x0000000000000000,0x0000000000000000}}, {{0x000001c935289072,0x000f4a229e4010ce,0x000b1be023ab7710,0x00073fb44f780b68}, {0x0002944ddc611373,0x000ba09ab8b61290,0x000be003d4bb157e,0x000f7557730f52d1}, {0x000506c275d184bf,0x000c57abea8b4979,0x0000000000000001,0x0000000000000000}}}, + {{{0x000004498fadaa48,0x0009d0bea3c3894e,0x000a8f46458aa39f,0x0000008b0b3654a0}, {0x000ca4cd7392bf83,0x00012eb97aa46a22,0x000b9cb80e1d7afb,0x000cf74c8adcd888}, {0x000b51d04bb6e179,0x000b50968eb22473,0x0000000000000000,0x0000000000000000}}, {{0x000f96d03d831756,0x0007499de9e10051,0x000ecddcd4ffade3,0x0009dbdffc72771e}, {0x0006b5e1bb9647aa,0x000addb508dc2415,0x000ddf40de78eeab,0x000ab1c488946fac}, {0x000c823824a964d6,0x0003b16f258c8749,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=20 [{1,2,3,..,}]*([2^80]*G) */ + {{{0x000cc508d53fa611,0x00057fcd40894532,0x000f3eb54e960b10,0x000ea40877d231ff}, {0x00043e5110313bd6,0x0005209f6eb9ee83,0x000589764924e778,0x000332e258b2e7fa}, {0x000e2e038618a6eb,0x000aaf96067c3511,0x0000000000000001,0x0000000000000000}}, {{0x00022156015c8ff4,0x0003a0ef974e440f,0x0008ea1f931a1b7a,0x000e417472932b48}, {0x00003bb75d745720,0x00096758e51bf9c8,0x000f97c7f0b39099,0x000b39d56a488d83}, {0x000fe1ded1fac932,0x000399aaf43ccf55,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fb78344f73774,0x000a49ad3e73876f,0x0008771e37ad3158,0x00003f2cb98ec469}, {0x000f31bd531106f1,0x000434959ff8325a,0x00064eee47f875ba,0x0001cf224bc0a102}, {0x0007d33a19ccf2f6,0x000f2186ce603133,0x0000000000000001,0x0000000000000000}}, {{0x00006e91f2869773,0x0000239179c5ea67,0x0009aa4ed3879ba3,0x0003eb977e239f26}, {0x00090ef091443aa8,0x00036fc4d282853a,0x000a0bb2b260d343,0x0008119fbd0756b3}, {0x00053a3a6e0f1619,0x000016a2af080234,0x0000000000000000,0x0000000000000000}}}, + {{{0x00000185bd1fcc92,0x000a0002ebe1f280,0x00030d3e5f23ebcd,0x0009d40f75cccaba}, {0x00063108edd488ea,0x000028024e152a65,0x0008296732e422c6,0x0006142e6cc11761}, {0x0004e44889dea726,0x0004d1b05325e95d,0x0000000000000001,0x0000000000000000}}, {{0x000270a2e4063870,0x0004d9c29b5dcaf3,0x000d2f759d7bad98,0x000ff7c2ad7bc046}, {0x0000fa4e4f59d347,0x000a06be29c16d4c,0x000bb31872d14ff0,0x0002b7a5b6ec2390}, {0x0008ae4cc66be2ce,0x0007006b9b1fe040,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c4cee52cfafd0,0x000916a99628d59c,0x0004417813a4764e,0x0003f0c49a05da16}, {0x000992babb644e42,0x000179a66e24dca8,0x000cbef894f6883d,0x0001ed7756c7c157}, {0x000ff08e144c3013,0x0008ac78b0a3e9cd,0x0000000000000000,0x0000000000000000}}, {{0x000dabd753963ba6,0x000426be7ba3ec43,0x000d17b8f8b93626,0x000d7ac0bfcd2a78}, {0x000c2aeda53c9486,0x000c99eeaefc3c49,0x0003d0949fb4a9cb,0x0005db07562812ab}, {0x0005da4c6c0f863b,0x0009e08ec31fe43d,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008d00b0f45825d,0x00075f4acb7a9109,0x000fe317cf8f4f81,0x0009a77cf8155d16}, {0x000d7ac3ddeef2bc,0x000aeae3c417520b,0x000e6ff44ee6fbc0,0x0008d8c238521aaa}, {0x0003f42c9f47bc82,0x000d2fc09b26d055,0x0000000000000000,0x0000000000000000}}, {{0x00032ac7c6897ed6,0x000498c1e669bb9a,0x000697322f4c8aca,0x000625a543042d46}, {0x0003cdf16aa69334,0x000b4b67c267bda0,0x0005d6f205d341fa,0x000005daa2bd83a5}, {0x000c9573fcdfd94e,0x0004e81cb76afe9a,0x0000000000000001,0x0000000000000000}}}, + {{{0x00074fcede51930f,0x0001c997863b91f0,0x00092d449a3c4328,0x000c91197a68c2d7}, {0x0006a3b2de0b3063,0x0003e7d82555e166,0x000f427f70b4227f,0x00066c04e18d6aac}, {0x0004c82c2c2b9b61,0x00095a376fa210aa,0x0000000000000001,0x0000000000000000}}, {{0x000de0f4a3a29f55,0x00023263844f1727,0x000fd0bec7770941,0x000e79f43b5f4e85}, {0x000035cbc9a5768f,0x0005bb2328826a73,0x0008a77da7d22096,0x00096978fe424078}, {0x000ae1a0514c7cf9,0x00085e77943ce3c2,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000d1b4594afc85,0x0006a925e9937fdb,0x000d1cf398814c56,0x00000694cd250848}, {0x0005fbfd82b6ccc3,0x00047db4ae135bc7,0x000c1f18639e63fa,0x000730a5e5b32295}, {0x00041bb1c61f91b2,0x0009451335383b28,0x0000000000000000,0x0000000000000000}}, {{0x000df27e3f2dca32,0x000ee40fb695c7e1,0x000c8c313d1721a9,0x0008bc93267e9801}, {0x0006a9aafbe12b28,0x000e34c2b180d7a3,0x000e6b65e8b79ae5,0x00047da7f03b22ef}, {0x00094e563552e913,0x000f4aab16538cee,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006db42e9e50fad,0x00042149f7546b33,0x00057093c06f6900,0x000dbce88e00d7d3}, {0x0004ad9ede7428d2,0x0001940521d004dc,0x000e4970d3be2ce0,0x00031bb5cf60dc4a}, {0x0003df5670a6ccb0,0x000b64df04605d80,0x0000000000000001,0x0000000000000000}}, {{0x0005f0fb0c7d8a77,0x0006951f8ad28aa0,0x000e5b908dd39d0a,0x0005f76fd67e92ff}, {0x00080f281077f416,0x0009ee2db2c8d529,0x000e9a09ff0b841c,0x000f9a5850f2e792}, {0x000e9887cd74d1ff,0x0009aa468c4978db,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=21 [{1,2,3,..,}]*([2^84]*G) */ + {{{0x00045bc39568d9b4,0x000deebca99c74cf,0x000ae132b3816aa0,0x0003fb57b713a9d8}, {0x000e4139b0131f8d,0x00042164bbc38156,0x0005a533293d5ffc,0x000f28a54d0e74da}, {0x000246758970fcef,0x0005cb3ef8fd2b56,0x0000000000000000,0x0000000000000000}}, {{0x000e59886b3941bc,0x0009ade1a4b217a0,0x00023117719aa3f6,0x000c88c1b7b4e45e}, {0x000c3f1294233118,0x0001ed8c9dd7dfa5,0x0003ffafa2104f8f,0x000e89ed71382221}, {0x000d0f8573ea0a97,0x000a81f09db9f82c,0x0000000000000000,0x0000000000000000}}}, + {{{0x00077d542b1d8c85,0x0009eb6c76648a7d,0x000ae9936fca1675,0x000c8db3d9556eeb}, {0x0008f1fc23af7239,0x000956a6643df02c,0x0005264fec894e1d,0x0000aaa92f802a0d}, {0x000d756f014a90b9,0x000e0753d197ff93,0x0000000000000001,0x0000000000000000}}, {{0x000dc80b7f62d4df,0x0005de026f897406,0x000bf46ad6add1ea,0x000f1c5d1c416858}, {0x0004d6b3d82ce8f0,0x000459159df587ce,0x000ca473b92c19aa,0x0006da5bec10b6ba}, {0x000e0b4be600af3c,0x000cf6c81e2b9b40,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c67c15f2b99a5,0x0002e78f41b12d02,0x000f7e85b9e3bb96,0x000e6c293dd82110}, {0x000a0b7296f35eee,0x0008b9f01a446a48,0x000f7d8d89873daa,0x000d90409d0bfd67}, {0x000b42d1c91c3962,0x00005e6c3afa1fdc,0x0000000000000001,0x0000000000000000}}, {{0x000607a511880114,0x00046b3caa5f65bf,0x000ed1d7edcb6427,0x000223b76ca3eaf2}, {0x000c254785aeacd8,0x0003d96bed772614,0x000fe17074c3138f,0x000fc4599803c303}, {0x00029d4441854c4a,0x00068d2f47c7e6ad,0x0000000000000001,0x0000000000000000}}}, + {{{0x00027dadf66942d9,0x0002d934d4f0887d,0x00024ab4a3b4ff58,0x0008094d151ee4b7}, {0x00059df116aee58c,0x000c8ad8141ceee5,0x000c277f6cc0cd16,0x000b9d41dd2c3d13}, {0x00018d63c75e0cd1,0x000c06bb0767f3f3,0x0000000000000000,0x0000000000000000}}, {{0x0003f3f369ef6b69,0x0007808f1170f91f,0x0006338ef6344906,0x000cb4597495e6b8}, {0x000283f524ab766d,0x000d7731127ec634,0x00075be86373e0af,0x0008d2af0e3a5495}, {0x00014c6819dfc2be,0x000f7affa7af5c63,0x0000000000000001,0x0000000000000000}}}, + {{{0x000892c7124cd33e,0x000b92182e71043c,0x000db014cae4df90,0x0009ceb0a4ea4119}, {0x000ef942ed19b706,0x0000628b68098d1b,0x00084c6cb159ff0e,0x0004d4b5184cdc53}, {0x000190191d032e77,0x0006b2ec68efce97,0x0000000000000001,0x0000000000000000}}, {{0x0003436236c90d20,0x000e12c74816ecfc,0x0003e074e74849dd,0x0007be255b09c30d}, {0x000526507824bfa8,0x000ef7cb512aeee2,0x0002afeb20a50c2e,0x0008aa489a2c4123}, {0x000334adba554c1c,0x000ed1b94b601c93,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001c752e894f83b,0x0001102db47294b0,0x000efd031528755f,0x0008e7a5233b9d7e}, {0x000dc69c62c7500f,0x00051f44711ee3b5,0x0009d94a5e280f05,0x000b11042cd8c7dd}, {0x0008b14370c2167e,0x0007807f4636e4af,0x0000000000000000,0x0000000000000000}}, {{0x000598691d482817,0x000b8412f599a077,0x0000459d6b4cf61c,0x000405e26f27cc0b}, {0x000ddbc7fdaf5126,0x000cdbba7c4a3026,0x000b262658e4a3b0,0x0000f2e795bb25d0}, {0x000766509eec95e9,0x0005a452259c52c8,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005f6dc2c523bd7,0x000003d082f18f83,0x000ef7ee57fec42f,0x000f2558c3c5a1e3}, {0x00038f0a9e89f93b,0x000efbe9151ca6a7,0x000ed767c4685458,0x00079d486204e6f8}, {0x000a36a1a4b728f1,0x00043b885c25b705,0x0000000000000001,0x0000000000000000}}, {{0x000eabc2b52d4646,0x0006c95bf22f084b,0x000314aed2f78fee,0x000dd61877362fd0}, {0x0009044697d005db,0x0001d56d41727a4e,0x000627e07ab413dd,0x0000b5903e3cd67c}, {0x0009c224e9a02779,0x000806739d1d3428,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004109673b0becb,0x00029788f9eb9435,0x000ae5dfb3d20da6,0x00057d88527623e5}, {0x00015c844e99c175,0x0006a57ec3b40311,0x0000b594aff5aa0b,0x000cea2e84adbe7d}, {0x0007fcbaf1e84a37,0x0008e3048c293594,0x0000000000000001,0x0000000000000000}}, {{0x000f58bede275de5,0x000b21503171b093,0x0007b8e1c737aaa2,0x000dfceb6261f263}, {0x000d21e8e8701620,0x000e453d37db241d,0x000825774e79c85c,0x00066f92bc717db8}, {0x000b9d9ff5a2566e,0x000bfd4ae0bd7b6f,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=22 [{1,2,3,..,}]*([2^88]*G) */ + {{{0x000cd0f9ef7a9efa,0x0001757bbdb01042,0x0001996a380a3fbb,0x0009e651f39db731}, {0x000cdf3f08146bb6,0x000679b0b6ec6679,0x000ae26608474788,0x000d883e5a5990d1}, {0x00061924fa5e209e,0x0001de3c755c0bba,0x0000000000000000,0x0000000000000000}}, {{0x0007c1f82ebae92f,0x000ccf8ace9c6a84,0x000857d9026a1434,0x0005b0b7ad864d4c}, {0x00018f613e2210ee,0x0001165b2c86a357,0x00019fb55984d679,0x000f15401901080d}, {0x0009a0e8b3389ecc,0x000e608b509b98d9,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a526cf604c662,0x0003afa9ed0f7a0c,0x0001dd685ac125b3,0x0007ff8f516f5290}, {0x000ad927c416e17e,0x000fc77cc9720475,0x000071767e1e9190,0x000f6652fcb33aec}, {0x0000f0d48cb2653d,0x00086c8bf16720d8,0x0000000000000000,0x0000000000000000}}, {{0x000404c440590fcd,0x0003377f43e4e408,0x000defb22729c42e,0x000241aec3b37e10}, {0x00092c795c866daf,0x000f4d30790a07c8,0x000075bb2425f5fb,0x0001b7cb5830a5db}, {0x000c950890875f16,0x000e6591cad66493,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003de8c91c31e47,0x000a2de46bc7eb7b,0x000f3de301a0b479,0x00094aa7479aa235}, {0x000be5191502fe1c,0x000266a8b4adef28,0x0002961e0e185a17,0x000f211c2c23ddea}, {0x0007d3314a5b8f85,0x0007d3d59f2b026d,0x0000000000000001,0x0000000000000000}}, {{0x00032b1fd4f159bf,0x0003721f923e006e,0x00024a7d38b715f2,0x0000994620d23277}, {0x000ab6678b2917d4,0x000fa4a8245b0c3a,0x000912038e0b4172,0x000f6fdcf8c4b1b8}, {0x000ccd3b3eaaf19e,0x000d40f97e7249e4,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007975597dddacd,0x0009d9266f6975c3,0x000599f544c22dfb,0x000c2be6db081480}, {0x0002aeb8ec462839,0x0009d49cd3b5cdf1,0x0006a8ba917fb29d,0x0008233b216f9614}, {0x000abf1a9d936c0b,0x0007878c8a45a2f0,0x0000000000000000,0x0000000000000000}}, {{0x0005dd64a0356029,0x0008c2d1625aef0f,0x0005ff56fc705652,0x000323cb9b293d67}, {0x000bd02b295cca5c,0x000c7129104d697c,0x000d83fe4eb4b02b,0x0004a4e9327cc1e4}, {0x000f46cdc9c23cdd,0x00053f946406995a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d1e43a1e16a36,0x000514cd5be788b6,0x000f3827d2f55b7d,0x0000a3f8f594d05c}, {0x0006accb980d1448,0x0004ad1e4f1f6b59,0x000e7dd3016801fc,0x0007c435098ccf31}, {0x000c6bc2e61b9059,0x000588b12be241e3,0x0000000000000001,0x0000000000000000}}, {{0x0000b8e2e65481b3,0x000aef410135fbc4,0x000c7a2e23221960,0x000fd4a513faa141}, {0x000a0357c6f569e3,0x000f4ac3eadff143,0x000f6174146f64bf,0x000c13f9a5506c59}, {0x0005ed7b5be845e0,0x000d0deb4721eef8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e8dfde28d4a2d,0x0001761a2d5208a2,0x00005b6ff5ebb541,0x000b58d09bebbafe}, {0x000a9eccec1be769,0x0004b3933ce41d83,0x000e22e31e1a1a39,0x00081430e109c5df}, {0x0005c36dffc66dc3,0x0006a93ad68549c2,0x0000000000000001,0x0000000000000000}}, {{0x000135d5a197f614,0x000b4beb4875f558,0x000374737f60f213,0x000b3391150b17e2}, {0x000fd51cce3f02fd,0x00090f492191217f,0x000bccbadc4f8a8a,0x0005d89eef2479ce}, {0x000b7145781a1c26,0x000e4d791a7d8953,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006a3d38b806bee,0x0002ffcbc7fbb018,0x0004904b1192a4cb,0x00039b7f571c01df}, {0x00040717c8035f6f,0x000f75f4a725c0f7,0x0003575b1f8427ca,0x000cefd7922924c3}, {0x000c3f91c6705a27,0x000f14804d6b5694,0x0000000000000001,0x0000000000000000}}, {{0x000d6688c387623f,0x000533d1b2b7249a,0x0006a96c61952611,0x0009fa8adb7cd547}, {0x0006614cc5f19687,0x0000dc38a5b55739,0x000b43a1185de8e8,0x000489b0890de38d}, {0x000cfe16e6aaab3a,0x0009a02c0ab01066,0x0000000000000000,0x0000000000000000}}}, + {{{0x00047414fc9de104,0x000b82aed9435d61,0x00062ff16a9bd16d,0x000caf4a3b07e71a}, {0x0003ff9456ee752d,0x000d78dd65ea0d3e,0x0005bf864901fef1,0x0007bc9f42253114}, {0x000cb13ee366fd36,0x000fe6290083f481,0x0000000000000001,0x0000000000000000}}, {{0x00032088e6e77ebe,0x000f38c5e887c852,0x000f005e149cc7b3,0x00089874e1bede78}, {0x000c72dfeaf32e8c,0x000cb0a4d9cb4e28,0x000aba5da48c7113,0x000b1fe289a0af7d}, {0x0005d0dc00d3633a,0x000801c0b05c86bd,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=23 [{1,2,3,..,}]*([2^92]*G) */ + {{{0x000567a7a06de008,0x0007cf045155d807,0x000ce8bb24635169,0x000c2900cba64633}, {0x000c724297174dd5,0x000c3a3851e7f044,0x000f59548c830bf0,0x0003817a26f0d35f}, {0x0003d8b027d923f5,0x00062c2b3dd7cad9,0x0000000000000000,0x0000000000000000}}, {{0x00094cbf6924bf9f,0x000c09986d299bcc,0x000f89ccb5adf6f5,0x00099f825aee26f4}, {0x00056c1b545bb186,0x0000d22aa56595e6,0x000ba5ea3953faeb,0x0003a9580b4b6abc}, {0x000465246d4e240d,0x000d8613b6fdf7ef,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008a64cd725af51,0x000d6dda66823389,0x0001f40d7d1c8516,0x000115e05fb1f564}, {0x000ad7906c2d8d5a,0x000f4efe00496ac4,0x0002d973643f7076,0x0004414f58386c89}, {0x0002d83c2e34b14c,0x000437c00d08bc7c,0x0000000000000000,0x0000000000000000}}, {{0x0004451656bebe71,0x0003f2219e2e5bca,0x000118227eacbf3a,0x0007e2cef1a84019}, {0x0002d58a5f9de601,0x0001ecfa6e192212,0x0006fb198696eb0f,0x000854826be2d3df}, {0x000dea0068fefc08,0x00074e77c2979102,0x0000000000000001,0x0000000000000000}}}, + {{{0x00048eb205a5b22a,0x0007d680f21ad148,0x0008e50bcbdde0fb,0x0006f6074c1119fd}, {0x00079f9f2e43583d,0x00065361f1d9961c,0x000463e625f26bb7,0x000f2b47c8db008a}, {0x0008c397787cd134,0x00029b36eea7ef32,0x0000000000000001,0x0000000000000000}}, {{0x0006647223894ce2,0x00087adfe036fb3d,0x00067daf1eb206e8,0x000b19b372f017c4}, {0x000a8ad33a99ef7d,0x00055c0da806ea7b,0x000c02414bd637ef,0x000b598649739b12}, {0x000feed3dd282f3b,0x0003ecce69b37255,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e5f81ac137092,0x0000518f81e9a3bd,0x0009720014a7f4da,0x0001f457a02bf073}, {0x0006be074553e9ff,0x0004351eaa3a46ea,0x00022b27e32f0dd6,0x0003b488462fd22b}, {0x0006ddddacafc2c2,0x00035bfb75908f56,0x0000000000000001,0x0000000000000000}}, {{0x000987332b5b9a11,0x00044ffe94dfd9e8,0x000f9b91bc64f63b,0x00077f430dbd772b}, {0x000dfd580392aecb,0x000ddc69fb2fb67d,0x000314d2fdb69c91,0x000e754b9b9f9ea2}, {0x000f2e9c2e624f23,0x0000a3c6e677e1f3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e37a930c3bc57,0x00006f969b4cf1af,0x000df3ff74237c4c,0x000d1ea35c488b6e}, {0x000e084f47372a77,0x00065b61ccb75b2d,0x000a4e47577fd773,0x000dbd98a086f5f2}, {0x000533002b74aa9d,0x000bedfb9c8068e6,0x0000000000000001,0x0000000000000000}}, {{0x000b7aec02da823b,0x0009baf08dcbb7e2,0x000400bf0e5f485f,0x0003a3c7f9dfd4e3}, {0x0007472ece43050d,0x00091a092b1134f2,0x0004c1a0e70ff8a8,0x00037f3b75a31807}, {0x0000f51f254e9906,0x000c2183d0367614,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a39c0dd80f6fe,0x000a13cb07adfd25,0x000ee3ca4d8c1a3a,0x0007a28212986a18}, {0x000c5167c4c47943,0x000beb7b7306e9bb,0x00038cfc9b26c1f3,0x000b68e5bc206604}, {0x0003bd9665b63ba8,0x000661b9d7de6c40,0x0000000000000001,0x0000000000000000}}, {{0x000c9e6e7c3229ea,0x000fb93cb721672d,0x0002429ae120fbe8,0x0007d3de1f64e3d5}, {0x000492888bee099a,0x0009c2f4894dc1d6,0x00011bda9ef3c7dd,0x000289559ae47758}, {0x0008fcbb34df4ae3,0x0005c440c5d0ce22,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fc1fd2377e231,0x000257cc9235e4c6,0x000a8f0482692e0c,0x00027d24355728b1}, {0x00087856d3663645,0x000dfe4f7c7f19ee,0x000c0f9ccd7eb847,0x0001019511788244}, {0x000c4838c54b2a98,0x0008b89d2d46944a,0x0000000000000001,0x0000000000000000}}, {{0x000e02a1a1d2a70d,0x000b7d63b4d27dff,0x000ab61d5fa9a970,0x000d7730420f7a7f}, {0x00079f4479996041,0x0001189500cc1597,0x000981b342dd1a18,0x000b0c87b154435a}, {0x000fe5a645fb9438,0x000a1ab34fb7fc43,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f438f4b100160,0x000f22d13ff0c314,0x000d55796ecb8e45,0x0000ab873dd2e2bb}, {0x000789eb71d33f83,0x0003167e0b14a364,0x00002c246513aa48,0x000b03e86d3a7935}, {0x000b2db2bb0fe98c,0x0000d70404a0ec4e,0x0000000000000001,0x0000000000000000}}, {{0x0004384c5c6b60bc,0x0002570cd19a5c8f,0x0001c33b468c19b3,0x000cbac39210942f}, {0x0007d36048a2a29c,0x000f69ef5fd4ffa9,0x000ece5cd6b0a674,0x000b1322973982d0}, {0x0001493bd4bce1b8,0x00083d4d6596bf49,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=24 [{1,2,3,..,}]*([2^96]*G) */ + {{{0x0000db5e813acae0,0x0005831117f6d456,0x0001106059c8e19b,0x000f908ce8232c57}, {0x00092d0f09782c78,0x000bd0fcb64a24aa,0x00077e3d766becf8,0x000f155f53d2f599}, {0x000389ae2fa9a727,0x000920ff877e9249,0x0000000000000001,0x0000000000000000}}, {{0x00085d510d2d4458,0x000dc73b4e520499,0x000aa68342be4788,0x0004f89c8a0ca8e6}, {0x000e8668748927b1,0x00017375ddf19eb3,0x00041d15e5f8b7ce,0x00052912af54652a}, {0x000b9a777a86a727,0x00003bbaf706d85a,0x0000000000000001,0x0000000000000000}}}, + {{{0x00017d39542a7b35,0x000d6953d2cbb145,0x00044a3ef5b5b733,0x00076565472126ff}, {0x000b2a4a1334dee0,0x0002573d17b26c37,0x0002c7ab5b295171,0x0008d328148c129c}, {0x000907f5aa2c72b0,0x00018b1d10e10308,0x0000000000000001,0x0000000000000000}}, {{0x000159666154b57d,0x0005dd9359d8885e,0x0000281b6f14827d,0x0009bc4ba475f3a4}, {0x000c32eef44696b1,0x00082b50dbdc6dfb,0x000236a9ef4383e7,0x000fd73208450583}, {0x000d190b07767db3,0x0003153c0278a00d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ba905f5456251,0x0008ee5b3d8d39c0,0x000ea2a0a4462a26,0x000032f3094457cb}, {0x0009bab36ceff80f,0x0001b0fdf3879073,0x0009dc840209bce2,0x000df0c1c8e03824}, {0x000c51d81213ecb4,0x00063c2b025e0d70,0x0000000000000001,0x0000000000000000}}, {{0x0003bb32c4b899f8,0x000ccb798bfbf249,0x00028838277f622f,0x000e5b67c2594827}, {0x0003c2c07c4dd5cb,0x000c19526a2c4c70,0x0000177dcd0df4c1,0x000457a743a1ed39}, {0x00032bea63a4c527,0x00075d1c302e78ac,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fc5003828ff0b,0x000436a9841f4323,0x000c6f35f8a62407,0x0009286efc260a1f}, {0x000fbe74c4b2df5e,0x000cb3568b504bfa,0x000dbcf3548e5047,0x0005d92aaad71af9}, {0x00018241085e423c,0x0004f894d1d8842d,0x0000000000000001,0x0000000000000000}}, {{0x00075b2a3f29b75d,0x000ec555f7834899,0x00092b31a410939e,0x000b7bc223255263}, {0x000db65a25c264a1,0x0008fc1aed283464,0x0005c70ecd1a9b70,0x000d90a7a2a0ea33}, {0x000d21f2e9f14ffd,0x000fb49566dadd7f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fa5757545376f,0x000ae164cbfd55ff,0x0008a8545451f1c3,0x0002e007d0be9705}, {0x000ed2a8f4c49727,0x00097ed736254138,0x000516215e864c7c,0x000bb624fc1b83df}, {0x0000313aaf4114fd,0x000a7a8c7f0423cc,0x0000000000000000,0x0000000000000000}}, {{0x000ed76abc8d276d,0x000bfe3e74f599a4,0x00025d1f92d8b381,0x0005a3599e406956}, {0x00071869bdf5e06a,0x000ec86f625afaf6,0x000d724bbcc12cda,0x0003da7516890dd1}, {0x0009b69252163060,0x0002541f15a18b40,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e1c4e632e5d61,0x0002987ad659b7d5,0x0003f7f338de2f2a,0x000b55a5aaeb06f1}, {0x000b9a60e84f26d9,0x000d10563130c6f8,0x000e760d017d58e9,0x00039e20b973fa41}, {0x0000eaafdb2f4acf,0x000501ec9c6ab584,0x0000000000000000,0x0000000000000000}}, {{0x000f4549ba5a6302,0x000a98b140b89722,0x0003e099225c2510,0x000f31b19117bbe6}, {0x00046ba7147bd18a,0x0000f540e368bb5c,0x000eacf29d33114f,0x0007e59588a01c9a}, {0x000ef0e25eb2d0e6,0x00058e4bb1b8d029,0x0000000000000001,0x0000000000000000}}}, + {{{0x00057915cb5440b5,0x00088e89a3e1eb04,0x000ed12c670e08cc,0x000eab1d89133ab9}, {0x000f615d9bc0c1fa,0x00081504d63c4250,0x00062cd084c8e8f8,0x000aaf76dbe53ead}, {0x000bf1dcc49cfac6,0x000fc7007ea0b885,0x0000000000000001,0x0000000000000000}}, {{0x000472352fc50515,0x000fa2123835c747,0x00067bab29e80692,0x000cca008379c2a8}, {0x000799065aafbc2e,0x000a605d2e32da97,0x0002283421bbbfbd,0x000dbdc2e1151243}, {0x0007a9d899c126b9,0x0007467ce3f8d643,0x0000000000000000,0x0000000000000000}}}, + {{{0x00000c97f4a1ee70,0x0000a55fa6cdb3e0,0x000fd5fcd60595ed,0x000522bda02a23c6}, {0x0000361844a1d76e,0x000c6c179ebaf8c0,0x000a6ccd0a47af40,0x000071e2a1156aa1}, {0x000a1b0fc4eb0062,0x000bb4c1c5314a2c,0x0000000000000000,0x0000000000000000}}, {{0x000c048376702b16,0x0002ef5b4e8123cd,0x000a7d67834242a3,0x0003bc3accb0fead}, {0x00007e65ed32fc2a,0x000b8b44e6e71194,0x00077e9aeb1712aa,0x000039ce4f895a59}, {0x0009d43ed708cfeb,0x0004254957cd1ca1,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=25 [{1,2,3,..,}]*([2^100]*G) */ + {{{0x0009a3fb62f03e91,0x000fc3cfe3b9a1c2,0x0008c5a528bca033,0x00096cd7b4bc3e3f}, {0x0008c4bd134e2233,0x00065224c739c3eb,0x00071ec25548c0a5,0x0007b0fb17f6f014}, {0x000aee1015fc6579,0x000448c4d69b6d18,0x0000000000000001,0x0000000000000000}}, {{0x00074be708f600f9,0x000042a14b550a00,0x000f8e6b95a52425,0x0004e9813f438c42}, {0x0005181004aa1017,0x00010cd9a834ae43,0x0002105b1b67e295,0x000141438bad8cdf}, {0x0004d11308ec5ba9,0x00034300e8c08dc6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000625d111480c24,0x00034cdcf3505fb2,0x000c306874b99629,0x00004410981e8fcd}, {0x000492bd0a650027,0x000a534a84249eb3,0x000e1326b6bb40b6,0x000ebe5d29140c32}, {0x0009956b2cb2ca52,0x000b8c77c7225102,0x0000000000000001,0x0000000000000000}}, {{0x0002b4e077c5c4dd,0x0008846314442efe,0x00066618e794431d,0x000a933fcd3eeea2}, {0x00006644159656a5,0x00022dc52fbda24f,0x000542f82f45dda5,0x000e0e5075c9d412}, {0x0002aba0fff34a66,0x000d69512c4a1d9a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dc5b949f6aa55,0x000cb79872016ba3,0x0001df5e18d2889c,0x000aebf5e0129254}, {0x0003a4cd20b4cdbc,0x000f30108963d6c3,0x000c0dbc46a1dad1,0x00042c0e39b6755f}, {0x00007fa126ef9e69,0x000805d500d36fac,0x0000000000000000,0x0000000000000000}}, {{0x0000b5e7bd19e5fb,0x000b3765e8dbbff9,0x000e491cc2deb8ec,0x000ab995d314c068}, {0x000b4e810513ad31,0x000b50dc0fcca181,0x00029580c1e05269,0x0006b6453c858930}, {0x0009a98b2de5a7d2,0x000b386f7a77183c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d861fc542368a,0x000a737b3c184cd7,0x00014a6e3b95c425,0x000f514e85d4a651}, {0x00098b665bb45532,0x00066a39b08b87e5,0x00008dbdbcbbabba,0x000ba64b561fa462}, {0x0005692509520864,0x000281de8b31e205,0x0000000000000001,0x0000000000000000}}, {{0x0001bb6a74473c21,0x000932e76a8c5ddd,0x000c6ee633cc0f66,0x000f68d0c546bb80}, {0x00006828f4e0c911,0x000b2a4276c213a2,0x0008cb204a16b2ce,0x000d38c09aa1cbe9}, {0x000f3ebeebcc1671,0x00032c7a684ba9a6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a3463989cd762,0x00035114b160b22c,0x00057f2d520e3cc4,0x0000ff788707011b}, {0x00068b1a346a61d3,0x00084618b8d69eda,0x00020c04008115fa,0x000dfeeecaa806f5}, {0x0007e08436a14e30,0x00005f68bc839ccc,0x0000000000000000,0x0000000000000000}}, {{0x000ae58e3c998f3f,0x000951d35d5af6b3,0x00038625415f29bb,0x000fd087552cd755}, {0x0002087ef7e8ab49,0x0006b067b5de9ebd,0x0001e74110309c17,0x0007b224505a1ece}, {0x000ba962991a5a2d,0x000b8879263dad03,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001b7e0189fcda6,0x0008775ba885f2a7,0x000b98305b9915b6,0x00019b2753769a90}, {0x000638d87ac0d10c,0x00083c77c18f7acf,0x000d23964d02af25,0x000de5be92026e04}, {0x0005a30998f85294,0x0002d2bb22f8803a,0x0000000000000001,0x0000000000000000}}, {{0x0000daae09876e93,0x0007b9f1b9b10415,0x000e48eb13c50096,0x000cf9ccec3e5c4d}, {0x000f7b6158629895,0x000aa201ea7d90f3,0x0006e88c0cda29f8,0x000f4c0d70150c9a}, {0x000ee70bc97d1c62,0x000b8e4fd0f68d56,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003edbb844d6c8a,0x00076a792ccd3b41,0x00072527a7c1564f,0x00055b682778d6f2}, {0x0002167ba3cee45b,0x000d96d43a6e138f,0x000806538c932f15,0x000d4892afee6363}, {0x0002b82f06ed7c45,0x000fee287b4614b8,0x0000000000000000,0x0000000000000000}}, {{0x000953f4fc1bb9d4,0x000e995150d18cb0,0x00067e23c2e107a5,0x000bfba071a733f6}, {0x00008ca46066c2e8,0x000cfb49871d6c61,0x0004ece39bb5a648,0x00040cf34f514816}, {0x0009b9250336996f,0x000c69d6e08146e9,0x0000000000000001,0x0000000000000000}}}, + {{{0x00008e517921a752,0x000ab87a6c13d140,0x000c4597b07c5d69,0x00074a68c66db12e}, {0x00019ca40dec9dbd,0x000a617fff4579d7,0x0005876131725395,0x000d09e3b946e383}, {0x000d20c852478942,0x00087982ecbef742,0x0000000000000001,0x0000000000000000}}, {{0x000589886da1602b,0x000c3fc9ae2bbd5f,0x0002126ee978ba22,0x00075595e212b5ab}, {0x000a2389b739eff8,0x00063595af9d6707,0x0000f9787d12dd72,0x0003b014c3309267}, {0x0002f506a0067880,0x000f67060764da69,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=26 [{1,2,3,..,}]*([2^104]*G) */ + {{{0x000365108b90f9d0,0x000f80765f67fb1e,0x000b1b38d141aae9,0x00024d697a9407e4}, {0x0003f9693e7ccc84,0x000a50e7d291d93e,0x000cd34385c13c5b,0x00066fcf73c9d94e}, {0x000598f4a80eb0bb,0x000b721c4d4c290d,0x0000000000000001,0x0000000000000000}}, {{0x0000fb9a3bbeb3c7,0x0007ba326d546e3b,0x000a848cf094c6d2,0x0000e41609d2dc18}, {0x000266f0069ca46c,0x000c4aef799231b9,0x000abacbdbead081,0x000b272ba1959d4d}, {0x00049b7208e216ce,0x0002ba83cc03eccc,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004c0998b5250d8,0x000c867c43b599d6,0x0004c9f6ac785a2e,0x0004ec8b59f29f0d}, {0x0004df16ae8c0faa,0x000b8d8f78201760,0x000bc38bb59089da,0x0007384039822772}, {0x000d1571c6e88e81,0x000a7b7d4e8e0cf3,0x0000000000000001,0x0000000000000000}}, {{0x0007bc572ea0f919,0x00064539b5eb1047,0x00077d71bc88d22a,0x0004dc62d769223e}, {0x000adfe2b562c973,0x000173fab241cdb0,0x000603370ddf3ff3,0x000f70dbbbbd997d}, {0x0008a88a56d59561,0x0004be64aafc3299,0x0000000000000000,0x0000000000000000}}}, + {{{0x00045d30a00d827f,0x0006bbe20955e997,0x000cead0ee1643eb,0x000fce2db7c5ac6f}, {0x000ad1d2efb30bc2,0x000d9fbc667affb8,0x000bb6fb3983d3ef,0x000f70a834538091}, {0x0008384fd172dade,0x0003f32390fa3030,0x0000000000000000,0x0000000000000000}}, {{0x00022aae53d2000c,0x000caf0273baad84,0x0004a6a878c712a8,0x00002615beecdb4d}, {0x000b0e868dba85ad,0x000964d03b5c6537,0x000cbcf8b6d0fd98,0x0006a16ca9f74a32}, {0x000552ffb8c5dbeb,0x000bf0f20d682f2c,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009a64c8deb9f4b,0x000532674c0fe944,0x00001e88fe681603,0x000b8697595c6e13}, {0x0008cf6f513d4913,0x0008c1e3203b6d47,0x000b68db28573518,0x000bdfb9fd4390cf}, {0x0006601496c4bb93,0x0000633f388af7cc,0x0000000000000001,0x0000000000000000}}, {{0x0005258fb2317523,0x00040dacae0a8b9a,0x000ba0560abb741a,0x0008bc6a795d005e}, {0x00096caa47999397,0x000ff04fef1c0b24,0x000b0926ddcefe71,0x0008f281ff3947c3}, {0x000027cc7cc93f3d,0x000e78773c9a3f23,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001c60cc85e7257,0x00011fa52f42f768,0x0002f380ec8fe41b,0x0004893bc07fb9d3}, {0x00034451f49fbf7a,0x000388023d1b4705,0x00079c42053de8b9,0x000cf909c04d42cb}, {0x000eca57f6797b3a,0x000cf34d35027c43,0x0000000000000001,0x0000000000000000}}, {{0x00086008351763ff,0x000f9e1103300427,0x000991707dcb32e9,0x000efb21a41fbb4f}, {0x000b5649d55978db,0x00004e4d7b3fa6d3,0x00012196968dee3a,0x0003561c60989b74}, {0x0009c91c53ee540c,0x000b9823a2ee0db7,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f6a15601d1f8d,0x000406c4591dc921,0x000b36c8aaaf7c15,0x000834fd3b0d0813}, {0x000e544ef9e76287,0x0002fb609294a18c,0x00008d9bd0198775,0x000cd4816092b24d}, {0x0008b097d39d2d32,0x000b3a5b9f00f218,0x0000000000000000,0x0000000000000000}}, {{0x000da9d6f0979e9d,0x00080741dad104cc,0x0004ee619b7637d2,0x000d71560f5a9cc8}, {0x000b897bb554b4f3,0x000890a210367054,0x000aff63f1f61c3e,0x000cb92963c20784}, {0x0009317afc9acc43,0x0005c1dadb0d3e30,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004debc7af95096,0x0002bf8bc26e7cbc,0x000070bd1c43e146,0x00017181a62e8acb}, {0x0001c46b5339f3b4,0x000a2c14c9b646ef,0x0005de576b9f4c81,0x0004f9a155e97645}, {0x0003cfbba219f7e3,0x0009fb1fd4f92031,0x0000000000000001,0x0000000000000000}}, {{0x000bcf11449769d9,0x000ea5acc7cb996d,0x0006bdb653213f43,0x0003a2cf9c396c5f}, {0x000777fb3075bc28,0x0009fab46fa97f51,0x000d80cd600dc1e5,0x0008ba6a57a9d490}, {0x000c9975b8111175,0x00067a2ad8270658,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005e67b8d52ab83,0x000eb2049665d86d,0x000b56e1ced19993,0x0009c1fc7a62ba87}, {0x000276fc5cf75dfb,0x00054f5dad4712b6,0x00089fbe0548bd15,0x000d1ee24125ecba}, {0x000176a53fa18f5a,0x0004e18796b5267e,0x0000000000000000,0x0000000000000000}}, {{0x000a0f1a17a9eb45,0x000584e4e5f968ad,0x0008e12a3e089107,0x0009c73cd6a2ba69}, {0x00002e23b2a1f1ee,0x00028e9adc43a76e,0x00062c6e3d7526f4,0x000d0557ab8af09d}, {0x00058b1d337cd537,0x000000e54434b827,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=27 [{1,2,3,..,}]*([2^108]*G) */ + {{{0x00036c3a6abc7042,0x00004a11953f80fe,0x0000b4cc57cd15f7,0x000df44d3d3a8bb5}, {0x00015b5099398347,0x00081f3a553789e2,0x000d0115f2bce30d,0x00090b7f91f0853e}, {0x0007ec29320d53ac,0x00085b63e7bfbe8d,0x0000000000000000,0x0000000000000000}}, {{0x000cdcd80232c6da,0x000d8fc636cf5e56,0x0006e4c3d9621241,0x000b84a86812f9d5}, {0x000287741d3de81f,0x000ab3d77eb50a79,0x00048627cc80386b,0x000a1901afee8f37}, {0x00095591fbf5ceb2,0x00080aed0c8140dd,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002fcdd07efc38c,0x000c9ad8b1dbd166,0x000af6b6e1566c06,0x0005c4ad28998a9b}, {0x000b12d2005dbca4,0x00009acb17fcd947,0x000af2e6bf7b35f6,0x0000b8a8aba325eb}, {0x000302e3f599df52,0x00080d2bf9b973e4,0x0000000000000001,0x0000000000000000}}, {{0x000aebd112a3c0c1,0x000c408868630c25,0x000af7c4f6ba5529,0x000d49e0f5657b1a}, {0x000da3fa70b84c0f,0x0009f530044d86ec,0x0003f7ec59dce6d3,0x0004bdaf73433951}, {0x00022dd61822c292,0x000466acb0786ece,0x0000000000000000,0x0000000000000000}}}, + {{{0x000bab3d6168fc90,0x0007cbb6b2be9857,0x0001cf2ccb017656,0x0001630304c6ccfa}, {0x000ab9344dbdd28a,0x00075f0fec3093b4,0x000ff2494e7a4029,0x000ca3bad1c9c568}, {0x000b17aa4b7bc2e4,0x0001be8844e06c12,0x0000000000000001,0x0000000000000000}}, {{0x000748f359f51efa,0x0006b016fa4643bf,0x000de784a5c3f1e9,0x0006412db1ab3996}, {0x0002a042b01eeae2,0x0005a0d3a2a424ea,0x0009b9a7aeefe348,0x000b209614c9d52b}, {0x000556ff1e6afd00,0x0001e2290dec8fe5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000dedb27f20e8c4,0x000f535a0fc33855,0x000788ccd8803e8a,0x0001f7d6e10cabd0}, {0x000355f889d7fa1f,0x000583e3030487ee,0x000f3dd1885d800a,0x000f09ae9a4a2fc9}, {0x00054fc302887b5b,0x000678d91181d3a5,0x0000000000000001,0x0000000000000000}}, {{0x000b146d6cdca631,0x00046652f280d553,0x000e0b73d63dfaac,0x000399cd0d77869d}, {0x00057ba5ffe6aa8a,0x000ffc1da65c61b7,0x000738771cf6c9ea,0x000620ae124834d2}, {0x0006504def184b95,0x000d761c974cb47f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b12824a32cfa1,0x0009c552049f6e5b,0x0002cf47aab27c7f,0x000c49affe61e35a}, {0x0002247309f28abd,0x000d8f5d3d157087,0x000c6b864fe18c22,0x000addbbfad216e7}, {0x0006e83c0b6f0f26,0x000fd5df730de2cf,0x0000000000000000,0x0000000000000000}}, {{0x000d5ed49aa6d720,0x0003b8bf56601c9e,0x000932a05f265897,0x000b6e7997e501b5}, {0x000a12ea7ac82871,0x0009ee973ffc91a5,0x0008bc4a89b5c6c1,0x0003ff7cc4ea3cde}, {0x000dd04f7b689969,0x000d1dbe61024f53,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009c8cbe80fbbcf,0x0001820704f59919,0x000a2837d2432345,0x0001d7c57c052221}, {0x0004dd7abcf6f7fc,0x000ceb0c9ac384fa,0x000cbcbae19fcf70,0x00044465c2e5cd22}, {0x000a11ffc8ca98c5,0x0007b72231b3018f,0x0000000000000001,0x0000000000000000}}, {{0x0005516f6500002e,0x00015b8dc7f05ee2,0x000111229aa6356e,0x0006bd0e54525c30}, {0x000dcfc5ecb4c0df,0x000355785f844693,0x000ab74792af79c9,0x0007357c34213765}, {0x00008a7b5867734f,0x00069a6d820a3083,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b3a34b0a583e8,0x0004109d1c2a05b3,0x00056d185c8227f4,0x000c30eb0f8b309e}, {0x000e5f0d836e7213,0x0002fdae4ffef15c,0x000257bcdd2d7309,0x000dad1ff9a8d757}, {0x00098efcc192b734,0x000fe0e5b46f1d9f,0x0000000000000001,0x0000000000000000}}, {{0x000ec3057c0b1268,0x000e1eea4fea07c8,0x000ac5ab201c4cbc,0x0001b75086654bcd}, {0x000e612c2aee9474,0x00065fa077070bf8,0x00015dd97afeaab6,0x00088802f9979ef0}, {0x000c9b3109eb556d,0x000e513d135fae08,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009b9b53c1efab4,0x000babd37156ff65,0x000a115d2c7f8338,0x0007371c9d1175b5}, {0x000a353c22d6aa92,0x00079ee37be5b07d,0x00020293585421cb,0x000abe2b0a938ac9}, {0x0003622f3d489e47,0x000ac9ccd5811b36,0x0000000000000000,0x0000000000000000}}, {{0x000cb54f0f506ac3,0x000feebf83fb7441,0x0007d9fa2d5527b4,0x000b40376d4a3597}, {0x00045e4619c87f8a,0x000b913b27d590e9,0x0001da0e8861075a,0x000dd8fb707f389b}, {0x000140b6fe0beb49,0x000bf7392dd17235,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=28 [{1,2,3,..,}]*([2^112]*G) */ + {{{0x00082a01cdf12457,0x000bf550e3442670,0x00027cfd7b191616,0x0009bf54426bd9ae}, {0x000375f468d0ec29,0x00095e63540487ca,0x000f558b93aa7dc6,0x00028f48edec9322}, {0x0007ee742818f059,0x000d23aca5b08895,0x0000000000000001,0x0000000000000000}}, {{0x00018972085008e4,0x0009e445a0130711,0x0005bf246e5348cb,0x0008ccf1f5c183c6}, {0x000f2e9a40aeb3fd,0x00087abdef0fbda6,0x00050f5daf09cee0,0x0003e33344ee90c4}, {0x0004044243abe107,0x000b8f02a065d1a3,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b66d418145236,0x0007896ea70c3fff,0x000cb17d54fc5491,0x00042a641eaf6e4d}, {0x00096b15be10c7c6,0x00011efe5f993282,0x000c04930829e9c6,0x000a5f18e8613cde}, {0x0007985a51a7c38d,0x000b8f3536d908ab,0x0000000000000001,0x0000000000000000}}, {{0x000ce50b447f989e,0x0006725435f6e48e,0x00060505d7413d04,0x00051fa907efc4e5}, {0x00091cc601ad28a5,0x000eeaf4b18fed33,0x0002e1a4338a8549,0x000b61868d3372c5}, {0x0003a511bce70bb6,0x000e1f5c8d75eb9c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d68d2a3e7e05d,0x0009bf6f65a63322,0x000368db479d7794,0x000e22f5738f46ed}, {0x000947212d465e52,0x000bb783e24758d1,0x0009d33d677a59c8,0x0005609046041b23}, {0x000f6497a9c2f277,0x000e7a9be5339a8d,0x0000000000000001,0x0000000000000000}}, {{0x000804d780847503,0x000fb6bd5cd190b5,0x000d58769b6bfbeb,0x000a5b2366d25685}, {0x00084206ac283f9e,0x00045e93a909d14a,0x0007818e03b612f8,0x0005061fa312c680}, {0x000501efdeb98070,0x00043cfa3670b66b,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008296f30c9bed5,0x00099a4bb11c1f32,0x00015b4084960501,0x000c50ce53a7ca7c}, {0x000f50a2c1da281b,0x0002c0e34f682873,0x000f21f441021705,0x000e9f354fbc9c5e}, {0x000d7990a0bba954,0x000ca402432a326c,0x0000000000000001,0x0000000000000000}}, {{0x000e6dddd976d76d,0x000a57e55cac7b2b,0x000da37392c8a3b8,0x000fecd4ec1dc93e}, {0x00009cf4f78c92e3,0x000ff689fefedf3f,0x000abd5033740521,0x0000df4087ca092d}, {0x00002763eb9e4e11,0x000689f3f329b79d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d09236f94e981,0x000f3b87c2492089,0x000090559806590f,0x0006b638cb962e83}, {0x00043caf0b4cf40f,0x00066f61c7a2faca,0x000edaa5c1d246d3,0x000b19d9f9d7b0bc}, {0x000d3b97c04cafce,0x000f23bf9f27399e,0x0000000000000000,0x0000000000000000}}, {{0x000b2a804eb31689,0x0009a2a7437938a7,0x000f3c9cd990c2d5,0x000b68b7f843ec1e}, {0x0005141dcc07de04,0x000fdd1e7d56eecb,0x000a099220b61db4,0x0004184b463b9f76}, {0x00076a6a6fd2bcb4,0x00067d87f98ad9c6,0x0000000000000000,0x0000000000000000}}}, + {{{0x00025736286ff497,0x0002401f1271e328,0x000981dcd7607683,0x000cfb7ab6548084}, {0x000df4da03d9c990,0x000d822ebf4ae8a1,0x00099db5f23d4a99,0x000f6315e3fb9894}, {0x000021f262e80d80,0x00027457b91d5ecd,0x0000000000000000,0x0000000000000000}}, {{0x0007a0ed90d98205,0x000cf6f6b6c517c8,0x00057c5ae11bc6b8,0x00000efaef845be3}, {0x0005e74813e365be,0x000c8e0106700aae,0x000d776c99ef5ca6,0x0001e3d37bff71e1}, {0x0003a89779b96572,0x000c15ea2a31bd25,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000092959940ede,0x000bb4c7bf2ceef4,0x000d604555c30636,0x0003fe5635d8d5c1}, {0x0008cdef0cb902ce,0x000b6f22235732b0,0x000fddf6f7cfc6cb,0x000369004df1a446}, {0x0004ba65bcff1dc7,0x00020adfd4756b77,0x0000000000000001,0x0000000000000000}}, {{0x000afeaa9dfdfa89,0x0000b80d92606c1c,0x0006888e19c65eb3,0x000bf9bb4db51900}, {0x0008e84280b5d191,0x00077a1cb4c3d007,0x00055fc83156ea4d,0x0009f40279edea0b}, {0x000aa5223480bee2,0x000f264b4f70afa9,0x0000000000000001,0x0000000000000000}}}, + {{{0x00054382d016c8d9,0x000ec7826f7b17bd,0x000dce64f2832c36,0x000193ae22a16680}, {0x0000aaf6a85c2ab2,0x000f20270252cc0a,0x000f317cc1335b32,0x00003743776e2afb}, {0x000a199000deb474,0x0006bc61591f25f9,0x0000000000000001,0x0000000000000000}}, {{0x00084eebf2800729,0x000608b06a4eb61d,0x000b23e73968bb72,0x000a3ae82e886104}, {0x000d27c8605d2992,0x00033bec6e418a91,0x00029d45f2b49e6e,0x000bd1f4a3f4a9d8}, {0x000bc4ceaeb2f044,0x000c63b1ef09fa28,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=29 [{1,2,3,..,}]*([2^116]*G) */ + {{{0x000826845611f97e,0x00015b6b1ee54a04,0x000608b1dc092400,0x0009050925698b8a}, {0x00031b5e532ada13,0x0000c41c46df4acb,0x00090c116e05bee3,0x0009642c127307d1}, {0x000365a48b566eca,0x00046d5c3cffa21b,0x0000000000000000,0x0000000000000000}}, {{0x000b8836b9754189,0x00079ea005768621,0x0007bf51510520f5,0x000bbc0ca43d38cb}, {0x000c9fe21891a0a4,0x000242b093687446,0x0006d618feab8811,0x00047a921f31cacb}, {0x000cb09d3cf611aa,0x0007d8fef9a8efc5,0x0000000000000001,0x0000000000000000}}}, + {{{0x00042c81af50749b,0x00081540e019366d,0x000d6072e7b7487e,0x0004156c32da913c}, {0x0003df1e87478e7b,0x000880f5ccb21742,0x0002347ca344dd54,0x000d15da2c269018}, {0x000993e2887d2337,0x000379604cc23f8d,0x0000000000000001,0x0000000000000000}}, {{0x000778d40c2ec9c0,0x00027ec9dd1808f9,0x000dcd7b63f43450,0x000cf65f198a63ab}, {0x000d3a7a4c38803b,0x000476f99f1130c2,0x000d6b9c1ea5019b,0x00034f67377e991a}, {0x0009047dfa9f5ad1,0x0005dc80641e2fd9,0x0000000000000001,0x0000000000000000}}}, + {{{0x000de0d9dfa7af75,0x000eba7ea5710283,0x000dd5435234652c,0x0006f821b8a36856}, {0x000c319e00261b58,0x000ed079e56ce309,0x0001099e0f75ac31,0x000e2442020d51ff}, {0x0008b83fa0c077ae,0x000e6fc85e1f8724,0x0000000000000001,0x0000000000000000}}, {{0x000872b798445d10,0x00032b311d3108af,0x0005040c97d2ca2a,0x0005703d4fa4c2f0}, {0x0006980d5eb27761,0x0005f074a536c8c1,0x000181395daa1e3b,0x000b672dad89bda9}, {0x0001f3d94395bd4f,0x0004b4c4a2c81ef6,0x0000000000000001,0x0000000000000000}}}, + {{{0x000924e7856ff846,0x000ee4f61f664ccb,0x0005ac67cb02e404,0x00050da76b002de5}, {0x000c4537e3c3c875,0x000c36c052b6b43f,0x000b204b2d5ce01c,0x00088e7f6d0e0c5b}, {0x000c188bbf930fde,0x000168056f87d909,0x0000000000000001,0x0000000000000000}}, {{0x0001106b668bd3a0,0x0008dce76203aabd,0x00002fff3110182e,0x000f7d1e1307d3fa}, {0x000347101339296b,0x0004a22e456ed2ca,0x0002d011b668eed2,0x000b79cf95e5e410}, {0x0006693b0681d10c,0x000355f94e08ac6c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000323242b9413a5,0x000d8925b57cdbcc,0x0004d31e6960afac,0x000cc1c8075e88b1}, {0x0003a4d853d5880e,0x000c2d17b4e21339,0x000c35a1d02b3405,0x000f7f4eb22a29f6}, {0x0001b6570763f945,0x00008a38d9e91699,0x0000000000000000,0x0000000000000000}}, {{0x0009e262a8faf74b,0x000d89cdb707d091,0x000c28362e27b3cc,0x0000a8d2e31adec3}, {0x0004f2e5340b0d97,0x00076d44ac11f1ff,0x000ddee42bd388ab,0x00052165e718528c}, {0x000c2384a7cb055f,0x000e3bd81cae87a8,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e0ef29067ec5b,0x000b3efb1759268e,0x00093d33d241c82d,0x0005ebc6b912da50}, {0x00004cea7d557bb1,0x000a95c0c2531329,0x000338d1728bce52,0x00023e934774d703}, {0x000bdaa179ff6232,0x0009c05a25267ea4,0x0000000000000000,0x0000000000000000}}, {{0x000b3f1bf490cbf7,0x000ec049cf21d24d,0x0001567c730a18c0,0x0008c3e0f359d391}, {0x0004ea1bf7eca8f7,0x000252d4d89f9aa6,0x0007a2e5b2ffd6d4,0x000e70d5197d3cf7}, {0x000ac046e420f1fd,0x000f82fbaabfd6c4,0x0000000000000000,0x0000000000000000}}}, + {{{0x00023d833bf81b28,0x000064787960d20f,0x0001e23da2c1a82d,0x000fca0df31fd1ab}, {0x0000d67beaa32632,0x0009e45d2648f548,0x000d563bb162f9bb,0x000110e02089d434}, {0x0007082d3a10eef0,0x000cb7b7735d1d64,0x0000000000000000,0x0000000000000000}}, {{0x000d95b89701e6ec,0x0003bbe61d29d940,0x0001c7d5b4e68b4d,0x00012a5ad78df4bc}, {0x00047d83302cabd6,0x00011140b2809827,0x000211a754f62795,0x00041d43610e16e7}, {0x00099e665f0dec95,0x000ee6baca9f0f39,0x0000000000000001,0x0000000000000000}}}, + {{{0x000657257b2d9252,0x000915208861aaee,0x0008adfc02b5d4bf,0x000f78398b2a8792}, {0x0002cd1929e3951b,0x0001878fc66ac2d8,0x000a1972453f26a5,0x000c0ebd963c67c6}, {0x0006feb8829e6f9c,0x000c986a8aecc7ab,0x0000000000000000,0x0000000000000000}}, {{0x00030636d8df74f1,0x00011de6a5beb09f,0x000247b37675f6af,0x0003d122a04301fc}, {0x0003f577167d7789,0x000a69addd4d974f,0x000f8be983fc60de,0x0003627055a8d35b}, {0x000c83aaf95c80a8,0x000a9aa21f06b151,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=30 [{1,2,3,..,}]*([2^120]*G) */ + {{{0x000c1e136664d27c,0x000e853cf04eac1d,0x000599f98901c4f5,0x000f0e3ecbc44867}, {0x000ee5a12a7f834f,0x000066c152851c12,0x0002df97ca61be6f,0x00027153da2c7383}, {0x0003e882e14acdbe,0x00030b87567338b7,0x0000000000000001,0x0000000000000000}}, {{0x000fe8148de5b00a,0x0003a405fd56d3d1,0x000e986a7db49ee5,0x000cf7bc11101981}, {0x000a9750760e2695,0x000815cb90b6aca2,0x0009f299f5ace2a4,0x000d6b06b61bc3dc}, {0x0002e5c223b28698,0x000c0b5687880a6b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f552c0e5d59cd,0x00029aaaadcddf1a,0x000f071e91a160c3,0x000bbaf777f33e93}, {0x000696e836178f9c,0x00030ecc6d74f3bc,0x0002571349ec6474,0x000dbbec63ff9e68}, {0x000eff8b43f624e0,0x0008000d19e23a64,0x0000000000000000,0x0000000000000000}}, {{0x00060d53484cb54f,0x0000d83eff3832ce,0x00012f600dae89d0,0x00089d2df8745dbd}, {0x0008a48217cd83eb,0x0005ce0f8ae79b86,0x0004021c2c4ae44c,0x000ea980ca2b0fe9}, {0x0004146745ab9482,0x0001c2cffa33fcf0,0x0000000000000001,0x0000000000000000}}}, + {{{0x00076fd51fd99bf9,0x0007e3a2b01fa7b1,0x0001a17875cbebf2,0x0008df20ca98073a}, {0x0001c738732531a0,0x000c360b05cea958,0x0008986bad316bfd,0x00009591db5fb8a6}, {0x0008ce8516941db2,0x000cd50df495ad83,0x0000000000000001,0x0000000000000000}}, {{0x000d46b24a5b2933,0x000a4af0d09b27b5,0x000e34ef392f2b04,0x00028d0cc4e0cb50}, {0x0005bbe1270619c0,0x00002d927660b899,0x000c444a9beaf922,0x0003686effea3a61}, {0x000321e427cc238c,0x000fe609075147ce,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e9dd164c62b53,0x0001878a3599a216,0x0000821091d05317,0x0002cda324ef2697}, {0x000e94950f2f16ed,0x000815b553eaefd2,0x000f8019f00612dc,0x0001930eacc547c1}, {0x0006fc4a1fd1730a,0x000db88252d52d13,0x0000000000000001,0x0000000000000000}}, {{0x00077522a6c4bee6,0x0006b12deb38426b,0x000ca869197aea9f,0x000c43193823d16a}, {0x00028f12c9d38187,0x00031f43dad5cc98,0x000728a436529c3e,0x000863d40c6f0781}, {0x000da1798bfbb097,0x0001e17a19693394,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a20633820f8b6,0x0008884ce6057395,0x000b9e9ac4298b05,0x000f80c79f28e7bc}, {0x00012abb15751770,0x000ce75763d01472,0x000afbe67296f82c,0x0002a2950d9f8034}, {0x00031ca6f1179141,0x0008bb87c616f997,0x0000000000000001,0x0000000000000000}}, {{0x000f27dc8004bd5d,0x0004fc5fa5d017c7,0x0009fdb4deb95bcc,0x00051c1e39917e40}, {0x000cfbefa777d300,0x0006ebd51f3f36df,0x000089ed9696a852,0x000c58a6c0bc16cc}, {0x00093efb56723f03,0x000f77e4f7a67531,0x0000000000000001,0x0000000000000000}}}, + {{{0x00082edbf63cd0fa,0x000fb67ff0d41a00,0x00076aa53cf1522f,0x00099dda453dcda7}, {0x000bf634bcd8a3ac,0x000f09af12ca31a6,0x00045d3da6aee65d,0x0000b2e1c131b960}, {0x0001888166f3c7e7,0x000d21cb58f8b972,0x0000000000000001,0x0000000000000000}}, {{0x000f3e0321dcdf91,0x0009a8d4da7b1151,0x000e3a95788cafbe,0x0007071e39c010af}, {0x0004b05cb3faf8c8,0x0008a702fbafcfc0,0x000618742c775b70,0x00068aab53d65b3b}, {0x000b27ffbb84f938,0x000a7508491b708b,0x0000000000000001,0x0000000000000000}}}, + {{{0x00020328d4b15dd1,0x000274b581eaa62f,0x0008fb2a285d269e,0x0006ea89604b1779}, {0x000933aa53ad75b2,0x000fa62691d5119e,0x00067e03e002a949,0x0000629215018ba1}, {0x000ae2796195dffb,0x000282dc1f93eae4,0x0000000000000001,0x0000000000000000}}, {{0x0000977c61f7743f,0x0008f7654950f798,0x0009f0fcf77422ba,0x00070562b7dc1d4c}, {0x0008f0b2f76176b9,0x00094ad6c12de606,0x000d53dd34579508,0x0001fc63f78fe569}, {0x000a90b5214981ae,0x0005ab902dadf9f2,0x0000000000000000,0x0000000000000000}}}, + {{{0x00006fc86d7474a9,0x000491c759885f54,0x0002d4cddc55bd2a,0x00061045c35aa122}, {0x0007a2154985eb54,0x000f0dcbe4188b45,0x0006a7e235148dff,0x0006a2535a30d70c}, {0x000e2be337d8e901,0x000cf899a19ee96b,0x0000000000000001,0x0000000000000000}}, {{0x000dc1860747030f,0x000a1d519771baa1,0x000e6bf7f8dea4c9,0x000b88d5c44825c6}, {0x0001648270d80fd4,0x000d7c088d619d7b,0x000e67f50ac4887c,0x0009d1ac72f9cc2c}, {0x000dce091aafa6b8,0x000ac9b9365de8af,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=31 [{1,2,3,..,}]*([2^124]*G) */ + {{{0x000c9884018b1bd5,0x00017e335350476d,0x000f240ea34a105e,0x0007225c0ca7c1ed}, {0x0002e60ee9bcde0a,0x0001b7a04f8d5abc,0x000d636ed201196d,0x000fee08dcde421f}, {0x000648f1c3a41da5,0x00014b37a2b18a4d,0x0000000000000001,0x0000000000000000}}, {{0x000574ca3d13216a,0x00000c8f4aa46ce2,0x0005e6cb8b142b50,0x000aeecc2cc007b3}, {0x0008b139d4602d18,0x000857b6e6fad62b,0x000703a0b8035154,0x00047dfe5be4aaf5}, {0x000e255f15b88d9b,0x000ceeb42f23b0c7,0x0000000000000001,0x0000000000000000}}}, + {{{0x00027bf41035c3be,0x000003d6c228d698,0x000ac8482db53bd6,0x000f6c6cedd6d84e}, {0x00055554b59c1199,0x000b3dd0d5c80a25,0x00098fd9a255d70b,0x00088ce8ece5b616}, {0x00010e4ff0160238,0x000e8b21f2b5b409,0x0000000000000001,0x0000000000000000}}, {{0x0009be6e93956f12,0x00028be014bad7ba,0x0007941a6f1d6c8e,0x000374aa983d3be4}, {0x0001ab03efe8a93e,0x000ecc1517778750,0x000a07f3863f0102,0x00022339ade08ce1}, {0x0002e138fb118165,0x00037ded66083914,0x0000000000000000,0x0000000000000000}}}, + {{{0x000be450955d0f49,0x000350db3612b4e4,0x0008b05c6937d0f5,0x00091d0bc00589e9}, {0x000f08134602fbb3,0x00072898cb46a43b,0x0000c3f425983612,0x00092a9319d102b7}, {0x0002adb9889640c9,0x000f69984da61b9f,0x0000000000000000,0x0000000000000000}}, {{0x000925b413e1ae3e,0x00046d808d55308e,0x0001e8e95f85495a,0x0001aa328926b87f}, {0x000e6f7c0b2cf48a,0x00097c234327b453,0x000bc1b584c452ac,0x000ac04a1db1b2a7}, {0x0002c2df96a4716f,0x0008b35f6c998afc,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c246de542c405,0x00006abed2f33bb7,0x000d46decdec7b50,0x000afeed50c509c6}, {0x0007109502cf683e,0x000fa7b0916c8d21,0x000971ce284eb826,0x000b5478a9a06ef3}, {0x000dbb05d7e812b4,0x000fa9bdf3afd0be,0x0000000000000001,0x0000000000000000}}, {{0x000c0e4a6519aab5,0x000d79de9fb97617,0x0002d46f889510f0,0x00025cb75085caf9}, {0x000f963379f4c576,0x00002dc4877679ee,0x000748161e8da062,0x0007933c7094d95a}, {0x000527ab96f198e7,0x0000a23cef9bb67e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000254c4bef57a31,0x000f8fe05ebbca4c,0x000036d19011dab0,0x00092f09f97449f1}, {0x000feb784d8ec601,0x000551e5955591a4,0x00088c74b266204b,0x000fefa58c8cd4d4}, {0x000954c3d29f9c68,0x000262f04bf8acfc,0x0000000000000000,0x0000000000000000}}, {{0x0005e5c9d99f906b,0x0005ebe8f2ee55b8,0x000f127eee6b4d59,0x0005b10ba97a057a}, {0x000c7680e692309f,0x0007c47d151a8543,0x000975bcc38cb298,0x00056b40037e7ed1}, {0x00069095953732ea,0x000e079710f9d766,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007ef5561843b50,0x000725adb4b17e58,0x000223554b9e6db7,0x00040d6a298840a9}, {0x00089b9987d3e8ea,0x000c544359088f19,0x000712498c4e6798,0x0009d49555742687}, {0x000531911aeb4757,0x000c25edd6bd8c42,0x0000000000000000,0x0000000000000000}}, {{0x000da2be384ee90b,0x000ed1578452ef17,0x00026ec7e64f3506,0x000d93fd400c530b}, {0x0006442c14bcb0a9,0x000bc44330eec280,0x000b7a321d894abd,0x000383284ca21784}, {0x000aabf2cbd2fe67,0x000a0b333a314bbd,0x0000000000000001,0x0000000000000000}}}, + {{{0x000deccb4cc0fcd3,0x0002b5d6f0d87e14,0x00022447f7757c4f,0x000f03b5e4d05426}, {0x0003dcf9d56f98d5,0x0001c6d571746b68,0x000648164a40c197,0x00086a775d32054f}, {0x000bbccdf9c7e93f,0x000ab95b370c616c,0x0000000000000000,0x0000000000000000}}, {{0x000ad22f9be04193,0x00049e68cea75e3b,0x0004683245da929e,0x000316e38a93792f}, {0x000965e00dbe19e7,0x000e9c59fb61ef64,0x00094c5036fbab0d,0x0009e4c2c8f5993c}, {0x000c76d4a049b3bd,0x000c781dc2d523d7,0x0000000000000000,0x0000000000000000}}}, + {{{0x00010cba8003a62b,0x0002963dead37561,0x00024e572ee261b1,0x000924c14f710c53}, {0x0003a3234879da4d,0x0000242c6b2bb72d,0x00025965319d73bf,0x000c5d438ac356b7}, {0x000eb1ea69c1467e,0x0006ea40556d55e4,0x0000000000000000,0x0000000000000000}}, {{0x0003bb0cfbfbdc6b,0x000292f755482f11,0x000b750229b1fdd8,0x0006dd9d36eb56b3}, {0x0009fd65055f0875,0x00005fbea1ad24bc,0x000b5ba29626eb13,0x0004c9855409fcec}, {0x000000d0af627326,0x000b249d561b2281,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=32 [{1,2,3,..,}]*([2^128]*G) */ + {{{0x00097f8c2da756c3,0x00065716b51e78af,0x0004d4e4ac9bb4d7,0x000be63f12ece85a}, {0x0007f2c2556ca2a2,0x0002341b0c191c3b,0x00063796c15ecee1,0x00092e302dd7df66}, {0x000d162a4ce9cb82,0x0003dfa7f8ba9276,0x0000000000000000,0x0000000000000000}}, {{0x000403973587aa55,0x000a9956dae839d8,0x000d9da7dcbd9d38,0x000d0fffb69b8acf}, {0x000544e0adb2ad93,0x000b2ad644f74f04,0x000e7d5b5de013bb,0x000f944ef674d489}, {0x000e01d0ea2d2bd3,0x0008aedd32d1ec0a,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003c3743a6b3bf8,0x00083b2cea274d8e,0x000f6accb4a79b20,0x000ac9cff7eff159}, {0x000c5bd1a458b1a2,0x000af5afd8c30597,0x000e95f67ad0a34d,0x000ffcb5f547ad0c}, {0x0002c927ef492633,0x000118d70d201bd4,0x0000000000000000,0x0000000000000000}}, {{0x00025271d14dfd7c,0x000f83511be77473,0x000e33f2540532d9,0x0002d9c50e1e6624}, {0x000b9f8f4394e620,0x00085289919c8fa1,0x000d6412359d3b9f,0x000a4c00c9ead88e}, {0x000626daa054c125,0x000853e0db1f33bd,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ad013227cbee4,0x0005d963a674d5e9,0x0002422839e1c90e,0x0006f11c073f8abd}, {0x00051cbde443fb90,0x000f94add68e37cb,0x000d9cdf247fb6d7,0x0003b3ec024c71cd}, {0x000015c9b5032da9,0x0007607e0d83a94a,0x0000000000000000,0x0000000000000000}}, {{0x000d4287c9083b11,0x000b167379dfa59e,0x00092871f05ea23f,0x0000a530c1fbcc90}, {0x000c9b670aaadfc5,0x000840b4f012b3f9,0x0006d74574236725,0x0005827f0582ac31}, {0x00047f13870e7720,0x0006f314a9061f10,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003be466658f617,0x0009fd565e43add7,0x0004a046e438ce3b,0x0007e9edef2d69e6}, {0x0006c7f11d4e7b33,0x0009fce23db4d264,0x0007ee69cfe36cf0,0x0009d497797ff857}, {0x0000fa9f71e1b23f,0x0002d2813fdfceba,0x0000000000000001,0x0000000000000000}}, {{0x0005801d34f0db76,0x0008b9ba1d6ad8bc,0x00038f8437efa8c8,0x000755dc58d2c493}, {0x0008ea5d4147adf5,0x000454e0d19f3138,0x0005174d880f0ef2,0x0006f4ab4400ed7c}, {0x0002f97c02972f59,0x000bb7fd1f05bd42,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f26521378e02f,0x0002d730a6852468,0x000763f810a221e5,0x000f48636e9cb246}, {0x0004c1b9e4959290,0x00093bb4ca5e4a52,0x000f2a6103eedfad,0x0009e3ea2bb0a0a9}, {0x00013663d597d7ac,0x000a98c50bf00061,0x0000000000000001,0x0000000000000000}}, {{0x00050b19a3ef90bc,0x0000ea69cbaa303c,0x00074f8f2fe993d5,0x000223c8be835b07}, {0x000f455e7085ef84,0x0002207ec6b0871e,0x000e48bd79a714e6,0x000daa1613ef3b51}, {0x00098f36229d3dd8,0x000c2d9134c94bcc,0x0000000000000000,0x0000000000000000}}}, + {{{0x00050a19f5342c54,0x000dc653d78301f8,0x0006bbf10f389ca9,0x0004326e54a5af67}, {0x000fdd8a13b29709,0x0008aa3fafda8b65,0x0006c2e3f7baf8bf,0x000bca4111083f35}, {0x000cdf78842a34d7,0x0002a973106a6473,0x0000000000000001,0x0000000000000000}}, {{0x000155f05f4ec88f,0x000ffd8679f932ba,0x000e00ae69c605da,0x000b7c72ba823e0d}, {0x0009e0bbb62edf8b,0x000f7bf5bd871069,0x0004e610f36c3cf4,0x000e41a06519118f}, {0x00014868b2ff5976,0x0000f7b8d8554854,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003e5d502754293,0x000e9ee9e0f2543e,0x000a3731f423dc07,0x0003b8bc5bf91184}, {0x000726f4ea8f1d1a,0x0008035844d23059,0x000c7266e29e66af,0x00082574f0c5767c}, {0x0001a6dd0e57d5d2,0x0004e537115bccdf,0x0000000000000000,0x0000000000000000}}, {{0x0009f7ce1bfb6728,0x0000ccb130bc8170,0x00039a62c614cf63,0x00068e187476935f}, {0x00034de841f4a723,0x00011647b88ac5f1,0x000e09f54f07f6bb,0x000f505a8bf2adfb}, {0x000d75a5f605b64d,0x0000df9bbeb2b499,0x0000000000000000,0x0000000000000000}}}, + {{{0x000308733efc5f8c,0x000b75cdb37e83e5,0x00060b5bfda48081,0x0009f06138365296}, {0x0009688a8974b9f6,0x0005444cc05fb9ec,0x0005a67f252002f7,0x0009664675a1899c}, {0x000b6d7be11db7cc,0x000549e5e85617c6,0x0000000000000001,0x0000000000000000}}, {{0x0000536e04ec0d89,0x000ceb7897a84665,0x000b8acad3957bde,0x000ba89439f416b8}, {0x000cfde12e814bb4,0x000a77e0ef45c679,0x000f35bbfcd091bf,0x0009f3ea6cc5ae92}, {0x000f66583ff4f9db,0x0009a867f0fed315,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=33 [{1,2,3,..,}]*([2^132]*G) */ + {{{0x000487d30649cced,0x000796a5efc98a70,0x00086f3d00556482,0x000c177d81ed5742}, {0x000f3693c918841a,0x00044078e141f63f,0x000ad9ccb0cceba5,0x0005cd9ca803f396}, {0x000a3b9f81f2f890,0x000c5b4318691bb9,0x0000000000000001,0x0000000000000000}}, {{0x00076e3095e41a52,0x0001ffb6fd45a8f8,0x000a8a0715ef8788,0x000192a0b8d73d7d}, {0x00086ca88981c074,0x0000f41a80dc66d0,0x0002bbb8f279d460,0x000cb55640383488}, {0x00052b11c10c7a90,0x000053f89b04d855,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002e1e8d88792dc,0x00022e3ae581427b,0x00090f869db2e712,0x000e06689d393376}, {0x000702d537bfdb1c,0x0007346bbf1a9bff,0x00090f54aeeb8464,0x000273c9dd468a0e}, {0x000c871a654e3afa,0x0007465945d8c3b6,0x0000000000000000,0x0000000000000000}}, {{0x0000e770af4a5960,0x000be4ac70e87a10,0x000797d6d911c87d,0x000533fb961a5c5e}, {0x000b8548c0001c5b,0x0009d47191b560cf,0x0009eeca65c8463a,0x000ecad37d2137d3}, {0x0000514ad716bab4,0x000f8789ad5bc27b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dbc583693bf30,0x000ef8d24b6766c6,0x00095890706d31b0,0x000c51cce3a35296}, {0x00080b8ed7618c90,0x000973ebf17cff3a,0x0009c68d473b1c44,0x0001098525e43a12}, {0x00074031f5036c9f,0x0001d33955ea92c3,0x0000000000000001,0x0000000000000000}}, {{0x0006f1c314ce3a37,0x000a4064ddf24cf4,0x00070db52569e1fd,0x000405305ea2c55e}, {0x000d5f14297acf89,0x00046ea96e034f59,0x000622a42888331a,0x000a102ad1347dc4}, {0x00088a514e007741,0x0000461db8ec7cfe,0x0000000000000000,0x0000000000000000}}}, + {{{0x00023847d8cf0718,0x00021ccb2c301d0f,0x00024b1883c46a31,0x00063cce64fb5faa}, {0x0003cc10bc090432,0x000510506a731fce,0x0009a05134986c0e,0x0003aa30a907d289}, {0x00071f165d859243,0x000eeaa5074a4066,0x0000000000000000,0x0000000000000000}}, {{0x000b1d8c9f3b369e,0x0008874f03f7bd39,0x0004a870054ed9a2,0x000756adbd121753}, {0x0001a9a0d0a37510,0x000529605385faa5,0x000c2eddf5c089f3,0x000a130a237e15a5}, {0x00074ff2cbd316fb,0x0007ee2c9d3ce137,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009dbdc68f3280d,0x000657e090c25dbe,0x00024c6421981e70,0x00037a5a5d0a99ac}, {0x00037fc8c760c5df,0x00044d1a53e37845,0x000ff43dddfe06f5,0x000e4ab44983d93f}, {0x000c0915a82bb80c,0x000646c74033c3a1,0x0000000000000000,0x0000000000000000}}, {{0x00004b5d5c7ce211,0x0001372b933ba5de,0x000ea64d116a103a,0x0006df2d3d823414}, {0x000619b7a1bf8333,0x0006eac1655d2034,0x0009aeedd521f9b1,0x0006d98d98725948}, {0x000610e8ae934636,0x000efd7b215cbea4,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005d0308e1127f5,0x000cf03c8e2019c4,0x000aa0237cf6545f,0x000764372510cd18}, {0x00097139d47739de,0x000a85188927140f,0x00037dc9b8b5e192,0x000b2545731c10b5}, {0x000991ea59d03831,0x00067dea66743632,0x0000000000000001,0x0000000000000000}}, {{0x000cc6866cf98c39,0x0009016f3fd54524,0x000592bcebafd818,0x0002f06cc34bdbb8}, {0x000b6cb2e7a209f5,0x0005749dab7ee649,0x00076406958e2abb,0x0009516d049dfaf2}, {0x000de5f7e8adfc4b,0x0007ce97062d4c5e,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007da121df0699c,0x000ad3597a95de87,0x000181d213d52a92,0x00002da71c92de4d}, {0x000dd3803396793e,0x000c8761f332f0e0,0x0005c1e0d83b70eb,0x00048cf70527f5a7}, {0x000ceb82fe3e31cf,0x00029a56f1047f6a,0x0000000000000001,0x0000000000000000}}, {{0x000ae721531eb7f3,0x000c70c79169f267,0x000d345b58d29bb0,0x0006c1daec3533a3}, {0x000115913b369665,0x00099820ca585f3e,0x000623473863b5d7,0x0003e2b952a9549d}, {0x00011f22279d7812,0x0007e6cad8cfd481,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c384b610f9960,0x0009e42d4100e245,0x000c5264e577187b,0x0000ec202477a817}, {0x0009dc146fbb4cb2,0x000c49fc51a5dd07,0x000dd34b66b540f6,0x000418cb3114a207}, {0x000042a4afc85f36,0x000592a886f4d479,0x0000000000000000,0x0000000000000000}}, {{0x00062b5959d642be,0x000c107df28ef33c,0x000c98bc18d09a83,0x000908cb61720266}, {0x00034bfa40c64e8b,0x0005f7d00d3266ed,0x0006699785d5c5ac,0x00070fda50cded6e}, {0x000a7129a0528d63,0x000df6226a01349f,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=34 [{1,2,3,..,}]*([2^136]*G) */ + {{{0x0004a83b5020b6b5,0x00064ea6b7250085,0x000f5cc5dee82b8a,0x0007e307a44f4310}, {0x00061a979f99982f,0x0006271c95260383,0x00087bd9d4a6e7e3,0x000183121a682c2e}, {0x000a0c42c801461a,0x0009efc46dd1bbdd,0x0000000000000001,0x0000000000000000}}, {{0x000ff9d53c8adce8,0x0004cbac7e6d6ff5,0x0008a2a18c9ba604,0x000457234e0b1c61}, {0x0001b538c1881476,0x000d20849fff1d07,0x000e3333d9430380,0x0001d1326f05033a}, {0x0004a49c4e89c642,0x000e640c63716450,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a7c6657e0c514,0x00010e4ba5060489,0x00003183bcaf92c4,0x00051063325bb838}, {0x000624a227afade7,0x000d611fad61ce2f,0x0001f27e1c057fe8,0x000426a808156374}, {0x00051e188cc3f494,0x000e601fb19202dc,0x0000000000000001,0x0000000000000000}}, {{0x000f5c4ba35ecd6e,0x000c838b90f28423,0x000ecc8f9f7eac00,0x0004ae3bc63ca5b1}, {0x0000a61f4eb49abd,0x000e5e94c7586825,0x00050828aa62e59d,0x000ca27ce17d2e20}, {0x000f7dcd24d94b7e,0x0004ed84ff72ff3c,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dae22413fe9d4,0x000881c93ceb2c9e,0x000376b68f1c40b8,0x0004d107493ec443}, {0x000de2613f0552fe,0x000264177a2adbc0,0x00044456850f4d4c,0x000c024b1759999b}, {0x00032c490b5528e8,0x0004e4fe9cb25fa5,0x0000000000000001,0x0000000000000000}}, {{0x0002401de7dabddf,0x00056529f2c840ea,0x0006004e218ae4f0,0x00026d7d9745c833}, {0x000bc1aa8e8c745a,0x000254366c2e1e3a,0x0009a65d176c592f,0x000575f2ce2f5dba}, {0x000390121cb70eda,0x000ad4df3bd7c9ef,0x0000000000000001,0x0000000000000000}}}, + {{{0x00052f406338228b,0x00000044f05c5be3,0x0003a7061d336069,0x000371f2e7fd3e15}, {0x000ddb123a32ed82,0x000a15e8eec0c29b,0x00046b80938b2d11,0x000ba2ae38c19bba}, {0x0000c4e7466a69b9,0x000ba8e7a0607a47,0x0000000000000001,0x0000000000000000}}, {{0x000e250e34d513c2,0x0009900d3d611604,0x0002850e69a99aa8,0x000ea018e87aacf0}, {0x0008ea9b70f5d0f5,0x0009dfec50e62995,0x000ef7267ad0ad8c,0x0009fbbc4dd8a19f}, {0x000ef73af4e91334,0x000d0636506a6e44,0x0000000000000000,0x0000000000000000}}}, + {{{0x000533f2ba0eb14a,0x000b9fc6b2073504,0x00059889c71f37ca,0x000d3e3b2957243a}, {0x00033cd4ef031ee6,0x000e1fa792c82e2f,0x000936a9431aaa2b,0x00075897dee2d5df}, {0x0005c1a2769038db,0x0004c149337ba93c,0x0000000000000000,0x0000000000000000}}, {{0x000ff077c9595fa2,0x000b4e92632965da,0x00073090129d489d,0x00024c2f940397cb}, {0x0000f08747c463ab,0x000063f57ea7844d,0x000a687de4ab15b4,0x000d7bdc8db9dfb6}, {0x0000393c5c4b7272,0x0002b3cc129fac67,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d85352986f86b,0x000b3bb5e1a9d134,0x00096ed674c04b6f,0x0001eaebc5869197}, {0x0001ec13b24f0220,0x0005acb88043fe14,0x0006b2f77717702d,0x0001f913c28eb4c3}, {0x0008bc0cbbd9e8fe,0x000014871dc376bb,0x0000000000000000,0x0000000000000000}}, {{0x000b182392919d22,0x0005619062a004b3,0x00084b9c0aa0d96f,0x000e6a14d38134a4}, {0x000b962e9b9dd384,0x000d2a3f87434945,0x000e17c26111d5b0,0x000cca088afb0558}, {0x0004109b67e83601,0x000ebef3372d865f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c5a0356b17ac7,0x000f616fb80668c9,0x000f7001431d3037,0x0006786061783bd7}, {0x000e2a8db044a7eb,0x000d63e80e687c5b,0x0006dba72619e19b,0x000b3f54433d79bd}, {0x000179eabd3da5ab,0x000fcebeded88553,0x0000000000000001,0x0000000000000000}}, {{0x0001156c4d223604,0x0006fa0e48c3398c,0x000d70c895f6a870,0x0000aa32def1e5d8}, {0x000a3628036e774e,0x0006fa3b42b31a93,0x0003f15e7bb3f2aa,0x000fd667e0a491ab}, {0x0002f04b61d5276e,0x0001fdac2e330e17,0x0000000000000001,0x0000000000000000}}}, + {{{0x000760d231c36820,0x0008bd2a50426c8d,0x000d4451d722fd74,0x0001877484a5084a}, {0x00019395bd1ac7d5,0x000dc03d6541ad77,0x00068a254b40eaa5,0x000dc699a962f42c}, {0x000f2ecdd481b2b4,0x000345d9badbf178,0x0000000000000000,0x0000000000000000}}, {{0x00090c94035684fe,0x000e517a9849bb68,0x0005822be91e8615,0x00067ca7e3c3e516}, {0x0004c5ebee67a9ed,0x000f03236f5438f4,0x000029ef9e45ec0b,0x0003412d001129c5}, {0x000bad0b64fd4f4e,0x0000e15f591e3c09,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=35 [{1,2,3,..,}]*([2^140]*G) */ + {{{0x00067ca62dd9afd4,0x000678b2e8cc8368,0x000d7d6c96a2abfd,0x00075f62bb6c702c}, {0x000988eb9ab34b7b,0x0007b382272a8eb6,0x0005e40ee1d17286,0x000b6f600751bff1}, {0x000ff996b4ec3001,0x00015d7fb8efdf30,0x0000000000000000,0x0000000000000000}}, {{0x00062d76a29a2746,0x000f091c80dd81fc,0x000c1a9825d4a2f2,0x000a4fb54ae9b61a}, {0x000db71a812fcb05,0x000bb96eaaa7baf2,0x000dfd9cc434e4e8,0x000b8fce567253c2}, {0x000b948eeceeb8e7,0x000abac787b7e9d6,0x0000000000000001,0x0000000000000000}}}, + {{{0x000566d2087a8f7e,0x000f8d816dab3c44,0x00068ad0a5ea555e,0x000ab76093fa3eae}, {0x000bcad51a41fb45,0x000c784a1114a732,0x0002d99cd96f3573,0x000f7808bc957e91}, {0x00022a461547dff3,0x000e9dd3f93d98d0,0x0000000000000001,0x0000000000000000}}, {{0x000f5792b3bed20d,0x0003199e50e443dc,0x000ab35921f1c5d0,0x000cb763ce7e3777}, {0x0009ec69a2c8061a,0x0004921d8bd5a1f1,0x000d3f186d49b86d,0x0003d287849a3eff}, {0x00019a1d3969ee2c,0x00097e7987e8d923,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e6b3554a3f3c4,0x000c8b48d7c64666,0x0004319bb26494ce,0x00023bd53c15f132}, {0x000a4b25b7340a49,0x0002c82187e36296,0x00076cb62a70b23d,0x00013ce0a44b3a26}, {0x000e1376215ada95,0x0004bdcdd5bfa093,0x0000000000000000,0x0000000000000000}}, {{0x0006f0577c34a522,0x0002d6eb1d23f2e1,0x00074b1ae5a563bc,0x00076c1922ce417d}, {0x0008d8b56e586f06,0x0003d2111864665c,0x0007a1f4a9d1f08d,0x00009ad18a2eb5b5}, {0x000f16f69121b144,0x00055ad3dba51f31,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a0990f6c14c34,0x0002ae1571f4bd14,0x000a7e981428a12a,0x0008a57064ea4bd5}, {0x0005ec2f56d89f54,0x0004fcfb513a99f0,0x00081deb029c28b2,0x000c16eb364a4688}, {0x000f6df6754a22d8,0x00039a8e7ba7c29d,0x0000000000000001,0x0000000000000000}}, {{0x000585b840875f9d,0x0006688b87eab66d,0x00061b8a4aef8f2e,0x000968d01b210ab1}, {0x0007a38c32d9fcd5,0x000170203f9469f2,0x00027ba7e65bf262,0x0003268e8f3ddf53}, {0x000d5d6a50d743f2,0x0006f76866dcf3bb,0x0000000000000001,0x0000000000000000}}}, + {{{0x00075ceb39ee406f,0x000fddc2dbf93cfe,0x00005aa3d0f7d044,0x000c04043459ab15}, {0x000bfbea051fd1e4,0x0005c86723eeca2c,0x000dd90428637a5a,0x0006d3aca9d581d9}, {0x000277709f646127,0x000d9e5fdc588878,0x0000000000000000,0x0000000000000000}}, {{0x0005fdeadee7c5a7,0x000b59b799ae3c10,0x0005e3595acc919d,0x000b6f6b2aa1f7f7}, {0x000cc519dab324e9,0x00070aa0c81054ee,0x0006840dab1fa02d,0x000ce8162c464504}, {0x0007fc117382d8fa,0x00079cc63a2e343f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f45643ca65cbd,0x0007305e42072e40,0x0006980bc47b22b4,0x00091f480c0959ae}, {0x000df17382117d00,0x000fb6755fe76ce6,0x0008195083b13716,0x00053ce928778e33}, {0x000eadd235784446,0x0005f288650fd122,0x0000000000000001,0x0000000000000000}}, {{0x00032d4f966b7e9c,0x0006ec40795011b8,0x00056106a162f5eb,0x00060472439d72fa}, {0x000ed9a6959807a3,0x000d3315f177c4b5,0x000b196cd83808fb,0x000c21f3f41dc773}, {0x000518607dcca40d,0x000920d975bf1042,0x0000000000000000,0x0000000000000000}}}, + {{{0x00043d0a4a0b7f26,0x000c9bca61488d76,0x00078d40864c9a4e,0x0009191208ac32aa}, {0x00065e2c33dbbd1f,0x0006b041d84ce172,0x00022f6c73e5e84a,0x0000caf07f551302}, {0x000e0bc76bc20bdd,0x000a43482195b22f,0x0000000000000000,0x0000000000000000}}, {{0x000f04c8745c6a12,0x0002b2bdd6ee1437,0x000b9431fd260182,0x000e54b7f10879b1}, {0x000a6b8d5c027ebe,0x0002358509530c61,0x00071ee3b953e075,0x0001d055e247c05d}, {0x000f78c21fc120f3,0x000c40b71a77f551,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ca1655dd01fc4,0x00023cfcdcd83fdc,0x0006fe01dad6f137,0x000a92f448fc724e}, {0x00071e9506b3510e,0x0002c50316bacd31,0x000812e5b9c38263,0x0005b06a2041b525}, {0x000d1e51d6095bd3,0x00018f8c9f2aff29,0x0000000000000000,0x0000000000000000}}, {{0x000e8440d9f6b1c5,0x000d8f5815a76ff5,0x0000ba6e7eb4652d,0x0000cfa7a2d772d1}, {0x000e12c2c10a367d,0x000122408a9134fb,0x0006be74d3fc999e,0x0007f158ed729839}, {0x000445a86f173644,0x0008103589b3e72e,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=36 [{1,2,3,..,}]*([2^144]*G) */ + {{{0x00002ef5664a50e9,0x000569e6626b5584,0x000bb9dc4c85c34e,0x0006cac4009d6dab}, {0x00047cf68656c674,0x000e65ab973336b9,0x000ecf3e266a898f,0x000b5830a2ee0371}, {0x0007109821d57e75,0x0002643e097669c9,0x0000000000000001,0x0000000000000000}}, {{0x000e2ad77fec8187,0x0001deddfb754e78,0x0004aaa3d5328431,0x000f5938ac9d56ca}, {0x0000419e9ec29fe5,0x00089e92d324185a,0x00068c4746f628de,0x00086959a461fd09}, {0x00039e1752cc1b19,0x000f685c4efa867f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000578941d3daa6e,0x0001e81a86314a15,0x000e2ec49066a742,0x00085f37e975bc97}, {0x000abd59fd20aa74,0x000b001318e5e712,0x000bdca951133a15,0x0006057f57ee1259}, {0x000dad04acbd3b2c,0x0009e7ef3153ef33,0x0000000000000001,0x0000000000000000}}, {{0x000d37d508c6263d,0x000d87a4e81e7b2e,0x0005a01a3eff8f36,0x000726730288c3e4}, {0x0009b846f52088b3,0x000f560651a99118,0x000aeef71db52e56,0x000e58e36c06431c}, {0x000d03f83a3f98d5,0x000adc020099b8d8,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d0b7b6a8a3320,0x0007c1820c541666,0x000008d89959635c,0x0006f6b2d261e2b0}, {0x000b20857dc9286c,0x0008490da31aca2d,0x00001835ecf8b430,0x000769b376d5c408}, {0x0006c3593326d702,0x000ae359276d5c27,0x0000000000000000,0x0000000000000000}}, {{0x000052b955ccca9f,0x000132f8bdb8b0e1,0x0001fc788aac66dc,0x0007aff377f81134}, {0x0005f3f5c42cf8fe,0x00063a0cd5ec56c8,0x00044e19f92551b9,0x0005a03e4e9df2c1}, {0x0005981a18a9c38e,0x00038410aaa01483,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ab1b79d73f8b8,0x0002c67e2040bd52,0x00089ab066095a12,0x00020058f1cb78af}, {0x00035c77cb75101a,0x000e13361531375e,0x00075eaea159ba65,0x000a7ecbfca3524c}, {0x00019d039ab8ae0f,0x00099c623ac91c57,0x0000000000000001,0x0000000000000000}}, {{0x0001430a249d36df,0x000efe8450eb5d6b,0x000afb92b30c47b9,0x00024beea9991147}, {0x00039e1752c3ff68,0x000fd6a6252b160b,0x00046e76256f4b47,0x0009076f7bff5746}, {0x0003f350ce5bbdfa,0x000da84642b5dbcc,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f59f034423df4,0x0000c74c6502a253,0x00051f6b04936dd5,0x000ac1dfa20fd420}, {0x000a26ee480942df,0x000b8f32c2aa1793,0x0008f9fd5819aba5,0x000593ae9a68c3be}, {0x000809f95c514dfc,0x0005832a0100c51d,0x0000000000000000,0x0000000000000000}}, {{0x00084df91d0b9d7b,0x00019af96dda8b28,0x0009e06515fe82b7,0x0004e7882cd87d52}, {0x000d3f4a8cd84bcd,0x0005a839e5e4c173,0x000eace8b4e2b402,0x00009c378fed4c2c}, {0x000b8a183c245522,0x00026032daca8b53,0x0000000000000001,0x0000000000000000}}}, + {{{0x00021d74b7f15174,0x000b1737719209fa,0x00000c8bba28cfe5,0x0000523f1c2878b2}, {0x000c0170331c9a62,0x000cd83b50a5843a,0x000131d0381135b8,0x0003a643b75eb047}, {0x000ef1464d2ab54c,0x0007f362ed0e42c5,0x0000000000000000,0x0000000000000000}}, {{0x000bb20fbad15614,0x00040a78f8613291,0x000895f7e0d7805c,0x0004b54ca2a8624a}, {0x0000e6579a8713ce,0x000626e2cc1b0cde,0x00093c66377df41d,0x0009cd6454de0451}, {0x00009db1f1c3ca34,0x000d91b047b0a149,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006148c3607c309,0x00072dd5c6a1cd15,0x0004ea2e6d51f4ab,0x000bb9012a38398f}, {0x00025cc1f09df84a,0x0009c3bace064bf4,0x000f3b1a1aeaac49,0x0008ba0e470586b9}, {0x00026aca2a7b1cc0,0x00037064de7e58e0,0x0000000000000001,0x0000000000000000}}, {{0x000f70f6864c071b,0x000cebbcde808997,0x00042d9268c9d10f,0x0001f3646bf97f61}, {0x00099c6124289f61,0x000f65308f5fa877,0x0003b1cbe10f2164,0x000db1cfb717f6c1}, {0x0002178fd0705446,0x00053784aa2a3cca,0x0000000000000000,0x0000000000000000}}}, + {{{0x00032b93eb6bf0f8,0x0008d44a6f35d7f4,0x00062f74f5a61124,0x0008d968ff45509d}, {0x00090f78b11dcef9,0x000e0fdb4e540d2d,0x000178df19486918,0x000b775c9c48f839}, {0x000a4516e1546952,0x000548b05a9a422d,0x0000000000000001,0x0000000000000000}}, {{0x0000e6542e705240,0x000ea85c40801a5a,0x0008cf4381fc9bfc,0x00026551ecff5ed1}, {0x00006e3765708042,0x000f10bb393addaf,0x0004c0be6d6327db,0x000ade98dcbda7a9}, {0x00045d1d2c9cc265,0x0001d23919800694,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=37 [{1,2,3,..,}]*([2^148]*G) */ + {{{0x000136d3adf7c0d8,0x000a615150ed1e22,0x00048b602d1f12f4,0x000a438f58c86ca8}, {0x0006c2ad94dbc8f3,0x0001741520fd2861,0x0006926fc8f344fa,0x000aa2867b7697e9}, {0x00063769f3f74f49,0x0003389eafe4ecc9,0x0000000000000000,0x0000000000000000}}, {{0x0003271ab880c04c,0x0007eceb904c8b8d,0x000cf0e8b6b36124,0x000b8dfe9dc846a9}, {0x000c71bd5a3dcf58,0x000bb872ef46766e,0x000ea257028f76aa,0x00037d56cad75976}, {0x000e6e410a7a4c1e,0x000aa4d9ef6dff50,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003f21a068b1990,0x00028b83926d837e,0x00046424f5058ff9,0x000540b150a21088}, {0x0007bd69839e2656,0x000836bb43217215,0x0008f5d34535e3bc,0x000a61ec6b271f81}, {0x00014bd57f4cd40a,0x0009c8fdb8302a87,0x0000000000000000,0x0000000000000000}}, {{0x0006b22f2553a3a3,0x0003b58b7033af0a,0x000213a07cddbf4f,0x000434d1d71e271e}, {0x0003ac069f3affa9,0x0004ccd448d5d23e,0x0005a3de785990cc,0x0009500536e9dd21}, {0x0005a1f484316890,0x0008d39f92d8e2e4,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e463b75bb6ea5,0x000ed0a11789a549,0x000dd32eea4152e4,0x000b779f3244c612}, {0x000a765d467497f7,0x0001f2317d762ed2,0x000fb479fdc0f1f6,0x0005b625c778a26f}, {0x00086e4279e293c7,0x000778007cc51b6a,0x0000000000000000,0x0000000000000000}}, {{0x0008d10c9ca3a103,0x000303626747aa01,0x0009d0d1059a4b9c,0x00047b992888178d}, {0x0005dee73f8df999,0x0003009b79f58ee6,0x00095bbb19efb6cd,0x000ee364f704fdad}, {0x00075210ba101581,0x0009e1f5ffb0008b,0x0000000000000000,0x0000000000000000}}}, + {{{0x00061dbbf0d6ad65,0x00037943121ba6f6,0x000176edfca2325e,0x00061e28f0cef68c}, {0x00084617ac6eda38,0x0007535e8ca77e7f,0x00023d1d31f498d5,0x0000546d78b2f36e}, {0x000c7d55e2c3f881,0x000891156a1cb9cf,0x0000000000000000,0x0000000000000000}}, {{0x0004ce76bf8c0b46,0x000f73894a4c0a97,0x000e4d65f8fc178a,0x000cb9405d4f42d7}, {0x00089f73dac29f71,0x00028141921d35c6,0x00055dee3cb66f43,0x0003af9effca7532}, {0x0004e3d9ea981425,0x00042022e23b71d3,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d0b7e99b465d6,0x000dcdbbc6a7f631,0x000fdb4862b8d0eb,0x0002d00e72a3f599}, {0x0003fff9e95d96f0,0x00098b66f4cdbc62,0x000ac921634cb2b5,0x000ec0deea0b5c81}, {0x0005b0a27a76f063,0x0001e02d30431834,0x0000000000000000,0x0000000000000000}}, {{0x000c98aa1c9ac7a1,0x0007c5a7466568e8,0x000fb66755607c49,0x000ef99d83842e7b}, {0x0003f63d03b04212,0x000eea39bde1d43a,0x000c0a3d0947a656,0x000da642406f1e3f}, {0x000c396f50ca4ece,0x00002261add500ea,0x0000000000000000,0x0000000000000000}}}, + {{{0x000faccc08dd24e3,0x0002a75b2039c36b,0x0007b00e10c370cd,0x000decd44a6f8b5d}, {0x0005623fd6ab9f44,0x00019a1ddd85e65f,0x0007f5f2f27bfaa2,0x000934e1d6c8baa2}, {0x0002398cf5bc3e40,0x000936e76ebca08a,0x0000000000000001,0x0000000000000000}}, {{0x000b72cc3defb1bf,0x0007c48e0f8a00ef,0x000b50a281abffca,0x000290112a957074}, {0x000c6cc0bcd2913c,0x00080828c73f9cbe,0x0002b7332c142bad,0x000b82fd75dcc17d}, {0x00071d9dc563b115,0x000fa46eb1fc833d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000293af2196db74,0x000aa8f516dffa78,0x000ab476917c3f2d,0x000a17a44ba1c0ca}, {0x000771d0d213b4e6,0x000872d37a8c50d3,0x000a9d4f31d594dc,0x00020ae17df8f34d}, {0x00012ccecab30c4d,0x000fa5e5b7722b87,0x0000000000000000,0x0000000000000000}}, {{0x000e6e4b1df4a900,0x0005d66c421f23c8,0x000473d466e42335,0x000dad17c61ddae2}, {0x000ed279fa7168cb,0x000addca2ea2657f,0x0004d479a5bdfda6,0x0009ec1a80eb84e8}, {0x0001a95ca1a89847,0x000f2ca605fdb8f2,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000bda5161e9684,0x00055c62c59939aa,0x0001e39fae89d4f2,0x00072aef74c49bbe}, {0x00060180fc9e6093,0x00063da12ade7248,0x00028defa823f501,0x000a965a30e8a72a}, {0x0005cf1083c600ec,0x0004af9f8b968790,0x0000000000000001,0x0000000000000000}}, {{0x000afd7d7d936a7a,0x00003b13810cfd26,0x00037d1ddbf986aa,0x0005d035eede05c2}, {0x00071b7ae0b88271,0x000812487895ef9e,0x000f170e50423460,0x00003054f1639f87}, {0x0002e674eebc0936,0x000654593b42f2ce,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=38 [{1,2,3,..,}]*([2^152]*G) */ + {{{0x000a2f3a1cbc282c,0x000e19a09feeb1c6,0x000c54628c6180b5,0x000cefbae8c61be2}, {0x00031054eeedc773,0x000005e41190648d,0x0004925364893510,0x000a54e9064644b7}, {0x00026639e573a22c,0x0003b5a6074dacd6,0x0000000000000001,0x0000000000000000}}, {{0x0002e1f28cb4398c,0x000fba11161ac99e,0x000aaf012b04f328,0x00060a6cb74a91c1}, {0x000690cf3c48dadb,0x0007c4e07d1b8182,0x000bed19eb0dacbf,0x0001aba090482e6f}, {0x000b8c6fb9ea1ef8,0x000d6d4b567809aa,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006de757b8ee9dd,0x0004f4a9eb572b8b,0x000650813f9e5a92,0x000081024cddfbbc}, {0x0003e750529ae0f8,0x000c407a678dbdc2,0x0005c643db36c6df,0x0009adee9ab1549e}, {0x000add1f855d46bd,0x000aedf68182d8ac,0x0000000000000001,0x0000000000000000}}, {{0x000e2fb66eef3f12,0x00004b24a7282866,0x00050b3c877e75f1,0x000590fae38bb301}, {0x00008b7b5535d2f8,0x0001b50eaef87c62,0x0000c4541ba355de,0x00098bfe96023f0d}, {0x000dcf2eadc15969,0x000f41ab8c033f3c,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001bfbe835763b7,0x000da08736745919,0x000d000c52158859,0x000dbafd4373d9cc}, {0x0003efeee235e560,0x000fe980f98d303a,0x0004f012a6082ad1,0x000e567ed43eb524}, {0x000eddca68306748,0x000f954e531e38a7,0x0000000000000000,0x0000000000000000}}, {{0x0000101b465ee778,0x000f8f4e95956310,0x000bcb6c6057ab1d,0x00052b140218cd6f}, {0x0000a217b7b093a1,0x000924c99c9b3267,0x0000b388550cfd67,0x000eda396f8cf9af}, {0x00035154327557bf,0x00098cf74a0d9f01,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cd9335dea0190,0x00015fcbf855836a,0x0007808f96352fb5,0x0005c5cb374fc6d2}, {0x0001eebbbb50f586,0x0007f3a5b9a4d0c8,0x000bc6329ed702e4,0x000264f0fada97b4}, {0x0005e3bbcf73be9b,0x000dd442f9f14de6,0x0000000000000000,0x0000000000000000}}, {{0x00029cdbcd6414f5,0x000db247ce590b47,0x0005be836ddf363c,0x00032e4b6a8da968}, {0x000c049bdb9815fd,0x000d8f7528076e41,0x000d50b097db4cb8,0x0007f829470b7fc1}, {0x000b6caef75b1cc6,0x000ed3d55324b1d2,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002ed4b0886efde,0x0002e69216f70caa,0x000a19fc084c43fa,0x000bf1fcd447360e}, {0x00088b44bef17255,0x000c941e542e92c6,0x000c9462ab05687b,0x000f4a55ed27b06d}, {0x00006c4879438508,0x000b3f5a16cdbf59,0x0000000000000001,0x0000000000000000}}, {{0x00090da308f335bb,0x0002c62f75607156,0x000ac3878c204f5d,0x00019a70e1d9ebee}, {0x00065ce18d8dd345,0x00053d4a7a6a59b3,0x000ab840d7a66249,0x000e9f8efc3edfda}, {0x0006a32d022f5317,0x00072a29be1120dd,0x0000000000000001,0x0000000000000000}}}, + {{{0x000bdbfdee3c7792,0x000b747684a7e37c,0x0006fd64e032b7ae,0x00031287b0371790}, {0x0003245ed96aa7b2,0x000bcb2d9689dd51,0x0009eceb1d9918cd,0x00053e6e8dbeb445}, {0x0003cd8435c2226c,0x000a212888b11938,0x0000000000000000,0x0000000000000000}}, {{0x0001020457ce98be,0x0009fbe80ddb3555,0x000e385ff7a0d009,0x000821584b1de3c2}, {0x000f36cd64d47bdf,0x000d2c6d2f0d97c5,0x000126f061319f64,0x00050f118e4e9aeb}, {0x000dd0fd66a1918b,0x0008c9bb60247ff9,0x0000000000000000,0x0000000000000000}}}, + {{{0x00006452a69b40ef,0x000a58916404d8d3,0x000489351fe54188,0x00083228fc171eb7}, {0x000410e07508f15f,0x000b2d0bdc317f64,0x00075755181b0c85,0x000c4ca35cc09ad3}, {0x000bdec4e4688b7b,0x000ec2f6e18ec10c,0x0000000000000000,0x0000000000000000}}, {{0x0000b91ff7109c43,0x0001353357108dc1,0x0006db397b6c17eb,0x00038d3f418ed53c}, {0x000a1a7d0d6f5104,0x000558963fe8aa2f,0x000629ed52f70d0f,0x00070987dde60b3f}, {0x000b95a72bb4ccee,0x000aae64e168b593,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009ff50fcb47b0c,0x000001fc1e2456f6,0x0001c124be702b84,0x0007f671a6c9b545}, {0x0000e07337c72285,0x000d3661d0b0a89f,0x0007db2af0223087,0x0001d9b173b261f1}, {0x000c65404d0457b5,0x00086eefc1cd30f8,0x0000000000000001,0x0000000000000000}}, {{0x000fafb34fbb3972,0x000db4c5bd6770ff,0x0000de59815fc7a7,0x000b5602342e8ca8}, {0x000220e1c9e4f843,0x000b0b7c5b3bfe91,0x000b313a1e2826c8,0x000988ce465ce442}, {0x000217ce5f2ef9e9,0x000682a10ff59077,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=39 [{1,2,3,..,}]*([2^156]*G) */ + {{{0x00041390c3361b6e,0x000b58054f802294,0x0009b74e1597143a,0x000652a48a901ba0}, {0x0004b9b4f3635116,0x0005e2ee300afb31,0x00079f7d46228864,0x0001b66e61674d2f}, {0x00005aad2298ff3c,0x000bd327d6400925,0x0000000000000001,0x0000000000000000}}, {{0x000b20dd543f093d,0x000dac4b51c2ba0e,0x000bf1d364874c9c,0x0002601310d4063e}, {0x000c6c8c6fbaa6b7,0x000ce6639ff8b94a,0x000066c91f488ec6,0x000524c600b8f454}, {0x000ff656ef37706e,0x0008a0434286c21c,0x0000000000000001,0x0000000000000000}}}, + {{{0x00077e284b1fd44f,0x0001dc37f60445d8,0x00069f0b4dfca419,0x000aa285358c7759}, {0x0003172cf55e112a,0x000ffea4f47f71ae,0x000412afc352eb30,0x000bc7ffc3d95b8d}, {0x0009ccbacabdbf74,0x00030dd4b6acd123,0x0000000000000001,0x0000000000000000}}, {{0x000870d6326f819d,0x0001f9d1598751a6,0x000c925f0b6c6b0d,0x000c309ba890fd44}, {0x000f1cedd20fe106,0x000408588dc46673,0x00053cbebfbcf6f2,0x000da52fed53b541}, {0x0002bbf3f7b4aace,0x0008d484a22a2167,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d633fc6b2523f,0x0003c8573eaf11ae,0x0005f254d2bc0511,0x0001c7fd283764aa}, {0x000f770135776ee7,0x0003df5ba988759f,0x00065da842051883,0x000b809c0705d522}, {0x0001067f4912507f,0x000fb628d91a9464,0x0000000000000000,0x0000000000000000}}, {{0x000e6e2ac33e3aac,0x00065c0000ebfac5,0x000ced796bda6c05,0x000a32836c90c0d4}, {0x000d2ee187fc8100,0x000d7848e982bcb3,0x000be08290e6b628,0x00085ab586db4a59}, {0x000b07e2fb9a0080,0x000d56210d8de2f4,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000ac7a2fd05258,0x00034c744e57f4bf,0x0002edb448a88343,0x0004d56a4c1f9523}, {0x0003b85d4cde6c8e,0x0003063d710bd23e,0x000833d45b52f378,0x000d2012d08a14ca}, {0x000ccbe55ff85aae,0x000e919fa9b95c02,0x0000000000000001,0x0000000000000000}}, {{0x000999b76646e255,0x0001f5f355b09a04,0x00000d64b669309a,0x00089605b2bd55ad}, {0x000656b121bac578,0x000d693b7220d91b,0x00053ea1faab888e,0x000745d07a303444}, {0x000e7a52e75e36d6,0x000a7986433618f7,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002484fcef15b60,0x000485fc2dc91c4b,0x000d7e9f8403b5be,0x0005ec8542217cb5}, {0x0003f3deede9d858,0x0008c56ddda1f005,0x0009028845902ce4,0x000cdbb111feb2e9}, {0x000537c2b8f6659b,0x00075d89960f5bf1,0x0000000000000000,0x0000000000000000}}, {{0x000a9e85b9799e89,0x0001de39c6986f88,0x0000fa555ee69af1,0x000f3b270c555b9d}, {0x0004c62266b30411,0x00084a11940b0e86,0x0005b26112da8247,0x000fc56950bfb7ec}, {0x00066d81f8a57ba0,0x0003b772e0aa0038,0x0000000000000000,0x0000000000000000}}}, + {{{0x000710f55ddf9e13,0x00018f67ff0e8dc1,0x000601481b67ef67,0x00009ffab39b462d}, {0x000b5ad90ba1057d,0x00018d94f2f83bbb,0x0008d2eed4c7a169,0x00019ddb61a12bee}, {0x00096ab74dadd029,0x0003902e5753e9de,0x0000000000000001,0x0000000000000000}}, {{0x000926dcd7de034d,0x000eab5af3e375a3,0x000eb250dce827a6,0x00008bd108623cdc}, {0x000d49a7d0e9c524,0x00066e3019236fda,0x00040ab55ed033af,0x000667077bc755cf}, {0x0006972e633b49be,0x00095334396ea43d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000671c0c20009e5,0x000956db94fffef7,0x000bca8fdc30361d,0x000ebfa5860aa7a6}, {0x000feca2b724bff4,0x000572f34fd506fb,0x00048ff2e88a7d1e,0x000874822e19430c}, {0x0003c0129eb20b17,0x0003db07cc6f0162,0x0000000000000000,0x0000000000000000}}, {{0x000244f5da60b490,0x000fbd8954a885e9,0x000f39699542bf3b,0x000c93a6a7e331fd}, {0x0009816b29c5180d,0x000ad960c8e85d80,0x0003a3a7931b35df,0x00092e570f2974ab}, {0x000904daaf442234,0x000cf25e1f700754,0x0000000000000000,0x0000000000000000}}}, + {{{0x00056e1b7ae8ee13,0x0009b65f8128c4ea,0x000e5e0d92d02840,0x00074f688ed0e1c4}, {0x000f9c55f66d6f3b,0x000eb2ab8035d3f9,0x0006b643bde4296d,0x000f25e29f7ea7cb}, {0x0007f5f239b9d057,0x0001af17e3fac208,0x0000000000000001,0x0000000000000000}}, {{0x00063cbb323c7d21,0x0002b6d926fd3ed4,0x000ab9ee679014b1,0x0007e6093a1bcb9a}, {0x000dc171705931f4,0x000b0a4387f44f73,0x000c7cdd2a12e513,0x000a473ec3b73ce5}, {0x000ef17967f341e3,0x000a3809a474c86a,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=40 [{1,2,3,..,}]*([2^160]*G) */ + {{{0x000dc98081f0b504,0x0002377f1bc655c2,0x00067de245fb688a,0x000260cdd7a61e34}, {0x000d89aaf28a330b,0x0004e078039aeae5,0x000a42253d349d8d,0x000438cabcfed7ae}, {0x000a9960f3728bd2,0x000af658af568325,0x0000000000000001,0x0000000000000000}}, {{0x0006e52ab17d640b,0x00019d1bc21ee481,0x00026613d4c31a58,0x000c14072a5969b3}, {0x0005babfa75ee1a8,0x000c563bc4d35701,0x0000425d2086ecb7,0x000c9b8fafb1a4a8}, {0x0007ef737c2661a2,0x000c20e7afb2d654,0x0000000000000000,0x0000000000000000}}}, + {{{0x000726f329838a5e,0x000204b7a9942b65,0x0004a26b80fa33e2,0x0006f40abbf82a56}, {0x00026970dfcc973c,0x0001c38e96f95485,0x00019abd2bbae55f,0x000c1edd71d62ecb}, {0x00020adf26d97496,0x0000d917e1cf322e,0x0000000000000000,0x0000000000000000}}, {{0x000aaf44ac399116,0x00067bb67e29ba76,0x0003d1213c21031c,0x0003b345e37fdfde}, {0x000dab46f2bbeb4f,0x0003442227ef5d5b,0x0005c11bdace9105,0x00060e12dac175a6}, {0x000cdb1cf99010c3,0x00087106f2502658,0x0000000000000000,0x0000000000000000}}}, + {{{0x00044188249a4961,0x000eb8deb1c61cee,0x0006080b71cf8ff5,0x000b75b57b2ccc29}, {0x000b9ffb3c6aa214,0x0000a50e70e80f53,0x000fd2ffeb156be9,0x0005a94620e80211}, {0x0005db41e15422e5,0x00055d2030526508,0x0000000000000001,0x0000000000000000}}, {{0x0009e1933e619307,0x00086b5084131313,0x000b6d55898976e9,0x0003f79536a0866b}, {0x000b8e06bc0b2a44,0x00034e542863ba00,0x00040e4dd7a73a37,0x0008b2efa3822134}, {0x0005312ecb0905af,0x0008efb084f884e9,0x0000000000000000,0x0000000000000000}}}, + {{{0x000172c5ec6e6f32,0x000784d8ddaafa3f,0x000785f2ae4eb6e8,0x000db162f77d65ef}, {0x00085dec5c58d4e5,0x000a30bffa2375c7,0x0000bb7c92e0f7f4,0x0002294b17a00c92}, {0x0009107e026f93d7,0x000911ce9dc0950a,0x0000000000000000,0x0000000000000000}}, {{0x000841c6766f1f49,0x000079724523292b,0x0000e7ddb4cb0490,0x000d47f955646515}, {0x000b44b2a0877c3a,0x0004c3de4bd8708d,0x0009d24b4a9131fa,0x000585e650ae938e}, {0x000bb2e4980176c4,0x0001820248559a60,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cef71c9a9281b,0x00078b2e3e260928,0x000b15a4e8453115,0x000c76cc66031c77}, {0x000e2f2c06ffcc30,0x000a471db8c352a0,0x000184b9a687b94e,0x0009b19798642e1e}, {0x0001d84cf08e1a1c,0x000462a36c823a7d,0x0000000000000000,0x0000000000000000}}, {{0x000b775551fedfb4,0x000c921b0d298e47,0x000071e1319e7833,0x000e6f4ce5e5ae43}, {0x0001348ff7cbdbf6,0x000c042f31447260,0x00061f1861a992ae,0x00020e5f80d48204}, {0x0008846b75b72853,0x0005ef4edf14c058,0x0000000000000001,0x0000000000000000}}}, + {{{0x00051608c9277436,0x00036641c6cf4e0f,0x000263e7b7515b1b,0x000a50636eb6d459}, {0x000df53679a56041,0x000b4abcaa6ef1d0,0x0005077b47a03019,0x0009d2d427efae97}, {0x0003dfa9162f30c4,0x000f8bc801e5655a,0x0000000000000001,0x0000000000000000}}, {{0x000202783ac347e0,0x00001a26d59f4868,0x0003895e6664e175,0x000031f4202e3866}, {0x00069d2af7613aa8,0x00021cc1e58ddf28,0x000159ee13d84ffa,0x000c8f6eb59a5da3}, {0x0005df9b7b87bbc9,0x000771b8b6006cdc,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006aa5bb86ea29f,0x0000e29e7a21c03e,0x0009e430844ee3c4,0x000584b091ca8307}, {0x0006afb05a033420,0x00015d7ef65dc354,0x000acb0dfae44d05,0x000bad35608c8e97}, {0x000a78e5d1c181a0,0x0007cad8ba90d885,0x0000000000000000,0x0000000000000000}}, {{0x0001cba5026e7f38,0x0009593d89eff94b,0x000b88834191828d,0x000881379cd1acbe}, {0x000c4d9c16250e77,0x000f4d66dbf51b1f,0x000703cbf985d682,0x000998e4fae0e78a}, {0x000e124668125e5c,0x00095c7096d1799f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c267dbe90f79a,0x000a682de8af3a96,0x000fc2373c7d7a0d,0x00046c045ae71058}, {0x00067b05a94e6008,0x0009ec9a78879108,0x000973f0df20f654,0x0003d4a6c168aecf}, {0x00050f6bc30604ed,0x000f342722d4210b,0x0000000000000001,0x0000000000000000}}, {{0x00089badc8348ffd,0x0005ea32767a9d3c,0x000dc1a4baa76ac9,0x000219cd3eced60d}, {0x0007d2d3cddf3114,0x000c14e1ea557cfa,0x000c466d40b6e234,0x000224ae183077a3}, {0x000e59e159bfca75,0x0004c30d62fa0c8e,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=41 [{1,2,3,..,}]*([2^164]*G) */ + {{{0x000acef3fd9ab352,0x000a04dda16fb097,0x000e90de3351fbdc,0x0001f9baff197a3e}, {0x0003610909fc0701,0x0003d538e2bf8355,0x000fbd9d3c214c4a,0x00064b2db047d1ad}, {0x0000b9e3fa7800e1,0x0001033ba0bb0ce3,0x0000000000000001,0x0000000000000000}}, {{0x000cb2552f015a84,0x000cdab20301de3c,0x000af7c3af2c8c0d,0x000fe99606c79c8a}, {0x000d638fb52847ee,0x0009bf56737cb586,0x00000b1ec4f260f5,0x000362ff887d36f2}, {0x000ed3b693913291,0x0006e3c40f0d7ae5,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008a516e5648dad,0x00047202a3fb8a9d,0x000ecb3edff5fedd,0x000220d17fb9838f}, {0x000dc8b9ac40f762,0x0009a8311e23ad98,0x00084edfb615d6c5,0x0004e6c85dc486c7}, {0x000bf81a7ee5f8f8,0x000ecc58d5bb866b,0x0000000000000001,0x0000000000000000}}, {{0x000d41ef176fcfa3,0x00078f007acce1a1,0x000d8b8126b20e97,0x000a71b3438944de}, {0x000134e76c73c437,0x0004a56abd9a1b4b,0x000de8db7385f9b1,0x00043115d58229b4}, {0x00034725891b4078,0x000c55ba8c32f815,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008e051939a3b7d,0x00010361ba38d482,0x0009c9a686091017,0x00050f6456db6700}, {0x00031ba66d450ac6,0x000e0bdd4225b759,0x0006e52d315738bc,0x000d21403d74797c}, {0x000a041eb53ed58e,0x0002f948ee60c564,0x0000000000000001,0x0000000000000000}}, {{0x00014e408d1cd601,0x000cfebde9152461,0x0004123bd5f4532c,0x00083ab7b9fe9b7a}, {0x0009704a01b31e49,0x00040d9c79a4402d,0x0009ff5b8e0a168a,0x00048d442aea1790}, {0x0001410d782cc3c0,0x0002bf2d98ba10cb,0x0000000000000000,0x0000000000000000}}}, + {{{0x000943818d1af858,0x0005d42684f68399,0x00068a5f9139d27b,0x000d03a1a3ed9c84}, {0x00024e699de7f9f9,0x000ddd7e41e31174,0x00089cc967769d86,0x000a0e9e00b5f6fd}, {0x0007b63934a6926e,0x00011c5b068a8b3d,0x0000000000000001,0x0000000000000000}}, {{0x0007d21cfa86aa41,0x000f529a2aecb429,0x000251f8677cf147,0x000bad3bd2a35774}, {0x00090bedc57bbf0b,0x000a31f1dbfe5b37,0x0001e75b3cb7422a,0x0006476bcd9901bb}, {0x000278bd8b31cdbf,0x00082a6fb171258c,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009d9b88bd44811,0x00086c7bafe985de,0x000eb018e7fc2f20,0x00037a5b53cb3738}, {0x0000a097f28e364d,0x0000b5541e546ab4,0x000530e972bd2ec0,0x000b65a95e020994}, {0x000221ddc10db4cf,0x000295000b94fc68,0x0000000000000000,0x0000000000000000}}, {{0x0006ace5e2ed6000,0x0008ffd606613047,0x0002a24af3b853da,0x000aba583e1b87cd}, {0x0004618719533717,0x000d61f56ae2be40,0x00025ef5e9069ea8,0x000f94027fe98e78}, {0x000db6fc7d9c1583,0x00075271696c0d71,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f12734c3ec92d,0x0002bb3d48fbed19,0x00049bdd26ff69ad,0x000fbf26985b989b}, {0x000ad451c21eb61b,0x000237a30e35f12c,0x000a3b3680a082df,0x000188ebe4c92751}, {0x00087a8fbc731694,0x000b03a8bdfe9408,0x0000000000000001,0x0000000000000000}}, {{0x0006f89f4e0d5883,0x000d80de19c8b935,0x00077afef27eab9c,0x000538f8f941390d}, {0x0002b8c79f62a16f,0x0004a907ee9a2c1a,0x000951eb7aa5d968,0x0001fe7d75aa9877}, {0x0007b983b59fbafe,0x0002bab437db42c1,0x0000000000000001,0x0000000000000000}}}, + {{{0x000bf512d363aeb8,0x000e0db50c6d9411,0x0000e1101f753fc2,0x0006d62a0ded1b7d}, {0x0004a1ec0fcb3b8e,0x0000a9719f9cb02e,0x000fa60331be1189,0x000525c569643656}, {0x00081aa5691f4f2d,0x000a963a9ea530b1,0x0000000000000000,0x0000000000000000}}, {{0x000098b88fd83f01,0x0009e9aed5969329,0x000769c1597dbeae,0x0003f34dc1aadb7c}, {0x0006d041d0f773cd,0x000dcc7a18555ae3,0x00057b66cab6672b,0x000c3dbd797513fa}, {0x000ec420f27eb3f3,0x0003c62ce13b7853,0x0000000000000000,0x0000000000000000}}}, + {{{0x00057f7ec577ceaf,0x0009584ce56b583a,0x000ce15377e1306d,0x0005b26b1e23a49b}, {0x000f42d98c317bad,0x000c523283ae8b11,0x00081ddf50073f0d,0x0004ab516099e7af}, {0x00029299e519277c,0x000c0d8cb7cfdd6a,0x0000000000000001,0x0000000000000000}}, {{0x00029a85f4a1c822,0x000b7e9213cb42ad,0x000364e5e4a37030,0x000a3941f8a54d03}, {0x00050b7d507ec771,0x000db1def4d6f8ad,0x000eab3bd493bf4d,0x0009716822a9c65e}, {0x0005d463b7e2f601,0x000728062fa75d1d,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=42 [{1,2,3,..,}]*([2^168]*G) */ + {{{0x0002ee214ad0e3d6,0x000d51de6a66c4a4,0x000c1ce94446c6c7,0x000c0d5dd2eee21b}, {0x000e88f8f4a8deaa,0x00055296fd5914a3,0x000dd876c3945207,0x00083798ebb4e647}, {0x000fd6484696a7a6,0x0001d866ec9d8ec9,0x0000000000000001,0x0000000000000000}}, {{0x000ca34e120495f9,0x00050701e46446f4,0x0004431e6d90fc27,0x0006b7610b310d40}, {0x00086e5199614976,0x000e7e80f704e266,0x000aa764f7efe74a,0x0003d9535c6d9829}, {0x0005a23c25702e18,0x0000a0457bd92a75,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009cf085024c2f1,0x000c0aff178cc9fb,0x000cd1f6670717cd,0x000588548870fa8c}, {0x0001a99c44c6bc4d,0x0007a4c31ed62743,0x000f88c552f232dd,0x0008940140f085da}, {0x000a8211a1d88681,0x00041216e4c1b09a,0x0000000000000001,0x0000000000000000}}, {{0x0006cac59e6c3159,0x0000ba3374279c4b,0x0008991eda2c878a,0x0003b4cf84ea0b3f}, {0x000025e729a3932e,0x00047222c0cc5f31,0x000ba94b4346c5bd,0x000e2995032ec5c9}, {0x000db493f41a4bab,0x00024e7b6e042b7d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000aefc5789d3eda,0x000070117b5af24b,0x000a5c6b9c3050d4,0x000dbfc9621085b7}, {0x0006f4c0b7973deb,0x00006f6cf4b4e834,0x000082f092a35673,0x0002d877db7b37b4}, {0x000c2eac8682b506,0x000eac10f86afedc,0x0000000000000000,0x0000000000000000}}, {{0x0002caf651b8b0a4,0x0008310eef2a1934,0x00026025b8808ec6,0x000dcff1e64f055a}, {0x000a67192e09ae5e,0x000d785482258125,0x0007daa7d24e92c4,0x000a9c45e5162876}, {0x000fc7c72fb7aba4,0x000522976bb5f88c,0x0000000000000001,0x0000000000000000}}}, + {{{0x000921c0f982798b,0x0001a2079475b7fe,0x000ea0fd52e410ea,0x000e44af77d4bbcb}, {0x0001f260a54b0212,0x000269af2ec66a7d,0x00034794993bda84,0x00050b15e358d04f}, {0x00067a4d30bdfadc,0x000e912250ea3d1c,0x0000000000000001,0x0000000000000000}}, {{0x00083de4fe7bebfa,0x0004fdfb63579e27,0x0001abe0cbad5ac8,0x000820014b8a145c}, {0x000a85d987c51840,0x0009eba9aacfadab,0x000291af5fccfd5d,0x000785e551a982de}, {0x0002bcee4372c455,0x00049c9d89842d5e,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000817678d00826,0x0003072fc12b3906,0x000fabe24fd4868f,0x000b2a4f9e0b8813}, {0x000ccd87b27441cf,0x000e7fd0a48234db,0x000ea747d9a2a9fe,0x000c91ba0d4add56}, {0x000c9d0dd2d3e7c8,0x00005660e4fd17f4,0x0000000000000000,0x0000000000000000}}, {{0x000a904f88c1be1b,0x000e5cce4c6964ff,0x0005fb6194a74952,0x0000f033d222444b}, {0x0008c26fbb11965c,0x00055ed1ac1d1bab,0x00020c09d970630d,0x00075b608324cefd}, {0x00050cf259835d15,0x000462cd49bc1143,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b46239d54de36,0x00013af2871bf6df,0x000bb6d9f31a1b7c,0x000528b0f5b2569d}, {0x0006b9497778a81b,0x000c963043af6788,0x0003bf9954a12672,0x00059feeec8df36a}, {0x000d60c22b5fdead,0x00060d265f0f8b6f,0x0000000000000001,0x0000000000000000}}, {{0x00050d0b6534b1ea,0x000703b71e08797c,0x000d2bd35e284a7c,0x000105aa68827a45}, {0x000902245c12e4ca,0x000f1afdb8eeeba0,0x000caa7693b8db6c,0x000824a39f45018e}, {0x000945d0c9d12756,0x00055f86289ff82e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f246813a5e2f3,0x0004d2dd1bc96870,0x0005743352958a8b,0x00007a9386d4a79c}, {0x0008b4a29091d043,0x00059ba9e47bd2da,0x000478de8a606e11,0x0008c9f2a8c27ae1}, {0x0002946224c1c93c,0x0003ef3adcff2ded,0x0000000000000001,0x0000000000000000}}, {{0x0005100b79546483,0x000ac268f6c48348,0x000e4b2ec17a54ad,0x000f85818d6815bf}, {0x0004f425318546e1,0x00013cbacecaadf3,0x0006d908fa2a9c92,0x000e8808196d6c46}, {0x000ad801f4a291fd,0x000b7ecba0623fa6,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007b0f39088ef39,0x000a435ae74e03d1,0x000fbdcdaf3b17b1,0x00090868e5084910}, {0x000019102285b63c,0x0005454d88d8e63c,0x0009e2380d185fed,0x000af9e19dfe50f9}, {0x0008e09d7ce8d3eb,0x0000155127749872,0x0000000000000000,0x0000000000000000}}, {{0x0007fda1b031ef4b,0x000dfd7188feeb77,0x0006801e0f6f597f,0x000e9d1729652f82}, {0x0009d58dec034252,0x0003cc68d0c6aa0c,0x000a4e76779b37e4,0x00008d509f569c62}, {0x0000c41330558ca7,0x00056956b5657bd9,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=43 [{1,2,3,..,}]*([2^172]*G) */ + {{{0x0009008a556937c2,0x000f76241f10378e,0x0004e7ecf0092193,0x00097f48f8905d70}, {0x000c86b4870ad280,0x000f86eb6f389aca,0x0003ffbc3b9a3132,0x000a9c6b9598fe5a}, {0x000429f1014fb463,0x000e06408908552f,0x0000000000000000,0x0000000000000000}}, {{0x0000c94ae41024de,0x000a6dd0399afa53,0x0007da5ef17ac70c,0x00080b49854eb299}, {0x000104afd62b1e2c,0x0000b1375777d7cf,0x000794db8dbecfef,0x000ff21b1b05dfbd}, {0x000f1e68e47404db,0x00080928abdaf296,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001636898bf4d11,0x000fb75ab01bffaa,0x000ba4b1f3e58bf7,0x00059cab50bc67e3}, {0x0008acea4689ce8b,0x000f1932a30d30cf,0x0006e5cb3d1d8eda,0x0005fa7949e492c0}, {0x00041db2db16d8b2,0x000b0610d851b96f,0x0000000000000001,0x0000000000000000}}, {{0x00054a2b36667691,0x000ca196d36fe2b1,0x000766e2a6109d47,0x000f9263f1863dba}, {0x0003be92b5a5ba8e,0x000aad9918a5da16,0x0009189520c8298c,0x00010a27963af5e7}, {0x000b8c3b84ab05f9,0x0007bafd0103c420,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e3e45f8d73683,0x000eb8ebb6d11caa,0x0000f274ee508fde,0x00020c83562c576b}, {0x0008510e47baeee6,0x00079b810588c571,0x000894a919ff42e2,0x00007edf259b927c}, {0x0009d16a223100a0,0x000a5b2acb9ccb16,0x0000000000000001,0x0000000000000000}}, {{0x000e8415a9179d06,0x0004b594d74f07fe,0x0004fb6e0e5cacca,0x000788b708cc549b}, {0x000c0c62edae508e,0x000b9ef886c2847d,0x000e40664c8eee69,0x0003ed24b57a9dee}, {0x0002b9d44a547432,0x000a6f16f12261ca,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005496bc42e6e51,0x000d33d320585033,0x000cf402bd388067,0x0003e6730074be0b}, {0x00043e8db4e94291,0x000f7beef462a0cb,0x000e58a8c2ead81c,0x000b97eccd5df06d}, {0x0005954e3501f23b,0x0004b4a8b8e4e11d,0x0000000000000000,0x0000000000000000}}, {{0x000598c1e025da1b,0x000b09bf9648fc1d,0x000d224f8ad9987c,0x00065a60d88fba1f}, {0x00054d86a1d9f606,0x0006c4ad1df1e7f7,0x000e1da4acf77f72,0x0000938971a27713}, {0x0007fc94e0f78da1,0x00083992811d7d3b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c9cc6dd4a5914,0x000862d80be96443,0x00008c7a249fd0f7,0x0001ea54a0d2c9f8}, {0x00048d9e55013f6b,0x0007ab76e8d002ac,0x000cbf4462d73cac,0x000faf5cdb58c492}, {0x000ca322b819e5c1,0x000b840745406425,0x0000000000000001,0x0000000000000000}}, {{0x0005f739a14940b4,0x00097d20ee2a886c,0x00035ab04c341a53,0x000f7a9d2904ba7b}, {0x000d9cae762f47f9,0x00007d2eaeeeb5be,0x00070ab079042e0b,0x00060a339ed63e5f}, {0x000c7b9658ba8e43,0x0002d18d85499745,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b401e3813737f,0x000ff61118cf0239,0x000909b65cbad1c8,0x000da081fe099573}, {0x00028cfc70caa9fc,0x0002bfc31062db69,0x000e85af4aac9c83,0x000ba3d1d4e51a7e}, {0x000363dd1405fca7,0x0009117097ec2370,0x0000000000000001,0x0000000000000000}}, {{0x00065c78edf4f376,0x000f36321b45daed,0x0003283085bc71ee,0x00018a85f5b5aa08}, {0x00055758f2c2f181,0x0001623497212c90,0x0006ecdfee014f92,0x0000a48aadb790d1}, {0x000881e12f4528d4,0x0004482acaa286a1,0x0000000000000000,0x0000000000000000}}}, + {{{0x00050bbeb7940a25,0x000eb62b0dec1d2e,0x000f7146dd0fa42c,0x00051beef911c829}, {0x0009947cccb28e02,0x0009505362c5e903,0x000767ef06d55451,0x0003dcda2ee6b16e}, {0x000b2373652d7be8,0x000cb5af116c86d2,0x0000000000000001,0x0000000000000000}}, {{0x000d36b874b6449e,0x0002d7bb963c1def,0x000de8609229e57d,0x000375fd0ce127b2}, {0x000b5890dc213b70,0x000a1d88db3c82d4,0x0007b583b09ebdc9,0x000cc6b137b10089}, {0x000cf29a5fc13efd,0x0001907605ca17a3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000665e2bbfdb04a,0x00017e4232c5cb5c,0x00026232f5f9a245,0x0007a0275981cd79}, {0x0005ae253d4d80a2,0x0006c00bb7783b1d,0x0004c2589b5ab0bd,0x000f6c48caf740ea}, {0x00082e177fc5351c,0x0000fd2b0e714ba4,0x0000000000000000,0x0000000000000000}}, {{0x00052b5ad6ac73dd,0x0007a311881ba785,0x0004ccac10cfb206,0x0003dcbe5d449097}, {0x0008b8873accd901,0x00080d70e5b2cf2a,0x000440b2c2817333,0x00067c3b711d4631}, {0x000b996623747bc6,0x000383423c70b2d6,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=44 [{1,2,3,..,}]*([2^176]*G) */ + {{{0x000b11d1789dc869,0x00016c2eed227fa8,0x000916842cb7fd9a,0x0008564ce12a5d02}, {0x000bee59ed474675,0x000e675f354b48f9,0x0005d69ece126be8,0x00018ce3aca2f7c7}, {0x000768d6000f88d2,0x00090f26ea6ff29a,0x0000000000000000,0x0000000000000000}}, {{0x00096ef4ce69e270,0x000f2da0efb2f05d,0x000a99dc276ac3a2,0x000e0342757c443d}, {0x0003b390d2a5e23c,0x000e7ea78e9b674e,0x00085e132e72b987,0x0006b6c21856dca4}, {0x0005bed8cda17d0d,0x000237220788bdee,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002364996ca25a6,0x0007ec8d70cd440e,0x000d8467c5161afc,0x000408724c9aa882}, {0x000b962a215cbbc1,0x000c4986c1ad6d3c,0x0001332912aaf7a6,0x000d6db2702d8369}, {0x000a17e017d4a1ec,0x000f2dbf2405e93f,0x0000000000000000,0x0000000000000000}}, {{0x0000641168090c5e,0x0006fce42ae3e68a,0x00039938713395b0,0x000394a15bb1098f}, {0x000db97734c1bca3,0x000edfc62ae8c0be,0x000bc2f9b0452cb1,0x000304c79c90c661}, {0x0000dada4e625332,0x0006fc2e4ae4342a,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001bd7fc156252b,0x0000ddb25b337fb0,0x000ac5d025ae1e66,0x000c26056a73c379}, {0x00095dede6af2b69,0x0001ae9121b7e81b,0x000754f6cd030d2a,0x0008b47d1e9a5f7f}, {0x00025d238c9b7c0f,0x000d32d6fa902ce9,0x0000000000000000,0x0000000000000000}}, {{0x0005ace423d94184,0x00056f6ab6a655f9,0x0008fa78d47709a3,0x0003f5d39d32f258}, {0x000beab0a90b8c58,0x000bc517995d68b6,0x000ea4acae9d65d8,0x000fd569fb104a80}, {0x000b09db02cb3b12,0x000c624b3e1e5f67,0x0000000000000000,0x0000000000000000}}}, + {{{0x00093cbca6dca0b6,0x0004a2146559221e,0x0006c357ebc20032,0x000e73dafbe29569}, {0x00073f1c77b70537,0x0002b0a8e959d415,0x00055d9c50a71dc1,0x00037c9b3656d184}, {0x000283b617fcbc17,0x0000976acf8093d9,0x0000000000000000,0x0000000000000000}}, {{0x0008b573715b4734,0x000173f0027024fa,0x000386bfccf3b38a,0x00095480bbc99c54}, {0x000668bfbf241bdb,0x000353dffbcc88d5,0x000216b7968e8858,0x000de22f661faa2a}, {0x000189437f0cc373,0x000c1f5601679c0c,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a86967182c501,0x0001f634e40148fc,0x0001c864ffbfa398,0x0009d6d142879632}, {0x000443e4b6047507,0x000e1e5a879eef57,0x000d2b8fd7f7f136,0x000d19b6378838d5}, {0x0007815ed1c2726d,0x00042ef17abcb4c1,0x0000000000000000,0x0000000000000000}}, {{0x000b9a5999895b25,0x000be140e558227b,0x0007f28ae923d146,0x000d00a58852f582}, {0x0000e60ada16c8cd,0x000158a85a7def11,0x000e5c61d1152d28,0x000d4be61bf1a55a}, {0x000cf413c0a31606,0x000b3cd625cdfd8f,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003f2f8ccce2027,0x000fd5cd45c4a564,0x000a6b2411224a0a,0x0007a5ca2258c4c8}, {0x000678f855fedfa8,0x00055199f43975cb,0x000e9a39edc6298c,0x00007312684e5a48}, {0x000adaeb9f55daba,0x000b39c9f5f377bf,0x0000000000000001,0x0000000000000000}}, {{0x0003e0968382a7ce,0x000869c70ffd115a,0x000ba001f2afcccb,0x000107bdfe8068fd}, {0x0000206868f7c124,0x000821a90928b9fe,0x000afc533728dac3,0x000b3e9edff0ac94}, {0x000d10c697f67565,0x000bea250773ba0b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000275a2c8f91400,0x000bb4c241f78224,0x000c4fd93b4ba60f,0x0002941b616268c1}, {0x00020107f7964087,0x00031b438825e04f,0x00019247786625f8,0x00028de20083c5f6}, {0x000abde39791c6d5,0x000b3b75c25ecfb0,0x0000000000000001,0x0000000000000000}}, {{0x0008e09f47b9d8c3,0x0009374c6bc5ceb5,0x00038e27941b3112,0x000e3235cee2666e}, {0x000ea8dbee896ca0,0x00030660009b498d,0x0005f8f0f2897645,0x0000fb5ee44458ff}, {0x000fb559aa7b5e14,0x000272ac85e138f9,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009f0c6193905a5,0x00013e99256667bb,0x00027fdbbfc34892,0x0000d2c71218ca33}, {0x000915a83f00e563,0x000d628331bdc8df,0x0003e8128ee96b80,0x00016a5f7e06bfe7}, {0x00016364a2a7cd33,0x000c748cd2a08bdd,0x0000000000000001,0x0000000000000000}}, {{0x0001d90fa51d3800,0x00020c814ecb8822,0x00000fc79208b5df,0x000f252076343a10}, {0x0008a14b68032c99,0x00054fe0dc71413b,0x000d97c9a173cb46,0x000c85a386e9a9ac}, {0x000bf160a14a40bf,0x000032849e997087,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=45 [{1,2,3,..,}]*([2^180]*G) */ + {{{0x000384b0dc2ffbb2,0x000e0c16c289b477,0x0009eabe48cf9601,0x000199d671ddca51}, {0x0006f3fce7863b3f,0x000e01be3ea3ecba,0x000b70167c58c7d2,0x000f4893679afbf4}, {0x00019a4362cb78d1,0x00061515a3d7fee0,0x0000000000000000,0x0000000000000000}}, {{0x000f2840f746e722,0x0002ef160c51fc25,0x00097156a16516e7,0x000e8398d9625db3}, {0x000d63f5b2c0ebf6,0x000c5b6523651404,0x000476dd10c4d87f,0x0001f40ffa318eef}, {0x000788025e5d3977,0x0003c298fa2547e3,0x0000000000000000,0x0000000000000000}}}, + {{{0x000523e81658a625,0x000aef8e050759b2,0x000b0377d5042659,0x000b9ae72b36823c}, {0x0007eff957169419,0x0009705cebf46fc1,0x000bd18b61ce7ad5,0x0007a7135b602fff}, {0x000f2e092fe9192a,0x00074d30a3a8e596,0x0000000000000000,0x0000000000000000}}, {{0x0007c895ead96751,0x0006523da4889766,0x000467afe86eb732,0x000a5ee25b7a7cf8}, {0x00000f2568e46393,0x00079a3304b15dd0,0x00036bd203f1569b,0x0009a5e938c0d91a}, {0x0001da1271a34645,0x0004c688c575bf52,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c62a6b633bf04,0x0003c0eaef0121c8,0x00058d7354098cc5,0x000448cc925273a9}, {0x0006f73c56bf4c04,0x00042b800bc52be4,0x0008d6b39147d475,0x000444cb5cfe3029}, {0x000d4247fb2312e0,0x0007054c4d89dd9e,0x0000000000000001,0x0000000000000000}}, {{0x0000edd6a97a9163,0x000582ed4f4d5b46,0x000b9ca61309206a,0x000fafa93e18c6dd}, {0x000bda68f9bb8a3e,0x00070a52c8b2d783,0x0007728c0dda564b,0x000c0dc789e7dbe4}, {0x000119aa3e8a6481,0x000bed27f421a4e4,0x0000000000000001,0x0000000000000000}}}, + {{{0x00001ee133405081,0x000b94055dadf3f3,0x0008803374bd3d6a,0x0000e431a078817f}, {0x0000ae1298465c73,0x000a08da98aae817,0x00076bc8b779119b,0x000c1b8f7410f128}, {0x000bc98dcbe46247,0x0001761805980867,0x0000000000000001,0x0000000000000000}}, {{0x0009de67dab5cae2,0x0003d2d0125b70f5,0x0008c5ad3a01682d,0x000cf59a9c7c1b26}, {0x000ada095cf6362f,0x000b79b1ed6482c8,0x0002b3bc253c84e5,0x000756917d1dd695}, {0x0008f439fdfad9c3,0x000651a63232aa5c,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003a055275e1f13,0x000bce620ca4b51f,0x000765c9fcc48133,0x000387e5710e23a7}, {0x00041d9c294797a6,0x000fe4eedda6621b,0x0009f733bf9d9ac9,0x000e4cb8a3045df1}, {0x000d5c96c4f51d70,0x00041a25c50ad245,0x0000000000000000,0x0000000000000000}}, {{0x000acd86687a04f6,0x0009bc4b6a5c45b3,0x0003f85a2b09f7d1,0x000f69420758494b}, {0x0007e554c9337d50,0x000ccb9c2f40c240,0x000e482c5dfc1a60,0x00016ad44e8b11e7}, {0x000d080e60fea531,0x0001889fd549f4ed,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007e29c5ef5cdd9,0x00046b2b2e558b7e,0x0004702314f3e6bc,0x00026fae56eeaa30}, {0x000145ca44a1b067,0x000ea8da792ee6f2,0x0007e4c829cf9680,0x000d723cb279141e}, {0x000c514c645b326c,0x000b3d5e8e8931da,0x0000000000000001,0x0000000000000000}}, {{0x000e5ed0862bd48f,0x0009404a34e74e61,0x000e1d4a98483644,0x000f45001f65c56b}, {0x0008e062ee7183e5,0x000a39ef75aa764b,0x000f4509012ed646,0x000742837f0ebdde}, {0x0009ab588faa786a,0x0008d7474accf0f8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f31aa7add26e0,0x000b5f70683b341e,0x0002190eb5f5ed33,0x000e3b2bf3278604}, {0x0002cdb29e4008f6,0x00042f0700c911a6,0x000f5e3688f5189d,0x0007c2de5c257eff}, {0x00089c193e2d4667,0x000cca5de47c9861,0x0000000000000001,0x0000000000000000}}, {{0x000dddac10383cca,0x000803caddccaca7,0x0000778df17cf555,0x0009278c5faf93e7}, {0x0000e7cfbb523b02,0x0003ef004ba7546c,0x0007290d52d052d3,0x000f54a34c36c895}, {0x000e1b89dcc555fa,0x00058777136cbca3,0x0000000000000001,0x0000000000000000}}}, + {{{0x00060b5ef6c20e82,0x000bf430fe1ead47,0x0003a480e70d1479,0x00097c0aba684ec7}, {0x000549990971954c,0x000a1c5645d306cb,0x000cc85cc5c264ce,0x000739efac323d9e}, {0x0003b20c4465cbfa,0x000b4ee9cad749e6,0x0000000000000000,0x0000000000000000}}, {{0x000242934808827e,0x0008a9860bc18213,0x0007a452bdb41b29,0x0006c3f651ceda44}, {0x000f153ca2965078,0x000e0cd8cc7845a5,0x000c9cd5913baf87,0x00050312de2e060b}, {0x000a1444279bfb31,0x000ff8a16f8265f7,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=46 [{1,2,3,..,}]*([2^184]*G) */ + {{{0x00033bcc8924eb55,0x0002e9d518ffb740,0x0001ae0cd732da2c,0x000cfbc19a4290d6}, {0x000d8784c1f06357,0x000fe209893ca1ae,0x000969a85a8dedb3,0x0009c8eb2e932f87}, {0x000bcc740550ff52,0x0004f554bf85aafb,0x0000000000000000,0x0000000000000000}}, {{0x000bc6372d7f8438,0x000dc0557f4f2ed5,0x0009d0c30f3c2efb,0x000ddabb262ac2fc}, {0x000f7a05b87d4d5d,0x000c91e745769d1c,0x0008c994d0a4907f,0x000889250072dcd3}, {0x000ffae1ac453a28,0x0002a8e72458000d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d9177fbc76a5c,0x0003975e3cbf7406,0x0002f09def039ed5,0x00034da80caf736f}, {0x0008efcc790febc5,0x0000ad47e746448c,0x0001ca336b92fa7b,0x000b90e92c64c767}, {0x000dfd8d6637080a,0x00032f5711517b52,0x0000000000000001,0x0000000000000000}}, {{0x000a0257ff4a1581,0x000bc02441238656,0x000364971ed77234,0x0008b1d09b2d316f}, {0x000bfdf4ae5e00cc,0x000468fa8d307856,0x000805be3791c041,0x0003fa589236fc69}, {0x000a337620c1fe73,0x0001e737b5760989,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e1990ae2c44bd,0x00083ee2175b6a29,0x00005d1fb5989698,0x0001375eaf1c4bd3}, {0x0009f54aec5725cd,0x00017c1f0f7d222f,0x000f9f96b74e2d73,0x00053fff253f88e6}, {0x000b31a11aea1b12,0x000aa32748b4a307,0x0000000000000001,0x0000000000000000}}, {{0x00007b074c7b461c,0x000258e6e4224b52,0x000162fc7af983c9,0x0004966825052f5a}, {0x000f9138a0346a4a,0x000a7041242b7952,0x0000a366f5699476,0x000460c88c7d5eb7}, {0x0003f2b3125e31d3,0x0002a892d14ada09,0x0000000000000000,0x0000000000000000}}}, + {{{0x00001e6a21a7b432,0x000c3971b4886b8a,0x000dae7cb7883120,0x00059d28f3efe6ce}, {0x00028e1699713fd6,0x000252af65756250,0x0002a3acd7c4a210,0x000f7efc9c5a81fe}, {0x000e2a5f82fab4ec,0x0005c0924441558a,0x0000000000000001,0x0000000000000000}}, {{0x000495dd493563c9,0x000ccadf9b0e7295,0x000ab5a8f70bb0fa,0x0005b32501ed29d2}, {0x00036f439adfe6b6,0x0000a6c7202e9c24,0x0006531bcd403e24,0x00064526a2b69777}, {0x0001dc2d590cd125,0x000b64170acdcfa6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b0bb5e03ac48f,0x0009bb5837030273,0x000a05cded5e6ec1,0x0008034dce79ed12}, {0x0000fc54532094d5,0x0008fcc6c534a769,0x000bca87d8be0fee,0x00041150d981f9e6}, {0x000222345254c456,0x000b2aa496b6e112,0x0000000000000001,0x0000000000000000}}, {{0x000d2c8de5bb7e5b,0x000278f0be2794e5,0x0001b31bbb57b1c7,0x00001958330187ab}, {0x000f5dd751abf9bc,0x0002de4b57d090a0,0x0009cb74fbe565f2,0x000f83e310b95170}, {0x000d1301cd0ee2f4,0x00049fd2006501c7,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e8d883bcef9f8,0x000be3770de7cc8b,0x00007c65e3e95107,0x000ac96f780e3eca}, {0x000413d615089cf6,0x000585b5b22549b6,0x0008b5facd5da79f,0x000f3c8b5c5a4c0d}, {0x000d6dfaa970b49f,0x00065cc025c0e7ad,0x0000000000000000,0x0000000000000000}}, {{0x0003c64dd34154da,0x000343c797b7cd0b,0x0001f367813bc308,0x000fbf3f138ae118}, {0x0006f1f8c6302e7b,0x000f35ea2ee3cc54,0x0003a0b904ac34ee,0x00052596f106852c}, {0x0006e533ab1310ec,0x000abf763b19381e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d9a73e24c887c,0x000707461d095f01,0x0005d3ad552ce968,0x000f402b6c527f5f}, {0x000818672d6016b3,0x000279bc4633dd66,0x0000c571c90fed28,0x000cee78b5512020}, {0x00048d6ae97b4812,0x00055292fa8b91d9,0x0000000000000000,0x0000000000000000}}, {{0x0004608b8c1577cc,0x00058615049c4716,0x00077fa05c3b187a,0x0000d33110dc1846}, {0x000554a923122c03,0x00015b3d3cf40b2d,0x0005e05a3843c4de,0x0006438408a6964a}, {0x0005f646af7c591a,0x000ae89a0f7132ab,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b5e462dd556b6,0x000f3aab5e9c2f29,0x00040c3ae00c87a1,0x000aade98fdfc7cb}, {0x000f2f671ec86f72,0x00069dd7b2aa376f,0x000b6f90c4b07483,0x000ae5c39e831a9e}, {0x000ef6929b8bdb31,0x0007125a4c5224c9,0x0000000000000000,0x0000000000000000}}, {{0x00080ab908d10b8d,0x000b7c8a32a9943d,0x00051b7d4fd0edbb,0x0008eaa89eb83ad0}, {0x000fb343de0ebbe0,0x000d3c4d0cc33cc9,0x000b15124b0953fa,0x0007582773fc9c30}, {0x000ab2c193a021a4,0x000b73ddfb881675,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=47 [{1,2,3,..,}]*([2^188]*G) */ + {{{0x000f014ad29ca649,0x00075a10e7e9c3d6,0x000042dda6a91edf,0x00069276fbe9047f}, {0x0005a497f91416df,0x000b982ab7fce403,0x000b8b61e6adadfa,0x000d218a9fd9d973}, {0x0001c8c04e2c23f1,0x000cb12274d47d9e,0x0000000000000000,0x0000000000000000}}, {{0x0000ec3de397b98a,0x000d9a272cecd709,0x00050e492db6d724,0x00082a50e32d2f19}, {0x000db6bf40e9c68f,0x000b25727f0678af,0x0007a36e6ae78194,0x000cbb096d1806b7}, {0x0001afd3feedfa35,0x000e57c17d9b9ff4,0x0000000000000001,0x0000000000000000}}}, + {{{0x00078e57ab05c549,0x00081a123d2b219f,0x000ecb0183ca3cf9,0x0008ed9f1eddfd07}, {0x0002f8f90e3c6699,0x000ad41bb20e0515,0x00019c77dab5c5ef,0x0002ca7830069394}, {0x000ae5cd1de605b3,0x0003933d6039cc98,0x0000000000000001,0x0000000000000000}}, {{0x0000ae5b05bb2b74,0x00071168c4bf8259,0x00001a66f3efdf4f,0x000e1da4a65b0015}, {0x000ba0665dbdf241,0x00015f360d4c3387,0x0004e85c88fe301f,0x000c061a8e048acf}, {0x000bcc0119ca9957,0x0009ea8585dfcf51,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c2a4869f8ca68,0x0005748af64adfdd,0x00044c661ce61bf4,0x000fa33532bda5e6}, {0x0004409ebd1c4df9,0x00063b107af0f45d,0x00013ef2dc8804b9,0x000a186c6c3f3d75}, {0x0005a7ed73f6b67c,0x0000b525bc5b72fc,0x0000000000000001,0x0000000000000000}}, {{0x00008fa0f93430b8,0x000bf3cdf63616c2,0x000a2ed8b79415ed,0x00008df169f3be1c}, {0x00006a9b7669442a,0x000be581a2acda6a,0x00093d2dae365779,0x0006ea987608134d}, {0x00059b31b3052589,0x000d8078ebfe0716,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a0e4faa59f069,0x000d33d96e52e437,0x00029f2632f3aebd,0x0000c85e4fd15682}, {0x000de4f3be7892c7,0x0007d9fb180a1634,0x000b175638b44c2c,0x0002e33499b53e6c}, {0x000cdad290b60dc3,0x0009d1cf1fcbab2e,0x0000000000000001,0x0000000000000000}}, {{0x0001854cefb1da9f,0x000257b5b7539f5d,0x00096df1240b9d47,0x000f9e9a561ffc72}, {0x0000d6d9452715e9,0x0005aea9109f0df3,0x0005d521e814b452,0x000c7037d6e74c47}, {0x00060afbb2239aca,0x000dfe3a178a1e6b,0x0000000000000001,0x0000000000000000}}}, + {{{0x00085fac7aac5d24,0x000e6efcd816f4de,0x00001aa65b85ec90,0x00042ef288a94272}, {0x000527aa3e5baff2,0x0002c225dbf973aa,0x00073237d80e262e,0x000ac84d268b446c}, {0x0000056980d17882,0x000089041c6047c7,0x0000000000000001,0x0000000000000000}}, {{0x000f5b36106ae92d,0x000b658d82ab92e5,0x00036754a0792779,0x00032fae5cee6721}, {0x000bd0394c90fe6b,0x0001825f86d43336,0x000fa2e7d57eb880,0x00022294f3c7cd21}, {0x00070bb4a5b81f76,0x000e5c797152fbf7,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d4560b8c46ee0,0x000b73ca40a188f7,0x000b593661397fde,0x00026cffd18ba8cc}, {0x000c47a735170abd,0x0002887e49a94d3e,0x0002a2ec01caeb9b,0x0007426e36269901}, {0x000522aa9c52b5bf,0x00066af9e1ef518f,0x0000000000000001,0x0000000000000000}}, {{0x000d742afa309fe0,0x0006f810d9df60b6,0x000084e739c300f5,0x00056da63d1a036a}, {0x000cd4f33c2df42f,0x0000b456fee1f0f2,0x0008f569e5589fab,0x00062492c9b09b89}, {0x000079adb7885960,0x000cf412b618c75e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e60d6e9faeb2f,0x000298054778495c,0x0000f99d00d5919a,0x00052dad049c1204}, {0x000e8b4f342e902f,0x000c225bd4b3fa2a,0x0004f48aaba21576,0x0009d33ad4b48b96}, {0x000a24fa9d5b26df,0x000f2799a4fd763d,0x0000000000000001,0x0000000000000000}}, {{0x00017650a566263d,0x000e25ee8cfe1893,0x000763623662e408,0x000a4360ad7e6d05}, {0x0000ba65a8e233ee,0x000338261baaa5ea,0x000af51b8dde194d,0x000003aaa23ac37d}, {0x000ab55391298a43,0x0008f52d2a4172a8,0x0000000000000000,0x0000000000000000}}}, + {{{0x000760e887bee904,0x0009f91c8cff613a,0x0003af1d33766225,0x0002f55a798ee44c}, {0x0002c7171b76304c,0x00051b89de6b4202,0x000754ce995dc454,0x000a5d7e90f40166}, {0x00037fe2c45f5e9e,0x000d835f81a1be14,0x0000000000000001,0x0000000000000000}}, {{0x000c04a7dafbcd8e,0x0007d22e0b1aaf34,0x000ad92815662ecd,0x000b88ed3ef4d947}, {0x0000190778cccdc8,0x000ea32bf7d0a755,0x00094ed615d6df41,0x00066cdce7de3703}, {0x0005d94b6a5a2d85,0x000869b1500a755b,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=48 [{1,2,3,..,}]*([2^192]*G) */ + {{{0x000556d5fcb0ca3e,0x000bb40eb6f5de7b,0x00092b00751e1fef,0x000d985badf10d77}, {0x000bda78c0fd8245,0x00097cec621ec6c5,0x0009de36f6534761,0x000929578b20f59e}, {0x00008129148b6a34,0x000260858df1e4dd,0x0000000000000001,0x0000000000000000}}, {{0x0002df7b80140bb6,0x000f0872cf54b64a,0x0005ba02c9e702cc,0x0006a4694fa2136f}, {0x000ae62ca46c9431,0x000a69d6c72a601f,0x000ff0af210ce686,0x000a108647e23ca9}, {0x00072d54b7301dc8,0x000b4fc0d011e4bc,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c2c9272139ecb,0x0008248890056b04,0x000319a82e4c5944,0x000bd6a55d37d95b}, {0x00074d80dfb735a8,0x000b368732a7edec,0x000dbb960fac47dd,0x0009b7d149244f46}, {0x0005c8153e4ae15b,0x000dd7d6f5637025,0x0000000000000000,0x0000000000000000}}, {{0x00023077c37f59fa,0x000e01c814ef1183,0x000d2dfe1b52b965,0x000d66c5cad600e8}, {0x00064cd44f8d02cd,0x000b170f04ad1f49,0x000b95d6b03da74b,0x0009721ac42809f8}, {0x0003fd08dc3ee705,0x0005bd69cd062aab,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b883d845a0ae0,0x000afbae353f2a2f,0x000473d0adeb61aa,0x00037ae3890f51bd}, {0x000480f0c4103d1b,0x000087e22deca493,0x000ae96c669a58f0,0x0000d7ec27b93462}, {0x0005f63a771fe3af,0x0004035d6f692734,0x0000000000000001,0x0000000000000000}}, {{0x00047ce82b6063a3,0x000a032d78ca1a20,0x000ffe80d92bf2a2,0x000357128144148d}, {0x00065f437565141e,0x000044794e70453a,0x000ed9d74d6e72f4,0x0002c9dec888c3b6}, {0x000d35b1703c9efa,0x0005564a8b5ee101,0x0000000000000001,0x0000000000000000}}}, + {{{0x000408c0ef420ccb,0x0003751466bdddb5,0x000686318317d090,0x000f5c351d77faab}, {0x000e6e1c56990fd6,0x00044f54fded7bc7,0x0007a03658746405,0x000acb87ac9e9b1f}, {0x000e1a951d060b45,0x0002d4d46b22b133,0x0000000000000000,0x0000000000000000}}, {{0x000b308639e1f9dd,0x00088fb9f340687c,0x000545e0d0da3dfc,0x0007c0127b5897e6}, {0x000708cdc1322bbf,0x0003ce8bdc5bfb35,0x0009aefe13ad9991,0x0006b6cb7333e158}, {0x0005d1b9d92265f8,0x00065e9dfffba15f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dfc8b990a47ce,0x00010afcf7dc8ef3,0x000e84517ba6c8fc,0x0002906aab79d6ea}, {0x000563aab2198045,0x00005b6fc1e2c314,0x000e1c75139c8775,0x000f87b03c5339f9}, {0x00013db5c7dd8d56,0x000be729d4f04194,0x0000000000000001,0x0000000000000000}}, {{0x0003ca2969a49a45,0x0003d7263734a805,0x000a96220f01659f,0x000a81ea503a05cb}, {0x0009a4b1e826b6e7,0x000b9124852cc317,0x000a53155592390b,0x000adcbcb9064287}, {0x000f6cda7ecb3423,0x000745fa7b75f585,0x0000000000000000,0x0000000000000000}}}, + {{{0x000020f9870c5652,0x0008ed2cf4bf5440,0x00043a293130a211,0x000b5775772ea602}, {0x00033659b8c321b9,0x000b8b914e8eddd5,0x00016d7acd2ea084,0x000600a84078289a}, {0x000073293df2fe16,0x000f1b7632be02d1,0x0000000000000000,0x0000000000000000}}, {{0x000ae60c00fc41df,0x000dee1aec5298cf,0x000dc3a384668cb0,0x00039330262dc7a6}, {0x0008200480e942b2,0x0007f1ad6908e660,0x0004d8902ca00250,0x0009dfae47555ead}, {0x000dd7fb7e96dfa4,0x0004d09336664145,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d1eaa79614564,0x0008f53026152677,0x0004e1ef41c569ec,0x0009c61bebc6f47b}, {0x0005a764d392b91a,0x00081c91fd03bca4,0x000d12e91e91f33f,0x000ceb9cb7de2868}, {0x0000e9b7cc6516bd,0x000c8bcc47c28272,0x0000000000000000,0x0000000000000000}}, {{0x0007539aee683a33,0x000df86171edb94b,0x000cb40fe4798476,0x000b93f35533bd14}, {0x0009da702f13dc6d,0x000ba7ad4d348188,0x000a392741f6a108,0x000c52b97e5c2cce}, {0x000568205c383605,0x000d4f58766e7a6c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d3d9203521aef,0x0003dde5091b5f60,0x000ec304735ae314,0x000afe69e360b755}, {0x000f3119298c9f78,0x000c6a7738e3ed2f,0x000298a24d640365,0x00078b486bf006b1}, {0x000e9050b3448a96,0x000ac46d50f02b81,0x0000000000000001,0x0000000000000000}}, {{0x000b1ce68a1d8699,0x000b8559ff13a9f1,0x00023011f5efc1bf,0x0004e57b1d2b17a5}, {0x0008efdcb9ac6bec,0x00009c3a1153d5a5,0x0006b2a4b16461a1,0x0005a5edc709e6c0}, {0x000d62c80c93e99c,0x000b0218529aa94e,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=49 [{1,2,3,..,}]*([2^196]*G) */ + {{{0x000e7cc655ddb9f3,0x00013549c78f7abc,0x0006489c7f6e90f1,0x000e52627145775f}, {0x00027c353f1cebe8,0x000a2f29fc36a4b9,0x0000acc3ef5baced,0x000fb8074e6a3d4c}, {0x0008d3fd643a9c64,0x0004c070fffe4c63,0x0000000000000001,0x0000000000000000}}, {{0x000fbd2cdf57826f,0x0005bd9bf19e6e5e,0x0007942ab0ce8665,0x0000c790e82b0e8c}, {0x0001e2f2b552cb1c,0x00090a098c9dab8e,0x0009810a67eba463,0x000c6a4756fc9b4d}, {0x000e8cb25c97785e,0x000215f5f5b6c18f,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002bf06c6b067f9,0x000a2b3dcbcaa8f7,0x000559f9fa4cedc2,0x00001ff4707cbdc6}, {0x0005eb59f1a1d653,0x000b9620b3fc409d,0x00091f76c53a5feb,0x000e766a3eea48b5}, {0x00013597ec3fc458,0x000a5eb4cf309e19,0x0000000000000000,0x0000000000000000}}, {{0x000b24162ae5ce89,0x000e57dda1da6f8b,0x00092393366cd895,0x000d0cbc02de8414}, {0x0007365ce8f0759a,0x000cfa2564893b65,0x000a74873186b40b,0x0004d0156cb04fbe}, {0x000490f66512a03d,0x00036b328165e70e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d63dbde7982b9,0x000c29e4cd39f5d1,0x000aa87372309f98,0x000951ea561fec44}, {0x0001afd07b42ddc9,0x00045755866c4665,0x000b2e07bf78c6a3,0x000e9284f87ca447}, {0x00035d4199cdea2e,0x00049a677e175372,0x0000000000000001,0x0000000000000000}}, {{0x000229ff95010f5f,0x0003cbc8f306c814,0x0001a7861e7a79e9,0x0002d63c05616521}, {0x000d995f90f64784,0x0000e16cd8cf737e,0x0001408ff0413e3c,0x0009c3a4f30dedcf}, {0x000a0a6b443a170a,0x0006e0cc49b5c711,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ac308c74d834c,0x000a8dd825f7406b,0x0000fbb496f34b0d,0x000075e1de870fb5}, {0x000227841bcf2365,0x000b8e05ffd3c983,0x000e33dc39c86d83,0x0009f0fd6d0e74cb}, {0x000d62a5a8904ae1,0x0008c32b1e28056e,0x0000000000000000,0x0000000000000000}}, {{0x000d2a2671b67c79,0x0004494c1cde5597,0x000c0326e9105031,0x000b1ee150606033}, {0x00061f18317b0423,0x000cc474ed398c9c,0x000df4796a972375,0x000696b52ef07eb4}, {0x000ed96071372ae4,0x0005ffabf9d1feb1,0x0000000000000000,0x0000000000000000}}}, + {{{0x00045b8e28f19059,0x000286054435bd90,0x00012ddcca1e377c,0x0009f510d747b1a8}, {0x000d3775c0ea63eb,0x000865c7834fcce9,0x0007bbad37d19f75,0x0007bbc7cb402eb6}, {0x000530a0f5327111,0x000908600a1a8bd5,0x0000000000000001,0x0000000000000000}}, {{0x000abbe5e02132c6,0x000b17b10fe3c6dd,0x00011b655993587d,0x0008aa4f1c163208}, {0x00092e7539751ad7,0x000229bfb751c187,0x00003ce5719f77dc,0x0009dd5c3eedf84f}, {0x000b8c257bb9c60b,0x000345e60da1b9c4,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e7d40935779ea,0x0002b583ea2a70e6,0x000137328e54c9ba,0x000501ecd4654390}, {0x000e5d733683ab93,0x0009f374dd118e98,0x000b90700d407bd8,0x000c13b0afb65295}, {0x00048095857db6bf,0x00070895fc47c66b,0x0000000000000000,0x0000000000000000}}, {{0x00037df304273762,0x00053684543a49aa,0x000af1483095c127,0x000176dbbf08a1c2}, {0x000fbbab267dccb7,0x000bd6efdfa7bbd2,0x000abfc8aeeb27ea,0x0008c902ad03e86e}, {0x0009e682a4e44e71,0x000fe0064991f1f0,0x0000000000000000,0x0000000000000000}}}, + {{{0x000aed77f4d8e151,0x000d64f6fa111299,0x000d4feb2e79c04e,0x0007b4f97a120999}, {0x000d370550af65d5,0x0001340660d07357,0x000084ce4afb7c64,0x00040826e57205ac}, {0x000a7fc0bae197ca,0x0008238f07d6803e,0x0000000000000000,0x0000000000000000}}, {{0x000454a02cb353a2,0x0000deb5cdf6d6af,0x000f3bb89c8b32bd,0x000b355a1bd8c3f6}, {0x000e63db355ab5de,0x0005c6b3982f043a,0x000910f0e90987dd,0x0001380521adabe8}, {0x000fa044a4bf6a24,0x000fd8fb752ed23d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fdd1be70b4926,0x0009a826f6dba658,0x000cb4e95121bc79,0x000f676af00f6eae}, {0x000cee75a521d56d,0x000eca7d7729d333,0x0002e5027fb68ac4,0x0004a49aec5f206d}, {0x0006a988faa272aa,0x00047f341efc691b,0x0000000000000000,0x0000000000000000}}, {{0x000df0f078415461,0x0006ca3afd9193e6,0x000e7785c7d78268,0x00030f1e3c2a9148}, {0x000aaa49f1fa54c3,0x000e96229782ded4,0x00093b6b845da08d,0x00020729c99179a9}, {0x000904b0df8fef02,0x0009cee6016c6aad,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=50 [{1,2,3,..,}]*([2^200]*G) */ + {{{0x0008c22f80cbfbe4,0x000130943a347193,0x000e2773aac837e8,0x000010c64a3c4f46}, {0x000be2b750229f24,0x00007131ff138446,0x0000ce7731813b90,0x0000e94672d6c2c9}, {0x000dcb075dd149a0,0x0006d07531381b69,0x0000000000000001,0x0000000000000000}}, {{0x000b38c7be8e6de0,0x000a9739ced7c6b6,0x000a61fbc4fb63d5,0x000fe4d18f6b6bae}, {0x000bd6ae1dbab075,0x0002c3dbf8c1ebed,0x000b0516dce109a1,0x000e4a2962c4c087}, {0x0000db685a1e1733,0x0001ad9f800e79f4,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003feea78bb9ff0,0x00046e4fde5cbe66,0x0003f440437dd027,0x0002a08933232942}, {0x000e421f2f6038cb,0x0008d7b95a50b4f0,0x00073ae18c0b0f4a,0x000bc9451cc035a4}, {0x0005154ba8955b22,0x000d349d1fd0859c,0x0000000000000001,0x0000000000000000}}, {{0x000f04652c1a8bcf,0x000b73e19db868af,0x000eea574f2961dc,0x00027664f8c3e1f9}, {0x000839b512b73f43,0x00002a0ec5b683e4,0x000b38a0fb615a0b,0x0001b1e55bb87991}, {0x0003094173f71955,0x000d3c0ba8f16419,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ed0fcb63247bd,0x000c61e26950f920,0x0008ac76960a5916,0x00049cfc2ae5b02a}, {0x0008cda5eb1a5171,0x000118595b5c8f4a,0x000c88e0004518e9,0x00089dcbce699e0c}, {0x000dca7cdb0b0583,0x0009678f7a0d455e,0x0000000000000001,0x0000000000000000}}, {{0x0003e3080d452c74,0x00067cd9ebc5ab77,0x00092748ad132f85,0x0000eb812f890896}, {0x0009083d0c649d6e,0x000d13cd26dc1732,0x000539d6815ffdae,0x0007727168b4775e}, {0x000ad256509166ff,0x0001747a36c1d3bf,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e6e936a559258,0x000787f262712646,0x0007ee8f55296d6c,0x000b44326540e78b}, {0x000ef2fb8850453e,0x000e4739b6073a9c,0x00032c19bbfb39a0,0x0005bec805ba5b65}, {0x000b74df44331c49,0x0009d3002e8ec8ed,0x0000000000000001,0x0000000000000000}}, {{0x000d7ba6c48685b3,0x00073d4bae18cecb,0x000a9e818b43a66d,0x000e109d5a439da7}, {0x00084e2bd60c3422,0x00082785ad715748,0x0009a5bf6bd330b4,0x00066c8383da8c0c}, {0x0009a00bf0007cc5,0x000256a489783e2a,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004a8e407a2ccd9,0x00086ad221fba29d,0x000fddda1e9d46ad,0x0008643114fcb5bf}, {0x0005a60db0e24f96,0x000659be98b0468c,0x0000c785c91bca8a,0x000b1e072204cabd}, {0x000ebbe04d9453df,0x0007688aef77cf50,0x0000000000000000,0x0000000000000000}}, {{0x000b62e349b426c5,0x0004467872d194b8,0x000ddbd4e1c43334,0x00024117aad0f260}, {0x000ea7d8cfb9c423,0x00083e18f4bd6c92,0x0008dd5687682258,0x000359ac483a7289}, {0x000ec708225923bd,0x00062148de2e57ff,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004d07f78796d38,0x000a0307a33d42f6,0x0008948a2a44d434,0x000f90db03ccc6f0}, {0x000696ff7592ebb8,0x0007ff2ae969af49,0x00014fcec7fca3c8,0x0000d6cec6f56874}, {0x0009ae9c6b325541,0x0003ea961c98239a,0x0000000000000001,0x0000000000000000}}, {{0x00084bbf91f7e4e9,0x0009ac472d023742,0x000d63ca5a686ea8,0x000614346cd552ac}, {0x000072fb24ab8e61,0x00080d3677dc07d1,0x000c8c0d1833f7c8,0x000717c50635d225}, {0x000f8a2192bf84ae,0x00027f2e83c678c1,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007ea965c0d1be3,0x000dffe0762dd1bf,0x000d60aa7917e003,0x0002fc7262c54da8}, {0x0004421eaa7edfa9,0x0002c86ea7ff6dc2,0x000473729f82d5e6,0x000d535c6df46821}, {0x0004bda6bb69bc00,0x000b33f34e260149,0x0000000000000001,0x0000000000000000}}, {{0x00096ecec3563dba,0x0004fd12da169210,0x0002f945903cc5db,0x00014cb4c4f95586}, {0x0007af70f6fbb150,0x000a6967e23d80e4,0x0003ebeadb489f20,0x0006a009490665a1}, {0x000afaa96a28958e,0x000a31da82221f9f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b5dfd8f4cc713,0x0009de59f2c453ba,0x0000c9b2cc1e3fa6,0x00033c17b6318b0b}, {0x000e92d5d399a56b,0x00008f8a6f6dc3c1,0x000b7f39e28633ff,0x000ff1fbcd4351ff}, {0x000013e8c77388ee,0x00066a953e5ebf9d,0x0000000000000001,0x0000000000000000}}, {{0x000bfd2f419a3879,0x0001d195e5a481bd,0x0001ef3e1ae017a3,0x0008b706b5b37267}, {0x0003f748e8ba9898,0x000e9de7d3391698,0x0007cde6e3e3c930,0x0009ee4ca324e7e3}, {0x000b6a772ae3cdd9,0x0004235fda48d82f,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=51 [{1,2,3,..,}]*([2^204]*G) */ + {{{0x000ce56e11c7765f,0x000fe4cfdef6377d,0x00035b399363df3d,0x000ca630a715e9e9}, {0x000a21011f820ffa,0x00022d3bc633f64d,0x000dab0c59875522,0x000dc95736a8523a}, {0x0008fef5b787c715,0x00032a66393c6305,0x0000000000000000,0x0000000000000000}}, {{0x00034ecf897f6f48,0x000d40891f4ace54,0x00051c5f6bf7708a,0x0007ca62fe89ee25}, {0x000eae6011a07c37,0x000028c949d24cd2,0x000ab99c094a1a4d,0x00031fed19d9cf84}, {0x00051c154036f7f0,0x0003d437b50c3205,0x0000000000000001,0x0000000000000000}}}, + {{{0x00036aa0bf5fef4c,0x000b4bb069d26c89,0x0002e3dd1d0d3718,0x000bf3daeaaab400}, {0x00076315a34c426e,0x000eb5f38604c676,0x000805197e2eb1b1,0x00037226db1abc31}, {0x0009ad73df5e17eb,0x000d3797d098f510,0x0000000000000000,0x0000000000000000}}, {{0x00082cf0882acea0,0x00006b48806f5a59,0x000abd275055f094,0x00049a504db94328}, {0x000ec38e43c40b3c,0x00082b99e608d386,0x000cf443b07fe475,0x000b7186cac29089}, {0x000d982cfac474a1,0x0009aa7b0368d422,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006f1287e600c1a,0x000cffcc5624ecb0,0x0002d1ca07fb78a4,0x000a1f9666cc7bc9}, {0x0008539fb634b6eb,0x000c73e361397798,0x00014a496c8d68c2,0x000d7ca4181be620}, {0x00069a299a451732,0x0001c06004061fe8,0x0000000000000000,0x0000000000000000}}, {{0x00029e4b308242d0,0x000a13eeecee128a,0x000f659548ea451c,0x000490cf14707b99}, {0x000362f80a26ba79,0x000292eee64971fe,0x000871b89c8fc38f,0x000d6dc0d122e55c}, {0x000979f11919fbb1,0x000f85c98fe350a4,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006cb60e51b31a9,0x0009c2f6d82cb3ba,0x000f86e04fd98949,0x00087bb6cb66fb0c}, {0x000cb7e6257cf354,0x000caa5a38dbe642,0x0007ff70132dd977,0x000a9fe7cec8cf0c}, {0x000f2a9f98b24a15,0x000c7552eb7ce954,0x0000000000000000,0x0000000000000000}}, {{0x000aec9e842f8ae5,0x00096d766fc55447,0x00099065768ced0e,0x000adad9493166bd}, {0x000c328be045e2b9,0x000e70d305222a08,0x000ec1d4f554727a,0x0002fed1873d61d8}, {0x0001c46d541e23d8,0x00042ef348b3f19f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ccf976377d19f,0x000f1cf68ff2fc1a,0x000d98b274ba0faf,0x000788c074f0bd37}, {0x000a798f5cd04250,0x0003cafaaeab508b,0x0009fd1e881c2856,0x000dd63706ee8361}, {0x0001b79794f0ad14,0x0006f33d5c0505bc,0x0000000000000000,0x0000000000000000}}, {{0x000090b50612a9e3,0x0003e3a662f706ea,0x000cdebf25eed8bb,0x000d3a7d888eb094}, {0x000fdc87a6c4d17f,0x000574531e25001b,0x0007e6d823c00762,0x00014c6a486f9d98}, {0x0006d2d6573a4d0f,0x00074c191e9a8851,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d58220482e6f9,0x000c77488e8bdb82,0x000ba1084c7aabd7,0x000ae76567c7272c}, {0x00079ab82a151ca6,0x000826c75c1ca84a,0x000434806316ad0a,0x00040dd7f329f3c6}, {0x00033bd2dde3d6a0,0x000c43689c3e453f,0x0000000000000001,0x0000000000000000}}, {{0x00061be6ee98af37,0x000291b8361cc48c,0x000b8a7b622624c3,0x0000547d4c3e4e24}, {0x000c937a21d5f3c1,0x00007a153ffa09bf,0x000a63d54fa325a4,0x00048d13bea75c7f}, {0x000e1e55bfb7c45a,0x00055a1a8b85312f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000094bb55dffec6,0x000b1ee483a0b1a7,0x000e63531718eed4,0x0009354c0be15b59}, {0x00029a3b937fed84,0x000295e4506353d0,0x000205f7b6d68fbd,0x000e59b3375fdbda}, {0x000b4aaddd0cb573,0x000348c879da0f51,0x0000000000000000,0x0000000000000000}}, {{0x000afd066ea2106e,0x000ee293d8c45af2,0x000bc67374a1f66a,0x00016d7c0fd1fd2b}, {0x0002493231dcd541,0x00019502a277efda,0x0003c7872e2fab64,0x000a95c3d06567be}, {0x000fa48d7ff41d2a,0x0001cc69c52d2e6d,0x0000000000000000,0x0000000000000000}}}, + {{{0x00046d25ca0b12ed,0x0003e7af11f36102,0x000d246f5c00ca56,0x0005f2713dbda22c}, {0x000571517fe92c1f,0x000e558aff5b82f3,0x000852ec7e4811aa,0x000a0a7d7a0cfe93}, {0x0009a571e80c69ef,0x000d5ecf0c8dc85a,0x0000000000000000,0x0000000000000000}}, {{0x000629e0362ea61b,0x00019570463933fa,0x0004d8bdb2997e91,0x0008d16c1670ff63}, {0x00042ac0e352c375,0x000bf5c218c31489,0x0009269789d4077e,0x000eedd9111468df}, {0x0009e59bdc949bb1,0x000694a97ced001c,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=52 [{1,2,3,..,}]*([2^208]*G) */ + {{{0x0000e658f63653aa,0x000362a4e263b15e,0x000f1a72f5cb787e,0x0008dd85ade21c8a}, {0x0009351d6c477346,0x000ea4254fd69f8f,0x000c982ae15e0af4,0x0005dd836935db86}, {0x00023278398d3a2d,0x00082c5ffb0769dc,0x0000000000000000,0x0000000000000000}}, {{0x0002ae6ecd27779d,0x000456043db3d94c,0x00073642e7c09230,0x000692df6f9dd795}, {0x000422cd985762a8,0x0006ac0a49a83e72,0x00059cfa2e9e20f1,0x0000d0093708d3fe}, {0x000c84d0b10a4692,0x00035fa5bda12a10,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009924edfb9aeab,0x00028a46d2968a10,0x000fe84ed7a9147a,0x000478aa49744c91}, {0x00030fd88965188e,0x000dc8d99e65a34f,0x00006f221fd955c8,0x00027ea7cd997402}, {0x000f83ab9dedce89,0x0006e8a7c26d23d4,0x0000000000000000,0x0000000000000000}}, {{0x000728e182c8cb8b,0x00078b0fa5f32091,0x000760a4e2a3ad9d,0x0002b50f65aca369}, {0x0003d46ee027e681,0x0005a7e2b8db993f,0x00003752acac076e,0x0003a179054a6029}, {0x0007bff0fddbfa0d,0x0008feee0dfeeff8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e1e66266af2df,0x0002e36c081c96d8,0x0002c3c896d714ef,0x0002acfe977ac59e}, {0x0001a95d1b3f90be,0x00003c79555da335,0x000ac68d1f4138b3,0x000d2dc5e8301aff}, {0x0007f5144ad06837,0x0000d0ff81349a59,0x0000000000000001,0x0000000000000000}}, {{0x0003ebad0af48caf,0x0005e5d9aadd9976,0x00026bfaeb96c7e8,0x000c9ceb03564b50}, {0x000254586ab1371e,0x00038a2ddf7b0228,0x000ca35a77209961,0x0003fd9f60e7f5a6}, {0x000f0eb7073273c4,0x000a1bce76f5e62d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a60a63bd16196,0x00077f090aae19bd,0x000e7638c32cb3f5,0x0002a6ddf59abf93}, {0x0001d3548613634b,0x0001b5e6513c50db,0x000b5bd49476ec89,0x000a83b636d2f4bb}, {0x000071e3a3dd95f7,0x000ef977c02f69d5,0x0000000000000000,0x0000000000000000}}, {{0x0008603799531d83,0x000ec49c9ad3cfc6,0x0004e50cb9635f1e,0x0003ca9d26b39588}, {0x0006f3bd6a0e5d70,0x0008ef03a93fe903,0x000aad2605b0ecc0,0x000b6abd3a9b070f}, {0x000a81977f3494ea,0x000831164f95f67f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d576c129bba19,0x000dc781b1958f67,0x0004c725830444b8,0x000d772989a02957}, {0x0003160191e1f14a,0x000b3aba62ef31af,0x000a9c026782cae3,0x0005e2df9de1d797}, {0x0007d5d393897669,0x000e09de2e3f7f60,0x0000000000000001,0x0000000000000000}}, {{0x0002f590d9230f6d,0x0008e59ce71ff8f2,0x00065bfab0b97ecb,0x0005b773840ae894}, {0x0005df550efa55da,0x000a03525e361e4f,0x00032a275d9fd4c6,0x000f30d16226c4bb}, {0x000512eb88ebc1cc,0x000a048dd37790a6,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005c82e7c82fe0b,0x000b6b153f48688a,0x00079cad28ce32c1,0x0004dd65d7330f19}, {0x0005fd6ce0841643,0x0004ad25ddac7886,0x0007705833e0df48,0x0008294753bb4502}, {0x000ad8dbbbf63937,0x00019b436c10a463,0x0000000000000001,0x0000000000000000}}, {{0x0005b7516a304d40,0x0008185865f25816,0x000cfc1c163a4965,0x000ed7eed35d77f6}, {0x0002d2246fce8e80,0x00064fa59660ff02,0x000081304ce77dc8,0x000c6fc813dd85ee}, {0x000db13057fabb84,0x0008d66a509ef64a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ae85bb3c1e90e,0x0001923787b4a031,0x0009e575e9892a6e,0x00074c2ebb769eea}, {0x00063064d9df4bf8,0x000e1bf584f54d2f,0x0007ecc49f863e83,0x0003213fe023848a}, {0x000c07e3d527042f,0x000c51626ab6da53,0x0000000000000000,0x0000000000000000}}, {{0x000783a377f5ac26,0x00010cfafa402a74,0x000f762b70abfb39,0x000eac42e208b3a1}, {0x000497274db0b567,0x000b54ede1f18ddf,0x0001de4808fda6ea,0x0002ceac81237a87}, {0x0007edd6e7428e9d,0x0000cb9fb5801abb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000205d81676b493,0x0001cfe8f546e257,0x00087afe8b644287,0x000676bad5e346c5}, {0x000f4a964afa3748,0x0001422f71ca39ba,0x000328b0e9e0a58e,0x0001d31cca18d62c}, {0x000787f6507714d7,0x0009ad810168e375,0x0000000000000001,0x0000000000000000}}, {{0x00030f78aa1440c8,0x000f7e509d6354b7,0x000beae80e0ec14f,0x000f7cc09793053f}, {0x00025b6b1fd1b019,0x0004558d48e4fca0,0x0002aae7ed4a0374,0x00070e2db1c48699}, {0x0007f4b02f033375,0x000af43011764955,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=53 [{1,2,3,..,}]*([2^212]*G) */ + {{{0x00015e37a2d438c7,0x0006bb436c808cd7,0x000782325918615d,0x000d68ce58c6e6b2}, {0x00075a40e8f75ca6,0x00001da381c4c378,0x00055d9be962879c,0x00075dd3d4cf58a1}, {0x00099fd85847d5de,0x000e158f7f76b4ee,0x0000000000000000,0x0000000000000000}}, {{0x000c9f66a4cec18d,0x0006e45302a76bd4,0x0001b679cdf64708,0x0002c24293b84a7e}, {0x000a092243bc4d41,0x0005c3c375519ccb,0x000d06b585371f2d,0x000590f4c0f28ba3}, {0x00073b4091daa768,0x00073c6342e78bf5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dcb7fa9fca3c3,0x00047144679a2a9d,0x0003be369b38069c,0x000a82620de84dbc}, {0x00098d5e1f28d82c,0x000205de8989e877,0x000abac84051f10a,0x000ac26a5b9c5c22}, {0x00074ecbb99bba5f,0x000253359fa6c2dd,0x0000000000000001,0x0000000000000000}}, {{0x0002ac09a82c210a,0x000b422ac08c572e,0x000c5c720e071535,0x00095966a7bd1c3d}, {0x0003a0a4b0c9e18f,0x000faa6c6449a62e,0x000bdd44f85595c2,0x00047bb9f75f529c}, {0x000f46a6493955cf,0x000622defa5af650,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006df335e8acd01,0x0009b6996f91a727,0x0008be8a5f6bba5b,0x0006ef24a13311be}, {0x000b7fe2a95d51f2,0x00084a38b4ee11ba,0x000caf93233a4f76,0x00073771e4762ff2}, {0x00024adb050176c1,0x000a9e7e6a96ea5e,0x0000000000000000,0x0000000000000000}}, {{0x000540fbecee1541,0x0003f39f444fded1,0x0006ce01534c5cef,0x000a886125f5b460}, {0x000b437e2199b1d8,0x000a994fb5a77157,0x000fcae599e6b65e,0x0002599cf24da91d}, {0x0009f0d7248964c9,0x0007ac171d21915d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ca4b8955dde0b,0x000f850c9b5cc251,0x000b99572d6cb500,0x000f8952b82356c8}, {0x00088575ebe209ee,0x00089253a4607df2,0x000ff9ba421a6b33,0x000799f0eb4dd513}, {0x0003ed789c84b56b,0x000293e6a5c4d425,0x0000000000000001,0x0000000000000000}}, {{0x000ff217c0f18530,0x0008986930ae0198,0x00012fd1e778abc5,0x000f509594fad4d8}, {0x000656733dccef2f,0x0006afad83f10fab,0x00078f717d75c593,0x00018a1a313cd995}, {0x000cd73871602741,0x000f5446078ec40b,0x0000000000000001,0x0000000000000000}}}, + {{{0x00034871165b0407,0x00041aa1bdd6d509,0x000fcc9e894c7b1e,0x000369e1389494fd}, {0x00087f5116c5472d,0x0000a1b0d04b3663,0x0000b4c49058303b,0x0002bdbdc1d8cd26}, {0x000ae8f01c121d9d,0x000dc1d8c7270b76,0x0000000000000001,0x0000000000000000}}, {{0x000d922f0e06b7cb,0x000f07bd16843c5d,0x000c01dd32245ab8,0x000fa9f6081477df}, {0x000c2db624f56ea9,0x000b2fb3e2bccdb5,0x000cb3b768793cb3,0x000c8d894f04384c}, {0x00010a3af20b15d0,0x00045ab5af8411db,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006b9ed8590e4a5,0x0008a58a2974d283,0x0001c7668bc64c35,0x000acc81cd837cfc}, {0x000fc7b9eb02f729,0x000fee9d6ad1171e,0x000a8d7ca7eeb433,0x000a79ea2e79ed5e}, {0x0001fb8522e38381,0x000cc8162a76e7a5,0x0000000000000001,0x0000000000000000}}, {{0x000c67543c98a4ea,0x0001f713941c4de6,0x00081dc75d38a3eb,0x000374ce9c459cdd}, {0x000bdd7ff2d1d555,0x0000d7b03a560a54,0x000ad6193d7f976c,0x000099ff27e977d0}, {0x000749edcba5d394,0x0002c6804ed826ed,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003e3bd3291cd15,0x0006a26271a72635,0x0001ef4581082f50,0x000cb6109637a812}, {0x00043e376f158b63,0x000e1fb8b4f92150,0x000fd4238523b166,0x000edb09ffe09019}, {0x000a7d8e27b82fb2,0x0001989a4df94f9f,0x0000000000000000,0x0000000000000000}}, {{0x000410feb007ca74,0x000ed314198cb45e,0x000e234a35b4b72c,0x000c1779579fdfb5}, {0x000da54f63558ebf,0x000b68211f279305,0x000b7f7a88ea265f,0x0000914728cae4ca}, {0x0002ed65205137c3,0x00045ed6df45a086,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001cfb71cb23bf8,0x00067b25479ac001,0x0002f48bcdb785ff,0x000da267c454fd25}, {0x000154e460f65f62,0x0006fa21e0ac759a,0x000770bdb56d239e,0x000db91d7ccefa07}, {0x000f07f46fe275a8,0x000527a152927368,0x0000000000000001,0x0000000000000000}}, {{0x000969a0d74d64a1,0x00059c36f066b2d7,0x0003a664061d81a7,0x0008c41d929c3e1c}, {0x000a4033ad63b5ba,0x000387b665fdb5a8,0x0002e2c2b433c84f,0x000e4f2d4d931e74}, {0x000631141b030d2d,0x00086de3845c248d,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=54 [{1,2,3,..,}]*([2^216]*G) */ + {{{0x0000c039d020c1dd,0x000d44ab7b690765,0x00026b42700b4f64,0x0002c1e20576d051}, {0x0009e70d2ad712c7,0x00015f46314322ae,0x000dfb189904b573,0x000124905a45ef02}, {0x00026cce68a7b470,0x0004ac5f0db2cade,0x0000000000000000,0x0000000000000000}}, {{0x00042cd205524778,0x0000d86fcfeb993a,0x0001cc7f2d2ee992,0x000c209546bdb299}, {0x000531516a6eab71,0x0005f1492f99e62c,0x0002cf5197ae7709,0x0002013e12e8e95c}, {0x000b78cb72aad7be,0x0000320e70b96760,0x0000000000000000,0x0000000000000000}}}, + {{{0x00011fae297851e8,0x0004f69afd113575,0x000ab322fa242843,0x000f361ecbe5e3de}, {0x000b7c1b08880d89,0x000a50aa80c1fbd2,0x000104d9e40537e6,0x000ed4f51df57fdf}, {0x0008a6cfbe707164,0x000f36d887e3d0b7,0x0000000000000000,0x0000000000000000}}, {{0x000365e7f9a5983b,0x0003c6129d87d996,0x0002952186a64aad,0x00009284f8224d3c}, {0x0007bc689c1d4452,0x0003f44aec2c194d,0x00057e00e7c6b2d0,0x000de28c9eb3f18a}, {0x0008b7de6fac4981,0x000009552159064b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000147285c5f1e84,0x00054bbe273f4c79,0x000ec66bd4d71c06,0x000771b4dd0505e9}, {0x0002d4c891619ed4,0x00021a0542316ff1,0x000ffae0c65ede48,0x000db678c0c5a23c}, {0x000bbf48abf05e02,0x00032691ff4f9e32,0x0000000000000000,0x0000000000000000}}, {{0x0004ec586f495f39,0x0007665c351b2d94,0x0003939c0c800e74,0x0000a9b2fe310474}, {0x000c05e63ba55b78,0x00011119c911cfce,0x0000043322972c9c,0x000235f5ba3b0c8e}, {0x0002b78daa0946bc,0x000a82622257dc22,0x0000000000000001,0x0000000000000000}}}, + {{{0x00053147b3b22c3b,0x00004897a83e73cf,0x000d11d0f510fba4,0x000de4abfcf9128e}, {0x00047095c92d56df,0x000f3cd334bcfa2a,0x0000038a5b6f4d4f,0x00095df73169a249}, {0x000aba80e663bcbc,0x000c64a47769e841,0x0000000000000001,0x0000000000000000}}, {{0x00004365a62c4cf6,0x000531a582938f21,0x00043321e6dc439a,0x00061253f7387146}, {0x0008352424fe3ee8,0x000a676302135902,0x000702fe71ab2ae0,0x0005f460396ca837}, {0x000882e04f7bce51,0x000f93d936239901,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dc17de84a8cec,0x0000802c374c6c6c,0x000bd6a5b20e3454,0x00046c40337b0f58}, {0x0003431d7aff9402,0x0001dba6a849292d,0x000f90b37486a260,0x000c12d61cbe41a0}, {0x00033f828782067d,0x000486ebc39fcd30,0x0000000000000001,0x0000000000000000}}, {{0x0006818da93cb68a,0x00039ef42673be02,0x00040e906d3f2e27,0x0000e1f1d8ecf6f0}, {0x000655c024d3837b,0x000417cf596708c0,0x0000946c57882083,0x00058942a1031702}, {0x0009752bc7086a40,0x000474bd8d65b027,0x0000000000000001,0x0000000000000000}}}, + {{{0x00057bccc2137aff,0x0003cdce9d3ef437,0x000021aa7d7b10a8,0x00014071804bf03e}, {0x0005009822fa479a,0x000c4d2fe91adecf,0x000bad18fc3b061e,0x0002ffe82ea4479f}, {0x000b0bed7b70c576,0x000d5c8a667da425,0x0000000000000001,0x0000000000000000}}, {{0x00036c22b574750b,0x0001a79beeade4d8,0x000d7c41634d28e0,0x00030d7e124715f6}, {0x000b28e33c4f983d,0x000442a0682ee2bd,0x0000a48a18cfc1f5,0x0009a6cb16376839}, {0x000ecc58844abd78,0x000383bd6682cba8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c36944a224339,0x0002221a86a3568f,0x000a933230388a55,0x0002ca0cfc1f186c}, {0x000051f24d4d5f8c,0x00053ac024a82a69,0x000e4e0b6761f2a7,0x0006b4a03fa98a0f}, {0x000862d5fd1d2058,0x0006922bcb9949cb,0x0000000000000001,0x0000000000000000}}, {{0x00085574f50da47c,0x000f8cb1192295a2,0x0002436f1d423eb5,0x000f6ae23f4febd2}, {0x000640f1f266f842,0x000e94d3498091b2,0x00016f1f4561f25e,0x000c6e303b526f4a}, {0x000bbc14e80ed7ff,0x0009ac6f957c1908,0x0000000000000001,0x0000000000000000}}}, + {{{0x00089a398d206da8,0x000e6a92326c61c3,0x0000b658149c80b1,0x000f4f6423067f4a}, {0x00022c96735aed5c,0x0003cb53c31cf4dd,0x000c7214b478ba14,0x000d3b1bbb1eb353}, {0x0005aa79b46f2e84,0x0007d44a4fa3d67b,0x0000000000000000,0x0000000000000000}}, {{0x000d31f07cf711e2,0x00031e5402e45d5a,0x0005565057819f0b,0x00050ebe214cdf81}, {0x000e63efd8e063fd,0x000c82d63ad808de,0x000d0ee39ccec300,0x00085249be7d39df}, {0x000e9271ab6c788e,0x000a727ffa3cadeb,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=55 [{1,2,3,..,}]*([2^220]*G) */ + {{{0x00061361be3ee97b,0x0006e1f3125658fd,0x00096b636a1d69b6,0x000b9e470c7ac9e9}, {0x0005bf9bb3617e69,0x0002050a8c1b1e89,0x0002213fa5a11a51,0x000bc2919affa249}, {0x000be1b1008d55c3,0x0003926dcf2c08c4,0x0000000000000001,0x0000000000000000}}, {{0x000fb57fda93efc6,0x0008276ce4aac2b4,0x0009277cab16292f,0x000e677dc90518a9}, {0x000ab0432d015144,0x0005d9214eea4408,0x000b8a649b20eb23,0x000b48a45d8a2560}, {0x000cf7d1d37dd269,0x00049d71a47616ce,0x0000000000000001,0x0000000000000000}}}, + {{{0x00034d86d189072b,0x0000b9475ac257a7,0x0003a9d12f132433,0x000adf08cecaa5dc}, {0x000dc33641cc3048,0x00040352a6bfcc4f,0x000dac876f01bade,0x00035bd7dfb06e93}, {0x0001d4494c0e1ca5,0x000219b51965b8b2,0x0000000000000001,0x0000000000000000}}, {{0x000f90e9be7f6998,0x00040776cb857a46,0x00031907caf1b517,0x0007040038843e17}, {0x00014b3c14ab5377,0x0008c99d12b47cfe,0x0001590d18daa185,0x000f84db2817d455}, {0x0008544bbc4d8f7e,0x000ee1752b595c5a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000718c9c3382876,0x000798d016412ea8,0x000c7059eeb3d459,0x000e910707afd251}, {0x000366ae603f57f6,0x000f1d424b7c29b3,0x000f4591f08b6d11,0x0004fa0b188406f8}, {0x000a09ce46dfa46f,0x000f3e1ee6193a22,0x0000000000000001,0x0000000000000000}}, {{0x000ef37aacfd9628,0x00044abc282a7b59,0x00016eca5fb04908,0x0002a4a0fa414af6}, {0x00010748c915edd4,0x0003d4af5a6f1ab8,0x000aff331ef86bba,0x0006d8ffc35ce768}, {0x000278d36b6c4e53,0x0006238f61ddd56e,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008204ec1fe994f,0x000a401febacf810,0x000a1fbe66e0a0c3,0x000654b72570b727}, {0x0007b5299d8ae343,0x00058b323a83e064,0x00034d13d86ee0d1,0x000be946224b7585}, {0x000a38321cb77d0e,0x000ea9b845ec39e9,0x0000000000000000,0x0000000000000000}}, {{0x00021327ccd07b3e,0x000b9c13edfc5044,0x000efee69b80c4b9,0x000b9736ce07a452}, {0x000de2779de28110,0x0009cb506b810433,0x00009831468d2371,0x000fb54615eed293}, {0x000a72f30895d360,0x0000822a939f9fa6,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003613a0bad2c78,0x000a2841479bab61,0x000ae853dfe64b3b,0x000c5d69d7d5f8f3}, {0x000913c023c98edd,0x000e51c064c2af1c,0x000caf23e811beb5,0x000a297f73a13e28}, {0x0002c2db1b2c63f7,0x000869272783c6e9,0x0000000000000000,0x0000000000000000}}, {{0x0009e33e7c2b0e8b,0x000a6e2930859a4d,0x00021c82319f96d2,0x00062855234b3a37}, {0x000cfe1e952c7999,0x0009fff526834c3f,0x00082932d66290aa,0x000ed0618b6fc1aa}, {0x000f51b1765d795b,0x0000fa7ad3a784d8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b99ec5345605e,0x000d705b03ab3b6f,0x000d514df02df673,0x000d979497926d51}, {0x000327f3cad9968b,0x00007b8edfa7bbd7,0x000fc5c1dee65278,0x00036db8f1709072}, {0x000d430f38a088d0,0x000f9df3373c9bfa,0x0000000000000001,0x0000000000000000}}, {{0x0002932b26523f7a,0x000a4698ce826d56,0x000d64992b915d43,0x000f137e0e1471fe}, {0x0006811a1c25612c,0x0007e5e74619907c,0x0000f455dcff6a59,0x0006fe503afcb4d1}, {0x000af47382daf8e9,0x00085e51a1e9e2bf,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c899ed52c7ebf,0x000805309ddc9f57,0x000f9ec0561000b8,0x0005599061be65ad}, {0x000c7c6ac2e8bdb7,0x000546a9f7f8f392,0x000b38f709f90fbc,0x0005b81ee256aa4e}, {0x0000cd9ffe3bb73d,0x000ad1e54f791392,0x0000000000000000,0x0000000000000000}}, {{0x000e432eaecfeb4f,0x000efd7d99d4376f,0x000ecbf257042314,0x0006524d0d11bf19}, {0x00070c070e8811a2,0x0009bb46ac80db71,0x0005deced6976256,0x0001f5d4f1996e7f}, {0x000c6d1bc35c855b,0x000b7fcfaf131b63,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007faf89dff5e6d,0x000701e289504c4c,0x000c21c143d7c67c,0x000b8b1051104808}, {0x0001a8547ea3f429,0x00042d1597643f8b,0x000c20d8e30463a4,0x00019700b9ca1322}, {0x000c7c74112313e3,0x00021d429e582d53,0x0000000000000001,0x0000000000000000}}, {{0x000df174dc25e320,0x000421f30a9c65a6,0x000cca7bd70734a8,0x000970e912f441c1}, {0x000b0da35c85642e,0x000fbc6108990f29,0x00004f9201a5ca87,0x0000b4ba5b8a0067}, {0x00032f15dd79c420,0x0001dcaa2c572053,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=56 [{1,2,3,..,}]*([2^224]*G) */ + {{{0x0009f88e8ef42daf,0x000fa3828b99d9e1,0x00051fa512ec2bee,0x0004d684d33e3c3c}, {0x000ae34a6c37abe1,0x0009d4bea55b5936,0x000e6492802583c8,0x000098da605bd938}, {0x000288cfc1f04542,0x000ed0659c47e455,0x0000000000000001,0x0000000000000000}}, {{0x000ddaea5046a68e,0x0003e422472a49b9,0x000c2da95690aefe,0x000dcef36e21cee3}, {0x000eab14f0abf0c7,0x00064941e198c3c9,0x000fcf64819eee0b,0x000dbfe77fa8433c}, {0x000c3b28a2f7686d,0x0009c3dbfd233403,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b7107c522fbbd,0x000c42e8887082c3,0x000cd304c29d218c,0x0004d8477a96d44b}, {0x000ecee7f483ff1c,0x000951d19c530d4b,0x000d68d4d6bf1fdc,0x000fe03d009b71d2}, {0x0005537694d3bd1d,0x0003c3db4cb1a2c4,0x0000000000000000,0x0000000000000000}}, {{0x00086f0e3fa15f33,0x000388caf5fb4c5e,0x000b2f14ba7715c3,0x0002610381191db4}, {0x000e0f68a08e3384,0x000342059cb75d25,0x0002bd292f767fcd,0x000a7a696b414dec}, {0x000dfb67016057d6,0x00035999c277b18a,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008ba73e1f475e0,0x000dd3f1b783f77c,0x0007375b491b116c,0x0007d166e4a377a6}, {0x00011bc5434f7131,0x000a2dbe9d40b215,0x0001220856a6b5e6,0x0007b890e757f7e0}, {0x000f02578a944660,0x0004883ff77008f5,0x0000000000000001,0x0000000000000000}}, {{0x000a3e2632a212b7,0x000302b8f038a3d8,0x000a306506181a49,0x000301702b3192c1}, {0x0002c30f8e6d2d73,0x0002a0c5b0c340d2,0x000f8bfe6e8c90fd,0x000e8d703d0478e5}, {0x0005135b5979aaf2,0x00034da81fa7add8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f16b10733860a,0x00007e088e20bfd6,0x000859fdd39b30d0,0x00096072d4c40b6e}, {0x0007d0a59d2a4c91,0x000f5b531a3c4f60,0x00005885c546c30a,0x000ddc1d5df2fdc4}, {0x00026f4df2971b1a,0x000bb67cb15104fb,0x0000000000000001,0x0000000000000000}}, {{0x000f74646d17eec9,0x000e3de3bee8f39f,0x000560fc63e96143,0x000d7aab2e0395d9}, {0x0003f099cc808fd9,0x000e3c3dca422f15,0x0002c61efabb0d74,0x0008d736943aed2c}, {0x000d74e4178f87c1,0x0003d1b76afadf96,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009583eea912fe1,0x0006a5587f3b9010,0x0002a020829ea8e9,0x000b82ec346b73a8}, {0x0001f44eda406972,0x00067b4504fbb553,0x000e7a6189bcd268,0x00039bdb40c39e05}, {0x0005c436a03e5e06,0x0007019eedb498d3,0x0000000000000000,0x0000000000000000}}, {{0x000662e3f77764f2,0x000cda79a7c8507e,0x00040c75e0594299,0x000bed938a93a1fb}, {0x000829d1bab3f2df,0x000df99ce48d52d8,0x00032fb8c4092f5f,0x000036b5fa768aef}, {0x000201a9ee7997be,0x000ca0344038e8d5,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004ae17c6c4ef83,0x000409ab5b4b2b20,0x000c4c863d0780e0,0x0003a003f73d00d9}, {0x000f7d17b97edd24,0x000335ec2eca6e6e,0x0007def3f246d97d,0x000f0e2518ced6c0}, {0x000f728fdb8b0595,0x0006dcc1ccb10bfd,0x0000000000000001,0x0000000000000000}}, {{0x0009f012dd02f504,0x0009d50a767d8e86,0x0001bbb0510be6fa,0x000cdab7deeebbfe}, {0x000f08332cdf98f4,0x000468782175d651,0x000610add0fc83f5,0x0004965277afa428}, {0x000ff5c3438635dc,0x0001fc0961df5b9d,0x0000000000000001,0x0000000000000000}}}, + {{{0x00069bd3ef1fabd9,0x00064fe7b00b747c,0x000195c6097cd6a8,0x000470709e13f896}, {0x0002cf79709fe958,0x000b72450de744f3,0x000df3f80fb1524e,0x000527ea0bf24b8d}, {0x0001b2774e7c3f06,0x00031ad38e7aad24,0x0000000000000001,0x0000000000000000}}, {{0x000b784c1f4489c7,0x000f2a889f589505,0x000a5a3175ee6df1,0x00047a68c157fe56}, {0x000497f7b784bd67,0x0005ed8ff0792025,0x0001528aca7e0427,0x000d473d7c41594f}, {0x000cb017e35b5669,0x000f1ce78bb2a52b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000290556eb6cb2d,0x0005feea12a072e4,0x000d082bac976238,0x0007c4331be16424}, {0x00021f06c7a59869,0x000de72b68a812dd,0x000652502f900697,0x000d9acaec02a2e5}, {0x0009120c4a89c7ef,0x000a1bdf713a324f,0x0000000000000001,0x0000000000000000}}, {{0x00067220e1027a34,0x000cabc964145333,0x00029a9fac99b048,0x0001c2850e9e757a}, {0x00057de9cc170cb2,0x000d017c03bef969,0x0008cbf0f3534a37,0x00085a627fd6a9c1}, {0x000c29da8ed78ac5,0x000ae4ef092acab9,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=57 [{1,2,3,..,}]*([2^228]*G) */ + {{{0x00060edf11bb374f,0x00007883a0baf3f0,0x000eb8cb2a326de7,0x00095554f5a8d631}, {0x000236ba14fb5cfa,0x00053769e29d950c,0x00043eac3b6e6d4c,0x000400e396b6857d}, {0x000b3b40a28cc2c6,0x000f0142ca52de79,0x0000000000000000,0x0000000000000000}}, {{0x000536d43744d95a,0x00080dbb696fec4e,0x00086879c7360fe9,0x0006d4736a564e15}, {0x0001262e7ce9d679,0x0004cced89ee75c8,0x0005fe2dd4f732cd,0x00004a4d97d2a3a7}, {0x000e046cc62def6c,0x000c590bfe781afc,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001e39da3d53729,0x000c68258dcf68b5,0x000b1289a021c50c,0x00028ef654112229}, {0x000f4c73b83c7489,0x000a0ebdbdf0df33,0x00033245f1663936,0x0006bdfac3bf0988}, {0x0001bcc9c21bceec,0x000bcb64a15de987,0x0000000000000001,0x0000000000000000}}, {{0x000fb2f27cba002c,0x0002f0ce8d66f97e,0x000c4f49e106a48e,0x000720d60d05177f}, {0x0001b9e35427304e,0x00008c355b746f84,0x00061577b7b7cd5e,0x0008586eb9a88122}, {0x00003b21c38ce383,0x000aec02872c5a8c,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003ee736c032ac5,0x000efdfdb4c3d4de,0x0006ff01d94dbf41,0x000a0bb5ee1889b9}, {0x0009e7a8dc456a87,0x000c2bb8ca379bb9,0x0000100b2eae0668,0x000d2063b0184325}, {0x0006daafabf5c71a,0x000da2051e835c68,0x0000000000000001,0x0000000000000000}}, {{0x000eaacab83acf78,0x000761a09a5ec30c,0x000838055c361c20,0x0002e34e4fa05860}, {0x0001b9a7a3c102c4,0x000f91746c97086b,0x000c731ba10529e6,0x000e8a7f6450292d}, {0x00076f3144af4061,0x00077cacdce041a7,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004b67237f032bd,0x0003fda08c68528a,0x000c719571479a5b,0x00011c75d8054fed}, {0x000bf503c35807c6,0x00037b9ea9e88e5d,0x000c9422b4c4521b,0x0002950eb17e75f1}, {0x0008eca427950847,0x000c0f845c91f923,0x0000000000000001,0x0000000000000000}}, {{0x000c1e80ea8c1010,0x0002e1978ae396a0,0x0002c0d00f914b24,0x0004e43fb47bf7bf}, {0x00034b416e50ae94,0x0007c8d114906c36,0x0000ad0347f03a3e,0x0006a6eba25165b0}, {0x00021e9dc53a14e2,0x00076911eb83f4f5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000bb95adc5ef776,0x0008da0ab8c5f233,0x000a4ab915fb3034,0x000423a63a5dffb8}, {0x00063715aa2304a4,0x000018304840df01,0x00037b80028296bc,0x000854f7402fb23a}, {0x0006ebdeaf3e5fac,0x00005463cd3d8406,0x0000000000000000,0x0000000000000000}}, {{0x000c9468fa481453,0x0003a0abd61a0348,0x00047c025f468b21,0x00090d7078cd984d}, {0x0005284e72a10788,0x000156fa2b542f64,0x0003b3c956017512,0x000991f2c57b982f}, {0x000989b3c05c1c45,0x0001ce6eb96dccdb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c0c76c91a3d86,0x00001a3cab8eb5fd,0x000752ec9cff796c,0x0003f81d37bdda1a}, {0x000e12c746df5d95,0x00027c38d512fd50,0x0004e23ce093d983,0x0004adeb3545f200}, {0x0008acce0db1764a,0x0004097d3ea0eee0,0x0000000000000000,0x0000000000000000}}, {{0x00057c8acd0df62f,0x000a235a3f7e354d,0x00043547a0eeee98,0x000831405ee1adbc}, {0x0006a916c043f6f0,0x000e4844ab1da766,0x0000728cc7b74a71,0x0007192544b4fdc6}, {0x0009d41decd4aad8,0x000497605d2bc303,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c16253894ed63,0x00072cd0f6a2350d,0x000412983f7baee8,0x00009f78d054975c}, {0x000d7bad42e9614f,0x0005f2ac60d67eaa,0x000622d671f099d8,0x00021f07bed1e830}, {0x00081424aeea7845,0x000f7592014c5f2e,0x0000000000000001,0x0000000000000000}}, {{0x000619d3fbb4d7a6,0x000a9269d1beee9e,0x0002e4ef27debfd4,0x00069156fc40ac5c}, {0x000b31c86af27730,0x000f4aa3fc30b8ff,0x000bfd86f500b895,0x000c9dccb88b68a2}, {0x0003b7832b9f66f8,0x000853497ba1895e,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000b0ab29d3bde4,0x0009c71ea0d8e5cf,0x0004b6204df30d49,0x000d3f548f748b9e}, {0x0006eba95c754c4d,0x0007ad6cc9c44387,0x0009e2d08e10896d,0x000ea9428b4a544e}, {0x000fe71891a2d3e1,0x0006b905c7660eb6,0x0000000000000000,0x0000000000000000}}, {{0x00066e6414125179,0x000e2877106f8fb3,0x0002d9d82f542b36,0x000b4eca63743c2e}, {0x000cfc887146aaf2,0x000ed669e0b28d08,0x000c885c73913714,0x000914ee1f56da28}, {0x000d4479d84424da,0x00015e3364622742,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=58 [{1,2,3,..,}]*([2^232]*G) */ + {{{0x000bd25b5edea690,0x000347c3abc5bd1f,0x00078a11d29a3138,0x000c6d62f2283223}, {0x0007b4af4ece3ada,0x0001c75e4372b0dc,0x0009560a7308e28f,0x000d0ea7127d9913}, {0x0000172da9cb3c31,0x000c36c69386a7ee,0x0000000000000000,0x0000000000000000}}, {{0x0003be2a2cae0b56,0x0000778293313929,0x00041cdee07af8d3,0x0000895f4118b415}, {0x000b9b3a9502ad6d,0x00004e1d44242767,0x0001a843924f3834,0x000a3c5c40dce7a9}, {0x000443e9e0f30db5,0x000c5338df60b62d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d88264070b39a,0x00060f5a265bdb95,0x000717063ef771ed,0x0004ca000dd813de}, {0x0005a4d348196d97,0x000def16129d2691,0x000bcbbfcdfb3523,0x00057290d6981eca}, {0x0000c5d2444e08c7,0x00091c65a063c65c,0x0000000000000000,0x0000000000000000}}, {{0x0001941d0c9b7cd3,0x000cc0a5845e0e75,0x000c51c09cc90c04,0x000ce8aff11f3a2b}, {0x000303944ca09536,0x0005cb9d10d614a2,0x00062674cf73a00e,0x000639b5262911f3}, {0x000379f49e681d43,0x000ea07634bb0927,0x0000000000000000,0x0000000000000000}}}, + {{{0x000aea3b47740815,0x000ede22e76e20e2,0x0007e03afde6eca1,0x000f70d608d1c44e}, {0x0000b88d585444ed,0x00074d298cd8ec39,0x0001146c4c3f6754,0x00073274110e9ce2}, {0x0009cf1f4b12ae7e,0x0004fa67e9f4b4ce,0x0000000000000000,0x0000000000000000}}, {{0x0002ef9318bf7948,0x0004cb3efdaff610,0x00059bd31047a8b9,0x000fad7c4b8b1235}, {0x000a02488482725a,0x0003b462badd939d,0x0009f8945cb99ab4,0x000c0f6b65c66a4b}, {0x000e97dd0bddb4b1,0x0009d75a1f797639,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000ec0aca9d0f94,0x0002fb13ee984570,0x000e5ad047be55b4,0x00073a0845bc6993}, {0x000ffee41f2aee8f,0x0003c832041ac680,0x000bb4a740b12fcd,0x000521ebc1645e36}, {0x000dfcc7735a45c9,0x0008ef92b0fbdab8,0x0000000000000000,0x0000000000000000}}, {{0x000805ed4e45e0eb,0x000584829d754db5,0x00036cc488a6c810,0x00060f1ec9632468}, {0x000c0f2ebc30d39f,0x000e960758390502,0x000f4626d1feec9d,0x0004f944bca363ad}, {0x000375dbfdeea282,0x00050ba887d0959c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000857ce82a61386,0x000fab480b18fa40,0x000223002b9297b0,0x000f9b41f698e6a5}, {0x0005eb688e33b253,0x000cc09f30bec2ad,0x000eeb6333a5ffe4,0x000bc81e94524303}, {0x000091b660b277fb,0x0008fd03ed404dad,0x0000000000000001,0x0000000000000000}}, {{0x0005dd59faaf5be9,0x000abe017edd5410,0x000aaa4856720e0a,0x000d987f4b1178d8}, {0x000fe5e556ef405d,0x00081f659d8f4002,0x000f7836cb450ed9,0x000350d35c2f69df}, {0x00095c15741d4705,0x0004c982d30172da,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f854cfa0f1b9c,0x00036c27f5709e7d,0x0002fcca4c8efcec,0x000a965fa53691ad}, {0x000f70705ad9f4c9,0x0006ca89080d5043,0x0005cff60c807ea8,0x000ff2e47ec8fa95}, {0x000846288bda4094,0x00003dd7b4f68fa6,0x0000000000000000,0x0000000000000000}}, {{0x000c953f0c60b7aa,0x000060469787d616,0x0009579f0ed52085,0x000faf3c529ad3be}, {0x0006f18223d47482,0x000c07ac1ad869d6,0x000437b5cb0dcd56,0x0004dc765feb592a}, {0x00004a294944df05,0x000184cb4ad2de82,0x0000000000000000,0x0000000000000000}}}, + {{{0x00003d153000960d,0x0008f85dc5ffb696,0x00009b3d9302c4f3,0x000fd9668bf9ae36}, {0x000a25bdc3c8ecf4,0x0005c1a7bbfdb2a9,0x000393a4a4463083,0x000a4d41df85c97b}, {0x000d92cc6610ea8e,0x000bee7a14446540,0x0000000000000001,0x0000000000000000}}, {{0x000fe7092ab307cd,0x00055b75f48236e0,0x0009f206af987311,0x000191b95f1aca72}, {0x000b01a57a7e9b13,0x000784300caa5513,0x0001b4e8ad08534f,0x000e7a92df980dd1}, {0x000edd78871ce4ff,0x000f2fbe3e6a8b6a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cf8b0ae3366de,0x000c06074154422f,0x00007a17d21e5dad,0x00001e78c237ee85}, {0x000d108f5fd2183c,0x00098eec2dada49a,0x0001c303e35f7659,0x00091f2075445a12}, {0x0007426d8f5fdddb,0x0006af1dd7a92c53,0x0000000000000001,0x0000000000000000}}, {{0x000c31da2f658936,0x000e72228504949a,0x0007646877ed3189,0x000cbac9e04fe426}, {0x00093f8802494ee0,0x000975ea85d9fdf7,0x00038fb0c9c6045a,0x000802b88cb118cf}, {0x00057e39ea12c877,0x0002548e571e0697,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=59 [{1,2,3,..,}]*([2^236]*G) */ + {{{0x0001f89eed993384,0x000860d77e7f7ed9,0x000e9a249862cf0f,0x00026963705ade19}, {0x0005d0f929eafa4b,0x000a12f7eef6f18b,0x0009d590ff1861d1,0x000d6b67d2954ef5}, {0x000540dd418bcbd0,0x00096e83b51e5170,0x0000000000000000,0x0000000000000000}}, {{0x0000a67de6f33ef5,0x000d0f090cb0d50b,0x000b8b3eeba89c8f,0x00026dc5289c0d96}, {0x000e0e6dd7431a8a,0x0000a660c8afde18,0x000cfa02cc76374f,0x000b7654494d397b}, {0x000476b8fd958a15,0x00097d53a314e324,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005d2d913938d7d,0x0006d9d471ad5a92,0x00018a88bdce6ad3,0x000b90be599734aa}, {0x00099aa6c0fb7b20,0x000eda14b233c887,0x00024ee7dad41f1c,0x000cb7c643d13bb9}, {0x000e7d84ea63db6f,0x0003a846de4666cf,0x0000000000000001,0x0000000000000000}}, {{0x000e6128e81e8c45,0x0001464a9235f4eb,0x0002db34ea2780d1,0x000ad3e8b3ecdbc0}, {0x000f8cdbe120731f,0x000f4318097ab5eb,0x00079ebbf1d4990d,0x0007e93c15830f8e}, {0x000c40a1cfba03ee,0x00068df76de664ef,0x0000000000000001,0x0000000000000000}}}, + {{{0x000267eeb458a4eb,0x000e492a1279f17f,0x000c76f729af11c0,0x0007339e92b8f2a3}, {0x00014e00c8ca3543,0x000dbcc01641f96b,0x000755e449dde571,0x000a0a0df11e5fa3}, {0x00031770742dc646,0x0006f53610d1c65d,0x0000000000000001,0x0000000000000000}}, {{0x000e5b808553c438,0x000499c99fe83176,0x00019eef1a061f75,0x0007deb8d4c21a60}, {0x00033192fdd7ecc6,0x0003250ef2ec37ce,0x000aff8f6ed93441,0x00058d1e9777ac4b}, {0x00083407f0d67d5c,0x00079fd1b5287171,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009d6152b9c90b3,0x000aff28f438100d,0x0000a2146e64ecd5,0x0009ad5b7e0c0df1}, {0x0003f6775181b0d1,0x0003c7a1b8151d7c,0x00035c338a3ef9f4,0x000e1fdd81712dd2}, {0x00034726a1f2597e,0x000cb3083971de47,0x0000000000000001,0x0000000000000000}}, {{0x000c041200d9bef5,0x00067c85ff590dfa,0x0008b72aaea952b7,0x000265e7843ae9c1}, {0x00032307d7542004,0x0002dea503395a89,0x000e1eec7f73a8fc,0x0004b86c7eb53399}, {0x00021cf862926b2c,0x00019347a4f0820d,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004f7b384cd7297,0x000acc1a4787e2cb,0x000a5590739ea069,0x000be73fa99d3f7a}, {0x000e7cf6cca23601,0x000960cc53aa83e6,0x000b86b5920b1173,0x000fa7ac9dbe20e0}, {0x00068bb6f6b3ef99,0x00064060ac6c56f4,0x0000000000000001,0x0000000000000000}}, {{0x000626c189f97eeb,0x00092eb7dd82a1dc,0x000142f8425008f8,0x0004b241705cbf37}, {0x000c04c8483d101a,0x0002075cfd275951,0x000f282a7dae45a8,0x000263c98e81a9d9}, {0x000c331b130bf290,0x000c95c5f55addef,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ac9a1c36e3c24,0x0008e09fb461cd04,0x0007bca251b2abd0,0x00098ad8fa6e8384}, {0x000087e953f04f5d,0x000d9f6c57ca3dcc,0x000f179679c5992f,0x000cc9cf93cdfac8}, {0x0000d1a320e29622,0x000580703c650a05,0x0000000000000000,0x0000000000000000}}, {{0x000188e58d397fdc,0x00021860a160b5c1,0x000be9a3f426d729,0x000f8747311911d3}, {0x000b78a79eb1a864,0x0006b881dee2ff5e,0x000fc87ef83107b6,0x000ed139997a8784}, {0x00080e84fd894e5e,0x0003aa1a2f41979a,0x0000000000000000,0x0000000000000000}}}, + {{{0x00031707560bd53c,0x000c9501712fc58e,0x00010e30ced00607,0x000465e677b023a2}, {0x00067620a31c653b,0x0008ea62e5b10af4,0x000d99048d08ca5a,0x000d65af877831dd}, {0x00029f5ab5be8899,0x00028321d38a082b,0x0000000000000001,0x0000000000000000}}, {{0x0006bb42378c6e38,0x000fb8ba4bc4d5d5,0x000a4ef2e4b28b7a,0x000b41f7c314822c}, {0x000a2882d9a51ae9,0x000e6c2280f2b327,0x00019697ce965ab1,0x00075708dae4a49d}, {0x000f1175eea346d9,0x0000e9572d2fbccf,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007d4bad9839247,0x0002744af0bab5bd,0x000cd1e04b0ade61,0x00080a7fe21c3a53}, {0x000864b9871244ec,0x0003f6fd1428f483,0x000889d63b180bf2,0x0006acf748b0e2b4}, {0x000a061072996dea,0x0006607cdec9d5f3,0x0000000000000000,0x0000000000000000}}, {{0x000a9858e242fc0a,0x0001fa2d38ce4fc2,0x00087521e69c709b,0x0005bae8f5996fd9}, {0x0005e131ac99f4d0,0x0002578fe3c3bad7,0x0002279c9d139206,0x0004b6fbac903ada}, {0x000292885696da36,0x000ddbd02ce1356c,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=60 [{1,2,3,..,}]*([2^240]*G) */ + {{{0x0001074e0ee1b4c2,0x0001a0ff10eeb73d,0x000c77549f2e087c,0x0006808a5e2e0837}, {0x000e948c7156c74d,0x000c13bf7c11f82c,0x000a51472ee287eb,0x000b28c4e6f906f6}, {0x0000fef0b165038c,0x0002d8b6f1c9d932,0x0000000000000001,0x0000000000000000}}, {{0x000d310ce2cf5a19,0x000c08add6b6df57,0x000dcd4cb28cd825,0x000e1cbe48bebf85}, {0x00051f1d5aa6a644,0x00008ba85cbebbd3,0x0001bc84d8a2aa19,0x000d343d2d77518b}, {0x000a9098229b988e,0x000a9f940fc8d07e,0x0000000000000001,0x0000000000000000}}}, + {{{0x00096ebc173a5d8b,0x0000ed54a67c958f,0x000ef67809a984cd,0x000abb728dd8453d}, {0x0009f4fe5f363de0,0x000e4fc4614b7360,0x000fee4aab1b83c8,0x000606d2158cb989}, {0x000096597fe56f7d,0x00057270734a0c52,0x0000000000000001,0x0000000000000000}}, {{0x0004ef503a18dccd,0x0009b732b2f44d09,0x0002c29898debd6d,0x0005ffd4e0ef3ff7}, {0x0003830b99ae2e5d,0x000dd5fca5e1c94a,0x000e97015b084de2,0x0000e94504be6d08}, {0x00079eaed90fe0fe,0x00051eafa2897ddb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dd470cee4255c,0x0008ea907208e445,0x0001157ba3e551b3,0x000f94c51b72b693}, {0x000b183c616c9cf9,0x000fe84fcaaf1c59,0x00077c97ed67f1d2,0x000a1d1e1a09f1bd}, {0x000c2f47751550da,0x00038d58d345e7ba,0x0000000000000001,0x0000000000000000}}, {{0x000d95b5f854d3f8,0x0004daa404c99ba5,0x0005a1bac7d29f41,0x000da46981c9d673}, {0x000652c1bc49956f,0x000e505f2a66bdcd,0x00081069783eab5f,0x00036f9996ab9237}, {0x000238170a7330e6,0x000670fa70e33da6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e86a58386cf1e,0x000572f15be04bfe,0x000e35f663e32b87,0x000f5c5294b48632}, {0x0001362fb4267165,0x00007dadeb7d3b94,0x000012e189d86c34,0x000d63e5f7805689}, {0x000b7e33561c7907,0x0003c0c0dc085fa2,0x0000000000000000,0x0000000000000000}}, {{0x000cbe4f2b4f6916,0x0002f30cfb081da9,0x00011fe0a525ac2d,0x000bbd4632662679}, {0x000223e344c2d8fc,0x0000a08757b1ff41,0x00001c0a48229e9a,0x000456b8c92c6f71}, {0x0009a086c4af0e80,0x000d74c21360d8bb,0x0000000000000001,0x0000000000000000}}}, + {{{0x00000ce7164d30ca,0x000fedb34ef3a45a,0x000800620f8ac5c1,0x000c7c79ba6237c0}, {0x00088ff56f44997d,0x0008ab94745563d5,0x000df21b2b00a9ae,0x00086a286295b8d1}, {0x000426dbb4cf9b37,0x000ec830b7004300,0x0000000000000001,0x0000000000000000}}, {{0x000a97f98f792db1,0x000f9d5a4e4b251f,0x00061b4d385d3a62,0x000b4cdaad987701}, {0x0002341727a73b90,0x000c4abf7e84f908,0x000f0ded814c4a3e,0x0002c453671bed3d}, {0x000a888690c8945f,0x00019a94087855dd,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e5f28e7fb0752,0x0005ca705e5e780c,0x00093ca952d3af74,0x000eccdc7351cb28}, {0x000bfc12e9837fed,0x00014b93567e7bfb,0x000546247999f34d,0x000a3f729887c629}, {0x0006edd285692b0d,0x000fc9812e383cc9,0x0000000000000000,0x0000000000000000}}, {{0x0001bc941d72f110,0x0009ba70199860ef,0x0002d090c33493b9,0x000503ff279e0c37}, {0x0005c3fbe286bbe1,0x0006d81c3e80f646,0x0008d3a0a9257bf0,0x000e402ee72a2a44}, {0x00092b91c6a5669f,0x000ad95315497ce5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b397c9c0b3f5e,0x0008573318572b93,0x0000e667f17a3327,0x0000b9137af5bff7}, {0x00017fb65a96b2e6,0x000188dfee9e25ef,0x0002c9edd117ab29,0x00015472d03d830a}, {0x000512ca1063aa4e,0x000adf9593f42bd8,0x0000000000000000,0x0000000000000000}}, {{0x00043be475ba796e,0x00023dbbccf7b7a1,0x00080d4a4b140a81,0x000247748562ea6a}, {0x0002f53e144c7e84,0x0009ac8b6fa39d88,0x000b1eab451fe154,0x000ec4538f34ffe4}, {0x00076cc290527aed,0x000d83bcd8efdc10,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000c5c5bcdaef57,0x000720046d980167,0x0000601ff33f7b5e,0x000e6b0aa07084cc}, {0x00007791af83b900,0x000dd856fdd2391e,0x0008d880430654d2,0x000f826068896340}, {0x000a4b443c176e8b,0x000c4e18c663e62f,0x0000000000000001,0x0000000000000000}}, {{0x000d8ae0441a598d,0x00065c950e8cec48,0x0001316d53d11b80,0x000cd6863a5ccc8c}, {0x0008ced41a668fee,0x00076ba771bb4164,0x000b49a9a4bb4b6f,0x000e370974d5a9b2}, {0x0000485def9f130a,0x0001b84c25f49d20,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=61 [{1,2,3,..,}]*([2^244]*G) */ + {{{0x000f43bc2dfb404c,0x0008b314169ebb20,0x0004d9ce016776ec,0x000b6f3c40cc814f}, {0x00075de6701fd64d,0x000be16687bc27b3,0x000c8ca41b2641f1,0x000e5c7ebdd8aaf1}, {0x00021918a667e429,0x000d9384d2d4cd92,0x0000000000000001,0x0000000000000000}}, {{0x0009667398bc8b35,0x00026c502a6f1f65,0x000612fc65ae7726,0x00047588d1717c45}, {0x000b0cd0bd27306b,0x0007b68702fd9dbc,0x000a43a5beaed3af,0x0008d9e3bfb560d2}, {0x000c14b9b618c615,0x0002421dad1537ee,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009e7889bf8b6ea,0x000292e957ebe27b,0x0002bd715ca3ae1f,0x000ea4756ae08fea}, {0x000f5cab67aaf3b2,0x00047caa37f247c9,0x0001b8953af0925d,0x000557e7bd1f409f}, {0x000979eb14ee5b8e,0x0008bb0e2890300b,0x0000000000000001,0x0000000000000000}}, {{0x00078d6b71ea9467,0x0000c63dfcb1d01d,0x0008e6aaf05595db,0x00006ff49217ec90}, {0x000b8ab12df36451,0x0004207aff8489ad,0x000b85d257b835bc,0x0003706e08a1abbb}, {0x0002a5b7d71ad10a,0x00056ae224792f6d,0x0000000000000001,0x0000000000000000}}}, + {{{0x00028daca765356a,0x0000ee74680323bf,0x00005f51f95b6f29,0x000c6656c3eab37e}, {0x00038ce239752348,0x000cf8aff4ec8ff2,0x0003adc6745b80af,0x000e56c344a76be9}, {0x0006011d48a9f827,0x000ed4a3e016c1c3,0x0000000000000001,0x0000000000000000}}, {{0x00096e22c7a80fb0,0x000891624b09ab2c,0x00049f6d4616a383,0x000b275d1cd7006e}, {0x000adb9075332618,0x000586e58c4079b5,0x000645e2b19bf36f,0x000f76906dc5820f}, {0x000f6bdd7a51a11b,0x000b67dd8137d034,0x0000000000000000,0x0000000000000000}}}, + {{{0x00095b8b650fd71f,0x00014965b39aaa82,0x0001270c9510690f,0x000b3a9f763e6fce}, {0x000be3f839143baf,0x000866c1890dc990,0x00074c8a0d6a0e73,0x0004b520d476087b}, {0x00081006ed8910a1,0x00052b16e6fb91bd,0x0000000000000000,0x0000000000000000}}, {{0x00057756a63f7354,0x000a1ebe4b13d097,0x0003f1884cec54fb,0x000503924519ff97}, {0x00059fb9e4f42689,0x0002ce5e202d309b,0x00098e0004b85f0f,0x000b05c20b1735d8}, {0x000add1fbd4f54e0,0x000dcb178e2a7f34,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b4ec871f1c2e0,0x0003b5de22756058,0x0000837f536100e3,0x0000c16f1ccaf424}, {0x00056dcf857da01f,0x00038c07ebb5fb6d,0x00096a096d6242a9,0x0003055c2b2c30cf}, {0x000a782e55f66ac8,0x0004f012cc9c2c3a,0x0000000000000001,0x0000000000000000}}, {{0x000506352d9bc635,0x000b06aeaaa56b9a,0x000095186c35174d,0x0002167f537385d7}, {0x000cf421a089f0ea,0x00022c37dc99678c,0x000356bf33a69466,0x0003e97eafc66d63}, {0x000e3c0197b16669,0x000d912a0fa3fee5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a52c892d50f2a,0x000dfd8fc48ea89f,0x0004b09bae86a680,0x000a1e1278d67917}, {0x000370f37ae3b7ce,0x000f51107a8383d3,0x0005c8e157913dc9,0x0004c347e479bbd0}, {0x0007dfb63e7f7f02,0x000ac4a32c2410c2,0x0000000000000001,0x0000000000000000}}, {{0x000c5983d275b47a,0x000f3ebc8a42a9a0,0x000db0533ac31f03,0x000cb9b707b4440f}, {0x00064522041e91b5,0x000076367218816d,0x00023be78c44489a,0x00060289668fa7d8}, {0x000b7bda9a033e06,0x000c041bf9880e14,0x0000000000000000,0x0000000000000000}}}, + {{{0x000df487e3ac46f1,0x00026f6aeda132f0,0x000f9138020c745f,0x000a8841334fb2d5}, {0x000c66722bd6a712,0x0005a1ea4533d309,0x000636323c57e66d,0x00008eb26f26bbe3}, {0x000fa479b5dc3fac,0x0008f02e50177e02,0x0000000000000000,0x0000000000000000}}, {{0x000c92b56635aa25,0x0007f4d610ada23b,0x00010104e5566f0f,0x0004f4b30ea26b57}, {0x0004efd9675fd322,0x0001af8f50ca2f0b,0x000382d177aefb1d,0x000538151171ef73}, {0x0003347891a319cf,0x000711dcdab779a2,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002b024db8d3d78,0x000aa5cc47fd4499,0x0004ca3c2ae301e6,0x000f6635a239d460}, {0x0001e72a93968b59,0x000f3e7cb493da74,0x00057a0e451c8476,0x00090539a4ae9584}, {0x000df123a0ccc6f4,0x000f3e4b36ee4a70,0x0000000000000001,0x0000000000000000}}, {{0x000bf5964aec0226,0x0008d0d54e934ea5,0x000838881f3a4f9d,0x0001904c5759057f}, {0x00054f74d21e3d23,0x0009110e0965fa28,0x00025473e3fbb9d0,0x00066659568773f8}, {0x000e05953c3213d4,0x000de0c6c9fbf74e,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=62 [{1,2,3,..,}]*([2^248]*G) */ + {{{0x00023dd4a823eac8,0x000e2984db5faf62,0x000d39d495d0b0f5,0x000841ce0a14e52d}, {0x000cb365ed8de723,0x000bcb1fe9b4ef0f,0x00047ee3aa7d5d2d,0x00032d33c7e0b190}, {0x000d3b9dde2978f5,0x0005329dbc97d12a,0x0000000000000001,0x0000000000000000}}, {{0x000d165556c00ac2,0x00057fb3172c7a02,0x000beeb32c48804b,0x00099dadad774958}, {0x0007934b2bc9659e,0x0003fd281f90ab3c,0x00013abe477effe3,0x000378b329a3faa7}, {0x00036cbb9f3df235,0x00014562e824d0ac,0x0000000000000001,0x0000000000000000}}}, + {{{0x00078de5aeb19662,0x000d1f458b071bd2,0x0000313ed9b5b584,0x000ce5fe5f476cd6}, {0x00077007678c1c54,0x000258964a6d145a,0x000420c0c62f8fee,0x0008595f7056fa68}, {0x00089119263621f2,0x00019c5d8cf9f82d,0x0000000000000000,0x0000000000000000}}, {{0x0000243d2e6cb7a7,0x0008d78d5a87bb13,0x000c4e517b3bcf90,0x0000f65dd0ef67bc}, {0x000d930e5dd35ba7,0x000eb9fb0741af2f,0x00075eb448314eea,0x00003702fdd3f71f}, {0x0002c0a91bac4835,0x0008e91ebd11ec1d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000160f761d5cda1,0x000d737ebbdcd5d3,0x000d7809f98ac1a9,0x000dcdbd555d558c}, {0x000fa398a682b263,0x0004f2c8dcb516cf,0x0003f1fdc39fa308,0x000c8f35f0892119}, {0x000b1a2e7b6b0e00,0x00060305cb4b78de,0x0000000000000000,0x0000000000000000}}, {{0x0005dc3804225ef5,0x000a4dd0142d36ef,0x0006183af50e0ed5,0x0006c670fcbeb371}, {0x0008629b90cb9a81,0x0002af3261b35739,0x0008aa6b6e9823af,0x000fbd19a0ec458b}, {0x000311a98270a0a9,0x000299fe388efd5b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000bf04df8057734,0x000b1031cb2cfcf4,0x00013e25b6e0c3ad,0x000fa4cf3dd2ab40}, {0x00007758e2edfff8,0x00031ad907feffd3,0x000b4564baf111bf,0x00073c4f6a12eba1}, {0x000fad75513a8160,0x00074de7fc43bd94,0x0000000000000001,0x0000000000000000}}, {{0x000d44eee593810b,0x000f1e369ffff5b8,0x00064f19da65334d,0x00021d0f5c2b9ceb}, {0x00091c5ca3390013,0x0005689acf02b87e,0x000bf7c3a49c8b54,0x000093f7ed7c049d}, {0x000a0a1d58d27784,0x0003d7726f20ba73,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ec366cfe8b8dc,0x0005109510bbe0e0,0x000aea6451541d52,0x0007f0a613f8478f}, {0x0000f85f758544a0,0x000f2b250e479f86,0x000b98246494bdaa,0x000483bd40872db5}, {0x0001ef43cbf9eee7,0x000bc8abec7ccf7e,0x0000000000000001,0x0000000000000000}}, {{0x0005c21b7bfcf30c,0x0003ee117f493af1,0x000fdb4b0534832d,0x0001fa1bf55f45c9}, {0x00078f7e3c1efc43,0x0008a7de78a32d11,0x000dc3559e7ee791,0x0004e7a865c863d0}, {0x0007e1e671e05898,0x0005634bd3bf85ef,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d81691c2ab48f,0x0002541bcc0607cd,0x000da791a7f87cac,0x0008347771261610}, {0x0008e3bac250c120,0x000659e04001e2db,0x00052cf1b9282899,0x0009b392289990cc}, {0x000164d7d417f75a,0x000945df41fb11a9,0x0000000000000000,0x0000000000000000}}, {{0x0009c07103c6ae84,0x000480fee72710d4,0x000b8360a2b9d155,0x0000e0d3d7e07da2}, {0x000d149f0388daf1,0x0002f71dfdfd1523,0x000418130ff86f14,0x0009f7346c3e8b09}, {0x000b2e35c5e699a7,0x00052b1c1fdc6ba3,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003345adc3b52d1,0x00068ceb5ac071d1,0x000e11041a7e60d2,0x00074a2a70677323}, {0x00040734a03353e1,0x00041105a4c9d8da,0x00044e1f19873918,0x00091f314a743285}, {0x000322e1b26f9179,0x000d3d1613ed69ba,0x0000000000000001,0x0000000000000000}}, {{0x0004543cf00ed5fb,0x00053fab663cf4cd,0x000be8cc8843f104,0x000f74fe45dc2276}, {0x0004319b78ce0e03,0x000389520a05dc90,0x000cbb592960d2ca,0x00026ed0dfe3e1c7}, {0x0009036fca8841aa,0x000549d9ea193025,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d95d4b57fe6e7,0x000237e45eed99e3,0x000ddc0cb978fe19,0x00073f687eb46e14}, {0x0006f57bdaf6e4df,0x00047741a18670ac,0x0004925a46fbe2b8,0x000282f9632d0245}, {0x0002e144fc15a10d,0x000815c55aed10af,0x0000000000000000,0x0000000000000000}}, {{0x0004dce0659c9bac,0x000b25a506cebbc4,0x00048b6559b03aaa,0x0008048a933863a2}, {0x00020d37a9de4c34,0x00020f440226cd5e,0x00074e9ee95db69c,0x00082f425e1eff1c}, {0x00033a6f8d820bb8,0x000ef06f95cad219,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=63 [{1,2,3,..,}]*([2^252]*G) */ + {{{0x000e4e5c561d5097,0x000b584aedde8b8f,0x000aba27830c0d36,0x000c7d59c0f869dc}, {0x000b714a35cbc32b,0x0004bed4bc22d71a,0x000061f00680d9e0,0x00033bf0836adf25}, {0x0000d7fedb3d768c,0x00095c616b984e3b,0x0000000000000001,0x0000000000000000}}, {{0x0008c5d5c16b3659,0x0009b2bd923c283c,0x000fbaf03219a32e,0x0005bdb0f0d8e95a}, {0x00027d3039b5fed1,0x000c59ce26d89427,0x000676fa1dec9a4c,0x000121992696f0b3}, {0x000260c98b8c7cfb,0x000541c1c9792927,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002f821dc52854f,0x00009f01e839c81b,0x000f9520b0acb7e7,0x0005ef6ec4857ab9}, {0x0007209f9eda63a8,0x0006daca6651f475,0x000d6976e7173379,0x000240b37bfaccec}, {0x000b4437229f4ce0,0x0001910fe8a0ffcb,0x0000000000000001,0x0000000000000000}}, {{0x0007819702adce4e,0x000559cf2ed75ea3,0x000524a7d80f948f,0x000a15733e1fceef}, {0x0008e25fd5510058,0x0004c29ed3586531,0x0004e51cb7d9fa11,0x0006f171b487caa6}, {0x0006163b82558054,0x000686de74000000,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b150deff72861,0x0006369a87c08222,0x000222ff210ad76f,0x000b4d66f2177234}, {0x0006ffb6d673f874,0x00059b847a7a63aa,0x00088181fb601b85,0x00061d5a56e17f52}, {0x0009cad3b2dceae5,0x000b7064799ea515,0x0000000000000000,0x0000000000000000}}, {{0x00071777678fbf96,0x000ee3fb840953c6,0x0006c82ee1fe6943,0x0000476345986586}, {0x00027b2c01a1da88,0x0001dd9ed1d2e620,0x00093b57ac9ecf98,0x000aea3ed52ca86a}, {0x00083c732ab42d43,0x0005274badd57297,0x0000000000000000,0x0000000000000000}}}, + {{{0x000860f86c3463c3,0x000fa451b92975d3,0x000e9c89aced751f,0x00082df00fff3b8f}, {0x0004d44ceed1d22e,0x00022e7d389ef4bd,0x000e91dec43e5b63,0x00003ac6cd725daf}, {0x0003c7139385f22e,0x000deeecc87ca1c2,0x0000000000000000,0x0000000000000000}}, {{0x00051580221e0fc8,0x000941fbf97dbfd6,0x000689ac9e872372,0x000740f84611974e}, {0x00046e04ba0c6ce7,0x000419caa07a8f97,0x000565905b0cdaf7,0x0003cd2570033075}, {0x0003b2c015af7e40,0x0003287d54b47d8e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000087653c1971e3,0x00077f0a153e5f28,0x0003ed97c2828991,0x000095935157a12d}, {0x0003722663e4ec8c,0x0008ec4fe824b403,0x000dd44aff641d97,0x0006da087485323c}, {0x00044e2cb2c2b861,0x0006eba170078d74,0x0000000000000001,0x0000000000000000}}, {{0x000b5b83303bc746,0x00013dec62dad85e,0x000eb52890ef39fd,0x0007414a67a192cc}, {0x000ca32294492ed1,0x000e1460a8a16787,0x00024c190537d3f9,0x0004d8dd49fa5c1c}, {0x00025dcc6564966f,0x000872ce77f122af,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f907cb543fab3,0x000c69a83a50077e,0x000cb4bde1d63e29,0x000c33fc44a3bb56}, {0x000f82a91020da98,0x00021551aca18ce5,0x0000524e8061c783,0x00030bbde84c8ff8}, {0x00080aaffd7e7a07,0x00025503d2cefb4d,0x0000000000000001,0x0000000000000000}}, {{0x000d489c09cd7406,0x0003bbf72e670d86,0x000584e3d6cd578d,0x000c5357fb7dc505}, {0x00078eb6069dbc02,0x0003d4fa59d19b85,0x0000398d29e9ce8a,0x000efb99649fd29d}, {0x000ce49c616fbd54,0x000860686cd02ccf,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b5280bf38c012,0x000b16e5d0e927a5,0x000e0fabbb77cb27,0x0009a5fc1a89a6d3}, {0x000a92cdb34cf1fa,0x000464dc9a9cf793,0x000eb464387be7aa,0x0007fbfde96cd4d4}, {0x000232f3e162772a,0x000656aee57c0a02,0x0000000000000000,0x0000000000000000}}, {{0x000a4f88de057838,0x00017126373b6048,0x000e4a0f6263ace7,0x0001d00ce841a9eb}, {0x0004964f3fadfdda,0x00053a6795df2847,0x0007970db46fe5d6,0x000fc5cc5ee32eac}, {0x000634cedbf5f3ce,0x000fca10e755fd0e,0x0000000000000001,0x0000000000000000}}}, + {{{0x000aeb844e0e5a47,0x000278171b725206,0x0003ef95a8f2f67f,0x0001fdfb411d7c3d}, {0x0002cbc9db5d5134,0x0004cd3d499c831f,0x00090a75fa0db406,0x00072c8d72cfb8bb}, {0x00070a986050fdef,0x000f2a584d26e897,0x0000000000000001,0x0000000000000000}}, {{0x000357b6cd8cc5f7,0x0006b375fe114c8a,0x000aa2296d0e1fc2,0x0007cba1e2fe623c}, {0x000b8ca73315ce03,0x0007e86db236843e,0x0005e04b5b70ddfb,0x000420198f9d4b15}, {0x000535cfa0692139,0x0005a2aa06d43751,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=64 [{1,2,3,..,}]*([2^256]*G) */ + {{{0x000cc45663bc9f5b,0x000b2868f57feb89,0x0004bd3cbd6a2543,0x000a5e560bf63c0e}, {0x0000e648f4a5666d,0x000591427cb7d9cc,0x0005977ab848b1a7,0x000af4656829e85c}, {0x000ae8f7a4025667,0x0003b4ab876527cd,0x0000000000000001,0x0000000000000000}}, {{0x0004ed81840ffbcd,0x000e4830db96c420,0x00026c352dd1b3e5,0x00003369497308c9}, {0x000023370174e547,0x000c6d8497a95345,0x000ecbfae86058c7,0x0008a32e4cdcae7a}, {0x0004e9eb567daf0b,0x00085eaf8dd7df3a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000deae24e7511a4,0x000762cb23734ed7,0x00066bcd84d23939,0x000c037c989a46bd}, {0x000c06543988385e,0x0003f08c8acc808e,0x00000e7680dc66ca,0x000e4c3c5332a768}, {0x00063204acc98ee9,0x000db0a0ef46de86,0x0000000000000000,0x0000000000000000}}, {{0x000b4a4e27fff289,0x0007eeb14e22b305,0x000e9d3141e930a3,0x0004f15435f5cd09}, {0x00052f55ccf3f336,0x0006c9377055f313,0x0000f610c74549ef,0x000c8d0207da4bf8}, {0x000b6ee97b1c2b15,0x0000920992fd2caf,0x0000000000000001,0x0000000000000000}}}, + {{{0x00043f2525d2ebb4,0x000811edb2cca106,0x000c996f27900e32,0x00092edb6f6af92c}, {0x0002dbdef8275bf9,0x0004dd3d26338446,0x0004401818a7ff9a,0x000d60e7694d8e21}, {0x00054e87fa7aec62,0x000f988bdd22449d,0x0000000000000001,0x0000000000000000}}, {{0x00063c9fbe4e6775,0x00026d7e7ff11afb,0x000c6b3e18f7eec0,0x0005c983e08b80f1}, {0x000b75d6b5a4c84b,0x0005f99e3a4b0fd4,0x0005a7cfc4904ce8,0x0006c336a99a7afd}, {0x000e4a736ba1e62f,0x000595be20ba2924,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008c92f010fc781,0x0002463423f6e871,0x0005f129e35dae8d,0x000d59f4aeff7db0}, {0x0000c963932f5dba,0x0005e468db3cf82c,0x000e23c6b7d10e1f,0x00006e08595910e6}, {0x0008880e8c76fb1b,0x000134e8c1259453,0x0000000000000000,0x0000000000000000}}, {{0x000506649d87b671,0x00014c272ea4f089,0x000aa2740669dd1a,0x000622f8a6cc0d62}, {0x000e392244f6f191,0x0003dcbd9dd28338,0x0000c61a8dd7166c,0x000e4930a90ca39c}, {0x000d41296b979b8c,0x000037aa5c88b76c,0x0000000000000000,0x0000000000000000}}}, + {{{0x00051d16f31cd955,0x0003fd720fff5e54,0x0006c62e42ceacd9,0x000b72856f74fc83}, {0x0002b8a51db93ff9,0x0006ca983e7b6bb4,0x000e06f8fd893a36,0x0002491c6c8908ee}, {0x0008e9f64e123094,0x0005764984e58063,0x0000000000000001,0x0000000000000000}}, {{0x000ad9aba979f347,0x0005557b9d835c0b,0x00089b7877984846,0x000ce8c3c6bb325d}, {0x0002e0fb571c388f,0x0007185f17237c5f,0x000ac5737bcf4832,0x0005f037df6f53b0}, {0x000b6f7ae34a972e,0x000821f685c7b273,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e5575bc0dd4ad,0x00028eabf66053ac,0x00054861cbd6dc53,0x0005b123ea9fdaff}, {0x000c00ecf823c855,0x0005d8934d09e411,0x000eb090ae97a01a,0x000591dabc9c170c}, {0x000f751f273c40a7,0x000f0f52861011d8,0x0000000000000000,0x0000000000000000}}, {{0x0002bc9a33075cd8,0x000bb779de4fde35,0x0002eb1b199f0130,0x000e29003c4457b6}, {0x0009ff04878d3a95,0x00004ebfeec1a9dc,0x0007d0d097a6545e,0x0008673c7b41f5aa}, {0x0007894e63c5c4ce,0x00005b385d1700a6,0x0000000000000001,0x0000000000000000}}}, + {{{0x00046d7efcbdeae0,0x000fbb2f349cfbe6,0x00022f14a9cfd187,0x000ef46f7fb5a2ff}, {0x000d8084df701781,0x000b2e7da6ada115,0x000273537b36285a,0x000d779e5cbe2143}, {0x0007b1bb342159b5,0x000321182d17ef98,0x0000000000000000,0x0000000000000000}}, {{0x000974b9395d5c1b,0x000a203e9046670c,0x000c9fa51be4f31c,0x0000167fed87df23}, {0x0006d7ab1aee3553,0x0006c8a7b334d671,0x00037b8b3f821601,0x000677ee013df3eb}, {0x0007a3a1013ff132,0x000a7ed7d1a2e9a5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b3fd002806466,0x000fd4605cfac818,0x00085d2f0b811efd,0x000167145bb41efb}, {0x0006e3c03cac7ee2,0x00085c4b2dade36a,0x000220dcd3725a14,0x00032cf525a550bc}, {0x00014db66b11c84f,0x000013664e47ace3,0x0000000000000001,0x0000000000000000}}, {{0x000a48858e7d464c,0x0002276f7bbfd1a7,0x000e24ada567d04c,0x0006a941adced466}, {0x000c270addbb103a,0x000761ca82f14e02,0x0004d0794b62798c,0x0007a0bec3f90326}, {0x000caf618966e8d4,0x00021a1f211c02e6,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=65 [{1,2,3,..,}]*([2^260]*G) */ + {{{0x000c24408b5b4bc1,0x000d861e48c2aa26,0x0008746f93b2fb6c,0x0005f018515690c4}, {0x0008d76a3c1b771e,0x00093035c899fbb2,0x000d18ac338e0049,0x0001b4e7f02fa3d8}, {0x000fabf9b804c035,0x0002f83e6175e309,0x0000000000000001,0x0000000000000000}}, {{0x000830680485a054,0x000962c1a8a622f6,0x000f94a3f3450d94,0x0007a83e0a44d62d}, {0x0000105319e21805,0x000a4a1ebdd2bed2,0x000f4863d6076c13,0x00034672ca137368}, {0x0006135e4ef4b1a4,0x00020b6692537ff9,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001b7a5e08fe30e,0x00029eb048815ab8,0x0002e0a161f11e12,0x0001801becb84207}, {0x000ad5b394a58f8e,0x0007512807890edf,0x000f675b3e4e4773,0x0008c99841055d81}, {0x0003ed35c1050ce1,0x0006c217bd56acf4,0x0000000000000000,0x0000000000000000}}, {{0x0000d6c8c5a1e005,0x000ddbaf53db5dcf,0x000c6ab4e4f6ee72,0x000e686032c8481a}, {0x000415c545af61b4,0x0003595ad60e7c0e,0x000f59b261ffe75c,0x000cf66fa7cfbf47}, {0x0002e7097fa1aaf6,0x000a8386b7977f21,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000029a7619e46f,0x000f29f5c333074b,0x0009e45f3bb1eec5,0x00035aadf8396133}, {0x0000825d3e2a3176,0x00034ef799bdaba5,0x0007f38574f4d09c,0x0009085e808678d4}, {0x0004a57483db0387,0x00054465ae9f6d1c,0x0000000000000001,0x0000000000000000}}, {{0x0002fb74fcaebc4b,0x000ef4b901e46eb5,0x00068ec4a861868e,0x000f51a07bab1199}, {0x000748f19df109f2,0x000d75da4f6a75a0,0x000f255613859652,0x000e60c8067759f7}, {0x000b663826b7b569,0x000f450533f4d440,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008e66704c4911e,0x000b5ad20de07d3b,0x000dab27e9b7aafa,0x00052dbe3fb66eb5}, {0x000cf7ce856345ac,0x000025496cdf84c8,0x00082f095b8e1e29,0x000e8e6db4cd7761}, {0x000b0faa321aaa54,0x00088ae73fef003b,0x0000000000000000,0x0000000000000000}}, {{0x000d643fd4fac454,0x000c4870e138d616,0x00069ca59b85612f,0x000a26a00889a9e6}, {0x000c093e3dad6fb3,0x0006ce66bb43df1b,0x000244dae036271e,0x000c05182a82fcd4}, {0x0002559d8958ca2a,0x000a7526838c8510,0x0000000000000001,0x0000000000000000}}}, + {{{0x00084b954cc2f383,0x000a776cd88b3801,0x00070c99422dcf3b,0x000bd45086f66f43}, {0x0005f7b81c0e8bc4,0x00004cad2493575c,0x00070ce4091825d7,0x0004f1ff4bbf4b9f}, {0x000d28bd9ac2a0a2,0x000c23e5ebf7a3b5,0x0000000000000000,0x0000000000000000}}, {{0x000270e7ebdf9c15,0x000050eb783548eb,0x00081562bc5fd0b1,0x0005f68896b8a59a}, {0x00073bc130375edb,0x0001c5bd938ab1fc,0x000c19c89b28feaa,0x000f8d6e4b1c7f18}, {0x0009f7384e98a494,0x000a3f55131bf640,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a27923d9331dc,0x000f04ffb6351b25,0x0007f29f1e1c9bc2,0x00069b7d91e80528}, {0x000d48a56cb26370,0x000d9a9a20ff75d6,0x0000b393f52dd397,0x0003703dee3c5227}, {0x000f9c1c267288a6,0x00083849651d4713,0x0000000000000001,0x0000000000000000}}, {{0x000d56c853c2dd2e,0x000a93bc1a8d521c,0x0008735173646598,0x000967ee4685de4b}, {0x0004cf35701ef418,0x00080b116b6dbbce,0x0006b03c5acf7cf3,0x000fe839b4243541}, {0x000841fbd8d1a9cf,0x0003a6e1730d1f15,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fdbea99958b96,0x000e01f76bf65ac0,0x0000c6778adf573b,0x000d0f51ffd85a6f}, {0x0004afe98c72d927,0x00087e8ec8173887,0x000d76d032ae57d1,0x0004df95e88800c6}, {0x000ec4042dee55d1,0x0008e8cd5760c30d,0x0000000000000000,0x0000000000000000}}, {{0x000eac1084c10f00,0x0001c37bdb463a14,0x00076281603cbf77,0x00034037d48543b5}, {0x000f3b965ac3efc6,0x0009a7be5b6e5426,0x0003d0f87fba3664,0x0004ddb5ca9f2e20}, {0x000052649abbc317,0x0004b72eb6083655,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001bc4f61438294,0x00002964a43b5d5c,0x0005d7c26171c634,0x000967cc93c0fb82}, {0x0004b96145dca1b7,0x000b5c4ddfd06836,0x0007f0eec5bd3c73,0x00082d7bf8f0d500}, {0x0005b93c7771d6fd,0x000475f222990f21,0x0000000000000001,0x0000000000000000}}, {{0x00026e01b4722367,0x000926340c9a0a1d,0x0007edb2bec04b5b,0x0005d17d0417ca25}, {0x00072b41c7280efd,0x0003c942f670df33,0x0007910fbfcef999,0x000437ef3a577e3d}, {0x0004d4c9039005c5,0x000edddb0ceb3a8c,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=66 [{1,2,3,..,}]*([2^264]*G) */ + {{{0x000a3a0634a3ce07,0x0008f38d14324956,0x0002232fc3562771,0x000d389e5a0479ef}, {0x000b882744b806a6,0x0000bd687af4d435,0x000d3172792b960b,0x0001f792e60e4cec}, {0x0009dcb17063be91,0x000c5902f6ffb4b0,0x0000000000000000,0x0000000000000000}}, {{0x0004fbf6f215ba3d,0x000918e7c66f8fb0,0x00095b38bbb07b90,0x000022d201c5b207}, {0x000344fdf3937c67,0x0005a11142ee01b8,0x000cb5fc7b97506e,0x000c2ae4043311b8}, {0x000e1937f2450b7b,0x00045fa26a70cfe3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fdc4396bfa539,0x00092b7edbcb88f2,0x00019d35421db912,0x0000a538d5dee79a}, {0x0003b035e9ea2a42,0x00021709fe9cf14f,0x000a5b749703f94e,0x0002495b47e8690c}, {0x0002ef0574deb7af,0x000dd4b09d6324cc,0x0000000000000000,0x0000000000000000}}, {{0x000f7df3b9fe6e0b,0x000f9e25c764e67f,0x000b9153d851593e,0x000822d7ef6d9489}, {0x000c9238e5449117,0x000bd3333b1e34e4,0x0006cfb58cc8198b,0x000b7b487650416c}, {0x000068c07a8085b4,0x000b7b5e20cc8eb3,0x0000000000000000,0x0000000000000000}}}, + {{{0x000af6a4691425a8,0x000eb7a958bb9efe,0x00085a7002151b0a,0x0006a8775208123e}, {0x000055575f5446b3,0x000528fdeea0c896,0x000a43b1b4d824bd,0x00096f550c5c7315}, {0x00050cdbb6610168,0x000b9c3638cd4a93,0x0000000000000001,0x0000000000000000}}, {{0x00039bfed8d0ec30,0x000230c0cb3e1745,0x0004b3cb7f69dddc,0x000a60a97d0d2a3a}, {0x000c6d61d74827e9,0x00048c2e237c10e2,0x000c78dae64ccf95,0x00031e036445ee96}, {0x000bee13f244e4cb,0x00012ec220b81c78,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008b837d4bef687,0x000919e15922b2f9,0x000c8afde9c62c29,0x0009534c95a1a3c5}, {0x0008f604b1043ffe,0x0007a01a13fa2f63,0x000393b04cd8a8d2,0x0006e26fd0c22660}, {0x0000808a072545d9,0x0003871dd10699cf,0x0000000000000000,0x0000000000000000}}, {{0x0007dfe3a4ea56b7,0x000094c38223ef03,0x000e8b66c87d36e2,0x0002766ee28405ae}, {0x000f0a065b535e3e,0x00084a317ded4b87,0x000866d3f53ac0b0,0x0007a0ee55860ca5}, {0x000a7080382b21bd,0x0002f3ff1d58cf1f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000760a0d077a674,0x000256d1eb02b933,0x000a86e63e76464f,0x000e22b473632441}, {0x000db481034e4b15,0x000914ef870834a6,0x0004c2dffa8bbf34,0x000d9d0466943feb}, {0x00031a2dbf893cc1,0x000615fa26911a87,0x0000000000000000,0x0000000000000000}}, {{0x0002f76d13211f86,0x000b53e5f9871239,0x000bd8e3f6da4b87,0x000367de3555d6f5}, {0x00095ebc54c2b323,0x000413dbb2bd8e48,0x000ddef4e974c105,0x000de08da1d15f48}, {0x000eb47f901deb65,0x0004f245e4c32880,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005b2c93a39a68f,0x00012def13c9b690,0x000a5eaf60ed34ff,0x000eed4546115d13}, {0x000acc0704820ad4,0x0000c499c60761b0,0x00013af5dd51e45f,0x0007a978e5524abd}, {0x0009f811db1ec09b,0x0005900dab7d3aa7,0x0000000000000001,0x0000000000000000}}, {{0x0005f21e6490481e,0x0009c0ea3d3b19a7,0x00068df5edf0364a,0x000c93c95e1d6b4a}, {0x0008333e2dcc0b44,0x000a8fc7be078322,0x000350437cb9512e,0x0005c965c20fe9e1}, {0x000d3176a887068c,0x000004e870a54162,0x0000000000000001,0x0000000000000000}}}, + {{{0x00005c3b211947b8,0x00027fda98024305,0x000832a6aa27a459,0x00057be3feea006c}, {0x000ba0bb599ef407,0x0009c187eff74059,0x00032aa4ef6180b7,0x00072b398f55afe2}, {0x000cc5ddc46af4a2,0x000e611d5ea71271,0x0000000000000001,0x0000000000000000}}, {{0x00085981da5484c4,0x0002661fa0fa34a4,0x00025e8fb282c8f6,0x00009d9542344d00}, {0x0005e720cc73e773,0x00081ad0388c6b65,0x00097a5b5f85f411,0x0006173a273c5fde}, {0x0000126c0a036ea1,0x00030085c778a65a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dd3a67c2984a5,0x00072c7824703af1,0x000bf0c69c5b39c7,0x0000901a46f942bc}, {0x000f89e0174be31d,0x000b6326f7d38bdf,0x000eadb91bfcc1ea,0x0002541868bb8787}, {0x000a48a8ba038566,0x0004606d8787616b,0x0000000000000001,0x0000000000000000}}, {{0x000e290f5d5f8e88,0x000eb41d33d54569,0x000662b634f1ba52,0x000fc5049dfd1d1b}, {0x00059be51c909876,0x000b7406ba93e420,0x000475a49355b9dc,0x00048963ea182651}, {0x000985ceebcf7670,0x00062eaa85c80508,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=67 [{1,2,3,..,}]*([2^268]*G) */ + {{{0x000b5648e1eb2291,0x000ba734c2f6e413,0x0008535398b202b7,0x000a8b23ebd7f177}, {0x0009fd3b0fc5e7ee,0x0003df55ddc7a0f1,0x000261d577641e2a,0x0008f496646ecb9f}, {0x000f2be9c112454e,0x000e02c23da6a9da,0x0000000000000000,0x0000000000000000}}, {{0x0009d35c52fed679,0x0007671efd66d8e5,0x000904f29b91b401,0x000c352b084f27ae}, {0x0000123e88566129,0x000229faaea32636,0x00087f4c04620cfd,0x0005535f695ec91c}, {0x000fc2a2127c5854,0x000fa1c94873fa3c,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004b028b8f44cc5,0x000fa18c73e470d1,0x00046af781c684d5,0x000aadf0eb44feae}, {0x000604610320e3e3,0x0008fffa44fd9c59,0x000908270d9d9d3d,0x00088a6283f3ebbc}, {0x00060d649fcec534,0x000e1d44a603fadd,0x0000000000000000,0x0000000000000000}}, {{0x000740ae33023df3,0x0000135f6a91ebce,0x0003780772b2000b,0x0004747ae7ea71ec}, {0x0007f6f03b13d0e5,0x0006603e33fc299d,0x0000d28b6e9df68d,0x000a2043747f8604}, {0x0006089683aeee37,0x00024e9926fb8de4,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006c9f15018542e,0x00079fb1f6fe5f6f,0x0005889ab7c13ba5,0x000129b7c5358418}, {0x000a9ac0306d8ad0,0x00008b37c84cfb84,0x000acf7da701dcb0,0x00014bb42427b3eb}, {0x0006e318d3d02d27,0x000958db234da419,0x0000000000000001,0x0000000000000000}}, {{0x00031a9f2e6d1d68,0x0000ba7009240e02,0x00063eb8c05422c8,0x00081b3a6ec6a77b}, {0x000bc58689a5aa19,0x0006306dfb930061,0x00007013549ec203,0x0005410416293e63}, {0x0001a4d303fabd7a,0x000ac172f1e81c7f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b9ad3970b9e18,0x0000bf6af8e430ab,0x000f59d55e652348,0x0002bd614bc56b8b}, {0x000183df0a6ecc07,0x000ee1786d25c98f,0x0003feabcc84059b,0x0007b20a09a6f26f}, {0x000d600ce79a2dfb,0x000f39cf2e6f0393,0x0000000000000001,0x0000000000000000}}, {{0x00072a39f3507cb8,0x0007042b1470af9b,0x0007da313b04804a,0x0000e590e67c9622}, {0x000cabec90cccc29,0x0005e76e6a796f29,0x0001637cadb620bf,0x000d15b03af38ec0}, {0x000dcf7634087520,0x0001906c0ca6b7d8,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007eccab473c8b5,0x000354c80ff211e0,0x00045d2bf3c3aaa3,0x0005bdea352cfb52}, {0x00016f804d4fc256,0x000e5ad706ca34f0,0x0006619c96cff608,0x000490525e689857}, {0x0004163c78de4a6f,0x0007e4b87dad9b7c,0x0000000000000000,0x0000000000000000}}, {{0x00035a48ce31e1e3,0x000c4a6aef85129a,0x0002e4b9afe02466,0x000a8b4fb7e5c1b3}, {0x000e4ea65ec8abb1,0x0009979db25393ba,0x00064b047eeb2086,0x000d6e5e56906ac0}, {0x0008d958b203281d,0x000de4155ed9842b,0x0000000000000001,0x0000000000000000}}}, + {{{0x00019bc174c6d988,0x000cf4d9f702e572,0x000883fd073431fc,0x000f7c52e0996638}, {0x000331a7f7f18050,0x000e9196a2374342,0x00087a7400e71f3a,0x0003791b5d724c12}, {0x000499ca89fe518a,0x000e565820d945a9,0x0000000000000001,0x0000000000000000}}, {{0x00035b7cb9fac00e,0x000a632b3417a9e4,0x000077b9768bc095,0x000afb46dde432fd}, {0x00032553ea0ffde2,0x0000725529dbe056,0x00071cbdddb8ca1c,0x000edb41a198fcb3}, {0x000f5060041dd314,0x0009a1fe368a743c,0x0000000000000000,0x0000000000000000}}}, + {{{0x00059195e6de2d3f,0x00030ea9f4518076,0x000e3f066c30b9f7,0x0003bd981db2f294}, {0x00046e95c601e580,0x000782f5d49b6ae4,0x000f2a24bea15da5,0x000d57d82c482be0}, {0x000747b852b55a3b,0x000400c12ad66ee4,0x0000000000000000,0x0000000000000000}}, {{0x000106fc9ab22be0,0x000f3ff85e4be397,0x00064c04ee049a9a,0x00068c1771b2f4aa}, {0x0009c56a4f6e25c6,0x0006c0243a7cc3be,0x000082558b6f8b1c,0x000d25ba47737910}, {0x0009a82551abc22c,0x00044f195c4a902e,0x0000000000000000,0x0000000000000000}}}, + {{{0x00037e57ac34630d,0x000fc2c030f2d54f,0x000b84aa880649ef,0x000b55a13ad19d77}, {0x0002091bd296d1ca,0x0008f7f0b28c0816,0x000d7580c469726c,0x00021840b8cfb847}, {0x000fd3c1cc59a8b1,0x0008b90e2778fdc8,0x0000000000000000,0x0000000000000000}}, {{0x0006cc1f42f98900,0x00026c3bf2f82644,0x0008d5f8bb74fc86,0x00077c747df08423}, {0x0005d41c77ea13a8,0x000556d8fe471d93,0x0008287e98cde5b5,0x000c068f4d40279a}, {0x000305a88e400538,0x000e77c091d74bdb,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=68 [{1,2,3,..,}]*([2^272]*G) */ + {{{0x000190a6f12cf864,0x0009e0eee766f86e,0x0005b775cd536070,0x00057c69d4566a98}, {0x0005745df1e07e40,0x00047733f9c06722,0x0006e2b1b1c2a5a9,0x000fc80987a24bcd}, {0x000f4061ae7293fb,0x0007d711f7042b89,0x0000000000000000,0x0000000000000000}}, {{0x0003c1b0341e791c,0x000537daedd9c1c5,0x000495a12d7c48bf,0x0002d4a32c8c9765}, {0x0005a662fe9dfe7c,0x0007c6bad9faed52,0x000660c5c4df70a2,0x000bba7fb07624dd}, {0x00091b1d621abac8,0x000771b618ce5d4a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c915030a7a399,0x00068b673999f751,0x00008c22b2afe146,0x000bf6a5fc300d5b}, {0x000b3e178c0bceca,0x0009d38258020b90,0x000176381c171fe7,0x000e86f32623a2f1}, {0x000f64b9bf3a66cd,0x0002c55668f5ac6f,0x0000000000000001,0x0000000000000000}}, {{0x0001812516e735d9,0x000aea3ea58c5dac,0x000356a5f10de279,0x000295b07e9f7153}, {0x000f586ce9eb4d08,0x000daab1a3f7c783,0x00000a0030b2d7c4,0x000c2198f3166033}, {0x000184aa9d0c0475,0x000b11a6fe88caba,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ba5c8d0193b1f,0x0007644c52e9d2ec,0x000084d971b1a2c0,0x0000ba2904071452}, {0x00016420810c95b0,0x000726c12ee37ace,0x0005cdbfb3b34658,0x0001ddb8f12176e9}, {0x0002665465a782ea,0x0005989e91fb9ee1,0x0000000000000000,0x0000000000000000}}, {{0x0000c16d55245f9b,0x000a5ab01d1b1ade,0x000186cc016cdfa5,0x000f20c1907f643d}, {0x000b819ce2692951,0x0001e463db499758,0x000551bae173a15a,0x000c9960164a1a60}, {0x0005b509da7db4de,0x000254d9cec8875c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b44e11c323d06,0x000fd5d6d986113f,0x000894e506cf902d,0x00052247fd0b1d00}, {0x000a2782247b185a,0x0003bd1827ee7a96,0x00075cc817a81ab7,0x000d58e21da1b5a6}, {0x0006b1f8c96f3b0a,0x0005eb0b4feab1ba,0x0000000000000000,0x0000000000000000}}, {{0x000e1e70f2721b75,0x000160a2caaa6a94,0x000c595ff3de4a5a,0x000a75c84e2aab67}, {0x000e555f145b7c4c,0x000c6003a47731be,0x0008f07e7fe03b5f,0x0007c95ac06b0bfb}, {0x0000ec8f9062bb21,0x000d58a73aafef97,0x0000000000000000,0x0000000000000000}}}, + {{{0x000123c6709431e0,0x00010ae6e4e2793d,0x00084b28d12b01b7,0x0007bca51962e973}, {0x000f98e6a52dea7f,0x0002d8bb8dd35519,0x00063c8d202bed1f,0x00009ec87640cd7a}, {0x000e8802cf11aa3f,0x0002789d1734b8f7,0x0000000000000000,0x0000000000000000}}, {{0x00015a8a3e8d859e,0x000534ae889a29d5,0x000da86637742cb4,0x0005ee22c15c8252}, {0x000ad4f9397a87f5,0x00093d8a684e2ab5,0x0006af7ba63ff2ec,0x0004f0fe6a52e297}, {0x000effff8321e195,0x000d2957562f8dbd,0x0000000000000001,0x0000000000000000}}}, + {{{0x00023e7069e42e0e,0x000d2239c3ca8089,0x00005746ae0d546f,0x0009bcbb8ee8194a}, {0x0005279f5c84f339,0x000373c06a06d19b,0x000c70d34e701108,0x0008ba438171e418}, {0x0007c7306769b5b5,0x000064bf193f46da,0x0000000000000000,0x0000000000000000}}, {{0x0005544b033a42d2,0x00061e556329a54d,0x0006aab67ee7a477,0x000c61bcc63287d0}, {0x00034397f22f1672,0x00021907d612d307,0x000ccf64c77cc188,0x000f80df2be0b759}, {0x0001db9d853899e4,0x0007cb0c4b9b73aa,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ff9f36c3349d4,0x000c3db537864c16,0x000d990835ee2990,0x0003c5fb1d408a12}, {0x0004b5ff931b6504,0x000452158a1b1e0b,0x000db8a2c29f72a6,0x0009d61be31c5985}, {0x0007a2320489621d,0x000480174d202617,0x0000000000000000,0x0000000000000000}}, {{0x000294c195148880,0x0009ed88751bd34b,0x000f46ac8a70ae99,0x000917e5c0560f97}, {0x0002525c8ba24922,0x00048c3502a88bf3,0x000ee6a458ba7134,0x0003f607a14e42a8}, {0x000dd29054842573,0x0009c1acd66ae0e2,0x0000000000000000,0x0000000000000000}}}, + {{{0x000edee700e2b9a1,0x000ca05fd3e47e10,0x000775354363597f,0x000b8ab9d14d9e5f}, {0x0009809ae6cb63e8,0x0008a4dd84740965,0x000dd249f1a5c96c,0x0004d2f79af0cb6e}, {0x000166e5361d2b7a,0x000692fe3d22a60e,0x0000000000000000,0x0000000000000000}}, {{0x0002fa6f8995a329,0x0006e396d7a363f7,0x000d92f57cc488ad,0x0009d1958510a286}, {0x000c0b888aa8bf0a,0x00042decec317136,0x0008b9bdf9fc71bf,0x000ac0298d41b6cc}, {0x0009ecbb249e5d99,0x0004db314b57f810,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=69 [{1,2,3,..,}]*([2^276]*G) */ + {{{0x000d708c668b7357,0x000d96ce839038b2,0x00020e1ea62ce28e,0x000713c58763eab5}, {0x000e2c4523fd6ed2,0x000eae1cb271027f,0x0005e4f9c4b8cf67,0x0009601ad02024a9}, {0x0007d73ac0716494,0x00064337442ffcdd,0x0000000000000000,0x0000000000000000}}, {{0x0007851b23ec84bf,0x000beedb8574d7b7,0x000286ebfe9b645b,0x000e45ce0c8710d8}, {0x00056a79aecb4766,0x000f379f83c2d312,0x000bbc5340ea164b,0x000df851521a164b}, {0x0009d5d5e1ac3081,0x000081b205779b7e,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003e4b56c489ffe,0x0000450823173431,0x000479ae5276717f,0x000cb05ce3d436d8}, {0x000ddf2257834d02,0x0007cf804300a63f,0x00048d555acde6aa,0x000b3233d0de457f}, {0x000aa55b4de5db66,0x0008a60379d9ac81,0x0000000000000000,0x0000000000000000}}, {{0x000e90717067058f,0x000132c47bead613,0x00090e8a449f2111,0x0001c278b92dfa6c}, {0x000a20e5052e4286,0x000d62ef7fbb21a8,0x0005d03da29cea2d,0x0002b105405706ce}, {0x000dda27b321921a,0x000d13a8070a212b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d23cf55c45926,0x0005b98778f5f299,0x0001705a5c8c8b02,0x000b88f43919b71b}, {0x0001fcb92372e0d5,0x00043296e160fa37,0x000a4970a89cc719,0x000334a3ae695fe1}, {0x00051e4b95dec2f9,0x0004d6275a594212,0x0000000000000001,0x0000000000000000}}, {{0x00047e08dd859c11,0x000f2faa12f1b2ff,0x000ffb55ea0ad152,0x0005927a2d49016e}, {0x00063e898a743956,0x0007e768ee6cdbde,0x0009ce79201bbe74,0x000b64e8832a0a06}, {0x000cff0774d3af5c,0x00081d58cc25a522,0x0000000000000001,0x0000000000000000}}}, + {{{0x00027f0e1b46fd00,0x0003f1c1b9a1af5b,0x0003c2c754fc491a,0x0007d3165cbaab1f}, {0x000360310665c2a7,0x000a6d64bd760e64,0x0004ce1abfa1968d,0x000d2b0e1701fb5f}, {0x000d3c4d7b466c4e,0x000f912ebf21257e,0x0000000000000000,0x0000000000000000}}, {{0x000f6e44d2ef47a9,0x000cdeddd0d09650,0x000acd3234c8ca37,0x000cba5fb7244def}, {0x000f3acca56c2d39,0x0004d3ff0e42e4fe,0x0003498d03959e10,0x000b101ed923e651}, {0x0000842e240deada,0x00047140cf65c53a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000420de7a3cca92,0x00078c40b5d961dc,0x0000669c0650c56a,0x0006512b20ea2fcd}, {0x000c80cfdc1ced7d,0x0002dc4c42793f28,0x00014af2a2c66b61,0x00038712d0f465ef}, {0x000a3e10f498de28,0x000eefd43378b1ab,0x0000000000000001,0x0000000000000000}}, {{0x000182339af2de22,0x0000f52743e62529,0x0007cb967f975c8a,0x000a495f3b942e5d}, {0x000442c93c4c7a6f,0x0005ea4e81af911e,0x0001c3361393032e,0x00046ad975cf453b}, {0x0008fb85fbd84437,0x000e9f19bef58359,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001c8a03a758373,0x0002ff5d3c5d987b,0x0008d28755f9b053,0x000696c9a6811aec}, {0x000671a05c762526,0x000b50917885c6fe,0x000e435b1cd97329,0x0007d6424b129ce1}, {0x000fb69b5d25c001,0x0005bf8fd3449e7d,0x0000000000000000,0x0000000000000000}}, {{0x0003b3b4745aa0fc,0x000a304f13caa8db,0x000c42581d38c65d,0x000a26e3f1637449}, {0x00075086fb17831b,0x00070bccf51f20a3,0x000ec67794f66bbe,0x00008759114e8fb9}, {0x000e55fefba15c3e,0x0006b06274e840ba,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001392a85eee65b,0x00037ebdba8a73a9,0x00057c70feb31623,0x000f9841fe6064d0}, {0x000abb8ea58571cb,0x000f4d78e10f9265,0x00010194ea34ee68,0x000ee932bccc86c6}, {0x00018b05ba4d88af,0x000c7f1b666c9e95,0x0000000000000001,0x0000000000000000}}, {{0x000bfc49e59e8fd1,0x000ae405208c75f8,0x000d373c5a99df54,0x000a977279933e71}, {0x000da64aa0b3f5b8,0x00036d2c0da96b6a,0x0002eed5227ca046,0x000b6e0ffb64c414}, {0x000baa05111d0f26,0x0006496cce8a3203,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c440343aef952,0x00019eda15115cbf,0x0004c0ca17c7be65,0x000b899e1e404697}, {0x0006bd56cb968d39,0x00077f25afafaffc,0x000e8460c48baa89,0x000cb8ddcae733c5}, {0x0004e7b4d8db3dd6,0x000d4730c42ef0ea,0x0000000000000001,0x0000000000000000}}, {{0x000ded4336e0e996,0x0007761c36485b3b,0x0003a9ef9b460a85,0x000ea119c163b2e2}, {0x000f8699c32d39ca,0x0009afc21d6fbf2a,0x0006105b2f30acbc,0x000d2782e1795cd4}, {0x000bd0296c5de1eb,0x0003f540db331e94,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=70 [{1,2,3,..,}]*([2^280]*G) */ + {{{0x000566c4dd75c1b4,0x000a0570856265b3,0x000cbace31affa63,0x0002b4ed64645336}, {0x0006de49945b2d79,0x000ffedb2ccdc41c,0x0001239fc3fec1e4,0x00056c094341fb38}, {0x00028185bb5868f9,0x000adaf680572da8,0x0000000000000000,0x0000000000000000}}, {{0x000e0585aa2d876a,0x000b95480f8f0fbf,0x0005be334d530bd3,0x0002f278c2d3c86e}, {0x0006b676d6c82d76,0x00039dec8e1488b5,0x0003e4b756194ec5,0x00094e5ad8a2c0fc}, {0x0001d4129e01cce4,0x000c459cb7e94c1e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e172f71314c57,0x00073776d707122e,0x00007937b43cc86b,0x0005775ac42e1bf4}, {0x00055e0abab130a1,0x000a4930e58a6f41,0x0005a237af5f75c8,0x0004f7ffdb8ee4d2}, {0x0008fe7af47745ba,0x000467da1f09c11c,0x0000000000000000,0x0000000000000000}}, {{0x000ab833ab90a6b8,0x000669bed4019358,0x00007b7fe4d74f45,0x000d834f00a5516c}, {0x000f035a36d318fe,0x000f8a31bb46f3d5,0x000972946e1df3bc,0x0001ef24a7e886c9}, {0x00085864c383ab5e,0x000a5b85a50c0d32,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d65b66d82688c,0x0003872c2925e382,0x00080fde81ac79d0,0x000a2b38a2432027}, {0x0005fa34422b6bc3,0x000948d55e24a659,0x0004efa7ed8f149b,0x00071011867cfac1}, {0x000bd1e94e578bbe,0x000803efa0276501,0x0000000000000000,0x0000000000000000}}, {{0x000f7389f88ed003,0x00099b4f58dfa2c9,0x00027af2024d3bff,0x000a0ca5e0ca7fb1}, {0x00083782dbf7ba09,0x0009fa5d6101098d,0x0005231abdbaa4b1,0x0009c03b0d70ddb8}, {0x000cba60cbb85949,0x0003ba8d596ce326,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ec042211830fd,0x000f78b67d56f78a,0x000d0dd5f0085f0a,0x00077ef6d1879493}, {0x00009d412929cede,0x000f8f47fc6254c3,0x00038136cfbb6a12,0x00090a561c304af6}, {0x00064012770283e0,0x0006e8c77dd363b1,0x0000000000000000,0x0000000000000000}}, {{0x0009730231689c1a,0x00078a2910104065,0x0006adb22ec70366,0x00007eaa5919dc9a}, {0x0000eff75ea6bb96,0x0001b154022f103f,0x0002e9dc4300dcfa,0x00023ebbf1abfdcf}, {0x000c7610a1be47bf,0x000ee8e48e43b23b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000366222079ff20,0x000dd6c255282fb1,0x000e5f65eafcf45b,0x0009b30515c02959}, {0x000efd5074c2f0d5,0x000460bf3169d34d,0x000d88198c4daf0f,0x00042d35aae9cd4d}, {0x0006f8fb3a3e2b92,0x000e5b7ee19179cd,0x0000000000000000,0x0000000000000000}}, {{0x00015c0c8bdd26b4,0x0009fc2499885330,0x000c27ee4ed9b18e,0x000e30d901ee8c44}, {0x000a438c4d057961,0x0007a847d74e4722,0x0005e9ebd34c3ce2,0x00049ec1f371fc17}, {0x00062cfa628ad626,0x0000258cb8ba2199,0x0000000000000001,0x0000000000000000}}}, + {{{0x000414eef61746f8,0x0002f44b16d63548,0x00091c53690466a2,0x000700b4b9b4826e}, {0x00069ba41d6fddfa,0x000f48b184a9d1c2,0x000af1a9a1ae5623,0x000688445e2f1d66}, {0x00028a0ef16e7621,0x000ea0a509e87455,0x0000000000000000,0x0000000000000000}}, {{0x00016c4ebf9d1f30,0x000002405c88d64d,0x00021995ea2cb159,0x000476f59206340d}, {0x0007fbdb47138c1b,0x0001fc51a673c4a8,0x000c132d81d7d81f,0x00033035e2c568d2}, {0x0001981e0c2e86c3,0x000c9f25fcaa15dd,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b2a49ca5dfb81,0x0008d370aadb7c4a,0x0009f4ebf1398343,0x0004d610d25c9ac8}, {0x000b49c7f0f75d8d,0x000cfed5c3ca14e0,0x000cd7f4d6f7590d,0x0007d93cbfaa36f5}, {0x000dce79a65cb3d1,0x0004b4bd97f1011d,0x0000000000000000,0x0000000000000000}}, {{0x00001207087dd6cd,0x00049477a85a518b,0x0007671964d279a4,0x0001d11aff88af2c}, {0x000a1dbb6c2c5f27,0x0005ba326b82395c,0x0003c2898f431018,0x000463dc513c0cb7}, {0x00069f2786b20305,0x00061fc5c18db944,0x0000000000000001,0x0000000000000000}}}, + {{{0x00080adc636061c1,0x0006244e403a263d,0x000ad04e1deab320,0x00059720dcbb6130}, {0x000d66e8505322a2,0x00060fb3f5231b1a,0x00049e1cd79b6e2a,0x0006179c366e663d}, {0x000c6ea0d01277eb,0x000473883c4ffde6,0x0000000000000001,0x0000000000000000}}, {{0x00040167fca5210d,0x000d95aec71f687e,0x0001c63bde59a231,0x00074dfa4af79a44}, {0x00060fd79e68ddec,0x000b613ae2a19527,0x000036b08e61ca70,0x0003e30d2b549e73}, {0x0008fb383d922e0f,0x000aa028c146216d,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=71 [{1,2,3,..,}]*([2^284]*G) */ + {{{0x000090e2290855e3,0x000c63856faf70c3,0x000a537fff7cf9c3,0x00002007d0317a7a}, {0x00010dc853b3261c,0x0006ccdf2c616875,0x000385cd6f188d53,0x000a2955fa1d26fd}, {0x00087bdaef2d7d6e,0x000b0f3173148e30,0x0000000000000000,0x0000000000000000}}, {{0x00084c9a254216ed,0x00047cc0770de6d7,0x00035e4c8fa4bf8c,0x0000f637aece660d}, {0x000adedb7b99e891,0x00082ce72b5ced4f,0x0001d4d0fa07446a,0x000194600c851570}, {0x0004ffcea4152f30,0x000c96f31c15edf3,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005b1c7831bdcc8,0x000d027bafc7d23f,0x00050c19efdbe5d1,0x0007a7533cdce225}, {0x000573af279d2535,0x0006015a5e144120,0x000803b571412097,0x000eb203384ac91c}, {0x000edd68012ba72d,0x00091d825c3d8d2b,0x0000000000000000,0x0000000000000000}}, {{0x00023553a39f8385,0x0005b8eaf27fe164,0x000c4539fb7ef933,0x000adc9ffa5830e5}, {0x000950a5e503466b,0x0003a2a96a1dcbb8,0x0001a89a62dca0dd,0x0001d5f98db48a88}, {0x000554b9506e0a31,0x000dcd69efeec8e2,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b8cbe4b97fc6c,0x000e5a71915ba245,0x00044263935f5290,0x000ce189775a8de5}, {0x000cd0549c8def51,0x00027c89477b9645,0x00047cfbc54728e8,0x0000c7cb6412bf4c}, {0x00016bf97806ea22,0x000feea61b447d92,0x0000000000000000,0x0000000000000000}}, {{0x000a3fafee06d0a1,0x00032a2cf4c624fa,0x000baceff4ee9dd4,0x0007411d429aa2e7}, {0x000d154759f7bffe,0x00091cde409d4d9c,0x000a9a31ac9508e0,0x000deb0f736891db}, {0x000c17f78c058b52,0x000b43e218c9736e,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000f4f238352945,0x000f07d445a023b0,0x000551441addd54c,0x00008f85e62fb5bf}, {0x000ffd275f3aa334,0x00001eb4ed1f4e87,0x0000af1b08c2f8d7,0x00093b5987facbec}, {0x000542336f0bc311,0x000587219a8c1237,0x0000000000000001,0x0000000000000000}}, {{0x00052f04dae724bc,0x000e221a68b0a55d,0x0005bdff6f9d5fa5,0x0007e3f2da24e831}, {0x000628b43c649948,0x000a393f548cc549,0x000acee934d621cc,0x000e0ce12d1b52e8}, {0x0000b93c4f0e6025,0x00077116663ffdcb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b53f717a44956,0x0002c65fee76e1bb,0x000ae70d2da363ec,0x000cd6887a61f9c3}, {0x0002283a4e23325b,0x000ae6d909c60aab,0x000702a1dcca3dd1,0x000938d6a31c5517}, {0x0003e01f167bc2d3,0x00067596be65d549,0x0000000000000000,0x0000000000000000}}, {{0x0007978a4e132cb0,0x0005df10adf1702e,0x000364f7e05324c1,0x000693e3866569f8}, {0x00082e303b6c9df3,0x000298933d134854,0x0003d7696e64c215,0x0000f465322046cb}, {0x000e839e686c1c09,0x000b7f8ac2e6f682,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e71627b708629,0x00012bf54385d85d,0x0007bb4ab478b057,0x000a3b2ccc6b5489}, {0x000f67fa6f6a05a9,0x00073cd5233bfef8,0x000c4c4f505a80c7,0x0006a3fe8c185c9c}, {0x00059e110f37ae33,0x00054cb440dc7a62,0x0000000000000000,0x0000000000000000}}, {{0x00050c98bc7b0e1e,0x0005a04b3793331e,0x0003b8d31034a8aa,0x000c95dac900df01}, {0x000fd52027ee1c99,0x000b5be3aeb891a1,0x00042f3b68574224,0x000ae00bb37d5ba8}, {0x000a7f31f3f36375,0x0008c304743a2813,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c7e03b7aa645a,0x00091f7e39a28977,0x000995d7d443d68e,0x0009f39216c442e1}, {0x000b376cc21c4025,0x000705644f75967c,0x000592e3b90bca20,0x00056be0ef613507}, {0x00097f2f7456e836,0x0004b46438409baf,0x0000000000000001,0x0000000000000000}}, {{0x0005a21df85e1c6c,0x000b0ab454500393,0x0004c5912b476c6d,0x00065a0d1aa49d94}, {0x00059cdd7e7069d5,0x00090a402b7eeef8,0x000283db40b228bb,0x0005dcdf2c268733}, {0x0005a42d37d44810,0x000b80e5d1af0360,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c14cb537e819c,0x0005f2b3bf6b7569,0x000cc275187a0bac,0x000925ef6c2d559b}, {0x00025a54533380eb,0x00019f0d6cd0382a,0x0001433bbf74a021,0x000bbd994d4caf68}, {0x00027772c53999a9,0x0003af249226a38d,0x0000000000000001,0x0000000000000000}}, {{0x0006a46b5b493127,0x000bee887c8f7779,0x00045dd063eabbf7,0x00029199a0a8e117}, {0x000918d22e28aea4,0x0000ecebe77e69a9,0x0007cecb0ed2deab,0x000637aa98d20edf}, {0x000a194790e52888,0x00060c73078fbd0c,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=72 [{1,2,3,..,}]*([2^288]*G) */ + {{{0x0009af391a8697ed,0x0007fe5bb7320546,0x00080d05ad03f5f9,0x000f9b7973b1a3ca}, {0x00033b52add9800a,0x0003cc487ccc82c5,0x000f71a0da2ae069,0x000c060c7047e46c}, {0x000a21503aeb64ab,0x0004ed0075b1d33a,0x0000000000000001,0x0000000000000000}}, {{0x000a2bed91298551,0x0000c49a79f6b129,0x00022374a19da463,0x0001305962f001a1}, {0x000a3a3cc4dcc90a,0x000188b4cc026cef,0x0002ff30fbb1d3fb,0x000c36e3761cad09}, {0x000dbdbdc6354b93,0x000b2ab73317cff3,0x0000000000000000,0x0000000000000000}}}, + {{{0x00003f3665635e4e,0x0004e17fd85da26c,0x00052fd006ed5f69,0x00032d252f043a61}, {0x0005c8bc9cc74510,0x000f5370ca9348d5,0x000540b56333c4c6,0x000bc9a5ca533610}, {0x000d8071b716d25c,0x0002367337f70a39,0x0000000000000001,0x0000000000000000}}, {{0x000db6fc5387c11b,0x000cfd3251b14397,0x000d84aa2bfdb755,0x000e38100cc3e62a}, {0x000046071f1f89e9,0x000e7012d9e47fb1,0x000e6ad97ec5c7c3,0x000698bc4de4f6c7}, {0x0000c6a07a4e7cef,0x000198a03a3a1224,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003b8713123ec24,0x0000419a51d2d151,0x000c8ee7e2c9c855,0x00039f110d3d8f17}, {0x0008ce870e320ac3,0x0000d4e71030e599,0x000ace1a5cbbd4da,0x0007c15bfcfe41d9}, {0x000408b36096093d,0x0006b26a0c56d39a,0x0000000000000001,0x0000000000000000}}, {{0x00035ac9181317f5,0x0008d46d26280ae2,0x0003c29370c4bff6,0x000addee48f7eaa2}, {0x00030f605627b203,0x0003e03ba6674883,0x000cdd81ae186660,0x000d8bc04a9667b4}, {0x000cbc45ee0c1b5b,0x0003d34e81dc5ff7,0x0000000000000000,0x0000000000000000}}}, + {{{0x00063b161dddd94b,0x0003d7c93f0cc576,0x00022d6ac11071af,0x00012d84b9149bdc}, {0x00088e44e4632e63,0x000448cc8ec50d4c,0x000f89a6c85277ac,0x000e128700eabfe4}, {0x00042928ea38e5f2,0x000e293e261880b7,0x0000000000000000,0x0000000000000000}}, {{0x00051028cc113b68,0x0001919b6a14e2fa,0x00082dfd5da09549,0x000ca662e13022a3}, {0x0002996fafc24233,0x00018dea4f505fe4,0x0005a2d96182166a,0x0000199ba55815ea}, {0x00077232622a4ac8,0x000311b13c3b8133,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008673adf41d204,0x000e2a0a390575d9,0x000dcb844f35fe0b,0x000b6f4f917550d3}, {0x000fc6ecf7285d09,0x000925f580342d9d,0x0008746022d9fb4c,0x0001b6b73d4bc619}, {0x0004aa1c30d7a3bb,0x00003bf32bccb3c5,0x0000000000000000,0x0000000000000000}}, {{0x000783e73d6e9052,0x00006db6e57f7b8e,0x0005d1afd274f869,0x000318770758e016}, {0x000290175b314342,0x000e6d25df464413,0x000da9ee1f0d5093,0x000297855e553138}, {0x0007c7b64937a717,0x00057ccbf262664b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d9056eeba30b5,0x000355a8c404c7b9,0x00039ffec5e11fca,0x000c3ac7b4f4c637}, {0x0001ace1869851e4,0x000e1816afc7de47,0x000d517fb7e6978f,0x00040e256f62bd56}, {0x0004bb4c53034a6f,0x000aa98eb4b9ad2d,0x0000000000000000,0x0000000000000000}}, {{0x000fd2909662ab1d,0x000c55f8463596cd,0x000074f62f74b11c,0x0004dfc43f12c5ee}, {0x000ad69405653ae5,0x00089f1d6e4668a4,0x000187ca431697ab,0x000831cc4eed080d}, {0x0003a69f7d775edf,0x0004e434435eef6f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a1403851eb93a,0x00085c9ae49b53f2,0x000926a512455b57,0x000ca729dbef4a6b}, {0x000b8440248e399a,0x000191c77a9a0e66,0x000873c8f27a8296,0x0005408861a08ed7}, {0x0002bbe9c5e3865f,0x0003549235be42ba,0x0000000000000001,0x0000000000000000}}, {{0x000a46fbe3334020,0x000abf1524bdbc9e,0x000b376fa382ce55,0x00075b35cc1fb214}, {0x0000910d13b19369,0x000cf5d3212ad3b7,0x000c7e93b691b3bd,0x0001ba22d0312eb4}, {0x000285b3975e5da3,0x000c999e2ec96eee,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005bf15f46be575,0x000a1061cb09c821,0x000ae2de789e5912,0x000cecccd84851c6}, {0x00001b95ccd21d74,0x00032dddf26a2851,0x00049210122d3f6d,0x000f02c5d952db55}, {0x0004be99796a4aa1,0x0004078cde88aab2,0x0000000000000001,0x0000000000000000}}, {{0x000d753b80855f9f,0x00078288aff9b92c,0x000f7cdce61cc49d,0x00048cc3dac4e445}, {0x000cb0ac2a937fad,0x0008c5bdda956fdf,0x000bb3e81841ce29,0x0005170e6c819f12}, {0x000efd73ecab58ad,0x0000f476a3a48130,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=73 [{1,2,3,..,}]*([2^292]*G) */ + {{{0x0004f332dc67a3c5,0x0003213d82a4383a,0x0000fc0621356af6,0x0004ca32ca05acfd}, {0x000c1e80103ea886,0x0009dd0ff4c2e9c7,0x0009d764c64b7589,0x000680c128a8c988}, {0x000fdb7cd881a125,0x000ec5f09f58ad77,0x0000000000000000,0x0000000000000000}}, {{0x000ecd4f9cda86d6,0x000c4c41a633a8c6,0x000847c2f58ecb1f,0x0007b29592dae51a}, {0x0006e268f50e3a7d,0x000a27de2a3b5eef,0x0006d540d7a599e3,0x0000d01f9b571491}, {0x0005e52e5204fbca,0x0003d9eb48615c67,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d9eaa867420c4,0x0002f7f5caa2ddb0,0x000c31038c0ddc32,0x0001596a08fb4b57}, {0x000a6d9ca6980a65,0x00095c78a8ab32e2,0x000ba78e5808eeac,0x0004f5f9923d5a32}, {0x000ad1c8d3bbece3,0x0007098f8b845926,0x0000000000000001,0x0000000000000000}}, {{0x000843645beef787,0x000fa28875d75316,0x000e13608c5a90e9,0x0005556eaf90c364}, {0x000dacc40e05857e,0x000c5012b59e332d,0x000230b2b76768f9,0x00032932d53c8a76}, {0x000999fbd573bdff,0x000840eee9300114,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002362363f6901a,0x000be66748446167,0x0005f5c47c0db36f,0x0002fbb39fb54024}, {0x000e344525a7871f,0x00071375bdbedf63,0x0000bd89f085fb8e,0x00001c59b6e647d5}, {0x0008031fa2f2ea43,0x000d9b58012b6657,0x0000000000000000,0x0000000000000000}}, {{0x0003015fd48eca8d,0x00082cfde2151d47,0x000e4d908c99616e,0x00004977d4ec3b2f}, {0x000f513df9ad204a,0x000b66641e3ee923,0x0009df2175bb5d92,0x0004cdb5c3c90fcd}, {0x000de8809fac5725,0x000985c6981a627f,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001a0d912586411,0x0001b0d49fbe5702,0x000bb57b277de5b2,0x000a4b2d7291e7e7}, {0x0008c16da29ce1e6,0x0008f8b71f4426f8,0x000fbf76a6ebaff6,0x000cab510adb9995}, {0x0004b996a6ec18d2,0x0003bc3ce11f1f8d,0x0000000000000001,0x0000000000000000}}, {{0x00004c4051321f3c,0x0003af34703d798e,0x000dd55e68b6b0a3,0x0007f09cb14161e8}, {0x0005357558d9c473,0x000d9a485a90c00b,0x000dac2508e73fc9,0x000ed252e5f5bb09}, {0x000b1efcb4ba2132,0x000593c58bf23933,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d1217cba9c6d8,0x00087cb7a562f7c7,0x00004fa0d0ea0e23,0x000c05e3acd8379e}, {0x0006d159e80cdee0,0x000029ffd63834d6,0x000500f3ee777b61,0x0007b75be130d659}, {0x0003756de768a261,0x000a541b809584c6,0x0000000000000001,0x0000000000000000}}, {{0x000af54a67204972,0x00085857b547d484,0x000954a25746036a,0x000bc1881e0295bb}, {0x000d3d231831b4de,0x00002708fd517190,0x000b1e9571812770,0x000c3e25dfa6c88c}, {0x000fb3c57a9f5467,0x0001d404949d8103,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a34fad1eabbbf,0x000de71fa7ad8210,0x000d67acfecf1047,0x0005ec7ec527279f}, {0x0007906ba2abc3a7,0x00066a25ce54f7d9,0x0001e7d558ddfb44,0x000ba77bccd91efa}, {0x0005405027796dc3,0x00072f9ae8e511f6,0x0000000000000000,0x0000000000000000}}, {{0x000feaa4cfcc2a79,0x000d60cf749b854d,0x000ac1632a7218b2,0x000a7ce21f4e0ce3}, {0x000550325628caf5,0x0006b7d84c8e6b8a,0x00081d8e5bd9a461,0x000bb7affd9d5730}, {0x000dca775afff520,0x0006a52e629d73fb,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008f6b8297fa26e,0x000d76f386ac99ac,0x000ce235f3a2acb0,0x000620801a076df3}, {0x000c62031f455ef8,0x000d6e488b1627c3,0x0008ebc5bf3c9afb,0x000c4512c254ea59}, {0x000abb87bcef237d,0x000cb4dcacb5a5ed,0x0000000000000001,0x0000000000000000}}, {{0x0008e7718ef189e7,0x0004207cf70cc015,0x000e9a66810fd747,0x000d69bb7c99d1b5}, {0x000454409a3962cd,0x00014e1d3b541825,0x0008bec33aca5afe,0x000a9c5e4a92268e}, {0x000bf2e95060a307,0x00093a289c336375,0x0000000000000001,0x0000000000000000}}}, + {{{0x000781a84aba36d2,0x000ad7584291d55b,0x000992c0a266ea73,0x000e02af20e9954c}, {0x000ca4d73d175169,0x0001612ee12718e0,0x000cf1ded50926de,0x0008c1060d91c638}, {0x0007dc332b5998df,0x0002624eb7dc884b,0x0000000000000000,0x0000000000000000}}, {{0x0008eae21aadf4bc,0x0005c2a9f4bf2cd7,0x00086c74c6b37272,0x000a4de4b5b5158f}, {0x00093ba4800d6736,0x000138590e451f46,0x000263ed2239cb95,0x000545bdc4c56f5d}, {0x0006676d4c0f8acf,0x0004038bbd0743d0,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=74 [{1,2,3,..,}]*([2^296]*G) */ + {{{0x0004fe80d04c169d,0x0001452da244cb71,0x000cda8b72206f04,0x0005887084ee9fa6}, {0x000920e111da7c3d,0x0003bb35ef1c2673,0x0008e61906e57c45,0x00073eebaa206a85}, {0x000dd3b5bf458238,0x00015dcf71c4a720,0x0000000000000001,0x0000000000000000}}, {{0x000605cdd81e2955,0x000ac0e98756fb91,0x000f0286c4ccda7a,0x00017819b4372718}, {0x00031dae0a5d8a40,0x000720f8cb219351,0x0003217261dafa40,0x00006fb18c8c40e0}, {0x0003c7d483485194,0x000d46e02770cacd,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b16ebe5676f0c,0x0006e7f47e5b4652,0x00071c81701e6ae3,0x0007f8d6e3a4cc33}, {0x00067b29431c31ae,0x000869125faeb29c,0x000fd62e16be2afb,0x0004934ce6d0052c}, {0x000cd74901063882,0x0002e62b021800e1,0x0000000000000001,0x0000000000000000}}, {{0x000a39e3523a9de5,0x00076121f34b3253,0x000d9c36b4aaa3b5,0x000b23992e0442ed}, {0x00023d2725144419,0x000ced8d6e4d3747,0x00011186d58a7080,0x00050cd63ed11b1f}, {0x000c6faa6d7a4d0b,0x0002559c897561f4,0x0000000000000001,0x0000000000000000}}}, + {{{0x000657d806465325,0x00095fd29c362706,0x000e70b9e028365a,0x000fa40d084d6b18}, {0x0009d80bbbcfec68,0x000a06728aae56df,0x000361eb62533738,0x000dc77e1c92bd4a}, {0x0004fbeefd3c11b1,0x000cfba52dffafa9,0x0000000000000000,0x0000000000000000}}, {{0x0009acb1f00a47f4,0x000024e668d3f2f1,0x000095d2d5d23cbf,0x00076b697f105b84}, {0x000da5b550d7489f,0x000c9d3a15e73345,0x00093e0d2b26a8fb,0x0001e4494adfd6a2}, {0x0008e6417e038745,0x000fb0b051833181,0x0000000000000001,0x0000000000000000}}}, + {{{0x00013685fee3f167,0x00059193a123f397,0x000f28bae616ef5a,0x000d2c6567b33050}, {0x0004dae5b6596da7,0x000481adbd59fc9e,0x0002c1618dde4a40,0x0001f2a194682fe9}, {0x000c05bc15adc043,0x00013edb30fcceea,0x0000000000000001,0x0000000000000000}}, {{0x00047d7a2900c6ea,0x000e954cf35b8dee,0x00074908606c425e,0x00094a88cdac359e}, {0x000fbef2c858622c,0x000d0f745810d20b,0x00041d71ca77f658,0x000782f59f1e4267}, {0x0004af36c640314c,0x000e35ec0709c829,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c5c739f094c18,0x000b75fcd89a8d55,0x00071a4d047c0dcd,0x000ef9a3d498ccfb}, {0x0008f669e7edb8ba,0x0008d6b13c20d8ae,0x000a564d16a48c79,0x000250d241703f4c}, {0x000680ef9509f9dc,0x000970b2c17a388c,0x0000000000000000,0x0000000000000000}}, {{0x000778808942861e,0x0009abe8d8d33c23,0x0009bd2fb189dd26,0x000112581e8769b1}, {0x0009d657bacd662b,0x00084fbcaa8521c1,0x00091c546adc05d5,0x000c68fad3f4e938}, {0x00057bce78617aeb,0x000701e39a422608,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d79f624f8eb1a,0x0008e9c5d103b9cf,0x00071b65a5829554,0x00034991b8462f3d}, {0x000b51453c2b2409,0x000cf62fb341c087,0x0006cdb37eea50d1,0x00027ada571b02ab}, {0x0009e677d1b49b69,0x000004b52dc4d6da,0x0000000000000001,0x0000000000000000}}, {{0x00042f171b839d5a,0x000765b6cceda32e,0x00009960889dbcc6,0x00040e8e2e336d9f}, {0x0001f34cefd7de54,0x0008bc6b5ab410a8,0x0000cbb91782d60d,0x000a95e22f3046d8}, {0x000775cf7c99291e,0x000282ca473be09e,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b6a03ba3e1ec6,0x0006b7fefa851ec2,0x0003a92f6680a7bf,0x00075deabf4905c0}, {0x00096ff483a6ae8a,0x000c163b2b784673,0x000be098999b6fbd,0x0009c4a535388968}, {0x000b8e919419a12c,0x000b0bd87c889640,0x0000000000000000,0x0000000000000000}}, {{0x000f69e3681b9e47,0x0008fc5971b3c868,0x000bd601db453ea0,0x000aee960ff01a96}, {0x000a0347158b6a72,0x0008994151ef1dc3,0x0007de4b70d9ea4c,0x0005a29068423993}, {0x000e4276c73a1788,0x0008a834f8bee71a,0x0000000000000001,0x0000000000000000}}}, + {{{0x00059366b70a0b8b,0x000d60abadb72457,0x00087caf5b975b84,0x000cc3f1983f793d}, {0x0002e94d8de541ce,0x00090b687cd8885c,0x0006b6cd952f2acf,0x000016cc05b6d504}, {0x000f97cdb266e5bb,0x0007c95959c78452,0x0000000000000000,0x0000000000000000}}, {{0x0001e70e0efd1f63,0x000528c8989bfc93,0x000c244410e36663,0x000645d5f14f2667}, {0x0008cf8059cc8bca,0x000d2134f71c94e0,0x000ba7b1d1a84e91,0x000e21c35b983489}, {0x00003bfc5dddbab1,0x00099886156a8fa3,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=75 [{1,2,3,..,}]*([2^300]*G) */ + {{{0x00083fd796b1a72b,0x000c549640b910ec,0x0001f3c076c5166d,0x000b7e4e553ff932}, {0x000e97e2f7e676d2,0x000a2cdad5097c11,0x0004bc0c5cedff5a,0x000757d09eef397f}, {0x0007434958d95f66,0x0004eee32eada9e7,0x0000000000000001,0x0000000000000000}}, {{0x00041f85b3f06836,0x0003aba0e3496ce6,0x0007931548ea6b77,0x000149273aecbf5b}, {0x0001858c42c5d2ef,0x000ddc70d91528b8,0x0008d341c157c1ef,0x000a690e10df0a32}, {0x00064f5d30760fd8,0x0000d14ec3b44ea3,0x0000000000000001,0x0000000000000000}}}, + {{{0x00087f011572bb6c,0x0000d126f1e48db1,0x0000d05c4b7b6201,0x000a2ba1e0fbe5e8}, {0x0000224d802f13f0,0x000e0b8698189e96,0x0001b4bc0b8af43d,0x000c706b742b2859}, {0x000d9196336bf7ae,0x00007fec0d2fd363,0x0000000000000001,0x0000000000000000}}, {{0x0000b0b6ce7179b1,0x0007cde982e3e244,0x000d814a6fad99d6,0x0007d3497edfbb4d}, {0x0007a46c6afc84ac,0x0004cd907a63bbd7,0x000909a18bcc3d68,0x000d756b5193f098}, {0x000f37ab5d6e0581,0x000ffb06adf4d102,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000415e4f4b1ce2,0x0002f16bd8544ce9,0x0003e7600d6c664d,0x000d9aa401912f05}, {0x000dd3e0c268e1e8,0x000f14013443dcda,0x000f59cbf936e212,0x0004b8aaec39252c}, {0x000d652c200b8cef,0x0000aac64c11e47e,0x0000000000000001,0x0000000000000000}}, {{0x000c08e2e7a2dfe0,0x00048459176893a7,0x000c7c5a8f0afe8a,0x000e999b6f043d0d}, {0x00000b3c3cfd6e33,0x000b4fbc5e2a496c,0x000f5eee2690de5c,0x00073d2db4511dfa}, {0x000fecdd2743e927,0x0004f4ade6a1948b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000039609cadf211,0x000339488fdf258d,0x0000e39945a1e037,0x0009a8444d16fa60}, {0x000c454408c23f53,0x000ef729fbf7f8cc,0x0001fe369b8abc6b,0x00053dbd87a47666}, {0x0000f6266a890341,0x000de3c7b4bcd279,0x0000000000000000,0x0000000000000000}}, {{0x00006e205ec9aa47,0x00063cce1af477a4,0x000f7fcf64572e77,0x000c931743d00999}, {0x0003902adccdc1f7,0x00041be26f8b87a1,0x00006779ffcb96f5,0x0001c0636264bb59}, {0x000484331c0db1d6,0x00076e5585c8ae19,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005899b377cc15c,0x000f315fff92e2e8,0x000a8cf599eb4a44,0x0002e4cfca1a3e87}, {0x0003f205f34e217a,0x0009eb1362e4f28f,0x00061c84aa7c205e,0x0006fa76515b6ace}, {0x00083aca37e55058,0x00030435e870f8ec,0x0000000000000000,0x0000000000000000}}, {{0x00002203ed113de7,0x000655318327d42e,0x0005d903904004d9,0x00094adb7cd1d2f1}, {0x000ebca1242c89d2,0x000af2a1423b5bb4,0x00066f393818e824,0x00079a30444115e3}, {0x000183b2cd6a53de,0x00047bfd324d8249,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001ee196db2cf29,0x000718a1d049034d,0x000acaf386ae53d6,0x00006d746605e4e6}, {0x000c4458e136fcc3,0x000b7a1ac677dc40,0x0006ee4bb331955a,0x0007b95c386ed47f}, {0x0006640fb4384103,0x00081000a37bb752,0x0000000000000001,0x0000000000000000}}, {{0x0008cc55b8f1bcdb,0x00025171d84cd78b,0x0001b8eb12ee7e03,0x000bd8c564c45f59}, {0x00076c2283df12d7,0x0008a36461b03bfc,0x0000c8cafd6fc812,0x000ae72b6275a058}, {0x000438282511c376,0x0008780ca3213fce,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002c0f6f353cadb,0x00056c17179cb81e,0x000af140db008101,0x0001bb5e63cd1fa8}, {0x000b0729533d8217,0x0006676827544c77,0x000fe1b0143af56f,0x00045a759df2599e}, {0x000962b593accffd,0x0007a3c61321e555,0x0000000000000001,0x0000000000000000}}, {{0x000e58a6aa5358dc,0x000739bb4d42d566,0x000e6ef3760e0cfd,0x0004fb370620ef46}, {0x000c2253e0f9e680,0x000b5c8c64f4e9cd,0x00008daec6f6658c,0x000504153037a80d}, {0x000215b47cc959be,0x000e4e7aaaa8653d,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002bc233166381e,0x0000199700029af5,0x0003201dddf2a837,0x00085cdad02e2c74}, {0x0006daea6cd36d88,0x000c3f784e7e3512,0x000e882fa40cea6b,0x0001eec16a3a5130}, {0x000c43706ace2f12,0x0009ccf3c3a16a13,0x0000000000000000,0x0000000000000000}}, {{0x00064823f9e7a6c2,0x0007bae8e4729ac9,0x0003fe54edfeed8d,0x000a4e7bcfba42bd}, {0x00039e917bf88ec6,0x00004163c606be20,0x00009b017d5a63a6,0x000c276869bd6bdf}, {0x00094144ff021410,0x000a13f038cdd94b,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=76 [{1,2,3,..,}]*([2^304]*G) */ + {{{0x0002f8bd1741a941,0x000d4f3177637189,0x00060a2c8b16c0b1,0x00012ea49a688a19}, {0x0004556eef3eca0d,0x0000c833814746c3,0x0008d8b842db71e9,0x000b1bf4ae9e3fdb}, {0x0000ee706bc576b9,0x00054e85a8de649e,0x0000000000000000,0x0000000000000000}}, {{0x00032799b9f19edf,0x000975259805923c,0x00076f95241c4760,0x000d3b18d6c8d637}, {0x000fa677dee0ddd3,0x0002ad9334e5bcea,0x000ceb27ca464781,0x000594d56dac3990}, {0x000338deb39d6e55,0x00096c7a9d83d78e,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d7b49014b2147,0x000f134215e0ae52,0x00084df8cb33a781,0x000b10bfaf858985}, {0x00065449e13a9c3a,0x000859368bea1a4d,0x000d78c2c8134dfb,0x000ba7d94439b51f}, {0x0003f1c754b1e6f5,0x000d464cf5d47b00,0x0000000000000000,0x0000000000000000}}, {{0x000c286403cdb3ba,0x000c15d6597a8e6d,0x000e5e853fbe3d2a,0x0004c9898bd192da}, {0x0003c76032d13f80,0x00038d5e8bdb66ee,0x0007ea1349bcb167,0x0001e4001679e16c}, {0x000f1f584d22ec20,0x0007b7d9f317a982,0x0000000000000001,0x0000000000000000}}}, + {{{0x000196d862941c7f,0x00015fd4c9380d4d,0x0000a23a9cf4968a,0x00039223ad85ace8}, {0x000b20fbe77f6374,0x0003ae3be886de7e,0x000a36dd5eea175a,0x00061d0a78e19da4}, {0x000a64f9638a5733,0x00007bdb82dd1f3a,0x0000000000000000,0x0000000000000000}}, {{0x0007fe74ebe49201,0x000a7702be0b4d0b,0x0000cad19bf2f6ec,0x000d6c0b5b514f13}, {0x000c08518708375c,0x00035c8f337b8d0b,0x00055fc06adb3974,0x00083bfc4b137fa3}, {0x00045b3d91207a07,0x0009d53cd23a6fdf,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000a67f092fe026,0x000e142efbca10ec,0x000cc433a343767e,0x000f6b9e68131944}, {0x000e836fcc884370,0x0005328231b4d1b5,0x000895d85b956e68,0x000117afd7ce3e4b}, {0x00028a48e23cd96a,0x0007756cbf1cc4fc,0x0000000000000001,0x0000000000000000}}, {{0x000c45bb98d0ddee,0x0002774201b8565c,0x000b4f52020bec2c,0x000bda65cd76ab62}, {0x000ae2fb221ac3aa,0x0007ba962fd348e9,0x000e7c381d5e875b,0x00068ae119edacdd}, {0x000b495d57186eb9,0x00056fdf795bd0d5,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003ca5ab59ddb41,0x000f7f1ebc9c6cc7,0x000f57e85f634cbe,0x0005a16eddf122c7}, {0x000c8a63efc695ac,0x0003541555a07f9c,0x0002a4d80e98783f,0x0006230998aabf3c}, {0x0008cb24667129fc,0x0002de1b3b8ba86c,0x0000000000000000,0x0000000000000000}}, {{0x00062aec0af56692,0x0007719a7045c1fc,0x0005b9718436f251,0x000c9b5d581f4e26}, {0x00069b5489f5725c,0x00051e7c1aa8e91e,0x00028ec256fe93ea,0x000487a680376ebe}, {0x00030e63df392cad,0x0009887cd96ae342,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e42367a9d725f,0x00039383477d80ab,0x0009bf84781ae655,0x000527eaf1389d3f}, {0x0004102ffac6350d,0x000a3b0583300052,0x0001cf3332af83e5,0x0006d633aac030a5}, {0x00033508c7e87b5f,0x00094e54cf554461,0x0000000000000000,0x0000000000000000}}, {{0x000f352ebddfa61b,0x00025e3d5e304a79,0x000673478bec8a85,0x00072acfcd082890}, {0x000446528a7ef652,0x000120a7a607746b,0x000c8aaaa126f2d6,0x000e0714c411ed8d}, {0x000219322242ecc1,0x00076f4dd29b9909,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c19050d8003bd,0x0000966c18887790,0x000653ed598ed239,0x000bbd18179a89ab}, {0x00050e32e18d6ebb,0x0003a242275a6e33,0x000cf9fda141c240,0x000cba7fbc6f732a}, {0x0007d9042bdcaed5,0x0004cddd17f09749,0x0000000000000000,0x0000000000000000}}, {{0x000dc494bed8e1aa,0x00072f9b4efbdcb4,0x000846e40ceacaf0,0x0008e7a08c964b79}, {0x000b697992c6dba0,0x000a31236d2a3b33,0x000f13c67e503cfa,0x000758371b2297ad}, {0x000a30fe4d1b0d5b,0x000937f2f3ba13a0,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001e3e792f54f5e,0x0002d66e1c349e9d,0x000411c782a7cb86,0x0004b067774f6f73}, {0x000f3d88b7029f91,0x0008ac9342be145f,0x000fba10730a2fc6,0x00017ace014c77dc}, {0x0006ebecfe34f062,0x000f04b7a85b9087,0x0000000000000001,0x0000000000000000}}, {{0x000e45d39d99da4a,0x0006122af68cfe2b,0x000beab553aeda14,0x000338ecc8cf47bb}, {0x0007a9f26575d185,0x000dafc93ebcf570,0x0006b569b4f26152,0x000a1c5170968500}, {0x00059575a58e4408,0x000d43a451b6b327,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=77 [{1,2,3,..,}]*([2^308]*G) */ + {{{0x00031eea8652aa77,0x00075a9b33eda2b8,0x000ccb42fd2dd1ac,0x0005ab8fe55769fc}, {0x000ee2ea2c9e4a86,0x0008effb93c60208,0x0001522321dff3f2,0x000e5124fb782d6b}, {0x000f961e96e29dc3,0x000a6d2f39193c4c,0x0000000000000001,0x0000000000000000}}, {{0x0005e63b7e317479,0x0009d667da851f03,0x0007183aa797e9f3,0x00059f9fe886c75f}, {0x000d96d9e68574aa,0x000ee25277706045,0x000aa94b18ceb8f2,0x000d5bc3971ae4bc}, {0x0007b608157fc8f0,0x000150dd6428487b,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003f45b89aa7776,0x00091f2af99e2d25,0x00076414d1e112b4,0x000800014a8e2b12}, {0x000ffa17691a71c3,0x000bd4233ab0f6f9,0x000bd49cf4e764a4,0x0004012735f0ccb8}, {0x000037d3dc7fc071,0x000ae03da811ddf6,0x0000000000000000,0x0000000000000000}}, {{0x0004a8fb960d3228,0x00048eb39e1a42f2,0x00007ea05b5a3c40,0x000b7bd9d581bb93}, {0x0008feeb6ce36fa0,0x0000329bb28b7b8d,0x000e608fcc8cab6a,0x000504c03b085c44}, {0x000593cce3f2c4c9,0x00093bb2ef5a3d51,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005eee4a29b9e00,0x000dc20740482d3d,0x000e9ca5a465e210,0x000dbcf9b04be3f8}, {0x000cf79a10d11c21,0x00098890d16c757a,0x000df4eccacfdb2e,0x000f11b8ece9836e}, {0x000bc4d7a9a35695,0x0009ee2c9b7d003b,0x0000000000000000,0x0000000000000000}}, {{0x000e2dd26ff13203,0x000133cc51c6bc72,0x0009ca679c2a2da6,0x000951011dc4426e}, {0x00093bedba6ea308,0x00088d9217c2a099,0x0000e9979694eb83,0x000d521e97150620}, {0x000035d356c66be4,0x000161e2cef90abf,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002a5d7a2fe5424,0x000c5abd77fdcc05,0x0007ae8084591e67,0x0006481030c17511}, {0x0001f92e55b534fb,0x0006bd1eba6c21b3,0x00096514d056aef9,0x000df597cfd93bd8}, {0x000c4de2939ce9f5,0x0004ef6737cbaf10,0x0000000000000001,0x0000000000000000}}, {{0x0006ccf17f5b4aa6,0x00049ba070d7b272,0x00033084cb0ef8a2,0x00018fa7fece71d7}, {0x000e7f11b328ddbf,0x000b8c5b898e7f8f,0x000699bc5842d33d,0x000944b7141938ef}, {0x00039a13d619477d,0x000d5228db36f5cd,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b8747f420dd4b,0x000fb52bb177eca6,0x000f43dcaa9b6760,0x0007a3f15a0ec05a}, {0x000736800fc5d305,0x000bb74572a151d8,0x00065a96cf22ff7d,0x00019519394cd42f}, {0x0008227699f90840,0x00068419e24fe2e2,0x0000000000000000,0x0000000000000000}}, {{0x00025578363927ed,0x000574db66d688d6,0x000d409ddc1459fb,0x0007f82b70d69f87}, {0x000cb67c0931340b,0x000a17e9ba495398,0x00095f5bb6fc86af,0x000372330a201b0b}, {0x0002bfb684331f96,0x000759b31f0fa4ba,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008a9686e50ea9a,0x000fa53caf16bb29,0x0001e6775d854b08,0x00037450aecb3742}, {0x000a7e3971ac67a8,0x000916720ee3a053,0x0007ef527af5a2ad,0x0008c78907d26a51}, {0x0000187ff88dddeb,0x000580501085ffc1,0x0000000000000000,0x0000000000000000}}, {{0x000bd54c631b5ef7,0x0000a533ff81bdf1,0x0000234fa962cf5c,0x000a7f99121d8411}, {0x0004d769fb90a1f3,0x0005f3f42e621b7c,0x0007e5f02655798a,0x000d995fc9fe9a95}, {0x000560ed712fc645,0x00059000f20fc194,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ca8aff309b100,0x0000c85dcacc4c44,0x000282732cee9318,0x000efc73a9f020ed}, {0x00070ac2ec46ccda,0x0004edd612a22d61,0x000fb7673b4cf6d2,0x0000510828deb00f}, {0x000a061d4c49e843,0x00016c8aea6c342b,0x0000000000000000,0x0000000000000000}}, {{0x000ffaa28b87e79b,0x0001bb9617a5663f,0x00097f1ba9e99062,0x0002ee20742a4b1f}, {0x0000500e34cdf43b,0x0002b6de4ad6c0ab,0x00002eba08ef6f81,0x0004e0bbfd3a6364}, {0x00094460899a3582,0x0008335d3e07b17d,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005a71e395d239e,0x00026a160db974ae,0x0004df55ba5b2671,0x00091fe0f2bfd214}, {0x00027e4215d39cf2,0x000849498b3dc0a6,0x0000c7dfec311ed8,0x00029fbb50995b22}, {0x0005f9ca4a3d83cc,0x00085332f62dd6c5,0x0000000000000001,0x0000000000000000}}, {{0x0003278db69ec48f,0x000c56caebf5d4e7,0x000e4ab979b38b01,0x00005e1e7e210f66}, {0x000e800e35bf7fe3,0x00041625bdbbd247,0x000140764eabbcaf,0x000ae49d3fb6b3c0}, {0x000bed09dc31a840,0x00044a6c67185e6e,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=78 [{1,2,3,..,}]*([2^312]*G) */ + {{{0x000976185cedb78e,0x00000d5ac29ab973,0x0005376ef5010492,0x000fcfdeb7cabe96}, {0x000e82ebeaa6eb29,0x000856863e849702,0x0002b7dd5820c1d9,0x00080b85b8b6adb3}, {0x000cc2bebcb2a1da,0x0001cb911240a24e,0x0000000000000001,0x0000000000000000}}, {{0x0009339d66471f42,0x00086865738f288e,0x000ec9ab31ac9389,0x0006dfc0b78b477c}, {0x000d22531d4c9b75,0x000957b1f72bea7b,0x000f90819668750a,0x000023544082b7ac}, {0x00010dd35fa97aa9,0x0000657c9376d4d3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d393a7e12c9a1,0x00087315af1e7695,0x0005dad48c909f6c,0x00065a7e168b010a}, {0x00026d86fdc5603c,0x0008f52d5373f51c,0x000a497697c8b7d8,0x0006670982debc64}, {0x0009f942aaf7a067,0x0000beb15cc57a80,0x0000000000000000,0x0000000000000000}}, {{0x000728397fd456a4,0x000c8ff5563ef971,0x0004e73a2dd305f3,0x000cc516a80ae4a1}, {0x000352258160b828,0x00008533e6e74db7,0x000028314ad68011,0x0007541598a03b32}, {0x000c3d815763ab10,0x000089f632644f56,0x0000000000000001,0x0000000000000000}}}, + {{{0x00096953520ee092,0x000306d200f67521,0x0008a20dfb41aa95,0x000ecbdc450070d5}, {0x00044a73c2aa2e56,0x000cf15e09936979,0x00039822bf1cc5f8,0x000ba98dee98b81e}, {0x00049763f39d2614,0x000dce88bf80d042,0x0000000000000001,0x0000000000000000}}, {{0x00090be494194f3d,0x00009eeb5f7526ea,0x00042892f629d76e,0x000de6b9665e7661}, {0x000e4db45bef0dd2,0x000f0c29ede66edd,0x000cdcbd947a3fe0,0x0009dc0bb66739bc}, {0x000aa185f9760092,0x000d98f355b62fee,0x0000000000000000,0x0000000000000000}}}, + {{{0x00095d178d8fc8db,0x00088ab909e6143a,0x00089b7600c18603,0x0000f4aa942112c1}, {0x0008b5a1967f7a08,0x0003543a0e5057c0,0x000cafbf9ac78fd1,0x00049408a20a1598}, {0x000b58bcdfa7974b,0x00036217ad4e198f,0x0000000000000000,0x0000000000000000}}, {{0x000138c5bd603cb6,0x00072af896026457,0x000ea9d78b2185f1,0x000482318652917b}, {0x0008b9b757159621,0x000f2c7ae3b7470a,0x000d10f532d77474,0x000d6b40b8bfc96f}, {0x0004da23277081db,0x0005192cd44f13a5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000210b018203491,0x00081f7f56d37ef1,0x0003499eb28c2bde,0x000d16d800ddf3bd}, {0x0001a8ad11d2638e,0x00081f6ac5a19953,0x00073cbdac06d819,0x00089e5df343701d}, {0x00080e56132b9d88,0x0008f82b847a3187,0x0000000000000001,0x0000000000000000}}, {{0x000ae2fb5a3b782f,0x000dfec66b9766a4,0x0003802b7f84c2ba,0x0002adc75633f423}, {0x0009ba300fd1c729,0x000a85bdc16e7491,0x000bea7ecdc049f9,0x0008cba7fd0e8182}, {0x000a5a9aa8bce3aa,0x00008a0977d90d48,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ee51072d71e54,0x000e9e2a68ca9bef,0x000a9707bfc11ef4,0x000ae91635e6d8f0}, {0x000dd87435cc0e00,0x0002d6a89b217b9e,0x000c5bada1452b8b,0x000d602de29b175c}, {0x0003f43b9bd73fb3,0x0000724373642133,0x0000000000000000,0x0000000000000000}}, {{0x0002c3dc04031002,0x000c73ba54808162,0x00084fe7d46fa018,0x000e61eb44ff91a6}, {0x000448f89778fb3a,0x000d0dc5c96379eb,0x000f26ee0588d9eb,0x000aafd623f750bb}, {0x000b6e0aafb4a855,0x000ab06c0e1eab53,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001292993c3f0c9,0x0009243ce8e0477f,0x00002cd6d125a6a7,0x000424b8f8d2f4dd}, {0x0000e036966f98b0,0x000b28d9609c6ed4,0x0006f54dde908ae8,0x0001261395876628}, {0x0001a89f477ea392,0x000b89a6253dab22,0x0000000000000001,0x0000000000000000}}, {{0x0000776cda9e2906,0x0004dd51a83a13fd,0x00024cb69c0833d7,0x000afa9f2d0d7515}, {0x000d5068104d274c,0x000b1536c256cfc3,0x00005c2c5a3bb4ea,0x000e695b252297e0}, {0x000674ad5032178b,0x0007afaaac5118a0,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b5f87444140a9,0x00070937761e89c1,0x000052402d8c768e,0x000e0d8fa7063fcc}, {0x000065032ca28437,0x0000560b81d70497,0x000a63bfcc5af72e,0x0007abb68cfddac1}, {0x0007b3b85e89f391,0x000e3880d7454a25,0x0000000000000001,0x0000000000000000}}, {{0x0001d4cbebc9cca5,0x00014fe965181800,0x00064d65a9766b10,0x000646ec511b3639}, {0x000cc26e7c4e0d56,0x00094ae11adfae8d,0x0001a6886e8d406a,0x000547bbf4ad6e9a}, {0x000e8901b3004a68,0x000c8d5981c48013,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=79 [{1,2,3,..,}]*([2^316]*G) */ + {{{0x0003223ffb7f0034,0x00056eeed01f7ec6,0x000a95759d3b10c6,0x0008fe9fc8ceacdd}, {0x00036b6ab8ec35f6,0x0008c0b21550e979,0x0008e1de4ccc3b92,0x0007fc6be17e92be}, {0x0001bdb6320828c7,0x0009d213352a78b8,0x0000000000000001,0x0000000000000000}}, {{0x0009b3c1ecfa9e13,0x000b3a0b5daa423d,0x0006bf95aa594567,0x000fbfb5a3d149d4}, {0x0003d4e9979588d0,0x0001e08ca45e636b,0x0005c358fa3b11bc,0x0003552e11b17364}, {0x000b67bc8931ab99,0x0002d3ce614c5f0d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ed714844f3544,0x000cc4bb9010843a,0x000996ac0026321b,0x0003453553c74ad5}, {0x00041741982c7cb6,0x000196d8fedc48a0,0x00020d244c9f0921,0x00070a8fce97fabc}, {0x000a6d44732828d2,0x00060bcab0c77562,0x0000000000000001,0x0000000000000000}}, {{0x00061da3943969d2,0x000d674b749d7b3a,0x0009df6dae1fb5b6,0x00005c30ec275083}, {0x000ae7da1a9284fd,0x000c82a28eb7bd6d,0x000a71d66cd19bae,0x0002d599b2c6a08c}, {0x000faa1546c312c5,0x0007f06795e3065b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fff9188aa7d8c,0x000deb80ad064a0a,0x0007114ab9689af5,0x000fad0b4dbde778}, {0x00055fd29cd3c099,0x000d379d42525d60,0x00016d04df50e85b,0x00053602e006dfc1}, {0x000e6c63f374d96b,0x0000f26509a7f32e,0x0000000000000000,0x0000000000000000}}, {{0x000822c176aa9790,0x000f58fc039cb1ee,0x0005872cad56c2fd,0x000e8ae0ea665324}, {0x0004daf2e64bf3b9,0x0008f96bb4b8314c,0x00090e063c57f41a,0x000d5149d3063df9}, {0x000ba61281d5f9b0,0x0004ba3d6cc9c608,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005d4a76da49005,0x000c3b224e91125c,0x00062ab184a74621,0x000b682a17406495}, {0x00053c3f7c8cdedf,0x0008e38d4416ae20,0x0009c28df044060d,0x000f86143e5739ed}, {0x00095f9f7f327b97,0x000872538531478b,0x0000000000000000,0x0000000000000000}}, {{0x000b98e468155010,0x0001fc05661b3943,0x0009ee23198c1bcc,0x000744fc64ff1647}, {0x000560f20d871115,0x0002c9feeacdf5ac,0x00070b263cba9c39,0x000badbac8fda72f}, {0x0001aad35365c71d,0x0002f99d51687d17,0x0000000000000000,0x0000000000000000}}}, + {{{0x000acd4ec9302acf,0x00046876812a6969,0x00062f921abd47ef,0x00030834c8ee3434}, {0x00087c08c033bb79,0x000e51d0a2369c3e,0x000c1fbd98cac8fe,0x0006a309b704c675}, {0x000a173a43fcbb3c,0x00009432c4949569,0x0000000000000000,0x0000000000000000}}, {{0x0005e781f2ef36de,0x000e3479bd3a702b,0x000d74e86eb68837,0x0003849622881aa5}, {0x000ba91b89a84ecb,0x000caeee87dd2964,0x0000f40b0230b757,0x000e7853cadc83a1}, {0x0005f5ad1465657a,0x000e75100e5033e4,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e44f3911651e4,0x00088f7f22b492d2,0x00072f850dbf1662,0x0003ab2a45a14853}, {0x000e1480b82ee674,0x000ca609c8235a84,0x00085d8422668b9b,0x000a5d6f0bf02f4e}, {0x000afb880792321d,0x000cb82c095f0261,0x0000000000000000,0x0000000000000000}}, {{0x000bc2f5725cea9c,0x000e1f43f99381e6,0x000e6089c844a832,0x00000aa951ad7011}, {0x000282a695207656,0x00007e689c114477,0x0000e537bb9a4c6a,0x0009df06eaf0cd7b}, {0x0007c474d7895232,0x000f0710d2b00b77,0x0000000000000001,0x0000000000000000}}}, + {{{0x00093c8e0aebae92,0x0001a4248ef98180,0x0005353d71384b97,0x000564228ab8dd10}, {0x000ee9e95615cf3f,0x000dbed91f163427,0x000ff8c7cd8d83e1,0x00002a117b26a05b}, {0x000d651309094b7c,0x0005fa8d73f3a728,0x0000000000000001,0x0000000000000000}}, {{0x00045cf4f3fc6c29,0x00069a5dd01b3bfb,0x000e3b24278a983b,0x000ba6e8dda15e64}, {0x0007ceabdafeb0be,0x00028dd1f4ce3cbe,0x00083c003c3a01ee,0x0004286b68f03154}, {0x0003661bd44cc13c,0x0006d7a5a2b18a65,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f4f2d2f859a83,0x000584cf466ff03e,0x00078dc82b847044,0x000110dcb52d320e}, {0x0007adfe140d78b5,0x000b45fd46e07b11,0x000943939af65810,0x000f26b6d5c5bda1}, {0x00091095a8309f53,0x0000d4aad23c7d80,0x0000000000000000,0x0000000000000000}}, {{0x000dd82bca9e7ca1,0x0001551ee78b6090,0x000453fc776839c5,0x0001d0262966b875}, {0x000729e2a29966bf,0x0008c49cfc825d3c,0x00009961345ab1d4,0x00007e6049f3ad60}, {0x000007da4f1b3985,0x000c382c8f36cb0b,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=80 [{1,2,3,..,}]*([2^320]*G) */ + {{{0x000a284c690646dd,0x0003eedcd5cc91eb,0x000ea471fd6292fa,0x00023a125841cc32}, {0x0002e35810a749fb,0x00061336484e18eb,0x000b6f65228a2bfd,0x000207542e7452ca}, {0x000526cd940c7469,0x000d2936b9b32962,0x0000000000000001,0x0000000000000000}}, {{0x000573e4f063ef2a,0x000418ca996c2a17,0x00033e1f9c1c3d42,0x000b3cbf970fbd47}, {0x000088c0b1561246,0x0006e93234f08535,0x0009d7f8ff901881,0x0000aa556f8574d9}, {0x000a5d989d3b1d29,0x000ed0ab78218edd,0x0000000000000000,0x0000000000000000}}}, + {{{0x000233d6557077d6,0x000f2b32cea9ff87,0x0006963e65db1454,0x000b05b7d5f2627e}, {0x0005a68cad15bd15,0x0009679cfef2c921,0x000cc1f982da4ecf,0x000673910763dd21}, {0x000110fdc3925aff,0x000a3cad0858b1ce,0x0000000000000000,0x0000000000000000}}, {{0x0000c51bfdb7b566,0x000e8b88f58f7516,0x000713a7cf39e39e,0x0004ac365af813ed}, {0x00040a788e43e8ac,0x00010b5e01e789c0,0x000ddf33d0cb49ec,0x000a3f2d9bd726fd}, {0x0006e3c30504e525,0x000e51a456acdf77,0x0000000000000000,0x0000000000000000}}}, + {{{0x000707d7da6499d4,0x000c004b6d85bc23,0x0004b483dd72372e,0x000b15c9838f63c9}, {0x000dd40b6584e869,0x0005bb5ad6291644,0x00069be693ec1c90,0x0007b5c6018dc109}, {0x000c9c113b81150c,0x00040bbd460de804,0x0000000000000001,0x0000000000000000}}, {{0x000d558a1b81757d,0x00046da356589b5a,0x000f093ea9cf88e0,0x000cd54eede9de0f}, {0x0001f19ec3f8839a,0x0004ec243ffcbf45,0x000d0d1f8b02c0e4,0x000a42d2cc07981f}, {0x000363b43f4701bc,0x0007f930f2e9e43f,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006b0772d9f5845,0x000f28a8c7c3d700,0x000c1d96b231ba3f,0x0000f432c17a4f5f}, {0x00014ca88f653da5,0x0001ac5da9fce5ef,0x000105dd10257bb3,0x000206b910de18d3}, {0x000d121d64f95008,0x000e83748b9a298e,0x0000000000000001,0x0000000000000000}}, {{0x000dc94560ad3e4a,0x000b34cda193affe,0x000f39dff5030add,0x000d72c1a3a58a0d}, {0x0001ad7c02e84586,0x0006dddddd7190f7,0x000431dd7f7815ab,0x0001b059af2893fd}, {0x0006d66ebdb90a30,0x000ac5b55b254562,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a7032755a2cc5,0x00087b60173b4c02,0x000853a0c8b700e1,0x000d3fcbebfa5d41}, {0x000106636a248a74,0x000d439df17f1529,0x0001a48433bf866c,0x000ed52b92a93d36}, {0x000de5dbf96508fc,0x00064c08fb48dbcd,0x0000000000000001,0x0000000000000000}}, {{0x000e6d70757d607d,0x00099aa287bad741,0x000aca83d8bc1d01,0x000a6deb3248272c}, {0x0006281490886dee,0x00003b3e7ed5830e,0x000b8f50b5515018,0x000ee61ae410329b}, {0x000dd209b1b1ec67,0x0009f79d8f057d2a,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009240ac4aeeb4f,0x0009de701cba0d15,0x0001e2030d5be49e,0x000f5b9fa8d80ea6}, {0x0009e389aa0a7891,0x000f08f46a281d5c,0x0003d8942c2a6a9b,0x000dcae5c6263013}, {0x0006ed6f226d80fb,0x000e7cd744527397,0x0000000000000000,0x0000000000000000}}, {{0x00064112eebe5a16,0x0005561ba10f054b,0x000076de3983c715,0x000338a0051c721c}, {0x00017ed93ec2b1b6,0x00040d08e30b18e6,0x00086d02546a805e,0x000b289546bf39d9}, {0x00029a40d87fe36c,0x00003828ca6d96cb,0x0000000000000000,0x0000000000000000}}}, + {{{0x000888aaaf08b61b,0x0004baeb89b8a3b8,0x00013c31ce0504b2,0x000084891577d88f}, {0x0001501541da01d3,0x000be18906c31edb,0x000cf8acb88a0c0f,0x000de0a54814b123}, {0x000d30b10ce17eb8,0x0003c65435ad1112,0x0000000000000001,0x0000000000000000}}, {{0x0003c3081d6e0b2e,0x000bd1198cbd6e7a,0x0009feff60218481,0x0009559a8a4e33b7}, {0x000ae242155d34dc,0x000458dbdb49b265,0x0003688660033750,0x000853753ede19c3}, {0x000b6969aac09e0c,0x000a5225b275670e,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004c030e13db910,0x000b8e4bb182d8fd,0x00024d5733c45ba7,0x000e09929bbae322}, {0x000c5e18395c5857,0x000beb34317a4b7e,0x00065979d2ffacfb,0x00000dac7ff47099}, {0x0002ac181634b33c,0x000b325a113dabd2,0x0000000000000000,0x0000000000000000}}, {{0x000f6d0b44a18451,0x000ebd4b60b5e31a,0x0007c6c236a60067,0x000b1be8ccf47b3d}, {0x000a21dbd1cc7199,0x0004932466e888eb,0x0001dee034c21f8b,0x000ff9da169619ff}, {0x0007e95c7e040c95,0x000b5a9dbe56efee,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=81 [{1,2,3,..,}]*([2^324]*G) */ + {{{0x0008f08161486b22,0x000be755ab4efe68,0x00048d9609c012b1,0x00098843db068e78}, {0x0002d958488ad0fb,0x0003f6d23cff5eda,0x000c41d3ec7372a8,0x00035d185ec0b176}, {0x0006314a5925e490,0x000a3de4ff957947,0x0000000000000000,0x0000000000000000}}, {{0x00029cc94c1b43aa,0x000d43d2ad417dd5,0x000360ab4fa2dfe7,0x000e9eb552cc454d}, {0x00035a4732c24fb2,0x0008d1e843cf82a2,0x000ab8e67bb7a406,0x000191877eafbca2}, {0x000574ab099566cd,0x0009f922f9872f62,0x0000000000000000,0x0000000000000000}}}, + {{{0x00085f8208bbe4fe,0x000ecc287db7bb2d,0x000e568667e702fb,0x000cbeb7a157f36d}, {0x000bf484f3352f4e,0x00058da014941bbf,0x000586c3d5fe38d5,0x000a8a8ef1b37b22}, {0x0005949627a9e7fe,0x0004740c422ebeba,0x0000000000000000,0x0000000000000000}}, {{0x000c2ec0fe63724c,0x000be0eb88269034,0x00016f607ed8c7ff,0x000b235b0a729f09}, {0x000b2fb783d219ca,0x000a1f91a0e85a3b,0x000f36eaf1659ef7,0x00023c3d4be9067e}, {0x0005e5bd92b43e99,0x0001e3e81391aa3b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cdab06c0f497a,0x000ba682d62fd58a,0x000624d8816a960e,0x0006c48669b75099}, {0x0001fb169d6d2670,0x0009d5b924784941,0x000361b9811c3888,0x00005ccc21278392}, {0x000173173a0f5de5,0x000862da0030f596,0x0000000000000000,0x0000000000000000}}, {{0x000580503b5bd1a6,0x000460a53f77d734,0x0009ac0fc516703a,0x000cc1b1f0c1292d}, {0x000599d98d3204b9,0x000365fabf012bdb,0x0001f82c240390bf,0x0007f3c05cb807a9}, {0x0001aacb4486b03f,0x0002d4bf3cd7e64a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cf4fb66902a59,0x0006522d970cf058,0x0008db985646108b,0x0005bd091c524ec7}, {0x0001c8ded01bac37,0x000a7571d5eaf41a,0x0003ae41513bf75c,0x0000831a58ce8343}, {0x000b5c1d0b1cbad6,0x000a127e3558b4d4,0x0000000000000001,0x0000000000000000}}, {{0x000c5bcaa2423577,0x000e95cd90416c5f,0x000f9cd3e851fd11,0x00043cec77429d71}, {0x00033818263e74b1,0x000b0bed2ab694e3,0x0009d3b078fef207,0x000322c62d90900d}, {0x00013057fb2dcc39,0x000b0aee2cd8c7f7,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ca837cf1af373,0x0003ae0bc7638546,0x0005fbd88b9c057e,0x0000f14623993437}, {0x000d8418b02866d1,0x000938602b2a7398,0x000d172bab8e8fb6,0x00001960cc17eb57}, {0x0000f437b4d86f8d,0x0000c3266073d8a3,0x0000000000000001,0x0000000000000000}}, {{0x000b4a64de3a3170,0x000d07d300586858,0x000590b48d2c8237,0x00064608c48f8521}, {0x00055a4fad372745,0x000ad1664c3cb9d0,0x0000e5148678bfbc,0x000ce1f67995bdb9}, {0x0000ce6b82ba0137,0x000865e65d5e9060,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a3697b62e274a,0x0004f036666b6cc6,0x0004615de0a77111,0x000d1a544656bc00}, {0x0004cfe1b0ffd27e,0x0007b011fe7a367a,0x000028f9395287ba,0x0000e474d2cd1539}, {0x000df81c967ab663,0x000809d416f7d850,0x0000000000000000,0x0000000000000000}}, {{0x0004ff0171522411,0x000cb614e9eb99cd,0x000efe5013168ce9,0x00000068878690dc}, {0x0003ea58b25b4f05,0x000697bfbefe708a,0x00061484cbc18871,0x000fd61b572d109e}, {0x000507a67ea6e538,0x000c108cf0642bcd,0x0000000000000000,0x0000000000000000}}}, + {{{0x00073712d28f1037,0x000dcbb85bee07b2,0x0002d427b383b0b0,0x000886a4c921569c}, {0x000a22bb54a08b63,0x00016efd18019f62,0x000be30e896a901a,0x000b1c79b63790d0}, {0x0007550d4ad3f339,0x000c014ebb2a7324,0x0000000000000000,0x0000000000000000}}, {{0x0000eb80b7360646,0x0004292a8064819e,0x0001aa8d66966eba,0x000cb5433c6786ce}, {0x000c176010116f6a,0x00042b7f40b26c85,0x000bb51bb431c00e,0x00079fd699bb4a71}, {0x00083711f2c2acd8,0x0008a64b1e3905a7,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004f281744c4f31,0x000fb974f0427525,0x00022ee390de534c,0x000caed9f368e25e}, {0x000470d3f5a1ebc4,0x0006bb7427d70104,0x000830891f024042,0x0006993cd5f37f0d}, {0x000a9d89f4ebe578,0x000c7b2549a02c1b,0x0000000000000000,0x0000000000000000}}, {{0x0005527d2ef3c160,0x000aa733afd2d857,0x000200435a36240e,0x000dbed50df72a8e}, {0x00064e9f3dcc7104,0x00084041401f5c34,0x000b281791b398c9,0x000ad77cd49e1581}, {0x00029530ca203aa2,0x00024a7004073823,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=82 [{1,2,3,..,}]*([2^328]*G) */ + {{{0x0004b896de83f7b2,0x000dd1b2e000727a,0x000d43d965547a68,0x000c1f1e1ce79a50}, {0x000e5ec87252c6ab,0x00060d6a5ae7160f,0x000985fdcf45caab,0x00091b3180d9d235}, {0x000646ab8f898256,0x0009f0446d6798dc,0x0000000000000000,0x0000000000000000}}, {{0x000ec719b8387586,0x0001de5f9db6636e,0x00038f4a187cc943,0x000ac366ef383b03}, {0x000022fa366743db,0x000760fac1cc0b0d,0x000265067948b1b5,0x000693934495e8d4}, {0x000c64b8f4f88921,0x0005281cd8ec2ed3,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008479d81fdc38a,0x00096a893e0d1c8a,0x000972cecee045ea,0x0000ed0b37445b26}, {0x000bf1c0a16a9b25,0x000509c76808e477,0x00070c4c826b6837,0x0008008a3f9fb748}, {0x00088d0f74d58040,0x00063d18d474fc4b,0x0000000000000000,0x0000000000000000}}, {{0x000a143fb2178ecd,0x000ee2726dcabd2f,0x000e017d3cb36d39,0x000d77e2d8d9e011}, {0x00069332c865043b,0x000231a13fc89650,0x000e078f7a775c43,0x0002e93c91cf1e3d}, {0x000d48604e0f7c89,0x00031d2709749250,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006fca2f24da625,0x000adeacc535625c,0x00020bfcd99308f2,0x000732872a2697fb}, {0x0007578b9abdd39d,0x000d7e3c3e30d29a,0x000dc63c314955de,0x0002de0cf2a14e6d}, {0x0002e4f4d6b0bbff,0x0008423dc75d4cf8,0x0000000000000001,0x0000000000000000}}, {{0x000dc6563086abd4,0x0007f2e300951d8c,0x000a989054197751,0x000a88edbb68daee}, {0x000ee17db6bcc0fa,0x000d996d71fcc36f,0x00038a1dafea4a84,0x000fc8d72ef68c32}, {0x000c6b07cf974baf,0x000b2a140ef1e1e5,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006034713a3e42b,0x00008cfb50e4479e,0x000f617634a25363,0x000ba17f9549272f}, {0x000163e264556302,0x000db056ef0f6ed9,0x0009449c67d2e92d,0x00027bf608bef04b}, {0x000a41494e0fd2d6,0x000ecafaa0f9ad5b,0x0000000000000001,0x0000000000000000}}, {{0x0000394a908a0374,0x0002739ed3e6c1ac,0x0002bf950e49017e,0x0006ca69441c9b0d}, {0x0003c717b7978985,0x0006f1bf123315b5,0x000d5ffc5bce1316,0x0000f7b0dacbdc85}, {0x0005306a73236570,0x0000fc22ce0f19f8,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a6e6af09b8eae,0x000343b43c513568,0x0003425270500040,0x000fb4508580e8a3}, {0x000b307fa3d1f99e,0x000113638a6f65cd,0x000be36db7f5ca63,0x000ede447eb7ec8b}, {0x00022e6ed48cec2c,0x0007bb1afd7c927f,0x0000000000000000,0x0000000000000000}}, {{0x000c11f9a334fdc7,0x00026ae8011e9b06,0x000ba4fc7ee152d9,0x0005ebe2d92b45f4}, {0x000643466d3d6908,0x000a09e637a743ca,0x000aba719664e4ce,0x0003162cc6d5e41c}, {0x00060cdf202e7dd3,0x000c307d09d0c5c7,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b621fceac0c99,0x000cd9f0c6398393,0x000246af19db94f8,0x000def03f4511189}, {0x0007e278282d9eea,0x0005d51872d67451,0x00069251c97cb275,0x000152306520f8d9}, {0x000f0746e9696ce9,0x0009ec26638c1b12,0x0000000000000000,0x0000000000000000}}, {{0x0006fbb28d6db318,0x000282f1e3fd8169,0x0001638aa745ba97,0x000741cbd6f6afe6}, {0x000674be06f9a37c,0x000f0e4d5ef37aa1,0x000c66c847151102,0x00086ff305cd0c0a}, {0x000dec0bec87dfaa,0x0006e29a33525521,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009e94294764d17,0x0002085b396e5ed1,0x000a114f1c4a72c2,0x0007528c8545f538}, {0x000963b0d0aaa085,0x0000ee6c82fe930c,0x0009cc321991f876,0x000bfd79b22e04e6}, {0x000e404e5103af68,0x0009a8126bf818d5,0x0000000000000000,0x0000000000000000}}, {{0x0006f18c56b9245c,0x000be8cf2d749759,0x000d0534792607af,0x000737082c9ac67b}, {0x000b81d246c242f3,0x0004a1675a873285,0x000b8be65c0f0c83,0x00031f4367aaf8a7}, {0x000eeb7fdd2c4760,0x000b71b7bc940b35,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e474b29bda866,0x000e2b3a2640ed4a,0x00021f91da93684d,0x0005df67424bab62}, {0x000b550d60209995,0x00096c99d55193b4,0x0003c748e9f27481,0x000631e6b3fe7e7f}, {0x000f47f4e257248f,0x000f8f56db9ba373,0x0000000000000000,0x0000000000000000}}, {{0x000bc357ebc4dd12,0x0003a33556892c48,0x000b72124cffa435,0x000e35056ea40bee}, {0x000a1b37aa3c71db,0x000ddc96c72e951c,0x000291c71de6fcaa,0x000ff88244eb58ae}, {0x00089a7bf96fd42a,0x000eb41c5d8ae97e,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=83 [{1,2,3,..,}]*([2^332]*G) */ + {{{0x0008ac7511fc1235,0x0005af51e9a589c7,0x000c09d63e56a5f8,0x00055b518ce24a89}, {0x000a75441652a9b6,0x0004ffab489b445d,0x00071289523b0e9f,0x000290aaf7cb23e7}, {0x000c9bc7899234af,0x0001dda65dc198b5,0x0000000000000000,0x0000000000000000}}, {{0x000eeaccabd5a6f7,0x000d5900e72c44fa,0x00047a63782a2bbb,0x000393bbf531aecb}, {0x00009c7dda45067c,0x000719fa6f31630b,0x000f3a0c95e46b2e,0x0004deaf5d70f849}, {0x0007dd5d46829965,0x00096c286bc1f082,0x0000000000000001,0x0000000000000000}}}, + {{{0x00012d5838ca6af1,0x000964e9241a8a04,0x00024077ab2ac6aa,0x00089da3e1536c1d}, {0x00001df56af4aad1,0x0006ef9e57fbfb6e,0x000b17f8ca8e6244,0x0009cbcb351a7c9e}, {0x00085fb54f3eda4f,0x000c296970873909,0x0000000000000000,0x0000000000000000}}, {{0x00056d8d32e5fdd1,0x0006814d7980be46,0x00065dbc6a68d7ed,0x000cebebe9b6528d}, {0x000269dfcc27d433,0x00073aec8225c88d,0x000d90643f7caaf2,0x00041c78327e8662}, {0x000763fdae4a09eb,0x000b0ead9bd2f604,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008f42a8c29bd6f,0x0001879cf21db610,0x000555cfe2bddcfd,0x0004d452af269c11}, {0x000fcc4011856e7b,0x000e6e45593cb7c3,0x000b215415957c0f,0x000d3b983b2c8996}, {0x00012f953be5cf31,0x000f7078abc3a003,0x0000000000000001,0x0000000000000000}}, {{0x0002c0d6b39b80ab,0x0007b2847e724ed5,0x000cfdfc83942bcb,0x000c1c0a2ddac314}, {0x0001da690e67e2aa,0x000310507c60736a,0x0008b8515f2f407e,0x000203447dd4a30b}, {0x000208fe5f3ddc7c,0x000470482e113587,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d7682eb5538d3,0x00058bd8734ac8b7,0x00075fcdec6d3223,0x000ffc3556d9d86e}, {0x0003a6c363b61e72,0x000d03c2ead1066f,0x00074fd7095dbd73,0x0002b42f9972cd16}, {0x00070acc2acc3e68,0x0006fd80c7114993,0x0000000000000001,0x0000000000000000}}, {{0x00049c09589c235f,0x000294e10709485a,0x000e55bcaedd0d2a,0x00084da3a073e38c}, {0x0004725346561d28,0x000ed8195e95d347,0x00001ec990b2c19b,0x000817664aecefe7}, {0x0005f12464c59ce8,0x000f85a23cc1c6cb,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fb48cd5b9dd85,0x000ea5640b16ec8e,0x0004991733d00d1c,0x000e2230142b823b}, {0x000d1646ff2bfccb,0x000e87a4efbbe898,0x0007933417bfbbcd,0x0002ac0c744278e4}, {0x00079c8483d8b4b3,0x000fafae62ecea8b,0x0000000000000001,0x0000000000000000}}, {{0x00063d47c065003b,0x0004185cb3cef55d,0x000bfcfe8d3872f3,0x0009112c490c5e61}, {0x0003b1e7d4274313,0x000517366c9c6308,0x000bc9bb53389bc7,0x00025afa81750fe0}, {0x000afda6e1b71dc2,0x000c6a9aba51c85b,0x0000000000000000,0x0000000000000000}}}, + {{{0x00000e070af57b1c,0x000441246548fb7a,0x000c563ead66464d,0x0007508f0851b47e}, {0x000f31999ecfeae6,0x000f85797a3840b6,0x000c74080d60c378,0x000f3eaf1e242bf3}, {0x00003ca35d886cbe,0x00022754c9a357ba,0x0000000000000000,0x0000000000000000}}, {{0x000982d0aaae9f75,0x000176d1b4b6ca3d,0x0007980f7d421826,0x000979133a61fcc4}, {0x000cb63f41cac3bc,0x00079bb4b9516419,0x00033cd18a279569,0x00075e18895b57d5}, {0x00063599127b0d23,0x00063dbbded01670,0x0000000000000000,0x0000000000000000}}}, + {{{0x000342ad817f361c,0x000cb1bd9eb81b06,0x000c7b97a0843c43,0x00083f804f029e13}, {0x000b3486644af0ff,0x0002a64dc632346d,0x0002a39cc0dcbed6,0x00056457b2ff9c5a}, {0x0000fe8536001cce,0x000def7d14af048a,0x0000000000000000,0x0000000000000000}}, {{0x0006c4115861eef1,0x0006a14bad6b1ac1,0x0005dee3e9d201f9,0x0002b396cf147ed1}, {0x000f4643f8a21b3b,0x0004c9915584149b,0x000a893cfd7ba449,0x00027a8a4eb7aef9}, {0x000cc4fa992b1d31,0x000eec6c99a8fa7f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a8d985f7ab9a0,0x000b7d39a70c2f72,0x000f6f8acabea7d5,0x00095d0273f642dc}, {0x0007d8a54bc56deb,0x000a63f1883f3cc3,0x0004b831ef1bba05,0x0008e112f14c8c07}, {0x00089737917f937a,0x0004874d335ca229,0x0000000000000000,0x0000000000000000}}, {{0x0008374f770af11f,0x000cad8ee96d7e99,0x000bff9e11a7d432,0x00056384e6665366}, {0x0004a9b692423f6d,0x00075f044efc7e34,0x000ee60ee1b3dddf,0x00039cd00df7a827}, {0x000529eb5b2612c9,0x000cd7c4ffa6a13d,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=84 [{1,2,3,..,}]*([2^336]*G) */ + {{{0x000c16671a6774f1,0x000af03753ce5839,0x00054c5f8c07356f,0x0001afc71165a356}, {0x000f9d6adf86cf5c,0x000a6b4966903b89,0x0009f4ebff86c3fb,0x0004a87b0151b151}, {0x000efd27bbe4f95b,0x000b040513d26385,0x0000000000000000,0x0000000000000000}}, {{0x000622a63fa5d90d,0x0008d92aca99c7d4,0x0001d6acf3aa6efd,0x0001b7387e55d6dd}, {0x00010db119c2295a,0x00011a67dad9703d,0x000eedb427c0f52d,0x0001e055192fe412}, {0x0004a5758174c7a3,0x00055cfd4b1dde40,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000d119f7fe9853,0x000fe49990254b37,0x0008a86cb40764d3,0x000820af39be0e2c}, {0x00027458321b04b9,0x000c2ba583294752,0x000ae89a07a5c7f2,0x0008fa6d520652e9}, {0x0005604c9bdc0eee,0x0000c06f2e484243,0x0000000000000000,0x0000000000000000}}, {{0x00014a30a2bfa81c,0x000cbd6640003017,0x000ab87a938a3f37,0x000e1c91f3132874}, {0x000e57e9d7ac6ecb,0x000e33fb881734fa,0x000073b600765b07,0x0009428cbfb5edfc}, {0x00029028585e9a20,0x0001e077ef7692bd,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cf34a0d6f6ffe,0x000370c22b280291,0x000e87a26b1fd975,0x0008088a662b3666}, {0x000eea746601046d,0x0008edbdfb0988f2,0x000f2131f7fc1ebd,0x0009266b6d41f4b2}, {0x0003c1c020089694,0x000be27c849de8c8,0x0000000000000000,0x0000000000000000}}, {{0x000bcda37f3a594e,0x000726480ec74a90,0x00026216e2ddde9d,0x00064b02bef16495}, {0x000aafba3c749a5c,0x000a872930c3f630,0x000654a8695df3be,0x000cb5372491b21d}, {0x00017f3b3a2f3f6f,0x00094613fe01cfe9,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008937b47b39090,0x000415bb7112fdec,0x00066e9e19d3ed5a,0x0006597801eab0fa}, {0x0005e740c409bbbe,0x000050b19bba9267,0x000df2c3e8b56daa,0x00012fbcf099e6ee}, {0x000195262a55e069,0x000ee2f2c7d1e980,0x0000000000000001,0x0000000000000000}}, {{0x000c1384c013e53c,0x00074951ffea5bee,0x000d0ad477deaca6,0x0004ee3245756473}, {0x00030808642161fd,0x00050c8b97a30694,0x000340f405f653b8,0x000d5a543cae9de4}, {0x00031ca24347d550,0x00092a75f4312ea3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c8162c746ef6f,0x000f6715dbf9ea58,0x0005523d8217dd87,0x0000b2c52bc5b0b4}, {0x0005db8903ecd878,0x0004296f75f92e78,0x0003c6e6397e4045,0x000e84bad1cccce3}, {0x000b82162d3c5f54,0x00009333f935ae95,0x0000000000000001,0x0000000000000000}}, {{0x0004ff1c33e26a2e,0x000785b4ec10e1f5,0x000a1634274c2886,0x000b5d5ee5822d49}, {0x0002fbe9122e0bfa,0x00003c2cc2955a06,0x000e08e579ad9b7f,0x0001dd6ee255f2e5}, {0x0004f08f71b65e70,0x000c9dcd7d23cb93,0x0000000000000000,0x0000000000000000}}}, + {{{0x000927819d85c389,0x00088dd986cf5001,0x000eb6ebdddab174,0x000a1e388628281f}, {0x000014511bc0392f,0x000b79c2a5e1691b,0x000d866b842f8440,0x0000343c71a48805}, {0x0002ac5c5d5d795d,0x0004aaedd8558804,0x0000000000000000,0x0000000000000000}}, {{0x000896067875f110,0x00080b0d43dab8fa,0x0009a3104ecd6f15,0x00017c31840b3b59}, {0x0007841201091767,0x0008de871b2243eb,0x0003f7be2323a388,0x000f764799c353ac}, {0x0009d244edaf476f,0x000513c595b87c99,0x0000000000000001,0x0000000000000000}}}, + {{{0x000800832e6fdb7c,0x000df2ceb7712003,0x000625cbf7ec3398,0x0007b9eb4c74b442}, {0x00090424f2515df6,0x000abc10516b9778,0x0005df82462b4902,0x000a6d60d9807c8f}, {0x000606aee1bb838c,0x00030e1e7a2ff1ff,0x0000000000000000,0x0000000000000000}}, {{0x0008fce9b8ce853f,0x000b7049a4c20923,0x000ae2b39f773f7b,0x0002f55bcfbf4b1e}, {0x000b07309ae9653e,0x000cf869d6026775,0x00099fe1b0e83daf,0x000202f8a21d72ed}, {0x00037619de81bf7a,0x000b7b2bf238b7d7,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008ca9dd54298a1,0x0000e1308270c47f,0x0002be3ff9743378,0x000471b0b186cdf8}, {0x000b1747ce696eb6,0x00015fe31005f60a,0x000ac1b5a457da88,0x000f4901af0f6bb9}, {0x0002f972c925bd14,0x000186acd8b58a65,0x0000000000000001,0x0000000000000000}}, {{0x0000f355372184c6,0x0005e1f7ba0c693e,0x0005b11db3d6dbda,0x00051b89e46fae1c}, {0x000c97c0b46b0f1f,0x000cc037caa48d5e,0x0000355bdcc75991,0x000f28784dc0e5f4}, {0x000837eadd1a3fa4,0x0009eeb5a1926d0b,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=85 [{1,2,3,..,}]*([2^340]*G) */ + {{{0x000847fc397e26dd,0x000de02cc0ff17de,0x00063e6fe388ee8b,0x0001e73a774123d0}, {0x000daf8cb9f5597b,0x000b938535ee20c8,0x0000d7da8b1bfac8,0x0008e2a819363df1}, {0x00079861ae7d4273,0x00003eaf0a677999,0x0000000000000000,0x0000000000000000}}, {{0x000611141de00c8a,0x0001d2aefc5b58bb,0x00033633ce29b3d9,0x0004bfef0d5e3306}, {0x000d78956c10a254,0x000fa84101beaa2d,0x000f9588ba22402c,0x000e0df8f46296a5}, {0x000c7018734ace12,0x000ca8e0e00d25c6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c26d9a28cda66,0x000ac34788e2808c,0x000a2e3c895ddb52,0x00092cc3305bc55d}, {0x00086ee8076376e7,0x000da2d9cb5f9d99,0x000f0d8aea185a30,0x00068ef462b956f8}, {0x0000f61c2096bebd,0x00044e7be11b5930,0x0000000000000000,0x0000000000000000}}, {{0x000ea58bb15fdd13,0x000d5b2585fb779d,0x000d75c3d978271c,0x000e827a5ac1a4b5}, {0x0006c6fe4d4804ee,0x000f66c09f0147df,0x000b3203f6a4c217,0x00081eeb950292c3}, {0x000da3f441776841,0x00071712f688beeb,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004586de8027c8d,0x0003b7dc25b073ea,0x00049b36fccf2477,0x000032458466e794}, {0x0006f36f854043cc,0x00051e24c902d71d,0x000ec681a81ea4c2,0x00060e710d119e39}, {0x000dfa8e50e27e69,0x000bc96885ae0f44,0x0000000000000001,0x0000000000000000}}, {{0x00072cc7ee3e54e0,0x000e54b8224b0f78,0x000e5d4bd3db5696,0x000d27cc64ead37d}, {0x0009b5b2f36d2cba,0x00021210e2a45e52,0x0002c8d788fbf745,0x000440c5440be1bd}, {0x000157b392b99018,0x00045deeecc510bc,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001f34441941c1e,0x000786af242ed224,0x00082ffb7bd73f71,0x00040040ee8f684b}, {0x0000b0e0a77660b9,0x00055090773cb918,0x0003b4341ff934d0,0x000efe154397d7e6}, {0x000566086597b1f2,0x00038e115dad8d73,0x0000000000000001,0x0000000000000000}}, {{0x000320279e97eed7,0x00092b44ad3c59a0,0x0009546c02d95d0b,0x000317d617644016}, {0x000b3b1278de80cf,0x000150eec20cc035,0x0004047a454911ca,0x000eb15350f140f3}, {0x000297dd664a854c,0x000c1545fd389a24,0x0000000000000000,0x0000000000000000}}}, + {{{0x00054c6d42f4ddeb,0x0001a5d46442b31b,0x0008eb97dd3c9497,0x000f35259e3e1ff6}, {0x00049058db0b2e2d,0x0006968077e0b694,0x000456e4ea6ec9f4,0x00098457796aba76}, {0x0005412cc7718336,0x000c5eb4e4306f25,0x0000000000000000,0x0000000000000000}}, {{0x000f4a91bf2060dc,0x000e9a57dadc33ce,0x00051f56adeb934d,0x000b29d22e8fe341}, {0x0000f85723b5e49a,0x000ee66b41fabf52,0x0005253bffe67611,0x000c50202f550a60}, {0x0006d250b9e49468,0x0001a2956ea13fef,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000dc097ea2b524,0x000c5eb5323240e3,0x000082d33c53dd49,0x000c5d6917c692b6}, {0x000337e9d695a12b,0x00078372d602c7fd,0x000ef2985e92117b,0x0008ceacebcbefa0}, {0x00068cc3e9b4e8e1,0x000db3e3e50ee13d,0x0000000000000000,0x0000000000000000}}, {{0x000980bec0d2f5e3,0x000eaa9b062f585f,0x00083ee3b5103eda,0x000605534f1f8028}, {0x000add292d29ee4a,0x000f9ba28df95f8d,0x000d134fb5785f57,0x000f0fe162fe54b8}, {0x00047f0902bd8287,0x000de3769ce1a122,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006e3d538c32c91,0x000eb774341e7141,0x0009e6b225ba2b4e,0x000824dcff742236}, {0x0004d5e3b9c67d3c,0x0006e4276dd54722,0x0001d2dcc105d46c,0x000392da4b3a8a00}, {0x000e2f3953b25248,0x0002fecbb5174b67,0x0000000000000000,0x0000000000000000}}, {{0x00008d720508826b,0x000b9b4e2e807123,0x0001bf6b1169562d,0x0006d2acb14e6841}, {0x0008cbfd3257245f,0x000189ac1c8cdf45,0x000ee493f894fd3e,0x000fa59cbf0ab5d6}, {0x000476d8e672a0c8,0x000ed9fbb78753d8,0x0000000000000000,0x0000000000000000}}}, + {{{0x00039334c1cd9788,0x0008ab0560e3e74e,0x000fa2ff6e2c62b5,0x000acd7d25b0cfee}, {0x000c456f469aee3d,0x000a862fad6476d0,0x000688f0d8d2340a,0x000b648a9494468a}, {0x000f4ed209d4d2fe,0x0008a93e7c5890e9,0x0000000000000001,0x0000000000000000}}, {{0x000cdd07e3f60721,0x0002466078437612,0x000ea1835868d6d1,0x0005ba6a85400753}, {0x000f7f252808d5c3,0x0007b45d6857ba4d,0x000d683048ddde70,0x000c759393e38c60}, {0x0000c630e919b183,0x0007209017172576,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=86 [{1,2,3,..,}]*([2^344]*G) */ + {{{0x00060ead50b81885,0x000bcef73cb6f0c1,0x00053fb7eb3e2cd2,0x00062b319bb7bc05}, {0x000a38a471706b6b,0x00046c6b42daf298,0x00005e59d404cf98,0x00048fac2e73085e}, {0x000ff0af6c53893b,0x000de9e3d8eea7a8,0x0000000000000001,0x0000000000000000}}, {{0x00034470acd5b055,0x0000c4c1af94ede9,0x0004fba6b3889b3f,0x00023ee49af80496}, {0x000f0d89fd53a3e4,0x00053cc302793fad,0x000b36dcd463b613,0x0003782e102e51fb}, {0x000c63732d6d1c6c,0x00059dc97f604bbb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000db31484a7e177,0x0001740a1bc3a05f,0x000c265e95ebda07,0x000546d643b1d3c4}, {0x000c2611b9709edc,0x00015784fc807b04,0x000e5bd473ceec4e,0x0003c97fb33e58af}, {0x000d6d5327b94dc5,0x00062a914fc6dc39,0x0000000000000000,0x0000000000000000}}, {{0x000cbcf73d880ddb,0x000029df80627a67,0x00091ccf95a67d3e,0x000ec7aefd91b52d}, {0x0003aa855273ca53,0x0007213a95113157,0x000b98a49db550c0,0x000b470643affa5f}, {0x000f0628a0fa67f5,0x000d2cf906186e6b,0x0000000000000000,0x0000000000000000}}}, + {{{0x00039cff07a9f5bc,0x000b27814ba6cdbc,0x0008da0e67469efd,0x0004ccf0a198fcd4}, {0x000cbf71a6e5b71a,0x000500eabe51b9c8,0x0007908463c5cf80,0x0004962539aa0260}, {0x0001de61db956e33,0x0004f9e2c1ac338f,0x0000000000000000,0x0000000000000000}}, {{0x0005f37dc080da53,0x000c1c2a74369386,0x000025722593f4e4,0x000a4e09b626a8d5}, {0x0004b1e7f8c96db6,0x0002c5a75c187079,0x000cb91e644a3045,0x00024e7eb18af641}, {0x000fb48086d9cefa,0x000b4dd6532fa3f7,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001be067e3e2f37,0x0007737f152d2c7f,0x000242f8dec8659f,0x000c7d958df47d63}, {0x0001b91c63b0acba,0x000c2c6ad3f62088,0x00099adda54c0028,0x000a3012f6937019}, {0x00014f4c499516f6,0x000da068d44cb73c,0x0000000000000001,0x0000000000000000}}, {{0x000209ec58d1b414,0x0008e876dcc7401d,0x0009323106751dc5,0x000f75f24e14fe98}, {0x000ac88f5086e5a4,0x000294dbdb4ccd6a,0x000be99edf86543f,0x0003767f48ab30e3}, {0x0007667c622dcd0b,0x000d7fd6615681d8,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008c453ac10be58,0x0006d75a48dfcf2c,0x000c4944bc5042f3,0x000e7ad5c9cee1eb}, {0x000996c45d109bc9,0x000689f02d424fbf,0x00023528e926c326,0x000e84ac793d58e5}, {0x0008eeaddb5a4ed0,0x0005d31f9ea2560c,0x0000000000000000,0x0000000000000000}}, {{0x0007ba171a6ebc35,0x000d39e242ba28da,0x0000694f0cc97464,0x000d7fb496b0d2fb}, {0x000d7e1b5b66b3d8,0x00001db81788dc1a,0x0003854dd5fe4e9e,0x000f9965063e6021}, {0x0003751c74ab4631,0x00006945420e7941,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005b110bb6dcc9c,0x000e9d1e6c13e60d,0x00058585159a0842,0x000b46fe443356f4}, {0x000853b25c086265,0x000ebbff20877291,0x000136ec71c4d1d0,0x00003ebeca5e79c2}, {0x000a0af3b3a96ed2,0x000f93012e330a32,0x0000000000000001,0x0000000000000000}}, {{0x00017ed67dacd4b6,0x000ceade583a567d,0x000316840b4e5703,0x000c414303d396ce}, {0x000ed6970ea480cf,0x00063761b9b1974c,0x000788f3de4383da,0x000ad07d6726e400}, {0x0003056bda545993,0x000385d3fe822ea3,0x0000000000000000,0x0000000000000000}}}, + {{{0x000285c58225166f,0x00072d2451ec99f6,0x0005efbddf5101b0,0x000dbc066e055890}, {0x0002c29985ac7cd6,0x000f1839b6caca94,0x00093cafd8d9c1ce,0x000b177ba7911d6a}, {0x00098fc762e30d5d,0x00067686b89a78b5,0x0000000000000001,0x0000000000000000}}, {{0x000dff4557a32b93,0x00037e16c6af191e,0x0007ad7362550f1a,0x000983cb772b5537}, {0x000b0746f50f2068,0x000dbb42f7ee6b8c,0x000f0cdda882070d,0x000a732384a13e83}, {0x00055b3be67dc4f2,0x0003cf20d84f4cbc,0x0000000000000001,0x0000000000000000}}}, + {{{0x00007348004e40c0,0x000448f78fb0602f,0x000c2ac8aebb2604,0x00064b78277ca03f}, {0x000eb2c6f473d278,0x000cb793a9eb1664,0x000e2b358eee9a37,0x000194f18cbc9c2c}, {0x000f6078bc87a3dc,0x0006220e93cd112d,0x0000000000000001,0x0000000000000000}}, {{0x000d1ed5d96d6d2f,0x000b72be10752f3f,0x000d1e476660c38f,0x000b1d6d9b093c35}, {0x00026d898dff773a,0x0004b445df00e4cf,0x000d1ce422c1136c,0x000db6e821b59ee0}, {0x000de6252e82511e,0x0002f481c804e41a,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=87 [{1,2,3,..,}]*([2^348]*G) */ + {{{0x000d7989af2b44ed,0x0006f91b1a9086f8,0x0002b4d5672b30f1,0x00072009919c3dae}, {0x000003b6ec0a964f,0x00012b7f4f64ce56,0x00076bfe0f0d4fbc,0x00043eb40f821444}, {0x000cbb4480332a8a,0x000f3ff375566080,0x0000000000000001,0x0000000000000000}}, {{0x00018caf35e5d712,0x0009aba53d6591e5,0x0004f1b1b50e170d,0x000f9eca3e56ed3e}, {0x000288dfe4cc67c4,0x00059c7726fa0dd0,0x000a0660a01f234a,0x000a704007db6c8f}, {0x00070b32e8366767,0x00096994810fb845,0x0000000000000000,0x0000000000000000}}}, + {{{0x00092a1897b4c0b5,0x0009027fe35612df,0x000a5105c7f9f97d,0x00021853ba021326}, {0x0005dd2cadb219c5,0x0003ab9d259b3ed4,0x000857fddadc1ebb,0x0004addab0607b4a}, {0x000ff916fbbc92a3,0x000721ee7e6c527d,0x0000000000000001,0x0000000000000000}}, {{0x000ba1dabc6f5958,0x0000087b0e564aa3,0x000b9c963dd27f6c,0x00028eca3c030970}, {0x000c23cd7a457768,0x00017b833d0834d3,0x000be25f44c50d54,0x000a153d4a6bf0d8}, {0x000e9c71da49590e,0x000d43f3a30dc247,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009bd585a57c01e,0x000ee844d7078c7b,0x0006c16cb258be3e,0x000a3282f9caf55b}, {0x000e08d004fc2ebd,0x0009db3ca2d054d0,0x000ff89010ddde2b,0x0006615b9b156d6c}, {0x00000ee87cbb5e96,0x0000965826673f04,0x0000000000000000,0x0000000000000000}}, {{0x0005c973c58e4e2f,0x000bfed17990af45,0x000982806a235d03,0x0003a7e6203578b6}, {0x0002679d20d4837e,0x000fa09a67212915,0x0001e993e548aecf,0x000034e7752d33de}, {0x0008c0133b8d99be,0x0005d644443ed88b,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005d09795891669,0x00055ce0c6b8f799,0x000cdfa7a67baad2,0x0009a5462a84102f}, {0x000ca5fff322b2ed,0x00016895f0238b4c,0x000e1fc27a1fc8f3,0x0007399300db4369}, {0x00016f718708ed71,0x000aa4931503fe5f,0x0000000000000001,0x0000000000000000}}, {{0x00040da9e1ff0c6b,0x00022af9967269a0,0x0005871908b86944,0x000801c88350fa73}, {0x000f680cd1b5d61c,0x000f0b415826cc63,0x0008b363474f5f7a,0x00027800e5401e93}, {0x0002305262f20f7f,0x0005e6d27bb44c56,0x0000000000000000,0x0000000000000000}}}, + {{{0x000dab714dbca0be,0x000450d634bc786d,0x000d2802c42f3afb,0x000ef6e542d9994d}, {0x000946669336b0ea,0x0006a8fe65059b68,0x000f702cce1812e5,0x00030e3c70e359c5}, {0x0009fd5b9f2069d5,0x000093f3f0186d75,0x0000000000000001,0x0000000000000000}}, {{0x0006d10e2b40858b,0x000a417e22a4fbc2,0x00013ba0de831401,0x000d41a31a86b763}, {0x000893ad0b78b7c2,0x000aacf20f1564cd,0x000bac0041297947,0x0004ac69dc2da24d}, {0x000ba071987933c2,0x0007176068dfbd75,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c8b4eb4601064,0x00099a991f16e053,0x0005bcf58e425bfa,0x000b1e6fefc21bff}, {0x0005da04d7e97cf6,0x0003f93bddaedacc,0x000336130ff2741f,0x00028f428d033ae2}, {0x000b98d58f0cc054,0x000281be6796c6ea,0x0000000000000001,0x0000000000000000}}, {{0x000562d3cd261bc6,0x000c4e652831be2e,0x0007f84fc06f2ac2,0x000b078d9ca13774}, {0x000d2b248e882f5c,0x0006981dfa0231e8,0x0005f7dcfabfd673,0x000f3658f51759de}, {0x000d6a68de41452d,0x00038358c049f993,0x0000000000000000,0x0000000000000000}}}, + {{{0x000dba36a11f468b,0x000ddefecb4596c7,0x00004044ba328343,0x000e3d89658e943c}, {0x000955f5e1aeb372,0x00008650d658c0f4,0x0004309aed6ff5c1,0x0000ad875f7bb480}, {0x000c35156e670707,0x00066875cf1c6033,0x0000000000000000,0x0000000000000000}}, {{0x000bceb289713705,0x000a8a9a03fa8061,0x000cac052e91978c,0x000b61eb6bb99c20}, {0x000e50fb8f33460f,0x000ec61a887398ae,0x0007437f45e3c633,0x000fcf4c74c22971}, {0x0004691a2d9b4866,0x0009004647f4a64b,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004f3cfa7e54e73,0x00076a7075c33047,0x000b446bdd4b3ee5,0x0003371a1b7efe90}, {0x00013826a3c98a14,0x000412cdba45fcf1,0x00048a44b5601caa,0x000206ebe3f76143}, {0x00050e4439f111b6,0x0008451f6bb4a9d7,0x0000000000000000,0x0000000000000000}}, {{0x000c0d59b5f2d48b,0x00029bcb29ae2863,0x0003a9a3c78e216b,0x0007856c2465c5b5}, {0x0004736d155fd956,0x0001ce6b07dfbfe0,0x0008361c3a4fa43a,0x000d0e9f03c0f19b}, {0x000e803f9b21f548,0x0002f885460ccb9d,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=88 [{1,2,3,..,}]*([2^352]*G) */ + {{{0x0006b287cbed671f,0x00071c978130d6d2,0x0007aadd881d433a,0x0004f45fb4ad7bb1}, {0x000d7b1940d6b52e,0x0002d44569722e2b,0x000de70f91dc84e7,0x000ed42546436d3f}, {0x00047e41abd1bc41,0x00010f544a7be2b8,0x0000000000000000,0x0000000000000000}}, {{0x000e82545325818a,0x0003cf3d8e5d2be2,0x0005f30317d1c986,0x00015ce098fb8ec2}, {0x000158947db8581f,0x00055d8793f3e6c3,0x000f50843a7feb50,0x0008ac153d3d8417}, {0x0004329e7248bbc3,0x000d2ffcfbcb0366,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b91e88872c802,0x0009859329a6f390,0x000332091e85e0fd,0x000d0a1fc7233994}, {0x000c07172741e069,0x000870fafc953488,0x000d8073b040fb91,0x00089e841e1bbb2f}, {0x000f582161687272,0x0007bfa72dc0f548,0x0000000000000001,0x0000000000000000}}, {{0x000c2f4044695d52,0x000e9fc898f3ae4e,0x000d6d16346893df,0x000cc356cfc2a2d6}, {0x0008f9780e14adcf,0x00040c34a952a0f5,0x000bf1f1f74017fe,0x000ae85cc7e49637}, {0x0002400547db8273,0x000eafd4e119d7f7,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a5355afe08a2e,0x000687a2f29baf29,0x000653058a23e11c,0x000110b2ab5abb63}, {0x000e4ead1d1b9533,0x0005d1b7b6254324,0x00074059ad5a8616,0x00090712ab62d100}, {0x000e9d5016f88f2a,0x000afeefd62c6b78,0x0000000000000000,0x0000000000000000}}, {{0x000d2d42ce0d173b,0x0009198d15289e62,0x0004baf7b535d68b,0x0008566e4a9af773}, {0x000402c278158bfd,0x000603f6310f0f5b,0x000331a366d639ea,0x0007457655beed79}, {0x0004b46175b5f4bc,0x00048f6ced012274,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b20efdb706d0d,0x000c40117c40b081,0x0000a6d9c2aec008,0x0004d3e0693270e3}, {0x000674266a5ea611,0x0001ebf62144a6af,0x0003d45ee3917e38,0x0008c35ff5d67fca}, {0x0006e79dba352604,0x00081a7e7bfed40f,0x0000000000000000,0x0000000000000000}}, {{0x00006eb8dc692380,0x000fe33343c5a20c,0x0003e67d0a53418c,0x0008959e15eb001a}, {0x000ac0ead5e7c7e4,0x0002e4162f0962e6,0x00017bb3e28513c3,0x0004317568fafb81}, {0x000912ceb3a2e303,0x000102559381740c,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005f372c77f1047,0x000b3d958eb7b744,0x00069ac2a8ab1157,0x00057d2ec5015809}, {0x0007f4db5c158ff6,0x000e3fc15a71737f,0x00048e949735c5de,0x0003845758233ed6}, {0x000e91137608f198,0x000720cc72b9199c,0x0000000000000000,0x0000000000000000}}, {{0x000b050528cb006d,0x000ac29d53a71cfd,0x0009a1f2ad6eb262,0x0006c829676f56dc}, {0x0003dd6ddbfb591a,0x000c61cac801979f,0x00031b13cd6cc83a,0x0003cf1a5e5c85bc}, {0x0007cff1f95623b3,0x0004f7b2cd595d6e,0x0000000000000001,0x0000000000000000}}}, + {{{0x000699fc8b3dab7b,0x000229f393f97b3f,0x000012376dbad08a,0x00038a797638cccb}, {0x0006110a40e7e328,0x000e3d1acf08dea4,0x00003f85adfc07de,0x000fffa8d9d37eb4}, {0x000db3ca114eff2b,0x000b41dd72c79e23,0x0000000000000001,0x0000000000000000}}, {{0x000822fbbe3ad3af,0x000ddd71461cfcd7,0x000d3d8f03aedaa8,0x000f069c35282be1}, {0x0009283f776eb004,0x000746b05b9838ad,0x0002fcc85c205f31,0x000bd9143e61b0eb}, {0x0004e7f4435b3321,0x000a673088e100ce,0x0000000000000001,0x0000000000000000}}}, + {{{0x00052e132b686982,0x000419eaf166734f,0x000edb4ffc59ba11,0x0004fda13f9e0e45}, {0x0000c12226a0efde,0x00070adf716ee2a5,0x000402012f467257,0x000f2ecf2b32d94e}, {0x000205b1386ade63,0x000b3bc779c31b50,0x0000000000000001,0x0000000000000000}}, {{0x000cbbdbe0875f47,0x000a208dcda3e65d,0x00048b61b40cb945,0x0002b16480725e0f}, {0x000aa186079b7359,0x0007e306ab144462,0x0004b09effdc0e10,0x000a76ab4395ae17}, {0x0008c3ddeeefeec9,0x000216cdb5d669d6,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c70f6d4b2fef7,0x000c0c92ef06acfe,0x000790f3344c38aa,0x0000fed753c30edf}, {0x0003dfc8006501b4,0x000df722f2f6da80,0x000c340284a42e2f,0x0002a0f154005cec}, {0x00082f0dfb36ac65,0x0007bed1506b21ef,0x0000000000000000,0x0000000000000000}}, {{0x000d76b785906061,0x000edca1c3d7b884,0x000307e9a89c6050,0x000e0ccc1519baa6}, {0x000663495eff88c7,0x000a17475b22e916,0x000c39e69639f1ce,0x000b1f0e827f8c53}, {0x000066355ede8121,0x000d5b91249281eb,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=89 [{1,2,3,..,}]*([2^356]*G) */ + {{{0x000ccccf35a37229,0x000465167517203a,0x0001bf938eaa2ac7,0x000d73d683a983dd}, {0x0007f598a6f1db73,0x000235f9ed630b4f,0x000f332db784cb56,0x0003b330540f52bd}, {0x0005843b0221e5e8,0x00044a09499b4ec2,0x0000000000000000,0x0000000000000000}}, {{0x0000fb3cab0a1b02,0x0008968b6e52dc01,0x00022c046dc60a24,0x000695beae1e187a}, {0x000d3006acf49482,0x000960f10535934b,0x000df011e1d0143b,0x00085de371d84cfd}, {0x00082841456c439e,0x000585582ff3b564,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e94ac6fbf17fb,0x00044289803b61bc,0x0002e798f31e8afe,0x0005e43d9a42f37b}, {0x000f377aef7a7947,0x00003a6947a8f685,0x000c1b4969c3b8c2,0x000b9c542cdbdf0d}, {0x000501682c76bc8f,0x0006972a768660ff,0x0000000000000000,0x0000000000000000}}, {{0x000f9daec5f3009b,0x000325c4a46652c8,0x000b09499ac89b1c,0x0003ccd5721c0cae}, {0x00098da46e3445e6,0x0002db691caca0b9,0x000845a793a1fc73,0x000ad927f614049e}, {0x000024bf07aea310,0x0007245359be8b80,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000db1596cc9e80,0x0009a231d0f49f13,0x000f1d499d6bd9c7,0x000757ac7ea9b7cf}, {0x0005305a4d545367,0x000f2c85480a42a4,0x00029efd461a5b51,0x000fe691c9e6b8ed}, {0x00090ea1ca549541,0x00058f09c0153e64,0x0000000000000000,0x0000000000000000}}, {{0x000525f593f9a0ed,0x000edbc140a1f67f,0x000f5bef166a98aa,0x0007a559750be5c2}, {0x000fb8cba58b2d45,0x00014d93d0c5d96c,0x000723470bfa2f95,0x0004f6b79058b86d}, {0x000d58f11a8a7858,0x000fe32b2d0ad418,0x0000000000000001,0x0000000000000000}}}, + {{{0x00016f6d1a0d42ca,0x0000a7c2c062afb4,0x0001630676c3dacb,0x000c297ad74ee6b3}, {0x000d18f736e4995f,0x00064edc2548a7a2,0x00031596b5d5f53d,0x00040e945b2c8330}, {0x000587c06dfaa52c,0x00037c462a8f05b0,0x0000000000000000,0x0000000000000000}}, {{0x000cd636b4f0d870,0x000b2b0835ddc02f,0x000d233347086482,0x000bf92bc7f1c7b2}, {0x00050d5f30c92b32,0x000ce136c0491539,0x000254d29288cec9,0x000c34eb38494ac8}, {0x000ba2a1b0b3117a,0x000c473a85376a14,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002a61629b67537,0x000edcfef26d3aba,0x0004bac42f2af22b,0x0004da8b32bd0514}, {0x000be474d59e6af5,0x000c190f17846ca3,0x000f3e17e7c79bfa,0x000a13543ecbaea0}, {0x000e74acd0ff996b,0x000cbde27a5f5aab,0x0000000000000000,0x0000000000000000}}, {{0x000ccc73ffeccff0,0x00082b1e746179a8,0x000b19b717d62af8,0x0005045a4e0895be}, {0x0006b8f194a8bb25,0x00089f1cd50b3736,0x000f2a57b3da3e10,0x000691e4f67468b1}, {0x0008976ca9c4602f,0x0005e53ed98ad969,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f79bf523ecdd9,0x00097ebf36d74486,0x0000fe48147bf45f,0x000868d46235b3ae}, {0x00073a9b13d93d40,0x0004e9264c45fa91,0x0008c79b5705f4c3,0x0000fd4b166fd0d5}, {0x000aca2edaf4ff87,0x000955b68a488f7a,0x0000000000000000,0x0000000000000000}}, {{0x000f3e0b19951fb2,0x000c26747dd972f5,0x00092d84bc8f6fc0,0x000255f7088102b5}, {0x000c984970893201,0x000a6791707f6288,0x00072769309b54e6,0x0006389f4da5d532}, {0x000c1eb23c48b5de,0x000d1bac794b858f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e2d8dfd2d5a87,0x000e5a708c918328,0x0009b9fb00f1dbe8,0x000fe9c7a3695cb8}, {0x000749205b4caaea,0x00056f204bd6ec0b,0x0001a73a9e0254c7,0x0004152441cfd51d}, {0x0000d2b8b0ca9156,0x0004dee3cdd9e937,0x0000000000000001,0x0000000000000000}}, {{0x000ab13754dec146,0x000b5d5322d78e9d,0x0000adbfc5578b8a,0x0000ce27a2b97f9c}, {0x000b49cd573f2d5d,0x0006ee23d2e94e39,0x00061ea213bd15a0,0x000e561b9d34708d}, {0x000fb576c6271f59,0x0001669ae9450741,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001a66376c54f37,0x000a06b888102e23,0x000430b0efaaecdf,0x0003b1e3d888793c}, {0x0004f8beed2dbb12,0x000ea5e72a8887df,0x000d4aa2425e9853,0x0009d98e93f3ccc7}, {0x000cba97fe918171,0x0006b08ea6eef307,0x0000000000000001,0x0000000000000000}}, {{0x00019b171f51c344,0x000d5e5d9f40be57,0x000fea96313e16ec,0x0001461efe1e359f}, {0x00043de9904f3d9f,0x00081bb7a038f6d9,0x000ed552c5787d58,0x000a67fc2cd9a74e}, {0x000643f377ccb483,0x0009db7070b5762c,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=90 [{1,2,3,..,}]*([2^360]*G) */ + {{{0x000188556b53942b,0x000736bd7c7672ca,0x000a466705820ced,0x00039ba4b83d6897}, {0x000af174ecbf7e3f,0x00003dc58b34188f,0x000b453db5dba0b2,0x000ef54df32d5206}, {0x000d08e3c52fcf51,0x0003732f551f3408,0x0000000000000000,0x0000000000000000}}, {{0x000937ade92603b2,0x000b6a7f7f5dfd6b,0x0003151876b632c9,0x0009040d3ee4a789}, {0x0007441b009fd7a5,0x0008b427fedfc2d2,0x0007f921c0ceded6,0x0002220fc8f207d5}, {0x0000f675383c79a4,0x000d6f410a2e837b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fb8b792ff9c0f,0x00062d82addc4301,0x000b9cdf1d9fdb00,0x00042255b1cf25ad}, {0x0009daaea42ebb5a,0x000dffd105199066,0x00001d688f207641,0x0001da7769bd6130}, {0x0004ea507a275aa1,0x000073ea612e43e0,0x0000000000000000,0x0000000000000000}}, {{0x000f18b4b24386fb,0x000f72268a5e0821,0x000ad126436a7554,0x000ba02f714fe1c3}, {0x00019b7c7cde45b5,0x000c576f09f2da35,0x000aef34fb328e0f,0x0001a0386e0f185f}, {0x0007a6bb32adc73d,0x000733da21be9ac9,0x0000000000000001,0x0000000000000000}}}, + {{{0x00023d540d542b80,0x0004cc500040b26a,0x000e6a09fa7f8755,0x00027fbb548aea96}, {0x00065fa1d8c060cf,0x000943cfee1a6187,0x00061bce6a8c7ea1,0x000d99730b0b20bf}, {0x000eac170744528d,0x000423d049742c42,0x0000000000000000,0x0000000000000000}}, {{0x0002bba636da345a,0x000a62e601cd801e,0x000c9e240a6cbeef,0x000103af8106469f}, {0x00007c7109e54da8,0x000b9a3ec3dcc449,0x0007788e44b6df8d,0x000d0e67c93ee34b}, {0x000e8347b4a58495,0x00037223b5096e63,0x0000000000000001,0x0000000000000000}}}, + {{{0x000417e035b970b5,0x000ca1b60364c1bf,0x000ea847f52dda37,0x000517fb28527f5c}, {0x00007a1e399f798d,0x000452c79fff102f,0x000688a87dfab3cc,0x0006490b0295c5aa}, {0x000d17acd0dbc605,0x0005acb4f6972c3d,0x0000000000000001,0x0000000000000000}}, {{0x000fa35559042635,0x0004e33a903ffa23,0x000c46f6e3526281,0x0007bc6b1cec4214}, {0x0004bca2e1dc8726,0x000b50045720b747,0x000c697f394811de,0x000ba5001f3d4304}, {0x0009ea7fd0f7a5e2,0x00090dead3d0124c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e47c23d19de00,0x0009afd475bc3cb7,0x0001acc6490ff459,0x0009f5dc39b1950f}, {0x00064d14540f1ee0,0x0001b75050e51c95,0x0005647bebd088ff,0x000f240dba4c1789}, {0x0009b95e8097400c,0x00085b5d4b842055,0x0000000000000001,0x0000000000000000}}, {{0x000986a76d06fbfb,0x000d7fc2ffb65385,0x00018e264c5a478e,0x0005a2784841d184}, {0x000fe21d9e8a017a,0x000bf52154297fe2,0x0007dad072d6d911,0x000eae77c8ea8832}, {0x000786b6a02d1fcb,0x000e682555450013,0x0000000000000000,0x0000000000000000}}}, + {{{0x000de731f9f48a0a,0x000a357753cff617,0x00073655403972b7,0x0000484d28d73a10}, {0x000c846d46c140c7,0x00055b7ef1516a9d,0x00014890b5525944,0x0005f418ade1b816}, {0x000a465f264a9164,0x000ed37693e9a176,0x0000000000000001,0x0000000000000000}}, {{0x000e5c3bfdcbca2f,0x000121dc135bc4e5,0x0003d39b5c7ca946,0x000be46855877498}, {0x000879fb5d801318,0x000afd92b1e5cb62,0x00024aecd7f80343,0x0004a3835c8434ed}, {0x00025764c6aa7d95,0x000a0241780668d3,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c0928cf2280c1,0x000f2c37933b1734,0x0006bae2a2974a56,0x0001e8bdb1d26ac8}, {0x0009c84c336cb6bd,0x000ca41014cdaa1b,0x00024b87838c44fa,0x000f525239cae2ce}, {0x000cb0507515f204,0x000993dbd0e0a58b,0x0000000000000001,0x0000000000000000}}, {{0x0001411bdc3926ce,0x00087f3e15aa5363,0x000ade47bf68672c,0x000028e493da50d5}, {0x000120048f8cd148,0x0005ecfaeb03c756,0x000e1347b7867aab,0x000ba0208953afcd}, {0x000be9b23e2411e3,0x000a2e848d40b424,0x0000000000000001,0x0000000000000000}}}, + {{{0x000583ec08d4ad28,0x0007687b7ba7d916,0x0002b3f0b4e2bbb4,0x0002caace0e4b3fb}, {0x000b0e6fb63a6917,0x00000520c822aab4,0x000f41f7930e37aa,0x00046bfa91da4dcb}, {0x0008bd604f521a69,0x00040fa707c1f0b8,0x0000000000000001,0x0000000000000000}}, {{0x000520b880d23952,0x000bb822333018d8,0x000aa6a00bca6bc2,0x000f3469011553af}, {0x000c20ed5fc0a5de,0x000ee0e8c5bcfec7,0x000476e2f464224d,0x0002d844542e8adb}, {0x00009924fd3c1bdb,0x000f2fac98d161a7,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=91 [{1,2,3,..,}]*([2^364]*G) */ + {{{0x000c9a655367407c,0x00001acf48b04d30,0x00004344830b68ea,0x00058a53174d6fa7}, {0x000f59044eeb31ac,0x00087d51a60524d6,0x000a344fb882d4df,0x000d1ed41d08aa0b}, {0x00086b6aea85fb93,0x0007f27fa57f4860,0x0000000000000001,0x0000000000000000}}, {{0x0006f6fa7b7febd7,0x000ef92aae956259,0x000abc183c404813,0x00011be4ded30d2a}, {0x000e220b7ae966a0,0x000c3e6cfc88e77b,0x000a92b77d5e0cab,0x0003d7f99c6dac06}, {0x0000a6be4c76c302,0x00032d1d55150da8,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000d37f0300cf42,0x000564d1a1ebfaea,0x000bce4cf04b07ea,0x00084f2b4677d784}, {0x000db14a4f867741,0x0000b95ce93b8741,0x000a31735b5960b0,0x0003d2c80a76fae4}, {0x00022c4d123107ec,0x0006cd8678a9d705,0x0000000000000001,0x0000000000000000}}, {{0x0004b58dcaec13d9,0x00067d88c3d5f230,0x000f847248f45f52,0x0003da2628ef4e85}, {0x000e37945a7b9c0f,0x000a2da387ea2c17,0x0008e98e84de9888,0x00038290c88f211a}, {0x0004ce3667557434,0x000040ca4612f56b,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009e872c584974d,0x0006ca75132450c3,0x0006c420ca2dafbb,0x00069da0e632e68f}, {0x00018e1d45c5a963,0x0000394fa7a8601f,0x00098adcea6c9852,0x0001b23e3c6dad95}, {0x000f0655b2b99628,0x0001992529d81db4,0x0000000000000000,0x0000000000000000}}, {{0x00000b6625e14e8c,0x0006611065dd0a46,0x0000a833140f2868,0x000735d82490f09d}, {0x000326d182482735,0x00074f69a678ac02,0x000e336a3425366d,0x0000093a8f215358}, {0x000644f6ddf3569b,0x000d19beff776a6e,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007a73bd7975b73,0x0004ba1e3ef4b56c,0x000835871e0104fc,0x000ed4624759b57a}, {0x000eed3c95d4d9b4,0x00029d8353648a71,0x0006bedece81ad28,0x0001452c12f2b2a5}, {0x000ab19b8b67ec3e,0x000ccd3f8f88bf35,0x0000000000000000,0x0000000000000000}}, {{0x000062e0d5c7f0b6,0x000dd34abff69676,0x0009b89962a6641c,0x0002be1c0add12e1}, {0x00014a078191a9f4,0x000c488cf972d9da,0x00090e9607f65fc7,0x000d5cdadd7da7e7}, {0x0001ca37f83b3584,0x000dd43c6df02d38,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003f8ca58799292,0x000601d1cbef0700,0x000f41308b0cefb1,0x00090de4387a468e}, {0x00035f90ae8d18bb,0x000b356306c0a768,0x0005e167044866de,0x000114237a5a47dc}, {0x000143e3b4bbc084,0x000c1c6d0277c186,0x0000000000000000,0x0000000000000000}}, {{0x000c81887bc12544,0x0006af4b6c2a8e8c,0x000ba5958fe82cbe,0x00067cd479340299}, {0x000d360f1809e7e6,0x000de77ee94fcc0f,0x0009d25d201341ff,0x000fac2af6e20977}, {0x000dfea19f8974a2,0x000fba7a5252c712,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001e6367ded4905,0x000fd6fd8b41173a,0x0000c717ef3cdcf0,0x000608fdb3300d01}, {0x0000d527d7c8e07e,0x00039cd9ece69c0a,0x000677211bdaf48d,0x000b5d520c7fa557}, {0x000bf842692f3c61,0x000055814bffe31f,0x0000000000000001,0x0000000000000000}}, {{0x000c94502a0e0f49,0x0000528193bb953d,0x000d7bdda5ab1a23,0x0007c4a219650b25}, {0x0000f78abb7ba4c6,0x000eb157bdb9dbe1,0x000ace6b3d0ff943,0x00048180c4dc1a32}, {0x0000124b69e9b36a,0x000da7fee72796eb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000530dbdddc111e,0x0004131a0423e417,0x0002a2fcd4c890b5,0x000685a6ffdb8021}, {0x0001c68bcc7cf314,0x000fb29a153281e3,0x00090775f2e2a729,0x000fe4fc20716627}, {0x0005fa8915460a5d,0x000b7744dbded762,0x0000000000000001,0x0000000000000000}}, {{0x00058330ded93a3e,0x0002ad9ca2943c52,0x00031d21ab8030d0,0x000fe30e76f64897}, {0x0002b30fd418c647,0x000815868a20f82e,0x00098d35bf8cbd5b,0x000facccde412b85}, {0x000358ff02bb4ec8,0x000fa54fb1673bc1,0x0000000000000001,0x0000000000000000}}}, + {{{0x000aed08c7bd3b0c,0x0004e546195fa3ed,0x000c31c13efbcb9e,0x000f2eaeb2cc8a6a}, {0x000a1912ca200483,0x000f0ff27a5ee60f,0x0000a7b9e9c56cff,0x00044977503cdac7}, {0x00064deabbda5a3e,0x00038efe3a9fcba5,0x0000000000000001,0x0000000000000000}}, {{0x000821113784eeb7,0x000a12560a5e577e,0x000ae4b9aaf4ec38,0x0005c9a38358d926}, {0x000497b69c24b1cb,0x00007485410e5464,0x00026fb660a2d50c,0x000987263ee5a4c4}, {0x000b3ba20c286e0b,0x000ae54bed6c50f7,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=92 [{1,2,3,..,}]*([2^368]*G) */ + {{{0x000e2418ebe8f2ee,0x000f4560bac026d4,0x00008c6a85ee3153,0x000c7d7d8e05a0fb}, {0x000d35867d053abe,0x000ebaaa06ca6918,0x00022207d8627f01,0x000fdfe74b9c6ea9}, {0x000478deb27dc332,0x0006b633ddba7b54,0x0000000000000000,0x0000000000000000}}, {{0x000eb3b84da8ae44,0x000dced254321c2f,0x000ae0be12cbd92c,0x000b5fae91edd7e2}, {0x000adacef448565a,0x0003f288c1607c22,0x000ea8d01e22b70e,0x0004e3598c73a3ba}, {0x0009cd9f6c24e3c9,0x0007a5595791d3f8,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cd049d3a9026e,0x000dbe859af0b3a1,0x000d9aa6b9632b70,0x00029dc483656cba}, {0x0007d02bc7ba1a52,0x000fc68a06574b48,0x000470a9518ff35f,0x000aaf20c720ad36}, {0x0003bb49ecf8b908,0x000f66f8b9d88aee,0x0000000000000001,0x0000000000000000}}, {{0x0004ae92aaca41ff,0x0009e2ff799aa5c0,0x00048de6d0a352ca,0x0008f5f2eb0f3051}, {0x000fea98f1062e2b,0x000285eca4dfe726,0x00044d322419400c,0x0001441ba1f95272}, {0x000c0f6113ec0c84,0x000b67f7b093769a,0x0000000000000001,0x0000000000000000}}}, + {{{0x00010c16516e4d3c,0x000611e277c39f9f,0x00040673dd719aec,0x000e007e471514eb}, {0x0006cb0a884f04c5,0x0007cdfc977e1e7d,0x00096fd19b101b5e,0x0008b661589b4413}, {0x0006ee58455ad5da,0x00030384dfd6a666,0x0000000000000001,0x0000000000000000}}, {{0x000dcee7cc09a195,0x000f049d8452fc3f,0x000453637f0d8b3f,0x0001dc43d12fc712}, {0x000f4b97aa7b885d,0x00030970db43c87b,0x000015eb8214e6b6,0x0006a5744b5ac5b8}, {0x0008d3fab8987808,0x0008438a227d82a5,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002d58e6de7c70e,0x000a184fd2b399ce,0x000d46ffafde56a0,0x0003266443a772e3}, {0x0009e5e99ec73618,0x00068acc975a652a,0x000b99dda22ced10,0x000f17534159829e}, {0x000ab0176c94c616,0x000fbda334609df6,0x0000000000000001,0x0000000000000000}}, {{0x000e586ebac6018e,0x000f2f03144a03f0,0x00070d82d13df49e,0x000fad35f054795a}, {0x000bfca4e83c93d4,0x000ccd2e817178dc,0x00006d906f96d5dd,0x000999860a4c0599}, {0x0007c4473b0cc898,0x0002a9c7a2422f0b,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002b09542f251bc,0x000e9c6a4a88693c,0x000ca160d5142fa0,0x000a8912377d1615}, {0x000e8a6efbddaae6,0x000a4c058235658a,0x000f27a6a6dd7c56,0x00070769ea7bd61f}, {0x0006f5dde4e365fe,0x000d56d5c0ff87a3,0x0000000000000000,0x0000000000000000}}, {{0x000ceae2e0074d51,0x0000c081ba44424f,0x000d9e0eec434166,0x000bbc85793c6ecf}, {0x0000cfdda19dc769,0x0009ff9b44e244b1,0x00055190f00a8e3e,0x000a30e6f1e94105}, {0x0002df24f630f9cd,0x000164028859bc1d,0x0000000000000001,0x0000000000000000}}}, + {{{0x00091d8b229586b3,0x00062d4212a9d0d7,0x000a44dcf82dea37,0x000886a8066a0e31}, {0x000c8d5c7f9428cd,0x000e7fa7c681f5e4,0x000db54aa6ccbecd,0x000e8442c468c6ab}, {0x000eb0d35eb4fd66,0x000ecc62bfda1f45,0x0000000000000000,0x0000000000000000}}, {{0x00043fbb4e2cb5f4,0x000b78f0a96488d5,0x0000f4585ef033e7,0x000ccf9f3f7c9386}, {0x0002c56f736843a4,0x0003c2a98300d2f8,0x000d0e9651445c74,0x0006ad9774234178}, {0x000b0d7d2ff89fee,0x0002dc8f018f3a2c,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a0b1e42fb1d75,0x0005875ba8ec633c,0x0009652adf59ccbb,0x000c9a8c4da98461}, {0x000058421fa35715,0x000861494cf70c21,0x0001a367a4a6e22b,0x000f1f29e364cf7f}, {0x0002eb8412063103,0x000046241f101761,0x0000000000000001,0x0000000000000000}}, {{0x00035295fd113dfe,0x00087ca26d83dc56,0x00009b60485e1379,0x0006992ee53da791}, {0x0003f63e81d304b9,0x0005e83c82169ed5,0x000cdfc2181cd77e,0x0002864256eb4e4a}, {0x000dd24e836cab6d,0x0000560017a3ed5b,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000d40ea7dbd218,0x0000bffd292d5f99,0x0000b3c033efe2aa,0x0003caf5350ffa07}, {0x00062cba18d05709,0x000de1ef348e77aa,0x00050628dcafce95,0x000654c13b978d30}, {0x0004b7581a218420,0x000aebc1eed7a302,0x0000000000000000,0x0000000000000000}}, {{0x000467c3cff7787c,0x000cc65919f6e7d2,0x000e4ef4ee66f3a2,0x0005339dd95dc335}, {0x00083538624188b1,0x000c9f6ee9c47f71,0x000c2d00164075ad,0x0000fb8c9b9b8fc3}, {0x000ab425082f15ec,0x0003706da80b242c,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=93 [{1,2,3,..,}]*([2^372]*G) */ + {{{0x000981c54aaf54da,0x000345cebb5e6933,0x000544b1b1632546,0x0001b01f84cafbc6}, {0x000115cddc181798,0x000378ad86aa1393,0x00075fe68cbb4941,0x0009588ce3ac7e26}, {0x000708d627f2694e,0x000a9deda381ddab,0x0000000000000001,0x0000000000000000}}, {{0x000d5f56fe3c020f,0x00064c1a13df6f31,0x00002f2a54ccdb45,0x00018f47586ae362}, {0x000f6db9ebb1f191,0x000b71b6517fa3e3,0x000f8c282c695b00,0x000758306aa882ec}, {0x000bb71fac8a72bb,0x0005351671f4f924,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008318350691a0c,0x000b269d0103c9cb,0x000bca486ca47a18,0x0001af062d151fe9}, {0x000e7c2bcd6c38a3,0x000a2dd4944c38da,0x000d5e2d0cab5f56,0x0001aaffb6b80e8d}, {0x000b4ab87f1aa045,0x000baad7ec926bd1,0x0000000000000000,0x0000000000000000}}, {{0x0001499620b24214,0x0007f0d276179361,0x0005f42f5e14dbe6,0x000a3745bdaa4d19}, {0x000b02770c1ff9ae,0x00030746fe336a10,0x0005a19965986ef7,0x000598b61ae7500d}, {0x000c2b7c92c56a5b,0x0007c0f20ece26fb,0x0000000000000000,0x0000000000000000}}}, + {{{0x00087e69d72ded5b,0x000cbed0493c7849,0x00059557a83ba0a5,0x000cabc475bbdb17}, {0x0003d65e4a623f2a,0x00071fb7df8bf3c5,0x000f576c8eb2466d,0x0003c6d8140f7545}, {0x00002bd4e620a012,0x000cb967837a469f,0x0000000000000001,0x0000000000000000}}, {{0x000871f9216cfc43,0x000a4dc25382488b,0x000ef93af7d4b3a3,0x0003ed77dbf730c3}, {0x000a6f764526ebfd,0x000b6152b407f935,0x00025711c016476c,0x0003dee3ad5a2bf3}, {0x00009ed5688aaec7,0x0007cb5a614fc9fb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d2983eb57fb01,0x0006f8090fc8d49a,0x00055cd8ed43313e,0x000063128651d168}, {0x0009d55315e356a9,0x0003731bdb591a91,0x00090f35172884d8,0x000ce2ac6b9b209c}, {0x000e9deccfbd125c,0x0004c67d19839d92,0x0000000000000000,0x0000000000000000}}, {{0x0007835fb081749a,0x00038c29318405ed,0x000c88969fe7858c,0x000d9e6b39c13839}, {0x0001a193b85889e3,0x0000167b73a0e542,0x000e3a6c6ebad78e,0x000fea5061213cbb}, {0x000f99af7a8cbcf0,0x000934dbdf82d320,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dd97cee516977,0x000fc49266fa93ba,0x000b3371de037896,0x000f3467c9ec4ba4}, {0x000bff13f9988671,0x000c0500963fcb88,0x0009447add0b56dd,0x0005dc495e382a32}, {0x000c531e8e3d8f13,0x0003f8ab53419d64,0x0000000000000001,0x0000000000000000}}, {{0x0005999b06e01bce,0x0004ac4c86e9d1b3,0x0001acac55379f5c,0x000ed5f60cf793db}, {0x000deecc778efaf8,0x0005438ff64587a9,0x000da09df4f7f063,0x00095b550b56ea7d}, {0x000d4a2f2118371b,0x000897f5ee846337,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e73c876ead4f8,0x000074f77e1ef006,0x00068e9d113a8d10,0x00068c4c79701512}, {0x000c8af63c9e4975,0x0001a355ba1ddb87,0x000a7f69e6cd38b6,0x0001a9ae068bd113}, {0x000bc3a633214952,0x000e40b4f3b0cfc9,0x0000000000000001,0x0000000000000000}}, {{0x000dc3573f4bb5e4,0x000ce2ef087b7068,0x000ffeeffd386368,0x000053bd77e46931}, {0x0008c8fd63c43732,0x0009915ece7b6a54,0x0009d1980b122996,0x0000807d3a509f62}, {0x000abb80ee8c76fd,0x000ea6d20af82699,0x0000000000000001,0x0000000000000000}}}, + {{{0x00023cc70a1b7646,0x000fb2fea8f69076,0x00051b6f61d27313,0x00053b59960e18ea}, {0x0003b52c79117607,0x0003c4870ae1dead,0x000b0ba34bd1f16b,0x000eb6ec0bc7a291}, {0x000e48716fbdf694,0x000f3b9ceb0fbb83,0x0000000000000001,0x0000000000000000}}, {{0x000f4df150c14682,0x0004d73e71ecfad2,0x0001f4eed11e2bf5,0x000e8f7ba0e6130a}, {0x000d0ee611881177,0x0004b3748fb1ee0f,0x00018bc0f1b2681f,0x000d95b14d7b81f4}, {0x0005715bb9df9123,0x00010458047bf5c1,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007c0378bc40ed7,0x000325851811caa9,0x0000425fd5a042ad,0x00083181ae223e37}, {0x000dcf721e5a193b,0x000e3457f090e949,0x000bab83df6a8520,0x00045f22447cb654}, {0x0000dfbcc720ad35,0x00030064eddb51ec,0x0000000000000001,0x0000000000000000}}, {{0x0007e2d48a4ebf78,0x00086d5a22dda9a9,0x0004ad7ed63a6603,0x000bdfd6f4eac86c}, {0x0006ea0b3cfe90e9,0x0009746e43f3d057,0x000247c38598edeb,0x00066c63f53c5a4f}, {0x0007de7ce9110d7d,0x000580edc5628f93,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=94 [{1,2,3,..,}]*([2^376]*G) */ + {{{0x000ceb75a39240f6,0x000cd422d17ed307,0x000816d46db1d003,0x0000a452acb6fef8}, {0x000cb9bbe93acb00,0x000e7044e1a33425,0x000fc32d94105ed8,0x00077b448d72bf04}, {0x000527b278a8006d,0x0003f3ce1c27af77,0x0000000000000001,0x0000000000000000}}, {{0x000e21a0404fea41,0x000ba2bea8a562ed,0x0007dcaa390fe905,0x000e3be58bd01814}, {0x00024ad37906a8c2,0x0004147c934bd6ba,0x0008700ab35993ee,0x0003eb32c19654b1}, {0x000e9fb6dc4b6283,0x000fffefce4982fd,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008ddce89d919a0,0x000c8653953842cb,0x000510be22ec94ea,0x0004fc6818af52b2}, {0x000d36cd384c6520,0x0000918e38b08bd4,0x0008cd3bbca8f664,0x000f9b3d5866c2ac}, {0x00015b5a22e4fdae,0x00028fcebfa696bd,0x0000000000000001,0x0000000000000000}}, {{0x00086becff5dbeff,0x0002b0a9f4f0a089,0x0002781857ab5bde,0x000f7d34f623a384}, {0x000ab2fc32d5df48,0x000357b29a5aed2e,0x0002a4f85d8000c3,0x000a47c091a8d7a0}, {0x0008c875883e2289,0x00004c78f3991d74,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006929bd70c6394,0x00085f2018c22473,0x0004be72094183d0,0x00086c43b8504d5a}, {0x00086b6f18e21a1b,0x000ad297dd4ff469,0x0000f368a9142ac6,0x000e09fe86beaf09}, {0x0008c552b3b6921a,0x000bce953006e93c,0x0000000000000000,0x0000000000000000}}, {{0x00072ac6e0006309,0x00015780956c6baf,0x000c4c2c5f7fa741,0x0001eba55e9870c9}, {0x00060f57cfca17ec,0x0006e490ccc10b4b,0x0008a9db0618cc6a,0x000131fe5f0039e9}, {0x000970dbcf0f5361,0x000700a442baa6b1,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003ec842981eb23,0x0008fb16678799e5,0x000db8c26f2eb3f7,0x000307e41091298b}, {0x000c2265d3b22e09,0x000829161a79682b,0x00094108a62536ff,0x0002002fb6dedea9}, {0x00079fdbc3d369ec,0x0002baf58b2f20ca,0x0000000000000000,0x0000000000000000}}, {{0x00056d9fea698757,0x00041a61419646f7,0x000308b017c99346,0x0002b76a5de627fc}, {0x000cb23ee7d29bea,0x000ab47900ba8603,0x00096bb85c794766,0x000df41684cc004b}, {0x0007656ed94d547e,0x000e302003142b8b,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005cdf0222a69bc,0x0005e1e346fabbc8,0x000e07629de2b094,0x0005724f76a1e2b5}, {0x0006b43bc885c45e,0x000d1f53506f8c50,0x000458ec4a247aeb,0x000ee8c49a8e9759}, {0x000961f24ad9f81f,0x000c780789ce81ef,0x0000000000000000,0x0000000000000000}}, {{0x000ac3a5a536c8ac,0x000fe30d120ebbbd,0x00029a29c912f38c,0x000d27e5470f8673}, {0x000f785f54b6aa93,0x00069bc2c6347ce7,0x00091c1681c6e838,0x00015f8951322402}, {0x00054c132d778a68,0x0009133565718293,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f8e71a3d24acd,0x000de7f8ccaa4039,0x0004a565eb389f9f,0x0001445b3a88c7c8}, {0x000b1b88e20b6224,0x00022d8db00479b1,0x000369096695cdce,0x000d48a7013202fe}, {0x000e3713baba6a66,0x0009b65be868e0af,0x0000000000000000,0x0000000000000000}}, {{0x00018718a6375d71,0x0003fe3e38b8c6c5,0x000ee16d3bd00a61,0x0001a73a8bab2dac}, {0x0001decd0dde75f5,0x0009a19d5d5d598b,0x0002f5dcc2ed8e1f,0x0007b66c768674ed}, {0x000717b781a03645,0x000cd5eb14d9fd45,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009a4c40a33f00c,0x000d2d3bef2c63e1,0x000922215ae57c68,0x000763ee03e85348}, {0x000337a4a0d2cb54,0x00047d23204381fb,0x000be443d9712227,0x0007d96627f6c828}, {0x000fb6b5f6d1199b,0x000a433d2170b3ab,0x0000000000000001,0x0000000000000000}}, {{0x0001d3366971bb69,0x0007a38c946a2ebb,0x000b29fb103a111d,0x00047d3675997def}, {0x000fd82824e10a96,0x00029d6d05a45fde,0x000500fa9b94f37f,0x0002317e08c1e35c}, {0x0006ed9214c60102,0x000ee0a2afcd4a2a,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003291f02ce62ff,0x0005b8a731176ae1,0x00053e5b4c8c2f09,0x000d5a2322d8f01b}, {0x00092f09c90539b8,0x000c4c22646cfad1,0x0008df5016016f3a,0x0002500c56f4c2d4}, {0x0006618c9bed5731,0x000f52249d380720,0x0000000000000000,0x0000000000000000}}, {{0x00052bb2164b93c6,0x00009ba854f0dba7,0x0002bd9fbffad821,0x0002cee339d0e928}, {0x000515cfc63fee61,0x0008541bf33aca9e,0x0001f0f0fd5f8231,0x0008dccc44f51df1}, {0x000e26d92e5d7f0f,0x000334dc204c43c8,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=95 [{1,2,3,..,}]*([2^380]*G) */ + {{{0x000df775a4cea698,0x00057fa877dfb590,0x000f628f95d0e8c6,0x0004b622c58775b2}, {0x000e755966c521f9,0x000b826bcad94ba3,0x000585e536e18362,0x00056a8bf64e1429}, {0x000c0d065ab9cff4,0x000c6b7ad254f1fd,0x0000000000000001,0x0000000000000000}}, {{0x000be22413e6824f,0x0009f5a869cd6010,0x000399cde94b5cc4,0x000c96f6029dfb84}, {0x00068c7d0822053b,0x0006cb5f4bf3d33d,0x00090bad70bd72fb,0x000c5f85b78281e7}, {0x000fbd3aad6b87dd,0x00067e9bddab2fd6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f0963f658551e,0x0002ea1215b91acf,0x000276c4b8c7ce3e,0x0002c599ae4d76fd}, {0x00006cf3a3b9f27c,0x00006667b3985a81,0x00095ab3dd5545f7,0x000e9ae8ea63e5bf}, {0x0008eb3015a494d9,0x00014b36df8e2aac,0x0000000000000000,0x0000000000000000}}, {{0x0001e0605f96eb43,0x000d54ec384ae024,0x000bfb3e2ee19fc3,0x000c041bce0a2d7c}, {0x000b57e0aa0d1a5a,0x000f6adf1022b978,0x000452550508726c,0x000b77d6d81e1380}, {0x000536c9802fbac9,0x0007d16666d2c234,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d75964c31ca58,0x0004e22c167fba0f,0x0006865896879fb3,0x00085f113d2ac14b}, {0x000fcf92650326bb,0x0009815c6ae567c4,0x000703330478f2d0,0x000c2d4e045bb2da}, {0x0004917027450186,0x0001cb3d6ff5bbeb,0x0000000000000000,0x0000000000000000}}, {{0x0006aee5ed6230d6,0x0006f57fa7f974a9,0x000d445b19954b86,0x000cc41b7edd540d}, {0x0002f6672b9eada3,0x0005adb45c3c302e,0x00085355ea3de1bf,0x000a70efd3fa201f}, {0x0002e28049bc11d2,0x000a9e4d97e0553d,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005aaa83e0b7193,0x000ef4020dd38cdb,0x0000a2db89cf16c4,0x0008b727a5cd426b}, {0x000baf5617c8e43e,0x00043d6e5823ddc0,0x000180e259e17f2b,0x000506737413c826}, {0x0004e741255f63ef,0x00009623e6163c43,0x0000000000000001,0x0000000000000000}}, {{0x00095e5ae0c64c88,0x0006e547505a1996,0x00074ec16e26e1e3,0x0001814a43d8b0e2}, {0x0004c037ed439483,0x00075672e85b1a10,0x00064a05bc4b4563,0x0004f4e8604b9fdc}, {0x000d8d54cdb5b099,0x0008d7035e5850a1,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006358cac1e1dd9,0x000326ae97ec9d6b,0x00096931bf3f89cd,0x0008a8a20db33ff8}, {0x000f15df6988b172,0x0009cd5efc8b413b,0x000bb187876052fc,0x0004662d8014980d}, {0x000d9235f7d44d41,0x000edff0c8921456,0x0000000000000000,0x0000000000000000}}, {{0x0002553d46a6bdb6,0x000a25d43349dd7d,0x00098c5095dc275f,0x000e81697e9d6a23}, {0x00021486070955da,0x000de66e5e004d62,0x00061fc887538530,0x000b0cbeddeb407e}, {0x000968acbb1e576a,0x000ee36df6504685,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001376b4df2834d,0x0009122c927fc01d,0x000cb3e3200f4b1b,0x00077db8d6a633a1}, {0x000324c991410544,0x0009a4d4ddbf0c1c,0x0004f89da008df0a,0x000df68e550730c0}, {0x000e5c51e1a10f51,0x0008da410315475c,0x0000000000000001,0x0000000000000000}}, {{0x000c76b031581137,0x000f3f4ca12b9bde,0x0004e3a329753a8b,0x000499c86ef86a89}, {0x000c838a372fcc5a,0x000ec44e4a97d666,0x0000ea241b991236,0x0001650c8dbf9560}, {0x0007627fd4eb71cc,0x00078654f79c844c,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ce7225c38fca0,0x000cf6f1a6e96969,0x0009cc6268e77785,0x000308efc7d8303c}, {0x0008a6b0e52762b8,0x0004bf9968cba9dc,0x000db7c416fd26fa,0x0000e7d932fa8c4c}, {0x0002063b5de7df0b,0x000a1bd8e36d9447,0x0000000000000000,0x0000000000000000}}, {{0x0002f11b9d88f945,0x000b6a528d0c6d85,0x0000491c222e34eb,0x0005246f572cf3b4}, {0x000826a507a97323,0x00051b49545419c4,0x000f246a45d14681,0x0008555cac591e9f}, {0x00067c66c74cf909,0x000c814d10852a3f,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004d6495109aae5,0x000c4b86a81e7f4d,0x0004316eb1054df2,0x0006877c19b90005}, {0x0007963ac12d941b,0x000bdc46a9dbe383,0x000befbe68280f87,0x00071d97d1dc04af}, {0x000aabbcc64f8fe9,0x0008543ef9d7ecfd,0x0000000000000001,0x0000000000000000}}, {{0x00056ebb21998e32,0x000ab05f744a3f42,0x000c6587a4d462bb,0x000c14a18de305cc}, {0x00056d2c0e8c5f7c,0x0007f552fd1c2fa4,0x000165b93096db0d,0x0003eef9e935df5d}, {0x00013440e0a7d4ef,0x00020c2ecbc3b683,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=96 [{1,2,3,..,}]*([2^384]*G) */ + {{{0x0003ac5243ed86b5,0x00075f9805e79dc4,0x0002bee2dfe95a21,0x000284b06125c31c}, {0x000a0103195082b6,0x000cedfa4a2264eb,0x000afa325bc143e8,0x000ae3ae24853199}, {0x000ebe96963067c6,0x00096c54a7cecdeb,0x0000000000000000,0x0000000000000000}}, {{0x000e3a5229434e36,0x00055f3a1a50446d,0x000644f2db4f7215,0x000ad43f6dc38924}, {0x0002239beb126b72,0x000840de05e7dd77,0x0002862d6caacd0d,0x000bce6fa639c67a}, {0x000087602ba53021,0x000679ec9b598271,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005ed4dab9a7e9f,0x0006797aaab2f5b7,0x000301593051ee37,0x000962a30b02f44a}, {0x000a1d622cf13021,0x000a7dfa0555a3ee,0x0006aca4fcd685c9,0x000ad2e750777a2a}, {0x0006aa905bd4c914,0x0008ffeec52d7b1e,0x0000000000000001,0x0000000000000000}}, {{0x00095204a3f6fa1e,0x000c34539f85e4fa,0x000e8ddc16e36eee,0x00044a9e74599d1c}, {0x0007ab343c6c5502,0x00007951ae714c01,0x0005c8c4503f92db,0x0006830499e544d1}, {0x000188a7b94680ff,0x000147d6c4809fe7,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e6ff25ab97af1,0x000ec754ac7f57b5,0x000607a92403e802,0x0000eca9aece9592}, {0x00080834b57b8bd9,0x000e2fcd37a127de,0x000ed63155d3ec1e,0x000f99b11a3b9b54}, {0x000db302a147172f,0x0005d9290b10d36a,0x0000000000000000,0x0000000000000000}}, {{0x000eee6089f16e1a,0x000772f210e83cea,0x0002496230bbfc3c,0x000c1fbbcea01caa}, {0x00032cc99a5937d0,0x00074603f91be511,0x0003cfecb00c641e,0x000ef833255bc0f0}, {0x00085cab2f6311c8,0x000c7fcc61e9c871,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f147189a2546b,0x00070bf89fcfd41b,0x000a403ed89c0790,0x0003f861a107b324}, {0x0009b4dade6e318c,0x00032b6327665e9f,0x00016ecb408e3b33,0x000c11ee2181f62f}, {0x000ba590467bbd1b,0x000a0f4b5440b9d0,0x0000000000000001,0x0000000000000000}}, {{0x000b1aa7ade86660,0x000d1a8a32a33d9c,0x0009ae722d5edb96,0x0004c7770654bd1b}, {0x0001d03d0e5a5166,0x000b01ee816a4a63,0x00015843d1d9344f,0x000c1e1821b3c769}, {0x000c22520be2d285,0x000fe7e0834d6faf,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a30d8168852db,0x0007853d06621fd0,0x0000e561a31ba03d,0x000e2351f7abbee6}, {0x000bfa802185d2d6,0x000a8cb11d19a8eb,0x000b4f2b7623f602,0x000f149b3db4a55d}, {0x000399a66e1d6eee,0x000dded7de613b1a,0x0000000000000000,0x0000000000000000}}, {{0x000694da4aed0861,0x00013409999d11ea,0x00021cefe8e175cf,0x000ca47b4e5a0420}, {0x0008274d934ac552,0x000e270720e741b5,0x0003c0a8bd69787c,0x000e75f9cc756f74}, {0x0003e654e1ea2208,0x00040979701ca5a9,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d12f4d256a679,0x000fb6f240706408,0x0001c6799f2d7255,0x0002b1c7ad7d86d9}, {0x000c6259fb2898c3,0x000dc9f2eb172083,0x000f61ec85a5a26c,0x0002303eee79dca9}, {0x0003cc24582cff2b,0x000018aea38a1c28,0x0000000000000001,0x0000000000000000}}, {{0x000fee514ac3447b,0x00004db0b385f6f7,0x000785b0f880a482,0x0006256aaff858dd}, {0x0005224f69e65ae6,0x00099c8d9092f5e3,0x000a4d5b2e1cceee,0x00065201f6ee40cf}, {0x000abc908fefbb83,0x000f4461f21689bc,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006ba04a3b21865,0x000b257a4daf424e,0x000a3bec5e4ad4b6,0x0001bf9b577cca5f}, {0x000e764bad272e02,0x0003f73ae3883e3d,0x00078df5e21be44c,0x00046e6d9107b020}, {0x00009a9e8ecf5414,0x00062dbf7ce0cbdd,0x0000000000000001,0x0000000000000000}}, {{0x000ed268a93dd876,0x0001345efa0e6741,0x000a124edec5cb04,0x0002301ceb5830ec}, {0x000c074b8d138854,0x0003717a195a4b92,0x00078d388cdf3e4c,0x000aa6e0172f6f1a}, {0x000474fe593756f7,0x00063e14f10ad2f4,0x0000000000000000,0x0000000000000000}}}, + {{{0x00056d8ef5183d33,0x0006d4aef07505d7,0x000fd1d5c09dd4c2,0x00026645b43bb4e7}, {0x000876a817eb253c,0x000209c32af92f54,0x00083a63e205a086,0x000d802502f8b9b8}, {0x00069b5a7a6f9cb8,0x000e8d87089ec121,0x0000000000000000,0x0000000000000000}}, {{0x000c2981d5c3f78b,0x000fd7c0b6dcff4c,0x000e2051e1d39135,0x00056f990f800ca1}, {0x000bbae12c766764,0x000fc5fcbf987a86,0x000db02cbf344cfd,0x000965a4f55ea853}, {0x000d8cf4b24b115f,0x000ddb28cffa2bf4,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=97 [{1,2,3,..,}]*([2^388]*G) */ + {{{0x0004c9f1b01bbcb1,0x0008c564ba5d43cd,0x000b6d345ac26289,0x000156220f11b91d}, {0x000dcfa53c395f80,0x000e8f0647eb32e3,0x00071de125c49a24,0x00035c7837015374}, {0x000bc6a877a9741e,0x000a3e1c5d3aa600,0x0000000000000000,0x0000000000000000}}, {{0x000eae31d5cbf2fb,0x000ff21336f73218,0x00063097ec47555d,0x000e41ac8f16a8d5}, {0x00010c063790a928,0x000842e2a872cf72,0x000d214bed4668e2,0x000e7b5aab91e7f0}, {0x0002089cbbd94783,0x000d7755df6f3c47,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c45be80c5ceff,0x0008b5f3a736f81d,0x000f684853db7b94,0x0007af37a1d8a120}, {0x000c1e37602997de,0x0001ba866cadb401,0x000496a24e3e6caa,0x0002c3eae9d6cd94}, {0x00074e14e06f82a8,0x000343069d99834a,0x0000000000000001,0x0000000000000000}}, {{0x00060baf525e3e5c,0x000adc3855bae42a,0x00020017824fbb6a,0x000d2439950ab7cd}, {0x0001396b971049df,0x000925d16b65cd1e,0x0000815f2ec4dd14,0x00099059e2e1d82c}, {0x0007231633ba03a7,0x000c17f35a3c602f,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005cd392892c72b,0x000067c79588a466,0x0003e61043554996,0x000e4fea3dc40ec6}, {0x0006245b592ed7ab,0x000d5fddb91366af,0x0005bcef5cf9183d,0x0006f2afe7d93c79}, {0x00038f789bd81e98,0x000a24ae25969d23,0x0000000000000000,0x0000000000000000}}, {{0x00015df628bff28b,0x0008b0238f67e086,0x000debae13d569b1,0x000537b081c52561}, {0x000e3e637e8d5f7e,0x0000b558a9b4dba0,0x00092e9e6c338cb1,0x00054c7742924ded}, {0x0001b877e357069a,0x00077dfb12df7675,0x0000000000000000,0x0000000000000000}}}, + {{{0x000eac10daa6fc06,0x000a451d0d93fa05,0x00030dbe3663fb80,0x0003df5569a67246}, {0x000583a7b7740137,0x000a1bf5763b688d,0x00007976f4ce0d19,0x000972348a80c203}, {0x000296b9dd874e74,0x000ad726fc872424,0x0000000000000001,0x0000000000000000}}, {{0x000626a33acca649,0x00019c0b206a34a4,0x000597e1cfe661fc,0x000915e61f98c11b}, {0x0006400c41adb010,0x000ed21859bdcb2d,0x000247507de82c2f,0x0007ba1295daeffa}, {0x0000842d673a4f29,0x0001721fc083b457,0x0000000000000000,0x0000000000000000}}}, + {{{0x00034490e59e8714,0x0004db94a827c594,0x000be5c43f7b8f49,0x0005c1ed99f38332}, {0x000c89e5a5eae6d0,0x0007a328c3f873b0,0x000b195eb0205cc5,0x000957c8e1b9bcde}, {0x000a9c05764ec15f,0x0003785ee6082c58,0x0000000000000000,0x0000000000000000}}, {{0x0006efc5f7d22a96,0x000c221343eb9e1a,0x000752365f225594,0x00006ed92aaffd4a}, {0x00047b4ac0a51a79,0x00034752a1b444db,0x0000b01d86935b36,0x000ff91905b43171}, {0x000a16a9f33a34ae,0x00098febd2ea9993,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009425bd3be24b1,0x000ddf604bb70186,0x00004732993f7d31,0x0003e481243d40e7}, {0x000cdd085631cbfd,0x00020a779443a447,0x0005a3d17a4bd6e9,0x000c2ba013a6f159}, {0x000091ba40454351,0x000bd45892d66dc6,0x0000000000000000,0x0000000000000000}}, {{0x000413e025588ac6,0x0006b5fdc28cccb3,0x0001b7df9aa499d4,0x000dec43b5bc5fae}, {0x00066d0478edbc5a,0x000c5c7523db595f,0x000f66c3689cc921,0x000369286e3460ae}, {0x0009f5650aae055f,0x000ecf05c2d82ed3,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002dc4c335595b5,0x00087d3146806d12,0x000280502c85e0da,0x0006080ca34c63d6}, {0x00057bee19e4fbfb,0x000b329c24618627,0x00059c63cee44932,0x000729a1018b673d}, {0x00038096ab196705,0x0008deabcefcd004,0x0000000000000000,0x0000000000000000}}, {{0x0008d702c45db29c,0x000164a83c7ff2f7,0x00004bdcc8d9c10d,0x0006a51badde1985}, {0x0007b3d628a8f0d9,0x000238514e884060,0x0003ad2af9123d94,0x0001c02c79997897}, {0x000547f0e64e4ad3,0x0009546706bd2921,0x0000000000000000,0x0000000000000000}}}, + {{{0x000474c793f4e626,0x0001b9f27eccc505,0x0004061bf3c9bbd8,0x000776661385eed6}, {0x000ca2d5cbcfee54,0x000b0a8618a0f415,0x000c45418675f88a,0x000e0d5df7ae47e7}, {0x000f8808275324e3,0x0005bfe818ccf0e2,0x0000000000000000,0x0000000000000000}}, {{0x000d8f452acbfbda,0x000031ef224de6c2,0x00070dcb7f79ce12,0x00097b18d958660b}, {0x000224dfd1c89c45,0x000d69ce10da0fa5,0x0001b65989afa822,0x00094e1b3fa146e8}, {0x0002ae217dcac503,0x0006327d3eef4183,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=98 [{1,2,3,..,}]*([2^392]*G) */ + {{{0x000f424e1d9c6487,0x0001fab2d1847091,0x000c18abe11482b3,0x00002a204548d244}, {0x000d2901117bfc9e,0x00086c34a4b1dc1c,0x00025a48ee98a6d2,0x000cb76b3ae604c3}, {0x0001c8298db518ae,0x00008fb7194b2498,0x0000000000000001,0x0000000000000000}}, {{0x000055d976a5cca1,0x000a2cc7061a3bfd,0x0005a667bf88a107,0x00028dc3af0a63ac}, {0x000873e8641fb210,0x00040a558da80d94,0x000fc0963f8d8c7d,0x0009ccc465473acc}, {0x0005ce362fbd5307,0x00081d15006f15e8,0x0000000000000001,0x0000000000000000}}}, + {{{0x00022141cc3287fc,0x00038266149a76c1,0x000fdcc4f6ec602d,0x000673e316b23844}, {0x0002f7ff0591cea0,0x000226449753082d,0x0008c9cafeaf6b58,0x000801a84f6bca52}, {0x000738672e240363,0x0000fb54c4174c43,0x0000000000000000,0x0000000000000000}}, {{0x00005f340ab8f558,0x0003c50b6de62a42,0x000c67ea2a5a8485,0x000584f292e0d583}, {0x000976bb7a441296,0x000e6eb31fa9f0cd,0x0005886d0d33dfac,0x0005ca9b5dbb850b}, {0x0003bbd95e75a3fb,0x000aa9fc35ee4214,0x0000000000000000,0x0000000000000000}}}, + {{{0x00048296df946f82,0x000d1ae0f7178948,0x0009fea01e8f3835,0x00032c83af761a04}, {0x000c81060dc76c7d,0x00037519156c5ff4,0x000bd4aec6a8a45c,0x000cdf6166cd6f1d}, {0x00042edd4a64bcec,0x00087353c4d352a9,0x0000000000000000,0x0000000000000000}}, {{0x0007c5d100fac674,0x000db9e757c12a95,0x0005aae530260819,0x00099d6efbc64c70}, {0x00069b00bbd4972a,0x0000b755c13bf68d,0x000c9bf125fdc71f,0x0002e7e830894502}, {0x000fe09937e20c9f,0x00002b5fa7bc0dae,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006f3e4a3b653b6,0x000d1a688f6e0a4c,0x0009e0c6a622a9b6,0x00092759febdd4b3}, {0x0007de14d66ca7fb,0x000a2edb8e3d698e,0x0001ab808ea4d110,0x00080f85570610b2}, {0x0004c29e8f8405b0,0x00027dadf7ff6310,0x0000000000000001,0x0000000000000000}}, {{0x00057c2f52f741db,0x0008e2e671ed8847,0x000d5288875b3801,0x000d96a8629331d9}, {0x0005a7e602196279,0x0001f2dc09559eca,0x0008fe5f274c1468,0x0006483d04249681}, {0x000f5286b1c8246f,0x00077944ba105276,0x0000000000000001,0x0000000000000000}}}, + {{{0x00065afeabf73b11,0x0008c74def9ab376,0x00022e8ebbf2f73b,0x000cbc3cc29566a6}, {0x000e491e3c34a56e,0x0005e3e30062fb22,0x0008f34bd61c9faa,0x0006ad9002a6b766}, {0x0001e57f55fbc947,0x00052212e9e41cf0,0x0000000000000001,0x0000000000000000}}, {{0x0000895f7a4eff76,0x00077650f0c0269a,0x000b638552f2435d,0x000cabbe1734cb6d}, {0x000ac1912708cc1d,0x00051cb37cd08219,0x0002a65eea8444e1,0x000bbf996f86f52b}, {0x000fc6bb767f7430,0x000d61b13f4e2c8e,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d5ccc9d50240d,0x00084d2e5496b2b0,0x000f884405e473c3,0x00057903c51b5ae8}, {0x000d55afcc0675e0,0x000125af4b250a76,0x000937bc2b1d7e99,0x000a633470b9206a}, {0x0000cfe28137ad4e,0x0002cd8906210714,0x0000000000000000,0x0000000000000000}}, {{0x000877153680ec3c,0x00019913626b5dae,0x000bd89f532b2d72,0x000d578470af1c82}, {0x000b3f975bb94d7b,0x000f53a6076b8092,0x000db22bb5b744d5,0x000f43f924c34cb2}, {0x0006114e078b5812,0x000fb3e3de49501e,0x0000000000000000,0x0000000000000000}}}, + {{{0x00028536905d5e34,0x00092fdd83e93bc7,0x0001a64b28a1f75a,0x000a170fe5a66cb3}, {0x0001e6a59754016b,0x000c5178f6263ade,0x000bc78f0892f5d7,0x0002723285c0f5f3}, {0x000ce420f8de3807,0x0004c264b36ac9d2,0x0000000000000001,0x0000000000000000}}, {{0x000334fb73061393,0x000f6bbeabea50b7,0x000a60e0b4b57374,0x000565e15377dc7c}, {0x000ef0ff94b0e964,0x000e47e49a96f0ea,0x00030ac68d3dc2bc,0x0009347ee5d6453c}, {0x000eac1f6901d599,0x000086abf91bda19,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d441660f7e89b,0x0004d20a8f4b5442,0x000f7bf31e592476,0x0002835026e4af60}, {0x000359fc53bdf7be,0x00012726ea080568,0x00075b1726e147ea,0x0001ca2a0207d5e1}, {0x000322cae833e591,0x000e936cba51a14d,0x0000000000000001,0x0000000000000000}}, {{0x000a1d6534e7b937,0x00065ce0948dd2da,0x0002f88e2acca2b5,0x00091e6c94ccb3a4}, {0x000c7d8fe477585d,0x000807f46db59ceb,0x000b940f42378210,0x000e402ecff0fc9e}, {0x0007bc598d173f94,0x000f16af975145bf,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=99 [{1,2,3,..,}]*([2^396]*G) */ + {{{0x000942a4c75e9fe7,0x000c673dad29e115,0x000e6be55a2350de,0x00045659ca3c399f}, {0x0003c87e22652712,0x000bd4c4458f51c6,0x00057db758ae1a11,0x000c547db810319b}, {0x000c8ba847d5c89d,0x000239959a5bbe62,0x0000000000000001,0x0000000000000000}}, {{0x0003d490f3876f02,0x000521482b690e8c,0x00083aada0850d48,0x0004a53582c13331}, {0x0007bae5a342545c,0x0001c50d6f31c146,0x000d97c2d093b815,0x000e82d6fbdb84a7}, {0x00053468edb41ffb,0x0009e6ae0e9fad49,0x0000000000000000,0x0000000000000000}}}, + {{{0x00060773f6c223a7,0x000ee1e8255739aa,0x000672547b158459,0x0000639d3f4e65fb}, {0x000635059b89e003,0x000ffb7b9ac29a4f,0x000cad3267e18233,0x000a7f7d6bbb6854}, {0x000d91b6e79c3b99,0x00065ebec22c4720,0x0000000000000000,0x0000000000000000}}, {{0x0002fbb0f6be8071,0x0006dc307d9b73d7,0x000c6fa2f527f8c4,0x000e537cfbf3d06f}, {0x00018d7888122d62,0x0001ea61a84ebd38,0x0005532479a6f831,0x0004a4bf3325eafa}, {0x000717809c7a3155,0x0000399520a8095a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b807898f2ae67,0x000d7e4f60fc8927,0x000bd2ecac1c97bb,0x00075b365b008578}, {0x000f53b54d53eaaf,0x000e5a0ab86540b6,0x00009c6ac54c1d9c,0x000267e6b65d52d9}, {0x000a061126607ea0,0x00011c0a94e0f97e,0x0000000000000000,0x0000000000000000}}, {{0x000dd52c7077ac64,0x000e6849bb24e97f,0x000e60101c7fc9b8,0x000e52f0dcbe3ce9}, {0x000023c779930c2a,0x00050df58185f016,0x000a6864a7c2cfea,0x000d52f720dc8c89}, {0x0006aecf1e2d3b3f,0x000fe51ac6cabd56,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002f47341f417ba,0x000cd8bb740324e4,0x000e45bfed89909b,0x00089a7fe9550616}, {0x000b7861f9828778,0x0008946a71446a53,0x0006502fbe6cdbfc,0x000f70373dcf7291}, {0x000b59a0e59c8ba5,0x0004ed07606ee31a,0x0000000000000001,0x0000000000000000}}, {{0x0003f237a7cf7e71,0x000f61b5ddd50efa,0x00056f3a63a0f211,0x0004dae68319e664}, {0x00090e5acc6a3312,0x000d6c5fe3f2c7d0,0x0005f435cc8df625,0x000420f4229fa016}, {0x0009c92c95adf8ff,0x000c03d951affc2e,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008e856f1a63237,0x000c38cfb4864e09,0x000a9b6c8ef2a48d,0x000565ee070c9954}, {0x000b247d25c31c3e,0x000d383653eec5d7,0x00033815ac0ce45d,0x0001d40035f31f5f}, {0x00016fd77486c728,0x0002145bbe546eb5,0x0000000000000000,0x0000000000000000}}, {{0x000f8a00f9535f58,0x0006793f432f2f0d,0x000a22b5ed0740ff,0x00046e71ff907935}, {0x0006ed013a6683d4,0x0006c4dc5feeee1f,0x000e49d371167831,0x000c07fabe848ed6}, {0x000dbccd8d710493,0x0003939263e99e29,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009123d0b7caf2a,0x00010c9813e058eb,0x000b14ecd8d170c4,0x000aafb543a445ef}, {0x00066b13251ba12c,0x000a58ee44692c76,0x0009f4193734f736,0x000a0ff39b6d1ecf}, {0x00049d16c582e2c3,0x000a54bc874e11dd,0x0000000000000000,0x0000000000000000}}, {{0x00086c1422f1debe,0x000be6be161bed99,0x00094c11992adb85,0x0007d02a974392b1}, {0x000dc1355dd0b472,0x00001779ff9ef84f,0x0008dc1dbbcd1c30,0x0007615360f70921}, {0x000cd90cece2bff5,0x000a085b2b4772a1,0x0000000000000000,0x0000000000000000}}}, + {{{0x000bac8ffc9b1cbb,0x00041fbeb1c7a5f9,0x00032bb744d70f6e,0x0006377a1f50a7aa}, {0x00008611c61b42a6,0x000ce936f3324a60,0x000a084c3dc201c1,0x0002b70db700c5bc}, {0x000f0caf347988c8,0x00025e2dfe3675fe,0x0000000000000001,0x0000000000000000}}, {{0x000fee427e9f9424,0x00069a165d8d1c76,0x000dc1fbe1e937f2,0x000db180dfee35cc}, {0x000b55475d4c9745,0x00036d0a2fefc6cd,0x000476726ccd4e8b,0x000f3783e580f7ab}, {0x0005d079b31ff3c1,0x00009ced18ab19ce,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000806a0ffa1183,0x000b368c8ad93735,0x00045322006bc207,0x000356cef3feb2a7}, {0x0000d9772041b29b,0x00015326534db436,0x000c3a4ffd400337,0x0004525bb0cb62b4}, {0x0003dfc1aef8cba9,0x00023c5f95e7e7b2,0x0000000000000001,0x0000000000000000}}, {{0x0009f0d5faafe7a7,0x00079f056236883a,0x000e0f2e02fe7ca4,0x00020a75821e669e}, {0x000fc3208dc12d93,0x000c95bd4d2a90f1,0x000127ab836d5d0a,0x0006a56f1f5b0f15}, {0x00053533b35a8c80,0x000e1db5d6ee484b,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=100 [{1,2,3,..,}]*([2^400]*G) */ + {{{0x000b291af321cc48,0x0000d263480c29b1,0x000ec9060276afae,0x000489d0d90afac7}, {0x000ec62d3da37067,0x00088f38b3e31b78,0x0007f35ff5fafe7d,0x0007885361013dfa}, {0x000270f897a6237d,0x000c2a42a2eac980,0x0000000000000000,0x0000000000000000}}, {{0x000b6527c69198d0,0x0008c038b2196095,0x00056c8573aab3e2,0x000c299349dbf002}, {0x0009c016fc238b06,0x000c26c63dc550c5,0x000712822cb43957,0x00044a5765b7d6c8}, {0x0000be87f42f34ea,0x00061a9436ed5036,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006c0f3c9200410,0x000c1523b6d0c7cf,0x000b2a524b701323,0x00080e1d445c4f05}, {0x000cfb721bd24fb2,0x0004d74f5043a450,0x000c3ca459a36903,0x0001f8a997769ed3}, {0x0004569349bd35cd,0x000fa7a1b94559af,0x0000000000000000,0x0000000000000000}}, {{0x000479e9fda50d86,0x00039193e5dd5ac7,0x000fcfc382ffdaf1,0x0006e937727251e2}, {0x000819f976e0e477,0x000e0dea37faf936,0x0002b3218ec38c97,0x00020308bb264566}, {0x000441534d581e3f,0x000046c275dc071a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cb5968e20ed2c,0x000a52702c5bb89b,0x00033f897addfb47,0x000f030ce16c51a7}, {0x000945e8bc092078,0x0000a224a9b9a4c1,0x00074fb0d2a2dbea,0x000a00b01506244c}, {0x000403180ef3b3ed,0x0000d544f09c72f4,0x0000000000000001,0x0000000000000000}}, {{0x0007f0289c261b7e,0x000d803c0211ff4a,0x0001ffe93b188323,0x000b503181a127a4}, {0x000960bd651117de,0x000f238b1565ffd2,0x000706280cef133f,0x0004ddb33d18643d}, {0x00057a46393ccc6e,0x00011d1fcc4678c9,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cb18067eb6c9c,0x000904e0e232321c,0x000c2c362eb5eae4,0x0004f20ada675b34}, {0x0009513d2fa912c1,0x000c8c7ff960f4ae,0x000ea3278df20646,0x0004b702cc146790}, {0x000b87bb57608da3,0x000f1fadae0fb9e2,0x0000000000000001,0x0000000000000000}}, {{0x0006a843b0ca7a84,0x000ffac89f77d5a2,0x000265d14c35a368,0x000486e7957c89a9}, {0x000f9514b7e05bd1,0x00037cf3d5a9030e,0x0002008b9ea39985,0x00050c45cfba4fb3}, {0x0008d5a1561ff956,0x000bc01cc6a56407,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005bb52ea9ac7ec,0x000e28f7ce0ec366,0x0004c059fd569d2f,0x0000e89276b354dc}, {0x00013674b639e129,0x00051c92206d8283,0x0005fd8d62852509,0x00083a0ba16eee81}, {0x00023ff408ee3851,0x000e736678fced53,0x0000000000000001,0x0000000000000000}}, {{0x000a8b28dba67d24,0x000216ba84ecb673,0x00034998afbbd048,0x0004e06cfb264967}, {0x00064c024c958fcd,0x000c3e07fdd668c7,0x000e902ee5004559,0x000c7be484240ea9}, {0x00085d1cbdf78504,0x00001fc315ffe9b1,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003f67e6d554604,0x000a7edbdf25d6db,0x0004a86faf823503,0x000561d458cbd82a}, {0x000fd50ad1fb2727,0x000d57e2f00994b8,0x0006a571b2b47251,0x00025dcba3cd1573}, {0x0003351634df5819,0x000f90f716e579ec,0x0000000000000001,0x0000000000000000}}, {{0x00015c741fd15e62,0x000782e4509eb436,0x000bb1dede8ef754,0x000e32d87a793f6d}, {0x000cb27d972fea02,0x0000af4ace00b65e,0x000665980ede0c9d,0x000f6c809dcb9681}, {0x0003f6f1f979a653,0x000fa70638c8e694,0x0000000000000001,0x0000000000000000}}}, + {{{0x00069573569a82f9,0x00074c79907894c3,0x000923a4f546a942,0x0003c148a698895f}, {0x000c357afe3d1621,0x0000597be114eca3,0x0008bde57638ac14,0x000ab1f30c4d2325}, {0x000c1e648b9d09ce,0x000b5b544e3974e2,0x0000000000000000,0x0000000000000000}}, {{0x000a45f392d296b8,0x0008740111ad4028,0x000c3e262fdbe28f,0x000c3453830a9ee4}, {0x000ae0fdaa4f4e3c,0x000db8b9c8044def,0x000827b06665f64c,0x0004b0bfa5e94a06}, {0x000288ab3926f336,0x00095cd9d3c3ecaf,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b181f2f210670,0x0009ac047db30c5e,0x000f0b9977abb73f,0x000685fec5355db3}, {0x000cba356655da26,0x00050bb7fd48c1a2,0x000094ac2c2dc459,0x0002437ff8a8e766}, {0x00026425d80146ca,0x000d215b7aafe50b,0x0000000000000001,0x0000000000000000}}, {{0x0008a54b77260e44,0x000200683c3c461c,0x000806c758fee244,0x000ee02fb90af5d8}, {0x0005167ac6f6571d,0x000f1dfed253aeab,0x00051fc762d73380,0x000f059d556559bf}, {0x0001430491432973,0x00077ebf133e93a9,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=101 [{1,2,3,..,}]*([2^404]*G) */ + {{{0x0002ff226442343f,0x000cd833f176501e,0x00095759918597f6,0x0008de415f1a7fb7}, {0x000e4316d41dcb51,0x00029d89c6966644,0x000513d7775eaca8,0x000a9d45da4eed7a}, {0x0002852aadd14ef8,0x00062ec016fff623,0x0000000000000001,0x0000000000000000}}, {{0x00091f95c7b230dd,0x000a732cc46d0d07,0x00004775f23d4641,0x000d9d15b9dcdfdd}, {0x0007a727ace99c9b,0x00077fe3e5aec6f6,0x00023beeac1ee2fa,0x00008f21d63275b9}, {0x00065885355852cf,0x000ce1be6d4550b6,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006e321251c61dc,0x0002560a1fff242c,0x000a45d55894b5a6,0x000bc8f1bc1ece0d}, {0x00099655945af852,0x00081d51a6f4152e,0x00048184573b7d9f,0x000f69e42e8015c7}, {0x000b2c20669dba53,0x000e9f9624512355,0x0000000000000000,0x0000000000000000}}, {{0x000c96019553b866,0x000abe8a5146d011,0x0006c8e83c7c8d9f,0x000d33f93fede45c}, {0x0006fb87d2fad3d5,0x0007a48456e1fe30,0x000e6e9f030c2436,0x000ab8f59e2c2aa7}, {0x000e2ecee8097392,0x000ce7dbed7e8f7a,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009869c0eb3066b,0x000607798fe984da,0x000507796822415b,0x000b35e4cf4e7bb0}, {0x00043514e2eac3dd,0x0006f5f2ec73d5e0,0x00073c55dac4fc5a,0x00009ae9d9b66b29}, {0x000e7849157dbfd1,0x000a5482a9437d4b,0x0000000000000001,0x0000000000000000}}, {{0x000c4e943ae95512,0x0006cf652253cdb5,0x000d6ec12d70a741,0x000569eacfb8355d}, {0x000eedc557ace0f2,0x00079ed65a726737,0x000cbaa427929f79,0x000f9f7b12d69985}, {0x000f61768135719d,0x000ae5a402492b60,0x0000000000000001,0x0000000000000000}}}, + {{{0x000feaf2d1e3892c,0x000ab68c7ed96e8e,0x0003cb959b9f3e2f,0x000c2e34fe65989c}, {0x00089b397dfd24ce,0x0005a4f7a72a8210,0x0003d4d194fcfc29,0x0004009eac36cd18}, {0x0004df54ac2005f3,0x00037ac4355ce338,0x0000000000000000,0x0000000000000000}}, {{0x00018f15a5288002,0x00084aab158f0c62,0x000919d3c1cc9db6,0x000c654f22157c5c}, {0x00061a5d7e7c5733,0x000dc89cd41bb67f,0x00046690cac1f786,0x000f2b55f183f6e7}, {0x000f41e4cb445fa4,0x0005a969c4dd429d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f3df64800b6f3,0x000d7480b73133bc,0x000b600425660d57,0x000b837e3aef4df6}, {0x0005fb5d2c2dd02d,0x00011fe018b03d5a,0x000c71322317085a,0x000d374ad3a452d3}, {0x000a4d81aa830346,0x0004a3299709ce7b,0x0000000000000001,0x0000000000000000}}, {{0x00016776ed8701be,0x0009a6af0a211f00,0x000ee5799e2d0b99,0x0004ffaa89dc73ac}, {0x0005974371ca9e1e,0x000e0cc77bcb98c1,0x000c6b4ceea4b327,0x000a8308bd6b7617}, {0x000c8a4f2fabfb14,0x0006930491f45b7a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d9bdcbcf79471,0x00074d3dd4ca53d8,0x0001af7d8d51306c,0x000b82f03e680d58}, {0x000a7884ca0be9c6,0x000c62e3720aacdb,0x000ad9ad633f5955,0x0000c84d067a1c4c}, {0x000e24eee54e3c55,0x00019dbe3f67b54f,0x0000000000000001,0x0000000000000000}}, {{0x00099b839c026b9e,0x000bc7d75cb7b6b9,0x0005e6b4aa8a5275,0x000156cdfaa9f40a}, {0x0004a1992d1c2e6b,0x000b18092816e51f,0x00027a900c94afd0,0x00010f9d0fb16b34}, {0x0008f98b409eefa5,0x000aaed3cae46309,0x0000000000000001,0x0000000000000000}}}, + {{{0x00060d5e996dc11b,0x000619082845b56f,0x0006ef36f7ab0ecb,0x000d028f81fdfa6c}, {0x000060da295844af,0x0009596e31cc9ebb,0x000308c32eb79211,0x0001ea951754105b}, {0x00008750f063690e,0x00083b8a021ee964,0x0000000000000001,0x0000000000000000}}, {{0x000d813e43ebc1f3,0x000af78ecca7ac06,0x000d8eb52a4c2d59,0x00067d3099d75877}, {0x0005b00d48668cb3,0x0002755481aaf570,0x0000b8ddd277a751,0x000dd4573c6cfa3c}, {0x00075e83624bf68a,0x000ee89ee03e9ce2,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001adc31d17fe65,0x000ba5bb3a93b688,0x000b603dd9e8ce1c,0x0008b0cf4f5b70c1}, {0x000175f958dd3aed,0x00070f44e15eae25,0x000177aa5b942f5b,0x000302efb949c526}, {0x0002ba3a2c8dd115,0x000b89f9288a9513,0x0000000000000001,0x0000000000000000}}, {{0x0005972ebede20db,0x0005b1bc841aedc4,0x000933a99b87853d,0x000597276e1536aa}, {0x000a0238abf3c852,0x000485ab1105488f,0x0006d521debe07d8,0x0002f1ad18f16d6f}, {0x000d3c55a54637f9,0x000804a2b58773df,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=102 [{1,2,3,..,}]*([2^408]*G) */ + {{{0x00085142795b0fc9,0x00032b75a8973a1f,0x000125d27c2f65e5,0x000245efb7e6ca7e}, {0x000a3d37a1c1d680,0x0008ed8871c0ac3f,0x000f92273ed1f61c,0x000f1c0619b125a3}, {0x000c151e1baaf99b,0x000b5fb9c92ca12f,0x0000000000000001,0x0000000000000000}}, {{0x000d45f1302c2800,0x00028a46eca65c4c,0x000181d940c2f16b,0x00008156dae561c3}, {0x000ffdb51b5dbdef,0x0007d0f3f05aff9f,0x000216756731470d,0x000d3e4323b09f64}, {0x000c256f1c5c736f,0x000c46af757ebac2,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008b99d3a5cf086,0x000a6f7dad9f189d,0x0009613956296f2e,0x00029ebaf5d410b4}, {0x000d4c6b1f46d86c,0x0001709ad92dbba6,0x0000cc09de07504b,0x0006c7c9ec95eea8}, {0x00007648647d01eb,0x000b3919b1d6cd99,0x0000000000000000,0x0000000000000000}}, {{0x0005f9f34e61ba7e,0x000eff53cc24a00a,0x000672781ea5e367,0x0005266f275cfce0}, {0x0009992d98139edc,0x0002c0efd50d9e20,0x000de18f3d9cb26c,0x000b647d23fe687b}, {0x00054a71ad97b9cc,0x00027a258eaff20c,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008f39dfcb8ed4b,0x000811922f1fcd37,0x000a2846f7edab95,0x000566857a64449b}, {0x0005d6755b91a9b1,0x00033e748b542e81,0x00055f4eecb18a57,0x0006c4663a3a4f59}, {0x00052acaf4bb5b32,0x00079a0d2cfa0bdf,0x0000000000000001,0x0000000000000000}}, {{0x000a0b89e0ca131f,0x000be75df1d52db6,0x000534480e6cb8fa,0x000be7af1d438291}, {0x000ad1a493673eca,0x000a16c7e34998f0,0x000d3ab56804db13,0x000479fc142bd461}, {0x000daa988aca4c3a,0x0001acd3bd93e84a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cbad8f99ea394,0x000cf3fa23022a30,0x0009f3a186b0f3c6,0x000e922b33420e3c}, {0x000c1bffbbdb1dc6,0x000aa59cdeeac227,0x0003dd943d5b8787,0x0005513a5be5e367}, {0x0004c0fefae77a5b,0x0003518e4c10fcbc,0x0000000000000000,0x0000000000000000}}, {{0x00024505728229a8,0x00014b020fe0ed2a,0x00039e8625b5e8e9,0x000ac893dbd2dbf4}, {0x0002a5bf5b95c3df,0x0009c6d879c2cfde,0x000a75fca30a3152,0x000f3ac05ce905a9}, {0x000445553894b84c,0x000dc2eb87696cb5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c1e6489e4e3ff,0x000e40fadb280ee1,0x0009bea8383ad81c,0x000e1b3d235f576b}, {0x000a3198405d1a52,0x00058352c1e2f66a,0x0004288cd9077fa6,0x000dbd50c9d00a90}, {0x0009bd9a7d893793,0x000b363fd16ecce4,0x0000000000000001,0x0000000000000000}}, {{0x00020eac52973702,0x0003e0c70e76207c,0x00006b2a996d0f74,0x000f4f6a44bb0744}, {0x000df28bc6807b4d,0x00017b088a4a4664,0x000ec1355d57eb8f,0x000182cf9ce6cfbc}, {0x000610a314e418de,0x00010173ffff5e3f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000165051d386e1e,0x000bd47b826f3a9b,0x000a1c2b86d2360d,0x0009b8835ea5cf34}, {0x0009783bb9260611,0x0002b789b3e982a5,0x000e987100210011,0x00097fc2b9ab3e6b}, {0x000ba0e81d76b916,0x0007fbcd1d8d4518,0x0000000000000000,0x0000000000000000}}, {{0x00091e776c559b38,0x0004c1e4fe7c517d,0x0006b3ca068cf1e7,0x0001a6fbc371e38f}, {0x0003b1539a3d7c5a,0x000cd0c3d50e8468,0x000c7e40ea4660b7,0x00012b9d873faeb0}, {0x0007f3ea3f2ff663,0x000c8c52e58fcf13,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e0d1c0e7b0a6e,0x000182d5a79223c1,0x0002d07160d41c08,0x000de95d46cca38e}, {0x0004d00dd9df759c,0x0001f3ff3dc94e0c,0x000ad18e4b33fc34,0x000d2cfdbdfdd807}, {0x000c70a120714770,0x0005cb86265c3704,0x0000000000000001,0x0000000000000000}}, {{0x0002e095e7588e93,0x000bb0fc7a7538c8,0x00049b1bf8ce184d,0x0006eac46bad884f}, {0x000da577205521af,0x00073592b9bc40d1,0x000dae6302c8fae5,0x000e9a408dc07f7a}, {0x000d86c203a973c3,0x000db4c1145f0edb,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b134fd6bc3c71,0x00030305a92256f9,0x0007ccfce0b23245,0x000ca36a6d8cb621}, {0x000236d0ef54fd61,0x000a182b1b210c1e,0x000e2c48ae4f2531,0x000aa16671b7b1f2}, {0x0001cf556d29f38d,0x0001c83fa6c8eaae,0x0000000000000000,0x0000000000000000}}, {{0x000a18df67396e49,0x000978a098406db9,0x000d15a5ed3d588a,0x0008786d781ea818}, {0x000c4ad06fce15e6,0x0006d7a550f98680,0x0004140981589bd6,0x000f7ff83976d3ff}, {0x00088eabc6ffe6df,0x00031647479f189c,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=103 [{1,2,3,..,}]*([2^412]*G) */ + {{{0x0000d7e3378fb507,0x000c9bb0731c42eb,0x0005dc372a3657ba,0x00074ab3d967282a}, {0x00057f9ac8856a93,0x000b740967bdf210,0x0003024fec8274b3,0x00015596459a5693}, {0x000d21c1794a1687,0x000a98ef7bcfc7c8,0x0000000000000000,0x0000000000000000}}, {{0x000af7b9ab0a89f0,0x000a24bfd8b660f9,0x0009cb13ed97b728,0x0000fd15ee5e0227}, {0x000febd3b7d28a45,0x000367bf5b972ff1,0x00091b608f71ea2f,0x000f496276edaa41}, {0x000a6a4c152d016b,0x0000bf52e7daddc4,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ed176dc4c781a,0x000f2149979e6d8c,0x000b3c390a71d8f2,0x0009ec42d1cc9018}, {0x00013805d407dff4,0x00092c79f656592d,0x000250a69b4fae8b,0x0009ea40b75d7816}, {0x000e49fbb9c23c18,0x000630012080c698,0x0000000000000001,0x0000000000000000}}, {{0x000297ec2f3d27ef,0x0009b4394adc76de,0x000084a2dca39d2e,0x0004162fa4a3c98c}, {0x000de4df52d9fff5,0x0006af6c27847a48,0x00049729a4d9dcca,0x000b96ed3609128a}, {0x0002001168323c41,0x00051e81fed2290a,0x0000000000000000,0x0000000000000000}}}, + {{{0x00023ceeaf6fda5e,0x000fb751aba8d27a,0x00058878762241c7,0x0009d28160069d96}, {0x0001830ade2dd51c,0x0001c3eb509b6317,0x000cb86f909879a9,0x000dee7eb48aca8d}, {0x00028bf799244bc3,0x0009202a06470538,0x0000000000000000,0x0000000000000000}}, {{0x00015f7fc2843df9,0x0002f53ba48f85a0,0x00095ae129c2b6a1,0x000ddb2a444e10a6}, {0x0006aecfba54d8ae,0x0007c39b4f0e8bdf,0x000e6010a72c4d1c,0x000d5cdfd0f373b3}, {0x00068c9e099b50a0,0x0001c8bed1929d51,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c2c46683ba5b5,0x00057c57128a2090,0x000dbf610a813452,0x000009fdd16c4a33}, {0x000c78f1d5b65bff,0x000560ad02b49af8,0x000ea450eb8499df,0x0003a52dc630fb45}, {0x000da8ac57e35202,0x000fb72fd6cb3d8a,0x0000000000000001,0x0000000000000000}}, {{0x0006d77839d10202,0x000f1f4a52a42a8f,0x0004175b2fd3f44a,0x000ac14905fe7f14}, {0x000701757d0c0079,0x0008ae6d1c475fac,0x000d56b7bfd93878,0x0001b7dbf13b33f3}, {0x000d1df20cacad13,0x0006098aef62c8eb,0x0000000000000000,0x0000000000000000}}}, + {{{0x000224c02776a096,0x000fdf0428bd2668,0x000824486a9c4320,0x0009f3de8bb8cb98}, {0x00008a99c85515ad,0x00087cd9c5ea0fc3,0x00030bd0c213cb33,0x00075f7ddf36e0e9}, {0x0008b09a16a3e9e2,0x000ff92ba0c69ed0,0x0000000000000001,0x0000000000000000}}, {{0x000dd8b8dacd787a,0x00044526b1b4ed23,0x000c4fcde2872824,0x000a0aecc5884baf}, {0x0000edf7e8ded34b,0x000a4bc010f4ef7d,0x0007a006485cbfe6,0x000ba70311a2f225}, {0x00032199cd733758,0x000ee0992d474968,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d4dc4b29d1e7e,0x000ced039d3b8a01,0x000815590ff2c2bd,0x00021d5655ef3773}, {0x0006fddb06996f34,0x0006f2915cab4832,0x0005a14903f506e5,0x0004bd51fa3522da}, {0x0009df3d4ada1113,0x00041c2c8aabe985,0x0000000000000001,0x0000000000000000}}, {{0x000708b80fba1a02,0x00028b6a0afd8d60,0x00058773df43d0b1,0x000ecec358a258ce}, {0x0008b0ae7440af59,0x0000e74789fcab99,0x0007429cf7b8fd56,0x000584c72e545e3c}, {0x0001897264b148aa,0x000a07b9a2d9b131,0x0000000000000000,0x0000000000000000}}}, + {{{0x000edce9ca1286ed,0x000ff3a46b7fad16,0x000535c9d7d2b840,0x0003708d5ca958c2}, {0x0005420c1e063332,0x000713a6fa0fa9a8,0x000918405a51ff70,0x000da85f855da776}, {0x000d1bea73da5e0f,0x00064183a6508fa4,0x0000000000000001,0x0000000000000000}}, {{0x00083d4f23ca730b,0x000725501529af4b,0x0008000d1b6d21a0,0x000a7b3eee3507cb}, {0x00022a88a07a33b4,0x000540f9d09c28e9,0x0004983b28faa40e,0x000f54edb432d0fc}, {0x000ce23569311803,0x000d266759b9bb64,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fd03e2a0c4500,0x000d5cf3f782f796,0x0003ffeae620bf4a,0x000ca0158514f603}, {0x000545633e085e39,0x0004884fbea88f4e,0x000882a85fc77f29,0x00012678c646f605}, {0x0009ba323a505f9b,0x00029223217b4379,0x0000000000000000,0x0000000000000000}}, {{0x0002e8744f4170bf,0x00081a29194f6c03,0x000a932a7916cab1,0x000fb0f9f60ec063}, {0x000ff217a0ff0b94,0x00003ea56b8f066a,0x000ed4a56ee8b26d,0x0005efbf8ce2c1ff}, {0x0002eb114ed13051,0x00043d7447433992,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=104 [{1,2,3,..,}]*([2^416]*G) */ + {{{0x000affb50d183763,0x000c1c5fc7f37a88,0x000a1f73a2f170a0,0x0001192983474ff9}, {0x0006b4738ed4fea8,0x0004d293dcdd7868,0x0000cd916188a232,0x000bc585fd523667}, {0x000b67188a2e54db,0x0008ed10b37344d3,0x0000000000000000,0x0000000000000000}}, {{0x000548b086336003,0x000991fbe0b348b4,0x000ef3cdca5ad120,0x000cfcd2034c9a59}, {0x0004f56699960d16,0x0006df1f5f10f252,0x00000324733c5f1f,0x000a757f84ed98a5}, {0x0002f7eec2ce4fa9,0x000ae3d296f3ba03,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004e9382b32007c,0x000d81cd77eae7c3,0x00013604a2dad7f0,0x00043d13d0e3fde5}, {0x0004c6cb59871704,0x000a8441d1c5f3e6,0x0002361adfd909c7,0x0004efba78610053}, {0x0001559070eb9abb,0x000708ee4fe6fb05,0x0000000000000001,0x0000000000000000}}, {{0x00079200ca4f6cc8,0x000579128ad5ec75,0x000c265973749006,0x000f0a7f8cf2fa39}, {0x0002ddb548c37c9d,0x000da31069648b65,0x0006a7e075eeef13,0x000504d0e4093491}, {0x000fd613bea6b782,0x00055bba92eb2c08,0x0000000000000001,0x0000000000000000}}}, + {{{0x0005ab4da4a4107d,0x000f0dbf85411a8b,0x000a933992a7b991,0x0000accdce47a748}, {0x000c5662f2eb8c82,0x00064b5fdd12508c,0x000db73adddfe6b9,0x000af97a44a31358}, {0x00044c5ddfefeaca,0x0003403a084f6ff5,0x0000000000000000,0x0000000000000000}}, {{0x000ad406fec21428,0x000e8954cddbeba4,0x00092a7fe19ec844,0x00084bffa4c49f5f}, {0x000ec8eb76b96304,0x00014948f0f75a70,0x000dff2c139503c4,0x00032fdf031b7606}, {0x000fa11a5ead6208,0x00047ef7a1eba7c5,0x0000000000000001,0x0000000000000000}}}, + {{{0x00073a3dabdb3534,0x0006dd5d8f611c69,0x000799bf33f3f4e8,0x00026f63749fb625}, {0x00092667bd3584a3,0x00060fa9fea81613,0x000999ea3a8de550,0x0004dd75d71ac4af}, {0x00078319418b1e64,0x000c67e995c857c8,0x0000000000000000,0x0000000000000000}}, {{0x000c7afa552eb541,0x000a7222bb4a0732,0x000c7e0e1a608c59,0x00009057e1132506}, {0x0009c5c6a19981fa,0x00019205096b7bf3,0x000a7d38ab7490c4,0x00099e016ba7462b}, {0x00007f474dc3595d,0x0006636a3d8c9f12,0x0000000000000001,0x0000000000000000}}}, + {{{0x000058d88f35f241,0x000a59b2e8d2532f,0x00015502597aca02,0x000fb1e8bd7d1caf}, {0x00055680e361da0d,0x000ed31cfd9355f1,0x00047c0b0064d2b2,0x0004f348830f3080}, {0x000b7440fbffaf7d,0x000a5a553b98e17b,0x0000000000000001,0x0000000000000000}}, {{0x0000f6eacb637570,0x000d4925881bc39f,0x000d655e7e9a7105,0x0002f09a033db883}, {0x000e97d5a4975dc8,0x000036e619a17847,0x00079d0e9b209304,0x000434fdadf80484}, {0x000412216e6c7daa,0x0000eb152f330b19,0x0000000000000001,0x0000000000000000}}}, + {{{0x000362cca8e2db27,0x000b58fb4260cc2d,0x000e2d527b899614,0x0001f0b467cb8aa3}, {0x000d1ef71b82f08c,0x000dc68072c4649a,0x00098aa11a9313c4,0x000165002fbe1ac2}, {0x0000bf5399f23796,0x00024b537dfdd6e9,0x0000000000000001,0x0000000000000000}}, {{0x000f6c830ade2b53,0x00074af2e76469fc,0x00051f1bc5f4ed41,0x0000406c3a450f7e}, {0x00002b53708a683c,0x000428a6e3aa7dce,0x000c0df44b377b62,0x000e9c1a58f5f1ab}, {0x000c5458b0f02c35,0x000b16ea8718da27,0x0000000000000000,0x0000000000000000}}}, + {{{0x000134d37c05c59c,0x0007233d57586878,0x0006cf5af7409f53,0x0008ae6dfc4fd018}, {0x000e8b54df4cc39a,0x0005f3046db1d402,0x000312aeece717b2,0x000da13a0c5d98af}, {0x00073d6305f96c47,0x000587c80a3e3a7f,0x0000000000000001,0x0000000000000000}}, {{0x00027d5a2516f5d0,0x000f9338bbf8fa7f,0x0002109c7d0c4360,0x0006004be57b26a1}, {0x000da32aad5aeeea,0x00041aa5daf9dede,0x000b0a16abc83073,0x000088080bdafdd6}, {0x0004fa8814cecd6e,0x000f5f24b2b7fe1d,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cc19d6d74494a,0x0009296d31ebaa05,0x0003edd43b02f30e,0x000c79aac72cbbb4}, {0x000d57829df3e827,0x0008bb62624e4cf8,0x0004f05ffe745fb9,0x000950b350aaad89}, {0x000ea5e2db566ef1,0x000e1e37f6dcf4f2,0x0000000000000001,0x0000000000000000}}, {{0x00034202ee7f3c59,0x000ed5d748da48fa,0x000e1cf505b68fd9,0x00031b86c7778cb3}, {0x000dbdadb45073af,0x0004b6e80bfe717f,0x0001ee413036b30b,0x0003482b138b2c3f}, {0x000e1ed1e4fc0159,0x000e84d788bd2771,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=105 [{1,2,3,..,}]*([2^420]*G) */ + {{{0x0009afb73836ce2c,0x00035d1c0854627d,0x000acf6649f2eb9d,0x000acf4c38a8a9ec}, {0x0002178be52c0095,0x0008f6e06df7d7ea,0x0008285115ce7bb4,0x000b7f232680bedc}, {0x0004103a6e51e8f4,0x000aaa09aa0bc0d2,0x0000000000000001,0x0000000000000000}}, {{0x0001c4bc539f42b1,0x0009f1f757159ce1,0x0000e9e10c0bc8d0,0x0007345be3621884}, {0x000d1822e5e0a60d,0x000ae792acddc802,0x0006be0f49763d76,0x000dff0f1717868a}, {0x0004437867cae1bc,0x00070e8bfe19f269,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001b8994b02326b,0x00031ce496416ae0,0x000dc0825cea213f,0x00050bdf0281aa93}, {0x00059236853f9e44,0x00041e294dc8c09e,0x000b03a595c72a58,0x000c2bc6e5381e14}, {0x00020b03546b3008,0x0008eca57d1874ef,0x0000000000000000,0x0000000000000000}}, {{0x00051a61ce5948af,0x000925d36a169359,0x0001712f7655b84b,0x0002f3fdc1e05016}, {0x0009aa758020ba42,0x0006927405b02281,0x0009822fced2aa8b,0x00019ae63d9313a7}, {0x000d9c07887cbebb,0x00065e13e45febcd,0x0000000000000001,0x0000000000000000}}}, + {{{0x00034f1f7e499842,0x000a48878049fec4,0x000692a3fe1f0c9c,0x00048261277fbbb0}, {0x00032263dc0fe7ad,0x000e09052ac6fec0,0x000683804d38aeb7,0x000d6c55fb1237fd}, {0x000bce4b453925e9,0x00056ac33e2d8263,0x0000000000000000,0x0000000000000000}}, {{0x000a764c5c6d3730,0x000ed9705b2adb70,0x0003bab4631b9f1b,0x00014535b4850149}, {0x0009c2385e82937a,0x0007aa5ebdcd9ea7,0x000656517e5b5eb0,0x00078fb6885fd321}, {0x00087f791c6b2bd8,0x000bcad44bfcfcce,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a7c1bbda99502,0x000d13ad86ee95d4,0x0001edd6edef741f,0x0001221485b8fada}, {0x00062b65b3c0a089,0x000583aac0300922,0x000ec2e6716727e3,0x0006d6729d8a817e}, {0x0002ad34233bfe29,0x000806779921dca9,0x0000000000000000,0x0000000000000000}}, {{0x000373f0b0bc37c3,0x0006835632a2bfc1,0x000a8cd4f472c2b1,0x0004b6c9a4cedeb1}, {0x00076180690c132a,0x000eca05f9fa510c,0x0004e0551eb02c41,0x000e63213fc52e0f}, {0x0001b429bb6165cd,0x0002bc1fdd188cd9,0x0000000000000000,0x0000000000000000}}}, + {{{0x000629f7658d599b,0x000b1e87d39d0d52,0x000caaa997607dbd,0x000fcf23eb7d6dd2}, {0x000857e0cd30a02f,0x0003ecd22778d510,0x0005c5e961e1f158,0x00068aa70a145465}, {0x000c8fb1ff96ec7c,0x0009b464d2f55e62,0x0000000000000001,0x0000000000000000}}, {{0x000e904d20ac7941,0x000e4f0bec2602b6,0x00080f6effaef59a,0x00060688330793e6}, {0x000db2442ae08549,0x0005e3d773ff5a5f,0x000cecbc6ac0199c,0x00012fa7a795cacf}, {0x000d6f9bfc57e52d,0x000ce32e4eaeafdf,0x0000000000000000,0x0000000000000000}}}, + {{{0x000eeeccbba2a7d7,0x000ad1d77ed0ffef,0x0005e752d769db74,0x00015b240b6200a7}, {0x000597b48ab8cfc3,0x000f97504538ef48,0x0005a2e980da41b6,0x000c0010c2010969}, {0x0007fe53f0d2b23a,0x000a1efe8b48887b,0x0000000000000001,0x0000000000000000}}, {{0x0007b952e8dd021c,0x00026e6b8cb163c9,0x000d62feeed16bdd,0x0007e3db6129cfd5}, {0x0009dcfa4489e9be,0x000f551707d804ec,0x00012a2adb1fbcf8,0x000c05be22830553}, {0x000c9f74b7d87937,0x0008d7e5edd3be33,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004b2f4546a8f7e,0x000d2a223a807885,0x000155358a6954ae,0x00086e4b30349ae5}, {0x000a5982c7a2aae1,0x0006ca4f6415564a,0x000013abb73fd2e2,0x00092d10cb063fca}, {0x0006104963b01aea,0x000bbcd0f1f68f33,0x0000000000000000,0x0000000000000000}}, {{0x00069aedbf43f1a2,0x000ebe1ef2c9b47f,0x0003246ee727e6d3,0x0003f5bd1a5a6120}, {0x000987e829b05fc2,0x000b70444c023806,0x000f0d6e903fa23f,0x000baba52743b14c}, {0x0009994d97e9872d,0x000a52cbf74f834a,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007ea3240feb8cc,0x000792ae77094407,0x0001201418e13db8,0x0003920cbc07e7f8}, {0x000aed56c93837f4,0x00013ae3d2a87da3,0x00044b8ddc44f1df,0x00069328fcaa2209}, {0x000b928d8e381964,0x0007313e55f26bee,0x0000000000000001,0x0000000000000000}}, {{0x000ec4f451bd8008,0x0007bdfe195b7e42,0x000e12b70e68b680,0x000159222b99f5fa}, {0x0000c4e0659127ea,0x000efe86909b5076,0x0008c58b9b667112,0x00047b7026cf16a3}, {0x0007373740ea01a9,0x0000153963989580,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=106 [{1,2,3,..,}]*([2^424]*G) */ + {{{0x000546c7f70bcb2f,0x0007212027084052,0x00013f0d6d83c3eb,0x000eaca7142e7b62}, {0x00029f973a763019,0x000be00c2a025efc,0x0003eca6f6199ab8,0x0002b5618bcc0394}, {0x000b02749fbfb9ab,0x00013c0ae9ab795f,0x0000000000000001,0x0000000000000000}}, {{0x000f295b93c3d712,0x000bf1ab6d0e9f50,0x000bf53d7cb083d8,0x000d744e07076abe}, {0x0005a51a53561f29,0x000d647b915c2fc1,0x0009ead253f84287,0x000e91bd9d6251a2}, {0x00006dd74006b7bc,0x000c92c770e4efe1,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002703ae4d5c812,0x000427e95afaa341,0x000271961d1eb61e,0x0000fb71509a4412}, {0x0007bef04644ecf6,0x00044d4556d64abf,0x0002a7bfd03e651f,0x00094add4bdd9b05}, {0x000438d74bb2156b,0x000fa36c6c16572a,0x0000000000000001,0x0000000000000000}}, {{0x000ae16f96be2911,0x000d52afa2d73a0e,0x0005bc81a5a44951,0x0000fc89324d90b4}, {0x00018cab36337849,0x000cb411d87db838,0x00021f7d6cb710ad,0x0006ad26521480af}, {0x00094a666f370ca0,0x000375d8bc966e31,0x0000000000000000,0x0000000000000000}}}, + {{{0x00082baa7d62ed15,0x000a2a0c35293a3e,0x00068a91eba6b63e,0x000715c2cd81a65b}, {0x000ed39839d20270,0x0001cd1c736c49a2,0x00023b8eae3fee67,0x000006012e0a11a6}, {0x0006b901f0657746,0x0003944e0864a739,0x0000000000000000,0x0000000000000000}}, {{0x00089e4689d04d8a,0x00060efa98dca953,0x000708ea3f1bf018,0x000f379e0740bbd3}, {0x000ab07cf1111586,0x00040f6bae4389cc,0x000c0c62ec14d78f,0x000a8ca2edc050cd}, {0x000eb9e22353ae3b,0x000221497d609a22,0x0000000000000000,0x0000000000000000}}}, + {{{0x000dc15d0ed0cc63,0x0001ce35b540e1bb,0x000973de7aa979e9,0x0005e965745fa684}, {0x0008a999e957c84d,0x00071ead702675f7,0x0002beeec63eb2b6,0x00062262a9349f4e}, {0x0005b027fa151a2d,0x0005b45a63374388,0x0000000000000000,0x0000000000000000}}, {{0x000ade9fdcbfe121,0x00019964a13f4063,0x000ea6e576b23957,0x0009fa2021e1e294}, {0x000f93e8e8d0c1a3,0x000627a8aaeb1db8,0x0001c83a239f73f2,0x0009dc2704f34ba1}, {0x00053062be1591a1,0x0004c975cd21326d,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006b8fb25e6414b,0x0003f3c35210ef6c,0x000fcf4305218c66,0x00044c1aba52d092}, {0x000ad9ddbd46b892,0x000a630015bf7459,0x000b32b246737751,0x000ced081a65d447}, {0x0002e2e5f643a94b,0x00044927f131866d,0x0000000000000001,0x0000000000000000}}, {{0x0004645014a53592,0x0009ee4e5661d1ca,0x0009024d9b573293,0x000159f5f55c84df}, {0x000a0100b8c24f2c,0x0002de6a0aef0178,0x0009e7eedb7e96ff,0x0002067fc1f195df}, {0x000897eb377d8a42,0x000f1229a3daed81,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005287cf2f5961b,0x000cef9beb6f8461,0x000a7eaedc75201f,0x000d39dfabd8969f}, {0x0004252116284485,0x0002945b419a298f,0x0000f03b98d985bc,0x0007be292f990254}, {0x0007d1f59fb5c829,0x00002d379bfc2592,0x0000000000000000,0x0000000000000000}}, {{0x0001179af2527211,0x000f2724128932bd,0x000920719e949c7f,0x000f184c1ce441c4}, {0x00091d4d77a7c7bd,0x00086d6826d00ec0,0x000125b3901be8d2,0x000c6d7da5fd8de5}, {0x00084f0587b71c09,0x000ecbd13d8a200a,0x0000000000000001,0x0000000000000000}}}, + {{{0x00034258888b309d,0x000da5700df117ec,0x000eecc1e03d3856,0x000d69afef5df311}, {0x000ced3bd1e65823,0x0009ca00a3d94409,0x00053de41e7eb569,0x00002f1291722236}, {0x000dbd2ee0ded7b4,0x000a909f40f6e980,0x0000000000000001,0x0000000000000000}}, {{0x00082d95c76e2f3a,0x0006d18779f8f974,0x000021eeb4e7e5b3,0x00070089298e7654}, {0x00003aa90b7f11d4,0x00020fd2c120d0de,0x000ddfdcf3b2e6f9,0x000134293b957e6e}, {0x000d5361a94456e0,0x0004bc62d97be2a1,0x0000000000000000,0x0000000000000000}}}, + {{{0x00047691dfe1ac32,0x00095bb25141cf40,0x000cb8b02c59109a,0x000eb57046b0d286}, {0x000a8b7de816343c,0x000109a4f745b33c,0x000bf34e4de2617d,0x000950869270fe1e}, {0x000a3a1b01ca6170,0x00012e38634a9ad0,0x0000000000000001,0x0000000000000000}}, {{0x000f079109fbe1e8,0x00071bce15260c38,0x00059aca1efc1bab,0x0006c7ad5da68584}, {0x000030bec54d9816,0x0009a9c32e8f4612,0x0001154d88a51704,0x000ebe8180a7efea}, {0x00008abc6ec5ede1,0x000d7de0d26459ad,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=107 [{1,2,3,..,}]*([2^428]*G) */ + {{{0x000019394140932c,0x0009a362bec3a200,0x0005ab884c7a2c57,0x000cab2ba06cf4c6}, {0x0003ee7eda004083,0x000107bb12f5f6cd,0x0008a0ae8649e92a,0x000a5a344683492e}, {0x000cfb24291fc3fb,0x000c3894cfd1718d,0x0000000000000001,0x0000000000000000}}, {{0x000751b1b1d1f30f,0x00043fce22373903,0x00023da45dac2f10,0x0000105df9307b4a}, {0x000892b6d1b2c311,0x000f645131b39e6a,0x0006331d8e317be2,0x0000b2f395de9046}, {0x000d56345f1e436a,0x0001b0547fe7481c,0x0000000000000000,0x0000000000000000}}}, + {{{0x00078f4b7084325f,0x000727f8bc0fa450,0x0001eb36b7bf5948,0x0004268cea0106cf}, {0x000e8c80e06d4c70,0x000c216323300186,0x000b3016e94d5075,0x000d882e86c372cc}, {0x00048a28a053b8cf,0x000343d171001931,0x0000000000000001,0x0000000000000000}}, {{0x000c0287664ae003,0x0002766d8c63b224,0x000b8220989c0738,0x000b967cd418521b}, {0x0004152d761e7a59,0x000fa019e4601efc,0x000f11b41cb4d7c0,0x000dcac0131d9d52}, {0x000c991e4e27a162,0x000789975ffa76aa,0x0000000000000001,0x0000000000000000}}}, + {{{0x000adcdaf64c0019,0x0002a5ef0c2175ba,0x0001cfec89a01d6c,0x000b25fa94296a25}, {0x00089c7ef16afeec,0x000c007e24585f16,0x000bbbc143cb4742,0x000531bcdafbbc24}, {0x000013773a99937c,0x000e19b7d849db6c,0x0000000000000001,0x0000000000000000}}, {{0x000e83417610eec6,0x000e934e9e9d81b9,0x000af4480e73d7b1,0x00086003aa3fea2a}, {0x00079c57f5c52d5f,0x000495c2aa9268f2,0x000922e4d082c9f5,0x000448a981d714f5}, {0x000bdf27622c6821,0x0001ae01e6436230,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007602120347ad3,0x000dd3e9ad407753,0x0002f89c76c52251,0x00044aaf5957d5e2}, {0x0006157c28051b58,0x00069eb597630bd3,0x000a387acac6af33,0x0002aad0ef875611}, {0x000ccba64de2edc3,0x000ff1731d170b0b,0x0000000000000000,0x0000000000000000}}, {{0x000557f665f21957,0x00064548e1ee52c2,0x0000cf955615f44f,0x0002bf2c64b6036a}, {0x0008d89213e751e5,0x0005aa570d34bd85,0x0005ae3bf1cb2e71,0x0003f29e703acc20}, {0x000a34a47fb1911e,0x00089578616fc498,0x0000000000000000,0x0000000000000000}}}, + {{{0x000dc828f86252e4,0x000d09ec8dfb2555,0x0005077092f2430a,0x00078d5b0c56862b}, {0x0002f9b2b116f869,0x0007b998e4dcbf23,0x000fbcf91af3491c,0x00056f1110038af4}, {0x000e0888ba8f38ec,0x00043daf07963a9c,0x0000000000000001,0x0000000000000000}}, {{0x0008da925a008487,0x0004f369188e0311,0x000ec8e641278107,0x000a270db9969754}, {0x00072aaa78c429c9,0x0001a344c1da5196,0x0003087bd58c2f7e,0x00088aeffcfb4dad}, {0x000fbcec5f2532f6,0x000a809230f905b4,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000b4a0ddb8dfab,0x0009deda0e27481d,0x000949ab745b2f9c,0x000dc2842dbe3df2}, {0x00059b98be5c35da,0x0002ed3249c0c912,0x000dc475c0841958,0x0005a3cc60128529}, {0x000078110f67e016,0x00017fe4fa3624ca,0x0000000000000000,0x0000000000000000}}, {{0x0006abd2bfebf71d,0x000617fcd7e4413e,0x000ac8bf7c39197b,0x00022ac8be897f87}, {0x000878bd60d51691,0x000ed69bb2587c48,0x000a51aae1defc49,0x0003d1f77705c7ae}, {0x00021ab01c739c3e,0x000801dacd9f17c4,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002a912967cbb3e,0x000f46687e4df221,0x00007e4eef350ebe,0x000e38a4de052972}, {0x0009d5282d27fb20,0x0006e64b3686af97,0x00067350cb71692e,0x0008437b220d3baf}, {0x00042c826bce6850,0x000642d60e139b00,0x0000000000000000,0x0000000000000000}}, {{0x0004eb43ead3cd1c,0x0007d1cbedb5fe6f,0x0001b45fb1ca7933,0x000a503cea7b46bd}, {0x000fef3868c8b110,0x000f9fe2cde99fc9,0x0006dd89f348e20b,0x00022d25b6cd54cf}, {0x00051adcb2128528,0x000ea79e7afb9c6c,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001fc12e7ca5055,0x00025e91d6adbf30,0x000587a0d31dc42e,0x000cc8a9cecd10d8}, {0x0009d8d1b41ccf88,0x0003b3f96490bd95,0x000e028999c5a513,0x0004c3a0882547be}, {0x000fc3438b39f5f7,0x000fa75af39ed4d4,0x0000000000000000,0x0000000000000000}}, {{0x00002b54c1f9ad9d,0x000dbd0a29ee5fbf,0x00057045bbc4f0d6,0x0000fce2e6fde293}, {0x00033040027dfc7d,0x0003be51ffcda45a,0x00054869841c14d2,0x000156ff1e336d04}, {0x000a634d9fdc8522,0x0003ae619b696b5e,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=108 [{1,2,3,..,}]*([2^432]*G) */ + {{{0x000019f2fc6beb7f,0x000666646b70deb9,0x00090a5717d2e533,0x0006810fd38f5274}, {0x000233bb33bad791,0x0009b6b88efd9526,0x000d5745dad71c05,0x0004ca300788fe6e}, {0x000ed4a6a21a98ac,0x000e10eeff58916d,0x0000000000000001,0x0000000000000000}}, {{0x000da52e803a67cf,0x0007d398c1a5fc48,0x00042b185c01901e,0x0004eda6cb2700b0}, {0x0004eeec867cdaca,0x000dcb7e930a19ae,0x00010a288471dcc7,0x0003198ed17517e0}, {0x0004e8756bb36f68,0x00027df915ed36bb,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009d95ae2bd1168,0x000fb9d6f73873c0,0x00027b3bc9e7cafd,0x00005fa81f14d40f}, {0x000ed4eebf4e66fc,0x000bb6036a4e6b76,0x0009e3f736cb7387,0x000b2277b08a58e1}, {0x00055c0d7a4986be,0x0004d18f830adabb,0x0000000000000000,0x0000000000000000}}, {{0x0005e59f982356bc,0x0000599a3ae563b2,0x000d06e16bf18997,0x00088dac7505891e}, {0x0004c76b3eb973d6,0x0006498b2d10cb08,0x00074af2d6e8e95c,0x000a503f71b8afa5}, {0x00066999bc16133c,0x000bd76f3443fa99,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009cc5a1fdf300d,0x0000ede5aa101a8c,0x00053342a7d32907,0x000bb4fe852398fa}, {0x00036673ceb9c007,0x000c9247b3a94312,0x0001ee51cb682683,0x00075c07f2ef115b}, {0x00083b0143f6486b,0x000d101585ec3771,0x0000000000000000,0x0000000000000000}}, {{0x00080da54d84cedc,0x000e569a2e8c0006,0x000e94c0472e41a7,0x000a41c1b7c713ec}, {0x000e5742d18ccf2a,0x000df3c3763e3162,0x0006b9977417a84e,0x000f165b44c75791}, {0x00045d988246f2e2,0x00095c8287828d1c,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f9c015fdb1c06,0x00099f25767d4418,0x00077c536b749d61,0x00054bfdb54e847b}, {0x000237979776c1af,0x0001eefa220b8386,0x00018acdf9bb4a75,0x0008ce45beb5028f}, {0x00030f98a7dd8621,0x0003023f055e3ab9,0x0000000000000001,0x0000000000000000}}, {{0x000f321b72c7f6a2,0x000659eeb57c141d,0x0000b2255cf53902,0x0009dbecf2a776fd}, {0x000e6453cf8ab4cc,0x0002d5647863e94e,0x00049fe93a4007af,0x00039cf116d00271}, {0x000dc8184a637605,0x00061de7465f7317,0x0000000000000000,0x0000000000000000}}}, + {{{0x000dae8508371ab1,0x0009f5759cf42671,0x0001705cf63d991b,0x000e90ca5edd0265}, {0x000af5c715a86e95,0x00096331dd94a89f,0x0005808565c73b46,0x0004c9ca8a595723}, {0x000561170be646eb,0x000a57b5fc879ce5,0x0000000000000000,0x0000000000000000}}, {{0x00080540adb44437,0x000abb97c57c16dd,0x000be7baf4488307,0x00019e753dbf21d2}, {0x000ac5be29dc51e1,0x000df21c9ad3cc57,0x000a9aa74fbb9193,0x000a11ec7b8e665f}, {0x000c01bfce350115,0x0009909f2c73b53a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000744ab95b71183,0x0005aa6c81566c3d,0x00033310fbbacd74,0x00006a2dd55a7d6d}, {0x0002db05de914221,0x0001ffd4282301fd,0x0008cf7489b2de85,0x000c6f0a02baf309}, {0x0002ce9af0a85604,0x000261197b0884c2,0x0000000000000000,0x0000000000000000}}, {{0x000e2c60da7deb89,0x0008d4b2f2e54489,0x0002e5dee75d5785,0x0005e0e953899934}, {0x000ecd968f2eb742,0x000229cbd8cbbbd2,0x0008dcc6b871d5e3,0x000490c7582e68a9}, {0x000cde3999720429,0x0005eaec58ffb639,0x0000000000000001,0x0000000000000000}}}, + {{{0x00028ab59549216b,0x00005d61d82596b8,0x0009fa679fcfc930,0x000ccf438ed2cad9}, {0x000a40190b3069f6,0x0007f5af4bb6d49c,0x00002f9e7c50f6a7,0x00019940efdd8671}, {0x00002add96c554a6,0x000e007d80786684,0x0000000000000001,0x0000000000000000}}, {{0x000ad0fb54ef0a37,0x00046af5d15fc57d,0x000b825452e8ccd9,0x00044232c710cb6b}, {0x000cf88855ecdc6f,0x0001d6d2b8f40b3c,0x000436e2bc3e510d,0x00007b1ff42aeddf}, {0x0000ed88484552b4,0x00075c1505c18430,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a55f734e8c16e,0x00026ef042fa2f6e,0x000b24c1848ab1d2,0x000acbe86862a1dd}, {0x000651f4168e7413,0x000d596e07914083,0x00079ca23961d189,0x000e6d53679701b3}, {0x000cf35fa05ec7b7,0x000d20d7f6b70713,0x0000000000000000,0x0000000000000000}}, {{0x00018785b4c707b1,0x00038676095f2dbc,0x000e28a0370a0054,0x000af09e50c89610}, {0x0000f144bba0bfee,0x0004cf6dd7455cf1,0x000e722f509d9783,0x000b05c279e5f94f}, {0x0001244fe8092deb,0x000153b314f061e7,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=109 [{1,2,3,..,}]*([2^436]*G) */ + {{{0x000803868bfafe94,0x0002ddeb7719717f,0x000911e1ad005b4c,0x00076f1e0df34f87}, {0x000b29958d5da570,0x0005d1ebf66f49ec,0x000f5712ca7b49e5,0x0005b2ff1b32fcb4}, {0x000f97d3d42a971c,0x000804838bb32749,0x0000000000000001,0x0000000000000000}}, {{0x0002e7908789eb65,0x000af786529c3ba5,0x000e71594737ddd9,0x0005400f6dd64d51}, {0x00039922bf016830,0x000db4bbaa21ca42,0x000935d8c94ee851,0x000c80623440afda}, {0x000110efc0a576c9,0x000396d79f58dcd9,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b38ccc9df95f7,0x000d1849ee6062ae,0x000164333dec1411,0x000e81b4a4a4727a}, {0x0009c74b241dc566,0x0005069fb7290aa5,0x0009d322865cb6d8,0x000ecbd648392838}, {0x000909864ce3c8f7,0x000ac9fef248d28c,0x0000000000000001,0x0000000000000000}}, {{0x00061d435126259d,0x0005a6b96bec8542,0x0001f509bbc62a6f,0x000ddbc8b43f9c90}, {0x0005e94118466c53,0x0002a386779ad388,0x000db58d109dd2e2,0x000aeef4f2af60b6}, {0x000bc0cd7adf1adc,0x0008220fb47811d5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f1b4d9b2b9d58,0x000635d4601e4549,0x0005712ad28d37e9,0x000e19b42c3143dd}, {0x000fdc6366f04af7,0x0004b34637aa565a,0x0005b2ac12b452bc,0x000277fe7f5bdd13}, {0x000c6ff31feea8b4,0x0000c45cdaec8e9e,0x0000000000000000,0x0000000000000000}}, {{0x0007813178366af1,0x000e83664c221b3f,0x000afac4ecd652c3,0x0007c4666da93d03}, {0x000652ceac0d6cfa,0x000b1a4cf4039d2b,0x0005c58a6eb1946c,0x0007422c9b53a228}, {0x0007349ed1b4d836,0x000afa4c55a379cc,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009ee173ac4010e,0x000fb942f467a4b5,0x0005770a30141b66,0x0004198802513df6}, {0x0002c7e0148f2f1d,0x0009a1b6c6f54abf,0x00056f2bb47b51bd,0x0004f5846505fba9}, {0x0002a3ddcb02618f,0x000a7b69ec8c6450,0x0000000000000000,0x0000000000000000}}, {{0x0004b69533aa9231,0x000b0804316d8f19,0x000006107c58f7bc,0x000310f29f43afd0}, {0x000e7a15ea5dc32f,0x000849a363e2b91a,0x00074452b4966c63,0x00071d63455b6a45}, {0x00039b535b8835c1,0x0005091ae86f54cd,0x0000000000000001,0x0000000000000000}}}, + {{{0x000de1ec8614daa5,0x000f0834c4db4a7b,0x00048a29f6ba70a6,0x000be231587d1015}, {0x000bb998c9a2049d,0x0005eedcf88aceaf,0x0008878e6b738f7e,0x00019b693ecfcab0}, {0x0008dd1ddb374ede,0x0003be7a6cd94f00,0x0000000000000001,0x0000000000000000}}, {{0x000bd130c16a2f12,0x000343c20757ed83,0x000228e06b217bff,0x000046a91bef19ad}, {0x000400e88da5cc51,0x0000a9f961011b58,0x0003f9049ae6f047,0x000e9d079a03c6f8}, {0x000401435912f072,0x0007490b78fe3f9a,0x0000000000000000,0x0000000000000000}}}, + {{{0x00081fdfff4245fc,0x00050168c14a6614,0x000764d4d2b84edc,0x000aaa60be356501}, {0x00030e6771588736,0x000714d50c0c40e3,0x00029157b8fe8875,0x000a9215aac4fbdf}, {0x000b4091b549e25d,0x0001ad442d2b0058,0x0000000000000001,0x0000000000000000}}, {{0x000ee6a91c584138,0x000d84934568ba88,0x00010dd1585307ef,0x0009b046cb644b24}, {0x000dc2bd376e1321,0x000cecc49bef0c68,0x000f76556c2d2d1d,0x000d810f8810c907}, {0x000a20da5052b3dd,0x00079ec3448a3c1b,0x0000000000000000,0x0000000000000000}}}, + {{{0x000084366f4dadcf,0x00087f5cc0a55e0e,0x000a139c3fe7ef01,0x0003f2e749d53f7b}, {0x000ffd809a727542,0x0002e74f9e5a94a4,0x0001929541f08d0e,0x000114dd07932254}, {0x000f53ad14915984,0x00078a408f5bb7db,0x0000000000000000,0x0000000000000000}}, {{0x000b74adedde4d64,0x000eeb46e287111d,0x0001ad3605f3b22d,0x000070fc8863541b}, {0x00093fdd530f51fe,0x000f3d69c04af47e,0x000f551d93cb6477,0x0002bc684cde6d16}, {0x000154a9f50cd685,0x000e9f16ac0cc2b5,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006190bccf09089,0x000de2a4a386bf1b,0x00095703cbb17c47,0x00013d223bf84891}, {0x0007a124742673f0,0x000290f2b86fdb82,0x000f44e50e9b7e10,0x000ecc65826079a8}, {0x0004d12b589a9228,0x0001b683a119d1ab,0x0000000000000001,0x0000000000000000}}, {{0x00025950f93cc637,0x000b7a6b02229a2d,0x000fb0617d538c46,0x0001dd7b6bc581dc}, {0x0005b6b522d590ce,0x000133e3f5d0dcdf,0x0005bdf5cce47e79,0x000e21b8ecd0d71f}, {0x000ac21b717d9aef,0x000b887b6090257a,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=110 [{1,2,3,..,}]*([2^440]*G) */ + {{{0x0009fcba235d8a1e,0x000ca359a63f98f8,0x000f60025c086d07,0x00018d4e590915cb}, {0x000c915cc7c3b68c,0x000933480185575e,0x000511ae8d10d820,0x000082704b904789}, {0x000a4e997db2e76c,0x0008c3f5824d99f6,0x0000000000000001,0x0000000000000000}}, {{0x00053628d8f32dc9,0x00000ea757555069,0x0008537e14185044,0x0007f7a0609d8295}, {0x000c55da70118c7b,0x0009ad1223c50379,0x0008629c936f6ea7,0x00054f7f839cbde4}, {0x000f8def61ba0172,0x000f5c1bef09ebdf,0x0000000000000001,0x0000000000000000}}}, + {{{0x0002eeedc5fe3f41,0x0004f9330d665ae8,0x0003f5e64a30753a,0x000e92f39e477096}, {0x000aa07f9d297ef9,0x00048c3ddf388062,0x000e61e60ab0df5c,0x00095a47567e55e6}, {0x00066d0129872a6f,0x000953425f368c3a,0x0000000000000001,0x0000000000000000}}, {{0x000b7cc7bf66ffa4,0x000f16b2825eba03,0x00090e67535ba3ce,0x0004aef14aec5704}, {0x00001511ac67bcc3,0x0001002739d95c0e,0x00029220f4f36575,0x0001465557ab45e9}, {0x0009abecf1baabf9,0x000fe98337c9760e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000025751d2b325a,0x000cde6a01039da1,0x0005ba8462228499,0x0003490747232500}, {0x0001a523417ab4da,0x0003451baf54b07c,0x000516f3fa7e4ffd,0x00042fbff2147ce5}, {0x0003f1b0afc522cc,0x000cb395c7010ca3,0x0000000000000001,0x0000000000000000}}, {{0x0005ed5f55af51c6,0x00015b980e568466,0x000a5a1b30bd5964,0x000bb04e8834a37b}, {0x000becf282494fee,0x00040dc6ceb29d17,0x0004a868d5399a53,0x000276012bcea50f}, {0x000c769aa83faa31,0x000d8e6550a0654b,0x0000000000000000,0x0000000000000000}}}, + {{{0x00066fa0ef4dbc14,0x00071d134a53f7ec,0x0001ee39cdaa7b28,0x0009b3f183070c04}, {0x000c76da77991974,0x000916f1eb867841,0x000b27421e5438ae,0x00051b0e12d8e409}, {0x0005e08b83842a6e,0x00094374b9e008de,0x0000000000000000,0x0000000000000000}}, {{0x000a4cba763a6340,0x00013308e07acdfe,0x000db2143a906789,0x000fe6dd815c887a}, {0x000e2a9d2043c85f,0x0003ceab79a68d05,0x000986393674d33d,0x000d12ee73ca7a8a}, {0x00003b9bbd54b7af,0x000b702eead11264,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000b987f57f80d5,0x000d4367c06145fa,0x00034438e79fd55d,0x0000f9f8e8ca9c52}, {0x00036810f12c2fad,0x0003ec5af1a97a71,0x00085613d0eababb,0x000aecb3da01b7b5}, {0x0000150798aadf26,0x0008029cce9cadbb,0x0000000000000000,0x0000000000000000}}, {{0x0005a72e54383960,0x000decd025e95126,0x0005b2c914390e3d,0x000864784955e972}, {0x0008cdae63ed0053,0x000aa5ded860c28f,0x0001dd80fb99e774,0x00020f07854bb74c}, {0x00091581c2caae0f,0x000d48069f6ba766,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f135836126647,0x0004208b738df6f5,0x000786c7341e91f4,0x00084ed91ae2188a}, {0x0000b08e3293bda3,0x000e09af3119b1a0,0x0003662652676669,0x000fd07b9f37322f}, {0x000ae129d764ea40,0x000b85c16a911b11,0x0000000000000001,0x0000000000000000}}, {{0x000021aec95ad18b,0x00080eeb3197c759,0x000dfd4a4334daed,0x000ff78d606234ad}, {0x0003ff98a1d73ab3,0x000c9cac669f90a4,0x00063cf99bed1762,0x00028f03fcd45e80}, {0x000b17bf750672a2,0x000879027e080bfd,0x0000000000000001,0x0000000000000000}}}, + {{{0x0006a647cfcf8e23,0x000d745dafe04723,0x000c3212b4d30081,0x000945780f548f13}, {0x000a0d885e14f51f,0x0006ed3092941059,0x000651e189c478f0,0x00007a26e8c75042}, {0x000a14b52f36b6ee,0x0001a032dfdec009,0x0000000000000000,0x0000000000000000}}, {{0x0008ca67379eb582,0x000b6f527f0a50be,0x000adaba76e4c6be,0x0009b987fc7fd1fd}, {0x000a047c90091990,0x0006d6f45b992155,0x000e37e2da697e00,0x00011a38bcd1740d}, {0x0009b93e8ce3867f,0x000b60503be8b250,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c16ca71ab9de2,0x000d4b4d3bbd16e8,0x00053785c45519f4,0x000fab776454947e}, {0x00019d9b9416f1aa,0x000337e34e6883b4,0x00041570208ba8ab,0x000cab67774a7e58}, {0x0008ac5165a84d18,0x0003a977b69d3110,0x0000000000000000,0x0000000000000000}}, {{0x000e5bcfd652943f,0x000743cd5e892a91,0x000502744c85aa27,0x000bb91ba0414bf5}, {0x000f8bc4ef773e26,0x000f9e301b8bcd45,0x00028983589038c8,0x00019a5f5e5a30d4}, {0x0005c6671a609f77,0x000a3aade09eb4af,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=111 [{1,2,3,..,}]*([2^444]*G) */ + {{{0x0008fa162e0dbf60,0x0003f486c08a442e,0x000d94f9cd2b15f8,0x000f2a2350bb6a89}, {0x0005b606cc5727bb,0x00003f198a74b132,0x0001a6f73b79d3ab,0x0001c95046a9cf73}, {0x0005ed71e298efd1,0x000274d622bb2409,0x0000000000000001,0x0000000000000000}}, {{0x000c383b3b59eae1,0x000e81b2f1927508,0x0000d888be6e14de,0x000fb612ce4b12e8}, {0x0001378248f53213,0x000330dbca43092c,0x0009ef5e40c52b24,0x000e9d869889952b}, {0x000c05f4131f1126,0x000503fd03ae1dfb,0x0000000000000000,0x0000000000000000}}}, + {{{0x000868b8bbdfd1e3,0x00069e244e266c6e,0x0007c7bf40b05a43,0x0003b7e1e296776b}, {0x000e22cfd9c18aed,0x000ea90d63ddbc31,0x000929198abb7bc1,0x0005791f36a5e50b}, {0x000737c71c2f87e5,0x00024f75c6d8e7fe,0x0000000000000000,0x0000000000000000}}, {{0x0004c9eb7d596ad7,0x0001e1a0fb486ad5,0x000d820f02c91d1e,0x000160179160a67f}, {0x00057f1163f25e5d,0x000cbc9a928b61c5,0x000df9b84ed79f2f,0x000854ba69556a33}, {0x000c5cb8ac8febe1,0x0009a7ec5a344343,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a1f2d5d90dce2,0x00048086d7fdecb8,0x00005e3d618ccc17,0x00081c1e93d5b7f5}, {0x000a9cc469c44a02,0x000561bd59d9df3b,0x000788578aa5fba5,0x000f6a295757cdc7}, {0x000387a16bd50e1c,0x00029d1a6695b773,0x0000000000000001,0x0000000000000000}}, {{0x000b40770bcc13d9,0x000a0b4cb7c0701f,0x00058a0433c71ad0,0x000e93cd5406bd3d}, {0x00098c999eda26c3,0x000092f416481951,0x00047a1b9bfd4b10,0x000f450e0ae46263}, {0x000aa14d201a717d,0x000a1f0cadae7402,0x0000000000000000,0x0000000000000000}}}, + {{{0x00025a8ecef36f15,0x0000495828c615a7,0x000ac113424f603a,0x00042c1687a77e81}, {0x00098761c2762346,0x0009b1a4749d0db2,0x00097828ac3391f2,0x0005050c5b69143a}, {0x00078b0a25ae0092,0x000d6c144730edc5,0x0000000000000001,0x0000000000000000}}, {{0x000bfa3844e6437c,0x000f55606aeb933b,0x00097e413566e3da,0x0001c1ae4263527e}, {0x000823a0378934ac,0x0002143f588c3363,0x00027262bb7d997b,0x00082419935b6941}, {0x0004eeef99cb555c,0x0009b82ef7f7cb72,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f0062dfac9c48,0x00002d81a18ce131,0x000ddcf23a0713ab,0x000a1fcdc4c43fef}, {0x0007bce6f244518e,0x000ad87348b34742,0x0006967b2b850180,0x00045248a8e5aac5}, {0x000029c18af90606,0x000027d44e26ac08,0x0000000000000001,0x0000000000000000}}, {{0x000cb47b7d6fa01c,0x0000fa06669eb12a,0x000ba3426d87d938,0x000cc362d25b1811}, {0x0005c938c9a5e9c2,0x000513be5311d61f,0x000c741f99e49306,0x000858e6ea44630f}, {0x00001034df68ea15,0x0009fda601eea831,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001335ca463c947,0x000056d6526151f8,0x0003c494f0f999ff,0x00082dc10a7433ca}, {0x000067fa3bcdc41b,0x000c803bb39af11e,0x00031fc0ac7bb35e,0x0005b5e185aa457b}, {0x0006ab2cbed55591,0x000c973304481958,0x0000000000000000,0x0000000000000000}}, {{0x000c07b3b2112108,0x00057bae813666bf,0x0008eee1f424f0a9,0x0002122582cf0958}, {0x000314daeb7bdc33,0x0004de4e23458ec0,0x000a768d0f97884e,0x000a1655c201fc50}, {0x000f1a537b424f36,0x000a6c0cdff48114,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007e2caf6bd29ac,0x0003376357d313a7,0x0007372bec99c462,0x000dae50c449ad64}, {0x000a9851fff00473,0x00047fec5d20efdd,0x000826de033e859f,0x000f46311785804a}, {0x000104e3184caf5e,0x0001ecedcc25e31e,0x0000000000000001,0x0000000000000000}}, {{0x000e47c0beec6da0,0x0001b1920715db74,0x000ae32e6188b124,0x000b5dfc6ee77c87}, {0x0006b132638e4040,0x000b86b665e1c6f4,0x00028fe14b060006,0x000b71efffb869b7}, {0x0006eab86370f188,0x0003e80379ec88c1,0x0000000000000001,0x0000000000000000}}}, + {{{0x000f8cb24f3b637b,0x00076af131c20322,0x000815ccfff0c2b0,0x000fbdbff056364e}, {0x00060c8028853dbd,0x000af0ee0841ab57,0x000da56ca93ac088,0x000d301350923094}, {0x000228a255054010,0x000a058e7dde6774,0x0000000000000000,0x0000000000000000}}, {{0x0005176aa5c512c3,0x00020d3779fd868a,0x0007658fb3dbe164,0x000cf13041f45c5c}, {0x0005049dea64d110,0x0003f6746e19e0e3,0x000a39087ca45757,0x0008108ab4e2fe7d}, {0x0009cce4e874c545,0x000b791d64965ce3,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=112 [{1,2,3,..,}]*([2^448]*G) */ + {{{0x0001f7c72b336855,0x000f76e247b483cf,0x000202781dc97b6b,0x0005bb58c0f81747}, {0x0000c92efba888b6,0x0009612af59611a6,0x000ccbeaf54a57cd,0x000ef8689ba520d7}, {0x00091cc366d3cbf9,0x000056dc1abfe905,0x0000000000000000,0x0000000000000000}}, {{0x000a04beccd53894,0x00021b1e600b02d4,0x0006c3ebe8f2a150,0x00007cfe9586be60}, {0x00062f4028af5b85,0x000d392e8954dda7,0x000dadc519d37584,0x000b58c3813ebde8}, {0x000557ce681db641,0x00006323fa3b9991,0x0000000000000000,0x0000000000000000}}}, + {{{0x000327209a17e11d,0x000d294da0ba85ba,0x0002e3b7145fac1e,0x000fef1248cf218d}, {0x00034de112f175cb,0x00094a8f1676f3e2,0x000f9c2657870861,0x000518958d56de1a}, {0x0003dbcba495c76a,0x000cbfa5e9c9c9dd,0x0000000000000000,0x0000000000000000}}, {{0x000fcebaff9f1e95,0x00070930a1b712b1,0x0008296f1f273d82,0x00071eddfa6e1f41}, {0x000af7dd190815ef,0x000f6fda9bc4a2f8,0x000482585b1234b2,0x000e23556036541a}, {0x0001ac1cc79e6b22,0x00079988ea71f991,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a9c0f0a888100,0x0007d24e7957d723,0x000347cf9592bff9,0x000365bb77516430}, {0x000532639eeab522,0x00075ffdcf80bee0,0x000715b06a25a527,0x000f841be2cacf87}, {0x000bc301ef1a4c9c,0x000be09159817e68,0x0000000000000000,0x0000000000000000}}, {{0x000ae077a00f18c6,0x00066d4baba09883,0x00026a600e57c245,0x000d614baadec7ac}, {0x000df9f1c7a24538,0x0006e61c4241b694,0x000e25d7cba200ff,0x0002e6c811de028a}, {0x000a7a2ca09bc137,0x0004b214e3d38684,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002cc5d8d86efa4,0x00086c8ee779a0a2,0x000fd2159545dd5d,0x000c7262fd5e2c81}, {0x0008275f13cf7ab1,0x000759a0b74f36ad,0x0003c0c8c3ddc91e,0x000d10948a51d222}, {0x0007160cf9b2c7f7,0x00060f285822b597,0x0000000000000001,0x0000000000000000}}, {{0x0001e962392851c3,0x000b50d7c127ef1a,0x000d984c5287e5e2,0x0005ce7d3999dfdf}, {0x0006fd1373907aad,0x0007f8f0825c8472,0x000b5c55ebbc32d9,0x0002bd51b3a068dc}, {0x000935287a1b4f59,0x0006c8f3eb9dca36,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e20e45266c880,0x000d20d089ee45a2,0x000924531cdc6e8e,0x000f7ce2e1fa4436}, {0x0002517f9a18e676,0x000d570398bec610,0x000dea4d0f9eb1c1,0x000c9914ddf30f65}, {0x000cb21d0d421e9a,0x0002d38fb5fd0304,0x0000000000000000,0x0000000000000000}}, {{0x000db46cd0b507ab,0x000ba53f3ce83b8d,0x000a8aca81c50a03,0x000245a83198cc38}, {0x0008bb4ffb6faabe,0x000c93601934e1ba,0x000061b676968674,0x000710e9ebcf5033}, {0x000185f4475389bc,0x000687b9bd9763f5,0x0000000000000001,0x0000000000000000}}}, + {{{0x00029514447f1de3,0x000d950771604321,0x0003a8cfdfffb078,0x00022ba412e08811}, {0x00097ef9f248a108,0x000b82c1196accaa,0x0001f8d1787041bc,0x000ec8430565e6d4}, {0x000eacea7ff3e1c3,0x000896b9bec2206b,0x0000000000000001,0x0000000000000000}}, {{0x000508946b504e8a,0x00067cc71474da28,0x0009ad4094d373bd,0x00068f87798411db}, {0x000b0b90d5d507cc,0x0000617d88846f61,0x000a437ea42aac2f,0x00012a4ea205a926}, {0x000adcb25d613e80,0x000fb7ef615aab09,0x0000000000000000,0x0000000000000000}}}, + {{{0x000127afd82f8260,0x000f4ea3f09c69bf,0x000b49f3f0e43a3e,0x00052457b8b9c3f9}, {0x0004fe6ce00409f0,0x00044efa3e31f441,0x000e3e0240cf1253,0x0001f0b4a170983e}, {0x000d166b0cc9e8c1,0x000b455417a2207f,0x0000000000000000,0x0000000000000000}}, {{0x0000fd522cdf167d,0x000b48039daf9a36,0x0007cdbcd7341cc4,0x000c7db3b7805076}, {0x000641b0db786edf,0x0006ea9b69b8bccc,0x000eded2a4e25e3e,0x000651b8f0911cf0}, {0x000614b601e95ba9,0x0005000aeb19e877,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c0c51d56f967b,0x0008dddbb7684495,0x00035dbc45f7bb76,0x000f9e6deda49098}, {0x000e73639006a39d,0x000878e5a247f77e,0x000cd83d141b2c8d,0x000804a47e332c8c}, {0x0009dc7a02d4027f,0x000b1b9934bb002c,0x0000000000000001,0x0000000000000000}}, {{0x000777a838efe004,0x000368d9919c1d8d,0x0009dd721650f685,0x0002b1de892863f1}, {0x000d78f2b25a32a9,0x0002a4320690ff3d,0x00005a4af7bb8bc1,0x000cd763efcfe035}, {0x000701c70cf4f256,0x000443ef26775353,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=113 [{1,2,3,..,}]*([2^452]*G) */ + {{{0x000e0800cd422057,0x000077d1b7504d49,0x00004fd80e159ebe,0x000a18a8714afb4f}, {0x000de28810d8b90e,0x00019cff83f02c3c,0x000eb9e19367a867,0x0009952bac438786}, {0x0000e0748ecceb4e,0x000faa55aefa6646,0x0000000000000000,0x0000000000000000}}, {{0x000aa315b1f2623e,0x0002b544f96e097a,0x0005dae237e7a5db,0x000873d0a9362519}, {0x0005569799223163,0x0001a58ea84d0fbf,0x000d43fd3bb728ac,0x000f100cfe43661e}, {0x0004f55c6f1cd21a,0x00091825dcbe9fa2,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fc794a5858d75,0x000a4affcd84d641,0x0005082ece4f5985,0x000b4853cf3bb3f4}, {0x0000bb1d8af65850,0x000953dc3e670d98,0x000424ef579458a6,0x0008ac2f2e4a7963}, {0x0000d771e540b685,0x0009be1f5fed2292,0x0000000000000001,0x0000000000000000}}, {{0x0001be223c4864af,0x000fbb662c4dc573,0x000a57017521419c,0x000c0240d65099ca}, {0x000b13af88f3bfbc,0x000bc4861e1643ac,0x00067ed67405bcdf,0x000d9351f1c835f0}, {0x000d0e188cb8018e,0x0001f8d276f971ee,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006a9e449621f3d,0x00052e91ee418d60,0x0007e5ea0e7d2dd0,0x0006f73c92e787f3}, {0x000cc4508ea4869d,0x0002d461acfe248e,0x000bd24529ffcc1a,0x0002f90dc5dc22dc}, {0x0002f8abba336456,0x00056cd254e4f954,0x0000000000000001,0x0000000000000000}}, {{0x0000aa036c0262fa,0x0002edc4f4234a99,0x0001031cef9b59ee,0x000145d5d5d4b081}, {0x00087df2c037b984,0x000a2d6af2c7b077,0x0006ff431d568532,0x000e309a7c9b6d5e}, {0x0006a3ee9bb40c66,0x000c81af9db41cda,0x0000000000000000,0x0000000000000000}}}, + {{{0x0000f6f067a194c8,0x00066d7ad7abcf3a,0x00041cf832b531ca,0x000f470a4ac4965a}, {0x000cbe00766a00f9,0x000432af80a92657,0x0008968ac40c892b,0x000cbd44ededa94b}, {0x0008d46204be8b74,0x0005dd98f760bd2a,0x0000000000000001,0x0000000000000000}}, {{0x0007f464f2479db1,0x000c0fdb3e7dcb2a,0x0001a96b28900b58,0x0000a2993c1d7ee5}, {0x00057bf0ce9357a3,0x0001f5d39eb49f5f,0x000fb8b8f0c1970f,0x00060718d4faac9c}, {0x000ec4ed9e1c25a3,0x00004bb0d7504b66,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c9e1b2fe9b1f5,0x0008d34221feb754,0x00042a589958e706,0x00008c19119e3c31}, {0x00021ac738645a87,0x0004d7be72a33383,0x000a72a39907dc71,0x000beb5759bb91f8}, {0x0009abd4b13e9374,0x000b96398db67d76,0x0000000000000000,0x0000000000000000}}, {{0x0000945a75d3799d,0x00031dd530ad32ad,0x0000c605c645aa0c,0x000c247141d0f230}, {0x000876cc8fca8350,0x000943188b899279,0x0001484afb9ffa8c,0x000536d0aa571f07}, {0x0002b7a0c7fbe8ba,0x000c736f36c17e51,0x0000000000000000,0x0000000000000000}}}, + {{{0x000618a7bb29e0e4,0x000c09c2bff10aed,0x000781dbe57f3993,0x000965b0e2b9baeb}, {0x00005cf5dc5bd4b3,0x000ce5975c6e0f92,0x000471ab0fcf2bf8,0x0002a2d43bae9f5d}, {0x000bcafa18f22cc7,0x0005911e3b357902,0x0000000000000001,0x0000000000000000}}, {{0x00057df200a9fe3a,0x000b50d956c845fd,0x0007f211bf361887,0x0009b4007c382ac0}, {0x000ee4f517e7f4f0,0x0008256df5e905bd,0x000fa86a9368d1c3,0x000a7df56d37c426}, {0x000efab6ec26a5b8,0x0005cdfe9cfac9c1,0x0000000000000001,0x0000000000000000}}}, + {{{0x00082202f99826cc,0x0004867eca10dd40,0x00071f5c4e281cfc,0x0007b5da880b8221}, {0x000325e5cd3e67f8,0x000671c0e0906564,0x000df4bd6ef65d7c,0x000c8a693695da96}, {0x00076e79dcdb1aea,0x0005bd96f080eaaf,0x0000000000000000,0x0000000000000000}}, {{0x000240c6e69e5a49,0x00080c138884ae0a,0x0002f7e55e87844e,0x000a57d17ee0d45e}, {0x00033a1990475a82,0x0004fc5139e3efb1,0x000093a8d1fcb820,0x0007e2fdf23f8eaf}, {0x000aec2eac127538,0x000a0742581e77ed,0x0000000000000001,0x0000000000000000}}}, + {{{0x000de604b9db6d8d,0x000262da62b65572,0x0009db8d0d3fb7d9,0x00067b7f8e9c2aa3}, {0x00074f2912d3c9b8,0x00079e6d831a5ad6,0x0006f3cc6935b1c2,0x00009a75e08b8223}, {0x000aaa28cfcf8f6f,0x0004f75ff407271b,0x0000000000000000,0x0000000000000000}}, {{0x00024706c120a90c,0x000b4f991d9aa4ab,0x000767e06952ed85,0x00006ffc0793e3c1}, {0x0003d6115d975f7d,0x000c57472c131644,0x00024430b8651df9,0x000bda1a64f28b97}, {0x0006db846f1bbd8d,0x0002f562aea1650c,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=114 [{1,2,3,..,}]*([2^456]*G) */ + {{{0x000d810c86eab937,0x0008e6e6eb51bdd5,0x0009bc2e3a0e4219,0x0007e391c4b3dc48}, {0x000736ed77fe5eda,0x0005e60972cd0e3d,0x0001aaa05f70f41c,0x000db07669f426a5}, {0x0005914839830a47,0x00029045b98cf434,0x0000000000000001,0x0000000000000000}}, {{0x0009d9c576932524,0x000409f4c3b8bddc,0x000d467dc9295086,0x000bdef23e6cf0fa}, {0x000729684c1e0fbe,0x000c3a23011daa3a,0x0008c4ef40ca0da8,0x00034dda12c0850f}, {0x0002c5e51990ccbe,0x000494c2f0adaf8f,0x0000000000000000,0x0000000000000000}}}, + {{{0x00087b36a390065e,0x000c93a9bb0064f8,0x0004572329d651f2,0x00010e01d988aed3}, {0x000be48541e9e6f5,0x0000ac10a8abc023,0x000b700a8621efc9,0x0003eb208400f943}, {0x000d85b1c768bb3b,0x000f42634af0db64,0x0000000000000000,0x0000000000000000}}, {{0x000e0a10a250b4be,0x0000634e42e593a7,0x000adef0026acaa8,0x000002da6f2f96cb}, {0x0008dca66aa2e955,0x0005a69e8157271d,0x000f32666dc76291,0x000c378977ddcf29}, {0x0000e5eaa07d6619,0x0002a548e47a94e1,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cd510985c6ead,0x000d1cc399a1876d,0x000fc77243f5c966,0x000c3b2c4abf82c9}, {0x0001efaf22c713ae,0x000a22e1704988df,0x0002a2d8f28a287a,0x0000f724ea967d19}, {0x000ed48e76179ade,0x000ff318acdc5b8c,0x0000000000000001,0x0000000000000000}}, {{0x00063196ac8ad685,0x0002708e70052b0c,0x000d8ff45f4a08be,0x00064862e9bd37fa}, {0x000efcc39748e461,0x000dcfa2843cc067,0x0006ae8688367317,0x000b8aabfd38c458}, {0x0005642ea85ecef5,0x000873af78e84b81,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b763fd4a23b33,0x00004ce905f61100,0x000ad5b3ffa31c96,0x000817bf059b27d0}, {0x0004f957d997fe85,0x0008adabfcc9cea6,0x0002fa1bf24cb58a,0x000afe218a3174dd}, {0x000ee69ca08cb0de,0x000fdf310fed00cf,0x0000000000000000,0x0000000000000000}}, {{0x0006e131eb000160,0x000a4d18c779a4d6,0x00013180dd747a1f,0x0009340c23f27ad3}, {0x00004df4a2f35316,0x000ec77b35a8c2be,0x0007fb23a1f8aa1a,0x0009e69edc272eed}, {0x000d58ddb6110abc,0x00042ae7590226a5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f3cc8ae818a77,0x000f54ede150dbf6,0x000c2f06bc371295,0x0006ab2d173c2266}, {0x0007fda0b8b46bd2,0x00070909e3958aad,0x0005242beb035184,0x00006b5aad800c13}, {0x0003a70dce6b782b,0x0007761ebe42a4f4,0x0000000000000001,0x0000000000000000}}, {{0x000ee87f40792877,0x00080b5c7acfe8e9,0x0007c5775efcb053,0x0007bf0a2d540e71}, {0x0008c839d644d450,0x000d1ff451c6b81a,0x0001b7ea45f8834b,0x000306bfc9c3c653}, {0x000cabe92f1a607c,0x000c13152a3731fa,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ad1ff805361f9,0x0003b3536327ce4d,0x0005b0b62672d1bf,0x000ddf3847367af0}, {0x000278798d158f13,0x0004fbc252a948f1,0x0006fc03d0fe92b8,0x000c0138676b978e}, {0x000ea4ba8ef9334e,0x000f98b13cf22496,0x0000000000000001,0x0000000000000000}}, {{0x000ac5c627d693fd,0x00015f19d6d21fa8,0x000b4a2fb70b6705,0x0002c39928de441a}, {0x000db0fd9e912476,0x00096888c13371fc,0x00013f185fb68ee8,0x00092d86c189d0e2}, {0x0001cf6facea1f84,0x0005b949b94eff15,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003e85508c930d5,0x00050167c798885c,0x00018ef2850f4f27,0x000547f00d7f6b01}, {0x000899cb15ed2f40,0x000bc417a989d6f1,0x00008165c9378941,0x000bb0e0c28f2218}, {0x000839d9572ddfe6,0x000d6ab0b70e2e95,0x0000000000000001,0x0000000000000000}}, {{0x00092c31b5a755fc,0x0005623261be8d00,0x0002ed776ec81547,0x000ed7b92bc72da3}, {0x0006d943fbdb47af,0x00096c45167b5a5d,0x0006fef44f208158,0x000d5bd5c28e23f0}, {0x000da432e8f4f6c6,0x0007b3355da25eae,0x0000000000000001,0x0000000000000000}}}, + {{{0x00076c8ab8c349a0,0x000850693d15749f,0x000d18a6991254fd,0x000f60f54944e4ef}, {0x000febc73879cf78,0x0004c63e00125696,0x00042f68e1e2dbe0,0x000b688fd93a88e1}, {0x000f1e83abbe7321,0x0003aaa7b2fa13d6,0x0000000000000001,0x0000000000000000}}, {{0x000caa293a9d97c5,0x00059519ff3b97cb,0x000cedb5893b39ad,0x00064ed07e59369f}, {0x0003315852af3473,0x000d5a40d47c32e9,0x000386582768fe34,0x000453f8e4c60653}, {0x0004a96dcf43bf2b,0x000e332542e1828b,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=115 [{1,2,3,..,}]*([2^460]*G) */ + {{{0x00011a7aae3fec0f,0x00081883626ec806,0x000aebe504491b56,0x00031dd2ecc113fd}, {0x0001068171e0f3fc,0x000d2fbb6b5fdadf,0x0000ee0e94a492b4,0x00090723f06e06c2}, {0x00016b906e2fed2d,0x00033b2f32d5d083,0x0000000000000001,0x0000000000000000}}, {{0x000731c43f27e685,0x000c912924bed063,0x00058df5bd8f8996,0x00080e3a04d16a64}, {0x000303ff6f14cb47,0x000f56c8175aed03,0x0003011b62e0f3ec,0x000eee8bd1d8f816}, {0x000a055be5c28fa8,0x0005635edb8d9c9f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000eb4c2e9d6a36d,0x000f1c0e66e6ba0d,0x000058a747cb2451,0x0004b10a20962d66}, {0x000e1da104e82021,0x0004693d32e594ca,0x0003bb7f837609cb,0x000e53eda7c5059d}, {0x000b602751dd16ca,0x00007ac67ede2a3e,0x0000000000000000,0x0000000000000000}}, {{0x00038202cc49b145,0x00003535c208aec8,0x00056079145b2fb2,0x000814d455be9713}, {0x00082fd8f0bb395c,0x000c755426c09f67,0x0000b748edafadbc,0x000deaf4bc3a4ecf}, {0x000bff049553943e,0x00057ee542c407a2,0x0000000000000000,0x0000000000000000}}}, + {{{0x00058193376e77cb,0x000e72c0bba4380d,0x000bc54c3a89ddc3,0x000dd63a1bbc6d0f}, {0x000bf1518f660f2c,0x0007e5bf5faf2f62,0x0004682bfe7727a2,0x000da33defeb7b16}, {0x00032b5ef40ec257,0x000a0e902b2e8961,0x0000000000000000,0x0000000000000000}}, {{0x000ab468387524e3,0x00024e69a88271e3,0x0004545479e82998,0x000121a7373761e0}, {0x00093e3b1f753397,0x000463acb40aaebe,0x000cb721af707dad,0x000c14e152331d6d}, {0x00065553048e5280,0x000612aaad009d91,0x0000000000000001,0x0000000000000000}}}, + {{{0x00092b39f964e28f,0x000fa7cfd7976897,0x000f279c07ec556d,0x0001cf40d7670e8c}, {0x0007b5e04abdedad,0x0006fcc19990b137,0x0008572f5067ad94,0x000a28101c966a08}, {0x000b5e33c2ad58ac,0x000eb0e333e24c43,0x0000000000000001,0x0000000000000000}}, {{0x000f0361a475ac89,0x0002dcf79463ef54,0x000dd053538c22ce,0x0001013b4e6817ca}, {0x000b44b01a6e12bc,0x000d109d85844a6e,0x000b985bfdaef54a,0x000f6830be544481}, {0x000fd8dd0297f121,0x0007cb6d0b67a68b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ba65ede23b338,0x00026845dcbcdc45,0x0000a0b1cdddd83e,0x000092ea63968b4f}, {0x0004b71e6e72d35e,0x00046c5ed03f1ddc,0x0006efc5a166bbfa,0x00090de0b5f6b7c7}, {0x000445136c1387b7,0x000ba78923450ab6,0x0000000000000000,0x0000000000000000}}, {{0x000a850194005e74,0x0009c00cae44ea99,0x000e5e17b631e4af,0x0001c80d51c0dae8}, {0x000120c3cbe08ee9,0x00023c8041a40936,0x000ada73446b0eda,0x000643d14026f215}, {0x0006fbac37813fb6,0x000fc70031b68bb2,0x0000000000000000,0x0000000000000000}}}, + {{{0x00075ab901660b40,0x0001e645ee7e0ee2,0x00037b06a37399f2,0x00080496e9bd12b1}, {0x00026a5d50d58960,0x000c1e3f3705ba3f,0x000274a1d4a00817,0x000d2d00866a4d39}, {0x000f146bf0317c40,0x00024e2ec71ea064,0x0000000000000001,0x0000000000000000}}, {{0x0003c199f5c7f563,0x00062e4f78f16893,0x000a194ad2a3fb13,0x000080225259655c}, {0x000bc5898f9da5f4,0x000553edffd8a6c1,0x000e20b2793c4797,0x00041ea73083e26d}, {0x000a2971a533d937,0x0000e54fd22035b2,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f9d4de9a27585,0x000400debb5987f8,0x000d526ec09e3156,0x0008bd03e0023f66}, {0x000aed7d715cc557,0x00058cc9c03099f2,0x000506b4417ca0c8,0x000d23b4df572ea5}, {0x000c5dc147420ffb,0x00032899652bdfe0,0x0000000000000000,0x0000000000000000}}, {{0x00031987cf8e9148,0x000b259461ad7d0d,0x000c859a4a7e6bba,0x00030e2b3d2a289c}, {0x000e9be629139087,0x0003904cf1cf6e14,0x000cca9dab045a7c,0x00082a43de3eacb2}, {0x000d82c3afa439f6,0x000decd187ae70d4,0x0000000000000001,0x0000000000000000}}}, + {{{0x00087b4497808581,0x00012be293d33455,0x0004ce4906c6f8ad,0x000a66938d521bfa}, {0x00046a914bdb3b26,0x000ae5f6e99dc3e7,0x00059dbb0881c2e3,0x00009191a1b5ac25}, {0x000c6a97a72e5343,0x000ddd07226ad4a6,0x0000000000000000,0x0000000000000000}}, {{0x00039e249234483b,0x000669419af2063a,0x00042122752c72bc,0x000aa7e19a44c7a3}, {0x00011188ac573c28,0x0009a3360e14ec6b,0x000bc0bc86245880,0x000741e192993af7}, {0x000d8d75742bd481,0x0006cd8768555ba8,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=116 [{1,2,3,..,}]*([2^464]*G) */ + {{{0x000ebaeb9266fcb3,0x0006c49166afc8c7,0x000b1a4fb9f8df09,0x0003a2759ef63e0b}, {0x000ded0e62d1d0a6,0x000215cb79a13c16,0x000942482d5b46ef,0x000a5cf390334543}, {0x00039ce21c9b239a,0x0000a2fcf03ed34a,0x0000000000000000,0x0000000000000000}}, {{0x000466a8adf517f0,0x000775523be0b6d8,0x00074759167493a7,0x000284c64894bb12}, {0x000e2864e9ca25e2,0x0008b7f98fd07d26,0x0003fdb6d6620610,0x000ef64b5a668e1e}, {0x000d31c44a0ba6ca,0x000891dac14a11ed,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007e005c5b2f805,0x00010b6d99c24dd3,0x000813da1409fa02,0x0008bf13d53cbcd5}, {0x0005bb6d8655f948,0x00021f224e5b2d05,0x00077dd3ba305b4b,0x00005337f568059a}, {0x0008b4b1e783aa9f,0x000d6ce8c56442b8,0x0000000000000001,0x0000000000000000}}, {{0x0007e0acb71f23b1,0x0007f2e0e90fde9b,0x000336f8ff1da186,0x0004751614e3d072}, {0x0003187e51c7e8e6,0x0007ef17101ca72a,0x0008a9761c42d892,0x000ebb69cc0c641d}, {0x0002903e96138250,0x0006b8d2873a54c1,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007b97b6b68155f,0x000799e78b707b09,0x000e1f75bd19e80f,0x00035096285e6628}, {0x000d9b8661ae0f1a,0x000fe90a8911dc8a,0x00018180a1d7fb12,0x000733dbb76ae258}, {0x000085cc47bdbf1a,0x0008c417eada4711,0x0000000000000001,0x0000000000000000}}, {{0x0006498715c0f18b,0x0008cd3093549e44,0x0007888a48d3a384,0x000a0d971c9394dd}, {0x000f79cc4aa385aa,0x000d44729501e42f,0x0002ea4042d9ad6a,0x000c1e43ab081b30}, {0x0002a374ef11901b,0x0009de3ad60e42b4,0x0000000000000000,0x0000000000000000}}}, + {{{0x00023f47f06415e1,0x000ec51fe7219c05,0x000bd8a88f411a49,0x000308976713e8b2}, {0x0006ee0f84892d3f,0x000957e9fa410c61,0x000903d60b015584,0x000f41fc07f1fce0}, {0x000fa3ce182117ef,0x000654b039b5693f,0x0000000000000000,0x0000000000000000}}, {{0x000f700d59c0d688,0x000bcc693fd9aa04,0x000b8b0e7fea0743,0x000182c181c35812}, {0x0008864896cc8fcb,0x000c77cf499f019f,0x00010bba6594c508,0x000e88406e142c41}, {0x000b45fd50fcaee7,0x0009894dc1ba3eb8,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007488ba3fe2367,0x000752106ad62ea4,0x000980bc62d3b8ad,0x000328ef733708df}, {0x000d47b00f88c069,0x000f6bb0176a2cf3,0x0009f6480ef1ba36,0x000ac0712001822e}, {0x00032f8aac418a68,0x000ff326047c12c9,0x0000000000000001,0x0000000000000000}}, {{0x00039bbf3cc8d8c5,0x00091d5e4cf0789b,0x00042078d73c679f,0x000b71a650f7aeca}, {0x00082a530b74abff,0x000a71711bd8405b,0x000c3bb0ac95d510,0x00094cee94894b3c}, {0x000906c5e7b66990,0x00030a027cdba56d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c446c47eef0c8,0x00044a0878421c07,0x0008722c55cf2755,0x000ec763424a48fb}, {0x000f4f6b5b3b9028,0x00078d4fe3ca8f7b,0x0003f4277d82e20f,0x000fbc6300a704e2}, {0x000a908b8f5f71bb,0x000b090bc8e8a53a,0x0000000000000001,0x0000000000000000}}, {{0x000dcad6549fc8da,0x0004e635d31de3d0,0x0009ac9c9dae5fbc,0x0005d812525deba7}, {0x00028465a1ffb0b8,0x000039c002085422,0x000d1431962a343c,0x0001729577d460c9}, {0x000befcdb0fe4b63,0x000f982552806705,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c16470afeefa0,0x000c0df482969752,0x000988294a6b7345,0x000192c323f56fda}, {0x000ece866a0fbb9d,0x0003fb58e433eb87,0x00044e600bdf291f,0x000bc9a43f5fab4d}, {0x00060683951124ce,0x00065a7c641677f4,0x0000000000000001,0x0000000000000000}}, {{0x000ce490f8bb04ea,0x0002e7ad3382ee72,0x000272231533e6b8,0x000186b13ffe5f10}, {0x000cc8faf0cc5e1a,0x000c709ed2b173b2,0x00067e514381962f,0x000cd58bc198455b}, {0x0006402864604346,0x0009d46f62db1463,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007bb607e896c28,0x000e0a894887a4bc,0x0006eb1e97614230,0x00003e71e2c653f8}, {0x00096dded494be93,0x0008ac95d09fc0dd,0x000bea563fba0619,0x0008f3c1624d738a}, {0x0009df64d4a0ea98,0x0001d5c6ae182338,0x0000000000000001,0x0000000000000000}}, {{0x000eeeb900454516,0x0006377d7a8b0a7f,0x000a9c345a7de36c,0x000100d5611067e9}, {0x000806bcdcedd0a9,0x0002b5dec6f6c68c,0x00051f38d7d4a349,0x00022d5061b9ad36}, {0x0005c9ea7f739c0f,0x000ee734e6cedbd1,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=117 [{1,2,3,..,}]*([2^468]*G) */ + {{{0x000eb05013cb5aab,0x0009afca55bd420f,0x0009c3c71fd8695f,0x00000cafcc6e5ed1}, {0x000728edc89ca3d5,0x00076471854e21b8,0x000201f0ff872ac7,0x0003e23036d8ee45}, {0x0002c13f7c8bee8b,0x000707a1d51a1e5f,0x0000000000000000,0x0000000000000000}}, {{0x00022b011bf68532,0x0000cf529ed8e280,0x000b8a477a52b6ff,0x000cd2f63b6e8238}, {0x0007c291c55c9cf5,0x000f4796ab42ab24,0x000c0989f93937b3,0x000bca7b47aa5dbf}, {0x0006f0a6b7620e79,0x000f58dd4ea00729,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004f87aac9cea1d,0x000fabffc3ba2342,0x000a3b2b167162b1,0x00073da5b86c7978}, {0x000769b5f991d83e,0x000cb3d9088d484c,0x0004542e085b4392,0x0004eba2ea8f2806}, {0x000c46cb82b91d2b,0x0008c0e83321f8cd,0x0000000000000000,0x0000000000000000}}, {{0x00097601a9d31426,0x0009ef4a0c50dffd,0x000fc4b8056305e9,0x0000c1c8a29f6e86}, {0x000d4be1babedf5b,0x0005e98d4d558d2c,0x0007fd7d17d7bc87,0x00009a0a33b745e5}, {0x0008c2a2bc3cf9b6,0x0006235277b76d2d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000ad9eb395de05c,0x00050bddffa75224,0x0008d48f88a50e57,0x0005bffe3c2175d5}, {0x000aded74a44ab8f,0x000f36097483dc36,0x00041e5290fdaaf9,0x00051f0f28ee6aea}, {0x00006d6a082ff0ae,0x000068e3568c35a6,0x0000000000000000,0x0000000000000000}}, {{0x00052b137174e56f,0x000a242808c3c521,0x000cee713ccf3a0d,0x0007f4523126e210}, {0x0009790a26049fad,0x000293cb237c8c65,0x000391754b82c700,0x0005060129b75ceb}, {0x000ad78c9cbc1be8,0x000452fab6d7a60a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000614e7a62b479f,0x00091b1806f1503e,0x000c937295d07735,0x000468f3b432690c}, {0x000027af2bc376d3,0x0001568b1fc765b5,0x00004c84508081cf,0x00093b08d2fa4f2d}, {0x000aa23530d43841,0x000eddd4118eb0fd,0x0000000000000000,0x0000000000000000}}, {{0x00095d916a74bf7e,0x00052f879c30fb73,0x00033e906c3732a6,0x0009ecd6d707078b}, {0x000764fe7914feb0,0x000164429576e244,0x00070601ef70830f,0x00038d1a94c290ff}, {0x0007e067e8e38b39,0x00004d7b7a7e7934,0x0000000000000000,0x0000000000000000}}}, + {{{0x00092dd8b3c6e87d,0x0006c49275954a31,0x00016b291ceab935,0x0002ae4fca80283b}, {0x0002ae3f769e974a,0x00047d8e3a1a96a2,0x000875bc17f080fc,0x000a5eabb84f45c1}, {0x000e2f2661df31c8,0x000663147f43e69b,0x0000000000000000,0x0000000000000000}}, {{0x0002716571c12164,0x000b5580b0b11754,0x000bedf056c51a6e,0x00019d3572bd29fd}, {0x0006ce46ac6d5756,0x000d711d909ced7c,0x00056c0ec115b51f,0x0005ebe8c1ea4d63}, {0x0005d77cf7a0032e,0x000ddbec9919b1e6,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002437a972f2c78,0x00015b5e5010e549,0x000fb968e48079c6,0x000ee7041338af95}, {0x0007cad3cea2147a,0x00063a330c01aad8,0x000ecdd3002cfb58,0x000bf58e568343ac}, {0x0007567e97251d0a,0x000b568be5a71fbd,0x0000000000000001,0x0000000000000000}}, {{0x0003982ec0a47e47,0x000862df20207b07,0x0002c656e08dda4d,0x0005ad59afe9aa6b}, {0x000ee04d8bf8d524,0x000d84cab42cc2b5,0x000ee837ff8c6d4a,0x0008b691af448525}, {0x0003b100c345fb36,0x0000d061abec1e80,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c9cc4477a0393,0x0002f0a9ecb165af,0x0008a80444bd4fb6,0x000a9d4dd001619b}, {0x0000b10c19a21051,0x000801b4ef3f9384,0x00076219bc4d71f3,0x000ea7190314526d}, {0x000da93e188e8697,0x0000967b67776acf,0x0000000000000000,0x0000000000000000}}, {{0x0006ab2717f542c5,0x000ae82426abc0aa,0x000641af35023777,0x0005dcf6c7153a96}, {0x000977e0ee60ca55,0x000c371732ddcc64,0x000063579dd744f3,0x0004f34c496af4bc}, {0x00000f9df0536028,0x000b1c2a26167cf5,0x0000000000000000,0x0000000000000000}}}, + {{{0x00061fdc0b1fc134,0x00059fe59da03f7e,0x00051831e7698bd3,0x0009f81df982fb68}, {0x0001c64253ce4407,0x00084a0c0fffbd0a,0x000fd2724ab08376,0x000aaefd7b900fa3}, {0x000017be08cd54b9,0x000359398932034f,0x0000000000000000,0x0000000000000000}}, {{0x0008bfed571b358d,0x0006e5bd73f12c5f,0x0007574722cbd9b4,0x000789de672fc532}, {0x000cf9d4c5de795b,0x0008e00647313e84,0x00001e2002f19344,0x0007649a15d6dda4}, {0x000a4f04c96114ef,0x000ac34a9dc08537,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=118 [{1,2,3,..,}]*([2^472]*G) */ + {{{0x0005e5ed4ea72f88,0x000dc27eafbd5d75,0x0008274c8f222817,0x000e4b956ed11c56}, {0x0002ac506cd96a0b,0x000c56121cfca3c6,0x000e3c5160f64376,0x0001cd969d9794e1}, {0x0002818ba2a1b9ac,0x000bbd5d12cb946a,0x0000000000000001,0x0000000000000000}}, {{0x000065269838f81f,0x000a256eaf242367,0x000743908912f4af,0x00048d332342e954}, {0x000f75565f855ec0,0x000e4ec59a3a8816,0x000505255b015d48,0x0006bf898ef06a71}, {0x000af90ae385313b,0x0001d5415dc8688b,0x0000000000000001,0x0000000000000000}}}, + {{{0x000115486df6f2ba,0x000803b08c738eec,0x0002302443593e59,0x000e60eb4f00e934}, {0x000e57c91438ebdb,0x00080e89c523e859,0x000d75cba0053e05,0x0000d11317c9b329}, {0x00035e5703d38955,0x0003845aac6426d2,0x0000000000000000,0x0000000000000000}}, {{0x000349105fa06b94,0x000e9b21c69e6c42,0x000f70eb1519a81d,0x000827ae2990539b}, {0x00048fe9bf0bbafc,0x0008dbb3c1ee9dd5,0x0002a908c4d4274b,0x000cb7224476f3be}, {0x00028346b6e6842b,0x0003ad39da0c7384,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a9a342fa007b1,0x00065415bb7a90ea,0x000dcc6aa0c26771,0x000a1f0bc720264a}, {0x000b5e93f7bc1986,0x000bf6b3fca182f9,0x0009a7b5c22f84c1,0x00087bdec7ad14eb}, {0x0008902c942c3b07,0x000a69d7973e7810,0x0000000000000000,0x0000000000000000}}, {{0x000230ff44676602,0x000d3064b8821220,0x000d730a5228928d,0x000ea087c0f54e1a}, {0x0000abe8035de528,0x000d9e98d62188b8,0x000d85f12fe3f391,0x00095d1c13b3c4b4}, {0x000c9a4940436d0a,0x0007d2cc5f243602,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c484e2708d61a,0x000e14446b62d85c,0x0009c0fff451d84c,0x000a49ca08f1ae70}, {0x0003d71899e1ae53,0x000709a90d9917f9,0x000f39b12fbb0503,0x000038af72a2045e}, {0x000817cd90b8cc9a,0x0002f352b4ed83f0,0x0000000000000001,0x0000000000000000}}, {{0x000a71d48ae023ef,0x000d8744e50d53a7,0x000192ec22667e7a,0x0002e19437867d3b}, {0x0007124825f0cce3,0x000aa41f07fce902,0x000fc674b8262125,0x000d1f602e03c9ce}, {0x000f93cc0c071ae6,0x0003fae4c52caef9,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d102ba58b5201,0x000cb021f49742da,0x00078984de6430a2,0x0005002098f1e552}, {0x000c9b804a37766b,0x00095479cd052eaa,0x00083f87dcee9cc2,0x000ce159b125b614}, {0x00001a384dc69331,0x0002e4ec5a2f8699,0x0000000000000001,0x0000000000000000}}, {{0x00049fffc681e26f,0x00001b52ea90f687,0x00080117445f69ef,0x00093fb5f32e704c}, {0x000d36110b81abea,0x000a3e64f4ffada3,0x0000ff99dcba475c,0x0000eb1b968c2040}, {0x000ded29d4be59cb,0x000ba78061ed859d,0x0000000000000000,0x0000000000000000}}}, + {{{0x0004949755c59603,0x000c796691a84904,0x000a8445d0aabdba,0x0002396cff6a7bd7}, {0x000562547f935def,0x0009038b91c344b0,0x0001f20274812ef2,0x000e1fe565e5087b}, {0x00074866fd902829,0x00032844aad6b8f8,0x0000000000000001,0x0000000000000000}}, {{0x00092e9251d05a0d,0x000328420cd4a328,0x000e00dfce4ccaef,0x000beca3a94d516d}, {0x0000fce64bd11bb9,0x00054cb1e99e5269,0x000cfc1bfec9624a,0x0004e634fe2023b3}, {0x000e53481128c3b5,0x000cd2258147276f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e9ad8d783865a,0x0008e5a58d54402a,0x000e236d64e3be62,0x000daf46f4aae16f}, {0x000049ba7000cd7f,0x000deb437c36e86b,0x00025e5a9179d63e,0x000fb30e5ec5adff}, {0x000fc4d691408156,0x000d8b4dff418608,0x0000000000000000,0x0000000000000000}}, {{0x000c4eed479219ce,0x0008e4d5ead8e114,0x0005f4f71316535a,0x0001c636b70e9489}, {0x0008aa2310479eec,0x0004e1dcd4f2eb70,0x000474c99b5134b7,0x000ce4754e99035c}, {0x000218919b4c0dad,0x000e1d1dd3f97981,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cc18c358773b9,0x00036bf6385f12eb,0x0008a0c24ba8caf5,0x0003093cd83891ca}, {0x000f5b8c3762108b,0x00041e3399b26a0e,0x000fadfca8c426db,0x0004173bf6760263}, {0x000a6677ad40bf58,0x0004eca4760acdd8,0x0000000000000001,0x0000000000000000}}, {{0x000c42b8b4207fa1,0x0006dc5a60d34efb,0x000a367e08d67868,0x0008cead3e942c85}, {0x000409d289bdc2dd,0x0004b034c3a6d1bb,0x000889304955940a,0x00080034f3684e43}, {0x000808a7cddeee0c,0x0001148f3d9aa263,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=119 [{1,2,3,..,}]*([2^476]*G) */ + {{{0x000df4a3fd3e1bab,0x0006287d84daca3d,0x000d7eaf57017e3e,0x000d1a4e4870b354}, {0x0004c26a3e3ca9fe,0x000ce1ea5e5710e0,0x000709e17a2ff920,0x0000f8a3bc06ee67}, {0x000788ab8c019a66,0x0006f43d909c0fdb,0x0000000000000001,0x0000000000000000}}, {{0x000c0c61eebda5c3,0x000395c130704b51,0x000762ffbcb5d086,0x000f660bf6639983}, {0x0001646d9fb03337,0x00065cf06a8fa37c,0x0005f2e3f14b6d28,0x00088227d360e736}, {0x000a48fcdc5c3e58,0x00059e8c2eaf07b6,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001ce2b5f2dc50d,0x0007e39f8c4d01b0,0x00078d34284f417d,0x000d157acbf04214}, {0x000c0c4238071f59,0x000b0a1e05f8a594,0x000d81bbaf85cdc7,0x000d1d1329e8c9cf}, {0x00068fc55c9be4f2,0x00029b5c20884e31,0x0000000000000000,0x0000000000000000}}, {{0x0009fd4109cb4727,0x00021d96d542276e,0x000d61e57db16c16,0x00052da58656adf3}, {0x00089d546ecce2da,0x00041508ee2098e0,0x00011997499c874b,0x0006f525839d9cf3}, {0x000de08e59654896,0x000e511cdd85c0a0,0x0000000000000000,0x0000000000000000}}}, + {{{0x000db13610c4d993,0x000192018344e51f,0x000cb8a7e81016f0,0x000425ff1ca2c27e}, {0x00047a8df5318c36,0x0004872bcd56d5d2,0x000d142a2e0d2618,0x000a83feb22e4866}, {0x00013dac70999b14,0x000ed007863be6ab,0x0000000000000000,0x0000000000000000}}, {{0x000023bbbd62b467,0x000e6ef8f48d21ce,0x000ea9c5f9c35940,0x0009af532bd76e0a}, {0x0000f8ff97911a1f,0x000efcff41750c50,0x0007cfa3985ad13d,0x000136812ef99c02}, {0x000319ee534694b3,0x000b9d9722dca85d,0x0000000000000001,0x0000000000000000}}}, + {{{0x00040d25bac4c923,0x0005026132b9fa82,0x000ddc2ef3e74ec9,0x000151b0a9db4e16}, {0x000ff5ad95c1429d,0x0008144cde9bb57b,0x0000c02f2a19e480,0x0005655b0b6aef98}, {0x00038725b1f2df6c,0x000672346457ed21,0x0000000000000000,0x0000000000000000}}, {{0x0003077ffe12bd18,0x000e682804b9bb8e,0x000b8a3a7328db75,0x0007b6f50cb1bbec}, {0x0007a823e8549b58,0x000d7be7a7e70575,0x0007103b60b8617d,0x0004131d7bc32367}, {0x000713f91128ac22,0x0000deadb3b9bf03,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b46eea58e4f6c,0x000e8500cef9c4a5,0x000e36179b50381a,0x000498cb317e7dbb}, {0x000df2d824ab9ac6,0x000aa97d96328707,0x00068fd80e79f5f6,0x000ee03799c5c193}, {0x000688d4b109d20b,0x000fae5dfd91a5a4,0x0000000000000001,0x0000000000000000}}, {{0x000e4aa8649aaa1b,0x000caf8a4a894ffc,0x000f0a6af855f3c5,0x000fa6ef0a082826}, {0x000564cf46392869,0x000d9060255a7500,0x0007688b437590a1,0x0005fa2a21425afd}, {0x000dd69d65b91f19,0x0008045302895146,0x0000000000000000,0x0000000000000000}}}, + {{{0x0009a872aecfc094,0x000c8cde3af050fb,0x000ebe6b500bec0f,0x0004d4b7e7c4ef2e}, {0x00094b38a6c4228e,0x0004f9fb0e82362d,0x0000dbf4e229d20c,0x0003a6e45bdfa369}, {0x000b1c90f730c74e,0x000306f2fc481fa7,0x0000000000000000,0x0000000000000000}}, {{0x000e496c4b887a36,0x000e6ae46148f8e5,0x0004268188f16f8a,0x000cf1b360936452}, {0x000ea828f2ec9dce,0x000a581be5eec097,0x0000a093e062b3a8,0x000e4da12b498543}, {0x000b50541562092d,0x000eae33c27b17cb,0x0000000000000001,0x0000000000000000}}}, + {{{0x000bed4ffad0684c,0x000bb264e57bfffb,0x0009eb6b035825f2,0x00013466fd8b6643}, {0x000ab9c3537903c2,0x000b0366be7313de,0x00096ae2121723c9,0x0005953e87c3ac29}, {0x000b6974bbd38278,0x0003e43a30236cf9,0x0000000000000001,0x0000000000000000}}, {{0x0003b2707ffdea7f,0x0002da68809f795f,0x000374c5228ca4a1,0x000ef9a132cc5a86}, {0x0002bae5f8c0d15c,0x00061ce20672616f,0x000abed75c41da6e,0x0006a5fc5af7de33}, {0x00076a4d15065912,0x000ed44c16e78857,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003498018e534a0,0x00031b029f064c8f,0x000b893aedc07be9,0x000b0eea14f71f6a}, {0x000eee179067b242,0x0009f6bf528af895,0x00020985e852a279,0x000b94bc19691d5c}, {0x00005deba296ab7d,0x0000b231b9475f76,0x0000000000000001,0x0000000000000000}}, {{0x000c45d63f8d3bc5,0x000aab0d9145a0f8,0x000bc0cd8bbb3a1d,0x0001299d614875d3}, {0x0008bad650d624f5,0x000b91d8407baf74,0x00054a383b9d385d,0x0006840ae765f5cc}, {0x0005a54bdbe2653a,0x0002865728a0edab,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=120 [{1,2,3,..,}]*([2^480]*G) */ + {{{0x000e419064732d33,0x0000fb9f1fdd6e2b,0x000b458dd169ab15,0x000b79def3f55fa5}, {0x0001fd9b88ebfb1b,0x000b8b17a8c1d98e,0x000e6b37f6beb8b7,0x000dbc72340b6c86}, {0x0007c19d37bb70ed,0x000f6867a99418dc,0x0000000000000001,0x0000000000000000}}, {{0x000a4a09f22c0fb3,0x000bb19cb6bc1256,0x00077d8b51c8ded9,0x000574809f35ca45}, {0x000bef1168ba7eb2,0x0002cdae11770b52,0x000ff68ed4f42bd1,0x0003d326b225de9d}, {0x00037f1445631a8c,0x00012cb14a3c371d,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b0b95f0603f03,0x000fa7f969adad66,0x0001acf774657813,0x000a2615220707f6}, {0x0002f71d4cd53712,0x000f82a44a2fd4ef,0x000773fd9e262931,0x0002f763ad200681}, {0x0009b206fe31fd70,0x000765c3a8767fa9,0x0000000000000000,0x0000000000000000}}, {{0x000a7f8ce84569e5,0x0009a821c3dd4741,0x000e90e3290cc915,0x000cf99306b623fa}, {0x000d7531760ae9e8,0x0009e7cf282874af,0x0006e1ae6527ae8c,0x0008f99eef73293d}, {0x00037109e03d3d87,0x00036ee1efdba892,0x0000000000000000,0x0000000000000000}}}, + {{{0x00051928ed074ce9,0x000b292af7a58dcc,0x0005ec5d4bdfb374,0x000cdd85d01fb1db}, {0x0006e626365656d8,0x00074fc478641e47,0x00016a5e28d244d6,0x000adbaa94ddb39d}, {0x0007fdde95fd5183,0x000b47ea66d8626b,0x0000000000000000,0x0000000000000000}}, {{0x0004c9d4962ab02a,0x00021388f7fd2b57,0x0006c23d66031232,0x000a1a6ab2ca0c2c}, {0x00017664a406bce3,0x000f5497442ca199,0x000866b6f2fc1498,0x000a41cbc3b0ab32}, {0x000557ca37a277ae,0x000af01602653825,0x0000000000000000,0x0000000000000000}}}, + {{{0x000db75622a8dfc2,0x0005479be9e5c74f,0x000548d39ec29bd5,0x0007942d29c79da4}, {0x00079c4bc1f5df3f,0x0004a7cecb948e1f,0x0008793b63229ed3,0x000939c1a7d67689}, {0x00057ad78be3b341,0x00052f2801351b91,0x0000000000000000,0x0000000000000000}}, {{0x000cbeae6fece889,0x000b3085ddee3b59,0x000eeab1d348140d,0x0006bba941a033c2}, {0x000b685703aafb67,0x0005046b6423a9d8,0x00075dab832a7c83,0x00015b8c259b9e24}, {0x00018a6bbb51f863,0x0003a253eb5dc8db,0x0000000000000000,0x0000000000000000}}}, + {{{0x000cca37a85cafbb,0x000b3657f26e3623,0x000787ec793c4d2a,0x000337f7520b9137}, {0x0000dbcfb7906436,0x00018cfaf22caa7a,0x00044625a502d754,0x0000066c6a130ba1}, {0x0001212f51d083e4,0x0004ebb9541e99d2,0x0000000000000000,0x0000000000000000}}, {{0x0009384f4e2ab22a,0x000ff707cf7953a3,0x000aa5f9b05bdfba,0x000626e81b083e95}, {0x000defb350599782,0x00092399d206f421,0x0008bd9415729d3e,0x0008cf10387904ad}, {0x0006e0bc19370ad7,0x000b48f2c002a076,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b8bb85d8adb3e,0x00067b9a142f9bd6,0x000fc51be0f979dc,0x000cb118f84e32d8}, {0x000a7f5b6ca36f9c,0x000a900f565e79ab,0x0003143fcfd2df63,0x000122db9b751516}, {0x00086015e5f85f9f,0x000bf0e7c48af6d8,0x0000000000000001,0x0000000000000000}}, {{0x000cbc466d0dec7f,0x000fcfc13f4daf5d,0x000613ac2b0043ae,0x0007d2ec60909041}, {0x000eff4b79cb6956,0x000e04188e57b5e5,0x00045aa9dd05dcf8,0x0007cd8106c6759c}, {0x0004b84b0c6c633a,0x00041ee796334569,0x0000000000000001,0x0000000000000000}}}, + {{{0x0008ed21f68b4a3f,0x0009e0f39b982afe,0x000ef033664df945,0x0006109c1245ad2f}, {0x0004d6578f9c34c2,0x0008e9fc097b7383,0x0007b3121a085c72,0x000365666df584bd}, {0x0007af58ed558596,0x0007e9fd1e18ec9d,0x0000000000000000,0x0000000000000000}}, {{0x00017df29af6bc16,0x000dbbf468848de7,0x000d747cd3b7c888,0x000801a051097e9d}, {0x000f68bb9b824e70,0x00027a8a5f172bbf,0x00074f9f45d5351c,0x00080ba6fcc24020}, {0x000d4e050d7e5a57,0x000cebcb9d2f1cc1,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b990fe3b9d773,0x000eb81096bf3df2,0x000eb580e653b2d5,0x000cfd31a2ad7396}, {0x00065cddd150bca4,0x000cde916b4cdae8,0x00019b56ffe74e35,0x00021e7dc0b21b6f}, {0x00099d8bf333016e,0x000eb146cec318c7,0x0000000000000000,0x0000000000000000}}, {{0x00030acdbab36d51,0x00089ddd1e911c98,0x000891db5801a0df,0x000f1a5d646bbddd}, {0x0000ac4d27510e25,0x00044af2f910d55b,0x00024a75bcea08e1,0x00037ae5f37d50da}, {0x000d372739ad211e,0x0002a2d9d5c41773,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=121 [{1,2,3,..,}]*([2^484]*G) */ + {{{0x000ce74763660052,0x000da3e409da1731,0x000098b5f715b328,0x0003538d607382a2}, {0x0007bc3ee7b0651c,0x0006d5eed9abf1dd,0x000eb18e8c0d16d9,0x000e3fe464dc1a4c}, {0x00030d6fa6b9f8f1,0x000cfa359d987d0c,0x0000000000000001,0x0000000000000000}}, {{0x00047d09810803ed,0x0007b5b97b578929,0x000cc27fc5005d73,0x00040feb2087e2c1}, {0x000b7dd0d960662d,0x00025ee555f37345,0x000d7c17f3858a72,0x000a0cf2ae739ae8}, {0x00000ee77dcf4e1a,0x000c12649e41ecee,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008de672d619b61,0x0000ea8326922a80,0x0001a0841b015626,0x0000f8a963e3e317}, {0x00037806aeb44acb,0x000d9d8a14334837,0x00026bd761a3419a,0x000d2e7a343fbffd}, {0x00086e32c6d361b6,0x00023ef433219c4d,0x0000000000000000,0x0000000000000000}}, {{0x00025620f22d4f25,0x00067dd5c03d381f,0x00080f734643a87f,0x00006c5ee876505e}, {0x0002b491baac4e49,0x0003e07deb178a01,0x000ad060f735b869,0x000576ce5dd8d75f}, {0x000dd4cd9c97cb18,0x000cbc634bbb55f5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000b9733710e8e01,0x000e73a5711788b8,0x000bf8afcacf73a9,0x000d6725ee57149b}, {0x000e7fe486c64e2e,0x000322f9087bd5a6,0x00009af08709418b,0x000084990390cb99}, {0x000a6bb3ab911d03,0x000d2868a69e665b,0x0000000000000001,0x0000000000000000}}, {{0x0005e749b382f6d2,0x000a9a1034406b89,0x000826ec06265b52,0x000e64e9aec95b07}, {0x0003982f9a9c5d16,0x0000698b37d7e83c,0x00050d8bbdbeb42b,0x0007c82f4fbc8ae9}, {0x000adc1e63d423d5,0x000b249310802372,0x0000000000000000,0x0000000000000000}}}, + {{{0x0007033614a6d5dd,0x000fddc5f2fac137,0x000e014aa4b4dee5,0x0004a9b72218fde8}, {0x000c10e229612a68,0x000cb5b99f1d9b66,0x000eff01796c1307,0x000ec087152271c7}, {0x0009f171d27930b1,0x000dd53091f21ad1,0x0000000000000001,0x0000000000000000}}, {{0x0004c873e4172f54,0x0006ecbd512368a7,0x000d3ea21d4bc31a,0x0003a95f62eff689}, {0x0007c73a33474bd4,0x00088fa97a141350,0x000b4d3b01846eff,0x0005fbac8f6a8f06}, {0x0009ddd58dc2a301,0x00001f7b911f1a15,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002e681058bcd0b,0x000ecb766f6bc98d,0x000866fedccaaef5,0x000b2e2473204d11}, {0x000f6e18757016ad,0x00011d59effc1a8a,0x0002050629e88cfc,0x00093c7bdc024782}, {0x000a9b2aeb9bb00e,0x000336991f06d2c0,0x0000000000000000,0x0000000000000000}}, {{0x0001568955531744,0x0008281170681859,0x00050d7be99cf6e1,0x0008cb9d185c0963}, {0x000f49cfc22a2afc,0x000f9d20626a2a56,0x000ad87b48f04b95,0x000bd1441cc30d3e}, {0x0003e9b72d43f56f,0x000e3b3843d17383,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e873b05f77e97,0x00071d5ebf3c8d2f,0x0005b9ca7cc32fe3,0x0008798cc245b054}, {0x000e6eaf83f8b265,0x00061d87bdf09afd,0x00048a529e1b9707,0x00001501c97ba4fd}, {0x000ca96655ab0a10,0x00042f0ec7beee1d,0x0000000000000001,0x0000000000000000}}, {{0x000296b82c7a9289,0x00070c171dfdb228,0x0001dac3a3a171bb,0x000b7ea6ad9a13af}, {0x000251fe361dde21,0x000cea9acd2f8b81,0x0008480e8df3c1ec,0x00038a5f495ca4b4}, {0x000fd225cb8ecc78,0x000454bc6bffc707,0x0000000000000000,0x0000000000000000}}}, + {{{0x000af33412f12687,0x00015e41163cf0f3,0x000967fdc5a6a476,0x0004235cf9f62e34}, {0x000b314d06a6a848,0x000820f5665619a2,0x000f11a14ea427a8,0x000ce9a80c44b6a1}, {0x000f92bed7985fca,0x000dc713540bdff6,0x0000000000000001,0x0000000000000000}}, {{0x00065826c0cb51e6,0x00030220ec95e76a,0x00064aea77a786d0,0x000cb5ba9e93c602}, {0x000f020c5b781189,0x000e7b4655282299,0x000e97af8ea95e4d,0x000a8a80a0f194a4}, {0x0006433581c41d62,0x00066e34a29ca8e3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cef36ab807b63,0x000040cdf4c99984,0x000c211953a5f8d7,0x000ab4c0faefc5ed}, {0x0005ca17066a1563,0x000fb2c0940c339a,0x000b1e8517a5667a,0x000c3d2a94a0b135}, {0x000185e4d4526e2e,0x0001b53c05d493d9,0x0000000000000001,0x0000000000000000}}, {{0x000c5ced3676f843,0x000195ff470fab2f,0x000ed29f4a221ddb,0x0000868b2d94f5fe}, {0x0003caf8fcc5069f,0x000dcfc1418631be,0x000998943a070623,0x0009bafa5f731c9d}, {0x000c5c56c1cc4a06,0x000a82f502e626e1,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=122 [{1,2,3,..,}]*([2^488]*G) */ + {{{0x0009edf282d019ec,0x00099e8e335e18d2,0x0004ace8ce0e046e,0x00001d0f72c0503a}, {0x0007e9c6d09e242f,0x000998b6c2fcb456,0x0000be40686ceb13,0x000db8fca6af9143}, {0x000c77e852236ef5,0x000ba3718e1a2901,0x0000000000000001,0x0000000000000000}}, {{0x0005ae430ab427d9,0x0003d8a843a1b6ab,0x000c9500fb6025f6,0x000b9cb8d803e788}, {0x000fcea023d9bfb7,0x00003f3ec5cdad70,0x000188da7e50d4c8,0x000f9eb540fd9c07}, {0x00014ab57822ee2a,0x000574aff12ba00d,0x0000000000000001,0x0000000000000000}}}, + {{{0x0003c20dbe0952a3,0x000480b6013f7fd5,0x000447348d109d4a,0x000fe6fecb6a7da1}, {0x0006564e8c529d8b,0x000034045fa60672,0x0003ee2a8df68fa9,0x00021796dbc7ff3f}, {0x000a130fededc279,0x000fe24c3f368ae9,0x0000000000000001,0x0000000000000000}}, {{0x0002961eb9eed66d,0x000919ed55f27279,0x0000068193a9b014,0x000f317444cb0bf8}, {0x00096e22227ee32e,0x00047c8b854cb4a8,0x000bf6dc6a73b281,0x000d6804296e2ed1}, {0x0003e6f8a77be001,0x00084c89b143ab22,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008d791f2d40215,0x00003b05d1fd525c,0x00037b16b3ca30ae,0x00070792a856131f}, {0x000b7639faf0f678,0x00006b7cf12eff42,0x00098ab7a44f2173,0x0006714e846ec06d}, {0x000eac350874a266,0x000b56e5920dc3ae,0x0000000000000000,0x0000000000000000}}, {{0x000d703e34853d1e,0x0002cd53a7cce717,0x000410bff4f394e1,0x00074ecb0bba0cc1}, {0x000de8fa9da2c436,0x000f5e3f74e2caa0,0x000cc28b148d1eb1,0x0009fc1ac5bad585}, {0x0001220666fb73af,0x0000c3241a57ee07,0x0000000000000001,0x0000000000000000}}}, + {{{0x0000e99218ea1f1f,0x000ccf21044500ec,0x0000c873630cba88,0x00064f806fd4e4b8}, {0x000a7056645dd457,0x0002ed87394551a9,0x0008987025ba6b17,0x0005dd01b45fa9a7}, {0x000ccea3a1f9f135,0x000592807cbab8d2,0x0000000000000001,0x0000000000000000}}, {{0x0006c96e8e24e119,0x000d921a51e8134c,0x0002ab9759957065,0x0004035ca89e1baa}, {0x000df057c2aafabc,0x000c0890aa1a6716,0x0006bd3f802387d9,0x0006a39383e5c778}, {0x000601e4e1f62705,0x000096f226577900,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001d3b5076ee66b,0x000068e996c31106,0x00063f8bf5d922ca,0x00008ed44203a2fa}, {0x0001df0821d991eb,0x00019d54e602f04f,0x000bf35cd4ee7bb8,0x00015f2609e3729a}, {0x0009e8e65b2fcd60,0x0001df9e9c109298,0x0000000000000001,0x0000000000000000}}, {{0x00058eae5edc3042,0x000fe31ba09cdc97,0x0006f52853b56fdb,0x0003df0f5ca36adc}, {0x0000a54940d61878,0x000902cef58665ba,0x0004efbb68e67641,0x00036806e0aaf0f5}, {0x000194a89e785e8c,0x0008883379ceb241,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001a19f7b341ee3,0x000076e0e5354bd1,0x0001806a485286dc,0x000d2bf681431840}, {0x0002c82334b1343e,0x000b6908add258b2,0x000737bf47a5dbe4,0x0007303c531a0b11}, {0x0003a29d6501615d,0x0009313aaea01e10,0x0000000000000000,0x0000000000000000}}, {{0x0007b22b906a725c,0x00024ad4ce011033,0x000bf242639d28fc,0x000fa39cd38de6c9}, {0x000a72beeb0f8fd8,0x0009a0ad9b93380e,0x000c8221fc799b7c,0x000be51116d9d8de}, {0x000a10526402ca53,0x000777aa2c9ac3b1,0x0000000000000001,0x0000000000000000}}}, + {{{0x0001a723455b8da2,0x0001d0c7c777796b,0x000fb41cc9b1644a,0x0000ef5ce0972939}, {0x000637a26ddcdf7a,0x0008cf1a639f0844,0x000023a3ce642ca3,0x00098f7db827cdb3}, {0x0005279eee7f6f0d,0x000565523e47e762,0x0000000000000001,0x0000000000000000}}, {{0x000fd1b034828d4a,0x0000721a61eafcaf,0x0001ce95f4ec0ae3,0x0003ba2db4a66fba}, {0x0006525e6f06fee9,0x000817b26fcb0ef3,0x0000265db68ac06f,0x000f74e811cb24b3}, {0x0006550f9c2bf885,0x0003940f2d2fcd83,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e8955d1b109b2,0x000e1de1d0f381d4,0x0006407a6cf45a79,0x000f2393e689a76d}, {0x000d3d92aed2a407,0x0005547cc6ac261b,0x0005e0b9e62fcac9,0x00081e2910774983}, {0x0003d6780dde8f90,0x0003c5c4cab77f7b,0x0000000000000000,0x0000000000000000}}, {{0x000e052d3f3dc82c,0x00039caa1aeecdbd,0x00024153092958c9,0x000c11b7ca5c0f7b}, {0x00027c92847965c0,0x000732af643698d8,0x0000367351c0ba1d,0x000f1b1bf491a3ee}, {0x000df3514ec2302c,0x000b4c4436d640af,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=123 [{1,2,3,..,}]*([2^492]*G) */ + {{{0x0004265bd7179d88,0x00032014b97128c5,0x000fd3dafdfe0b08,0x000b1956b3fd6699}, {0x00091416a87bbb8b,0x0001dd4344038f86,0x000566c88826c840,0x000f07a8a4b77456}, {0x0007671e1b2fca59,0x000200797dc52a03,0x0000000000000000,0x0000000000000000}}, {{0x0007843bbe8d7f70,0x0004f9ee9b4c465d,0x000303b1652fa39c,0x000ae7c4c4a55ae2}, {0x000263ccdcb67c15,0x000a17fd06da8ac5,0x000c10d8d1d1e927,0x000e5bfc6232685a}, {0x0003162cd048bbb8,0x000b11c2cffebb23,0x0000000000000000,0x0000000000000000}}}, + {{{0x0002cb202ec3c178,0x000285de81ad92d1,0x000b71b77497dfd0,0x0007a8a10c150a03}, {0x000bbe99f4ad3f59,0x000f4533b0aef51d,0x0003b27838ed4931,0x0008ffc95a8ebcf1}, {0x0002cefcf5623ddf,0x00010737c166832b,0x0000000000000000,0x0000000000000000}}, {{0x000e740d8da2ff7e,0x000624f3d3ab048c,0x000376415ced03ed,0x000fbe5676391c7d}, {0x00081671ffe7b22f,0x0000390438cc5f49,0x00084a5ae289dd49,0x0008f9a1f5bbef09}, {0x000b05c4941c6652,0x00083aef77ff073e,0x0000000000000000,0x0000000000000000}}}, + {{{0x000604a9bc6900b6,0x000878e5f51ce9df,0x000b763f98cad97f,0x000f5a1389d3ab54}, {0x000ab3d0efdef6fe,0x0009be5cf0df2543,0x0002a0d518696763,0x000134850193d832}, {0x000860abf9047761,0x0004b4f04b3d8de0,0x0000000000000000,0x0000000000000000}}, {{0x000e57c44a551894,0x000a3fa66238e065,0x000d140af7878a12,0x000de14d55dcc858}, {0x00061c7b391cc65f,0x000d7dbf324d8825,0x0005d09aa74e78f2,0x0008ed166a4503f8}, {0x000da0c2a7ad860c,0x0002048d8fe387e6,0x0000000000000000,0x0000000000000000}}}, + {{{0x000505ddc7162a8e,0x0001fb5ed0deab66,0x0005e972cc689dc5,0x000e495fb69dc78b}, {0x000ca3f1826690c6,0x0005f6186896d605,0x000fd32f66789288,0x0008863f96f8edfb}, {0x000e644e5dece22e,0x0009b7f857a4d564,0x0000000000000000,0x0000000000000000}}, {{0x000691ddbeebfc5d,0x0005901566a70055,0x000e1f4e6067fa43,0x00086e62796a672c}, {0x000b4e5ee14cf308,0x000b327c1a40aaca,0x0002fed3294bd689,0x0009103e56992c00}, {0x000b1323df8494f5,0x000d7b51fec2bb9e,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009f1b91641749a,0x000415c17bca5ff6,0x000c6d3a845d2248,0x0005f9b6f404856a}, {0x000cbf400b63630d,0x0003b4ba273b60be,0x0005d238fa843e67,0x00015df9fe916d32}, {0x000747b338f22dd6,0x000213df0dde0478,0x0000000000000000,0x0000000000000000}}, {{0x0000235c1fe8e923,0x0003196a6c0855b8,0x0009e7caa33347ee,0x000bc0a45596b47b}, {0x00011e3fa8377c58,0x000acaedbc6f8b16,0x000fc365c99edd72,0x0002dbbec0f6e0a6}, {0x0002b70a4b7723c1,0x000a4bf65f3c20c8,0x0000000000000001,0x0000000000000000}}}, + {{{0x0004bf14c1a4d603,0x00062d773ba946d2,0x000a858973ed2e17,0x000af47e821e4637}, {0x000c4e2f1b685a3b,0x000a24d7fe743f00,0x00011c916f0b3711,0x00019d3f29631796}, {0x000070eeb3ea27a8,0x000fcf9d0e9d8d24,0x0000000000000001,0x0000000000000000}}, {{0x000a9e0cc6d6de0a,0x0007d8c5fca34ad4,0x000c81d46494c7d6,0x0008c618856d1751}, {0x000ea22fc514e835,0x000e085f741c8235,0x000c321d004a049d,0x000bcb516087e553}, {0x0002d6363ccbbe68,0x00083e572fe7f6b5,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e20ba96faf5c5,0x000e8d8c8a0cc4ab,0x0009b5c593a344d4,0x000c6c34af049395}, {0x0005aa8d456d94a3,0x000ed953bf7c9473,0x000962cd0b8cc1dd,0x0000c01bb3088b5c}, {0x000c82c42c7d7139,0x0005bd26c576d9ee,0x0000000000000001,0x0000000000000000}}, {{0x000ee2f364e79144,0x000e681f5a9a561f,0x00014c6812d4021d,0x000e552f50051d32}, {0x000f6a99f35033a6,0x000e505a2349153d,0x0001622a1be8e97e,0x00067971f625164b}, {0x000d441d9fc2328e,0x000d2eb0550478b4,0x0000000000000001,0x0000000000000000}}}, + {{{0x000769c73aea3c08,0x000df9a9593240cb,0x0004e8217f3b057c,0x000ceca2220054ab}, {0x000c95ba1c2a734d,0x0006500d1322b719,0x000ec571b4360381,0x0006f76e87cb0ba1}, {0x000c5938559db2c7,0x000397be033b5877,0x0000000000000000,0x0000000000000000}}, {{0x000b6a77feb075ca,0x000d9cc6a6cde3dd,0x000e49872538f578,0x000e469feaf37819}, {0x0002ddc9c48cda10,0x0001a6e5450f9883,0x0002d31bf05ea5f5,0x000375cd216a195d}, {0x0008007e689987c4,0x000cbc358f3e07d1,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=124 [{1,2,3,..,}]*([2^496]*G) */ + {{{0x0006a73f6f2770c4,0x0000f968ca281cd6,0x000827efca6a0867,0x0003a96b180e8f32}, {0x000809979b757eac,0x000d9223bfbff7df,0x00047dd166015fc2,0x00065475a88730d7}, {0x000ce16229ea9d12,0x00076d23756de3fb,0x0000000000000000,0x0000000000000000}}, {{0x000ed537bee27c6e,0x000943e46c7c15a8,0x0004b3f87656d7df,0x000a9213335be530}, {0x00076cb0ee208db8,0x0004f5fc16b61ee3,0x000c1114ee85495a,0x000253ced62c2d47}, {0x000641c92453ad35,0x0003e4e1a21d73af,0x0000000000000001,0x0000000000000000}}}, + {{{0x000483ff2c9de102,0x00017f0cb9492bab,0x0001999673c19107,0x0005c7a75ba40ad7}, {0x00022ec8c1ec861f,0x00078704457a9540,0x0001194ab6d023c8,0x0000daf5008c607c}, {0x000d394925361233,0x0005ab5bf20a934a,0x0000000000000001,0x0000000000000000}}, {{0x0008ed3301b16277,0x000b31045574d7ab,0x000ed11cb44f38e3,0x0001af67ab10bb4e}, {0x000d033cee10ca51,0x000549874c9fe7c1,0x000392d6999489f1,0x000ffcfe4a15a85b}, {0x000b006a13684dec,0x0007b8baefda3eb3,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e82cbfe7306a8,0x00002e52832eb494,0x000b381c8b461b41,0x000a6e877f0afbca}, {0x0006b8482ae88f1b,0x000709eb28c8cc07,0x0000cd45fc8e5ced,0x000b1363d1cf0c64}, {0x00093a63d6be8f78,0x0001407a8e7f6a49,0x0000000000000000,0x0000000000000000}}, {{0x000fd703c088bf64,0x000708b3415df01b,0x000f82eeb2c8b57f,0x0003ed35407aa69d}, {0x000449767c6b4a72,0x0002e1a8184dbc3f,0x000d25edffc3e965,0x0003e8855e29ad89}, {0x000c695a889f2e49,0x00025dae2a995ab2,0x0000000000000000,0x0000000000000000}}}, + {{{0x000c300d63dacf22,0x000f84149cc93249,0x0004f71e87a984e1,0x000ebeada635f884}, {0x000cac51f48942eb,0x00076c6b878d815d,0x000587460dede95b,0x000883c91cf8c3f2}, {0x00013e9be5375387,0x00076d4ce987a56d,0x0000000000000000,0x0000000000000000}}, {{0x000fb20151675f42,0x000bf54bf1c2d622,0x00022da7f9e8bc4a,0x000051b0e7b83f3a}, {0x00073eda536a6e42,0x000ce8431a9d89d5,0x0002b7a64d23c5a3,0x000007a6be7b3eec}, {0x000672919b5fb43a,0x000c454a7d18005b,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009f484a29e97a0,0x0005e90aa411ba92,0x00016fc135a72a99,0x0006cfa3c8dd8a3a}, {0x00066efeed6df222,0x000e66eb40ebb1a2,0x0000f8ad15ad7b0b,0x000e0c3a19929e39}, {0x00051e3404d13a05,0x000175cf393bacd1,0x0000000000000000,0x0000000000000000}}, {{0x0006cdbeb4d89814,0x000b884f6ce10295,0x0003138d1321a20d,0x0006528c4bd065b9}, {0x0003d082878ee395,0x00029465651ab383,0x000cb4e49e6b0dcc,0x000710248d30e955}, {0x0006e01a51ae9cc3,0x0002fc5567eab89e,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c59218072f54a,0x000195bad5f014fe,0x000deabd55429cb3,0x000b2ab5fb9c1406}, {0x0006cf39524ff8ca,0x000fbb57c01480bd,0x00018cbc932f5376,0x000c9e4e5da034f1}, {0x000fb16c36eb8d83,0x000048c80fc4eaa6,0x0000000000000000,0x0000000000000000}}, {{0x000668aa11e1cfe6,0x000d4f614afa98be,0x0004cadab479a412,0x000864b0b94d7822}, {0x0002651053a74933,0x000dd43fe6424e5f,0x0004f2c600bdaac3,0x000ec0b432ccf8a0}, {0x0004d82574257110,0x00024e58edc3e12f,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d5163c2f29845,0x000271b8856ff717,0x000a79d0557c5c08,0x0001484032810d21}, {0x000a5a6e95174165,0x00093b8782ce8f06,0x000a6f7f14b15d03,0x000ca398eeacdf3d}, {0x000eb31c7c040c1a,0x0003ace9ed34f4d2,0x0000000000000000,0x0000000000000000}}, {{0x00086bac2cc4ff50,0x0008d5294f7bd063,0x000ec0b7a55f986d,0x0006868155592285}, {0x000e215833824965,0x0003366d9a307162,0x0001de9196efa150,0x00076afbb75f7833}, {0x00046ce65ce11aa8,0x0002f7a207e31942,0x0000000000000001,0x0000000000000000}}}, + {{{0x000d6129f7d0fa54,0x000150bddf5a7cf8,0x000b4988625b2f43,0x0009bbfb3c2f3809}, {0x000f5b080f7b3129,0x0000ab0abb84ed45,0x000510d824f7bed2,0x0006d6447243533e}, {0x000c576b7b64fbbb,0x000e16caa9ee8267,0x0000000000000001,0x0000000000000000}}, {{0x00053a269ea0b07f,0x000e06f68fe62242,0x000a777b6874572d,0x000d5f86cf599bf5}, {0x000fe2a811045a16,0x000873264294a33d,0x0007a04ac970a0c0,0x000ceb2b7d05d686}, {0x00029a28a0e51a57,0x000bacbf79a38ead,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=125 [{1,2,3,..,}]*([2^500]*G) */ + {{{0x0003efe866dc2f62,0x000853cb9e407c10,0x0000e6c71edaaa13,0x00018f751b70a2af}, {0x000b0cf7e3e825ae,0x0005c36a5a1ec11b,0x000487f56ab4b564,0x000a86df052ea4e5}, {0x000d750313868ef9,0x000e60ee422740c7,0x0000000000000000,0x0000000000000000}}, {{0x000ee652bd47edd5,0x000397faa97f40b7,0x000294d2d1ba3dd7,0x000344d3453daecf}, {0x000d324bd3f56e65,0x00078c6f611c9985,0x000e24f2675985ec,0x00038b4060d38ad7}, {0x000dfb7496c92821,0x000be627a6ad57ff,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009be6a7e5a166a,0x000d06313031bd58,0x000704962d984289,0x0002ec5b522512df}, {0x000386a669eef493,0x000fe747674db075,0x0004dbaabd7aebbc,0x0004d27fb22ce794}, {0x000e70494458ef81,0x000fadc96805636a,0x0000000000000000,0x0000000000000000}}, {{0x0005b60c511b3ff8,0x000584915adb1e6c,0x000f8937e8e108c6,0x0008406d64ea3a9f}, {0x0004461d268f9ab8,0x000e3ff279d6126f,0x000d3b3ed1f3032a,0x00023a1b63af22a5}, {0x000caf9282fd7a53,0x000d99f7a42a7590,0x0000000000000001,0x0000000000000000}}}, + {{{0x000dfb005014a6bc,0x000d36179f05f79f,0x0001f0a00c591c70,0x00009f861bdb8aa0}, {0x000851877e4cc13b,0x00004921bdab098b,0x000265f47ca34718,0x000478a5d59cb874}, {0x0008aac74eb734d8,0x0002f6a87e5bc7bb,0x0000000000000001,0x0000000000000000}}, {{0x0005dd559082ec4f,0x000fd3340b409a63,0x000e395e6174cff9,0x00035fdf83237476}, {0x0006e995df5d90e4,0x000535beb0acf902,0x000ddc2f60fe3f20,0x000821d68a60c3ba}, {0x0008005435d079f0,0x00084ef7a20c388b,0x0000000000000000,0x0000000000000000}}}, + {{{0x0001ce9624902c85,0x000dacee54d7fc06,0x0008e982883e676d,0x000cea68fc5997cf}, {0x000b94f3d06f1e8c,0x0007b80d8242831b,0x000ec2e625c36045,0x00015466a1d87389}, {0x000c5009313ff25b,0x00045efb5d45d1f9,0x0000000000000001,0x0000000000000000}}, {{0x0004e32c6f246301,0x00064608ec78b5ab,0x00053a9c0b324014,0x0004ddead5ffb795}, {0x0008bf933bdcc559,0x0005249289dc110f,0x00047d25d52f652d,0x000d95ab06c0cb41}, {0x000bbff17968adb2,0x0002664039be6fa1,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006c159dee64527,0x000d486c1da85118,0x0002ffecac887f87,0x000401c5326e8ac4}, {0x000fe68a082d270a,0x000b17b4ec0bd703,0x0009b1a9fe82427b,0x0008f75c6b25d502}, {0x000ac56e28859df5,0x000bc70f97f9bffa,0x0000000000000001,0x0000000000000000}}, {{0x00073b932e4e3e21,0x0005f8e721dc13af,0x000825bde1498f11,0x00080fd3102f60c7}, {0x000f292e5a9e9f07,0x0006a4edbc9fcac3,0x0008f2651ae44279,0x0002622ca1bb123f}, {0x000a4ca103d2d6a7,0x000ca577d0f1994f,0x0000000000000000,0x0000000000000000}}}, + {{{0x000e577af10e1302,0x000156bf557eaa33,0x000ca7cba0f98005,0x0001e9d6e3d41486}, {0x000ad3a30b9f973d,0x0009856b55aa3443,0x000724f819219409,0x0008250cf13f0ca4}, {0x0006f0f69ba1696b,0x00063bba1deb1e9b,0x0000000000000001,0x0000000000000000}}, {{0x00037cb6672f9435,0x000d7e7437eb08a0,0x000579149c6faf55,0x000e4c6943f7c61c}, {0x00026eba03e36921,0x000a3ade34c342ab,0x000052386264eb60,0x0000ffc57653cf12}, {0x00070eec7914e6e2,0x0004912d67845657,0x0000000000000001,0x0000000000000000}}}, + {{{0x00006fc3e072e1bd,0x00066e9739a62b31,0x0006ea97e6ad1669,0x0002aa2bbc843284}, {0x000871768bc4f0fb,0x000a51f2d1bd1f5f,0x000245a8890f99b0,0x000b6a0000aa5f53}, {0x000547c1538e0dc0,0x0001c33dbece2149,0x0000000000000000,0x0000000000000000}}, {{0x000b56de17b97c51,0x0000fccb15a8e3ea,0x000c00352a78e0ff,0x000e7d480dae3bf3}, {0x00092273cee30716,0x0000962a4283dde8,0x000e674e18ae53b0,0x0002b8c78835cb2c}, {0x000faee271217641,0x00046294e0f5e7c6,0x0000000000000000,0x0000000000000000}}}, + {{{0x0005697612d854d6,0x000590266d871a78,0x000015aa94be7df9,0x000482ac4e8bbf72}, {0x0007c12880439150,0x0003495f23aa4b2f,0x00074815ef777bb5,0x000838a798c004a6}, {0x0008a425cc7aadc8,0x000c432ccb5f5730,0x0000000000000001,0x0000000000000000}}, {{0x00006af85640f288,0x0003a6718ebc6cb5,0x0002c50bba9dd21e,0x000e3c4d56098fde}, {0x000a4a8a721857b6,0x000218f9c402f4d7,0x000a6f255530e5d9,0x0000bf7b3c63a541}, {0x000f0181b97421bb,0x00023de7a08f2804,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=126 [{1,2,3,..,}]*([2^504]*G) */ + {{{0x00061ebad9ee2c24,0x000dd46aced3ddaa,0x0000bd3e3fde5fe2,0x00020569fe14f9f4}, {0x00088d818d1a2095,0x0002f0bdc9b4968b,0x000e3de0b8b77328,0x0007fe9e8edc6520}, {0x000017cf0272ff76,0x000eda0f65dc99bc,0x0000000000000000,0x0000000000000000}}, {{0x0009b50b03dc034f,0x000ff04ea634ab0a,0x0007b191db6e6308,0x000a9de7ee04399a}, {0x000e6da7bdea8dde,0x00054c55ae492d45,0x000f4e939e666b7b,0x00090c925a51f573}, {0x000f916220292c15,0x0002d380fc7f5071,0x0000000000000001,0x0000000000000000}}}, + {{{0x000639a92b83d191,0x000b3a1ce7b1b453,0x0000d260e431474f,0x00032954aefab808}, {0x0006dfaf9e670c4e,0x000e42d0d7b5bae7,0x000bfa89eb4687fd,0x000c7d89b1ca5f45}, {0x000ecce4fba638bb,0x0008a21de873fcc0,0x0000000000000001,0x0000000000000000}}, {{0x000c9c2b49165fd5,0x0005fb318f9f9636,0x0006f676d6c2cb81,0x000c633a7560919e}, {0x00011e2d4752541c,0x000199c5999a79e2,0x000515dfbee081ee,0x00053107dec5265f}, {0x0002bdc9ed0ea4e2,0x00041c5a539ab36f,0x0000000000000001,0x0000000000000000}}}, + {{{0x00009de7ecb2ac56,0x0002d837bb7a345c,0x0004863cfd4369c7,0x00077c66a5755a3b}, {0x000682ccc872cef3,0x000bc1363c743442,0x0008b997f1a0d907,0x000d72224eed734a}, {0x000d1850457f924f,0x000f3bbd996258f2,0x0000000000000001,0x0000000000000000}}, {{0x0004953714391350,0x0002a08de1fb04ea,0x0009bb0ca7d3f0e3,0x00020e2fc4a54760}, {0x000d525812eece55,0x000dc3c7c680f4ea,0x00064f097079b269,0x0001e81a267b891a}, {0x0002df53061afa20,0x0007339d7335dbc1,0x0000000000000000,0x0000000000000000}}}, + {{{0x000fa11c22d57017,0x0007061bfc65866f,0x000e25c9a781f882,0x00052d54eb5d1a25}, {0x00034e5fcb1fe128,0x0008c5dfb74f3317,0x000cca2e48b7e54d,0x0005e9b41639cfad}, {0x000e1f8c2193402d,0x000348c49e8f71b8,0x0000000000000001,0x0000000000000000}}, {{0x00033ca43943f50d,0x00016ce98a1f644e,0x000bd595ac8a7cb4,0x000d4eb1e328cd45}, {0x000e8ec3fd8cbf8f,0x000eb626b0f768cf,0x0001524476b1bbc9,0x000d8d0ffe31069d}, {0x00025aa89220edd8,0x00063660b3755829,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003a78191abe914,0x000aed083110e37c,0x00072de9a657b228,0x0003d434d0dfafec}, {0x0009778c8ba568ce,0x00021f193e09ab8a,0x00032b59891165df,0x00090a0e20c8f7ac}, {0x0005b8a1f64088c4,0x000b717ed2f2d69f,0x0000000000000001,0x0000000000000000}}, {{0x000ac4849a39a0ab,0x000e9224368b5d72,0x0009a57abd9c0589,0x000f04bfeb21218d}, {0x00049bfe57f2080a,0x00082fbca66b72d8,0x000f0c09eaa93852,0x000e04db305e15a6}, {0x000bb2bcc4365052,0x000d0e18047907b5,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003c1031f4f778c,0x0009bbc5cc621ce8,0x000ac957c67434bc,0x000a368627bcbc47}, {0x000adace0a905430,0x0008aa0831ed2cb5,0x000c11d0f4f5d323,0x0001c48e91c91fa3}, {0x000229765edbfb35,0x00032bdf2591e498,0x0000000000000000,0x0000000000000000}}, {{0x0008e455572bcfd0,0x000ecba53bea9ae3,0x000196518c997db1,0x0005c33258970b56}, {0x000a3c6b46d1e689,0x0008e44ad30fe772,0x0005dd6482160561,0x000b86d1933faf1a}, {0x0005a53d718ae6de,0x000e4e4345a6badf,0x0000000000000001,0x0000000000000000}}}, + {{{0x0009f15950170034,0x0008a7d9e0681bfb,0x0002dc602830c283,0x000e8af178838dfd}, {0x000987d3f8bcc134,0x0008904081cb94f3,0x000a460c0da2bca6,0x000f718b8913d63c}, {0x00022ed274e647de,0x000ff3a58fd52338,0x0000000000000001,0x0000000000000000}}, {{0x0002950ff4836dad,0x000fe4a51fa111b5,0x000e13de206b61a9,0x000941373ab42508}, {0x000c7bf8c1651d7a,0x000dbd9276666a02,0x00056dcdd411c37b,0x000f5a9ab3e87536}, {0x0000f464671775e6,0x000bc59bc827eaae,0x0000000000000000,0x0000000000000000}}}, + {{{0x000eafce57fbc903,0x00072ba11885f40d,0x000d640aa98f9421,0x000bfcf817ce6b52}, {0x000389d8e40bcdc1,0x000c804e7d14a7d6,0x0008fa880e955163,0x00034af7c92b6304}, {0x000fd685115381b0,0x000faf73ec6a9688,0x0000000000000001,0x0000000000000000}}, {{0x000f85d1af3848b2,0x0008716ba36666f4,0x000fbfc6c17f47de,0x00003b35f9474540}, {0x0004b72b1ddc670e,0x000f48bdd3ad6387,0x000d7cfd249ea687,0x0009c16141926a15}, {0x000d8d963e9d101f,0x0000771b9b1c2fac,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=127 [{1,2,3,..,}]*([2^508]*G) */ + {{{0x0006bccc65f30461,0x0006e44b51d15f3b,0x00061b0ed084d989,0x000f84c9df4f3be0}, {0x000626ed8e29bced,0x000a49395cf45bde,0x0001bfb128499bea,0x000d30e7b9a9812a}, {0x0000016d9442e44b,0x000577251b4710e5,0x0000000000000000,0x0000000000000000}}, {{0x000c58ea8faa5f8e,0x0006398972e1afb4,0x0002d603c3a6a3b7,0x000090f464b41953}, {0x0003e1c1cc6d5ad6,0x0009fc4551644bda,0x0003bf0e003b3c67,0x0004879a2d4dc4fe}, {0x0002492059f3993d,0x00089490933a0bd0,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003d39ba21abe88,0x000b8dfe497366b8,0x0003fb2e32d1a08b,0x00040dcc68fadea4}, {0x0009bc78d9e5b900,0x000999242f620135,0x000e38d4ca94e098,0x000f3e9a937783f1}, {0x000c271edf5e42de,0x000cdad3d42e09c5,0x0000000000000001,0x0000000000000000}}, {{0x00014caf1b7e4897,0x00092052b710207f,0x000840b578b42fb2,0x000c859d4e0acb78}, {0x000efbd1059c69f5,0x000fc0d187f5ce1f,0x000018dd99b98e1d,0x000fd9d695b6b702}, {0x00087f7037056ff1,0x00080b73121d9b11,0x0000000000000000,0x0000000000000000}}}, + {{{0x00078d674ce9ba28,0x00098667edd1931d,0x0007a2c798ce814e,0x00054444ef1eef63}, {0x000bbc4342cdf2cd,0x0008690dad1f9bf2,0x000e17a85c72b72f,0x00027215c615b685}, {0x000ab98eb37dbb69,0x00072850ebda62ab,0x0000000000000000,0x0000000000000000}}, {{0x000b543dc482d1d8,0x00066dc72bee2f05,0x000576c719cbc26f,0x000bf9361970fe88}, {0x00012aede3868858,0x000d0a81339054e9,0x00050f3227db12ff,0x00054f85925da234}, {0x0007c4995e06e9ee,0x000343899d0c96c8,0x0000000000000001,0x0000000000000000}}}, + {{{0x000622bfd7a6e63b,0x000ca212bebe9c89,0x000487abee2cafd2,0x000143f4d290457b}, {0x0007d05d13bf4c04,0x00067f0ae3716aab,0x000a3097740d4130,0x000debe6d02d5925}, {0x000ef2c2714370b8,0x000fcffae20be9e8,0x0000000000000001,0x0000000000000000}}, {{0x00009dc727eac0b8,0x000802b463618a8d,0x000e00f824949d83,0x00021e8850666aae}, {0x000a354be3730d5a,0x0006ce164b258522,0x000386cbf3fd223a,0x0000b7ba5ba4fefa}, {0x0008ecff5479bc6a,0x000ec6ece410bb37,0x0000000000000001,0x0000000000000000}}}, + {{{0x000fb0fd2b03ceeb,0x000c34d346742d91,0x0007fb1da808f925,0x00014c3e50e576d5}, {0x00045dde45aec274,0x0007634b06ff5225,0x000e8f635cfee4ae,0x0006af16b33722c1}, {0x000b6c9512df9861,0x00087905f5ba1ed3,0x0000000000000001,0x0000000000000000}}, {{0x0006849e44fd7308,0x000ca8c188190c88,0x000568eece8b82ee,0x000afcede37dce03}, {0x000956f0105616d6,0x000fcd4f42159b96,0x00016a63204d42e3,0x000f90e66b95446b}, {0x0003ff7137d7895f,0x00015f08ed8c3b6a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000080c877cdc551,0x00063fd88170e394,0x000069a5394fa226,0x000fe13aafd4abd3}, {0x000aac77685a1a56,0x0002270caf504acd,0x000b15ab3b28bcb6,0x000ff30df2535d28}, {0x000dad1836a25af3,0x000fa6c25940501a,0x0000000000000001,0x0000000000000000}}, {{0x00072e0f5dfd0431,0x000680aa3b20ecdb,0x000be825e1b5fe43,0x0005a5c2422130db}, {0x000f0dc02a5e8b8e,0x00053d6d0a6ed0ac,0x0007b39bd52bad22,0x000defc7beec9197}, {0x000d80e249e46059,0x0009869fd32b5153,0x0000000000000000,0x0000000000000000}}}, + {{{0x000d5488a9c159ea,0x000c7c99f362daa9,0x000520e4056562a1,0x000f58587c3780d4}, {0x000cf122d12decdc,0x00066fa3df2e094a,0x0006c99c7f2dc2a5,0x0005a3f3e1f8fe88}, {0x000ead106c542a2f,0x0001bd548c70f9bd,0x0000000000000000,0x0000000000000000}}, {{0x00025e9e39905a6d,0x000d9b4651431540,0x0007d3343ac64109,0x00071e3dd6b3d33e}, {0x000a550593155d88,0x0005e988444776c0,0x00092c204b5ef211,0x000132ec6af46f8f}, {0x0000975bc42ba82e,0x0000ec605e3e60a7,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ebdae497fc314,0x000068fcc42342b8,0x0002e8a76fa0addd,0x000d98aa1ba58a99}, {0x0006f585d2056972,0x0001a667125a290a,0x000e664a47990be5,0x0003e44696beab19}, {0x0000ab4a22f64d1c,0x00054a0b8ce48449,0x0000000000000000,0x0000000000000000}}, {{0x000cf9a538895145,0x000e7e3b3fd1990a,0x0001c1f1592daaaf,0x000016843015bdb3}, {0x00095b2dbb2d0adb,0x000f77ef5d670d12,0x0008bf1b3f98aca3,0x0003b5280fd35140}, {0x0007a58660b5ee9d,0x000f86e58791223a,0x0000000000000000,0x0000000000000000}}} + }, + {/* digit=128 [{1,2,3,..,}]*([2^512]*G) */ + {{{0x00031c51f5b59b03,0x000c7665ab584951,0x0008739b754d5115,0x000b253e840523eb}, {0x000078a1f77e3b96,0x000742a046765d97,0x000823d7e942e5b8,0x00080b3194bd1539}, {0x0002679bf560b997,0x00061abda6ff32b5,0x0000000000000001,0x0000000000000000}}, {{0x000820e93e66dad8,0x000f2c881e08a892,0x0007e5fd839208f9,0x000d25804e86968c}, {0x000fc76aeb554305,0x0004c686c9b44037,0x0002e51b80d02e02,0x000e5774d5a620e6}, {0x000000eae653df90,0x00072ac9b31961f0,0x0000000000000000,0x0000000000000000}}}, + {{{0x000f8d7860917b4f,0x000bb3357359429f,0x000995f4b0a05d76,0x000e0f1c58d0fe01}, {0x0002921dccd2ee40,0x0000ab0ca33af9c6,0x000637c074069c34,0x0002098a102fa30b}, {0x00037701844888bc,0x000d6cb2e96e33de,0x0000000000000000,0x0000000000000000}}, {{0x00070d506a96d190,0x000f2ce57ed3ba0f,0x0002492cf26e59c4,0x000305995879a0eb}, {0x0000675760ae93d1,0x0009f9d0d04103b2,0x000d618a2b740898,0x000e723e7b444b0a}, {0x000b80451ab5c813,0x000616305a1f27eb,0x0000000000000000,0x0000000000000000}}}, + {{{0x000b480b60680f46,0x00097a71a65ccb4a,0x0002360920f061e1,0x000428aeb306dab3}, {0x0005aee5267509d9,0x00058e47b1cbaf9d,0x0003350d9a6f7e9f,0x00035af36c30696a}, {0x000ff438c1f66ddb,0x000119d4937e17ea,0x0000000000000000,0x0000000000000000}}, {{0x0009df61e7821be6,0x000b8322655044ac,0x0001ae7bb1e106e2,0x00039508343bc8e6}, {0x000a2bc1e06e0991,0x00066bd6b8166453,0x00044e23756d0eb9,0x00003795c5a1b4bb}, {0x000605deb625fe17,0x000248426f42f1b7,0x0000000000000000,0x0000000000000000}}}, + {{{0x000ebb49b8b6d8d8,0x000c9576edd0b2c0,0x000089746d87ef78,0x000ee54686ff89a1}, {0x000cd51992a8e30d,0x000fcb70ff8362ad,0x00008d8883f2631a,0x0002a13e25b5a551}, {0x000d32baa9313847,0x00049764387fbe1f,0x0000000000000000,0x0000000000000000}}, {{0x000652373d0f2fcd,0x0007e9e1299928e8,0x00016c54d21ce8fd,0x000e62d7938b0123}, {0x000ce4d602bacad0,0x00055138cbf9df41,0x000e0e625dfe098c,0x000dbf9a6851bc01}, {0x0000b0da12bdbc63,0x000aec8b07cebaa7,0x0000000000000000,0x0000000000000000}}}, + {{{0x0006a52b356ba3e0,0x000fa486ee1abbf6,0x00074bf145f1f28e,0x000ef4af39b6c538}, {0x00084376c3d3f698,0x00007cbe4b46d363,0x0003db26e35a57f0,0x000ecc45a1933b62}, {0x0007b9610a9a44f8,0x000057b84f95bccb,0x0000000000000001,0x0000000000000000}}, {{0x000bdacb48b9bb6b,0x000642a5eb931fe7,0x00097c327f5fbd2e,0x000a3062ea3deca5}, {0x000a3dad9ef787fc,0x00092f83b35a8216,0x00042427945728d9,0x0007537c6394f3cf}, {0x000b615698a93762,0x0001f468793ceb99,0x0000000000000000,0x0000000000000000}}}, + {{{0x000217c6562eea14,0x000a6a042cb3da1e,0x00060f9ac91e9595,0x00013fef00e33063}, {0x0001954b4b6c8a05,0x00007e6bb37592ca,0x00018fef0e569527,0x000f4449441c7534}, {0x0003c8e93a050abd,0x00050bb02598e0eb,0x0000000000000000,0x0000000000000000}}, {{0x00044683d956af18,0x000340076bbbf06c,0x00006b8e5826911d,0x000bd47b4442693c}, {0x000bdbfb4883b7be,0x000a67f8d229f111,0x000eceec785481be,0x000d18ec8ccc0a58}, {0x000ed2b1cc9fd671,0x000ee9b77fbdfe40,0x0000000000000000,0x0000000000000000}}}, + {{{0x00033f2848525772,0x0002def8aeb9f6cd,0x0009c738e373fa1e,0x000ca3f54bf1bb33}, {0x0000dd3b12e5c621,0x000856fbe6604112,0x0004fa2d98399489,0x0000ba4686140d31}, {0x000be8a65034e7d6,0x000fc1d2c9034f2b,0x0000000000000000,0x0000000000000000}}, {{0x0002e0e02cbac5de,0x00036d1bbef4bfe6,0x000db812e9ceffa7,0x000c4f097569d138}, {0x000c2795f975ff41,0x000cfa1a794c9978,0x000e1e65c9b377a9,0x000e6d66f7a547fd}, {0x00058785dc7270ac,0x000b34d6e188dec1,0x0000000000000000,0x0000000000000000}}}, + {{{0x000a511d09de2eac,0x000031698e16faac,0x0002e96a74ccb4d0,0x000b85017b609854}, {0x0005887d91373679,0x00039fd4a56f39c3,0x000f60f3aea2bb2a,0x00084e8edd3fc7ee}, {0x000e1d001d481288,0x0003732f4d1fa989,0x0000000000000001,0x0000000000000000}}, {{0x000629c27855b7b6,0x000652d6fdccbf0a,0x0005f32800f6bc14,0x0007f62ad29c1358}, {0x000dbf3a9fdce69e,0x000aa9f4b69418d0,0x000e5fef492796fd,0x000332f4a27a525a}, {0x0001a7293d91d135,0x0006fadc6b1bb1cc,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=129 [{1,2,3,..,}]*([2^516]*G) */ + {{{0x00076fe9e4b410aa,0x0002e2e46e8257e7,0x000285dece1c90ea,0x0004f07e02e70a0d}, {0x0007d9e22652fd2e,0x000325ca4b7fb066,0x0001305e36daaa95,0x000feebe9d3d04df}, {0x0000e3be0fcd0755,0x0005f74f74e60357,0x0000000000000001,0x0000000000000000}}, {{0x000a7ff33f158714,0x00012737b93b28b8,0x000a408dc4f02791,0x0009c78d219fcf52}, {0x0008fbf0f03e3758,0x000d6cdb0c0bb10f,0x0007428d517b4d78,0x000d37e06b1f9904}, {0x000f8786ba69f3ae,0x000b508624d39698,0x0000000000000000,0x0000000000000000}}}, + {{{0x000314e66fead340,0x0009f5c35e0de977,0x00086281b424220d,0x00095c9d69b8f421}, {0x000075fd90a74e5f,0x000c09fc499a89c7,0x0004b64e12f34808,0x00068c161166a676}, {0x000f40cf1886f3c3,0x000c4968ad8aaa55,0x0000000000000000,0x0000000000000000}}, {{0x0001f4bec36790bc,0x000d77489002d4f9,0x0001759ca38e8177,0x000e759ae14e5a1f}, {0x000289005868dab2,0x000a1dff8ca02b41,0x000a4d82b9cd06ea,0x0004578741ea12d6}, {0x000343e8d641aef6,0x0002d4c6a85c8b1a,0x0000000000000001,0x0000000000000000}}}, + {{{0x0007c33639a0b3f1,0x000010f791b828fa,0x00069b98b785836e,0x000f9367ba2d3b6c}, {0x0005ecea4290d504,0x0003dd0621586083,0x000de6622ac6245f,0x0002d8153e71208b}, {0x00091cd77d2a1a55,0x0007ebc7df7c52cd,0x0000000000000001,0x0000000000000000}}, {{0x000fe4e1268ac84e,0x000d05fdf620f30b,0x00078c9c26de9aa6,0x000fef3a7d0e875e}, {0x0001f45acf57d581,0x0009769d1b4f2f3f,0x000f8a2b516d4fb8,0x000ca50e2afa7161}, {0x00069ea98a831731,0x000a4069e2a679a5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000573b5ab69b37b,0x00099e464e098a37,0x0004b6ae9bd2eac1,0x0007e83941109e44}, {0x000b3638c710996c,0x0005b0374099e6be,0x000e0cd0943a1c3a,0x0008fab6ecb18490}, {0x0009f0eb14e71bae,0x00011229f06246b6,0x0000000000000001,0x0000000000000000}}, {{0x0006e2d865b8fa8c,0x000e4ba2a3d8ca53,0x0004c428120f4f50,0x00003e5bcb6eaa4c}, {0x0006c69871129b42,0x00018bdacf6da13d,0x0006a314f621f852,0x00031ea900e85204}, {0x000d280193a13fa0,0x000437167b70a8c7,0x0000000000000001,0x0000000000000000}}}, + {{{0x000e47d41aa029d1,0x00083c1c1e4e8c82,0x000819d110bf6923,0x00080e340caaa47b}, {0x000e4f6e315e8cb2,0x000865960449f5a7,0x0002a736db3e3bf6,0x0008b38233a8c18d}, {0x0006ab95cab54c2d,0x0007b4670af6e721,0x0000000000000000,0x0000000000000000}}, {{0x0009cd8d15df2f21,0x000c9e95f873ccf7,0x000d4ae259b8946e,0x0003026a352c8cec}, {0x000c84b6773b4638,0x000327edc3574f14,0x000980243f9e1167,0x000c58a2e8d3fc2d}, {0x000e789b426360b9,0x00084beac487c72a,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a504d7a128f19,0x000bec706161d077,0x0008d3f449e0d717,0x00027553cd6aa437}, {0x00023bfa097584c3,0x00031032e9ecfed0,0x000de734abfe6661,0x0005972524c62301}, {0x00068a20ad67cd7b,0x0001d7d8e4bd981b,0x0000000000000001,0x0000000000000000}}, {{0x000dd411d75c8560,0x00020a136bd0f9a0,0x000e9c06f6a8521a,0x0001770134117a07}, {0x000c6625cc2c0b14,0x0006f01c93534fec,0x000bcd3698e9742e,0x000543a9724acea5}, {0x000820ced54b554d,0x00005a7954cbcc77,0x0000000000000001,0x0000000000000000}}}, + {{{0x00060a7aed1a8afb,0x00037a6526a7b404,0x000f752335e80ab0,0x000a8f65f14c43bd}, {0x0004f9b989eabd11,0x000976a80f23fa92,0x0000171f16dad870,0x000d3baaac454e44}, {0x000f34704b9635c0,0x00051b0e1ca863f0,0x0000000000000000,0x0000000000000000}}, {{0x000fcc07647c957a,0x0007e8420a4e5f40,0x000cec847e324cf5,0x000db2fe1f189869}, {0x0009827f88deeb20,0x00023c17a4487124,0x0009568284e63444,0x000010b9bfa3fe02}, {0x000626ee2d426c18,0x0006c496cbf2d807,0x0000000000000001,0x0000000000000000}}}, + {{{0x000a48e1016cc257,0x000e7a08472093bf,0x000b7492e4ec8ac9,0x0001bd1c471d73ed}, {0x000a7243428ce53d,0x0007d49d1740adec,0x000c66dd60077c0b,0x0005737593cb7a95}, {0x0007c6f6ef237e1e,0x000660a7929ff06a,0x0000000000000001,0x0000000000000000}}, {{0x0004bcc2e6c3da59,0x0003e87b3c416f89,0x00021231992a493d,0x0006d0824c0a5993}, {0x000e60d5c6c61f37,0x000a3430f29e1550,0x0005e81f1d1beb92,0x00027b6bc5ab11f9}, {0x000858c60a78bae0,0x000f95bdd9ea9017,0x0000000000000001,0x0000000000000000}}} + }, + {/* digit=130 [{1,2,3,..,}]*([2^520]*G) */ + {{{0x0008b69f6c0a103c,0x00014cb96747cd0b,0x0009e707ed23f30c,0x00092336029690c8}, {0x0002b884265ced12,0x00087e627555cfec,0x0008f62a097ab7dc,0x000df635118ea555}, {0x00070b69e23dda1a,0x00011d1b70ffff57,0x0000000000000000,0x0000000000000000}}, {{0x0002606bce985157,0x000cf38c9c6bbd4f,0x00058d1b308ccb92,0x000fb6fe2ce6913c}, {0x0005b1967bfefbbd,0x00053132fce5cb51,0x000b2f22527584e4,0x00082a1591dfc389}, {0x0002d57610460d61,0x000dc57498b0d160,0x0000000000000000,0x0000000000000000}}}, + {{{0x0008cffee5938175,0x000028a135a61fb3,0x0002c9fe1a18ac17,0x000b968e30418249}, {0x0000b4c958b813ec,0x00023285e86f834a,0x000b05e54df836f5,0x0008f77b5fb229e4}, {0x000371505e864d89,0x000fb3cce3c32e48,0x0000000000000000,0x0000000000000000}}, {{0x000a0e5e3ce8bcd8,0x000dc2fb74fd48c4,0x000875aaa2018996,0x000827185e9f86f5}, {0x000196642422b5eb,0x0006d6f0dd874310,0x000f5719d7e7982d,0x0005346044e6cb46}, {0x00002d250a348c67,0x0009ec517508afdc,0x0000000000000001,0x0000000000000000}}}, + {{{0x000145140a7a865f,0x000095ded9f8c118,0x00040df2b19ba498,0x0007dec03834dace}, {0x0009e3687e664a0c,0x0009d971f2feee9a,0x0008796a032ee720,0x0003a0b2cc310714}, {0x000067d48b65bcec,0x0007f5d8c2af6546,0x0000000000000001,0x0000000000000000}}, {{0x00015c856b094864,0x0004f779c821c5d7,0x00062cf6310bebe0,0x00086c833844c220}, {0x000322644f899899,0x00080ac439439357,0x0009f2dfd741ec2f,0x000c3022b589299a}, {0x000663af1bcf4790,0x000a46767587f6f5,0x0000000000000001,0x0000000000000000}}}, + {{{0x000cdfa0667f8929,0x00055eda7b7826f1,0x000dd93845997fea,0x00073f54c39699cc}, {0x000d85971fbd417d,0x000631f8049f08e1,0x0003b8e65a870ee3,0x000aa3cdc8e351a7}, {0x00099901454f69b2,0x0002d659cbe0fe85,0x0000000000000001,0x0000000000000000}}, {{0x0005bfaeb9c77879,0x00078817f6a7aa08,0x0001e5f6c61e07f9,0x000a5dffb271762a}, {0x000df5d3e3cd3cc6,0x000eadd52e895eb0,0x0003b342cd665b46,0x000393078c5b9252}, {0x0006202122ebcff3,0x0005f4777dd50c48,0x0000000000000000,0x0000000000000000}}}, + {{{0x0003fcdbd57bfa90,0x000d1b118dee98fe,0x0000a524ceccfc4a,0x0007420c6d1ffa5c}, {0x00053919d859de0d,0x00081fb74544af55,0x0007c3f0981d6def,0x00076680c297a17a}, {0x000d22135e0cc4fe,0x000d15de36e57af6,0x0000000000000001,0x0000000000000000}}, {{0x0008ae03fd78b0a1,0x000c06ac0c41950b,0x000c994e2c7c2638,0x00075a944523ebb6}, {0x0002bdb72a76549b,0x0007a73d0573310e,0x000ae4c8ce6d6b85,0x000e4309eb9e1e23}, {0x0008aedc0842f06a,0x0006ededf71264f9,0x0000000000000001,0x0000000000000000}}}, + {{{0x00047c62f7f81bbb,0x000568d4c38f8cbe,0x000085a52c049173,0x000151d87d057b19}, {0x000462de5c929612,0x0004036de18a4ea9,0x000290b0a8300ddc,0x000e195518bc5a6e}, {0x000e21097894ed83,0x000a74d8dd898c35,0x0000000000000001,0x0000000000000000}}, {{0x000eee2e29a47676,0x000325c0b89ddfd0,0x0000c5c995a8a7bf,0x0003e514a5131a24}, {0x00078e5998b6e957,0x000ba59336939798,0x00032157906f3c87,0x0001093cead5ff51}, {0x0003bc2e1b76588a,0x000a055abc03c824,0x0000000000000001,0x0000000000000000}}}, + {{{0x000c9d2081074b7d,0x000b4b234d223107,0x000c6fe7d17524b8,0x000b3e26469a9182}, {0x0001d35461f18688,0x0008f9ef1eb0f49d,0x00072164bb2130a7,0x00069240661ee72b}, {0x0004674d4ec1e4e4,0x000df195346b1529,0x0000000000000001,0x0000000000000000}}, {{0x00094d4cd2beae09,0x00021cf533e3fea5,0x00099051c26db75a,0x0000237aea1a808b}, {0x00066230cfcd19c1,0x0000aedfcfe63965,0x000965518cdd9349,0x0000446502d88c39}, {0x0006de0650de6be1,0x000c487b3640aa4a,0x0000000000000000,0x0000000000000000}}}, + {{{0x000315f2c4f3b202,0x000844f2e07c55f6,0x0009040fc8f62ee6,0x0006bb02af168881}, {0x000eea1922677aec,0x0003b90132968e4d,0x000b75f92b21f9e5,0x000b4ae4c1d62b9c}, {0x0000f373265408d1,0x00013d70be8f94d2,0x0000000000000000,0x0000000000000000}}, {{0x000c00995b2d1ac5,0x000acf4e16ae2b05,0x000d04ee882f20b5,0x000b5e061f8c5834}, {0x00040c9dbfe4135d,0x000f7b55b63a42f5,0x0003b47500e266e3,0x0004da6911e652ce}, {0x00043c4db0c53d0a,0x0009946052a6d7ee,0x0000000000000001,0x0000000000000000}}} + } +}; + +#endif /* #if !defined(_DISABLE_ECP_521R1_HARDCODED_BP_TBL_) */ + +IPP_OWN_DEFN(const cpPrecompAP *, gfpec_precom_nistP521r1_radix52_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 4, + /* select function */ NULL, + /* precomputed data */ (BNU_CHUNK_T *)ifma_ec_nistp521r1_bp_precomp + }; + return &t; +} + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif /* #ifndef IFMA_ECPRECOMP4_P521_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp7_p256.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp7_p256.h new file mode 100644 index 000000000..5bab5b848 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_ecprecomp7_p256.h @@ -0,0 +1,2544 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_ECPRECOMP7_P256_H +#define IFMA_ECPRECOMP7_P256_H + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" + +#include "ifma_defs.h" +#include "ifma_ecpoint_p256.h" + + +#define BASE_POINT_WIN_SIZE (7) +#define BASE_POINT_N_ENTRY (1 << ((BASE_POINT_WIN_SIZE)-1)) + +#define OPERAND_BITSIZE (256) +#define LEN52_P256 (NUMBER_OF_DIGITS(OPERAND_BITSIZE, DIGIT_SIZE)) + +/* P256 affine point */ +typedef struct { + BNU_CHUNK_T X[LEN52_P256]; + BNU_CHUNK_T Y[LEN52_P256]; +} P256_POINT_AFFINE_IFMA_MEM; + +extern const __ALIGN64 P256_POINT_AFFINE_IFMA_MEM ifma_ec_nistp256r1_bp_precomp[37][BASE_POINT_N_ENTRY]; + +#if !defined(_DISABLE_ECP_256R1_HARDCODED_BP_TBL_) + +/* Montgomery coefficient R = 2^(6*52) mod p */ +const __ALIGN64 P256_POINT_AFFINE_IFMA_MEM ifma_ec_nistp256r1_bp_precomp[][BASE_POINT_N_ENTRY] = { + { + /* digit=0 (1,2,..,64)*(2^{0})*G */ + {{ 0x0008905f76bdc7b5, 0x0007bd418a9143c1, 0x000c475d568abc1f, 0x0009a701075ba95f, 0x00003d1f32c8b4b9 }, { 0x000571ff18aafa5c, 0x000f757ce95560a8, 0x000434a7e54432f7, 0x0002797258b4ab8e, 0x00009df870e37032 }}, + {{ 0x0006bb32e5348a6d, 0x000d9d410ddd64df, 0x0000ad784f985075, 0x0008a23d9aa6ae3c, 0x00001fb0f13f1e58 }, { 0x0008c57751832101, 0x00047d361bee1a57, 0x000b725df8a6ac15, 0x000e32cbe152cd7c, 0x00008c240484bd0e }}, + {{ 0x0006936a3fdd92de, 0x00061904eebc1272, 0x0009e1ea17bc2219, 0x00038de98b027f84, 0x0000be1daceb9daa }, { 0x0005f06a2abb7836, 0x000261fc983a7ebd, 0x000c327193eff4d4, 0x000b6b38e583e47a, 0x0000315e09d4065e }}, + {{ 0x00077362f599237a, 0x0003b0d46918dcc5, 0x000d6eb05e7ddb8d, 0x000ec90f24650a6e, 0x0000604e8ac3b74e }, { 0x0004b14c39d10c04, 0x000ee4ce4cbaba68, 0x00017625a80d5c8a, 0x000d1ce2e1762847, 0x00009cb7c6eea514 }}, + {{ 0x0009079606520cb9, 0x000d1aec45c61f5c, 0x0009cbb1bd776c0e, 0x0006a090c90ec649, 0x0000ce1d21d8a47e }, { 0x0003a076bba1725f, 0x0003c4ae7ba4f107, 0x000f724b117049be, 0x00007c06873c568e, 0x0000d1631291cbdd }}, + {{ 0x0003074b59672881, 0x000c6373e77664a1, 0x000f2165a2e4d910, 0x000ef22ad55ae744, 0x0000cd292bcbc0f3 }, { 0x0004c9916deed188, 0x000da20d377e44ba, 0x000309358347a501, 0x000921711299c2b5, 0x0000cd3e2ccadf00 }}, + {{ 0x0003ba5119d6cc8f, 0x000a64ea0173b4f1, 0x0003be81afdd3079, 0x000572c082bd2021, 0x00001db750e89b35 }, { 0x000aedd9165911e1, 0x000ef303f5b9d4de, 0x000172b8a2c6cf35, 0x000b760956742f2f, 0x00007d5db743c61e }}, + {{ 0x000763891f69c8ac, 0x000a0d19499a78fb, 0x0004b837ab35be28, 0x00064506b462ab5c, 0x00002c41f6130b86 }, { 0x0006ec12f2cdf2f2, 0x000b1a9532d49775, 0x000d78b2a72327aa, 0x0006dc9f021e3327, 0x00006889435a91f0 }}, + {{ 0x00005b3081d12011, 0x0005d8f264e20e8e, 0x000c794c77bfa4a9, 0x000a8da00abe6bfe, 0x0000ec1d857c8273 }, { 0x00086659ce05e9b9, 0x000be7aa45f33140, 0x000dc5f6ec1518cd, 0x000c7761a56af7be, 0x00006928f160cc82 }}, + {{ 0x000c61c947f1150b, 0x000d0d19dc21ec8c, 0x0009436db7f13b03, 0x00010004998f9868, 0x0000d698306e8e57 }, { 0x0008719a5563ace5, 0x0005b7880dd9e767, 0x0000bfce23b2a87e, 0x000ef00d2c43a899, 0x00000a4ab8781013 }}, + {{ 0x000e7090f1a30d21, 0x000050a6245e4043, 0x0005300f4eef4770, 0x0009ef9b59de4079, 0x00006484903423ea }, { 0x000893002449b8b8, 0x000cd612b944e886, 0x000e7cec61a3d0bd, 0x000f4ac3d250f939, 0x0000b1ed336264d4 }}, + {{ 0x000ee1df781a65c0, 0x0005aa7d26977684, 0x00057b527abaea51, 0x000d1785eabdedef, 0x0000cdef8db325d3 }, { 0x000ff57c95d31907, 0x0000bd91cbb5b437, 0x00064a93d9a13993, 0x000c56666170ed2f, 0x00005f7b461764b7 }}, + {{ 0x00038477acc71a2f, 0x000f6634b2ed7097, 0x000911eb5b6105a9, 0x0008469110e35676, 0x00000610528b928e }, { 0x000bc0876ac5a83f, 0x000ec90c00ee17ff, 0x000f786e4b786fcc, 0x000771cc16874838, 0x00000146b81bb7f7 }}, + {{ 0x000aae7333f7c13a, 0x000695bb0cf664af, 0x000684e894afaa81, 0x000c1ec60126e48f, 0x000061142a8620ce }, { 0x00052706dc43d122, 0x0000bb7995d586b1, 0x000e6dfb30e5e3e4, 0x00094c5dbbe29569, 0x000098178e3461e6 }}, + {{ 0x0002aa0e43ed7de8, 0x000f0b7bc60055be, 0x000d74387007853e, 0x00003ab7003cc23e, 0x00004cf9074de0f7 }, { 0x000042170a90bbc4, 0x0008e4f6383c45d2, 0x00042262041aaffc, 0x000ce8397d766355, 0x0000fed56953d3e6 }}, + {{ 0x0004d63c80e5d9f3, 0x00018650bc6fb805, 0x0004eb27f1ea9ab1, 0x000aa02495882e07, 0x0000a466f2e5fb46 }, { 0x0004edf7b266ddd9, 0x00042d652a23f9b6, 0x0008e61d6dd58c13, 0x0007a359e3670c31, 0x0000d257b443894a }}, + {{ 0x0001a35c0b2e1db3, 0x0006acbd53c5c9dc, 0x0005ea66bb7068eb, 0x000e07afff17624b, 0x0000591d6b9069fe }, { 0x000bd512271e49d5, 0x0005c4693e79987e, 0x000ffcc7a5e70433, 0x000ceaebb0575bf2, 0x0000f661c2e757ee }}, + {{ 0x00075abd1bd6dba8, 0x000a9c856ada97a6, 0x000d283083228862, 0x0005281794afc964, 0x0000f61673328f6a }, { 0x000c6fc7d9717201, 0x000bc725e485a1d6, 0x000f22df4362f530, 0x000127aba4b2a5ca, 0x0000262b28cba5aa }}, + {{ 0x000e545c2926ec20, 0x000f2baa5659ae8f, 0x0009278d4545d7bc, 0x0004021ac68363ab, 0x000024e11be64e4e }, { 0x000720ee26643347, 0x000a2e7dc4c696bf, 0x000a0488899ec903, 0x00061c1c15806244, 0x0000a0f278b7757f }}, + {{ 0x0002d1eeb7e12dea, 0x000a729d2337a31e, 0x000e2cb43d24a969, 0x000a499ba5916868, 0x00000502dc95217c }, { 0x000ee104e224dfe5, 0x00037417884005d5, 0x0007a11ec6cc5e0f, 0x000c97966a2d4ec1, 0x0000b25760a55d65 }}, + {{ 0x000cead9f5ae523c, 0x00010ecc135b208e, 0x00045a991a87a7dc, 0x000ecff3074e1b26, 0x0000f12e91b276ab }, { 0x000086d5f289ce55, 0x0007fb2e286e5b9c, 0x000fc334666f68cf, 0x000ddd4a41b0fadb, 0x00009543bc814bf5 }}, + {{ 0x000dc777e9e6fad0, 0x00041352f6f3076f, 0x0002e5c9b2b028cb, 0x000fdea3dc99ffa2, 0x00008d533e5e9beb }, { 0x00093e8d07d69b5d, 0x0002abb35415f047, 0x0009d3e5719cbe0c, 0x0009ed8b5640c2d6, 0x00007bfb45e7d23e }}, + {{ 0x000f2cea7cc654a9, 0x000cd532de45068a, 0x0007ef0134f22ea3, 0x00003976937c7a7e, 0x0000bee7aa1e25dd }, { 0x0003d0687c1447ce, 0x000d6fb9e4785a98, 0x000ba35936cdef18, 0x000646171e5fda49, 0x0000ead87df3975d }}, + {{ 0x00097b2330287754, 0x0002fb215d02819f, 0x000f4762770544c1, 0x000b3f29f6d0d754, 0x00004490d3fcc8f4 }, { 0x00095dc55f23d140, 0x0009750b24bcbc75, 0x00092f441df78180, 0x000fa350111ea494, 0x0000e940dd6ad26f }}, + {{ 0x00066742ebfbaa6d, 0x000acacd837879f9, 0x000e570424c4a8f8, 0x0004786af6fc1b49, 0x00001a48d8c34737 }, { 0x000b948dc3d28c27, 0x000a2feb49662287, 0x0001c85fab8c7901, 0x0002b0aee96cc631, 0x00002b68fe2195f7 }}, + {{ 0x00094baaa8ef3ea5, 0x0000832ed1f80089, 0x000a3f65ca8f72a6, 0x0004151fbe6c9267, 0x0000b870bac04296 }, { 0x000d178031be45da, 0x0003ae11d248018e, 0x000a757344d6c689, 0x000636af55a39898, 0x0000f7e62c4349a1 }}, + {{ 0x000f8aa54bce826c, 0x000bef497e2feb49, 0x00070f34cdc735a9, 0x000cd91d7d36a42d, 0x0000b578ca909f39 }, { 0x000d431069058eee, 0x000c9ba09895e702, 0x000fb074eaef8c71, 0x0005c5ebb3bd0c66, 0x00009a05e3ae9f73 }}, + {{ 0x00097f6b6bdc2a47, 0x000f7b7172ccd1fe, 0x000747273d266f27, 0x000b70ceb7323cb2, 0x00000289b30a54f3 }, { 0x0009b4cc5fea0d1e, 0x0001b3ed1a83da1a, 0x0006d6965e083330, 0x000ff991ea6a7f9c, 0x0000d78ac0dce842 }}, + {{ 0x000266f95a2ac736, 0x0007e6acb66e132e, 0x00092b2b5f263396, 0x0005083e2f1be963, 0x0000a1dcaaacccd8 }, { 0x000798142a61d3f6, 0x00070735c2088993, 0x00076b6304793707, 0x000a86b9f9047244, 0x000045b4d24b0f15 }}, + {{ 0x0000288cb622df88, 0x00094b13298b343d, 0x0008e426d8eb9144, 0x000e7f2cda3a14e4, 0x0000f218abd21717 }, { 0x00060d45ce976d65, 0x000272f1c040abc4, 0x000dc0b2557c3e5f, 0x000cd3f41b675511, 0x00004127c7f96903 }}, + {{ 0x00048dc4f9468a4c, 0x000f0696755ff899, 0x0006b2a252ed9c6c, 0x0006d140ddd3cf7e, 0x0000ad40f1efa3f6 }, { 0x00038ae89241062f, 0x000cf814ea53299f, 0x0001a560779698e3, 0x00091d4fc2d921ca, 0x0000d74868346acb }}, + {{ 0x0009227077a277a3, 0x00059cfc5e3a3d83, 0x000c07576f48364e, 0x000355e97befd904, 0x00001c25c29ce15c }, { 0x000231d792f7c39a, 0x000a46ddbef42f56, 0x0003e5d8c175121e, 0x000d694407e449b6, 0x00003711285e87b5 }}, + {{ 0x0003ec6869243119, 0x000fb560f6645343, 0x000c177c889a62e3, 0x0002671b985ceae7, 0x0000759c4e754541 }, { 0x00016c4304749ba6, 0x000dd2b3a8ec1f1b, 0x0007a6db92eaf628, 0x000a36f745509d12, 0x0000c8bc38c34b01 }}, + {{ 0x000982ddd5a6b31c, 0x00004147ca23cd3c, 0x0005da0ea6c80ff8, 0x000b47194caa7a5c, 0x0000393836b1cdce }, { 0x000159100cf86685, 0x0007b0b5db6f971a, 0x000ece2e5f860514, 0x000f00f26bba2cb1, 0x0000051e80a79643 }}, + {{ 0x000a640b870d07f0, 0x000947fdec67ef5c, 0x000358da6b30f00e, 0x000bac4c8742ee46, 0x0000a74e3225ade2 }, { 0x000ba90162b75d7c, 0x00085908ceb6aa92, 0x000c28cf5172addc, 0x000c5fef7313c300, 0x00005ab09925afb3 }}, + {{ 0x000569656d0ab3a3, 0x000b5d6a8219bb73, 0x000ce59d601232aa, 0x000a3b46ec691d0b, 0x00002fe02f08a3c7 }, { 0x00080b9e12257943, 0x0006bbd94cda03a4, 0x0002ce206001c072, 0x000d85dc6934e82d, 0x000038227865a8bc }}, + {{ 0x000763a388070738, 0x00043c58cce08b52, 0x000c57b3e9ccf93f, 0x00070a006b636458, 0x000073a51820269f }, { 0x0008b36143bab3e9, 0x0005b8a7d3cebb65, 0x000e166d770ce677, 0x000a45d2ce7adda3, 0x0000ec583f44a15a }}, + {{ 0x000df0c7dd2a5105, 0x000beca4d63c0eea, 0x000661f880f15fdb, 0x000ddee3b5123311, 0x000048f0c43aa7f7 }, { 0x0009a4c281762585, 0x000a83bfe7765e5d, 0x0008e5934187989d, 0x00033ac9cccaab35, 0x0000ce5a2b475518 }}, + {{ 0x000853e4c48e856b, 0x0002988a059c1425, 0x0004a6b7ae821b53, 0x00075cb646f5ae71, 0x0000703cc0a9b888 }, { 0x000c0bc0e57524e4, 0x000992363c52f980, 0x00067576c7916db3, 0x00029971c2ec4a76, 0x0000edb0d188156c }}, + {{ 0x00062d7b00bc24ad, 0x000bb1db82e9f3e4, 0x000b98f8663c28b2, 0x000cdc58083200f0, 0x000027ff00ca4baa }, { 0x0003466612d4f0d6, 0x000cb88f26517980, 0x000c3364b622041a, 0x000046d5974c6e18, 0x0000427ccfde908a }}, + {{ 0x0008100a5073116b, 0x000f5492ed22e919, 0x0004d6f71dd1ef3b, 0x000bcb7716fdfe0b, 0x00009fc9cb71c4c6 }, { 0x00070bfeecfa9449, 0x00091a2a35c628ff, 0x000dd1729b5abc1c, 0x000c390ceb6f94d2, 0x000067c9ff7c6c22 }}, + {{ 0x00049c89cec09788, 0x000d4cfed2bad016, 0x0002b90a1bf89f1b, 0x00011a78fa155cbe, 0x0000121edd577d70 }, { 0x0003a8cfe47d654d, 0x000197de9ff257af, 0x0000ff8380ca53f3, 0x000fac7cf9b35961, 0x000020d4bd2f2712 }}, + {{ 0x00079c85db554c9f, 0x000a0fd248a7d061, 0x00046febee1efaa5, 0x00027ba8180c5bfb, 0x00006ff589c6b4b0 }, { 0x0007795f4fdd2c3c, 0x000746261a6966c4, 0x0002a3638658dd15, 0x000ba67184d82d05, 0x0000f03444a9ebc8 }}, + {{ 0x000f3425f708c1f8, 0x000841fd55a897c5, 0x000b535ceb04e43b, 0x000bfdbb0009194a, 0x000088089bf24fda }, { 0x000b629f9123de43, 0x0002387730d50dae, 0x000b5fa59bee9bc2, 0x000bef1170423446, 0x0000ba71f5c7ecb2 }}, + {{ 0x00094f7d3556d1af, 0x00077ccd5cd79bfe, 0x000aab1cf0e2c812, 0x00075d0580032940, 0x0000ac88a0bcab00 }, { 0x00073acbff0414b2, 0x0001996782ba21ad, 0x00091ff067a6c333, 0x000e35a81c525446, 0x0000b3a408dcdfc3 }}, + {{ 0x000ec684c472efb6, 0x000ffb149ee90d9c, 0x0009d1a819f5cd85, 0x000086fe0785c339, 0x0000a0452c3e9739 }, { 0x00033da338c4f59b, 0x000c7c9c1586e630, 0x000657769bf27db5, 0x00001e85d45431d6, 0x00009e1980aa8791 }}, + {{ 0x000b969975373e25, 0x0005013caa760974, 0x0008eb319f90f0fe, 0x0001ccdc70a624fa, 0x00007256c83b773a }, { 0x000bbff86f099df5, 0x00060ccd921d60e9, 0x000fdfeed1a41869, 0x0004f9ed49b944e0, 0x000095725f99e254 }}, + {{ 0x00084039030f437c, 0x000c53077adc612c, 0x0008f397ca9d5bf0, 0x0004489bda749652, 0x0000af611eeda45e }, { 0x0005efc7e9c72224, 0x0007b66175adff18, 0x000b31e8fdcd72d3, 0x0007b51e30b26d7f, 0x0000abe9a851e48b }}, + {{ 0x000bdbe608fb93c1, 0x0004a421ff6acd3a, 0x0003a80083002601, 0x000e2a027ffe7048, 0x0000344f04aba92c }, { 0x000394077fc5dc01, 0x00091285e1109e8d, 0x000720d053dabda0, 0x000a58dd826147d2, 0x0000b53fc0ef1331 }}, + {{ 0x000dceb8db394d64, 0x0005ed0488c171a0, 0x000a0599999cd66c, 0x00064966aa78bfba, 0x000083197a8d8d9c }, { 0x0007d341959b35cd, 0x000b3899ae2b710d, 0x0005cc715b012468, 0x000de6d46efde7ae, 0x0000a80719fcd630 }}, + {{ 0x00020ebe0e2e4e62, 0x0008a1c3b3f64c9d, 0x00094c502131223e, 0x000f4b6d4e20bc0b, 0x000051365d8f7700 }, { 0x000731e3847a272f, 0x0001fa773241ea3d, 0x000b86e87be0bce4, 0x00040ed6261f1511, 0x0000b13c9b2db908 }}, + {{ 0x0008f77f3559dd64, 0x0008f6e834459048, 0x0009264e7a8accb5, 0x00097c4b72e0ec46, 0x000077614016cc6c }, { 0x000ef2f2271b0201, 0x0008c295864687c7, 0x000da3ec433bdb78, 0x000bcc29e23b92ea, 0x0000b3f836102480 }}, + {{ 0x000c3a318e1ca066, 0x0003038546c4d8de, 0x0003a6b814eb7a95, 0x0002846d95f9c3fc, 0x00003dc194c05f8c }, { 0x000ba1da5a3ee82c, 0x0005341c31cb264f, 0x000e567f3998412e, 0x000c7b5973db82f6, 0x0000dcf49c0e789d }}, + {{ 0x000b8a0feba9b0d8, 0x000838eb212cf53b, 0x000e3ccb6c73f691, 0x00013fd6c4f2e512, 0x00003caf4f380d7c }, { 0x000a556e4004eb04, 0x0006cd2e7d6107e1, 0x0004cd0cf76abda4, 0x0002e32b17ee0c44, 0x00002b28880d6418 }}, + {{ 0x000cee844a04a5b5, 0x00006f9e73056835, 0x000eab00d79c20e6, 0x000225fc131eea5b, 0x000026b5a23f0042 }, { 0x0005e801401734f5, 0x000a0c5a0182bde2, 0x0007783fa574d37f, 0x000b023caee759f8, 0x000034b41c5e2869 }}, + {{ 0x000a3f0c4b2e90ba, 0x00087407e8d7a14b, 0x0009db17e71f6133, 0x000cf4644bb1ff3c, 0x0000added5f139e5 }, { 0x000392768185fea2, 0x000205b1f9af32a8, 0x00062e5faaca59cc, 0x000b6f4ac01e0db8, 0x000089510687411e }}, + {{ 0x00013298312c0224, 0x0000ee77acaca28c, 0x00070605c2f812c6, 0x0001c8b381bfeea5, 0x0000fc71519eb2d1 }, { 0x000a44c6c6da463c, 0x000b6db2aac9e59d, 0x000cdc1cb163dec3, 0x000553e015748060, 0x0000ecc5ac9b6bed }}, + {{ 0x00005f725f94ec75, 0x0008be8a7ea82f03, 0x000db3ca28505d7f, 0x000eb16e199cac80, 0x00002d3afce656e9 }, { 0x00063749945c9e90, 0x0008bc4623fb21b0, 0x000e742bd018d74e, 0x000c16b3efa70533, 0x0000d56e129c9961 }}, + {{ 0x000c2bab1bd708fe, 0x00050d65c46aa8e4, 0x00035ca4b8b592cb, 0x000c87e362100d5d, 0x0000d356747acecb }, { 0x0000624998e75dc4, 0x000250c15426704a, 0x000307d5a251b927, 0x00086b3f8778afcd, 0x000023ad4d716895 }}, + {{ 0x00040c4cce907be5, 0x0008328ed8a6e19d, 0x00056d7d8cf94ba2, 0x000a054bc33fc233, 0x0000e2bedf2813d6 }, { 0x0004820109c066e9, 0x0004cbbf80e75ca0, 0x00001e2bfe22ef3a, 0x000eac49612c651a, 0x00003c7feeecb38e }}, + {{ 0x00094a44a734cd7a, 0x000711a7f4c04cc9, 0x00010ff60add019a, 0x000013b0a5955662, 0x0000a10d512bac4a }, { 0x000d1bc7809447a3, 0x0005519dbeb9b690, 0x0000e1b86d8d43b3, 0x000fd18a2473c568, 0x0000743d915fe645 }}, + {{ 0x000dbcb03af2f664, 0x0008d75a1962f910, 0x0001df9c456cf23f, 0x000933e336ed7e06, 0x00004dfcb458852d }, { 0x000b60cfffa10db0, 0x000924ebb32e38e6, 0x000efca5a01f42ce, 0x0003e39ee6472e5e, 0x00000912f4df98e0 }}, + {{ 0x000763a4348a5ffa, 0x000df319ff91fe50, 0x0000e8edeab92e73, 0x00022d126039c480, 0x0000c218bfcbfe07 }, { 0x0000876a01d11d05, 0x000ffd5383e76ba9, 0x000ff1c717959f5e, 0x0000608e0ac98b92, 0x000071d355178dc0 }}, + {{ 0x0005fb8394ec96bc, 0x000daf305968b809, 0x000272a3f024eed6, 0x0002f6201380a091, 0x00005bd44243eed6 }, { 0x000967204437eb69, 0x000fc1280edfe2f2, 0x000966478f3e6250, 0x00056e2f88f726bb, 0x0000b48e94ed5c40 }}, + }, + { + /* digit=1 (1,2,..,64)*(2^{7})*G */ + {{ 0x000d311f2cf406c5, 0x00006817a2ad62aa, 0x0008ff31e0276fbf, 0x000a6d8b57ef2b6b, 0x0000437e1f6177bf }, { 0x000a38d321e63954, 0x0002c87c2ff3b6df, 0x00023c3f61ddd141, 0x0009d5d38b46feaf, 0x0000a9e4aaa74b8f }}, + {{ 0x000c3da1963d1b37, 0x00058fa696946fc7, 0x00083d8e03d70b52, 0x000d8231550fbc6d, 0x0000c23f1ad7a853 }, { 0x00099d49ebcaeaa8, 0x00055b03cfd5d8b3, 0x00024f00b2ba1b89, 0x000385daa0704b7c, 0x00003f881bb6342a }}, + {{ 0x000e4b32b147920e, 0x0003b6d6ec293cde, 0x0006a0251f43f078, 0x000b7060a733dbda, 0x0000a65cc513dc70 }, { 0x000af675f284aa5c, 0x000a1a9cae368d14, 0x0000b2ba3d012d1a, 0x00090686e5001a7b, 0x000048a7a97981a9 }}, + {{ 0x00042370d35642b3, 0x000ce10399492969, 0x000aa1fa40e1eea0, 0x0002bfcf55b63827, 0x00006300726619ca }, { 0x000dc61f92142820, 0x0008f2ee0d985a17, 0x000af47364dbdea2, 0x0003af2f8192cc64, 0x00009a126d8fb59a }}, + {{ 0x000e8aa3ab0b8178, 0x000835bc2da7de94, 0x000ec16e3013acaf, 0x000091e41d0e643d, 0x0000aceee54c0f0d }, { 0x000d296a148a8106, 0x0005f329a49110f0, 0x000620ad480c6f7a, 0x00042e45ad18317f, 0x00005efb94892cc8 }}, + {{ 0x0005d5bbfc230970, 0x000353eed4c37174, 0x000ef73916a712cd, 0x0004acaa59f8240c, 0x0000b069410109c2 }, { 0x0004d5e0fcf149d6, 0x000f673137fd28e3, 0x000f92655f0108ba, 0x000ab48f2862ac6e, 0x00009efcb3eef840 }}, + {{ 0x000662dcbd70a604, 0x000642008913f4f8, 0x0001646660d881ac, 0x00000ae6cea20ed6, 0x00006d3c305ff6fc }, { 0x00037f7913789dfb, 0x0002e5c725d2aaaa, 0x000eead363c6f511, 0x00079dfccbad2752, 0x000044f72f690d92 }}, + {{ 0x000da26e1aec73e6, 0x0009be144cc3adda, 0x0005da1c14b462fc, 0x000697e72d5ffa1d, 0x00007dc85a835122 }, { 0x0001c794b1a357c1, 0x000661563483caaf, 0x00083d98e34b8417, 0x000eead3ce6924cd, 0x0000cfb7382ae666 }}, + {{ 0x000adbb3f3f634c4, 0x000728882a8042c0, 0x000fc24bcea4eeec, 0x00062e340d931cfa, 0x00006ff1f31aecff }, { 0x000577c11e875a33, 0x000621e5eaa8eb87, 0x00049c3ccd5a10e4, 0x000a9bfc5e663a8b, 0x00000028143def02 }}, + {{ 0x000a786d62a93d0d, 0x0002b5c08369a907, 0x000a9e9647958a75, 0x000519f802990c59, 0x000076b05f00e31d }, { 0x000b2ce9e430d6f9, 0x000b4be20ac3a8dd, 0x00007f8d434c0323, 0x000cdfc6531a2178, 0x00009e7647365eaa }}, + {{ 0x000c56feb051eaca, 0x000694b168984df5, 0x0006d73097883b04, 0x0004c56f0e81dce1, 0x00009cec7a5febd4 }, { 0x000233e35ef6807b, 0x000db01fde58c84a, 0x00068c98cfb5957e, 0x0001a0f7874e2411, 0x0000c7113cb30256 }}, + {{ 0x000f3a8f9d8cc3f9, 0x00072f38bd7aff18, 0x000a8e4721a92651, 0x00064b0151b5ee4c, 0x00003b792b15a449 }, { 0x000255f53b1b9da9, 0x00010c9a0748be7d, 0x0004d6d86ce4578c, 0x00072ff371d391c9, 0x0000702e661ee631 }}, + {{ 0x000f627439d898dc, 0x000c204f1788ee3f, 0x000ea906c4682ecd, 0x000a125c0c14f27a, 0x000041647e0afb10 }, { 0x000c1c33bbabfba6, 0x000dfd8ca2a59655, 0x00027acd85f7ce0d, 0x000fdcce83d9a554, 0x0000b9121e2a4fa0 }}, + {{ 0x0008c889de2e32a8, 0x000b0d474a861082, 0x000fc583d3b1de17, 0x0003aa480f8048a8, 0x00003ee931e746ba }, { 0x0001c240230a2d47, 0x0001f2eb214a040f, 0x0007461ec3244db5, 0x0007f2d8ae8c48e9, 0x0000149fdf2f3f76 }}, + {{ 0x000359ed623dd564, 0x00070c35f74040ab, 0x00014990dbf56e58, 0x000ef8823409aeb7, 0x00004dda364e2017 }, { 0x0002f1d4df601f90, 0x000b926ed6f4a607, 0x000ed89f5903b254, 0x00050ca59e21e8d7, 0x0000edcf85157a9c }}, + {{ 0x000c5fe1306bd6ce, 0x00056b9eb7926b83, 0x0003915e73d8d154, 0x00006960bbff88cb, 0x000076006a867f79 }, { 0x000daf6b21ea15f4, 0x0006ef43764fb3df, 0x000733a24b0b851f, 0x00086f1f37b5af31, 0x000030c22394a5ed }}, + {{ 0x0008cc13d69c73d0, 0x00097ec6063540cf, 0x0001ed2db7b8d6e8, 0x00025f6ab50b259c, 0x00005b5c1b0bc3a3 }, { 0x000f8efeb1d7be88, 0x0002b05c52176597, 0x0003cf322ba2a903, 0x00054bdfefe5364d, 0x00003115b68dac90 }}, + {{ 0x000e583c57029879, 0x00078e5d59233595, 0x000cf5436359e633, 0x000ed2298db0cea9, 0x00001cb09b717846 }, { 0x000b4d4d5956cfae, 0x0006c2dd48185b77, 0x000df304ca2dbb2c, 0x00040ad8bc93fbc7, 0x000021236a00feae }}, + {{ 0x0003768f8316e330, 0x00000b046eb842ab, 0x0009c86455eacc56, 0x00014cdfc8e844a9, 0x0000f8985bdb1afd }, { 0x00051b6eefc870ce, 0x00026e04e09e61c1, 0x00018bac5eec5fb1, 0x0002391cd414dc3a, 0x0000e1888cf3478c }}, + {{ 0x000e19084bc4ca0c, 0x000ca136339c0831, 0x0005c19d3eb5ee51, 0x000cbf8ab39ff815, 0x00008e22e48c871d }, { 0x000222840c0fb45d, 0x000f7c0eccd47ef9, 0x0004b83b7724081a, 0x000269cf68969338, 0x000064e761fcef38 }}, + {{ 0x000c5d75f6acf986, 0x00082f5803bac625, 0x000cdb3e5e689697, 0x0006a3f810b7dd91, 0x00004626edf8311d }, { 0x000036b9b2545d4c, 0x0007b381f2dc308f, 0x000ee94d9b0c2902, 0x000ba643120faa7b, 0x00005df95dde3c50 }}, + {{ 0x00004884ebe91706, 0x0005b0939842194e, 0x000d6987cda9dbf9, 0x0009d28e0b7e2353, 0x000008055a9e7106 }, { 0x00013520c2fe68f0, 0x0006d817419f40e7, 0x00023860a17ef38e, 0x0005c66465b0ac16, 0x0000599f3cf0f8c6 }}, + {{ 0x00024a8434f084ae, 0x000ac5ce98c51002, 0x000d0b928b25c421, 0x0001e398b6cec871, 0x000093f359354aab }, { 0x0006936830d34d21, 0x0005e6125f5c46fd, 0x000b71c0f68f5335, 0x0006e3bdc6a22bed, 0x0000bf2268186fde }}, + {{ 0x0007c2eec1224f3e, 0x00041e891e5d7d3f, 0x00067bdd87b70fb3, 0x000909f61f14b7d1, 0x0000092310e6f29e }, { 0x0000472beb05816d, 0x00006f43756e621a, 0x000f77de8d5da4d4, 0x000061872c013a23, 0x00006e813df45a5e }}, + {{ 0x000e87acdcb83dff, 0x0002f270ac69a804, 0x0005a696a81a3be4, 0x000c1a69134096d2, 0x00005b6a5c9aeed7 }, { 0x0004a56cd8946d50, 0x0009037e285ccb47, 0x0003dc3862797108, 0x000a2a719188089e, 0x000041ca5eaccff2 }}, + {{ 0x000421cc52cbf744, 0x0000ae21726931ae, 0x0007523f20aa75d9, 0x0008a4a180bbbb2c, 0x0000d98ec4e59258 }, { 0x000359b3dc444ac7, 0x0000b08bea87be65, 0x00035e7422a6acdd, 0x000509cf716a475d, 0x0000928ea2c9a7ff }}, + {{ 0x000fc3a5983894c4, 0x0002dde8bf06e31d, 0x0003fd749369a738, 0x0008323d21fdf8f4, 0x00008669487b1517 }, { 0x0001b4f11e41bf9b, 0x0002da0b1ecff106, 0x000bc68b142b2d0a, 0x0008ff273ee6ed6c, 0x0000d795b8258fd9 }}, + {{ 0x000f3d47897647f6, 0x000e09bd4eff2d71, 0x0001234b6e8604ea, 0x00059f12388ae677, 0x0000156c9f102ac1 }, { 0x000794b13b286f95, 0x00083c07f9871da6, 0x00088ea1313d5e21, 0x000e488ac35fbda7, 0x00009a346a1a06b8 }}, + {{ 0x00023a9f8173b2f9, 0x0006bac09cc0917d, 0x0008f44aa17b929d, 0x0006f7d7127c5372, 0x000084aea5a60d7b }, { 0x00040f1c67e5aa9c, 0x000f92852650359a, 0x0000d0929045b31a, 0x000ab235cfa09ad0, 0x0000eb49c8d9c125 }}, + {{ 0x0002383e48552e85, 0x000f02edcc18770a, 0x000ee5ed855ce52d, 0x00082ceed4baf1f2, 0x00006b9ecc862bcc }, { 0x000b2dfd7c4b99b3, 0x000af0a2646d19a8, 0x000b789a42819c25, 0x000d236f156cb44e, 0x0000656fde1d4d03 }}, + {{ 0x0007bdb99d7bc622, 0x00050f2a672c5c73, 0x0007d5960c453caa, 0x0007d3732eacb11c, 0x0000d966e32b0083 }, { 0x00026693bd8b6c09, 0x00026b62899c20f7, 0x0001d2183a676b7a, 0x000eb73e33535d51, 0x0000b014e1e0cb73 }}, + {{ 0x000a20ed2a8c1c6f, 0x00041e5ab4b35a24, 0x0001abcdbda4db56, 0x0003f26801d8b600, 0x000004b48afeb9ed }, { 0x000a24142725a709, 0x00053d44fec01e63, 0x000c6ddb3c8679c1, 0x000868efd3ed7ddc, 0x0000203192c73ce6 }}, + {{ 0x0007fd26ae8cf314, 0x000cb2c6a8ea8208, 0x000b6a2f9ba58ade, 0x000360026b2b50d3, 0x0000e7087b5a0c2a }, { 0x00066f7ffa7c7f1a, 0x0007ccc02bee4ba6, 0x0003a0128fdc2037, 0x00093cf855312180, 0x000003bbef5c6e85 }}, + {{ 0x0006c3200fa35ff3, 0x000da33bccd9617a, 0x000413b4109421a3, 0x0007b1486365dede, 0x0000cb76293645ba }, { 0x000a57354a206551, 0x000aa2ce5e35efd0, 0x000b4afe6c76e5aa, 0x000a5e65199a4e25, 0x00004027e76f2bd6 }}, + {{ 0x0006a6f79278950c, 0x000a24bf8e4b0651, 0x000417ac0a99741e, 0x000fde19607a834c, 0x00007e7ec115210d }, { 0x000ea49b3d3fd55e, 0x00005c66a8649edc, 0x000db7faa2d74f3b, 0x000d255ecfbcdfcf, 0x00002d9e2c5a83c0 }}, + {{ 0x0000ab7b49321f95, 0x0006f4fe9d964888, 0x000e00d72578140d, 0x0007254e94b53d52, 0x000052362af789d1 }, { 0x000995d53e000a78, 0x0009dd427d3317fc, 0x000a50ce91e0ec03, 0x00091e3928dfc1dd, 0x00006eca410021d4 }}, + {{ 0x000c32fbd2c44064, 0x000ddec090090ae0, 0x000ce17d6c5d6bed, 0x0008932902278a0c, 0x0000acd50fc16037 }, { 0x000cf307bda4feac, 0x0009adaf341a6c11, 0x0008fefc60e33292, 0x000789f3aae0ba13, 0x0000954ec449a5e8 }}, + {{ 0x0003b88a9ddcf1a4, 0x00019c719803511c, 0x000ac4d03920e342, 0x000d52c5ea9f97b3, 0x00008856a1c81ea8 }, { 0x000bd715882bc1be, 0x0004948c48b0ee35, 0x000babd03139016e, 0x000ab99f37506bc7, 0x0000a2cc32ebf442 }}, + {{ 0x0005c8485a9d19bd, 0x0004708c1bc52257, 0x000ab150da1307d3, 0x000737043d0b946d, 0x0000f537f04207d8 }, { 0x000df3874cc30296, 0x000c9499ce4177a4, 0x000e2bcd84f0edb4, 0x0006566d74fa61a1, 0x0000f53571e1b3de }}, + {{ 0x0008d158672d3eea, 0x00042f983dfedc91, 0x000474b60ab2fc6f, 0x000eaded2f843713, 0x0000d9c3c4a8aa46 }, { 0x000a5956bae7a26b, 0x000d3cf69769bb7a, 0x00061a2054c79b62, 0x0000e89b2c55eb85, 0x0000df9c408d613a }}, + {{ 0x00045c51f0556ac4, 0x000d2c29fe20ebae, 0x000b00ce08e2eb0f, 0x000b2d989f27168b, 0x000069b4c47cc369 }, { 0x000a9db957a6f395, 0x000bd76099b42210, 0x000c1ab9e80238d6, 0x0000fc3958dc6407, 0x000089ab035eddea }}, + {{ 0x0006a52433a64b6b, 0x000cbd3df61bc767, 0x000fc8d268a83dbb, 0x00023378f13a619b, 0x0000e79d7f68711f }, { 0x000ac045e020fb6c, 0x000ac91ac5bdc5d3, 0x000280079621025d, 0x000e41853ff4a1a7, 0x00003f7f41088141 }}, + {{ 0x000fb4f9a3e59e5a, 0x000da1bad53dba78, 0x000bf3c668b6a4a0, 0x00044b7898ec269c, 0x0000c42d0387de55 }, { 0x0001da22fc32c200, 0x000f823ff9875cf9, 0x0006cb6a079f4d88, 0x00004267923224f5, 0x0000acbd3518a2ba }}, + {{ 0x000364ebbf27875b, 0x000d74d6c04a661c, 0x00059ad281587be8, 0x000bd88579710d3b, 0x0000db51af083108 }, { 0x000aa7641d8ee984, 0x000d9517733d61c0, 0x0009c400c2a5a595, 0x000b8d148d55644b, 0x0000c50509008fc6 }}, + {{ 0x000b6066dd443936, 0x000b681318106601, 0x0007c2ead965cfff, 0x00004cc739dfa650, 0x00008f398de4fb88 }, { 0x000bf773f8103f84, 0x000c1919c9efebdb, 0x000ee624abfcc370, 0x0003683d3425d4bd, 0x00007bb42dbf21c5 }}, + {{ 0x000ed26d818f0304, 0x000b96994b03ed1e, 0x0002747a57c4f532, 0x000e11ccad9ad1de, 0x00005dcd24ba7a71 }, { 0x000ff2db2716bd02, 0x00009e7a4db09d2e, 0x000ca61347d0c139, 0x000d9c529f47f569, 0x00003c0c5c86b05b }}, + {{ 0x000187d6657e670b, 0x000c514b913e759b, 0x0005de6d082e2895, 0x000b95de153da478, 0x000092e140a21444 }, { 0x000e8d345fd30ff2, 0x000c4501dc90b596, 0x00030f1ce6c7249f, 0x000fc18848170e94, 0x00005a2d667b789c }}, + {{ 0x0004b7839d2bce29, 0x00096a1c5c5ea50e, 0x000b82de82e45901, 0x00006e042d3baf14, 0x0000ff6d502965e2 }, { 0x000d93355322d13b, 0x000bc94e7de6dc08, 0x0003d497727bb320, 0x000dbc3ec5cd0f4d, 0x000059e7d3f99e36 }}, + {{ 0x000be924c158e0e0, 0x000aec5776c57224, 0x0001df76044b6efa, 0x0001345a9dc467e6, 0x000033e12139aef7 }, { 0x0000c9ca4e9b5641, 0x00084aea18921310, 0x0003a63bff437207, 0x000da19c58bf8a8e, 0x0000f70e2d2715de }}, + {{ 0x000bc2ffb0c0a600, 0x000e80f83774bdde, 0x000199b044d49d58, 0x000a469a96313160, 0x000087769824fdd0 }, { 0x00009015dea24c28, 0x00015b77cfa46a5c, 0x000e60d52571b07d, 0x00070300a71e6161, 0x00003117310e7902 }}, + {{ 0x000f2b9ffa5ce94f, 0x000f8b2d174d7aa6, 0x00088475bd09ee91, 0x00010b8ed4072d8e, 0x0000abdc7583857a }, { 0x0001914e9bad73f4, 0x00022153760fe8aa, 0x000f4edb1d776b51, 0x0002edc717a96e6b, 0x000069595ca97461 }}, + {{ 0x0005b20d1b136d4c, 0x0009757d8a3c5cf1, 0x000315091df843b9, 0x000413cdd1197ecc, 0x00001969c8be641e }, { 0x00099ea238db2755, 0x0005526705840398, 0x00091e3df50ef1df, 0x0002e83152277c96, 0x0000630e2f484e9d }}, + {{ 0x000875384b505bc8, 0x0005a8b760c1c9d4, 0x000152e6e08ee77d, 0x0009b13c5c7efbb1, 0x0000a686f3ab7cc9 }, { 0x000912a263785680, 0x0008baa3ba8cd86a, 0x000b197dbb7d4f6e, 0x000cc9952b0ce40f, 0x0000893fc7e41001 }}, + {{ 0x0000049c55f94a22, 0x000bbcceb5b76c16, 0x0004c6f76e5ea2ee, 0x000e2049f746f528, 0x000076ebebbffadc }, { 0x000d3fe2ee578482, 0x0000d823c2f7c9eb, 0x0002d43d7a059070, 0x0007d72696bd9904, 0x0000ce8557b6ba2f }}, + {{ 0x000ff4f96876ad1b, 0x0005eca12ef3d36a, 0x000b8e89ac75cb71, 0x000521bf79ee3c36, 0x000090ab39ba4d57 }, { 0x000a347a48af4239, 0x00064d0c47adb7e5, 0x0002a8fa03b1669f, 0x0006bc96a45699b2, 0x0000959575cb4270 }}, + {{ 0x000e6e24892d0ac0, 0x000933b3cef0d7d8, 0x00079d4d1ef8b947, 0x000763500d94f7b1, 0x0000842223ee34e1 }, { 0x000d016ec18d3932, 0x000e49716caca6a2, 0x00080b51ac183c3b, 0x000187be1866c49d, 0x0000c9294fa577e4 }}, + {{ 0x000e969937eb4c0c, 0x000c0c900eac3f90, 0x0000d456ae10b8bb, 0x0007d820d835f628, 0x000023a90a360f31 }, { 0x00089014af462bca, 0x000fee88f30c9cbf, 0x00043eac31b1d4ea, 0x0002462aba606ae7, 0x0000fd95461debef }}, + {{ 0x000b9912384ae29c, 0x000ce9c31c71f7be, 0x00023dd6ec23d54c, 0x000ec27a301f95aa, 0x00007cbf09e9dc08 }, { 0x000c8b46801a5c63, 0x000305e5d91ba877, 0x00008ecb0399943e, 0x00077eb69c6ac628, 0x0000c52861049c21 }}, + {{ 0x000e5d49ffd84deb, 0x0003a1fea5b8e69b, 0x000d075a15bd1f24, 0x0003205e5aeecb3b, 0x00003034bad431b0 }, { 0x000f13f5a83d106c, 0x000a7aae5c8646f1, 0x000801cda3d81b1b, 0x0009b5194dbaa12e, 0x00000bad3d6972ba }}, + {{ 0x000608b69829f0bc, 0x00035eeaceb4fc02, 0x0002386658aa3391, 0x00022b4c83625600, 0x0000214f4fdc3f4b }, { 0x000209f113e9fbcd, 0x00005fc05268301b, 0x00088e26a0fee5c5, 0x000d514c2a6943d3, 0x000089511c6cae35 }}, + {{ 0x0003ffdde3be7cc0, 0x0009e0697bf1298a, 0x000f7d9d85bb314f, 0x000a1cc6fcbdb672, 0x0000c8ea86a332f9 }, { 0x000a3d7005cb8287, 0x00033aaa914d3ba5, 0x000f2ea215e8f9bd, 0x0006b8051836d500, 0x0000034ad2de159b }}, + {{ 0x000da3ce9ebe72c9, 0x0009a4d39eedbbab, 0x000746b1d5ce6360, 0x00065220c35cd2e6, 0x0000dcc999f8c73b }, { 0x00032fd30a1b75d3, 0x000a7602c9cf7a47, 0x0004089bb469c24b, 0x000ff75df01572ee, 0x0000ed51712af770 }}, + {{ 0x000a4544aa046b21, 0x000e8c716543a402, 0x0006d498f7c2ddb5, 0x000b9c5149acafd3, 0x00004ad54644a863 }, { 0x0003a83affc7b669, 0x000e96291d60b063, 0x0008f4ccfa455de1, 0x0003ad227281b7be, 0x0000b48074a91ac9 }}, + {{ 0x00058ae74fac8317, 0x0008162d5d721d5b, 0x0002a648ba32d37d, 0x0001fb6a40c3357a, 0x0000d41eebd7ebce }, { 0x0007312ec0f21311, 0x00009812e6dad6be, 0x00010d0c3d9a387e, 0x00083b3d8de28605, 0x00000e56beae8107 }}, + }, + { + /* digit=2 (1,2,..,64)*(2^{14})*G */ + {{ 0x000161957d933aea, 0x00028e76e6485b37, 0x000b05babd7b6596, 0x0000f456d4d3e24d, 0x0000ce6abd42c3d5 }, { 0x000aefa7aee9d873, 0x0009f83cdb12a6c3, 0x0001f36139b52f8a, 0x0008e5973bf3fa88, 0x0000e7a50e16b447 }}, + {{ 0x0003f63771beff8f, 0x0006f623b36f9fd2, 0x0003d9eb684ebab1, 0x00084f3ef26543b2, 0x000096ae77bc2ed6 }, { 0x000fb89d795ff65e, 0x0007796b6a1142e5, 0x0005d3a20e91b4d9, 0x00011bfd55ea6aac, 0x0000a386dea94493 }}, + {{ 0x00086584c9b213cb, 0x000f83af72e34d46, 0x000fa8a9676c4401, 0x000cad84e0bd9ea3, 0x00006265c102920f }, { 0x00057594c72c920d, 0x00088d38c97b942f, 0x000958e6e09ae71b, 0x000e172894609561, 0x00007cd5b11ce7c5 }}, + {{ 0x000564bade8d111c, 0x00049fce3779ee34, 0x000d77e4a2bf81f0, 0x00017327ae00e7f9, 0x0000f7675150c393 }, { 0x0007f7ccb1668c80, 0x000b12ac4708e8e4, 0x000b5f26ce2e2a59, 0x000dbcb9f4f5725f, 0x0000c707f408fcd6 }}, + {{ 0x0003a7c17140472d, 0x000581b8d9465810, 0x0003ba4cdea132db, 0x0003dade0f0d1313, 0x0000dedff07af825 }, { 0x00058b1494211ca0, 0x000df38e475381a1, 0x00026ff71ea03acc, 0x000c4dddaca1ba42, 0x0000a403ce5132ea }}, + {{ 0x0007c64e36e21202, 0x00075e5522e6b693, 0x000384071de1f828, 0x00012fb5669c908c, 0x00002dc9675211f7 }, { 0x000fb08f0866ab60, 0x0007bdfee478d7d1, 0x000be1e36897f3a4, 0x00021b6dfba75c8b, 0x000059cbb6ef7bf0 }}, + {{ 0x0007560abcab01ab, 0x00000f9842e9f302, 0x000f375578f2df7b, 0x0007d7f6aa331d4b, 0x0000a0561e6ffd56 }, { 0x0003b77509e9eaaa, 0x00089870e3a6b750, 0x000267e7dbebaacd, 0x000134cd025c6aea, 0x00001e66709e13cc }}, + {{ 0x000dbde4ac826d0d, 0x0007c0361a341c13, 0x000fcf3f7c95b3aa, 0x000c6246c3604dc5, 0x0000ce46d1be3f02 }, { 0x000f0d1f30affc92, 0x0006a5d1c7eef696, 0x000562423070d98e, 0x0003f8fca5889680, 0x00003b45ef942f70 }}, + {{ 0x0006f04d3172e6a8, 0x0009cd4196224f85, 0x0004e05cba6c1ba5, 0x00062492375a4ab9, 0x00000994feb99b0a }, { 0x000000efa0311470, 0x0004f1cbda602b24, 0x0002b9603cc9b10c, 0x0003b606b73ee174, 0x00007167141027d7 }}, + {{ 0x00099b055d1c6101, 0x0001a4b12cfe2978, 0x000b9f946f882bbf, 0x0008773e83eee129, 0x00009e74c40cf1ad }, { 0x0005132b2b61a7c7, 0x000b3643a39c8cf8, 0x000df383119dec9f, 0x0008c316382f09ef, 0x00008e4c68996471 }}, + {{ 0x000b4afef949e9b3, 0x000f0ab516eb17bb, 0x000f177c3832341c, 0x0009fbaa673bec06, 0x0000087396035c70 }, { 0x000f54befe9fd403, 0x000bbc8e61d66b0f, 0x0003efd4710c8da1, 0x00097a75a02bda4b, 0x00003e2c39ecdf62 }}, + {{ 0x000c9a9d2168c124, 0x000671dbe7a2af37, 0x0008d31cad5154da, 0x000c67297ec51caa, 0x0000f6a5ba0129fa }, { 0x00003937564cf036, 0x000ae4f6ef5f0145, 0x000298d331a9ca83, 0x00051e01e8abcf41, 0x0000803532cecc34 }}, + {{ 0x0001e274de55c8d4, 0x0002956ed6def63f, 0x00018b709b8e424b, 0x00056a6c153cf648, 0x00008cfd0094deed }, { 0x0009fdddc13851d6, 0x000243c44cc78808, 0x000af2278bc0bdee, 0x000524ae0411a426, 0x0000bf64ecb23c5b }}, + {{ 0x00088c68b8e8aff1, 0x000162232398baaa, 0x0001b47037788dbe, 0x00052abf2205fee4, 0x0000c5e4c2db8891 }, { 0x000e9e19413381a3, 0x000ad417337aaa82, 0x000ce0156bb388a5, 0x0002a062f9ed364a, 0x0000c9e564f943f6 }}, + {{ 0x0009d84aaee0a3f0, 0x000044a3dafd2d50, 0x00058e154e29774b, 0x0006409b135d1fae, 0x000075272e315a42 }, { 0x000286418cf25deb, 0x00030c788aaa6917, 0x00093d60897674a9, 0x0001ac1012dea57a, 0x0000de5fb8c5274b }}, + {{ 0x000688350470c6e0, 0x000970977f7195ad, 0x0006d7634e8b89f8, 0x00088212d8ec8616, 0x000043845130a44a }, { 0x000f5c2ee645cfc9, 0x0005bf8309004c28, 0x000584a3ba78a88d, 0x0005275a4a96e4b7, 0x000038c353982c77 }}, + {{ 0x000270f0d3fad15e, 0x0004ca5dd968198b, 0x0001bfd0499861e3, 0x000657b03fa131c5, 0x0000619c34d7bc9a }, { 0x000c59900ea25f24, 0x0005164a053a3bc5, 0x0006be2d3ae0af2d, 0x00056cbd0088254b, 0x00006bf9c020a568 }}, + {{ 0x00058215b141a06f, 0x00072dda1887395c, 0x0005cda8502dab0c, 0x00008e62940960f3, 0x0000e7123058aaf9 }, { 0x000dd036eeb10f06, 0x0009558f0e1a5240, 0x000be7c0a8ca237d, 0x000ca5062b406856, 0x0000716a9f2d15eb }}, + {{ 0x00060caadd4449ef, 0x00082acc33156b3e, 0x000964736c5160b7, 0x000929feff09d24e, 0x0000caac5cb6e932 }, { 0x00018427c2846cf1, 0x00007a6979b1d8f6, 0x000c35f465637c02, 0x00002fdc060908a1, 0x00001090f1c298a2 }}, + {{ 0x0006877b288e2940, 0x000f33959145a65f, 0x000803b8e80eaf37, 0x0006112a0cd9bc36, 0x0000b81a72e0ba9f }, { 0x00040fa5a0fd54f6, 0x0008b9bf5cbdb258, 0x000859f95ca88625, 0x00044185f2a4fd1d, 0x0000bbdb6fce4677 }}, + {{ 0x000251fe80573ec6, 0x000aebe6558842d7, 0x0003a5a1d225d97a, 0x000041e6d70df8c6, 0x0000a3616cfca01e }, { 0x000d97a9062076a5, 0x0008fcb5e9aac9a8, 0x0004626cb46bc51a, 0x00054784e11bb093, 0x000096e6c4d5afbb }}, + {{ 0x00077708c667d059, 0x0003a277946d3f97, 0x00038fd019ad9658, 0x000e65586e132bd2, 0x00002ddf44a145b6 }, { 0x000ac06c3764df11, 0x000b7cd1297029e8, 0x000c3138c426b403, 0x000a6c5d92c61095, 0x000067be85672106 }}, + {{ 0x000e2347ffc2edcb, 0x0001139a13046683, 0x0004c9d54e06e078, 0x000d9578de4a9c88, 0x000002ea6f0c8fe9 }, { 0x000ff875671915b2, 0x0004977ea7d23a38, 0x000cd731fc668ce1, 0x0005492d32fac257, 0x0000e0f225fb9165 }}, + {{ 0x0000d8b2dae7ca94, 0x000fcb36b0cf82eb, 0x0005753d030cfdc3, 0x000d1805a6438d24, 0x0000a53ea3da217e }, { 0x000afa8c8dcb9f12, 0x000c8dbd9184c4d2, 0x0005ce430ce88936, 0x000756b473dbb18d, 0x000096aae294c905 }}, + {{ 0x000ad8848abb5fc6, 0x0008de8bc36742c8, 0x000e63c869056bf3, 0x000e7b500898f427, 0x00006d577bd5f382 }, { 0x00074a2d9a7f8c04, 0x0003838d74a2a464, 0x000954574e07ece4, 0x0002da5e45e3e05a, 0x000086fa3c45cbcb }}, + {{ 0x000df865364f0739, 0x00000ad653ae3263, 0x000a6954560d380b, 0x000cd878314bcf72, 0x0000e5984638d7d1 }, { 0x000ccfe3cd6ce14b, 0x00024e7b53ca5557, 0x000d2f05f16b65f7, 0x000f23968688cb00, 0x000083bf9324d5ad }}, + {{ 0x00074a1d2d22f9b4, 0x00093e06c4c1fe61, 0x000a12419e4cac55, 0x000daa614557e1f1, 0x0000f204eb2e220d }, { 0x00075797ca396209, 0x0003230c51fbf539, 0x000157111a5b409e, 0x000ad3873d894099, 0x00001cfd1518ece2 }}, + {{ 0x000dfe0d903a457a, 0x0001207e3533d77b, 0x000970360f08ec9b, 0x000e84aedd7222e6, 0x00008819a858ad52 }, { 0x000eb874ec49378f, 0x0000bb61d056605f, 0x000587efe032d6ae, 0x000c3fe8ca9ea9df, 0x0000fbcf08ae31fe }}, + {{ 0x0005f49faf4f53a7, 0x00043867ee0d98fd, 0x000b060178b5af0c, 0x0006c8ad4201ad34, 0x0000d0bf380597e8 }, { 0x000a24911e00876c, 0x0004691c7f4a40c8, 0x0000e8e94c74da88, 0x0004ffd872e69d9c, 0x0000a4ebb0eb3649 }}, + {{ 0x000d6de7bd491998, 0x000801060a716760, 0x0008e8fca31418e2, 0x000fd8b1ee852d1a, 0x0000dc52d76da81a }, { 0x0007f0f335115f76, 0x000f988c8e347f89, 0x000703e8a98e5e7e, 0x000a7f3501c58754, 0x0000eef253d19b22 }}, + {{ 0x000b3fe0f9da5724, 0x000bdce4924867ad, 0x000f8578681e0a84, 0x000597679bd5f51a, 0x0000d1366a434662 }, { 0x000ca8b8c079486a, 0x0002ad8556fa9db6, 0x0008b69876ff7430, 0x000332891fa26216, 0x0000f462db921b41 }}, + {{ 0x00022a049341c337, 0x00033a9bd7638026, 0x00000306390eab7d, 0x00022f7c4c21486a, 0x0000d141475b8b86 }, { 0x000540cb1b1be032, 0x000da9dbb7a8ee0d, 0x000b96c0e3c063f7, 0x000de42ecdc2ed3b, 0x0000397c62c0f6ec }}, + {{ 0x000736f9291ef406, 0x000e74ecf84f6c7a, 0x000b85d2161ab278, 0x0002f97b48561fb9, 0x0000bcf6264a5050 }, { 0x000c70cb296a5d7b, 0x0005e292c1950ee1, 0x00033a6b46899d57, 0x0000d0c8eda17754, 0x0000b3f3cc6b8110 }}, + {{ 0x00070c1c8efd9357, 0x000358b6f0f7c500, 0x00087e41afdefe0f, 0x000242f42a8eba2b, 0x00006e5680230b39 }, { 0x00079d74c341868c, 0x00037716484d2e49, 0x000e75a3cc667a4d, 0x00052af0bfb78318, 0x0000b9d00abad929 }}, + {{ 0x000667ac0d2f8437, 0x0001f4761fb04286, 0x000a587e78c7cc95, 0x0002a4ffd4d78954, 0x000020826521d389 }, { 0x000ac4bacee14c89, 0x0007c1243bcf832f, 0x0006a53c4668bdcb, 0x0006e01a7fbadf8b, 0x000053ad230ebad2 }}, + {{ 0x00058566c410a298, 0x000708d977eab403, 0x0005f1db4ccc80c1, 0x0006b3d5351f4c5b, 0x00008dad5554cb23 }, { 0x0009e5f0b7cfc603, 0x000d39e5068f5ff5, 0x000c81197a4e6a94, 0x00018bcf0f31435f, 0x0000e92434aca407 }}, + {{ 0x000943b3af624454, 0x000dbb898559acf1, 0x000e3473e7a0fb04, 0x0005b12aa96018c2, 0x0000fe9ef544dffe }, { 0x000ec75726be2472, 0x00024df15a40d39b, 0x00038d59a09f0400, 0x00073ce4cb2a4468, 0x00009d760075d37d }}, + {{ 0x000213754eefea23, 0x0007e63bea064441, 0x0002e51141a3c690, 0x0004ea5ab27e95bb, 0x00006619f7919ae2 }, { 0x000cc970d32e84eb, 0x0002520716e0f742, 0x000ed2f724ef5dbe, 0x000273e326679c82, 0x000049306f2821a2 }}, + {{ 0x000f8396342a360d, 0x000122f740f0e66f, 0x000a2be78d984691, 0x000d47ed7545c616, 0x0000556fdb469789 }, { 0x000fcb8983c3880e, 0x00019d9025ac99a0, 0x00001b9859b74109, 0x000503719d314d4a, 0x00003e7c7f956365 }}, + {{ 0x000fd58ff1b72f01, 0x000216138634818c, 0x0003e4769e197596, 0x000b0daa3501814f, 0x00007ddf3af2b89d }, { 0x000db6eef931c2b7, 0x0002414d3b507a84, 0x000e7754ebdfc74a, 0x0002342aa57bd478, 0x00004e0dcd5fe91f }}, + {{ 0x000de92572a83fdd, 0x000151ad1fc0654d, 0x0002a33d78008489, 0x0003f6cf9c71cc96, 0x000005b75269915f }, { 0x0005f44d1e992bfc, 0x000daa3f97ad8f78, 0x000f0c59969f0192, 0x00014ac00e6c19d3, 0x000025a10641d608 }}, + {{ 0x000332b6dc4e101e, 0x000a28b09d64c52b, 0x000f42ace06d0b43, 0x00063417da1b5e49, 0x000046ce47f6dc04 }, { 0x000f0bc5a141ae2f, 0x00059a0b4511aa47, 0x00025cca06b413dd, 0x0001f23bd0978875, 0x00000bd956a4fb97 }}, + {{ 0x0009ff29ad65488e, 0x00084d4c11f61ef0, 0x00043084bdf0af25, 0x000773c159ce1075, 0x0000ec6435d82c07 }, { 0x0008b5fef46ca97d, 0x000f5bde7da946e1, 0x000bd5caa5fe7671, 0x000b00fe4ebf9eb3, 0x000075259e3b13aa }}, + {{ 0x00038c534e92ad2a, 0x000a3d35958cd79a, 0x000479aaddc64328, 0x000e62d263580a1b, 0x0000ae928f234367 }, { 0x0003cc3e51cd352e, 0x000b60a2ff5845be, 0x000cd9abd92da353, 0x0004a6b20e5bb40b, 0x0000ae386f9756b8 }}, + {{ 0x0008ec52c22da1f9, 0x000befee5682d265, 0x000f55dba5b9efc6, 0x0007758ab5206f76, 0x0000dc15c6ab6dd6 }, { 0x000ae060d5586b0b, 0x00084990f75cf9ae, 0x000ecfa270009add, 0x0001d8aabf411951, 0x0000e895791fe909 }}, + {{ 0x000bd450efe0661a, 0x000c5737fb54dc25, 0x000ac9c1e559ba7b, 0x0009f36811f3e391, 0x0000aca8c08c3b1d }, { 0x000890e30907b5a8, 0x0005467981eb389e, 0x000751746dcc2ec9, 0x000873f5ced7e192, 0x00002b55533c62a3 }}, + {{ 0x000d7f7a52f077e7, 0x000cf82feccef760, 0x00057e3af33fc8e9, 0x000ab8ec48b8e11f, 0x00004d722538f93a }, { 0x000e2b5b0ebc17e7, 0x000ec0a9efe5633d, 0x000a76269e26417c, 0x0003683002d8d246, 0x00005e002152d468 }}, + {{ 0x0007d2501ccbde9a, 0x000a25abf776f5b8, 0x0000d8632ae86106, 0x000e0a57a6f72407, 0x0000bbf66580faa5 }, { 0x000a4228cbe2da60, 0x000f2e187b053405, 0x0007c7202366612a, 0x000206ddbb7bf7cc, 0x0000bac9edde0240 }}, + {{ 0x000632d18502246d, 0x00069d6fd4fd6717, 0x000e4ca7cf89ed63, 0x0009c7e96a233687, 0x00006b0153bdbf01 }, { 0x000381366bc36648, 0x000b0e940735ff4f, 0x0002cc87fb85426a, 0x00097f7183a3e6e1, 0x00007201b1efff17 }}, + {{ 0x00034d89dd22ce0a, 0x00018a960167d923, 0x000841dc67af01f4, 0x00085a71462f9d6f, 0x00002030a417e2e0 }, { 0x0007d6912f7833d4, 0x0008fba2a4383ce6, 0x0006f5229a7161b8, 0x0008aa0c0cec8e93, 0x0000c10be8855950 }}, + {{ 0x00084ec70d77159c, 0x000d0461b9131492, 0x000f11ff3bcd0483, 0x00018499436aae2e, 0x000053055174f620 }, { 0x0001596fa6d718a3, 0x0000fd061391d54e, 0x00061cb7deec1cba, 0x0002f8aff69c5d5d, 0x00006bb3ce340edd }}, + {{ 0x0008ec05f3a623c5, 0x000965696a71cba9, 0x000264ded8c36a35, 0x000a9bf71944938b, 0x0000d4afba995956 }, { 0x00012ecd8b87d02c, 0x000a21b0698304a7, 0x0003b08f2a1059a1, 0x00051b2c12d69144, 0x0000fce76e99e893 }}, + {{ 0x000176fbaba509a9, 0x00057a700fd56e19, 0x000267db806ce842, 0x0003499e102ec969, 0x0000b53556f68ba5 }, { 0x000e116c316d7216, 0x000dbba44b7b6187, 0x000973ccdceb19b4, 0x000436cc0b4d7aae, 0x00006be87ea1879a }}, + {{ 0x0008553aba1f2c4a, 0x000c581466265d74, 0x000205a2733679fa, 0x00047457fb15b6fe, 0x00004fd50ac219da }, { 0x0001bd339486e911, 0x00019c8c21e94db8, 0x000d3c038859a5de, 0x00057368f795ac38, 0x0000e90f47c1b4a7 }}, + {{ 0x000cf9b00c68264b, 0x00090e956b3c4f2a, 0x000ee347c7bffba2, 0x000dac4c1017a99c, 0x00002d4fa858cee4 }, { 0x0003e8b689fdab85, 0x000378d47173611a, 0x00080894bee52bc5, 0x00029bca21a4cbe0, 0x0000cd609cc3206a }}, + {{ 0x00010dfae15b10c8, 0x0009eda4d88f1dda, 0x0004d9c563094fbf, 0x000680267c604f16, 0x0000e738ded43ee9 }, { 0x0004f544eac66991, 0x0008b76af36f4e47, 0x00023a4a4a5e2681, 0x0005f158c994b229, 0x00008811132390b1 }}, + {{ 0x0002b76b184bc485, 0x000d6b98113a7572, 0x000467e11acc370b, 0x000e3015f4ef2d2b, 0x00006a474045ccce }, { 0x000def0c94233a80, 0x000a310443516830, 0x000696031bac0d4f, 0x000e459479d86189, 0x0000536ea5513960 }}, + {{ 0x000f5796a5a19f3a, 0x0001a174c7c15e09, 0x00019acfe58d4e71, 0x0003d955f539bfb0, 0x000062e8e0c9e958 }, { 0x0004a8ce6d3e344e, 0x0004fe84f157269f, 0x000485874afe4d4f, 0x000560c91c825c1e, 0x000052b87c2a4f9e }}, + {{ 0x000a6c9d078887c3, 0x00072a770cbac78d, 0x000b1c459c509446, 0x000e4ed1183488e9, 0x00005eb15cc6694e }, { 0x000d2b810054b0ec, 0x0000f30dd648c523, 0x000c15d01ed16251, 0x000a54486994ca02, 0x0000ab1e189c171a }}, + {{ 0x0006c4fcdd32e0c3, 0x00085c85963a46e3, 0x000572d964eab5be, 0x000a454b4658ab87, 0x0000336a4535aa18 }, { 0x000adbe47f352065, 0x000c2a1a3906def5, 0x00070765a4c6a931, 0x000b907de9fe95f5, 0x00005cfb0d9f02c8 }}, + {{ 0x0003d6b0785941c9, 0x0006e0f396de2b60, 0x000bed16174546c7, 0x000db3d7298583d4, 0x0000fd49ba83df8b }, { 0x000c93db80ebbbf3, 0x000ea93b0b64912e, 0x000328d49f883c1f, 0x000302da99b3a343, 0x0000fc0ce27be066 }}, + {{ 0x000a22cd41ae626e, 0x0001e2466e48bdd8, 0x000887aa0a4c529d, 0x000c298032514f2f, 0x0000980fe0c00e32 }, { 0x00016284b5cf64ac, 0x000e1f4b283e4c6c, 0x0008c9d6f389d580, 0x000c0ec0978c2985, 0x0000926037d62cd5 }}, + {{ 0x0001d36874bc33f5, 0x00084161338830dc, 0x000b103ed755e9c1, 0x0009151f86d4b8a6, 0x0000aa1dcf33163d }, { 0x000f1ebe4e82f431, 0x000b3958d436d13c, 0x0000c091c2614a82, 0x000b90eb5d4d9c22, 0x00002e1a3189da65 }}, + {{ 0x000e6e2135aa3e34, 0x000406a584c5e205, 0x00015b6e4efffd6a, 0x00016589b267e4ea, 0x000028a50a289a0f }, { 0x000fef4e6229a8b1, 0x0001b6a8c8f936e6, 0x000445d2f37ab589, 0x000b64a868af84d0, 0x00002d1d526d0d0a }}, + }, + { + /* digit=3 (1,2,..,64)*(2^{21})*G */ + {{ 0x0005c78880bdb670, 0x0001f09257226088, 0x000a8d556d463880, 0x000fe87ac131260d, 0x0000a978da1cbb3c }, { 0x00081d1c0fbab2fc, 0x00085ffc3bdf24eb, 0x000b3da6a9989162, 0x0009b73405bff75c, 0x0000d9387ea82fe6 }}, + {{ 0x0002b79aff1b7640, 0x0003cc8f43a730f8, 0x000bb0f3be0fe168, 0x0008ce40be89b6f3, 0x0000da60e29a2a91 }, { 0x000b662498ee8663, 0x000c556962fe5de3, 0x000b255f6d5a6808, 0x000a245580c590ad, 0x0000e4d2e7887b5b }}, + {{ 0x000414582cf35827, 0x000a80d6c39765a2, 0x000d882871de9e8b, 0x0003d1450a2db3ac, 0x000046f7d2fddbd8 }, { 0x000672303b75f511, 0x0007abc60eee9a8a, 0x0001cc28700717f7, 0x0003de4d554c79f0, 0x00009aa79fb6b0ef }}, + {{ 0x0004ff052f5917b5, 0x000faa8719c05631, 0x000ca760c26fde52, 0x0005d57d3cd8ad2d, 0x0000bd74588b7072 }, { 0x0006ad71d02a024a, 0x0003acf3e2d65208, 0x00078da16339cd4e, 0x000f011987ebdf0f, 0x0000079790c922a9 }}, + {{ 0x0005c0e37aec2320, 0x000de9226f435728, 0x000ad7c163ddcc04, 0x0006d74c1dfd3ab5, 0x0000e297c00ebf67 }, { 0x00035b9485776668, 0x00011727be19ae06, 0x00067bb1a22fdff6, 0x0004b977e616a339, 0x0000d8b5f68742af }}, + {{ 0x0005de4f4a416a75, 0x000c7dada430c0b9, 0x000da4b88b7c5154, 0x00041bd6a4702850, 0x00002e74a9165ad4 }, { 0x00017cb319502a4a, 0x0006309e265c17ce, 0x000326fe85685ff1, 0x000d07bca24e4546, 0x0000bf42ebef2391 }}, + {{ 0x000819dd9659911d, 0x000754374dcec468, 0x000ccca8d9a91332, 0x000dbbc9c33cfc02, 0x00001f5408b7ae98 }, { 0x000eb357eb3611e6, 0x00044a60871f4274, 0x0005a83cc448d345, 0x000e00faf8e0cf36, 0x00003b6703b79d89 }}, + {{ 0x000f5d55f460757a, 0x0004ec4868af75df, 0x000e466b71f6795b, 0x0000c72b0d7325cf, 0x0000e10c5f3da26c }, { 0x00094ad8a7522d79, 0x000cc411977a0ee8, 0x0004e8d5601f6c03, 0x0001e3b955085c4c, 0x000028f635d618a7 }}, + {{ 0x000f311e0eabc31c, 0x0000741ada354383, 0x0008c56a6e3fb07b, 0x00054b334f4a9fc8, 0x00001f2b7d334bf3 }, { 0x00027ce89b6036fc, 0x000043892ab98919, 0x0000ac10010e629b, 0x0008e3fee257bdcc, 0x0000d4e8e7aaee28 }}, + {{ 0x000cdb6e7895d161, 0x000cbca523db2808, 0x0009c3f8c90b1ad1, 0x000c6706f5c889f8, 0x0000605933f73ab2 }, { 0x000076d41f277058, 0x000c4f0179c8e744, 0x000207aa49414348, 0x00014ba00d8874e5, 0x000029e04258b6c3 }}, + {{ 0x0008a790b23045f3, 0x000333c47b517ea8, 0x000ca7c0cdac91c8, 0x000c03ea079a448f, 0x0000f88cfdd1c6c8 }, { 0x00044cc5afb2f094, 0x000787d80969fe8f, 0x00034cfc5609af25, 0x000a4e12654f92fd, 0x00002a65082a73a9 }}, + {{ 0x0006c0d50cd87d6c, 0x00017278b1e68b79, 0x0009997e54c71ee5, 0x00052d2cbc731ad7, 0x0000b44017339c7f }, { 0x000bf64f7d3a4aac, 0x000f3e79b4f7f248, 0x0007b1a318728a1b, 0x000e1748dfdd781d, 0x00003026e7244622 }}, + {{ 0x00007a3c1ceeb879, 0x0000d2c467be912a, 0x000926c2f4afd167, 0x000ffc5c7f4c85ee, 0x0000156de531a17b }, { 0x0002c133aac4e622, 0x000cd450c00beb33, 0x0002cd4c1893c312, 0x000229d5b30e2c2b, 0x0000fcacc4f9ea39 }}, + {{ 0x000894a646301fb9, 0x0005dbb32e5685df, 0x000860524efe08bf, 0x000a632c668a9e06, 0x0000a480e5c2b19d }, { 0x0007ec2caf1e7fea, 0x0004b0a09e27ecf4, 0x000e110aeaeed496, 0x000f877baeced201, 0x0000dd057fe48dca }}, + {{ 0x0007eca65a996482, 0x00015c4f68367ced, 0x000ae66db0fb60e8, 0x000342779e4f47d0, 0x0000d6d9565d0319 }, { 0x000b6873efddb317, 0x000a47149ded0a33, 0x0004bfcc5fd5434a, 0x000d273334cb2aad, 0x0000fecf3dc03882 }}, + {{ 0x00066010689e1641, 0x000f3b22c11bb373, 0x000db6ec643ab5eb, 0x000afb15d2d0366d, 0x0000ab615f997250 }, { 0x000b5f7e8a49c22d, 0x000402c68d7b6d44, 0x0008c124aab7be0b, 0x000a684eea8f74f0, 0x00006ee0d7c27a2d }}, + {{ 0x0008fc242b74d79d, 0x000d47789070d267, 0x000e6420679c51cf, 0x000c68217a1f28e4, 0x00000be63ac7dad1 }, { 0x00042c485ec72b60, 0x00065928b0588f1b, 0x000c610949c0029c, 0x000ba4e35b6b7a0f, 0x0000c2df5af332f6 }}, + {{ 0x000752e537b3aeec, 0x0005213dbab98aa3, 0x000b6a282aeced62, 0x00097413ade9d469, 0x0000c4a05092000c }, { 0x000617ba15d6404b, 0x0001fdd15544eb9e, 0x00069ae3e8640d68, 0x000dfb6b5f013aea, 0x0000c07b8448571b }}, + {{ 0x000d7158f2903d4a, 0x00038a6936219d36, 0x000440e072274354, 0x000ca5d4c5ce1f19, 0x0000aeea5b76a62e }, { 0x0008beb35eb7c48c, 0x000df21e300ce18d, 0x000f545273fe83bf, 0x0005f0f9b35fba62, 0x00009e3ee834d7e8 }}, + {{ 0x0002699749223725, 0x00006b01f7e320d9, 0x0003db3989a12b79, 0x000dc64a30641c36, 0x000085fd6388145f }, { 0x000b92552feb649d, 0x0005217ceb6c1434, 0x00018da120fb460b, 0x000267af867fcb84, 0x0000515b55c60526 }}, + {{ 0x00099bdc6fc777ca, 0x000fd0e46aca7930, 0x0004dbdd54abe6f3, 0x0008b2d161cf0b0e, 0x0000bd4ba21f4e90 }, { 0x000ce18473bb041f, 0x0000cb20caf8b051, 0x000a55f4b97f1131, 0x000c0d508f74d505, 0x0000a157aa07d7d6 }}, + {{ 0x0004d831d9980ef8, 0x0007d9783abdb4a0, 0x0006da10193eb141, 0x0008f6fdc850fbcb, 0x0000b1f65be994c8 }, { 0x000ca16d905a0431, 0x0007d3bfa12d45da, 0x000d9aa574b633e6, 0x000f1c21ee425f8c, 0x0000472d6784e4ca }}, + {{ 0x0006be873329a887, 0x000d36a9152f9347, 0x000d764f8b8de418, 0x0009ef6acf1235e5, 0x000039762606b9b0 }, { 0x0003ee10d17b708a, 0x000ee310c0cd3130, 0x0003a226153c53ce, 0x00041a3153c52455, 0x0000f1a929d0274f }}, + {{ 0x00079739f7318d32, 0x00027b21994ef202, 0x00093bf3a921a053, 0x000dc5e102a653b6, 0x0000417acbe360fd }, { 0x000b40cff123155f, 0x000073c8b799336a, 0x000c74fb67fa3a8f, 0x000c69c2dfdfdf14, 0x00008baaad38eb7e }}, + {{ 0x00090bdcfccc29da, 0x000d983d20b42d5b, 0x000ee66ca762f3ee, 0x00090c3f0f9a810e, 0x0000f553cd3456f1 }, { 0x000e248f78d9528b, 0x0007a91f01ab782d, 0x00008ccc9b0f3f1f, 0x0006eb901c823f21, 0x00005ba0497c7a34 }}, + {{ 0x0005b53add7650bf, 0x00085e50cafe751d, 0x000bff2797447909, 0x00034812473997c9, 0x000097d3990af468 }, { 0x000e25f2ce2b08a5, 0x000d511dcedd8d12, 0x0008468d39b5d584, 0x000d543b1406bd1c, 0x0000fd5a272530da }}, + {{ 0x000a70e6bf33183a, 0x000a35e29dfc254e, 0x00054127cba88ba8, 0x00015b8ad4455fcf, 0x00005553f496e694 }, { 0x00036bb6459a57f5, 0x0006c695820f3bf6, 0x000d3acc40499055, 0x0008db783f410d2d, 0x000031a7e7bc74e1 }}, + {{ 0x000fa724e36fba72, 0x000dca39754e21c0, 0x00067dbc9e8fb755, 0x0004f699abc87a3e, 0x00008aa8469ef3d1 }, { 0x0006c5db934e2c84, 0x000c829b0720b169, 0x00026fe7131a51c7, 0x0003ca5a62dd0cf1, 0x0000be10a91df994 }}, + {{ 0x00074764ddb736f7, 0x000ddc05f18395e0, 0x000418396b551790, 0x0004f105bd3f2274, 0x0000b92a58459d14 }, { 0x000f0b4e7fc1d0d6, 0x00013507bc7f3893, 0x00007a6a15e11d01, 0x000d3ab57c580c85, 0x00003331b44a24bb }}, + {{ 0x000f11236279ebc4, 0x000a9e8a9f19c539, 0x0002ca63bfeba930, 0x00064cba95717bd7, 0x000086b4bc72b477 }, { 0x00076fcfeec45e44, 0x0001a31823b73482, 0x000584f3707abbb6, 0x000397e584dd8f0d, 0x00002080c6a3d85e }}, + {{ 0x0001374518550834, 0x000e75e2bc0aea9e, 0x0004fcfb4f1939ad, 0x000dc847e4f668fd, 0x00002277741998e3 }, { 0x00010649ba9269ce, 0x00029e6853ac983a, 0x000dc7e1409c87dd, 0x0003f9fd1c3bdf42, 0x00001a9e558bca9c }}, + {{ 0x000984d8c0756da9, 0x000f60b879fbbed4, 0x000691183fa97cc8, 0x00008c6450ff0ae8, 0x0000bc7e3aa798e1 }, { 0x0002c0087c8490da, 0x000bba6d21008f03, 0x0000075a13ccfa3b, 0x000db76f329bd54a, 0x0000cdfd68fa494d }}, + {{ 0x000eda0108b2b2b2, 0x0008ae60c1cdb260, 0x000746a2a0fce8f9, 0x000ff4bcdcd94d94, 0x000051bef4868fea }, { 0x000105f6c2d3fcbc, 0x000aa1056152fcc1, 0x0006d6133470c109, 0x0003149a4c2f037e, 0x0000f1a1f67957f5 }}, + {{ 0x00013c1b9dfbee2e, 0x00007008733913cd, 0x00026dfec0a26cf9, 0x000b44ae9cce8616, 0x0000301eb9bba43c }, { 0x00058c5a3c8e1fd6, 0x000a8c71c74cf5c3, 0x0008bc18677805cd, 0x0001a3bf18887dc4, 0x0000f290c47af3bd }}, + {{ 0x000c23f6bd8f7001, 0x000c304890228299, 0x00069f5598bb730d, 0x0004e6dad40e9397, 0x00001a83f93d79a9 }, { 0x0004233cffc4cc06, 0x0001435fbffd8bb2, 0x0008f52696de0ca5, 0x00059d33a60fcfb4, 0x000067aa71b84bb3 }}, + {{ 0x0006fe382d94c44a, 0x0009a6ce6d982af4, 0x000ea056154ed2e9, 0x000c78687ebb6bf3, 0x0000ae247fcc48a8 }, { 0x000a247e575d5c4d, 0x0005ae8b5bdbd756, 0x00014ecdaaa75fdd, 0x000bff600ab38133, 0x000002fa41762570 }}, + {{ 0x000df2688e5c0bfa, 0x000f81b636288bec, 0x0003fab55a773328, 0x00085a4049dfdca7, 0x000085fc068e8d8e }, { 0x000976ef578a35f1, 0x000ee44d0f8a67ee, 0x000a21e1e0b95bd1, 0x000ef07f4d985df4, 0x000004f8b7366d81 }}, + {{ 0x000b539e244d918a, 0x0000baca1c323732, 0x000a47f86bef05d2, 0x000da4bbc351027a, 0x000011f52fa1b210 }, { 0x000bea3fa5e2c7e5, 0x00067ec0eaa1d710, 0x000d5a338fbff1d1, 0x0008ce2402a83381, 0x00009435f8928998 }}, + {{ 0x000aad621cd624b4, 0x000028436cc61347, 0x000345f6e1c0c72b, 0x00016c92a8eb9bbf, 0x00007457c7601162 }, { 0x0003e95ca5e2ca28, 0x00025740a8f7cc07, 0x000d936cd0bf865e, 0x000cd30eee820c2c, 0x0000d32e75fd1366 }}, + {{ 0x00075553bbd18331, 0x0005fabfbaf50a55, 0x000b10f8b3952494, 0x000f37f05df55e76, 0x000083667f4aec1f }, { 0x0001b91149c64f10, 0x0006ca3553afa736, 0x000beb9cb1077179, 0x000ef4d35315f3ff, 0x0000724cdc42e0e8 }}, + {{ 0x0006710053e87e6e, 0x00027d3fa326dc3b, 0x000e628b2c963b4e, 0x000250f591df4da1, 0x00007156cd0888e8 }, { 0x000ea109e476ac64, 0x000027e618344d14, 0x000251c33bcb204d, 0x000e1583acc7ce04, 0x00003fc838df305f }}, + {{ 0x00061e97bf3ccbad, 0x000faacb40961bf5, 0x00071486d43b1a75, 0x000ebb8d14ada593, 0x0000416698a685c5 }, { 0x00083dfe218457e7, 0x000beb6da3982f5d, 0x000cdd08f647376c, 0x0000946200c2659e, 0x0000016501cf88d5 }}, + {{ 0x000970713804550a, 0x000ba5fb835398c3, 0x000f7a19d08a80db, 0x000a0d2db6106a8b, 0x000024eccd926e31 }, { 0x000c5926d6e5fabb, 0x0007d34d8249f00d, 0x000ececc10c98ac7, 0x0006705c29f14b58, 0x00007dd9e5578e79 }}, + {{ 0x00059b045ae4cdd6, 0x0002d398e77738ae, 0x000f16095fcbf91e, 0x000b19886d07a63e, 0x00009b2d8bb94209 }, { 0x000115fba320b394, 0x000f0e520fa03389, 0x000859e95f2ba538, 0x000efef1397939ac, 0x00002792ae3d4093 }}, + {{ 0x00097bb53067a096, 0x0007ac25fadf8c35, 0x0002749e0bb22636, 0x0005dba2266be38a, 0x0000e8e24f086be5 }, { 0x0008e7ffb7148254, 0x00032b7c153ca7f9, 0x0002d7956406285c, 0x000de7e1ea8d30fb, 0x000062282ab3dba8 }}, + {{ 0x000b613b880d4a8f, 0x000eef8e9726a306, 0x000f446cf9abc9c9, 0x000a75d40b5e216f, 0x000085573a0b1122 }, { 0x00016530e4f15d5b, 0x00032ba792d56100, 0x000aa02bcafc965b, 0x0009826da2ee1270, 0x000079f2ed0cf73d }}, + {{ 0x000b9754a0266bcf, 0x0006efd8fd6ee891, 0x00062aed3b5fa54d, 0x00038abdf16d3d98, 0x0000116ae37983f7 }, { 0x000a47cbfca3dc3a, 0x0002cdf70c33b988, 0x000e54ec4c71ebb6, 0x000f60732aadc87a, 0x0000b626c156e4a6 }}, + {{ 0x0009f8db144f77e9, 0x000026662b5f3af3, 0x0000d0c25c1ff887, 0x0007b73b1cefab56, 0x0000cd5a1cf3f9ca }, { 0x000d5a818694755a, 0x000725b3c61bfd60, 0x000d33c6e57d6b39, 0x000d8c2c2a5a4d41, 0x0000da06aa84668d }}, + {{ 0x000f71b5f5f2e3b8, 0x000bcf7d22da9a9b, 0x00080d18e517fe23, 0x000df74ff45b8a67, 0x00009b0d34e92cca }, { 0x0001751253d7af6a, 0x000152f69fc4db96, 0x000c14e7ef8dbe16, 0x000e0dc35b6dad34, 0x0000dff44628ebf3 }}, + {{ 0x0005c4cb0846e24e, 0x000db9781af2c2d1, 0x00046bf50cd29179, 0x00070f08dc0f7d9c, 0x000019b4a7b7a5c1 }, { 0x000c9beacfa5ec60, 0x000d2858e121e14e, 0x000d98641f8ff20b, 0x000390274eea7dc1, 0x00008ec5b0cee6b7 }}, + {{ 0x000bad30cf8c7404, 0x000a6d71df978283, 0x00056ce647a78ac9, 0x000f06b3cbf851cb, 0x000022014a98c474 }, { 0x0009c81e9e8866f3, 0x000bf02496bbcea3, 0x000eded9ca1c764b, 0x0009f6d293cf9fd4, 0x000097210cbc6093 }}, + {{ 0x00067291d1c7e163, 0x000a9b97b390d355, 0x000d3fd8195610dc, 0x0000e01f801df2bb, 0x0000aeaffaeb93fc }, { 0x000e7ba92c88e286, 0x000166c5f5406d3b, 0x00089d2d39130c67, 0x00026e8ce71fdda3, 0x0000429a520ee24c }}, + {{ 0x00059814cd121bf2, 0x000e16bc6fb5a7df, 0x00097795bc1333ec, 0x0007bb16ae3eea15, 0x0000ea9234811e7d }, { 0x000b866e7b5afbdb, 0x000eab01c33c23f3, 0x00043423d2bafbcd, 0x000358a51a96c1da, 0x00000a66348cf983 }}, + {{ 0x000243ce8547c141, 0x000e6d81495ed6bc, 0x0002f43f0e622ab5, 0x000c4cff3b239424, 0x0000291035b7c92d }, { 0x000997f8cbbf2476, 0x0009771dbbf370fb, 0x0006bf48fefebc0d, 0x00056dc3fff9afa3, 0x00000d06a64f152b }}, + {{ 0x00080c94a72ec503, 0x000ca2a37bbb1840, 0x00099c508afef996, 0x000d131cb51dcec4, 0x0000989196a9bdb3 }, { 0x0008f4ead02f1a6d, 0x000d0b12283fbe37, 0x0007e19e2b1d8b3d, 0x0007bdeec902bddc, 0x0000d0bde74ee357 }}, + {{ 0x000633d510319630, 0x0000a4956f908239, 0x000fdde9a26b1a49, 0x000f5c760ba0f507, 0x000011a47fccb3c1 }, { 0x00074a4f6a780782, 0x0003543b8c9de617, 0x0003e69cf7b58be5, 0x000c69ab2b475125, 0x000059a05b225efc }}, + {{ 0x000530e06a0e952c, 0x00059f773848f22f, 0x0005fec775249e0e, 0x0002f45f953dad71, 0x000030c4df804685 }, { 0x000aa392d634bc5b, 0x00056ffdd59d31ae, 0x000e1e3714bf08e3, 0x000102dd74382e0d, 0x0000d560753775a1 }}, + {{ 0x00032c96e155ca24, 0x0001867648024ee6, 0x0002290314ec3e56, 0x000e4a435188763f, 0x0000359aad14cb65 }, { 0x000aec2c62bf9c7a, 0x0002c0e4c00a95ea, 0x00003525bd976a14, 0x0001af8232ef17f4, 0x0000950b712f6e56 }}, + {{ 0x000cb27078304cb0, 0x000d8d83d84e58c4, 0x000c48d30163a309, 0x000b9d2a62af5094, 0x0000f43399bda145 }, { 0x00025423b825ac58, 0x0006d474ff0e321a, 0x000578e0a546e9ad, 0x0000fc3a7169f34a, 0x0000fbaf5744de2d }}, + {{ 0x0001d6998c9bae7d, 0x00058d50ac8b7823, 0x000bfbdd2f05c1a7, 0x000dd3942ff6622e, 0x000068b2d4cab4cf }, { 0x00020e9934c184c5, 0x000bb04cadcaed01, 0x0002c60e6c081a2a, 0x000de49c6801b014, 0x0000c34427b5c797 }}, + {{ 0x000321a50d8134d2, 0x000c8a4fdc6a4043, 0x000e6e6ef43ad26d, 0x000b3c48119d8e01, 0x0000448b0fd8e456 }, { 0x000066350f1fe586, 0x000e263e9a861112, 0x0000e63d8756b063, 0x000ba08ef8c0cde6, 0x000050af05bd3adc }}, + {{ 0x00058deddc932110, 0x0003689e56ddfbd6, 0x000798a4aa5dbc69, 0x0001ba8cbea1b0c0, 0x00007b58c49685f4 }, { 0x0002efa53a6c1ccc, 0x000e34d0f64ef589, 0x000ce01d226df9d2, 0x000e7b170fe43287, 0x00000387e93337d0 }}, + {{ 0x000bbb69838b4dc3, 0x000c15794b565268, 0x000e7da596a97b99, 0x0008eee0f415cb80, 0x00008189781ee1eb }, { 0x0008da59e33a17c1, 0x000b85b9abc26689, 0x0003858d35ce15d0, 0x00065e1b9b5d4f53, 0x0000e8073f5adb41 }}, + {{ 0x00041b32e5ee0cd0, 0x000bea601799a527, 0x00014451f66c2b00, 0x000f25a7ca20cec4, 0x00001caa549ccc91 }, { 0x000641caaadc47ea, 0x00097814eb57d471, 0x0004006d25c11bc5, 0x000a4cb887a2d0ed, 0x000005cf797f0540 }}, + }, + { + /* digit=4 (1,2,..,64)*(2^{28})*G */ + {{ 0x000cf9a2f2b6ddb7, 0x000cb4f20151427a, 0x0005e5495f13c8bb, 0x000336c57206828b, 0x0000deb474abe52a }, { 0x000c630fc54290e0, 0x000e9da279153564, 0x0006b3bbef1e9949, 0x00021a8e27e0734b, 0x0000614b2885f690 }}, + {{ 0x0004ab68d7e959ee, 0x000227a1ac2703b2, 0x0008471ceedd9bdd, 0x00080ded1b49258d, 0x0000011c8d9a06d3 }, { 0x0000b360f8d06cf6, 0x000bfd4734e59d08, 0x000843e26b87ae6b, 0x000b0c3b35f8740c, 0x0000b6d468726158 }}, + {{ 0x000ac1e3e5d6df58, 0x000075d5fa067d1d, 0x000ebba6b226d7b2, 0x000af82ac4134b57, 0x00001bb953caf0cd }, { 0x000cde538c8bc9c2, 0x0003669d81fbb26c, 0x000be58de047db86, 0x0007841e8449ed3e, 0x0000d643fef5794d }}, + {{ 0x0003331d3c69f2bc, 0x0000a8da61a76fa3, 0x000d96e2379febe3, 0x000486b9c598b441, 0x0000390a58c27d0d }, { 0x000cdb9daf4c5417, 0x0006d8e298de399d, 0x0006c4c6e1a6e0f8, 0x000649470cfdb8e7, 0x0000690440cf3b0b }}, + {{ 0x000cd3d0d4027b25, 0x000d3c2019f2a596, 0x00035e7beba07964, 0x000164eddb3ce5bb, 0x00000d8037d39488 }, { 0x0000c29968554c2a, 0x0009ad6efed021c1, 0x000059b49a323da0, 0x0003c9c4a09a9f9b, 0x0000c0cc53fbad1c }}, + {{ 0x000c73d2287162dd, 0x000c529ed6e82ef1, 0x00034977dd25e6f6, 0x0004a8aae16f338e, 0x0000dc61c21e5eed }, { 0x00096fe447e4eae7, 0x0006a3174a5c8c7d, 0x000fa5f9c92267ca, 0x0007c117e01cd296, 0x000068abc8039604 }}, + {{ 0x00041d6367599350, 0x000706e88fbd3813, 0x00042818412bda97, 0x0005e6bcd02cd4a8, 0x0000b40e707676fb }, { 0x0006fe0a3a3a6e7f, 0x000d8fbd238202b9, 0x000a1286e09fb174, 0x000d4efa0600b4d1, 0x00005566cd140a17 }}, + {{ 0x000246780b6116f2, 0x00015367f636a38c, 0x00064c305dbfeb38, 0x0009f998b9f943fb, 0x00002a4f058aaf47 }, { 0x000300fadd2ed37d, 0x00097156d549fc2b, 0x0000ad7686ed0d31, 0x00005d713c2953f3, 0x0000c01130ae8caa }}, + {{ 0x0000e57c5b8cc8c5, 0x000b65087e9189fa, 0x000c53485dcbf535, 0x000419404db17375, 0x0000410edb213b42 }, { 0x000cf14a112a5ea6, 0x0006bd3f40e3c80d, 0x0000b0c5bbb47bb1, 0x000a038c3b118932, 0x00002d9c468c8d26 }}, + {{ 0x0006c8b3e970a581, 0x000a55b556913429, 0x0003fa3be9dd94c6, 0x00015610ae8e0850, 0x00009ceceff70c59 }, { 0x000953c3d70998e4, 0x0001438fb4ee6b40, 0x000b3895091982c7, 0x000476cc6fc5a9ae, 0x000057745cd78df1 }}, + {{ 0x00071e305a112a00, 0x000268238dfe7e82, 0x000504996cf1100d, 0x000bdcf2dea417e1, 0x000026436feec265 }, { 0x000396770a6a23bd, 0x000c0fd7253ecbd7, 0x0004dc33ea7bf828, 0x00062b19c2f552e2, 0x00001ac28594c2e3 }}, + {{ 0x000b1dac7015ef7f, 0x0009263c27901b4b, 0x000fce7ddf838b5b, 0x000d75b0afd9236d, 0x0000069d82647cb5 }, { 0x000f374bb4fe7c59, 0x000c453a91cf76e1, 0x0002b3e7d3328269, 0x0007376774110a41, 0x00002b0cccd10515 }}, + {{ 0x0001616338327868, 0x0007af20d188dab3, 0x0000c35722b72c00, 0x0009bef0fe3968ed, 0x00005947d75b5640 }, { 0x0006a44d86a5f4a0, 0x00047e24f0c8afe3, 0x000fa8462b5372ed, 0x00068ea514caa75f, 0x0000f6f22bba6bd6 }}, + {{ 0x000ff17a8fcc8db3, 0x000a8da0333974fb, 0x000d67b586b70a9e, 0x0008146215db516a, 0x000074410c8af154 }, { 0x000c274e88147e8f, 0x000f24e12476da14, 0x0002e79a1af86475, 0x000cebccac1e1661, 0x00006666b278e72d }}, + {{ 0x0001da368c16a10b, 0x000ad8d6c2f5226c, 0x00039333461ca008, 0x000230c0914d1b94, 0x0000a4acd35a7009 }, { 0x000b480cfa6c0f39, 0x0004cced5113cf71, 0x00033eec6394bef8, 0x000bd06880670f63, 0x00008997a9636ca9 }}, + {{ 0x000953c50eb5331d, 0x00069024147519ad, 0x000b4d5fade16af5, 0x00052cec8d0981ea, 0x0000f785b3ffbbf2 }, { 0x00063ebb7f24f144, 0x0001dccfd590f8f8, 0x000abea80d987872, 0x000fa20cf72e9626, 0x0000721e8be990fd }}, + {{ 0x00083e50e54aa3f3, 0x000c4616aca8ee7c, 0x00090f75b27323c6, 0x000bbf80d97d10b3, 0x00005e98ed7591d3 }, { 0x0005f9680c64a8ca, 0x000dffec954b3132, 0x00070b13b7552acc, 0x000af06e0cc2e8f4, 0x0000143469e3b900 }}, + {{ 0x000561bf1c36fc6e, 0x000f8094354080b3, 0x000546913f00c25f, 0x000812afa5225bfa, 0x00007cc75ab3c625 }, { 0x000332d9e420107e, 0x0002117ba1514741, 0x00049d1c94e63e5f, 0x0008a4d1edec2f93, 0x00007771c10cbd06 }}, + {{ 0x000cf057fdaa6cc2, 0x0000d69df23de05b, 0x000143a2e1a2b66a, 0x000fc772366d17da, 0x00006a8d4733875f }, { 0x000c23b3ee9a963f, 0x00089c5f0b5662c7, 0x000860969b36292f, 0x000952aff25318dd, 0x0000ef7f5b56866d }}, + {{ 0x00039af66ebf381e, 0x000ec0a097e4403b, 0x000565ea4ff656a8, 0x000452a26cb3d0a8, 0x0000a7947609a317 }, { 0x000290d33bd0a0a9, 0x0009c88bd475ca8d, 0x0005ede6e4cfd558, 0x00087196ce06b796, 0x00001bfceaea4a09 }}, + {{ 0x0003e4fe080af01f, 0x000ad47f34fb0fa1, 0x00080bccad01991b, 0x00083a0e3b4760cc, 0x00004486d52a8b97 }, { 0x00069059367f304a, 0x0006f92fdb05163c, 0x0000459ac07fbc9d, 0x000c299e28c484b1, 0x0000e9d36b72292b }}, + {{ 0x000ab74e6a2a524b, 0x000249d586e74e18, 0x000cdd00b61a885b, 0x00049f2db488883a, 0x00009b15259f5d0c }, { 0x000de0781ad6fc39, 0x000f4285e21beb19, 0x000993abcade39ff, 0x000d307c33484518, 0x0000f3708fe8c17c }}, + {{ 0x000604437bc3417c, 0x0006c58693807e1b, 0x0006987d894bcc6d, 0x00041df84a386532, 0x00004f10004876ac }, { 0x000a01df0ef92b9e, 0x000ec985ca1823d5, 0x0008a9bc2415bad0, 0x0003cac33b82f7ec, 0x00008c8d609652d6 }}, + {{ 0x0005e94efbb5789d, 0x00065f31306583d2, 0x00001d931332b2e9, 0x000f1dec805b10da, 0x00003f4f29f81351 }, { 0x000ede6596524043, 0x00086b7fa3dc26dc, 0x0002c8209e2f37f5, 0x0008351cee0e5fb9, 0x0000f62ae015ad99 }}, + {{ 0x00025ef904c10f7c, 0x000a6f6a19935459, 0x0005927778b6116c, 0x0005a468eab01cc3, 0x00007a92aaab72e0 }, { 0x00060897892570ee, 0x000b5cf53aa0b32d, 0x000a9bbc05f115be, 0x00094f47fb27beb5, 0x00009605766eabab }}, + {{ 0x000cf6c431cbebca, 0x00082e0d6fbc2acd, 0x0000a469311f571d, 0x00003479c738037a, 0x0000ebc968b789a0 }, { 0x0002ad6eced662ff, 0x000ff7be3ef104a2, 0x000be758e7592a81, 0x0002f053eebdd9a2, 0x0000d738f011f4b1 }}, + {{ 0x000c11a2e84862b7, 0x0005cc039cd297dc, 0x000d39ac02f15755, 0x000ad94968ec7e16, 0x0000f7a4858d93c4 }, { 0x0007c422e7b70ed4, 0x000865396ee63809, 0x000536df645adfbb, 0x0003f267d054c865, 0x0000eed4df196b1e }}, + {{ 0x000ba62aa6a9ec8b, 0x000ea090c22b5403, 0x000a7c1c3d2e15a3, 0x000c44b932cde42a, 0x000080285f5a46b0 }, { 0x00066c5b9ee54102, 0x000f77bab9ea96a6, 0x00027d49b293cd0a, 0x0000c99d55d03964, 0x000042cd3eeb6797 }}, + {{ 0x000a56a7143dc2a2, 0x0003ad98edbd7cc8, 0x00073c76303fbc7d, 0x00024144f4660bb8, 0x0000534e55030be4 }, { 0x000b2524cccf0e8b, 0x00055965726d47f7, 0x00018ff575b2dcee, 0x000a8bf379eed01b, 0x00003984d331077f }}, + {{ 0x000539a4fc4c4c2e, 0x0003a3b8f4b002f6, 0x0009dcbb57241ddd, 0x000e75cccc2200d7, 0x000071b64d7d7ded }, { 0x000b7a26a5d05150, 0x000cc14c33c7fcf7, 0x000b4c440b85fe71, 0x000f5a6237eb6799, 0x00004066761e4395 }}, + {{ 0x0003ed2c34dbfa56, 0x0009a8d403f46f2f, 0x000226219492ef3d, 0x00037be2f94b8fc4, 0x0000aea3923eaee7 }, { 0x00047ff958e890e9, 0x00097afb639126c8, 0x00005ed54185a48f, 0x000ed4209f7b6be6, 0x0000839d619a4633 }}, + {{ 0x0009fb18a0fee18b, 0x000f1f5678a31b0f, 0x000d3f9d9d7f8899, 0x0002e2896d50301a, 0x0000467828ca24c1 }, { 0x000a2f2a98bf1696, 0x00042ebe8758851b, 0x0005a36a8fac4075, 0x000e6fdb71e64e4c, 0x00002450761a46be }}, + {{ 0x000106b953c0b0b7, 0x00055bae8053433d, 0x000f6c25dc31bcc8, 0x000283eedc8e7259, 0x000070486fc2230d }, { 0x0009b714490d84cc, 0x000ab5b0eff13a96, 0x000a76a0a4e72ed7, 0x0003240bd242442b, 0x0000e38dc2108bbc }}, + {{ 0x000ad0436ab80ab8, 0x0008ef60e2ed7422, 0x00051536312889e3, 0x0004a0b04573f104, 0x00006d3f1bc994e5 }, { 0x0002b773beca9fd2, 0x000d82d431a8121d, 0x000ab5b79e2f23aa, 0x000aa3cb7cd38b3a, 0x0000164fbcfce738 }}, + {{ 0x000d927bed2c4843, 0x00057c49b5c1f14c, 0x000970c2633e1e0d, 0x0005bd591c444be1, 0x00007472609e17c1 }, { 0x0007c6a79d00e920, 0x0006516e48c8a348, 0x0001c38dbeccea53, 0x00064d8ec1b7ac81, 0x000001913870f958 }}, + {{ 0x0000b9e865afa38c, 0x00016f09b56ddbdb, 0x000bd975348dfe5f, 0x000fa730d1339b5a, 0x0000a2f19f0d61d3 }, { 0x000bafec279d834b, 0x0007f4177bb064e9, 0x00026174b33bb275, 0x000ec1d9a145a281, 0x0000853c8b1d855a }}, + {{ 0x0004b8f6ae320ba5, 0x000a7654265aa91f, 0x00030ea60793f5f9, 0x0002e39c7a4b1830, 0x000052a5da5f3864 }, { 0x0008eb65e67a4037, 0x0005ccc971a8a130, 0x000d43a7e7218152, 0x0006c85293f159e5, 0x00000f9da5baca8f }}, + {{ 0x0007b514916e3af9, 0x000fc8930b75c3ed, 0x0001bc940801e1b4, 0x0007469bb0bb82fe, 0x0000306f321be91b }, { 0x000a91fcbaa89e73, 0x000277b04497f19d, 0x00093fe8d485032c, 0x00029fbd61b35ed0, 0x0000ab396c946696 }}, + {{ 0x00043b4fbd7ee0ab, 0x000a57bd7ab27e14, 0x00051f590bbe1f47, 0x0001bed277c19a55, 0x00004ea5e94be42c }, { 0x00079cdff78fa878, 0x000b6656962c88f7, 0x00045670d0d30682, 0x000e4f44f139da8d, 0x00001bd14a9de58b }}, + {{ 0x00003907bb055ec3, 0x0007cddae57c7b7a, 0x00017b5a1d67b643, 0x0000e87a3345342f, 0x00001c62c23c4350 }, { 0x0006a27dca73d570, 0x000a0e1ff2189336, 0x000443af93b0c4da, 0x0001d76eac066b65, 0x00007c9b470b5621 }}, + {{ 0x0007ec6e15fb0c4c, 0x000ad93048b37172, 0x000a898c40066ebb, 0x00042d16bbf5a989, 0x0000641d1a6e425b }, { 0x00009c3566d8138b, 0x00078737276e7fc9, 0x0008f93a899b74ba, 0x000ba4e7964086d7, 0x000097a1ea45df74 }}, + {{ 0x000ca56513af6eb9, 0x000036b75dd7125f, 0x00068afadd796c99, 0x0007cb29db4c6bc9, 0x0000450348223f4e }, { 0x000cf70def0b74d0, 0x000a181d0e8bd06b, 0x000709c438fb0a64, 0x000dde624384dd31, 0x0000e9a2bfac312d }}, + {{ 0x000ec09a48204c79, 0x000886e6628e8c30, 0x0007a749dada16de, 0x000e7d5e207a0d66, 0x000034e09153d2e9 }, { 0x000c7f44552abda4, 0x000994ed83dce467, 0x000d1d53b819438d, 0x00011604c43a6316, 0x00000c57dbe9342c }}, + {{ 0x0009b1ddeddfb155, 0x0005c21fbabbe926, 0x000b77812288d335, 0x000d7ab15281850f, 0x0000e27f34f8feb7 }, { 0x000c9f1b87c58c64, 0x0004d8fab1051053, 0x00016bfdb467b764, 0x00004dc09953ced3, 0x000034ba3f40d826 }}, + {{ 0x00067e10d16361cc, 0x000d5a14a7eadcb4, 0x00010bb060fe6649, 0x000cc8383928e750, 0x0000a507d1a255d6 }, { 0x000d744bd0c7e26b, 0x000bfc3b955dcf05, 0x000d766199572b61, 0x000958974ba96307, 0x0000c161d1c03e35 }}, + {{ 0x000b7e2a947ab5c8, 0x000602aa777899e0, 0x000fc4c1124a57d1, 0x000fab531e20eda8, 0x000078d9b61326d5 }, { 0x00039bad6e2b1553, 0x00011ad19f593cf4, 0x000edadb41af06b6, 0x000180d9c7b1a9e4, 0x0000bec906422f8b }}, + {{ 0x0006fb4c2d81211e, 0x0007266e032f1445, 0x000891b7a03ca07c, 0x0008011781db632b, 0x0000932932e1a77c }, { 0x00027d6babb8c904, 0x0002ae1255a03f19, 0x000256ed85caa685, 0x0009fb89761cd6af, 0x00003a067d13fd17 }}, + {{ 0x000b89a4e82f20ac, 0x0005be0e90fb21e5, 0x0000601e57b9726e, 0x000acbbb500fd2b8, 0x0000def3cf863f66 }, { 0x000f548f31add03f, 0x0006e3f894407ce5, 0x00040ccdd200e1b3, 0x00036823ba0025b9, 0x000057161113964b }}, + {{ 0x00088658197f5e5d, 0x0000e8feac6d1135, 0x000bb5fae45cabee, 0x0008397b9a67e3f9, 0x000027605a7662c0 }, { 0x0005660e1a5eff95, 0x000cf0cf7f06f200, 0x00062500dda83af3, 0x0007a8908dc61021, 0x000035ac8c485b17 }}, + {{ 0x0000a886286039e7, 0x00030626d3c46934, 0x0006f744f5c20ad5, 0x000213b6df0e7d62, 0x000063e4a8b99f57 }, { 0x000bf9a358ea18f6, 0x000c4a7bbb38ce0f, 0x0004c1e30a289e84, 0x000b0711fe0404b6, 0x0000cdecdc1fe1a1 }}, + {{ 0x000970195f38876c, 0x000fdb028f33398d, 0x000c9978f6062539, 0x00023b2b1b07ec11, 0x0000e90d968debc2 }, { 0x0003e03b335e7e4e, 0x0000ebe0181e6402, 0x00020262f609f432, 0x00074d182f5debd6, 0x0000f8b0b29420ff }}, + {{ 0x000447ad7afa3513, 0x00076494fde0c1fc, 0x000e216f3ea60540, 0x000acc86cbf8a1ab, 0x000009a60fde808d }, { 0x0006736b8b4a3189, 0x000213803d0ccf24, 0x00083b271077fea3, 0x000e645cc80acb33, 0x00000d9f85e61323 }}, + {{ 0x0007a56d943a749e, 0x000dd60c0432f963, 0x0003a70fd69b9be8, 0x0008acba2ddebe7a, 0x0000b67c71837343 }, { 0x0008b4408a4b9b5b, 0x0002fedf2350d0a8, 0x00057ac6cd104010, 0x0002b01ae13c3f27, 0x000012894baff1f9 }}, + {{ 0x000b605ef4a68b33, 0x000b2a35cb026649, 0x0000eb26683a34fd, 0x000f7a23e5d4c0bf, 0x000025f5686f6dff }, { 0x000715b3a144285b, 0x0006702c69645d0f, 0x00097305b3462d92, 0x00066f2c4a115f03, 0x00002d4b3efd98d1 }}, + {{ 0x000d8c3079ecf96a, 0x000a048d413213a4, 0x000d72bfbc61a285, 0x0008c1df52035806, 0x0000eb8c40841f70 }, { 0x00042be3c0b0a8c3, 0x00067678d95a8f6a, 0x000d4de5294c6a81, 0x000e6f73fc58c9d7, 0x000028eb6b61151e }}, + {{ 0x0001f8fbd7da4886, 0x0007142d43b5eaaa, 0x00063dac9fad46de, 0x000237745054a076, 0x000066d55ce85e38 }, { 0x0000aad9183a3f7e, 0x00002f5d563fccc1, 0x0005e1d5d00ff737, 0x00075facf48ca505, 0x00002d09a02699ed }}, + {{ 0x0005475f79a136dd, 0x0009e62b7bdc9534, 0x00021679276438a9, 0x0002811779f0f6ff, 0x00006a65c14a85c4 }, { 0x000d71419bada82b, 0x000fdfa86f702ccb, 0x00045190dd6b9201, 0x000e77dc692e6090, 0x0000c7da1d12ccd1 }}, + {{ 0x000831b6ca7da654, 0x0008dcc6028da9ad, 0x0009ea203ea89978, 0x0000343f45352fe1, 0x0000299e73c0a3c2 }, { 0x000d50ba88136cf1, 0x0003d1de350e2c27, 0x0008a0bc297b691a, 0x0000804cbc56240d, 0x0000b08ffae6ef56 }}, + {{ 0x000b049ff6e562d0, 0x000c4265a3a2518a, 0x00091b2b9d4cf195, 0x0003b8696cf81779, 0x0000718b68347a7c }, { 0x0000d0bf5e9df0d2, 0x00027b0feb13ec70, 0x00079cbf39ae46dd, 0x00009c4afd5e9711, 0x00000194165fa7fd }}, + {{ 0x000d542a16dde633, 0x000fd1f358bcdc04, 0x0008bd491de20858, 0x0005da13a07689e9, 0x00001aaffaa71871 }, { 0x0009749558e9ff03, 0x00090d59ca0a7072, 0x00056151eb0cc4a3, 0x00090fd8cd061fe4, 0x00000ed0be2cc216 }}, + {{ 0x000229acb440cbd2, 0x0002a59c1d5d0340, 0x000665b8692c33ea, 0x000362ee6f712e9f, 0x00003d3bf4320945 }, { 0x000d5dbb02d12e1f, 0x000c24cfff0c82e2, 0x00022c68e370cba3, 0x0009e9a8987684b6, 0x0000967e564a19c5 }}, + {{ 0x0001f390883520b9, 0x0001a3ae86b173c3, 0x000575ac605bbd0a, 0x000ec5310e8e41ea, 0x00008104ffff9da7 }, { 0x0005cd6ee65978c1, 0x000b0e17829839ea, 0x00039f353f7221c6, 0x00083a0150cf691b, 0x0000faa310dfd765 }}, + {{ 0x000fa20deeef2680, 0x0000d7b5f1d23474, 0x0009fd20174b3146, 0x000121e08794645b, 0x000077749c4b1069 }, { 0x000a1c9150ecf76e, 0x00004d8d797770a6, 0x000d55260cd5fea9, 0x000b814797360c91, 0x000033f4db806293 }}, + {{ 0x000379ae15e41fc7, 0x0000ca7c35d87949, 0x00076fdd0ccf2ac7, 0x000135bfd042e655, 0x00007cefff827780 }, { 0x000b09f648a49efa, 0x000b462fcc9981ea, 0x0000c21f3e7dc01a, 0x000af6bebaed3d63, 0x0000701de9b6b9b9 }}, + }, + { + /* digit=5 (1,2,..,64)*(2^{35})*G */ + {{ 0x000a823a4160c545, 0x000f51222248acc7, 0x000eb7e2a9255142, 0x00038a9281f6ec0e, 0x0000f63c9cc1c2fa }, { 0x000efe9ed3f2c904, 0x0002604e1900a791, 0x000aaaefc6a23190, 0x00095a14acde09d4, 0x00007b2680ab6b58 }}, + {{ 0x000c47940a63bdc1, 0x000acbe305406dd9, 0x000f4115854d7ebc, 0x000bf8c8f8eb7dc7, 0x0000eebcc0956bd4 }, { 0x00040deabe2974cf, 0x0008c5d99b307781, 0x00065a6b4bc494d8, 0x0005271e325380c5, 0x00006c75941c35b1 }}, + {{ 0x000049d7316af76b, 0x0006567afd32acfd, 0x000a11ad459dd98a, 0x0009f87dad8f0fcc, 0x00002a6cb670db4a }, { 0x00027074910360a8, 0x0007e3d42ab580e7, 0x0000b1869323c43e, 0x000fd66da09411bb, 0x0000931dee156e7f }}, + {{ 0x0003c3a8ea6b2c0c, 0x0005526c49a861ec, 0x00051d8b641c7fc2, 0x0006ff017024f3b6, 0x00006af90c54fe5b }, { 0x0006848b57a6af77, 0x000fe2cb103d4c8d, 0x0002bb9428138d50, 0x000a1d94a02bc461, 0x00005196aa6193cf }}, + {{ 0x000a9423bc0124a5, 0x0005de6c30fa92bf, 0x000c9fc103c8bc73, 0x0005e719b5a70d96, 0x0000e39716462e3e }, { 0x000d96bc718ee9dd, 0x000e112fe97a5b9f, 0x00087422d4a6a114, 0x0002dab4685da604, 0x0000ff2e0f500dd4 }}, + {{ 0x000f0e96b0521716, 0x0006bdb1782269b6, 0x0008b6894ea0436c, 0x000213b53ae34bf7, 0x0000f89e64dfb40d }, { 0x000020f0e5f7aa5e, 0x000a41577884456e, 0x000b89101dc1c7bf, 0x0005074deb3b5688, 0x0000322f52afaf0d }}, + {{ 0x0002cfa977b4a1d5, 0x000cbab0976505f7, 0x0002968e854dbe69, 0x0008fd671567f681, 0x00001688d84b98ae }, { 0x000f34f1cd8b8aab, 0x000b3ad8a2373da8, 0x0003ec6f689aa85a, 0x00077f215a8d0d5f, 0x0000c0b67348ce77 }}, + {{ 0x00039b66645c58c8, 0x0007a8dbbe5a1a9a, 0x000e8d8b5703704b, 0x000b790268187fd5, 0x000003b8f3f8d5eb }, { 0x000b2f3a4a4db66a, 0x00074ef2d65a8087, 0x000f193430cf1f8c, 0x000a6ec4c4969044, 0x0000c1c8991dfd8f }}, + {{ 0x0002864e5048aa8c, 0x000f145300eb294a, 0x000d7415c6444b6a, 0x000f9eea92b2a656, 0x0000f466251b268a }, { 0x0006be862b1eb6e3, 0x0008947db89842e4, 0x00071a89198c63ba, 0x000fc13dc12dfd7d, 0x0000921392892bc1 }}, + {{ 0x000b8888bb33c9a0, 0x00038dd0f82b2148, 0x0009657b430acfe7, 0x0000dfe19460c34f, 0x0000b39b6f7347e5 }, { 0x000bf0221449dce2, 0x00055dcc07226779, 0x0008802bed13455f, 0x0001abec610d21be, 0x0000f48269445497 }}, + {{ 0x0007c2ae5722977f, 0x000fe1242b48b998, 0x000cc07f923ee912, 0x00063ddfb1bcb665, 0x00006426594d7fc9 }, { 0x0001f5e5985dc788, 0x00029220de367261, 0x00082de9d7899404, 0x000b24c60e7043c6, 0x00006397a224d1f0 }}, + {{ 0x000dd04b97f56424, 0x0001d60b7fe7b6e0, 0x000a3239f41aa1f1, 0x000c4a61e7d16189, 0x000064bed27452ed }, { 0x00079b5499dfb43f, 0x000fd9b506db8cc0, 0x000ec79d2cb2ca13, 0x0009706e65cd47aa, 0x00001dff152d73d6 }}, + {{ 0x000ad76ee910eedb, 0x0003602c1c24a3b9, 0x0007813ead31dac1, 0x000012f4aca24e56, 0x0000638656568026 }, { 0x0007b4a7bd68d6f7, 0x00028c2538e0ff72, 0x00093e500bf32e6e, 0x00072d8d794f8980, 0x000026a43392b0c9 }}, + {{ 0x000aa7cb935a507d, 0x000551ae0ac29416, 0x0004582b4da3a965, 0x0007915d0279b025, 0x00008622b071bf70 }, { 0x00035a70c90666d4, 0x00051800d37c7a50, 0x000730d2e35953b1, 0x0006c1b9213380c3, 0x00008f95b8909dcf }}, + {{ 0x000c43c6cd7fe37b, 0x000aadd4ce4f152f, 0x0000fd9bb539417c, 0x0000140141f419a7, 0x00009af0fad64712 }, { 0x0001a9c2a0337ed0, 0x0009591925d6b2de, 0x0002806ea2f81671, 0x0009c46294b37d9d, 0x0000a4de29b6d19c }}, + {{ 0x0003fba6baaee763, 0x000548571ba18615, 0x000c7ccd5282a222, 0x0004c589348b22d5, 0x0000c343e640ecd7 }, { 0x000d50cd542a5f8c, 0x000f1f3e5eea7d82, 0x00063b79a4045592, 0x0000f8e05521c879, 0x000038b6e3d1e7a4 }}, + {{ 0x000a89dbdc1abdd9, 0x0003cd6c5a3ef169, 0x000d1f7db645ad63, 0x0009fcf1c993eff9, 0x000061650e298230 }, { 0x000c6ab8862e32eb, 0x000b3bf2b892891c, 0x000090a9ec4f324e, 0x000cab92153902b2, 0x000009cc8b82cba9 }}, + {{ 0x00084b1fe4ac70cd, 0x000d433f74cff170, 0x0003e46cf40d687a, 0x000f58eee240aaa0, 0x00005873e1125bc2 }, { 0x000ada9f07b6f730, 0x0002d16d081f6a60, 0x0008e41d8d8849a6, 0x000a77a2235304fe, 0x0000eb9e1fd7cdf3 }}, + {{ 0x0001bd2ee144dc4b, 0x000cb78968a61446, 0x000ba5f5eb3d6205, 0x000a5b0e154c1f77, 0x00002bb9da949d12 }, { 0x0001db4ebe3697d8, 0x000c9e9781105fc0, 0x000f79543fc2bbc2, 0x00067b99b9cf2971, 0x00002c5b8ddd5497 }}, + {{ 0x00065daedf9277bf, 0x0007f23b40df1cf8, 0x00030e8bc2d4eb23, 0x000253a215933737, 0x000043cb71cd34d4 }, { 0x0009699f551d880e, 0x000fdd3832791254, 0x000eeb833b56212e, 0x000ed4eafbc3d5b9, 0x00005766025c2941 }}, + {{ 0x00074ce7196c4a18, 0x00058e1d4a7a15b6, 0x000a835fa0cdac0d, 0x000e71bea08f3587, 0x0000153a1d49c1da }, { 0x0001ea48a86150df, 0x000b935088b3e0e6, 0x0008fb22fef91a3c, 0x00023c4c47a0356a, 0x0000149d050cb103 }}, + {{ 0x000a6b2421ccb0e5, 0x00092580f3e48342, 0x0001ed3e8ba96390, 0x000e982b3fdbb21c, 0x0000ca17b5625d62 }, { 0x0004efa84d6f03e8, 0x0003f944af02291c, 0x000565685cb0f5ba, 0x000eca7d7ade465c, 0x0000883813fcec37 }}, + {{ 0x00007ae2719b9b5b, 0x000c02a442b0f5c9, 0x00073f1e94c5061d, 0x0004db316b748e31, 0x000031983bdb4e33 }, { 0x0001a9c0d712eeb4, 0x0009f4b0c9bcddd6, 0x0003d8040daccc42, 0x00037d06a043fb05, 0x00006a4a48036cc5 }}, + {{ 0x000ac71e23fc88f2, 0x0008e46477184276, 0x000b03bbf167de2b, 0x000112147df17ff9, 0x0000d1d24f52c4e8 }, { 0x0008aa8296dcbae1, 0x000d8fd1defd73c7, 0x000743117c2eec10, 0x000c417ea1984065, 0x0000c69deb7b1ec1 }}, + {{ 0x000974f73d3cbc56, 0x00061f0a3738c290, 0x000ab2bd5966671d, 0x000a1f6af0a2f235, 0x0000b7892c65b907 }, { 0x0006060d7d7242b0, 0x0000ba35ba2f5a80, 0x000364edf2e9613b, 0x000948e2c542c6e6, 0x0000bb93163dd653 }}, + {{ 0x00001b3ad0550c5c, 0x00095c2065fef4a2, 0x000ddd40581378b2, 0x00064275077e60f7, 0x0000900cb66b1fd1 }, { 0x000fc0738fd99566, 0x0005ca10334fc145, 0x0008d484df668635, 0x000cfca828a9a9e0, 0x000018f7ad9443bd }}, + {{ 0x000efb14b1a6205e, 0x000c64d17d2d8c38, 0x0004e187f1d2d25c, 0x000d6dce5effc634, 0x0000567500e02c3e }, { 0x000a688b252296a0, 0x0009eee2245ae7aa, 0x000e3fa966194c20, 0x000197f5dbca4061, 0x0000512da556f80e }}, + {{ 0x000e48482682519c, 0x000f271bd3502bad, 0x0003d6962d79e50e, 0x0000f89e54ef41f2, 0x000065549732387b }, { 0x0001a43c79f96f00, 0x0008d9865cc22950, 0x00016c6aa32825aa, 0x000845fc7428a377, 0x00004147615b28b4 }}, + {{ 0x0002125ed3349bd9, 0x00097590fd3659a3, 0x000c896ccec77bc1, 0x0005dabd38927f30, 0x00001842ad4bd958 }, { 0x000b61fc67c66d39, 0x000f4ad3d4142055, 0x00028898864234e9, 0x0009d1c8173000ef, 0x00000cb713a5822a }}, + {{ 0x000568faf8627d03, 0x0008a5b7cae440c3, 0x00010ac27a395ea8, 0x00016202121c08b4, 0x0000a8232e915d7c }, { 0x00081b20b280f35d, 0x00001999ecf965b6, 0x000880fc06bcf0be, 0x000199ce2f14ed24, 0x000030dfcd06ef01 }}, + {{ 0x000461905346ffbc, 0x000b78dc6c011203, 0x00037a0f508825de, 0x000b0258c71db081, 0x00003aa89a31f12d }, { 0x00074bf462da8bad, 0x000afeadb2a3b15d, 0x000e04007c10a5d5, 0x0004726670a49a19, 0x00000c115b3d65b5 }}, + {{ 0x0005910a01f9dd2f, 0x0003e65533ef2177, 0x00044e3924858ec2, 0x0004e12677158c7e, 0x0000817fb332f9e2 }, { 0x0009f8be4c5579ed, 0x000d207cf88577d2, 0x0000ba656c829dbc, 0x0002850852224525, 0x0000a45a5a5d4127 }}, + {{ 0x0000f984312881bf, 0x000fba7076fe12bc, 0x000aed1bb3c8b51c, 0x0003c3c463f2400c, 0x00007182316ff6ef }, { 0x00040b796b1fe386, 0x00067e10170911db, 0x000a80c9381435ad, 0x0004332d27562f5b, 0x0000c44dd22a86f8 }}, + {{ 0x0008f3a69b2e986f, 0x00082973467ba92a, 0x000b4e15ae15a7c3, 0x000e0825d8c9b46d, 0x0000fc1d6d6957df }, { 0x000e56dec238f6a0, 0x000c60f61e4ce9b9, 0x0002d04f9a4a094b, 0x000a1c416bf06aab, 0x0000e7611030ccb3 }}, + {{ 0x000bb61ceb16d2d4, 0x00072f49a9898d9a, 0x000aaa7db1043ba9, 0x000cb6e97d799e77, 0x00001e9007832b66 }, { 0x0003918e6dab135c, 0x0008ca7f778443cd, 0x0000564ca17913cf, 0x000f05f6f3bb42bf, 0x000063a36f543384 }}, + {{ 0x000b7faa84dc37b4, 0x0007e719a5103f11, 0x0006d98f01816fb6, 0x000a50d195243efc, 0x00008d79992c468e }, { 0x000fc83cb87ebe8b, 0x00046bd6dfcd08ca, 0x000d5c1beb25b405, 0x00067b183129dec4, 0x0000b767a1b5e39e }}, + {{ 0x00044f601bff0a52, 0x0000e882fa6be76c, 0x000a4ed96be286e1, 0x000573bda892585f, 0x000089fc0fc5d1d0 }, { 0x00076f26dd1cd1c7, 0x000b60b2be1fdfdc, 0x000c59a459115f23, 0x000e3caa8a833bd2, 0x000032e8b64f5910 }}, + {{ 0x000c72c01889f6f7, 0x000ed7d3fdf5a517, 0x0002d9570a979390, 0x000e9616e7afb5f9, 0x0000219f402c76ff }, { 0x00053985e9b35d2b, 0x0007ffb99b5c3dc4, 0x000cf30b28c6f648, 0x0000ab982a48a0f1, 0x000083df9c5cf403 }}, + {{ 0x0008892c68df5eaf, 0x000196001b25dd8c, 0x0008330050216af6, 0x0004a5dd90dd37f4, 0x000075766028a72f }, { 0x000015de22cdfad4, 0x0001bc0ef514ca5f, 0x0008f716c0c41d51, 0x000c9395f478eb67, 0x00006c79af16b80d }}, + {{ 0x0009f0694bcc6e29, 0x00024e0eaf4b8a5d, 0x000971d5a4e6ddfc, 0x00063357068cfd9c, 0x0000e859080ab5b3 }, { 0x0003e274e3cfa9ed, 0x000ddd5ba708bcd2, 0x000937d6e7472719, 0x00016b88f5cd2ba6, 0x00005455f039ef64 }}, + {{ 0x000072e8b9f6e62c, 0x0003d2ddfd20a4a9, 0x0002f1337d994ddd, 0x000ba497d091c5fd, 0x0000a3d27ef9d712 }, { 0x000fccd127ddda11, 0x000fdb080848beca, 0x0009ca3065a453f9, 0x0001332f595bd480, 0x0000e62fb4bc3988 }}, + {{ 0x000f46369ed3f8aa, 0x0001e2d1cc1884bc, 0x00008e011d1618d7, 0x000955f9fc85ac20, 0x00002ecc593e0d91 }, { 0x0008bfe3c7e56fef, 0x000e149506467ea2, 0x00020f0e0904fd77, 0x00010253a481b63a, 0x00004ffcd9b71108 }}, + {{ 0x0002f7b360a494a2, 0x0006e090643d84a3, 0x000878d95ce09757, 0x000a592d6885f366, 0x00001f4c9f31cc53 }, { 0x000d2bd553f44765, 0x0001337dad1fe7ac, 0x00088715cb5cfc25, 0x0008d105060a157a, 0x00007397650095ee }}, + {{ 0x00076feec510b8c5, 0x000332f33e24a0b2, 0x000fcae661b4ee9f, 0x000a693259cbee23, 0x000026ff7e0a62da }, { 0x0006368fffd036a1, 0x0008ac6da10032b9, 0x000d5ab09a54017f, 0x000ea46ba718351d, 0x00008ccd45317653 }}, + {{ 0x000c8455fd5923e1, 0x0004c26150a49e46, 0x0005d2801a6da7aa, 0x0008db5d00c28b63, 0x000079a775e548ff }, { 0x00039639e7b06e8c, 0x000fd5f2d71867e2, 0x000bca63b9a5389d, 0x0008860045c0be31, 0x000038b70ff37728 }}, + {{ 0x0008d12af80f55bd, 0x00096159c7c4c6b6, 0x00006e6f6fffc941, 0x0001b75fb603aa3c, 0x0000305f59cf13f1 }, { 0x00010c71d2070171, 0x00096e7bf5d92796, 0x000549ce02fcb704, 0x0007d1bcb9aa5005, 0x0000308e0578f9b3 }}, + {{ 0x000938f757b46a0c, 0x000d5a75aa07093f, 0x000aae24ad24e9c4, 0x0007d4801ca84004, 0x0000e8c27e4df989 }, { 0x00028446eb3f9ed5, 0x000a11800a43421b, 0x0001553831dd567a, 0x000783d7639a2536, 0x0000f2b4a9ff1eca }}, + {{ 0x00086d90b771416f, 0x00012bfe3b6a6611, 0x000dce64e93fa706, 0x0005d47627751cb1, 0x00005f51d3741f54 }, { 0x0004fb8c61a5d90b, 0x000abc1dfb4f754b, 0x000a762c757a6872, 0x0007b4b4d5c5cf56, 0x000074b63f62f079 }}, + {{ 0x0004d9a14957069f, 0x000f73033ff98c71, 0x000aba3dd553a17d, 0x000f7390a9619fff, 0x0000ad3a3609acc4 }, { 0x00013dbda876d927, 0x0009c606f6df9ea2, 0x000d00515a423c7b, 0x000120d80dbcf770, 0x0000ce7619212003 }}, + {{ 0x00051b92e197fca7, 0x000790b29fc81b30, 0x000f1201f4e0144f, 0x00085039eebc3e09, 0x0000dc245aa94e7c }, { 0x00064b685717ec74, 0x0001ee9ecb5537f9, 0x000b92c10c2cc7a3, 0x000f23c1644b1b2c, 0x00008328b2510312 }}, + {{ 0x0007a54f50c83a40, 0x0005d99cec036235, 0x0005978d229986db, 0x000b408490553222, 0x00005422c6af52fd }, { 0x000d092808697dfe, 0x000441d9598b3525, 0x000c0a3802abd4af, 0x00045ab12e865a49, 0x000065df0e601cb3 }}, + {{ 0x0009d129392f3324, 0x00035084088567a3, 0x000de550212844c1, 0x000bd9d3deb6b280, 0x0000b981fcd6fb9b }, { 0x0001e32d5d00ce68, 0x000d25ebc6edfb49, 0x00016c69f3b1b20d, 0x000b846727485b1b, 0x0000e475193ea3e0 }}, + {{ 0x0006e21e7dd420a9, 0x000cbd74be59224c, 0x000baa8b377599d4, 0x000b64433ebc88cc, 0x00008d34017152f6 }, { 0x000ec23629ccb29a, 0x000ea0e5bcc36bb3, 0x000e3ee5193f6012, 0x0009ef9a89292445, 0x00003d19d936f781 }}, + {{ 0x000e29493df08894, 0x0001a85b134defa9, 0x000f7d898b37d761, 0x000db2c0d6073b1c, 0x0000020c0cac2037 }, { 0x00014b0d0b49b08d, 0x00090ea4e9acf4f7, 0x000833c2ab82797a, 0x0002a046c3e1f01c, 0x00004988c2f0debb }}, + {{ 0x000ee06e882c17f3, 0x000a0fc9920cb5e5, 0x000733e735241fbc, 0x000d49f355b44b1f, 0x0000db6fdef70b90 }, { 0x00050566058761ad, 0x000d473da621607b, 0x000be4f06c8b479d, 0x0009587ac2bb03e4, 0x000036fba157651f }}, + {{ 0x0008a673a256cc00, 0x000920ce079afee3, 0x00002ee30f7d0279, 0x0007e5ae5686e17a, 0x0000e8778c4b4660 }, { 0x00015ec10c65e1bb, 0x00006f283141c954, 0x000ecd38237a573b, 0x0000441783b2ecf4, 0x000086f1bda28a0f }}, + {{ 0x0007bf22ad35869a, 0x000aa19805033800, 0x000acb5590e4df9c, 0x0004452ae513d917, 0x0000b8de7ca6a12e }, { 0x0001fa0bdb4ffa7c, 0x0006ca1e4306839f, 0x00016bddf2cf9767, 0x000ccfcf11b3be96, 0x0000d0ade7990324 }}, + {{ 0x000b1c1f39afd405, 0x00055316ec3f510d, 0x0003f77be53bd54c, 0x0005ce6fd2c7e4a1, 0x00007db2f3ff86bf }, { 0x000930967a574854, 0x000c6755dce364a2, 0x000bdc5ec569a6e0, 0x000b64f8cb7b22a3, 0x0000915aea8087e0 }}, + {{ 0x0001bd8b5ca9eac1, 0x00048de0c061c658, 0x000c6c0961e7de05, 0x000c4f0ebcb014aa, 0x0000e471ea525791 }, { 0x0004753e714b1b3f, 0x000797ef01a17aff, 0x0003f29ac7c9d1bf, 0x000e1429321f37ac, 0x0000ccb1125704f7 }}, + {{ 0x0004fb0c0cc4be26, 0x000535ea15b0a44b, 0x0006d45d9d4b3d51, 0x000f84fb58f37c8d, 0x0000f6737b028edf }, { 0x000bc5118d042dee, 0x000f839a7ff1f2e5, 0x000305d1036ee967, 0x0004363ab9880f5a, 0x000068871fdb7590 }}, + {{ 0x0004ddb6540d8771, 0x000af554c20cea5a, 0x000d6fe72046cb52, 0x000a5e89bcac2776, 0x0000a43574dd6d54 }, { 0x0005542e3d637e0e, 0x000e3511b4941b44, 0x000429a7774ac8d1, 0x0000537e0e1ff19b, 0x000001532d232661 }}, + {{ 0x0004dcf4218a8c26, 0x000a591349f7aed5, 0x00003aed8fff670b, 0x0001ed0d83b2b5a0, 0x0000d7b1c690c699 }, { 0x0007a54456147aa0, 0x000a30727d6561e7, 0x000459d06d8bf726, 0x00005ddb5879d5ee, 0x0000236499921d85 }}, + {{ 0x0006a53ca0e071a9, 0x00056130105c0720, 0x000f873541040651, 0x000bb8cc118f7a99, 0x00002325fc847f2d }, { 0x0006bd173faf618c, 0x000401ef1aa1d9e1, 0x000433b89aa8fac0, 0x0005d13dc3241433, 0x000099c31187e85f }}, + {{ 0x0006aebf577abd9d, 0x00015452133ffd9d, 0x0000ac605ac980fc, 0x000e4582a39a8b2f, 0x00004eec5aa7265a }, { 0x000045d5cf88aa51, 0x00029cb76ccdac60, 0x000c15412957a97b, 0x000342cd1af4d36e, 0x0000e6170f039470 }}, + }, + { + /* digit=6 (1,2,..,64)*(2^{42})*G */ + {{ 0x0008c8bf5c4dddf3, 0x000e274c005979da, 0x0001c17823f45915, 0x00004f9f9c2072b4, 0x0000aaa1baf4fa40 }, { 0x0001cb9e28458fbd, 0x0002855114df14a7, 0x000d8bfa4e43521f, 0x000189718d4374a4, 0x0000a04910e166e7 }}, + {{ 0x00032caa306d36d2, 0x0007e7903605c397, 0x000e2e161f3c1bd9, 0x0005b6484f0843d9, 0x0000c3ed7e7103a9 }, { 0x0002e9423a811470, 0x000527061160170e, 0x000b6096786931d4, 0x000d933acc32788c, 0x000040d7f8af5425 }}, + {{ 0x000fa20877d18f60, 0x000739b0260e52a4, 0x000c40c32aad97d8, 0x0003b1954d42585c, 0x00002a8f892d8d50 }, { 0x0002278164a77a97, 0x00058f8e34a0bbeb, 0x000bd2cf6dffb947, 0x00034ed8356b0040, 0x0000781e1140c00a }}, + {{ 0x0001682c10b4b42c, 0x00049455922ac1c3, 0x000c73c31352d93e, 0x0002a2bc4a7b3ef5, 0x00009c11c3b203bd }, { 0x000c092172b4577e, 0x000a6f04bd55d319, 0x00057bacfaff1310, 0x0004d8a9db6d1c08, 0x0000b14a2965910e }}, + {{ 0x0004577870abf0ac, 0x000415bc00cc638c, 0x000a9cd01752318c, 0x000474cd61a2015e, 0x00001d16278617be }, { 0x00098cd105a45700, 0x0004cce2c51211a6, 0x0001bb3533930fa7, 0x00036b5e5ad9b10b, 0x0000c8cba2a94a2e }}, + {{ 0x00023c2d425da318, 0x0001507e91b536de, 0x0001bc7ddc93f16e, 0x000d9216fceb982f, 0x000065b77c65e9bb }, { 0x000b019211c4463a, 0x0001dd93f330d370, 0x00016e0efbd983c6, 0x000d362e5b3a4c8a, 0x0000e6296830cd06 }}, + {{ 0x00025fbe30039a0d, 0x0009992840bb3366, 0x000c440a3c4b2158, 0x0002fb6007c353bd, 0x0000477b5b25ccdb }, { 0x00082dd27d9f45bb, 0x000fb1adbc173281, 0x000f912383a4036b, 0x000db4446008965b, 0x000099d080f1bc26 }}, + {{ 0x000910b95bc8d4b3, 0x0009d35ea6c39976, 0x000a5950529391f9, 0x000ac2a3954259aa, 0x0000954edcb4e373 }, { 0x000982812f18224f, 0x000a61043e09aee6, 0x000f3de4d536e4c0, 0x000508c61ced56c9, 0x000097bf82337dc0 }}, + {{ 0x000ba2f548cb64d1, 0x00040c6ce8009982, 0x00028d606b905e59, 0x000e6049072bb175, 0x000008cbdb0d4e8e }, { 0x000f7d4aa9ad99b8, 0x00036bbe490ebe0c, 0x000cb030c716d24b, 0x0006a023712a0a4c, 0x0000814fb43cd83b }}, + {{ 0x00007b3c44361615, 0x00056f43fd5684c4, 0x000f3fbace5d5c99, 0x0003e55822b26eec, 0x000042b330e7ebca }, { 0x00033f9344702a99, 0x0004cfe249c82ba0, 0x00072123e10816a0, 0x00066c9729e0faec, 0x000059f4e057a424 }}, + {{ 0x000fee4cf4b36856, 0x0005ad18be82e84d, 0x000d9a69e2fa6af6, 0x00080cbfa89967f0, 0x0000ae907090e0f3 }, { 0x000caf68098cfd0f, 0x0005a65b493c465c, 0x000ba986582707f3, 0x000f34f9f638b9a1, 0x00002e36b41f5ad9 }}, + {{ 0x000fc9cdf0a602a7, 0x0000f90768fccfce, 0x000cc86be572242c, 0x000fb55cef402d37, 0x00007fc53399e03c }, { 0x00038fa2f84181fd, 0x0002e72d1669a8bc, 0x000b93e529c4e96f, 0x000b28a0e33c536b, 0x0000c1aea47311b9 }}, + {{ 0x000d9775dc6e01cc, 0x000242bbf81f3f5e, 0x000dc1e6cfa506c4, 0x0003a88ae0525a5a, 0x0000a1093d00ddd5 }, { 0x00031ec1f450f0af, 0x000c48ac0edb37d9, 0x000dd3ad5d5d822f, 0x0006f5e7625fdb6e, 0x00006a6a380a22bf }}, + {{ 0x00008d930a7b99e6, 0x000376219ee43f1f, 0x000d6ff50a8cea27, 0x000b200e85cd57c3, 0x0000c75d78e4991c }, { 0x000037762700e77d, 0x000215bc016e4eae, 0x0008319cc70493d5, 0x000889455d391683, 0x00003ba91c61b072 }}, + {{ 0x00025cc3dbf43b85, 0x00044ecaa80ba596, 0x000a05f6ca758ac6, 0x00045a3af3083411, 0x00002728e23215f4 }, { 0x000579c8e5f5af02, 0x000646c01ac3107f, 0x0006df8bb1de094a, 0x0000f5bf7b2a8d57, 0x000009b1279bb39d }}, + {{ 0x000e413c023b543e, 0x000ff931341ed7a4, 0x000c597461477da5, 0x0006486a44223272, 0x0000e62ade1b4548 }, { 0x00073540e59ce025, 0x0006c27e17e44ceb, 0x00047c7e6d15d0b9, 0x000ca71caee86bf7, 0x000062dc3b140088 }}, + {{ 0x000308c289f47083, 0x0009a7b1b4a158cc, 0x000d64d9e0df3e0f, 0x000696e97e571c99, 0x000037723337361c }, { 0x000efbce6ccabf4d, 0x00050d3eb7958f24, 0x000be10cab44dc30, 0x0001fb936a7226df, 0x000059e89431f5b4 }}, + {{ 0x00050d86fc79732f, 0x000fb058d6990216, 0x00091217dfe6fc85, 0x000a7a33a586d4c7, 0x0000a84bf24df4fc }, { 0x0004cefe9970cdc2, 0x0001257842ba251a, 0x00059d544a9a0981, 0x000dd14576b65e3e, 0x0000027b14071dc0 }}, + {{ 0x000c30477ad22c94, 0x00046909f47befbc, 0x000a7500e598e35b, 0x000c53afe6562e9f, 0x000070ac8e36df1d }, { 0x000c834e7cd5fa4f, 0x000d5610b0ffd3dd, 0x000a7eb20ad9cb68, 0x0002a9d24a1f16f3, 0x0000a6548b8dd66c }}, + {{ 0x000bd5ca4b43dca6, 0x000b875b2c69dbcc, 0x000837ee1021381f, 0x000b45c713aa77a2, 0x0000a05614cbf186 }, { 0x0006c5c5b213f9f3, 0x00065076db476cb9, 0x0001c871dd6ccdd0, 0x000210116fde15d6, 0x00006771cf226ee0 }}, + {{ 0x000f2bc1c174c5bf, 0x00084b7eb4ceb9be, 0x000f5f4b7558a096, 0x0009784af2e99300, 0x000032a2c38518f2 }, { 0x0000f8a74351233e, 0x0000d7b9342f6b2e, 0x00019b95caad4566, 0x000fc00fc201eadf, 0x0000476372345bf8 }}, + {{ 0x00015f9c975edbc2, 0x00082b6b3eba40cc, 0x0009006244398c21, 0x000c18e5ef9739f2, 0x0000d49e0d6c8302 }, { 0x000ec5b26dc91097, 0x000db8583afbe332, 0x000ed62c2e2492d3, 0x0000a0611a3b6d6a, 0x00004081b00b4bac }}, + {{ 0x00088d1c341332d0, 0x00024d902f6fb8d2, 0x00016e040530d834, 0x000bc60004063c56, 0x000024d616048d6d }, { 0x0008547775093d38, 0x00030d607806fd8f, 0x000453677d9adf3f, 0x000502e27b2f7f9d, 0x0000af367fefc5a3 }}, + {{ 0x0001dde5dfbb6e3a, 0x000b56c872b4a606, 0x0003e4356c3c10e2, 0x000cfdbd1ab2a34a, 0x0000f1935615b0dc }, { 0x000bfd9fd4818329, 0x000cd219f2275f33, 0x0006091fe9776294, 0x0002d94aa0750c8b, 0x000091bb35d3e4f7 }}, + {{ 0x0001dc0dbedb662a, 0x0001430ee9120b67, 0x0002b1c86680159b, 0x0006b239e2b51af9, 0x0000f154211bef6d }, { 0x000650c83c8fe6f4, 0x0006ed20180cca4c, 0x0006fd05c1270162, 0x00094d0441ae6067, 0x0000b656885374b3 }}, + {{ 0x000c2c8d4a51bcd4, 0x000f3ddfe7ccfc4a, 0x000c6f660ffdd205, 0x000bb6833f925c89, 0x0000a3e9f13e00b4 }, { 0x0007ece5fa9b1c9a, 0x0001a07b807bba06, 0x000d0212a9406024, 0x000d2caa49d1e362, 0x0000acd66e4a8730 }}, + {{ 0x0005a83685cf0044, 0x000659b739f10e3a, 0x000959aa229f9a00, 0x000e28c41c3341ca, 0x0000631770b3a0da }, { 0x000031413543d5f2, 0x0001a819d7de3cd3, 0x0005f0318e67af71, 0x0003afbb0edf0258, 0x0000e407d9d3c57c }}, + {{ 0x0009529ca84f2105, 0x000db2adb22b94b8, 0x0009189807b37871, 0x000fd1763993d8ae, 0x000032507bd52b7d }, { 0x0006d1b1faa44f66, 0x0007daae572a2530, 0x0007fbd06d00887f, 0x000f39d58e02b643, 0x0000ff4486cf7424 }}, + {{ 0x00026e4489446194, 0x000d932c47447335, 0x0000e53159ab1422, 0x000ad62ca40517c7, 0x0000c82158b4d5ce }, { 0x000eb5da0a8b9559, 0x00064177ee4a9765, 0x0003335d89c6f8d2, 0x000d487411d9dc91, 0x00005c05b1cb2924 }}, + {{ 0x000bea4094530df8, 0x00044b1197b994f7, 0x0004ac59aa54c901, 0x000fb86a53c95a6c, 0x0000fb4e8ab73552 }, { 0x00098a15acd05a20, 0x000ff734db378f9b, 0x000029f161ffe433, 0x000ca8d4670025b0, 0x000031ab0dd33ade }}, + {{ 0x0002618905cfd82c, 0x0000cba2743b0043, 0x000700e28ce86b04, 0x0008aa45ab1c7f4f, 0x0000bc87ba82894e }, { 0x00094df65f20b8d8, 0x00033b5a23a0f46b, 0x000ab0b39b2d0f04, 0x000bb67945bc971d, 0x000089df6cbaeb93 }}, + {{ 0x000977faf2fd74af, 0x00010abaf95894c5, 0x0006cdf3274ead88, 0x00068f58b7b9bdc0, 0x0000d28ef6376f5e }, { 0x000d37fa9f638299, 0x000a9ef052c4b5b7, 0x0000893d97515b4d, 0x0006fb5c79fe87f7, 0x0000baaee7122abf }}, + {{ 0x0002ca17164dce09, 0x0007b1a15562627c, 0x0002ff79991dd942, 0x000f87d092c01a61, 0x00000ba8174e3fdd }, { 0x000ff6218fe602a4, 0x000c82d3eb81d82a, 0x0009df77cfaee393, 0x00070103bc02abf4, 0x00003fadbfce47a9 }}, + {{ 0x0006755712b47088, 0x000ea6c8d55b9d21, 0x0009837468e85634, 0x000495f2adc0adbe, 0x0000242e92858a3b }, { 0x00077f3fc7d01a76, 0x0008384f26847f99, 0x00074833ccf00d71, 0x00057799cbcb8e38, 0x000006fa9868df81 }}, + {{ 0x000ac30885fb7702, 0x000ad2bf4babda01, 0x000ddc4e340815f7, 0x00067f326feab68b, 0x000088b297e9debc }, { 0x00080e110807e7ff, 0x0006f7b40142d9d3, 0x0002f8840b031472, 0x000b917a3839b560, 0x00007518cceff22e }}, + {{ 0x000356d404f08cea, 0x00000d858854be16, 0x000e687e009888b9, 0x0009cd8ef4111c12, 0x0000fa7a19c7e749 }, { 0x000abe5cc63d28f8, 0x000728f594d320e9, 0x000d5b93700c61e4, 0x00066e5e40989316, 0x0000820e9cacb3d2 }}, + {{ 0x00086e2220dbc255, 0x0000bfb9723f6711, 0x000d66cf371bf433, 0x000f7b19621b2a12, 0x0000a5a81f4bb948 }, { 0x000435c651e5363c, 0x00028e088312c29f, 0x000823a6b1008cf9, 0x0004fb28994282a9, 0x0000f15346f16d75 }}, + {{ 0x0000179a7dfec12f, 0x000e63943b3a50bb, 0x000b6a3c553ecb3d, 0x000ef96b77132130, 0x000049806974e5f8 }, { 0x0002dd6225d0701e, 0x00046b3c85f455b2, 0x00086c909e3c4260, 0x00005b8d94725932, 0x0000eda3e114e5e8 }}, + {{ 0x0008515b8d05849c, 0x000678eb9c3bd6dd, 0x00062368cc3bb0d3, 0x000de285d00cdb0d, 0x000009399b53aa0a }, { 0x0000a8dafe0d5d78, 0x000f19e8cbb5ecf2, 0x0008a55ffcdabe31, 0x000e088db8c4347f, 0x00001718c6220cad }}, + {{ 0x00040e94e3de442a, 0x000ea8045ee2f40e, 0x000e5d5ccbebdf33, 0x000057ec475e354a, 0x000019d840edbdaf }, { 0x000a9e01bfa34f38, 0x0006d9f62accd765, 0x000a31d826781a00, 0x0003cef7b05cf466, 0x0000fffe5d10d9a1 }}, + {{ 0x000800bf0a44ff12, 0x0006598326aad8d2, 0x00049b9638dd5846, 0x00054d092bdef495, 0x0000f18cb0c7987d }, { 0x000e5e7f141dfe5e, 0x0000f3144438fd49, 0x0002bfc720860444, 0x000f80464ef23392, 0x0000bec1282f27e5 }}, + {{ 0x0002b639eaff99d6, 0x000e16c5fcc1aba9, 0x0007c6ff860d56c4, 0x0001cfdfaea63254, 0x000005c26b5c9cab }, { 0x0003b90f531f7c6d, 0x0007a82953b135c8, 0x000dbe99599be78a, 0x0009207697308912, 0x0000c7f561f073e9 }}, + {{ 0x000f18cdffd1566d, 0x00046d0244975b3f, 0x0007127d8f7275fa, 0x000375a51f3a4435, 0x0000eee9da0674cb }, { 0x00063c9f3d509320, 0x00018332028e2472, 0x0002cd831d3c736e, 0x000f4ea8496e280e, 0x00008f205a98807f }}, + {{ 0x0005a0beee1cf41a, 0x000fbb32d2ce8114, 0x0002b2885e3319c9, 0x000abb5db846dc0c, 0x000088344d69dd5b }, { 0x000cf49ef219e334, 0x0006b0796d69af13, 0x00081ca617ead2ab, 0x000ffac9f31a7c5b, 0x00003db05bdafddf }}, + {{ 0x0001e5f7c08d641d, 0x0002ff3086cff9bc, 0x000077bd3e4ede7f, 0x0005ba01d88dbd49, 0x000011ea14de0b80 }, { 0x000c2b9818dff733, 0x0007f1428819d98c, 0x000baebf05b22550, 0x0002635c8c770dd9, 0x0000c0c2bc6fae24 }}, + {{ 0x00049dd198ff7e19, 0x000a376fe86c6072, 0x00072b8cc8fc8049, 0x000cf92636b7b933, 0x000056f429238ed1 }, { 0x0003d2fe1f767829, 0x0003c84a981a2029, 0x0007a6b6356871bd, 0x000e449093531dd1, 0x000078fe864a7151 }}, + {{ 0x000649cddbdcf87f, 0x00040e2ec6d6b975, 0x000466c0d802a52d, 0x0007f205f9cf6d6f, 0x0000cf17c30aef77 }, { 0x000497381a72d1fc, 0x00039793f26ce5a8, 0x0001d0780b03bf41, 0x000e6506fc289a10, 0x0000f143d893c000 }}, + {{ 0x00064e359de41d5c, 0x000f9e6f2606a828, 0x00010aa4c5b9d100, 0x00087877ce25f706, 0x0000a40abe928ccd }, { 0x000056538d0f8dac, 0x000bf187ce573162, 0x00001a405eb03810, 0x00063c1f72cab250, 0x000042dc7ff0d57f }}, + {{ 0x000620742019e130, 0x000565ef15d31016, 0x0009fb94dfb78dfe, 0x000f0129480c5533, 0x0000f5ea2ed57734 }, { 0x0005d06cf408388d, 0x0004cc4edc454181, 0x000eabfbdda91999, 0x0008bd5f0005b859, 0x0000bbd16a163c99 }}, + {{ 0x000378dfaf3e1b18, 0x0000cee3484be472, 0x00062693b0806164, 0x000f0ac532ff33e9, 0x00008a1b602ca81b }, { 0x000e287f8b8af0ea, 0x00036ec856720f22, 0x000b6850f3059c33, 0x000992b582ad9d95, 0x0000342dec973aeb }}, + {{ 0x000a1efa102f0077, 0x000fcd0990cecaa7, 0x0000ed3e46704a67, 0x000f05684ade55f8, 0x000011db276b92f2 }, { 0x0005cbba4dc5488d, 0x000f720037cc0618, 0x0000500883c5313c, 0x000d8fa10682e05f, 0x00004999403c4661 }}, + {{ 0x000f5f5dc0118781, 0x00016297a3cd22af, 0x000b4b0325d760e8, 0x000a9e4ed9f8cd5d, 0x00009329e15df9b0 }, { 0x0003608bc8757f53, 0x00091b5654a446d2, 0x000f4411cbf24c65, 0x000f71756d1a9496, 0x000012b5a681cc68 }}, + {{ 0x00073e00f8daf702, 0x00020d76688c4d4f, 0x00010ff939c43bae, 0x00037f8a39d6b428, 0x00007889e808b3d9 }, { 0x00072755fb51d00c, 0x00053ec49421c3e1, 0x000b26a7d07ce447, 0x00050e49fc4e44f9, 0x0000cab187f97020 }}, + {{ 0x0003ecaa12dc8429, 0x0007457446139cc3, 0x00022bf3767cde34, 0x00061aa990a0a6e0, 0x00001e7652e2cf35 }, { 0x000dcf01768fd984, 0x0000721f7c426641, 0x00028d96cf13c980, 0x00076a126b3e91b3, 0x00001f7562a57864 }}, + {{ 0x0000c3aa50085a1b, 0x0003e8f3d589e023, 0x000f811292dc489e, 0x00017b207df0478f, 0x00001d6316d96d0d }, { 0x00082736a4a1651d, 0x000e04b941ade7f2, 0x000c0a51c96c8483, 0x000da82f03d1debd, 0x000040def4c31898 }}, + {{ 0x000c4a826abdd1fd, 0x000a3c3d41d3bd3d, 0x00082b57e9743197, 0x0005ce29fb533b8c, 0x00005ac407982d1d }, { 0x00046833e45024d6, 0x00082513d590dbeb, 0x000b39e65f731bf7, 0x0008e5d7484632f6, 0x0000ca6f29d8d329 }}, + {{ 0x0001416d4f55d1cf, 0x0006a13f7fc0586d, 0x0006957dd9c9e1b7, 0x0004686dc385315f, 0x00004cf755c4445d }, { 0x00028a41409d5b93, 0x000187851047213e, 0x00010db688562158, 0x0002f8a0c447f6e6, 0x00006e8b3e82ccc6 }}, + {{ 0x000df39b884c94aa, 0x000cccb82003f867, 0x00068dda211b1bc5, 0x000101a55610d07f, 0x0000743e976e9950 }, { 0x000fa15eb2e071d1, 0x0008e96e22db2188, 0x000a7901ed91d8b3, 0x0002dc1768cc6d9e, 0x0000e81e206dd3a5 }}, + {{ 0x000ffef809be123e, 0x000fa45cf2c24b5a, 0x000ea2facbb12142, 0x0009590b389f66a9, 0x00008f9d35fbb026 }, { 0x000dbfa947e096f3, 0x000eec68eb8fac22, 0x000afaef20465dbc, 0x0000d48cb93c1e4e, 0x0000996990687d52 }}, + {{ 0x00088969f06f59c6, 0x0000b90ca84bad76, 0x000f44cf7c6c710c, 0x00071a831fb13919, 0x00002f4311cd9b82 }, { 0x00029f789c4e2b27, 0x00025e721264d452, 0x000950c7da8f86ce, 0x0001a7c9dfdfb65e, 0x0000d786a79714bb }}, + {{ 0x00006451aee0821e, 0x000013e6f49f15d1, 0x0008801ab5e3f872, 0x00024ca67678ce82, 0x00003896b89ad41c }, { 0x0009a3bf5194d5f6, 0x00001f019fc32d29, 0x000c1668938086df, 0x000c8ae4564633df, 0x0000568a458b4918 }}, + {{ 0x000bac9c2aea0873, 0x000b2a2534d4dbc4, 0x000176f66278228d, 0x00028891a45b8f1d, 0x00005f1547f876bb }, { 0x0006452e97fd7988, 0x0004f6a7b4e35876, 0x000dab3dab4b5c1d, 0x0008e693d0045cde, 0x0000d8b2227e2114 }}, + {{ 0x000e4caa4ece9077, 0x00039549f950cd0d, 0x0000f9b126264855, 0x000941f639cc72fb, 0x0000195f212e9897 }, { 0x000d4a60338b6b56, 0x0009f7a55c7ac17f, 0x00031d3b82198646, 0x000f52be7779cbd4, 0x0000760624055358 }}, + {{ 0x000e4daa4cf03ebf, 0x000a5880a750c0f3, 0x00031006e436dc3b, 0x000d2500539bacfe, 0x0000d4ef32a1291b }, { 0x000a444f665140ba, 0x0002db55ffc69ff6, 0x000c27c0e1c0d5f3, 0x000e2259446f147b, 0x0000e26f578ece85 }}, + }, + { + /* digit=7 (1,2,..,64)*(2^{49})*G */ + {{ 0x000392f2ec04cd39, 0x0000d5ac3f16ea83, 0x000d7f5ede30754d, 0x0009b6872115a461, 0x00008418a223a967 }, { 0x000fc5ff44240c84, 0x00018cde526cdc7f, 0x000b22632c3da39d, 0x000c70d988e537fd, 0x0000709b1f542582 }}, + {{ 0x0008d2c9ae428f00, 0x0004f7ea90567e6d, 0x0006dddb93095522, 0x00081903d513257b, 0x0000d1ef01808e5c }, { 0x000ffa707b56bdd1, 0x000c2246b29cb44f, 0x000c77ce5b30e21c, 0x000d3bd42b540a21, 0x0000c8f28344b9aa }}, + {{ 0x000c41d1ca8f6911, 0x000d2f1d4e353b7b, 0x00043304ded57d7b, 0x000e262fd062d8a1, 0x0000c7373014e0c7 }, { 0x000d825d0c68baec, 0x000f5e76be77800a, 0x000717e2f324cc7d, 0x000e0471a71fe8b3, 0x00007ed811a51502 }}, + {{ 0x00067b085c91370d, 0x000d35b1cb76219d, 0x00009adb7621c58b, 0x0008dbc100ec0bf9, 0x000035a1c37429d0 }, { 0x000539991832fa6f, 0x00095595e93a96a9, 0x000a66a28b826cbe, 0x000e29cb77526c1e, 0x0000acab05a94fb9 }}, + {{ 0x000fa297b54139e5, 0x00029e99e240d181, 0x000c9516acb11ffc, 0x000ab4d5c057cdca, 0x0000f108fdca1bee }, { 0x0001468d72cb1fb0, 0x000d1e7db083d762, 0x0006d0c02fa32f20, 0x000a1ef8c31993be, 0x0000ca3322492849 }}, + {{ 0x000f2a6cb5724fa2, 0x0002383a4c506ece, 0x0007e28291e1ba7c, 0x000a20ca2957ed18, 0x0000e20ed40d7da0 }, { 0x00052999a29a324e, 0x00090428e195c43b, 0x00095936b72378db, 0x000361c5dc842025, 0x00004a12b227046e }}, + {{ 0x000cae6fbba2a2e6, 0x000aab910a5a8bda, 0x00085cb9f51f374d, 0x000c4f5c1ca91d24, 0x000007845f0a029c }, { 0x000257ba0e5ed119, 0x000ade0d21411a01, 0x000fc7b290c9b692, 0x000bb673028fa787, 0x000016219da80e31 }}, + {{ 0x00096e6d076e5fb1, 0x000e067ceca9754a, 0x0005a20acc991594, 0x000e01fbf426d2cf, 0x0000e8ea47274e03 }, { 0x0003439dd70f73cd, 0x000dbdd87880e616, 0x000581c546fe37f4, 0x0004291151554381, 0x000076b608169ba2 }}, + {{ 0x000f4d069bfe9043, 0x0003d2fc14e35c23, 0x000c03f42ca0baaf, 0x00044b06271735b7, 0x000029c2e58d6818 }, { 0x000d0809671ae302, 0x000ac01f78f5a7c7, 0x000dff46e39ff2a0, 0x000fe0d8350a8ffb, 0x000048652a819f5b }}, + {{ 0x000dbc9d0aa61099, 0x0005fe1698e04cc2, 0x0002e8d368be0b0d, 0x0002bc879877be20, 0x00000faac89a81a9 }, { 0x000fe29735ce620f, 0x00040939454d9370, 0x000da49d76e54a1b, 0x000fc59e8e682ce9, 0x000091679212a247 }}, + {{ 0x0005ef72b2ec9bc7, 0x0002d0c5b9e02b75, 0x0001dffe92356668, 0x0003a9c2ba37c969, 0x00000df5f3206d48 }, { 0x000de1f2900b0c39, 0x000231f7b91b0620, 0x0007ad51f591a0e0, 0x0009308170a79e1c, 0x0000eab82efa982f }}, + {{ 0x000043d055253a89, 0x00013cf3a4434b4b, 0x00006a3584870bc7, 0x0000ee9a7a345811, 0x0000321ed180b8be }, { 0x00093e67f479fe7d, 0x000b49e11137b1a0, 0x000ee41e584a881d, 0x000ebddd400a754c, 0x0000aa7b62dca051 }}, + {{ 0x0005185e8a26f6cd, 0x00031e9c97e3f6b8, 0x000431c215d74bd7, 0x000a139b9c10bcab, 0x0000d0dce141728e }, { 0x000380e52200f33e, 0x000551f0eb6c4d46, 0x000d717975e238f3, 0x000cb40b84d4440b, 0x0000ddf18ad14c33 }}, + {{ 0x00046e79f34d63c5, 0x0003e51d598d7107, 0x000656cbd3b0d348, 0x0000e191f272c416, 0x000002b47849277d }, { 0x00013ba3f17082d1, 0x000f6364b573e9b5, 0x0006ac0fac4efdfc, 0x00016077b75d03f4, 0x0000927b63f07b9b }}, + {{ 0x000fbb3bb17bdaa1, 0x0000e26abb177dde, 0x000788d699b2fdf6, 0x000488073f82ab56, 0x0000c9b786cdf7f6 }, { 0x00048e86e3fd3f51, 0x000c0dba6d183586, 0x00074c02e656b55c, 0x000499190519e279, 0x0000636d8ce30c94 }}, + {{ 0x000be5a560218c0f, 0x0002245983c38b5e, 0x000b7795172b6411, 0x000736ce6b14f176, 0x0000b95d3a653da9 }, { 0x00090806472dd13c, 0x000e1cd9f87dc596, 0x000392d3ef194f1a, 0x00019f6577c595cd, 0x000044201d70daf9 }}, + {{ 0x000d06a5428770ef, 0x000550381e9ede3c, 0x0003fdf039c7f7bd, 0x000964c11243c389, 0x0000a436caa56e94 }, { 0x0004e52114b12630, 0x000594949d4e2e5b, 0x00069611476b77f0, 0x00082203533649d0, 0x00005fbc01d77138 }}, + {{ 0x000b45d0b53b1b49, 0x0006e0678a6513b9, 0x000a0395488ea188, 0x00052e4d892ea4a2, 0x000048a2399a61a0 }, { 0x0005c5b4d8712eaa, 0x000c6dbc69d11ae9, 0x0008b691a486a01f, 0x0004918721477dd1, 0x000074978afddc7b }}, + {{ 0x000353dc8bc4376c, 0x000906342e532b72, 0x0002778f7604f48d, 0x000ca80bc386ba42, 0x0000629c4169b70d }, { 0x0003fe03ce10af95, 0x000f0ea68f7e978d, 0x000156d8cd51895b, 0x00046f36d96ec568, 0x00001a9ad92e9ed5 }}, + {{ 0x0003a1c621b2b2f9, 0x00026a47ea67c77a, 0x000f4048baeb4ba1, 0x0004eda74952bd2a, 0x00008f88312234da }, { 0x0005059bc76aee10, 0x000c5a9c7ec6d792, 0x000f0d20277aefe2, 0x0007b501bff7038a, 0x0000444624dac251 }}, + {{ 0x000600da329b3360, 0x00005b2f2086fbfe, 0x0005a09086465f16, 0x000d4bd6cf6840ea, 0x0000778cdefbedd4 }, { 0x000017637cd7cb9e, 0x000d163529b8a80f, 0x00073d660bc129c5, 0x000992c7ce80e485, 0x000088119f4a6bfe }}, + {{ 0x0009ef732984387b, 0x0004d0676cb25661, 0x000198591fb0163d, 0x000d083458f76acb, 0x000001e530c1a29a }, { 0x000baf76b4f735a9, 0x00002715f228bf03, 0x000945c0bc22367f, 0x000763ac0f3cdea3, 0x000010c6a57a79e5 }}, + {{ 0x000ef5d295913cb7, 0x000aee010089465d, 0x0008af81f3014353, 0x0000106953bab5d2, 0x00002e287da81088 }, { 0x000de01f9c58ac00, 0x00058b9286b24756, 0x00095fa0668f5980, 0x000ed2388a0b9393, 0x0000e81acea89e97 }}, + {{ 0x000a4bf3535ca72f, 0x000398eadd70482e, 0x000990fe5b370e05, 0x000e33fef708de92, 0x000095e812192018 }, { 0x0004f0f83a164ec7, 0x000582c87912868c, 0x00052a18313ff9b5, 0x000a4bf0ab1b1be9, 0x0000846b0bf28b93 }}, + {{ 0x000cad0a1ecf03bf, 0x0000da397f6306a7, 0x000debf69a916d7b, 0x0009e19a2744c44a, 0x000096bc23c881e4 }, { 0x000db7091f94675d, 0x000e2cd33791d9ed, 0x000c96fbd74055fd, 0x00013a2a29cc2a05, 0x0000612a63e5bd69 }}, + {{ 0x000cbdfda897260d, 0x0001abf8538a5c69, 0x000cecee016f2ff8, 0x0004bd6da195c63d, 0x000048f79961dc84 }, { 0x000c5bd833e2b6f3, 0x00083ca849d7eab8, 0x000aafcb5a3dbb01, 0x00051e9eaebe2764, 0x0000a3bc8e72b00f }}, + {{ 0x0003a594c485ad1b, 0x00099f59837fc0d8, 0x000823f75b4b4716, 0x000321e909b641ba, 0x000075762faa795a }, { 0x0000344e3d60af43, 0x000021a526c45028, 0x000deaa6f1565663, 0x0004fc9cd9d39438, 0x000000de2d56a689 }}, + {{ 0x00082cc2c2ba07f1, 0x0001c7c2fa4f1264, 0x0005146cdf6fbb88, 0x0001defc308a3b86, 0x0000a19653e4fd21 }, { 0x000d3322183959bf, 0x000bf645f321bb80, 0x000b8d4ce39bfe85, 0x000325a588a93821, 0x0000226bc98df493 }}, + {{ 0x000b779c98067abe, 0x000c319e246b0e64, 0x000487d2607f1a30, 0x0009fe300b39781e, 0x0000008d964486ac }, { 0x000b59cb15ee57a6, 0x00073e1c84705003, 0x0008d0f2bb875ce7, 0x0004f15cc45b7efe, 0x0000d78e82ce74b3 }}, + {{ 0x00020a4bb98bb7ca, 0x0004adf3fd165e81, 0x0008f4153c582e9d, 0x00037d500499fd6a, 0x000043ec7a9e2734 }, { 0x0002fa487b4aec69, 0x00067955f4a5ac5d, 0x0000c2ad5a75a813, 0x0002b51f1cfd174f, 0x0000044c15223f52 }}, + {{ 0x000d3785755ef9c9, 0x000d5feb1dc77e1f, 0x00082492110d3db6, 0x000669ebbe956693, 0x0000caee16ac8c0d }, { 0x000b93cfea66af2d, 0x0003fbe81796b334, 0x00060d54afa0c4bb, 0x0006bd4b462d550f, 0x0000fc36919b3218 }}, + {{ 0x0003043896a03a07, 0x0004b381d531696e, 0x000fa5c9a5d318fa, 0x0004ca8c757201bf, 0x00003e9b1ef0bafa }, { 0x0000bf7978610e72, 0x0004fe18555970de, 0x0008447619e614fa, 0x00020318b8267dfa, 0x00002d551502ded1 }}, + {{ 0x000b228da47438a6, 0x0000528c06fece4c, 0x000dc9c526f8a5d5, 0x000350528d405991, 0x00009f6e58cf2dfc }, { 0x00076a72c60289e4, 0x0005d64107d1cea6, 0x0003698b662b1fc4, 0x000e45dcdeb9fdab, 0x00000c5b4b14c00a }}, + {{ 0x000b95b2310a2529, 0x000b4984d6cb00b1, 0x000ac298db4bf5b1, 0x000f75036cef9c5c, 0x00005f904b6ca659 }, { 0x000bb3c9580effd9, 0x000d02ee8ac25b1c, 0x000b6e64ee6ee865, 0x000ccb066ceb04cf, 0x00005b6ae05c96fb }}, + {{ 0x0000ebfbfb92eddc, 0x00095a1a43ff93c7, 0x000730f75cae09ab, 0x000ebe0825bc2db1, 0x00004d67b6663315 }, { 0x000d6c3f4e74d6e2, 0x00082c792871591c, 0x0005e6c0c2cb3b08, 0x000020e3cea5bcae, 0x00008a85be0f06b6 }}, + {{ 0x000d7b2902aa47f5, 0x00001230bca6de32, 0x0009846bddfb146e, 0x0004864d4dd20dd9, 0x0000510d80cb9b02 }, { 0x000dbc84fa3046b6, 0x0005459ce98840f7, 0x00000653e31059c2, 0x000ecc3a5a5d947e, 0x00004ffc38657061 }}, + {{ 0x000fc1dd78654cb5, 0x000241654a1aff29, 0x00099ab71e2397f4, 0x000dd445eabf318b, 0x00007215a0065fca }, { 0x000e995e35c91e4f, 0x0002a1513595c172, 0x000860c955739687, 0x0001206b0b950466, 0x00005b2b004bef36 }}, + {{ 0x000c3c9001d90f0f, 0x000c0697e9bbcfb2, 0x0006bc3106e1aecb, 0x00086985c95d0c1d, 0x0000231244ed3a54 }, { 0x000d62b88afe3771, 0x00044616c973f57b, 0x000be7bf5db81fb3, 0x000b808d4108b7e2, 0x000050a0c350cec6 }}, + {{ 0x000320c24f7e2d8c, 0x0009dc4197c75d61, 0x0002a3e6ad9c36af, 0x000c55311266a6df, 0x00003c001f9a9acd }, { 0x00013439c1f03bd2, 0x0000ee101a595966, 0x000b8ec570ea7b76, 0x0001ed4c98317c5b, 0x000050f4c2d89c48 }}, + {{ 0x00020ab732d47663, 0x000a19f16a66e918, 0x0000781056db02b9, 0x000d5c5eae97f282, 0x000094939d8bd05b }, { 0x000b2c87b6265c14, 0x0008af9287144234, 0x000a628484fc8c50, 0x0002a90cc54ecfff, 0x0000ff62b0d3b8d2 }}, + {{ 0x0007448f03eef746, 0x00087200a44295d8, 0x0000d1822140f960, 0x0009f2f7c707d7d2, 0x0000181637d8f606 }, { 0x000cf227783ae69d, 0x0001f455ebcd58d0, 0x00098430ac48d8c3, 0x00020c94279bcced, 0x0000f56a58b7cf63 }}, + {{ 0x0008df2c35144158, 0x00056e471d444b66, 0x000f5c291de84a20, 0x0009292f6211236b, 0x00002a2977e8653b }, { 0x00023b925d834202, 0x0004d0f59bf4f363, 0x000ba5b7bb161b25, 0x00007791df883669, 0x0000991591315aae }}, + {{ 0x000aa252908f15e7, 0x000884274082008c, 0x0009fda5d93a92ff, 0x000014d79effc521, 0x00002020dbc62e83 }, { 0x000f621ec39ad5ed, 0x000232a8f1b3c4d1, 0x00010e39cd49e9fc, 0x000cf59efcf64dfc, 0x0000b4beb3b9e9dd }}, + {{ 0x000023a25232bd58, 0x0007e27373386156, 0x000aa1b54ba4382f, 0x0002b1366162082a, 0x00002d55d436c6e7 }, { 0x000df2593f2a2fa6, 0x000663abbf04b89f, 0x0008b0824105cb8b, 0x000e4383b6735eb6, 0x00000bfd1da5861c }}, + {{ 0x000ec9322dec7ec3, 0x0007e4efdd236675, 0x000a9b56e3c02f10, 0x0001762ffdd52aac, 0x0000b9cbe745e9d1 }, { 0x00021cdfd65b39cd, 0x000df85a96f5294d, 0x00028f8386946139, 0x000cedf4282aa5bf, 0x0000d1d292453a63 }}, + {{ 0x0000fc5e10e7712b, 0x0008a7b67f8be10c, 0x000b96034915aa1b, 0x000c1b393365d1a7, 0x0000124aaa91f37d }, { 0x000148c2fe2e9e96, 0x00066f89cbbb1423, 0x000a7e7c43943fb3, 0x0001e18221d436e5, 0x0000b673c1d30111 }}, + {{ 0x000e85a1614b76ce, 0x0002fc9233222fa2, 0x0002b5945a0a0751, 0x000ae7b7789ff109, 0x00000859c80837d9 }, { 0x000d07e6b6010c68, 0x000ec7cdc810bc9e, 0x000eb01d956cacc5, 0x000ca499bea3f458, 0x00005b7830a10826 }}, + {{ 0x0000f30fee8c3f0a, 0x000134286d2e0f86, 0x0001ad978fe6de9b, 0x0004d1149e592012, 0x0000ed2e1530c0e4 }, { 0x0008c9d2519e343d, 0x0007006858e6a61a, 0x00069709a27ec803, 0x00054a1fbce4c776, 0x0000b72f3fb5dbd3 }}, + {{ 0x000e5b62c68d8a29, 0x000e65eb24fe1dcd, 0x000d8d188f85cb71, 0x000dade059eaf9de, 0x0000ef583c1ec4a5 }, { 0x000a60c4ef22069a, 0x00035aed3c2b36ea, 0x000458e370eb3a6c, 0x000784745868c19d, 0x0000a0000634a4bf }}, + {{ 0x00029b382fff57d0, 0x000efd23b60c472f, 0x000bf881f819bd9d, 0x000e0c5c9af4ef13, 0x00005143fbdccce1 }, { 0x0008035f45578ded, 0x000cb5373efaef69, 0x000c10c60ffac46e, 0x0008b3124cf56ac9, 0x00000797387ec422 }}, + {{ 0x000b0f588a0f9e16, 0x0005bb91e750c846, 0x000bf2b76bdfe46c, 0x0001e03c1c57f7b0, 0x000041ee2fa51260 }, { 0x0004a5ad25356120, 0x000b084a07c4e9ff, 0x0000b68230ef27de, 0x0007f6dccc383011, 0x0000c74f049cd8fe }}, + {{ 0x000840fa43472eaa, 0x00018bf490f97ca7, 0x0005ef60d3d59758, 0x000159d8d288f09c, 0x00008305396842d1 }, { 0x0005e16ea2c38bce, 0x0002fd25a631b378, 0x000e1e9b1cda4ede, 0x00090946694761f1, 0x00004a39b68d7484 }}, + {{ 0x000a2a463cbfea70, 0x000f033924910480, 0x0003eaa9bc9b0ced, 0x00080165c0c2f696, 0x0000c418f721a31f }, { 0x0001669c5553f128, 0x00073e7bf2f12ee2, 0x000245543d335cf1, 0x0003299d7f0a2200, 0x0000ed5a8309ae3d }}, + {{ 0x0003e34ebe7538d4, 0x000c40392f145296, 0x000bffb1ff34a332, 0x0002172f6d3d056c, 0x00001640598299a2 }, { 0x000c8da4b79d1b0b, 0x000e2ee5b80cfa5b, 0x00001774371a4424, 0x0008ecb67e872a12, 0x00004a32f2dc5f4b }}, + {{ 0x000ac787ee441dff, 0x000babb1b703e75a, 0x0006296bfb74f2f1, 0x000d17cff6773b18, 0x0000c7b2314a8aa8 }, { 0x000884ecd8191468, 0x000828b0437164b0, 0x00006b798c862eed, 0x000d18373f430ad2, 0x0000e6c1f3907575 }}, + {{ 0x000c5a4b66e99b1a, 0x000a6965f5206989, 0x000da89d6d7224d3, 0x000bf4eb9640631f, 0x0000b4e03e0395b9 }, { 0x000436d53d463c5d, 0x000f7bf80b6783d1, 0x000e25fb34d34e57, 0x000cddcb280e701f, 0x000018bf1fde0cd3 }}, + {{ 0x000ba1cfa6be5052, 0x0001c6d6556c3629, 0x000046a38dd836b9, 0x00021def9bc23a3c, 0x0000a35d2970adc2 }, { 0x000fc77d5dfd93f1, 0x000147a99c5d7062, 0x000b545b986b85a6, 0x000133e128be85f4, 0x00002b9e4f8b3c69 }}, + {{ 0x0001f6c57acb1b9f, 0x000eb805616ee306, 0x000f85b44b08579c, 0x000f6d1cdfb09548, 0x000025f3fb849285 }, { 0x000bf9f676805df1, 0x000ce7290aecb08b, 0x000851fd8e2e2099, 0x000512c03849f87c, 0x000043ec2b969f4f }}, + {{ 0x0003e4e910ccd797, 0x0009565765ba5436, 0x000bdf0577ccc478, 0x0006c55b318ce3ca, 0x0000fc4ec1949ba1 }, { 0x000fc62b2afeca4c, 0x00003a3c85932eeb, 0x000a8cca99222759, 0x000c004f696883e8, 0x00000968be080da2 }}, + {{ 0x000739fcc7a7b873, 0x0000a906d3e1fa9c, 0x000836cbbbdc2a72, 0x0007329011711561, 0x0000690a8b0f5f13 }, { 0x00013b9b26e41c59, 0x0003857165e439a0, 0x00026954c8b16ff2, 0x000cccea306353a6, 0x0000a667ba136d7d }}, + {{ 0x000c2af206d24a25, 0x000c73b973497f10, 0x000dfd13ca267da0, 0x00064e08315c0f94, 0x0000473115252061 }, { 0x000aa99338a37060, 0x0005df14457397cb, 0x0007101327a82eed, 0x00010f3062e8ed01, 0x0000a0cbc7d6001f }}, + {{ 0x0008fe977ed7b8cc, 0x00065823b0ec7de9, 0x000abfe06e603098, 0x0000aea831e1b822, 0x00004c9aceb8b0ce }, { 0x0004ee56e7d95e11, 0x00005c20d5e88732, 0x000a981eeb9623c5, 0x000e1b861e48d839, 0x000045fdcadc3088 }}, + {{ 0x0002d762b3177523, 0x000825b91e4de589, 0x00054d073fd57a0f, 0x00067a643a7488ca, 0x0000af2bc1467b91 }, { 0x000e0fcd863d7b0f, 0x0003b12091ff4a95, 0x0009ae9dd4edfec9, 0x0005ddbe2581113f, 0x00007099494bbef3 }}, + {{ 0x0008e7dd3da6ac7a, 0x0007068c094dbb56, 0x000e7080f6d2bb87, 0x00006862db77d062, 0x0000957c36387eb2 }, { 0x000c48a3b41f412c, 0x0002b40013a5e585, 0x0006e05598676e41, 0x000588aab2131174, 0x0000a5cfa92af35d }}, + }, + { + /* digit=8 (1,2,..,64)*(2^{56})*G */ + {{ 0x000b63b80c17b3a5, 0x0009991991724f36, 0x000bce681e7aafdd, 0x00021571e5eda799, 0x0000608a0582bb4c }, { 0x0001f37958fc7a0f, 0x000ed697e5fb5166, 0x000a6efe500b7226, 0x0002f1da5737708b, 0x0000d330af0a0615 }}, + {{ 0x0001d5f271b2ffcd, 0x000ce2caa6650728, 0x00046dfd327de7f3, 0x00027f03178322fa, 0x0000216e3f0e2310 }, { 0x00003bbfc59abb34, 0x000d842f48027f5b, 0x000bd4fb27522c72, 0x0007b690faa40cdb, 0x0000abded9d9b492 }}, + {{ 0x0002c6f30c43f226, 0x0009e180d738ded3, 0x0000ae17641d02b6, 0x000b5f0756f1a5bb, 0x0000e1022d63ad47 }, { 0x000709b3807f334a, 0x000c89dd8fffb620, 0x0007ad500b84f625, 0x000081d766a281b4, 0x0000baefeb53ba7b }}, + {{ 0x000e8143ae4b352e, 0x0008432a3326505c, 0x00021f9bfe1140f1, 0x000adfcfa38d6927, 0x000034810d2f90b4 }, { 0x0000bf0d00ef8992, 0x0002ffa7e6ab6665, 0x000fd1695563a3a5, 0x000ad66ed6cd2d22, 0x0000bbe464cbfd77 }}, + {{ 0x0000824eeec7168a, 0x000ce52877a21ec5, 0x0006bed12ba5446b, 0x000931ca2300414a, 0x0000eeb5b0f5515a }, { 0x000322d64e381de0, 0x0001cecf83cba5d5, 0x000840921d7268be, 0x000d46dd7f953814, 0x00002b466f4b1410 }}, + {{ 0x000bd6a7d881d987, 0x000ec843d9325f3b, 0x0000379b23abd56a, 0x00044afc5a9bef2d, 0x00004a3dd4f7b324 }, { 0x00032b0b1e2614cb, 0x000de028f61bc0b8, 0x000ceba5ab839425, 0x00059b798f49085e, 0x00003b2eafe5b888 }}, + {{ 0x00020cf3f9601768, 0x0005c47f1f0ced18, 0x00031285e9324320, 0x0008926fa800cc79, 0x000017299d89245e }, { 0x00019c8dbe5b7b2e, 0x00054dc1c0f7d133, 0x00005341590ca39e, 0x0007e40e3ef92196, 0x00008544b679b3ea }}, + {{ 0x0006e673cd25c857, 0x000e1717b82b99b6, 0x000ce0284257ae21, 0x000cd7d6675922d4, 0x0000134e48cf8715 }, { 0x00020fa3844dead5, 0x00092c4b5f2b89a4, 0x0005e6feb94f1d13, 0x0001f55da3de9c1e, 0x0000bf9802bd31e3 }}, + {{ 0x00024c930f786d38, 0x0009e3b0eb919b03, 0x000d74ff03109274, 0x00006f10cd74ee51, 0x00001f7f74fdc12e }, { 0x000970167dca0115, 0x0003819fbac27d45, 0x000a427dd82e631e, 0x0006685b84086e8c, 0x0000417d6e1f9dd1 }}, + {{ 0x000343e877e929af, 0x00043c9faf1fc639, 0x00099f48a33c4af7, 0x000c84f4a616d333, 0x0000b1d34afcd46e }, { 0x00039a2aff6798ee, 0x000296be970e78cb, 0x000eacb90b27effc, 0x000350e1ba36cceb, 0x000025b07b3680a2 }}, + {{ 0x000613ab7466a572, 0x000a9a16224408a4, 0x0001de6950ea5159, 0x000e65293cc856e9, 0x00009b2282c9735a }, { 0x000316fb85a186df, 0x000099cc420bf2b3, 0x00065d1c833d089f, 0x0007b80c700a5317, 0x000062412e82bddb }}, + {{ 0x0007022f7ed617cd, 0x0003df59ac50814f, 0x0007a38c12a4513a, 0x000a6f8a0fdf95e7, 0x0000db96fd7cab80 }, { 0x000a0e79e834cb0c, 0x000deb1cac1fe8ff, 0x000b3d3697805f23, 0x0009cd0e68040188, 0x000080b9a53ca2a4 }}, + {{ 0x000e74c82c8bdfad, 0x0007ffc2064cfd1e, 0x000dc1f05107db53, 0x0005c1eea339c31d, 0x0000f20f060da89e }, { 0x000e4bb978fc26e7, 0x000e95ebaf28ee6f, 0x000b9f25d6af0d00, 0x0008c1b8982cecf2, 0x0000a108e862c5e1 }}, + {{ 0x000756758aa3f827, 0x0009290640bfd9e7, 0x00070b9fab7e1763, 0x00007b656d226e27, 0x00003f7891bafa5f }, { 0x000ca7e720c3e4d0, 0x00092a35285fe91b, 0x0009cff4ea1fff46, 0x00077e008edbc546, 0x000012258488f2eb }}, + {{ 0x000c20ce094f2cf7, 0x00033b817a91cae1, 0x0004ecc1b15a91de, 0x00076e6f9b89aab6, 0x00007bae3c9d9e8c }, { 0x000d1adb3d74632f, 0x000e8b45fcf7e33a, 0x0002e7421004f735, 0x000000e19e679374, 0x0000b0e04475d7e8 }}, + {{ 0x000a6b62d93fdd41, 0x00055796424c49b9, 0x0007cd56def02492, 0x000194a49f888dfe, 0x0000f9869f29b9e5 }, { 0x000f96a765fed464, 0x0004e6d179483cb7, 0x0002157b537c82e0, 0x00066411f666f963, 0x00007c51bf707ed6 }}, + {{ 0x000f21da47afb8d4, 0x000e1bf074a30ce2, 0x0006d138589ef83f, 0x0006aaad4d7f5210, 0x000072f03502bfa0 }, { 0x000998db4eb5079d, 0x000ffb4eec863a09, 0x000cfb8e86bc3ed9, 0x000747ff8d18f77f, 0x0000d2b07489cd8b }}, + {{ 0x00012874a0a79f95, 0x000f4e5c247d44d3, 0x00010e26c8dfd693, 0x000d911c71250714, 0x00005f4b31216fa2 }, { 0x000bb7940ea2bdb7, 0x000a2a6759443709, 0x000f9f7477cf3c12, 0x0000351e3d6123d8, 0x0000f7ac71946caf }}, + {{ 0x0000e639fd11e75f, 0x000ce5984ac066c6, 0x000285a62fa36766, 0x000f23eccf5954a9, 0x000013d9c6495b3d }, { 0x00065ad32f4dc3be, 0x00043257de792488, 0x00046ad4f3a87522, 0x000779f32e9ef640, 0x0000b913b812d8dc }}, + {{ 0x0002e257466c6324, 0x0000f1b13fb70b6a, 0x0000f27743e13f9f, 0x00059e42c037b44c, 0x000046e406dc7df4 }, { 0x000140e65ebb8a31, 0x00056a81da0263ef, 0x00043bd00d7832a9, 0x000681932931bfb9, 0x0000e425b1bd11e6 }}, + {{ 0x00090be4402602f7, 0x000e891b2f1ac7a0, 0x000b6d0409e7294a, 0x000bf31e5f99eaab, 0x0000fb74eb134a23 }, { 0x000a063ac1c5c13d, 0x000bee45004f022a, 0x0001ac97e034e6d0, 0x0005c6da5d838c2c, 0x000081f282d44949 }}, + {{ 0x000cc1e4250112ec, 0x000b82259558a787, 0x00090773f60a0825, 0x0003124dc5343c66, 0x0000291b4782f302 }, { 0x000581ddda3dc5d2, 0x000823f16dfbb7d8, 0x0001d5d9f7b848db, 0x00077fe3c921fa94, 0x0000f85610bf9475 }}, + {{ 0x00047ab1f32b86a0, 0x000bfcb81d73c9e1, 0x0008f5e3e5b8290c, 0x000b3cbab6d07e97, 0x00000464d3a117a3 }, { 0x0001f4e9cbfa8244, 0x0004a3d9fafdee4f, 0x000a6195a1c9102d, 0x0006ef471fab3dbc, 0x00001448eb4ee774 }}, + {{ 0x0009c341cf277327, 0x000fdd366b33f1dd, 0x000f832103f17459, 0x00020d8613b97b81, 0x0000e530424a7a93 }, { 0x000bac5ff89d496b, 0x0003c6e16efb6f3b, 0x0009a4af35445de7, 0x000b6909fdf24b8c, 0x00008e6d72360625 }}, + {{ 0x0001088fdb965d4a, 0x000d187459afccd8, 0x0003363a9676ad62, 0x000588d8e6bd4514, 0x00005899c7ff54bf }, { 0x0000a630bc8a6a3d, 0x000682c1e269375c, 0x00036d1fbb542336, 0x000557f11f9f037c, 0x0000eb8a2a124b0a }}, + {{ 0x0009609d82cffc8f, 0x000ea7eab64c31ee, 0x000a8aefd3c18eff, 0x000a9ea0cffdb1da, 0x000041dcae34044c }, { 0x000ce67dc8a145d6, 0x000af9500d24fc90, 0x0003d839364f3a43, 0x000b1e5de9c75033, 0x000024e5e262c95d }}, + {{ 0x000982daa186bf3d, 0x000d1d44763eb501, 0x0001a82832c513b3, 0x000c80bf324a0e22, 0x000032d177c5f1dd }, { 0x0001ab688e43f0b8, 0x000f1f78bbc55499, 0x0000ed8acfc02b0f, 0x000a6c7507a1783e, 0x0000b89a79b2959a }}, + {{ 0x0007e04350f65b7d, 0x00039b56d0bdd662, 0x000e3cd6ced83cbf, 0x00020b82f0a6ef32, 0x000023dea34ebe08 }, { 0x000df290bff0bdd6, 0x000b4cdc1070c828, 0x0002f2d76e2f397e, 0x000e16129fb2034d, 0x000008903ddb617f }}, + {{ 0x00014fb49f1ee184, 0x0001b33fc2e43263, 0x000d2d8e3b92e418, 0x00083abb53b30076, 0x00001aa8b3c82fed }, { 0x000ada351697521c, 0x000d0a52f7007501, 0x00035650105f08c1, 0x000dedfb02b9e3c2, 0x00008861ad3c4117 }}, + {{ 0x000ebf2c0b49920f, 0x000ddb27b1356705, 0x000f1e3cf422fc64, 0x0003faf9fe85d19d, 0x00004ef9ee33bc0f }, { 0x000f87fda813afff, 0x000ff4eabc199c90, 0x00024732b3060181, 0x0006fed54c703259, 0x0000301ad32fa058 }}, + {{ 0x00001e4bd167db75, 0x000d1fc609e4a74a, 0x00031a4833c074c3, 0x000fcbf362a44a14, 0x00002983fab4c44c }, { 0x000f18181f25f8ed, 0x0003c3273483c908, 0x000118af9d79551f, 0x000b1d37ea79c6aa, 0x000005561a58a7c4 }}, + {{ 0x00083fd5597eef8d, 0x000467c051af62b9, 0x000a73b96f3d0664, 0x000e60da1e9a998e, 0x00006cc734074631 }, { 0x000f6191644596a8, 0x00018ca65d698049, 0x000dcf446dc950da, 0x00041ba3b732b22d, 0x0000e67d9922451a }}, + {{ 0x0001f01cf87103c7, 0x00060eeacee50437, 0x0002bcc0f2099af8, 0x000403405ae419e7, 0x00002218d3d2d918 }, { 0x000ecb8ef6d99c8f, 0x000e47e8887a132f, 0x00086765f5199df3, 0x0003eea5e6751330, 0x0000a872eae8aca4 }}, + {{ 0x0002a910af444e76, 0x000d4223021926a4, 0x00092cf23b6d15a8, 0x000dc5aabb7c28a4, 0x00004beebfd8904c }, { 0x0002c1c510c876a0, 0x00026e07bd68cab6, 0x0008141545b76fcc, 0x000dd0aeb2b57fa3, 0x000028f01be29773 }}, + {{ 0x000fb2f0f13fe534, 0x0008dfbb2d09dc72, 0x0001f6b8e14a4dfd, 0x000cd49b6c3dfed1, 0x0000cba2af46aa95 }, { 0x000b67125e538c1f, 0x000817b80be73992, 0x000df438154aa4c9, 0x0000fbff7ed9327c, 0x0000e6c8e2a6691f }}, + {{ 0x00002e29099045b3, 0x00073e88670ced73, 0x000f92edaaaae805, 0x00082a9bce3dfe41, 0x0000a6fe4cc3fd2c }, { 0x0005bdd6a63370ab, 0x0001411a6eac16e3, 0x0000746d6406529a, 0x0009a52ab7644700, 0x00006744b2717351 }}, + {{ 0x00010c6b129788b3, 0x000e1b07e5c9ce97, 0x0002afa2c95c509c, 0x000dcfa4a0f379e5, 0x000038870779d124 }, { 0x000e2ff99da77528, 0x0003ef971954cf1a, 0x00025edaa877aa54, 0x00047fba8b1cec79, 0x000023185a87ebdf }}, + {{ 0x0006bf94a9ce8a49, 0x0004c3c340ceaa2d, 0x0004576efe8a0a53, 0x000fca76d2635527, 0x0000ef0d9f9a4fb6 }, { 0x000c6f98643cdd39, 0x000610ab76a9af0c, 0x0002ed99c292f6e8, 0x0005b63a052740ab, 0x00002f34b27f25e7 }}, + {{ 0x0001d6152495a6cb, 0x00076a76b2515cf3, 0x000163afb2252000, 0x000dd139771c4160, 0x000019dc05c32b50 }, { 0x000c06a0b6aebb7e, 0x00047e1fbce090b8, 0x000d6fc489a4cb51, 0x0001cce35aac927e, 0x0000dd0bd5bb9272 }}, + {{ 0x00040304b2f32575, 0x000608bafe7ddf39, 0x000d2de3e0a8e028, 0x000e121e755851fe, 0x000012305bc663a2 }, { 0x0009215b9ac0aa93, 0x0006561b0a2a8600, 0x0002055b6de6ae99, 0x0000bb796cf12128, 0x0000d6c9a199774a }}, + {{ 0x00001d3c3571f271, 0x000420537387c09e, 0x000e1021ab2abf2c, 0x000057919c5832fc, 0x000085c20ac422c1 }, { 0x0003afcdec0503c2, 0x0002c41da48ea80e, 0x000deb9fd6d517a2, 0x000ee1fc734e71e8, 0x000090527eb13975 }}, + {{ 0x00010dd399eaf33a, 0x0004ad700235e9a6, 0x00042b3eafd5b269, 0x0003ff3e50308d3f, 0x0000894a8bd16a9e }, { 0x0009738198fc9a32, 0x0007260d1ac16352, 0x000af72f3f46fc54, 0x000b016c584cbb3f, 0x0000e913d664efea }}, + {{ 0x000dd645686c5987, 0x000ed7fa6d74081e, 0x000467cc1cabbdbd, 0x0002f3efe60ea4c0, 0x0000d3d1d48d4bb3 }, { 0x00069876a93ccb94, 0x00037ec96460b259, 0x000dd2439ab5990b, 0x000acaceaa12fd0c, 0x0000da6bef5c292c }}, + {{ 0x00001c7318116168, 0x000fa17472ff5805, 0x0004fab7a07b4f61, 0x000da2392f422970, 0x00000e0d1e93d88e }, { 0x0001e184b20a7a54, 0x000b5b318464945d, 0x000ba2e4420c0b15, 0x0009fe2606d5e594, 0x0000d365f13f5f27 }}, + {{ 0x0006362953e25a5b, 0x000ec524c6a7e046, 0x000adf1ee2117945, 0x000664ea547fa1e2, 0x00008a103e0c9c66 }, { 0x000e3f0859cdc2f8, 0x0004cb15cb12a88b, 0x00096d25592eff44, 0x000ffc8c0561b6f9, 0x0000f36918054b98 }}, + {{ 0x000ab5b320711223, 0x000a2beb92041b8f, 0x00062b91c9ed202f, 0x0001a579401ae38c, 0x0000fb40e7e1d360 }, { 0x000f7ad0829dc074, 0x0000092487443e97, 0x0000199242c6d8ee, 0x0008596378595a31, 0x00001217219125df }}, + {{ 0x000ab2609e227e6c, 0x000e1b61059705ab, 0x000a2c0765f9ca9e, 0x000351fd5a3dd492, 0x000054b35ef99c4c }, { 0x000517ab66adb516, 0x000e8896e70ee822, 0x000deecf0c7cd20f, 0x0001d59caeff2c56, 0x0000ac23b6003787 }}, + {{ 0x00021487098d3893, 0x00021e0bdefdd4f1, 0x0005e1525cf8642f, 0x000032bc06995846, 0x00002ad5c774a21a }, { 0x00067f595255747a, 0x000b83318969006d, 0x000e0b7efa7ee217, 0x00097c961cb4d73c, 0x00007cde45c8bbbd }}, + {{ 0x000e56937bdc883b, 0x000a71e9e70c72e5, 0x0008f7103f8014bd, 0x0009b5cf5b2e52e2, 0x000059c31c61ce26 }, { 0x0003442dae76f13a, 0x000bb17456c61e10, 0x000aa56c75d9f1eb, 0x000b77d55bc2e954, 0x00008d57023bf8e9 }}, + {{ 0x000621dbccc0ef22, 0x000c547ceb26210c, 0x0007b259d32c7710, 0x000b4bc31983545e, 0x0000a78659cb68c5 }, { 0x0000cb3b3dddc4f9, 0x00049e959266fbbf, 0x000642d20bdea51f, 0x00008b496a3514c3, 0x00002d270b753385 }}, + {{ 0x0008c2bf83f14439, 0x000a2ce478e2135c, 0x000ef4e093be4e87, 0x0002341f67547b5c, 0x00000ad1fffb6d99 }, { 0x000c1d8afc50c539, 0x000b1af455809854, 0x00057d1dbacf8e42, 0x000b613acc68d1f0, 0x0000821512510276 }}, + {{ 0x0007e0606f082f40, 0x00083fd9eb45ab26, 0x000b6cd1ce05d312, 0x000e6558a5b234b5, 0x00000f7a741d7de9 }, { 0x0003ddf9a8ed377e, 0x0007270ef751b115, 0x0005a3127425be84, 0x0000278b4f352f17, 0x000037791e3b067b }}, + {{ 0x00051e4e6b8cb501, 0x000c279c21520b0e, 0x000ff6b7834b4d94, 0x00094c6f790864fe, 0x000042d69c0fb7d2 }, { 0x000d60d912391757, 0x0004f7f5c9dc340a, 0x00070f46ed0e8a4a, 0x000afffd05ad53c3, 0x00002565d3e375f9 }}, + {{ 0x000effdf0c11cd5f, 0x0001cdf0eeec8c68, 0x0000788a3915c4f7, 0x0003c36244a27fec, 0x00006b8aecf409b1 }, { 0x000bb395927f21d8, 0x000141c65842df85, 0x00087766136f5c4f, 0x00020dd298821b35, 0x000018965c995c5f }}, + {{ 0x000dee4dc0194e60, 0x000d316fd6f7140f, 0x000abfa03437b7c9, 0x000b47962f9fadb5, 0x0000e38b7d704c40 }, { 0x00062cdef4e7d515, 0x0005f0735d7620e5, 0x00039e5f211dd6fc, 0x000802f9a04e3c2c, 0x0000b9308ad3b24c }}, + {{ 0x00048abb8f5d2a2e, 0x000fc5f477010973, 0x0008cafe1533323d, 0x0009158dd617125d, 0x000015bd2f4c94fa }, { 0x0006588b45797dda, 0x00010b599d94bbd6, 0x000de02c461b7193, 0x0004b1a1ad51ba28, 0x00008fbf0633d6b7 }}, + {{ 0x000970de6f2beb58, 0x0006701fad097a5a, 0x0007b79da2ede893, 0x00026865649883ea, 0x0000dc66c7da4b5e }, { 0x000820bb894ec5ea, 0x0002a245e17fc196, 0x0006990084cddd1e, 0x00078883fd833c65, 0x000023fa1aafb1e7 }}, + {{ 0x000baeb23e56969d, 0x000cc70d875d56ae, 0x000b664d448127e8, 0x000719f12d6a0a9a, 0x0000a1bfa272524c }, { 0x000a8a927cea79d8, 0x000843ab99a907a9, 0x000f67e1618ebdee, 0x00088f59ef1e7454, 0x0000b1cb62e5aadd }}, + {{ 0x000e3f57dc2d6e51, 0x000a50c08191224d, 0x000b000f68b5b448, 0x000753c84c4126eb, 0x000061310eee001d }, { 0x000304ef0417f39d, 0x000a637d446a1dda, 0x000fe29988f21ca2, 0x0002976f57bf2179, 0x00002b04dfb32376 }}, + {{ 0x00051e67299da7b9, 0x000a547d19dfa5a2, 0x00035a8f31025ec7, 0x0008f5cf5db007de, 0x0000c7a0a9aca7c3 }, { 0x0004743570466a59, 0x000f8841ae98e78c, 0x000c62a876c22c05, 0x00089b7f5f818537, 0x0000034a977f0e71 }}, + {{ 0x0003e514e5a4fbe0, 0x000fc5ac242316b4, 0x000c980f9b0feddf, 0x0009eaec6abe060a, 0x000079cfa30418eb }, { 0x000756c3e6d3c154, 0x000a63807d784f90, 0x0000ed5eef704cb7, 0x000ec963d1161a88, 0x0000f21eee5e923f }}, + {{ 0x000fac0dd10881c6, 0x0003801aaa79697b, 0x0008968d0fe0583b, 0x000197fa004a73b2, 0x0000aa2663657610 }, { 0x00019b3e879170f7, 0x00043f57d3d2ec27, 0x000caee09527a33a, 0x000e416ed6fa2fc2, 0x00009abfc9b90ad4 }}, + {{ 0x0007050b07a66baa, 0x000fa966d17fbc7e, 0x00098ccda746ff07, 0x000fbbf370cd1a70, 0x000027f44964c30b }, { 0x000e2646e5bb924d, 0x000fbb61ede9046d, 0x0000b93fdf744056, 0x0006ed7c5a053005, 0x0000ad3637db0835 }}, + {{ 0x00054660dbc8b1ab, 0x000d6088cad38c0b, 0x000fb6902a066a7d, 0x000dc7ca3471b7e8, 0x0000e86a1789d644 }, { 0x00095173a8f8b220, 0x000fe11a6fd8de44, 0x000a5a2626461987, 0x000b8a17c44dbffe, 0x000097f4a165ced5 }}, + }, + { + /* digit=9 (1,2,..,64)*(2^{63})*G */ + {{ 0x00013e2c380a9bf2, 0x000364d391c2a82a, 0x00027444dcb0941f, 0x00055fbcabcdd486, 0x0000ff69ccdcb479 }, { 0x00052b540c86a1b2, 0x000a4f04a057a87a, 0x000001893b8ba415, 0x000c36a44a876550, 0x00000e23c958c1e1 }}, + {{ 0x000f5e69622c79cf, 0x00060c516a0d2bb2, 0x000beb03cb372318, 0x0004c5d8b0d5cc16, 0x0000e18f5d34d82b }, { 0x000648f91783b808, 0x000bf0bf5a01797f, 0x000c6a4c687ad85d, 0x00067d3523d20b44, 0x00009192002a1f83 }}, + {{ 0x00028c5bd0e3d52e, 0x0007eafe60b7cf78, 0x0000021d7c9889ec, 0x000e55cc425860a5, 0x00006eb845413903 }, { 0x000c4c0a359d0286, 0x000bd5edc55ae5f2, 0x000c93c569dc0f68, 0x00021ae2ca527f56, 0x000043058b802960 }}, + {{ 0x0003271e6c831d51, 0x00077b8fac61d9a1, 0x0002d09fe01d7f5f, 0x000a2a4037d25e06, 0x000064507e385362 }, { 0x000ea6041214d255, 0x00051c0232f76a55, 0x000d1178f014410a, 0x00037fc788957c32, 0x000085a49edcb98c }}, + {{ 0x00060cf82fa14b89, 0x0000d4ed0b8892be, 0x0002acf4c3455b03, 0x00078fd269ea1768, 0x0000311da4567f5b }, { 0x00005c27534d6570, 0x0008797d4df55311, 0x00017d92c88f0a48, 0x000cafeb1235b59a, 0x0000809db71804f1 }}, + {{ 0x000f3338ee1c0299, 0x000f84bb5def9961, 0x0003040a98f9248d, 0x0003ac5761cb69c8, 0x000000beb921e57f }, { 0x00066c038dfaec8c, 0x000d10d2f5378a8d, 0x00065894c993b6fc, 0x000735690acf4c2c, 0x00003b9318cab2f0 }}, + {{ 0x00040461e09c5a97, 0x0008f4af94d70cf7, 0x000eff105d9de3f2, 0x000d95602bdb802e, 0x0000b9b80b8301a6 }, { 0x0003d814bf093a24, 0x0008ec8365e9383a, 0x00029c06e19337d9, 0x0007f32c1ea762c8, 0x000062b44e7d6f3e }}, + {{ 0x000e0341bd6ee336, 0x000102bb4d8bc50a, 0x0005fb1615b32bf2, 0x0005df468181c0b1, 0x000049acb4f25f09 }, { 0x0002c9d27e3d254d, 0x000f8cf7003e8666, 0x000a275ad19d7996, 0x00026d7c2f11a6de, 0x0000e62e628f9c93 }}, + {{ 0x000b4e10567aa138, 0x0000a3588cceff67, 0x000f0fb9dd12b3f5, 0x000abd50d8594c54, 0x0000be14cc0ee64d }, { 0x00086ed7a832f320, 0x000a0d5b5ec995a1, 0x0004fbb9c2ac7055, 0x00008b777bf4b9d5, 0x0000c5b6259dfe26 }}, + {{ 0x000a5ff674823c2b, 0x0000030614c09004, 0x000172a0cbd7525d, 0x0008894a1da98d12, 0x000030b72f8253fc }, { 0x000c72e27f2e7888, 0x0000eb81d7ea1d7e, 0x00029433ef893a49, 0x00053356e38cf289, 0x0000353f5c728ab5 }}, + {{ 0x0004cde963d2fb2c, 0x0003cf5a44f77f7a, 0x000d0f6e695842ef, 0x000f5ba097aa5f9f, 0x00008eb52caa0bc1 }, { 0x000239c14011b93e, 0x00062c0eee470afa, 0x000de8059d887af6, 0x000e9d43184137d0, 0x00000f5b3380d1e8 }}, + {{ 0x000b6b6e1ca760d8, 0x0007f19a8afd30bb, 0x0007cf16ffb18b25, 0x0004823e08679832, 0x0000efcafa52751d }, { 0x0002beaaf58337ec, 0x0006f11471f1ff0f, 0x0008cb570ffa8731, 0x0005ed83ed76c338, 0x00004c92081ca03b }}, + {{ 0x000c9c96430e9a0b, 0x000a59ec3076a27d, 0x000e0779be1a0693, 0x000d3642e5e82908, 0x000023d4c1872f26 }, { 0x000b6eb671cf9704, 0x000b48d519bf6156, 0x00059a3370dc9737, 0x000c72ba0e29ecd7, 0x0000d89e2cc152ef }}, + {{ 0x0000aaee181a2a7a, 0x000ff32b88756ddc, 0x000230d35049ce8e, 0x000b74aa4ed4e865, 0x0000261c5ca08124 }, { 0x000d55e8ca475a13, 0x000dab96c168af3a, 0x000f0644ffaace6a, 0x00053a1366563c7b, 0x00008a47ff05a4d9 }}, + {{ 0x000813e66abf3deb, 0x00033d8b76da1f56, 0x00063d76e529d81c, 0x000c8178210dfa46, 0x000088e501fc78ec }, { 0x000d7ee53868e5f5, 0x000b91e350cb901c, 0x0005834c92ea4be6, 0x000c54687b653d65, 0x000007ddaf56d876 }}, + {{ 0x000f835f9d0aad8a, 0x000272e523b8bf60, 0x000b800dac7dffa3, 0x00068eb888009eb5, 0x00005af05fd9e53f }, { 0x00029d4c6fdd401d, 0x0000c312afceb620, 0x000a13ffebd0185b, 0x0006be5b0c797df2, 0x00003ac5e2304089 }}, + {{ 0x00033878925685fc, 0x0009fc1afab4bc58, 0x000ed33fb9b57d7f, 0x000a73a05833f5c6, 0x0000c58881e99e36 }, { 0x0001b7f21a55c701, 0x000b20fadd9419a0, 0x0009ae2c0ace83ac, 0x00042a9c6bcca109, 0x00002b5c2691fab2 }}, + {{ 0x000ce9141bcb3848, 0x0004a19909523c8b, 0x000ee6b8b3259a8a, 0x000919d5aa62f648, 0x00009596a8c13395 }, { 0x000520dbd9ba1d54, 0x000298435f9b9887, 0x0001bce399dce0dc, 0x00073f36c0210da6, 0x00000d8103e648d7 }}, + {{ 0x000a389397c74a91, 0x0009bfec1ab1bbdd, 0x000e022c75a0a320, 0x00012eac4ef8a65b, 0x0000945f9752a8b9 }, { 0x000b8d4c407c4937, 0x000863674660876b, 0x0003f8d0b2f52d8c, 0x000aca39411d67c5, 0x0000712bb3bc0828 }}, + {{ 0x000ecf1276d09b96, 0x00055d1e0a1b12ac, 0x000ca83c96e8b70c, 0x0008f53cb1e4ef88, 0x0000798dffb7e60b }, { 0x00068fc88f16a70b, 0x000f62e1b39b80f3, 0x000cff33731551d4, 0x000ef56c2fd90d0a, 0x00002d84069cd845 }}, + {{ 0x000203d2c908ee78, 0x000ef61196a2fa2a, 0x00071b575e65ca1d, 0x00006d231931b981, 0x00000a20eba5436a }, { 0x000781b3c4ff64b0, 0x0002ee098939db32, 0x000c16deb83df347, 0x000bb4643e37d6c2, 0x000068ca7511af52 }}, + {{ 0x00077057e537e323, 0x000ddb07850ec06e, 0x000895c9b8ea2e5f, 0x00067909dac5a38b, 0x00009de2a5e3a8ab }, { 0x000620a4c251a5ac, 0x0001442b59e78df5, 0x0007c77739906b4b, 0x0003b1e4a4cfc91e, 0x00007e41e6a9a9ed }}, + {{ 0x000e5ae52c223602, 0x000d2aa049f842cb, 0x000456e602ff290e, 0x00090ef56ceabc5d, 0x00009d94422dd0f3 }, { 0x000f78ebd3835c75, 0x00072e6334957f10, 0x0000219b5e9c8395, 0x00039cf7b57e388f, 0x0000e66f4d445c5c }}, + {{ 0x00080ff42e6bc91f, 0x00007052b7ce5421, 0x00095c62c9b34c59, 0x00009d5dae6d4ce9, 0x00005ca79a998f9e }, { 0x0005aebf80664f4a, 0x00082022c34a1c65, 0x0008ec7d87425f4c, 0x000c55ea23803d6f, 0x0000a8295081cef5 }}, + {{ 0x000d185891700399, 0x000e4587135593fc, 0x00065ecd183bf605, 0x00088ed0d32e6eff, 0x0000f3fb39aa7eba }, { 0x0003c612df40b960, 0x000899d6d97e1340, 0x0000d9be34ef3c31, 0x0000ba273d42c6b7, 0x0000fd96d1086b78 }}, + {{ 0x000bf546da5d876f, 0x0005b1504b6c5a08, 0x00088cfb9cc92732, 0x00010fd0035216f3, 0x0000d81054fae260 }, { 0x00001d5cefaf619b, 0x000baa44cd623c3e, 0x0007700e316b2264, 0x0003f24e7366ce71, 0x00007cfc40c2c53f }}, + {{ 0x0005eccae559fb71, 0x000d4d9036520f83, 0x00015ce743b334c4, 0x0005a2904dfb3c3d, 0x0000962fbaf2e972 }, { 0x0007e09d0efe288f, 0x000a3dbf8a5a0ac5, 0x00059388f9f119e2, 0x000fe2da0547972a, 0x00006949be49f2cb }}, + {{ 0x000564c83f9203e1, 0x000b60e2fdd23cc0, 0x000c511e21322752, 0x000e48dbcb80288b, 0x0000797385f1df08 }, { 0x00012d656be5c3a7, 0x0008ba239560368e, 0x000a236ec3766f55, 0x000ddb1c3e893752, 0x0000ce0f9a1079c0 }}, + {{ 0x0003f375576cb563, 0x000f24e63e3bc1da, 0x0001a110da9fde91, 0x000d84707c719b6a, 0x00001a17e6c0b377 }, { 0x0002b1aa240c1a70, 0x0004f760700d3607, 0x00040f793abe8e2d, 0x000d78b4cbb1a182, 0x000018bc4b3b7f7d }}, + {{ 0x000b0c591bd83326, 0x000c4cabe063f644, 0x000371d820edcf2c, 0x0009d54ca9b392f4, 0x00002b614ae1ed42 }, { 0x000be79af8c567bc, 0x00021fd92f1169ae, 0x000b60d7889967db, 0x00029e6af63aeb1a, 0x0000d1f76a097e41 }}, + {{ 0x000fe8bd2ff0d26a, 0x000c04e40e50acf6, 0x00073f191935df0c, 0x0005f541ff0a98ad, 0x0000d0709fed8f27 }, { 0x00066466bcac1668, 0x0009ba16cafbc916, 0x00091ca479cfe8aa, 0x0006a974f170f875, 0x0000aea394d3eeeb }}, + {{ 0x0000b1d093f471bb, 0x0006510f5b343bcf, 0x000a023f726a643d, 0x000ed90df0f2e400, 0x00003c3843aa4ab3 }, { 0x0000bb7742e67add, 0x0003e95c70816030, 0x00093cfe99544825, 0x000be16a6e943e4c, 0x0000792d7df86acd }}, + {{ 0x0003a9e4817dcf52, 0x0001e83824297b45, 0x000001da60dd959c, 0x000f8849e9d0e558, 0x0000f7d56e3c5b73 }, { 0x0001d44293968f25, 0x0008be065eb24132, 0x00046defc5136d73, 0x000f02f92dadbbb8, 0x0000281b17b810f6 }}, + {{ 0x0002077086307267, 0x00015e63b5f1cc41, 0x000abc7fbddc361f, 0x000938b4437ae52e, 0x0000d5d97371ebf8 }, { 0x000fc8b47bfe2c04, 0x0004a491058edeaf, 0x0002b67015a14d38, 0x0000c551c827510e, 0x0000de8b56068862 }}, + {{ 0x000270352a539749, 0x000d7e61b4d5e634, 0x00025b25e620e74a, 0x0003a22edbd86474, 0x0000a57233245448 }, { 0x000a08d537795ccb, 0x00034e664cfc50e9, 0x0009842df60b03bb, 0x0007f949a50dee01, 0x000062e5de6beabc }}, + {{ 0x000ff7a5b46ad8be, 0x00056576be5f7de2, 0x0008922e96e9e3fe, 0x000f20d36d93006f, 0x0000601b5481985f }, { 0x000c615b703d9998, 0x000bbf1cd871236b, 0x000d064911e1ff34, 0x000ff3f6df156a39, 0x0000a91dfe2f0173 }}, + {{ 0x000cde4adff641f7, 0x00041e8de3eee6b3, 0x00086eb2c2b1af03, 0x0009081bd58c7753, 0x00008deb4969dc62 }, { 0x0001141f046d8047, 0x000d8d25302169cc, 0x000fe875ce874407, 0x0001659ee8ca60f9, 0x0000414e05bc5492 }}, + {{ 0x00090cfd9375a854, 0x000ec8d6dfafed30, 0x0003305917f500ce, 0x000ca1ba033a0165, 0x00006da9376c5895 }, { 0x000e293b24e6645a, 0x000f1aea3c40af51, 0x000bb3e7eeccfcea, 0x000bc22e83469ead, 0x00001e948c862537 }}, + {{ 0x00073554cc7c12ee, 0x0004f131e6c0bb48, 0x0005094218689b04, 0x000d40b221900469, 0x0000eedc75a767f1 }, { 0x000c08d7b45cd697, 0x0002f27cbf18a512, 0x000b0429e8cca640, 0x0006fec4d4d93651, 0x000034514ce6bcdc }}, + {{ 0x0007f5e2fb1758d8, 0x00077b486df2a61b, 0x00073501d1a6fc21, 0x000776affa1ed9c0, 0x0000e7124755e764 }, { 0x0003bc919d78f96e, 0x0007e6bcc2423b79, 0x000f26a75d0a01ad, 0x0005738e175ce0a7, 0x00003c4ce13c1479 }}, + {{ 0x0003e291023c1b3b, 0x000ba6f871942dfe, 0x000e94771c645656, 0x000afdf782372ff6, 0x000084b784d593f7 }, { 0x00061a89634cbefb, 0x0001b11e4e8110ce, 0x00044ce70f6b5b2e, 0x00061f4e02a2d70d, 0x0000222495a4851a }}, + {{ 0x0006cd7685d97af3, 0x0004785825808bd3, 0x00070909727c9ff2, 0x000e726d151dc3cb, 0x0000b806e9f304b7 }, { 0x000deb57a092fbd7, 0x000c605b22922a44, 0x000e8db73ec050df, 0x000d714c76494c87, 0x00002e35bd113f29 }}, + {{ 0x0009ed0eda00c05d, 0x000c259c3d12a732, 0x000c7bd5b6434166, 0x000b91ecb5f71687, 0x00008aa1f29eec04 }, { 0x0003fa2fed9642f5, 0x00066474683c2eb9, 0x0005034a4c594fbb, 0x000dd7c674956eeb, 0x0000dc5d5eff55da }}, + {{ 0x0001e6e6273a9971, 0x00099f231f63950e, 0x000032e3bca22cf9, 0x000130d62a77797c, 0x000012ab210bc6ed }, { 0x000864d0edf2e53f, 0x00039b0b3c9fef02, 0x000044fabfd0707c, 0x000e912cfaf7752e, 0x00000d5f6d1d2afb }}, + {{ 0x00024de3470dc37d, 0x000668397c69134a, 0x000648db2f4c601f, 0x0009d3de05a42c31, 0x00001832ed2bd25c }, { 0x000033860bde0c47, 0x0002daab75d49411, 0x00061d1c99e46bc7, 0x0006d2dcf9890058, 0x0000216cef95030d }}, + {{ 0x0006acbb473c0f8d, 0x0000dc82094cec3b, 0x0007898ebbc57ab7, 0x00049cc0d9976fb8, 0x000043a34cd4250c }, { 0x000d91996754db45, 0x0007f6144569d857, 0x00061a5eefb627fb, 0x000fa5c7dc3190a3, 0x00002f9e3edd2df3 }}, + {{ 0x00005c3197c1a20c, 0x0003c37dd1c8a206, 0x0007cf0c0281a36e, 0x000f1f62e7e5410c, 0x000059f6d21710fc }, { 0x00077db2a94dd7cd, 0x000a80101683d546, 0x0004f1dd5f8af1e8, 0x000a95a7f1d7127c, 0x000083f71312d346 }}, + {{ 0x00054d652ad70ca6, 0x00026aaddce33450, 0x0006fbdcde261523, 0x0004ce5dc2a6811b, 0x000053683550c6d5 }, { 0x000c91c825e881fb, 0x00056d492a210056, 0x0000c67f47b9218f, 0x000de150fad7f397, 0x0000880885c56630 }}, + {{ 0x00093e4b2fa0fdfa, 0x000b8a2ce309f06b, 0x000910e8d51c27ca, 0x0004ae92efdb27b5, 0x00004db9e3997567 }, { 0x000141c1e6fe9e0b, 0x0007fe644aa3dedf, 0x0009ced4138cc692, 0x000f98c07317a666, 0x00003ed5e5173c1b }}, + {{ 0x00060318b442f800, 0x0007de5619063736, 0x000e85967ce17243, 0x000a65c36858dbad, 0x0000f669b02efe62 }, { 0x000465311b7e9e0e, 0x0000ecd12ba4b7aa, 0x000b5462f70f3e78, 0x00014050df399daa, 0x000097efc0401f70 }}, + {{ 0x000096a8921179a4, 0x0004ac864d3779b8, 0x00062cce18df4dfc, 0x00017a0283c5d047, 0x0000bb1823fedf19 }, { 0x00068eded5c79181, 0x0002d9d23b3ebc2e, 0x000abef1f1010c41, 0x0001e9e6c90bdd6d, 0x0000b133de5a1dfe }}, + {{ 0x000990b4e4f167a4, 0x000b77799eb6df0e, 0x000089f602942610, 0x000b0008e26c3cc5, 0x0000153c35c8a372 }, { 0x000a4c3313da4eec, 0x0007f7e2586abba3, 0x00051f7d3b8634f6, 0x0009c5606239ca6a, 0x00001e8329fe8908 }}, + {{ 0x000c7bfad0211361, 0x000e706f6a3f6fbe, 0x000e9946570d08fd, 0x0009423d3ad5cad2, 0x0000a4c7595c43d4 }, { 0x00060c43d2476796, 0x00037333e23cb3ba, 0x00041f9a075abd4c, 0x000f0fb063979fe8, 0x000050ba89794e36 }}, + {{ 0x00004ca6d9af362f, 0x0006182be7cf3a64, 0x00027c49cb9a7e78, 0x0006a79a9cc86ba9, 0x00008d6173b50eff }, { 0x0000b23616d2a4f4, 0x000a85d005921b83, 0x0001143565e32ad9, 0x000d0e9c2f56297f, 0x00009e435672493a }}, + {{ 0x000a3e7d01e42a4d, 0x000c021bfe50e2b2, 0x0000b78170df66dc, 0x00081fde07ef8cfd, 0x00003567a5d00f46 }, { 0x00087981154ff114, 0x00063ece38d9d1cc, 0x000dd3e3acce4961, 0x0004b94c9b500249, 0x0000c4108a4b0ba1 }}, + {{ 0x0005187a5a610468, 0x000aa5dec3f1dec5, 0x00003bf8fe7fb8e1, 0x00045ff3807b1f04, 0x000027e52acc802f }, { 0x0000c3db2b856872, 0x000d522eb329d415, 0x000ea0acd8667267, 0x000318628f449099, 0x00009931d6113e45 }}, + {{ 0x000842a93785dba6, 0x000d1843757b3927, 0x000d31f9f72363de, 0x00009edd4326caef, 0x00004a867e26046c }, { 0x000d01979080ff2e, 0x00091965f96b10d1, 0x0005e9a735756595, 0x000f199fc373a9df, 0x0000befd7ab4c167 }}, + {{ 0x000fc047a72b6bf5, 0x000e3585499fb325, 0x000917e8670fd4f8, 0x0009cf9c57b67bad, 0x0000c3e8ea66d001 }, { 0x000b687b7d967ef6, 0x000db59e54a64bb8, 0x000b38cc1c666ef8, 0x000616a8d8862201, 0x000029b881c8aa96 }}, + {{ 0x000ca73dcaf21a68, 0x0006b678b2ecfa91, 0x000d8c64fe6d7cba, 0x000cb5c2b24dfe62, 0x00006a76f958454d }, { 0x000efc172f16fa07, 0x00031b776bb87ad6, 0x000b8346a0f01ef6, 0x0000389cd674976a, 0x0000c0f729ce4f9a }}, + {{ 0x000f232b5f42ffb1, 0x000059b92222f1f5, 0x000a0dd48310f507, 0x0005266ee5a2459c, 0x00000b4b667c3d65 }, { 0x000bd63ba4fde95d, 0x000e1c548e9e5167, 0x0006b5c1af8c6824, 0x000136d23124b4e4, 0x0000f392b3ec6ead }}, + {{ 0x0003122eee899cef, 0x000e8cc290a7f4fc, 0x000d3f748573265d, 0x0000718af6b409c9, 0x0000611f3640b176 }, { 0x0006bba5dab0844e, 0x00050504ef24d7e7, 0x0003c76eb236673b, 0x0000be0015d92979, 0x00002b8b64708c52 }}, + {{ 0x00078e66aa656cc6, 0x000a09cda94951ec, 0x000c9f2a6d6e848c, 0x0006760a44b6af58, 0x0000d198106fc9b2 }, { 0x00085099b31bdc5f, 0x00061834a53b9649, 0x0008670f897ce93a, 0x000e96997fc659d3, 0x0000918e4123a93c }}, + {{ 0x000954ac9501ff4f, 0x0004ffcc52fc2384, 0x0008216d2daa041e, 0x00084af08712b272, 0x00008cb41023b490 }, { 0x0004ccdbf9cf67dd, 0x000d0a47fb2e74f1, 0x000ea3cc4ab6b658, 0x00069d25bee8ba98, 0x0000589f94d48354 }}, + {{ 0x0009c15b35bafc8c, 0x000bc1b7bfe71786, 0x000dfb7efd32fb77, 0x0008ffa7d4e1deba, 0x00001f575658ec09 }, { 0x000e07633366d529, 0x000ed66368710884, 0x000cc4194ecbd474, 0x00068764de5e29f5, 0x0000a864508101bc }}, + }, + { + /* digit=10 (1,2,..,64)*(2^{70})*G */ + {{ 0x000ff71880242404, 0x000f1c7a3e6fced0, 0x0005e468a56ae92f, 0x0000f9670e8cbbdd, 0x0000020c88ed5eef }, { 0x000f9526f1333efc, 0x0008b74bd70437a2, 0x00018a76b379190f, 0x0004cd66e5fb3289, 0x0000132085c0e1be }}, + {{ 0x000edc4d24ff34d2, 0x0005e5192c4d6840, 0x00056736a2a84199, 0x00067dc208b04d72, 0x000091aa355f1170 }, { 0x0000b62c6dbea762, 0x00084bf854279005, 0x00058b53b37ca64b, 0x000f4906c3de8129, 0x000017420c7a1978 }}, + {{ 0x000c11118ac1c9dd, 0x00006b4c72dfe67a, 0x0005e4d08e55132f, 0x00049e035c416b0f, 0x0000282e71d5028a }, { 0x0004097747951cdc, 0x000c718f00628413, 0x000f55e9dfad607b, 0x000fa9e0cbfe0602, 0x00007edbf6c8369a }}, + {{ 0x0004645d0c999206, 0x000f55ed005832ae, 0x000aac9fd1427420, 0x000def2ca5f5efd3, 0x0000d8417da6ba53 }, { 0x00015bfe3a91ab48, 0x000ad8bc9001d1f8, 0x000bccb573cb03eb, 0x000ed588452c8f0b, 0x0000190d99ea9851 }}, + {{ 0x0000b35e6bb694d2, 0x000723f23885e5fd, 0x0009178fdc3fe150, 0x000401404f72f8f9, 0x00006aa2e224e92e }, { 0x000c8b1a1eb06618, 0x00088489164722d3, 0x000b4beb04a9a74c, 0x0004220323e3c665, 0x000059dfb811788d }}, + {{ 0x00086a67d771ac98, 0x00014e654317cac3, 0x000919ad09dbd2eb, 0x0003350b8be600ab, 0x0000e6ed7070c73f }, { 0x0003ebd5c9545d9c, 0x000f18d4431cc288, 0x00021471ef5ad0f6, 0x000672232a7cff14, 0x0000aa1dd2bbd83f }}, + {{ 0x000fd169fdcd85cc, 0x000b4a7b1fd2b0bc, 0x00058c1ac9eaecb4, 0x000ee73b39b3ad39, 0x0000f7b13aef63ab }, { 0x0007e6961db7503a, 0x0005fd79ce0a6af4, 0x00019c46a9db1c64, 0x00073a7b255dc1cf, 0x0000917465424f0f }}, + {{ 0x000f6928ec987520, 0x0001acce548b37b2, 0x0002556adc5cbc76, 0x000befb4fb38e754, 0x0000e6f549a164e2 }, { 0x000cbaf6791e178f, 0x000242386ce6c413, 0x0004d3f2b753e67f, 0x0009e6bf901be1c5, 0x0000fea1ab006e2d }}, + {{ 0x0003452936f20eda, 0x000474550ca42470, 0x000ae49807739ac2, 0x000811424ba1aa47, 0x00001f1e4b8ebaf3 }, { 0x000ac86d5bc8d43a, 0x0000181243aea965, 0x000ebafb6389c308, 0x000c049619a2919a, 0x00002b0cb20d9047 }}, + {{ 0x000f1bcbbb3db35c, 0x0007d18c36cf4406, 0x00075a1da5e1badf, 0x0006e2f64aed3e83, 0x0000987f12991782 }, { 0x00022fe40b1a2d46, 0x00090ed60919b8eb, 0x0000d89215e03057, 0x000a894efd890079, 0x0000d06046a39ef3 }}, + {{ 0x000d57eb5760d1c2, 0x00099a2157f2db33, 0x000f50d0df45370f, 0x000e83254bda2fc8, 0x000085807ee44cd6 }, { 0x00038f14b932ce60, 0x0008ba2fb5ee9973, 0x0002ad862411b6e7, 0x00064197401648ca, 0x00007031fac23dc3 }}, + {{ 0x000afcbcddc5b4e3, 0x0003f6ad7ab9a2d8, 0x000cf2fe2c7a8c98, 0x0009cf5c29c00090, 0x00000a465e1b5bc1 }, { 0x00039efc04140b7d, 0x000aa29e99d043b6, 0x000b4b1d9836432d, 0x0007aac35ef51263, 0x00007f50574f8f0c }}, + {{ 0x0007b58f4a281850, 0x00004b366b4be7ad, 0x000dacedead3f7c8, 0x000bf0cd93f25a9d, 0x0000ff4401b26350 }, { 0x0006a8e2b1dfd7fe, 0x000fba9ff563436b, 0x000932066f358f9c, 0x0001181ecf718ff2, 0x0000bb7b63ee6136 }}, + {{ 0x0001fe1782b8ceeb, 0x0004fa8327720c15, 0x0002680b1545ef26, 0x000a5814d956ca32, 0x000014f5d4a9c76f }, { 0x0007ab1de209b63f, 0x000f5db3c832c80a, 0x000bc5f7c5d2c7e4, 0x0005a0dcc60dccc5, 0x0000de8668f74c00 }}, + {{ 0x000686123db19be9, 0x000c50b3893d123d, 0x0002dad8d4df00f7, 0x0000d5d8bf7b7578, 0x00008135b99cd691 }, { 0x000b6a20e86bb9c5, 0x000a391a7ab4116f, 0x0007a97c837120a7, 0x0002c35d76fcd72c, 0x0000531c7135280c }}, + {{ 0x0003b25760e88423, 0x0009b7d341d81dcf, 0x00083e622c18ffb5, 0x0007e4badcddb688, 0x0000becf33dd410e }, { 0x0009a60cc895ade5, 0x000e3f6a7a73ae65, 0x000e082fa7baab21, 0x000f729bc83879a5, 0x0000c301b48a24ab }}, + {{ 0x0007d6af9dfc33c4, 0x000f9ceb18762621, 0x000ffad89f4b1f3f, 0x0003a59072b0d79e, 0x0000cd702c4f6dd8 }, { 0x00002614f15b98f8, 0x0000c616d7364517, 0x0006e68aaa6917b9, 0x00000a39d43cbbd9, 0x0000899bf61d6a7a }}, + {{ 0x0006dedaf4a7ec4d, 0x000a31a59c3e9f87, 0x0007578c622162c1, 0x000f162ad40200e7, 0x0000d60b302fdf36 }, { 0x0007b6a2e807e456, 0x0002a7c4bc2e88f8, 0x00008cb732bd420b, 0x000a903e96ba8129, 0x00003121d1ba9275 }}, + {{ 0x000582b557d8da3c, 0x0005d971b4e598eb, 0x000e517b95c5fc8d, 0x000d82bc5f499ef1, 0x0000275cd05a5723 }, { 0x000af53901d82522, 0x00090ca1715cb07e, 0x0001998aeb1b5a8e, 0x00031fccd4c3de6a, 0x0000aa50e5e8ebf3 }}, + {{ 0x000f2386acf8a72d, 0x000604ac3b819900, 0x00028ee94251e622, 0x0000cfab91cb8372, 0x000019e78eaae4da }, { 0x000f8063ac90f7e0, 0x0006d1eb32912137, 0x000dda25c7380214, 0x00046a9e3a2f82b2, 0x00002b889ab4a768 }}, + {{ 0x000586ef16cc6afe, 0x000b76759ad2877c, 0x0001d2ded83e32a3, 0x000039c846f45464, 0x0000d9ede27f0357 }, { 0x0000d0e5fc379cde, 0x000d8e024bafad93, 0x00023409aa6e07c5, 0x0009598a0c8b42bd, 0x00004ed05a16b8a2 }}, + {{ 0x00086b599a8c25a4, 0x00086e1e8b4dfd4f, 0x00068a9672118f45, 0x0000495acd754d5c, 0x000052f9c3c08e85 }, { 0x00027d16d7f92149, 0x00095a799f9d5812, 0x0008a07de7d22da8, 0x00003bca50473b1a, 0x0000faeb0de17d42 }}, + {{ 0x000721dfee849503, 0x000f43cad3d97f9a, 0x000477f19466ae81, 0x000004b7c52bf3bb, 0x0000ff72b1d2fc85 }, { 0x0004e7ef4acdcc1e, 0x0007a21141d4579b, 0x000bf553e4eae6c6, 0x0002e42153411321, 0x000058c897845f4a }}, + {{ 0x000a78b173431ac6, 0x000037c593710000, 0x000074fceaa51d30, 0x000c0a565e1c48c7, 0x0000087805015262 }, { 0x00044c6adeb5098c, 0x000f59dbcc8ad945, 0x0006844fc921b6d7, 0x000aaf80a70dc04f, 0x00009ea6e278d5f1 }}, + {{ 0x00018b6ba74db2c9, 0x000294e907a544b9, 0x000a9fb236691c4e, 0x00031d04ba7520dc, 0x000017babaf8cdc4 }, { 0x000818ebab294990, 0x00050fc644be8924, 0x0006b5968097aa9c, 0x0001283fe707a981, 0x0000f54144f9bcc8 }}, + {{ 0x000a2e6ab0d7e737, 0x0009cad58d2f767a, 0x000d2db95cc250c3, 0x000c89598dc5267f, 0x0000fb76d298d7eb }, { 0x000b5ae1ce39226a, 0x0008204d0c63eaaf, 0x00041ea4c6649b4d, 0x00017f91fa1cb92c, 0x000080a55559aaab }}, + {{ 0x000d96332d46ecf1, 0x0000a906e77de048, 0x000062d7886a21c8, 0x0002acf1d7992bcf, 0x00002e42c527e67d }, { 0x000072690f62575b, 0x0006e3a413aa2b94, 0x0005bc265f962dd8, 0x00007b63799a4d91, 0x00009074a785f7f4 }}, + {{ 0x000cf86624af5d13, 0x000f4cf02ff6072b, 0x0008cde126b78788, 0x000985309a47d2ca, 0x0000c4b1abc9fa46 }, { 0x00028fb8b07c6947, 0x000bf87aa9e5cb6d, 0x000144b063bc3aa2, 0x0003ccd35c98124f, 0x0000562b62f1af58 }}, + {{ 0x00050467db792ce5, 0x000972a40c251f81, 0x00078dd5dce34079, 0x0006e6f2388cd5d8, 0x00009ca7a668bb67 }, { 0x000b3e67f86537e5, 0x000f9bbcdabb8397, 0x0002764532467c29, 0x000f53b2ba79e974, 0x00008ea58750c9ff }}, + {{ 0x00068bd1f9103bc2, 0x000158fb1cb6ac9d, 0x000df3913b4c4a6a, 0x00069fd95ffa13e8, 0x000056704285e41b }, { 0x000990a0579bee8e, 0x000f8f926d783f2c, 0x000332aa0f6a131e, 0x0008f1b7c543a59b, 0x00009d122d6f7adf }}, + {{ 0x0006ba4245768c48, 0x0002db8519cce2c4, 0x000f6759961dc7db, 0x00035185cfc9af71, 0x00002da71c5029d1 }, { 0x0009e5918edc1491, 0x0005da4d3fd524d4, 0x000123fc1b33c45b, 0x000399a421e72464, 0x0000b38767166257 }}, + {{ 0x000915ee22d46e27, 0x00009b665c7322db, 0x0000faabc5d86f27, 0x00004cf85cf12cc0, 0x00003fe2633a632d }, { 0x0000a1c1ed8106c2, 0x0002e3ba317db248, 0x000897173dd719f7, 0x000cd0e5087dec65, 0x0000d47fab598e63 }}, + {{ 0x000caeecf58691f9, 0x000319678bf030ed, 0x000973a71452fdfe, 0x000a42b26fb5e9c9, 0x0000351791169cdc }, { 0x0008168ffbb6faf1, 0x00096bb518d0c6b1, 0x0002b381cba209dd, 0x00080d2819918115, 0x0000fd4bfcc99d38 }}, + {{ 0x00083365828a1975, 0x00058aa2502753c1, 0x0006390d16bf0feb, 0x0001befe5bb279e2, 0x0000995cb1132868 }, { 0x000733edbe3a75bd, 0x000fbc4eb8098772, 0x000dc2da79704c0e, 0x000789b67b336e18, 0x00009002f7d131fa }}, + {{ 0x000791f21653a4b0, 0x000d09a26025c3c4, 0x00064bbeed725db9, 0x0005e4d8ee6e981a, 0x0000b19e4a202131 }, { 0x000266ff7fb4c307, 0x000608925f02425c, 0x0003b83044c40262, 0x0007ec552ec86319, 0x0000716e68f00346 }}, + {{ 0x000c27ebc50428fd, 0x000abc3017025f39, 0x000c5f6d8def3924, 0x0000e19ecefcf628, 0x000032c44e11511b }, { 0x0005c3dffed38017, 0x000f7a11da1767e7, 0x0001d13c6c588b39, 0x000a35cb7fe15145, 0x0000aa988aa4f7b8 }}, + {{ 0x0009889769d0f731, 0x000f973ddc925fcd, 0x000055dd56a16ccb, 0x000258eebb679c84, 0x00009268c8cc2b74 }, { 0x00097b2662417e26, 0x000a87fb28ad2470, 0x0003f70e2717aaa2, 0x000e018a7e99146c, 0x000093a9487d1a5d }}, + {{ 0x0003e3172fc44d4d, 0x0001de6cf9f82a81, 0x00092fac300b1732, 0x000eb09c3319decb, 0x00004b56a4e95663 }, { 0x0006f61f75789888, 0x00070dc7d5a006c0, 0x00066f0587dcb0c1, 0x00029a49e2dbc27c, 0x00002832c4e33d0f }}, + {{ 0x0005c14ee801bced, 0x000cc7104779ce2a, 0x000164ec7c3519ae, 0x000edc5d5aca8381, 0x0000fa85767ed4ac }, { 0x000ab6c37ae9b82f, 0x0009683f17a62c70, 0x000c0c80967bc048, 0x00011798f39eb962, 0x0000d8fded0d599d }}, + {{ 0x0001e7018d266862, 0x000e5dba28a0749b, 0x00063c6a8fd87c38, 0x00018a515246c20d, 0x000045c4ea3224ad }, { 0x0003ddb70877d76c, 0x00045faf380ff628, 0x000d6fed75158c1e, 0x000ba3bdaef7fb1d, 0x000069deaeeea084 }}, + {{ 0x0005f83f869b4f81, 0x0006111fe7df7a4b, 0x000150472fba2a01, 0x00027069ca7cd07f, 0x000060963577ae8e }, { 0x000e155d967e0f8b, 0x000475ef3d8ac3d1, 0x000f446c416bd09a, 0x000e51a646fe2066, 0x000079aaace72c50 }}, + {{ 0x0005c34d6e4e9113, 0x0008e9bc3a72d004, 0x000b3f5075acc01f, 0x0003533374037665, 0x0000a738807c50b6 }, { 0x000a94ea00049bb0, 0x000310ff01fd7967, 0x000183a17db85256, 0x0008620c04dfb810, 0x0000ab6af468538b }}, + {{ 0x000fa6b43cf5d930, 0x00080d9bb9aa8822, 0x0005bc5f48d33762, 0x00043764eea20e4e, 0x0000fab3b1672224 }, { 0x00016dd2c48181ee, 0x000f5cf3aa91121f, 0x000948c634d733f5, 0x0005e41c08c6bd5e, 0x0000bc67f9d574df }}, + {{ 0x0003b606436178b1, 0x000c5d980101b980, 0x000db479092353f9, 0x0004b3ef3760883f, 0x000083e79a8931ea }, { 0x0007ca7221dd1d3e, 0x00015dfe05beeac9, 0x00022468b3abf051, 0x00031c5c3f2f1e86, 0x00003d226244ff9a }}, + {{ 0x0002738eddf0b5e3, 0x00087fe1cd19f723, 0x000cbf106d0d6957, 0x000765d3ca20915d, 0x0000205e1c9f6292 }, { 0x00018be236919468, 0x000b5f6b5eccf1aa, 0x0001872fffb9b505, 0x0007994934b5aff4, 0x00005e213e2348c5 }}, + {{ 0x000cecf93e151784, 0x0008bbab00ed3a95, 0x000416e0ff80909b, 0x000ade39734c6137, 0x00001fe486ea0896 }, { 0x0002d754720a1bc6, 0x000f841a968fbf0c, 0x000257852acb7321, 0x0006be3c7d23d458, 0x00003c39d3db2eb6 }}, + {{ 0x000b84a8eb836754, 0x0004b4a4eb732ec8, 0x000d2645c301b385, 0x000de24926c943bb, 0x0000f1ce27e0f66e }, { 0x0004a527b9540d18, 0x00054d32499dd5f3, 0x000dda2b269e8c86, 0x00023459d12053d7, 0x00005b6b44f0bd90 }}, + {{ 0x000c957990ece73d, 0x0000df09cec46eaa, 0x0000b8f62236fab3, 0x000c7f275b15347a, 0x0000c5ac243cde48 }, { 0x000f0546734a7a95, 0x00048a3c33a655d3, 0x000e494c042fdbef, 0x000d948415d503c2, 0x0000ebeb1661c3ec }}, + {{ 0x000222b6eb506da1, 0x000b577496125bd4, 0x0007f55249816eaa, 0x00095d799fb0023c, 0x0000430859f143e9 }, { 0x000dfb4f419b49b7, 0x000a7767866d25a6, 0x0007da3c5b2da294, 0x000a816b8b6eb04f, 0x00007d8063c0d891 }}, + {{ 0x000b45f1f50f92af, 0x0008fa448ee1f3a5, 0x0006aa5cbde06eff, 0x000579a489604d9f, 0x000024726a073e31 }, { 0x00065f33c2e91ce3, 0x000a0764acc757ed, 0x00078d775c347692, 0x000f15d4ba7cf9ab, 0x0000a19d93dea6f5 }}, + {{ 0x00095867f0c050ab, 0x0003315a377b14ed, 0x000ab4e18e1c0315, 0x00095d6486bf5463, 0x00009848fb503c6c }, { 0x000d4e25b124b432, 0x000d044ef5ab0172, 0x00011d673761aee5, 0x000af5f690bd2d8c, 0x00003bc0b64a021c }}, + {{ 0x000ab18bf1911b77, 0x0003cb5e224c5d71, 0x000c4dafdd27e4f1, 0x000f8ae52fa3baf8, 0x0000e716268c21fb }, { 0x000e9459a90edef4, 0x000013e9bdf25ddf, 0x0002ccd877ab4708, 0x000099c8004cc0bf, 0x00006969a689a087 }}, + {{ 0x000150ff364d5f18, 0x00071cacce9bb324, 0x0001b68d834f5fce, 0x000f2a54bddea65e, 0x0000dd6efba4ff65 }, { 0x000d6aaf6a6490d4, 0x000f401345f4e475, 0x0000c2cf77022252, 0x000ca4b133bf21f7, 0x0000818207356a20 }}, + {{ 0x000e990b48335965, 0x000ade1813d28f11, 0x000d5c3e99daeab5, 0x000eb3c7b6000e11, 0x000048dc9938a793 }, { 0x000bccfa65f60763, 0x00077ee93e976d58, 0x0000ba9412fd72f6, 0x000367788696241d, 0x0000ac1c3f505d93 }}, + {{ 0x0007de5f15b7c4ec, 0x00039b4c5cd14112, 0x0002d757f99bfdcf, 0x000bfe393701b404, 0x00007673cbf8b48f }, { 0x000d5487494f9df8, 0x000d7cef8d53f19f, 0x0000a6b5ebc3fb1b, 0x00050128addb1031, 0x0000e5c1f0ad87ff }}, + {{ 0x00098a932a972998, 0x000cb16a8123ef0f, 0x0003ee6ec10db2ac, 0x00074e05473c32db, 0x000030cbcdd6de76 }, { 0x0004ed4bc54db179, 0x000c3f60c6aa20a6, 0x0004103a4fed7821, 0x00098fa079a32ba1, 0x00008266f6300629 }}, + {{ 0x0002377007b82c41, 0x000d906d4caed0d9, 0x000684e5b2ac09e2, 0x0000627d7b802140, 0x00002dfa1b9afd19 }, { 0x000deb5a5140a60f, 0x000bcc371f21a855, 0x000a9a380f69015e, 0x0002249f918461b7, 0x0000baa37b31dfff }}, + {{ 0x00024176970787f9, 0x000a446d5eea89e7, 0x0003960208b4ce0d, 0x000762c4ffdff842, 0x0000b88756f44d35 }, { 0x000fc0da3195c361, 0x00027b9102cae3e6, 0x000d81d583cdc7bf, 0x000b577472d143e3, 0x00006226cc2a450a }}, + {{ 0x00019f54522deaac, 0x0003edfe45083a2c, 0x00079cbbf77b74d0, 0x00060e27f66bc721, 0x0000bc98cdbbf0a2 }, { 0x000fb17de31b650e, 0x0001e495b7eeed57, 0x000cfaf861be44b3, 0x000d376add9954ec, 0x0000243fb73909ab }}, + {{ 0x0007b8aeb5cd1941, 0x00023c5abb020e8c, 0x0003520c40119c32, 0x0002e52e53d18c18, 0x00009ba1a706394f }, { 0x000fe115bb0b6f18, 0x000b243f0f8c16bb, 0x000c16989d3b2f32, 0x00032edc9224ed5e, 0x00004558e4f0f44a }}, + {{ 0x0001277b7939f433, 0x000d5493927f4fec, 0x0003b4732c4c5df1, 0x000f4d751f91fbf9, 0x00009c1127aef031 }, { 0x000ec971f4c96c45, 0x000206ee7a759524, 0x000043c434006fef, 0x00038004f00df7de, 0x0000b58465048083 }}, + {{ 0x0000d60da1b917d4, 0x000f107e75d9ccc5, 0x0009ecf2f5648cab, 0x0009c77dc63b7be8, 0x000043a02262c4a4 }, { 0x00017f5de960c25a, 0x0000bee08df1b120, 0x00097e712bf60ed9, 0x00025a73d3873487, 0x0000b1fb76167cdf }}, + {{ 0x0005d84aa3afdbbf, 0x000b966e8e575672, 0x000ed4249074932b, 0x000372274c9f781c, 0x0000cdc2169236eb }, { 0x0007c4b46d4fac70, 0x0002e094d0c0ce2b, 0x000adafa0737f634, 0x000c614c71564008, 0x0000178fd068c458 }}, + {{ 0x0002aabc59c94f12, 0x00095b397acf4ec2, 0x00003bfdf9e674d3, 0x0004780850426c40, 0x0000ca04d6eb4c85 }, { 0x0006908d03fd22f0, 0x000814c5f5942bc4, 0x000db3a0f5e9bc06, 0x0001e62ba9a6168b, 0x00006bd8a9096113 }}, + }, + { + /* digit=11 (1,2,..,64)*(2^{77})*G */ + {{ 0x00009d21104a01b4, 0x00024745a1251fb6, 0x0008668a04b75ff4, 0x000fe349e967747a, 0x00006e02c0c6d4e7 }, { 0x000084a333d89913, 0x00059a82fe122271, 0x0005f3a1a369f264, 0x000fa053caf9b5b9, 0x000022f6b350187d }}, + {{ 0x00048ff65b341317, 0x0008233aed1d1f71, 0x00033bc63a356251, 0x0001b22cf566eaff, 0x00007f53d3789579 }, { 0x00086fa303582c2a, 0x0005fd4cf94cf0dc, 0x0003899cb5afac02, 0x00035800d319bec8, 0x0000afb9e2fd22fb }}, + {{ 0x000f31d817bed07d, 0x00055ab5c8b06d5c, 0x00022f1cd42f3db3, 0x0009efa79b1a785a, 0x00001ca931baa4c5 }, { 0x000b66d8a740682e, 0x000d06a15d7dc85d, 0x0003d89a928be329, 0x000b486c72f132b0, 0x0000478e55d53bd7 }}, + {{ 0x000e23139482dcb9, 0x0001ee1adc1696fc, 0x00023caa5f3be88a, 0x0003ebb3598ebe59, 0x0000801aabeabc49 }, { 0x000560a9c8a8fda0, 0x00082d4db067df91, 0x0005b59ef1377a4c, 0x0000329c198dda09, 0x00005daf596bd7b8 }}, + {{ 0x000029268430e2db, 0x000923e99e0925f5, 0x000612f910d69e1d, 0x000881aba2dd74a9, 0x000075a644f8e684 }, { 0x000b66a21626e638, 0x00014b41aeaffa32, 0x000f702ee5abbbdd, 0x000eafd0c8b17203, 0x00001a68d527f1c3 }}, + {{ 0x00089de4e0f889d4, 0x0005e5efe51bf748, 0x000dd5a81bb30fc6, 0x000505b259c4f579, 0x000013cc73a8497e }, { 0x00057568b82d7835, 0x000b706646083ce7, 0x00054a6bbebb3b88, 0x000bc0c10be2a033, 0x0000d865d4a67d97 }}, + {{ 0x000e11a1d8d399bf, 0x000d87900f7e6c85, 0x000eb19b3117a1bb, 0x00064247538e8b94, 0x0000d5742a10d630 }, { 0x0007b6a724c5c32f, 0x000812ec1e2f2ef2, 0x000b9e4effa0ede3, 0x000d6dc2d193d2bb, 0x00006ad06c86c96d }}, + {{ 0x00064232b86345c6, 0x000491cf1c367cab, 0x000b12cd89c580bf, 0x0005b4a329bc85a9, 0x000061507757ea7e }, { 0x0007fbd8ddb9611c, 0x00062b0167dad297, 0x00011cbbb1d53bf6, 0x000c8188b1604f30, 0x00001f4d0fd7d22e }}, + {{ 0x000307a8c0590774, 0x0009aa5b964e39a7, 0x000c5dcc1eae81ad, 0x000c9a564d4c29e3, 0x0000ef66dab1bbfd }, { 0x000139e05cf3cde4, 0x000ddaa91708c3b5, 0x000bd7852e8e71ed, 0x000d569b7a151e62, 0x0000050f4937247b }}, + {{ 0x0001e893a8e9fd20, 0x00031b494a7cd2e1, 0x0000f4b09fc385f9, 0x0009d696a5671ffd, 0x00009847745f23ad }, { 0x00023ac856040d5f, 0x000a7a165cf7b104, 0x000882d2bc2f947b, 0x0002854de81b6717, 0x0000ef3de081df86 }}, + {{ 0x000b2c9190e12088, 0x0008587dac50b74b, 0x000e9d3ce1bbce37, 0x0002da0fb28b2b89, 0x0000cabf97afa5a6 }, { 0x000f9f3f579f2fc2, 0x000a71884a9d5b7c, 0x0004aed7c41c7a6f, 0x000092de27ebe232, 0x000029c3d363af68 }}, + {{ 0x000aec5d6d717771, 0x000f8e1096187086, 0x000456979c440027, 0x000f2b0afcc9e836, 0x00008cf2ab4e27c4 }, { 0x00007dfe122baae8, 0x0000f8a994f04e95, 0x0007d694479ec283, 0x00039574fb39ccae, 0x0000aa93a28e976c }}, + {{ 0x000a7d33d6e39217, 0x0006acb489b03e9c, 0x000aa446e1236c2d, 0x0008923e5db86ec5, 0x0000d513e9282311 }, { 0x000832e75dca4e42, 0x000ed5c0ae6c4d0e, 0x000d8b63ae0adf74, 0x00059047ea9ca1d1, 0x0000237a1f96d350 }}, + {{ 0x000170458c664431, 0x00049ea5232123db, 0x000bb43e414ecb07, 0x0000237ed08307c8, 0x0000c4bbbb01d044 }, { 0x000c7f7317b92a8f, 0x000afc6c19bb9866, 0x0006418391d59403, 0x000750822c5f3484, 0x000021de21b188b3 }}, + {{ 0x00068d834bef31c4, 0x000d00e9d6d2e8b4, 0x00010e11f94b7363, 0x0003f7485d318b8c, 0x000049cae972b8a8 }, { 0x000b12c61b315467, 0x0007eb2bfba796e0, 0x000b625f2afba6cb, 0x000620753152364d, 0x0000ade1ce1d3e84 }}, + {{ 0x000eb572d99661c4, 0x0008402fcf0a7fd8, 0x0008c5d33d449b8f, 0x000f0f09842fd078, 0x0000da7983de9402 }, { 0x00076f6bdb01f785, 0x0001f4c4d194a88b, 0x00090292128bdeab, 0x0009129fcd2b63fd, 0x0000ebc377dfedf6 }}, + {{ 0x000ba4521833ac99, 0x000984bb46c2397b, 0x0005a248d600e4d2, 0x000c9b434004cf56, 0x00002121f29dec04 }, { 0x00078cd8c6df3a54, 0x000f1711171121e1, 0x0001d03cddaa270c, 0x000d52107ad7b7eb, 0x000098a27d377993 }}, + {{ 0x0008ca59bbd2a43f, 0x000a201b2a672385, 0x000756d1bb36ec67, 0x000c1e1753556d36, 0x0000c58a255d75d2 }, { 0x000aed0cd5454528, 0x0002b92a569a73b1, 0x00083babe9f4067f, 0x00068af55517a52e, 0x000059afbc58d069 }}, + {{ 0x000c3323e86fa8e0, 0x0001f8480af13722, 0x0003c58739374a0c, 0x00050ad31244c311, 0x0000126dd368d686 }, { 0x000979d546fc2f7c, 0x0002f4a5594b1dd8, 0x000b453aa4371b74, 0x00058ee19a1928bf, 0x0000915af098fee8 }}, + {{ 0x00033084d9c7276b, 0x000bbbc19f9e9676, 0x000285cb3a74d9cf, 0x000491240d9d0315, 0x0000ba33cddb43f0 }, { 0x000d408f6f73b28c, 0x00010dc55667eaf7, 0x000ab10446007a1b, 0x000e39f1473b7f92, 0x00002ef1a03646da }}, + {{ 0x000103f6bba1307c, 0x000d1dc164a89bb6, 0x0001ddefc64a2b32, 0x0005d70bb74a42bb, 0x00005152ad60f6a1 }, { 0x000e4781a0271b2b, 0x000ca81355a5752f, 0x0007024ce4d4d310, 0x00084f73b562f96a, 0x0000c477204acd46 }}, + {{ 0x0000757b5f4712e4, 0x0004c75f8dfcf8a2, 0x000a74f11cc657d7, 0x0006a5bd8a284f0a, 0x00007dda9a0af13f }, { 0x0002a3e7718f7a6e, 0x000d22093b8a5ded, 0x0009191c86356347, 0x000f92e33d3f9335, 0x000055ce4eafcd22 }}, + {{ 0x000c17e23aa997b3, 0x00096f4cd941534e, 0x000af7af39d3fdd7, 0x0000044e30d37406, 0x000017d4ad645c92 }, { 0x00052737e78e08ec, 0x00019516f496ba27, 0x0001c18619005520, 0x000df03f56a69317, 0x0000b6ddc6edbaf5 }}, + {{ 0x0009a1904af269a5, 0x000ee2c68af43eec, 0x000da69b7072b08d, 0x00046bcf55502468, 0x0000f80ea4ac443d }, { 0x000a17081f1c5679, 0x000da8d470c56a4f, 0x000e1f2684ceb758, 0x000ba15f3159abc5, 0x0000964c76954003 }}, + {{ 0x0008102033e8adcd, 0x0002e2b10c8c0f59, 0x0009a854e5133f03, 0x00015f2a72102c3e, 0x0000c9a9e311aba2 }, { 0x0007a89342969c71, 0x000f33ff1d18a13b, 0x00012053c7add2ec, 0x0004e3ed835eebd9, 0x0000d9e680e72864 }}, + {{ 0x000ce7c67c39f8eb, 0x000838decf2a73a0, 0x0007816d5317f027, 0x0009468a2066a639, 0x000026677b2d0e7f }, { 0x0005a428ef86e036, 0x0009071759a113ce, 0x000269cb3f0ac1ee, 0x000563c7be3b373d, 0x00006ff591e18a76 }}, + {{ 0x000b6b40b404a661, 0x0007ac81c86682bd, 0x0006dd64ea76b3ad, 0x00015d19ab78d272, 0x0000fbd431bc398a }, { 0x000802739262b87e, 0x000297db8c4961f6, 0x000bb8e36d198176, 0x00030325eb1a12f7, 0x0000129ba25ce217 }}, + {{ 0x000c873312835882, 0x000685f16b1bd5e5, 0x000ff15bd7c0e8a6, 0x000dcb99ef957e41, 0x0000fdf280b53be6 }, { 0x000093ef1a573f41, 0x000b88cb65f57cb1, 0x00014d78ee26f748, 0x00048d340db60a62, 0x0000c4ae6cba4b4f }}, + {{ 0x0005f9a99adf6ad0, 0x000dfb53f4ece64e, 0x000d900aab7fe12a, 0x000bbe8cd6a6bb02, 0x0000244f4571b32b }, { 0x000cb9c4a0dadc5c, 0x000682511a7de841, 0x0005e0eaa53ce5b2, 0x0009034a28356809, 0x0000d2319e930091 }}, + {{ 0x00070b941f431f96, 0x00035babb2eec644, 0x000492f8199f509d, 0x000c8d4c4a0c23b6, 0x0000055b8ea1eb9d }, { 0x00073291adbc3b63, 0x00073799df435742, 0x0008e83346629e9d, 0x000445a814ccfb8a, 0x0000b7b0d75235ee }}, + {{ 0x0005efcdfd123b2e, 0x000866b42a92806b, 0x000bf27ae64de389, 0x000d09bf8810684e, 0x000050a1dcc40eb7 }, { 0x00050352364d1ab7, 0x000d2076e9edd128, 0x00004fd440c2c9e1, 0x000e85a6de29d0b5, 0x0000da6c7734e64d }}, + {{ 0x000943b9b2fa6dc9, 0x000e0b2b4b4b67c8, 0x00005ebe4c512574, 0x000128fd8c1d10df, 0x00006e0e8ebb49c2 }, { 0x000b34a5656dfc03, 0x000d6143b3def048, 0x0001c1b2d09a22f2, 0x000c08d4085ab3aa, 0x000060432732650d }}, + {{ 0x0009efab06795cba, 0x0000f4a10358560e, 0x0001b46c7da3c8a3, 0x0006b31152d8a507, 0x0000637882aff5d3 }, { 0x00020630df6bfbd5, 0x00072a9d19e9b915, 0x0004b06fe46d6faf, 0x00003090d8cfed74, 0x0000ce2f38fbcec1 }}, + {{ 0x0004f8e4921219b0, 0x000ef7ce382360f1, 0x000973c673c5135b, 0x0003f246cb6db05c, 0x00000c2638a18b5a }, { 0x000d76ff4b38f5e9, 0x000897a11c203407, 0x000f3205cc6b7d94, 0x000eab1200386f86, 0x000080180ab081c5 }}, + {{ 0x00082444682aa7c3, 0x00028e7db15be7ac, 0x0004107abe9a7d16, 0x00071706467a0805, 0x000025b9428d4196 }, { 0x0007714718a7a5d9, 0x000b58b20d841b88, 0x000854475e368b17, 0x0000c2936127a054, 0x000012a411de8dbc }}, + {{ 0x000cc20bdfcef420, 0x000aaaaaa8a5288b, 0x0009f26195e97eb7, 0x0002dee0c91cc0c8, 0x00002946f9408a70 }, { 0x0007409503d2975e, 0x000e4daa20ede1b5, 0x000c1d5f70119b97, 0x000b42e4bc441f00, 0x0000a83a9d6eb2a0 }}, + {{ 0x0005f1068db22608, 0x0004a61e4585d453, 0x000d3143dfb4ed4d, 0x0004ae66c9231fae, 0x00004c8d8da2e90c }, { 0x00009002a8263ee7, 0x0001200a2d261155, 0x00029e7afc3b45b0, 0x000e539a1649406f, 0x00005414f28a6295 }}, + {{ 0x00027abb0cc2f99c, 0x0009aa53ff3571bf, 0x000790fe6cb4f16e, 0x0003a2b1624f98b7, 0x0000a232d3065d82 }, { 0x00072b0da96f4899, 0x000cbfc5c6d5bfd7, 0x000179a26cce6886, 0x000505c346915c75, 0x000008d2131b6918 }}, + {{ 0x00071a4c560e39dd, 0x000490c2e03fa69a, 0x000994c7571e040a, 0x000ccdc6036cf0e3, 0x00004bd59ba6dde0 }, { 0x0005e78c885a065c, 0x000b65133c673db2, 0x00004e0134a9208d, 0x000f06b34c0bea51, 0x00008995c776117a }}, + {{ 0x000d702cfbe0903e, 0x0006ef88e2f7d902, 0x00074a4e05d17b88, 0x0005b20e9fdbf33d, 0x000010bd286ddbf2 }, { 0x000dd0fd8fb34fd8, 0x00013db85c88ce89, 0x000b8030d8880391, 0x000235bac23a3ce3, 0x0000fa45c03bfea3 }}, + {{ 0x00047e2ad1ea2431, 0x0001602b57872b88, 0x000ee0ff350f3dd3, 0x000ab0c402ef26b4, 0x00004bfae875386d }, { 0x000c3fc966771b4f, 0x0008aa009996a74c, 0x000c5de647f65d59, 0x00053fe4316a56ac, 0x00001cad819b5d5a }}, + {{ 0x000c2f5e8ebb9875, 0x0006573ce07d1b0c, 0x00018c7de2e97cd3, 0x0008da2f4d82910c, 0x0000fe01b8994111 }, { 0x00085928bcf47e0c, 0x0001950b8c30ccc0, 0x000a12352e9d8df2, 0x0002d88597b856ae, 0x00004ba7a71332bd }}, + {{ 0x0001d44d0c939385, 0x0007decba8f4b4d6, 0x00099ee0887ec970, 0x0008ef97ac07cd4b, 0x00007b8f4d37c895 }, { 0x000aa760774d89e6, 0x000f62b135e6f4d6, 0x000b7cecb07896fc, 0x00076a2b5680962e, 0x0000fd88fe58cca3 }}, + {{ 0x0008eb579c89ba85, 0x000b8118fb98871c, 0x0002f2dc1362f68b, 0x00025b114cb26f5c, 0x00008a957abc4172 }, { 0x000dfba9354cbe2e, 0x0001e15c93bae41a, 0x000c8cf0fa7d7f42, 0x000606cb146fbae5, 0x0000f605d4ba99c2 }}, + {{ 0x000697b7814fba90, 0x0004013f216c980b, 0x0008410654403924, 0x000dd1237c8ac4fb, 0x0000683bbe6245ab }, { 0x00033aad090c72fd, 0x000c939ddb945b56, 0x00077d5a16a024cf, 0x000b36f90447b06c, 0x00004f7703863965 }}, + {{ 0x000d40e0825f1a07, 0x0008c6bb57c64779, 0x00044c0cdc444452, 0x000779f7b871f8b6, 0x000076eaaa21e046 }, { 0x00087b30ac366f12, 0x000d8f6f2d84b5af, 0x0008acea8597faa2, 0x00014068b228993f, 0x0000424abfd6e5f6 }}, + {{ 0x000ba6b8ef40499b, 0x000f0317642bca8e, 0x000e66d95628781b, 0x00075f9451a032d7, 0x00004159c0acf639 }, { 0x000ec80051301541, 0x0005badd44856928, 0x000dfabee96d2c76, 0x000f8734884bda40, 0x0000d972ba5752fe }}, + {{ 0x000be6868dc83e03, 0x0005e0798fa7aaac, 0x0004248d23c0ea74, 0x00098ae9b41209ee, 0x00003cedae7fcc2a }, { 0x0000a5ccc7b9ebec, 0x0005fdc32c04dd3e, 0x000def4916cf5e80, 0x0009ad4cfa6c35fa, 0x0000a98de7d24b36 }}, + {{ 0x000b2d7405bd794a, 0x0002eaa1536189f8, 0x000f2f40816c05a9, 0x0001b0c0e1126c55, 0x0000e641bd7bfcf4 }, { 0x0001863ad3cc6a83, 0x000109e3738be712, 0x0009f8c75cd5b817, 0x000f12615b5090b1, 0x00007dbc50add023 }}, + {{ 0x0003c1abe2e2289b, 0x0008b79a7aae5d37, 0x000c9a2415e1f025, 0x000dd1b297076013, 0x00009d9bb7e7d7d8 }, { 0x00022100092b6697, 0x0001d22f2488af76, 0x0002041aa56cc46e, 0x0003ffd57e4105d0, 0x00004447fba18228 }}, + {{ 0x0000d8ea16b68aca, 0x0008a7877a50ec69, 0x0006795ebd16449a, 0x00056c47abf0392f, 0x0000c5c659818595 }, { 0x00060dbb7c6ed91f, 0x0008393ef953f575, 0x000567b78ade06a9, 0x00077e81790a64d0, 0x00009be345281b73 }}, + {{ 0x000d3b3730c3da90, 0x000a2864b66abfb6, 0x0004ebc7d1cf59b3, 0x000aa041ad26f52e, 0x00008875834f1291 }, { 0x0008f625c182ae12, 0x000942f4789dba54, 0x000529bfa3f61d44, 0x000e1880e91fcb81, 0x0000772dfeb7bbe9 }}, + {{ 0x0006ee1cad7e490c, 0x000dc011c6219b80, 0x000921be12763c71, 0x00098f988e7a562d, 0x0000ff590f7684a8 }, { 0x0009c6ab4f30f5e0, 0x000ce43faff79f72, 0x00023b683e91a933, 0x000696bd0c141a41, 0x0000472541b41fe8 }}, + {{ 0x0009a4a020384d2c, 0x000e87730448112c, 0x00011afee636432e, 0x000e4241082b51af, 0x0000f39a9a8e69f6 }, { 0x000d49d0784959b5, 0x000e0d8257e5818e, 0x000fc707ca9eace4, 0x0004f5bbfdd8efa0, 0x00002149995867c4 }}, + {{ 0x0002daa6890484d1, 0x000db5eb7caee1e4, 0x000d651a33cea7b5, 0x000e198b91033898, 0x00002903be868557 }, { 0x000107f8ce029e4d, 0x000745c1a1d885a8, 0x000073af6f495ffe, 0x000f1422825572ec, 0x00005e04a9386799 }}, + {{ 0x000fd321053b8bde, 0x00015a36fa6110cc, 0x00012bc0351a15e4, 0x000cb742b74fb1eb, 0x0000cad7c54d4248 }, { 0x000d56251a7ec868, 0x0001ca2cc80ad571, 0x00056953911caea0, 0x0002c80cd7c27fc3, 0x00000a95d3fdd32f }}, + {{ 0x0002503375e361ed, 0x000e509c955bef4d, 0x0001345d7cd1281e, 0x0006562eedf02cad, 0x0000ba01e9851b7b }, { 0x000be946c753683b, 0x0003a5edf53cb366, 0x0001c77f0e544309, 0x00037eaa454dcb61, 0x00000c4e558ee575 }}, + {{ 0x000541c7c1655fac, 0x0009ad1a995e0941, 0x0006cfdc3d170c39, 0x000be851365e848f, 0x0000c5364d173f04 }, { 0x0000fc20ed612d22, 0x000a7faf4acfade6, 0x0006e3d0ea83ec7d, 0x00024ab770e58589, 0x00005a5480d97ba9 }}, + {{ 0x000018f5e5fc5e81, 0x00083eca42768678, 0x000bb4da53ad5c55, 0x000d864bd46f6c3c, 0x00002cc3c22b21c9 }, { 0x0005acc0361b36ae, 0x0007470e47b668f5, 0x000d986831cd85e9, 0x000c8ed4dcef48cc, 0x000012e983797847 }}, + {{ 0x000dbf24eccee72c, 0x000e6af64db44442, 0x0004910eaf9370ff, 0x000496b8a19e9d63, 0x00002081b3c75ada }, { 0x00086167eacf78d7, 0x0000c8c2cd706b27, 0x000abd2eafce6c92, 0x000681eae5b012a5, 0x00008d905b32a1a3 }}, + {{ 0x0009ad7d324559d4, 0x000b57d594881dc3, 0x0008960aa38fa09f, 0x000f644de6b5efad, 0x000000bdc3e7618f }, { 0x000a309b4ea8cce9, 0x00039e02cfc0e816, 0x00018ca8025c0c84, 0x000981109117c466, 0x00002b74c94f9322 }}, + {{ 0x000b6614f982ece8, 0x000b7b7abea49b1e, 0x000c257cb1cc77aa, 0x000c2f67ab4b1d27, 0x00005154e895caa0 }, { 0x000ea5d68b9993ba, 0x000c76b7f6f7459c, 0x000e3a9037efb0c9, 0x00075d74ce431a44, 0x000063571583a729 }}, + {{ 0x000102c8a0fb0bfe, 0x000f8653a0a3f957, 0x00060be8d9da3b5c, 0x0006691e98936941, 0x00000313a1550ce9 }, { 0x00067e106b240330, 0x000010e235d21c8d, 0x0000e87d6f10977d, 0x000925a67505e55d, 0x000059ee2e27a5ee }}, + {{ 0x0003858b5c81bd3f, 0x000d2a9431dd80e8, 0x0009efaae17d3682, 0x000f67830eb7c7cc, 0x00002f1f3290cd4f }, { 0x000990a639034a2c, 0x000a593b6251d5c7, 0x000299c23319bc02, 0x000b194511cca1fd, 0x00006f501add6b8d }}, + }, + { + /* digit=12 (1,2,..,64)*(2^{84})*G */ + {{ 0x0006beb87707b7a2, 0x000c72a87dec0e16, 0x000d90f4e489ddf2, 0x00017feb5010ded8, 0x00009f1c146a514d }, { 0x0002ae989277487f, 0x00076313476cd0e8, 0x00052ddea0b6d98f, 0x000ff20c6a63d0e6, 0x0000d40ea3d516db }}, + {{ 0x00019c667d0d91d1, 0x000e8105ca7d8669, 0x0001a93ed4b79dc6, 0x00058efbc582967e, 0x00007205a3aecabf }, { 0x000187f1f85aef05, 0x00012b160f5dcd7b, 0x000f2c42bbc43ffd, 0x0004562f5ec697b9, 0x000026b5000648eb }}, + {{ 0x0000d41a77c52336, 0x000441d214aeb181, 0x000c6340187fcbdb, 0x0006e6ac41506af3, 0x00003b6fa4818220 }, { 0x0006bdb65cf1fb29, 0x0003ce4a84bde96b, 0x00083b4cb3bfaea2, 0x0008473e742f060d, 0x0000fba067aea100 }}, + {{ 0x000b6c2d46254ea3, 0x00039b6ec7fae9f1, 0x0004d44a4114c60f, 0x000f5ba52995f271, 0x000066e8cbd34843 }, { 0x00062c42a011d210, 0x0000c318129d7161, 0x0000f32c7f0a2090, 0x000229f63b03909f, 0x00009687ec5c5909 }}, + {{ 0x000507db0a04df74, 0x000af43753b9371c, 0x00099a17c1cd2a88, 0x00066679629cab45, 0x0000a296edbca1ad }, { 0x000519b397e39c16, 0x000e052af036c326, 0x00079fe7dac46a92, 0x000efcd5086f0cc7, 0x0000bf3f8cd63cc7 }}, + {{ 0x00042e43a80c6fad, 0x000b1ef9c053df72, 0x00078ed2a6c7dc5b, 0x000da22fb8de25b3, 0x000063c34563eabb }, { 0x00066648e3f185ac, 0x000a5f4dd6f958ec, 0x000f2dde11a9f374, 0x00087dd496925a77, 0x00007412068d6cf7 }}, + {{ 0x00005e399e662c0f, 0x0000a57173e460c5, 0x0004e0120bf24c7f, 0x000f062621bbbce7, 0x0000fbd676e31f74 }, { 0x000bef99ec94a32a, 0x00023cb57797ab7b, 0x0009ae3d0efbd3a0, 0x000900cc160ad35b, 0x00000124b141f449 }}, + {{ 0x0007c8bdf49d7f19, 0x0007df31711ebec8, 0x000f46d03fcfcebc, 0x00035281f2da40f1, 0x0000aacf4dcfdeba }, { 0x0004907c5d800621, 0x00068e3c2eef12d5, 0x000ae7e3f5965a34, 0x0000ca494de95bb9, 0x0000c88b84c6fe58 }}, + {{ 0x0000c1e7da0cf5f8, 0x000cdf08db60e357, 0x000689c14b3f9c46, 0x000208bc9743e3cd, 0x00005819e16c67eb }, { 0x000b4a07ea1a52ab, 0x0009f39a6be09070, 0x00057b86afe8f489, 0x000d94f6036d4703, 0x0000fe9b7f7d190c }}, + {{ 0x0003057bc03a43d5, 0x000782945c1dd539, 0x000790186ff52f5a, 0x0003b2be0cadc589, 0x0000ce868856076d }, { 0x0009d9be5f0800fd, 0x00081cd027a4cd18, 0x00033c3a42bb278a, 0x000667f68114734b, 0x0000ae65c75c585f }}, + {{ 0x000361bc67e9e34d, 0x0007e2e089808ef0, 0x000dd23c849fe842, 0x0002e6cc9f1f7a27, 0x0000c13a3157f998 }, { 0x0001b02bc1e235bd, 0x000a00b7f071426a, 0x00004556f9a54850, 0x000360dbd6a3c181, 0x00007d7ec15b5c2b }}, + {{ 0x000f7d41e8e79665, 0x000895931fba2393, 0x000359404fe8f948, 0x00083d71df47424d, 0x000023b7a1aa0b1f }, { 0x000ef6eea564a053, 0x000d0c2cf6eb9980, 0x000f51a339da0be5, 0x00028b46286bb49a, 0x0000f0e9d516a3ff }}, + {{ 0x000b44589e394e0d, 0x000207236f5defe7, 0x000bdbb538d8261f, 0x0003ed3c7fa9922d, 0x0000fc2a961330be }, { 0x0009acb43064282b, 0x00010ca9ea837700, 0x000f210a61177cf3, 0x000f5b1c0d7fa2c7, 0x00003784b94dc9c5 }}, + {{ 0x000028746afacb37, 0x000132e649d4e574, 0x000fd8eede035012, 0x000e913c4cd53a2a, 0x0000887fc8e5c525 }, { 0x000c3ac1b0c48f95, 0x000ee9064291d4c7, 0x0001722017588ca1, 0x00088c181bf48f15, 0x0000f3153a52a8b6 }}, + {{ 0x0008e6567629384f, 0x0002ec3c093c171c, 0x00035c0dd4ef3c20, 0x0002147cbae7acb2, 0x000090ba8583656c }, { 0x0009e2f0802b74dd, 0x00042ba28b8d0b1c, 0x0006ecde1a103afc, 0x000ae4d8015d7413, 0x0000a3d25fc46b0e }}, + {{ 0x000cadd1a806623b, 0x000e2b6f79588c00, 0x0009a8a99724a1aa, 0x000f2088afa52fc6, 0x0000f705025b0678 }, { 0x0009b5b7e0f923c4, 0x000e2b31803dd6fc, 0x00048c34f654baea, 0x0000a8a16488e4fa, 0x000078ce7289743f }}, + {{ 0x000bf0e7f5c451a2, 0x00030d3957626499, 0x00072bbdbc00a6ca, 0x000755696a9604ee, 0x0000c65ea7b931a9 }, { 0x00082e474cddae64, 0x00064217cb44b924, 0x0003667b7a354fe4, 0x000a641fda2f5ce6, 0x0000f36622cc64b3 }}, + {{ 0x000c9dd0ef759995, 0x000ddd0b611c24be, 0x0004740b22624bff, 0x00035cf211d468e6, 0x0000807471447a06 }, { 0x0007b4f8f0064eff, 0x000d3bf956c2e32a, 0x00043529005e550a, 0x0009f776573dc686, 0x0000b45bf82931b6 }}, + {{ 0x000d2dba29a420a1, 0x00077dd7280f8553, 0x00004e810c5f5788, 0x0001f6e42bbaac26, 0x00000e0aa6d6e58f }, { 0x000163cfe5ae3f65, 0x000b594985093755, 0x000f7d4053e708b7, 0x000c881fb8f33031, 0x0000315d7722ea99 }}, + {{ 0x00023d24bafda93d, 0x0005217cf41c6e88, 0x0009813e6da10623, 0x00029057cf1f03c2, 0x00009f3f08321169 }, { 0x000891e4e39dfe78, 0x0001813901f0b4f7, 0x00018002374a94f1, 0x00029912e684360f, 0x0000123427926e8e }}, + {{ 0x0007ced2848ab4fb, 0x0004819ac445e3d2, 0x000766d870fcc671, 0x00034ca0a553432e, 0x00004c49d4d2e4dd }, { 0x000df18da1030901, 0x000d2757a4afa571, 0x0003c69333af3c8d, 0x000b49823de0a14c, 0x0000c31b61984a35 }}, + {{ 0x00069041a0c93e91, 0x000fe82d8d38a9b9, 0x0000514dd1f04e0f, 0x00082e4dd2e97c60, 0x0000d5f81ee7afd8 }, { 0x000a8b342d40d5ba, 0x000993b76a2086b3, 0x000b9d37b4d18b27, 0x000c84167d6bba71, 0x000006b92014b8c8 }}, + {{ 0x000a7dbf4441e65d, 0x0001949522f9be32, 0x000bb4a18a63f9da, 0x0006e8f42690c075, 0x00000b984a4ca3f6 }, { 0x0000aca623b9e392, 0x0006a0e3faf40783, 0x000eae64e0090621, 0x000be25b3b2f02e9, 0x0000a47a4149ebe6 }}, + {{ 0x000e79d046d6c0d9, 0x000e60502f40d9ab, 0x00076db7ba07217b, 0x000db4d744681c46, 0x000074b09e5ed137 }, { 0x0005cee5b6dd4217, 0x000310a78bd01e0c, 0x0003acd63802d1dc, 0x0006da3b66dd359e, 0x00004f7a41696b06 }}, + {{ 0x000a2e4e3632e762, 0x000ced46ffd9fbbc, 0x00086c97c281ada3, 0x000fb00cf6e5bc69, 0x0000f75bfce3bc69 }, { 0x00075117090a5ff5, 0x0006fc016de36c5e, 0x000c5b91a11ff6bd, 0x00025b5f8e0b10fd, 0x00009f9ba307785c }}, + {{ 0x000ff3974d378756, 0x00082fc3b922bf8a, 0x000f9c3619e62f97, 0x000e743c4e4d8c09, 0x0000070f7ed0ec03 }, { 0x0002c29a21b92463, 0x00031052c18df9b0, 0x00038e3dd7174a50, 0x00055a895c5c3a29, 0x00008d20d8ec2e2a }}, + {{ 0x000b0838226e8425, 0x000ccd6141ecf611, 0x000e20a9f7315526, 0x00050ee579195509, 0x0000827cd560e1b4 }, { 0x000ee0b7e6ba0f71, 0x000fd35e07289f09, 0x000bcef7b719136d, 0x000002bfa1f94c48, 0x000063e3e9d89c31 }}, + {{ 0x000fbe8ff0b58802, 0x000fc2e34d74e31b, 0x000f7c390ac5a4ca, 0x00076e98fa352c30, 0x0000f58dc8de69f6 }, { 0x0001022c67c9035b, 0x000c1e6a79046089, 0x000a33fa75e20d04, 0x000e287001f812f3, 0x00004fd325eb32f0 }}, + {{ 0x000f7a6bb4ac623e, 0x0005e5d30a713a1e, 0x000f9574a3df3bdb, 0x00099bb284876e3e, 0x000058865f427515 }, { 0x00067d2e36052baa, 0x000c828dfa2a659d, 0x000801fa7659b2da, 0x00031653fd5cd339, 0x000060ed537958fd }}, + {{ 0x0004a96feb09a9c1, 0x00026d7cc5f43941, 0x000c308d71570ea4, 0x000a0e50ab5551b5, 0x0000c0238a0327c9 }, { 0x0009f80382b52a70, 0x0007f740d12bb0b3, 0x000026c163fb98f7, 0x000cd031dc522f02, 0x0000b4064550e478 }}, + {{ 0x000c58e2b0841de2, 0x000810c39024a940, 0x00088ad8b1a25b9a, 0x00085a47caacb96a, 0x00007b4e4f38b169 }, { 0x0008ab30080ea35c, 0x00001634da919fac, 0x000a28b2f2812eb1, 0x000e84f10ef79b69, 0x00003e9ab4693571 }}, + {{ 0x000c047df2f3ac76, 0x000c2b67c4a658ad, 0x000864e2a38fcd7a, 0x000ec6e4fb3c4763, 0x000051531fb65393 }, { 0x0005e4fd59db390b, 0x000c9c55e59d92d3, 0x0005b30150334900, 0x000919016cedca47, 0x0000584c78dab3ac }}, + {{ 0x0006a76dd7489981, 0x0007e18e4bcf6b1a, 0x000482a8ab23b028, 0x000ca4849856d628, 0x0000dfe5317984e9 }, { 0x0000d6fb0302b210, 0x0001334cc7b4f79f, 0x0001159b13471521, 0x00027aed5a1d0312, 0x0000d3bf917b1a7f }}, + {{ 0x000739327907285e, 0x000bcd51fb747d2c, 0x000868fa43b278a8, 0x000c7515aab50f95, 0x0000376a6d9ca2f4 }, { 0x00038542d43e54fa, 0x000a8440df6f9be3, 0x000b3e6a8f41a44a, 0x000e875d99092757, 0x00005ff9309a3d10 }}, + {{ 0x0008059420aa911f, 0x000200838961a0f4, 0x000e5063f3a99a11, 0x000f51dc61426ead, 0x0000999972790d9f }, { 0x000bd6e76938fb53, 0x000e7d87396e1dea, 0x00078ceec367f734, 0x00093fd665c8bdc4, 0x000025cb654cb623 }}, + {{ 0x0008dd4397eab620, 0x00020bb23330a011, 0x0004aa716c087df4, 0x0002a0c21d23f5ee, 0x00009e0d97bf7d73 }, { 0x0006bba1a6ca60ae, 0x000e59a122d7b44f, 0x0009ac7ccf2f7140, 0x000ef35f8e6d3b40, 0x00006562071bc951 }}, + {{ 0x000eb4a728dfb0d1, 0x000ece5cfc0aee0c, 0x0005f1d7a9946ac7, 0x000b2f8b2847edc4, 0x0000f3cb9e6d73cd }, { 0x000fd7e0f19cebb2, 0x000320e26da033d0, 0x000cf4084592072e, 0x000e145256cc3889, 0x0000f9a9e6566860 }}, + {{ 0x000e87665c992681, 0x000f23b1f0df9d48, 0x0003142e7e966892, 0x00009ced48cc2c5f, 0x0000034da4569da1 }, { 0x0009723443b0241c, 0x0000decd73dc965f, 0x0004451def97585b, 0x000aa0cb415ace45, 0x00008cda22cac57b }}, + {{ 0x00036cf77e985285, 0x000e12eb72d9f264, 0x000ead77798b269b, 0x000e004d0b19396d, 0x0000b0da9787f548 }, { 0x000ed049715c4ef1, 0x00042b3e990ef77c, 0x000c4c41b2b3b279, 0x0007441ce7373e3e, 0x0000c74b8d8215b3 }}, + {{ 0x00087b9090eee8d9, 0x0001e857e977ca05, 0x000a8761cc9b0977, 0x000721b61b66ee8d, 0x00000d8c50c1bfa1 }, { 0x000f5f64b5366b2f, 0x0005b1b32ba0127e, 0x000624b6b0f733ae, 0x00003c3f2a7720e0, 0x0000f1e94afee463 }}, + {{ 0x0007d52107341dcf, 0x000da6292b8c5599, 0x000fd19ee9087108, 0x0009ff1a50c14aab, 0x0000faa98a57dc72 }, { 0x00064ed85eec4469, 0x00054303e7c253b2, 0x000a21af1562e2d2, 0x000f6422ecc834b1, 0x00005e395857864a }}, + {{ 0x0003b3e080e596b9, 0x00020c066d41870b, 0x000093d3d98894b0, 0x0003d8d35a50c20b, 0x00005c4a4156d0fe }, { 0x0006900c54967769, 0x0007c58a179e9d94, 0x00092e175b2d285a, 0x000c91d4f2daa3f7, 0x000009935a179da3 }}, + {{ 0x000e2ddd1a219abc, 0x0005b1ef76765d05, 0x0002379a97e897c4, 0x000e1ddbd4ad726d, 0x0000c1f23448c02b }, { 0x000809d5edd717e7, 0x00030fca93e6dea4, 0x000b4b6d3b35eb09, 0x000f0bca2e8a2583, 0x0000004d3d719c22 }}, + {{ 0x00066b19648d9dd3, 0x00077a3da7a095ed, 0x0000508a9178ada3, 0x0004ae54a9049acf, 0x000017300723e8de }, { 0x0006ccb81ee1f40b, 0x000b7a0de6e95555, 0x00085ef0cf517a36, 0x000de7e21cf52d09, 0x00008ba0c8b2872d }}, + {{ 0x00094348a4e6b6a4, 0x000e6b89f4ccbb8c, 0x000211dece842856, 0x000082d0ced5f44d, 0x00002f608774e31a }, { 0x000c51779a9eec3d, 0x000acc429ef8479b, 0x0002a4faf1a4db07, 0x00027fd144c13a4e, 0x00005e156474bbef }}, + {{ 0x0000f4728b20513d, 0x0003c922774856f7, 0x0004fb2782d3e590, 0x000a061166e52fb0, 0x0000b15e370c9ac4 }, { 0x0005ee9fb249de3d, 0x000dbd1b2947f224, 0x0005e22ed0071342, 0x00012adbdc827ea1, 0x0000818801cfdb43 }}, + {{ 0x000537c1f02c6851, 0x000b321bb937d636, 0x0005671375b66207, 0x000852a68df8ff2d, 0x0000496bf164c230 }, { 0x00045b0e55c95c63, 0x00007263b37f8e84, 0x000b9a90b8785c72, 0x000cc742c170e9a9, 0x0000126204cdfcbd }}, + {{ 0x0000d9a50b845667, 0x000a70683a7337bd, 0x00042f134d3dc726, 0x0004c501f1e3416d, 0x000077d800d0f3e2 }, { 0x0002ade2f283b9d7, 0x000aa506fe28ef7e, 0x00054084698d5e5f, 0x000e17b633cc5ef1, 0x000066c31b2862f2 }}, + {{ 0x000e6fbcea358249, 0x000d7fa458d36710, 0x000c1f54c790f34a, 0x00096f8e31549722, 0x0000b594e2aa6b23 }, { 0x0007b2736a31e704, 0x0001a6b3bef0262d, 0x000bb7a26d997c33, 0x000d94eecfa8c472, 0x000052cf6e513e40 }}, + {{ 0x00075c9c88b57072, 0x0006ff1716843491, 0x000e1b84ff0e5ecf, 0x0002798ff36b4722, 0x0000fd7a19679edb }, { 0x000cf60d2f9f4605, 0x00056226e6bfdb1f, 0x0001c1e53e170898, 0x0000469445ea5b7b, 0x00001577a6f96234 }}, + {{ 0x000ca2e2a9f36d95, 0x000a42d677819e1a, 0x000dfdb7473e6ddc, 0x0005aca3f7be74c7, 0x0000e0f21bb12470 }, { 0x000f16207d6ca7e8, 0x0001b88122a6fe3d, 0x0002a913e42b12c8, 0x000d30557db69f70, 0x0000ec28095ae062 }}, + {{ 0x000023dda39ee7d8, 0x00071ab63ed9998a, 0x0004075a01f290e2, 0x0004c6872a3125c4, 0x0000f904a184e285 }, { 0x0002370cab7cf923, 0x0001efc0c743032b, 0x0000ac0c798dc522, 0x00042f8074f2120c, 0x0000c5c63ec4a64b }}, + {{ 0x000b922caee9c36d, 0x0006c626cc820fb6, 0x000c4cc8181044ef, 0x000a22bf059feee5, 0x0000001293501b71 }, { 0x000509216ce29c86, 0x000bfad106bed4e9, 0x00054a98c83f1cea, 0x000260e87546e71f, 0x00009ce0ef82db3c }}, + {{ 0x0009536e2465169d, 0x000936785c9a2dbc, 0x0001a294f24b62b3, 0x00035c81dd6ae515, 0x0000b9a59ef9c27c }, { 0x0000a8075f1088c7, 0x0006ea934521b032, 0x000c66df4fa0987c, 0x00065293cf39c526, 0x0000932812328d7a }}, + {{ 0x0005b9502ede5c00, 0x0009c62640264225, 0x000fcf00804813d3, 0x0009329508dd1077, 0x00003a1cef23fb5d }, { 0x0007fcafd4d1e2ef, 0x00025b486a098170, 0x000c3fbe909cd3bb, 0x000fd6a2fa39dd3a, 0x0000301ef9be9169 }}, + {{ 0x0000d74541238bb1, 0x000a1ee346eb2263, 0x0005bb58677672aa, 0x0008f2c267dfab08, 0x00008519f05e7745 }, { 0x000b740ffbc988fa, 0x000ed3ef2c2d065e, 0x000fe8badacd3c5f, 0x00097a322ff9b89f, 0x0000270de0bc09cd }}, + {{ 0x00021b2cceb112c7, 0x0003213a8aef5181, 0x000bedd9a2d4160d, 0x000a099487bfc74b, 0x0000bfb60e023e05 }, { 0x0007a59316c50a89, 0x0003f36a01eb3d34, 0x000a17d37464fae9, 0x000fa32cf50eb1c6, 0x00003421f128bfda }}, + {{ 0x000c2da0c5ea518b, 0x000897f931020167, 0x000418a384b07616, 0x0006ae09112c5f65, 0x00005b5dd45be1df }, { 0x000c2e94a72326bd, 0x00088b6d4a1dd5d1, 0x000674f41c95d1d6, 0x000cebd483e7ad9b, 0x0000363b24c971c3 }}, + {{ 0x000e5d95c2d82265, 0x0002a075a97d231b, 0x00068f25f195c1c4, 0x00064c2277c80de9, 0x0000d8d6a5c50d2d }, { 0x000e26d6207fa264, 0x000f8b19c2492eed, 0x000062269993127a, 0x0005724d342192dc, 0x0000a4ee006ab0b3 }}, + {{ 0x0005cdcbbff59de0, 0x000fcb6137c7408e, 0x000550d49b1acec8, 0x00020df1b9a38d7b, 0x0000a28ec5df468e }, { 0x000827dcdbc769cd, 0x0006a6df65965a08, 0x0002638c0c826940, 0x00084a22060fe88c, 0x00007b733efb859f }}, + {{ 0x00066d1dfef7b4aa, 0x000f3240c56c6904, 0x000d974a461ec7d5, 0x000b6bc2b40265da, 0x00009a037291c042 }, { 0x000effe346803700, 0x00069621484469b5, 0x0008a3dfac592a2a, 0x00081bf510db6054, 0x00002ee4b2e6bbbc }}, + {{ 0x000c3f2c5b8478f1, 0x0006164ff112c32f, 0x000c7f57f357647d, 0x000fc170d8a9c736, 0x0000f62d2b5914f6 }, { 0x000853ac70c175fe, 0x000797e5aeb49c20, 0x000dd1c7318d5bf6, 0x000bfb1fcf3db034, 0x00006e90923fe993 }}, + {{ 0x0008ef1d90bd82e4, 0x000f1948b2a29d5d, 0x000674f0f04a7a60, 0x000a94e8b28f1f45, 0x0000cb6517882536 }, { 0x000ed48d66270e5a, 0x000086041dc61bde, 0x000c3919a2246fed, 0x00086105df74e8a9, 0x000062b49a271a05 }}, + {{ 0x000fc8a61448916d, 0x000c74f3a29467a3, 0x0009855614595002, 0x0005455f2de81e94, 0x0000c7e3b2cd575d }, { 0x0001458e271cf38c, 0x0006c8f06d0de9fa, 0x00049a303fe35dec, 0x000c8fbd5bbc11cf, 0x0000091b6978a5de }}, + }, + { + /* digit=13 (1,2,..,64)*(2^{91})*G */ + {{ 0x00072002d0deafc1, 0x0007568e039c2560, 0x000b74f7fa8c3e04, 0x000fa452b5f26fb8, 0x0000d5c673e4de9a }, { 0x00094308345d1eb9, 0x000e937e84fb7e3e, 0x0000233f0b08ef7d, 0x0005f8881b401d8a, 0x0000861e80d65e10 }}, + {{ 0x00076ddafe513028, 0x000b231be24319a2, 0x000bb927cde9a7fd, 0x00047f98503f7d28, 0x0000bacef2354247 }, { 0x000e4d52a90363e2, 0x00072961d7a64eb7, 0x000900d06b997d69, 0x000d4f0d5e436088, 0x0000deb49837ce80 }}, + {{ 0x000bab8085f68f7e, 0x00057b11d59715df, 0x0001dbdd17b82354, 0x000627448c7eaa76, 0x000008e08b2e2ab5 }, { 0x0009f8090d0bada8, 0x000652153765b2f5, 0x0003a01a76305a37, 0x000cd7310bdd4e08, 0x0000e04ea95f672d }}, + {{ 0x000bb2d0d12e52d0, 0x0002d9d615faa8f2, 0x00006ad2841c4cc3, 0x0005178828fa1eb4, 0x0000037e5443ad4c }, { 0x00018eaef0ca0cd3, 0x00057646caa6d2f2, 0x000e0158862a3d51, 0x0004399628eb879d, 0x0000cd6553865dd0 }}, + {{ 0x000c0571a1474d7d, 0x000eb4744ddfa350, 0x0005ceae85a5f097, 0x0009beff49ccfc5c, 0x000030d609ea9dd7 }, { 0x00057759b5198b47, 0x0006cd54b3a7b3cd, 0x0008885661e41633, 0x000b6143a35c0366, 0x00004e96b4e32798 }}, + {{ 0x0000a94af9ea7cde, 0x00069d83d30a2c5c, 0x000e36e136e23569, 0x0009d6c9b0857f77, 0x0000ee3ba9363a28 }, { 0x00091c4d690c1482, 0x000da0bdaa6ec1a9, 0x0002efb68a84b025, 0x0004cc597ba9fe49, 0x00009c2e3b6a4baf }}, + {{ 0x0001e48f047ae313, 0x0007928d2f01cb3a, 0x0003357921acd842, 0x00099fab493d6eaa, 0x0000971a98af096d }, { 0x0007186cef6f15a9, 0x00051f6c508b23ac, 0x00096ebcc85a8832, 0x000e40f38f137571, 0x0000e4475b94f38d }}, + {{ 0x000f0606c39967da, 0x0008ecee978a1d35, 0x00031bb32640de50, 0x0003dde62e3a68b3, 0x0000e08b646ad0ee }, { 0x0000f5f9d3887578, 0x00046276f9326f11, 0x0004b608425a9f9f, 0x00069fb512f521c1, 0x0000178ec5cbaa24 }}, + {{ 0x00015759ba88c80e, 0x000536b269fb37d5, 0x00042c8ed42b45c6, 0x000153353aaf7380, 0x000055e311c5bac7 }, { 0x00087e91e457b502, 0x000e9f8aa423a61a, 0x000124c369ae3354, 0x000978736592245a, 0x0000f1cbf0fedd43 }}, + {{ 0x00019c380abd55aa, 0x000a2e43d34a2e3f, 0x000dc29f25566282, 0x0003bdcc7ee3759c, 0x00006455153981a4 }, { 0x000fab2b4f7c81ad, 0x00074aade744b1f6, 0x000ff14cda1c443c, 0x000bd5111a7d222a, 0x0000a28194e30835 }}, + {{ 0x0004f489bbe9959d, 0x0004d5f4bf1d7255, 0x0001fa780b53c39e, 0x000e212069c1d8ee, 0x00009ce8effaceb9 }, { 0x0005945723762269, 0x0006d34992fb7e89, 0x000a0d0fec2418ef, 0x000dfa5000169a7a, 0x00002dfdd7e68c1e }}, + {{ 0x000876812dab14b9, 0x0007f78a4d32282f, 0x000c4f8b89ba0bce, 0x00094fe50e36e029, 0x00004692f67fcd8c }, { 0x000d3eea24df7225, 0x000ee8ed23a17f08, 0x00006374aae9a53a, 0x0006455e06d7b448, 0x00001b31dbe9cf50 }}, + {{ 0x00008ccbe2c9375c, 0x000c475b15d5acc9, 0x000f2cf48fe143cd, 0x0006c10f2c6d9c79, 0x000052c6758da616 }, { 0x0004e7f0deea926a, 0x000b8c4ba35afce8, 0x00007882ce2c78f4, 0x00030cbc15a3da8b, 0x00007993789e4ddf }}, + {{ 0x000a821ab5d22890, 0x0001522b99a72cb0, 0x00077cdf65604ed9, 0x000cad53e06de6e6, 0x000000279f3d1814 }, { 0x000490a31fb979cc, 0x000d92b7cb0b5a2b, 0x000c1473e470c4c5, 0x00054393aa7fb121, 0x0000cf1f5b79004d }}, + {{ 0x0005647406b4d83d, 0x000a77d62dd61ad3, 0x000c367b9f6b2ca3, 0x0000b8eba781a961, 0x0000c08fd788cd26 }, { 0x000f2bdb2ab6d0a3, 0x000f27b2736a129c, 0x00021de8172c3e3d, 0x0004959c5a631370, 0x0000e07bdbb63a83 }}, + {{ 0x0007d51e7e42a51e, 0x000f444c5f95cd80, 0x0000ecd677766dc5, 0x00040656dda8c8af, 0x00007a567e594477 }, { 0x0001a1b8848c495f, 0x000ff6ac2ccbcda6, 0x000f23870b5b7597, 0x000568bd43bc1923, 0x0000956dd9ebf318 }}, + {{ 0x000e676223b52ac3, 0x000ab08700230ef6, 0x00014eb24bd5447d, 0x0003015f20af585a, 0x00006fbd09543e40 }, { 0x000716998cd613d8, 0x0004d7c4e774d3fe, 0x0002c4f9938e4db7, 0x000fe92a582a3851, 0x0000708acb1bfba4 }}, + {{ 0x000ce0a3b86fb6ef, 0x000e671fb1675839, 0x0008348bebd1d282, 0x000eb8619dd011c7, 0x000021f9f273dcf9 }, { 0x000c00295b68f0cc, 0x000a689d5ec67385, 0x000a2c40c61023a6, 0x000546819a3b49f9, 0x0000308d7cb76e31 }}, + {{ 0x0004ada5e11c599f, 0x00075fb1d4bcc766, 0x0001e0ece31035ea, 0x000b3720fb07691d, 0x0000d42fa02b82da }, { 0x00097f2f7329b17d, 0x0007c4e5b544cf50, 0x0005f3a7e48b861f, 0x0005af7f4b4a13a1, 0x0000b8d9cdcafafb }}, + {{ 0x0008e1b8c2d74b0e, 0x00029d8affa8208d, 0x000b0347f239c200, 0x000ef527fc3c31b0, 0x0000983c109b8ea2 }, { 0x00039cab167742fb, 0x0001d15c8418682f, 0x000e8a2c7280fa2b, 0x000566e82541d487, 0x000043cc4696534f }}, + {{ 0x000f6985d44acee8, 0x00019a0e68db0554, 0x00086ac9b300b789, 0x0005c1284f356975, 0x0000a5ac2e22d6a3 }, { 0x000c9d95d6ef7c99, 0x0008615132ed17ab, 0x000403a5d02745a2, 0x000355766510ed0b, 0x0000b2d6d88461f6 }}, + {{ 0x000ddcc3fd82271c, 0x000b36e19abd09e2, 0x00012214bade2615, 0x00022eace0b4097c, 0x0000faacf01c7b54 }, { 0x000b860163208096, 0x000ba3d9e8153b8e, 0x00018bee1638b3c8, 0x000587c0c3324fd0, 0x00003de457dc65bb }}, + {{ 0x00039ed2562fdbc2, 0x000fbd1972f07f4b, 0x000e1edcea95283b, 0x0003623a6e5579e2, 0x00009e02c169c92f }, { 0x0006d17da40df3f7, 0x0006d17a2f62e55f, 0x000e24fe04fed313, 0x000f732f96b9ab38, 0x0000e962da3c756c }}, + {{ 0x00012c0401631864, 0x00079bd0f968c006, 0x000b9ee0840a483b, 0x000826e4da03da7e, 0x0000d17d0ff62307 }, { 0x000c74ec710cf280, 0x0008493109f5df10, 0x0000743a88df63de, 0x000c729b3fbda403, 0x0000893136d324b9 }}, + {{ 0x000c593df45e820c, 0x00049646edb951fb, 0x0007c2c9848e3595, 0x0000b05965f4a9d7, 0x00007059afd6a155 }, { 0x00047ed87de67e90, 0x000cbd46af3641a8, 0x000ab91c654ee10d, 0x00064a3047802200, 0x0000176fc6f6b4a5 }}, + {{ 0x0008923bbab39469, 0x0002e4e6d6711921, 0x000ac584ba5544c8, 0x0002f1e971e14100, 0x00005ee0cd3a9fe2 }, { 0x000af777f11421a3, 0x0004599bbe7e86e1, 0x000e0668efcedb0a, 0x000b42b3e4a1510e, 0x000081d2b6ac6370 }}, + {{ 0x000f3a93c5729e80, 0x00034004ef657241, 0x00091cd213392d1e, 0x00061a9943e04a4c, 0x0000714ea218efe2 }, { 0x000dbd736683a3d4, 0x0003afe3923555b8, 0x00089059de839c3c, 0x00012bf57744bedd, 0x0000f135993bf2e7 }}, + {{ 0x0002c8361b7a2aca, 0x0006699df1ea40e2, 0x000b350de8491faa, 0x00043ee12b3f24a0, 0x00002727eb357cdf }, { 0x00035a753655680b, 0x0001497f9c0d95c1, 0x00027ae958781188, 0x000c30ac38846117, 0x0000025367304961 }}, + {{ 0x0004c10cf8896213, 0x000ddf75f7ae2f68, 0x000d533960a9a46b, 0x000722eb615fc6e1, 0x0000ae866b88a248 }, { 0x0008a74fcafc168d, 0x000df95a73fbbd0f, 0x000a54e81f1dad9b, 0x0000f13437f24e0c, 0x0000c84c23966c22 }}, + {{ 0x00040a120307c01c, 0x0004985c9f842969, 0x000aa7b866ad1714, 0x0008fafd07fbaa8f, 0x0000621c9f76d164 }, { 0x00092f8868ee11e7, 0x000fa2055a4aec84, 0x000492a7ba874698, 0x0007a81ab550e9a7, 0x00002f1e26b56e34 }}, + {{ 0x000b6155609a0534, 0x000e1adb2d8f3984, 0x000c102373f2ce23, 0x000b3e3d6f13b51c, 0x0000421c4ce957c1 }, { 0x00020f448ada30a5, 0x000a9850a52c1c82, 0x0004fea81b397d5a, 0x000db0ec6eab1a69, 0x00001f18e2afb1cf }}, + {{ 0x000589fb928c5f43, 0x000ab31b0e63d348, 0x0002245b5418c388, 0x0008872a4f460057, 0x0000c3c71e7aa249 }, { 0x000bb0696dee0485, 0x00070cc6583553ae, 0x0009f6a5e077bc6c, 0x000ffc1520879094, 0x0000bccee4609921 }}, + {{ 0x000c457b0b8cd23b, 0x000e4deb9718710f, 0x0007f72f2ee9cd44, 0x0006782c138f1bed, 0x0000d9595242d62d }, { 0x00095c766178c8de, 0x000a1d4883841e20, 0x00092f15dd20214f, 0x0002f65958ec25b3, 0x0000f894c054a41e }}, + {{ 0x000a9fc894303e0f, 0x000b95c4bdc56104, 0x0003ccfeea6d613c, 0x0003aaeccb2885fe, 0x00002d45649bb35b }, { 0x0005fcc99d08171b, 0x000d5cd3ce299af5, 0x000357f6c183b368, 0x00076c08f195be9b, 0x0000561cacedeacb }}, + {{ 0x00098ba31d719d2c, 0x0002f4c721a4593f, 0x00047d0307a4b9cc, 0x000eccd14ed1e9a1, 0x00002d73755fff02 }, { 0x000ffb3c0ec394be, 0x00055739b128eb4e, 0x000de44d733bbc94, 0x000accfd37801214, 0x000050af6c641c91 }}, + {{ 0x0005f825c4f07a21, 0x000e67cc7bf3827e, 0x000a61fffdcaef2b, 0x000eab454f2165bc, 0x00005d08b9caa394 }, { 0x000659f053bb7164, 0x000eb67ffed4d6f5, 0x00085eb0445c885a, 0x000d096f1bc60957, 0x000009efc070a594 }}, + {{ 0x000c64a71a41fd04, 0x0007ec36044d63bf, 0x000810766586a678, 0x000b5b8f6a608940, 0x000015d2319af57d }, { 0x0002002ddd63570e, 0x000cc8083dbedba1, 0x000219e65019b26d, 0x000e6e1de804ae11, 0x0000b12ba3767b3e }}, + {{ 0x000d0a9304441d8a, 0x00024895dd21b96d, 0x000af239cf49a271, 0x000aaff7a8b99f28, 0x00007171f2ff03da }, { 0x0001f37bf44ca0c6, 0x000af224e233de42, 0x000109432cb14982, 0x00098cdd9192445b, 0x000083d6a7497fb5 }}, + {{ 0x000a5ab0888caa4f, 0x000f449f8bd2bbd7, 0x0008ce0d68d4a75f, 0x0005367f11d902cd, 0x0000a44f775a6959 }, { 0x000b840d135a5237, 0x0007406f7a09e03c, 0x0006666eb4106a14, 0x000c92f572f8a197, 0x00008f690387b3a9 }}, + {{ 0x0007753ef58b6176, 0x000379f7db326750, 0x0003002b30262a9f, 0x000bdea9478fea13, 0x00009fe0ef597427 }, { 0x000109beb4404306, 0x00054ed9c0bea786, 0x00095b35866fc305, 0x0003c6c6d41bb398, 0x0000d3e8797ead29 }}, + {{ 0x00025549467a0bf6, 0x0001bea3b6d1145a, 0x00090602dd0e0635, 0x000da6f62b6271ea, 0x0000e2394cc29faa }, { 0x000777d45fafe2fb, 0x0009d5e99bfe35f8, 0x000ff3d9f99729e1, 0x000a51d329770ccb, 0x000030a49d96b3e2 }}, + {{ 0x000b3786e5ed1d59, 0x0008122d847999db, 0x0006081ad64caea1, 0x0008c00a103aa33b, 0x0000197d6168ee3b }, { 0x000f6688f1378163, 0x00070ce6961f247b, 0x000e4392b44e7734, 0x000264b4f20aa85a, 0x00009914ec874ca0 }}, + {{ 0x000e24bf90175fbf, 0x0004f867469ceadb, 0x0003727b0ab89a54, 0x000f4fcc71904c52, 0x000031f4ae121f33 }, { 0x000f170db279ffb1, 0x0005690bd98764be, 0x0006b3571bec445e, 0x0009033c7a0f45f1, 0x000097d5d9760ff1 }}, + {{ 0x000ee1767e237834, 0x0002da029e0ccc17, 0x000de1cbc04beb15, 0x0009f0422cd53e87, 0x0000d2d72323a5a4 }, { 0x0003f6bc86ce1e10, 0x0002259648945af4, 0x000ce1d14415bbd3, 0x000439b8c9e45a5f, 0x00000c39573f5251 }}, + {{ 0x000f428fce95e48b, 0x0009848f2142e791, 0x0009a7a393bbf194, 0x0009f129b17d8925, 0x0000aaebd8ce27b4 }, { 0x000b5da0d65b712d, 0x00069010db06dfe5, 0x0000f54602f5c09f, 0x000bfc71bbfc16bc, 0x0000a4f9df66163f }}, + {{ 0x000e43c42cf85546, 0x000c44856ef96a74, 0x000849e83415f3c7, 0x000ea2a0db47eb84, 0x00000d10f03005f3 }, { 0x00020e52e37d20d6, 0x0005431d1a4aa2a8, 0x00083df6a0eb24b6, 0x000ddb47a440d466, 0x000048087cb057c8 }}, + {{ 0x00097c4c88758f6e, 0x000f1cf25e51b09f, 0x000e26a784d0b41c, 0x0005c8b0e180cd2b, 0x000009259c42e92c }, { 0x0008e2f4d6cd7faf, 0x0001824c03dbb7ea, 0x000458a9c70dd19e, 0x000e82253ae04376, 0x0000c21fa7e45f39 }}, + {{ 0x00099cfe2f0814de, 0x0007447d95ea1682, 0x0009ffd3781b0f15, 0x00082a3691758fad, 0x00004a8af81a2215 }, { 0x0002e22a81992dca, 0x0005417b0a98927c, 0x00005d1f1a13cbfc, 0x00047eb6a2e26e1d, 0x000016512c4f1dd8 }}, + {{ 0x0008cdcef72b2cef, 0x0000afbd90a060ab, 0x000b0225b18e21e3, 0x0004a7ccf496a27d, 0x000094a48f740aaf }, { 0x0002d4d14b785966, 0x000a937436a0bbaa, 0x0007d3b12efde960, 0x000dbdccf263fa10, 0x00008368434e4361 }}, + {{ 0x000e4e4a56705d8e, 0x0000f6812e9a1bcd, 0x000b811fe812283e, 0x0004f583861d9075, 0x000054c73bae5329 }, { 0x000eb36201e51c99, 0x0007b4ad673c0175, 0x000e10baa3e900c7, 0x000b52456667417a, 0x000012e79d4dacf7 }}, + {{ 0x00069ef68c67b87f, 0x00046043a1aa9145, 0x0009203d62e8c5c3, 0x0000f935c175a129, 0x000001fa1a6965d8 }, { 0x000d9e2a0a581188, 0x000536363a113b4a, 0x0005eae52d5c3801, 0x0002fa5eae3bd3f5, 0x000066503ca8481e }}, + {{ 0x0009192ffa7d59dd, 0x000bb4c508b65e9e, 0x000084d870d6c300, 0x00060a3dabde4a1d, 0x000027aed4e0a762 }, { 0x000479a99a505811, 0x00085965099fe925, 0x000bb6adfbb04f0c, 0x00038c96125ddb65, 0x0000b41360e14375 }}, + {{ 0x0004fb15b0510f55, 0x000f905013fe1620, 0x00025e32316b7fd8, 0x000feb39fbe11dc9, 0x0000d62b1f4b95aa }, { 0x000a88e26620cd37, 0x00028c213c999279, 0x000fa35a08cf8550, 0x0000d94b4a033e9d, 0x0000037e5cb1f698 }}, + {{ 0x0001d933d32c017b, 0x000346254671ff6c, 0x000a9dcc5230cb16, 0x00075f8c04bd4241, 0x0000bb7123eb38ba }, { 0x000c6641dc5f7a5b, 0x00051f3689e2c70c, 0x00067a54bb55957b, 0x000f99be592aab0e, 0x0000100ca18fcdd4 }}, + {{ 0x0002150673a6e180, 0x000f757d31e535ec, 0x0005c5ade79e2400, 0x000211ffa04cc43b, 0x00009f71ec100187 }, { 0x0005a52faef35750, 0x00071e08d68b0139, 0x000f584d694447ac, 0x00028f464a9d6816, 0x0000d379add57aaf }}, + {{ 0x0006293a2dec1ae3, 0x0003e600e1cb64eb, 0x0005c8568fd06998, 0x000961893004828f, 0x00004d492af4542f }, { 0x00028e52e6b40b4b, 0x000a421d145d2d9a, 0x00031901531d2a2a, 0x000c3da2dbe6225b, 0x0000a8127987847e }}, + {{ 0x0008303593dd6e66, 0x000629b4c371e6da, 0x00048ebed994bfaf, 0x000bac981cebe067, 0x000016931e8d75c6 }, { 0x000130cefca57500, 0x0005b0a7e37a9bb0, 0x000e2a5edfc6fbfc, 0x00054b1028c56f61, 0x0000ecf694a5348e }}, + {{ 0x000752496e016bd2, 0x000cda0bd865cfbc, 0x0007f50cd4695497, 0x00052a0244b03e57, 0x0000637b077b76b9 }, { 0x0005ae9668f90345, 0x000e83b564beb6b0, 0x000033f32f9fd853, 0x000f2bc260db1d11, 0x00009c49e1c7cb1d }}, + {{ 0x000633e728e450f7, 0x0007637c92544f2b, 0x0002ed2450ac358d, 0x0000057cecc08435, 0x00008ef9d3967336 }, { 0x0002ca7d5cb05be9, 0x000ed9f936c581cb, 0x000dc16f479d4101, 0x000e8a15b96e7b8c, 0x0000175bf8daeb7d }}, + {{ 0x0003f3086f736b1f, 0x0000641f50240258, 0x000960cfd0c861ef, 0x000f6f99f47bc576, 0x0000686ca9cfba8f }, { 0x000b7e65f9f1ce62, 0x0000b94b587579ab, 0x0007756906660826, 0x000329dcfec2d22d, 0x0000255e257067be }}, + {{ 0x0002c8ff8f6efa40, 0x00054776652a220f, 0x0008e3cdc9f20d82, 0x000f5bff361618f8, 0x0000f1cc52b08e1a }, { 0x00062b9b103f16d5, 0x0003ead8efb4d3e2, 0x000fa7ebd284ee8d, 0x00051001c937b5ad, 0x0000d93b71b723eb }}, + {{ 0x000588993b473591, 0x000bee4c43ff28b8, 0x0006e4ddb53f06fb, 0x0006fd4c27647662, 0x00006c003ddbd070 }, { 0x000832749a9bb5b3, 0x0004ed68f938829a, 0x000d96ab08b23bff, 0x0001781c7996627e, 0x0000272b5788c7f5 }}, + {{ 0x000ddbacedcf37d2, 0x000bf7d4bf503533, 0x000b178bb90d5ee0, 0x0009dd96685dd726, 0x0000ebe65a8ae8c4 }, { 0x000da2828c5f8f65, 0x00074a412f22e85f, 0x00066f647430480a, 0x0003ab137e2a2486, 0x00009656ded0c9e4 }}, + {{ 0x0005aaf668ac79d7, 0x000433ea2dee7a63, 0x000c3da02c1bc912, 0x00031cfaddcde2f3, 0x00001022732669a2 }, { 0x000b89dea0558e1e, 0x000e6a9e5aa049a6, 0x000d25865fe4287c, 0x00021cec3e74083a, 0x00001aa8b5c32deb }}, + }, + { + /* digit=14 (1,2,..,64)*(2^{98})*G */ + {{ 0x000be00843e7b7e6, 0x000b723fe67ba665, 0x000037ef26f02671, 0x0004513139145076, 0x00001e80333c65b0 }, { 0x00067e7cf2b69e56, 0x000e805d53ff04d3, 0x0003276aa2047eed, 0x000006ba0bf7ccdc, 0x00008a2d8826cd00 }}, + {{ 0x0009356a79debb8e, 0x00065b7b0dc85957, 0x000825e834b42de6, 0x00021f4a727de460, 0x0000c18079e2bfdc }, { 0x0003b0bfe5e20c23, 0x0000045f5f9a0529, 0x00087fe98313de54, 0x000411dfc1a8b0f8, 0x00004e039a515ca2 }}, + {{ 0x000607c8357f525c, 0x0008102c024789cf, 0x00094badb3c6d4e2, 0x000e13cdf90dca9e, 0x0000f013f32caca4 }, { 0x000259ced8a8fa9f, 0x0001f97c2c99b76f, 0x00062668c42a120d, 0x00009098c6576ba6, 0x0000ddf41abff43e }}, + {{ 0x0009d20f961c2e82, 0x000b85dc8de610b8, 0x000ade101437f35a, 0x0007eebc5e8c515f, 0x00002509d1321032 }, { 0x000842e3dac8ba0c, 0x000fd66098583ce0, 0x00048bafc3fcb163, 0x00076414aa2eedb9, 0x000007db9f48bc83 }}, + {{ 0x000c04346f8b4a53, 0x0001fa33b9e2d7b5, 0x0007687de490598f, 0x000ca4a917cc60b2, 0x00003bbf0d26c8f8 }, { 0x0008cace3b4eac97, 0x00066f2614650a98, 0x0007392b98719d3d, 0x0000e25835e35b53, 0x0000792a37dc963a }}, + {{ 0x000a9c2a39c1acbe, 0x000e5753de92e23f, 0x0007651f8ca95eef, 0x000048a7eccb03cc, 0x00005893c9a2ca16 }, { 0x000cba2866a3fc9d, 0x0009b236724ceedd, 0x00073c72dabcd16f, 0x00061668e3a90225, 0x0000f7789359b346 }}, + {{ 0x000a35b6a1ba7e68, 0x000bb7f788907328, 0x0008c9c6fe382aca, 0x000b618d6c443bef, 0x000027c8cd8a0530 }, { 0x00044a35a0bbe471, 0x000d61665e9a90a2, 0x000d40e5d11ff8ff, 0x000053d3b45bf380, 0x00001226d9bd6c94 }}, + {{ 0x000595c4b3f8dbd9, 0x000359d74cd06ff8, 0x000f270e29f8a825, 0x00087d12b9c17c7d, 0x0000b2e80e811f87 }, { 0x000db27ce43a86c1, 0x0003fca990f62ccd, 0x0002ec59bf016957, 0x0000628f5d9bed21, 0x000027d55a4ba6a5 }}, + {{ 0x00088b9aa14b8da6, 0x000a46658926ddd8, 0x000907f47b17a1a9, 0x00091d4b8138b2d4, 0x00001b4b6e70d892 }, { 0x000f508ea42a5543, 0x000c04e3a96e3551, 0x0008d3bf2ff6a996, 0x000cbf37aba65b0b, 0x000012115142acd4 }}, + {{ 0x000f55cded9f6e0e, 0x0000c49747c866c7, 0x000d85c2d274f8e8, 0x0006e2808bbb1e5f, 0x00001441178e9e4d }, { 0x0005bd1a0a03f0a8, 0x0004495f38c85f0f, 0x000e96069eb98983, 0x000220e6f5b589fd, 0x00000accc96b8e0b }}, + {{ 0x000a8761f7872bd9, 0x00061e55e915918c, 0x0008bc714273ddea, 0x000c0209c6158d6d, 0x0000e6410b2c4167 }, { 0x00091666024d7e90, 0x000b9c29ebbc601e, 0x0000f7ad482d61b5, 0x00067a752ef3b0f4, 0x0000530ed4817b10 }}, + {{ 0x000d03f718913dd5, 0x000c2befc15aa1ee, 0x0007c847102cc8f2, 0x0005c8a1240d1254, 0x0000fdffe724edc0 }, { 0x000f68ea1cc2db7d, 0x0003e6c4a02c4997, 0x000d509587b544b9, 0x0005f5faff725083, 0x00002c702007fc4c }}, + {{ 0x000b3261f5dfe89f, 0x00029c7b7ffd977f, 0x00048543b82d075f, 0x000575c83ec104c3, 0x0000ac684c28b97a }, { 0x0003997db2fbb677, 0x000d260d883e5448, 0x000009297105579d, 0x0001fe89913520d7, 0x00000d81132cc8d8 }}, + {{ 0x000236a324c0abe2, 0x0000f060dbd2c016, 0x000abd6646100dc4, 0x000ed57214f8eea6, 0x0000ebb2e4bb264d }, { 0x00004281091086cd, 0x0005284a16022e9a, 0x0007a38f5aa9551d, 0x000c6229c0c18d87, 0x00007ce409a2371c }}, + {{ 0x000ceb5971a6fc75, 0x0007c5e9afdfb3cb, 0x00029ef45d6dc1e8, 0x00085c89749a5614, 0x00009b93cd3762b8 }, { 0x0004b4099139dd59, 0x000ec5fb269bbc4a, 0x000e450853d0fc8d, 0x0003b57867cd85e1, 0x00004a5c6d138b15 }}, + {{ 0x000d112927153319, 0x0003f1d26ee83821, 0x0005188c3a678749, 0x000f5953dcf17dcc, 0x00006ee6a46384a1 }, { 0x000b8bdb94fd5a59, 0x0002b7750491a746, 0x00019255042413ef, 0x00049dcab687fa76, 0x0000d3bdf3fd8d81 }}, + {{ 0x000d8811182f36a0, 0x000bdc93bf834aa0, 0x000941e46d331d24, 0x000001cad0437181, 0x0000a5e4336ef208 }, { 0x000560a8b653f914, 0x000fb82f48c8e33c, 0x0004dc5e9825a5d5, 0x0002e1fe5a11fd07, 0x00008d6b831c2888 }}, + {{ 0x000054303f46b6d4, 0x0004be23929d0979, 0x0000029d58b20226, 0x000b8f9ac3885b29, 0x0000aac58d89d493 }, { 0x000f3d6452261dfd, 0x00021440738042ae, 0x0006ce71fff79069, 0x000abe21b98e6a97, 0x00004b0f9c9efeab }}, + {{ 0x00018d761d16f241, 0x0006d82b6d72d285, 0x0001a44aca62ed09, 0x0009cbb1c77ca9db, 0x0000674f75f7e28e }, { 0x000e54ba56fa1c83, 0x000f10ef0d1b5ce8, 0x000c5b965d2e6f98, 0x000d8b082717039c, 0x0000b2abaa683928 }}, + {{ 0x00073eb5de6f16ea, 0x000838af7f91d0f2, 0x000180eba14a2d69, 0x000c07d543b61b0f, 0x0000a48e18374f25 }, { 0x0002413c252f7b56, 0x00055f77b4e4d538, 0x000f5bfedb51fa0d, 0x000d51bb3b7ce66b, 0x0000bd4cf4850d41 }}, + {{ 0x00058897dc9c0e4c, 0x0007cc4e0e8ad934, 0x000e1a22eeb0bf71, 0x0002afaf3b5679ae, 0x0000e7087f871d8f }, { 0x000917072350b58a, 0x0003f3089d0caf3f, 0x000e7f4d276ecde3, 0x00008251839564c5, 0x0000087315f576bd }}, + {{ 0x000446bca9aa0ee7, 0x0001c17e4515fa57, 0x000486c5bc65bdfd, 0x0001f2065f85cff8, 0x0000dbfd705501c3 }, { 0x0002113ffe594d91, 0x00076aa6d63184f9, 0x00079416c3a80498, 0x00070ef357c1a46a, 0x0000f69954823f55 }}, + {{ 0x0000c22f68309ca1, 0x0003f8312e7e46ca, 0x0009b5503c6d1a9c, 0x00023dd0469d0a37, 0x0000cf8b19a3e343 }, { 0x000c392312daf2bd, 0x00043514d2c7d8fb, 0x00030fa9a7d2b439, 0x000fe3577bc45ced, 0x0000ab008068f4cd }}, + {{ 0x0005fe87134cd0da, 0x000a17e3cc8ac855, 0x00078703ee282882, 0x00067052f8d725f5, 0x000030f3d852516a }, { 0x000242d3ae1ef785, 0x0007fa96ab6b01c8, 0x0008fa96637638d6, 0x0008ee49b69a02a8, 0x0000dfec375d87b0 }}, + {{ 0x000c24d8d4d1fb51, 0x000be65d62105e5f, 0x00093104e58c9f41, 0x000009e09bb222bf, 0x000003c8d01fc99b }, { 0x000f5d057a938685, 0x000eb85d41299673, 0x000c9cdf24c8ca30, 0x0005254a3db81c3c, 0x0000a0f18edf4572 }}, + {{ 0x0000a412c93e0e06, 0x000ef6d88c546946, 0x00053a654474d349, 0x0009ff9d1b26baba, 0x00004c0a14f6e6e4 }, { 0x000e419776983108, 0x000e18b54b25039c, 0x00029a3cd9d75545, 0x000cfad94d4ee67d, 0x000011516306d1e2 }}, + {{ 0x000a4bb3d86217f3, 0x0007c851c203a40e, 0x000600b1dbb8dedf, 0x0003f9ad230d352d, 0x00001526e5ac6533 }, { 0x0006ec4cd010437b, 0x0004203b98e782b8, 0x000f7f38453d3262, 0x0001381c8ac958c3, 0x00002e418f417cec }}, + {{ 0x000f921d710cc9ab, 0x0008a269be47be0e, 0x0007db96e1305cfa, 0x000a2bce5323b7dd, 0x0000b7178cc6492d }, { 0x0006c2921097b191, 0x000d0fc3c4b880ea, 0x000df1d178576177, 0x0003f6e393f6f914, 0x0000ac9a7fe9fa67 }}, + {{ 0x000e1999144d70e0, 0x000616651b8d9a36, 0x0008a1e1749d7d0f, 0x0001207ce42531bc, 0x00005552258e045d }, { 0x000453c20f47dfdb, 0x000d63dd5d369463, 0x0005c23b3f858e11, 0x00030f7308255dc6, 0x000097f02a0dbe3f }}, + {{ 0x0000448da6108dbd, 0x000d0c089a6ef014, 0x0000581351df8a6b, 0x0008d1c244dbcc3f, 0x0000ec04c9855b4b }, { 0x000882a424d7120b, 0x000876d4ee343e2f, 0x000c9865fedd1f17, 0x0006f503f6343f1b, 0x00001fce589b6c69 }}, + {{ 0x000b6c5db412e00f, 0x000c6f4e7db9f57e, 0x000950cbee732732, 0x000e651b17dfba38, 0x0000cfa203fd495c }, { 0x00067ce8c320f904, 0x000ea661cdfe0491, 0x000e2dd72666a257, 0x000f366ad9baac0c, 0x00006dc6d3d1e884 }}, + {{ 0x000bc95725aee3d5, 0x0002ea553fb2b560, 0x0007423c28530356, 0x00000bbd96ce141e, 0x00009b1c7fa39ddb }, { 0x0007326ca7661923, 0x00044911220fd06a, 0x000b99589f2eb8ac, 0x000d2c8a9716e3a3, 0x000016f0b4225082 }}, + {{ 0x0001690ce1657980, 0x000051ccd090c436, 0x00038fc32ca6d826, 0x000d1fbe4561e8f1, 0x00005c54597e892a }, { 0x000bc9fb209cabb7, 0x000e3370f009052d, 0x0000145c0e0d8cf2, 0x00051250f258758f, 0x0000f2608411d361 }}, + {{ 0x000532da0afeae19, 0x000c46e246518404, 0x00046092c0b1374b, 0x0001c3038dca45a8, 0x000033c9b87864ee }, { 0x0007d1a0f94114b6, 0x000a8a51999a6bf9, 0x0009c69a51f582fe, 0x000472a933aa9505, 0x000027a0c0040cfe }}, + {{ 0x000422b0ea14fa4b, 0x000a0ba2e1c21dd4, 0x000be844e6da17b6, 0x00005c51ff41b29f, 0x00007397b90d379e }, { 0x000a349d39ffa32b, 0x000651c92f1bfc4c, 0x000f17ac719f4a41, 0x00085fbb806ab1f8, 0x0000fbba41e33ddb }}, + {{ 0x000e959ff7b2ee8f, 0x000ae32343bf1a9e, 0x0007493c06b9bdc7, 0x00079d6b48fd3bd2, 0x000098c8ad76a47e }, { 0x0004498bbccb8f72, 0x0006af89706dc3f5, 0x0001c204bf7138d2, 0x000f8d1c8737db0e, 0x0000b2806c0cc363 }}, + {{ 0x00065b514edf386a, 0x00009faa29e24afb, 0x0003ba4f3652565c, 0x0001ed0cefcc3c45, 0x0000b4260964a621 }, { 0x0003d84d2f4de65c, 0x0008bcf2193e3934, 0x0001b16c00689684, 0x00018dced60e9a4e, 0x000031f1675d66b3 }}, + {{ 0x0000da1a5636e5cb, 0x000e641ee398a212, 0x000ec2e2ab685487, 0x0004e95eab88a56a, 0x0000f1202655d900 }, { 0x00084fcb18da2d59, 0x000409d65bf0384d, 0x0003850a4cf62127, 0x00046220471a14d2, 0x0000aabe22696247 }}, + {{ 0x000c58b582f24ca4, 0x000ef7bfa44b4794, 0x0009104047cc8e91, 0x000a3e3275350549, 0x0000d5c4cf012836 }, { 0x000c293a547b773e, 0x000f8d88327f246f, 0x00095154b8cc443a, 0x000e8e6f2c3a3bfa, 0x0000876c2770053d }}, + {{ 0x0001a4c61890bb48, 0x000ed2b5acf6e10e, 0x000cce418caac285, 0x0009c327fc50343f, 0x000054fa09fb1487 }, { 0x0001219614c932a6, 0x0002acd33425d0a3, 0x000d6a5a2e6ad1f4, 0x000390c0b306399e, 0x000069c28a3f1ea7 }}, + {{ 0x00080094dc4fe82e, 0x000926487f5d28b0, 0x00018e21e3213666, 0x00082bf5f11392d9, 0x0000b5fd9212666b }, { 0x000eebe7f030377c, 0x000dc8c208ba19bd, 0x000ea6270a941ac2, 0x000bdfd9ad3e7570, 0x0000821cf9f8f5d2 }}, + {{ 0x000233c3bcb79698, 0x0007798e5c298ff6, 0x000dd44472627899, 0x00035021617f561b, 0x00004d4a92c755e1 }, { 0x00039704dff5bf49, 0x000cca192e3a2cb7, 0x0001729f4c39863a, 0x000cd0ab1961bcfd, 0x000099be056ddf36 }}, + {{ 0x000983e996aeb001, 0x000fa587e7b754b2, 0x00017e82e022cefc, 0x000a043522336079, 0x00001a6d17a03274 }, { 0x0000980f9163017c, 0x0006929958d881dd, 0x000255946bab7a49, 0x00009d6d1026bae0, 0x00008bccd8fe0233 }}, + {{ 0x000d2d5a30705fba, 0x000888cd5f30851d, 0x00064d220bffdbbf, 0x000fd8ea494dfed2, 0x0000fde12797428b }, { 0x00094c486a8e2a7a, 0x0009bbdd44cc7a57, 0x000d43c60acfc916, 0x00005ddc94ba6b20, 0x00007845c76e4d96 }}, + {{ 0x0000a4725a093707, 0x000cdcef21496e4d, 0x00081bc4f0d7dfee, 0x000567a2ff951d19, 0x000004d0a3778435 }, { 0x000aeb8750fba3d2, 0x000d0b50e3bab661, 0x000590c1a91e5597, 0x00060f29e462caff, 0x00005cc394b808b3 }}, + {{ 0x0001170c04952602, 0x000ef2f2f7d0ca2a, 0x00083f53c32b2b0e, 0x000d4ca2f6d2e812, 0x00000b742e457e8c }, { 0x000c212c2c471b8d, 0x000904f7805a99ca, 0x000620057f79b6ee, 0x000379240bde56a3, 0x000033f6108aa3ee }}, + {{ 0x00052e379c819e4d, 0x0001ef315697be5d, 0x000b57359024af02, 0x0002f60af6f0545d, 0x00005709fccda5fb }, { 0x0001cedd8c6a019a, 0x000c747f462c23e6, 0x0007e4ed47245af3, 0x00083d34fd44a429, 0x00006bc4a68eae78 }}, + {{ 0x000f0076f4926fec, 0x000495699f241d77, 0x00068119bda8ce25, 0x00019f891ee4adbd, 0x00003a1ea5347618 }, { 0x000550518bb90e9b, 0x0007dba9264da3d1, 0x000d4d575100188b, 0x000532e716eb2d2c, 0x0000e97178dd93ce }}, + {{ 0x00024db6c372c507, 0x000dbf057d0b70c4, 0x000e8ac584e05e23, 0x0007c63eceea8612, 0x000024b1bdc12cd1 }, { 0x000dd6f3a8ca9d0a, 0x0002fd116213fd1b, 0x00045acc53e70ec3, 0x0006f4621c61e7fa, 0x000085b4cbd42400 }}, + {{ 0x00099a3c67370e5c, 0x0003a675d97f7e2b, 0x0000f571b84ecef2, 0x00083067a31db0fc, 0x000017a0dc2e6d1d }, { 0x00085346d4a4a2c2, 0x0009d5536b1ff923, 0x000718d7f1b94518, 0x0005a30632973857, 0x00001c47d9a812ac }}, + {{ 0x000f7d00d2868ab4, 0x00011ef31631f9e0, 0x0000f428795737fc, 0x000994421bf91da2, 0x0000273abfaac3f4 }, { 0x0004d97e8ccbeaa3, 0x000c93bd8fe79da6, 0x0000704c4b09c411, 0x00014c02acc5e8c4, 0x0000b4ad51bd9104 }}, + {{ 0x0002ef029032eee0, 0x000f97302f1cd1e1, 0x000b0ae310148f43, 0x000a922f7ce87eac, 0x00004d8e4c69e3b3 }, { 0x000bf1615a2e8a8c, 0x0003b4e1bcea6e23, 0x000400c7cb616594, 0x000051105d0b5402, 0x0000087338e47a50 }}, + {{ 0x000f0469962cc718, 0x000da79f8a7a838e, 0x0000165cecca8079, 0x0005857a111aea63, 0x00005efd15955b73 }, { 0x00066e898fcc53b0, 0x0000ec9d8080711c, 0x0009d97055e6ac0a, 0x000ce1126e1aec60, 0x0000c1f2ccbe262d }}, + {{ 0x000ba8ad1ed135cc, 0x0009dc408811fdbf, 0x0007341f43636885, 0x0001975388bfe1ef, 0x0000b69e74c27446 }, { 0x000526bed9600a55, 0x0007bcebfd2fd5bb, 0x0001b9bf4e885c17, 0x000c7cd530b839a8, 0x00008c55b30c7f4f }}, + {{ 0x00038b8ee0eac787, 0x00034c2385644641, 0x000778ba2d92e1fa, 0x0005103789e3ff94, 0x0000d8a525b4c26d }, { 0x0005fab8823fdd61, 0x000c24c4123c4899, 0x000864697a151ca0, 0x000c3fea366e6936, 0x0000a8b00c976bf9 }}, + {{ 0x0002f26699c531ca, 0x000a607eafbb1e1a, 0x0006446913f9ed17, 0x00084c378d75c9ce, 0x00002f579798942a }, { 0x000be4b0873a045a, 0x000c4cfe469b17ae, 0x0008fb488e3bb18c, 0x000c6b73f6254577, 0x000013dcc4276048 }}, + {{ 0x00017c8bfcafa626, 0x00038d78cdfedb1f, 0x00070ca48e783c87, 0x0002c1ec5a535c07, 0x00007254a1aa9e62 }, { 0x000e719e57fc7500, 0x000412efb11fbc42, 0x00026639a10db9dc, 0x000828243ea0b548, 0x00002ca6e35f3d10 }}, + {{ 0x0005b95cd967e18c, 0x0006485304ddc5b8, 0x000cc7f246112826, 0x000bb9ca9095e8c6, 0x0000dc3c5bfcdad7 }, { 0x0008349cc1a3f2ac, 0x0001c19b97447336, 0x0008944abac218e4, 0x0009d8ce429c5f53, 0x0000d9a807c23931 }}, + {{ 0x000adb13a8f96a40, 0x000cc1d21830ee5a, 0x000e3ee48eeed2de, 0x00073da9436f9c4e, 0x000084a78c9eeb4f }, { 0x0004d8c4d2962386, 0x00024a081313dbae, 0x0007dd3c6905bb3b, 0x0003055f8c76bb46, 0x000014e6ca4ea310 }}, + {{ 0x0006544814c3dd38, 0x000ae75b055cb405, 0x000b41270952f9db, 0x000528063898f8e7, 0x0000345a4f463cf4 }, { 0x000d3837fbd3e57e, 0x0001095263a75a91, 0x000efceac4dedcad, 0x00056557ccfb6836, 0x0000601bca5adf6b }}, + {{ 0x0008cfb7c7648894, 0x0002138ff4f94ab1, 0x000254b0012b17d7, 0x000d3be877243c71, 0x0000e33accb24543 }, { 0x000bac55e7f80d33, 0x0008ce6729082196, 0x000b31a4eec38aec, 0x000e7812f35c4592, 0x0000abded42c4fa4 }}, + {{ 0x000c639ea67a665e, 0x000231e94dea0f66, 0x0004752922fd3b67, 0x0008002f8259ecae, 0x000098781142c79b }, { 0x000839e6a69aa2dc, 0x000dccb7e1026fd1, 0x000b4aec329bec7e, 0x0004d41a39e73b50, 0x0000263b2ffecddd }}, + {{ 0x000014c5132e700e, 0x00086155150b8057, 0x000e8917ab8428ab, 0x000983d951892389, 0x00006f4bc50a7b1b }, { 0x000b4f4f21091832, 0x000a9361b07523ca, 0x000d80cd15d93e68, 0x00013de5a2f6219c, 0x0000812154648f57 }}, + {{ 0x000a527e6b978cee, 0x000db82cf7d62d27, 0x000ca96802e48946, 0x000e9519e1f36e29, 0x00007265e87b84fa }, { 0x000802786e991660, 0x0003097581a85e38, 0x000f541313771b92, 0x00067126e1f1a520, 0x0000d10aa19b0e7d }}, + }, + { + /* digit=15 (1,2,..,64)*(2^{105})*G */ + {{ 0x0006f0af00724aea, 0x0002a9e36f09ab05, 0x0009f3200c5b7d67, 0x000971f9803f163c, 0x0000abeb83ab4494 }, { 0x000dc4a79b89e736, 0x00099ec70880e0de, 0x000ed078e9a3f10d, 0x000e77ebd7332a66, 0x0000efcf0956aef4 }}, + {{ 0x000dce3782cc4229, 0x00054d0c55c44969, 0x000687ed744ff73a, 0x00095ca63a6a9635, 0x00006189f2556fe1 }, { 0x0005e2f1f92bf8e0, 0x000c16ab2b91f71a, 0x0002b5bd2443b5ec, 0x000ec35ade448982, 0x0000c8788b8a39ca }}, + {{ 0x000392b0b18c6d03, 0x00098e7abded5516, 0x00086524935ee7e4, 0x000a3d6a903d358b, 0x00006875db035981 }, { 0x0006fc5d51954294, 0x0000e980b75c904f, 0x000db1fb9c1ad202, 0x000ea6532c305b0a, 0x00001aa27478cb82 }}, + {{ 0x0008f862ec09473d, 0x0000ac9d64cc78c4, 0x000b52744f8f7011, 0x00038e5ab6c50621, 0x000008c758760cd6 }, { 0x0006d3b2c6ac19b7, 0x0007bede1603c166, 0x000ef5c6e18a250d, 0x0000ffdfc19a80e0, 0x0000dc276b838e08 }}, + {{ 0x00006fa37070bc95, 0x000637e822e37bef, 0x000334cc36ddfbe8, 0x0005c75eb73f237b, 0x0000f47794e531d0 }, { 0x000fa0c354bdcde3, 0x000d86efc621c127, 0x0003c1174b714c9d, 0x000d773f35d624b6, 0x0000fc893443d0bd }}, + {{ 0x0003d69f745fb237, 0x000c331e3229d41f, 0x0001a07c7c60896f, 0x000214b09a929c65, 0x000030eff0f7b347 }, { 0x0009ce6bfe978f9e, 0x000339a168336319, 0x000d6a06afe4f177, 0x000c17ed868a34c2, 0x0000a6c91a8a3c76 }}, + {{ 0x000567bcf9802012, 0x000c8aaffcdb4631, 0x000a1f3bce0ebf8c, 0x00088f58d658bbc1, 0x0000d77d6056ff71 }, { 0x000c08728ddda15b, 0x0003de03572359bb, 0x0004ca5173fe02e3, 0x00082257ccf0353e, 0x00002fdd1fd23a9f }}, + {{ 0x00011cac13161f9c, 0x0001bbc453cadd69, 0x00072aef15e577c3, 0x0008c37af203900a, 0x00000e41db5e3490 }, { 0x000b87d44a487f26, 0x000dc42ec965469f, 0x00012e582d33e4d5, 0x0001872850e9f769, 0x000038b03659451d }}, + {{ 0x000cc69f23d9740e, 0x000004bfc25419a6, 0x0002df389dda0805, 0x00042da3f3646720, 0x0000f63588d2624c }, { 0x000b9eea3275aa7e, 0x000665a6bc68bb94, 0x0005dde089018c6f, 0x000b34b7ce43d79b, 0x0000cca74fe735d0 }}, + {{ 0x00075c28e4f6afb1, 0x00015ba6102d0212, 0x000807e8390524e7, 0x000ef68a8eaafac7, 0x00005aa40be45ccd }, { 0x00072a4f8c8e1dc1, 0x000599ddd2e54e03, 0x0004cedb11fea727, 0x000190c246991adb, 0x0000a2b27ebd40ed }}, + {{ 0x0009ee1edba4daa1, 0x0001c73a6a5da60f, 0x000fe25e811523b6, 0x00078cd576f083d9, 0x00001e9fcdcfb94b }, { 0x000aaf21de46d633, 0x0000eec8bdcf8e7c, 0x00004054fc48103c, 0x00029bd40a5db827, 0x0000e01632abbb9d }}, + {{ 0x000759b8001f79c6, 0x000ece14f0dd2e8f, 0x000e12ddc2c79568, 0x000005b98e77e7c4, 0x0000b791403a3eee }, { 0x000aa7ff8c7ea4a3, 0x00083eddcfe314e5, 0x0003f92dd00d49d0, 0x000ac95b6eb84c52, 0x000080d5b1ce41d2 }}, + {{ 0x000baaaaa42eba90, 0x00083c3b9791a263, 0x000a922ae072d050, 0x000f042de960022d, 0x0000bdcee541ee28 }, { 0x0003bb68bfa63380, 0x000a3460d881efdb, 0x000f9276f56af417, 0x0002898d4506416b, 0x00006f83b035b65d }}, + {{ 0x000fd6b0c5230ca5, 0x00013bf5116f9379, 0x0006214fd87df2b3, 0x0000cfdc87c64a58, 0x000027f51850fe61 }, { 0x00092d51304b9476, 0x000443ce8ee0e0e2, 0x0000005ed0ca005c, 0x000d248e06f6fba6, 0x0000747a3ca00962 }}, + {{ 0x00048c919c326cd0, 0x000405dbab093b30, 0x0008fdf707eac1e4, 0x00007d89c012f59b, 0x000033b871966602 }, { 0x000eaf517a2fb4d1, 0x000d1b591071cd58, 0x0009749a1f2b94c1, 0x00002c84b791ed89, 0x0000772ac30fc8b2 }}, + {{ 0x000da8e4f1aff818, 0x000caa2d551ee106, 0x000804d524b4b06e, 0x00008fc8d87a8f1d, 0x0000ef431fbeb97c }, { 0x0000c0d9b00298e4, 0x00033f0cf9a4e718, 0x000fbb34f16943d4, 0x000ca08c0ff50200, 0x0000745ea7a228cd }}, + {{ 0x000d1395ccbc828b, 0x000e6d8033f28764, 0x000630492e0f2bf4, 0x00047311db0186ec, 0x0000dac857b0b37f }, { 0x000038d71b0c1915, 0x0004dd6186244a03, 0x0002e0d184389b23, 0x0000269ab918e5f2, 0x00006cc928b6af68 }}, + {{ 0x000de6ad0f11bc0e, 0x000f6b7a93c32461, 0x000982d307be7245, 0x0001a341821ab606, 0x0000a0e9cfcf1ca0 }, { 0x000b972fd6728dfb, 0x000af88ff1929c78, 0x000ad87757dee47c, 0x000d111ccc6df4c6, 0x0000d7c581401c53 }}, + {{ 0x0001f7f91b4ffc66, 0x000d0b60b846531f, 0x00051eadeb59f002, 0x0004950c5ba7e45e, 0x0000b7e2a63df2f1 }, { 0x0004c828296f804a, 0x0005c9244de90d77, 0x000a7cd199349397, 0x00056f3eb951a1d4, 0x0000788cafa21d5a }}, + {{ 0x000ce2e57adaafd4, 0x000a4fce7560b907, 0x00012b053f53cfb7, 0x0009317a8b4073e6, 0x0000b35cda57c1fb }, { 0x000b6dd71e0124a6, 0x00021891df1ad467, 0x00018e156fdf889e, 0x0000b1b7783a0692, 0x00003ab3282c54d9 }}, + {{ 0x000182d411742393, 0x000da0a73fa9cb0d, 0x000d6109219851e6, 0x00008f982edd3992, 0x00006166219cbf0f }, { 0x000cb8df03c5c3e4, 0x0009038d9a528dba, 0x00091e3c5a90b7d9, 0x00055b47ce8b1a0e, 0x0000a0f6e1eafa48 }}, + {{ 0x00012fcc62fd2575, 0x000c5328300129f8, 0x0001e7946f9a564a, 0x000bfcb511f63766, 0x00002838b2c1b003 }, { 0x00017bbc879d576e, 0x0002f5f29fb85da6, 0x000a07cb9d60a23f, 0x000afb8b772f4e00, 0x0000907e471fcadb }}, + {{ 0x000682238fc10ebe, 0x000cdb997aee3170, 0x0006e19313189010, 0x000b1dd9b812a409, 0x000009ce0a98c979 }, { 0x000b75351318c260, 0x0008ad6aeccb4bdf, 0x00096db6712057b0, 0x0003d3d336a34e9a, 0x000074e57bd9af57 }}, + {{ 0x000f1e0fa64b9ba1, 0x000a4ff1d7aadabe, 0x000fe6d896d5ce68, 0x00034116f65d3825, 0x00007bcae08c6246 }, { 0x000ac54f612c30f9, 0x000ceba33db72cdc, 0x00092fb725511bb6, 0x000d9573c017cbc0, 0x0000a29dfebf2fc8 }}, + {{ 0x00044c4ab2167d7a, 0x0005980b2369f0f0, 0x000d1f7b169f84ef, 0x000e52fc697d3a70, 0x00000371cf064a81 }, { 0x0002f2497b167080, 0x00020fd834a2ddc6, 0x0002698938f1ecee, 0x0008c649049e6b86, 0x00006463bb9f084c }}, + {{ 0x00070d2d35f711e1, 0x00024b6c64582934, 0x0006a1c3ddc10d9e, 0x000d436b836bb527, 0x00000a5cf78fdd97 }, { 0x000e797ecd201480, 0x0008832feeb1b77f, 0x000886ec00cee664, 0x000e180042bb75c3, 0x000057f8a6d620a0 }}, + {{ 0x0008abdd527350b0, 0x0003c2a753aebcc9, 0x000c308e0f53280b, 0x00044fd09daf9f3d, 0x00004eb1613ae15d }, { 0x000462e7e6da22c6, 0x00044318d168be52, 0x000ffec2ba55ff61, 0x0004c09afcf7c10d, 0x0000ff5b8008b9a4 }}, + {{ 0x000d3eea67fe0e27, 0x000638ba0cc3f125, 0x000d5f283fc1ad1f, 0x0006105d368dd485, 0x0000f512d2d3ea5b }, { 0x0004dc21e92938f6, 0x0002481e6602671c, 0x000f4f264a2357d1, 0x0007c19858f144a3, 0x00008d20d20e844d }}, + {{ 0x0001db64b60dcc0f, 0x0001eea521d03782, 0x000de325b7b9b75a, 0x000800aea802b8e0, 0x0000a207924704fd }, { 0x000e7c824e8b91d0, 0x0007ee970342f9d6, 0x000dad47c7c593a7, 0x0006b3baa93a10ae, 0x0000b3c50420ccb3 }}, + {{ 0x00044dd196d3754c, 0x000ae819966e7eef, 0x00071169c0771aae, 0x0001b5ed464ec4aa, 0x00006b0c6bc0965a }, { 0x000ca9d721b441b9, 0x000b8f1bb46b6a1a, 0x000350de796ed922, 0x00067beb41e65d31, 0x0000103b3fe2d35f }}, + {{ 0x0000c504bf8e9753, 0x00032a0fcff6a17e, 0x00023e05782f0bc3, 0x000b8f8e39970a3f, 0x0000a169715bac3a }, { 0x0006fd0c5dcd460e, 0x000cb5677fcc2f46, 0x0006febe5366b0c3, 0x0004c78aaef1a522, 0x0000e87aa65153be }}, + {{ 0x0000903c4cbe46bc, 0x000c0eb1bf4581ca, 0x00060c177519da3e, 0x0005066ace635e18, 0x00005345445cd5a7 }, { 0x0007197ca469b8c0, 0x000858948f214029, 0x0004225140fdccb5, 0x00087719031b49c1, 0x0000a2053b8e6576 }}, + {{ 0x000332d0815fb0b2, 0x0002b1e274983d81, 0x000e423eac0e20c3, 0x000b147d1da1a3bd, 0x00005049bb2f20a3 }, { 0x000aa2f407901242, 0x000b5a3aa6d0e10a, 0x00034aac28430b6c, 0x000c1136717db2e7, 0x00007894ad4da6bc }}, + {{ 0x000fe4ca540470ce, 0x000a79e7ace3fc7a, 0x000e95c40e7284f5, 0x00012800e9594eac, 0x000074e26fc1378d }, { 0x000ab186fc36c333, 0x000b556e6ee81c69, 0x000ad0d7933ec714, 0x0002305298f671be, 0x00009b93b73b2fc4 }}, + {{ 0x000df0fefced17bd, 0x000f66910b5be761, 0x0009dd130cd0a056, 0x0005c2188046b773, 0x0000009bdb10a2de }, { 0x0009ee86e04a5ad7, 0x00080a6bcfcd0279, 0x00052142deea631c, 0x0003ecdd9a8786c7, 0x00002b9a476e5434 }}, + {{ 0x000074d3de5dd49a, 0x00093ddc15c9f0ab, 0x00039220c4bffda7, 0x000fbf5dadf87a73, 0x0000e0074caa9da5 }, { 0x0006df62f75d4dc7, 0x000b20351a03776e, 0x000a43811d0fc2f2, 0x000c76a852bb1f77, 0x00003d9c33f35883 }}, + {{ 0x0005c11927d7db11, 0x000c0beed51275ad, 0x0006594e2f1817d8, 0x000e7addf5de47dc, 0x0000c87b4cd166bf }, { 0x000890cd3245ae9a, 0x0007800a73a294ea, 0x0009f531344057c6, 0x000c0b66a5f88434, 0x00007a6fab6ca15c }}, + {{ 0x0005929d26ae4d60, 0x0004ec170f4d3b44, 0x0008ca69efd95c9e, 0x000881838fd1a136, 0x00008822948519a9 }, { 0x000418f5d76d3725, 0x000ab6025b15ca6a, 0x0000ca2e4e6eecf5, 0x000e72c344b3c83e, 0x000017e3caa4a180 }}, + {{ 0x00041b28983194f2, 0x0000a8a213ed68b6, 0x000cecef298c37a2, 0x0005ba953860ae7e, 0x00002530dfcc9dad }, { 0x00085a2310dabfe5, 0x00053e101110f35d, 0x00018c30f6264efd, 0x000d17ff479c26f4, 0x0000836740a708c2 }}, + {{ 0x0002dda543915e7e, 0x0005f5d4b07e2b19, 0x000afac0fcdde015, 0x000a72d14d144c4c, 0x000034e73127607f }, { 0x0002db773ecd3720, 0x0000fa8cf03dce66, 0x0004b74758be1c61, 0x0007668c48b5ea96, 0x00009b6250934072 }}, + {{ 0x0006f31c01a3dfbe, 0x00044fb93f245674, 0x0009ea5f3bc92e2f, 0x000eafb87fd46c69, 0x0000f667b3eec5e7 }, { 0x00083cc1ece5f671, 0x0006a59888b219e5, 0x000789c00b155ab8, 0x00029106ce50ecc3, 0x0000f8a9874cc0ab }}, + {{ 0x0009a7ffecf51501, 0x0002d66a483bf119, 0x0005180ac17cfeb8, 0x000d4f928fa08a6f, 0x00000c4ee2e35856 }, { 0x000cba1424521b06, 0x000b7dbc4ae62da7, 0x000dba90db391823, 0x00031ffbc6cea00a, 0x00007680c0ab694b }}, + {{ 0x000ff63e0965f49b, 0x0003121208490def, 0x0002bd04ea6fe3be, 0x0007b166f1ca66ec, 0x0000bbe50fc3adb5 }, { 0x00010d8a6a559d7c, 0x000debe8b2610bed, 0x000f68d0b38a6296, 0x0007eb6b4b732ed7, 0x0000e692b4dee5cb }}, + {{ 0x00046bae92221adf, 0x0006498ed4de248b, 0x000d5bdcda959eec, 0x0004c5f13d7cedac, 0x00004112599c6663 }, { 0x000b84c4c8c12811, 0x0007372fcef7ad8e, 0x0007e92e99ce45e0, 0x000ba88866115160, 0x00004192a1db5e1c }}, + {{ 0x000f01e9b964c398, 0x0002d5c164e1214b, 0x000ce245d14a5d2b, 0x000e5d035891be86, 0x000058456cfb56a6 }, { 0x000ed62a7c96800a, 0x000d739b186ebc0e, 0x000596e2f14dd4cd, 0x000592e54d5c74c2, 0x000037f83089202c }}, + {{ 0x00069dfbf102d869, 0x000846f76b7618a3, 0x0004cd18647184a0, 0x000791ddbbff750a, 0x00000418f22b31b3 }, { 0x0008af82f7454899, 0x000196c7191a321c, 0x0008783dee978292, 0x0008738839edac3f, 0x00008a38ad413f8b }}, + {{ 0x00018d12afd54f4c, 0x00098d897ce0b2a0, 0x000fc2184a2fde82, 0x00068cefee6d7c87, 0x0000880946a4e593 }, { 0x0008157478782d1a, 0x000480801206e150, 0x00039ba30e4db2ff, 0x000d448d5e0e4245, 0x0000a2f55c162b2c }}, + {{ 0x000d7803581ab555, 0x000eab4820357c72, 0x000e419c5554fe07, 0x000fef5a1992039a, 0x0000d9875b456d0a }, { 0x0000ee0ea7058063, 0x0001b4dc77ad4d4a, 0x000858f1411d534f, 0x000f0bd5ed49a799, 0x000050a8f7fd0e17 }}, + {{ 0x00033d6d545551ce, 0x00020cfab7bd7712, 0x00031284f564f60d, 0x0004b93e76c87307, 0x0000270e7036f3e7 }, { 0x0004b690d19b6f88, 0x000ce26fc195bcc5, 0x0007b020fa92369c, 0x0007d06f32544595, 0x00005326f8c26b7c }}, + {{ 0x000a5acf73de976d, 0x000bf8a212306466, 0x00089df47218a462, 0x000994d43f51aabb, 0x00006b738c5c4d3b }, { 0x000ea5938bb50b53, 0x0006057d635b4d5d, 0x000d0e302e4e6897, 0x0000f9dddc3de68d, 0x0000247ceec78021 }}, + {{ 0x000446bc5330e6c4, 0x000131afe637294c, 0x0005e1616084d14b, 0x000a79fb501968aa, 0x00003b7dc534fcd3 }, { 0x000178d549b09def, 0x00061a696d6134bb, 0x0004ec90cb133eee, 0x000053a1a9361fbf, 0x00006af0a49f5d2c }}, + {{ 0x000b745f8fc43a35, 0x000024ba4df39156, 0x000ec4617678c3bc, 0x000a91c02566ce1b, 0x0000719b228fbdb9 }, { 0x000f385adab6fcc4, 0x00066f663122edfe, 0x000c4c603faed143, 0x000bd6d563190f9e, 0x00007f12983cad34 }}, + {{ 0x000f1627dec28dca, 0x000b7de3f642c293, 0x000851f9d3a9edf4, 0x0009b5b4620be088, 0x00004176cb7f6c12 }, { 0x000787c0dcf777ac, 0x000f413eefcd6385, 0x00061d44b6e6ae82, 0x000d1495e8f3bf62, 0x00007ad2517a88ab }}, + {{ 0x000193cecacc8855, 0x000e5a2d9a23e449, 0x0002bc7c9a4324de, 0x00070bc0888dfa99, 0x00001357e1a16b5f }, { 0x000cdf57355cc9f8, 0x0003a7d2d738fc52, 0x00076a8097379e6a, 0x0007681a56697b03, 0x0000e15f32fe6b63 }}, + {{ 0x0000441aedd1db0b, 0x0003920bd55659e1, 0x000b3331ee1ea4b9, 0x000604e1a7973e32, 0x0000b848523ff344 }, { 0x0006429320a3e8ed, 0x000324a045ad915b, 0x0006ee6d1990975a, 0x00014ced86c11b43, 0x0000ed1e5721bace }}, + {{ 0x0003cab91b752141, 0x000a5e89c92b2350, 0x000e676eda85d689, 0x0001c8f31a73bbd0, 0x00003841c3e8d0f4 }, { 0x000cd61ad4ee96e2, 0x000a42f1db3574b2, 0x000537e4eb45e77e, 0x000813c06485b018, 0x00002be90410b3b1 }}, + {{ 0x000fbec0cb6f0fc0, 0x0002d5a2ff9f403a, 0x000ab264cf5dcff0, 0x00007f70d8dc98d8, 0x0000dfe1570152b0 }, { 0x0008d1e1d5d329b1, 0x000c06480130dfa7, 0x00051130fb1fccc3, 0x000875ec0306dc2b, 0x000026a348354b2b }}, + {{ 0x000e31318e23bd1d, 0x0006f5a192ef7106, 0x000acd43006b8a32, 0x00067ef9e88afbd4, 0x00009533ab5f7940 }, { 0x0002a21cf2ee4b63, 0x00061b824f89b4e2, 0x000826214d380f04, 0x000d957a765a5dd8, 0x0000431ac8130d01 }}, + {{ 0x0009ea88981c66a0, 0x000fdee42a554f77, 0x000486443c22796b, 0x00047173d828983a, 0x0000d1238eb95f6f }, { 0x0000e913e1673541, 0x00064a7d065fd831, 0x0001a1798cdb2234, 0x000f61027f49af79, 0x00009e532ad5d547 }}, + {{ 0x0006b46e1f443280, 0x0001d14bc21ef518, 0x000ac63104730cf1, 0x000894c3be51c3ce, 0x00000536de024903 }, { 0x000be017a2ce58da, 0x000e02380041ef4b, 0x0004a6821c8b404d, 0x00079bad4d72fe50, 0x00006b9d35305a63 }}, + {{ 0x000b652edcec4a5b, 0x0009f09b389328ad, 0x0001f4b242d8c5b2, 0x00065eabf322fbc6, 0x0000dd15a5fc8674 }, { 0x000ea672143089ac, 0x000e72c03ec6627f, 0x000cc347decf2065, 0x000adfd0dde1b3b2, 0x0000a98c9af7b1ab }}, + {{ 0x0005cdafe7faf119, 0x0009ccb4f2999aa1, 0x0006a2fe40f56991, 0x00042ecbb38476cc, 0x0000d4790f63e31c }, { 0x000bf2c38ae9c943, 0x00018a4d935b7db4, 0x0003d0a6e142ea64, 0x000ec115b648b600, 0x00003a16278132b9 }}, + {{ 0x000ee635fb2543bc, 0x00020634442449cd, 0x000954c719bd8c67, 0x00024b182e0e9921, 0x000066a2b2a91885 }, { 0x00074ea6ed7740f1, 0x000314a18ee6e8a7, 0x000675f4394244fb, 0x00033dc08eed748a, 0x0000cce701dd1d5d }}, + {{ 0x000add5f69c02408, 0x000d61cf3480d4af, 0x0006c1ad6fb043be, 0x00005529cf0d8edc, 0x0000e6b784db99a8 }, { 0x0005a454130bbd68, 0x0002fad96f8acb1a, 0x0004c17786cf7d98, 0x0001fdbf4bddd49d, 0x00002c7d15e91516 }}, + }, + { + /* digit=16 (1,2,..,64)*(2^{112})*G */ + {{ 0x0003c0440fd7f2f9, 0x000bdbfc360e25a8, 0x00048399d668b4f6, 0x0002439f4e642519, 0x000089f1fa0b9870 }, { 0x00097b3d282ee427, 0x0008cf1d720281f6, 0x000e67baa329978c, 0x0002104e72205910, 0x000061a43a34e6ac }}, + {{ 0x00071279a45648bd, 0x000de9afb3ff9ed0, 0x000b10e3d7b7d810, 0x00004e74928c2e0a, 0x0000f66bf52858f1 }, { 0x000e9fccc7111eb0, 0x0004f6601fbe8556, 0x0007f13a84fd868d, 0x0003acc0b3ee394e, 0x000011bb82692f56 }}, + {{ 0x000f57841f3144bf, 0x0001f9314092ebb4, 0x000cf3369fecda45, 0x0008e3164f17256b, 0x000033b176e2d462 }, { 0x000333e4efa6df27, 0x0001d05e708d8553, 0x0001d0bddee0a802, 0x000f8c7d5856aae7, 0x0000603c90846016 }}, + {{ 0x0007512e2eb6a7c2, 0x000b8dedda492f81, 0x000a60d843d6851f, 0x000eb594cc11a3ae, 0x0000e9fde037b87d }, { 0x000cf109a400a483, 0x000c6f3177bf8b6c, 0x00093bd6f59a5d1e, 0x0006c915d232ea4b, 0x000066d0031672f4 }}, + {{ 0x00008a54ec2b1382, 0x000f888a1f258972, 0x000f812b7fecbc4a, 0x000e06b5c7ac6961, 0x0000e7ee6a3486dd }, { 0x0003eeb9a9acb8ed, 0x000811978660710a, 0x00067f8f391f11c9, 0x000b760a50cf70a9, 0x0000a64a54a69740 }}, + {{ 0x000869d0d5ac68e0, 0x0008233169bca968, 0x0003a53cda259d70, 0x0005a1a9404d286d, 0x000088e4951616f4 }, { 0x00052a733ab82011, 0x00026e5d0150d651, 0x00030ee1a18ef179, 0x0006e1c49a92e250, 0x0000660861970a58 }}, + {{ 0x0001843074252dfe, 0x0003f588434a920a, 0x0002c09cd3518f04, 0x0005fc19ac0af8e9, 0x000065ea1ee67b6e }, { 0x0000581fc169a790, 0x00004aa5447ab801, 0x0005b7021d9fcb63, 0x000998a9ee5e5a32, 0x000086ce09c0bdfe }}, + {{ 0x000b0da855c77138, 0x0004d7080eb24a90, 0x000d3d8064a79971, 0x000e895b87bedfb4, 0x0000ff2e824b81fa }, { 0x000939b48c4a16ef, 0x00015dbde314c709, 0x000bd2f933b9e136, 0x0004c0d9ecdbf1fb, 0x000042e460791f67 }}, + {{ 0x00031e066075581e, 0x0007aa7cb0c9c8cb, 0x000fcea630fbe552, 0x00099ab0f75105f2, 0x00001f912867f6e9 }, { 0x0004564766700a62, 0x0007075d4b6d45a8, 0x000cde96422fe35a, 0x00087645bd363f3a, 0x0000ada1862cd2d3 }}, + {{ 0x000f0a0c47a9219b, 0x000f3cc37107c78e, 0x000a68021e1e77af, 0x000af3d45acff3b6, 0x0000e6dd110491f2 }, { 0x0006145e628202b8, 0x000de5176b6028e0, 0x00041e71b471983e, 0x00035f755c49ec67, 0x000098d7591e8ff1 }}, + {{ 0x000bedcf6b007f50, 0x0000d07e75746b54, 0x000d781ea953336a, 0x000b0a8e21c1e1f6, 0x0000184b09b48421 }, { 0x00054ff226110b80, 0x00069c13d7a4c8a9, 0x000bd88ff53a5a2c, 0x0002edbbc2748887, 0x00009a72c0defd99 }}, + {{ 0x000775780f973b43, 0x00047b197c3dfb92, 0x0000a7a109452cf0, 0x00079c39255a549b, 0x0000db1d2d13d82a }, { 0x00002f1085a734db, 0x000a5b8e1c9d7c80, 0x00013facbcd0a776, 0x000350fce8c69dae, 0x0000dfeeec7f75f2 }}, + {{ 0x0000deb4ca3a9977, 0x00053446d3fea556, 0x000693a2509e138a, 0x000c97b7db4ae9c8, 0x000056217a7b50ef }, { 0x000b113eaae38142, 0x00096947de6c34cb, 0x0008898319d2c511, 0x000be485b4ee6825, 0x00002fb9bee4a336 }}, + {{ 0x00009ed751690d07, 0x000fcb92115b4c9e, 0x0007a869f38018bc, 0x0000b109a7c163d3, 0x0000d25180d0c741 }, { 0x000626f43012e59c, 0x00047fa26f516cac, 0x0006c84c3b619391, 0x000580cb4753cacf, 0x0000d99e17d2ba70 }}, + {{ 0x000d31e20e626aa0, 0x0002899a7b56eaf9, 0x000b97bd91088d33, 0x00016ea8600c0e52, 0x00005520570c169c }, { 0x000e6b9cffa1bae0, 0x000b32d3ed689748, 0x0007ede2eac48130, 0x00023baefe44bbc0, 0x00004454704b6e6c }}, + {{ 0x000c8ac9b3f30faa, 0x000821f711b0eb9e, 0x00078b7fefa0a379, 0x000f7e8dbb905f2c, 0x0000d9b3674355ae }, { 0x000e568622b92879, 0x0005fb6b40a24474, 0x0001518d75018f42, 0x00065c23f60121fc, 0x0000b6c0f8efac61 }}, + {{ 0x00029b6e563d4ca5, 0x000090d196aa5a1c, 0x00064da647a59d2e, 0x0006673b7e0df8c7, 0x00003ebfc59c82e9 }, { 0x00077c02963ba3d8, 0x000dc8b711484633, 0x00032cc947dff086, 0x0005fd3e4b5738de, 0x00002458f4cf0a1e }}, + {{ 0x000f18fb2162c8d8, 0x00018b92bb39c1fd, 0x000c06efdda4112d, 0x00032e00514373f2, 0x00001c606faff29e }, { 0x000b75dfb7307746, 0x000394242b3523f1, 0x000d6c807144512e, 0x00093377ce958532, 0x000075bf8f2eff5a }}, + {{ 0x000f8237e184aa56, 0x000a1c92d7d1413a, 0x0004e8b2bdb60c3a, 0x0005e6de867e2d6b, 0x0000a224fd131823 }, { 0x0003b73e5c38837f, 0x000e0dc84687cee2, 0x000181fb2daced27, 0x00066f750c5ded6b, 0x0000dba3169b9090 }}, + {{ 0x000e01470209ad8f, 0x000b4183037bf522, 0x00054ac5ded5224d, 0x0000656d7b61e6db, 0x0000906aa9885eb2 }, { 0x0002c37583833f85, 0x0004a9a360aa449b, 0x0004c69fd7852936, 0x000bb90efb70cfd0, 0x0000ef760d62ea7c }}, + {{ 0x00045a8ff05fe573, 0x000ccdcf50225f97, 0x000c3c869b135443, 0x000c34c64c52e175, 0x0000b6e1d4a6ca70 }, { 0x0007a71cdf35f6f4, 0x000f1a358321bc3f, 0x0006141dc268fae0, 0x000f35c58b1732be, 0x0000235d7150b4b3 }}, + {{ 0x000eeee592f8a112, 0x000413e894c5bbba, 0x0008bae94aef8e2b, 0x00074b0446915c7d, 0x000077f05c59725f }, { 0x000df69b21ac3da5, 0x000f813781354864, 0x000ec8c0d40ddda5, 0x000f943f53a275c1, 0x00001739b2d5fa33 }}, + {{ 0x00040e9f29ec6f84, 0x0002e502d0f39aaa, 0x000a7199ba1db519, 0x0007170fa622118b, 0x000062772036e611 }, { 0x000754b54fc3aaa5, 0x000aceb22b57f0fd, 0x0008a72baefab7bf, 0x00045f0fe849a33b, 0x0000513d3bc11f59 }}, + {{ 0x000b33f80501f2c1, 0x000fa22236f4a982, 0x0008db3408b65b08, 0x000a7b6740b0c59e, 0x00004d2185638a58 }, { 0x0004d80f0e06a637, 0x0005b9532e6c4662, 0x000f29818d65accc, 0x000b5facc68956d0, 0x00005c86484c910e }}, + {{ 0x00093cca39225886, 0x00097fb988baf015, 0x000d82749c0eab29, 0x000f43360e6331a7, 0x0000dde7d468f9e6 }, { 0x0008a7318da83916, 0x000968d265674566, 0x000957a433029011, 0x0007db2f640fa030, 0x0000ecd715314932 }}, + {{ 0x00048c5860d99716, 0x000ba4efc4d31579, 0x000197676589c678, 0x0000e5b72b56f8ab, 0x000013465a13e776 }, { 0x000bbbc6da512eeb, 0x00072f00ebd4f086, 0x000ca2c6ccb3e2fc, 0x000b072d03e5168c, 0x0000f06060e5f45f }}, + {{ 0x0005959cbe186e9c, 0x0003886605daaa67, 0x00074604cfe0af51, 0x000b65f8946fd72b, 0x00007a875d7ef388 }, { 0x000a73bb803de3a1, 0x000fe65c8a588eea, 0x00060d978e1d0473, 0x000b6bcf1368c92e, 0x0000847dbedc4d5b }}, + {{ 0x000eb1b6c88eb6f6, 0x000b10d6457d188b, 0x000accc881c36490, 0x000166a1386eda86, 0x00007a87d33e3d7e }, { 0x000eb5009735b4ad, 0x000768799240a9f2, 0x000f48ac891ad54d, 0x000b16c3a1bbb384, 0x0000158d9593875a }}, + {{ 0x00040b8b0c182e20, 0x00089c04a7d2caa5, 0x0001519f1783ee26, 0x000194e8f6f3fb3d, 0x0000f047804535e7 }, { 0x0007a5b479c3334f, 0x000ebc905e214f55, 0x0009fefb01bee293, 0x0006b190b9a74075, 0x00007399d8ab170b }}, + {{ 0x000505be1efb2b17, 0x00031e726bfe65cf, 0x000b7d8b04e8129f, 0x0003ed02e097e391, 0x0000ca6e619f0f6b }, { 0x000d838a95ee8071, 0x000cda1e3a3035a8, 0x00060f518312713d, 0x000e396f26431ebf, 0x00004e5e1383c630 }}, + {{ 0x00083bf494f1922a, 0x000d07f650006f01, 0x00033885071d3899, 0x000678396dfd7dad, 0x00008e6b9b5a00db }, { 0x00061e1a6d262a4f, 0x00090434a7bd989d, 0x000bcf24f627dcab, 0x00019a63e505385c, 0x0000162da51b10d7 }}, + {{ 0x0002b23a10647092, 0x000b4c64a8a3d626, 0x000fc1c509c1f5da, 0x0008752338469c4c, 0x0000592d71f92d24 }, { 0x000e65e5e66ab21c, 0x0007ab4a63d1a4c4, 0x000a2eb259587d83, 0x000fd941c454e7fe, 0x00001e808c047aac }}, + {{ 0x000985fe38c5fb2d, 0x00031a1ef74c45bd, 0x0005d4ac86cd7bdd, 0x000df50a92cfbfa6, 0x0000f38525a7bc74 }, { 0x00027e0dfe332909, 0x0005ffe5a0148b4a, 0x00068afa056fbba5, 0x0008e20ce6f9a55c, 0x0000c1b3d8c7c69f }}, + {{ 0x0002ab75b80ff311, 0x000335212b4603ee, 0x000088c4f75c8654, 0x000b6c312a876c55, 0x0000ec0c5bfb1759 }, { 0x0009a79cb22aa461, 0x00039761a23ff976, 0x0001f38e005de83b, 0x000defe22c613899, 0x00008b2f4e8bfccf }}, + {{ 0x0005afec02a30992, 0x000a30d594cc7e13, 0x0002fda0bf775275, 0x000f5c74a3079ca6, 0x00002d8fc95c11f7 }, { 0x0008853e7d3553e5, 0x00061f406ed2c6ed, 0x0004a50e5bda669a, 0x0007d947e58da173, 0x000046a193aa855a }}, + {{ 0x000e471b95b01638, 0x000188da35fcd5fe, 0x000b5b15af55904f, 0x000cb71628965df8, 0x000058d0fcc4ba62 }, { 0x000d74938578142d, 0x0006ec80a08fb758, 0x0004f469a20c56dd, 0x000db2288704958f, 0x0000e41307922cc2 }}, + {{ 0x0007a222bccd2e68, 0x000ed378c9049f43, 0x000343f0b5f94e09, 0x000b4556b5be948f, 0x00000a6efbb7a0e9 }, { 0x0004a461c9039832, 0x000e8bb8809bf618, 0x000b8ea28fc4e42d, 0x000e3db1c46f07fb, 0x0000437a4a4ab1e4 }}, + {{ 0x000e03fdde9732a4, 0x00038e6d9278d982, 0x00036ff876027328, 0x000107dc324d9481, 0x0000e4b863ced76e }, { 0x0002045a740a4e7f, 0x000871947b533c0b, 0x000e7a9f65e10697, 0x00067ac8f1a8bc73, 0x00005706a2f93e11 }}, + {{ 0x000fb693dc0269f5, 0x000e0afbd76e195d, 0x000c898214343849, 0x00079e0cb478dd1a, 0x0000bf92ae14b76c }, { 0x00050e61bd7654af, 0x000959651dbf1a78, 0x000e839485a58314, 0x000470b9acab4b4e, 0x000053da0f7c685d }}, + {{ 0x0008bb92b4197f71, 0x000bfe3dc09508b4, 0x000f2b75e3a19e68, 0x000e99255faf6d2c, 0x00008a43244b37c5 }, { 0x00012686517eb89e, 0x000b6845c7cf8929, 0x000944af69cde6fe, 0x000877f69f6cd7ac, 0x0000c9b055220817 }}, + {{ 0x0008da07e4a739f9, 0x0000013b78c558ff, 0x000acfd5d2c490d2, 0x000b770d343c0bae, 0x0000eee5df52f0ad }, { 0x000001122fea8b0b, 0x000b99da8a90ea83, 0x000b53a188f1cbeb, 0x0004dc77681c1ff2, 0x0000b1f2bc907c40 }}, + {{ 0x0000f5091f08fba5, 0x000efbe6718e4488, 0x0001fb4964f4d8db, 0x0002b10ef246c148, 0x0000fbde6b0ad954 }, { 0x000f886488030d36, 0x000f82f724bdd38b, 0x0003c4e9843fc28b, 0x00002bca902e915b, 0x000027da8403820a }}, + {{ 0x0002c8cdd5a84a71, 0x00075a6c93f72d63, 0x0002980f33151397, 0x000628017d5f75d1, 0x00002b6fc243ca3f }, { 0x0001bcaa034d4c38, 0x000e1927023c4994, 0x0006f72f8efe26d5, 0x000c24bf0a8afe5d, 0x0000af62213dc85b }}, + {{ 0x000bbee6e35723eb, 0x00074f98d2668d5c, 0x0009af1932828c67, 0x000a2e3110715281, 0x000018a72e0098ac }, { 0x000b8bfd572fd9c8, 0x00047e80cdb9808a, 0x000652b2d5bdd6d6, 0x00031881817d6e06, 0x000045b2eb036f1d }}, + {{ 0x00010e2fa9c3473f, 0x0000b59513aed8bf, 0x000c403da0d07f42, 0x000fb7682f77f3b6, 0x00008f8e17dae5ca }, { 0x000f98a2d0c72d35, 0x0001b2262a2f201c, 0x000f81558fe0288c, 0x0007a54a84d59ea4, 0x000094d0140957a6 }}, + {{ 0x00034de6ed85c687, 0x000eb39720943c28, 0x0004b642d2e37390, 0x0002c014aba044cf, 0x00009c5d21883610 }, { 0x000c0c6eeb0043f2, 0x000fc9a5f25bd125, 0x000a136e4386c89d, 0x0008c19769259cea, 0x00001522a51ab777 }}, + {{ 0x0008f8514711e5e4, 0x000de0f5606b81d7, 0x000494a0cd9e404c, 0x0004cf551abd7b37, 0x0000aae61990ee74 }, { 0x00069b8f8064759f, 0x000d4f0f30c3282a, 0x000000ed938b30a2, 0x00022f77f0da8ac8, 0x000034f8a1881bef }}, + {{ 0x0003840fe88767bf, 0x000b8176add85450, 0x00066f408b7e5e73, 0x000da5e771b71cb6, 0x0000d35c39b650e0 }, { 0x000174cced9e5822, 0x000b8d51ec699775, 0x0008df0a9a391539, 0x00071f40cae243fb, 0x0000e2156e1d8e4a }}, + {{ 0x0008e419d542ad83, 0x000d666e58ba37d6, 0x00020f33198855f5, 0x0004e44bffdcc8da, 0x000059353e915b41 }, { 0x000e22cd180b3421, 0x00018f402a403801, 0x000f01c6aaa43566, 0x0005abda688940fa, 0x000095b351fd3384 }}, + {{ 0x0006fb438a17556f, 0x000f9ce59ffc3e20, 0x0005bae3a15dcb2f, 0x00027446360aa1b5, 0x00007cd6cec33e6c }, { 0x000544607e7d51cd, 0x000b1c4500d8e20f, 0x000c112c7a91b2e3, 0x000e9affd1ad9095, 0x0000a60766068749 }}, + {{ 0x0007d49c6cff6daa, 0x000e9b1a20ef103d, 0x000f93d1bb0e184c, 0x000346aa0ad85912, 0x0000118d622a8970 }, { 0x000916a1f7d47a14, 0x000d88d20bb569d7, 0x000275e91a3c185f, 0x00072f067bd4b250, 0x0000837bba3c6297 }}, + {{ 0x0002546a940f5586, 0x000c37d53a4f5668, 0x00041560fd7cc5a3, 0x0003f20218973466, 0x0000fc85e2f5dff5 }, { 0x000a16ad6208772e, 0x0009d19c61ac1625, 0x000c51965fdc16c3, 0x00040bc4352f8fa9, 0x000086c395e5c1ac }}, + {{ 0x000644324f2ef32f, 0x000897f4faed184c, 0x000c89e5c21081c9, 0x000d382fc5f236b1, 0x0000323cdb72b7dc }, { 0x0000ed6d6bc3b8ef, 0x0002e595c5d84462, 0x0006f2c0ac0dca60, 0x000ecadc7c020807, 0x00002650966fe977 }}, + {{ 0x00067238b80e6e38, 0x0008219b6efcffc7, 0x0008214e7fc3fae4, 0x0003bf8bc60f12d6, 0x000005e6dec70c8e }, { 0x000a94dc7004d5b7, 0x0008221501b5d92f, 0x000ec80e9ac7e6f1, 0x00043be433279e3d, 0x0000bdaa02065868 }}, + {{ 0x000ae57d7389dc14, 0x000a01a530ccbbd2, 0x0006bf9cb7b1e9b6, 0x000fd790c87c8214, 0x0000c004262ed87b }, { 0x000d81a25c341115, 0x000e2bf3042a6dd3, 0x000fdbe2d8085f66, 0x000b98267b1a007b, 0x000031f1387a3dd8 }}, + {{ 0x000030f0a67c1e0d, 0x0005af8ff81578e1, 0x0000801453d6f902, 0x000e79d6f7862215, 0x00001e2caf4c2888 }, { 0x000a817bd311699b, 0x00004151f0bd7390, 0x0007dc5d42b22089, 0x000fde3982d7989c, 0x0000a862ef2d9f7c }}, + {{ 0x000a570c2107ac75, 0x0006330b0f2ac952, 0x000a80c9da2db964, 0x0007d589a48d0995, 0x000066ec9369c06f }, { 0x0005135ae5c22331, 0x0008bfd4e86214dc, 0x00020a4df9b2cf0a, 0x0000da66e2d014ee, 0x0000b652f2880073 }}, + {{ 0x000ba378872d98f6, 0x000313ad4f3049fd, 0x00030b64fbefd2cd, 0x0002deffdbb8e989, 0x0000f27faf9b53e7 }, { 0x000726e0841b2012, 0x000cea65a72f2cfd, 0x000ea4c375be3f8e, 0x000671a371208bfb, 0x0000a839bfdbb74c }}, + {{ 0x0003b681d32f73b1, 0x00029a5061f16587, 0x00016b5650dfe8e1, 0x000c99fdec0016df, 0x0000ea7e61216b53 }, { 0x000fc9eebda36ba8, 0x000c5c43ac343c03, 0x000d45a775638b98, 0x000ac46d49c847e7, 0x0000844582f5d365 }}, + {{ 0x000647b7837876bd, 0x000ad727fe02299e, 0x000143077b95970a, 0x000cf08be6335ccc, 0x0000f0ca4f1d1bce }, { 0x000627278ca4b059, 0x000f0de02cafb8aa, 0x000f569bc5401d7d, 0x0005e2982299bc2f, 0x00009199192015c9 }}, + {{ 0x00058f5c2f9e22e4, 0x000b3337933e47b6, 0x0002c8e707d309be, 0x00021299ff4ff6b1, 0x000037dd6c45dafa }, { 0x000ca95dd4570da3, 0x000b377c95b3b3ec, 0x0008648e592b39a9, 0x000b6d929fa04426, 0x00008591df48c6ec }}, + {{ 0x0004d3be78cdc4c0, 0x000cba42333fc4c2, 0x0008d262e3383d84, 0x000588b2e274f8e6, 0x00001215944a8491 }, { 0x0006a7c58ef9ec49, 0x000af58ca14f530f, 0x000264f068c28b49, 0x000f57662a6e7f16, 0x0000a687c108833c }}, + {{ 0x000f323c80b194e1, 0x0005603f9374ab69, 0x0004cf2404c4a6aa, 0x000bd8c50864f919, 0x000016461ee3c770 }, { 0x000be0fe51bd269a, 0x0000dae3f046a9a9, 0x000e43a90548ed71, 0x0008371a670da183, 0x00007e7cae92ca95 }}, + {{ 0x0003c2f435522de5, 0x00099b6cbc613e57, 0x0004d5bbb1e76fb3, 0x00050f9d533131d5, 0x0000500dd4c4695d }, { 0x0006451f5801b985, 0x0009f93a4a375fa7, 0x000c41eea66a4aeb, 0x000b4eccf5f06787, 0x0000be0cc26ec73c }}, + }, + { + /* digit=17 (1,2,..,64)*(2^{119})*G */ + {{ 0x000274dcf1b355e8, 0x000d5ef694db7e04, 0x0007778800d4cda3, 0x00062f4e1edca878, 0x000092c279274250 }, { 0x000be2b2abb3de8a, 0x000b9b86def6d1a2, 0x0000bff865bb4348, 0x0002de558d25b167, 0x0000a14c44f5e051 }}, + {{ 0x000da4a7963ed790, 0x000cc9dd111f8ec7, 0x000d3a203fc9ff36, 0x000619a51bcc33f8, 0x0000c3316282fb7e }, { 0x00058ffec2ca8e3f, 0x000cbe30bb1151be, 0x00071d53238e4f7c, 0x000c05f7854febac, 0x00007acf3890bf9e }}, + {{ 0x00074fc72746a6d0, 0x000c2fcd1e0cf9e1, 0x000da997ebc1b1ae, 0x0008e884edea75f0, 0x000051ef991ea87a }, { 0x0007fb62f575580c, 0x0006c77eb930beae, 0x000a76b4c76571cf, 0x000cc0f9b504cacc, 0x000049875ab2027f }}, + {{ 0x00066adbf6bb7535, 0x000ff9d29c4120ba, 0x000f1a65fd1f4042, 0x0009b85519f94391, 0x000007d911a8b098 }, { 0x0008234499aed7de, 0x000763c34bfca38e, 0x000fd1be8863128c, 0x00048439ce0f2755, 0x000013608ea8ba39 }}, + {{ 0x0000cbaad6fa0860, 0x0002b769d4c54230, 0x0000af867172d5b0, 0x0007ea0a19e56eb1, 0x0000613acac087c4 }, { 0x000d6254b0899ec5, 0x00036ded92a5e67d, 0x000b41d22a615f85, 0x00021935bca4979a, 0x00009335529dd4e2 }}, + {{ 0x000b6304a752fd49, 0x0007c13516e19e45, 0x00076a61d0ec2826, 0x000e9d5f656e2e84, 0x00006c970cc1cc09 }, { 0x000935381bb3523e, 0x00069363ab7e433f, 0x0000053ef767b2e6, 0x0002d839f1adea47, 0x0000b39a71be38a8 }}, + {{ 0x00035142c413720c, 0x0009f2d799e9a748, 0x000e25f8b46540fc, 0x0001df95a96239e0, 0x0000745a4815a75d }, { 0x000856e0e8e441ac, 0x000ba7aa2e8807fe, 0x0004324cf2b5bfc3, 0x000bac6f529f2c08, 0x000024c840287b5e }}, + {{ 0x000cb10d572b5962, 0x000ed9d918e49366, 0x000645a02c2b89f6, 0x000f43ab965035ef, 0x00005fc3fbf56b43 }, { 0x0007c7032b9ad449, 0x0000eb7a242da112, 0x000d3f646f3cae05, 0x0002e606b16a4d3d, 0x000066b08ba950ea }}, + {{ 0x000b92420a9f510e, 0x0001d18e4136a147, 0x000cebfbf0b51e6f, 0x0004b2e03bacf969, 0x000059ed4c55993e }, { 0x0008945e1eb1c203, 0x0001c78c64d565c0, 0x0000085e247722f2, 0x0007b021a9f969d0, 0x0000a495ad2457ff }}, + {{ 0x000fa003d16724c1, 0x000aa7d5846426f7, 0x0008a4dd404bee11, 0x0004afe48e7d09e8, 0x00004e388ffd7c0c }, { 0x000d40da8e2b1cbb, 0x000a64f17fd95965, 0x0000d88abe4cfada, 0x00066ec6a49e0e0a, 0x000085fa4175ed03 }}, + {{ 0x0002031717ee94cd, 0x000f705050bad247, 0x000d50a7310c0423, 0x000ee98a78918426, 0x0000a7a77c69c5b4 }, { 0x000fd7cb763dc643, 0x000939960a94120d, 0x000d09c6e3764d3a, 0x0009a67fd478a255, 0x0000291d53e1e931 }}, + {{ 0x00089bc84468e031, 0x0005ab4a595939dd, 0x00084fd839d2cf16, 0x000cd45120355647, 0x0000a31eb877381b }, { 0x00012d8643774d44, 0x000965d85a9184d6, 0x000b3e932a3180a6, 0x0003d448e562563b, 0x0000bf1cf2a46781 }}, + {{ 0x0000885735dbeebd, 0x0001ea7f64085e79, 0x000399222ddb6a70, 0x000b41488b230f30, 0x00007e9e9ee9f0f1 }, { 0x000cdbdf44d9a14c, 0x000b39a652f54f6d, 0x000382d24cab9561, 0x00054a2e365c8229, 0x0000b474dc1a9b89 }}, + {{ 0x000d03d7d3318572, 0x00049a354530bb24, 0x00077e0492176e2e, 0x000bd9f63bde3ef7, 0x0000086e3e2a72d9 }, { 0x000280da9fc53e22, 0x0002d9e43b6a782b, 0x0006ea07cbe66e70, 0x000c1cbd9216db30, 0x0000dfa49ad0403b }}, + {{ 0x000fd508e7dab215, 0x000b68a1635e7417, 0x0009f8e8f9bf57f5, 0x000c8cb30fe14008, 0x0000d09a8cbf4c40 }, { 0x0000c96743cb7c12, 0x0002019d607ad51e, 0x0009ac772f06a74c, 0x0000b7ba20f229c0, 0x0000c906956df251 }}, + {{ 0x00048234a455944a, 0x0003c913e538cd75, 0x000c398678aeeffb, 0x000c8cbffa7001f6, 0x00008153cadc4269 }, { 0x000cbd665cbd5dcd, 0x000d02d3d5b40458, 0x0005bdd2db3441fc, 0x00002b28bb0ffeeb, 0x000086864413478b }}, + {{ 0x000230378fd7d8e6, 0x0004ee0425830687, 0x000b81c6aef3b01f, 0x000e83c4802da2ae, 0x00008bd11eeccd2d }, { 0x00084d402dbd9f8e, 0x000f2b571e8e5cae, 0x000bcb68e4f6d61d, 0x000fcc72e53ab041, 0x000092f0d852e5ae }}, + {{ 0x0007fbf56c3f426c, 0x000c973f37f59371, 0x000db9e90739643c, 0x0004844fceb0f6c7, 0x00001850ac1be86d }, { 0x000ae327a65859cf, 0x0009cd9acf7d720d, 0x0007353f1fbfd5d5, 0x0007b6cef41fc8f8, 0x000076cef0bc0d2d }}, + {{ 0x0001699a1c4e7ed0, 0x000d065c48182672, 0x000b165821a51c51, 0x000ba5a9233aa189, 0x00000691ac4135d8 }, { 0x00081497d823b2a6, 0x000d19cc2d7a7fda, 0x0008f1b3a51aa96d, 0x0000e12c7e318605, 0x000025170752334f }}, + {{ 0x00044990c52f624e, 0x0000e891f5f82dce, 0x00067f1776d921fb, 0x0004105309a7f67d, 0x0000dff3f33f1de2 }, { 0x000830f09a7edeef, 0x000fe95af103e596, 0x0007257ba1c748f6, 0x000b5c9d3ece8aba, 0x00001dd530aeff14 }}, + {{ 0x000520304e191d19, 0x00010b488172d014, 0x000585df6db40bed, 0x00089199a8b20bd6, 0x00006e8ca44ed0cf }, { 0x000244c2cdc93ee2, 0x000f81f2b47f7ef2, 0x000839bb0272e506, 0x000261674e07f528, 0x0000069e938f3b6b }}, + {{ 0x0004b043a81d5e7b, 0x0009fc194d7d9b17, 0x0002537e3b6f2665, 0x0007b94ca5bafdd8, 0x00005587b44c1942 }, { 0x000143bdc27d5d11, 0x0009ea19e71734c5, 0x000e4b01516bbe49, 0x0008531b115d5437, 0x0000847671d73bea }}, + {{ 0x000037543bac95c5, 0x000c653fc5e89202, 0x00087a6599cca795, 0x000b2a908363bf9a, 0x00000d8e95cfd516 }, { 0x000badceac56e4f2, 0x000cacc625640b46, 0x000e20185d8f1a24, 0x0005a34eacbc1051, 0x0000d0e37c834129 }}, + {{ 0x0003505bb870eafa, 0x000d47c6b53f5f95, 0x0004c7c711e131be, 0x000710e1b6424659, 0x00009ecec42b7e48 }, { 0x000febceda1c9c8b, 0x0001361f2ba70b0d, 0x0008ab0f057922d3, 0x0004ebf6ad07e16c, 0x000067dbc750e1cb }}, + {{ 0x0000e4587f5ed835, 0x000a7dc53868c8b3, 0x0002077caf2733fb, 0x000c31964174311a, 0x0000356efdbcfd09 }, { 0x00003d37200e52c0, 0x0002a310811b3b2d, 0x000c3c910cca75c8, 0x00047b8036144d41, 0x00004f8461ce611c }}, + {{ 0x000602500ca3dbe7, 0x000f0f2b1f3390b4, 0x000c5fb3c266229a, 0x0000540a99f7a1b8, 0x0000cbac9856bd1f }, { 0x000289eb1fd8ddb6, 0x000c11c4711230f9, 0x000b6f851ea1a62b, 0x000082d8b058eb37, 0x0000dff1bd082c26 }}, + {{ 0x00009e4ea0d957a8, 0x0009eabd51b9cf59, 0x00020e62d30ee577, 0x000b61a74d2aa9c0, 0x0000dc7f6451320f }, { 0x0007e947df046bb8, 0x0004c966f32dbdb8, 0x00000319c35fe24b, 0x0004a5fe2672188a, 0x00007d6b8255d4cb }}, + {{ 0x000f11c4d76b7c46, 0x000e5391770f5a7b, 0x00004f3326ab38d0, 0x000ed2b2ae4d4d79, 0x0000e4ef511e46d3 }, { 0x000a61e28b58878e, 0x00065e542c4224c6, 0x000bda3bb1915d60, 0x000c95a78d6b4e81, 0x0000df4b98688afb }}, + {{ 0x000f0956569ac4ed, 0x0003394e6f1cd952, 0x000cde0f10e89862, 0x0003727647512f30, 0x0000d19eb33b73c0 }, { 0x0003d7563e475d5b, 0x000eccaa82262004, 0x000cd6e91d2b1111, 0x000b651be02c868a, 0x00008a5278bd077e }}, + {{ 0x000c20578305b14e, 0x0004fc7ab952578a, 0x00017ac7f5884f29, 0x000d5d242b5423df, 0x0000620247456895 }, { 0x000f807ef9d65a21, 0x00075eb21f4c77af, 0x0003ab31f4b5799c, 0x000dc92f11a79c3e, 0x00007300963434bd }}, + {{ 0x00011afff4ca371a, 0x000d03d778f22a00, 0x00085a437474b875, 0x000e1d47dfb10b2e, 0x00002489cd838b5d }, { 0x00011554104be448, 0x0008926ad124418d, 0x00051618d54f49c2, 0x00010937531c081a, 0x000071b18a1c2aa7 }}, + {{ 0x000d41f01735a335, 0x00073f833f6746cb, 0x00054167a0b39250, 0x0003a7ba921e46f6, 0x00006c09c11aae95 }, { 0x000d59e95785f38c, 0x000b834426ffb589, 0x00057781d8acae7b, 0x000a30f7f8055943, 0x0000f1dc76c3a6d4 }}, + {{ 0x00008d0596f30cdc, 0x000bb1c8ad4cf4b4, 0x000fef6e8a21fea3, 0x000272fa40344885, 0x0000efa2f182a572 }, { 0x000acd518b235195, 0x000f9a498c364b09, 0x00046a51392ac475, 0x0000bfb02a4aac4a, 0x0000e0426618d525 }}, + {{ 0x0009dd82ce983ea9, 0x000bf8fd06f56c0a, 0x000d3524f6a44c8b, 0x0005bb79da48af70, 0x0000dc57803535c6 }, { 0x000cdada016942b8, 0x0001263a0ef18d34, 0x0004f091c9bc1fc1, 0x000b1c5039fb7ee3, 0x00008fc41c7e9b42 }}, + {{ 0x0005a0cad09fcdc8, 0x0006f499355a244c, 0x0005898086d8b232, 0x000e727cbe77fd2b, 0x0000f5438a6a25c6 }, { 0x000338ecde1a98b7, 0x000475cef8118650, 0x00089b6cdf5ef5b6, 0x0001cd6bcf52813e, 0x0000ef9cb64dfe26 }}, + {{ 0x000e182e702cbf4d, 0x000093774921592b, 0x000cfba36ec1cce1, 0x000dd0759b4f1261, 0x0000c2c3bb484721 }, { 0x000f11d5488868ed, 0x000c37cdfc50573d, 0x000983acb7fc4b3a, 0x0004278d39ba1afd, 0x00004a4526ea82ca }}, + {{ 0x000db4207965c6e3, 0x00020ee02a2404ab, 0x0003635469f7a3cd, 0x0003dcb71497406f, 0x0000db415a568fea }, { 0x000e3be64146ee7c, 0x000270fd88284423, 0x0007be7a06dae484, 0x000b58415283add2, 0x000031007377bf1f }}, + {{ 0x000b74b0ed03932d, 0x00050c1e038a6759, 0x0002f0e7b233a87f, 0x00079ff53729deff, 0x0000c01ffe0be7a5 }, { 0x000184c1d9aaf43a, 0x0006c23dab407e5c, 0x0004b52e7eecb1c1, 0x00033ff2ccdbd361, 0x0000098af3b980d2 }}, + {{ 0x000904bdbb6109f8, 0x000571981d3a80f5, 0x00016fdb66776216, 0x0003fe8c1fde0c84, 0x00002e8025758320 }, { 0x00011469a106add9, 0x00044d1101b68053, 0x000c189603a82a4e, 0x00069678743c223b, 0x0000a9746fe0a073 }}, + {{ 0x00021ed0b2fc0d23, 0x00093845e43fc616, 0x00057eb4daa4b57c, 0x0000afaa8f328237, 0x00006ae9919db4b5 }, { 0x0003856ec86c297e, 0x0000fe1ad9906763, 0x000b234fd19d2eee, 0x0000f4401d51de67, 0x00002462d036fc09 }}, + {{ 0x00033a00db254686, 0x0007615be6cdcde0, 0x00039bd26eadffdc, 0x000f7aaa61e603f3, 0x0000199ba172e7ea }, { 0x000eef4c32c845b6, 0x000ee09f7bb7fd76, 0x000dd73dccc40b89, 0x0003a2c9570f8781, 0x000026152e934da0 }}, + {{ 0x0000ea7d6756508f, 0x000a13b2f7e85c33, 0x000140ae12343058, 0x000e81db55fce462, 0x00007980f96d8f6a }, { 0x000a553d4d7f0b2d, 0x00088f4e51ab9a22, 0x000a83b13f2b7013, 0x000bf6fa60587c98, 0x0000a508840aeef8 }}, + {{ 0x0000b460d07f52d4, 0x000ae364da29ec28, 0x0003391112464836, 0x000853947dbdd5d1, 0x000061c41be19aad }, { 0x0005f292a360f3f1, 0x0009babf963c31e5, 0x0003765aa05a3770, 0x00003d58767f9f63, 0x00004a15f588fa9d }}, + {{ 0x0003283f79a5eaca, 0x0009eb2cd21ab3de, 0x0001e06b9418e3f9, 0x0001670f9e504f02, 0x0000446de46c5aff }, { 0x000101dc7671519a, 0x0009bf6226bf99fc, 0x00034d2741f38239, 0x000ba7c2de835427, 0x00003411b6f79f40 }}, + {{ 0x000e01db0d46ca69, 0x0004bc2255bd6178, 0x0002de28b6473c59, 0x0009d2a876c96969, 0x0000307faee6531b }, { 0x00082ca080d00c87, 0x000a173893a55595, 0x000aef7740c863b7, 0x000c2aef87630f04, 0x0000b32db7ee850d }}, + {{ 0x00037f9c22a738a4, 0x000b2e10b1894a02, 0x0001b49ccc9d8538, 0x0007871b59203400, 0x00001570db64de21 }, { 0x0009ed518775904d, 0x000a62f4470e2c05, 0x0000fed0fd0d9912, 0x0001e0763b725f7c, 0x00008b2ac0c6733c }}, + {{ 0x000b0b081e23ebf4, 0x000ff16d0115d4d7, 0x000f585e0d7bd2f4, 0x0009316415180b12, 0x0000ddbe5f1eab2e }, { 0x000974e2b1e03fb6, 0x000f48abf4f0dd06, 0x0006e3b043e48d7a, 0x000b8aefe99b289c, 0x00005cf08248acfb }}, + {{ 0x000d737e72363c9d, 0x00021e206ddd6572, 0x000102802afaff9f, 0x0002f4a58e7cbdd1, 0x0000cf910137f5d1 }, { 0x0006f52b1e708142, 0x000696286ec37766, 0x000d2d6a7c82ef02, 0x0006dc73398aa649, 0x0000cffe04031902 }}, + {{ 0x00032721221eeb7a, 0x000defbd803738b6, 0x000781c149828000, 0x000c99a9291aaade, 0x00009626df3ef586 }, { 0x000571b8055894f6, 0x00032f0862c51290, 0x00092dafec9b2579, 0x000acd28f0a8f79a, 0x0000403590545ef7 }}, + {{ 0x000f5f638ebe18a2, 0x0002adec95207114, 0x000ced2c21311398, 0x000e6511455a9e4e, 0x0000ba02dffbaae3 }, { 0x00017596079bc6ae, 0x00070d32bf9341bd, 0x00007bcd3fa21e63, 0x000a719c5d63c132, 0x0000589ce7628195 }}, + {{ 0x000076bc4095656c, 0x000b41ff9e6ed353, 0x000536bfd61a4343, 0x000f2aef7b7b5ee4, 0x0000916f72ab7c03 }, { 0x00070cb65edfe066, 0x000638c02dec312a, 0x00077c8115197531, 0x000bba2c9270de89, 0x0000cc65c87f3d73 }}, + {{ 0x00032e89869168bc, 0x000050ecfe57bbde, 0x00055272392f1fc6, 0x000b3abbd82c7b65, 0x0000528c02084684 }, { 0x000152ce2cb419fd, 0x0009744d11a5529a, 0x000182d52bedc6a0, 0x000877a0ae964ed0, 0x0000f927ef680070 }}, + {{ 0x000871bfa5e6e0c7, 0x0008ca48ec07649b, 0x000f8d2c14ad8a64, 0x00083ea1018b4c28, 0x00004818a1be6e94 }, { 0x000b0cdf9b0c7f86, 0x0008ce59e2e3c9b3, 0x0005099db15ba9f1, 0x000d40a06fbf250e, 0x00000ac8ed941db0 }}, + {{ 0x0006facb0812925d, 0x00042eaf8c511875, 0x000c1d23829fdb64, 0x0007ee64505bb67e, 0x0000b90376a129f5 }, { 0x000841357c4ddd34, 0x000d3e98f6229e49, 0x0003ba2e8493a602, 0x00056697962d103f, 0x00003d04cfbd7b62 }}, + {{ 0x000750cc3c1a7b0a, 0x000b159c34e67058, 0x000af889dc10e012, 0x000957b37c3c7180, 0x0000968c82b0c089 }, { 0x000d86dbd34a175e, 0x000689db7275d7d1, 0x000b10d2d7166c05, 0x000b45693ffa0168, 0x0000abf693ace924 }}, + {{ 0x00071b360f0679b7, 0x0005467e28ef5ba5, 0x000973fdab5aa7a4, 0x000f206202c9a469, 0x0000e0be2b8f2417 }, { 0x0004bed023283151, 0x0009958101c1d454, 0x000dd3c9342fa56e, 0x0005c83466651788, 0x0000f38d09a711f7 }}, + {{ 0x000343b5fb200f96, 0x000952d33da525d4, 0x000dcfd099dce93b, 0x000b1701df193678, 0x0000ef95773ba9d4 }, { 0x000484d4e14aaebc, 0x0006771638127137, 0x000d82dc48b25dc1, 0x0007325d747bf6d2, 0x00005e1c9c82ab72 }}, + {{ 0x000c8d3645c866b0, 0x000beea60dbac1fd, 0x0003fd796cb1baa7, 0x00063a35b23d8c48, 0x0000e075408e6a88 }, { 0x0007c5425467d1b6, 0x00043fab12177b4c, 0x00038b881b47a89d, 0x000d9800bf79bf46, 0x0000a2c54416f53e }}, + {{ 0x000a0d41b10e0cdc, 0x000c447e5911a766, 0x0007fa71dd36a5ba, 0x00049cf4261ffa5c, 0x000079b9ae6dbe81 }, { 0x000e89e390495427, 0x00042f5cc30d3577, 0x0000ece8db061fa0, 0x000e6ad61be9adf8, 0x0000aae7a36a6e46 }}, + {{ 0x000c6cb4fe4e3e7e, 0x000afe5facf69d43, 0x00060b087f4ea2b9, 0x000a4ef04363b7e7, 0x0000a37a66bc1464 }, { 0x00008b945060128f, 0x00034394008e1f2c, 0x000964139e1c25c7, 0x00079cf065e9a85e, 0x0000f97bbcc0ba07 }}, + {{ 0x0003879cbfbabf2e, 0x000922c89f71f0f1, 0x0001ebb607012381, 0x000532fedad8f3e3, 0x000042e5dc9aab87 }, { 0x0007a589356da4cc, 0x00048a56b306a0b0, 0x00065fbee32901a2, 0x000cd9768359c2ea, 0x00005460cecc0d99 }}, + {{ 0x000dc35c554b2226, 0x0003bd168754ab0e, 0x000c817f3e20d9b4, 0x0006ac169801fce1, 0x0000801dc7720a5a }, { 0x00096d0960303067, 0x000c06fa3f660d1d, 0x000ddf8f6807ba00, 0x0005d49aea0184eb, 0x00007165e44fb9ed }}, + {{ 0x0003109d80d2b121, 0x000e1b5f8c2a25b9, 0x0008728167361b42, 0x00003c24c1bb772b, 0x0000da906c6e6147 }, { 0x000cc31b47879cf5, 0x000d7f78ef59fb59, 0x0001eb43ee1bcd5a, 0x00056c59b3b438fe, 0x0000d98902a011aa }}, + {{ 0x00097ba641eb7f97, 0x00074a9b733aa5fc, 0x000b26df4bf350af, 0x0002ceba5dece47c, 0x0000cc1ae7e7d3b7 }, { 0x0007fab43b1d99a8, 0x000ad0409c110608, 0x0004beb49cf2a615, 0x00058d94656ea2c0, 0x0000cf90618174d6 }}, + }, + { + /* digit=18 (1,2,..,64)*(2^{126})*G */ + {{ 0x000b433b59bb0813, 0x0000341d4c5105f3, 0x000e323c820b4e81, 0x000deaab01ae80f8, 0x0000ba1d2bfa0603 }, { 0x00002fefd81e661f, 0x0004eb693e856387, 0x000273b996572680, 0x000f613ecf7b5925, 0x00002889ae807f47 }}, + {{ 0x000e89f3d33e658c, 0x000bb5d0fefb0c3a, 0x000a984dcf89f8ee, 0x000d20ca4d48fb56, 0x0000b9304c4e5ff7 }, { 0x0003083bb07dcf66, 0x00023c86363d14cb, 0x0000b4a396cd193c, 0x000063a218981752, 0x00009e66befec3c7 }}, + {{ 0x000047f6491b324e, 0x000f3debe949a447, 0x0007e422595c1d64, 0x000d22ddc638e938, 0x000012ead0995384 }, { 0x0007d3336dfbf8ab, 0x000df9041fbab170, 0x00084f98a83458eb, 0x0003252dcda8e0b2, 0x00002ddc2d664ecb }}, + {{ 0x0001d587d483a8ac, 0x0001644bfe209256, 0x00032e076092df00, 0x0008fc46391c19ac, 0x0000ca7c69ca0159 }, { 0x000a11fe134033ed, 0x00086a2a37173eaf, 0x000759658d52a842, 0x00086c73e2384800, 0x0000d0571a330ac5 }}, + {{ 0x000b0b43fae02d19, 0x0005e2e81685d7b3, 0x00018429657b244e, 0x000322fef23f27d8, 0x0000be6797dde7b1 }, { 0x0000b732a6bc6506, 0x000f52663ca72840, 0x00041c968590b9ae, 0x000d64c6b7f5729b, 0x000078435f1bf19b }}, + {{ 0x000b01ea6b5b07b3, 0x00041262048e3968, 0x0005ad3bb37932fb, 0x00016d2ad436b50b, 0x000041c792fd15ec }, { 0x00054b52698a8d32, 0x0007dee97015c07d, 0x000878f05045493a, 0x000466fd246cdf1a, 0x00005d2f84c497f9 }}, + {{ 0x000f1bc8463a493f, 0x00090304e23e9bca, 0x000563526dde04db, 0x000c22e614387f81, 0x0000c1b1d1e0bd00 }, { 0x00058493c7b7d8e9, 0x00018ba527de79c6, 0x0003dcdd27ee6deb, 0x000a262c70e1346d, 0x0000f69deb198370 }}, + {{ 0x000617ff6bb8909f, 0x000aafeb8a24a205, 0x00019f14a5d36b68, 0x0006aa95317ebfed, 0x0000c8fde1bb5304 }, { 0x000967ce0fa78f8e, 0x000a6c5e3c99ebdb, 0x000d5e1c475a7c8b, 0x000cdd9dffc64242, 0x000020302e081fc1 }}, + {{ 0x000d6c2966703b01, 0x000365121c80b5d3, 0x000c65b2a339f5a0, 0x000fd9f7e2e7a563, 0x0000bb183ed3e7e1 }, { 0x000a43951972d8ef, 0x0008e1aaf70b8855, 0x0008d324cf4076c4, 0x000efcb5bafc3bad, 0x0000bcb50e192c99 }}, + {{ 0x00087e191f93cace, 0x00049a85fe4e3142, 0x0000d43a775064ea, 0x0003b4d23e60234d, 0x0000bc6b31f78d5e }, { 0x0002da4b5432efe0, 0x0009ddc09d877d88, 0x000b918d3decee95, 0x000f07ea41c23478, 0x0000526c06550283 }}, + {{ 0x0003639eb906c44f, 0x0001891fadb86087, 0x000d08112f3df08e, 0x000f4bb34049e832, 0x0000c537963213bb }, { 0x00072064455862d7, 0x0005c1fe1e4a71b6, 0x0003195294d3f757, 0x00004b9326ffd6b9, 0x0000135f9599d70d }}, + {{ 0x000418871e270c0b, 0x00029a3b23358342, 0x000a6cd6e14299eb, 0x000d6b00d9526205, 0x000018ce7f6af8dd }, { 0x000fdb3c22d19812, 0x00064814082c1576, 0x000fb9e6c451057f, 0x000efd528cc914ac, 0x000020534397c913 }}, + {{ 0x0009874445537fd6, 0x0003ea6f2f9f8e93, 0x00031665058cdd50, 0x00085d2d9963ece2, 0x0000dfa018b78042 }, { 0x0000899785dc3ccd, 0x000326512bf476a1, 0x0007f945e60b257a, 0x0008189ca598a64d, 0x00009ba39facc3b7 }}, + {{ 0x000b8bc785ae777b, 0x00017fd02eee3ad4, 0x0004e4888aeb0a29, 0x0009b3b75a86b3d3, 0x00009495294c40d6 }, { 0x000cd576bcde4c88, 0x0009754413f9cdef, 0x000e2ed5dfa79ee3, 0x000736423a5e4fb4, 0x0000c8fea236703e }}, + {{ 0x00088fe5f08c69ad, 0x000d03e83731a34b, 0x000e34f3889d77d8, 0x000a91d7c2bb9028, 0x00002a8744970829 }, { 0x00069e9172abed8b, 0x000e0c6edea4eb34, 0x000301f05b05123c, 0x000837be143b9313, 0x0000a5596eeef405 }}, + {{ 0x000e205c1544399e, 0x000710441c23fa36, 0x000053783e19700e, 0x00068fea7b4712eb, 0x0000a112e4fbfa4f }, { 0x000514d89ca1abfd, 0x0007c57b36416860, 0x000d4097b2b1ef2f, 0x000a206500432691, 0x0000b3a43e7e1054 }}, + {{ 0x00090d4325fd9679, 0x0009b7fa8e67fc38, 0x000b22134298196a, 0x00091d5579e2e0b8, 0x00008a49ee4dfeae }, { 0x000a54ce4da649a5, 0x000b96ec55e68a39, 0x000aa8e4fa0ce432, 0x000d91155bf12e90, 0x00004d3d79423852 }}, + {{ 0x0008a43035135501, 0x000e73af1a142952, 0x000c89e1a4c4c49f, 0x000aad9ba916f955, 0x000087d02c81ab86 }, { 0x00053db5fc807a2d, 0x000d2a2b8a9cef88, 0x000e34ae4f1d89bc, 0x000eeb9725517407, 0x0000f797b5d79a69 }}, + {{ 0x00061e9a4969a240, 0x0000ba9e864a51ae, 0x0008886b8141b7a5, 0x0006fca286c26769, 0x0000240005dbdd2a }, { 0x000449c2ec4a9e15, 0x0003b039f84216d6, 0x000748fa0a993339, 0x00074b159ab020d0, 0x0000997a8c005c8f }}, + {{ 0x0008a5b251a46688, 0x000c41c2cf9d7c1c, 0x000a25f0335a2815, 0x000478f0c1320886, 0x0000b3973c66051a }, { 0x0004dada9450a7b7, 0x0005d32c11d23031, 0x00020a289c0afe30, 0x000abe1287da6691, 0x0000967694826933 }}, + {{ 0x000c3bd859c92095, 0x0002e217ef6b0d15, 0x000a205766c8c264, 0x00023768252a9477, 0x0000b7cbdb2f3134 }, { 0x0000ac583b4bc642, 0x0003ef5f22c2d3e6, 0x0000570f148a45c5, 0x000cf5f1c368d504, 0x0000aba17b2c65da }}, + {{ 0x0009f147f44133d1, 0x000ea980eab2437e, 0x000474350cd3f048, 0x000a45f7f8cc08c5, 0x000087556fee2ca5 }, { 0x00043f23a09ea234, 0x0004914d2fd6cf16, 0x0003c910a80fc0fa, 0x000d10df7a3ecd06, 0x0000fce7e70f4fef }}, + {{ 0x00085c4a77db6510, 0x00068abe65ab743f, 0x00003d917e24f825, 0x000a8e568bf7c75b, 0x0000f920e13ab677 }, { 0x000d8f276467f157, 0x000feb2e68acf374, 0x000d5da38820e4a7, 0x0006b9d93a544df3, 0x00004f65f0f3913a }}, + {{ 0x000ce5870a0c41fd, 0x000faaaf0dcbc49e, 0x000883d62d516f72, 0x000eaa5e57de551f, 0x0000f8ef2d69da92 }, { 0x000ff5e2f5425d4e, 0x000c0dd167d79ae1, 0x0002da879bcbf034, 0x000d36191039df8a, 0x00004f16c971cb78 }}, + {{ 0x000fc8cc32aee2fd, 0x000a3396ea51d668, 0x0004f0b4adf36311, 0x000779e24506c144, 0x0000d07ff487d2c6 }, { 0x0003173d2554ae54, 0x000d94d9433d67d1, 0x000f576695712eb5, 0x000cd8a077fa5cb8, 0x00002098fca8b646 }}, + {{ 0x000723c7f687405a, 0x000ff9dd5b340fff, 0x0006b9daaecf62ef, 0x0004f00dcfc6b529, 0x000082ac85fad224 }, { 0x0007febee863592d, 0x00096219773d4025, 0x0002c3531e5edeaa, 0x000d2b53cdf7c6aa, 0x00006f48a45191f1 }}, + {{ 0x0005d48ee54627c0, 0x000fee47bd8e7397, 0x0004388f30907fc4, 0x000d3c92379d4499, 0x000014e6df0129f2 }, { 0x000bb8f6ef5589da, 0x0009daadb5cdf33b, 0x000580b07079ffc5, 0x000738d4e3396e89, 0x0000d3c9aebf037e }}, + {{ 0x000aee99a83de201, 0x0000551cbae2f701, 0x000578bc0f4313d7, 0x0003bf399efc4bc0, 0x00004db1c0ede19f }, { 0x000c5f317b20b8d4, 0x000b1b9ae8274c57, 0x000500d18221751b, 0x000091b816c14d44, 0x0000685f584b909c }}, + {{ 0x00037932990a975f, 0x000b1754ef442271, 0x000ec8a7c1fcf689, 0x00000f4cda17bed6, 0x00008003fe108b77 }, { 0x000ac3793bd9befd, 0x0003378dbbe307b4, 0x000e2c2b1ffa6260, 0x0007dad206dd1c20, 0x000049b2e9cf1b68 }}, + {{ 0x00013eddb15b9981, 0x000b7ebed1f8ca0c, 0x00078d7c47f137aa, 0x000d0086f3e54665, 0x0000ee5e70525d64 }, { 0x000020737111ef2e, 0x000f24fd49eb8f61, 0x000cc72ea2ff6814, 0x0000cd758d0d5bdf, 0x00004f38669d1545 }}, + {{ 0x000ed13c9ad8f9ee, 0x000f8900647a82b8, 0x0004006ec8b4868d, 0x0008b4a03908e0ed, 0x0000ecf41ee539a0 }, { 0x0004380e0ee30563, 0x00093761f460f648, 0x000ab29855275b29, 0x000bf349b53930b9, 0x0000a5933dc89dac }}, + {{ 0x0003bc3770684e62, 0x000ca6bc4fe3c395, 0x000318bfb46f7b63, 0x0001ad259ba4a815, 0x00008206cce146bd }, { 0x000c2731bc0908f4, 0x000d4ab5afc60db8, 0x00049492c0e73d3c, 0x00006d107aa02235, 0x0000a2cf845790c5 }}, + {{ 0x000e83daed4291aa, 0x0005eab18a0339d4, 0x000ce8b1687fb104, 0x00007814fac7a658, 0x0000c1a639fa1a8b }, { 0x000721d740a55e87, 0x00040be2f39ea3e5, 0x000f598395ede4d6, 0x0007ef938ef0c005, 0x0000b5b0afcf29c9 }}, + {{ 0x000530a00b6f6334, 0x000e111fbeeee1be, 0x000309ec6bf9af40, 0x0005d4935d1ef5e7, 0x00009dcd3183c604 }, { 0x000632a3a250e986, 0x00031fef15ebfb03, 0x000c9cefa5780c6c, 0x00071ac37549de03, 0x000059126cd86023 }}, + {{ 0x000f033918a2c159, 0x00061890ef59f78e, 0x0002dae1f2816a7a, 0x000a1bb470dfc644, 0x0000c8d185b680cf }, { 0x0003bfaab3be88e6, 0x0008d5db13839481, 0x0002ad1dd2c94e09, 0x000b5ea68c1fc29a, 0x0000900f4ef1e381 }}, + {{ 0x0007640487bdae6e, 0x00058a90deeaf523, 0x00021500178d835f, 0x0001696c4b003fb0, 0x0000fe99cf01049e }, { 0x0002f3acc9ce3d00, 0x0001bc6222a77da2, 0x00073b543e47375c, 0x000de432c62260a5, 0x0000b372f8b94a23 }}, + {{ 0x000e8055d0741a6d, 0x000dc228e41d155c, 0x00076c40041ede78, 0x0006dd7114d02456, 0x00005f55ba2e84d9 }, { 0x00009bcf6bd46086, 0x0004baff62045490, 0x000ec66a97edf917, 0x000123c29a0a00a3, 0x00001c1ad528832e }}, + {{ 0x00017eca6dedef2e, 0x0000aa822305177a, 0x000e9fe591513c37, 0x000b875c0d51d59d, 0x00005bf481a68fd2 }, { 0x00042c3114902bd5, 0x000b2ed60d9dcec0, 0x00011c80f3407b8c, 0x000452dbad6d28e5, 0x00001d77ed06f416 }}, + {{ 0x0004dacf96735388, 0x00012c58aa68e305, 0x000bbfa881a889b6, 0x000da070c7a6a3d7, 0x0000eb1e4523df46 }, { 0x000d0b1e0fc6e9e4, 0x000856fa4a9af892, 0x000fd9a17add2f5b, 0x000bc96203a41193, 0x000035db9779e65b }}, + {{ 0x000a132f7ea9a6a6, 0x000eb9240be34e8c, 0x0006c77d4fb67e21, 0x000afca2bc7162b3, 0x00001a6fac0542ff }, { 0x000f9b75c44f951a, 0x0002af90e2025b4c, 0x00083cc77b87ef39, 0x0004eb21167aaec6, 0x0000d22d6db853d3 }}, + {{ 0x000c7cce51163e7a, 0x000b1164d348272c, 0x0009ccdd071becbb, 0x00037af16bd99d61, 0x0000d10610c58a02 }, { 0x0007eb5875e27497, 0x00054aad846bd832, 0x000c8134cfd36ae5, 0x000aab5a98775a9d, 0x000086c275896b8b }}, + {{ 0x0005528b5f9ab927, 0x0002651662cc565f, 0x000a1861882d656f, 0x000797e9482353a6, 0x0000a67f2e464b0f }, { 0x000d6414aca8eb30, 0x000d2312f23c5ff3, 0x000a2d9b8ef54a36, 0x00042ada0e3e8147, 0x00008166c958af77 }}, + {{ 0x000188223a7a093e, 0x00044e1a51a168a0, 0x00014726320dde66, 0x0001a00b8b712c67, 0x0000e412af6796fc }, { 0x000487211ce123d4, 0x0008a21f7c18de1f, 0x0000bdf491697418, 0x0002e15297682e45, 0x00006b2b6ce9962d }}, + {{ 0x0009c135ff5a9bcb, 0x00077770c24efc82, 0x0004953601a4b26d, 0x000b112280349fd0, 0x0000209df732d2f6 }, { 0x0007f7525d0fd68b, 0x000ba08f78b0b6f2, 0x00023f94c1dfda97, 0x0000b9365176f5dd, 0x000020eff3bcbb3c }}, + {{ 0x000a7c2c5789636a, 0x000a409748ab1a42, 0x0000348217db9653, 0x00093f0f29cba50a, 0x0000ffd72e054e8c }, { 0x000e9d1cf178ebdd, 0x00089a43f0a449a3, 0x000b6ef3df4bc9f9, 0x00075f35745474c3, 0x000083ae967e4c12 }}, + {{ 0x000fa729a87fe481, 0x0006353f380a6e68, 0x00010b6d0e19961f, 0x00044e00a0b86e43, 0x00009f6a7ecb4a6f }, { 0x0002ed3e3509796d, 0x000026e6c9c217e3, 0x00095ea456ef349f, 0x000c3e2b1be1d307, 0x0000a66932593b0b }}, + {{ 0x00008a89af9a9081, 0x000817f9eb1a8b70, 0x0007c527a6393cf4, 0x000462091bc37eb7, 0x0000c5e0712c411f }, { 0x0003154f5208b269, 0x000bffb7d42c10ab, 0x000e969ea76610fd, 0x000ee44e37fe8c92, 0x0000cdae2d966e9c }}, + {{ 0x000c5def04862376, 0x00079b6d9790ed61, 0x000c8a4c8a36ca43, 0x0001a8e2ea77a0cb, 0x00004f8456e6379c }, { 0x0007052acbcdeaab, 0x000557873b6c1da8, 0x000275d32aae4098, 0x0007648b155cf85d, 0x00002e5661fcaa36 }}, + {{ 0x000e8d5c0dec3769, 0x000c280907eae66d, 0x000f6ee4c07b1ce9, 0x0000e431c3cb068d, 0x0000c8b6234ea0f1 }, { 0x000a212bebfadf0c, 0x00013dce3502e6ed, 0x000073687498df63, 0x000e33ffbc894420, 0x0000da93c59a72f5 }}, + {{ 0x000d7b05dd7857f5, 0x000ad4bf82ce682c, 0x00053a7c1a0771d5, 0x000a2e3de058d381, 0x000087e07d1384e7 }, { 0x0002699a5f9d773f, 0x000b9ed1d9f54ec8, 0x0008306a1b6b36cb, 0x000f3ede28be3d61, 0x00001ffd2fb37142 }}, + {{ 0x000e5782cd47a8b9, 0x0004df571c0c3a75, 0x0009aedc953ef848, 0x0002f1a758f580f5, 0x000042380c4840db }, { 0x000acf2240badb82, 0x000d60c99c82a70a, 0x000e6b1b6a0b6799, 0x00065dc70e8359fb, 0x00005463c0ed77c0 }}, + {{ 0x00044e55ad6bba22, 0x000aaf5e4652f1d2, 0x000ab113020533f0, 0x000a7ca50bd6fdd2, 0x0000ffec60c771f6 }, { 0x000d2dbc0fe69c05, 0x0008e05047d320ba, 0x0004b4536a2fa180, 0x000f3b3ee1ca983d, 0x0000736ebce33440 }}, + {{ 0x000b59f3e30d097b, 0x000bfa29268b3de0, 0x000adb866cb76535, 0x000eac7520d1ca29, 0x0000d07af7edc75f }, { 0x0007f84282de8bcf, 0x00016ff7f4a6c51d, 0x000189e3ecfc03a9, 0x00009091fa8768fd, 0x000063e18fffaf2c }}, + {{ 0x0005978d0a53ff5e, 0x000de0e0546063ea, 0x0001b7ca1ebc5a0b, 0x0009b66007fbadcb, 0x000016843f73bee2 }, { 0x0007fb68ea74f94b, 0x000d61e4f85eaaca, 0x000152cf5d96b415, 0x0008a39cde61e2ad, 0x0000f97b10343ac3 }}, + {{ 0x00048364d3e5d0bd, 0x000fc363daed4c29, 0x000f918392b59488, 0x000d61c0a80a9aa3, 0x000059055976d210 }, { 0x0005f25bd356dc7f, 0x0003d6070985182c, 0x000d6d3eacc1af52, 0x0004d43f5a6db5b0, 0x000050f58b44a28c }}, + {{ 0x000c527f92db6aac, 0x00019242d0a4c230, 0x00045f614cbf9dab, 0x000338092eb5d26e, 0x00008b05b2bd83e5 }, { 0x000c81836dfe11e3, 0x00036382aede0ac3, 0x00083041c5cba047, 0x000916061b292220, 0x000053fe2de8f49b }}, + {{ 0x000a0369abbd0203, 0x000b27fa001ec5a8, 0x000b16d8f40e8efc, 0x000481080e993f5b, 0x0000af7a86da5db5 }, { 0x000551c295b0441c, 0x00071608c927db84, 0x000f4f1394ac39c2, 0x00072abeabf5f37c, 0x000060b2c65c0c54 }}, + {{ 0x000b04f7d8f72e56, 0x0001be7ed77ee8ba, 0x00004804ddee725d, 0x000b92acabddf7bd, 0x0000ccae2b20533d }, { 0x000c088c89918989, 0x000e9944313a8cee, 0x000ba6c1c0748b0a, 0x0001e207ae532e4a, 0x0000e42ef48bf73f }}, + {{ 0x00046b3d3b414b91, 0x0008dcc42ce9e515, 0x000d5df49fef1fdf, 0x0009c67398f9840f, 0x0000bb29bacc84c0 }, { 0x0008c7d4845045fe, 0x0001ba980d309162, 0x00072f844c3fd6d1, 0x0008188084549710, 0x0000d0d70dbdf40b }}, + {{ 0x000ed2436122cc51, 0x000c66788a2ffe41, 0x00050a0f2644da13, 0x0002d783adc506a3, 0x000069129b160058 }, { 0x000218e8eafe18f8, 0x000b292a3d694e78, 0x000d6d37d38998d1, 0x000f855b4c0f43b4, 0x0000bf4a6ab4a165 }}, + {{ 0x0000f3271f894fd3, 0x0008afb185f88448, 0x000a946484dc2331, 0x0007019dfcd7e90c, 0x0000692c2e123626 }, { 0x000981d9ea441cc2, 0x000d8a7d0e62f477, 0x0000cc886efb3ba6, 0x000724e1e88d519d, 0x00000023f082da8e }}, + {{ 0x000afff39d12e58b, 0x000da2c9ac382032, 0x000f2c658c484952, 0x00039c91686eaf87, 0x0000523e755bd5cf }, { 0x0005df02e43ae54f, 0x0006c07256d4eab9, 0x0001eca6a8a4fff6, 0x000375ffe2259869, 0x00006edafe5d45c9 }}, + {{ 0x000d1c4cc4d8b709, 0x0002c6ec7004bf30, 0x0004ce677b1974ac, 0x000529eb7230a08f, 0x0000f295c26eabae }, { 0x000fed0da0e7efbd, 0x000096e7550fee88, 0x00070d0a16dda21c, 0x000c5fae7369cd4c, 0x00001bcd58dde3aa }}, + {{ 0x00044ed736b966ec, 0x000a5c2e48fb8898, 0x0002f73bc5cfb109, 0x0001bb4e226882c1, 0x000063d7619b2c62 }, { 0x0006a413e95e2beb, 0x0005c6fd86e27c75, 0x0009ae0bdbf2ca03, 0x000edf84da04edac, 0x00007492ad45d302 }}, + }, + { + /* digit=19 (1,2,..,64)*(2^{133})*G */ + {{ 0x00024f4d696da3cb, 0x0003b1d5a74be506, 0x00047c52228c154a, 0x0001bfda2e41781c, 0x000096ec0545b52c }, { 0x00001059ae4af1e1, 0x000735dbdcc9ae4f, 0x0005508ac4dfef91, 0x000d754392573dbb, 0x000045a30ae8165b }}, + {{ 0x000c13673627c363, 0x0003c973112795f7, 0x00071c3b07ab4999, 0x000f308cde824443, 0x000024017b4422c4 }, { 0x0007e6782a430857, 0x000be955dbec38e2, 0x000c10a45929115d, 0x000d83e2f51c0782, 0x0000d2b6c6a41083 }}, + {{ 0x000f9b21b06e4d48, 0x000483d4ed2dbc25, 0x00081ca00bd2f9e2, 0x000314b350eba59c, 0x0000879d4fee9d2e }, { 0x000846aa4551a9b0, 0x0002394af267bae5, 0x000565e76b699192, 0x000e51500aa86cc2, 0x00009d486efc3818 }}, + {{ 0x00023eed8fe44b7b, 0x0001c40e2c2bf152, 0x000587aaa9751a65, 0x000b04a65627a220, 0x000078ae9a0140de }, { 0x0008dfbb97c7d47d, 0x000a883a8363b49a, 0x000920e2f50e570e, 0x000074b5c1a0b6cb, 0x00004368ec853ac9 }}, + {{ 0x0003cdd7ea38297d, 0x000d04c65c7c2aba, 0x00073ef8129a7789, 0x00012cdb51d4610e, 0x0000ae1d9b12315f }, { 0x000a8296356d58cb, 0x0007e83064417ee3, 0x000c72e948f5f2f8, 0x0009e5bc31459b23, 0x00007f5688f80bef }}, + {{ 0x000e7c88b34096a2, 0x000ee1fab192c181, 0x000e51b38d9be8b8, 0x0008dc9a6ec5fcbf, 0x0000c004fd1604a1 }, { 0x000d9b52b3513161, 0x0007c93c92d88c5e, 0x000d236ba8a62196, 0x000c4ae1441c2148, 0x0000e3b813e3424f }}, + {{ 0x0002d6dbe520bd47, 0x00002ebb0a5b358f, 0x0001aba752f14bc6, 0x000e71bdbb154c5c, 0x00004df8bc57eacc }, { 0x0007ad0af3ff3ee3, 0x0000af38665e5b22, 0x000353d24c2f432c, 0x0008cd086488a851, 0x00006ced5e1bbf8c }}, + {{ 0x000c2a360971c31d, 0x000066e846e364f6, 0x000c727ad6974fa9, 0x000639b6d7f33527, 0x000015ca19ee6b97 }, { 0x000b4ef351021aa4, 0x000ba52f024e9245, 0x00044265bc79a45a, 0x000687390e0fa07a, 0x000026bc8f7f2c64 }}, + {{ 0x000eb356d99847ee, 0x000c1c4b6205969f, 0x0001f8142e759402, 0x000504d4842563f0, 0x00002d9aff65fb85 }, { 0x000340185f8291c1, 0x0006b81d1a39bd77, 0x000f7353328a0998, 0x000e743da8f44340, 0x00008523dea1bcc1 }}, + {{ 0x000c87111ada74f5, 0x0000bfb7409ab463, 0x0006445b7897551a, 0x00013f0d1057e78e, 0x0000fca1d2e611ce }, { 0x000f201ffa6c5d1a, 0x000f41c7809460b4, 0x000222a98bccef3d, 0x0006f03c9e751c85, 0x000002a8d1482e5b }}, + {{ 0x000984b27405ee90, 0x000005c3e6721cea, 0x000a272eb4d7fd0e, 0x000927da4d52d70d, 0x00000cba2cc35612 }, { 0x0009d70b01b1eae7, 0x0003e2784de5ca41, 0x0002ae7bd3c2b1ce, 0x000f8f7092f1c987, 0x000030b0c4119210 }}, + {{ 0x0005583b9f7c63fb, 0x000702da6dc1d29b, 0x00094319a5a4c61c, 0x000909776d303000, 0x0000ea690a72942e }, { 0x0000d34175165b72, 0x0004c7895695f204, 0x000148fcd1400755, 0x0009aa443fc84181, 0x00009d399222fcef }}, + {{ 0x000758ee5709e62d, 0x00069f5674198335, 0x00022ee28cb1cdab, 0x00070430c6059e25, 0x00001b376756c012 }, { 0x0008f5c1bf938d37, 0x000401d013b0ea65, 0x000afbd027f9ea15, 0x000a32680fddf524, 0x0000feb88c703890 }}, + {{ 0x000d105f424816f7, 0x00040f17c696042c, 0x000b7d14d99c5d98, 0x0008d2f00d4cba22, 0x0000ca9c23515356 }, { 0x00065cd5704583a6, 0x0002919ddb81e743, 0x00091afae35a6c5e, 0x0001a1285472f2d8, 0x0000a117968098a9 }}, + {{ 0x00061f2dfaaea695, 0x0006dbba2be70539, 0x0005e49a78db79a4, 0x000511030dcbbf7c, 0x0000c25cacbca172 }, { 0x0006bc1247ed44bf, 0x000d53570dc80c4f, 0x0002f9bc2ed8f5b8, 0x00011b222104d6b6, 0x0000be75e1d87966 }}, + {{ 0x0001a05fe05069b5, 0x00097050f15dde91, 0x0007fbbecba1b4b7, 0x0007e7662a47a76a, 0x0000cef9eea25012 }, { 0x000d251439c9ff5b, 0x000996e9d529b36f, 0x0000927929bcb4b0, 0x000321b9855ab130, 0x0000e6913e2a37cf }}, + {{ 0x00002e1795824e90, 0x000a54723d695ead, 0x000d46b77220484d, 0x00039408648ce626, 0x0000dd1d7bdd322f }, { 0x0000941af25d109b, 0x0004e8f7198111d6, 0x00057c65a8da2e48, 0x0002feeb090ca630, 0x0000f1530e7e8096 }}, + {{ 0x000b5c989f6938ee, 0x000d2a222eb51e58, 0x00041f4057fb3762, 0x000dcb106c0bb724, 0x0000ad14845ce016 }, { 0x0007d1e1160ea6c5, 0x0002e16512e1f433, 0x000475371e4c0b2c, 0x0002b464e02eac55, 0x0000f6d7ff9c35f9 }}, + {{ 0x000f15a10f16a85a, 0x000e41aab7b19a8c, 0x000e0fe32c369f9b, 0x000b5a9daf08d067, 0x000024ab40acda51 }, { 0x0009684eaabd75c3, 0x00009e5b738a4250, 0x00058cce645336d6, 0x000db1305ebe131d, 0x0000484813fc96ba }}, + {{ 0x000d8bd56620b954, 0x000129c72ba075b6, 0x00054cbabaaf6b83, 0x000e637a889f78b5, 0x00003d0a3429781d }, { 0x0004afac04fc7b8c, 0x0005a3b805f08d67, 0x000d4f0d15b02979, 0x000aa4c477f48200, 0x0000acd64bf963b3 }}, + {{ 0x00065ecce6ddbcf2, 0x0003a2b7e63d6900, 0x000ffbc500d16630, 0x000c7e1feefb6bbe, 0x00008b274a61c74a }, { 0x000c29f8ff0209d3, 0x000c1ce69f790713, 0x000ec8218d676a18, 0x000acca8f0d9a8e5, 0x0000f615e9cc3915 }}, + {{ 0x000f37825c9ef1ce, 0x000848febae68c4c, 0x0001618e37c4f175, 0x000eb4cec5b38563, 0x0000d423c83cbc80 }, { 0x0009c52aea308776, 0x0008380beb11454b, 0x0000a6fc857c4768, 0x000022bc740a1a99, 0x0000ca5ec3d496c8 }}, + {{ 0x000cd4fde296905a, 0x00062ce45650ef47, 0x00000dcd9ce46f6b, 0x000746a70ae000f1, 0x000007a206cd8fb8 }, { 0x0006cd56404f4acd, 0x000e52ae88408697, 0x0008e8efb046152c, 0x000cc12baa886885, 0x0000b6caba36edc1 }}, + {{ 0x000a22c213a1381c, 0x0005998a9d82abfd, 0x000b0c9eaee2416b, 0x0002e94875f188cc, 0x0000ed487d7becaf }, { 0x000a1bfe43d8e989, 0x000d43afbddb4799, 0x0003d3555d553c34, 0x000ae422e4b606b8, 0x0000a98941400820 }}, + {{ 0x000d93563973829e, 0x0008a092a67d48a1, 0x000de58c53a8a8ae, 0x000c1054acd6a671, 0x00000d14b278f09a }, { 0x000286662fa4b2d7, 0x0004d898fea73ea3, 0x00046daf4982b9ed, 0x000b2de4c8247b36, 0x00007827af7176ad }}, + {{ 0x0004d969cb439a74, 0x000636bb4ec4c20e, 0x00062a667a3273e5, 0x0003e53e8f0a12fa, 0x0000735706c629fe }, { 0x000d4b3454ad59df, 0x00074b743e232a3f, 0x000b3aad70059ea6, 0x0007e3d8fdc7a3fa, 0x000053ec510c7073 }}, + {{ 0x000267aa86866f79, 0x0001686d36e30622, 0x00077edc547bf065, 0x000077b2e626c527, 0x000032b789435829 }, { 0x00088821cbb8b0bc, 0x000a75172e572d59, 0x000721eb0f204226, 0x000dcca57ab861af, 0x00001dc0ca62fb88 }}, + {{ 0x000ce1680d34fa1e, 0x0000722cccc18ad5, 0x000d94c5781a4479, 0x000c8174daadf3f8, 0x000096cf50e285e2 }, { 0x000921dfeb77456e, 0x0004dfcd9ecbee97, 0x000ba38c82c0be59, 0x000d5558a4330689, 0x0000d3b38073c94d }}, + {{ 0x000da886aed8ecd4, 0x000eaf8271d1ca55, 0x00078b0236696085, 0x000b711e33e423bc, 0x000014d2f4ec906b }, { 0x00036e1f5d068ff6, 0x0007034a99643755, 0x0003162eb1a26190, 0x000151fe9356a2fa, 0x0000f7623180c7d5 }}, + {{ 0x000f35afef5374dc, 0x000b53a5c04e4ea9, 0x000e37bb65248044, 0x000884194d549dcf, 0x000056a261a80626 }, { 0x0003eb6a05b04ad5, 0x000b824f1314f53b, 0x000816d16e1d2218, 0x000a9b8b062baf94, 0x0000b751a249239e }}, + {{ 0x0008e248259fd6b1, 0x0005fae1208e16aa, 0x00054f53f5fe83ea, 0x000752f0b1a4d15b, 0x0000322765d11e76 }, { 0x000a06028f32c493, 0x000e0a290b170cfe, 0x000058eb8f6521c2, 0x000831797a1bef33, 0x0000d5b9b2a9415f }}, + {{ 0x000495775835ddea, 0x00038f3dbfb894e2, 0x0006a991d3c0ab53, 0x0007ac0dfbe9b79f, 0x0000a996ed108d94 }, { 0x000a1485e6867237, 0x000b861bb9390993, 0x0009ecbcb0ad8aab, 0x00089ee3b1d6a974, 0x00004490d265e84d }}, + {{ 0x0005d8bafdc81765, 0x00002b4147c15b45, 0x000b25ed58041f7f, 0x000f1de81e34f553, 0x00001e756a2afa4e }, { 0x0008b5d2446a18ad, 0x000cc95f1c0e74e9, 0x000e53045657f07f, 0x00033d5515a9b292, 0x00004e129faf6e81 }}, + {{ 0x00054ce98632c8d9, 0x000e666683425204, 0x0009755b794b887e, 0x0003dd2cd08d6894, 0x000093ff6f3941b6 }, { 0x00011538eb926db1, 0x000ab9eb55b803b2, 0x000a10ce88821a3d, 0x000060e12b03468e, 0x000072cd7c995240 }}, + {{ 0x00032cd90a50d0eb, 0x0005f2f731dea2d9, 0x0001e1c0a21fc8bd, 0x000d579fed5856cf, 0x00009b444a44e0c2 }, { 0x0009e7c0c1c75493, 0x00002d4c0c4ddc0f, 0x00073a980207bdba, 0x000b2d8cbc0f422f, 0x000047b3f99102be }}, + {{ 0x000665427bc303fe, 0x0004fdb0f5f27cac, 0x000ae1a81783a295, 0x0005c1223e85461f, 0x000076fba4039ea3 }, { 0x00022639d9c5cdc0, 0x0005a697587fd52b, 0x0007db23b5f4ea89, 0x000744688935289f, 0x0000887566528724 }}, + {{ 0x000bc9cdaec3de6b, 0x000f720361ecf90e, 0x000f398696b456af, 0x0007dc079001f23d, 0x000063bcc338ae46 }, { 0x0007015cc0864754, 0x00010a1934aa7289, 0x000e179a04332cea, 0x00055a7fd750eb00, 0x0000b649d7589b15 }}, + {{ 0x000c21aa55e58d8c, 0x00038a5bf5151dff, 0x0000b44f6e9cced5, 0x000b2182c21adcc4, 0x000000bf7836051e }, { 0x000405a74bccb408, 0x000bb2f4e51ea80e, 0x000f4195b6421b97, 0x000db135e3dae45e, 0x0000c8a422289ff6 }}, + {{ 0x0005afe3df554744, 0x000a5c69f1c56bdb, 0x00079441b2c565d3, 0x0002dc52b8c176b9, 0x00001263e0533213 }, { 0x00004e3fc1406d5b, 0x000a249145813e50, 0x0009e2650265686d, 0x000129a7f687fc4d, 0x00000832fee46c0c }}, + {{ 0x0001f9addb3fd772, 0x00068b61430c9ab7, 0x0002b03f3bbc1b26, 0x000a8d0ae0bdd41d, 0x0000a6be72385501 }, { 0x00063accbd8fe7a9, 0x0001716c52dd907b, 0x000c73a737c1e0a9, 0x0002868a6d9bdf44, 0x000035c09edac28b }}, + {{ 0x000add2b06f54586, 0x0005c351272a95b5, 0x00074b4a3fc1da82, 0x0009268f70c66771, 0x000044d6759202ed }, { 0x000d2a2bf9fa5f60, 0x000732d14ea5d65e, 0x0005a053a90c3bdb, 0x000554ac6f8e01f0, 0x00005fd71f56197b }}, + {{ 0x000d3d1774087028, 0x00051b5e9d3a7c31, 0x0006647adbd73b2d, 0x0005492758e0ee5a, 0x00003bba70bd8115 }, { 0x0007246f125d77c6, 0x000ab127747ae836, 0x000fb258fc2e4b6e, 0x0001e4e0031f4315, 0x000079fb7523dc70 }}, + {{ 0x00022cef7e044521, 0x000ab5aef0c31335, 0x000d2be979bd6bea, 0x000e49649247cc45, 0x00008daf607fcbc2 }, { 0x0004be69d5e2999c, 0x000580559ab93b3c, 0x0000da59a69c02d5, 0x0009972d0225fba1, 0x0000cc519897bf32 }}, + {{ 0x00000ed311acec40, 0x00036680448087c4, 0x000f31345a9c7960, 0x0000d7f47ac30903, 0x000014a52f1f5454 }, { 0x0006f2e733d21f38, 0x00041fef8fd24247, 0x000a837ac257323f, 0x000ff2f3afdfd974, 0x00009ba0f6470d39 }}, + {{ 0x00050c547e9953dd, 0x0000eb52a6017539, 0x000c306fd8ca8187, 0x000b82024b286514, 0x0000a0dcbe1ef184 }, { 0x000f64a7dd340b95, 0x0008469e5d32bfe8, 0x0001e5a8c4619dc8, 0x000d6ea3a30bc147, 0x0000e933dd6721ac }}, + {{ 0x0007ccc59280d519, 0x0008037633dfb1fc, 0x0004cfb25fb4af10, 0x000498d46ea82c39, 0x0000e384e83287e5 }, { 0x000e6e0a4144dfdd, 0x0009c6281761e131, 0x000f73287e1b3d37, 0x0001fe070da57596, 0x0000b0e289bb07e4 }}, + {{ 0x00066b4e44ff11ff, 0x000882c4152fcf57, 0x0000280c990f629c, 0x0003c0009441c87b, 0x0000b659204e90a4 }, { 0x000df4368ea4d935, 0x000701211f1c7924, 0x0002fdef25b0372d, 0x00033119eea02ae9, 0x0000eb3caf4bdf44 }}, + {{ 0x0002ad31f429e92f, 0x0007dab4baef62e3, 0x000275ae5ff44e2e, 0x000fc47109f5a220, 0x0000f78da2e8f242 }, { 0x00089cf1ff54aea4, 0x0008ca425bcf4d6c, 0x000288b364e70dd4, 0x000847d56ea95059, 0x0000d5e592ce8a8c }}, + {{ 0x000bb30b4c5c4041, 0x000f81304e60cc0f, 0x000c4a72c8291975, 0x000e6a462ce811e8, 0x0000eb639b79afd0 }, { 0x000e60a95e94bf15, 0x000e32c485281182, 0x00059ec7afb2ce90, 0x000767a287c6fe08, 0x000067e5869c6204 }}, + {{ 0x000b6d146193e6d2, 0x000ab3d9b785dbf2, 0x000b7beca8857459, 0x0000f4039530889a, 0x00009e5aa29e84bf }, { 0x0004f877f4c051e2, 0x0004a0451a7bbf7f, 0x000f81f9d270263e, 0x0006a8ba030ad99e, 0x0000b432329b85d8 }}, + {{ 0x000cd2b7ced02b6a, 0x0008c2d4c44f1190, 0x0006dce4bc47e034, 0x000836c3b4555f53, 0x0000788b19828abc }, { 0x0004d4598c6d92d3, 0x000557b46945fa35, 0x000081a82e04d1a0, 0x000a4ea08f8785b2, 0x000063de08f3d528 }}, + {{ 0x000d3e738b6fd0d3, 0x00087cbc46d7ce17, 0x00070dc9e4ec18cd, 0x000a97d509a515bb, 0x0000c0ed53ffb19b }, { 0x0009fd2c8134d2bd, 0x00005ce2a6cb0ebd, 0x0004b57daff8514a, 0x0002ea6766f2e295, 0x000010bc9a64cffe }}, + {{ 0x000465c200623f5c, 0x000db38b2b836a16, 0x000017a7a4228368, 0x000823ef1855b41a, 0x0000cb16497d171a }, { 0x00094b4447686be0, 0x000e23f6974b99e0, 0x000b99263876de79, 0x000c0065875a7cf8, 0x0000dfac4f57f79d }}, + {{ 0x000a8e6f779b6900, 0x00085edb940cb5af, 0x00018239bf98af89, 0x0009c26fa6706d79, 0x0000b769a307f467 }, { 0x0007c08b475deaab, 0x000f234591ee4f0d, 0x00066866b61f19ff, 0x0007c69575f46e33, 0x000028a209b8748c }}, + {{ 0x000b82c392e80537, 0x000f93c1c08ad635, 0x000ff1019ae85ec6, 0x000ee34f79954343, 0x000039a812312260 }, { 0x000b0e72020ed2dd, 0x00035c4928435d5c, 0x0000ae24917dfa24, 0x00007284a071cf0f, 0x00005e0b1098229a }}, + {{ 0x000e70062ee0a4a2, 0x000917ac0b7eff35, 0x000e6774850d2a32, 0x0004c985f8552225, 0x0000ed692c26dd93 }, { 0x000068c99ecd36b0, 0x000a048e7073969a, 0x000922d3ea339e56, 0x00093f20f392d2a2, 0x0000a61b1d58dd81 }}, + {{ 0x000a4141443fe874, 0x000f11fb87a29137, 0x0004c28111acbcec, 0x000845fe4ea3e3c1, 0x00002b3d24c59afb }, { 0x00010dc2aa355a06, 0x0008f1aa71ff4939, 0x00022ac5ba4c733b, 0x00075e8fffe980c9, 0x000092ea09a1baa9 }}, + {{ 0x000bd61a53336f7c, 0x000c326cca9f54d3, 0x000b572ddc8897d0, 0x0007f6a7c928bbdf, 0x00001633d0f6cb76 }, { 0x000e19742c3c3494, 0x000a4e6395c9a791, 0x000d43d1c100cd6d, 0x00052c2316940ca2, 0x0000fd9b397c3285 }}, + {{ 0x000baa11cf6966bf, 0x0001a0823fc2e6e0, 0x0008fceb7f79dccd, 0x00086bea5a76e29a, 0x000020bec34acd1b }, { 0x000a26322d5b0637, 0x000b564961849da5, 0x000f551759fb7518, 0x0009cb74493b75f1, 0x000085589c5471c1 }}, + {{ 0x000097196463dab3, 0x000235861a023efa, 0x0004194e0b09b4ae, 0x0007b8bc01d72aab, 0x0000a76ce5fce481 }, { 0x00008748d29fbf98, 0x0003d4badb9b5b76, 0x000163d30978b6be, 0x000794e0873fac1a, 0x00001acf21ce255e }}, + {{ 0x0009ab9f40344f97, 0x0008094c486094f9, 0x0002f24809967c07, 0x000bb7725869254a, 0x000017af2e8590fc }, { 0x0003a576905d94dc, 0x000ea8a6706c02e5, 0x000c15d397dbab92, 0x000dc5b6c22b5e76, 0x0000e77621b7d00e }}, + {{ 0x000d38e9c47b4340, 0x000b852edffcf3a5, 0x0003ded185911220, 0x0000e5b9eb4d2ed0, 0x00005ef944ff1997 }, { 0x000cbf19807bc19d, 0x0008bbf303747e2b, 0x000c38f6a80d0b53, 0x000aa5c23a208e77, 0x00001f5c1520084e }}, + {{ 0x0009789f1f62f6fe, 0x000f230273231941, 0x000b1a24067e38a4, 0x0006f97203b055a8, 0x000043fde981f2ac }, { 0x000ee11ececcedef, 0x000a568aaf018013, 0x00004c88b6cdcf5b, 0x00006d17972ee119, 0x00001719e065c6e0 }}, + {{ 0x0006e4617f3e69bc, 0x000caec1ed66f181, 0x000bbf3b6cc4ad74, 0x000551b4d225d906, 0x00003684306257aa }, { 0x000516497c9675a0, 0x0000addb2fbc3dd3, 0x000f55d795decef3, 0x000598fadedb5484, 0x000015e8ee776bd7 }}, + }, + { + /* digit=20 (1,2,..,64)*(2^{140})*G */ + {{ 0x00020f2beb76812c, 0x00013ecfa181e695, 0x0000dec76ead7889, 0x000698d5d9ea02f8, 0x00000cd75bcfa2f0 }, { 0x00017a069c2d2cc5, 0x0008f0a1df843618, 0x0000f08066c134ef, 0x000c931ff1203772, 0x00008f19ef39b4e2 }}, + {{ 0x0000aecc1c7112bc, 0x00073b6b294cda6a, 0x00051854d3181244, 0x00049ff216ce9bf7, 0x0000f5f14402d398 }, { 0x00056e372344bdbd, 0x0005f3af02909e50, 0x000f436065b91304, 0x0002579f8c7d59ec, 0x00001766823e2146 }}, + {{ 0x00027d200e7695ba, 0x000fb3189e800ca4, 0x0006d1d4e8ef137a, 0x0007f003750fe0c1, 0x0000dad25c5ac540 }, { 0x000807804fa82f49, 0x000994fe616e2c00, 0x0008e610d4715daf, 0x00004e1739c25f4c, 0x0000a1ed59eb55e7 }}, + {{ 0x000c966787f80791, 0x000d43a4f0d56f34, 0x00077d92507dca1a, 0x0006bb24b961e404, 0x0000a0d775222852 }, { 0x000bb6d594089b2b, 0x0004142864fee422, 0x000a2f57f8c8c37e, 0x000969659c1be93d, 0x0000e98561f48eb8 }}, + {{ 0x0003d36eea5a411b, 0x00083c9b809b7ceb, 0x000b2ef3bd41c883, 0x0005fa4368a41486, 0x00005327a94036a4 }, { 0x0009d81a294550be, 0x000028a328cc987f, 0x000b405a4a382a8d, 0x000c01dba0a3bcd2, 0x0000ecbc7c687492 }}, + {{ 0x000ee9ea4399d83c, 0x00029ade4d559419, 0x000d914e5643a410, 0x000194f9bdedafa5, 0x0000ab6a2f9c77b5 }, { 0x00023fc56d6b71dc, 0x000ce1637a55a4a5, 0x0003af1fce4bba9d, 0x0002a5998eb19a51, 0x0000fb6b0a026533 }}, + {{ 0x0005384859f3a770, 0x000970cb98fe684f, 0x00091d11cbfe5c75, 0x00014fb3fd60fbe9, 0x000024a2c6896e9f }, { 0x000a7731d1c175f6, 0x0007bf7b59e763bd, 0x000880e35c8c898c, 0x0002e8c923d4606a, 0x00001705d921c944 }}, + {{ 0x000bd17983bec34f, 0x000e79390d458714, 0x000fba44f409e51f, 0x000e5b503e976403, 0x0000bb28b50bfeca }, { 0x000460fc77585d24, 0x000439ed5d2c53a7, 0x0008896e3f104db9, 0x0000d454e5ec4bcd, 0x00005c92699d9c5e }}, + {{ 0x000cb1236b66c01c, 0x0007f8295caabee0, 0x00057be3de780986, 0x000aeb665de024ca, 0x00001dc5e9d49aa0 }, { 0x0001359afecfc3d8, 0x00005bf0972ebf9d, 0x00045177093370a2, 0x000872776f1dd387, 0x000022a719d4d0a4 }}, + {{ 0x000802eabd5b22c0, 0x000fa2b91502cf37, 0x0007904acc9ff780, 0x0000df1c92c3832a, 0x0000c8e7c1032083 }, { 0x0006aeb0c9d5f503, 0x0007027a37fddab7, 0x000b8400f8a95d7b, 0x000f1f61a65d6f2a, 0x0000d4946c17ee3b }}, + {{ 0x000af61472ec944c, 0x00013f62f93a6750, 0x0003fafe7206fbed, 0x000f69c84a6ec968, 0x0000e64f69ece348 }, { 0x00036a8a8778d2a5, 0x0009e72a5f696be1, 0x000a5bb870e8f960, 0x0009a4590c65e57e, 0x0000b18bf5bd851b }}, + {{ 0x000b4b36c8c2e8ff, 0x00082dc0f9f44d43, 0x000ff0fb2191ea75, 0x0005ed2b1f09a695, 0x00007a5902599c01 }, { 0x000a904b3c1f4b94, 0x000837b3b6b234cb, 0x00045ca08e940188, 0x00034bf1d096a250, 0x0000986acd027cd0 }}, + {{ 0x0009958546371d81, 0x00058d493a3147a2, 0x000c70c0cffeda75, 0x000d2f1129f30a5d, 0x0000599e39f58537 }, { 0x0008d658f17504df, 0x0005fffc17db9ba2, 0x000ca23febb75e2d, 0x0004520bccb18548, 0x00007564d18ce2da }}, + {{ 0x000e430a33a255cb, 0x00095cda99f8c71a, 0x000a9db438cba264, 0x000f5749967b7abd, 0x0000945a43d068ee }, { 0x000cb8f38cf63ea6, 0x000d0d388ace52f4, 0x0004061e12f02828, 0x000c9271b4bc0fa2, 0x00004dad48391d98 }}, + {{ 0x000a1c5643447901, 0x000bd808c3bff364, 0x000208478f323f53, 0x00022dbd1005a0bd, 0x0000ae406a2896e1 }, { 0x000137007e0dbeb6, 0x00025b99fe4fc88b, 0x00081b60bb371dbd, 0x000646bae09418e2, 0x0000cc34af053693 }}, + {{ 0x0000693a18674889, 0x00096e1c63c4962c, 0x0008d7b6a10d190a, 0x00003a26b50541e8, 0x0000e282f1e08996 }, { 0x0001ed4e5703fca0, 0x000c04e0117f203b, 0x000258ac6a79aec7, 0x000248c44245f196, 0x0000ff00eb7253c2 }}, + {{ 0x0002a6cd6b58c40f, 0x000e675f8547be3b, 0x000cf73d922da584, 0x00000f2000a7033c, 0x000044f163153dc0 }, { 0x000273a484b87506, 0x000aef557933c6b8, 0x000ca899db77a846, 0x0006120b6a7538eb, 0x0000ded4a50d08d4 }}, + {{ 0x0003995b1a10381b, 0x0007d450168e508a, 0x0001f60fefa3784d, 0x000788b718cbc9bb, 0x000015ddd98778ea }, { 0x000b59fe5b0f3810, 0x000568e1239e1525, 0x0008605ee199d7d9, 0x000b969635689255, 0x0000ae3fda8f50cc }}, + {{ 0x0000f551a177b5e0, 0x00040eb34a9f7aec, 0x0002165c9e43067d, 0x000084f37e5e8cf7, 0x0000983560921b62 }, { 0x000e549e04b370fb, 0x0006768038f67254, 0x00051f3e35b1a2ef, 0x0005adb861dd38e3, 0x0000ac6cfc2b7810 }}, + {{ 0x000ddba4b3d8e704, 0x000f53b08b193400, 0x0004bceb33e96771, 0x0002e98c7c2fae6f, 0x0000d016b8e9d8b6 }, { 0x0009d9e008a1dcc9, 0x000feb51dd95f8c7, 0x000754cbe24d3872, 0x0006dc34c1d163cd, 0x0000d6587365fd85 }}, + {{ 0x000846f5f2308016, 0x00088bfe6ddd5053, 0x00047cc4f727d222, 0x000b2675737064e7, 0x0000ae37a4ce7376 }, { 0x00090c603077e9a7, 0x000cd9160df1b9b3, 0x0004f411426f0fd9, 0x000e7cd3c4cfb289, 0x0000f64f81bf99d6 }}, + {{ 0x000762921d03717d, 0x000d6128c0a78de0, 0x000a17234d538bcc, 0x000a9e882ccd02bd, 0x0000eed2d646e6a2 }, { 0x000287c7f8080a37, 0x000d123d85010c02, 0x000addbd0727cb42, 0x000abb08ad73aaac, 0x000037e0c3c8c39b }}, + {{ 0x0009ea4996a3c06e, 0x0008942580b1a014, 0x000d1657f1e2a72a, 0x0001e3344f080415, 0x0000093afc473704 }, { 0x00090e3df700aea3, 0x000eeef571f3913f, 0x0003fca41c93b37a, 0x00008fb8f0610f21, 0x0000984f4e2a8e30 }}, + {{ 0x000c69c29d48bff8, 0x00065eb43e2e0349, 0x0003a7d6620d144a, 0x0004ca77f53fb5a3, 0x0000f354b8c1cb22 }, { 0x0006812c52e71fa4, 0x0007bebbace47b69, 0x0009082476997303, 0x00043e13ebdce028, 0x0000fc56789759ad }}, + {{ 0x000a5a5512b3d42d, 0x0002a7157151692d, 0x0007ff33c7322027, 0x000656ee1eb2721f, 0x0000ca99ca38747e }, { 0x0001ef52167f204a, 0x0008b5dc6f567809, 0x00037bd855ddf45e, 0x00073d003e20d300, 0x00004fefff6aeb76 }}, + {{ 0x000c08620a2c393a, 0x00045c14092d85f7, 0x0005e041820ffc39, 0x00031138172d223c, 0x000087580008988e }, { 0x000769b5baf39b4b, 0x000017dfc588b090, 0x0009510b05f510e9, 0x000b0b995728cd49, 0x00004ab8441733f4 }}, + {{ 0x00082ded8c15f913, 0x0000f8bf99c24714, 0x000ad0f0c3845063, 0x000745d24f2d8a11, 0x00002d13601a08bd }, { 0x000fc739d67f549d, 0x0000cd8dadd48854, 0x000ea20b7b714a04, 0x000b658507004477, 0x00002739d35a18aa }}, + {{ 0x00010188c19608f8, 0x000b727786f08a98, 0x0005c1c0eabddfc4, 0x000452e708700bb2, 0x0000b09a61e07f86 }, { 0x0009d4f07bc35bad, 0x00023c9abcd3297f, 0x0006faac186ffef6, 0x000734030ae4c896, 0x000068869b2a6b55 }}, + {{ 0x000a11de9f5e8da7, 0x000e7d583fa1e08b, 0x000e0499f35bfc4b, 0x000ad6a967780d33, 0x00006387ac199d31 }, { 0x00028fa43af1c617, 0x0001dda02c2d064f, 0x000cb1fe3e00767d, 0x000ca72d87ecf360, 0x00008656d8273918 }}, + {{ 0x0003edd0e98b762e, 0x00054cbea4570b35, 0x000b51fdfe00672e, 0x000f31ed5ee65d68, 0x00001bd0155d4d2d }, { 0x000500888c6c33f6, 0x0003d07beb9bc6d2, 0x00077a5bdedc774a, 0x000be200fe9abb90, 0x0000328aca3a48e5 }}, + {{ 0x000d700c7f811577, 0x00027d9926fce430, 0x0006f76a1cb0b72a, 0x000373b27809dd1c, 0x0000b7a49c601709 }, { 0x000574395a4d1adf, 0x0000b33ab64a0652, 0x0004edc4a625cb0b, 0x00049167faab9b73, 0x00008e3cbcb5b34e }}, + {{ 0x000d0301187bc101, 0x0000eb6700a1acd0, 0x0003f09695693995, 0x000f3e0bae823fd7, 0x0000bc494f5d06f0 }, { 0x00015737c0a7b0f1, 0x000bfc989fca8cdb, 0x000b4882d64acc9e, 0x00080e66f970d01d, 0x00002a01327ea3d1 }}, + {{ 0x000860368ee95e14, 0x0001fe8a8b484e77, 0x000901c6a838f33b, 0x000c0ed36b2fdbdf, 0x0000699447c715b5 }, { 0x000e12a5ec3c2973, 0x000b91cf9ad3e183, 0x00072a8ca88d9d13, 0x000267eb66d6c5f1, 0x000078786b1aa576 }}, + {{ 0x000c54b9cb562934, 0x00040e9a56b872f8, 0x000c70a1d4d6fe0c, 0x0002cdaf7a1ad550, 0x0000563272b206e9 }, { 0x000acf260393473d, 0x000cd4a088ac342d, 0x000b3aa7a0ccb38c, 0x0004f4ce9ec450c7, 0x00001b6e01fa188c }}, + {{ 0x000cba2eeb210411, 0x00026c6c8cb6b42a, 0x00030cb4c496878e, 0x000ec67251326fc9, 0x000017ca1f4e8294 }, { 0x0007a18a6d684fc4, 0x000c47a633c30000, 0x0002d02a45040c90, 0x0001d2dbecb6cd17, 0x000008914cbb715b }}, + {{ 0x000b3294258afecb, 0x0005b799edce57e9, 0x000443cd891c286d, 0x000a327c652b892f, 0x00002fc850e5378b }, { 0x000c76a331bc95f9, 0x000e1f2bd2e21df5, 0x000ca5d06767748a, 0x000c7ba2e55298d2, 0x0000676b98053ae3 }}, + {{ 0x000d2c801bc4bf64, 0x000fdfff8a4f29c3, 0x000099630d2de628, 0x000f1ce1c70dc924, 0x0000ea1da14883bc }, { 0x0001e8e630540696, 0x0006172425218760, 0x000c3f839381a073, 0x00037c5c90bed93b, 0x000079f89d6bd4d2 }}, + {{ 0x000f0e75ce977889, 0x000de38c6f3431e1, 0x0002c417ff72df79, 0x00013fe7ce609cb0, 0x00009a2977125eea }, { 0x000b453193606cdc, 0x000ee641158544d7, 0x0008f171ed3d9490, 0x0003d6b555d777e8, 0x0000d3214ae1a449 }}, + {{ 0x000a448a130c115a, 0x0009c8839f05ffea, 0x000fc33dcd3bcf48, 0x00017d31b8f4f4bd, 0x0000992eb014f9e2 }, { 0x000af5cebde70108, 0x00089b3f7914967f, 0x000a1e12d72fc4cd, 0x0000f3ae74537f09, 0x0000f1941d7b610e }}, + {{ 0x00011f21588397cb, 0x00032874ca6b39ac, 0x000c41d0b1e9ef78, 0x000c4c3db70fb72e, 0x0000a9adbfdfa153 }, { 0x000e9af3e27ac409, 0x000ed35bf3bfebf3, 0x00042d3e6c3d4995, 0x0005cc2733a1ff0b, 0x00008605fa3d4149 }}, + {{ 0x00028d0a1e02ab66, 0x000c672b41c34403, 0x0005b0769041de1c, 0x000dc2fa3175239e, 0x00007eb126a76c52 }, { 0x00054fa107e49200, 0x0005f2ed3788a049, 0x0005d171799725b7, 0x0004492d625d8ff1, 0x0000ec4457bdfdba }}, + {{ 0x0004ee0734a79d5e, 0x0004df2e98aaa995, 0x000041c2f15629cd, 0x000b6a46a90cd8ba, 0x000006e82e9e4e19 }, { 0x0002e25421fbf8ee, 0x000b05445b4147a9, 0x000107702d4ac0ff, 0x000bd40773d102f2, 0x0000f9d11eeb5c3d }}, + {{ 0x000a2e45bf1c1c78, 0x0006071bb608558c, 0x000e2ca6b9dcbb05, 0x000d5fe3e60e4eba, 0x0000055d8f3a5a25 }, { 0x000d5d7316bcf10b, 0x00067ec2bfd7a5f1, 0x000f57733e16a9e0, 0x000cd65dc528a8f2, 0x0000538112b6221d }}, + {{ 0x0004396860fdc301, 0x000174adf423e315, 0x00015aa1b1af53ef, 0x00098c9b9cb41729, 0x000050c9de633264 }, { 0x00088ae797a2c6e3, 0x00013c4a54ae57ef, 0x000ff5d9a705ab8d, 0x0003413bc0ffeb58, 0x000021a5f9a644c8 }}, + {{ 0x0001abd8610e73d8, 0x0004544d2359ed9e, 0x000311a87481122b, 0x000de0d69ac68dd0, 0x0000f82040d9e6ee }, { 0x00048969704b7037, 0x000e1d9343b6e3a4, 0x00086f80b23dd859, 0x000cf0767480797e, 0x00006cd8d794a707 }}, + {{ 0x000fc09d2dcb11e8, 0x000285552a82e8de, 0x000488856faec190, 0x000f18978b2caf78, 0x000085276cc6351d }, { 0x0006b1386691ac89, 0x00070ee9113be5c0, 0x000fad47eeb5cd81, 0x000d773542fbda78, 0x0000a86b95d248fd }}, + {{ 0x0006d449d8e3dcd4, 0x000740f43e3865d4, 0x0007d70afe005519, 0x000438bf772dd77a, 0x0000b18fb1739868 }, { 0x00018bef015b1939, 0x000e0ea185d706fc, 0x000b06519061374c, 0x000a2e731e47e02e, 0x0000ca817e6aa631 }}, + {{ 0x0002887ba15c20fd, 0x0007d9c6bdf22da8, 0x000f0e54073dbcd2, 0x0004f3951efbc432, 0x0000469ec570ed01 }, { 0x000deaa2e18dbfd8, 0x000c5dab920ec1de, 0x0002fe53ea59ef2c, 0x000e8af47d0d7e8c, 0x000015e430f8b3be }}, + {{ 0x000111a7619e2658, 0x000c5936cc874756, 0x00020c11dc5ba7f4, 0x00069dd46d92a52e, 0x00007437d17bf839 }, { 0x00049cab0510e4cd, 0x000b7feb3d5f6126, 0x000cfc4b7de6fa00, 0x00023a3305ea69b8, 0x000003184fab8043 }}, + {{ 0x0000efb2747d10ac, 0x00041cf8bdce214d, 0x0001b5bfc0eca8dc, 0x000280de2b5622f7, 0x0000eaba332135f3 }, { 0x00040a52c6704d02, 0x000f68b79df975b7, 0x0005a58efd781132, 0x000ebea46856bf28, 0x000034b117e458df }}, + {{ 0x00080784d755ed6d, 0x0004e152cbb1a3f8, 0x000d8fa0af51d84b, 0x000794e74c3eb99f, 0x0000d39835b41a87 }, { 0x00041e50a81e7f57, 0x000f51cb4e7a0be1, 0x000da8f75687bf48, 0x0006cd9e18780510, 0x0000e64f1df80763 }}, + {{ 0x00043afaf8568dee, 0x000691847be87ae0, 0x0007f32f4879b707, 0x00079d5d368a6141, 0x00002b47d1718f6f }, { 0x0004001ae4f33965, 0x0007c211552a4d28, 0x0002374d2fcfd8db, 0x000feb1a4b6dee69, 0x00000e25e4bee3ac }}, + {{ 0x0003473caf8cdb36, 0x0004d44d795fb455, 0x000d645818f5cf12, 0x000f1a9fc57326e7, 0x0000b402e73630bd }, { 0x0005614508afbc82, 0x0006993a13df4c82, 0x0006726a9f66c94a, 0x000284af8a73e51f, 0x0000c55c0677d85b }}, + {{ 0x0000b9c41619d1d1, 0x000286211a71b27b, 0x000abafe3623481e, 0x0000622efdf71412, 0x00003f1c33b3a212 }, { 0x000e3bcc6e9333c9, 0x0007c52014cdde5e, 0x000a343f7f4d5b8d, 0x000b5bff3702c624, 0x000071d00de55440 }}, + {{ 0x00046ed52661de90, 0x000f22a42ac6c853, 0x0005e98b1d913b21, 0x000ff8e582db0cea, 0x000088053a8d84e0 }, { 0x0005662908845062, 0x000c7951a2faf097, 0x000006bf38262f45, 0x000a502902fa8a58, 0x0000693f983dd1f8 }}, + {{ 0x00020c5984ecc7c0, 0x00035c53d080847c, 0x000890357b714942, 0x000ce5a63cb081d3, 0x000080dfb69e8b8a }, { 0x000fbd9c6a0c8dae, 0x000fc7cf902f245a, 0x00059e95ceb430b2, 0x00025654f9cb1273, 0x000018bbaa36708d }}, + {{ 0x000322f9d772ff68, 0x0007b0ac7088c7d2, 0x00000ee43ec82717, 0x0004112535ab6571, 0x0000826ae5c2a874 }, { 0x0003b5b6363c24f8, 0x000fa2d7430de4de, 0x000602d6f37384cd, 0x0006960681938269, 0x000039706131bb55 }}, + {{ 0x000a9ac3ed8e4ce8, 0x00011803fbc43419, 0x000fc0c429608622, 0x00035fc1d359f2c7, 0x0000af92e79860e6 }, { 0x000cd6f4e3313ee1, 0x000c5fe91fc50ae7, 0x000b493d05996022, 0x000f4105a89ccc66, 0x0000e63d8e773195 }}, + {{ 0x0000f3ffc1435cfd, 0x0009b69ce56b40e9, 0x000c2f39ded7b89a, 0x000912fd7f93e094, 0x000003a249c0e7aa }, { 0x0003ffdeb1ddd9da, 0x000235608241aedd, 0x00072cb1d136a3ce, 0x00057335295ab7ad, 0x0000f449ec6ba460 }}, + {{ 0x000389cfbf4c9e0c, 0x0005091d11a8594e, 0x00074e459df97c5a, 0x00017d3d02e74d25, 0x000044ebb0b8e3b6 }, { 0x000ea3c28478a740, 0x0002405941768d8b, 0x0004451bbfd95774, 0x00025d7e24510399, 0x0000fd86525ee1de }}, + {{ 0x000301e47f2cd335, 0x0008b6ed9a475207, 0x000a3c833f852147, 0x000b42f8afbfe18a, 0x0000580fe7496353 }, { 0x000afffe040e720e, 0x000ebddb299b9777, 0x000b2ab785106b87, 0x0000a82e776697a7, 0x0000b8a44884646f }}, + {{ 0x000cfb5fa19ed6c2, 0x0007c4b28c22cee9, 0x00076d01f60cbc18, 0x000539b6aefb0ecd, 0x0000f84ec5d3906e }, { 0x0001527a37e73f9e, 0x0006d57f36e1ac55, 0x000ce5788145521e, 0x000c926db008fa9a, 0x0000af255a03386b }}, + {{ 0x000db8eaa84aa125, 0x000c9305bd213110, 0x000282e3a62f6f6c, 0x000e571d36ed41b2, 0x00002902def1b031 }, { 0x000bc226cb0016cb, 0x0003337b24b4b6f6, 0x0007e66af842d281, 0x0008210d9fe58afe, 0x0000f22b8a2b6b8c }}, + {{ 0x00062dbbba9d84ad, 0x0008b4ece53c2d04, 0x000d18184b2003a6, 0x0006765b0779d897, 0x000067fc9538f5d6 }, { 0x000035f7ff931704, 0x00005f2cafe37b68, 0x000f6c983617d6e7, 0x000df03fd273d1eb, 0x0000249da2e138a9 }}, + }, + { + /* digit=21 (1,2,..,64)*(2^{147})*G */ + {{ 0x0009d1febf2de9a9, 0x0008bc77e6c55202, 0x000fb2e7eb995763, 0x0009cbd6dc27df9e, 0x0000444476cdaaa8 }, { 0x000ba7ced0785f36, 0x0004b9e93470afed, 0x000906fab0ce1fe7, 0x000bf2f043e6a966, 0x0000d9c1876fd26a }}, + {{ 0x0008d94f6be7acf2, 0x0000341338d6e434, 0x0002fc6886610503, 0x0000f96ca56f7dd7, 0x00002f54a7c972af }, { 0x0003e19d89ed269e, 0x00005bb2ef8279cf, 0x000a1736ca68762e, 0x000fbb351d575465, 0x000061e8deb175a7 }}, + {{ 0x000f96f33f9e0680, 0x000b268e32dd620a, 0x000eb2e15662f4a1, 0x000310882913ec99, 0x00003ddc488aba8e }, { 0x0003f9b5a7ed9adf, 0x00058e5dc3fa8a51, 0x00019cb68475d2cc, 0x0005558b0236bb53, 0x0000fb0d86c8819c }}, + {{ 0x0002aae2b99711c5, 0x00031ce51efb3108, 0x000412e3130475fc, 0x00003c959cb5b2eb, 0x0000efeaac806f9f }, { 0x0004837f98bf8cb0, 0x000da39411aa636f, 0x0004e03d299b3bd8, 0x0006376b77152ecc, 0x0000b7bc15a5f18a }}, + {{ 0x0001162ade988968, 0x0009ac4c753c45fb, 0x000648b216204571, 0x0006f3be618ca81b, 0x00009a6be30dbc18 }, { 0x00042cd4528f9326, 0x0008720236e3ab64, 0x00056e788ed3e0dd, 0x000e9967af88cdaf, 0x0000c45162d8c709 }}, + {{ 0x00083eca38629302, 0x000f164b71698f58, 0x0002173c96261574, 0x000a82abb6ba418d, 0x0000a7d774e7d73d }, { 0x000c1dd5576a4dbc, 0x000283ff3437f24a, 0x0001f86ddde594be, 0x000503b65e910b43, 0x00004e079387d0c8 }}, + {{ 0x0004a222c42e90db, 0x00035f924a0a3fcd, 0x000413dfa13526e5, 0x0007cd19938e17bf, 0x0000dbc59707ebbe }, { 0x00038d8fd101963f, 0x000debe13f542b66, 0x000d80984486c605, 0x0005578791fc65e0, 0x0000318e04247e1c }}, + {{ 0x00039d3ee2963f2f, 0x000233a626332d5d, 0x000281c47c620310, 0x000452fa27bc3883, 0x00006bc300c4cda7 }, { 0x0004c341a09ee9c3, 0x0003ad3e7676b0dc, 0x000f36ad1e76c678, 0x0007b36a8620e35f, 0x00009710f4c3af53 }}, + {{ 0x00073207beab3a63, 0x0009a2f69beb6e85, 0x0003163e05455030, 0x000493e4f3a50b99, 0x0000ae1c490dee61 }, { 0x000c1b26b4aa0c62, 0x00020e309fe7e5b9, 0x00039f25812cb0ec, 0x00023f4e2957678a, 0x0000be251e8728aa }}, + {{ 0x0000e7c2becbd6ac, 0x000da1cf405ff065, 0x000cf786bfcc5059, 0x0009287fcebac86b, 0x000006628092b297 }, { 0x0003a21f33a3f231, 0x0006f95fa90d7679, 0x000b52ce8c481fe2, 0x00088d46dae60eb7, 0x0000dd27b34c3095 }}, + {{ 0x00081eea1daaae26, 0x000110babb886433, 0x0006eac32b7bbb8e, 0x000c7f07191df36d, 0x00000e8acae417e0 }, { 0x0009aba1faa58bab, 0x00046ba39966e6ca, 0x00083d7db2981427, 0x00026c07f7c464a2, 0x0000d90bb6000f64 }}, + {{ 0x0007112386fc20ce, 0x0005122369b87ada, 0x00088beb81cf895b, 0x0008f96663c00e5d, 0x0000786fe6f72494 }, { 0x0003cd4c08b1b97b, 0x00066986d9bd5f51, 0x000845f5fa36c27c, 0x000c259b22dcc7e3, 0x00003a7a6a264018 }}, + {{ 0x00066ec8de9b7d5f, 0x000fef8e32377106, 0x000e65642ed171bd, 0x0002ca92b0dadb26, 0x00004cd467fccd49 }, { 0x000b7d34d2311a46, 0x000d8d5ee5242161, 0x000b265d7be3eae2, 0x0006c90bacd93c59, 0x0000677b279563a0 }}, + {{ 0x00014104124194f3, 0x000f16022caf46b4, 0x000f5955fa3d17a1, 0x000fa544e6a45dd8, 0x000027f7e6432277 }, { 0x0001bcd329f0aee1, 0x000ac1241de97bff, 0x0000cbc3ebca8120, 0x0002c1f37b8547b6, 0x000028b36f4746d4 }}, + {{ 0x0003e297caf789c4, 0x0006a0910caad676, 0x000ff14f0a163a1f, 0x000c604401f59195, 0x000036cf5f7f1567 }, { 0x000cd19846f4da2f, 0x000dc2e49abad67c, 0x000c206c18924750, 0x00014ee406ec405f, 0x000043041d3be98b }}, + {{ 0x0004a07f82ebea7c, 0x000b5769bb816483, 0x00053090a14d150d, 0x000e04062d69eb48, 0x00003488c7727160 }, { 0x00062b085ef31ed0, 0x0002787bbfb55541, 0x00004cb77b99391c, 0x0007343a0b06ed4d, 0x00001334165040ae }}, + {{ 0x000ae1cac5e3f9c0, 0x0000b31e0dd3eca2, 0x000cba4d48dfd8b5, 0x000c10297c6237fb, 0x0000108543603d43 }, { 0x0006f85dc5404165, 0x000a2d47845ae4f6, 0x00026761151b0706, 0x00037b0bbfec7dd9, 0x00008f9d062c7bdd }}, + {{ 0x000c6ff6e5be4b0a, 0x000ae88bdbcf0ca3, 0x0006a2b7a7ba1b36, 0x00009df34d75f5da, 0x0000309466d23eb2 }, { 0x000f30b5ece886f8, 0x00084f4047d26e4d, 0x00077119364a90d4, 0x000524daff370f7b, 0x0000a8cfc76f60e6 }}, + {{ 0x000e32f8475f689e, 0x000ae624896246e5, 0x0006905dc38a3b9a, 0x000963d735652c01, 0x00005aec6e092828 }, { 0x00069e5622c8ef2d, 0x0008612cf933c835, 0x000dc3e0f1c33e14, 0x000acf715d05bb76, 0x00001af4af25e9cb }}, + {{ 0x000f6d12f8d61cbc, 0x0002f3a6568013e8, 0x000e93853103e5cd, 0x00025b74a8dbd203, 0x00007ce46d1f9bdd }, { 0x0000b6a7c6e4974b, 0x000c5a2c9eade291, 0x000337266751d4ee, 0x00084c246bab4f32, 0x0000f12b5a16b482 }}, + {{ 0x0004d506bf73235e, 0x0007ff33035b41cc, 0x000ed4ef51d687f6, 0x000a4f9e5d336343, 0x000094104ca078e1 }, { 0x000895041f284f32, 0x00096cbbbc33f758, 0x000a09cdc35e1489, 0x000caf6237281f08, 0x000051a7f97c87c8 }}, + {{ 0x00013888f004cd15, 0x000d5499c438edfc, 0x0002d0b53154f812, 0x000ed3bf07678dcc, 0x00000b340fc797dd }, { 0x000ce0637b7a5424, 0x00036d41140af420, 0x0003858e6e2c47bf, 0x000a2455f8e5104f, 0x00009c5fb7f1500e }}, + {{ 0x00000c81b681942b, 0x000d6e6fe631e8f0, 0x0007d7b150953146, 0x00006a94f1c5563d, 0x0000b00f364d03b5 }, { 0x0006d17634ee0c1b, 0x0008e51aae1fd9a7, 0x000716897755713c, 0x0008cab22e35626c, 0x00003897cfcc2e16 }}, + {{ 0x000127ee79d5b629, 0x000e4daeb300f7aa, 0x000c4c8df9876122, 0x0001efb4c9dcf7df, 0x00001b98eaecee9f }, { 0x000be67d99c079ff, 0x000cd53575f1dbba, 0x0004d4ff98848810, 0x000ac51d095037e8, 0x0000af6c7913e968 }}, + {{ 0x000227b7d5fa2779, 0x0001b4b3f8e10652, 0x000610e6d14e4258, 0x0002b8836ed908cb, 0x00003ee0ee50ff75 }, { 0x000381ae0cc87753, 0x0007593b5cd6dd54, 0x000162a5e8db86de, 0x000a18e2c82225e1, 0x000026e1628fc502 }}, + {{ 0x000ea9dd3d739ece, 0x00045d37fafa4c8b, 0x000145e7cd82c0ba, 0x000ca584c3d91808, 0x00000a483c77e1ca }, { 0x000b89ee5c5235ad, 0x00023673eadd3e7c, 0x000739e9ce7c6b70, 0x0006c9b6c0033c1b, 0x000042ac04521d0b }}, + {{ 0x000ec25669d8ed84, 0x00024f322532e5d5, 0x000013bba5e2b6f3, 0x00079a2dbb6410ff, 0x000030dbc6caee49 }, { 0x0005a7ea04cc0c9d, 0x00091064c3beb017, 0x00000526bb51e340, 0x00076ab7a852123d, 0x0000ef64f923f62b }}, + {{ 0x0004049e0b602df5, 0x0009a356798e4ba6, 0x000563cc4285eaa9, 0x000fb0f039214e6e, 0x000054c04a0b7d50 }, { 0x0008dabf1a099126, 0x00034f13ae9841ff, 0x0008b7dba38bfa5e, 0x000b40e58dbe4ca1, 0x00003b573ac345f0 }}, + {{ 0x0000c60f36acc716, 0x000daaacce2793bb, 0x000e1526388b0989, 0x0005c39a971db851, 0x0000043ab896078e }, { 0x000ff069e32c40e4, 0x0008d21774eadbd4, 0x000f7e41ce7fd901, 0x000c7857625367fa, 0x0000b451922fe6a0 }}, + {{ 0x0000e7363ef92c3e, 0x00014568776e6676, 0x000c515535767ae8, 0x0000e4c876e76142, 0x00007574380ed322 }, { 0x0004548dca9348c5, 0x000800eb7366d800, 0x000a43e34e14c3f8, 0x0008b6c6fe4ee14c, 0x0000f0365a22d0d6 }}, + {{ 0x000b8dd3d3c731b7, 0x000974c5ae888eb9, 0x0000bb5bd8c5d56d, 0x000390929733abb5, 0x00006206511f4cf3 }, { 0x0006c1ff0991bcef, 0x0005d920bc5d11a2, 0x0007759d899a17fe, 0x000604db8f20127a, 0x0000afba4da06484 }}, + {{ 0x00027d09f86b87a6, 0x000672f7189e71f4, 0x00081c5287eec6df, 0x000edd421c643874, 0x0000dd3e802a5f6f }, { 0x0005cba1123d99ff, 0x000318f38384a7a9, 0x00041aa78a8746d0, 0x000ea5919aac3acb, 0x00001546626df6d9 }}, + {{ 0x000d7ba8b08355a7, 0x000a87fb00009c49, 0x0006f276e2aeebe7, 0x00041f05db8396c2, 0x0000859783ac9299 }, { 0x000c3a6250aec83b, 0x000b59f34f485b64, 0x000c17d7c2c584c4, 0x0000c36febc0ddac, 0x00001a06deb2c157 }}, + {{ 0x000630745c2443f6, 0x000db03d1295837c, 0x000f71d776d34583, 0x000701e91a2893e4, 0x00009134f5638299 }, { 0x000d8586465dff85, 0x0008b9e48661ae16, 0x000b7ca5a02e6a92, 0x0002951b58d17e7e, 0x0000e3f1660e4165 }}, + {{ 0x0009be4d8ef6f6d7, 0x0004d3e19115ead5, 0x000df1ee024075e8, 0x000331b5b1ce1393, 0x000093c9ce9841a5 }, { 0x00058519cc609023, 0x000bd6cd0def72b5, 0x000d8aaf0d7bacb6, 0x000dd273db923db5, 0x00006b02deb40132 }}, + {{ 0x000c548b69ea5df5, 0x000f6f8827097ef5, 0x000b740069f3544a, 0x000d0db89259353d, 0x0000e612d2045282 }, { 0x0008b57bb32e6372, 0x0008416994b995dc, 0x0005dcceda4ea724, 0x000bc67f04d1531f, 0x00007cded8a96b16 }}, + {{ 0x000c6b9000bbb209, 0x00006cb1cd5ad73c, 0x000594d94a4eac92, 0x000b0b5b8b9c860e, 0x00007f19f8ffa9c8 }, { 0x000d03e590e97791, 0x0007ca420c8a471b, 0x0000bafb9a1ec30a, 0x0003e497769ae05a, 0x00000ae589eaa8d6 }}, + {{ 0x00098231b2fdae8d, 0x0009e5eb2940d9e2, 0x00062218c3b180d7, 0x00034763d3c663d8, 0x000079ac5ceb7ec0 }, { 0x0008b408269ba673, 0x0009a2c552ad093f, 0x000c06d13e6ea662, 0x000789a00a4799d1, 0x00006bad7b20b037 }}, + {{ 0x000f3764f7b38e54, 0x0005dedf1bd72186, 0x000adbed6377389b, 0x000079665d491c53, 0x00000d1755479780 }, { 0x00048c7a526618d7, 0x0003a6dcdc348009, 0x00062d56bf03752a, 0x00092516bcdbcd45, 0x0000cec167b1ee0e }}, + {{ 0x000439be9201d0e9, 0x000c1377378058e6, 0x0000a00752c2e9b0, 0x000b1a1c741c746a, 0x0000bb3ea39e2af9 }, { 0x000f7de5688e9cd2, 0x000e2b043a2fbad0, 0x000f733802d7bd56, 0x000faeb4c39e6dad, 0x000033ce90509fd4 }}, + {{ 0x000b539dc2f62b1e, 0x000a7a1d2ffbfc15, 0x0009f177c68e623a, 0x000880758f74211f, 0x0000f1010e0ac5ca }, { 0x000a989eca797cca, 0x000b9d02f3af6f6c, 0x0007cefab003de17, 0x0004d1f835213207, 0x000053ff9d904563 }}, + {{ 0x000c547b711b42fe, 0x000ca29d6f62f995, 0x0008efd6009b4f01, 0x0005dcd0a8f06a30, 0x0000d50d91362f7d }, { 0x000916e5205bf484, 0x000bce1682afe112, 0x000a522adb87ea28, 0x00018d9369e0fc77, 0x000083acc24ddd86 }}, + {{ 0x000fc96822eaed69, 0x000e9e83f883faf0, 0x00091bbd25130ab0, 0x000b42f81396f963, 0x0000c9a426aabc61 }, { 0x000ba8446d25cd38, 0x0003d8766f1c68d2, 0x0003cf9f27a01b56, 0x00052259010fc6de, 0x0000b7f2dba90c5e }}, + {{ 0x0002ac509835efa4, 0x0001520ef4a9975b, 0x00037083f2c76c48, 0x000c843b560bb600, 0x0000295a37fec299 }, { 0x000d83ca9a68bcb1, 0x0003d2fb0d1ea67c, 0x0009a7419796877a, 0x000c6d9e6ae779a6, 0x000089f4f8df2e42 }}, + {{ 0x000ecbc81ce29d74, 0x0004af5e33deed3a, 0x000e514cca8bd88a, 0x00042493ee6356f6, 0x0000b9f30d92af98 }, { 0x000e29242f1443f0, 0x000c909e6e861dcc, 0x000385ccd3d2d0ba, 0x000f07e5790a247a, 0x00004947dfd69c12 }}, + {{ 0x0001d1645c39f241, 0x000e04a2f998a912, 0x0001b2e98e1ecaea, 0x000d02622271ee9b, 0x00004196510475ae }, { 0x0005bbdedb159a7a, 0x000aa2c7501779c0, 0x0007f452a12df2d4, 0x0007df729f006140, 0x0000ac021b7f9c4a }}, + {{ 0x000c314056ab1eb9, 0x0008f3225d984730, 0x0005503443d0bd10, 0x0004846a1f207fe8, 0x0000f455eb506396 }, { 0x000e1c005b309371, 0x000938f4107e28f1, 0x0001230567e4dd24, 0x000104f6e74ed387, 0x00008f86c0103426 }}, + {{ 0x000a793b2657b1ce, 0x0005c73f37ec3c39, 0x000d42e0b07a8381, 0x0009b6457c65259b, 0x0000b5dfca037683 }, { 0x000a1d4307f2b6b5, 0x0002e4be43756f0e, 0x000db0de13c200e9, 0x00069d6272f76bdc, 0x0000caa7d0f8726e }}, + {{ 0x000ad40c5a7ab2a8, 0x000ab308bdf623a6, 0x000a196def2311a6, 0x0002b55955f5accd, 0x0000420ad92fbdb8 }, { 0x000ee1c791d19a99, 0x0002189aeca8709a, 0x00007d42c30b7260, 0x000c8e176c64a7cf, 0x00004c391ad3c0a0 }}, + {{ 0x00097b04cf4dcd27, 0x00071fd21a843b21, 0x000d738557e2a32a, 0x0004063be56e4ed4, 0x0000f569b199b0d1 }, { 0x00027ecdb28f119d, 0x000161ffd42c13f0, 0x0002b190c58ab2e8, 0x0004f1dd45ef7feb, 0x00003bb3c53e8fce }}, + {{ 0x000985b93206998e, 0x00056d14e3352feb, 0x000eb9d3625dfe11, 0x00040ef6008414d2, 0x00001dabe9e71cb1 }, { 0x00010ec86988d8f2, 0x000e1ab96bf36f90, 0x0005bad089761cb9, 0x00093257d012dbed, 0x0000392d438d5756 }}, + {{ 0x0006074b7b7f3ff9, 0x00007f6bf926dffa, 0x00014eb820473ad7, 0x0009a18f57c9fdbd, 0x0000f0b5518a13e5 }, { 0x000bb55bbfa1756b, 0x0009566e84f44a48, 0x000846c6398e72b1, 0x0007e239a99998d3, 0x0000d5d77e99f313 }}, + {{ 0x0002f49e3766fab5, 0x000bdb40ea2ab303, 0x0000c448caa69039, 0x000c82cebd365a34, 0x000050f4208830b2 }, { 0x000004213cabc507, 0x00050f101d8b4d66, 0x000bc6b055c40b77, 0x000137b6a03c8423, 0x0000747dddf18bf9 }}, + {{ 0x0008f4ffcfd9c86f, 0x000f5a1c1c06681f, 0x000ef60c8e811dc3, 0x0007a43b316e0a16, 0x000027129f4ec201 }, { 0x000aba00062f76e3, 0x0008ecd4cc5e3e06, 0x000a366fe3da9e55, 0x0003be8f1d55c7cf, 0x0000d191984e99e0 }}, + {{ 0x000c5d7ec808f4e1, 0x000fa30d232cfc4d, 0x000df92cbe274727, 0x000ebb0499ddcf12, 0x00001e2f6a31d47e }, { 0x000abfb950d7fce1, 0x000b76e0b50d7dd6, 0x000715bf57d98c4a, 0x0000e08f688fdbaf, 0x000030c606a9d9d8 }}, + {{ 0x0002335df2a1fb08, 0x0003c878a429f4f8, 0x000b591e08172eac, 0x0006eaddf0649712, 0x0000e4d7ee646545 }, { 0x00038956fb888a73, 0x0007d675c93d9950, 0x000a64de24ea9aff, 0x0004f221b59ac367, 0x0000ca2c7aa20399 }}, + {{ 0x000ac7d898fb100b, 0x0003dcbbb734e37e, 0x0001411dd9d6657e, 0x000a195d9c08c0bf, 0x0000b128040fa2fe }, { 0x0004303f220f9f80, 0x000cbafbc1a6dea1, 0x000f02fa70b9b9bc, 0x00096441afdd0e2b, 0x0000f73ba67d9a72 }}, + {{ 0x000a9157dd651c99, 0x0009d210408f237b, 0x000a32417a1054e9, 0x0008f1da2cad3b09, 0x000057f0f2c67ced }, { 0x00053cba344ed082, 0x000b3074f013efbe, 0x000ac4fc0a6eafae, 0x000d5c1451b112c4, 0x00003f0ad4322c4c }}, + {{ 0x00074ea0b52dc146, 0x0001a63ded40d232, 0x000d2d41ed701785, 0x0007af6313d5f1f4, 0x0000d9a531a3ad12 }, { 0x000744ef50a57f11, 0x0007c99451d1b71a, 0x0002e834e0295a02, 0x0004f26f580e8264, 0x00004d9fa000c2ce }}, + {{ 0x000fe5e5592df016, 0x000d1f5cf551396c, 0x000db6a682124601, 0x000541636c616898, 0x0000d5c526596e5e }, { 0x000fa2cd6fae11ac, 0x0002c187051f476d, 0x0005354d66d26431, 0x0003324f656fad2a, 0x0000bcf48f474c5c }}, + {{ 0x0002136d7196d889, 0x000f83ad15d15174, 0x0001f569d783786a, 0x000612a5f61214cb, 0x00008b285ec5b82f }, { 0x000ec5c4199a8b19, 0x000581b084172219, 0x0002b38e963dfce9, 0x000c53f2d0a5546b, 0x0000d57c27a12776 }}, + {{ 0x000378c25b25433e, 0x0009ead771849f1d, 0x00042e5efd140744, 0x000ce30b2b0c932c, 0x00002dbc7048e363 }, { 0x000fbfe01a53e807, 0x00099da9e6e3e319, 0x000d16caf5b6722a, 0x000dee6b80417a54, 0x0000e7b46d452fce }}, + {{ 0x000e093761507e7d, 0x000a805ba9384a2d, 0x000d86a4325fdf2a, 0x000bcb8a621b8596, 0x0000d301c511e847 }, { 0x0004f1d7d5d3607e, 0x0004ec8f7bffe6d9, 0x000ec8a24e675bb4, 0x000936e3027566bf, 0x00008ff4238ff05a }}, + {{ 0x000842e7e3646f13, 0x000721aaaca5e9b7, 0x0000de2e53b43348, 0x0009b4ef6518aa52, 0x00004c1f8413e3b0 }, { 0x00027091000d9504, 0x000ab656868a5489, 0x00024df86b81806a, 0x000fc7333d963bd8, 0x000027dffecf8b57 }}, + }, + { + /* digit=22 (1,2,..,64)*(2^{154})*G */ + {{ 0x000de8cdd0926a17, 0x000b2a7d298c241d, 0x00097897af2c8ee1, 0x000fad3dbe3b697b, 0x000095a39dc131b2 }, { 0x00088519ea3f0b69, 0x00087a75a4d2604d, 0x000e93901ec55560, 0x0004fb6cc27154d7, 0x00006bfc52e1469f }}, + {{ 0x0002571fa1c005d3, 0x0000a1a7cb1282c7, 0x00064bef7798f823, 0x0000303b2a08d762, 0x000094b95e409f27 }, { 0x000cc832f936b83a, 0x000392ff22dfd98c, 0x000633bedd944ef9, 0x000cfe67a87ab01a, 0x00004e149b05af22 }}, + {{ 0x000f839761bec299, 0x000fc0e36ff3bf0c, 0x000f212faed6d78a, 0x00014bf5f8ad20f6, 0x0000003cd07951f7 }, { 0x000f568724f96e64, 0x00061b38288c545c, 0x000a43bae4ac5ec1, 0x000b2bcef2f8e4e9, 0x0000482335f80a39 }}, + {{ 0x0005d70b7657b7a1, 0x0007085ca8d9d1ae, 0x000cf3b0d35bf0d7, 0x0000cc024adf2c77, 0x000069d110cf7a09 }, { 0x0003a7564e157769, 0x0001d506260e70ff, 0x000703a97ab76d5e, 0x000435a6439d75ea, 0x000076aec3e36360 }}, + {{ 0x000b491d7bce26e6, 0x0001ecd2f52d2a7a, 0x000a379638de4a08, 0x00078ccf74fde149, 0x000012daea2770d9 }, { 0x00082aa266a6dcf5, 0x0007718c6312c7fe, 0x000c827977f0f2fa, 0x000766ea0ca0d5f3, 0x0000282fd2c5bf2a }}, + {{ 0x000b4394784f1e40, 0x0000700ec3128c2f, 0x000192f4aad1458d, 0x00011e4eb6c76d86, 0x0000e130115cd871 }, { 0x00052289429acd15, 0x000614a8dc796230, 0x000daf1e7270619b, 0x000f8d90d5b86995, 0x0000166c13057d31 }}, + {{ 0x0006fdbec46ef830, 0x00010a51e6a75c1d, 0x000537aa19534622, 0x0007f159724327c7, 0x0000279e5d72bd98 }, { 0x000d87b2825485ae, 0x000effb13c90f48c, 0x00029ae73fe0cc43, 0x00070a0ebd6ac527, 0x0000b44da3075aaa }}, + {{ 0x0002f99d592d4607, 0x0009d3e3fcd3efca, 0x0004150ef1418504, 0x000f73feadd26c03, 0x0000c8303bb7708f }, { 0x00028bb4209cedef, 0x000e4552f1da46cd, 0x000d486f19b140bd, 0x000e6167872c3f8c, 0x0000b4a36e89cdf5 }}, + {{ 0x000c77a0a3360371, 0x0009611745edc116, 0x000cd150d4b51af8, 0x00099ad649dd9ad7, 0x00009c97f502587e }, { 0x0009ae48860379bb, 0x000eb296baf7cb10, 0x0001c348e49c5f3f, 0x000e9d571cf065f9, 0x0000b56bcf3f6375 }}, + {{ 0x0003b56be8e6e5b5, 0x00086ecee8314f30, 0x000dd834bda67796, 0x0009af7ec1c068ae, 0x000043ec03cb0895 }, { 0x000635be527dea03, 0x000b5f29222882d6, 0x00065e79cda53115, 0x000db7a8c95ff38f, 0x000042689771e2a1 }}, + {{ 0x0006fa038810126b, 0x000e776a5177900a, 0x00074f8b83c9f4be, 0x000030e6c4e1dbb4, 0x000046c45fbd9ab6 }, { 0x000f312eb8992e97, 0x000c6562844c6d0a, 0x000a547118c55450, 0x000088ad6c633cf9, 0x00009ee0bbc48794 }}, + {{ 0x0007709b7b97f8c5, 0x000cdd2e7417ce17, 0x00011f9e4c798c2e, 0x0006edf1eff42bc7, 0x0000d3407d05f1c4 }, { 0x000b2930ca06e395, 0x000de1dbe217f2cb, 0x000ca08df0ad2e70, 0x0003a3b592af2a8c, 0x000040a4a94b9f52 }}, + {{ 0x000519834b80ba88, 0x00058477d930cfc2, 0x000114564ea90584, 0x000e06fe14c262ad, 0x0000425017607c82 }, { 0x0004968949e7bfda, 0x000414cd105f961c, 0x000511a5410a9516, 0x000e2177ca5415da, 0x0000759aabd156a0 }}, + {{ 0x0008eb87587c0983, 0x0000e26cecdaa7af, 0x000d12279d229b41, 0x0007b3ec4fc8c7e0, 0x000092acdf0c79b8 }, { 0x0009f00adefde818, 0x000ea12c00674527, 0x000e01ab878d0446, 0x0005ac2f43f6f69e, 0x0000c28cfb3ac1f1 }}, + {{ 0x000aae38b1dc4f8d, 0x0004e7181236c972, 0x000b14323f6d85c1, 0x00094867274f7685, 0x0000efff992ec9c7 }, { 0x0002818fa5d10725, 0x000bd22f6dd9d1bb, 0x0007a909d4e14581, 0x00027b9aa5769544, 0x00000f6612b6817a }}, + {{ 0x000cf60f96d10e48, 0x00095daf176f2c08, 0x0004556116c14d5c, 0x00025e7fb01ca460, 0x00006c4e588656b4 }, { 0x0007fb754d3440e4, 0x000851cc9071c4aa, 0x00038c48b2b6677b, 0x0005b2981fd58874, 0x0000cc23558b384c }}, + {{ 0x000a3165c2d1e96e, 0x000ce5cd51805e1f, 0x0008b86876e5f775, 0x000018700ab4ccd3, 0x00005515bbda4876 }, { 0x00052c258fdcb035, 0x0005654e160e552a, 0x0009eaedab8f23ae, 0x000ea157adc4972b, 0x000066592aa69e2f }}, + {{ 0x000ffedd92412715, 0x0008af4c1e99d816, 0x000633c73a2eb72e, 0x0006556a708e1a7d, 0x00002684c134b0e3 }, { 0x0009bf250d515cb9, 0x000a0d2d629d2080, 0x00052ad12e01390d, 0x000f3a089a9d141d, 0x0000fb8a94900ae6 }}, + {{ 0x0005d66a6d649943, 0x00090b1b38227904, 0x00004de22caebda1, 0x0005eb7626c5926c, 0x0000f67f61d51111 }, { 0x0009445c606af316, 0x000c063987d2792d, 0x000c656ec0cad92f, 0x00039a3e64a73caa, 0x0000e4821ae46138 }}, + {{ 0x000981afc00085d1, 0x000d0d5af71013f7, 0x0004926c19866a71, 0x000ed9fa0e68216e, 0x00008c7bcfc44bd1 }, { 0x0005694612f9623f, 0x0002b679449f0e1f, 0x000d14dea79b08e7, 0x0009c8b2286cfc4b, 0x00000d346cc223b8 }}, + {{ 0x00096cf17200d729, 0x0008e23901515ea5, 0x00051b2ffec6cf8c, 0x000c727594c6c77a, 0x0000320acc1aeeaa }, { 0x000269e868e20629, 0x0002afa6530ae7aa, 0x000d6528bf3d9e09, 0x000d558c90f5e631, 0x0000229c5edcbc0d }}, + {{ 0x0004cc22b4444cf0, 0x00009e12cb7191e8, 0x000860e46bf2a7c8, 0x000e63bb978ea1bd, 0x0000d8fbe677e701 }, { 0x00039a0269232967, 0x00082e9d49d5bf18, 0x0005956e7b3add6f, 0x000cd7c57cd4ec1c, 0x000020dc2c6c5c8b }}, + {{ 0x00021474c07616b6, 0x0003562c6d8607f9, 0x0004d89521244fd3, 0x0009dcd17759689f, 0x00003d544887a945 }, { 0x000f77453607db96, 0x0007d5b2a354c8c4, 0x000231b85f7fc2e2, 0x0005589e8d51e52d, 0x000081a4d861604b }}, + {{ 0x0001287ee355832e, 0x000a8715bde48f8d, 0x000250613d9a672a, 0x00086c08ac970387, 0x0000dae19fd8bb71 }, { 0x0005fdcbcf36d30f, 0x0007974db1dbf1fd, 0x000ac30ebd07464c, 0x000637413ea46588, 0x00007cc18fa7cb4d }}, + {{ 0x0000a61162698c8d, 0x000e043810d5ab00, 0x00090431d46a2727, 0x000a6ef336739d8f, 0x0000a26b0295f5a3 }, { 0x0005c0032a22784c, 0x000f53b379f0a1ff, 0x0004f422a86b7376, 0x000e6cd9cfe12660, 0x00003c940fd45b0c }}, + {{ 0x00089fa086f4a3d4, 0x000903037577dd85, 0x0003d1265e0202f1, 0x00019ed3283b82af, 0x00002538201d9fd9 }, { 0x00032bd123d0e234, 0x0006138b13799dff, 0x0000df69ff10325c, 0x000bba8ca85fa8b2, 0x000057bcce5a1bec }}, + {{ 0x000774df733efabd, 0x000cba7858b044cc, 0x00019335042416f4, 0x000dd98591f0d69c, 0x000024cd837a5001 }, { 0x000d42a35cffec65, 0x00084f6d3bd2e1c7, 0x00002b1b5b735de0, 0x00000a4c4eb30da2, 0x000019e181b75ed4 }}, + {{ 0x0008561eaab750ec, 0x000fd959890272db, 0x0009861b1b6617ec, 0x000313bb875f3432, 0x0000725d0e14f52b }, { 0x000a16eb56377ba8, 0x000efa08332aafd7, 0x0004f969b00c6f26, 0x000e75b6f9b0d8bb, 0x0000fe905ed9a6d4 }}, + {{ 0x0005c59502191a75, 0x00080f678e62ddc9, 0x00037237e0292642, 0x0002906be2267c45, 0x000076e18afb6945 }, { 0x000b67703ed66163, 0x000fc85f2b254d9a, 0x000c814dbb101610, 0x000e0fcb5844b617, 0x000051187f47b6f8 }}, + {{ 0x000df6ef65292f82, 0x000ccc13cf482834, 0x00054e9380f92393, 0x0004dcd84b09daa2, 0x000002ad22636b32 }, { 0x0004d671be580fab, 0x0005c63aa21ba469, 0x00080dbd873d895b, 0x00010ffbfc6b1d17, 0x000037d32eef447d }}, + {{ 0x0008511a63429641, 0x00057cf4f5792fac, 0x000648d037fe39e7, 0x0002f65d47c5e0d6, 0x0000b0155eccce65 }, { 0x0003bd08cf6b4388, 0x000da1ca5a60d998, 0x00084ba13ffba0d2, 0x0009a6608f7fbab8, 0x00000b92a4ebd38c }}, + {{ 0x0009badc329d1f15, 0x000798a2ac13e274, 0x000f04f6cdc35ac5, 0x000fff5624494f6d, 0x0000234123bdb8fa }, { 0x0003d01cf2e4388b, 0x0001a41004f7571b, 0x00002b4c77fb6c86, 0x000ef3131bac67d1, 0x00001a55a5e1aed2 }}, + {{ 0x000dc88b3456a9ee, 0x0008d1b55fd0b8ba, 0x00035123a63efb0d, 0x0006484b7a099d18, 0x000092c90c828310 }, { 0x0005f1462aa51ab5, 0x0006c6af989d9051, 0x000013c446d68fcd, 0x000caa593c2e68d2, 0x00006aa1218b67ca }}, + {{ 0x0000bd29c9340da1, 0x0003275ea3d62f2e, 0x0002210b6db3e508, 0x0006d85f6a17765a, 0x00006dc8a9e841b0 }, { 0x000bb9f1ed8d6637, 0x000606d08d84858f, 0x00046e14e3d3d3f9, 0x000cec356370dfe8, 0x0000614d73954f19 }}, + {{ 0x000e324aa43d7d34, 0x000b853060dd7ef1, 0x000d50332ed5585a, 0x000234e35eef2dac, 0x0000e1739c044fa5 }, { 0x000d402c7e387317, 0x0006771e6e676710, 0x0000b212ce791c9b, 0x000c9af2abccd519, 0x0000dc23b3bd97e9 }}, + {{ 0x000480be272bb944, 0x0007c39306a5a3b6, 0x000d31f77bf47852, 0x0009a89d44e0a41f, 0x00005f69215972d6 }, { 0x000a8f43e1bf1716, 0x000481d2285f3821, 0x000fd17c18552f1f, 0x000f83782188d8d8, 0x00007bd976ec665f }}, + {{ 0x00075ffd7e18ac01, 0x000216d77aefb3a4, 0x000dd712c4d568bc, 0x000ad4cf1f69a751, 0x0000e55f50391cd0 }, { 0x000dd2e229415715, 0x000adb13844e95c1, 0x0007bf400d6b744b, 0x000af280085caf64, 0x00003a42515d76af }}, + {{ 0x0000db2ffa6b60c9, 0x000179d73d172440, 0x00068eeb23f6cd90, 0x000c0191c3ede774, 0x0000e518c9f2fb70 }, { 0x00079a440a790688, 0x000a43930cfd9057, 0x00042e26ce9b9861, 0x0008576954934d07, 0x000024bf5ca7badd }}, + {{ 0x000b28c70e222015, 0x000dd1897d6fbdcf, 0x0006e54ea39dea03, 0x000f2d3dbd3a5cd8, 0x00009af5dacd64b4 }, { 0x00051b3088c8cb5e, 0x0006928b61301a0c, 0x00080e5712cc3715, 0x000c4a0dca628216, 0x00007183a4f877ad }}, + {{ 0x00033f48d51a3fa9, 0x0006b7c3902dda59, 0x00066b2a2adf8b68, 0x000179c7e35d2f70, 0x0000efe1c34ffaa8 }, { 0x00032c6af415357b, 0x00034884912beb26, 0x0005b30274a0ae30, 0x000fd784b7f5a4de, 0x000068784fca87f6 }}, + {{ 0x000f4a94d8f05720, 0x000d2e3753e43a97, 0x0006a58a4d66687d, 0x00096c6a670e1d21, 0x00003923588250bf }, { 0x000b64615e973715, 0x000f5968d4faa6a0, 0x0002a502553213a1, 0x0007fc6fdd9ed0b3, 0x00008fdecf871ce1 }}, + {{ 0x000e553fc34528cf, 0x0005148cfb9fad53, 0x000ce5b636f9dd65, 0x000b208bcbeaa386, 0x000021343a11054b }, { 0x00047831ec12559a, 0x000419b9d5f97505, 0x000a7e142922e027, 0x000f2299b3e85c52, 0x000013d6e4fdc33f }}, + {{ 0x000101b9ab1418b8, 0x000ea274a82f424f, 0x00078d463ef2df0e, 0x000ae812c36919c7, 0x0000a9078f376e2f }, { 0x000e6b4528b15e10, 0x0008e9c1c5009d2d, 0x0002be663e1d0b7e, 0x0007067c7fb55ea1, 0x000065c8a8ad08f2 }}, + {{ 0x0005e18cc10dacdb, 0x000c8339bb26f5f6, 0x000d9e6bf8f50349, 0x0006ca3541e85db8, 0x0000696b34c84786 }, { 0x0008da3ee5c6c70a, 0x0004550a471fe6ea, 0x0009863904b6dcc5, 0x00040278bf031747, 0x00002271b171d4f9 }}, + {{ 0x0000398ec951344f, 0x000641c558216b17, 0x000bbf4057f8b421, 0x0005a9e3c90c7810, 0x0000ef7c615f84ad }, { 0x000d37bb5223d947, 0x000fd9ef701b2350, 0x0003de5d38438590, 0x000f22d310ceecdb, 0x0000b63f014f16ac }}, + {{ 0x0007f5e17c602df8, 0x0001538b880d2dd4, 0x000b1d9d2bdaa4e3, 0x000343df5a60f177, 0x00003595db60eb93 }, { 0x00042647efbb60cc, 0x0007f57db394af4c, 0x000cac10af9a0c05, 0x000c6e87239ba215, 0x0000a63e0d4e1e73 }}, + {{ 0x00049c0c51c25079, 0x000fc4564488f1d6, 0x000890337983826b, 0x000946663aa92270, 0x00003ecfce6e8391 }, { 0x0006ae337281abf8, 0x000de4e3cffcb6c1, 0x000e3a48ea23ea44, 0x000159ca0e3bf93f, 0x0000c6e00209e63b }}, + {{ 0x000bda54e9b5f5de, 0x0003cdf5ca48f3fb, 0x00062650469b09ca, 0x00013c04a64352f0, 0x0000a9c900d6b80b }, { 0x00034c2438695df8, 0x00045f56f6e55fbe, 0x00033ccb4b4fad0c, 0x00059bdff1ca44a2, 0x0000d8197cd15076 }}, + {{ 0x0006b3a610c31e52, 0x0006975861421033, 0x000ae881563cbbe1, 0x000a35f226704ba1, 0x0000fa0894f27e4d }, { 0x0009ee25bb322589, 0x00037a775a0d0508, 0x0006b2f5187779d7, 0x000d880be066f919, 0x00000c76c7c238f7 }}, + {{ 0x0003422f090ad74e, 0x0009022fd29dc766, 0x0008d3af43571f67, 0x00073f3267fd32ed, 0x0000d0b442ee5f1d }, { 0x000b361400cf8a31, 0x000f3f40807e199e, 0x00003777308f86a0, 0x0002880b4fe9ce5d, 0x00000da749380f3e }}, + {{ 0x0003eea570082bb1, 0x00099052680813be, 0x000c722c6366b500, 0x000f4a458527aa55, 0x00005bce35af9e9e }, { 0x0003afeb82f8170f, 0x0002917a0ff58b3a, 0x000476b9faa4836e, 0x00052a6d6b67d3f6, 0x00006f5fdddf36b0 }}, + {{ 0x0009432bf6f80693, 0x000ae6d3e5548920, 0x000d39cafe4e671d, 0x0002c0fa08413b53, 0x0000a88888d1f798 }, { 0x000b84f7978aae7d, 0x000d3c6daf0ecc11, 0x0005404428b0ca79, 0x000d2960749ebce5, 0x00002f4edff10ec9 }}, + {{ 0x000b1771c2c13be7, 0x0001d818d1d7a0dc, 0x00026f583393b81d, 0x000627635d9fabe0, 0x0000399a341196f9 }, { 0x00046124aa70c355, 0x000f2cae9a6312bd, 0x000f80ccb41ae366, 0x000b5f216a34b355, 0x00003e9a5b7e359c }}, + {{ 0x000bc3dd47503d26, 0x0001d5d68afe8b4d, 0x000f9049b15a067a, 0x000db429827f2053, 0x0000558730c6cd22 }, { 0x0007e4665dbf09b3, 0x000e542c03b0c057, 0x0003013d5638d610, 0x000167b0a8b1b3bb, 0x0000b3ec98ffe86c }}, + {{ 0x000ac7168a05d60b, 0x00002fcd23e39845, 0x000c910a2bac02e1, 0x0003b40a7ab86e8b, 0x00007c554cfc6e51 }, { 0x0003931577b8f581, 0x00022840139d9af1, 0x000862d13578d007, 0x000e1ce4a72733f8, 0x0000f2968562b2ac }}, + {{ 0x0001f568c4e93444, 0x00095eb70f8d5a4d, 0x000705c64963ec81, 0x000e7c732375adde, 0x00006e492766c122 }, { 0x0003224c6ff30b48, 0x000b4835459df02e, 0x000a2cab4e0e2287, 0x0003bf30a2beac0f, 0x0000b7c08ff94828 }}, + {{ 0x0002d191d34652ff, 0x000d10ee87edf5b7, 0x0001ae15eb2221b8, 0x000efd2b230385f0, 0x00004abd2d05ed06 }, { 0x000564f3ba13cfbd, 0x0001dca0917d9e55, 0x0008ca2af9c50195, 0x000eb7b96394eab5, 0x000048607473d36b }}, + {{ 0x0003da3500cac108, 0x0001505d73654ef8, 0x00038ffd58742011, 0x000886ba068d1a9c, 0x00002aa8c6ea07a2 }, { 0x0008af07c42cfaab, 0x00051a468ae01189, 0x0009377e98a53d43, 0x000b0d802a1b9a4c, 0x0000f99f7b9d03be }}, + {{ 0x000dd2d01e319688, 0x000eb26995f0f9ff, 0x000f73e2bba85402, 0x000cbd22b467fadd, 0x0000ea7ba8013c8b }, { 0x0005ee2fa76c4cbc, 0x000f228c693f9fa1, 0x00091ea149f1bfeb, 0x0001539834862232, 0x000070ee1dffe6b5 }}, + {{ 0x00052e2214ff073f, 0x00089455777e1891, 0x000030410614a29e, 0x0006eecd5cc10bee, 0x0000bd74b27941db }, { 0x000b6dff74a64cd2, 0x0003c727cb23c74a, 0x000ffd9e676af10e, 0x000132a53fd5d766, 0x000022b0948b387c }}, + {{ 0x00015648065531e4, 0x00083816f4cbe9d9, 0x0008d90103d196a3, 0x000769dfa0ed8b24, 0x000076059de2f82c }, { 0x000b69dcba54041f, 0x0000c085b8628093, 0x00011a1bb0c183bd, 0x00005ca2a1facd1f, 0x0000198f2db6c25b }}, + {{ 0x0002cf1f8a6fd4d2, 0x000bc9f967365efa, 0x00024532d63e9c0d, 0x000ae632f57300eb, 0x00004160be5ee065 }, { 0x00025c377f9c4ca1, 0x000fa744dcc40cc3, 0x00057b48ec7bdfbf, 0x0004d2b4dfee38c4, 0x0000461e8ab76c74 }}, + {{ 0x000377f264a991d9, 0x0007fce476cc9ff0, 0x000cc35cd8ff3792, 0x000e04f9b580e0b6, 0x00003f7b7baf52e6 }, { 0x0008e50f30877c3e, 0x000156288e591a5c, 0x000cac3ebafa9eec, 0x000630733a453a7b, 0x0000a9492c65a23a }}, + {{ 0x00010ee253308b7a, 0x0006b0f6d3549cf8, 0x000f79be840ba3a8, 0x0008682b46f33696, 0x0000b318d895599d }, { 0x000485717b66f888, 0x00087e17159bb2cd, 0x000da105c3fffe4c, 0x000a76272f7dfbeb, 0x0000bfbd7894f96f }}, + }, + { + /* digit=23 (1,2,..,64)*(2^{161})*G */ + {{ 0x0005fd5fa205d0f4, 0x0004ee8ee36860ce, 0x000c5b16628b839b, 0x0003f4e13daf04df, 0x00008b3aaf4c153e }, { 0x0004e879df3f3f34, 0x00029941a4e0551e, 0x000d33e8877228e4, 0x0005911236772cfb, 0x00007681b72c03ca }}, + {{ 0x000e349a4b31aebd, 0x000f2b0285b94916, 0x0007b017d6137900, 0x0002b0dab01a0be8, 0x00008ac2977211f9 }, { 0x0006974d05362415, 0x000fd464a1c6a163, 0x0005f2a0e55b98f7, 0x000493f71d99e6b6, 0x0000a0e9ca0b6129 }}, + {{ 0x000b8f7229523466, 0x000e3a1cfe89d80f, 0x000cdf0d11487037, 0x0009c00d2b42c026, 0x0000172110f51188 }, { 0x0009ff21f71bf171, 0x00008ecd850935b3, 0x000c9c32bfbbecc4, 0x00028143434c1a74, 0x00001cad52349f90 }}, + {{ 0x000d9cce837c6d61, 0x0003d148f9290579, 0x0006232b855bab85, 0x0007c64ce7a64ae0, 0x000028043d63ffdc }, { 0x000f181a75f69e00, 0x00059796e93b7c7b, 0x000172a383b1d5d0, 0x0000029a0e1e4709, 0x0000b9ee91160db4 }}, + {{ 0x000b670a385747ca, 0x00062658ead09f79, 0x0004fc19c7159df7, 0x000d39cbc1335e1d, 0x00000025ace0a875 }, { 0x000ab38fcace8fb2, 0x0002a8128efbeedb, 0x000bc873171affc4, 0x000fee8630c74e77, 0x00001249e10307e9 }}, + {{ 0x000ba8e478b7779e, 0x0004ac85c0a3f1ee, 0x000190dedf06d75f, 0x0006c198dbcad249, 0x0000bec9ca1c42e7 }, { 0x000b123f368231d5, 0x000b7b0eeaede4b8, 0x0007ee649f7fb5a1, 0x0002f72fb0bc498e, 0x00003fa9b3e1cde9 }}, + {{ 0x0005c8295bc7ccf1, 0x000ebc7de79dc241, 0x00023fc74071d988, 0x0004b5fdff1168a3, 0x0000a46cc6dd3945 }, { 0x0003a26e3c4f8d24, 0x00086367d8184ffe, 0x000d4ca20d9fa6d4, 0x00057819ec396228, 0x0000217db807076e }}, + {{ 0x00026fc9c4cd4abf, 0x000e23f1402b9d0c, 0x00026a0bfe9f0668, 0x000417f6e573441c, 0x000042560b13ff8a }, { 0x0003ef07f65b14ba, 0x00061fd7493cea35, 0x000ec7090c603bd2, 0x00077a68fd05d4b3, 0x00006ce1efdc940f }}, + {{ 0x000613ddd45cbe56, 0x000a5d27824fc56a, 0x00076d14b2a2aae7, 0x000062d493467521, 0x00004912a1180184 }, { 0x00016c4168b43a86, 0x0003b9c5450d8660, 0x000c8e186318cb3e, 0x000c25c3946f4409, 0x00002251eb5dbfdc }}, + {{ 0x00035d95c1f7dfd4, 0x0004ff0c74359787, 0x0007ad857857c300, 0x0001a9bafb152c88, 0x00002220a65483ec }, { 0x0002c5cc53ddbb41, 0x0003473039553173, 0x0009bd757d41255e, 0x0006c05000b4b02a, 0x00005bb2616a0592 }}, + {{ 0x0006f267f3450bcf, 0x0009e1f606241297, 0x0004236bc36ba3a3, 0x000fc5e72b7bc5d6, 0x00006d062e175519 }, { 0x000d792d60b7e583, 0x000e00fb36eed930, 0x00072e7c3aa2aa86, 0x00041b3a055230cd, 0x00005222efcee916 }}, + {{ 0x00025b58889424a0, 0x0003bfdd5c7c5d2f, 0x000614cfdba46ef4, 0x00069438ab38f8da, 0x0000c9d7330553e7 }, { 0x00099f94c0e0b82c, 0x00086842946ad608, 0x000d6031dbbdd21d, 0x000b21909854f29a, 0x0000f80169f11b4b }}, + {{ 0x000d22a1149324b5, 0x0002751f4a55b03c, 0x000d68c111c13c46, 0x0005dc651261762d, 0x00005612c643fd71 }, { 0x00026455eddae243, 0x000931a247c9569c, 0x00030eee68dcf34d, 0x000c4d3d459a5097, 0x0000bc8501472388 }}, + {{ 0x000cd3142c078a4f, 0x000e7e049ce89e7e, 0x0008dfb5f889206a, 0x000b1dba11890853, 0x0000fe4b40447fd0 }, { 0x000af34eb1a2b760, 0x0005f59b3f5ab84e, 0x000807cb5614c7ce, 0x000ecf41f3c320a6, 0x0000376551d686ca }}, + {{ 0x000d8eec2b43abc0, 0x0004129977c97c4f, 0x000ac7efcdced8cc, 0x0007704785ff9bee, 0x00003fe869d8f984 }, { 0x0005c75015e7e220, 0x000f94ef027458c3, 0x0008e754910013fb, 0x00084b6f4b4ff531, 0x0000df161344c360 }}, + {{ 0x000f63cfc83f45b8, 0x00011d646ac49d20, 0x000b73afaae16770, 0x000dca23842c77c0, 0x0000cf54b1e93428 }, { 0x0004dcfda1adde56, 0x0005a1bc6441f959, 0x000957b146ed74f3, 0x000a15bba7d38f71, 0x000080b43552bdca }}, + {{ 0x0004512fad93b7bf, 0x000f4395f6d4a09f, 0x000bfa01887930c4, 0x00063d40a6b4f355, 0x000015dc769eb061 }, { 0x0001dbaca543e3fd, 0x00084d5206c4c74f, 0x0003d97181a31083, 0x000245f2dd021d4d, 0x00004c9b52a51d86 }}, + {{ 0x000f5829708831a1, 0x000f226490a1aca3, 0x000c01fa4191db95, 0x00065f158cb64dd9, 0x0000b704509d211a }, { 0x000d54e389cc560a, 0x00066d17c213ba70, 0x0005db4beb4b0a15, 0x000ad2ec1c28febb, 0x00007d2a923ea7f4 }}, + {{ 0x00069bcfe21bda90, 0x00044604af206ee4, 0x0006314dacd7546e, 0x00089f02e786c88f, 0x0000fea9761aff90 }, { 0x0009a4ef238392e0, 0x000540d470622302, 0x00079c0fb4897908, 0x0005c65ace743bb5, 0x0000ac57eea586d6 }}, + {{ 0x0009fcce8362831a, 0x00014feb483689bc, 0x0005873df3dedda1, 0x00023c1722575d3f, 0x0000658b868344aa }, { 0x000525a7345027f1, 0x00021ff0149362d4, 0x0001d725423d3479, 0x00035076c95e5758, 0x0000632aa6fb7444 }}, + {{ 0x000caab33910184d, 0x0003e628f3383609, 0x00028c433ff2d754, 0x00072cdec483ff59, 0x000059db5682d119 }, { 0x0008c75049787047, 0x0008bfd668927090, 0x000cac92ccf7e399, 0x000d9fc942496b4d, 0x00000b039ef1d169 }}, + {{ 0x000389359d183e8e, 0x00043c2c905d85f7, 0x000f93aa78bab2ac, 0x0003e4f94e9d7f78, 0x0000cdc97efebfd8 }, { 0x0007303b35c1dcbb, 0x0004eb7367e45f70, 0x0007c44e3fa733aa, 0x000da6d181f20306, 0x0000693cf0cbca05 }}, + {{ 0x00016554135f365c, 0x00088e4d13b7ea1a, 0x00043f81ed6cbee8, 0x0003a9370e6489b2, 0x0000a763c3cdfd1f }, { 0x0005fb3cd26c7a98, 0x00026fb7af4194e1, 0x000c788e80c9e8e4, 0x0000ec056533c1c3, 0x0000e7c9daf6851d }}, + {{ 0x00014e77a0de8421, 0x000cc45526f09fd2, 0x000c5fd9ac6926fb, 0x000a7dc8de8a4f10, 0x0000d25068992420 }, { 0x000b6cda791fe0f2, 0x0007b7314faa40ec, 0x000b3679170d12a8, 0x000c08f3e767867e, 0x00000e1e221077f7 }}, + {{ 0x00083667c4ab99b7, 0x000646d349d51aa0, 0x000edb9151250bb8, 0x00006dfdff56b5a9, 0x0000e96a55350487 }, { 0x00075a324beb86c4, 0x000dd3518087f2fd, 0x000bf9dcb2114ad7, 0x000280589f1b8eaa, 0x0000a4dccd763888 }}, + {{ 0x000cc4569fc6534b, 0x000850101dae185d, 0x000abeb63e1cf161, 0x00085800b45434e0, 0x00003dded22e1035 }, { 0x000e50258feb27e0, 0x000518a09a512993, 0x0006746000488c61, 0x000c0779281b4d20, 0x000087a3225e890f }}, + {{ 0x0001a7ec6bfaf389, 0x000c3db2996864b3, 0x0008eda07338e1f4, 0x00058e15aa2e6708, 0x0000a57bd6c84a58 }, { 0x000d24ee7c6e4db1, 0x000c666d6bc20da4, 0x000c39512313aed3, 0x000225f634acdb5e, 0x000017899b25ac05 }}, + {{ 0x0000ef95acc5b65a, 0x00091d3a19fd8680, 0x000cda9e478efabc, 0x000ae7e52612e481, 0x00005879a89ba754 }, { 0x000ff9d98e9d1fb0, 0x00022edaa0a6c469, 0x0005a37d6e017817, 0x000202a106129408, 0x00008051d4fc5997 }}, + {{ 0x000a9868340ef12b, 0x000847c468b8835a, 0x000ac8766672f855, 0x000de1f81977a31c, 0x0000ae09622e4cb3 }, { 0x0004b60159822469, 0x00032f3a6bd9d340, 0x000b2f0fd6fae8ce, 0x000eed25e6a62fe9, 0x0000a1ce552aab34 }}, + {{ 0x0005f9ee8b1f3b1b, 0x0007bdf5579bea49, 0x0007c6f4ec662d97, 0x00081aab110e35ac, 0x0000838e05f272c4 }, { 0x0008c93722dc320b, 0x0004eee82b6eb0fd, 0x0004bcf973ba5062, 0x000f5f1fe2e84576, 0x0000987ab3588bf6 }}, + {{ 0x0007afbfe9bfa97c, 0x000db48f83e8a3b0, 0x00068574d6094e13, 0x0009ff29ba579aa9, 0x0000ac0b5352b6ee }, { 0x0008e78e9f640109, 0x000d36d5b7bd2931, 0x000f573aa39dd6c0, 0x0000935763b592cf, 0x00006b052765f938 }}, + {{ 0x0000cd9c328d84f2, 0x000ec10296c36eff, 0x000191f73e449397, 0x000f344da7ee8967, 0x00003d52cf283e17 }, { 0x000adab3ad961303, 0x000c8f7e455fe908, 0x000af39881456bea, 0x0006ae1ec3fb53cb, 0x00007d83567df6b8 }}, + {{ 0x000d359f6fd4efcb, 0x000232f53d648293, 0x0007652ba9bb3daf, 0x000db7f2c7a471e1, 0x00009d7cb3d94a0f }, { 0x0006782372900602, 0x00065860aacd6975, 0x00031f4ad535a466, 0x00057f24e92b444c, 0x0000a4012d7fa548 }}, + {{ 0x00018c74a1ce7f88, 0x00008f2bbbab3b85, 0x000e39780cc99267, 0x000135cd24851f8a, 0x00000d44135a09ce }, { 0x0003ccc547f7ecdc, 0x000d90af9877d4ca, 0x0000054d05740761, 0x00071d6b614578d9, 0x00002bd6390f7cb4 }}, + {{ 0x0007167876861ca8, 0x0004c8e327f83495, 0x00069d263dca7c3f, 0x000f26885f3e9734, 0x0000cc0b31df68c9 }, { 0x00011b5e5c6b6cf5, 0x0001fb9411925a6b, 0x0007eff6df88f06c, 0x000be215d7c078d4, 0x000083a8bd8ed8ac }}, + {{ 0x000abc1295834d88, 0x0001f6c1eea7b85f, 0x00009818e5c95ff1, 0x000938dbb2352b46, 0x0000387993489f2c }, { 0x000c5e12df15edd0, 0x000fdc05233f9251, 0x000bcb21d976697d, 0x0007be659e0a802d, 0x000053b74438966a }}, + {{ 0x000b70d5488e28d0, 0x00088c64b8457ee6, 0x0008e40dd4aef873, 0x00037e38fa5360f6, 0x00007f082ebb5766 }, { 0x0006f388f3012c36, 0x00001f13bfae3154, 0x000284ec6a763ea6, 0x00088e0f93379785, 0x0000205217d30224 }}, + {{ 0x00034f30d0a7f21e, 0x000285889d8ddbbc, 0x000dada45e17bd7a, 0x0001ff4b08830b26, 0x00008227c3ea8c36 }, { 0x0009e76d098d7344, 0x000eda356ab64b81, 0x000cbfb4f01d1e3d, 0x00024d9947f77f0c, 0x000077da11412e32 }}, + {{ 0x000ecd83bcdac8cc, 0x000bec396238f398, 0x000e19632faa0ca3, 0x00085e899c0a482b, 0x00002203b4334230 }, { 0x000b32d5095835f0, 0x0003cb7a2f3776f8, 0x00046985b5d63ee5, 0x000e9b446b42176a, 0x0000db866498ec65 }}, + {{ 0x00097128795b26d4, 0x000007d53b618c0e, 0x000b80b150a9c145, 0x0006c0564c424f46, 0x00006ae4b9ab6582 }, { 0x0000d841a1380e4e, 0x0005832f815561dd, 0x000502e81430573a, 0x000171a4f85f48ff, 0x000063896020863d }}, + {{ 0x00042ad522e18a65, 0x00044260b9267c6a, 0x00012add234060bb, 0x000833924c78913f, 0x000039e7e3dc6b6b }, { 0x000136fd8d64e5e2, 0x0003549a2c989d55, 0x000f90beea015851, 0x00038c4da928292d, 0x0000b65cea1cb0a5 }}, + {{ 0x0005f43682904822, 0x00022b1f2c34a996, 0x000459641f29f5c4, 0x0006715be3b00aca, 0x00008ad64a961e6a }, { 0x0000473f5f609763, 0x000f501a11b12e13, 0x000cb1c79515bd02, 0x000aa7dd578a7ab2, 0x0000493e312a1f39 }}, + {{ 0x000c13966b2406fb, 0x000e59d169c7d97d, 0x0003f39b6362b933, 0x0009d4d035cd5baa, 0x000048a4caa8a041 }, { 0x000310fa4ebd46a4, 0x00087e82b8357c1f, 0x0004f6c481db4a34, 0x000b8923e0cb1b4c, 0x00003d448294e348 }}, + {{ 0x000fb357b1ee936f, 0x0004452f97f68c6f, 0x000f0b4f77a6ed24, 0x0008c27d90c773b4, 0x0000c6d90e5f6f4d }, { 0x000ae575c3e40e20, 0x00004cde0f28039c, 0x00097bbe8620d5bb, 0x00038bb6c0b36c95, 0x0000c238d358e07a }}, + {{ 0x00073da0ba4fff56, 0x000bd02a70dab865, 0x00091a87ec422f67, 0x000e17592fcbd12a, 0x00003dc4b150156e }, { 0x00022cb8d1d292ad, 0x0004ffe0d41d5505, 0x0002cf29172c74c0, 0x000c83548e7eec0e, 0x00001f902993f981 }}, + {{ 0x0009a38d4ab89a62, 0x000342a70cbb96cb, 0x000a032d975e6da2, 0x00090838de034362, 0x000051f017afdd83 }, { 0x000aebcb837a69e7, 0x00043821ff140fd2, 0x000ff5c31c5d3793, 0x000bb3249bd162f2, 0x0000c09d95c15150 }}, + {{ 0x000f921c720023d1, 0x000e15f937b05271, 0x0007cbeb7d25606a, 0x000816929f42e1e4, 0x0000a8cc384e52b8 }, { 0x0006ea82172f000f, 0x0008f7b5b26bbd51, 0x000d247724699de2, 0x0001f0d7e7a8ef5e, 0x0000f1fe050d2c8b }}, + {{ 0x000f7199dc46d818, 0x000722b599ff0f94, 0x00073193628eba9f, 0x0009137f368a923d, 0x0000ee5360c30393 }, { 0x0004f710bd7921fc, 0x00093f6e46f2a79c, 0x000d25010260474b, 0x00092d27c08b5dea, 0x0000fab67c859c32 }}, + {{ 0x00064519deca0cdb, 0x000d55778bde41ac, 0x000fedd3517b736a, 0x000b97c416474bf7, 0x00003208530088be }, { 0x000025813a05a641, 0x000f7460edfcc4f9, 0x0006b8cc2931d960, 0x000ea5e77319aa73, 0x000029012049c8c4 }}, + {{ 0x000de5048b827884, 0x0004fcac0c227196, 0x00045be510935647, 0x00029229cc60209e, 0x00001a8f07ca2a57 }, { 0x000130388eeb5d29, 0x0000fd8e115ac04c, 0x000f5b3ade432bbc, 0x000316be77df7093, 0x000022d0dba6d494 }}, + {{ 0x00039aaf90e9d532, 0x0008c8477f54e6e0, 0x0002623b60542e7b, 0x000bc14d69f258a7, 0x00009ce5ba732f82 }, { 0x0000931ba5ed41d1, 0x000a9739460342f0, 0x000c3ee643e44bb0, 0x0003fd87e4703148, 0x00003a0863fbd5a9 }}, + {{ 0x00004525097c5017, 0x0005a9d786f337c0, 0x0002e6bf14745166, 0x0000c18efd9c01cd, 0x00002c8b553116d9 }, { 0x0000641053c931ba, 0x000c64784db8e765, 0x000a436499b28b73, 0x0005fda223bacf1a, 0x0000938a983f292e }}, + {{ 0x0007bde5834630c1, 0x00077749f7144aea, 0x000e9c16c77a33ff, 0x000ad12ef170c963, 0x00002afc875cc612 }, { 0x0007882dab2f3b77, 0x000638b6fa687508, 0x0001cfa5d49dd82e, 0x000de3631fa64e53, 0x000078a45e28f1f6 }}, + {{ 0x0009c5714d71771f, 0x00098316c67a7751, 0x000ad6005f642df7, 0x00040e7b2cb10471, 0x0000cc0be522bf70 }, { 0x000bc82ce45c7f2a, 0x000617bed03fd3f8, 0x000ea5f3ec6a645d, 0x000e3f6b5dd03344, 0x00007777234fc32f }}, + {{ 0x00081d837a740b62, 0x000d301b35f1341b, 0x000c6d86bac884d5, 0x000a3565ce53156d, 0x00002f8f9bd103d9 }, { 0x000c596b31a8eb5d, 0x000f76e2e4358674, 0x00049f4c722e721f, 0x000256e9d9020eb9, 0x000000946b032fd9 }}, + {{ 0x0004828817b2b97d, 0x0002c0f0e0b040d2, 0x0002217d0167ff6f, 0x00040e422baf02d8, 0x00006eb8e36ece4e }, { 0x0001f86203c5e993, 0x0008a31113ec3567, 0x000da3f78ff4f368, 0x000ea84159e48861, 0x0000bb7e93050f1a }}, + {{ 0x000560b0e9aafe66, 0x00042da3fd19408b, 0x000b722cecb04b0f, 0x000c6b6904aa716d, 0x0000052ee2e70dfd }, { 0x00015ca19443e93c, 0x0008d92fa34bdad6, 0x00043b7857295ea6, 0x000c094d3f024fa1, 0x0000ea3f81cb62df }}, + {{ 0x000d3a74d028189e, 0x000aa3d6f73c51e3, 0x0002acd34e0d4511, 0x000a079ffa4cb241, 0x00006e3b446570f6 }, { 0x0008027c148bf575, 0x000240f4a7a92024, 0x00095faee0289dbe, 0x000ea1d08a9bccf5, 0x00003daa96c5c819 }}, + {{ 0x00079738d8eab83c, 0x000fb7c40b557f08, 0x000645d10d87e8cc, 0x0005ffe27e001c36, 0x0000017e39f092f7 }, { 0x000943d1b495d0bb, 0x0000c4bbda948826, 0x00083d40e0e510b7, 0x0006a7c24d1bbcc4, 0x0000acdbfbfa5df0 }}, + {{ 0x000bf3dd51c8d19c, 0x00007bb098cafb4c, 0x000f94e0af5e1773, 0x000601c4d27ed230, 0x0000285109152371 }, { 0x00024c7557bb1196, 0x000891641b1d830b, 0x000d18bfa8cf69f1, 0x0009cdfdba7ec851, 0x000077b4e1b088fa }}, + {{ 0x00040f8ac3df8d0b, 0x00006dc1d4636c38, 0x0005e40b0e75786b, 0x000f4a2b3f843652, 0x0000977ae94715bc }, { 0x000123d8f150f27a, 0x0001e11f4387f1af, 0x0002c3f18f8f2228, 0x000f40e677c501cd, 0x0000110598eb168e }}, + {{ 0x000796ff08cfa1b0, 0x0005e71d607039eb, 0x000515a3463d5019, 0x0009090912b70e21, 0x0000a34adda11483 }, { 0x00038e8cdf8fccad, 0x000cd863c57c4aa3, 0x000f84360d47a30b, 0x0009660982aed9ca, 0x000082fbf17ecca1 }}, + {{ 0x0005213908309c96, 0x000cb8266cde8dbf, 0x000f3851c42e5054, 0x000d1ba724e15997, 0x0000c913344e336a }, { 0x000a1c0c559056b7, 0x000681d8ce4396ea, 0x000ffdd114ecbcec, 0x000c3f86b37a1a67, 0x0000bba57201413f }}, + {{ 0x000e3d7a82a07312, 0x000248b4ed80940f, 0x00057c32545a8fa1, 0x00024459f67e6d05, 0x0000781e5623c72a }, { 0x0009422f1dd9d9ed, 0x00045027e096ae27, 0x0006ab7164488446, 0x00002f2fcb1f3e1e, 0x0000a08771e4d556 }}, + }, + { + /* digit=24 (1,2,..,64)*(2^{168})*G */ + {{ 0x000b1adfbccd5f72, 0x000bafb9db3b3818, 0x000e49c42a8e58da, 0x000a5741f9c3a2de, 0x0000e1b4d1992caf }, { 0x000d2ae779d25bd8, 0x00001397e053a1bd, 0x000689b00f8d9c66, 0x000aeefabee2be5c, 0x0000ed75eb0e9aae }}, + {{ 0x00070ef12df3aecb, 0x0000e7a205b9d8b0, 0x0003fe5865a61087, 0x00049560e6eb8f06, 0x000018c288645dc3 }, { 0x000c1f205200dec5, 0x000d0053bcc876ae, 0x0007bb212c914ca5, 0x000c3165e12a7533, 0x0000fee6eaee8fb7 }}, + {{ 0x000b625175d3e131, 0x000ba79b6828f364, 0x0007b65b0a28d9d9, 0x000a31a0c9d7a025, 0x00003f761efd974a }, { 0x000cea06f50c8e7a, 0x00025dd9669b6210, 0x0006ea0e74a30782, 0x0007f7cbc88a2ca5, 0x0000eefdd32a930a }}, + {{ 0x0006927bdc72fcef, 0x00092b5c4e83d33c, 0x0008986accaed0f0, 0x000ee5e0fd9f3587, 0x00006fc2b4d5332a }, { 0x000bd4c284a559fb, 0x00092f79f9e0f036, 0x000e91031f24a068, 0x000494df12868661, 0x000064b67a214c5a }}, + {{ 0x00038062d4c1e75b, 0x0004591289a8619a, 0x000fc2f14e9e6431, 0x000a96b32ef796e5, 0x0000cf84b53f10ce }, { 0x000e2d93f2a93799, 0x000b1200573274eb, 0x0003eaf97fa1c33c, 0x000a47520d07b67e, 0x000099241c28bfc2 }}, + {{ 0x000e16a8fa9459c5, 0x00069533f36d1411, 0x00042fe5fb485de4, 0x000223d3ae84bb3d, 0x0000362e47c092d7 }, { 0x00051ac53cf453e0, 0x00072adddd472e03, 0x0006d8041bea2700, 0x0004e95997d405ee, 0x000072103589e10b }}, + {{ 0x000c45b260b78e4a, 0x000cab84444896b8, 0x000f6cfa759ac76b, 0x000f5fe7d64974d2, 0x0000fc1b25688826 }, { 0x00018f2e67924f42, 0x00079c2d84634875, 0x0006ee2d190516ad, 0x000a501c0d1b2b3f, 0x0000036290195036 }}, + {{ 0x000578dc4ce14fbe, 0x000b08c06d75fc1f, 0x00063cd0cc5274b3, 0x000f629dd2dcf7bb, 0x0000f36db3fef100 }, { 0x000304c0d907ee38, 0x0005103df2ce7a06, 0x00083934eed34414, 0x00075ccabaee3628, 0x0000f1816df3580c }}, + {{ 0x00082f4b52e4cec2, 0x0001aa2a91f6791e, 0x000fb37b53a9c983, 0x000cdb8c12abe418, 0x00008cd67259a170 }, { 0x0009b47fddf3ac31, 0x000ff274073e81c2, 0x000cd201171eb3c4, 0x000d8c60cc0276fa, 0x0000bde77950ebb2 }}, + {{ 0x000db1d445e12d1b, 0x000c603459b19402, 0x00092d4f6a4d5460, 0x000260fd3ec881c5, 0x00002404d2934d68 }, { 0x0000c0e5d7b17ee8, 0x0007387df239fd84, 0x0004d45c3f1714c5, 0x000bd7a59c718af7, 0x0000cf1f5fc6cd42 }}, + {{ 0x0007e104334dd14b, 0x00045f4721b33f2e, 0x000b16fe00b71c74, 0x00074a4e72124f1f, 0x00000c5ed583ab49 }, { 0x000b6a0a0c1b3b39, 0x000698ee4d0c7e6c, 0x0009bbbb310fa8c1, 0x00008ad43847e339, 0x0000d0eb2a823c1c }}, + {{ 0x000c83d2104da3af, 0x00087c327d02dccc, 0x0001ade4eab2adc4, 0x000bae22d5ad0098, 0x00000d9c44913bb2 }, { 0x0005934268273a75, 0x00009c1666fba0ca, 0x00066ee203cd0f18, 0x0003334c26994819, 0x00001a7e83e4402e }}, + {{ 0x0001240501d5f60c, 0x00008eda714181da, 0x000abf43ae40161c, 0x0004fd31f609ac13, 0x00006d341d5395cf }, { 0x0002c2adc36656d7, 0x00035231409ca976, 0x0007bda0de8008a3, 0x000a46fcd254cc1a, 0x0000ead8778cec76 }}, + {{ 0x00082b49f9e98b30, 0x0006df056e464833, 0x00002b48195cdcf0, 0x000c68c52a55abb2, 0x0000455cf3a69edb }, { 0x0004c589d9fde490, 0x00091ad4dff8d47e, 0x00045eb86afca0dd, 0x00060d50979caf61, 0x0000ed7832e28abd }}, + {{ 0x000716dd735d4299, 0x0000fab3fd40e095, 0x000e201a6135ca74, 0x00012ff8be455842, 0x00006f917d8d6ec2 }, { 0x0007e76496178dbd, 0x00054e54e8bf3de2, 0x0005f39e59a54bae, 0x000840fa69a0e77b, 0x0000a545f75f92f1 }}, + {{ 0x00065ca49bf70465, 0x0002633070d3aab6, 0x000b33d03149eda8, 0x000f82c732643672, 0x0000dae397b7ff25 }, { 0x0005986e7c2b0613, 0x000c759b3efb9983, 0x000ccf96a4c52f87, 0x000f392308a5b922, 0x000053a40c602f11 }}, + {{ 0x00060575d954191d, 0x0004e5cff3513cc7, 0x0009bb938203e64a, 0x000d85286bb0cf8b, 0x00009896e7ac48ed }, { 0x00058c95fcf57592, 0x000bc169f7aa1811, 0x000fdf7d571f4181, 0x000cb1291163a3ec, 0x0000a74ad3d22246 }}, + {{ 0x000d52e6bccfbd9d, 0x0007e6e13cda46f1, 0x000516dcc813d3db, 0x000adbc707948241, 0x00009aa625122196 }, { 0x000fc7bf7e178d47, 0x0005ae78608dd3d1, 0x000aca3fa6085efe, 0x0004ed3fa4930db2, 0x000095d11cde96d0 }}, + {{ 0x000d1764efa19423, 0x00089cdd9eee96cd, 0x000b08758747c9b3, 0x0006ea12a0ca277f, 0x00003fd5bca22445 }, { 0x000cff95c47d1a9d, 0x000dfde7b3ed7397, 0x0008dfea4bfb8703, 0x0000b151250cb745, 0x0000e035718c4eac }}, + {{ 0x0003e982abb759a4, 0x000a8bd8088b454e, 0x0006b6b489deac94, 0x000caa3cbdb7f32f, 0x00004686e7f56cb3 }, { 0x000bbf1d3400c329, 0x00098e4c2a2a5938, 0x00047bb4d51b0609, 0x000c26b2372c3686, 0x0000c3163f597394 }}, + {{ 0x0009e8e77eb6f0ef, 0x0001a73da50c991b, 0x000ac8448763bb7e, 0x0000c887148afcd5, 0x00001fe304790c6a }, { 0x0005b82406b0e023, 0x000ec4499a7703de, 0x000d7bd612ecce7d, 0x000a058be6972930, 0x000055f6a476b172 }}, + {{ 0x000a9e252eded6d3, 0x000b8e3bd3790620, 0x000d23302563dbb4, 0x000be5b37d64b7a1, 0x0000f8d8432196d3 }, { 0x00008e4790ff828a, 0x0000b6bc39d3bcbd, 0x000fe29ce5d2ddc1, 0x000bef0181a31c9f, 0x000059056576275c }}, + {{ 0x000e5d55febb0e31, 0x000e9e9255c09801, 0x00010ced1da0ddbc, 0x0003c14a14bd8638, 0x00002df70d0ce263 }, { 0x000e5bf8ecb0386b, 0x000b0068ff5cc292, 0x000ee05cac07c42d, 0x0004c2124026b389, 0x00009cd54793b7a8 }}, + {{ 0x000c6360bfa4642b, 0x0005cd0ad886aac2, 0x000a8b0e55855f5d, 0x000dc1aab5c16878, 0x0000ad287ec6b022 }, { 0x000e29d50b1fec3f, 0x0001cb5b9c972a3d, 0x000d9e7098af043d, 0x000bb5ba6c9e6f88, 0x0000ccd2c2291972 }}, + {{ 0x000d8f2c9dc84b95, 0x0005f83d309cbe6a, 0x000a332dc0b1d6bf, 0x000348ee35b020d8, 0x0000d07b2b00cfeb }, { 0x000c5bec9951a99c, 0x000921de7400e938, 0x0008c66271b3c77f, 0x0005ce4bffe3e18a, 0x0000fcae372683dc }}, + {{ 0x0009779f4565f3cd, 0x000992a74a55d1f0, 0x000efaf7c792c505, 0x000e87a94e3fbf28, 0x00001e0023586f6e }, { 0x000da67cfc184107, 0x000b6afc3d19d8d3, 0x00041a3029e3c052, 0x000ed5b55d5a7509, 0x0000fb679388fd7c }}, + {{ 0x0007c48aae979814, 0x000e22a2c160dcd0, 0x000387cc6040b48b, 0x0000e495a34e6c5e, 0x0000ebc559de6b12 }, { 0x0000871f6c9b95e8, 0x000c6da50068527a, 0x00027c0973fe1c51, 0x000e34a4c2c09ef2, 0x0000a42cfbc74a4c }}, + {{ 0x0006897ae28b8aa6, 0x0005568d84d835d2, 0x00095f9447042666, 0x0000a52d7c90caf3, 0x00007477e6db63ea }, { 0x0002c7980e3a62d5, 0x000b508a4d6755dd, 0x000b36ca63cc8293, 0x0005c42e8403ee41, 0x000072dad9713001 }}, + {{ 0x000f22110209bd6a, 0x000f832d2e11305f, 0x0001f49e696d2947, 0x00057e69d966be49, 0x0000a57523d1fdb1 }, { 0x000e0267ea28eb43, 0x000134aabe30129b, 0x000f756bfce543b4, 0x000213d22c6f2c93, 0x0000707ad02d7862 }}, + {{ 0x000a76e9e4386d11, 0x00081f193bc042b7, 0x000437c0da73ea74, 0x000bf3068f085b53, 0x0000015ec7b9d94a }, { 0x0001889c8d4274a0, 0x000e2fab88911b55, 0x0004635272281033, 0x0003323ffc85345e, 0x0000f694aa06193f }}, + {{ 0x000043f2c0486dd3, 0x0004069a5e829e5c, 0x000b55c3b7815495, 0x000afb1c1cbb4c6f, 0x0000adfdd639e5db }, { 0x000d515f74e0a7f0, 0x0009f758ea5e1853, 0x00099b2b5e2aa1fb, 0x000e7d6018bda40b, 0x00002841bc77e94c }}, + {{ 0x00003172599604ef, 0x000e04fda79e5acb, 0x0009d5feaf05bd45, 0x00080866e68b83b3, 0x00000b424807d53a }, { 0x0005296e9538c34c, 0x000381ac5ccc2c46, 0x000ad873e1d42e72, 0x0005408bd7d7dc96, 0x00006a74e1c17bc4 }}, + {{ 0x0001fdfedce79aef, 0x000c3d0bc8fa5bc5, 0x0006fe0e289f0f1a, 0x000059b5d8a5ead6, 0x000023b6e31609f8 }, { 0x000d66af2147f6ba, 0x000890b289fca32e, 0x000eb0352d1e23d2, 0x000f354dee36ff0c, 0x00005f8a7192aa10 }}, + {{ 0x00010989c077ae7b, 0x0001b8b5fa9f4d67, 0x000dc699d9268932, 0x000596c722d4066c, 0x000090b03f888845 }, { 0x0004d874f8f53831, 0x000ae35ce40cbd89, 0x000f826ab444e0a6, 0x0006a1d2cab55c5e, 0x0000acd6cecd4b95 }}, + {{ 0x0004c0e1b8f9d216, 0x000dae8a518001b4, 0x000658440d56a993, 0x000bb3725ee605eb, 0x00002b0f4a4a14c0 }, { 0x000bf395cc3b7ed0, 0x00054e88b6740dc8, 0x00036229b9409031, 0x00046137289087a5, 0x0000be581ada8fe4 }}, + {{ 0x000d51afe901e219, 0x000b0a1deb8568b6, 0x000013a98d491c8f, 0x00016e281a35daea, 0x0000537d475b7d2b }, { 0x000c6865cafe90b4, 0x000f86e51803a198, 0x000ef9b92ab5832d, 0x000de923ce3d24b7, 0x0000b2e4a54bd2e0 }}, + {{ 0x000c70ca45125561, 0x0002a7db743f4ef2, 0x000bbb6053892073, 0x0009d8ae83793909, 0x0000dbb97d8fdd1d }, { 0x0000384cb6274347, 0x0005229cb1131b10, 0x0008255041c3b80a, 0x000952d0a7826f29, 0x00004174450b76ca }}, + {{ 0x0009570c16f8f650, 0x000c25b3ab480953, 0x0006297944efd26d, 0x0009f08453451c25, 0x00004a96dc9b66ab }, { 0x000ad4b67319678a, 0x00020d3adecf263d, 0x000101a22a8fbe78, 0x0005f1e36f1c3d8d, 0x0000ed9d0a1de53b }}, + {{ 0x000d2db93bcd3273, 0x000260ff0d796a03, 0x0008a1e0d1c6f14c, 0x000d98dad5fc6247, 0x00004b1ab345b835 }, { 0x000ea6e007bc5637, 0x0005379d85d5ddc0, 0x00075d099f2d2836, 0x0004877d5e907caa, 0x00002c068a8b32e7 }}, + {{ 0x000651f5d8d828b1, 0x0004069d23233f3a, 0x0005d1796da707e5, 0x000781e6c3e32279, 0x0000b55160373545 }, { 0x0008bdd37cafc9ac, 0x00003191a230c767, 0x000254ec8ace2d98, 0x000e2217ebd52727, 0x00005901810eba20 }}, + {{ 0x000491ccaacfb314, 0x00002c217cd93fe1, 0x000dc64b1a37f286, 0x0009b2ef865b97a4, 0x0000b59b701c4047 }, { 0x000da2b7ef8c43e7, 0x0009b80231963324, 0x00070ad88faa8816, 0x00098e9ed3c3862d, 0x00000eddebb7b375 }}, + {{ 0x000ee5cf3c1ad26f, 0x0003f33b126e48e4, 0x0002a5af12fbde15, 0x000885bdb404a0b3, 0x00001567d76438aa }, { 0x00055c5bfa632ed7, 0x0005cb97df3c8c32, 0x0003920bad02d03c, 0x00016ea6abd905fe, 0x00005ccd15e48747 }}, + {{ 0x0004610714435ee0, 0x0007cbfc3dd9b4d7, 0x000f87a583732e37, 0x000fc229bce23edb, 0x0000d1868b201130 }, { 0x000f1bc7d1d5a193, 0x000645f1266bf52e, 0x000129c8d3e49b75, 0x000cd86e30204672, 0x000000c5c9aacd67 }}, + {{ 0x000c3fefca460bc8, 0x0005fc17078c4322, 0x000c8b3ffded87cf, 0x0001d3d70e1961b9, 0x00005038a807927c }, { 0x000eb77640143e4f, 0x000bb36c2af389a8, 0x000d2eefa6aabb49, 0x0006c356396c610f, 0x00004a75c050691e }}, + {{ 0x0004778ffba62fa6, 0x0007e542a296e775, 0x0002ee0bea399904, 0x000da2131c871868, 0x0000d6cf7f2694c3 }, { 0x000c13e651883a51, 0x0006eecaf06defd3, 0x000f497ed0b9e2f9, 0x000a01014fe3c105, 0x000029455e6852d9 }}, + {{ 0x000dffbb5f63e5d5, 0x000d329855938e83, 0x000e5fe590137f7d, 0x000e725b92eeb5d9, 0x000084e49f54aebc }, { 0x0005d787c5f79f6e, 0x000f0431acc093d5, 0x000ce38d469b87c5, 0x0004a46600cb6cc3, 0x0000f30c7a69dbee }}, + {{ 0x000a17ef8e44cede, 0x0001f47deadbf02f, 0x0008b22da0da0860, 0x0002433f011e8021, 0x0000e0cbc364982d }, { 0x000764196f27ef16, 0x000e72593e43bff7, 0x000e947fecc38758, 0x000f707a35cb5ff3, 0x00007e04f36d9766 }}, + {{ 0x000cfc53b4244564, 0x0004fedf0290a8fd, 0x0005ee4b6fd35ed5, 0x00009974fcae8196, 0x0000c1f220ef19f4 }, { 0x000bedf5f9d4ef28, 0x000ca3c4cb632f9e, 0x0005cd318a6d91a9, 0x00094f00ac42a1ad, 0x0000689a17da238d }}, + {{ 0x000ea61e2a63d186, 0x000c69f97e3e0442, 0x000fe32a819f8e55, 0x000bce8234201851, 0x0000668bd1c6ed6d }, { 0x000868c740040cde, 0x000b3bc575eaa945, 0x000160968aed23c5, 0x000e36f6f9e7bc72, 0x0000880b167f7fa3 }}, + {{ 0x000c19e283331498, 0x0002adb7be0eead0, 0x0002f357aeb26c71, 0x000d5f8d7511e784, 0x0000b48101676692 }, { 0x000621b037cb2a49, 0x000a7cfe9206c550, 0x00042f321032bfce, 0x00035370489389cb, 0x000054fee486602b }}, + {{ 0x00049dfb6757e9ab, 0x0003b3596e78cc4c, 0x00014768b940c469, 0x000fed2035385c8b, 0x0000146b998f7458 }, { 0x000d882de450b14e, 0x000937059f707727, 0x0003bc9587871fc0, 0x000d9a3903a073a8, 0x0000d3d672691eea }}, + {{ 0x000882984a6412d2, 0x0006d0ab2cf89408, 0x0007e711f7072d50, 0x0001381c872b0b17, 0x00004f08b915e614 }, { 0x00012be0ff5c5e45, 0x000180c6a19d2bbd, 0x000bb5cba1cc5bab, 0x000322b644b9e7f0, 0x00003b06299d88d1 }}, + {{ 0x000246e8af14e4f9, 0x000d93d0e165dc33, 0x00021bdc901f20a9, 0x000d3a7873d47ce6, 0x00006860c9c10ae9 }, { 0x000c598bba00d6aa, 0x000a4c703ce2b4df, 0x000abf66ec1544c8, 0x000c296c1e9b4ca1, 0x00006a2a90d3380d }}, + {{ 0x000a1105556dd7cb, 0x000fb2b45036099d, 0x00013c6b6083296c, 0x000e64e43a9dee74, 0x000078a017dad06c }, { 0x0003baaf9a80f826, 0x0007f2c651a3be27, 0x000d14899a0c2d08, 0x0003b98d1cda5111, 0x00004e13797d5a7e }}, + {{ 0x00000cab02e61927, 0x000e59d7fc63668b, 0x000c5bf6f1db6ce1, 0x00098fc516886c9d, 0x000015963851966f }, { 0x000d956d9d123a74, 0x000a2bc81b69442a, 0x000007c6cf517a7b, 0x000612e784148670, 0x0000acd5ae38e4e2 }}, + {{ 0x000d774e4ee4ff1f, 0x000d38b638a7e819, 0x000ebc098f74b062, 0x00070057a54155cd, 0x00004efa631b47ed }, { 0x0006843cb3f5f8f6, 0x000782e078637d27, 0x000ce786a3b624a5, 0x000d6ad541c363e2, 0x000040f408018af3 }}, + {{ 0x0004197ed9721891, 0x000d491d4b66947f, 0x0007102c8bb348b1, 0x0005dfe55b452ce9, 0x0000b7e62fe46cd1 }, { 0x000ada31f6ad76d5, 0x000df72400dd0f70, 0x000f40443e9cb7aa, 0x0008c63ae59f5ca8, 0x0000bd128c94245a }}, + {{ 0x000c2a3869098900, 0x0004eb694a2c2152, 0x000ad97b424b1af0, 0x000e689fed83a43a, 0x00002b03a91bd120 }, { 0x0001ce6e973b5ec6, 0x00073408439d9b28, 0x000188feb07a97d8, 0x000880619715ea67, 0x0000f2fc52299eac }}, + {{ 0x000af556ee5923e0, 0x000ffe0d809c7bd0, 0x000c841af9bcabc1, 0x00080376fd7b2580, 0x00006abbc0368a7f }, { 0x000e61844f2bc503, 0x0008873921de0acb, 0x0001c045ffb0ea65, 0x000091e7452ac9c2, 0x0000c85b8dcd9bc4 }}, + {{ 0x000b192421f0e56b, 0x00086bc789a283b1, 0x000d6cef12d213ac, 0x000ffd52d72d3ac3, 0x00005f7fe8a58197 }, { 0x000a3bc86647bf41, 0x00058989dc84cacd, 0x000cc232ad52144c, 0x00059dbe2b0a8482, 0x000095d11cda69f2 }}, + {{ 0x0007b4d51ba3adb8, 0x0004e53056e6f8fb, 0x0000ad1c5e8c26eb, 0x000bd064084861c4, 0x00001e7739155ad0 }, { 0x0000518677787161, 0x000d111220a255d5, 0x000bb1f017f68d42, 0x0009aceeac997152, 0x0000559f1f223eea }}, + {{ 0x00043d74bc914746, 0x00072bacf902b0bb, 0x0004839dbb7ea13c, 0x00008cbbc8d4b4eb, 0x000057a993c570e4 }, { 0x000004512228d85d, 0x0000ec98adba3503, 0x000c8517c8053c9c, 0x000d515ec364eaf8, 0x0000420c9b7173e7 }}, + {{ 0x0008a61cf4dc1641, 0x00058b7ea7b979b7, 0x00046e551ed89117, 0x000b9bafecd78cd7, 0x0000ea75547ea9aa }, { 0x00033effd03f2de0, 0x000e8723d502295f, 0x0003524db2b8913d, 0x00001a586f137685, 0x00006e05ca06d0f5 }}, + {{ 0x000fd495f78c275c, 0x00068cdb30cfb3a6, 0x0000fcc91ed14bb9, 0x000a17ddf6d09b8c, 0x0000645d0ce04a7b }, { 0x000dc229b0415b16, 0x000009f275264daf, 0x0005e7bb59b2b9b3, 0x000525c2280c2b74, 0x00002b3172744708 }}, + }, + { + /* digit=25 (1,2,..,64)*(2^{175})*G */ + {{ 0x000fc20755e3176b, 0x000828452666a58c, 0x000016e7bc6ccdba, 0x00078f9084bcb6e0, 0x0000554faca4c643 }, { 0x00094e142cf0b0d6, 0x00046505294dba30, 0x0006822fbef1afda, 0x0006df474a30ba28, 0x0000e6be6e6ae1a8 }}, + {{ 0x000b296904664fc3, 0x000b53e979f39254, 0x000a642320a351cd, 0x000cc34fa1efd130, 0x0000a26d827b4096 }, { 0x000df088ada01cc1, 0x000d534b9db65b69, 0x0001656914dd4d71, 0x00018a2f335c82e3, 0x000058dcd3dda1a0 }}, + {{ 0x00036f4fb314c50d, 0x000a366bb3fd30a1, 0x000adc80e59bd10a, 0x0005fd66c429169d, 0x0000d081f2b59f20 }, { 0x0002bf6af341698f, 0x00020011fbba712e, 0x00036dac36ae06bd, 0x00045183e6ef0f0b, 0x000041383caf3e36 }}, + {{ 0x00008fc59cde3468, 0x000e7124237b64b8, 0x0009635d376aaed3, 0x0004ff5d8688ebe9, 0x0000c1b55d497018 }, { 0x000b143a98f532c8, 0x000632ba3585862b, 0x000532de58edb3d0, 0x000ebfa9bb66825d, 0x000060efc436424d }}, + {{ 0x000ae5a380deb2a8, 0x000ecce12ae381b9, 0x000bebe7370f573b, 0x0005442ca3a7f176, 0x0000600a0769fd67 }, { 0x000d65f035454aa2, 0x000eb15ed251b464, 0x00007d646e2f56a1, 0x000a76d071f5d6d3, 0x0000bb2c5fed005a }}, + {{ 0x000f8f66b8a7cdf7, 0x000c324f111661eb, 0x0003f176844bf6c5, 0x00056be78edced48, 0x0000217f1b2be94c }, { 0x000ec85fbc8973e6, 0x00067f4d7ed8216f, 0x00068f645f12fdb9, 0x000735154bf07f37, 0x0000c3cd2d5edd0f }}, + {{ 0x0002b052011404ae, 0x0005feea5ba5b0b7, 0x000dd02000988637, 0x000ab7f42e6a116c, 0x0000b74febd1fdd5 }, { 0x000b000c06b573c2, 0x000ad7d31a3b4ea6, 0x000820bd8f2c06dc, 0x0003d6897e589307, 0x000078133015312f }}, + {{ 0x000f53916fc6beae, 0x0001122765fa7d04, 0x000fce16c2004cf7, 0x000c22d9859805be, 0x000052df10ff2d7b }, { 0x00099f450e1f9830, 0x000c61f33ddf6269, 0x000e06e68bf551b7, 0x000e86ee34206238, 0x00002aa249bfa9c5 }}, + {{ 0x0004c88f374f6f88, 0x000d851e4c79e9bf, 0x0002d1a210b3161a, 0x0004ef3231394cb7, 0x000034829a179e77 }, { 0x00060e7f8aef7dc8, 0x000aa1f4aaa499e0, 0x0005ddecaae02032, 0x00014bd1d68b3a7d, 0x00009e90f751f24b }}, + {{ 0x00047aa4c7ac2b3c, 0x00082731a3a93bc2, 0x00057da03752d6c3, 0x000d7d2fd42bbf46, 0x00008348bc06dd42 }, { 0x000825653cf027b6, 0x0001032f60c77da5, 0x000a69fded019b66, 0x0001dc3cf6ffbc26, 0x0000333cf94fd444 }}, + {{ 0x000648487f9f745e, 0x000ab7ebc1aa2b92, 0x00031157eabb1368, 0x0002c7d380788939, 0x000092962173f198 }, { 0x00006a7a345f44e5, 0x0002e363fcef2614, 0x000cce4176f57b8b, 0x000e286e26239c81, 0x000007adc1ccaa3d }}, + {{ 0x000ddab96e59ccf0, 0x00077ba4a493b31c, 0x0001ce1d36b7f226, 0x000c8a14b54f20a5, 0x00001a428916f43d }, { 0x00047a670dede59a, 0x0002d0aed25ea138, 0x000afd5154d9620d, 0x0009faac5fa1d09e, 0x000024f267bf7958 }}, + {{ 0x00006f4098b6440f, 0x000331e64bcb626e, 0x0007466fa01d3aef, 0x000cc256caea638c, 0x00006bacbc3672fc }, { 0x000063d8a3c3a04d, 0x000c7527512a30b9, 0x000d5525ccf645f5, 0x000307480f3d867f, 0x00004f61af99ab8f }}, + {{ 0x00017e76ea8b4aec, 0x000d995d314e7bc2, 0x000b24fa2303625b, 0x000d3e9d32ee7464, 0x0000fd86bbb7517e }, { 0x000a5817e3ed6c66, 0x000681fe7cda917f, 0x000a903127323a60, 0x0005ae96b12d8016, 0x000044afeb2ca0b2 }}, + {{ 0x00098ad9f490f5c1, 0x00080640821ee4c9, 0x0003723b3f9d8e3f, 0x0007cc69f1583eab, 0x0000a66bfbb2018c }, { 0x000ee4ed6e631317, 0x0000250a41157f70, 0x0006d9f54d0fbb05, 0x00013a25fa9d7e1e, 0x00007eea65ae7d21 }}, + {{ 0x000b69cbf65aaebc, 0x00090c5ac751e7b7, 0x000281d845c75cee, 0x0002f93c693f9647, 0x00005a6bb7c3dc6e }, { 0x000be7048732b0cf, 0x0003da2f4bf94e19, 0x00085541905b0af8, 0x00067070b1a5325f, 0x0000e3a10d49e546 }}, + {{ 0x000c686e55c3531d, 0x00063bfe1dc5c055, 0x000a92567d01f185, 0x000bcc9a3d738add, 0x0000afd5ebc87e1b }, { 0x0008a947fad2853c, 0x000cf50dfd0b7ec5, 0x000b11a03426ca2b, 0x000cf3096bdd0264, 0x00002575e52919b9 }}, + {{ 0x000fab1ac5f1c3a5, 0x000e84e49ccd6d74, 0x000c39123abacef0, 0x00010ceb2ff8fb02, 0x0000b9696ac02316 }, { 0x000d8260aa363274, 0x0002fbc97576ec06, 0x00079dfc1c84ccdd, 0x000fde200e8c946e, 0x00005e0955dd2239 }}, + {{ 0x000fba35ff441c20, 0x000104f70bba85cb, 0x0000e4e69d11bf4c, 0x000f9cec1ad090da, 0x000045f5d2d270df }, { 0x0002160efb05643b, 0x000c69ac1e919380, 0x000318e632645d14, 0x00055d30fa47638f, 0x0000433a1488c0b7 }}, + {{ 0x000cd99e61699f04, 0x0000c73615cd9e45, 0x0007944a9da57d26, 0x000dc398c498ec04, 0x0000524b1feda847 }, { 0x000ec9746fc9036f, 0x000a3df7851dafeb, 0x0009e8c6ed72b8df, 0x00008ea0ef156f5b, 0x0000108b102601bf }}, + {{ 0x00012050d9a73af9, 0x000b0c1c8ed1f7a4, 0x000566fd0f18765d, 0x00065804a09e43bb, 0x0000103c0ab78e66 }, { 0x0003868fbbf33bcb, 0x000b14e90747e405, 0x000b62a3a6cab563, 0x0005268536dc05eb, 0x0000757f03238b3d }}, + {{ 0x00080f9fb1b49db5, 0x0001dc3cfdcf7dd0, 0x00036a302b02766c, 0x00057c7a341a9fce, 0x00000720671b4553 }, { 0x000320fd327ff00b, 0x00083849ba7a5317, 0x00067a79174cfc18, 0x00058b83607d3558, 0x0000ab6cf754792f }}, + {{ 0x000b96d16da0f72c, 0x000db98b18bd1ff8, 0x0000244657980980, 0x0004b3bcd52c2e30, 0x0000cd07defe68a2 }, { 0x00019448d72e9986, 0x0008a494b45706bd, 0x000da2a8dd214d19, 0x000597a76e7f58b8, 0x00003146bb218459 }}, + {{ 0x000769788c7ccd96, 0x000f6b9d3210a041, 0x0003c391d9dca1fe, 0x000f5b29f6bc7d46, 0x0000a7a3bdce7dea }, { 0x000971da0e302072, 0x000462dbd6cb838c, 0x000559fb85145a33, 0x000e7e16e7066d6e, 0x0000166a58b45338 }}, + {{ 0x000941b2a22935bd, 0x000eb6bc49a2fac6, 0x000fc75134d7d87d, 0x00039f8563b8420b, 0x000028c1f97d5e54 }, { 0x00075bcd770bf80b, 0x00058080658ff2ac, 0x00026cc8ddbf0813, 0x00059d7998780436, 0x0000b046effada4b }}, + {{ 0x0002a6b802d70649, 0x000f7907f8f875d6, 0x000df41bb3bcbbe4, 0x0000a72e79c9d754, 0x0000ec89ec7b5eaa }, { 0x00019fe96bba031c, 0x00025aac6e7394b3, 0x00037bb805a4ed99, 0x000a3d80c445b6a8, 0x0000d094b5aa7fb4 }}, + {{ 0x0000920d0920b3ba, 0x0000c1f385f63cb6, 0x0003c22bc41dea5c, 0x0003588c241250c8, 0x00006627f300e7e9 }, { 0x000a9bfe7766cbd7, 0x0008046724d81a52, 0x0002311e3421bbd3, 0x000755932b7ffb89, 0x0000c38dbc2a2a77 }}, + {{ 0x000c94a8b3fecb0b, 0x000d7393191f4fd2, 0x0006a74204edcd02, 0x000ab8b0643093e1, 0x00000fea7bdc3f59 }, { 0x000ac3f5f4222e4b, 0x0006ec05c437d8e4, 0x00038e15fdd446f4, 0x0004245a23d4ae42, 0x0000b1ce9686cd0c }}, + {{ 0x00048ef841ec905b, 0x000adfc6b6af9917, 0x000fa6cdf37b4794, 0x000b3b2d70d5270f, 0x00003f3048a38ef0 }, { 0x0002c56f83b0eb6a, 0x000940edfc6fafb1, 0x0005e46a9fa3f7f0, 0x000cee4c9eadfdf0, 0x00001b1b2c4fdc4d }}, + {{ 0x00000f6ee71a6cd6, 0x0006c03d39b8c34b, 0x000581167ef45d8b, 0x00076c7c5ed8b1be, 0x000070c61c8b5adc }, { 0x000c324341fd93fc, 0x00072cf57d0ea992, 0x0007ebae2901bcb1, 0x000c74faadcae0f5, 0x0000ffd2c5f6a211 }}, + {{ 0x000d8607e66825bc, 0x000c355e126d4682, 0x000f48ee862317f1, 0x0008401c2ed325f1, 0x00004e9bb5b46467 }, { 0x0006b0cdc1954e42, 0x000fc276009d660b, 0x000dd65ff7df7908, 0x00041c7a03a525d2, 0x000009b10a289aa6 }}, + {{ 0x0002dfa557bfa495, 0x0000476e1337c262, 0x000db45dc38dd4f8, 0x00012d3d96faadeb, 0x0000c13ada75bd32 }, { 0x000c6ca5801dad5e, 0x0007c17be93c6d61, 0x000188985039af29, 0x000bbefa124866c6, 0x0000462261edbc6f }}, + {{ 0x000e8d3ac716b9cf, 0x000de8ce964021e7, 0x0009849e47ecab8b, 0x00035c998b83bffb, 0x00005192ceb4ff31 }, { 0x000b2b0564f91674, 0x000ac91bc2d124af, 0x000c0a865a8f2693, 0x00065fbb7bd54c3d, 0x0000ca36576246cf }}, + {{ 0x000570dfff87d7fe, 0x000c7575b45afb42, 0x0009ca47b12dc69f, 0x0001ee757e9ded64, 0x0000ffe130d9f5bb }, { 0x00098ca255a80b64, 0x000977888e084bd4, 0x0008a9f3435e8330, 0x0005936eea024b23, 0x00002da3669daeed }}, + {{ 0x0005af3c6e99cba1, 0x000c5eaaaa07e869, 0x000b5db14917a1fb, 0x000f6b8c80db6fac, 0x00000dbef989db23 }, { 0x0006542e486c2d07, 0x0008b8c02e30afbc, 0x000c3a365a70473d, 0x000f0979d9b5356a, 0x000015f1407ea962 }}, + {{ 0x000afe3247ac4682, 0x0009de87adfb6cc6, 0x00032d694ef9c6bf, 0x00039cf5acc826fd, 0x0000ca422fa86990 }, { 0x000a6778b884ff75, 0x00093b9b6ae8a751, 0x000d3067d9288acb, 0x0006244d6b8cf388, 0x0000c49ee251a7e4 }}, + {{ 0x0004f1a6a51a864f, 0x000aec1ecc4c7e38, 0x000c91e9c227bdba, 0x0005bc7aade9fe47, 0x0000637ef4323989 }, { 0x0003365b1415cdea, 0x00093725a7b162b9, 0x00091a91bc8f680e, 0x000e7a346c5cfda1, 0x00002d033d623c62 }}, + {{ 0x000f201022c136d0, 0x000022526a1fc900, 0x00023e50603a6d0e, 0x000d575f40d6d10d, 0x00009c8b622aee15 }, { 0x000394ff6b33c8ff, 0x00067c5658fde413, 0x000d4a9260b29b00, 0x0005a0ce7a8d2bc7, 0x000020c000e376cb }}, + {{ 0x000550bd2e68ff28, 0x0009d098132c9af4, 0x000af0cdbb3a6f91, 0x0002dedaaaac4b0e, 0x0000ab754349a57f }, { 0x000fb1b899561971, 0x000c08eea5399d41, 0x000a71b1d2e6e9c0, 0x00031302dd989bff, 0x0000dd9508dd374b }}, + {{ 0x000f01732de8a9ab, 0x000ce6944c44d6a8, 0x0009c8e6ee09ad42, 0x00004014491df144, 0x00002eeb080df28b }, { 0x0009476f970fa389, 0x00014253aa0a6332, 0x000ca08f6605dcb4, 0x0004bf71006de5e7, 0x000099a78f12c1a2 }}, + {{ 0x000aff2f226112af, 0x000c8c0d34c35659, 0x0001809fef7bd257, 0x000cdd102ef1105b, 0x0000c029fa506998 }, { 0x000b332e089dab46, 0x00009853a80e75d8, 0x000de08a787917ca, 0x000ecb77ade71853, 0x000002996859d6e3 }}, + {{ 0x0002ca07544326df, 0x000bce8b9c20cda9, 0x000543030543c2b2, 0x00092628389f7aad, 0x0000462f560eaa18 }, { 0x0004fdfd9c7882f6, 0x000e51174a1e0359, 0x00077eececf624e2, 0x0006205f202628cc, 0x000053d65edaa5d1 }}, + {{ 0x00013045bf671e99, 0x000c75463428c6ba, 0x0001ef83c3e5fed6, 0x0002715112f7205b, 0x000071bd670eb998 }, { 0x00099f3ec14c07f5, 0x0001fff03ef77fee, 0x000f16504d2e9402, 0x00092e922689cd59, 0x00006897e1a72bd2 }}, + {{ 0x000d2466e3ef3d22, 0x0005b91ea1b3c3ec, 0x0002eb5dd366b2c8, 0x0008d231e2d1a705, 0x000040cdd3ee863d }, { 0x00007c4b82673e6c, 0x000882fc8cb762d2, 0x000e5613d59cd383, 0x0009208507e312aa, 0x0000c2327bddf0de }}, + {{ 0x0005670fbf65ef80, 0x000a5c1375913eca, 0x0005c229726133e4, 0x000785bf694e45e9, 0x0000158117a0c867 }, { 0x00077fefaeecfab4, 0x000024a66f5b8fca, 0x0009d0effc797a1d, 0x000049552d5a56ae, 0x000049ee3eb9b0d4 }}, + {{ 0x00004a61164aac1e, 0x0000f7c98379d445, 0x000b00547b73dedc, 0x000c3c664d000bdf, 0x0000f6c15b16639b }, { 0x00067ecf4a4fa56c, 0x0004c71effea31ae, 0x000d0a434b0a070e, 0x000a1e7bf2d3de26, 0x0000cf8b029be733 }}, + {{ 0x000004ceed9ae923, 0x0004652151fe690f, 0x00038f260c71df2e, 0x000cd078d0351580, 0x0000d3995d9f2836 }, { 0x000008e04b1b6128, 0x000c27cf0386fac2, 0x0002b1f3c705ed36, 0x00018dcec3b62ff1, 0x0000371099c99400 }}, + {{ 0x0002a2c2241af6c3, 0x000518e41dbd7725, 0x0002cff16430b650, 0x000ce81f72b419f7, 0x00006d2ef331afce }, { 0x0006510652363465, 0x0008914634dfb02e, 0x00000e2763a12775, 0x0005ed5cc5f074ff, 0x000022c4d1e63b6d }}, + {{ 0x000fde089e1449b9, 0x000db82f1012e7a7, 0x000028c75e109fa1, 0x00076543b51013cc, 0x00008371ca42a533 }, { 0x000f1f5764038bdc, 0x00078fec731b4b3b, 0x0003dade48fdff7b, 0x0008e59bc12a136a, 0x000052c07ce95456 }}, + {{ 0x0000061987d3a8bf, 0x000e66da16d4b346, 0x00097c9c02c81980, 0x000e525867fba9d0, 0x000068da7a517899 }, { 0x000d7e28755b891e, 0x000f1869da28ff0c, 0x0007764631272fb6, 0x0009fad0d3133f70, 0x000092271cbf4392 }}, + {{ 0x0008dc98e16ac555, 0x0009bf272ed91fcd, 0x0000c3f80a91efc0, 0x0005fd03c85214f3, 0x0000571a08a1dcae }, { 0x000cbff4f341eeda, 0x000d5fe585cc3a25, 0x000d169c04872f31, 0x000c46b81724952e, 0x0000703ab0cce8fc }}, + {{ 0x000126332eeca533, 0x000d70e87d8cc7b9, 0x000360ac4da1a08c, 0x0004994049beaa7f, 0x000085d58a9542af }, { 0x0006092eed4373ee, 0x000d3b48ed3bd6db, 0x0002233cbc36be87, 0x00016f45535bb2c1, 0x00009ff16f286157 }}, + {{ 0x00011e4bcd460f2c, 0x000e83fcc058865e, 0x00018d064d550766, 0x00041a7537b0a5af, 0x000046efe0747324 }, { 0x0002573bfa73d9cf, 0x000ca3aa14a90fa5, 0x000c67b515d9d098, 0x00058982d7706e20, 0x00007d1585bc34a1 }}, + {{ 0x000717596c322d2f, 0x00087a93b5bdb831, 0x00008d8fc9ac384e, 0x000bdd75f08da65c, 0x0000f1e0a2f83e31 }, { 0x0002f3b50d9aca4d, 0x000a3d0b266d88b4, 0x0007164ddf4c7663, 0x0005edfacf688ae9, 0x000069a04a1ed5e1 }}, + {{ 0x0001bc81d1567fa5, 0x00054986a90fc34e, 0x0002840e08bc1725, 0x000d25262c8f257d, 0x00007d37c1cef912 }, { 0x0000aa9ebd5aee4b, 0x0004467251a2a12f, 0x0006cddfd21ec0d8, 0x0000a022e10d8658, 0x00004f408c5bc296 }}, + {{ 0x000652b5c82520ed, 0x000d104275968936, 0x0005df6c8f6344c2, 0x000a5abc8b6bb02a, 0x00005bc743f852cf }, { 0x000c773c3afe64cb, 0x0008afd4f5c04999, 0x000818dbeefd7cd2, 0x00084a3f76ea1655, 0x00008333b4274ea4 }}, + {{ 0x000f9a78b85b575e, 0x000dc409b323abc8, 0x000161475ed8d00d, 0x0002fb77ae26605e, 0x0000ce1190f5abef }, { 0x000c94bddefb0e25, 0x0001faac407eddd6, 0x000836c6d870d410, 0x000fa149981ddd1d, 0x0000e0d5b79ac001 }}, + {{ 0x0003624f3e74bdef, 0x0005bda8545d185d, 0x0009a029698ce572, 0x000c9f20e82ae44e, 0x00002103e5d5a56a }, { 0x0001f363f57898e9, 0x000379b14be42542, 0x000c9bc8cab053ab, 0x0002a92be7d0efcb, 0x0000217605b86c8c }}, + {{ 0x000f7246a4a10356, 0x000e71ca85015501, 0x0001b938ca17004c, 0x0005e6f1c2251e0e, 0x00000d5fa3abf1c8 }, { 0x000120a64c2cae9e, 0x000a6ee5f2591f26, 0x000efd41cb0b0208, 0x000451f683c47d33, 0x0000a218fb5a7cf6 }}, + {{ 0x0001c18807f2e6b7, 0x0000fc07b5d07df4, 0x00083d320f7b47b4, 0x00053e44fa92b955, 0x00000d924dd02cb8 }, { 0x00001b784f6b6a60, 0x000708980ba9b1c1, 0x000eb517318e9114, 0x000ba0809ac8dc6d, 0x00005f1ad1849fe9 }}, + {{ 0x000fd8ae60415444, 0x00001bbb6f116037, 0x000dc1f9d1be7f45, 0x00020f0a857b09db, 0x000074bd20b5cf68 }, { 0x0007958e09141208, 0x0009e6678308435e, 0x000bebf0fe4490f9, 0x000c5a2b09572f77, 0x000007396bf5f419 }}, + {{ 0x000fd7296995f44b, 0x000e342253466896, 0x000040a5469aeb31, 0x000a0c3e3716da29, 0x00001e5c16338121 }, { 0x000ef6d5416eee55, 0x000430308b640d30, 0x000e79883d5fe34a, 0x000403e115b0026e, 0x00003880d9961f05 }}, + {{ 0x0001e0f84f93b4ba, 0x0006df0f9c41135f, 0x000876c5514402dc, 0x0008ccd5cf21d60c, 0x00008207421ebd51 }, { 0x000f04b824048527, 0x0007c5906002d609, 0x000b67145d2e9747, 0x00092f7c3be2da60, 0x00003cc3292a8a5c }}, + {{ 0x0002edf52c078d85, 0x000c57dd4b79bb87, 0x000adfda839ce9d2, 0x000ba33e8aee806f, 0x00007fc8b3dee585 }, { 0x0003b2818874b38e, 0x0001a4e2127015a3, 0x000069054d6b7749, 0x000ba60c89051d0c, 0x0000fcc7ea0acfb4 }}, + }, + { + /* digit=26 (1,2,..,64)*(2^{182})*G */ + {{ 0x00063f4153af6dcd, 0x000c683171b445fe, 0x00029af26bf85199, 0x000cbbae89bcf21e, 0x0000e2560e6db219 }, { 0x000e1d75ae224a6c, 0x000f6a930add43df, 0x0002cb637aac5049, 0x000bc7d6862ebb14, 0x00005e73664b3718 }}, + {{ 0x00080034798ca4d4, 0x000f2c7af8685c8b, 0x000d778ecd30d2f0, 0x000cf952ad4c1c8c, 0x0000e198f05db898 }, { 0x00063d51806a84e5, 0x000e1e52eca3cdb7, 0x000b75c78219120a, 0x000a6e0cfea1db16, 0x000052a4a35bae24 }}, + {{ 0x0006c8bebe50eb45, 0x0007cb808bd98d05, 0x00040ead3381f366, 0x0008a8d70644b1cd, 0x00007b632a717522 }, { 0x0008239899b73b3c, 0x00096acc4632b46f, 0x0009b7b269a90fd8, 0x00021394617da427, 0x000076f048091e12 }}, + {{ 0x0008e13092cf573a, 0x0005c3f4c8303203, 0x00005750d3512460, 0x000db40fb842c7aa, 0x0000494598d37817 }, { 0x00077989cb6b3d8b, 0x0007062757558f1a, 0x000150731ef6087b, 0x000f58b273cc3e83, 0x0000ffa7db45a98a }}, + {{ 0x000e632a990cd2b6, 0x00061a144a081e00, 0x000da8aafed1d92a, 0x0004cbb9cd797fb7, 0x0000eb29b6b6973b }, { 0x00010f9eff77898f, 0x0004216c5f0c2848, 0x000eac88dd631243, 0x000a457cff51088a, 0x0000f820a5bcdad4 }}, + {{ 0x0002830fdbcd7a9a, 0x000fab97ffe4b3ed, 0x000113774d45e378, 0x0008122750b691d2, 0x0000dbabb5016bd0 }, { 0x0004aef03d79fd03, 0x000219c52434f573, 0x0005635a7d6e7d8f, 0x000fbbdb34b1f754, 0x000089b90d825715 }}, + {{ 0x0005157b6a28f2a3, 0x000aef4b7ac7ec57, 0x000a6ff82c6bcfde, 0x000476bb8d6ceb95, 0x0000cd5591ba46b3 }, { 0x000117f5ae655dc1, 0x000064ec5413d62f, 0x0006cb47cf197d67, 0x0009cdcdabe329ff, 0x000034f79ff63bfb }}, + {{ 0x000d84601a040653, 0x000c4f4b0166f7a3, 0x0007916814ccaa7c, 0x00080f8fdfbd3e3f, 0x0000bdc4370992dc }, { 0x000a6279f7786e45, 0x000a95c7c1620b02, 0x000d01014b0992a4, 0x000fa801eba68b4d, 0x000052fa0f983aed }}, + {{ 0x0001c6a659019d30, 0x00039b06ae85c104, 0x0008dc372d4d1620, 0x0006a5bec7294697, 0x0000ab9976bc0f2a }, { 0x000333af21cebd7b, 0x00095240e0239001, 0x00019dd9652bff2c, 0x000cd3ddcbaeec12, 0x0000ff15e9da5236 }}, + {{ 0x0009088b4d137854, 0x00096e03aaba1f19, 0x000da268b982cbad, 0x0003344bc2cada16, 0x0000badfeeab305e }, { 0x0002071cf6a8f781, 0x0003fa03549dbd42, 0x000fcf51a6b55cde, 0x000f6558542cbdf8, 0x0000c6c6a717b9de }}, + {{ 0x000cdbcd7623a9b8, 0x000ba1fff2811e50, 0x0003f1a3e116af2c, 0x000483fbbdb81b70, 0x0000d353c95f79b0 }, { 0x0004c3074db8bf13, 0x000512a566a808ce, 0x00034f3d5d88967a, 0x00069e76f02b7445, 0x000003ceb7b97c4c }}, + {{ 0x000a03aee51cbd7a, 0x0003eb0b796d2197, 0x000eba706ef4966f, 0x000307cf5c3e95f4, 0x00007329daec404c }, { 0x000aacb62b09eeb6, 0x0000d76f53a89aa8, 0x000109dd72b102e5, 0x0003bfa4f0d8af9b, 0x0000584ec8a3c986 }}, + {{ 0x0002c97a20562f30, 0x00055ebf62ffd521, 0x000e44ce44efba3a, 0x000b3daefe670b54, 0x0000098ea607e96f }, { 0x0001985e228d3952, 0x000f4ce1fe32093e, 0x0005576f4aa6830c, 0x00035206b13cb4ff, 0x0000bb374024af47 }}, + {{ 0x000f278cb2b3179b, 0x00043a910a230cd3, 0x00038e096c95125c, 0x000ca660a24f46a9, 0x00000266524e1cf8 }, { 0x000207cf075b1512, 0x000b47d50b920eb4, 0x000d4c6e366a9240, 0x00080a509f1cb9a2, 0x000070955e1401ad }}, + {{ 0x000747d648fddd2d, 0x0005181c4127fe1a, 0x000c93a1ef1d3d25, 0x000e28ea5a9f8b9a, 0x00003db1465f08ae }, { 0x000a7234813df238, 0x000f35c2ba97bf75, 0x000d6287fea38e24, 0x00093ef9d15e0f77, 0x00005486c5bb1638 }}, + {{ 0x000a4c97a4abc3b1, 0x000629f8f5fcda83, 0x000483a1c45951ca, 0x0007bee77f3e558c, 0x00000e48e3d45037 }, { 0x000f9b7025a36d96, 0x000524bf6dce6a73, 0x0005d44b52ac36ba, 0x000ec10e9ff373d9, 0x00005254e73f1733 }}, + {{ 0x000917ab9ff1c65a, 0x000f031317cd0627, 0x000da087d792e7af, 0x000eac10b30779d8, 0x00007850b5ef6624 }, { 0x0004d90fa2ac1df6, 0x000a6be28fb1d8e4, 0x0002ce95ca910a5c, 0x00053b26c2e31356, 0x000059685056c6f7 }}, + {{ 0x000012062fd2dce6, 0x0002267d6b3e243a, 0x000cb8f28618953c, 0x000962f389fe6cd9, 0x00007eebcb8ff8c2 }, { 0x0002260beaa35c3a, 0x0008ebc9399d0822, 0x000a1fb906f7ddab, 0x00093057347e8c54, 0x0000f595f07f2d13 }}, + {{ 0x0007401e4d1294c0, 0x000661e1a18cc20d, 0x000e4be1b7e97e55, 0x0007cf6a02192999, 0x0000422ab974c7d0 }, { 0x000b5cbc27a1ccf6, 0x000a3836fbca2bae, 0x0002a46340237734, 0x000b9c94046ad329, 0x00002357b30dce95 }}, + {{ 0x000f6e149c30d036, 0x000786c252bd4796, 0x0009a3476ff36be0, 0x000f9406305e0f88, 0x0000f83a58f41674 }, { 0x000e1a0a8596c4ab, 0x000785cde601a897, 0x00087559b39a4f3d, 0x000826d27d17bbe9, 0x00009be39f3ad611 }}, + {{ 0x0007ac8746207af9, 0x0003896270580c34, 0x0009aa1d02ce4c08, 0x000b9e7a51e23383, 0x0000cf4081696e8d }, { 0x000d9da6c4963c2a, 0x0004d9a100dd467c, 0x0006814766449538, 0x0002461c9274a433, 0x00004c28dc524eed }}, + {{ 0x000774457fbdd20a, 0x0000f9f355116ac9, 0x00091f5d496d688e, 0x00079b671cc38bb5, 0x0000fd56d3b79f71 }, { 0x0000f140b199642b, 0x0007ec8c6db88bb2, 0x000f2dd84d526d42, 0x000887f8b6429d07, 0x00002d0578cfc96c }}, + {{ 0x000e6fa37e3db750, 0x000bf09ca4946937, 0x000073e3458ba1d4, 0x000f9fb1248d3a02, 0x00009a0ba3d63119 }, { 0x000d35c7755bbb5b, 0x0005a0649a0c938c, 0x00079eb02caa0b2c, 0x0007a3912b72c0d4, 0x0000f4f8e7d64356 }}, + {{ 0x000e3c3c1d7cda3d, 0x00032ea87baa6279, 0x000158ee6a629579, 0x0004420c958c1fec, 0x0000d64ac7b719e3 }, { 0x000792f805f03b27, 0x000eb7b2bcfe0b0f, 0x0001327ffd07ff8c, 0x0003e8c973510710, 0x00002665759bab58 }}, + {{ 0x0006229c472f32af, 0x0009904a9b46402f, 0x000ccaec6c09216a, 0x0002f59aaedddf85, 0x000022cb9423951c }, { 0x0004f9e47fc8c2c3, 0x000011e7727b9b64, 0x000b654a63c2fce5, 0x000e684ea289e4e4, 0x00003b8864805a20 }}, + {{ 0x000e57c4ea5be12e, 0x00073fe611f8b8ef, 0x0009f6c12f3d9e96, 0x0006d8cc3fd2e416, 0x00006523896385b5 }, { 0x000a38efd1795651, 0x00002acb1aaf6131, 0x000fd01f6a74847a, 0x00041ff3431df210, 0x00000190aa223cab }}, + {{ 0x000936a01ee6f056, 0x0009c370b1e9e212, 0x000cf487e88bd896, 0x000d164f9b258514, 0x0000b0dbf25b69a9 }, { 0x000717e61d824da3, 0x0003b986dd5b20c8, 0x0000e9e1a8b25329, 0x000df8cd7b586bf7, 0x000098c804cbf541 }}, + {{ 0x0000291d43fc236f, 0x000e82235e6fc06c, 0x000e4b14f6918efa, 0x0006704723477728, 0x0000cd51067b09ae }, { 0x0009f8b71be82198, 0x0002467cec5a196b, 0x0003a235d360dea7, 0x0004c8451deeb31e, 0x000071e8bcc32913 }}, + {{ 0x0006bbee27162ea6, 0x000fc87968a2ab91, 0x00092fffdcf8b836, 0x0007f9930e3c5ce6, 0x000052f83aed92d1 }, { 0x000aee94a5c4b253, 0x000cd17fd42cd227, 0x00007dc33dfaa1ab, 0x0006df6321e13997, 0x00008a5c209883b4 }}, + {{ 0x00046af04a0b75ce, 0x000336089821a663, 0x00085b2d261f5d51, 0x000566845f7c3767, 0x000046b01307b23d }, { 0x000e266e7ea58076, 0x0003c32370bf29c0, 0x000e34bfe26f7ad7, 0x000a63590f90c73c, 0x0000fa778d8e6bfb }}, + {{ 0x0008c7ca3988b700, 0x0008eb90fca65d93, 0x0009dde77b7ef7a0, 0x000105a4e7e2989e, 0x0000f1c42756f442 }, { 0x0008f99897246c90, 0x0003494d402676af, 0x0005fe32e3b161e4, 0x000cdb64e26ab5a6, 0x0000d779dfab8fa9 }}, + {{ 0x00005ab8b7207ede, 0x000a6911a335cc88, 0x0009e9fe5b2d6bb2, 0x000344b19563459b, 0x000063bbb632aaa7 }, { 0x000b647545ffb149, 0x000c9da8d006086c, 0x0009f1914bb72b13, 0x0006fefd76ca4846, 0x000088e4372592ac }}, + {{ 0x000ffea6429715c7, 0x000278fbd7d90402, 0x000e519cf6536d14, 0x000921044ee66a2d, 0x0000fdbc110ce347 }, { 0x0005fc22ff710224, 0x000b7d1114344eab, 0x00064711998bde17, 0x000ea5b910430453, 0x00004bbc5151aab8 }}, + {{ 0x000e608d3b84a63c, 0x00027a91ee682e0d, 0x0000202539ebdc33, 0x000ca402ddf48abc, 0x000039b2f368d7a9 }, { 0x000a5e736f80cbe2, 0x000e08bedafd8830, 0x000eb3366aaf8525, 0x0008d5c413c362ed, 0x00001f043dd12d92 }}, + {{ 0x00051c374c6eccaa, 0x0007911f68cf9d16, 0x00075c5d3e0a50dc, 0x000351809a4f9ef8, 0x0000ad1a87ccd2e7 }, { 0x000f8b5ca64e7fbd, 0x0004e5888b5cead1, 0x0008501e7f03fb15, 0x00096363a0ef0005, 0x0000e724123c7fff }}, + {{ 0x00090f925a13bf98, 0x00028a3ee9523f07, 0x00021e4f171e207b, 0x000b3eff4bb75eab, 0x000087b67cf8d7fc }, { 0x000a80ca34fe2f62, 0x00001ad1e4f6a5f6, 0x0003f7d0d01bf374, 0x000368fee06e08b8, 0x000092f43fe95274 }}, + {{ 0x000932ad964afa6f, 0x0002868aaba4864c, 0x0001c41ffa4036b8, 0x000b294f1b13cabf, 0x000056378b24b243 }, { 0x0006cecce0d322ce, 0x000a28ecae1e27be, 0x0008343f2967812f, 0x000aaeabc9dac426, 0x0000540f92402c0c }}, + {{ 0x000d95bc6cfae79d, 0x000e75e95081181f, 0x000f6bfd9968c225, 0x000cbd8a8cc8a791, 0x0000480e6df000c8 }, { 0x000bdbfb94f56234, 0x00036266888523a0, 0x0006bf25a4d854ae, 0x000577f974d142bd, 0x0000a963460af4b8 }}, + {{ 0x00001be6298ca10a, 0x00098291660f6a6a, 0x0005b5001e039d37, 0x00022f5e87f6abcd, 0x000023ff88c1c17e }, { 0x000064091feffe54, 0x000ed030ca1c3287, 0x000d489f896e7ea4, 0x00092f0b0c74114b, 0x0000370a3f4a2eae }}, + {{ 0x0004f21fd5b99340, 0x000b521e447f2c48, 0x0009db50721aea61, 0x000c5e6de81b8da7, 0x0000050b21dc70c3 }, { 0x0009f72f7ea729c2, 0x0006f814e9df3d85, 0x0009dfb45db575f4, 0x000efe84a1ca4861, 0x0000e4cdd0716db3 }}, + {{ 0x00033c65bf36ee47, 0x000f841386d5087c, 0x000c1a2b70906c0a, 0x00081da5840bf739, 0x00003727fb23462f }, { 0x0008de9cfbb71ad6, 0x0008f7c38ca61533, 0x000aa39a7c7b16b2, 0x00053493997f4519, 0x00002e4ab8b82e16 }}, + {{ 0x0009ed75a8075803, 0x000e8a37b793f853, 0x0009b67a736cdcf0, 0x000bcab87e9f8dbf, 0x0000d28da38fbee9 }, { 0x000320fecff5c637, 0x00011487ffba390a, 0x000ac7d8bd39b7eb, 0x000ae3fdb67f8cb8, 0x0000a584d17078a6 }}, + {{ 0x000c04d32f4cd7b7, 0x0007902b2aced2bb, 0x0008a56701019371, 0x0005a0770dfba180, 0x00007ee3ef2a1576 }, { 0x000b1949fd771f7e, 0x00022d10f9f142d6, 0x0004dcd51025a0e6, 0x0006a36e32c44a0c, 0x00007e3d8d8e45c2 }}, + {{ 0x000b87bcd0217256, 0x0004808be0f44920, 0x0003de4e28470c89, 0x0002210a83ff0da0, 0x00000219c682d1d6 }, { 0x00045c0f29f6bf67, 0x0009583ab1f58ab6, 0x000a1d22cd60f4a5, 0x0007c00e56d9598d, 0x00007cfc00573c26 }}, + {{ 0x000e4c720d49953f, 0x0009e82eabaf21cb, 0x000963f4f390dba7, 0x0000a319182b9602, 0x0000a7b7f6d4dee4 }, { 0x000b26d3ec37e7f8, 0x000c4036f08d6c97, 0x000733e9eb5434fd, 0x00029071236e8a99, 0x0000804003513506 }}, + {{ 0x0008486600572aec, 0x000e6d0c9469ad61, 0x000d18673a5b5b15, 0x00040b686c4a11b4, 0x00004c8a42d0ce86 }, { 0x0001f6653acf2e26, 0x000b0ba8d9ce5be6, 0x00059d5595d2893b, 0x000d2a9730d8f68c, 0x00007023d6e1d087 }}, + {{ 0x000ac7e2a0e832ad, 0x000962b5aff5a48b, 0x0008b7f257c9170a, 0x000e5ecef0d81c4b, 0x00009e1bf2654911 }, { 0x000e23feb138dff4, 0x0004b6c1c664399f, 0x00005da714ac9df9, 0x000cb88bf4c288de, 0x0000a0bdbf12fa64 }}, + {{ 0x000d63ff677c67f5, 0x0002f66cdedca850, 0x00000ca5542522b3, 0x000a91c5d140bb71, 0x0000061b8edde9e1 }, { 0x000dd6d4fcf285d8, 0x0007d517d234afbb, 0x000dc049bac482d8, 0x00004735d61c2db4, 0x00000bdf475cd200 }}, + {{ 0x000379bc0760a44f, 0x000536d3be01cb1e, 0x000b40c0e4757120, 0x000abe6029ba14ff, 0x0000b2768766a251 }, { 0x000499f0b7403ff6, 0x00022e9d4ca8d68a, 0x000bdc215072febc, 0x00005b368083558e, 0x00000674a9be8956 }}, + {{ 0x000524194f020327, 0x000303cb8349abe3, 0x0004fb90e2cd1e88, 0x0004f22903baab3e, 0x0000cf54c8866bc9 }, { 0x00078e9bd6163cb1, 0x00066257d4bcc42b, 0x000b01726de44c34, 0x000e730e0e90a3d9, 0x00006e99c9f280fc }}, + {{ 0x0001b393ef075bff, 0x000b8469e03d2781, 0x0005c55acea80038, 0x0006d79558017860, 0x00004b0cbffe0992 }, { 0x000975eb80eb4487, 0x000de82d8884f278, 0x000a35a3cede5daa, 0x000dbdbc6bd44737, 0x0000d4e86779cbb8 }}, + {{ 0x000a12aeaeda2167, 0x000f0c7d7fe71f3b, 0x000002851f89faec, 0x000cf14631534219, 0x00002b71cc5b2f73 }, { 0x000a778c8bea0c7d, 0x000b8d2a9b4f8f67, 0x0005805f4d10c1d4, 0x00088167c04619d6, 0x000025b9fb741b8f }}, + {{ 0x000fbfee7fb522a9, 0x000dd2320a71b899, 0x000c7c62a2e5d72d, 0x000d59199241a2ae, 0x0000474a8ea015f5 }, { 0x00083dd738132807, 0x00051b95c4017e32, 0x000fecd4344ed7ce, 0x000db466f1dc7f9d, 0x000070c33943a538 }}, + {{ 0x000e55d0c2e5f7e9, 0x0003d09cd85d6a2d, 0x00051c9030b43387, 0x0001b15de6ebbc34, 0x00002dbfb11b5868 }, { 0x0000178c71b5b3ad, 0x000367f24dcdd5a7, 0x00050eba05896a00, 0x0004e910d8d602da, 0x000031562bd0e4c0 }}, + {{ 0x000d3b63b60559ae, 0x000f5863fe54cf05, 0x000ea58050bff57b, 0x00043e6d7a4a3ec4, 0x000068c2c4366a8c }, { 0x000e0ffffce55a24, 0x0000fd85ad3d2aff, 0x000cd39c7a3a9a4d, 0x0001d7214fbc586d, 0x0000260f7349e15b }}, + {{ 0x000c326d123c14a3, 0x000437f906151e50, 0x000f49ae99370325, 0x0006854b7cea27f5, 0x0000400c840acf85 }, { 0x000dea4b70fa8920, 0x0008c337dd35df39, 0x000925ac906e0b6e, 0x0002ebb1c0c3b763, 0x00001965b1ca3b09 }}, + {{ 0x000ebf9747546784, 0x000ea53aae3f639a, 0x000c4d67f464f2f6, 0x00028b35ffaba0e7, 0x000050bca1ceda40 }, { 0x0004311819988796, 0x000193ff41ad5d66, 0x000c4eb87a0aad72, 0x00047c0aa03c4623, 0x0000ecb71c39431b }}, + {{ 0x000e526f3fe97340, 0x000b2118be489ac8, 0x000d2b4ea10c02e4, 0x000f1a0072821895, 0x00003dbc2e993576 }, { 0x000c5a3e30980bb1, 0x00019775b645aee2, 0x000f53b3d2ced666, 0x0009145de3d1dcb9, 0x000083a266843180 }}, + {{ 0x000c4e57b437a58e, 0x0003f3e2a6c6fbf0, 0x000a3fab215289e1, 0x000f7db01a74516f, 0x0000f786a2c596ef }, { 0x000965f3c5b529a6, 0x0000c29b6e386b6e, 0x000cb078b861c0d4, 0x000478029b46793f, 0x0000a2baaffa251a }}, + {{ 0x000f1ef3355edcbb, 0x0004083425c65590, 0x0005fbd17ca52ef5, 0x000fc9bdf7fc00ee, 0x0000d8394a59efd4 }, { 0x0004329d7084b6fe, 0x0005345b79b8ea2c, 0x0004f98d5517a604, 0x000615fb740fd294, 0x00000a2b05ab5452 }}, + {{ 0x0006c177171f353e, 0x0003d52ed1be45d6, 0x000d7e0bb55daa85, 0x0000bfbb1891dd20, 0x00002712c1116863 }, { 0x00091b3fa0fa9f46, 0x0007b412843c4e0c, 0x0006f063761e63bc, 0x0006d4fc7d5ac481, 0x000065f27cb5b34a }}, + {{ 0x000c1fcd2acc0b57, 0x000dd0aab9d97f89, 0x0006f48308e66a00, 0x0009ba0e5fb57bd0, 0x00003a73253811da }, { 0x000f78f55b916830, 0x0009ca9c7ea74322, 0x000c0107819b05c3, 0x000f31ca51b0b924, 0x000084e2a1bbee98 }}, + {{ 0x0006f2e3dafbe296, 0x000de4ac18a414fe, 0x000da94a26abfc55, 0x00062a955c611eaa, 0x000053a9ca6e3b2e }, { 0x00087883af2cb656, 0x0000a179320dc3cc, 0x000ec57e31f52ec4, 0x0008aa490692e382, 0x0000c6a39be83100 }}, + {{ 0x000cfd57c06983bb, 0x00098e453544774f, 0x000b3dde4afbe78c, 0x0005fb6f5834d0ec, 0x00007bae9c3b3751 }, { 0x000ee4d65bdcce8d, 0x000ab3dd6901b1d3, 0x00047673a7680203, 0x00093d2623b49fbb, 0x0000be9b2e57312a }}, + }, + { + /* digit=27 (1,2,..,64)*(2^{189})*G */ + {{ 0x0009ae30f9bf470b, 0x000087d0d63d1fae, 0x000118fba7a5a59e, 0x000fc5809658fc05, 0x00005a1e22227a90 }, { 0x00083acb655ee723, 0x000edd1818baf918, 0x0006032f40bacfef, 0x000334844e27e9e0, 0x000040f4d53495bd }}, + {{ 0x000ee84e265cd5da, 0x000988dc2c6ff707, 0x000f46f3d40f2a5f, 0x0000c9df979d6122, 0x0000ed01e35bdcbd }, { 0x0002d0793015eb1a, 0x00095b063cd880a6, 0x0005d2a436307bbd, 0x000f365423f3ea7c, 0x000081c0177d53ec }}, + {{ 0x00065f36c733ecb7, 0x00097438a5807cef, 0x0002edb163b75a2e, 0x000e8e6daad28389, 0x00005a009a4a047b }, { 0x00026231865878db, 0x0006b9ea60d32b2d, 0x000a6c1f604286b8, 0x000e303b5ee93df4, 0x0000ae2226c13edc }}, + {{ 0x000968734e4dd7f6, 0x0008df9dec31a21e, 0x0002817162256254, 0x000a3ed65988c8b2, 0x00009bb859066057 }, { 0x000f94739f3adb65, 0x000858f5da6309bd, 0x0003e25d5a77565c, 0x00068a42110f3a62, 0x000053d37190038f }}, + {{ 0x0004cf63c0f10c8f, 0x0005106cce85c9b6, 0x00063ff85f12ae8f, 0x000ed8f60360e70d, 0x00002db912ea29bd }, { 0x000f8b36c18dac42, 0x0003da3e1cf6f904, 0x000686550e256d64, 0x00088999fb7e937c, 0x000091b309d5b740 }}, + {{ 0x0002ceef4d55dd08, 0x0005da434a35ea84, 0x00070a7523a8c814, 0x000ab2ec33418e0f, 0x0000b26e001161fb }, { 0x000772f4c008038e, 0x0003c0b543a1957f, 0x000490f9bc634d5d, 0x000955f30c33761e, 0x00003c76f2e45ff6 }}, + {{ 0x0009ff51a206fb0a, 0x00036bb4885d4104, 0x000051a6a735edea, 0x0009dd5b17287f81, 0x000044dfcc90c3d7 }, { 0x0009e739a001c317, 0x000e3536bc3012e7, 0x00019d261a7db4f3, 0x0004c32663d31fd7, 0x0000a707f44faf49 }}, + {{ 0x00003f3e034d81e9, 0x000580ef4f8b16a8, 0x000e443be8670976, 0x0001a9ec197241af, 0x00001dd783168b20 }, { 0x000097440f10fef1, 0x00018a804dbec69c, 0x00067b238c506e04, 0x0008f287fa83b85f, 0x0000d016711f649c }}, + {{ 0x0000c59ad98e2c8c, 0x00023b63524ff164, 0x000e417a2bf4e4e2, 0x00011bec0d7f9b51, 0x0000f07523fe58b6 }, { 0x00038fdb3274f644, 0x000cf6f17c387a48, 0x000567f6a51af73c, 0x000642fc95043b8d, 0x0000e865fd6bdff2 }}, + {{ 0x0007b53ed41360f7, 0x000bfdd418e7ddd1, 0x00032f79db02b1a6, 0x000c6f44d39888d9, 0x0000587a59dee9f8 }, { 0x000b2fea9bbd72cd, 0x000351b2b01ae4fe, 0x0006e4189be73eb4, 0x000eb608788462e8, 0x0000369123795063 }}, + {{ 0x0003fd41b6333ef3, 0x000685fb821fc28e, 0x0006f820e91c2a59, 0x000f1c76289d2e19, 0x00007ba4f718025c }, { 0x000b586236bb3b57, 0x000552eb9a96d612, 0x000a0b3be1bdfbfd, 0x000c84d407f8567c, 0x000013167b56f73c }}, + {{ 0x0003132b63c9bbbe, 0x00042c756b95bce4, 0x00061e5a7b1cf210, 0x0006584525ec0390, 0x000035ffbec182a8 }, { 0x00063e8924f392fe, 0x00041f22f3263bf6, 0x000c3692181d584a, 0x000ae5ecbd5b3733, 0x00000ee6831f5d50 }}, + {{ 0x0000089cda3b5352, 0x000505e5236344e0, 0x000dbd9ed20c4505, 0x00078eb2282e8df9, 0x0000041841a4fdd6 }, { 0x000a6297cdfe9726, 0x0007a71bd38a3db5, 0x000095102157933c, 0x000a7b9754ea97fc, 0x0000a0b0d44f8deb }}, + {{ 0x000a11dae24e01a0, 0x0000b35ce7c42d4d, 0x000ea8ecd02dbf37, 0x0000f7b459fd493e, 0x0000a4b9f5308b34 }, { 0x00014369a85af1f5, 0x0000d785545a7fb2, 0x000c1f919e3e8182, 0x000750558bdb2601, 0x0000d24bcc8a4315 }}, + {{ 0x00019d679200106c, 0x0009dcb06e0956ce, 0x000e1f6f6bb91946, 0x0006139324c9d254, 0x0000df1391186504 }, { 0x000a6bd1e8bf9fff, 0x000a728db5c7be33, 0x000877e20c1d3762, 0x000fb2f2ec714121, 0x0000a3614c505432 }}, + {{ 0x000a1a96613ebed5, 0x000aaa0b311898c7, 0x000452f4160400b5, 0x00055fbbce2a272e, 0x000044105e96f0ba }, { 0x0002280dcf97d62e, 0x00039cea1c8cde9a, 0x0008d0499e144dcd, 0x0003fe7cd9d958ba, 0x00007fe9ad9ee6a5 }}, + {{ 0x000c0f4672046418, 0x0008dc1cf6401471, 0x000d42748aa65277, 0x000c0ad11ea5a2e3, 0x000085ed223cfbd5 }, { 0x000a05f641ba27d2, 0x000e5a9695653812, 0x0000b4c92919d77e, 0x000cdfe09dc96624, 0x000016ab44addb42 }}, + {{ 0x000306333a079f4d, 0x0008866d4312483b, 0x000cb137ee35846f, 0x00064f7935179a95, 0x00005b20b179b20f }, { 0x000dc92787c3fd1b, 0x000d1db0081a726e, 0x000561df74341404, 0x000949bb90149b0c, 0x00002a861cf9d27f }}, + {{ 0x000e08e3479258df, 0x000e34aae6a8e13d, 0x000dc12fb46451af, 0x000c1281585833fd, 0x0000a5f7d00a3745 }, { 0x000c0dcfd1df99fd, 0x0001b4ccdeff2e08, 0x000a8a50deff90fa, 0x000e2498a49f9387, 0x0000a9b6e98e5797 }}, + {{ 0x00094d3f1ba6043c, 0x0009de37a6a308bd, 0x000f72da28b830d5, 0x0008882b66237582, 0x0000b9540188ab4d }, { 0x0007f04703513909, 0x0006a5bba21f248e, 0x000484e1a8ad4170, 0x000772984272ad0e, 0x000027dd807898b4 }}, + {{ 0x00077c871440e1a8, 0x000184acba2ececf, 0x000fec2ab72d4975, 0x000078f250c18126, 0x0000bcb6186f88c3 }, { 0x000109fe96d12373, 0x0001e83fa7f9f909, 0x000bfb8d0916c333, 0x0009e56a3f2e7aa4, 0x00009e0eec3e2355 }}, + {{ 0x0003f901e0ee3da8, 0x000c0a9e9adfe1c3, 0x000cfd5537daacaa, 0x000c08f8f3984403, 0x0000096fcbfd4004 }, { 0x000dbd3ddcb09925, 0x00000fe3652438c6, 0x00063014b42f3978, 0x000265abdae9ec4e, 0x000078614ff4c20e }}, + {{ 0x000bd4d8f33bce8b, 0x0009fecedd36776e, 0x0007fdb0b7462639, 0x00060e565f612c47, 0x000003f48d640dc7 }, { 0x0006125c1b173232, 0x0006eaaaac4cb325, 0x0006bfdae3ea27f1, 0x000704c63ea3aadb, 0x0000876e11548998 }}, + {{ 0x000320c5cb34fa83, 0x000c1a43794f8dcb, 0x0009951b966af168, 0x000a28da0dcca923, 0x0000bdaf4528f40a }, { 0x00083be9a0dbe4b2, 0x00076ff47b50a951, 0x0001b6b449d08629, 0x0002b4f53933e3b0, 0x000077b42a87e4bd }}, + {{ 0x0008df26cd861bb0, 0x0002c5ad6bbe24db, 0x000f9aa510c7c822, 0x000d07d4cc6c7462, 0x00007f4555c709df }, { 0x000cd8924978fe2f, 0x000b4995a483f8df, 0x000680fa9ef11fdd, 0x0000da47572d8a95, 0x00005ee12e0f4b32 }}, + {{ 0x00058280d4ddee6f, 0x000d4d77613aa81f, 0x000f907be4afaca5, 0x000c29388801007f, 0x0000bc59683be7a1 }, { 0x00091554cb1a8b9b, 0x0003d2f7c978c385, 0x0000b4cef8affa72, 0x000d48a2fdf1204c, 0x000070620062b926 }}, + {{ 0x0000f9e4bb715381, 0x000b6d6a05bd5254, 0x000ac69b9680aff6, 0x000bd1ac948d5f09, 0x0000a232a16a1065 }, { 0x0008d30a61a7b345, 0x000b503f46ad2ec6, 0x000f5b10ef8d1b72, 0x00087007700f766c, 0x0000f4ea35a1072c }}, + {{ 0x000b867e6badbcba, 0x000c7ea77b46a081, 0x0007abc1882dd01f, 0x000773c83cf5a647, 0x0000cbd5df06c8b8 }, { 0x000a7c66d6817ff2, 0x0001f141f60558ee, 0x000244c4de37c212, 0x000e31c8bcdbcdd6, 0x00001916c3d12b4a }}, + {{ 0x000dfcf4d119ad85, 0x00033a504e99fd8c, 0x000179885fc958ac, 0x00057cde198a8dd1, 0x00006e59f62aab6a }, { 0x000f97af8853b43a, 0x00033b253758da79, 0x00034b31e858e0f4, 0x00058217ee643bb8, 0x0000da4a5c964eff }}, + {{ 0x0001f37864c9d751, 0x0003720fbeee3f97, 0x000fd715a2986b25, 0x0005aa25c93e5348, 0x000088ce2f7480d0 }, { 0x000c9682db64cb9b, 0x00099e0943aa75e5, 0x00084ef974089e2f, 0x000037219a18c9c5, 0x000082104449d5cf }}, + {{ 0x0007678cab68e47e, 0x000cea6b709c3de9, 0x00019e0e2c451e58, 0x0001cd6bb64a8426, 0x00005633f2cb7399 }, { 0x000c5ab10a85e889, 0x000f05f951a95c33, 0x000314a21afe0190, 0x000f06731dd35b16, 0x0000667bfe6e1cad }}, + {{ 0x0000a02b0eaceafd, 0x00088c341dca5663, 0x000aa7c1ff9509d6, 0x0003070fb7de7fed, 0x00009716331f83e3 }, { 0x0005f449ec69c78b, 0x00092aa2fd3cf36d, 0x000709959bb35e00, 0x00081dc33d131954, 0x0000174691c29863 }}, + {{ 0x00091481c1059a6a, 0x000b11b25fe531df, 0x00017108d4857909, 0x00043e61af979743, 0x00005c928c67b126 }, { 0x000f9f87695e4b85, 0x0005f65f8b05bc60, 0x000ef348b5716c43, 0x000905e3b1844e1c, 0x00004c192e0ee156 }}, + {{ 0x000c992a8a0219ee, 0x000c3c038b27fe29, 0x000b0f0ad855471c, 0x00051edab63b6359, 0x000025a641ada563 }, { 0x00048d3f95b0f902, 0x0008d152a60aed16, 0x00047c320a49af15, 0x00049d79aeb089ca, 0x00008fe88effe77c }}, + {{ 0x000de501a3cb5123, 0x00060a8e1add3f34, 0x000a017fa1a51172, 0x000dfb8dbf42c0c6, 0x000001a82938cb34 }, { 0x000025a2cad7b920, 0x0005c1f4b9a64bc7, 0x0002b4712a8e7257, 0x000cfbffba77f0ad, 0x000059630c29979e }}, + {{ 0x000c477cc78dbf35, 0x0007dd1d1a8f4e7a, 0x0006c70d15b57029, 0x000612235f5b3da4, 0x0000dec5fdbedc4b }, { 0x0009b795f963ab82, 0x000f1d2a883239a8, 0x000642d3ed5e9773, 0x00073cd86e12572f, 0x00006777294aa397 }}, + {{ 0x000ef0e314d85ff1, 0x00065f1b54398dc7, 0x0006c0fd0bc04f5e, 0x0000d10401890efd, 0x0000f8bc668d0ac4 }, { 0x0002c591e55172f8, 0x0006e31cc61dab32, 0x000dd1c0dc69ff57, 0x000c343394a39801, 0x00008f9576364d5c }}, + {{ 0x000e02fc57543709, 0x0009a08de02a53e8, 0x000f4586f7004114, 0x000bd02662a6c060, 0x000038ad03da91a7 }, { 0x0003660ea088e386, 0x000f19573adb4ba8, 0x000c244a29655bb1, 0x000aae9a67b86122, 0x0000a46975ac7183 }}, + {{ 0x00097b8de565ca26, 0x0006b0521ba473cd, 0x000e0559aab8550d, 0x000b275c0b6c50be, 0x00008c7a7b476844 }, { 0x000df7725c5e3459, 0x000e570ab3bbddbe, 0x000e37a00efe4bc1, 0x000e15ad93898aab, 0x0000dfe696962d4d }}, + {{ 0x0006166b44b3b527, 0x000e8abe085116b3, 0x00055111e7cb7191, 0x0000aae2f04a4337, 0x0000b8cbd7d43a2f }, { 0x000af71e91ff6ddc, 0x000673cfd4b322cf, 0x0006bf828cbf933f, 0x0006d39eb726aa81, 0x0000f4fde56a46c2 }}, + {{ 0x0002cadc98401f3b, 0x0006b40641fad989, 0x0007969748c19d4a, 0x000225edcb799591, 0x00004bb11b390d9e }, { 0x00095f7b90617d6a, 0x000b98b256534e4c, 0x0005bc35c509aeaa, 0x000e05b9b73e80ce, 0x000010012b3ad66e }}, + {{ 0x0009cf84aa0fcd26, 0x0004a14d856ac253, 0x000d7282c920e466, 0x0003773f5441bd9d, 0x00002c3a08dedb4f }, { 0x00017edeb92c2909, 0x000a755b2aa95a02, 0x0009ec6039a6d8be, 0x00016624329e33f0, 0x0000c812d89efc16 }}, + {{ 0x0005b9b9cd84c5c7, 0x000783583cbea55b, 0x000d065ea3a2d3f2, 0x00099a292c485ee4, 0x0000a2524bfd6d99 }, { 0x0008ca325a560d39, 0x000b58e4e9e8a506, 0x000af99fa8a3269d, 0x000da58c6462e907, 0x0000ea5c18d58fa5 }}, + {{ 0x00060fff17c23588, 0x00035f213b5ba885, 0x0009dfdf0bac693d, 0x00084130860294c8, 0x0000c20857b9d557 }, { 0x000c2f31600cb009, 0x0007b87d67703743, 0x000d5e27c525487b, 0x000416cd9a373202, 0x000070a468d0a739 }}, + {{ 0x000f684368d3db41, 0x000a8dd7b9520e80, 0x0001fb87f44c3d55, 0x000c0cf4cc078f9e, 0x0000fafd402c5e4a }, { 0x0009cd516968dccf, 0x000e6ed6247e7ef6, 0x0008cfa0acb86b14, 0x000bdd3c2b32d33a, 0x0000aa46051a8ae1 }}, + {{ 0x000f0837e6eccb46, 0x000940f4b3234da4, 0x0005654f66d7528e, 0x0005930c7cf0b023, 0x0000ef0adfc93e80 }, { 0x00089a4060c4f953, 0x00022bb906f6e98b, 0x00040ec7a770d547, 0x0007a5c10253bb43, 0x00007cea8d76fea9 }}, + {{ 0x000f5d57fd84b794, 0x000acc5b8cc037fb, 0x000ab4a8634a4c70, 0x000abb4b83d093a5, 0x0000a4275cfe559b }, { 0x000ef22458521286, 0x000430c8c3bef483, 0x00031b1871b237e4, 0x00018bcab23ac762, 0x00004ef2dd9f1303 }}, + {{ 0x00081dcee597d414, 0x00087dac97e65165, 0x00006a1325b93f7a, 0x000a0d6498877936, 0x000087e6a262fd86 }, { 0x0009a34fc66e7cce, 0x00055918f483f148, 0x000c479481754c72, 0x000f76c426d2dddf, 0x00002d39a7634863 }}, + {{ 0x0008653ffddba12a, 0x000cbb312e08ce5b, 0x0007ef8b72cc3850, 0x000f6fe05a80540b, 0x000001a887b97925 }, { 0x00059b30e1948bdc, 0x000ab8702b0b4c9b, 0x000ee52fe628f9ef, 0x0008038e52675261, 0x0000cae50b48aefe }}, + {{ 0x000aee5ef0da9c40, 0x0005ea60200ec7db, 0x000850dfb43a4325, 0x000a1e7e0b6f4a3f, 0x00005fd883bfa016 }, { 0x000d4f59c8134ed7, 0x00093aae4c6cf389, 0x000633e73e4d5bf1, 0x0008679c6ab4cfe0, 0x00000083cf7bbfdc }}, + {{ 0x00032363a7734ed2, 0x00081b151deb6adc, 0x0003ee6413a23cd6, 0x0001134e1812399a, 0x00001e7ebc657857 }, { 0x000b6f7d030cfaa8, 0x000a7bedc36c64d8, 0x00011c72315df52d, 0x0000f314a86c81e3, 0x0000b2a701f2e2ac }}, + {{ 0x000d56d36a2b2bd9, 0x000140756faa38ab, 0x000bd5aee7eac178, 0x0009b5761a3790e6, 0x00007e4559f47050 }, { 0x0008c39768edb7d6, 0x0008349229a8aa9c, 0x00067cd254bfe89f, 0x000f379e6dcca8f4, 0x00007ea637445818 }}, + {{ 0x0009ebbecd961518, 0x0004736523f2b367, 0x00031821d4ee4c8f, 0x000dc4b2b995c649, 0x00002214d933e9fa }, { 0x0007d928a6a9b4ac, 0x00091db79592f48f, 0x000a67afc0f21e06, 0x0004c6d3e67216a7, 0x0000a28afa8ce512 }}, + {{ 0x000011b6acb767b5, 0x000cf17e991f600b, 0x000d796ff2879e7b, 0x0004986de2a91113, 0x0000f0d31fd49b4f }, { 0x00076430677f20c6, 0x000ef18045ec6135, 0x00016b9162a2f02b, 0x0000d9fde522d2d3, 0x0000d682877747b9 }}, + {{ 0x00075b4a21968cc3, 0x000ad5d1c7193f0d, 0x0006648d3b6cc785, 0x0003a1cc7f0f32f4, 0x00007e378db65c00 }, { 0x0007387e1e912b73, 0x0007e7b342659d41, 0x00042db7b9710081, 0x000269f9de596ea3, 0x0000a3bf0865713d }}, + {{ 0x000cca31c7a57625, 0x000ade949dee1686, 0x0002d160c071cd59, 0x0001de16a1ae0522, 0x0000da394a68f678 }, { 0x0007da93fd13da3f, 0x000971d9bc499082, 0x000cce082821a131, 0x0009544ac4a9b4a8, 0x000025d76c70fa80 }}, + {{ 0x0005f1bfec0f543d, 0x0000f964821c8c54, 0x000d624a5608dadd, 0x0009ef3048de49de, 0x0000fc43c74c346b }, { 0x000087cdaa1179d9, 0x0002d2654b9df609, 0x000c18d43d897611, 0x00089848e5e4fdc3, 0x000036663c4320b0 }}, + {{ 0x0009a7b853608cac, 0x00070238319ade44, 0x000a94e545a4d669, 0x000e28b05766f287, 0x0000f55f670cf4d3 }, { 0x0002971e277b213e, 0x000baa75cedadfd1, 0x00057b1b89ee3e92, 0x000d551958f56281, 0x0000b62941f52c86 }}, + {{ 0x0002ad741cbec2f6, 0x000c096d0ff34fce, 0x00012f74fd700b35, 0x000d2324d20824de, 0x00005c4e2951824d }, { 0x00078a169ffa86e9, 0x000bddf54043ccfa, 0x000b30b9fc13145c, 0x00042a1f016ff479, 0x00009b49c42140e5 }}, + {{ 0x000e5064503a3e24, 0x000634699c930e9d, 0x00076b90b3559e70, 0x000e6519f1d33e85, 0x00006cd16fbc642b }, { 0x000249ef84233f4a, 0x0001300caf3155ed, 0x000bea29f7db9bad, 0x000cbb7db672d66a, 0x0000fcd7af334203 }}, + {{ 0x0004b29cdde6a208, 0x000ced473978fe39, 0x0001e09863c37a8f, 0x0003dc7e9cc4e454, 0x0000cd9ff54a2771 }, { 0x000d2de14cb33c91, 0x0007bff9bc7edf24, 0x000d86ac84a73116, 0x000ae7a488ac236f, 0x00008575be2d1315 }}, + {{ 0x0004d1f3d3a5e8cd, 0x000eea760430e540, 0x0006d56095d81a1d, 0x000aecf5910a2d0d, 0x0000183d1a538a31 }, { 0x000c80b505a3cfa0, 0x00084738a0983cd2, 0x00089c0315b5fc22, 0x000d5e99528e25b3, 0x0000e560b7c69fa3 }}, + {{ 0x000d37c5b1792718, 0x00023714a953beb9, 0x000e790b2245754f, 0x000aecf22502e223, 0x0000c74bd4088fe8 }, { 0x000016a8607ff0a0, 0x0004d70f8330bc73, 0x000645907f288125, 0x000de2cc2139850e, 0x00005677b1f28c7f }}, + {{ 0x000e658aedcda8bb, 0x00031644cd8f64c3, 0x000fe937f063f6ea, 0x0001e975658a2d78, 0x0000049c304fd752 }, { 0x000473ffef5b241b, 0x000792e05da59eb6, 0x0002a9683732b03d, 0x0000a6487ba3d60a, 0x00005d72e137e219 }}, + }, + { + /* digit=28 (1,2,..,64)*(2^{196})*G */ + {{ 0x00099ee566eb922a, 0x000364f692ac542f, 0x000028dcac6c9771, 0x00018cfbdf079ffe, 0x0000610be982fc2a }, { 0x00013889ee80e815, 0x000511fd62191997, 0x000663545a2e0935, 0x0008cc4048c883bc, 0x00000920149ca0bb }}, + {{ 0x000eee0c0ea6e1a4, 0x0009b8f81a1b3bed, 0x0004ef395891f049, 0x000e351f74f3ce14, 0x000069aac489bd81 }, { 0x00027729a694a1ff, 0x000aec0d39e25c35, 0x000071f076d9e952, 0x0002d5b584061982, 0x0000a6863991eccd }}, + {{ 0x0001ad919aac7231, 0x000d837b1b76ba6f, 0x00045b7295421df9, 0x000677d0a1a2eab8, 0x0000c06c35fd7a6d }, { 0x000314874f18d1ae, 0x00031b807ea7b0ef, 0x000e4bc5643a1ce2, 0x0009b5aabedf5496, 0x00007faef00cb014 }}, + {{ 0x000747ea0bede08a, 0x000e0753f73f449b, 0x0007d5fd126e01d1, 0x000e0524d1d1c94f, 0x0000db80899bb94d }, { 0x000c10697e01e74f, 0x00074fe228d291e6, 0x0004d7b0c0585031, 0x000c5761635b804b, 0x0000e6909f3f3acf }}, + {{ 0x000a8f2439972c6b, 0x000d88f0876fd4e6, 0x00071943cf4a2c61, 0x000dcc9cb45f0c30, 0x0000274cda09b319 }, { 0x0004426efde75793, 0x000b01b65ccde7b6, 0x0007c3a4fb720a13, 0x000dcf1d741e2cd1, 0x0000483cddf39166 }}, + {{ 0x000d32fba5127c0b, 0x0008344fc94dea3f, 0x000edda3a50b098e, 0x0009531ef34c8cdb, 0x00009ea6e5479af1 }, { 0x0003173f9743bb5a, 0x00036f6795dcfb75, 0x000330414c181516, 0x0006467c0fef01b0, 0x0000608f1137cc86 }}, + {{ 0x000731021c804f19, 0x000272aba16f73bc, 0x0003c5c8b7dfaace, 0x0001fdebf2fb3101, 0x000060e66ffcf1c4 }, { 0x00051f55a60c6b7d, 0x000ca244fee99d47, 0x000685a66c4490cf, 0x0007f1df74bca48b, 0x0000e008421c6eaf }}, + {{ 0x0008949a50ad4589, 0x0009c1acb452fdbb, 0x0004985e6bffc0ea, 0x000efbfd931ee696, 0x0000aba564d3b7e5 }, { 0x0007a12f75fecfe0, 0x000a3263c88f3bd1, 0x0000c37c6a1321bb, 0x00004ff03ab147c3, 0x00003bd493c68746 }}, + {{ 0x000b70130c3e980c, 0x0006d6d36cf69db9, 0x0008baf6f90bfcc1, 0x0006f018e1219eee, 0x000018a15b3aeb3b }, { 0x0007bfbcdfd435df, 0x00045620ae18e0e8, 0x0002bf00e958626d, 0x000f8d1d42021a62, 0x00007271917a37f1 }}, + {{ 0x000c923aa6870f8d, 0x0002805cdd61d649, 0x000c2c2f4db1707b, 0x00004e8158c7a53f, 0x00007b90d120c88f }, { 0x000555917e796337, 0x000d2cb5c18871f5, 0x00081e5e3af648e3, 0x0006e9dc47d53bec, 0x0000007d33f08184 }}, + {{ 0x0009ea61f1bde96d, 0x0004eda548f5a0e4, 0x0009f1d559f00cff, 0x0008e42c31910eab, 0x00004e2256a193b8 }, { 0x0004b491b0ca83fb, 0x00059784f7c39221, 0x000d0c11fd3eade1, 0x000f39fb995d337c, 0x0000591ec14b3514 }}, + {{ 0x000f450138039993, 0x00028e028e3fe894, 0x00047665bfb376d3, 0x000e4be40e7e1fee, 0x000057339c7f6d65 }, { 0x000251437e2a615a, 0x000058495cd81854, 0x00018b61a205b101, 0x000fd13e474be0ba, 0x0000b796f513feb2 }}, + {{ 0x0004e39da416895e, 0x00014a0ac6203668, 0x000c31f1f5a051e4, 0x0006217b94be3fb9, 0x0000b0003105438b }, { 0x0005627d144873ff, 0x0001590b38f04092, 0x000306c8616def58, 0x0001ca3d80295194, 0x0000cebe7a096ec9 }}, + {{ 0x000f637e4fd3515f, 0x000f1aa658a6d877, 0x00075038f4d59b63, 0x00035e9c91405aaa, 0x0000302534f4de89 }, { 0x000f15b373895ff9, 0x0002e7614ffad2c7, 0x000d3be5b41e6f6a, 0x0002f9afce58fb1b, 0x0000c8215fd1b036 }}, + {{ 0x0008d69d5541959a, 0x00013d2d842ca726, 0x0000d602c5aff83f, 0x0006b2414a71e439, 0x00004b346f996925 }, { 0x0007ac7bdebe7e5f, 0x000f46737183bcfe, 0x000a4bc46418e5e0, 0x00093f35b7152b7b, 0x0000aba65a5ecc00 }}, + {{ 0x00032811a7abd874, 0x000db7881fdad909, 0x00057a04e50379b8, 0x0002cd9e5cf638f5, 0x0000f7d1bc229820 }, { 0x000dd099becd5a2a, 0x00089309bbd11ff0, 0x000fa633afb561a6, 0x000f7a86676108a6, 0x0000803fa54a21da }}, + {{ 0x000c23f829f27693, 0x00017aaabe329866, 0x0009e4b1a3fd664f, 0x000b9e0050fe9dd2, 0x0000a20ae7baca9a }, { 0x0009a25a18798042, 0x000e0180b136a798, 0x000dedffaf7dd73a, 0x0003b0ba67e2174d, 0x0000f25ede8ca147 }}, + {{ 0x000ca5bdc1609c2b, 0x000777ec11ee01d3, 0x000aa94b503a968c, 0x000505e3cf900553, 0x0000383c90f106a2 }, { 0x000b715a6d47b75e, 0x000b73797eada9f1, 0x0002f4b407c350c0, 0x000850bb359c50ab, 0x0000b660a6466bea }}, + {{ 0x000adfe0af71e0c3, 0x00011766ae06e0be, 0x000db26301b0323d, 0x000d19720cdd7888, 0x00002c963a41c4e4 }, { 0x0007e4b0dd7b445f, 0x000f3a9699500937, 0x000aba9adc633558, 0x0009b296a3525d9c, 0x00009fbb8308b6ec }}, + {{ 0x0001610588bce8e4, 0x000ce0a517d7061b, 0x0002baccf0fa5475, 0x000de186777fe343, 0x00000b73f8bc3f10 }, { 0x0006327dec759e0e, 0x00076cad9c4ddbe2, 0x000c1742cdf5be97, 0x00048ba94b3164f1, 0x000038569d7d4e4c }}, + {{ 0x000aeebb5d055643, 0x00083de97b5cd328, 0x000e2afe337097f3, 0x0008894fe40835da, 0x00006140cad890d4 }, { 0x00048990ad4be3f7, 0x00038b75b8ee9ecc, 0x000cc9b3106b05f0, 0x00010490ed7a17bd, 0x0000a0c831b76ce3 }}, + {{ 0x000b19131435469c, 0x000e12a2199e347e, 0x00053f20cd3d5899, 0x00027b5dcbee7555, 0x0000ffa0bf10725c }, { 0x000a33a79b0335bc, 0x000a50d37d341eda, 0x0000aca174906343, 0x0001371ba434fbb4, 0x00002e3e4d934cd4 }}, + {{ 0x00031af02f504322, 0x0002e54e4bd6d3d2, 0x0004379a61a0f9b9, 0x000ffb1a609540f0, 0x00006ab7f4c255f8 }, { 0x000c8be793b491d3, 0x000b9ac0992c163c, 0x0000bc025420deb3, 0x000fa538c1fef8e7, 0x0000930f5d791209 }}, + {{ 0x000a5e00b2f8398a, 0x000f1aec61c3855c, 0x000c8e63fc8830ec, 0x000d209b8ebff429, 0x00000550b4100d93 }, { 0x000174306911bdd3, 0x0002e17c3fed8b79, 0x0009f027d18dbd75, 0x00051ea54d49ac6f, 0x000037ee2449542a }}, + {{ 0x000db067bf6ab9fa, 0x0009e1eaff2ef812, 0x0004fa6846c16bc5, 0x00070ae92c3654d3, 0x0000e7bed9e284b0 }, { 0x0007c60de3cf3529, 0x0007586703dcc974, 0x0007996dd4321892, 0x00065515ce66f9b3, 0x000045556034c314 }}, + {{ 0x000ee790cfd235d5, 0x0008439d860f1b25, 0x000c9705bc7a9c0a, 0x00080e7bd3e9a1db, 0x000066b271a5cef7 }, { 0x0005613245b1f9b0, 0x00084b15bdaf9bbe, 0x0006674163ab3eae, 0x00094878c02cedda, 0x0000e912b227e619 }}, + {{ 0x0009176f1bf4b9dc, 0x00046cc76b23a502, 0x000ce154b2b21706, 0x00010e7f54a2793a, 0x00007203d4f46495 }, { 0x000438b216a5a2bb, 0x000a6874f6f59eb5, 0x000937a3b3776086, 0x00040490286e9bca, 0x0000d17e13cdbcb2 }}, + {{ 0x0005ab800dbb99e9, 0x0001d3c7672765ab, 0x00034f9c39b14ed0, 0x00017bd3337a3ce6, 0x00006e48af02badd }, { 0x000ed04363ca7756, 0x000e95911a5acd6a, 0x0006974fcd00271e, 0x0001ecb0abaee615, 0x0000ef5280b8e5db }}, + {{ 0x0002ace7a063fccf, 0x000ae1ca4a82b765, 0x000ea0d384496b84, 0x000df9cb55586960, 0x00008b8c0663e8a5 }, { 0x000afe4322af8875, 0x0000118cbbc9b701, 0x000a454e62bf1e10, 0x000356c334f06fd5, 0x000087253946a7be }}, + {{ 0x0009b42e68963555, 0x000d7a6c44b2c6c4, 0x0008c5444f9610d7, 0x000340e77ab72679, 0x0000087d908b7398 }, { 0x000d2878a8e58f15, 0x0002fc3cea0b1760, 0x0007bdfe18d92915, 0x0002b88cb53a8ddf, 0x0000dccc4d1142d6 }}, + {{ 0x000803fc21b1eff9, 0x0003cd5d019b6a39, 0x000da86b222452c9, 0x00067c811bb5cf88, 0x000099bb7d29f4a9 }, { 0x000469591564f145, 0x000d79ec07764a90, 0x000eb2f2773fea31, 0x000f584ded93286e, 0x0000a5e431316829 }}, + {{ 0x0002ede0e2398f58, 0x000858a58d6cd461, 0x00057b7853efdb37, 0x0008c6b289cb633b, 0x0000c7e7d1c765be }, { 0x0009e66e59813ff9, 0x000d162065a6f4f9, 0x000ccdd7da21b1ec, 0x00007f41cc3a47ec, 0x00006d5b783c2d8e }}, + {{ 0x000ff6ea2132c1aa, 0x0009aca63d0ff123, 0x00047619b63e3c43, 0x000ebd147e5efc78, 0x0000e1e9f3d79049 }, { 0x000b88bb8cfbac0c, 0x0006d1bf21db8b7e, 0x0000ec5079d8d077, 0x0009fcead7dac70b, 0x0000f978502a906d }}, + {{ 0x000d9e8a3ff2c9a2, 0x00092b4dfdbeb1be, 0x0001c74fc3aad1fc, 0x00088a62122f5ca7, 0x0000f11570bb28f3 }, { 0x00061bd711a3d136, 0x000f6b1b961f49a5, 0x000124e4bf5ef7ad, 0x0007f446d7fee2ec, 0x00002e82c2e6427e }}, + {{ 0x0000ba9d0379c1f5, 0x000a7cc320bbcaff, 0x000eee634788d256, 0x000e6fc28568434c, 0x00003ef3f9080a95 }, { 0x0008117623d9511e, 0x000220432ff9f60d, 0x0005ea4c590f9a09, 0x000762eef3dd8e4b, 0x0000d0f362b6f269 }}, + {{ 0x0007df2ca0800f08, 0x0002076f51fe76eb, 0x000b59f6f8e8b673, 0x000134f188a6811c, 0x00006d8c2c59c4c6 }, { 0x00047ed447b1ad6a, 0x000e452dd7b205bb, 0x000793240fcc896f, 0x000fba748b695947, 0x0000bc03136d4c3d }}, + {{ 0x000c521308e5a687, 0x00011b904c9d9bfb, 0x00005f271d3f34ca, 0x000785d61661e288, 0x000077daf5dd5dca }, { 0x000d465b18f0dbea, 0x000b6fc2477de506, 0x000c1076f6d6d82d, 0x0004d5f05d80bb41, 0x0000b02bf176d362 }}, + {{ 0x000288573948f643, 0x000b030fb6840fd2, 0x000411798f8ece00, 0x000bf71f8faaeb21, 0x000084d5f1bed683 }, { 0x000b394dafddac9a, 0x0009c7c7bc467dfe, 0x0002ed0984ca7407, 0x0003d7aa6926562e, 0x000088d23eb26432 }}, + {{ 0x0004b74cc6bc1151, 0x00094d211c0be981, 0x00016c97349e82d9, 0x0001a7d1cb1e6ed1, 0x0000a0c06a8af629 }, { 0x000cbac448c5b98a, 0x00087868c060985e, 0x000d4102bb339e15, 0x0004fb8ca071047d, 0x0000652742014308 }}, + {{ 0x0003ca782157f884, 0x0004ce2ebf3232f7, 0x000e515fb6bc3716, 0x000bcdbdbfff80f9, 0x00003291c8c0121d }, { 0x000f24a939bc6d67, 0x00079a0e6251b462, 0x000c1ce8e9f3b13f, 0x000f03a9a89bc6b5, 0x000034c1818b3d4c }}, + {{ 0x00027c1c2e5d8f7c, 0x0000246766561b79, 0x00057c5415fc3c25, 0x000fe9c65736600e, 0x00002dd1b7dc8305 }, { 0x000cdd998788c6f5, 0x0002e370cc5df696, 0x00019cf8b021a08d, 0x00028e62799b37c0, 0x0000aee1d95fb4e2 }}, + {{ 0x0004274408c7cb95, 0x0007431390420d28, 0x000b855cab9ba1b9, 0x0006e19ad299c40a, 0x00009b7daa386fe7 }, { 0x00051fddc7f82d4e, 0x000c1b991a711a0c, 0x0007da32cd4f739f, 0x0000f20d6461592c, 0x00002ee7a072ece2 }}, + {{ 0x000bcde201ec9e56, 0x00068b6da50d5311, 0x000d8ad9d7d8a81c, 0x000ad8689521b840, 0x00004b23d5891c53 }, { 0x000e61d34d4d78fc, 0x000ab8b3b76a59a8, 0x000d791746cea6ae, 0x00018f11cf84841c, 0x000090aaea3d7172 }}, + {{ 0x000e7ba65e352870, 0x00054515541b8923, 0x0001be21f7f5e835, 0x00096f10db186ee4, 0x0000fd944bfe00a0 }, { 0x0006f4ce31269aef, 0x000897aa83694867, 0x000717c0ec22773f, 0x000ad2cc309f9dab, 0x0000350aa14102af }}, + {{ 0x000ff862f1ec19ab, 0x00055cff4f066b52, 0x000316254cd0bce0, 0x0001eee9889ab514, 0x0000f50054e6e5b7 }, { 0x0001743d0a1819e9, 0x0001085b05556e3e, 0x000d52f2cb14146f, 0x000ac4eeacd96058, 0x0000e5b40fed6cd5 }}, + {{ 0x000d1e0148639a3f, 0x00033e27eb37726e, 0x000d27639eef0363, 0x0005a6b79f7fa264, 0x00006a16397995e2 }, { 0x0000ad13cee1fbfd, 0x000fc7982e7abe2a, 0x0001a54920299425, 0x0003bc23a19eedc7, 0x00001d27e9fe8f7f }}, + {{ 0x00045446dee19896, 0x0003f241c0e651a2, 0x0009de79db9fb24b, 0x00019e8caab1a6e2, 0x000018a4f366b869 }, { 0x00075841e5ee98b0, 0x0007a2156c07613a, 0x000e4ccf12b26b49, 0x00064594643deafc, 0x0000c457c3bae579 }}, + {{ 0x000e4bf888b90c57, 0x0004f777b0ac93d1, 0x000d5aa9e84f32ca, 0x000e8f22ba6e37b0, 0x0000c2bfd71f0dbd }, { 0x00029438c4942ce8, 0x00044e04df0ba2b4, 0x000d0dcdfb573987, 0x0007fc420935d5cf, 0x0000d2dbc8e26eee }}, + {{ 0x0002e6bead7a7f69, 0x000d2c9049d33fa6, 0x000a3188a951a288, 0x000226da358b82dd, 0x000075c3d6d80aed }, { 0x0006a933d8e7223f, 0x000590fde46c58c0, 0x0009631fa3e61563, 0x00058f6eca7f6937, 0x0000e503ce844e9c }}, + {{ 0x000ca3f44a175048, 0x000c69b077ff55dc, 0x0007ee82f2366b2b, 0x0004c6d4f5397779, 0x000038a3ff5c2a06 }, { 0x00093eed830e7f4f, 0x0000d87a07eda0fc, 0x000f34251345035d, 0x000668b72c138bcc, 0x00000099d6e25005 }}, + {{ 0x0009915109fb7643, 0x0006e574d0b75c00, 0x000259f4b65201c7, 0x00004e9169716eb4, 0x00000af81e525286 }, { 0x0003c7b8c6ede208, 0x000a1285cca6c3bc, 0x0009713e103947e7, 0x0002278c4b25f7d1, 0x0000e315b9cc5975 }}, + {{ 0x0008f732f82265f4, 0x000243c5a1f8e24e, 0x0009b4db22f81d33, 0x000196ea6fdb118f, 0x000088f3204c98a0 }, { 0x00032a76c6083b31, 0x000fc910be786ab0, 0x000f079b2a2f4a0e, 0x000eac5945d32ade, 0x00004fa0648f108e }}, + {{ 0x000ceb151b607fe0, 0x000b1a3ebeb15447, 0x000bc1ec25a82383, 0x000ecd8b344b7b88, 0x00002db5e0795ec4 }, { 0x000e9e1a3e4dbbe7, 0x0007fd05bc1e6a8e, 0x000a1a70ed816faf, 0x000d78e89ec70cec, 0x00003b862411af2f }}, + {{ 0x000a22d40d38f45d, 0x000ad84745b98d25, 0x0000cb34193377df, 0x000202fb9da429a2, 0x000043d54875e04c }, { 0x0009c0bb328b4510, 0x000a9e570e8a4cea, 0x000af4ed4846b07f, 0x000c6c47ebfd1445, 0x000063d3c380d98e }}, + {{ 0x0008653ca70dc05b, 0x000f2600a4c3f6b0, 0x000923b0b29d901b, 0x00087efccbdfaad7, 0x0000bcd3b0c08f71 }, { 0x000be1fdf72ebf6f, 0x0001824538873a39, 0x000d10ffc9f0003b, 0x00023c3ba09299e5, 0x0000ad9a8d1c6f7f }}, + {{ 0x0004957d29e4f3e6, 0x00077595758b11cd, 0x0002f3cfd216bfa7, 0x00043ae470b85289, 0x000035c69d5fca6d }, { 0x000e1c2610168c00, 0x0004363646559b01, 0x000c2b5c647e66bc, 0x0004254a9f4a8273, 0x0000abe6b046a81e }}, + {{ 0x0006133b9250e9e5, 0x000fd28cf6a4a81c, 0x000255354be09066, 0x000bfdc5b1fa3b6a, 0x0000d8a9469a7e74 }, { 0x000ceecdb6a205f7, 0x000de5c9dffa978f, 0x000c624a983be8bf, 0x0002cbe2fba1d1c1, 0x0000bd9e811e29d5 }}, + {{ 0x0009e1cce6add388, 0x000825f10f2b8f5d, 0x000e826a627d023e, 0x000263a13c83a6cd, 0x0000bb21395fab4b }, { 0x000121696926c8fb, 0x000c17caba7e3721, 0x0008ceb03971e6c8, 0x0007d1de5fcdc74c, 0x0000c71b97399710 }}, + {{ 0x0001acfdfce2e995, 0x0000323f6021c5dd, 0x00041e444626f1df, 0x000e37e96880d5e8, 0x0000877660535d8a }, { 0x0005ab89623c630f, 0x00055e8bbb66840f, 0x000d7d09faf7745e, 0x000d5d9ecf7f4301, 0x0000fb09525a4469 }}, + {{ 0x0005b6c3c5a8fbdb, 0x0009e740e9547505, 0x00080f430f00f4c1, 0x00089482e0121de8, 0x00003c819e927d30 }, { 0x000f3e226365392e, 0x000b747519cb9fb2, 0x000f54ea3daa561a, 0x000484b1af134019, 0x00006b90423d137b }}, + {{ 0x00062246dec7aa4b, 0x000e51773d273b06, 0x000610ffa8bbeae1, 0x000a69139ccd2107, 0x00003c66d4c6b3ee }, { 0x000b65168903af15, 0x0003dfa6b83c0d12, 0x00076c84b6bd8c9c, 0x000e810e4a72df26, 0x0000ab60b5424485 }}, + {{ 0x00088043d808618d, 0x0000e7902f345331, 0x0003f3f77d7057e6, 0x000f1ef785e354c1, 0x000037a49cbea99f }, { 0x00040c9ad6afca4a, 0x000e5428c1d50261, 0x00067fc80fd4ebd6, 0x0008d7a502e0c8a2, 0x0000c659782ab4fa }}, + {{ 0x000ce3f19260a150, 0x0005a4225ac0f182, 0x000ad7ee0a60bfc6, 0x0000ef824f7b1295, 0x000023483fef7f44 }, { 0x0008e821b9993c9c, 0x00081558f2e1b72b, 0x00057742808a033d, 0x00081f954fe93228, 0x00002729d121fb3b }}, + {{ 0x000aebfa4044443e, 0x000fabe67e573e06, 0x0008d598ca0bb6e3, 0x0007d84c505891db, 0x00008b6a89573352 }, { 0x000fd835db9f7005, 0x000d7e9e56e55c19, 0x00028cd210f50d2c, 0x000afe3eb7148ced, 0x0000282da8971416 }}, + }, + { + /* digit=29 (1,2,..,64)*(2^{203})*G */ + {{ 0x0009d7b51caacc1c, 0x0008509081e9387c, 0x0006c2bba30bf8a1, 0x000749415fb9780d, 0x000016b6886a163a }, { 0x0009d9971a12e8dd, 0x000f041d6d9f6711, 0x000897c914fde7c4, 0x00037415fba6c1e2, 0x000044ff79be19da }}, + {{ 0x000a38783edbf56a, 0x0008a62060b5f619, 0x0003e197df84183c, 0x000ec5565a56f46b, 0x00003d764abc2d6b }, { 0x000a0edc3fc096b3, 0x00080a9da710718f, 0x000633fc0eb6b9c6, 0x000931e875a77998, 0x000072910f080d6c }}, + {{ 0x000f379672eac03b, 0x000fb216a31e09bd, 0x000ce1fd77c2b332, 0x000e09452de89e44, 0x0000aa34a9ecfe61 }, { 0x000697c8bf759643, 0x0000e0a2591d61b1, 0x000741c37bbc5394, 0x000923c7779aa87d, 0x000040557c30456f }}, + {{ 0x000c351b873ccd50, 0x000f849cb198ac73, 0x000cd2f12adddfbb, 0x00052b678a884a93, 0x00006d2e4199685e }, { 0x000ba6f9e2ce488e, 0x000619fe2c4b44b8, 0x0006a77f7f29e16a, 0x000b9984a580f6c4, 0x0000c4fae9993e3c }}, + {{ 0x0003c99a73f9f984, 0x000135f8fb547385, 0x0007d3fa5060028e, 0x00050845a3516078, 0x00000a2971005ebd }, { 0x0009a4598291f660, 0x000fbe05b81c51b3, 0x00088463f934f561, 0x00056b9a7925bafa, 0x000056cef7017b16 }}, + {{ 0x00043775095179f6, 0x00074b65eb03c0ee, 0x00038e84cad4f821, 0x000c08ad2f19b795, 0x0000a815addc931c }, { 0x000a6a2475d15354, 0x000e250bb3ee8a3e, 0x000bc6c7e2e9f012, 0x00084e0f675eb14f, 0x0000728fb5f890a9 }}, + {{ 0x00058b5fe31ed9d4, 0x00029950f8d67583, 0x00010b00a7fa7e99, 0x000085e21cb84e10, 0x00000fa25fc01a87 }, { 0x0003e86e791375d2, 0x000a5ec95f40e756, 0x0000d98b855d088f, 0x000a5c966f015545, 0x0000404ce330eea9 }}, + {{ 0x00079fb23be5ff7d, 0x000b7abd3c095f18, 0x000e5d17bb3553d9, 0x0003eec8404b261b, 0x00004c7b8e343501 }, { 0x000f0ac52ff88cf7, 0x0007572dfd754907, 0x0004e2b22c9118c3, 0x000d179073a97d08, 0x0000d6bca24f52c6 }}, + {{ 0x0003c66b47990520, 0x000abc46eb564d4c, 0x000bda90a2e18e10, 0x000f0dd5d8d6c752, 0x00005bcd40fc8105 }, { 0x0008ac0b779ee6a7, 0x0000d010f87de563, 0x000f8e19f83df780, 0x000692242ce62c06, 0x00009114b5e7e8df }}, + {{ 0x00062d8c5230f8f7, 0x00029ee4b049136e, 0x00014f3cb9c19a54, 0x000e78a288b63bf1, 0x0000675ced19a43f }, { 0x0004ac0245017d70, 0x000da67379e7896c, 0x000206517d607078, 0x000c44a6ab25237a, 0x0000c32d492b5336 }}, + {{ 0x000eff66bf542bac, 0x000fc6921fea4ca8, 0x000764e07402005f, 0x0003cb3afd36d081, 0x000058cf051c60a0 }, { 0x00069fb9dd0bb00e, 0x000a0e70b57235e6, 0x00009a66b74e0c7f, 0x0004cceb0ee3c39b, 0x000096f6178742b5 }}, + {{ 0x000e008c5bcdd3fe, 0x00003fb319d76820, 0x0008fc97a392e47d, 0x0008db544b029312, 0x00005611953b5d34 }, { 0x000d3a1aadc08c32, 0x000ab1c0278ca331, 0x0006c870390417da, 0x0008770cf666f76a, 0x0000e48921cecb9f }}, + {{ 0x000a418ea93670f8, 0x0002d3173faa4851, 0x000fa665d9cf986c, 0x000a06e7dc8ee6c4, 0x000003f9ec391ff3 }, { 0x0001e3de1002180f, 0x000ae9251f73971d, 0x0002084afa8fd8f9, 0x00025f4193e4b3c8, 0x0000beca7924e4e5 }}, + {{ 0x0000ffc1739db82e, 0x000d6ff50f75f9cd, 0x0002ad7569ae9e9d, 0x000e1e3181d8eddf, 0x0000eddba8e1699e }, { 0x00002aac66c37326, 0x000c6e3037d90f29, 0x0005d02ad905e85e, 0x000d947afe3f307d, 0x00000675780cc1ba }}, + {{ 0x00081be1ba9dae65, 0x00082bf94cdfadef, 0x000c87aaf47a18f3, 0x0004cfef86c97e1e, 0x0000bf0bbd559305 }, { 0x00049a602bc81752, 0x00013e4d14b4206e, 0x000dab067b39bec0, 0x00068756cbecc2e0, 0x00007986052ab4e9 }}, + {{ 0x000709def8c8c5c7, 0x0004c1a567193ec5, 0x000a8eed0812adee, 0x0005924ddaf3c305, 0x00002a0743a5403a }, { 0x000f431d23ed5fa0, 0x000f9830eb2b6692, 0x000b5818530569a5, 0x000050c164d80ce1, 0x0000cf41a7008416 }}, + {{ 0x000bead645c0c39c, 0x00076a6f9294dd32, 0x000f6f60373224a4, 0x00024945cb448d01, 0x0000848887261b44 }, { 0x000041af6242087e, 0x000c54d84fd8b072, 0x000fd7682f82c87c, 0x0004d3f85537b983, 0x0000ee0f932db6ad }}, + {{ 0x0003d2646d5d67ea, 0x0009d4cb940c71e3, 0x0009a78ce6cd30ea, 0x000b333c3211935a, 0x00008dbdca8a24d2 }, { 0x0003929f2c8f6353, 0x000834bef9114044, 0x000a56a9bfc7874d, 0x000d1d9789d1f25e, 0x0000546cc2b4beba }}, + {{ 0x0001b0310c8f78fa, 0x0006c67c7196e295, 0x000041e18d3c15ec, 0x00067d36e7992c2f, 0x0000cbe87245b10f }, { 0x000d6e5a5a506ca1, 0x000e9cfdd9f22cb0, 0x0001a8177b29d312, 0x000d4c288bb1d81a, 0x0000a9d05bcc9b3b }}, + {{ 0x000d04e18964b4be, 0x000696638235d4e4, 0x0006fc69510f82cc, 0x000629dc81c62bd6, 0x0000d69b284282da }, { 0x000f0e6f4ef7aeaf, 0x000670185a8068c5, 0x000133a42b363af9, 0x0005edb3bdb58e4e, 0x00008a81469b37cf }}, + {{ 0x000d487b80c0f188, 0x0000e8469ed23707, 0x000c8b2972a54721, 0x000aad30534dc30b, 0x0000077e05f5c7bb }, { 0x0008c4e13b06dfc6, 0x000f437dd0e71799, 0x00011b3f36d639a9, 0x00094b5a545f8019, 0x0000cc8a58f51d91 }}, + {{ 0x0003ff120d6b43b6, 0x00080e6e82c9f9e4, 0x000c7f3afe366902, 0x000473605711db87, 0x0000b79687b6563f }, { 0x000c63a68310f640, 0x000492fae77779bc, 0x0008c078f8ffc2c7, 0x000cf71bcf0fe0cc, 0x0000f50ef21963e0 }}, + {{ 0x0007fcd27a7b8803, 0x000b70c09dbe19a1, 0x000d535fa1484c62, 0x0005d09302f3585a, 0x000034ee43c2d08f }, { 0x000ec3df2b85cbb5, 0x000983410b3d5a5a, 0x00017bd6edc62975, 0x0009ead4209c107d, 0x00006cece29a740e }}, + {{ 0x000eb585fc03a598, 0x000fab73f894ae03, 0x000578a992d2287e, 0x000ae32d0f59df3e, 0x00009041a752d68b }, { 0x000f18757657a10e, 0x000fe8632c7f717e, 0x000ac07bc9d5c038, 0x000db43d2eb8c795, 0x0000beb76ad83f9e }}, + {{ 0x000f678f4d369698, 0x00025b20389168b6, 0x00087aefedb6701e, 0x000dd9882c4ecd25, 0x00001a019280de1e }, { 0x0006b6c517470dd7, 0x0003acf65e58dd88, 0x000e4d4bfbb60e27, 0x00029ea4cd53b4e3, 0x0000c0f835501259 }}, + {{ 0x000e54523f9dd595, 0x000453eb38dff6f0, 0x0002dc0f19a88a5f, 0x00007a2f8be012c5, 0x00001ab8ae664cc4 }, { 0x0008e19b0ec8804e, 0x0006636036a05d8c, 0x000e55b225f11a9e, 0x00001cfdf83e3cdf, 0x0000493f71b10088 }}, + {{ 0x000a39687fe60d79, 0x0001b3fb569a5fec, 0x000409fac4f5e2bf, 0x000df2700ad0090d, 0x00006a9ddd1bcbe4 }, { 0x0005efb775a4c718, 0x000f5f765959d77e, 0x0007b6a6922442f3, 0x0007a3c5139d7821, 0x00007d9756c3730d }}, + {{ 0x00063dec3e3e2558, 0x000b9a4e822f0d08, 0x0000d44918ba007a, 0x000a12a0fbc647ad, 0x00002a7318c6f712 }, { 0x00063dde65759c1b, 0x000423af017bfc7f, 0x0008a12da3c38c63, 0x00020f23b2005443, 0x00007385de06d196 }}, + {{ 0x000223802a112a4d, 0x000a2b32a4c94e9b, 0x000de4d4a76011b1, 0x000d92c3dafbff0f, 0x000052dfb56d8723 }, { 0x0002e8a4369887b3, 0x0008b578ec3fecad, 0x00036655cc1ccce8, 0x000df81c406c3831, 0x000054665660b4e3 }}, + {{ 0x000668270095818c, 0x00004525e9ca895c, 0x000dd0b84bde7efc, 0x00044e95c2f4dd31, 0x00005870893f8e51 }, { 0x00050bf75458d456, 0x00020a30cf43895a, 0x000fdeb71226c646, 0x00064b80ea9d604d, 0x0000539558e1b50d }}, + {{ 0x00090b3defe902aa, 0x00013def6a702510, 0x000b335f737a1d94, 0x000cddd62548b801, 0x00003e17f46314bb }, { 0x0009b0f6c59961be, 0x0000d8969cb91584, 0x00044fadd77dee87, 0x000783df544a9074, 0x0000f348045d2e71 }}, + {{ 0x00037dccb38225c9, 0x000f315adf7cccff, 0x0005ec2414fcf3b3, 0x00075f87e81a3e5d, 0x0000f61ae1e090a2 }, { 0x00009fa4f71b333a, 0x0000e73907fba12d, 0x00097997840dbf32, 0x000506cc535daa6d, 0x0000b54ff864cf47 }}, + {{ 0x000f979bec99a237, 0x00067c9aeb19a362, 0x000e982823c7ceec, 0x00020c3a6d913f1c, 0x0000fee386354fc8 }, { 0x000f2edcdad2a280, 0x0001d0f359679ec3, 0x000cc86c2785e2f4, 0x000583870ebcf523, 0x00007790dea32d3e }}, + {{ 0x0001f3e3242b67c2, 0x00037a76f568431c, 0x000b4104a667e1fd, 0x000a399d5f848c27, 0x00000c5d8c8cbcfa }, { 0x000519b637651d15, 0x0001c9c26c185ddb, 0x00079f55548ce1cc, 0x0006288576d85b7d, 0x00007ef27cc4babf }}, + {{ 0x000f6557c2e6a3cf, 0x00094a9ab87d59c5, 0x0002da65524e84bd, 0x000d3697bff9f58c, 0x0000bbd202141b4a }, { 0x000ea096448fc959, 0x000e70636a830417, 0x0009f74e8327d786, 0x000c320409b1c96c, 0x00005b046b469a20 }}, + {{ 0x000e20be26cf50fa, 0x000b9b56aa39dff0, 0x0002916d8f65e5bf, 0x000fb519f59b43da, 0x00002869fe6dd6ce }, { 0x00029808bacacede, 0x0009382e8ee47c94, 0x000b3b2178464d49, 0x0001271f6d9687cd, 0x00002d0288e392d7 }}, + {{ 0x000aa219cfc47b4c, 0x0005a0d4944b6639, 0x000909570115df01, 0x000bb97b1f901f7a, 0x0000200ebd199ed9 }, { 0x000598dee385254a, 0x0009875056a2512b, 0x000928ccfa78af5a, 0x0007a79eda4d643d, 0x0000a165f63eb2e4 }}, + {{ 0x000ef8428d09f84c, 0x00075e5dda9e5c65, 0x00026bb1ba085e32, 0x000339e444e0d3c7, 0x000054c2fab4516d }, { 0x000e342afaa45999, 0x0004b7a460ff0166, 0x000f041e56d127f3, 0x000ca11d2da6d12b, 0x0000227aebe64d5d }}, + {{ 0x000d33b92ef918a8, 0x000130b93a37c047, 0x000b5fdd04671ae8, 0x000939eb762b1bc9, 0x00007fee369cbc14 }, { 0x000ef80e1f1184ae, 0x000fb4be61fa29a5, 0x000ea74a1414172d, 0x00088df374b2be13, 0x000023e963704321 }}, + {{ 0x000d96dd292ac476, 0x000d0996d16768e9, 0x0009c4f514edec88, 0x00089d30d9fc4ff6, 0x0000a3049df36aea }, { 0x000386b3c21696a6, 0x00033d8ce5d72c41, 0x0004ad95bd8d614c, 0x0004dfa3e9d06c5a, 0x00004d05ba437463 }}, + {{ 0x0007d17dc0d747a5, 0x00043a6fb283f61f, 0x0004fbda463b273b, 0x0000591227df203e, 0x000021ce3dea9063 }, { 0x00056d9dd063bbcd, 0x000a144522055f0a, 0x000aea39ab0b5fd9, 0x00061ff14de3012d, 0x00000a88edfa935b }}, + {{ 0x000ff42bc607a539, 0x0004db68bcec9c2f, 0x000868177340b0bc, 0x0002d59817cf24df, 0x0000d7cc1c5324b9 }, { 0x0004c5f529e4d5e0, 0x0005c404d289427b, 0x0008ffbe999a2d50, 0x0006aa00c3d5f189, 0x00004942095ae6eb }}, + {{ 0x0009c75b689ed4a6, 0x000998fde94fdcb0, 0x0009bdfb94f62d7f, 0x00051ece1e96af73, 0x0000523f6b4acde9 }, { 0x00018c7501c3e7db, 0x00062f2b5932a7a7, 0x000e6c7d04ab9f0e, 0x000febb312658252, 0x00006c7c749a3df1 }}, + {{ 0x0006ba6d4797b4e0, 0x0004d69ea40dc3a4, 0x0002681194478eef, 0x000bc104adc84ad2, 0x00003476bddf339a }, { 0x000c417d369d684d, 0x00084c593e58a8e2, 0x0000e5ca8b55cecf, 0x0000639daa239473, 0x00006f34e5122d2e }}, + {{ 0x00056f1bda88811f, 0x000dac58b6f8efae, 0x00095202695bd2ef, 0x000b8aa2b671a2fa, 0x00009c76e0d6ec2c }, { 0x000d267e667d7ee6, 0x00088c49ff3c8eb5, 0x0001e6229e840d8a, 0x0001551942deae43, 0x0000a944be2e849a }}, + {{ 0x0000009e494c202c, 0x000e56db07159d03, 0x000f9188c3c7511c, 0x00075e979ae07a67, 0x00001fabe7db3e6f }, { 0x0007b796c365a4fe, 0x000b122e31328195, 0x000c9a831e3c24e7, 0x000b8d887cffa197, 0x00006565fda180ba }}, + {{ 0x000195969620544b, 0x000ef6ca1779ad79, 0x000da3e6732eeb47, 0x000605a7ea33cfe2, 0x0000c3bd61477f1d }, { 0x0004f291ca3b4ea1, 0x00018a6e546c8792, 0x00043da3370bd63f, 0x0009ddf6b8e996df, 0x0000fff3f513ba1a }}, + {{ 0x000136d7f23d9040, 0x000e3bb440e22296, 0x000212b875128f14, 0x00081ac39324673a, 0x0000c58b94474200 }, { 0x00061d7940cb50ff, 0x0002999b053a9270, 0x0001a7e9058caf2a, 0x000269dd93eaa266, 0x00002b4a7d3f8737 }}, + {{ 0x0003f67568134616, 0x0009283f06d18bd9, 0x00031e7992db2ac5, 0x000d4884d4ba6de5, 0x00005538b6570045 }, { 0x0002d4d4f88e4a39, 0x000381b4347237bd, 0x000f14bf8b95cbb8, 0x000ad048cbc041e2, 0x0000ef112474fce2 }}, + {{ 0x000533837f402aea, 0x0009089b3e93ce7b, 0x0004a806a89c97a7, 0x00030378af7b5a87, 0x0000d33d95cf20e5 }, { 0x000972a7c51e92cf, 0x0008b73579fab2e2, 0x0001c3649bc0b31d, 0x000cbc215b41055a, 0x000013a756b9af25 }}, + {{ 0x000fd1823a519a79, 0x000ba4ef678e68a2, 0x000069ded5b31a6d, 0x000323d9a4e4160f, 0x0000ac5ec7087e01 }, { 0x000c3930bb0e4209, 0x000fe2f3298f0557, 0x0009828e19b3d13c, 0x00072c7418c0566f, 0x00000b7752b85e4d }}, + {{ 0x00058d3c48fce8ff, 0x00042fcaaa2902bc, 0x00091f695e8ae388, 0x00056a0fd539ad79, 0x00003fdda1024b84 }, { 0x000ceb97675efd50, 0x0001fad5dc64e964, 0x000965554bed5435, 0x000a497a93aafcaa, 0x0000072f2cc19c4d }}, + {{ 0x000fde3ee29e89ec, 0x0005249e32a858e7, 0x000e2eb23ccb4e1e, 0x0002fc8944c32892, 0x0000fdf45fd7d390 }, { 0x0000793aacf7c0a2, 0x0000909caf549579, 0x000e557c9b281bf5, 0x0004340c0bfb028b, 0x0000eff9d16da328 }}, + {{ 0x0009ee5f4330c617, 0x0001779c81710a00, 0x00061dde4e912dce, 0x00009560c557e4a3, 0x00004f997a74131b }, { 0x000606bdf720e7be, 0x0001de9d4292f19b, 0x0005adeaad214a89, 0x00013f62a56f74c2, 0x0000372d1eb10015 }}, + {{ 0x000b1ef85cb235c6, 0x000974d044573ac0, 0x00064a4c13476c7b, 0x000d830f77dc3cf8, 0x0000e93ec667d713 }, { 0x000aaf7c181ff6b2, 0x0004684c96958bee, 0x00034ab98d4b092c, 0x000a94e617c32fa9, 0x00007362c69c64ca }}, + {{ 0x0005faa9c8bd37eb, 0x000f34687032d585, 0x00030831d017617c, 0x000cd0423c54f3d8, 0x00007c6ebecf2b9f }, { 0x000b53e0cd41d986, 0x000c96f89b95355d, 0x0009dbed7bb78cfc, 0x0003534d34860d2e, 0x00008bc6614104c3 }}, + {{ 0x0004603695bcdea6, 0x0001a319feb65939, 0x000fd66cc881fb52, 0x00076b610dd87f30, 0x0000fa4b825b15e2 }, { 0x0002aac5a362f271, 0x000a0c32e83358c6, 0x00048c503bd59590, 0x000c81552508dd9b, 0x0000887ce9e262ca }}, + {{ 0x00078ebe5bca260d, 0x000c5a08b1ea7b31, 0x000396fc5629d03b, 0x000df2299d495ab6, 0x000045eb0b5e28bc }, { 0x0004348796ae1fc6, 0x000f6ca5b36d17fa, 0x000306c3e75354eb, 0x000d923e0b5e4cce, 0x00000bbf054089ba }}, + {{ 0x00055e14b2edfcf1, 0x0003209eef1a7522, 0x000749cc8d3ad05c, 0x000038cd25d7162d, 0x0000d5775e923a21 }, { 0x000c80242e03d505, 0x000db720303b6972, 0x0005c3d6fcd1b6b0, 0x00053e6b6c5d17e2, 0x000040da0a6e404d }}, + {{ 0x00094cc7f33d38db, 0x000ef5fabfae1ca1, 0x000c00d47da85466, 0x0002dc9d2937afaa, 0x000024c1f8bc28e2 }, { 0x000c53b0093312f3, 0x000213a8aa116906, 0x000c9d61edff7a12, 0x0003d930abe40ad8, 0x000054fe955092b4 }}, + {{ 0x000b70ce22f66999, 0x000a85d1356eb809, 0x0002fa0810b5bf08, 0x000261a8bb8bf9da, 0x0000447d5e591368 }, { 0x0008f8655fa050ca, 0x000378a829a81803, 0x00037f266d35dbaf, 0x000ec208384329f9, 0x000095e38ca342be }}, + {{ 0x0009bb9dc9c786dd, 0x000c3d01d3ec517a, 0x0001a76783e4deda, 0x0002248989874465, 0x0000b42617e4c825 }, { 0x00071bb70b07ff38, 0x0000b5578b4c2405, 0x000b09f0f8d10cc6, 0x000394c6b5ed62a3, 0x00006bb834b02c13 }}, + {{ 0x000e530573a2840b, 0x000ae5b2da705d20, 0x0006a34d8a2512d2, 0x00068f0e53ef8ada, 0x000041196132343b }, { 0x0007f458eb02c886, 0x000c75521a9255d9, 0x00015aff273f5d8c, 0x0007ef27563a32fa, 0x00008ba09cf2c5ca }}, + {{ 0x0008797e91aea7cc, 0x000a480eb6b242d6, 0x0002d2f863b4d485, 0x00089479dd30bd02, 0x0000e4b655e68a0f }, { 0x000d53005ec1aeb9, 0x000290a6b4e185ab, 0x000d8586b6a88091, 0x00048c81b82f2c67, 0x0000bb2a23d0098b }}, + }, + { + /* digit=30 (1,2,..,64)*(2^{210})*G */ + {{ 0x0002f4209bf9bcf0, 0x00059be9d8e68fd9, 0x000288102284ec39, 0x000064398db0f053, 0x00004a5dc6b917e7 }, { 0x000420b560d4b030, 0x0007fcc1a739d4b6, 0x000f3e6a037e1521, 0x00016c1d009aea75, 0x00000584c6da5516 }}, + {{ 0x00082b921a859ae8, 0x000619c6254dc41f, 0x00038257ec641913, 0x0006a3ca77e29392, 0x00000c021e167183 }, { 0x000a3d8c1544aca0, 0x000f62e1402cec5e, 0x00070ff1a4d2048f, 0x0000bd9cb9f17ca1, 0x000074174697d3a5 }}, + {{ 0x0006d4822ab85c35, 0x000e0e75e0dee6e5, 0x0002858e08782681, 0x00005869374f2487, 0x00000b357177d3c0 }, { 0x0000031f8adc8033, 0x000e4cfc59826f90, 0x00092404f713d9e3, 0x0001ec585ca26096, 0x00001aca73b07beb }}, + {{ 0x000e0ace9790f135, 0x00011e60ebcf7262, 0x0001342678767f4b, 0x0008aec094482b83, 0x000086d2546132b7 }, { 0x000cf8daedabfb38, 0x00071d31f8d1f420, 0x00014a5069e4864b, 0x00083fb4b1b1e83f, 0x00006eb2e2034cf9 }}, + {{ 0x0003ad49be80c260, 0x0002ea800ee11c1c, 0x0003f23693b6b015, 0x000c9e3c5eb053cd, 0x000021587ac78054 }, { 0x000143e74d589844, 0x0004a41b64279905, 0x000d1f3ac6d14165, 0x00013731e12cf15b, 0x00005b3101abcdc2 }}, + {{ 0x00088690b3b5dbba, 0x000a936c88bdee1c, 0x00058fefe5c87a4a, 0x000975f9625f2930, 0x000004895caebe10 }, { 0x00007be238c00228, 0x000042d852705b44, 0x00040d8d72f4674d, 0x000634dd1b0bf8d4, 0x000089f5af04b2d8 }}, + {{ 0x000bcaced2f7f0f6, 0x0003a49a639fc6b8, 0x0008fa356752166d, 0x000db2046e75c35d, 0x00000c7919830565 }, { 0x000757ac98dd7581, 0x0004e1db55367425, 0x0006c34659f304b9, 0x0000388c5013dd89, 0x00009e9e11e632ad }}, + {{ 0x0004d5ef9bcae914, 0x0000b0d1e935abb5, 0x0003c077f3debaf5, 0x000b3d7b5defd10b, 0x00005a2eed07f66b }, { 0x000687601569519a, 0x000a7ba74f17e266, 0x0008123a7dcee411, 0x000877efdc0a0e3c, 0x000028a9a1af6c1e }}, + {{ 0x0008f0539945768c, 0x000b29cf36658f0c, 0x000ba907b1e581ba, 0x000f3f75ac433ef1, 0x0000e501b89aacd5 }, { 0x000e4ebf5dc2f5a3, 0x000e9dfe983c4a11, 0x0001e568f9d43c43, 0x000c3615bbf5e816, 0x0000c937c01fe8f4 }}, + {{ 0x000792a7ad2ea66a, 0x000c06043a24fe7c, 0x000e3820a17ecaed, 0x00089740529c1191, 0x0000da0679e69c61 }, { 0x000df141eef101e6, 0x000a4d8b737982c6, 0x0009342d1ef43ed6, 0x00081731a7e3a031, 0x0000448cc1825582 }}, + {{ 0x00001f483720d8ad, 0x000f339e6d6f4714, 0x000ed17988f78de8, 0x0001638ac14b2ba0, 0x000005cc7b06291a }, { 0x000e8e9670cc34e3, 0x00054964fd03f663, 0x00099f00a8a162af, 0x000032c183fdb4e4, 0x000086fc98b4855d }}, + {{ 0x0009432af25a44dc, 0x0003c0c207674f17, 0x0006ba6b64e961d4, 0x00069db1e112e09a, 0x0000b97a68266210 }, { 0x00016fbbff8bf955, 0x000008fde2ddec64, 0x000f11e7b94049f2, 0x000e7c08a81392d1, 0x000090f2310497ae }}, + {{ 0x00073c690595d548, 0x000b5fd0d4a9dcf2, 0x00086d11760d0890, 0x000b020667bc29e4, 0x0000e82ab371d3a6 }, { 0x000ed3d505fc5b0f, 0x000d518cdfaa6b88, 0x0002c18df1996da1, 0x0009c4f27606bd82, 0x000024b05bcf9a6e }}, + {{ 0x00060e86489642ef, 0x00039416ab25b6a0, 0x0007250bbedb1912, 0x00086af03c6c0ffc, 0x0000643b4ceb328b }, { 0x0004f435d3812e8a, 0x0006f0f93c7f3988, 0x000afe049b37d0d9, 0x000a26fe39f4a96c, 0x0000c8d9ac21a5b9 }}, + {{ 0x0008aca1dc8cc929, 0x0009c5b8e33787f1, 0x00058d8ba496be3a, 0x0008890f0ef42f97, 0x00009f738f8c1ac3 }, { 0x000f6c9c74fac735, 0x000eba72d4bfe80d, 0x000c25d1d6b75c29, 0x000709516fd823b3, 0x0000df2d17686f7a }}, + {{ 0x000a995e5dfbc6e3, 0x0004fc7904fc3fa4, 0x00057d4a050cf2ac, 0x000caf6aa14a23f4, 0x00009e74b3de65f4 }, { 0x00016c563b4a41b8, 0x00083ecf3a5598a7, 0x0007407e5359d663, 0x000c3283c56534b1, 0x0000a377a93e6974 }}, + {{ 0x000bf3352222107c, 0x000fba41d6178e77, 0x000fecaeca6c05a9, 0x000037a3de4c80c3, 0x0000151b1e5776e8 }, { 0x000829e76053679c, 0x000858e10b365bbb, 0x000357ae0314b797, 0x0004c0d258102180, 0x000045a0e1b22a51 }}, + {{ 0x000867e8fbae98cc, 0x000a9a54d53e5fb8, 0x00024cbf2ee7bd43, 0x0000b62c204a5dc0, 0x00007dace033343b }, { 0x0007f6fd799a066e, 0x000ee6ebec9889bd, 0x0001f350cc14257d, 0x00005bc1254f491f, 0x00000465189040df }}, + {{ 0x000fa37d174d524d, 0x0005f30acde5e173, 0x000028af37c05817, 0x000b76154d0f996d, 0x000078f2cc1b9df8 }, { 0x000a99951b3d4f35, 0x000518434b8fb41f, 0x000ca461cfd62559, 0x000f9acf299a2acb, 0x000083fa11ba4326 }}, + {{ 0x00064110e3d7be93, 0x000db892f3b26e7d, 0x00000446416395d6, 0x000c44aa3f470986, 0x0000d33c4ed3954c }, { 0x0002e3c7706265bd, 0x000d02cfad414e41, 0x00081bec63b3b22c, 0x0001c5ef12b155f5, 0x00004a979c09ab69 }}, + {{ 0x000f6db89c6efc0b, 0x00052e59fff83814, 0x00020c510ff875a0, 0x000517dc41105323, 0x0000b7c05ea42fd6 }, { 0x0007d34d61e350d7, 0x00068d6ca563a441, 0x000541073d5751ad, 0x0002419a17f5c221, 0x00006c4fc28b0bb1 }}, + {{ 0x0004b95e3dbdc078, 0x000c1101c474019d, 0x0009007390bdd0dc, 0x000a1b42bcaff262, 0x000042e2d657f503 }, { 0x00021d322b01c90c, 0x0009a1f1594438c2, 0x0005e28dacb4f9f3, 0x000183d401eb6e6a, 0x0000c764dc01c967 }}, + {{ 0x000629a6c01aa769, 0x00040f6b7cb179a6, 0x000d5169a70cd2e7, 0x00061af0ddc7b764, 0x00009db12efb8043 }, { 0x0007d3a142e389a6, 0x000b84e9f5a915e1, 0x00074a30a2dbdc3b, 0x00082b953b1db9d3, 0x0000f4c3e36d8caf }}, + {{ 0x000e709afd4ebe8c, 0x000b8ea308780f21, 0x000119d55ae78e9a, 0x000664ba3dc8de76, 0x00001b9c38ab8027 }, { 0x000526074ae5ec7c, 0x000c776021704560, 0x000ac3d34419af49, 0x000944e68bf204b3, 0x0000bf2f1a243170 }}, + {{ 0x000f57691dba40a3, 0x0002bf8ecd92af61, 0x000a4d7a0b3cdb98, 0x000e520e4e6b9fa7, 0x0000cbd83da71fe8 }, { 0x000c2134f4315826, 0x000cdfe9d2e1a33d, 0x000ecfe50841b739, 0x000bb7d27d430093, 0x00008342dc8c1e23 }}, + {{ 0x000a626f3a19601b, 0x000e32c5c2102869, 0x000d8248f65290f1, 0x000d557923f68aae, 0x000026d9214bd1df }, { 0x00023bbc1636c361, 0x000daf3199d78e38, 0x0006ef80072fc767, 0x000961f2cb7a2af7, 0x000031f1a12763e7 }}, + {{ 0x00049f321e4bf811, 0x00028f299d0a4221, 0x0005dfb794dd3969, 0x000277ad69ac3df6, 0x0000a5e53844a824 }, { 0x000d0299708cd13b, 0x000bc14721b7ebaf, 0x000734a097ba251b, 0x000f39a81e17df09, 0x0000236afe787c48 }}, + {{ 0x000a45755beb5e5a, 0x0004c3e7882f14f1, 0x0004ed815580f741, 0x0002464d0c9f6dc3, 0x000088180b1213cd }, { 0x000ca2ca9f747a28, 0x00054277c4608cf7, 0x0001d9dd48232ab2, 0x000f8730e7ccbdf3, 0x00005ef4880c3dec }}, + {{ 0x000a91f32af5551d, 0x000cfb16f640f620, 0x000b2f63261c003a, 0x000339244e274b92, 0x0000106a1125d96d }, { 0x000ec1cc3386a669, 0x000be4bd6aaba315, 0x000fb0a6b8c5bd06, 0x00052b520719a163, 0x0000859041c6c354 }}, + {{ 0x0008724aa3301862, 0x0007c963b54a0599, 0x0005574ab31008dc, 0x000a32ba60e0015e, 0x00004faf233b361d }, { 0x000a0642cb6dca07, 0x000815bfdb6558ef, 0x0009cd8357cac326, 0x00063ba12f9f7a28, 0x00002446724efd19 }}, + {{ 0x0007e5eeb46274cc, 0x0009d81e7dfc8d6c, 0x000f57cfca95b2b4, 0x00069313767cd444, 0x00007aa955fa3cac }, { 0x0002cf71b93c6df1, 0x0009d3d81d950286, 0x00020de171a3c63e, 0x0001a2ee30088f17, 0x000063c5a29ef2a5 }}, + {{ 0x0006539c7de5db9b, 0x00043a7e0f222c2d, 0x000b9c92b4c46a68, 0x0003b3230309d42a, 0x000069a4869c5fac }, { 0x000331fb46a1f47e, 0x000277c432ac7d72, 0x00000f4ddec961d1, 0x000121ade72692cf, 0x0000f86aeb4b1886 }}, + {{ 0x0005cc064fc464c6, 0x00034322867e6332, 0x0001e4d0c1c60ee7, 0x000f969a578709a8, 0x00000556972914c2 }, { 0x0008ecec23a18976, 0x0009f1c493a65c5a, 0x0000aa2b3840fd26, 0x000bca2e25fb5d94, 0x0000d962837b0d4e }}, + {{ 0x0003895ce010bd56, 0x000728bb96209bd8, 0x000b30586d00bcad, 0x000d038ac65fa8cd, 0x00004331b11c1539 }, { 0x000e7f5c64f975b7, 0x0001359b56cd3d1b, 0x000b1c7425cdaf38, 0x00092539f10c8350, 0x00009e660c7a4eab }}, + {{ 0x000780dd3a8a4d1b, 0x000253997403a113, 0x0006da9ab974a228, 0x0004b23c294626cf, 0x00003195ea2589e0 }, { 0x0004c61ed6713b28, 0x000e6462baf8e3b1, 0x000d3d0c7ad8714e, 0x0003efc08abe68aa, 0x000057bcb3c222f3 }}, + {{ 0x000a3f84425ebffe, 0x0004614c53352e78, 0x000b88f8502c29f3, 0x0009f2dc85a34889, 0x00007c35ac8f1e9a }, { 0x000c80f9252c564d, 0x00051975224da68d, 0x0007e76a07c43bb7, 0x00015767560cd6e8, 0x0000e6884afd696e }}, + {{ 0x000dbc7e7af4947a, 0x000ba156ac774075, 0x000ec785880677b6, 0x000732a58a1e5ea8, 0x000073eaf3f59951 }, { 0x0004bc8be8ae5699, 0x000ec1b31590a478, 0x00099131e20fb613, 0x0005da6c0039e85b, 0x0000ecfb39af4929 }}, + {{ 0x00021c3831e88d1f, 0x0000a36f20df03ab, 0x0001d3ec9c404310, 0x000bc012a2405438, 0x0000e8ad27a0d2a8 }, { 0x0002abde10a71547, 0x000e959d6fdee104, 0x0003359cb06136c3, 0x000e7b4259da47ad, 0x000064fe3586ecf9 }}, + {{ 0x0008660001e36d74, 0x000a1fc17eab9fe8, 0x00044b810970315e, 0x000c49d2cd6e863e, 0x0000d984aeea5a80 }, { 0x000086431bc9586b, 0x000ac5a2c088eaef, 0x000d91aa75b86dd0, 0x00006d87913afbca, 0x00002d1d48a935c8 }}, + {{ 0x00092167c2a88bb1, 0x0006855c298b9743, 0x0000bf4fb6418eba, 0x0000aec18905fb5f, 0x000010e7e5087856 }, { 0x0000016589c91554, 0x000b92d28c511da9, 0x000c2668c0a43364, 0x0004ea9f0f127c7d, 0x0000d032d8aa0c34 }}, + {{ 0x0008dd39e5a927e3, 0x000c43c11aa600d6, 0x000d36d8716ccbaa, 0x0008f1d682f5379b, 0x00008d24e8fcbed6 }, { 0x0005ff84acc088eb, 0x000e4572ecaa9c3c, 0x000b2224fdbef927, 0x000a8b8c4ba0e103, 0x00004e5b4b7fde85 }}, + {{ 0x000b9042d1372832, 0x0008c22ac95aff87, 0x000b3a142a37f646, 0x000c61d8d1c9bb6d, 0x0000bffd2852091c }, { 0x0000111675a26c12, 0x000de80830cf6bdb, 0x0009beb790506d1b, 0x000c2efaa4861d19, 0x00004ac5fbd62b7d }}, + {{ 0x000f2bed06be1b4e, 0x00088cf1afb20d91, 0x0000213b2ebeaee5, 0x0006a9c9b1369500, 0x0000b3302a11d566 }, { 0x00088a52e02d7437, 0x0004b176d799e206, 0x0006c9e76ffe5798, 0x000db221093415f3, 0x0000011fe4eb093e }}, + {{ 0x000ea4725092fb05, 0x00056a3e2a9a6db4, 0x000d0a54b43a9d4e, 0x000b5eb4f4601303, 0x0000be0291a05ceb }, { 0x000e240a57294dcf, 0x000b898d33fd3e7b, 0x00092d1f2cb16361, 0x000af81ad1ccd8a8, 0x0000360a29a8915e }}, + {{ 0x000acada29bfbe26, 0x000d798ca0e7ebd0, 0x000adc7d87452c91, 0x000bd8499f586783, 0x0000c65aa3596607 }, { 0x0004fd5e3650c743, 0x000937d0fe723ac6, 0x0004d4c60de7e613, 0x00084a7411d8e53a, 0x000016d0a718f6ce }}, + {{ 0x000d2fe3065bcddd, 0x000429057908805e, 0x000c71a49dd73b22, 0x0002f50d0b5b9ea3, 0x00002ca50a57bbe3 }, { 0x00041b9241ca1156, 0x00092926e9197e27, 0x00093734981b7b64, 0x0000dcb3f11719c0, 0x0000987c423fab1e }}, + {{ 0x0001f06bcf00e99c, 0x000df6849a5f4f41, 0x00028dd3efae77c2, 0x0000c5755f91d70a, 0x0000a828a98575b0 }, { 0x000341205886affa, 0x000d85d038d05e1c, 0x0004f78afcf954d4, 0x000dee60b04838ee, 0x0000776112a82e17 }}, + {{ 0x000a0f5ab82fff45, 0x000741364d9c2f41, 0x000386014e477e81, 0x0003658417468bac, 0x000084f5c1ea7f07 }, { 0x000549d8e1b91689, 0x000242f659d0ce0a, 0x000ac23bf70fc30f, 0x0000b09c74011bcb, 0x0000c926584930c5 }}, + {{ 0x00079ff428e80f59, 0x0002fd8c85438b17, 0x000d4485d6fe9846, 0x0003ca4f45680332, 0x00008f4d41216d32 }, { 0x0001d426d9f3da01, 0x000e898f059987ad, 0x0001fa94470d97e4, 0x00062fcb2f6ce8cf, 0x0000101ab31670a1 }}, + {{ 0x000bd0c9b88b7971, 0x000803fc781a2419, 0x000e3b8298f02847, 0x0002fa0843e89360, 0x0000acbc78ffab3d }, { 0x0000be4b4b26462d, 0x00020538a912a4b1, 0x0008ac36cdb271a8, 0x00021b4e0de5e15f, 0x0000a17f8d3dad9e }}, + {{ 0x000be980de325ae2, 0x00032f2668621c9c, 0x0000dfb311e3a6b1, 0x00079993cd5518f5, 0x000052f4db6222a4 }, { 0x000f159768ae1fb0, 0x0008f10ddd83683c, 0x000ccab52fd3a1ed, 0x0006425503b6cb35, 0x0000ef327d2522b2 }}, + {{ 0x0006283e8437a770, 0x0005f5343ad73b3b, 0x000f98db1c104d18, 0x000473c691b528c1, 0x0000c3c4141f72fc }, { 0x0003347161a895a5, 0x00024590a5f25b1e, 0x000475107cc11b68, 0x000483fdeefaf8aa, 0x000020a387cf4433 }}, + {{ 0x000de20ec9734397, 0x000ab198d9ea9f87, 0x000b761a0bec4dd4, 0x000ae95da090de5d, 0x00005d35adbfe798 }, { 0x000182de8a62cc1b, 0x0003d8eecdaecabd, 0x000cb6b148b91280, 0x000dd1dec6ca4b0e, 0x0000550839c85391 }}, + {{ 0x000cd9daab10e14f, 0x000763ec8a4186a5, 0x000b3793b388c571, 0x00056173cb3e878d, 0x000035bc8bc8154e }, { 0x0009c5d26f779d48, 0x000d17f586d5e720, 0x0008ba7df7ea2a57, 0x000c7dc2447500be, 0x0000ece6c6ab436a }}, + {{ 0x000636393a1d534b, 0x0005c9aa74d3f7b3, 0x000d99286b1f5422, 0x0007e296d0428fd8, 0x0000b23839cb4288 }, { 0x0008021fc06fa7bf, 0x0003a5510350bf49, 0x0008c8a8c7c25f86, 0x000c0c909b381743, 0x0000c67eee6023ce }}, + {{ 0x000caffa79164dbb, 0x000ec0c0e367a98a, 0x000462b2bd497a28, 0x000b04843bea1bc1, 0x0000c78fe367131a }, { 0x000b512e742ec763, 0x0003664457bf9c43, 0x000ad1dd7f0fc57f, 0x000ff90eb0db6407, 0x0000e05c4ba13983 }}, + {{ 0x0007f983c7b84b15, 0x000f91ffce104080, 0x00035264a1b62bef, 0x00017d0b389ddc00, 0x00002960ff9e4a4b }, { 0x000967d1accb38ae, 0x0009f155d5231e7b, 0x000c51e7c366f7b0, 0x0009802b5cff22ae, 0x000081c1f665309f }}, + {{ 0x0007012c7d47081d, 0x0004ec6cf777b6c0, 0x000d456becdc46a4, 0x000edaf850062bdb, 0x0000cc93e16237c7 }, { 0x00095cb26b4e0be4, 0x0001562ac47800d1, 0x000ba7a63b09f80c, 0x000ace5d353365f2, 0x000034e8d2215ffc }}, + {{ 0x000f81609ee40822, 0x0004c2905f2c4ce9, 0x000af8d535cd568a, 0x0004a4e15bd2bdec, 0x0000cfa19d6c9ba1 }, { 0x000241b6f9fad805, 0x000662cda350002f, 0x000007d9c63cdde1, 0x0004574bcbd05469, 0x000047e52739fbec }}, + {{ 0x0005ce69cde21889, 0x000fd432fe3cd4c0, 0x000baeedf96e9a6a, 0x000fb161fe0f33ac, 0x00001790f40c1e5a }, { 0x000b8e29796a6e6a, 0x000b116f5f98aaf9, 0x0005d395b776372e, 0x0005f93d345bb71d, 0x0000430258e053dc }}, + {{ 0x000fb4879b3fe9bf, 0x000f346ae0a6828c, 0x0003a0c44e0f5c7f, 0x000cb3cdbba533d2, 0x0000f6ea637a253b }, { 0x000dbf6a4042ef68, 0x0006b0b3281705b5, 0x000be2907641494e, 0x00070e6df7e361c6, 0x0000876051625bfc }}, + {{ 0x0000e78507af85ef, 0x0008d234b54d9bf9, 0x0000a42a3ed21495, 0x0002cc8581374e68, 0x00009d3702290f12 }, { 0x0000946dbd4e2626, 0x000d38d5d86f1749, 0x0002f55502275d25, 0x0009fad44d74e0bd, 0x000004488f9be27c }}, + {{ 0x000f710571dd1d02, 0x0002158fe1a838c8, 0x0004d299c4671897, 0x000b1580b05aae6c, 0x0000e3dbc53866c4 }, { 0x00091241f3b00662, 0x0007b48182caaac9, 0x00096af503dbdd89, 0x000b2dc6d8c4aeef, 0x0000048abae31743 }}, + {{ 0x000ffdfc7e7c2a09, 0x00085eae457a4773, 0x000bae6fdf8723eb, 0x0009a0d71d19857d, 0x0000d6ef525ea59c }, { 0x000d15002a515a26, 0x0002c5426ee7cda3, 0x0009a1edc37de8e0, 0x000e199c8341b086, 0x0000bbb468e51820 }}, + }, + { + /* digit=31 (1,2,..,64)*(2^{217})*G */ + {{ 0x000f6927b0d79bd1, 0x000614c85edfa308, 0x0003f86bcc29875b, 0x000193b862597655, 0x00001c7d62051005 }, { 0x000d0721ecd294e3, 0x000feba55f2f94c5, 0x0008d744240dfdf9, 0x00015625d6a996f9, 0x0000e456c18ca0d6 }}, + {{ 0x0004cae01e64c20e, 0x0009b2079e5fb67e, 0x000a8bdf924006e5, 0x00033ca37e1331fe, 0x00003ed077fad719 }, { 0x000c957822ca746f, 0x000cfe60412a77db, 0x000c22af18030eaf, 0x0007aeb3106ff7ca, 0x0000cacc54eeaa59 }}, + {{ 0x0007e0aa7adc7a48, 0x000db0cb0ce1c552, 0x0004e3df0b8cb07c, 0x0009bee3b5b534d0, 0x0000fda2b88e9831 }, { 0x000f7d9eeff2ac2e, 0x0007e2d79362c410, 0x0000823dcdc0db71, 0x00077b12467920c9, 0x00001801931c732f }}, + {{ 0x000f5fa5904e2bd3, 0x000209afa8338349, 0x000206d2dfd21b18, 0x0004529102295172, 0x0000fd30a26b44f3 }, { 0x000137b286ed0846, 0x0004125e77d9a3b0, 0x000a624d3959c964, 0x0003d9c4a11235ce, 0x000037f27954916b }}, + {{ 0x0000d262f88de12c, 0x000b5ce44ace1509, 0x0008b2af868437a8, 0x000e478b8e0f8d3d, 0x0000f156f86418d4 }, { 0x000dbdf5922834ef, 0x00065c9283e13c98, 0x0007211e7af3d393, 0x000a7cfcb2d04fde, 0x0000f09ff470d31f }}, + {{ 0x00073c8530e34004, 0x00002950de1e5786, 0x000782baa695ecd5, 0x000f9e8a52e1463e, 0x0000607baa031037 }, { 0x000c1d160b022745, 0x0006100747f91da5, 0x00016dae62deceaf, 0x0008e89f5b08d43e, 0x0000e0b5caf53925 }}, + {{ 0x0004669f46350981, 0x0002d5328c8e13bb, 0x0003fe873d8bc483, 0x000c485ad375f10c, 0x000035558e6d3927 }, { 0x0009293790f894ed, 0x0000cd05bbd8699b, 0x00092e6e3582dcff, 0x000e93bd35528a4c, 0x000007788f960423 }}, + {{ 0x00061bbb05f9956d, 0x000106ac42bd6d29, 0x00082503dba8e1c1, 0x000ae458e6df8646, 0x00004572780d144e }, { 0x00004d881133b185, 0x00070f070a6a26b8, 0x000cb240e6288319, 0x000ae43d370686c0, 0x0000da343e03be55 }}, + {{ 0x0008584ef74bf3d5, 0x000b27b207f16700, 0x00084609039a722e, 0x000afedbf9b0dd18, 0x0000dfa5f66ee54b }, { 0x000c334771dc5db5, 0x000dba5dcd898ffc, 0x000f5425a6cc0213, 0x00029fcc126286c3, 0x0000264ddb1fa583 }}, + {{ 0x000725af16318964, 0x00085542f770fb1d, 0x000f75b1a448a814, 0x000806afc97c1c61, 0x00000e2e1a79320d }, { 0x000e079d3c015b41, 0x000914fc01e20ecf, 0x00039cdf74e30b3a, 0x0001c76ecdfd3749, 0x0000e980c17f36eb }}, + {{ 0x0000d6a5c42da56f, 0x000780a2e6ac8d23, 0x0002df97b64102c1, 0x000402c8c9c6b5a4, 0x0000724fa29031c0 }, { 0x000d131ab892404e, 0x0002e224fc0a9ef0, 0x000388ae52355bac, 0x0009dc1de190ff08, 0x0000ec43401fd702 }}, + {{ 0x000eec726a98db71, 0x0006f7e857012919, 0x00087a53ef3da9d1, 0x00019338594793ed, 0x0000b72ad73d6c3f }, { 0x00032b2c8ec764fc, 0x000be590c9d8005a, 0x00077b4e8d42c947, 0x000eb6e1e5feca45, 0x000035b3f8239855 }}, + {{ 0x0006c04225a0b97d, 0x000447373dd0b4ea, 0x00039de012a075b8, 0x000d1d6f137a2821, 0x0000c37b6f44f5ad }, { 0x000f54feb8e2353a, 0x0001134cf671e3ce, 0x0001de54badb3643, 0x00075fe4881bbecd, 0x0000e52b6354c0d0 }}, + {{ 0x0003469898a0538f, 0x000eda7fb8088fa5, 0x0006fa95fe2d2ec5, 0x00023e2760142724, 0x0000b5efdf4b7190 }, { 0x000e706aca43c3d6, 0x00061b83a2aaac68, 0x0002cc8322d12925, 0x000fb5299e9f91dc, 0x0000dfdaec18b984 }}, + {{ 0x00093ea6c3ee3c56, 0x0001e95f688dc983, 0x0006d90da43852a0, 0x000dc215c26490cd, 0x00000e9b4f9bc030 }, { 0x00059cacd2538ba3, 0x00090437f338e0d8, 0x000adab73ae2ca93, 0x0001271d539fb832, 0x0000b214d5f9080e }}, + {{ 0x0001567f755e516f, 0x0002de74462007dd, 0x00047b5f76420568, 0x0000d6ee7b8ab48a, 0x00004f2bc1635d97 }, { 0x000931de26c2af42, 0x000d96b0887bcec5, 0x000e8847159b8388, 0x000b324cb694497c, 0x000039c7e289bc5b }}, + {{ 0x000bd0a121216b32, 0x000ad7c0e58d4939, 0x000fbce69df1668d, 0x00035914db1ae5ec, 0x0000c149038863bd }, { 0x0007f13e98b5b5ed, 0x0009bb7cc863c683, 0x000e052e0eccfa57, 0x000f268933a1cc11, 0x00008167fd8f4e54 }}, + {{ 0x000ee1b6170663fd, 0x0008967bc947badd, 0x000d4b5538170a6f, 0x00013ffac738e07c, 0x000023f0b6b7b6bf }, { 0x0007cdc47eb25821, 0x0003d672e793d12f, 0x000de923c25b844a, 0x0008859f7d6aa6ca, 0x00005201d76c5ace }}, + {{ 0x000236ac0915006e, 0x000ff9dab15247f0, 0x00004703a77613ae, 0x000a2c6e77c789c1, 0x0000808d9373070e }, { 0x00042da81b066709, 0x000b4251d7a51446, 0x000a8d111cd1a17e, 0x00089a2ca098b9c2, 0x000013d8733bafcd }}, + {{ 0x0005441757848811, 0x0004b054f7269b13, 0x0007ad43ac2df8a6, 0x0001c5e21fcf3077, 0x00008d6031c1f86e }, { 0x000728edac03ee8f, 0x000e999fd703431a, 0x00056fb46aceed43, 0x000d9a62da438d7a, 0x0000f9c288edabe5 }}, + {{ 0x000356c23a712a04, 0x00086bc42531689f, 0x00070db2a1b53dad, 0x000edd5b30a51a0e, 0x0000c4d54a3bd065 }, { 0x00050964756fe418, 0x00027ff8d3a3dace, 0x0009588ae4a9b9ac, 0x000663ea4409597f, 0x0000d6d7b2598a4f }}, + {{ 0x0001c02c179a9537, 0x0001a265c3427b0b, 0x000c20c29da60ee6, 0x0009725456401405, 0x0000041eff03bf87 }, { 0x000a43463e984012, 0x000db75d9635bc92, 0x000743e10ef12662, 0x000b1be66226790c, 0x00006caa30be64cd }}, + {{ 0x0009f2f368831642, 0x000033adb4837611, 0x00054be273c309ad, 0x00028ba87e7cc608, 0x00001790a225635b }, { 0x000590dd601ac1f6, 0x0004d175c0b800bd, 0x0008b5dcc9827fed, 0x0008cd15e1f1e7c8, 0x000021b22c5fb59e }}, + {{ 0x000b15d6243f1091, 0x0000ca11f17a34c7, 0x0008a8443e31d5d4, 0x0003fa53b5420ab3, 0x0000927b5e2d1cf0 }, { 0x000424051138a243, 0x000fdb1e274e49c4, 0x0004528d80f9684c, 0x0000da2a45cf5074, 0x0000abcad67dae2e }}, + {{ 0x000248c0344ff4d0, 0x000734311b2d595d, 0x00091c801f234930, 0x0007f0d05f136749, 0x00005dba5d3c2cee }, { 0x000e8c07a9b72e10, 0x0003f13a77739f5e, 0x000a3546a79917e7, 0x000b691cfbf4288c, 0x00009c7306d20c7b }}, + {{ 0x00089e1462801321, 0x00028996fe8393f2, 0x000fc08125d060fa, 0x0001c42c80f809a3, 0x00009fb87e79ba00 }, { 0x0001826047e09dee, 0x000287e9889feea9, 0x00024f16d8c20c68, 0x000b29cc6d5c9c0e, 0x0000ca96182e9075 }}, + {{ 0x000a074b4cbdc635, 0x000527a9a4a27515, 0x000270dfb3609166, 0x000e3e44171bd007, 0x0000f49c9e777f48 }, { 0x000fb0efe038c226, 0x0003334c1cec8edc, 0x000ddb0b13dd9e14, 0x000c85e15a6ecb49, 0x0000c013efc7e2a5 }}, + {{ 0x0003ceb3f5d13058, 0x000edee23ab3495c, 0x000747a89247407e, 0x0002caef4a132df8, 0x00002b96856566b0 }, { 0x000c0899c9fa2622, 0x000071de88fb1da6, 0x0003b19887afb52c, 0x000d8d520ea05797, 0x00000f3ef4a9c2d8 }}, + {{ 0x000f5d86d67ee298, 0x000dd04752ddad71, 0x000f824903c11932, 0x000766399d60bd74, 0x0000bacfccb4d377 }, { 0x000571960bc9fc41, 0x0007b424b5a6d88f, 0x0002254d6471eea8, 0x000cd841069eb2c3, 0x00004e6a49e4dc49 }}, + {{ 0x0009b988353bd1dd, 0x0001ecf704e23c66, 0x0001bef11e2642bb, 0x0008c5f83c71b7d2, 0x000034725a0787e8 }, { 0x000a08f0037397b3, 0x00074a3963bfeec0, 0x000ad474b7c8163a, 0x000d0f6b199947aa, 0x00006b872dacd87a }}, + {{ 0x000ed489e3948b33, 0x0000d9478ef24870, 0x0004f3fb6243555f, 0x00051c028c8d2d41, 0x00001b4ae6438b23 }, { 0x000b9784bc1dfe6e, 0x0002a6bbef3366e9, 0x0000524658fc7d96, 0x000df6de20de59c7, 0x0000fc82425dd0cc }}, + {{ 0x00084e81ad96c3d5, 0x00080021a93507a4, 0x000744ed85217d67, 0x000286a40b4cd118, 0x0000702de63abcfb }, { 0x00077e27e30a727b, 0x0000cb5272e9d6ec, 0x0004ff812967789d, 0x000a6af8eea1c93e, 0x00003caac07df9b9 }}, + {{ 0x000fcc837acc3f62, 0x0004936d2b713c5b, 0x00000fae8958d09c, 0x00070206b86274ea, 0x00001d84b95f783d }, { 0x000f1a38bcdc1a88, 0x000769dd6529b73d, 0x0007848e4745cca3, 0x00002bdb9708aa22, 0x000012697ae997ed }}, + {{ 0x0003317d153dbf41, 0x0005926b8bad853a, 0x000293f26dd1f0cd, 0x0000ae7302d52cea, 0x0000259fdb316c19 }, { 0x0006bc5834b6d375, 0x000edfefd4ddedab, 0x0009fea120f6e9b2, 0x000f37444ed2a153, 0x000027704cde3608 }}, + {{ 0x0004269d64c13d9e, 0x000b4b383d102b6b, 0x000652201ae42133, 0x00030cf37fe695a4, 0x0000c2b2d20a73d0 }, { 0x000282e5be5c5683, 0x000d3a10a1d22850, 0x0001444f87b4312a, 0x000fdb1a7feef6c5, 0x0000eff77ff509ef }}, + {{ 0x0005aaf78c7288d5, 0x0001c81721c486d5, 0x000066ad8ac27b77, 0x000ce2b31301baf1, 0x0000f49e14841d8d }, { 0x000dd8c0882b51a7, 0x000ec7159c639522, 0x00045de99b26fb30, 0x0009386c33a3bd27, 0x000050ea586ccf8c }}, + {{ 0x0001dbe32c1fbaaa, 0x0008874f5531461d, 0x00008bb9666f009a, 0x000c64fd28b4a128, 0x00008430a73d0dfa }, { 0x000431531ac44d42, 0x000df0d30c34169a, 0x0002d4895218eac4, 0x000ebb054ba74a95, 0x0000755d2f2b53df }}, + {{ 0x00006ae448efaa11, 0x0004d22f669d7ec1, 0x00042514d0cc257f, 0x000f9ecb3ca374f6, 0x0000f169c333b6fa }, { 0x00010a7d3f6b9eaa, 0x000609033c8e9a1f, 0x000180a2db4623fc, 0x0006c4314234645e, 0x000084b79c5ee4b0 }}, + {{ 0x000d8727967cf447, 0x00097ee40d5c9be3, 0x000f7cfdc601ff1d, 0x000e146ddb2bae7f, 0x000039d35690a32d }, { 0x000213071385c0a3, 0x00027818569ff132, 0x000b784d085ec27a, 0x000ae88868b89a5f, 0x00001eb069c3b03a }}, + {{ 0x000098baf9cb4cd3, 0x000b81e48ac28403, 0x0004bc21d97de9e8, 0x0004798431831129, 0x000013750d1196db }, { 0x000ae9e34b83b95b, 0x00066584198da522, 0x000be98219cfe30b, 0x0007d4e08ab4fc17, 0x00008387d9c3f13b }}, + {{ 0x00010ea88587f6e9, 0x000699e3fa11b1f7, 0x0007263c4a2f6c1a, 0x00039903b21e4367, 0x0000789308d6093a }, { 0x000722a5d5edffef, 0x00032fcc5dc67cf9, 0x0006f11db1430e0b, 0x000e4afb708d5164, 0x0000f530330b49e1 }}, + {{ 0x0006370339f57e7c, 0x000d4e2c861baa5c, 0x000ccecea904d470, 0x000fd8a3fc0c21a5, 0x0000fadeb312f995 }, { 0x000ef031de2f466c, 0x0002dc7638167c3f, 0x00057a6d812df399, 0x0003edd89fe6ffe7, 0x0000825bd8675575 }}, + {{ 0x0002fcb419b70685, 0x0001a82d57c667f8, 0x000e490ec2d75faa, 0x0000b05ecc70312c, 0x00004cf30e7acd12 }, { 0x000d8db5533f5c10, 0x000a385ab45d44d1, 0x000243edce4fdb2e, 0x0008c0b52fba0722, 0x000052d22dab8a19 }}, + {{ 0x000dc5e37371a728, 0x00090d4e344a8732, 0x000dd070f1cabef0, 0x000cebf507d8d116, 0x00005db19373e506 }, { 0x00072b8ab82adaeb, 0x00047e6e799eb95b, 0x000eb16e5c349584, 0x000d038d5e9e5f4d, 0x00009e31731daff4 }}, + {{ 0x00089197287c3914, 0x00066e02cecc84ab, 0x0007c349eff41179, 0x0008b5b58600016d, 0x000061064bc7eb5b }, { 0x000c91e7660a8876, 0x00045bddafd60884, 0x00061f4025d3c53e, 0x0003b9a721a74014, 0x0000074a6b09578e }}, + {{ 0x000f2874056008c5, 0x00020ca08819a786, 0x00095a30051c1c8d, 0x000b3077dcf48b72, 0x00004df9fccd5a7e }, { 0x0007e550b59c1a48, 0x00012c226cd44ecc, 0x00060804d4595c21, 0x000eca3c588ae32a, 0x0000363ef9fbc480 }}, + {{ 0x00061b1ca7d7673a, 0x000e2f25c727bd2e, 0x000036ddf9088a43, 0x00035ff202e4badb, 0x0000a50c99cb451f }, { 0x000f2e941699137f, 0x000faccbd6bd51f4, 0x000131175819f7a0, 0x000db8f628024e40, 0x0000d71497878c8c }}, + {{ 0x0009f80d55b0c703, 0x0003dec0ccced589, 0x000b73ac42429524, 0x000510fc625cd4b9, 0x0000a65aaf5a02d6 }, { 0x000f34bb38b3eac6, 0x0007ac9ce6dc1532, 0x0007a93199e8a328, 0x0001c3b4d138d511, 0x0000ca319150839a }}, + {{ 0x000b70ab66820487, 0x000c8d22ae8921e6, 0x000e1dbaf67c7245, 0x000bcf9b2b039288, 0x0000edb438dd0e2f }, { 0x000b5629d34a9d60, 0x0004bc9e70574810, 0x000f912ab26e33fe, 0x0008be6824581dde, 0x0000b84bd043d606 }}, + {{ 0x000fbfb416c23b23, 0x000a49eb06f5b41e, 0x000d5e6480526105, 0x0001f4ea9a42e84c, 0x0000cccc1d701e42 }, { 0x000897f9fd8a78ab, 0x0003f239d33cd6f3, 0x000871d410fa9b73, 0x00055c4969caedb8, 0x000057a5bd2f9d4f }}, + {{ 0x000f306e8d3ef41b, 0x00096f88e5d788e9, 0x000842a42261b628, 0x00064b03c1aec7ba, 0x0000bdc61d3e538d }, { 0x0002865801e16113, 0x000ed6e5040a0acd, 0x000328c1172c7e8b, 0x000896723ca9d504, 0x000064b076c1e6dd }}, + {{ 0x000671c6f1b51569, 0x000c03f6967469a8, 0x00090718c7e7267c, 0x000b208222894d83, 0x00005bb66d861506 }, { 0x000fc913dfbae46d, 0x0008bd6d7de9853b, 0x0005f229a8e82949, 0x000b8e3cf2e3ce34, 0x00006ed57b771cce }}, + {{ 0x000dbe9e4865fdfb, 0x000959fe61f7908e, 0x000eadfddce11bc6, 0x00006b838192e304, 0x0000a93c2ce3f05b }, { 0x000ebd91e9d1f474, 0x00075be2db30660f, 0x000ec22deba43a12, 0x00039956eda3e613, 0x000030ac3120ad60 }}, + {{ 0x0003a058ce6c6132, 0x0009ac4df655a499, 0x000bcb11a94222b2, 0x000f584eaa9e00df, 0x0000155d23f64159 }, { 0x0003455bbbdf94ba, 0x000d64a67bd3448e, 0x000a104fa1a088b1, 0x0008da5524a3d4e1, 0x000055bd521fe9fb }}, + {{ 0x000381dd5350039c, 0x000fc5b4b9ad1ce1, 0x000648361a401b32, 0x000ae0816a981853, 0x00003aa8a7a07cf8 }, { 0x00041e541e27a4b9, 0x00054617a4a76209, 0x0005a59a402eaafe, 0x000f30a3ac841292, 0x000004cfa2d4a052 }}, + {{ 0x00061e15b0193f73, 0x00026e84a34f239b, 0x000c02e5ed252835, 0x000fb353215fdb83, 0x0000611a80a40f29 }, { 0x00053277336c58d7, 0x00082d4a127f89a5, 0x000bb2b59fa73e65, 0x000bfdf925d541e0, 0x000059c1e0662639 }}, + {{ 0x0000309532509fa6, 0x000fafc95f57552b, 0x000fbc7c1b975eb3, 0x0008218013294764, 0x000077c5af065b77 }, { 0x000e03f65c2dc5db, 0x000e2f505c2e54da, 0x000c78e4e6c62bf5, 0x000b84353158f27a, 0x0000694c1d649f0b }}, + {{ 0x0007332f3b061b87, 0x000c7bd9c95f0f98, 0x00019d30d836a35c, 0x00039dac45ed9deb, 0x000018b00ca2bbfd }, { 0x0005cb917ba93167, 0x000079e2b9e0d888, 0x0003d0d4cecd60b0, 0x00027c84852d910f, 0x0000f373e4a9fc00 }}, + {{ 0x000137a6d994065e, 0x000be934c8998d19, 0x0000e1d6feb6644a, 0x000fc3fb02186a3f, 0x00003352e74d4d1d }, { 0x000ca1b89b828df6, 0x0008937748bc82c0, 0x000173a4e6f0ad53, 0x000fb24a287c2e93, 0x000028fafbaf323c }}, + {{ 0x000737d6fb05a03f, 0x00004aa5e1cd3cd7, 0x00082350a52d4bcc, 0x00049e09f8939780, 0x0000f18ec22e9ed8 }, { 0x000429759f59ae9f, 0x000d56a60f1524b3, 0x000585dbb50813e4, 0x000e39fa536985e5, 0x0000b06736fc8393 }}, + {{ 0x000ac8aaf9b029b8, 0x000b6c3092e9f414, 0x0006175cc0c40ea0, 0x00083907d3a238c6, 0x00008d3d8a65f0c0 }, { 0x00090005fc438ce7, 0x0001ab15e4ccab05, 0x000244e145fefc14, 0x000a4a29d9bf430f, 0x0000798b9c3dca21 }}, + {{ 0x0000075aacd2e5f0, 0x000a12f24544cb60, 0x000ad7936836f151, 0x00072b2129987b71, 0x0000b2e6c26f30ed }, { 0x0007813de7e02a59, 0x000f78b6cac83696, 0x00078dce2ea1a080, 0x0009ad9a487842be, 0x0000b0205681558b }}, + {{ 0x00040896be942344, 0x0001dcec3427239e, 0x000fe1609e1ac9a8, 0x000f5d1915f3c7ce, 0x00006570948e3d4e }, { 0x0003d4708d9dd274, 0x000f3910492d25f2, 0x0009c36c11e8ef73, 0x000b536cc8aeb30c, 0x00006263417807f4 }}, + {{ 0x000f9b71b8c0f425, 0x00077f2d0c051995, 0x00029b4c129bcbe6, 0x0007e7c82502fbc2, 0x00002b22165d2734 }, { 0x000b6e3e8373047f, 0x000bb592b82dd077, 0x000519b4c4ab6dee, 0x0004bdb327630273, 0x0000227777e79e51 }}, + }, + { + /* digit=32 (1,2,..,64)*(2^{224})*G */ + {{ 0x000c41114d0d0f0a, 0x00071c035d0b34a2, 0x000b56e6af5ad632, 0x000f458d1440b386, 0x00009070851ee09e }, { 0x0000477abf63470d, 0x000c1f1ad95a0b12, 0x0008478dc8a2c85e, 0x0009d79c9c09b37a, 0x00005669d660129e }}, + {{ 0x000a68df70882277, 0x00065b3292a92874, 0x00062d47b35717e2, 0x000498f05ddc15cf, 0x00002045f41bf3f8 }, { 0x000a8b9343580755, 0x000f94505bf7dd0a, 0x0008e243ec49440b, 0x000aea3afa4e63d3, 0x00000f5462133be9 }}, + {{ 0x0006113c503cd9d4, 0x00061b51e706ad97, 0x00044d98af8ed595, 0x00086b990b99cebb, 0x0000a86e1c215f82 }, { 0x0003cbb144e6b9aa, 0x000e4b097e2b5aa3, 0x000c2fed61bf9a24, 0x000125c6c7e1022c, 0x000044eec8aec086 }}, + {{ 0x0004e7b4f75c69c7, 0x0009d717af715d2e, 0x0003eb2b959f67ad, 0x000b50256e2f7f59, 0x0000faa39a85f847 }, { 0x000657624d4d6888, 0x000779788d5374a6, 0x00031a2adb0e9860, 0x0008607e22b915e6, 0x00009ed17ced0865 }}, + {{ 0x0007e49f538144e9, 0x0000801dace5aca9, 0x000179c203139436, 0x000579d09c4fdbcf, 0x0000b8c43e3ced43 }, { 0x000f036040802177, 0x0007090937e2ad5c, 0x0007636ab7b11bc7, 0x0009a49dc846e250, 0x000015f05617398b }}, + {{ 0x000858e1e42fa26a, 0x00096e07442f1d58, 0x0000de8801c7a755, 0x00023d647475607d, 0x00002129ca073288 }, { 0x0007cdea3e2c120d, 0x000050b8231ee10a, 0x000abbbc34902c47, 0x0009866a41b80e7e, 0x0000ea4fb6751c9a }}, + {{ 0x0005b9d57b4ca325, 0x0009b07f8ae7c38d, 0x000b67ba2c17122d, 0x0004048b36db07a5, 0x0000c13547ebaf13 }, { 0x000fe5a101822457, 0x000dbe78eba20f2f, 0x000e71d40250d287, 0x000744f58ef11ca8, 0x000067b29ced3d7d }}, + {{ 0x000af127793627f3, 0x0008811e51732d26, 0x0007ba47d495211f, 0x00011fbc5dfd6eb2, 0x0000d0277a7c5305 }, { 0x00059aba7caa2e14, 0x000712d06c425aef, 0x000b6687611ec682, 0x00054599c6df92f8, 0x00003f2120a92224 }}, + {{ 0x000eee4194a7b79a, 0x0003ed5da64309d0, 0x000682c4c56fb4d7, 0x000e3be0861a6de5, 0x00003c6f7e87d587 }, { 0x0000847a2186a0fc, 0x0009eab771e4caa3, 0x000d4837a79d473c, 0x0001408f583965df, 0x0000b258cc7ec22d }}, + {{ 0x000c06085b99b726, 0x00006f152bfda056, 0x0008f591b1313934, 0x000ea4c6fe0e4c4e, 0x0000984ae625115e }, { 0x000eea86f0bd9963, 0x00061d74463ba14f, 0x000201459c9b5827, 0x0008df06d9d292f8, 0x00000dd1c0ca9a79 }}, + {{ 0x000c48ec0b853213, 0x00079d366131e2e7, 0x000f04b53a77349f, 0x000e3ef89f31d974, 0x0000a4bfcdc5045e }, { 0x00080a6ebc348716, 0x000fbd8d1989aa7f, 0x0009f3eeb83d4cf9, 0x000be314ab34fa0a, 0x00001217dc8a396d }}, + {{ 0x000f4dca515118cd, 0x0009354afa05dd8e, 0x00010d61474d56e0, 0x0004bee5926dfcf2, 0x00000943d9f591b4 }, { 0x0009b587257c123f, 0x000448a65d306723, 0x0004c3aff7615195, 0x000c356c88b08d53, 0x00005b8eb7fb6fca }}, + {{ 0x0008c318b548154d, 0x000c3593de9abe37, 0x00012418eb094690, 0x000d8818c4043488, 0x0000566a78469087 }, { 0x00030ce97683fa8d, 0x0004216fde24c99d, 0x0004cfb615e6cd11, 0x0009b82b42a77cb7, 0x0000a14d76ffb4a3 }}, + {{ 0x000ac78848467605, 0x0004e931a62cc262, 0x000625f9580ab732, 0x000502ef323c69b9, 0x000090bdd65bcd79 }, { 0x0008b8974d570b21, 0x00057f9187d073d8, 0x00090dc6e92ff16d, 0x000634c8f6c2be91, 0x00009044aaeb8adc }}, + {{ 0x000c764803a21e34, 0x000dd77ff57d0517, 0x00077ef3d15d6733, 0x000b936d42ff3803, 0x00001b21b2a67101 }, { 0x000a30e0b2c6a5f0, 0x000e75f48879bc89, 0x000fbe9d8b0eae8c, 0x000e37c16ea7eacb, 0x00009ff4968601c7 }}, + {{ 0x0006605ecd65db55, 0x000d72e421d3aa42, 0x000cc1ef49735da2, 0x000798f1cf926407, 0x0000115826b66fae }, { 0x000b337ce7ef919a, 0x000a7a6d6a5eabf5, 0x0003c637e9a63491, 0x0006f67021edb84f, 0x0000746c950ad014 }}, + {{ 0x00034288799ea710, 0x0004c77c055dc14a, 0x0004de9614663360, 0x00056bbaf2a0ffa2, 0x0000e0884c9d70d1 }, { 0x000fd61e66f6e09b, 0x000fecf884655fb3, 0x0005f6771fda3095, 0x0003d81b7fa5b5bd, 0x0000cdb900fd5f4d }}, + {{ 0x00059455d0433f8f, 0x00013dccc78cf662, 0x00044a47a9a7232c, 0x0004db768b301817, 0x0000faaaf90a0ad3 }, { 0x0005deb6ca3cd246, 0x0001ec5cde3acec5, 0x0004bdcefbacb8b3, 0x0005df9657714192, 0x000045397101934d }}, + {{ 0x00068f895e9004fd, 0x000b957b1fa70fbf, 0x000ee177b0a26d56, 0x0009b2800fa07f50, 0x00006b90a3ae492c }, { 0x00066663c21efba8, 0x00078605cae2a6aa, 0x00075c20e4801115, 0x000e8d3d301bd721, 0x0000b7b5d77ccf5d }}, + {{ 0x00030d7189e49226, 0x000dfd73272d8383, 0x0009c755243ba1ba, 0x0009db432e22924f, 0x0000ce330e0db587 }, { 0x0000a894fbc9777d, 0x000292cbde1f7140, 0x0004e5228567b078, 0x000a5063235771c9, 0x00004ff8170ebc9a }}, + {{ 0x0002b9e66ddcbd1a, 0x000899b36194d408, 0x0004f4a73f93d7fc, 0x000121558e857a7c, 0x0000f54e23d16472 }, { 0x000c57761e509ec5, 0x000a434e4e8b9dd4, 0x000d57cc01b97144, 0x0009c1f3bd2372c9, 0x00008d5623e3a8bd }}, + {{ 0x000653a576829f13, 0x000ba0a1058a3184, 0x000531b195245a3b, 0x000277ae2369cf3f, 0x000016030f4bd9af }, { 0x0007f95f135e7fcf, 0x0000e5aaa4e5c975, 0x00015fb1dd60b809, 0x000e5f3835be80aa, 0x0000a477556e695d }}, + {{ 0x000d4690afc07e00, 0x00014e24415503b6, 0x0005df748739e313, 0x00060c966c08ff7c, 0x0000127236d69e17 }, { 0x000d769c04659257, 0x0008c2eea74237b0, 0x000ebfe0b48a99dd, 0x00039e9fec436d17, 0x0000486dc5e3dd88 }}, + {{ 0x0001787c9e286fcf, 0x000e7de34eaacda9, 0x00079a28754099d0, 0x000d3bf55d9e116e, 0x00007562dbb12950 }, { 0x00014f95d0e6cf70, 0x000e32bf129ac2fd, 0x000788e74c5ba2af, 0x000d048f3d307b7c, 0x0000f8a713e0a48d }}, + {{ 0x000d063b675b0d68, 0x00068296ae550430, 0x000f37a2427aa344, 0x000d796e28931e98, 0x0000fa3386495eae }, { 0x00040f65cbe226f3, 0x000a5b9ed0e4316a, 0x000a8c5b647a8e82, 0x000b3a4c7e74a736, 0x00005f2b0889266d }}, + {{ 0x000497e5c3ee0d06, 0x000300416df4285e, 0x000aec2d851e2818, 0x000b8c9c3b0c9bab, 0x0000197c784b55e1 }, { 0x000c8f0069e898e6, 0x00085b4164bda960, 0x000994284d372970, 0x0009f40ba1ee4241, 0x0000ca6bcd47d957 }}, + {{ 0x000394f375958bf5, 0x000f481c27253c98, 0x000b0f1e76cff0db, 0x0002bc64605a6aef, 0x0000f0b8234cc107 }, { 0x000753d452dd6652, 0x000759c5f109d0fe, 0x00057438f1b79715, 0x0008a4c68cad88a7, 0x0000fe76d824187b }}, + {{ 0x000c362a70e2529b, 0x000d9a15b0ec6f5e, 0x000366538847e1f8, 0x00084617347989fe, 0x00001b6a7bf51376 }, { 0x000a56149e2522b2, 0x000e6a7b3a8ad418, 0x000ff10dc6b2e1e9, 0x0002983f473a20fb, 0x00006887f8bed5cf }}, + {{ 0x0001f4d76b4d26fa, 0x0007e819ac6e0f4f, 0x000eb21ede824bca, 0x000d9b6fd360fdea, 0x00003d6157db8955 }, { 0x0005570e9aed5fe8, 0x0006909587f76b89, 0x000c8dc0ef1ab00f, 0x00008c8958b4ee08, 0x000053e011751c9f }}, + {{ 0x00043ef52d2d581c, 0x000a76f35d33ae72, 0x00032c7c6567763d, 0x00057cc4b200ea12, 0x00009729e0b08fde }, { 0x0008914cb19c5b91, 0x0003477e23ae233d, 0x000ecbcf853a9cd9, 0x0009ee5a4b93807a, 0x0000427af498005c }}, + {{ 0x0008f30be32aa9eb, 0x00099943fb42622f, 0x000b5715fbf20368, 0x000ec01633b2700a, 0x0000a02527da25ef }, { 0x0004d487b147ea98, 0x00060d269e55f156, 0x0001673e9c38aac8, 0x000fb56f61fead85, 0x00002fdd4c705f91 }}, + {{ 0x000add3db7ec68b8, 0x000b386d23ddc820, 0x000c732406385f9e, 0x000123ac503fd344, 0x0000078adedd4745 }, { 0x000755e7ed4c6729, 0x000153f8260e01bc, 0x00048d4be4a45000, 0x0008bbb33fbeb49e, 0x0000d816465d0546 }}, + {{ 0x00045bbb58e226bb, 0x0009639296077453, 0x00006e136fcfe782, 0x000a03edd0ca0742, 0x00001978f2908e69 }, { 0x0003f5cdb0aae739, 0x0006a8cbe0f27a29, 0x000bd029fda61b77, 0x000fb8e5767c24d7, 0x0000f943175bf6fe }}, + {{ 0x000c4647529cc278, 0x00031d7c5ee30a1e, 0x0004ccc36fd68fe3, 0x0001c8748d159363, 0x00001530c91aa13e }, { 0x0001789e131a19dd, 0x00082f39e49af6a5, 0x000a1dc463a96fbc, 0x000b4fb43f2d6238, 0x0000ead936950af1 }}, + {{ 0x000ce1ad11ac24e3, 0x0001629763231dff, 0x000ceaea30de2a0f, 0x000017aa846df9f7, 0x0000e2b10bbfaf1f }, { 0x0004deb125091869, 0x000a4f6fc6a0a7e8, 0x0007e8c574b783f8, 0x0001c41bedd431b9, 0x00002151fe66860f }}, + {{ 0x000e9dd70df9b33d, 0x000b4693c2a59987, 0x0003faa941ff8de3, 0x000a633149b9247b, 0x0000fbd0cf3f9717 }, { 0x0006a6e285611fca, 0x000aef7cbcd5e64a, 0x0006f52dddad338d, 0x000a258ae0359ac1, 0x000096f58aa22a1b }}, + {{ 0x00073f78f0342793, 0x000723f24cea1a04, 0x0009ec229ba14f6a, 0x000120be9c97bce4, 0x0000c16b99f54401 }, { 0x0001a21357d12b82, 0x000ade0f63d3d0d4, 0x00006e094fa470ab, 0x000ea0183e620b88, 0x0000c42192da71c1 }}, + {{ 0x000a9e41a1d48ae1, 0x00001fac7dcfcabd, 0x000dbaa89e6546d4, 0x000254d07650acfd, 0x0000deba6e56a7dd }, { 0x000c591b9fe8b554, 0x0005327175a54ab2, 0x0000be0471701886, 0x0004842a9ca0cd19, 0x0000e042468b20ad }}, + {{ 0x000a78a81b42cff9, 0x000dbe42bad4d5f9, 0x000064775d802ce4, 0x000422994fa4c359, 0x0000ec1267726fb2 }, { 0x000cc8b1f090da45, 0x000c079a98e84e7f, 0x000f4ccf33c47417, 0x000479ce4fe1242b, 0x00008d7b8bba4b39 }}, + {{ 0x000700ef747f8ab2, 0x000f10292d0487a1, 0x000c124aa28a6283, 0x000e05c8f1442dbe, 0x00008c88040d8a3b }, { 0x0000b08ab557d66b, 0x00094c370f1fc62b, 0x0005b91712159de5, 0x0001fc90d3b31d4b, 0x0000bf8fe20af650 }}, + {{ 0x000b9ed428d2bc49, 0x0000e01ae3400501, 0x00060151f1407234, 0x000255151ba4b301, 0x00005711c0145b29 }, { 0x000bf2831a40ba61, 0x000844eeb4819f5f, 0x000ca2263440d5ac, 0x000281a0b616cdfe, 0x00006655f6b3a3fe }}, + {{ 0x0003e7363ac7c9d0, 0x0001c85e0e60d843, 0x000fe9d0b83e0ebc, 0x000727d6e68037e2, 0x0000a4ef48579238 }, { 0x0009b9aa509df363, 0x000d76108d0756c9, 0x000b95f568fafb67, 0x000401523d727f85, 0x000004ff00a6a67f }}, + {{ 0x0000cb3198286b38, 0x0007904e2b4e075d, 0x000472b1178e49c3, 0x0003e802d4998729, 0x00008d0984c74c1e }, { 0x000afaaaa6c45a17, 0x000f87dd7808c569, 0x000eb6fdeccc2f83, 0x000631aaab5c54d8, 0x00005179697da3e9 }}, + {{ 0x00019ed11ae91fb6, 0x000a82104cf667af, 0x000aab9a64bcab50, 0x000e9707cfc2a811, 0x0000554d8be76583 }, { 0x000d6d34f69204ef, 0x0008d09067b6269c, 0x00028f41c0a35e1d, 0x000eaffbc967b853, 0x0000dbd9f34c4cd6 }}, + {{ 0x0000c8e44f888e23, 0x000b2d36cceb3707, 0x000936c497a9954a, 0x0002857622aeac57, 0x0000b6752a402de8 }, { 0x000c4acd0404bf66, 0x000a35086a34d092, 0x0006bac87c03cd3c, 0x0003e6d15e0fca25, 0x0000b1bac43b987c }}, + {{ 0x0004309c3d5be708, 0x0006d173b5a9ba6e, 0x00052eb47e145ec8, 0x0002e4097b9cbe1f, 0x0000dd504546a602 }, { 0x000270b2a44f2d47, 0x0001105f67f37466, 0x000a40f34f5ba628, 0x0001c535385fc37b, 0x0000ffcc4377268a }}, + {{ 0x000b87878a9289fb, 0x00069f5974ad33b0, 0x0007f2f3a6671d24, 0x00026447304d8597, 0x000094b1402774b8 }, { 0x000a86f6939e30ae, 0x00091015a0617323, 0x000e68a3226dcef5, 0x000e4a218c25430c, 0x0000225b9562aa3c }}, + {{ 0x00074a9e86f273ac, 0x0003768da9f3804c, 0x000dda1996154227, 0x000ef0ea5470f07f, 0x00007a00585a4292 }, { 0x000a3d7f108e6847, 0x000633543471a24c, 0x000deddbc6014539, 0x000748d4d239446b, 0x00003d82eda4eff3 }}, + {{ 0x000052b13e4c4fc6, 0x000ea85fdaf45207, 0x000fd4f729b3d2ed, 0x0005d9642bb6d3e7, 0x00004fd193b24bcd }, { 0x00032412778a49c4, 0x000491b682b90604, 0x0003691032b4873f, 0x000ee41b4a71d388, 0x0000b5eb5db6e3ed }}, + {{ 0x00089111e4596bb4, 0x000456e4901bbed5, 0x00009ba190d798a1, 0x0003e197d6419c71, 0x00002d587b9dd586 }, { 0x00051bb0af6d78db, 0x000bf337b60554e1, 0x0007d8c6d2f4ac07, 0x000c32235ea5f888, 0x00000285ce6252e2 }}, + {{ 0x000dd50e6646b5c5, 0x000ca7443b30ca81, 0x000abbbe371cf9fa, 0x0005b4bade10b5bb, 0x00002c1185fd706e }, { 0x0002c679e115a447, 0x0005654cff2b821f, 0x000c54619d7f138a, 0x000808fe33882555, 0x0000813626061721 }}, + {{ 0x0006e2ff3e3cf7e4, 0x000a4156d2a57687, 0x0001a53b7eef03f6, 0x0005810437f227bd, 0x0000890e9085f693 }, { 0x000ab8ff4c5d4c80, 0x0000d6fa3177ec75, 0x0000c87000a8d96c, 0x0006d958ebf731d5, 0x0000d478202f55ec }}, + {{ 0x0000a38f5769375d, 0x000035635edc56d2, 0x00095df07e21caaa, 0x0004f10cb5a69d34, 0x000046b4e39da99a }, { 0x0002061ea52a1372, 0x0007590fac3a15b2, 0x000e58496fc6d1e0, 0x0002758866ed7ea2, 0x00009cae713eaa92 }}, + {{ 0x0009654db53619a3, 0x0003ce6f546783f8, 0x0009d0a51668ee67, 0x000c4e665d38bc6d, 0x000084a7bd921bf8 }, { 0x0005f504d34681c8, 0x000f79a26e1adee2, 0x0004113d9000faba, 0x000febbfe291f376, 0x000014210635841d }}, + {{ 0x000e987967ce4bc6, 0x000c85ec3a0ee43c, 0x000999001f97950e, 0x0007a775670aaebc, 0x0000679e9d41df8f }, { 0x0004eac8b0e95f7e, 0x000ed195e26310aa, 0x0003933fc3f81098, 0x000d5b1e49e43548, 0x00002169b080d0d8 }}, + {{ 0x000fb265b41cf750, 0x0002512c1ad8cf84, 0x000e4a2e50e3a4c2, 0x000f10df0193b4e9, 0x0000b160e21161e4 }, { 0x0001099ad8ca10c5, 0x000b8cde51e1ae29, 0x000652cf15bd680d, 0x0004f84988e3a8ca, 0x00007fc6eb96d788 }}, + {{ 0x0001c9c40bf7f829, 0x000d01c93aa96b8d, 0x000aae006a072e1f, 0x0003a5e230fc8716, 0x00002dcd3ed4529d }, { 0x000363fc5ef58287, 0x000778642b7c094a, 0x000c71dfc3c2c438, 0x0003c765d1873439, 0x00005e33d9307f67 }}, + {{ 0x000b6c8350158412, 0x000200df862eaacc, 0x00025759c48cda62, 0x000c2c22814419c6, 0x0000de581dff2c38 }, { 0x000c9b41c4227517, 0x0002345d30f917c7, 0x00091bde6e29ed24, 0x000dae963d4c4b04, 0x0000c95bedff5a4d }}, + {{ 0x000bfb7557c62b30, 0x000cc2f2f8ba2c73, 0x000f406c34d0f5d5, 0x0004d39720966eb2, 0x0000f79e276fbe94 }, { 0x00021e887875bdea, 0x00065235a2b96204, 0x00072d90be459d5e, 0x000593923bff3ed2, 0x0000becee3d55908 }}, + {{ 0x00064e33579d3be5, 0x000737a25a416322, 0x00047d0d393b726c, 0x000afd3dbc081412, 0x0000f3a2065b9dbc }, { 0x000961bb956822d9, 0x00083cdc87c51e26, 0x000ae6bca67f4701, 0x00015a9ce16b3015, 0x000099b9f2e2caa2 }}, + {{ 0x000154c9356b909d, 0x000be8deff7a3a0d, 0x0007e08aa9f0cff1, 0x000cfad1fbec3373, 0x0000ce02e948472d }, { 0x00011828d5dd509d, 0x000b36f1cc7a906c, 0x0001ab3de5b9cee2, 0x000ed9c4473bb539, 0x000009806170e848 }}, + {{ 0x00085a892ec2931e, 0x0002de13e4b12ff9, 0x0008952ddd4d7a3d, 0x000ee02cfc3aad9f, 0x000060ef6671c961 }, { 0x000785426e98218f, 0x000231b3bb85fa06, 0x000026771ffb6393, 0x000c11deaf95375e, 0x00008e2bebfcfde6 }}, + {{ 0x00099fe2c7f70e55, 0x000c2c8d8ceb147d, 0x000ddd6a728c6e8c, 0x0005d71349b649ee, 0x0000f688ee12edb5 }, { 0x0003baeb490b7ac9, 0x0001e628d3abba2e, 0x0006c3dccc50256c, 0x0001b7d4d18fee6e, 0x00005a845d13c4bb }}, + {{ 0x000157c30c88e767, 0x0007447f23206d55, 0x000fcbce3e45a30e, 0x000a8919a2f6d341, 0x0000644f481a46b6 }, { 0x000508455987e93f, 0x00086c52d4fb936f, 0x000bf1494782ed2e, 0x0009b3b64ef22f7a, 0x0000e271957d8d37 }}, + }, + { + /* digit=33 (1,2,..,64)*(2^{231})*G */ + {{ 0x000595cd1fa2a781, 0x000d8d8df7304d44, 0x000bb98b416f08ee, 0x000983c60b71bcf1, 0x0000fe06b3f76c34 }, { 0x0009429622589d67, 0x000cb9a4835859dc, 0x000cb478d834436f, 0x000f5234e4a0f0d2, 0x000076555e5f3c86 }}, + {{ 0x0004c9b20d431706, 0x0002e62f23f2d925, 0x000d0bef8e6b4e0a, 0x00055d8206cab71b, 0x0000c95a2a5e55d4 }, { 0x00031469c615f1a7, 0x00031aa9f2ac02f8, 0x00069d5a83ea26e1, 0x00016bd3403f8e61, 0x00007f5ad3cb507d }}, + {{ 0x0006930a553f291e, 0x000c1248f9813540, 0x000c2ef5980445f8, 0x000777b2c587e23e, 0x00005d0484062c98 }, { 0x000c4f3993ac460c, 0x00001ebbe5bbe21a, 0x0004784247eb5cec, 0x000c04560a7ffa5b, 0x00003ce6bf87455c }}, + {{ 0x0008b75007f2d3e8, 0x000b9583ae9c1bde, 0x0007fac5923887d3, 0x000d750b4e0af6d9, 0x0000d1ef5fdad135 }, { 0x0004069ea597b54b, 0x0003bafe02358f2b, 0x0006368b73835819, 0x000671cfc31b8b85, 0x0000fde8d8c56c72 }}, + {{ 0x0002f45c13822eb4, 0x00022e27fa03cb3d, 0x000a3ce92174b004, 0x0009d485ddb938e5, 0x000021b3fc2ab9aa }, { 0x000cc71d2d719fc7, 0x00059b57883e6142, 0x000891b541f8e786, 0x000c81ae35fd27e6, 0x0000dc5876ef7ba3 }}, + {{ 0x00028ad2a84e6c41, 0x0004fcde36d07576, 0x00017717c0d9fc24, 0x000484cdff722d7b, 0x0000ebe7611ea3b6 }, { 0x000c336b09195735, 0x0008ab520226040e, 0x000064d14bbbb3e8, 0x000ac8c886c34ecb, 0x0000b85de43f45af }}, + {{ 0x0001830b48c43912, 0x00050a21e206ee56, 0x00002ac69aea8304, 0x000bda0c3f1e2748, 0x000032ea619c2425 }, { 0x0004c11642e0594c, 0x0001c46e78e815f7, 0x000ed740f1e78774, 0x000d57765fe40139, 0x0000edbe53f588b4 }}, + {{ 0x000dcefcddd2868c, 0x000b79e558df0194, 0x000a5ea22e49ccca, 0x00091ce24230da4b, 0x00002dd640a90582 }, { 0x00072d824d931811, 0x000feb2a47d4c5ab, 0x000efbe07e5114c0, 0x000d6c17355ac9ab, 0x0000fcd91a520be1 }}, + {{ 0x000b1757ee1625e4, 0x00036744513e2cae, 0x00014d0cb33eb84c, 0x00094c0500b41861, 0x0000123028257abf }, { 0x000558a2a835c536, 0x00008283dfac6d55, 0x000df349954d38f7, 0x00030de99b2431e2, 0x0000130b37f17b1d }}, + {{ 0x000b8b3bb657e0d1, 0x0002823cbb13d1b0, 0x0002507060487a33, 0x0003073a998799f4, 0x0000a4673e731318 }, { 0x00071b9484805f36, 0x000b92e3ecebb211, 0x000b1f5665228e4a, 0x0000fe71f17cb6c4, 0x0000fab132e7caf2 }}, + {{ 0x0008f096fe69263f, 0x0006f2d7ef0329c3, 0x000258d3a92be87e, 0x000ae1cbc0850922, 0x00004f94dbc53746 }, { 0x000b4c0dfa96c3eb, 0x000a074a1dec0270, 0x0007447bcec03082, 0x000dc7853e8cf10e, 0x00006175addc465d }}, + {{ 0x000e8ef838c9fbc1, 0x000c452de7e5c194, 0x000973312d33ad9f, 0x000d8b33dfab2860, 0x000073e06257b5e1 }, { 0x000ec0507e35022e, 0x000df264cb1bf3d1, 0x0009551e8ee3b962, 0x000b4deed4c1f9d0, 0x00009cc539a7598a }}, + {{ 0x00038fd905d568c2, 0x0009ac7cde450794, 0x000a0ddaf0def815, 0x000076f5cde173c9, 0x000000e3536d8eec }, { 0x00053add2c142e87, 0x0003e06c7d9630b4, 0x000baf4270493d17, 0x0006bf9e86457a87, 0x0000eaa209f092f9 }}, + {{ 0x00094abebcf27683, 0x0008e09a607419d5, 0x000262210bc3d71d, 0x0004daef3faa71e6, 0x000036cd41505615 }, { 0x000a29a36702adec, 0x000ba91eb78399f1, 0x00052519283d6b50, 0x000ce18f048aafb3, 0x000081d651ae4804 }}, + {{ 0x000568d2e1c64bfe, 0x00042e51c21f2bf8, 0x000c1f9ca80c3bee, 0x0005f092ef99a513, 0x0000b0e4e1a943f6 }, { 0x0007a6dafc4f015a, 0x0003aebd3f69d9f8, 0x000280091fb54144, 0x000e1d6f4181a973, 0x0000bdac310c7a67 }}, + {{ 0x000a55b52ea9cdb8, 0x000fab5ef7d92893, 0x0007df294c2baacf, 0x00036dbb62480d4a, 0x00005fd14d5bdd1a }, { 0x000d5e9d7d31477a, 0x0000715309eadb09, 0x0009f58728a80fa4, 0x00022c35adea7de5, 0x0000ddf8bf0e739b }}, + {{ 0x0004d8163beea5c0, 0x000fef5206d3ffce, 0x000298a8759903f1, 0x000a735ba23d5e03, 0x0000c5541d12d6e3 }, { 0x000219da8243f413, 0x000d6efd3082e8e5, 0x000baf7918ddca19, 0x0009adb0a4fe1246, 0x00009d116a39ce07 }}, + {{ 0x0003fcac89cfa8ee, 0x000b7c1f7ea25aaa, 0x000f57b3d0d5ac4d, 0x0003e9871d165e6b, 0x0000a30effd4d7ba }, { 0x000e263feae7d9d1, 0x0009ed4f0baa8abc, 0x0001149b82faf7d1, 0x000fe87495a4adac, 0x00006b868aef4658 }}, + {{ 0x0005547c4f5be3f1, 0x00012d307032c722, 0x000e53b4ec796f84, 0x0000587f07f40d5c, 0x00006bdd6dfb6e81 }, { 0x0007df465d70f0e6, 0x0009ffd65fb2a9eb, 0x000e66d9d13f40f5, 0x0005f5e42ce69336, 0x0000c86a6ebbc9a1 }}, + {{ 0x00058de498e2b259, 0x000aba3315980cd1, 0x0002e4ae075ed625, 0x000a16c04693bc49, 0x00003b029d23553f }, { 0x000836ce7e2b454a, 0x000abc7cfda83685, 0x000320a048ffe7ec, 0x0007c9a6ed2d7bbb, 0x000066b26f8ebcc8 }}, + {{ 0x0002b52f65c725d1, 0x0007e1994f834cbc, 0x00037fe9a81cbbe2, 0x000bfb143d35653d, 0x000092a9b3930992 }, { 0x000f186cdd7031a0, 0x000821b18f23d962, 0x000c1039e5d77384, 0x000a47402cb05aba, 0x0000c20b19c6ae17 }}, + {{ 0x0005624623a128a9, 0x00043e59a29a5c5b, 0x0006860a3ddf3f1a, 0x000b07d84b19b3c0, 0x000095b53ccaa378 }, { 0x0005a9d0868addaf, 0x000bf653c04fa024, 0x000c4900692381db, 0x000c3b43f83a7176, 0x0000f9656734975f }}, + {{ 0x000b179393f74d6f, 0x000bd1d3dc090bc7, 0x000f2f422dd3e906, 0x0009a8d4d82c996e, 0x00000d602d115417 }, { 0x0007c5dff255af16, 0x0008825f8c5dbfdc, 0x000d576c9b126092, 0x000dee6a84d9d7a1, 0x00005c2588a5a8d3 }}, + {{ 0x000ea886daec0451, 0x000078d04c82bdd5, 0x0004998917222f76, 0x000e744806800553, 0x00005c6be61fdaec }, { 0x000de96ef613e33c, 0x000ce01252a0b4d7, 0x000db80131abd46f, 0x0000659631bffb4f, 0x00007cc0d1f5bbc5 }}, + {{ 0x000fe64809d55519, 0x000140cd77d970c2, 0x0003a358b1c17566, 0x000cc06e903cfb93, 0x0000d055c34cf7b5 }, { 0x0003d31b05a74dde, 0x0007824c2ac98ccf, 0x000f2666232e242f, 0x0001827212a1372b, 0x0000ee7c4caf1682 }}, + {{ 0x00061891a0a38e82, 0x00067df5ece6e7ce, 0x000e299469b4ff0c, 0x00013b1a50603ac8, 0x0000588d5e4bda3a }, { 0x0003b117efd74152, 0x00051d299bf1603d, 0x00091dd30d6b1e14, 0x00058ec021f43afc, 0x000028e06b2d515a }}, + {{ 0x000103fa05977e5a, 0x000801365d1d131c, 0x00070276d6394917, 0x000ae7edd86f1636, 0x0000eb35b19898ae }, { 0x0001ae47f2c3b604, 0x0003f44f4b478f01, 0x0008cf69819a940d, 0x00069bd2ece91edd, 0x0000bdb21f33bd5f }}, + {{ 0x000d53ae910e4572, 0x0005d8d20f8a2425, 0x000d94da6c47cb3e, 0x0007f8cb37aff5b1, 0x00007219eed53f71 }, { 0x000e86515094eea4, 0x000d505ec0418032, 0x0006e5b9f737bc0c, 0x00073e98f85e3c97, 0x00007c74d04d9d17 }}, + {{ 0x000a04ca6726822e, 0x0007ca46a67a6b02, 0x0005885821d9ef2a, 0x00044421ef4cdee2, 0x00003f466bb9f3be }, { 0x0004a874138b9a64, 0x000ec18ef0543fbf, 0x0004dd08640a5f75, 0x0007b6f33f709a4f, 0x0000bdf2825ed29d }}, + {{ 0x0007b80581df3f89, 0x000a6a74d82f4c2b, 0x000fb04cea31d778, 0x00083b95e90725a5, 0x0000bfe40a6fc4ce }, { 0x00087f6f736e6376, 0x000631cdd1fc74cd, 0x000b0f04375170e3, 0x000a155badc1c62c, 0x0000d6efb5c07fab }}, + {{ 0x0007be9ed2271299, 0x00036c1317f4a765, 0x000b3944ccfbdba2, 0x000d491568d2703e, 0x0000e1677466f47e }, { 0x0000d9e943522c82, 0x000c371ef0b17acc, 0x000e183e31f4b70a, 0x00066db0e74b2655, 0x0000795a4aa76537 }}, + {{ 0x0008d2fe5724a2d6, 0x0008a411e84e0e5b, 0x0002f5d04e3bf4c5, 0x000d0d132a5db84d, 0x00001765a592c24b }, { 0x0008b4a422ebc11c, 0x0004336f3eb82fab, 0x000c454ae73559b6, 0x000b3a5108cb20cc, 0x0000bc49662e3c97 }}, + {{ 0x000ed06e285bdac8, 0x000fbea6fe8208b7, 0x0003a99e0ad61a08, 0x000fe721abd74b9e, 0x0000d5e8ed41f37b }, { 0x0003186b23df1bb9, 0x000a1586be8b800c, 0x0001152e70049303, 0x000ccd5d3428299d, 0x000034b1cedc477c }}, + {{ 0x00017aae8c429f29, 0x000039e8977d99b6, 0x0001227a835b6392, 0x0003488d4be94433, 0x0000ff63573b35d6 }, { 0x0001efae75205711, 0x0002ec4282aec3b3, 0x000fc5c949ae1fbe, 0x000ade84cc6063d2, 0x0000bb575870e312 }}, + {{ 0x000184a526e63b6f, 0x000fd6d40a9b97c5, 0x0002fde1bd2fd49f, 0x0004943e314702c6, 0x00006773701eca6b }, { 0x00059cd28024561a, 0x0003937003c32ea4, 0x000cdabca247db9a, 0x000b7bd1a5aa374d, 0x00006c792f7fd426 }}, + {{ 0x0003e1589a804b9d, 0x000e461459c2b92c, 0x0007b20d365b2696, 0x00064c6102f020fa, 0x0000ca6d9d3092b0 }, { 0x0008466ee83f88e8, 0x0006bfeaa3f451a6, 0x00035a933dc49cd6, 0x0009efd8b3a3c7f2, 0x000087060571aa2b }}, + {{ 0x00013994bea33721, 0x0002cd41fa266138, 0x000b3c8908a4f4fb, 0x000dbb557a2dc6da, 0x0000d41b64ebec33 }, { 0x0000b65bedddf81b, 0x0009c22fd4f75534, 0x000bb2ed0f327ed3, 0x0005d82f55135ff8, 0x00001de1ffe7c18b }}, + {{ 0x000331c0941a20d5, 0x0001da43734e5205, 0x0002cd6a1c26bf6b, 0x0007386355e3abbe, 0x00003e3eb679bfa2 }, { 0x0008f2c0da9416e2, 0x0001c2976b60c80e, 0x000a91db561dbd79, 0x00014b5842285593, 0x000090564385f22a }}, + {{ 0x0005c558090f5634, 0x0003d74c1df065c4, 0x000b19a020f15227, 0x000e520a8afeeb5a, 0x0000ebe08fef2016 }, { 0x000ab226cebd5622, 0x00094c0ecc8c1778, 0x0004ced0c5db8594, 0x000b1cd8e799ea9b, 0x0000fb29019d75f8 }}, + {{ 0x000a741ef1df7c17, 0x0002ae57ea973dc8, 0x000f9614703c94db, 0x0008185f15c00ca6, 0x000063d1e4dbdd66 }, { 0x0003b6c6786317cb, 0x000512f196b4cec3, 0x000395c7df9fe4ad, 0x00099bf2b70d08e4, 0x00008cc26ea5e3b2 }}, + {{ 0x000ef2c5fb93c237, 0x000adf807ac97946, 0x00004b14057e32a0, 0x000171de51eccf05, 0x0000be44bff72854 }, { 0x00006e0b10d8d552, 0x00011d2679784532, 0x0005fcf73fe7d9eb, 0x000e85837a0cf379, 0x0000f1351989d9a5 }}, + {{ 0x000c6469812142a9, 0x000055fd5ecfefc4, 0x0008765b8f7b26db, 0x000ef9c9607084fd, 0x0000b7551edf99c8 }, { 0x000ae28483d757ee, 0x000bd4ed65abfc39, 0x000e78719a43c760, 0x000116212e01cb91, 0x00006fcb78045826 }}, + {{ 0x00091c285c2a4c9a, 0x000b29ea66d80a18, 0x0003ecd9d0b57b14, 0x0006db5c1680a3e4, 0x00001cad3822f1a4 }, { 0x0006f8b13781c29d, 0x000dfeb799ece3c0, 0x00093ae7ccf04903, 0x00021942329b910a, 0x0000f5e1879fd271 }}, + {{ 0x00043be0aaf3f89b, 0x0005ffd385470908, 0x000f01a760b26589, 0x000ea802719ab8b9, 0x0000ed6be57be9d3 }, { 0x00085f39d0ed1528, 0x000c543a6db836ca, 0x000359452235069c, 0x000ac7b772a1330e, 0x00000393cfe1f4a8 }}, + {{ 0x000ad599c449623a, 0x000546d4ae528342, 0x0009494e42ebf43f, 0x000d510ef5a403b3, 0x0000d5d9e1fe46a8 }, { 0x000827cf81a805c4, 0x0006bb9014b3bf81, 0x0004de4580857334, 0x0002e3d027309268, 0x00005f977d08a51c }}, + {{ 0x000b5212970e3e2d, 0x000d8f6f10ff9276, 0x0000b8218d2fb9f7, 0x0008395ccd387145, 0x00005c10024eb9bc }, { 0x0003ea9e97f9fabf, 0x00005f96e3cb4a55, 0x000123a0215f0c0c, 0x000937b45e47d3f4, 0x0000f7e86aadc6c4 }}, + {{ 0x000a9b83894c7656, 0x000ba6e39cbb688c, 0x0002289ce9a8fb03, 0x000435e21532401d, 0x0000c8103121db65 }, { 0x0002767c4b7d6814, 0x000174e2093913eb, 0x0001b74604c733da, 0x0007f9ec7533d2f9, 0x0000110a91af736e }}, + {{ 0x000581cf9346f15c, 0x000a387aedbae9f1, 0x000921063ac18234, 0x0005bb2717daf0eb, 0x000088c3f46a6255 }, { 0x0003d318ac75f3ac, 0x000fc873ac1f4527, 0x00098797d751c8f8, 0x00007e1c3b417fce, 0x0000aca7b2139a79 }}, + {{ 0x000f8a35b721d031, 0x0000f0f728693e5f, 0x000a340ef236c630, 0x0001a6810e87d814, 0x00001fb62f488436 }, { 0x00014052c2a4d35e, 0x000f5d77f200d34a, 0x00076e24ea1e5f64, 0x000cd0579470f1e6, 0x0000eb853f10fab4 }}, + {{ 0x00078fe4024f3dda, 0x00020b526bc27979, 0x00060261836f1c35, 0x000006ed113670d1, 0x000079b7c4f64fcf }, { 0x000768d7e586bd52, 0x000a992d41c5dd45, 0x00077049a5bfcf2f, 0x0008264065ff8e24, 0x00002216a5fc8c7a }}, + {{ 0x000c3672af71c96a, 0x00080a360017a5ff, 0x0003a02e5bec495b, 0x0007474076b18e6e, 0x00009937b8bda59e }, { 0x000c948f1455702e, 0x0007f77d06283a1a, 0x000038410e854096, 0x000d0b9c2542fc65, 0x00006954911b34d4 }}, + {{ 0x000fc87df6be7f7a, 0x0001c82b04465c31, 0x000a44a03f1eaecd, 0x000b2137ee3d062f, 0x00008c43ce25b5a0 }, { 0x000f663391d373da, 0x0006ca80591f6528, 0x0006c92fee18905d, 0x000bd5a8ca861b8f, 0x00006b9e0397c8fa }}, + {{ 0x000aab4e6a3238d0, 0x000a8acb591ffa38, 0x0004c2349d649d6e, 0x00015d6b3027ca9c, 0x0000be661b873b12 }, { 0x00068aae83dc529a, 0x000564fb474d6b85, 0x0003add089d147e5, 0x000f552aa6597ffd, 0x00008040d2d5caed }}, + {{ 0x00043d8baa45a8fd, 0x0007164c73b23834, 0x00078d3ffbb7c8ed, 0x000f760ab49eb344, 0x0000e0df7be97747 }, { 0x000bf53de2fa0299, 0x000caa5ea7610d6e, 0x0004e2276b961c38, 0x000b80832e47e418, 0x000046bc71e68286 }}, + {{ 0x000de1666fe499b7, 0x00045b4d3c8c1cab, 0x00029f234c99a8a2, 0x0004e1c950d914ef, 0x0000577ca7b4a559 }, { 0x000e9faf6f83c4d3, 0x000f76ed449ab198, 0x000259fa7703581c, 0x00006a7538902b32, 0x00006ea68c6f0f57 }}, + {{ 0x000da8564dcf371f, 0x00016da9a85788bc, 0x000def5dd0869c6e, 0x0003cbd64d21f03a, 0x0000cb0b2e54fa19 }, { 0x0004ee3dffcc2d2b, 0x0004f5cde92c68ca, 0x0000ce43fec47260, 0x00053d47c78e035a, 0x0000a966314f762c }}, + {{ 0x000e2ab3decb0797, 0x0009e07af4e18f85, 0x0004a8483f498d7a, 0x000959a86967ec9b, 0x00007b0ac9fcfa8a }, { 0x000c0c1a5b8ce6b8, 0x000b64d11c226dff, 0x00028b6615b91ec6, 0x000a19f19f9783f4, 0x00001a2b243e738d }}, + {{ 0x0002f2a62f45d86b, 0x0008149571d92ac3, 0x000e139fab5045e2, 0x0007639af569e85f, 0x0000dc961974e55b }, { 0x0006e5ba0c5b997b, 0x000533a06d89b85d, 0x00095911bffc3d29, 0x0005e1aa2b90741a, 0x0000a4a9e49fefa6 }}, + {{ 0x000b842ac7fd440d, 0x000775112e4c9366, 0x000d5187b6b3804a, 0x000e21ec9ae419f7, 0x0000853743dec424 }, { 0x0006ae3fc4509621, 0x000d3e9440d68277, 0x000e78d3bb4fe338, 0x000b99a925f69f4d, 0x00001ccb54d831d2 }}, + {{ 0x000f9a722461f223, 0x000d3c2e9740b335, 0x000ce9c8647cec97, 0x000deea15677bc85, 0x0000f16ec53b5b06 }, { 0x000eb6094dff8468, 0x00051164ad859617, 0x000767a1a1fc7112, 0x000c1b57e5f8c47f, 0x0000305f263682f7 }}, + {{ 0x0008ca06c000315d, 0x000c0fd341905477, 0x00037793ca900aec, 0x000ade7e68a394f4, 0x0000d89206088d97 }, { 0x0001ba76c1885187, 0x000ad626ffeec228, 0x0009b5136239e6b9, 0x000b437479d91bce, 0x0000a4b31a467b18 }}, + {{ 0x000b0c03e9bb6ab5, 0x0006fcb28c682c67, 0x00080b06537181b0, 0x0007bb99827f2522, 0x0000e7f5e678902d }, { 0x000287223f5705ed, 0x000e33015b548e76, 0x000fd62c48b8a6ea, 0x0002b1f40a8be76d, 0x00002b41597b0af8 }}, + {{ 0x000fcf45b93bfe6a, 0x000f6558b399320d, 0x0005e04f008d2b8f, 0x00027b05e61fe3fa, 0x00000320b1aab1c7 }, { 0x000c421d977c1dfe, 0x0009c512f684b432, 0x00049adfeccf138d, 0x00091a78ff796c65, 0x0000756d6c50e779 }}, + {{ 0x000dc9d1ec6f170f, 0x000bea3af2ebc2fd, 0x000ced852c3855dd, 0x000b601b1a0af843, 0x0000efe50594d52d }, { 0x000740f316de5b77, 0x00051bb62771deb1, 0x000a7a84b76a9d83, 0x000c81aae829277a, 0x0000e1420c11bfa4 }}, + }, + { + /* digit=34 (1,2,..,64)*(2^{238})*G */ + {{ 0x000fcf57c64d0fe1, 0x000089aeeaf8c495, 0x000d0e557f623c19, 0x0001b346cee7aa73, 0x0000e3399090fc9a }, { 0x0006eb38aad81cf7, 0x000a739b6057604e, 0x0000db9b5314c754, 0x000f3472d7d343c0, 0x00004c1dfbe3a0a5 }}, + {{ 0x000848949c160154, 0x0000e4f8be762b49, 0x00006d459f779d3d, 0x000d6b1fa2a9ee4d, 0x000073144722cd51 }, { 0x000631594e5d8939, 0x0009ee5d23a84178, 0x000d6db14456f57f, 0x000650e1f892f3b1, 0x0000d7a0b3f34fe0 }}, + {{ 0x000a613a9e60b8e8, 0x000423cde918dcce, 0x00033c9c94ad800f, 0x00012332d2e7b599, 0x0000a4f91cafaad2 }, { 0x00000da7133e2037, 0x000286cf1fdc9f70, 0x000887923f6f84cb, 0x000fc857fb6eae8b, 0x0000f963508ecd1a }}, + {{ 0x000585113ba8dd62, 0x00080ea1f095615b, 0x00065f617af767a6, 0x000aab6be0a28ad7, 0x0000085f54531694 }, { 0x00033ed1deec48b1, 0x000ae0b30df8aa1c, 0x000b877911cd914a, 0x000e64fcbaddda07, 0x00004abbcd21ba68 }}, + {{ 0x000610ffa32530f1, 0x000285d80e877662, 0x000877ce4b1cfd91, 0x000b658349e99e6d, 0x0000e408841fab40 }, { 0x00090cb5663d4ea5, 0x000a2d4751c8159a, 0x0005062dddfd0fce, 0x000f8d733697b498, 0x000058975ab9e049 }}, + {{ 0x00091be071c8396f, 0x000c94836f024cb1, 0x00071ce580f69081, 0x0004498f185be1f7, 0x0000741b76e70b14 }, { 0x00048a876e5adf25, 0x0007aa5cca5e55cb, 0x000c4345c73e6437, 0x0009de0db3864ba3, 0x0000cb37b2d41132 }}, + {{ 0x00053fc7d8535a0e, 0x000b856580e40a2f, 0x000b7d40a0e49c2f, 0x0001f82c9f194ed8, 0x000020d26cc66d51 }, { 0x0003b7d63457b0ca, 0x000e49b78593e7d5, 0x0002ee238fa36714, 0x000f3099b2cac4ee, 0x000023acbadeefac }}, + {{ 0x00032b33d4f558d6, 0x00037483e07113c9, 0x0008ea602fd9386b, 0x0000f762b6e4a5d3, 0x000040b7b04b7684 }, { 0x000f178169d618d6, 0x00020510dbbf08dd, 0x000885aab8e91f1c, 0x00043069b211d07c, 0x0000c105f022a618 }}, + {{ 0x000b741973430cb0, 0x00096350a712229b, 0x00074db32619911c, 0x000070c8393cbe44, 0x0000fe88492c7c4c }, { 0x000da7715e131810, 0x000f9a256dbe6e72, 0x00062cb5c88e8a5a, 0x000078a31e578ec5, 0x0000121ed1b3bd72 }}, + {{ 0x00084867a70ea8a3, 0x0008d1753dfabf0f, 0x0007c09b2ab277d6, 0x000b4f658728d207, 0x00008772d5dc2672 }, { 0x000c9017adeb92a2, 0x0000f3d70e35b1c7, 0x00079d20267edcd3, 0x0008c8f210241446, 0x00002a5362cc2cc0 }}, + {{ 0x000461d767714a05, 0x00068e90a482873d, 0x0000e31c7d6d3a7f, 0x0003383e74265d6b, 0x00004a05abbc1234 }, { 0x000626833fe129d4, 0x000cac564a7e489c, 0x000cdab872b2a050, 0x00033754ecc5675c, 0x000089b5043845b7 }}, + {{ 0x000568d0917c4acb, 0x000c55a83cdd60ed, 0x0004cbae30f32f9c, 0x000d8992a50602fb, 0x0000910f7a813c33 }, { 0x000ec2057b354ced, 0x00035c70259217fd, 0x0008e56f3c6925cc, 0x000490b6e93831cd, 0x0000a336551d0bd7 }}, + {{ 0x000563cce247e851, 0x0005499f98a759a3, 0x0002c25e6f3b7c66, 0x000dca58755a0a7a, 0x00005ae8843b044c }, { 0x000eea4056f758e4, 0x0005117e7b1fbe12, 0x00092088f88989d2, 0x0007764db8a7dc97, 0x00000ee98d72925b }}, + {{ 0x000ee376f827fa0f, 0x00059a7ba772b34e, 0x0000706aae49b0d1, 0x000f205dbe16ed34, 0x0000b5d4498eade7 }, { 0x0009a59c3b7533ce, 0x000dc1783674c027, 0x0006de9d65ef7473, 0x00070cb0f65832f9, 0x0000512581da9ee6 }}, + {{ 0x000fa352b73388b3, 0x0009a2ebd19bb161, 0x00009382dacf6953, 0x000135847c6c7cfd, 0x0000dfe8b3751963 }, { 0x00059df31f52f920, 0x00035b8973db6d32, 0x0000c347c49fe544, 0x000c2371f7183685, 0x0000f1f4cc727793 }}, + {{ 0x0008835dedbc740c, 0x0007d25913cc16df, 0x000ce91f116c9a1b, 0x000808dae18bc5b6, 0x000071a394c1d139 }, { 0x000ce433b9ac0821, 0x000ead865a40ab05, 0x0008bc6703c50add, 0x0000029696559643, 0x00009a0bfc436be6 }}, + {{ 0x0001e29ee4d40158, 0x000984f6ad651437, 0x000764feac1214e7, 0x0009468c71151182, 0x0000fa9f57c32bae }, { 0x000b4d4bd6ce4114, 0x000e80963717b46b, 0x000e251d88cbd747, 0x00081172202be02f, 0x00001fa60920ef36 }}, + {{ 0x0001cc10cacd0147, 0x000ad9620efd6628, 0x000043c91c4987a3, 0x000963dc292ba6d2, 0x00000e78ee2053ff }, { 0x0005c6097c119aa3, 0x000cdad4b4d7f6ce, 0x00059edbd3562f1a, 0x000ad44975c9f1d9, 0x0000702d0c39051f }}, + {{ 0x000ea0e79fe0f90d, 0x000a2a6328e5e200, 0x000a45e06db05fe3, 0x000c6bc78f7b5244, 0x0000518bfd167866 }, { 0x000e3a0690854dfd, 0x00099eb646c7ecfb, 0x00028633e40d1fc1, 0x0005dd269eb81149, 0x000077f2043ce75a }}, + {{ 0x00066dd6d2079f06, 0x0004c3d42e06189e, 0x000067cd28417e6e, 0x000130050bf07794, 0x0000de2c929cf8ba }, { 0x000333b1e86df344, 0x000b967ff99abde3, 0x00009477132566ad, 0x000536ed7c990355, 0x0000973cee61a30e }}, + {{ 0x000982aad98c4636, 0x000db3c6c491c14e, 0x0007975a94ae8585, 0x00092fced0597668, 0x0000469878650d9d }, { 0x00092d6943d57f62, 0x000f1478be0dcf0e, 0x000d7c9ceaae9a12, 0x000bd457f700080a, 0x0000c7c4650a126e }}, + {{ 0x00038b135b3697ef, 0x0009bf885dfe9aef, 0x0004599f736f9c08, 0x000480120d825d9a, 0x00009a6f60743203 }, { 0x000847fb2ab7025d, 0x0002de062a7150b5, 0x000db3ec1370558f, 0x000b9932ef31fd8d, 0x0000640e5b498396 }}, + {{ 0x000ce5e866272fbc, 0x0008bdcdccbac8b2, 0x0007da0e9d6243e6, 0x0000930dfb642aa7, 0x00006481890aff49 }, { 0x0009424317123bb7, 0x0008088c98c44004, 0x000da8b80f62d7e6, 0x0008318d78104a8c, 0x0000c585f14062f4 }}, + {{ 0x0000428dffccb096, 0x000cfe784d6365d8, 0x000f0f3311b8f429, 0x000378330bcb7443, 0x0000aa82351ab1ae }, { 0x00058c1fb6bdb9c6, 0x000e9efa4faf8433, 0x000dca1d65a933e3, 0x0008101ceced8538, 0x0000d4a8d9e6e600 }}, + {{ 0x0008aba53a05bf33, 0x0008de5fd349961a, 0x0000db761dc2a9ea, 0x000e35a382b2cfa5, 0x0000b7879468dded }, { 0x000eebef3fda587c, 0x000b11d6e96eb8db, 0x00000cc3a6e277a8, 0x0000c796c65d8dea, 0x0000e172dfe107d8 }}, + {{ 0x0005a760658ad3df, 0x0008e98ce7852541, 0x0002a5bd40fc7160, 0x000a56bddd50e8d7, 0x00005c3561e661be }, { 0x000e509af3870a6a, 0x0003822961f23d6a, 0x0007c59c25bcd2e9, 0x0007893e4378e443, 0x000027a005b340d3 }}, + {{ 0x0005626678970f60, 0x0008e46577f44a13, 0x000c80af7872b352, 0x000e85884e09b748, 0x0000e421f514b45e }, { 0x000ceafe50229ea3, 0x0002218bf8d21e6b, 0x0000f51aa91d1556, 0x000a1d0c022d9653, 0x0000b69daf2a9172 }}, + {{ 0x000e6c984782812a, 0x000b4f7be42a5821, 0x00004697d39f6d6b, 0x00067b1a9d3fc608, 0x0000472dc3a58087 }, { 0x0006fec314288ecc, 0x0007d25d30c31f70, 0x000aa52b5e0e12c8, 0x000798de7b7eb72b, 0x00005698fa1698c6 }}, + {{ 0x000a05261d35c7d3, 0x000e910f8c22049d, 0x0006ad59994bee9c, 0x0006e5f6b9bfbcce, 0x000017336b3b0d0d }, { 0x000c744e8ee14501, 0x0005adceba7efc8d, 0x00094967709fe15a, 0x00030f027471237c, 0x0000b4abf8266348 }}, + {{ 0x0007b411642b925d, 0x0009016a56edb730, 0x0007244c6d0c0d15, 0x000ee570064357e3, 0x000045c5461cf724 }, { 0x0008434e8e56e691, 0x0008d3274c898834, 0x0000e03f995f5bf2, 0x0001d53823c16282, 0x0000bfbc0e792c1e }}, + {{ 0x00017b66ac0eda90, 0x000624f2c7ae0b94, 0x0000d7be4d9e6b1a, 0x0007eceb1c46fbf8, 0x000073445e243c47 }, { 0x000d06252a7f7cde, 0x00054b2c5ceec209, 0x000f449ba5b7dfa6, 0x00085a8e6d69661f, 0x0000bd415537281b }}, + {{ 0x0009650f1aafc77c, 0x00018b07e50122b3, 0x000b118b6d8a8280, 0x000784d7bdd744f8, 0x0000b7a7039bee26 }, { 0x0003cde18959c8fa, 0x0004df71fa38477c, 0x0009110e30c5b652, 0x000a5bb8a3d815f1, 0x00000fab64c70c58 }}, + {{ 0x000af52d3611da39, 0x000ba7bf9539a488, 0x0005e913946f430f, 0x0007dd3bbb0100e0, 0x00008c0902a3dbd8 }, { 0x0008a53a687694aa, 0x000f347dbbf698b0, 0x0009fb36e20b6928, 0x000d5b3f82961a1e, 0x0000e28e2ca89070 }}, + {{ 0x0009d84d2e9b0fce, 0x0002d481bee45d41, 0x0006229033078bdf, 0x0001f5669b3cee34, 0x000090c773d3e729 }, { 0x000fb1fb1bd23754, 0x0006fc51c4d349f6, 0x0003a68b5ea950a0, 0x000747aae6596584, 0x0000f1319ee53ae6 }}, + {{ 0x000f0bece2f566fc, 0x000010607bf8fe31, 0x0008155b86689659, 0x00090f4d346259c5, 0x0000d4aef04c0740 }, { 0x000849f911d26148, 0x0006cb3f3c72914e, 0x0004546b3a782574, 0x0000a254629e8ea9, 0x0000ef344da514b1 }}, + {{ 0x00007d28f8169af0, 0x0003fbbf4737f217, 0x000af18cccb4682b, 0x0005ebdbed8dba5a, 0x00005fcad39eb18f }, { 0x0008f0c981a47c9b, 0x000ab0bcaa999eab, 0x000c63a21b4ad294, 0x00058242dba7b174, 0x0000fa27d77ce474 }}, + {{ 0x0009619367bed35c, 0x0008e9a324b47379, 0x00029946a8624378, 0x0005f80edfba9e42, 0x00002193d51edbe3 }, { 0x000898978136c517, 0x000dc5754b7032b4, 0x0009dbaa3dc9b204, 0x000cbaf5af936b3b, 0x00005c1090706f4b }}, + {{ 0x000ed617a5a061dc, 0x000f95a13d4f95eb, 0x0004eec56d5b0d63, 0x00012183d737cff8, 0x00001b08a819d5ea }, { 0x000791e248259760, 0x000f4017dfd8ab26, 0x000dd2968e62408c, 0x000108545ae7b89a, 0x000093d95add0afe }}, + {{ 0x000d5c3a7fff1f96, 0x000a0ad324fa34d3, 0x00070f6273a886e1, 0x000bd9c99ea11144, 0x0000b3c3fd9df0bf }, { 0x000a251c3731c8ea, 0x000f1678d0412d2e, 0x000212b74f637f2d, 0x0005fbf82d92625e, 0x0000b4da522a951c }}, + {{ 0x000cf06fd6232db8, 0x000d132790691bf5, 0x0008a9c6c6d87a37, 0x000a8836eed61058, 0x0000653769772e9d }, { 0x000cf4a1aa26fac0, 0x0007facd9588e411, 0x00020e9e83d4703b, 0x000800ace1f9bf76, 0x000079b3d81e1a3f }}, + {{ 0x000fc099ea249902, 0x0008849dc1818d01, 0x000983a180c61c4b, 0x00005f4390643ff3, 0x00003e5c40cc22bf }, { 0x00058d9a82959817, 0x000a2c3eccd28fd0, 0x0002795eba28fb98, 0x0001c5eb6d743cbd, 0x0000a1953590ed50 }}, + {{ 0x000603700554b317, 0x0000b9291262b72f, 0x0008c50b6efe112d, 0x0006d514296f924f, 0x000024bbaa00c3a9 }, { 0x00040606f5dab0ef, 0x0007a9e18d7dd96b, 0x000217a51d9f847f, 0x000dafa49381e878, 0x0000e4b811835102 }}, + {{ 0x00020c00eed74984, 0x0003439fc6751a47, 0x0004899c000050c9, 0x000d0a4751619621, 0x000037a8d658db74 }, { 0x0007d16ea9dbaf18, 0x00086b0d820007cf, 0x000fabc9e97be6ba, 0x000705184880ee65, 0x0000435446efea6b }}, + {{ 0x0005512b4e835c1f, 0x00056b2c0519a238, 0x000dca182794a57a, 0x000cd2b8a9ebf94f, 0x000043f096ab191e }, { 0x0003ebbb9869ab72, 0x00019a899b16a0de, 0x000bd6898d0eaeea, 0x000c0741595c2430, 0x0000e438ccd17837 }}, + {{ 0x0003ec66f6fddbd1, 0x0006bfe18549fdb7, 0x000edbe1509ba54b, 0x000cfd46cf6e200b, 0x000098de96d82185 }, { 0x000c5616c5a42a40, 0x0006dd7d1b9a305c, 0x0008eb5804d7e8ed, 0x000a1c94aa959c5b, 0x00007e60385e5cc7 }}, + {{ 0x000a06b329f8877b, 0x0005f01e6a33f7ce, 0x0006b347bd83ae53, 0x00039e07cc6217a0, 0x00007de49a6fee11 }, { 0x00012c4acbdef85a, 0x000b7cea5f5e7b9c, 0x000fb7501b28384f, 0x0001e515466dfc30, 0x00003b6c73cc9d54 }}, + {{ 0x0005ad49e51ce957, 0x000361a1e407dd9b, 0x000bdc025fb2c747, 0x0008e60a5e8a3587, 0x0000375165792d8e }, { 0x0003f99fc369de26, 0x0008cb27006085ab, 0x000fd3c5cefed71b, 0x0005240a6a88ff33, 0x0000a54d6a89ede4 }}, + {{ 0x00017969cd6413a4, 0x0009b5eb2e636456, 0x0007234ed864a3a1, 0x0000131cfbe57e54, 0x000097da13fc490e }, { 0x0008c4f4f07e5b7f, 0x000e9cd8a7017a0a, 0x000a15d689f8531a, 0x000ba987677b4d19, 0x0000622e9398a31d }}, + {{ 0x000b8c3c1ca6d7d7, 0x0009acc67b3de77b, 0x000da7c33ce88288, 0x0009929c9ae3c0b8, 0x00005e532fdba5e3 }, { 0x00018487aab79e34, 0x000b4eac51b35836, 0x000f33a15e97b5d3, 0x00056d5f37591f5a, 0x0000464d53dbd05c }}, + {{ 0x0007623bd0306c82, 0x00063f79d61718a7, 0x000bfe3096bc0a06, 0x000cfb3cf00413bc, 0x0000bd36a5580365 }, { 0x000b0231a0568154, 0x000d33bdcdd2a50c, 0x000a3aff52ce886d, 0x0004595294a741f9, 0x00006cbf37c0b0b8 }}, + {{ 0x000a0c030ad04bbc, 0x000940d084bae24a, 0x00068a312388eb95, 0x000933c112f0ae8d, 0x000059d33f6ee7ac }, { 0x00089e38dd68ef7a, 0x0009361a0f442dea, 0x00067f1300f605ff, 0x000e94228f92e181, 0x00000cdb381fd9a1 }}, + {{ 0x000ff5b8f078049a, 0x0001e65d2fdca23e, 0x0007dc993fa509ea, 0x0008bbc145a15ee0, 0x00008afe9e821989 }, { 0x0006f2789726e911, 0x000b9bbcb1c8a0ef, 0x000cc1d5c062c9d7, 0x0006103c02e1ee9c, 0x00007b357e712163 }}, + {{ 0x00078ec0a2491df2, 0x000fd1c89ee6256c, 0x000da3a67aa3a41a, 0x000cb11b3f44ee1f, 0x00008112a4f22527 }, { 0x00023aae4f91b961, 0x000d224b7dccbc61, 0x000304010dd5da46, 0x000347705d96dd1f, 0x000040b329358dcb }}, + {{ 0x000ccb9b14c45c47, 0x000b5f5a26262cd2, 0x000cd39550c052c7, 0x0008e5caf1f7f4d5, 0x0000e4892d07ecee }, { 0x0002fe771f54a03a, 0x000e2ad52324aa65, 0x00061f496834cafb, 0x0002935826320052, 0x0000a358d4c12366 }}, + {{ 0x000d971c910c2659, 0x000483db1001684e, 0x000db3d982e44846, 0x000b52d72b56b4ee, 0x00008b44f48218c9 }, { 0x0008b44cb030e094, 0x000f291e3a07b296, 0x000c7c024a091d9c, 0x000e755ae7570d9e, 0x0000f4a48be7b74a }}, + {{ 0x000e62960e80d5a9, 0x0008bb3bf44da801, 0x00093c509857d0c7, 0x000a2f700283834f, 0x000004d0d39a88e1 }, { 0x0006394239b24d7d, 0x000357be6901c550, 0x00081ec479e5e93a, 0x0005f457d80e7853, 0x00009467d044177d }}, + {{ 0x0006f9d9edf5287c, 0x000ce40376c1944a, 0x0003bce03b234092, 0x000ec0e3b7cb6269, 0x0000dbfe013373c1 }, { 0x0006ce2871c6ea89, 0x000a3a2880dd2123, 0x00036f4311374ef1, 0x00024fe85903c381, 0x000070bac414fba5 }}, + {{ 0x000d3ed11bf23e7f, 0x0003128e10d9c12f, 0x000105f062b7d445, 0x000649c587573baa, 0x00002d7ca95fda75 }, { 0x000beec455ef108f, 0x0001b9a0cb2748e2, 0x000831811ac094cc, 0x00064aa418239f01, 0x00008c7d897f4683 }}, + {{ 0x000939e11117c855, 0x00001063f8b84cec, 0x0002c3fee75e7039, 0x000c0fedd7641708, 0x00003953dd909641 }, { 0x000585638f431edf, 0x000e3b35a914f2f1, 0x0003d1c62c0d57fb, 0x000fc50b039e35ed, 0x000031fe78392334 }}, + {{ 0x000e8d6d63ec1c25, 0x0003f6e9e2fce99d, 0x00003ff3181bb02f, 0x00027902a68a2108, 0x0000a6146405e04a }, { 0x0003b6c03c53dedd, 0x000386342146a0a4, 0x00021af375e61c53, 0x00034aa878ba826f, 0x00007332a2758132 }}, + {{ 0x00093c8fa198c421, 0x0008ebbb54dde39a, 0x000a32329dbdca62, 0x0002d37e1744e5e8, 0x000030383a3af937 }, { 0x00096449c0bb9f0d, 0x000ec56de058c5cc, 0x0001ca0b54b965e3, 0x000441167216235d, 0x0000a79f1b841b17 }}, + {{ 0x00022e45572f2733, 0x000f574170693bd8, 0x000d22301dde4f72, 0x0001b4044a28e14f, 0x0000500450e45c27 }, { 0x00086c3726a97a95, 0x000d9e2e6a285cd9, 0x0001117303c981ff, 0x000cb23445866f21, 0x00006f51ec40b74e }}, + {{ 0x000ad1ce128a1832, 0x000da2af7172277b, 0x000e51fae431e94f, 0x0002b5aa757b94f0, 0x00000f8d45d654a3 }, { 0x000ebc4f922ef269, 0x000849dd8f71caef, 0x000597638b146921, 0x0007aad37f43272a, 0x000009ef351a878e }}, + {{ 0x0009c02205f112dc, 0x0009e952f41deff1, 0x000acc7b67b111a0, 0x0002d1d510e44a59, 0x0000fa3e8511d623 }, { 0x00051ff946f13b54, 0x000dc69c4b7d692e, 0x000317f509655586, 0x000e6b4462e6392c, 0x0000a96c730c5b29 }}, + }, + { + /* digit=35 (1,2,..,64)*(2^{245})*G */ + {{ 0x0000a3933301eb25, 0x000a651566c5c43e, 0x000854f45d136c9a, 0x000a9b44acff9c91, 0x0000afb49c7ad947 }, { 0x000a2e067e61d8ad, 0x0004dc10dc1eb2bf, 0x000135c5137c224f, 0x000bda57488cfd8c, 0x0000c44a7f8d059f }}, + {{ 0x0006c13cc1c1b2ba, 0x000707f3e5f9f11f, 0x0009e009feccf526, 0x0004546bd9afe153, 0x0000da180beb161c }, { 0x000f8417a1d44bc5, 0x000008e325fc3ee3, 0x00006399ac1041ab, 0x000580ee77109540, 0x0000ceab562965db }}, + {{ 0x000fab17514db1c6, 0x0008172813b230d7, 0x000e97892cd69e71, 0x000cdff6a634d0f5, 0x0000c7df5b396089 }, { 0x000b9815a106666f, 0x000a1a74f7c4f830, 0x000416725238afc5, 0x000ab9aa0a7d2edc, 0x000091170e9acf8b }}, + {{ 0x000db6d961011f15, 0x000439b319540c33, 0x000964ccfd972723, 0x0008f8acb18490f5, 0x00000165db5b23d9 }, { 0x0003f6e09555115e, 0x00005bb146110697, 0x000e9391de70734b, 0x0006302d2b19436a, 0x000046716ed749df }}, + {{ 0x0007e83eda22ea79, 0x0001a8eb6357f373, 0x0008f3f06b88b995, 0x000bf00fcc5d00f7, 0x000073b37b16df09 }, { 0x000b956bc10c800a, 0x000d8731560bf3d1, 0x0009017a42a05ea3, 0x000140abd1086e45, 0x000062690f21558e }}, + {{ 0x000610ad741347e3, 0x000d891c31b9c38e, 0x000a62deaa41683d, 0x000f3c86f0c5aa90, 0x0000f90c15e6f59b }, { 0x000921d5778fdb23, 0x0004ddf02ba8e15d, 0x0005b38621fa615d, 0x00050e06c0337edb, 0x0000f89b6644d026 }}, + {{ 0x000357c9e3ee8927, 0x0003d392c422f7ac, 0x000229dcbeb4ed3f, 0x000d2d5d1fb63536, 0x0000f4ae39a384d5 }, { 0x000c225a84c23dc0, 0x000f5405b2e5b8ce, 0x0000f4e05f1fef35, 0x000d1f1997e94693, 0x0000aeede3f666b8 }}, + {{ 0x000b8a4cbe978aa8, 0x000fbc8ee3c76cb3, 0x0003979fd2b05b7b, 0x000d941563cf1162, 0x0000e542d606a5d0 }, { 0x0005e56df6f115ed, 0x0003ca59ce6bb278, 0x00017eef4378ebbf, 0x0000d8c8dc4afaa5, 0x0000a21b92c92f88 }}, + {{ 0x0000ceb3fa8e1f73, 0x000163c2bf296984, 0x000496ffc2087462, 0x0007ae28f91fc19a, 0x000071c2f69ba91f }, { 0x0004cf10c29819fa, 0x0006660bc9ba369d, 0x000684a977ff8395, 0x000895207927e103, 0x0000429c81a856ee }}, + {{ 0x0009c0d0a7824c13, 0x0004034859dd614c, 0x000a4f0ff846b7f2, 0x000813ed59c475b5, 0x0000cd1b934f7785 }, { 0x000230a6e8f478a9, 0x000dd91c234296f5, 0x00044257d8cd2650, 0x00071f3f22a0a83a, 0x0000ddf899163e18 }}, + {{ 0x0000030a795ce50d, 0x000b20f72e3d5c1e, 0x00056f1e39259abd, 0x000fdf6343771744, 0x0000727bbec1ac3f }, { 0x000c8d087f282848, 0x00056bf1202e9ca6, 0x000c0959dd124705, 0x000b27cf8e79dde6, 0x0000ccb0bbb230c9 }}, + {{ 0x00025cd048f7a136, 0x000913dbce913af4, 0x000b032d3782b56e, 0x0004ed68a909e587, 0x0000f4c845403bdd }, { 0x0001af92d3eba46f, 0x0004abe90e9d8bf9, 0x000aac93883ac9f8, 0x000767dff991616d, 0x00000f2d9eeda667 }}, + {{ 0x000653fe47f4d959, 0x0006992e93fda293, 0x0007b3299374a645, 0x000d388e676bb6c1, 0x00002b338f3417ba }, { 0x000d70a99798c8cb, 0x00040280f680e752, 0x000bc14618d4da4f, 0x000a4773675eefd1, 0x000070102614081d }}, + {{ 0x00005cf3d8688b24, 0x000be0720445c36d, 0x0001892a7d9c11b3, 0x000144fe971d1ac8, 0x000058a7f36a1f2c }, { 0x000e16f5c25e1654, 0x0008e0b7b1c7129b, 0x000f98876c302942, 0x0003df82dffadcc1, 0x000015505c986cfb }}, + {{ 0x000e029db51b3c16, 0x0004fb8aad581350, 0x0008f57808095893, 0x00033c0a0622c211, 0x0000848670b38a49 }, { 0x000627cfbfce8544, 0x000803794fba0377, 0x0006ebdfc7e6bd5a, 0x000ab8f8eaefbd68, 0x0000239802ac6bee }}, + {{ 0x00035dc5396eb247, 0x000c8ef4e4ca4631, 0x00072209072a4380, 0x000c5c200bcef728, 0x0000b72cb6549160 }, { 0x000b0c5738b12183, 0x000822e27bf1bc68, 0x000f7cd34933b26d, 0x000119eda10a224e, 0x0000c80f888434bc }}, + {{ 0x0002cf43d8bba995, 0x000ba2a346060743, 0x00086e27c0a14c45, 0x000f74e0680fe7fe, 0x0000fac5f4d27a25 }, { 0x000dcd1a75979538, 0x000715f5f02ffe6f, 0x0003829db97527f4, 0x00033ad5e3d9eb9a, 0x0000209af43545e2 }}, + {{ 0x000e5c0304618223, 0x000f48bb95560983, 0x000f41c035820ec0, 0x000e596124090a1d, 0x0000cc98be20fb39 }, { 0x000626289bc31852, 0x000ea4b70dceecab, 0x000461f93bf28884, 0x0001ae25cbb2d3c1, 0x0000160674019bab }}, + {{ 0x000865a96da8e141, 0x00085598baebdcf4, 0x00092d795877cd89, 0x0007735d81a28ae0, 0x00006e178e1b6c8e }, { 0x00097f5dfc26037f, 0x0009ccd237936b24, 0x000b16c21697ffd9, 0x00006a247332f4f4, 0x0000ffad165e6c11 }}, + {{ 0x000ec6787acea84e, 0x000febd32be5e0fc, 0x000648d99afacf1e, 0x0003024b17475bcb, 0x0000b743664d4e82 }, { 0x000fe814369d2cde, 0x0008214d8578c70c, 0x0007a8d35754fdd3, 0x000ce5a06c9ad99a, 0x0000e934ddca5774 }}, + {{ 0x0008474a9996f7eb, 0x0002a822f4fb344d, 0x000f6ff85c520bf6, 0x000348c49b882344, 0x0000f420ddd2a3ce }, { 0x0007a033ec204ecb, 0x0004a4d5d1c00d06, 0x0008a69e46c0c3ed, 0x000d712f87fd581d, 0x000024e3f35d2d04 }}, + {{ 0x00023c422eac602c, 0x000d2c19ef2d2e4a, 0x000e3364a85064df, 0x00011200a1bf6767, 0x00001c6223e12f57 }, { 0x00013599f87f98e9, 0x000822d540f83afd, 0x000d84b4acaf5dc6, 0x000912908c2c2c27, 0x00007299ce914de7 }}, + {{ 0x000f627fd7a63a1a, 0x000315cd7b32c6ee, 0x000ffb93983d2957, 0x0005001bb61a5a63, 0x00007c449b79b37a }, { 0x00080cf93461f5c1, 0x0006efcc4c86bc81, 0x000aee0840c9e22d, 0x00095d433e6f9231, 0x0000b966edba2633 }}, + {{ 0x000e0efb3b8b1b5d, 0x00038959884aaf7a, 0x000259a44d6afe4d, 0x000f91f87b1959be, 0x0000337331701bb0 }, { 0x000b01a0216bb368, 0x0000c5eca8c325e7, 0x000671fd9f4f814d, 0x000e76c1d3c91169, 0x000010645e8443c5 }}, + {{ 0x0003a375e672dfca, 0x000e89363a1483f9, 0x0000e68119b07752, 0x000518de589eabe7, 0x0000537b9e85ecc1 }, { 0x000e0eb3eb3def9e, 0x000f5436a2afe69a, 0x0000335814a3a97e, 0x000978293c4f8910, 0x00004bb46fe72211 }}, + {{ 0x0006fcd2c98f37de, 0x0009b0d9d79046e6, 0x000d05f136ad2051, 0x000cf40ca4d650f2, 0x0000c7cbce68d0b3 }, { 0x0006ddebdb5a0c55, 0x00009b5696605f18, 0x00071e6ee7b1b45a, 0x000ccfbcfe77e5d0, 0x000090641c6e2ee9 }}, + {{ 0x000de285025363f9, 0x000513dfddf74157, 0x0008c18c08581775, 0x000318675f7fa130, 0x0000499a04911b96 }, { 0x00079deed354d5f0, 0x00080789e2aeb6b4, 0x0004aedc64ef1a47, 0x000c7ffc3ba2b9ff, 0x0000ff43ce38948a }}, + {{ 0x000eaefbd10b4a81, 0x000379b3a8631e8d, 0x000d9b723b75c7a3, 0x000c1de118de855d, 0x0000b4dea0f1e6a4 }, { 0x00072cd4b1febb5e, 0x0003c8dd150892d4, 0x0005da5ea4d30538, 0x0007c011a37b8468, 0x00003fedb7f726b8 }}, + {{ 0x000910e7019eb79c, 0x0005a51e9f05de9b, 0x000873d8a4a77728, 0x00080664cd404506, 0x0000f06a0d5cacfc }, { 0x000d896e2f49d140, 0x00016eab3aa8f0df, 0x000681650677644b, 0x0007b0620bab2a50, 0x0000225a11e3b301 }}, + {{ 0x000d55e62f7b147f, 0x0002f53308fbd93d, 0x000d256d89ab7031, 0x00090048546cd5a2, 0x00008f07fbe7613f }, { 0x000f410b11223a4e, 0x0001ca02a81ede7f, 0x0003f9e643967f06, 0x0000701866860dd1, 0x000037f2d5f3b15e }}, + {{ 0x00004aa9d3156f13, 0x000b93849ad467b6, 0x000baa288c1e44c4, 0x000e49060efb48b6, 0x00009eca1fbdd19b }, { 0x0003345e17323e5d, 0x0006786754e48e96, 0x0004d412c0772c5f, 0x000fcdab6693cb45, 0x00001eca39d6b65a }}, + {{ 0x0005b4488b3fb1e8, 0x000d26b23a5d8961, 0x00056a2fedc3595e, 0x00081de771fe19e3, 0x00005b981b48385a }, { 0x0002c4f79da9b17b, 0x00017541a1f22bff, 0x000fb8bc6c4a7592, 0x00033ea8e920a8a6, 0x000037f6be35ab5e }}, + {{ 0x0003272fd83d30cb, 0x000f8d04aa38d1b5, 0x000c62b22135dd8a, 0x0003013c03b0db35, 0x00000b015e47a001 }, { 0x0008a2e909f55c72, 0x000d74f07a8e1078, 0x0006e1dea8f06a53, 0x000ee63444a89e13, 0x0000850dcd40ec46 }}, + {{ 0x0002e8a6205f5be2, 0x0007be3b44a3f84f, 0x000324de206fb879, 0x000c74190acb2f34, 0x0000169e7bbd47b0 }, { 0x000baae31cbf3f3b, 0x0006fb69c2d76521, 0x0003d1eae29fe835, 0x00042b610fb5307e, 0x0000e643f0cba58a }}, + {{ 0x000959c3f21417f3, 0x000255bcbea62e7d, 0x000e119c6c6709d7, 0x00009921ce8ac9ea, 0x00004c4448bc0b85 }, { 0x0008f6c667720f2c, 0x000692520e40ae55, 0x0002aeab843a32e2, 0x0008386bc320789e, 0x0000f23eb6cec001 }}, + {{ 0x00005e16bb852160, 0x00052bbc55d2d8b9, 0x00076498b39b48fc, 0x00066161441d58bb, 0x0000a86b13ffc50a }, { 0x00053f7146de7703, 0x0004e40f661acacd, 0x000ff5e2ff690eca, 0x000c929ba3b8784e, 0x00006044fa1265ab }}, + {{ 0x000d45e2d4b575cf, 0x000bfe5e5681e833, 0x0005b966bb760ac6, 0x000f54b386212610, 0x0000920d33916add }, { 0x0000ca34a27332f1, 0x000d33976e8ae983, 0x000b8eea7b6bf672, 0x000057b89b53b2ee, 0x00008733d0036fff }}, + {{ 0x0008a92a0eca49dd, 0x000fb6c783417303, 0x00087c7cb839b4d4, 0x00005e2388ef5beb, 0x0000914d653ceeed }, { 0x00093b5505c32a66, 0x000543f22433ccf6, 0x00063963b0a3b74d, 0x000ee34fcde8362d, 0x000054d95941e49d }}, + {{ 0x000cbb9da03036b6, 0x000b5c0cd1797a18, 0x000e67fc118d1fef, 0x000c2923eea17b47, 0x0000697a3f1abc0d }, { 0x000986f3fa1f44ea, 0x000139c4d8424cff, 0x0000b195410c7287, 0x0003d1ca3db7048f, 0x0000c7c46d5a24e3 }}, + {{ 0x0006210d9e58a61a, 0x00029b5224c08dca, 0x0003db93fef2cd7b, 0x00002ae4f2bbb09b, 0x00004673f3e36b54 }, { 0x000acede4893a3e0, 0x000167a09cb54d69, 0x000fb53a3b5bd9ea, 0x0006f485791eef6d, 0x0000d389cb15387b }}, + {{ 0x000410cbabdf6c15, 0x000067190b771c33, 0x000486535b12a4e1, 0x0004bedff563b71e, 0x0000ecda5577d7de }, { 0x0003d7d5dee03f61, 0x000cc2630da84dd0, 0x0009ea44ecbb751b, 0x000151692d0711ae, 0x000014aba617814f }}, + {{ 0x0004912ebf56ac82, 0x000ada8ced806b84, 0x000424ede5b8b06d, 0x0005059bf222e613, 0x000077ee32509e55 }, { 0x00024cc23645bf6a, 0x000cc742496c27c5, 0x000bcdaf647a66d4, 0x0001f552c8ea3176, 0x000068aa54cc75ce }}, + {{ 0x0005468b2dae9bab, 0x00036d89f6f1b18b, 0x00048f86582e286b, 0x000f286fc2552f00, 0x00007485d84694f9 }, { 0x000ee3525470e487, 0x000b7883ff90f2ba, 0x000e802701cf5d83, 0x000725c2877947bd, 0x00000092a2e7377c }}, + {{ 0x000c1f75e1fc6e4d, 0x000e97d3567962f6, 0x000f15694a198229, 0x00082e3a1379ed61, 0x000016040a7a66fe }, { 0x0005b5c318e65050, 0x00016423b4a79fce, 0x000c6f39817a3245, 0x000c19ca1f20bc83, 0x0000e78407cf44aa }}, + {{ 0x000450a8760aef29, 0x000895d13221bc57, 0x0001f6ee42812871, 0x0004b6ca1707baad, 0x0000156dc61f6269 }, { 0x0002697b59a57f39, 0x0008453e5d0338fe, 0x000e491ec0628d37, 0x000e4b3d01e77f7a, 0x0000a053efd0726a }}, + {{ 0x000d3b14f7467390, 0x00015bdda85d5347, 0x000f825cf9f2e0fe, 0x0008ff5e753e78c1, 0x000059772a4a8d49 }, { 0x0005e906b119a241, 0x00033b0cb8f2bd25, 0x00062c96a2e1fd6c, 0x00050eaab2d50b48, 0x0000699177c6e9dd }}, + {{ 0x000dc63a9d42470f, 0x00013fc8fe280d19, 0x0005151ada0e3238, 0x000c459b0cd8e0de, 0x00004eff38b04e9e }, { 0x000f4187bc92bdf7, 0x000c53b4be1495fb, 0x0007d4178a70e616, 0x0004bd4dc25eb3db, 0x0000eb13072f9e75 }}, + {{ 0x00078c2ec1e3ed4f, 0x00051691416a6a5e, 0x00085c63595aa0e1, 0x000163b5d8f860c7, 0x0000283d923fc854 }, { 0x0005beef7ad3f5b3, 0x0007b815ad735813, 0x000023a1511c7557, 0x0006b79bab4cc9e0, 0x0000199d8c4e721f }}, + {{ 0x0000a1b1af1e78d3, 0x000f4cfdbcf41b9d, 0x0009de07e610f9cc, 0x0008a23d85703662, 0x000010d9697c4fc5 }, { 0x00023c2688aafc37, 0x0007c7503c41c4b1, 0x000af155a9b9f44b, 0x0003f540aa023829, 0x00006df810563aa5 }}, + {{ 0x000f8aff74187332, 0x0008ecc36ba06eee, 0x00044e47cc9819db, 0x000c0b71fface311, 0x000023dc4d264ada }, { 0x00009a815983bd68, 0x00045042d05841bb, 0x000e84cfa0889ade, 0x0001ffa7e42f0e3d, 0x00006a7649f271c7 }}, + {{ 0x000cee582b9889e1, 0x00045a10fee104a6, 0x0007ca159e31ee59, 0x000326733ad7788f, 0x000065aa11dd04af }, { 0x00044cc9c627cd7f, 0x0002267e8f55a7b8, 0x000655974f477505, 0x0003eaf9defbee3c, 0x00000dd76f26bfac }}, + {{ 0x00065e1d58e34a25, 0x00069cd66926e04d, 0x000eaab2a4614ef5, 0x000205a070001e38, 0x00007f9aa8b3ba19 }, { 0x00091abd3f792d82, 0x000bf41be76ca2da, 0x000c3f7835fb599f, 0x00043b7d27895cf5, 0x000000657fe7cdbd }}, + {{ 0x000e6ea8cc26f72a, 0x0001e8387eb36bff, 0x000192dce6e80e03, 0x000c29f5fc5f0710, 0x000060b97966ad86 }, { 0x000db3af99846589, 0x000c765edfa9284e, 0x00013dd8ddcbf735, 0x0008321fd6c510bd, 0x0000a06e6ac55647 }}, + {{ 0x000b32a66e2632f7, 0x000809d6295d4269, 0x0006a471070d02cc, 0x0005b2f040c4f6ac, 0x00004f774520e665 }, { 0x000688122ab3d6ee, 0x0004566f0476ce2b, 0x0002ef7ab5896bbd, 0x000783a097554d95, 0x000014bb84887b9e }}, + {{ 0x0009e6c0473150eb, 0x000218f508efb637, 0x0007f0d62f80b77c, 0x000f0c04f9eb5b5c, 0x000069accc4a1882 }, { 0x000dea6143dd9627, 0x000522ce37a1f698, 0x000a7569ca1c970e, 0x0002be4d3cbd252c, 0x00004fc80b2b91d6 }}, + {{ 0x000e42f66dd9a70c, 0x0000846de6736294, 0x000e21f936b36c3b, 0x000215cc757f7aa1, 0x0000e42c4db111bf }, { 0x000f78959874b51d, 0x00067dc910778965, 0x000f6350f2c2eb73, 0x000e53487a0d690c, 0x00008713f1619ac6 }}, + {{ 0x0009401711af5ba4, 0x000394752b16dba7, 0x0005bbe4aa9f7237, 0x000dc9293deefc0e, 0x0000a97c7a345d34 }, { 0x000c122b07c3fd19, 0x00093e9f21a15cb6, 0x000383dc6fe3e1fc, 0x00079e86c73d2616, 0x00000e249332ac22 }}, + {{ 0x000e79dab8354f95, 0x00047e715f096905, 0x0001cf8235118233, 0x000890ac6508b9b1, 0x0000c766eb659330 }, { 0x000d4ca47748ce93, 0x0008ef06c775aa2e, 0x000b4a7b482a1c21, 0x000611206df09d8c, 0x00003cf5f801f0a6 }}, + {{ 0x00087fc1cec8e5a8, 0x000363610bbb8b54, 0x0002bdc1ebd45d49, 0x0009d74cc0737ce8, 0x000003ccfa0ebc20 }, { 0x000a1b8ea3c1eb6f, 0x0000bb3b8bb36591, 0x000e6b42b27cef52, 0x000ff9344dea5df3, 0x000047617165cfc3 }}, + {{ 0x000fbbcec8aedc8a, 0x000e71967b0867ce, 0x0007ad7a76578ca6, 0x0005466e38d5e0d0, 0x00007711fd87562a }, { 0x000079e8e108ea31, 0x000cbab0263ad100, 0x000dfc57a6a990e5, 0x00006d517d8199e6, 0x0000296d52bf5ee1 }}, + {{ 0x0003b3afef9ade77, 0x000219f8a3422839, 0x000c147c62f6768b, 0x0008c19018097799, 0x0000ebf4142ddbef }, { 0x000ac70895b5ba6b, 0x000cf2a2db3d5ba7, 0x00020ef8474730ce, 0x0007efb73263dc46, 0x00004bc34642342a }}, + {{ 0x00025b0834bbbd7c, 0x000524d5c2f342bb, 0x000a02d27279ffdf, 0x000a440d0bf80907, 0x000081a156479865 }, { 0x000ccd9a92ebac1a, 0x00074a56c3a1ddad, 0x000a29fb8884da05, 0x0007030fefe4ec7e, 0x0000acc66637fdc1 }}, + {{ 0x000105a92d7a6a29, 0x000b4dadb58da1f8, 0x000f37c53dc1205c, 0x000f2214322bbc12, 0x0000f4c05d3cc006 }, { 0x00023213222f51a0, 0x0003bf37a859d51f, 0x00053e0f0648de72, 0x000bec7c9e3ec7ce, 0x0000fa1715d802dd }}, + {{ 0x000bdec2116e9b29, 0x000389c76497ee80, 0x0006bb3874fd1cc1, 0x000343fe15d2b0ac, 0x0000a3fadcb3a4e1 }, { 0x00037248e9d64745, 0x00087efa63b10110, 0x0007dd6bd1db932c, 0x000c6c78bf9e3fa9, 0x00009e31d0655466 }}, + }, + { + /* digit=36 (1,2,..,64)*(2^{252})*G */ + {{ 0x000be5ed0e405bae, 0x0007fc91ec34f9e7, 0x0004b79b18f54024, 0x000b106f3d8772d3, 0x000037037c975e12 }, { 0x000aec44147d71ff, 0x0003d1931e82b100, 0x0007bf1327384e2c, 0x0002fb55ec63d285, 0x0000df2ba6d3b215 }}, + {{ 0x0007a23f356e3059, 0x00041e71e29a3efb, 0x000f94f0f0f98de8, 0x0007a880ecbe906e, 0x00002d869e92df60 }, { 0x000cf0bbf87a34ec, 0x00089c2efd2119d3, 0x000ebfbd0dd06fa3, 0x0006c851303198c6, 0x000030a29d4bfdd3 }}, + {{ 0x00089caef387625f, 0x000fcb72b7247593, 0x00017a38174726e5, 0x0001b102c945353e, 0x0000fcd0db4d1457 }, { 0x0003429bba3484a4, 0x0001753db65ef147, 0x000e6a574289160a, 0x0006d9c5f2dc2cb7, 0x00005d42b1ac334f }}, + {{ 0x00012c9e1ee0d0a1, 0x0003490b01e6e274, 0x000da05414bdd548, 0x000de03a9047e2cc, 0x0000c371569c9623 }, { 0x00078851bc8c9a7d, 0x0000d36794075521, 0x0006dbaa6726fc38, 0x000ce611949c5013, 0x000053af2d9b1059 }}, + {{ 0x00035aa24062df0d, 0x0002a52fb85fa4ca, 0x000d94e1eaa94f02, 0x0001840aed61257c, 0x0000fb93c2113070 }, { 0x0000d05aabec972c, 0x000f75d4421fc835, 0x00007292ec8f71dc, 0x000b37558f6df8ee, 0x0000d9d09ec67e4f }}, + {{ 0x0000235a102cb4ec, 0x000fb35a64785f45, 0x000b0f0672f75fa1, 0x0002e6467bc56637, 0x00008030444d7012 }, { 0x000881065be741fe, 0x000b8d8f2c4aa658, 0x0000fb14fbdf31d8, 0x000b607bac347583, 0x00006adf01034a09 }}, + {{ 0x000f12502f6f25d9, 0x0000c22cc1b5e838, 0x0000f6f93bcc544b, 0x0008c7ddfde2d4ad, 0x0000c68d49d6c0f8 }, { 0x0003511dcdcef6f9, 0x000a7dc7783920a0, 0x000dbd6b689c8148, 0x0000f52a6e80014a, 0x0000730b2f927704 }}, + {{ 0x000211e48a709134, 0x000a06d95a7b1a29, 0x0005aa515d70a8ec, 0x000baface9c4e7ad, 0x00001420ee199ed7 }, { 0x0005f92e47355a0e, 0x000716ec78ef1f42, 0x000fe05e173edf3f, 0x000e4dfe82b2c090, 0x00005f26894a26e6 }}, + {{ 0x0000e5daec35c312, 0x000444631890a36e, 0x000f77190f6f4a99, 0x000791e30703ef5f, 0x0000248d7cab9079 }, { 0x000a1bd7b6437663, 0x00041c3c9c9f1554, 0x00066b1d61acbaae, 0x000aa5c297e4bf17, 0x0000f13072c92c6b }}, + {{ 0x000372def7fe9e8e, 0x000089946191d3d6, 0x000d1815135fa99d, 0x00071e788281fc8d, 0x0000e04cb9db1b55 }, { 0x0003bcefb0c7e3f0, 0x000cb480d8972cae, 0x000672598a8f1310, 0x0004d1cf43f2dd4b, 0x00005a02d3e37cbc }}, + {{ 0x0005e8048f16243a, 0x0002f1ed785e73d3, 0x0005f8bdffd849c1, 0x000a2174aa5db5ab, 0x0000f3e31e72b2c9 }, { 0x000343d185ef14b5, 0x0005c8f1adaa0f81, 0x0005718a48d45076, 0x0005191b828ec3b4, 0x000095c49bafe83d }}, + {{ 0x00037b515fb7aa40, 0x000b844caaa358cb, 0x0003e5a8c6cb2e2d, 0x000dd1d9a1a1db7e, 0x000027da7bc2cde4 }, { 0x0005a481c0d7db4b, 0x00089097b165fbe5, 0x00098c626e327572, 0x000dc967efc322ed, 0x0000c100250a4181 }}, + {{ 0x00056b31e0992f90, 0x000c312c23fc9759, 0x0005706af79af358, 0x0005f4d391571580, 0x000032a43ce4ae5e }, { 0x000b37b634d74c5f, 0x00016d5ff7b33a68, 0x00098146b10a6fb6, 0x000e2c698c8d5dc3, 0x0000a98da6d07fa6 }}, + {{ 0x000f40ac3c4dd2af, 0x000cfd68b11888c9, 0x000de0fd79a08293, 0x000b4f34a5e0e8c3, 0x00005ee377d3a06b }, { 0x000ef1ec28436dca, 0x000149534e0f63a7, 0x0001ec713cd110f6, 0x000f727b7a128bf9, 0x00005d0d98ab5496 }}, + {{ 0x0000f1a43a4a1ad5, 0x0004f0fa36a27378, 0x0005e27077875e3c, 0x000e0939735dc136, 0x0000d7436395198a }, { 0x0000d7c67d880277, 0x000b04bf8cb0ba05, 0x00062fa0ff6e7415, 0x000ff59efb0b5376, 0x00001a3237f9a695 }}, + {{ 0x0008910bd3c74498, 0x000d8af3aeac968f, 0x0008cc252692ed9e, 0x00067be64e4f7fee, 0x000092836060ef1c }, { 0x000890896b28139e, 0x000470cc9c0726e3, 0x0009a0eab753f427, 0x00046bc1b1530956, 0x000038600b6014d5 }}, + {{ 0x00053794e8af97d5, 0x0007c5ca5618c937, 0x000b02a1ade8a949, 0x0005f92a8e665432, 0x0000f8ed81c1d707 }, { 0x000c21fb8d99ba56, 0x000957ce8c0dbccf, 0x00025d6478156ff5, 0x0008c850031e0261, 0x0000b4fb313fc9e3 }}, + {{ 0x000b3bcc8886aff4, 0x0000d16b0843e0bb, 0x0007ae7478a94254, 0x00027e43053b1b3a, 0x000070a88a7167ff }, { 0x00047e1384f31100, 0x0001100c93dce831, 0x00018d1416a58415, 0x000039ce87e79da6, 0x000008370d177e00 }}, + {{ 0x00034714e4870f2c, 0x00057d3af077f30f, 0x00031311a055c13d, 0x0006bc053ea78f84, 0x00006124e88ddd7b }, { 0x000ba0c58a21a931, 0x0002c15c2376c840, 0x00093179e1f91646, 0x000dbf9908315b65, 0x00005e507e2ffacd }}, + {{ 0x000b7587e7d8f6a9, 0x000e47a529a6d482, 0x000d977c0a1b5071, 0x0003784f99c7f250, 0x0000a3bfb164138f }, { 0x00043e21ae8a2808, 0x000fa33e0182a650, 0x0007dfa2f0dba6d3, 0x000d3018fb82ecf8, 0x000055f7520eb309 }}, + {{ 0x000e6559e9dabe39, 0x00010d666c834ea0, 0x000838dbe89dd09d, 0x000dbf1473be43e1, 0x000026c068976f46 }, { 0x000e63ef6977674b, 0x000b38e0c6615b48, 0x000cc7e1ae0786b6, 0x00076b88614abc8f, 0x0000e564e456248e }}, + {{ 0x000faca8d0cebb8d, 0x00074b453b31e91a, 0x0003948a0c0742a8, 0x000bf70660cba7ad, 0x000094b060ddcf41 }, { 0x0008fb9a616bc52b, 0x000311d9ee9761ca, 0x000b47c4be2e0a39, 0x0003f554c3497a16, 0x00001a01ac4f5b97 }}, + {{ 0x00024d301b78fa64, 0x000cefe392511143, 0x000c987a034b5852, 0x000ace55c36bf25b, 0x0000a71003604b62 }, { 0x000b211a0e5ee431, 0x000310cd670407e5, 0x000188521ff34062, 0x000def3e00ea8d4f, 0x0000dbd759ec2451 }}, + {{ 0x000e220933648ca0, 0x000dd205ffe7b376, 0x000aa925c9a6a480, 0x000c325193b7f3ef, 0x0000519935e92c50 }, { 0x0006fa48a2afcd4b, 0x00015dfb486d440d, 0x000568e6ebc32df4, 0x0001776517fcfec4, 0x0000575cad80abc7 }}, + {{ 0x000f59e604baf773, 0x000dc265872cd88f, 0x000b2831aa9d0b38, 0x000f9491c806c1d3, 0x00005ff0f174210f }, { 0x000212f245cd494b, 0x000c4327a0b85dd7, 0x000a21d9cfd1d70b, 0x0008cd713dec5720, 0x00009a66bf0ffb9c }}, + {{ 0x000b75466ceb202d, 0x0001411b5cae787e, 0x00073287eab73556, 0x0005581fb13cb7f5, 0x0000e12d755e6d26 }, { 0x0000fbf8f7c29358, 0x000173bdb6cff322, 0x000a4100e1a2b244, 0x00091aa8b7440f37, 0x000020bd4b0b9af2 }}, + {{ 0x000913b93cb994fa, 0x00098e1df83097f7, 0x000bdc374ec3de91, 0x00039352f28738f6, 0x0000d11cf177dae9 }, { 0x0000deb384609912, 0x00033931fe896366, 0x000f96a98121a3f9, 0x0007b93a17b98443, 0x0000d01181097cf0 }}, + {{ 0x000ab007761cf94e, 0x00006c601a982e6c, 0x000069e1c5b02fb1, 0x000c41d051dd35e1, 0x000099e98577e95f }, { 0x0009c7a367e425f4, 0x000a71f6565e15ae, 0x0008a2c80cbe203f, 0x0007aea37bf30f52, 0x00007bf67fb4b3c4 }}, + {{ 0x000f733e7e5b9a30, 0x0006ca552f03ad8b, 0x000842daf7427fea, 0x000299789c7e8dbe, 0x0000e03dc9ad2e74 }, { 0x000abfec927f95e5, 0x00016f5b8444823a, 0x0007c1385ba9089a, 0x000291140b7224e8, 0x00005f27d833f8e6 }}, + {{ 0x000cff1ae2810e9b, 0x0007a10079ea1bd1, 0x000cb35e424422ff, 0x000d7f24f1ad9add, 0x0000223f4eaec892 }, { 0x0002b37f69fa04b0, 0x0000749d4cee1172, 0x000b1d83599fe6e3, 0x000489c388e9f275, 0x000066a58613b395 }}, + {{ 0x000f59bf5ce72e10, 0x000e1fdb40146044, 0x000939e7911b9cb2, 0x0004b1efea8ce991, 0x0000b81a0bac185a }, { 0x0002588530df2495, 0x0009d4f923a277d8, 0x000ce2b6aed5cd2a, 0x000152751d9bc9b7, 0x0000c023c697a0ab }}, + {{ 0x000cd15a3cc6fb9b, 0x000a19f82e4c6346, 0x0003cd730abb95f1, 0x000222f258efb831, 0x000068413078deb3 }, { 0x0001e7c1ed462bd3, 0x000d5fdbfcd8fb51, 0x000f5c6d0b354d1b, 0x000acc02f31db2ee, 0x00009cf8f2c231b2 }}, + {{ 0x000c1b23430b5424, 0x000e10cdc9a151e9, 0x00079f9585161afe, 0x000026de79edbfc0, 0x0000dd01a58284f2 }, { 0x000676c6277d628a, 0x000928b7f8474b9c, 0x00063aff51f1e745, 0x0007dad5a90657c0, 0x0000a3eff6f709d8 }}, + {{ 0x0006cc32b494aa16, 0x0001c47b7d6dee80, 0x00077299605ebcb8, 0x000011fed0948d92, 0x0000bd274de4ad55 }, { 0x0004428c5ee2c46b, 0x0006b64061ef338c, 0x0001fdc05d8e8c6b, 0x000d73e9b1606fa0, 0x0000c773ba6a62af }}, + {{ 0x000205fb46da5307, 0x00021aef91b0b2ab, 0x00033e3801f8f3cd, 0x000ace1edce870a2, 0x0000468f39384030 }, { 0x0007205ff5fc9697, 0x00068e744cefa48d, 0x0007ca7816e1c2c7, 0x000209163b6fc37a, 0x000044e445df560c }}, + {{ 0x000b1f606a304a7a, 0x00093328887de41e, 0x000b9b7f44ca4fe8, 0x0000c70175de0df0, 0x0000e1591f40e90c }, { 0x000901a9494fafda, 0x0006996e30ea15cb, 0x0001084797dc0097, 0x000bbd98f575816a, 0x00004054cb1612ae }}, + {{ 0x0009f2630bb6056d, 0x000a208d8fc35489, 0x00003d4999fd2fa9, 0x000f8f85a5010b5d, 0x000008b55032749d }, { 0x00083d306cbd6562, 0x00019afb4e3b76fc, 0x000bf00347df1b02, 0x0009b30ce14e51dd, 0x00007b2794a6a001 }}, + {{ 0x0007c824b04ea420, 0x000471577d4715c5, 0x000913a80d8575a1, 0x000c5c986d30019f, 0x0000d81758c67e87 }, { 0x000c66382097faea, 0x000692fd8f92a230, 0x00048f5357b258f0, 0x000eb2f9a4a557fd, 0x00000e310f808729 }}, + {{ 0x000f50250aaa7e2c, 0x000928ff83a92661, 0x0006e1b1983af0c4, 0x0003f70ebc7741c9, 0x00004f20a513065d }, { 0x000e8025b4418b73, 0x0007bc81477b6547, 0x000d976fbfe6b5d7, 0x000bb3597c65b900, 0x0000304bd4ae9453 }}, + {{ 0x000683125ec1f5d5, 0x00090ef12045cf9f, 0x000ea649d65eec4a, 0x000d990256fcb2ca, 0x00006feb137cf030 }, { 0x0005f11e11f4e767, 0x0003deae312410e0, 0x000766e7ca1eab36, 0x00013d80767e2867, 0x0000b79acfa040a4 }}, + {{ 0x0004f1f61b1ed88a, 0x00070ef9d3472c26, 0x0007628b1d2a9b6f, 0x0003d25ee3adff69, 0x00007d01488de9be }, { 0x000bb88d5112808b, 0x00094ab9bfb9093f, 0x000ea55ab0ade7e8, 0x0004be60d3df8ae8, 0x0000c9e427871646 }}, + {{ 0x000b283e83436d45, 0x000d64ce88c50d10, 0x00079d4eddcc4a93, 0x000ba49e47532e80, 0x0000ad9d0c90c59e }, { 0x0000afcff7b09b52, 0x000a09149e692749, 0x000787b8e224e80b, 0x0000d3e8eb96e966, 0x00009458dc2fcb01 }}, + {{ 0x0001382d0c39d19c, 0x0000783210b08568, 0x00025db81b7d5f44, 0x000933909a5a8060, 0x00007b38a809ed42 }, { 0x0004fa1871dda89f, 0x0001b5381927e27e, 0x000165fae9106b66, 0x00004c3ce46c63b3, 0x0000a770fae667f6 }}, + {{ 0x00070bd00e57f777, 0x00059bcd7466b255, 0x000a84178c56f6d2, 0x000449f8884ddbe1, 0x0000555f11ecdfbe }, { 0x000c7d249df1def7, 0x000bf29128bfa0f9, 0x000ccfa016cb0872, 0x0008881b192fce1b, 0x00005893d5343ec4 }}, + {{ 0x000ac38b3da9a9f7, 0x00031bf0bbc6229b, 0x000e25158959fa61, 0x000d9e8051c83c05, 0x0000da4e85bd1746 }, { 0x000896ef10770631, 0x00086e3ec0dfcfd2, 0x000e627395068017, 0x0000c7966f2ecda8, 0x000082a16d1f7601 }}, + {{ 0x0004a0885be18687, 0x000916a0fe9a745f, 0x000c5529e8801da0, 0x00096254908249fc, 0x0000b2610ba18a62 }, { 0x0009895a50a60550, 0x00067317d7ead588, 0x00058f0f76b3c827, 0x000274a89f96cf7d, 0x00000ccc62724ca9 }}, + {{ 0x00023b9b36df10cd, 0x000ebe5573cecfa3, 0x000e9f2368affd6b, 0x000f7772066497ea, 0x0000e7189610325f }, { 0x0009369a44ac6ad3, 0x000660a0115a3c12, 0x000b042f2fca2382, 0x000e839789414c40, 0x000036e7483f7882 }}, + {{ 0x000ee3e9bd875a0b, 0x00079f5903fa2711, 0x00029af6a861120e, 0x000561354e6da0fd, 0x00000c0f6913abd6 }, { 0x000948148819fd8a, 0x0008e1ce27a94979, 0x0003f4d9497c8870, 0x0002f21ca36d254e, 0x00009bc3a89fe40b }}, + {{ 0x0007862d5db75ad2, 0x0002c6940d9cae17, 0x000f9a1ae1ab94f3, 0x00036e44b0586957, 0x00009909fd1ff97d }, { 0x00039531fedb222b, 0x0005a6e503491266, 0x00010e2ff490e472, 0x0009425a62be30bd, 0x0000fb87c6381af0 }}, + {{ 0x0007bbabb687d4ad, 0x000bd11b29353593, 0x000677d066b77a80, 0x0008b697fda38aa9, 0x00008397f4e80b81 }, { 0x000dd9c0966b3966, 0x00013e02c9477784, 0x00052c405d304bb0, 0x00066490cd69a517, 0x000086e14cf5ff32 }}, + {{ 0x00059cf5ae217581, 0x000af4d64f16ea85, 0x000628d490757f4e, 0x000f26f3e8b1cac1, 0x0000aed72ff0985a }, { 0x000c6e2c5d3b9f54, 0x00023bb0e2af19ae, 0x0000b4b46034cba9, 0x000cf35201f717ec, 0x000060bfeddfa2f6 }}, + {{ 0x00077eaf4cee5651, 0x000997d3fca4752b, 0x00086a9346dd5414, 0x0009165b5f12c094, 0x0000c95b968e8b8d }, { 0x000b6d88c7322484, 0x000a381fda78fd37, 0x000faae161f6e327, 0x000d9a7c4848a83a, 0x0000f137df7a291d }}, + {{ 0x000cc1bade2b6b43, 0x0007647ce417d99b, 0x0002cecfb1e654f4, 0x000bbf0234b93dcc, 0x00004be18fe3d4f5 }, { 0x0000e6a5a4e609ba, 0x00076114bc5ee855, 0x000470a83c3f2818, 0x000b337f1a561be7, 0x00002e0b52e72fc0 }}, + {{ 0x000ae9bcf25208f9, 0x000071fa00b500bb, 0x000ba2941103788d, 0x0003b71855c098cf, 0x0000543d6d693c3a }, { 0x000d4f3fa4da32f1, 0x00035838435a2c5b, 0x000b8e5e069e748f, 0x0009a03e38ceaed6, 0x0000c306dcaca2f2 }}, + {{ 0x0000ccfe8e6e9bc7, 0x000ea10a3db32927, 0x000a4469c7dc6903, 0x000ae1fa9e28a37d, 0x000071256bb0ed1f }, { 0x0008ff50ee6ae731, 0x000b3e03ba464b2d, 0x000dd3aa52a9b6ac, 0x00044e1ab0f39d60, 0x0000e50f6112c18d }}, + {{ 0x000bd9abbfb15903, 0x0000d58fa28a7e00, 0x0005001c40b5393d, 0x000c99366c726cf2, 0x0000598cccad0929 }, { 0x00032a8b5f2075fd, 0x000f2074dfc47b3a, 0x000269286dbe5403, 0x00032c0e2d9c65fc, 0x0000df0b4df59f16 }}, + {{ 0x000db8b22b2b7d9a, 0x000e26112e832330, 0x0002cf110cfd3ee9, 0x000fa75610fbb351, 0x0000c773f37679e1 }, { 0x000b47b17faba833, 0x0009efb89be01445, 0x00066f0f5fbb5ec7, 0x00061961c8c77d24, 0x0000cb969988de53 }}, + {{ 0x000d2b61710647ca, 0x000d8b016287b52d, 0x000ff3a22d3f5266, 0x0008dbb73a134351, 0x00001e8a651d5fbf }, { 0x000061da3d7648b8, 0x00081291da3b3b75, 0x0008b862d1d32fd2, 0x000cf1d835f946d7, 0x00009b66ecb267fb }}, + {{ 0x0005057a8f03a393, 0x000010dec1b49919, 0x0000a1ef0b1f2d70, 0x000769be0f12195e, 0x0000fd15ee98236f }, { 0x0007f25d916cad26, 0x000a3112e1301367, 0x0005bbd3af843715, 0x00053c82b97dfbb3, 0x000049bfae8df046 }}, + {{ 0x0001f37cbd3c62c7, 0x00088986d840cd64, 0x0000a440abcf9eb9, 0x00065da61471d62c, 0x00009f893242a192 }, { 0x000904261943916d, 0x000350f4b7099851, 0x000bd6a472422402, 0x000fcf7467a7bd33, 0x0000da56f786a44f }}, + {{ 0x00056fbb9354d802, 0x0008467cc36975fb, 0x0007e7ef6267c1ac, 0x00063a89402acf16, 0x000003023c61410c }, { 0x0001b7d9bedec678, 0x000950de9e405698, 0x000eb390c630ef9a, 0x0002b13977b99c65, 0x00009969974b5c5f }}, + {{ 0x0007c7289562f9a3, 0x00075c0c716cc0a1, 0x00006da1f3b47558, 0x0003bc7c6f4b5ff9, 0x00000ff02fe0d66b }, { 0x000283d331c15563, 0x000ed85da6be7de9, 0x000da07e001d37e7, 0x0009ee5e8ff71530, 0x00002b7baaf41117 }}, + {{ 0x000b9d6b1bdf4ea1, 0x0003c992a8498705, 0x000ae5b9f8196de5, 0x0004d3fe5a716964, 0x00004e830f707f38 }, { 0x000e1481a495c70b, 0x000ccd4a52f313bc, 0x000f9565c4bba5c4, 0x00077168fc9dd959, 0x0000dff7b5e2bd75 }}, + {{ 0x0004af860fe1d658, 0x0005c3a43228d831, 0x00003626b989c96b, 0x000ceba2924ae1c3, 0x0000c45b79310a64 }, { 0x0002ceb1de0d0667, 0x00088613f714aa18, 0x000d68a9c780c9b4, 0x000a36f94f51865a, 0x0000055e19d4f0d9 }}, + }, +}; + +#endif /* #if !defined(_DISABLE_ECP_256R1_HARDCODED_BP_TBL_) */ + +IPP_OWN_DEFN(const cpPrecompAP *, gfpec_precom_nistP256r1_radix52_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 7, + /* select function */ p256r1_select_ap_w7_ifma, + /* precomputed data */ (BNU_CHUNK_T *)ifma_ec_nistp256r1_bp_precomp + }; + return &t; +} + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif /* #ifndef IFMA_ECPRECOMP7_P256_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_norm.c b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_norm.c new file mode 100644 index 000000000..1eb0568e2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_norm.c @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include +#include +#include + +IPP_OWN_DEFN(m512, ifma_lnorm52, (const m512 a)) +{ + const m512 mask52 = set1_i64(DIGIT_MASK); + const m512 one = set1_i64(1ULL); + const mask64 mask_shift_carry = 0xffffffffffffff00; + + const m512 idxi8 = set_i64(0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908, // 15, 14, 13, 12, 11, 10, 9, 8 + 0x0706050403020100, // 7, 6, 5, 4, 3, 2, 1, 0 + 0x0); // 0, 0, 0, 0, 0, 0, 0, 0 + + m512 r = a; + int k1, k2; + m512 carry = srai_i64(r, DIGIT_SIZE); + carry = maskz_permutexvar_i8(mask_shift_carry, idxi8, carry); + + r = and_i64(r, mask52); + r = add_i64(r, carry); + + k2 = (int)(cmp_i64_mask(mask52, r, _MM_CMPINT_EQ)); + k1 = (int)(cmp_i64_mask(mask52, r, _MM_CMPINT_LT)); + + k1 = k2 + (k1 << 1); + k1 ^= k2; + + r = mask_add_i64(r, (mask8)(k1), r, one); + r = and_i64(r, mask52); + + return r; +} + +IPP_OWN_DEFN(void, ifma_lnorm52_dual, (m512 pr1[], const m512 a1, m512 pr2[], const m512 a2)) +{ + const m512 mask52 = set1_i64(DIGIT_MASK); + const m512 one = set1_i64(1UL); + const mask64 mask_shift_carry = 0xffffffffffffff00; + + const m512 idxi8 = set_i64(0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908, // 15, 14, 13, 12, 11, 10, 9, 8 + 0x0706050403020100, // 7, 6, 5, 4, 3, 2, 1, 0 + 0x0); // 0, 0, 0, 0, 0, 0, 0, 0 + + m512 r1 = a1; + m512 r2 = a2; + int k1_1, k1_2, k2_1, k2_2; + + m512 carry1 = srai_i64(r1, DIGIT_SIZE); + m512 carry2 = srai_i64(r2, DIGIT_SIZE); + carry1 = maskz_permutexvar_i8(mask_shift_carry, idxi8, carry1); + carry2 = maskz_permutexvar_i8(mask_shift_carry, idxi8, carry2); + + r1 = and_i64(r1, mask52); + r1 = add_i64(r1, carry1); + r2 = and_i64(r2, mask52); + r2 = add_i64(r2, carry2); + + k2_1 = (int)(cmp_i64_mask(mask52, r1, _MM_CMPINT_EQ)); + k1_1 = (int)(cmp_i64_mask(mask52, r1, _MM_CMPINT_LT)); + k2_2 = (int)(cmp_i64_mask(mask52, r2, _MM_CMPINT_EQ)); + k1_2 = (int)(cmp_i64_mask(mask52, r2, _MM_CMPINT_LT)); + + k1_1 = k2_1 + (k1_1 << 1); + k1_1 ^= k2_1; + k1_2 = k2_2 + (k1_2 << 1); + k1_2 ^= k2_2; + + r1 = mask_add_i64(r1, (mask8)(k1_1), r1, one); + r1 = and_i64(r1, mask52); + r2 = mask_add_i64(r2, (mask8)(k1_2), r2, one); + r2 = and_i64(r2, mask52); + + *pr1 = r1; + *pr2 = r2; + return; +} + + +IPP_OWN_DEFN(m512, ifma_norm52, (const m512 a)) +{ + const m512 mask52 = set1_i64(DIGIT_MASK); + const m512 one = set1_i64(1LL); + const m512 mone = set1_i64(-1LL); + const mask64 mask_shift_carry = 0xFFFFFFFFFFFFFF00; + + const m512 idxi8 = set_i64(0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908, // 15, 14, 13, 12, 11, 10, 9, 8 + 0x0706050403020100, // 7, 6, 5, 4, 3, 2, 1, 0 + 0x0); // 0, 0, 0, 0, 0, 0, 0, 0 + + m512 r = a; + + /* standart step - first round normalization */ + m512 carry = srai_i64(r, DIGIT_SIZE); + carry = maskz_permutexvar_i8(mask_shift_carry, idxi8, carry); + + r = and_i64(r, mask52); + r = add_i64(r, carry); + + /* create mask add ONE(1) to slot */ + int k2 = (int)(cmp_i64_mask(mask52, r, _MM_CMPINT_EQ)); /* (r) == 0xF(13) */ + int k1 = (int)(cmp_i64_mask(mask52, r, _MM_CMPINT_LT)); /* (r) > 0xF(13) */ + + k1 = k2 + (k1 << 1); + k1 ^= k2; + + r = mask_add_i64(r, (mask8)(k1), r, one); + + /* create mask add MINUS ONE(-1) to slot */ + const int cadd = 0x100; + + int ma = (int)(cmp_i64_mask(r, one, _MM_CMPINT_GE)); /* (r) >= 1 */ + int mb = (int)(cmp_i64_mask(r, setzero_i64(), _MM_CMPINT_LT)); /* (r) < 0 */ + + /* add 0x100 - we make a number from which we subtract intentionally more */ + ma += cadd; + /* we emulate a shift to a neighboring slot, + * as well as perform masking with 0xFF, + * so as NOT to get a number greater than from which we will subtract. + */ + mb = (mb << 1) & 0xFF; + + /* calculate loans */ + const int mc = ma - mb; + /* after the step above, the problem arises that after subtracting from (ma), + * we see dips of units (below in response) in those slots that do not need to add -1 + * and these slots can be determined if 3 conditions are met: + * 1) (ma) == 1 + * 2) (mb) == 0 + * 3) (mc) == 1 + */ + const int mx = ~(ma & (~mb) & mc); + /* add mask mx AND if there was a suppression of 1 in the slot - add minus 1 */ + const int mask_mone = (mx & mc) | (ma & ~mc); + + r = mask_add_i64(r, (mask8)mask_mone, r, mone); + r = and_i64(r, mask52); + + return r; +} + +IPP_OWN_DEFN(void, ifma_norm52_dual, (m512 pr1[], const m512 a1, m512 pr2[], const m512 a2)) +{ + const m512 mask52 = set1_i64(DIGIT_MASK); + const m512 one = set1_i64(1ULL); + const m512 mone = set1_i64(-1); + const mask64 mask_shift_carry = 0xFFFFFFFFFFFFFF00; + + const m512 idxi8 = set_i64(0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908, // 15, 14, 13, 12, 11, 10, 9, 8 + 0x0706050403020100, // 7, 6, 5, 4, 3, 2, 1, 0 + 0x0); // 0, 0, 0, 0, 0, 0, 0, 0 + + m512 r1 = a1; + m512 r2 = a2; + /* one */ + /* 1 */ + m512 carry1 = srai_i64(r1, DIGIT_SIZE); + carry1 = maskz_permutexvar_i8(mask_shift_carry, idxi8, carry1); + /* 2 */ + m512 carry2 = srai_i64(r2, DIGIT_SIZE); + carry2 = maskz_permutexvar_i8(mask_shift_carry, idxi8, carry2); + + /* 1 */ + r1 = and_i64(r1, mask52); + r1 = add_i64(r1, carry1); + + /* 2 */ + r2 = and_i64(r2, mask52); + r2 = add_i64(r2, carry2); + + /* add one slots */ + /* 1 */ + int k21 = (int)(cmp_i64_mask(mask52, r1, _MM_CMPINT_EQ)); + int k11 = (int)(cmp_i64_mask(mask52, r1, _MM_CMPINT_LT)); + /* 2 */ + int k22 = (int)(cmp_i64_mask(mask52, r2, _MM_CMPINT_EQ)); + int k12 = (int)(cmp_i64_mask(mask52, r2, _MM_CMPINT_LT)); + + /* 1 */ + k11 = k21 + (k11 << 1); + k11 ^= k21; + /* 2 */ + k12 = k22 + (k12 << 1); + k12 ^= k22; + + r1 = mask_add_i64(r1, (mask8)(k11), r1, one); + r2 = mask_add_i64(r2, (mask8)(k12), r2, one); + + /* add minus one in slots */ + const int cadd = 0x100; + + /* 1 */ + int ma1 = (int)(cmp_i64_mask(r1, one, _MM_CMPINT_GE)); + int mb1 = (int)(cmp_i64_mask(r1, setzero_i64(), _MM_CMPINT_LT)); + /* 2 */ + int ma2 = (int)(cmp_i64_mask(r2, one, _MM_CMPINT_GE)); + int mb2 = (int)(cmp_i64_mask(r2, setzero_i64(), _MM_CMPINT_LT)); + + /* 1 */ + ma1 += cadd; + mb1 = (mb1 << 1) & 0xFF; + /* 2 */ + ma2 += cadd; + mb2 = (mb2 << 1) & 0xFF; + + /* 1 */ + const int mc1 = ma1 - mb1; + const int mx1 = ~(ma1 & (~mb1) & mc1); + /* 2 */ + const int mc2 = ma2 - mb2; + const int mx2 = ~(ma2 & (~mb2) & mc2); + + const int mask_mone1 = (mx1 & mc1) | (ma1 & ~mc1); + const int mask_mone2 = (mx2 & mc2) | (ma2 & ~mc2); + + /* 1 */ + r1 = mask_add_i64(r1, (mask8)mask_mone1, r1, mone); + r1 = and_i64(r1, mask52); + /* 2 */ + r2 = mask_add_i64(r2, (mask8)mask_mone2, r2, mone); + r2 = and_i64(r2, mask52); + + *pr1 = r1; + *pr2 = r2; + return; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_norm.h b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_norm.h new file mode 100644 index 000000000..a4bcf4bb4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ecnist/ifma_norm.h @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ +#ifndef _IFMA_NORM_H_ +#define _IFMA_NORM_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ifma_alias_avx512.h" + +/** + * \brief + * + * Lightweight single-round normalization. Can be used after multiplication or + * addition only. + * + * \param[in] a ptr value (52 radix and more) + * \return m512 value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_lnorm52, (const m512 a)) + +/** + * \brief + * + * Dual variant of ifma_lnorm52() function. + * + * \param[out] pr1 ptr first value (in radix 2^52) + * \param[in] a1 value first (52 radix and more) + * \param[out] pr2 ptr second value (in radix 2^52) + * \param[in] a2 ptr value second (52 radix and more) + */ +IPP_OWN_DECL(void, ifma_lnorm52_dual, (m512 pr1[], const m512 a1, m512 pr2[], const m512 a2)) + +/** + * \brief + * + * Subtraction single-round normalization. Can be used after subtraction or other. + * + * \param[in] a ptr value (52 radix and more) + * \return m512 value (in radix 2^52) + */ +IPP_OWN_DECL(m512, ifma_norm52, (const m512 a)) + +/** + * \brief + * + * Dual variant of ifma_norm52() function. + * + * \param[out] pr1 ptr first value (in radix 2^52) + * \param[in] a1 value first (52 radix and more) + * \param[out] pr2 ptr second value (in radix 2^52) + * \param[in] a2 ptr value second (52 radix and more) + */ +IPP_OWN_DECL(void, ifma_norm52_dual, (m512 pr1[], const m512 a1, m512 pr2[], const m512 a2)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_NORM_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/emptyfile.c b/plugin/ippcp/library/src/sources/ippcp/emptyfile.c new file mode 100644 index 000000000..4cd910bbc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/emptyfile.c @@ -0,0 +1,20 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +typedef int to_avoid_translation_unit_is_empty_warning; + +/* The empty file to build a dynamic library in Visual Studio. The IDE does not produce a dll without source files */ diff --git a/plugin/ippcp/library/src/sources/ippcp/exports.linux.lib-export b/plugin/ippcp/library/src/sources/ippcp/exports.linux.lib-export new file mode 100644 index 000000000..0ac719ae3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/exports.linux.lib-export @@ -0,0 +1,1123 @@ +EXTERN (ippcpInit) +EXTERN (cpGetReg) +EXTERN (cpStartTscp) +EXTERN (cpStopTscp) +EXTERN (cpStartTsc) +EXTERN (cpStopTsc) +EXTERN (cpGetCacheSize) +EXTERN (cpGetFeature) +EXTERN (ippcpSetCpuFeatures) +EXTERN (ippcpGetCpuFeatures) +EXTERN (ippcpGetCpuClocks) +EXTERN (ippcpSetNumThreads) +EXTERN (ippcpGetNumThreads) +EXTERN (ippcpGetEnabledCpuFeatures) +EXTERN (ippcpGetEnabledNumThreads) +EXTERN (ippcpGetStatusString) + +EXTERN (ippcpGetLibVersion) +EXTERN (ippsDESGetSize) +EXTERN (ippsDESInit) +EXTERN (ippsDESPack) +EXTERN (ippsDESUnpack) +EXTERN (ippsTDESEncryptECB) +EXTERN (ippsTDESDecryptECB) +EXTERN (ippsTDESEncryptCBC) +EXTERN (ippsTDESDecryptCBC) +EXTERN (ippsTDESEncryptCFB) +EXTERN (ippsTDESDecryptCFB) +EXTERN (ippsTDESEncryptOFB) +EXTERN (ippsTDESDecryptOFB) +EXTERN (ippsTDESEncryptCTR) +EXTERN (ippsTDESDecryptCTR) +EXTERN (ippsAESGetSize) +EXTERN (ippsAESInit) +EXTERN (ippsAESSetKey) +EXTERN (ippsAESPack) +EXTERN (ippsAESUnpack) +EXTERN (ippsAESSetupNoise) +EXTERN (ippsAES_GCMSetupNoise) +EXTERN (ippsAES_CMACSetupNoise) +EXTERN (ippsAESEncryptECB) +EXTERN (ippsAESDecryptECB) +EXTERN (ippsAESEncryptCBC) +EXTERN (ippsAESEncryptCBC_CS1) +EXTERN (ippsAESEncryptCBC_CS2) +EXTERN (ippsAESEncryptCBC_CS3) +EXTERN (ippsAESDecryptCBC) +EXTERN (ippsAESDecryptCBC_CS1) +EXTERN (ippsAESDecryptCBC_CS2) +EXTERN (ippsAESDecryptCBC_CS3) +EXTERN (ippsAESEncryptCFB) +EXTERN (ippsAESDecryptCFB) +EXTERN (ippsAESEncryptOFB) +EXTERN (ippsAESDecryptOFB) +EXTERN (ippsAESEncryptCTR) +EXTERN (ippsAESDecryptCTR) +EXTERN (ippsAESEncryptXTS_Direct) +EXTERN (ippsAESDecryptXTS_Direct) +EXTERN (ippsAES_EncryptCFB16_MB) +EXTERN (ippsSMS4GetSize) +EXTERN (ippsSMS4Init) +EXTERN (ippsSMS4SetKey) +EXTERN (ippsSMS4EncryptECB) +EXTERN (ippsSMS4DecryptECB) +EXTERN (ippsSMS4EncryptCBC) +EXTERN (ippsSMS4EncryptCBC_CS1) +EXTERN (ippsSMS4EncryptCBC_CS2) +EXTERN (ippsSMS4EncryptCBC_CS3) +EXTERN (ippsSMS4DecryptCBC) +EXTERN (ippsSMS4DecryptCBC_CS1) +EXTERN (ippsSMS4DecryptCBC_CS2) +EXTERN (ippsSMS4DecryptCBC_CS3) +EXTERN (ippsSMS4EncryptCFB) +EXTERN (ippsSMS4DecryptCFB) +EXTERN (ippsSMS4EncryptOFB) +EXTERN (ippsSMS4DecryptOFB) +EXTERN (ippsSMS4EncryptCTR) +EXTERN (ippsSMS4DecryptCTR) +EXTERN (ippsSMS4_CCMGetSize) +EXTERN (ippsSMS4_CCMInit) +EXTERN (ippsSMS4_CCMMessageLen) +EXTERN (ippsSMS4_CCMTagLen) +EXTERN (ippsSMS4_CCMStart) +EXTERN (ippsSMS4_CCMEncrypt) +EXTERN (ippsSMS4_CCMDecrypt) +EXTERN (ippsSMS4_CCMGetTag) +EXTERN (ippsAES_CCMGetSize) +EXTERN (ippsAES_CCMInit) +EXTERN (ippsAES_CCMMessageLen) +EXTERN (ippsAES_CCMTagLen) +EXTERN (ippsAES_CCMStart) +EXTERN (ippsAES_CCMEncrypt) +EXTERN (ippsAES_CCMDecrypt) +EXTERN (ippsAES_CCMGetTag) +EXTERN (ippsAES_GCMGetSize) +EXTERN (ippsAES_GCMInit) +EXTERN (ippsAES_GCMReinit) +EXTERN (ippsAES_GCMReset) +EXTERN (ippsAES_GCMProcessIV) +EXTERN (ippsAES_GCMProcessAAD) +EXTERN (ippsAES_GCMStart) +EXTERN (ippsAES_GCMEncrypt) +EXTERN (ippsAES_GCMDecrypt) +EXTERN (ippsAES_GCMGetTag) +EXTERN (ippsAES_XTSGetSize) +EXTERN (ippsAES_XTSInit) +EXTERN (ippsAES_XTSEncrypt) +EXTERN (ippsAES_XTSDecrypt) +EXTERN (ippsAES_S2V_CMAC) +EXTERN (ippsAES_SIVEncrypt) +EXTERN (ippsAES_SIVDecrypt) +EXTERN (ippsAES_CMACGetSize) +EXTERN (ippsAES_CMACInit) +EXTERN (ippsAES_CMACUpdate) +EXTERN (ippsAES_CMACFinal) +EXTERN (ippsAES_CMACGetTag) +EXTERN (ippsARCFourCheckKey) +EXTERN (ippsARCFourGetSize) +EXTERN (ippsARCFourInit) +EXTERN (ippsARCFourReset) +EXTERN (ippsARCFourPack) +EXTERN (ippsARCFourUnpack) +EXTERN (ippsARCFourEncrypt) +EXTERN (ippsARCFourDecrypt) +EXTERN (ippsSHA1GetSize) +EXTERN (ippsSHA1Init) +EXTERN (ippsSHA1Duplicate) +EXTERN (ippsSHA1Pack) +EXTERN (ippsSHA1Unpack) +EXTERN (ippsSHA1Update) +EXTERN (ippsSHA1GetTag) +EXTERN (ippsSHA1Final) +EXTERN (ippsSHA1MessageDigest) +EXTERN (ippsSHA224GetSize) +EXTERN (ippsSHA224Init) +EXTERN (ippsSHA224Duplicate) +EXTERN (ippsSHA224Pack) +EXTERN (ippsSHA224Unpack) +EXTERN (ippsSHA224Update) +EXTERN (ippsSHA224GetTag) +EXTERN (ippsSHA224Final) +EXTERN (ippsSHA224MessageDigest) +EXTERN (ippsSHA256GetSize) +EXTERN (ippsSHA256Init) +EXTERN (ippsSHA256Duplicate) +EXTERN (ippsSHA256Pack) +EXTERN (ippsSHA256Unpack) +EXTERN (ippsSHA256Update) +EXTERN (ippsSHA256GetTag) +EXTERN (ippsSHA256Final) +EXTERN (ippsSHA256MessageDigest) +EXTERN (ippsSHA384GetSize) +EXTERN (ippsSHA384Init) +EXTERN (ippsSHA384Duplicate) +EXTERN (ippsSHA384Pack) +EXTERN (ippsSHA384Unpack) +EXTERN (ippsSHA384Update) +EXTERN (ippsSHA384GetTag) +EXTERN (ippsSHA384Final) +EXTERN (ippsSHA384MessageDigest) +EXTERN (ippsSHA512GetSize) +EXTERN (ippsSHA512Init) +EXTERN (ippsSHA512Duplicate) +EXTERN (ippsSHA512Pack) +EXTERN (ippsSHA512Unpack) +EXTERN (ippsSHA512Update) +EXTERN (ippsSHA512GetTag) +EXTERN (ippsSHA512Final) +EXTERN (ippsSHA512MessageDigest) +EXTERN (ippsMD5GetSize) +EXTERN (ippsMD5Init) +EXTERN (ippsMD5Duplicate) +EXTERN (ippsMD5Pack) +EXTERN (ippsMD5Unpack) +EXTERN (ippsMD5Update) +EXTERN (ippsMD5GetTag) +EXTERN (ippsMD5Final) +EXTERN (ippsMD5MessageDigest) +EXTERN (ippsSM3GetSize) +EXTERN (ippsSM3Init) +EXTERN (ippsSM3Duplicate) +EXTERN (ippsSM3Pack) +EXTERN (ippsSM3Unpack) +EXTERN (ippsSM3Update) +EXTERN (ippsSM3GetTag) +EXTERN (ippsSM3Final) +EXTERN (ippsSM3MessageDigest) +EXTERN (ippsHashGetSize) +EXTERN (ippsHashInit) +EXTERN (ippsHashPack) +EXTERN (ippsHashUnpack) +EXTERN (ippsHashDuplicate) +EXTERN (ippsHashUpdate) +EXTERN (ippsHashGetTag) +EXTERN (ippsHashFinal) +EXTERN (ippsHashMessage) +EXTERN (ippsHashMethodGetSize) +EXTERN (ippsHashMethodSet_MD5) +EXTERN (ippsHashMethodSet_SM3) +EXTERN (ippsHashMethodSet_SHA1) +EXTERN (ippsHashMethodSet_SHA1_NI) +EXTERN (ippsHashMethodSet_SHA1_TT) +EXTERN (ippsHashMethodSet_SHA256) +EXTERN (ippsHashMethodSet_SHA256_NI) +EXTERN (ippsHashMethodSet_SHA256_TT) +EXTERN (ippsHashMethodSet_SHA224) +EXTERN (ippsHashMethodSet_SHA224_NI) +EXTERN (ippsHashMethodSet_SHA224_TT) +EXTERN (ippsHashMethodSet_SHA512) +EXTERN (ippsHashMethodSet_SHA384) +EXTERN (ippsHashMethodSet_SHA512_256) +EXTERN (ippsHashMethodSet_SHA512_224) +EXTERN (ippsHashStateMethodSet_SM3) +EXTERN (ippsHashStateMethodSet_SHA256) +EXTERN (ippsHashStateMethodSet_SHA256_NI) +EXTERN (ippsHashStateMethodSet_SHA256_TT) +EXTERN (ippsHashStateMethodSet_SHA224) +EXTERN (ippsHashStateMethodSet_SHA224_NI) +EXTERN (ippsHashStateMethodSet_SHA224_TT) +EXTERN (ippsHashStateMethodSet_SHA512) +EXTERN (ippsHashStateMethodSet_SHA384) +EXTERN (ippsHashStateMethodSet_SHA512_256) +EXTERN (ippsHashStateMethodSet_SHA512_224) +EXTERN (ippsHashMethod_MD5) +EXTERN (ippsHashMethod_SM3) +EXTERN (ippsHashMethod_SHA1) +EXTERN (ippsHashMethod_SHA1_NI) +EXTERN (ippsHashMethod_SHA1_TT) +EXTERN (ippsHashMethod_SHA256) +EXTERN (ippsHashMethod_SHA256_NI) +EXTERN (ippsHashMethod_SHA256_TT) +EXTERN (ippsHashMethod_SHA224) +EXTERN (ippsHashMethod_SHA224_NI) +EXTERN (ippsHashMethod_SHA224_TT) +EXTERN (ippsHashMethod_SHA512) +EXTERN (ippsHashMethod_SHA384) +EXTERN (ippsHashMethod_SHA512_256) +EXTERN (ippsHashMethod_SHA512_224) +EXTERN (ippsHashMethodGetInfo) +EXTERN (ippsHashGetSize_rmf) +EXTERN (ippsHashInit_rmf) +EXTERN (ippsHashPack_rmf) +EXTERN (ippsHashUnpack_rmf) +EXTERN (ippsHashDuplicate_rmf) +EXTERN (ippsHashUpdate_rmf) +EXTERN (ippsHashGetTag_rmf) +EXTERN (ippsHashFinal_rmf) +EXTERN (ippsHashMessage_rmf) +EXTERN (ippsHashGetInfo_rmf) +EXTERN (ippsMGF) +EXTERN (ippsMGF1_rmf) +EXTERN (ippsMGF2_rmf) +EXTERN (ippsHMAC_GetSize) +EXTERN (ippsHMAC_Init) +EXTERN (ippsHMAC_Pack) +EXTERN (ippsHMAC_Unpack) +EXTERN (ippsHMAC_Duplicate) +EXTERN (ippsHMAC_Update) +EXTERN (ippsHMAC_Final) +EXTERN (ippsHMAC_GetTag) +EXTERN (ippsHMAC_Message) +EXTERN (ippsHMACGetSize_rmf) +EXTERN (ippsHMACInit_rmf) +EXTERN (ippsHMACPack_rmf) +EXTERN (ippsHMACUnpack_rmf) +EXTERN (ippsHMACDuplicate_rmf) +EXTERN (ippsHMACUpdate_rmf) +EXTERN (ippsHMACFinal_rmf) +EXTERN (ippsHMACGetTag_rmf) +EXTERN (ippsHMACMessage_rmf) +EXTERN (ippsBigNumGetSize) +EXTERN (ippsBigNumInit) +EXTERN (ippsCmpZero_BN) +EXTERN (ippsCmp_BN) +EXTERN (ippsGetSize_BN) +EXTERN (ippsSet_BN) +EXTERN (ippsGet_BN) +EXTERN (ippsRef_BN) +EXTERN (ippsExtGet_BN) +EXTERN (ippsAdd_BN) +EXTERN (ippsSub_BN) +EXTERN (ippsMul_BN) +EXTERN (ippsMAC_BN_I) +EXTERN (ippsDiv_BN) +EXTERN (ippsMod_BN) +EXTERN (ippsGcd_BN) +EXTERN (ippsModInv_BN) +EXTERN (ippsSetOctString_BN) +EXTERN (ippsGetOctString_BN) +EXTERN (ippsMontGetSize) +EXTERN (ippsMontInit) +EXTERN (ippsMontSet) +EXTERN (ippsMontGet) +EXTERN (ippsMontForm) +EXTERN (ippsMontMul) +EXTERN (ippsMontExp) +EXTERN (ippsPRNGGetSize) +EXTERN (ippsPRNGInit) +EXTERN (ippsPRNGSetModulus) +EXTERN (ippsPRNGSetH0) +EXTERN (ippsPRNGSetAugment) +EXTERN (ippsPRNGSetSeed) +EXTERN (ippsPRNGGetSeed) +EXTERN (ippsPRNGen) +EXTERN (ippsPRNGen_BN) +EXTERN (ippsPRNGenRDRAND) +EXTERN (ippsPRNGenRDRAND_BN) +EXTERN (ippsTRNGenRDSEED) +EXTERN (ippsTRNGenRDSEED_BN) +EXTERN (ippsPrimeGetSize) +EXTERN (ippsPrimeInit) +EXTERN (ippsPrimeGen) +EXTERN (ippsPrimeTest) +EXTERN (ippsPrimeGen_BN) +EXTERN (ippsPrimeTest_BN) +EXTERN (ippsPrimeGet) +EXTERN (ippsPrimeGet_BN) +EXTERN (ippsPrimeSet) +EXTERN (ippsPrimeSet_BN) +EXTERN (ippsRSA_GetSizePublicKey) +EXTERN (ippsRSA_InitPublicKey) +EXTERN (ippsRSA_SetPublicKey) +EXTERN (ippsRSA_GetPublicKey) +EXTERN (ippsRSA_GetSizePrivateKeyType1) +EXTERN (ippsRSA_InitPrivateKeyType1) +EXTERN (ippsRSA_SetPrivateKeyType1) +EXTERN (ippsRSA_GetPrivateKeyType1) +EXTERN (ippsRSA_GetSizePrivateKeyType2) +EXTERN (ippsRSA_InitPrivateKeyType2) +EXTERN (ippsRSA_SetPrivateKeyType2) +EXTERN (ippsRSA_GetPrivateKeyType2) +EXTERN (ippsRSA_GetBufferSizePublicKey) +EXTERN (ippsRSA_GetBufferSizePrivateKey) +EXTERN (ippsRSA_Encrypt) +EXTERN (ippsRSA_Decrypt) +EXTERN (ippsRSA_GenerateKeys) +EXTERN (ippsRSA_ValidateKeys) +EXTERN (ippsRSAEncrypt_OAEP) +EXTERN (ippsRSADecrypt_OAEP) +EXTERN (ippsRSAEncrypt_OAEP_rmf) +EXTERN (ippsRSADecrypt_OAEP_rmf) +EXTERN (ippsRSAEncrypt_PKCSv15) +EXTERN (ippsRSADecrypt_PKCSv15) +EXTERN (ippsRSASign_PSS) +EXTERN (ippsRSAVerify_PSS) +EXTERN (ippsRSASign_PSS_rmf) +EXTERN (ippsRSAVerify_PSS_rmf) +EXTERN (ippsRSASign_PKCS1v15) +EXTERN (ippsRSAVerify_PKCS1v15) +EXTERN (ippsRSASign_PKCS1v15_rmf) +EXTERN (ippsRSAVerify_PKCS1v15_rmf) +EXTERN (ippsDLGetResultString) +EXTERN (ippsDLPGetSize) +EXTERN (ippsDLPInit) +EXTERN (ippsDLPPack) +EXTERN (ippsDLPUnpack) +EXTERN (ippsDLPSet) +EXTERN (ippsDLPGet) +EXTERN (ippsDLPSetDP) +EXTERN (ippsDLPGetDP) +EXTERN (ippsDLPGenKeyPair) +EXTERN (ippsDLPPublicKey) +EXTERN (ippsDLPValidateKeyPair) +EXTERN (ippsDLPSetKeyPair) +EXTERN (ippsDLPSignDSA) +EXTERN (ippsDLPVerifyDSA) +EXTERN (ippsDLPSharedSecretDH) +EXTERN (ippsDLPGenerateDSA) +EXTERN (ippsDLPValidateDSA) +EXTERN (ippsDLPGenerateDH) +EXTERN (ippsDLPValidateDH) +EXTERN (ippsECCGetResultString) +EXTERN (ippsECCPGetSize) +EXTERN (ippsECCPGetSizeStd128r1) +EXTERN (ippsECCPGetSizeStd128r2) +EXTERN (ippsECCPGetSizeStd192r1) +EXTERN (ippsECCPGetSizeStd224r1) +EXTERN (ippsECCPGetSizeStd256r1) +EXTERN (ippsECCPGetSizeStd384r1) +EXTERN (ippsECCPGetSizeStd521r1) +EXTERN (ippsECCPGetSizeStdSM2) +EXTERN (ippsECCPInit) +EXTERN (ippsECCPInitStd128r1) +EXTERN (ippsECCPInitStd128r2) +EXTERN (ippsECCPInitStd192r1) +EXTERN (ippsECCPInitStd224r1) +EXTERN (ippsECCPInitStd256r1) +EXTERN (ippsECCPInitStd384r1) +EXTERN (ippsECCPInitStd521r1) +EXTERN (ippsECCPInitStdSM2) +EXTERN (ippsECCPSet) +EXTERN (ippsECCPSetStd) +EXTERN (ippsECCPSetStd128r1) +EXTERN (ippsECCPSetStd128r2) +EXTERN (ippsECCPSetStd192r1) +EXTERN (ippsECCPSetStd224r1) +EXTERN (ippsECCPSetStd256r1) +EXTERN (ippsECCPSetStd384r1) +EXTERN (ippsECCPSetStd521r1) +EXTERN (ippsECCPSetStdSM2) +EXTERN (ippsECCPBindGxyTblStd192r1) +EXTERN (ippsECCPBindGxyTblStd224r1) +EXTERN (ippsECCPBindGxyTblStd256r1) +EXTERN (ippsECCPBindGxyTblStd384r1) +EXTERN (ippsECCPBindGxyTblStd521r1) +EXTERN (ippsECCPBindGxyTblStdSM2) +EXTERN (ippsECCPGet) +EXTERN (ippsECCPGetOrderBitSize) +EXTERN (ippsECCPValidate) +EXTERN (ippsECCPPointGetSize) +EXTERN (ippsECCPPointInit) +EXTERN (ippsECCPSetPoint) +EXTERN (ippsECCPSetPointAtInfinity) +EXTERN (ippsECCPGetPoint) +EXTERN (ippsECCPCheckPoint) +EXTERN (ippsECCPComparePoint) +EXTERN (ippsECCPNegativePoint) +EXTERN (ippsECCPAddPoint) +EXTERN (ippsECCPMulPointScalar) +EXTERN (ippsECCPGenKeyPair) +EXTERN (ippsECCPPublicKey) +EXTERN (ippsECCPValidateKeyPair) +EXTERN (ippsECCPSetKeyPair) +EXTERN (ippsECCPSharedSecretDH) +EXTERN (ippsECCPSharedSecretDHC) +EXTERN (ippsECCPSignDSA) +EXTERN (ippsECCPVerifyDSA) +EXTERN (ippsECCPSignNR) +EXTERN (ippsECCPVerifyNR) +EXTERN (ippsECCPSignSM2) +EXTERN (ippsECCPVerifySM2) +EXTERN (ippsGFpGetSize) +EXTERN (ippsGFpInitArbitrary) +EXTERN (ippsGFpInitFixed) +EXTERN (ippsGFpInit) +EXTERN (ippsGFpMethod_p192r1) +EXTERN (ippsGFpMethod_p224r1) +EXTERN (ippsGFpMethod_p256r1) +EXTERN (ippsGFpMethod_p384r1) +EXTERN (ippsGFpMethod_p521r1) +EXTERN (ippsGFpMethod_p256sm2) +EXTERN (ippsGFpMethod_p256bn) +EXTERN (ippsGFpMethod_p256) +EXTERN (ippsGFpMethod_pArb) +EXTERN (ippsGFpxGetSize) +EXTERN (ippsGFpxInit) +EXTERN (ippsGFpxInitBinomial) +EXTERN (ippsGFpxMethod_binom2_epid2) +EXTERN (ippsGFpxMethod_binom3_epid2) +EXTERN (ippsGFpxMethod_binom2) +EXTERN (ippsGFpxMethod_binom3) +EXTERN (ippsGFpxMethod_binom) +EXTERN (ippsGFpxMethod_com) +EXTERN (ippsGFpScratchBufferSize) +EXTERN (ippsGFpElementGetSize) +EXTERN (ippsGFpElementInit) +EXTERN (ippsGFpSetElement) +EXTERN (ippsGFpSetElementRegular) +EXTERN (ippsGFpSetElementOctString) +EXTERN (ippsGFpSetElementRandom) +EXTERN (ippsGFpSetElementHash) +EXTERN (ippsGFpSetElementHash_rmf) +EXTERN (ippsGFpCpyElement) +EXTERN (ippsGFpGetElement) +EXTERN (ippsGFpGetElementOctString) +EXTERN (ippsGFpCmpElement) +EXTERN (ippsGFpIsZeroElement) +EXTERN (ippsGFpIsUnityElement) +EXTERN (ippsGFpConj) +EXTERN (ippsGFpNeg) +EXTERN (ippsGFpInv) +EXTERN (ippsGFpSqrt) +EXTERN (ippsGFpSqr) +EXTERN (ippsGFpAdd) +EXTERN (ippsGFpSub) +EXTERN (ippsGFpMul) +EXTERN (ippsGFpExp) +EXTERN (ippsGFpMultiExp) +EXTERN (ippsGFpAdd_PE) +EXTERN (ippsGFpSub_PE) +EXTERN (ippsGFpMul_PE) +EXTERN (ippsGFpGetInfo) +EXTERN (ippsGFpECGetSize) +EXTERN (ippsGFpECInit) +EXTERN (ippsGFpECSet) +EXTERN (ippsGFpECSetSubgroup) +EXTERN (ippsGFpECInitStd128r1) +EXTERN (ippsGFpECInitStd128r2) +EXTERN (ippsGFpECInitStd192r1) +EXTERN (ippsGFpECInitStd224r1) +EXTERN (ippsGFpECInitStd256r1) +EXTERN (ippsGFpECInitStd384r1) +EXTERN (ippsGFpECInitStd521r1) +EXTERN (ippsGFpECInitStdSM2) +EXTERN (ippsGFpECInitStdBN256) +EXTERN (ippsGFpECBindGxyTblStd192r1) +EXTERN (ippsGFpECBindGxyTblStd224r1) +EXTERN (ippsGFpECBindGxyTblStd256r1) +EXTERN (ippsGFpECBindGxyTblStd384r1) +EXTERN (ippsGFpECBindGxyTblStd521r1) +EXTERN (ippsGFpECBindGxyTblStdSM2) +EXTERN (ippsGFpECGet) +EXTERN (ippsGFpECGetInfo_GF) +EXTERN (ippsGFpECGetSubgroup) +EXTERN (ippsGFpECScratchBufferSize) +EXTERN (ippsGFpECVerify) +EXTERN (ippsGFpECPointGetSize) +EXTERN (ippsGFpECPointInit) +EXTERN (ippsGFpECSetPointAtInfinity) +EXTERN (ippsGFpECSetPoint) +EXTERN (ippsGFpECSetPointRegular) +EXTERN (ippsGFpECSetPointRandom) +EXTERN (ippsGFpECMakePoint) +EXTERN (ippsGFpECSetPointHash) +EXTERN (ippsGFpECSetPointHash_rmf) +EXTERN (ippsGFpECSetPointHashBackCompatible) +EXTERN (ippsGFpECSetPointHashBackCompatible_rmf) +EXTERN (ippsGFpECGetPoint) +EXTERN (ippsGFpECGetPointRegular) +EXTERN (ippsGFpECTstPoint) +EXTERN (ippsGFpECTstPointInSubgroup) +EXTERN (ippsGFpECCpyPoint) +EXTERN (ippsGFpECCmpPoint) +EXTERN (ippsGFpECNegPoint) +EXTERN (ippsGFpECAddPoint) +EXTERN (ippsGFpECMulPoint) +EXTERN (ippsGFpECPrivateKey) +EXTERN (ippsGFpECPublicKey) +EXTERN (ippsGFpECTstKeyPair) +EXTERN (ippsGFpECSharedSecretDH) +EXTERN (ippsGFpECSharedSecretDHC) +EXTERN (ippsGFpECSignDSA) +EXTERN (ippsGFpECVerifyDSA) +EXTERN (ippsGFpECSignNR) +EXTERN (ippsGFpECVerifyNR) +EXTERN (ippsGFpECSignSM2) +EXTERN (ippsGFpECVerifySM2) +EXTERN (ippsGFpECUserIDHashSM2) +EXTERN (ippsGFpECMessageRepresentationSM2) +EXTERN (ippsGFpECKeyExchangeSM2_GetSize) +EXTERN (ippsGFpECKeyExchangeSM2_Init) +EXTERN (ippsGFpECKeyExchangeSM2_Setup) +EXTERN (ippsGFpECKeyExchangeSM2_SharedKey) +EXTERN (ippsGFpECKeyExchangeSM2_Confirm) +EXTERN (ippsGFpECEncryptSM2_Ext_EncMsgSize) +EXTERN (ippsGFpECEncryptSM2_Ext) +EXTERN (ippsGFpECDecryptSM2_Ext_DecMsgSize) +EXTERN (ippsGFpECDecryptSM2_Ext) +EXTERN (ippsGFpECESGetSize_SM2) +EXTERN (ippsGFpECESInit_SM2) +EXTERN (ippsGFpECESSetKey_SM2) +EXTERN (ippsGFpECESStart_SM2) +EXTERN (ippsGFpECESEncrypt_SM2) +EXTERN (ippsGFpECESDecrypt_SM2) +EXTERN (ippsGFpECESFinal_SM2) +EXTERN (ippsGFpECESGetBuffersSize_SM2) +EXTERN (ippsGFpECSetPointOctString) +EXTERN (ippsGFpECGetPointOctString) + +VERSION { + { + global: + ippcpInit; + cpGetReg; + cpStartTscp; + cpStopTscp; + cpStartTsc; + cpStopTsc; + cpGetCacheSize; + cpGetFeature; + ippcpSetCpuFeatures; + ippcpGetCpuFeatures; + ippcpGetCpuClocks; + ippcpSetNumThreads; + ippcpGetNumThreads; + ippcpGetEnabledCpuFeatures; + ippcpGetEnabledNumThreads; + ippcpGetStatusString; + + ippcpGetLibVersion; + ippsDESGetSize; + ippsDESInit; + ippsDESPack; + ippsDESUnpack; + ippsTDESEncryptECB; + ippsTDESDecryptECB; + ippsTDESEncryptCBC; + ippsTDESDecryptCBC; + ippsTDESEncryptCFB; + ippsTDESDecryptCFB; + ippsTDESEncryptOFB; + ippsTDESDecryptOFB; + ippsTDESEncryptCTR; + ippsTDESDecryptCTR; + ippsAESGetSize; + ippsAESInit; + ippsAESSetKey; + ippsAESPack; + ippsAESUnpack; + ippsAESSetupNoise; + ippsAES_GCMSetupNoise; + ippsAES_CMACSetupNoise; + ippsAESEncryptECB; + ippsAESDecryptECB; + ippsAESEncryptCBC; + ippsAESEncryptCBC_CS1; + ippsAESEncryptCBC_CS2; + ippsAESEncryptCBC_CS3; + ippsAESDecryptCBC; + ippsAESDecryptCBC_CS1; + ippsAESDecryptCBC_CS2; + ippsAESDecryptCBC_CS3; + ippsAESEncryptCFB; + ippsAESDecryptCFB; + ippsAESEncryptOFB; + ippsAESDecryptOFB; + ippsAESEncryptCTR; + ippsAESDecryptCTR; + ippsAESEncryptXTS_Direct; + ippsAESDecryptXTS_Direct; + ippsAES_EncryptCFB16_MB; + ippsSMS4GetSize; + ippsSMS4Init; + ippsSMS4SetKey; + ippsSMS4EncryptECB; + ippsSMS4DecryptECB; + ippsSMS4EncryptCBC; + ippsSMS4EncryptCBC_CS1; + ippsSMS4EncryptCBC_CS2; + ippsSMS4EncryptCBC_CS3; + ippsSMS4DecryptCBC; + ippsSMS4DecryptCBC_CS1; + ippsSMS4DecryptCBC_CS2; + ippsSMS4DecryptCBC_CS3; + ippsSMS4EncryptCFB; + ippsSMS4DecryptCFB; + ippsSMS4EncryptOFB; + ippsSMS4DecryptOFB; + ippsSMS4EncryptCTR; + ippsSMS4DecryptCTR; + ippsSMS4_CCMGetSize; + ippsSMS4_CCMInit; + ippsSMS4_CCMMessageLen; + ippsSMS4_CCMTagLen; + ippsSMS4_CCMStart; + ippsSMS4_CCMEncrypt; + ippsSMS4_CCMDecrypt; + ippsSMS4_CCMGetTag; + ippsAES_CCMGetSize; + ippsAES_CCMInit; + ippsAES_CCMMessageLen; + ippsAES_CCMTagLen; + ippsAES_CCMStart; + ippsAES_CCMEncrypt; + ippsAES_CCMDecrypt; + ippsAES_CCMGetTag; + ippsAES_GCMGetSize; + ippsAES_GCMInit; + ippsAES_GCMReinit; + ippsAES_GCMReset; + ippsAES_GCMProcessIV; + ippsAES_GCMProcessAAD; + ippsAES_GCMStart; + ippsAES_GCMEncrypt; + ippsAES_GCMDecrypt; + ippsAES_GCMGetTag; + ippsAES_XTSGetSize; + ippsAES_XTSInit; + ippsAES_XTSEncrypt; + ippsAES_XTSDecrypt; + ippsAES_S2V_CMAC; + ippsAES_SIVEncrypt; + ippsAES_SIVDecrypt; + ippsAES_CMACGetSize; + ippsAES_CMACInit; + ippsAES_CMACUpdate; + ippsAES_CMACFinal; + ippsAES_CMACGetTag; + ippsARCFourCheckKey; + ippsARCFourGetSize; + ippsARCFourInit; + ippsARCFourReset; + ippsARCFourPack; + ippsARCFourUnpack; + ippsARCFourEncrypt; + ippsARCFourDecrypt; + ippsSHA1GetSize; + ippsSHA1Init; + ippsSHA1Duplicate; + ippsSHA1Pack; + ippsSHA1Unpack; + ippsSHA1Update; + ippsSHA1GetTag; + ippsSHA1Final; + ippsSHA1MessageDigest; + ippsSHA224GetSize; + ippsSHA224Init; + ippsSHA224Duplicate; + ippsSHA224Pack; + ippsSHA224Unpack; + ippsSHA224Update; + ippsSHA224GetTag; + ippsSHA224Final; + ippsSHA224MessageDigest; + ippsSHA256GetSize; + ippsSHA256Init; + ippsSHA256Duplicate; + ippsSHA256Pack; + ippsSHA256Unpack; + ippsSHA256Update; + ippsSHA256GetTag; + ippsSHA256Final; + ippsSHA256MessageDigest; + ippsSHA384GetSize; + ippsSHA384Init; + ippsSHA384Duplicate; + ippsSHA384Pack; + ippsSHA384Unpack; + ippsSHA384Update; + ippsSHA384GetTag; + ippsSHA384Final; + ippsSHA384MessageDigest; + ippsSHA512GetSize; + ippsSHA512Init; + ippsSHA512Duplicate; + ippsSHA512Pack; + ippsSHA512Unpack; + ippsSHA512Update; + ippsSHA512GetTag; + ippsSHA512Final; + ippsSHA512MessageDigest; + ippsMD5GetSize; + ippsMD5Init; + ippsMD5Duplicate; + ippsMD5Pack; + ippsMD5Unpack; + ippsMD5Update; + ippsMD5GetTag; + ippsMD5Final; + ippsMD5MessageDigest; + ippsSM3GetSize; + ippsSM3Init; + ippsSM3Duplicate; + ippsSM3Pack; + ippsSM3Unpack; + ippsSM3Update; + ippsSM3GetTag; + ippsSM3Final; + ippsSM3MessageDigest; + ippsHashGetSize; + ippsHashInit; + ippsHashPack; + ippsHashUnpack; + ippsHashDuplicate; + ippsHashUpdate; + ippsHashGetTag; + ippsHashFinal; + ippsHashMessage; + ippsHashMethodGetSize; + ippsHashMethodSet_MD5; + ippsHashMethodSet_SM3; + ippsHashMethodSet_SHA1; + ippsHashMethodSet_SHA1_NI; + ippsHashMethodSet_SHA1_TT; + ippsHashMethodSet_SHA256; + ippsHashMethodSet_SHA256_NI; + ippsHashMethodSet_SHA256_TT; + ippsHashMethodSet_SHA224; + ippsHashMethodSet_SHA224_NI; + ippsHashMethodSet_SHA224_TT; + ippsHashMethodSet_SHA512; + ippsHashMethodSet_SHA384; + ippsHashMethodSet_SHA512_256; + ippsHashMethodSet_SHA512_224; + ippsHashStateMethodSet_SM3; + ippsHashStateMethodSet_SHA256; + ippsHashStateMethodSet_SHA256_NI; + ippsHashStateMethodSet_SHA256_TT; + ippsHashStateMethodSet_SHA224; + ippsHashStateMethodSet_SHA224_NI; + ippsHashStateMethodSet_SHA224_TT; + ippsHashStateMethodSet_SHA512; + ippsHashStateMethodSet_SHA384; + ippsHashStateMethodSet_SHA512_256; + ippsHashStateMethodSet_SHA512_224; + ippsHashMethod_MD5; + ippsHashMethod_SM3; + ippsHashMethod_SHA1; + ippsHashMethod_SHA1_NI; + ippsHashMethod_SHA1_TT; + ippsHashMethod_SHA256; + ippsHashMethod_SHA256_NI; + ippsHashMethod_SHA256_TT; + ippsHashMethod_SHA224; + ippsHashMethod_SHA224_NI; + ippsHashMethod_SHA224_TT; + ippsHashMethod_SHA512; + ippsHashMethod_SHA384; + ippsHashMethod_SHA512_256; + ippsHashMethod_SHA512_224; + ippsHashMethodGetInfo; + ippsHashGetSize_rmf; + ippsHashInit_rmf; + ippsHashPack_rmf; + ippsHashUnpack_rmf; + ippsHashDuplicate_rmf; + ippsHashUpdate_rmf; + ippsHashGetTag_rmf; + ippsHashFinal_rmf; + ippsHashMessage_rmf; + ippsHashGetInfo_rmf; + ippsMGF; + ippsMGF1_rmf; + ippsMGF2_rmf; + ippsHMAC_GetSize; + ippsHMAC_Init; + ippsHMAC_Pack; + ippsHMAC_Unpack; + ippsHMAC_Duplicate; + ippsHMAC_Update; + ippsHMAC_Final; + ippsHMAC_GetTag; + ippsHMAC_Message; + ippsHMACGetSize_rmf; + ippsHMACInit_rmf; + ippsHMACPack_rmf; + ippsHMACUnpack_rmf; + ippsHMACDuplicate_rmf; + ippsHMACUpdate_rmf; + ippsHMACFinal_rmf; + ippsHMACGetTag_rmf; + ippsHMACMessage_rmf; + ippsBigNumGetSize; + ippsBigNumInit; + ippsCmpZero_BN; + ippsCmp_BN; + ippsGetSize_BN; + ippsSet_BN; + ippsGet_BN; + ippsRef_BN; + ippsExtGet_BN; + ippsAdd_BN; + ippsSub_BN; + ippsMul_BN; + ippsMAC_BN_I; + ippsDiv_BN; + ippsMod_BN; + ippsGcd_BN; + ippsModInv_BN; + ippsSetOctString_BN; + ippsGetOctString_BN; + ippsMontGetSize; + ippsMontInit; + ippsMontSet; + ippsMontGet; + ippsMontForm; + ippsMontMul; + ippsMontExp; + ippsPRNGGetSize; + ippsPRNGInit; + ippsPRNGSetModulus; + ippsPRNGSetH0; + ippsPRNGSetAugment; + ippsPRNGSetSeed; + ippsPRNGGetSeed; + ippsPRNGen; + ippsPRNGen_BN; + ippsPRNGenRDRAND; + ippsPRNGenRDRAND_BN; + ippsTRNGenRDSEED; + ippsTRNGenRDSEED_BN; + ippsPrimeGetSize; + ippsPrimeInit; + ippsPrimeGen; + ippsPrimeTest; + ippsPrimeGen_BN; + ippsPrimeTest_BN; + ippsPrimeGet; + ippsPrimeGet_BN; + ippsPrimeSet; + ippsPrimeSet_BN; + ippsRSA_GetSizePublicKey; + ippsRSA_InitPublicKey; + ippsRSA_SetPublicKey; + ippsRSA_GetPublicKey; + ippsRSA_GetSizePrivateKeyType1; + ippsRSA_InitPrivateKeyType1; + ippsRSA_SetPrivateKeyType1; + ippsRSA_GetPrivateKeyType1; + ippsRSA_GetSizePrivateKeyType2; + ippsRSA_InitPrivateKeyType2; + ippsRSA_SetPrivateKeyType2; + ippsRSA_GetPrivateKeyType2; + ippsRSA_GetBufferSizePublicKey; + ippsRSA_GetBufferSizePrivateKey; + ippsRSA_Encrypt; + ippsRSA_Decrypt; + ippsRSA_GenerateKeys; + ippsRSA_ValidateKeys; + ippsRSAEncrypt_OAEP; + ippsRSADecrypt_OAEP; + ippsRSAEncrypt_OAEP_rmf; + ippsRSADecrypt_OAEP_rmf; + ippsRSAEncrypt_PKCSv15; + ippsRSADecrypt_PKCSv15; + ippsRSASign_PSS; + ippsRSAVerify_PSS; + ippsRSASign_PSS_rmf; + ippsRSAVerify_PSS_rmf; + ippsRSASign_PKCS1v15; + ippsRSAVerify_PKCS1v15; + ippsRSASign_PKCS1v15_rmf; + ippsRSAVerify_PKCS1v15_rmf; + ippsDLGetResultString; + ippsDLPGetSize; + ippsDLPInit; + ippsDLPPack; + ippsDLPUnpack; + ippsDLPSet; + ippsDLPGet; + ippsDLPSetDP; + ippsDLPGetDP; + ippsDLPGenKeyPair; + ippsDLPPublicKey; + ippsDLPValidateKeyPair; + ippsDLPSetKeyPair; + ippsDLPSignDSA; + ippsDLPVerifyDSA; + ippsDLPSharedSecretDH; + ippsDLPGenerateDSA; + ippsDLPValidateDSA; + ippsDLPGenerateDH; + ippsDLPValidateDH; + ippsECCGetResultString; + ippsECCPGetSize; + ippsECCPGetSizeStd128r1; + ippsECCPGetSizeStd128r2; + ippsECCPGetSizeStd192r1; + ippsECCPGetSizeStd224r1; + ippsECCPGetSizeStd256r1; + ippsECCPGetSizeStd384r1; + ippsECCPGetSizeStd521r1; + ippsECCPGetSizeStdSM2; + ippsECCPInit; + ippsECCPInitStd128r1; + ippsECCPInitStd128r2; + ippsECCPInitStd192r1; + ippsECCPInitStd224r1; + ippsECCPInitStd256r1; + ippsECCPInitStd384r1; + ippsECCPInitStd521r1; + ippsECCPInitStdSM2; + ippsECCPSet; + ippsECCPSetStd; + ippsECCPSetStd128r1; + ippsECCPSetStd128r2; + ippsECCPSetStd192r1; + ippsECCPSetStd224r1; + ippsECCPSetStd256r1; + ippsECCPSetStd384r1; + ippsECCPSetStd521r1; + ippsECCPSetStdSM2; + ippsECCPBindGxyTblStd192r1; + ippsECCPBindGxyTblStd224r1; + ippsECCPBindGxyTblStd256r1; + ippsECCPBindGxyTblStd384r1; + ippsECCPBindGxyTblStd521r1; + ippsECCPBindGxyTblStdSM2; + ippsECCPGet; + ippsECCPGetOrderBitSize; + ippsECCPValidate; + ippsECCPPointGetSize; + ippsECCPPointInit; + ippsECCPSetPoint; + ippsECCPSetPointAtInfinity; + ippsECCPGetPoint; + ippsECCPCheckPoint; + ippsECCPComparePoint; + ippsECCPNegativePoint; + ippsECCPAddPoint; + ippsECCPMulPointScalar; + ippsECCPGenKeyPair; + ippsECCPPublicKey; + ippsECCPValidateKeyPair; + ippsECCPSetKeyPair; + ippsECCPSharedSecretDH; + ippsECCPSharedSecretDHC; + ippsECCPSignDSA; + ippsECCPVerifyDSA; + ippsECCPSignNR; + ippsECCPVerifyNR; + ippsECCPSignSM2; + ippsECCPVerifySM2; + ippsGFpGetSize; + ippsGFpInitArbitrary; + ippsGFpInitFixed; + ippsGFpInit; + ippsGFpMethod_p192r1; + ippsGFpMethod_p224r1; + ippsGFpMethod_p256r1; + ippsGFpMethod_p384r1; + ippsGFpMethod_p521r1; + ippsGFpMethod_p256sm2; + ippsGFpMethod_p256bn; + ippsGFpMethod_p256; + ippsGFpMethod_pArb; + ippsGFpxGetSize; + ippsGFpxInit; + ippsGFpxInitBinomial; + ippsGFpxMethod_binom2_epid2; + ippsGFpxMethod_binom3_epid2; + ippsGFpxMethod_binom2; + ippsGFpxMethod_binom3; + ippsGFpxMethod_binom; + ippsGFpxMethod_com; + ippsGFpScratchBufferSize; + ippsGFpElementGetSize; + ippsGFpElementInit; + ippsGFpSetElement; + ippsGFpSetElementRegular; + ippsGFpSetElementOctString; + ippsGFpSetElementRandom; + ippsGFpSetElementHash; + ippsGFpSetElementHash_rmf; + ippsGFpCpyElement; + ippsGFpGetElement; + ippsGFpGetElementOctString; + ippsGFpCmpElement; + ippsGFpIsZeroElement; + ippsGFpIsUnityElement; + ippsGFpConj; + ippsGFpNeg; + ippsGFpInv; + ippsGFpSqrt; + ippsGFpSqr; + ippsGFpAdd; + ippsGFpSub; + ippsGFpMul; + ippsGFpExp; + ippsGFpMultiExp; + ippsGFpAdd_PE; + ippsGFpSub_PE; + ippsGFpMul_PE; + ippsGFpGetInfo; + ippsGFpECGetSize; + ippsGFpECInit; + ippsGFpECSet; + ippsGFpECSetSubgroup; + ippsGFpECInitStd128r1; + ippsGFpECInitStd128r2; + ippsGFpECInitStd192r1; + ippsGFpECInitStd224r1; + ippsGFpECInitStd256r1; + ippsGFpECInitStd384r1; + ippsGFpECInitStd521r1; + ippsGFpECInitStdSM2; + ippsGFpECInitStdBN256; + ippsGFpECBindGxyTblStd192r1; + ippsGFpECBindGxyTblStd224r1; + ippsGFpECBindGxyTblStd256r1; + ippsGFpECBindGxyTblStd384r1; + ippsGFpECBindGxyTblStd521r1; + ippsGFpECBindGxyTblStdSM2; + ippsGFpECGet; + ippsGFpECGetInfo_GF; + ippsGFpECGetSubgroup; + ippsGFpECScratchBufferSize; + ippsGFpECVerify; + ippsGFpECPointGetSize; + ippsGFpECPointInit; + ippsGFpECSetPointAtInfinity; + ippsGFpECSetPoint; + ippsGFpECSetPointRegular; + ippsGFpECSetPointRandom; + ippsGFpECMakePoint; + ippsGFpECSetPointHash; + ippsGFpECSetPointHash_rmf; + ippsGFpECSetPointHashBackCompatible; + ippsGFpECSetPointHashBackCompatible_rmf; + ippsGFpECGetPoint; + ippsGFpECGetPointRegular; + ippsGFpECTstPoint; + ippsGFpECTstPointInSubgroup; + ippsGFpECCpyPoint; + ippsGFpECCmpPoint; + ippsGFpECNegPoint; + ippsGFpECAddPoint; + ippsGFpECMulPoint; + ippsGFpECPrivateKey; + ippsGFpECPublicKey; + ippsGFpECTstKeyPair; + ippsGFpECSharedSecretDH; + ippsGFpECSharedSecretDHC; + ippsGFpECSignDSA; + ippsGFpECVerifyDSA; + ippsGFpECSignNR; + ippsGFpECVerifyNR; + ippsGFpECSignSM2; + ippsGFpECVerifySM2; + ippsGFpECUserIDHashSM2; + ippsGFpECMessageRepresentationSM2; + ippsGFpECKeyExchangeSM2_GetSize; + ippsGFpECKeyExchangeSM2_Init; + ippsGFpECKeyExchangeSM2_Setup; + ippsGFpECKeyExchangeSM2_SharedKey; + ippsGFpECKeyExchangeSM2_Confirm; + ippsGFpECEncryptSM2_Ext_EncMsgSize; + ippsGFpECEncryptSM2_Ext; + ippsGFpECDecryptSM2_Ext_DecMsgSize; + ippsGFpECDecryptSM2_Ext; + ippsGFpECESGetSize_SM2; + ippsGFpECESInit_SM2; + ippsGFpECESSetKey_SM2; + ippsGFpECESStart_SM2; + ippsGFpECESEncrypt_SM2; + ippsGFpECESDecrypt_SM2; + ippsGFpECESFinal_SM2; + ippsGFpECESGetBuffersSize_SM2; + ippsGFpECSetPointOctString; + ippsGFpECGetPointOctString; + local: *; + }; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/exports.macosx.lib-export b/plugin/ippcp/library/src/sources/ippcp/exports.macosx.lib-export new file mode 100644 index 000000000..6d4fbf36a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/exports.macosx.lib-export @@ -0,0 +1,558 @@ +_ippcpInit +_cpGetReg +_cpStartTscp +_cpStopTscp +_cpStartTsc +_cpStopTsc +_cpGetCacheSize +_cpGetFeature +_ippcpSetCpuFeatures +_ippcpGetCpuFeatures +_ippcpGetCpuClocks +_ippcpSetNumThreads +_ippcpGetNumThreads +_ippcpGetEnabledCpuFeatures +_ippcpGetEnabledNumThreads +_ippcpGetStatusString + +_ippcpGetLibVersion +_ippsDESGetSize +_ippsDESInit +_ippsDESPack +_ippsDESUnpack +_ippsTDESEncryptECB +_ippsTDESDecryptECB +_ippsTDESEncryptCBC +_ippsTDESDecryptCBC +_ippsTDESEncryptCFB +_ippsTDESDecryptCFB +_ippsTDESEncryptOFB +_ippsTDESDecryptOFB +_ippsTDESEncryptCTR +_ippsTDESDecryptCTR +_ippsAESGetSize +_ippsAESInit +_ippsAESSetKey +_ippsAESPack +_ippsAESUnpack +_ippsAESSetupNoise +_ippsAES_GCMSetupNoise +_ippsAES_CMACSetupNoise +_ippsAESEncryptECB +_ippsAESDecryptECB +_ippsAESEncryptCBC +_ippsAESEncryptCBC_CS1 +_ippsAESEncryptCBC_CS2 +_ippsAESEncryptCBC_CS3 +_ippsAESDecryptCBC +_ippsAESDecryptCBC_CS1 +_ippsAESDecryptCBC_CS2 +_ippsAESDecryptCBC_CS3 +_ippsAESEncryptCFB +_ippsAESDecryptCFB +_ippsAESEncryptOFB +_ippsAESDecryptOFB +_ippsAESEncryptCTR +_ippsAESDecryptCTR +_ippsAESEncryptXTS_Direct +_ippsAESDecryptXTS_Direct +_ippsAES_EncryptCFB16_MB +_ippsSMS4GetSize +_ippsSMS4Init +_ippsSMS4SetKey +_ippsSMS4EncryptECB +_ippsSMS4DecryptECB +_ippsSMS4EncryptCBC +_ippsSMS4EncryptCBC_CS1 +_ippsSMS4EncryptCBC_CS2 +_ippsSMS4EncryptCBC_CS3 +_ippsSMS4DecryptCBC +_ippsSMS4DecryptCBC_CS1 +_ippsSMS4DecryptCBC_CS2 +_ippsSMS4DecryptCBC_CS3 +_ippsSMS4EncryptCFB +_ippsSMS4DecryptCFB +_ippsSMS4EncryptOFB +_ippsSMS4DecryptOFB +_ippsSMS4EncryptCTR +_ippsSMS4DecryptCTR +_ippsSMS4_CCMGetSize +_ippsSMS4_CCMInit +_ippsSMS4_CCMMessageLen +_ippsSMS4_CCMTagLen +_ippsSMS4_CCMStart +_ippsSMS4_CCMEncrypt +_ippsSMS4_CCMDecrypt +_ippsSMS4_CCMGetTag +_ippsAES_CCMGetSize +_ippsAES_CCMInit +_ippsAES_CCMMessageLen +_ippsAES_CCMTagLen +_ippsAES_CCMStart +_ippsAES_CCMEncrypt +_ippsAES_CCMDecrypt +_ippsAES_CCMGetTag +_ippsAES_GCMGetSize +_ippsAES_GCMInit +_ippsAES_GCMReinit +_ippsAES_GCMReset +_ippsAES_GCMProcessIV +_ippsAES_GCMProcessAAD +_ippsAES_GCMStart +_ippsAES_GCMEncrypt +_ippsAES_GCMDecrypt +_ippsAES_GCMGetTag +_ippsAES_XTSGetSize +_ippsAES_XTSInit +_ippsAES_XTSEncrypt +_ippsAES_XTSDecrypt +_ippsAES_S2V_CMAC +_ippsAES_SIVEncrypt +_ippsAES_SIVDecrypt +_ippsAES_CMACGetSize +_ippsAES_CMACInit +_ippsAES_CMACUpdate +_ippsAES_CMACFinal +_ippsAES_CMACGetTag +_ippsARCFourCheckKey +_ippsARCFourGetSize +_ippsARCFourInit +_ippsARCFourReset +_ippsARCFourPack +_ippsARCFourUnpack +_ippsARCFourEncrypt +_ippsARCFourDecrypt +_ippsSHA1GetSize +_ippsSHA1Init +_ippsSHA1Duplicate +_ippsSHA1Pack +_ippsSHA1Unpack +_ippsSHA1Update +_ippsSHA1GetTag +_ippsSHA1Final +_ippsSHA1MessageDigest +_ippsSHA224GetSize +_ippsSHA224Init +_ippsSHA224Duplicate +_ippsSHA224Pack +_ippsSHA224Unpack +_ippsSHA224Update +_ippsSHA224GetTag +_ippsSHA224Final +_ippsSHA224MessageDigest +_ippsSHA256GetSize +_ippsSHA256Init +_ippsSHA256Duplicate +_ippsSHA256Pack +_ippsSHA256Unpack +_ippsSHA256Update +_ippsSHA256GetTag +_ippsSHA256Final +_ippsSHA256MessageDigest +_ippsSHA384GetSize +_ippsSHA384Init +_ippsSHA384Duplicate +_ippsSHA384Pack +_ippsSHA384Unpack +_ippsSHA384Update +_ippsSHA384GetTag +_ippsSHA384Final +_ippsSHA384MessageDigest +_ippsSHA512GetSize +_ippsSHA512Init +_ippsSHA512Duplicate +_ippsSHA512Pack +_ippsSHA512Unpack +_ippsSHA512Update +_ippsSHA512GetTag +_ippsSHA512Final +_ippsSHA512MessageDigest +_ippsMD5GetSize +_ippsMD5Init +_ippsMD5Duplicate +_ippsMD5Pack +_ippsMD5Unpack +_ippsMD5Update +_ippsMD5GetTag +_ippsMD5Final +_ippsMD5MessageDigest +_ippsSM3GetSize +_ippsSM3Init +_ippsSM3Duplicate +_ippsSM3Pack +_ippsSM3Unpack +_ippsSM3Update +_ippsSM3GetTag +_ippsSM3Final +_ippsSM3MessageDigest +_ippsHashGetSize +_ippsHashInit +_ippsHashPack +_ippsHashUnpack +_ippsHashDuplicate +_ippsHashUpdate +_ippsHashGetTag +_ippsHashFinal +_ippsHashMessage +_ippsHashMethodGetSize +_ippsHashMethodSet_MD5 +_ippsHashMethodSet_SM3 +_ippsHashMethodSet_SHA1 +_ippsHashMethodSet_SHA1_NI +_ippsHashMethodSet_SHA1_TT +_ippsHashMethodSet_SHA256 +_ippsHashMethodSet_SHA256_NI +_ippsHashMethodSet_SHA256_TT +_ippsHashMethodSet_SHA224 +_ippsHashMethodSet_SHA224_NI +_ippsHashMethodSet_SHA224_TT +_ippsHashMethodSet_SHA512 +_ippsHashMethodSet_SHA384 +_ippsHashMethodSet_SHA512_256 +_ippsHashMethodSet_SHA512_224 +_ippsHashStateMethodSet_SM3 +_ippsHashStateMethodSet_SHA256 +_ippsHashStateMethodSet_SHA256_NI +_ippsHashStateMethodSet_SHA256_TT +_ippsHashStateMethodSet_SHA224 +_ippsHashStateMethodSet_SHA224_NI +_ippsHashStateMethodSet_SHA224_TT +_ippsHashStateMethodSet_SHA512 +_ippsHashStateMethodSet_SHA384 +_ippsHashStateMethodSet_SHA512_256 +_ippsHashStateMethodSet_SHA512_224 +_ippsHashMethod_MD5 +_ippsHashMethod_SM3 +_ippsHashMethod_SHA1 +_ippsHashMethod_SHA1_NI +_ippsHashMethod_SHA1_TT +_ippsHashMethod_SHA256 +_ippsHashMethod_SHA256_NI +_ippsHashMethod_SHA256_TT +_ippsHashMethod_SHA224 +_ippsHashMethod_SHA224_NI +_ippsHashMethod_SHA224_TT +_ippsHashMethod_SHA512 +_ippsHashMethod_SHA384 +_ippsHashMethod_SHA512_256 +_ippsHashMethod_SHA512_224 +_ippsHashMethodGetInfo +_ippsHashGetSize_rmf +_ippsHashInit_rmf +_ippsHashPack_rmf +_ippsHashUnpack_rmf +_ippsHashDuplicate_rmf +_ippsHashUpdate_rmf +_ippsHashGetTag_rmf +_ippsHashFinal_rmf +_ippsHashMessage_rmf +_ippsHashGetInfo_rmf +_ippsMGF +_ippsMGF1_rmf +_ippsMGF2_rmf +_ippsHMAC_GetSize +_ippsHMAC_Init +_ippsHMAC_Pack +_ippsHMAC_Unpack +_ippsHMAC_Duplicate +_ippsHMAC_Update +_ippsHMAC_Final +_ippsHMAC_GetTag +_ippsHMAC_Message +_ippsHMACGetSize_rmf +_ippsHMACInit_rmf +_ippsHMACPack_rmf +_ippsHMACUnpack_rmf +_ippsHMACDuplicate_rmf +_ippsHMACUpdate_rmf +_ippsHMACFinal_rmf +_ippsHMACGetTag_rmf +_ippsHMACMessage_rmf +_ippsBigNumGetSize +_ippsBigNumInit +_ippsCmpZero_BN +_ippsCmp_BN +_ippsGetSize_BN +_ippsSet_BN +_ippsGet_BN +_ippsRef_BN +_ippsExtGet_BN +_ippsAdd_BN +_ippsSub_BN +_ippsMul_BN +_ippsMAC_BN_I +_ippsDiv_BN +_ippsMod_BN +_ippsGcd_BN +_ippsModInv_BN +_ippsSetOctString_BN +_ippsGetOctString_BN +_ippsMontGetSize +_ippsMontInit +_ippsMontSet +_ippsMontGet +_ippsMontForm +_ippsMontMul +_ippsMontExp +_ippsPRNGGetSize +_ippsPRNGInit +_ippsPRNGSetModulus +_ippsPRNGSetH0 +_ippsPRNGSetAugment +_ippsPRNGSetSeed +_ippsPRNGGetSeed +_ippsPRNGen +_ippsPRNGen_BN +_ippsPRNGenRDRAND +_ippsPRNGenRDRAND_BN +_ippsTRNGenRDSEED +_ippsTRNGenRDSEED_BN +_ippsPrimeGetSize +_ippsPrimeInit +_ippsPrimeGen +_ippsPrimeTest +_ippsPrimeGen_BN +_ippsPrimeTest_BN +_ippsPrimeGet +_ippsPrimeGet_BN +_ippsPrimeSet +_ippsPrimeSet_BN +_ippsRSA_GetSizePublicKey +_ippsRSA_InitPublicKey +_ippsRSA_SetPublicKey +_ippsRSA_GetPublicKey +_ippsRSA_GetSizePrivateKeyType1 +_ippsRSA_InitPrivateKeyType1 +_ippsRSA_SetPrivateKeyType1 +_ippsRSA_GetPrivateKeyType1 +_ippsRSA_GetSizePrivateKeyType2 +_ippsRSA_InitPrivateKeyType2 +_ippsRSA_SetPrivateKeyType2 +_ippsRSA_GetPrivateKeyType2 +_ippsRSA_GetBufferSizePublicKey +_ippsRSA_GetBufferSizePrivateKey +_ippsRSA_Encrypt +_ippsRSA_Decrypt +_ippsRSA_GenerateKeys +_ippsRSA_ValidateKeys +_ippsRSAEncrypt_OAEP +_ippsRSADecrypt_OAEP +_ippsRSAEncrypt_OAEP_rmf +_ippsRSADecrypt_OAEP_rmf +_ippsRSAEncrypt_PKCSv15 +_ippsRSADecrypt_PKCSv15 +_ippsRSASign_PSS +_ippsRSAVerify_PSS +_ippsRSASign_PSS_rmf +_ippsRSAVerify_PSS_rmf +_ippsRSASign_PKCS1v15 +_ippsRSAVerify_PKCS1v15 +_ippsRSASign_PKCS1v15_rmf +_ippsRSAVerify_PKCS1v15_rmf +_ippsDLGetResultString +_ippsDLPGetSize +_ippsDLPInit +_ippsDLPPack +_ippsDLPUnpack +_ippsDLPSet +_ippsDLPGet +_ippsDLPSetDP +_ippsDLPGetDP +_ippsDLPGenKeyPair +_ippsDLPPublicKey +_ippsDLPValidateKeyPair +_ippsDLPSetKeyPair +_ippsDLPSignDSA +_ippsDLPVerifyDSA +_ippsDLPSharedSecretDH +_ippsDLPGenerateDSA +_ippsDLPValidateDSA +_ippsDLPGenerateDH +_ippsDLPValidateDH +_ippsECCGetResultString +_ippsECCPGetSize +_ippsECCPGetSizeStd128r1 +_ippsECCPGetSizeStd128r2 +_ippsECCPGetSizeStd192r1 +_ippsECCPGetSizeStd224r1 +_ippsECCPGetSizeStd256r1 +_ippsECCPGetSizeStd384r1 +_ippsECCPGetSizeStd521r1 +_ippsECCPGetSizeStdSM2 +_ippsECCPInit +_ippsECCPInitStd128r1 +_ippsECCPInitStd128r2 +_ippsECCPInitStd192r1 +_ippsECCPInitStd224r1 +_ippsECCPInitStd256r1 +_ippsECCPInitStd384r1 +_ippsECCPInitStd521r1 +_ippsECCPInitStdSM2 +_ippsECCPSet +_ippsECCPSetStd +_ippsECCPSetStd128r1 +_ippsECCPSetStd128r2 +_ippsECCPSetStd192r1 +_ippsECCPSetStd224r1 +_ippsECCPSetStd256r1 +_ippsECCPSetStd384r1 +_ippsECCPSetStd521r1 +_ippsECCPSetStdSM2 +_ippsECCPBindGxyTblStd192r1 +_ippsECCPBindGxyTblStd224r1 +_ippsECCPBindGxyTblStd256r1 +_ippsECCPBindGxyTblStd384r1 +_ippsECCPBindGxyTblStd521r1 +_ippsECCPBindGxyTblStdSM2 +_ippsECCPGet +_ippsECCPGetOrderBitSize +_ippsECCPValidate +_ippsECCPPointGetSize +_ippsECCPPointInit +_ippsECCPSetPoint +_ippsECCPSetPointAtInfinity +_ippsECCPGetPoint +_ippsECCPCheckPoint +_ippsECCPComparePoint +_ippsECCPNegativePoint +_ippsECCPAddPoint +_ippsECCPMulPointScalar +_ippsECCPGenKeyPair +_ippsECCPPublicKey +_ippsECCPValidateKeyPair +_ippsECCPSetKeyPair +_ippsECCPSharedSecretDH +_ippsECCPSharedSecretDHC +_ippsECCPSignDSA +_ippsECCPVerifyDSA +_ippsECCPSignNR +_ippsECCPVerifyNR +_ippsECCPSignSM2 +_ippsECCPVerifySM2 +_ippsGFpGetSize +_ippsGFpInitArbitrary +_ippsGFpInitFixed +_ippsGFpInit +_ippsGFpMethod_p192r1 +_ippsGFpMethod_p224r1 +_ippsGFpMethod_p256r1 +_ippsGFpMethod_p384r1 +_ippsGFpMethod_p521r1 +_ippsGFpMethod_p256sm2 +_ippsGFpMethod_p256bn +_ippsGFpMethod_p256 +_ippsGFpMethod_pArb +_ippsGFpxGetSize +_ippsGFpxInit +_ippsGFpxInitBinomial +_ippsGFpxMethod_binom2_epid2 +_ippsGFpxMethod_binom3_epid2 +_ippsGFpxMethod_binom2 +_ippsGFpxMethod_binom3 +_ippsGFpxMethod_binom +_ippsGFpxMethod_com +_ippsGFpScratchBufferSize +_ippsGFpElementGetSize +_ippsGFpElementInit +_ippsGFpSetElement +_ippsGFpSetElementRegular +_ippsGFpSetElementOctString +_ippsGFpSetElementRandom +_ippsGFpSetElementHash +_ippsGFpSetElementHash_rmf +_ippsGFpCpyElement +_ippsGFpGetElement +_ippsGFpGetElementOctString +_ippsGFpCmpElement +_ippsGFpIsZeroElement +_ippsGFpIsUnityElement +_ippsGFpConj +_ippsGFpNeg +_ippsGFpInv +_ippsGFpSqrt +_ippsGFpSqr +_ippsGFpAdd +_ippsGFpSub +_ippsGFpMul +_ippsGFpExp +_ippsGFpMultiExp +_ippsGFpAdd_PE +_ippsGFpSub_PE +_ippsGFpMul_PE +_ippsGFpGetInfo +_ippsGFpECGetSize +_ippsGFpECInit +_ippsGFpECSet +_ippsGFpECSetSubgroup +_ippsGFpECInitStd128r1 +_ippsGFpECInitStd128r2 +_ippsGFpECInitStd192r1 +_ippsGFpECInitStd224r1 +_ippsGFpECInitStd256r1 +_ippsGFpECInitStd384r1 +_ippsGFpECInitStd521r1 +_ippsGFpECInitStdSM2 +_ippsGFpECInitStdBN256 +_ippsGFpECBindGxyTblStd192r1 +_ippsGFpECBindGxyTblStd224r1 +_ippsGFpECBindGxyTblStd256r1 +_ippsGFpECBindGxyTblStd384r1 +_ippsGFpECBindGxyTblStd521r1 +_ippsGFpECBindGxyTblStdSM2 +_ippsGFpECGet +_ippsGFpECGetInfo_GF +_ippsGFpECGetSubgroup +_ippsGFpECScratchBufferSize +_ippsGFpECVerify +_ippsGFpECPointGetSize +_ippsGFpECPointInit +_ippsGFpECSetPointAtInfinity +_ippsGFpECSetPoint +_ippsGFpECSetPointRegular +_ippsGFpECSetPointRandom +_ippsGFpECMakePoint +_ippsGFpECSetPointHash +_ippsGFpECSetPointHash_rmf +_ippsGFpECSetPointHashBackCompatible +_ippsGFpECSetPointHashBackCompatible_rmf +_ippsGFpECGetPoint +_ippsGFpECGetPointRegular +_ippsGFpECTstPoint +_ippsGFpECTstPointInSubgroup +_ippsGFpECCpyPoint +_ippsGFpECCmpPoint +_ippsGFpECNegPoint +_ippsGFpECAddPoint +_ippsGFpECMulPoint +_ippsGFpECPrivateKey +_ippsGFpECPublicKey +_ippsGFpECTstKeyPair +_ippsGFpECSharedSecretDH +_ippsGFpECSharedSecretDHC +_ippsGFpECSignDSA +_ippsGFpECVerifyDSA +_ippsGFpECSignNR +_ippsGFpECVerifyNR +_ippsGFpECSignSM2 +_ippsGFpECVerifySM2 +_ippsGFpECUserIDHashSM2 +_ippsGFpECMessageRepresentationSM2 +_ippsGFpECKeyExchangeSM2_GetSize +_ippsGFpECKeyExchangeSM2_Init +_ippsGFpECKeyExchangeSM2_Setup +_ippsGFpECKeyExchangeSM2_SharedKey +_ippsGFpECKeyExchangeSM2_Confirm +_ippsGFpECEncryptSM2_Ext_EncMsgSize +_ippsGFpECEncryptSM2_Ext +_ippsGFpECDecryptSM2_Ext_DecMsgSize +_ippsGFpECDecryptSM2_Ext +_ippsGFpECESGetSize_SM2 +_ippsGFpECESInit_SM2 +_ippsGFpECESSetKey_SM2 +_ippsGFpECESStart_SM2 +_ippsGFpECESEncrypt_SM2 +_ippsGFpECESDecrypt_SM2 +_ippsGFpECESFinal_SM2 +_ippsGFpECESGetBuffersSize_SM2 +_ippsGFpECSetPointOctString +_ippsGFpECGetPointOctString diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_almmontinv.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_almmontinv.c new file mode 100644 index 000000000..a02b3afb4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_almmontinv.c @@ -0,0 +1,105 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// alm_mont_inv() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" +#include "pcpmask_ct.h" + +/* +// almost Montgomery Inverse +// +// returns (k,r), r = (1/a)*(2^k) mod m +// +*/ +IPP_OWN_DEFN (int, alm_mont_inv, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 4; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pME, polLength); + if(NULL == pBuffer) + return 0; // zero return value is handled by the calling function + + BNU_CHUNK_T* pu = pBuffer; + BNU_CHUNK_T* ps = pu+mLen; + BNU_CHUNK_T* pv = ps+mLen; + BNU_CHUNK_T* pt = pv+mLen; + + int k = 0; + BNU_CHUNK_T ext = 0; + + // u=modulus, v=a, t=0, s=1 + COPY_BNU(pu, pm, mLen); + ZEXPAND_BNU(ps, 0, mLen); ps[0] = 1; + COPY_BNU(pv, pa, mLen); + ZEXPAND_BNU(pt, 0, mLen); + + while(!cpEqu_BNU_CHUNK(pv, mLen, 0)) { // while(v>0) { + if(0==(pu[0]&1)) { // if(isEven(u)) { + cpLSR_BNU(pu, pu, mLen, 1); // u = u/2; + cpAdd_BNU(ps, ps, ps, mLen); // s = 2*s; + } // } + else if(0==(pv[0]&1)) { // else if(isEven(v)) { + cpLSR_BNU(pv, pv, mLen, 1); // v = v/2; + /*ext +=*/ cpAdd_BNU(pt, pt, pt, mLen); // t = 2*t; + } // } + else { + int cmpRes = cpCmp_BNU(pu, mLen, pv, mLen); + if(cmpRes>0) { // else if (u>v) { + cpSub_BNU(pu, pu, pv, mLen); // u = (u-v); + cpLSR_BNU(pu, pu, mLen, 1); // u = u/2; + /*ext +=*/ cpAdd_BNU(pt, pt, ps, mLen); // t = t+s; + cpAdd_BNU(ps, ps, ps, mLen); // s = 2*s; + } // } + else { // else if(v>=u) { + cpSub_BNU(pv, pv, pu, mLen); // v = (v-u); + cpLSR_BNU(pv, pv, mLen, 1); // v = v/2; + cpAdd_BNU(ps, ps, pt, mLen); // s = s+t; + ext += cpAdd_BNU(pt, pt, pt, mLen); // t = 2*t; + } // } + } + k++; // k += 1; + } // } + + // test + if(1!=cpEqu_BNU_CHUNK(pu, mLen, 1)) { + k = 0; /* inversion not found */ + } + + else { + ext -= cpSub_BNU(pr, pt, pm, mLen); // if(t>mod) r = t-mod; + cpMaskedReplace_ct(pr, pt, mLen, ~cpIsZero_ct(ext)); // else r = t; + cpSub_BNU(pr, pm, pr, mLen); // return r= (mod - r) and k + } + + gsModPoolFree(pME, polLength); + return k; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_almmontinv_ct.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_almmontinv_ct.c new file mode 100644 index 000000000..4a1f03cde --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_almmontinv_ct.c @@ -0,0 +1,136 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// alm_mont_inv_ct() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" +#include "pcpmask_ct.h" + +/* +// almost Montgomery Inverse +// +// returns (k,r), r = (1/a)*(2^k) mod m +// +// (constant-execution-time version) +*/ +IPP_OWN_DEFN (int, alm_mont_inv_ct, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + int mLen = MOD_LEN(pME); + int modulusBitSize = MOD_BITSIZE(pME); + + const int polLength = 6; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pME, polLength); + if(NULL == pBuffer) + return 0; // zero return value is handled by the calling function + + BNU_CHUNK_T* pu = pBuffer; + BNU_CHUNK_T* ps = pu+mLen; + BNU_CHUNK_T* pv = ps+mLen; + BNU_CHUNK_T* pt = pv+mLen; + + BNU_CHUNK_T* px = pt+mLen; + BNU_CHUNK_T* py = px+mLen; + + int k = 0; + int i; + BNU_CHUNK_T ext = 0; + + // u=modulus, s=1 and v=a, t=0, + COPY_BNU(pu, pm, mLen); + ZEXPAND_BNU(ps, 0, mLen); ps[0] = 1; + COPY_BNU(pv, pa, mLen); + ZEXPAND_BNU(pt, 0, mLen); + + for(i=0; i<2*modulusBitSize; i++) { + /* update mask - update = (v==0)? 0xFF : 0 */ + BNU_CHUNK_T update = ~cpIsGFpElemEquChunk_ct(pv, mLen, 0); + /* temporary masks */ + BNU_CHUNK_T m, mm; + + /* compute in advance r = s+t */ + cpAdd_BNU(pr, ps, pt, mLen); + + /* + // update or keep current u, s, v, t + */ + + /* if(isEven(u)) { u=u/2; s=2*s; } 1-st branch */ + m = update & cpIsEven_ct(pu[0]); + cpLSR_BNU(px, pu, mLen, 1); + cpAdd_BNU(py, ps, ps, mLen); + cpMaskedReplace_ct(pu, px, mLen, m); + cpMaskedReplace_ct(ps, py, mLen, m); + + /* else if(isEven(v)) { v=v/2; t=2*t; } 2-nd branch */ + mm = update & ~m & cpIsEven_ct(pv[0]); + cpLSR_BNU(px, pv, mLen, 1); + cpAdd_BNU(py, pt, pt, mLen); + cpMaskedReplace_ct(pv, px, mLen, mm); + cpMaskedReplace_ct(pt, py, mLen, mm); + + m |= mm; /* if fall in the 1-st of 2-nf branches m=FF.. else m=0 */ + + /* else if(v>=u) { v=(v-u)/2; s=s+t; t=2*t;} 3-st branch */ + mm = cpSub_BNU(px, pv, pu, mLen); + mm = cpIsZero_ct(mm); + mm = update & ~m & mm; + cpLSR_BNU(px, px, mLen, 1); + ext += cpAdd_BNU(py, pt, pt, mLen) & mm; + cpMaskedReplace_ct(pv, px, mLen, mm); + cpMaskedReplace_ct(ps, pr, mLen, mm); + cpMaskedReplace_ct(pt, py, mLen, mm); + + /* else { u=(u-v)/2; t= t+s; s=2*s; } 4-rd branch*/ + cpSub_BNU(px, pu, pv, mLen); + mm = update & ~m & ~mm; + cpLSR_BNU(px, px, mLen, 1); + cpAdd_BNU(py, ps, ps, mLen); + cpMaskedReplace_ct(pu, px, mLen, mm); + cpMaskedReplace_ct(pt, pr, mLen, mm); + cpMaskedReplace_ct(ps, py, mLen, mm); + + /* update or keep current k */ + k = ((k+1) & (Ipp32s)update) | (k & (Ipp32s)~update); + } + + /* + // r = (t>mod)? t-mod : t; + // r = mod - t; + */ + ext -= cpSub_BNU(pr, pt, pm, mLen); + cpMaskedReplace_ct(pr, pt, mLen, ~cpIsZero_ct(ext)); + cpSub_BNU(pr, pm, pr, mLen); + + /* test if inversion not found (k=0) */ + k &= cpIsGFpElemEquChunk_ct(pu, mLen, 1); + + gsModPoolFree(pME, polLength); + return k; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_enginegetsize.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_enginegetsize.c new file mode 100644 index 000000000..613e7c5ad --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_enginegetsize.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// gsModEngineGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" +#include "pcptool.h" + +/*F* +// Name: gsModEngineGetSize +// +// Purpose: Specifies size of size of ModEngine context (Montgomery). +// +// Returns: Reason: +// ippStsLengthErr modulusBitSize < 1 +// numpe < MOD_ENGINE_MIN_POOL_SIZE +// ippStsNoErr no errors +// +// Parameters: +// numpe length of pool +// modulusBitSize max modulus length (in bits) +// pSize pointer to size +// +*F*/ + +IPP_OWN_DEFN (IppStatus, gsModEngineGetSize, (int modulusBitSize, int numpe, int* pSize)) +{ + int modLen = BITS_BNU_CHUNK(modulusBitSize); + int pelmLen = BITS_BNU_CHUNK(modulusBitSize); + + IPP_BADARG_RET(modulusBitSize<1, ippStsLengthErr); + IPP_BADARG_RET(numpepoolLenUsed >= pME->poolLen)? NULL : MOD_BUFFER(pME, pME->poolLenUsed); + return pPool; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_inv.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_inv.c new file mode 100644 index 000000000..afc6f8af0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_inv.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// gs_inv() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" + +/* +// returns r =1/a +// a in desidue domain +// r in desidue domain +*/ +IPP_OWN_DEFN (BNU_CHUNK_T*, gs_inv, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME, alm_inv alm_inversion)) +{ + int k = alm_inversion(pr, pa, pME); + + if(0==k) + return NULL; + + { + int mLen = MOD_LEN(pME); + int m = mLen*BNU_CHUNK_BITS; + mod_mul mon_mul = MOD_METHOD(pME)->mul; + + BNU_CHUNK_T* t = gsModPoolAlloc(pME, 1); + if(NULL == t) + return NULL; + + if(k>m) { + ZEXPAND_BNU(t, 0, mLen); + t[0] = 1; + mon_mul(pr, pr, t, pME); + k -= m; + } + ZEXPAND_BNU(t, 0, mLen); + SET_BIT(t, m-k); /* t = 2^(m-k) */ + mon_mul(pr, pr, t, pME); + + gsModPoolFree(pME, 1); + + return pr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_montfactor.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_montfactor.c new file mode 100644 index 000000000..47b30a37d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_montfactor.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// gsMontFactor() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" +#include "pcptool.h" + +/* +// montfomery factor k0 = -((modulus^-1 mod B) %B) +*/ +IPP_OWN_DEFN (BNU_CHUNK_T, gsMontFactor, (BNU_CHUNK_T m0)) +{ + BNU_CHUNK_T y = 1; + BNU_CHUNK_T x = 2; + BNU_CHUNK_T mask = 2*x-1; + + int i; + for(i=2; i<=BNU_CHUNK_BITS; i++, x<<=1) { + BNU_CHUNK_T rH, rL; + MUL_AB(rH, rL, m0, y); + if( x < (rL & mask) ) /* x < ((m0*y) mod (2*x)) */ + y+=x; + mask += mask + 1; + } + return 0-y; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_montinv.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_montinv.c new file mode 100644 index 000000000..b0a21c7ad --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_montinv.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// gs_mont_inv() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" +#include "pcpmask_ct.h" + +__INLINE BNU_CHUNK_T* cpPow2_ct(int bit, BNU_CHUNK_T* dst, int len) +{ + int slot = bit/BNU_CHUNK_BITS; + BNU_CHUNK_T value = (BNU_CHUNK_T)1 << (bit%BNU_CHUNK_BITS); + + int i; + len -= (int)( cpIsEqu_ct((BNU_CHUNK_T)slot, (BNU_CHUNK_T)len) ); + for(i=0; imul; + + BNU_CHUNK_T* t = gsModPoolAlloc(pME, 1); + if(NULL == t) + return NULL; + + if(k <= m) { + mon_mul(pr, pr, MOD_MNT_R2(pME), pME); + k += m; + } + + //ZEXPAND_BNU(t, 0, mLen); + //SET_BIT(t, 2*m-k); /* t = 2^(2*m-k) */ + cpPow2_ct(2*m-k, t, mLen); + mon_mul(pr, pr, t, pME); + + gsModPoolFree(pME, 1); + + return pr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_packctx.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_packctx.c new file mode 100644 index 000000000..846556275 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_packctx.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// gsPackModEngineCtx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" +#include "pcptool.h" + +/* +// Pack/Unpack methods +*/ +IPP_OWN_DEFN (void, gsPackModEngineCtx, (const gsModEngine* pCtx, Ipp8u* pBuffer)) +{ + gsModEngine* pB = (gsModEngine*)pBuffer; + + /* max modulus length */ + int modSize = MOD_LEN(pCtx); + /* size of context (bytes) without cube and pool buffers */ + int ctxSize = (Ipp32s)sizeof(gsModEngine) + +(Ipp32s)sizeof(BNU_CHUNK_T)*(modSize*3); + + CopyBlock(pCtx, pB, ctxSize); + MOD_MODULUS(pB) = (BNU_CHUNK_T*)((Ipp8u*)NULL + IPP_UINT_PTR(MOD_MODULUS(pCtx))-IPP_UINT_PTR(pCtx)); + MOD_MNT_R(pB) = (BNU_CHUNK_T*)((Ipp8u*)NULL + IPP_UINT_PTR(MOD_MNT_R(pCtx))-IPP_UINT_PTR(pCtx)); + MOD_MNT_R2(pB) = (BNU_CHUNK_T*)((Ipp8u*)NULL + IPP_UINT_PTR(MOD_MNT_R2(pCtx))-IPP_UINT_PTR(pCtx)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmod_unpackctx.c b/plugin/ippcp/library/src/sources/ippcp/gsmod_unpackctx.c new file mode 100644 index 000000000..bc0d9ff6c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmod_unpackctx.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. Modular Arithmetic Engine. General Functionality +// +// Contents: +// gsUnpackModEngineCtx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" +#include "gsmodstuff.h" +#include "pcptool.h" + +IPP_OWN_DEFN (void, gsUnpackModEngineCtx, (const Ipp8u* pBuffer, gsModEngine* pCtx)) +{ + gsModEngine* pAlignedBuffer = (gsModEngine*)pBuffer; + + /* max modulus length */ + int modSize = MOD_LEN(pAlignedBuffer); + /* size of context (bytes) without cube and pool buffers */ + int ctxSize = (Ipp32s)sizeof(gsModEngine) + +(Ipp32s)sizeof(BNU_CHUNK_T)*(modSize*3); + + CopyBlock(pAlignedBuffer, pCtx, ctxSize); + MOD_MODULUS(pCtx) = (BNU_CHUNK_T*)((Ipp8u*)pCtx + IPP_UINT_PTR(MOD_MODULUS(pAlignedBuffer))); + MOD_MNT_R(pCtx) = (BNU_CHUNK_T*)((Ipp8u*)pCtx + IPP_UINT_PTR(MOD_MNT_R(pAlignedBuffer))); + MOD_MNT_R2(pCtx) = (BNU_CHUNK_T*)((Ipp8u*)pCtx + IPP_UINT_PTR(MOD_MNT_R2(pAlignedBuffer))); + MOD_POOL_BUF(pCtx) = MOD_MNT_R2(pCtx) + modSize; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmodmethod.c b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod.c new file mode 100644 index 000000000..4bc74debd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "gsmodmethodstuff.h" + +/* + methods +*/ + +static gsModMethod* gsModArith_C(void) +{ + static gsModMethod m = { + gs_mont_encode, + gs_mont_decode, + gs_mont_mul, + gs_mont_sqr, + gs_mont_red, + gs_mont_add, + gs_mont_sub, + gs_mont_neg, + gs_mont_div2, + gs_mont_mul2, + gs_mont_mul3, + }; + return &m; +} + +#if (_IPP32E>=_IPP32E_L9) +static gsModMethod* gsModArith_X(void) +{ + static gsModMethod m = { + gs_mont_encodeX, + gs_mont_decodeX, + gs_mont_mulX, + gs_mont_sqrX, + gs_mont_redX, + gs_mont_add, + gs_mont_sub, + gs_mont_neg, + gs_mont_div2, + gs_mont_mul2, + gs_mont_mul3, + }; + return &m; +} +#endif + +IPP_OWN_DEFN (gsModMethod*, gsModArith, (void)) +{ + #if (_IPP32E>=_IPP32E_L9) + if(IsFeatureEnabled(ippCPUID_ADCOX)) + return gsModArith_X(); + else + #endif + return gsModArith_C(); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmodmethod.h b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod.h new file mode 100644 index 000000000..16a449cb4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod.h @@ -0,0 +1,101 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_GS_MOD_METHOD_H) +#define _GS_MOD_METHOD_H + +//#include "owndefs.h" +#include "owncp.h" + +#include "pcpbnuimpl.h" +//#include "gsmodstuff.h" + +typedef struct _gsModEngine gsEngine; + +/* modular arith methods */ +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_encode, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_decode, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_red, (BNU_CHUNK_T* pR, BNU_CHUNK_T* pA, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_sqr, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_mul, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_add, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_sub, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_neg, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_div2, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_mul2, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pMA)) +IPP_OWN_FUNPTR (BNU_CHUNK_T*, mod_mul3, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pMA)) + +typedef struct _gsModMethod { + mod_encode encode; + mod_decode decode; + mod_mul mul; + mod_sqr sqr; + mod_red red; + mod_add add; + mod_sub sub; + mod_neg neg; + mod_div2 div2; + mod_mul2 mul2; + mod_mul3 mul3; +} gsModMethod; + +/* These functions should not be used, because they have non-constant execution time, see their safe analogues in pcpmask_ct.h */ +#if 0 +__INLINE BNU_CHUNK_T cpIsZero(BNU_CHUNK_T x) +{ return x==0; } +__INLINE BNU_CHUNK_T cpIsNonZero(BNU_CHUNK_T x) +{ return x!=0; } +__INLINE BNU_CHUNK_T cpIsOdd(BNU_CHUNK_T x) +{ return x&1; } +__INLINE BNU_CHUNK_T cpIsEven(BNU_CHUNK_T x) +{ return 1-cpIsOdd(x); } + +/* dst[] = (flag)? src[] : dst[] */ +__INLINE void cpMaskMove_gs(BNU_CHUNK_T* dst, const BNU_CHUNK_T* src, int len, BNU_CHUNK_T moveFlag) +{ + BNU_CHUNK_T srcMask = 0-cpIsNonZero(moveFlag); + BNU_CHUNK_T dstMask = ~srcMask; + int n; + for(n=0; n=_IPP32E_L9) +static gsModMethod* gsModArithDLP_X(void) +{ + static gsModMethod m = { + gs_mont_encodeX, + gs_mont_decodeX, + gs_mont_mulX, + gs_mont_sqrX, + gs_mont_redX, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + return &m; +} +#endif + +IPP_OWN_DEFN (gsModMethod*, gsModArithDLP, (void)) +{ + #if (_IPP32E>=_IPP32E_L9) + if(IsFeatureEnabled(ippCPUID_ADCOX)) + return gsModArithDLP_X(); + else + #endif + return gsModArithDLP_C(); +} +/* ******************************************** */ diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_gfp.c b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_gfp.c new file mode 100644 index 000000000..7b22ab64e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_gfp.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "gsmodmethodstuff.h" + +/* + methods +*/ + +/* ******************************************** */ + +static gsModMethod* gsArithGFp_C(void) +{ + static gsModMethod m = { + gs_mont_encode, + gs_mont_decode, + gs_mont_mul, + gs_mont_sqr, + NULL, + gs_mont_add, + gs_mont_sub, + gs_mont_neg, + gs_mont_div2, + gs_mont_mul2, + gs_mont_mul3, + }; + return &m; +} +#if (_IPP32E>=_IPP32E_L9) +static gsModMethod* gsArithGFp_X(void) +{ + static gsModMethod m = { + gs_mont_encode, + gs_mont_decode, + gs_mont_mul, + gs_mont_sqr, + NULL, + gs_mont_add, + gs_mont_sub, + gs_mont_neg, + gs_mont_div2, + gs_mont_mul2, + gs_mont_mul3, + }; + return &m; +} +#endif + +IPP_OWN_DEFN (gsModMethod*, gsArithGFp, (void)) +{ + #if (_IPP32E>=_IPP32E_L9) + if(IsFeatureEnabled(ippCPUID_ADCOX)) + return gsArithGFp_X(); + else + #endif + return gsArithGFp_C(); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_mont.c b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_mont.c new file mode 100644 index 000000000..4f10933df --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_mont.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "gsmodmethodstuff.h" + +/* + methods +*/ + +/* ******************************************** */ + +static gsModMethod* gsModArithMont_C(void) +{ + static gsModMethod m = { + gs_mont_encode, + gs_mont_decode, + gs_mont_mul, + gs_mont_sqr, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + return &m; +} +#if (_IPP32E>=_IPP32E_L9) +static gsModMethod* gsModArithMont_X(void) +{ + static gsModMethod m = { + gs_mont_encodeX, + gs_mont_decodeX, + gs_mont_mulX, + gs_mont_sqrX, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + return &m; +} +#endif + +IPP_OWN_DEFN (gsModMethod*, gsModArithMont, (void)) +{ + #if (_IPP32E>=_IPP32E_L9) + if(IsFeatureEnabled(ippCPUID_ADCOX)) + return gsModArithMont_X(); + else + #endif + return gsModArithMont_C(); +} +/* ******************************************** */ diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_rsa.c b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_rsa.c new file mode 100644 index 000000000..ba8ac214d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmodmethod_rsa.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "gsmodmethodstuff.h" + +/* + methods +*/ + +/* ******************************************** */ + +static gsModMethod* gsModArithRSA_C(void) +{ + static gsModMethod m = { + gs_mont_encode, + gs_mont_decode, + gs_mont_mul, + gs_mont_sqr, + gs_mont_red, + NULL, + gs_mont_sub, + NULL, + NULL, + NULL, + NULL, + }; + return &m; +} +#if (_IPP32E>=_IPP32E_L9) +static gsModMethod* gsModArithRSA_X(void) +{ + static gsModMethod m = { + gs_mont_encodeX, + gs_mont_decodeX, + gs_mont_mulX, + gs_mont_sqrX, + gs_mont_redX, + NULL, + gs_mont_sub, + NULL, + NULL, + NULL, + NULL, + }; + return &m; +} +#endif + +IPP_OWN_DEFN (gsModMethod*, gsModArithRSA, (void)) +{ + #if (_IPP32E>=_IPP32E_L9) + if(IsFeatureEnabled(ippCPUID_ADCOX)) + return gsModArithRSA_X(); + else + #endif + return gsModArithRSA_C(); +} +/* ******************************************** */ diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmodmethodstuff.h b/plugin/ippcp/library/src/sources/ippcp/gsmodmethodstuff.h new file mode 100644 index 000000000..6a37c0373 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmodmethodstuff.h @@ -0,0 +1,500 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_GS_MOD_METHOD_STUFF_H) +#define _GS_MOD_METHOD_STUFF_H + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnuarith.h" + +#include "gsmodstuff.h" +#include "gsmodmethod.h" +#include "pcpmontred.h" +#include "pcpmask_ct.h" + +/* r = (a+m) mod m */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Length of pb data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) + */ +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_add, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, const BNU_CHUNK_T* pb, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 1; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pME, polLength); + if(NULL == pBuffer) + return NULL; + + { + BNU_CHUNK_T extension = cpAdd_BNU(pr, pa, pb, mLen); + extension -= cpSub_BNU(pBuffer, pr, pm, mLen); + cpMaskedReplace_ct(pr, pBuffer, mLen, cpIsZero_ct(extension)); + } + gsModPoolFree(pME, polLength); + return pr; +} + +/* r = (a-b) mod m */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Length of pb data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) + */ +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_sub, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, const BNU_CHUNK_T* pb, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 1; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pME, polLength); + if(NULL == pBuffer) + return NULL; + + { + BNU_CHUNK_T extension = cpSub_BNU(pr, pa, pb, mLen); + cpAdd_BNU(pBuffer, pr, pm, mLen); + cpMaskedReplace_ct(pr, pBuffer, mLen, ~cpIsZero_ct(extension)); + } + gsModPoolFree(pME, polLength); + return pr; +} + +/* r = (m-a) mod m */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) + */ +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_neg, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 1; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pME, polLength); + if(NULL == pBuffer) + return NULL; + + { + BNU_CHUNK_T extension = cpSub_BNU(pr, pm, pa, mLen); + extension -= cpSub_BNU(pBuffer, pr, pm, mLen); + cpMaskedReplace_ct(pr, pBuffer, mLen, cpIsZero_ct(extension)); + } + gsModPoolFree(pME, polLength); + return pr; +} + +/* r = (a/2) mod m */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) + */ +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_div2, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 1; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pME, polLength); + if(NULL == pBuffer) + return NULL; + + { + cpSize i; + BNU_CHUNK_T mask = 0 - (pa[0]&1); + for(i=0; i=_IPP32E_L9) +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_redX, (BNU_CHUNK_T* pr, BNU_CHUNK_T* prod, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + BNU_CHUNK_T k0 = MOD_MNT_FACTOR(pME); + int mLen = MOD_LEN(pME); + + cpMontRedAdx_BNU(pr, prod, pm, mLen, k0); + + return pr; +} +#endif + +#endif + + +/* r = (a*b) mod m */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Length of pb data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) * 2 + */ +#if ((_IPP <_IPP_W7) && (_IPP32E <_IPP32E_M7)) +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_mul, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, const BNU_CHUNK_T* pb, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + BNU_CHUNK_T m0 = MOD_MNT_FACTOR(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 1; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pME, polLength); + if(NULL == pBuffer) + return NULL; + + { + BNU_CHUNK_T carry = 0; + int i, j; + + /* clear buffer */ + for(i=0; i=_IPP32E_L9) +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_mulX, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, const BNU_CHUNK_T* pb, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + BNU_CHUNK_T m0 = MOD_MNT_FACTOR(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 2; + BNU_CHUNK_T* pProduct = gsModPoolAlloc(pME, polLength); + if(NULL == pProduct) + return NULL; + + cpMulAdx_BNU_school(pProduct, pa,mLen, pb,mLen); + cpMontRedAdx_BNU(pr, pProduct, pm, mLen, m0); + + gsModPoolFree(pME, polLength); + return pr; +} +#endif +#endif + +/* r = (a^2) mod m */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) + */ +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_sqr, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + //return gs_mont_mul(pr, pa, pa, pME); + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + BNU_CHUNK_T m0 = MOD_MNT_FACTOR(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 2; + BNU_CHUNK_T* pProduct = gsModPoolAlloc(pME, polLength); + if(NULL == pProduct) + return NULL; + + cpSqrAdc_BNU_school(pProduct, pa,mLen); + cpMontRedAdc_BNU(pr, pProduct, pm, mLen, m0); + + gsModPoolFree(pME, polLength); + return pr; +} + +#if (_IPP32E>=_IPP32E_L9) +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_sqrX, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + BNU_CHUNK_T m0 = MOD_MNT_FACTOR(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 2; + BNU_CHUNK_T* pProduct = gsModPoolAlloc(pME, polLength); + if(NULL == pProduct) + return NULL; + + cpSqrAdx_BNU_school(pProduct, pa,mLen); + cpMontRedAdx_BNU(pr, pProduct, pm, mLen, m0); + + gsModPoolFree(pME, polLength); + return pr; +} +#endif + +/* r = to_mont(a) */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) + */ +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_encode, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + //return gs_mont_mul(pr, pa, MOD_MNT_R2(pME), pME); + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + BNU_CHUNK_T m0 = MOD_MNT_FACTOR(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 2; + BNU_CHUNK_T* pProduct = gsModPoolAlloc(pME, polLength); + if(NULL == pProduct) + return NULL; + + cpMulAdc_BNU_school(pProduct, pa,mLen, MOD_MNT_R2(pME),mLen); + cpMontRedAdc_BNU(pr, pProduct, pm, mLen, m0); + + gsModPoolFree(pME, polLength); + return pr; +} + +#if (_IPP32E>=_IPP32E_L9) +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_encodeX, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + //return gs_mont_mul(pr, pa, MOD_MNT_R2(pME), pME); + const BNU_CHUNK_T* pm = MOD_MODULUS(pME); + BNU_CHUNK_T m0 = MOD_MNT_FACTOR(pME); + int mLen = MOD_LEN(pME); + + const int polLength = 2; + BNU_CHUNK_T* pProduct = gsModPoolAlloc(pME, polLength); + if(NULL == pProduct) + return NULL; + + cpMulAdx_BNU_school(pProduct, pa,mLen, MOD_MNT_R2(pME),mLen); + cpMontRedAdx_BNU(pr, pProduct, pm, mLen, m0); + + gsModPoolFree(pME, polLength); + return pr; +} +#endif + +/* r = from_momt(a) */ +/* + * Requirements: + * Length of pr data buffer: modLen + * Length of pa data buffer: modLen + * Memory size from the pool: modLen * sizeof(BNU_CHUNK_T) + */ +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_decode, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + int mLen = MOD_LEN(pME); + + const int polLength = 2; + BNU_CHUNK_T* pProduct = gsModPoolAlloc(pME, polLength); + if(NULL == pProduct) + return NULL; + + ZEXPAND_COPY_BNU(pProduct, 2*mLen, pa, mLen); + cpMontRedAdc_BNU(pr, pProduct, MOD_MODULUS(pME), mLen, MOD_MNT_FACTOR(pME)); + + gsModPoolFree(pME, polLength); + return pr; +} + +#if (_IPP32E>=_IPP32E_L9) +IPP_OWN_DEFN (static BNU_CHUNK_T*, gs_mont_decodeX, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pME)) +{ + int mLen = MOD_LEN(pME); + + const int polLength = 2; + BNU_CHUNK_T* pProduct = gsModPoolAlloc(pME, polLength); + if(NULL == pProduct) + return NULL; + + ZEXPAND_COPY_BNU(pProduct, 2*mLen, pa, mLen); + cpMontRedAdx_BNU(pr, pProduct, MOD_MODULUS(pME), mLen, MOD_MNT_FACTOR(pME)); + + gsModPoolFree(pME, polLength); + return pr; +} +#endif + +#endif /* _GS_MOD_METHOD_STUFF_H */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/gsmodstuff.h b/plugin/ippcp/library/src/sources/ippcp/gsmodstuff.h new file mode 100644 index 000000000..1ed3f2cf5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsmodstuff.h @@ -0,0 +1,162 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#if !defined(_GS_MOD_STUFF_H) +#define _GS_MOD_STUFF_H + +//#define MONTMUL_ONESTAGE + +#include "owncp.h" + +#include "pcpbnuimpl.h" +#include "gsmodmethod.h" + +#define MOD_ENGINE_MIN_POOL_SIZE 1 + +typedef struct _gsModEngine gsModEngine_T; + +typedef struct _gsModEngine +{ + gsModEngine_T* pParentME; /* pointer to parent stuff */ + int extdegree; /* parent modulus extension (deg) */ + int modBitLen; /* length of modulus in bits */ + int modLen; /* length of modulus (BNU_CHUNK_T) */ + int modLen32; /* length of modulus (Ipp32u) */ + int peLen; /* length of pool element (BNU_CHUNK_T) */ + const gsModMethod* method; /* modular arithmetic methods - regular radix */ + const void* method_alt; /* modular arithmetic methods - alternative radix implementation */ + BNU_CHUNK_T* pModulus; /* modulus */ + BNU_CHUNK_T k0; /* low word of (1/modulus) mod R */ + BNU_CHUNK_T* pMontR; /* mont_enc(1) */ + BNU_CHUNK_T* pMontR2; /* mont_enc(1)^2 */ + BNU_CHUNK_T* pHalfModulus; /* modulus/2 */ + BNU_CHUNK_T* pQnr; /* quadratic non-residue */ + int poolLenUsed; /* number of reserved temporary BNU */ + int poolLen; /* max number of temporary BNU */ + BNU_CHUNK_T* pBuffer; /* buffer of modLen*nBuffers length */ +} gsModEngine; + +/* accessory macros */ +#define MOD_PARENT(eng) ((eng)->pParentME) +#define MOD_EXTDEG(eng) ((eng)->extdegree) +#define MOD_BITSIZE(eng) ((eng)->modBitLen) +#define MOD_LEN(eng) ((eng)->modLen) +#define MOD_LEN32(eng) ((eng)->modLen32) +#define MOD_PELEN(eng) ((eng)->peLen) +#define MOD_METHOD(eng) ((eng)->method) +#define MOD_METHOD_ALT(eng) ((eng)->method_alt) +#define MOD_MODULUS(eng) ((eng)->pModulus) +#define MOD_MNT_FACTOR(eng) ((eng)->k0) +#define MOD_MNT_R(eng) ((eng)->pMontR) +#define MOD_MNT_R2(eng) ((eng)->pMontR2) +#define MOD_HMODULUS(eng) ((eng)->pHalfModulus) +#define MOD_QNR(eng) ((eng)->pQnr) +#define MOD_POOL_BUF(eng) ((eng)->pBuffer) +#define MOD_MAXPOOL(eng) ((eng)->poolLen) +#define MOD_USEDPOOL(eng) ((eng)->poolLenUsed) + +#define MOD_BUFFER(eng,n) ((eng)->pBuffer+(MOD_PELEN(eng))*(n)) + +#define MOD_ENGINE_ALIGNMENT ((int)sizeof(void*)) + +/* +// size of context and it initialization +*/ +#define gsModEngineInit OWNAPI(gsModEngineInit) + IPP_OWN_DECL (IppStatus, gsModEngineInit, (gsModEngine* pME, const Ipp32u* pModulus, int modulusBitSize, int numpe, const gsModMethod* method)) +#define gsModEngineGetSize OWNAPI(gsModEngineGetSize) + IPP_OWN_DECL (IppStatus, gsModEngineGetSize, (int modulusBitSIze, int numpe, int* pSize)) +#define gsMontFactor OWNAPI(gsMontFactor) + IPP_OWN_DECL (BNU_CHUNK_T, gsMontFactor, (BNU_CHUNK_T m0)) + + +/* +// pool management methods +*/ + +/*F* +// Name: gsModPoolAlloc +// +// Purpose: Allocation pool. +// +// Returns: Reason: +// pointer to allocate Pool enough of pool +// NULL required pool more than pME have +// +// Parameters: +// pME ModEngine +// poolReq Required pool +*F*/ + +__INLINE BNU_CHUNK_T* gsModPoolAlloc(gsModEngine* pME, int poolReq) +{ + BNU_CHUNK_T* pPool = MOD_BUFFER(pME, pME->poolLenUsed); + + if(pME->poolLenUsed + poolReq > pME->poolLen) + pPool = NULL; + else + pME->poolLenUsed += poolReq; + + return pPool; +} + +/*F* +// Name: gsModPoolFree +// +// Purpose: Delete pool. +// +// Returns: +// nothing +// +// Parameters: +// pME ModEngine +// poolReq Required pool +*F*/ + +__INLINE void gsModPoolFree(gsModEngine* pME, int poolReq) +{ + if(pME->poolLenUsed < poolReq) + poolReq = pME->poolLenUsed; + pME->poolLenUsed -= poolReq; +} + +/* return pointer to the top pool buffer */ +#define gsModGetPool OWNAPI(gsModGetPool) + IPP_OWN_DECL (BNU_CHUNK_T*, gsModGetPool, (gsModEngine* pME)) +/* +// advanced operations +*/ +IPP_OWN_FUNPTR (int, alm_inv, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pMA)) + +#define alm_mont_inv OWNAPI(alm_mont_inv) + IPP_OWN_DECL (int, alm_mont_inv, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pMA)) +#define alm_mont_inv_ct OWNAPI(alm_mont_inv_ct) + IPP_OWN_DECL (int, alm_mont_inv_ct, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pMA)) +#define gs_mont_inv OWNAPI(gs_mont_inv) + IPP_OWN_DECL (BNU_CHUNK_T*, gs_mont_inv, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pMA, alm_inv invf)) +#define gs_inv OWNAPI(gs_inv) + IPP_OWN_DECL (BNU_CHUNK_T*, gs_inv, (BNU_CHUNK_T* pr, const BNU_CHUNK_T* pa, gsModEngine* pMA, alm_inv invf)) + +/* +// Pack/Unpack methods +*/ +#define gsPackModEngineCtx OWNAPI(gsPackModEngineCtx) + IPP_OWN_DECL (void, gsPackModEngineCtx, (const gsModEngine* pCtx, Ipp8u* pBuffer)) +#define gsUnpackModEngineCtx OWNAPI(gsUnpackModEngineCtx) + IPP_OWN_DECL (void, gsUnpackModEngineCtx, (const Ipp8u* pBuffer, gsModEngine* pCtx)) + +#endif /* _GS_MOD_STUFF_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/gsscramble.c b/plugin/ippcp/library/src/sources/ippcp/gsscramble.c new file mode 100644 index 000000000..5f6a8fcc8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/gsscramble.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Fixed window exponentiation scramble/unscramble +// +// Contents: +// gsScramblePut() +// gsScrambleGet() +// +*/ + +#include "owncp.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (int, gsGetScrambleBufferSize, (int modulusLen, int w)) +{ + /* size of resource to store 2^w values of modulusLen*sizeof(BNU_CHUNK_T) each */ + int size = (1<=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" + +#include "ifma_math_avx512vl.h" +#include "ifma_norm52x.h" +#include "ifma_rsa_arith.h" + +#define ADD104(rh, rl, ih, il) { \ + rl += il; \ + rh += ih; \ + rh += (rl>52U) | rh<<(64U-52U)) + +/* + * Almost Montgomery Multiplication in 2^52-radix + * + * Data represented as 20-qwords arrays in 2^52-radix. + * + */ +IPP_OWN_DEFN(void, ifma256_amm52x20, (Ipp64u out[20], + const Ipp64u a [20], + const Ipp64u b [20], + const Ipp64u m [20], + Ipp64u k0)) +{ + /* R0, R1, R2 holds result */ + U64 R0 = get_zero64(); + U64 R1 = get_zero64(); + U64 R2 = get_zero64(); + + /* High part of 512bit result in 256bit mode */ + U64 R0h = get_zero64(); + U64 R1h = get_zero64(); + U64 R2h = get_zero64(); + + U64 Bi, Yi; + + Ipp64u m0 = m[0]; + Ipp64u a0 = a[0]; + Ipp64u acc0 = 0; + + int i; + for (i=0; i<20; i++) { + Ipp64u t0, t1, t2, yi; + + Bi = set64((long long)b[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0, b[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0, 0, t0) + yi = (acc0 * k0) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + Yi = set64((long long)yi); + + t0 = _mulx_u64(m0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0 = SHRD52(t2, acc0); + + fma52x8lo_mem(R0, R0, Bi, a, 64*0) + fma52x8lo_mem(R1, R1, Bi, a, 64*1) + fma52x8lo_mem_len(R2, R2, Bi, a, 64*2, 4) + fma52x8lo_mem(R0, R0, Yi, m, 64*0) + fma52x8lo_mem(R1, R1, Yi, m, 64*1) + fma52x8lo_mem_len(R2, R2, Yi, m, 64*2, 4) + + shift64_imm(R0, R0h, 1) + shift64_imm(R0h, R1, 1) + shift64_imm(R1, R1h, 1) + shift64_imm(R1h, R2, 1) + shift64_imm(R2, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0, 0); + acc0 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0, R0, Bi, a, 64*0) + fma52x8hi_mem(R1, R1, Bi, a, 64*1) + fma52x8hi_mem_len(R2, R2, Bi, a, 64*2, 4) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0, R0, Yi, m, 64*0) + fma52x8hi_mem(R1, R1, Yi, m, 64*1) + fma52x8hi_mem_len(R2, R2, Yi, m, 64*2, 4) + } + + /* Set R0[0] == acc0 */ + Bi = set64((long long)acc0); + R0 = blend64(R0, Bi, 1); + + NORMALIZE_52x20(R0, R1, R2) + + storeu64(out + 0*4, R0); + storeu64(out + 1*4, R0h); + storeu64(out + 2*4, R1); + storeu64(out + 3*4, R1h); + storeu64(out + 4*4, R2); +} + +#if 0 +/* + * Almost Montgomery Multiplication in 2^52-radix + * + * Data represented as 20-qwords arrays in 2^52-radix. + * + * Note: |a| and |m| shall be zero-padded on 32 bytes (see R2h usage). + * this allows to save on alignr's. + * + */ +IPP_OWN_DEFN(void, ifma256_amm52x20, (Ipp64u out[20], + const Ipp64u a [24], /* 32-byte zero-padded */ + const Ipp64u b [20], + const Ipp64u m [24], /* 32-byte zero-padded */ + Ipp64u k0)) +{ + /* R0, R1, R2 holds result */ + U64 R0 = get_zero64(); + U64 R1 = get_zero64(); + U64 R2 = get_zero64(); + + /* High part of 512bit result in 256bit mode */ + U64 R0h = get_zero64(); + U64 R1h = get_zero64(); + U64 R2h = get_zero64(); + + U64 Bi, Yi; + + Ipp64u m0 = m[0]; + Ipp64u a0 = a[0]; + Ipp64u acc0 = 0; + + int i; + for(i=0; i<20; i+=4) { + Ipp64u t0, t1, t2, yi; + + /* =================================== */ + Bi = set64((long long)b[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0, b[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2,acc0, 0,t0) + yi = (acc0 * k0) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + Yi = set64((long long)yi); + + t0 = _mulx_u64(m0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2,acc0, t1,t0) /* (t2:acc0) += (t1:t0) */ + acc0 = SHRD52(t2, acc0); + + fma52x8lo_mem(R0, R0, Bi, a, 64*0-8*0) + fma52x8lo_mem(R1, R1, Bi, a, 64*1-8*0) + fma52x8lo_mem_len(R2, R2, Bi, a, 64*2-8*0, 4) + fma52x8lo_mem(R0, R0, Yi, m, 64*0-8*0) + fma52x8lo_mem(R1, R1, Yi, m, 64*1-8*0) + fma52x8lo_mem_len(R2, R2, Yi, m, 64*2-8*0, 4) + + /* "shift" R */ + t0 = get64(R0, 1); + acc0 += t0; + + fma52x8hi_mem(R0, R0, Bi, a,64*0-8*1) /* U = A*Bi (hi) */ + fma52x8hi_mem(R1, R1, Bi, a,64*1-8*1) + fma52x8hi_mem(R2, R2, Bi, a,64*2-8*1) + fma52x8hi_mem(R0, R0, Yi, m,64*0-8*1) /* R += M*Yi (hi) */ + fma52x8hi_mem(R1, R1, Yi, m,64*1-8*1) + fma52x8hi_mem(R2, R2, Yi, m,64*2-8*1) + + /* =================================== */ + Bi = set64((long long)b[i+1]); /* broadcast(b[i+1]) */ + /* compute yi */ + t0 = _mulx_u64(a0, b[i+1], &t2); /* (t2:t0) = acc0 + a[0]*b[i+1] */ + ADD104(t2,acc0, 0,t0) + yi = (acc0 * k0) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + Yi = set64((long long)yi); + + t0 = _mulx_u64(m0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2,acc0, t1,t0) /* (t2:acc0) += (t1:t0) */ + acc0 = SHRD52(t2, acc0); + + fma52x8lo_mem(R0, R0, Bi, a,64*0-8*1) + fma52x8lo_mem(R1, R1, Bi, a,64*1-8*1) + fma52x8lo_mem(R2, R2, Bi, a,64*2-8*1) + fma52x8lo_mem(R0, R0, Yi, m,64*0-8*1) + fma52x8lo_mem(R1, R1, Yi, m,64*1-8*1) + fma52x8lo_mem(R2, R2, Yi, m,64*2-8*1) + + /* "shift" R */ + t0 = get64(R0, 2); + acc0 += t0; + + fma52x8hi_mem(R0, R0, Bi, a,64*0-8*2) /* U = A*Bi (hi) */ + fma52x8hi_mem(R1, R1, Bi, a,64*1-8*2) + fma52x8hi_mem(R2, R2, Bi, a,64*2-8*2) + fma52x8hi_mem(R0, R0, Yi, m,64*0-8*2) /* R += M*Yi (hi) */ + fma52x8hi_mem(R1, R1, Yi, m,64*1-8*2) + fma52x8hi_mem(R2, R2, Yi, m,64*2-8*2) + + /* =================================== */ + Bi = set64((long long)b[i+2]); /* broadcast(b[i+2]) */ + /* compute yi */ + t0 = _mulx_u64(a0, b[i+2], &t2); /* (t2:t0) = acc0 + a[0]*b[i+2] */ + ADD104(t2,acc0, 0,t0) + yi = (acc0 * k0) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + Yi = set64((long long)yi); + + t0 = _mulx_u64(m0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2,acc0, t1,t0) /* (t2:acc0) += (t1:t0) */ + acc0 = SHRD52(t2, acc0); + + fma52x8lo_mem(R0, R0, Bi, a,64*0-8*2) + fma52x8lo_mem(R1, R1, Bi, a,64*1-8*2) + fma52x8lo_mem(R2, R2, Bi, a,64*2-8*2) + fma52x8lo_mem(R0, R0, Yi, m,64*0-8*2) + fma52x8lo_mem(R1, R1, Yi, m,64*1-8*2) + fma52x8lo_mem(R2, R2, Yi, m,64*2-8*2) + + /* "shift" R */ + t0 = get64(R0, 3); + acc0 += t0; + + fma52x8hi_mem(R0, R0, Bi, a,64*0-8*3) /* U = A*Bi (hi) */ + fma52x8hi_mem(R1, R1, Bi, a,64*1-8*3) + fma52x8hi_mem(R2, R2, Bi, a,64*2-8*3) + fma52x8hi_mem(R0, R0, Yi, m,64*0-8*3) /* R += M*Yi (hi) */ + fma52x8hi_mem(R1, R1, Yi, m,64*1-8*3) + fma52x8hi_mem(R2, R2, Yi, m,64*2-8*3) + + /* =================================== */ + Bi = set64((long long)b[i+3]); /* broadcast(b[i+3]) */ + /* compute yi */ + t0 = _mulx_u64(a0, b[i+3], &t2); /* (t2:t0) = acc0 + a[0]*b[i+3] */ + ADD104(t2,acc0, 0,t0) + yi = (acc0 * k0) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + Yi = set64((long long)yi); + + t0 = _mulx_u64(m0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2,acc0, t1,t0) /* (t2:acc0) += (t1:t0) */ + acc0 = SHRD52(t2, acc0); + + fma52x8lo_mem(R0, R0, Bi, a,64*0-8*3) + fma52x8lo_mem(R1, R1, Bi, a,64*1-8*3) + fma52x8lo_mem(R2, R2, Bi, a,64*2-8*3) + fma52x8lo_mem(R0, R0, Yi, m,64*0-8*3) + fma52x8lo_mem(R1, R1, Yi, m,64*1-8*3) + fma52x8lo_mem(R2, R2, Yi, m,64*2-8*3) + + /* shift R */ + shift64(R0, R1) + shift64(R1, R2) + shift64(R2, get_zero64()) + + t0 = get64(R0, 0); + acc0 += t0; + + fma52x8hi_mem(R0, R0, Bi, a, 64*0-8*0) /* U = A*Bi (hi) */ + fma52x8hi_mem(R1, R1, Bi, a, 64*1-8*0) + fma52x8hi_mem_len(R2, R2, Bi, a, 64*2-8*0, 4) + fma52x8hi_mem(R0, R0, Yi, m, 64*0-8*0) /* R += M*Yi (hi) */ + fma52x8hi_mem(R1, R1, Yi, m, 64*1-8*0) + fma52x8hi_mem_len(R2, R2, Yi, m, 64*2-8*0, 4) + } + + /* set up R0.0 == acc0 */ + Bi = set64((long long)acc0); + R0 = blend64(R0, Bi, 1); + + NORMALIZE_52x20(R0, R1, R2) + + storeu64(out + 0*4, R0); + storeu64(out + 1*4, R0h); + storeu64(out + 2*4, R1); + storeu64(out + 3*4, R1h); + storeu64(out + 4*4, R2); +} +#endif + +IPP_OWN_DEFN(void, ifma256_ams52x20, (Ipp64u out[20], + const Ipp64u a [20], + const Ipp64u m [20], + Ipp64u k0)) +{ + ifma256_amm52x20(out, a, a, m, k0); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x20_dual.c b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x20_dual.c new file mode 100644 index 000000000..a62077107 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x20_dual.c @@ -0,0 +1,182 @@ + /******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcpngmontexpstuff_avx512.h" + +#include "ifma_norm52x.h" +#include "ifma_math_avx512vl.h" +#include "ifma_rsa_arith.h" + +#define ADD104(rh, rl, ih, il) { \ + rl += il; \ + rh += ih; \ + rh += (rl>52U) | rh<<(64U-52U)) + +/* + * Almost Montgomery Multiplication in 2^52-radix + * + * Implements two independent interleaved multiplications. + * Data represented as 2 20-qwords arrays in 2^52-radix. + * + */ +IPP_OWN_DEFN(void, ifma256_amm52x20_dual, (Ipp64u out[2][20], + const Ipp64u a [2][20], + const Ipp64u b [2][20], + const Ipp64u m [2][20], + const Ipp64u k0 [2])) +{ + const Ipp64u *a_0 = a[0]; + const Ipp64u *b_0 = b[0]; + const Ipp64u *m_0 = m[0]; + Ipp64u m0_0 = m_0[0]; + Ipp64u a0_0 = a_0[0]; + Ipp64u acc0_0 = 0; + U64 R0_0, R1_0, R2_0, R0_0h, R1_0h, R2_0h; + R0_0 = R1_0 = R2_0 = R0_0h = R1_0h = R2_0h = get_zero64(); + + const Ipp64u *a_1 = a[1]; + const Ipp64u *b_1 = b[1]; + const Ipp64u *m_1 = m[1]; + Ipp64u m0_1 = m_1[0]; + Ipp64u a0_1 = a_1[0]; + Ipp64u acc0_1 = 0; + U64 R0_1, R1_1, R2_1, R0_1h, R1_1h, R2_1h; + R0_1 = R1_1 = R2_1 = R0_1h = R1_1h = R2_1h = get_zero64(); + + int i; + for (i=0; i<20; i++) { + { + Ipp64u t0, t1, t2, yi; + U64 Bi = set64((long long)b_0[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0_0, b_0[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0_0, 0, t0) + yi = (acc0_0 * k0[0]) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + U64 Yi = set64((long long)yi); + + t0 = _mulx_u64(m0_0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0_0, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0_0 = SHRD52(t2, acc0_0); + + fma52x8lo_mem(R0_0, R0_0, Bi, a_0, 64*0) + fma52x8lo_mem(R1_0, R1_0, Bi, a_0, 64*1) + fma52x8lo_mem_len(R2_0, R2_0, Bi, a_0, 64*2, 4) + fma52x8lo_mem(R0_0, R0_0, Yi, m_0, 64*0) + fma52x8lo_mem(R1_0, R1_0, Yi, m_0, 64*1) + fma52x8lo_mem_len(R2_0, R2_0, Yi, m_0, 64*2, 4) + + shift64_imm(R0_0, R0_0h, 1) + shift64_imm(R0_0h, R1_0, 1) + shift64_imm(R1_0, R1_0h, 1) + shift64_imm(R1_0h, R2_0, 1) + shift64_imm(R2_0, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0_0, 0); + acc0_0 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0_0, R0_0, Bi, a_0, 64*0) + fma52x8hi_mem(R1_0, R1_0, Bi, a_0, 64*1) + fma52x8hi_mem_len(R2_0, R2_0, Bi, a_0, 64*2, 4) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0_0, R0_0, Yi, m_0, 64*0) + fma52x8hi_mem(R1_0, R1_0, Yi, m_0, 64*1) + fma52x8hi_mem_len(R2_0, R2_0, Yi, m_0, 64*2, 4) + } + { + Ipp64u t0, t1, t2, yi; + U64 Bi = set64((long long)b_1[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0_1, b_1[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0_1, 0, t0) + yi = (acc0_1 * k0[1]) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + U64 Yi = set64((long long)yi); + + t0 = _mulx_u64(m0_1, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0_1, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0_1 = SHRD52(t2, acc0_1); + + fma52x8lo_mem(R0_1, R0_1, Bi, a_1, 64*0) + fma52x8lo_mem(R1_1, R1_1, Bi, a_1, 64*1) + fma52x8lo_mem_len(R2_1, R2_1, Bi, a_1, 64*2, 4) + fma52x8lo_mem(R0_1, R0_1, Yi, m_1, 64*0) + fma52x8lo_mem(R1_1, R1_1, Yi, m_1, 64*1) + fma52x8lo_mem_len(R2_1, R2_1, Yi, m_1, 64*2, 4) + + shift64_imm(R0_1, R0_1h, 1) + shift64_imm(R0_1h, R1_1, 1) + shift64_imm(R1_1, R1_1h, 1) + shift64_imm(R1_1h, R2_1, 1) + shift64_imm(R2_1, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0_1, 0); + acc0_1 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0_1, R0_1, Bi, a_1, 64*0) + fma52x8hi_mem(R1_1, R1_1, Bi, a_1, 64*1) + fma52x8hi_mem_len(R2_1, R2_1, Bi, a_1, 64*2, 4) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0_1, R0_1, Yi, m_1, 64*0) + fma52x8hi_mem(R1_1, R1_1, Yi, m_1, 64*1) + fma52x8hi_mem_len(R2_1, R2_1, Yi, m_1, 64*2, 4) + } + } + { + /* Normalize and store idx=0 */ + /* Set R0.0 == acc0 */ + U64 Bi = set64((long long)acc0_0); + R0_0 = blend64(R0_0, Bi, 1); + NORMALIZE_52x20(R0_0, R1_0, R2_0) + storeu64(out[0] + 0*4, R0_0); + storeu64(out[0] + 1*4, R0_0h); + storeu64(out[0] + 2*4, R1_0); + storeu64(out[0] + 3*4, R1_0h); + storeu64(out[0] + 4*4, R2_0); + } + { + /* Normalize and store idx=1 */ + /* Set R0.1 == acc1 */ + U64 Bi = set64((long long)acc0_1); + R0_1 = blend64(R0_1, Bi, 1); + NORMALIZE_52x20(R0_1, R1_1, R2_1) + storeu64(out[1] + 0*4, R0_1); + storeu64(out[1] + 1*4, R0_1h); + storeu64(out[1] + 2*4, R1_1); + storeu64(out[1] + 3*4, R1_1h); + storeu64(out[1] + 4*4, R2_1); + } +} + +IPP_OWN_DEFN(void, ifma256_ams52x20_dual, (Ipp64u out[2][20], + const Ipp64u a [2][20], + const Ipp64u m [2][20], + const Ipp64u k0 [2])) +{ + ifma256_amm52x20_dual(out, a, a, m, k0); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x30.c b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x30.c new file mode 100644 index 000000000..57c57f9fd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x30.c @@ -0,0 +1,142 @@ + /******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" + +#include "ifma_norm52x.h" +#include "ifma_math_avx512vl.h" +#include "ifma_rsa_arith.h" + +#define ADD104(rh, rl, ih, il) { \ + rl += il; \ + rh += ih; \ + rh += (rl>52U) | rh<<(64U-52U)) + +/* + * Almost Montgomery Multiplication in 2^52-radix + * + * Data represented as (30+2)-qwords arrays in 2^52-radix. + * + * Note: 2 high qwords - zero padding. + * + */ +IPP_OWN_DEFN(void, ifma256_amm52x30, (Ipp64u out[32], + const Ipp64u a [32], + const Ipp64u b [32], + const Ipp64u m [32], + Ipp64u k0)) +{ + U64 R0 = get_zero64(); + U64 R1 = get_zero64(); + U64 R2 = get_zero64(); + U64 R3 = get_zero64(); + + U64 R0h = get_zero64(); + U64 R1h = get_zero64(); + U64 R2h = get_zero64(); + U64 R3h = get_zero64(); + + U64 Bi, Yi; + + Ipp64u m0 = m[0]; + Ipp64u a0 = a[0]; + Ipp64u acc0 = 0; + + int i; + for (i=0; i<30; i++) { + Ipp64u t0, t1, t2, yi; + + Bi = set64((long long)b[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0, b[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0, 0, t0) + yi = (acc0 * k0) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + Yi = set64((long long)yi); + + t0 = _mulx_u64(m0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0 = SHRD52(t2, acc0); + + fma52x8lo_mem(R0, R0, Bi, a, 64*0) + fma52x8lo_mem(R1, R1, Bi, a, 64*1) + fma52x8lo_mem(R2, R2, Bi, a, 64*2) + fma52x8lo_mem(R3, R3, Bi, a, 64*3) + + fma52x8lo_mem(R0, R0, Yi, m, 64*0) + fma52x8lo_mem(R1, R1, Yi, m, 64*1) + fma52x8lo_mem(R2, R2, Yi, m, 64*2) + fma52x8lo_mem(R3, R3, Yi, m, 64*3) + + shift64_imm(R0, R0h, 1) + shift64_imm(R0h, R1, 1) + shift64_imm(R1, R1h, 1) + shift64_imm(R1h, R2, 1) + shift64_imm(R2, R2h, 1) + shift64_imm(R2h, R3, 1) + shift64_imm(R3, R3h, 1) + shift64_imm(R3h, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0, 0); + acc0 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0, R0, Bi, a, 64*0) + fma52x8hi_mem(R1, R1, Bi, a, 64*1) + fma52x8hi_mem(R2, R2, Bi, a, 64*2) + fma52x8hi_mem(R3, R3, Bi, a, 64*3) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0, R0, Yi, m, 64*0) + fma52x8hi_mem(R1, R1, Yi, m, 64*1) + fma52x8hi_mem(R2, R2, Yi, m, 64*2) + fma52x8hi_mem(R3, R3, Yi, m, 64*3) + } + + /* Set R0[0] == acc0 */ + Bi = set64((long long)acc0); + R0 = blend64(R0, Bi, 1); + + NORMALIZE_52x30(R0, R1, R2, R3) + + storeu64(out + 0*4, R0); + storeu64(out + 1*4, R0h); + storeu64(out + 2*4, R1); + storeu64(out + 3*4, R1h); + storeu64(out + 4*4, R2); + storeu64(out + 5*4, R2h); + storeu64(out + 6*4, R3); + storeu64(out + 7*4, R3h); +} + +IPP_OWN_DEFN(void, ifma256_ams52x30, (Ipp64u out[32], + const Ipp64u a [32], + const Ipp64u m [32], + Ipp64u k0)) +{ + ifma256_amm52x30(out, a, a, m, k0); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x30_dual.c b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x30_dual.c new file mode 100644 index 000000000..338387fc6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x30_dual.c @@ -0,0 +1,210 @@ + /******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcpngmontexpstuff_avx512.h" + +#include "ifma_math_avx512vl.h" +#include "ifma_norm52x.h" +#include "ifma_rsa_arith.h" + +#define ADD104(rh, rl, ih, il) { \ + rl += il; \ + rh += ih; \ + rh += (rl>52U) | rh<<(64U-52U)) + +/* + * Almost Montgomery Multiplication in 2^52-radix + * + * Implements two independent interleaved multiplications. + * Data represented as 2 (30+2)-qwords arrays in 2^52-radix. + * + * Note: 2 high qwords - zero padding. + * + */ +IPP_OWN_DEFN(void, ifma256_amm52x30_dual, (Ipp64u out[2][32], + const Ipp64u a [2][32], + const Ipp64u b [2][32], + const Ipp64u m [2][32], + const Ipp64u k0 [2])) +{ + const Ipp64u *a_0 = a[0]; + const Ipp64u *b_0 = b[0]; + const Ipp64u *m_0 = m[0]; + Ipp64u m0_0 = m_0[0]; + Ipp64u a0_0 = a_0[0]; + Ipp64u acc0_0 = 0; + U64 R0_0, R1_0, R2_0, R3_0, R0_0h, R1_0h, R2_0h, R3_0h; + R0_0 = R1_0 = R2_0 = R3_0 = R0_0h = R1_0h = R2_0h = R3_0h = get_zero64(); + + const Ipp64u *a_1 = a[1]; + const Ipp64u *b_1 = b[1]; + const Ipp64u *m_1 = m[1]; + Ipp64u m0_1 = m_1[0]; + Ipp64u a0_1 = a_1[0]; + Ipp64u acc0_1 = 0; + U64 R0_1, R1_1, R2_1, R3_1, R0_1h, R1_1h, R2_1h, R3_1h; + R0_1 = R1_1 = R2_1 = R3_1 = R0_1h = R1_1h = R2_1h = R3_1h = get_zero64(); + + int i; + for (i=0; i<30; i++) { + { + Ipp64u t0, t1, t2, yi; + U64 Bi = set64((long long)b_0[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0_0, b_0[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0_0, 0, t0) + yi = (acc0_0 * k0[0]) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + U64 Yi = set64((long long)yi); + + t0 = _mulx_u64(m0_0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0_0, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0_0 = SHRD52(t2, acc0_0); + + fma52x8lo_mem(R0_0, R0_0, Bi, a_0, 64*0) + fma52x8lo_mem(R1_0, R1_0, Bi, a_0, 64*1) + fma52x8lo_mem(R2_0, R2_0, Bi, a_0, 64*2) + fma52x8lo_mem(R3_0, R3_0, Bi, a_0, 64*3) + + fma52x8lo_mem(R0_0, R0_0, Yi, m_0, 64*0) + fma52x8lo_mem(R1_0, R1_0, Yi, m_0, 64*1) + fma52x8lo_mem(R2_0, R2_0, Yi, m_0, 64*2) + fma52x8lo_mem(R3_0, R3_0, Yi, m_0, 64*3) + + shift64_imm(R0_0, R0_0h, 1) + shift64_imm(R0_0h, R1_0, 1) + shift64_imm(R1_0, R1_0h, 1) + shift64_imm(R1_0h, R2_0, 1) + shift64_imm(R2_0, R2_0h, 1) + shift64_imm(R2_0h, R3_0, 1) + shift64_imm(R3_0, R3_0h, 1) + shift64_imm(R3_0h, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0_0, 0); + acc0_0 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0_0, R0_0, Bi, a_0, 64*0) + fma52x8hi_mem(R1_0, R1_0, Bi, a_0, 64*1) + fma52x8hi_mem(R2_0, R2_0, Bi, a_0, 64*2) + fma52x8hi_mem(R3_0, R3_0, Bi, a_0, 64*3) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0_0, R0_0, Yi, m_0, 64*0) + fma52x8hi_mem(R1_0, R1_0, Yi, m_0, 64*1) + fma52x8hi_mem(R2_0, R2_0, Yi, m_0, 64*2) + fma52x8hi_mem(R3_0, R3_0, Yi, m_0, 64*3) + } + { + Ipp64u t0, t1, t2, yi; + U64 Bi = set64((long long)b_1[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0_1, b_1[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0_1, 0, t0) + yi = (acc0_1 * k0[1]) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + U64 Yi = set64((long long)yi); + + t0 = _mulx_u64(m0_1, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0_1, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0_1 = SHRD52(t2, acc0_1); + + fma52x8lo_mem(R0_1, R0_1, Bi, a_1, 64*0) + fma52x8lo_mem(R1_1, R1_1, Bi, a_1, 64*1) + fma52x8lo_mem(R2_1, R2_1, Bi, a_1, 64*2) + fma52x8lo_mem(R3_1, R3_1, Bi, a_1, 64*3) + + fma52x8lo_mem(R0_1, R0_1, Yi, m_1, 64*0) + fma52x8lo_mem(R1_1, R1_1, Yi, m_1, 64*1) + fma52x8lo_mem(R2_1, R2_1, Yi, m_1, 64*2) + fma52x8lo_mem(R3_1, R3_1, Yi, m_1, 64*3) + + shift64_imm(R0_1, R0_1h, 1) + shift64_imm(R0_1h, R1_1, 1) + shift64_imm(R1_1, R1_1h, 1) + shift64_imm(R1_1h, R2_1, 1) + shift64_imm(R2_1, R2_1h, 1) + shift64_imm(R2_1h, R3_1, 1) + shift64_imm(R3_1, R3_1h, 1) + shift64_imm(R3_1h, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0_1, 0); + acc0_1 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0_1, R0_1, Bi, a_1, 64*0) + fma52x8hi_mem(R1_1, R1_1, Bi, a_1, 64*1) + fma52x8hi_mem(R2_1, R2_1, Bi, a_1, 64*2) + fma52x8hi_mem(R3_1, R3_1, Bi, a_1, 64*3) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0_1, R0_1, Yi, m_1, 64*0) + fma52x8hi_mem(R1_1, R1_1, Yi, m_1, 64*1) + fma52x8hi_mem(R2_1, R2_1, Yi, m_1, 64*2) + fma52x8hi_mem(R3_1, R3_1, Yi, m_1, 64*3) + } + } + { + /* Normalize and store idx=0 */ + /* Set R0.0 == acc0 */ + U64 Bi = set64((long long)acc0_0); + R0_0 = blend64(R0_0, Bi, 1); + + NORMALIZE_52x30(R0_0, R1_0, R2_0, R3_0) + + storeu64(out[0] + 0*4, R0_0); + storeu64(out[0] + 1*4, R0_0h); + storeu64(out[0] + 2*4, R1_0); + storeu64(out[0] + 3*4, R1_0h); + storeu64(out[0] + 4*4, R2_0); + storeu64(out[0] + 5*4, R2_0h); + storeu64(out[0] + 6*4, R3_0); + storeu64(out[0] + 7*4, R3_0h); + } + { + /* Normalize and store idx=1 */ + /* Set R0.1 == acc1 */ + U64 Bi = set64((long long)acc0_1); + R0_1 = blend64(R0_1, Bi, 1); + + NORMALIZE_52x30(R0_1, R1_1, R2_1, R3_1) + + storeu64(out[1] + 0*4, R0_1); + storeu64(out[1] + 1*4, R0_1h); + storeu64(out[1] + 2*4, R1_1); + storeu64(out[1] + 3*4, R1_1h); + storeu64(out[1] + 4*4, R2_1); + storeu64(out[1] + 5*4, R2_1h); + storeu64(out[1] + 6*4, R3_1); + storeu64(out[1] + 7*4, R3_1h); + } +} + +IPP_OWN_DEFN(void, ifma256_ams52x30_dual, (Ipp64u out[2][32], + const Ipp64u a [2][32], + const Ipp64u m [2][32], + const Ipp64u k0 [2])) +{ + ifma256_amm52x30_dual(out, a, a, m, k0); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x40.c b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x40.c new file mode 100644 index 000000000..a6ca19d98 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x40.c @@ -0,0 +1,150 @@ + /******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" + +#include "ifma_norm52x.h" +#include "ifma_math_avx512vl.h" +#include "ifma_rsa_arith.h" + +#define ADD104(rh, rl, ih, il) { \ + rl += il; \ + rh += ih; \ + rh += (rl>52U) | rh<<(64U-52U)) + +/* + * Almost Montgomery Multiplication in 2^52-radix + * + * Data represented as 40-qwords arrays in 2^52-radix. + * + */ +IPP_OWN_DEFN(void, ifma256_amm52x40, (Ipp64u out[40], + const Ipp64u a [40], + const Ipp64u b [40], + const Ipp64u m [40], + Ipp64u k0)) +{ + U64 R0 = get_zero64(); + U64 R1 = get_zero64(); + U64 R2 = get_zero64(); + U64 R3 = get_zero64(); + U64 R4 = get_zero64(); + + U64 R0h = get_zero64(); + U64 R1h = get_zero64(); + U64 R2h = get_zero64(); + U64 R3h = get_zero64(); + U64 R4h = get_zero64(); + + U64 Bi, Yi; + + Ipp64u m0 = m[0]; + Ipp64u a0 = a[0]; + Ipp64u acc0 = 0; + + int i; + for (i=0; i<40; i++) { + Ipp64u t0, t1, t2, yi; + + Bi = set64((long long)b[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0, b[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0, 0, t0) + yi = (acc0 * k0) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + Yi = set64((long long)yi); + + t0 = _mulx_u64(m0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0 = SHRD52(t2, acc0); + + fma52x8lo_mem(R0, R0, Bi, a, 64*0) + fma52x8lo_mem(R1, R1, Bi, a, 64*1) + fma52x8lo_mem(R2, R2, Bi, a, 64*2) + fma52x8lo_mem(R3, R3, Bi, a, 64*3) + fma52x8lo_mem(R4, R4, Bi, a, 64*4) + + fma52x8lo_mem(R0, R0, Yi, m, 64*0) + fma52x8lo_mem(R1, R1, Yi, m, 64*1) + fma52x8lo_mem(R2, R2, Yi, m, 64*2) + fma52x8lo_mem(R3, R3, Yi, m, 64*3) + fma52x8lo_mem(R4, R4, Yi, m, 64*4) + + shift64_imm(R0, R0h, 1) + shift64_imm(R0h, R1, 1) + shift64_imm(R1, R1h, 1) + shift64_imm(R1h, R2, 1) + shift64_imm(R2, R2h, 1) + shift64_imm(R2h, R3, 1) + shift64_imm(R3, R3h, 1) + shift64_imm(R3h, R4, 1) + shift64_imm(R4, R4h, 1) + shift64_imm(R4h, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0, 0); + acc0 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0, R0, Bi, a, 64*0) + fma52x8hi_mem(R1, R1, Bi, a, 64*1) + fma52x8hi_mem(R2, R2, Bi, a, 64*2) + fma52x8hi_mem(R3, R3, Bi, a, 64*3) + fma52x8hi_mem(R4, R4, Bi, a, 64*4) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0, R0, Yi, m, 64*0) + fma52x8hi_mem(R1, R1, Yi, m, 64*1) + fma52x8hi_mem(R2, R2, Yi, m, 64*2) + fma52x8hi_mem(R3, R3, Yi, m, 64*3) + fma52x8hi_mem(R4, R4, Yi, m, 64*4) + } + + /* Set R0[0] == acc0 */ + Bi = set64((long long)acc0); + R0 = blend64(R0, Bi, 1); + + NORMALIZE_52x40(R0, R1, R2, R3, R4) + + storeu64(out + 0*4, R0); + storeu64(out + 1*4, R0h); + storeu64(out + 2*4, R1); + storeu64(out + 3*4, R1h); + storeu64(out + 4*4, R2); + storeu64(out + 5*4, R2h); + storeu64(out + 6*4, R3); + storeu64(out + 7*4, R3h); + storeu64(out + 8*4, R4); + storeu64(out + 9*4, R4h); +} + +IPP_OWN_DEFN(void, ifma256_ams52x40, (Ipp64u out[40], + const Ipp64u a [40], + const Ipp64u m [40], + Ipp64u k0)) +{ + ifma256_amm52x40(out, a, a, m, k0); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x40_dual.c b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x40_dual.c new file mode 100644 index 000000000..f45c54dd5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_amm52x40_dual.c @@ -0,0 +1,224 @@ + /******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcpngmontexpstuff_avx512.h" + +#include "ifma_math_avx512vl.h" +#include "ifma_norm52x.h" +#include "ifma_rsa_arith.h" + +#define ADD104(rh, rl, ih, il) { \ + rl += il; \ + rh += ih; \ + rh += (rl>52U) | rh<<(64U-52U)) + +/* + * Almost Montgomery Multiplication in 2^52-radix + * + * Implements two independent interleaved multiplications. + * Data represented as 2 40-qwords arrays in 2^52-radix. + * + */ +IPP_OWN_DEFN(void, ifma256_amm52x40_dual, (Ipp64u out[2][40], + const Ipp64u a [2][40], + const Ipp64u b [2][40], + const Ipp64u m [2][40], + const Ipp64u k0 [2])) +{ + const Ipp64u *a_0 = a[0]; + const Ipp64u *b_0 = b[0]; + const Ipp64u *m_0 = m[0]; + Ipp64u m0_0 = m_0[0]; + Ipp64u a0_0 = a_0[0]; + Ipp64u acc0_0 = 0; + U64 R0_0, R1_0, R2_0, R3_0, R4_0, R0_0h, R1_0h, R2_0h, R3_0h, R4_0h; + R0_0 = R1_0 = R2_0 = R3_0 = R4_0 = R0_0h = R1_0h = R2_0h = R3_0h = R4_0h = get_zero64(); + + const Ipp64u *a_1 = a[1]; + const Ipp64u *b_1 = b[1]; + const Ipp64u *m_1 = m[1]; + Ipp64u m0_1 = m_1[0]; + Ipp64u a0_1 = a_1[0]; + Ipp64u acc0_1 = 0; + U64 R0_1, R1_1, R2_1, R3_1, R4_1, R0_1h, R1_1h, R2_1h, R3_1h, R4_1h; + R0_1 = R1_1 = R2_1 = R3_1 = R4_1 = R0_1h = R1_1h = R2_1h = R3_1h = R4_1h = get_zero64(); + + int i; + for (i=0; i<40; i++) { + { + Ipp64u t0, t1, t2, yi; + U64 Bi = set64((long long)b_0[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0_0, b_0[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0_0, 0, t0) + yi = (acc0_0 * k0[0]) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + U64 Yi = set64((long long)yi); + + t0 = _mulx_u64(m0_0, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0_0, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0_0 = SHRD52(t2, acc0_0); + + fma52x8lo_mem(R0_0, R0_0, Bi, a_0, 64*0) + fma52x8lo_mem(R1_0, R1_0, Bi, a_0, 64*1) + fma52x8lo_mem(R2_0, R2_0, Bi, a_0, 64*2) + fma52x8lo_mem(R3_0, R3_0, Bi, a_0, 64*3) + fma52x8lo_mem(R4_0, R4_0, Bi, a_0, 64*4) + + fma52x8lo_mem(R0_0, R0_0, Yi, m_0, 64*0) + fma52x8lo_mem(R1_0, R1_0, Yi, m_0, 64*1) + fma52x8lo_mem(R2_0, R2_0, Yi, m_0, 64*2) + fma52x8lo_mem(R3_0, R3_0, Yi, m_0, 64*3) + fma52x8lo_mem(R4_0, R4_0, Yi, m_0, 64*4) + + shift64_imm(R0_0, R0_0h, 1) + shift64_imm(R0_0h, R1_0, 1) + shift64_imm(R1_0, R1_0h, 1) + shift64_imm(R1_0h, R2_0, 1) + shift64_imm(R2_0, R2_0h, 1) + shift64_imm(R2_0h, R3_0, 1) + shift64_imm(R3_0, R3_0h, 1) + shift64_imm(R3_0h, R4_0, 1) + shift64_imm(R4_0, R4_0h, 1) + shift64_imm(R4_0h, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0_0, 0); + acc0_0 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0_0, R0_0, Bi, a_0, 64*0) + fma52x8hi_mem(R1_0, R1_0, Bi, a_0, 64*1) + fma52x8hi_mem(R2_0, R2_0, Bi, a_0, 64*2) + fma52x8hi_mem(R3_0, R3_0, Bi, a_0, 64*3) + fma52x8hi_mem(R4_0, R4_0, Bi, a_0, 64*4) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0_0, R0_0, Yi, m_0, 64*0) + fma52x8hi_mem(R1_0, R1_0, Yi, m_0, 64*1) + fma52x8hi_mem(R2_0, R2_0, Yi, m_0, 64*2) + fma52x8hi_mem(R3_0, R3_0, Yi, m_0, 64*3) + fma52x8hi_mem(R4_0, R4_0, Yi, m_0, 64*4) + } + { + Ipp64u t0, t1, t2, yi; + U64 Bi = set64((long long)b_1[i]); /* broadcast(b[i]) */ + /* compute yi */ + t0 = _mulx_u64(a0_1, b_1[i], &t2); /* (t2:t0) = acc0 + a[0]*b[i] */ + ADD104(t2, acc0_1, 0, t0) + yi = (acc0_1 * k0[1]) & EXP_DIGIT_MASK_AVX512; /* yi = acc0*k0 */ + U64 Yi = set64((long long)yi); + + t0 = _mulx_u64(m0_1, yi, &t1); /* (t1:t0) = m0*yi */ + ADD104(t2, acc0_1, t1, t0) /* (t2:acc0) += (t1:t0) */ + acc0_1 = SHRD52(t2, acc0_1); + + fma52x8lo_mem(R0_1, R0_1, Bi, a_1, 64*0) + fma52x8lo_mem(R1_1, R1_1, Bi, a_1, 64*1) + fma52x8lo_mem(R2_1, R2_1, Bi, a_1, 64*2) + fma52x8lo_mem(R3_1, R3_1, Bi, a_1, 64*3) + fma52x8lo_mem(R4_1, R4_1, Bi, a_1, 64*4) + + fma52x8lo_mem(R0_1, R0_1, Yi, m_1, 64*0) + fma52x8lo_mem(R1_1, R1_1, Yi, m_1, 64*1) + fma52x8lo_mem(R2_1, R2_1, Yi, m_1, 64*2) + fma52x8lo_mem(R3_1, R3_1, Yi, m_1, 64*3) + fma52x8lo_mem(R4_1, R4_1, Yi, m_1, 64*4) + + shift64_imm(R0_1, R0_1h, 1) + shift64_imm(R0_1h, R1_1, 1) + shift64_imm(R1_1, R1_1h, 1) + shift64_imm(R1_1h, R2_1, 1) + shift64_imm(R2_1, R2_1h, 1) + shift64_imm(R2_1h, R3_1, 1) + shift64_imm(R3_1, R3_1h, 1) + shift64_imm(R3_1h, R4_1, 1) + shift64_imm(R4_1, R4_1h, 1) + shift64_imm(R4_1h, get_zero64(), 1) + + /* "shift" R */ + t0 = get64(R0_1, 0); + acc0_1 += t0; + + /* U = A*Bi (hi) */ + fma52x8hi_mem(R0_1, R0_1, Bi, a_1, 64*0) + fma52x8hi_mem(R1_1, R1_1, Bi, a_1, 64*1) + fma52x8hi_mem(R2_1, R2_1, Bi, a_1, 64*2) + fma52x8hi_mem(R3_1, R3_1, Bi, a_1, 64*3) + fma52x8hi_mem(R4_1, R4_1, Bi, a_1, 64*4) + /* R += M*Yi (hi) */ + fma52x8hi_mem(R0_1, R0_1, Yi, m_1, 64*0) + fma52x8hi_mem(R1_1, R1_1, Yi, m_1, 64*1) + fma52x8hi_mem(R2_1, R2_1, Yi, m_1, 64*2) + fma52x8hi_mem(R3_1, R3_1, Yi, m_1, 64*3) + fma52x8hi_mem(R4_1, R4_1, Yi, m_1, 64*4) + } + } + { + /* Normalize and store idx=0 */ + /* Set R0.0 == acc0 */ + U64 Bi = set64((long long)acc0_0); + R0_0 = blend64(R0_0, Bi, 1); + + NORMALIZE_52x40(R0_0, R1_0, R2_0, R3_0, R4_0) + + storeu64(out[0] + 0*4, R0_0); + storeu64(out[0] + 1*4, R0_0h); + storeu64(out[0] + 2*4, R1_0); + storeu64(out[0] + 3*4, R1_0h); + storeu64(out[0] + 4*4, R2_0); + storeu64(out[0] + 5*4, R2_0h); + storeu64(out[0] + 6*4, R3_0); + storeu64(out[0] + 7*4, R3_0h); + storeu64(out[0] + 8*4, R4_0); + storeu64(out[0] + 9*4, R4_0h); + } + { + /* Normalize and store idx=1 */ + /* Set R0.1 == acc1 */ + U64 Bi = set64((long long)acc0_1); + R0_1 = blend64(R0_1, Bi, 1); + + NORMALIZE_52x40(R0_1, R1_1, R2_1, R3_1, R4_1) + + storeu64(out[1] + 0*4, R0_1); + storeu64(out[1] + 1*4, R0_1h); + storeu64(out[1] + 2*4, R1_1); + storeu64(out[1] + 3*4, R1_1h); + storeu64(out[1] + 4*4, R2_1); + storeu64(out[1] + 5*4, R2_1h); + storeu64(out[1] + 6*4, R3_1); + storeu64(out[1] + 7*4, R3_1h); + storeu64(out[1] + 8*4, R4_1); + storeu64(out[1] + 9*4, R4_1h); + } +} + +IPP_OWN_DEFN(void, ifma256_ams52x40_dual, (Ipp64u out[2][40], + const Ipp64u a [2][40], + const Ipp64u m [2][40], + const Ipp64u k0 [2])) +{ + ifma256_amm52x40_dual(out, a, a, m, k0); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x20.c b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x20.c new file mode 100644 index 000000000..61c5394dc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x20.c @@ -0,0 +1,161 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" +#include "ifma_math_avx512vl.h" +#include "ifma_rsa_arith.h" + +#define BITSIZE_MODULUS (1024) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,52)) // 20 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) // 16 + +#define EXP_WIN_SIZE (5U) +#define EXP_WIN_MASK ((1U<> exp_chunk_shift; + + extract_multiplier(red_Y, (const Ipp64u(*)[LEN52])red_table, (int)red_table_idx); + + /* process other exp windows */ + for (exp_bit_no -= EXP_WIN_SIZE; exp_bit_no >= 0; exp_bit_no -= EXP_WIN_SIZE) { + /* series of squaring */ + AMS(red_Y, red_Y, modulus, k0); + AMS(red_Y, red_Y, modulus, k0); + AMS(red_Y, red_Y, modulus, k0); + AMS(red_Y, red_Y, modulus, k0); + AMS(red_Y, red_Y, modulus, k0); + + /* extract pre-computed multiplier from the table */ + { + Ipp64u T; + exp_chunk_no = exp_bit_no / 64; + exp_chunk_shift = exp_bit_no % 64; + + red_table_idx = expz[exp_chunk_no]; + T = expz[exp_chunk_no+1]; + + red_table_idx = red_table_idx >> exp_chunk_shift; + T = exp_chunk_shift == 0 ? 0 : T << (64 - exp_chunk_shift); + red_table_idx = (red_table_idx ^ T) & table_idx_mask; + + extract_multiplier(red_X, (const Ipp64u(*)[LEN52])red_table, (int)red_table_idx); + AMM(red_Y, red_Y, red_X, modulus, k0); + } + } + } + + /* clear exponents */ + PurgeBlock((Ipp64u*)expz, (LEN64+1)*(int)sizeof(Ipp64u)); + + /* convert result back in regular 2^52 domain */ + ZEXPAND_BNU(red_X, 0, LEN52); + red_X[0] = 1ULL; + AMM(out, red_Y, red_X, modulus, k0); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x20_dual.c b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x20_dual.c new file mode 100644 index 000000000..19599e73e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x20_dual.c @@ -0,0 +1,185 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" +#include "ifma_math_avx512vl.h" +#include "ifma_rsa_arith.h" + +#define BITSIZE_MODULUS (1024) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,52)) // 20 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) // 16 + +#define EXP_WIN_SIZE (5U) +#define EXP_WIN_MASK ((1U<> exp_chunk_shift; + red_table_idx_1 = red_table_idx_1 >> exp_chunk_shift; + + extract_multiplier_n(red_Y[0], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_0, 0); + extract_multiplier_n(red_Y[1], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_1, 1); + + /* process other exp windows */ + for (exp_bit_no -= EXP_WIN_SIZE; exp_bit_no >= 0; exp_bit_no -= EXP_WIN_SIZE) { + /* extract pre-computed multiplier from the table */ + { + Ipp64u T; + exp_chunk_no = exp_bit_no / 64; + exp_chunk_shift = exp_bit_no % 64; + { + red_table_idx_0 = expz[0][exp_chunk_no]; + T = expz[0][exp_chunk_no + 1]; + + red_table_idx_0 = red_table_idx_0 >> exp_chunk_shift; + T = exp_chunk_shift == 0 ? 0 : T << (64 - exp_chunk_shift); + red_table_idx_0 = (red_table_idx_0 ^ T) & table_idx_mask; + + extract_multiplier_n(red_X[0], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_0, 0); + } + { + red_table_idx_1 = expz[1][exp_chunk_no]; + T = expz[1][exp_chunk_no + 1]; + + red_table_idx_1 = red_table_idx_1 >> exp_chunk_shift; + T = exp_chunk_shift == 0 ? 0 : T << (64 - exp_chunk_shift); + red_table_idx_1 = (red_table_idx_1 ^ T) & table_idx_mask; + + extract_multiplier_n(red_X[1], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_1, 1); + } + + } + + /* series of squaring */ + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + + DAMM(red_Y, (const Ipp64u(*)[LEN52])red_Y, (const Ipp64u(*)[LEN52])red_X, modulus, k0); + } + } + + /* clear exponents */ + PurgeBlock((Ipp64u*)expz, 2*(LEN64+1)*(int)sizeof(Ipp64u)); + + /* convert result back in regular 2^52 domain */ + ZEXPAND_BNU((Ipp64u*)red_X, 0, 2*LEN52); + storeu64(&red_X[0][0], _mm256_setr_epi64x(1,0,0,0)); + storeu64(&red_X[1][0], _mm256_setr_epi64x(1,0,0,0)); + DAMM(out, (const Ipp64u(*)[LEN52])red_Y, (const Ipp64u(*)[LEN52])red_X, modulus, k0); + + PurgeBlock((Ipp64u*)red_Y, 2*LEN52*(int)sizeof(Ipp64u)); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x30_dual.c b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x30_dual.c new file mode 100644 index 000000000..22e995130 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x30_dual.c @@ -0,0 +1,190 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" +#include "ifma_math_avx512vl.h" +#include "ifma_rsa_arith.h" + +#define BITSIZE_MODULUS (1536) +#define LEN52 ((NUMBER_OF_DIGITS(BITSIZE_MODULUS,52)) + 2) // 30 + 2 (with zero-padding) +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) // 24 + +#define EXP_WIN_SIZE (5U) +#define EXP_WIN_MASK ((1U<> exp_chunk_shift; + red_table_idx_1 = red_table_idx_1 >> exp_chunk_shift; + + extract_multiplier_n(red_Y[0], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_0, 0); + extract_multiplier_n(red_Y[1], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_1, 1); + + /* process other exp windows */ + for (exp_bit_no -= EXP_WIN_SIZE; exp_bit_no >= 0; exp_bit_no -= EXP_WIN_SIZE) { + /* extract pre-computed multiplier from the table */ + { + Ipp64u T; + exp_chunk_no = exp_bit_no / 64; + exp_chunk_shift = exp_bit_no % 64; + { + red_table_idx_0 = expz[0][exp_chunk_no]; + T = expz[0][exp_chunk_no + 1]; + + red_table_idx_0 = red_table_idx_0 >> exp_chunk_shift; + T = exp_chunk_shift == 0 ? 0 : T << (64 - exp_chunk_shift); + red_table_idx_0 = (red_table_idx_0 ^ T) & table_idx_mask; + + extract_multiplier_n(red_X[0], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_0, 0); + } + { + red_table_idx_1 = expz[1][exp_chunk_no]; + T = expz[1][exp_chunk_no + 1]; + + red_table_idx_1 = red_table_idx_1 >> exp_chunk_shift; + T = exp_chunk_shift == 0 ? 0 : T << (64 - exp_chunk_shift); + red_table_idx_1 = (red_table_idx_1 ^ T) & table_idx_mask; + + extract_multiplier_n(red_X[1], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_1, 1); + } + + } + + /* series of squaring */ + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + + DAMM(red_Y, (const Ipp64u(*)[LEN52])red_Y, (const Ipp64u(*)[LEN52])red_X, modulus, k0); + } + } + + /* clear exponents */ + PurgeBlock((Ipp64u*)expz, 2*(LEN64+1)*(int)sizeof(Ipp64u)); + + /* convert result back in regular 2^52 domain */ + ZEXPAND_BNU((Ipp64u*)red_X, 0, 2*LEN52); + storeu64(&red_X[0][0], _mm256_setr_epi64x(1,0,0,0)); + storeu64(&red_X[1][0], _mm256_setr_epi64x(1,0,0,0)); + DAMM(out, (const Ipp64u(*)[LEN52])red_Y, (const Ipp64u(*)[LEN52])red_X, modulus, k0); + + PurgeBlock((Ipp64u*)red_Y, 2*LEN52*(int)sizeof(Ipp64u)); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x40_dual.c b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x40_dual.c new file mode 100644 index 000000000..5b20e5d88 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x40_dual.c @@ -0,0 +1,195 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" +#include "ifma_math_avx512vl.h" +#include "ifma_rsa_arith.h" + +#define BITSIZE_MODULUS (2048) +#define LEN52 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,52)) // 40 +#define LEN64 (NUMBER_OF_DIGITS(BITSIZE_MODULUS,64)) // 32 + +#define EXP_WIN_SIZE (5U) +#define EXP_WIN_MASK ((1U<> exp_chunk_shift; + red_table_idx_1 = red_table_idx_1 >> exp_chunk_shift; + + extract_multiplier_n(red_Y[0], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_0, 0); + extract_multiplier_n(red_Y[1], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_1, 1); + + /* process other exp windows */ + for (exp_bit_no -= EXP_WIN_SIZE; exp_bit_no >= 0; exp_bit_no -= EXP_WIN_SIZE) { + /* extract pre-computed multiplier from the table */ + { + Ipp64u T; + exp_chunk_no = exp_bit_no / 64; + exp_chunk_shift = exp_bit_no % 64; + { + red_table_idx_0 = expz[0][exp_chunk_no]; + T = expz[0][exp_chunk_no + 1]; + + red_table_idx_0 = red_table_idx_0 >> exp_chunk_shift; + T = exp_chunk_shift == 0 ? 0 : T << (64 - exp_chunk_shift); + red_table_idx_0 = (red_table_idx_0 ^ T) & table_idx_mask; + + extract_multiplier_n(red_X[0], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_0, 0); + } + { + red_table_idx_1 = expz[1][exp_chunk_no]; + T = expz[1][exp_chunk_no + 1]; + + red_table_idx_1 = red_table_idx_1 >> exp_chunk_shift; + T = exp_chunk_shift == 0 ? 0 : T << (64 - exp_chunk_shift); + red_table_idx_1 = (red_table_idx_1 ^ T) & table_idx_mask; + + extract_multiplier_n(red_X[1], (const Ipp64u(*)[2][LEN52])red_table, (int)red_table_idx_1, 1); + } + + } + + /* series of squaring */ + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + DAMS(red_Y, (const Ipp64u(*)[LEN52])red_Y, modulus, k0); + + DAMM(red_Y, (const Ipp64u(*)[LEN52])red_Y, (const Ipp64u(*)[LEN52])red_X, modulus, k0); + } + } + + /* clear exponents */ + PurgeBlock((Ipp64u*)expz, 2*(LEN64+1)*(int)sizeof(Ipp64u)); + + /* convert result back in regular 2^52 domain */ + ZEXPAND_BNU((Ipp64u*)red_X, 0, 2*LEN52); + storeu64(&red_X[0][0], _mm256_setr_epi64x(1,0,0,0)); + storeu64(&red_X[1][0], _mm256_setr_epi64x(1,0,0,0)); + DAMM(out, (const Ipp64u(*)[LEN52])red_Y, (const Ipp64u(*)[LEN52])red_X, modulus, k0); + + PurgeBlock((Ipp64u*)red_Y, 2*LEN52*(int)sizeof(Ipp64u)); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x_dual.c b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x_dual.c new file mode 100644 index 000000000..6e33fa2e2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_exp52x_dual.c @@ -0,0 +1,136 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +#include "pcptool.h" + +#include "pcpngmontexpstuff_avx512.h" +#include "ifma_rsa_arith.h" + +IPP_OWN_DEFN (cpSize, gsMontDualExpWinBuffer_avx512, (int modulusBits)) +{ + cpSize redNum = numofVariable_avx512(modulusBits); + /* Reg (ymm) capacity = 4 qwords */ + cpSize redBufferNum = numofVariableBuff_avx512(redNum, 4); + return redBufferNum * 2 * 8; +} + +IPP_OWN_FUNPTR (void, AMM52, (Ipp64u *out, const Ipp64u *a, const Ipp64u *b, const Ipp64u *m, Ipp64u k0)) +IPP_OWN_FUNPTR (void, DEXP52, (Ipp64u* out, const Ipp64u* base, const Ipp64u* exp[2], const Ipp64u* modulus, const Ipp64u* pMont, const Ipp64u k0[2])) + +IPP_OWN_DEFN (cpSize, gsMontDualExpWin_BNU_sscm_avx512, (BNU_CHUNK_T* dataY[2], + const BNU_CHUNK_T* dataX[2], + cpSize nsX[2], + const BNU_CHUNK_T* dataE[2], + gsModEngine* pMont[2], + BNU_CHUNK_T* pBuffer)) +{ + const BNU_CHUNK_T* modulus[2] = {0}; + const BNU_CHUNK_T* rr[2] = {0}; + cpSize modulusSize[2] = {0}; + BNU_CHUNK_T k0[2] = {0}; + + modulus[0] = MOD_MODULUS(pMont[0]); + modulus[1] = MOD_MODULUS(pMont[1]); + modulusSize[0] = MOD_LEN(pMont[0]); + modulusSize[1] = MOD_LEN(pMont[1]); + rr[0] = MOD_MNT_R2(pMont[0]); + rr[1] = MOD_MNT_R2(pMont[1]); + k0[0] = MOD_MNT_FACTOR(pMont[0]); + k0[1] = MOD_MNT_FACTOR(pMont[1]); + + /* + * Dual expo implemenentation assumes that bit sizes of P and Q are + * the same, so query size from the first. + */ + int modulusBitSize = BITSIZE_BNU(modulus[0], modulusSize[0]); + int redLen = NUMBER_OF_DIGITS(modulusBitSize + 2, EXP_DIGIT_SIZE_AVX512); + /* For ymm-based implementation reg capacity = 4 qwords */ + int redBufferLen = numofVariableBuff_avx512(redLen, 4); + + /* Allocate buffers */ + BNU_CHUNK_T* redX = pBuffer; + BNU_CHUNK_T* redM = redX + 2*redBufferLen; + BNU_CHUNK_T* redRR = redM + 2*redBufferLen; + BNU_CHUNK_T* redCoeff = redRR + 2*redBufferLen; + BNU_CHUNK_T* redBuffer = redCoeff + redBufferLen; + + AMM52 ammFunc = NULL; + DEXP52 dexpFunc = NULL; + switch (modulusBitSize) { + case 1024: + ammFunc = ifma256_amm52x20; + dexpFunc = (DEXP52)ifma256_exp52x20_dual; + break; + case 1536: + ammFunc = ifma256_amm52x30; + dexpFunc = (DEXP52)ifma256_exp52x30_dual; + break; + case 2048: + ammFunc = ifma256_amm52x40; + dexpFunc = (DEXP52)ifma256_exp52x40_dual; + break; + default: + /* Other modulus sizes not supported. This function shall not be called for them. */ + return 0; + } + + ZEXPAND_BNU(redCoeff, 0, redBufferLen); + int conv_coeff = 4 * (EXP_DIGIT_SIZE_AVX512 * redLen - modulusBitSize); + /* Set corresponding bit in reduced domain */ + SET_BIT(redCoeff, 64 * (int)(conv_coeff / 52) + conv_coeff % 52); + + for (int i = 0; i < 2; i++) { + /* Convert base into redundant domain */ + ZEXPAND_COPY_BNU(redBuffer, redBufferLen, dataX[i], nsX[i]); + regular_dig52(redX + i*redBufferLen, redBufferLen, redBuffer, modulusBitSize); + + /* Convert modulus into redundant domain */ + ZEXPAND_COPY_BNU(redBuffer, redBufferLen, modulus[i], modulusSize[i]); + regular_dig52(redM + i*redBufferLen, redBufferLen, redBuffer, modulusBitSize); + + /* + * Compute target domain Montgomery converter RR' based on original domain RR. + * + * Example: modlen = 1024: RR = 2^2048 mod m, RR' = 2^2080 mod m + * conv_coeff = 2^64 + * (1st amm): 2^2048*2^2048/2^1040= 2^3056 mod m + * (2nd amm): 2^3056*2^64/2^1040 = 2^2080 mod m + * + */ + ZEXPAND_COPY_BNU(redBuffer, redBufferLen, rr[i], modulusSize[i]); + regular_dig52(redRR + i*redBufferLen, redBufferLen, redBuffer, modulusBitSize); + ammFunc(redRR + i*redBufferLen, redRR + i*redBufferLen, redRR + i*redBufferLen, redM + i*redBufferLen, k0[i]); + ammFunc(redRR + i*redBufferLen, redRR + i*redBufferLen, redCoeff, redM + i*redBufferLen, k0[i]); + } + + dexpFunc(redRR, redX, dataE, redM, redRR, k0); + + /* Convert result back to regular domain */ + for (int i = 0; i < 2; i++) + dig52_regular(dataY[i], redRR + i*redBufferLen, modulusBitSize); + + /* Clear redundant exponents buffer */ + PurgeBlock(redRR, 2*redBufferLen*(int)sizeof(BNU_CHUNK_T)); + + return (modulusSize[0] + modulusSize[1]); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_math_avx512vl.h b/plugin/ippcp/library/src/sources/ippcp/ifma_math_avx512vl.h new file mode 100644 index 000000000..f7a950c82 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_math_avx512vl.h @@ -0,0 +1,208 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#ifndef IFMA_MATH_AVX512VL_H +#define IFMA_MATH_AVX512VL_H + +/* + * This header provides low-level abstraction for 256-bit AVX512VL + * ISA instructions. + * + */ + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // for MSVC + #pragma warning(disable:4101) + #pragma warning(disable:4127) // warning: conditional expression is constant (see fma52x8lo_mem_len()) +#elif defined (__INTEL_COMPILER) + #pragma warning(disable:177) +#endif + +#include + +#ifndef SIMD_LEN +#define SIMD_LEN 256 +#endif + +#define SIMD_TYPE(LEN) typedef __m ## LEN ## i U64; + +#if (SIMD_LEN == 256) + SIMD_TYPE(256) + #define SIMD_BYTES (SIMD_LEN/8) + #define SIMD_QWORDS (SIMD_LEN/64) + + __INLINE U64 loadu64(const void *p) { + return _mm256_loadu_si256((U64*)p); + } + + __INLINE void storeu64(const void *p, U64 v) { + _mm256_storeu_si256((U64*)p, v); + } + + #define set64 _mm256_set1_epi64x + + #ifdef __GNUC__ + static U64 fma52lo(U64 a, U64 b, U64 c) + { + __asm__ ( "vpmadd52luq %2, %1, %0" : "+x" (a): "x" (b), "x" (c) ); + return a; + } + + static U64 fma52hi(U64 a, U64 b, U64 c) + { + __asm__ ( "vpmadd52huq %2, %1, %0" : "+x" (a): "x" (b), "x" (c) ); + return a; + } + + #define _mm_madd52lo_epu64_(r, a, b, c, o) \ + { \ + r=a; \ + __asm__ ( "vpmadd52luq " #o "(%2), %1, %0" : "+x" (r): "x" (b), "r" (c) ); \ + } + + #define _mm_madd52hi_epu64_(r, a, b, c, o) \ + { \ + r=a; \ + __asm__ ( "vpmadd52huq " #o "(%2), %1, %0" : "+x" (r): "x" (b), "r" (c) ); \ + } + #else + /* Use IFMA instrinsics for all other compilers */ + static U64 fma52lo(U64 a, U64 b, U64 c) + { + return _mm256_madd52lo_epu64(a, b, c); + } + + static U64 fma52hi(U64 a, U64 b, U64 c) + { + return _mm256_madd52hi_epu64(a, b, c); + } + + #define _mm_madd52lo_epu64_(r, a, b, c, o) \ + { \ + r=fma52lo(a, b, loadu64((U64*)(((char*)c)+o))); \ + } + + #define _mm_madd52hi_epu64_(r, a, b, c, o) \ + { \ + r=fma52hi(a, b, loadu64((U64*)(((char*)c)+o))); \ + } + #endif + + __INLINE U64 mul52lo(U64 b, U64 c) + { + return fma52lo(_mm256_setzero_si256(), b, c); + } + + #define fma52lo_mem(r, a, b, c, o) _mm_madd52lo_epu64_(r, a, b, c, o) + #define fma52hi_mem(r, a, b, c, o) _mm_madd52hi_epu64_(r, a, b, c, o) + + __INLINE U64 add64(U64 a, U64 b) + { + return _mm256_add_epi64(a, b); + } + + __INLINE U64 sub64(U64 a, U64 b) + { + return _mm256_sub_epi64(a, b); + } + + __INLINE U64 get_zero64() + { + return _mm256_setzero_si256(); + } + + __INLINE void set_zero64(U64 *a) + { + *a = _mm256_xor_si256(*a, *a); + } + + __INLINE U64 set1(unsigned long long a) + { + return _mm256_set1_epi64x((long long)a); + } + + __INLINE U64 srli64(U64 a, int s) + { + return _mm256_srli_epi64(a, s); + } + + #define slli64 _mm256_slli_epi64 + + __INLINE U64 and64_const(U64 a, unsigned long long mask) + { + return _mm256_and_si256(a, _mm256_set1_epi64x((long long)mask)); + } + + __INLINE U64 and64(U64 a, U64 mask) + { + return _mm256_and_si256(a, mask); + } + + #define or64 _mm256_or_si256 + #define xor64 _mm256_xor_si256 + + static Ipp64u get64(U64 v, int idx) { + long long int res; + switch (idx) { + case 1: res = _mm256_extract_epi64(v, 1); break; + case 2: res = _mm256_extract_epi64(v, 2); break; + case 3: res = _mm256_extract_epi64(v, 3); break; + default: res = _mm256_extract_epi64(v, 0); + } + return (Ipp64u)res; + } + + #define fma52x8lo_mem(r, a, b, c, o) \ + fma52lo_mem(r, a, b, c, o); \ + fma52lo_mem(r ## h, a ## h, b, c, (o) + 32); + + #define fma52x8hi_mem(r, a, b, c, o) \ + fma52hi_mem(r, a, b, c, o); \ + fma52hi_mem(r ## h, a ## h, b, c, (o) + 32); + + #define fma52x8lo_mem_len(r, a, b, c, o, l) \ + fma52lo_mem(r, a, b, c, o); \ + if (l > 4) { fma52lo_mem(r ## h, a ## h, b, c, (o) + 32); } + + #define fma52x8hi_mem_len(r, a, b, c, o, l) \ + fma52hi_mem(r, a, b, c, o); \ + if (l > 4) { fma52hi_mem(r ## h, a ## h, b, c, (o) + 32); } + + #define fma52x8lo_mask_mem(r, m, a, b, c, o) \ + fma52lo_mem(r, a, b, c, o); \ + fma52lo_mem(r ## h, a ## h, b, c, (o) + 32); + + #define fma52x8hi_mask_mem(r, m, a, b, c, o) \ + fma52hi_mem(r, a, b, c, o); \ + fma52hi_mem(r ## h, a ## h, b, c, (o) + 32); + + #define shift64(R0, R1) { \ + R0 = R0 ## h; \ + R0 ## h = R1; } + + #define shift64_imm(R0, R1, imm) \ + R0 = _mm256_alignr_epi64(R1, R0, imm); + + #define blend64(a, b, m) \ + _mm256_blend_epi32(a, b, (int)(0x3<<((m-1)<<1))); + +#else + #error "Incorrect SIMD length" +#endif // SIMD_LEN + +#endif // IFMA_MATH_AVX512VL_H diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_norm52x.h b/plugin/ippcp/library/src/sources/ippcp/ifma_norm52x.h new file mode 100644 index 000000000..704aa46f1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_norm52x.h @@ -0,0 +1,315 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#ifndef IFMA_NORM_52X_H +#define IFMA_NORM_52X_H + +#define NORMALIZE_52x20(R0,R1,R2) { \ + __m256i T0 = _mm256_srli_epi64(R0, EXP_DIGIT_SIZE_AVX512); \ + __m256i T0h = _mm256_srli_epi64(R0 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T1 = _mm256_srli_epi64(R1, EXP_DIGIT_SIZE_AVX512); \ + __m256i T1h = _mm256_srli_epi64(R1 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T2 = _mm256_srli_epi64(R2, EXP_DIGIT_SIZE_AVX512); \ + __m256i MASK = _mm256_set1_epi64x(EXP_DIGIT_MASK_AVX512); \ + \ + Ipp32u kk0, kk1, kk2; \ + Ipp32u kk0h, kk1h; \ + kk0 = kk1 = kk2 = kk0h = kk1h = 0; \ + \ + R0 = _mm256_and_si256(R0, MASK); \ + R1 = _mm256_and_si256(R1, MASK); \ + R2 = _mm256_and_si256(R2, MASK); \ + R0 ## h = _mm256_and_si256(R0 ## h, MASK); \ + R1 ## h = _mm256_and_si256(R1 ## h, MASK); \ + \ + T2 = _mm256_alignr_epi64(T2, T1h, 3); \ + T1h = _mm256_alignr_epi64(T1h, T1, 3); \ + T1 = _mm256_alignr_epi64(T1, T0h, 3); \ + T0h = _mm256_alignr_epi64(T0h, T0, 3); \ + T0 = _mm256_alignr_epi64(T0, _mm256_setzero_si256(), 3); \ + \ + R0 = _mm256_add_epi64(R0, T0); \ + R1 = _mm256_add_epi64(R1, T1); \ + R2 = _mm256_add_epi64(R2, T2); \ + R0 ## h = _mm256_add_epi64(R0 ## h, T0h); \ + R1 ## h = _mm256_add_epi64(R1 ## h, T1h); \ + { \ + Ipp32u k,l; \ + k = l = 0; \ + \ + kk0 = _mm256_cmp_epu64_mask(MASK, R0, _MM_CMPINT_LT); \ + kk1 = _mm256_cmp_epu64_mask(MASK, R1, _MM_CMPINT_LT); \ + kk2 = _mm256_cmp_epu64_mask(MASK, R2, _MM_CMPINT_LT); \ + kk0h = _mm256_cmp_epu64_mask(MASK, R0 ## h, _MM_CMPINT_LT); \ + kk1h = _mm256_cmp_epu64_mask(MASK, R1 ## h, _MM_CMPINT_LT); \ + \ + k = (kk2<<16)|(kk1h<<12)|(kk1<<8)|(kk0h<<4)|kk0; \ + \ + kk0 = _mm256_cmp_epu64_mask(MASK, R0, _MM_CMPINT_EQ); \ + kk1 = _mm256_cmp_epu64_mask(MASK, R1, _MM_CMPINT_EQ); \ + kk2 = _mm256_cmp_epu64_mask(MASK, R2, _MM_CMPINT_EQ); \ + kk0h = _mm256_cmp_epu64_mask(MASK, R0 ## h, _MM_CMPINT_EQ); \ + kk1h = _mm256_cmp_epu64_mask(MASK, R1 ## h, _MM_CMPINT_EQ); \ + \ + l = (kk2<<16)|(kk1h<<12)|(kk1<<8)|(kk0h<<4)|kk0; \ + \ + k = l + 2*k; \ + k ^= l; \ + \ + kk0 = k; \ + kk0h = (k>>4); \ + kk1 = (k>>8); \ + kk1h = (k>>12); \ + kk2 = (k>>16); \ + } \ + \ + R0 = _mm256_mask_sub_epi64(R0, (__mmask8)kk0, R0, MASK); \ + R1 = _mm256_mask_sub_epi64(R1, (__mmask8)kk1, R1, MASK); \ + R2 = _mm256_mask_sub_epi64(R2, (__mmask8)kk2, R2, MASK); \ + R0 ## h = _mm256_mask_sub_epi64(R0 ## h, (__mmask8)kk0h, R0 ## h, MASK); \ + R1 ## h = _mm256_mask_sub_epi64(R1 ## h, (__mmask8)kk1h, R1 ## h, MASK); \ + \ + R0 = _mm256_and_si256(R0, MASK); \ + R1 = _mm256_and_si256(R1, MASK); \ + R2 = _mm256_and_si256(R2, MASK); \ + R0 ## h = _mm256_and_si256(R0 ## h, MASK); \ + R1 ## h = _mm256_and_si256(R1 ## h, MASK); \ +} + +#define NORMALIZE_52x30(R0,R1,R2,R3) { \ + __m256i T0 = _mm256_srli_epi64(R0, EXP_DIGIT_SIZE_AVX512); \ + __m256i T0h = _mm256_srli_epi64(R0 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T1 = _mm256_srli_epi64(R1, EXP_DIGIT_SIZE_AVX512); \ + __m256i T1h = _mm256_srli_epi64(R1 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T2 = _mm256_srli_epi64(R2, EXP_DIGIT_SIZE_AVX512); \ + __m256i T2h = _mm256_srli_epi64(R2 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T3 = _mm256_srli_epi64(R3, EXP_DIGIT_SIZE_AVX512); \ + __m256i T3h = _mm256_srli_epi64(R3 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i MASK = _mm256_set1_epi64x(EXP_DIGIT_MASK_AVX512); \ + \ + Ipp32u kk0, kk1, kk2, kk3; \ + Ipp32u kk0h, kk1h, kk2h, kk3h; \ + kk0 = kk1 = kk2 = kk3 = kk0h = kk1h = kk2h = kk3h = 0; \ + \ + R0 = _mm256_and_si256(R0, MASK); \ + R1 = _mm256_and_si256(R1, MASK); \ + R2 = _mm256_and_si256(R2, MASK); \ + R3 = _mm256_and_si256(R3, MASK); \ + R0 ## h = _mm256_and_si256(R0 ## h, MASK); \ + R1 ## h = _mm256_and_si256(R1 ## h, MASK); \ + R2 ## h = _mm256_and_si256(R2 ## h, MASK); \ + R3 ## h = _mm256_and_si256(R3 ## h, MASK); \ + \ + T3h = _mm256_alignr_epi64(T3h, T3, 3); \ + T3 = _mm256_alignr_epi64(T3 , T2h, 3); \ + T2h = _mm256_alignr_epi64(T2h, T2, 3); \ + T2 = _mm256_alignr_epi64(T2 , T1h, 3); \ + T1h = _mm256_alignr_epi64(T1h, T1, 3); \ + T1 = _mm256_alignr_epi64(T1 , T0h, 3); \ + T0h = _mm256_alignr_epi64(T0h, T0, 3); \ + T0 = _mm256_alignr_epi64(T0, _mm256_setzero_si256(), 3); \ + \ + R0 = _mm256_add_epi64(R0, T0); \ + R1 = _mm256_add_epi64(R1, T1); \ + R2 = _mm256_add_epi64(R2, T2); \ + R3 = _mm256_add_epi64(R3, T3); \ + R0 ## h = _mm256_add_epi64(R0 ## h, T0h); \ + R1 ## h = _mm256_add_epi64(R1 ## h, T1h); \ + R2 ## h = _mm256_add_epi64(R2 ## h, T2h); \ + R3 ## h = _mm256_add_epi64(R3 ## h, T3h); \ + \ + { \ + Ipp32u k, l; \ + k = l = 0; \ + \ + kk0 = _mm256_cmp_epu64_mask(MASK, R0, _MM_CMPINT_LT); \ + kk1 = _mm256_cmp_epu64_mask(MASK, R1, _MM_CMPINT_LT); \ + kk2 = _mm256_cmp_epu64_mask(MASK, R2, _MM_CMPINT_LT); \ + kk3 = _mm256_cmp_epu64_mask(MASK, R3, _MM_CMPINT_LT); \ + kk0h = _mm256_cmp_epu64_mask(MASK, R0 ## h, _MM_CMPINT_LT); \ + kk1h = _mm256_cmp_epu64_mask(MASK, R1 ## h, _MM_CMPINT_LT); \ + kk2h = _mm256_cmp_epu64_mask(MASK, R2 ## h, _MM_CMPINT_LT); \ + kk3h = _mm256_cmp_epu64_mask(MASK, R3 ## h, _MM_CMPINT_LT); \ + \ + k = (kk3h<<28)|(kk3<<24)|(kk2h<<20)|(kk2<<16)|(kk1h<<12)|(kk1<<8)|(kk0h<<4)|kk0; \ + \ + kk0 = _mm256_cmp_epu64_mask(MASK, R0, _MM_CMPINT_EQ); \ + kk1 = _mm256_cmp_epu64_mask(MASK, R1, _MM_CMPINT_EQ); \ + kk2 = _mm256_cmp_epu64_mask(MASK, R2, _MM_CMPINT_EQ); \ + kk3 = _mm256_cmp_epu64_mask(MASK, R3, _MM_CMPINT_EQ); \ + kk0h = _mm256_cmp_epu64_mask(MASK, R0 ## h, _MM_CMPINT_EQ); \ + kk1h = _mm256_cmp_epu64_mask(MASK, R1 ## h, _MM_CMPINT_EQ); \ + kk2h = _mm256_cmp_epu64_mask(MASK, R2 ## h, _MM_CMPINT_EQ); \ + kk3h = _mm256_cmp_epu64_mask(MASK, R3 ## h, _MM_CMPINT_EQ); \ + \ + l = (kk3h<<28)|(kk3<<24)|(kk2h<<20)|(kk2<<16)|(kk1h<<12)|(kk1<<8)|(kk0h<<4)|kk0; \ + \ + k = l + 2*k; \ + k ^= l; \ + \ + kk0 = k; \ + kk0h = (k>>4); \ + kk1 = (k>>8); \ + kk1h = (k>>12); \ + kk2 = (k>>16); \ + kk2h = (k>>20); \ + kk3 = (k>>24); \ + kk3h = (k>>28); \ + } \ + \ + R0 = _mm256_mask_sub_epi64(R0, (__mmask8)kk0, R0, MASK); \ + R1 = _mm256_mask_sub_epi64(R1, (__mmask8)kk1, R1, MASK); \ + R2 = _mm256_mask_sub_epi64(R2, (__mmask8)kk2, R2, MASK); \ + R3 = _mm256_mask_sub_epi64(R3, (__mmask8)kk3, R3, MASK); \ + R0 ## h = _mm256_mask_sub_epi64(R0 ## h, (__mmask8)kk0h, R0 ## h, MASK); \ + R1 ## h = _mm256_mask_sub_epi64(R1 ## h, (__mmask8)kk1h, R1 ## h, MASK); \ + R2 ## h = _mm256_mask_sub_epi64(R2 ## h, (__mmask8)kk2h, R2 ## h, MASK); \ + R3 ## h = _mm256_mask_sub_epi64(R3 ## h, (__mmask8)kk3h, R3 ## h, MASK); \ + \ + R0 = _mm256_and_si256(R0, MASK); \ + R1 = _mm256_and_si256(R1, MASK); \ + R2 = _mm256_and_si256(R2, MASK); \ + R3 = _mm256_and_si256(R3, MASK); \ + R0 ## h = _mm256_and_si256(R0 ## h, MASK); \ + R1 ## h = _mm256_and_si256(R1 ## h, MASK); \ + R2 ## h = _mm256_and_si256(R2 ## h, MASK); \ + R3 ## h = _mm256_and_si256(R3 ## h, MASK); \ +} + +#define NORMALIZE_52x40(R0,R1,R2,R3,R4) { \ + __m256i T0 = _mm256_srli_epi64(R0, EXP_DIGIT_SIZE_AVX512); \ + __m256i T0h = _mm256_srli_epi64(R0 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T1 = _mm256_srli_epi64(R1, EXP_DIGIT_SIZE_AVX512); \ + __m256i T1h = _mm256_srli_epi64(R1 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T2 = _mm256_srli_epi64(R2, EXP_DIGIT_SIZE_AVX512); \ + __m256i T2h = _mm256_srli_epi64(R2 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T3 = _mm256_srli_epi64(R3, EXP_DIGIT_SIZE_AVX512); \ + __m256i T3h = _mm256_srli_epi64(R3 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i T4 = _mm256_srli_epi64(R4, EXP_DIGIT_SIZE_AVX512); \ + __m256i T4h = _mm256_srli_epi64(R4 ## h, EXP_DIGIT_SIZE_AVX512); \ + __m256i MASK = _mm256_set1_epi64x(EXP_DIGIT_MASK_AVX512); \ + \ + Ipp64u kk0, kk1, kk2, kk3, kk4; \ + Ipp64u kk0h, kk1h, kk2h, kk3h, kk4h; \ + kk0 = kk1 = kk2 = kk3 = kk4 = kk0h = kk1h = kk2h = kk3h = kk4h = 0; \ + \ + R0 = _mm256_and_si256(R0, MASK); \ + R1 = _mm256_and_si256(R1, MASK); \ + R2 = _mm256_and_si256(R2, MASK); \ + R3 = _mm256_and_si256(R3, MASK); \ + R4 = _mm256_and_si256(R4, MASK); \ + R0 ## h = _mm256_and_si256(R0 ## h, MASK); \ + R1 ## h = _mm256_and_si256(R1 ## h, MASK); \ + R2 ## h = _mm256_and_si256(R2 ## h, MASK); \ + R3 ## h = _mm256_and_si256(R3 ## h, MASK); \ + R4 ## h = _mm256_and_si256(R4 ## h, MASK); \ + \ + T4h = _mm256_alignr_epi64(T4h, T4, 3); \ + T4 = _mm256_alignr_epi64(T4 , T3h, 3); \ + T3h = _mm256_alignr_epi64(T3h, T3, 3); \ + T3 = _mm256_alignr_epi64(T3 , T2h, 3); \ + T2h = _mm256_alignr_epi64(T2h, T2, 3); \ + T2 = _mm256_alignr_epi64(T2 , T1h, 3); \ + T1h = _mm256_alignr_epi64(T1h, T1, 3); \ + T1 = _mm256_alignr_epi64(T1 , T0h, 3); \ + T0h = _mm256_alignr_epi64(T0h, T0, 3); \ + T0 = _mm256_alignr_epi64(T0, _mm256_setzero_si256(), 3); \ + \ + R0 = _mm256_add_epi64(R0, T0); \ + R1 = _mm256_add_epi64(R1, T1); \ + R2 = _mm256_add_epi64(R2, T2); \ + R3 = _mm256_add_epi64(R3, T3); \ + R4 = _mm256_add_epi64(R4, T4); \ + R0 ## h = _mm256_add_epi64(R0 ## h, T0h); \ + R1 ## h = _mm256_add_epi64(R1 ## h, T1h); \ + R2 ## h = _mm256_add_epi64(R2 ## h, T2h); \ + R3 ## h = _mm256_add_epi64(R3 ## h, T3h); \ + R4 ## h = _mm256_add_epi64(R4 ## h, T4h); \ + \ + { \ + Ipp64u k, l; \ + k = l = 0; \ + \ + kk0 = _mm256_cmp_epu64_mask(MASK, R0, _MM_CMPINT_LT); \ + kk1 = _mm256_cmp_epu64_mask(MASK, R1, _MM_CMPINT_LT); \ + kk2 = _mm256_cmp_epu64_mask(MASK, R2, _MM_CMPINT_LT); \ + kk3 = _mm256_cmp_epu64_mask(MASK, R3, _MM_CMPINT_LT); \ + kk4 = _mm256_cmp_epu64_mask(MASK, R4, _MM_CMPINT_LT); \ + kk0h = _mm256_cmp_epu64_mask(MASK, R0 ## h, _MM_CMPINT_LT); \ + kk1h = _mm256_cmp_epu64_mask(MASK, R1 ## h, _MM_CMPINT_LT); \ + kk2h = _mm256_cmp_epu64_mask(MASK, R2 ## h, _MM_CMPINT_LT); \ + kk3h = _mm256_cmp_epu64_mask(MASK, R3 ## h, _MM_CMPINT_LT); \ + kk4h = _mm256_cmp_epu64_mask(MASK, R4 ## h, _MM_CMPINT_LT); \ + \ + k = (kk4h<<36)|(kk4<<32)|(kk3h<<28)|(kk3<<24)|(kk2h<<20)| \ + (kk2<<16)|(kk1h<<12)|(kk1<<8)|(kk0h<<4)|kk0; \ + \ + kk0 = _mm256_cmp_epu64_mask(MASK, R0, _MM_CMPINT_EQ); \ + kk1 = _mm256_cmp_epu64_mask(MASK, R1, _MM_CMPINT_EQ); \ + kk2 = _mm256_cmp_epu64_mask(MASK, R2, _MM_CMPINT_EQ); \ + kk3 = _mm256_cmp_epu64_mask(MASK, R3, _MM_CMPINT_EQ); \ + kk4 = _mm256_cmp_epu64_mask(MASK, R4, _MM_CMPINT_EQ); \ + kk0h = _mm256_cmp_epu64_mask(MASK, R0 ## h, _MM_CMPINT_EQ); \ + kk1h = _mm256_cmp_epu64_mask(MASK, R1 ## h, _MM_CMPINT_EQ); \ + kk2h = _mm256_cmp_epu64_mask(MASK, R2 ## h, _MM_CMPINT_EQ); \ + kk3h = _mm256_cmp_epu64_mask(MASK, R3 ## h, _MM_CMPINT_EQ); \ + kk4h = _mm256_cmp_epu64_mask(MASK, R4 ## h, _MM_CMPINT_EQ); \ + \ + l = (kk4h<<36)|(kk4<<32)|(kk3h<<28)|(kk3<<24)|(kk2h<<20)| \ + (kk2<<16)|(kk1h<<12)|(kk1<<8)|(kk0h<<4)|kk0; \ + \ + k = l + 2*k; \ + k ^= l; \ + \ + kk0 = k; \ + kk0h = (k>>4); \ + kk1 = (k>>8); \ + kk1h = (k>>12); \ + kk2 = (k>>16); \ + kk2h = (k>>20); \ + kk3 = (k>>24); \ + kk3h = (k>>28); \ + kk4 = (k>>32); \ + kk4h = (k>>36); \ + } \ + \ + R0 = _mm256_mask_sub_epi64(R0, (__mmask8)kk0, R0, MASK); \ + R1 = _mm256_mask_sub_epi64(R1, (__mmask8)kk1, R1, MASK); \ + R2 = _mm256_mask_sub_epi64(R2, (__mmask8)kk2, R2, MASK); \ + R3 = _mm256_mask_sub_epi64(R3, (__mmask8)kk3, R3, MASK); \ + R4 = _mm256_mask_sub_epi64(R4, (__mmask8)kk4, R4, MASK); \ + R0 ## h = _mm256_mask_sub_epi64(R0 ## h, (__mmask8)kk0h, R0 ## h, MASK); \ + R1 ## h = _mm256_mask_sub_epi64(R1 ## h, (__mmask8)kk1h, R1 ## h, MASK); \ + R2 ## h = _mm256_mask_sub_epi64(R2 ## h, (__mmask8)kk2h, R2 ## h, MASK); \ + R3 ## h = _mm256_mask_sub_epi64(R3 ## h, (__mmask8)kk3h, R3 ## h, MASK); \ + R4 ## h = _mm256_mask_sub_epi64(R4 ## h, (__mmask8)kk4h, R4 ## h, MASK); \ + \ + R0 = _mm256_and_si256(R0, MASK); \ + R1 = _mm256_and_si256(R1, MASK); \ + R2 = _mm256_and_si256(R2, MASK); \ + R3 = _mm256_and_si256(R3, MASK); \ + R4 = _mm256_and_si256(R4, MASK); \ + R0 ## h = _mm256_and_si256(R0 ## h, MASK); \ + R1 ## h = _mm256_and_si256(R1 ## h, MASK); \ + R2 ## h = _mm256_and_si256(R2 ## h, MASK); \ + R3 ## h = _mm256_and_si256(R3 ## h, MASK); \ + R4 ## h = _mm256_and_si256(R4 ## h, MASK); \ +} + +#endif // IFMA_NORM_52X_H diff --git a/plugin/ippcp/library/src/sources/ippcp/ifma_rsa_arith.h b/plugin/ippcp/library/src/sources/ippcp/ifma_rsa_arith.h new file mode 100644 index 000000000..cdec434fd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ifma_rsa_arith.h @@ -0,0 +1,97 @@ + /******************************************************************************* + * Copyright (C) 2019 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef _IFMA_RSA_ARITH_H_ +#define _IFMA_RSA_ARITH_H_ + +/* + * RSA kernels implemented with AVX512_IFMA256 ISA + */ + +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K1) + +/* Almost Montgomery Multiplication / Squaring */ +#define ifma256_amm52x20 OWNAPI(ifma256_amm52x20) + IPP_OWN_DECL(void, ifma256_amm52x20, (Ipp64u out[20], const Ipp64u a[20], const Ipp64u b[20], const Ipp64u m[20], Ipp64u k0)) +#define ifma256_ams52x20 OWNAPI(ifma256_ams52x20) + IPP_OWN_DECL(void, ifma256_ams52x20, (Ipp64u out[20], const Ipp64u a[20], const Ipp64u m[20], Ipp64u k0)) +#define ifma256_amm52x30 OWNAPI(ifma256_amm52x30) + IPP_OWN_DECL(void, ifma256_amm52x30, (Ipp64u out[32], const Ipp64u a[32], const Ipp64u b[32], const Ipp64u m[32], Ipp64u k0)) +#define ifma256_ams52x30 OWNAPI(ifma256_ams52x30) + IPP_OWN_DECL(void, ifma256_ams52x30, (Ipp64u out[32], const Ipp64u a[32], const Ipp64u m[32], Ipp64u k0)) +#define ifma256_amm52x40 OWNAPI(ifma256_amm52x40) + IPP_OWN_DECL(void, ifma256_amm52x40, (Ipp64u out[40], const Ipp64u a[40], const Ipp64u b[40], const Ipp64u m[40], Ipp64u k0)) +#define ifma256_ams52x40 OWNAPI(ifma256_ams52x40) + IPP_OWN_DECL(void, ifma256_ams52x40, (Ipp64u out[40], const Ipp64u a[40], const Ipp64u m[40], Ipp64u k0)) + + +/* + * Dual Almost Montgomery Multiplication / Squaring + * (two independent operations and data arrays) + */ +#define ifma256_amm52x20_dual OWNAPI(ifma256_amm52x20_dual) + IPP_OWN_DECL(void, ifma256_amm52x20_dual, (Ipp64u out[2][20], const Ipp64u a[2][20], const Ipp64u b[2][20], const Ipp64u m[2][20], const Ipp64u k0[2])) +#define ifma256_ams52x20_dual OWNAPI(ifma256_ams52x20_dual) + IPP_OWN_DECL(void, ifma256_ams52x20_dual, (Ipp64u out[2][20], const Ipp64u a[2][20], const Ipp64u m[2][20], const Ipp64u k0[2])) +#define ifma256_amm52x30_dual OWNAPI(ifma256_amm52x30_dual) + IPP_OWN_DECL(void, ifma256_amm52x30_dual, (Ipp64u out[2][32], const Ipp64u a[2][32], const Ipp64u b[2][32], const Ipp64u m[2][32], const Ipp64u k0[2])) +#define ifma256_ams52x30_dual OWNAPI(ifma256_ams52x30_dual) + IPP_OWN_DECL(void, ifma256_ams52x30_dual, (Ipp64u out[2][32], const Ipp64u a[2][32], const Ipp64u m[2][32], const Ipp64u k0[2])) +#define ifma256_amm52x40_dual OWNAPI(ifma256_amm52x40_dual) + IPP_OWN_DECL(void, ifma256_amm52x40_dual, (Ipp64u out[2][40], const Ipp64u a[2][40], const Ipp64u b[2][40], const Ipp64u m[2][40], const Ipp64u k0[2])) +#define ifma256_ams52x40_dual OWNAPI(ifma256_ams52x40_dual) + IPP_OWN_DECL(void, ifma256_ams52x40_dual, (Ipp64u out[2][40], const Ipp64u a[2][40], const Ipp64u m[2][40], const Ipp64u k0[2])) + + +/* Exponentiation */ +#define ifma256_exp52x20 OWNAPI(ifma256_exp52x20) + IPP_OWN_DECL (void, ifma256_exp52x20, (Ipp64u *out, + const Ipp64u *base, + const Ipp64u *exp, + const Ipp64u *modulus, + const Ipp64u *toMont, + const Ipp64u k0)) + +/* Dual exponentiation */ +#define ifma256_exp52x20_dual OWNAPI(ifma256_exp52x20_dual) + IPP_OWN_DECL (void, ifma256_exp52x20_dual, (Ipp64u out [2][20], + const Ipp64u base [2][20], + const Ipp64u *exp [2], // 2x16 + const Ipp64u modulus[2][20], + const Ipp64u toMont [2][20], + const Ipp64u k0 [2])) + +#define ifma256_exp52x30_dual OWNAPI(ifma256_exp52x30_dual) + IPP_OWN_DECL (void, ifma256_exp52x30_dual, (Ipp64u out [2][32], + const Ipp64u base [2][32], + const Ipp64u *exp [2], // 2x24 + const Ipp64u modulus[2][32], + const Ipp64u toMont [2][32], + const Ipp64u k0 [2])) + +#define ifma256_exp52x40_dual OWNAPI(ifma256_exp52x40_dual) + IPP_OWN_DECL (void, ifma256_exp52x40_dual, (Ipp64u out [2][40], + const Ipp64u base [2][40], + const Ipp64u *exp [2], // 2x32 + const Ipp64u modulus[2][40], + const Ipp64u toMont [2][40], + const Ipp64u k0 [2])) + +#endif // #if(_IPP32E>=_IPP32E_K1) +#endif // #ifndef _IFMA_RSA_ARITH_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/internal_hashmessage_mb.c b/plugin/ippcp/library/src/sources/ippcp/internal_hashmessage_mb.c new file mode 100644 index 000000000..8daf08f8b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/internal_hashmessage_mb.c @@ -0,0 +1,36 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "internal_hashmessage_mb.h" + +IPP_OWN_DEFN (IppStatus, cpHashMessage_MB8_rmf, (const Ipp8u* const pSrc[8], int const lens[8], Ipp8u* const pDst[8], const IppsHashMethod* pMethod)) +{ + int i; + for (i = 0; i < 8; ++i) { // 8 buffers, for RSA + ippsHashMessage_rmf(pSrc[i], lens[i], pDst[i], pMethod); + } + return ippStsNoErr; +} + +IPP_OWN_DEFN (IppStatus, cpMGF1_MB8_rmf, (const Ipp8u* const pSeeds[8], int const seedLens[8], Ipp8u* const pMasks[8], int const maskLens[8], const IppsHashMethod* pMethod)) +{ + int i; + for (i = 0; i < 8; ++i) { // 8 buffers, for RSA + ippsMGF1_rmf(pSeeds[i], seedLens[i], pMasks[i], maskLens[i], pMethod); + } + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/internal_hashmessage_mb.h b/plugin/ippcp/library/src/sources/ippcp/internal_hashmessage_mb.h new file mode 100644 index 000000000..fcff212c3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/internal_hashmessage_mb.h @@ -0,0 +1,23 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#define cpHashMessage_MB8_rmf OWNAPI(cpHashMessage_MB8_rmf) + IPP_OWN_DECL (IppStatus, cpHashMessage_MB8_rmf, (const Ipp8u* const pSrc[8], int const lens[8], Ipp8u* const pDst[8], const IppsHashMethod* pMethod)) +#define cpMGF1_MB8_rmf OWNAPI(cpMGF1_MB8_rmf) + IPP_OWN_DECL (IppStatus, cpMGF1_MB8_rmf, (const Ipp8u* const pSeeds[8], int const seedLens[8], Ipp8u* const pMasks[8], int const maskLens[8], const IppsHashMethod* pMethod)) diff --git a/plugin/ippcp/library/src/sources/ippcp/ippcp.def b/plugin/ippcp/library/src/sources/ippcp/ippcp.def new file mode 100644 index 000000000..4a3f5579b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/ippcp.def @@ -0,0 +1,560 @@ +EXPORTS + +ippcpInit +cpGetReg +cpStartTscp +cpStopTscp +cpStartTsc +cpStopTsc +cpGetCacheSize +cpGetFeature +ippcpSetCpuFeatures +ippcpGetCpuFeatures +ippcpGetCpuClocks +ippcpSetNumThreads +ippcpGetNumThreads +ippcpGetEnabledCpuFeatures +ippcpGetEnabledNumThreads +ippcpGetStatusString + +ippcpGetLibVersion +ippsDESGetSize +ippsDESInit +ippsDESPack +ippsDESUnpack +ippsTDESEncryptECB +ippsTDESDecryptECB +ippsTDESEncryptCBC +ippsTDESDecryptCBC +ippsTDESEncryptCFB +ippsTDESDecryptCFB +ippsTDESEncryptOFB +ippsTDESDecryptOFB +ippsTDESEncryptCTR +ippsTDESDecryptCTR +ippsAESGetSize +ippsAESInit +ippsAESSetKey +ippsAESPack +ippsAESUnpack +ippsAESSetupNoise +ippsAES_GCMSetupNoise +ippsAES_CMACSetupNoise +ippsAESEncryptECB +ippsAESDecryptECB +ippsAESEncryptCBC +ippsAESEncryptCBC_CS1 +ippsAESEncryptCBC_CS2 +ippsAESEncryptCBC_CS3 +ippsAESDecryptCBC +ippsAESDecryptCBC_CS1 +ippsAESDecryptCBC_CS2 +ippsAESDecryptCBC_CS3 +ippsAESEncryptCFB +ippsAESDecryptCFB +ippsAESEncryptOFB +ippsAESDecryptOFB +ippsAESEncryptCTR +ippsAESDecryptCTR +ippsAESEncryptXTS_Direct +ippsAESDecryptXTS_Direct +ippsAES_EncryptCFB16_MB +ippsSMS4GetSize +ippsSMS4Init +ippsSMS4SetKey +ippsSMS4EncryptECB +ippsSMS4DecryptECB +ippsSMS4EncryptCBC +ippsSMS4EncryptCBC_CS1 +ippsSMS4EncryptCBC_CS2 +ippsSMS4EncryptCBC_CS3 +ippsSMS4DecryptCBC +ippsSMS4DecryptCBC_CS1 +ippsSMS4DecryptCBC_CS2 +ippsSMS4DecryptCBC_CS3 +ippsSMS4EncryptCFB +ippsSMS4DecryptCFB +ippsSMS4EncryptOFB +ippsSMS4DecryptOFB +ippsSMS4EncryptCTR +ippsSMS4DecryptCTR +ippsSMS4_CCMGetSize +ippsSMS4_CCMInit +ippsSMS4_CCMMessageLen +ippsSMS4_CCMTagLen +ippsSMS4_CCMStart +ippsSMS4_CCMEncrypt +ippsSMS4_CCMDecrypt +ippsSMS4_CCMGetTag +ippsAES_CCMGetSize +ippsAES_CCMInit +ippsAES_CCMMessageLen +ippsAES_CCMTagLen +ippsAES_CCMStart +ippsAES_CCMEncrypt +ippsAES_CCMDecrypt +ippsAES_CCMGetTag +ippsAES_GCMGetSize +ippsAES_GCMInit +ippsAES_GCMReinit +ippsAES_GCMReset +ippsAES_GCMProcessIV +ippsAES_GCMProcessAAD +ippsAES_GCMStart +ippsAES_GCMEncrypt +ippsAES_GCMDecrypt +ippsAES_GCMGetTag +ippsAES_XTSGetSize +ippsAES_XTSInit +ippsAES_XTSEncrypt +ippsAES_XTSDecrypt +ippsAES_S2V_CMAC +ippsAES_SIVEncrypt +ippsAES_SIVDecrypt +ippsAES_CMACGetSize +ippsAES_CMACInit +ippsAES_CMACUpdate +ippsAES_CMACFinal +ippsAES_CMACGetTag +ippsARCFourCheckKey +ippsARCFourGetSize +ippsARCFourInit +ippsARCFourReset +ippsARCFourPack +ippsARCFourUnpack +ippsARCFourEncrypt +ippsARCFourDecrypt +ippsSHA1GetSize +ippsSHA1Init +ippsSHA1Duplicate +ippsSHA1Pack +ippsSHA1Unpack +ippsSHA1Update +ippsSHA1GetTag +ippsSHA1Final +ippsSHA1MessageDigest +ippsSHA224GetSize +ippsSHA224Init +ippsSHA224Duplicate +ippsSHA224Pack +ippsSHA224Unpack +ippsSHA224Update +ippsSHA224GetTag +ippsSHA224Final +ippsSHA224MessageDigest +ippsSHA256GetSize +ippsSHA256Init +ippsSHA256Duplicate +ippsSHA256Pack +ippsSHA256Unpack +ippsSHA256Update +ippsSHA256GetTag +ippsSHA256Final +ippsSHA256MessageDigest +ippsSHA384GetSize +ippsSHA384Init +ippsSHA384Duplicate +ippsSHA384Pack +ippsSHA384Unpack +ippsSHA384Update +ippsSHA384GetTag +ippsSHA384Final +ippsSHA384MessageDigest +ippsSHA512GetSize +ippsSHA512Init +ippsSHA512Duplicate +ippsSHA512Pack +ippsSHA512Unpack +ippsSHA512Update +ippsSHA512GetTag +ippsSHA512Final +ippsSHA512MessageDigest +ippsMD5GetSize +ippsMD5Init +ippsMD5Duplicate +ippsMD5Pack +ippsMD5Unpack +ippsMD5Update +ippsMD5GetTag +ippsMD5Final +ippsMD5MessageDigest +ippsSM3GetSize +ippsSM3Init +ippsSM3Duplicate +ippsSM3Pack +ippsSM3Unpack +ippsSM3Update +ippsSM3GetTag +ippsSM3Final +ippsSM3MessageDigest +ippsHashGetSize +ippsHashInit +ippsHashPack +ippsHashUnpack +ippsHashDuplicate +ippsHashUpdate +ippsHashGetTag +ippsHashFinal +ippsHashMessage +ippsHashMethodGetSize +ippsHashMethodSet_MD5 +ippsHashMethodSet_SM3 +ippsHashMethodSet_SHA1 +ippsHashMethodSet_SHA1_NI +ippsHashMethodSet_SHA1_TT +ippsHashMethodSet_SHA256 +ippsHashMethodSet_SHA256_NI +ippsHashMethodSet_SHA256_TT +ippsHashMethodSet_SHA224 +ippsHashMethodSet_SHA224_NI +ippsHashMethodSet_SHA224_TT +ippsHashMethodSet_SHA512 +ippsHashMethodSet_SHA384 +ippsHashMethodSet_SHA512_256 +ippsHashMethodSet_SHA512_224 +ippsHashStateMethodSet_SM3 +ippsHashStateMethodSet_SHA256 +ippsHashStateMethodSet_SHA256_NI +ippsHashStateMethodSet_SHA256_TT +ippsHashStateMethodSet_SHA224 +ippsHashStateMethodSet_SHA224_NI +ippsHashStateMethodSet_SHA224_TT +ippsHashStateMethodSet_SHA512 +ippsHashStateMethodSet_SHA384 +ippsHashStateMethodSet_SHA512_256 +ippsHashStateMethodSet_SHA512_224 +ippsHashMethod_MD5 +ippsHashMethod_SM3 +ippsHashMethod_SHA1 +ippsHashMethod_SHA1_NI +ippsHashMethod_SHA1_TT +ippsHashMethod_SHA256 +ippsHashMethod_SHA256_NI +ippsHashMethod_SHA256_TT +ippsHashMethod_SHA224 +ippsHashMethod_SHA224_NI +ippsHashMethod_SHA224_TT +ippsHashMethod_SHA512 +ippsHashMethod_SHA384 +ippsHashMethod_SHA512_256 +ippsHashMethod_SHA512_224 +ippsHashMethodGetInfo +ippsHashGetSize_rmf +ippsHashInit_rmf +ippsHashPack_rmf +ippsHashUnpack_rmf +ippsHashDuplicate_rmf +ippsHashUpdate_rmf +ippsHashGetTag_rmf +ippsHashFinal_rmf +ippsHashMessage_rmf +ippsHashGetInfo_rmf +ippsMGF +ippsMGF1_rmf +ippsMGF2_rmf +ippsHMAC_GetSize +ippsHMAC_Init +ippsHMAC_Pack +ippsHMAC_Unpack +ippsHMAC_Duplicate +ippsHMAC_Update +ippsHMAC_Final +ippsHMAC_GetTag +ippsHMAC_Message +ippsHMACGetSize_rmf +ippsHMACInit_rmf +ippsHMACPack_rmf +ippsHMACUnpack_rmf +ippsHMACDuplicate_rmf +ippsHMACUpdate_rmf +ippsHMACFinal_rmf +ippsHMACGetTag_rmf +ippsHMACMessage_rmf +ippsBigNumGetSize +ippsBigNumInit +ippsCmpZero_BN +ippsCmp_BN +ippsGetSize_BN +ippsSet_BN +ippsGet_BN +ippsRef_BN +ippsExtGet_BN +ippsAdd_BN +ippsSub_BN +ippsMul_BN +ippsMAC_BN_I +ippsDiv_BN +ippsMod_BN +ippsGcd_BN +ippsModInv_BN +ippsSetOctString_BN +ippsGetOctString_BN +ippsMontGetSize +ippsMontInit +ippsMontSet +ippsMontGet +ippsMontForm +ippsMontMul +ippsMontExp +ippsPRNGGetSize +ippsPRNGInit +ippsPRNGSetModulus +ippsPRNGSetH0 +ippsPRNGSetAugment +ippsPRNGSetSeed +ippsPRNGGetSeed +ippsPRNGen +ippsPRNGen_BN +ippsPRNGenRDRAND +ippsPRNGenRDRAND_BN +ippsTRNGenRDSEED +ippsTRNGenRDSEED_BN +ippsPrimeGetSize +ippsPrimeInit +ippsPrimeGen +ippsPrimeTest +ippsPrimeGen_BN +ippsPrimeTest_BN +ippsPrimeGet +ippsPrimeGet_BN +ippsPrimeSet +ippsPrimeSet_BN +ippsRSA_GetSizePublicKey +ippsRSA_InitPublicKey +ippsRSA_SetPublicKey +ippsRSA_GetPublicKey +ippsRSA_GetSizePrivateKeyType1 +ippsRSA_InitPrivateKeyType1 +ippsRSA_SetPrivateKeyType1 +ippsRSA_GetPrivateKeyType1 +ippsRSA_GetSizePrivateKeyType2 +ippsRSA_InitPrivateKeyType2 +ippsRSA_SetPrivateKeyType2 +ippsRSA_GetPrivateKeyType2 +ippsRSA_GetBufferSizePublicKey +ippsRSA_GetBufferSizePrivateKey +ippsRSA_Encrypt +ippsRSA_Decrypt +ippsRSA_GenerateKeys +ippsRSA_ValidateKeys +ippsRSAEncrypt_OAEP +ippsRSADecrypt_OAEP +ippsRSAEncrypt_OAEP_rmf +ippsRSADecrypt_OAEP_rmf +ippsRSAEncrypt_PKCSv15 +ippsRSADecrypt_PKCSv15 +ippsRSASign_PSS +ippsRSAVerify_PSS +ippsRSASign_PSS_rmf +ippsRSAVerify_PSS_rmf +ippsRSASign_PKCS1v15 +ippsRSAVerify_PKCS1v15 +ippsRSASign_PKCS1v15_rmf +ippsRSAVerify_PKCS1v15_rmf +ippsDLGetResultString +ippsDLPGetSize +ippsDLPInit +ippsDLPPack +ippsDLPUnpack +ippsDLPSet +ippsDLPGet +ippsDLPSetDP +ippsDLPGetDP +ippsDLPGenKeyPair +ippsDLPPublicKey +ippsDLPValidateKeyPair +ippsDLPSetKeyPair +ippsDLPSignDSA +ippsDLPVerifyDSA +ippsDLPSharedSecretDH +ippsDLPGenerateDSA +ippsDLPValidateDSA +ippsDLPGenerateDH +ippsDLPValidateDH +ippsECCGetResultString +ippsECCPGetSize +ippsECCPGetSizeStd128r1 +ippsECCPGetSizeStd128r2 +ippsECCPGetSizeStd192r1 +ippsECCPGetSizeStd224r1 +ippsECCPGetSizeStd256r1 +ippsECCPGetSizeStd384r1 +ippsECCPGetSizeStd521r1 +ippsECCPGetSizeStdSM2 +ippsECCPInit +ippsECCPInitStd128r1 +ippsECCPInitStd128r2 +ippsECCPInitStd192r1 +ippsECCPInitStd224r1 +ippsECCPInitStd256r1 +ippsECCPInitStd384r1 +ippsECCPInitStd521r1 +ippsECCPInitStdSM2 +ippsECCPSet +ippsECCPSetStd +ippsECCPSetStd128r1 +ippsECCPSetStd128r2 +ippsECCPSetStd192r1 +ippsECCPSetStd224r1 +ippsECCPSetStd256r1 +ippsECCPSetStd384r1 +ippsECCPSetStd521r1 +ippsECCPSetStdSM2 +ippsECCPBindGxyTblStd192r1 +ippsECCPBindGxyTblStd224r1 +ippsECCPBindGxyTblStd256r1 +ippsECCPBindGxyTblStd384r1 +ippsECCPBindGxyTblStd521r1 +ippsECCPBindGxyTblStdSM2 +ippsECCPGet +ippsECCPGetOrderBitSize +ippsECCPValidate +ippsECCPPointGetSize +ippsECCPPointInit +ippsECCPSetPoint +ippsECCPSetPointAtInfinity +ippsECCPGetPoint +ippsECCPCheckPoint +ippsECCPComparePoint +ippsECCPNegativePoint +ippsECCPAddPoint +ippsECCPMulPointScalar +ippsECCPGenKeyPair +ippsECCPPublicKey +ippsECCPValidateKeyPair +ippsECCPSetKeyPair +ippsECCPSharedSecretDH +ippsECCPSharedSecretDHC +ippsECCPSignDSA +ippsECCPVerifyDSA +ippsECCPSignNR +ippsECCPVerifyNR +ippsECCPSignSM2 +ippsECCPVerifySM2 +ippsGFpGetSize +ippsGFpInitArbitrary +ippsGFpInitFixed +ippsGFpInit +ippsGFpMethod_p192r1 +ippsGFpMethod_p224r1 +ippsGFpMethod_p256r1 +ippsGFpMethod_p384r1 +ippsGFpMethod_p521r1 +ippsGFpMethod_p256sm2 +ippsGFpMethod_p256bn +ippsGFpMethod_p256 +ippsGFpMethod_pArb +ippsGFpxGetSize +ippsGFpxInit +ippsGFpxInitBinomial +ippsGFpxMethod_binom2_epid2 +ippsGFpxMethod_binom3_epid2 +ippsGFpxMethod_binom2 +ippsGFpxMethod_binom3 +ippsGFpxMethod_binom +ippsGFpxMethod_com +ippsGFpScratchBufferSize +ippsGFpElementGetSize +ippsGFpElementInit +ippsGFpSetElement +ippsGFpSetElementRegular +ippsGFpSetElementOctString +ippsGFpSetElementRandom +ippsGFpSetElementHash +ippsGFpSetElementHash_rmf +ippsGFpCpyElement +ippsGFpGetElement +ippsGFpGetElementOctString +ippsGFpCmpElement +ippsGFpIsZeroElement +ippsGFpIsUnityElement +ippsGFpConj +ippsGFpNeg +ippsGFpInv +ippsGFpSqrt +ippsGFpSqr +ippsGFpAdd +ippsGFpSub +ippsGFpMul +ippsGFpExp +ippsGFpMultiExp +ippsGFpAdd_PE +ippsGFpSub_PE +ippsGFpMul_PE +ippsGFpGetInfo +ippsGFpECGetSize +ippsGFpECInit +ippsGFpECSet +ippsGFpECSetSubgroup +ippsGFpECInitStd128r1 +ippsGFpECInitStd128r2 +ippsGFpECInitStd192r1 +ippsGFpECInitStd224r1 +ippsGFpECInitStd256r1 +ippsGFpECInitStd384r1 +ippsGFpECInitStd521r1 +ippsGFpECInitStdSM2 +ippsGFpECInitStdBN256 +ippsGFpECBindGxyTblStd192r1 +ippsGFpECBindGxyTblStd224r1 +ippsGFpECBindGxyTblStd256r1 +ippsGFpECBindGxyTblStd384r1 +ippsGFpECBindGxyTblStd521r1 +ippsGFpECBindGxyTblStdSM2 +ippsGFpECGet +ippsGFpECGetSubgroup +ippsGFpECGetInfo_GF +ippsGFpECScratchBufferSize +ippsGFpECVerify +ippsGFpECPointGetSize +ippsGFpECPointInit +ippsGFpECSetPointAtInfinity +ippsGFpECSetPoint +ippsGFpECSetPointRegular +ippsGFpECSetPointRandom +ippsGFpECMakePoint +ippsGFpECSetPointHash +ippsGFpECSetPointHash_rmf +ippsGFpECSetPointHashBackCompatible +ippsGFpECSetPointHashBackCompatible_rmf +ippsGFpECGetPoint +ippsGFpECGetPointRegular +ippsGFpECSetPointOctString +ippsGFpECGetPointOctString +ippsGFpECTstPoint +ippsGFpECTstPointInSubgroup +ippsGFpECCpyPoint +ippsGFpECCmpPoint +ippsGFpECNegPoint +ippsGFpECAddPoint +ippsGFpECMulPoint +ippsGFpECPrivateKey +ippsGFpECPublicKey +ippsGFpECTstKeyPair +ippsGFpECSharedSecretDH +ippsGFpECSharedSecretDHC +ippsGFpECSignDSA +ippsGFpECVerifyDSA +ippsGFpECUserIDHashSM2 +ippsGFpECMessageRepresentationSM2 +ippsGFpECSignNR +ippsGFpECVerifyNR +ippsGFpECSignSM2 +ippsGFpECVerifySM2 +ippsGFpECKeyExchangeSM2_GetSize +ippsGFpECKeyExchangeSM2_Init +ippsGFpECKeyExchangeSM2_Setup +ippsGFpECKeyExchangeSM2_SharedKey +ippsGFpECKeyExchangeSM2_Confirm +ippsGFpECEncryptSM2_Ext_EncMsgSize +ippsGFpECEncryptSM2_Ext +ippsGFpECDecryptSM2_Ext_DecMsgSize +ippsGFpECDecryptSM2_Ext +ippsGFpECESGetSize_SM2 +ippsGFpECESInit_SM2 +ippsGFpECESSetKey_SM2 +ippsGFpECESStart_SM2 +ippsGFpECESEncrypt_SM2 +ippsGFpECESDecrypt_SM2 +ippsGFpECESFinal_SM2 +ippsGFpECESGetBuffersSize_SM2 diff --git a/plugin/ippcp/library/src/sources/ippcp/owncp.h b/plugin/ippcp/library/src/sources/ippcp/owncp.h new file mode 100644 index 000000000..bb9604e02 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/owncp.h @@ -0,0 +1,207 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +*/ + +#ifndef __OWNCP_H__ +#define __OWNCP_H__ + +#ifndef __OWNDEFS_H__ + #include "owndefs.h" +#endif + +#ifndef IPPCP_H__ + #if defined _MERGED_BLD + #include "ippcp_cpuspc.h" + #endif + + #include "ippcp.h" +#endif + +/* +// modes of the CPU feature +*/ +#define _FEATURE_OFF_ (0) /* feature is OFF */ +#define _FEATURE_ON_ (1) /* feature is ON */ +#define _FEATURE_TICKTOCK_ (2) /* dectect if feature is OFF/ON */ + +#include "pcpvariant.h" + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) // for MSVC +#pragma warning(disable : 4324) // structures padding warning +#endif + +/* ippCP length */ +typedef int cpSize; + +/* +// Common ippCP Macros +*/ + +/* size of cache line (bytes) */ +#if (_IPP==_IPP_M5) +#define CACHE_LINE_SIZE (16) +#define LOG_CACHE_LINE_SIZE (4) +#else +#define CACHE_LINE_SIZE (64) +#define LOG_CACHE_LINE_SIZE (6) +#endif + +/* swap data & pointers */ +#define SWAP_PTR(ATYPE, pX,pY) { ATYPE* aPtr=(pX); (pX)=(pY); (pY)=aPtr; } +#define SWAP(x,y) {(x)^=(y); (y)^=(x); (x)^=(y);} + +/* alignment value */ +#define ALIGN_VAL ((int)sizeof(void*)) + +/* bitsize */ +#define BYTESIZE (8) +#define BITSIZE(x) ((int)(sizeof(x)*BYTESIZE)) + +/* bit length -> byte/word length conversion */ +#define BITS2WORD8_SIZE(x) (((x)+ 7)>>3) +#define BITS2WORD16_SIZE(x) (((x)+15)>>4) +#define BITS2WORD32_SIZE(x) (((x)+31)>>5) +#define BITS2WORD64_SIZE(x) (((x)+63)>>6) + +/* WORD and DWORD manipulators */ +#define IPP_LODWORD(x) ((Ipp32u)(x)) +#define IPP_HIDWORD(x) ((Ipp32u)(((Ipp64u)(x) >>32) & 0xFFFFFFFF)) + +#define IPP_MAKEHWORD(bLo,bHi) ((Ipp16u)(((Ipp8u)(bLo)) | ((Ipp16u)((Ipp8u)(bHi))) << 8)) +#define IPP_MAKEWORD(hLo,hHi) ((Ipp32u)(((Ipp16u)(hLo)) | ((Ipp32u)((Ipp16u)(hHi))) << 16)) +#define IPP_MAKEDWORD(wLo,wHi) ((Ipp64u)(((Ipp32u)(wLo)) | ((Ipp64u)((Ipp32u)(wHi))) << 32)) + +/* extract byte */ +#define EBYTE(w,n) ((Ipp8u)((w) >> (8 * (n)))) + +/* hexString <-> Ipp32u conversion */ +#define HSTRING_TO_U32(ptrByte) \ + (Ipp32u)(((ptrByte)[0]) <<24) \ + +(Ipp32u)(((ptrByte)[1]) <<16) \ + +(Ipp32u)(((ptrByte)[2]) <<8) \ + +(Ipp32u)((ptrByte)[3]) +#define U32_TO_HSTRING(ptrByte, x) \ + (ptrByte)[0] = (Ipp8u)((x)>>24); \ + (ptrByte)[1] = (Ipp8u)((x)>>16); \ + (ptrByte)[2] = (Ipp8u)((x)>>8); \ + (ptrByte)[3] = (Ipp8u)(x) + +/* 32- and 64-bit masks for MSB of nbits-sequence */ +#define MAKEMASK32(nbits) (0xFFFFFFFF >>((32 - ((nbits)&0x1F)) &0x1F)) +#define MAKEMASK64(nbits) (0xFFFFFFFFFFFFFFFF >>((64 - ((nbits)&0x3F)) &0x3F)) + +/* Logical Shifts (right and left) of WORD */ +#define LSR32(x,nBits) ((x)>>(nBits)) +#define LSL32(x,nBits) ((x)<<(nBits)) + +/* Rorate (right and left) of WORD */ +#if defined(_MSC_VER) && !defined( __ICL ) +# include +# define ROR32(x, nBits) _lrotr((x),(nBits)) +# define ROL32(x, nBits) _lrotl((x),(nBits)) +#else +# define ROR32(x, nBits) (LSR32((x),(nBits)) | LSL32((x),32-(nBits))) +# define ROL32(x, nBits) ROR32((x),(32-(nBits))) +#endif + +/* Logical Shifts (right and left) of DWORD */ +#define LSR64(x,nBits) ((x)>>(nBits)) +#define LSL64(x,nBits) ((x)<<(nBits)) + +/* Rorate (right and left) of DWORD */ +#define ROR64(x, nBits) (LSR64((x),(nBits)) | LSL64((x),64-(nBits))) +#define ROL64(x, nBits) ROR64((x),(64-(nBits))) + +/* change endian */ +#if defined(_MSC_VER) +# define ENDIANNESS(x) _byteswap_ulong((x)) +# define ENDIANNESS32(x) ENDIANNESS((x)) +# define ENDIANNESS64(x) _byteswap_uint64((x)) +#elif defined(__ICL) +# define ENDIANNESS(x) _bswap((x)) +# define ENDIANNESS32(x) ENDIANNESS((x)) +# define ENDIANNESS64(x) _bswap64((x)) +#else +# define ENDIANNESS(x) ((ROR32((x), 24) & 0x00ff00ff) | (ROR32((x), 8) & 0xff00ff00)) +# define ENDIANNESS32(x) ENDIANNESS((x)) +# define ENDIANNESS64(x) IPP_MAKEDWORD(ENDIANNESS(IPP_HIDWORD((x))), ENDIANNESS(IPP_LODWORD((x)))) +#endif + +#define IPP_MAKE_MULTIPLE_OF_8(x) ((x) = ((x)+7)&(~7)) +#define IPP_MAKE_MULTIPLE_OF_16(x) ((x) = ((x)+15)&(~15)) + +/* define 64-bit constant */ +#if !defined(__GNUC__) + #define CONST_64(x) (x) /*(x##i64)*/ +#else + #define CONST_64(x) (x##LL) +#endif + +/* define 64-bit constant or pair of 32-bit dependding on architecture */ +#if ((_IPP_ARCH == _IPP_ARCH_EM64T) || (_IPP_ARCH == _IPP_ARCH_LP64) || (_IPP_ARCH == _IPP_ARCH_LRB) || (_IPP_ARCH == _IPP_ARCH_LRB2)) +#define LL(lo,hi) (((Ipp64u)(lo)) | ((Ipp64u)(hi) << 32)) +#define L_(lo) ((Ipp64u)(lo)) +#else +#define LL(lo,hi) (lo),(hi) +#define L_(lo) (lo) +#endif + + +/* test if library's feature is ON */ +int cpGetFeature( Ipp64u Feature ); +/* test CPU crypto features */ +__INLINE Ipp32u IsFeatureEnabled(Ipp64u niMmask) +{ + return (Ipp32u)cpGetFeature(niMmask); +} + +#define IPPCP_GET_NUM_THREADS() ( ippcpGetEnabledNumThreads() ) +#define IPPCP_OMP_NUM_THREADS() num_threads( IPPCP_GET_NUM_THREADS() ) +#define IPPCP_OMP_LIMIT_MAX_NUM_THREADS(n) num_threads( IPP_MIN(IPPCP_GET_NUM_THREADS(),(n))) + +/* copy under mask */ +#define MASKED_COPY_BNU(dst, mask, src1, src2, len) { \ + cpSize i; \ + for(i=0; i<(len); i++) (dst)[i] = ((mask) & (src1)[i]) | (~(mask) & (src2)[i]); \ +} + +#if (_IPP > _IPP_PX || _IPP32E > _IPP32E_PX) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) +#if !defined( _M_X64 ) && defined ( _MSC_VER ) +__inline __m128i +_mm_cvtsi64_si128(__int64 a) +{ + __m128i x; + x.m128i_i64[0] = a; + x.m128i_i64[1] = 0; + return x; +} +#endif + +#if !defined( __x86_64__ ) && defined(__GNUC__) +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsi64_si128 (long long __A) +{ + return _mm_set_epi64x (0, __A); +} +#endif +#endif /* (_IPP > _IPP_PX || _IPP32E > _IPP32E_PX) && !defined(__INTEL_COMPILER) */ + +#endif /* __OWNCP_H__ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_128keyexpansion_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_128keyexpansion_ni.c new file mode 100644 index 000000000..1888ce5b4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_128keyexpansion_ni.c @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. AES keys expansion +// +// Contents: +// aes128_KeyExpansion_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" + + + +#if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) + +/* +// AES-128 key expansion +*/ +static __m128i aes128_assist(__m128i temp1, __m128i temp2) +{ + __m128i temp3; + temp2 = _mm_shuffle_epi32 (temp2 ,0xff); + temp3 = _mm_slli_si128 (temp1, 0x4); + temp1 = _mm_xor_si128 (temp1, temp3); + temp3 = _mm_slli_si128 (temp3, 0x4); + temp1 = _mm_xor_si128 (temp1, temp3); + temp3 = _mm_slli_si128 (temp3, 0x4); + temp1 = _mm_xor_si128 (temp1, temp3); + temp1 = _mm_xor_si128 (temp1, temp2); + return temp1; +} + +#define aes128_KeyExpansion_NI OWNAPI(aes128_KeyExpansion_NI) + IPP_OWN_DECL (void, aes128_KeyExpansion_NI, (Ipp8u* keyExp, const Ipp8u* userkey)) + +IPP_OWN_DEFN (void, aes128_KeyExpansion_NI, (Ipp8u* keyExp, const Ipp8u* userkey)) +{ + __m128i *pKeySchedule = (__m128i*)keyExp; + + __m128i temp[2]; + /* + temp[0] = temp1 + temp[1] = temp2 + */ + + temp[0] = _mm_loadu_si128((__m128i*)userkey); + pKeySchedule[0] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0] ,0x1); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[1] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x2); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[2] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x4); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[3] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x8); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[4] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x10); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[5] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x20); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[6] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x40); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[7] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x80); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[8] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x1b); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[9] = temp[0]; + temp[1] = _mm_aeskeygenassist_si128 (temp[0],0x36); + temp[0] = aes128_assist(temp[0], temp[1]); + pKeySchedule[10] = temp[0]; + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(temp)/sizeof(temp[0]); i++){ + temp[i] = _mm_xor_si128(temp[i],temp[i]); + } +} + +#endif /* #if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_192keyexpansion_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_192keyexpansion_ni.c new file mode 100644 index 000000000..016c1e2b5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_192keyexpansion_ni.c @@ -0,0 +1,115 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. AES keys expansion +// +// Contents: +// aes192_KeyExpansion_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_keys_ni.h" + +#if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) + +////////////////////////////////////////////////////////////////////// +/* +// AES-192 key expansion +*/ +static void aes192_assist(__m128i* temp1, __m128i * temp2, __m128i * temp3) +{ + __m128i temp4; + *temp2 = _mm_shuffle_epi32 (*temp2, 0x55); + temp4 = _mm_slli_si128 (*temp1, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + *temp1 = _mm_xor_si128 (*temp1, *temp2); + *temp2 = _mm_shuffle_epi32(*temp1, 0xff); + temp4 = _mm_slli_si128 (*temp3, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + *temp3 = _mm_xor_si128 (*temp3, *temp2); +} + +IPP_OWN_DEFN (void, aes192_KeyExpansion_NI, (Ipp8u* keyExp, const Ipp8u* userkey)) +{ + __m128i *pKeySchedule = (__m128i*)keyExp; + + __m128i temp[3]; + /* + temp[0] = temp1 + temp[1] = temp2 + temp[2] = temp3 + */ + + temp[0] = _mm_loadu_si128((__m128i*)userkey); + temp[2] = _mm_cvtsi64_si128(((Ipp64s*)(userkey+16))[0]);//_mm_loadu_si128((__m128i*)(userkey+16)); // read 8 bytes only other are zero + + pKeySchedule[0]=temp[0]; + pKeySchedule[1]=temp[2]; + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x1); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[1] = _mm_unpacklo_epi64 (pKeySchedule[1], temp[0]); + pKeySchedule[2] = _mm_alignr_epi8 (temp[2], temp[0], 8); + + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x2); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[3]=temp[0]; + pKeySchedule[4]=temp[2]; + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x4); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[4] = _mm_unpacklo_epi64(pKeySchedule[4], temp[0]); + pKeySchedule[5] = _mm_alignr_epi8(temp[2], temp[0], 8); + + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x8); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[6]=temp[0]; + pKeySchedule[7]=temp[2]; + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x10); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[7] = _mm_unpacklo_epi64(pKeySchedule[7], temp[0]); + pKeySchedule[8] = _mm_alignr_epi8(temp[2], temp[0],8); + + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x20); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[9]=temp[0]; + pKeySchedule[10]=temp[2]; + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x40); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[10] = _mm_unpacklo_epi64(pKeySchedule[10], temp[0]); + pKeySchedule[11] = _mm_alignr_epi8(temp[2], temp[0], 8); + + temp[1]=_mm_aeskeygenassist_si128 (temp[2],0x80); + aes192_assist(&temp[0], &temp[1], &temp[2]); + pKeySchedule[12]=temp[0]; + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(temp)/sizeof(temp[0]); i++){ + temp[i] = _mm_xor_si128(temp[i],temp[i]); + } +} + +#endif /* #if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_256keyexpansion_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_256keyexpansion_ni.c new file mode 100644 index 000000000..8f3b04736 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_256keyexpansion_ni.c @@ -0,0 +1,129 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. AES keys expansion +// +// Contents: +// aes256_KeyExpansion_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_keys_ni.h" + + +#if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) + +////////////////////////////////////////////////////////////////////// +/* +// AES-256 key expansion +*/ +static void aes256_assist_1(__m128i* temp1, __m128i * temp2) +{ + __m128i temp4; + *temp2 = _mm_shuffle_epi32(*temp2, 0xff); + temp4 = _mm_slli_si128 (*temp1, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp1 = _mm_xor_si128 (*temp1, temp4); + *temp1 = _mm_xor_si128 (*temp1, *temp2); +} + +static void aes256_assist_2(__m128i* temp1, __m128i * temp3) +{ + __m128i temp2,temp4; + temp4 = _mm_aeskeygenassist_si128 (*temp1, 0x0); + temp2 = _mm_shuffle_epi32(temp4, 0xaa); + temp4 = _mm_slli_si128 (*temp3, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + temp4 = _mm_slli_si128 (temp4, 0x4); + *temp3 = _mm_xor_si128 (*temp3, temp4); + *temp3 = _mm_xor_si128 (*temp3, temp2); +} + +IPP_OWN_DEFN (void, aes256_KeyExpansion_NI, (Ipp8u* keyExp, const Ipp8u* userkey)) +{ + __m128i *pKeySchedule = (__m128i*)keyExp; + + __m128i temp[3]; + /* + temp[0] = temp1 + temp[1] = temp2 + temp[2] = temp3 + */ + + temp[0] = _mm_loadu_si128((__m128i*)userkey); + temp[2] = _mm_loadu_si128((__m128i*)(userkey+16)); + pKeySchedule[0] = temp[0]; + pKeySchedule[1] = temp[2]; + + temp[1] = _mm_aeskeygenassist_si128 (temp[2],0x01); + aes256_assist_1(&temp[0], &temp[1]); + pKeySchedule[2]=temp[0]; + aes256_assist_2(&temp[0], &temp[2]); + pKeySchedule[3]=temp[2]; + + temp[1] = _mm_aeskeygenassist_si128 (temp[2],0x02); + aes256_assist_1(&temp[0], &temp[1]); + pKeySchedule[4]=temp[0]; + aes256_assist_2(&temp[0], &temp[2]); + pKeySchedule[5]=temp[2]; + + temp[1] = _mm_aeskeygenassist_si128 (temp[2],0x04); + aes256_assist_1(&temp[0], &temp[1]); + pKeySchedule[6]=temp[0]; + aes256_assist_2(&temp[0], &temp[2]); + pKeySchedule[7]=temp[2]; + + temp[1] = _mm_aeskeygenassist_si128 (temp[2],0x08); + aes256_assist_1(&temp[0], &temp[1]); + pKeySchedule[8]=temp[0]; + aes256_assist_2(&temp[0], &temp[2]); + pKeySchedule[9]=temp[2]; + + temp[1] = _mm_aeskeygenassist_si128 (temp[2],0x10); + aes256_assist_1(&temp[0], &temp[1]); + pKeySchedule[10]=temp[0]; + aes256_assist_2(&temp[0], &temp[2]); + pKeySchedule[11]=temp[2]; + + temp[1] = _mm_aeskeygenassist_si128 (temp[2],0x20); + aes256_assist_1(&temp[0], &temp[1]); + pKeySchedule[12]=temp[0]; + aes256_assist_2(&temp[0], &temp[2]); + pKeySchedule[13]=temp[2]; + + temp[1] = _mm_aeskeygenassist_si128 (temp[2],0x40); + aes256_assist_1(&temp[0], &temp[1]); + pKeySchedule[14]=temp[0]; + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(temp)/sizeof(temp[0]); i++){ + temp[i] = _mm_xor_si128(temp[i],temp[i]); + } +} + +#endif /* #if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes.h new file mode 100644 index 000000000..284a75c16 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes.h @@ -0,0 +1,199 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES GCM AVX2 +// Internal Functions Implementations +// +*/ + +#ifndef __AES_GCM_AVX2_H_ +#define __AES_GCM_AVX2_H_ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthgcm.h" +#include "pcptool.h" + +#if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) + +#define MAX_NK 15 //the largest possible number of keys + +#define SHUFD_MASK 78 // 01001110b +#define STEP_SIZE 64 // 4*BLOCK_SIZE, due to block size is always 16 for AES +#define HALF_STEP_SIZE 32 // 2*BLOCK_SIZE, due to block size is always 16 for AES + +//is used to increment two 128-bit words in a 256-bit register +#define IncrementRegister256(t_block, t_incr, t_shuffle_mask) \ + t_block = _mm256_shuffle_epi8(t_block, t_shuffle_mask); \ + t_block = _mm256_add_epi32(t_block, t_incr); \ + t_block = _mm256_shuffle_epi8(t_block, t_shuffle_mask) + +// these constants are used to increment two 128-bit words in a 256-bit register +__ALIGN32 static const Ipp32u _increment2[] = {0, 0, 0, 2, 0, 0, 0, 2}; +__ALIGN32 static const Ipp32u _increment4[] = {0, 0, 0, 4, 0, 0, 0, 4}; +__ALIGN32 static const Ipp8u swapBytes256[] = { + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 31, 30, 29, 28, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 15, 14, 13, 12 +}; + +// shuffle masks +__ALIGN32 static const Ipp8u _shuff_mask_128[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; +__ALIGN32 static const Ipp8u _shuff_mask_256[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; + +// masks for operations with intrinsics +__ALIGN32 static const Ipp8u _mask_lo_256[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0}; +__ALIGN32 static const Ipp8u _mask_hi_256[] = {0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +/* +// sse_clmul_gcm performs clmul with 128-bit registers; is used in the combine hash step +// input: +// const __m128i *HK - containts hashed keys +// input/output: +// __m128i *GH - contains GHASH. Will be overwritten in this function +*/ +__INLINE void sse_clmul_gcm(__m128i *GH, const __m128i *HK) { + __m128i tmpX0, tmpX1, tmpX2, tmpX3; + tmpX2 = _mm_shuffle_epi32 (*GH, SHUFD_MASK); //tmpX2 = {GH0:GH1} + tmpX0 = _mm_shuffle_epi32 (*HK, SHUFD_MASK); //tmpX0 = {HK0:HK1} + tmpX2 = _mm_xor_si128(tmpX2, *GH); //tmpX2 = {GH0+GH1:GH1+GH0} + tmpX0 = _mm_xor_si128(tmpX0, *HK); //tmpX0 = {HK0+HK1:HK1+HK0} + tmpX2 = _mm_clmulepi64_si128 (tmpX2, tmpX0, 0x00); //tmpX2 = (a1+a0)*(b1+b0); tmpX2 = (GH1+GH0)*(HK1+HK0) + tmpX1 = *GH; + *GH = _mm_clmulepi64_si128 (*GH, *HK, 0x00); //GH = a0*b0; GH = GH0*HK0 + tmpX0 = _mm_xor_si128(tmpX0, tmpX0); + tmpX1 = _mm_clmulepi64_si128 (tmpX1, *HK, 0x11); //tmpX1 = a1*b1; tmpX1 = GH1*HK1 + tmpX2 = _mm_xor_si128(tmpX2, *GH); //tmpX2 = (GH1+GH0)*(HK1+HK0) + GH0*HK0 + tmpX2 = _mm_xor_si128(tmpX2, tmpX1); //tmpX2 = a0*b1+a1*b0; tmpX2 = (GH1+GH0)*(HK1+HK0) + GH0*HK0 + GH1*HK1 = GH0*HK1+GH1*HK0 + tmpX0 = _mm_alignr_epi8 (tmpX0, tmpX2, 8); //tmpX0 = {Zeros : HI(a0*b1+a1*b0)} + tmpX2 = _mm_slli_si128 (tmpX2, 8); //tmpX2 = {LO(HI(a0*b1+a1*b0)) : Zeros} + tmpX1 = _mm_xor_si128(tmpX1, tmpX0); // holds the result of the carry-less multiplication of GH by HK + *GH = _mm_xor_si128(*GH, tmpX2); + + //first phase of the reduction + tmpX0 = *GH; //copy GH into tmpX0, tmpX2, tmpX3 + tmpX2 = *GH; + tmpX3 = *GH; + tmpX0 = _mm_slli_epi64 (tmpX0, 63); //packed left shifting << 63 + tmpX2 = _mm_slli_epi64 (tmpX2, 62); //packed left shifting shift << 62 + tmpX3 = _mm_slli_epi64 (tmpX3, 57); //packed left shifting shift << 57 + tmpX0 = _mm_xor_si128(tmpX0, tmpX2); //xor the shifted versions + tmpX0 = _mm_xor_si128(tmpX0, tmpX3); + tmpX2 = tmpX0; + tmpX2 = _mm_slli_si128 (tmpX2, 8); //shift-L tmpX2 2 DWs + tmpX0 = _mm_srli_si128 (tmpX0, 8); //shift-R xmm2 2 DWs + *GH = _mm_xor_si128(*GH, tmpX2); //first phase of the reduction complete + tmpX1 = _mm_xor_si128(tmpX1, tmpX0); //save the lost MS 1-2-7 bits from first phase + + //second phase of the reduction + tmpX2 = *GH; + tmpX2 = _mm_srli_epi64(tmpX2, 5); //packed right shifting >> 5 + tmpX2 = _mm_xor_si128(tmpX2, *GH); //xor shifted versions + tmpX2 = _mm_srli_epi64(tmpX2, 1); //packed right shifting >> 1 + tmpX2 = _mm_xor_si128(tmpX2, *GH); //xor shifted versions + tmpX2 = _mm_srli_epi64(tmpX2, 1); //packed right shifting >> 1 + *GH = _mm_xor_si128(*GH, tmpX2); //second phase of the reduction complete + *GH = _mm_xor_si128(*GH, tmpX1); //the result is in GH +} + +/* +// avx2_clmul_gcm performs clmul with 256-bit registers; is used in the hash calculation step +// input: +// const __m128i *HK - containts hashed keys +// const __m256i *HKeyKaratsuba - countains temporary data for Karatsuba method +// const __m256i *mask_lo - contains mask for taking lower bits +// const __m256i *mask_hi - contains mask for taking higher bits +// input/output: +// __m128i *GH - contains GHASH. Will be overwritten in this function +*/ +__INLINE void avx2_clmul_gcm(__m256i *GH, const __m256i *HK, const __m256i *HKeyKaratsuba, const __m256i *mask_lo, const __m256i *mask_hi) { + __m256i tmpX0, tmpX1, tmpX2; + + tmpX2 = _mm256_shuffle_epi32 (*GH, SHUFD_MASK); + // Karatsuba Method + tmpX1 = *GH; + tmpX2 = _mm256_xor_si256(tmpX2, *GH); + *GH = _mm256_clmulepi64_epi128(*GH, *HK, 0x00); + // Karatsuba Method + + tmpX1 = _mm256_clmulepi64_epi128(tmpX1, *HK, 0x11); + tmpX2 = _mm256_clmulepi64_epi128(tmpX2, *HKeyKaratsuba, 0x00); + tmpX2 = _mm256_xor_si256(tmpX2, *GH); + tmpX2 = _mm256_xor_si256(tmpX2, tmpX1); + tmpX0 = _mm256_shuffle_epi32 (tmpX2, SHUFD_MASK); + tmpX2 = tmpX0; + tmpX0 = _mm256_and_si256(tmpX0, *mask_hi); + tmpX2 = _mm256_and_si256(tmpX2, *mask_lo); + *GH = _mm256_xor_si256(*GH, tmpX0); + tmpX1 = _mm256_xor_si256(tmpX1, tmpX2); + + // first phase of the reduction + tmpX0 = *GH; + *GH = _mm256_slli_epi64 (*GH, 1); + *GH = _mm256_xor_si256(*GH, tmpX0); + *GH = _mm256_slli_epi64 (*GH, 5); + *GH = _mm256_xor_si256(*GH, tmpX0); + *GH = _mm256_slli_epi64 (*GH, 57); + tmpX2 = _mm256_shuffle_epi32(*GH, SHUFD_MASK); + *GH = tmpX2; + tmpX2 = _mm256_and_si256(tmpX2, *mask_lo); + *GH = _mm256_and_si256(*GH, *mask_hi); + *GH = _mm256_xor_si256(*GH, tmpX0); + tmpX1 = _mm256_xor_si256(tmpX1, tmpX2); + + // second phase of the reduction + tmpX2 = *GH; + *GH = _mm256_srli_epi64(*GH, 5); + *GH = _mm256_xor_si256(*GH, tmpX2); + *GH = _mm256_srli_epi64(*GH, 1); + *GH = _mm256_xor_si256(*GH, tmpX2); + *GH = _mm256_srli_epi64(*GH, 1); + *GH = _mm256_xor_si256(*GH, tmpX2); + *GH = _mm256_xor_si256(*GH, tmpX1); +} + +/* +// aes_encoder_avx2vaes_sb is used for single block encryption +// input: +// const Ipp8u *in - contains data for encryprion +// const int Nr - contains number of the rounds +// const __m256i* keys - contains keys +// output: +// Ipp8u *out - stores encrypted data. +*/ +__INLINE void aes_encoder_avx2vaes_sb(const Ipp8u *in, Ipp8u *out, const int Nr, const __m256i* keys) { + __m128i lo = _mm_loadu_si128((void*)in); + __m128i hi = _mm_setzero_si128(); + __m256i block = _mm256_setr_m128i(lo, hi); + block = _mm256_xor_si256(block, *keys); + for(int round = 1; round < Nr; round++) { + keys++; + block = _mm256_aesenc_epi128(block, *keys); + } + keys++; + block = _mm256_aesenclast_epi128(block, *keys); + _mm_storeu_si128((void*)out, _mm256_castsi256_si128(block)); +} + +#endif /* #if(_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) */ + +#endif /* __AES_GCM_AVX2_H_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes_decrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes_decrypt.c new file mode 100644 index 000000000..884bf3743 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes_decrypt.c @@ -0,0 +1,188 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES decryption (GCM mode) +// +*/ + +#include "pcpaes_avx2_vaes.h" + +#if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) + +IPP_OWN_DEFN (void, AesGcmDec_vaes_avx2, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pState)) +{ + const int nloop = len / STEP_SIZE; + IppsRijndael128Spec* pAES = AESGCM_CIPHER(pState); + Ipp8u* pCounter = AESGCM_COUNTER(pState); + Ipp8u* pECounter = AESGCM_ECOUNTER(pState); + __m256i pCounter256, pCounter256_1, pECounter256, pECounter256_1; + __m256i block, block1, cipherText, cipherText_1, plainText, plainText_1; + + // setting temporary data for incremention + const __m256i increment2 = _mm256_loadu_si256((void*)_increment2); // increment by 2 + const __m256i increment4 = _mm256_loadu_si256((void*)_increment4); // increment by 4 + const __m256i shuffle_mask = _mm256_loadu_si256((void*)swapBytes256); + + // loading keys from memory + __m256i rkeys[MAX_NK]; + __m128i tmp_keys_128; + for (int i = 0; i < RIJ_NR(pAES) + 1; i++) { + tmp_keys_128 = _mm_loadu_si128((void*)(RIJ_EKEYS(pAES)+i*16)); + rkeys[i] = _mm256_setr_m128i(tmp_keys_128, tmp_keys_128); + } + + // skip extra calculations if plaintext less than 4 blocks + if (nloop) { + // loading counters from memory + __m128i lo, hi; + lo = _mm_loadu_si128((void*)pCounter); + IncrementCounter32(pCounter); + hi = _mm_loadu_si128((void*)pCounter); + pCounter256_1 = _mm256_setr_m128i(lo, hi); + pCounter256 = pCounter256_1; + IncrementRegister256(pCounter256_1, increment2, shuffle_mask); + + // setting some masks + const __m128i shuff_mask_128 = _mm_loadu_si128((void*)_shuff_mask_128); + const __m256i shuff_mask_256 = _mm256_loadu_si256((void*)_shuff_mask_256); + const __m256i mask_lo_256 = _mm256_loadu_si256((void*)_mask_lo_256); + const __m256i mask_hi_256 = _mm256_loadu_si256((void*)_mask_hi_256); + + lo = _mm_loadu_si128((void*)AESGCM_GHASH(pState)); + hi = _mm_setzero_si128(); + __m256i rpHash0 = _mm256_setr_m128i(_mm_shuffle_epi8(lo, shuff_mask_128), hi); + __m256i rpHash1 = _mm256_setzero_si256(); + + // setting pre-calculated data for hash combining + Ipp8u *pkeys = AESGCM_HKEY(pState); + __m128i HashKey0 = _mm_loadu_si128((void*)pkeys); + pkeys += 16; + __m128i HashKey2 = _mm_loadu_si128((void*)pkeys); + pkeys += 16; + __m128i HashKey4 = _mm_loadu_si128((void*)pkeys); + + // setting pre-calculated data in correct order for Karatsuba method + __m256i HKey = _mm256_setr_m128i(HashKey4, HashKey4); + __m256i HKeyKaratsuba = _mm256_shuffle_epi32(HKey, SHUFD_MASK); + HKeyKaratsuba = _mm256_xor_si256(HKey, HKeyKaratsuba); + do { + // decrypt stage + block = _mm256_xor_si256(pCounter256, *rkeys); + block1 = _mm256_xor_si256(pCounter256_1, *rkeys); + block = _mm256_aesenc_epi128(block, *(rkeys+1)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+1)); + block = _mm256_aesenc_epi128(block, *(rkeys+2)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+2)); + block = _mm256_aesenc_epi128(block, *(rkeys+3)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+3)); + IncrementRegister256(pCounter256, increment4, shuffle_mask); + block = _mm256_aesenc_epi128(block, *(rkeys+4)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+4)); + block = _mm256_aesenc_epi128(block, *(rkeys+5)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+5)); + block = _mm256_aesenc_epi128(block, *(rkeys+6)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+6)); + block = _mm256_aesenc_epi128(block, *(rkeys+7)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+7)); + block = _mm256_aesenc_epi128(block, *(rkeys+8)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+8)); + block = _mm256_aesenc_epi128(block, *(rkeys+9)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+9)); + IncrementRegister256(pCounter256_1, increment4, shuffle_mask); + if (RIJ_NR(pAES) >= 12) { + block = _mm256_aesenc_epi128(block, *(rkeys+10)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+10)); + block = _mm256_aesenc_epi128(block, *(rkeys+11)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+11)); + if (RIJ_NR(pAES) >= 14) { + block = _mm256_aesenc_epi128(block, *(rkeys+12)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+12)); + block = _mm256_aesenc_epi128(block, *(rkeys+13)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+13)); + } + } + pECounter256 = _mm256_aesenclast_epi128(block, *(rkeys+RIJ_NR(pAES))); + pECounter256_1 = _mm256_aesenclast_epi128(block1, *(rkeys+RIJ_NR(pAES))); + + // set ciphertext + plainText = _mm256_loadu_si256((void*)pSrc); + cipherText = _mm256_xor_si256(plainText, pECounter256); + pSrc += HALF_STEP_SIZE; + plainText_1 = _mm256_loadu_si256((void*)pSrc); + cipherText_1 = _mm256_xor_si256(plainText_1, pECounter256_1); + pSrc += HALF_STEP_SIZE; + + // hash calculation stage + rpHash0 = _mm256_xor_si256(rpHash0, _mm256_shuffle_epi8(plainText, shuff_mask_256)); + _mm256_storeu_si256((void*)pDst, cipherText); + pDst += HALF_STEP_SIZE; + _mm256_storeu_si256((void*)pDst, cipherText_1); + pDst += HALF_STEP_SIZE; + rpHash1 = _mm256_xor_si256(rpHash1, _mm256_shuffle_epi8(plainText_1, shuff_mask_256)); + len -= STEP_SIZE; + if (len >= STEP_SIZE) { + avx2_clmul_gcm(&rpHash0, &HKey, &HKeyKaratsuba, &mask_lo_256, &mask_hi_256); + avx2_clmul_gcm(&rpHash1, &HKey, &HKeyKaratsuba, &mask_lo_256, &mask_hi_256); + } + } while(len >= STEP_SIZE); + + // loading temporary data to memory + _mm_storeu_si128((void*)pECounter, _mm256_extractf128_si256(pECounter256, 1)); + _mm_storeu_si128((void*)pCounter, _mm256_castsi256_si128(pCounter256)); + + // combine hash + __m128i GHash0 = _mm256_extractf128_si256(rpHash0, 0); + __m128i GHash1 = _mm256_extractf128_si256(rpHash0, 1); + __m128i GHash2 = _mm256_extractf128_si256(rpHash1, 0); + __m128i GHash3 = _mm256_extractf128_si256(rpHash1, 1); + + sse_clmul_gcm(&GHash0, &HashKey4); //GHash0 = GHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm(&GHash1, &HashKey2); //GHash1 = GHash1 * (HashKey^2)<<1 mod poly + sse_clmul_gcm(&GHash2, &HashKey0); //GHash2 = GHash2 * (HashKey^1)<<1 mod poly + GHash3 = _mm_xor_si128(GHash3, GHash1); + GHash3 = _mm_xor_si128(GHash3, GHash2); + + sse_clmul_gcm(&GHash3, &HashKey0); //GHash3 = GHash3 * (HashKey)<<1 mod poly + GHash3 = _mm_xor_si128(GHash3, GHash0); + GHash3 = _mm_shuffle_epi8(GHash3, shuff_mask_128); + _mm_storeu_si128((void*)(AESGCM_GHASH(pState)), GHash3); + } + + const Ipp8u* pHashedData = pSrc; + int hashedDataLen = len; + + // decryption for the tail (1-3 blocks) + while(len >= BLOCK_SIZE) { + aes_encoder_avx2vaes_sb(pCounter, pECounter, RIJ_NR(pAES), rkeys); + XorBlock16(pSrc, pECounter, pDst); + pSrc += BLOCK_SIZE; + pDst += BLOCK_SIZE; + len -= BLOCK_SIZE; + IncrementCounter32(pCounter); + } + aes_encoder_avx2vaes_sb(pCounter, pECounter, RIJ_NR(pAES), rkeys); + + // hash calculation for the tail (1-3 blocks) + if (hashedDataLen >= BLOCK_SIZE) + AesGcmAuth_avx(AESGCM_GHASH(pState), pHashedData, hashedDataLen, AESGCM_HKEY(pState), AesGcmConst_table); +} + +#endif /* #if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes_encrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes_encrypt.c new file mode 100644 index 000000000..bae8a2db1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_avx2_vaes_encrypt.c @@ -0,0 +1,186 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption (GCM mode) +// +*/ + +#include "pcpaes_avx2_vaes.h" + +#if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) + +IPP_OWN_DEFN (void, AesGcmEnc_vaes_avx2, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pState)) +{ + const int nloop = len / STEP_SIZE; + IppsRijndael128Spec* pAES = AESGCM_CIPHER(pState); + Ipp8u* pCounter = AESGCM_COUNTER(pState); + Ipp8u* pECounter = AESGCM_ECOUNTER(pState); + __m256i pCounter256, pCounter256_1, pECounter256, pECounter256_1; + __m256i block, block1, cipherText, cipherText_1; + + // setting temporary data for incremention + const __m256i increment2 = _mm256_loadu_si256((void*)_increment2); // increment by 2 + const __m256i increment4 = _mm256_loadu_si256((void*)_increment4); // increment by 4 + const __m256i shuffle_mask = _mm256_loadu_si256((void*)swapBytes256); + + // loading keys from memory + __m256i rkeys[MAX_NK]; + __m128i tmp_keys_128; + for (int i = 0; i < RIJ_NR(pAES) + 1; i++) { + tmp_keys_128 = _mm_loadu_si128((void*)(RIJ_EKEYS(pAES)+i*16)); + rkeys[i] = _mm256_setr_m128i(tmp_keys_128, tmp_keys_128); + } + + // skip extra calculations if plaintext less than 4 blocks + if (nloop) { + // loading counters from memory + __m128i lo, hi; + lo = _mm_loadu_si128((void*)pCounter); + IncrementCounter32(pCounter); + hi = _mm_loadu_si128((void*)pCounter); + pCounter256_1 = _mm256_setr_m128i(lo, hi); + pCounter256 = pCounter256_1; + IncrementRegister256(pCounter256_1, increment2, shuffle_mask); + + // setting some masks + const __m128i shuff_mask_128 = _mm_loadu_si128((void*)_shuff_mask_128); + const __m256i shuff_mask_256 = _mm256_loadu_si256((void*)_shuff_mask_256); + const __m256i mask_lo_256 = _mm256_loadu_si256((void*)_mask_lo_256); + const __m256i mask_hi_256 = _mm256_loadu_si256((void*)_mask_hi_256); + + lo = _mm_loadu_si128((__m128i*)AESGCM_GHASH(pState)); + hi = _mm_setzero_si128(); + __m256i rpHash0 = _mm256_setr_m128i(_mm_shuffle_epi8(lo, shuff_mask_128), hi); + __m256i rpHash1 = _mm256_setzero_si256(); + + // setting pre-calculated data for hash combining + Ipp8u *pkeys = AESGCM_HKEY(pState); + __m128i HashKey0 = _mm_loadu_si128((void*)pkeys); + pkeys += 16; + __m128i HashKey2 = _mm_loadu_si128((void*)pkeys); + pkeys += 16; + __m128i HashKey4 = _mm_loadu_si128((void*)pkeys); + + // setting pre-calculated data in correct order for Karatsuba method + __m256i HKey = _mm256_setr_m128i(HashKey4, HashKey4); + __m256i HKeyKaratsuba = _mm256_shuffle_epi32(HKey, SHUFD_MASK); + HKeyKaratsuba = _mm256_xor_si256(HKey, HKeyKaratsuba); + do { + // encrypt stage + block = _mm256_xor_si256(pCounter256, *rkeys); + block1 = _mm256_xor_si256(pCounter256_1, *rkeys); + block = _mm256_aesenc_epi128(block, *(rkeys+1)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+1)); + block = _mm256_aesenc_epi128(block, *(rkeys+2)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+2)); + block = _mm256_aesenc_epi128(block, *(rkeys+3)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+3)); + IncrementRegister256(pCounter256, increment4, shuffle_mask); + block = _mm256_aesenc_epi128(block, *(rkeys+4)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+4)); + block = _mm256_aesenc_epi128(block, *(rkeys+5)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+5)); + block = _mm256_aesenc_epi128(block, *(rkeys+6)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+6)); + block = _mm256_aesenc_epi128(block, *(rkeys+7)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+7)); + block = _mm256_aesenc_epi128(block, *(rkeys+8)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+8)); + block = _mm256_aesenc_epi128(block, *(rkeys+9)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+9)); + IncrementRegister256(pCounter256_1, increment4, shuffle_mask); + if (RIJ_NR(pAES) >= 12) { + block = _mm256_aesenc_epi128(block, *(rkeys+10)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+10)); + block = _mm256_aesenc_epi128(block, *(rkeys+11)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+11)); + if (RIJ_NR(pAES) >= 14) { + block = _mm256_aesenc_epi128(block, *(rkeys+12)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+12)); + block = _mm256_aesenc_epi128(block, *(rkeys+13)); + block1 = _mm256_aesenc_epi128(block1, *(rkeys+13)); + } + } + pECounter256 = _mm256_aesenclast_epi128(block, *(rkeys+RIJ_NR(pAES))); + pECounter256_1 = _mm256_aesenclast_epi128(block1, *(rkeys+RIJ_NR(pAES))); + + // set ciphertext + cipherText = _mm256_xor_si256( _mm256_loadu_si256((void*)pSrc), pECounter256); + pSrc += HALF_STEP_SIZE; + cipherText_1 = _mm256_xor_si256( _mm256_loadu_si256((void*)pSrc), pECounter256_1); + pSrc += HALF_STEP_SIZE; + + // hash calculation stage + rpHash0 = _mm256_xor_si256(rpHash0, _mm256_shuffle_epi8(cipherText, shuff_mask_256)); + _mm256_storeu_si256((void*)pDst, cipherText); + pDst += HALF_STEP_SIZE; + _mm256_storeu_si256((void*)pDst, cipherText_1); + pDst += HALF_STEP_SIZE; + rpHash1 = _mm256_xor_si256(rpHash1, _mm256_shuffle_epi8(cipherText_1, shuff_mask_256)); + len -= STEP_SIZE; + if (len >= STEP_SIZE) { + avx2_clmul_gcm(&rpHash0, &HKey, &HKeyKaratsuba, &mask_lo_256, &mask_hi_256); + avx2_clmul_gcm(&rpHash1, &HKey, &HKeyKaratsuba, &mask_lo_256, &mask_hi_256); + } + } while(len >= STEP_SIZE); + + // loading temporary data to memory + _mm_storeu_si128((void*)pECounter, _mm256_extractf128_si256(pECounter256, 1)); + _mm_storeu_si128((void*)pCounter, _mm256_castsi256_si128(pCounter256)); + + // combine hash + __m128i GHash0 = _mm256_extractf128_si256(rpHash0, 0); + __m128i GHash1 = _mm256_extractf128_si256(rpHash0, 1); + __m128i GHash2 = _mm256_extractf128_si256(rpHash1, 0); + __m128i GHash3 = _mm256_extractf128_si256(rpHash1, 1); + + sse_clmul_gcm(&GHash0, &HashKey4); //GHash0 = GHash0 * (HashKey^4)<<1 mod poly + sse_clmul_gcm(&GHash1, &HashKey2); //GHash1 = GHash1 * (HashKey^2)<<1 mod poly + sse_clmul_gcm(&GHash2, &HashKey0); //GHash2 = GHash2 * (HashKey^1)<<1 mod poly + GHash3 = _mm_xor_si128(GHash3, GHash1); + GHash3 = _mm_xor_si128(GHash3, GHash2); + + sse_clmul_gcm(&GHash3, &HashKey0); //GHash3 = GHash3 * (HashKey)<<1 mod poly + GHash3 = _mm_xor_si128(GHash3, GHash0); + GHash3 = _mm_shuffle_epi8(GHash3, shuff_mask_128); + _mm_storeu_si128((void*)(AESGCM_GHASH(pState)), GHash3); + } + + Ipp8u* pHashedData = pDst; + int hashedDataLen = len; + + // encryption for the tail (1-3 blocks) + while(len >= BLOCK_SIZE) { + aes_encoder_avx2vaes_sb(pCounter, pECounter, RIJ_NR(pAES), rkeys); + XorBlock16(pSrc, pECounter, pDst); + pSrc += BLOCK_SIZE; + pDst += BLOCK_SIZE; + len -= BLOCK_SIZE; + IncrementCounter32(pCounter); + } + aes_encoder_avx2vaes_sb(pCounter, pECounter, RIJ_NR(pAES), rkeys); + + // hash calculation for the tail (1-3 blocks) + if (hashedDataLen >= BLOCK_SIZE) + AesGcmAuth_avx(AESGCM_GHASH(pState), pHashedData, hashedDataLen, AESGCM_HKEY(pState), AesGcmConst_table); +} + +#endif /* #if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_decrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_decrypt.c new file mode 100644 index 000000000..1abde000d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_decrypt.c @@ -0,0 +1,131 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES decryption (CBC mode) +// AES decryption (CBC-CS mode) +// +// Contents: +// cpDecryptAES_cbc() +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_cbc_decrypt.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/* +// AES-CBC decryption +// +// Parameters: +// pIV pointer to the initialization vector +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// nBlocks number of decrypted data blocks +// pCtx pointer to the AES context +*/ +IPP_OWN_DEFN (void, cpDecryptAES_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, const IppsAESSpec* pCtx)) +{ +#if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + DecryptCBC_RIJ128pipe_VAES_NI(pSrc, pDst, nBlocks*MBS_RIJ128, pCtx, pIV); + } + else +#endif +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use pipelined version is possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + DecryptCBC_RIJ128pipe_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), nBlocks*MBS_RIJ128, pIV); + } + else +#endif + { + /* setup decoder method */ + RijnCipher decoder = RIJ_DECODER(pCtx); + + Ipp32u iv[NB(128)]; + + /* copy IV */ + CopyBlock16(pIV, iv); + + /* not inplace block-by-block decryption */ + if(pSrc != pDst) { + while(nBlocks) { + //decoder((const Ipp32u*)pSrc, (Ipp32u*)pDst, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), (const Ipp32u (*)[256])RIJ_DEC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + decoder(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijDecSbox/*NULL*/); + #else + decoder(pSrc, pDst, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), NULL); + #endif + + ((Ipp32u*)pDst)[0] ^= iv[0]; + ((Ipp32u*)pDst)[1] ^= iv[1]; + ((Ipp32u*)pDst)[2] ^= iv[2]; + ((Ipp32u*)pDst)[3] ^= iv[3]; + + iv[0] = ((Ipp32u*)pSrc)[0]; + iv[1] = ((Ipp32u*)pSrc)[1]; + iv[2] = ((Ipp32u*)pSrc)[2]; + iv[3] = ((Ipp32u*)pSrc)[3]; + + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + nBlocks--; + } + } + /* inplace block-by-block decryption */ + else { + Ipp32u tmpOut[NB(128)]; + + while(nBlocks) { + //decoder(pSrc, tmpOut, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), (const Ipp32u (*)[256])RIJ_DEC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + decoder(pSrc, (Ipp8u*)tmpOut, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijDecSbox/*NULL*/); + #else + decoder(pSrc, (Ipp8u*)tmpOut, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), NULL); + #endif + + tmpOut[0] ^= iv[0]; + tmpOut[1] ^= iv[1]; + tmpOut[2] ^= iv[2]; + tmpOut[3] ^= iv[3]; + + iv[0] = ((Ipp32u*)pSrc)[0]; + iv[1] = ((Ipp32u*)pSrc)[1]; + iv[2] = ((Ipp32u*)pSrc)[2]; + iv[3] = ((Ipp32u*)pSrc)[3]; + + CopyBlock16(tmpOut, pDst); + + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + nBlocks--; + } + + /* clear secret data */ + PurgeBlock(tmpOut, sizeof(tmpOut)); + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_decrypt.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_decrypt.h new file mode 100644 index 000000000..d48ee3110 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_decrypt.h @@ -0,0 +1,39 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES decryption (CBC mode) +// AES decryption (CBC-CS mode) +// +// Contents: +// cpDecryptAES_cbc() +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#if !defined(_PCP_AES_CBC_DECRYPT_H_) +#define _PCP_AES_CBC_DECRYPT_H_ + +#define cpDecryptAES_cbc OWNAPI(cpDecryptAES_cbc) + IPP_OWN_DECL (void, cpDecryptAES_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, const IppsAESSpec* pCtx)) + +#endif /* #if !defined(_PCP_AES_CBC_DECRYPT_H_) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_encrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_encrypt.c new file mode 100644 index 000000000..293c4649a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_encrypt.c @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption (CBC mode) +// AES encryption (CBC-CS mode) +// +// Contents: +// cpEncryptAES_cbc() +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_cbc_encrypt.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/* +// AES-CBC ecnryption +// +// Parameters: +// pIV pointer to the initialization vector +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// nBlocks number of ecnrypted data blocks +// pCtx pointer to the AES context +*/ +IPP_OWN_DEFN (void, cpEncryptAES_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, const IppsAESSpec* pCtx)) +{ +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + EncryptCBC_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), nBlocks*MBS_RIJ128, pIV); + } + else +#endif + { + /* setup encoder method */ + RijnCipher encoder = RIJ_ENCODER(pCtx); + + /* read IV */ + Ipp32u iv[NB(128)]; + CopyBlock16(pIV, iv); + + /* block-by-block encryption */ + while(nBlocks) { + iv[0] ^= ((Ipp32u*)pSrc)[0]; + iv[1] ^= ((Ipp32u*)pSrc)[1]; + iv[2] ^= ((Ipp32u*)pSrc)[2]; + iv[3] ^= ((Ipp32u*)pSrc)[3]; + + //encoder(iv, (Ipp32u*)pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)iv, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)iv, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), NULL); + #endif + + iv[0] = ((Ipp32u*)pDst)[0]; + iv[1] = ((Ipp32u*)pDst)[1]; + iv[2] = ((Ipp32u*)pDst)[2]; + iv[3] = ((Ipp32u*)pDst)[3]; + + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + nBlocks--; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_encrypt.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_encrypt.h new file mode 100644 index 000000000..40d612760 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_encrypt.h @@ -0,0 +1,39 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption (CBC mode) +// AES encryption (CBC-CS mode) +// +// Contents: +// cpEncryptAES_cbc() +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#if !defined(_PCP_AES_CBC_ENCRYPT_H_) +#define _PCP_AES_CBC_ENCRYPT_H_ + +#define cpEncryptAES_cbc OWNAPI(cpEncryptAES_cbc) + IPP_OWN_DECL (void, cpEncryptAES_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, const IppsAESSpec* pCtx)) + +#endif /* #if !defined(_PCP_AES_CBC_ENCRYPT_H_) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_vaes512.c new file mode 100644 index 000000000..2e9accc61 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbc_vaes512.c @@ -0,0 +1,170 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CBC mode) +// +// Contents: +// DecryptCBC_RIJ128pipe_VAES_NI() +// +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_decrypt_vaes512.h" + +#if(_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // zmmintrin.h bug: truncation of constant value +#endif +//////////////////////////////////////////////////////////////////////////////// + +IPP_OWN_DEFN (void, DecryptCBC_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, // pointer to the ciphertext + Ipp8u* pDst, // pointer to the plaintext + int len, // message length + const IppsAESSpec* pCtx, // pointer to context + const Ipp8u* pIV)) // pointer to the Initialization Vector +{ + int cipherRounds = RIJ_NR(pCtx) - 1; + + __m128i* pRkey = (__m128i*)RIJ_DKEYS(pCtx) + cipherRounds + 1; + __m512i* pSrc512 = (__m512i*)pSrc; + __m512i* pDst512 = (__m512i*)pDst; + __m512i* pIV512 = (__m512i*)pIV; + + // load IV + __m512i IV = _mm512_maskz_expandloadu_epi64(0xC0, pIV512); + + int blocks; + // 4 blocks of 128-bit can be loaded into one zmm register + // assuming that vaesdec latency is 4, we need 4 zmm registers to make effective pipeline + for (blocks = len / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + __m512i blk3 = _mm512_loadu_si512(pSrc512 + 3); + + // prepare blocks for the last xor + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); + __m512i z1 = _mm512_alignr_epi64(blk1, blk0, 6); + __m512i z2 = _mm512_alignr_epi64(blk2, blk1, 6); + __m512i z3 = _mm512_alignr_epi64(blk3, blk2, 6); + + // update IV + IV = blk3; + + cpAESDecrypt4_VAES_NI(&blk0, &blk1, &blk2, &blk3, pRkey, cipherRounds); + + // the last xor + blk0 = _mm512_xor_si512(blk0, z0); + blk1 = _mm512_xor_si512(blk1, z1); + blk2 = _mm512_xor_si512(blk2, z2); + blk3 = _mm512_xor_si512(blk3, z3); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + _mm512_storeu_si512(pDst512 + 3, blk3); + + pSrc512 += 4; + pDst512 += 4; + } + + if ((3 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); + __m512i z1 = _mm512_alignr_epi64(blk1, blk0, 6); + __m512i z2 = _mm512_alignr_epi64(blk2, blk1, 6); + + // update IV + IV = blk2; + + cpAESDecrypt3_VAES_NI(&blk0, &blk1, &blk2, pRkey, cipherRounds); + + blk0 = _mm512_xor_si512(blk0, z0); + blk1 = _mm512_xor_si512(blk1, z1); + blk2 = _mm512_xor_si512(blk2, z2); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + + pSrc512 += 3; + pDst512 += 3; + blocks -= (3 * 4); + } + if ((4 * 2) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); + __m512i z1 = _mm512_alignr_epi64(blk1, blk0, 6); + + // update IV + IV = blk1; + + cpAESDecrypt2_VAES_NI(&blk0, &blk1, pRkey, cipherRounds); + + blk0 = _mm512_xor_si512(blk0, z0); + blk1 = _mm512_xor_si512(blk1, z1); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + + pSrc512 += 2; + pDst512 += 2; + blocks -= (2 * 4); + } + for (; blocks >= 4; blocks -= 4) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); + + // update IV + IV = blk0; + + cpAESDecrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + blk0 = _mm512_xor_si512(blk0, z0); + + _mm512_storeu_si512(pDst512, blk0); + + pSrc512 += 1; + pDst512 += 1; + } + if (blocks) { + __mmask8 k = (__mmask8)((1 << (blocks + blocks)) - 1); + __m512i blk0 = _mm512_maskz_loadu_epi64(k, pSrc512); + + __m512i z0 = _mm512_maskz_alignr_epi64(k, blk0, IV, 6); + + cpAESDecrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + blk0 = _mm512_maskz_xor_epi64(k, blk0, z0); + + _mm512_mask_storeu_epi64(pDst512, k, blk0); + } +} + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbcdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbcdecrypt.c new file mode 100644 index 000000000..976d05055 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbcdecrypt.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CBC mode) +// AES encryption/decryption (CBC-CS mode) +// +// Contents: +// ippsAESDecryptCBC() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_cbc_decrypt.h" + +/*F* +// Name: ippsAESDecryptCBC +// +// Purpose: AES-CBC decryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsUnderRunErr 0!=(dataLen%MBS_RIJ128) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +// +*F*/ +IPPFUN(IppStatus, ippsAESDecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test source, target buffers and initialization pointers */ + IPP_BAD_PTR3_RET(pSrc, pIV, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test stream integrity */ + IPP_BADARG_RET((len&(MBS_RIJ128-1)), ippStsUnderRunErr); + + /* do encryption */ + { + int nBlocks = len / MBS_RIJ128; + + cpDecryptAES_cbc(pIV, pSrc, pDst, nBlocks, pCtx); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbcdecrypt_cs1.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbcdecrypt_cs1.c new file mode 100644 index 000000000..924a90d7d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cbcdecrypt_cs1.c @@ -0,0 +1,132 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CBC mode) +// AES encryption/decryption (CBC-CS mode) +// +// Contents: +// ippsAESDecryptCBC_CS1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_cbc_decrypt.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/*F* +// Name: ippsAESDecryptCBC_CS1 +// +// Purpose: AES-CBC_CS1 decryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len AESCCM_MSGLEN(pState), ippStsLengthErr); + + /* + // enctypt payload and update MAC + */ + if(len) { + /* setup encoder method */ + IppsAESSpec* pAES = AESCCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + Ipp32u flag = (Ipp32u)( AESCCM_LENPRO(pState) &(MBS_RIJ128-1) ); + + Ipp32u qLen; + Ipp32u counterVal; + + Ipp32u MAC[NB(128)]; + Ipp32u CTR[NB(128)]; + Ipp32u S[NB(128)]; + /* extract from the state */ + CopyBlock16(AESCCM_MAC(pState), MAC); + CopyBlock16(AESCCM_CTR0(pState), CTR); + CopyBlock16(AESCCM_Si(pState), S); + counterVal = AESCCM_COUNTER(pState); + + /* extract qLen */ + qLen = (((Ipp8u*)CTR)[0] &0x7) +1; /* &0x7 just to fix KW issue */ + + if(flag) { + Ipp32u tmpLen = (Ipp32u)( IPP_MIN(len, MBS_RIJ128-1) ); + XorBlock(pSrc, (Ipp8u*)S+flag, pDst, (Ipp32s)tmpLen); + + /* copy as much input as possible into the internal buffer*/ + CopyBlock(pDst, AESCCM_BLK(pState)+flag, (Ipp32s)tmpLen); + + /* update MAC */ + if(flag+tmpLen == MBS_RIJ128) { + XorBlock16(MAC, AESCCM_BLK(pState), MAC); + //encoder(MAC, MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + + AESCCM_LENPRO(pState) += tmpLen; + pSrc += tmpLen; + pDst += tmpLen; + len -= tmpLen; + } + + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pAES)) { + Ipp32u processedLen = (Ipp32u)(len & -MBS_RIJ128); + if(processedLen) { + /* local state: MAC, counter block, counter bits mask */ + __ALIGN16 Ipp8u localState[3*MBS_RIJ128]; + + /* format counter block and fill local state */ + Ipp32u n; + for(n=0; n= MBS_RIJ128) { + Ipp32u counterEnc[2]; + /* increment counter and format counter block */ + counterVal++; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)qLen, counterVal), ((Ipp8u*)CTR)+MBS_RIJ128-qLen, (Ipp32s)qLen); + /* encode counter block */ + //encoder(CTR, S, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + /* store cipher text */ + XorBlock16(pSrc, S, pDst); + + /* update MAC */ + XorBlock16(MAC, pDst, MAC); + //encoder(MAC, MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + AESCCM_LENPRO(pState) += MBS_RIJ128; + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + len -= MBS_RIJ128; + } + + if(len) { + Ipp32u counterEnc[2]; + /* increment counter and format counter block */ + counterVal++; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)qLen, counterVal), ((Ipp8u*)CTR)+MBS_RIJ128-qLen, (Ipp32s)qLen); + /* encode counter block */ + //encoder(CTR, S, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + /* store cipher text */ + XorBlock(pSrc, S, pDst, len); + + /* workaround to avoid false positive stringop-overflow error on gcc10.1 and gcc11.1 */ + len = ( IPP_MIN(len, MBS_RIJ128-1) ); + + /* store partial data block */ + CopyBlock(pDst, AESCCM_BLK(pState), len); + + AESCCM_LENPRO(pState) += (Ipp64u)len; + } + + /* update state */ + CopyBlock16(MAC, AESCCM_MAC(pState)); + CopyBlock16(S, AESCCM_Si(pState)); + AESCCM_COUNTER(pState) = counterVal; + + /* clear secret data */ + PurgeBlock(S, sizeof(S)); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmencrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmencrypt.c new file mode 100644 index 000000000..d43d9270e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmencrypt.c @@ -0,0 +1,211 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsAES_CCMEncrypt() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthccm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/*F* +// Name: ippsAES_CCMEncrypt +// +// Purpose: Encrypts data and updates authentication tag. +// +// Returns: Reason: +// ippStsNullPtrErr pState== NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr !VALID_AESCCM_ID() +// ippStsLengthErr if exceed overall length of message is being processed +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the plane text beffer +// pDst pointer to the cipher text bubber +// len length of the buffer +// pState pointer to the CCM context +// +*F*/ +IPPFUN(IppStatus, ippsAES_CCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_CCMState* pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!VALID_AESCCM_ID(pState), ippStsContextMatchErr); + + /* test source/destination data */ + IPP_BAD_PTR2_RET(pSrc, pDst); + + /* test message length */ + IPP_BADARG_RET(len<0 || AESCCM_LENPRO(pState)+(Ipp64u)len >AESCCM_MSGLEN(pState), ippStsLengthErr); + + /* + // enctypt payload and update MAC + */ + if(len) { + /* setup encoder method */ + IppsAESSpec* pAES = AESCCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + Ipp32u flag = (Ipp32u)( AESCCM_LENPRO(pState) &(MBS_RIJ128-1) ); + + Ipp32u qLen; + Ipp32u counterVal; + + Ipp32u MAC[NB(128)]; + Ipp32u CTR[NB(128)]; + Ipp32u S[NB(128)]; + /* extract from the state */ + CopyBlock16(AESCCM_MAC(pState), MAC); + CopyBlock16(AESCCM_CTR0(pState), CTR); + CopyBlock16(AESCCM_Si(pState), S); + counterVal = AESCCM_COUNTER(pState); + + /* extract qLen */ + qLen = (((Ipp8u*)CTR)[0] &0x7) +1; /* &0x7 just to fix KW issue */ + + if(flag) { + Ipp32u tmpLen = (Ipp32u)IPP_MIN(len, MBS_RIJ128-1); + + /* copy as much input as possible into the internal buffer*/ + CopyBlock(pSrc, AESCCM_BLK(pState)+flag, (Ipp32s)tmpLen); + + XorBlock(pSrc, (Ipp8u*)S+flag, pDst, (Ipp32s)tmpLen); + + /* update MAC */ + if(flag+(Ipp32u)tmpLen == MBS_RIJ128) { + XorBlock16(MAC, AESCCM_BLK(pState), MAC); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + + AESCCM_LENPRO(pState) += (Ipp32u)tmpLen; + pSrc += tmpLen; + pDst += tmpLen; + len -= tmpLen; + } + + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pAES)) { + Ipp32u processedLen = (Ipp32u)(len & -MBS_RIJ128); + if(processedLen) { + /* local state: MAC, counter block, counter bits mask */ + __ALIGN16 Ipp8u localState[3*MBS_RIJ128]; + + /* format counter block and fill local state: */ + Ipp32u n; + for(n=0; n= MBS_RIJ128) { + Ipp32u counterEnc[2]; + + /* update MAC */ + XorBlock16(MAC, pSrc, MAC); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + /* increment counter and format counter block */ + counterVal++; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)qLen, counterVal), ((Ipp8u*)CTR)+MBS_RIJ128-qLen, (Ipp32s)qLen); + /* encode counter block */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + /* store cipher text */ + XorBlock16(pSrc, S, pDst); + + AESCCM_LENPRO(pState) += MBS_RIJ128; + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + len -= MBS_RIJ128; + } + + if(len) { + Ipp32u counterEnc[2]; + + /* workaround to avoid false positive stringop-overflow error on gcc10.1 and gcc11.1 */ + len = ( IPP_MIN(len, MBS_RIJ128-1) ); + + /* store partial data block */ + CopyBlock(pSrc, AESCCM_BLK(pState), len); + + /* increment counter and format counter block */ + counterVal++; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)qLen, counterVal), ((Ipp8u*)CTR)+MBS_RIJ128-qLen, (Ipp32s)qLen); + /* encode counter block */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)CTR, (Ipp8u*)S, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + /* store cipher text */ + XorBlock(pSrc, S, pDst, len); + + AESCCM_LENPRO(pState) += (Ipp64u)len; + } + + /* update state */ + CopyBlock16(MAC, AESCCM_MAC(pState)); + CopyBlock16(S, AESCCM_Si(pState)); + AESCCM_COUNTER(pState) = counterVal; + + /* clear secret data */ + PurgeBlock(S, sizeof(S)); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmgetsize.c new file mode 100644 index 000000000..f101403cb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmgetsize.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsAES_CCMGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthccm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/*F* +// Name: ippsAES_CCMGetSize +// +// Purpose: Returns size of AES-CCM state (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of CCM (in bytes) +// +*F*/ +IPPFUN(IppStatus, ippsAES_CCMGetSize,(int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = cpSizeofCtx_AESCCM(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmgettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmgettag.c new file mode 100644 index 000000000..3c0faddd3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmgettag.c @@ -0,0 +1,92 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsAES_CCMGetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthccm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/*F* +// Name: ippsAES_CCMGetTag +// +// Purpose: Compute message auth tag and return one. +// Note, that futher encryption/decryption and auth tag update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr !VALID_AESCCM_ID() +// ippStsLengthErr MBS_RIJ128 < tagLen +// 1 > tagLen +// ippStsNoErr no errors +// +// Parameters: +// pTag pointer to the output authenticated tag +// tagLen requested length of the tag +// pState pointer to the CCM context +// +*F*/ +IPPFUN(IppStatus, ippsAES_CCMGetTag,(Ipp8u* pTag, int tagLen, const IppsAES_CCMState* pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + + /* test state ID */ + IPP_BADARG_RET(!VALID_AESCCM_ID(pState), ippStsContextMatchErr); + + /* test tag (pointer and length) */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((Ipp32u)tagLen>AESCCM_TAGLEN(pState) || tagLen<1, ippStsLengthErr); + + { + Ipp32u flag = (Ipp32u)( AESCCM_LENPRO(pState) &(MBS_RIJ128-1) ); + + Ipp32u MAC[NB(128)]; + CopyBlock16(AESCCM_MAC(pState), MAC); + + if(flag) { + IppsAESSpec* pAES = AESCCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + Ipp8u BLK[MBS_RIJ128]; + FillBlock16(0, NULL,BLK, 0); + CopyBlock(AESCCM_BLK(pState), BLK, (cpSize)flag); + + XorBlock16(MAC, BLK, MAC); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + + XorBlock(MAC, AESCCM_S0(pState), pTag, (cpSize)tagLen); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccminit.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccminit.c new file mode 100644 index 000000000..aaa4191ff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccminit.c @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsAES_CCMInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthccm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/*F* +// Name: ippsAES_CCMInit +// +// Purpose: Init AES-CCM state. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsMemAllocErr size of buffer is not match fro operation +// ippStsLengthErr keyLen != 16 && +// != 24 && +// != 32 +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length of secret key (in bytes) +// pState pointer to initialized as CCM context +// ctxSize available size (in bytes) of buffer above +// +*F*/ +IPPFUN(IppStatus, ippsAES_CCMInit,(const Ipp8u* pKey, int keyLen, + IppsAES_CCMState* pState, int ctxSize)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + + /* test available size of context buffer */ + IPP_BADARG_RET(ctxSize13), ippStsLengthErr); + + /* test AAD pointer if defined */ + IPP_BADARG_RET(adLen<0, ippStsLengthErr); + if(adLen) + IPP_BAD_PTR1_RET(pAD); + + /* init for new message */ + AESCCM_LENPRO(pState) = 0; + AESCCM_COUNTER(pState) = 0; + + { + /* setup encoder method */ + IppsAESSpec* pAES = AESCCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + Ipp32u MAC[NB(128)]; + Ipp32u CTR[NB(128)]; + Ipp32u block[2*NB(128)]; + + /* + // prepare the 1-st input block B0 and encode + */ + Ipp32u qLen = (Ipp32u)( (MBS_RIJ128-1) - ivLen); + Ipp32u qLenEnc = qLen-1; + + Ipp32u tagLenEnc = (AESCCM_TAGLEN(pState)-2)>>1; + + Ipp64u payloadLen = AESCCM_MSGLEN(pState); + + ((Ipp8u*)MAC)[0] = (Ipp8u)( (Ipp32u)((adLen!=0) <<6) + (tagLenEnc<<3) + qLenEnc); /* flags */ + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + MAC[2] = ENDIANNESS(IPP_HIDWORD(payloadLen)); + MAC[3] = ENDIANNESS(IPP_LODWORD(payloadLen)); + #else + MAC[2] = IPP_HIDWORD(payloadLen); + MAC[3] = IPP_LODWORD(payloadLen); + #endif + CopyBlock(pIV, ((Ipp8u*)MAC)+1, ivLen); + + /* setup CTR0 */ + FillBlock16(0, NULL,CTR, 0); + ((Ipp8u*)CTR)[0] = (Ipp8u)qLenEnc; /* flags */ + CopyBlock(pIV, ((Ipp8u*)CTR)+1, ivLen); + CopyBlock16(CTR, AESCCM_CTR0(pState)); + + /* compute and store S0=ENC(CTR0) */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)CTR, AESCCM_S0(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)CTR, AESCCM_S0(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + /* init MAC value MAC = ENC(MAC) */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + + /* + // update MAC by the AD + */ + if(adLen) { + /* encode length of associated data */ + Ipp32u adLenEnc[3]; + Ipp8u* adLenEncPtr; + int adLenEncSize; + + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + adLenEnc[1] = ENDIANNESS(IPP_HIDWORD(adLen)); + adLenEnc[2] = ENDIANNESS(IPP_LODWORD(adLen)); + #else + adLenEnc[1] = IPP_HIDWORD(adLen); + adLenEnc[2] = IPP_LODWORD(adLen); + #endif + + if(adLen >= 0xFF00) { + adLenEncSize = 6; + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + adLenEnc[1] = 0xFEFFFFFF; + #else + adLenEnc[1] = 0xFFFFFFFE; + #endif + } + else { + adLenEncSize= 2; + } + adLenEncPtr = (Ipp8u*)adLenEnc+3*sizeof(Ipp32u)-adLenEncSize; + + /* prepare first formatted block of Header */ + CopyBlock(adLenEncPtr, block, adLenEncSize); + FillBlock16(0,pAD, (Ipp8u*)block+adLenEncSize, IPP_MIN((MBS_RIJ128-adLenEncSize), adLen)); + + /* and update MAC */ + MAC[0] ^= block[0]; + MAC[1] ^= block[1]; + MAC[2] ^= block[2]; + MAC[3] ^= block[3]; + //encoder(MAC, MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + /* update MAC the by rest of addition data */ + if( (adLen+adLenEncSize) > MBS_RIJ128 ) { + pAD += (MBS_RIJ128-adLenEncSize); + adLen -= (MBS_RIJ128-adLenEncSize); + while(adLen >= MBS_RIJ128) { + CopyBlock16(pAD, block); + MAC[0] ^= block[0]; + MAC[1] ^= block[1]; + MAC[2] ^= block[2]; + MAC[3] ^= block[3]; + //encoder(MAC, MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + pAD += MBS_RIJ128; + adLen -= MBS_RIJ128; + } + + if(adLen) { + FillBlock16(0, pAD, block, (int)adLen); + MAC[0] ^= block[0]; + MAC[1] ^= block[1]; + MAC[2] ^= block[2]; + MAC[3] ^= block[3]; + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)MAC, (Ipp8u*)MAC, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + } + } + + AESCCM_COUNTER(pState) = 0; + CopyBlock16(MAC, AESCCM_MAC(pState)); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmtaglen.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmtaglen.c new file mode 100644 index 000000000..d5bffc0c0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ccmtaglen.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsAES_CCMTagLen() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthccm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/*F* +// Name: ippsAES_CCMTagLen +// +// Purpose: Setup length of the tag. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsContextMatchErr !VALID_AESCCM_ID() +// ippStsLengthErr MBS_RIJ128 < tagLen || tagLen < 4 +// or odd value of tagLen +// ippStsNoErr no errors +// +// Parameters: +// tagLen length in bytes of the requested tag +// pState pointer to the AES-CCM state +// +*F*/ +IPPFUN(IppStatus, ippsAES_CCMTagLen,(int tagLen, IppsAES_CCMState* pState)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!VALID_AESCCM_ID(pState), ippStsContextMatchErr); + + /* test tag length */ + IPP_BADARG_RET(tagLen>MBS_RIJ128 || tagLen<4 || tagLen&1, ippStsLengthErr); + + /* init for new message */ + AESCCM_TAGLEN(pState) = (Ipp32u)tagLen; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb128decrypt_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb128decrypt_vaes512.c new file mode 100644 index 000000000..901665fc3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb128decrypt_vaes512.c @@ -0,0 +1,173 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CFB mode) +// +// Contents: +// DecryptCFB128_RIJ128pipe_VAES_NI() +// +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" + +#if(_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // zmmintrin.h bug: truncation of constant value +#endif + +IPP_OWN_DEFN (void, DecryptCFB128_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, // pointer to the ciphertext + Ipp8u* pDst, // pointer to the plaintext + int len, // message length + const IppsAESSpec* pCtx, // pointer to context + const Ipp8u* pIV)) // pointer to the Initialization Vector +{ + int cipherRounds = RIJ_NR(pCtx) - 1; + + __m128i* pRkey = (__m128i*)RIJ_EKEYS(pCtx); + __m512i* pSrc512 = (__m512i*)pSrc; + __m512i* pDst512 = (__m512i*)pDst; + + // load IV (128-bit) + __m512i IV = _mm512_maskz_expandloadu_epi64(0xC0, pIV); // IV 0 0 0 + + int blocks; + for (blocks = len / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + // load ciphertext + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + __m512i blk3 = _mm512_loadu_si512(pSrc512 + 3); + + // prepare vectors for decryption + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); // C3 C2 C1 IV + __m512i z1 = _mm512_alignr_epi64(blk1, blk0, 6); // C7 C6 C5 C4 + __m512i z2 = _mm512_alignr_epi64(blk2, blk1, 6); // C11 C10 C9 C8 + __m512i z3 = _mm512_alignr_epi64(blk3, blk2, 6); // C15 C14 C13 C12 + + // update IV + IV = blk3; + + cpAESEncrypt4_VAES_NI(&z0, &z1, &z2, &z3, pRkey, cipherRounds); + + blk0 = _mm512_xor_si512(blk0, z0); + blk1 = _mm512_xor_si512(blk1, z1); + blk2 = _mm512_xor_si512(blk2, z2); + blk3 = _mm512_xor_si512(blk3, z3); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + _mm512_storeu_si512(pDst512 + 3, blk3); + + pSrc512 += 4; + pDst512 += 4; + } + + if ((3 * 4) <= blocks) { + // load ciphertext + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); + __m512i z1 = _mm512_alignr_epi64(blk1, blk0, 6); + __m512i z2 = _mm512_alignr_epi64(blk2, blk1, 6); + + // update IV + IV = blk2; + + cpAESEncrypt3_VAES_NI(&z0, &z1, &z2, pRkey, cipherRounds); + + blk0 = _mm512_xor_si512(blk0, z0); + blk1 = _mm512_xor_si512(blk1, z1); + blk2 = _mm512_xor_si512(blk2, z2); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + + pSrc512 += 3; + pDst512 += 3; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + // load ciphertext + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); + __m512i z1 = _mm512_alignr_epi64(blk1, blk0, 6); + + // update IV + IV = blk1; + + cpAESEncrypt2_VAES_NI(&z0, &z1, pRkey, cipherRounds); + + blk0 = _mm512_xor_si512(blk0, z0); + blk1 = _mm512_xor_si512(blk1, z1); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + + pSrc512 += 2; + pDst512 += 2; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + // load ciphertext + __m512i blk0 = _mm512_loadu_si512(pSrc512); + + __m512i z0 = _mm512_alignr_epi64(blk0, IV, 6); + + // update IV + IV = blk0; + + cpAESEncrypt1_VAES_NI(&z0, pRkey, cipherRounds); + + blk0 = _mm512_xor_si512(blk0, z0); + + _mm512_storeu_si512(pDst512, blk0); + + pSrc512 += 1; + pDst512 += 1; + } + + if (blocks) { + __mmask8 k = (__mmask8)((1 << (blocks + blocks)) - 1); + + __m512i blk0 = _mm512_maskz_loadu_epi64(k, pSrc512); + + __m512i z0 = _mm512_maskz_alignr_epi64(k, blk0, IV, 6); + + cpAESEncrypt1_VAES_NI(&z0, pRkey, cipherRounds); + + blk0 = _mm512_maskz_xor_epi64(k, blk0, z0); + + _mm512_mask_storeu_epi64(pDst512, k, blk0); + } +} + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb64decrypt_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb64decrypt_vaes512.c new file mode 100644 index 000000000..b71023411 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb64decrypt_vaes512.c @@ -0,0 +1,236 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CFB mode) +// +// Contents: +// DecryptCFB64_RIJ128pipe_VAES_NI() +// +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" + +#if(_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // zmmintrin.h bug: truncation of constant value +#endif + +IPP_OWN_DEFN (void, DecryptCFB64_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, // pointer to the ciphertext + Ipp8u* pDst, // pointer to the plaintext + int len, // message length + const IppsAESSpec* pCtx, // pointer to context + const Ipp8u* pIV)) // pointer to the Initialization Vector +{ + int cipherRounds = RIJ_NR(pCtx) - 1; + + __m128i* pRkey = (__m128i*)RIJ_EKEYS(pCtx); + __m256i* pSrc256 = (__m256i*)pSrc; + __m256i* pDst256 = (__m256i*)pDst; + + // load/store masks + __mmask8 k8_load = 0xAA; // 1010 1010 - load to high addresses of 128-bit lanes + __mmask8 k8_store = 0x55; // 0101 0101 - store low addresses of 128-bit lanes (MSB of OutputBlocks) + + // load IV and init IV vector in appropriate for further batch processing manner + __m128i IV128 = _mm_maskz_loadu_epi64(0x03, pIV); + // 64-bit values: IV_l IV_h IV_l IV_h 0 0 0 0 + __m512i IV = _mm512_maskz_broadcast_i64x2(0xF0, IV128); + // 64-bit values: IV_l IV_h IV_h IV_h 0 0 0 0 + IV = _mm512_maskz_permutex_epi64(0xF0, IV, 0xE1); // 0xE1 = 1110 0001 + + int blocks = len / (MBS_RIJ128 >> 1); + + for (; blocks >= (4 * 4); blocks -= (4 * 4)) { + // load 64-bit blocks of ciphertext to high part of 128-bit lanes + __m512i blk0 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256); // C3 0 C2 0 C1 0 C0 0 + __m512i blk1 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256 + 1); // C7 0 C6 0 C5 0 C4 0 + __m512i blk2 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256 + 2); + __m512i blk3 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256 + 3); + + // prepare vectors for decryption + __m512i z00 = _mm512_alignr_epi64(blk0, IV, 4); // C2 0 | C1 0 | IV_l IV_h | IV_h IV_l + __m512i z01 = _mm512_alignr_epi64(blk0, IV, 6); // C3 0 | C2 0 | C1 0 | IV_l IV_h + z00 = _mm512_unpackhi_epi64(z00, z01); // C3 C2 | C2 C1 | C1 IV_l | IV_l IV_h + + __m512i z10 = _mm512_alignr_epi64(blk1, blk0, 4); + __m512i z11 = _mm512_alignr_epi64(blk1, blk0, 6); + z10 = _mm512_unpackhi_epi64(z10, z11); + + __m512i z20 = _mm512_alignr_epi64(blk2, blk1, 4); + __m512i z21 = _mm512_alignr_epi64(blk2, blk1, 6); + z20 = _mm512_unpackhi_epi64(z20, z21); + + __m512i z30 = _mm512_alignr_epi64(blk3, blk2, 4); + __m512i z31 = _mm512_alignr_epi64(blk3, blk2, 6); + z30 = _mm512_unpackhi_epi64(z30, z31); + + // update IV + IV = blk3; + + cpAESEncrypt4_VAES_NI(&z00, &z10, &z20, &z30, pRkey, cipherRounds); + + // move cipher blocks to MSB part of 128-bit lanes + blk0 = _mm512_bsrli_epi128(blk0, 8); + blk1 = _mm512_bsrli_epi128(blk1, 8); + blk2 = _mm512_bsrli_epi128(blk2, 8); + blk3 = _mm512_bsrli_epi128(blk3, 8); + + blk0 = _mm512_xor_si512(blk0, z00); + blk1 = _mm512_xor_si512(blk1, z10); + blk2 = _mm512_xor_si512(blk2, z20); + blk3 = _mm512_xor_si512(blk3, z30); + + _mm512_mask_compressstoreu_epi64(pDst256, k8_store, blk0); + _mm512_mask_compressstoreu_epi64(pDst256 + 1, k8_store, blk1); + _mm512_mask_compressstoreu_epi64(pDst256 + 2, k8_store, blk2); + _mm512_mask_compressstoreu_epi64(pDst256 + 3, k8_store, blk3); + + pSrc256 += 4; + pDst256 += 4; + } + + if ((3 * 4) <= blocks) { + // load 64-bit blocks of ciphertext to high part of 128-bit lanes + __m512i blk0 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256); + __m512i blk1 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256 + 1); + __m512i blk2 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256 + 2); + + // prepare vectors for decryption + __m512i z00 = _mm512_alignr_epi64(blk0, IV, 4); + __m512i z01 = _mm512_alignr_epi64(blk0, IV, 6); + z00 = _mm512_unpackhi_epi64(z00, z01); + + __m512i z10 = _mm512_alignr_epi64(blk1, blk0, 4); + __m512i z11 = _mm512_alignr_epi64(blk1, blk0, 6); + z10 = _mm512_unpackhi_epi64(z10, z11); + + __m512i z20 = _mm512_alignr_epi64(blk2, blk1, 4); + __m512i z21 = _mm512_alignr_epi64(blk2, blk1, 6); + z20 = _mm512_unpackhi_epi64(z20, z21); + + // update IV + IV = blk2; + + cpAESEncrypt3_VAES_NI(&z00, &z10, &z20, pRkey, cipherRounds); + + // move cipher blocks to MSB part of 128-bit lanes + blk0 = _mm512_bsrli_epi128(blk0, 8); + blk1 = _mm512_bsrli_epi128(blk1, 8); + blk2 = _mm512_bsrli_epi128(blk2, 8); + + blk0 = _mm512_xor_si512(blk0, z00); + blk1 = _mm512_xor_si512(blk1, z10); + blk2 = _mm512_xor_si512(blk2, z20); + + _mm512_mask_compressstoreu_epi64(pDst256, k8_store, blk0); + _mm512_mask_compressstoreu_epi64(pDst256 + 1, k8_store, blk1); + _mm512_mask_compressstoreu_epi64(pDst256 + 2, k8_store, blk2); + + pSrc256 += 3; + pDst256 += 3; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + // load 64-bit blocks of ciphertext to high part of 128-bit lanes + __m512i blk0 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256); + __m512i blk1 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256 + 1); + + // prepare vectors for decryption + __m512i z00 = _mm512_alignr_epi64(blk0, IV, 4); + __m512i z01 = _mm512_alignr_epi64(blk0, IV, 6); + z00 = _mm512_unpackhi_epi64(z00, z01); + + __m512i z10 = _mm512_alignr_epi64(blk1, blk0, 4); + __m512i z11 = _mm512_alignr_epi64(blk1, blk0, 6); + z10 = _mm512_unpackhi_epi64(z10, z11); + + // update IV + IV = blk1; + + cpAESEncrypt2_VAES_NI(&z00, &z10, pRkey, cipherRounds); + + // move cipher blocks to MSB part of 128-bit lanes + blk0 = _mm512_bsrli_epi128(blk0, 8); + blk1 = _mm512_bsrli_epi128(blk1, 8); + + blk0 = _mm512_xor_si512(blk0, z00); + blk1 = _mm512_xor_si512(blk1, z10); + + _mm512_mask_compressstoreu_epi64(pDst256, k8_store, blk0); + _mm512_mask_compressstoreu_epi64(pDst256 + 1, k8_store, blk1); + + pSrc256 += 2; + pDst256 += 2; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + // load 64-bit blocks of ciphertext to high part of 128-bit lanes + __m512i blk0 = _mm512_maskz_expandloadu_epi64(k8_load, pSrc256); + + // prepare vectors for decryption + __m512i z00 = _mm512_alignr_epi64(blk0, IV, 4); + __m512i z01 = _mm512_alignr_epi64(blk0, IV, 6); + z00 = _mm512_unpackhi_epi64(z00, z01); + + // update IV + IV = blk0; + + cpAESEncrypt1_VAES_NI(&z00, pRkey, cipherRounds); + + // move cipher blocks to MSB part of 128-bit lanes + blk0 = _mm512_bsrli_epi128(blk0, 8); + + blk0 = _mm512_xor_si512(blk0, z00); + + _mm512_mask_compressstoreu_epi64(pDst256, k8_store, blk0); + + pSrc256 += 1; + pDst256 += 1; + } + + if (blocks) { + __mmask8 k = (__mmask8)((1 << (blocks + blocks)) - 1); // 64-bit chunks + + // load 64-bit blocks of ciphertext to hi part of 128-bit lanes + __m512i blk0 = _mm512_maskz_expandloadu_epi64(k & k8_load, pSrc256); + + // prepare vectors for decryption + __m512i z00 = _mm512_alignr_epi64(blk0, IV, 4); + __m512i z01 = _mm512_alignr_epi64(blk0, IV, 6); + z00 = _mm512_maskz_unpackhi_epi64(k, z00, z01); + + cpAESEncrypt1_VAES_NI(&z00, pRkey, cipherRounds); + + // move cipher blocks to MSB part of 128-bit lanes + blk0 = _mm512_bsrli_epi128(blk0, 8); + + blk0 = _mm512_xor_epi64(blk0, z00); + + _mm512_mask_compressstoreu_epi64(pDst256, k & k8_store, blk0); + } +} + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb_mb_encrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb_mb_encrypt.c new file mode 100644 index 000000000..346e44fad --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfb_mb_encrypt.c @@ -0,0 +1,234 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES Multi Buffer Encryption (CFB mode) +// +// Contents: +// ippsAES_EncryptCFB16_MB() +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "aes_cfb_vaes_mb.h" +#include "aes_cfb_aesni_mb.h" + + +/*! + * \brief ippsAES_EncryptCFB16_MB + * + * Name: ippsAES_EncryptCFB16_MB + * + * Purpose: AES-CFB16 Multi Buffer Encryption + * + * Parameters: + * \param[in] pSrc Pointer to the array of source data + * \param[out] pDst Pointer to the array of target data + * \param[in] len Pointer to the array of input buffer lengths (in bytes) + * \param[in] pCtx Pointer to the array of AES contexts + * \param[in] pIV Pointer to the array of initialization vectors (IV) + * \param[out] status Pointer to the IppStatus array that contains status + * for each processed buffer in encryption operation + * \param[in] numBuffers Number of buffers to be processed + * + * Returns: Reason: + * \return ippStsNullPtrErr Indicates an error condition if any of the specified pointers is NULL: + * NULL == pSrc + * NULL == pDst + * NULL == len + * NULL == pCtx + * NULL == pIV + * NULL == status + * \return ippStsContextMatchErr Indicates an error condition if input buffers have different key sizes + * \return ippStsLengthErr Indicates an error condition if numBuffers < 1 + * \return ippStsErr One or more of performed operation executed with error + * Check status array for details + * \return ippStsNoErr No error + */ + +/* Work Load Size from Buffers */ +#define WORKLOAD_LINES_16 (AES_MB_MAX_KERNEL_SIZE) /* size 16 */ +#define WORKLOAD_LINES_8 (AES_MB_MAX_KERNEL_SIZE / 2) /* size 8 */ +#define WORKLOAD_LINES_4 (AES_MB_MAX_KERNEL_SIZE / 4) /* size 4 */ + + +IPPFUN(IppStatus, ippsAES_EncryptCFB16_MB, (const Ipp8u* pSrc[], Ipp8u* pDst[], int len[], const IppsAESSpec* pCtx[], + const Ipp8u* pIV[], IppStatus status[], int numBuffers)) +{ + int i; + + // Check input pointers + IPP_BAD_PTR2_RET(pCtx, pIV); + IPP_BAD_PTR4_RET(pSrc, pDst, len, status); + + // Check number of buffers to be processed + IPP_BADARG_RET((numBuffers < 1), ippStsLengthErr); + + // Sequential check of all input buffers + int isAllBuffersValid = 1; + for (i = 0; i < numBuffers; i++) { + // Test source, target buffers and initialization pointers + if (pSrc[i] == NULL || pDst[i] == NULL || pIV[i] == NULL || pCtx[i] == NULL) { + status[i] = ippStsNullPtrErr; + isAllBuffersValid = 0; + continue; + } + + // Test the context ID + if(!VALID_AES_ID(pCtx[i])) { + status[i] = ippStsContextMatchErr; + isAllBuffersValid = 0; + continue; + } + + // Test stream length + if (len[i] < 1) { + status[i] = ippStsLengthErr; + isAllBuffersValid = 0; + continue; + } + + // Test stream integrity + if ((len[i] % CFB16_BLOCK_SIZE)) { + status[i] = ippStsUnderRunErr; + isAllBuffersValid = 0; + continue; + } + + status[i] = ippStsNoErr; + } + + // If any of the input buffer is not valid stop the processig + IPP_BADARG_RET(!isAllBuffersValid, ippStsErr) + + // Check compatibility of the keys + int referenceKeySize = RIJ_NK(pCtx[0]); + for (i = 0; i < numBuffers; i++) { + IPP_BADARG_RET((RIJ_NK(pCtx[i]) != referenceKeySize), ippStsContextMatchErr); + } + + #if (_IPP32E>=_IPP32E_Y8) + Ipp32u const* loc_enc_keys[AES_MB_MAX_KERNEL_SIZE]; + Ipp8u const* loc_src[AES_MB_MAX_KERNEL_SIZE]; + Ipp8u* loc_dst[AES_MB_MAX_KERNEL_SIZE]; + Ipp8u const* loc_iv[AES_MB_MAX_KERNEL_SIZE]; + int loc_len[AES_MB_MAX_KERNEL_SIZE]; + int buffersProcessed = 0; + int numRounds = 0; + #endif + + #if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + int workLoadSize = 0; + while(numBuffers > 0) { + /* init work load size */ + if (numBuffers > WORKLOAD_LINES_8) { /* size 16 */ + workLoadSize = WORKLOAD_LINES_16; + } else if (numBuffers > WORKLOAD_LINES_4 && numBuffers <= WORKLOAD_LINES_8) { /* size 8 */ + workLoadSize = WORKLOAD_LINES_8; + } else if (numBuffers > 0 && numBuffers <= WORKLOAD_LINES_4) { /* size 4 */ + workLoadSize = WORKLOAD_LINES_4; + } else { + break; + } + + /* fill buffers */ + for (i = 0; i < workLoadSize; i++) { + if (i >= numBuffers) { + loc_len[i] = 0; + continue; + } + + loc_src[i] = pSrc[i + buffersProcessed]; + loc_dst[i] = pDst[i + buffersProcessed]; + loc_iv[i] = pIV[i + buffersProcessed]; + loc_enc_keys[i] = (Ipp32u*)RIJ_EKEYS(pCtx[i + buffersProcessed]); + loc_len[i] = len[i + buffersProcessed]; + /* As numRounds is the same for all buffers, get it from the last one */ + numRounds = RIJ_NR(pCtx[i + buffersProcessed]); + } + + /* choosing a core for filled buffers */ + switch (workLoadSize) { + case WORKLOAD_LINES_16: { + aes_cfb16_enc_vaes_mb16(loc_src, loc_dst, loc_len, numRounds, loc_enc_keys, loc_iv); + break; + } + case WORKLOAD_LINES_8: { + aes_cfb16_enc_vaes_mb8(loc_src, loc_dst, loc_len, numRounds, loc_enc_keys, loc_iv); + break; + } + case WORKLOAD_LINES_4: { + aes_cfb16_enc_vaes_mb4(loc_src, loc_dst, loc_len, numRounds, loc_enc_keys, loc_iv); + break; + } + default: + break; + } + + /* changing the remaining buffers for processing */ + numBuffers -= workLoadSize; + buffersProcessed += workLoadSize; + } + } + #endif // if(_IPP32E>=_IPP32E_K1) + + #if (_IPP32E>=_IPP32E_Y8) + if( IsFeatureEnabled(ippCPUID_AES) ) { + while(numBuffers > 0) { + for (i = 0; i < WORKLOAD_LINES_4; i++) { + if (i >= numBuffers) { + loc_len[i] = 0; + continue; + } + + loc_src[i] = pSrc[i + buffersProcessed]; + loc_dst[i] = pDst[i + buffersProcessed]; + loc_iv[i] = pIV[i + buffersProcessed]; + loc_enc_keys[i] = (Ipp32u*)RIJ_EKEYS(pCtx[i + buffersProcessed]); + loc_len[i] = len[i + buffersProcessed]; + /* As numRounds is the same for all buffers, get it from the last one */ + numRounds = RIJ_NR(pCtx[i + buffersProcessed]); + } + + aes_cfb16_enc_aesni_mb4(loc_src, loc_dst, loc_len, numRounds, loc_enc_keys, loc_iv); + numBuffers -= WORKLOAD_LINES_4; + buffersProcessed += WORKLOAD_LINES_4; + } + } + #endif // (_IPP32E>=_IPP32E_Y8) + + for (i = 0; i < numBuffers; i++) { + status[i] = ippsAESEncryptCFB(pSrc[i], pDst[i], len[i], CFB16_BLOCK_SIZE, pCtx[i], pIV[i]); + } + + for (i = 0; i < numBuffers; i++) { + if (status[i] != ippStsNoErr) { + return ippStsErr; + } + } + + return ippStsNoErr; +} + +#undef WORKLOAD_LINES_16 +#undef WORKLOAD_LINES_8 +#undef WORKLOAD_LINES_4 diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfbdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfbdecrypt.c new file mode 100644 index 000000000..ba7fcd43e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfbdecrypt.c @@ -0,0 +1,180 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CFB mode) +// +// Contents: +// ippsAESDecryptCFB() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + + + +/*F* +// Name: ippsAESDecryptCFB +// +// Purpose: AES-CFB decryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsCFBSizeErr (1>cfbBlkSize || cfbBlkSize>MBS_RIJ128) +// ippStsUnderRunErr 0!=(dataLen%cfbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len output buffer length (in bytes) +// cfbBlkSize CFB block size (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +// +*F*/ +static +void cpDecryptAES_cfb(const Ipp8u* pIV, + const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, int cfbBlkSize, + const IppsAESSpec* pCtx) +{ +#if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + if(cfbBlkSize==MBS_RIJ128) + DecryptCFB128_RIJ128pipe_VAES_NI(pSrc, pDst, nBlocks*cfbBlkSize, pCtx, pIV); + else if (8 == cfbBlkSize) + DecryptCFB64_RIJ128pipe_VAES_NI(pSrc, pDst, nBlocks*cfbBlkSize, pCtx, pIV); + else + #if !defined (__INTEL_COMPILER) && defined (_MSC_VER) && (_MSC_VER < 1920) + goto msvc_fallback; + #else + DecryptCFB_RIJ128pipe_VAES_NI(pSrc, pDst, nBlocks*cfbBlkSize, cfbBlkSize, pCtx, pIV); + #endif + } + else +#endif +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use pipelined version is possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + #if !defined (__INTEL_COMPILER) && defined (_MSC_VER) && (_MSC_VER < 1920) && (_IPP32E>=_IPP32E_K1) +msvc_fallback: + #endif + if(cfbBlkSize==MBS_RIJ128) + DecryptCFB128_RIJ128pipe_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), nBlocks*cfbBlkSize, pIV); + else if(0==(cfbBlkSize&3)) + DecryptCFB32_RIJ128pipe_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), nBlocks, cfbBlkSize, pIV); + else + DecryptCFB_RIJ128pipe_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), nBlocks, cfbBlkSize, pIV); + } + else +#endif + { + Ipp32u tmpInp[2*NB(128)]; + Ipp32u tmpOut[ NB(128)]; + + /* setup encoder method */ + RijnCipher encoder = RIJ_ENCODER(pCtx); + + /* read IV */ + CopyBlock16(pIV, tmpInp); + + /* decrypt data block-by-block of cfbLen each */ + while(nBlocks) { + /* decryption */ + //encoder(tmpInp, tmpOut, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)tmpInp, (Ipp8u*)tmpOut, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)tmpInp, (Ipp8u*)tmpOut, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), NULL); + #endif + + /* store output and put feedback into the input buffer (tmpInp) */ + if( cfbBlkSize==MBS_RIJ128 && pSrc!=pDst) { + ((Ipp32u*)pDst)[0] = tmpOut[0]^((Ipp32u*)pSrc)[0]; + ((Ipp32u*)pDst)[1] = tmpOut[1]^((Ipp32u*)pSrc)[1]; + ((Ipp32u*)pDst)[2] = tmpOut[2]^((Ipp32u*)pSrc)[2]; + ((Ipp32u*)pDst)[3] = tmpOut[3]^((Ipp32u*)pSrc)[3]; + + tmpInp[0] = ((Ipp32u*)pSrc)[0]; + tmpInp[1] = ((Ipp32u*)pSrc)[1]; + tmpInp[2] = ((Ipp32u*)pSrc)[2]; + tmpInp[3] = ((Ipp32u*)pSrc)[3]; + } + else { + int n; + for(n=0; ncfbBlkSize) || (MBS_RIJ128= 1920) + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" + +#if(_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // zmmintrin.h bug: truncation of constant value +#endif + +__INLINE Ipp64u broadcast_16to64(Ipp16u mask16) +{ + Ipp64u mask64 = (Ipp64u)mask16; + mask64 = (mask64 << 48) | (mask64 << 32) | (mask64 << 16) | mask64; + return mask64; +} + +__INLINE __m512i getInputBlocks(__m128i * const currentState, const __m512i * const pCipherBlocks, __mmask16 blocksCompressMask) +{ + // extract 128-bit cipher blocks + __m128i c0 = _mm512_extracti64x2_epi64(*pCipherBlocks, 0); + __m128i c1 = _mm512_extracti64x2_epi64(*pCipherBlocks, 1); + __m128i c2 = _mm512_extracti64x2_epi64(*pCipherBlocks, 2); + __m128i c3 = _mm512_extracti64x2_epi64(*pCipherBlocks, 3); + + // InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit + __m128i inpBlk0 = *currentState; + // drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits + __m128i inpBlk1 = _mm_mask_compress_epi8(c0, blocksCompressMask, inpBlk0); + __m128i inpBlk2 = _mm_mask_compress_epi8(c1, blocksCompressMask, inpBlk1); + __m128i inpBlk3 = _mm_mask_compress_epi8(c2, blocksCompressMask, inpBlk2); + + // next InputBlock ready + *currentState = _mm_mask_compress_epi8(c3, blocksCompressMask, inpBlk3); + + // inserts + __m512i inpBlk512 = _mm512_setzero_si512(); + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0x03, inpBlk0); // 0000 0011 + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0x0C, inpBlk1); // 0000 1100 + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0x30, inpBlk2); // 0011 0000 + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0xC0, inpBlk3); // 1100 0000 + + return inpBlk512; +} + +//////////////////////////////////////////////////////////////////////////////// +IPP_OWN_DEFN (void, DecryptCFB_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, // pointer to the ciphertext + Ipp8u* pDst, // pointer to the plaintext + int len, // message length + int cfbBlkSize, // CFB block size in bytes (1 <= cfbBlkSize <= 16)); s = 8*cfbBlkSize + const IppsAESSpec* pCtx, // pointer to context + const Ipp8u* pIV)) // pointer to the Initialization Vector +{ + const int cipherRounds = RIJ_NR(pCtx) - 1; + + __m128i* pRkey = (__m128i*)RIJ_EKEYS(pCtx); + Ipp8u* pSrc8 = (Ipp8u*)pSrc; + Ipp8u* pDst8 = (Ipp8u*)pDst; + + const int bytesPerLoad512 = 4 * cfbBlkSize; + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + // load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register + __mmask64 kLsbMask64 = (__mmask64)broadcast_16to64((Ipp16u)(0xFFFF << (16-cfbBlkSize))); + // same mask to load in MSB parts + __mmask64 kMsbMask64 = (__mmask64)broadcast_16to64(~blocksCompressMask); + + // load IV + __m128i IV128 = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + __m128i currentState = IV128; + + int blocks; + for (blocks = len / cfbBlkSize; blocks >= (4 * 4); blocks -= (4 * 4)) { + // load cipher blocks to LSB parts of registers + __m512i ciphLsb0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8); + __m512i ciphLsb1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8 + 1 * bytesPerLoad512); + __m512i ciphLsb2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8 + 2 * bytesPerLoad512); + __m512i ciphLsb3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8 + 3 * bytesPerLoad512); + + // load same cipher blocks to MSB parts of registers (shall be taken from cache) + __m512i ciphMsb0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8); + __m512i ciphMsb1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8 + 1 * bytesPerLoad512); + __m512i ciphMsb2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8 + 2 * bytesPerLoad512); + __m512i ciphMsb3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8 + 3 * bytesPerLoad512); + + // prepare InputBlocks for decryption + __m512i inpBlk0 = getInputBlocks(¤tState, &ciphLsb0, blocksCompressMask); + __m512i inpBlk1 = getInputBlocks(¤tState, &ciphLsb1, blocksCompressMask); + __m512i inpBlk2 = getInputBlocks(¤tState, &ciphLsb2, blocksCompressMask); + __m512i inpBlk3 = getInputBlocks(¤tState, &ciphLsb3, blocksCompressMask); + + cpAESEncrypt4_VAES_NI(&inpBlk0, &inpBlk1, &inpBlk2, &inpBlk3, pRkey, cipherRounds); + + ciphLsb0 = _mm512_xor_si512(ciphMsb0, inpBlk0); + ciphLsb1 = _mm512_xor_si512(ciphMsb1, inpBlk1); + ciphLsb2 = _mm512_xor_si512(ciphMsb2, inpBlk2); + ciphLsb3 = _mm512_xor_si512(ciphMsb3, inpBlk3); + + _mm512_mask_compressstoreu_epi8(pDst8, kMsbMask64, ciphLsb0); + _mm512_mask_compressstoreu_epi8(pDst8 + 1 * bytesPerLoad512, kMsbMask64, ciphLsb1); + _mm512_mask_compressstoreu_epi8(pDst8 + 2 * bytesPerLoad512, kMsbMask64, ciphLsb2); + _mm512_mask_compressstoreu_epi8(pDst8 + 3 * bytesPerLoad512, kMsbMask64, ciphLsb3); + + pSrc8 += 4 * bytesPerLoad512; + pDst8 += 4 * bytesPerLoad512; + } + + if ((3 * 4) <= blocks) { + // load ciphertext + __m512i ciphLsb0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8); + __m512i ciphLsb1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8 + 1 * bytesPerLoad512); + __m512i ciphLsb2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8 + 2 * bytesPerLoad512); + + __m512i ciphMsb0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8); + __m512i ciphMsb1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8 + 1 * bytesPerLoad512); + __m512i ciphMsb2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8 + 2 * bytesPerLoad512); + + // prepare InputBlocks for decryption + __m512i inpBlk0 = getInputBlocks(¤tState, &ciphLsb0, blocksCompressMask); + __m512i inpBlk1 = getInputBlocks(¤tState, &ciphLsb1, blocksCompressMask); + __m512i inpBlk2 = getInputBlocks(¤tState, &ciphLsb2, blocksCompressMask); + + cpAESEncrypt3_VAES_NI(&inpBlk0, &inpBlk1, &inpBlk2, pRkey, cipherRounds); + + ciphLsb0 = _mm512_xor_si512(ciphMsb0, inpBlk0); + ciphLsb1 = _mm512_xor_si512(ciphMsb1, inpBlk1); + ciphLsb2 = _mm512_xor_si512(ciphMsb2, inpBlk2); + + _mm512_mask_compressstoreu_epi8(pDst8, kMsbMask64, ciphLsb0); + _mm512_mask_compressstoreu_epi8(pDst8 + 1 * bytesPerLoad512, kMsbMask64, ciphLsb1); + _mm512_mask_compressstoreu_epi8(pDst8 + 2 * bytesPerLoad512, kMsbMask64, ciphLsb2); + + pSrc8 += 3 * bytesPerLoad512; + pDst8 += 3 * bytesPerLoad512; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + // load ciphertext + __m512i ciphLsb0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8); + __m512i ciphLsb1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8 + 1 * bytesPerLoad512); + + __m512i ciphMsb0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8); + __m512i ciphMsb1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8 + 1 * bytesPerLoad512); + + // prepare InputBlocks for decryption + __m512i inpBlk0 = getInputBlocks(¤tState, &ciphLsb0, blocksCompressMask); + __m512i inpBlk1 = getInputBlocks(¤tState, &ciphLsb1, blocksCompressMask); + + cpAESEncrypt2_VAES_NI(&inpBlk0, &inpBlk1, pRkey, cipherRounds); + + ciphLsb0 = _mm512_xor_si512(ciphMsb0, inpBlk0); + ciphLsb1 = _mm512_xor_si512(ciphMsb1, inpBlk1); + + _mm512_mask_compressstoreu_epi8(pDst8, kMsbMask64, ciphLsb0); + _mm512_mask_compressstoreu_epi8(pDst8 + 1 * bytesPerLoad512, kMsbMask64, ciphLsb1); + + pSrc8 += 2 * bytesPerLoad512; + pDst8 += 2 * bytesPerLoad512; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + // load ciphertext + __m512i ciphLsb0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc8); + __m512i ciphMsb0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc8); + + // prepare InputBlocks for decryption + __m512i inpBlk0 = getInputBlocks(¤tState, &ciphLsb0, blocksCompressMask); + + cpAESEncrypt1_VAES_NI(&inpBlk0, pRkey, cipherRounds); + + ciphLsb0 = _mm512_xor_si512(ciphMsb0, inpBlk0); + + _mm512_mask_compressstoreu_epi8(pDst8, kMsbMask64, ciphLsb0); + + pSrc8 += bytesPerLoad512; + pDst8 += bytesPerLoad512; + } + + // at least one block left (max 3 blocks) + if (blocks) { + __mmask64 k64 = (1LL << (blocks << 4)) - 1; + + // load ciphertext + __m512i ciphLsb0 = _mm512_maskz_expandloadu_epi8(k64 & kLsbMask64, pSrc8); + __m512i ciphMsb0 = _mm512_maskz_expandloadu_epi8(k64 & kMsbMask64, pSrc8); + + // prepare InputBlocks for decryption + __m512i inpBlk0 = _mm512_setzero_si512(); + inpBlk0 = _mm512_mask_broadcast_i64x2(inpBlk0, 0x03, currentState); + __m128i c; + for (int i = 0; i < blocks; i++) { + // NB: we cannot provide non-immediate parameter to extract function + switch (i) { + case 0: c = _mm512_extracti64x2_epi64(ciphLsb0, 0); break; + case 1: c = _mm512_extracti64x2_epi64(ciphLsb0, 1); break; + default: c = _mm512_extracti64x2_epi64(ciphLsb0, 2); + } + currentState = _mm_mask_compress_epi8(c, blocksCompressMask, currentState); + inpBlk0 = _mm512_mask_broadcast_i64x2(inpBlk0, (__mmask8)(0x03 << ((i + 1) << 1)), currentState); + } + + cpAESEncrypt1_VAES_NI(&inpBlk0, pRkey, cipherRounds); + + ciphLsb0 = _mm512_xor_si512(ciphMsb0, inpBlk0); + + _mm512_mask_compressstoreu_epi8(pDst8, k64 & kMsbMask64, ciphLsb0); + } +} + +#endif /* _IPP32E>=_IPP32E_K1 */ +#else +typedef int to_avoid_translation_unit_is_empty_warning; +#endif /* #if defined (__INTEL_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfbencrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfbencrypt.c new file mode 100644 index 000000000..e36fe7d4b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cfbencrypt.c @@ -0,0 +1,144 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CFB mode) +// +// Contents: +// ippsAESEncryptCFB() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + + +/*F* +// Name: ippsAESEncryptCFB +// +// Purpose: AES-CFB encryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsCFBSizeErr (1>cfbBlkSize || cfbBlkSize>MBS_RIJ128) +// ippStsUnderRunErr 0!=(dataLen%cfbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input buffer length (in bytes) +// cfbBlkSize CFB block size (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +// +*F*/ +IPPFUN(IppStatus, ippsAESEncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsAESSpec* pCtx, + const Ipp8u* pIV)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test source, target buffers and initialization pointers */ + IPP_BAD_PTR3_RET(pSrc, pIV, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test CFB value */ + IPP_BADARG_RET(((1>cfbBlkSize) || (MBS_RIJ128=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use pipelined version is possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + if(cfbBlkSize==MBS_RIJ128) + EncryptCFB128_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), len, pIV); + else if(0==(cfbBlkSize&3)) + EncryptCFB32_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), len, cfbBlkSize, pIV); + else + EncryptCFB_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), len, cfbBlkSize, pIV); + return ippStsNoErr; + } + else +#endif + + { + Ipp32u tmpInp[2*NB(128)]; + Ipp32u tmpOut[ NB(128)]; + + /* setup encoder method */ + RijnCipher encoder = RIJ_ENCODER(pCtx); + + /* read IV */ + CopyBlock16(pIV, tmpInp); + + /* encrypt data block-by-block of cfbLen each */ + while(len>=cfbBlkSize) { + int n; + + /* encryption */ + //encoder(tmpInp, tmpOut, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)tmpInp, (Ipp8u*)tmpOut, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)tmpInp, (Ipp8u*)tmpOut, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), NULL); + #endif + + /* store output and put feedback into the input buffer (tmpInp) */ + if( cfbBlkSize==MBS_RIJ128 && pSrc!=pDst) { + tmpInp[0] = ((Ipp32u*)pDst)[0] = tmpOut[0]^((Ipp32u*)pSrc)[0]; + tmpInp[1] = ((Ipp32u*)pDst)[1] = tmpOut[1]^((Ipp32u*)pSrc)[1]; + tmpInp[2] = ((Ipp32u*)pDst)[2] = tmpOut[2]^((Ipp32u*)pSrc)[2]; + tmpInp[3] = ((Ipp32u*)pDst)[3] = tmpOut[3]^((Ipp32u*)pSrc)[3]; + } + else { + for(n=0; n>8) & 0xFF; + } +} + + +/*F* +// Name: ippsAES_CMACInit +// +// Purpose: Init AES-CMAC context. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsMemAllocErr size of buffer is not match fro operation +// ippStsLengthErr keyLen != 16 +// keyLen != 24 +// keyLen != 32 +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length of secret key +// pState pointer to the CMAC context +// ctxSize available size (in bytes) of buffer above +// +*F*/ +IPPFUN(IppStatus, ippsAES_CMACInit,(const Ipp8u* pKey, int keyLen, IppsAES_CMACState* pState, int ctxSize)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + + /* test available size of context buffer */ + IPP_BADARG_RET(ctxSize>7)) & 0x87); /* ^ Rb changed for constant time execution */ + /* precompute k2 subkey */ + msb = (CMAC_K1(pState))[0]; + LogicalLeftSift16(CMAC_K1(pState),CMAC_K2(pState)); + (CMAC_K2(pState))[MBS_RIJ128-1] ^= (Ipp8u)((0-(msb>>7)) & 0x87); /* ^ Rb changed for constant time execution */ + } + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_cmacupdate.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cmacupdate.c new file mode 100644 index 000000000..549f7b153 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_cmacupdate.c @@ -0,0 +1,198 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-CMAC Functions +// +// Contents: +// ippsAES_CMACUpdate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpcmac.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + + +/*F* +// Name: ippsAES_CMACUpdate +// +// Purpose: Updates intermadiate digest based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr !VALID_AESCMAC_ID() +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the CMAC context +// +*F*/ +static void AES_CMAC_processing(Ipp8u* pDigest, const Ipp8u* pSrc, int processedLen, const IppsAESSpec* pAES) +{ +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pAES)) { + cpAESCMAC_Update_AES_NI(pDigest, pSrc, processedLen, RIJ_NR(pAES), RIJ_EKEYS(pAES)); + } + else +#endif + { + /* setup encoder method */ + RijnCipher encoder = RIJ_ENCODER(pAES); + + while(processedLen) { + ((Ipp32u*)pDigest)[0] ^= ((Ipp32u*)pSrc)[0]; + ((Ipp32u*)pDigest)[1] ^= ((Ipp32u*)pSrc)[1]; + ((Ipp32u*)pDigest)[2] ^= ((Ipp32u*)pSrc)[2]; + ((Ipp32u*)pDigest)[3] ^= ((Ipp32u*)pSrc)[3]; + + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pDigest, pDigest, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(pDigest, pDigest, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + pSrc += MBS_RIJ128; + processedLen -= MBS_RIJ128; + } + } +} + +IPPFUN(IppStatus, ippsAES_CMACUpdate,(const Ipp8u* pSrc, int len, IppsAES_CMACState* pState)) +{ + int processedLen; + + /* test context pointer */ + IPP_BAD_PTR1_RET(pState); + /* test ID */ + IPP_BADARG_RET(!VALID_AESCMAC_ID(pState), ippStsContextMatchErr); + /* test input message and it's length */ + IPP_BADARG_RET((len<0 && pSrc), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + if(!len) + return ippStsNoErr; + + { + /* + // test internal buffer filling + */ + if(CMAC_INDX(pState)) { + /* copy from input stream to the internal buffer as match as possible */ + processedLen = IPP_MIN(len, (MBS_RIJ128 - CMAC_INDX(pState))); + CopyBlock(pSrc, CMAC_BUFF(pState)+CMAC_INDX(pState), processedLen); + + /* internal buffer filling */ + CMAC_INDX(pState) += processedLen; + + /* update message pointer and length */ + pSrc += processedLen; + len -= processedLen; + + if(!len) + return ippStsNoErr; + + /* update CMAC if buffer full but not the last */ + if(MBS_RIJ128==CMAC_INDX(pState) ) { + const IppsAESSpec* pAES = &CMAC_CIPHER(pState); + /* setup encoder method */ + RijnCipher encoder = RIJ_ENCODER(pAES); + XorBlock16(CMAC_BUFF(pState), CMAC_MAC(pState), CMAC_MAC(pState)); + + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(CMAC_MAC(pState), CMAC_MAC(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(CMAC_MAC(pState), CMAC_MAC(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + + CMAC_INDX(pState) = 0; + } + } + + /* + // main part + */ + + processedLen = len & ~(MBS_RIJ128-1); + if(!(len & (MBS_RIJ128-1))) + processedLen -= MBS_RIJ128; + if (processedLen) { + const IppsAESSpec *pAES = &CMAC_CIPHER(pState); + +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* Mistletoe3 mitigation */ + cpAESNoiseParams *params = (cpAESNoiseParams *)&AESCMAC_NOISE_PARAMS(pState); + if (AES_NOISE_LEVEL(params) > 0) { + /* Number of bytes allowed for operation without adding noise */ + int chunk_size; + /* Number of bytes remaining for operation */ + int remaining_size = processedLen; + + while (remaining_size > 0) { + /* How many bytes to encrypt in this operation */ + chunk_size = (remaining_size >= MISTLETOE3_MAX_CHUNK_SIZE) ? MISTLETOE3_MAX_CHUNK_SIZE : remaining_size; + + AES_CMAC_processing(CMAC_MAC(pState), pSrc, chunk_size, pAES); + + cpAESRandomNoise(NULL, + MISTLETOE3_BASE_NOISE_LEVEL + AES_NOISE_LEVEL(params), + MISTLETOE3_NOISE_RATE, + &AES_NOISE_RAND(params)); + + pSrc += chunk_size; + remaining_size -= chunk_size; + } + } else +#endif + { + AES_CMAC_processing(CMAC_MAC(pState), pSrc, processedLen, pAES); + /* update message pointer and length */ + pSrc += processedLen; + } + + len -= processedLen; + } + + /* + // remaind + */ + if(len) { + /* workaround to avoid false positive stringop-overflow error on gcc10.1 and gcc11.1 */ + len = ( IPP_MIN(len, MBS_RIJ128) ); + + CopyBlock(pSrc, (Ipp8u*)(&CMAC_BUFF(pState)), len); + /* update internal buffer filling */ + CMAC_INDX(pState) += len; + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctr_process.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctr_process.h new file mode 100644 index 000000000..62aa1f68c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctr_process.h @@ -0,0 +1,255 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CTR mode) +// +// Contents: +// cpProcessAES_ctr() +// cpProcessAES_ctr128() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/* +// AES-CRT processing. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pCtrValue ==NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsCTRSizeErr 128 < ctrNumBitSize < 1 +// ippStsCTRSizeErr data blocks number > 2^ctrNumBitSize +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// dataLen input/output buffer length (in bytes) +// pCtx pointer to rge AES context +// pCtrValue pointer to the counter block +// ctrNumBitSize counter block size (bits) +// +// Note: +// counter will updated on return +// +*/ +__INLINE void MaskCounter128(Ipp8u* pMaskIV, int ctrBtSize) +{ + /* construct ctr mask */ + int maskPosition = (MBS_RIJ128*8-ctrBtSize)/8; + Ipp8u maskValue = (Ipp8u)(0xFF >> (MBS_RIJ128*8-ctrBtSize)%8 ); + + //Ipp8u maskIV[MBS_RIJ128]; + int n; + for(n=0; n= 8 * sizeof(int) - 5 + // function can process data with any possible + // passed dataLen without counter overflow + */ + + int dataBlocksNum = dataLen >> 4; + if(dataLen & 15){ + dataBlocksNum++; + } + + IPP_BADARG_RET(dataBlocksNum > (1 << ctrNumBitSize), ippStsCTRSizeErr); + } + + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use pipelined version if possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + /* construct ctr mask */ + Ipp8u maskIV[MBS_RIJ128]; + MaskCounter128(maskIV, ctrNumBitSize); /* const-exe-time version */ + +#if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + EncryptCTR_RIJ128pipe_VAES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), dataLen, pCtrValue, maskIV); + } + else +#endif + { + EncryptCTR_RIJ128pipe_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), dataLen, pCtrValue, maskIV); + } + return ippStsNoErr; + } + else + #endif + { + Ipp32u counter[NB(128)]; + Ipp32u output[NB(128)]; + + /* setup encoder method */ + RijnCipher encoder = RIJ_ENCODER(pCtx); + + /* copy counter */ + CopyBlock16(pCtrValue, counter); + + /* + // encrypt block-by-block aligned streams + */ + while(dataLen>= MBS_RIJ128) { + /* encrypt counter block */ + //encoder(counter, output, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)counter, (Ipp8u*)output, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)counter, (Ipp8u*)output, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), NULL); + #endif + + /* compute ciphertext block */ + if( !(IPP_UINT_PTR(pSrc) & 0x3) && !(IPP_UINT_PTR(pDst) & 0x3)) { + ((Ipp32u*)pDst)[0] = output[0]^((Ipp32u*)pSrc)[0]; + ((Ipp32u*)pDst)[1] = output[1]^((Ipp32u*)pSrc)[1]; + ((Ipp32u*)pDst)[2] = output[2]^((Ipp32u*)pSrc)[2]; + ((Ipp32u*)pDst)[3] = output[3]^((Ipp32u*)pSrc)[3]; + } + else + XorBlock16(pSrc, output, pDst); + /* encrement counter block */ + StdIncrement((Ipp8u*)counter,MBS_RIJ128*8, ctrNumBitSize); + + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + dataLen -= MBS_RIJ128; + } + /* + // encrypt last data block + */ + if(dataLen) { + /* encrypt counter block */ + //encoder(counter, output, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)counter, (Ipp8u*)output, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)counter, (Ipp8u*)output, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), NULL); + #endif + + /* compute ciphertext block */ + XorBlock(pSrc, output, pDst,dataLen); + /* encrement counter block */ + StdIncrement((Ipp8u*)counter,MBS_RIJ128*8, ctrNumBitSize); + } + + /* update counter */ + CopyBlock16(counter, pCtrValue); + + return ippStsNoErr; + } +} + +#if (_IPP32E>=_IPP32E_Y8) + +/* +// special version: 128-bit counter +*/ +static +IppStatus cpProcessAES_ctr128(const Ipp8u* pSrc, Ipp8u* pDst, int dataLen, const IppsAESSpec* pCtx, Ipp8u* pCtrValue) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test source, target and counter block pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pCtrValue); + /* test stream length */ + IPP_BADARG_RET((dataLen<1), ippStsLengthErr); + + { + while(dataLen>=MBS_RIJ128) { + Ipp32u blocks = (Ipp32u)(dataLen>>4); /* number of blocks per loop processing */ + + /* low LE 32 bit of counter */ + Ipp32u ctr32 = ((Ipp32u*)(pCtrValue))[3]; + ctr32 = ENDIANNESS32(ctr32); + + /* compute number of locks being processed without ctr32 overflow */ + ctr32 += blocks; + if(ctr32 < blocks) + blocks -= ctr32; + +#if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + EncryptStreamCTR32_VAES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (Ipp32s)blocks*MBS_RIJ128, pCtrValue); + } + else +#endif + EncryptStreamCTR32_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (Ipp32s)blocks*MBS_RIJ128, pCtrValue); + + pSrc += blocks*MBS_RIJ128; + pDst += blocks*MBS_RIJ128; + dataLen -= blocks*MBS_RIJ128; + } + + if(dataLen) { + EncryptStreamCTR32_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), dataLen, pCtrValue); + } + + return ippStsNoErr; + } +} + +#endif /* #if (_IPP32E>=_IPP32E_Y8) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrdecrypt.c new file mode 100644 index 000000000..d92828d81 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrdecrypt.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CTR mode) +// +// Contents: +// ippsAESDecryptCTR() +// +*/ +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4206) // empty unit +#endif + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_ctr_process.h" + +/* +// Name: ippsAESDecryptCTR +// +// Purpose: +// AES-CFB encryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pCtrValue ==NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsCTRSizeErr 128 < ctrNumBitSize < 1 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len output buffer length (in bytes) +// pCtx pointer to rge AES context +// pCtrValue pointer to the counter block +// ctrNumBitSize counter block size (bits) +// +// Note: +// counter will updated on return +// +*/ + +IPPFUN(IppStatus, ippsAESDecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + + #if(_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) + return ctrNumBitSize==128? cpProcessAES_ctr128(pSrc, pDst, len, pCtx, pCtrValue) : + cpProcessAES_ctr(pSrc, pDst, len, pCtx, pCtrValue, ctrNumBitSize); + else + return cpProcessAES_ctr(pSrc, pDst, len, pCtx, pCtrValue, ctrNumBitSize); + #else + return cpProcessAES_ctr(pSrc, pDst, len, pCtx, pCtrValue, ctrNumBitSize); + #endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencrypt_rij128pipe_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencrypt_rij128pipe_vaes512.c new file mode 100644 index 000000000..5ffd378f5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencrypt_rij128pipe_vaes512.c @@ -0,0 +1,265 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CTR mode) +// +// Contents: +// EncryptCTR_RIJ128pipe_VAES_NI +// +*/ + +#include "owncp.h" +#include "pcpaes_encrypt_vaes512.h" +#include "pcpaesm.h" + +#if (_IPP32E >= _IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable : 4310) // cast truncates constant value in MSVC +#endif + +#define M512(mem) (*((__m512i *)((Ipp8u *)(mem)))) + +/* Mask to convert 64-bit parts of four 128-bit numbers stored in one 512-bit register + * from Little-Endian to Big-Endian */ + +/* clang-format off */ +static __ALIGN32 Ipp8u swapBytes[] = { + 7, 6, 5, 4, 3, 2, 1, 0, 15,14,13,12, 11,10, 9, 8, + 23,22,21,20, 19,18,17,16, 31,30,29,28, 27,26,25,24, + 39,38,37,36, 35,34,33,32, 47,46,45,44, 43,42,41,40, + 55,54,53,52, 51,50,49,48, 63,62,61,60, 59,58,57,56 +}; +/* clang-format on */ + +/* Increment masks for Hi-Lo 64-bit parts of 128-bit numbers in 512-bit register */ +static __ALIGN64 Ipp64u startIncLoMask[] = { 0x0, 0x0, 0x0, 0x1, 0x0, 0x2, 0x0, 0x3 }; +static __ALIGN64 Ipp64u nextIncLoMask[] = { 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4 }; +static __ALIGN64 Ipp64u incLoByOneMask[] = { 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1 }; +static __ALIGN64 Ipp64u incHiByOneMask[] = { 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0 }; + +__INLINE __m512i adcLo_epi64(__m512i a, __m512i b) +{ + a = _mm512_add_epi64(a, b); + // check overflow in each low 64-bit of 128-bit numbers + __mmask8 overMsk = _mm512_cmplt_epu64_mask(a, b); + // get mask of each high 64-bit that need to be increased + overMsk <<= 1; + a = _mm512_mask_add_epi64(a, overMsk, a, M512(incHiByOneMask)); + return a; +} + +__INLINE __m512i applyNonce(__m512i a, __m512i ctrBitMask, __m512i templateCtr) +{ + a = _mm512_shuffle_epi8(a, M512(swapBytes)); + a = _mm512_and_epi64(a, ctrBitMask); + a = _mm512_or_epi64(a, templateCtr); + + return a; +} + +//////////////////////////////////////////////////////////////////////////////// +/* clang-format off */ +IPP_OWN_DEFN (void, EncryptCTR_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, + Ipp8u* pDst, + int nr, + const Ipp8u* pRKey, + int length, /* message length in bytes */ + Ipp8u* pCtrValue, + const Ipp8u* pCtrBitMask)) +/* clang-format on */ +{ + int cipherRounds = nr - 1; + + __m128i *pKeys = (__m128i *)pRKey; + __m512i *pSrc512 = (__m512i *)pSrc; + __m512i *pDst512 = (__m512i *)pDst; + + Ipp64u *pCtr64 = (Ipp64u *)pCtrValue; + + // Initial counter + __m128i initialCtr128 = _mm_maskz_loadu_epi64(0x03, pCtrValue); + __m128i ctrBitMask128 = _mm_maskz_loadu_epi64(0x03, pCtrBitMask); + // Unchanged counter part + __m128i templateCtr128 = _mm_maskz_andnot_epi64(0x03 /* all 128-bits */, ctrBitMask128, initialCtr128); + + __m512i ctrBitMask512 = _mm512_broadcast_i64x2(ctrBitMask128); + __m512i templateCtr512 = _mm512_broadcast_i64x2(templateCtr128); + + Ipp64u ctr64_h = ENDIANNESS64(pCtr64[0]); // high 64-bit of BE counter converted to LE + Ipp64u ctr64_l = ENDIANNESS64(pCtr64[1]); // low 64-bit of BE counter converted to LE + + __m512i ctr512 = _mm512_set4_epi64((Ipp64s)ctr64_l, (Ipp64s)ctr64_h, (Ipp64s)ctr64_l, (Ipp64s)ctr64_h); + + // int blocks; + int remainded_length; + __m512i incMsk = M512(startIncLoMask); + for (remainded_length = length; remainded_length >= (4 * 4 * MBS_RIJ128); remainded_length -= (4 * 4 * MBS_RIJ128)) { + __m512i counter0 = adcLo_epi64(incMsk, ctr512); + __m512i counter1 = adcLo_epi64(M512(nextIncLoMask), counter0); + __m512i counter2 = adcLo_epi64(M512(nextIncLoMask), counter1); + __m512i counter3 = adcLo_epi64(M512(nextIncLoMask), counter2); + + incMsk = M512(nextIncLoMask); + ctr512 = counter3; + + // convert back to BE and add nonce + counter0 = applyNonce(counter0, ctrBitMask512, templateCtr512); + counter1 = applyNonce(counter1, ctrBitMask512, templateCtr512); + counter2 = applyNonce(counter2, ctrBitMask512, templateCtr512); + counter3 = applyNonce(counter3, ctrBitMask512, templateCtr512); + + cpAESEncrypt4_VAES_NI(&counter0, &counter1, &counter2, &counter3, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + __m512i blk3 = _mm512_loadu_si512(pSrc512 + 3); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + blk2 = _mm512_xor_si512(blk2, counter2); + blk3 = _mm512_xor_si512(blk3, counter3); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + _mm512_storeu_si512(pDst512 + 3, blk3); + + pSrc512 += 4; + pDst512 += 4; + } + + if ((3 * 4 * MBS_RIJ128) <= remainded_length) { + __m512i counter0 = adcLo_epi64(incMsk, ctr512); + __m512i counter1 = adcLo_epi64(M512(nextIncLoMask), counter0); + __m512i counter2 = adcLo_epi64(M512(nextIncLoMask), counter1); + + incMsk = M512(nextIncLoMask); + ctr512 = counter2; + + // convert back to BE and add nonce + counter0 = applyNonce(counter0, ctrBitMask512, templateCtr512); + counter1 = applyNonce(counter1, ctrBitMask512, templateCtr512); + counter2 = applyNonce(counter2, ctrBitMask512, templateCtr512); + + cpAESEncrypt3_VAES_NI(&counter0, &counter1, &counter2, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + blk2 = _mm512_xor_si512(blk2, counter2); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + + pSrc512 += 3; + pDst512 += 3; + remainded_length -= (3 * 4 * MBS_RIJ128); + } + + if ((4 * 2 * MBS_RIJ128) <= remainded_length) { + __m512i counter0 = adcLo_epi64(incMsk, ctr512); + __m512i counter1 = adcLo_epi64(M512(nextIncLoMask), counter0); + + incMsk = M512(nextIncLoMask); + ctr512 = counter1; + + // convert back to BE and add nonce + counter0 = applyNonce(counter0, ctrBitMask512, templateCtr512); + counter1 = applyNonce(counter1, ctrBitMask512, templateCtr512); + + cpAESEncrypt2_VAES_NI(&counter0, &counter1, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + + pSrc512 += 2; + pDst512 += 2; + remainded_length -= (2 * 4 * MBS_RIJ128); + } + + for (; remainded_length >= 4 * MBS_RIJ128; remainded_length -= 4 * MBS_RIJ128) { + __m512i counter0 = adcLo_epi64(incMsk, ctr512); + + incMsk = M512(nextIncLoMask); + ctr512 = counter0; + + // convert back to BE and add nonce + counter0 = applyNonce(counter0, ctrBitMask512, templateCtr512); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + blk0 = _mm512_xor_si512(blk0, counter0); + _mm512_storeu_si512(pDst512, blk0); + + pSrc512 += 1; + pDst512 += 1; + } + + if (remainded_length) { + __m512i counter0 = _mm512_add_epi64(incMsk, ctr512); + __mmask8 overMsk = _mm512_cmplt_epu64_mask(counter0, ctr512); + overMsk <<= 1; + counter0 = _mm512_mask_add_epi64(counter0, overMsk, counter0, M512(incHiByOneMask)); + + incMsk = M512(nextIncLoMask); + ctr512 = counter0; + + // convert back to BE and add nonce + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + counter0 = _mm512_and_epi64(counter0, ctrBitMask512); + counter0 = _mm512_or_epi64(counter0, templateCtr512); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + __mmask64 rw_mask = (__mmask64)((1LL << remainded_length) - 1); + + __m512i blk0 = _mm512_maskz_loadu_epi8(rw_mask, pSrc512); + blk0 = _mm512_xor_si512(blk0, counter0); + _mm512_mask_storeu_epi8(pDst512, rw_mask, blk0); + } + + // return last counter + int blocks = remainded_length % MBS_RIJ128 == 0 ? remainded_length / MBS_RIJ128 : (remainded_length / MBS_RIJ128) + 1; + __mmask8 lastCtrK8 = blocks == 0 ? 0xC0 : (__mmask8)((Ipp8u)0x03 << ((blocks - 1) << 1)); + __mmask64 lastCtrK64 = blocks == 0 ? 0xFFFF000000000000 : (__mmask64)((Ipp64u)0xFFFF << ((blocks - 1) << 4)); + + ctr512 = adcLo_epi64(M512(incLoByOneMask), ctr512); + + ctr512 = _mm512_maskz_shuffle_epi8(lastCtrK64, ctr512, M512(swapBytes)); + ctr512 = _mm512_maskz_and_epi64(lastCtrK8, ctr512, ctrBitMask512); + ctr512 = _mm512_maskz_or_epi64(lastCtrK8, ctr512, templateCtr512); + + _mm512_mask_compressstoreu_epi64(pCtrValue, lastCtrK8, ctr512); +} + +#endif /* #if (_IPP32E>=_IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencrypt_stream_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencrypt_stream_vaes512.c new file mode 100755 index 000000000..d7c35cb4f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencrypt_stream_vaes512.c @@ -0,0 +1,238 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CTR mode) +// +// Contents: +// EncryptStreamCTR32_VAES_NI +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" + +#if (_IPP32E>=_IPP32E_K1) + +/* Mask to convert low 32-bit parts of four 128-bit Big-Endian numbers + * stored in 512-bit register. The low 32-bit of each number converted + * from LE to BE */ +static __ALIGN32 Ipp8u swapBytes[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, 15,14,13,12, + 16,17,18,19, 20,21,22,23, 24,25,26,27, 31,30,29,28, + 32,33,34,35, 36,37,38,39, 40,41,42,43, 47,46,45,44, + 48,49,50,51, 52,53,54,55, 56,57,58,59, 63,62,61,60 +}; + +//////////////////////////////////////////////////////////////////////////////// + +IPP_OWN_DEFN (void, EncryptStreamCTR32_VAES_NI, (const Ipp8u* pSrc, + Ipp8u* pDst, + int nr, + const Ipp8u* pRKey, + int length, /* message length in bytes */ + Ipp8u* pIV)) /* BE counter representation */ +{ + int cipherRounds = nr - 1; + + __m128i* pKeys = (__m128i*)pRKey; + __m512i* pSrc512 = (__m512i*)pSrc; + __m512i* pDst512 = (__m512i*)pDst; + + Ipp32u* pIV32 = (Ipp32u*)pIV; + Ipp64u* pIV64 = (Ipp64u*)pIV; + + // start increment mask for IV + __m512i startIncMask = _mm512_set_epi32(0x3, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x0, + 0x1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0); + + // continuous increment mask for IV + __m512i incMask = _mm512_set_epi32(0x4, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0, + 0x4, 0x0, 0x0, 0x0); + + // initial BE counter with 32-bit low part converted to LE: + // pIV: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | fc fd fe ff + // IV: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | ff fe fd fc + __m512i IV = _mm512_set4_epi32((Ipp32s)ENDIANNESS32(pIV32[3]), (Ipp32s)pIV32[2], (Ipp32s)pIV32[1], (Ipp32s)pIV32[0]); + + + // Update IV counter for next function calls + int blocks = length / MBS_RIJ128; + + Ipp64u ctr64_h = ENDIANNESS64(pIV64[0]); // high 64-bit of BE IV converted to LE + Ipp64u ctr64_l = ENDIANNESS64(pIV64[1]); // low 32-bit of BE pIV converted to LE + + ctr64_l += (Ipp64u)blocks; + if (ctr64_l < (Ipp64u)blocks) { // overflow of low part + ctr64_h += 1; + } + + // update IV + pIV64[0] = ENDIANNESS64(ctr64_h); + pIV64[1] = ENDIANNESS64(ctr64_l); + + //-------------------------------------- + + for (blocks = length / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + // counter0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | ff fe fd fc + // counter1: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | 00 ff fd fc + // counter2: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | 01 ff fd fc + // counter3: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | 02 ff fd fc + __m512i counter0 = _mm512_add_epi32(startIncMask, IV); + __m512i counter1 = _mm512_add_epi32(incMask, counter0); + __m512i counter2 = _mm512_add_epi32(incMask, counter1); + __m512i counter3 = _mm512_add_epi32(incMask, counter2); + + startIncMask = incMask; + IV = counter3; + + // convert last 32-bit (LE->BE): + // counter0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | fc fd fe ff + // counter1: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | fc fd ff 00 + // counter2: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | fc fd ff 01 + // counter3: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb | fc fd ff 02 + counter0 = _mm512_shuffle_epi8(counter0, *((__m512i*)swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, *((__m512i*)swapBytes)); + counter2 = _mm512_shuffle_epi8(counter2, *((__m512i*)swapBytes)); + counter3 = _mm512_shuffle_epi8(counter3, *((__m512i*)swapBytes)); + + cpAESEncrypt4_VAES_NI(&counter0, &counter1, &counter2, &counter3, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + __m512i blk3 = _mm512_loadu_si512(pSrc512 + 3); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + blk2 = _mm512_xor_si512(blk2, counter2); + blk3 = _mm512_xor_si512(blk3, counter3); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + _mm512_storeu_si512(pDst512 + 3, blk3); + + pSrc512 += 4; + pDst512 += 4; + } + + if ((3 * 4) <= blocks) { + __m512i counter0 = _mm512_add_epi32(startIncMask, IV); + __m512i counter1 = _mm512_add_epi32(incMask, counter0); + __m512i counter2 = _mm512_add_epi32(incMask, counter1); + + startIncMask = incMask; + IV = counter2; + + // convert last 32-bit (LE->BE) + counter0 = _mm512_shuffle_epi8(counter0, *((__m512i*)swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, *((__m512i*)swapBytes)); + counter2 = _mm512_shuffle_epi8(counter2, *((__m512i*)swapBytes)); + + cpAESEncrypt3_VAES_NI(&counter0, &counter1, &counter2, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + blk2 = _mm512_xor_si512(blk2, counter2); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + + pSrc512 += 3; + pDst512 += 3; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + __m512i counter0 = _mm512_add_epi32(startIncMask, IV); + __m512i counter1 = _mm512_add_epi32(incMask, counter0); + + startIncMask = incMask; + IV = counter1; + + // convert last 32-bit (LE->BE) + counter0 = _mm512_shuffle_epi8(counter0, *((__m512i*)swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, *((__m512i*)swapBytes)); + + cpAESEncrypt2_VAES_NI(&counter0, &counter1, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + + pSrc512 += 2; + pDst512 += 2; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + __m512i counter0 = _mm512_add_epi32(startIncMask, IV); + + startIncMask = incMask; + IV = counter0; + + // convert last 32-bit (LE->BE) + counter0 = _mm512_shuffle_epi8(counter0, *((__m512i*)swapBytes)); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + blk0 = _mm512_xor_si512(blk0, counter0); + _mm512_storeu_si512(pDst512, blk0); + + pSrc512 += 1; + pDst512 += 1; + } + + if (blocks) { + __mmask8 k8 = (__mmask8)((1 << (blocks + blocks)) - 1); // 64-bit chunks + __mmask16 k16 = (__mmask16)((1 << (blocks << 2)) - 1); // 32-bit chunks + __mmask64 k64 = (__mmask64)((1LL << (blocks << 4)) - 1); // 8-bit chunks + + __m512i counter0 = _mm512_maskz_add_epi32(k16, startIncMask, IV); + + // swap last 32-bit (LE->BE) + counter0 = _mm512_maskz_shuffle_epi8(k64, counter0, *((__m512i*)swapBytes)); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + __m512i blk0 = _mm512_maskz_loadu_epi64(k8, pSrc512); + blk0 = _mm512_maskz_xor_epi64(k8, blk0, counter0); + _mm512_mask_storeu_epi64(pDst512, k8, blk0); + } +} + +#endif /* #if (_IPP32E>=_IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencryptr.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencryptr.c new file mode 100644 index 000000000..149e00168 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ctrencryptr.c @@ -0,0 +1,84 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (CTR mode) +// +// Contents: +// ippsAESEncryptCTR() +// +*/ +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4206) // empty unit +#endif + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_ctr_process.h" + + +/* +// Name: ippsAESEncryptCTR +// +// Purpose: +// AES-CFB encryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pCtrValue ==NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsCTRSizeErr 128 < ctrNumBitSize < 1 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input buffer length (in bytes) +// pCtx pointer to rge AES context +// pCtrValue pointer to the counter block +// ctrNumBitSize counter block size (bits) +// +// Note: +// counter will updated on return +// +*/ + +IPPFUN(IppStatus, ippsAESEncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + + #if(_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) + return ctrNumBitSize==128? cpProcessAES_ctr128(pSrc, pDst, len, pCtx, pCtrValue) : + cpProcessAES_ctr(pSrc, pDst, len, pCtx, pCtrValue, ctrNumBitSize); + else + return cpProcessAES_ctr(pSrc, pDst, len, pCtx, pCtrValue, ctrNumBitSize); + #else + return cpProcessAES_ctr(pSrc, pDst, len, pCtx, pCtrValue, ctrNumBitSize); + #endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_deckeyexpansion_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_deckeyexpansion_ni.c new file mode 100644 index 000000000..ef6f9c30b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_deckeyexpansion_ni.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. AES keys expansion +// +// Contents: +// aes_DecKeyExpansion_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_keys_ni.h" + +#if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) + +////////////////////////////////////////////////////////////////////// +/* +// AES decryption key schelule +*/ +IPP_OWN_DEFN (void, aes_DecKeyExpansion_NI, (Ipp8u* decKeys, const Ipp8u* encKeys, int nr)) +{ + __m128i* encKeys16 = (__m128i*)encKeys; + __m128i* decKeys16 = (__m128i*)decKeys; + + decKeys16[nr] = encKeys16[nr]; + for(nr-=1; nr > 0; nr--) { + decKeys16[nr] = _mm_aesimc_si128(encKeys16[nr]); + } + decKeys16[0] = encKeys16[0]; +} + +#endif /* #if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_decrypt_vaes512.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_decrypt_vaes512.h new file mode 100644 index 000000000..0811d69b9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_decrypt_vaes512.h @@ -0,0 +1,192 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES decryption (VAES-512 kernels) +// +// Contents: +// cpAESDecrypt1_VAES_NI +// cpAESDecrypt2_VAES_NI +// cpAESDecrypt3_VAES_NI +// cpAESDecrypt4_VAES_NI +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" + +#if(_IPP32E>=_IPP32E_K1) + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4305) // zmmintrin.h bug: conversion from int to _mmask8 +#endif + +#if !defined(_PCP_AES_DECRYPT_VAES512_H_) +#define _PCP_AES_DECRYPT_VAES512_H_ +//////////////////////////////////////////////////////////////////////////////// + +static void cpAESDecrypt1_VAES_NI(__m512i* blk0, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[-1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[-2]); + + for (nr = 1, pRkey--; nr < cipherRounds; nr += 2, pRkey -= 2) { + b0 = _mm512_aesdec_epi128(b0, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[-2]); + b0 = _mm512_aesdec_epi128(b0, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[-3]); + } + + b0 = _mm512_aesdec_epi128(b0, rKey1); + *blk0 = _mm512_aesdeclast_epi128(b0, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +static void cpAESDecrypt2_VAES_NI(__m512i* blk0, + __m512i* blk1, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[-1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + __m512i b1 = _mm512_xor_si512(*blk1, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[-2]); + + for (nr = 1, pRkey--; nr < cipherRounds; nr += 2, pRkey -= 2) { + b0 = _mm512_aesdec_epi128(b0, rKey1); + b1 = _mm512_aesdec_epi128(b1, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[-2]); + + b0 = _mm512_aesdec_epi128(b0, rKey0); + b1 = _mm512_aesdec_epi128(b1, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[-3]); + } + b0 = _mm512_aesdec_epi128(b0, rKey1); + b1 = _mm512_aesdec_epi128(b1, rKey1); + + *blk0 = _mm512_aesdeclast_epi128(b0, rKey0); + *blk1 = _mm512_aesdeclast_epi128(b1, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +static void cpAESDecrypt3_VAES_NI(__m512i* blk0, + __m512i* blk1, + __m512i* blk2, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[-1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + __m512i b1 = _mm512_xor_si512(*blk1, rKey0); + __m512i b2 = _mm512_xor_si512(*blk2, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[-2]); + + for (nr = 1, pRkey--; nr < cipherRounds; nr += 2, pRkey -= 2) { + b0 = _mm512_aesdec_epi128(b0, rKey1); + b1 = _mm512_aesdec_epi128(b1, rKey1); + b2 = _mm512_aesdec_epi128(b2, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[-2]); + + b0 = _mm512_aesdec_epi128(b0, rKey0); + b1 = _mm512_aesdec_epi128(b1, rKey0); + b2 = _mm512_aesdec_epi128(b2, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[-3]); + } + b0 = _mm512_aesdec_epi128(b0, rKey1); + b1 = _mm512_aesdec_epi128(b1, rKey1); + b2 = _mm512_aesdec_epi128(b2, rKey1); + + *blk0 = _mm512_aesdeclast_epi128(b0, rKey0); + *blk1 = _mm512_aesdeclast_epi128(b1, rKey0); + *blk2 = _mm512_aesdeclast_epi128(b2, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +static void cpAESDecrypt4_VAES_NI(__m512i* blk0, + __m512i* blk1, + __m512i* blk2, + __m512i* blk3, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[-1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + __m512i b1 = _mm512_xor_si512(*blk1, rKey0); + __m512i b2 = _mm512_xor_si512(*blk2, rKey0); + __m512i b3 = _mm512_xor_si512(*blk3, rKey0); + + rKey0 = _mm512_broadcast_i64x2(pRkey[-2]); + + for (nr = 1, pRkey--; nr < cipherRounds; nr += 2, pRkey -= 2) { + b0 = _mm512_aesdec_epi128(b0, rKey1); + b1 = _mm512_aesdec_epi128(b1, rKey1); + b2 = _mm512_aesdec_epi128(b2, rKey1); + b3 = _mm512_aesdec_epi128(b3, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[-2]); + + b0 = _mm512_aesdec_epi128(b0, rKey0); + b1 = _mm512_aesdec_epi128(b1, rKey0); + b2 = _mm512_aesdec_epi128(b2, rKey0); + b3 = _mm512_aesdec_epi128(b3, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[-3]); + } + + b0 = _mm512_aesdec_epi128(b0, rKey1); + b1 = _mm512_aesdec_epi128(b1, rKey1); + b2 = _mm512_aesdec_epi128(b2, rKey1); + b3 = _mm512_aesdec_epi128(b3, rKey1); + + *blk0 = _mm512_aesdeclast_epi128(b0, rKey0); + *blk1 = _mm512_aesdeclast_epi128(b1, rKey0); + *blk2 = _mm512_aesdeclast_epi128(b2, rKey0); + *blk3 = _mm512_aesdeclast_epi128(b3, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +#endif /* _PCP_AES_DECRYPT_VAES512_H_ */ + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecb_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecb_vaes512.c new file mode 100644 index 000000000..b45f5fdb5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecb_vaes512.c @@ -0,0 +1,199 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (ECB mode) +// +// Contents: +// EncryptECB_RIJ128pipe_VAES_NI +// DecryptECB_RIJ128pipe_VAES_NI +// +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" +#include "pcpaes_decrypt_vaes512.h" + +#if (_IPP32E>=_IPP32E_K1) + +IPP_OWN_DEFN (void, EncryptECB_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, // pointer to the plaintext + Ipp8u* pDst, // pointer to the ciphertext buffer + int len, // text length in bytes + const IppsAESSpec* pCtx)) // pointer to the context +{ + int cipherRounds = RIJ_NR(pCtx) - 1; + + __m128i* pRkey = (__m128i*)RIJ_EKEYS(pCtx); + __m512i* pInp512 = (__m512i*)pSrc; + __m512i* pOut512 = (__m512i*)pDst; + + int blocks; + for (blocks = len / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + __m512i blk3 = _mm512_loadu_si512(pInp512 + 3); + + cpAESEncrypt4_VAES_NI(&blk0, &blk1, &blk2, &blk3, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + _mm512_storeu_si512(pOut512 + 3, blk3); + + pInp512 += 4; + pOut512 += 4; + } + + if ((3 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + + cpAESEncrypt3_VAES_NI(&blk0, &blk1, &blk2, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + + pInp512 += 3; + pOut512 += 3; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + + cpAESEncrypt2_VAES_NI(&blk0, &blk1, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + + pInp512 += 2; + pOut512 += 2; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + + cpAESEncrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + + pInp512 += 1; + pOut512 += 1; + } + + if (blocks) { + __mmask8 k = (__mmask8)((1 << (blocks + blocks)) - 1); + __m512i blk0 = _mm512_maskz_loadu_epi64(k, pInp512); + + cpAESEncrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + _mm512_mask_storeu_epi64(pOut512, k, blk0); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +IPP_OWN_DEFN (void, DecryptECB_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, // pointer to the plaintext + Ipp8u* pDst, // pointer to the ciphertext buffer + int len, // text length in bytes + const IppsAESSpec* pCtx)) // pointer to the context +{ + int cipherRounds = RIJ_NR(pCtx) - 1; + + __m128i* pRkey = (__m128i*)RIJ_DKEYS(pCtx) + cipherRounds + 1; + __m512i* pInp512 = (__m512i*)pSrc; + __m512i* pOut512 = (__m512i*)pDst; + + int blocks; + for (blocks = len / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + __m512i blk3 = _mm512_loadu_si512(pInp512 + 3); + + cpAESDecrypt4_VAES_NI(&blk0, &blk1, &blk2, &blk3, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + _mm512_storeu_si512(pOut512 + 3, blk3); + + pInp512 += 4; + pOut512 += 4; + } + + if ((3 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + + cpAESDecrypt3_VAES_NI(&blk0, &blk1, &blk2, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + + pInp512 += 3; + pOut512 += 3; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + + cpAESDecrypt2_VAES_NI(&blk0, &blk1, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + + pInp512 += 2; + pOut512 += 2; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + + cpAESDecrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + _mm512_storeu_si512(pOut512, blk0); + pInp512 += 1; + pOut512 += 1; + } + + if (blocks) { + __mmask8 k = (__mmask8)((1 << (blocks + blocks)) - 1); + __m512i blk0 = _mm512_maskz_loadu_epi64(k, pInp512); + + cpAESDecrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + _mm512_mask_storeu_epi64(pOut512, k, blk0); + } +} + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecbdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecbdecrypt.c new file mode 100644 index 000000000..44ccfdf07 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecbdecrypt.c @@ -0,0 +1,157 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (ECB mode) +// +// Contents: +// ippsAESDecryptECB() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +/* +// AES-ECB denryption +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// nBlocks number of decrypted data blocks +// pCtx pointer to the AES context +*/ +static +void cpDecryptAES_ecb(const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, const IppsAESSpec* pCtx) +{ +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use pipelined version is possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + DecryptECB_RIJ128pipe_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), nBlocks*MBS_RIJ128); + } + else +#endif + { + /* block-by-block decryption */ + RijnCipher decoder = RIJ_DECODER(pCtx); + + while(nBlocks) { + //decoder((const Ipp32u*)pSrc, (Ipp32u*)pDst, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), (const Ipp32u (*)[256])RIJ_DEC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + decoder(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijDecSbox/*NULL*/); + #else + decoder(pSrc, pDst, RIJ_NR(pCtx), RIJ_DKEYS(pCtx), NULL); + #endif + + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + nBlocks--; + } + } +} + +static void cpDecryptAES_ecb_dispatch(const Ipp8u *pSrc, Ipp8u *pDst, int len, const IppsAESSpec *pCtx) +{ +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) + DecryptECB_RIJ128pipe_VAES_NI(pSrc, pDst, len, pCtx); + else +#endif + { + int nBlocks = len / MBS_RIJ128; + cpDecryptAES_ecb(pSrc, pDst, nBlocks, pCtx); + } +} + +/*F* +// Name: ippsAESDecryptECB +// +// Purpose: AES-ECB decryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr dataLen <1 +// ippStsUnderRunErr 0!=(dataLen%MBS_RIJ128) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// pCtx pointer to the AES context +// +*F*/ +IPPFUN(IppStatus, ippsAESDecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test source and target buffer pointers */ + IPP_BAD_PTR2_RET(pSrc, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test stream integrity */ + IPP_BADARG_RET((len&(MBS_RIJ128-1)), ippStsUnderRunErr); + + /* do encryption */ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + cpAESNoiseParams *params = (cpAESNoiseParams*)&RIJ_NOISE_PARAMS(pCtx); + /* Mistletoe3 mitigation */ + if (AES_NOISE_LEVEL(params) > 0) { + /* Number of bytes allowed for operation without adding noise */ + int chunk_size; + /* Number of bytes remaining for operation */ + int remaining_size = len; + + while (remaining_size > 0) { + /* How many bytes to encrypt in this operation */ + chunk_size = (remaining_size >= MISTLETOE3_MAX_CHUNK_SIZE) ? MISTLETOE3_MAX_CHUNK_SIZE : remaining_size; + + cpDecryptAES_ecb_dispatch(pSrc, pDst, chunk_size, pCtx); + + cpAESRandomNoise(NULL, + MISTLETOE3_BASE_NOISE_LEVEL + AES_NOISE_LEVEL(params), + MISTLETOE3_NOISE_RATE, + &AES_NOISE_RAND(params)); + + pSrc += chunk_size; + pDst += chunk_size; + remaining_size -= chunk_size; + } + } else +#endif + { + cpDecryptAES_ecb_dispatch(pSrc, pDst, len, pCtx); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecbencrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecbencrypt.c new file mode 100644 index 000000000..640a390c9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ecbencrypt.c @@ -0,0 +1,159 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (ECB mode) +// +// Contents: +// ippsAESEncryptECB() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcprij.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + + +/* +// AES-ECB ecnryption +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// nBlocks number of ecnrypted data blocks +// pCtx pointer to the AES context +*/ +static +void cpEncryptAES_ecb(const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, const IppsAESSpec* pCtx) +{ +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use pipelined version is possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + EncryptECB_RIJ128pipe_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), nBlocks*MBS_RIJ128); + } + else +#endif + { + /* block-by-block encryption */ + RijnCipher encoder = RIJ_ENCODER(pCtx); + + while(nBlocks) { + //encoder((const Ipp32u*)pSrc, (Ipp32u*)pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijEncSbox/*NULL*/); + #else + encoder(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), NULL); + #endif + + pSrc += MBS_RIJ128; + pDst += MBS_RIJ128; + nBlocks--; + } + } +} + +static void cpEncryptAES_ecb_dispatch(const Ipp8u *pSrc, Ipp8u *pDst, int len, const IppsAESSpec *pCtx) +{ +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) + EncryptECB_RIJ128pipe_VAES_NI(pSrc, pDst, len, pCtx); + else +#endif + { + int nBlocks = len / MBS_RIJ128; + cpEncryptAES_ecb(pSrc, pDst, nBlocks, pCtx); + } +} + +/*F* +// Name: ippsAESEncryptECB +// +// Purpose: AES-ECB encryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr dataLen <1 +// ippStsUnderRunErr 0!=(dataLen%MBS_RIJ128) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// pCtx pointer to the AES context +// +*F*/ +IPPFUN(IppStatus, ippsAESEncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsAESSpec* pCtx)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test source and target buffer pointers */ + IPP_BAD_PTR2_RET(pSrc, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test stream integrity */ + IPP_BADARG_RET((len&(MBS_RIJ128-1)), ippStsUnderRunErr); + + /* do encryption */ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* Mistletoe3 mitigation */ + cpAESNoiseParams *params = (cpAESNoiseParams*)&RIJ_NOISE_PARAMS(pCtx); + if (AES_NOISE_LEVEL(params) > 0) { + /* Number of bytes allowed for operation without adding noise */ + int chunk_size; + /* Number of bytes remaining for operation */ + int remaining_size = len; + + while (remaining_size > 0) { + /* How many bytes to encrypt in this operation */ + chunk_size = (remaining_size >= MISTLETOE3_MAX_CHUNK_SIZE) ? MISTLETOE3_MAX_CHUNK_SIZE : remaining_size; + + cpEncryptAES_ecb_dispatch(pSrc, pDst, chunk_size, pCtx); + + cpAESRandomNoise(NULL, + MISTLETOE3_BASE_NOISE_LEVEL + AES_NOISE_LEVEL(params), + MISTLETOE3_NOISE_RATE, + &AES_NOISE_RAND(params)); + + pSrc += chunk_size; + pDst += chunk_size; + remaining_size -= chunk_size; + } + } else +#endif + { + cpEncryptAES_ecb_dispatch(pSrc, pDst, len, pCtx); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_encrypt_vaes512.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_encrypt_vaes512.h new file mode 100644 index 000000000..88a267142 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_encrypt_vaes512.h @@ -0,0 +1,193 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption (VAES-512 kernels) +// +// Contents: +// cpAESEncrypt1_VAES_NI +// cpAESEncrypt2_VAES_NI +// cpAESEncrypt3_VAES_NI +// cpAESEncrypt4_VAES_NI +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" + +#if(_IPP32E>=_IPP32E_K1) + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4305) // zmmintrin.h bug: conversion from int to _mmask8 +#endif + +#if !defined(_PCP_AES_ENCRYPT_VAES512_H_) +#define _PCP_AES_ENCRYPT_VAES512_H_ + +//////////////////////////////////////////////////////////////////////////////// + +static void cpAESEncrypt1_VAES_NI(__m512i* blk0, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[2]); + + for (nr = 1, pRkey++; nr < cipherRounds; nr += 2, pRkey += 2) { + b0 = _mm512_aesenc_epi128(b0, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[2]); + b0 = _mm512_aesenc_epi128(b0, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[3]); + } + + b0 = _mm512_aesenc_epi128(b0, rKey1); + *blk0 = _mm512_aesenclast_epi128(b0, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +static void cpAESEncrypt2_VAES_NI(__m512i* blk0, + __m512i* blk1, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + __m512i b1 = _mm512_xor_si512(*blk1, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[2]); + + for (nr = 1, pRkey++; nr < cipherRounds; nr += 2, pRkey += 2) { + b0 = _mm512_aesenc_epi128(b0, rKey1); + b1 = _mm512_aesenc_epi128(b1, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[2]); + + b0 = _mm512_aesenc_epi128(b0, rKey0); + b1 = _mm512_aesenc_epi128(b1, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[3]); + } + + b0 = _mm512_aesenc_epi128(b0, rKey1); + b1 = _mm512_aesenc_epi128(b1, rKey1); + + *blk0 = _mm512_aesenclast_epi128(b0, rKey0); + *blk1 = _mm512_aesenclast_epi128(b1, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +static void cpAESEncrypt3_VAES_NI(__m512i* blk0, + __m512i* blk1, + __m512i* blk2, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + __m512i b1 = _mm512_xor_si512(*blk1, rKey0); + __m512i b2 = _mm512_xor_si512(*blk2, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[2]); + + for (nr = 1, pRkey++; nr < cipherRounds; nr += 2, pRkey += 2) { + b0 = _mm512_aesenc_epi128(b0, rKey1); + b1 = _mm512_aesenc_epi128(b1, rKey1); + b2 = _mm512_aesenc_epi128(b2, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[2]); + + b0 = _mm512_aesenc_epi128(b0, rKey0); + b1 = _mm512_aesenc_epi128(b1, rKey0); + b2 = _mm512_aesenc_epi128(b2, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[3]); + } + + b0 = _mm512_aesenc_epi128(b0, rKey1); + b1 = _mm512_aesenc_epi128(b1, rKey1); + b2 = _mm512_aesenc_epi128(b2, rKey1); + + *blk0 = _mm512_aesenclast_epi128(b0, rKey0); + *blk1 = _mm512_aesenclast_epi128(b1, rKey0); + *blk2 = _mm512_aesenclast_epi128(b2, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +static void cpAESEncrypt4_VAES_NI(__m512i* blk0, + __m512i* blk1, + __m512i* blk2, + __m512i* blk3, + const __m128i* pRkey, + int cipherRounds) +{ + int nr; + + __m512i rKey0 = _mm512_broadcast_i64x2(pRkey[0]); + __m512i rKey1 = _mm512_broadcast_i64x2(pRkey[1]); + + __m512i b0 = _mm512_xor_si512(*blk0, rKey0); + __m512i b1 = _mm512_xor_si512(*blk1, rKey0); + __m512i b2 = _mm512_xor_si512(*blk2, rKey0); + __m512i b3 = _mm512_xor_si512(*blk3, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[2]); + + for (nr = 1, pRkey++; nr < cipherRounds; nr += 2, pRkey += 2) { + b0 = _mm512_aesenc_epi128(b0, rKey1); + b1 = _mm512_aesenc_epi128(b1, rKey1); + b2 = _mm512_aesenc_epi128(b2, rKey1); + b3 = _mm512_aesenc_epi128(b3, rKey1); + rKey1 = _mm512_broadcast_i64x2(pRkey[2]); + + b0 = _mm512_aesenc_epi128(b0, rKey0); + b1 = _mm512_aesenc_epi128(b1, rKey0); + b2 = _mm512_aesenc_epi128(b2, rKey0); + b3 = _mm512_aesenc_epi128(b3, rKey0); + rKey0 = _mm512_broadcast_i64x2(pRkey[3]); + } + b0 = _mm512_aesenc_epi128(b0, rKey1); + b1 = _mm512_aesenc_epi128(b1, rKey1); + b2 = _mm512_aesenc_epi128(b2, rKey1); + b3 = _mm512_aesenc_epi128(b3, rKey1); + + *blk0 = _mm512_aesenclast_epi128(b0, rKey0); + *blk1 = _mm512_aesenclast_epi128(b1, rKey0); + *blk2 = _mm512_aesenclast_epi128(b2, rKey0); + *blk3 = _mm512_aesenclast_epi128(b3, rKey0); + + rKey0 = _mm512_setzero_si512(); + rKey1 = _mm512_setzero_si512(); +} + +#endif /* _PCP_AES_ENCRYPT_VAES512_H_ */ + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_expandkey_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_expandkey_ni.c new file mode 100644 index 000000000..d6f6c2be8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_expandkey_ni.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. AES keys expansion +// +// Contents: +// cpExpandAesKey_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_keys_ni.h" + +#if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) + +IPP_OWN_DEFN (void, cpExpandAesKey_NI, (const Ipp8u* pSecret, IppsAESSpec* pCtx)) +{ + int nRounds = RIJ_NR(pCtx); + Ipp8u* pEncKeys = RIJ_EKEYS(pCtx); + Ipp8u* pDecKeys = RIJ_DKEYS(pCtx); + + switch (nRounds) { + case 12: aes192_KeyExpansion_NI(pEncKeys, pSecret); break; + case 14: aes256_KeyExpansion_NI(pEncKeys, pSecret); break; + default: aes128_KeyExpansion_NI(pEncKeys, pSecret); break; + } + + aes_DecKeyExpansion_NI(pDecKeys, pEncKeys, nRounds); +} + +#endif /* #if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcm_vaes512.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcm_vaes512.h new file mode 100644 index 000000000..0d2368bec --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcm_vaes512.h @@ -0,0 +1,146 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM auxilary +// +// Contents: +// +*/ + +#if 0 // Not used + +#if !defined(_CP_AES_GCM_VAES512_H) +#define _CP_AES_GCM_VAES512_H + +#if (_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // cast truncates constant value in MSVC +#endif + +#define M128(mem) (*((__m128i*)((Ipp8u*)(mem)))) +#define M256(mem) (*((__m256i*)((Ipp8u*)(mem)))) +#define M512(mem) (*((__m512i*)((Ipp8u*)(mem)))) + +static const __ALIGN64 Ipp64u POLY2[] = { 0x1, 0xC200000000000000, 0x1, 0xC200000000000000, + 0x1, 0xC200000000000000, 0x1, 0xC200000000000000 }; + +static __ALIGN64 Ipp8u swapBytes[] = { + 15,14,13,12, 11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, + 31,30,29,28, 27,26,25,24, 23,22,21,20, 19,18,17,16, + 47,46,45,44, 43,42,41,40, 39,38,37,36, 35,34,33,32, + 63,62,61,60, 59,58,57,56, 55,54,53,52, 51,50,49,48, +}; + +/* The function performs careless Karatsuba multiplication of 4x128-bit blocks stored + * in 512-bit inputs: + * A = [A3 A2 A1 A0], B = [B3 B2 B1 B0] + * Ai=[a1i:a0i] and Bi=[b1i:b0i], i=0..3 + * and returns parts of the multiplication Hi, Mi and Li, i=0..3, where + * Hi = a1i*b1i + * Mi = (a1i^a0i)*(b1i^b0i) + * Li = a0i*b0i + * + * NB: make sure unused parts of input registers are zeroed to avoid issues with further horizontal XOR. + */ +__INLINE void AesGcmKaratsubaMul4(const __m512i * const pA, /* A3 A2 A1 A0 */ + const __m512i * const pHKeys, /* B3 B2 B1 B0 */ + const __m512i * const pHKeysKaratsuba, /* precomputed (b1i^b0i) */ + __m512i * const pH, + __m512i * const pM, + __m512i * const pL) +{ + *pL = _mm512_clmulepi64_epi128(*pA, *pHKeys, 0x00); // L = [a0i*b0i] + *pH = _mm512_clmulepi64_epi128(*pA, *pHKeys, 0x11); // H = [a1i*b1i] + + *pM = _mm512_shuffle_epi32(*pA, 78); // M = [a0i:a1i] + *pM = _mm512_xor_epi32(*pM, *pA); // M = [a1i^a0i:a1i^a0i] + *pM = _mm512_clmulepi64_epi128(*pM, *pHKeysKaratsuba, 0x00); // M = (a1i^a0i)*(b1i^b0i) +} + +/* The function performs horizontal XOR for 4 128-bit values in 512-bit register + 128-bit result value saved in the low part of the 512-bit register + */ +__INLINE void HXor4x128(const __m512i * const zmm, + __m128i * const xmm) +{ + __m256i ymm; + + ymm = _mm512_extracti64x4_epi64(*zmm, 0x1); // zmm = [3 2 1 0]; ymm = [3 2] + ymm = _mm256_xor_si256(_mm512_castsi512_si256(*zmm), ymm); // ymm = [1^3 0^2] + + *xmm = _mm256_extracti32x4_epi32(ymm, 0x1); // xmm = [1^3] + *xmm = _mm_maskz_xor_epi64(0xFF, _mm256_castsi256_si128(ymm), *xmm); +} + +/* The function performs Montgomery reduction of 256-bit polynomial to 128-bit one + with irreducible polynomial + */ +__INLINE void ReducePoly2x128(const __m128i * const pHI, + const __m128i * const pLO, + __m128i * const result) +{ + __m256i tmp1, tmp2, HI, LO; + + HI = _mm256_set_m128i(_mm_setzero_si128(), *pHI); + LO = _mm256_set_m128i(_mm_setzero_si128(), *pLO); + + tmp1 = _mm256_clmulepi64_epi128(LO, M256(POLY2), 0x10); + tmp2 = _mm256_shuffle_epi32(LO, 78); // 78 = 01001110b + LO = _mm256_xor_si256(tmp1, tmp2); + + tmp1 = _mm256_clmulepi64_epi128(LO, M256(POLY2), 0x10); + tmp2 = _mm256_shuffle_epi32(LO, 78); // 78 = 01001110b + LO = _mm256_xor_si256(tmp1, tmp2); + + tmp1 = _mm256_xor_si256(HI, LO); + *result = _mm256_castsi256_si128(tmp1); +} + +/* The function aggregates partial products of Karatsuba multiplication into final ghash value */ +__INLINE void AggregateKaratsubaPartialProducts(const __m512i * const pH, + const __m512i * const pM, + const __m512i * const pL, + __m128i * const result) +{ + __m512i H, M, L; + __m128i H128, L128; + + /* Aggregation step1 - combine multiplication results H,M,L into Hi and Lo 128-bit parts */ + M = _mm512_xor_si512(*pM, *pH); + M = _mm512_xor_si512(M, *pL); + H = _mm512_bsrli_epi128(M, 8); + H = _mm512_xor_si512(*pH, H); + L = _mm512_bslli_epi128(M, 8); + L = _mm512_xor_si512(*pL, L); + + /* Aggregation step2 - horizontal XOR for H, L*/ + HXor4x128(&H, &H128); + HXor4x128(&L, &L128); + + /* Reduction of 256-bit poly to 128-bit poly using irreducible polynomial */ + ReducePoly2x128(&H128, &L128, result); +} + +#endif /* #if (_IPP32E>=_IPP32E_K1) */ + +#endif /* _CP_AES_GCM_VAES512_H*/ + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmauth_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmauth_vaes512.c new file mode 100644 index 000000000..e8b789fe1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmauth_vaes512.c @@ -0,0 +1,231 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES authentication (GCM mode) +// +// Contents: +// +*/ + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4206) // empty translation unit in MSVC +#endif + +#if 0 // Not used + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" +#include "pcpaes_gcm_vaes512.h" +#include "pcpaesauthgcm.h" + +#if (_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // cast truncates constant value in MSVC +#endif + +/* AES-GCM authentication function. It calculates GHASH of the source input */ +IPP_OWN_DEFN (void, AesGcmAuth_vaes, (Ipp8u* pGHash, const Ipp8u* pSrc, int len, const Ipp8u* pHKey, const void* pParam)) +{ + IPP_UNREFERENCED_PARAMETER(pParam); + + __m512i* pSrc512 = (__m512i*)pSrc; + __m512i* pHKey512 = (__m512i*)pHKey; + + /* Load hKeys vectors */ + __m512i hKeys0 = _mm512_loadu_si512(pHKey512); + __m512i hKeys1 = _mm512_loadu_si512(pHKey512 + 1); + __m512i hKeys2 = _mm512_loadu_si512(pHKey512 + 2); + __m512i hKeys3 = _mm512_loadu_si512(pHKey512 + 3); + + /* Load precomputed multipliers for Karatsuba multiplication */ + __m512i hKeysKaratsuba0 = _mm512_loadu_si512(pHKey512 + 4); + __m512i hKeysKaratsuba1 = _mm512_loadu_si512(pHKey512 + 5); + __m512i hKeysKaratsuba2 = _mm512_loadu_si512(pHKey512 + 6); + __m512i hKeysKaratsuba3 = _mm512_loadu_si512(pHKey512 + 7); + + /* Current GHASH value */ + __m128i ghash128; + __m512i ghash512 = _mm512_maskz_loadu_epi64(0x03, pGHash); + ghash512 = _mm512_shuffle_epi8(ghash512, M512(swapBytes)); + + int blocks; + for (blocks = len / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + __m512i blk3 = _mm512_loadu_si512(pSrc512 + 3); + + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + blk2 = _mm512_shuffle_epi8(blk2, M512(swapBytes)); + blk3 = _mm512_shuffle_epi8(blk3, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + /* Karatsuba multiplication for 16 blocks with postponed aggregation */ + __m512i H, M, L, tmp1, tmp2, tmp3; + AesGcmKaratsubaMul4(&blk0, &hKeys3, &hKeysKaratsuba3, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys2, &hKeysKaratsuba2, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk2, &hKeys1, &hKeysKaratsuba1, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk3, &hKeys0, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 4; + } + + if ((3 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512+1); + __m512i blk2 = _mm512_loadu_si512(pSrc512+2); + + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + blk2 = _mm512_shuffle_epi8(blk2, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + __m512i H, M, L, tmp1, tmp2, tmp3; + AesGcmKaratsubaMul4(&blk0, &hKeys2, &hKeysKaratsuba2, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys1, &hKeysKaratsuba1, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk2, &hKeys0, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 3; + } + + if ((4 * 2) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512+1); + + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + __m512i H, M, L, tmp1, tmp2, tmp3; + AesGcmKaratsubaMul4(&blk0, &hKeys1, &hKeysKaratsuba1, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys0, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 2; + } + + for (; blocks >= 4; blocks -= 4) { + __m512i blk0 = _mm512_loadu_si512(pSrc512); + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + __m512i H, M, L; + AesGcmKaratsubaMul4(&blk0, &hKeys0, &hKeysKaratsuba0, &H, &M, &L); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 1; + } + + // at least one block left (max 3 blocks) + if (blocks) { + __mmask8 k8 = (__mmask8)((1 << (blocks + blocks)) - 1); // 64-bit chunks + + __m512i blk0 = _mm512_maskz_loadu_epi64(k8, pSrc512); + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + __m512i H = _mm512_setzero_si512(); + __m512i M = _mm512_setzero_si512(); + __m512i L = _mm512_setzero_si512(); + + // NB: we need immediate parameter in alignr function + switch (blocks) { + case 1: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 6); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 6); + break; + } + case 2: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 4); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 4); + break; + } + default: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 2); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 2); + } + } + AesGcmKaratsubaMul4(&blk0, &hKeys0, &hKeysKaratsuba0, &H, &M, &L); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + } + + ghash512 = _mm512_shuffle_epi8(ghash512, M512(swapBytes)); + _mm512_mask_storeu_epi64(pGHash, 0x03, ghash512); +} + +#endif /* #if (_IPP32E>=_IPP32E_K1) */ + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmdecrypt.c new file mode 100644 index 000000000..4e4b29e9d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmdecrypt.c @@ -0,0 +1,216 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMDecrypt() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMDecrypt +// +// Purpose: Decrypts a data buffer in the GCM mode. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pDst == NULL +// pState == NULL +// ippStsContextMatchErr !AESGCM_VALID_ID() +// ippStsLengthErr len<0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc Pointer to ciphertext. +// pDst Pointer to plaintext. +// len Length of the plaintext and ciphertext in bytes +// pState pointer to the context +// +*F*/ + +IPPFUN(IppStatus, ippsAES_GCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsAES_GCMState* pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + /* use aligned context */ + pState = (IppsAES_GCMState*)( IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT) ); + /* test state ID */ + IPP_BADARG_RET(!AESGCM_VALID_ID(pState), ippStsContextMatchErr); + /* test context validity */ + IPP_BADARG_RET(!(GcmAADprocessing==AESGCM_STATE(pState) || GcmTXTprocessing==AESGCM_STATE(pState)), ippStsBadArgErr); + + /* test text pointers and length */ + IPP_BAD_PTR2_RET(pSrc, pDst); + IPP_BADARG_RET(len<0, ippStsLengthErr); + + /* According to the NIST Special Publication 800-38D (Recommendation for GCM + * mode, p.5.2.1.1 Input Data) the input text shall be between 0 and 2^39-256 + * bits. */ + const Ipp64u MAX_TXT_LEN = ((Ipp64u)1 << 36) - 32; /* length in bytes */ + IPP_BADARG_RET(((AESGCM_TXT_LEN(pState) > MAX_TXT_LEN - (Ipp64u)len) || + ((AESGCM_TXT_LEN(pState) + (Ipp64u)len) < (Ipp64u)len)), + ippStsScaleRangeErr); + +#if (_IPP32E < _IPP32E_K0) + /* get method */ + IppsAESSpec *pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + MulGcm_ hashFunc = AESGCM_HASH(pState); +#endif + + if( GcmAADprocessing==AESGCM_STATE(pState) ) { +#if(_IPP32E>=_IPP32E_K0) + if(AESGCM_BUFLEN(pState)) { + MulGcm_ ghashFunc = AES_GCM_GMUL(pState); + ghashFunc(&AES_GCM_KEY_DATA(pState), AESGCM_GHASH(pState)); + } +#else + /* complete AAD processing */ + if(AESGCM_BUFLEN(pState)) + hashFunc(AESGCM_GHASH(pState), AESGCM_HKEY(pState), AesGcmConst_table); + + /* increment counter block */ + IncrementCounter32(AESGCM_COUNTER(pState)); + /* and encrypt counter */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + /* switch mode and init counters */ + AESGCM_BUFLEN(pState) = 0; + AESGCM_TXT_LEN(pState) = CONST_64(0); + AESGCM_STATE(pState) = GcmTXTprocessing; + } + + /* + // process text (authenticate and decrypt) + */ + +#if(_IPP32E>=_IPP32E_K0) + DecryptUpdate_ dec = AES_GCM_DECRYPT_UPDATE(pState); +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* Mistletoe3 mitigation */ + cpAESNoiseParams *params = (cpAESNoiseParams*)&AESGCM_NOISE_PARAMS(pState); + if (AES_NOISE_LEVEL(params) > 0) { + /* Number of bytes allowed for operation without adding noise */ + int chunk_size; + /* Number of bytes remaining for operation */ + int remaining_size = len; + + while (remaining_size > 0) { + /* How many bytes to encrypt in this operation */ + chunk_size = (remaining_size >= MISTLETOE3_MAX_CHUNK_SIZE) ? MISTLETOE3_MAX_CHUNK_SIZE : remaining_size; + + dec(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), pDst, pSrc, (Ipp64u)chunk_size); + + cpAESRandomNoise(NULL, + MISTLETOE3_BASE_NOISE_LEVEL + AES_NOISE_LEVEL(params), + MISTLETOE3_NOISE_RATE, + &AES_NOISE_RAND(params)); + + pSrc += chunk_size; + pDst += chunk_size; + remaining_size -= chunk_size; + } + } else +#endif + { + dec(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), pDst, pSrc, (Ipp64u)len); + } +#else + /* process partial block */ + if(AESGCM_BUFLEN(pState)) { + int locLen = IPP_MIN(len, BLOCK_SIZE-AESGCM_BUFLEN(pState)); + /* authentication */ + XorBlock(pSrc, AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), locLen); + /* ctr decryption */ + XorBlock(pSrc, AESGCM_ECOUNTER(pState)+AESGCM_BUFLEN(pState), pDst, locLen); + + AESGCM_BUFLEN(pState) += locLen; + AESGCM_TXT_LEN(pState) += (Ipp64u)locLen; + pSrc += locLen; + pDst += locLen; + len -= locLen; + + /* if buffer full */ + if(BLOCK_SIZE==AESGCM_BUFLEN(pState)) { + /* hash buffer */ + hashFunc(AESGCM_GHASH(pState), AESGCM_HKEY(pState), AesGcmConst_table); + AESGCM_BUFLEN(pState) = 0; + + /* increment counter block */ + IncrementCounter32(AESGCM_COUNTER(pState)); + /* and encrypt counter */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + } + + /* process the main part of text */ + { + int lenBlks = len & (-BLOCK_SIZE); + if(lenBlks) { + Decrypt_ decFunc = AESGCM_DEC(pState); + + decFunc(pDst, pSrc, lenBlks, pState); + + AESGCM_TXT_LEN(pState) += (Ipp64u)lenBlks; + pSrc += lenBlks; + pDst += lenBlks; + len -= lenBlks; + } + } + + /* process the rest of text */ + if(len) { + /* ctr encryption */ + XorBlock(pSrc, AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), len); + XorBlock(pSrc, AESGCM_ECOUNTER(pState)+AESGCM_BUFLEN(pState), pDst, len); + + AESGCM_BUFLEN(pState) += len; + AESGCM_TXT_LEN(pState) += (Ipp64u)len; + } +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmdecrypt_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmdecrypt_vaes512.c new file mode 100644 index 000000000..4d21be312 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmdecrypt_vaes512.c @@ -0,0 +1,347 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES decryption (GCM mode) +// +// Contents: +// +*/ + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4206) // empty translation unit in MSVC +#endif + +#if 0 // Not used + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" +#include "pcpaes_gcm_vaes512.h" +#include "pcpaesauthgcm.h" + +#if (_IPP32E>=_IPP32E_K1) + +static __ALIGN64 Ipp32u inc_lo32x4[] = { 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 }; +static __ALIGN64 Ipp32u inc1_lo32x4[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 }; +static __ALIGN64 Ipp32u inc4_lo32x4[] = { 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0 }; + +IPP_OWN_DEFN (void, AesGcmDec_vaes, (Ipp8u* pDst, const Ipp8u* pSrc, int length, IppsAES_GCMState* pCtx)) +{ + IppsAESSpec* pAES = AESGCM_CIPHER(pCtx); + int cipherRounds = RIJ_NR(pAES) - 1; + const Ipp8u* pRKey = RIJ_EKEYS(pAES); + + Ipp8u* pCtrValue = AESGCM_COUNTER(pCtx); + Ipp8u* pGHash = AESGCM_GHASH(pCtx); + const Ipp8u* pHKey = AESGCM_HKEY(pCtx); + + __m128i* pKeys = (__m128i*)pRKey; + __m512i* pSrc512 = (__m512i*)pSrc; + __m512i* pDst512 = (__m512i*)pDst; + __m512i* pHKey512 = (__m512i*)pHKey; + + __m512i incMsk = M512(inc_lo32x4); + + /* Load hKeys vectors */ + __m512i hKeys0 = _mm512_loadu_si512(pHKey512); + __m512i hKeys1 = _mm512_loadu_si512(pHKey512 + 1); + __m512i hKeys2 = _mm512_loadu_si512(pHKey512 + 2); + __m512i hKeys3 = _mm512_loadu_si512(pHKey512 + 3); + + /* Load precomputed multipliers for Karatsuba multiplication */ + __m512i hKeysKaratsuba0 = _mm512_loadu_si512(pHKey512 + 4); + __m512i hKeysKaratsuba1 = _mm512_loadu_si512(pHKey512 + 5); + __m512i hKeysKaratsuba2 = _mm512_loadu_si512(pHKey512 + 6); + __m512i hKeysKaratsuba3 = _mm512_loadu_si512(pHKey512 + 7); + + /* Current GHASH value */ + __m128i ghash128; + __m512i ghash512 = _mm512_maskz_loadu_epi64(0x03, pGHash); + ghash512 = _mm512_shuffle_epi8(ghash512, M512(swapBytes)); + + /* Load initial counter */ + __m128i ctr128 = _mm_maskz_loadu_epi64(0x03, pCtrValue); + __m512i ctr512 = _mm512_broadcast_i64x2(ctr128); + + // convert counter to little-endian + ctr512 = _mm512_shuffle_epi8(ctr512, M512(swapBytes)); + + int blocks; + for (blocks = length / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + __m512i counter0 = _mm512_add_epi32(incMsk, ctr512); + __m512i counter1 = _mm512_add_epi32(M512(inc4_lo32x4), counter0); + __m512i counter2 = _mm512_add_epi32(M512(inc4_lo32x4), counter1); + __m512i counter3 = _mm512_add_epi32(M512(inc4_lo32x4), counter2); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter3; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, M512(swapBytes)); + counter2 = _mm512_shuffle_epi8(counter2, M512(swapBytes)); + counter3 = _mm512_shuffle_epi8(counter3, M512(swapBytes)); + + cpAESEncrypt4_VAES_NI(&counter0, &counter1, &counter2, &counter3, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + __m512i blk3 = _mm512_loadu_si512(pSrc512 + 3); + + _mm512_storeu_si512(pDst512, _mm512_xor_si512(blk0, counter0)); + _mm512_storeu_si512(pDst512 + 1, _mm512_xor_si512(blk1, counter1)); + _mm512_storeu_si512(pDst512 + 2, _mm512_xor_si512(blk2, counter2)); + _mm512_storeu_si512(pDst512 + 3, _mm512_xor_si512(blk3, counter3)); + + /* Authenticate */ + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + blk2 = _mm512_shuffle_epi8(blk2, M512(swapBytes)); + blk3 = _mm512_shuffle_epi8(blk3, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + /* Karatsuba multiplication for 16 blocks with postponed aggregation */ + __m512i H, M, L, tmp1, tmp2, tmp3; + AesGcmKaratsubaMul4(&blk0, &hKeys3, &hKeysKaratsuba3, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys2, &hKeysKaratsuba2, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk2, &hKeys1, &hKeysKaratsuba1, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk3, &hKeys0, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 4; + pDst512 += 4; + } + + if ((3 * 4) <= blocks) { + __m512i counter0 = _mm512_add_epi32(incMsk, ctr512); + __m512i counter1 = _mm512_add_epi32(M512(inc4_lo32x4), counter0); + __m512i counter2 = _mm512_add_epi32(M512(inc4_lo32x4), counter1); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter2; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, M512(swapBytes)); + counter2 = _mm512_shuffle_epi8(counter2, M512(swapBytes)); + + cpAESEncrypt3_VAES_NI(&counter0, &counter1, &counter2, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + __m512i blk2 = _mm512_loadu_si512(pSrc512 + 2); + + _mm512_storeu_si512(pDst512, _mm512_xor_si512(blk0, counter0)); + _mm512_storeu_si512(pDst512 + 1, _mm512_xor_si512(blk1, counter1)); + _mm512_storeu_si512(pDst512 + 2, _mm512_xor_si512(blk2, counter2)); + + /* Authenticate */ + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + blk2 = _mm512_shuffle_epi8(blk2, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + /* Karatsuba multiplication for 16 blocks with postponed aggregation */ + __m512i H, M, L, tmp1, tmp2, tmp3; + AesGcmKaratsubaMul4(&blk0, &hKeys3, &hKeysKaratsuba2, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys2, &hKeysKaratsuba1, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk2, &hKeys1, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 3; + pDst512 += 3; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + __m512i counter0 = _mm512_add_epi32(incMsk, ctr512); + __m512i counter1 = _mm512_add_epi32(M512(inc4_lo32x4), counter0); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter1; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, M512(swapBytes)); + + cpAESEncrypt2_VAES_NI(&counter0, &counter1, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + __m512i blk1 = _mm512_loadu_si512(pSrc512 + 1); + + _mm512_storeu_si512(pDst512, _mm512_xor_si512(blk0, counter0)); + _mm512_storeu_si512(pDst512 + 1, _mm512_xor_si512(blk1, counter1)); + + /* Authenticate */ + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + __m512i H, M, L, tmp1, tmp2, tmp3; + AesGcmKaratsubaMul4(&blk0, &hKeys1, &hKeysKaratsuba1, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys0, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 2; + pDst512 += 2; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + __m512i counter0 = _mm512_add_epi32(incMsk, ctr512); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter0; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + __m512i blk0 = _mm512_loadu_si512(pSrc512); + _mm512_storeu_si512(pDst512, _mm512_xor_si512(blk0, counter0)); + + /* Authenticate */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + __m512i H, M, L; + AesGcmKaratsubaMul4(&blk0, &hKeys0, &hKeysKaratsuba0, &H, &M, &L); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 1; + pDst512 += 1; + } + + if (blocks) { + __mmask8 k8 = (__mmask8)((1 << (blocks + blocks)) - 1); // 64-bit chunks + __mmask16 k16 = (__mmask16)((1 << (blocks << 2)) - 1); // 32-bit chunks + __mmask64 k64 = (__mmask64)((1LL << (blocks << 4)) - 1); // 8-bit chunks + + __m512i counter0 = _mm512_maskz_add_epi32(k16, incMsk, ctr512); + ctr512 = counter0; + + // convert back to big-endian + counter0 = _mm512_maskz_shuffle_epi8(k64, counter0, M512(swapBytes)); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + __m512i blk0 = _mm512_maskz_loadu_epi64(k8, pSrc512); + _mm512_mask_storeu_epi64(pDst512, k8, _mm512_maskz_xor_epi64(k8, blk0, counter0)); + + /* Authenticate */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + __m512i H = _mm512_setzero_si512(); + __m512i M = _mm512_setzero_si512(); + __m512i L = _mm512_setzero_si512(); + + // NB: we need immediate parameter in alignr function + switch (blocks) { + case 1: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 6); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 6); + break; + } + case 2: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 4); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 4); + break; + } + default: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 2); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 2); + } + } + AesGcmKaratsubaMul4(&blk0, &hKeys0, &hKeysKaratsuba0, &H, &M, &L); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + } + + // return last counter + __mmask8 lastCtrK8 = blocks == 0 ? 0xC0 : (__mmask8)((Ipp8u)0x03<<((blocks-1)<<1)); + __mmask16 lastCtrK16 = blocks == 0 ? 0xF000 : (__mmask16)((Ipp16u)0xF<<((blocks-1)<<2)); + __mmask64 lastCtrK64 = blocks == 0 ? 0xFFFF000000000000 : (__mmask64)((Ipp64u)0xFFFF<<((blocks-1)<<4)); + + ctr512 = _mm512_maskz_add_epi32(lastCtrK16, M512(inc1_lo32x4), ctr512); + ctr512 = _mm512_maskz_shuffle_epi8(lastCtrK64, ctr512, M512(swapBytes)); + + /* save next counter */ + _mm512_mask_compressstoreu_epi64(pCtrValue, lastCtrK8, ctr512); + + /* save current ghash value */ + ghash512 = _mm512_shuffle_epi8(ghash512, M512(swapBytes)); + _mm512_mask_storeu_epi64(pGHash, 0x03, ghash512); +} + +#endif + +#endif /* #if (_IPP32E>=_IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmencrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmencrypt.c new file mode 100644 index 000000000..9312a29c0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmencrypt.c @@ -0,0 +1,216 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMEncrypt() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMEncrypt +// +// Purpose: Encrypts a data buffer in the GCM mode. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pDst == NULL +// pState == NULL +// ippStsContextMatchErr !AESGCM_VALID_ID() +// ippStsLengthErr len<0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc Pointer to plaintext. +// pDst Pointer to ciphertext. +// len Length of the plaintext and ciphertext in bytes +// pState pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + IppsAES_GCMState* pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + /* use aligned context */ + pState = (IppsAES_GCMState*)( IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT) ); + /* test state ID */ + IPP_BADARG_RET(!AESGCM_VALID_ID(pState), ippStsContextMatchErr); + /* test context validity */ + IPP_BADARG_RET(!(GcmAADprocessing==AESGCM_STATE(pState) || GcmTXTprocessing==AESGCM_STATE(pState)), ippStsBadArgErr); + + /* test text pointers and length */ + IPP_BAD_PTR2_RET(pSrc, pDst); + IPP_BADARG_RET(len<0, ippStsLengthErr); + + /* According to the NIST Special Publication 800-38D (Recommendation for GCM + * mode, p.5.2.1.1 Input Data) the input text shall be between 0 and 2^39-256 + * bits. */ + const Ipp64u MAX_TXT_LEN = ((Ipp64u)1 << 36) - 32; /* length in bytes */ + IPP_BADARG_RET(((AESGCM_TXT_LEN(pState) > MAX_TXT_LEN - (Ipp64u)len) || + ((AESGCM_TXT_LEN(pState) + (Ipp64u)len) < (Ipp64u)len)), + ippStsScaleRangeErr); + +#if(_IPP32E<_IPP32E_K0) + /* get method */ + IppsAESSpec* pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + MulGcm_ hashFunc = AESGCM_HASH(pState); +#endif + + if( GcmAADprocessing==AESGCM_STATE(pState) ) { +#if(_IPP32E>=_IPP32E_K0) + if(AESGCM_BUFLEN(pState)) { + MulGcm_ ghashFunc = AES_GCM_GMUL(pState); + ghashFunc(&AES_GCM_KEY_DATA(pState), AESGCM_GHASH(pState)); + } +#else + /* complete AAD processing */ + if(AESGCM_BUFLEN(pState)) + hashFunc(AESGCM_GHASH(pState), AESGCM_HKEY(pState), AesGcmConst_table); + + /* increment counter block */ + IncrementCounter32(AESGCM_COUNTER(pState)); + /* and encrypt counter */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + /* switch mode and init counters */ + AESGCM_STATE(pState) = GcmTXTprocessing; + AESGCM_TXT_LEN(pState) = CONST_64(0); + AESGCM_BUFLEN(pState) = 0; + } + + /* execute encryption with code from Intel IPsec if possible */ +#if(_IPP32E>=_IPP32E_K0) + EncryptUpdate_ enc = AES_GCM_ENCRYPT_UPDATE(pState); +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* Mistletoe3 mitigation */ + cpAESNoiseParams *params = (cpAESNoiseParams*)&AESGCM_NOISE_PARAMS(pState); + if (AES_NOISE_LEVEL(params) > 0) { + /* Number of bytes allowed for operation without adding noise */ + int chunk_size; + /* Number of bytes remaining for operation */ + int remaining_size = len; + + while (remaining_size > 0) { + /* How many bytes to encrypt in this operation */ + chunk_size = (remaining_size >= MISTLETOE3_MAX_CHUNK_SIZE) ? MISTLETOE3_MAX_CHUNK_SIZE : remaining_size; + + enc(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), pDst, pSrc, (Ipp64u)chunk_size); + + cpAESRandomNoise(NULL, + MISTLETOE3_BASE_NOISE_LEVEL + AES_NOISE_LEVEL(params), + MISTLETOE3_NOISE_RATE, + &AES_NOISE_RAND(params)); + + pSrc += chunk_size; + pDst += chunk_size; + remaining_size -= chunk_size; + } + } else +#endif + { + enc(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), pDst, pSrc, (Ipp64u)len); + } +#else + /* + // process text (encrypt and authenticate) + */ + + /* process partial block */ + if(AESGCM_BUFLEN(pState)) { + int locLen = IPP_MIN(len, BLOCK_SIZE-AESGCM_BUFLEN(pState)); + /* ctr encryption */ + XorBlock(pSrc, AESGCM_ECOUNTER(pState)+AESGCM_BUFLEN(pState), pDst, locLen); + /* authentication */ + XorBlock(pDst, AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), locLen); + + AESGCM_BUFLEN(pState) += locLen; + AESGCM_TXT_LEN(pState) += (Ipp64u)locLen; + pSrc += locLen; + pDst += locLen; + len -= locLen; + + /* if buffer full */ + if(BLOCK_SIZE==AESGCM_BUFLEN(pState)) { + /* hash buffer */ + hashFunc(AESGCM_GHASH(pState), AESGCM_HKEY(pState), AesGcmConst_table); + AESGCM_BUFLEN(pState) = 0; + + /* increment counter block */ + IncrementCounter32(AESGCM_COUNTER(pState)); + /* and encrypt counter */ + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + } + + /* process the main part of text */ + { + int lenBlks = len & (-BLOCK_SIZE); + if(lenBlks) { + Encrypt_ encFunc = AESGCM_ENC(pState); + + encFunc(pDst, pSrc, lenBlks, pState); + + AESGCM_TXT_LEN(pState) += (Ipp64u)lenBlks; + pSrc += lenBlks; + pDst += lenBlks; + len -= lenBlks; + } + } + + /* process the rest of text */ + if(len) { + XorBlock(pSrc, AESGCM_ECOUNTER(pState)+AESGCM_BUFLEN(pState), pDst, len); + XorBlock(pDst, AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), len); + + AESGCM_BUFLEN(pState) += len; + AESGCM_TXT_LEN(pState) += (Ipp64u)len; + } +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmencrypt_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmencrypt_vaes512.c new file mode 100755 index 000000000..3778cf0be --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmencrypt_vaes512.c @@ -0,0 +1,362 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption (GCM mode) +// +// Contents: +// +*/ + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4206) // empty translation unit in MSVC +#endif + +#if 0 // Not used + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" +#include "pcpaes_gcm_vaes512.h" +#include "pcpaesauthgcm.h" + +#if (_IPP32E>=_IPP32E_K1) + +static __ALIGN64 Ipp32u inc_lo32x4[] = { 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0 }; +static __ALIGN64 Ipp32u inc1_lo32x4[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 }; +static __ALIGN64 Ipp32u inc4_lo32x4[] = { 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0 }; + +/* Encryption with authentication */ +IPP_OWN_DEFN (void, AesGcmEnc_vaes, (Ipp8u* pDst, const Ipp8u* pSrc, int length, IppsAES_GCMState* pCtx)) +{ + IppsAESSpec* pAES = AESGCM_CIPHER(pCtx); + int cipherRounds = RIJ_NR(pAES) - 1; + const Ipp8u* pRKey = RIJ_EKEYS(pAES); + + Ipp8u* pCtrValue = AESGCM_COUNTER(pCtx); + Ipp8u* pGHash = AESGCM_GHASH(pCtx); + const Ipp8u* pHKey = AESGCM_HKEY(pCtx); + + __m128i* pKeys = (__m128i*)pRKey; + __m512i* pSrc512 = (__m512i*)pSrc; + __m512i* pDst512 = (__m512i*)pDst; + __m512i* pHKey512 = (__m512i*)pHKey; + + __m512i incMsk = M512(inc_lo32x4); + + __m512i H, M, L, tmp1, tmp2, tmp3; + __m512i counter0, counter1, counter2, counter3; + __m512i blk0, blk1, blk2, blk3; + + /* Load hKeys vectors */ + __m512i hKeys0 = _mm512_loadu_si512(pHKey512); + __m512i hKeys1 = _mm512_loadu_si512(pHKey512 + 1); + __m512i hKeys2 = _mm512_loadu_si512(pHKey512 + 2); + __m512i hKeys3 = _mm512_loadu_si512(pHKey512 + 3); + + /* Load precomputed multipliers for Karatsuba multiplication */ + __m512i hKeysKaratsuba0 = _mm512_loadu_si512(pHKey512 + 4); + __m512i hKeysKaratsuba1 = _mm512_loadu_si512(pHKey512 + 5); + __m512i hKeysKaratsuba2 = _mm512_loadu_si512(pHKey512 + 6); + __m512i hKeysKaratsuba3 = _mm512_loadu_si512(pHKey512 + 7); + + /* Current GHASH value */ + __m128i ghash128; + __m512i ghash512 = _mm512_maskz_loadu_epi64(0x03, pGHash); + ghash512 = _mm512_shuffle_epi8(ghash512, M512(swapBytes)); + + /* Load initial counter */ + __m128i ctr128 = _mm_maskz_loadu_epi64(0x03, pCtrValue); + __m512i ctr512 = _mm512_broadcast_i64x2(ctr128); + + // convert counter to little-endian + ctr512 = _mm512_shuffle_epi8(ctr512, M512(swapBytes)); + + int blocks; + for (blocks = length / MBS_RIJ128; blocks >= (4 * 4); blocks -= (4 * 4)) { + counter0 = _mm512_add_epi32(incMsk, ctr512); + counter1 = _mm512_add_epi32(M512(inc4_lo32x4), counter0); + counter2 = _mm512_add_epi32(M512(inc4_lo32x4), counter1); + counter3 = _mm512_add_epi32(M512(inc4_lo32x4), counter2); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter3; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, M512(swapBytes)); + counter2 = _mm512_shuffle_epi8(counter2, M512(swapBytes)); + counter3 = _mm512_shuffle_epi8(counter3, M512(swapBytes)); + + cpAESEncrypt4_VAES_NI(&counter0, &counter1, &counter2, &counter3, pKeys, cipherRounds); + + blk0 = _mm512_loadu_si512(pSrc512); + blk1 = _mm512_loadu_si512(pSrc512 + 1); + blk2 = _mm512_loadu_si512(pSrc512 + 2); + blk3 = _mm512_loadu_si512(pSrc512 + 3); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + blk2 = _mm512_xor_si512(blk2, counter2); + blk3 = _mm512_xor_si512(blk3, counter3); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + _mm512_storeu_si512(pDst512 + 3, blk3); + + /* Authenticate */ + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + blk2 = _mm512_shuffle_epi8(blk2, M512(swapBytes)); + blk3 = _mm512_shuffle_epi8(blk3, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + /* Karatsuba multiplication for 16 blocks with postponed aggregation */ + AesGcmKaratsubaMul4(&blk0, &hKeys3, &hKeysKaratsuba3, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys2, &hKeysKaratsuba2, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk2, &hKeys1, &hKeysKaratsuba1, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk3, &hKeys0, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 4; + pDst512 += 4; + } + + if ((3 * 4) <= blocks) { + counter0 = _mm512_add_epi32(incMsk, ctr512); + counter1 = _mm512_add_epi32(M512(inc4_lo32x4), counter0); + counter2 = _mm512_add_epi32(M512(inc4_lo32x4), counter1); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter2; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, M512(swapBytes)); + counter2 = _mm512_shuffle_epi8(counter2, M512(swapBytes)); + + cpAESEncrypt3_VAES_NI(&counter0, &counter1, &counter2, pKeys, cipherRounds); + + blk0 = _mm512_loadu_si512(pSrc512); + blk1 = _mm512_loadu_si512(pSrc512 + 1); + blk2 = _mm512_loadu_si512(pSrc512 + 2); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + blk2 = _mm512_xor_si512(blk2, counter2); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + _mm512_storeu_si512(pDst512 + 2, blk2); + + /* Authenticate */ + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + blk2 = _mm512_shuffle_epi8(blk2, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + /* Karatsuba multiplication for 16 blocks with postponed aggregation */ + AesGcmKaratsubaMul4(&blk0, &hKeys3, &hKeysKaratsuba2, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys2, &hKeysKaratsuba1, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + AesGcmKaratsubaMul4(&blk2, &hKeys1, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 3; + pDst512 += 3; + blocks -= (3 * 4); + } + + if ((4 * 2) <= blocks) { + counter0 = _mm512_add_epi32(incMsk, ctr512); + counter1 = _mm512_add_epi32(M512(inc4_lo32x4), counter0); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter1; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + counter1 = _mm512_shuffle_epi8(counter1, M512(swapBytes)); + + cpAESEncrypt2_VAES_NI(&counter0, &counter1, pKeys, cipherRounds); + + blk0 = _mm512_loadu_si512(pSrc512); + blk1 = _mm512_loadu_si512(pSrc512 + 1); + + blk0 = _mm512_xor_si512(blk0, counter0); + blk1 = _mm512_xor_si512(blk1, counter1); + + _mm512_storeu_si512(pDst512, blk0); + _mm512_storeu_si512(pDst512 + 1, blk1); + + /* Authenticate */ + /* Reflect inputs */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + blk1 = _mm512_shuffle_epi8(blk1, M512(swapBytes)); + + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + AesGcmKaratsubaMul4(&blk0, &hKeys1, &hKeysKaratsuba1, &H, &M, &L); + AesGcmKaratsubaMul4(&blk1, &hKeys0, &hKeysKaratsuba0, &tmp1, &tmp2, &tmp3); + H = _mm512_xor_si512(H, tmp1); + M = _mm512_xor_si512(M, tmp2); + L = _mm512_xor_si512(L, tmp3); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 2; + pDst512 += 2; + blocks -= (2 * 4); + } + + for (; blocks >= 4; blocks -= 4) { + counter0 = _mm512_add_epi32(incMsk, ctr512); + + incMsk = M512(inc4_lo32x4); + ctr512 = counter0; + + // convert back to big-endian + counter0 = _mm512_shuffle_epi8(counter0, M512(swapBytes)); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + blk0 = _mm512_loadu_si512(pSrc512); + blk0 = _mm512_xor_si512(blk0, counter0); + _mm512_storeu_si512(pDst512, blk0); + + /* Authenticate */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + AesGcmKaratsubaMul4(&blk0, &hKeys0, &hKeysKaratsuba0, &H, &M, &L); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + + pSrc512 += 1; + pDst512 += 1; + } + + if (blocks) { + __mmask8 k8 = (__mmask8)((1 << (blocks + blocks)) - 1); // 64-bit chunks + __mmask16 k16 = (__mmask16)((1 << (blocks << 2)) - 1); // 32-bit chunks + __mmask64 k64 = (__mmask64)((1LL << (blocks << 4)) - 1); // 8-bit chunks + + counter0 = _mm512_maskz_add_epi32(k16, incMsk, ctr512); + ctr512 = counter0; + + // convert back to big-endian + counter0 = _mm512_maskz_shuffle_epi8(k64, counter0, M512(swapBytes)); + + cpAESEncrypt1_VAES_NI(&counter0, pKeys, cipherRounds); + + blk0 = _mm512_maskz_loadu_epi64(k8, pSrc512); + blk0 = _mm512_maskz_xor_epi64(k8, blk0, counter0); + _mm512_mask_storeu_epi64(pDst512, k8, blk0); + + /* Authenticate */ + blk0 = _mm512_shuffle_epi8(blk0, M512(swapBytes)); + /* Add current GHASH to src[0] */ + blk0 = _mm512_mask_xor_epi64(blk0, 0x03, blk0, ghash512); + + H = _mm512_setzero_si512(); + M = _mm512_setzero_si512(); + L = _mm512_setzero_si512(); + + // NB: we need immediate parameter in alignr function + switch (blocks) { + case 1: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 6); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 6); + break; + } + case 2: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 4); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 4); + break; + } + default: { + hKeys0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeys0, 2); + hKeysKaratsuba0 = _mm512_alignr_epi64(_mm512_setzero_si512(), hKeysKaratsuba0, 2); + } + } + AesGcmKaratsubaMul4(&blk0, &hKeys0, &hKeysKaratsuba0, &H, &M, &L); + + AggregateKaratsubaPartialProducts(&H, &M, &L, &ghash128); + + /* save current ghash value */ + ghash512 = _mm512_castsi128_si512(ghash128); + } + + // return last counter + __mmask8 lastCtrK8 = blocks == 0 ? 0xC0 : (__mmask8)((Ipp8u)0x03<<((blocks-1)<<1)); + __mmask16 lastCtrK16 = blocks == 0 ? 0xF000 : (__mmask16)((Ipp16u)0xF<<((blocks-1)<<2)); + __mmask64 lastCtrK64 = blocks == 0 ? 0xFFFF000000000000 : (__mmask64)((Ipp64u)0xFFFF<<((blocks-1)<<4)); + + ctr512 = _mm512_maskz_add_epi32(lastCtrK16, M512(inc1_lo32x4), ctr512); + ctr512 = _mm512_maskz_shuffle_epi8(lastCtrK64, ctr512, M512(swapBytes)); + + /* save next counter */ + _mm512_mask_compressstoreu_epi64(pCtrValue, lastCtrK8, ctr512); + + /* save current ghash value */ + ghash512 = _mm512_shuffle_epi8(ghash512, M512(swapBytes)); + _mm512_mask_storeu_epi64(pGHash, 0x03, ghash512); +} + +#endif + +#endif /* #if (_IPP32E>=_IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmgetsize.c new file mode 100644 index 000000000..e5b566c42 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmgetsize.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMGetSize +// +// Purpose: Returns size of AES_GCM state (in bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to size of context +// +*F*/ + +IPPFUN(IppStatus, ippsAES_GCMGetSize,(int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = cpSizeofCtx_AESGCM(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmgettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmgettag.c new file mode 100644 index 000000000..de23cf552 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmgettag.c @@ -0,0 +1,111 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMGetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMGetTag +// +// Purpose: Generates authentication tag in the GCM mode. +// +// Returns: Reason: +// ippStsNullPtrErr pDstTag == NULL +// pState == NULL +// ippStsLengthErr tagLen<=0 || tagLen>16 +// ippStsContextMatchErr !AESGCM_VALID_ID() +// ippStsNoErr no errors +// +// Parameters: +// pDstTag pointer to the authentication tag. +// tagLen length of the authentication tag *pDstTag in bytes +// pState pointer to the context +// +*F*/ + +IPPFUN(IppStatus, ippsAES_GCMGetTag,(Ipp8u* pDstTag, int tagLen, const IppsAES_GCMState* pState)) +{ + /* test State pointer */ + IPP_BAD_PTR1_RET(pState); + /* use aligned context */ + pState = (IppsAES_GCMState*)( IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT) ); + /* test state ID */ + IPP_BADARG_RET(!AESGCM_VALID_ID(pState), ippStsContextMatchErr); + + /* test tag pointer and length */ + IPP_BAD_PTR1_RET(pDstTag); + IPP_BADARG_RET(tagLen<=0 || tagLen>BLOCK_SIZE, ippStsLengthErr); + +#if(_IPP32E>=_IPP32E_K0) + GetTag_ getTag = AES_GCM_GET_TAG(pState); + getTag(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), pDstTag, (Ipp64u)tagLen); +#else + /* get method */ + MulGcm_ hashFunc = AESGCM_HASH(pState); + + __ALIGN16 Ipp8u tmpHash[BLOCK_SIZE]; + Ipp8u tmpCntr[BLOCK_SIZE]; + + /* local copy of AAD and text counters (in bits) */ + Ipp64u aadBitLen = AESGCM_AAD_LEN(pState)*BYTESIZE; + Ipp64u txtBitLen = AESGCM_TXT_LEN(pState)*BYTESIZE; + + /* do local copy of ghash */ + CopyBlock16(AESGCM_GHASH(pState), tmpHash); + + /* complete text processing */ + if(AESGCM_BUFLEN(pState)) { + hashFunc(tmpHash, AESGCM_HKEY(pState), AesGcmConst_table); + } + + /* process lengths of AAD and text */ + U32_TO_HSTRING(tmpCntr, IPP_HIDWORD(aadBitLen)); + U32_TO_HSTRING(tmpCntr+4, IPP_LODWORD(aadBitLen)); + U32_TO_HSTRING(tmpCntr+8, IPP_HIDWORD(txtBitLen)); + U32_TO_HSTRING(tmpCntr+12,IPP_LODWORD(txtBitLen)); + + XorBlock16(tmpHash, tmpCntr, tmpHash); + hashFunc(tmpHash, AESGCM_HKEY(pState), AesGcmConst_table); + + /* add encrypted initial counter */ + XorBlock16(tmpHash, AESGCM_ECOUNTER0(pState), tmpHash); + + /* return tag of required length */ + CopyBlock(tmpHash, pDstTag, tagLen); +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcminit.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcminit.c new file mode 100644 index 000000000..92d81f6b0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcminit.c @@ -0,0 +1,179 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMInit() +// +*/ + +#include "aes_gcm_avx512.h" +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaesminit_internal.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#include "aes_keyexp.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMInit +// +// Purpose: Init AES_GCM context for future usage. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsMemAllocErr size of buffer is not match fro operation +// ippStsLengthErr keyLen != 16 && +// != 24 && +// != 32 +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length of secret key +// pState pointer to the AES-GCM context +// ctxSize available size (in bytes) of buffer above +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMInit,(const Ipp8u* pKey, int keyLen, IppsAES_GCMState* pState, int ctxSize)) +{ + /* test pCtx pointer */ + IPP_BAD_PTR1_RET(pState); + + /* test available size of context buffer */ + IPP_BADARG_RET(ctxSize=_IPP32E_K0) + AES_GCM_KEY_LEN(pState) = (Ipp64u)keyLen; + + Ipp8u zeroKey[32] = {0}; + const Ipp8u* pActualKey = pKey? pKey : zeroKey; + +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* Reset AES noise parameters */ + cpAESNoiseParams *params = (cpAESNoiseParams *)&AESGCM_NOISE_PARAMS(pState); + + AES_NOISE_RAND(params) = 0; + AES_NOISE_LEVEL(params) = 0; +#endif + if (IsFeatureEnabled(ippCPUID_AVX512VAES) && IsFeatureEnabled(ippCPUID_AVX512VCLMUL)) { + + switch AES_GCM_KEY_LEN(pState) { + case 16: + aes_keyexp_128_enc(pActualKey, &AES_GCM_KEY_DATA(pState)); + aes_gcm_precomp_128_vaes_avx512(&AES_GCM_KEY_DATA(pState)); + break; + case 24: + aes_keyexp_192_enc(pActualKey, &AES_GCM_KEY_DATA(pState)); + aes_gcm_precomp_192_vaes_avx512(&AES_GCM_KEY_DATA(pState)); + break; + case 32: + aes_keyexp_256_enc(pActualKey, &AES_GCM_KEY_DATA(pState)); + aes_gcm_precomp_256_vaes_avx512(&AES_GCM_KEY_DATA(pState)); + break; + } + } else { + + switch AES_GCM_KEY_LEN(pState) { + case 16: + aes_keyexp_128_enc(pActualKey, &AES_GCM_KEY_DATA(pState)); + aes_gcm_precomp_128_avx512(&AES_GCM_KEY_DATA(pState)); + break; + case 24: + aes_keyexp_192_enc(pActualKey, &AES_GCM_KEY_DATA(pState)); + aes_gcm_precomp_192_avx512(&AES_GCM_KEY_DATA(pState)); + break; + case 32: + aes_keyexp_256_enc(pActualKey, &AES_GCM_KEY_DATA(pState)); + aes_gcm_precomp_256_avx512(&AES_GCM_KEY_DATA(pState)); + break; + } + } + +#else + + /* init cipher */ + { + IppStatus sts = ippsAESInit(pKey, keyLen, AESGCM_CIPHER(pState), cpSizeofCtx_AES()); + if(ippStsNoErr!=sts) + return sts; + } + + /* precomputations (for constant multiplier(s)) */ + { + IppsAESSpec* pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + /* multiplier c = Enc({0}) */ + PadBlock(0, AESGCM_HKEY(pState), BLOCK_SIZE); + //encoder((Ipp32u*)AESGCM_HKEY(pState), (Ipp32u*)AESGCM_HKEY(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(AESGCM_HKEY(pState), AESGCM_HKEY(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(AESGCM_HKEY(pState), AESGCM_HKEY(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + // the dead code that currently is unused + //#if(_IPP32E>=_IPP32E_K0) + //if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + // /* pre-compute hKey<<1, (hKey<<1)^2, (hKey<<1)^3, ... , (hKey<<1)^15 and corresponding + // Karatsuba constant multipliers for aggregated reduction */ + // AesGcmPrecompute_vaes(AESGCM_CPWR(pState), AESGCM_HKEY(pState)); + //} + //else + //#endif /* #if(_IPP32E>=_IPP32E_K0) */ + if(IsFeatureEnabled(ippCPUID_AES|ippCPUID_CLMUL) || IsFeatureEnabled(ippCPUID_AVX2VAES|ippCPUID_AVX2VCLMUL)) { + /* pre-compute reflect(hkey) and hKey<<1, (hKey<<1)^2 and (hKey<<1)^4 powers of hKey */ + AesGcmPrecompute_avx(AESGCM_CPWR(pState), AESGCM_HKEY(pState)); + } + else + #endif + AesGcmPrecompute_table2K(AES_GCM_MTBL(pState), AESGCM_HKEY(pState)); + #endif /* #if(_IPP32E>=_IPP32E_K0) */ + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmmul_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmmul_vaes512.c new file mode 100644 index 000000000..8f5fa85f8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmmul_vaes512.c @@ -0,0 +1,242 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES GFMUL and GHASH (GCM mode) +// +// Contents: +// +*/ + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4206) // empty translation unit in MSVC +#endif + +#if 0 // Not used + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaes_encrypt_vaes512.h" +#include "pcpaes_gcm_vaes512.h" +#include "pcpaesauthgcm.h" + +#if (_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // cast truncates constant value in MSVC +#endif + +/* The function calculates multiplication of two 2x128-bit polynomials C = A*B with + polynomial reduction. 2 polynomials can be processed at one call. + The inputs are bit-reflected. The result is bit-reflected. + */ +__INLINE void AesGcmGhash2(const __m256i* const src1, + const __m256i* const src2, + __m256i * const result) +{ + __m256i tmp1, tmp2, tmp3, tmp4; + +#if 0 + /* School-book multiplication */ + tmp1 = _mm256_clmulepi64_epi128(src2, src1, 0x00); // [C1:C0] + tmp2 = _mm256_clmulepi64_epi128(src2, src1, 0x11); // [D1:D0] + tmp3 = _mm256_clmulepi64_epi128(src2, src1, 0x10); // [F1:F0] + tmp4 = _mm256_clmulepi64_epi128(src2, src1, 0x01); // [E1:E0] + + tmp3 = _mm256_xor_si256(tmp4, tmp3); + + tmp4 = _mm256_bslli_epi128(tmp3, 8); + tmp3 = _mm256_bsrli_epi128(tmp3, 8); + tmp1 = _mm256_xor_si256(tmp4, tmp1); + tmp4 = _mm256_xor_si256(tmp3, tmp2); +#endif + + /* Karatsuba multiplication */ + tmp1 = _mm256_clmulepi64_epi128(*src2, *src1, 0x00); + tmp4 = _mm256_clmulepi64_epi128(*src2, *src1, 0x11); + + tmp2 = _mm256_shuffle_epi32(*src2, 78); // 78 = 01001110b + tmp3 = _mm256_shuffle_epi32(*src1, 78); // 78 = 01001110b + tmp2 = _mm256_xor_si256(tmp2, *src2); + tmp3 = _mm256_xor_si256(tmp3, *src1); + + tmp2 = _mm256_clmulepi64_epi128(tmp2, tmp3, 0x00); + tmp2 = _mm256_xor_si256(tmp2, tmp1); + tmp2 = _mm256_xor_si256(tmp2, tmp4); + + tmp3 = _mm256_bslli_epi128(tmp2, 8); + tmp2 = _mm256_bsrli_epi128(tmp2, 8); + + tmp1 = _mm256_xor_si256(tmp1, tmp3); + tmp4 = _mm256_xor_si256(tmp4, tmp2); + + /* Montgomery reduction */ + tmp2 = _mm256_clmulepi64_epi128(tmp1, M256(POLY2), 0x10); + tmp3 = _mm256_shuffle_epi32(tmp1, 78); // 78 = 01001110b + tmp1 = _mm256_xor_si256(tmp2, tmp3); + + tmp2 = _mm256_clmulepi64_epi128(tmp1, M256(POLY2), 0x10); + tmp3 = _mm256_shuffle_epi32(tmp1, 78); // 78 = 01001110b + tmp1 = _mm256_xor_si256(tmp2, tmp3); + + *result = _mm256_xor_si256(tmp1, tmp4); +} + +/* The function calculates multiplication of two 128-bit polynomials C = A*B with + polynomial reduction. + The inputs are bit-reflected. The result is bit-reflected. + */ +__INLINE void AesGcmGhash(const __m128i* const a, + const __m128i* const b, + __m128i * const result) +{ + __m256i res256; + + __m256i src1 = _mm256_set_m128i(_mm_setzero_si128(), *a); + __m256i src2 = _mm256_set_m128i(_mm_setzero_si128(), *b); + + AesGcmGhash2(&src1, &src2, &res256); + + *result = _mm256_castsi256_si128(res256); +} + +/* The function calculates multiplication of 128-bit polynomials C = A*B with + polynomial reduction. 4 polynomials can be processed at one call. + The inputs are bit-reflected. The result is bit-reflected. + */ +__INLINE void AesGcmGhash4(const __m512i* const src1, + const __m512i* const src2, + __m512i * const result) +{ + __m512i tmp1, tmp2, tmp3, tmp4; + + /* Karatsuba multiplication */ + tmp1 = _mm512_clmulepi64_epi128(*src2, *src1, 0x00); + tmp4 = _mm512_clmulepi64_epi128(*src2, *src1, 0x11); + + tmp2 = _mm512_shuffle_epi32(*src2, 78); // 78 = 01001110b + tmp3 = _mm512_shuffle_epi32(*src1, 78); // 78 = 01001110b + tmp2 = _mm512_xor_si512(tmp2, *src2); + tmp3 = _mm512_xor_si512(tmp3, *src1); + + tmp2 = _mm512_clmulepi64_epi128(tmp2, tmp3, 0x00); + tmp2 = _mm512_xor_si512(tmp2, tmp1); + tmp2 = _mm512_xor_si512(tmp2, tmp4); + + tmp3 = _mm512_bslli_epi128(tmp2, 8); + tmp2 = _mm512_bsrli_epi128(tmp2, 8); + + tmp1 = _mm512_xor_si512(tmp1, tmp3); + tmp4 = _mm512_xor_si512(tmp4, tmp2); + + /* Montgomery reduction */ + tmp2 = _mm512_clmulepi64_epi128(tmp1, M512(POLY2), 0x10); + tmp3 = _mm512_shuffle_epi32(tmp1, 78); // 78 = 01001110b + tmp1 = _mm512_xor_si512(tmp2, tmp3); + + tmp2 = _mm512_clmulepi64_epi128(tmp1, M512(POLY2), 0x10); + tmp3 = _mm512_shuffle_epi32(tmp1, 78); // 78 = 01001110b + tmp1 = _mm512_xor_si512(tmp2, tmp3); + + *result = _mm512_xor_si512(tmp1, tmp4); +} + +/* The function performs single A*(Hash<<1 mod poly) multiplication */ +IPP_OWN_DEFN (void, AesGcmMulGcm_vaes, (Ipp8u* pGHash, const Ipp8u* pHKey, const void * pParam)) +{ + IPP_UNREFERENCED_PARAMETER(pParam); + + __m128i ghash = _mm_maskz_loadu_epi64(0x03, pGHash); + __m128i hkey = _mm_maskz_loadu_epi64(0x03, pHKey + 16*3); // NB: hKey is at index 3 in the array + + ghash = _mm_maskz_shuffle_epi8((Ipp16u)(-1), ghash, M128(swapBytes)); + AesGcmGhash(&ghash, &hkey, &ghash); + ghash = _mm_maskz_shuffle_epi8((Ipp16u)(-1), ghash, M128(swapBytes)); + + _mm_mask_storeu_epi64(pGHash, (Ipp8u)(-1), ghash); +} + +/* The function computes reflected hKey<<1, hKey^2<<1, hKey^3<<1, ..., hKey^16<<1 - all mod poly + * to use in batch GHASH calculation. + * It also pre-computes parts of Karatsuba multipliers that are fixed and derived from the hKey. + */ +IPP_OWN_DEFN (void, AesGcmPrecompute_vaes, (Ipp8u* const pHtbl, const Ipp8u* const hKey)) +{ + /* Initial hKey = E_ctr(key, 0^16) */ + __m128i* pDst = (__m128i*)pHtbl; + + __m128i xmm0, xmm1; + __m256i ymm0, ymm1, ymm3, ymm4, ymm5; + __m512i zmm0, zmm1, zmm2; + + /* Load initial hKey = E_ctr(key,0^16) */ + ymm0 = _mm256_maskz_loadu_epi64(0x03, hKey); + /* Reflect hKey */ + ymm0 = _mm256_shuffle_epi8(ymm0, M256(swapBytes)); + + /* Compute reflected hKey<<1 mod poly */ + ymm3 = _mm256_srai_epi32(ymm0, 31); + ymm3 = _mm256_shuffle_epi32(ymm3, 0xFF); + ymm5 = _mm256_and_si256(ymm3, M256(POLY2)); + ymm3 = _mm256_srli_epi32(ymm0, 31); + ymm4 = _mm256_slli_epi32(ymm0, 1); + ymm3 = _mm256_bslli_epi128(ymm3, 4); + ymm0 = _mm256_xor_si256(ymm4, ymm3); + ymm0 = _mm256_xor_si256(ymm0,ymm5); + + xmm0 = _mm256_castsi256_si128(ymm0); + + AesGcmGhash(&xmm0, &xmm0, &xmm1); /* xmm1 = hKey^2 */ + + ymm0 = _mm256_broadcast_i64x2(xmm1); /* ymm0 = hKey^2 hKey^2 */ + ymm1 = _mm256_set_m128i(xmm0, xmm1); /* ymm1 = hKey hKey^2 */ + AesGcmGhash2(&ymm0, &ymm1, &ymm0); /* ymm0 = hKey^3 hKey^4 */ + + xmm1 = _mm256_extracti64x2_epi64(ymm0, 0); /* xmm1 = hKey^4 */ + + zmm0 = _mm512_setzero_si512(); + zmm0 = _mm512_inserti64x4(zmm0, ymm1, 1); /* zmm0 = hKey hKey^2 0 0 */ + zmm0 = _mm512_inserti64x4(zmm0, ymm0, 0); /* zmm0 = hKey hKey^2 hKey^3 hKey^4 */ + zmm1 = _mm512_broadcast_i64x2(xmm1); /* zmm1 = hKey^4 hKey^4 hKey^4 hKey^4 */ + + /* Store 4xhKey<<1 mod poly degrees in precompute table */ + _mm512_storeu_si512(pDst, zmm0); + + /* Prepare constant multipliers for Karatsuba (Bh^Bl) */ + zmm2 = _mm512_shuffle_epi32(zmm0, 78); + zmm2 = _mm512_xor_si512(zmm0, zmm2); + _mm512_storeu_si512(pDst + 16, zmm2); + + for (int i = 1; i < 4; i++) + { + AesGcmGhash4(&zmm0, &zmm1, &zmm0); + + /* Store 4xhKey<<1 mod poly degrees in precompute table */ + _mm512_storeu_si512(pDst + 4*i, zmm0); + + /* Prepare constant multipliers for Karatsuba (Bh^Bl) */ + zmm2 = _mm512_shuffle_epi32(zmm0, 78); + zmm2 = _mm512_xor_si512(zmm0, zmm2); + _mm512_storeu_si512(pDst + 4*i + 16, zmm2); + } +} + +#endif /* #if (_IPP32E>=_IPP32E_K1) */ + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmprocessaad.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmprocessaad.c new file mode 100644 index 000000000..f87fdead8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmprocessaad.c @@ -0,0 +1,224 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMProcessAAD() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMProcessAAD +// +// Purpose: AAD processing. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pAAD == NULL, aadLen>0 +// ippStsContextMatchErr !AESGCM_VALID_ID() +// ippStsLengthErr aadLen <0 +// ippStsBadArgErr illegal sequence call +// ippStsNoErr no errors +// +// Parameters: +// pAAD pointer to the AAD +// aadlen length of AAD (it could be 0) +// pState pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMProcessAAD,(const Ipp8u* pAAD, int aadLen, IppsAES_GCMState* pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + /* use aligned context */ + pState = (IppsAES_GCMState*)( IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT) ); + /* test if context is valid */ + IPP_BADARG_RET(!AESGCM_VALID_ID(pState), ippStsContextMatchErr); + + /* test AAD pointer and length */ + IPP_BADARG_RET(aadLen && !pAAD, ippStsNullPtrErr); + IPP_BADARG_RET(aadLen<0, ippStsLengthErr); + + /* According to the NIST Special Publication 800-38D (Recommendation for GCM + * mode, p.5.2.1.1 Input Data) the AAD shall be between 0 and 2^64 bits. */ + IPP_BADARG_RET(((AESGCM_AAD_LEN(pState) + (Ipp64u)aadLen) < (Ipp64u)aadLen), ippStsScaleRangeErr); + + IPP_BADARG_RET(!(GcmIVprocessing==AESGCM_STATE(pState) || GcmAADprocessing==AESGCM_STATE(pState)), ippStsBadArgErr); + + if( GcmIVprocessing==AESGCM_STATE(pState) ) { + IPP_BADARG_RET(0==AESGCM_IV_LEN(pState), ippStsBadArgErr); + +#if(_IPP32E>=_IPP32E_K0) + IvFinalize_ ivHashFinalize = AES_GCM_IV_FINALIZE(pState); + + /* complete IV processing */ + ivHashFinalize(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), + AESGCM_COUNTER(pState), (Ipp64u)AESGCM_BUFLEN(pState), AESGCM_IV_LEN(pState)); +#else + /* complete IV processing */ + if(CTR_POS==AESGCM_IV_LEN(pState)) { + /* apply special format if IV length is 12 bytes */ + AESGCM_COUNTER(pState)[12] = 0; + AESGCM_COUNTER(pState)[13] = 0; + AESGCM_COUNTER(pState)[14] = 0; + AESGCM_COUNTER(pState)[15] = 1; + } else { + /* get method */ + MulGcm_ hashFunc = AESGCM_HASH(pState); + + /* process the rest of IV */ + if(AESGCM_BUFLEN(pState)) + hashFunc(AESGCM_COUNTER(pState), AESGCM_HKEY(pState), AesGcmConst_table); + + /* add IV bit length */ + { + Ipp64u ivBitLen = AESGCM_IV_LEN(pState)*BYTESIZE; + Ipp8u tmp[BLOCK_SIZE]; + PadBlock(0, tmp, BLOCK_SIZE-8); + U32_TO_HSTRING(tmp+8, IPP_HIDWORD(ivBitLen)); + U32_TO_HSTRING(tmp+12, IPP_LODWORD(ivBitLen)); + XorBlock16(tmp, AESGCM_COUNTER(pState), AESGCM_COUNTER(pState)); + hashFunc(AESGCM_COUNTER(pState), AESGCM_HKEY(pState), AesGcmConst_table); + } + } + + /* prepare initial counter */ + { + IppsAESSpec* pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + //encoder((Ipp32u*)AESGCM_COUNTER(pState), (Ipp32u*)AESGCM_ECOUNTER0(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER0(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(AESGCM_COUNTER(pState), AESGCM_ECOUNTER0(pState), RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + /* switch mode and init counters */ + AESGCM_STATE(pState) = GcmAADprocessing; + AESGCM_AAD_LEN(pState) = CONST_64(0); + AESGCM_BUFLEN(pState) = 0; + } + + /* + // AAD processing + */ + +#if(_IPP32E>=_IPP32E_K0) + /* test if buffer is not empty */ + if(AESGCM_BUFLEN(pState)) { + /* Cast to int here does not produce loss of data as AESGCM_BUFLEN <= BLOCK_SIZE, which is 16 bytes */ + int bufCapacity = BLOCK_SIZE-(int)AESGCM_BUFLEN(pState); + int locLen = IPP_MIN(aadLen, bufCapacity); + XorBlockMirror(pAAD, AESGCM_GHASH(pState), AESGCM_GHASH(pState), bufCapacity, locLen); + AESGCM_BUFLEN(pState) += (Ipp64u)locLen; + + /* if buffer full */ + if(BLOCK_SIZE==AESGCM_BUFLEN(pState)) { + MulGcm_ ghashFunc = AES_GCM_GMUL(pState); + ghashFunc(&AES_GCM_KEY_DATA(pState), AESGCM_GHASH(pState)); + AESGCM_BUFLEN(pState) = 0; + } + + AESGCM_AAD_LEN(pState) += (Ipp64u)locLen; + pAAD += locLen; + aadLen -= locLen; + } + + /* process main part of AAD */ + int lenBlks = aadLen & (-BLOCK_SIZE); + if(lenBlks) { + AadUpdate_ aadHashUpdate = AES_GCM_AAD_UPDATE(pState); + + aadHashUpdate(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), pAAD, (Ipp64u)lenBlks); + + AESGCM_AAD_LEN(pState) += (Ipp64u)lenBlks; + pAAD += lenBlks; + aadLen -= lenBlks; + } + + /* copy the rest of AAD into the buffer */ + if(aadLen) { + /* Note: GHASH in the IPsec context is byte-reflected */ + XorBlockMirror(pAAD, AESGCM_GHASH(pState), AESGCM_GHASH(pState), BLOCK_SIZE, aadLen); + AESGCM_AAD_LEN(pState) += (Ipp64u)aadLen; + AESGCM_BUFLEN(pState) = (Ipp64u)aadLen; + } +#else + /* test if buffer is not empty */ + if(AESGCM_BUFLEN(pState)) { + int locLen = IPP_MIN(aadLen, BLOCK_SIZE-AESGCM_BUFLEN(pState)); + XorBlock(pAAD, AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), AESGCM_GHASH(pState)+AESGCM_BUFLEN(pState), locLen); + AESGCM_BUFLEN(pState) += locLen; + + /* if buffer full */ + if(BLOCK_SIZE==AESGCM_BUFLEN(pState)) { + MulGcm_ hashFunc = AESGCM_HASH(pState); + hashFunc(AESGCM_GHASH(pState), AESGCM_HKEY(pState), AesGcmConst_table); + AESGCM_BUFLEN(pState) = 0; + } + + AESGCM_AAD_LEN(pState) += (Ipp64u)locLen; + pAAD += locLen; + aadLen -= locLen; + } + + /* process main part of AAD */ + { + int lenBlks = aadLen & (-BLOCK_SIZE); + if(lenBlks) { + Auth_ authFunc = AESGCM_AUTH(pState); + + authFunc(AESGCM_GHASH(pState), pAAD, lenBlks, AESGCM_HKEY(pState), AesGcmConst_table); + + AESGCM_AAD_LEN(pState) += (Ipp64u)lenBlks; + pAAD += lenBlks; + aadLen -= lenBlks; + } + } + + /* copy the rest of AAD into the buffer */ + if(aadLen) { + XorBlock(pAAD, AESGCM_GHASH(pState), AESGCM_GHASH(pState), aadLen); + AESGCM_AAD_LEN(pState) += (Ipp64u)aadLen; + AESGCM_BUFLEN(pState) = aadLen; + } +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmprocessiv.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmprocessiv.c new file mode 100644 index 000000000..03854d8a0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmprocessiv.c @@ -0,0 +1,158 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMProcessIV() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMProcessIV +// +// Purpose: IV processing. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pIV ==NULL && ivLen>0 +// ippStsContextMatchErr !AESGCM_VALID_ID() +// ippStsLengthErr ivLen <0 +// ippStsBadArgErr illegal sequence call +// ippStsNoErr no errors +// +// Parameters: +// pIV pointer to the IV +// ivLen length of IV (it could be 0) +// pState pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMProcessIV,(const Ipp8u* pIV, int ivLen, IppsAES_GCMState* pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + + /* test IV pointer and length */ + IPP_BADARG_RET(ivLen && !pIV, ippStsNullPtrErr); + IPP_BADARG_RET(ivLen<0, ippStsLengthErr); + + /* use aligned context */ + pState = (IppsAES_GCMState*)( IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT) ); + /* test context validity */ + IPP_BADARG_RET(!AESGCM_VALID_ID(pState), ippStsContextMatchErr); + + /* According to the NIST Special Publication 800-38D (Recommendation for GCM + * mode, p.5.2.1.1 Input Data) the IV shall be between 1 and 2^64 bits. */ + IPP_BADARG_RET(((AESGCM_IV_LEN(pState) + (Ipp64u)ivLen) < (Ipp64u)ivLen), ippStsScaleRangeErr); + + IPP_BADARG_RET(!(GcmInit==AESGCM_STATE(pState) || GcmIVprocessing==AESGCM_STATE(pState)), ippStsBadArgErr); + + /* switch IVprocessing on */ + AESGCM_STATE(pState) = GcmIVprocessing; + +#if(_IPP32E>=_IPP32E_K0) + IvUpdate_ ivHashUpdate = AES_GCM_IV_UPDATE(pState); + + /* test if buffer is not empty */ + if(AESGCM_BUFLEN(pState)) { + /* Cast to int here does not produce loss of data as AESGCM_BUFLEN <= BLOCK_SIZE, which is 16 bytes */ + int locLen = IPP_MIN(ivLen, BLOCK_SIZE-(int)AESGCM_BUFLEN(pState)); + CopyBlock((void*)pIV, (void*)(AESGCM_COUNTER(pState)+AESGCM_BUFLEN(pState)), locLen); + AESGCM_BUFLEN(pState) += (Ipp64u)locLen; + + /* if buffer full */ + if(BLOCK_SIZE==AESGCM_BUFLEN(pState)) { + ivHashUpdate(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), AESGCM_COUNTER(pState), BLOCK_SIZE); + AESGCM_BUFLEN(pState) = 0; + } + + AESGCM_IV_LEN(pState) += (Ipp64u)locLen; + pIV += locLen; + ivLen -= locLen; + } + + /* process main part of IV */ + int lenBlks = ivLen & (-BLOCK_SIZE); + if(lenBlks) { + ivHashUpdate(&AES_GCM_KEY_DATA(pState), &AES_GCM_CONTEXT_DATA(pState), pIV, (Ipp64u)lenBlks); + AESGCM_IV_LEN(pState) += (Ipp64u)lenBlks; + pIV += lenBlks; + ivLen -= lenBlks; + } + + /* copy the rest of IV into the buffer */ + if(ivLen) { + CopyBlock((void*)pIV, (void*)(AESGCM_COUNTER(pState)), ivLen); + AESGCM_IV_LEN(pState) += (Ipp64u)ivLen; + AESGCM_BUFLEN(pState) = (Ipp64u)ivLen; + } +#else + /* test if buffer is not empty */ + if(AESGCM_BUFLEN(pState)) { + int locLen = IPP_MIN(ivLen, BLOCK_SIZE-AESGCM_BUFLEN(pState)); + XorBlock(pIV, AESGCM_COUNTER(pState)+AESGCM_BUFLEN(pState), AESGCM_COUNTER(pState)+AESGCM_BUFLEN(pState), locLen); + AESGCM_BUFLEN(pState) += locLen; + + /* if buffer full */ + if(BLOCK_SIZE==AESGCM_BUFLEN(pState)) { + MulGcm_ ghashFunc = AESGCM_HASH(pState); + ghashFunc(AESGCM_COUNTER(pState), AESGCM_HKEY(pState), AesGcmConst_table); + AESGCM_BUFLEN(pState) = 0; + } + + AESGCM_IV_LEN(pState) += (Ipp64u)locLen; + pIV += locLen; + ivLen -= locLen; + } + + /* process main part of IV */ + { + int lenBlks = ivLen & (-BLOCK_SIZE); + if(lenBlks) { + Auth_ authFunc = AESGCM_AUTH(pState); + authFunc(AESGCM_COUNTER(pState), pIV, lenBlks, AESGCM_HKEY(pState), AesGcmConst_table); + AESGCM_IV_LEN(pState) += (Ipp64u)lenBlks; + pIV += lenBlks; + ivLen -= lenBlks; + } + } + + /* copy the rest of IV into the buffer */ + if(ivLen) { + XorBlock(pIV, AESGCM_COUNTER(pState), AESGCM_COUNTER(pState), ivLen); + AESGCM_IV_LEN(pState) += (Ipp64u)ivLen; + AESGCM_BUFLEN(pState) += ivLen; + } +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmreinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmreinit.c new file mode 100644 index 000000000..61206e5d1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmreinit.c @@ -0,0 +1,87 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM functionality +// +// Contents: +// ippsAES_GCMReinit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpaesminit_internal.h" +#include "pcptool.h" + +#if (_IPP32E >= _IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMReinit +// +// Purpose: Re-init AES_GCM context for future usage - +// the state of the context left unchanged, just the internal stuff is updated +// (it's useful when the context physically lies in the same memory, but its +// virtual address changes - some pointers inside become stale and need to be re-initialized). +// Important note: this API shouldn't be used to re-initialize a context that was copied +// from some original context, computations in this case may be incorrect. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsNoErr no errors +// +// Parameters: +// pState pointer to the AES-GCM context to be re-initialized +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMReinit, (IppsAES_GCMState * pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + + /* use aligned context */ + pState = (IppsAES_GCMState *)(IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT)); + + /* set proper GCM context id */ + AESGCM_SET_ID(pState); + + Ipp64u keyByteLen; +/* re-init pointers inside the cipher context */ +#if (_IPP32E >= _IPP32E_K0) + keyByteLen = AES_GCM_KEY_LEN(pState); +#else + IppsAESSpec *pAesCtx = AESGCM_CIPHER(pState); + /* set proper cipher context id*/ + RIJ_SET_ID(pAesCtx); + keyByteLen = (Ipp64u)RIJ_NK(pAesCtx) * RIJ_BYTES_IN_WORD; + + cpAes_setup_ptrs_and_methods(pAesCtx); +#endif + + /* re-init pointers inside the AES-GCM context */ + cpAesGCM_setup_ptrs_and_methods(pState, keyByteLen); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmreset.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmreset.c new file mode 100644 index 000000000..835a85725 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmreset.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMReset() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/*F* +// Name: ippsAES_GCMReset +// +// Purpose: Resets AES_GCM context. +// +// Returns: Reason: +// ippStsNullPtrErr pState== NULL +// ippStsContextMatchErr pState points on invalid context +// ippStsNoErr no errors +// +// Parameters: +// pState pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMReset,(IppsAES_GCMState* pState)) +{ + /* test pState pointer */ + IPP_BAD_PTR1_RET(pState); + + /* use aligned context */ + pState = (IppsAES_GCMState*)( IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT) ); + /* test context validity */ + IPP_BADARG_RET(!AESGCM_VALID_ID(pState), ippStsContextMatchErr); + + /* reset GCM */ + AESGCM_STATE(pState) = GcmInit; + AESGCM_IV_LEN(pState) = CONST_64(0); + AESGCM_AAD_LEN(pState) = CONST_64(0); + AESGCM_TXT_LEN(pState) = CONST_64(0); + + AESGCM_BUFLEN(pState) = 0; + PadBlock(0, AESGCM_COUNTER(pState), BLOCK_SIZE); + PadBlock(0, AESGCM_ECOUNTER(pState), BLOCK_SIZE); + PadBlock(0, AESGCM_ECOUNTER0(pState), BLOCK_SIZE); + PadBlock(0, AESGCM_GHASH(pState), BLOCK_SIZE); + + #if(_IPP32E>=_IPP32E_K0) + + PadBlock(0, (void*)&AES_GCM_CONTEXT_DATA(pState), sizeof(struct gcm_context_data)); + + #endif /* #if(_IPP32E>=_IPP32E_K0) */ + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmstart.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmstart.c new file mode 100644 index 000000000..7b98f1c9f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_gcmstart.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// ippsAES_GCMStart() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if(_IPP32E>=_IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K1) */ + +/*F* +// Name: ippsAES_GCMStart +// +// Purpose: Start the process of encryption or decryption and authentication tag generation. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pIV == NULL, ivLen>0 +// pAAD == NULL, aadLen>0 +// ippStsContextMatchErr !AESGCM_VALID_ID() +// ippStsLengthErr ivLen < 0 +// aadLen < 0 +// ippStsNoErr no errors +// +// Parameters: +// pIV pointer to the IV (nonce) +// ivLen length of the IV in bytes +// pAAD pointer to the Addition Authenticated Data (header) +// aadLen length of the AAD in bytes +// pState pointer to the AES-GCM state +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMStart,(const Ipp8u* pIV, int ivLen, + const Ipp8u* pAAD, int aadLen, + IppsAES_GCMState* pState)) +{ + IppStatus sts = ippsAES_GCMReset(pState); + if(ippStsNoErr==sts) + sts = ippsAES_GCMProcessIV(pIV, ivLen, pState); + if(ippStsNoErr==sts) + sts = ippsAES_GCMProcessAAD(pAAD, aadLen, pState); + return sts; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_keys_ni.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_keys_ni.h new file mode 100644 index 000000000..2bf119db1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_keys_ni.h @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. AES keys expansion +// +// Contents: +// cpExpandAesKey_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" + +#if !defined (_PCP_AES_KEYS_NI_H) +#define _PCP_AES_KEYS_NI_H + +#if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) + +////////////////////////////////////////////////////////////////////// +#define cpExpandAesKey_NI OWNAPI(cpExpandAesKey_NI) + IPP_OWN_DECL (void, cpExpandAesKey_NI, (const Ipp8u* pSecret, IppsAESSpec* pCtx)) +#define aes_DecKeyExpansion_NI OWNAPI(aes_DecKeyExpansion_NI) + IPP_OWN_DECL (void, aes_DecKeyExpansion_NI, (Ipp8u* decKeys, const Ipp8u* encKeys, int nr)) +#define aes128_KeyExpansion_NI OWNAPI(aes128_KeyExpansion_NI) + IPP_OWN_DECL (void, aes128_KeyExpansion_NI, (Ipp8u* keyExp, const Ipp8u* userkey)) +#define aes192_KeyExpansion_NI OWNAPI(aes192_KeyExpansion_NI) + IPP_OWN_DECL (void, aes192_KeyExpansion_NI, (Ipp8u* keyExp, const Ipp8u* userkey)) +#define aes256_KeyExpansion_NI OWNAPI(aes256_KeyExpansion_NI) + IPP_OWN_DECL (void, aes256_KeyExpansion_NI, (Ipp8u* keyExp, const Ipp8u* userkey)) + +#endif /* #if (_AES_NI_ENABLING_==_FEATURE_ON_) || (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) */ + +#endif /* #if !defined (_PCP_AES_KEYS_NI_H) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_ofb.h b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ofb.h new file mode 100644 index 000000000..75ba3da57 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_ofb.h @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (OFB mode) +// +// Contents: +// cpProcessAES_ofb8() +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#if !defined(_PCP_AES_OFB_H) +#define _PCP_AES_OFB_H + +/* +// AES-OFB ecnryption/decryption +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// dataLen input/output buffer length (in bytes) +// ofbBlkSize ofb block size (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +*/ +#define cpProcessAES_ofb8 OWNAPI(cpProcessAES_ofb8) + IPP_OWN_DECL (void, cpProcessAES_ofb8, (const Ipp8u *pSrc, Ipp8u *pDst, int dataLen, int ofbBlkSize, const IppsAESSpec* pCtx, Ipp8u* pIV)) + +#endif /* #if !defined(_PCP_AES_OFB_H) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_process_ofb8.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_process_ofb8.c new file mode 100644 index 000000000..d2a84c83e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_process_ofb8.c @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption/decryption (OFB mode) +// +// Contents: +// cpProcessAES_ofb8() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_ofb.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + + +/* +// AES-OFB ecnryption/decryption +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// dataLen input/output buffer length (in bytes) +// ofbBlkSize ofb block size (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +*/ +IPP_OWN_DEFN (void, cpProcessAES_ofb8, (const Ipp8u *pSrc, Ipp8u *pDst, int dataLen, int ofbBlkSize, const IppsAESSpec* pCtx, Ipp8u* pIV)) +{ + /* setup encoder method */ + RijnCipher encoder = RIJ_ENCODER(pCtx); + + Ipp32u tmpInpOut[2*NB(128)]; + + CopyBlock16(pIV, tmpInpOut); + + while(dataLen>=ofbBlkSize) { + /* block-by-block processing */ + //encoder(tmpInpOut, tmpInpOut+NB(128), RIJ_NR(pCtx), RIJ_EKEYS(pCtx), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pCtx)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder((Ipp8u*)tmpInpOut, (Ipp8u*)(tmpInpOut+NB(128)), RIJ_NR(pCtx), RIJ_EKEYS(pCtx), RijEncSbox/*NULL*/); + #else + encoder((Ipp8u*)tmpInpOut, (Ipp8u*)(tmpInpOut+NB(128)), RIJ_NR(pCtx), RIJ_EKEYS(pCtx), NULL); + #endif + + /* store output and shift inpBuffer for the next OFB operation */ + if(ofbBlkSize==MBS_RIJ128) { + ((Ipp32u*)pDst)[0] = tmpInpOut[0+NB(128)]^((Ipp32u*)pSrc)[0]; + ((Ipp32u*)pDst)[1] = tmpInpOut[1+NB(128)]^((Ipp32u*)pSrc)[1]; + ((Ipp32u*)pDst)[2] = tmpInpOut[2+NB(128)]^((Ipp32u*)pSrc)[2]; + ((Ipp32u*)pDst)[3] = tmpInpOut[3+NB(128)]^((Ipp32u*)pSrc)[3]; + tmpInpOut[0] = tmpInpOut[0+NB(128)]; + tmpInpOut[1] = tmpInpOut[1+NB(128)]; + tmpInpOut[2] = tmpInpOut[2+NB(128)]; + tmpInpOut[3] = tmpInpOut[3+NB(128)]; + } + else { + XorBlock(pSrc, tmpInpOut+NB(128), pDst, ofbBlkSize); + CopyBlock16((Ipp8u*)tmpInpOut+ofbBlkSize, tmpInpOut); + } + + pSrc += ofbBlkSize; + pDst += ofbBlkSize; + dataLen -= ofbBlkSize; + } + + /* update pIV */ + CopyBlock16((Ipp8u*)tmpInpOut, pIV); + + /* clear secret data */ + PurgeBlock(tmpInpOut, sizeof(tmpInpOut)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_randomnoise.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_randomnoise.c new file mode 100644 index 000000000..a8a66a82b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_randomnoise.c @@ -0,0 +1,120 @@ +/******************************************************************************* +* Copyright 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/* +// +// Purpose: +// AES noise function +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcpbnumisc.h" +#include "pcptool.h" +#include "pcpprng.h" + +/*F* +// Name: cpAESRandomNoise +// +// Purpose: AES Random Noise +// +// Returns: Reason: +// ippStsNullPtrErr pRndValue == NULL +// ippStsLengthErr 29 < nBits > 32 +// ippStsScaleRangeErr noiseRate > 1 +// (MISTLETOE3_MAX_CHUNK_SIZE > MISTLETOE3_TARGET_SIZE - invalid) +// ippStsNotSupportedModeErr Mistletoe3 mitigation isn't applicable for current CPU +// (no support of Intel® Advanced Encryption Standard New Instructions (Intel® AES-NI) or +// vector extensions of Intel® AES-NI) +// ippStsErr random bit sequence can't be generated +// ippStsNoErr no errors +// +// Parameters: +// rndFunc external random generator +// nBits number of bits that should be taken +// from generated 32-bit random value +// noiseRate probability of refreshing the random +// number pRndValue in the context +// pRndValue pointer to random number value from previous noise injection +// +*F*/ +IPP_OWN_DEFN(IppStatus, cpAESRandomNoise, (IppBitSupplier rndFunc, Ipp32u nBits, Ipp64f noiseRate, Ipp32u *pRndValue)) +{ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* test that pRndValue pointer isn't NULL */ + IPP_BAD_PTR1_RET(pRndValue); + + /* test nBits and noiseRate values */ + IPP_BADARG_RET(nBits < 29 || nBits > 32, ippStsLengthErr); + IPP_BADARG_RET((noiseRate > 1), ippStsScaleRangeErr); + + Ipp32u rand = 0; + IppStatus status = ippStsNoErr; + + IppsPRNGState Ctx; + IppsPRNGState* pCtx = NULL; + + /* Use internal PRNG implementations if no external random source provided */ + if (NULL == rndFunc) { + if( IsFeatureEnabled(ippCPUID_RDRAND) ) + rndFunc = ippsPRNGenRDRAND; + else // RDRAND feature isn't available + { + pCtx = &Ctx; + ippsPRNGInit(160, pCtx); + rndFunc = ippsPRNGen; + } + } + + Ipp32u ctxRand = *pRndValue; + + /* Get the threshold to generate random noise */ + const Ipp32u randMax = (Ipp32u)(-1); + Ipp32u noiseThreshold = (Ipp32u)((Ipp64f)randMax * noiseRate); + + /* Get a random value, which is used to decide whether a new random should be + * generated. This allows generate random latency with probability */ + status = rndFunc(&rand, 32, pCtx); + + /* Check if new rand value required */ + if ((ippStsNoErr == status) && ((rand < noiseThreshold) || (ctxRand == 0))) { + status = rndFunc(&ctxRand, (int)nBits, pCtx); + if (ippStsNoErr == status) { + /* Write back a new random */ + *pRndValue = ctxRand; + } + } + + /* Scale down based on noise rate */ + rand = (Ipp32u)((Ipp64f)ctxRand * noiseRate); + + if (ippStsNoErr == status) { + _ippcpDelay(rand); + } + + return status; +#else + /* To remove MSVC warning C4100: 'XXX': unreferenced formal parameter*/ + IPP_UNREFERENCED_PARAMETER(rndFunc); + IPP_UNREFERENCED_PARAMETER(nBits); + IPP_UNREFERENCED_PARAMETER(noiseRate); + IPP_UNREFERENCED_PARAMETER(pRndValue); + + return ippStsNotSupportedModeErr; +#endif /* #if (_AES_PROB_NOISE == _FEATURE_ON_) */ +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_s2v_cmac.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_s2v_cmac.c new file mode 100644 index 000000000..2a34fb8b8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_s2v_cmac.c @@ -0,0 +1,107 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-SIV Functions (RFC 5297) +// +// Contents: +// ippsAES_S2V_CMAC() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpcmac.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_sivstuff.h" + +/*F* +// Name: ippsAES_S2V_CMAC +// +// Purpose: Converts strings to vector - +// performs S2V operation as defined RFC 5297. +// +// Returns: Reason: +// ippStsNullPtrErr pV == NULL +// pAD== NULL +// pADlen==NULL +// pADlen[i]!=0 && pAD[i]==0 +// ippStsLengthErr keyLen != 16 +// keyLen != 24 +// keyLen != 32 +// pADlen[i]<0 +// 0 > numAD +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length of secret key +// pAD[] array of pointers to input strings +// pADlen[] array of input string lengths +// numAD number of pAD[] and pADlen[] terms +// pV pointer to output vector +// +*F*/ +IPPFUN(IppStatus, ippsAES_S2V_CMAC,(const Ipp8u* pKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD, + Ipp8u V[MBS_RIJ128])) +{ + /* test output vector */ + IPP_BAD_PTR1_RET(V); + + /* make sure that number of input string is legal */ + IPP_BADARG_RET(0>numAD, ippStsLengthErr); + + /* test arrays of input */ + IPP_BAD_PTR2_RET(pAD, pADlen); + + int n; + for(n=0; n 4 +// ippStsNotSupportedModeErr Mistletoe3 mitigation isn't applicable for current CPU +// (no support of Intel® Advanced Encryption Standard New Instructions (Intel® AES-NI) or +// vector extensions of Intel® AES-NI) +// ippStsNoErr no errors +// +// Parameters: +// noiseLevel the value of this parameter is directly +// proportional to the amount of noise injected +// Increasing noise level by 1 means the delay +// (performance impact) is doubled +// pCtx pointer to the AES context +// +*F*/ +IPPFUN(IppStatus, ippsAESSetupNoise, (Ipp32u noiseLevel, IppsAESSpec* pCtx)) +{ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test noise level range */ + IPP_BADARG_RET(noiseLevel > 4, ippStsLengthErr); + + cpAESNoiseParams *params = (cpAESNoiseParams *)&RIJ_NOISE_PARAMS(pCtx); + + /* set up the parameters with initial values */ + AES_NOISE_RAND(params) = 0; + AES_NOISE_LEVEL(params) = noiseLevel; + + return ippStsNoErr; +#else + /* To remove MSVC warning C4100: 'XXX': unreferenced formal parameter*/ + IPP_UNREFERENCED_PARAMETER(noiseLevel); + IPP_UNREFERENCED_PARAMETER(pCtx); + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_sivdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_sivdecrypt.c new file mode 100644 index 000000000..54e7541e5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_sivdecrypt.c @@ -0,0 +1,140 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-SIV Functions (RFC 5297) +// +// Contents: +// ippsAES_SIVDecrypt() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpcmac.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_sivstuff.h" + +/*F* +// Name: ippsAES_SIVDecrypt +// +// Purpose: RFC 5297 authenticated decryption +// +// Returns: Reason: +// ippStsNullPtrErr pSrc==NULL, pDst==NULL +// pAuthPassed==NULL +// pAuthKey==NULL, pConfKey==NULL +// pAD== NULL, pADlen==NULL +// pADlen[i]!=0 && pAD[i]==0 +// pSIV == NULL +// ippStsLengthErr keyLen != 16 +// keyLen != 24 +// keyLen != 32 +// pADlen[i]<0 +// numAD<0 +// len<=0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to ciphertext +// pDst pointer to plaintext +// len length (in bytes) of plaintext/ciphertext +// pAuthPassed "authentication passed" flag +// pAuthKey pointer to the authentication key +// pConfKey pointer to the confidendat key +// keyLen length of keys +// pAD[] array of pointers to input strings +// pADlen[] array of input string lengths +// numAD number of pAD[] and pADlen[] terms +// pSIV pointer to input SIV +// +*F*/ +IPPFUN(IppStatus, ippsAES_SIVDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + int* pAuthPassed, + const Ipp8u* pAuthKey, const Ipp8u* pConfKey, int keyLen, + const Ipp8u* pAD[], const int pADlen[], int numAD, + const Ipp8u* pSIV)) +{ + /* test ciphertext, plaintex and length */ + IPP_BAD_PTR2_RET(pSrc, pDst); + IPP_BADARG_RET(0>=len, ippStsLengthErr); + + /* test keys & keyLen */ + IPP_BAD_PTR2_RET(pAuthKey, pConfKey); + IPP_BADARG_RET(keyLen!=16 && keyLen!=24 && keyLen!=32, ippStsLengthErr); + + /* test passed flag & auth vector */ + IPP_BAD_PTR2_RET(pAuthPassed, pSIV); + + /* test arrays of input AD[] */ + IPP_BAD_PTR2_RET(pAD, pADlen); + IPP_BADARG_RET(0>numAD, ippStsLengthErr); + + { + int n; + for (n = 0; n < numAD; n++) { + /* test input message and it's length */ + IPP_BADARG_RET((pADlen[n] < 0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((pADlen[n] && !pAD[n]), ippStsNullPtrErr); + } + } + + { + int n; + + /* iv an dmask */ + Ipp8u iv[MBS_RIJ128]; + Ipp8u vmask[MBS_RIJ128] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0x7f,0xff,0xff,0xff,0x7f,0xff,0xff,0xff}; + /* AES context */ + Ipp8u aesBlob[sizeof(IppsAESSpec)]; + IppsAESSpec* paesCtx = (IppsAESSpec*)aesBlob; + + ippsAESInit(pConfKey, keyLen, paesCtx, sizeof(aesBlob)); + + /* construct iv */ + for(n=0; n=len, ippStsLengthErr); + + /* test keys & keyLen */ + IPP_BAD_PTR2_RET(pAuthKey, pConfKey); + IPP_BADARG_RET(keyLen!=16 && keyLen!=24 && keyLen!=32, ippStsLengthErr); + + /* test output vector */ + IPP_BAD_PTR1_RET(pSIV); + + /* test arrays of input AD[] */ + IPP_BAD_PTR2_RET(pAD, pADlen); + IPP_BADARG_RET(0>numAD, ippStsLengthErr); + + { + int n; + for (n = 0; n < numAD; n++) { + /* test input message and it's length */ + IPP_BADARG_RET((pADlen[n] < 0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((pADlen[n] && !pAD[n]), ippStsNullPtrErr); + } + } + + { + int n; + + /* iv and mask */ + Ipp8u iv[MBS_RIJ128]; + Ipp8u vmask[MBS_RIJ128] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0x7f,0xff,0xff,0xff,0x7f,0xff,0xff,0xff}; + /* AES context */ + Ipp8u aesBlob[sizeof(IppsAESSpec)]; + IppsAESSpec* paesCtx = (IppsAESSpec*)aesBlob; + + { + Ipp8u ctxBlob[sizeof(IppsAES_CMACState)]; + IppsAES_CMACState* pCtx = (IppsAES_CMACState*)ctxBlob; + cpAES_S2V_init(pSIV, pAuthKey, keyLen, pCtx, sizeof(ctxBlob)); + + for(n=0; n>8) & 0xFF; + } + + out[MBS_RIJ128-1] ^= ((Ipp8u)(0-carry) & 0x87); + return out; +} +__INLINE void cpAES_S2V_update(Ipp8u v[MBS_RIJ128], const Ipp8u* pSrc, int len, IppsAES_CMACState* pCtx) +{ + Ipp8u t[MBS_RIJ128]; + cpAES_CMAC(t, pSrc, len, pCtx); + double16(v, v); + XorBlock16(v, t, v); +} + +static void cpAES_S2V_final(Ipp8u v[MBS_RIJ128], const Ipp8u* pSrc, int len, IppsAES_CMACState* pCtx) +{ + Ipp8u t[MBS_RIJ128]; + + if(len>=MBS_RIJ128) { + ippsAES_CMACUpdate(pSrc, len-MBS_RIJ128, pCtx); + XorBlock16(pSrc+len-MBS_RIJ128, v, t); + } + else { + double16(t, v); + XorBlock(pSrc, t, t, len); + t[len] ^= 0x80; + } + cpAES_CMAC(v, t, MBS_RIJ128, pCtx); +} + +#endif /*_PCP_AES_SIV_STUFF_H_*/ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_wrpaesgcmdec_avx.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_wrpaesgcmdec_avx.c new file mode 100644 index 000000000..2904b747c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_wrpaesgcmdec_avx.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// wrpAesGcmDec_avx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthgcm.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) +#if(_IPP32E<_IPP32E_K0) + +/*F* +// Name: ippsAES_GCMDecrypt +// +// Purpose: Decrypts a data buffer in the GCM mode. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pDst == NULL +// pState == NULL +// ippStsContextMatchErr !AESGCM_VALID_ID() +// ippStsLengthErr txtLen<0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc Pointer to ciphertext. +// pDst Pointer to plaintext. +// len Length of the plaintext and ciphertext in bytes +// pState pointer to the context +// +*F*/ +IPP_OWN_DEFN (void, wrpAesGcmDec_avx, (Ipp8u* pDst, const Ipp8u* pSrc, int lenBlks, IppsAES_GCMState* pState)) +{ + IppsAESSpec* pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + AesGcmDec_avx(pDst, pSrc, lenBlks, + encoder, RIJ_NR(pAES), RIJ_EKEYS(pAES), + AESGCM_GHASH(pState), + AESGCM_COUNTER(pState), + AESGCM_ECOUNTER(pState), + AESGCM_HKEY(pState)); +} + +#endif /* (_IPP32E<_IPP32E_K0) */ +#endif /* #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_wrpaesgcmenc_avx.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_wrpaesgcmenc_avx.c new file mode 100644 index 000000000..204bd0eb1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_wrpaesgcmenc_avx.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM +// +// Contents: +// wrpAesGcmEnc_avx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesauthgcm.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) +#if(_IPP32E<_IPP32E_K0) + +/* encrypts and authenticates n*BLOCK_SIZE bytes */ +IPP_OWN_DEFN (void, wrpAesGcmEnc_avx, (Ipp8u* pDst, const Ipp8u* pSrc, int lenBlks, IppsAES_GCMState* pState)) +{ + IppsAESSpec* pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + AesGcmEnc_avx(pDst, pSrc, lenBlks, + encoder, RIJ_NR(pAES), RIJ_EKEYS(pAES), + AESGCM_GHASH(pState), + AESGCM_COUNTER(pState), + AESGCM_ECOUNTER(pState), + AESGCM_HKEY(pState)); +} + +#endif /* (_IPP32E<_IPP32E_K0) */ +#endif /* #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_xts_vaes512.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xts_vaes512.c new file mode 100644 index 000000000..ee5a6f03b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xts_vaes512.c @@ -0,0 +1,506 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-XTS VAES512 Functions (IEEE P1619) +// +// Contents: +// cpAESEncryptXTS_VAES() +// cpAESDecryptXTS_VAES() +// +*/ + +#include "owncp.h" +#include "pcpaesmxts.h" +#include "pcptool.h" +#include "pcpaesmxtsstuff.h" + +#include "pcpaes_encrypt_vaes512.h" +#include "pcpaes_decrypt_vaes512.h" + +#if (_IPP32E>=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // cast truncates constant value in MSVC +#endif + +#define M512(mem) (*((__m512i*)(mem))) + +/* Generate next 4 tweaks with 2^8 multiplier */ +__INLINE __m512i nextTweaks_x8(__m512i tweak128x4) +{ + const __m512i poly = _mm512_set_epi64(0, 0x87, 0, 0x87, 0, 0x87, 0, 0x87); + + __m512i highBytes = _mm512_bsrli_epi128(tweak128x4, 15); + __m512i tmp = _mm512_clmulepi64_epi128(highBytes, poly, 0); + tweak128x4 = _mm512_bslli_epi128(tweak128x4, 1); + tweak128x4 = _mm512_xor_si512(tweak128x4, tmp); + + return tweak128x4; +} + +/* Generate next 4 tweaks with 2^32 multiplier */ +__INLINE __m512i nextTweaks_x32(__m512i tweak128x4) +{ + const __m512i poly = _mm512_set_epi64(0, 0x87, 0, 0x87, 0, 0x87, 0, 0x87); + + /* Shift 128-bit lanes right by 12 bytes */ + __m512i highBytes = _mm512_bsrli_epi128(tweak128x4, 12); + + __m512i tmp = _mm512_clmulepi64_epi128(highBytes, poly, 0); + + /* Shift 128-bit lanes left by 4 bytes */ + tweak128x4 = _mm512_bslli_epi128(tweak128x4, 4); + + /* Xor low 4 bytes in each 128-bit lane with 0x87-modified ones */ + tweak128x4 = _mm512_xor_si512(tweak128x4, tmp); + + return tweak128x4; +} + +IPP_OWN_DEFN (void, cpAESEncryptXTS_VAES, (Ipp8u* outBlk, const Ipp8u* inpBlk, int nBlks, const Ipp8u* pRKey, int nr, Ipp8u* pTweak)) +{ + if (0 == nBlks) { + return; // do not modify tweak value + } + + int cipherRounds = nr - 1; + + __m128i* pRkey = (__m128i*)pRKey; + __m512i* pInp512 = (__m512i*)inpBlk; + __m512i* pOut512 = (__m512i*)outBlk; + + /* Produce initial 32 tweaks */ + __ALIGN64 Ipp8u tempTweakBuffer[AES_BLK_SIZE * 4 * 8]; // 32 tweaks + cpXTSwhitening(tempTweakBuffer, 8, pTweak); // generate 8 tweaks + + const __m512i* pInitialTweaks = (const __m512i*)tempTweakBuffer; + + int tailTweaksConsumedCount = 0; + + __m512i tweakBlk0 = M512(pInitialTweaks); + __m512i tweakBlk1 = M512(pInitialTweaks + 1); + __m512i tweakBlk2 = M512(pInitialTweaks + 2); + __m512i tweakBlk3 = M512(pInitialTweaks + 3); + __m512i tweakBlk4 = M512(pInitialTweaks + 4); + __m512i tweakBlk5 = M512(pInitialTweaks + 5); + __m512i tweakBlk6 = M512(pInitialTweaks + 6); + __m512i tweakBlk7 = M512(pInitialTweaks + 7); + + // generate other 24 tweaks + tweakBlk2 = nextTweaks_x8(tweakBlk0); + tweakBlk3 = nextTweaks_x8(tweakBlk1); + tweakBlk4 = nextTweaks_x8(tweakBlk2); + tweakBlk5 = nextTweaks_x8(tweakBlk3); + tweakBlk6 = nextTweaks_x8(tweakBlk4); + tweakBlk7 = nextTweaks_x8(tweakBlk5); + + int blocks; + for (blocks = nBlks; blocks >= (4 * 8); blocks -= (4 * 8)) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + __m512i blk3 = _mm512_loadu_si512(pInp512 + 3); + __m512i blk4 = _mm512_loadu_si512(pInp512 + 4); + __m512i blk5 = _mm512_loadu_si512(pInp512 + 5); + __m512i blk6 = _mm512_loadu_si512(pInp512 + 6); + __m512i blk7 = _mm512_loadu_si512(pInp512 + 7); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + blk4 = _mm512_xor_epi64(tweakBlk4, blk4); + blk5 = _mm512_xor_epi64(tweakBlk5, blk5); + blk6 = _mm512_xor_epi64(tweakBlk6, blk6); + blk7 = _mm512_xor_epi64(tweakBlk7, blk7); + + cpAESEncrypt4_VAES_NI(&blk0, &blk1, &blk2, &blk3, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + + tweakBlk0 = nextTweaks_x32(tweakBlk0); + tweakBlk1 = nextTweaks_x32(tweakBlk1); + tweakBlk2 = nextTweaks_x32(tweakBlk2); + tweakBlk3 = nextTweaks_x32(tweakBlk3); + + cpAESEncrypt4_VAES_NI(&blk4, &blk5, &blk6, &blk7, pRkey, cipherRounds); + + blk4 = _mm512_xor_epi64(tweakBlk4, blk4); + blk5 = _mm512_xor_epi64(tweakBlk5, blk5); + blk6 = _mm512_xor_epi64(tweakBlk6, blk6); + blk7 = _mm512_xor_epi64(tweakBlk7, blk7); + + tweakBlk4 = nextTweaks_x32(tweakBlk4); + tweakBlk5 = nextTweaks_x32(tweakBlk5); + tweakBlk6 = nextTweaks_x32(tweakBlk6); + tweakBlk7 = nextTweaks_x32(tweakBlk7); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + _mm512_storeu_si512(pOut512 + 3, blk3); + _mm512_storeu_si512(pOut512 + 4, blk4); + _mm512_storeu_si512(pOut512 + 5, blk5); + _mm512_storeu_si512(pOut512 + 6, blk6); + _mm512_storeu_si512(pOut512 + 7, blk7); + + pInp512 += 8; + pOut512 += 8; + } + + if ((4 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + __m512i blk3 = _mm512_loadu_si512(pInp512 + 3); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + + cpAESEncrypt4_VAES_NI(&blk0, &blk1, &blk2, &blk3, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + _mm512_storeu_si512(pOut512 + 3, blk3); + + tailTweaksConsumedCount += 4; + pInp512 += 4; + pOut512 += 4; + blocks -= (4 * 4); + } + + if ((3 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + tweakBlk1 = M512(pInitialTweaks + tailTweaksConsumedCount + 1); + tweakBlk2 = M512(pInitialTweaks + tailTweaksConsumedCount + 2); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + + cpAESEncrypt3_VAES_NI(&blk0, &blk1, &blk2, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + + tailTweaksConsumedCount += 3; + pInp512 += 3; + pOut512 += 3; + blocks -= (3 * 4); + } + else if ((2 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + tweakBlk1 = M512(pInitialTweaks + tailTweaksConsumedCount + 1); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + + cpAESEncrypt2_VAES_NI(&blk0, &blk1, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + + tailTweaksConsumedCount += 2; + pInp512 += 2; + pOut512 += 2; + blocks -= (2 * 4); + } + else if ((1 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + cpAESEncrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + _mm512_storeu_si512(pOut512, blk0); + + tailTweaksConsumedCount += 1; + pInp512 += 1; + pOut512 += 1; + blocks -= (1 * 4); + } + + if (blocks) { + __mmask8 k = (__mmask8)((1 << (blocks + blocks)) - 1); + __m512i blk0 = _mm512_maskz_loadu_epi64(k, pInp512); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + cpAESEncrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + _mm512_mask_storeu_epi64(pOut512, k, blk0); + } + + { + __mmask8 maskTweakToReturn = (__mmask8)(((Ipp8u)0x03u << (blocks << 1))); + _mm512_mask_compressstoreu_epi64(pTweak, maskTweakToReturn /* the first unused tweak */, tweakBlk0); + } + +} + +IPP_OWN_DEFN (void, cpAESDecryptXTS_VAES, (Ipp8u* outBlk, const Ipp8u* inpBlk, int nBlks, const Ipp8u* pRKey, int nr, Ipp8u* pTweak)) +{ + if (0 == nBlks) { + return; // do not modify tweak value + } + + int cipherRounds = nr - 1; + + __m128i* pRkey = (__m128i*)pRKey + cipherRounds + 1; + __m512i* pInp512 = (__m512i*)inpBlk; + __m512i* pOut512 = (__m512i*)outBlk; + + /* Produce initial 32 tweaks */ + __ALIGN64 Ipp8u tempTweakBuffer[AES_BLK_SIZE * 4 * 8]; // 32 tweaks + cpXTSwhitening(tempTweakBuffer, 8, pTweak); // generate 8 tweaks + + const __m512i* pInitialTweaks = (const __m512i*)tempTweakBuffer; + + int tailTweaksConsumedCount = 0; + + __m512i tweakBlk0 = M512(pInitialTweaks); + __m512i tweakBlk1 = M512(pInitialTweaks + 1); + __m512i tweakBlk2 = M512(pInitialTweaks + 2); + __m512i tweakBlk3 = M512(pInitialTweaks + 3); + __m512i tweakBlk4 = M512(pInitialTweaks + 4); + __m512i tweakBlk5 = M512(pInitialTweaks + 5); + __m512i tweakBlk6 = M512(pInitialTweaks + 6); + __m512i tweakBlk7 = M512(pInitialTweaks + 7); + + // generate other 24 tweaks + tweakBlk2 = nextTweaks_x8(tweakBlk0); + tweakBlk3 = nextTweaks_x8(tweakBlk1); + tweakBlk4 = nextTweaks_x8(tweakBlk2); + tweakBlk5 = nextTweaks_x8(tweakBlk3); + tweakBlk6 = nextTweaks_x8(tweakBlk4); + tweakBlk7 = nextTweaks_x8(tweakBlk5); + + int blocks; + for (blocks = nBlks; blocks >= (4 * 8); blocks -= (4 * 8)) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + __m512i blk3 = _mm512_loadu_si512(pInp512 + 3); + __m512i blk4 = _mm512_loadu_si512(pInp512 + 4); + __m512i blk5 = _mm512_loadu_si512(pInp512 + 5); + __m512i blk6 = _mm512_loadu_si512(pInp512 + 6); + __m512i blk7 = _mm512_loadu_si512(pInp512 + 7); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + blk4 = _mm512_xor_epi64(tweakBlk4, blk4); + blk5 = _mm512_xor_epi64(tweakBlk5, blk5); + blk6 = _mm512_xor_epi64(tweakBlk6, blk6); + blk7 = _mm512_xor_epi64(tweakBlk7, blk7); + + cpAESDecrypt4_VAES_NI(&blk0, &blk1, &blk2, &blk3, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + + tweakBlk0 = nextTweaks_x32(tweakBlk0); + tweakBlk1 = nextTweaks_x32(tweakBlk1); + tweakBlk2 = nextTweaks_x32(tweakBlk2); + tweakBlk3 = nextTweaks_x32(tweakBlk3); + + cpAESDecrypt4_VAES_NI(&blk4, &blk5, &blk6, &blk7, pRkey, cipherRounds); + + blk4 = _mm512_xor_epi64(tweakBlk4, blk4); + blk5 = _mm512_xor_epi64(tweakBlk5, blk5); + blk6 = _mm512_xor_epi64(tweakBlk6, blk6); + blk7 = _mm512_xor_epi64(tweakBlk7, blk7); + + tweakBlk4 = nextTweaks_x32(tweakBlk4); + tweakBlk5 = nextTweaks_x32(tweakBlk5); + tweakBlk6 = nextTweaks_x32(tweakBlk6); + tweakBlk7 = nextTweaks_x32(tweakBlk7); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + _mm512_storeu_si512(pOut512 + 3, blk3); + _mm512_storeu_si512(pOut512 + 4, blk4); + _mm512_storeu_si512(pOut512 + 5, blk5); + _mm512_storeu_si512(pOut512 + 6, blk6); + _mm512_storeu_si512(pOut512 + 7, blk7); + + pInp512 += 8; + pOut512 += 8; + } + + if ((4 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + __m512i blk3 = _mm512_loadu_si512(pInp512 + 3); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + + cpAESDecrypt4_VAES_NI(&blk0, &blk1, &blk2, &blk3, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + blk3 = _mm512_xor_epi64(tweakBlk3, blk3); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + _mm512_storeu_si512(pOut512 + 3, blk3); + + tailTweaksConsumedCount += 4; + pInp512 += 4; + pOut512 += 4; + blocks -= (4 * 4); + } + + if ((3 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + __m512i blk2 = _mm512_loadu_si512(pInp512 + 2); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + tweakBlk1 = M512(pInitialTweaks + tailTweaksConsumedCount + 1); + tweakBlk2 = M512(pInitialTweaks + tailTweaksConsumedCount + 2); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + + cpAESDecrypt3_VAES_NI(&blk0, &blk1, &blk2, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + blk2 = _mm512_xor_epi64(tweakBlk2, blk2); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + _mm512_storeu_si512(pOut512 + 2, blk2); + + tailTweaksConsumedCount += 3; + pInp512 += 3; + pOut512 += 3; + blocks -= (3 * 4); + } + else if ((2 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + __m512i blk1 = _mm512_loadu_si512(pInp512 + 1); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + tweakBlk1 = M512(pInitialTweaks + tailTweaksConsumedCount + 1); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + + cpAESDecrypt2_VAES_NI(&blk0, &blk1, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + blk1 = _mm512_xor_epi64(tweakBlk1, blk1); + + _mm512_storeu_si512(pOut512, blk0); + _mm512_storeu_si512(pOut512 + 1, blk1); + + tailTweaksConsumedCount += 2; + pInp512 += 2; + pOut512 += 2; + blocks -= (2 * 4); + } + else if ((1 * 4) <= blocks) { + __m512i blk0 = _mm512_loadu_si512(pInp512); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + cpAESDecrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + _mm512_storeu_si512(pOut512, blk0); + + tailTweaksConsumedCount += 1; + pInp512 += 1; + pOut512 += 1; + blocks -= (1 * 4); + } + + if (blocks) { + __mmask8 k = (__mmask8)((1 << (blocks + blocks)) - 1); + __m512i blk0 = _mm512_maskz_loadu_epi64(k, pInp512); + + tweakBlk0 = M512(pInitialTweaks + tailTweaksConsumedCount); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + cpAESDecrypt1_VAES_NI(&blk0, pRkey, cipherRounds); + + blk0 = _mm512_xor_epi64(tweakBlk0, blk0); + + _mm512_mask_storeu_epi64(pOut512, k, blk0); + } + + { + __mmask8 maskTweakToReturn = (__mmask8)(((Ipp8u)0x03u << (blocks << 1))); + _mm512_mask_compressstoreu_epi64(pTweak, maskTweakToReturn /* the first unused tweak */, tweakBlk0); + } +} + +#endif /* (_IPP32E>=_IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsdecrypt.c new file mode 100644 index 000000000..a21aa72a9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsdecrypt.c @@ -0,0 +1,181 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-XTS Functions (IEEE P1619) +// +// Contents: +// ippsAES_XTSDecrypt() +// +*/ + +#include "owncp.h" +#include "pcpaesmxts.h" +#include "pcptool.h" +#include "pcpaesmxtsstuff.h" + + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +// +// +static void cpAES_XTS_DecBlock(Ipp8u* ctxt, const Ipp8u* ptxt, const Ipp8u* tweak, const IppsAESSpec* pEncCtx) +{ + /* pre-whitening */ + XorBlock16(ptxt, tweak, ctxt); + /* encryption */ + ippsAESDecryptECB(ctxt, ctxt, AES_BLK_SIZE, pEncCtx); + /* post-whitening */ + XorBlock16(ctxt, tweak, ctxt); +} + +/*F* +// Name: ippsAES_XTSDecrypt +// +// Purpose: AES-XTS decryption. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pDst == NULL +// pTweak ==NULL +// pCtx == NULL +// ippStsLengthErr bitLen <128 +// ippStsContextMatchErr !VALID_AES_XTS_ID(pCtx) +// ippStsBadArgErr !IsLegalGeometry(startCipherBlkNo, +// bitLen, pCtx->duBitsize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc points input buffer +// pDst points output buffer +// bitLen length of the input buffer in bits +// startCipherBlkNo number of the first block for data unit +// pTweak points tweak value +// pCtx points AES_XTS context +// +*F*/ + +IPPFUN(IppStatus, ippsAES_XTSDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int bitLen, + const IppsAES_XTSSpec* pCtx, + const Ipp8u* pTweak, + int startCipherBlkNo)) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_XTS_ID(pCtx), ippStsContextMatchErr); + + /* test data pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pTweak); + + /* test startCipherBlkNo and bitLen */ + IPP_BADARG_RET(bitLen < IPP_AES_BLOCK_BITSIZE, ippStsLengthErr); + IPP_BADARG_RET(!IsLegalGeometry(startCipherBlkNo, bitLen, pCtx->duBitsize), ippStsBadArgErr); + + { + __ALIGN16 Ipp8u tweakCT[AES_BLK_SIZE]; + + { /* encrypt tweak */ + const IppsAESSpec* ptwkAES = &pCtx->tweakAES; + + RijnCipher encoder = RIJ_ENCODER(ptwkAES); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pTweak, tweakCT, RIJ_NR(ptwkAES), RIJ_EKEYS(ptwkAES), RijEncSbox/*NULL*/); + #else + encoder(pTweak, tweakCT, RIJ_NR(ptwkAES), RIJ_EKEYS(ptwkAES), NULL); + #endif + + /* update tweakCT */ + for(; startCipherBlkNo>0; startCipherBlkNo--) + gf_mul_by_primitive(tweakCT); + } + + /* XTS decryption */ + { + const IppsAESSpec* pdatAES = &pCtx->datumAES; + + int encBlocks = bitLen/IPP_AES_BLOCK_BITSIZE; + int encBlocklast = bitLen%IPP_AES_BLOCK_BITSIZE; + if(encBlocklast) encBlocks--; + + /* decrypt data blocks */ + if( encBlocks>0) { + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use Intel(R) AES New Instructions version if possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pdatAES)) { + #if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + cpAESDecryptXTS_VAES(pDst, pSrc, encBlocks, RIJ_DKEYS(pdatAES), RIJ_NR(pdatAES), tweakCT); + } + else + #endif + cpAESDecryptXTS_AES_NI(pDst, pSrc, encBlocks, RIJ_DKEYS(pdatAES), RIJ_NR(pdatAES), tweakCT); + pSrc += encBlocks*AES_BLK_SIZE; + pDst += encBlocks*AES_BLK_SIZE; + } + else + #endif + { + for(; encBlocks>0; encBlocks--) { + cpAES_XTS_DecBlock(pDst, pSrc, tweakCT, pdatAES); + gf_mul_by_primitive(tweakCT); + pSrc += AES_BLK_SIZE; + pDst += AES_BLK_SIZE; + } + } + } + + /* "stealing" - decrypt last partial block if is */ + if(encBlocklast) { + int partBlockSize = encBlocklast/BYTESIZE; + + __ALIGN16 Ipp8u cc[AES_BLK_SIZE]; + __ALIGN16 Ipp8u pp[AES_BLK_SIZE]; + CopyBlock16(tweakCT, cc); + gf_mul_by_primitive(cc); + cpAES_XTS_DecBlock(pp, pSrc, cc, pdatAES); + + CopyBlock16(pp, cc); + CopyBlock(pSrc+AES_BLK_SIZE, cc, partBlockSize); + + encBlocklast %= BYTESIZE; + if(encBlocklast) { + Ipp8u partBlockMask = (Ipp8u)((0xFF)<<((BYTESIZE -encBlocklast) %BYTESIZE)); + Ipp8u x = pSrc[AES_BLK_SIZE+partBlockSize]; + Ipp8u y = cc[partBlockSize]; + x = (x & partBlockMask) | (y & ~partBlockMask); + cc[partBlockSize] = x; + pp[partBlockSize] &= partBlockMask; + partBlockSize++; + } + cpAES_XTS_DecBlock(pDst, cc, tweakCT, pdatAES); + + CopyBlock(pp, pDst+AES_BLK_SIZE, partBlockSize); + + /* clear secret data */ + PurgeBlock(pp, sizeof(pp)); + } + return ippStsNoErr; + } + } +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsdecrypt_direct.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsdecrypt_direct.c new file mode 100644 index 000000000..37df5d471 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsdecrypt_direct.c @@ -0,0 +1,229 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-XTS Functions (IEEE P1619) +// +// Contents: +// ippsAESDecryptXTS_Direct() +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaesmxtsstuff.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if !defined AES_BLK_SIZE +#define AES_BLK_SIZE (IPP_AES_BLOCK_BITSIZE/BITSIZE(Ipp8u)) +#endif + +#define AES_BLKS_PER_BUFFER (32) + + +/*F* +// Name: ippsAESDecryptXTS_Direct +// +// Purpose: AES-XTS decryption (see IEEE P1619-2007). +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pDst == NULL +// pTweak ==NULL +// pKey ==NULL +// ippStsLengthErr dataUnitBitsize <128 +// keyBitsize != 256, !=512 +// ippStsBadArgErr aesBlkNo >= dataUnitBitsize/IPP_AES_BLOCK_BITSIZE +// ippStsNoErr no errors +// +// Parameters: +// pSrc points input buffer +// pDst points output buffer +// encBitsize lendth of the input/output buffer in bits +// aesBlkNo number of the first block for data unit +// ptweakPT points tweak value +// pKey pointer to the XTS key +// keyBitsize length of the key in bits +// dataUnitBitsize length of Data Unit in bits +// +*F*/ +static IppStatus cpAES_XTS_DecBlock(Ipp8u* ctxt, const Ipp8u* ptxt, const Ipp8u* tweak, const IppsAESSpec* pEncCtx) +{ + IppStatus sts; + /* pre-whitening */ + XorBlock16(ptxt, tweak, ctxt); + /* decryption */ + sts = ippsAESDecryptECB(ctxt, ctxt, AES_BLK_SIZE, pEncCtx); + /* post-whitening */ + XorBlock16(ctxt, tweak, ctxt); + return sts; +} + +// +// To Do: advance parameter check!! +// +IPPFUN(IppStatus, ippsAESDecryptXTS_Direct,(const Ipp8u* pSrc, Ipp8u* pDst, int encBitsize, int aesBlkNo, + const Ipp8u* pTweakPT, + const Ipp8u* pKey, int keyBitsize, + int dataUnitBitsize)) +{ + /* test dataUnitBitsize */ + IPP_BADARG_RET(dataUnitBitsize (1<<27), ippStsBadArgErr); + + /* test dataUnitBitsize and aesBlkNo */ + IPP_BADARG_RET(((dataUnitBitsize/IPP_AES_BLOCK_BITSIZE)<=aesBlkNo) || (0>aesBlkNo), ippStsBadArgErr); + + { + IppStatus sts = ippStsNoErr; + + int keySize = keyBitsize/2/8; + const Ipp8u* pConfKey = pKey; + const Ipp8u* pTweakKey = pKey+keySize; + + do { + int encBlocks = encBitsize/IPP_AES_BLOCK_BITSIZE; + int encBlocklast = encBitsize%IPP_AES_BLOCK_BITSIZE; + + __ALIGN16 IppsAESSpec aesCtx; + __ALIGN16 Ipp8u tweakCT[AES_BLK_SIZE]; + __ALIGN16 Ipp8u tmp[AES_BLKS_PER_BUFFER*AES_BLK_SIZE]; + + sts = ippsAESInit(pTweakKey, keySize, &aesCtx, sizeof(aesCtx)); + if(ippStsNoErr!=sts) break; + + { + RijnCipher encoder = RIJ_ENCODER(&aesCtx); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pTweakPT, tweakCT, RIJ_NR(&aesCtx), RIJ_EKEYS(&aesCtx), RijEncSbox/*NULL*/); + #else + encoder(pTweakPT, tweakCT, RIJ_NR(&aesCtx), RIJ_EKEYS(&aesCtx), NULL); + #endif + } + + sts = ippsAESInit(pConfKey, keySize, &aesCtx, sizeof(aesCtx)); + if(ippStsNoErr!=sts) break; + + for(; aesBlkNo>0; aesBlkNo--) + gf_mul_by_primitive(tweakCT); + + if(encBlocklast) encBlocks--; + + /* + // decrypt data + */ + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use Intel(R) AES New Instructions version if possible */ + if(AES_NI_ENABLED==RIJ_AESNI(&aesCtx)) { + #if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + cpAESDecryptXTS_VAES(pDst, pSrc, encBlocks, RIJ_DKEYS(&aesCtx), RIJ_NR(&aesCtx), tweakCT); + } + else + #endif + cpAESDecryptXTS_AES_NI(pDst, pSrc, encBlocks, RIJ_DKEYS(&aesCtx), RIJ_NR(&aesCtx), tweakCT); + pSrc += encBlocks*AES_BLK_SIZE; + pDst += encBlocks*AES_BLK_SIZE; + } + else + #endif + { + for(; encBlocks>=AES_BLKS_PER_BUFFER && ippStsNoErr==sts; encBlocks-=AES_BLKS_PER_BUFFER) { + /* compute whitening tweaks */ + cpXTSwhitening(tmp, AES_BLKS_PER_BUFFER, tweakCT); + /* pre-whitening */ + cpXTSxor16(pDst, pSrc, tmp, AES_BLKS_PER_BUFFER); + + sts = ippsAESDecryptECB(pDst, pDst, AES_BLKS_PER_BUFFER*AES_BLK_SIZE, &aesCtx); + + /* post-whitening */ + cpXTSxor16(pDst, pDst, tmp, AES_BLKS_PER_BUFFER); + + pSrc += AES_BLKS_PER_BUFFER*AES_BLK_SIZE; + pDst += AES_BLKS_PER_BUFFER*AES_BLK_SIZE; + } + if(ippStsNoErr!=sts) break; + + if(encBlocks) { + cpXTSwhitening(tmp, encBlocks, tweakCT); + + /* pre-whitening */ + cpXTSxor16(pDst, pSrc, tmp, encBlocks); + + ippsAESDecryptECB(pDst, pDst, AES_BLK_SIZE*encBlocks, &aesCtx); + + /* post-whitening */ + cpXTSxor16(pDst, pDst, tmp, encBlocks); + + pSrc += AES_BLK_SIZE*encBlocks; + pDst += AES_BLK_SIZE*encBlocks; + } + } + + /* "stealing" - encrypt last partial block if is */ + if(encBlocklast) { + int partBlockSize = encBlocklast/BYTESIZE; + + __ALIGN16 Ipp8u cc[AES_BLK_SIZE]; + __ALIGN16 Ipp8u pp[AES_BLK_SIZE]; + CopyBlock16(tweakCT, cc); + gf_mul_by_primitive(cc); + cpAES_XTS_DecBlock(pp, pSrc, cc, &aesCtx); + + CopyBlock16(pp, cc); + CopyBlock(pSrc+AES_BLK_SIZE, cc, partBlockSize); + + encBlocklast %= BYTESIZE; + if(encBlocklast) { + Ipp8u partBlockMask = (Ipp8u)((0xFF)<<((BYTESIZE -encBlocklast) %BYTESIZE)); + Ipp8u x = pSrc[AES_BLK_SIZE+partBlockSize]; + Ipp8u y = cc[partBlockSize]; + x = (x & partBlockMask) | (y & ~partBlockMask); + cc[partBlockSize] = x; + pp[partBlockSize] &= partBlockMask; + partBlockSize++; + } + cpAES_XTS_DecBlock(pDst, cc, tweakCT, &aesCtx); + + CopyBlock(pp, pDst+AES_BLK_SIZE, partBlockSize); + + /* clear secret data */ + PurgeBlock(pp, sizeof(pp)); + } + + } while(0); + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsencrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsencrypt.c new file mode 100644 index 000000000..5c45f21dc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsencrypt.c @@ -0,0 +1,175 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-XTS Functions (IEEE P1619) +// +// Contents: +// ippsAES_XTSEncrypt() +// +*/ + +#include "owncp.h" +#include "pcpaesmxts.h" +#include "pcptool.h" +#include "pcpaesmxtsstuff.h" + + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +static void cpAES_XTS_EncBlock(Ipp8u* ctxt, const Ipp8u* ptxt, const Ipp8u* tweak, const IppsAESSpec* pEncCtx) +{ + /* pre-whitening */ + XorBlock16(ptxt, tweak, ctxt); + /* encryption */ + ippsAESEncryptECB(ctxt, ctxt, AES_BLK_SIZE, pEncCtx); + /* post-whitening */ + XorBlock16(ctxt, tweak, ctxt); +} + +/*F* +// Name: ippsAES_XTSEncrypt +// +// Purpose: AES-XTS encryption. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pDst == NULL +// pTweak ==NULL +// pCtx == NULL +// ippStsLengthErr bitLen <128 +// ippStsContextMatchErr !VALID_AES_XTS_ID(pCtx) +// ippStsBadArgErr !IsLegalGeometry(startCipherBlkNo, +// bitLen, pCtx->duBitsize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc points input buffer +// pDst points output buffer +// bitLen length of the input buffer in bits +// startCipherBlkNo number of the first block for data unit +// pTweak points tweak value +// pCtx points AES_XTS context +// +*F*/ + +IPPFUN(IppStatus, ippsAES_XTSEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int bitLen, + const IppsAES_XTSSpec* pCtx, + const Ipp8u* pTweak, + int startCipherBlkNo)) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_XTS_ID(pCtx), ippStsContextMatchErr); + + /* test data pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pTweak); + + /* test startCipherBlkNo and bitLen */ + IPP_BADARG_RET(bitLen < IPP_AES_BLOCK_BITSIZE, ippStsLengthErr); + IPP_BADARG_RET(!IsLegalGeometry(startCipherBlkNo, bitLen, pCtx->duBitsize), ippStsBadArgErr); + + { + __ALIGN16 Ipp8u tweakCT[AES_BLK_SIZE]; + + { /* encrypt tweak */ + const IppsAESSpec* ptwkAES = &pCtx->tweakAES; + + RijnCipher encoder = RIJ_ENCODER(ptwkAES); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pTweak, tweakCT, RIJ_NR(ptwkAES), RIJ_EKEYS(ptwkAES), RijEncSbox/*NULL*/); + #else + encoder(pTweak, tweakCT, RIJ_NR(ptwkAES), RIJ_EKEYS(ptwkAES), NULL); + #endif + + /* update tweakCT */ + for(; startCipherBlkNo>0; startCipherBlkNo--) + gf_mul_by_primitive(tweakCT); + } + + /* XTS encryption */ + { + const IppsAESSpec* pdatAES = &pCtx->datumAES; + + int encBlocks = bitLen/IPP_AES_BLOCK_BITSIZE; + int encBlocklast = bitLen%IPP_AES_BLOCK_BITSIZE; + if(encBlocklast) encBlocks--; + + /* encrypt data blocks */ + if( encBlocks>0) { + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use Intel(R) AES New Instructions version if possible */ + if(AES_NI_ENABLED==RIJ_AESNI(pdatAES)) { + #if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + cpAESEncryptXTS_VAES(pDst, pSrc, encBlocks, RIJ_EKEYS(pdatAES), RIJ_NR(pdatAES), tweakCT); + } + else + #endif + cpAESEncryptXTS_AES_NI(pDst, pSrc, encBlocks, RIJ_EKEYS(pdatAES), RIJ_NR(pdatAES), tweakCT); + pSrc += encBlocks*AES_BLK_SIZE; + pDst += encBlocks*AES_BLK_SIZE; + } + else + #endif + { + for(; encBlocks>0; encBlocks--) { + cpAES_XTS_EncBlock(pDst, pSrc, tweakCT, pdatAES); + gf_mul_by_primitive(tweakCT); + pSrc += AES_BLK_SIZE; + pDst += AES_BLK_SIZE; + } + } + } + + /* "stealing" - encrypt last partial block if is */ + if(encBlocklast) { + int partBlockSize = encBlocklast/BYTESIZE; + + __ALIGN16 Ipp8u cc[AES_BLK_SIZE]; + __ALIGN16 Ipp8u pp[AES_BLK_SIZE]; + cpAES_XTS_EncBlock(cc, pSrc, tweakCT, pdatAES); + gf_mul_by_primitive(tweakCT); + + CopyBlock16(cc, pp); + CopyBlock(pSrc+AES_BLK_SIZE, pp, partBlockSize); + + encBlocklast %= BYTESIZE; + if(encBlocklast) { + Ipp8u partBlockMask = (Ipp8u)((0xFF)<<((BYTESIZE -encBlocklast) %BYTESIZE)); + Ipp8u x = pSrc[AES_BLK_SIZE+partBlockSize]; + Ipp8u y = cc[partBlockSize]; + x = (x & partBlockMask) | (y & ~partBlockMask); + pp[partBlockSize] = x; + cc[partBlockSize] &= partBlockMask; + partBlockSize++; + } + cpAES_XTS_EncBlock(pDst, pp, tweakCT, pdatAES); + + CopyBlock(cc, pDst+AES_BLK_SIZE, partBlockSize); + } + return ippStsNoErr; + } + } +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsencrypt_direct.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsencrypt_direct.c new file mode 100644 index 000000000..d5b5cc1d3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsencrypt_direct.c @@ -0,0 +1,224 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-XTS Functions (IEEE P1619) +// +// Contents: +// ippsAESEncryptXTS_Direct() +// +*/ + +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaesmxtsstuff.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if !defined AES_BLK_SIZE +#define AES_BLK_SIZE (IPP_AES_BLOCK_BITSIZE/BITSIZE(Ipp8u)) +#endif + +#define AES_BLKS_PER_BUFFER (32) + + +/*F* +// Name: ippsAESEncryptXTS_Direct +// +// Purpose: AES-XTS encryption (see IEEE P1619-2007). +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pDst == NULL +// pTweak ==NULL +// pKey ==NULL +// ippStsLengthErr dataUnitBitsize <128 +// keyBitsize != 256, !=512 +// ippStsBadArgErr aesBlkNo >= dataUnitBitsize/IPP_AES_BLOCK_BITSIZE +// aesBlkNo < 0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc points input buffer +// pDst points output buffer +// encBitsize length of the input/output buffer in bits +// aesBlkNo number of the first block for data unit +// ptweakPT points tweak value +// pKey pointer to the XTS key +// keyBitsize length of the key in bits +// dataUnitBitsize length of Data Unit in bits +// +*F*/ +static IppStatus cpAES_XTS_EncBlock(Ipp8u* ctxt, const Ipp8u* ptxt, const Ipp8u* tweak, const IppsAESSpec* pEncCtx) +{ + IppStatus sts; + /* pre-whitening */ + XorBlock16(ptxt, tweak, ctxt); + /* encryption */ + sts = ippsAESEncryptECB(ctxt, ctxt, AES_BLK_SIZE, pEncCtx); + /* post-whitening */ + XorBlock16(ctxt, tweak, ctxt); + return sts; +} + +IPPFUN(IppStatus, ippsAESEncryptXTS_Direct,(const Ipp8u* pSrc, Ipp8u* pDst, int encBitsize, int aesBlkNo, + const Ipp8u* pTweakPT, + const Ipp8u* pKey, int keyBitsize, + int dataUnitBitsize)) +{ + /* test dataUnitBitsize */ + IPP_BADARG_RET(dataUnitBitsize (1<<27), ippStsBadArgErr); + + /* test dataUnitBitsize and aesBlkNo */ + IPP_BADARG_RET(((dataUnitBitsize/IPP_AES_BLOCK_BITSIZE)<=aesBlkNo) || (0>aesBlkNo), ippStsBadArgErr); + + { + IppStatus sts = ippStsNoErr; + + int keySize = keyBitsize/2/8; + const Ipp8u* pConfKey = pKey; + const Ipp8u* pTweakKey = pKey+keySize; + + do { + int encBlocks = encBitsize/IPP_AES_BLOCK_BITSIZE; + int encBlocklast = encBitsize%IPP_AES_BLOCK_BITSIZE; + + __ALIGN16 IppsAESSpec aesCtx; + __ALIGN16 Ipp8u tweakCT[AES_BLK_SIZE]; + __ALIGN16 Ipp8u tmp[AES_BLKS_PER_BUFFER*AES_BLK_SIZE]; + __ALIGN16 Ipp8u tmpDst[AES_BLKS_PER_BUFFER*AES_BLK_SIZE]; + + sts = ippsAESInit(pTweakKey, keySize, &aesCtx, sizeof(aesCtx)); + if(ippStsNoErr!=sts) break; + + { + RijnCipher encoder = RIJ_ENCODER(&aesCtx); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pTweakPT, tweakCT, RIJ_NR(&aesCtx), RIJ_EKEYS(&aesCtx), RijEncSbox/*NULL*/); + #else + encoder(pTweakPT, tweakCT, RIJ_NR(&aesCtx), RIJ_EKEYS(&aesCtx), NULL); + #endif + } + + sts = ippsAESInit(pConfKey, keySize, &aesCtx, sizeof(aesCtx)); + if(ippStsNoErr!=sts) break; + + for(; aesBlkNo>0; aesBlkNo--) + gf_mul_by_primitive(tweakCT); + + if(encBlocklast) encBlocks--; + + /* + // encrypt data + */ + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + /* use Intel(R) AES New Instructions version if possible */ + if(AES_NI_ENABLED==RIJ_AESNI(&aesCtx)) { + #if(_IPP32E>=_IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { + cpAESEncryptXTS_VAES(pDst, pSrc, encBlocks, RIJ_EKEYS(&aesCtx), RIJ_NR(&aesCtx), tweakCT); + } + else + #endif + cpAESEncryptXTS_AES_NI(pDst, pSrc, encBlocks, RIJ_EKEYS(&aesCtx), RIJ_NR(&aesCtx), tweakCT); + pSrc += encBlocks*AES_BLK_SIZE; + pDst += encBlocks*AES_BLK_SIZE; + } + else + #endif + { + for(; encBlocks>=AES_BLKS_PER_BUFFER && ippStsNoErr==sts; encBlocks-=AES_BLKS_PER_BUFFER) { + /* compute whitening tweaks */ + cpXTSwhitening(tmp, AES_BLKS_PER_BUFFER, tweakCT); + /* pre-whitening */ + cpXTSxor16(tmpDst, pSrc, tmp, AES_BLKS_PER_BUFFER); + + sts = ippsAESEncryptECB(tmpDst, pDst, AES_BLKS_PER_BUFFER*AES_BLK_SIZE, &aesCtx); + + /* post-whitening */ + cpXTSxor16(pDst, pDst, tmp, AES_BLKS_PER_BUFFER); + + pSrc += AES_BLKS_PER_BUFFER*AES_BLK_SIZE; + pDst += AES_BLKS_PER_BUFFER*AES_BLK_SIZE; + } + if(ippStsNoErr!=sts) break; + + if(encBlocks) { + cpXTSwhitening(tmp, encBlocks, tweakCT); + + /* pre-whitening */ + cpXTSxor16(tmpDst, pSrc, tmp, encBlocks); + + ippsAESEncryptECB(tmpDst, pDst, AES_BLK_SIZE*encBlocks, &aesCtx); + + /* post-whitening */ + cpXTSxor16(pDst, pDst, tmp, encBlocks); + + pSrc += AES_BLK_SIZE*encBlocks; + pDst += AES_BLK_SIZE*encBlocks; + } + } + + /* "stealing" - encrypt last partial block if is */ + if(encBlocklast) { + int partBlockSize = encBlocklast/BYTESIZE; + + __ALIGN16 Ipp8u cc[AES_BLK_SIZE]; + __ALIGN16 Ipp8u pp[AES_BLK_SIZE]; + cpAES_XTS_EncBlock(cc, pSrc, tweakCT, &aesCtx); + gf_mul_by_primitive(tweakCT); + + CopyBlock16(cc, pp); + CopyBlock(pSrc+AES_BLK_SIZE, pp, partBlockSize); + + encBlocklast %= BYTESIZE; + if(encBlocklast) { + Ipp8u partBlockMask = (Ipp8u)((0xFF)<<((BYTESIZE -encBlocklast) %BYTESIZE)); + Ipp8u x = pSrc[AES_BLK_SIZE+partBlockSize]; + Ipp8u y = cc[partBlockSize]; + x = (x & partBlockMask) | (y & ~partBlockMask); + pp[partBlockSize] = x; + cc[partBlockSize] &= partBlockMask; + partBlockSize++; + } + cpAES_XTS_EncBlock(pDst, pp, tweakCT, &aesCtx); + + CopyBlock(cc, pDst+AES_BLK_SIZE, partBlockSize); + } + + } while(0); + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsinit.c new file mode 100644 index 000000000..106b72a0c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaes_xtsinit.c @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-XTS Functions (IEEE P1619) +// +// Contents: +// ippsAES_XTSInit() +// +*/ + +#include "owncp.h" +#include "pcpaesmxts.h" +#include "pcptool.h" + +/*F* +// Name: ippsAES_XTSInit +// +// Purpose: Init AES_XTS context for future usage. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// ippStsMemAllocErr size of buffer is not match fro operation +// ippStsLengthErr keyLen != 16*8*2 && +// != 32*8*2 +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length of the secret key in bits +// pCtx pointer to the AES-XTS context +// ctxSize available size (in bytes) of buffer above +// duBitSize length of Data Unit in bits +// +*F*/ + +IPPFUN(IppStatus, ippsAES_XTSInit,(const Ipp8u* pKey, int keyLen, + int duBitsize, + IppsAES_XTSSpec* pCtx, int ctxSize)) +{ + /* test key and keyLenBits */ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(keyLen!=16*BYTESIZE*2 && keyLen!=32*BYTESIZE*2, ippStsLengthErr); + + /* test DU parameters */ + IPP_BADARG_RET(duBitsize ctxSize, ippStsMemAllocErr); + + { + IppsAESSpec* pdatAES = &pCtx->datumAES; + IppsAESSpec* ptwkAES = &pCtx->tweakAES; + + int keySize = keyLen/2/BYTESIZE; + const Ipp8u* pdatKey = pKey; + const Ipp8u* ptwkKey = pKey+keySize; + + IppStatus sts = ippStsNoErr; + sts = ippsAESInit(pdatKey, keySize, pdatAES, sizeof(IppsAESSpec)); + if(ippStsNoErr!=sts) return sts; + + sts = ippsAESInit(ptwkKey, keySize, ptwkAES, sizeof(IppsAESSpec)); + if(ippStsNoErr!=sts) return sts; + + AES_XTS_SET_ID(pCtx); + pCtx->duBitsize = duBitsize; + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesauthccm.h b/plugin/ippcp/library/src/sources/ippcp/pcpaesauthccm.h new file mode 100644 index 000000000..a6b6d1592 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesauthccm.h @@ -0,0 +1,99 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message Authentication Algorithm +// Internal Definitions and Internal Functions Prototypes +// +// +*/ + +#if !defined(_CP_AES_CCM_H) +#define _CP_AES_CCM_H + +#include "pcprij.h" +#include "pcpaesm.h" + +struct _cpAES_CCM { + Ipp32u idCtx; /* CCM ID */ + + Ipp64u msgLen; /* length of message to be processed */ + Ipp64u lenProcessed; /* message length has been processed */ + Ipp32u tagLen; /* length of authentication tag */ + Ipp32u counterVal; /* current counter value */ + Ipp8u ctr0[MBS_RIJ128]; /* counter value */ + Ipp8u s0[MBS_RIJ128]; /* S0 = ENC(CTR0) content */ + Ipp8u si[MBS_RIJ128]; /* Si = ENC(CTRi) content */ + Ipp8u blk[MBS_RIJ128]; /* temporary data container */ + Ipp8u mac[MBS_RIJ128]; /* current MAC value */ + + Ipp8u cipher[sizeof(IppsAESSpec)]; +}; + +/* alignment */ +#define AESCCM_ALIGNMENT ((int)(sizeof(void*))) + +/* +// access macros +*/ +#define AESCCM_SET_ID(stt) ((stt)->idCtx = (Ipp32u)idCtxAESCCM ^ (Ipp32u)IPP_UINT_PTR(stt)) +#define AESCCM_MSGLEN(stt) ((stt)->msgLen) +#define AESCCM_LENPRO(stt) ((stt)->lenProcessed) +#define AESCCM_TAGLEN(stt) ((stt)->tagLen) +#define AESCCM_COUNTER(stt) ((stt)->counterVal) +#define AESCCM_CTR0(stt) ((stt)->ctr0) +#define AESCCM_S0(stt) ((stt)->s0) +#define AESCCM_Si(stt) ((stt)->si) +#define AESCCM_BLK(stt) ((stt)->blk) +#define AESCCM_MAC(stt) ((stt)->mac) +#define AESCCM_CIPHER(stt) (IppsAESSpec*)(&((stt)->cipher)) + +/* valid context ID */ +#define VALID_AESCCM_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxAESCCM) + +/* +// Internal functions +*/ +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) +#define AuthEncrypt_RIJ128_AES_NI OWNAPI(AuthEncrypt_RIJ128_AES_NI) + IPP_OWN_DECL (void, AuthEncrypt_RIJ128_AES_NI, (const Ipp8u* inpBlk, Ipp8u* outBlk, int nr, const void* pRKey, Ipp32u len, void* pLocalCtx)) +#define DecryptAuth_RIJ128_AES_NI OWNAPI(DecryptAuth_RIJ128_AES_NI) + IPP_OWN_DECL (void, DecryptAuth_RIJ128_AES_NI, (const Ipp8u* inpBlk, Ipp8u* outBlk, int nr, const void* pRKey, Ipp32u len, void* pLocalCtx)) +#endif + +/* Counter block formatter */ +static Ipp8u* CounterEnc(Ipp32u* pBuffer, int fmt, Ipp64u counter) +{ + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + pBuffer[0] = ENDIANNESS(IPP_HIDWORD(counter)); + pBuffer[1] = ENDIANNESS(IPP_LODWORD(counter)); + #else + pBuffer[0] = IPP_HIDWORD(counter); + pBuffer[1] = IPP_LODWORD(counter); + #endif + return (Ipp8u*)pBuffer + 8 - fmt; +} + +static int cpSizeofCtx_AESCCM(void) +{ + return sizeof(IppsAES_CCMState); +} + +#endif /* _CP_AES_CCM_H*/ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesauthgcm.h b/plugin/ippcp/library/src/sources/ippcp/pcpaesauthgcm.h new file mode 100644 index 000000000..d33a1441a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesauthgcm.h @@ -0,0 +1,237 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message Authentication Algorithm +// Internal Definitions and Internal Functions Prototypes +// +// +*/ + +#if !defined(_CP_AESAUTH_GCM_H) +#define _CP_AESAUTH_GCM_H + +#include "owncp.h" +#include "pcpaesm.h" + +#if(_IPP32E < _IPP32E_K0) + +#define BLOCK_SIZE (MBS_RIJ128) + +/* GCM Hash prototype: GHash = GHash*HKey mod G() */ +IPP_OWN_FUNPTR (void, MulGcm_, (Ipp8u* pGHash, const Ipp8u* pHKey, const void* pParam)) + +/* GCM Authentication prototype: GHash = (GHash^src[])*HKey mod G() */ +IPP_OWN_FUNPTR (void, Auth_, (Ipp8u* pHash, const Ipp8u* pSrc, int len, const Ipp8u* pHKey, const void* pParam)) + +/* GCM Encrypt_Authentication prototype */ +IPP_OWN_FUNPTR (void, Encrypt_, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) + +/* GCM Authentication_Decrypt prototype */ +IPP_OWN_FUNPTR (void, Decrypt_, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) + +typedef enum { + GcmInit, + GcmIVprocessing, + GcmAADprocessing, + GcmTXTprocessing +} GcmState; + +struct _cpAES_GCM { + + Ipp32u idCtx; /* AES-GCM id */ + GcmState state; /* GCM state: Init, IV|AAD|TXT processing */ + Ipp64u ivLen; /* IV length (bytes) */ + Ipp64u aadLen; /* header length (bytes) */ + Ipp64u txtLen; /* text length (bytes) */ + + int bufLen; /* stuff buffer length */ + __ALIGN16 /* aligned buffers */ + Ipp8u counter[BLOCK_SIZE]; /* counter */ + Ipp8u ecounter0[BLOCK_SIZE]; /* encrypted initial counter */ + Ipp8u ecounter[BLOCK_SIZE]; /* encrypted counter */ + Ipp8u ghash[BLOCK_SIZE]; /* ghash accumulator */ + + MulGcm_ hashFun; /* AES-GCM mul function */ + Auth_ authFun; /* authentication function */ + Encrypt_ encFun; /* encryption & authentication */ + Decrypt_ decFun; /* authentication & decryption */ + + __ALIGN16 /* aligned AES context */ + IppsAESSpec cipher; + +#if (_AES_PROB_NOISE == _FEATURE_ON_) + __ALIGN16 + cpAESNoiseParams noiseParams; +#endif + + __ALIGN16 /* aligned pre-computed data: */ + Ipp8u multiplier[BLOCK_SIZE]; /* - (default) hKey */ + /* - (aes_ni) hKey*t, (hKey*t)^2, (hKey*t)^4 */ + /* - (vaes_ni) 8 reverted ordered vectors by 4 128-bit values. + hKeys derivations in the multiplier[] array in order of appearance + (zero-index starts from the left): + hKey^4<<1, hKey^3<<1, hKey^2<<1, hKey<<1, + hKey^8<<1, hKey^7<<1, hKey^6<<1, hKey^5<<1, + hKey^12<<1, hKey^11<<1, hKey^10<<1, hKey^9<<1, + hKey^16<<1, hKey^15<<1, hKey^14<<1, hKey^13<<1, + ... ... + */ + /* - (safe) hKey*(t^i), i=0,...,127 */ +}; + +#define CTR_POS 12 + +/* alignment */ +#define AESGCM_ALIGNMENT (16) + +#define PRECOMP_DATA_SIZE_AES_NI_AESGCM (BLOCK_SIZE*4) +#define PRECOMP_DATA_SIZE_VAES_NI_AESGCM (BLOCK_SIZE*16*2) +#define PRECOMP_DATA_SIZE_FAST2K (BLOCK_SIZE*128) + +/* +// Useful macros +*/ +#define AESGCM_SET_ID(context) ((context)->idCtx = (Ipp32u)idCtxAESGCM ^ (Ipp32u)IPP_UINT_PTR(context)) +#define AESGCM_STATE(context) ((context)->state) + +#define AESGCM_IV_LEN(context) ((context)->ivLen) +#define AESGCM_AAD_LEN(context) ((context)->aadLen) +#define AESGCM_TXT_LEN(context) ((context)->txtLen) + +#define AESGCM_BUFLEN(context) ((context)->bufLen) +#define AESGCM_COUNTER(context) ((context)->counter) +#define AESGCM_ECOUNTER0(context) ((context)->ecounter0) +#define AESGCM_ECOUNTER(context) ((context)->ecounter) +#define AESGCM_GHASH(context) ((context)->ghash) + +#define AESGCM_HASH(context) ((context)->hashFun) +#define AESGCM_AUTH(context) ((context)->authFun) +#define AESGCM_ENC(context) ((context)->encFun) +#define AESGCM_DEC(context) ((context)->decFun) + +#define AESGCM_CIPHER(context) (IppsAESSpec*)(&((context)->cipher)) + +#if (_AES_PROB_NOISE == _FEATURE_ON_) +#define AESGCM_NOISE_PARAMS(context) ((context)->noiseParams) +#endif + +#define AESGCM_HKEY(context) ((context)->multiplier) +#define AESGCM_CPWR(context) ((context)->multiplier) +#define AES_GCM_MTBL(context) ((context)->multiplier) + +#define AESGCM_VALID_ID(context) ((((context)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((context))) == (Ipp32u)idCtxAESGCM) + +#if 0 +__INLINE void IncrementCounter32(Ipp8u* pCtr) +{ + int i; + for(i=BLOCK_SIZE-1; i>=CTR_POS && 0==(Ipp8u)(++pCtr[i]); i--) ; +} +#endif +__INLINE void IncrementCounter32(Ipp8u* pCtr) +{ + Ipp32u* pCtr32 = (Ipp32u*)pCtr; + Ipp32u ctrVal = pCtr32[3]; + ctrVal = ENDIANNESS32(ctrVal); + ctrVal++; + ctrVal = ENDIANNESS32(ctrVal); + pCtr32[3] = ctrVal; +} + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) +#define AesGcmPrecompute_avx OWNAPI(AesGcmPrecompute_avx) + IPP_OWN_DECL (void, AesGcmPrecompute_avx, (Ipp8u* pPrecomputeData, const Ipp8u* pHKey)) +#define AesGcmMulGcm_avx OWNAPI(AesGcmMulGcm_avx) + IPP_OWN_DECL (void, AesGcmMulGcm_avx, (Ipp8u* pGhash, const Ipp8u* pHkey, const void* pParam)) +#define AesGcmAuth_avx OWNAPI(AesGcmAuth_avx) + IPP_OWN_DECL (void, AesGcmAuth_avx, (Ipp8u* pGhash, const Ipp8u* pSrc, int len, const Ipp8u* pHkey, const void* pParam)) +#define wrpAesGcmEnc_avx OWNAPI(wrpAesGcmEnc_avx) + IPP_OWN_DECL (void, wrpAesGcmEnc_avx, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) +#define wrpAesGcmDec_avx OWNAPI(wrpAesGcmDec_avx) + IPP_OWN_DECL (void, wrpAesGcmDec_avx, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) +#define AesGcmEnc_avx OWNAPI(AesGcmEnc_avx) + IPP_OWN_DECL (void, AesGcmEnc_avx, (Ipp8u* pDst, const Ipp8u* pSrc, int len, RijnCipher cipher, int nr, const Ipp8u* pKeys, Ipp8u* pGhash, Ipp8u* pCnt, Ipp8u* pECnt, const Ipp8u* pMuls)) +#define AesGcmDec_avx OWNAPI(AesGcmDec_avx) + IPP_OWN_DECL (void, AesGcmDec_avx, (Ipp8u* pDst, const Ipp8u* pSrc, int len, RijnCipher cipher, int nr, const Ipp8u* pKeys, Ipp8u* pGhash, Ipp8u* pCnt, Ipp8u* pECnt, const Ipp8u* pMuls)) +#endif + +#if(_IPP32E>=_IPP32E_K0) +#define AesGcmPrecompute_vaes OWNAPI(AesGcmPrecompute_vaes) + IPP_OWN_DECL (void, AesGcmPrecompute_vaes, (Ipp8u* const pPrecomputeData, const Ipp8u* const pHKey)) +#define AesGcmMulGcm_vaes OWNAPI(AesGcmMulGcm_vaes) + IPP_OWN_DECL (void, AesGcmMulGcm_vaes, (Ipp8u* pGhash, const Ipp8u* pHkey, const void* pParam)) +#define AesGcmAuth_vaes OWNAPI(AesGcmAuth_vaes) + IPP_OWN_DECL (void, AesGcmAuth_vaes, (Ipp8u* pGhash, const Ipp8u* pSrc, int len, const Ipp8u* pHkey, const void* pParam)) +#define AesGcmEnc_vaes OWNAPI(AesGcmEnc_vaes) + IPP_OWN_DECL (void, AesGcmEnc_vaes, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) +#define AesGcmDec_vaes OWNAPI(AesGcmDec_vaes) + IPP_OWN_DECL (void, AesGcmDec_vaes, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) +#endif /* _IPP32E>=_IPP32E_K0 */ + +#define AesGcmPrecompute_table2K OWNAPI(AesGcmPrecompute_table2K) + IPP_OWN_DECL (void, AesGcmPrecompute_table2K, (Ipp8u* pPrecomputeData, const Ipp8u* pHKey)) + +/* #define AesGcmMulGcm_table2K OWNAPI(AesGcmMulGcm_table2K) */ +/* IPP_OWN_DECL (void, AesGcmMulGcm_table2K, (Ipp8u* pGhash, const Ipp8u* pHkey, const void* pParam)) */ +#define AesGcmMulGcm_table2K_ct OWNAPI(AesGcmMulGcm_table2K_ct) + IPP_OWN_DECL (void, AesGcmMulGcm_table2K_ct, (Ipp8u* pGhash, const Ipp8u* pHkey, const void* pParam)) + +/* #define AesGcmAuth_table2K OWNAPI(AesGcmAuth_table2K) */ +/* IPP_OWN_DECL (void, AesGcmAuth_table2K, (Ipp8u* pGhash, const Ipp8u* pSrc, int len, const Ipp8u* pHkey, const void* pParam)) */ +#define AesGcmAuth_table2K_ct OWNAPI(AesGcmAuth_table2K_ct) + IPP_OWN_DECL (void, AesGcmAuth_table2K_ct, (Ipp8u* pGhash, const Ipp8u* pSrc, int len, const Ipp8u* pHkey, const void* pParam)) + +#define wrpAesGcmEnc_table2K OWNAPI(wrpAesGcmEnc_table2K) + IPP_OWN_DECL (void, wrpAesGcmEnc_table2K, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) +#define wrpAesGcmDec_table2K OWNAPI(wrpAesGcmDec_table2K) + IPP_OWN_DECL (void, wrpAesGcmDec_table2K, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) + +#if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) +#define AesGcmEnc_vaes_avx2 OWNAPI(AesGcmEnc_vaes_avx2) + IPP_OWN_DECL (void, AesGcmEnc_vaes_avx2, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) +#define AesGcmDec_vaes_avx2 OWNAPI(AesGcmDec_vaes_avx2) + IPP_OWN_DECL (void, AesGcmDec_vaes_avx2, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pCtx)) +#endif /* #if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) */ + +extern const Ipp16u AesGcmConst_table[256]; /* precomputed reduction table */ + +static int cpSizeofCtx_AESGCM(void) +{ + int precomp_size; + + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(IsFeatureEnabled(ippCPUID_AES|ippCPUID_CLMUL) || IsFeatureEnabled(ippCPUID_AVX2VAES|ippCPUID_AVX2VCLMUL)) + precomp_size = PRECOMP_DATA_SIZE_AES_NI_AESGCM; + else + #endif + precomp_size = PRECOMP_DATA_SIZE_FAST2K; + + /* decrease precomp_size as soon as BLOCK_SIZE bytes already reserved in context */ + precomp_size -= BLOCK_SIZE; + + return (Ipp32s)sizeof(IppsAES_GCMState) + +precomp_size + +AESGCM_ALIGNMENT-1; +} + +#endif // (_IPP32E < _IPP32E_K0) + +#endif /* _CP_AESAUTH_GCM_H*/ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesauthgcm_avx512.h b/plugin/ippcp/library/src/sources/ippcp/pcpaesauthgcm_avx512.h new file mode 100644 index 000000000..e81a8a7a7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesauthgcm_avx512.h @@ -0,0 +1,153 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES GCM otimized for AVX512 and AVX512-VAES features +// Internal Definitions +// +// +*/ + +#ifndef _CP_AESAUTH_GCM_AVX512_H +#define _CP_AESAUTH_GCM_AVX512_H + +#include "owndefs.h" +#include "owncp.h" + +#if(_IPP32E>=_IPP32E_K0) + +#include "pcprij.h" + +#include "aes_gcm_vaes.h" +#include "aes_gcm_avx512.h" +#include "aes_gcm_avx512_structures.h" + +// Prototypes for internal functions from IPsec + +// IV processing +IPP_OWN_FUNPTR (void, IvUpdate_, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *iv, const Ipp64u iv_len)) +IPP_OWN_FUNPTR (void, IvFinalize_, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *iv, const Ipp64u iv_len, const Ipp64u iv_general_len)) + +// AAD processing +IPP_OWN_FUNPTR (void, AadUpdate_, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, const Ipp8u *aad, const Ipp64u aad_len)) + +// GCM multiplication +IPP_OWN_FUNPTR (void, MulGcm_, (const struct gcm_key_data *key_data, Ipp8u *ghash)) + +// Encryption-authentication +IPP_OWN_FUNPTR (void, EncryptUpdate_, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) + +// Decryption-verification +IPP_OWN_FUNPTR (void, DecryptUpdate_, (const struct gcm_key_data *key_data, struct gcm_context_data *context_data, Ipp8u *out, const Ipp8u *in, Ipp64u len)) + +// Get tag +IPP_OWN_FUNPTR (void, GetTag_, (const struct gcm_key_data *key_data, const struct gcm_context_data *context_data, Ipp8u *auth_tag, Ipp64u auth_tag_len)) + +typedef enum { + GcmInit, + GcmIVprocessing, + GcmAADprocessing, + GcmTXTprocessing +} GcmState; + +#define BLOCK_SIZE (MBS_RIJ128) + +// Structure modified to work with functions from IPsec + +struct _cpAES_GCM { + + Ipp32u idCtx; /* AES-GCM id */ + GcmState state; /* GCM state: Init, IV|AAD|TXT processing */ + Ipp64u ivLen; /* IV length (bytes) */ + Ipp64u aadLen; /* header length (bytes) */ + Ipp64u txtLen; /* text length (bytes) */ + + int bufLen; /* stuff buffer length */ + __ALIGN16 /* aligned buffers */ + Ipp8u counter[BLOCK_SIZE]; /* counter */ + Ipp8u ecounter0[BLOCK_SIZE]; /* encrypted initial counter */ + Ipp8u ecounter[BLOCK_SIZE]; /* encrypted counter */ + Ipp8u ghash[BLOCK_SIZE]; /* ghash accumulator */ + + __ALIGN16 + struct gcm_key_data key_data; + __ALIGN16 + struct gcm_context_data context_data; + Ipp64u keyLen; /* key length (bytes) */ + + IvUpdate_ ivUpdateFunc; // IV processing + IvFinalize_ ivFinalizeFunc; + AadUpdate_ aadUpdateFunc; // AAD processing + MulGcm_ gcmMulFunc; // GCM multiplication + EncryptUpdate_ encryptUpdateFunc; // Encryption-authentication + DecryptUpdate_ decryptUpdateFunc; // Decryption-verification + GetTag_ getTagFunc; // Get tag + +#if (_AES_PROB_NOISE == _FEATURE_ON_) + __ALIGN16 + cpAESNoiseParams noiseParams; +#endif +}; + +// Alignment +#define AESGCM_ALIGNMENT (16) + +// Useful macros +#define AESGCM_SET_ID(context) ((context)->idCtx = (Ipp32u)idCtxAESGCM ^ (Ipp32u)IPP_UINT_PTR(context)) +#define AESGCM_STATE(context) ((context)->state) + +#define AESGCM_IV_LEN(context) ((context)->ivLen) + +#define AESGCM_COUNTER(context) ((context)->counter) +#define AESGCM_ECOUNTER0(context) ((context)->ecounter0) +#define AESGCM_ECOUNTER(context) ((context)->ecounter) + +#define AES_GCM_KEY_DATA(context) ((context)->key_data) +#define AES_GCM_CONTEXT_DATA(context) ((context)->context_data) +#define AES_GCM_KEY_LEN(context) ((context)->keyLen) + +#define AES_GCM_IV_UPDATE(context) ((context)->ivUpdateFunc) +#define AES_GCM_IV_FINALIZE(context) ((context)->ivFinalizeFunc) +#define AES_GCM_AAD_UPDATE(context) ((context)->aadUpdateFunc) +#define AES_GCM_GMUL(context) ((context)->gcmMulFunc) +#define AES_GCM_ENCRYPT_UPDATE(context) ((context)->encryptUpdateFunc) +#define AES_GCM_DECRYPT_UPDATE(context) ((context)->decryptUpdateFunc) +#define AES_GCM_GET_TAG(context) ((context)->getTagFunc) + +// Fields retargeted to IPsec context +#define AESGCM_GHASH(context) (&(AES_GCM_CONTEXT_DATA(context).aad_hash[0])) +#define AESGCM_TXT_LEN(context) (AES_GCM_CONTEXT_DATA(context).in_length) +#define AESGCM_AAD_LEN(context) (AES_GCM_CONTEXT_DATA(context).aad_length) +#define AESGCM_BUFLEN(context) (AES_GCM_CONTEXT_DATA(context).partial_block_length) + +#if (_AES_PROB_NOISE == _FEATURE_ON_) +#define AESGCM_NOISE_PARAMS(ctx) ((ctx)->noiseParams) +#endif + +#define AESGCM_VALID_ID(context) ((((context)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((context))) == (Ipp32u)idCtxAESGCM) + +static int cpSizeofCtx_AESGCM(void) +{ + return (Ipp32s)sizeof(IppsAES_GCMState) + AESGCM_ALIGNMENT-1; +} + +#endif // (_IPP32E>=_IPP32E_K0) + +#endif // _CP_AESAUTH_GCM_AVX512_H diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaescmac_setupnoise.c b/plugin/ippcp/library/src/sources/ippcp/pcpaescmac_setupnoise.c new file mode 100644 index 000000000..7981e5311 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaescmac_setupnoise.c @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-CMAC noise setup function +// +// Contents: +// ippsAES_CMACSetupNoise +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpcmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsAES_CMACSetupNoise +// +// Purpose: AES-CMAC Setup Noise +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsContextMatchErr AES context is invalid +// ippStsLengthErr noiseLevel > 4 +// ippStsNotSupportedModeErr Mistletoe3 mitigation isn't applicable for current CPU +// (no support of Intel® Advanced Encryption Standard New Instructions (Intel® AES-NI) or +// vector extensions of Intel® AES-NI) +// ippStsNoErr no errors +// +// Parameters: +// noiseLevel the value of this parameter is directly +// proportional to the amount of noise injected +// Increasing noise level by 1 means the delay +// (performance impact) is doubled +// pState pointer to the AES context +// +*F*/ +IPPFUN(IppStatus, ippsAES_CMACSetupNoise,(Ipp32u noiseLevel, IppsAES_CMACState* pState)) +{ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* test context */ + IPP_BAD_PTR1_RET(pState); + /* test ID */ + IPP_BADARG_RET(!VALID_AESCMAC_ID(pState), ippStsContextMatchErr); + + /* test noise level range */ + IPP_BADARG_RET(noiseLevel > 4, ippStsLengthErr); + + cpAESNoiseParams *params = (cpAESNoiseParams *)&AESCMAC_NOISE_PARAMS(pState); + + /* set up the parameters with initial values */ + AES_NOISE_RAND(params) = 0; + AES_NOISE_LEVEL(params) = noiseLevel; + + return ippStsNoErr; +#else + /* To remove MSVC warning C4100: 'XXX': unreferenced formal parameter*/ + IPP_UNREFERENCED_PARAMETER(noiseLevel); + IPP_UNREFERENCED_PARAMETER(pState); + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesdecryptofb.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesdecryptofb.c new file mode 100644 index 000000000..962985c33 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesdecryptofb.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES decryption (OFB mode) +// +// Contents: +// ippsAESDecryptOFB() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_ofb.h" + +/*F* +// Name: ippsAESDecryptOFB +// +// Purpose: Decrypts byte data stream according to Rijndael in OFB mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsOFBSizeErr (1>ofbBlkSize || ofbBlkSize>MBS_RIJ128) +// ippStsUnderRunErr (len%ofbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len output buffer length (in bytes) +// ofbBlkSize OFB block size (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +*F*/ +IPPFUN(IppStatus, ippsAESDecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsAESSpec* pCtx, + Ipp8u* pIV)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test source, target buffers and initialization pointers */ + IPP_BAD_PTR3_RET(pSrc, pIV, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test OFB value */ + IPP_BADARG_RET(((1>ofbBlkSize) || (MBS_RIJ128=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + if(ofbBlkSize==MBS_RIJ128) + EncryptOFB128_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), len, pIV); + else + EncryptOFB_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), len, ofbBlkSize, pIV); + return ippStsNoErr; + } + else +#endif + { + cpProcessAES_ofb8(pSrc, pDst, len, ofbBlkSize, pCtx, pIV); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesencryptofb.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesencryptofb.c new file mode 100644 index 000000000..78362d22c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesencryptofb.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES encryption (OFB mode) +// +// Contents: +// ippsAESEncryptOFB() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" +#include "pcpaes_ofb.h" + +/*F* +// Name: ippsAESEncryptOFB +// +// Purpose: Encrypts byte data stream according to Rijndael in OFB mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_AES_ID() +// ippStsLengthErr len <1 +// ippStsOFBSizeErr (1>ofbBlkSize || ofbBlkSize>MBS_RIJ128) +// ippStsUnderRunErr (len%ofbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input buffer length (in bytes) +// ofbBlkSize OFB block size (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +*F*/ +IPPFUN(IppStatus, ippsAESEncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsAESSpec* pCtx, + Ipp8u* pIV)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test source, target buffers and initialization pointers */ + IPP_BAD_PTR3_RET(pSrc, pIV, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test OFB value */ + IPP_BADARG_RET(((1>ofbBlkSize) || (MBS_RIJ128=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(AES_NI_ENABLED==RIJ_AESNI(pCtx)) { + if(ofbBlkSize==MBS_RIJ128) + EncryptOFB128_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), len, pIV); + else + EncryptOFB_RIJ128_AES_NI(pSrc, pDst, RIJ_NR(pCtx), RIJ_EKEYS(pCtx), len, ofbBlkSize, pIV); + return ippStsNoErr; + } + else +#endif + { + cpProcessAES_ofb8(pSrc, pDst, len, ofbBlkSize, pCtx, pIV); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesgcm_setupnoise.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcm_setupnoise.c new file mode 100644 index 000000000..fbf3c63b8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcm_setupnoise.c @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-GCM noise setup function +// +// Contents: +// ippsAES_GCMSetupNoise +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#include "pcpaesauthgcm.h" +#include "pcpaesauthgcm_avx512.h" + +/*F* +// Name: ippsAES_GCMSetupNoise +// +// Purpose: AES-GCM Setup Noise +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsContextMatchErr AES context is invalid +// ippStsLengthErr noiseLevel > 4 +// ippStsNotSupportedModeErr Mistletoe3 mitigation isn't applicable for current CPU +// (no support of Intel® Advanced Encryption Standard New Instructions (Intel® AES-NI) or +// vector extensions of Intel® AES-NI) +// ippStsNoErr no errors +// +// Parameters: +// noiseLevel the value of this parameter is directly +// proportional to the amount of noise injected +// Increasing noise level by 1 means the delay +// (performance impact) is doubled +// pState pointer to the AES context +// +*F*/ +IPPFUN(IppStatus, ippsAES_GCMSetupNoise,(Ipp32u noiseLevel, IppsAES_GCMState* pState)) +{ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* test context */ + IPP_BAD_PTR1_RET(pState); + + /* use aligned context */ + pState = (IppsAES_GCMState*)(IPP_ALIGNED_PTR(pState, AESGCM_ALIGNMENT)); + + /* test state ID */ + IPP_BADARG_RET(!AESGCM_VALID_ID(pState), ippStsContextMatchErr); + + /* test noise level range */ + IPP_BADARG_RET(noiseLevel > 4, ippStsLengthErr); + + cpAESNoiseParams *params = (cpAESNoiseParams *)&AESGCM_NOISE_PARAMS(pState); + + /* set up the parameters with initial values */ + AES_NOISE_RAND(params) = 0; + AES_NOISE_LEVEL(params) = noiseLevel; + + return ippStsNoErr; +#else + /* To remove MSVC warning C4100: 'XXX': unreferenced formal parameter*/ + IPP_UNREFERENCED_PARAMETER(noiseLevel); + IPP_UNREFERENCED_PARAMETER(pState); + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtableca.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtableca.c new file mode 100644 index 000000000..7ab98d05b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtableca.c @@ -0,0 +1,54 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt/Decrypt byte data stream according to Rijndael128 (GCM mode) +// +// "fast" stuff +// +// Contents: +// +// +*/ + + +#include "owndefs.h" +#include "owncp.h" + +#if defined( _IPP_DATA ) +__ALIGN64 const Ipp16u AesGcmConst_table[256] = { +0x0000, 0xc201, 0x8403, 0x4602, 0x0807, 0xca06, 0x8c04, 0x4e05, 0x100e, 0xd20f, 0x940d, 0x560c, 0x1809, 0xda08, 0x9c0a, 0x5e0b, +0x201c, 0xe21d, 0xa41f, 0x661e, 0x281b, 0xea1a, 0xac18, 0x6e19, 0x3012, 0xf213, 0xb411, 0x7610, 0x3815, 0xfa14, 0xbc16, 0x7e17, +0x4038, 0x8239, 0xc43b, 0x063a, 0x483f, 0x8a3e, 0xcc3c, 0x0e3d, 0x5036, 0x9237, 0xd435, 0x1634, 0x5831, 0x9a30, 0xdc32, 0x1e33, +0x6024, 0xa225, 0xe427, 0x2626, 0x6823, 0xaa22, 0xec20, 0x2e21, 0x702a, 0xb22b, 0xf429, 0x3628, 0x782d, 0xba2c, 0xfc2e, 0x3e2f, +0x8070, 0x4271, 0x0473, 0xc672, 0x8877, 0x4a76, 0x0c74, 0xce75, 0x907e, 0x527f, 0x147d, 0xd67c, 0x9879, 0x5a78, 0x1c7a, 0xde7b, +0xa06c, 0x626d, 0x246f, 0xe66e, 0xa86b, 0x6a6a, 0x2c68, 0xee69, 0xb062, 0x7263, 0x3461, 0xf660, 0xb865, 0x7a64, 0x3c66, 0xfe67, +0xc048, 0x0249, 0x444b, 0x864a, 0xc84f, 0x0a4e, 0x4c4c, 0x8e4d, 0xd046, 0x1247, 0x5445, 0x9644, 0xd841, 0x1a40, 0x5c42, 0x9e43, +0xe054, 0x2255, 0x6457, 0xa656, 0xe853, 0x2a52, 0x6c50, 0xae51, 0xf05a, 0x325b, 0x7459, 0xb658, 0xf85d, 0x3a5c, 0x7c5e, 0xbe5f, +0x00e1, 0xc2e0, 0x84e2, 0x46e3, 0x08e6, 0xcae7, 0x8ce5, 0x4ee4, 0x10ef, 0xd2ee, 0x94ec, 0x56ed, 0x18e8, 0xdae9, 0x9ceb, 0x5eea, +0x20fd, 0xe2fc, 0xa4fe, 0x66ff, 0x28fa, 0xeafb, 0xacf9, 0x6ef8, 0x30f3, 0xf2f2, 0xb4f0, 0x76f1, 0x38f4, 0xfaf5, 0xbcf7, 0x7ef6, +0x40d9, 0x82d8, 0xc4da, 0x06db, 0x48de, 0x8adf, 0xccdd, 0x0edc, 0x50d7, 0x92d6, 0xd4d4, 0x16d5, 0x58d0, 0x9ad1, 0xdcd3, 0x1ed2, +0x60c5, 0xa2c4, 0xe4c6, 0x26c7, 0x68c2, 0xaac3, 0xecc1, 0x2ec0, 0x70cb, 0xb2ca, 0xf4c8, 0x36c9, 0x78cc, 0xbacd, 0xfccf, 0x3ece, +0x8091, 0x4290, 0x0492, 0xc693, 0x8896, 0x4a97, 0x0c95, 0xce94, 0x909f, 0x529e, 0x149c, 0xd69d, 0x9898, 0x5a99, 0x1c9b, 0xde9a, +0xa08d, 0x628c, 0x248e, 0xe68f, 0xa88a, 0x6a8b, 0x2c89, 0xee88, 0xb083, 0x7282, 0x3480, 0xf681, 0xb884, 0x7a85, 0x3c87, 0xfe86, +0xc0a9, 0x02a8, 0x44aa, 0x86ab, 0xc8ae, 0x0aaf, 0x4cad, 0x8eac, 0xd0a7, 0x12a6, 0x54a4, 0x96a5, 0xd8a0, 0x1aa1, 0x5ca3, 0x9ea2, +0xe0b5, 0x22b4, 0x64b6, 0xa6b7, 0xe8b2, 0x2ab3, 0x6cb1, 0xaeb0, 0xf0bb, 0x32ba, 0x74b8, 0xb6b9, 0xf8bc, 0x3abd, 0x7cbf, 0xbebe +}; +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2k_mulpx.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2k_mulpx.c new file mode 100644 index 000000000..e01d60439 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2k_mulpx.c @@ -0,0 +1,350 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt/Decrypt byte data stream according to Rijndael128 (GCM mode) +// +// "fast" stuff +// +// Contents: +// AesGcmMulGcm_table2K() +// +*/ + + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpaesauthgcm.h" +#include "pcptool.h" +#include "pcpmask_ct.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if(_IPP32E<_IPP32E_K0) + +typedef struct{ + Ipp8u b[16]; +} AesGcmPrecompute_GF; + + +#if !((_IPP==_IPP_V8) || (_IPP==_IPP_P8) || \ + (_IPP==_IPP_S8) || (_IPP>=_IPP_G9) || \ + (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) +/* +// AesGcmMulGcm_def|safe(Ipp8u* pGhash, const Ipp8u* pHKey) +// +// Ghash = Ghash * HKey mod G() +*/ +__INLINE Ipp16u getAesGcmConst_table_ct(int idx) +{ + #define TBL_SLOTS_REP_READ (Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(AesGcmConst_table[0])) + const BNU_CHUNK_T* TblEntry = (BNU_CHUNK_T*)AesGcmConst_table; + + BNU_CHUNK_T idx_sel = (BNU_CHUNK_T)(idx / TBL_SLOTS_REP_READ); /* selection index */ + BNU_CHUNK_T i; + BNU_CHUNK_T selection = 0; + for (i = 0; i>= (idx & (TBL_SLOTS_REP_READ-1)) * sizeof(Ipp16u)*8; + return (Ipp16u)(selection & 0xFFffFF); + #undef TBL_SLOTS_REP_READ +} + +#if 0 +void AesGcmMulGcm_table2K(Ipp8u* pGhash, const Ipp8u* pPrecomputeData, const void* pParam) +{ + __ALIGN16 Ipp8u t5[BLOCK_SIZE]; + __ALIGN16 Ipp8u t4[BLOCK_SIZE]; + __ALIGN16 Ipp8u t3[BLOCK_SIZE]; + __ALIGN16 Ipp8u t2[BLOCK_SIZE]; + + int nw; + Ipp32u a; + + IPP_UNREFERENCED_PARAMETER(pParam); + + #if 0 + XorBlock16(t5, t5, t5); + XorBlock16(t4, t4, t4); + XorBlock16(t3, t3, t3); + XorBlock16(t2, t2, t2); + #endif + PadBlock(0, t5, sizeof(t5)); + PadBlock(0, t4, sizeof(t4)); + PadBlock(0, t3, sizeof(t3)); + PadBlock(0, t2, sizeof(t2)); + + for(nw=0; nw<4; nw++) { + Ipp32u hashdw = ((Ipp32u*)pGhash)[nw]; + + a = hashdw & 0xf0f0f0f0; + XorBlock16(t5, pPrecomputeData+1024+EBYTE(a,1)+256*nw, t5); + XorBlock16(t4, pPrecomputeData+1024+EBYTE(a,0)+256*nw, t4); + XorBlock16(t3, pPrecomputeData+1024+EBYTE(a,3)+256*nw, t3); + XorBlock16(t2, pPrecomputeData+1024+EBYTE(a,2)+256*nw, t2); + + a = (hashdw<<4) & 0xf0f0f0f0; + XorBlock16(t5, pPrecomputeData+EBYTE(a,1)+256*nw, t5); + XorBlock16(t4, pPrecomputeData+EBYTE(a,0)+256*nw, t4); + XorBlock16(t3, pPrecomputeData+EBYTE(a,3)+256*nw, t3); + XorBlock16(t2, pPrecomputeData+EBYTE(a,2)+256*nw, t2); + } + + XorBlock(t2+1, t3, t2+1, BLOCK_SIZE-1); + XorBlock(t5+1, t2, t5+1, BLOCK_SIZE-1); + XorBlock(t4+1, t5, t4+1, BLOCK_SIZE-1); + + nw = t3[BLOCK_SIZE-1]; + //a = (Ipp32u)AesGcmConst_table[nw]; + a = (Ipp32u)getAesGcmConst_table_ct(nw); + a <<= 8; + nw = t2[BLOCK_SIZE-1]; + //a ^= (Ipp32u)AesGcmConst_table[nw]; + a ^= (Ipp32u)getAesGcmConst_table_ct(nw); + a <<= 8; + nw = t5[BLOCK_SIZE-1]; + //a ^= (Ipp32u)AesGcmConst_table[nw]; + a ^= (Ipp32u)getAesGcmConst_table_ct(nw); + + XorBlock(t4, &a, t4, sizeof(Ipp32u)); + CopyBlock16(t4, pGhash); +} +#endif + +/* +// CTE version of AesGcmMulGcm_table2K() +*/ +#if (_IPP_ARCH ==_IPP_ARCH_EM64T) +__INLINE void MaskedXorBlock16(const Ipp8u* pSrc1, const Ipp8u* pSrc2, Ipp8u* pDst, Ipp64u src2mask) +{ + ((Ipp64u*)pDst)[0] = ((Ipp64u*)pSrc1)[0] ^ (((Ipp64u*)pSrc2)[0] & src2mask); + ((Ipp64u*)pDst)[1] = ((Ipp64u*)pSrc1)[1] ^ (((Ipp64u*)pSrc2)[1] & src2mask); +} +#else /* IPP_ARCH == IPP_ARCH_IA32 */ +__INLINE void MaskedXorBlock16(const Ipp8u* pSrc1, const Ipp8u* pSrc2, Ipp8u* pDst, Ipp32u src2mask) +{ + ((Ipp32u*)pDst)[0] = ((Ipp32u*)pSrc1)[0] ^ (((Ipp32u*)pSrc2)[0] & src2mask); + ((Ipp32u*)pDst)[1] = ((Ipp32u*)pSrc1)[1] ^ (((Ipp32u*)pSrc2)[1] & src2mask); + ((Ipp32u*)pDst)[2] = ((Ipp32u*)pSrc1)[2] ^ (((Ipp32u*)pSrc2)[2] & src2mask); + ((Ipp32u*)pDst)[3] = ((Ipp32u*)pSrc1)[3] ^ (((Ipp32u*)pSrc2)[3] & src2mask); +} +#endif + +IPP_OWN_DEFN (void, AesGcmMulGcm_table2K_ct, (Ipp8u* pGhash, const Ipp8u* pPrecomputeData, const void* pParam)) +{ + __ALIGN16 Ipp8u t5[BLOCK_SIZE]; + __ALIGN16 Ipp8u t4[BLOCK_SIZE]; + __ALIGN16 Ipp8u t3[BLOCK_SIZE]; + __ALIGN16 Ipp8u t2[BLOCK_SIZE]; + + int nw; + + IPP_UNREFERENCED_PARAMETER(pParam); + +#if 0 + XorBlock16(t5, t5, t5); + XorBlock16(t4, t4, t4); + XorBlock16(t3, t3, t3); + XorBlock16(t2, t2, t2); +#endif + PadBlock(0, t5, sizeof(t5)); + PadBlock(0, t4, sizeof(t4)); + PadBlock(0, t3, sizeof(t3)); + PadBlock(0, t2, sizeof(t2)); + + for(nw=0; nw<4; nw++) { + Ipp32u hashdw = ((Ipp32u*)pGhash)[nw]; + Ipp32u a = hashdw & 0xf0f0f0f0; + + Ipp32u a0 = EBYTE(a,0); + Ipp32u a1 = EBYTE(a,1); + Ipp32u a2 = EBYTE(a,2); + Ipp32u a3 = EBYTE(a,3); + + int idx; + for(idx=0; idx<256; idx+=16) { + BNU_CHUNK_T mask0 = cpIsEqu_ct(a0, (BNU_CHUNK_T)idx); + BNU_CHUNK_T mask1 = cpIsEqu_ct(a1, (BNU_CHUNK_T)idx); + BNU_CHUNK_T mask2 = cpIsEqu_ct(a2, (BNU_CHUNK_T)idx); + BNU_CHUNK_T mask3 = cpIsEqu_ct(a3, (BNU_CHUNK_T)idx); + MaskedXorBlock16(t5, pPrecomputeData+1024 +256*nw +idx, t5, mask1); + MaskedXorBlock16(t4, pPrecomputeData+1024 +256*nw +idx, t4, mask0); + MaskedXorBlock16(t3, pPrecomputeData+1024 +256*nw +idx, t3, mask3); + MaskedXorBlock16(t2, pPrecomputeData+1024 +256*nw +idx, t2, mask2); + } + + a = (hashdw << 4) & 0xf0f0f0f0; + a0 = EBYTE(a, 0); + a1 = EBYTE(a, 1); + a2 = EBYTE(a, 2); + a3 = EBYTE(a, 3); + for (idx = 0; idx < 256; idx += 16) { + BNU_CHUNK_T mask0 = cpIsEqu_ct(a0, (BNU_CHUNK_T)idx); + BNU_CHUNK_T mask1 = cpIsEqu_ct(a1, (BNU_CHUNK_T)idx); + BNU_CHUNK_T mask2 = cpIsEqu_ct(a2, (BNU_CHUNK_T)idx); + BNU_CHUNK_T mask3 = cpIsEqu_ct(a3, (BNU_CHUNK_T)idx); + MaskedXorBlock16(t5, pPrecomputeData +256*nw +idx, t5, mask1); + MaskedXorBlock16(t4, pPrecomputeData +256*nw +idx, t4, mask0); + MaskedXorBlock16(t3, pPrecomputeData +256*nw +idx, t3, mask3); + MaskedXorBlock16(t2, pPrecomputeData +256*nw +idx, t2, mask2); + } + } + + XorBlock(t2 + 1, t3, t2 + 1, BLOCK_SIZE - 1); + XorBlock(t5 + 1, t2, t5 + 1, BLOCK_SIZE - 1); + XorBlock(t4 + 1, t5, t4 + 1, BLOCK_SIZE - 1); + + nw = t3[BLOCK_SIZE - 1]; + { + //a = (Ipp32u)AesGcmConst_table[nw]; + Ipp32u a = (Ipp32u)getAesGcmConst_table_ct(nw); + a <<= 8; + nw = t2[BLOCK_SIZE - 1]; + //a ^= (Ipp32u)AesGcmConst_table[nw]; + a ^= (Ipp32u)getAesGcmConst_table_ct(nw); + a <<= 8; + nw = t5[BLOCK_SIZE - 1]; + //a ^= (Ipp32u)AesGcmConst_table[nw]; + a ^= (Ipp32u)getAesGcmConst_table_ct(nw); + + XorBlock(t4, &a, t4, sizeof(Ipp32u)); + CopyBlock16(t4, pGhash); + } +} + +#endif + +#if ((_IPP>=_IPP_V8) || (_IPP32E>=_IPP32E_N8)) + +__INLINE Ipp16u getAesGcmConst_table_ct(int idx) +{ + /* init current indexes */ + __ALIGN16 Ipp16u idx_start[] = { 0,1,2,3,4,5,6,7 }; + __m128i idx_curr = _mm_load_si128((__m128i*)idx_start); + /* indexes step */ + __m128i idx_step = _mm_set1_epi16(sizeof(__m128i) / sizeof(AesGcmConst_table[0])); + /* broadcast idx */ + __m128i idx_bcst = _mm_set1_epi16((Ipp16s)idx); + + /* init accumulator */ + __m128i acc = _mm_setzero_si128(); + + int i; + for (i = 0; i < (int)sizeof(AesGcmConst_table); i += sizeof(__m128i)) { + /* read 16 entries of AesGcmConst_table[] */ + __m128i tbl = _mm_load_si128((__m128i*)((Ipp8u*)AesGcmConst_table + i)); + /* set mask if idx==idx_curr[] */ + __m128i mask = _mm_cmpeq_epi16(idx_bcst, idx_curr); + mask = _mm_and_si128(mask, tbl); + /* accumulates masked */ + acc = _mm_or_si128(acc, mask); + /* ad advance idx_curr[] indexes */ + idx_curr = _mm_add_epi16(idx_curr, idx_step); + } + + /* shift accumulator to get AesGcmConst_table[idx] in low word */ + acc = _mm_or_si128(acc, _mm_srli_si128(acc, sizeof(__m128i) / 2)); /* pack result into dword */ + acc = _mm_or_si128(acc, _mm_srli_si128(acc, sizeof(__m128i) / 4)); + acc = _mm_or_si128(acc, _mm_srli_si128(acc, sizeof(__m128i) / 8)); + i = _mm_cvtsi128_si32(acc); + + return (Ipp16u)i; +} + +IPP_OWN_DEFN (void, AesGcmMulGcm_table2K_ct, (Ipp8u* pHash, const Ipp8u* pPrecomputedData, const void* pParam)) +{ + __m128i t5 = _mm_setzero_si128(); + __m128i t4 = _mm_setzero_si128(); + __m128i t3 = _mm_setzero_si128(); + __m128i t2 = _mm_setzero_si128(); + + IPP_UNREFERENCED_PARAMETER(pParam); + + { + int nw; + for (nw = 0; nw < 4; nw++) { + Ipp32u hashdw = ((Ipp32u*)pHash)[nw]; + + Ipp32u a = hashdw & 0xf0f0f0f0; + Ipp32u a0 = EBYTE(a, 0); + Ipp32u a1 = EBYTE(a, 1); + Ipp32u a2 = EBYTE(a, 2); + Ipp32u a3 = EBYTE(a, 3); + int idx; + for (idx = 0; idx < 256; idx += 16) { + __m128i mask0 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a0, (BNU_CHUNK_T)idx)); + __m128i mask1 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a1, (BNU_CHUNK_T)idx)); + __m128i mask2 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a2, (BNU_CHUNK_T)idx)); + __m128i mask3 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a3, (BNU_CHUNK_T)idx)); + t5 = _mm_xor_si128(t5, _mm_and_si128(mask1, _mm_load_si128((__m128i*)(pPrecomputedData + 1024 + 256 * nw + idx)))); + t4 = _mm_xor_si128(t4, _mm_and_si128(mask0, _mm_load_si128((__m128i*)(pPrecomputedData + 1024 + 256 * nw + idx)))); + t3 = _mm_xor_si128(t3, _mm_and_si128(mask3, _mm_load_si128((__m128i*)(pPrecomputedData + 1024 + 256 * nw + idx)))); + t2 = _mm_xor_si128(t2, _mm_and_si128(mask2, _mm_load_si128((__m128i*)(pPrecomputedData + 1024 + 256 * nw + idx)))); + } + + a = (hashdw << 4) & 0xf0f0f0f0; + a0 = EBYTE(a, 0); + a1 = EBYTE(a, 1); + a2 = EBYTE(a, 2); + a3 = EBYTE(a, 3); + for (idx = 0; idx < 256; idx += 16) { + __m128i mask0 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a0, (BNU_CHUNK_T)idx)); + __m128i mask1 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a1, (BNU_CHUNK_T)idx)); + __m128i mask2 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a2, (BNU_CHUNK_T)idx)); + __m128i mask3 = _mm_set1_epi32((Ipp32s)cpIsEqu_ct(a3, (BNU_CHUNK_T)idx)); + t5 = _mm_xor_si128(t5, _mm_and_si128(mask1, _mm_load_si128((__m128i*)(pPrecomputedData + 256 * nw + idx)))); + t4 = _mm_xor_si128(t4, _mm_and_si128(mask0, _mm_load_si128((__m128i*)(pPrecomputedData + 256 * nw + idx)))); + t3 = _mm_xor_si128(t3, _mm_and_si128(mask3, _mm_load_si128((__m128i*)(pPrecomputedData + 256 * nw + idx)))); + t2 = _mm_xor_si128(t2, _mm_and_si128(mask2, _mm_load_si128((__m128i*)(pPrecomputedData + 256 * nw + idx)))); + } + } + + { + Ipp32u a; + t2 = _mm_xor_si128(t2, _mm_slli_si128(t3, 1)); + t5 = _mm_xor_si128(t5, _mm_slli_si128(t2, 1)); + t4 = _mm_xor_si128(t4, _mm_slli_si128(t5, 1)); + + nw = _mm_cvtsi128_si32(_mm_srli_si128(t3, 15)); + a = (Ipp32u)getAesGcmConst_table_ct(nw); + a <<= 8; + + nw = _mm_cvtsi128_si32(_mm_srli_si128(t2, 15)); + a ^= (Ipp32u)getAesGcmConst_table_ct(nw); + a <<= 8; + + nw = _mm_cvtsi128_si32(_mm_srli_si128(t5, 15)); + a ^= (Ipp32u)getAesGcmConst_table_ct(nw); + + t2 = _mm_cvtsi32_si128((Ipp32s)a); + t4 = _mm_xor_si128(t4, t2); + _mm_storeu_si128((__m128i*)pHash, t4); + } + } +} +#endif + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2k_precom.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2k_precom.c new file mode 100644 index 000000000..5d81607c8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2k_precom.c @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt/Decrypt byte data stream according to Rijndael128 (GCM mode) +// +// "fast" stuff +// +// Contents: +// AesGcmPrecompute_table2K() +// +*/ + + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpaesauthgcm.h" +#include "pcptool.h" + +#if(_IPP32E<_IPP32E_K0) + +/* +// AES-GCM precomputations. +*/ +static void RightShiftBlock16(Ipp8u* pBlock) +{ + Ipp8u v0 = 0; + int i; + for(i=0; i<16; i++) { + Ipp8u v1 = pBlock[i]; + Ipp8u tmp = (Ipp8u)( (v1>>1) | (v0<<7) ); + pBlock[i] = tmp; + v0 = v1; + } +} + +IPP_OWN_DEFN (void, AesGcmPrecompute_table2K, (Ipp8u* pPrecomputeData, const Ipp8u* pHKey)) +{ + Ipp8u t[BLOCK_SIZE]; + int n; + + CopyBlock16(pHKey, t); + + for(n=0; n<128-24; n++) { + /* get msb */ + int hBit = t[15]&1; + + int k = n%32; + if(k<4) { + CopyBlock16(t, pPrecomputeData +1024 +(n/32)*256 +(Ipp32u)(1<<(7-k))); + } + else if(k<8) { + CopyBlock16(t, pPrecomputeData +(n/32)*256 +(Ipp32u)(1<<(11-k))); + } + + /* shift */ + RightShiftBlock16(t); + /* xor if msb=1 */ + if(hBit) + t[0] ^= 0xe1; + } + + for(n=0; n<4; n++) { + int m, k; + XorBlock16(pPrecomputeData +n*256, pPrecomputeData +n*256, pPrecomputeData +n*256); + XorBlock16(pPrecomputeData +1024 +n*256, pPrecomputeData +1024 +n*256, pPrecomputeData +1024 +n*256); + for(m=2; m<=8; m*=2) + for(k=1; k=_IPP_G9) || \ +// (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ +// (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) +#if 0 +IPP_OWN_DEFN (void, AesGcmAuth_table2K, (Ipp8u* pHash, const Ipp8u* pSrc, int len, const Ipp8u* pHKey, const void* pParam)) +{ + IPP_UNREFERENCED_PARAMETER(pParam); + + while(len>=BLOCK_SIZE) { + /* add src */ + XorBlock16(pSrc, pHash, pHash); + /* hash it */ + AesGcmMulGcm_table2K(pHash, pHKey, AesGcmConst_table); + + pSrc += BLOCK_SIZE; + len -= BLOCK_SIZE; + } +} +#endif + +#if(_IPP32E<_IPP32E_K0) + +IPP_OWN_DEFN (void, AesGcmAuth_table2K_ct, (Ipp8u* pHash, const Ipp8u* pSrc, int len, const Ipp8u* pHKey, const void* pParam)) +{ + IPP_UNREFERENCED_PARAMETER(pParam); + + while (len >= BLOCK_SIZE) { + /* add src */ + XorBlock16(pSrc, pHash, pHash); + /* hash it */ + AesGcmMulGcm_table2K_ct(pHash, pHKey, AesGcmConst_table); + + pSrc += BLOCK_SIZE; + len -= BLOCK_SIZE; + } +} + +#endif + +//#endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2kca_decpx.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2kca_decpx.c new file mode 100644 index 000000000..bc5b37b3d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2kca_decpx.c @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt/Decrypt byte data stream according to Rijndael128 (GCM mode) +// +// "fast" stuff +// +// Contents: +// wrpAesGcmDec_table2K() +// +*/ + + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpaesauthgcm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if(_IPP32E<_IPP32E_K0) + +/* +// authenticates and decrypts n*BLOCK_SIZE bytes +*/ +IPP_OWN_DEFN (void, wrpAesGcmDec_table2K, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pState)) +{ + //AesGcmAuth_table2K(AESGCM_GHASH(pState), pSrc, len, AESGCM_HKEY(pState), AesGcmConst_table); + AesGcmAuth_table2K_ct(AESGCM_GHASH(pState), pSrc, len, AESGCM_HKEY(pState), AesGcmConst_table); + + { + Ipp8u* pCounter = AESGCM_COUNTER(pState); + Ipp8u* pECounter = AESGCM_ECOUNTER(pState); + + IppsRijndael128Spec* pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + while(len>=BLOCK_SIZE) { + /* encrypt whole AES block */ + XorBlock16(pSrc, pECounter, pDst); + + pSrc += BLOCK_SIZE; + pDst += BLOCK_SIZE; + len -= BLOCK_SIZE; + + /* increment counter block */ + IncrementCounter32(pCounter); + /* and encrypt counter */ + //encoder((Ipp32u*)pCounter, (Ipp32u*)pECounter, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pCounter, pECounter, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(pCounter, pECounter, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + } +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2kca_encpx.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2kca_encpx.c new file mode 100644 index 000000000..83092ad5d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesgcmtbl2kca_encpx.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt/Decrypt byte data stream according to Rijndael128 (GCM mode) +// +// "fast" stuff +// +// Contents: +// wrpAesGcmEnc_table2K() +// +*/ + + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpaesauthgcm.h" +#include "pcptool.h" + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +# include "pcprijtables.h" +#endif + +#if(_IPP32E<_IPP32E_K0) + +/* +// encrypts and authenticates n*BLOCK_SIZE bytes +*/ +IPP_OWN_DEFN (void, wrpAesGcmEnc_table2K, (Ipp8u* pDst, const Ipp8u* pSrc, int len, IppsAES_GCMState* pState)) +{ + Ipp8u* pHashedData = pDst; + int hashedDataLen = len; + + Ipp8u* pCounter = AESGCM_COUNTER(pState); + Ipp8u* pECounter = AESGCM_ECOUNTER(pState); + + IppsRijndael128Spec* pAES = AESGCM_CIPHER(pState); + RijnCipher encoder = RIJ_ENCODER(pAES); + + while(len>=BLOCK_SIZE) { + /* encrypt whole AES block */ + XorBlock16(pSrc, pECounter, pDst); + + pSrc += BLOCK_SIZE; + pDst += BLOCK_SIZE; + len -= BLOCK_SIZE; + + /* increment counter block */ + IncrementCounter32(pCounter); + /* and encrypt counter */ + //encoder((Ipp32u*)pCounter, (Ipp32u*)pECounter, RIJ_NR(pAES), RIJ_EKEYS(pAES), (const Ipp32u (*)[256])RIJ_ENC_SBOX(pAES)); + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + encoder(pCounter, pECounter, RIJ_NR(pAES), RIJ_EKEYS(pAES), RijEncSbox/*NULL*/); + #else + encoder(pCounter, pECounter, RIJ_NR(pAES), RIJ_EKEYS(pAES), NULL); + #endif + } + + //AesGcmAuth_table2K(AESGCM_GHASH(pState), pHashedData, hashedDataLen, AESGCM_HKEY(pState), AesGcmConst_table); + AesGcmAuth_table2K_ct(AESGCM_GHASH(pState), pHashedData, hashedDataLen, AESGCM_HKEY(pState), AesGcmConst_table); +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesgetsize.c new file mode 100644 index 000000000..2bb59ef07 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesgetsize.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Initialization of AES +// +// Contents: +// ippsAESGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcprij128safe.h" +#include "pcptool.h" + +/*F* +// Name: ippsAESGetSize +// +// Purpose: Returns size of AES context (in bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to AES size of context(in bytes) +// +*F*/ +IPPFUN(IppStatus, ippsAESGetSize,(int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = cpSizeofCtx_AES(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesm.h b/plugin/ippcp/library/src/sources/ippcp/pcpaesm.h new file mode 100644 index 000000000..8954683f0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesm.h @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions and +// Internal AES Function Prototypes +// +// +*/ + +#if !defined(_PCP_AES_H) +#define _PCP_AES_H + +#include "pcprij.h" + +/* Intel(R) AES New Instructions (Intel(R) AES-NI) flag */ +#define AES_NI_ENABLED (ippCPUID_AES) + +/* alignment of AES context */ +#define AES_ALIGNMENT (RIJ_ALIGNMENT) + +/* valid AES context ID */ +#define VALID_AES_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxRijndael) + +/* number of rounds (use [NK] for access) */ +static int rij128nRounds[3] = {NR128_128, NR128_192, NR128_256}; + +/* +// number of keys (estimation only!) (use [NK] for access) +// +// accurate number of keys necassary for encrypt/decrypt are: +// nKeys = NB * (NR+1) +// where NB - data block size (32-bit words) +// NR - number of rounds (depend on NB and keyLen) +// +// but the estimation +// estnKeys = (NK*n) >= nKeys +// or +// estnKeys = ( (NB*(NR+1) + (NK-1)) / NK) * NK +// where NK - key length (words) +// NB - data block size (word) +// NR - number of rounds (depend on NB and keyLen) +// nKeys - accurate numner of keys +// is more convinient when calculates key extension +*/ +static int rij128nKeys[3] = {44, 52, 60 }; + +/* +// helper for nRounds[] and estnKeys[] access +// note: x is length in 32-bits words +*/ +__INLINE int rij_index(int x) +{ + return (x-NB(128))>>1; +} + +/* size of AES context */ +__INLINE int cpSizeofCtx_AES(void) +{ + return sizeof(IppsAESSpec); +} + +#endif /* _PCP_AES_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesminit_internal.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesminit_internal.c new file mode 100644 index 000000000..1aaaaab71 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesminit_internal.c @@ -0,0 +1,172 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Initialization functions for internal methods and pointers +// AES cipher context +// AES-GCM context +// +*/ + +#include "pcpaesminit_internal.h" +#include "aes_gcm_avx512.h" +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcptool.h" + +#if (_IPP32E >= _IPP32E_K0) +#include "pcpaesauthgcm_avx512.h" +#else +#include "pcpaesauthgcm.h" +#endif /* #if(_IPP32E>=_IPP32E_K0) */ + +/* + * This function set up pointers to encryption and decryption key schedules, + * dispatches to the right internal methods and sets pointers to them inside the AES state. + */ +IPP_OWN_DEFN(void, cpAes_setup_ptrs_and_methods, (IppsAESSpec * pCtx)) +{ + int nExpKeys = rij128nKeys[rij_index(RIJ_NK(pCtx))]; + + RIJ_EKEYS(pCtx) = (Ipp8u *)(IPP_ALIGNED_PTR(RIJ_KEYS_BUFFER(pCtx), AES_ALIGNMENT)); + RIJ_DKEYS(pCtx) = (Ipp8u *)((Ipp32u *)RIJ_EKEYS(pCtx) + nExpKeys); + +#if (_AES_NI_ENABLING_ == _FEATURE_ON_) + RIJ_AESNI(pCtx) = AES_NI_ENABLED; + RIJ_ENCODER(pCtx) = Encrypt_RIJ128_AES_NI; /* AES_NI based encoder */ + RIJ_DECODER(pCtx) = Decrypt_RIJ128_AES_NI; /* AES_NI based decoder */ +#else +#if (_AES_NI_ENABLING_ == _FEATURE_TICKTOCK_) + if (IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)) { + RIJ_AESNI(pCtx) = AES_NI_ENABLED; + RIJ_ENCODER(pCtx) = Encrypt_RIJ128_AES_NI; /* AES_NI based encoder */ + RIJ_DECODER(pCtx) = Decrypt_RIJ128_AES_NI; /* AES_NI based decoder */ + } else +#endif + { +#if (_ALG_AES_SAFE_ == _ALG_AES_SAFE_COMPOSITE_GF_) + { + RIJ_ENCODER(pCtx) = SafeEncrypt_RIJ128; /* safe encoder (composite GF) */ + RIJ_DECODER(pCtx) = SafeDecrypt_RIJ128; /* safe decoder (composite GF)*/ + } +#else + { + RIJ_ENCODER(pCtx) = Safe2Encrypt_RIJ128; /* safe encoder (compact Sbox)) */ + RIJ_DECODER(pCtx) = Safe2Decrypt_RIJ128; /* safe decoder (compact Sbox)) */ + } +#endif + } +#endif +} + +/* + * This function dispatches to the right internal methods and sets pointers to them inside the AES-GCM state. + */ +IPP_OWN_DEFN(void, cpAesGCM_setup_ptrs_and_methods, (IppsAES_GCMState * pState, Ipp64u keyByteLen)) +{ +#if (_IPP32E >= _IPP32E_K0) + if (IsFeatureEnabled(ippCPUID_AVX512VAES) && IsFeatureEnabled(ippCPUID_AVX512VCLMUL)) { + switch (keyByteLen) { + case 16: + AES_GCM_ENCRYPT_UPDATE(pState) = aes_gcm_enc_128_update_vaes_avx512; + AES_GCM_DECRYPT_UPDATE(pState) = aes_gcm_dec_128_update_vaes_avx512; + AES_GCM_GET_TAG(pState) = aes_gcm_gettag_128_vaes_avx512; + break; + case 24: + AES_GCM_ENCRYPT_UPDATE(pState) = aes_gcm_enc_192_update_vaes_avx512; + AES_GCM_DECRYPT_UPDATE(pState) = aes_gcm_dec_192_update_vaes_avx512; + AES_GCM_GET_TAG(pState) = aes_gcm_gettag_192_vaes_avx512; + break; + case 32: + AES_GCM_ENCRYPT_UPDATE(pState) = aes_gcm_enc_256_update_vaes_avx512; + AES_GCM_DECRYPT_UPDATE(pState) = aes_gcm_dec_256_update_vaes_avx512; + AES_GCM_GET_TAG(pState) = aes_gcm_gettag_256_vaes_avx512; + break; + } + + AES_GCM_IV_UPDATE(pState) = aes_gcm_iv_hash_update_vaes512; + AES_GCM_IV_FINALIZE(pState) = aes_gcm_iv_hash_finalize_vaes512; + AES_GCM_AAD_UPDATE(pState) = aes_gcm_aad_hash_update_vaes512; + AES_GCM_GMUL(pState) = aes_gcm_gmult_vaes512; + } else { + switch (keyByteLen) { + case 16: + AES_GCM_ENCRYPT_UPDATE(pState) = aes_gcm_enc_128_update_avx512; + AES_GCM_DECRYPT_UPDATE(pState) = aes_gcm_dec_128_update_avx512; + AES_GCM_GET_TAG(pState) = aes_gcm_gettag_128_avx512; + break; + case 24: + AES_GCM_ENCRYPT_UPDATE(pState) = aes_gcm_enc_192_update_avx512; + AES_GCM_DECRYPT_UPDATE(pState) = aes_gcm_dec_192_update_avx512; + AES_GCM_GET_TAG(pState) = aes_gcm_gettag_192_avx512; + break; + case 32: + AES_GCM_ENCRYPT_UPDATE(pState) = aes_gcm_enc_256_update_avx512; + AES_GCM_DECRYPT_UPDATE(pState) = aes_gcm_dec_256_update_avx512; + AES_GCM_GET_TAG(pState) = aes_gcm_gettag_256_avx512; + break; + } + + AES_GCM_IV_UPDATE(pState) = aes_gcm_iv_hash_update_avx512; + AES_GCM_IV_FINALIZE(pState) = aes_gcm_iv_hash_finalize_avx512; + AES_GCM_AAD_UPDATE(pState) = aes_gcm_aad_hash_update_avx512; + AES_GCM_GMUL(pState) = aes_gcm_gmult_avx512; + } +#else + IPP_UNREFERENCED_PARAMETER(keyByteLen); + + /* set up: + // - ghash function + // - authentication function + */ + AESGCM_HASH(pState) = AesGcmMulGcm_table2K_ct; // AesGcmMulGcm_table2K; + AESGCM_AUTH(pState) = AesGcmAuth_table2K_ct; // AesGcmAuth_table2K; + AESGCM_ENC(pState) = wrpAesGcmEnc_table2K; + AESGCM_DEC(pState) = wrpAesGcmDec_table2K; + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) +// the dead code that currently is unused +//#if (_IPP32E >= _IPP32E_K0) +// if (IsFeatureEnabled(ippCPUID_AVX512VAES)) { +// AESGCM_HASH(pState) = AesGcmMulGcm_vaes; +// AESGCM_AUTH(pState) = AesGcmAuth_vaes; +// AESGCM_ENC(pState) = AesGcmEnc_vaes; +// AESGCM_DEC(pState) = AesGcmDec_vaes; +// } else +//#endif /* #if(_IPP32E>=_IPP32E_K0) */ + if (IsFeatureEnabled(ippCPUID_AES | ippCPUID_CLMUL)) { + AESGCM_HASH(pState) = AesGcmMulGcm_avx; + AESGCM_AUTH(pState) = AesGcmAuth_avx; + AESGCM_ENC(pState) = wrpAesGcmEnc_avx; + AESGCM_DEC(pState) = wrpAesGcmDec_avx; + } +#if (_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) + if (IsFeatureEnabled(ippCPUID_AVX2VAES | ippCPUID_AVX2VCLMUL)) { + AESGCM_HASH(pState) = AesGcmMulGcm_avx; + AESGCM_AUTH(pState) = AesGcmAuth_avx; + AESGCM_ENC(pState) = AesGcmEnc_vaes_avx2; + AESGCM_DEC(pState) = AesGcmDec_vaes_avx2; + } +#endif /* #if(_IPP==_IPP_H9) || (_IPP32E==_IPP32E_L9) */ +#endif /* #if(_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) */ + +#endif /* #if(_IPP32E>=_IPP32E_K0) */ +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesminit_internal.h b/plugin/ippcp/library/src/sources/ippcp/pcpaesminit_internal.h new file mode 100644 index 000000000..55985cead --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesminit_internal.h @@ -0,0 +1,39 @@ +/******************************************************************************* +* Copyright (C) 2023 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Initialization functions for internal methods and pointers +// AES cipher context +// AES-GCM context +// +*/ + +#if !defined(_PCP_AES_INIT_INTERNAL_H) +#define _PCP_AES_INIT_INTERNAL_H + +#include "owndefs.h" + +#define cpAes_setup_ptrs_and_methods OWNAPI(cpAes_setup_ptrs_and_methods) +IPP_OWN_DECL(void, cpAes_setup_ptrs_and_methods, (IppsAESSpec * pCtx)) + +#define cpAesGCM_setup_ptrs_and_methods OWNAPI(cpAesGCM_setup_ptrs_and_methods) +IPP_OWN_DECL(void, cpAesGCM_setup_ptrs_and_methods, (IppsAES_GCMState * pCtx, Ipp64u keyByteLen)) + +#endif /* _PCP_AES_INIT_INTERNAL_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesminitca.c b/plugin/ippcp/library/src/sources/ippcp/pcpaesminitca.c new file mode 100644 index 000000000..65d45005c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesminitca.c @@ -0,0 +1,146 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Initialization of AES +// +// Contents: +// ippsAESInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcprij128safe.h" +#include "pcptool.h" +#include "pcpaesminit_internal.h" + +/*F* +// Name: ippsAESInit +// +// Purpose: Init AES context for future usage +// and setup secret key. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// ippStsMemAllocErr size of buffer is not match for operation +// ippStsLengthErr keyLen != 16 +// keyLen != 24 +// keyLen != 32 +// ippStsNoErr no errors +// +// Parameters: +// pKey secret key +// keyLen length of the secret key (in bytes) +// pCtx pointer to buffer initialized as AES context +// ctxSize available size (in bytes) of buffer above +// +// Note: +// if pKey==NULL, then AES initialized by zero value key +// +*F*/ +IPPFUN(IppStatus, ippsAESInit,(const Ipp8u* pKey, int keyLen, + IppsAESSpec* pCtx, int ctxSize)) +{ + /* test context pointer */ + IPP_BAD_PTR1_RET(pCtx); + + /* make sure in legal keyLen */ + IPP_BADARG_RET(keyLen!=16 && keyLen!=24 && keyLen!=32, ippStsLengthErr); + + IPP_BADARG_RET(((Ipp8u*)pCtx+sizeof(IppsAESSpec)) > ((Ipp8u*)pCtx+ctxSize), ippStsMemAllocErr); + + { + int keyWords = NK(keyLen*BITSIZE(Ipp8u)); + int nExpKeys = rij128nKeys [ rij_index(keyWords) ]; + int nRounds = rij128nRounds[ rij_index(keyWords) ]; + + Ipp8u zeroKey[32] = {0}; + const Ipp8u* pActualKey = pKey? pKey : zeroKey; + + /* clear context */ + PadBlock(0, pCtx, sizeof(IppsAESSpec)); + + /* init spec */ + /* light trick to prevent context copy: add low 32-bit part of its current address to the context Id and + * check if is changed later in processing functions */ + RIJ_SET_ID(pCtx); + RIJ_NB(pCtx) = NB(128); + RIJ_NK(pCtx) = keyWords; + RIJ_NR(pCtx) = nRounds; + RIJ_SAFE_INIT(pCtx) = 1; + +#if (_AES_PROB_NOISE == _FEATURE_ON_) + /* Reset AES noise parameters */ + cpAESNoiseParams *params = (cpAESNoiseParams *)&RIJ_NOISE_PARAMS(pCtx); + + AES_NOISE_RAND(params) = 0; + AES_NOISE_LEVEL(params) = 0; +#endif + + cpAes_setup_ptrs_and_methods(pCtx); + + #if (_AES_NI_ENABLING_==_FEATURE_ON_) + cpExpandAesKey_NI(pActualKey, pCtx); /* AES_NI based key expansion */ + #else + #if (_AES_NI_ENABLING_==_FEATURE_TICKTOCK_) + if(IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)) { + cpExpandAesKey_NI(pActualKey, pCtx); /* AES_NI based key expansion */ + } + else + #endif + { + ExpandRijndaelKey(pActualKey, keyWords, NB(128), nRounds, nExpKeys, + RIJ_EKEYS(pCtx), + RIJ_DKEYS(pCtx)); + + #if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPOSITE_GF_) + { + int nr; + Ipp8u* pEnc_key = (Ipp8u*)(RIJ_EKEYS(pCtx)); + Ipp8u* pDec_key = (Ipp8u*)(RIJ_DKEYS(pCtx)); + /* update key material: convert into GF((2^4)2) */ + for(nr=0; nr<(1+nRounds); nr++) { + TransformNative2Composite(pEnc_key+16*nr, pEnc_key+16*nr); + TransformNative2Composite(pDec_key+16*nr, pDec_key+16*nr); + } + } + #else + { + int nr; + Ipp8u* pEnc_key = (Ipp8u*)(RIJ_EKEYS(pCtx)); + /* update key material: transpose inplace */ + for(nr=0; nr<(1+nRounds); nr++, pEnc_key+=16) { + SWAP(pEnc_key[ 1], pEnc_key[ 4]); + SWAP(pEnc_key[ 2], pEnc_key[ 8]); + SWAP(pEnc_key[ 3], pEnc_key[12]); + SWAP(pEnc_key[ 6], pEnc_key[ 9]); + SWAP(pEnc_key[ 7], pEnc_key[13]); + SWAP(pEnc_key[11], pEnc_key[14]); + } + } + #endif + } + #endif + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesmxts.h b/plugin/ippcp/library/src/sources/ippcp/pcpaesmxts.h new file mode 100644 index 000000000..dac04648b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesmxts.h @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// AES-XTS Internal Definitions +// +// +*/ + +#if !defined(_PCP_AES_XTS_H) +#define _PCP_AES_XTS_H + +#include "owncp.h" +#include "pcpaesm.h" + +#define _NEW_XTS_API_3 +#if defined (_NEW_XTS_API_3) +/* +// AES-XTS State +*/ +#if !defined(AES_BLK_SIZE) +#define AES_BLK_SIZE (IPP_AES_BLOCK_BITSIZE/BITSIZE(Ipp8u)) +#endif + +#define AES_BLKS_PER_BUFFER (32) + +struct _cpAES_XTS +{ + Ipp32u idCtx; + int duBitsize; /* size of data unit (in bits) */ + IppsAESSpec datumAES; /* datum AES context */ + IppsAESSpec tweakAES; /* tweak AES context */ +}; + +#define AES_XTS_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxAESXTS ^ (Ipp32u)IPP_UINT_PTR(ctx)) +/* valid AES_XTS context ID */ +#define VALID_AES_XTS_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxAESXTS) + +/* size of AES-XTS context */ +__INLINE int cpSizeof_AES_XTS_Ctx(void) +{ + return sizeof(IppsAES_XTSSpec); +} + +static int IsLegalGeometry(int startCipherBlkNo, int bitLen, int duBitsize) +{ + int duBlocks = (duBitsize+IPP_AES_BLOCK_BITSIZE-1)/IPP_AES_BLOCK_BITSIZE; + int legalBlk = (0<=startCipherBlkNo && startCipherBlkNo> 63) & GF_POLY; + Ipp64u addH = ((Ipp64s)x64[0] >> 63) & 1; + x64[0] = (x64[0]+x64[0]) ^ xorL; + x64[1] = (x64[1]+x64[1]) + addH; +} + +/* + the following are especially for multi-block processing +*/ +static void cpXTSwhitening(Ipp8u* buffer, int nblk, Ipp8u* ptwk) +{ + Ipp64u* pbuf64 = (Ipp64u*)buffer; + Ipp64u* ptwk64 = (Ipp64u*)ptwk; + + pbuf64[0] = ptwk64[0]; + pbuf64[1] = ptwk64[1]; + + for(nblk--, pbuf64+=2; nblk>0; nblk--, pbuf64+=2) { + gf_mul_by_primitive(ptwk64); + pbuf64[0] = ptwk64[0]; + pbuf64[1] = ptwk64[1]; + } + gf_mul_by_primitive(ptwk64); +} + +static void cpXTSxor16(Ipp8u* pDst, const Ipp8u* pSrc1, const Ipp8u* pSrc2, int nblk) +{ + Ipp64u* pdst64 = (Ipp64u*)pDst; + const Ipp64u* ps1_64 = (const Ipp64u*)pSrc1; + const Ipp64u* ps2_64 = (const Ipp64u*)pSrc2; + for(; nblk>0; nblk--, pdst64+=2, ps1_64+=2, ps2_64+=2) { + pdst64[0] = ps1_64[0] ^ ps2_64[0]; + pdst64[1] = ps1_64[1] ^ ps2_64[1]; + } +} + +#endif /* _PCP_AES_XTS_STUFF_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaesnoise.h b/plugin/ippcp/library/src/sources/ippcp/pcpaesnoise.h new file mode 100644 index 000000000..f783446f8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaesnoise.h @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*******************************************************************************/ + +#if !defined(_PCP_AES_NOISE_H) +#define _PCP_AES_NOISE_H + +/* + * The parameters below are empirical and choosen in advance to guarantee + * the high level of security protection against Mistletoe3 attack. + */ +#define MISTLETOE3_MAX_CHUNK_SIZE (16000) /* maximum chunks size allowed to be processed without noise injection (in bytes) \ + 16000 bytes = 16*1000 bytes = 1000 AES blocks */ +#define MISTLETOE3_TARGET_SIZE (800000000) /* expected sampling interval of the attacker. During the attack \ + the adversary measures how long it takes to encrypt MISTLETOE3_TARGET_SIZE of bytes. \ + MISTLETOE3_TARGET_SIZE is much greater than MISTLETOE3_MAX_CHUNK_SIZE \ + 800000000 bytes = 16*50000000 bytes = 50000000 AES blocks */ +#define MISTLETOE3_BASE_NOISE_LEVEL (28) /* noiseLevel adjusts the random number of what bitsize will be generated, this number will be \ + used as a parameter for _ippcpDelay function. Level of noise needed depends on many factors, such \ + as processor, code implementation, power limit setting by the attacker, etc. \ + For base noise level was selected a relatively safe value of 28, for user this parameter was \ + introduced as abstract with tunable range [0,4] */ + +#define MISTLETOE3_NOISE_RATE ((double)MISTLETOE3_MAX_CHUNK_SIZE / \ + (double)MISTLETOE3_TARGET_SIZE) + +/* Structure containing noise parameters required for Mistletoe3 mitigation */ +typedef struct _cpAESNoiseParams { + Ipp32u rnd; /* Random number value from previous noise injection */ + Ipp32u noiseLevel; /* Number of bits that should be taken from generated \ + 32-bit random value. noiseLevel == 0 -> mitigation is off */ +} cpAESNoiseParams; + +#define AES_NOISE_RAND(ctx) ((ctx)->rnd) +#define AES_NOISE_LEVEL(ctx) ((ctx)->noiseLevel) + +/* size of _cpAESNoiseParams structure */ +__INLINE int cpSizeofNoise_Params(void) +{ + return sizeof(cpAESNoiseParams); +} + +#define _ippcpDelay OWNAPI(_ippcpDelay) + IPP_OWN_DECL(void, _ippcpDelay, (Ipp32u value)) + +#define cpAESRandomNoise OWNAPI(cpAESRandomNoise) + IPP_OWN_DECL(IppStatus, cpAESRandomNoise, (IppBitSupplier rndFunc, Ipp32u nBits, Ipp64f noiseRate, Ipp32u *pRndValue)) + +#endif /* _PCP_AES_NOISE_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpaespack.c b/plugin/ippcp/library/src/sources/ippcp/pcpaespack.c new file mode 100644 index 000000000..3236d9179 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpaespack.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Initialization of AES +// +// Contents: +// ippsAESPack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpaesm.h" +#include "pcprij128safe.h" +#include "pcptool.h" + +/*F* +// Name: ippsAESPack +// +// Purpose: Serialize AES context into the buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pBuffer == NULL +// ippStsContextMatchErr RIJ_ID(pCtx) != idCtxRijndael +// ippStsLengthErr avaliable size of buffer is not enough for operation +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer RIJ spec +// pBuffer pointer to the buffer +// bufsize available size of buffer above +// +*F*/ +IPPFUN(IppStatus, ippsAESPack,(const IppsAESSpec* pCtx, Ipp8u* pBuffer, int bufsize)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + + /* test the context */ + IPP_BADARG_RET(!VALID_AES_ID(pCtx), ippStsContextMatchErr); + + /* test available size of destination buffer */ + IPP_BADARG_RET(bufsize=_IPP_V8) || (_IPP32E>=_IPP32E_M7)) + #define rc4word Ipp32u + +#else + #define rc4word Ipp8u +#endif + +/* +// ARCFOUR context +*/ +struct _cpARCfour { + Ipp32u idCtx; /* RC4 identifier */ + + Ipp32u cntX; /* algorithm's counter x */ + Ipp32u cntY; /* algorithm's counter y */ + rc4word Sbox[256]; /* current state block.*/ + Ipp8u Sbox0[256]; /* initial state block */ +}; + +/* alignment */ +#define RC4_ALIGNMENT ((int)(sizeof(Ipp32u))) + +/* +// Useful macros +*/ +#define RC4_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxARCFOUR ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define RC4_RESET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxARCFOUR) +#define RC4_CNTX(ctx) ((ctx)->cntX) +#define RC4_CNTY(ctx) ((ctx)->cntY) +#define RC4_SBOX(ctx) ((ctx)->Sbox) +#define RC4_SBOX0(ctx) ((ctx)->Sbox0) + +#define RC4_VALID_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxARCFOUR) + +/* +// internal functions +*/ +#define ARCFourProcessData OWNAPI(ARCFourProcessData) + IPP_OWN_DECL (void, ARCFourProcessData, (const Ipp8u *pSrc, Ipp8u *pDst, int length, IppsARCFourState *pCtx)) + +#endif /* _ARCFOUR_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfour_processdata.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfour_processdata.c new file mode 100644 index 000000000..e797fe0b7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfour_processdata.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + + +/* +// data processing function. +*/ +#if !((_IPP>=_IPP_M5) || (_IPP32E>=_IPP32E_M7)) + +IPP_OWN_DEFN (void, ARCFourProcessData, (const Ipp8u *pSrc, Ipp8u *pDst, int length, IppsARCFourState *pCtx)) +{ + if(length) { + rc4word tx, ty; + + Ipp32u x = RC4_CNTX(pCtx); + Ipp32u y = RC4_CNTY(pCtx); + rc4word* pSbox = RC4_SBOX(pCtx); + + x = (x+1) &0xFF; + tx = pSbox[x]; + + while(length) { + y = (y+tx) & 0xFF; + ty = pSbox[y]; + pSbox[x] = ty; + x = (x+1) & 0xFF; + ty = (ty+tx) & 0xFF; + pSbox[y] = tx; + tx = pSbox[x]; + ty = pSbox[ty]; + *pDst = (Ipp8u)( *pSrc ^ ty ); + pDst++; + pSrc++; + length--; + } + RC4_CNTX(pCtx) = (x-1) & 0xFF; + RC4_CNTY(pCtx) = y; + } +} + +#endif /* #if !((_IPP>=_IPP_M5) || (_IPP32E>=_IPP32E_M7)) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourca.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourca.c new file mode 100644 index 000000000..73a3bc026 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourca.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/*F* +// Name: ippsARCFourInit +// +// Purpose: Init ARCFOUR spec for future usage. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// ippStsLengthErr 1 > keyLen +// keyLen > IPP_ARCFOUR_KEYMAX_SIZE +// ippStsNoErr no errors +// +// Parameters: +// key security key +// keyLen length of key (bytes) +// pCtx pointer to the ARCFOUR context +// +*F*/ +IPPFUN(IppStatus, ippsARCFourInit, (const Ipp8u *pKey, int keyLen, IppsARCFourState *pCtx)) +{ + /* test context pointer */ + IPP_BAD_PTR1_RET(pCtx); + + /* test key */ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(((1>keyLen)||(IPP_ARCFOUR_KEYMAX_SIZE< keyLen)), ippStsLengthErr); + + { + int i; + Ipp8u kblk[256], j, tmp; + + /* init RC4 context */ + RC4_SET_ID(pCtx); + + for(i=0; i<256; i++) { + pCtx->Sbox0[i] = (Ipp8u)i; + kblk[i] = pKey[i%keyLen]; + } + j=0; + for(i=0; i<256; i++) { + j += pCtx->Sbox0[i] + kblk[i]; + tmp = pCtx->Sbox0[j]; + pCtx->Sbox0[j] = pCtx->Sbox0[i]; + pCtx->Sbox0[i] = tmp; + } + + return ippsARCFourReset(pCtx); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourcheckkey.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourcheckkey.c new file mode 100644 index 000000000..42ff69947 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourcheckkey.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/*F* +// Name: ippsARCFourCheckKey +// +// Purpose: Checks key for weakness. +// +// Returns: Reason: +// ippStsNullPtrErr pKey== NULL +// ippStsNullPtrErr pIsWeak== NULL +// ippStsLengthErr 1 > keyLen +// keyLen > IPP_ARCFOUR_KEYMAX_SIZE +// ippStsNoErr no errors +// +// Parameters: +// key security key +// keyLen length of key (bytes) +// pIsWeak pointer to the result +// +// Note: +// See ANDREW ROOS "A CLASS OF WEAK KEYS IN THE RC4 STREAM CIPHER" +// (http://marcel.wanda.ch/Archive/WeakKeys) +*F*/ +IPPFUN(IppStatus, ippsARCFourCheckKey, (const Ipp8u *pKey, int keyLen, IppBool* pIsWeak)) +{ + /* test key */ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(((1>keyLen)||(IPP_ARCFOUR_KEYMAX_SIZE< keyLen)), ippStsLengthErr); + + /* test result*/ + IPP_BAD_PTR1_RET(pIsWeak); + + if(1==keyLen) + *pIsWeak = (pKey[0]==128)? ippTrue : ippFalse; + else + *pIsWeak = (pKey[0] + pKey[1])%256 == 0 ? ippTrue : ippFalse; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourdecrypt.c new file mode 100644 index 000000000..10aef07cf --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourdecrypt.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/*F* +// Name: ippsARCFourDecrypt +// +// Purpose: Decrypt data stream. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr pCtx->idCtx != idCtxARCFOUR +// ippStsLengthErr length<1 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data block stream +// pDst pointer to the destination byte data block stream +// length stream length (bytes) +// pCtx pointer to the ARCFOUR context +// +// Note: +// Convenience function only +*F*/ +IPPFUN(IppStatus, ippsARCFourDecrypt, (const Ipp8u *pSrc, Ipp8u *pDst, int length, + IppsARCFourState *pCtx)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RC4_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test source and destination pointers */ + IPP_BAD_PTR2_RET(pSrc, pDst); + /* test stream length */ + IPP_BADARG_RET((length<1), ippStsLengthErr); + + + /* process data */ + ARCFourProcessData(pSrc, pDst, length, pCtx); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourencrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourencrypt.c new file mode 100644 index 000000000..b0560b5e8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourencrypt.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/*F* +// Name: ippsARCFourEncrypt +// +// Purpose: Encrypt data stream. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr pCtx->idCtx != idCtxARCFOUR +// ippStsLengthErr length<1 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data block stream +// pDst pointer to the destination byte data block stream +// length stream length (bytes) +// pCtx ponter to the ARCFOUR context +// +// Note: +// Convenience function only +*F*/ +IPPFUN(IppStatus, ippsARCFourEncrypt, (const Ipp8u *pSrc, Ipp8u *pDst, int length, + IppsARCFourState *pCtx)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RC4_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test source and destination pointers */ + IPP_BAD_PTR2_RET(pSrc, pDst); + /* test stream length */ + IPP_BADARG_RET((length<1), ippStsLengthErr); + + /* process data */ + ARCFourProcessData(pSrc, pDst, length, pCtx); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourgetsize.c new file mode 100644 index 000000000..baa43056c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourgetsize.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +/*F* +// Name: ippsARCFourGetSize +// +// Purpose: Returns size of ARCFOUR context (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSzie == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of ARCFOUR context +// +*F*/ +IPPFUN(IppStatus, ippsARCFourGetSize, (int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsARCFourState); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourpack.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourpack.c new file mode 100644 index 000000000..e8e3c6a07 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourpack.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/*F* +// Name: ippsARCFourPack +// +// Purpose: Copy initialized context to the buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pCtx == NULL +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer ARCFour spec +// pSize pointer to the packed spec size +// +*F*/ +IPPFUN(IppStatus, ippsARCFourPack,(const IppsARCFourState* pCtx, Ipp8u* pBuffer)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + /* test the context */ + IPP_BADARG_RET(!RC4_VALID_ID(pCtx), ippStsContextMatchErr); + + CopyBlock(pCtx, pBuffer, sizeof(IppsARCFourState)); + IppsARCFourState* pCopy = (IppsARCFourState*)pBuffer; + RC4_RESET_ID(pCopy); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourreset.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourreset.c new file mode 100644 index 000000000..093ba284b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourreset.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/*F* +// Name: ippsARCFourReset +// +// Purpose: Resrt ARCFOUR context: +// set current state block to the initial one +// and zeroes counters +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// ippStsContextMatchErr pCtx->idCtx != idCtxARCFOUR +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer to the ARCFOUR context +// +*F*/ +IPPFUN(IppStatus, ippsARCFourReset, (IppsARCFourState* pCtx)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RC4_VALID_ID(pCtx), ippStsContextMatchErr); + + { + /* reset Sbox */ + int n; + for(n=0; n<256; n++) + RC4_SBOX(pCtx)[n] = RC4_SBOX0(pCtx)[n]; + + /* reset counters */ + RC4_CNTX(pCtx) = 0; + RC4_CNTY(pCtx) = 0; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcparcfourunpack.c b/plugin/ippcp/library/src/sources/ippcp/pcparcfourunpack.c new file mode 100644 index 000000000..9f9df52f0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcparcfourunpack.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RC4 implementation +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcparcfour.h" +#include "pcptool.h" + +/*F* +// Name: ippsARCFourUnpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pCtx == NULL +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer ARCFour spec +// pSize pointer to the packed spec size +// +*F*/ +IPPFUN(IppStatus, ippsARCFourUnpack,(const Ipp8u* pBuffer, IppsARCFourState* pCtx)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + + CopyBlock(pBuffer, pCtx, sizeof(IppsARCFourState)); + RC4_SET_ID(pCtx); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbn.h b/plugin/ippcp/library/src/sources/ippcp/pcpbn.h new file mode 100644 index 000000000..4b47281d4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbn.h @@ -0,0 +1,207 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// +// +*/ + +#if !defined(_CP_BN_H) +#define _CP_BN_H + +#include "pcpbnuimpl.h" +#include "pcpbnuarith.h" +#include "pcpbnumisc.h" +#include "pcpbnu32arith.h" +#include "pcpbnu32misc.h" + +/* +// Big Number context +*/ +struct _cpBigNum +{ + Ipp32u idCtx; /* BigNum ctx id */ + IppsBigNumSGN sgn; /* sign */ + cpSize size; /* BigNum size (BNU_CHUNK_T) */ + cpSize room; /* BigNum max size (BNU_CHUNK_T) */ + BNU_CHUNK_T* number; /* BigNum value */ + BNU_CHUNK_T* buffer; /* temporary buffer */ +}; + +/* BN accessory macros */ +#define BN_SET_ID(pBN) ((pBN)->idCtx = (Ipp32u)idCtxBigNum ^ (Ipp32u)IPP_UINT_PTR(pBN)) +#define BN_SIGN(pBN) ((pBN)->sgn) +#define BN_POSITIVE(pBN) (BN_SIGN(pBN)==ippBigNumPOS) +#define BN_NEGATIVE(pBN) (BN_SIGN(pBN)==ippBigNumNEG) +#define BN_NUMBER(pBN) ((pBN)->number) +#define BN_BUFFER(pBN) ((pBN)->buffer) +#define BN_ROOM(pBN) ((pBN)->room) +#define BN_SIZE(pBN) ((pBN)->size) +#define BN_SIZE32(pBN) ((pBN)->size*((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)))) +//#define BN_SIZE32(pBN) (BITS2WORD32_SIZE( BITSIZE_BNU(BN_NUMBER((pBN)),BN_SIZE((pBN))))) + +#define BN_VALID_ID(pBN) ((((pBN)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((pBN))) == (Ipp32u)idCtxBigNum) + +#define INVERSE_SIGN(s) (((s)==ippBigNumPOS)? ippBigNumNEG : ippBigNumPOS) + +#define BN_ALIGNMENT ((int)sizeof(void*)) + + +/* pack-unpack context */ +#define cpPackBigNumCtx OWNAPI(cpPackBigNumCtx) + IPP_OWN_DECL (void, cpPackBigNumCtx, (const IppsBigNumState* pBN, Ipp8u* pBuffer)) +#define cpUnpackBigNumCtx OWNAPI(cpUnpackBigNumCtx) + IPP_OWN_DECL (void, cpUnpackBigNumCtx, (const Ipp8u* pBuffer, IppsBigNumState* pBN)) + +/* copy BN */ +__INLINE IppsBigNumState* cpBN_copy(IppsBigNumState* pDst, const IppsBigNumState* pSrc) +{ + BN_SIGN(pDst) = BN_SIGN(pSrc); + BN_SIZE(pDst) = BN_SIZE(pSrc); + ZEXPAND_COPY_BNU(BN_NUMBER(pDst), BN_ROOM(pDst), BN_NUMBER(pSrc), BN_SIZE(pSrc)); + return pDst; +} +/* set BN to zero */ +__INLINE IppsBigNumState* cpBN_zero(IppsBigNumState* pBN) +{ + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = 1; + ZEXPAND_BNU(BN_NUMBER(pBN),0, (int)BN_ROOM(pBN)); + return pBN; +} +/* fixup BN */ +__INLINE IppsBigNumState* cpBN_fix(IppsBigNumState* pBN) +{ + cpSize len = BN_SIZE(pBN); + FIX_BNU(BN_NUMBER(pBN), len); + BN_SIZE(pBN) = len; + return pBN; +} +/* set BN to chunk */ +__INLINE IppsBigNumState* cpBN_chunk(IppsBigNumState* pBN, BNU_CHUNK_T a) +{ + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = 1; + ZEXPAND_BNU(BN_NUMBER(pBN),0, (int)BN_ROOM(pBN)); + BN_NUMBER(pBN)[0] = a; + return pBN; +} +/* set BN to 2^m */ +__INLINE IppsBigNumState* cpBN_power2(IppsBigNumState* pBN, int power) +{ + cpSize size = BITS_BNU_CHUNK(power+1); + if(BN_ROOM(pBN) >= size) { + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = size; + ZEXPAND_BNU(BN_NUMBER(pBN),0, BN_ROOM(pBN)); + SET_BIT(BN_NUMBER(pBN), power); + return pBN; + } + else return NULL; +} + +/* bitsize of BN */ +__INLINE int cpBN_bitsize(const IppsBigNumState* pA) +{ + int bitsize = BITSIZE_BNU(BN_NUMBER(pA), BN_SIZE(pA)); + return bitsize; +} + +/* returns -1/0/+1 depemding on A~B comparison */ +__INLINE int cpBN_cmp(const IppsBigNumState* pA, const IppsBigNumState* pB) +{ + IppsBigNumSGN signA = BN_SIGN(pA); + IppsBigNumSGN signB = BN_SIGN(pB); + + if(signA==signB) { + int result = cpCmp_BNU(BN_NUMBER(pA), BN_SIZE(pA), BN_NUMBER(pB), BN_SIZE(pB)); + return (ippBigNumPOS==signA)? result : -result; + } + return (ippBigNumPOS==signA)? 1 : -1; +} + +/* returns -1/0/+1 depemding on A comparison 00 */ +__INLINE int cpBN_tst(const IppsBigNumState* pA) +{ + if(1==BN_SIZE(pA) && 0==BN_NUMBER(pA)[0]) + return 0; + else + return BN_POSITIVE(pA)? 1 : -1; +} + + +// some addtition functions +__INLINE int IsZero_BN(const IppsBigNumState* pA) +{ + return ( BN_SIZE(pA)==1 ) && ( BN_NUMBER(pA)[0]==0 ); +} +__INLINE int IsOdd_BN(const IppsBigNumState* pA) +{ + return BN_NUMBER(pA)[0] & 1; +} + +__INLINE IppsBigNumState* BN_Word(IppsBigNumState* pBN, BNU_CHUNK_T w) +{ + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = 1; + ZEXPAND_BNU(BN_NUMBER(pBN),0, BN_ROOM(pBN)); + BN_NUMBER(pBN)[0] = w; + return pBN; +} +__INLINE IppsBigNumState* BN_Set(const BNU_CHUNK_T* pData, cpSize len, IppsBigNumState* pBN) +{ + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = len; + ZEXPAND_COPY_BNU(BN_NUMBER(pBN), BN_ROOM(pBN), pData, len); + return pBN; +} +__INLINE IppsBigNumState* BN_Make(BNU_CHUNK_T* pData, BNU_CHUNK_T* pBuffer, cpSize len, IppsBigNumState* pBN) +{ + BN_SET_ID(pBN); + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = 1; + BN_ROOM(pBN) = len; + BN_NUMBER(pBN) = pData; + BN_BUFFER(pBN) = pBuffer; + return pBN; +} + +/* +// fixed single chunk BN +*/ +typedef struct _ippcpBigNumChunk { + IppsBigNumState bn; + BNU_CHUNK_T value; + BNU_CHUNK_T temporary; +} IppsBigNumStateChunk; + +/* reference to BN(1) and BN(2) */ +#define cpBN_OneRef OWNAPI(cpBN_OneRef) + IPP_OWN_DECL (IppsBigNumState*, cpBN_OneRef, (void)) +#define cpBN_TwoRef OWNAPI(cpBN_TwoRef) + IPP_OWN_DECL (IppsBigNumState*, cpBN_TwoRef, (void)) +#define cpBN_ThreeRef OWNAPI(cpBN_ThreeRef) + IPP_OWN_DECL (IppsBigNumState*, cpBN_ThreeRef, (void)) + +#define BN_ONE_REF() cpBN_OneRef() +#define BN_TWO_REF() cpBN_TwoRef() +#define BN_THREE_REF() cpBN_ThreeRef() + +#endif /* _CP_BN_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbn_pack.c b/plugin/ippcp/library/src/sources/ippcp/pcpbn_pack.c new file mode 100644 index 000000000..1abd0563f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbn_pack.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpPackBigNumCtx() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: cpPackBigNumCtx +// +// Purpose: Serialize bigNum context +// +// Parameters: +// pBN BigNum +// pBuffer buffer +*F*/ +IPP_OWN_DEFN (void, cpPackBigNumCtx, (const IppsBigNumState* pBN, Ipp8u* pBuffer)) +{ + IppsBigNumState* pB = (IppsBigNumState*)(pBuffer); + CopyBlock(pBN, pB, sizeof(IppsBigNumState)); + + cpSize dataAlignment = (cpSize)(IPP_INT_PTR(BN_NUMBER(pBN)) - IPP_INT_PTR(pBN) - (IPP_INT64)sizeof(IppsBigNumState)); + + BN_NUMBER(pB) = (BNU_CHUNK_T*)((Ipp8u*)NULL + IPP_INT_PTR(BN_NUMBER(pBN))-IPP_INT_PTR(pBN) - dataAlignment); + BN_BUFFER(pB) = (BNU_CHUNK_T*)((Ipp8u*)NULL + IPP_INT_PTR(BN_BUFFER(pBN))-IPP_INT_PTR(pBN) - dataAlignment); + + CopyBlock(BN_NUMBER(pBN), (Ipp8u*)pB+IPP_UINT_PTR(BN_NUMBER(pB)), BN_ROOM(pBN)*(Ipp32s)sizeof(BNU_CHUNK_T)); + CopyBlock(BN_BUFFER(pBN), (Ipp8u*)pB+IPP_UINT_PTR(BN_BUFFER(pB)), BN_ROOM(pBN)*(Ipp32s)sizeof(BNU_CHUNK_T)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbn_unpack.c b/plugin/ippcp/library/src/sources/ippcp/pcpbn_unpack.c new file mode 100644 index 000000000..7740c3fb6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbn_unpack.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpUnpackBigNumCtx() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: cpUnpackBigNumCtx +// +// Purpose: Deserialize bigNum context +// +// Parameters: +// pBN BigNum +// pBuffer buffer +*F*/ + + +IPP_OWN_DEFN (void, cpUnpackBigNumCtx, (const Ipp8u* pBuffer, IppsBigNumState* pBN)) +{ + IppsBigNumState* pB = (IppsBigNumState*)(pBuffer); + CopyBlock(pBuffer, pBN, sizeof(IppsBigNumState)); + + Ipp8u* ptr = (Ipp8u*)pBN; + ptr += sizeof(IppsBigNumState); + ptr = IPP_ALIGNED_PTR(ptr, BN_ALIGNMENT); + BN_NUMBER(pBN) = (BNU_CHUNK_T*)(ptr); + ptr += BN_ROOM(pBN)*(Ipp32s)sizeof(BNU_CHUNK_T); + BN_BUFFER(pBN) = (BNU_CHUNK_T*)(ptr); + + cpSize bufferOffset = (cpSize)(IPP_INT_PTR(BN_BUFFER(pBN)) - IPP_INT_PTR(pBN)); + + CopyBlock((Ipp8u*)pB+sizeof(IppsBigNumState), BN_NUMBER(pBN), BN_ROOM(pBN)*(Ipp32s)sizeof(BNU_CHUNK_T)); + CopyBlock((Ipp8u*)pB+bufferOffset, BN_BUFFER(pBN), BN_ROOM(pBN)*(Ipp32s)sizeof(BNU_CHUNK_T)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbn_val1.c b/plugin/ippcp/library/src/sources/ippcp/pcpbn_val1.c new file mode 100644 index 000000000..0e0f7e441 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbn_val1.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpBN_OneRef() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: cpBN_OneRef +// +// Purpose: BN(1) and reference +// +// Return: +// BigNum = 1 +*F*/ + +/* BN(1) and reference */ +IPP_OWN_DEFN (IppsBigNumState*, cpBN_OneRef, (void)) +{ + static IppsBigNumStateChunk cpChunk_BN1 = { + { + idCtxUnknown, + ippBigNumPOS, + 1,1, + &cpChunk_BN1.value,&cpChunk_BN1.temporary + }, + 1,0 + }; + BN_SET_ID(&cpChunk_BN1.bn); + return &cpChunk_BN1.bn; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbn_val2.c b/plugin/ippcp/library/src/sources/ippcp/pcpbn_val2.c new file mode 100644 index 000000000..82c2779de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbn_val2.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpBN_TwoRef() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: cpBN_TwoRef +// +// Purpose: BN(2) and reference +// +// Return: +// BigNum = 2 +*F*/ + +IPP_OWN_DEFN (IppsBigNumState*, cpBN_TwoRef, (void)) +{ + static IppsBigNumStateChunk cpChunk_BN2 = { + { + idCtxUnknown, + ippBigNumPOS, + 1,1, + &cpChunk_BN2.value,&cpChunk_BN2.temporary + }, + 2,0 + }; + BN_SET_ID(&cpChunk_BN2.bn); + return &cpChunk_BN2.bn; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbn_val3.c b/plugin/ippcp/library/src/sources/ippcp/pcpbn_val3.c new file mode 100644 index 000000000..bde9f8faf --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbn_val3.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpBN_ThreeRef() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: cpBN_ThreeRef +// +// Purpose: BN(3) and reference +// +// Return: +// BigNum = 3 +*F*/ + +IPP_OWN_DEFN (IppsBigNumState*, cpBN_ThreeRef, (void)) +{ + static IppsBigNumStateChunk cpChunk_BN3 = { + { + idCtxUnknown, + ippBigNumPOS, + 1,1, + &cpChunk_BN3.value,&cpChunk_BN3.temporary + }, + 3,0 + }; + BN_SET_ID(&cpChunk_BN3.bn); + return &cpChunk_BN3.bn; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithadd.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithadd.c new file mode 100644 index 000000000..2a323438e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithadd.c @@ -0,0 +1,124 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsAdd_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsAdd_BN +// +// Purpose: Add BigNums. +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pB == NULL +// pR == NULL +// ippStsContextMatchErr !BN_VALID_ID(pA) +// !BN_VALID_ID(pB) +// !BN_VALID_ID(pR) +// ippStsOutOfRangeErr pR can not hold result +// ippStsNoErr no errors +// +// Parameters: +// pA source BigNum A +// pB source BigNum B +// pR resultant BigNum +// +*F*/ +IPPFUN(IppStatus, ippsAdd_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +{ + IPP_BAD_PTR3_RET(pA, pB, pR); + + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pB), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + { + cpSize nsA = BN_SIZE(pA); + cpSize nsB = BN_SIZE(pB); + cpSize nsR = BN_ROOM(pR); + IPP_BADARG_RET(nsR < IPP_MAX(nsA, nsB), ippStsOutOfRangeErr); + + { + BNU_CHUNK_T* pDataR = BN_NUMBER(pR); + + IppsBigNumSGN sgnA = BN_SIGN(pA); + IppsBigNumSGN sgnB = BN_SIGN(pB); + BNU_CHUNK_T* pDataA = BN_NUMBER(pA); + BNU_CHUNK_T* pDataB = BN_NUMBER(pB); + + BNU_CHUNK_T carry; + + if(sgnA==sgnB) { + if(nsA < nsB) { + SWAP(nsA, nsB); + SWAP_PTR(BNU_CHUNK_T, pDataA, pDataB); + } + + carry = cpAdd_BNU(pDataR, pDataA, pDataB, nsB); + if(nsA>nsB) + carry = cpInc_BNU(pDataR+nsB, pDataA+nsB, nsA-nsB, carry); + if(carry) { + if(nsR>nsA) + pDataR[nsA++] = carry; + else + IPP_ERROR_RET(ippStsOutOfRangeErr); + } + BN_SIGN(pR) = sgnA; + } + + else { + int cmpRes = cpCmp_BNU(pDataA, nsA, pDataB, nsB); + + if(0==cmpRes) { + pDataR[0] = 0; + BN_SIZE(pR) = 1; + BN_SIGN(pR) = ippBigNumPOS; + return ippStsNoErr; + } + + if(0>cmpRes) { + SWAP(nsA, nsB); + SWAP_PTR(BNU_CHUNK_T, pDataA, pDataB); + } + + carry = cpSub_BNU(pDataR, pDataA, pDataB, nsB); + if(nsA>nsB) + cpDec_BNU(pDataR+nsB, pDataA+nsB, nsA-nsB, carry); + + BN_SIGN(pR) = cmpRes>0? sgnA : INVERSE_SIGN(sgnA); + } + + FIX_BNU(pDataR, nsA); + BN_SIZE(pR) = nsA; + + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithcmp.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithcmp.c new file mode 100644 index 000000000..5a8bc7679 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithcmp.c @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsCmp_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + +/*F* +// Name: ippsCmp_BN +// +// Purpose: Compare two BigNums. +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pB == NULL +// pResult == NULL +// ippStsContextMatchErr !BN_VALID_ID(pA) +// !BN_VALID_ID(pB) +// ippStsNoErr no errors +// +// Parameters: +// pA BigNum ctx +// pB BigNum ctx +// pResult result of comparison +// +*F*/ +IPPFUN(IppStatus, ippsCmp_BN,(const IppsBigNumState* pA, const IppsBigNumState* pB, Ipp32u *pResult)) +{ + IPP_BAD_PTR3_RET(pA, pB, pResult); + + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pB), ippStsContextMatchErr); + + { + BNU_CHUNK_T positiveA = cpIsEqu_ct(ippBigNumPOS, BN_SIGN(pA)); + BNU_CHUNK_T positiveB = cpIsEqu_ct(ippBigNumPOS, BN_SIGN(pB)); + BNU_CHUNK_T signMask; + + /* (ippBigNumPOS == BN_SIGN(pA)) && (ippBigNumPOS==BN_SIGN(pB)) => res = cpCmp_BNU() */ + BNU_CHUNK_T res = (BNU_CHUNK_T)( cpCmp_BNU(BN_NUMBER(pA), BN_SIZE(pA), BN_NUMBER(pB), BN_SIZE(pB)) ); + + /* (ippBigNumNEG == BN_SIGN(pA)) && (ippBigNumNEG==BN_SIGN(pB)) => invert res value */ + signMask = ~positiveA & ~positiveB; + res = (res & ~signMask) | ((0-res) & signMask); + + /* (ippBigNumPOS == BN_SIGN(pA)) && (ippBigNumNEG==BN_SIGN(pB)) => res = 1 */ + signMask = positiveA & ~positiveB; + res = (res & ~signMask) | ((1) & signMask); + + /* (ippBigNumNEG == BN_SIGN(pA)) && (ippBigNumPOS==BN_SIGN(pB)) => res = -1 */ + signMask = ~positiveA & positiveB; + res = (res & ~signMask) | ((BNU_CHUNK_T)(-1) & signMask); + + // map res into IPP_IS_LT/EQ/GT + Ipp32u cmpResult = (Ipp32u)( (cpIsEqu_ct(res, (BNU_CHUNK_T)(-1)) & IPP_IS_LT) + | (cpIsEqu_ct(res, (BNU_CHUNK_T)(0)) & IPP_IS_EQ) + | (cpIsEqu_ct(res, (BNU_CHUNK_T)(1)) & IPP_IS_GT) ); + *pResult = cmpResult; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithcmpz.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithcmpz.c new file mode 100644 index 000000000..bd848b7dd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithcmpz.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsCmpZero_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsCmpZero_BN +// +// Purpose: Compare BigNum value with zero. +// +// Returns: Reason: +// ippStsNullPtrErr pBN == NULL +// pResult == NULL +// ippStsContextMatchErr !BN_VALID_ID(pBN) +// ippStsNoErr no errors +// +// Parameters: +// pBN BigNum ctx +// pResult result of comparison +// +*F*/ +IPPFUN(IppStatus, ippsCmpZero_BN, (const IppsBigNumState* pBN, Ipp32u* pResult)) +{ + IPP_BAD_PTR2_RET(pBN, pResult); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + + if(BN_SIZE(pBN)==1 && BN_NUMBER(pBN)[0]==0) + *pResult = IS_ZERO; + else if (BN_SIGN(pBN)==ippBigNumPOS) + *pResult = GREATER_THAN_ZERO; + else if (BN_SIGN(pBN)==ippBigNumNEG) + *pResult = LESS_THAN_ZERO; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithdiv.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithdiv.c new file mode 100644 index 000000000..22ed9744b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithdiv.c @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsDiv_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsDiv_BN +// +// Purpose: Divide BigNums. +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pB == NULL +// pQ == NULL +// pR == NULL +// ippStsContextMatchErr !BN_VALID_ID(pA) +// !BN_VALID_ID(pB) +// !BN_VALID_ID(pQ) +// !BN_VALID_ID(pR) +// ippStsDivByZeroErr BN_SIZE(pB) == 1 && BN_NUMBER(pB)[0] == 0 +// ippStsOutOfRangeErr pQ and/or pR can not hold result +// ippStsNoErr no errors +// +// Parameters: +// pA source BigNum +// pB source BigNum +// pQ quotient BigNum +// pR reminder BigNum +// +// A = Q*B + R, 0 <= val(R) < val(B), sgn(A)==sgn(R) +// +*F*/ +IPPFUN(IppStatus, ippsDiv_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pQ, IppsBigNumState* pR)) +{ + IPP_BAD_PTR4_RET(pA, pB, pQ, pR); + + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pB), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pQ), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + IPP_BADARG_RET(BN_SIZE(pB)== 1 && BN_NUMBER(pB)[0]==0, ippStsDivByZeroErr); + + IPP_BADARG_RET(BN_ROOM(pR)cmpRes) + SWAP_PTR(IppsBigNumState, x, y); + if(0==cmpRes) { + COPY_BNU(BN_NUMBER(g), BN_NUMBER(x), BN_SIZE(x)); + BN_SIGN(g) = ippBigNumPOS; + BN_SIZE(g) = BN_SIZE(x); + return ippStsNoErr; + } + if(BN_SIZE(x)==1) { + BNU_CHUNK_T gcd = cpGcd_BNU(BN_NUMBER(x)[0], BN_NUMBER(y)[0]); + BN_NUMBER(g)[0] = gcd; + BN_SIZE(g) = 1; + return ippStsNoErr; + } + } + + { + Ipp32u* xBuffer = (Ipp32u*)BN_BUFFER(x); + Ipp32u* yBuffer = (Ipp32u*)BN_BUFFER(y); + Ipp32u* gBuffer = (Ipp32u*)BN_BUFFER(g); + Ipp32u* xData = (Ipp32u*)BN_NUMBER(x); + Ipp32u* yData = (Ipp32u*)BN_NUMBER(y); + Ipp32u* gData = (Ipp32u*)BN_NUMBER(g); + cpSize nsXmax = BN_ROOM(x)*((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))); + cpSize nsYmax = BN_ROOM(y)*((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))); + cpSize nsGmax = BN_ROOM(g)*((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))); + cpSize nsX = BN_SIZE(x)*((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))); + cpSize nsY = BN_SIZE(y)*((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))); + + Ipp32u* T; + Ipp32u* u; + + FIX_BNU32(xData, nsX); + FIX_BNU32(yData, nsY); + + /* init buffers */ + ZEXPAND_COPY_BNU(xBuffer, nsXmax, xData, nsX); + ZEXPAND_COPY_BNU(yBuffer, nsYmax, yData, nsY); + + T = gBuffer; + u = gData; + ZEXPAND_BNU(T, 0, nsGmax); + ZEXPAND_BNU(u, 0, nsGmax); + + while(nsX > (cpSize)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))) { + /* xx and yy is the high-order digits of x and y (yy could be 0) */ + + Ipp64u xx = (Ipp64u)(xBuffer[nsX-1]); + Ipp64u yy = (nsY < nsX)? 0 : (Ipp64u)(yBuffer[nsY-1]); + + Ipp64s AA = 1; + Ipp64s BB = 0; + Ipp64s CC = 0; + Ipp64s DD = 1; + Ipp64s t; + + while((yy+(Ipp64u)CC)!=0 && (yy+(Ipp64u)DD)!=0) { + Ipp64u q = ( xx + (Ipp64u)AA ) / ( yy + (Ipp64u)CC ); + Ipp64u q1 = ( xx + (Ipp64u)BB ) / ( yy + (Ipp64u)DD ); + if(q!=q1) + break; + t = AA - (Ipp64s)q*CC; + AA = CC; + CC = t; + t = BB - (Ipp64s)q*DD; + BB = DD; + DD = t; + t = (Ipp64s)(xx - q*yy); + xx = yy; + yy = (Ipp64u)t; + } + + if(BB == 0) { + /* T = x mod y */ + cpSize nsT = cpMod_BNU32(xBuffer, nsX, yBuffer, nsY); + ZEXPAND_BNU(T, 0, nsGmax); + COPY_BNU(T, xBuffer, nsT); + /* a = b; b = T; */ + ZEXPAND_BNU(xBuffer, 0, nsXmax); + COPY_BNU(xBuffer, yBuffer, nsY); + ZEXPAND_BNU(yBuffer, 0, nsYmax); + COPY_BNU(yBuffer, T, nsY); + } + + else { + Ipp32u carry; + /* + // T = AA*x + BB*y; + // u = CC*x + DD*y; + // b = u; a = T; + */ + if((AA <= 0)&&(BB>=0)) { + Ipp32u a1 = (Ipp32u)(-AA); + carry = cpMulDgt_BNU32(T, yBuffer, nsY, (Ipp32u)BB); + carry = cpMulDgt_BNU32(u, xBuffer, nsY, a1); + /* T = BB*y - AA*x; */ + carry = cpSub_BNU32(T, T, u, nsY); + } + else { + if((AA >= 0)&&(BB<=0)) { + Ipp32u b1 = (Ipp32u)(-BB); + carry = cpMulDgt_BNU32(T, xBuffer, nsY, (Ipp32u)AA); + carry = cpMulDgt_BNU32(u, yBuffer, nsY, b1); + /* T = AA*x - BB*y; */ + carry = cpSub_BNU32(T, T, u, nsY); + } + else { + /*AA*BB>=0 */ + carry = cpMulDgt_BNU32(T, xBuffer, nsY, (Ipp32u)AA); + carry = cpMulDgt_BNU32(u, yBuffer, nsY, (Ipp32u)BB); + /* T = AA*x + BB*y; */ + carry = cpAdd_BNU32(T, T, u, nsY); + } + } + + /* Now T is reserved. We use only u for intermediate results. */ + if((CC <= 0)&&(DD>=0)){ + Ipp32u c1 = (Ipp32u)(-CC); + /* u = x*CC; x = u; */ + carry = cpMulDgt_BNU32(u, xBuffer, nsY, c1); + COPY_BNU(xBuffer, u, nsY); + /* u = y*DD; */ + carry = cpMulDgt_BNU32(u, yBuffer, nsY, (Ipp32u)DD); + /* u = DD*y - CC*x; */ + carry = cpSub_BNU32(u, u, xBuffer, nsY); + } + else { + if((CC >= 0)&&(DD<=0)){ + Ipp32u d1 = (Ipp32u)(-DD); + /* u = y*DD; y = u */ + carry = cpMulDgt_BNU32(u, yBuffer, nsY, d1); + COPY_BNU(yBuffer, u, nsY); + /* u = CC*x; */ + carry = cpMulDgt_BNU32(u, xBuffer, nsY, (Ipp32u)CC); + /* u = CC*x - DD*y; */ + carry = cpSub_BNU32(u, u, yBuffer, nsY); + } + else { + /*CC*DD>=0 */ + /* y = y*DD */ + carry = cpMulDgt_BNU32(u, yBuffer, nsY, (Ipp32u)DD); + COPY_BNU(yBuffer, u, nsY); + /* u = x*CC */ + carry = cpMulDgt_BNU32(u, xBuffer, nsY, (Ipp32u)CC); + /* u = x*CC + y*DD */ + carry = cpAdd_BNU32(u, u, yBuffer, nsY); + } + } + + IPP_UNREFERENCED_PARAMETER(carry); + + /* y = u; x = T; */ + COPY_BNU(yBuffer, u, nsY); + COPY_BNU(xBuffer, T, nsY); + } + + FIX_BNU32(xBuffer, nsX); + FIX_BNU32(yBuffer, nsY); + + if (nsY > nsX) { + SWAP_PTR(IppsBigNumState, x, y); + SWAP(nsX, nsY); + } + + if (nsY==1 && yBuffer[nsY-1]==0) { + /* End evaluation */ + ZEXPAND_BNU(gData, 0, nsGmax); + COPY_BNU(gData, xBuffer, nsX); + BN_SIZE(g) = INTERNAL_BNU_LENGTH(nsX); + BN_SIGN(g) = ippBigNumPOS; + return ippStsNoErr; + } + } + + BN_NUMBER(g)[0] = cpGcd_BNU(((BNU_CHUNK_T*)xBuffer)[0], ((BNU_CHUNK_T*)yBuffer)[0]); + BN_SIZE(g) = 1; + BN_SIGN(g) = ippBigNumPOS; + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithmac.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithmac.c new file mode 100644 index 000000000..6fafc3753 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithmac.c @@ -0,0 +1,125 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMAC_BN_I() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsMAC_BN_I +// +// Purpose: Multiply and Accumulate BigNums. +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pB == NULL +// pR == NULL +// ippStsContextMatchErr !BN_VALID_ID(pA) +// !BN_VALID_ID(pB) +// !BN_VALID_ID(pR) +// ippStsOutOfRangeErr pR can not fit result +// ippStsNoErr no errors +// +// Parameters: +// pA source BigNum +// pB source BigNum +// pR resultant BigNum +// +*F*/ +IPPFUN(IppStatus, ippsMAC_BN_I, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +{ + IPP_BAD_PTR3_RET(pA, pB, pR); + + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pB), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + { + BNU_CHUNK_T* pDataA = BN_NUMBER(pA); + BNU_CHUNK_T* pDataB = BN_NUMBER(pB); + + cpSize nsA = BN_SIZE(pA); + cpSize nsB = BN_SIZE(pB); + + cpSize bitSizeA = BITSIZE_BNU(pDataA, nsA); + cpSize bitSizeB = BITSIZE_BNU(pDataB, nsB); + /* size of temporary pruduct */ + cpSize nsP = BITS_BNU_CHUNK(bitSizeA+bitSizeB); + + /* test if multiplicant/multiplier is zero */ + if(!bitSizeA || !bitSizeB) return ippStsNoErr; + /* test if product can't fit to the result */ + IPP_BADARG_RET(BN_ROOM(pR)cmpRes) { + SWAP_PTR(BNU_CHUNK_T, pTmp, pDataP); + } + cpSub_BNU(pDataR, pTmp, pDataP, room); + + BN_SIGN(pR) = cmpRes>0? sgnR : INVERSE_SIGN(sgnR); + } + + FIX_BNU(pDataR, room); + BN_SIZE(pR) = room; + + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithminv.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithminv.c new file mode 100644 index 000000000..4bc4038af --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithminv.c @@ -0,0 +1,84 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsModInv_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsModInv_BN +// +// Purpose: Multiplicative Inversion BigNum. +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pM == NULL +// pInv == NULL +// ippStsContextMatchErr !BN_VALID_ID(pA) +// !BN_VALID_ID(pM) +// !BN_VALID_ID(pInv) +// ippStsBadArgErr A<=0 +// ippStsBadModulusErr M<=0 +// ippStsScaleRangeErr A>=M +// ippStsOutOfRangeErr pInv can not hold result +// ippStsNoErr no errors +// ippStsBadModulusErr inversion not found +// +// Parameters: +// pA source (value) BigNum +// pM source (modulus) BigNum +// pInv result BigNum +// +*F*/ +IPPFUN(IppStatus, ippsModInv_BN, (IppsBigNumState* pA, IppsBigNumState* pM, IppsBigNumState* pInv) ) +{ + IPP_BAD_PTR3_RET(pA, pM, pInv); + + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pM), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pInv), ippStsContextMatchErr); + + IPP_BADARG_RET(BN_ROOM(pInv) < BN_SIZE(pM), ippStsOutOfRangeErr); + IPP_BADARG_RET(BN_NEGATIVE(pA) || (BN_SIZE(pA)==1 && BN_NUMBER(pA)[0]==0), ippStsBadArgErr); + IPP_BADARG_RET(BN_NEGATIVE(pM) || (BN_SIZE(pM)==1 && BN_NUMBER(pM)[0]==0), ippStsBadModulusErr); + IPP_BADARG_RET(cpCmp_BNU(BN_NUMBER(pA), BN_SIZE(pA), BN_NUMBER(pM), BN_SIZE(pM)) >= 0, ippStsScaleRangeErr); + + { + cpSize nsR = cpModInv_BNU(BN_NUMBER(pInv), + BN_NUMBER(pA), BN_SIZE(pA), + BN_NUMBER(pM), BN_SIZE(pM), + BN_BUFFER(pInv), BN_BUFFER(pA), BN_BUFFER(pM)); + if(nsR) { + BN_SIGN(pInv) = ippBigNumPOS; + BN_SIZE(pInv) = nsR; + return ippStsNoErr; + } + else + return ippStsBadModulusErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithmod.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithmod.c new file mode 100644 index 000000000..76e88b51c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithmod.c @@ -0,0 +1,101 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMod_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsMod_BN +// +// Purpose: reduction BigNum. +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pM == NULL +// pR == NULL +// ippStsContextMatchErr !BN_VALID_ID(pA) +// !BN_VALID_ID(pM) +// !BN_VALID_ID(pR) +// ippStsOutOfRangeErr pR can not hold result +// ippStsBadModulusErr modulus IppsBigNumState* pM +// is not a positive integer +// ippStsNoErr no errors +// +// Parameters: +// pA source BigNum +// pB source BigNum +// pR reminder BigNum +// +// A = Q*M + R, 0 <= R < B +// +*F*/ +IPPFUN(IppStatus, ippsMod_BN, (IppsBigNumState* pA, IppsBigNumState* pM, IppsBigNumState* pR)) +{ + IPP_BAD_PTR3_RET(pA, pM, pR); + + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pM), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + IPP_BADARG_RET(BN_NEGATIVE(pM), ippStsBadModulusErr); + IPP_BADARG_RET(BN_SIZE(pM)== 1 && BN_NUMBER(pM)[0]==0, ippStsBadModulusErr); + + IPP_BADARG_RET(BN_ROOM(pR)BN_ROOM(pR), ippStsOutOfRangeErr); + + BN_SIZE(pR) = nsR; + BN_SIGN(pR) = (BN_SIGN(pA)==BN_SIGN(pB)? ippBigNumPOS : ippBigNumNEG); + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnarithsub.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithsub.c new file mode 100644 index 000000000..5b1a2e60b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnarithsub.c @@ -0,0 +1,124 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsSub_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsSub_BN +// +// Purpose: Subtract BigNums. +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pB == NULL +// pR == NULL +// ippStsContextMatchErr !BN_VALID_ID(pA) +// !BN_VALID_ID(pB) +// !BN_VALID_ID(pR) +// ippStsOutOfRangeErr pR can not hold result +// ippStsNoErr no errors +// +// Parameters: +// pA source BigNum +// pB source BigNum +// pR resultant BigNum +// +*F*/ +IPPFUN(IppStatus, ippsSub_BN, (IppsBigNumState* pA, IppsBigNumState* pB, IppsBigNumState* pR)) +{ + IPP_BAD_PTR3_RET(pA, pB, pR); + + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pB), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + { + cpSize nsA = BN_SIZE(pA); + cpSize nsB = BN_SIZE(pB); + cpSize nsR = BN_ROOM(pR); + IPP_BADARG_RET(nsR < IPP_MAX(nsA, nsB), ippStsOutOfRangeErr); + + { + BNU_CHUNK_T* pDataR = BN_NUMBER(pR); + + IppsBigNumSGN sgnA = BN_SIGN(pA); + IppsBigNumSGN sgnB = BN_SIGN(pB); + BNU_CHUNK_T* pDataA = BN_NUMBER(pA); + BNU_CHUNK_T* pDataB = BN_NUMBER(pB); + + BNU_CHUNK_T carry; + + if(sgnA!=sgnB) { + if(nsA < nsB) { + SWAP(nsA, nsB); + SWAP_PTR(BNU_CHUNK_T, pDataA, pDataB); + } + + carry = cpAdd_BNU(pDataR, pDataA, pDataB, nsB); + if(nsA>nsB) + carry = cpInc_BNU(pDataR+nsB, pDataA+nsB, nsA-nsB, carry); + if(carry) { + if(nsR > nsA) + pDataR[nsA++] = carry; + else + IPP_ERROR_RET(ippStsOutOfRangeErr); + } + BN_SIGN(pR) = sgnA; + } + + else { + int cmpRes= cpCmp_BNU(pDataA, nsA, pDataB, nsB); + + if(0==cmpRes) { + ZEXPAND_BNU(pDataR,0, nsR); + BN_SIZE(pR) = 1; + BN_SIGN(pR) = ippBigNumPOS; + return ippStsNoErr; + } + + if(0>cmpRes) { + SWAP(nsA, nsB); + SWAP_PTR(BNU_CHUNK_T, pDataA, pDataB); + } + + carry = cpSub_BNU(pDataR, pDataA, pDataB, nsB); + if(nsA>nsB) + cpDec_BNU(pDataR+nsB, pDataA+nsB, nsA-nsB, carry); + + BN_SIGN(pR) = cmpRes>0? sgnA : INVERSE_SIGN(sgnA); + } + + FIX_BNU(pDataR, nsA); + BN_SIZE(pR) = nsA; + + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbngetext.c b/plugin/ippcp/library/src/sources/ippcp/pcpbngetext.c new file mode 100644 index 000000000..075dd0d16 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbngetext.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsExtGet_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + +/*F* +// Name: ippsExtGet_BN +// +// Purpose: Extracts the specified combination of the sign, data +// length, and value characteristics of the integer big +// number from the input structure. +// +// Returns: Reason: +// ippStsNullPtrErr pBN == NULL +// ippStsContextMatchErr !BN_VALID_ID(pBN) +// ippStsNoErr no errors +// +// Parameters: +// pSgn pointer to the sign +// pBitSize pointer to the data size (in bits) +// pData pointer to the data buffer +// pBN BigNum ctx +// +*F*/ + +IPPFUN(IppStatus, ippsExtGet_BN, (IppsBigNumSGN* pSgn, int* pBitSize, Ipp32u* pData, + const IppsBigNumState* pBN)) +{ + IPP_BAD_PTR1_RET(pBN); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + + { + cpSize bitSize = BITSIZE_BNU(BN_NUMBER(pBN), BN_SIZE(pBN)); + if(0==bitSize) + bitSize = 1; + if(pData) + COPY_BNU(pData, (Ipp32u*)BN_NUMBER(pBN), BITS2WORD32_SIZE(bitSize)); + if(pSgn) + *pSgn = BN_SIGN(pBN); + if(pBitSize) + *pBitSize = bitSize; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbngetlen.c b/plugin/ippcp/library/src/sources/ippcp/pcpbngetlen.c new file mode 100644 index 000000000..e3ab59e68 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbngetlen.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsGetSize_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGetSize_BN +// +// Purpose: Returns BigNum room. +// +// Returns: Reason: +// ippStsNullPtrErr pBN == NULL +// pSize == NULL +// ippStsContextMatchErr !BN_VALID_ID(pBN) +// ippStsNoErr no errors +// +// Parameters: +// pBN BigNum ctx +// pSize max BigNum length (in Ipp32u chunks) +// +*F*/ +IPPFUN(IppStatus, ippsGetSize_BN, (const IppsBigNumState* pBN, int* pSize)) +{ + IPP_BAD_PTR2_RET(pBN, pSize); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + + *pSize = BN_ROOM(pBN)*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbngetoctstr.c b/plugin/ippcp/library/src/sources/ippcp/pcpbngetoctstr.c new file mode 100644 index 000000000..c96927fbc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbngetoctstr.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Big Number Operations +// +// Contents: +// ippsGetOctString_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" + + +/*F* +// Name: ippsGetOctString_BN +// +// Purpose: Convert BN value into the octet string. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pOctStr +// NULL == pBN +// +// ippStsContextMatchErr !BN_VALID_ID(pBN) +// +// ippStsRangeErr BN <0 +// +// ippStsLengthErr strLen is enough for keep BN value +// +// ippStsNoErr no errors +// +// Parameters: +// pBN pointer to the source BN +// pOctStr pointer to the target octet string +// strLen octet string length +*F*/ +IPPFUN(IppStatus, ippsGetOctString_BN,(Ipp8u* pOctStr, int strLen, + const IppsBigNumState* pBN)) +{ + IPP_BAD_PTR2_RET(pOctStr, pBN); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pBN), ippStsRangeErr); + IPP_BADARG_RET((0>strLen), ippStsLengthErr); + + return cpToOctStr_BNU(pOctStr,strLen, BN_NUMBER(pBN),BN_SIZE(pBN))? ippStsNoErr : ippStsLengthErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbngetref.c b/plugin/ippcp/library/src/sources/ippcp/pcpbngetref.c new file mode 100644 index 000000000..ddb44f784 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbngetref.c @@ -0,0 +1,90 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsBigNumGetSize() +// ippsBigNumInit() +// +// ippsSet_BN() +// ippsGet_BN() +// ippsGetSize_BN() +// ippsExtGet_BN() +// ippsRef_BN() +// +// ippsCmpZero_BN() +// ippsCmp_BN() +// +// ippsAdd_BN() +// ippsSub_BN() +// ippsMul_BN() +// ippsMAC_BN_I() +// ippsDiv_BN() +// ippsMod_BN() +// ippsGcd_BN() +// ippsModInv_BN() +// +// cpPackBigNumCtx(), cpUnpackBigNumCtx() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsRef_BN +// +// Purpose: Get BigNum info. +// +// Returns: Reason: +// ippStsNullPtrErr pBN == NULL +// ippStsContextMatchErr !BN_VALID_ID(pBN) +// ippStsNoErr no errors +// +// Parameters: +// pSgn pointer to the sign +// pBitSize pointer to the data size (in bits) +// ppData pointer to the data buffer +// pBN BigNum ctx +// +*F*/ +IPPFUN(IppStatus, ippsRef_BN, (IppsBigNumSGN* pSgn, int* pBitSize, Ipp32u** const ppData, + const IppsBigNumState *pBN)) +{ + IPP_BAD_PTR1_RET(pBN); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + + if(pSgn) + *pSgn = BN_SIGN(pBN); + if(pBitSize) { + cpSize bitLen = BITSIZE_BNU(BN_NUMBER(pBN), BN_SIZE(pBN)); + *pBitSize = bitLen? bitLen : 1; + } + + if(ppData) + *ppData = (Ipp32u*)BN_NUMBER(pBN); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbngetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpbngetsize.c new file mode 100644 index 000000000..ae07e9ae7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbngetsize.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsBigNumGetSize() +// ippsBigNumInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsBigNumGetSize +// +// Purpose: Returns size of BigNum ctx (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pCtxSize == NULL +// ippStsLengthErr length < 1 +// length > BITS2WORD32_SIZE(BN_MAXBITSIZE) +// ippStsNoErr no errors +// +// Parameters: +// length max BN length (32-bits segments) +// pSize pointer BigNum ctx size +// +*F*/ +IPPFUN(IppStatus, ippsBigNumGetSize, (int length, cpSize *pCtxSize)) +{ + IPP_BAD_PTR1_RET(pCtxSize); + IPP_BADARG_RET(length<1 || length>BITS2WORD32_SIZE(BN_MAXBITSIZE), ippStsLengthErr); + + { + /* convert length to the number of BNU_CHUNK_T */ + cpSize len = INTERNAL_BNU_LENGTH(length); + + /* reserve one BNU_CHUNK_T more for cpDiv_BNU, + mul, mont exp operations */ + len++; + + *pCtxSize = (Ipp32s)sizeof(IppsBigNumState) + + len*(Ipp32s)sizeof(BNU_CHUNK_T) + + len*(Ipp32s)sizeof(BNU_CHUNK_T) + + BN_ALIGNMENT-1; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbngetwords.c b/plugin/ippcp/library/src/sources/ippcp/pcpbngetwords.c new file mode 100644 index 000000000..b6654662a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbngetwords.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsGet_BN() +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGet_BN +// +// Purpose: Get BigNum. +// +// Returns: Reason: +// ippStsNullPtrErr pBN == NULL +// pData == NULL +// pSgn == NULL +// pLengthInBits ==NULL +// ippStsContextMatchErr !BN_VALID_ID(pBN) +// ippStsNoErr no errors +// +// Parameters: +// pSgn pointer to the sign +// pLengthInBits pointer to the data size (in Ipp32u chunks) +// pData pointer to the data buffer +// pBN BigNum ctx +// +*F*/ +IPPFUN(IppStatus, ippsGet_BN, (IppsBigNumSGN* pSgn, int* pLengthInBits, Ipp32u* pData, + const IppsBigNumState* pBN)) +{ + IPP_BAD_PTR4_RET(pSgn, pLengthInBits, pData, pBN); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + + { + cpSize len32 = BN_SIZE(pBN)*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)); + Ipp32u* bnData = (Ipp32u*)BN_NUMBER(pBN); + + FIX_BNU32(bnData, len32); + COPY_BNU(pData, bnData, len32); + + *pSgn = BN_SIGN(pBN); + *pLengthInBits = len32; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbninit.c b/plugin/ippcp/library/src/sources/ippcp/pcpbninit.c new file mode 100644 index 000000000..2d7185b3b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbninit.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsBigNumGetSize() +// ippsBigNumInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + +/*F* +// Name: ippsBigNumInit +// +// Purpose: Init BigNum spec for future usage. +// +// Returns: Reason: +// ippStsNullPtrErr pBN == NULL +// ippStsLengthErr length<1 +// length > BITS2WORD32_SIZE(BN_MAXBITSIZE) +// ippStsNoErr no errors +// +// Parameters: +// length max BN length (32-bits segments) +// pBN BigNum ctx +// +*F*/ +IPPFUN(IppStatus, ippsBigNumInit, (int length, IppsBigNumState* pBN)) +{ + IPP_BADARG_RET(length<1 || length>BITS2WORD32_SIZE(BN_MAXBITSIZE), ippStsLengthErr); + IPP_BAD_PTR1_RET(pBN); + + { + Ipp8u* ptr = (Ipp8u*)pBN; + + /* convert length to the number of BNU_CHUNK_T */ + cpSize len = INTERNAL_BNU_LENGTH(length); + + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = 1; /* initial valie is zero */ + BN_ROOM(pBN) = len; /* close to what has been passed by user */ + + /* reserve one BNU_CHUNK_T more for cpDiv_BNU, + mul, mont exp operations */ + len++; + + ptr += sizeof(IppsBigNumState); + + /* allocate buffers */ + ptr = (Ipp8u*)(IPP_ALIGNED_PTR(ptr, BN_ALIGNMENT)); + BN_NUMBER(pBN) = (BNU_CHUNK_T*)ptr; + ptr += len * (Ipp32s)sizeof(BNU_CHUNK_T); + BN_BUFFER(pBN) = (BNU_CHUNK_T*)(ptr); /* use expanded length here */ + + /* set BN value and buffer to zero */ + ZEXPAND_BNU(BN_NUMBER(pBN), 0, len); + ZEXPAND_BNU(BN_BUFFER(pBN), 0, len); + + BN_SET_ID(pBN); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnresource.h b/plugin/ippcp/library/src/sources/ippcp/pcpbnresource.h new file mode 100644 index 000000000..5fa0e2125 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnresource.h @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal BN Resource Definitions & Function Prototypes +// +// +*/ + +#if !defined(_PCP_BNRESOURCE_H) +#define _PCP_BNRESOURCE_H + + +typedef struct { + void* pNext; + IppsBigNumState* pBN; +} BigNumNode; + + +/* size (byte) of BN resource */ +#define cpBigNumListGetSize OWNAPI(cpBigNumListGetSize) + IPP_OWN_DECL (int, cpBigNumListGetSize, (int feBitSize, int nodes)) + +/* init BN resource */ +#define cpBigNumListInit OWNAPI(cpBigNumListInit) + IPP_OWN_DECL (void, cpBigNumListInit, (int feBitSize, int nodes, BigNumNode* pList)) + +/* get BN from resource */ +#define cpBigNumListGet OWNAPI(cpBigNumListGet) + IPP_OWN_DECL (IppsBigNumState*, cpBigNumListGet, (BigNumNode** pList)) + +#endif /* _PCP_BNRESOURCE_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnresourceca.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnresourceca.c new file mode 100644 index 000000000..1f5202dd8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnresourceca.c @@ -0,0 +1,121 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal ECC (prime) Resource List Function +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbnresource.h" +#include "pcpbn.h" + + + +/*F* +// Name: cpBigNumListGetSize +// +// Purpose: Size of BigNum List Buffer +// +// Returns: +// Size of List Buffer +// +// Parameters: +// feBitSize size in bits +// nodes number of nodes +// +*F*/ + +IPP_OWN_DEFN (int, cpBigNumListGetSize, (int feBitSize, int nodes)) +{ + /* size of buffer per single big number */ + int bnSize; + ippsBigNumGetSize(BITS2WORD32_SIZE(feBitSize), &bnSize); + + /* size of buffer for whole list */ + return ((Ipp32s)sizeof(BigNumNode) + bnSize) * nodes; +} + +/*F* +// Name: cpBigNumListInit +// +// Purpose: Init list +// +// +// Parameters: +// feBitSize size in bit +// nodes number of nodes +// pList pointer to list +// +// Note: buffer for BN list must have appropriate alignment +// +*F*/ +IPP_OWN_DEFN (void, cpBigNumListInit, (int feBitSize, int nodes, BigNumNode* pList)) +{ + int itemSize; + /* length of Big Num */ + int bnLen = BITS2WORD32_SIZE(feBitSize); + /* size of buffer per single big number */ + ippsBigNumGetSize(bnLen, &itemSize); + /* size of list item */ + itemSize += sizeof(BigNumNode); + + { + int n; + /* init all nodes */ + BigNumNode* pNode = (BigNumNode*)( (Ipp8u*)pList + (nodes-1)*itemSize ); + BigNumNode* pNext = NULL; + for(n=0; npNext = pNext; + pNode->pBN = (IppsBigNumState*)(tbnPtr); + ippsBigNumInit(bnLen, pNode->pBN); + pNext = pNode; + pNode = (BigNumNode*)( (Ipp8u*)pNode - itemSize); + } + } +} + + +/*F* +// Name: cpBigNumListGet +// +// Purpose: Get BigNum reference +// +// Returns: +// BigNum reference +// +// Parameters: +// ppList pointer to pointer to List +// +*F*/ + +IPP_OWN_DEFN (IppsBigNumState*, cpBigNumListGet, (BigNumNode** ppList)) +{ + if(*ppList) { + IppsBigNumState* ret = (*ppList)->pBN; + *ppList = (*ppList)->pNext; + return ret; + } + else + return NULL; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnsetoctstr.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnsetoctstr.c new file mode 100644 index 000000000..8be4c1e22 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnsetoctstr.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Big Number Operations +// +// Contents: +// ippsSetOctString_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" + + +/*F* +// Name: ippsSetOctString_BN +// +// Purpose: Convert octet string into the BN value. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pOctStr +// NULL == pBN +// +// ippStsContextMatchErr !BN_VALID_ID(pBN) +// +// ippStsLengthErr 0 > strLen +// +// ippStsSizeErr BN_ROOM(pBN) is enough for keep actual strLen +// +// ippStsNoErr no errors +// +// Parameters: +// pOctStr pointer to the source octet string +// strLen octet string length +// pBN pointer to the target BN +// +*F*/ +IPPFUN(IppStatus, ippsSetOctString_BN,(const Ipp8u* pOctStr, int strLen, + IppsBigNumState* pBN)) +{ + IPP_BAD_PTR2_RET(pOctStr, pBN); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + + IPP_BADARG_RET((0>strLen), ippStsLengthErr); + + /* remove leading zeros */ + while(strLen && (0==pOctStr[0])) { + strLen--; + pOctStr++; + } + + /* test BN size */ + IPP_BADARG_RET((int)((Ipp32s)sizeof(BNU_CHUNK_T)*BN_ROOM(pBN)) BN_ROOM(pBN) +// ippStsNoErr no errors +// +// Parameters: +// sgn sign +// length data size (in Ipp32u chunks) +// pData source data pointer +// pBN BigNum ctx +// +*F*/ +IPPFUN(IppStatus, ippsSet_BN, (IppsBigNumSGN sgn, int length, const Ipp32u* pData, + IppsBigNumState* pBN)) +{ + IPP_BAD_PTR2_RET(pData, pBN); + + IPP_BADARG_RET(!BN_VALID_ID(pBN), ippStsContextMatchErr); + + IPP_BADARG_RET(length<1, ippStsLengthErr); + + /* compute real size */ + FIX_BNU32(pData, length); + + { + cpSize len = INTERNAL_BNU_LENGTH(length); + IPP_BADARG_RET(len > BN_ROOM(pBN), ippStsOutOfRangeErr); + + ZEXPAND_COPY_BNU((Ipp32u*)BN_NUMBER(pBN), BN_ROOM(pBN)*(int)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)), pData, length); + + BN_SIZE(pBN) = len; + + if(length==1 && pData[0] == 0) + sgn = ippBigNumPOS; /* consider zero value as positive */ + BN_SIGN(pBN) = sgn; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_add.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_add.c new file mode 100644 index 000000000..739192825 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_add.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal BNU32 arithmetic. +// +// Contents: +// cpAdd_BNU32() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnu32misc.h" +#include "pcpbnu32arith.h" + + +/*F* +// Name: cpSub_BNU32 +// +// Purpose: addition BNU32. +// +// Returns: +// carry +// +// Parameters: +// pA source +// pB source +// ns size +// pR result +// +*F*/ +IPP_OWN_DEFN (Ipp32u, cpAdd_BNU32, (Ipp32u* pR, const Ipp32u* pA, const Ipp32u* pB, cpSize ns)) +{ + Ipp32u carry = 0; + cpSize i; + for(i=0; i>(32-1); + } + return borrow; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_div.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_div.c new file mode 100644 index 000000000..59fdbc620 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_div.c @@ -0,0 +1,175 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal BNU32 arithmetic. +// +// Contents: +// cpDiv_BNU32() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnu32misc.h" +#include "pcpbnu32arith.h" + + +/*F* +// Name: cpDiv_BNU32 +// +// Purpose: BNU32 division. +// +// Returns: +// size of result +// +// Parameters: +// pX source X +// pY source Y +// pQ source quotient +// sizeQ pointer to max size of Q +// sizeX size of A +// sizeY size of B +// +*F*/ + +#if !((_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) +IPP_OWN_DEFN (int, cpDiv_BNU32, (Ipp32u* pQ, cpSize* sizeQ, Ipp32u* pX, cpSize sizeX, Ipp32u* pY, cpSize sizeY)) +{ + FIX_BNU32(pY,sizeY); + FIX_BNU32(pX,sizeX); + + /* special case */ + if(sizeX < sizeY) { + + if(pQ) { + pQ[0] = 0; + *sizeQ = 1; + } + + return sizeX; + } + + /* special case */ + if(1 == sizeY) { + int i; + Ipp32u r = 0; + for(i=(int)sizeX-1; i>=0; i--) { + Ipp64u tmp = IPP_MAKEDWORD(pX[i],r); + Ipp32u q = IPP_LODWORD(tmp / pY[0]); + r = IPP_LODWORD(tmp - q*pY[0]); + if(pQ) pQ[i] = q; + } + + pX[0] = r; + + if(pQ) { + FIX_BNU32(pQ,sizeX); + *sizeQ = sizeX; + } + + return 1; + } + + + /* common case */ + { + cpSize qs = sizeX-sizeY+1; + + cpSize nlz = cpNLZ_BNU32(pY[sizeY-1]); + + /* normalization */ + pX[sizeX] = 0; + if(nlz) { + cpSize ni; + + pX[sizeX] = pX[sizeX-1] >> (32-nlz); + for(ni=sizeX-1; ni>0; ni--) + pX[ni] = (pX[ni]<>(32-nlz)); + pX[0] <<= nlz; + + for(ni=sizeY-1; ni>0; ni--) + pY[ni] = (pY[ni]<>(32-nlz)); + pY[0] <<= nlz; + } + + /* + // division + */ + { + Ipp32u yHi = pY[sizeY-1]; + + int i; + for(i=(int)qs-1; i>=0; i--) { + Ipp32u extend; + + /* estimate digit of quotient */ + Ipp64u tmp = IPP_MAKEDWORD(pX[i+sizeY-1], pX[i+sizeY]); + Ipp64u q = tmp / yHi; + Ipp64u r = tmp - q*yHi; + + /* tune estimation above */ + //for(; (q>=CONST_64(0x100000000)) || (Ipp64u)q*pY[sizeY-2] > IPP_MAKEDWORD(pX[i+sizeY-2],r); ) { + for(; IPP_HIDWORD(q) || (Ipp64u)q*pY[sizeY-2] > IPP_MAKEDWORD(pX[i+sizeY-2],r); ) { + q -= 1; + r += yHi; + if( IPP_HIDWORD(r) ) + break; + } + + /* multiply and subtract */ + extend = cpSubMulDgt_BNU32(pX+i, pY, sizeY, (Ipp32u)q); + extend = (pX[i+sizeY] -= extend); + + if(extend) { /* subtracted too much */ + q -= 1; + extend = cpAdd_BNU32(pX+i, pY, pX+i, sizeY); + pX[i+sizeY] += extend; + } + + /* store quotation digit */ + if(pQ) pQ[i] = IPP_LODWORD(q); + } + } + + /* de-normalization */ + if(nlz) { + cpSize ni; + for(ni=0; ni>nlz) | (pX[ni+1]<<(32-nlz)); + for(ni=0; ni>nlz) | (pY[ni+1]<<(32-nlz)); + pY[sizeY-1] >>= nlz; + } + + FIX_BNU32(pX,sizeX); + + if(pQ) { + FIX_BNU32(pQ,qs); + *sizeQ = qs; + } + + return sizeX; + } +} +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_inc.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_inc.c new file mode 100644 index 000000000..c2a18db25 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_arith_inc.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal BNU32 arithmetic. +// +// Contents: +// cpInc_BNU32() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpbnu32misc.h" +#include "pcpbnu32arith.h" + + +/*F* +// Name: cpInc_BNU32 +// +// Purpose: BNU32 increment. +// +// Returns: +// carry +// +// Parameters: +// pA source +// pR result +// ns size +// v borrow +// +*F*/ +IPP_OWN_DEFN (Ipp32u, cpInc_BNU32, (Ipp32u* pR, const Ipp32u* pA, cpSize ns, Ipp32u v)) +{ + Ipp32u carry = v; + cpSize i; + for(i=0; i=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) +IPP_OWN_DEFN (Ipp32u, cpSubMulDgt_BNU32, (Ipp32u* pR, const Ipp32u* pA, cpSize nsA, Ipp32u val)) +{ + Ipp32u carry = 0; + for(; nsA>0; nsA--) { + Ipp64u r = (Ipp64u)*pR - (Ipp64u)(*pA++) * val - carry; + *pR++ = IPP_LODWORD(r); + carry = 0-IPP_HIDWORD(r); + } + return carry; +} +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_getoctstr.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_getoctstr.c new file mode 100644 index 000000000..03e4c83d9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_getoctstr.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Unsigned internal BNU32 misc functionality +// +// Contents: +// cpToOctStr_BNU32() +// +*/ + +#include "owncp.h" +#include "pcpbnuimpl.h" +#include "pcpbnumisc.h" +#include "pcpbnu32misc.h" + +/*F* +// Name: cpToOctStr_BNU32 +// +// Purpose: Convert BNU into HexString representation. +// +// Returns: +// length of the string or 0 if no success +// +// Parameters: +// pBNU pointer to the source BN +// bnuSize size of BN +// pStr pointer to the target octet string +// strLen octet string length +*F*/ + +IPP_OWN_DEFN (cpSize, cpToOctStr_BNU32, (Ipp8u* pStr, cpSize strLen, const Ipp32u* pBNU, cpSize bnuSize)) +{ + FIX_BNU32(pBNU, bnuSize); + { + int bnuBitSize = BITSIZE_BNU32(pBNU, bnuSize); + if(bnuBitSize <= strLen*BYTESIZE) { + Ipp32u x = pBNU[bnuSize-1]; + + ZEXPAND_BNU(pStr, 0, strLen); + pStr += strLen - BITS2WORD8_SIZE(bnuBitSize); + + if(x) { + int nb; + for(nb=cpNLZ_BNU32(x)/BYTESIZE; nb<4; nb++) + *pStr++ = EBYTE(x,3-nb); + + for(--bnuSize; bnuSize>0; bnuSize--) { + x = pBNU[bnuSize-1]; + *pStr++ = EBYTE(x,3); + *pStr++ = EBYTE(x,2); + *pStr++ = EBYTE(x,1); + *pStr++ = EBYTE(x,0); + } + } + return strLen; + } + else + return 0; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_nlz.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_nlz.c new file mode 100644 index 000000000..a14d3ac64 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_nlz.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Unsigned internal BNU32 misc functionality +// +// Contents: +// cpNLZ_BNU32() +// +*/ + +#include "owncp.h" +#include "pcpbnuimpl.h" +#include "pcpbnumisc.h" +#include "pcpbnu32misc.h" + +/*F* +// Name: cpNLZ_BNU32 +// +// Purpose: Returns number of leading zeros of the 32-bit BN chunk. +// +// Returns: +// number of leading zeros of the 32-bit BN chunk +// +// Parameters: +// x BigNum x +// +*F*/ + +#if (_IPP < _IPP_H9) + IPP_OWN_DEFN (cpSize, cpNLZ_BNU32, (Ipp32u x)) + { + cpSize nlz = BITSIZE(Ipp32u); + if(x) { + nlz = 0; + if( 0==(x & 0xFFFF0000) ) { nlz +=16; x<<=16; } + if( 0==(x & 0xFF000000) ) { nlz += 8; x<<= 8; } + if( 0==(x & 0xF0000000) ) { nlz += 4; x<<= 4; } + if( 0==(x & 0xC0000000) ) { nlz += 2; x<<= 2; } + if( 0==(x & 0x80000000) ) { nlz++; } + } + return nlz; + } +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_setoctstr.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_setoctstr.c new file mode 100644 index 000000000..629a34015 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32_setoctstr.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Unsigned internal BNU32 misc functionality +// +// Contents: +// cpToOctStr_BNU32() +// +*/ + +#include "owncp.h" +#include "pcpbnuimpl.h" +#include "pcpbnumisc.h" +#include "pcpbnu32misc.h" + +/*F* +// Name: cpFromOctStr_BNU32 +// +// Purpose: Convert Oct String into BNU representation. +// +// Returns: +// size of BNU in BNU_CHUNK_T chunks +// +// Parameters: +// pOctStr pointer to the source octet string +// strLen octet string length +// pBNU pointer to the target BN +// +*F*/ + +IPP_OWN_DEFN (cpSize, cpFromOctStr_BNU32, (Ipp32u* pBNU, const Ipp8u* pOctStr, cpSize strLen)) +{ + cpSize bnuSize=0; + *pBNU = 0; + + /* start from the end of string */ + for(; strLen>=4; bnuSize++,strLen-=4) { + /* pack 4 bytes into single Ipp32u value*/ + *pBNU++ = (Ipp32u)(( pOctStr[strLen-4]<<(8*3) ) + +( pOctStr[strLen-3]<<(8*2) ) + +( pOctStr[strLen-2]<<(8*1) ) + + pOctStr[strLen-1]); + } + + /* convert the beginning of the string */ + if(strLen) { + Ipp32u x; + for(x=0; strLen>0; strLen--) { + Ipp32u d = *pOctStr++; + x = x*256 + d; + } + *pBNU++ = x; + bnuSize++; + } + + return bnuSize? bnuSize : 1; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32arith.h b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32arith.h new file mode 100644 index 000000000..1118c9656 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32arith.h @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2012 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. +// Internal BNU32 arithmetic +// +// +*/ + +#if !defined(_CP_BNU32_ARITH_H) +#define _CP_BNU32_ARITH_H + +#define cpAdd_BNU32 OWNAPI(cpAdd_BNU32) + IPP_OWN_DECL (Ipp32u, cpAdd_BNU32, (Ipp32u* pR, const Ipp32u* pA, const Ipp32u* pB, int ns)) +#define cpSub_BNU32 OWNAPI(cpSub_BNU32) + IPP_OWN_DECL (Ipp32u, cpSub_BNU32, (Ipp32u* pR, const Ipp32u* pA, const Ipp32u* pB, int ns)) +#define cpInc_BNU32 OWNAPI(cpInc_BNU32) + IPP_OWN_DECL (Ipp32u, cpInc_BNU32, (Ipp32u* pR, const Ipp32u* pA, cpSize ns, Ipp32u val)) +#define cpDec_BNU32 OWNAPI(cpDec_BNU32) + IPP_OWN_DECL (Ipp32u, cpDec_BNU32, (Ipp32u* pR, const Ipp32u* pA, cpSize ns, Ipp32u val)) +#define cpMulDgt_BNU32 OWNAPI(cpMulDgt_BNU32) + IPP_OWN_DECL (Ipp32u, cpMulDgt_BNU32, (Ipp32u* pR, const Ipp32u* pA, int ns, Ipp32u val)) +#define cpSubMulDgt_BNU32 OWNAPI(cpSubMulDgt_BNU32) + IPP_OWN_DECL (Ipp32u, cpSubMulDgt_BNU32, (Ipp32u* pR, const Ipp32u* pA, int nsA, Ipp32u val)) + +#define cpDiv_BNU32 OWNAPI(cpDiv_BNU32) + IPP_OWN_DECL (int, cpDiv_BNU32, (Ipp32u* pQ, int* nsQ, Ipp32u* pX, int nsX, Ipp32u* pY, int nsY)) +#define cpMod_BNU32(pX,sizeX, pM,sizeM) cpDiv_BNU32(NULL,NULL, (pX),(sizeX), (pM),(sizeM)) + +#define cpFromOS_BNU32 OWNAPI(cpFromOS_BNU32) + IPP_OWN_DECL (int, cpFromOS_BNU32, (Ipp32u* pBNU, const Ipp8u* pOctStr, int strLen)) +#define cpToOS_BNU32 OWNAPI(cpToOS_BNU32) + IPP_OWN_DECL (int, cpToOS_BNU32, (Ipp8u* pStr, int strLen, const Ipp32u* pBNU, int bnuSize)) + +#endif /* _CP_BNU32_ARITH_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu32misc.h b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32misc.h new file mode 100644 index 000000000..e6a62c85e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu32misc.h @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal Miscellaneous BNU 32 bit Definitions & Function Prototypes +// +// +*/ + +#if !defined(_CP_BNU32_MISC_H) +#define _CP_BNU32_MISC_H + + +/* bit operations */ +#define BITSIZE_BNU32(p,ns) ((ns)*BNU_CHUNK_32BIT-cpNLZ_BNU32((p)[(ns)-1])) + +/* number of leading/trailing zeros */ +#if (_IPP < _IPP_H9) +#define cpNLZ_BNU32 OWNAPI(cpNLZ_BNU32) + IPP_OWN_DECL (cpSize, cpNLZ_BNU32, (Ipp32u x)) +#else + __INLINE cpSize cpNLZ_BNU32(Ipp32u x) + { + return (cpSize)_lzcnt_u32(x); + } +#endif + +/* Name: cpFix_BNU32 +// +// Purpose: fix up BNU. +// +// Returns: +// fixed nsA +// +// Parameters: +// pA BNU ptr +// nsA size of BNU +// +*/ +__INLINE int cpFix_BNU32(const Ipp32u* pA, int nsA) +{ + Ipp32u zscan = (Ipp32u)(-1); + int outLen = nsA; + for(; nsA>0; nsA--) { + zscan &= (Ipp32u)cpIsZero_ct((BNU_CHUNK_T)pA[nsA-1]); + outLen -= 1 & zscan; + } + return (int)((1 & zscan) | ((BNU_CHUNK_T)outLen & ~(BNU_CHUNK_T)zscan)); // change to scanz +} + +#define FIX_BNU32(src,srcLen) ((srcLen) = cpFix_BNU32((src), (srcLen))) + +/* most significant BNU bit */ +#if 0 +__INLINE int cpMSBit_BNU32(const Ipp32u* pA, cpSize nsA) +{ + FIX_BNU(pA, nsA); + return nsA*BITSIZE(Ipp32u) - cpNLZ_BNU32(pA[nsA-1]) -1; +} +#endif + +#if 0 +__INLINE int cpCmp_BNU32(const Ipp32u* pA, cpSize nsA, const Ipp32u* pB, cpSize nsB) +{ + if(nsA!=nsB) + return nsA>nsB? 1 : -1; + else { + BNU_CHUNK_T idx = 0; + for(; nsA>0; nsA--) + idx |= ~cpIsEqu_ct(pA[nsA-1], pB[nsA-1]) & cpIsZero_ct(idx) & (nsA-1); + return pA[idx] < pB[idx] ? -1 : (pA[idx] > pB[idx] ? 1 : 0); + } +} +#endif + +/* to/from oct string conversion */ +#define cpToOctStr_BNU32 OWNAPI(cpToOctStr_BNU32) + IPP_OWN_DECL (cpSize, cpToOctStr_BNU32, (Ipp8u* pStr, cpSize strLen, const Ipp32u* pBNU, cpSize bnuSize)) +#define cpFromOctStr_BNU32 OWNAPI(cpFromOctStr_BNU32) + IPP_OWN_DECL (cpSize, cpFromOctStr_BNU32, (Ipp32u* pBNU, const Ipp8u* pOctStr, cpSize strLen)) + +#endif /* _CP_BNU32_MISC_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu_arith_add.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_arith_add.c new file mode 100644 index 000000000..1ada073c0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_arith_add.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal Unsigned arithmetic +// +// Contents: +// cpAdd_BNU() +// +*/ + +#include "owncp.h" +#include "pcpbnuarith.h" +#include "pcpbnumisc.h" + + +/*F* +// Name: cpAdd_BNU +// +// Purpose: Addition of two BigNums. +// +// Returns: +// carry of result of add two BigNums. +// +// Parameters: +// pA source BigNum A +// pB source BigNum B +// pR resultant BigNum +// ns size of BigNums +*F*/ +#if !((_IPP==_IPP_W7) || \ + (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || \ + (_IPP==_IPP_P8) || \ + (_IPP>=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpAdd_BNU_) +IPP_OWN_DEFN (BNU_CHUNK_T, cpAdd_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, cpSize ns)) +{ + BNU_CHUNK_T carry = 0; + cpSize i; + for(i=0; i=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpAddMulDgt_BNU_) +IPP_OWN_DEFN (BNU_CHUNK_T, cpAddMulDgt_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val)) +{ + BNU_CHUNK_T extension = 0; + cpSize i; + for(i=0; i=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) + +IPP_OWN_DEFN (BNU_CHUNK_T, cpDec_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val)) +{ + cpSize i; + for(i=0; i b){ + gcd = a; + t = b; + } else { + t = a; + gcd = b; + } + + while (t != 0) { + r = gcd % t; + gcd = t; + t = r; + } + return gcd; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu_arith_inc.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_arith_inc.c new file mode 100644 index 000000000..5e30f3750 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_arith_inc.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal Unsigned arithmetic +// +// Contents: +// cpInc_BNU() +// +*/ + +#include "owncp.h" +#include "pcpbnuarith.h" +#include "pcpbnumisc.h" + + +/*F* +// Name: cpInc_BNU +// +// Purpose: increment BigNum. +// +// Returns: +// carry of result of inc BigNum. +// +// Parameters: +// pA source BigNum A +// pR resultant BigNum +// ns size of BigNum +// val carry +*F*/ +#if !((_IPP==_IPP_W7) || \ + (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || \ + (_IPP==_IPP_P8) || \ + (_IPP>=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpInc_BNU_) +IPP_OWN_DEFN (BNU_CHUNK_T, cpInc_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val)) +{ + cpSize i; + for(i=0; i=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpMulAdc_BNU_school_) +IPP_OWN_DEFN (BNU_CHUNK_T, cpMulAdc_BNU_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize nsA, const BNU_CHUNK_T* pB, cpSize nsB)) +{ + const BNU_CHUNK_T* pa = (BNU_CHUNK_T*)pA; + const BNU_CHUNK_T* pb = (BNU_CHUNK_T*)pB; + BNU_CHUNK_T* pr = (BNU_CHUNK_T*)pR; + + BNU_CHUNK_T extension = 0; + cpSize i, j; + + ZEXPAND_BNU(pr, 0, nsA+nsB); + + for(i=0; i=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpSqrAdc_BNU_school_) +IPP_OWN_DEFN (BNU_CHUNK_T, cpSqrAdc_BNU_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize nsA)) +{ + cpSize i; + + BNU_CHUNK_T extension; + BNU_CHUNK_T rH, rL; + + /* init result */ + pR[0] = 0; + for(i=1, extension=0; i=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpSub_BNU_) +IPP_OWN_DEFN (BNU_CHUNK_T, cpSub_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, cpSize ns)) +{ + BNU_CHUNK_T borrow = 0; + cpSize i; + for(i=0; i=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpSubMulDgt_BNU_) +BNU_CHUNK_T cpSubMulDgt_BNU(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val) +{ + BNU_CHUNK_T extension = 0; + cpSize i; + for(i=0; i0; cnvLen+=(Ipp32s)sizeof(BNU_CHUNK_T), nsA--) { + x = pA[nsA-1]; + #if (BNU_CHUNK_BITS==BNU_CHUNK_64BIT) + *pStr++ = EBYTE(x,7); + *pStr++ = EBYTE(x,6); + *pStr++ = EBYTE(x,5); + *pStr++ = EBYTE(x,4); + #endif + *pStr++ = EBYTE(x,3); + *pStr++ = EBYTE(x,2); + *pStr++ = EBYTE(x,1); + *pStr++ = EBYTE(x,0); + } + } + IPP_UNREFERENCED_PARAMETER(cnvLen); + + return strLen; + } + else + return 0; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu_lsr.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_lsr.c new file mode 100644 index 000000000..b9e9928f4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_lsr.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal Unsigned BNU misc functionality +// +// Contents: +// cpLSL_BNU() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" + + +/*F* +// Name: cpLSR_BNU +// +// Purpose: Logical shift right (including inplace). +// +// Returns: +// new length +// +// Parameters: +// pA BigNum A +// pR result BigNum +// nsA size of A +// nBits size of shift in bits +*F*/ + +IPP_OWN_DEFN (cpSize, cpLSR_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize nsA, cpSize nBits)) +{ + cpSize nw = nBits/BNU_CHUNK_BITS; + cpSize n; + + pA += nw; + nsA -= nw; + + nBits %= BNU_CHUNK_BITS; + if(nBits) { + BNU_CHUNK_T hi; + BNU_CHUNK_T lo = pA[0]; + + for(n=0; n<(nsA-1); n++) { + hi = pA[n+1]; + pR[n] = (lo>>nBits) | (hi<<(BNU_CHUNK_BITS-nBits)); + lo = hi; + } + pR[nsA-1] = (lo>>nBits); + } + else { + for(n=0; n= _IPP_H9) || (_IPP32E >= _IPP32E_L9)) +#if 0 + IPP_OWN_DEFN (cpSize, cpNLZ_BNU, (BNU_CHUNK_T x)) + { + cpSize nlz = BNU_CHUNK_BITS; + if(x) { + nlz = 0; + #if (BNU_CHUNK_BITS == BNU_CHUNK_64BIT) + if( 0==(x & 0xFFFFFFFF00000000) ) { nlz +=32; x<<=32; } + if( 0==(x & 0xFFFF000000000000) ) { nlz +=16; x<<=16; } + if( 0==(x & 0xFF00000000000000) ) { nlz += 8; x<<= 8; } + if( 0==(x & 0xF000000000000000) ) { nlz += 4; x<<= 4; } + if( 0==(x & 0xC000000000000000) ) { nlz += 2; x<<= 2; } + if( 0==(x & 0x8000000000000000) ) { nlz++; } + #else + if( 0==(x & 0xFFFF0000) ) { nlz +=16; x<<=16; } + if( 0==(x & 0xFF000000) ) { nlz += 8; x<<= 8; } + if( 0==(x & 0xF0000000) ) { nlz += 4; x<<= 4; } + if( 0==(x & 0xC0000000) ) { nlz += 2; x<<= 2; } + if( 0==(x & 0x80000000) ) { nlz++; } + #endif + } + return nlz; + } +#endif +/* cte version */ +IPP_OWN_DEFN (cpSize, cpNLZ_BNU, (BNU_CHUNK_T x)) +{ + cpSize nlz = 0; + BNU_CHUNK_T + #if (BNU_CHUNK_BITS == BNU_CHUNK_64BIT) + mask = cpIsZero_ct(x & 0xFFFFFFFF00000000); + nlz += 32 & mask; x = ((x<<32) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0xFFFF000000000000); + nlz += 16 & mask; x = ((x<<16) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0xFF00000000000000); + nlz += 8 & mask; x = ((x << 8) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0xF000000000000000); + nlz += 4 & mask; x = ((x << 4) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0xC000000000000000); + nlz += 2 & mask; x = ((x << 2) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0x8000000000000000); + nlz += 1 & mask; x = ((x << 1) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0x8000000000000000); + nlz += 1 & mask; +#else + mask = cpIsZero_ct(x & 0xFFFF0000); + nlz += 16 & mask; x = ((x << 16) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0xFF000000); + nlz += 8 & mask; x = ((x << 8) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0xF0000000); + nlz += 4 & mask; x = ((x << 4) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0xC0000000); + nlz += 2 & mask; x = ((x << 2) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0x80000000); + nlz += 1 & mask; x = ((x << 1) & mask) | (x & ~mask); + + mask = cpIsZero_ct(x & 0x80000000); + nlz += 1 & mask; +#endif + return nlz; +} + +#endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu_ntz.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_ntz.c new file mode 100644 index 000000000..ff4051877 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_ntz.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal Unsigned BNU misc functionality +// +// Contents: +// cpNTZ_BNU() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" + + +/*F* +// Name: cpNTZ_BNU +// +// Purpose: Returns number of trailing zeros of the BNU. +// +// Returns: +// number of trailing zeros of the BNU +// +// Parameters: +// x BigNum x +// +*F*/ + +IPP_OWN_DEFN (cpSize, cpNTZ_BNU, (BNU_CHUNK_T x)) +{ + cpSize ntz = BNU_CHUNK_BITS; + if(x) { + ntz = 0; + #if (BNU_CHUNK_BITS==BNU_CHUNK_64BIT) + if( 0==(x & 0x00000000FFFFFFFF) ) { ntz+=32; x>>=32; } + if( 0==(x & 0x000000000000FFFF) ) { ntz+=16; x>>=16; } + if( 0==(x & 0x00000000000000FF) ) { ntz+= 8; x>>= 8; } + if( 0==(x & 0x000000000000000F) ) { ntz+= 4; x>>= 4; } + if( 0==(x & 0x0000000000000003) ) { ntz+= 2; x>>= 2; } + if( 0==(x & 0x0000000000000001) ) { ntz++; } + #else + if( 0==(x & 0x0000FFFF) ) { ntz+=16; x>>=16; } + if( 0==(x & 0x000000FF) ) { ntz+= 8; x>>= 8; } + if( 0==(x & 0x0000000F) ) { ntz+= 4; x>>= 4; } + if( 0==(x & 0x00000003) ) { ntz+= 2; x>>= 2; } + if( 0==(x & 0x00000001) ) { ntz++; } + #endif + } + return ntz; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnu_setoctstr.c b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_setoctstr.c new file mode 100644 index 000000000..d0cefe656 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnu_setoctstr.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal Unsigned BNU misc functionality +// +// Contents: +// cpFromOctStr_BNU() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" + +/*F* +// Name: cpFromOctStr_BNU +// +// Purpose: Convert Oct String into BNU representation. +// +// Returns: +// size of BNU in BNU_CHUNK_T chunks +// +// Parameters: +// pStr pointer to the source octet string +// strLen octet string length +// pA pointer to the target BN +// +*F*/ + +IPP_OWN_DEFN (cpSize, cpFromOctStr_BNU, (BNU_CHUNK_T* pA, const Ipp8u* pStr, cpSize strLen)) +{ + int nsA =0; + + /* start from the end of string */ + for(; strLen>=(int)sizeof(BNU_CHUNK_T); nsA++,strLen-=(int)(sizeof(BNU_CHUNK_T))) { + /* pack sizeof(BNU_CHUNK_T) bytes into single BNU_CHUNK_T value*/ + *pA++ = + #if (BNU_CHUNK_BITS==BNU_CHUNK_64BIT) + +( (BNU_CHUNK_T)pStr[strLen-8]<<(8*7) ) + +( (BNU_CHUNK_T)pStr[strLen-7]<<(8*6) ) + +( (BNU_CHUNK_T)pStr[strLen-6]<<(8*5) ) + +( (BNU_CHUNK_T)pStr[strLen-5]<<(8*4) ) + #endif + +( (BNU_CHUNK_T)pStr[strLen-4]<<(8*3) ) + +( (BNU_CHUNK_T)pStr[strLen-3]<<(8*2) ) + +( (BNU_CHUNK_T)pStr[strLen-2]<<(8*1) ) + + (BNU_CHUNK_T)pStr[strLen-1]; + } + + /* convert the beginning of the string */ + if(strLen) { + BNU_CHUNK_T x = 0; + for(x=0; strLen>0; strLen--) { + BNU_CHUNK_T d = *pStr++; + x = (x<<8) + d; + } + *pA++ = x; + nsA++; + } + + return nsA; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnuarith.h b/plugin/ippcp/library/src/sources/ippcp/pcpbnuarith.h new file mode 100644 index 000000000..4a49f52d8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnuarith.h @@ -0,0 +1,189 @@ +/******************************************************************************* +* Copyright (C) 2012 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. +// Internal Unsigned internal arithmetic +// +// +*/ + +#if !defined(_CP_BNU_ARITH_H) +#define _CP_BNU_ARITH_H + +#include "pcpbnuimpl.h" +#include "pcpbnu32arith.h" + +#define cpAdd_BNU OWNAPI(cpAdd_BNU) + IPP_OWN_DECL (BNU_CHUNK_T, cpAdd_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, cpSize ns)) +#define cpSub_BNU OWNAPI(cpSub_BNU) + IPP_OWN_DECL (BNU_CHUNK_T, cpSub_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, cpSize ns)) +#define cpInc_BNU OWNAPI(cpInc_BNU) + IPP_OWN_DECL (BNU_CHUNK_T, cpInc_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val)) +#define cpDec_BNU OWNAPI(cpDec_BNU) + IPP_OWN_DECL (BNU_CHUNK_T, cpDec_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val)) +#define cpAddMulDgt_BNU OWNAPI(cpAddMulDgt_BNU) + IPP_OWN_DECL (BNU_CHUNK_T, cpAddMulDgt_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize ns, BNU_CHUNK_T val)) +#define cpMulAdc_BNU_school OWNAPI(cpMulAdc_BNU_school) + IPP_OWN_DECL (BNU_CHUNK_T, cpMulAdc_BNU_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize nsA, const BNU_CHUNK_T* pB, cpSize nsB)) +#define cpMulAdx_BNU_school OWNAPI(cpMulAdx_BNU_school) + IPP_OWN_DECL (BNU_CHUNK_T, cpMulAdx_BNU_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize nsA, const BNU_CHUNK_T* pB, cpSize nsB)) + +/*F* +// Name: cpMul_BNU_school +// +// Purpose: Multiply 2 BigNums. +// +// Returns: +// extension of result of multiply 2 BigNums +// +// Parameters: +// pA source BigNum A +// nsA size of A +// pB source BigNum B +// nsB size of B +// pR resultant BigNum +// +*F*/ + +__INLINE BNU_CHUNK_T cpMul_BNU_school(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, cpSize nsA, + const BNU_CHUNK_T* pB, cpSize nsB) +{ +#if(_ADCOX_NI_ENABLING_==_FEATURE_ON_) + return cpMulAdx_BNU_school(pR, pA,nsA, pB,nsB); +#elif(_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_) + return IsFeatureEnabled(ippCPUID_ADCOX)? cpMulAdx_BNU_school(pR, pA,nsA, pB,nsB) + : cpMulAdc_BNU_school(pR, pA,nsA, pB,nsB); +#else + return cpMulAdc_BNU_school(pR, pA,nsA, pB,nsB); +#endif +} + + +#define cpSqrAdc_BNU_school OWNAPI(cpSqrAdc_BNU_school) + IPP_OWN_DECL (BNU_CHUNK_T, cpSqrAdc_BNU_school, (BNU_CHUNK_T * pR, const BNU_CHUNK_T * pA, cpSize nsA)) +#define cpSqrAdx_BNU_school OWNAPI(cpSqrAdx_BNU_school) + IPP_OWN_DECL (BNU_CHUNK_T, cpSqrAdx_BNU_school, (BNU_CHUNK_T * pR, const BNU_CHUNK_T * pA, cpSize nsA)) + +/*F* +// Name: cpSqr_BNU_school +// +// Purpose: Square BigNum. +// +// Returns: +// extension of result of square BigNum +// +// Parameters: +// pA source BigNum +// pR resultant BigNum +// +*F*/ + +__INLINE BNU_CHUNK_T cpSqr_BNU_school(BNU_CHUNK_T * pR, const BNU_CHUNK_T * pA, cpSize nsA) +{ +#if(_ADCOX_NI_ENABLING_==_FEATURE_ON_) + return cpSqrAdx_BNU_school(pR, pA,nsA); +#elif(_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_) + return IsFeatureEnabled(ippCPUID_ADCOX)? cpSqrAdx_BNU_school(pR, pA,nsA) + : cpSqrAdc_BNU_school(pR, pA,nsA); +#else + return cpSqrAdc_BNU_school(pR, pA,nsA); +#endif +} + +#define cpGcd_BNU OWNAPI(cpGcd_BNU) + IPP_OWN_DECL (BNU_CHUNK_T, cpGcd_BNU, (BNU_CHUNK_T a, BNU_CHUNK_T b)) +#define cpModInv_BNU OWNAPI(cpModInv_BNU) + IPP_OWN_DECL (int, cpModInv_BNU, (BNU_CHUNK_T* pInv, const BNU_CHUNK_T* pA, cpSize nsA, const BNU_CHUNK_T* pM, cpSize nsM, BNU_CHUNK_T* bufInv, BNU_CHUNK_T* bufA, BNU_CHUNK_T* bufM)) + +/* +// multiplication/squaring wrappers +*/ +__INLINE BNU_CHUNK_T cpMul_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, cpSize nsA, + const BNU_CHUNK_T* pB, cpSize nsB, + BNU_CHUNK_T* pBuffer) +{ + IPP_UNREFERENCED_PARAMETER(pBuffer); + return cpMul_BNU_school(pR, pA,nsA, pB,nsB); +} +__INLINE BNU_CHUNK_T cpSqr_BNU(BNU_CHUNK_T * pR, + const BNU_CHUNK_T * pA, cpSize nsA, + BNU_CHUNK_T* pBuffer) +{ + IPP_UNREFERENCED_PARAMETER(pBuffer); + return cpSqr_BNU_school(pR, pA,nsA); +} + +/*F* +// Name: cpDiv_BNU +// +// Purpose: division/reduction BigNums. +// +// Returns: +// size of result +// +// Parameters: +// pA source BigNum +// pB source BigNum +// pQ quotient BigNum +// pnsQ pointer to max size of Q +// nsA size of A +// nsB size of B +// +*F*/ + +__INLINE cpSize cpDiv_BNU(BNU_CHUNK_T* pQ, cpSize* pnsQ, BNU_CHUNK_T* pA, cpSize nsA, BNU_CHUNK_T* pB, cpSize nsB) +{ + int nsR = cpDiv_BNU32((Ipp32u*)pQ, pnsQ, + (Ipp32u*)pA, nsA*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)), + (Ipp32u*)pB, nsB*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))); + #if (BNU_CHUNK_BITS == BNU_CHUNK_64BIT) + if(nsR&1) ((Ipp32u*)pA)[nsR] = 0; + nsR = INTERNAL_BNU_LENGTH(nsR); + if(pQ) { + if(*pnsQ&1) ((Ipp32u*)pQ)[*pnsQ] = 0; + *pnsQ = INTERNAL_BNU_LENGTH(*pnsQ); + } + #endif + return nsR; +} + +/*F* +// Name: cpMod_BNU +// +// Purpose: reduction BigNums. +// +// Returns: +// cpDiv_BNU(NULL,NULL, pX,nsX, pModulus, nsM) +// +// Parameters: +// pX source BigNum +// pModulus source BigNum +// nsX size of X +// nsM size of Modulus +// +*F*/ + +__INLINE cpSize cpMod_BNU(BNU_CHUNK_T* pX, cpSize nsX, BNU_CHUNK_T* pModulus, cpSize nsM) +{ + return cpDiv_BNU(NULL,NULL, pX,nsX, pModulus, nsM); +} + +#endif /* _CP_BNU_ARITH_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnuimpl.h b/plugin/ippcp/library/src/sources/ippcp/pcpbnuimpl.h new file mode 100644 index 000000000..6c7d30c6c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnuimpl.h @@ -0,0 +1,133 @@ +/******************************************************************************* +* Copyright (C) 2012 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. +// BNU data type definition +// +// +// +*/ + +#if !defined(_CP_BNU_IMPL_H) +#define _CP_BNU_IMPL_H + +#define BNU_CHUNK_64BIT (64) +#define BNU_CHUNK_32BIT (32) + + +/* +// define BNU chunk data type +*/ +#if ((_IPP_ARCH == _IPP_ARCH_EM64T) || (_IPP_ARCH == _IPP_ARCH_LP64) || (_IPP_ARCH == _IPP_ARCH_LRB) || (_IPP_ARCH == _IPP_ARCH_LRB2)) + typedef Ipp64u BNU_CHUNK_T; + typedef Ipp64s BNS_CHUNK_T; + #define BNU_CHUNK_LOG2 (6) + #define BNU_CHUNK_BITS BNU_CHUNK_64BIT + +#else + typedef Ipp32u BNU_CHUNK_T; + typedef Ipp32s BNS_CHUNK_T; + #define BNU_CHUNK_LOG2 (5) + #define BNU_CHUNK_BITS BNU_CHUNK_32BIT +#endif + +#define BNU_CHUNK_MASK (~(BNU_CHUNK_T)(0)) + +#if (BNU_CHUNK_BITS != BNU_CHUNK_64BIT && BNU_CHUNK_BITS != BNU_CHUNK_32BIT) + #error BNU_CHUNK_BITS should be either 64 or 32 bit! +#endif + + +#ifdef _MSC_VER +// #pragma warning( disable : 4127 4711 4206) +# pragma warning( disable : 4127) +#endif + +/* user's API BNU chunk data type */ +typedef Ipp32u API_BNU_CHUNK_T; + +/* convert API_BNU_CHUNK_T (usual Ipp32u) length into the BNU_CHUNK_T length */ +#define INTERNAL_BNU_LENGTH(apiLen) \ + ((apiLen) + (Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(API_BNU_CHUNK_T)) -1)/((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(API_BNU_CHUNK_T))) + +/* Low and High parts of BNU_CHUNK_T value */ +#define BNU_CHUNK_2H ((BNU_CHUNK_T)1 << (BNU_CHUNK_BITS/2)) +#define LO_CHUNK(c) ((BNU_CHUNK_T)(c) & (BNU_CHUNK_2H - 1)) +#define HI_CHUNK(c) ((BNU_CHUNK_T)(c) >> (BNU_CHUNK_BITS/2)) + +/* (carry,R) = A+B */ +#define ADD_AB(CARRY,R, A,B) \ +do { \ + BNU_CHUNK_T __s = (A) + (B); \ + (CARRY) = __s < (A); \ + (R) = __s; \ +} while(0) + +/* (carry,R) = A+B+C */ +#define ADD_ABC(CARRY,R, A,B,C) \ +do { \ + BNU_CHUNK_T __s = (A) + (B); \ + BNU_CHUNK_T __t1= __s < (A); \ + BNU_CHUNK_T __r = __s + (C); \ + BNU_CHUNK_T __t2 = __r < __s; \ + (CARRY) = __t1 + __t2; \ + (R) = __r; \ +} while(0) + +/* (borrow,R) = A-B */ +#define SUB_AB(BORROW,R, A,B) \ +do { \ + (BORROW) = (A)<(B); \ + (R) = (A)-(B); \ +} while(0) + +/* (borrow,R) = A-B-C */ +#define SUB_ABC(BORROW,R, A,B,C) \ +do { \ + BNU_CHUNK_T __s = (A) -( B); \ + BNU_CHUNK_T __t1= __s > (A); \ + BNU_CHUNK_T __r = __s - (C); \ + BNU_CHUNK_T __t2 = __r > __s; \ + (BORROW) = __t1 + __t2; \ + (R) = __r; \ +} while(0) + +/* (RH,RL) = A*B */ +#define MUL_AB(RH, RL, A, B) \ + do { \ + BNU_CHUNK_T __aL = LO_CHUNK((A)); \ + BNU_CHUNK_T __aH = HI_CHUNK((A)); \ + BNU_CHUNK_T __bL = LO_CHUNK((B)); \ + BNU_CHUNK_T __bH = HI_CHUNK((B)); \ + \ + BNU_CHUNK_T __x0 = (BNU_CHUNK_T) __aL * __bL; \ + BNU_CHUNK_T __x1 = (BNU_CHUNK_T) __aL * __bH; \ + BNU_CHUNK_T __x2 = (BNU_CHUNK_T) __aH * __bL; \ + BNU_CHUNK_T __x3 = (BNU_CHUNK_T) __aH * __bH; \ + \ + __x1 += HI_CHUNK(__x0); \ + __x1 += __x2; \ + if(__x1 < __x2) \ + __x3 += BNU_CHUNK_2H; \ + \ + (RH) = __x3 + HI_CHUNK(__x1); \ + (RL) = (__x1 << BNU_CHUNK_BITS/2) + LO_CHUNK(__x0); \ + } while (0) + +#endif /* _CP_BNU_IMPL_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpbnumisc.h b/plugin/ippcp/library/src/sources/ippcp/pcpbnumisc.h new file mode 100644 index 000000000..3fb678856 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpbnumisc.h @@ -0,0 +1,239 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal Miscellaneous BNU Definitions & Function Prototypes +// +// +*/ + +#if !defined(_PCP_BNUMISC_H) +#define _PCP_BNUMISC_H + +#include "pcpbnuimpl.h" +#include "pcpmask_ct.h" + + +/* bit operations */ +#define BITSIZE_BNU(p,ns) ((ns)*BNU_CHUNK_BITS-cpNLZ_BNU((p)[(ns)-1])) +#define BIT_BNU(bnu, ns,nbit) ((((nbit)>>BNU_CHUNK_LOG2) < (ns))? ((((bnu))[(nbit)>>BNU_CHUNK_LOG2] >>((nbit)&(BNU_CHUNK_BITS))) &1) : 0) + +#define TST_BIT(bnu, nbit) (((Ipp8u*)(bnu))[(nbit)/8] & ((1<<((nbit)%8)) &0xFF)) +#define SET_BIT(bnu, nbit) (((Ipp8u*)(bnu))[(nbit)/8] |= ((1<<((nbit)%8)) &0xFF)) +#define CLR_BIT(bnu, nbit) (((Ipp8u*)(bnu))[(nbit)/8] &=~((1<<((nbit)%8)) &0xFF)) + +/* convert bitsize nbits into the number of BNU_CHUNK_T */ +#define BITS_BNU_CHUNK(nbits) (((nbits)+BNU_CHUNK_BITS-1)/BNU_CHUNK_BITS) + +/* mask for top BNU_CHUNK_T */ +#define MASK_BNU_CHUNK(nbits) ((BNU_CHUNK_T)(-1) >>((BNU_CHUNK_BITS- ((nbits)&(BNU_CHUNK_BITS-1))) &(BNU_CHUNK_BITS-1))) + +/* copy BNU content */ +#define COPY_BNU(dst, src, len) \ +{ \ + cpSize __idx; \ + for(__idx=0; __idx<(len); __idx++) (dst)[__idx] = (src)[__idx]; \ +} + +/* expand by zeros */ +#define ZEXPAND_BNU(srcdst,srcLen, dstLen) \ +{ \ + cpSize __idx; \ + for(__idx=(srcLen); __idx<(dstLen); __idx++) (srcdst)[__idx] = 0; \ +} + +/* copy and expand by zeros */ +#define ZEXPAND_COPY_BNU(dst,dstLen, src,srcLen) \ +{ \ + cpSize __idx; \ + for(__idx=0; __idx<(srcLen); __idx++) (dst)[__idx] = (src)[__idx]; \ + for(; __idx<(dstLen); __idx++) (dst)[__idx] = 0; \ +} + + +/* copy and set */ +__INLINE void cpCpy_BNU(BNU_CHUNK_T* pDst, const BNU_CHUNK_T* pSrc, cpSize ns) +{ COPY_BNU(pDst, pSrc, ns); } + +__INLINE void cpSet_BNU(BNU_CHUNK_T* pDst, cpSize ns, BNU_CHUNK_T val) +{ + ZEXPAND_BNU(pDst, 0, ns); + pDst[0] = val; +} + +/* fix up */ + +/* Name: cpFix_BNU +// +// Purpose: fix up BigNums. +// +// Returns: +// fixed nsA +// +// Parameters: +// pA BigNum ctx +// nsA Size of pA +// +*/ +__INLINE int cpFix_BNU(const BNU_CHUNK_T* pA, int nsA) +{ + BNU_CHUNK_T zscan = (BNU_CHUNK_T)(-1); + int outLen = nsA; + for(; nsA>0; nsA--) { + zscan &= cpIsZero_ct(pA[nsA-1]); + outLen -= 1 & zscan; + } + return (int)((1 & zscan) | ((BNU_CHUNK_T)outLen & ~zscan)); // change to scanz +} + +#define FIX_BNU(src,srcLen) ((srcLen) = cpFix_BNU((src), (srcLen))) + +/* Name: cpCmp_BNU +// +// Purpose: Compare two BigNums. +// +// Returns: +// negative, if A < B +// 0, if A = B +// positive, if A > B +// +// Parameters: +// pA BigNum ctx +// nsA Size of pA +// pB BigNum ctx +// nsB Size of pB +// +*/ +#if 0 +__INLINE int cpCmp_BNU(const BNU_CHUNK_T* pA, cpSize nsA, const BNU_CHUNK_T* pB, cpSize nsB) +{ + if(nsA!=nsB) + return nsA>nsB? 1 : -1; + else { + BNU_CHUNK_T idx = 0; + for(; nsA>0; nsA--) + idx |= ~cpIsEqu_ct(pA[nsA-1], pB[nsA-1]) & cpIsZero_ct(idx) & (BNU_CHUNK_T)(nsA-1); + return pA[idx] < pB[idx] ? -1 : (pA[idx] > pB[idx] ? 1 : 0); + } +} +#endif + +__INLINE int cpCmp_BNU0(const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, int len) +{ + const Ipp32u* a32 = (const Ipp32u*)a; + const Ipp32u* b32 = (const Ipp32u*)b; + len *= (sizeof(BNU_CHUNK_T))/sizeof(Ipp32u); + + // borrow, difference |= (a[]-b[]) + BNU_CHUNK_T borrow = 0; + BNU_CHUNK_T difference = 0; + for(int n=0; n>63); + } + + int resb = (int)( cpIsEqu_ct(borrow, 1) ); + int resd = (int)(~cpIsZero_ct(difference) ) &1; + return (int)(resb|resd); +} + +__INLINE int cpCmp_BNU(const BNU_CHUNK_T* a, int aLen, const BNU_CHUNK_T* b, int bLen) +{ + BNU_CHUNK_T aLen_eq_bLen = cpIsZero_ct((BNU_CHUNK_T)(aLen-bLen)); // FFFF/0000 if (aLen=bLen) / (aLen!=bLen) + BNU_CHUNK_T aLen_gt_bLen = cpIsMsb_ct((BNU_CHUNK_T)(bLen-aLen)) & 1; // 1/0 if (aLen>bLen) / (aLenbLen) + + + int len = (int)(((Ipp32u)aLen & aLen_lt_bLen) | ((Ipp32u)bLen & ~aLen_lt_bLen)); + int cmp_res = cpCmp_BNU0(a, b, len); + + return (int)( aLen_gt_bLen | (aLen_eq_bLen & (Ipp32u)cmp_res) | aLen_lt_bLen ); +} + +/* Name: cpEqu_BNU_CHUNK +// +// Purpose: Compare two BNU_CHUNKs. +// +// Returns: +// positive, if A = b +// 0 , if A != b +// +// Parameters: +// pA BigNum ctx +// nsA Size of pA +// b BNU_CHUNK_T to compare +// +*/ +__INLINE int cpEqu_BNU_CHUNK(const BNU_CHUNK_T* pA, cpSize nsA, BNU_CHUNK_T b) +{ + BNU_CHUNK_T res = pA[0] ^ b; + int n; + for(n=1; n0, if A > 0 +// <0, looks like impossible (or error) case +*/ +__INLINE int cpTst_BNU(const BNU_CHUNK_T* pA, int nsA) +{ + for(; (nsA>0) && (0==pA[nsA-1]); nsA--) ; + return nsA; +} + +/* number of leading/trailing zeros */ +#if !((_IPP >= _IPP_H9) || (_IPP32E >= _IPP32E_L9)) +#define cpNLZ_BNU OWNAPI(cpNLZ_BNU) + IPP_OWN_DECL (cpSize, cpNLZ_BNU, (BNU_CHUNK_T x)) +#else + __INLINE cpSize cpNLZ_BNU(BNU_CHUNK_T x) + { + #if (BNU_CHUNK_BITS == BNU_CHUNK_64BIT) + return (cpSize)_lzcnt_u64(x); + #else + return (cpSize)_lzcnt_u32(x); + #endif + } +#endif + +#define cpNTZ_BNU OWNAPI(cpNTZ_BNU) + IPP_OWN_DECL (cpSize, cpNTZ_BNU, (BNU_CHUNK_T x)) + +/* logical shift left/right */ +#define cpLSR_BNU OWNAPI(cpLSR_BNU) + IPP_OWN_DECL (int, cpLSR_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, cpSize nsA, cpSize nBits)) + +/* most significant BNU bit */ +#define cpMSBit_BNU OWNAPI(cpMSBit_BNU) + IPP_OWN_DECL (int, cpMSBit_BNU, (const BNU_CHUNK_T* pA, cpSize nsA)) + +/* BNU <-> hex-string conversion */ +#define cpToOctStr_BNU OWNAPI(cpToOctStr_BNU) + IPP_OWN_DECL (int, cpToOctStr_BNU, (Ipp8u* pStr, cpSize strLen, const BNU_CHUNK_T* pA, cpSize nsA)) +#define cpFromOctStr_BNU OWNAPI(cpFromOctStr_BNU) + IPP_OWN_DECL (int, cpFromOctStr_BNU, (BNU_CHUNK_T* pA, const Ipp8u* pStr, cpSize strLen)) + +#endif /* _PCP_BNUMISC_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpcmac.h b/plugin/ippcp/library/src/sources/ippcp/pcpcmac.h new file mode 100644 index 000000000..9ba036fb9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpcmac.h @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2007 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Ciper-based Message Authentication Code (CMAC) see SP800-38B +// Internal Definitions and Internal Functions Prototypes +// +*/ + +#if !defined(_PCP_CMAC_H) +#define _PCP_CMAC_H + +#include "pcprij.h" + + +/* +// Rijndael128 based CMAC context +*/ +struct _cpAES_CMAC { + Ipp32u idCtx; /* CMAC identifier */ + int index; /* internal buffer entry (free) */ + Ipp8u k1[MBS_RIJ128]; /* k1 subkey */ + Ipp8u k2[MBS_RIJ128]; /* k2 subkey */ + Ipp8u mBuffer[MBS_RIJ128];/* buffer */ + Ipp8u mMAC[MBS_RIJ128]; /* intermediate digest */ + IppsRijndael128Spec mCipherCtx; +}; + +/* alignment */ +//#define CMACRIJ_ALIGNMENT (RIJ_ALIGNMENT) +#define AESCMAC_ALIGNMENT (RIJ_ALIGNMENT) + +/* +// Useful macros +*/ +#define CMAC_SET_ID(stt) ((stt)->idCtx = (Ipp32u)idCtxCMAC ^ (Ipp32u)IPP_UINT_PTR(stt)) +#define CMAC_INDX(stt) ((stt)->index) +#define CMAC_K1(stt) ((stt)->k1) +#define CMAC_K2(stt) ((stt)->k2) +#define CMAC_BUFF(stt) ((stt)->mBuffer) +#define CMAC_MAC(stt) ((stt)->mMAC) +#define CMAC_CIPHER(stt) ((stt)->mCipherCtx) + +#if (_AES_PROB_NOISE == _FEATURE_ON_) +#define AESCMAC_NOISE_PARAMS(ctx) (CMAC_CIPHER(ctx).noiseParams) +#endif + +/* valid context ID */ +#define VALID_AESCMAC_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxCMAC) + +#define cpAESCMAC_Update_AES_NI OWNAPI(cpAESCMAC_Update_AES_NI) + IPP_OWN_DECL (void, cpAESCMAC_Update_AES_NI, (Ipp8u* pMac, const Ipp8u* inpBlk, int nBlks, int nr, const Ipp8u* pKeys)) + +#endif /* _PCP_CMAC_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdes.h b/plugin/ippcp/library/src/sources/ippcp/pcpdes.h new file mode 100644 index 000000000..cd6fdb1e9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdes.h @@ -0,0 +1,96 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions and +// Internal DES based Encrypt/Decrypt Function Prototypes +// +// +*/ + + +#if !defined(_PCP_DES_H) +#define _PCP_DES_H + + +/* +// really DES round key saved in terms of pear of 24-bit half mentioned in FIPS 46-3 +*/ +typedef Ipp64u RoundKeyDES; +typedef Ipp32u HalfRoundKeyDES; + +/* +// DES context +*/ +struct _cpDES { + Ipp32u idCtx; /* DES spec identifier */ + RoundKeyDES enc_keys[16]; /* array of keys for encryprion */ + RoundKeyDES dec_keys[16]; /* array of keys for decryprion */ +}; + +/* alignment */ +#define DES_ALIGNMENT ((int)(sizeof(Ipp64u))) + +#define MBS_DES (8) /* data block (bytes) */ + +/* +// Useful macros +*/ +#define DES_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxDES ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define DES_RESET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxDES) +#define DES_EKEYS(ctx) ((ctx)->enc_keys) +#define DES_DKEYS(ctx) ((ctx)->dec_keys) + +#define VALID_DES_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxDES) + +/* +// Internal Tables +*/ +#define MITIGATED (4) + +#define IMPLEMENTATION MITIGATED + + +#if (IMPLEMENTATION == MITIGATED) + extern const __ALIGN64 Ipp32u DESspbox[16*16]; +#endif + + +/* +// internal functions +*/ +#define SetKey_DES OWNAPI(SetKey_DES) + IPP_OWN_DECL (void, SetKey_DES, (const Ipp8u* pKey, IppsDESSpec* pCtx)) + +#define Cipher_DES OWNAPI(Cipher_DES) + IPP_OWN_DECL (Ipp64u, Cipher_DES, (Ipp64u inpBlk, const RoundKeyDES* pRKey, const Ipp32u spbox[])) + +#define ENCRYPT_DES(blk, pCtx) Cipher_DES((blk), DES_EKEYS((pCtx)), DESspbox) +#define DECRYPT_DES(blk, pCtx) Cipher_DES((blk), DES_DKEYS((pCtx)), DESspbox) + +/* TDES prototypes */ +#define ECB_TDES OWNAPI(ECB_TDES) + IPP_OWN_DECL (void, ECB_TDES, (const Ipp64u* pSrc, Ipp64u* pDst, int nBlocks, const RoundKeyDES* pRKey[3], const Ipp32u spbox[])) +#define EncryptCBC_TDES OWNAPI(EncryptCBC_TDES) + IPP_OWN_DECL (void, EncryptCBC_TDES, (const Ipp64u* pSrc, Ipp64u* pDst, int nBlocks, const RoundKeyDES* pRKey[3], Ipp64u iv, const Ipp32u spbox[])) +#define DecryptCBC_TDES OWNAPI(DecryptCBC_TDES) + IPP_OWN_DECL (void, DecryptCBC_TDES, (const Ipp64u* pSrc, Ipp64u* pDst, int nBlocks, const RoundKeyDES* pRKey[3], Ipp64u iv, const Ipp32u spbox[])) + +#endif /* _PCP_DES_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdescipherm.c b/plugin/ippcp/library/src/sources/ippcp/pcpdescipherm.c new file mode 100644 index 000000000..81ba39c7a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdescipherm.c @@ -0,0 +1,177 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DES Cipher function (MemJam mitigation incuded) +// +// Contents: +// initial permutation: ip() +// final permutation: fp() +// round function: rndm() +// DES block encypt/decrypt: Chipher_DES() +// +// +*/ + + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdes.h" +#include "pcpmask_ct.h" + +/* +// Following implementation of ip(), fp() and rndm() +// assumes input and output of DES as sequence of bytes. +*/ +#define ip(x,y) { \ + Ipp32u t; \ + (x) = ROR32((x), 4); \ + (t) = ((x)^(y)) & 0x0f0f0f0fL; \ + (y)^= (t); \ + (x) = ROR32((x)^(t), 12); \ + (t) = ((y)^(x)) & 0xffff0000L; \ + (y)^= (t); \ + (x) = ROR32((x)^(t), 18); \ + (t) = ((x)^(y)) & 0x33333333L; \ + (y)^= (t); \ + (x) = ROR32((x)^(t), 22); \ + (t) = ((y)^(x)) & 0xff00ff00L; \ + (y)^= (t); \ + (x) = ROR32((x)^(t), 9); \ + (t) = ((x)^(y)) & 0x55555555L; \ + (x) = ROL32((x)^(t), 2); \ + (y) = ROL32((y)^(t), 1); \ +} + +#define fp(x,y) { \ + Ipp32u t; \ + (y) = ROR32((y), 1); \ + (x) = ROR32((x), 2); \ + (t) = ((x)^(y)) & 0x55555555L; \ + (y)^= (t); \ + (x) = ROL32((x)^(t), 9); \ + (t) = ((y)^(x)) & 0xff00ff00L; \ + (y)^= (t); \ + (x) = ROL32((x)^(t), 22); \ + (t) = ((x)^(y)) & 0x33333333L; \ + (y)^= (t); \ + (x) = ROL32((x)^(t), 18); \ + (t) = ((y)^(x)) & 0xffff0000L; \ + (y)^= (t); \ + (x) = ROL32((x)^(t), 12); \ + (t) = ((x)^(y)) & 0x0f0f0f0fL; \ + (y)^= (t); \ + (x) = ROL32((x)^(t), 4); \ +} + + +static BNU_CHUNK_T getSbox(const BNU_CHUNK_T sbox[], int idx) +{ + unsigned int i; + BNU_CHUNK_T res = 0; + for(i=0; i<(64/sizeof(BNU_CHUNK_T)); i++) { + BNU_CHUNK_T mask = cpIsEqu_ct(i, (BNU_CHUNK_T)idx); + res |= sbox[i] & mask; + } + return res; +} +static Ipp8u getSbox8u(const Ipp8u sbox[], int idx) +{ + int shift = idx % (Ipp32s)((sizeof(BNU_CHUNK_T))/sizeof(Ipp8u)); + idx /= ((sizeof(BNU_CHUNK_T))/sizeof(Ipp8u)); + return (Ipp8u)( getSbox((BNU_CHUNK_T*)sbox, idx) >>(shift*8) ); +} +static Ipp32u getSbox32u(const Ipp8u sbox[], int idx) +{ + int shift = idx % (Ipp32s)((sizeof(BNU_CHUNK_T))/sizeof(Ipp32u)); + idx /= ((sizeof(BNU_CHUNK_T))/sizeof(Ipp32u)); + return (Ipp32u)( getSbox((BNU_CHUNK_T*)sbox, idx)>>shift*32 ); +} + +static Ipp32u rndm(Ipp32u x0, Ipp32u x1, Ipp32u* key, const Ipp8u* sbox) +{ + Ipp32u + tt = key[0] ^ (x1 &0x3F3F3F3F); + x0 ^= getSbox32u(sbox+512+64*0, getSbox8u(sbox+64*0, (Ipp8u)tt)); + tt >>= 8; + x0 ^= getSbox32u(sbox+512+64*2, getSbox8u(sbox+64*2, (Ipp8u)tt)); + tt >>= 8; + x0 ^= getSbox32u(sbox+512+64*4, getSbox8u(sbox+64*4, (Ipp8u)tt)); + tt >>= 8; + x0 ^= getSbox32u(sbox+512+64*6, getSbox8u(sbox+64*6, (Ipp8u)tt)); + + tt = (key)[1] ^ (ROR32((x1 &0xF3F3F3F3),4)); + x0 ^= getSbox32u(sbox+512+64*1, getSbox8u(sbox+64*1, (Ipp8u)tt)); + tt >>= 8; + x0 ^= getSbox32u(sbox+512+64*3, getSbox8u(sbox+64*3, (Ipp8u)tt)); + tt >>= 8; + x0 ^= getSbox32u(sbox+512+64*5, getSbox8u(sbox+64*5, (Ipp8u)tt)); + tt >>= 8; + x0 ^= getSbox32u(sbox+512+64*7, getSbox8u(sbox+64*7, (Ipp8u)tt)); + + return x0; +} + +IPP_OWN_DEFN (Ipp64u, Cipher_DES, (Ipp64u inpBlk, const RoundKeyDES* pRKey, const Ipp32u sbox[])) +{ + const Ipp8u* sbox8 = (const Ipp8u*)sbox; + + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + Ipp32u q0 = IPP_LODWORD(inpBlk); + Ipp32u q1 = IPP_HIDWORD(inpBlk); + q0 = ENDIANNESS(q0); + q1 = ENDIANNESS(q1); + #else + Ipp32u q0 = IPP_HIDWORD(inpBlk); + Ipp32u q1 = IPP_LODWORD(inpBlk); + #endif + + /* apply inverse permutation IP */ + ip(q0,q1); + + /* 16 magic encrypt iterations */ + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey)), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+1 )), sbox8); + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey+2 )), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+3 )), sbox8); + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey+4 )), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+5 )), sbox8); + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey+6 )), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+7 )), sbox8); + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey+8 )), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+9 )), sbox8); + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey+10)), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+11)), sbox8); + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey+12)), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+13)), sbox8); + q0 = rndm(q0,q1, ((HalfRoundKeyDES*)(pRKey+14)), sbox8); + q1 = rndm(q1,q0, ((HalfRoundKeyDES*)(pRKey+15)), sbox8); + + /* apply forward permutation FP */ + fp(q1,q0); + + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + q0 = ENDIANNESS(q0); + q1 = ENDIANNESS(q1); + return IPP_MAKEDWORD(q1,q0); + #else + return IPP_MAKEDWORD(q0,q1); + #endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdesgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpdesgetsize.c new file mode 100644 index 000000000..a284407bd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdesgetsize.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Set Round Keys for DES/TDES +// +// Contents: +// ippsDESGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdes.h" +#include "pcptool.h" + +/*F* +// Name: ippsDESGetSize +// +// Purpose: Returns size of DES spec (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer DES spec size +// +*F*/ +IPPFUN(IppStatus, ippsDESGetSize, (int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsDESSpec); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdesinitca.c b/plugin/ippcp/library/src/sources/ippcp/pcpdesinitca.c new file mode 100644 index 000000000..7c66b0404 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdesinitca.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Set Round Keys for DES/TDES +// +// Contents: +// ippsDESInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdes.h" +#include "pcptool.h" + +/*F* +// Name: ippsDESInit +// +// Purpose: Init DES spec for future usage. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pKey == NULL +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to security key +// pCtx pointer DES spec +// +*F*/ +IPPFUN(IppStatus, ippsDESInit,(const Ipp8u* pKey, IppsDESSpec* pCtx)) +{ + /* test key's and spec's pointers */ + IPP_BAD_PTR2_RET(pKey, pCtx); + + /* init DES spec */ + DES_SET_ID(pCtx); + + /* set round keys */ + SetKey_DES(pKey, pCtx); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdesinitpxca.c b/plugin/ippcp/library/src/sources/ippcp/pcpdesinitpxca.c new file mode 100644 index 000000000..6cdbd29e7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdesinitpxca.c @@ -0,0 +1,159 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Set Round Keys for DES/TDES +// +// Contents: +// SetKey_DES() +// ippcSetKey_DES() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdes.h" + + +/* +// bit 0 is left-most in byte (reference FIPS 46-3) +*/ +static int bytebit[] = { + 0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1 +}; + +/* +// Key schedule-related tables (reference FIPS 46-3) +*/ + +/* PC-1 permuted table (for the user key) */ +static Ipp8u pc1[] = { + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 +}; + +/* number left rotations of PC-1 key */ +static int rotations[] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 +}; + +/* PC-2 table (for round key constuction) */ +static Ipp8u pc2[] = { + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 +}; + +#define SWAP8U(a,b) { Ipp8u x=(a); (a)=(b); (b)=x; } +/* +// Generate key schedule for encryption and decryption +*/ +IPP_OWN_DEFN (void, SetKey_DES, (const Ipp8u* pKey, IppsDESSpec* pCtx)) +{ + RoundKeyDES* pEncRoundKey = DES_EKEYS(pCtx); + RoundKeyDES* pDecRoundKey = DES_DKEYS(pCtx); + + __ALIGN64 Ipp8u pc1key[56]; /* PC-1 permuted user key bits */ + __ALIGN64 Ipp8u rndkey[56]; /* rounded key bits */ + + int nkey; + int i; + + /* + // apply permutation PC-1 + */ + for(i=0; i<56; i++) { + /* location into the user key (bit number) */ + int nBit = pc1[i]-1; + /* location into the user key (byte and offset in the byte) */ + int nByte = nBit>>3; + int offset = nBit & 0x07; + + /* test bit in the user key and set into the permuted */ + pc1key[i] = (Ipp8u)( (pKey[nByte] & bytebit[offset] ) >>(7-offset)); + } + + /* + // key schedule for encryption + */ + for(nkey=0; nkey<16; nkey++) { + Ipp64u tmp = 0; + Ipp8u* rkeyNibble = (Ipp8u*)(&tmp); + + int pc1keyBit, pc1keyBit_m28; + Ipp32u mask; + + /* rotate right pc1key */ + for (i=0; i<28; i++) { + pc1keyBit = i+rotations[nkey]; + pc1keyBit_m28 = pc1keyBit-28; + mask = (Ipp32u)(pc1keyBit_m28>>(BITSIZE(Ipp32u)-1)); + pc1keyBit = (Ipp32s)((Ipp32u)pc1keyBit & mask) | (Ipp32s)((Ipp32u)pc1keyBit_m28 &~mask); + rndkey[i] = pc1key[pc1keyBit]; + } + for (; i<56; i++) { + pc1keyBit = i+rotations[nkey]; + pc1keyBit_m28 = pc1keyBit-28; + mask = (Ipp32u)((pc1keyBit-56)>>(BITSIZE(Ipp32u)-1)); + pc1keyBit = (Ipp32s)((Ipp32u)pc1keyBit & mask) | (Ipp32s)((Ipp32u)pc1keyBit_m28 &~mask); + rndkey[i] = pc1key[pc1keyBit]; + } + + /* + // construct eight 6-bit nibbles of round key + // applying PC-2 permutation to rndkey[] + */ + for(i=0; i<48; i++) { + int offset = i%6; + rkeyNibble[i/6] |= (rndkey[pc2[i]-1]<idCtx = (Ipp32u)idCtxDLP ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define DLP_RESET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxDLP) +#define DLP_FLAG(ctx) ((ctx)->flag) +#define DLP_BITSIZEP(ctx) ((ctx)->bitSizeP) +#define DLP_BITSIZER(ctx) ((ctx)->bitSizeR) +#define DLP_EXPMETHOD(ctx) ((ctx)->method) + +#define DLP_MONTP0(ctx) ((ctx)->pMontP0) +#define DLP_MONTP1(ctx) ((ctx)->pMontP1) +#define DLP_MONTR(ctx) ((ctx)->pMontR) + +#define DLP_P(ctx) (MOD_MODULUS(DLP_MONTP0((ctx)))) +#define DLP_R(ctx) (MOD_MODULUS(DLP_MONTR((ctx)))) +#define DLP_GENC(ctx) ((ctx)->pGenc) +#define DLP_X(ctx) ((ctx)->pX) +#define DLP_YENC(ctx) ((ctx)->pYenc) + +#define DLP_PRIMEGEN(ctx) ((ctx)->pPrimeGen) + +#define DLP_METBL(ctx) ((ctx)->pMeTable) +#define DLP_BNCTX(ctx) ((ctx)->pBnList) +#if defined(_USE_WINDOW_EXP_) +#define DLP_BNUCTX0(ctx) ((ctx)->pBnuList0) +#define DLP_BNUCTX1(ctx) ((ctx)->pBnuList1) +#endif + +#define DLP_VALID_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxDLP) +#define DLP_COMPLETE(ctx) (DLP_FLAG((ctx))==(IppDLPkeyP|IppDLPkeyR|IppDLPkeyG)) + +/* alignment */ +#define DLP_ALIGNMENT ((int)(sizeof(void*))) + +/* pool size for gsModEngine */ +#define DLP_MONT_POOL_LENGTH (6) + +#define cpPackDLPCtx OWNAPI(cpPackDLPCtx) + IPP_OWN_DECL (void, cpPackDLPCtx, (const IppsDLPState* pDLP, Ipp8u* pBuffer)) +#define cpUnpackDLPCtx OWNAPI(cpUnpackDLPCtx) + IPP_OWN_DECL (void, cpUnpackDLPCtx, (const Ipp8u* pBuffer, IppsDLPState* pDLP)) + +#endif /* _PCP_DLP_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlp_packctx.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlp_packctx.c new file mode 100644 index 000000000..f70e8f504 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlp_packctx.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Field (initialization) +// +// Contents: +// cpPackDLPCtx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcptool.h" + +IPP_OWN_DEFN (void, cpPackDLPCtx, (const IppsDLPState* pDLP, Ipp8u* pBuffer)) +{ + IppsDLPState* pB = (IppsDLPState*)(pBuffer); + + CopyBlock(pDLP, pB, sizeof(IppsDLPState)); + DLP_MONTP0(pB) = (gsModEngine*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_MONTP0(pDLP))-IPP_UINT_PTR(pDLP)); + DLP_MONTP1(pB) = NULL; + DLP_MONTR(pB) = (gsModEngine*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_MONTR(pDLP)) -IPP_UINT_PTR(pDLP)); + + DLP_GENC(pB) = (IppsBigNumState*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_GENC(pDLP)) -IPP_UINT_PTR(pDLP)); + DLP_X(pB) = (IppsBigNumState*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_X(pDLP)) -IPP_UINT_PTR(pDLP)); + DLP_YENC(pB) = (IppsBigNumState*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_YENC(pDLP)) -IPP_UINT_PTR(pDLP)); + + DLP_PRIMEGEN(pB)= (IppsPrimeState*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_PRIMEGEN(pDLP))-IPP_UINT_PTR(pDLP)); + + DLP_METBL(pB) = (BNU_CHUNK_T*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_METBL(pDLP)) -IPP_UINT_PTR(pDLP)); + + DLP_BNCTX(pB) = (BigNumNode*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_BNCTX(pDLP)) -IPP_UINT_PTR(pDLP)); + #if defined(_USE_WINDOW_EXP_) + DLP_BNUCTX0(pB) = (WINDOW==DLP_EXPMETHOD(pDLP))?(BNU_CHUNK_T*)((Ipp8u*)NULL + IPP_UINT_PTR(DLP_BNUCTX0(pDLP))-IPP_UINT_PTR(pDLP)) : NULL; + DLP_BNUCTX1(pB) = NULL; + #endif + + gsPackModEngineCtx(DLP_MONTP0(pDLP), (Ipp8u*)pB+IPP_UINT_PTR(DLP_MONTP0(pB))); + gsPackModEngineCtx(DLP_MONTR(pDLP), (Ipp8u*)pB+IPP_UINT_PTR(DLP_MONTR(pB))); + + cpPackBigNumCtx(DLP_GENC(pDLP), (Ipp8u*)pB+IPP_UINT_PTR(DLP_GENC(pB))); + cpPackBigNumCtx(DLP_X(pDLP), (Ipp8u*)pB+IPP_UINT_PTR(DLP_X(pB))); + cpPackBigNumCtx(DLP_YENC(pDLP), (Ipp8u*)pB+IPP_UINT_PTR(DLP_YENC(pB))); + + cpPackPrimeCtx(DLP_PRIMEGEN(pDLP), (Ipp8u*)pB+IPP_UINT_PTR(DLP_PRIMEGEN(pB))); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlp_unpackctx.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlp_unpackctx.c new file mode 100644 index 000000000..7bf5b9095 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlp_unpackctx.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Field (initialization) +// +// Contents: +// cpUnpackDLPCtx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcptool.h" + +IPP_OWN_DEFN (void, cpUnpackDLPCtx, (const Ipp8u* pBuffer, IppsDLPState* pDLP)) +{ + IppsDLPState* pB = (IppsDLPState*)(pBuffer); + + CopyBlock(pB, pDLP, sizeof(IppsDLPState)); + DLP_MONTP0(pDLP) = (gsModEngine*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_MONTP0(pB))); + DLP_MONTP1(pDLP) = NULL; + DLP_MONTR(pDLP) = (gsModEngine*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_MONTR(pB))); + + DLP_GENC(pDLP) = (IppsBigNumState*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_GENC(pB))); + DLP_X(pDLP) = (IppsBigNumState*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_X(pB))); + DLP_YENC(pDLP) = (IppsBigNumState*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_YENC(pB))); + + DLP_PRIMEGEN(pDLP)= (IppsPrimeState*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_PRIMEGEN(pB))); + + DLP_METBL(pDLP) = (BNU_CHUNK_T*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_METBL(pB))); + DLP_BNCTX(pDLP) = (BigNumNode*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_BNCTX(pB))); + #if defined(_USE_WINDOW_EXP_) + DLP_BNUCTX0(pDLP) = (WINDOW==DLP_EXPMETHOD(pDLP))?(BNU_CHUNK_T*)((Ipp8u*)pDLP+ IPP_UINT_PTR(DLP_BNUCTX0(pB))) : NULL; + DLP_BNUCTX1(pDLP) = NULL; + #endif + + gsUnpackModEngineCtx((Ipp8u*)pB+IPP_UINT_PTR(DLP_MONTP0(pB)), DLP_MONTP0(pDLP)); + gsUnpackModEngineCtx((Ipp8u*)pB+IPP_UINT_PTR(DLP_MONTR(pB)), DLP_MONTR(pDLP)); + cpUnpackBigNumCtx((Ipp8u*)pB+IPP_UINT_PTR(DLP_GENC(pB)), DLP_GENC(pDLP)); + cpUnpackBigNumCtx((Ipp8u*)pB+IPP_UINT_PTR(DLP_X(pB)), DLP_X(pDLP)); + cpUnpackBigNumCtx((Ipp8u*)pB+IPP_UINT_PTR(DLP_YENC(pB)), DLP_YENC(pDLP)); + cpUnpackPrimeCtx((Ipp8u*)pB+IPP_UINT_PTR(DLP_PRIMEGEN(pB)),DLP_PRIMEGEN(pDLP)); + cpBigNumListInit(DLP_BITSIZEP(pDLP)+1, BNLISTSIZE, DLP_BNCTX(pDLP)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpgeneratedh.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpgeneratedh.c new file mode 100644 index 000000000..b95f8d741 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpgeneratedh.c @@ -0,0 +1,346 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (generate domain parameters) +// +// Contents: +// ippsDLPGenerateDH() +// ippsDLPGenerateDSA() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + + +/*F* +// Name: ippsDLPGenerateDH +// +// Purpose: Generate DL (DH) Domain Parameters. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDH +// NULL == rndFunc +// +// ippStsContextMatchErr illegal pDH->idCtx +// illegal pSeedIn->idCtx +// illegal pSeedOut->idCtx +// +// ippStsSizeErr !(MIN_DLPDH_BITSIZE <= DLP_BITSIZEP()) +// !(256|DLP_BITSIZEP()) +// !(MIN_DLPDH_BITSIZER <= DLP_BITSIZER()) +// +// ippStsRangeErr BitSize(pSeedIn) < DH_BITSIZER() +// no room for pSeedOut +// +// ippStsBadArgErr nTrials <=0 +// +// ippStsInsufficientEntropy +// genration failure due to poor random generator +// +// ippStsNoErr no errors +// +// Parameters: +// pSeedIn pointer to the input seed (probably null) +// nTrials number of trials of primality test +// pDL pointer to the DL context +// pSeedOut pointer to the output seed (probably null, or ==pSeedIn) +// pCounter pointer to the generator loop counter (probably null) +// rndFunc external random generator +// pRndParam pointer to the external random generator params +// +// Note: +// 1) pSeedIn==NULL means, that rndFunc will be used for input seed generation +// 2) PseedIn!=NULL limited by DL bitsizeP parameter! +*F*/ +#define MAXLOOP (4096) + +IPPFUN(IppStatus, ippsDLPGenerateDH,(const IppsBigNumState* pSeedIn, + int nTrials, IppsDLPState* pDL, + IppsBigNumState* pSeedOut, int* pCounter, + IppBitSupplier rndFunc, void* pRndParam)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test DL sizes */ + IPP_BADARG_RET(MIN_DLPDH_BITSIZER>DLP_BITSIZER(pDL), ippStsSizeErr); + IPP_BADARG_RET(MIN_DLPDH_BITSIZE >DLP_BITSIZEP(pDL), ippStsSizeErr); + IPP_BADARG_RET(DLP_BITSIZEP(pDL)%256, ippStsSizeErr); + + /* test number of trials for primality check */ + IPP_BADARG_RET(nTrials<=0, ippStsBadArgErr); + + IPP_BAD_PTR1_RET(rndFunc); + + { + /* allocate BN resources */ + BigNumNode* pList = DLP_BNCTX(pDL); + IppsBigNumState* pP = cpBigNumListGet(&pList); + IppsBigNumState* pR = cpBigNumListGet(&pList); + IppsBigNumState* pG = cpBigNumListGet(&pList); + + IppsBigNumState* pSeed1 = cpBigNumListGet(&pList); + IppsBigNumState* pSeed2 = cpBigNumListGet(&pList); + + /* interally generates SeedIn value by default */ + IppBool seed_is_random = ippTrue; + int seedBitSize = DLP_BITSIZER(pDL); + + DLP_FLAG(pDL) = 0; + /* + // DH generator uses input SEED + // either defined by user or generated internally + */ + if(pSeedIn) { + /* test SeedIn */ + IPP_BADARG_RET(!BN_VALID_ID(pSeedIn), ippStsContextMatchErr); + seedBitSize = BITSIZE_BNU(BN_NUMBER(pSeedIn), BN_SIZE(pSeedIn)); + IPP_BADARG_RET(DLP_BITSIZER(pDL)>seedBitSize, ippStsRangeErr); + IPP_BADARG_RET(BN_ROOM(pSeed1)BITSIZE(BNU_CHUNK_T)*BN_ROOM(pSeedOut), ippStsRangeErr); + } + + /* + // generation DSA domain parameters + */ + { + int feBitsize = DLP_BITSIZEP(pDL); + int ordBitsize = DLP_BITSIZER(pDL); + int m = (ordBitsize + IPP_SHA1_DIGEST_BITSIZE -1)/IPP_SHA1_DIGEST_BITSIZE; + int l = (feBitsize + IPP_SHA1_DIGEST_BITSIZE -1)/IPP_SHA1_DIGEST_BITSIZE; + int n = (feBitsize + 1023)/1024; + + IppsPrimeState* pPrimeGen = DLP_PRIMEGEN(pDL); + + /* pointers to the BNU32-value of SEED */ + Ipp32u* pSeed1BNU32 = (Ipp32u*)BN_NUMBER(pSeed1); + Ipp32u* pSeed2BNU32 = (Ipp32u*)BN_NUMBER(pSeed2); + int seedSize32 = BITS2WORD32_SIZE(seedBitSize); + /* pointers to the octet-string-value of SEED */ + Ipp8u* pSeed1Oct = (Ipp8u*)BN_BUFFER(pSeed1); + Ipp8u* pSeed2Oct = (Ipp8u*)BN_BUFFER(pSeed2); + + int octSize; + Ipp8u shaDgst1[BITS2WORD8_SIZE(IPP_SHA1_DIGEST_BITSIZE)]; + Ipp8u shaDgst2[BITS2WORD8_SIZE(IPP_SHA1_DIGEST_BITSIZE)]; + + int primeGenerated = 0; + int genCounter; + + ippsSet_BN(ippBigNumPOS, 1, (Ipp32u*)&m, pP); /* P = m */ + + /* + // generate prime Q + */ + for(genCounter=0; genCounteridCtx +// illegal pSeedIn->idCtx +// illegal pSeedOut->idCtx +// +// ippStsSizeErr !(MIN_DLPDLP_BITSIZE <= DLP_BITSIZEP() <= MAX_DLPDLP_BITSIZE) +// !(64|DLP_BITSIZEP()) +// !(DEF_DLPDLP_BITSIZER == DLP_BITSIZER()) +// +// ippStsRangeErr BitSize(pSeedIn) < MIN_DLPDLP_SEEDSIZE +// BitSize(pSeedIn) > DLP_BITSIZEP() +// no room for pSeedOut +// +// ippStsBadArgErr nTrials <=0 +// +// ippStsInsufficientEntropy +// genration failure due to poor random generator +// +// ippStsNoErr no errors +// +// Parameters: +// pSeedIn pointer to the input seed (probably null) +// nTrials number of trials of primality test +// pDL pointer to the DL context +// pSeedOut pointer to the output seed (probably null, or ==pSeedIn) +// pCounter pointer to the generator loop counter (probably null) +// rndFunc external random generator +// pRndParam pointer to the external random generator params +// +// Note: +// 1) pSeedIn==NULL means, that rndFunc will be used for input seed generation +// 2) PseedIn!=NULL limited by DSA bitsize (L) parameter! +*F*/ +#define R_MAXLOOP (100) +#define P_MAXLOOP (4096) +#define G_MAXLOOP (100) + +IPPFUN(IppStatus, ippsDLPGenerateDSA,(const IppsBigNumState* pSeedIn, + int nTrials, IppsDLPState *pDL, + IppsBigNumState* pSeedOut, int* pCounter, + IppBitSupplier rndFunc, void* pRndParam)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test DL sizes */ + IPP_BADARG_RET(DEF_DLPDSA_BITSIZER != DLP_BITSIZER(pDL),ippStsSizeErr); + IPP_BADARG_RET(MIN_DLPDSA_BITSIZE >DLP_BITSIZEP(pDL), ippStsSizeErr); + IPP_BADARG_RET(MAX_DLPDSA_BITSIZE = MIN_DLPDSA_SEEDSIZE (==160 bits) - it's FIPS-186 claim + - divisible by 8 + (week request, because provided automatically by BITS2WORD8_SIZE(seedBitSize) conversion) + + If seedBitSize (been calculated above) <160 this means + that there are some zero msb bits in SeedIn representation. + For example, if SeedIn hex string is + is 0000000000000000000000000000000000000001 + or even 01 + we'll think about 160 bit length + **/ + if(seedBitSizeidCtx +// invalid pPrivate->idCtx +// invalid pPublic->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsRangeErr not enough room for: +// pPrivate, +// pPublic +// +// ippStsNoErr no error +// +// Parameters: +// pPrvKey pointer to the new privatea key +// pPubKey pointer to the corrsponding public key +// pDL pointer to the DL context +// rndFunc external random generator +// pRndParam pointer to the external random generator params +*F*/ +IPPFUN(IppStatus, ippsDLPGenKeyPair,(IppsBigNumState* pPrvKey, IppsBigNumState* pPubKey, + IppsDLPState* pDL, + IppBitSupplier rndFunc, void* pRndParam)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test random generator */ + IPP_BAD_PTR1_RET(rndFunc); + + /* test private/public keys */ + IPP_BAD_PTR2_RET(pPrvKey, pPubKey); + IPP_BADARG_RET(!BN_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(DLP_BITSIZER(pDL)>BITSIZE(BNU_CHUNK_T)*BN_ROOM(pPrvKey), ippStsRangeErr); + IPP_BADARG_RET(DLP_BITSIZEP(pDL)>BITSIZE(BNU_CHUNK_T)*BN_ROOM(pPubKey), ippStsRangeErr); + + { + /* + // generate random private key X: 0 < X < R + */ + BNU_CHUNK_T* pOrder = DLP_R(pDL); + cpSize ordBitSize = DLP_BITSIZER(pDL); + cpSize ordLen = BITS_BNU_CHUNK(ordBitSize); + BNU_CHUNK_T xMask = MASK_BNU_CHUNK(ordBitSize); + + //BNU_CHUNK_T* pY = BN_NUMBER(pPubKey); + BNU_CHUNK_T* pX = BN_NUMBER(pPrvKey); + + //gsModEngine* pME = DLP_MONTP0(pDL); + + do { + rndFunc((Ipp32u*)pX, ordBitSize, pRndParam); + pX[ordLen-1] &= xMask; + } while( cpEqu_BNU_CHUNK(pX, ordLen, 0) || cpCmp_BNU(pX,ordLen, pOrder,ordLen)>=0 ); + BN_SIZE(pPrvKey) = ordLen; + BN_SIGN(pPrvKey) = ippBigNumPOS; + + /* + // compute public key: G^prvKey (mod P) + */ + cpMontExpBin_BN_sscm(pPubKey, DLP_GENC(pDL), pPrvKey, DLP_MONTP0(pDL)); + cpMontDec_BN(pPubKey, pPubKey, DLP_MONTP0(pDL)); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpget.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpget.c new file mode 100644 index 000000000..b0e5009ec --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpget.c @@ -0,0 +1,96 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsDLPGet() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + +/*F* +// Name: ippsDLPGet +// +// Purpose: Retrieve DLP Domain Parameter. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pP +// NULL == pR +// NULL == pG +// NULL == pDL +// +// ippStsContextMatchErr illegal pP->idCtx +// illegal pR->idCtx +// illegal pG->idCtx +// illegal pDL->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsRangeErr not enough room for: +// pP, +// pR, +// pG +// +// ippStsNoErr no errors +// +// Parameters: +// pP pointer to the retrieval P +// pR pointer to the retrieval R +// pG pointer to the retrieval G +// pDSA pointer to the DL context +// +*F*/ +IPPFUN(IppStatus, ippsDLPGet,(IppsBigNumState* pP, + IppsBigNumState* pR, + IppsBigNumState* pG, + IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test DL parameters */ + IPP_BAD_PTR3_RET(pP, pR, pG); + IPP_BADARG_RET(!BN_VALID_ID(pP), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pG), ippStsContextMatchErr); + + /* test size of retrieval parameters */ + IPP_BADARG_RET(BN_ROOM(pP)idCtx +// illegal pDL->idCtx +// +// ippStsIncompleteContextErr requested parameter hasn't set up +// +// ippStsOutOfRangeErr BN_ROOM(pDP) < BN_ROOM(DLP_{P|R|G}(pDL)) +// +// ippStsBadArgErr invalid key tag +// +// errors produced by ippsSet_BN() +// +// ippStsNoErr no errors +// +// Parameters: +// pDP pointer to the DL domain parameter +// tag DLP key component tag +// pDL pointer to the DL context +// +*F*/ +IPPFUN(IppStatus, ippsDLPGetDP,(IppsBigNumState* pDP, IppDLPKeyTag tag, const IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test DL parameter to be set */ + IPP_BAD_PTR1_RET(pDP); + IPP_BADARG_RET(!BN_VALID_ID(pDP), ippStsContextMatchErr); + + { + IppStatus sts = ippStsNoErr; + + switch(tag) { + case ippDLPkeyP: + if(DLP_FLAG(pDL)&ippDLPkeyP) + sts = ippsSet_BN(ippBigNumPOS, BITS2WORD32_SIZE(DLP_BITSIZEP(pDL)), (Ipp32u*)DLP_P(pDL), pDP); + else + sts = ippStsIncompleteContextErr; + break; + case ippDLPkeyR: + if(DLP_FLAG(pDL)&ippDLPkeyR) + sts = ippsSet_BN(ippBigNumPOS, BITS2WORD32_SIZE(DLP_BITSIZER(pDL)), (Ipp32u*)DLP_R(pDL), pDP); + else + sts = ippStsIncompleteContextErr; + break; + case ippDLPkeyG: + if(DLP_FLAG(pDL)&ippDLPkeyG) { + cpMontDec_BN(pDP, DLP_GENC(pDL), DLP_MONTP0(pDL)); + } + else + sts = ippStsIncompleteContextErr; + break; + default: + sts = ippStsBadArgErr; + } + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpgetsize.c new file mode 100644 index 000000000..6c74f271b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpgetsize.c @@ -0,0 +1,125 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Field (initialization) +// +// Contents: +// ippsDLPGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcptool.h" + +#include "pcpmont_exp_bufsize.h" + + + +/*F* +// Name: ippsDLPGetSize +// +// Purpose: Returns size of DL context (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsSizeErr MIN_DLP_BITSIZE > feBitSize +// MIN_DLP_BITSIZER > ordBitSize +// ordBitSize >= feBitSize +// +// ippStsNoErr no errors +// +// Parameters: +// feBitSize size (bits) of field element (GF(p)) of DL system +// ordBitSize size (bits) of subgroup (GF(p)) generator order +// pSize pointer to the size of DLP context (bytes) +// +*F*/ +IPPFUN(IppStatus, ippsDLPGetSize,(int feBitSize, int ordBitSize, int *pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + /* test sizes of DL system */ + IPP_BADARG_RET(MIN_DLP_BITSIZE >feBitSize, ippStsSizeErr); + IPP_BADARG_RET(MIN_DLP_BITSIZER>ordBitSize, ippStsSizeErr); + IPP_BADARG_RET(ordBitSize>=feBitSize, ippStsSizeErr); + + { + int bnSizeP; + int bnSizeR; + int montSizeP; + int montSizeR; + int primeGenSize; + int bn_resourceSize; + + #if defined(_USE_WINDOW_EXP_) + int window = cpMontExp_WinSize(ordBitSize); + int bnu_resourceSize = window==1? 0 : cpMontExpScratchBufferSize(feBitSize, ordBitSize, 1); + #endif + + /* size of GF(P) element */ + int sizeP = BITS2WORD32_SIZE(feBitSize); + /* size of GF(R) element */ + int sizeR = BITS2WORD32_SIZE(ordBitSize); + /* sizeof multi-exp table */ + int sizeMeTable = cpMontExpScratchBufferSize(feBitSize, ordBitSize, 2); + + /* size of BigNum over GF(P) */ + ippsBigNumGetSize(sizeP, &bnSizeP); + /* size of BigNum over GF(R) */ + ippsBigNumGetSize(sizeR, &bnSizeR); + + /* size of montgomery engine over GF(P) */ + gsModEngineGetSize(feBitSize, DLP_MONT_POOL_LENGTH, &montSizeP); + + /* size of montgomery engine over GF(R) */ + gsModEngineGetSize(ordBitSize, DLP_MONT_POOL_LENGTH, &montSizeR); + + /* size of prime engine */ + ippsPrimeGetSize(feBitSize, &primeGenSize); + + /* size of big num list (big num in the list preserve 32 bit word) */ + bn_resourceSize = cpBigNumListGetSize(feBitSize+1, BNLISTSIZE); + + *pSize = (Ipp32s)sizeof(IppsDLPState) + +montSizeP /* montgomery(P) */ + +montSizeR /* montgomery(Q) */ + + +bnSizeP /* Genc */ + +bnSizeR /* X */ + +bnSizeP /* Y */ + + +primeGenSize /* prime engine */ + + +sizeMeTable /* pre-computed multi-exp table */ + + +bn_resourceSize /* BN resource */ + #if defined(_USE_WINDOW_EXP_) + +bnu_resourceSize /* BNU resource */ + #endif + ; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpinit.c new file mode 100644 index 000000000..5ded86f91 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpinit.c @@ -0,0 +1,160 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Field (initialization) +// +// Contents: +// ippsDLPInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcptool.h" + +#include "pcpmont_exp_bufsize.h" + +/*F* +// Name: ippsDLPInit +// +// Purpose: Init DL context. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDSA +// +// ippStsSizeErr MIN_DLP_BITSIZE > feBitSize +// MIN_DLP_BITSIZER > ordBitSize +// ordBitSize >= feBitSize +// +// ippStsNoErr no errors +// +// Parameters: +// feBitSize size (bits) of field element (GF(p)) of DL system +// ordBitSize size (bits) of subgroup (GF(p)) generator order +// pDL pointer to the DL context +// +*F*/ +IPPFUN(IppStatus, ippsDLPInit,(int feBitSize, int ordBitSize, IppsDLPState* pDL)) +{ + /* test DSA context */ + IPP_BAD_PTR1_RET(pDL); + + /* test sizes of DL system */ + IPP_BADARG_RET(MIN_DLP_BITSIZE >feBitSize, ippStsSizeErr); + IPP_BADARG_RET(MIN_DLP_BITSIZER>ordBitSize, ippStsSizeErr); + IPP_BADARG_RET(ordBitSize>=feBitSize, ippStsSizeErr); + + DLP_SET_ID(pDL); + DLP_FLAG(pDL) = 0; + DLP_BITSIZEP(pDL) = feBitSize; + DLP_BITSIZER(pDL) = ordBitSize; + DLP_EXPMETHOD(pDL)= BINARY; + + /* + // init other context fields + */ + { + int bnSizeP; + int bnSizeR; + int montSizeP; + int montSizeR; + int primeGenSize; + int bn_resourceSize; + + Ipp8u* ptr = (Ipp8u*)pDL; + + /* size of GF(P) element */ + int sizeP = BITS2WORD32_SIZE(feBitSize); + /* size of GF(R) element */ + int sizeR = BITS2WORD32_SIZE(ordBitSize); + /* size of pre-computed multi-exp table */ + int sizeMeTable = cpMontExpScratchBufferSize(feBitSize, ordBitSize, 2); + + /* size of window for exponentiation */ + #if defined(_USE_WINDOW_EXP_) + int window = cpMontExp_WinSize(ordBitSize); + DLP_EXPMETHOD(pDL) = window>1? WINDOW : BINARY; + #endif + + /* size of BigNum over GF(P) */ + ippsBigNumGetSize(sizeP, &bnSizeP); + /* size of BigNum over GF(R) */ + ippsBigNumGetSize(sizeR, &bnSizeR); + + /* size of montgomery engine over GF(P) */ + gsModEngineGetSize(feBitSize, DLP_MONT_POOL_LENGTH, &montSizeP); + + /* size of montgomery engine over GF(R) */ + gsModEngineGetSize(ordBitSize, DLP_MONT_POOL_LENGTH, &montSizeR); + + /* size of prime engine */ + ippsPrimeGetSize(feBitSize, &primeGenSize); + + /* size of big num list (big num in the list preserve 32 bit word) */ + bn_resourceSize = cpBigNumListGetSize(feBitSize+1, BNLISTSIZE); + + /* allocate buffers */ + ptr += sizeof(IppsDLPState); + DLP_MONTP0(pDL) = (gsModEngine*)(ptr); + ptr += montSizeP; + DLP_MONTP1(pDL) = 0; + DLP_MONTR(pDL) = (gsModEngine*)(ptr); + ptr += montSizeR; + + DLP_GENC(pDL) = (IppsBigNumState*)(ptr); + ptr += bnSizeP; + DLP_X(pDL) = (IppsBigNumState*)(ptr); + ptr += bnSizeR; + DLP_YENC(pDL) = (IppsBigNumState*)(ptr); + ptr += bnSizeP; + + DLP_PRIMEGEN(pDL)= (IppsPrimeState*)(ptr); + ptr += primeGenSize; + + DLP_METBL(pDL) = (BNU_CHUNK_T*)( IPP_ALIGNED_PTR(ptr, CACHE_LINE_SIZE) ); + ptr += sizeMeTable; + + DLP_BNCTX(pDL) = (BigNumNode*)(ptr); + ptr += bn_resourceSize; + + #if defined(_USE_WINDOW_EXP_) + DLP_BNUCTX0(pDL) = 0; + DLP_BNUCTX1(pDL) = 0; + DLP_BNUCTX0(pDL) = window>1? (BNU_CHUNK_T*)( IPP_ALIGNED_PTR(ptr, (int)sizeof(BNU_CHUNK_T)) ) : 0; + #endif + + /* init buffers */ + gsModEngineInit(DLP_MONTP0(pDL), NULL, feBitSize, DLP_MONT_POOL_LENGTH, gsModArithDLP()); + + gsModEngineInit(DLP_MONTR(pDL), NULL, ordBitSize, DLP_MONT_POOL_LENGTH, gsModArithDLP()); + + ippsBigNumInit(sizeP, DLP_GENC(pDL)); + ippsBigNumInit(sizeP, DLP_YENC(pDL)); + ippsBigNumInit(sizeR, DLP_X(pDL)); + + ippsPrimeInit(feBitSize, DLP_PRIMEGEN(pDL)); + + cpBigNumListInit(feBitSize+1, BNLISTSIZE, DLP_BNCTX(pDL)); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlppack.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlppack.c new file mode 100644 index 000000000..745cca509 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlppack.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Field (initialization) +// +// Contents: +// ippsDLPPack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcptool.h" + +/*F* +// Name: ippsDLPPack +// +// Purpose: Copy initialized context to the buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pCtx == NULL +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer DLP ctx +// pSize pointer to the packed spec size +// +*F*/ +IPPFUN(IppStatus, ippsDLPPack,(const IppsDLPState* pDL, Ipp8u* pBuffer)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pDL, pBuffer); + /* test the context */ + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + cpPackDLPCtx(pDL, pBuffer); + IppsDLPState* pCopy = (IppsDLPState*)pBuffer; + DLP_RESET_ID(pCopy); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlppublickey.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlppublickey.c new file mode 100644 index 000000000..279a6a96d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlppublickey.c @@ -0,0 +1,103 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (EC Key Generation, Validation and Set Up) +// +// Contents: +// ippsDLPPublicKey() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + +/*F* +// Name: ippsDLPPublicKey +// +// Purpose: Compute DL public key +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDL +// NULL == pPrvKey +// NULL == pPubKey +// +// ippStsContextMatchErr invalid pDL->idCtx +// invalid pPrvKey->idCtx +// invalid pPubKey->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsInvalidPrivateKey !(0 < pPrivate < DLP_R()) +// +// ippStsRangeErr not enough room for pPubKey +// +// ippStsNoErr no error +// +// Parameters: +// pPrvKey pointer to the private key +// pPubKey pointer to the public key +// pDL pointer to the DL context +*F*/ +IPPFUN(IppStatus, ippsDLPPublicKey,(const IppsBigNumState* pPrvKey, + IppsBigNumState* pPubKey, + IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test private/public keys */ + IPP_BAD_PTR2_RET(pPrvKey, pPubKey); + IPP_BADARG_RET(!BN_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pPubKey), ippStsContextMatchErr); + + /* test private key */ + IPP_BADARG_RET((0<=cpBN_cmp(cpBN_OneRef(), pPrvKey))|| + (0<=cpCmp_BNU(BN_NUMBER(pPrvKey),BN_SIZE(pPrvKey), DLP_R(pDL),BITS_BNU_CHUNK(DLP_BITSIZER(pDL)))), ippStsInvalidPrivateKey); + + /* test public key's room */ + IPP_BADARG_RET(BN_ROOM(pPubKey)idCtx +// illegal pPubKey->idCtx +// illegal pSecret->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsRangeErr no room for pSecret +// +// ippStsNoErr no errors +// +// Parameters: +// pPrvKeyA pointer to the own private key +// pPubKeyB pointer to the partner's public key +// pSecret pointer to the secret value +// pDL pointer to the DL context +*F*/ +IPPFUN(IppStatus, ippsDLPSharedSecretDH,(const IppsBigNumState* pPrvKeyA, + const IppsBigNumState* pPubKeyB, + IppsBigNumState* pSecret, + IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test public key */ + IPP_BAD_PTR1_RET(pPrvKeyA); + IPP_BADARG_RET(!BN_VALID_ID(pPrvKeyA), ippStsContextMatchErr); + + /* test public key */ + IPP_BAD_PTR1_RET(pPubKeyB); + IPP_BADARG_RET(!BN_VALID_ID(pPubKeyB), ippStsContextMatchErr); + + /* test secret */ + IPP_BAD_PTR1_RET(pSecret); + IPP_BADARG_RET(!BN_VALID_ID(pSecret), ippStsContextMatchErr); + IPP_BADARG_RET(BITS_BNU_CHUNK(DLP_BITSIZEP(pDL))>BN_ROOM(pSecret), ippStsRangeErr); + + cpMontEnc_BN(pSecret, pPubKeyB, DLP_MONTP0(pDL)); + + { + gsModEngine* pMEorder = DLP_MONTR(pDL); + int ordLen = MOD_LEN(pMEorder); + + /* expand privKeyA */ + BigNumNode* pList = DLP_BNCTX(pDL); + IppsBigNumState* pTmpPrivKey = cpBigNumListGet(&pList); + ZEXPAND_COPY_BNU(BN_NUMBER(pTmpPrivKey), ordLen, BN_NUMBER(pPrvKeyA), BN_SIZE(pPrvKeyA)); + BN_SIZE(pTmpPrivKey) = ordLen; + + #if !defined(_USE_WINDOW_EXP_) + cpMontExpBin_BN_sscm(pSecret, pSecret, pTmpPrivKey, DLP_MONTP0(pDL)); + #else + (DLP_EXPMETHOD(pDL)==BINARY) || (1==cpMontExp_WinSize(BITSIZE_BNU(BN_NUMBER(pTmpPrivKey), BN_SIZE(pTmpPrivKey))))? + cpMontExpBin_BN_sscm(pSecret, pSecret, pTmpPrivKey, DLP_MONTP0(pDL)) : + cpMontExpWin_BN_sscm(pSecret, pSecret, pTmpPrivKey, DLP_MONTP0(pDL), DLP_BNUCTX0(pDL)); + #endif + + cpMontDec_BN(pSecret, pSecret, DLP_MONTP0(pDL)); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpset.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpset.c new file mode 100644 index 000000000..68dd7d354 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpset.c @@ -0,0 +1,109 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsDLPSet() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + +/*F* +// Name: ippsDLPSet +// +// Purpose: Set DL Domain Parameters. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pP +// NULL == pR +// NULL == pG +// NULL == pDL +// +// ippStsContextMatchErr illegal pP->idCtx +// illegal pR->idCtx +// illegal pG->idCtx +// illegal pDL->idCtx +// +// ippStsRangeErr not enough room for: +// pP, +// pR, +// pG +// +// errors produced by ippsMontSet() +// ippsMontForm() +// +// ippStsNoErr no errors +// +// Parameters: +// pP pointer to the DL domain parameter (P) +// pR pointer to the DL domain parameter (R) +// pG pointer to the DL domain parameter (G) +// pDSA pointer to the DL context +// +*F*/ +IPPFUN(IppStatus, ippsDLPSet,(const IppsBigNumState* pP, + const IppsBigNumState* pR, + const IppsBigNumState* pG, + IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test DL domain parameters */ + IPP_BAD_PTR3_RET(pP, pR, pG); + IPP_BADARG_RET(!BN_VALID_ID(pP), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pG), ippStsContextMatchErr); + + /* test size of DL domain parameters */ + IPP_BADARG_RET(BN_SIZE(pP)>BITS_BNU_CHUNK(DLP_BITSIZEP(pDL)), ippStsRangeErr); + IPP_BADARG_RET(BN_SIZE(pR)>BITS_BNU_CHUNK(DLP_BITSIZER(pDL)), ippStsRangeErr); + IPP_BADARG_RET(BN_SIZE(pG)>BITS_BNU_CHUNK(DLP_BITSIZEP(pDL)), ippStsRangeErr); + + /* + // set up DL domain parameters + */ + { + IppStatus sts; + + DLP_FLAG(pDL) = 0; + + cpBN_zero(DLP_X(pDL)); + cpBN_zero(DLP_YENC(pDL)); + + sts = gsModEngineInit(DLP_MONTP0(pDL), (Ipp32u*)BN_NUMBER(pP), cpBN_bitsize(pP), DLP_MONT_POOL_LENGTH, gsModArithDLP()); + + if(ippStsNoErr==sts) { + sts = gsModEngineInit(DLP_MONTR(pDL), (Ipp32u*)BN_NUMBER(pR), cpBN_bitsize(pR), DLP_MONT_POOL_LENGTH, gsModArithDLP()); + if(ippStsNoErr==sts) { + cpMontEnc_BN(DLP_GENC(pDL), pG, DLP_MONTP0(pDL)); + DLP_FLAG(pDL) = ippDLPkeyP|ippDLPkeyR|ippDLPkeyG; + return ippStsNoErr; + } + } + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpsetdp.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpsetdp.c new file mode 100644 index 000000000..284335d04 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpsetdp.c @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsDLPSetDP() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + +/*F* +// Name: ippsDLPSetDP +// +// Purpose: Set tagged DL Domain Parameter. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDP +// NULL == pDL +// +// ippStsContextMatchErr illegal pDP->idCtx +// illegal pDL->idCtx +// +// ippStsRangeErr not enough room for pDP +// +// ippStsBadArgErr invalid key tag +// +// errors produced by ippsMontSet() +// ippsMontForm() +// +// ippStsNoErr no errors +// +// Parameters: +// pDP pointer to the DL domain parameter +// tag DLP key component tag +// pDL pointer to the DL context +// +*F*/ +IPPFUN(IppStatus, ippsDLPSetDP,(const IppsBigNumState* pDP, IppDLPKeyTag tag, IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test DL parameter to be set */ + IPP_BAD_PTR1_RET(pDP); + IPP_BADARG_RET(!BN_VALID_ID(pDP), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pDP), ippStsBadArgErr); + + { + IppStatus sts = ippStsNoErr; + + cpBN_zero(DLP_X(pDL)); + cpBN_zero(DLP_YENC(pDL)); + + switch(tag) { + case ippDLPkeyP: + DLP_FLAG(pDL) &=(Ipp32u)~ippDLPkeyP; + sts = gsModEngineInit(DLP_MONTP0(pDL), (Ipp32u*)BN_NUMBER(pDP), cpBN_bitsize(pDP), DLP_MONT_POOL_LENGTH, gsModArithDLP()); + if(ippStsNoErr==sts) { + DLP_FLAG(pDL) |= ippDLPkeyP; + } + break; + case ippDLPkeyR: + DLP_FLAG(pDL) &=(Ipp32u)~ippDLPkeyR; + sts = gsModEngineInit(DLP_MONTR(pDL), (Ipp32u*)BN_NUMBER(pDP), cpBN_bitsize(pDP), DLP_MONT_POOL_LENGTH, gsModArithDLP()); + if(ippStsNoErr==sts) + DLP_FLAG(pDL) |= ippDLPkeyR; + break; + case ippDLPkeyG: + DLP_FLAG(pDL) &=(Ipp32u)~ippDLPkeyG; + if(DLP_FLAG(pDL)&ippDLPkeyP) { + cpMontEnc_BN(DLP_GENC(pDL), pDP, DLP_MONTP0(pDL)); + DLP_FLAG(pDL) |= ippDLPkeyG; + } + else + sts = ippStsIncompleteContextErr; + break; + default: + sts = ippStsBadArgErr; + } + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpsetkeypair.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpsetkeypair.c new file mode 100644 index 000000000..abb035944 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpsetkeypair.c @@ -0,0 +1,116 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (EC Key Generation, Validation and Set Up) +// +// Contents: +// ippsDLPSetKeyPair() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + +/*F* +// Name: ippsDSASetKeyPair +// +// Purpose: Set up Key Pair into the DL context +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDL +// NULL == pPrvKey +// NULL == pPubKey +// +// ippStsContextMatchErr invalid pDL->idCtx +// invalid pPrvKey->idCtx +// invalid pPubKey->idCtx +// +// ippStsIncompleteContextErr +// incomplete context: P and/or R and/or G is not set +// +// ippStsInvalidPrivateKey PrvKey >= R +// PrvKey < 0 +// +// ippStsRangeErr PubKey >= P +// PubKey < 0 +// +// ippStsNoErr no error +// +// Parameters: +// pPrvKey pointer to the private key +// pPubKey pointer to the public key +// pDL pointer to the DL context +*F*/ +IPPFUN(IppStatus, ippsDLPSetKeyPair,(const IppsBigNumState* pPrvKey, + const IppsBigNumState* pPubKey, + IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* set up private key */ + if(pPrvKey) { + IPP_BADARG_RET(!BN_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pPrvKey), ippStsInvalidPrivateKey); + { + gsModEngine* pMontR = DLP_MONTR(pDL); + BNU_CHUNK_T* pOrder = MOD_MODULUS(pMontR); + int ordLen = MOD_LEN(pMontR); + + BNU_CHUNK_T* pPriData = BN_NUMBER(pPrvKey); + int priLen = BN_SIZE(pPrvKey); + + /* make sure regular 0 < private < order */ + IPP_BADARG_RET(cpEqu_BNU_CHUNK(pPriData, priLen, 0) || + 0<=cpCmp_BNU(pPriData, priLen, pOrder, ordLen), ippStsInvalidPrivateKey); + + cpBN_copy(DLP_X(pDL), pPrvKey); + BN_SIZE(DLP_X(pDL)) = ordLen; + } + } + + /* set up public key */ + if(pPubKey) { + IPP_BADARG_RET(!BN_VALID_ID(pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pPubKey), ippStsRangeErr); + { + gsModEngine* pMontP = DLP_MONTP0(pDL); + BNU_CHUNK_T* pPrime = MOD_MODULUS(pMontP); + int primeLen = MOD_LEN(pMontP); + + BNU_CHUNK_T* pPubData = BN_NUMBER(pPubKey); + int pubLen = BN_SIZE(pPubKey); + + /* make sure regular 0 < public < prime */ + IPP_BADARG_RET(cpEqu_BNU_CHUNK(pPubData, pubLen, 0) || + 0<=cpCmp_BNU(pPubData, pubLen, pPrime, primeLen), ippStsRangeErr); + + cpMontEnc_BN(DLP_YENC(pDL), pPubKey, DLP_MONTP0(pDL)); + } + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpsigndsaca.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpsigndsaca.c new file mode 100644 index 000000000..c5ea3614d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpsigndsaca.c @@ -0,0 +1,193 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (Sign, DSA version) +// +// Contents: +// ippsDLPSignDSA() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsDLPSignDSA +// +// Purpose: Signing of message representative +// (DSA version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDL +// NULL == pPrvKey +// NULL == pMsgDigest +// NULL == pSignR +// NULL == pSignS +// +// ippStsContextMatchErr illegal pDL->idCtx +// illegal pPrvKey->idCtx +// illegal pMsgDigest->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsIncompleteContextErr +// incomplete context: P and/or R and/or G is not set +// +// ippStsMessageErr MsgDigest >= R +// MsgDigest < 0 +// +// ippStsInvalidPrivateKey PrvKey >= R +// PrvKey < 0 +// +// ippStsRangeErr not enough room for: +// signR +// signS +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pPevKey pointer to the (signatory's) regular private key +// pSignR,pSignS pointer to the signature +// pDL pointer to the DL context +// +// Primitive sequence call: +// 1) set up domain parameters +// 2) generate (signatory's) ephemeral key pair +// 3) set up (signatory's) ephemeral key pair +// 4) use primitive with (signatory's) private key +*F*/ +IPPFUN(IppStatus, ippsDLPSignDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pSignR, + IppsBigNumState* pSignS, + IppsDLPState *pDL)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test message representative */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pMsgDigest), ippStsMessageErr); + + /* test regular private key */ + IPP_BAD_PTR1_RET(pPrvKey); + IPP_BADARG_RET(!BN_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pPrvKey), ippStsInvalidPrivateKey); + + /* test signature */ + IPP_BAD_PTR2_RET(pSignR,pSignS); + IPP_BADARG_RET(!BN_VALID_ID(pSignR), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pSignS), ippStsContextMatchErr); + IPP_BADARG_RET(BITSIZE(BNU_CHUNK_T)*BN_ROOM(pSignR)decode(buffer, buffer, pMontP); + ns = cpMod_BNU(buffer, elmLen, pOrder, ordLen); + ZEXPAND_COPY_BNU(dataR, ordLen, buffer, ns); + gsModPoolFree(pMontP, 1); + + if(!cpEqu_BNU_CHUNK(dataR, ordLen, 0)) { + /* + // signS = ((1/eX)*(MsgDigest + X*signR)) (mod R) + */ + + /* private representation in Montgomery domain */ + ZEXPAND_COPY_BNU(dataS, ordLen, pPriData, priLen); + MOD_METHOD(pMontR)->encode(dataS, dataS, pMontR); + + /* (X*signR) in regular domain */ + MOD_METHOD(pMontR)->mul(dataS, dataS, dataR, pMontR); + + /* pMsgDigest + (X*signR) */ + ZEXPAND_COPY_BNU(buffS, ordLen, pMsgData, msgLen); + cpModAdd_BNU(dataS, dataS, buffS, pOrder, ordLen, buffS); + + if(!cpEqu_BNU_CHUNK(dataS, ordLen, 0)) { + + ZEXPAND_COPY_BNU(buffS, ordLen, BN_NUMBER(DLP_X(pDL)), BN_SIZE(DLP_X(pDL))); + /* (1/eX) in Montgomery domain */ + gs_mont_inv(buffS, buffS, pMontR, alm_mont_inv_ct); + + /* signS = (1/eX)*(MsgDigest + X*signR) */ + MOD_METHOD(pMontR)->mul(dataS, dataS, buffS, pMontR); + + /* signR */ + ns = ordLen; + FIX_BNU(dataR, ns); + BN_SIGN(pSignR) = ippBigNumPOS; + BN_SIZE(pSignR) = ns; + /* signS */ + ns = ordLen; + FIX_BNU(dataS, ns); + BN_SIGN(pSignS) = ippBigNumPOS; + BN_SIZE(pSignS) = ns; + + return ippStsNoErr; + } + } + + return ippStsEphemeralKeyErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpunpack.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpunpack.c new file mode 100644 index 000000000..4824ac2fb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpunpack.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Field (initialization) +// +// Contents: +// ippsDLPUnpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcptool.h" + +/*F* +// Name: ippsDLPUnpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pCtx == NULL +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer DLP ctx +// pSize pointer to the packed spec size +// +*F*/ +IPPFUN(IppStatus, ippsDLPUnpack,(const Ipp8u* pBuffer, IppsDLPState* pDL)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pDL, pBuffer); + + cpUnpackDLPCtx(pBuffer, pDL); + DLP_SET_ID(pDL); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatedh.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatedh.c new file mode 100644 index 000000000..a6e8132f8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatedh.c @@ -0,0 +1,208 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (validate domain parameters) +// +// Contents: +// ippsDLPValidateDH() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + + +/* +// Name: DLPValidate +// +// Purpose: Validate DL Domain Parameters. +// +// Parameters: +// nTrials number of trials of primality test +// pResult pointer to the validation result +// pDL pointer to the DL context +// rndFunc external random generator +// pRndParam pointer to the external random generator params +*/ +static +IppDLResult DLPValidate(int nTrials, IppsDLPState* pDL, + IppBitSupplier rndFunc, void* pRndParam) +{ + /* + // validate DL parameters: + // check that P is odd and P > 2 + // check that R is odd and R > 2 + // check that R | (P-1) + // check that 1 < G < P + // check that 1 == G^R (mod P) + */ + + BNU_CHUNK_T* pP = DLP_P(pDL); + BNU_CHUNK_T* pR = DLP_R(pDL); + cpSize lenP = BITS_BNU_CHUNK(DLP_BITSIZEP(pDL)); + cpSize lenR = BITS_BNU_CHUNK(DLP_BITSIZER(pDL)); + + IppsPrimeState* pPrimeCtx = DLP_PRIMEGEN(pDL); + + /* allocate BN resources */ + BigNumNode* pList = DLP_BNCTX(pDL); + IppsBigNumState* pTmp = cpBigNumListGet(&pList); + BNU_CHUNK_T* pT = BN_NUMBER(pTmp); + + /* P is odd and prime */ + if(0 == (pP[0] & 1)) + return ippDLBaseIsEven; + if(0==cpPrimeTest(pP, lenP, nTrials, pPrimeCtx, rndFunc,pRndParam)) + return ippDLCompositeBase; + + /* R is odd and prime */ + if(0 == (pR[0] & 1)) + return ippDLOrderIsEven; + if(0==cpPrimeTest(pR, lenR, nTrials, pPrimeCtx, rndFunc,pRndParam)) + return ippDLCompositeOrder; + + /* R|(P-1) */ + cpDec_BNU(pT, pP, lenP, 1); + cpMod_BNU(pT, lenP, pR, lenR); + if(!cpEqu_BNU_CHUNK(pT, lenP, 0)) + return ippDLInvalidCofactor; + + /* 1 < G < P */ + cpMontDec_BN(pTmp, DLP_GENC(pDL), DLP_MONTP0(pDL)); + if( 0>=cpBN_cmp(pTmp, cpBN_OneRef()) || cpCmp_BNU(pT, BN_SIZE(pTmp), DLP_P(pDL), lenP)>=0 ) + return ippDLInvalidGenerator; + + /* G^R = 1 (mod P) */ + cpMontExpBin_BNU(pT, BN_NUMBER(DLP_GENC(pDL)),lenP, pR, lenR, DLP_MONTP0(pDL) ); + if( cpCmp_BNU(pT,lenP, MOD_MNT_R(DLP_MONTP0(pDL)), lenP) ) + return ippDLInvalidGenerator; + + return ippDLValid; +} + +/*F* +// Name: ippsDLPValidateDH +// +// Purpose: Validate DL (DH) Domain Parameters. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDL +// NULL == pResult +// NULL == rndFunc +// +// ippStsContextMatchErr illegal pDL->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsBadArgErr nTrials <=0 +// +// ippStsNoErr no errors +// +// Parameters: +// nTrials number of trials of primality test +// pResult pointer to the validation result +// pDL pointer to the DL context +// rndFunc external random generator +// pRndParam pointer to the external random generator params +*F*/ +IPPFUN(IppStatus, ippsDLPValidateDH,(int nTrials, IppDLResult* pResult, IppsDLPState* pDL, + IppBitSupplier rndFunc, void* pRndParam)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test operation flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test number of trials for primality check */ + IPP_BADARG_RET(nTrials<=0, ippStsBadArgErr); + + /* test another pointers */ + IPP_BAD_PTR3_RET(pResult, rndFunc, pRndParam); + + /* execute genetal DL validation */ + *pResult = DLPValidate(nTrials, pDL, rndFunc, pRndParam); + + /* + // DH specific validation + */ + if(ippDLValid == *pResult) { + /* allocate BN resources */ + BigNumNode* pList = DLP_BNCTX(pDL); + IppsBigNumState* pT = cpBigNumListGet(&pList); + + BNU_CHUNK_T* pP = DLP_P(pDL); + BNU_CHUNK_T* pR = DLP_R(pDL); + cpSize feBitSize = DLP_BITSIZEP(pDL); + cpSize ordBitSize= DLP_BITSIZER(pDL); + cpSize lenP = BITS_BNU_CHUNK(feBitSize); + cpSize lenR = BITS_BNU_CHUNK(ordBitSize); + + /* DLP_BITSIZEP() >= 512, 256|DLP_BITSIZEP() */ + if( (MIN_DLPDH_BITSIZE > feBitSize) || + (feBitSize % 256) ) { + *pResult = ippDLInvalidBaseRange; + return ippStsNoErr; + } + + /* 2^(DLP_BITSIZEP()-1) < P < 2^DLP_BITSIZEP() */ + cpBN_power2(pT, feBitSize-1); + if( 0<=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pP,lenP) ) { + *pResult = ippDLInvalidBaseRange; + return ippStsNoErr; + } + cpBN_power2(pT, feBitSize); + if( 0>=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pP,lenP) ) { + *pResult = ippDLInvalidBaseRange; + return ippStsNoErr; + } + + /* DLP_BITSIZER() >= 160 */ + if( (MIN_DLPDH_BITSIZER > ordBitSize) ) { + *pResult = ippDLInvalidOrderRange; + return ippStsNoErr; + } + /* 2^(DLP_BITSIZER()-1) < R < 2^DLP_BITSIZER() */ + cpBN_power2(pT, ordBitSize-1); + if( 0<=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pR,lenR) ) { + *pResult = ippDLInvalidOrderRange; + return ippStsNoErr; + } + cpBN_power2(pT, ordBitSize); + if( 0>=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pR,lenR) ) { + *pResult = ippDLInvalidOrderRange; + return ippStsNoErr; + } + + /* 1 < G < (P-1) */ + cpMontDec_BN(pT, DLP_GENC(pDL), DLP_MONTP0(pDL)); + if( !(0 < cpBN_cmp(pT, cpBN_OneRef()) && + 0 > cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pP,lenP)) ) { + *pResult = ippDLInvalidGenerator; + return ippStsNoErr; + } + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatedsa.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatedsa.c new file mode 100644 index 000000000..a36c366c9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatedsa.c @@ -0,0 +1,208 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (validate domain parameters) +// +// Contents: +// ippsDLPValidateDSA() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + + +/* +// Name: DLPValidate +// +// Purpose: Validate DL Domain Parameters. +// +// Parameters: +// nTrials number of trials of primality test +// pResult pointer to the validation result +// pDL pointer to the DL context +// rndFunc external random generator +// pRndParam pointer to the external random generator params +*/ +static +IppDLResult DLPValidate(int nTrials, IppsDLPState* pDL, + IppBitSupplier rndFunc, void* pRndParam) +{ + /* + // validate DL parameters: + // check that P is odd and P > 2 + // check that R is odd and R > 2 + // check that R | (P-1) + // check that 1 < G < P + // check that 1 == G^R (mod P) + */ + + BNU_CHUNK_T* pP = DLP_P(pDL); + BNU_CHUNK_T* pR = DLP_R(pDL); + cpSize lenP = BITS_BNU_CHUNK(DLP_BITSIZEP(pDL)); + cpSize lenR = BITS_BNU_CHUNK(DLP_BITSIZER(pDL)); + + IppsPrimeState* pPrimeCtx = DLP_PRIMEGEN(pDL); + + /* allocate BN resources */ + BigNumNode* pList = DLP_BNCTX(pDL); + IppsBigNumState* pTmp = cpBigNumListGet(&pList); + BNU_CHUNK_T* pT = BN_NUMBER(pTmp); + + /* P is odd and prime */ + if(0 == (pP[0] & 1)) + return ippDLBaseIsEven; + if(0==cpPrimeTest(pP, lenP, nTrials, pPrimeCtx, rndFunc,pRndParam)) + return ippDLCompositeBase; + + /* R is odd and prime */ + if(0 == (pR[0] & 1)) + return ippDLOrderIsEven; + if(0==cpPrimeTest(pR, lenR, nTrials, pPrimeCtx, rndFunc,pRndParam)) + return ippDLCompositeOrder; + + /* R|(P-1) */ + cpDec_BNU(pT, pP, lenP, 1); + cpMod_BNU(pT, lenP, pR, lenR); + if(!cpEqu_BNU_CHUNK(pT, lenP, 0)) + return ippDLInvalidCofactor; + + /* 1 < G < P */ + cpMontDec_BN(pTmp, DLP_GENC(pDL), DLP_MONTP0(pDL)); + if( 0>=cpBN_cmp(pTmp, cpBN_OneRef()) || cpCmp_BNU(pT, BN_SIZE(pTmp), DLP_P(pDL), lenP)>=0 ) + return ippDLInvalidGenerator; + + /* G^R = 1 (mod P) */ + cpMontExpBin_BNU(pT, BN_NUMBER(DLP_GENC(pDL)),lenP, pR, lenR, DLP_MONTP0(pDL) ); + if( cpCmp_BNU(pT,lenP, MOD_MNT_R(DLP_MONTP0(pDL)), lenP) ) + return ippDLInvalidGenerator; + + return ippDLValid; +} + +/*F* +// Name: ippsDLPValidateDSA +// +// Purpose: Validate DL (DSA) Domain Parameters. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDL +// NULL == pResult +// NULL == rndFunc +// +// ippStsContextMatchErr illegal pDL->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsBadArgErr nTrials <=0 +// +// ippStsNoErr no errors +// +// Parameters: +// nTrials number of trials of primality test +// pResult pointer to the validation result +// pDL pointer to the DL context +// rndFunc external random generator +// pRndParam pointer to the external random generator params +*F*/ +IPPFUN(IppStatus, ippsDLPValidateDSA,(int nTrials, IppDLResult* pResult, IppsDLPState* pDL, + IppBitSupplier rndFunc, void* pRndParam)) +{ + /* test DL context */ + IPP_BAD_PTR1_RET(pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test operation flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test number of trials for primality check */ + IPP_BADARG_RET(nTrials<=0, ippStsBadArgErr); + + /* test another pointers */ + IPP_BAD_PTR2_RET(pResult, rndFunc); + + + /* execute genetal DL validation */ + *pResult = DLPValidate(nTrials, pDL, rndFunc, pRndParam); + + /* + // DSA specific validation + */ + if(ippDLValid == *pResult) { + /* allocate BN resources */ + BigNumNode* pList = DLP_BNCTX(pDL); + IppsBigNumState* pT = cpBigNumListGet(&pList); + + BNU_CHUNK_T* pP = DLP_P(pDL); + BNU_CHUNK_T* pR = DLP_R(pDL); + cpSize feBitSize = DLP_BITSIZEP(pDL); + cpSize ordBitSize= DLP_BITSIZER(pDL); + cpSize lenP = BITS_BNU_CHUNK(feBitSize); + cpSize lenR = BITS_BNU_CHUNK(ordBitSize); + + /* 512 <= DLP_BITSIZEP() <= 1024, 64|DLP_BITSIZEP() */ + if( (MIN_DLPDSA_BITSIZE > feBitSize) || (MAX_DLPDSA_BITSIZE < feBitSize) || + (feBitSize % 64) ) { + *pResult = ippDLInvalidBaseRange; + return ippStsNoErr; + } + /* 2^(DLP_BITSIZEP()-1) < P < 2^DLP_BITSIZEP() */ + cpBN_power2(pT, feBitSize-1); + if( 0<=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pP,lenP) ) { + *pResult = ippDLInvalidBaseRange; + return ippStsNoErr; + } + cpBN_power2(pT, feBitSize); + if( 0>=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pP,lenP) ) { + *pResult = ippDLInvalidBaseRange; + return ippStsNoErr; + } + + /* DLP_BITSIZER() == 160 */ + if( (DEF_DLPDSA_BITSIZER != ordBitSize) ) { + *pResult = ippDLInvalidOrderRange; + return ippStsNoErr; + } + /* 2^(DLP_BITSIZER()-1) < R < 2^DLP_BITSIZER() */ + cpBN_power2(pT, ordBitSize-1); + if( 0<=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pR,lenR) ) { + *pResult = ippDLInvalidOrderRange; + return ippStsNoErr; + } + cpBN_power2(pT, ordBitSize); + if( 0>=cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pR,lenR) ) { + *pResult = ippDLInvalidOrderRange; + return ippStsNoErr; + } + + /* 1 < G < (P-1) */ + cpMontDec_BN(pT, DLP_GENC(pDL), DLP_MONTP0(pDL)); + if( !(0 < cpBN_cmp(pT, cpBN_OneRef()) && + 0 > cpCmp_BNU(BN_NUMBER(pT),BN_SIZE(pT), pP,lenP)) ) { + *pResult = ippDLInvalidGenerator; + return ippStsNoErr; + } + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatekeypair.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatekeypair.c new file mode 100644 index 000000000..eaeeea9ea --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpvalidatekeypair.c @@ -0,0 +1,129 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (EC Key Generation, Validation and Set Up) +// +// Contents: +// ippsDLPValidateKeyPair() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + +/*F* +// Name: ippsDLPValidateKeyPair +// +// Purpose: Validate DL Key Pair +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDL +// NULL == pPrvKey +// NULL == pPubKey +// +// ippStsContextMatchErr invalid pDL->idCtx +// invalid pPrvKey->idCtx +// invalid pPubKey->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsNoErr no error +// +// Parameters: +// pPrvKey pointer to the private key +// pPubKey pointer to the public key +// pResult pointer to the result: ippDLValid/ +// ippDLInvalidPrivateKey/ippDLInvalidPublicKey/ +// ippDLInvalidKeyPair +// pDL pointer to the DL context +*F*/ +IPPFUN(IppStatus, ippsDLPValidateKeyPair,(const IppsBigNumState* pPrvKey, + const IppsBigNumState* pPubKey, + IppDLResult* pResult, + IppsDLPState* pDL)) +{ + /* test DL context */ + IPP_BAD_PTR2_RET(pResult, pDL); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + { + /* allocate BN resources */ + BigNumNode* pList = DLP_BNCTX(pDL); + IppsBigNumState* pTmp = cpBigNumListGet(&pList); + BNU_CHUNK_T* pT = BN_NUMBER(pTmp); + + /* assume keys are OK */ + *pResult = ippDLValid; + + /* private key validation request */ + if(pPrvKey) { + cpSize lenR = BITS_BNU_CHUNK(DLP_BITSIZER(pDL)); + IPP_BADARG_RET(!BN_VALID_ID(pPrvKey), ippStsContextMatchErr); + + /* test private key: 1 < pPrvKey < (R-1) */ + cpDec_BNU(pT, DLP_R(pDL),lenR, 1); + if( 0>=cpBN_cmp(pPrvKey, cpBN_OneRef()) || + cpCmp_BNU(BN_NUMBER(pPrvKey),BN_SIZE(pPrvKey), pT,lenR)>=0 ) { + *pResult = ippDLInvalidPrivateKey; + return ippStsNoErr; + } + } + + /* public key validation request */ + if(pPubKey) { + cpSize lenP = BITS_BNU_CHUNK(DLP_BITSIZEP(pDL)); + IPP_BADARG_RET(!BN_VALID_ID(pPubKey), ippStsContextMatchErr); + + /* test public key: 1 < pPubKey < (P-1) */ + cpDec_BNU(pT, DLP_P(pDL),lenP, 1); + if( 0>=cpBN_cmp(pPubKey, cpBN_OneRef()) || + cpCmp_BNU(BN_NUMBER(pPubKey),BN_SIZE(pPubKey), pT,lenP)>=0 ) { + *pResult = ippDLInvalidPublicKey; + return ippStsNoErr; + } + + /* addition test: pPubKey = G^pPrvKey (mod P) */ + if(pPrvKey) { + int ordLen = MOD_LEN( DLP_MONTR(pDL) ); + IppsBigNumState* pTmpPrivate = cpBigNumListGet(&pList); + ZEXPAND_COPY_BNU(BN_NUMBER(pTmpPrivate), ordLen, BN_NUMBER(pPrvKey), BN_SIZE(pPrvKey)); + BN_SIZE(pTmpPrivate) = ordLen; + + /* recompute public key */ + cpMontExpBin_BN_sscm(pTmp, DLP_GENC(pDL), pTmpPrivate, DLP_MONTP0(pDL)); + cpMontDec_BN(pTmp, pTmp, DLP_MONTP0(pDL)); + + /* and compare */ + if( cpBN_cmp(pTmp, pPubKey) ) { + *pResult = ippDLInvalidKeyPair; + return ippStsNoErr; + } + } + } + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpdlpverifydsaca.c b/plugin/ippcp/library/src/sources/ippcp/pcpdlpverifydsaca.c new file mode 100644 index 000000000..6bfd7592c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpdlpverifydsaca.c @@ -0,0 +1,185 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Finite Field (Verify, DSA version) +// +// Contents: +// ippsDLPVerifyDSA() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" + + +/*F* +// Name: ippsDLPVerifyDSA +// +// Purpose: Verify Signature (DSA version) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pDL +// NULL == pMsgDigest +// NULL == pSignR +// NULL == pSignS +// NULL == pResult +// +// ippStsContextMatchErr illegal pDL->idCtx +// illegal pMsgDigest->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsIncompleteContextErr +// incomplete context +// +// ippStsMessageErr MsgDigest >= R +// MsgDigest < 0 +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pSignR,pSignS pointer to the signature +// pResult pointer to the result: IppSignIsValid/IppSignIsInvalid +// pDSA pointer to the DL context +// +// Primitive sequence call: +// 1) set up domain parameters +// 2) set up (signatory's) public key +*F*/ + +IPPFUN(IppStatus, ippsDLPVerifyDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppDLResult* pResult, + IppsDLPState* pDL)) +{ + /* test context*/ + IPP_BAD_PTR2_RET(pDL,pResult); + IPP_BADARG_RET(!DLP_VALID_ID(pDL), ippStsContextMatchErr); + + /* test operation flag */ + IPP_BADARG_RET(!DLP_COMPLETE(pDL), ippStsIncompleteContextErr); + + /* test message representative */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pMsgDigest), ippStsMessageErr); + + /* test signature */ + IPP_BAD_PTR2_RET(pSignR,pSignS); + IPP_BADARG_RET(!BN_VALID_ID(pSignR), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pSignS), ippStsContextMatchErr); + + /* test signature range */ + if(0idCtx +// illegal pA->idCtx +// illegal pB->idCtx +// illegal pGX->idCtx +// illegal pGY->idCtx +// illegal pOrder->idCtx +// illegal pECC->idCtx +// +// ippStsRangeErr not enough room for: +// pPrime +// pA, pB, +// pGX,pGY +// pOrder +// +// ippStsRangeErr 0>= cofactor +// +// ippStsNoErr no errors +// +// Parameters: +// pPrime pointer to the prime (specify FG(p)) +// pA pointer to the A coefficient of EC equation +// pB pointer to the B coefficient of EC equation +// pGX,pGY pointer to the Base Point (x and y coordinates) of EC +// pOrder pointer to the Base Point order +// cofactor cofactor value +// pECC pointer to the ECC context +// +*F*/ +IPP_OWN_DEFN (IppStatus, ECCPSetDP, (const IppsGFpMethod* method, int pLen, const BNU_CHUNK_T* pP, int aLen, const BNU_CHUNK_T* pA, int bLen, const BNU_CHUNK_T* pB, int xLen, const BNU_CHUNK_T* pX, int yLen, const BNU_CHUNK_T* pY, int rLen, const BNU_CHUNK_T* pR, BNU_CHUNK_T h, IppsGFpECState* pEC)) +{ + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + { + IppsGFpState * pGF = ECP_GFP(pEC); + + IppStatus sts = ippStsNoErr; + __ALIGN8 IppsBigNumState P; + __ALIGN8 IppsBigNumState H; + int primeBitSize = BITSIZE_BNU(pP, pLen); + //cpConstructBN(&P, pLen, (BNU_CHUNK_T*)pP, NULL); + //sts = cpGFpSetGFp(&P, primeBitSize, method, pGF); + cpGFpSetGFp(pP, primeBitSize, method, pGF); + + if(ippStsNoErr==sts) { + gsModEngine* pGFE = GFP_PMA(pGF); + + do { + int elemLen = GFP_FELEN(pGFE); + IppsGFpElement elmA, elmB; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + sts = ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + if(ippStsNoErr!=sts) break; + sts = ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + if(ippStsNoErr!=sts) break; + /* and set EC */ + sts = ippsGFpECSet(&elmA, &elmB, pEC); + if(ippStsNoErr!=sts) break; + + /* convert GX ans GY coeffs into GF elements */ + cpConstructBN(&P, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + sts = ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + if(ippStsNoErr!=sts) break; + sts = ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + if(ippStsNoErr!=sts) break; + /* and init EC subgroup */ + sts = ippsGFpECSetSubgroup(&elmA, &elmB, &P, &H, pEC); + } while(0); + + cpGFpReleasePool(2, pGFE); + } + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccp.h b/plugin/ippcp/library/src/sources/ippcp/pcpeccp.h new file mode 100644 index 000000000..26b9533bc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccp.h @@ -0,0 +1,190 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal ECC (prime) basic Definitions & Function Prototypes +// +// +*/ + +#if !defined(_NEW_PCP_ECCP_H) +#define _NEW_PCP_ECCP_H + +#include "pcpgfpecstuff.h" + + +__INLINE IppsBigNumState* cpConstructBN(IppsBigNumState* pBN, cpSize len, BNU_CHUNK_T* pData, BNU_CHUNK_T* pBuffer) +{ + BN_SET_ID(pBN); + BN_SIGN(pBN) = ippBigNumPOS; + BN_SIZE(pBN) = len; + BN_ROOM(pBN) = len; + BN_NUMBER(pBN) = pData; + BN_BUFFER(pBN) = pBuffer; + return pBN; +} + +/* set EC parameters */ +#define ECCPSetDP OWNAPI(ECCPSetDP) + IPP_OWN_DECL (IppStatus, ECCPSetDP, (const IppsGFpMethod* method, int pLen, const BNU_CHUNK_T* pP, int aLen, const BNU_CHUNK_T* pA, int bLen, const BNU_CHUNK_T* pB, int xLen, const BNU_CHUNK_T* pX, int yLen, const BNU_CHUNK_T* pY, int rLen, const BNU_CHUNK_T* pR, BNU_CHUNK_T h, IppsGFpECState* pEC)) + +/* +// Recommended (Standard) Domain Parameters +*/ +extern const BNU_CHUNK_T secp112r1_p[]; // (2^128 -3)/76439 +extern const BNU_CHUNK_T secp112r1_a[]; +extern const BNU_CHUNK_T secp112r1_b[]; +extern const BNU_CHUNK_T secp112r1_gx[]; +extern const BNU_CHUNK_T secp112r1_gy[]; +extern const BNU_CHUNK_T secp112r1_r[]; +extern BNU_CHUNK_T secp112r1_h; + +extern const BNU_CHUNK_T secp112r2_p[]; // (2^128 -3)/76439 +extern const BNU_CHUNK_T secp112r2_a[]; +extern const BNU_CHUNK_T secp112r2_b[]; +extern const BNU_CHUNK_T secp112r2_gx[]; +extern const BNU_CHUNK_T secp112r2_gy[]; +extern const BNU_CHUNK_T secp112r2_r[]; +extern BNU_CHUNK_T secp112r2_h; + +extern const BNU_CHUNK_T secp128r1_p[]; // 2^128 -2^97 -1 +extern const BNU_CHUNK_T secp128r1_a[]; +extern const BNU_CHUNK_T secp128r1_b[]; +extern const BNU_CHUNK_T secp128r1_gx[]; +extern const BNU_CHUNK_T secp128r1_gy[]; +extern const BNU_CHUNK_T secp128r1_r[]; +extern BNU_CHUNK_T secp128r1_h; + +extern const BNU_CHUNK_T* secp128_mx[]; + +extern const BNU_CHUNK_T secp128r2_p[]; // 2^128 -2^97 -1 +extern const BNU_CHUNK_T secp128r2_a[]; +extern const BNU_CHUNK_T secp128r2_b[]; +extern const BNU_CHUNK_T secp128r2_gx[]; +extern const BNU_CHUNK_T secp128r2_gy[]; +extern const BNU_CHUNK_T secp128r2_r[]; +extern BNU_CHUNK_T secp128r2_h; + +extern const BNU_CHUNK_T secp160r1_p[]; // 2^160 -2^31 -1 +extern const BNU_CHUNK_T secp160r1_a[]; +extern const BNU_CHUNK_T secp160r1_b[]; +extern const BNU_CHUNK_T secp160r1_gx[]; +extern const BNU_CHUNK_T secp160r1_gy[]; +extern const BNU_CHUNK_T secp160r1_r[]; +extern BNU_CHUNK_T secp160r1_h; + +extern const BNU_CHUNK_T secp160r2_p[]; // 2^160 -2^32 -2^14 -2^12 -2^9 -2^8 -2^7 -2^2 -1 +extern const BNU_CHUNK_T secp160r2_a[]; +extern const BNU_CHUNK_T secp160r2_b[]; +extern const BNU_CHUNK_T secp160r2_gx[]; +extern const BNU_CHUNK_T secp160r2_gy[]; +extern const BNU_CHUNK_T secp160r2_r[]; +extern BNU_CHUNK_T secp160r2_h; + +extern const BNU_CHUNK_T secp192r1_p[]; // 2^192 -2^64 -1 +extern const BNU_CHUNK_T secp192r1_a[]; +extern const BNU_CHUNK_T secp192r1_b[]; +extern const BNU_CHUNK_T secp192r1_gx[]; +extern const BNU_CHUNK_T secp192r1_gy[]; +extern const BNU_CHUNK_T secp192r1_r[]; +extern BNU_CHUNK_T secp192r1_h; + +extern const BNU_CHUNK_T secp224r1_p[]; // 2^224 -2^96 +1 +extern const BNU_CHUNK_T secp224r1_a[]; +extern const BNU_CHUNK_T secp224r1_b[]; +extern const BNU_CHUNK_T secp224r1_gx[]; +extern const BNU_CHUNK_T secp224r1_gy[]; +extern const BNU_CHUNK_T secp224r1_r[]; +extern BNU_CHUNK_T secp224r1_h; + +extern const BNU_CHUNK_T secp256r1_p[]; // 2^256 -2^224 +2^192 +2^96 -1 +extern const BNU_CHUNK_T secp256r1_a[]; +extern const BNU_CHUNK_T secp256r1_b[]; +extern const BNU_CHUNK_T secp256r1_gx[]; +extern const BNU_CHUNK_T secp256r1_gy[]; +extern const BNU_CHUNK_T secp256r1_r[]; +extern BNU_CHUNK_T secp256r1_h; + +extern const BNU_CHUNK_T secp384r1_p[]; // 2^384 -2^128 -2^96 +2^32 -1 +extern const BNU_CHUNK_T secp384r1_a[]; +extern const BNU_CHUNK_T secp384r1_b[]; +extern const BNU_CHUNK_T secp384r1_gx[]; +extern const BNU_CHUNK_T secp384r1_gy[]; +extern const BNU_CHUNK_T secp384r1_r[]; +extern BNU_CHUNK_T secp384r1_h; + +extern const BNU_CHUNK_T secp521r1_p[]; // 2^521 -1 +extern const BNU_CHUNK_T secp521r1_a[]; +extern const BNU_CHUNK_T secp521r1_b[]; +extern const BNU_CHUNK_T secp521r1_gx[]; +extern const BNU_CHUNK_T secp521r1_gy[]; +extern const BNU_CHUNK_T secp521r1_r[]; +extern BNU_CHUNK_T secp521r1_h; + +extern const BNU_CHUNK_T tpmBN_p256p_p[]; // TPM BN_P256 +extern const BNU_CHUNK_T tpmBN_p256p_a[]; +extern const BNU_CHUNK_T tpmBN_p256p_b[]; +extern const BNU_CHUNK_T tpmBN_p256p_gx[]; +extern const BNU_CHUNK_T tpmBN_p256p_gy[]; +extern const BNU_CHUNK_T tpmBN_p256p_r[]; +extern BNU_CHUNK_T tpmBN_p256p_h; + +extern const BNU_CHUNK_T tpmSM2_p256_p[]; // TPM SM2_P256 +extern const BNU_CHUNK_T tpmSM2_p256_a[]; +extern const BNU_CHUNK_T tpmSM2_p256_b[]; +extern const BNU_CHUNK_T tpmSM2_p256_gx[]; +extern const BNU_CHUNK_T tpmSM2_p256_gy[]; +extern const BNU_CHUNK_T tpmSM2_p256_r[]; +extern BNU_CHUNK_T tpmSM2_p256_h; + +extern const BNU_CHUNK_T* tpmSM2_p256_p_mx[]; + +/* half of some std modulus */ +extern const BNU_CHUNK_T h_secp128r1_p[]; +extern const BNU_CHUNK_T h_secp192r1_p[]; +extern const BNU_CHUNK_T h_secp224r1_p[]; +extern const BNU_CHUNK_T h_secp256r1_p[]; +extern const BNU_CHUNK_T h_secp384r1_p[]; +extern const BNU_CHUNK_T h_secp521r1_p[]; +extern const BNU_CHUNK_T h_tpmSM2_p256_p[]; + +__INLINE BNU_CHUNK_T* cpModAdd_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, + const BNU_CHUNK_T* pM, int ns, + BNU_CHUNK_T* pBuffer) +{ + BNU_CHUNK_T e = cpAdd_BNU(pR, pA, pB, ns); + e -= cpSub_BNU(pBuffer, pR, pM, ns); + MASKED_COPY_BNU(pR, e, pR, pBuffer, ns); + return pR; +} + +__INLINE BNU_CHUNK_T* cpModSub_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, + const BNU_CHUNK_T* pM, int ns, + BNU_CHUNK_T* pBuffer) +{ + BNU_CHUNK_T e = cpSub_BNU(pR, pA, pB, ns); + cpAdd_BNU(pBuffer, pR, pM, ns); + MASKED_COPY_BNU(pR, (0-e), pBuffer, pR, ns); + return pR; +} + +#endif /* _NEW_PCP_ECCP_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpaddpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpaddpoint.c new file mode 100644 index 000000000..37edbf931 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpaddpoint.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPAddPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPAddPoint +// +// Purpose: Perforn EC point operation: R = P+Q +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pP +// NULL == pQ +// NULL == pR +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pP->idCtx +// illegal pQ->idCtx +// illegal pR->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pP pointer to the source EC Point context +// pQ pointer to the source EC Point context +// pR pointer to the resultant EC Point context +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPAddPoint,(const IppsECCPPointState* pP, + const IppsECCPPointState* pQ, + IppsECCPPointState* pR, + IppsECCPState* pEC)) +{ + return ippsGFpECAddPoint(pP, pQ, pR, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd192r1.c new file mode 100644 index 000000000..53ce58d04 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd192r1.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPBindGxyTblStd192r1() +// +*/ + +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPBindGxyTblStd192r1 +// +// Purpose: Enable the use of base point-based pre-computed +// tables of standard elliptic curves for EC192r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ + +IPPFUN(IppStatus, ippsECCPBindGxyTblStd192r1,(IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + ECP_PREMULBP(pEC) = gfpec_precom_nistP192r1_fun(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd224r1.c new file mode 100644 index 000000000..2384ac7fc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd224r1.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPBindGxyTblStd224r1() +// +*/ + +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPBindGxyTblStd224r1 +// +// Purpose: Enable the use of base point-based pre-computed +// tables of standard elliptic curves for EC224r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ + +IPPFUN(IppStatus, ippsECCPBindGxyTblStd224r1,(IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + ECP_PREMULBP(pEC) = gfpec_precom_nistP224r1_fun(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd256r1.c new file mode 100644 index 000000000..a70d76fd8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd256r1.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPBindGxyTblStd256r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPBindGxyTblStd256r1 +// +// Purpose: Enable the use of base point-based pre-computed +// tables of standard elliptic curves for EC256r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ + +IPPFUN(IppStatus, ippsECCPBindGxyTblStd256r1,(IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + ECP_PREMULBP(pEC) = gfpec_precom_nistP256r1_fun(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd384r1.c new file mode 100644 index 000000000..97b59cb07 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd384r1.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPBindGxyTblStd384r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPBindGxyTblStd384r1 +// +// Purpose: Enable the use of base point-based pre-computed +// tables of standard elliptic curves for EC384r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ + +IPPFUN(IppStatus, ippsECCPBindGxyTblStd384r1,(IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + ECP_PREMULBP(pEC) = gfpec_precom_nistP384r1_fun(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd521r1.c new file mode 100644 index 000000000..04bd5a966 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstd521r1.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPBindGxyTblStd521r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPBindGxyTblStd521r1 +// +// Purpose: Enable the use of base point-based pre-computed +// tables of standard elliptic curves for EC521r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ + +IPPFUN(IppStatus, ippsECCPBindGxyTblStd521r1,(IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + ECP_PREMULBP(pEC) = gfpec_precom_nistP521r1_fun(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstdsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstdsm2.c new file mode 100644 index 000000000..9097f63ca --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpbindgxytblstdsm2.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPBindGxyTblStdSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPBindGxyTblStdSM2 +// +// Purpose: Enable the use of base point-based pre-computed +// tables of standard elliptic curves for ECSM2 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ + +IPPFUN(IppStatus, ippsECCPBindGxyTblStdSM2,(IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + ECP_PREMULBP(pEC) = gfpec_precom_sm2_fun(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpcheckpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpcheckpoint.c new file mode 100644 index 000000000..7799a8390 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpcheckpoint.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPCheckPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPCheckPoint +// +// Purpose: Check EC point: +// - is point lie on EC +// - is point at infinity +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pP +// NULL == pResult +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pP->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pPoint pointer to the EC Point context +// pEC pointer to the ECCP context +// pResult pointer to the result: +// ippECValid +// ippECPointIsNotValid +// ippECPointIsAtInfinite +// +*F*/ +IPPFUN(IppStatus, ippsECCPCheckPoint,(const IppsECCPPointState* pP, + IppECResult* pResult, + IppsECCPState* pEC)) +{ + return ippsGFpECTstPoint(pP, pResult, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpcomparepoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpcomparepoint.c new file mode 100644 index 000000000..85499cc56 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpcomparepoint.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPComparePoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPComparePoint +// +// Purpose: Compare two EC points +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pP +// NULL == pQ +// NULL == pResult +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pP->idCtx +// illegal pQ->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pP pointer to the EC Point context +// pQ pointer to the EC Point context +// pEC pointer to the EC context +// pResult pointer to the result: +// ippECPointIsEqual +// ippECPointIsNotEqual +// +*F*/ +IPPFUN(IppStatus, ippsECCPComparePoint,(const IppsECCPPointState* pP, + const IppsECCPPointState* pQ, + IppECResult* pResult, + IppsECCPState* pEC)) +{ + return ippsGFpECCmpPoint(pP, pQ, pResult, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgenkeyca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgenkeyca.c new file mode 100644 index 000000000..1058d64ad --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgenkeyca.c @@ -0,0 +1,108 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Key Generation) +// +// Contents: +// ippsECCPGenKeyPair() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPGenKeyPair +// +// Purpose: Generate (private,public) Key Pair +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivate +// NULL == pPublic +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pPrivate->idCtx +// illegal pPublic->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivate pointer to the resultant private key +// pPublic pointer to the resultant public key +// pEC pointer to the ECCP context +// rndFunc Specified Random Generator. +// pRndParam Pointer to the Random Generator context. +// +*F*/ +IPPFUN(IppStatus, ippsECCPGenKeyPair, (IppsBigNumState* pPrivate, IppsECCPPointState* pPublic, + IppsECCPState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR2_RET(pEC, rndFunc); + + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test private/public keys */ + IPP_BAD_PTR2_RET(pPrivate,pPublic); + IPP_BADARG_RET(!BN_VALID_ID(pPrivate), ippStsContextMatchErr); + IPP_BADARG_RET((BN_ROOM(pPrivate)*BITSIZE(BNU_CHUNK_T)idCtx +// illegal pA->idCtx +// illegal pB->idCtx +// illegal pGX->idCtx +// illegal pGY->idCtx +// illegal pOrder->idCtx +// illegal pEC->idCtx +// +// ippStsRangeErr not enough room for: +// pPrime +// pA, pB, +// pGX,pGY +// pOrder +// +// ippStsNoErr no errors +// +// Parameters: +// pPrime pointer to the retrieval prime (specify FG(p)) +// pA pointer to the retrieval A coefficient of EC equation +// pB pointer to the retrieval B coefficient of EC equation +// pGX,pGY pointer to the retrieval Base Point (x and y coordinates) of EC +// pOrder pointer to the retrieval Base Point order +// cofactor pointer to the retrieval cofactor value +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPGet, (IppsBigNumState* pPrime, + IppsBigNumState* pA, IppsBigNumState* pB, + IppsBigNumState* pGX,IppsBigNumState* pGY, + IppsBigNumState* pOrder, int* cofactor, + IppsECCPState* pEC)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + /* test pPrime */ + IPP_BAD_PTR1_RET(pPrime); + IPP_BADARG_RET(!BN_VALID_ID(pPrime), ippStsContextMatchErr); + IPP_BADARG_RET(BN_ROOM(pPrime)decode; /* gf decode method */ + BNU_CHUNK_T* tmp = cpGFpGetPool(1, pGFE); + + /* retrieve EC parameter */ + ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)GFP_MODULUS(pGFE), pPrime); + + decode(tmp, ECP_A(pEC), pGFE); + ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)tmp, pA); + decode(tmp, ECP_B(pEC), pGFE); + ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)tmp, pB); + + decode(tmp, ECP_G(pEC), pGFE); + ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)tmp, pGX); + decode(tmp, ECP_G(pEC)+GFP_FELEN(pGFE), pGFE); + ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)tmp, pGY); + + { + gsModEngine* pR = ECP_MONT_R(pEC); + ippsSet_BN(ippBigNumPOS, MOD_LEN(pR)*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)), (Ipp32u*)MOD_MODULUS(pR), pOrder); + } + + *cofactor = (int)ECP_COFACTOR(pEC)[0]; + + cpGFpReleasePool(1, pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetorderbitsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetorderbitsize.c new file mode 100644 index 000000000..f3e34bedb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetorderbitsize.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPGetOrderBitSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetOrderBitSize +// +// Purpose: Retrieve size of Base Point Order (in bits). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pBitSize +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pBitSize pointer to the size of base point order +// pEC pointer to the EC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPGetOrderBitSize,(int* pBitSize, IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test pBitSize*/ + IPP_BAD_PTR1_RET(pBitSize); + + *pBitSize = ECP_ORDBITSIZE(pEC); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetpoint.c new file mode 100644 index 000000000..84a08f9ee --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetpoint.c @@ -0,0 +1,105 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPGetPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetPoint +// +// Purpose: Converts internal presentation EC point - montgomery projective +// into regular affine coordinates EC point (pX,pY) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPoint +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pPoint->idCtx +// NULL != pX, illegal pX->idCtx +// NULL != pY, illegal pY->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pX pointer to the regular affine coordinate X +// pY pointer to the regular affine coordinate Y +// pPoint pointer to the EC Point context +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPGetPoint,(IppsBigNumState* pX, IppsBigNumState* pY, + const IppsECCPPointState* pPoint, + IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test pX and pY */ + if(pX) { + IPP_BADARG_RET(!BN_VALID_ID(pX), ippStsContextMatchErr); + } + if(pY) { + IPP_BADARG_RET(!BN_VALID_ID(pY), ippStsContextMatchErr); + } + + { + IppStatus sts; + + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_decode decode = GFP_METHOD(pGFE)->decode; /* gf decode method */ + + IppsGFpElement elmX, elmY; + + cpGFpElementConstruct(&elmX, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmY, cpGFpGetPool(1, pGFE), elemLen); + do { + sts = ippsGFpECGetPoint(pPoint, pX? &elmX:NULL, pY? &elmY:NULL, pEC); + if(ippStsNoErr!=sts) break; + + if(pX) { + decode(elmX.pData, elmX.pData, pGFE); + sts = ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)elmX.pData, pX); + if(ippStsNoErr!=sts) break; + } + if(pY) { + decode(elmY.pData, elmY.pData, pGFE); + sts = ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)elmY.pData, pY); + if(ippStsNoErr!=sts) break; + } + } while(0); + + cpGFpReleasePool(2, pGFE); + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsize.c new file mode 100644 index 000000000..8f8aa9394 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsize.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSize +// +// Purpose: Returns size of ECC context (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsSizeErr 2 > feBitSize +// feBitSize > EC_GFP_MAXBITSIZE +// ippStsNoErr no errors +// +// Parameters: +// feBitSize size of field element (bits) +// pSize pointer to the size of internal ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPGetSize, (int feBitSize, int *pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + /* test size of field element */ + IPP_BADARG_RET((2>feBitSize || feBitSize>EC_GFP_MAXBITSIZE), ippStsSizeErr); + + { + /* size of GF context */ + //int gfCtxSize = cpGFpGetSize(feBitSize); + int gfCtxSize = cpGFpGetSize(feBitSize, feBitSize+BITSIZE(BNU_CHUNK_T), GFP_POOL_SIZE); + /* size of EC context */ + int ecCtxSize = cpGFpECGetSize(1, feBitSize); + + /* size of EC scratch buffer: 16 points of BITS_BNU_CHUNK(feBitSize)*3 length each */ + int ecScratchBufferSize = 16*(BITS_BNU_CHUNK(feBitSize)*3)*(Ipp32s)sizeof(BNU_CHUNK_T); + + *pSize = ecCtxSize /* EC context */ + +gfCtxSize /* GF context */ + +ecScratchBufferSize /* *scratch buffer */ + +ecScratchBufferSize /* should be enough for 2 tables */ + +CACHE_LINE_SIZE; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd128r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd128r1.c new file mode 100644 index 000000000..73099d55b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd128r1.c @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStd128r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStd128r1 +// +// Purpose: Returns size of ECC context for secp128r1 [SEC2] (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ +IPPFUN(IppStatus, ippsECCPGetSizeStd128r1, (int *pSize)) +{ + return ippsECCPGetSize(128, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd128r2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd128r2.c new file mode 100644 index 000000000..f55894122 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd128r2.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStd128r2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStd128r2 +// +// Purpose: Returns size of ECC context for secp128r2 [SEC2] (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ + +IPPFUN(IppStatus, ippsECCPGetSizeStd128r2, (int *pSize)) +{ + return ippsECCPGetSize(128, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd192r1.c new file mode 100644 index 000000000..505af2fff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd192r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStd192r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStd192r1 +// +// Purpose: Returns size of ECC context for secp192r1 [SEC2] (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ + +IPPFUN(IppStatus, ippsECCPGetSizeStd192r1, (int *pSize)) +{ + return ippsECCPGetSize(192, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd224r1.c new file mode 100644 index 000000000..c3b0ed655 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd224r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStd224r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStd224r1 +// +// Purpose: Returns size of ECC context for secp224r1 [SEC2] (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ + +IPPFUN(IppStatus, ippsECCPGetSizeStd224r1, (int *pSize)) +{ + return ippsECCPGetSize(224, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd256r1.c new file mode 100644 index 000000000..3ea269e2a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd256r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStd256r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStd256r1 +// +// Purpose: Returns size of ECC context for secp256r1 [SEC2] (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ + +IPPFUN(IppStatus, ippsECCPGetSizeStd256r1, (int *pSize)) +{ + return ippsECCPGetSize(256, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd384r1.c new file mode 100644 index 000000000..b8cd7e337 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd384r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStd384r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStd384r1 +// +// Purpose: Returns size of ECC context for secp384r1 [SEC2] (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ + +IPPFUN(IppStatus, ippsECCPGetSizeStd384r1, (int *pSize)) +{ + return ippsECCPGetSize(384, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd521r1.c new file mode 100644 index 000000000..225aefd95 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestd521r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStd521r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStd521r1 +// +// Purpose: Returns size of ECC context for secp521r1 [SEC2] (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ + +IPPFUN(IppStatus, ippsECCPGetSizeStd521r1, (int *pSize)) +{ + return ippsECCPGetSize(521, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestdsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestdsm2.c new file mode 100644 index 000000000..a083c0a75 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpgetsizestdsm2.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPGetSizeStdSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPGetSizeStdSM2 +// +// Purpose: Returns size of ECC context for SM2 (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of internal ECC context +*F*/ + +IPPFUN(IppStatus, ippsECCPGetSizeStdSM2, (int *pSize)) +{ + return ippsECCPGetSize(256, pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinit.c new file mode 100644 index 000000000..65cd71d2f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinit.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInit +// +// Purpose: Init ECC context. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsSizeErr 2>feBitSize +// feBitSize>EC_GFP_MAXBITSIZE +// ippStsNoErr no errors +// +// Parameters: +// feBitSize size of field element (bits) +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInit, (int feBitSize, IppsECCPState* pEC)) +{ + /* test pEC pointer */ + IPP_BAD_PTR1_RET(pEC); + + /* test size of field element */ + IPP_BADARG_RET((2>feBitSize || feBitSize>EC_GFP_MAXBITSIZE), ippStsSizeErr); + + { + /* size of GF context */ + //int gfCtxSize = cpGFpGetSize(feBitSize); + int gfCtxSize = cpGFpGetSize(feBitSize, feBitSize+BITSIZE(BNU_CHUNK_T), GFP_POOL_SIZE); + /* size of EC context */ + int ecCtxSize = cpGFpECGetSize(1, feBitSize); + + IppsGFpState* pGF = (IppsGFpState*)((Ipp8u*)pEC+ecCtxSize); + BNU_CHUNK_T* pScratchBuffer = (BNU_CHUNK_T*)IPP_ALIGNED_PTR((Ipp8u*)pGF+gfCtxSize, CACHE_LINE_SIZE); + + /* set up contexts */ + IppStatus sts; + do { + sts = cpGFpInitGFp(feBitSize, pGF); + if(ippStsNoErr!=sts) break; + sts = ippsGFpECInit(pGF, NULL, NULL, pEC); + } while (0); + + /* save scratch buffer pointer */ + ECP_SBUFFER(pEC) = pScratchBuffer; + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd128r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd128r1.c new file mode 100644 index 000000000..cd0dccbd1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd128r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStd128r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStd128r1 +// +// Purpose: Init ECC context for secp128r1 [SEC2]. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStd128r1, (IppsECCPState* pEC)) +{ + return ippsECCPInit(128, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd128r2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd128r2.c new file mode 100644 index 000000000..24bf7cc63 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd128r2.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStd128r2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStd128r2 +// +// Purpose: Init ECC context for secp128r2 [SEC2]. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStd128r2, (IppsECCPState* pEC)) +{ + return ippsECCPInit(128, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd192r1.c new file mode 100644 index 000000000..dc03e49df --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd192r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStd192r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStd192r1 +// +// Purpose: Init ECC context for secp192r1 [SEC2]. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStd192r1, (IppsECCPState* pEC)) +{ + return ippsECCPInit(192, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd224r1.c new file mode 100644 index 000000000..817c35dfd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd224r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStd224r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStd224r1 +// +// Purpose: Init ECC context for secp224r1 [SEC2]. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStd224r1, (IppsECCPState* pEC)) +{ + return ippsECCPInit(224, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd256r1.c new file mode 100644 index 000000000..b97f90d31 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd256r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStd256r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStd256r1 +// +// Purpose: Init ECC context for secp256r1 [SEC2]. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStd256r1, (IppsECCPState* pEC)) +{ + return ippsECCPInit(256, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd384r1.c new file mode 100644 index 000000000..9f7dbbcd0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd384r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStd384r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStd384r1 +// +// Purpose: Init ECC context for secp384r1 [SEC2]. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStd384r1, (IppsECCPState* pEC)) +{ + return ippsECCPInit(384, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd521r1.c new file mode 100644 index 000000000..c11c6368c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstd521r1.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStd521r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStd521r1 +// +// Purpose: Init ECC context for secp521r1 [SEC2]. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStd521r1, (IppsECCPState* pEC)) +{ + return ippsECCPInit(521, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstdsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstdsm2.c new file mode 100644 index 000000000..9975638d8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpinitstdsm2.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (initialization) +// +// Contents: +// ippsECCPInitStdSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStdSM2 +// +// Purpose: Init ECC context for SM2. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pECC +// +// ippStsNoErr no errors +// +// Parameters: +// pECC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPInitStdSM2, (IppsECCPState* pEC)) +{ + return ippsECCPInit(256, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpmulpointscalar.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpmulpointscalar.c new file mode 100644 index 000000000..405f3c100 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpmulpointscalar.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPMulPointScalar() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPMulPointScalar +// +// Purpose: Perforn EC point operation: R = k*P +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pP +// NULL == pK +// NULL == pR +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pP->idCtx +// illegal pK->idCtx +// illegal pR->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pP pointer to the source EC Point context +// pK pointer to the source BigNum multiplier context +// pR pointer to the resultant EC Point context +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPMulPointScalar,(const IppsECCPPointState* pP, + const IppsBigNumState* pK, + IppsECCPPointState* pR, + IppsECCPState* pEC)) +{ + /* use aligned EC context */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + return ippsGFpECMulPoint(pP, pK, pR, pEC, (Ipp8u*)ECP_SBUFFER(pEC)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpnegativepoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpnegativepoint.c new file mode 100644 index 000000000..53b413aad --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpnegativepoint.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPNegativePoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPNegativePoint +// +// Purpose: Perforn EC point operation: R = -P +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pP +// NULL == pR +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pP->idCtx +// illegal pR->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pP pointer to the source EC Point context +// pR pointer to the resultant EC Point context +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPNegativePoint, (const IppsECCPPointState* pP, + IppsECCPPointState* pR, + IppsECCPState* pEC)) +{ + return ippsGFpECNegPoint(pP, pR, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccppointgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccppointgetsize.c new file mode 100644 index 000000000..b440c9888 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccppointgetsize.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC (prime) Point +// +// Contents: +// ippsECCPPointGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPPointGetSize +// +// Purpose: Returns size of EC Point context (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSzie +// ippStsSizeErr 2>feBitSize +// ippStsNoErr no errors +// +// Parameters: +// feBitSize size of field element (bits) +// pSize pointer to the size of EC Point context +// +*F*/ +IPPFUN(IppStatus, ippsECCPPointGetSize, (int feBitSize, int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + /* test size of field element */ + IPP_BADARG_RET((2>feBitSize), ippStsSizeErr); + + { + int elemLen = BITS_BNU_CHUNK(feBitSize); + *pSize= (Ipp32s)sizeof(IppsGFpECPoint) + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* X */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* Y */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T);/* Z */ + } + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccppointinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccppointinit.c new file mode 100644 index 000000000..f13b8948a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccppointinit.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC (prime) Point +// +// Contents: +// ippsECCPPointInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPPointInit +// +// Purpose: Init EC Point context. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pPoint +// ippStsSizeErr 2>feBitSize +// ippStsNoErr no errors +// +// Parameters: +// feBitSize size of field element (bits) +// pECC pointer to ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPPointInit, (int feBitSize, IppsECCPPointState* pPoint)) +{ + /* test pEC pointer */ + IPP_BAD_PTR1_RET(pPoint); + + /* test size of field element */ + IPP_BADARG_RET((2>feBitSize), ippStsSizeErr); + + { + int elemLen = BITS_BNU_CHUNK(feBitSize); + Ipp8u* ptr = (Ipp8u*)pPoint; + + ECP_POINT_SET_ID(pPoint); + ECP_POINT_FLAGS(pPoint) = 0; + ECP_POINT_FELEN(pPoint) = elemLen; + ptr += sizeof(IppsGFpECPoint); + ECP_POINT_DATA(pPoint) = (BNU_CHUNK_T*)(ptr); + + gfec_SetPointAtInfinity(pPoint); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccppublickeyca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccppublickeyca.c new file mode 100644 index 000000000..406e746d5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccppublickeyca.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Key Generation) +// +// Contents: +// ippsECCPPublicKey() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPPublicKey +// +// Purpose: Calculate Public Key +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivate +// NULL == pPublic +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pPrivate->idCtx +// illegal pPublic->idCtx +// +// ippStsInvalidPrivateKey !(0 < pPrivate < order) +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivate pointer to the private key +// pPublic pointer to the resultant public key +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPPublicKey, (const IppsBigNumState* pPrivate, + IppsECCPPointState* pPublic, + IppsECCPState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + return ippsGFpECPublicKey(pPrivate, pPublic, pEC, (Ipp8u*)ECP_SBUFFER(pEC)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsecretdhca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsecretdhca.c new file mode 100644 index 000000000..1f884a3a7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsecretdhca.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Key Ecxhange, Diffie-Hellman version) +// +// Contents: +// ippsECCPSharedSecretDH() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPSharedSecretDH +// +// Purpose: Shared Secret Value Derivation +// (Diffie-Hellman version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivateA +// NULL == pPublicB +// NULL == pShare +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pPrivateA->idCtx +// illegal pPublicB->idCtx +// illegal pShare->idCtx +// +// ippStsRangeErr not enough room for share key +// +// ippStsShareKeyErr (infinity) => z +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivateA pointer to own private key +// pPublicB pointer to alien public key +// pShare pointer to the shareds secret value +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSharedSecretDH,(const IppsBigNumState* pPrivateA, + const IppsECCPPointState* pPublicB, + IppsBigNumState* pShare, + IppsECCPState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + return ippsGFpECSharedSecretDH(pPrivateA, pPublicB, pShare, pEC, (Ipp8u*)ECP_SBUFFER(pEC)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsecretdhcca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsecretdhcca.c new file mode 100644 index 000000000..d97cbbe87 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsecretdhcca.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Key Ecxhange, Diffie-Hellman version with cofactor) +// +// Contents: +// ippsECCPSharedSecretDHC() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPSharedSecretDHC +// +// Purpose: Shared Secret Value Derivation +// (Diffie-Hellman version with cofactor). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivateA +// NULL == pPublicB +// NULL == pShare +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pPrivateA->idCtx +// illegal pPublicB->idCtx +// illegal pShare->idCtx +// +// ippStsRangeErr not enough room for share key +// +// ippStsShareKeyErr (infinity) => z +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivateA pointer to own private key +// pPublicB pointer to alien public key +// pShare pointer to the shared secret value +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSharedSecretDHC,(const IppsBigNumState* pPrivateA, + const IppsECCPPointState* pPublicB, + IppsBigNumState* pShare, + IppsECCPState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + return ippsGFpECSharedSecretDHC(pPrivateA, pPublicB, pShare, pEC, (Ipp8u*)ECP_SBUFFER(pEC)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpset.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpset.c new file mode 100644 index 000000000..82ad4a8ef --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpset.c @@ -0,0 +1,119 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSet() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPInitStdSM2 +// +// Purpose: Sets up the elliptic curve domain parameters +// over a prime finite field GF(p) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pPrime +// NULL == pA +// NULL == pB +// NULL == pGX +// NULL == pGY +// NULL == pOrder +// NULL == cofactor +// NULL == pEC +// +// ippStsContextMatchErr illegal pPrime->idCtx +// illegal pA->idCtx +// illegal pB->idCtx +// illegal pGX->idCtx +// illegal pGY->idCtx +// illegal pOrder->idCtx +// illegal pEC->idCtx +// +// ippStsRangeErr not enough room for: +// pPrime +// pA, pB, +// pGX, pGY +// pOrder +// +// ippStsNoErr no errors +// +// Parameters: +// pPrime pointer to the retrieval prime (specify FG(p)) +// pA pointer to the retrieval A coefficient of EC equation +// pB pointer to the retrieval B coefficient of EC equation +// pGX,pGY pointer to the retrieval Base Point (x and y coordinates) of EC +// pOrder pointer to the retrieval Base Point order +// cofactor pointer to the retrieval cofactor value +// pEC pointer to the ECC context +// +*F*/ + +IPPFUN(IppStatus, ippsECCPSet, (const IppsBigNumState* pPrime, + const IppsBigNumState* pA, const IppsBigNumState* pB, + const IppsBigNumState* pGX,const IppsBigNumState* pGY, + const IppsBigNumState* pOrder, int cofactor, + IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test pPrime */ + IPP_BAD_PTR1_RET(pPrime); + IPP_BADARG_RET(!BN_VALID_ID(pPrime), ippStsContextMatchErr); + IPP_BADARG_RET((cpBN_bitsize(pPrime)>GFP_FEBITLEN(GFP_PMA(ECP_GFP(pEC)))), ippStsRangeErr); + + /* test pA and pB */ + IPP_BAD_PTR2_RET(pA,pB); + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pB), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pA) || 0<=cpBN_cmp(pA,pPrime), ippStsRangeErr); + IPP_BADARG_RET(BN_NEGATIVE(pB) || 0<=cpBN_cmp(pB,pPrime), ippStsRangeErr); + + /* test pG and pGorder pointers */ + IPP_BAD_PTR3_RET(pGX,pGY, pOrder); + IPP_BADARG_RET(!BN_VALID_ID(pGX), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pGY), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pOrder), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pGX) || 0<=cpBN_cmp(pGX,pPrime), ippStsRangeErr); + IPP_BADARG_RET(BN_NEGATIVE(pGY) || 0<=cpBN_cmp(pGY,pPrime), ippStsRangeErr); + IPP_BADARG_RET((cpBN_bitsize(pOrder)>ECP_ORDBITSIZE(pEC)), ippStsRangeErr); + + /* test cofactor */ + IPP_BADARG_RET(!(0idCtx +// illegal pPrivate->idCtx +// illegal pPublic->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivate pointer to the private key +// pPublic pointer to the public key +// regular flag regular/ephemeral keys +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetKeyPair, (const IppsBigNumState* pPrivate, const IppsECCPPointState* pPublic, + IppBool regular, + IppsECCPState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + { + BNU_CHUNK_T* targetPrivate; + BNU_CHUNK_T* targetPublic; + + if(regular) { + targetPrivate = ECP_PRIVAT(pEC); + targetPublic = ECP_PUBLIC(pEC); + } + else { + targetPrivate = ECP_PRIVAT_E(pEC); + targetPublic = ECP_PUBLIC_E(pEC); + } + + /* set up private key request */ + if( pPrivate ) { + IPP_BADARG_RET(!BN_VALID_ID(pPrivate), ippStsContextMatchErr); + { + int privateLen = BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)); + cpGFpElementCopyPad(targetPrivate, privateLen, BN_NUMBER(pPrivate), BN_SIZE(pPrivate)); + } + } + + /* set up public key request */ + if( pPublic ) { + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPublic), ippStsContextMatchErr ); + { + BNU_CHUNK_T* targetPublicX = targetPublic; + BNU_CHUNK_T* targetPublicY = targetPublic+ECP_POINT_FELEN(pPublic); + gfec_GetPoint(targetPublicX, targetPublicY, pPublic, pEC); + gfec_SetPoint(targetPublic, targetPublicX, targetPublicY, pEC); + + //cpGFpElementCopy(targetPublic, ECP_POINT_DATA(pPublic), publicLen); + } + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetpoint.c new file mode 100644 index 000000000..ea295c21d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetpoint.c @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPSetPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetPoint +// +// Purpose: Converts regular affine coordinates EC point (pX,pY) +// into internal presentation - montgomery projective. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPoint +// NULL == pX +// NULL == pY +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pX->idCtx +// illegal pY->idCtx +// illegal pPoint->idCtx +// +// ippStsOutOfECErr point out-of EC +// +// ippStsNoErr no errors +// +// Parameters: +// pX pointer to the regular affine coordinate X +// pY pointer to the regular affine coordinate Y +// pPoint pointer to the EC Point context +// pEC pointer to the ECCP context +// +// Note: +// if B==0 and (x,y)=(0,y) then point at Infinity will be set up +// if B!=0 and (x,y)=(0,0) then point at Infinity will be set up +// else point with requested coordinates (x,y) wil be set up +// There are no check validation inside! +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetPoint,(const IppsBigNumState* pX, + const IppsBigNumState* pY, + IppsECCPPointState* pPoint, + IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test pX and pY */ + IPP_BAD_PTR2_RET(pX,pY); + IPP_BADARG_RET(!BN_VALID_ID(pX), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pY), ippStsContextMatchErr); + + { + IppStatus sts; + + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + IppsGFpElement elmX, elmY; + + cpGFpElementConstruct(&elmX, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmY, cpGFpGetPool(1, pGFE), elemLen); + do { + BNU_CHUNK_T* pData = BN_NUMBER(pX); + int ns = BN_SIZE(pX); + sts = ippsGFpSetElement((Ipp32u*)pData, BITS2WORD32_SIZE(BITSIZE_BNU(pData, ns)), &elmX, pGF); + if(ippStsNoErr!=sts) break; + pData = BN_NUMBER(pY); + ns = BN_SIZE(pY); + sts = ippsGFpSetElement((Ipp32u*)pData, BITS2WORD32_SIZE(BITSIZE_BNU(pData, ns)), &elmY, pGF); + if(ippStsNoErr!=sts) break; + sts = ippsGFpECSetPoint(&elmX, &elmY, pPoint, pEC); + } while(0); + + cpGFpReleasePool(2, pGFE); + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetpointatinfinity.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetpointatinfinity.c new file mode 100644 index 000000000..a6f5a2cf5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetpointatinfinity.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Point operations) +// +// Contents: +// ippsECCPSetPointAtInfinity() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetPointAtInfinity +// +// Purpose: Set point at Infinity +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPoint +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pPoint->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pPoint pointer to the EC Point context +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetPointAtInfinity,(IppsECCPPointState* pPoint, IppsECCPState* pEC)) +{ + return ippsGFpECSetPointAtInfinity(pPoint, pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd.c new file mode 100644 index 000000000..d51bdac8c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd.c @@ -0,0 +1,127 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd +// +// Purpose: Set Standard ECC Domain Parameter. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsECCInvalidFlagErr invalid flag +// +// ippStsNoErr no errors +// +// Parameters: +// flag specify standard ECC parameter(s) to be setup +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd, (IppECCType flag, IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + + switch(flag) { + case IppECCPStd112r1: + return ECCPSetDP(ippsGFpMethod_pArb(), + BITS_BNU_CHUNK(112), secp112r1_p, + BITS_BNU_CHUNK(112), secp112r1_a, + BITS_BNU_CHUNK(112), secp112r1_b, + BITS_BNU_CHUNK(112), secp112r1_gx, + BITS_BNU_CHUNK(112), secp112r1_gy, + BITS_BNU_CHUNK(112), secp112r1_r, + secp112r1_h, pEC); + + case IppECCPStd112r2: + return ECCPSetDP(ippsGFpMethod_pArb(), + BITS_BNU_CHUNK(112), secp112r2_p, + BITS_BNU_CHUNK(112), secp112r2_a, + BITS_BNU_CHUNK(112), secp112r2_b, + BITS_BNU_CHUNK(112), secp112r2_gx, + BITS_BNU_CHUNK(112), secp112r2_gy, + BITS_BNU_CHUNK(112), secp112r2_r, + secp112r2_h, pEC); + + case IppECCPStd128r1: return ippsECCPSetStd128r1(pEC); + + case IppECCPStd128r2: return ippsECCPSetStd128r2(pEC); + + case IppECCPStd160r1: + return ECCPSetDP(ippsGFpMethod_pArb(), + BITS_BNU_CHUNK(160), secp160r1_p, + BITS_BNU_CHUNK(160), secp160r1_a, + BITS_BNU_CHUNK(160), secp160r1_b, + BITS_BNU_CHUNK(160), secp160r1_gx, + BITS_BNU_CHUNK(160), secp160r1_gy, + BITS_BNU_CHUNK(161), secp160r1_r, + secp160r1_h, pEC); + + case IppECCPStd160r2: + return ECCPSetDP(ippsGFpMethod_pArb(), + BITS_BNU_CHUNK(160), secp160r2_p, + BITS_BNU_CHUNK(160), secp160r2_a, + BITS_BNU_CHUNK(160), secp160r2_b, + BITS_BNU_CHUNK(160), secp160r2_gx, + BITS_BNU_CHUNK(160), secp160r2_gy, + BITS_BNU_CHUNK(161), secp160r2_r, + secp160r2_h, pEC); + + case IppECCPStd192r1: return ippsECCPSetStd192r1(pEC); + + case IppECCPStd224r1: return ippsECCPSetStd224r1(pEC); + + case IppECCPStd256r1: return ippsECCPSetStd256r1(pEC); + + case IppECCPStd384r1: return ippsECCPSetStd384r1(pEC); + + case IppECCPStd521r1: return ippsECCPSetStd521r1(pEC); + + case ippEC_TPM_BN_P256: + return ECCPSetDP(ippsGFpMethod_pArb(), + BITS_BNU_CHUNK(256), tpmBN_p256p_p, + BITS_BNU_CHUNK(32), tpmBN_p256p_a, + BITS_BNU_CHUNK(32), tpmBN_p256p_b, + BITS_BNU_CHUNK(32), tpmBN_p256p_gx, + BITS_BNU_CHUNK(32), tpmBN_p256p_gy, + BITS_BNU_CHUNK(256), tpmBN_p256p_r, + tpmBN_p256p_h, pEC); + + case ippECPstdSM2: return ippsECCPSetStdSM2(pEC); + + default: + return ippStsECCInvalidFlagErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd128r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd128r1.c new file mode 100644 index 000000000..09c8944cb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd128r1.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd128r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd128r1 +// +// Purpose: Set EC128r1 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd128r1, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_pArb(), + BITS_BNU_CHUNK(128), secp128r1_p, + BITS_BNU_CHUNK(128), secp128r1_a, + BITS_BNU_CHUNK(128), secp128r1_b, + BITS_BNU_CHUNK(128), secp128r1_gx, + BITS_BNU_CHUNK(128), secp128r1_gy, + BITS_BNU_CHUNK(128), secp128r1_r, + secp128r1_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd128r2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd128r2.c new file mode 100644 index 000000000..2a015b716 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd128r2.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd128r2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd128r2 +// +// Purpose: Set EC128r2 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd128r2, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_pArb(), + BITS_BNU_CHUNK(128), secp128r2_p, + BITS_BNU_CHUNK(128), secp128r2_a, + BITS_BNU_CHUNK(128), secp128r2_b, + BITS_BNU_CHUNK(128), secp128r2_gx, + BITS_BNU_CHUNK(128), secp128r2_gy, + BITS_BNU_CHUNK(128), secp128r2_r, + secp128r2_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd192r1.c new file mode 100644 index 000000000..dc56b558f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd192r1.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd192r1() +// +*/ + +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd192r1 +// +// Purpose: Set EC192r1 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd192r1, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_p192r1(), + BITS_BNU_CHUNK(192), secp192r1_p, + BITS_BNU_CHUNK(192), secp192r1_a, + BITS_BNU_CHUNK(192), secp192r1_b, + BITS_BNU_CHUNK(192), secp192r1_gx, + BITS_BNU_CHUNK(192), secp192r1_gy, + BITS_BNU_CHUNK(192), secp192r1_r, + secp192r1_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd224r1.c new file mode 100644 index 000000000..977427d92 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd224r1.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd224r1() +// +*/ + +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd224r1 +// +// Purpose: Set EC224r1 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd224r1, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_p224r1(), + BITS_BNU_CHUNK(224), secp224r1_p, + BITS_BNU_CHUNK(224), secp224r1_a, + BITS_BNU_CHUNK(224), secp224r1_b, + BITS_BNU_CHUNK(224), secp224r1_gx, + BITS_BNU_CHUNK(224), secp224r1_gy, + BITS_BNU_CHUNK(224), secp224r1_r, + secp224r1_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd256r1.c new file mode 100644 index 000000000..7038cb93b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd256r1.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd256r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd256r1 +// +// Purpose: Set EC256r1 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd256r1, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_p256r1(), + BITS_BNU_CHUNK(256), secp256r1_p, + BITS_BNU_CHUNK(256), secp256r1_a, + BITS_BNU_CHUNK(256), secp256r1_b, + BITS_BNU_CHUNK(256), secp256r1_gx, + BITS_BNU_CHUNK(256), secp256r1_gy, + BITS_BNU_CHUNK(256), secp256r1_r, + secp256r1_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd384r1.c new file mode 100644 index 000000000..6e8ff2560 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd384r1.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd384r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd384r1 +// +// Purpose: Set EC384r1 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd384r1, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_p384r1(), + BITS_BNU_CHUNK(384), secp384r1_p, + BITS_BNU_CHUNK(384), secp384r1_a, + BITS_BNU_CHUNK(384), secp384r1_b, + BITS_BNU_CHUNK(384), secp384r1_gx, + BITS_BNU_CHUNK(384), secp384r1_gy, + BITS_BNU_CHUNK(384), secp384r1_r, + secp384r1_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd521r1.c new file mode 100644 index 000000000..77c1d2f67 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstd521r1.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStd521r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStd521r1 +// +// Purpose: Set EC521r1 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStd521r1, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_p521r1(), + BITS_BNU_CHUNK(521), secp521r1_p, + BITS_BNU_CHUNK(521), secp521r1_a, + BITS_BNU_CHUNK(521), secp521r1_b, + BITS_BNU_CHUNK(521), secp521r1_gx, + BITS_BNU_CHUNK(521), secp521r1_gy, + BITS_BNU_CHUNK(521), secp521r1_r, + secp521r1_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstdsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstdsm2.c new file mode 100644 index 000000000..b2cba147a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsetstdsm2.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (setup/retrieve domain parameters) +// +// Contents: +// ippsECCPSetStdSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsECCPSetStdSM2 +// +// Purpose: Set ECSM2 parameters +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr illegal pEC->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pEC pointer to the ECC context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSetStdSM2, (IppsECCPState* pEC)) +{ + /* test pEC */ + IPP_BAD_PTR1_RET(pEC); + + /* set domain parameters */ + return ECCPSetDP(ippsGFpMethod_p256sm2(), + BITS_BNU_CHUNK(256), tpmSM2_p256_p, + BITS_BNU_CHUNK(256), tpmSM2_p256_a, + BITS_BNU_CHUNK(256), tpmSM2_p256_b, + BITS_BNU_CHUNK(256), tpmSM2_p256_gx, + BITS_BNU_CHUNK(256), tpmSM2_p256_gy, + BITS_BNU_CHUNK(256), tpmSM2_p256_r, + tpmSM2_p256_h, + pEC); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsigndsaca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsigndsaca.c new file mode 100644 index 000000000..28542dda9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsigndsaca.c @@ -0,0 +1,205 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (Sign, DSA version) +// +// Contents: +// ippsECCPSignDSA() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPSignDSA +// +// Purpose: Signing of message representative. +// (DSA version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pPrivate +// NULL == pSignX +// NULL == pSignY +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pMsgDigest->idCtx +// illegal pPrivate->idCtx +// illegal pSignX->idCtx +// illegal pSignY->idCtx +// +// ippStsInvalidPrivateKey 0 >= Private +// Private >= order +// +// ippStsMessageErr MsgDigest >= order +// MsgDigest < 0 +// +// ippStsRangeErr not enough room for: +// signX +// signY +// +// ippStsEphemeralKeyErr (0==signX) || (0==signY) +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pPrivate pointer to the regular private key +// pSignX,pSignY pointer to the signature +// pEC pointer to the ECCP context +// +// Note: +// - ephemeral key pair extracted from pEC and +// must be generated and before ippsECCPDSASign() usage +// - ephemeral key pair destroy before exit +// +*F*/ +IPPFUN(IppStatus, ippsECCPSignDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrivate, + IppsBigNumState* pSignX, IppsBigNumState* pSignY, + IppsECCPState* pEC)) +{ + /* use aligned EC context */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test private key*/ + IPP_BAD_PTR1_RET(pPrivate); + IPP_BADARG_RET(!BN_VALID_ID(pPrivate), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pPrivate), ippStsInvalidPrivateKey); + + /* test message representative: pMsgDigest>=0 */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pMsgDigest), ippStsMessageErr); + /* make sure bisize(pMsgDigest) <= bitsize(order) */ + IPP_BADARG_RET(ECP_ORDBITSIZE(pEC) < cpBN_bitsize(pMsgDigest), ippStsMessageErr); + + /* test signature */ + IPP_BAD_PTR2_RET(pSignX,pSignY); + IPP_BADARG_RET(!BN_VALID_ID(pSignX), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pSignY), ippStsContextMatchErr); + IPP_BADARG_RET((BN_ROOM(pSignX)*BITSIZE(BNU_CHUNK_T)decode(buffer, buffer, pMontP); + ns = cpMod_BNU(buffer, elmLen, pOrder, ordLen); + cpGFpElementCopyPad(dataC, ordLen, buffer, ns); + gsModPoolFree(pMontP, 1); + } + + if(!GFP_IS_ZERO(dataC, ordLen)) { + /* + // signY = (1/ephPrivate)*(pMsgDigest + private*signX) (mod order) + */ + + /* copy and expand message is being signed and reduce just in case */ + ZEXPAND_COPY_BNU(buffF, ordLen, pMsgData, msgLen); + cpModSub_BNU(buffF, buffF, pOrder, pOrder, ordLen, buffT); + + /* private representation in Montgomery domain */ + ZEXPAND_COPY_BNU(dataD, ordLen, pPriData, priLen); + GFP_METHOD(pMontR)->encode(dataD, dataD, pMontR); + + /* (private*signX) in regular domain */ + GFP_METHOD(pMontR)->mul(dataD, dataD, dataC, pMontR); + + /* pMsgDigest + private*signX */ + cpModAdd_BNU(dataD, dataD, buffF, pOrder, ordLen, buffT); + + if(!GFP_IS_ZERO(dataD, ordLen)) { + /* (1/ephPrivate) in Montgomery domain */ + gs_mont_inv(buffT, ECP_PRIVAT_E(pEC), pMontR, alm_mont_inv_ct); + + /* (1/ephPrivate)*(pMsgDigest + private*signX) */ + GFP_METHOD(pMontR)->mul(dataD, dataD, buffT, pMontR); + + /* signX */ + ns = ordLen; + FIX_BNU(dataC, ns); + BN_SIGN(pSignX) = ippBigNumPOS; + BN_SIZE(pSignX) = ns; + /* signY */ + ns = ordLen; + FIX_BNU(dataD, ns); + BN_SIGN(pSignY) = ippBigNumPOS; + BN_SIZE(pSignY) = ns; + + sts = ippStsNoErr; + } + } + + /* clear ephemeral keys pair */ + { + BNU_CHUNK_T* pEphPrivate = ECP_PRIVAT_E(pEC); + BNU_CHUNK_T* pEphPublic = ECP_PUBLIC_E(pEC); + cpGFpElementSetChunk(pEphPrivate, BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)), 0); + cpGFpElementSetChunk(pEphPublic, ECP_POINTLEN(pEC), 0); + } + + return sts; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsignnrca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsignnrca.c new file mode 100644 index 000000000..163d5bbc6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsignnrca.c @@ -0,0 +1,188 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (Sign, NR version) +// +// Contents: +// ippsECCPSignNR() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPSignNR +// +// Purpose: Signing of message representative. +// (NR version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pPrivate +// NULL == pSignX +// NULL == pSignY +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pMsgDigest->idCtx +// illegal pPrivate->idCtx +// illegal pSignX->idCtx +// illegal pSignY->idCtx +// +// ippStsInvalidPrivateKey 0 >= Private +// Private >= order +// +// ippStsMessageErr MsgDigest >= order +// MsgDigest < 0 +// +// ippStsRangeErr not enough room for: +// signX +// signY +// +// ippStsEphemeralKeyErr (0==signX) || (0==signY) +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pPrivate pointer to the regular private key +// pSignX,pSignY pointer to the signature +// pEC pointer to the ECCP context +// +// Note: +// - ephemeral key pair extracted from pEC and +// must be generated and before ippsECCPNRSign() usage +// - ephemeral key pair destroy before exit +// +*F*/ +IPPFUN(IppStatus, ippsECCPSignNR,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pPrivate, + IppsBigNumState* pSignX, IppsBigNumState* pSignY, + IppsECCPState* pEC)) +{ + /* use aligned EC context */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test private key*/ + IPP_BAD_PTR1_RET(pPrivate); + IPP_BADARG_RET(!BN_VALID_ID(pPrivate), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pPrivate), ippStsInvalidPrivateKey); + + /* test message representative: msg>=0 */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pMsgDigest), ippStsMessageErr); + + /* test signature */ + IPP_BAD_PTR2_RET(pSignX,pSignY); + IPP_BADARG_RET(!BN_VALID_ID(pSignX), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pSignY), ippStsContextMatchErr); + IPP_BADARG_RET((BN_ROOM(pSignX)*BITSIZE(BNU_CHUNK_T)decode(buffer, buffer, pMontP); + ns = cpMod_BNU(buffer, elmLen, pOrder, ordLen); + cpGFpElementCopyPad(dataC, ordLen, buffer, ns); + gsModPoolFree(pMontP, 1); + } + + /* signX = (pMsgDigest + C) (mod order) */ + ZEXPAND_COPY_BNU(buffF, ordLen, pMsgData, msgLen); + cpModAdd_BNU(dataC, dataC, buffF, pOrder, ordLen, dataD); + + if(!GFP_IS_ZERO(dataC, ordLen)) { + + /* signY = (eph_private - private*signX) (mod order) */ + ZEXPAND_COPY_BNU(dataD, ordLen, pPriData, priLen); + GFP_METHOD(pMontR)->encode(dataD, dataD, pMontR); + GFP_METHOD(pMontR)->mul(dataD, dataD, dataC, pMontR); + cpModSub_BNU(dataD, ECP_PRIVAT_E(pEC), dataD, pOrder, ordLen, buffF); + + /* signX */ + ns = ordLen; + FIX_BNU(dataC, ns); + BN_SIGN(pSignX) = ippBigNumPOS; + BN_SIZE(pSignX) = ns; + + /* signY */ + ns = ordLen; + FIX_BNU(dataD, ns); + BN_SIGN(pSignY) = ippBigNumPOS; + BN_SIZE(pSignY) = ns; + + sts= ippStsNoErr; + } + + /* clear ephemeral keys pair */ + { + BNU_CHUNK_T* pEphPrivate = ECP_PRIVAT_E(pEC); + BNU_CHUNK_T* pEphPublic = ECP_PUBLIC_E(pEC); + cpGFpElementSetChunk(pEphPrivate, BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)), 0); + cpGFpElementSetChunk(pEphPublic, ECP_POINTLEN(pEC), 0); + } + + return sts; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpsignsm2ca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsignsm2ca.c new file mode 100644 index 000000000..499da15c7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpsignsm2ca.c @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (Sign, SM2 version) +// +// Contents: +// ippsECCPSignSM2() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPSignSM2 +// +// Purpose: Signing of message representative. +// (SM2 version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPrivate +// NULL == pEphPrivate +// NULL == pSignR +// NULL == pSignS +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pMsgDigest->idCtx +// illegal pRegPrivate->idCtx +// illegal pEphPrivate->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsInvalidPrivateKey (1 + regPrivate) >= order +// +// ippStsMessageErr MsgDigest >= order +// MsgDigest < 0 +// +// ippStsRangeErr not enough room for: +// signR +// signS +// +// ippStsEphemeralKeyErr (signR + ephPrivate) == order +// (0==signR) || (0==signS) +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pRegPrivate pointer to the regular private key +// pEphPrivate pointer to the ephemeral private key +// pSignR,pSignS pointer to the signature +// pEC pointer to the ECCP context +// +// Note: +// ephemeral key computes inside ippsECCPSignSM2 in contrast with ippsECCPSignDSA, +// where ephemeral key pair computed before call and setup in context +// +*F*/ +IPPFUN(IppStatus, ippsECCPSignSM2,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsECCPState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + return ippsGFpECSignSM2(pMsgDigest, + pRegPrivate, pEphPrivate, + pSignR, pSignS, + pEC, (Ipp8u*)ECP_SBUFFER(pEC)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_112r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_112r1.c new file mode 100644 index 000000000..687bcaec8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_112r1.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp112r1 +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp112r1 +*/ +const BNU_CHUNK_T secp112r1_p[] = { // (2^128 -3)/76439 + LL(0xBEAD208B, 0x5E668076), LL(0x2ABF62E3, 0xDB7C)}; +const BNU_CHUNK_T secp112r1_a[] = { + LL(0xBEAD2088, 0x5E668076), LL(0x2ABF62E3, 0xDB7C)}; +const BNU_CHUNK_T secp112r1_b[] = { + LL(0x11702B22, 0x16EEDE89), LL(0xF8BA0439, 0x659E)}; +const BNU_CHUNK_T secp112r1_gx[] = { + LL(0xF9C2F098, 0x5EE76B55), LL(0x7239995A, 0x0948)}; +const BNU_CHUNK_T secp112r1_gy[] = { + LL(0x0FF77500, 0xC0A23E0E), LL(0xE5AF8724, 0xA89C)}; +const BNU_CHUNK_T secp112r1_r[] = { + LL(0xAC6561C5, 0x5E7628DF), LL(0x2ABF62E3, 0xDB7C)}; +BNU_CHUNK_T secp112r1_h = 1; + +#endif /* _IPP_DATA */ \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_112r2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_112r2.c new file mode 100644 index 000000000..488ba2fa8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_112r2.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp112r2 +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp112r2 +*/ +const BNU_CHUNK_T secp112r2_p[] = { // (2^128 -3)/76439 + LL(0xBEAD208B, 0x5E668076), LL(0x2ABF62E3, 0xDB7C)}; +const BNU_CHUNK_T secp112r2_a[] = { + LL(0x5C0EF02C, 0x8A0AAAF6), LL(0xC24C05F3, 0x6127)}; +const BNU_CHUNK_T secp112r2_b[] = { + LL(0x4C85D709, 0xED74FCC3), LL(0xF1815DB5, 0x51DE)}; +const BNU_CHUNK_T secp112r2_gx[] = { + LL(0xD0928643, 0xB4E1649D), LL(0x0AB5E892, 0x4BA3)}; +const BNU_CHUNK_T secp112r2_gy[] = { + LL(0x6E956E97, 0x3747DEF3), LL(0x46F5882E, 0xADCD)}; +const BNU_CHUNK_T secp112r2_r[] = { + LL(0x0520D04B, 0xD7597CA1), LL(0x0AAFD8B8, 0x36DF)}; +BNU_CHUNK_T secp112r2_h = 4; + +#endif /* _IPP_DATA */ \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_128r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_128r1.c new file mode 100644 index 000000000..97e7e6f5a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_128r1.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp128r1 (* Montgomery Friendly Modulus (+1) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp128r1 +*/ +const BNU_CHUNK_T h_secp128r1_p[] = { // halpf of secp128r1_p + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0x7FFFFFFE)}; + +const BNU_CHUNK_T secp128r1_p[] = { // 2^128 -2^97 -1 + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFD), LL(0, 0)}; +const BNU_CHUNK_T secp128r1_a[] = { + LL(0xFFFFFFFC, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFD)}; +const BNU_CHUNK_T secp128r1_b[] = { + LL(0x2CEE5ED3, 0xD824993C), LL(0x1079F43D, 0xE87579C1)}; +const BNU_CHUNK_T secp128r1_gx[] = { + LL(0xA52C5B86, 0x0C28607C), LL(0x8B899B2D, 0x161FF752)}; +const BNU_CHUNK_T secp128r1_gy[] = { + LL(0xDDED7A83, 0xC02DA292), LL(0x5BAFEB13, 0xCF5AC839)}; +const BNU_CHUNK_T secp128r1_r[] = { + LL(0x9038A115, 0x75A30D1B), LL(0x00000000, 0xFFFFFFFE)}; +BNU_CHUNK_T secp128r1_h = 1; + +#endif /* _IPP_DATA */ \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_128r2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_128r2.c new file mode 100644 index 000000000..4f47f5c9b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_128r2.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp128r2 (* Montgomery Friendly Modulus (+1) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp128r2 +*/ +const BNU_CHUNK_T secp128r2_p[] = { // 2^128 -2^97 -1 + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFD), LL(0, 0)}; +const BNU_CHUNK_T secp128r2_a[] = { + LL(0xBFF9AEE1, 0xBF59CC9B), LL(0xD1B3BBFE, 0xD6031998)}; +const BNU_CHUNK_T secp128r2_b[] = { + LL(0xBB6D8A5D, 0xDC2C6558), LL(0x80D02919, 0x5EEEFCA3)}; +const BNU_CHUNK_T secp128r2_gx[] = { + LL(0xCDEBC140, 0xE6FB32A7), LL(0x5E572983, 0x7B6AA5D8)}; +const BNU_CHUNK_T secp128r2_gy[] = { + LL(0x5FC34B44, 0x7106FE80), LL(0x894D3AEE, 0x27B6916A)}; +const BNU_CHUNK_T secp128r2_r[] = { + LL(0x0613B5A3, 0xBE002472), LL(0x7FFFFFFF, 0x3FFFFFFF)}; +BNU_CHUNK_T secp128r2_h = 4; + +#endif /* _IPP_DATA */ \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_160r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_160r1.c new file mode 100644 index 000000000..b72e5d39a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_160r1.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp160r1 +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp160r1 +*/ +const BNU_CHUNK_T secp160r1_p[] = { // 2^160 -2^31 -1 + LL(0x7FFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0xFFFFFFFF)}; +const BNU_CHUNK_T secp160r1_a[] = { + LL(0x7FFFFFFC, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0xFFFFFFFF)}; +const BNU_CHUNK_T secp160r1_b[] = { + LL(0xC565FA45, 0x81D4D4AD), LL(0x65ACF89F, 0x54BD7A8B), L_(0x1C97BEFC)}; +const BNU_CHUNK_T secp160r1_gx[] = { + LL(0x13CBFC82, 0x68C38BB9), LL(0x46646989, 0x8EF57328), L_(0x4A96B568)}; +const BNU_CHUNK_T secp160r1_gy[] = { + LL(0x7AC5FB32, 0x04235137), LL(0x59DCC912, 0x3168947D), L_(0x23A62855)}; +const BNU_CHUNK_T secp160r1_r[] = { + LL(0xCA752257, 0xF927AED3), LL(0x0001F4C8, 0x00000000), LL(0x00000000, 0x1)}; +BNU_CHUNK_T secp160r1_h = 1; + +#endif /* _IPP_DATA */ \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_160r2.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_160r2.c new file mode 100644 index 000000000..164eca82a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_160r2.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp160r2 +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp160r2 +*/ +const BNU_CHUNK_T secp160r2_p[] = { // 2^160 -2^32 -2^14 -2^12 -2^9 -2^8 -2^7 -2^2 -1 + LL(0xFFFFAC73, 0xFFFFFFFE), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0xFFFFFFFF)}; +const BNU_CHUNK_T secp160r2_a[] = { + LL(0xFFFFAC70, 0xFFFFFFFE), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0xFFFFFFFF)}; +const BNU_CHUNK_T secp160r2_b[] = { + LL(0xF50388BA, 0x04664D5A), LL(0xAB572749, 0xFB59EB8B), L_(0xB4E134D3)}; +const BNU_CHUNK_T secp160r2_gx[] = { + LL(0x3144CE6D, 0x30F7199D), LL(0x1F4FF11B, 0x293A117E), L_(0x52DCB034)}; +const BNU_CHUNK_T secp160r2_gy[] = { + LL(0xA7D43F2E, 0xF9982CFE), LL(0xE071FA0D, 0xE331F296), L_(0xFEAFFEF2)}; +const BNU_CHUNK_T secp160r2_r[] = { + LL(0xF3A1A16B, 0xE786A818), LL(0x0000351E, 0x00000000), LL(0x00000000, 0x1)}; +BNU_CHUNK_T secp160r2_h = 1; + +#endif /* _IPP_DATA */ \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_192r1.c new file mode 100644 index 000000000..3a33d8ff5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_192r1.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp192r1 (* Montgomery Friendly Modulus (+1) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp192r1 +*/ +const BNU_CHUNK_T h_secp192r1_p[] = { // half of secp192r1_p + LL(0xFFFFFFFF, 0x7FFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0x7FFFFFFF)}; + +const BNU_CHUNK_T secp192r1_p[] = { // 2^192 -2^64 -1 + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFE, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0x0, 0x0)}; +const BNU_CHUNK_T secp192r1_a[] = { + LL(0xFFFFFFFC, 0xFFFFFFFF), LL(0xFFFFFFFE, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF)}; +const BNU_CHUNK_T secp192r1_b[] = { + LL(0xC146B9B1, 0xFEB8DEEC), LL(0x72243049, 0x0FA7E9AB), LL(0xE59C80E7, 0x64210519)}; +const BNU_CHUNK_T secp192r1_gx[] = { + LL(0x82FF1012, 0xF4FF0AFD), LL(0x43A18800, 0x7CBF20EB), LL(0xB03090F6, 0x188DA80E)}; +const BNU_CHUNK_T secp192r1_gy[] = { + LL(0x1E794811, 0x73F977A1), LL(0x6B24CDD5, 0x631011ED), LL(0xFFC8DA78, 0x07192B95)}; +const BNU_CHUNK_T secp192r1_r[] = { + LL(0xB4D22831, 0x146BC9B1), LL(0x99DEF836, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF)}; +BNU_CHUNK_T secp192r1_h = 1; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_224r1.c new file mode 100644 index 000000000..492f9078d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_224r1.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp224r1 (* Montgomery Friendly Modulus (-1) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp224r1 +*/ +const BNU_CHUNK_T h_secp224r1_p[] = { // half of secp224r1_p + LL(0x00000000, 0x00000000), LL(0x80000000, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0x7FFFFFFF, 0x0)}; + +const BNU_CHUNK_T secp224r1_p[] = { // 2^224 -2^96 +1 + LL(0x00000001, 0x00000000), LL(0x00000000, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0x0)}; +const BNU_CHUNK_T secp224r1_a[] = { + LL(0xFFFFFFFE, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFE), LL(0xFFFFFFFF, 0xFFFFFFFF), + L_(0xFFFFFFFF)}; +const BNU_CHUNK_T secp224r1_b[] = { + LL(0x2355FFB4, 0x270B3943), LL(0xD7BFD8BA, 0x5044B0B7), LL(0xF5413256, 0x0C04B3AB), + L_(0xB4050A85)}; +const BNU_CHUNK_T secp224r1_gx[] = { + LL(0x115C1D21, 0x343280D6), LL(0x56C21122, 0x4A03C1D3), LL(0x321390B9, 0x6BB4BF7F), + L_(0xB70E0CBD)}; +const BNU_CHUNK_T secp224r1_gy[] = { + LL(0x85007E34, 0x44D58199), LL(0x5A074764, 0xCD4375A0), LL(0x4C22DFE6, 0xB5F723FB), + L_(0xBD376388)}; +const BNU_CHUNK_T secp224r1_r[] = { + LL(0x5C5C2A3D, 0x13DD2945), LL(0xE0B8F03E, 0xFFFF16A2), LL(0xFFFFFFFF, 0xFFFFFFFF), + L_(0xFFFFFFFF)}; +BNU_CHUNK_T secp224r1_h = 1; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_256r1.c new file mode 100644 index 000000000..ddeb77733 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_256r1.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp256r1 (* Montgomery Friendly Modulus (+1) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp256r1 +*/ +const BNU_CHUNK_T h_secp256r1_p[] = { // half of secp256r1_p + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0x7FFFFFFF, 0x00000000), LL(0x00000000, 0x80000000), + LL(0x80000000, 0x7FFFFFFF)}; + +const BNU_CHUNK_T secp256r1_p[] = { // 2^256 -2^224 +2^192 +2^96 -1 + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0x00000000), LL(0x00000000, 0x00000000), + LL(0x00000001, 0xFFFFFFFF), LL(0x0, 0x0)}; +const BNU_CHUNK_T secp256r1_a[] = { + LL(0xFFFFFFFC, 0xFFFFFFFF), LL(0xFFFFFFFF, 0x00000000), LL(0x00000000, 0x00000000), + LL(0x00000001, 0xFFFFFFFF)}; +const BNU_CHUNK_T secp256r1_b[] = { + LL(0x27D2604B, 0x3BCE3C3E), LL(0xCC53B0F6, 0x651D06B0), LL(0x769886BC, 0xB3EBBD55), + LL(0xAA3A93E7, 0x5AC635D8)}; +const BNU_CHUNK_T secp256r1_gx[] = { + LL(0xD898C296, 0xF4A13945), LL(0x2DEB33A0, 0x77037D81), LL(0x63A440F2, 0xF8BCE6E5), + LL(0xE12C4247, 0x6B17D1F2)}; +const BNU_CHUNK_T secp256r1_gy[] = { + LL(0x37BF51F5, 0xCBB64068), LL(0x6B315ECE, 0x2BCE3357), LL(0x7C0F9E16, 0x8EE7EB4A), + LL(0xFE1A7F9B, 0x4FE342E2)}; +const BNU_CHUNK_T secp256r1_r[] = { + LL(0xFC632551, 0xF3B9CAC2), LL(0xA7179E84, 0xBCE6FAAD), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0x00000000, 0xFFFFFFFF)}; +BNU_CHUNK_T secp256r1_h = 1; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_384r1.c new file mode 100644 index 000000000..cce5e918c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_384r1.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp384r1 (* Montgomery Friendly Modulus (0x0000000100000001) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp384r1 +*/ +const BNU_CHUNK_T h_secp384r1_p[] = { // half of secp384r1_p + LL(0x7FFFFFFF, 0x00000000), LL(0x80000000, 0x7FFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0x7FFFFFFF)}; + +const BNU_CHUNK_T secp384r1_p[] = { // 2^384 -2^128 -2^96 +2^32 -1 + LL(0xFFFFFFFF, 0x00000000), LL(0x00000000, 0xFFFFFFFF), LL(0xFFFFFFFE, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0x0, 0x0)}; +const BNU_CHUNK_T secp384r1_a[] = { + LL(0xFFFFFFFC, 0x00000000), LL(0x00000000, 0xFFFFFFFF), LL(0xFFFFFFFE, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF)}; +const BNU_CHUNK_T secp384r1_b[] = { + LL(0xD3EC2AEF, 0x2A85C8ED), LL(0x8A2ED19D, 0xC656398D), LL(0x5013875A, 0x0314088F), + LL(0xFE814112, 0x181D9C6E), LL(0xE3F82D19, 0x988E056B), LL(0xE23EE7E4, 0xB3312FA7)}; +const BNU_CHUNK_T secp384r1_gx[] = { + LL(0x72760AB7, 0x3A545E38), LL(0xBF55296C, 0x5502F25D), LL(0x82542A38, 0x59F741E0), + LL(0x8BA79B98, 0x6E1D3B62), LL(0xF320AD74, 0x8EB1C71E), LL(0xBE8B0537, 0xAA87CA22)}; +const BNU_CHUNK_T secp384r1_gy[] = { + LL(0x90EA0E5F, 0x7A431D7C), LL(0x1D7E819D, 0x0A60B1CE), LL(0xB5F0B8C0, 0xE9DA3113), + LL(0x289A147C, 0xF8F41DBD), LL(0x9292DC29, 0x5D9E98BF), LL(0x96262C6F, 0x3617DE4A)}; +const BNU_CHUNK_T secp384r1_r[] = { + LL(0xCCC52973, 0xECEC196A), LL(0x48B0A77A, 0x581A0DB2), LL(0xF4372DDF, 0xC7634D81), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF)}; +BNU_CHUNK_T secp384r1_h = 1; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_521r1.c new file mode 100644 index 000000000..dd5151c31 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_521r1.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// secp521r1 (* Montgomery Friendly Modulus (+1) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters secp521r1 +*/ +const BNU_CHUNK_T h_secp521r1_p[] = { // half of secp521r1_p + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0x000000FF)}; + +const BNU_CHUNK_T secp521r1_p[] = { // 2^521 -1 + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0x000001FF)}; +const BNU_CHUNK_T secp521r1_a[] = { + LL(0xFFFFFFFC, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0x000001FF)}; +const BNU_CHUNK_T secp521r1_b[] = { + LL(0x6B503F00, 0xEF451FD4), LL(0x3D2C34F1, 0x3573DF88), LL(0x3BB1BF07, 0x1652C0BD), + LL(0xEC7E937B, 0x56193951), LL(0x8EF109E1, 0xB8B48991), LL(0x99B315F3, 0xA2DA725B), + LL(0xB68540EE, 0x929A21A0), LL(0x8E1C9A1F, 0x953EB961), L_(0x00000051)}; +const BNU_CHUNK_T secp521r1_gx[] = { + LL(0xC2E5BD66, 0xF97E7E31), LL(0x856A429B, 0x3348B3C1), LL(0xA2FFA8DE, 0xFE1DC127), + LL(0xEFE75928, 0xA14B5E77), LL(0x6B4D3DBA, 0xF828AF60), LL(0x053FB521, 0x9C648139), + LL(0x2395B442, 0x9E3ECB66), LL(0x0404E9CD, 0x858E06B7), L_(0x000000C6)}; +const BNU_CHUNK_T secp521r1_gy[] = { + LL(0x9FD16650, 0x88BE9476), LL(0xA272C240, 0x353C7086), LL(0x3FAD0761, 0xC550B901), + LL(0x5EF42640, 0x97EE7299), LL(0x273E662C, 0x17AFBD17), LL(0x579B4468, 0x98F54449), + LL(0x2C7D1BD9, 0x5C8A5FB4), LL(0x9A3BC004, 0x39296A78), L_(0x00000118)}; +const BNU_CHUNK_T secp521r1_r[] = { + LL(0x91386409, 0xBB6FB71E), LL(0x899C47AE, 0x3BB5C9B8), LL(0xF709A5D0, 0x7FCC0148), + LL(0xBF2F966B, 0x51868783), LL(0xFFFFFFFA, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), L_(0x000001FF)}; +BNU_CHUNK_T secp521r1_h = 1; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_BN_256.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_BN_256.c new file mode 100644 index 000000000..0d6fbf4d9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_BN_256.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// tpm_BN_p256 (BN, TPM) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters tpm_BN_p256 (Barreto-Naehrig) +*/ +const BNU_CHUNK_T tpmBN_p256p_p[] = { + LL(0xAED33013, 0xD3292DDB), LL(0x12980A82, 0x0CDC65FB), LL(0xEE71A49F, 0x46E5F25E), + LL(0xFFFCF0CD, 0xFFFFFFFF)}; +const BNU_CHUNK_T tpmBN_p256p_a[] = { + LL(0, 0)}; +const BNU_CHUNK_T tpmBN_p256p_b[] = { + LL(3, 0)}; +const BNU_CHUNK_T tpmBN_p256p_gx[] = { + LL(1, 0)}; +const BNU_CHUNK_T tpmBN_p256p_gy[] = { + LL(2, 0)}; +const BNU_CHUNK_T tpmBN_p256p_r[] = { + LL(0xD10B500D, 0xF62D536C), LL(0x1299921A, 0x0CDC65FB), LL(0xEE71A49E, 0x46E5F25E), + LL(0xFFFCF0CD, 0xFFFFFFFF)}; +BNU_CHUNK_T tpmBN_p256p_h = 1; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_SM2_256.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_SM2_256.c new file mode 100644 index 000000000..a7f2c0c0e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpstdca_SM2_256.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC over Prime Finite Field (recommended ECC parameters) +// +// Contents: +// tpmSM2_p256_p (SM2) (* Montgomery Friendly Modulus (+1) *) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" + +#if defined( _IPP_DATA ) + +/* +// Recommended Parameters tpm_SM2_p256 +*/ +#ifdef _SM2_SIGN_DEBUG_ +const BNU_CHUNK_T tpmSM2_p256_p[] = { + LL(0x08F1DFC3, 0x722EDB8B), LL(0x5C45517D, 0x45728391), LL(0xBF6FF7DE, 0xE8B92435), LL(0x4C044F18, 0x8542D69E), LL(0x0, 0x0)}; +const BNU_CHUNK_T tpmSM2_p256_a[] = { + LL(0x3937E498, 0xEC65228B), LL(0x6831D7E0, 0x2F3C848B), LL(0x73BBFEFF, 0x2417842E), LL(0xFA32C3FD, 0x787968B4)}; +const BNU_CHUNK_T tpmSM2_p256_b[] = { + LL(0x27C5249A, 0x6E12D1DA), LL(0xB16BA06E, 0xF61D59A5), LL(0x484BFE48, 0x9CF84241), LL(0xB23B0C84, 0x63E4C6D3)}; +const BNU_CHUNK_T tpmSM2_p256_gx[] = { + LL(0x7FEDD43D, 0x4C4E6C14), LL(0xADD50BDC, 0x32220B3B), LL(0xC3CC315E, 0x746434EB), LL(0x1B62EAB6, 0x421DEBD6)}; +const BNU_CHUNK_T tpmSM2_p256_gy[] = { + LL(0xE46E09A2, 0xA85841B9), LL(0xBFA36EA1, 0xE5D7FDFC), LL(0x153B70C4, 0xD47349D2), LL(0xCBB42C07, 0x0680512B)}; +const BNU_CHUNK_T tpmSM2_p256_r[] = { + LL(0xC32E79B7, 0x5AE74EE7), LL(0x0485628D, 0x29772063), LL(0xBF6FF7DD, 0xE8B92435), LL(0x4C044F18, 0x8542D69E)}; +#else +const BNU_CHUNK_T h_tpmSM2_p256_p[] = { // half of tpmSM2_p256_p + LL(0xFFFFFFFF, 0x7FFFFFFF), LL(0x80000000, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0x7FFFFFFF, 0x7FFFFFFF)}; + +const BNU_CHUNK_T tpmSM2_p256_p[] = { // 2^256 -2^224 -2^96 +2^64 -1 + LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0x00000000, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFE), LL(0x0, 0x0)}; +const BNU_CHUNK_T tpmSM2_p256_a[] = { + LL(0xFFFFFFFC, 0xFFFFFFFF), LL(0x00000000, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFE)}; +const BNU_CHUNK_T tpmSM2_p256_b[] = { + LL(0x4D940E93, 0xDDBCBD41), LL(0x15AB8F92, 0xF39789F5), LL(0xCF6509A7, 0x4D5A9E4B), LL(0x9D9F5E34, 0x28E9FA9E)}; +const BNU_CHUNK_T tpmSM2_p256_gx[] = { + LL(0x334C74C7, 0x715A4589), LL(0xF2660BE1, 0x8FE30BBF), LL(0x6A39C994, 0x5F990446), LL(0x1F198119, 0x32C4AE2C)}; +const BNU_CHUNK_T tpmSM2_p256_gy[] = { + LL(0x2139F0A0, 0x02DF32E5), LL(0xC62A4740, 0xD0A9877C), LL(0x6B692153, 0x59BDCEE3), LL(0xF4F6779C, 0xBC3736A2)}; +const BNU_CHUNK_T tpmSM2_p256_r[] = { + LL(0x39D54123, 0x53BBF409), LL(0x21C6052B, 0x7203DF6B), LL(0xFFFFFFFF, 0xFFFFFFFF), LL(0xFFFFFFFF, 0xFFFFFFFE)}; +#endif +BNU_CHUNK_T tpmSM2_p256_h = 1; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpvalidateca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpvalidateca.c new file mode 100644 index 000000000..8314d398f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpvalidateca.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (validate domain parameters) +// +// Contents: +// ippsECCPValidate() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPValidate +// +// Purpose: Validate ECC Domain Parameters. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == c +// NULL == pSeed +// NULL == pResult +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal c->idCtx +// +// ippStsBadArgErr nTrials <=0 +// BN_SIZE(c)<5 +// +// ippStsNoErr no errors +// +// Parameters: +// nTrials number of trials of primality test +// pResult pointer to the validation result +// pEC pointer to the ECC context +// rndFunc Specified Random Generator. +// pRndParam Pointer to Random Generator context. +// +// Note +// Validation Domain Parameters folowing by P1363 recommendation +// (reference A.16.8) +// +*F*/ + +#define _DISABLE_TEST_PRIMALITY_ +// validation has been reduced in comparison with legacy version: +// - no primality test of underlying prime +// - no primality test of base point order +// - no MOV test + +IPPFUN(IppStatus, ippsECCPValidate, (int nTrials, IppECResult* pResult, IppsECCPState* pEC, + IppBitSupplier rndFunc, void* pRndParam)) +{ + #if defined(_DISABLE_TEST_PRIMALITY_) + IPP_UNREFERENCED_PARAMETER(nTrials); + IPP_UNREFERENCED_PARAMETER(rndFunc); + IPP_UNREFERENCED_PARAMETER(pRndParam); + #else + /* test number of trials for primality check */ + IPP_BADARG_RET(nTrials<=0, ippStsBadArgErr); + IPP_BAD_PTR2_RET(rndFunc, pRndParam); + #endif + + IPP_BAD_PTR2_RET(pResult, pEC); + + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + return ippsGFpECVerify(pResult, pEC, (Ipp8u*)ECP_SBUFFER(pEC)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpvalidatekeyca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpvalidatekeyca.c new file mode 100644 index 000000000..e93664073 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpvalidatekeyca.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (EC Key Generation) +// +// Contents: +// ippsECCPValidateKeyPair() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPValidateKeyPair +// +// Purpose: Validate (private,public) Key Pair +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivate +// NULL == pPublic +// NULL == pResult +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pPrivate->idCtx +// illegal pPublic->idCtx +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivate pointer to the private key +// pPublic pointer to the public key +// pResult pointer to the result: +// ippECValid/ippECInvalidPrivateKey/ippECPointIsAtInfinite/ippECInvalidPublicKey +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPValidateKeyPair, (const IppsBigNumState* pPrivate, + const IppsECCPPointState* pPublic, + IppECResult* pResult, + IppsECCPState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + return ippsGFpECTstKeyPair(pPrivate, pPublic, pResult, pEC, (Ipp8u*)ECP_SBUFFER(pEC)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifydsaca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifydsaca.c new file mode 100644 index 000000000..622954df5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifydsaca.c @@ -0,0 +1,178 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (Verify Signature, DSA version) +// +// Contents: +// ippsECCPVerifyDSA() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPVerifyDSA +// +// Purpose: Verify Signature (DSA version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pSignX +// NULL == pSignY +// NULL == pResult +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pMsgDigest->idCtx +// illegal pSignX->idCtx +// illegal pSignY->idCtx +// +// ippStsMessageErr MsgDigest >= order +// MsgDigest < 0 +// +// ippStsRangeErr SignX < 0 or SignY < 0 +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pSignX,pSignY pointer to the signature +// pResult pointer to the result: ippECValid/ippECInvalidSignature +// pEC pointer to the ECCP context +// +// Note: +// - signer's key must be set up in ECCP context +// before ippsECCPVerifyDSA() usage +// +*F*/ +IPPFUN(IppStatus, ippsECCPVerifyDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignX, const IppsBigNumState* pSignY, + IppECResult* pResult, + IppsECCPState* pEC)) +{ + /* use aligned EC context */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + /* test message representative: pMsgDigest>=0 */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pMsgDigest), ippStsMessageErr); + /* make sure bisize(pMsgDigest) <= bitsize(order) */ + IPP_BADARG_RET(ECP_ORDBITSIZE(pEC) < cpBN_bitsize(pMsgDigest), ippStsMessageErr); + + /* test result */ + IPP_BAD_PTR1_RET(pResult); + + /* test signature */ + IPP_BAD_PTR2_RET(pSignX,pSignY); + IPP_BADARG_RET(!BN_VALID_ID(pSignX), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pSignY), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pSignX), ippStsRangeErr); + IPP_BADARG_RET(BN_NEGATIVE(pSignY), ippStsRangeErr); + + { + IppECResult vResult = ippECInvalidSignature; + + gsModEngine* pModEngine = ECP_MONT_R(pEC); + BNU_CHUNK_T* pOrder = MOD_MODULUS(pModEngine); + int orderLen = MOD_LEN(pModEngine); + + /* test signature value */ + if(!cpEqu_BNU_CHUNK(BN_NUMBER(pSignX), BN_SIZE(pSignX), 0) && + !cpEqu_BNU_CHUNK(BN_NUMBER(pSignY), BN_SIZE(pSignY), 0) && + 0>cpCmp_BNU(BN_NUMBER(pSignX), BN_SIZE(pSignX), pOrder, orderLen) && + 0>cpCmp_BNU(BN_NUMBER(pSignY), BN_SIZE(pSignY), pOrder, orderLen)) { + + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + + int elmLen = GFP_FELEN(pGFE); + int pelmLen = GFP_PELEN(pGFE); + + BNU_CHUNK_T* h1 = cpGFpGetPool(3, pGFE); + BNU_CHUNK_T* h2 = h1+pelmLen; + BNU_CHUNK_T* redMsg = h2+pelmLen; + + IppsGFpECPoint P, G, Public; + + /* Y = 1/signY mod order */ + __ALIGN8 IppsBigNumState Y; + __ALIGN8 IppsBigNumState R; + BNU_CHUNK_T* buffer = ECP_SBUFFER(pEC); + BN_Make(buffer, buffer+orderLen+1, orderLen, &Y); + BN_Make(buffer+(orderLen+1)*2, buffer+(orderLen+1)*3, orderLen, &R); + /* BN(order) */ + BN_Set(pOrder, orderLen, &R); + ippsModInv_BN((IppsBigNumState*)pSignY, &R, &Y); + /* h1 = 1/signY mod order */ + cpGFpElementCopyPad(h1, orderLen, BN_NUMBER(&Y), BN_SIZE(&Y)); + cpMontEnc_BNU_EX(h1, h1, orderLen, pModEngine); + + /* validate signature */ + cpEcGFpInitPoint(&P, cpEcGFpGetPool(1, pEC),0, pEC); + cpEcGFpInitPoint(&G, ECP_G(pEC), ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC); + cpEcGFpInitPoint(&Public, ECP_PUBLIC(pEC), ECP_FINITE_POINT, pEC); + + /* reduce message just in case */ + ZEXPAND_COPY_BNU(redMsg, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + cpModSub_BNU(redMsg, redMsg, pOrder, pOrder, orderLen, h2); + + /* h2 = pSignX * h1 (mod order) */ + cpMontMul_BNU_EX(h2, + h1,orderLen, BN_NUMBER(pSignX), BN_SIZE(pSignX), + pModEngine); + /* h1 = pMsgDigest * h1 (mod order) */ + cpMontMul_BNU_EX(h1, + h1,orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest), + //h1,orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest), + pModEngine); + + /* compute h1*BasePoint + h2*publicKey */ + gfec_BasePointProduct(&P, + h1, orderLen, &Public, h2, orderLen, + pEC, (Ipp8u*)ECP_SBUFFER(pEC)); + + /* check that P!=O */ + if( !gfec_IsPointAtInfinity(&P)) { + /* get P.X */ + gfec_GetPoint(h1, NULL, &P, pEC); + /* C' = int(P.x) mod order */ + GFP_METHOD(pGFE)->decode(h1, h1, pGFE); + elmLen = cpMod_BNU(h1, elmLen, pOrder, orderLen); + cpGFpElementPad(h1+elmLen, orderLen-elmLen, 0); + + /* and make sure signX==P.X */ + cpGFpElementCopyPad(h2, orderLen, BN_NUMBER(pSignX), BN_SIZE(pSignX)); + if(GFP_EQ(h1, h2, orderLen)) + vResult = ippECValid; + } + + cpEcGFpReleasePool(1, pEC); + cpGFpReleasePool(3, pGFE); + } + + *pResult = vResult; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifynrca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifynrca.c new file mode 100644 index 000000000..92fa865d2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifynrca.c @@ -0,0 +1,168 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (Verify Signature, NR version) +// +// Contents: +// ippsECCPVerifyNR() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPVerifyNR +// +// Purpose: Verify Signature (NR version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pSignX +// NULL == pSignY +// NULL == pResult +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pMsgDigest->idCtx +// illegal pSignX->idCtx +// illegal pSignY->idCtx +// +// ippStsMessageErr 0> MsgDigest +// order<= MsgDigest +// +// ippStsRangeErr SignX < 0 or SignY < 0 +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pSignX,pSignY pointer to the signature +// pResult pointer to the result: ippECValid/ippECInvalidSignature +// pEC pointer to the ECCP context +// +// Note: +// - signer's key must be set up in ECCP context +// before ippsECCPVerifyNR() usage +// +*F*/ +IPPFUN(IppStatus, ippsECCPVerifyNR,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pSignX, const IppsBigNumState* pSignY, + IppECResult* pResult, + IppsECCPState* pEC)) +{ + gsModEngine* pModEngine; + BNU_CHUNK_T* pOrder; + int orderLen; + + BNU_CHUNK_T* pMsgData; + int msgLen; + + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + pModEngine = ECP_MONT_R(pEC); + pOrder = MOD_MODULUS(pModEngine); + orderLen = MOD_LEN(pModEngine); + + /* test message representative */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pMsgDigest), ippStsMessageErr); + + pMsgData = BN_NUMBER(pMsgDigest); + msgLen = BN_SIZE(pMsgDigest); + IPP_BADARG_RET(0<=cpCmp_BNU(pMsgData, msgLen, pOrder, orderLen), ippStsMessageErr); + + /* test result */ + IPP_BAD_PTR1_RET(pResult); + + /* test signature */ + IPP_BAD_PTR2_RET(pSignX,pSignY); + IPP_BADARG_RET(!BN_VALID_ID(pSignX), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pSignY), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pSignX), ippStsRangeErr); + IPP_BADARG_RET(BN_NEGATIVE(pSignY), ippStsRangeErr); + + { + IppECResult vResult = ippECInvalidSignature; + + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + + int elmLen = GFP_FELEN(pGFE); + int pelmLen = GFP_PELEN(pGFE); + + BNU_CHUNK_T* pH1 = cpGFpGetPool(3, pGFE); + BNU_CHUNK_T* pH2 = pH1 + pelmLen; + BNU_CHUNK_T* pR1 = pH2 + pelmLen; + BNU_CHUNK_T* pF = pR1 + pelmLen; + + /* test signature value */ + if(0cpCmp_BNU(BN_NUMBER(pSignX),BN_SIZE(pSignX), pOrder,orderLen) && + 0>cpCmp_BNU(BN_NUMBER(pSignY),BN_SIZE(pSignY), pOrder,orderLen)) { + + /* validate signature */ + IppsGFpECPoint P, G, Public; + cpEcGFpInitPoint(&P, cpEcGFpGetPool(1, pEC),0, pEC); + cpEcGFpInitPoint(&G, ECP_G(pEC), ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC); + cpEcGFpInitPoint(&Public, ECP_PUBLIC(pEC), ECP_FINITE_POINT, pEC); + + /* expand signature: H1 = signY, H2 = signX */ + cpGFpElementCopyPad(pH1, orderLen, BN_NUMBER(pSignY), BN_SIZE(pSignY)); + cpGFpElementCopyPad(pH2, orderLen, BN_NUMBER(pSignX), BN_SIZE(pSignX)); + + /* compute H1*BasePoint + H2*publicKey */ + gfec_BasePointProduct(&P, + pH1, orderLen, &Public, pH2, orderLen, + pEC, (Ipp8u*)ECP_SBUFFER(pEC)); + + /* check that P!=O */ + if( !gfec_IsPointAtInfinity(&P)) { + /* P.X */ + gfec_GetPoint(pH1, NULL, &P, pEC); + /* H1 = int(P.X) mod order */ + GFP_METHOD(pGFE)->decode(pH1, pH1, pGFE); + elmLen = cpMod_BNU(pH1, elmLen, pOrder, orderLen); + cpGFpElementPad(pH1+elmLen, orderLen-elmLen, 0); + + /* recovered message: (SignX - H1) mod order */ + cpModSub_BNU(pH1, pH2, pH1, pOrder, orderLen, pF); + + /* and compare with input message*/ + cpGFpElementCopyPad(pH2, orderLen, pMsgData, msgLen); + if(GFP_EQ(pH1, pH2, orderLen)) + vResult = ippECValid; + } + + cpEcGFpReleasePool(1, pEC); + } + + cpGFpReleasePool(3, pGFE); + + *pResult = vResult; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifysm2ca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifysm2ca.c new file mode 100644 index 000000000..a192bb3a6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccpverifysm2ca.c @@ -0,0 +1,173 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (Verify Signature, SM2 version) +// +// Contents: +// ippsECCPVerifySM2() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsECCPVerifySM2 +// +// Purpose: Verify Signature (SM2 version). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPublic +// NULL == pSignR +// NULL == pSignS +// NULL == pResult +// +// ippStsContextMatchErr illegal pEC->idCtx +// illegal pMsgDigest->idCtx +// illegal pRegPublic->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsMessageErr 0> MsgDigest +// order<= MsgDigest +// +// ippStsRangeErr SignR < 0 or SignS < 0 +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to being signed +// pRegPublic pointer to the regular public key +// pSignR,pSignS pointer to the signature +// pResult pointer to the result: ippECValid/ippECInvalidSignature +// pEC pointer to the ECCP context +// +*F*/ +IPPFUN(IppStatus, ippsECCPVerifySM2,(const IppsBigNumState* pMsgDigest, + const IppsECCPPointState* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppECResult* pResult, + IppsECCPState* pEC)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + /* test message representative: pMsgDigest>=0 */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pMsgDigest), ippStsMessageErr); + /* make sure bisize(pMsgDigest) <= bitsize(order) */ + IPP_BADARG_RET(ECP_ORDBITSIZE(pEC) < cpBN_bitsize(pMsgDigest), ippStsMessageErr); + + /* test regular public key */ + IPP_BAD_PTR1_RET(pRegPublic); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pRegPublic), ippStsContextMatchErr ); + IPP_BADARG_RET( ECP_POINT_FELEN(pRegPublic)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + /* test result */ + IPP_BAD_PTR1_RET(pResult); + + /* test signature */ + IPP_BAD_PTR2_RET(pSignR, pSignS); + IPP_BADARG_RET(!BN_VALID_ID(pSignR), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pSignS), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pSignR), ippStsRangeErr); + IPP_BADARG_RET(BN_NEGATIVE(pSignS), ippStsRangeErr); + + { + IppECResult vResult = ippECInvalidSignature; + + gsModEngine* pMontR = ECP_MONT_R(pEC); + BNU_CHUNK_T* pOrder = MOD_MODULUS(pMontR); + int orderLen = MOD_LEN(pMontR); + + BNU_CHUNK_T* pMsgData = BN_NUMBER(pMsgDigest); + int msgLen = BN_SIZE(pMsgDigest); + + /* test signature value */ + if(!cpEqu_BNU_CHUNK(BN_NUMBER(pSignR), BN_SIZE(pSignR), 0) && + !cpEqu_BNU_CHUNK(BN_NUMBER(pSignS), BN_SIZE(pSignS), 0) && + 0>cpCmp_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pOrder, orderLen) && + 0>cpCmp_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pOrder, orderLen)) { + + int elmLen = GFP_FELEN(pGFE); + int ns; + + BNU_CHUNK_T* r = cpGFpGetPool(4, pGFE); + BNU_CHUNK_T* s = r+orderLen; + BNU_CHUNK_T* t = s+orderLen; + BNU_CHUNK_T* f = t+orderLen; + + /* expand signatire's components */ + cpGFpElementCopyPad(r, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + cpGFpElementCopyPad(s, orderLen, BN_NUMBER(pSignS), BN_SIZE(pSignS)); + + /* t = (r+s) mod order */ + cpModAdd_BNU(t, r, s, pOrder, orderLen, f); + + /* check if t!=0 */ + if( !cpIsGFpElemEquChunk_ct(t, orderLen, 0) ) { + + /* P = [s]G +[t]regPublic, t = P.x */ + IppsGFpECPoint P, G; + cpEcGFpInitPoint(&P, cpEcGFpGetPool(1, pEC),0, pEC); + cpEcGFpInitPoint(&G, ECP_G(pEC), ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC); + + gfec_BasePointProduct(&P, + s, orderLen, pRegPublic, t, orderLen, + pEC, (Ipp8u*)ECP_SBUFFER(pEC)); + + gfec_GetPoint(t, NULL, &P, pEC); + GFP_METHOD(pGFE)->decode(t, t, pGFE); + ns = cpMod_BNU(t, elmLen, pOrder, orderLen); + + cpEcGFpReleasePool(1, pEC); + + /* t = (msg+t) mod order */ + cpGFpElementCopyPad(f, orderLen, pMsgData, msgLen); + cpModSub_BNU(f, f, pOrder, pOrder, orderLen, s); + cpModAdd_BNU(t, t, f, pOrder, orderLen, s); + + if(GFP_EQ(t, r, orderLen)) + vResult = ippECValid; + + IPP_UNREFERENCED_PARAMETER(ns); + } + + cpGFpReleasePool(4, pGFE); + + } + + *pResult = vResult; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpeccresultca.c b/plugin/ippcp/library/src/sources/ippcp/pcpeccresultca.c new file mode 100644 index 000000000..69f84340b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpeccresultca.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// ECC operation results +// +// Contents: +// ippsECCGetResultString() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +/*F* +// Name: ippsECCGetResultString +// +// Purpose: Returns the string corresponding to code +// that represents the result of validation +// +// Parameters: +// code The code of the validation result +// +*F*/ + +IPPFUN( const char*, ippsECCGetResultString, (IppECResult code)) +{ + switch(code) { + case ippECValid: return "Validation pass successfully"; + case ippECCompositeBase: return "Finite Field produced by Composite"; + case ippECComplicatedBase: return "Too much non-zero terms in the polynomial"; + case ippECIsZeroDiscriminant: return "Zero discriminamt"; + case ippECCompositeOrder: return "Composite Base Point order"; + case ippECInvalidOrder: return "Invalid Base Point order"; + case ippECIsWeakMOV: return "EC cover by MOV Reduction Test"; + case ippECIsWeakSSSA: return "EC cover by SS-SA Reduction Test"; + case ippECIsSupersingular: return "EC is supersingular curve"; + case ippECInvalidPrivateKey: return "Invalid Private Key"; + case ippECInvalidPublicKey: return "Invalid Public Key"; + case ippECInvalidKeyPair: return "Invalid Key Pair"; + case ippECPointOutOfGroup: return "Point is out of group"; + case ippECPointIsAtInfinite: return "Point at Infinity"; + case ippECPointIsNotValid: return "Invalid EC Point"; + case ippECPointIsEqual: return "Points are equal"; + case ippECPointIsNotEqual: return "Points are different"; + case ippECInvalidSignature: return "Invalid Signature"; + default: return "Unknown ECC result"; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpecprime.h b/plugin/ippcp/library/src/sources/ippcp/pcpecprime.h new file mode 100644 index 000000000..6bbd875f2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpecprime.h @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Fixed EC primes +// +// +*/ + +#if !defined(_PCP_ECPRIME_H) +#define _PCP_ECPRIME_H + +#include "owndefs.h" +#include "pcpbnuimpl.h" + + +/* +// Recommended (NIST's) underlying EC Primes +*/ +extern const BNU_CHUNK_T secp112r1_p[]; // (2^128 -3)/76439 +extern const BNU_CHUNK_T secp112r2_p[]; // (2^128 -3)/76439 +extern const BNU_CHUNK_T secp128r1_p[]; // 2^128 -2^97 -1 +extern const BNU_CHUNK_T secp128r2_p[]; // 2^128 -2^97 -1 +extern const BNU_CHUNK_T secp160r1_p[]; // 2^160 -2^31 -1 +extern const BNU_CHUNK_T secp160r2_p[]; // 2^160 -2^32 -2^14 -2^12 -2^9 -2^8 -2^7 -2^2 -1 +extern const BNU_CHUNK_T secp192r1_p[]; // 2^192 -2^64 -1 +extern const BNU_CHUNK_T secp224r1_p[]; // 2^224 -2^96 +1 +extern const BNU_CHUNK_T secp256r1_p[]; // 2^256 -2^224 +2^192 +2^96 -1 +extern const BNU_CHUNK_T secp384r1_p[]; // 2^384 -2^128 -2^96 +2^32 -1 +extern const BNU_CHUNK_T secp521r1_p[]; // 2^521 -1 + +extern const BNU_CHUNK_T tpmBN_p256p_p[]; // TPM BN_P256 + +/* +// Recommended (SM2) underlying EC Prime +*/ +extern const BNU_CHUNK_T tpmSM2_p256_p[]; // TPM SM2_P256 + +#endif /* _PCP_ECPRIME_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp.c new file mode 100644 index 000000000..98563307b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp.c @@ -0,0 +1,109 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// cpGFpGetSize() +// cpGFpInitGFp() +// +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/* +// size of GFp engine context (Montgomery) +*/ +IPP_OWN_DEFN (int, cpGFpGetSize, (int feBitSize, int peBitSize, int numpe)) +{ + int ctxSize = 0; + int elemLen = BITS_BNU_CHUNK(feBitSize); + int pelmLen = BITS_BNU_CHUNK(peBitSize); + + /* size of GFp engine */ + ctxSize = (Ipp32s)sizeof(gsModEngine) + + elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* modulus */ + + elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* mont_R */ + + elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* mont_R^2 */ + + elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* half of modulus */ + + elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* quadratic non-residue */ + + pelmLen*(Ipp32s)sizeof(BNU_CHUNK_T)*numpe; /* pool */ + + ctxSize += sizeof(IppsGFpState); /* size of IppsGFPState */ + return ctxSize; +} + +/* +// init GFp engine context (Montgomery) +*/ +static void cpGFEInit(gsModEngine* pGFE, int modulusBitSize, int peBitSize, int numpe) +{ + int modLen = BITS_BNU_CHUNK(modulusBitSize); + int pelmLen = BITS_BNU_CHUNK(peBitSize); + + Ipp8u* ptr = (Ipp8u*)pGFE; + + /* clear whole context */ + PadBlock(0, ptr, sizeof(gsModEngine)); + ptr += sizeof(gsModEngine); + + GFP_PARENT(pGFE) = NULL; + GFP_EXTDEGREE(pGFE) = 1; + GFP_FEBITLEN(pGFE) = modulusBitSize; + GFP_FELEN(pGFE) = modLen; + GFP_FELEN32(pGFE) = BITS2WORD32_SIZE(modulusBitSize); + GFP_PELEN(pGFE) = pelmLen; + //GFP_METHOD(pGFE) = method; + GFP_MODULUS(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*(Ipp32s)sizeof(BNU_CHUNK_T); + GFP_MNT_R(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*(Ipp32s)sizeof(BNU_CHUNK_T); + GFP_MNT_RR(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*(Ipp32s)sizeof(BNU_CHUNK_T); + GFP_HMODULUS(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*(Ipp32s)sizeof(BNU_CHUNK_T); + GFP_QNR(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*(Ipp32s)sizeof(BNU_CHUNK_T); + GFP_POOL(pGFE) = (BNU_CHUNK_T*)(ptr);/* ptr += modLen*(Ipp32s)sizeof(BNU_CHUNK_T);*/ + GFP_MAXPOOL(pGFE) = numpe; + GFP_USEDPOOL(pGFE) = 0; + + cpGFpElementPad(GFP_MODULUS(pGFE), modLen, 0); + cpGFpElementPad(GFP_MNT_R(pGFE), modLen, 0); + cpGFpElementPad(GFP_MNT_RR(pGFE), modLen, 0); + cpGFpElementPad(GFP_HMODULUS(pGFE), modLen, 0); + cpGFpElementPad(GFP_QNR(pGFE), modLen, 0); +} + +IPP_OWN_DEFN (IppStatus, cpGFpInitGFp, (int primeBitSize, IppsGFpState* pGF)) +{ + IPP_BADARG_RET((primeBitSize< IPP_MIN_GF_BITSIZE) || (primeBitSize> IPP_MAX_GF_BITSIZE), ippStsSizeErr); + IPP_BAD_PTR1_RET(pGF); + + { + Ipp8u* ptr = (Ipp8u*)pGF; + + GFP_SET_ID(pGF); + GFP_PMA(pGF) = (gsModEngine*)(ptr+sizeof(IppsGFpState)); + cpGFEInit(GFP_PMA(pGF), primeBitSize, primeBitSize+BITSIZE(BNU_CHUNK_T), GFP_POOL_SIZE); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_exp.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_exp.c new file mode 100644 index 000000000..a2c1ceff7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_exp.c @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpExp +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpExp, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pE, int nsE, gsModEngine* pGFE)) +{ + int elemLen = GFP_FELEN(pGFE); + cpMontExpBin_BNU(pR, pA,cpFix_BNU(pA, elemLen), pE,cpFix_BNU(pE, nsE), pGFE); + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_get.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_get.c new file mode 100644 index 000000000..e180c86fa --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_get.c @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpGet +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + +//tbcd: temporary excluded: #include + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpGet, (BNU_CHUNK_T* pDataA, int nsA, const BNU_CHUNK_T* pElm, gsModEngine* pGFE)) +{ + int elemLen = GFP_FELEN(pGFE); + + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pGFE); + //tbcd: temporary excluded: assert(pTmp !=NULL); + + GFP_METHOD(pGFE)->decode(pTmp, pElm, pGFE); + ZEXPAND_COPY_BNU(pDataA, nsA, pTmp, elemLen); + + cpGFpReleasePool(1, pGFE); + return pDataA; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_getoctstring.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_getoctstring.c new file mode 100644 index 000000000..921294b64 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_getoctstring.c @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpSetOctString +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + +//tbcd: temporary excluded: #include + +IPP_OWN_DEFN (Ipp8u*, cpGFpGetOctString, (Ipp8u* pStr, int strSize, const BNU_CHUNK_T* pElm, gsModEngine* pGFE)) +{ + int elemLen = GFP_FELEN(pGFE); + int error; + + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pGFE); + //tbcd: temporary excluded: assert(pTmp !=NULL); + + GFP_METHOD(pGFE)->decode(pTmp, pElm, pGFE); + error = (0 == cpToOctStr_BNU(pStr, strSize, pTmp, elemLen)); + + cpGFpReleasePool(1, pGFE); + return error ? NULL : pStr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_gfeqnr.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_gfeqnr.c new file mode 100644 index 000000000..140c214a8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_gfeqnr.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// cpGFEqnr() +// +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +//tbcd: temporary excluded: #include + +IPP_OWN_DEFN (void, cpGFEqnr, (gsModEngine* pGFE)) +{ + BNU_CHUNK_T* pQnr = GFP_QNR(pGFE); + + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* e = cpGFpGetPool(3, pGFE); + BNU_CHUNK_T* t = e+elemLen; + BNU_CHUNK_T* p1 = t+elemLen; + //tbcd: temporary excluded: assert(NULL!=e); + + cpGFpElementCopyPad(p1, elemLen, GFP_MNT_R(pGFE), elemLen); + + /* (modulus-1)/2 */ + cpLSR_BNU(e, GFP_MODULUS(pGFE), elemLen, 1); + + /* find a non-square g, where g^{(modulus-1)/2} = -1 */ + cpGFpElementCopy(pQnr, p1, elemLen); + do { + cpGFpAdd(pQnr, pQnr, p1, pGFE); + cpGFpExp(t, pQnr, e, elemLen, pGFE); + cpGFpNeg(t, t, pGFE); + } while( !GFP_EQ(p1, t, elemLen) ); + + cpGFpReleasePool(3, pGFE); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_inv.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_inv.c new file mode 100644 index 000000000..3531679d4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_inv.c @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpInv +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpInv, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFE)) +{ + GFP_METHOD(pGFE)->decode(pR, pA, pGFE); + /* gs_mont_inv(pR, pR, pGFE, alm_mont_inv); */ + gs_mont_inv(pR, pR, pGFE, alm_mont_inv_ct); /* switch on CTE internal function */ + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_rand.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_rand.c new file mode 100644 index 000000000..0a901e69b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_rand.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpRand +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + +//tbcd: temporary excluded: #include + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpRand, (BNU_CHUNK_T* pR, gsModEngine* pGFE, IppBitSupplier rndFunc, void* pRndParam)) +{ + int elemLen = GFP_FELEN(pGFE); + int reqBitSize = GFP_FEBITLEN(pGFE)+GFP_RAND_ADD_BITS; + int nsR = (reqBitSize +BITSIZE(BNU_CHUNK_T)-1)/BITSIZE(BNU_CHUNK_T); + + int internal_err; + + BNU_CHUNK_T* pPool = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(pPool!=NULL); + + cpGFpElementPad(pPool, nsR, 0); + + internal_err = ippStsNoErr != rndFunc((Ipp32u*)pPool, reqBitSize, pRndParam); + + if(!internal_err) { + nsR = cpMod_BNU(pPool, nsR, GFP_MODULUS(pGFE), elemLen); + cpGFpElementPad(pPool+nsR, elemLen-nsR, 0); + GFP_METHOD(pGFE)->encode(pR, pPool, pGFE); + } + + cpGFpReleasePool(2, pGFE); + return internal_err? NULL : pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_set.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_set.c new file mode 100644 index 000000000..636456fd7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_set.c @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpSet +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + +//tbcd: temporary excluded: #include + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpSet, (BNU_CHUNK_T* pElm, const BNU_CHUNK_T* pDataA, int nsA, gsModEngine* pGFE)) +{ + const BNU_CHUNK_T* pModulus = GFP_MODULUS(pGFE); + int elemLen = GFP_FELEN(pGFE); + + if(0 <= cpCmp_BNU(pDataA, nsA, pModulus, elemLen)) + return NULL; + else { + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pGFE); + //tbcd: temporary excluded: assert(pTmp !=NULL); + + ZEXPAND_COPY_BNU(pTmp, elemLen, pDataA, nsA); + GFP_METHOD(pGFE)->encode(pElm, pTmp, pGFE); + + cpGFpReleasePool(1, pGFE); + return pElm; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_setgfp.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_setgfp.c new file mode 100644 index 000000000..aed6dcc91 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_setgfp.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// cpGFpSetGFp() +// +// +*/ +#include "gsmodmethod.h" +#include "gsmodstuff.h" +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +IPP_OWN_DEFN (IppStatus, cpGFpSetGFp, (const BNU_CHUNK_T* pPrime, int primeBitSize, const IppsGFpMethod* method, IppsGFpState* pGF)) +{ + gsModEngine* pGFE = GFP_PMA(pGF); + + int primeLen = BITS_BNU_CHUNK(primeBitSize); + + /* arithmetic methods */ + GFP_METHOD(pGFE) = method->arith; + pGFE->method_alt = method->arith_alt; + + /* store modulus */ + COPY_BNU(GFP_MODULUS(pGFE), pPrime, primeLen); + + /* montgomery factor */ + GFP_MNT_FACTOR(pGFE) = gsMontFactor(GFP_MODULUS(pGFE)[0]); + + /* montgomery identity (R) */ + ZEXPAND_BNU(GFP_MNT_R(pGFE), 0, primeLen); + GFP_MNT_R(pGFE)[primeLen] = 1; + cpMod_BNU(GFP_MNT_R(pGFE), primeLen+1, GFP_MODULUS(pGFE), primeLen); + + /* montgomery domain converter (RR) */ + ZEXPAND_BNU(GFP_MNT_RR(pGFE), 0, primeLen); + COPY_BNU(GFP_MNT_RR(pGFE)+primeLen, GFP_MNT_R(pGFE), primeLen); + cpMod_BNU(GFP_MNT_RR(pGFE), 2*primeLen, GFP_MODULUS(pGFE), primeLen); + + /* half of modulus */ + cpLSR_BNU(GFP_HMODULUS(pGFE), GFP_MODULUS(pGFE), primeLen, 1); + + /* set qnr value */ + cpGFEqnr(pGFE); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_setoctstring.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_setoctstring.c new file mode 100644 index 000000000..ce6542218 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_setoctstring.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpSetOctString +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + +//tbcd: temporary excluded: #include + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpSetOctString, (BNU_CHUNK_T* pElm, const Ipp8u* pStr, int strSize, gsModEngine* pGFE)) +{ + int elemLen = GFP_FELEN(pGFE); + + if((int)(elemLen*(Ipp32s)sizeof(BNU_CHUNK_T)) < strSize) + return NULL; + + { + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pGFE); + //tbcd: temporary excluded: assert(pTmp !=NULL); + { + int nsTmp = cpFromOctStr_BNU(pTmp, pStr, strSize); + BNU_CHUNK_T* ret = cpGFpSet(pElm, pTmp, nsTmp, pGFE); + + cpGFpReleasePool(1, pGFE); + return ret==NULL? NULL : pElm; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfp_sqrt.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_sqrt.c new file mode 100644 index 000000000..d0983e699 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfp_sqrt.c @@ -0,0 +1,148 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over prime GF(p). +// +// Context: +// cpGFpSqrt +// +*/ +#include "owncp.h" + +#include "pcpbn.h" +#include "pcpgfpstuff.h" + +static int factor2(BNU_CHUNK_T* pA, int nsA) +{ + int factor = 0; + int bits; + + int i; + for(i=0; i= BITSIZE(BNU_CHUNK_T)) { + int nchunk = bits/BITSIZE(BNU_CHUNK_T); + cpGFpElementCopyPad(pA, nsA, pA+nchunk, nsA-nchunk); + bits %= BITSIZE(BNU_CHUNK_T); + } + if(bits) + cpLSR_BNU(pA, pA, nsA, bits); + + return factor; +} + +static BNU_CHUNK_T* cpGFpExp2(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, int e, gsModEngine* pGFE) +{ + cpGFpElementCopy(pR, pA, GFP_FELEN(pGFE)); + while(e--) { + GFP_METHOD(pGFE)->sqr(pR, pR, pGFE); + } + return pR; +} + + +/* returns: + 0, if a - qnr + 1, if sqrt is found +*/ +IPP_OWN_DEFN (int, cpGFpSqrt, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFE)) +{ + int elemLen = GFP_FELEN(pGFE); + int poolelementLen = GFP_PELEN(pGFE); + int resultFlag = 1; + + /* case A==0 */ + if( GFP_IS_ZERO(pA, elemLen) ) + cpGFpElementPad(pR, elemLen, 0); + + /* general case */ + else { + BNU_CHUNK_T* q = cpGFpGetPool(4, pGFE); + BNU_CHUNK_T* x = q + poolelementLen; + BNU_CHUNK_T* y = x + poolelementLen; + BNU_CHUNK_T* z = y + poolelementLen; + + int s; + + //tbcd: temporary excluded: assert(q!=NULL); + + /* z=1 */ + GFP_ONE(z, elemLen); + + /* (modulus-1) = 2^s*q */ + cpSub_BNU(q, GFP_MODULUS(pGFE), z, elemLen); + s = factor2(q, elemLen); + + /* + // initialization + */ + + /* y = qnr^q */ + cpGFpExp(y, GFP_QNR(pGFE), q,elemLen, pGFE); + /* x = a^((q-1)/2) */ + cpSub_BNU(q, q, z, elemLen); + cpLSR_BNU(q, q, elemLen, 1); + cpGFpExp(x, pA, q, elemLen, pGFE); + /* z = a*x^2 */ + GFP_METHOD(pGFE)->mul(z, x, x, pGFE); + GFP_METHOD(pGFE)->mul(z, pA, z, pGFE); + /* R = a*x */ + GFP_METHOD(pGFE)->mul(pR, pA, x, pGFE); + + while( !GFP_EQ(z, MOD_MNT_R(pGFE), elemLen) ) { + int m = 0; + cpGFpElementCopy(q, z, elemLen); + + for(m=1; mmul(q, q, q, pGFE); + if( GFP_EQ(q, MOD_MNT_R(pGFE), elemLen) ) + break; + } + + if(m==s) { + /* A is quadratic non-residue */ + resultFlag = 0; + break; + } + else { + /* exponent reduction */ + cpGFpExp2(q, y, (s-m-1), pGFE); /* q = y^(2^(s-m-1)) */ + GFP_METHOD(pGFE)->mul(y, q, q, pGFE); /* y = q^2 */ + GFP_METHOD(pGFE)->mul(pR, q, pR, pGFE); /* R = q*R */ + GFP_METHOD(pGFE)->mul(z, y, z, pGFE); /* z = z*y */ + s = m; + } + } + + /* choose smallest between R and (modulus-R) */ + GFP_METHOD(pGFE)->decode(q, pR, pGFE); + if(1 == cpCmp_BNU(q, elemLen, GFP_HMODULUS(pGFE), elemLen)) + GFP_METHOD(pGFE)->neg(pR, pR, pGFE); + + cpGFpReleasePool(4, pGFE); + } + + return resultFlag; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpadd.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpadd.c new file mode 100644 index 000000000..720cef18f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpadd.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpAdd() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpAdd +// +// Purpose: Sum of GF elements +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// NULL == pB +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// invalid pB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pB Pointer to the context of the second finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpAdd,(const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR4_RET(pA, pB, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pB)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->add(GFPE_DATA(pR), GFPE_DATA(pA), GFPE_DATA(pB), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpaddpe.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpaddpe.c new file mode 100644 index 000000000..5a74a2e07 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpaddpe.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpAdd_PE() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpAdd_PE +// +// Purpose: Sum of GF element and parent GF element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// NULL == pParentB +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// invalid pParentB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsBadArgErr pGFp does not specify prime field +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pParentB Pointer to the context of the second finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpAdd_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR4_RET(pA, pParentB, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pParentB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( (GFPE_ROOM(pParentB)!=GFP_FELEN(GFP_PARENT(pGFE))), ippStsOutOfRangeErr); + + cpGFpxAdd_GFE(GFPE_DATA(pR), GFPE_DATA(pA), GFPE_DATA(pParentB), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpbufsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpbufsize.c new file mode 100644 index 000000000..5628723d0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpbufsize.c @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpScratchBufferSize +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpScratchBufferSize +// +// Purpose: Gets the size of the scratch buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pGFp == NULL +// pBufferSize == NULL +// ippStsContextMatchErr incorrect pGFp's context id +// ippStsBadArgErr 0>=nExponents +// nExponents>6 +// ippStsNoErr no error +// +// Parameters: +// nExponents Number of exponents. +// ExpBitSize Maximum bit size of the exponents. +// pGFp Pointer to the context of the finite field. +// pBufferSize Pointer to the calculated buffer size in bytes. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpScratchBufferSize,(int nExponents, int ExpBitSize, const IppsGFpState* pGFp, int* pBufferSize)) +{ + IPP_BAD_PTR2_RET(pGFp, pBufferSize); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + IPP_BADARG_RET( 0>=nExponents ||nExponents>IPP_MAX_EXPONENT_NUM, ippStsBadArgErr); + IPP_BADARG_RET( 0>=ExpBitSize, ippStsBadArgErr); + + /* gres 06/10/2019: ExpBirSize=BNU_CHUNK_BITS*n -- meet CTE implementation */ + ExpBitSize = ((ExpBitSize + BNU_CHUNK_BITS-1)/BNU_CHUNK_BITS) * BNU_CHUNK_BITS; + { + int elmDataSize = GFP_FELEN(GFP_PMA(pGFp))*(Ipp32s)sizeof(BNU_CHUNK_T); + + /* get window_size */ + int w = (nExponents==1)? cpGFpGetOptimalWinSize(ExpBitSize) : /* use optimal window size, if single-scalar operation */ + nExponents; /* or pseudo-oprimal if multi-scalar operation */ + + /* number of table entries */ + int nPrecomputed = 1<idCtx +// invalid pA->idCtx +// invalid pB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pB Pointer to the context of the second finite field element. +// pResult Pointer to the result of the comparison. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpCmpElement,(const IppsGFpElement* pA, const IppsGFpElement* pB, + int* pResult, + const IppsGFpState* pGFp)) +{ + IPP_BAD_PTR4_RET(pA, pB, pResult, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pB), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pB)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + { + BNU_CHUNK_T* a = cpGFpGetPool(2, pGFE); + BNU_CHUNK_T* b = a + GFP_PELEN(pGFE); + + GFP_METHOD(pGFE)->decode(a, GFPE_DATA(pA), pGFE); + GFP_METHOD(pGFE)->decode(b, GFPE_DATA(pB), pGFE); + + ZEXPAND_BNU(a, GFP_FELEN(pGFE), GFP_PELEN(pGFE)); + ZEXPAND_BNU(b, GFP_FELEN(pGFE), GFP_PELEN(pGFE)); + + int flag = cpCmp_BNU(a, GFP_PELEN(pGFE), b, GFP_PELEN(pGFE)); + if( GFP_IS_BASIC(pGFE) ) + *pResult = (0==flag)? IPP_IS_EQ : (0idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsBadArgErr 2!=GFP_EXTDEGREE(pGFE) +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the source finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpConj,(const IppsGFpElement* pA, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( 2!=GFP_EXTDEGREE(pGFE), ippStsBadArgErr ) + + cpGFpxConj(GFPE_DATA(pR), GFPE_DATA(pA), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpcpyelem.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpcpyelem.c new file mode 100644 index 000000000..4f32c6575 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpcpyelem.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpCpyElement() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + + +/*F* +// Name: ippsGFpCpyElement +// +// Purpose: Copy GF Element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA pointer to the source element +// pR pointer to the result element +// pGFp pointer to Finite Field context +*F*/ + +IPPFUN(IppStatus, ippsGFpCpyElement, (const IppsGFpElement* pA, IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + cpGFpElementCopy(GFPE_DATA(pR), GFPE_DATA(pA), GFP_FELEN(pGFE)); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec.c new file mode 100644 index 000000000..e545f8cb4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// cpGFpECGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + +IPP_OWN_DEFN (int, cpGFpECGetSize, (int basicDeg, int basicElmBitSize)) +{ + int ctxSize = 0; + int elemLen = basicDeg*BITS_BNU_CHUNK(basicElmBitSize); + + int maxOrderBits = 1+ basicDeg*basicElmBitSize; + #if defined(_LEGACY_ECCP_SUPPORT_) + int maxOrderLen = BITS_BNU_CHUNK(maxOrderBits); + #endif + + int modEngineCtxSize; + if(ippStsNoErr==gsModEngineGetSize(maxOrderBits, MONT_DEFAULT_POOL_LENGTH, &modEngineCtxSize)) { + + ctxSize = (Ipp32s)sizeof(IppsGFpECState) + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* EC coeff A */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* EC coeff B */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* generator G.x */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* generator G.y */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* generator G.z */ + +modEngineCtxSize /* mont engine (R) */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* cofactor */ + #if defined(_LEGACY_ECCP_SUPPORT_) + +2*elemLen*3*(Ipp32s)sizeof(BNU_CHUNK_T) /* regular and ephemeral public keys */ + +2*maxOrderLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* regular and ephemeral private keys */ + #endif + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T)*3*EC_POOL_SIZE; + } + return ctxSize; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_add.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_add.c new file mode 100644 index 000000000..17f0e73a9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_add.c @@ -0,0 +1,138 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_point_add() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpmask_ct.h" + + +#if ( ECP_PROJECTIVE_COORD == JACOBIAN ) +/* +// S1 = y1*z2^3 +// S2 = y2*z1^3 +// +// U1 = x1*z2^2 +// U2 = x2*z1^2 + +// R = S2-S1 +// H = U2-U1 +// +// x3 = -H^3 -2*U1*H^2 +R2 +// y3 = -S1*H^3 +R*(U1*H^2 -x3) +// z3 = z1*z2*H +// +// complexity = 4s+12m +*/ + +IPP_OWN_DEFN (void, gfec_point_add, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, const BNU_CHUNK_T* pQdata, IppsGFpECState* pEC)) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_sub sub = GFP_METHOD(pGFE)->sub; /* gf sub */ + mod_mul2 mul2= GFP_METHOD(pGFE)->mul2; /* gf mul2 */ + mod_mul mul = GFP_METHOD(pGFE)->mul; /* gf mul */ + mod_sqr sqr = GFP_METHOD(pGFE)->sqr; /* gf sqr */ + + /* coordinates of P */ + const BNU_CHUNK_T* px1 = pPdata; + const BNU_CHUNK_T* py1 = pPdata+elemLen; + const BNU_CHUNK_T* pz1 = pPdata+2*elemLen; + + /* coordinates of Q */ + const BNU_CHUNK_T* px2 = pQdata; + const BNU_CHUNK_T* py2 = pQdata+elemLen; + const BNU_CHUNK_T* pz2 = pQdata+2*elemLen; + + BNU_CHUNK_T inftyP = GFPE_IS_ZERO_CT(pz1, elemLen); + BNU_CHUNK_T inftyQ = GFPE_IS_ZERO_CT(pz2, elemLen); + + /* get temporary from top of EC point pool */ + BNU_CHUNK_T* U1 = pEC->pPool; + BNU_CHUNK_T* U2 = U1 + elemLen; + BNU_CHUNK_T* S1 = U2 + elemLen; + BNU_CHUNK_T* S2 = S1 + elemLen; + BNU_CHUNK_T* H = S2 + elemLen; + BNU_CHUNK_T* R = H + elemLen; + + BNU_CHUNK_T* pRx = R + elemLen; /* temporary result */ + BNU_CHUNK_T* pRy = pRx+ elemLen; + BNU_CHUNK_T* pRz = pRy+ elemLen; + + mul(S1, py1, pz2, pGFE); // S1 = Y1*Z2 + sqr(U1, pz2, pGFE); // U1 = Z2^2 + + mul(S2, py2, pz1, pGFE); // S2 = Y2*Z1 + sqr(U2, pz1, pGFE); // U2 = Z1^2 + + mul(S1, S1, U1, pGFE); // S1 = Y1*Z2^3 + mul(S2, S2, U2, pGFE); // S2 = Y2*Z1^3 + + mul(U1, px1, U1, pGFE); // U1 = X1*Z2^2 + mul(U2, px2, U2, pGFE); // U2 = X2*Z1^2 + + sub(R, S2, S1, pGFE); // R = S2-S1 + sub(H, U2, U1, pGFE); // H = U2-U1 + + { + BNU_CHUNK_T mask_zeroH = GFPE_IS_ZERO_CT(H, elemLen); + BNU_CHUNK_T mask = mask_zeroH & ~inftyP & ~inftyQ; + if(mask) { + if( GFPE_IS_ZERO_CT(R, elemLen) ) + gfec_point_double(pRdata, pPdata, pEC); + else + cpGFpElementPad(pRdata, 3*elemLen, 0); + return; + } + } + + mul(pRz, pz1, pz2, pGFE); // Z3 = Z1*Z2 + sqr(U2, H, pGFE); // U2 = H^2 + mul(pRz, pRz, H, pGFE); // Z3 = (Z1*Z2)*H + sqr(S2, R, pGFE); // S2 = R^2 + mul(H, H, U2, pGFE); // H = H^3 + + mul(U1, U1, U2, pGFE); // U1 = U1*H^2 + sub(pRx, S2, H, pGFE); // X3 = R^2 - H^3 + mul2(U2, U1, pGFE); // U2 = 2*U1*H^2 + mul(S1, S1, H, pGFE); // S1 = S1*H^3 + sub(pRx, pRx, U2, pGFE); // X3 = (R^2 - H^3) -2*U1*H^2 + + sub(pRy, U1, pRx, pGFE); // Y3 = R*(U1*H^2 - X3) -S1*H^3 + mul(pRy, pRy, R, pGFE); + sub(pRy, pRy, S1, pGFE); + + cpMaskedReplace_ct(pRx, px2, elemLen*3, inftyP); + cpMaskedReplace_ct(pRx, px1, elemLen*3, inftyQ); + + cpGFpElementCopy(pRdata, pRx, 3*elemLen); +} +#endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_addaffine.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_addaffine.c new file mode 100644 index 000000000..145e4881a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_addaffine.c @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_affine_point_add() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpmask_ct.h" + + +#if ( ECP_PROJECTIVE_COORD == JACOBIAN ) +/* +// complexity = 3s+8m +*/ +IPP_OWN_DEFN (void, gfec_affine_point_add, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, const BNU_CHUNK_T* pAdata, IppsGFpECState* pEC)) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_sub sub = GFP_METHOD(pGFE)->sub; /* gf sub */ + mod_mul2 mul2= GFP_METHOD(pGFE)->mul2; /* gf mul2 */ + mod_mul mul = GFP_METHOD(pGFE)->mul; /* gf mul */ + mod_sqr sqr = GFP_METHOD(pGFE)->sqr; /* gf sqr */ + + BNU_CHUNK_T* mont1 = GFP_MNT_R(pGFE); + + /* coordinates of projective P point */ + const BNU_CHUNK_T* px = pPdata; /* x1 */ + const BNU_CHUNK_T* py = pPdata+elemLen; /* y1 */ + const BNU_CHUNK_T* pz = pPdata+2*elemLen; /* z1 */ + + /* coordinates of affine A point, az==mont(1) */ + const BNU_CHUNK_T* ax = pAdata; /* x2 */ + const BNU_CHUNK_T* ay = pAdata+elemLen; /* y2 */ + + BNU_CHUNK_T inftyP = GFPE_IS_ZERO_CT(px, elemLen) & GFPE_IS_ZERO_CT(py, elemLen); + BNU_CHUNK_T inftyA = GFPE_IS_ZERO_CT(ax, elemLen) & GFPE_IS_ZERO_CT(ay, elemLen); + + /* get temporary from top of EC point pool */ + BNU_CHUNK_T* U2 = pEC->pPool; + BNU_CHUNK_T* S2 = U2 + elemLen; + BNU_CHUNK_T* H = S2 + elemLen; + BNU_CHUNK_T* R = H + elemLen; + + BNU_CHUNK_T* pRx = R + elemLen; /* temporary result */ + BNU_CHUNK_T* pRy = pRx+ elemLen; + BNU_CHUNK_T* pRz = pRy+ elemLen; + + sqr(R, pz, pGFE); // R = Z1^2 + mul(S2, ay, pz, pGFE); // S2 = Y2*Z1 + mul(U2, ax, R, pGFE); // U2 = X2*Z1^2 + mul(S2, S2, R, pGFE); // S2 = Y2*Z1^3 + + sub(H, U2, px, pGFE); // H = U2-X1 + sub(R, S2, py, pGFE); // R = S2-Y1 + + mul(pRz, H, pz, pGFE); // Z3 = H*Z1 + + sqr(U2, H, pGFE); // U2 = H^2 + sqr(S2, R, pGFE); // S2 = R^2 + mul(H, H, U2, pGFE); // H = H^3 + + mul(U2, U2, px, pGFE); // U2 = X1*H^2 + + mul(pRy, H, py, pGFE); // T = Y1*H^3 + + mul2(pRx, U2, pGFE); // X3 = 2*X1*H^2 + sub(pRx, S2, pRx, pGFE); // X3 = R^2 - 2*X1*H^2 + sub(pRx, pRx, H, pGFE); // X3 = R^2 - 2*X1*H^2 -H^3 + + sub(U2, U2, pRx, pGFE); // U2 = X1*H^2 - X3 + mul(U2, U2, R, pGFE); // U2 = R*(X1*H^2 - X3) + sub(pRy, U2, pRy, pGFE); // Y3 = -Y1*H^3 + R*(X1*H^2 - X3) + + cpMaskedReplace_ct(pRx, ax, elemLen, inftyP); + cpMaskedReplace_ct(pRy, ay, elemLen, inftyP); + cpMaskedReplace_ct(pRz, mont1, elemLen, inftyP); + cpMaskedReplace_ct(pRz, ax, elemLen, inftyP&inftyA); + + cpMaskedReplace_ct(pRx, px, elemLen*3, inftyA); + + cpGFpElementCopy(pRdata, pRx, 3*elemLen); +} +#endif + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_baseprod.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_baseprod.c new file mode 100644 index 000000000..823fb7da4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_baseprod.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_BasePointProduct() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + + +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_BasePointProduct, (IppsGFpECPoint* pR, const BNU_CHUNK_T* pScalarG, int scalarGlen, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalarP, int scalarPlen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + FIX_BNU(pScalarG, scalarGlen); + FIX_BNU(pScalarP, scalarPlen); + + { + gsModEngine* pGForder = ECP_MONT_R(pEC); + int orderBits = MOD_BITSIZE(pGForder); + int orderLen = MOD_LEN(pGForder); + BNU_CHUNK_T* tmpScalarG = cpGFpGetPool(2, pGForder); + BNU_CHUNK_T* tmpScalarP = tmpScalarG+orderLen+1; + + cpGFpElementCopyPad(tmpScalarG, orderLen+1, pScalarG,scalarGlen); + cpGFpElementCopyPad(tmpScalarP, orderLen+1, pScalarP,scalarPlen); + + if(ECP_PREMULBP(pEC)) { + BNU_CHUNK_T* productG = cpEcGFpGetPool(2, pEC); + BNU_CHUNK_T* productP = productG+ECP_POINTLEN(pEC); + + gfec_base_point_mul(productG, (Ipp8u*)tmpScalarG, orderBits, pEC); + gfec_point_mul(productP, ECP_POINT_X(pP), (Ipp8u*)tmpScalarP, orderBits, pEC, pScratchBuffer); + gfec_point_add(ECP_POINT_X(pR), productG, productP, pEC); + + cpEcGFpReleasePool(2, pEC); + } + + else { + gfec_point_prod(ECP_POINT_X(pR), + ECP_G(pEC), (Ipp8u*)tmpScalarG, + ECP_POINT_X(pP), (Ipp8u*)tmpScalarP, + orderBits, + pEC, pScratchBuffer); + } + + cpGFpReleasePool(2, pGForder); + } + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR)? 0 : ECP_FINITE_POINT; + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_comppont.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_comppont.c new file mode 100644 index 000000000..f4c163fd7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_comppont.c @@ -0,0 +1,103 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_ComparePoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + + +#if ( ECP_PROJECTIVE_COORD == JACOBIAN ) +IPP_OWN_DEFN (int, gfec_ComparePoint, (const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECState* pEC)) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + /* P or/and Q at Infinity */ + if( !IS_ECP_FINITE_POINT(pP) ) + return !IS_ECP_FINITE_POINT(pQ)? 1:0; + if( !IS_ECP_FINITE_POINT(pQ) ) + return !IS_ECP_FINITE_POINT(pP)? 1:0; + + /* Px==Qx && Py==Qy && Pz==Qz */ + if( GFP_EQ(ECP_POINT_Z(pP), ECP_POINT_Z(pQ), elemLen) + &&GFP_EQ(ECP_POINT_X(pP), ECP_POINT_X(pQ), elemLen) + &&GFP_EQ(ECP_POINT_Y(pP), ECP_POINT_Y(pQ), elemLen)) + return 1; + + else { + mod_mul mulF = GFP_METHOD(pGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGFE)->sqr; + + int isEqu = 1; + + BNU_CHUNK_T* pPtmp = cpGFpGetPool(1, pGFE); + BNU_CHUNK_T* pQtmp = cpGFpGetPool(1, pGFE); + BNU_CHUNK_T* pPz = cpGFpGetPool(1, pGFE); + BNU_CHUNK_T* pQz = cpGFpGetPool(1, pGFE); + + if(isEqu) { + /* Px*Qz^2 ~ Qx*Pz^2 */ + if( IS_ECP_AFFINE_POINT(pQ) ) /* Ptmp = Px * Qz^2 */ + cpGFpElementCopy(pPtmp, ECP_POINT_X(pP), elemLen); + else { + sqrF(pQz, ECP_POINT_Z(pQ), pGFE); + mulF(pPtmp, ECP_POINT_X(pP), pQz, pGFE); + } + if( IS_ECP_AFFINE_POINT(pP) ) /* Qtmp = Qx * Pz^2 */ + cpGFpElementCopy(pQtmp, ECP_POINT_X(pQ), elemLen); + else { + sqrF(pPz, ECP_POINT_Z(pP), pGFE); + mulF(pQtmp, ECP_POINT_X(pQ), pPz, pGFE); + } + isEqu = GFP_EQ(pPtmp, pQtmp, elemLen); + } + + if(isEqu) { + /* Py*Qz^3 ~ Qy*Pz^3 */ + if( IS_ECP_AFFINE_POINT(pQ) ) /* Ptmp = Py * Qz^3 */ + cpGFpElementCopy(pPtmp, ECP_POINT_Y(pP), elemLen); + else { + mulF(pQz, ECP_POINT_Z(pQ), pQz, pGFE); + mulF(pPtmp, pQz, ECP_POINT_Y(pP), pGFE); + } + if( IS_ECP_AFFINE_POINT(pP) ) /* Qtmp = Qy * Pz^3 */ + cpGFpElementCopy(pQtmp, ECP_POINT_Y(pQ), elemLen); + else { + mulF(pPz, ECP_POINT_Z(pP), pPz, pGFE); + mulF(pQtmp, pPz, ECP_POINT_Y(pQ), pGFE); + } + isEqu = GFP_EQ(pPtmp, pQtmp, elemLen); + } + + cpGFpReleasePool(4, pGFE); + return isEqu; + } +} +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_dblpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_dblpoint.c new file mode 100644 index 000000000..31139ff29 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_dblpoint.c @@ -0,0 +1,111 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_point_double() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + + + +#if ( ECP_PROJECTIVE_COORD == JACOBIAN ) +/* +// A = 4*x*y^2 +// B = 3*x^2 + a*z^4 +// +// x3 = -2*A + B^2 +// y3 = -8y^4 +B*(A-x3) +// z3 = 2*y*z +// +// complexity: = 4s+4m (NIST's, SM2 curves) +// = (EPID2 curve) +// = 6s+4m (arbitrary curves) +*/ +IPP_OWN_DEFN (void, gfec_point_double, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, IppsGFpECState* pEC)) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_add add = GFP_METHOD(pGFE)->add; /* gf add */ + mod_sub sub = GFP_METHOD(pGFE)->sub; /* gf sub */ + mod_div2 div2= GFP_METHOD(pGFE)->div2; /* gf div2 */ + mod_mul2 mul2= GFP_METHOD(pGFE)->mul2; /* gf mul2 */ + mod_mul3 mul3= GFP_METHOD(pGFE)->mul3; /* gf mul3 */ + mod_mul mul = GFP_METHOD(pGFE)->mul; /* gf mul */ + mod_sqr sqr = GFP_METHOD(pGFE)->sqr; /* gf sqr */ + + const BNU_CHUNK_T* pX = pPdata; + const BNU_CHUNK_T* pY = pPdata+elemLen; + const BNU_CHUNK_T* pZ = pPdata+2*+elemLen; + + BNU_CHUNK_T* rX = pRdata; + BNU_CHUNK_T* rY = pRdata+elemLen; + BNU_CHUNK_T* rZ = pRdata+2*elemLen; + + /* get temporary from top of EC point pool */ + BNU_CHUNK_T* U = pEC->pPool; + BNU_CHUNK_T* M = U+elemLen; + BNU_CHUNK_T* S = M+elemLen; + + mul2(S, pY, pGFE); /* S = 2*Y */ + sqr(U, pZ, pGFE); /* U = Z^2 */ + + sqr(M, S, pGFE); /* M = 4*Y^2 */ + mul(rZ, S, pZ, pGFE); /* Zres = 2*Y*Z */ + + sqr(rY, M, pGFE); /* Yres = 16*Y^4 */ + + mul(S, M, pX, pGFE); /* S = 4*X*Y^2 */ + div2(rY, rY, pGFE); /* Yres = 8*Y^4 */ + + if(ECP_STD==ECP_SPECIFIC(pEC)) { + add(M, pX, U, pGFE); /* M = 3*(X^2-Z^4) */ + sub(U, pX, U, pGFE); + mul(M, M, U, pGFE); + mul3(M, M, pGFE); + } + else { + sqr(M, pX, pGFE); /* M = 3*X^2 */ + mul3(M, M, pGFE); + if(ECP_EPID2!=ECP_SPECIFIC(pEC)) { + sqr(U, U, pGFE); /* M = 3*X^2+a*Z4 */ + mul(U, U, ECP_A(pEC), pGFE); + add(M, M, U, pGFE); + } + } + + mul2(U, S, pGFE); /* U = 8*X*Y^2 */ + sqr(rX, M, pGFE); /* Xres = M^2 */ + sub(rX, rX, U, pGFE); /* Xres = M^2-U */ + + sub(S, S, rX, pGFE); /* S = 4*X*Y^2-Xres */ + mul(S, S, M, pGFE); /* S = M*(4*X*Y^2-Xres) */ + sub(rY, S, rY, pGFE); /* Yres = M*(4*X*Y^2-Xres) -8*Y^4 */ +} +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_getpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_getpoint.c new file mode 100644 index 000000000..f854df33c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_getpoint.c @@ -0,0 +1,84 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_GetPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + + +#if ( ECP_PROJECTIVE_COORD == JACOBIAN ) +/* returns 1/0 if point is finite/infinite */ +IPP_OWN_DEFN (int, gfec_GetPoint, (BNU_CHUNK_T* pX, BNU_CHUNK_T* pY, const IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + if( !IS_ECP_FINITE_POINT(pPoint) ) { + if(pX) cpGFpElementPad(pX, elemLen, 0); + if(pY) cpGFpElementPad(pY, elemLen, 0); + return 0; + } + + /* affine point (1==Z) */ + if( IS_ECP_AFFINE_POINT(pPoint) ) { + if(pX) + cpGFpElementCopy(pX, ECP_POINT_X(pPoint), elemLen); + if(pY) + cpGFpElementCopy(pY, ECP_POINT_Y(pPoint), elemLen); + return 1; + } + + /* projective point (1!=Z) */ + { + mod_mul mulF = GFP_METHOD(pGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGFE)->sqr; + + /* T = (1/Z)*(1/Z) */ + BNU_CHUNK_T* pT = cpGFpGetPool(1, pGFE); + BNU_CHUNK_T* pZinv = cpGFpGetPool(1, pGFE); + BNU_CHUNK_T* pU = cpGFpGetPool(1, pGFE); + cpGFpxInv(pZinv, ECP_POINT_Z(pPoint), pGFE); + sqrF(pT, pZinv, pGFE); + + if(pX) { + mulF(pU, ECP_POINT_X(pPoint), pT, pGFE); + cpGFpElementCopy(pX, pU, elemLen); + } + if(pY) { + mulF(pT, pZinv, pT, pGFE); + mulF(pU, ECP_POINT_Y(pPoint), pT, pGFE); + cpGFpElementCopy(pY, pU, elemLen); + } + + cpGFpReleasePool(3, pGFE); + return 1; + } +} +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_makepoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_makepoint.c new file mode 100644 index 000000000..bf88d6ea0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_makepoint.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_MakePoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (int, gfec_MakePoint, (IppsGFpECPoint* pPoint, const BNU_CHUNK_T* pElm, IppsGFpECState* pEC)) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_mul mulF = GFP_METHOD(pGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGFE)->sqr; + mod_add addF = GFP_METHOD(pGFE)->add; + + BNU_CHUNK_T* pX = ECP_POINT_X(pPoint); + BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint); + BNU_CHUNK_T* pZ = ECP_POINT_Z(pPoint); + + /* set x-coordinate */ + cpGFpElementCopy(pX, pElm, elemLen); + + /* T = X^3 + A*X + B */ + sqrF(pY, pX, pGFE); + mulF(pY, pY, pX, pGFE); + if(ECP_SPECIFIC(pEC)!=ECP_EPID2) { + mulF(pZ, ECP_A(pEC), pX, pGFE); + addF(pY, pY, pZ, pGFE); + } + addF(pY, pY, ECP_B(pEC), pGFE); + + /* set z-coordinate =1 */ + cpGFpElementCopyPad(pZ, elemLen, GFP_MNT_R(pGFE), elemLen); + + /* Y = sqrt(Y) */ + if( cpGFpSqrt(pY, pY, pGFE) ) { + ECP_POINT_FLAGS(pPoint) = ECP_AFFINE_POINT | ECP_FINITE_POINT; + return 1; + } + else { + gfec_SetPointAtInfinity(pPoint); + return 0; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mul.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mul.c new file mode 100644 index 000000000..e073abd26 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mul.c @@ -0,0 +1,112 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_MulPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" +#include "pcpmask_ct.h" + + +IPP_OWN_DEFN (void, gfec_point_mul, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, const Ipp8u* pScalar8, int scalarBitSize, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + int pointLen = ECP_POINTLEN(pEC); + + /* optimal size of window */ + const int window_size = 5; + + /* aligned pre-computed table */ + BNU_CHUNK_T* pTable = (BNU_CHUNK_T*)IPP_ALIGNED_PTR(pScratchBuffer, CACHE_LINE_SIZE); + setupTable(pTable, pPdata, pEC); + + { + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_neg negF = GFP_METHOD(pGFE)->neg; + + BNU_CHUNK_T* pHy = cpGFpGetPool(1, pGFE); + + BNU_CHUNK_T* pTdata = cpEcGFpGetPool(1, pEC); /* points from the pool */ + BNU_CHUNK_T* pHdata = cpEcGFpGetPool(1, pEC); + + int wvalue; + Ipp8u digit, sign; + int mask = (1<<(window_size+1)) -1; + int bit = scalarBitSize-(scalarBitSize%window_size); + + /* first window */ + if(bit) { + wvalue = *((Ipp16u*)&pScalar8[(bit-1)/8]); + wvalue = (wvalue>> ((bit-1)%8)) & mask; + } + else + wvalue = 0; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pTdata, pointLen, pTable, digit-1, 5-1); + + for(bit-=window_size; bit>=window_size; bit-=window_size) { + gfec_point_double(pTdata, pTdata, pEC); /* probably it's better to have separate calls */ + gfec_point_double(pTdata, pTdata, pEC); /* instead of gfec_point_double_k() */ + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + + wvalue = *((Ipp16u*)&pScalar8[(bit-1)/8]); + wvalue = (wvalue>> ((bit-1)%8)) & mask; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pHdata, pointLen, pTable, digit-1, 5-1); + + negF(pHy, pHdata+elemLen, pGFE); + cpMaskedReplace_ct(pHdata+elemLen, pHy, elemLen, ~cpIsZero_ct(sign)); + gfec_point_add(pTdata, pTdata, pHdata, pEC); + } + + /* last window */ + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + + wvalue = *((Ipp16u*)&pScalar8[0]); + wvalue = (wvalue << 1) & mask; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pHdata, pointLen, pTable, digit-1, 5-1); + + negF(pHy, pHdata+elemLen, pGFE); + cpMaskedReplace_ct(pHdata+elemLen, pHy, elemLen, ~cpIsZero_ct(sign)); + gfec_point_add(pTdata, pTdata, pHdata, pEC); + + cpGFpElementCopy(pRdata, pTdata, pointLen); + + cpEcGFpReleasePool(2, pEC); + cpGFpReleasePool(1, pGFE); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mul1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mul1.c new file mode 100644 index 000000000..a555c1c55 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mul1.c @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_MulPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + +#if 0 +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_MulPoint, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + gsModEngine* pGForder = ECP_MONT_R(pEC); + + BNU_CHUNK_T* pTmpScalar = cpGFpGetPool(1, pGForder); /* length of scalar does not exceed length of order */ + int orderBits = MOD_BITSIZE(pGForder); + int orderLen = MOD_LEN(pGForder); + cpGFpElementCopyPad(pTmpScalar,orderLen+1, pScalar,scalarLen); + + gfec_point_mul(ECP_POINT_X(pR), ECP_POINT_X(pP), + (Ipp8u*)pTmpScalar, orderBits, + pEC, pScratchBuffer); + cpGFpReleasePool(1, pGForder); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR)? 0 : ECP_FINITE_POINT; + return pR; + } +} +#endif +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_MulPoint, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + gsModEngine* pME = GFP_PMA(ECP_GFP(pEC)); + + BNU_CHUNK_T* pTmpScalar = cpGFpGetPool(2, pME); + int orderBits = ECP_ORDBITSIZE(pEC); + int orderLen = BITS_BNU_CHUNK(orderBits); + cpGFpElementCopyPad(pTmpScalar, orderLen + 1, pScalar, scalarLen); + + gfec_point_mul(ECP_POINT_X(pR), ECP_POINT_X(pP), + (Ipp8u*)pTmpScalar, orderBits, + pEC, pScratchBuffer); + cpGFpReleasePool(2, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mulbase.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mulbase.c new file mode 100644 index 000000000..5f5892746 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mulbase.c @@ -0,0 +1,92 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_base_point_mul() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpmask_ct.h" + +IPP_OWN_DEFN (void, gfec_base_point_mul, (BNU_CHUNK_T* pRdata, const Ipp8u* pScalar8, int scalarBitSize, IppsGFpECState* pEC)) +{ + /* size of window, get function and pre-computed table */ + int window_size = ECP_PREMULBP(pEC)->w; + selectAP select_affine_point = ECP_PREMULBP(pEC)->select_affine_point; + const BNU_CHUNK_T* pTbl = ECP_PREMULBP(pEC)->pTbl; + + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elmLen = GFP_FELEN(pGFE); + + mod_neg negF = GFP_METHOD(pGFE)->neg; + + BNU_CHUNK_T* mont1 = GFP_MNT_R(pGFE); + + /* number of points per table slot */ + int tslot_point = 1<<(window_size-1); + int tslot_size = tslot_point * (elmLen*2); + + BNU_CHUNK_T* negtmp = cpGFpGetPool(1, pGFE); /* temporary element */ + BNU_CHUNK_T* pointT = cpEcGFpGetPool(1, pEC); /* temporary point */ + + Ipp8u digit, sign; + int mask = (1<<(window_size+1)) -1; + int bit = 0; + + /* processing of window[0] */ + int wvalue = *((Ipp16u*)&pScalar8[0]); + wvalue = (wvalue << 1) & mask; + + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + select_affine_point(pRdata, pTbl, digit); + + /* if(sign) R.y = -R.y */ + negF(negtmp, pRdata+elmLen, pGFE); + cpMaskedReplace_ct(pRdata+elmLen, negtmp, elmLen, ~cpIsZero_ct(sign)); + /* R.z = R!=O? mont(1) : 0 */ + cpGFpElementCopy(pRdata+elmLen*2, mont1, elmLen); + cpGFpElementSetChunk(negtmp, elmLen, 0); + cpMaskedReplace_ct(pRdata+elmLen*2, negtmp, elmLen, cpIsZero_ct(digit)); + //T afine cpGFpElementCopy(pointT+elmLen*2, mont1, elmLen); + + /* processing of other windows.. [1],[2],... */ + for(bit+=window_size, pTbl+=tslot_size; bit<=scalarBitSize; bit+=window_size, pTbl+=tslot_size) { + wvalue = *((Ipp16u*)&pScalar8[(bit-1)/8]); + wvalue = (wvalue>> ((bit-1)%8)) & mask; + + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + select_affine_point(pointT, pTbl, digit); + + negF(negtmp, pointT+elmLen, pGFE); + cpMaskedReplace_ct(pointT+elmLen, negtmp, elmLen, ~cpIsZero_ct(sign)); + + gfec_affine_point_add(pRdata, pRdata, pointT, pEC); + } + + cpEcGFpReleasePool(1, pEC); + cpGFpReleasePool(1, pGFE); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mulbase1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mulbase1.c new file mode 100644 index 000000000..659b092ea --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_mulbase1.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_MulBasePoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_MulBasePoint, (IppsGFpECPoint* pR, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + FIX_BNU(pScalar, scalarLen); + { + gsModEngine* pGForder = ECP_MONT_R(pEC); + + BNU_CHUNK_T* pTmpScalar = cpGFpGetPool(1, pGForder); /* length of scalar does not exceed length of order */ + int orderBits = MOD_BITSIZE(pGForder); + int orderLen = MOD_LEN(pGForder); + cpGFpElementCopyPad(pTmpScalar,orderLen+1, pScalar,scalarLen); + + if(ECP_PREMULBP(pEC)) + gfec_base_point_mul(ECP_POINT_X(pR), + (Ipp8u*)pTmpScalar, orderBits, + pEC); + else + gfec_point_mul(ECP_POINT_X(pR), ECP_G(pEC), + (Ipp8u*)pTmpScalar, orderBits, + pEC, pScratchBuffer); + cpGFpReleasePool(1, pGForder); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR)? 0 : ECP_FINITE_POINT; + return pR; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_negpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_negpoint.c new file mode 100644 index 000000000..bcb5875de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_negpoint.c @@ -0,0 +1,44 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_NegPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + + +IPP_OWN_DEFN (IppsGFpECPoint*, gfec_NegPoint, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, IppsGFpECState* pEC)) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elmLen = GFP_FELEN(pGFE); + if(pR!=pP) + gfec_CopyPoint(pR, pP, elmLen); + GFP_METHOD(pGFE)->neg(ECP_POINT_Y(pR), ECP_POINT_Y(pP), pGFE); + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_prod.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_prod.c new file mode 100644 index 000000000..d961dde15 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_prod.c @@ -0,0 +1,145 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_point_prod() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" +#include "pcpmask_ct.h" + + +IPP_OWN_DEFN (void, gfec_point_prod, (BNU_CHUNK_T* pointR, const BNU_CHUNK_T* pointA, const Ipp8u* scalarA, const BNU_CHUNK_T* pointB, const Ipp8u* scalarB, int scalarBitSize, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + int pointLen = ECP_POINTLEN(pEC); + + /* optimal size of window */ + const int window_size = 5; + /* number of table entries */ + const int tableLen = 1<<(window_size-1); + + /* aligned pre-computed tables */ + BNU_CHUNK_T* pTableA = (BNU_CHUNK_T*)IPP_ALIGNED_PTR(pScratchBuffer, CACHE_LINE_SIZE); + BNU_CHUNK_T* pTableB = pTableA+pointLen*tableLen; + + setupTable(pTableA, pointA, pEC); + setupTable(pTableB, pointB, pEC); + + { + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_neg negF = GFP_METHOD(pGFE)->neg; + + BNU_CHUNK_T* pHy = cpGFpGetPool(1, pGFE); + + BNU_CHUNK_T* pTdata = cpEcGFpGetPool(1, pEC); /* points from the pool */ + BNU_CHUNK_T* pHdata = cpEcGFpGetPool(1, pEC); + + int wvalue; + Ipp8u digit, sign; + int mask = (1<<(window_size+1)) -1; + int bit = scalarBitSize-(scalarBitSize%window_size); + + /* first window */ + if(bit) { + wvalue = *((Ipp16u*)&scalarA[(bit-1)/8]); + wvalue = (wvalue>> ((bit-1)%8)) & mask; + } + else + wvalue = 0; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pTdata, pointLen, pTableA, digit-1, 5-1); + + if(bit) { + wvalue = *((Ipp16u*)&scalarB[(bit-1)/8]); + wvalue = (wvalue>> ((bit-1)%8)) & mask; + } + else + wvalue = 0; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pHdata, pointLen, pTableB, digit-1, 5-1); + + gfec_point_add(pTdata, pTdata, pHdata, pEC); + + for(bit-=window_size; bit>=window_size; bit-=window_size) { + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + + wvalue = *((Ipp16u*)&scalarA[(bit-1)/8]); + wvalue = (wvalue>> ((bit-1)%8)) & mask; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pHdata, pointLen, pTableA, digit-1, 5-1); + + negF(pHy, pHdata+elemLen, pGFE); + cpMaskedReplace_ct(pHdata+elemLen, pHy, elemLen, ~cpIsZero_ct(sign)); + gfec_point_add(pTdata, pTdata, pHdata, pEC); + + wvalue = *((Ipp16u*)&scalarB[(bit-1)/8]); + wvalue = (wvalue>> ((bit-1)%8)) & mask; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pHdata, pointLen, pTableB, digit-1, 5-1); + + negF(pHy, pHdata+elemLen, pGFE); + cpMaskedReplace_ct(pHdata+elemLen, pHy, elemLen, ~cpIsZero_ct(sign)); + gfec_point_add(pTdata, pTdata, pHdata, pEC); + } + /* last window */ + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + gfec_point_double(pTdata, pTdata, pEC); + + wvalue = *((Ipp16u*)&scalarA[0]); + wvalue = (wvalue << 1) & mask; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pHdata, pointLen, pTableA, digit-1, 5-1); + + negF(pHy, pHdata+elemLen, pGFE); + cpMaskedReplace_ct(pHdata+elemLen, pHy, elemLen, ~cpIsZero_ct(sign)); + gfec_point_add(pTdata, pTdata, pHdata, pEC); + + wvalue = *((Ipp16u*)&scalarB[0]); + wvalue = (wvalue << 1) & mask; + booth_recode(&sign, &digit, (Ipp8u)wvalue, window_size); + gsScrambleGet_sscm(pHdata, pointLen, pTableB, digit-1, 5-1); + + negF(pHy, pHdata+elemLen, pGFE); + cpMaskedReplace_ct(pHdata+elemLen, pHy, elemLen, ~cpIsZero_ct(sign)); + gfec_point_add(pTdata, pTdata, pHdata, pEC); + + cpGFpElementCopy(pointR, pTdata, pointLen); + + cpEcGFpReleasePool(2, pEC); + cpGFpReleasePool(1, pGFE); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_selectp192r1w7.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_selectp192r1w7.c new file mode 100644 index 000000000..ba5600000 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpec_selectp192r1w7.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// p192r1_select_ap_w7() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpmask_ct.h" + +/* +// select affine point +*/ +#if (_IPP32E < _IPP32E_M7) +IPP_OWN_DEFN (void, p192r1_select_ap_w7, (BNU_CHUNK_T* pVal, const BNU_CHUNK_T* pTbl, int idx)) +{ + #define OPERAND_BITSIZE (192) + #define LEN_P192 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + #define LEN_P192_APOINT (2*LEN_P192) + + const int tblLen = 64; + int i; + unsigned int n; + + /* clear output affine point */ + for(n=0; nidCtx +// invalid pP->idCtx +// invalid pQ->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pP)!=GFP_FELEN() +// ECP_POINT_FELEN(pQ)!=GFP_FELEN() +// ECP_POINT_FELEN(pR)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pP Pointer to the context of the first elliptic curve point +// pQ Pointer to the context of the second elliptic curve point +// pR Pointer to the context of the resulting elliptic curve point +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECAddPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECPoint* pR, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR4_RET(pP, pQ, pR, pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_POINT_VALID_ID(pP), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_POINT_VALID_ID(pQ), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_POINT_VALID_ID(pR), ippStsContextMatchErr); + + IPP_BADARG_RET(ECP_POINT_FELEN(pP) != GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET(ECP_POINT_FELEN(pQ) != GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET(ECP_POINT_FELEN(pR) != GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + switch (ECP_MODULUS_ID(pEC)) { + case cpID_PrimeP256r1: { + gfec_AddPoint_nistp256_avx512(pR, pP, pQ, pEC); + return ippStsNoErr; + } + case cpID_PrimeP384r1: { + gfec_AddPoint_nistp384_avx512(pR, pP, pQ, pEC); + return ippStsNoErr; + } + case cpID_PrimeP521r1: { + gfec_AddPoint_nistp521_avx512(pR, pP, pQ, pEC); + return ippStsNoErr; + } + case cpID_PrimeTPM_SM2: { + gfec_AddPoint_sm2_avx512(pR, pP, pQ, pEC); + return ippStsNoErr; + } + default: + /* Go to default implementation below */ + break; + } + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + + if (pP == pQ) + gfec_DblPoint(pR, pP, pEC); + else + gfec_AddPoint(pR, pP, pQ, pEC); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd192r1.c new file mode 100644 index 000000000..88ed6405b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd192r1.c @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECBindGxyTblStd192r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + + +static IppStatus cpGFpECBindGxyTbl(const BNU_CHUNK_T* pPrime, + const cpPrecompAP* preComp, + IppsGFpECState* pEC) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + { + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + Ipp32u elemLen = (Ipp32u)GFP_FELEN(pGFE); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(pPrime, (cpSize)elemLen, GFP_MODULUS(pGFE), (cpSize)elemLen), ippStsBadArgErr); + + { + BNU_CHUNK_T* pbp_ec = ECP_G(pEC); + int cmpFlag; + BNU_CHUNK_T* pbp_tbl = cpEcGFpGetPool(1, pEC); + + selectAP select_affine_point = preComp->select_affine_point; + const BNU_CHUNK_T* pTbl = preComp->pTbl; + select_affine_point(pbp_tbl, pTbl, 1); + + /* check if EC's and G-table's Base Point is the same */ + cmpFlag = cpCmp_BNU(pbp_ec, (cpSize)elemLen*2, pbp_tbl, (cpSize)elemLen*2); + + cpEcGFpReleasePool(1, pEC); + + return cmpFlag? ippStsBadArgErr : ippStsNoErr; + } + } +} + +/*F* +// Name: ippsGFpECBindGxyTblStd192r1 +// +// Purpose: Enables the use of base point-based pre-computed tables of EC192r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsBadArgErr pEC is not EC192r1 +// +// ippStsNoErr no error +// +// Parameters: +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECBindGxyTblStd192r1,(IppsGFpECState* pEC)) +{ + IppStatus sts = cpGFpECBindGxyTbl(secp192r1_p, gfpec_precom_nistP192r1_fun(), pEC); + + /* setup pre-computed g-table and point access function */ + if(ippStsNoErr==sts) + ECP_PREMULBP(pEC) = gfpec_precom_nistP192r1_fun(); + + return sts; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd224r1.c new file mode 100644 index 000000000..0bc322a8b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd224r1.c @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECBindGxyTblStd224r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + + +static IppStatus cpGFpECBindGxyTbl(const BNU_CHUNK_T* pPrime, + const cpPrecompAP* preComp, + IppsGFpECState* pEC) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + { + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + Ipp32u elemLen = (Ipp32u)GFP_FELEN(pGFE); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(pPrime, (cpSize)elemLen, GFP_MODULUS(pGFE), (cpSize)elemLen), ippStsBadArgErr); + + { + BNU_CHUNK_T* pbp_ec = ECP_G(pEC); + int cmpFlag; + BNU_CHUNK_T* pbp_tbl = cpEcGFpGetPool(1, pEC); + + selectAP select_affine_point = preComp->select_affine_point; + const BNU_CHUNK_T* pTbl = preComp->pTbl; + select_affine_point(pbp_tbl, pTbl, 1); + + /* check if EC's and G-table's Base Point is the same */ + cmpFlag = cpCmp_BNU(pbp_ec, (cpSize)elemLen*2, pbp_tbl, (cpSize)elemLen*2); + + cpEcGFpReleasePool(1, pEC); + + return cmpFlag? ippStsBadArgErr : ippStsNoErr; + } + } +} + +/*F* +// Name: ippsGFpECBindGxyTblStd224r1 +// +// Purpose: Enables the use of base point-based pre-computed tables of EC224r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsBadArgErr pEC is not EC224r1 +// +// ippStsNoErr no error +// +// Parameters: +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECBindGxyTblStd224r1,(IppsGFpECState* pEC)) +{ + IppStatus sts = cpGFpECBindGxyTbl(secp224r1_p, gfpec_precom_nistP224r1_fun(), pEC); + + /* setup pre-computed g-table and point access function */ + if(ippStsNoErr==sts) + ECP_PREMULBP(pEC) = gfpec_precom_nistP224r1_fun(); + + return sts; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd256r1.c new file mode 100644 index 000000000..064096441 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd256r1.c @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECBindGxyTblStd256r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" +#include "pcpgfpmethod.h" + + +static IppStatus cpGFpECBindGxyTbl(const BNU_CHUNK_T* pPrime, + const cpPrecompAP* preComp, + IppsGFpECState* pEC) +{ + IppsGFpState *pGF = ECP_GFP(pEC); + gsModEngine *pGFE = GFP_PMA(pGF); + Ipp32u elemLen = (Ipp32u)GFP_FELEN(pGFE); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(pPrime, (cpSize)elemLen, GFP_MODULUS(pGFE), (cpSize)elemLen), ippStsBadArgErr); + + { + BNU_CHUNK_T *pbp_ec = ECP_G(pEC); + int cmpFlag; + BNU_CHUNK_T *pbp_tbl = cpEcGFpGetPool(1, pEC); + + selectAP select_affine_point = preComp->select_affine_point; + const BNU_CHUNK_T *pTbl = preComp->pTbl; + select_affine_point(pbp_tbl, pTbl, 1); + + /* check if EC's and G-table's Base Point is the same */ + cmpFlag = cpCmp_BNU(pbp_ec, (cpSize)elemLen * 2, pbp_tbl, (cpSize)elemLen * 2); + + cpEcGFpReleasePool(1, pEC); + + return cmpFlag ? ippStsBadArgErr : ippStsNoErr; + } +} + +/*F* +// Name: ippsGFpECBindGxyTblStd256r1 +// +// Purpose: Enables the use of base point-based pre-computed tables of EC256r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsBadArgErr pEC is not EC256r1 +// +// ippStsNoErr no error +// +// Parameters: +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECBindGxyTblStd256r1, (IppsGFpECState * pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + /* ModulusId as well as IFMA-based GF(p) method are assigned in + * ippsGFpECInitStd* function. If modulusId is not set (i.e. GFp method is + * not IFMA-based), then bind regular table (not for IFMA implementation). + */ + if (ECP_MODULUS_ID(pEC) == cpID_PrimeP256r1) { + ECP_PREMULBP(pEC) = gfpec_precom_nistP256r1_radix52_fun(); + return ippStsNoErr; + } + } +#endif + + const cpPrecompAP *precomp = gfpec_precom_nistP256r1_fun(); + IppStatus sts = cpGFpECBindGxyTbl(secp256r1_p, precomp, pEC); + + /* setup pre-computed g-table and point access function */ + if (ippStsNoErr == sts) + ECP_PREMULBP(pEC) = precomp; + + return sts; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd384r1.c new file mode 100644 index 000000000..d4d404ca2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd384r1.c @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECBindGxyTblStd384r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" +#include "pcpgfpmethod.h" + + +static IppStatus cpGFpECBindGxyTbl(const BNU_CHUNK_T* pPrime, + const cpPrecompAP* preComp, + IppsGFpECState* pEC) +{ + IppsGFpState *pGF = ECP_GFP(pEC); + gsModEngine *pGFE = GFP_PMA(pGF); + Ipp32u elemLen = (Ipp32u)GFP_FELEN(pGFE); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(pPrime, (cpSize)elemLen, GFP_MODULUS(pGFE), (cpSize)elemLen), ippStsBadArgErr); + + { + BNU_CHUNK_T *pbp_ec = ECP_G(pEC); + int cmpFlag; + BNU_CHUNK_T *pbp_tbl = cpEcGFpGetPool(1, pEC); + + selectAP select_affine_point = preComp->select_affine_point; + const BNU_CHUNK_T *pTbl = preComp->pTbl; + select_affine_point(pbp_tbl, pTbl, 1); + + /* check if EC's and G-table's Base Point is the same */ + cmpFlag = cpCmp_BNU(pbp_ec, (cpSize)elemLen * 2, pbp_tbl, (cpSize)elemLen * 2); + + cpEcGFpReleasePool(1, pEC); + + return cmpFlag ? ippStsBadArgErr : ippStsNoErr; + } +} + +/*F* +// Name: ippsGFpECBindGxyTblStd384r1 +// +// Purpose: Enables the use of base point-based pre-computed tables of EC384r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsBadArgErr pEC is not EC384r1 +// +// ippStsNoErr no error +// +// Parameters: +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECBindGxyTblStd384r1, (IppsGFpECState * pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + /* ModulusId as well as IFMA-based GF(p) method are assigned in + * ippsGFpECInitStd* function. If modulusId is not set (i.e. GFp method is + * not IFMA-based), then bind regular table (not for IFMA implementation). + */ + if (ECP_MODULUS_ID(pEC) == cpID_PrimeP384r1) { + ECP_PREMULBP(pEC) = gfpec_precom_nistP384r1_radix52_fun(); + return ippStsNoErr; + } + } +#endif + + const cpPrecompAP *precomp = gfpec_precom_nistP384r1_fun(); + IppStatus sts = cpGFpECBindGxyTbl(secp384r1_p, precomp, pEC); + + /* setup pre-computed g-table and point access function */ + if (ippStsNoErr == sts) + ECP_PREMULBP(pEC) = precomp; + + return sts; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd521r1.c new file mode 100644 index 000000000..b8a87532f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstd521r1.c @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECBindGxyTblStd521r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" +#include "pcpgfpmethod.h" + + +static IppStatus cpGFpECBindGxyTbl(const BNU_CHUNK_T* pPrime, + const cpPrecompAP* preComp, + IppsGFpECState* pEC) +{ + IppsGFpState *pGF = ECP_GFP(pEC); + gsModEngine *pGFE = GFP_PMA(pGF); + Ipp32u elemLen = (Ipp32u)GFP_FELEN(pGFE); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(pPrime, (cpSize)elemLen, GFP_MODULUS(pGFE), (cpSize)elemLen), ippStsBadArgErr); + + { + BNU_CHUNK_T *pbp_ec = ECP_G(pEC); + int cmpFlag; + BNU_CHUNK_T *pbp_tbl = cpEcGFpGetPool(1, pEC); + + selectAP select_affine_point = preComp->select_affine_point; + const BNU_CHUNK_T *pTbl = preComp->pTbl; + select_affine_point(pbp_tbl, pTbl, 1); + + /* check if EC's and G-table's Base Point is the same */ + cmpFlag = cpCmp_BNU(pbp_ec, (cpSize)elemLen * 2, pbp_tbl, (cpSize)elemLen * 2); + + cpEcGFpReleasePool(1, pEC); + + return cmpFlag ? ippStsBadArgErr : ippStsNoErr; + } +} + +/*F* +// Name: ippsGFpECBindGxyTblStd521r1 +// +// Purpose: Enables the use of base point-based pre-computed tables of EC521r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsBadArgErr pEC is not EC521r1 +// +// ippStsNoErr no error +// +// Parameters: +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECBindGxyTblStd521r1, (IppsGFpECState * pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + /* ModulusId as well as IFMA-based GF(p) method are assigned in + * ippsGFpECInitStd* function. If modulusId is not set (i.e. GFp method is + * not IFMA-based), then bind regular table (not for IFMA implementation). + */ + if (ECP_MODULUS_ID(pEC) == cpID_PrimeP521r1) { + ECP_PREMULBP(pEC) = gfpec_precom_nistP521r1_radix52_fun(); + return ippStsNoErr; + } + } +#endif + + const cpPrecompAP *precomp = gfpec_precom_nistP521r1_fun(); + IppStatus sts = cpGFpECBindGxyTbl(secp521r1_p, precomp, pEC); + + /* setup pre-computed g-table and point access function */ + if (ippStsNoErr == sts) + ECP_PREMULBP(pEC) = precomp; + + return sts; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstdsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstdsm2.c new file mode 100644 index 000000000..ad4322e5d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbindstdsm2.c @@ -0,0 +1,109 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECBindGxyTblStdSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" +#include "pcpgfpmethod.h" + + +static IppStatus cpGFpECBindGxyTbl(const BNU_CHUNK_T* pPrime, + const cpPrecompAP* preComp, + IppsGFpECState* pEC) +{ + IppsGFpState *pGF = ECP_GFP(pEC); + gsModEngine *pGFE = GFP_PMA(pGF); + Ipp32u elemLen = (Ipp32u)GFP_FELEN(pGFE); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(pPrime, (cpSize)elemLen, GFP_MODULUS(pGFE), (cpSize)elemLen), ippStsBadArgErr); + + { + BNU_CHUNK_T *pbp_ec = ECP_G(pEC); + int cmpFlag; + BNU_CHUNK_T *pbp_tbl = cpEcGFpGetPool(1, pEC); + + selectAP select_affine_point = preComp->select_affine_point; + const BNU_CHUNK_T *pTbl = preComp->pTbl; + select_affine_point(pbp_tbl, pTbl, 1); + + /* check if EC's and G-table's Base Point is the same */ + cmpFlag = cpCmp_BNU(pbp_ec, (cpSize)elemLen * 2, pbp_tbl, (cpSize)elemLen * 2); + + cpEcGFpReleasePool(1, pEC); + + return cmpFlag ? ippStsBadArgErr : ippStsNoErr; + } +} + +/*F* +// Name: ippsGFpECBindGxyTblStdSM2 +// +// Purpose: Enables the use of base point-based pre-computed tables of ECSM2 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsBadArgErr pEC is not ECSM2 +// +// ippStsNoErr no error +// +// Parameters: +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECBindGxyTblStdSM2,(IppsGFpECState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + /* ModulusId as well as IFMA-based GF(p) method are assigned in + * ippsGFpECInitStd* function. If modulusId is not set (i.e. GFp method is + * not IFMA-based), then bind regular table (not for IFMA implementation). + */ + if (ECP_MODULUS_ID(pEC) == cpID_PrimeTPM_SM2) { + ECP_PREMULBP(pEC) = gfpec_precom_sm2_radix52_fun(); + return ippStsNoErr; + } + } +#endif + const cpPrecompAP* precomp = gfpec_precom_sm2_fun(); + IppStatus sts = cpGFpECBindGxyTbl(tpmSM2_p256_p, precomp, pEC); + + /* setup pre-computed g-table and point access function */ + if(ippStsNoErr == sts) + ECP_PREMULBP(pEC) = precomp; + + return sts; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbufsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbufsize.c new file mode 100644 index 000000000..b1dcc1a3c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecbufsize.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECScratchBufferSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpScratchBufferSize +// +// Purpose: Gets the size of the scratch buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pEC == NULL +// pBufferSize == NULL +// ippStsContextMatchErr invalid pEC->idCtx +// ippStsBadArgErr 0>=nScalars +// nScalars>6 +// ippStsNoErr no error +// +// Parameters: +// nScalars Number of scalar values. +// pEC Pointer to the context of the elliptic curve +// pBufferSize Pointer to the calculated buffer size in bytes. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECScratchBufferSize,(int nScalars, const IppsGFpECState* pEC, int* pBufferSize)) +{ + IPP_BAD_PTR2_RET(pEC, pBufferSize); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + IPP_BADARG_RET( (0>=nScalars)||(nScalars>IPP_MAX_EXPONENT_NUM), ippStsBadArgErr); + + { + /* select constant size of window */ + const int w = 5; + /* number of table entries */ + const int nPrecomputed = 1<<(w-1); /* because of signed digit representation of scalar is uses */ + + int pointDataSize = ECP_POINTLEN(pEC)*(Ipp32s)sizeof(BNU_CHUNK_T); + + *pBufferSize = nScalars * pointDataSize*nPrecomputed + CACHE_LINE_SIZE; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpeccmppoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeccmppoint.c new file mode 100644 index 000000000..d61bd3b70 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeccmppoint.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECCmpPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECCmpPoint +// +// Purpose: Compares two points +// +// Returns: Reason: +// ippStsNullPtrErr pP == NULL +// pQ == NULL +// pEC == NULL +// pResult == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pP->idCtx +// invalid pQ->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pP)!=GFP_FELEN() +// ECP_POINT_FELEN(pQ)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pP Pointer to the context of the first elliptic curve point +// pQ Pointer to the context of the second elliptic curve point +// pEC Pointer to the context of the elliptic curve +// pResult Pointer to the result of the comparison +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECCmpPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, + IppECResult* pResult, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR4_RET(pP, pQ, pResult, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pP), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pQ), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pQ)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + *pResult = gfec_ComparePoint(pP, pQ, pEC)? ippECPointIsEqual : ippECPointIsNotEqual; + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpeccpypoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeccpypoint.c new file mode 100644 index 000000000..437973a57 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeccpypoint.c @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECCpyPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECCpyPoint +// +// Purpose: Copies one point to another +// +// Returns: Reason: +// ippStsNullPtrErr pA == NULL +// pR == NULL +// pEC == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pA)!=GFP_FELEN() +// ECP_POINT_FELEN(pR)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the elliptic curve point being copied +// pR Pointer to the context of the elliptic curve point being changed +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECCpyPoint,(const IppsGFpECPoint* pA, + IppsGFpECPoint* pR, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR3_RET(pA, pR, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pR), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pA)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pR)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + gfec_CopyPoint(pR, pA, GFP_FELEN(GFP_PMA(ECP_GFP(pEC)))); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecdh.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecdh.c new file mode 100644 index 000000000..3c1c6a0f6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecdh.c @@ -0,0 +1,184 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECSharedSecretDH() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECSharedSecretDHC +// +// Purpose: Compute Shared Secret (Diffie-Hellman) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivateA +// NULL == pPublicB +// NULL == pShare +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pPrivateA->idCtx +// illegal pPublicB->idCtx +// illegal pShare->idCtx +// +// ippStsRangeErr not enough room for share key +// +// ippStsShareKeyErr (infinity) => z +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivateA pointer to own private key +// pPublicB pointer to alien public key +// pShare pointer to the shared secret value +// pEC pointer to the EC context +// pScratchBuffer pointer to the scratch buffer +// +*F*/ +IPPFUN(IppStatus, ippsGFpECSharedSecretDH,(const IppsBigNumState* pPrivateA, const IppsGFpECPoint* pPublicB, + IppsBigNumState* pShare, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + IppsGFpState *pGF; + gsModEngine *pGFE; + + /* EC context and buffer */ + IPP_BAD_PTR2_RET(pEC, pScratchBuffer); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + /* test private (own) key */ + IPP_BAD_PTR1_RET(pPrivateA); + IPP_BADARG_RET(!BN_VALID_ID(pPrivateA), ippStsContextMatchErr); + /* test if 0 < pPrivateA < Order */ + IPP_BADARG_RET(0==gfec_CheckPrivateKey(pPrivateA, pEC), ippStsInvalidPrivateKey); + + /* test public (other party) key */ + IPP_BAD_PTR1_RET(pPublicB); + IPP_BADARG_RET(!ECP_POINT_VALID_ID(pPublicB), ippStsContextMatchErr); + /* test if pPublicB belongs EC */ + IPP_BADARG_RET(0==gfec_IsPointOnCurve(pPublicB, pEC), ippStsInvalidPoint); + + /* test share secret value */ + IPP_BAD_PTR1_RET(pShare); + IPP_BADARG_RET(!BN_VALID_ID(pShare), ippStsContextMatchErr); + IPP_BADARG_RET((BN_ROOM(pShare) < GFP_FELEN(pGFE)), ippStsRangeErr); + + { + /* init tmp Point */ + IppsGFpECPoint T; + cpEcGFpInitPoint(/* pPoint = */ &T, + /* pData = */ cpEcGFpGetPool(1, pEC), + /* flags = */ 0, + /* pEC = */ pEC); + + int finite_point = 0; + const int elmLen = GFP_FELEN(pGFE); + /* share data */ + BNU_CHUNK_T *pShareData = BN_NUMBER(pShare); + int nsShare = BN_ROOM(pShare); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + switch (ECP_MODULUS_ID(pEC)) { + case cpID_PrimeP256r1: { + finite_point = gfec_SharedSecretDH_nistp256_avx512(&T, pPublicB, BN_NUMBER(pPrivateA), BN_SIZE(pPrivateA), pEC, pScratchBuffer); + if (finite_point) { + cpGFpElementCopy(pShareData, ECP_POINT_X(&T), elmLen); + cpGFpElementPad(pShareData + elmLen, nsShare - elmLen, 0); + } + goto exit; + break; + } + case cpID_PrimeP384r1: { + finite_point = gfec_SharedSecretDH_nistp384_avx512(&T, pPublicB, BN_NUMBER(pPrivateA), BN_SIZE(pPrivateA), pEC, pScratchBuffer); + if (finite_point) { + cpGFpElementCopy(pShareData, ECP_POINT_X(&T), elmLen); + cpGFpElementPad(pShareData + elmLen, nsShare - elmLen, 0); + } + goto exit; + break; + } + case cpID_PrimeP521r1: { + finite_point = gfec_SharedSecretDH_nistp521_avx512(&T, pPublicB, BN_NUMBER(pPrivateA), BN_SIZE(pPrivateA), pEC, pScratchBuffer); + if (finite_point) { + cpGFpElementCopy(pShareData, ECP_POINT_X(&T), elmLen); + cpGFpElementPad(pShareData + elmLen, nsShare - elmLen, 0); + } + goto exit; + break; + } + case cpID_PrimeTPM_SM2: { + finite_point = gfec_SharedSecretDH_sm2_avx512(&T, pPublicB, BN_NUMBER(pPrivateA), BN_SIZE(pPrivateA), pEC, pScratchBuffer); + if (finite_point) { + cpGFpElementCopy(pShareData, ECP_POINT_X(&T), elmLen); + cpGFpElementPad(pShareData + elmLen, nsShare - elmLen, 0); + } + goto exit; + break; + } + default: + /* Go to default implementation below */ + break; + } + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + { + /* T = [privateA]pPublicB */ + gfec_MulPoint(&T, pPublicB, BN_NUMBER(pPrivateA), BN_SIZE(pPrivateA), /*ECP_ORDBITSIZE(pEC),*/ pEC, pScratchBuffer); + /* share = T.x */ + IppsGFpElement elm; + /* Buffer by GFpElement - get in Pool data */ + cpGFpElementConstruct(&elm, cpGFpGetPool(1, pGFE), elmLen); + + finite_point = gfec_GetPoint(GFPE_DATA(&elm), NULL, &T, pEC); + + /* check finit point */ + if (finite_point) { + /* share = decode(T.x) */ + GFP_METHOD(pGFE)->decode(pShareData, GFPE_DATA(&elm), pGFE); + cpGFpElementPad(pShareData + elmLen, nsShare - elmLen, 0); + } + + cpGFpReleasePool(1, pGFE); /* GFpElement */ + } + +#if (_IPP32E >= _IPP32E_K1) +exit: +#endif + + if (finite_point) { + BN_SIGN(pShare) = ippBigNumPOS; + FIX_BNU(pShareData, nsShare); + BN_SIZE(pShare) = nsShare; + } + cpEcGFpReleasePool(1, pEC); /* ECPoint */ + return finite_point ? ippStsNoErr : ippStsShareKeyErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecdhc.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecdhc.c new file mode 100644 index 000000000..8bff02e57 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecdhc.c @@ -0,0 +1,141 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECSharedSecretDHC() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +/*F* +// Name: ippsGFpECSharedSecretDHC +// +// Purpose: Compute Shared Secret (Diffie-Hellman with cofactor) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivateA +// NULL == pPublicB +// NULL == pShare +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pPrivateA->idCtx +// illegal pPublicB->idCtx +// illegal pShare->idCtx +// +// ippStsRangeErr not enough room for share key +// +// ippStsShareKeyErr (infinity) => z +// +// ippStsNoErr no errors +// +// Parameters: +// pPrivateA pointer to own private key +// pPublicB pointer to alien public key +// pShare pointer to the shared secret value +// pEC pointer to the EC context +// +*F*/ +IPPFUN(IppStatus, ippsGFpECSharedSecretDHC,(const IppsBigNumState* pPrivateA, const IppsGFpECPoint* pPublicB, + IppsBigNumState* pShare, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + /* EC context and buffer */ + IPP_BAD_PTR2_RET(pEC, pScratchBuffer); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + /* test private (own) key */ + IPP_BAD_PTR1_RET(pPrivateA); + IPP_BADARG_RET(!BN_VALID_ID(pPrivateA), ippStsContextMatchErr); + /* test if 0 < pPrivateA < Order */ + IPP_BADARG_RET(0 == gfec_CheckPrivateKey(pPrivateA, pEC), ippStsInvalidPrivateKey); + + /* test public (other party) key */ + IPP_BAD_PTR1_RET(pPublicB); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPublicB), ippStsContextMatchErr ); + /* test if pPublicB belongs EC */ + IPP_BADARG_RET(0 == gfec_IsPointOnCurve(pPublicB, pEC), ippStsInvalidPoint); + + /* test share key */ + IPP_BAD_PTR1_RET(pShare); + IPP_BADARG_RET(!BN_VALID_ID(pShare), ippStsContextMatchErr); + IPP_BADARG_RET((BN_ROOM(pShare)decode(pShareData, GFPE_DATA(&elm), pGFE); + cpGFpElementPad(pShareData+elmLen, nsShare-elmLen, 0); + + BN_SIGN(pShare) = ippBigNumPOS; + FIX_BNU(pShareData, nsShare); + BN_SIZE(pShare) = nsShare; + } + + cpGFpReleasePool(2, pGFE); + cpEcGFpReleasePool(1, pEC); + + return finite_point? ippStsNoErr : ippStsShareKeyErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesdecryptsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesdecryptsm2.c new file mode 100644 index 000000000..053268c95 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesdecryptsm2.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESDecrypt_SM2() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECESDecrypt_SM2 +// +// Purpose: Decrypts the given buffer, updates the auth tag +// +// Returns: Reason: +// ippStsNullPtrErr pInput == NULL / pOutput == NULL / pState == NULL +// ippStsContextMatchErr pState invalid context or the algorithm is in an invalid state +// ippStsSizeErr dataLen < 0 +// ippStsNoErr no errors +// +// Parameters: +// pInput Pointer to input data +// pOutput Pointer to output data +// dataLen Size of input and output buffers +// pState Pointer to a SM2 algorithm state +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESDecrypt_SM2, (const Ipp8u* pInput, Ipp8u* pOutput, int dataLen, IppsECESState_SM2* pState)) { + IPP_BAD_PTR3_RET(pInput, pOutput, pState); + IPP_BADARG_RET(!VALID_ECES_SM2_ID(pState), ippStsContextMatchErr); + /* a shared secret should be computed and the process should not be finished by getTag */ + IPP_BADARG_RET(pState->state != ECESAlgoProcessing, ippStsIncompleteContextErr); + IPP_BADARG_RET(dataLen < 0, ippStsSizeErr); + + { + int i; + for (i = 0; i < dataLen; ++i) { + pOutput[i] = pInput[i] ^ cpECES_SM2KdfNextByte(pState); + } + } + ippsHashUpdate_rmf(pOutput, dataLen, pState->pTagHasher); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesencryptsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesencryptsm2.c new file mode 100644 index 000000000..42a0f01b4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesencryptsm2.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESEncrypt_SM2() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECESEncrypt_SM2 +// +// Purpose: Encrypts the given buffer, updates the auth tag +// +// Returns: Reason: +// ippStsNullPtrErr pInput == NULL / pOutput == NULL / pState == NULL +// ippStsContextMatchErr pState invalid context or the algorithm is in an invalid state +// ippStsSizeErr dataLen < 0 +// ippStsNoErr no errors +// +// Parameters: +// pInput Pointer to input data +// pOutput Pointer to output data +// dataLen Size of input and output buffers +// pState Pointer to a SM2 algorithm state +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESEncrypt_SM2, (const Ipp8u* pInput, Ipp8u* pOutput, int dataLen, IppsECESState_SM2* pState)) { + IPP_BAD_PTR3_RET(pInput, pOutput, pState); + IPP_BADARG_RET(!VALID_ECES_SM2_ID(pState), ippStsContextMatchErr); + /* a shared secret should be computed and the process should not be finished by getTag */ + IPP_BADARG_RET(pState->state != ECESAlgoProcessing, ippStsIncompleteContextErr); + IPP_BADARG_RET(dataLen < 0, ippStsSizeErr); + + ippsHashUpdate_rmf(pInput, dataLen, pState->pTagHasher); + { + int i; + for (i = 0; i < dataLen; ++i) { + pOutput[i] = pInput[i] ^ cpECES_SM2KdfNextByte(pState); + } + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesfinalsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesfinalsm2.c new file mode 100644 index 000000000..a6a55981a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesfinalsm2.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESFinal_SM2() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECESFinal_SM2 +// +// Purpose: Ends SM2 algorithm chain and returns an auth tag +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL / pState == NULL +// ippStsContextMatchErr pState invalid context or the algorithm is in an invalid state +// ippStsSizeErr tagLen < 0 || tagLen > IPP_SM3_DIGEST_BITSIZE / BYTESIZE +// ippStsShareKeyErr All the kdf provided bytes were 0. The operation is completed successfully, but the warning is given +// ippStsNoErr no errors +// +// Parameters: +// pTag Pointer to a tag buffer to write to +// tagLen Size of the tag [0; IPP_SM3_DIGEST_BITSIZE / BYTESIZE] +// pState Pointer to a SM2 algorithm state +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESFinal_SM2, (Ipp8u* pTag, int tagLen, IppsECESState_SM2* pState)) { + IPP_BAD_PTR2_RET(pTag, pState); + IPP_BADARG_RET(!VALID_ECES_SM2_ID(pState), ippStsContextMatchErr); + /* a shared secret should be computed and the process should not be finished by getTag */ + IPP_BADARG_RET(pState->state != ECESAlgoProcessing, ippStsIncompleteContextErr); + IPP_BADARG_RET(tagLen < 0 || tagLen > IPP_SM3_DIGEST_BITSIZE / BYTESIZE, ippStsSizeErr); + + ippsHashUpdate_rmf(pState->pSharedSecret + pState->sharedSecretLen / 2, pState->sharedSecretLen / 2, pState->pTagHasher); + if (tagLen == IPP_SM3_DIGEST_BITSIZE / BYTESIZE) { + ippsHashFinal_rmf(pTag, pState->pTagHasher); + } else { + Ipp8u pFinal[IPP_SM3_DIGEST_BITSIZE / BYTESIZE]; + int i; + ippsHashFinal_rmf(pFinal, pState->pTagHasher); + for (i = 0; i < tagLen; ++i) { + pTag[i] = pFinal[i]; + } + } + + pState->state = ECESAlgoFinished; /* cannot proceed futher due to closing ippsSM3Update */ + + /* do the operation, but return an error code in 0-case */ + return pState->wasNonZero ? ippStsNoErr : ippStsShareKeyErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesgetbufferssizesm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesgetbufferssizesm2.c new file mode 100644 index 000000000..bd0f0ee7c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesgetbufferssizesm2.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESGetBuffersSize_SM2() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECESGetBuffersSize_SM2 +// +// Purpose: Returns sizes of used buffers +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL if pPublicKeySize != NULL or all the pointers are NULLs +// ippStsContextMatchErr pState invalid context if pPublicKeySize != NULL +// ippStsNoErr no errors +// +// Parameters: +// pPublicKeySize Pointer to write public (x||y) key length in bytes +// pMaximumTagSize Pointer to write maximum tag size in bytes +// pState Pointer to a state to get pPublicKeySize from +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESGetBuffersSize_SM2, (int* pPublicKeySize, + int* pMaximumTagSize, const IppsECESState_SM2* pState)) { + IPP_BADARG_RET(pPublicKeySize == NULL && pMaximumTagSize == NULL && pState == NULL, ippStsNullPtrErr); + + if (pMaximumTagSize) + *pMaximumTagSize = IPP_SM3_DIGEST_BITSIZE / BYTESIZE; + if (pPublicKeySize) { + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!VALID_ECES_SM2_ID(pState), ippStsContextMatchErr); + *pPublicKeySize = pState->sharedSecretLen; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesgetsizesm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesgetsizesm2.c new file mode 100644 index 000000000..1eee866e5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesgetsizesm2.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESGetSize_SM2() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECESGetSize_SM2 +// +// Purpose: Computes space required to allocate a SM2 algorithm state +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL / pEC == NULL +// ippStsContextMatchErr pEC invalid context +// ippStsNotSupportedModeErr pGFE->extdegree > 1 +// ippStsNoErr no errors +// +// Parameters: +// pEC Pointer to an EC to calculate a shared secret size +// pSize Pointer to write a SM2 algorithm state size +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESGetSize_SM2, (const IppsGFpECState* pEC, int* pSize)) { + IPP_BAD_PTR2_RET(pEC, pSize); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!pEC->subgroup, ippStsContextMatchErr); + IPP_BADARG_RET(1 < pEC->pGF->pGFE->extdegree, ippStsNotSupportedModeErr); + + { + int sm3size; + ippsHashGetSize_rmf(&sm3size); + + *pSize = (Ipp32s)sizeof(IppsECESState_SM2) + sm3size * 2 + BITS2WORD8_SIZE(pEC->pGF->pGFE->modBitLen) * 2; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesinitsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesinitsm2.c new file mode 100644 index 000000000..fffea8474 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesinitsm2.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESInit_SM2() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECESInit_SM2 +// +// Purpose: Inits the SM2 algorithm state +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL / pEC == NULL +// ippStsContextMatchErr pEC, pPoint invalid context +// ippStsNotSupportedModeErr pGFE->extdegree > 1 +// ippStsSizeErr size of the provided state is less than needed +// ippStsNoErr no errors +// +// Parameters: +// pEC Pointer to an EC to calculate a shared secret size +// pState Pointer to a SM2 algorithm state buffer +// avaliableCtxSize Count of avaliable bytes in the context allocation +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESInit_SM2, (IppsGFpECState* pEC, IppsECESState_SM2* pState, int avaliableCtxSize)) { + IPP_BAD_PTR2_RET(pEC, pState); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!pEC->subgroup, ippStsContextMatchErr); + IPP_BADARG_RET(1 < pEC->pGF->pGFE->extdegree, ippStsNotSupportedModeErr); + + { + int realCtxSize; + ippsGFpECESGetSize_SM2(pEC, &realCtxSize); + IPP_BADARG_RET(avaliableCtxSize < realCtxSize, ippStsSizeErr); + + { + int sm3size; + ippsHashGetSize_rmf(&sm3size); + + ECES_SM2_SET_ID(pState); + pState->sharedSecretLen = BITS2WORD8_SIZE(pEC->pGF->pGFE->modBitLen) * 2; + pState->pSharedSecret = ((Ipp8u*)pState) + sizeof(IppsECESState_SM2); + pState->pKdfHasher = (IppsHashState_rmf*)(((Ipp8u*)pState) + sizeof(IppsECESState_SM2) + pState->sharedSecretLen); + pState->pTagHasher = (IppsHashState_rmf*)(((Ipp8u*)pState) + sizeof(IppsECESState_SM2) + pState->sharedSecretLen + sm3size); + + ippsHashInit_rmf(pState->pKdfHasher, ippsHashMethod_SM3()); + + pState->state = ECESAlgoInit; + + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecessetkeysm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecessetkeysm2.c new file mode 100644 index 000000000..3f50051eb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecessetkeysm2.c @@ -0,0 +1,98 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESSetKey_SM2() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECESSetKey_SM2 +// +// Purpose: Resets all counters, computes shared secret and saves it into the SM2 algorithm state +// +// Returns: Reason: +// ippStsNullPtrErr pPrivate == NULL / pPublic == NULL / pState == NULL / pEC == NULL +// ippStsContextMatchErr the algorithm is in an invalid state or any of the specified contexts does not match the operation +// ippStsOutOfRangeErr private key does not belong to the EC's finite field or public key/result does not belong to EC +// ippStsNotSupportedModeErr pGFE->extdegree > 1 +// ippStsBadArgErr curve element size is not the same as in init / pPrivate is negative / pPrivate > pEC GFp mod +// ippStsPointAtInfinity shared secret is a point at infinity +// ippStsNoErr no errors +// +// Parameters: +// pEC Pointer to an EC to calculate a shared secret size +// pState Pointer to a SM2 algorithm state buffer +// pPrivate Pointer to a private component of shared secret +// pPublic Pointer to a public component +// pEcScratchBuffer Pointer to a scratch buffer for computations on the EC +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESSetKey_SM2, (const IppsBigNumState* pPrivate, + const IppsGFpECPoint* pPublic, IppsECESState_SM2* pState, + IppsGFpECState* pEC, Ipp8u* pEcScratchBuffer)) { + IPP_BAD_PTR4_RET(pPrivate, pPublic, pState, pEC); + IPP_BADARG_RET(!VALID_ECES_SM2_ID(pState), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!pEC->subgroup, ippStsContextMatchErr); + IPP_BADARG_RET(1 < pEC->pGF->pGFE->extdegree, ippStsNotSupportedModeErr); + + { + gsModEngine* pGFE = pEC->pGF->pGFE; + /* curve element size is not the same */ + IPP_BADARG_RET(BITS2WORD8_SIZE(pGFE->modBitLen) * 2 != pState->sharedSecretLen, ippStsBadArgErr); + + { + IppStatus multResult; + IppsGFpECPoint PT; + IppsGFpElement ptX, ptY; + int finitePoint = 0; + + cpEcGFpInitPoint(&PT, cpEcGFpGetPool(1, pEC), 0, pEC); + multResult = ippsGFpECMulPoint(pPublic, pPrivate, &PT, pEC, pEcScratchBuffer); + if (ippStsNoErr == multResult) { + cpGFpElementConstruct(&ptX, cpGFpGetPool(1, pGFE), pGFE->modLen); + cpGFpElementConstruct(&ptY, cpGFpGetPool(1, pGFE), pGFE->modLen); + finitePoint = gfec_GetPoint(ptX.pData, ptY.pData, &PT, pEC); + if (finitePoint) { + ippsGFpGetElementOctString(&ptX, pState->pSharedSecret, pState->sharedSecretLen / 2, pEC->pGF); + ippsGFpGetElementOctString(&ptY, pState->pSharedSecret + pState->sharedSecretLen / 2, pState->sharedSecretLen / 2, pEC->pGF); + + pState->kdfCounter = 0; + pState->kdfIndex = IPP_SM3_DIGEST_BITSIZE / BYTESIZE; /* will generate a kdf window */ + pState->wasNonZero = 0; + pState->state = ECESAlgoKeySet; + } + cpGFpReleasePool(2, pGFE); /* release ptX and ptY from the pool */ + } + cpEcGFpReleasePool(1, pEC); /* release PT from the pool */ + + if (multResult) + return multResult; + return finitePoint ? ippStsNoErr : ippStsPointAtInfinity; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecessm2.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecessm2.h new file mode 100644 index 000000000..e45b9aef0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecessm2.h @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// ES encryption/decryption API +// +// +*/ + +#if !defined(_CP_GFP_ES_SM2_H) +#define _CP_GFP_ES_SM2_H + +#include "owncp.h" + +typedef enum { + ECESAlgoInit, + ECESAlgoKeySet, + ECESAlgoProcessing, + ECESAlgoFinished +} ECESAlgoState; + +struct _cpStateECES_SM2 { + Ipp32u idCtx; + Ipp8u* pSharedSecret; + Ipp32s sharedSecretLen; + + ECESAlgoState state; + + Ipp32u kdfCounter; + Ipp8u pKdfWindow[IPP_SM3_DIGEST_BITSIZE / BYTESIZE]; + Ipp8u wasNonZero; + Ipp8u kdfIndex; + + IppsHashState_rmf* pKdfHasher; + IppsHashState_rmf* pTagHasher; +}; + +#define ECES_SM2_SET_ID(stt) ((stt)->idCtx = (Ipp32u)idxCtxECES_SM2 ^ (Ipp32u)IPP_UINT_PTR(stt)) +#define VALID_ECES_SM2_ID(stt) ((((stt)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((stt))) == (Ipp32u)idxCtxECES_SM2) + +/* get a byte, update 0-kdf status */ +__INLINE Ipp8u cpECES_SM2KdfNextByte(IppsECESState_SM2* pState) { + if (pState->kdfIndex == IPP_SM3_DIGEST_BITSIZE / BYTESIZE) { + ++pState->kdfCounter; + pState->kdfIndex = 0; + + { + Ipp8u ctnStr[sizeof(Ipp32u)]; + ippsHashUpdate_rmf(pState->pSharedSecret, pState->sharedSecretLen, pState->pKdfHasher); + U32_TO_HSTRING(ctnStr, pState->kdfCounter); + ippsHashUpdate_rmf(ctnStr, sizeof(Ipp32u), pState->pKdfHasher); + ippsHashFinal_rmf(pState->pKdfWindow, pState->pKdfHasher); + } + } + + pState->wasNonZero |= pState->pKdfWindow[pState->kdfIndex]; + + return pState->pKdfWindow[pState->kdfIndex++]; +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesstartsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesstartsm2.c new file mode 100644 index 000000000..27b7ac105 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecesstartsm2.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECESStart_SM2() +// +*/ + +#include "pcpgfpecessm2.h" + +/*F* +// Name: ippsGFpECESStart_SM2 +// +// Purpose: Starts an SM2 encryption chain. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsContextMatchErr pState invalid context or the algorithm is in an invalid state +// ippStsNoErr no errors +// +// Parameters: +// pState Pointer to a SM2 algorithm state +// +*F*/ +IPPFUN(IppStatus, ippsGFpECESStart_SM2, (IppsECESState_SM2* pState)) { + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!VALID_ECES_SM2_ID(pState), ippStsContextMatchErr); + IPP_BADARG_RET(pState->state != ECESAlgoKeySet, ippStsContextMatchErr); + + ippsHashInit_rmf(pState->pTagHasher, ippsHashMethod_SM3()); + ippsHashUpdate_rmf(pState->pSharedSecret, pState->sharedSecretLen / 2, pState->pTagHasher); + + pState->state = ECESAlgoProcessing; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecget.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecget.c new file mode 100644 index 000000000..1359fb634 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecget.c @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECGet() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECGet +// +// Purpose: Extracts the parameters of an elliptic curve +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pA->idCtx +// invalid pB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM(pA)!=GFP_FELEN(pGFE) +// GFPE_ROOM(pB)!=GFP_FELEN(pGFE) +// +// ippStsNoErr no error +// +// Parameters: +// ppGFp Pointer to the pointer to the context of underlying finite field +// pA Pointer to a copy of the coefficient A of the equation defining the elliptic curve +// pB Pointer to a copy of the coefficient B of the equation defining the elliptic curve +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECGet,(IppsGFpState** const ppGFp, + IppsGFpElement* pA, IppsGFpElement* pB, + const IppsGFpECState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + { + const IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + Ipp32u elementSize = (Ipp32u)GFP_FELEN(pGFE); + + if(ppGFp) { + *ppGFp = (IppsGFpState*)pGF; + } + + if(pA) { + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( GFPE_ROOM(pA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + cpGFpElementCopy(GFPE_DATA(pA), ECP_A(pEC), (cpSize)elementSize); + } + if(pB) { + IPP_BADARG_RET( !GFPE_VALID_ID(pB), ippStsContextMatchErr ); + IPP_BADARG_RET( GFPE_ROOM(pB)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + cpGFpElementCopy(GFPE_DATA(pB), ECP_B(pEC), (cpSize)elementSize); + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetinfo.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetinfo.c new file mode 100644 index 000000000..3678c4917 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetinfo.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECGetInfo_GF() +// +*/ + +#include "owncp.h" +#include "pcpeccp.h" + + +/*F* +// Name: ippsGFpECGetInfo_GF +// +// Purpose: Returns info regarding underlying GF +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pInfo +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pInfo Pointer to the info structure +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ +IPPFUN(IppStatus, ippsGFpECGetInfo_GF,(IppsGFpInfo* pInfo, const IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pInfo, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + return ippsGFpGetInfo(pInfo, ECP_GFP(pEC)); + #if 0 + { + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFpx = GFP_PMA(pGF); /* current */ + gsModEngine* pGFp = cpGFpBasic(pGFpx); /* basic */ + pInfo->parentGFdegree = MOD_EXTDEG(pGFpx); /* parent extension */ + pInfo->basicGFdegree = cpGFpBasicDegreeExtension(pGFpx); /* total basic extention */ + pInfo->basicElmBitSize = GFP_FEBITLEN(pGFp); /* basic bitsise */ + + return ippStsNoErr; + } + #endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpoint.c new file mode 100644 index 000000000..56772fb84 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpoint.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECGetPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECGetPoint +// +// Purpose: Retrieves coordinates of a point on an elliptic curve +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// pX != NULL && invalid pX->idCtx +// pY != NULL && invalid pY->idCtx +// pX != NULL && GFPE_ROOM(pX)!=GFP_FELEN() +// pY != NULL && GFPE_ROOM(pY)!=GFP_FELEN() +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// pX != NULL && GFPE_ROOM(pX)!=GFP_FELEN() +// pY != NULL && GFPE_ROOM(pY)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// pX, pY Pointers to the X and Y coordinates of a point on the elliptic curve +// +// Note: +// Is not a fact that computed point belongs to BP-related subgroup BP +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECGetPoint,(const IppsGFpECPoint* pPoint, + IppsGFpElement* pX, IppsGFpElement* pY, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pPoint, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BADARG_RET( pX && !GFPE_VALID_ID(pX), ippStsContextMatchErr ); + IPP_BADARG_RET( pY && !GFPE_VALID_ID(pY), ippStsContextMatchErr ); + + IPP_BADARG_RET( pX && GFPE_ROOM(pX)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( pY && GFPE_ROOM(pY)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + /* returns (X,Y) == (0,0) if Point is at infinity */ + gfec_GetPoint((pX)? GFPE_DATA(pX):NULL, (pY)? GFPE_DATA(pY):NULL, pPoint, pEC); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpointoctstring.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpointoctstring.c new file mode 100644 index 000000000..37b103b2a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpointoctstring.c @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECGetPointOctString() +// +*/ +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECGetPointOctString +// +// Purpose: Converts a point on EC into x||y octstring +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL / pEC == NULL / pStr == NULL +// ippStsContextMatchErr pEC, pPoint invalid context +// ippStsNotSupportedModeErr pGFE->extdegree > 1 +// ippStsSizeErr strLen is not equal to double GFp element +// ippStsOutOfRangeErr the point does not belong to the EC +// ippStsPointAtInfinity a point on infinity cannot be converted to a string +// ippStsNoErr no errors +// +// Parameters: +// pStr pointer to the string to read from +// strLen length of the string +// pPoint pointer to output point +// pEC EC ctx +// +*F*/ +IPPFUN(IppStatus, ippsGFpECGetPointOctString, (const IppsGFpECPoint* pPoint, + Ipp8u* pStr, int strLen, IppsGFpECState* pEC)) { + IPP_BAD_PTR3_RET(pPoint, pEC, pStr); + IPP_BADARG_RET(!ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + { + gsModEngine* pGFE = pEC->pGF->pGFE; + IppsGFpInfo gfi; + ippsGFpGetInfo(&gfi, pEC->pGF); + + { + int elemLenBits = gfi.basicGFdegree * gfi.basicElmBitSize; + int elemLenBytes = BITS2WORD8_SIZE(elemLenBits); + int elemLenChunks = BITS_BNU_CHUNK(elemLenBits); + IPP_BADARG_RET(strLen != elemLenBytes * 2, ippStsSizeErr); + IPP_BADARG_RET(pPoint->elementSize != elemLenChunks, ippStsOutOfRangeErr); + + { + int finitePoint; + IppsGFpElement ptX, ptY; + + cpGFpElementConstruct(&ptX, cpGFpGetPool(1, pGFE), elemLenChunks); + cpGFpElementConstruct(&ptY, cpGFpGetPool(1, pGFE), elemLenChunks); + finitePoint = gfec_GetPoint(ptX.pData, ptY.pData, pPoint, pEC); + if (finitePoint) { + ippsGFpGetElementOctString(&ptX, pStr, elemLenBytes, pEC->pGF); + pStr += elemLenBytes; + ippsGFpGetElementOctString(&ptY, pStr, elemLenBytes, pEC->pGF); + } + + cpGFpReleasePool(2, pGFE); /* release ptX and ptY from the pool */ + + return finitePoint ? ippStsNoErr : ippStsPointAtInfinity; + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpointreg.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpointreg.c new file mode 100644 index 000000000..8dad83bf9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetpointreg.c @@ -0,0 +1,107 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECGetPointRegular() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECGetPointRegular +// +// Purpose: Retrieves coordinates of a point on an elliptic curve in the regular domain +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// invalid pX->idCtx +// invalid pY->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// BN_ROOM(pX)*BNU_CHUNK_BITSdecode(x, x, pGFE); + ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)x, pX); + } + if(pY) { + GFP_METHOD(pGFE)->decode(y, y, pGFE); + ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)y, pY); + } + + cpGFpReleasePool(2, pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetsize.c new file mode 100644 index 000000000..3b00f1cc2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetsize.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECGetSize +// +// Purpose: Gets the size of an elliptic curve over the finite field +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pSize +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pSize Buffer size in bytes needed for the IppsGFpECState context +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECGetSize,(const IppsGFpState* pGFp, int* pSize)) +{ + IPP_BAD_PTR2_RET(pGFp, pSize); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + *pSize = cpGFpECGetSize(cpGFpBasicDegreeExtension(pGFE), GFP_FEBITLEN(cpGFpBasic(pGFE))); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetsubgroup.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetsubgroup.c new file mode 100644 index 000000000..d6ba8149d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecgetsubgroup.c @@ -0,0 +1,121 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECGetSubgroup() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECGet +// +// Purpose: Extracts the parameters (base point and its order) of an elliptic curve +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// +// ippStsContextMatchErr invalid pEC->idCtx +// NULL == pEC->subgroup +// invalid pX->idCtx +// invalid pY->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM(pX)!=GFP_FELEN(pGFE) +// GFPE_ROOM(pY)!=GFP_FELEN(pGFE) +// +// ippStsLengthErr BN_ROOM(pOrder) < orderLen +// BN_ROOM(pCofactor) < cofactorLen +// +// ippStsNoErr no error +// +// Parameters: +// ppGFp Pointer to the pointer to the context of underlying finite field +// pX, pY Pointers to the X and Y coordinates of the base point of the elliptic curve +// pOrder Pointer to the big number context storing the order of the base point. +// pCofactor Pointer to the big number context storing the cofactor. +// pEC Pointer to the context of the elliptic curve. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECGetSubgroup,(IppsGFpState** const ppGFp, + IppsGFpElement* pX, IppsGFpElement* pY, + IppsBigNumState* pOrder, + IppsBigNumState* pCofactor, + const IppsGFpECState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + { + const IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + Ipp32u elementSize = (Ipp32u)GFP_FELEN(pGFE); + + if(ppGFp) { + *ppGFp = (IppsGFpState*)pGF; + } + + if(pX) { + IPP_BADARG_RET( !GFPE_VALID_ID(pX), ippStsContextMatchErr ); + IPP_BADARG_RET( GFPE_ROOM(pX)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + cpGFpElementCopy(GFPE_DATA(pX), ECP_G(pEC), (cpSize)elementSize); + } + if(pY) { + IPP_BADARG_RET( !GFPE_VALID_ID(pY), ippStsContextMatchErr ); + IPP_BADARG_RET( GFPE_ROOM(pY)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + cpGFpElementCopy(GFPE_DATA(pY), ECP_G(pEC)+elementSize, (cpSize)elementSize); + } + + if(pOrder) { + BNU_CHUNK_T* pOrderData = MOD_MODULUS(ECP_MONT_R(pEC)); + int orderBitSize = ECP_ORDBITSIZE(pEC); + int orderLen = BITS_BNU_CHUNK(orderBitSize); + FIX_BNU(pOrderData, orderLen); + + IPP_BADARG_RET(!BN_VALID_ID(pOrder), ippStsContextMatchErr); + IPP_BADARG_RET(BN_ROOM(pOrder) < orderLen, ippStsLengthErr); + + ZEXPAND_COPY_BNU(BN_NUMBER(pOrder), BN_ROOM(pOrder), pOrderData, orderLen); + BN_SIZE(pOrder) = orderLen; + BN_SIGN(pOrder) = ippBigNumPOS; + } + + if(pCofactor) { + BNU_CHUNK_T* pCofactorData = ECP_COFACTOR(pEC); + int cofactorLen = (cpSize)elementSize; + FIX_BNU(pCofactorData, cofactorLen); + + IPP_BADARG_RET(!BN_VALID_ID(pCofactor), ippStsContextMatchErr); + IPP_BADARG_RET(BN_ROOM(pCofactor) < cofactorLen, ippStsLengthErr); + + ZEXPAND_COPY_BNU(BN_NUMBER(pCofactor), BN_ROOM(pCofactor), pCofactorData, cofactorLen); + BN_SIZE(pCofactor) = cofactorLen; + BN_SIGN(pCofactor) = ippBigNumPOS; + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinit.c new file mode 100644 index 000000000..75a1098cd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinit.c @@ -0,0 +1,122 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" +#include "pcpgfpmethod.h" + +/*F* +// Name: ippsGFpECInit +// +// Purpose: Initializes the context of an elliptic curve over a finite field. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pA +// NULL == pB +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pA->idCtx +// invalid pB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM(pA)!=GFP_FELEN(pGFE) +// GFPE_ROOM(pB)!=GFP_FELEN(pGFE) +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pA Pointer to the coefficient A of the equation defining the elliptic curve +// pB Pointer to the coefficient B of the equation defining the elliptic curve +// pEC Pointer to the context of the elliptic curve being initialized +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInit,(const IppsGFpState* pGFp, + const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGFp, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + Ipp8u* ptr = (Ipp8u*)pEC; + + gsModEngine* pGFE = GFP_PMA(pGFp); + int elemLen = GFP_FELEN(pGFE); + + int maxOrderBits = 1+ cpGFpBasicDegreeExtension(pGFE) * GFP_FEBITLEN(cpGFpBasic(pGFE)); /* Hasse's theorem */ + #if defined(_LEGACY_ECCP_SUPPORT_) + int maxOrdLen = BITS_BNU_CHUNK(maxOrderBits); + #endif + + int modEngineCtxSize; + gsModEngineGetSize(maxOrderBits, MONT_DEFAULT_POOL_LENGTH, &modEngineCtxSize); + + ECP_SET_ID(pEC); + ECP_MODULUS_ID(pEC) = cpID_Prime; + ECP_GFP(pEC) = (IppsGFpState*)pGFp; + ECP_SUBGROUP(pEC) = 0; + ECP_POINTLEN(pEC) = elemLen*3; + ECP_ORDBITSIZE(pEC) = maxOrderBits; + ECP_SPECIFIC(pEC) = ECP_ARB; + + ptr += sizeof(IppsGFpECState); + ECP_A(pEC) = (BNU_CHUNK_T*)(ptr); ptr += elemLen*(Ipp32s)sizeof(BNU_CHUNK_T); + ECP_B(pEC) = (BNU_CHUNK_T*)(ptr); ptr += elemLen*(Ipp32s)sizeof(BNU_CHUNK_T); + ECP_G(pEC) = (BNU_CHUNK_T*)(ptr); ptr += ECP_POINTLEN(pEC)*(Ipp32s)sizeof(BNU_CHUNK_T); + ECP_PREMULBP(pEC) = (cpPrecompAP*)NULL; + ECP_MONT_R(pEC) = (gsModEngine*)(ptr); ptr += modEngineCtxSize; + ECP_COFACTOR(pEC) = (BNU_CHUNK_T*)(ptr); ptr += elemLen*(Ipp32s)sizeof(BNU_CHUNK_T); + #if defined(_LEGACY_ECCP_SUPPORT_) + ECP_PUBLIC(pEC) = (BNU_CHUNK_T*)(ptr); ptr += 3*elemLen*(Ipp32s)sizeof(BNU_CHUNK_T); + ECP_PUBLIC_E(pEC) = (BNU_CHUNK_T*)(ptr); ptr += 3*elemLen*(Ipp32s)sizeof(BNU_CHUNK_T); + ECP_PRIVAT(pEC) = (BNU_CHUNK_T*)(ptr); ptr += maxOrdLen*(Ipp32s)sizeof(BNU_CHUNK_T); + ECP_PRIVAT_E(pEC) = (BNU_CHUNK_T*)(ptr); ptr += maxOrdLen*(Ipp32s)sizeof(BNU_CHUNK_T); + ECP_SBUFFER(pEC) = (BNU_CHUNK_T*)0; + #endif + ECP_POOL(pEC) = (BNU_CHUNK_T*)(ptr); //ptr += ECP_POINTLEN(pEC)*sizeof(BNU_CHUNK_T)*EC_POOL_SIZE; + + cpGFpElementPad(ECP_A(pEC), elemLen, 0); + cpGFpElementPad(ECP_B(pEC), elemLen, 0); + cpGFpElementPad(ECP_G(pEC), elemLen*3, 0); + //gsModEngineInit(ECP_MONT_R(pEC), NULL, maxOrderBits, MONT_DEFAULT_POOL_LENGTH, gsModArithMont()); + gsModEngineInit(ECP_MONT_R(pEC), NULL, maxOrderBits, MONT_DEFAULT_POOL_LENGTH, NULL); + + cpGFpElementPad(ECP_COFACTOR(pEC), elemLen, 0); + + cpGFpElementPad(ECP_POOL(pEC), elemLen*3*EC_POOL_SIZE, 0); + + /* set up EC if possible */ + if(pA && pB) + return ippsGFpECSet(pA,pB, pEC); + else + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd128r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd128r1.c new file mode 100644 index 000000000..c0038eb83 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd128r1.c @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStd128r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); +} + +/*F* +// Name: ippsGFpECInitStd128r1 +// +// Purpose: Initializes the context of EC128r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStd128r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGFp, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(secp128r1_p, BITS_BNU_CHUNK(128), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(128)), ippStsBadArgErr); + + ippsGFpECInit(pGFp, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(128), secp128r1_a, + BITS_BNU_CHUNK(128), secp128r1_b, + BITS_BNU_CHUNK(128), secp128r1_gx, + BITS_BNU_CHUNK(128), secp128r1_gy, + BITS_BNU_CHUNK(128), secp128r1_r, + secp128r1_h, + pEC); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd128r2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd128r2.c new file mode 100644 index 000000000..ee0cd5881 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd128r2.c @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStd128r2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); +} + +/*F* +// Name: ippsGFpECInitStd128r2 +// +// Purpose: Initializes the context of EC128r2 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStd128r2,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGFp, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(secp128r2_p, BITS_BNU_CHUNK(128), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(128)), ippStsBadArgErr); + + ippsGFpECInit(pGFp, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(128), secp128r2_a, + BITS_BNU_CHUNK(128), secp128r2_b, + BITS_BNU_CHUNK(128), secp128r2_gx, + BITS_BNU_CHUNK(128), secp128r2_gy, + BITS_BNU_CHUNK(128), secp128r2_r, + secp128r2_h, + pEC); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd192r1.c new file mode 100644 index 000000000..086251765 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd192r1.c @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStd192r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); +} + +/*F* +// Name: ippsGFpECInitStd192r1 +// +// Purpose: Initializes the context of EC192r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStd192r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGFp, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(secp192r1_p, BITS_BNU_CHUNK(192), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(192)), ippStsBadArgErr); + + ippsGFpECInit(pGFp, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(192), secp192r1_a, + BITS_BNU_CHUNK(192), secp192r1_b, + BITS_BNU_CHUNK(192), secp192r1_gx, + BITS_BNU_CHUNK(192), secp192r1_gy, + BITS_BNU_CHUNK(192), secp192r1_r, + secp192r1_h, + pEC); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd224r1.c new file mode 100644 index 000000000..46e2750dd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd224r1.c @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStd224r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); +} + +/*F* +// Name: ippsGFpECInitStd224r1 +// +// Purpose: Initializes the context of EC224r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStd224r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGFp, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(secp224r1_p, BITS_BNU_CHUNK(224), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(224)), ippStsBadArgErr); + + ippsGFpECInit(pGFp, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(224), secp224r1_a, + BITS_BNU_CHUNK(224), secp224r1_b, + BITS_BNU_CHUNK(224), secp224r1_gx, + BITS_BNU_CHUNK(224), secp224r1_gy, + BITS_BNU_CHUNK(224), secp224r1_r, + secp224r1_h, + pEC); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd256r1.c new file mode 100644 index 000000000..a895425fb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd256r1.c @@ -0,0 +1,126 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStd256r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +#include "ecnist/ifma_arith_method.h" +#include "pcpgfpmethod.h" + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + ECP_MONT_R(pEC)->method_alt = gsArithGF_n256r1_avx512(); + } +#endif +} + +/*F* +// Name: ippsGFpECInitStd256r1 +// +// Purpose: Initializes the context of EC256r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStd256r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGFp, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(secp256r1_p, BITS_BNU_CHUNK(256), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(256)), ippStsBadArgErr); + + ippsGFpECInit(pGFp, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(256), secp256r1_a, + BITS_BNU_CHUNK(256), secp256r1_b, + BITS_BNU_CHUNK(256), secp256r1_gx, + BITS_BNU_CHUNK(256), secp256r1_gy, + BITS_BNU_CHUNK(256), secp256r1_r, + secp256r1_h, + pEC); + + ECP_MODULUS_ID(pEC) = cpID_PrimeP256r1; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd384r1.c new file mode 100644 index 000000000..9309ba9e3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd384r1.c @@ -0,0 +1,125 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStd384r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +#include "ifma_arith_method.h" + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + ECP_MONT_R(pEC)->method_alt = gsArithGF_n384r1_avx512(); + } +#endif +} + +/*F* +// Name: ippsGFpECInitStd384r1 +// +// Purpose: Initializes the context of EC384r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStd384r1,(const IppsGFpState* pGFp, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGFp, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(secp384r1_p, BITS_BNU_CHUNK(384), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(384)), ippStsBadArgErr); + + ippsGFpECInit(pGFp, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(384), secp384r1_a, + BITS_BNU_CHUNK(384), secp384r1_b, + BITS_BNU_CHUNK(384), secp384r1_gx, + BITS_BNU_CHUNK(384), secp384r1_gy, + BITS_BNU_CHUNK(384), secp384r1_r, + secp384r1_h, + pEC); + + ECP_MODULUS_ID(pEC) = cpID_PrimeP384r1; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd521r1.c new file mode 100644 index 000000000..fe5bc7e3b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstd521r1.c @@ -0,0 +1,126 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStd521r1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + +#include "ecnist/ifma_arith_method_p521.h" + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + ECP_MONT_R(pEC)->method_alt = gsArithGF_n521r1_avx512(); + } +#endif +} + +/*F* +// Name: ippsGFpECInitStd521r1 +// +// Purpose: Initializes the context of EC521r1 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStd521r1,(const IppsGFpState* pGF, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGF, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGF), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGF); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(secp521r1_p, BITS_BNU_CHUNK(521), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(521)), ippStsBadArgErr); + + ippsGFpECInit(pGF, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(521), secp521r1_a, + BITS_BNU_CHUNK(521), secp521r1_b, + BITS_BNU_CHUNK(521), secp521r1_gx, + BITS_BNU_CHUNK(521), secp521r1_gy, + BITS_BNU_CHUNK(521), secp521r1_r, + secp521r1_h, + pEC); + + ECP_MODULUS_ID(pEC) = cpID_PrimeP521r1; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstdbn256.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstdbn256.c new file mode 100644 index 000000000..4c623983d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstdbn256.c @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStdBN256() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + + + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); +} + +/*F* +// Name: ippsGFpECInitStdBN256 +// +// Purpose: Initializes the context of ECBN256 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStdBN256,(const IppsGFpState* pGF, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGF, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGF), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGF); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(tpmBN_p256p_p, BITS_BNU_CHUNK(256), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(256)), ippStsBadArgErr); + + ippsGFpECInit(pGF, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(BNU_CHUNK_BITS), tpmBN_p256p_a, + BITS_BNU_CHUNK(BNU_CHUNK_BITS), tpmBN_p256p_b, + BITS_BNU_CHUNK(BNU_CHUNK_BITS), tpmBN_p256p_gx, + BITS_BNU_CHUNK(BNU_CHUNK_BITS), tpmBN_p256p_gy, + BITS_BNU_CHUNK(256), tpmBN_p256p_r, + tpmBN_p256p_h, + pEC); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstdsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstdsm2.c new file mode 100644 index 000000000..83ba0ff66 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecinitstdsm2.c @@ -0,0 +1,128 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECInitStdSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +#if (_IPP32E >= _IPP32E_K1) +#include "sm2/ifma_arith_method_sm2.h" +#include "pcpgfpmethod.h" +#endif // (_IPP32E >= _IPP32E_K1) + + +static void cpGFpECSetStd(int aLen, const BNU_CHUNK_T* pA, + int bLen, const BNU_CHUNK_T* pB, + int xLen, const BNU_CHUNK_T* pX, + int yLen, const BNU_CHUNK_T* pY, + int rLen, const BNU_CHUNK_T* pR, + BNU_CHUNK_T h, + IppsGFpECState* pEC) +{ + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IppsGFpElement elmA, elmB; + __ALIGN8 IppsBigNumState R; + __ALIGN8 IppsBigNumState H; + + /* convert A ans B coeffs into GF elements */ + cpGFpElementConstruct(&elmA, cpGFpGetPool(1, pGFE), elemLen); + cpGFpElementConstruct(&elmB, cpGFpGetPool(1, pGFE), elemLen); + ippsGFpSetElement((Ipp32u*)pA, BITS2WORD32_SIZE(BITSIZE_BNU(pA,aLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pB, BITS2WORD32_SIZE(BITSIZE_BNU(pB,bLen)), &elmB, pGF); + /* and set EC */ + ippsGFpECSet(&elmA, &elmB, pEC); + + /* construct R and H */ + cpConstructBN(&R, rLen, (BNU_CHUNK_T*)pR, NULL); + cpConstructBN(&H, 1, &h, NULL); + /* convert GX ans GY coeffs into GF elements */ + ippsGFpSetElement((Ipp32u*)pX, BITS2WORD32_SIZE(BITSIZE_BNU(pX,xLen)), &elmA, pGF); + ippsGFpSetElement((Ipp32u*)pY, BITS2WORD32_SIZE(BITSIZE_BNU(pY,yLen)), &elmB, pGF); + /* and init EC subgroup */ + ippsGFpECSetSubgroup(&elmA, &elmB, &R, &H, pEC); + cpGFpReleasePool(2, pGFE); + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + ECP_MONT_R(pEC)->method_alt = gsArithGF_nsm2_avx512(); + } +#endif // (_IPP32E >= _IPP32E_K1) +} + +/*F* +// Name: ippsGFpECInitStdSM2 +// +// Purpose: Initializes the context of ECSM2 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pGFp +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsBadArgErr pGFp does not specify the finite field over which the given +// standard elliptic curve is defined +// +// ippStsNoErr no error +// +// Parameters: +// pGFp Pointer to the IppsGFpState context of the underlying finite field +// pEC Pointer to the context of the elliptic curve being initialized. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECInitStdSM2,(const IppsGFpState* pGF, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pGF, pEC); + + IPP_BADARG_RET( !GFP_VALID_ID(pGF), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGF); + + /* test if GF is prime GF */ + IPP_BADARG_RET(!GFP_IS_BASIC(pGFE), ippStsBadArgErr); + /* test underlying prime value*/ + IPP_BADARG_RET(cpCmp_BNU(tpmSM2_p256_p, BITS_BNU_CHUNK(256), GFP_MODULUS(pGFE), BITS_BNU_CHUNK(256)), ippStsBadArgErr); + + ippsGFpECInit(pGF, NULL, NULL, pEC); + cpGFpECSetStd(BITS_BNU_CHUNK(256), tpmSM2_p256_a, + BITS_BNU_CHUNK(256), tpmSM2_p256_b, + BITS_BNU_CHUNK(256), tpmSM2_p256_gx, + BITS_BNU_CHUNK(256), tpmSM2_p256_gy, + BITS_BNU_CHUNK(256), tpmSM2_p256_r, + tpmSM2_p256_h, + pEC); + + ECP_MODULUS_ID(pEC) = cpID_PrimeTPM_SM2; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpeckeys.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeckeys.c new file mode 100644 index 000000000..502362888 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeckeys.c @@ -0,0 +1,157 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECTstKeyPair() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +/* +// checks privateKey +// +// returns 1 if private_key belongs (0,order) range +// 0 if otherwise +*/ +int gfec_CheckPrivateKey(const IppsBigNumState* pPrivate, IppsGFpECState* pEC) +{ + /* order */ + BNU_CHUNK_T* pOrder = MOD_MODULUS(ECP_MONT_R(pEC)); + int orderLen = BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)); + + /* key under check */ + BNU_CHUNK_T* pKey = BN_NUMBER(pPrivate); + int keyLen = BN_SIZE(pPrivate); + + IppsGFpState *pGF = ECP_GFP(pEC); + gsModEngine *pGFE = GFP_PMA(pGF); + + BNU_CHUNK_T* F = cpGFpGetPool(1, pGFE); + + int ret = BN_POSITIVE(pPrivate); + if (ret) + ret = !IsZero_BN(pPrivate); + if (ret) + ret = ECP_ORDBITSIZE(pEC) >= cpBN_bitsize(pPrivate); + if (ret) { + cpGFpElementCopyPad(F, orderLen, pKey, keyLen); + /* cpSub_BNU() returns borrow bit, so any non - zero value corresponds to a valid key range(key < order) */ + ret = 0 != cpSub_BNU(F, F, pOrder, orderLen); + } + + cpGFpReleasePool(1, pGFE); + + return ret; +} + +/*F* +// Name: ippsGFpECTstKeyPair +// +// Purpose: Test Key Pair +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivate +// NULL == pPublic +// NULL == pResult +// NULL == pScratchBuffer +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pPrivate->idCtx +// illegal pPublic->idCtx +// +// ippStsRangeErr ECP_POINT_FELEN(pPublic)idCtx +// invalid pPoint->idCtx +// invalid pX->idCtx +// +// ippStsBadArgErr !GFP_IS_BASIC(GFP_PMA(ECP_GFP(pEC))) +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// GFPE_ROOM(pX)!=GFP_FELEN() +// +// ippStsQuadraticNonResidueErr square of the Y-coordinate of +// the pPoint is a quadratic non-residue modulo +// +// +// ippStsNoErr no error +// +// Parameters: +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// pX Pointer to the X-coordinate of the point on the elliptic curve +// +// Note: +// Is not a fact that computed point belongs to BP-related subgroup BP +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECMakePoint,(const IppsGFpElement* pX, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR3_RET(pX, pPoint, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFP_IS_BASIC(GFP_PMA(ECP_GFP(pEC))), ippStsBadArgErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pX), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BADARG_RET( GFPE_ROOM(pX)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + return gfec_MakePoint(pPoint, GFPE_DATA(pX), pEC)? ippStsNoErr : ippStsQuadraticNonResidueErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecmulpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecmulpoint.c new file mode 100644 index 000000000..1af04d780 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecmulpoint.c @@ -0,0 +1,155 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECMulPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECMulPoint +// +// Purpose: Multiplies a point on an elliptic curve by a scalar +// +// Returns: Reason: +// ippStsNullPtrErr pP == NULL +// pQ == NULL +// pR == NULL +// pEC == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// pEC->subgroup == NULL +// invalid pP->idCtx +// invalid pQ->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pP)!=GFP_FELEN() +// ECP_POINT_FELEN(pR)!=GFP_FELEN() +// +// ippStsBadArgErr pN is negative +// pN > MOD_MODULUS(ECP_MONT_R(pEC)) +// +// ippStsNoErr no error +// +// Parameters: +// pP Pointer to the context of the given point on the elliptic curve +// pN Pointer to the Big Number context storing the scalar value +// pR Pointer to the context of the resulting elliptic curve point +// pEC Pointer to the context of the elliptic curve +// pScratchBuffer Pointer to the scratch buffer +// +// Note: +// computes [N]*P, 0 < N < order +// +*F*/ +#if 0 +IPPFUN(IppStatus, ippsGFpECMulPoint,(const IppsGFpECPoint* pP, + const IppsBigNumState* pN, + IppsGFpECPoint* pR, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_BAD_PTR4_RET(pP, pR, pEC, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pP), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pR), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pR)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + IPP_BAD_PTR1_RET(pN); + IPP_BADARG_RET(!BN_VALID_ID(pN), ippStsContextMatchErr ); + IPP_BADARG_RET( BN_NEGATIVE(pN), ippStsBadArgErr ); + + { + BNU_CHUNK_T* pScalar = BN_NUMBER(pN); + int scalarLen = BN_SIZE(pN); + IPP_BADARG_RET(0= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + switch (ECP_MODULUS_ID(pEC)) { + case cpID_PrimeP256r1: { + gfec_MulPoint_nistp256_avx512(pR, pP, pScalar, scalarLen, pEC, pScratchBuffer); + return ippStsNoErr; + } + case cpID_PrimeP384r1: { + gfec_MulPoint_nistp384_avx512(pR, pP, pScalar, scalarLen, pEC, pScratchBuffer); + return ippStsNoErr; + } + case cpID_PrimeP521r1: { + gfec_MulPoint_nistp521_avx512(pR, pP, pScalar, scalarLen, pEC, pScratchBuffer); + return ippStsNoErr; + } + case cpID_PrimeTPM_SM2: { + gfec_MulPoint_sm2_avx512(pR, pP, pScalar, scalarLen, pEC, pScratchBuffer); + return ippStsNoErr; + } + default: + /* Go to default implementation below */ + break; + } + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + + gfec_MulPoint(pR, pP, pScalar, scalarLen, pEC, pScratchBuffer); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecnegpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecnegpoint.c new file mode 100644 index 000000000..bb151ed27 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecnegpoint.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECNegPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECNegPoint +// +// Purpose: Computes the inverse of a point +// +// Returns: Reason: +// ippStsNullPtrErr pP == NULL +// pR == NULL +// pEC == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pP->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pP)!=GFP_FELEN() +// ECP_POINT_FELEN(pR)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pP Pointer to the context of the first elliptic curve point +// pR Pointer to the context of the resulting elliptic curve point +// pEC Pointer to the context of the elliptic curve +// +*F*/ + + +IPPFUN(IppStatus, ippsGFpECNegPoint,(const IppsGFpECPoint* pP, + IppsGFpECPoint* pR, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR3_RET(pP, pR, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pP), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pR), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pR)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + gfec_NegPoint(pR, pP, pEC); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecpoint.c new file mode 100644 index 000000000..31fbef3eb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecpoint.c @@ -0,0 +1,112 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECPointGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECPointGetSize +// +// Purpose: Gets the size of the IppsGFpECPoint context +// +// Returns: Reason: +// ippStsNullPtrErr pEC == NULL +// pSize == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pEC Pointer to the context of the elliptic curve +// pSize Pointer to the buffer size +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECPointGetSize,(const IppsGFpECState* pEC, int* pSize)) +{ + IPP_BAD_PTR2_RET(pEC, pSize); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + { + int elemLen = GFP_FELEN(GFP_PMA(ECP_GFP(pEC))); + *pSize = (Ipp32s)sizeof(IppsGFpECPoint) + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* X */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* Y */ + +elemLen*(Ipp32s)sizeof(BNU_CHUNK_T);/* Z */ + return ippStsNoErr; + } +} + +/*F* +// Name: ippsGFpECPointInit +// +// Purpose: Initializes the context of a point on an elliptic curve +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pX, pY Pointers to the X and Y coordinates of a point on the elliptic curve +// pPoint Pointer to the IppsGFpECPoint context being initialized +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECPointInit,(const IppsGFpElement* pX, const IppsGFpElement* pY, + IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pPoint, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + { + Ipp8u* ptr = (Ipp8u*)pPoint; + int elemLen = GFP_FELEN(GFP_PMA(ECP_GFP(pEC))); + + ECP_POINT_SET_ID(pPoint); + ECP_POINT_FLAGS(pPoint) = 0; + ECP_POINT_FELEN(pPoint) = elemLen; + ptr += sizeof(IppsGFpECPoint); + ECP_POINT_DATA(pPoint) = (BNU_CHUNK_T*)(ptr); + + if(pX && pY) + return ippsGFpECSetPoint(pX, pY, pPoint, pEC); + else { + gfec_SetPointAtInfinity(pPoint); + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecpointstuff.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecpointstuff.c new file mode 100644 index 000000000..9b8b70ae4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecpointstuff.c @@ -0,0 +1,133 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// Context: +// gfec_IsPointOnCurve() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "gsscramble.h" + + +#if ( ECP_PROJECTIVE_COORD == JACOBIAN ) +IPP_OWN_DEFN (int, gfec_IsPointOnCurve, (const IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +{ + /* point at infinity does not belong curve */ + if( !IS_ECP_FINITE_POINT(pPoint) ) + //return 1; + return 0; + + /* test that 0 == R = (Y^2) - (X^3 + A*X*(Z^4) + B*(Z^6)) */ + else { + int isOnCurve = 0; + + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + + mod_mul mulF = GFP_METHOD(pGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGFE)->sqr; + mod_sub subF = GFP_METHOD(pGFE)->sub; + + BNU_CHUNK_T* pX = ECP_POINT_X(pPoint); + BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint); + BNU_CHUNK_T* pZ = ECP_POINT_Z(pPoint); + + BNU_CHUNK_T* pR = NULL; + BNU_CHUNK_T* pT = NULL; + + BNU_CHUNK_T* pZ4 = NULL; + BNU_CHUNK_T* pZ6 = NULL; + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + switch (ECP_MODULUS_ID(pEC)) { + case cpID_PrimeP256r1: { + isOnCurve = gfec_point_on_curve_nistp256_avx512(pPoint, pEC); + goto exit; + break; + } + case cpID_PrimeP384r1: { + isOnCurve = gfec_point_on_curve_nistp384_avx512(pPoint, pEC); + goto exit; + break; + } + case cpID_PrimeP521r1: { + isOnCurve = gfec_point_on_curve_nistp521_avx512(pPoint, pEC); + goto exit; + break; + } + case cpID_PrimeTPM_SM2: { + isOnCurve = gfec_point_on_curve_sm2_avx512(pPoint, pEC); + goto exit; + break; + } + default: + /* Go to default implementation below */ + break; + } + } +#endif // (_IPP32E >= _IPP32E_K1) + pR = cpGFpGetPool(1, pGFE); + pT = cpGFpGetPool(1, pGFE); + + sqrF(pR, pY, pGFE); /* R = Y^2 */ + sqrF(pT, pX, pGFE); /* T = X^3 */ + mulF(pT, pX, pT, pGFE); + subF(pR, pR, pT, pGFE); /* R -= T */ + + if( IS_ECP_AFFINE_POINT(pPoint) ) { + mulF(pT, pX, ECP_A(pEC), pGFE); /* T = A*X */ + subF(pR, pR, pT, pGFE); /* R -= T */ + subF(pR, pR, ECP_B(pEC), pGFE); /* R -= B */ + } + else { + pZ4 = cpGFpGetPool(1, pGFE); + pZ6 = cpGFpGetPool(1, pGFE); + + sqrF(pZ6, pZ, pGFE); /* Z^2 */ + sqrF(pZ4, pZ6, pGFE); /* Z^4 */ + mulF(pZ6, pZ6, pZ4, pGFE); /* Z^6 */ + + mulF(pZ4, pZ4, pX, pGFE); /* X*(Z^4) */ + mulF(pZ4, pZ4, ECP_A(pEC), pGFE); /* A*X*(Z^4) */ + mulF(pZ6, pZ6, ECP_B(pEC), pGFE); /* B*(Z^4) */ + + subF(pR, pR, pZ4, pGFE); /* R -= A*X*(Z^4) */ + subF(pR, pR, pZ6, pGFE); /* R -= B*(Z^6) */ + + cpGFpReleasePool(2, pGFE); + } + + isOnCurve = GFP_IS_ZERO(pR, GFP_FELEN(pGFE)); + + cpGFpReleasePool(2, pGFE); +#if (_IPP32E >= _IPP32E_K1) + exit: +#endif // (_IPP32E >= _IPP32E_K1) + return isOnCurve; + } +} +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecprivatekey.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecprivatekey.c new file mode 100644 index 000000000..805767a63 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecprivatekey.c @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECPrivateKey() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECPrivateKey +// +// Purpose: Generate random private key +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pPrivate +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pPrivate->idCtx +// +// ippStsSizeErr BN_ROOM(pPrivate)*BITSIZE(BNU_CHUNK_T)idCtx +// pEC->subgroup == NULL +// illegal pPrivate->idCtx +// illegal pPublic->idCtx +// +// ippStsInvalidPrivateKey !(0 < pPrivate < order) +// +// ippStsRangeErr ECP_POINT_FELEN(pPublic)= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + switch (ECP_MODULUS_ID(pEC)) { + case cpID_PrimeP256r1: { + gfec_PubKey_nist256_avx512(pPublic, pS, nsS, pEC, pScratchBuffer); + return ippStsNoErr; + } + case cpID_PrimeP384r1: { + gfec_PubKey_nist384_avx512(pPublic, pS, nsS, pEC, pScratchBuffer); + return ippStsNoErr; + } + case cpID_PrimeP521r1: { + gfec_PubKey_nist521_avx512(pPublic, pS, nsS, pEC, pScratchBuffer); + return ippStsNoErr; + } + case cpID_PrimeTPM_SM2: { + gfec_PubKey_sm2_avx512(pPublic, pS, nsS, pEC, pScratchBuffer); + return ippStsNoErr; + } + default: + /* Go to default implementation below */ + break; + } + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + { + gfec_MulBasePoint(pPublic, pS, nsS, pEC, pScratchBuffer); + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecset.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecset.c new file mode 100644 index 000000000..9d17ea902 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecset.c @@ -0,0 +1,99 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECSet() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECSet +// +// Purpose: Sets up the parameters of an elliptic curve over a finite field +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pA +// NULL == pB +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pA->idCtx +// invalid pB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM(pA)!=GFP_FELEN(pGFE) +// GFPE_ROOM(pB)!=GFP_FELEN(pGFE) +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the coefficient A of the equation defining the elliptic curve +// pB Pointer to the coefficient B of the equation defining the elliptic curve +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSet,(const IppsGFpElement* pA, + const IppsGFpElement* pB, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + IPP_BAD_PTR2_RET(pA, pB); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pB), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(ECP_GFP(pEC)); + int elemLen = GFP_FELEN(pGFE); + + IPP_BADARG_RET( GFPE_ROOM(pA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + IPP_BADARG_RET( GFPE_ROOM(pB)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + /* copy A */ + cpGFpElementPad(ECP_A(pEC), elemLen, 0); + cpGFpElementCopy(ECP_A(pEC), GFPE_DATA(pA), elemLen); + /* and set up A-specific (a==0 or a==-3) if is */ + if(GFP_IS_ZERO(ECP_A(pEC), elemLen)) + ECP_SPECIFIC(pEC) = ECP_EPID2; + + cpGFpElementSetChunk(ECP_B(pEC), elemLen, 3); + GFP_METHOD(pGFE)->encode(ECP_B(pEC), ECP_B(pEC), pGFE); + GFP_METHOD(pGFE)->add(ECP_B(pEC), ECP_A(pEC), ECP_B(pEC), pGFE); + if(GFP_IS_ZERO(ECP_B(pEC), elemLen)) + ECP_SPECIFIC(pEC) = ECP_STD; + + /* copy B */ + cpGFpElementPad(ECP_B(pEC), elemLen, 0); + cpGFpElementCopy(ECP_B(pEC), GFPE_DATA(pB), elemLen); + /* and set type of affine infinity representation: + // (0,1) if B==0 + // (0,0) if B!=0 */ + ECP_INFINITY(pEC) = GFP_IS_ZERO(ECP_B(pEC), elemLen); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpoint.c new file mode 100644 index 000000000..3d2fe261a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpoint.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECSetPoint +// +// Purpose: Sets a point on an elliptic curve +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// pX == NULL +// pY == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// invalid pX->idCtx +// invalid pY->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pX)!=GFP_FELEN() +// ECP_POINT_FELEN(pY)!=GFP_FELEN() +// ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pX, pY Pointers to the X and Y coordinates of a point on the elliptic curve +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSetPoint,(const IppsGFpElement* pX, const IppsGFpElement* pY, + IppsGFpECPoint* pPoint, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pPoint, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BAD_PTR2_RET(pX, pY); + IPP_BADARG_RET( !GFPE_VALID_ID(pX), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pY), ippStsContextMatchErr ); + + IPP_BADARG_RET( GFPE_ROOM(pX)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( GFPE_ROOM(pY)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + if(gfec_SetPoint(ECP_POINT_DATA(pPoint), GFPE_DATA(pX), GFPE_DATA(pY), pEC)) + ECP_POINT_FLAGS(pPoint) = ECP_AFFINE_POINT | ECP_FINITE_POINT; + else + ECP_POINT_FLAGS(pPoint) = 0; + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointatinf.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointatinf.c new file mode 100644 index 000000000..6ac685f1d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointatinf.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointAtInfinity() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECSetPointAtInfinity +// +// Purpose: Sets a point on an elliptic curve as a point at infinity +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN()!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSetPointAtInfinity,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pPoint, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + gfec_SetPointAtInfinity(pPoint); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash.c new file mode 100644 index 000000000..5aa41722c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash.c @@ -0,0 +1,154 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointHash() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECSetPointHash +// +// Purpose: Constructs a point on an elliptic curve based on the hash of the input message +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// pScratchBuffer == NULL +// (msgLen && !pMsg) +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// +// ippStsBadArgErr !GFP_IS_BASIC(pGFE) +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// +// ippStsQuadraticNonResidueErr square of the Y-coordinate of +// the pPoint is a quadratic non-residue modulo +// +// ippStsLengthErr msgLen<0 +// +// ippStsNoErr no error +// +// Parameters: +// hdr Header of the input message +// pMsg Pointer to the input message +// msgLen Length of the input message +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// hashID ID of the hash algorithm used +// pScratchBuffer Pointer to the scratch buffer +// +// Note: +// Is not a fact that computed point belongs to BP-related subgroup BP +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSetPointHash,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, + IppsGFpECState* pEC, IppHashAlgId hashID, + Ipp8u* pScratchBuffer)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + /* get algorithm id */ + hashID = cpValidHashAlg(hashID); + IPP_BADARG_RET(ippHashAlg_Unknown==hashID, ippStsNotSupportedModeErr); + + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* pModulus = GFP_MODULUS(pGFE); + + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + int hashLen = cpHashAlgAttr[hashID].hashSize; + BNU_CHUNK_T hashVal[BITS_BNU_CHUNK(IPP_SHA512_DIGEST_BITSIZE)+1]; + int hashValLen; + + IppsHashState hashCtx; + ippsHashInit(&hashCtx, hashID); + + { + BNU_CHUNK_T* pPoolElm = cpGFpGetPool(1, pGFE); + + /* convert hdr => hdrStr */ + BNU_CHUNK_T locHdr = (BNU_CHUNK_T)hdr; + Ipp8u hdrOctStr[sizeof(hdr/*locHdr*/)]; + cpToOctStr_BNU(hdrOctStr, sizeof(hdrOctStr), &locHdr, 1); + + /* compute md = hash(hrd||msg) */ + ippsHashUpdate(hdrOctStr, sizeof(hdrOctStr), &hashCtx); + ippsHashUpdate(pMsg, msgLen, &hashCtx); + ippsHashFinal(md, &hashCtx); + + /* convert hash into the integer */ + hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, pModulus, elemLen); + cpGFpSet(pPoolElm, hashVal, hashValLen, pGFE); + + if( gfec_MakePoint(pPoint, pPoolElm, pEC)) { + /* choose even y-coordinate of the point (see SafeID Specs v2) */ + BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint); + GFP_METHOD(pGFE)->decode(pPoolElm, pY, pGFE); /* due to P(X,Y,Z=1) just decode Y->y */ + if(pPoolElm[0] & 1) + cpGFpNeg(pY, pY, pGFE); + + /* R = [cofactor]R */ + if(ECP_SUBGROUP(pEC)) { + BNU_CHUNK_T* pCofactor = ECP_COFACTOR(pEC); + int cofactorLen = GFP_FELEN(pGFE); + if(!GFP_IS_ONE(pCofactor, cofactorLen)) + gfec_MulPoint(pPoint, pPoint, pCofactor, cofactorLen, /*0,*/ pEC, pScratchBuffer); + } + + cpGFpReleasePool(1, pGFE); + return ippStsNoErr; + } + } + + cpGFpReleasePool(1, pGFE); + return ippStsQuadraticNonResidueErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_backc.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_backc.c new file mode 100644 index 000000000..15201b083 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_backc.c @@ -0,0 +1,155 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointHash() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECSetPointHashBackCompatible +// +// Purpose: Constructs a point on an elliptic curve based on the hash of the input message +// This version provide back compatibility with ipp2019update5 and before +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// pScratchBuffer == NULL +// (msgLen && !pMsg) +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// +// ippStsBadArgErr !GFP_IS_BASIC(pGFE) +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// +// ippStsQuadraticNonResidueErr square of the Y-coordinate of +// the pPoint is a quadratic non-residue modulo +// +// ippStsLengthErr msgLen<0 +// +// ippStsNoErr no error +// +// Parameters: +// hdr Header of the input message +// pMsg Pointer to the input message +// msgLen Length of the input message +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// hashID ID of the hash algorithm used +// pScratchBuffer Pointer to the scratch buffer +// +// Note: +// Is not a fact that computed point belongs to BP-related subgroup BP +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSetPointHashBackCompatible,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, + IppsGFpECState* pEC, IppHashAlgId hashID, + Ipp8u* pScratchBuffer)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + /* get algorithm id */ + hashID = cpValidHashAlg(hashID); + IPP_BADARG_RET(ippHashAlg_Unknown==hashID, ippStsNotSupportedModeErr); + + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* pModulus = GFP_MODULUS(pGFE); + + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + int hashLen = cpHashAlgAttr[hashID].hashSize; + BNU_CHUNK_T hashVal[BITS_BNU_CHUNK(IPP_SHA512_DIGEST_BITSIZE)+1]; + int hashValLen; + + IppsHashState hashCtx; + ippsHashInit(&hashCtx, hashID); + + { + BNU_CHUNK_T* pPoolElm = cpGFpGetPool(1, pGFE); + + /* convert hdr => hdrStr */ + BNU_CHUNK_T locHdr = (BNU_CHUNK_T)hdr; + Ipp8u hdrOctStr[sizeof(hdr/*locHdr*/)]; + cpToOctStr_BNU(hdrOctStr, sizeof(hdrOctStr), &locHdr, 1); + + /* compute md = hash(hrd||msg) */ + ippsHashUpdate(hdrOctStr, sizeof(hdrOctStr), &hashCtx); + ippsHashUpdate(pMsg, msgLen, &hashCtx); + ippsHashFinal(md, &hashCtx); + + /* convert hash into the integer */ + hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, pModulus, elemLen); + cpGFpSet(pPoolElm, hashVal, hashValLen, pGFE); + + if( gfec_MakePoint(pPoint, pPoolElm, pEC)) { + /* set y-coordinate of the point (positive or negative) */ + /* because y is in Montgomery domain the code below is not matched to SafeID Specs v2 */ + BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint); + if(pY[0] & 1) + cpGFpNeg(pY, pY, pGFE); + + /* R = [cofactor]R */ + if(ECP_SUBGROUP(pEC)) { + BNU_CHUNK_T* pCofactor = ECP_COFACTOR(pEC); + int cofactorLen = GFP_FELEN(pGFE); + if(!GFP_IS_ONE(pCofactor, cofactorLen)) + gfec_MulPoint(pPoint, pPoint, pCofactor, cofactorLen, /*0,*/ pEC, pScratchBuffer); + } + + cpGFpReleasePool(1, pGFE); + return ippStsNoErr; + } + } + + cpGFpReleasePool(1, pGFE); + return ippStsQuadraticNonResidueErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_backc_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_backc_rmf.c new file mode 100644 index 000000000..498d490b5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_backc_rmf.c @@ -0,0 +1,151 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointHashBackCompatible_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + + +/*F* +// Name: ippsGFpECSetPointHashBackCompatible_rmf +// +// Purpose: Constructs a point on an elliptic curve based on the hash of the input message +// This version provide back compatibility with ipp2019update5 and before +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// pScratchBuffer == NULL +// (msgLen && !pMsg) +// pMethod == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// +// ippStsBadArgErr !GFP_IS_BASIC(pGFE) +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// +// ippStsQuadraticNonResidueErr square of the Y-coordinate of +// the pPoint is a quadratic non-residue modulo +// +// ippStsLengthErr msgLen<0 +// +// ippStsNoErr no error +// +// Parameters: +// hdr Header of the input message +// pMsg Pointer to the input message +// msgLen Length of the input message +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// pMethod Pointer to the hash method +// pScratchBuffer Pointer to the scratch buffer +// +// Note: +// Is not a fact that computed point belongs to BP-related subgroup BP +// +*F*/ +IPPFUN(IppStatus, ippsGFpECSetPointHashBackCompatible_rmf,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, + IppsGFpECState* pEC, const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + /* test method pointer */ + IPP_BAD_PTR1_RET(pMethod); + + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* pModulus = GFP_MODULUS(pGFE); + + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + int hashLen = pMethod->hashLen; + BNU_CHUNK_T hashVal[BITS_BNU_CHUNK(IPP_SHA512_DIGEST_BITSIZE)+1]; + int hashValLen; + + IppsHashState_rmf hashCtx; + ippsHashInit_rmf(&hashCtx, pMethod); + + { + BNU_CHUNK_T* pPoolElm = cpGFpGetPool(1, pGFE); + + /* convert hdr => hdrStr */ + BNU_CHUNK_T locHdr = (BNU_CHUNK_T)hdr; + Ipp8u hdrOctStr[sizeof(hdr/*locHdr*/)]; + cpToOctStr_BNU(hdrOctStr, sizeof(hdrOctStr), &locHdr, 1); + + /* compute md = hash(hrd||msg) */ + ippsHashUpdate_rmf(hdrOctStr, sizeof(hdrOctStr), &hashCtx); + ippsHashUpdate_rmf(pMsg, msgLen, &hashCtx); + ippsHashFinal_rmf(md, &hashCtx); + + /* convert hash into the integer */ + hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, pModulus, elemLen); + cpGFpSet(pPoolElm, hashVal, hashValLen, pGFE); + + if( gfec_MakePoint(pPoint, pPoolElm, pEC)) { + /* set y-coordinate of the point (positive or negative) */ + /* because y is in Montgomery domain the code below is not matched to SafeID Specs v2 */ + BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint); + if(pY[0] & 1) + cpGFpNeg(pY, pY, pGFE); + + /* update point if cofactor>1 */ + if(ECP_SUBGROUP(pEC)) + gfec_MulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGFE), /*0,*/ pEC, pScratchBuffer); + + cpGFpReleasePool(1, pGFE); + return ippStsNoErr; + } + } + + cpGFpReleasePool(1, pGFE); + return ippStsQuadraticNonResidueErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_rmf.c new file mode 100644 index 000000000..044ddb568 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointhash_rmf.c @@ -0,0 +1,150 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointHash_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + + +/*F* +// Name: ippsGFpECSetPointHash_rmf +// +// Purpose: Constructs a point on an elliptic curve based on the hash of the input message +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// pScratchBuffer == NULL +// (msgLen && !pMsg) +// pMethod == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// +// ippStsBadArgErr !GFP_IS_BASIC(pGFE) +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// +// ippStsQuadraticNonResidueErr square of the Y-coordinate of +// the pPoint is a quadratic non-residue modulo +// +// ippStsLengthErr msgLen<0 +// +// ippStsNoErr no error +// +// Parameters: +// hdr Header of the input message +// pMsg Pointer to the input message +// msgLen Length of the input message +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// pMethod Pointer to the hash method +// pScratchBuffer Pointer to the scratch buffer +// +// Note: +// Is not a fact that computed point belongs to BP-related subgroup BP +// +*F*/ +IPPFUN(IppStatus, ippsGFpECSetPointHash_rmf,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint, + IppsGFpECState* pEC, const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + /* test method pointer */ + IPP_BAD_PTR1_RET(pMethod); + + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* pModulus = GFP_MODULUS(pGFE); + + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + int hashLen = pMethod->hashLen; + BNU_CHUNK_T hashVal[BITS_BNU_CHUNK(IPP_SHA512_DIGEST_BITSIZE)+1]; + int hashValLen; + + IppsHashState_rmf hashCtx; + ippsHashInit_rmf(&hashCtx, pMethod); + + { + BNU_CHUNK_T* pPoolElm = cpGFpGetPool(1, pGFE); + + /* convert hdr => hdrStr */ + BNU_CHUNK_T locHdr = (BNU_CHUNK_T)hdr; + Ipp8u hdrOctStr[sizeof(hdr/*locHdr*/)]; + cpToOctStr_BNU(hdrOctStr, sizeof(hdrOctStr), &locHdr, 1); + + /* compute md = hash(hrd||msg) */ + ippsHashUpdate_rmf(hdrOctStr, sizeof(hdrOctStr), &hashCtx); + ippsHashUpdate_rmf(pMsg, msgLen, &hashCtx); + ippsHashFinal_rmf(md, &hashCtx); + + /* convert hash into the integer */ + hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, pModulus, elemLen); + cpGFpSet(pPoolElm, hashVal, hashValLen, pGFE); + + if( gfec_MakePoint(pPoint, pPoolElm, pEC)) { + /* choose even y-coordinate of the point (see SafeID Specs v2) */ + BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint); + GFP_METHOD(pGFE)->decode(pPoolElm, pY, pGFE); /* due to P(X,Y,Z=1) just decode Y->y */ + if(pPoolElm[0] & 1) + cpGFpNeg(pY, pY, pGFE); + + /* update point if cofactor>1 */ + if(ECP_SUBGROUP(pEC)) + gfec_MulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGFE), /*0,*/ pEC, pScratchBuffer); + + cpGFpReleasePool(1, pGFE); + return ippStsNoErr; + } + } + + cpGFpReleasePool(1, pGFE); + return ippStsQuadraticNonResidueErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointoctstring.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointoctstring.c new file mode 100644 index 000000000..fd449f68d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointoctstring.c @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointOctString() +// +*/ + +#include "pcpgfpecessm2.h" +#include "pcpgfpecstuff.h" + +/*F* +// Name: ippsGFpECSetPointOctString +// +// Purpose: Converts x||y octstring into a point on EC +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL / pEC == NULL / pStr == NULL +// ippStsContextMatchErr pEC, pPoint invalid context +// ippStsNotSupportedModeErr pGFE->extdegree > 1 +// ippStsSizeErr strLen is not equal to double GFp element +// ippStsOutOfRangeErr X or Y from the string exceeds the EC's field modulus or the point does not belong to the EC +// ippStsNoErr no errors +// +// Parameters: +// pStr pointer to the string to read from +// strLen length of the string +// pPoint pointer to output point +// pEC EC ctx +// +*F*/ +IPPFUN(IppStatus, ippsGFpECSetPointOctString, (const Ipp8u* pStr, + int strLen, IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) { + IPP_BAD_PTR3_RET(pPoint, pEC, pStr); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + + { + gsModEngine* pGFE = pEC->pGF->pGFE; + IppsGFpInfo gfi; + ippsGFpGetInfo(&gfi, pEC->pGF); + + { + int elemLenBits = gfi.basicGFdegree * gfi.basicElmBitSize; + int elemLenBytes = BITS2WORD8_SIZE(elemLenBits); + int elemLenChunks = BITS_BNU_CHUNK(elemLenBits); + IPP_BADARG_RET(strLen != elemLenBytes * 2, ippStsSizeErr); + + { + IppStatus ret; + IppsGFpElement ptX, ptY; + cpGFpElementConstruct(&ptX, cpGFpGetPool(1, pGFE), elemLenChunks); + cpGFpElementConstruct(&ptY, cpGFpGetPool(1, pGFE), elemLenChunks); + + ret = ippsGFpSetElementOctString(pStr, elemLenBytes, &ptX, pEC->pGF); + if (ippStsNoErr == ret) { + pStr += elemLenBytes; + ret = ippsGFpSetElementOctString(pStr, elemLenBytes, &ptY, pEC->pGF); + } + if (ippStsNoErr == ret) { + ret = ippsGFpECSetPoint(&ptX, &ptY, pPoint, pEC); + } + + cpGFpReleasePool(2, pGFE); /* release ptX and ptY from the pool */ + + return ret; + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointrand.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointrand.c new file mode 100644 index 000000000..5e281a44b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointrand.c @@ -0,0 +1,135 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointRandom() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECSetPointRandom +// +// Purpose: Sets the coordinates of a point on an elliptic curve to random values +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// pScratchBuffer == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// NULL == pEC->subgroup +// invalid pPoint->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// rndFunc Pesudorandom number generator +// pRndParam Pointer to the pseudorandom number generator context +// pScratchBuffer Pointer to the scratch buffer +// +// Note: +// Is not a fact that computed point belongs to BP-related subgroup BP +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSetPointRandom,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC, + IppBitSupplier rndFunc, void* pRndParam, + Ipp8u* pScratchBuffer)) +{ + IppsGFpState* pGF; + gsModEngine* pGFE; + + IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + IPP_BAD_PTR2_RET(rndFunc, pRndParam); + + { + int internal_err; + + if( GFP_IS_BASIC(pGFE) ) { + BNU_CHUNK_T* pElm = cpGFpGetPool(1, pGFE); + + do { /* get random X */ + internal_err = NULL==cpGFpRand(pElm, pGFE, rndFunc, pRndParam); + } while( !internal_err && !gfec_MakePoint(pPoint, pElm, pEC) ); + + cpGFpReleasePool(1, pGFE); + + /* R = [cofactor]R */ + if(!internal_err && ECP_SUBGROUP(pEC)) { + BNU_CHUNK_T* pCofactor = ECP_COFACTOR(pEC); + int cofactorLen = GFP_FELEN(pGFE); + if(!GFP_IS_ONE(pCofactor, cofactorLen)) + gfec_MulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGFE), /*0,*/ pEC, pScratchBuffer); + } + } + + else { + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + { + /* number of bits being generated */ + int generatedBits = ECP_ORDBITSIZE(pEC) + GFP_RAND_ADD_BITS; + int generatedLen = BITS_BNU_CHUNK(generatedBits); + + /* allocate random exponent */ + int poolElements = (generatedLen + GFP_PELEN(pGFE) -1) / GFP_PELEN(pGFE); + BNU_CHUNK_T* pExp = cpGFpGetPool(poolElements, pGFE); + + /* setup copy of the base point */ + IppsGFpECPoint G; + cpEcGFpInitPoint(&G, ECP_G(pEC),ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC); + + /* get random bits */ + internal_err = ippStsNoErr != rndFunc((Ipp32u*)pExp, generatedBits, pRndParam); + + if(!internal_err) { + /* reduce with respect to order value */ + int nsE = cpMod_BNU(pExp, generatedLen, MOD_MODULUS(ECP_MONT_R(pEC)), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC))); + /* compute random point */ + gfec_MulPoint(pPoint, &G, pExp, nsE, pEC, pScratchBuffer); + } + + cpGFpReleasePool(poolElements, pGFE); + } + } + + return internal_err? ippStsErr : ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointreg.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointreg.c new file mode 100644 index 000000000..eed0ecf4c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetpointreg.c @@ -0,0 +1,106 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECSetPointRegular() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECSetPointRegular +// +// Purpose: Sets a point with Big Number coordinates +// +// Returns: Reason: +// ippStsNullPtrErr pPoint == NULL +// pEC == NULL +// pX == NULL +// pY == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pPoint->idCtx +// invalid pX->idCtx +// invalid pY->idCtx +// +// ippStsOutOfRangeErr GFP_FELEN() < pX <= 0 +// GFP_FELEN() < pY <= 0 +// ECP_POINT_FELEN(pPoint)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pX, pY Pointers to the X and Y coordinates of a point on the elliptic curve +// pPoint Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSetPointRegular,(const IppsBigNumState* pX, const IppsBigNumState* pY, + IppsGFpECPoint* pPoint, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR2_RET(pPoint, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pPoint), ippStsContextMatchErr ); + + IPP_BAD_PTR2_RET(pX, pY); + IPP_BADARG_RET( !BN_VALID_ID(pX), ippStsContextMatchErr ); + IPP_BADARG_RET( !BN_VALID_ID(pY), ippStsContextMatchErr ); + IPP_BADARG_RET( !BN_POSITIVE(pX), ippStsOutOfRangeErr); + IPP_BADARG_RET( !BN_POSITIVE(pY), ippStsOutOfRangeErr); + + { + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + + IPP_BADARG_RET( BN_SIZE(pX) > elemLen, ippStsOutOfRangeErr); + IPP_BADARG_RET( BN_SIZE(pY) > elemLen, ippStsOutOfRangeErr); + IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=elemLen, ippStsOutOfRangeErr); + + { + BNU_CHUNK_T* pointX = ECP_POINT_X(pPoint); + BNU_CHUNK_T* pointY = ECP_POINT_Y(pPoint); + BNU_CHUNK_T* pointZ = ECP_POINT_Z(pPoint); + + cpGFpElementCopyPad(pointX, elemLen, BN_NUMBER(pX), BN_SIZE(pX)); + cpGFpElementCopyPad(pointY, elemLen, BN_NUMBER(pY), BN_SIZE(pY)); + cpGFpElementCopy(pointZ, MOD_MNT_R(pGFE), elemLen); + + if( cpGFpSet(pointX, pointX, elemLen, pGFE) && cpGFpSet(pointY, pointY, elemLen, pGFE) ) + ECP_POINT_FLAGS(pPoint) = ECP_AFFINE_POINT | ECP_FINITE_POINT; + else + gfec_SetPointAtInfinity(pPoint); + + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetsubgroup.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetsubgroup.c new file mode 100644 index 000000000..0b820bcf1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsetsubgroup.c @@ -0,0 +1,120 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECSetSubgroup() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECSetSubgroup +// +// Purpose: Sets up the parameters defining an elliptic curve points subgroup. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pX +// NULL == pY +// NULL == pOrder +// NULL == pCofactor +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pX->idCtx +// invalid pY->idCtx +// invalid pOrder->idCtx +// invalid pCofactor->idCtx +// +// ippStsBadArgErr pOrder <= 0 +// pCofactor <= 0 +// +// ippStsOutOfRangeErr GFPE_ROOM(pX)!=GFP_FELEN(pGFE) +// GFPE_ROOM(pY)!=GFP_FELEN(pGFE) +// +// ippStsRangeErr orderBitSize>maxOrderBits +// cofactorBitSize>elemLen*BITSIZE(BNU_CHUNK_T) +// +// ippStsNoErr no error +// +// Parameters: +// pX, pY Pointers to the X and Y coordinates of the base point of the elliptic curve +// pOrder Pointer to the big number context storing the order of the base point. +// pCofactor Pointer to the big number context storing the cofactor. +// pEC Pointer to the context of the elliptic curve. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECSetSubgroup,(const IppsGFpElement* pX, const IppsGFpElement* pY, + const IppsBigNumState* pOrder, + const IppsBigNumState* pCofactor, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + IPP_BAD_PTR2_RET(pX, pY); + IPP_BADARG_RET( !GFPE_VALID_ID(pX), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pY), ippStsContextMatchErr ); + + IPP_BAD_PTR2_RET(pOrder, pCofactor); + IPP_BADARG_RET(!BN_VALID_ID(pOrder), ippStsContextMatchErr); + IPP_BADARG_RET(BN_SIGN(pOrder)!= IppsBigNumPOS, ippStsBadArgErr); + + IPP_BADARG_RET(!BN_VALID_ID(pCofactor), ippStsContextMatchErr); + IPP_BADARG_RET(BN_SIGN(pCofactor)!= IppsBigNumPOS, ippStsBadArgErr); + + { + gsModEngine* pGFE = GFP_PMA(ECP_GFP(pEC)); + int elemLen = GFP_FELEN(pGFE); + + IPP_BADARG_RET( GFPE_ROOM(pX)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + IPP_BADARG_RET( GFPE_ROOM(pY)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + gfec_SetPoint(ECP_G(pEC), GFPE_DATA(pX), GFPE_DATA(pY), pEC); + + { + int maxOrderBits = 1+ cpGFpBasicDegreeExtension(pGFE) * GFP_FEBITLEN(cpGFpBasic(pGFE)); + BNU_CHUNK_T* pOrderData = BN_NUMBER(pOrder); + int orderLen= BN_SIZE(pOrder); + int orderBitSize = BITSIZE_BNU(pOrderData, orderLen); + IPP_BADARG_RET(orderBitSize>maxOrderBits, ippStsRangeErr) + + /* set actual size of order and re-init engine */ + ECP_ORDBITSIZE(pEC) = orderBitSize; + gsModEngineInit(ECP_MONT_R(pEC),(Ipp32u*)pOrderData, orderBitSize, MONT_DEFAULT_POOL_LENGTH, gsModArithMont()); + } + + { + BNU_CHUNK_T* pCofactorData = BN_NUMBER(pCofactor); + int cofactorLen= BN_SIZE(pCofactor); + int cofactorBitSize = BITSIZE_BNU(pCofactorData, cofactorLen); + IPP_BADARG_RET(cofactorBitSize>elemLen*BITSIZE(BNU_CHUNK_T), ippStsRangeErr) + COPY_BNU(ECP_COFACTOR(pEC), pCofactorData, cofactorLen); + } + + ECP_SUBGROUP(pEC) = 1; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsigndsa.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsigndsa.c new file mode 100644 index 000000000..a2241fa56 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsigndsa.c @@ -0,0 +1,252 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECSignDSA() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" +#include "pcpgfpmethod.h" +#include "pcpgfpstuff.h" + +/*F* +// Name: ippsGFpECSignDSA +// +// Purpose: DSA Signature Generation. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPrivate +// NULL == pEphPrivate +// NULL == pSignR +// NULL == pSignS +// NULL == pScratchBuffer +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pMsgDigest->idCtx +// illegal pRegPrivate->idCtx +// illegal pEphPrivate->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsInvalidPrivateKey 0 >= RegPrivate +// RegPrivate >= order +// +// 0 >= EphPrivate +// EphPrivate >= order +// +// ippStsMessageErr MsgDigest >= order +// MsgDigest < 0 +// +// ippStsRangeErr not enough room for: +// signR +// signS +// +// ippStsEphemeralKeyErr (0==signR) || (0==signS) +// +// ippStsNotSupportedModeErr pGFE->extdegree > 1 +// +// +// ippStsNoErr no errors +// +// Parameters: +// pMsgDigest pointer to the message representative to be signed +// pRegPrivate pointer to the regular private key +// pEphPrivate pointer to the ephemeral private key +// pSignR,pSignS pointer to the signature +// pEC pointer to the EC context +// pScratchBuffer pointer to buffer (1 mul_point operation) +// +*F*/ +IPPFUN(IppStatus, ippsGFpECSignDSA,(const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IppsGFpState* pGF; + gsModEngine* pMontP; + + /* EC context and buffer */ + IPP_BAD_PTR2_RET(pEC, pScratchBuffer); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + pGF = ECP_GFP(pEC); + pMontP = GFP_PMA(pGF); + IPP_BADARG_RET(1= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + switch (ECP_MODULUS_ID(pEC)) { + case cpID_PrimeP256r1: { + sts = gfec_SignDSA_nistp256_avx512(pMsgDigest, pRegPrivate, pEphPrivate, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + break; + } + case cpID_PrimeP384r1: { + sts = gfec_SignDSA_nistp384_avx512(pMsgDigest, pRegPrivate, pEphPrivate, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + break; + } + case cpID_PrimeP521r1: { + sts = gfec_SignDSA_nistp521_avx512(pMsgDigest, pRegPrivate, pEphPrivate, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + break; + } + default: + /* Go to default implementation below */ + break; + } + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + { + int elmLen = GFP_FELEN(pMontP); + int ns; + + /* compute ephemeral public key */ + IppsGFpECPoint ephPublic; + cpEcGFpInitPoint(&ephPublic, cpEcGFpGetPool(1, pEC), 0, pEC); + gfec_MulBasePoint(&ephPublic, + BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate), + pEC, pScratchBuffer); + + /* + // signR = int(ephPublic.x) (mod order) + */ + { + BNU_CHUNK_T* buffer = gsModPoolAlloc(pMontP, 1); + IPP_BAD_PTR1_RET(buffer); // buffer can be NULL, stop processing + gfec_GetPoint(buffer, NULL, &ephPublic, pEC); + GFP_METHOD(pMontP)->decode(buffer, buffer, pMontP); + ns = cpMod_BNU(buffer, elmLen, pOrder, ordLen); + cpGFpElementCopyPad(dataC, ordLen, buffer, ns); + gsModPoolFree(pMontP, 1); + } + cpEcGFpReleasePool(1, pEC); + + if(!GFP_IS_ZERO(dataC, ordLen)) { + /* + // signS = (1/ephPrivate)*(pMsgDigest + private*signR) (mod order) + */ + + /* copy and expand message is being signed and reduce just in case */ + ZEXPAND_COPY_BNU(buffF, ordLen, pMsgData, msgLen); + cpModSub_BNU(buffF, buffF, pOrder, pOrder, ordLen, buffT); + + /* private representation in Montgomery domain */ + ZEXPAND_COPY_BNU(dataD, ordLen, pPriData, priLen); + GFP_METHOD(pMontR)->encode(dataD, dataD, pMontR); + + /* (private*signX) in regular domain */ + GFP_METHOD(pMontR)->mul(dataD, dataD, dataC, pMontR); + + /* pMsgDigest + private*signX */ + cpModAdd_BNU(dataD, dataD, buffF, pOrder, ordLen, buffT); + + if(!GFP_IS_ZERO(dataD, ordLen)) { + /* (1/ephPrivate) in Montgomery domain */ + ZEXPAND_COPY_BNU(buffT, ordLen, pEphData, ephLen); + gs_mont_inv(buffT, buffT, pMontR, alm_mont_inv_ct); + + /* (1/ephPrivate)*(pMsgDigest + private*signS) */ + GFP_METHOD(pMontR)->mul(dataD, dataD, buffT, pMontR); + + /* signR */ + ns = ordLen; + FIX_BNU(dataC, ns); + BN_SIGN(pSignR) = ippBigNumPOS; + BN_SIZE(pSignR) = ns; + /* signS */ + ns = ordLen; + FIX_BNU(dataD, ns); + BN_SIGN(pSignS) = ippBigNumPOS; + BN_SIZE(pSignS) = ns; + + sts = ippStsNoErr; + } + } + } + +#if (_IPP32E >= _IPP32E_K1) +exit: +#endif + /* clear ephemeral private key */ + cpBN_zero(pEphPrivate); + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsignnr.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsignnr.c new file mode 100644 index 000000000..72869df02 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsignnr.c @@ -0,0 +1,206 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECSignNR() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECSignNR +// +// Purpose: NR Signature Generation. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPrivate +// NULL == pEphPrivate +// NULL == pSignR +// NULL == pSignS +// NULL == pScratchBuffer +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pMsgDigest->idCtx +// illegal pRegPrivate->idCtx +// illegal pEphPrivate->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsInvalidPrivateKey 0 >= RegPrivate +// RegPrivate >= order +// +// 0 >= EphPrivate +// EphPrivate >= order +// +// ippStsMessageErr pMsgDigest < 0 +// pMsgDigest >= order +// +// ippStsRangeErr not enough room for: +// signC +// signD +// +// ippStsEphemeralKeyErr (0==signR) || (0==signS) +// +// ippStsNotSupportedModeErr 1decode(buffer, buffer, pMontP); + ns = cpMod_BNU(buffer, elmLen, pOrder, ordLen); + cpGFpElementCopyPad(dataC, ordLen, buffer, ns); + gsModPoolFree(pMontP, 1); + } + cpEcGFpReleasePool(1, pEC); + + /* C = (ephPublic.x + msg) mod order */ + ZEXPAND_COPY_BNU(buffF, ordLen, pMsgData, msgLen); + cpModAdd_BNU(dataC, dataC, buffF, pOrder, ordLen, dataD); + + if(!GFP_IS_ZERO(dataC, ordLen)) { + + /* signS = (eph_private - private*signR) (mod order) */ + ZEXPAND_COPY_BNU(dataD, ordLen, pPriData, priLen); + GFP_METHOD(pMontR)->encode(dataD, dataD, pMontR); + GFP_METHOD(pMontR)->mul(dataD, dataD, dataC, pMontR); + ZEXPAND_COPY_BNU(buffF, ordLen, pEphData, ephLen); + cpModSub_BNU(dataD, buffF, dataD, pOrder, ordLen, buffT); + + /* signR */ + ns = ordLen; + FIX_BNU(dataC, ns); + BN_SIGN(pSignR) = ippBigNumPOS; + BN_SIZE(pSignR) = ns; + /* signS */ + ns = ordLen; + FIX_BNU(dataD, ns); + BN_SIGN(pSignS) = ippBigNumPOS; + BN_SIZE(pSignS) = ns; + + sts = ippStsNoErr; + } + + /* clear ephemeral private key */ + cpBN_zero(pEphPrivate); + + return sts; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsignsm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsignsm2.c new file mode 100644 index 000000000..cba8e9df0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecsignsm2.c @@ -0,0 +1,226 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECSignSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECSignSM2 +// +// Purpose: SM2 Signature Generation. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPrivate +// NULL == pEphPrivate +// NULL == pSignR +// NULL == pSignS +// NULL == pScratchBuffer +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pMsgDigest->idCtx +// illegal pRegPrivate->idCtx +// illegal pEphPrivate->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsInvalidPrivateKey (1 + regPrivate) >= order +// +// ippStsMessageErr MsgDigest >= order +// MsgDigest < 0 +// +// ippStsRangeErr not enough room for: +// signR +// signS +// +// ippStsEphemeralKeyErr (signR + ephPrivate) == order +// (0==signR) || (0==signS) +// +// ippStsNotSupportedModeErr 1= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA) && ECP_MODULUS_ID(pEC) == cpID_PrimeTPM_SM2) { + sts = gfec_Sign_sm2_avx512(pMsgDigest, pRegPrivate, pEphPrivate, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + { + int elmLen = GFP_FELEN(pMontP); + int ns; + + /* compute ephemeral public key */ + IppsGFpECPoint ephPublic; + cpEcGFpInitPoint(&ephPublic, cpEcGFpGetPool(1, pEC), 0, pEC); + gfec_MulBasePoint(&ephPublic, + pEphData, ephLen, + pEC, pScratchBuffer); + + /* extract X component: ephPublicX = (ephPublic.x) mod order */ + { + BNU_CHUNK_T* buffer = gsModPoolAlloc(pMontP, 1); + IPP_BAD_PTR1_RET(buffer); // buffer can be NULL, stop processing + gfec_GetPoint(buffer, NULL, &ephPublic, pEC); + GFP_METHOD(pMontP)->decode(buffer, buffer, pMontP); + ns = cpMod_BNU(buffer, elmLen, pOrder, ordLen); + cpGFpElementCopyPad(dataR, ordLen, buffer, ns); + gsModPoolFree(pMontP, 1); + } + cpEcGFpReleasePool(1, pEC); + + /* compute R signature component: r = (msg + ephPublic.X) mod order */ + ZEXPAND_COPY_BNU(buffS, ordLen, pMsgData, msgLen); + cpModSub_BNU(buffS, buffS, pOrder, pOrder, ordLen, buffR); + cpModAdd_BNU(dataR, dataR, buffS, pOrder, ordLen, buffR); + + /* t = (r+ephPrivate) mod order */ + ZEXPAND_COPY_BNU(buffR,ordLen, pEphData, ephLen); + cpModAdd_BNU(buffR, buffR, dataR, pOrder, ordLen, buffS); + + /* check if r!=0 and t!=0 */ + if(!GFP_IS_ZERO(dataR, ordLen) && !GFP_IS_ZERO(buffR, ordLen)) { + + /* S = (1+regPrivate)^1 *(ephPrivate-r*regPrivate) mod order */ + ZEXPAND_COPY_BNU(buffS, ordLen, pPriData, priLen); + GFP_METHOD(pMontR)->encode(buffS, buffS, pMontR); /* mont(regPrivate) */ + GFP_METHOD(pMontR)->mul(buffS, buffS, dataR, pMontR); /* r*mont(regPrivate) */ + ZEXPAND_COPY_BNU(buffR, ordLen, pEphData, ephLen); + cpModSub_BNU(buffR, buffR, buffS, pOrder, ordLen, buffS); /* ephPrivate-r*mont(regPrivate) */ + + gs_mont_inv(dataS, dataS, pMontR, alm_mont_inv_ct); /* 1/(1+regPrivate) */ + GFP_METHOD(pMontR)->mul(dataS, dataS, buffR, pMontR); + + if( !GFP_IS_ZERO(dataS, ordLen)) { + /* signR */ + ns = ordLen; + FIX_BNU(dataR, ns); + BN_SIGN(pSignR) = ippBigNumPOS; + BN_SIZE(pSignR) = ns; + /* signS */ + ns = ordLen; + FIX_BNU(dataS, ns); + BN_SIGN(pSignS) = ippBigNumPOS; + BN_SIZE(pSignS) = ns; + + sts = ippStsNoErr; + } + } + } + +#if (_IPP32E >= _IPP32E_K1) +exit: +#endif + /* clear ephemeral private key */ + cpBN_zero(pEphPrivate); + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecstuff.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecstuff.h new file mode 100644 index 000000000..3dec864c0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecstuff.h @@ -0,0 +1,407 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal EC over GF(p^m) basic Definitions & Function Prototypes +// +// +*/ + +#if !defined(_CP_ECGFP_H_) +#define _CP_ECGFP_H_ + +#include "pcpgfpmethod.h" +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcpmask_ct.h" + +#define _LEGACY_ECCP_SUPPORT_ + +/* +// EC over GF(p) Point context +*/ +typedef struct _cpGFpECPoint { + Ipp32u idCtx; /* EC Point identifier */ + int flags; /* flags: affine */ + int elementSize; /* size of each coordinate */ + BNU_CHUNK_T* pData; /* coordinate X, Y, Z */ +} cpGFPECPoint; + +/* +// Contet Access Macros +*/ +#define ECP_POINT_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxGFPPoint ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define ECP_POINT_FLAGS(ctx) ((ctx)->flags) +#define ECP_POINT_FELEN(ctx) ((ctx)->elementSize) +#define ECP_POINT_DATA(ctx) ((ctx)->pData) +#define ECP_POINT_X(ctx) ((ctx)->pData) +#define ECP_POINT_Y(ctx) ((ctx)->pData+(ctx)->elementSize) +#define ECP_POINT_Z(ctx) ((ctx)->pData+(ctx)->elementSize*2) +#define ECP_POINT_VALID_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR(ctx)) == (Ipp32u)idCtxGFPPoint) + +/* point flags */ +#define ECP_AFFINE_POINT (1) +#define ECP_FINITE_POINT (2) + +#define IS_ECP_AFFINE_POINT(ctx) (ECP_POINT_FLAGS((ctx))&ECP_AFFINE_POINT) +#define SET_ECP_AFFINE_POINT(ctx) (ECP_POINT_FLAGS((ctx))|ECP_AFFINE_POINT) +#define SET_ECP_PROJECTIVE_POINT(ctx) (ECP_POINT_FLAGS((ctx))&~ECP_AFFINE_POINT) + +#define IS_ECP_FINITE_POINT(ctx) (ECP_POINT_FLAGS((ctx))&ECP_FINITE_POINT) +#define SET_ECP_FINITE_POINT(ctx) (ECP_POINT_FLAGS((ctx))|ECP_FINITE_POINT) +#define SET_ECP_INFINITE_POINT(ctx) (ECP_POINT_FLAGS((ctx))&~ECP_FINITE_POINT) + +/* +// define using projective coordinates +*/ +#define JACOBIAN (0) +#define HOMOGENEOUS (1) +#define ECP_PROJECTIVE_COORD JACOBIAN +//#define ECP_PROJECTIVE_COORD HOMOGENEOUS + +#if (ECP_PROJECTIVE_COORD != JACOBIAN && ECP_PROJECTIVE_COORD != HOMOGENEOUS) + #error ECP_PROJECTIVE_COORD should be either JACOBIAN or HOMOGENEOUS type +#endif + + +/* +// pre-computed Base Point descriptor +*/ +IPP_OWN_FUNPTR (void, selectAP, (BNU_CHUNK_T* pAP, const BNU_CHUNK_T* pAPtbl, int index)) + +typedef struct _cpPrecompAP { + int w; /* scalar's window bitsize */ + selectAP select_affine_point; /* get affine point function */ + const BNU_CHUNK_T* pTbl; /* pre-computed table */ +} cpPrecompAP; + + +/* EC over GF(p) context */ +typedef struct _cpGFpEC { + Ipp32u idCtx; /* EC identifier */ + cpModulusID idModulus; /* Modulus type */ + + IppsGFpState* pGF; /* arbitrary GF(p^d)*/ + + int subgroup; /* set up subgroup */ + int elementSize; /* length of EC point */ + int orderBitSize; /* base_point order bitsize */ + BNU_CHUNK_T* pA; /* EC parameter A */ + BNU_CHUNK_T* pB; /* B */ + BNU_CHUNK_T* pG; /* base_point */ + BNU_CHUNK_T* cofactor; /* cofactor = #E/base_point order */ + int parmAspc; /* NIST's, EPIDv2.0 A-parameter specific */ + int infinity; /* 0/1 if B !=0/==0 */ + const cpPrecompAP* pBaseTbl; /* address of pre-computed [n]G tabble */ + gsModEngine* pMontR; /* EC order montgomery engine */ + + BNU_CHUNK_T* pPool; /* pool of points */ + #if defined(_LEGACY_ECCP_SUPPORT_) + BNU_CHUNK_T* pPublic; /* regular public key */ + BNU_CHUNK_T* pPublicE; /* ephemeral public key */ + BNU_CHUNK_T* pPrivat; /* regular private key */ + BNU_CHUNK_T* pPrivatE; /* ephemeral private key */ + BNU_CHUNK_T* pBuffer; /* pointer to scaratch buffer (for legacy ECCP only) */ + #endif +} cpGFPEC; + +#define ECGFP_ALIGNMENT ((int)(sizeof(void*))) + +/* Local definitions */ +#define EC_POOL_SIZE (10) /* num of points into the pool */ + +#define EC_MONT_POOL_SIZE (4) /* num of temp values for modular arithmetic */ + +#define ECP_SET_ID(pCtx) ((pCtx)->idCtx = (Ipp32u)idCtxGFPEC ^ (Ipp32u)IPP_UINT_PTR(pCtx)) +#define ECP_MODULUS_ID(pCtx) ((pCtx)->idModulus) +#define ECP_GFP(pCtx) ((pCtx)->pGF) +#define ECP_SUBGROUP(pCtx) ((pCtx)->subgroup) +#define ECP_POINTLEN(pCtx) ((pCtx)->elementSize) +#define ECP_ORDBITSIZE(pCtx) ((pCtx)->orderBitSize) +#define ECP_COFACTOR(pCtx) ((pCtx)->cofactor) +#define ECP_SPECIFIC(pCtx) ((pCtx)->parmAspc) +#define ECP_INFINITY(pCtx) ((pCtx)->infinity) +#define ECP_A(pCtx) ((pCtx)->pA) +#define ECP_B(pCtx) ((pCtx)->pB) +#define ECP_G(pCtx) ((pCtx)->pG) +#define ECP_PREMULBP(pCtx) ((pCtx)->pBaseTbl) +#define ECP_MONT_R(pCtx) ((pCtx)->pMontR) +#define ECP_POOL(pCtx) ((pCtx)->pPool) +#if defined(_LEGACY_ECCP_SUPPORT_) + #define ECP_PUBLIC(pCtx) ((pCtx)->pPublic) + #define ECP_PUBLIC_E(pCtx) ((pCtx)->pPublicE) + #define ECP_PRIVAT(pCtx) ((pCtx)->pPrivat) + #define ECP_PRIVAT_E(pCtx) ((pCtx)->pPrivatE) + #define ECP_SBUFFER(pCtx) ((pCtx)->pBuffer) +#endif + +#define VALID_ECP_ID(pCtx) ((((pCtx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((pCtx))) == (Ipp32u)idCtxGFPEC) + +/* EC curve specific (a-parameter) */ +#define ECP_Acom (0) /* commont case */ +#define ECP_Ami3 (1) /* a=-3 NIST's and SM2 curve */ +#define ECP_Aeq0 (2) /* a=0 EPIDv2.0 curve */ + +#define ECP_ARB ECP_Acom +#define ECP_STD ECP_Ami3 +#define ECP_EPID2 ECP_Aeq0 + +/* std ec pre-computed tables */ +#define gfpec_precom_nistP192r1_fun OWNAPI(gfpec_precom_nistP192r1_fun) +#define gfpec_precom_nistP224r1_fun OWNAPI(gfpec_precom_nistP224r1_fun) +#define gfpec_precom_nistP256r1_fun OWNAPI(gfpec_precom_nistP256r1_fun) +#define gfpec_precom_nistP256r1_radix52_fun OWNAPI(gfpec_precom_nistP256r1_radix52_fun) +#define gfpec_precom_nistP384r1_fun OWNAPI(gfpec_precom_nistP384r1_fun) +#define gfpec_precom_nistP384r1_radix52_fun OWNAPI(gfpec_precom_nistP384r1_radix52_fun) +#define gfpec_precom_nistP521r1_fun OWNAPI(gfpec_precom_nistP521r1_fun) +#define gfpec_precom_nistP521r1_radix52_fun OWNAPI(gfpec_precom_nistP521r1_radix52_fun) +#define gfpec_precom_sm2_fun OWNAPI(gfpec_precom_sm2_fun) +#define gfpec_precom_sm2_radix52_fun OWNAPI(gfpec_precom_sm2_radix52_fun) + +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP192r1_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP224r1_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP256r1_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP256r1_radix52_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP384r1_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP384r1_radix52_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP521r1_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_nistP521r1_radix52_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_sm2_fun, (void)) +IPP_OWN_DECL (const cpPrecompAP*, gfpec_precom_sm2_radix52_fun, (void)) + +/* +// get/release n points from/to the pool +*/ +__INLINE BNU_CHUNK_T* cpEcGFpGetPool(int n, IppsGFpECState* pEC) +{ + BNU_CHUNK_T* pPool = ECP_POOL(pEC); + ECP_POOL(pEC) += n*GFP_FELEN(GFP_PMA(ECP_GFP(pEC)))*3; + return pPool; +} +__INLINE void cpEcGFpReleasePool(int n, IppsGFpECState* pEC) +{ + int chunk_size = n*GFP_FELEN(GFP_PMA(ECP_GFP(pEC)))*3; + ECP_POOL(pEC) -= chunk_size; + // Clean the pool for the security reasons + // (intermediate sensetive data may be stored here) + ZEXPAND_BNU(ECP_POOL(pEC), 0, chunk_size); +} + +__INLINE IppsGFpECPoint* cpEcGFpInitPoint(IppsGFpECPoint* pPoint, BNU_CHUNK_T* pData, int flags, const IppsGFpECState* pEC) +{ + ECP_POINT_SET_ID(pPoint); + ECP_POINT_FLAGS(pPoint) = flags; + ECP_POINT_FELEN(pPoint) = GFP_FELEN(GFP_PMA(ECP_GFP(pEC))); + ECP_POINT_DATA(pPoint) = pData; + return pPoint; +} + +/* copy one point into another */ +__INLINE IppsGFpECPoint* gfec_CopyPoint(IppsGFpECPoint* pPointR, const IppsGFpECPoint* pPointA, int elemLen) +{ + cpGFpElementCopy(ECP_POINT_DATA(pPointR), ECP_POINT_DATA(pPointA), 3*elemLen); + ECP_POINT_FLAGS(pPointR) = ECP_POINT_FLAGS(pPointA); + return pPointR; +} + + +__INLINE IppsGFpECPoint* gfec_SetPointAtInfinity(IppsGFpECPoint* pPoint) +{ + int elemLen = ECP_POINT_FELEN(pPoint); + cpGFpElementPad(ECP_POINT_X(pPoint), elemLen, 0); + cpGFpElementPad(ECP_POINT_Y(pPoint), elemLen, 0); + cpGFpElementPad(ECP_POINT_Z(pPoint), elemLen, 0); + ECP_POINT_FLAGS(pPoint) = 0; + return pPoint; +} + +/* +// test infinity: +// IsProjectivePointAtInfinity +*/ +__INLINE int gfec_IsPointAtInfinity(const IppsGFpECPoint* pPoint) +{ + return GFP_IS_ZERO( ECP_POINT_Z(pPoint), ECP_POINT_FELEN(pPoint)); +} + + + +/* signed encode */ +__INLINE void booth_recode(Ipp8u* sign, Ipp8u* digit, Ipp8u in, int w) +{ + Ipp8u s = (Ipp8u)(~((in >> w) - 1)); + int d = (1 << (w+1)) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + *sign = s & 1; + *digit = (Ipp8u)d; +} + + +#define gfec_point_add OWNAPI(gfec_point_add) +#define gfec_affine_point_add OWNAPI(gfec_affine_point_add) +#define gfec_point_double OWNAPI(gfec_point_double) +#define gfec_point_mul OWNAPI(gfec_point_mul) +#define gfec_point_prod OWNAPI(gfec_point_prod) +#define gfec_base_point_mul OWNAPI(gfec_base_point_mul) +#define setupTable OWNAPI(setupTable) + +IPP_OWN_DECL (void, gfec_point_add, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, const BNU_CHUNK_T* pQdata, IppsGFpECState* pEC)) +IPP_OWN_DECL (void, gfec_affine_point_add, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, const BNU_CHUNK_T* pAdata, IppsGFpECState* pEC)) +IPP_OWN_DECL (void, gfec_point_double, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, IppsGFpECState* pEC)) +IPP_OWN_DECL (void, gfec_point_mul, (BNU_CHUNK_T* pRdata, const BNU_CHUNK_T* pPdata, const Ipp8u* pScalar8, int scalarBitSize, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (void, gfec_point_prod, (BNU_CHUNK_T* pointR, const BNU_CHUNK_T* pointA, const Ipp8u* pScalarA, const BNU_CHUNK_T* pointB, const Ipp8u* pScalarB, int scalarBitSize, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (void, gfec_base_point_mul, (BNU_CHUNK_T* pRdata, const Ipp8u* pScalarB, int scalarBitSize, IppsGFpECState* pEC)) +IPP_OWN_DECL (void, setupTable, (BNU_CHUNK_T* pTbl, const BNU_CHUNK_T* pPdata, IppsGFpECState* pEC)) + + +/* size of context */ +#define cpGFpECGetSize OWNAPI(cpGFpECGetSize) +IPP_OWN_DECL (int, cpGFpECGetSize, (int deg, int basicElmBitSize)) + +/* point operations */ +#define gfec_GetPoint OWNAPI(gfec_GetPoint) +#define gfec_SetPoint OWNAPI(gfec_SetPoint) +#define gfec_MakePoint OWNAPI(gfec_MakePoint) +#define gfec_ComparePoint OWNAPI(gfec_ComparePoint) +#define gfec_IsPointOnCurve OWNAPI(gfec_IsPointOnCurve) + +IPP_OWN_DECL (int, gfec_GetPoint, (BNU_CHUNK_T* pX, BNU_CHUNK_T* pY, const IppsGFpECPoint* pPoint, IppsGFpECState* pEC)) +IPP_OWN_DECL (int, gfec_SetPoint, (BNU_CHUNK_T* pP, const BNU_CHUNK_T* pX, const BNU_CHUNK_T* pY, IppsGFpECState* pEC)) +IPP_OWN_DECL (int, gfec_MakePoint, (IppsGFpECPoint* pPoint, const BNU_CHUNK_T* pElm, IppsGFpECState* pEC)) +IPP_OWN_DECL (int, gfec_ComparePoint, (const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECState* pEC)) +IPP_OWN_DECL (int, gfec_IsPointOnCurve, (const IppsGFpECPoint* pP, IppsGFpECState* pEC)) + +__INLINE IppsGFpECPoint* gfec_DblPoint(IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, IppsGFpECState* pEC) +{ + gfec_point_double(ECP_POINT_X(pR), ECP_POINT_X(pP), pEC); + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR)? 0 : ECP_FINITE_POINT; + return pR; +} + +__INLINE IppsGFpECPoint* gfec_AddPoint(IppsGFpECPoint* pR, + const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, + IppsGFpECState* pEC) +{ + gfec_point_add(ECP_POINT_X(pR), ECP_POINT_X(pP), ECP_POINT_X(pQ), pEC); + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR)? 0 : ECP_FINITE_POINT; + return pR; +} + + +#define gfec_NegPoint OWNAPI(gfec_NegPoint) +#define gfec_MulPoint OWNAPI(gfec_MulPoint) +#define gfec_MulBasePoint OWNAPI(gfec_MulBasePoint) +/* #define gfec_PointProduct OWNAPI(gfec_PointProduct) */ +#define gfec_BasePointProduct OWNAPI(gfec_BasePointProduct) +#define p192r1_select_ap_w7 OWNAPI(p192r1_select_ap_w7) +#define p224r1_select_ap_w7 OWNAPI(p224r1_select_ap_w7) +#define p256r1_select_ap_w7 OWNAPI(p256r1_select_ap_w7) +#define p384r1_select_ap_w5 OWNAPI(p384r1_select_ap_w5) +#define p521r1_select_ap_w5 OWNAPI(p521r1_select_ap_w5) + +IPP_OWN_DECL (IppsGFpECPoint*, gfec_NegPoint, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, IppsGFpECState* pEC)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_MulPoint, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_MulBasePoint, (IppsGFpECPoint* pR, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +/* IPP_OWN_DECL (IppsGFpECPoint*, gfec_PointProduct, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalarP, int scalarPlen, const IppsGFpECPoint* pQ, const BNU_CHUNK_T* pScalarQ, int scalarQlen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) */ +IPP_OWN_DECL (IppsGFpECPoint*, gfec_BasePointProduct, (IppsGFpECPoint* pR, const BNU_CHUNK_T* pScalarG, int scalarGlen, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalarP, int scalarPlen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPP_OWN_DECL (void, p192r1_select_ap_w7, (BNU_CHUNK_T* pAffinePoint, const BNU_CHUNK_T* pTable, int index)) +IPP_OWN_DECL (void, p224r1_select_ap_w7, (BNU_CHUNK_T* pAffinePoint, const BNU_CHUNK_T* pTable, int index)) +IPP_OWN_DECL (void, p256r1_select_ap_w7, (BNU_CHUNK_T* pAffinePoint, const BNU_CHUNK_T* pTable, int index)) +IPP_OWN_DECL (void, p384r1_select_ap_w5, (BNU_CHUNK_T* pAffinePoint, const BNU_CHUNK_T* pTable, int index)) +IPP_OWN_DECL (void, p521r1_select_ap_w5, (BNU_CHUNK_T* pAffinePoint, const BNU_CHUNK_T* pTable, int index)) + +/* AVX512-IFMA implementations */ +#define gfec_SignDSA_nistp256_avx512 OWNAPI(gfec_SignDSA_nistp256_avx512) +#define gfec_SignDSA_nistp384_avx512 OWNAPI(gfec_SignDSA_nistp384_avx512) +#define gfec_SignDSA_nistp521_avx512 OWNAPI(gfec_SignDSA_nistp521_avx512) +#define gfec_Sign_sm2_avx512 OWNAPI(gfec_Sign_sm2_avx512) + +#define gfec_VerifyDSA_nistp256_avx512 OWNAPI(gfec_VerifyDSA_nistp256_avx512) +#define gfec_VerifyDSA_nistp384_avx512 OWNAPI(gfec_VerifyDSA_nistp384_avx512) +#define gfec_VerifyDSA_nistp521_avx512 OWNAPI(gfec_VerifyDSA_nistp521_avx512) +#define gfec_Verify_sm2_avx512 OWNAPI(gfec_Verify_sm2_avx512) + +#define gfec_SharedSecretDH_nistp256_avx512 OWNAPI(gfec_SharedSecretDH_nistp256_avx512) +#define gfec_SharedSecretDH_nistp384_avx512 OWNAPI(gfec_SharedSecretDH_nistp384_avx512) +#define gfec_SharedSecretDH_nistp521_avx512 OWNAPI(gfec_SharedSecretDH_nistp521_avx512) +#define gfec_SharedSecretDH_sm2_avx512 OWNAPI(gfec_SharedSecretDH_sm2_avx512) + +#define gfec_PubKey_nist256_avx512 OWNAPI(gfec_PubKey_nist256_avx512) +#define gfec_PubKey_nist384_avx512 OWNAPI(gfec_PubKey_nist384_avx512) +#define gfec_PubKey_nist521_avx512 OWNAPI(gfec_PubKey_nist521_avx512) +#define gfec_PubKey_sm2_avx512 OWNAPI(gfec_PubKey_sm2_avx512) + +#define gfec_MulPoint_nistp256_avx512 OWNAPI(gfec_MulPoint_nistp256_avx512) +#define gfec_MulPoint_nistp384_avx512 OWNAPI(gfec_MulPoint_nistp384_avx512) +#define gfec_MulPoint_nistp521_avx512 OWNAPI(gfec_MulPoint_nistp521_avx512) +#define gfec_MulPoint_sm2_avx512 OWNAPI(gfec_MulPoint_sm2_avx512) + +#define gfec_AddPoint_nistp256_avx512 OWNAPI(gfec_AddPoint_nistp256_avx512) +#define gfec_AddPoint_nistp384_avx512 OWNAPI(gfec_AddPoint_nistp384_avx512) +#define gfec_AddPoint_nistp521_avx512 OWNAPI(gfec_AddPoint_nistp521_avx512) +#define gfec_AddPoint_sm2_avx512 OWNAPI(gfec_AddPoint_sm2_avx512) + +#define gfec_point_on_curve_nistp256_avx512 OWNAPI(gfec_point_on_curve_nistp256_avx512) +#define gfec_point_on_curve_nistp384_avx512 OWNAPI(gfec_point_on_curve_nistp384_avx512) +#define gfec_point_on_curve_nistp521_avx512 OWNAPI(gfec_point_on_curve_nistp521_avx512) +#define gfec_point_on_curve_sm2_avx512 OWNAPI(gfec_point_on_curve_sm2_avx512) + +IPP_OWN_DECL (IppStatus, gfec_SignDSA_nistp256_avx512, (const IppsBigNumState* pMsgDigest, const IppsBigNumState* pRegPrivate, IppsBigNumState* pEphPrivate, IppsBigNumState* pSignR, IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppStatus, gfec_SignDSA_nistp384_avx512, (const IppsBigNumState* pMsgDigest, const IppsBigNumState* pRegPrivate, IppsBigNumState* pEphPrivate, IppsBigNumState* pSignR, IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppStatus, gfec_SignDSA_nistp521_avx512, (const IppsBigNumState* pMsgDigest, const IppsBigNumState* pRegPrivate, IppsBigNumState* pEphPrivate, IppsBigNumState* pSignR, IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppStatus, gfec_Sign_sm2_avx512, (const IppsBigNumState* pMsgDigest, const IppsBigNumState* pRegPrivate, IppsBigNumState* pEphPrivate, IppsBigNumState* pSignR, IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPP_OWN_DECL (IppECResult, gfec_VerifyDSA_nistp256_avx512, (const IppsBigNumState* pMsgDigest, const IppsGFpECPoint* pRegPublic, const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppECResult, gfec_VerifyDSA_nistp384_avx512, (const IppsBigNumState* pMsgDigest, const IppsGFpECPoint* pRegPublic, const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppECResult, gfec_VerifyDSA_nistp521_avx512, (const IppsBigNumState* pMsgDigest, const IppsGFpECPoint* pRegPublic, const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppECResult, gfec_Verify_sm2_avx512, (const IppsBigNumState* pMsgDigest, const IppsGFpECPoint* pRegPublic, const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPP_OWN_DECL (int, gfec_SharedSecretDH_nistp256_avx512, (IppsGFpECPoint * pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (int, gfec_SharedSecretDH_nistp384_avx512, (IppsGFpECPoint * pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (int, gfec_SharedSecretDH_nistp521_avx512, (IppsGFpECPoint * pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (int, gfec_SharedSecretDH_sm2_avx512, (IppsGFpECPoint * pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPP_OWN_DECL (IppsGFpECPoint*, gfec_PubKey_nist256_avx512, (IppsGFpECPoint * pR, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_PubKey_nist384_avx512, (IppsGFpECPoint * pR, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_PubKey_nist521_avx512, (IppsGFpECPoint * pR, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_PubKey_sm2_avx512, (IppsGFpECPoint * pR, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPP_OWN_DECL (IppsGFpECPoint*, gfec_MulPoint_nistp256_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_MulPoint_nistp384_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_MulPoint_nistp521_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_MulPoint_sm2_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const BNU_CHUNK_T* pScalar, int scalarLen, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) + +IPP_OWN_DECL (IppsGFpECPoint*, gfec_AddPoint_nistp256_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECState* pEC)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_AddPoint_nistp384_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECState* pEC)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_AddPoint_nistp521_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECState* pEC)) +IPP_OWN_DECL (IppsGFpECPoint*, gfec_AddPoint_sm2_avx512, (IppsGFpECPoint* pR, const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECState* pEC)) + +IPP_OWN_DECL (int, gfec_point_on_curve_nistp256_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) +IPP_OWN_DECL (int, gfec_point_on_curve_nistp384_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) +IPP_OWN_DECL (int, gfec_point_on_curve_nistp521_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) +IPP_OWN_DECL (int, gfec_point_on_curve_sm2_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) + +#define gfec_CheckPrivateKey OWNAPI(gfec_CheckPrivateKey) +IPP_OWN_DECL(int, gfec_CheckPrivateKey, (const IppsBigNumState* pPrivate, IppsGFpECState* pEC)) + +#endif /* _CP_ECGFP_H_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpectstpoint.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpectstpoint.c new file mode 100644 index 000000000..47bd4ca24 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpectstpoint.c @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECTstPoint() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsGFpECTstPoint +// +// Purpose: Checks if a point belongs to an elliptic curve +// +// Returns: Reason: +// ippStsNullPtrErr pP == NULL +// pEC == NULL +// pResult == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// invalid pP->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pP)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pP Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// pResult Pointer to the result of the check +// +// Note: +// Even if test passed is not a fact that the point belongs to BP-related subgroup BP +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECTstPoint,(const IppsGFpECPoint* pP, + IppECResult* pResult, + IppsGFpECState* pEC)) +{ + IPP_BAD_PTR3_RET(pP, pResult, pEC); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pP), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + if( gfec_IsPointAtInfinity(pP) ) + *pResult = ippECPointIsAtInfinite; + else if( !gfec_IsPointOnCurve(pP, pEC) ) + *pResult = ippECPointIsNotValid; + else + *pResult = ippECValid; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpectstpointinsubgroup.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpectstpointinsubgroup.c new file mode 100644 index 000000000..abae0718c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpectstpointinsubgroup.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p) Operations +// +// Context: +// ippsGFpECTstPointInSubgroup() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + + +/*F* +// Name: ippsGFpECTstPointInSubgroup +// +// Purpose: Checks if a point belongs to a specified subgroup +// +// Returns: Reason: +// ippStsNullPtrErr pP == NULL +// pEC == NULL +// pResult == NULL +/ pScratchBuffer == NULL +// +// ippStsContextMatchErr invalid pEC->idCtx +// pEC->subgroup == NULL +// invalid pP->idCtx +// +// ippStsOutOfRangeErr ECP_POINT_FELEN(pP)!=GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pP Pointer to the IppsGFpECPoint context +// pEC Pointer to the context of the elliptic curve +// pResult Pointer to the result of the check +// pScratchBuffer Pointer to the scratch buffer +// +*F*/ +IPPFUN(IppStatus, ippsGFpECTstPointInSubgroup,(const IppsGFpECPoint* pP, + IppECResult* pResult, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) +{ + IPP_BAD_PTR4_RET(pP, pResult, pEC, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + IPP_BADARG_RET( !ECP_POINT_VALID_ID(pP), ippStsContextMatchErr ); + + IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr); + + { + IppECResult tstResult; + ippsGFpECTstPoint(pP, &tstResult, pEC); + + if(ippECValid==tstResult) { + IppsGFpECPoint T; + cpEcGFpInitPoint(&T, cpEcGFpGetPool(1, pEC),0, pEC); + + gfec_MulPoint(&T, pP, MOD_MODULUS(ECP_MONT_R(pEC)), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)), /*0,*/ pEC, pScratchBuffer); + tstResult = gfec_IsPointAtInfinity(&T)? ippECValid : ippECPointOutOfGroup; + + cpEcGFpReleasePool(1, pEC); + } + *pResult = tstResult; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverify.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverify.c new file mode 100644 index 000000000..f84988ec2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverify.c @@ -0,0 +1,142 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// EC over GF(p^m) definitinons +// +// Context: +// ippsGFpECVerify() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpecstuff.h" +#include "pcpeccp.h" + +//tbcd: temporary excluded: #include +/*F* +// Name: ippsGFpECVerify +// +// Purpose: Verifies the parameters of an elliptic curve. +// +// Returns: Reason: +// ippStsNullPtrErr pEC == NULL +// pResult == NULL +// pScratchBuffer == NULL +// ippStsContextMatchErr invalid pEC->idCtx +// ippStsNoErr no error +// +// Parameters: +// pResult Pointer to the verification result +// pEC Pointer to the context of the elliptic curve +// pScratchBuffer Pointer to the scratch buffer +// +*F*/ + +IPPFUN(IppStatus, ippsGFpECVerify,(IppECResult* pResult, IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +{ + IPP_BAD_PTR3_RET(pEC, pResult, pScratchBuffer); + IPP_BADARG_RET( !VALID_ECP_ID(pEC), ippStsContextMatchErr ); + + *pResult = ippECValid; + + { + IppsGFpState* pGF = ECP_GFP(pEC); + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + + mod_mul mulF = GFP_METHOD(pGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGFE)->sqr; + mod_add addF = GFP_METHOD(pGFE)->add; + + /* + // check discriminant ( 4*A^3 + 27*B^2 != 0 mod P) + */ + if(ippECValid == *pResult) { + BNU_CHUNK_T* pT = cpGFpGetPool(1, pGFE); + BNU_CHUNK_T* pU = cpGFpGetPool(1, pGFE); + //tbcd: temporary excluded: assert(NULL!=pT && NULL!=pU); + + if(ECP_SPECIFIC(pEC)==ECP_EPID2) + cpGFpElementPad(pT, elemLen, 0); /* T = 4*A^3 = 0 */ + else { + addF(pT, ECP_A(pEC), ECP_A(pEC), pGFE); /* T = 4*A^3 */ + sqrF(pT, pT, pGFE); + mulF(pT, ECP_A(pEC), pT, pGFE); + } + + addF(pU, ECP_B(pEC), ECP_B(pEC), pGFE); /* U = 9*B^2 */ + addF(pU, pU, ECP_B(pEC), pGFE); + sqrF(pU, pU, pGFE); + + addF(pT, pU, pT, pGFE); /* T += 3*U */ + addF(pT, pU, pT, pGFE); + addF(pT, pU, pT, pGFE); + + *pResult = GFP_IS_ZERO(pT, elemLen)? ippECIsZeroDiscriminant: ippECValid; + + cpGFpReleasePool(2, pGFE); + } + + if(ECP_SUBGROUP(pEC)) { + /* + // check base point and it order + */ + if(ippECValid == *pResult) { + IppsGFpECPoint G; + cpEcGFpInitPoint(&G, ECP_G(pEC), ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC); + + /* check G != infinity */ + *pResult = gfec_IsPointAtInfinity(&G)? ippECPointIsAtInfinite : ippECValid; + + /* check G lies on EC */ + if(ippECValid == *pResult) + *pResult = gfec_IsPointOnCurve(&G, pEC)? ippECValid : ippECPointIsNotValid; + + /* check Gorder*G = infinity */ + if(ippECValid == *pResult) { + IppsGFpECPoint T; + cpEcGFpInitPoint(&T, cpEcGFpGetPool(1, pEC),0, pEC); + + gfec_MulBasePoint(&T, MOD_MODULUS(ECP_MONT_R(pEC)), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)), pEC, pScratchBuffer); + + *pResult = gfec_IsPointAtInfinity(&T)? ippECValid : ippECInvalidOrder; + + cpEcGFpReleasePool(1, pEC); + } + } + + /* + // check order==P + */ + if(ippECValid == *pResult) { + BNU_CHUNK_T* pPrime = GFP_MODULUS(pGFE); + int primeLen = GFP_FELEN(pGFE); + + gsModEngine* pR = ECP_MONT_R(pEC); + BNU_CHUNK_T* pOrder = MOD_MODULUS(pR); + int orderLen = MOD_LEN(pR); + + *pResult = (primeLen==orderLen && GFP_EQ(pPrime, pOrder, primeLen))? ippECIsWeakSSSA : ippECValid; + } + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifydsa.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifydsa.c new file mode 100644 index 000000000..6789e6864 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifydsa.c @@ -0,0 +1,205 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECVerifyDSA() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECVerifyDSA +// +// Purpose: DSA Signature Verification. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPublic +// NULL == pSignR +// NULL == pSignS +// NULL == pResult +// NULL == pScratchBuffer +// +// ippStsContextMatchErr illegal pECC->idCtx +// pEC->subgroup == NULL +// illegal pMsgDigestDigest->idCtx +// illegal pRegPublic->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsMessageErr 0> MsgDigest +// order<= MsgDigest +// +// ippStsRangeErr SignR < 0 or SignS < 0 +// +// ippStsOutOfRangeErr bitsize(pRegPublic) != bitsize(prime) +// +// ippStsNotSupportedModeErr 1 cpCmp_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pOrder, orderLen) && + 0 > cpCmp_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pOrder, orderLen)) { + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + switch (ECP_MODULUS_ID(pEC)) { + case cpID_PrimeP256r1: { + verifyResult = gfec_VerifyDSA_nistp256_avx512(pMsgDigest, pRegPublic, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + break; + } + case cpID_PrimeP384r1: { + verifyResult = gfec_VerifyDSA_nistp384_avx512(pMsgDigest, pRegPublic, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + break; + } + case cpID_PrimeP521r1: { + verifyResult = gfec_VerifyDSA_nistp521_avx512(pMsgDigest, pRegPublic, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + break; + } + default: + /* Go to default implementation below */ + break; + } + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + { + int elmLen = GFP_FELEN(pGFE); + int pelmLen = GFP_PELEN(pGFE); + BNU_CHUNK_T *h1 = cpGFpGetPool(3, pGFE); + BNU_CHUNK_T *h2 = h1 + pelmLen; + BNU_CHUNK_T *h = h2 + pelmLen; + + IppsGFpECPoint P; + cpEcGFpInitPoint(&P, cpEcGFpGetPool(1, pEC), 0, pEC); + + /* copy message and reduce */ + ZEXPAND_COPY_BNU(h1, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + cpModSub_BNU(h1, h1, pOrder, pOrder, orderLen, h2); + + /* h = d^-1, h1 = msg*h, h2 = c*h */ + ZEXPAND_COPY_BNU(h, orderLen, BN_NUMBER(pSignS), BN_SIZE(pSignS)); + gs_mont_inv(h, h, pMontR, alm_mont_inv); + + cpMontMul_BNU(h1, h, h1, pMontR); + ZEXPAND_COPY_BNU(h2, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + cpMontMul_BNU(h2, h, h2, pMontR); + + /* P = [h1]BasePoint + [h2]publicKey */ + gfec_BasePointProduct(&P, + h1, orderLen, pRegPublic, h2, orderLen, + pEC, pScratchBuffer); + + /* check that P!=O */ + if (!gfec_IsPointAtInfinity(&P)) { + /* get P.X */ + gfec_GetPoint(h1, NULL, &P, pEC); + /* c' = int(P.x) mod order */ + GFP_METHOD(pGFE)->decode(h1, h1, pGFE); + elmLen = cpMod_BNU(h1, elmLen, pOrder, orderLen); + cpGFpElementPad(h1 + elmLen, orderLen - elmLen, 0); + + /* and make sure c' = signC */ + cpGFpElementCopyPad(h2, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + if (GFP_EQ(h1, h2, orderLen)) + verifyResult = ippECValid; + } + + cpEcGFpReleasePool(1, pEC); + cpGFpReleasePool(3, pGFE); + } + } + +#if (_IPP32E >= _IPP32E_K1) +exit: +#endif + *pResult = verifyResult; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifynr.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifynr.c new file mode 100644 index 000000000..545db079d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifynr.c @@ -0,0 +1,166 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECVerifyNR() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECVerifyNR +// +// Purpose: NR Signature Verification. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPublic +// NULL == pSignR +// NULL == pSignS +// NULL == pResult +// NULL == pScratchBuffer +// +// ippStsContextMatchErr illegal pEC->idCtx +// pEC->subgroup == NULL +// illegal pMsgDigestDigest->idCtx +// illegal pRegPublic->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsMessageErr 0> MsgDigest +// order<= MsgDigest +// +// ippStsRangeErr SignR < 0 or SignS < 0 +// +// ippStsOutOfRangeErr bitsize(pRegPublic) != bitsize(prime) +// +// ippStsNotSupportedModeErr 1cpCmp_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pOrder, orderLen) && + 0>cpCmp_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pOrder, orderLen)) { + + int elmLen = GFP_FELEN(pGFE); + int pelmLen = GFP_PELEN(pGFE); + + BNU_CHUNK_T* h1 = cpGFpGetPool(3, pGFE); + BNU_CHUNK_T* h2 = h1+pelmLen; + BNU_CHUNK_T* f = h2+pelmLen; + + IppsGFpECPoint P; + cpEcGFpInitPoint(&P, cpEcGFpGetPool(1, pEC),0, pEC); + + /* P = [d]BasePoint + [c]publicKey */ + ZEXPAND_COPY_BNU(h1, orderLen, BN_NUMBER(pSignS),BN_SIZE(pSignS)); + ZEXPAND_COPY_BNU(h2, orderLen, BN_NUMBER(pSignR),BN_SIZE(pSignR)); + gfec_BasePointProduct(&P, + h1, orderLen, pRegPublic, h2, orderLen, + pEC, pScratchBuffer); + + /* check that P!=O */ + if( !gfec_IsPointAtInfinity(&P)) { + /* get P.X */ + gfec_GetPoint(h1, NULL, &P, pEC); + /* x = int(P.x) mod order */ + GFP_METHOD(pGFE)->decode(h1, h1, pGFE); + elmLen = cpMod_BNU(h1, elmLen, pOrder, orderLen); + cpGFpElementPad(h1+elmLen, orderLen-elmLen, 0); + + /* and recover msg f = (signC -x) mod order */ + ZEXPAND_COPY_BNU(f, orderLen, BN_NUMBER(pMsgDigest),BN_SIZE(pMsgDigest)); + cpModSub_BNU(h1, h2, h1, pOrder, orderLen, h2); + if(GFP_EQ(f, h1, orderLen)) + vResult = ippECValid; + } + + cpEcGFpReleasePool(1, pEC); + cpGFpReleasePool(3, pGFE); + } + + *pResult = vResult; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifysm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifysm2.c new file mode 100644 index 000000000..ea0b5b9cd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpecverifysm2.c @@ -0,0 +1,184 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsGFpECVerifySM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpeccp.h" + +/*F* +// Name: ippsGFpECVerifySM2 +// +// Purpose: SM2 Signature Verification. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pEC +// NULL == pMsgDigest +// NULL == pRegPublic +// NULL == pSignR +// NULL == pSignS +// NULL == pResult +// NULL == pScratchBuffer +// +// ippStsContextMatchErr illegal pECC->idCtx +// illegal pMsgDigestDigest->idCtx +// illegal pRegPublic->idCtx +// illegal pSignR->idCtx +// illegal pSignS->idCtx +// +// ippStsMessageErr 0> MsgDigest +// order<= MsgDigest +// +// ippStsRangeErr SignR < 0 or SignS < 0 +// +// ippStsOutOfRangeErr bitsize(pRegPublic) != bitsize(prime) +// +// ippStsNotSupportedModeErr 1cpCmp_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pOrder, orderLen) && + 0>cpCmp_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pOrder, orderLen)) { + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA) && ECP_MODULUS_ID(pEC) == cpID_PrimeTPM_SM2) { + vResult = gfec_Verify_sm2_avx512(pMsgDigest, pRegPublic, pSignR, pSignS, pEC, pScratchBuffer); + goto exit; + } /* no else */ +#endif // (_IPP32E >= _IPP32E_K1) + { + int elmLen = GFP_FELEN(pGFE); + int ns; + + BNU_CHUNK_T* r = cpGFpGetPool(4, pGFE); + BNU_CHUNK_T* s = r+orderLen; + BNU_CHUNK_T* t = s+orderLen; + BNU_CHUNK_T* f = t+orderLen; + + /* expand signatire's components */ + cpGFpElementCopyPad(r, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + cpGFpElementCopyPad(s, orderLen, BN_NUMBER(pSignS), BN_SIZE(pSignS)); + + /* t = (r+s) mod order */ + cpModAdd_BNU(t, r, s, pOrder, orderLen, f); + + /* check if t!=0 */ + if( !cpIsGFpElemEquChunk_ct(t, orderLen, 0) ) { + + /* P = [s]G +[t]regPublic, t = P.x */ + IppsGFpECPoint P, G; + cpEcGFpInitPoint(&P, cpEcGFpGetPool(1, pEC),0, pEC); + cpEcGFpInitPoint(&G, ECP_G(pEC), ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC); + + gfec_BasePointProduct(&P, + s, orderLen, pRegPublic, t, orderLen, + pEC, pScratchBuffer); + + gfec_GetPoint(t, NULL, &P, pEC); + GFP_METHOD(pGFE)->decode(t, t, pGFE); + ns = cpMod_BNU(t, elmLen, pOrder, orderLen); + + cpEcGFpReleasePool(1, pEC); + IPP_UNREFERENCED_PARAMETER(ns); + } + + /* t = (msg+t) mod order */ + cpGFpElementCopyPad(f, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + cpModSub_BNU(f, f, pOrder, pOrder, orderLen, s); + cpModAdd_BNU(t, t, f, pOrder, orderLen, f); + + if(GFP_EQ(t, r, orderLen)) + vResult = ippECValid; + + cpGFpReleasePool(4, pGFE); + } + } + +#if (_IPP32E >= _IPP32E_K1) +exit: +#endif + *pResult = vResult; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpelemgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpelemgetsize.c new file mode 100644 index 000000000..c28069a69 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpelemgetsize.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpElementGetSize() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +//tbcd: temporary excluded: #include + +/*F* +// Name: ippsGFpElementGetSize +// +// Purpose: Gets the size of the context for an element of the finite field. +// +// Returns: Reason: +// ippStsNullPtrErr pGFp == NULL +// pBufferSize == NULL +// ippStsContextMatchErr incorrect pGFp's context id +// ippStsNoErr no error +// +// Parameters: +// nExponents Number of exponents. +// ExpBitSize Maximum bit size of the exponents. +// pGFp Pointer to the context of the finite field. +// pBufferSize Pointer to the calculated buffer size in bytes. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpElementGetSize,(const IppsGFpState* pGFp, int* pElementSize)) +{ + IPP_BAD_PTR2_RET(pElementSize, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + *pElementSize = (Ipp32s)sizeof(IppsGFpElement) + +GFP_FELEN(GFP_PMA(pGFp))*(Ipp32s)sizeof(BNU_CHUNK_T); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpeleminit.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeleminit.c new file mode 100644 index 000000000..ee8e3522c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpeleminit.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpElementInit() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +//tbcd: temporary excluded: #include + +/*F* +// Name: ippsGFpElementInit +// +// Purpose: Initializes the context of an element of the finite field. +// +// Returns: Reason: +// ippStsNullPtrErr pGFp == NULL +// pR == NULL +// pA && nsA>0 == NULL +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pR->idCtx +// +// ippStsSizeErr pA && !(0<=lenA && lenA= modulus +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the data array storing the finite field element. +// lenA Length of the element. +// pR Pointer to the context of the finite field element being initialized. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpElementInit,(const Ipp32u* pA, int lenA, IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR2_RET(pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + IPP_BADARG_RET(0>lenA, ippStsSizeErr); + + { + int elemLen = GFP_FELEN(GFP_PMA(pGFp)); + + Ipp8u* ptr = (Ipp8u*)pR; + ptr += sizeof(IppsGFpElement); + cpGFpElementConstruct(pR, (BNU_CHUNK_T*)ptr, elemLen); + return ippsGFpSetElement(pA, lenA, pR, pGFp); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpexp.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpexp.c new file mode 100644 index 000000000..8363db90d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpexp.c @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpExp() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpExp +// +// Purpose: Raise GF element to the specified power +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// NULL == pE +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// invalid pE->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pE Pointer to the Big Number context storing the exponent +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// pScratchBuffer Pointer to the scratch buffer. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpExp,(const IppsGFpElement* pA, const IppsBigNumState* pE, + IppsGFpElement* pR, IppsGFpState* pGFp, + Ipp8u* pScratchBuffer)) +{ + IPP_BAD_PTR4_RET(pA, pE, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + + IPP_BADARG_RET( !BN_VALID_ID(pE), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + cpGFpxExp(GFPE_DATA(pR), GFPE_DATA(pA), BN_NUMBER(pE), BN_SIZE(pE), pGFE, pScratchBuffer); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpgetelem.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpgetelem.c new file mode 100644 index 000000000..83899e39b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpgetelem.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpGetElement() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +//tbcd: temporary excluded: #include + +/*F* +// Name: ippsGFpGetElement +// +// Purpose: Get GF Element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pDataA +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsSizeErr !(0=GFP_FELEN32(pGFE)) +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the finite field element. +// pDataA Pointer to the data array to copy the finite field element from. +// lenA Length of the data array. +// pGFp Pointer to the context of the finite field. +*F*/ + +IPPFUN(IppStatus, ippsGFpGetElement, (const IppsGFpElement* pA, Ipp32u* pDataA, int lenA, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pDataA, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFPE_ROOM(pA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + IPP_BADARG_RET( !(0=GFP_FELEN32(pGFE)), ippStsSizeErr ); + + { + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pGFE); + //tbcd: temporary excluded: assert(NULL!=pTmp); + + cpGFpxGet(pTmp, elemLen, GFPE_DATA(pA), pGFE); + cpGFpxCopyFromChunk(pDataA, pTmp, pGFE); + + cpGFpReleasePool(1, pGFE); + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpgetelemoctstr.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpgetelemoctstr.c new file mode 100644 index 000000000..b1f06546e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpgetelemoctstr.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpGetElementOctString() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpGetElementOctString +// +// Purpose: Get GF Element to the octet string +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pStr +// NULL == pA +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsSizeErr !(0=GFP_FELEN32(pGFE)) +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the finite field element. +// pStr Pointer to the octet string. +// strSize Size of the octet string buffer in bytes. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpGetElementOctString,(const IppsGFpElement* pA, Ipp8u* pStr, int strSize, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pStr, pA, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( 0>=strSize, ippStsSizeErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFPE_ROOM(pA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + { + gsModEngine* pBasicGFE = cpGFpBasic(pGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFE); + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicSize = BITS2WORD8_SIZE(BITSIZE_BNU(GFP_MODULUS(pBasicGFE),GFP_FELEN(pBasicGFE))); + + BNU_CHUNK_T* pDataElm = GFPE_DATA(pA); + int deg, error; + for(deg=0, error=0; deg GFP_MAX_BITSIZE), ippStsSizeErr); + + *pSize = cpGFpGetSize(feBitSize, feBitSize+BITSIZE(BNU_CHUNK_T), GFP_POOL_SIZE); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpinfo.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinfo.c new file mode 100644 index 000000000..d3351f5ae --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinfo.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p) ectension. +// +// Context: +// ippsGFpInfo() +// +*/ + +#include "owncp.h" +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" + + +/*F* +// Name: ippsGFpInit +// +// Purpose: finite field info +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pInfo +// +// ippStsContextMatchErr invalid pGFp->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pInfo pointer to finite field infon +// pGFp Pointer to the context of the finite field. +*F*/ +IPPFUN(IppStatus, ippsGFpGetInfo,(IppsGFpInfo* pInfo, const IppsGFpState* pGFp)) +{ + IPP_BAD_PTR2_RET(pGFp, pInfo); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + + { + gsModEngine* pGFpx = GFP_PMA(pGFp); /* current */ + gsModEngine* pGFpBasic = cpGFpBasic(pGFpx); /* basic */ + pInfo->parentGFdegree = MOD_EXTDEG(pGFpx); /* parent extension */ + pInfo->basicGFdegree = cpGFpBasicDegreeExtension(pGFpx); /* total basic extention */ + pInfo->basicElmBitSize = GFP_FEBITLEN(pGFpBasic); /* basic bitsise */ + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinit.c new file mode 100644 index 000000000..4764a0a91 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinit.c @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpInit +// +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpInit +// +// Purpose: initializes prime finite field GF(p) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFpMethod +// NULL == pGFp +// +// ippStsSizeErr !(IPP_MIN_GF_BITSIZE <= primeBitSize <=IPP_MAX_GF_BITSIZE +// +// ippStsContextMatchErr invalid pPrime->idCtx +// +// ippStsBadArgErr pGFpMethod != ippsGFpMethod_pXXX() or != ippsGFpMethod_pArb() +// prime != pGFpMethod->modulus +// prime <0 +// bitsize(prime) != primeBitSize +// prime IPP_MAX_GF_BITSIZE), ippStsSizeErr); + + /* use ippsGFpInitFixed() if NULL==pPrimeBN */ + if(!pPrimeBN) + return ippsGFpInitFixed(primeBitSize, pGFpMethod, pGFp); + + /* use ippsGFpInitArbitrary() if NULL==pGFpMethod */ + if(!pGFpMethod) + return ippsGFpInitArbitrary(pPrimeBN, primeBitSize, pGFp); + + /* test parameters if both pPrimeBN and method are defined */ + else { + IppStatus sts; + + /* test input prime */ + IPP_BADARG_RET(!BN_VALID_ID(pPrimeBN), ippStsContextMatchErr); + IPP_BADARG_RET(BN_SIGN(pPrimeBN)!= IppsBigNumPOS, ippStsBadArgErr); /* prime is negative */ + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pPrimeBN),BN_SIZE(pPrimeBN)) != primeBitSize, ippStsBadArgErr); /* primeBitSize == bitsize(prime) */ + IPP_BADARG_RET((BN_SIZE(pPrimeBN)==1) && (BN_NUMBER(pPrimeBN)[0]modulusID & cpID_Prime), ippStsBadArgErr); + + /* test if size of the prime is matched to method's prime */ + IPP_BADARG_RET(pGFpMethod->modulusBitDeg && (primeBitSize!=pGFpMethod->modulusBitDeg), ippStsBadArgErr); + + /* if method assumes fixed prime value */ + if(pGFpMethod->modulus) { + int primeLen = BITS_BNU_CHUNK(primeBitSize); + IPP_BADARG_RET(cpCmp_BNU(BN_NUMBER(pPrimeBN), primeLen, pGFpMethod->modulus, primeLen), ippStsBadArgErr); + } + + /* init GF */ + sts = cpGFpInitGFp(primeBitSize, pGFp); + + /* set up GF and find quadratic nonresidue */ + if(ippStsNoErr==sts) { + cpGFpSetGFp(BN_NUMBER(pPrimeBN), primeBitSize, pGFpMethod, pGFp); + } + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpinitarbitrary.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinitarbitrary.c new file mode 100644 index 000000000..ccdd9cefc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinitarbitrary.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpInitArbitrary() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpInitArbitrary +// +// Purpose: initializes prime finite field GF(p) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pPrime +// NULL == pGFp +// +// ippStsSizeErr !(IPP_MIN_GF_BITSIZE <= primeBitSize <=IPP_MAX_GF_BITSIZE) +// +// ippStsContextMatchErr incorrect pPrime context ID +// +// ippStsBadArgErr prime <0 +// bitsize(prime) != primeBitSize +// prime IPP_MAX_GF_BITSIZE), ippStsSizeErr); + + IPP_BAD_PTR1_RET(pPrime); + IPP_BADARG_RET(!BN_VALID_ID(pPrime), ippStsContextMatchErr); + IPP_BADARG_RET(BN_SIGN(pPrime)!= IppsBigNumPOS, ippStsBadArgErr); /* prime is negative */ + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pPrime),BN_SIZE(pPrime)) != primeBitSize, ippStsBadArgErr); /* primeBitSize == bitsize(prime) */ + IPP_BADARG_RET((BN_SIZE(pPrime)==1) && (BN_NUMBER(pPrime)[0]modulusID & cpID_Prime), ippStsBadArgErr); + /* test if method is not prime based arbitrary */ + IPP_BADARG_RET(!pGFpMethod->modulus, ippStsBadArgErr); + /* size of the underlying prime must be equal to primeBitSize parameter*/ + IPP_BADARG_RET(pGFpMethod->modulusBitDeg!=primeBitSize, ippStsBadArgErr); + + { + /* init GF */ + IppStatus sts = cpGFpInitGFp(primeBitSize, pGFp); + + /* set up GF engine */ + if(ippStsNoErr==sts) { + cpGFpSetGFp(pGFpMethod->modulus, primeBitSize, pGFpMethod, pGFp); + } + + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpinv.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinv.c new file mode 100644 index 000000000..7f4081467 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpinv.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpInv() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpInv +// +// Purpose: Multiplicative inverse GF element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsDivByZeroErr pA is zero +// +// ippStsBadArgErr computational error +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the source finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpInv,(const IppsGFpElement* pA, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( GFP_IS_ZERO(GFPE_DATA(pA),GFP_FELEN(pGFE)), ippStsDivByZeroErr ); + + return NULL != cpGFpxInv(GFPE_DATA(pR), GFPE_DATA(pA), pGFE)? ippStsNoErr : ippStsBadArgErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpisunityelem.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpisunityelem.c new file mode 100644 index 000000000..614b8ff58 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpisunityelem.c @@ -0,0 +1,84 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpIsUnityElement() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpIsUnityElement +// +// Purpose: Compare GF Element with unity element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pResult +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the finite field element. +// pResult Pointer to the result of the comparison +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpIsUnityElement,(const IppsGFpElement* pA, + int* pResult, + const IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pResult, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFPE_ROOM(pA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + { + gsModEngine* pBasicGFE = cpGFpBasic(pGFE); + int basicElmLen = GFP_FELEN(pBasicGFE); + BNU_CHUNK_T* pUnity = GFP_MNT_R(pBasicGFE); + + int elmLen = GFP_FELEN(pGFE); + int flag; + + FIX_BNU(pUnity, basicElmLen); + FIX_BNU(GFPE_DATA(pA), elmLen); + + flag = (basicElmLen==elmLen) && (GFP_EQ(GFPE_DATA(pA), pUnity, elmLen)); + *pResult = (1==flag)? IPP_IS_EQ : IPP_IS_NE; + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpiszeroelem.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpiszeroelem.c new file mode 100644 index 000000000..13e82a5e8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpiszeroelem.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpIsZeroElement() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpIsZeroElement +// +// Purpose: Compare GF Element with zero element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pResult +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the finite field element. +// pResult Pointer to the result of the comparison +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpIsZeroElement,(const IppsGFpElement* pA, + int* pResult, + const IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pResult, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFPE_ROOM(pA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + { + int flag = GFP_IS_ZERO(GFPE_DATA(pA), GFP_FELEN(pGFE)); + *pResult = (1==flag)? IPP_IS_EQ : IPP_IS_NE; + return ippStsNoErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod.h new file mode 100644 index 000000000..6e79cb01a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod.h @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives +// Internal GF(p) basic Definitions & Function Prototypes +// +*/ +#if !defined(_CP_GFP_METHOD_H) +#define _CP_GFP_METHOD_H + +#include "owncp.h" + +#include "pcpbnuimpl.h" +#include "gsmodmethod.h" + +/* modulus ID */ +typedef enum { + cpID_Prime = 0x1000, + cpID_PrimeP192r1 = cpID_Prime+6, + cpID_PrimeP224r1 = cpID_Prime+7, + cpID_PrimeP256r1 = cpID_Prime+8, + cpID_PrimeP384r1 = cpID_Prime+9, + cpID_PrimeP521r1 = cpID_Prime+10, + cpID_PrimeTPM_SM2 = cpID_Prime+11, + cpID_PrimeTPM_BN = cpID_Prime+12, + + cpID_Poly = 0x10000000, /* id=0x10000000: general polynomial */ + cpID_Binom = 0x01000000, /* id=0x11000000: x^d+a */ + + cpID_Binom2_epid20 = cpID_Binom|0x220000, /* 0x11220000 */ + cpID_Binom3_epid20 = cpID_Binom|0x230000 /* 0x11230000 */ + +} cpModulusID; + +typedef struct _cpGFpMethod { + cpModulusID modulusID; + int modulusBitDeg; + const BNU_CHUNK_T* modulus; + const gsModMethod* arith; + const void* arith_alt; // alternative radix implementation +} cpGFpMethod; + +/* common GF arith methods */ +#define gsArithGFp OWNAPI(gsArithGFp) + IPP_OWN_DECL (gsModMethod*, gsArithGFp, (void)) + +#endif /* _CP_GFP_METHOD_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_192r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_192r1.c new file mode 100644 index 000000000..eab0fa26d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_192r1.c @@ -0,0 +1,207 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpbnumisc.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpmethod.h" +#include "pcpecprime.h" + +//tbcd: temporary excluded: #include + +#if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + +/* arithmetic over P-192r1 NIST modulus */ +#define p192r1_add OWNAPI(p192r1_add) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_add, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p192r1_sub OWNAPI(p192r1_sub) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_sub, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p192r1_neg OWNAPI(p192r1_neg) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_neg, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p192r1_div_by_2 OWNAPI(p192r1_div_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_div_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p192r1_mul_by_2 OWNAPI(p192r1_mul_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_mul_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p192r1_mul_by_3 OWNAPI(p192r1_mul_by_3) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_mul_by_3, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) + +#if(_IPP_ARCH ==_IPP_ARCH_EM64T) +#define p192r1_mul_montl OWNAPI(p192r1_mul_montl) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_mul_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p192r1_mul_montx OWNAPI(p192r1_mul_montx) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_mul_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p192r1_sqr_montl OWNAPI(p192r1_sqr_montl) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_sqr_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p192r1_sqr_montx OWNAPI(p192r1_sqr_montx) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_sqr_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p192r1_to_mont OWNAPI(p192r1_to_mont) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_to_mont, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p192r1_mont_back OWNAPI(p192r1_mont_back) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_mont_back, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#endif + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +#define p192r1_mul_mont_slm OWNAPI(p192r1_mul_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_mul_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p192r1_sqr_mont_slm OWNAPI(p192r1_sqr_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_sqr_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p192r1_mred OWNAPI(p192r1_mred) + IPP_OWN_DECL (BNU_CHUNK_T*, p192r1_mred, (BNU_CHUNK_T* res, BNU_CHUNK_T* product)) +#endif + +#define OPERAND_BITSIZE (192) +#define LEN_P192 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* +// ia32 multiplicative methods +*/ +#if (_IPP_ARCH ==_IPP_ARCH_IA32) +IPP_OWN_DEFN (static BNU_CHUNK_T*, p192r1_mul_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpMulAdc_BNU_school(product, pA,LEN_P192, pB,LEN_P192); + p192r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p192r1_sqr_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpSqrAdc_BNU_school(product, pA,LEN_P192); + p192r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + + +/* +// Montgomery domain conversion constants +*/ +static BNU_CHUNK_T RR[] = { + 0x00000001,0x00000000,0x00000002,0x00000000, + 0x00000001,0x00000000}; + +static BNU_CHUNK_T one[] = { + 1,0,0,0,0,0}; + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p192r1_to_mont, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p192r1_mul_montl(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p192r1_mont_back, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p192r1_mul_montl(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p192r1_to_mont_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p192r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p192r1_mont_back_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p192r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} +#endif /* _IPP >= _IPP_P8 */ + +/* +// return specific gf p192r1 arith methods, +// p192r1 = 2^192 -2^64 -1 (NIST P192r1) +*/ +static gsModMethod* gsArithGF_p192r1 (void) +{ + static gsModMethod m = { + p192r1_to_mont, + p192r1_mont_back, + p192r1_mul_montl, + p192r1_sqr_montl, + NULL, + p192r1_add, + p192r1_sub, + p192r1_neg, + p192r1_div_by_2, + p192r1_mul_by_2, + p192r1_mul_by_3, + }; + + #if(_IPP_ARCH==_IPP_ARCH_EM64T) && ((_ADCOX_NI_ENABLING_==_FEATURE_ON_) || (_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_)) + if(IsFeatureEnabled(ippCPUID_ADCOX)) { + m.mul = p192r1_mul_montx; + m.sqr = p192r1_sqr_montx; + } + #endif + + #if(_IPP_ARCH==_IPP_ARCH_IA32) + if(IsFeatureEnabled(ippCPUID_SSSE3|ippCPUID_MOVBE) && !IsFeatureEnabled(ippCPUID_AVX)) { + m.mul = p192r1_mul_mont_slm; + m.sqr = p192r1_sqr_mont_slm; + m.encode = p192r1_to_mont_slm; + m.decode = p192r1_mont_back_slm; + } + #endif + + return &m; +} +#endif /* (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) */ + +/*F* +// Name: ippsGFpMethod_p192r1 +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). q = 2^192 - 2^64 - 1 +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_p192r1, (void) ) +{ + static IppsGFpMethod method = { + cpID_PrimeP192r1, + 192, + secp192r1_p, + NULL, + NULL + }; + + #if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p192r1(); + #else + method.arith = gsArithGFp(); + #endif + + return &method; +} + +#undef LEN_P192 +#undef OPERAND_BITSIZE diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_224r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_224r1.c new file mode 100644 index 000000000..66278e5e0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_224r1.c @@ -0,0 +1,207 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpbnumisc.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpmethod.h" +#include "pcpecprime.h" + +//tbcd: temporary excluded: #include + +#if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + +/* arithmetic over P-224r1 NIST modulus */ +#define p224r1_add OWNAPI(p224r1_add) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_add, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p224r1_sub OWNAPI(p224r1_sub) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_sub, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p224r1_neg OWNAPI(p224r1_neg) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_neg, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p224r1_div_by_2 OWNAPI(p224r1_div_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_div_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p224r1_mul_by_2 OWNAPI(p224r1_mul_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_mul_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p224r1_mul_by_3 OWNAPI(p224r1_mul_by_3) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_mul_by_3, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) + +#if(_IPP_ARCH ==_IPP_ARCH_EM64T) +#define p224r1_mul_montl OWNAPI(p224r1_mul_montl) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_mul_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p224r1_mul_montx OWNAPI(p224r1_mul_montx) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_mul_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p224r1_sqr_montl OWNAPI(p224r1_sqr_montl) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_sqr_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p224r1_sqr_montx OWNAPI(p224r1_sqr_montx) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_sqr_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p224r1_to_mont OWNAPI(p224r1_to_mont) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_to_mont, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p224r1_mont_back OWNAPI(p224r1_mont_back) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_mont_back, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#endif + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +#define p224r1_mul_mont_slm OWNAPI(p224r1_mul_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_mul_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p224r1_sqr_mont_slm OWNAPI(p224r1_sqr_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_sqr_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p224r1_mred OWNAPI(p224r1_mred) + IPP_OWN_DECL (BNU_CHUNK_T*, p224r1_mred, (BNU_CHUNK_T* res, BNU_CHUNK_T* product)) +#endif + +#define OPERAND_BITSIZE (224) +#define LEN_P224 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* +// ia32 multiplicative methods +*/ +#if (_IPP_ARCH ==_IPP_ARCH_IA32) +IPP_OWN_DEFN (static BNU_CHUNK_T*, p224r1_mul_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpMulAdc_BNU_school(product, pA,LEN_P224, pB,LEN_P224); + p224r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p224r1_sqr_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpSqrAdc_BNU_school(product, pA,LEN_P224); + p224r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + + +/* +// Montgomery domain conversion constants +*/ +static BNU_CHUNK_T RR[] = { + 0x00000001,0x00000000,0x00000000,0xfffffffe, + 0xffffffff,0xffffffff,0x00000000}; + +static BNU_CHUNK_T one[] = { + 1,0,0,0,0,0,0}; + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p224r1_to_mont, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p224r1_mul_montl(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p224r1_mont_back, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p224r1_mul_montl(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p224r1_to_mont_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p224r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p224r1_mont_back_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p224r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} +#endif /* _IPP >= _IPP_P8 */ + +/* +// return specific gf p224r1 arith methods, +// p224r1 = 2^224 -2^96 +1 (NIST P224r1) +*/ +static gsModMethod* gsArithGF_p224r1 (void) +{ + static gsModMethod m = { + p224r1_to_mont, + p224r1_mont_back, + p224r1_mul_montl, + p224r1_sqr_montl, + NULL, + p224r1_add, + p224r1_sub, + p224r1_neg, + p224r1_div_by_2, + p224r1_mul_by_2, + p224r1_mul_by_3, + }; + + #if(_IPP_ARCH==_IPP_ARCH_EM64T) && ((_ADCOX_NI_ENABLING_==_FEATURE_ON_) || (_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_)) + if(IsFeatureEnabled(ippCPUID_ADCOX)) { + m.mul = p224r1_mul_montx; + m.sqr = p224r1_sqr_montx; + } + #endif + + #if(_IPP_ARCH==_IPP_ARCH_IA32) + if(IsFeatureEnabled(ippCPUID_SSSE3|ippCPUID_MOVBE) && !IsFeatureEnabled(ippCPUID_AVX)) { + m.mul = p224r1_mul_mont_slm; + m.sqr = p224r1_sqr_mont_slm; + m.encode = p224r1_to_mont_slm; + m.decode = p224r1_mont_back_slm; + } + #endif + + return &m; +} +#endif /* (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) */ + +/*F* +// Name: ippsGFpMethod_p224r1 +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). q = 2^224 - 2^96 - 1 +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_p224r1, (void) ) +{ + static IppsGFpMethod method = { + cpID_PrimeP224r1, + 224, + secp224r1_p, + NULL, + NULL + }; + + #if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p224r1(); + #else + method.arith = gsArithGFp(); + #endif + + return &method; +} + +#undef LEN_P224 +#undef OPERAND_BITSIZE diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256.c new file mode 100644 index 000000000..317f32674 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "pcpgfpmethod_256.h" + +/*F* +// Name: ippsGFpMethod_p256 +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). Arbitrary 256 bit modulus. +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_p256, (void) ) +{ + static IppsGFpMethod method = { + cpID_Prime, + 256, + NULL, + NULL, + NULL + }; + + #if(_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p256(); + #else + method.arith = gsArithGFp(); + #endif + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256.h new file mode 100644 index 000000000..5a5318dd8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256.h @@ -0,0 +1,130 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpbnumisc.h" +#include "pcpgfpstuff.h" +#include "pcpgfpmethod.h" +#include "pcpecprime.h" + +#if !defined(_PCP_GFPMETHOD_256_H_) +#define _PCP_GFPMETHOD_256_H_ + +#if(_IPP32E >= _IPP32E_M7) + +/* arithmetic over arbitrary 256r-bit modulus */ +#define gf256_add OWNAPI(gf256_add) + IPP_OWN_DECL (BNU_CHUNK_T*, gf256_add, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, const BNU_CHUNK_T* pModulus)) +#define gf256_sub OWNAPI(gf256_sub) + IPP_OWN_DECL (BNU_CHUNK_T*, gf256_sub, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, const BNU_CHUNK_T* pModulus)) +#define gf256_neg OWNAPI(gf256_neg) + IPP_OWN_DECL (BNU_CHUNK_T*, gf256_neg, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pModulus)) +#define gf256_mulm OWNAPI(gf256_mulm) + IPP_OWN_DECL (BNU_CHUNK_T*, gf256_mulm, (BNU_CHUNK_T* pR,const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, const BNU_CHUNK_T* pModulus, BNU_CHUNK_T m0)) +#define gf256_sqrm OWNAPI(gf256_sqrm) + IPP_OWN_DECL (BNU_CHUNK_T*, gf256_sqrm, (BNU_CHUNK_T* pR,const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pModulus, BNU_CHUNK_T m0)) +#define gf256_div2 OWNAPI(gf256_div2) + IPP_OWN_DECL (BNU_CHUNK_T*, gf256_div2, (BNU_CHUNK_T* pR,const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pModulus)) + +#define OPERAND_BITSIZE (256) +#define LEN_P256 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +static BNU_CHUNK_T* p256_add(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE) +{ + return gf256_add(pR, pA, pB, GFP_MODULUS(pGFE)); +} + +static BNU_CHUNK_T* p256_sub(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE) +{ + return gf256_sub(pR, pA, pB, GFP_MODULUS(pGFE)); +} + +static BNU_CHUNK_T* p256_neg(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE) +{ + return gf256_neg(pR, pA, GFP_MODULUS(pGFE)); +} + +static BNU_CHUNK_T* p256_div_by_2(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE) +{ + return gf256_div2(pR, pA, GFP_MODULUS(pGFE)); +} + +static BNU_CHUNK_T* p256_mul_by_2(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE) +{ + return gf256_add(pR, pA, pA, GFP_MODULUS(pGFE)); +} + +static BNU_CHUNK_T* p256_mul_by_3(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE) +{ + BNU_CHUNK_T tmp[LEN_P256]; + gf256_add(tmp, pA, pA, GFP_MODULUS(pGFE)); + return gf256_add(pR, tmp, pA, GFP_MODULUS(pGFE)); +} + +static BNU_CHUNK_T* p256_mul_montl(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE) +{ + return gf256_mulm(pR, pA, pB, GFP_MODULUS(pGFE), GFP_MNT_FACTOR(pGFE)); +} + +static BNU_CHUNK_T* p256_sqr_montl(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE) +{ + return gf256_sqrm(pR, pA, GFP_MODULUS(pGFE), GFP_MNT_FACTOR(pGFE)); +} + +static BNU_CHUNK_T* p256_to_mont(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE) +{ + return gf256_mulm(pR, pA, GFP_MNT_RR(pGFE), GFP_MODULUS(pGFE), GFP_MNT_FACTOR(pGFE)); +} + +static BNU_CHUNK_T one[] = {1,0,0,0}; + +static BNU_CHUNK_T* p256_mont_back(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE) +{ + return gf256_mulm(pR, pA, one, GFP_MODULUS(pGFE), GFP_MNT_FACTOR(pGFE)); +} + +/* return specific gf p256 arith methods */ +static gsModMethod* gsArithGF_p256(void) +{ + static gsModMethod m = { + p256_to_mont, + p256_mont_back, + p256_mul_montl, + p256_sqr_montl, + NULL, + p256_add, + p256_sub, + p256_neg, + p256_div_by_2, + p256_mul_by_2, + p256_mul_by_3, + }; + return &m; +} +#endif /* _IPP32E >= _IPP32E_M7 */ + +#undef LEN_P256 +#undef OPERAND_BITSIZE + +#endif /* #if !defined(_PCP_GFPMETHOD_256_H_) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256bn.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256bn.c new file mode 100644 index 000000000..3f7719352 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256bn.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ + +#include "pcpgfpmethod_256.h" + +/*F* +// Name: ippsGFpMethod_p256bn +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). q = +// 0xFFFFFFFFFFFCF0CD46E5F25EEE71A49F0CDC65FB12980A82D3292DDBAED33013 +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_p256bn, (void) ) +{ + static IppsGFpMethod method = { + cpID_Prime, + 256, + tpmBN_p256p_p, + NULL, + NULL + }; + + #if(_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p256(); + #else + method.arith = gsArithGFp(); + #endif + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256r1.c new file mode 100644 index 000000000..1b8c01741 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_256r1.c @@ -0,0 +1,215 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpbnumisc.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpmethod.h" +#include "pcpecprime.h" + +#include "ifma_arith_method.h" + +//tbcd: temporary excluded: #include + +#if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + +/* arithmetic over P-256r1 NIST modulus */ +#define p256r1_add OWNAPI(p256r1_add) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_add, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p256r1_sub OWNAPI(p256r1_sub) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_sub, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p256r1_neg OWNAPI(p256r1_neg) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_neg, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p256r1_div_by_2 OWNAPI(p256r1_div_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_div_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p256r1_mul_by_2 OWNAPI(p256r1_mul_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_mul_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p256r1_mul_by_3 OWNAPI(p256r1_mul_by_3) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_mul_by_3, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) + +#if(_IPP_ARCH ==_IPP_ARCH_EM64T) +#define p256r1_mul_montl OWNAPI(p256r1_mul_montl) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_mul_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p256r1_mul_montx OWNAPI(p256r1_mul_montx) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_mul_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p256r1_sqr_montl OWNAPI(p256r1_sqr_montl) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_sqr_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p256r1_sqr_montx OWNAPI(p256r1_sqr_montx) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_sqr_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p256r1_to_mont OWNAPI(p256r1_to_mont) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_to_mont, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p256r1_mont_back OWNAPI(p256r1_mont_back) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_mont_back, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#endif + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +#define p256r1_mul_mont_slm OWNAPI(p256r1_mul_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_mul_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p256r1_sqr_mont_slm OWNAPI(p256r1_sqr_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_sqr_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p256r1_mred OWNAPI(p256r1_mred) + IPP_OWN_DECL (BNU_CHUNK_T*, p256r1_mred, (BNU_CHUNK_T* res, BNU_CHUNK_T* product)) +#endif + +#define OPERAND_BITSIZE (256) +#define LEN_P256 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* +// ia32 multiplicative methods +*/ +#if (_IPP_ARCH ==_IPP_ARCH_IA32) +IPP_OWN_DEFN (static BNU_CHUNK_T*, p256r1_mul_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpMulAdc_BNU_school(product, pA,LEN_P256, pB,LEN_P256); + p256r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p256r1_sqr_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpSqrAdc_BNU_school(product, pA,LEN_P256); + p256r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + + +/* +// Montgomery domain conversion constants +*/ +static BNU_CHUNK_T RR[] = { + 0x00000003,0x00000000, 0xffffffff,0xfffffffb, + 0xfffffffe,0xffffffff, 0xfffffffd,0x00000004}; + +static BNU_CHUNK_T one[] = { + 1,0,0,0,0,0,0,0}; + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p256r1_to_mont, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p256r1_mul_montl(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p256r1_mont_back, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p256r1_mul_montl(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p256r1_to_mont_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p256r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p256r1_mont_back_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p256r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} +#endif /* _IPP >= _IPP_P8 */ + +/* +// return specific gf p256r1 arith methods, +// p256r1 = 2^256 -2^224 +2^192 +2^96 -1 (NIST P256r1) +*/ +static gsModMethod* gsArithGF_p256r1 (void) +{ + static gsModMethod m = { + p256r1_to_mont, + p256r1_mont_back, + p256r1_mul_montl, + p256r1_sqr_montl, + NULL, + p256r1_add, + p256r1_sub, + p256r1_neg, + p256r1_div_by_2, + p256r1_mul_by_2, + p256r1_mul_by_3, + }; + + #if(_IPP_ARCH==_IPP_ARCH_EM64T) && ((_ADCOX_NI_ENABLING_==_FEATURE_ON_) || (_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_)) + if(IsFeatureEnabled(ippCPUID_ADCOX)) { + m.mul = p256r1_mul_montx; + m.sqr = p256r1_sqr_montx; + } + #endif + + #if(_IPP_ARCH==_IPP_ARCH_IA32) + if(IsFeatureEnabled(ippCPUID_SSSE3|ippCPUID_MOVBE) && !IsFeatureEnabled(ippCPUID_AVX)) { + m.mul = p256r1_mul_mont_slm; + m.sqr = p256r1_sqr_mont_slm; + m.encode = p256r1_to_mont_slm; + m.decode = p256r1_mont_back_slm; + } + #endif + + return &m; +} +#endif /* (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) */ + +/*F* +// Name: ippsGFpMethod_p256r1 +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). q = 2^256 - 2^224 + 2^192 + 2^96 - 1 +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_p256r1, (void) ) +{ + static IppsGFpMethod method = { + cpID_PrimeP256r1, + 256, + secp256r1_p, + NULL, + NULL + }; + +#if (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p256r1(); +#else + method.arith = gsArithGFp(); +#endif + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + method.arith_alt = gsArithGF_p256r1_avx512(); + } +#endif + + return &method; +} + +#undef LEN_P256 +#undef OPERAND_BITSIZE diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_384r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_384r1.c new file mode 100644 index 000000000..f98a0f9de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_384r1.c @@ -0,0 +1,213 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "ecnist/ifma_arith_method.h" + +#include "pcpbnumisc.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpmethod.h" +#include "pcpbnuarith.h" +#include "pcpecprime.h" + +#if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + +/* arithmetic over P-384r1 NIST modulus */ +#define p384r1_add OWNAPI(p384r1_add) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_add, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p384r1_sub OWNAPI(p384r1_sub) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_sub, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p384r1_neg OWNAPI(p384r1_neg) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_neg, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p384r1_div_by_2 OWNAPI(p384r1_div_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_div_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p384r1_mul_by_2 OWNAPI(p384r1_mul_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_mul_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p384r1_mul_by_3 OWNAPI(p384r1_mul_by_3) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_mul_by_3, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) + +#if(_IPP_ARCH ==_IPP_ARCH_EM64T) +//BNU_CHUNK_T* p384r1_mul_montl(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE); +//BNU_CHUNK_T* p384r1_sqr_montl(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +//BNU_CHUNK_T* p384r1_mul_montx(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE); +//BNU_CHUNK_T* p384r1_sqr_montx(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +//BNU_CHUNK_T* p384r1_to_mont (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +//BNU_CHUNK_T* p384r1_mont_back(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +#endif + +#define p384r1_mred OWNAPI(p384r1_mred) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_mred, (BNU_CHUNK_T* res, BNU_CHUNK_T* product)) + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +#define p384r1_mul_mont_slm OWNAPI(p384r1_mul_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_mul_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p384r1_sqr_mont_slm OWNAPI(p384r1_sqr_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p384r1_sqr_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#endif + +#define OPERAND_BITSIZE (384) +#define LEN_P384 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* +// multiplicative methods +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, p384r1_mul_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpMul_BNU_school(product, pA,LEN_P384, pB,LEN_P384); + p384r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p384r1_sqr_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = gsModPoolAlloc((gsModEngine*)pGFE, 2); + if(NULL == product) + return NULL; + + cpSqr_BNU_school(product, pA,LEN_P384); + p384r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + + +/* +// Montgomery domain conversion constants +*/ +static Ipp64u RR[] = { + 0xfffffffe00000001,0x0000000200000000,0xfffffffe00000000, + 0x0000000200000000,0x0000000000000001,0x0000000000000000 +}; + +static BNU_CHUNK_T one[] = { +#if(_IPP_ARCH == _IPP_ARCH_EM64T) + 1,0,0,0,0,0}; +#elif(_IPP_ARCH == _IPP_ARCH_IA32) + 1,0,0,0,0,0,0,0,0,0,0,0}; +#endif + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p384r1_to_mont, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p384r1_mul_montl(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p384r1_mont_back, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p384r1_mul_montl(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} + +#if (_ADCOX_NI_ENABLING_==_FEATURE_ON_) || (_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_) +//BNU_CHUNK_T* p384r1_mul_montx(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE) +//BNU_CHUNK_T* p384r1_sqr_montx(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE) +#endif + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +IPP_OWN_DEFN (static BNU_CHUNK_T*, p384r1_to_mont_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p384r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p384r1_mont_back_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p384r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} +#endif /* _IPP_ARCH ==_IPP_ARCH_IA32 */ + +/* +// return specific gf p384r1 arith methods, +// p384r1 = 2^384 -2^128 -2^96 +2^32 -1 (NIST P384r1) +*/ +static gsModMethod* gsArithGF_p384r1 (void) +{ + static gsModMethod m = { + p384r1_to_mont, + p384r1_mont_back, + p384r1_mul_montl, + p384r1_sqr_montl, + NULL, + p384r1_add, + p384r1_sub, + p384r1_neg, + p384r1_div_by_2, + p384r1_mul_by_2, + p384r1_mul_by_3, + }; + + #if(_IPP_ARCH==_IPP_ARCH_IA32) + if(IsFeatureEnabled(ippCPUID_SSSE3|ippCPUID_MOVBE) && !IsFeatureEnabled(ippCPUID_AVX)) { + m.mul = p384r1_mul_mont_slm; + m.sqr = p384r1_sqr_mont_slm; + m.encode = p384r1_to_mont_slm; + m.decode = p384r1_mont_back_slm; + } + #endif + + return &m; +} +#endif /* (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) */ + +/*F* +// Name: ippsGFpMethod_p384r1 +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). q = 2^384 - 2^128 - 2^96 + 2^32 - 1 +*F*/ + +IPPFUN(const IppsGFpMethod *, ippsGFpMethod_p384r1, (void)) +{ + static IppsGFpMethod method = { + cpID_PrimeP384r1, + 384, + secp384r1_p, + NULL, + NULL + }; + +#if (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p384r1(); +#else + method.arith = gsArithGFp(); +#endif + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + method.arith_alt = gsArithGF_p384r1_avx512(); + } +#endif + + return &method; +} + +#undef LEN_P384 +#undef OPERAND_BITSIZE diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_521r1.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_521r1.c new file mode 100644 index 000000000..a30345d9d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_521r1.c @@ -0,0 +1,220 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpbnumisc.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpmethod.h" +#include "pcpbnuarith.h" +#include "pcpecprime.h" + +#include "ecnist/ifma_arith_method_p521.h" + +//tbcd: temporary excluded: #include + +#if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + +/* arithmetic over P-521r1 NIST modulus */ +#define p521r1_add OWNAPI(p521r1_add) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_add, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p521r1_sub OWNAPI(p521r1_sub) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_sub, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p521r1_neg OWNAPI(p521r1_neg) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_neg, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p521r1_div_by_2 OWNAPI(p521r1_div_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_div_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p521r1_mul_by_2 OWNAPI(p521r1_mul_by_2) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_mul_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#define p521r1_mul_by_3 OWNAPI(p521r1_mul_by_3) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_mul_by_3, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) + +#if(_IPP_ARCH ==_IPP_ARCH_EM64T) +//BNU_CHUNK_T* p521r1_to_mont (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +//BNU_CHUNK_T* p521r1_mont_back(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +//BNU_CHUNK_T* p521r1_mul_montl(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE); +//BNU_CHUNK_T* p521r1_sqr_montl(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +//BNU_CHUNK_T* p521r1_mul_montx(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE); +//BNU_CHUNK_T* p521r1_sqr_montx(BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE); +#endif + +#define p521r1_mred OWNAPI(p521r1_mred) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_mred, (BNU_CHUNK_T* res, BNU_CHUNK_T* product)) + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +#define p521r1_mul_mont_slm OWNAPI(p521r1_mul_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_mul_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +#define p521r1_sqr_mont_slm OWNAPI(p521r1_sqr_mont_slm) + IPP_OWN_DECL (BNU_CHUNK_T*, p521r1_sqr_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#endif + +#define OPERAND_BITSIZE (521) +#define LEN_P521 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* +// multiplicative methods +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, p521r1_mul_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpMul_BNU_school(product, pA,LEN_P521, pB,LEN_P521); + p521r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p521r1_sqr_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpSqr_BNU_school(product, pA,LEN_P521); + p521r1_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + + +/* +// Montgomery domain conversion constants +*/ +static BNU_CHUNK_T RR[] = { +#if(_IPP_ARCH == _IPP_ARCH_EM64T) + 0x0000000000000000,0x0000400000000000,0x0000000000000000, + 0x0000000000000000,0x0000000000000000,0x0000000000000000, + 0x0000000000000000,0x0000000000000000,0x0000000000000000}; +#elif(_IPP_ARCH == _IPP_ARCH_IA32) + 0x00000000,0x00004000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000}; +#endif + +static BNU_CHUNK_T one[] = { +#if(_IPP_ARCH == _IPP_ARCH_EM64T) + 1,0,0,0,0,0,0,0,0}; +#elif(_IPP_ARCH == _IPP_ARCH_IA32) + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +#endif + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p521r1_to_mont, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p521r1_mul_montl(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p521r1_mont_back, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p521r1_mul_montl(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} + +#if (_ADCOX_NI_ENABLING_==_FEATURE_ON_) || (_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_) +//BNU_CHUNK_T* p521r1_mul_montx(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE) +//BNU_CHUNK_T* p521r1_sqr_montx(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE) +#endif + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +IPP_OWN_DEFN (static BNU_CHUNK_T*, p521r1_to_mont_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p521r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, p521r1_mont_back_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return p521r1_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} +#endif /* _IPP_ARCH ==_IPP_ARCH_IA32*/ + +/* +// return specific gf p521r1 arith methods, +// p521r1 = 2^521 -1 (NIST P521r1) +*/ +static gsModMethod* gsArithGF_p521r1 (void) +{ + static gsModMethod m = { + p521r1_to_mont, + p521r1_mont_back, + p521r1_mul_montl, + p521r1_sqr_montl, + NULL, + p521r1_add, + p521r1_sub, + p521r1_neg, + p521r1_div_by_2, + p521r1_mul_by_2, + p521r1_mul_by_3, + }; + + #if(_IPP_ARCH==_IPP_ARCH_IA32) + if(IsFeatureEnabled(ippCPUID_SSSE3|ippCPUID_MOVBE) && !IsFeatureEnabled(ippCPUID_AVX)) { + m.mul = p521r1_mul_mont_slm; + m.sqr = p521r1_sqr_mont_slm; + m.encode = p521r1_to_mont_slm; + m.decode = p521r1_mont_back_slm; + } + #endif + + return &m; +} +#endif /* (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) */ + +/*F* +// Name: ippsGFpMethod_p521r1 +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). q = 2^521 - 1 +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_p521r1, (void) ) +{ + static IppsGFpMethod method = { + cpID_PrimeP521r1, + 521, + secp521r1_p, + NULL, + NULL + }; + +#if (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p521r1(); +#else + method.arith = gsArithGFp(); +#endif + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + method.arith_alt = gsArithGF_p521r1_avx512(); + } +#endif + + return &method; +} + +#undef LEN_P521 +#undef OPERAND_BITSIZE diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_com.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_com.c new file mode 100644 index 000000000..bb6693363 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_com.c @@ -0,0 +1,48 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owncp.h" + +#include "pcpgfpmethod.h" + +/*F* +// Name: ippsGFpMethod_pArb +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). Arbitrary modulus q. +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_pArb, (void) ) +{ + static IppsGFpMethod method = { + cpID_Prime, + 0, + NULL, + NULL, + NULL + }; + method.arith = gsArithGFp(); + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_sm2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_sm2.c new file mode 100644 index 000000000..fe2a9597b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmethod_sm2.c @@ -0,0 +1,219 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p) methods +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpbnumisc.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpmethod.h" +#include "pcpecprime.h" + +#if (_IPP32E >= _IPP32E_K1) +#include "sm2/ifma_arith_method_sm2.h" +#endif // (_IPP32E >= _IPP32E_K1) +//tbcd: temporary excluded: #include + +#if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + +/* arithmetic over 256-bit SM2 modulus */ +#define sm2_add OWNAPI(sm2_add) +#define sm2_sub OWNAPI(sm2_sub) +#define sm2_neg OWNAPI(sm2_neg) +#define sm2_div_by_2 OWNAPI(sm2_div_by_2) +#define sm2_mul_by_2 OWNAPI(sm2_mul_by_2) +#define sm2_mul_by_3 OWNAPI(sm2_mul_by_3) + +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_add, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_sub, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_neg, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_div_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_mul_by_2, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_mul_by_3, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) + +#if(_IPP_ARCH ==_IPP_ARCH_EM64T) +#define sm2_mul_montl OWNAPI(sm2_mul_montl) +#define sm2_mul_montx OWNAPI(sm2_mul_montx) +#define sm2_sqr_montl OWNAPI(sm2_sqr_montl) +#define sm2_sqr_montx OWNAPI(sm2_sqr_montx) +#define sm2_to_mont OWNAPI(sm2_to_mont) +#define sm2_mont_back OWNAPI(sm2_mont_back) + +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_mul_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_mul_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_sqr_montl, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_sqr_montx, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_to_mont, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_mont_back, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +#endif + +#if(_IPP_ARCH ==_IPP_ARCH_IA32) +#define sm2_mul_mont_slm OWNAPI(sm2_mul_mont_slm) +#define sm2_sqr_mont_slm OWNAPI(sm2_sqr_mont_slm) +#define sm2_mred OWNAPI(sm2_mred) + +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_mul_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, const BNU_CHUNK_T* b, gsEngine* pGFE)) +IPP_OWN_DECL (BNU_CHUNK_T*, sm2_sqr_mont_slm, (BNU_CHUNK_T* res, const BNU_CHUNK_T* a, gsEngine* pGFE)) +IPP_OWN_DECL (void, sm2_mred, (BNU_CHUNK_T* res, BNU_CHUNK_T* product)) +#endif + +#define OPERAND_BITSIZE (256) +#define LEN_SM2 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* +// ia32 multiplicative methods +*/ +#if (_IPP_ARCH ==_IPP_ARCH_IA32 ) +IPP_OWN_DEFN (static BNU_CHUNK_T*, sm2_mul_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpMulAdc_BNU_school(product, pA, LEN_SM2, pB, LEN_SM2); + sm2_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, sm2_sqr_montl, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + BNU_CHUNK_T* product = cpGFpGetPool(2, pGFE); + //tbcd: temporary excluded: assert(NULL!=product); + + cpSqrAdc_BNU_school(product, pA, LEN_SM2); + sm2_mred(pR, product); + + cpGFpReleasePool(2, pGFE); + return pR; +} + + +/* +// Montgomery domain conversion constants +*/ +static BNU_CHUNK_T RR[] = { + 0x00000003,0x00000002, 0xffffffff,0x00000002, + 0x00000001,0x00000001, 0x00000002,0x00000004}; + +static BNU_CHUNK_T one[] = { + 1,0,0,0,0,0,0,0}; + +IPP_OWN_DEFN (static BNU_CHUNK_T*, sm2_to_mont, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return sm2_mul_montl(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, sm2_mont_back, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return sm2_mul_montl(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, sm2_to_mont_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return sm2_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)RR, pGFE); +} + +IPP_OWN_DEFN (static BNU_CHUNK_T*, sm2_mont_back_slm, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFE)) +{ + return sm2_mul_mont_slm(pR, pA, (BNU_CHUNK_T*)one, pGFE); +} +#endif /* _IPP >= _IPP_P8 */ + +/* +// return specific gf p256sm2 arith methods, +// p256sm2 = 2^256 -2^224 -2^96 +2^64 -1 (SM2 curve) +*/ +static gsModMethod* gsArithGF_p256sm2 (void) +{ + static gsModMethod m = { + sm2_to_mont, + sm2_mont_back, + sm2_mul_montl, + sm2_sqr_montl, + NULL, + sm2_add, + sm2_sub, + sm2_neg, + sm2_div_by_2, + sm2_mul_by_2, + sm2_mul_by_3, + }; + + #if(_IPP_ARCH==_IPP_ARCH_EM64T) && ((_ADCOX_NI_ENABLING_==_FEATURE_ON_) || (_ADCOX_NI_ENABLING_==_FEATURE_TICKTOCK_)) + if(IsFeatureEnabled(ippCPUID_ADCOX)) { + m.mul = sm2_mul_montx; + m.sqr = sm2_sqr_montx; + } + #endif + + #if(_IPP_ARCH==_IPP_ARCH_IA32) + if(IsFeatureEnabled(ippCPUID_SSSE3|ippCPUID_MOVBE) && !IsFeatureEnabled(ippCPUID_AVX)) { + m.mul = sm2_mul_mont_slm; + m.sqr = sm2_sqr_mont_slm; + m.encode = sm2_to_mont_slm; + m.decode = sm2_mont_back_slm; + } + #endif + + return &m; +} +#endif /* (_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) */ + +/*F* +// Name: ippsGFpMethod_p256sm2 +// +// Purpose: Returns a reference to an implementation of +// arithmetic operations over GF(q). +// +// Returns: Pointer to a structure containing an implementation of arithmetic +// operations over GF(q). q = 2^256 - 2^224 - 2^96 + 2^64 - 1 +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpMethod_p256sm2, (void) ) +{ + static IppsGFpMethod method = { + cpID_PrimeTPM_SM2, + 256, + tpmSM2_p256_p, + NULL, + NULL + }; + +#if(_IPP >= _IPP_P8) || (_IPP32E >= _IPP32E_M7) + method.arith = gsArithGF_p256sm2(); +#else + method.arith = gsArithGFp(); +#endif + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + method.arith_alt = gsArithGF_psm2_avx512(); + } +#endif // (_IPP32E >= _IPP32E_K1) + + return &method; +} + +#undef LEN_SM2 +#undef OPERAND_BITSIZE diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmul.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmul.c new file mode 100644 index 000000000..0e3611d91 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmul.c @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpMul() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpMul +// +// Purpose: Multiply of GF elements +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// NULL == pB +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// invalid pB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pB Pointer to the context of the second finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpMul,(const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR4_RET(pA, pB, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pB)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->mul(GFPE_DATA(pR), GFPE_DATA(pA), GFPE_DATA(pB),pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpmulexp.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmulexp.c new file mode 100644 index 000000000..2f7c3bcb4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpmulexp.c @@ -0,0 +1,133 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpMultiExp() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +//tbcd: temporary excluded: #include + +/*F* +// Name: ippsGFpMultiExp +// +// Purpose: Multiplies exponents of GF elements +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == ppElmA +// NULL == pR +// NULL == ppE +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid ppElmA[i]->idCtx +// invalid pR->idCtx +// invalid ppE[i]->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsBadArgErr 1>nItems +// nItems>6 +// +// ippStsNoErr no error +// +// Parameters: +// ppElmA Pointer to the array of contexts of the finite field elements representing the base of the exponentiation. +// ppE Pointer to the array of the Big Number contexts storing the exponents. +// nItems Number of exponents. +// pR Pointer to the context of the resulting element of the finite field. +// pGFp Pointer to the context of the finite field. +// pScratchBuffer Pointer to the scratch buffer. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpMultiExp,(const IppsGFpElement* const ppElmA[], const IppsBigNumState* const ppE[], int nItems, + IppsGFpElement* pR, IppsGFpState* pGFp, + Ipp8u* pScratchBuffer)) +{ + IPP_BAD_PTR2_RET(ppElmA, ppE); + + if(nItems==1) + return ippsGFpExp(ppElmA[0], ppE[0], pR, pGFp, pScratchBuffer); + + else { + /* test number of exponents */ + IPP_BADARG_RET(1>nItems || nItems>IPP_MAX_EXPONENT_NUM, ippStsBadArgErr); + + IPP_BAD_PTR2_RET(pR, pGFp); + + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + int n; + + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFPE_ROOM(pR)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + /* test all ppElmA[] and ppE[] pairs */ + for(n=0; nmul; + + BNU_CHUNK_T* pTmpR = cpGFpGetPool(1, pGFE); + //tbcd: temporary excluded: assert(NULL!=pTmpR); + + cpGFpxExp(GFPE_DATA(pR), GFPE_DATA(ppElmA[0]), BN_NUMBER(ppE[0]), BN_SIZE(ppE[0]), pGFE, 0); + for(n=1; nidCtx +// invalid pA->idCtx +// invalid pR->idCtx +// invalid pParentB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsBadArgErr pGFp does not specify prime field +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pParentB Pointer to the context of the second finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpMul_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR4_RET(pA, pParentB, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pParentB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( (GFPE_ROOM(pParentB)!=GFP_FELEN(GFP_PARENT(pGFE))), ippStsOutOfRangeErr); + + cpGFpxMul_GFE(GFPE_DATA(pR), GFPE_DATA(pA), GFPE_DATA(pParentB), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpneg.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpneg.c new file mode 100644 index 000000000..0f0b8f900 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpneg.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpNeg() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpNeg +// +// Purpose: Additive inverse GF element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the source finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpNeg,(const IppsGFpElement* pA, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->neg(GFPE_DATA(pR), GFPE_DATA(pA), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelem.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelem.c new file mode 100644 index 000000000..7655242f8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelem.c @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSetElement() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +//tbcd: temporary excluded: #include + +/*F* +// Name: ippsGFpSetElement +// +// Purpose: Set GF Element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pR +// NULL == pA && lenA>0 +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pR->idCtx +// +// ippStsSizeErr pA && !(0<=lenA && lenA= modulus +// +// ippStsNoErr no error +// +// Parameters: +// pA pointer to the data representation Finite Field element +// lenA length of Finite Field data representation array +// pR pointer to Finite Field Element context +// pGFp pointer to Finite Field context +*F*/ +IPPFUN(IppStatus, ippsGFpSetElement,(const Ipp32u* pA, int lenA, IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR2_RET(pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + + IPP_BADARG_RET( !pA && (00 +// +// ippStsNotSupportedModeErr hashID is not supported +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pElm->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsBadArgErr !GFP_IS_BASIC(pGFE) +// +// ippStsLengthErr msgLen<0 +// +// ippStsNoErr no error +// +// Parameters: +// pMsg pointer to the message is being hashed +// msgLen length of the message above +// pElm pointer to Finite Field Element context +// pGFp pointer to Finite Field context +// hashID applied hash algorithm ID +*F*/ +IPPFUN(IppStatus, ippsGFpSetElementHash,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGFp, IppHashAlgId hashID)) +{ + /* get algorithm id */ + hashID = cpValidHashAlg(hashID); + IPP_BADARG_RET(ippHashAlg_Unknown==hashID, ippStsNotSupportedModeErr); + + /* test message length and pointer */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR2_RET(pElm, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr); + IPP_BADARG_RET( !GFPE_VALID_ID(pElm), ippStsContextMatchErr); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + Ipp8u md[MAX_HASH_SIZE]; + BNU_CHUNK_T hashVal[(MAX_HASH_SIZE*8)/BITSIZE(BNU_CHUNK_T)+1]; /* +1 to meet cpMod_BNU() implementtaion specific */ + IppStatus sts = ippsHashMessage(pMsg, msgLen, md, hashID); + + if(ippStsNoErr==sts) { + int elemLen = GFP_FELEN(pGFE); + int hashLen = cpHashAlgAttr[hashID].hashSize; + int hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, GFP_MODULUS(pGFE), elemLen); + cpGFpSet(GFPE_DATA(pElm), hashVal, hashValLen, pGFE); + } + + return sts; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemhashrmf.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemhashrmf.c new file mode 100644 index 000000000..0c43ca719 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemhashrmf.c @@ -0,0 +1,99 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSetElementHash_rmf +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpSetElementHash_rmf +// +// Purpose: Set GF Element Hash of the Message +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pElm +// NULL == pMsg if msgLen>0 +// NULL = pMethod +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pElm->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsBadArgErr !GFP_IS_BASIC(pGFE) +// +// ippStsLengthErr msgLen<0 +// +// ippStsNoErr no error +// +// Parameters: +// pMsg pointer to the message is being hashed +// msgLen length of the message above +// pElm pointer to Finite Field Element context +// pGFp pointer to Finite Field context +// pMethod pointer to hash method +*F*/ + +IPPFUN(IppStatus, ippsGFpSetElementHash_rmf,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGFp, const IppsHashMethod* pMethod)) +{ + /* test method pointer */ + IPP_BAD_PTR1_RET(pMethod); + + /* test message length and pointer */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR2_RET(pElm, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr); + IPP_BADARG_RET( !GFPE_VALID_ID(pElm), ippStsContextMatchErr); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + Ipp8u md[MAX_HASH_SIZE]; + BNU_CHUNK_T hashVal[(MAX_HASH_SIZE*8)/BITSIZE(BNU_CHUNK_T)+1]; /* +1 to meet cpMod_BNU() implementtaion specific */ + IppStatus sts = ippsHashMessage_rmf(pMsg, msgLen, md, pMethod); + + if(ippStsNoErr==sts) { + int elemLen = GFP_FELEN(pGFE); + int hashLen = pMethod->hashLen; + int hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, GFP_MODULUS(pGFE), elemLen); + cpGFpSet(GFPE_DATA(pElm), hashVal, hashValLen, pGFE); + } + + return sts; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemoctstr.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemoctstr.c new file mode 100644 index 000000000..2b737cf7a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemoctstr.c @@ -0,0 +1,96 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSetElementOctString() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpSetElementOctString +// +// Purpose: Set GF Element from the input octet string +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pR +// NULL == pStr && strSize>0 +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pR->idCtx +// +// ippStsSizeErr !(0= modulus +// +// ippStsNoErr no error +// +// Parameters: +// pStr Pointer to the octet string +// strSize Size of the octet string buffer in bytes. +// pR pointer to Finite Field Element context +// pGFp pointer to Finite Field context +*F*/ +IPPFUN(IppStatus, ippsGFpSetElementOctString,(const Ipp8u* pStr, int strSize, IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR2_RET(pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + + IPP_BADARG_RET( (!pStr && 0idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsErr internal error caused by call of rndFunc() +// +// ippStsNoErr no error +// +// Parameters: +// pR Pointer to the context of the finite field element. +// pGFp Pointer to the context of the finite field. +// rndFunc Pseudorandom number generator. +// pRndParam Pointer to the context of the pseudorandom number generator. +*F*/ +IPPFUN(IppStatus, ippsGFpSetElementRandom,(IppsGFpElement* pR, IppsGFpState* pGFp, + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR3_RET(pR, pGFp, rndFunc); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFPE_ROOM(pR)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + return cpGFpxRand(GFPE_DATA(pR), pGFE, rndFunc, pRndParam)? ippStsNoErr : ippStsErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemreg.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemreg.c new file mode 100644 index 000000000..10bcc5ea9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsetelemreg.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSetElementRegular() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/*F* +// Name: ippsGFpSetElement +// +// Purpose: Set GF Element from the input Big Number +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pR +// NULL == pBN +// +// ippStsContextMatchErr invalid pBN->idCtx +// +// ippStsOutOfRangeErr BN is not positive +// +// ippStsNoErr no error +// +// Parameters: +// pBN pointer to the Big Number context +// pR pointer to Finite Field Element context +// pGFp pointer to Finite Field context +*F*/ + +IPPFUN(IppStatus, ippsGFpSetElementRegular,(const IppsBigNumState* pBN, IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR1_RET(pBN); + IPP_BADARG_RET( !BN_VALID_ID(pBN), ippStsContextMatchErr ); + IPP_BADARG_RET( !BN_POSITIVE(pBN), ippStsOutOfRangeErr); + + return ippsGFpSetElement((Ipp32u*)BN_NUMBER(pBN), BITS2WORD32_SIZE( BITSIZE_BNU(BN_NUMBER((pBN)),BN_SIZE((pBN)))), pR, pGFp); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsqr.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsqr.c new file mode 100644 index 000000000..408c508f0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsqr.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSqr() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsGFpSqr +// +// Purpose: Square of GF element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the source finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpSqr,(const IppsGFpElement* pA, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->sqr(GFPE_DATA(pR), GFPE_DATA(pA), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsqrt.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsqrt.c new file mode 100644 index 000000000..e9f9661fb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsqrt.c @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSqrt() +// +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +/*F* +// Name: ippsGFpSqrt +// +// Purpose: Square root of GF element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsDivByZeroErr pA is zero +// +// ippStsBadArgErr pGFp is not prime +// +// ippStsQuadraticNonResidueErr pA is a square non-residue +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the source finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpSqrt,(const IppsGFpElement* pA, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR3_RET(pA, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + return cpGFpSqrt(GFPE_DATA(pR), GFPE_DATA(pA), pGFE)? ippStsNoErr : ippStsQuadraticNonResidueErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpstuff.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpstuff.h new file mode 100644 index 000000000..f15f350c1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpstuff.h @@ -0,0 +1,210 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives +// Internal GF(p) basic Definitions & Function Prototypes +// +*/ + +#if !defined(_PCP_GFP_H_) +#define _PCP_GFP_H_ + +#include "owncp.h" +#include "pcpgfpmethod.h" +#include "pcpmontgomery.h" +#include "pcpmask_ct.h" + +/* GF element */ +typedef struct _cpGFpElement { + Ipp32u idCtx; /* GF() element ident */ + int length; /* length of element (in BNU_CHUNK_T) */ + BNU_CHUNK_T* pData; +} cpGFpElement; + +#define GFPE_SET_ID(pCtx) ((pCtx)->idCtx = (Ipp32u)idCtxGFPE ^ (Ipp32u)IPP_UINT_PTR(pCtx)) +#define GFPE_ROOM(pCtx) ((pCtx)->length) +#define GFPE_DATA(pCtx) ((pCtx)->pData) + +#define GFPE_VALID_ID(pCtx) ((((pCtx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR(pCtx)) == idCtxGFPE) + + +/* GF(p) context */ +typedef struct _cpGFp { + Ipp32u idCtx; /* GFp spec ident */ + cpModulusID modulusID; + gsModEngine* pGFE; /* arithmethic engine */ +} cpGFp; + +#define GFP_ALIGNMENT ((int)(sizeof(void*))) + +/* Local definitions */ +#define GFP_MAX_BITSIZE (IPP_MAX_GF_BITSIZE) /* max bitsize for GF element */ +#define GFP_POOL_SIZE (16)//(IPP_MAX_EXPONENT_NUM+3) /* num of elements into the pool */ +#define GFP_RAND_ADD_BITS (128) /* parameter of random element generation ?? == febits/2 */ + +#define GFP_SET_ID(pCtx) ((pCtx)->idCtx = (Ipp32u)idCtxGFP ^ (Ipp32u)IPP_UINT_PTR(pCtx)) +#define GFP_PMA(pCtx) ((pCtx)->pGFE) + +#define GFP_PARENT(pCtx) MOD_PARENT((pCtx)) +#define GFP_EXTDEGREE(pCtx) MOD_EXTDEG((pCtx)) +#define GFP_FEBITLEN(pCtx) MOD_BITSIZE((pCtx)) +#define GFP_FELEN(pCtx) MOD_LEN((pCtx)) +#define GFP_FELEN32(pCtx) MOD_LEN32((pCtx)) +#define GFP_PELEN(pCtx) MOD_PELEN((pCtx)) +#define GFP_METHOD(pCtx) MOD_METHOD((pCtx)) +#define GFP_METHOD_ALT(pCtx) MOD_METHOD_ALT((pCtx)) +#define GFP_MODULUS(pCtx) MOD_MODULUS((pCtx)) +#define GFP_MNT_FACTOR(pCtx) MOD_MNT_FACTOR((pCtx)) +#define GFP_MNT_R(pCtx) MOD_MNT_R((pCtx)) +#define GFP_MNT_RR(pCtx) MOD_MNT_R2((pCtx)) +#define GFP_HMODULUS(pCtx) MOD_HMODULUS((pCtx)) +#define GFP_QNR(pCtx) MOD_QNR((pCtx)) +#define GFP_POOL(pCtx) MOD_POOL_BUF((pCtx)) +#define GFP_MAXPOOL(pCtx) MOD_MAXPOOL((pCtx)) +#define GFP_USEDPOOL(pCtx) MOD_USEDPOOL((pCtx)) + +#define GFP_IS_BASIC(pCtx) (GFP_PARENT((pCtx))==NULL) +#define GFP_VALID_ID(pCtx) ((((pCtx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR(pCtx)) == idCtxGFP) + +/* +// get/release n element from/to the pool +*/ +#define cpGFpGetPool(n, gfe) gsModPoolAlloc((gfe), (n)) +#define cpGFpReleasePool(n, gfe) gsModPoolFree((gfe), (n)) + + +__INLINE int cpGFpElementLen(const BNU_CHUNK_T* pE, int nsE) +{ + for(; nsE>1 && 0==pE[nsE-1]; nsE--) ; + return nsE; +} +__INLINE BNU_CHUNK_T* cpGFpElementCopy(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pE, int nsE) +{ + int n; + for(n=0; nadd(pR, pA, pB, pGFE); +} + +__INLINE BNU_CHUNK_T* cpGFpSub(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsModEngine* pGFE) +{ + return GFP_METHOD(pGFE)->sub(pR, pA, pB, pGFE); +} + +__INLINE BNU_CHUNK_T* cpGFpNeg(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFE) +{ + return GFP_METHOD(pGFE)->neg(pR, pA, pGFE); +} + +__INLINE BNU_CHUNK_T* cpGFpMul(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsModEngine* pGFE) +{ + return GFP_METHOD(pGFE)->mul(pR, pA, pB, pGFE); +} + +__INLINE BNU_CHUNK_T* cpGFpSqr(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFE) +{ + return GFP_METHOD(pGFE)->sqr(pR, pA, pGFE); +} + +__INLINE BNU_CHUNK_T* cpGFpHalve(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFE) +{ + return GFP_METHOD(pGFE)->div2(pR, pA, pGFE); +} + + +#define GFP_EQ(a,b,size) (0 == cpCmp_BNU((a), (size), (b), (size))) + +#define GFP_IS_ZERO(a,size) cpGFpElementIsEquChunk((a),(size), 0) +#define GFP_IS_ONE(a,size) cpGFpElementIsEquChunk((a),(size), 1) + +#define GFP_ZERO(a,size) cpGFpElementSetChunk((a),(size), 0) +#define GFP_ONE(a,size) cpGFpElementSetChunk((a),(size), 1) + + +/* construct GF element */ +__INLINE IppsGFpElement* cpGFpElementConstruct(IppsGFpElement* pR, BNU_CHUNK_T* pDataBufer, int ns) +{ + GFPE_SET_ID(pR); + GFPE_ROOM(pR) = ns; + GFPE_DATA(pR) = pDataBufer; + return pR; +} + + +/* size of GFp context, init and setup */ +#define cpGFpGetSize OWNAPI(cpGFpGetSize) + IPP_OWN_DECL (int, cpGFpGetSize, (int feBitSize, int peBitSize, int numpe)) +#define cpGFpInitGFp OWNAPI(cpGFpInitGFp) + IPP_OWN_DECL (IppStatus, cpGFpInitGFp, (int primeBitSize, IppsGFpState* pGF)) +#define cpGFpSetGFp OWNAPI(cpGFpSetGFp) + IPP_OWN_DECL (IppStatus, cpGFpSetGFp, (const BNU_CHUNK_T* pPrime, int primeBitSize, const IppsGFpMethod* method, IppsGFpState* pGF)) + +/* operations */ +#define cpGFpRand OWNAPI(cpGFpRand) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpRand, (BNU_CHUNK_T* pR, gsModEngine* pGFE, IppBitSupplier rndFunc, void* pRndParam)) +#define cpGFpSet OWNAPI(cpGFpSet) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpSet, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pDataA, int nsA, gsModEngine* pGFE)) +#define cpGFpGet OWNAPI(cpGFpGet) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpGet, (BNU_CHUNK_T* pDataA, int nsA, const BNU_CHUNK_T* pR, gsModEngine* pGFE)) +#define cpGFpSetOctString OWNAPI(cpGFpSetOctString) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpSetOctString, (BNU_CHUNK_T* pR, const Ipp8u* pStr, int strSize, gsModEngine* pGFE)) +#define cpGFpGetOctString OWNAPI(cpGFpGetOctString) + IPP_OWN_DECL (Ipp8u*, cpGFpGetOctString, (Ipp8u* pStr, int strSize, const BNU_CHUNK_T* pA, gsModEngine* pGFE)) +#define cpGFpInv OWNAPI(cpGFpInv) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpInv, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFE)) +#define cpGFpExp OWNAPI(cpGFpExp) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpExp, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pE, int nsE, gsModEngine* pGFE)) +#define cpGFpSqrt OWNAPI(cpGFpSqrt) + IPP_OWN_DECL (int, cpGFpSqrt, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFE)) +#define cpGFEqnr OWNAPI(cpGFEqnr) + IPP_OWN_DECL (void, cpGFEqnr, (gsModEngine* pGFE)) + +#endif /* _PCP_GFP_H_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsub.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsub.c new file mode 100644 index 000000000..c3aeb2b88 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsub.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSub() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +/*F* +// Name: ippsGFpSub +// +// Purpose: Subtract of GF elements +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// NULL == pB +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// invalid pB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pB Pointer to the context of the second finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpSub,(const IppsGFpElement* pA, const IppsGFpElement* pB, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR4_RET(pA, pB, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pB)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->sub(GFPE_DATA(pR), GFPE_DATA(pA), GFPE_DATA(pB), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpsubpe.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsubpe.c new file mode 100644 index 000000000..e8aa3e911 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpsubpe.c @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpSub_PE() +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +/*F* +// Name: ippsGFpSub_PE +// +// Purpose: Subtract of GF element and parent GF element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFp +// NULL == pA +// NULL == pR +// NULL == pParentB +// +// ippStsContextMatchErr invalid pGFp->idCtx +// invalid pA->idCtx +// invalid pR->idCtx +// invalid pParentB->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsBadArgErr pGFp does not specify prime field +// +// ippStsNoErr no error +// +// Parameters: +// pA Pointer to the context of the first finite field element. +// pParentB Pointer to the context of the second finite field element. +// pR Pointer to the context of the result finite field element. +// pGFp Pointer to the context of the finite field. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpSub_PE,(const IppsGFpElement* pA, const IppsGFpElement* pParentB, + IppsGFpElement* pR, IppsGFpState* pGFp)) +{ + IPP_BAD_PTR4_RET(pA, pParentB, pR, pGFp); + IPP_BADARG_RET( !GFP_VALID_ID(pGFp), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pParentB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_VALID_ID(pR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGFp); + IPP_BADARG_RET( GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( (GFPE_ROOM(pParentB)!=GFP_FELEN(GFP_PARENT(pGFE))), ippStsOutOfRangeErr); + + cpGFpxSub_GFE(GFPE_DATA(pR), GFPE_DATA(pA), GFPE_DATA(pParentB), pGFE); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx.c new file mode 100644 index 000000000..6beddf471 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p) ectension. +// +// Context: +// pcpgfpec_initgfpxctx.c() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + +/* the "static" specificator removed because of incorrect result under Linux-32, p8 + what's wrong? not know maybe compiler (icl 2017) + need to check after switchng on icl 2018 + */ +/*static*/ +IPP_OWN_DEFN (void, InitGFpxCtx, (const IppsGFpState* pGroundGF, int extDeg, const IppsGFpMethod* method, IppsGFpState* pGFpx)) +{ + gsModEngine* pGFEp = GFP_PMA(pGroundGF); + int elemLen = extDeg * GFP_FELEN(pGFEp); + int elemLen32 = extDeg * GFP_FELEN32(pGFEp); + + Ipp8u* ptr = (Ipp8u*)pGFpx + sizeof(IppsGFpState); + + /* context identifier */ + GFP_SET_ID(pGFpx); + GFP_PMA(pGFpx) = (gsModEngine*)ptr; + { + gsModEngine* pGFEx = GFP_PMA(pGFpx); + + /* clear whole context */ + PadBlock(0, ptr, sizeof(gsModEngine)); + ptr += sizeof(gsModEngine); + + GFP_PARENT(pGFEx) = pGFEp; + GFP_EXTDEGREE(pGFEx) = extDeg; + GFP_FEBITLEN(pGFEx) = 0;//elemBitLen; + GFP_FELEN(pGFEx) = elemLen; + GFP_FELEN32(pGFEx) = elemLen32; + GFP_PELEN(pGFEx) = elemLen; + GFP_METHOD(pGFEx) = method->arith; + GFP_MODULUS(pGFEx) = (BNU_CHUNK_T*)(ptr); ptr += elemLen * (Ipp32s)sizeof(BNU_CHUNK_T); /* field polynomial */ + GFP_POOL(pGFEx) = (BNU_CHUNK_T*)(ptr); /* pool */ + GFP_MAXPOOL(pGFEx) = GFPX_POOL_SIZE; + GFP_USEDPOOL(pGFEx) = 0; + + cpGFpElementPad(GFP_MODULUS(pGFEx), elemLen, 0); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_add_gfe.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_add_gfe.c new file mode 100644 index 000000000..c03407f82 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_add_gfe.c @@ -0,0 +1,43 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxAdd_GFE() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxAdd_GFE, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pGroundB, gsModEngine* pGFEx)) +{ + gsModEngine* pGroundGFE = GFP_PARENT(pGFEx); + mod_add addF = MOD_METHOD(pGroundGFE)->add; + + if(pR != pA) { + int groundElemLen = GFP_FELEN(pGroundGFE); + int deg = GFP_EXTDEGREE(pGFEx); + cpGFpElementCopy(pR+groundElemLen, pA+groundElemLen, groundElemLen*(deg-1)); + } + return addF(pR, pA, pGroundB, pGroundGFE); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_conj.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_conj.c new file mode 100644 index 000000000..2ebe7f6ed --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_conj.c @@ -0,0 +1,42 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxConj() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxConj, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFEx)) +{ + gsModEngine* pGroundGFE = GFP_PARENT(pGFEx); + int groundElemLen = GFP_FELEN(pGroundGFE); + + if(pR != pA) + cpGFpElementCopy(pR, pA, groundElemLen); + MOD_METHOD(pGroundGFE)->neg(pR+groundElemLen, pA+groundElemLen, pGroundGFE); + + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_exp.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_exp.c new file mode 100644 index 000000000..1357616ab --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_exp.c @@ -0,0 +1,142 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxExp() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +//tbcd: temporary excluded: #include + +static int div_upper(int a, int d) +{ return (a+d-1)/d; } + +/* sscm version */ +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxExp, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pE, int nsE, gsModEngine* pGFEx, Ipp8u* pScratchBuffer)) +{ + gsModEngine* pBasicGFE = cpGFpBasic(pGFEx); + + /* remove leding zeros */ + /* gres 06/10/2019: FIX_BNU(pE, nsE); */ + + { + mod_mul mulF = GFP_METHOD(pGFEx)->mul; /* mul and sqr methods */ + mod_sqr sqrF = GFP_METHOD(pGFEx)->sqr; + + BNU_CHUNK_T* pScratchAligned; /* aligned scratch buffer */ + int nAllocation = 0; /* points from the pool */ + + /* size of element */ + int elmLen = GFP_FELEN(pGFEx); + + /* exponent bitsize */ + int expBitSize = nsE * BNU_CHUNK_BITS; /* gres 06/102019: BITSIZE_BNU(pE, nsE); */ + /* optimal size of window */ + int w = (NULL==pScratchBuffer)? 1 : cpGFpGetOptimalWinSize(expBitSize); + /* number of table entries */ + int nPrecomputed = 1<>shift) & dmask; + + /* initialize result */ + //cpScrambleGet((Ipp8u*)pR, elmDataSize, pScratchAligned+windowVal, nPrecomputed); + gsScrambleGet_sscm(pR, elmLen, pScratchAligned, (Ipp32s)windowVal, w); + + for(wPosition-=w; wPosition>=0; wPosition-=w) { + int k; + /* w times squaring */ + for(k=0; k>shift) & dmask; + + /* extract value from the pre-computed table */ + //cpScrambleGet((Ipp8u*)pTmp, elmDataSize, pScratchAligned+windowVal, nPrecomputed); + gsScrambleGet_sscm(pTmp, elmLen, pScratchAligned, (Ipp32s)windowVal, w); + + /* and multiply */ + mulF(pR, pR, pTmp, pGFEx); + } + } + + } + + cpGFpReleasePool(nAllocation+2, pGFEx); + + return pR; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_get.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_get.c new file mode 100644 index 000000000..1aacdf9e9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_get.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxGet() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxGet, (BNU_CHUNK_T* pDataA, int nsA, const BNU_CHUNK_T* pE, gsModEngine* pGFEx)) +{ + cpGFpElementPad(pDataA, nsA, 0); + + if( GFP_IS_BASIC(pGFEx) ) + return cpGFpGet(pDataA, nsA, pE, pGFEx); + + else { + gsModEngine* pBasicGFE = cpGFpBasic(pGFEx); + int basicElemLen = GFP_FELEN(pBasicGFE); + + BNU_CHUNK_T* pTmp = pDataA; + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + int deg; + for(deg=0; deg0; deg++) { + int pieceA = IPP_MIN(nsA, basicElemLen); + + cpGFpGet(pTmp, pieceA, pE, pBasicGFE); + pE += basicElemLen; + pTmp += pieceA; + nsA -= pieceA; + } + + return pDataA; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_getpolyterm.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_getpolyterm.c new file mode 100644 index 000000000..2dc972a88 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_getpolyterm.c @@ -0,0 +1,36 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxGetPolyTerm() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxGetPolyTerm, (BNU_CHUNK_T* pDataA, int nsA, const BNU_CHUNK_T* pE, int deg, gsModEngine* pGFEx)) +{ + pE += deg * GFP_FELEN(pGFEx); + return cpGFpxGet(pDataA, nsA, pE, pGFEx); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_inv.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_inv.c new file mode 100644 index 000000000..927dd1dcc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_inv.c @@ -0,0 +1,223 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxInv() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +//tbcd: temporary excluded: #include + +static BNU_CHUNK_T* gfpxPolyDiv(BNU_CHUNK_T* pQ, BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, + const BNU_CHUNK_T* pB, + gsModEngine* pGFEx) +{ + if( GFP_IS_BASIC(pGFEx) ) + return NULL; + + else { + int elemLen = GFP_FELEN(pGFEx); + gsModEngine* pGroundGFE = GFP_PARENT(pGFEx); + int termLen = GFP_FELEN(pGroundGFE); + + int degA = degree(pA, pGFEx); + int degB = degree(pB, pGFEx); + + if(degB==0) { + if( GFP_IS_ZERO(pB, termLen) ) + return NULL; + else { + gsModEngine* pBasicGFE = cpGFpBasic(pGroundGFE); + + cpGFpInv(pR, pB, pBasicGFE); + cpGFpElementPad(pR+GFP_FELEN(pGroundGFE), termLen-GFP_FELEN(pGroundGFE), 0); + cpGFpxMul_GFE(pQ, pA, pR, pGFEx); + cpGFpElementPad(pR, elemLen, 0); + return pR; + } + } + + if(degA < degB) { + cpGFpElementPad(pQ, elemLen, 0); + cpGFpElementCopyPad(pR, elemLen, pA, (degA+1)*termLen); + return pR; + } + + else { + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + int i, j; + BNU_CHUNK_T* pProduct = cpGFpGetPool(2, pGroundGFE); + BNU_CHUNK_T* pInvB = pProduct + GFP_PELEN(pGroundGFE); + //tbcd: temporary excluded: assert(NULL!=pProduct); + + cpGFpElementCopyPad(pR, elemLen, pA, (degA+1)*termLen); + cpGFpElementPad(pQ, elemLen, 0); + + cpGFpxInv(pInvB, GFPX_IDX_ELEMENT(pB, degB, termLen), pGroundGFE); + + for(i=0; i<=degA-degB && !GFP_IS_ZERO(GFPX_IDX_ELEMENT(pR, degA-i, termLen), termLen); i++) { + /* compute q term */ + mulF(GFPX_IDX_ELEMENT(pQ, degA-degB-i, termLen), + GFPX_IDX_ELEMENT(pR, degA-i, termLen), + pInvB, + pGroundGFE); + + /* R -= B * q */ + cpGFpElementPad(GFPX_IDX_ELEMENT(pR, degA-i, termLen), termLen, 0); + for(j=0; jmul; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + int termLen = GFP_FELEN(pGroundGFE); + + BNU_CHUNK_T* pInvB = cpGFpGetPool(2, pGroundGFE); + BNU_CHUNK_T* pTmp = pInvB + GFP_PELEN(pGroundGFE); + + int degB = degree(pB, pGFEx); + int i; + + //tbcd: temporary excluded: assert(NULL!=pInvB); + + cpGFpElementCopy(pR, GFP_MODULUS(pGFEx), elemLen); + cpGFpElementPad(pQ, elemLen, 0); + + cpGFpxInv(pInvB, GFPX_IDX_ELEMENT(pB, degB, termLen), pGroundGFE); + + for(i=0; i 0) { + gfpxPolyDiv(quo, temp, lastrem, rem, pGFEx); + SWAP_PTR(BNU_CHUNK_T, rem, lastrem); // + SWAP_PTR(BNU_CHUNK_T, temp, rem); + + GFP_METHOD(pGFEx)->neg(quo, quo, pGFEx); + GFP_METHOD(pGFEx)->mul(temp, quo, aux, pGFEx); + GFP_METHOD(pGFEx)->add(temp, lastaux, temp, pGFEx); + SWAP_PTR(BNU_CHUNK_T, aux, lastaux); + SWAP_PTR(BNU_CHUNK_T, temp, aux); + } + if (GFP_IS_ZERO(rem, elemLen)) { /* gcd != 1 */ + cpGFpReleasePool(pxVars, pGFEx); + return NULL; + } + + { + BNU_CHUNK_T* invRem = cpGFpGetPool(1, pGroundGFE); + //tbcd: temporary excluded: assert(NULL!=invRem); + + cpGFpxInv(invRem, rem, pGroundGFE); + cpGFpxMul_GFE(pR, aux, invRem, pGFEx); + + cpGFpReleasePool(1, pGroundGFE); + } + + cpGFpReleasePool(pxVars, pGFEx); + + return pR; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_mul_gfe.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_mul_gfe.c new file mode 100644 index 000000000..e14798677 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_mul_gfe.c @@ -0,0 +1,48 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxMul_GFE() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxMul_GFE, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pGroundB, gsModEngine* pGFEx)) +{ + gsModEngine* pGroundGFE = GFP_PARENT(pGFEx); + mod_mul mulF = MOD_METHOD(pGroundGFE)->mul; + + int grounfElemLen = GFP_FELEN(pGroundGFE); + + BNU_CHUNK_T* pTmp = pR; + + int deg; + for(deg=0; deg + +static int GetIndex(const BNU_CHUNK_T* ppE[], int nItems, int nBit) +{ + int shift = nBit%BYTESIZE; + int offset= nBit/BYTESIZE; + int index = 0; + + int n; + for(n=nItems; n>0; n--) { + const Ipp8u* pE = ((Ipp8u*)ppE[n-1]) + offset; + Ipp8u e = pE[0]; + index <<= 1; + index += (e>>shift) &1; + } + return index; +} + + +static void cpPrecomputeMultiExp(BNU_CHUNK_T* pTable, const BNU_CHUNK_T* ppA[], int nItems, gsModEngine* pGFEx) +{ + gsModEngine* pBasicGFE = cpGFpBasic(pGFEx); + + //int nPrecomputed = 1<mul; /* mul method */ + + int i, baseIdx; + for(i=1, baseIdx=2; i=0; k--) { + int tblIdx = baseIdx; + + int n; + for(n=0; nmul; /* mul and sqr methods and parameter */ + mod_sqr sqrF = GFP_METHOD(pGFEx)->sqr; + int elmLen = GFP_FELEN(pGFEx); + + /* find out the longest exponent */ + int expBitSize = cpGetMaxBitsizeExponent(ppE, nsE, nItems); + + /* allocate resource and copy expanded exponents into */ + const BNU_CHUNK_T* ppExponent[IPP_MAX_EXPONENT_NUM]; + { + int n; + for(n=0; n=0; expBitSize--) { + sqrF(pR, pR, pGFEx); + tblIdx = GetIndex(ppExponent, nItems, expBitSize); + //cpScrambleGet((Ipp8u*)pT, elmDataSize, pScratchBuffer+tblIdx, nPrecomputed); + gsScrambleGet_sscm(pT, elmLen, pTable, tblIdx, nItems); + mulF(pR, pR, pT, pGFEx); + } + + /* release resourse */ + cpGFpReleasePool(1, pGFEx); + } + + /* release resourse */ + cpGFpReleasePool(nItems, pGFEx); + + return pR; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_neg.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_neg.c new file mode 100644 index 000000000..5e4f8fa0a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_neg.c @@ -0,0 +1,46 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxNeg() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxNeg, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsModEngine* pGFEx)) +{ + gsModEngine* pBasicGFE = cpGFpBasic(pGFEx); + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; degneg(pTmp, pA, pBasicGFE); + pTmp += basicElemLen; + pA += basicElemLen; + } + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_rand.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_rand.c new file mode 100644 index 000000000..397b1bf7b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpx_rand.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Internal operations over GF(p) extension. +// +// Context: +// cpGFpxRand() +// +*/ + +#include "owncp.h" +#include "pcpbnumisc.h" +#include "pcpgfpxstuff.h" +#include "gsscramble.h" + + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxRand, (BNU_CHUNK_T* pR, gsModEngine* pGFEx, IppBitSupplier rndFunc, void* pRndParam)) +{ + if( GFP_IS_BASIC(pGFEx) ) + return cpGFpRand(pR, pGFEx, rndFunc, pRndParam); + + else { + gsModEngine* pBasicGFE = cpGFpBasic(pGFEx); + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; degsub; + + if(pR != pA) { + int groundElemLen = GFP_FELEN(pGroundGFE); + int deg = GFP_EXTDEGREE(pGFEx); + cpGFpElementCopy(pR+groundElemLen, pA+groundElemLen, groundElemLen*(deg-1)); + } + return subF(pR, pA, pGroundB, pGroundGFE); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxgetsize.c new file mode 100644 index 000000000..4ede120fb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxgetsize.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p) ectension. +// +// Context: +// pcpgfpxgetsize.c() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + +/* Get context size */ +static int cpGFExGetSize(int elemLen, int pelmLen, int numpe) +{ + int ctxSize = 0; + + /* size of GFp engine */ + ctxSize = (Ipp32s)sizeof(gsModEngine) + + elemLen*(Ipp32s)sizeof(BNU_CHUNK_T) /* modulus */ + + pelmLen*(Ipp32s)sizeof(BNU_CHUNK_T)*numpe; /* pool */ + + ctxSize = (Ipp32s)sizeof(IppsGFpState) /* size of IppsGFPState*/ + + ctxSize; /* GFpx engine */ + return ctxSize; +} + +/*F* +// Name: ippsGFpxGetSize +// +// Purpose: Gets the size of the context of a GF(p^d) field. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL. +// ippStsContextMatchErr !GFP_VALID_ID(pGroundGF) +// ippStsBadArgErr degree is greater than or equal to 9 or is less than 2. +// ippStsNoErr no error +// +// Parameters: +// pGroundGF Pointer to the context of the finite field GF(p) being extended. +// degree Degree of the extension. +// pSize Pointer to the buffer size, in bytes, needed for the IppsGFpState +// context. +// +*F*/ + +IPPFUN(IppStatus, ippsGFpxGetSize, (const IppsGFpState* pGroundGF, int degree, int* pSize)) +{ + IPP_BAD_PTR2_RET(pGroundGF, pSize); + IPP_BADARG_RET( degreeIPP_MAX_GF_EXTDEG, ippStsBadArgErr); + IPP_BADARG_RET( !GFP_VALID_ID(pGroundGF), ippStsContextMatchErr ); + + #define MAX_GFx_SIZE (1<<15) /* max size (bytes) of GF element (32KB) */ + { + int groundElmLen = GFP_FELEN(GFP_PMA(pGroundGF)); + Ipp64u elmLen64 = (Ipp64u)groundElmLen * (Ipp64u)sizeof(BNU_CHUNK_T) * (Ipp64u)degree; + int elemLen = (int)IPP_LODWORD(elmLen64); + *pSize = 0; + IPP_BADARG_RET(elmLen64> MAX_GFx_SIZE, ippStsBadArgErr); + + *pSize = cpGFExGetSize(elemLen, elemLen, GFPX_POOL_SIZE); + return ippStsNoErr; + } + #undef MAX_GFx_SIZE +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxinit.c new file mode 100644 index 000000000..515f868af --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxinit.c @@ -0,0 +1,108 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// Operations over GF(p) ectension. +// +// Context: +// pcpgfpxinit.c() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcptool.h" + + + +/*F* +// Name: ippsGFpxInit +// +// Purpose: initializes finite field extension GF(p^d) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGFpx +// NULL == pGroundGF +// NULL == ppGroundElm +// NULL == pGFpMethod +// +// ippStsContextMatchErr incorrect pGroundGF's context ID +// incorrect ppGroundElm[i]'s context ID +// +// ippStsOutOfRangeErr size of ppGroundElm[i] does not equal to size of pGroundGF element +// +// ippStsBadArgErr IPP_MIN_GF_EXTDEG > extDeg || extDeg > IPP_MAX_GF_EXTDEG +// (IPP_MIN_GF_EXTDEG==2, IPP_MAX_GF_EXTDEG==8) +// 1>nElm || nElm>extDeg +// +// cpID_Poly!=pGFpMethod->modulusID -- method does not refferenced to polynomial one +// pGFpMethod->modulusBitDeg!=extDeg -- fixed method does not match to degree extension +// +// ippStsNoErr no error +// +// Parameters: +// pGroundGF pointer to the context of the finite field is being extension +// extDeg degree of extension +// ppGroundElm[] pointer to the array of extension field polynomial +// nElm number of coefficients above +// pGFpMethod pointer to the basic arithmetic metods +// pGFpx pointer to Finite Field context is being initialized +*F*/ +IPPFUN(IppStatus, ippsGFpxInit,(const IppsGFpState* pGroundGF, int extDeg, + const IppsGFpElement* const ppGroundElm[], int nElm, + const IppsGFpMethod* pGFpMethod, IppsGFpState* pGFpx)) +{ + IPP_BAD_PTR4_RET(pGFpx, pGroundGF, ppGroundElm, pGFpMethod); + + IPP_BADARG_RET( !GFP_VALID_ID(pGroundGF), ippStsContextMatchErr ); + + /* test extension degree */ + IPP_BADARG_RET( extDegIPP_MAX_GF_EXTDEG, ippStsBadArgErr); + /* coeffs at (x^0), (x^1), ..., (x^(deg-1)) passed acually */ + /* considering normilized f(x), the coeff at (x^deg) is 1 and so could neither stored no passed */ + /* test if 1<=nElm<=extDeg */ + IPP_BADARG_RET( 1>nElm || nElm>extDeg, ippStsBadArgErr); + + /* test if method is polynomial based */ + IPP_BADARG_RET(cpID_Poly != (pGFpMethod->modulusID & cpID_Poly), ippStsBadArgErr); + /* test if method is fixed polynomial based */ + IPP_BADARG_RET(pGFpMethod->modulusBitDeg && (pGFpMethod->modulusBitDeg!=extDeg), ippStsBadArgErr); + + InitGFpxCtx(pGroundGF, extDeg, pGFpMethod, pGFpx); + + { + BNU_CHUNK_T* pPoly = GFP_MODULUS(GFP_PMA(pGFpx)); + int polyTermlen = GFP_FELEN(GFP_PMA(pGroundGF)); + int n; + for(n=0; n extDeg || extDeg > IPP_MAX_GF_EXTDEG +// (IPP_MIN_GF_EXTDEG==2, IPP_MAX_GF_EXTDEG==8) +// +// cpID_Poly!=pGFpMethod->modulusID -- method does not refferenced to polynomial one +// pGFpMethod->modulusBitDeg!=extDeg -- fixed method does not match to degree extension +// +// ippStsNoErr no error +// +// Parameters: +// pGroundGF pointer to the context of the finite field is being extension +// extDeg degree of extension +// pGroundElm pointer to the IppsGFpElement context containing the trailing coefficient of the field binomial. +// pGFpMethod pointer to the basic arithmetic metods +// pGFpx pointer to Finite Field context is being initialized +*F*/ +IPPFUN(IppStatus, ippsGFpxInitBinomial,(const IppsGFpState* pGroundGF, int extDeg, + const IppsGFpElement* pGroundElm, + const IppsGFpMethod* pGFpMethod, + IppsGFpState* pGFpx)) +{ + IPP_BAD_PTR4_RET(pGFpx, pGroundGF, pGroundElm, pGFpMethod); + + IPP_BADARG_RET( !GFP_VALID_ID(pGroundGF), ippStsContextMatchErr ); + + IPP_BADARG_RET( !GFPE_VALID_ID(pGroundElm), ippStsContextMatchErr ); + IPP_BADARG_RET(GFPE_ROOM(pGroundElm)!=GFP_FELEN(GFP_PMA(pGroundGF)), ippStsOutOfRangeErr); + + IPP_BADARG_RET( extDegIPP_MAX_GF_EXTDEG, ippStsBadArgErr); + + /* test method is binomial based */ + IPP_BADARG_RET(cpID_Binom != (pGFpMethod->modulusID & cpID_Binom), ippStsBadArgErr); + + /* test if method assums fixed degree extension */ + IPP_BADARG_RET(pGFpMethod->modulusBitDeg && (extDeg!=pGFpMethod->modulusBitDeg), ippStsBadArgErr); + + /* init context */ + InitGFpxCtx(pGroundGF, extDeg, pGFpMethod, pGFpx); + + /* store low-order coefficient of irresucible into the context */ + cpGFpElementCopy(GFP_MODULUS(GFP_PMA(pGFpx)), GFPE_DATA(pGroundElm), GFP_FELEN(GFP_PMA(pGroundGF))); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom.c new file mode 100644 index 000000000..0e44995d7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom.c @@ -0,0 +1,123 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods, if binomial generator +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" + +//tbcd: temporary excluded: #include + +/* +// Multiplication in GF(p^d), if field polynomial: g(x) = x^d + beta => binominal +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxMul_pd_binom, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + BNU_CHUNK_T* pGFpolynomial = GFP_MODULUS(pGFEx); + int deg = GFP_EXTDEGREE(pGFEx); + int elemLen= GFP_FELEN(pGFEx); + int groundElemLen = GFP_FELEN(GFP_PARENT(pGFEx)); + int d; + + BNU_CHUNK_T* R = cpGFpGetPool(4, pGFEx); + BNU_CHUNK_T* X = R+elemLen; + BNU_CHUNK_T* T0= X+elemLen; + BNU_CHUNK_T* T1= T0+elemLen; + //tbcd: temporary excluded: assert(NULL!=R); + + /* T0 = A * beta */ + cpGFpxMul_GFE(T0, pA, pGFpolynomial, pGFEx); + /* T1 = A */ + cpGFpElementCopy(T1, pA, elemLen); + + /* R = A * B[0] */ + cpGFpxMul_GFE(R, pA, pB, pGFEx); + + /* R += (A*B[d]) mod g() */ + for(d=1; dadd(R, R, X, pGFEx); + } + cpGFpElementCopy(pR, R, elemLen); + + cpGFpReleasePool(4, pGFEx); + return pR; +} + +/* +// Squaring in GF(p^d), if field polynomial: g(x) = x^d + beta => binominal +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxSqr_pd_binom, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +{ + #if defined(__INTEL_COMPILER) + #pragma noinline + #endif + return cpGFpxMul_pd_binom(pR, pA, pA, pGFEx); +} + +/* +// return specific polynomial arith methods +// polynomial - general binomial +*/ +static gsModMethod* gsPolyArith_binom (void) +{ + static gsModMethod m = { + cpGFpxEncode_com, + cpGFpxDecode_com, + cpGFpxMul_pd_binom, + cpGFpxSqr_pd_binom, + NULL, + cpGFpxAdd_com, + cpGFpxSub_com, + cpGFpxNeg_com, + cpGFpxDiv2_com, + cpGFpxMul2_com, + cpGFpxMul3_com, + //cpGFpxInv + }; + return &m; +} + +/*F* +// Name: ippsGFpxMethod_binom2 +// +// Purpose: Returns a reference to the implementation of arithmetic operations over GF(pd). +// +// Returns: pointer to a structure containing +// an implementation of arithmetic operations over GF(pd) +// g(x) = x^d - a0, a0 from GF(p) +// +// +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpxMethod_binom, (void) ) +{ + static IppsGFpMethod method = { + cpID_Binom, + 0, + NULL, + NULL, + NULL + }; + method.arith = gsPolyArith_binom(); + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom2.c new file mode 100644 index 000000000..0ab180171 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom2.c @@ -0,0 +1,191 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods, if binomial generator +// +*/ +#include "owncp.h" + +#include "pcpgfpxmethod_binom_mulc.h" +#include "pcpgfpxmethod_com.h" + +//tbcd: temporary excluded: #include + +/* +// Multiplication in GF(p^2), if field polynomial: g(x) = x^2 + beta => binominal +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxMul_p2_binom, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + int groundElemLen = GFP_FELEN(pGroundGFE); + + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + + const BNU_CHUNK_T* pB0 = pB; + const BNU_CHUNK_T* pB1 = pB+groundElemLen; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + + BNU_CHUNK_T* t0 = cpGFpGetPool(4, pGroundGFE); + BNU_CHUNK_T* t1 = t0+groundElemLen; + BNU_CHUNK_T* t2 = t1+groundElemLen; + BNU_CHUNK_T* t3 = t2+groundElemLen; + //tbcd: temporary excluded: assert(NULL!=t0); + + #if defined GS_DBG + BNU_CHUNK_T* arg0 = cpGFpGetPool(1, pGroundGFE); + BNU_CHUNK_T* arg1 = cpGFpGetPool(1, pGroundGFE); + #endif + #if defined GS_DBG + cpGFpxGet(arg0, groundElemLen, pA0, pGroundGFE); + cpGFpxGet(arg1, groundElemLen, pB0, pGroundGFE); + #endif + + mulF(t0, pA0, pB0, pGroundGFE); /* t0 = a[0]*b[0] */ + + #if defined GS_DBG + cpGFpxGet(arg0, groundElemLen, pA1, pGroundGFE); + cpGFpxGet(arg1, groundElemLen, pB1, pGroundGFE); + #endif + + mulF(t1, pA1, pB1, pGroundGFE); /* t1 = a[1]*b[1] */ + addF(t2, pA0, pA1, pGroundGFE); /* t2 = a[0]+a[1] */ + addF(t3, pB0, pB1, pGroundGFE); /* t3 = b[0]+b[1] */ + + #if defined GS_DBG + cpGFpxGet(arg0, groundElemLen, t2, pGroundGFE); + cpGFpxGet(arg1, groundElemLen, t3, pGroundGFE); + #endif + + mulF(pR1, t2, t3, pGroundGFE); /* r[1] = (a[0]+a[1]) * (b[0]+b[1]) */ + subF(pR1, pR1, t0, pGroundGFE); /* r[1] -= a[0]*b[0]) + a[1]*b[1] */ + subF(pR1, pR1, t1, pGroundGFE); + + cpGFpxMul_G0(t1, t1, pGFEx); + subF(pR0, t0, t1, pGroundGFE); + + #if defined GS_DBG + cpGFpReleasePool(2, pGroundGFE); + #endif + + cpGFpReleasePool(4, pGroundGFE); + return pR; +} + +/* +// Squaring in GF(p^2), if field polynomial: g(x) = x^2 + beta => binominal +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxSqr_p2_binom, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + int groundElemLen = GFP_FELEN(pGroundGFE); + + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGroundGFE)->sqr; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + + BNU_CHUNK_T* t0 = cpGFpGetPool(3, pGroundGFE); + BNU_CHUNK_T* t1 = t0+groundElemLen; + BNU_CHUNK_T* u0 = t1+groundElemLen; + //tbcd: temporary excluded: assert(NULL!=t0); + + #if defined GS_DBG + BNU_CHUNK_T* arg0 = cpGFpGetPool(1, pGroundGFE); + BNU_CHUNK_T* arg1 = cpGFpGetPool(1, pGroundGFE); + #endif + #if defined GS_DBG + cpGFpxGet(arg0, groundElemLen, pA0, pGroundGFE); + cpGFpxGet(arg1, groundElemLen, pA1, pGroundGFE); + #endif + + mulF(u0, pA0, pA1, pGroundGFE); /* u0 = a[0]*a[1] */ + sqrF(t0, pA0, pGroundGFE); /* t0 = a[0]*a[0] */ + sqrF(t1, pA1, pGroundGFE); /* t1 = a[1]*a[1] */ + cpGFpxMul_G0(t1, t1, pGFEx); + subF(pR0, t0, t1, pGroundGFE); + addF(pR1, u0, u0, pGroundGFE); /* r[1] = 2*a[0]*a[1] */ + + #if defined GS_DBG + cpGFpReleasePool(2, pGroundGFE); + #endif + + cpGFpReleasePool(3, pGroundGFE); + return pR; +} + +/* +// return specific polynomi alarith methods +// polynomial - deg 2 binomial +*/ +static gsModMethod* gsPolyArith_binom2 (void) +{ + static gsModMethod m = { + cpGFpxEncode_com, + cpGFpxDecode_com, + cpGFpxMul_p2_binom, + cpGFpxSqr_p2_binom, + NULL, + cpGFpxAdd_com, + cpGFpxSub_com, + cpGFpxNeg_com, + cpGFpxDiv2_com, + cpGFpxMul2_com, + cpGFpxMul3_com, + //cpGFpxInv + }; + return &m; +} + +/*F* +// Name: ippsGFpxMethod_binom2 +// +// Purpose: Returns a reference to the implementation of arithmetic operations over GF(pd). +// +// Returns: pointer to a structure containing +// an implementation of arithmetic operations over GF(pd) +// g(x) = x^2 - a0, a0 from GF(p) +// +// +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpxMethod_binom2, (void) ) +{ + static IppsGFpMethod method = { + cpID_Binom, + 2, + NULL, + NULL, + NULL + }; + method.arith = gsPolyArith_binom2(); + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom3.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom3.c new file mode 100644 index 000000000..5c831524e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom3.c @@ -0,0 +1,195 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods, if binomial generator +// +*/ +#include "owncp.h" + +#include "pcpgfpxmethod_binom_mulc.h" +#include "pcpgfpxmethod_com.h" + +//tbcd: temporary excluded: #include + +/* +// Multiplication in GF(p^3), if field polynomial: g(x) = x^3 + beta => binominal +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxMul_p3_binom, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + int groundElemLen = GFP_FELEN(pGroundGFE); + + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + const BNU_CHUNK_T* pA2 = pA+groundElemLen*2; + + const BNU_CHUNK_T* pB0 = pB; + const BNU_CHUNK_T* pB1 = pB+groundElemLen; + const BNU_CHUNK_T* pB2 = pB+groundElemLen*2; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + BNU_CHUNK_T* pR2 = pR+groundElemLen*2; + + BNU_CHUNK_T* t0 = cpGFpGetPool(6, pGroundGFE); + BNU_CHUNK_T* t1 = t0+groundElemLen; + BNU_CHUNK_T* t2 = t1+groundElemLen; + BNU_CHUNK_T* u0 = t2+groundElemLen; + BNU_CHUNK_T* u1 = u0+groundElemLen; + BNU_CHUNK_T* u2 = u1+groundElemLen; + //tbcd: temporary excluded: assert(NULL!=t0); + + addF(u0 ,pA0, pA1, pGroundGFE); /* u0 = a[0]+a[1] */ + addF(t0 ,pB0, pB1, pGroundGFE); /* t0 = b[0]+b[1] */ + mulF(u0, u0, t0, pGroundGFE); /* u0 = (a[0]+a[1])*(b[0]+b[1]) */ + mulF(t0, pA0, pB0, pGroundGFE); /* t0 = a[0]*b[0] */ + + addF(u1 ,pA1, pA2, pGroundGFE); /* u1 = a[1]+a[2] */ + addF(t1 ,pB1, pB2, pGroundGFE); /* t1 = b[1]+b[2] */ + mulF(u1, u1, t1, pGroundGFE); /* u1 = (a[1]+a[2])*(b[1]+b[2]) */ + mulF(t1, pA1, pB1, pGroundGFE); /* t1 = a[1]*b[1] */ + + addF(u2 ,pA2, pA0, pGroundGFE); /* u2 = a[2]+a[0] */ + addF(t2 ,pB2, pB0, pGroundGFE); /* t2 = b[2]+b[0] */ + mulF(u2, u2, t2, pGroundGFE); /* u2 = (a[2]+a[0])*(b[2]+b[0]) */ + mulF(t2, pA2, pB2, pGroundGFE); /* t2 = a[2]*b[2] */ + + subF(u0, u0, t0, pGroundGFE); /* u0 = a[0]*b[1]+a[1]*b[0] */ + subF(u0, u0, t1, pGroundGFE); + subF(u1, u1, t1, pGroundGFE); /* u1 = a[1]*b[2]+a[2]*b[1] */ + subF(u1, u1, t2, pGroundGFE); + subF(u2, u2, t2, pGroundGFE); /* u2 = a[2]*b[0]+a[0]*b[2] */ + subF(u2, u2, t0, pGroundGFE); + + cpGFpxMul_G0(u1, u1, pGFEx); /* u1 = (a[1]*b[2]+a[2]*b[1]) * beta */ + cpGFpxMul_G0(t2, t2, pGFEx); /* t2 = a[2]*b[2] * beta */ + + subF(pR0, t0, u1, pGroundGFE); /* r[0] = a[0]*b[0] - (a[2]*b[1]+a[1]*b[2])*beta */ + subF(pR1, u0, t2, pGroundGFE); /* r[1] = a[1]*b[0] + a[0]*b[1] - a[2]*b[2]*beta */ + + addF(pR2, u2, t1, pGroundGFE); /* r[2] = a[2]*b[0] + a[1]*b[1] + a[0]*b[2] */ + + cpGFpReleasePool(6, pGroundGFE); + return pR; +} + +/* +// Squaring in GF(p^3), if field polynomial: g(x) = x^3 + beta => binominal +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxSqr_p3_binom, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + int groundElemLen = GFP_FELEN(pGroundGFE); + + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGroundGFE)->sqr; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + const BNU_CHUNK_T* pA2 = pA+groundElemLen*2; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + BNU_CHUNK_T* pR2 = pR+groundElemLen*2; + + BNU_CHUNK_T* s0 = cpGFpGetPool(5, pGroundGFE); + BNU_CHUNK_T* s1 = s0+groundElemLen; + BNU_CHUNK_T* s2 = s1+groundElemLen; + BNU_CHUNK_T* s3 = s2+groundElemLen; + BNU_CHUNK_T* s4 = s3+groundElemLen; + //tbcd: temporary excluded: assert(NULL!=s0); + + addF(s2, pA0, pA2, pGroundGFE); + subF(s2, s2, pA1, pGroundGFE); + sqrF(s2, s2, pGroundGFE); + sqrF(s0, pA0, pGroundGFE); + sqrF(s4, pA2, pGroundGFE); + mulF(s1, pA0, pA1, pGroundGFE); + mulF(s3, pA1, pA2, pGroundGFE); + addF(s1, s1, s1, pGroundGFE); + addF(s3, s3, s3, pGroundGFE); + + addF(pR2, s1, s2, pGroundGFE); + addF(pR2, pR2, s3, pGroundGFE); + subF(pR2, pR2, s0, pGroundGFE); + subF(pR2, pR2, s4, pGroundGFE); + + cpGFpxMul_G0(s4, s4, pGFEx); + subF(pR1, s1, s4, pGroundGFE); + + cpGFpxMul_G0(s3, s3, pGFEx); + subF(pR0, s0, s3, pGroundGFE); + + cpGFpReleasePool(5, pGroundGFE); + return pR; +} + + +/* +// return specific polynomi alarith methods +// polynomial - deg 3 binomial +*/ +static gsModMethod* gsPolyArith_binom3 (void) +{ + static gsModMethod m = { + cpGFpxEncode_com, + cpGFpxDecode_com, + cpGFpxMul_p3_binom, + cpGFpxSqr_p3_binom, + NULL, + cpGFpxAdd_com, + cpGFpxSub_com, + cpGFpxNeg_com, + cpGFpxDiv2_com, + cpGFpxMul2_com, + cpGFpxMul3_com, + //cpGFpxInv + }; + return &m; +} + +/*F* +// Name: ippsGFpxMethod_binom2 +// +// Purpose: Returns a reference to the implementation of arithmetic operations over GF(pd). +// +// Returns: pointer to a structure containing +// an implementation of arithmetic operations over GF(pd) +// g(x) = x^3 - a0, a0 from GF(p) +// +// +*F*/ +IPPFUN( const IppsGFpMethod*, ippsGFpxMethod_binom3, (void) ) +{ + static IppsGFpMethod method = { + cpID_Binom, + 3, + NULL, + NULL, + NULL + }; + method.arith = gsPolyArith_binom3(); + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom3_epid2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom3_epid2.c new file mode 100644 index 000000000..4252d8540 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom3_epid2.c @@ -0,0 +1,254 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods, if binomial generator over GF((p^2)^3) +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" +#include "pcpgfpxmethod_binom_epid2.h" + +//tbcd: temporary excluded: #include + +/* +// Intel(R) Enhanced Privacy ID (Intel(R) EPID) 2.0 specific. +// +// Intel(R) EPID 2.0 uses the following finite field hierarchy: +// +// 1) prime field GF(p), +// p = 0xFFFFFFFFFFFCF0CD46E5F25EEE71A49F0CDC65FB12980A82D3292DDBAED33013 +// +// 2) 2-degree extension of GF(p): GF(p^2) == GF(p)[x]/g(x), g(x) = x^2 -beta, +// beta =-1 mod p, so "beta" represents as {1} +// +// 3) 3-degree extension of GF(p^2) ~ GF(p^6): GF((p^2)^3) == GF(p)[v]/g(v), g(v) = v^3 -xi, +// xi belongs GF(p^2), xi=x+2, so "xi" represents as {2,1} ---- "2" is low- and "1" is high-order coefficients +// +// 4) 2-degree extension of GF((p^2)^3) ~ GF(p^12): GF(((p^2)^3)^2) == GF(p)[w]/g(w), g(w) = w^2 -vi, +// psi belongs GF((p^2)^3), vi=0*v^2 +1*v +0, so "vi" represents as {0,1,0}---- "0", '1" and "0" are low-, middle- and high-order coefficients +// +// See representations in t_gfpparam.cpp +// +*/ + +/* +// Intel(R) EPID 2.0 specific +// ~~~~~~~~~~~~~~~ +// +// Multiplication over GF((p^2)^3) +// - field polynomial: g(v) = v^3 - xi => binominal with specific value of "xi" +// - xi = x+2 +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxMul_p3_binom_epid2, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + int groundElemLen = GFP_FELEN(pGroundGFE); + + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + const BNU_CHUNK_T* pA2 = pA+groundElemLen*2; + + const BNU_CHUNK_T* pB0 = pB; + const BNU_CHUNK_T* pB1 = pB+groundElemLen; + const BNU_CHUNK_T* pB2 = pB+groundElemLen*2; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + BNU_CHUNK_T* pR2 = pR+groundElemLen*2; + + BNU_CHUNK_T* t0 = cpGFpGetPool(6, pGroundGFE); + BNU_CHUNK_T* t1 = t0+groundElemLen; + BNU_CHUNK_T* t2 = t1+groundElemLen; + BNU_CHUNK_T* u0 = t2+groundElemLen; + BNU_CHUNK_T* u1 = u0+groundElemLen; + BNU_CHUNK_T* u2 = u1+groundElemLen; + //tbcd: temporary excluded: assert(NULL!=t0); + + addF(u0 ,pA0, pA1, pGroundGFE); /* u0 = a[0]+a[1] */ + addF(t0 ,pB0, pB1, pGroundGFE); /* t0 = b[0]+b[1] */ + mulF(u0, u0, t0, pGroundGFE); /* u0 = (a[0]+a[1])*(b[0]+b[1]) */ + mulF(t0, pA0, pB0, pGroundGFE); /* t0 = a[0]*b[0] */ + + addF(u1 ,pA1, pA2, pGroundGFE); /* u1 = a[1]+a[2] */ + addF(t1 ,pB1, pB2, pGroundGFE); /* t1 = b[1]+b[2] */ + mulF(u1, u1, t1, pGroundGFE); /* u1 = (a[1]+a[2])*(b[1]+b[2]) */ + mulF(t1, pA1, pB1, pGroundGFE); /* t1 = a[1]*b[1] */ + + addF(u2 ,pA2, pA0, pGroundGFE); /* u2 = a[2]+a[0] */ + addF(t2 ,pB2, pB0, pGroundGFE); /* t2 = b[2]+b[0] */ + mulF(u2, u2, t2, pGroundGFE); /* u2 = (a[2]+a[0])*(b[2]+b[0]) */ + mulF(t2, pA2, pB2, pGroundGFE); /* t2 = a[2]*b[2] */ + + subF(u0, u0, t0, pGroundGFE); /* u0 = a[0]*b[1]+a[1]*b[0] */ + subF(u0, u0, t1, pGroundGFE); + subF(u1, u1, t1, pGroundGFE); /* u1 = a[1]*b[2]+a[2]*b[1] */ + subF(u1, u1, t2, pGroundGFE); + subF(u2, u2, t2, pGroundGFE); /* u2 = a[2]*b[0]+a[0]*b[2] */ + subF(u2, u2, t0, pGroundGFE); + + /* Intel(R) EPID 2.0 specific */ + { + int basicExtDegree = cpGFpBasicDegreeExtension(pGFEx); + + /* deal with GF(p^2^3) */ + if(basicExtDegree==6) { + cpFq2Mul_xi(u1, u1, pGroundGFE); + cpFq2Mul_xi(t2, t2, pGroundGFE); + addF(pR0, t0, u1, pGroundGFE); /* r[0] = a[0]*b[0] - (a[2]*b[1]+a[1]*b[2])*beta */ + addF(pR1, u0, t2, pGroundGFE); /* r[1] = a[1]*b[0] + a[0]*b[1] - a[2]*b[2]*beta */ + } + /* just a case */ + else { + cpGFpxMul_G0(u1, u1, pGFEx); /* u1 = (a[1]*b[2]+a[2]*b[1]) * beta */ + cpGFpxMul_G0(t2, t2, pGFEx); /* t2 = a[2]*b[2] * beta */ + subF(pR0, t0, u1, pGroundGFE); /* r[0] = a[0]*b[0] - (a[2]*b[1]+a[1]*b[2])*beta */ + subF(pR1, u0, t2, pGroundGFE); /* r[1] = a[1]*b[0] + a[0]*b[1] - a[2]*b[2]*beta */ + } + } + + addF(pR2, u2, t1, pGroundGFE); /* r[2] = a[2]*b[0] + a[1]*b[1] + a[0]*b[2] */ + + cpGFpReleasePool(6, pGroundGFE); + return pR; +} + +/* +// Intel(R) EPID 2.0 specific +// ~~~~~~~~~~~~~~~ +// +// Squaring over GF((p^2)^3) +// - field polynomial: g(v) = v^3 - xi => binominal with specific value of "xi" +// - xi = x+2 +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxSqr_p3_binom_epid2, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + int groundElemLen = GFP_FELEN(pGroundGFE); + + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGroundGFE)->sqr; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + const BNU_CHUNK_T* pA2 = pA+groundElemLen*2; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + BNU_CHUNK_T* pR2 = pR+groundElemLen*2; + + BNU_CHUNK_T* s0 = cpGFpGetPool(5, pGroundGFE); + BNU_CHUNK_T* s1 = s0+groundElemLen; + BNU_CHUNK_T* s2 = s1+groundElemLen; + BNU_CHUNK_T* s3 = s2+groundElemLen; + BNU_CHUNK_T* s4 = s3+groundElemLen; + + addF(s2, pA0, pA2, pGroundGFE); + subF(s2, s2, pA1, pGroundGFE); + sqrF(s2, s2, pGroundGFE); + sqrF(s0, pA0, pGroundGFE); + sqrF(s4, pA2, pGroundGFE); + mulF(s1, pA0, pA1, pGroundGFE); + mulF(s3, pA1, pA2, pGroundGFE); + addF(s1, s1, s1, pGroundGFE); + addF(s3, s3, s3, pGroundGFE); + + addF(pR2, s1, s2, pGroundGFE); + addF(pR2, pR2, s3, pGroundGFE); + subF(pR2, pR2, s0, pGroundGFE); + subF(pR2, pR2, s4, pGroundGFE); + + /* Intel(R) EPID 2.0 specific */ + { + int basicExtDegree = cpGFpBasicDegreeExtension(pGFEx); + + /* deal with GF(p^2^3) */ + if(basicExtDegree==6) { + cpFq2Mul_xi(s4, s4, pGroundGFE); + cpFq2Mul_xi(s3, s3, pGroundGFE); + addF(pR1, s1, s4, pGroundGFE); + addF(pR0, s0, s3, pGroundGFE); + } + /* just a case */ + else { + cpGFpxMul_G0(s4, s4, pGFEx); + cpGFpxMul_G0(s3, s3, pGFEx); + subF(pR1, s1, s4, pGroundGFE); + subF(pR0, s0, s3, pGroundGFE); + } + } + + cpGFpReleasePool(5, pGroundGFE); + return pR; +} + +/* +// return specific polynomi alarith methods +// polynomial - deg 3 binomial (Intel(R) EPID 2.0) +*/ +static gsModMethod* gsPolyArith_binom3_epid2 (void) +{ + static gsModMethod m = { + cpGFpxEncode_com, + cpGFpxDecode_com, + cpGFpxMul_p3_binom_epid2, + cpGFpxSqr_p3_binom_epid2, + NULL, + cpGFpxAdd_com, + cpGFpxSub_com, + cpGFpxNeg_com, + cpGFpxDiv2_com, + cpGFpxMul2_com, + cpGFpxMul3_com, + //cpGFpxInv + }; + return &m; +} + +/*F* +// Name: ippsGFpxMethod_binom3_epid2 +// +// Purpose: Returns a reference to the implementation of arithmetic operations over GF(pd). +// +// Returns: pointer to a structure containing +// an implementation of arithmetic operations over GF(pd) +// g(v) = v^3 - U0, U0 from GF(q^2), U0 = u + 2 +// +// +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpxMethod_binom3_epid2, (void) ) +{ + static IppsGFpMethod method = { + cpID_Binom3_epid20, + 3, + NULL, + NULL, + NULL + }; + method.arith = gsPolyArith_binom3_epid2(); + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_epid2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_epid2.c new file mode 100644 index 000000000..030bfb987 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_epid2.c @@ -0,0 +1,274 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods, if binomial generator +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" +#include "pcpgfpxmethod_binom_epid2.h" + +//tbcd: temporary excluded: #include + +/* +// Intel(R) Enhanced Privacy ID (Intel(R) EPID) 2.0 specific. +// +// Intel(R) EPID 2.0 uses the following finite field hierarchy: +// +// 1) prime field GF(p), +// p = 0xFFFFFFFFFFFCF0CD46E5F25EEE71A49F0CDC65FB12980A82D3292DDBAED33013 +// +// 2) 2-degree extension of GF(p): GF(p^2) == GF(p)[x]/g(x), g(x) = x^2 -beta, +// beta =-1 mod p, so "beta" represents as {1} +// +// 3) 3-degree extension of GF(p^2) ~ GF(p^6): GF((p^2)^3) == GF(p)[v]/g(v), g(v) = v^3 -xi, +// xi belongs GF(p^2), xi=x+2, so "xi" represents as {2,1} ---- "2" is low- and "1" is high-order coefficients +// +// 4) 2-degree extension of GF((p^2)^3) ~ GF(p^12): GF(((p^2)^3)^2) == GF(p)[w]/g(w), g(w) = w^2 -vi, +// psi belongs GF((p^2)^3), vi=0*v^2 +1*v +0, so "vi" represents as {0,1,0}---- "0", '1" and "0" are low-, middle- and high-order coefficients +// +// See representations in t_gfpparam.cpp +// +*/ + +/* +// Multiplication case: mul(a, vi) over GF((p^2)^3), +// where: +// a, belongs to GF((p^2)^3) +// xi belongs to GF((p^2)^3), vi={0,1,0} +// +// The case is important in GF(((p^2)^3)^2) arithmetic for Intel(R) EPID 2.0. +// +*/ +__INLINE BNU_CHUNK_T* cpFq6Mul_vi(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + int termLen = GFP_FELEN(pGroundGFE); + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+termLen; + const BNU_CHUNK_T* pA2 = pA+termLen*2; + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+termLen; + BNU_CHUNK_T* pR2 = pR+termLen*2; + + BNU_CHUNK_T* t = cpGFpGetPool(1, pGroundGFE); + //tbcd: temporary excluded: assert(NULL!=t); + + cpFq2Mul_xi(t, pA2, pGroundGFE); + cpGFpElementCopy(pR2, pA1, termLen); + cpGFpElementCopy(pR1, pA0, termLen); + cpGFpElementCopy(pR0, t, termLen); + + cpGFpReleasePool(1, pGroundGFE); + + return pR; +} + +/* +// Intel(R) EPID 2.0 specific +// ~~~~~~~~~~~~~~~ +// +// Multiplication over GF(p^2) +// - field polynomial: g(x) = x^2 - beta => binominal with specific value of "beta" +// - beta = p-1 +// +// Multiplication over GF(((p^2)^3)^2) ~ GF(p^12) +// - field polynomial: g(w) = w^2 - vi => binominal with specific value of "vi" +// - vi = 0*v^2 + 1*v + 0 - i.e vi={0,1,0} belongs to GF((p^2)^3) +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxMul_p2_binom_epid2, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + int groundElemLen = GFP_FELEN(pGroundGFE); + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + + const BNU_CHUNK_T* pB0 = pB; + const BNU_CHUNK_T* pB1 = pB+groundElemLen; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + + BNU_CHUNK_T* t0 = cpGFpGetPool(4, pGroundGFE); + BNU_CHUNK_T* t1 = t0+groundElemLen; + BNU_CHUNK_T* t2 = t1+groundElemLen; + BNU_CHUNK_T* t3 = t2+groundElemLen; + //tbcd: temporary excluded: assert(NULL!=t0); + + mulF(t0, pA0, pB0, pGroundGFE); /* t0 = a[0]*b[0] */ + mulF(t1, pA1, pB1, pGroundGFE); /* t1 = a[1]*b[1] */ + addF(t2, pA0, pA1, pGroundGFE); /* t2 = a[0]+a[1] */ + addF(t3, pB0, pB1, pGroundGFE); /* t3 = b[0]+b[1] */ + + mulF(pR1, t2, t3, pGroundGFE); /* r[1] = (a[0]+a[1]) * (b[0]+b[1]) */ + subF(pR1, pR1, t0, pGroundGFE); /* r[1] -= a[0]*b[0]) + a[1]*b[1] */ + subF(pR1, pR1, t1, pGroundGFE); + + /* Intel(R) EPID 2.0 specific */ + { + int basicExtDegree = cpGFpBasicDegreeExtension(pGFEx); + + /* deal with GF(p^2) */ + if(basicExtDegree==2) { + subF(pR0, t0, t1, pGroundGFE); + } + /* deal with GF(p^6^2) */ + else if(basicExtDegree==12) { + cpFq6Mul_vi(t1, t1, pGroundGFE); + addF(pR0, t0, t1, pGroundGFE); + } + /* deal with GF(p^x^2) - it's not Intel(R) EPID 2.0 case, just a case */ + else { + cpGFpxMul_G0(t1, t1, pGFEx); + subF(pR0, t0, t1, pGroundGFE); + } + } + + cpGFpReleasePool(4, pGroundGFE); + return pR; +} + +/* +// Intel(R) EPID 2.0 specific +// ~~~~~~~~~~~~~~~ +// +// Squaring over GF(p^2) +// - field polynomial: g(x) = x^2 - beta => binominal with specific value of "beta" +// - beta = p-1 +// +// Squaring in GF(((p^2)^3)^2) ~ GF(p^12) +// - field polynomial: g(w) = w^2 - vi => binominal with specific value of "vi" +// - vi = 0*v^2 + 1*v + 0 - i.e vi={0,1,0} belongs to GF((p^2)^3) +*/ +IPP_OWN_DEFN (static BNU_CHUNK_T*, cpGFpxSqr_p2_binom_epid2, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + mod_sqr sqrF = GFP_METHOD(pGroundGFE)->sqr; + mod_add addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + int groundElemLen = GFP_FELEN(pGroundGFE); + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+groundElemLen; + + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+groundElemLen; + + BNU_CHUNK_T* t0 = cpGFpGetPool(3, pGroundGFE); + BNU_CHUNK_T* t1 = t0+groundElemLen; + BNU_CHUNK_T* u0 = t1+groundElemLen; + //tbcd: temporary excluded: assert(NULL!=t0); + + mulF(u0, pA0, pA1, pGroundGFE); /* u0 = a[0]*a[1] */ + + /* Intel(R) EPID 2.0 specific */ + { + int basicExtDegree = cpGFpBasicDegreeExtension(pGFEx); + + /* deal with GF(p^2) */ + if(basicExtDegree==2) { + addF(t0, pA0, pA1, pGroundGFE); + subF(t1, pA0, pA1, pGroundGFE); + mulF(pR0, t0, t1, pGroundGFE); + addF(pR1, u0, u0, pGroundGFE); /* r[1] = 2*a[0]*a[1] */ + } + /* deal with GF(p^6^2) */ + else if(basicExtDegree==12) { + subF(t0, pA0, pA1, pGroundGFE); + cpFq6Mul_vi(t1, pA1, pGroundGFE); + subF(t1, pA0, t1, pGroundGFE); + mulF(t0, t0, t1, pGroundGFE); + addF(t0, t0, u0, pGroundGFE); + cpFq6Mul_vi(t1, u0, pGroundGFE); + addF(pR0, t0, t1, pGroundGFE); + addF(pR1, u0, u0, pGroundGFE); + } + /* just a case */ + else { + sqrF(t0, pA0, pGroundGFE); /* t0 = a[0]*a[0] */ + sqrF(t1, pA1, pGroundGFE); /* t1 = a[1]*a[1] */ + cpGFpxMul_G0(t1, t1, pGFEx); + subF(pR0, t0, t1, pGroundGFE); + addF(pR1, u0, u0, pGroundGFE); /* r[1] = 2*a[0]*a[1] */ + } + } + + cpGFpReleasePool(3, pGroundGFE); + return pR; +} + +/* +// return specific polynomi alarith methods +// polynomial - deg 2 binomial (Intel(R) EPID 2.0) +*/ +static gsModMethod* gsPolyArith_binom2_epid2 (void) +{ + static gsModMethod m = { + cpGFpxEncode_com, + cpGFpxDecode_com, + cpGFpxMul_p2_binom_epid2, + cpGFpxSqr_p2_binom_epid2, + NULL, + cpGFpxAdd_com, + cpGFpxSub_com, + cpGFpxNeg_com, + cpGFpxDiv2_com, + cpGFpxMul2_com, + cpGFpxMul3_com, + //cpGFpxInv + }; + return &m; +} + +/*F* +// Name: ippsGFpxMethod_binom2_epid2 +// +// Purpose: Returns a reference to the implementation of arithmetic operations over GF(pd). +// +// Returns: pointer to a structure containing +// an implementation of arithmetic operations over GF(pd) +// g(x) = x^2 - a0, a0 from GF(q), a0 = 1 +// g(w) = w^2 - V0, v0 from GF((q^2)^3), V0 = 0*s^2 + v + 0 +// +// +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpxMethod_binom2_epid2, (void) ) +{ + static IppsGFpMethod method = { + cpID_Binom2_epid20, + 2, + NULL, + NULL, + NULL + }; + method.arith = gsPolyArith_binom2_epid2(); + return &method; +} + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_epid2.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_epid2.h new file mode 100644 index 000000000..f7e4a0008 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_epid2.h @@ -0,0 +1,99 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// internal functions for GF(p^d) methods, if binomial generator +// with Intel(R) Enhanced Privacy ID (Intel(R) EPID) 2.0 specific +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" + +//tbcd: temporary excluded: #include + +/* +// Intel(R) EPID 2.0 specific. +// +// Intel(R) EPID 2.0 uses the following finite field hierarchy: +// +// 1) prime field GF(p), +// p = 0xFFFFFFFFFFFCF0CD46E5F25EEE71A49F0CDC65FB12980A82D3292DDBAED33013 +// +// 2) 2-degree extension of GF(p): GF(p^2) == GF(p)[x]/g(x), g(x) = x^2 -beta, +// beta =-1 mod p, so "beta" represents as {1} +// +// 3) 3-degree extension of GF(p^2) ~ GF(p^6): GF((p^2)^3) == GF(p)[v]/g(v), g(v) = v^3 -xi, +// xi belongs GF(p^2), xi=x+2, so "xi" represents as {2,1} ---- "2" is low- and "1" is high-order coefficients +// +// 4) 2-degree extension of GF((p^2)^3) ~ GF(p^12): GF(((p^2)^3)^2) == GF(p)[w]/g(w), g(w) = w^2 -vi, +// psi belongs GF((p^2)^3), vi=0*v^2 +1*v +0, so "vi" represents as {0,1,0}---- "0", '1" and "0" are low-, middle- and high-order coefficients +// +// See representations in t_gfpparam.cpp +// +*/ + +/* +// Multiplication case: mul(a, xi) over GF(p^2), +// where: +// a, belongs to GF(p^2) +// xi belongs to GF(p^2), xi={2,1} +// +// The case is important in GF((p^2)^3) arithmetic for Intel(R) EPID 2.0. +// +*/ +__INLINE BNU_CHUNK_T* cpFq2Mul_xi(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + mod_mul addF = GFP_METHOD(pGroundGFE)->add; + mod_sub subF = GFP_METHOD(pGroundGFE)->sub; + + int termLen = GFP_FELEN(pGroundGFE); + BNU_CHUNK_T* t0 = cpGFpGetPool(2, pGroundGFE); + BNU_CHUNK_T* t1 = t0+termLen; + + const BNU_CHUNK_T* pA0 = pA; + const BNU_CHUNK_T* pA1 = pA+termLen; + BNU_CHUNK_T* pR0 = pR; + BNU_CHUNK_T* pR1 = pR+termLen; + + //tbcd: temporary excluded: assert(NULL!=t0); + addF(t0, pA0, pA0, pGroundGFE); + addF(t1, pA0, pA1, pGroundGFE); + subF(pR0, t0, pA1, pGroundGFE); + addF(pR1, t1, pA1, pGroundGFE); + + cpGFpReleasePool(2, pGroundGFE); + return pR; +} + +/* +// Multiplication case: mul(a, g0) over GF(()), +// where: +// a and g0 belongs to GF(()) - field is being extension +// +// The case is important in GF(()^d) arithmetic if constructed polynomial is generic binomial g(t) = t^d +g0. +// +*/ +static BNU_CHUNK_T* cpGFpxMul_G0(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + BNU_CHUNK_T* pGFpolynomial = GFP_MODULUS(pGFEx); /* g(x) = t^d + g0 */ + return GFP_METHOD(pGroundGFE)->mul(pR, pA, pGFpolynomial, pGroundGFE); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_mulc.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_mulc.h new file mode 100644 index 000000000..61043a22b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_binom_mulc.h @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods, if binomial generator +// +*/ +#if !defined(_CP_GFP_METHOD_BINOM_H) +#define _CP_GFP_METHOD_BINOM_H + +#include "owncp.h" +#include "pcpgfpxstuff.h" + + +static BNU_CHUNK_T* cpGFpxMul_G0(BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx) +{ + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + mod_mul mulF = GFP_METHOD(pGroundGFE)->mul; + + BNU_CHUNK_T* pGFpolynomial = GFP_MODULUS(pGFEx); /* g(x) = t^d + g0 */ + + #if defined GS_DBG + BNU_CHUNK_T* arg0 = cpGFpGetPool(1, pGroundGFE); + BNU_CHUNK_T* arg1 = cpGFpGetPool(1, pGroundGFE); + int groundElemLen = GFP_FELEN(pGroundGFE); + #endif + + #if defined GS_DBG + cpGFpxGet(arg0, groundElemLen, pA, pGroundGFE); + cpGFpxGet(arg1, groundElemLen, pGFpolynomial, pGroundGFE); + #endif + + mulF(pR, pA, pGFpolynomial, pGroundGFE); + + #if defined GS_DBG + cpGFpReleasePool(2, pGroundGFE); + #endif + + return pR; +} + +#endif /* _CP_GFP_METHOD_BINOM_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com.c new file mode 100644 index 000000000..c6eda7b91 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" + + +/* +// return common polynomi alarith methods +*/ +static gsModMethod* gsPolyArith(void) +{ + static gsModMethod m = { + cpGFpxEncode_com, + cpGFpxDecode_com, + cpGFpxMul_com, + cpGFpxSqr_com, + NULL, + cpGFpxAdd_com, + cpGFpxSub_com, + cpGFpxNeg_com, + cpGFpxDiv2_com, + cpGFpxMul2_com, + cpGFpxMul3_com, + //cpGFpxInv + }; + return &m; +} + +/*F* +// Name: ippsGFpxMethod_binom2 +// +// Purpose: Returns a reference to the implementation of arithmetic operations over GF(pd). +// +// Returns: pointer to a structure containing +// an implementation of arithmetic operations over GF(pd) +// g(x) = x^d + x(d - 1) a_(d-1) + x^(d - 2)a_(d - 2) + ... + x1a1 + a0, ai from GF(p) +// +// +*F*/ + +IPPFUN( const IppsGFpMethod*, ippsGFpxMethod_com, (void) ) +{ + static IppsGFpMethod method = { + cpID_Poly, + 0, + NULL, + NULL, + NULL + }; + method.arith = gsPolyArith(); + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com.h new file mode 100644 index 000000000..5bb03abb5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com.h @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods +// +*/ +#if !defined(_CP_GFP_METHOD_COM_H) +#define _CP_GFP_METHOD_COM_H + +#include "owncp.h" +#include "pcpgfpstuff.h" + +#define cpGFpxAdd_com OWNAPI(cpGFpxAdd_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxAdd_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +#define cpGFpxSub_com OWNAPI(cpGFpxSub_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxSub_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +#define cpGFpxNeg_com OWNAPI(cpGFpxNeg_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxNeg_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) + +#define cpGFpxMul_com OWNAPI(cpGFpxMul_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxMul_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +#define cpGFpxSqr_com OWNAPI(cpGFpxSqr_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxSqr_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) + +#define cpGFpxDiv2_com OWNAPI(cpGFpxDiv2_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxDiv2_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +#define cpGFpxMul2_com OWNAPI(cpGFpxMul2_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxMul2_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +#define cpGFpxMul3_com OWNAPI(cpGFpxMul3_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxMul3_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) + +#define cpGFpxEncode_com OWNAPI(cpGFpxEncode_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxEncode_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +#define cpGFpxDecode_com OWNAPI(cpGFpxDecode_com) + IPP_OWN_DECL (BNU_CHUNK_T*, cpGFpxDecode_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) + +#endif /* _CP_GFP_METHOD_COM_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_add.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_add.c new file mode 100644 index 000000000..3f51a7ec5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_add.c @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" + + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxAdd_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + gsEngine* pBasicGFE = cpGFpBasic(pGFEx); + mod_add addF = GFP_METHOD(pBasicGFE)->add; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; degdecode; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; degdiv2; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; degencode; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; deg + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxMul_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + int extDegree = GFP_EXTDEGREE(pGFEx); + + BNU_CHUNK_T* pGFpolynomial = GFP_MODULUS(pGFEx); + int degR = extDegree-1; + int elemLen= GFP_FELEN(pGFEx); + + int degB = degR; + BNU_CHUNK_T* pTmpProduct = cpGFpGetPool(2, pGFEx); + BNU_CHUNK_T* pTmpResult = pTmpProduct + GFP_PELEN(pGFEx); + + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + BNU_CHUNK_T* r = cpGFpGetPool(1, pGroundGFE); + int groundElemLen = GFP_FELEN(pGroundGFE); + + const BNU_CHUNK_T* pTmpB = GFPX_IDX_ELEMENT(pB, degB, groundElemLen); + + //tbcd: temporary excluded: assert(NULL!=pTmpProduct && NULL!=r); + + /* clear temporary */ + cpGFpElementPad(pTmpProduct, elemLen, 0); + + /* R = A * B[degB-1] */ + cpGFpxMul_GFE(pTmpResult, pA, pTmpB, pGFEx); + + for(degB-=1; degB>=0; degB--) { + /* save R[degR-1] */ + cpGFpElementCopy(r, GFPX_IDX_ELEMENT(pTmpResult, degR, groundElemLen), groundElemLen); + + { /* R = R * x */ + int j; + for (j=degR; j>=1; j--) + cpGFpElementCopy(GFPX_IDX_ELEMENT(pTmpResult, j, groundElemLen), GFPX_IDX_ELEMENT(pTmpResult, j-1, groundElemLen), groundElemLen); + cpGFpElementPad(pTmpResult, groundElemLen, 0); + } + + cpGFpxMul_GFE(pTmpProduct, pGFpolynomial, r, pGFEx); + GFP_METHOD(pGFEx)->sub(pTmpResult, pTmpResult, pTmpProduct, pGFEx); + + /* B[degB-i] */ + pTmpB -= groundElemLen; + cpGFpxMul_GFE(pTmpProduct, pA, pTmpB, pGFEx); + GFP_METHOD(pGFEx)->add(pTmpResult, pTmpResult, pTmpProduct, pGFEx); + } + + /* copy result */ + cpGFpElementCopy(pR, pTmpResult, elemLen); + + /* release pools */ + cpGFpReleasePool(1, pGroundGFE); + cpGFpReleasePool(2, pGFEx); + + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_mul2.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_mul2.c new file mode 100644 index 000000000..465389ad6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_mul2.c @@ -0,0 +1,44 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" + + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxMul2_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +{ + gsEngine* pBasicGFE = cpGFpBasic(pGFEx); + mod_mul2 mul2F = GFP_METHOD(pBasicGFE)->mul2; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; degmul3; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; degneg; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; deg + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxSqr_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, gsEngine* pGFEx)) +{ + int extDegree = GFP_EXTDEGREE(pGFEx); + + BNU_CHUNK_T* pGFpolynomial = GFP_MODULUS(pGFEx); + int degR = extDegree-1; + int elemLen= GFP_FELEN(pGFEx); + + int degA = degR; + BNU_CHUNK_T* pTmpProduct = cpGFpGetPool(2, pGFEx); + BNU_CHUNK_T* pTmpResult = pTmpProduct + GFP_PELEN(pGFEx); + + gsEngine* pGroundGFE = GFP_PARENT(pGFEx); + BNU_CHUNK_T* r = cpGFpGetPool(1, pGroundGFE); + int groundElemLen = GFP_FELEN(pGroundGFE); + + const BNU_CHUNK_T* pTmpA = GFPX_IDX_ELEMENT(pA, degA, groundElemLen); + + //tbcd: temporary excluded: assert(NULL!=pTmpProduct && NULL!=r); + + /* clear temporary */ + cpGFpElementPad(pTmpProduct, elemLen, 0); + + /* R = A * A[degA-1] */ + cpGFpxMul_GFE(pTmpResult, pA, pTmpA, pGFEx); + + for(degA-=1; degA>=0; degA--) { + /* save R[degR-1] */ + cpGFpElementCopy(r, GFPX_IDX_ELEMENT(pTmpResult, degR, groundElemLen), groundElemLen); + + { /* R = R * x */ + int j; + for (j=degR; j>=1; j--) + cpGFpElementCopy(GFPX_IDX_ELEMENT(pTmpResult, j, groundElemLen), GFPX_IDX_ELEMENT(pTmpResult, j-1, groundElemLen), groundElemLen); + cpGFpElementPad(pTmpResult, groundElemLen, 0); + } + + cpGFpxMul_GFE(pTmpProduct, pGFpolynomial, r, pGFEx); + GFP_METHOD(pGFEx)->sub(pTmpResult, pTmpResult, pTmpProduct, pGFEx); + + /* A[degA-i] */ + pTmpA -= groundElemLen; + cpGFpxMul_GFE(pTmpProduct, pA, pTmpA, pGFEx); + GFP_METHOD(pGFEx)->add(pTmpResult, pTmpResult, pTmpProduct, pGFEx); + } + + /* copy result */ + cpGFpElementCopy(pR, pTmpResult, elemLen); + + /* release pools */ + cpGFpReleasePool(1, pGroundGFE); + cpGFpReleasePool(2, pGFEx); + + return pR; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_sub.c b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_sub.c new file mode 100644 index 000000000..ff50b6757 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxmethod_com_sub.c @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// GF(p^d) methods +// +*/ +#include "owncp.h" + +#include "pcpgfpxstuff.h" +#include "pcpgfpxmethod_com.h" + + +IPP_OWN_DEFN (BNU_CHUNK_T*, cpGFpxSub_com, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, const BNU_CHUNK_T* pB, gsEngine* pGFEx)) +{ + gsEngine* pBasicGFE = cpGFpBasic(pGFEx); + mod_sub subF = GFP_METHOD(pBasicGFE)->sub; + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFEx); + + BNU_CHUNK_T* pTmp = pR; + int deg; + for(deg=0; deg=n_opt) break; + w_opt = w_trial; + n_opt = n_trial; + } + return w_opt; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpgfpxstuff.h b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxstuff.h new file mode 100644 index 000000000..ca03fc901 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpgfpxstuff.h @@ -0,0 +1,144 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippCP) +// GF(p) extension internal +// +*/ + +#if !defined(_PCP_GFPEXT_H_) +#define _PCP_GFPEXT_H_ + +#include "pcpgfpstuff.h" + + +/* GF(p^d) pool */ +#define GFPX_PESIZE(pGF) GFP_FELEN((pGF)) +#define GFPX_POOL_SIZE (14) //(8) /* Number of temporary variables in pool */ + +/* address of ground field element inside expanded field element */ +#define GFPX_IDX_ELEMENT(pxe, idx, eleSize) ((pxe)+(eleSize)*(idx)) + + +__INLINE int degree(const BNU_CHUNK_T* pE, const gsModEngine* pGFEx) +{ + int groundElemLen = GFP_FELEN(GFP_PARENT(pGFEx)); + int deg; + for(deg=GFP_EXTDEGREE(pGFEx)-1; deg>=0; deg--) { + if(!GFP_IS_ZERO(pE+groundElemLen*deg, groundElemLen)) break; + } + return deg; +} + +__INLINE gsModEngine* cpGFpBasic(const gsModEngine* pGFEx) +{ + while( !GFP_IS_BASIC(pGFEx) ) { + pGFEx = GFP_PARENT(pGFEx); + } + return (gsModEngine*)pGFEx; +} +__INLINE int cpGFpBasicDegreeExtension(const gsModEngine* pGFEx) +{ + int degree = GFP_EXTDEGREE(pGFEx); + while( !GFP_IS_BASIC(pGFEx) ) { + pGFEx = GFP_PARENT(pGFEx); + degree *= GFP_EXTDEGREE(pGFEx); + } + return degree; +} + +/* convert external data (Ipp32u) => internal element (BNU_CHUNK_T) representation + returns length of element (in BNU_CHUNK_T) +*/ +__INLINE int cpGFpxCopyToChunk(BNU_CHUNK_T* pElm, const Ipp32u* pA, int nsA, const gsModEngine* pGFEx) +{ + gsModEngine* pBasicGFE = cpGFpBasic(pGFEx); + int basicExtension = cpGFpBasicDegreeExtension(pGFEx); + int basicElmLen32 = GFP_FELEN32(pBasicGFE); + int basicElmLen = GFP_FELEN(pBasicGFE); + int deg; + for(deg=0; deg0; deg++, nsA -= basicElmLen32) { + int srcLen = IPP_MIN(nsA, basicElmLen32); + ZEXPAND_COPY_BNU((Ipp32u*)pElm, basicElmLen*(int)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)), pA,srcLen); + pElm += basicElmLen; + pA += basicElmLen32; + } + return basicElmLen*deg; +} + +/* convert internal element (BNU_CHUNK_T) => external data (Ipp32u) representation + returns length of data (in Ipp32u) +*/ +__INLINE int cpGFpxCopyFromChunk(Ipp32u* pA, const BNU_CHUNK_T* pElm, const gsModEngine* pGFEx) +{ + gsModEngine* pBasicGFE = cpGFpBasic(pGFEx); + int basicExtension = cpGFpBasicDegreeExtension(pGFEx); + int basicElmLen32 = GFP_FELEN32(pBasicGFE); + int basicElmLen = GFP_FELEN(pBasicGFE); + int deg; + for(deg=0; degidCtx = (Ipp32u)ctxid ^ (Ipp32u)IPP_UINT_PTR(stt)) +#define HASH_RESET_ID(stt,ctxid) ((stt)->idCtx = (Ipp32u)ctxid) +#define HASH_ALG_ID(stt) ((stt)->algID) +#define HASH_LENLO(stt) ((stt)->msgLenLo) +#define HASH_LENHI(stt) ((stt)->msgLenHi) +#define HASH_FUNC(stt) ((stt)->hashProc) +#define HASH_FUNC_PAR(stt) ((stt)->pParam) +#define HASH_VALUE(stt) ((stt)->msgHash) +#define HASH_BUFFIDX(stt) ((stt)->msgBuffIdx) +#define HASH_BUFF(stt) ((stt)->msgBuffer) +#define HASH_VALID_ID(stt,ctxId) ((((stt)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((stt))) == (Ipp32u)ctxId) + + +/* initial hash values */ +extern const Ipp32u SHA1_IV[]; +extern const Ipp32u SHA256_IV[]; +extern const Ipp32u SHA224_IV[]; +extern const Ipp64u SHA512_IV[]; +extern const Ipp64u SHA384_IV[]; +extern const Ipp32u MD5_IV[]; +extern const Ipp32u SM3_IV[]; +extern const Ipp64u SHA512_224_IV[]; +extern const Ipp64u SHA512_256_IV[]; + +/* hash alg additive constants */ +extern __ALIGN16 const Ipp32u SHA1_cnt[]; +extern __ALIGN16 const Ipp32u SHA256_cnt[]; +extern __ALIGN16 const Ipp64u SHA512_cnt[]; +extern __ALIGN16 const Ipp32u MD5_cnt[]; +extern __ALIGN16 const Ipp32u SM3_cnt[]; + +/* hash alg opt argument */ +extern const void* cpHashProcFuncOpt[]; + +/* enabled hash alg */ +extern const IppHashAlgId cpEnabledHashAlgID[]; + +/* hash alg IV (init value) */ +extern const Ipp8u* cpHashIV[]; + +/* hash alg attribute DB */ +extern const cpHashAttr cpHashAlgAttr[]; + +/* IV size helper */ +__INLINE int cpHashIvSize(IppHashAlgId algID) +{ return cpHashAlgAttr[algID].ivSize; } + +/* hash size helper */ +__INLINE int cpHashSize(IppHashAlgId algID) +{ return cpHashAlgAttr[algID].hashSize; } + +/* message block size helper */ +__INLINE int cpHashMBS(IppHashAlgId algID) +{ return cpHashAlgAttr[algID].msgBlkSize; } + +/* maps algID into enabled IppHashAlgId value */ +__INLINE IppHashAlgId cpValidHashAlg(IppHashAlgId algID) +{ + /* maps algID into the valid range */ + algID = (((int)ippHashAlg_Unknown < (int)algID) && ((int)algID < (int)ippHashAlg_MaxNo))? algID : ippHashAlg_Unknown; + return cpEnabledHashAlgID[algID]; +} + +/* common functions */ +#define cpComputeDigest OWNAPI(cpComputeDigest) + IPP_OWN_DECL (void, cpComputeDigest, (Ipp8u* pHashTag, int hashTagLen, const IppsHashState* pCtx)) + +/* processing functions */ +#define UpdateSHA1 OWNAPI(UpdateSHA1) + IPP_OWN_DECL (void, UpdateSHA1, (void* pHash, const Ipp8u* mblk, int mlen, const void* pParam)) +#define UpdateSHA256 OWNAPI(UpdateSHA256) + IPP_OWN_DECL (void, UpdateSHA256, (void* pHash, const Ipp8u* mblk, int mlen, const void* pParam)) +#define UpdateSHA512 OWNAPI(UpdateSHA512) + IPP_OWN_DECL (void, UpdateSHA512, (void* pHash, const Ipp8u* mblk, int mlen, const void* pParam)) +#define UpdateMD5 OWNAPI(UpdateMD5) + IPP_OWN_DECL (void, UpdateMD5, (void* pHash, const Ipp8u* mblk, int mlen, const void* pParam)) +#define UpdateSM3 OWNAPI(UpdateSM3) + IPP_OWN_DECL (void, UpdateSM3, (void* pHash, const Ipp8u* mblk, int mlen, const void* pParam)) + +#if (_SHA_NI_ENABLING_ == _FEATURE_TICKTOCK_) || (_SHA_NI_ENABLING_ == _FEATURE_ON_) +#define UpdateSHA1ni OWNAPI(UpdateSHA1ni) + IPP_OWN_DECL (void, UpdateSHA1ni, (void* pHash, const Ipp8u* mblk, int mlen, const void* pParam)) +#define UpdateSHA256ni OWNAPI(UpdateSHA256ni) + IPP_OWN_DECL (void, UpdateSHA256ni, (void* pHash, const Ipp8u* mblk, int mlen, const void* pParam)) +#endif + +/* general methods */ +#define cpInitHash OWNAPI(cpInitHash) + IPP_OWN_DECL (int, cpInitHash, (IppsHashState* pCtx, IppHashAlgId algID)) +#define cpReInitHash OWNAPI(cpReInitHash) + IPP_OWN_DECL (int, cpReInitHash, (IppsHashState* pCtx, IppHashAlgId algID)) + +#endif /* _PCP_HASH_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphash_digest.c b/plugin/ippcp/library/src/sources/ippcp/pcphash_digest.c new file mode 100644 index 000000000..94819e3d8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphash_digest.c @@ -0,0 +1,126 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// cpComputeDigest() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + + +IPP_OWN_DEFN (void, cpComputeDigest, (Ipp8u* pHashTag, int hashTagLen, const IppsHashState* pCtx)) +{ + /* hash alg and parameters */ + cpHashProc hashFunc = HASH_FUNC(pCtx); /* processing function */ + const void* pParam = HASH_FUNC_PAR(pCtx); /* and it's addition params */ + + /* attributes */ + const cpHashAttr* pAttr = &cpHashAlgAttr[HASH_ALG_ID(pCtx)]; + int mbs = pAttr->msgBlkSize; /* data block size */ + int ivSize = pAttr->ivSize; /* size of hash's IV */ + int msgLenRepSize = pAttr->msgLenRepSize; /* length of the message representation */ + + /* number of bytes in context buffer */ + int n = HASH_BUFFIDX(pCtx); + /* buffer and it actual length */ + Ipp8u buffer[MBS_HASH_MAX*2]; + int bufferLen = n < (mbs-msgLenRepSize)? mbs : mbs*2; + + /* copy current hash value */ + cpHash hash; + CopyBlock(HASH_VALUE(pCtx), hash, ivSize); + + /* copy of state's buffer */ + CopyBlock(HASH_BUFF(pCtx), buffer, n); + /* end of message bit */ + buffer[n++] = 0x80; + /* padd buffer */ + PadBlock(0, buffer+n, bufferLen-n-msgLenRepSize); + + /* message length representation in bits (remember about big endian) */ + { + /* convert processed message length bytes ->bits */ + Ipp64u lo = HASH_LENLO(pCtx); + Ipp64u hi = HASH_LENHI(pCtx); + hi = LSL64(hi,3) | LSR64(lo,63-3); + lo = LSL64(lo,3); + + if(msgLenRepSize>(int)(sizeof(Ipp64u))) { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + ((Ipp64u*)(buffer+bufferLen))[-2] = hi; + #else + ((Ipp64u*)(buffer+bufferLen))[-2] = ENDIANNESS64(hi); + #endif + } + + /* recall about MD5 specific */ + if(ippHashAlg_MD5!=HASH_ALG_ID(pCtx)) { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + ((Ipp64u*)(buffer+bufferLen))[-1] = lo; + #else + ((Ipp64u*)(buffer+bufferLen))[-1] = ENDIANNESS64(lo); + #endif + } + else { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + ((Ipp64u*)(buffer+bufferLen))[-1] = ENDIANNESS64(lo); + #else + ((Ipp64u*)(buffer+bufferLen))[-1] = lo; + #endif + } + } + + /* copmplete hash computation */ + hashFunc(hash, buffer, bufferLen, pParam); + + /* store digest into the user buffer (remember digest in big endian) */ + if(msgLenRepSize>(int)(sizeof(Ipp64u))) { + /* ippHashAlg_SHA384, ippHashAlg_SHA512, ippHashAlg_SHA512_224 and ippHashAlg_SHA512_256 */ + hash[0] = ENDIANNESS64(hash[0]); + hash[1] = ENDIANNESS64(hash[1]); + hash[2] = ENDIANNESS64(hash[2]); + hash[3] = ENDIANNESS64(hash[3]); + hash[4] = ENDIANNESS64(hash[4]); + hash[5] = ENDIANNESS64(hash[5]); + hash[6] = ENDIANNESS64(hash[6]); + hash[7] = ENDIANNESS64(hash[7]); + } + else if(ippHashAlg_MD5!=HASH_ALG_ID(pCtx)) { + ((Ipp32u*)hash)[0] = ENDIANNESS32(((Ipp32u*)hash)[0]); + ((Ipp32u*)hash)[1] = ENDIANNESS32(((Ipp32u*)hash)[1]); + ((Ipp32u*)hash)[2] = ENDIANNESS32(((Ipp32u*)hash)[2]); + ((Ipp32u*)hash)[3] = ENDIANNESS32(((Ipp32u*)hash)[3]); + ((Ipp32u*)hash)[4] = ENDIANNESS32(((Ipp32u*)hash)[4]); + if(ippHashAlg_SHA1!=HASH_ALG_ID(pCtx)) { + ((Ipp32u*)hash)[5] = ENDIANNESS32(((Ipp32u*)hash)[5]); + ((Ipp32u*)hash)[6] = ENDIANNESS32(((Ipp32u*)hash)[6]); + ((Ipp32u*)hash)[7] = ENDIANNESS32(((Ipp32u*)hash)[7]); + } + } + CopyBlock(hash, pHashTag, hashTagLen); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphash_func.h b/plugin/ippcp/library/src/sources/ippcp/pcphash_func.h new file mode 100644 index 000000000..6b4254e9f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphash_func.h @@ -0,0 +1,108 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Internal Definitions and Internal Functions Prototypes +// +// +*/ + +#if !defined(_PCP_HASH_FUNC_H) +#define _PCP_HASH_FUNC_H + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" + +/* +// hash alg default processing functions and opt argument +*/ +static cpHashProc cpHashProcFunc[] = { + (cpHashProc)NULL, + + #if defined(_ENABLE_ALG_SHA1_) + #if(_SHA_NI_ENABLING_==_FEATURE_ON_) + UpdateSHA1ni, + #else + UpdateSHA1, + #endif + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA256_) + #if(_SHA_NI_ENABLING_==_FEATURE_ON_) + UpdateSHA256ni, + #else + UpdateSHA256, + #endif + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA224_) + #if(_SHA_NI_ENABLING_==_FEATURE_ON_) + UpdateSHA256ni, + #else + UpdateSHA256, + #endif + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA512_) + UpdateSHA512, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA384_) + UpdateSHA512, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_MD5_) + UpdateMD5, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SM3_) + UpdateSM3, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA512_224_) + UpdateSHA512, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA512_256_) + UpdateSHA512, + #else + NULL, + #endif +}; + +#endif /* _PCP_HASH_FUNC_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphash_init.c b/plugin/ippcp/library/src/sources/ippcp/pcphash_init.c new file mode 100644 index 000000000..0278c617e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphash_init.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// cpInitHash() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_func.h" +#include "pcptool.h" + +IPP_OWN_DEFN (int, cpInitHash, (IppsHashState* pCtx, IppHashAlgId algID)) +{ + /* setup default processing function */ + HASH_FUNC(pCtx) = cpHashProcFunc[algID]; + + /* update default processing function if Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) enabled */ + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if( IsFeatureEnabled(ippCPUID_SHA) ) { + + #if defined(_ENABLE_ALG_SHA1_) + if(ippHashAlg_SHA1==algID) + HASH_FUNC(pCtx) = UpdateSHA1ni; + #endif + + #if defined(_ENABLE_ALG_SHA256_) || defined(_ENABLE_ALG_SHA224_) + if(ippHashAlg_SHA256==algID || ippHashAlg_SHA224==algID) + HASH_FUNC(pCtx) = UpdateSHA256ni; + #endif + } + #endif + + /* setup optional agr of processing function */ + HASH_FUNC_PAR(pCtx) = cpHashProcFuncOpt[algID]; + + return cpReInitHash(pCtx, algID); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphash_reinit.c b/plugin/ippcp/library/src/sources/ippcp/pcphash_reinit.c new file mode 100644 index 000000000..0a88722ff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphash_reinit.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// cpReInitHash() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashInit +// +// Purpose: Init Hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsNotSupportedModeErr if algID is not match to supported hash alg +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer to the Hash state +// algID hash alg ID +// +*F*/ +IPP_OWN_DEFN (int, cpReInitHash, (IppsHashState* pCtx, IppHashAlgId algID)) +{ + int hashIvSize = cpHashIvSize(algID); + const Ipp8u* iv = cpHashIV[algID]; + + HASH_LENLO(pCtx) = CONST_64(0); + HASH_LENHI(pCtx) = CONST_64(0); + HASH_BUFFIDX(pCtx) = 0; + CopyBlock(iv, HASH_VALUE(pCtx), hashIvSize); + + return hashIvSize; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphash_rmf.h b/plugin/ippcp/library/src/sources/ippcp/pcphash_rmf.h new file mode 100644 index 000000000..b3741f457 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphash_rmf.h @@ -0,0 +1,48 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Internal Definitions and Internal Functions Prototypes +// +*/ + +#if !defined(_CP_HASH_RMF_H) +#define _CP_HASH_RMF_H + +#include "pcphash.h" +#include "pcphashmethod_rmf.h" + +struct _cpHashCtx_rmf { + Ipp32u idCtx; /* hash identifier */ + const cpHashMethod_rmf* pMethod; /* hash methods */ + int msgBuffIdx; /* buffer index */ + Ipp8u msgBuffer[MBS_HASH_MAX]; /* buffer */ + Ipp64u msgLenLo; /* processed message */ + Ipp64u msgLenHi; /* length (bytes) */ + cpHash msgHash; /* hash value */ +}; + +/* accessors (see others in pcphash.h) */ +#define HASH_METHOD(stt) ((stt)->pMethod) + +#define cpFinalize_rmf OWNAPI(cpFinalize_rmf) + IPP_OWN_DECL (void, cpFinalize_rmf, (DigestSHA512 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u lenLo, Ipp64u lenHi, const IppsHashMethod* method)) + +#endif /* _CP_HASH_RMF_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashca_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashca_rmf.c new file mode 100644 index 000000000..5240fdd03 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashca_rmf.c @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// cpFinalize_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + + +IPP_OWN_DEFN (void, cpFinalize_rmf, (DigestSHA512 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u lenLo, Ipp64u lenHi, const IppsHashMethod* method)) +{ + int mbs = method->msgBlkSize; /* messge block size */ + int mrl = method->msgLenRepSize; /* processed length representation size */ + + /* local buffer and it length */ + Ipp8u buffer[MBS_SHA512*2]; + int bufferLen = inpLen < (mbs-mrl)? mbs : mbs*2; + + /* copy rest of message into internal buffer */ + CopyBlock(inpBuffer, buffer, inpLen); + + /* padd message */ + buffer[inpLen++] = 0x80; + PadBlock(0, buffer+inpLen, bufferLen-inpLen-mrl); + + /* message length representation */ + method->msgLenRep(buffer+bufferLen-mrl, lenLo, lenHi); + + /* copmplete hash computation */ + method->hashUpdate(pHash, buffer, bufferLen); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashcnt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashcnt.c new file mode 100644 index 000000000..6a4c6f5fd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashcnt.c @@ -0,0 +1,435 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Constants +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" + +#if defined( _IPP_DATA ) + +/* +// enabled hash alg IDs +*/ +const IppHashAlgId cpEnabledHashAlgID[] = { + IPP_ALG_HASH_UNKNOWN, + +#if defined(_ENABLE_ALG_SHA1_) + IPP_ALG_HASH_SHA1, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_SHA256_) + IPP_ALG_HASH_SHA256, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_SHA224_) + IPP_ALG_HASH_SHA224, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_SHA512_) + IPP_ALG_HASH_SHA512, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_SHA384_) + IPP_ALG_HASH_SHA384, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_MD5_) + IPP_ALG_HASH_MD5, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_SM3_) + IPP_ALG_HASH_SM3, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_SHA512_224_) + IPP_ALG_HASH_SHA512_224, +#else + IPP_ALG_HASH_UNKNOWN, +#endif + +#if defined(_ENABLE_ALG_SHA512_256_) + IPP_ALG_HASH_SHA512_256 +#else + IPP_ALG_HASH_UNKNOWN +#endif +}; +//////////////////////////////////////////////////////////// + +/* +// hash init values +*/ +const Ipp32u UnknownHash_IV[] = { + 0}; + +#if defined(_ENABLE_ALG_SHA1_) +const Ipp32u SHA1_IV[] = { + 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}; +#endif + +#if defined(_ENABLE_ALG_SHA256_) +const Ipp32u SHA256_IV[] = { + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19}; +#endif + +#if defined(_ENABLE_ALG_SHA224_) +const Ipp32u SHA224_IV[] = { + 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, + 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4}; +#endif + +#if defined(_ENABLE_ALG_SHA512_) +const Ipp64u SHA512_IV[] = { + CONST_64(0x6A09E667F3BCC908), CONST_64(0xBB67AE8584CAA73B), + CONST_64(0x3C6EF372FE94F82B), CONST_64(0xA54FF53A5F1D36F1), + CONST_64(0x510E527FADE682D1), CONST_64(0x9B05688C2B3E6C1F), + CONST_64(0x1F83D9ABFB41BD6B), CONST_64(0x5BE0CD19137E2179)}; +#endif + +#if defined(_ENABLE_ALG_SHA384_) +const Ipp64u SHA384_IV[] = { + CONST_64(0xCBBB9D5DC1059ED8), CONST_64(0x629A292A367CD507), + CONST_64(0x9159015A3070DD17), CONST_64(0x152FECD8F70E5939), + CONST_64(0x67332667FFC00B31), CONST_64(0x8EB44A8768581511), + CONST_64(0xDB0C2E0D64F98FA7), CONST_64(0x47B5481DBEFA4FA4)}; +#endif + +#if defined(_ENABLE_ALG_MD5_) +const Ipp32u MD5_IV[] = { + 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476}; +#endif + +#if defined(_ENABLE_ALG_SM3_) +const Ipp32u SM3_IV[] = { + 0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600, + 0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E}; +#endif + +#if defined(_ENABLE_ALG_SHA512_224_) +const Ipp64u SHA512_224_IV[] = { + CONST_64(0x8C3D37C819544DA2), CONST_64(0x73E1996689DCD4D6), + CONST_64(0x1DFAB7AE32FF9C82), CONST_64(0x679DD514582F9FCF), + CONST_64(0x0F6D2B697BD44DA8), CONST_64(0x77E36F7304C48942), + CONST_64(0x3F9D85A86A1D36C8), CONST_64(0x1112E6AD91D692A1)}; +#endif + +#if defined(_ENABLE_ALG_SHA512_256_) +const Ipp64u SHA512_256_IV[] = { + CONST_64(0x22312194FC2BF72C), CONST_64(0x9F555FA3C84C64C2), + CONST_64(0x2393B86B6F53B151), CONST_64(0x963877195940EABD), + CONST_64(0x96283EE2A88EFFE3), CONST_64(0xBE5E1E2553863992), + CONST_64(0x2B0199FC2C85B8AA), CONST_64(0x0EB72DDC81C52CA2)}; +#endif + +const Ipp8u* cpHashIV[] = { + (Ipp8u*)UnknownHash_IV, + + #if defined(_ENABLE_ALG_SHA1_) + (Ipp8u*)SHA1_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_SHA256_) + (Ipp8u*)SHA256_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_SHA224_) + (Ipp8u*)SHA224_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_SHA512_) + (Ipp8u*)SHA512_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_SHA384_) + (Ipp8u*)SHA384_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_MD5_) + (Ipp8u*)MD5_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_SM3_) + (Ipp8u*)SM3_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_SHA512_224_) + (Ipp8u*)SHA512_224_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif + + #if defined(_ENABLE_ALG_SHA512_256_) + (Ipp8u*)SHA512_256_IV, + #else + (Ipp8u*)UnknownHash_IV, + #endif +}; + +//////////////////////////////////////////////////////////// + +/* +// additive constatns +*/ +#if defined(_ENABLE_ALG_SHA1_) +__ALIGN16 const Ipp32u SHA1_cnt[] = { + 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 +}; +#endif + +#if defined(_ENABLE_ALG_SHA256_) || defined(_ENABLE_ALG_SHA224_) +__ALIGN16 const Ipp32u SHA256_cnt[] = { + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 +}; +#endif + +#if defined(_ENABLE_ALG_SHA512_) || defined(_ENABLE_ALG_SHA384_) || defined(_ENABLE_ALG_SHA512_224_) || defined(_ENABLE_ALG_SHA512_256_) +__ALIGN16 const Ipp64u SHA512_cnt[] = { + CONST_64(0x428A2F98D728AE22), CONST_64(0x7137449123EF65CD), CONST_64(0xB5C0FBCFEC4D3B2F), CONST_64(0xE9B5DBA58189DBBC), + CONST_64(0x3956C25BF348B538), CONST_64(0x59F111F1B605D019), CONST_64(0x923F82A4AF194F9B), CONST_64(0xAB1C5ED5DA6D8118), + CONST_64(0xD807AA98A3030242), CONST_64(0x12835B0145706FBE), CONST_64(0x243185BE4EE4B28C), CONST_64(0x550C7DC3D5FFB4E2), + CONST_64(0x72BE5D74F27B896F), CONST_64(0x80DEB1FE3B1696B1), CONST_64(0x9BDC06A725C71235), CONST_64(0xC19BF174CF692694), + CONST_64(0xE49B69C19EF14AD2), CONST_64(0xEFBE4786384F25E3), CONST_64(0x0FC19DC68B8CD5B5), CONST_64(0x240CA1CC77AC9C65), + CONST_64(0x2DE92C6F592B0275), CONST_64(0x4A7484AA6EA6E483), CONST_64(0x5CB0A9DCBD41FBD4), CONST_64(0x76F988DA831153B5), + CONST_64(0x983E5152EE66DFAB), CONST_64(0xA831C66D2DB43210), CONST_64(0xB00327C898FB213F), CONST_64(0xBF597FC7BEEF0EE4), + CONST_64(0xC6E00BF33DA88FC2), CONST_64(0xD5A79147930AA725), CONST_64(0x06CA6351E003826F), CONST_64(0x142929670A0E6E70), + CONST_64(0x27B70A8546D22FFC), CONST_64(0x2E1B21385C26C926), CONST_64(0x4D2C6DFC5AC42AED), CONST_64(0x53380D139D95B3DF), + CONST_64(0x650A73548BAF63DE), CONST_64(0x766A0ABB3C77B2A8), CONST_64(0x81C2C92E47EDAEE6), CONST_64(0x92722C851482353B), + CONST_64(0xA2BFE8A14CF10364), CONST_64(0xA81A664BBC423001), CONST_64(0xC24B8B70D0F89791), CONST_64(0xC76C51A30654BE30), + CONST_64(0xD192E819D6EF5218), CONST_64(0xD69906245565A910), CONST_64(0xF40E35855771202A), CONST_64(0x106AA07032BBD1B8), + CONST_64(0x19A4C116B8D2D0C8), CONST_64(0x1E376C085141AB53), CONST_64(0x2748774CDF8EEB99), CONST_64(0x34B0BCB5E19B48A8), + CONST_64(0x391C0CB3C5C95A63), CONST_64(0x4ED8AA4AE3418ACB), CONST_64(0x5B9CCA4F7763E373), CONST_64(0x682E6FF3D6B2B8A3), + CONST_64(0x748F82EE5DEFB2FC), CONST_64(0x78A5636F43172F60), CONST_64(0x84C87814A1F0AB72), CONST_64(0x8CC702081A6439EC), + CONST_64(0x90BEFFFA23631E28), CONST_64(0xA4506CEBDE82BDE9), CONST_64(0xBEF9A3F7B2C67915), CONST_64(0xC67178F2E372532B), + CONST_64(0xCA273ECEEA26619C), CONST_64(0xD186B8C721C0C207), CONST_64(0xEADA7DD6CDE0EB1E), CONST_64(0xF57D4F7FEE6ED178), + CONST_64(0x06F067AA72176FBA), CONST_64(0x0A637DC5A2C898A6), CONST_64(0x113F9804BEF90DAE), CONST_64(0x1B710B35131C471B), + CONST_64(0x28DB77F523047D84), CONST_64(0x32CAAB7B40C72493), CONST_64(0x3C9EBE0A15C9BEBC), CONST_64(0x431D67C49C100D4C), + CONST_64(0x4CC5D4BECB3E42B6), CONST_64(0x597F299CFC657E2A), CONST_64(0x5FCB6FAB3AD6FAEC), CONST_64(0x6C44198C4A475817) +}; +#endif + +#if defined(_ENABLE_ALG_MD5_) +__ALIGN16 const Ipp32u MD5_cnt[] = { + 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, + 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, + 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, + 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, + + 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, + 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, + 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, + 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, + + 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, + 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, + 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, + 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, + + 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, + 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, + 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, + 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 +}; +#endif + +#if defined(_ENABLE_ALG_SM3_) +__ALIGN16 const Ipp32u SM3_cnt[] = { + 0x79CC4519,0xF3988A32,0xE7311465,0xCE6228CB,0x9CC45197,0x3988A32F,0x7311465E,0xE6228CBC, + 0xCC451979,0x988A32F3,0x311465E7,0x6228CBCE,0xC451979C,0x88A32F39,0x11465E73,0x228CBCE6, + 0x9D8A7A87,0x3B14F50F,0x7629EA1E,0xEC53D43C,0xD8A7A879,0xB14F50F3,0x629EA1E7,0xC53D43CE, + 0x8A7A879D,0x14F50F3B,0x29EA1E76,0x53D43CEC,0xA7A879D8,0x4F50F3B1,0x9EA1E762,0x3D43CEC5, + 0x7A879D8A,0xF50F3B14,0xEA1E7629,0xD43CEC53,0xA879D8A7,0x50F3B14F,0xA1E7629E,0x43CEC53D, + 0x879D8A7A,0x0F3B14F5,0x1E7629EA,0x3CEC53D4,0x79D8A7A8,0xF3B14F50,0xE7629EA1,0xCEC53D43, + 0x9D8A7A87,0x3B14F50F,0x7629EA1E,0xEC53D43C,0xD8A7A879,0xB14F50F3,0x629EA1E7,0xC53D43CE, + 0x8A7A879D,0x14F50F3B,0x29EA1E76,0x53D43CEC,0xA7A879D8,0x4F50F3B1,0x9EA1E762,0x3D43CEC5 +}; +#endif + +/* +// hash alg default processing opt argument +*/ +const void* cpHashProcFuncOpt[] = { + NULL, + + #if defined(_ENABLE_ALG_SHA1_) + SHA1_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA256_) + SHA256_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA224_) + SHA256_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA512_) + SHA512_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA384_) + SHA512_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_MD5_) + MD5_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SM3_) + SM3_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA512_224_) + SHA512_cnt, + #else + NULL, + #endif + + #if defined(_ENABLE_ALG_SHA512_256_) + SHA512_cnt, + #else + NULL, + #endif +}; +//////////////////////////////////////////////////////////// + +/* hash alg attributes */ +const cpHashAttr cpHashAlgAttr[] = { + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, /* unknown */ + +#if defined(_ENABLE_ALG_SHA1_) /* sha1 / unknown */ + {IPP_SHA1_DIGEST_BITSIZE/8, IPP_SHA1_DIGEST_BITSIZE/8, MBS_SHA1, sizeof(Ipp64u), {CONST_64(0x2000000000000000-1),CONST_64(0)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_SHA256_) /* sha256 / unknown */ + {IPP_SHA256_DIGEST_BITSIZE/8,IPP_SHA256_DIGEST_BITSIZE/8, MBS_SHA256, sizeof(Ipp64u), {CONST_64(0x2000000000000000-1),CONST_64(0)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_SHA224_) /* sha224 / unknown */ + {IPP_SHA256_DIGEST_BITSIZE/8,IPP_SHA224_DIGEST_BITSIZE/8, MBS_SHA224, sizeof(Ipp64u), {CONST_64(0x2000000000000000-1),CONST_64(0)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_SHA512_) /* sha512 / unknown */ + {IPP_SHA512_DIGEST_BITSIZE/8,IPP_SHA512_DIGEST_BITSIZE/8, MBS_SHA512, sizeof(Ipp64u)*2, {CONST_64(0xFFFFFFFFFFFFFFFF),CONST_64(0x2000000000000000-1)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_SHA384_) /* sha384 / unknown */ + {IPP_SHA512_DIGEST_BITSIZE/8,IPP_SHA384_DIGEST_BITSIZE/8, MBS_SHA384, sizeof(Ipp64u)*2, {CONST_64(0xFFFFFFFFFFFFFFFF),CONST_64(0x2000000000000000-1)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_MD5_) /* md5 / unknown */ + {IPP_MD5_DIGEST_BITSIZE/8,IPP_MD5_DIGEST_BITSIZE/8, MBS_MD5, sizeof(Ipp64u), {CONST_64(0x2000000000000000-1),CONST_64(0)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_SM3_) /* sm3 / unknown */ + {IPP_SM3_DIGEST_BITSIZE/8,IPP_SM3_DIGEST_BITSIZE/8, MBS_SM3, sizeof(Ipp64u), {CONST_64(0x2000000000000000-1),CONST_64(0)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_SHA512_224_) /* sha512/224 / unknown */ + {IPP_SHA512_DIGEST_BITSIZE/8,IPP_SHA512_224_DIGEST_BITSIZE/8, MBS_SHA512, sizeof(Ipp64u)*2, {CONST_64(0xFFFFFFFFFFFFFFFF),CONST_64(0x2000000000000000-1)}}, +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}}, +#endif + +#if defined(_ENABLE_ALG_SHA512_256_) /* sha512/256 / unknown */ + {IPP_SHA512_DIGEST_BITSIZE/8,IPP_SHA512_256_DIGEST_BITSIZE/8, MBS_SHA512, sizeof(Ipp64u)*2, {CONST_64(0xFFFFFFFFFFFFFFFF),CONST_64(0x2000000000000000-1)}} +#else + {0, 0, 0, 0, {CONST_64(0),CONST_64(0)}} +#endif +}; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashduplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcphashduplicate.c new file mode 100644 index 000000000..c1d636ee9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashduplicate.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashDuplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashDuplicate +// +// Purpose: Clone Hash context. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxHash +// pDstState->idCtx != idCtxHash +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source Hash context +// pDstState pointer to the target Hash context +// +// Note: +// pDstState may to be uninitialized by ippsHashInit() +// +*F*/ +IPPFUN(IppStatus, ippsHashDuplicate,(const IppsHashState* pSrcState, IppsHashState* pDstState)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcState, pDstState); + /* test states ID */ + IPP_BADARG_RET(!HASH_VALID_ID(pSrcState, idCtxHash), ippStsContextMatchErr); + + /* copy state */ + CopyBlock(pSrcState, pDstState, sizeof(IppsHashState)); + HASH_SET_ID(pDstState, idCtxHash); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashduplicate_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashduplicate_rmf.c new file mode 100644 index 000000000..866367e00 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashduplicate_rmf.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashDuplicate_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashDuplicate_rmf +// +// Purpose: Clone Hash context. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxHash +// pDstState->idCtx != idCtxHash +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source Hash context +// pDstState pointer to the target Hash context +// +// Note: +// pDstState may to be uninitialized by ippsHashInit_rmf() +// +*F*/ +IPPFUN(IppStatus, ippsHashDuplicate_rmf,(const IppsHashState_rmf* pSrcState, IppsHashState_rmf* pDstState)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcState, pDstState); + /* test states ID */ + IPP_BADARG_RET(!HASH_VALID_ID(pSrcState,idCtxHash), ippStsContextMatchErr); + + /* copy state */ + CopyBlock(pSrcState, pDstState, sizeof(IppsHashState_rmf)); + HASH_SET_ID(pDstState, idCtxHash); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashfinal.c b/plugin/ippcp/library/src/sources/ippcp/pcphashfinal.c new file mode 100644 index 000000000..97cc4fb7a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashfinal.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashFinal() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + + +/*F* +// Name: ippsHashFinal +// +// Purpose: Complete message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHash +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SHS state +// +*F*/ +IPPFUN(IppStatus, ippsHashFinal,(Ipp8u* pMD, IppsHashState* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR2_RET(pMD, pState); + /* test the context */ + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + + { + IppHashAlgId algID = HASH_ALG_ID(pState); + int hashSize = cpHashAlgAttr[algID].hashSize; + + cpComputeDigest(pMD, hashSize, pState); + cpReInitHash(pState, algID); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashfinal_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashfinal_rmf.c new file mode 100644 index 000000000..5c1132dc7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashfinal_rmf.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashFinal_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + + +/*F* +// Name: ippsHashFinal_rmf +// +// Purpose: Complete message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHash +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SHS state +// +*F*/ +IPPFUN(IppStatus, ippsHashFinal_rmf,(Ipp8u* pMD, IppsHashState_rmf* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR2_RET(pMD, pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + + { + const IppsHashMethod* method = HASH_METHOD(pState); + + cpFinalize_rmf(HASH_VALUE(pState), + HASH_BUFF(pState), HASH_BUFFIDX(pState), + HASH_LENLO(pState), HASH_LENHI(pState), + method); + /* convert hash into oct string */ + method->hashOctStr(pMD, HASH_VALUE(pState)); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + HASH_LENHI(pState) = 0; + method->hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashgetinfo_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashgetinfo_rmf.c new file mode 100644 index 000000000..11109a9ec --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashgetinfo_rmf.c @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashMethodGetInfo() +// ippsHashGetInfo_rmf() +// +*/ + +#include "owncp.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsHashMethodGetInfo +// +// Purpose: Returns info of the Hash algorithm +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pMethod +// NULL == pInfo +// +// ippStsNoErr no error +// +// Parameters: +// pInfo Pointer to the info structure +// pMethod Pointer to the IppsHashMethod +// +*F*/ +IPPFUN(IppStatus, ippsHashMethodGetInfo,(IppsHashInfo* pInfo, const IppsHashMethod* pMethod)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pInfo, pMethod); + + pInfo->hashSize = pMethod->hashLen; + pInfo->msgBlockSize = pMethod->msgBlkSize; + + return ippStsNoErr; +} + +/*F* +// Name: ippsHashGetInfo_rmf +// +// Purpose: Returns info of the using Hash +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pState +// NULL == pInfo +// +// ippStsContextMatchErr invalid pState->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pInfo Pointer to the info structure +// pState Pointer to the state context +// +*F*/ +IPPFUN(IppStatus, ippsHashGetInfo_rmf,(IppsHashInfo* pInfo, const IppsHashState_rmf* pState)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pInfo, pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + + pInfo->hashSize = HASH_METHOD(pState)->hashLen; + pInfo->msgBlockSize = HASH_METHOD(pState)->msgBlkSize; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcphashgetsize.c new file mode 100644 index 000000000..015a79d10 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashgetsize.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashGetSize +// +// Purpose: Returns size (bytes) of IppsHashState state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ +IPPFUN(IppStatus, ippsHashGetSize,(int* pSize)) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsHashState); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashgetsize_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashgetsize_rmf.c new file mode 100644 index 000000000..cdf2f5b5d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashgetsize_rmf.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashGetSize_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashGetSize_rmf +// +// Purpose: Returns size (bytes) of IppsHashState state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ +IPPFUN(IppStatus, ippsHashGetSize_rmf,(int* pSize)) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsHashState_rmf); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashgettag.c b/plugin/ippcp/library/src/sources/ippcp/pcphashgettag.c new file mode 100644 index 000000000..d01cab5b5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashgettag.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashGetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashGetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHash +// ippStsLengthErr hashSize < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHS state +// +*F*/ +IPPFUN(IppStatus, ippsHashGetTag,(Ipp8u* pTag, int tagLen, const IppsHashState* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR2_RET(pTag, pState); + /* test the context */ + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + + { + /* size of hash */ + int hashSize = cpHashAlgAttr[HASH_ALG_ID(pState)].hashSize; + if(tagLen<1||hashSizeidCtx != idCtxHash +// ippStsLengthErr hashSize < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHS state +// +*F*/ +IPPFUN(IppStatus, ippsHashGetTag_rmf,(Ipp8u* pTag, int tagLen, const IppsHashState_rmf* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen <1) || HASH_METHOD(pState)->hashLenhashOctStr(pTag, hash); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashinit.c b/plugin/ippcp/library/src/sources/ippcp/pcphashinit.c new file mode 100644 index 000000000..18a076f93 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashinit.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashInit +// +// Purpose: Init Hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsNoErr no errors +// +// Parameters: +// pState pointer to the SHA1 state +// hashAlg identifier of the hash algorithm +// +*F*/ + +IPPFUN(IppStatus, ippsHashInit,(IppsHashState* pState, IppHashAlgId hashAlg)) +{ + /* get algorithm id */ + hashAlg = cpValidHashAlg(hashAlg); + /* test hash alg */ + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + + /* test ctx pointer */ + IPP_BAD_PTR1_RET(pState); + /* test hash alg */ + + /* set ctx ID */ + HASH_SET_ID(pState, idCtxHash); + HASH_ALG_ID(pState) = hashAlg; + + /* init context */ + cpInitHash(pState, hashAlg); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashinit_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashinit_rmf.c new file mode 100644 index 000000000..ece390c14 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashinit_rmf.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashInit_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashInit_rmf +// +// Purpose: Init Hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pMethod == NULL +// ippStsNoErr no errors +// +// Parameters: +// pState pointer to the Hash state +// pMethod hash method +// +*F*/ +IPPFUN(IppStatus, ippsHashInit_rmf,(IppsHashState_rmf* pState, const IppsHashMethod* pMethod)) +{ + /* test ctx pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + PadBlock(0, pState, sizeof(IppsHashState_rmf)); + HASH_METHOD(pState) = pMethod; + HASH_SET_ID(pState, idCtxHash); + pMethod->hashInit(HASH_VALUE(pState)); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmd5px.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmd5px.c new file mode 100644 index 000000000..b9c6aefa6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmd5px.c @@ -0,0 +1,206 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message block processing according to MD5 +// +// Contents: +// UpdateMD5() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +#if defined(_ENABLE_ALG_MD5_) + +#if !((_IPP==_IPP_M5) || \ + (_IPP==_IPP_W7) || (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || (_IPP==_IPP_P8) || \ + (_IPP==_IPP_S8) || (_IPP>=_IPP_G9) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) + + +/* +// Magic functions defined in RFC 1321 +// +*/ +#define F(X,Y,Z) ((Z) ^ ((X) & ((Y) ^ (Z)))) /* sightly optimized form of (((X) & (Y)) | ((~(X) & (Z)))*/ +#define G(X,Y,Z) F((Z),(X),(Y)) /* replace the original (((X) & (Z)) | ((Y) & ~(Z))) */ +#define H(X,Y,Z) ((X) ^ (Y) ^ (Z)) +#define I(X,Y,Z) ((Y) ^ ((X) | ~(Z))) + +/* +// MD5 step +*/ +#define MD5_STEP(MAGIC, A,B,C,D, data, constant, nrot) \ + (A = B +ROL32((A +MAGIC(B,C,D) +data +constant), nrot)) + +/* +// MD5 left rotations (number of bits) +// depends on round type +*/ +#define F1 7 +#define F2 12 +#define F3 17 +#define F4 22 + +#define G1 5 +#define G2 9 +#define G3 14 +#define G4 20 + +#define H1 4 +#define H2 11 +#define H3 16 +#define H4 23 + +#define I1 6 +#define I2 10 +#define I3 15 +#define I4 21 + +/*F* +// Name: UpdateMD5 +// +// Purpose: Update internal hash according to input message stream. +// +// Parameters: +// uniHash pointer to in/out hash +// mblk pointer to message stream +// mlen message stream length (multiple by message block size) +// uniParam pointer to the optional parameter +// +*F*/ +IPP_OWN_DEFN (void, UpdateMD5, (void* uinHash, const Ipp8u* mblk, int mlen, const void* uniParam)) +{ + Ipp32u* digest = (Ipp32u*)uinHash; + Ipp32u* MD5_cnt_loc = (Ipp32u*)uniParam; + + for(; mlen>=MBS_MD5; mblk += MBS_MD5, mlen -= MBS_MD5) { + + /* allocate data */ + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + Ipp32u data[MBS_MD5/sizeof(Ipp32u)]; + #else + /* or just word alias */ + Ipp32u* data = (Ipp32u*)mblk; + #endif + + /* init variables */ + Ipp32u a = digest[0]; + Ipp32u b = digest[1]; + Ipp32u c = digest[2]; + Ipp32u d = digest[3]; + + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + int t; + for(t=0; t<16; t++) { + data[t] = ENDIANNESS(((Ipp32u*)mblk)[t]); + } + #endif + + /* rounds type F */ + MD5_STEP(F, a,b,c,d, data[ 0], MD5_cnt_loc[ 0], F1); + MD5_STEP(F, d,a,b,c, data[ 1], MD5_cnt_loc[ 1], F2); + MD5_STEP(F, c,d,a,b, data[ 2], MD5_cnt_loc[ 2], F3); + MD5_STEP(F, b,c,d,a, data[ 3], MD5_cnt_loc[ 3], F4); + MD5_STEP(F, a,b,c,d, data[ 4], MD5_cnt_loc[ 4], F1); + MD5_STEP(F, d,a,b,c, data[ 5], MD5_cnt_loc[ 5], F2); + MD5_STEP(F, c,d,a,b, data[ 6], MD5_cnt_loc[ 6], F3); + MD5_STEP(F, b,c,d,a, data[ 7], MD5_cnt_loc[ 7], F4); + MD5_STEP(F, a,b,c,d, data[ 8], MD5_cnt_loc[ 8], F1); + MD5_STEP(F, d,a,b,c, data[ 9], MD5_cnt_loc[ 9], F2); + MD5_STEP(F, c,d,a,b, data[10], MD5_cnt_loc[10], F3); + MD5_STEP(F, b,c,d,a, data[11], MD5_cnt_loc[11], F4); + MD5_STEP(F, a,b,c,d, data[12], MD5_cnt_loc[12], F1); + MD5_STEP(F, d,a,b,c, data[13], MD5_cnt_loc[13], F2); + MD5_STEP(F, c,d,a,b, data[14], MD5_cnt_loc[14], F3); + MD5_STEP(F, b,c,d,a, data[15], MD5_cnt_loc[15], F4); + + /* rounds type G */ + MD5_STEP(G, a,b,c,d, data[ 1], MD5_cnt_loc[16], G1); + MD5_STEP(G, d,a,b,c, data[ 6], MD5_cnt_loc[17], G2); + MD5_STEP(G, c,d,a,b, data[11], MD5_cnt_loc[18], G3); + MD5_STEP(G, b,c,d,a, data[ 0], MD5_cnt_loc[19], G4); + MD5_STEP(G, a,b,c,d, data[ 5], MD5_cnt_loc[20], G1); + MD5_STEP(G, d,a,b,c, data[10], MD5_cnt_loc[21], G2); + MD5_STEP(G, c,d,a,b, data[15], MD5_cnt_loc[22], G3); + MD5_STEP(G, b,c,d,a, data[ 4], MD5_cnt_loc[23], G4); + MD5_STEP(G, a,b,c,d, data[ 9], MD5_cnt_loc[24], G1); + MD5_STEP(G, d,a,b,c, data[14], MD5_cnt_loc[25], G2); + MD5_STEP(G, c,d,a,b, data[ 3], MD5_cnt_loc[26], G3); + MD5_STEP(G, b,c,d,a, data[ 8], MD5_cnt_loc[27], G4); + MD5_STEP(G, a,b,c,d, data[13], MD5_cnt_loc[28], G1); + MD5_STEP(G, d,a,b,c, data[ 2], MD5_cnt_loc[29], G2); + MD5_STEP(G, c,d,a,b, data[ 7], MD5_cnt_loc[30], G3); + MD5_STEP(G, b,c,d,a, data[12], MD5_cnt_loc[31], G4); + + /* rounds type H */ + MD5_STEP(H, a,b,c,d, data[ 5], MD5_cnt_loc[32], H1); + MD5_STEP(H, d,a,b,c, data[ 8], MD5_cnt_loc[33], H2); + MD5_STEP(H, c,d,a,b, data[11], MD5_cnt_loc[34], H3); + MD5_STEP(H, b,c,d,a, data[14], MD5_cnt_loc[35], H4); + MD5_STEP(H, a,b,c,d, data[ 1], MD5_cnt_loc[36], H1); + MD5_STEP(H, d,a,b,c, data[ 4], MD5_cnt_loc[37], H2); + MD5_STEP(H, c,d,a,b, data[ 7], MD5_cnt_loc[38], H3); + MD5_STEP(H, b,c,d,a, data[10], MD5_cnt_loc[39], H4); + MD5_STEP(H, a,b,c,d, data[13], MD5_cnt_loc[40], H1); + MD5_STEP(H, d,a,b,c, data[ 0], MD5_cnt_loc[41], H2); + MD5_STEP(H, c,d,a,b, data[ 3], MD5_cnt_loc[42], H3); + MD5_STEP(H, b,c,d,a, data[ 6], MD5_cnt_loc[43], H4); + MD5_STEP(H, a,b,c,d, data[ 9], MD5_cnt_loc[44], H1); + MD5_STEP(H, d,a,b,c, data[12], MD5_cnt_loc[45], H2); + MD5_STEP(H, c,d,a,b, data[15], MD5_cnt_loc[46], H3); + MD5_STEP(H, b,c,d,a, data[ 2], MD5_cnt_loc[47], H4); + + /* rounds type I */ + MD5_STEP(I, a,b,c,d, data[ 0], MD5_cnt_loc[48], I1); + MD5_STEP(I, d,a,b,c, data[ 7], MD5_cnt_loc[49], I2); + MD5_STEP(I, c,d,a,b, data[14], MD5_cnt_loc[50], I3); + MD5_STEP(I, b,c,d,a, data[ 5], MD5_cnt_loc[51], I4); + MD5_STEP(I, a,b,c,d, data[12], MD5_cnt_loc[52], I1); + MD5_STEP(I, d,a,b,c, data[ 3], MD5_cnt_loc[53], I2); + MD5_STEP(I, c,d,a,b, data[10], MD5_cnt_loc[54], I3); + MD5_STEP(I, b,c,d,a, data[ 1], MD5_cnt_loc[55], I4); + MD5_STEP(I, a,b,c,d, data[ 8], MD5_cnt_loc[56], I1); + MD5_STEP(I, d,a,b,c, data[15], MD5_cnt_loc[57], I2); + MD5_STEP(I, c,d,a,b, data[ 6], MD5_cnt_loc[58], I3); + MD5_STEP(I, b,c,d,a, data[13], MD5_cnt_loc[59], I4); + MD5_STEP(I, a,b,c,d, data[ 4], MD5_cnt_loc[60], I1); + MD5_STEP(I, d,a,b,c, data[11], MD5_cnt_loc[61], I2); + MD5_STEP(I, c,d,a,b, data[ 2], MD5_cnt_loc[62], I3); + MD5_STEP(I, b,c,d,a, data[ 9], MD5_cnt_loc[63], I4); + + /* update digest */ + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; + } +} + +#endif +#endif /* IPP_ALG_HASH_MD5 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmessage.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmessage.c new file mode 100644 index 000000000..5a738222f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmessage.c @@ -0,0 +1,145 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashMessage() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_func.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashMessage +// +// Purpose: Hash of the whole message. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pMsg == NULL but len!=0 +// ippStsLengthErr len <0 +// ippStsNotSupportedModeErr if hashAlg is not match to supported hash alg +// ippStsNoErr no errors +// +// Parameters: +// pMsg pointer to the input message +// len input message length +// pMD address of the output digest +// hashAlg hash alg ID +// +*F*/ +IPPFUN(IppStatus, ippsHashMessage,(const Ipp8u* pMsg, int len, Ipp8u* pMD, IppHashAlgId hashAlg)) +{ + /* get algorithm id */ + hashAlg = cpValidHashAlg(hashAlg); + /* test hash alg */ + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + /* test message length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((len && !pMsg), ippStsNullPtrErr); + + { + /* processing function and parameter */ + cpHashProc hashFunc = cpHashProcFunc[hashAlg]; + const void* pParam = cpHashProcFuncOpt[hashAlg]; + + /* attributes */ + const cpHashAttr* pAttr = &cpHashAlgAttr[hashAlg]; + int mbs = pAttr->msgBlkSize; /* data block size */ + int ivSize = pAttr->ivSize; /* size of hash's IV */ + int hashSize = pAttr->hashSize; /* hash size */ + int msgLenRepSize = pAttr->msgLenRepSize; /* length of the message representation */ + + /* message bitlength representation */ + Ipp64u msgLenBits = (Ipp64u)len*8; + /* length of main message part */ + int msgLenBlks = len & (-mbs); + /* rest of message length */ + int msgLenRest = len - msgLenBlks; + + /* end of message buffer */ + Ipp8u buffer[MBS_HASH_MAX*2]; + int bufferLen = (msgLenRest < (mbs-msgLenRepSize))? mbs : mbs*2; + + /* init hash */ + cpHash hash; + const Ipp8u* iv = cpHashIV[hashAlg]; + CopyBlock(iv, hash, ivSize); + + /*construct last messge block(s) */ + #define MSG_LEN_REP (sizeof(Ipp64u)) + + /* copy end of message */ + CopyBlock(pMsg+len-msgLenRest, buffer, msgLenRest); + /* end of message bit */ + buffer[msgLenRest++] = 0x80; + /* padd buffer */ + PadBlock(0, buffer+msgLenRest, (cpSize)(bufferLen-msgLenRest-(int)MSG_LEN_REP)); + /* copy message bitlength representation */ + if(ippHashAlg_MD5!=hashAlg) + msgLenBits = ENDIANNESS64(msgLenBits); + ((Ipp64u*)(buffer+bufferLen))[-1] = msgLenBits; + + #undef MSG_LEN_REP + + /* message processing */ + if(msgLenBlks) + hashFunc(hash, pMsg, msgLenBlks, pParam); + hashFunc(hash, buffer, bufferLen, pParam); + + /* store digest into the user buffer (remember digest in big endian) */ + if(msgLenRepSize > (int)(sizeof(Ipp64u))) { + /* ippHashAlg_SHA384, ippHashAlg_SHA512, ippHashAlg_SHA512_224 and ippHashAlg_SHA512_256 */ + hash[0] = ENDIANNESS64(hash[0]); + hash[1] = ENDIANNESS64(hash[1]); + hash[2] = ENDIANNESS64(hash[2]); + hash[3] = ENDIANNESS64(hash[3]); + hash[4] = ENDIANNESS64(hash[4]); + hash[5] = ENDIANNESS64(hash[5]); + hash[6] = ENDIANNESS64(hash[6]); + hash[7] = ENDIANNESS64(hash[7]); + } + else if(ippHashAlg_MD5!=hashAlg) { + /* ippHashAlg_SHA1, ippHashAlg_SHA224, ippHashAlg_SHA256 and ippHashAlg_SM3 */ + ((Ipp32u*)hash)[0] = ENDIANNESS32(((Ipp32u*)hash)[0]); + ((Ipp32u*)hash)[1] = ENDIANNESS32(((Ipp32u*)hash)[1]); + ((Ipp32u*)hash)[2] = ENDIANNESS32(((Ipp32u*)hash)[2]); + ((Ipp32u*)hash)[3] = ENDIANNESS32(((Ipp32u*)hash)[3]); + ((Ipp32u*)hash)[4] = ENDIANNESS32(((Ipp32u*)hash)[4]); + ((Ipp32u*)hash)[5] = ENDIANNESS32(((Ipp32u*)hash)[5]); + ((Ipp32u*)hash)[6] = ENDIANNESS32(((Ipp32u*)hash)[6]); + ((Ipp32u*)hash)[7] = ENDIANNESS32(((Ipp32u*)hash)[7]); + } + CopyBlock(hash, pMD, hashSize); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmessage_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmessage_rmf.c new file mode 100644 index 000000000..389557b8a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmessage_rmf.c @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashMessage_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashMessage_rmf +// +// Purpose: Hash of the whole message. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pMsg == NULL but len!=0 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pMsg pointer to the input message +// len input message length +// pMD address of the output digest +// pMethod hash methods +// +*F*/ +IPPFUN(IppStatus, ippsHashMessage_rmf,(const Ipp8u* pMsg, int len, Ipp8u* pMD, const IppsHashMethod* pMethod)) +{ + /* test method pointer */ + IPP_BAD_PTR1_RET(pMethod); + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + /* test message length */ + IPP_BADARG_RET(0>len, ippStsLengthErr); + IPP_BADARG_RET((len && !pMsg), ippStsNullPtrErr); + + { + /* message length in the multiple MBS and the rest */ + int msgLenBlks = len &(-pMethod->msgBlkSize); + int msgLenRest = len - msgLenBlks; + + /* init hash */ + DigestSHA512 hash; + pMethod->hashInit(hash); + + /* process main part of the message */ + if(msgLenBlks) { + pMethod->hashUpdate(hash, pMsg, msgLenBlks); + pMsg += msgLenBlks; + } + cpFinalize_rmf(hash, + pMsg, msgLenRest, + (Ipp64u)len, 0, + pMethod); + + pMethod->hashOctStr(pMD, hash); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_md5.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_md5.c new file mode 100644 index 000000000..f6c9d49d1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_md5.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// ippsHashMethod_MD5() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpmd5stuff.h" + +/*F* +// Name: ippsHashMethod_MD5 +// +// Purpose: Return MD5 method. +// +// Returns: +// Pointer to MD5 hash-method. +// +*F*/ +IPPFUN( const IppsHashMethod*, ippsHashMethod_MD5, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_MD5, + IPP_MD5_DIGEST_BITSIZE/8, + MBS_MD5, + MLR_MD5, + 0, + 0, + 0, + 0 + }; + + method.hashInit = md5_hashInit; + method.hashUpdate = md5_hashUpdate; + method.hashOctStr = md5_hashOctString; + method.msgLenRep = md5_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_rmf.h b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_rmf.h new file mode 100644 index 000000000..bf4814fbd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_rmf.h @@ -0,0 +1,45 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Internal Definitions and Internal Functions Prototypes +// +*/ +#if !defined(_PCP_HASH_METHOD_RMF_H) +#define _PCP_HASH_METHOD_RMF_H + +/* hash alg methods */ +IPP_OWN_FUNPTR (void, hashInitF, (void* pHash)) +IPP_OWN_FUNPTR (void, hashUpdateF, (void* pHash, const Ipp8u* pMsg, int msgLen)) +IPP_OWN_FUNPTR (void, hashOctStrF, (Ipp8u* pDst, void* pHash)) +IPP_OWN_FUNPTR (void, msgLenRepF, (Ipp8u* pDst, Ipp64u lenLo, Ipp64u lenHi)) + +typedef struct _cpHashMethod_rmf { + IppHashAlgId hashAlgId; /* algorithm ID */ + int hashLen; /* hash length in bytes */ + int msgBlkSize; /* message blkock size in bytes */ + int msgLenRepSize; /* length of processed msg length representation in bytes */ + hashInitF hashInit; /* set initial hash value */ + hashUpdateF hashUpdate; /* hash compressor */ + hashOctStrF hashOctStr; /* convert hash into oct string */ + msgLenRepF msgLenRep; /* processed mgs length representation */ +} cpHashMethod_rmf; + +#endif /* _PCP_HASH_METHOD_RMF_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1.c new file mode 100644 index 000000000..84ffbc680 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsHashMethod_SHA1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsHashMethod_SHA1 +// +// Purpose: Return SHA1 method. +// +// Returns: +// Pointer to SHA1 hash-method. +// +*F*/ +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA1, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA1, + IPP_SHA1_DIGEST_BITSIZE/8, + MBS_SHA1, + MLR_SHA1, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha1_hashInit; + method.hashUpdate = sha1_hashUpdate; + method.hashOctStr = sha1_hashOctString; + method.msgLenRep = sha1_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1_ni.c new file mode 100644 index 000000000..1c15e73af --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1_ni.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsHashMethod_SHA1_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsHashMethod_SHA1_NI +// +// Purpose: Return SHA1 method (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: +// Pointer to SHA1 hash-method (using the Intel SHA-NI instruction set). +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA1_NI, (void) ) +{ + #if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + static IppsHashMethod method = { + ippHashAlg_SHA1, + IPP_SHA1_DIGEST_BITSIZE/8, + MBS_SHA1, + MLR_SHA1, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha1_hashInit; + method.hashUpdate = sha1_ni_hashUpdate; + method.hashOctStr = sha1_hashOctString; + method.msgLenRep = sha1_msgRep; + + return &method; + #else + return NULL; + #endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1_tt.c new file mode 100644 index 000000000..ca1527262 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha1_tt.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsHashMethod_SHA1_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsHashMethod_SHA1_TT +// +// Purpose: Return SHA1 method +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: +// Pointer to SHA1 hash-method +// (using the Intel SHA-NI instructions set +// if it is available at run time) +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA1_TT, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA1, + IPP_SHA1_DIGEST_BITSIZE/8, + MBS_SHA1, + MLR_SHA1, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha1_hashInit; + method.hashUpdate = sha1_hashUpdate; + method.hashOctStr = sha1_hashOctString; + method.msgLenRep = sha1_msgRep; + + #if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + method.hashUpdate = sha1_ni_hashUpdate; + #endif + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224.c new file mode 100644 index 000000000..cad8c8824 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethod_SHA224() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethod_SHA224 +// +// Purpose: Return SHA224 method. +// +// Returns: +// Pointer to SHA224 hash-method. +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA224, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA224, + IPP_SHA224_DIGEST_BITSIZE/8, + MBS_SHA256, + MLR_SHA256, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha224_hashInit; + method.hashUpdate = sha256_hashUpdate; + method.hashOctStr = sha224_hashOctString; + method.msgLenRep = sha256_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224_ni.c new file mode 100644 index 000000000..e1133f405 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224_ni.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethod_SHA224_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethod_SHA224_NI +// +// Purpose: Return SHA224 method (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: +// Pointer to SHA224 hash-method (using the Intel SHA-NI instruction set). +// +*F*/ + + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA224_NI, (void) ) +{ + #if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + static IppsHashMethod method = { + ippHashAlg_SHA224, + IPP_SHA224_DIGEST_BITSIZE/8, + MBS_SHA256, + MLR_SHA256, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha224_hashInit; + method.hashUpdate = sha256_ni_hashUpdate; + method.hashOctStr = sha224_hashOctString; + method.msgLenRep = sha256_msgRep; + + return &method; + #else + return NULL; + #endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224_tt.c new file mode 100644 index 000000000..5b17dd87c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha224_tt.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethod_SHA224_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethod_SHA224_TT +// +// Purpose: Return SHA224 method +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: +// Pointer to SHA224 hash-method +// (using the Intel SHA-NI instructions set +// if it is available at run time) +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA224_TT, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA224, + IPP_SHA224_DIGEST_BITSIZE/8, + MBS_SHA256, + MLR_SHA256, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha224_hashInit; + method.hashUpdate = sha256_hashUpdate; + method.hashOctStr = sha224_hashOctString; + method.msgLenRep = sha256_msgRep; + + #if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + method.hashUpdate = sha256_ni_hashUpdate; + #endif + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256.c new file mode 100644 index 000000000..efe78c53d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethod_SHA256() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethod_SHA256 +// +// Purpose: Return SHA256 method. +// +// Returns: +// Pointer to SHA256 hash-method. +// +*F*/ +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA256, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA256, + IPP_SHA256_DIGEST_BITSIZE/8, + MBS_SHA256, + MLR_SHA256, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha256_hashInit; + method.hashUpdate = sha256_hashUpdate; + method.hashOctStr = sha256_hashOctString; + method.msgLenRep = sha256_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256_ni.c new file mode 100644 index 000000000..fd4366657 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256_ni.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethod_SHA256_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethod_SHA256_NI +// +// Purpose: Return SHA256 method (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: +// Pointer to SHA256 hash-method (using the Intel SHA-NI instruction set). +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA256_NI, (void) ) +{ + #if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + static IppsHashMethod method = { + ippHashAlg_SHA256, + IPP_SHA256_DIGEST_BITSIZE/8, + MBS_SHA256, + MLR_SHA256, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha256_hashInit; + method.hashUpdate = sha256_ni_hashUpdate; + method.hashOctStr = sha256_hashOctString; + method.msgLenRep = sha256_msgRep; + + return &method; + #else + return NULL; + #endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256_tt.c new file mode 100644 index 000000000..0f8f6bb57 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha256_tt.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethod_SHA256_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethod_SHA256_TT +// +// Purpose: Return SHA256 method +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: +// Pointer to SHA256 hash-method +// (using the Intel SHA-NI instructions set +// if it is available at run time) +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA256_TT, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA256, + IPP_SHA256_DIGEST_BITSIZE/8, + MBS_SHA256, + MLR_SHA256, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha256_hashInit; + method.hashUpdate = sha256_hashUpdate; + method.hashOctStr = sha256_hashOctString; + method.msgLenRep = sha256_msgRep; + + #if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + method.hashUpdate = sha256_ni_hashUpdate; + #endif + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha384.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha384.c new file mode 100644 index 000000000..bdd00825c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha384.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethod_SHA384() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethod_SHA384 +// +// Purpose: Return SHA384 method. +// +// Returns: +// Pointer to SHA384 hash-method. +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA384, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA384, + IPP_SHA384_DIGEST_BITSIZE/8, + MBS_SHA512, + MLR_SHA512, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha512_384_hashInit; + method.hashUpdate = sha512_hashUpdate; + method.hashOctStr = sha512_384_hashOctString; + method.msgLenRep = sha512_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512.c new file mode 100644 index 000000000..a612672e6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethod_SHA512() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethod_SHA512 +// +// Purpose: Return SHA512 method. +// +// Returns: +// Pointer to SHA512 hash-method. +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA512, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA512, + IPP_SHA512_DIGEST_BITSIZE/8, + MBS_SHA512, + MLR_SHA512, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha512_hashInit; + method.hashUpdate = sha512_hashUpdate; + method.hashOctStr = sha512_hashOctString; + method.msgLenRep = sha512_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512_224.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512_224.c new file mode 100644 index 000000000..6b7e887bd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512_224.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethod_SHA512_224() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethod_SHA512_224 +// +// Purpose: Return SHA512_224 method. +// +// Returns: +// Pointer to SHA512_224 hash-method. +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA512_224, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA512_224, + IPP_SHA224_DIGEST_BITSIZE/8, + MBS_SHA512, + MLR_SHA512, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha512_224_hashInit; + method.hashUpdate = sha512_hashUpdate; + method.hashOctStr = sha512_224_hashOctString; + method.msgLenRep = sha512_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512_256.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512_256.c new file mode 100644 index 000000000..a7c51448b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sha512_256.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethod_SHA512_256() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethod_SHA512_256 +// +// Purpose: Return SHA512_256 method. +// +// Returns: +// Pointer to SHA512_256 hash-method. +// +*F*/ + +IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA512_256, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SHA512_256, + IPP_SHA256_DIGEST_BITSIZE/8, + MBS_SHA512, + MLR_SHA512, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sha512_256_hashInit; + method.hashUpdate = sha512_hashUpdate; + method.hashOctStr = sha512_256_hashOctString; + method.msgLenRep = sha512_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sm3.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sm3.c new file mode 100644 index 000000000..cc23353ea --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethod_sm3.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsHashMethod_SM3() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" + +/*F* +// Name: ippsHashMethod_SM3 +// +// Purpose: Return SM3 method. +// +// Returns: +// Pointer to SM3 hash-method. +// +*F*/ +IPPFUN( const IppsHashMethod*, ippsHashMethod_SM3, (void) ) +{ + static IppsHashMethod method = { + ippHashAlg_SM3, + IPP_SM3_DIGEST_BITSIZE/8, + MBS_SM3, + MLR_SM3, + 0, + 0, + 0, + 0 + }; + + method.hashInit = sm3_hashInit; + method.hashUpdate = sm3_hashUpdate; + method.hashOctStr = sm3_hashOctString; + method.msgLenRep = sm3_msgRep; + + return &method; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodgetsize.c new file mode 100644 index 000000000..c55985de2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodgetsize.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashMethodGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphashmethod_rmf.h" + +/*F* +// Name: ippsHashMethodGetSize +// +// Purpose: Returns size (bytes) of IppsHashMethod structure. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ +IPPFUN(IppStatus, ippsHashMethodGetSize,(int* pSize)) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsHashMethod); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_md5.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_md5.c new file mode 100644 index 000000000..e71c0ae47 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_md5.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// ippsHashMethodSet_MD5() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpmd5stuff.h" + +/*F* +// Name: ippsHashMethodSet_MD5 +// +// Purpose: Setup MD5 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ +IPPFUN( IppStatus, ippsHashMethodSet_MD5, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_MD5; + pMethod->hashLen = IPP_MD5_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_MD5; + pMethod->msgLenRepSize = MLR_MD5; + pMethod->hashInit = md5_hashInit; + pMethod->hashUpdate = md5_hashUpdate; + pMethod->hashOctStr = md5_hashOctString; + pMethod->msgLenRep = md5_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1.c new file mode 100644 index 000000000..6255bc3a4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsHashMethodSet_SHA1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA1 +// +// Purpose: Setup SHA1 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors + +// +*F*/ +IPPFUN( IppStatus, ippsHashMethodSet_SHA1, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA1; + pMethod->hashLen = IPP_SHA1_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA1; + pMethod->msgLenRepSize = MLR_SHA1; + pMethod->hashInit = sha1_hashInit; + pMethod->hashUpdate = sha1_hashUpdate; + pMethod->hashOctStr = sha1_hashOctString; + pMethod->msgLenRep = sha1_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1_ni.c new file mode 100644 index 000000000..f798113d3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1_ni.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsHashMethodSet_SHA1_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA1_NI +// +// Purpose: Setup SHA1 method (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNotSupportedModeErr mode disabled by configuration +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA1_NI, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + pMethod->hashAlgId = ippHashAlg_SHA1; + pMethod->hashLen = IPP_SHA1_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA1; + pMethod->msgLenRepSize = MLR_SHA1; + pMethod->hashInit = sha1_hashInit; + pMethod->hashUpdate = sha1_ni_hashUpdate; + pMethod->hashOctStr = sha1_hashOctString; + pMethod->msgLenRep = sha1_msgRep; + + return ippStsNoErr; +#else + pMethod->hashAlgId = ippHashAlg_Unknown; + pMethod->hashLen = 0; + pMethod->msgBlkSize = 0; + pMethod->msgLenRepSize = 0; + pMethod->hashInit = 0; + pMethod->hashUpdate = 0; + pMethod->hashOctStr = 0; + pMethod->msgLenRep = 0; + + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1_tt.c new file mode 100644 index 000000000..940b98ee6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha1_tt.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsHashMethodSet_SHA1_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA1_TT +// +// Purpose: Setup SHA1 method +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA1_TT, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA1; + pMethod->hashLen = IPP_SHA1_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA1; + pMethod->msgLenRepSize = MLR_SHA1; + pMethod->hashInit = sha1_hashInit; + pMethod->hashUpdate = sha1_hashUpdate; + pMethod->hashOctStr = sha1_hashOctString; + pMethod->msgLenRep = sha1_msgRep; + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + pMethod->hashUpdate = sha1_ni_hashUpdate; +#endif + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224.c new file mode 100644 index 000000000..1e9231d3e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethodSet_SHA224() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA224 +// +// Purpose: Setup SHA224 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA224, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha224_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha224_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224_ni.c new file mode 100644 index 000000000..6fa60e3e3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224_ni.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethodSet_SHA224_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA224_NI +// +// Purpose: Setup SHA224 method (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNotSupportedModeErr mode disabled by configuration +// ippStsNoErr no errors +// +*F*/ + + +IPPFUN( IppStatus, ippsHashMethodSet_SHA224_NI, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + pMethod->hashAlgId = ippHashAlg_SHA224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha224_hashInit; + pMethod->hashUpdate = sha256_ni_hashUpdate; + pMethod->hashOctStr = sha224_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +#else + pMethod->hashAlgId = ippHashAlg_Unknown; + pMethod->hashLen = 0; + pMethod->msgBlkSize = 0; + pMethod->msgLenRepSize = 0; + pMethod->hashInit = 0; + pMethod->hashUpdate = 0; + pMethod->hashOctStr = 0; + pMethod->msgLenRep = 0; + + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224_tt.c new file mode 100644 index 000000000..5e20bbe5d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha224_tt.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethodSet_SHA224_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA224_TT +// +// Purpose: Setup SHA224 method +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA224_TT, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha224_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha224_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + pMethod->hashUpdate = sha256_ni_hashUpdate; +#endif + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256.c new file mode 100644 index 000000000..3ffcd2853 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethodSet_SHA256() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA256 +// +// Purpose: Setup SHA256 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ +IPPFUN( IppStatus, ippsHashMethodSet_SHA256, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha256_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha256_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256_ni.c new file mode 100644 index 000000000..7da64dedf --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256_ni.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethodSet_SHA256_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA256_NI +// +// Purpose: Setup SHA256 method (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNotSupportedModeErr mode disabled by configuration +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA256_NI, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + pMethod->hashAlgId = ippHashAlg_SHA256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha256_hashInit; + pMethod->hashUpdate = sha256_ni_hashUpdate; + pMethod->hashOctStr = sha256_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +#else + pMethod->hashAlgId = ippHashAlg_Unknown; + pMethod->hashLen = 0; + pMethod->msgBlkSize = 0; + pMethod->msgLenRepSize = 0; + pMethod->hashInit = 0; + pMethod->hashUpdate = 0; + pMethod->hashOctStr = 0; + pMethod->msgLenRep = 0; + + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256_tt.c new file mode 100644 index 000000000..e77c29a5d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha256_tt.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashMethodSet_SHA256_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA256_TT +// +// Purpose: Setup SHA256 method +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA256_TT, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha256_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha256_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + pMethod->hashUpdate = sha256_ni_hashUpdate; +#endif + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha384.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha384.c new file mode 100644 index 000000000..8a69082ee --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha384.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethodSet_SHA384() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA384 +// +// Purpose: Setup SHA384 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA384, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA384; + pMethod->hashLen = IPP_SHA384_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_384_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_384_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512.c new file mode 100644 index 000000000..422f64de8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethodSet_SHA512() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA512 +// +// Purpose: Setup SHA512 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA512, (IppsHashMethod* pMethod) ) +{ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA512; + pMethod->hashLen = IPP_SHA512_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512_224.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512_224.c new file mode 100644 index 000000000..2978ffb56 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512_224.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethodSet_SHA512_224() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA512_224 +// +// Purpose: Return SHA512_224 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA512_224, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA512_224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_224_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_224_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512_256.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512_256.c new file mode 100644 index 000000000..7bbff90f5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sha512_256.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashMethodSet_SHA512_256() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashMethodSet_SHA512_256 +// +// Purpose: Setup SHA512_256 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashMethodSet_SHA512_256, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SHA512_256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_256_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_256_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sm3.c b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sm3.c new file mode 100644 index 000000000..7a066786a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashmethodset_sm3.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsHashMethodSet_SM3() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" + +/*F* +// Name: ippsHashMethodSet_SM3 +// +// Purpose: Setup SM3 method. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL +// ippStsNoErr no errors +// +*F*/ +IPPFUN( IppStatus, ippsHashMethodSet_SM3, (IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR1_RET(pMethod); + + pMethod->hashAlgId = ippHashAlg_SM3; + pMethod->hashLen = IPP_SM3_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SM3; + pMethod->msgLenRepSize = MLR_SM3; + pMethod->hashInit = sm3_hashInit; + pMethod->hashUpdate = sm3_hashUpdate; + pMethod->hashOctStr = sm3_hashOctString; + pMethod->msgLenRep = sm3_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashpack.c b/plugin/ippcp/library/src/sources/ippcp/pcphashpack.c new file mode 100644 index 000000000..1c13a3beb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashpack.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashPack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashPack +// +// Purpose: Copy initialized context to the buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pBuffer == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHash +// ippStsNoMemErr bufSize < sizeof(IppsHashState) +// ippStsNoErr no errors +// +// Parameters: +// pState pointer hash state +// pBuffer pointer to the destination buffer +// bufSize size of the destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsHashPack,(const IppsHashState* pState, Ipp8u* pBuffer, int bufSize)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + /* test the context */ + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + /* test buffer length */ + IPP_BADARG_RET((int)(sizeof(IppsHashState))>bufSize, ippStsNoMemErr); + + CopyBlock(pState, pBuffer, sizeof(IppsHashState)); + IppsHashState* pCopy = (IppsHashState*)pBuffer; + HASH_RESET_ID(pCopy, idCtxHash); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashpack_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashpack_rmf.c new file mode 100644 index 000000000..34962f046 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashpack_rmf.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashPack_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashPack_rmf +// +// Purpose: Copy initialized context to the buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pBuffer == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHash +// ippStsNoMemErr bufSize < sizeof(IppsHashState_rmf) +// ippStsNoErr no errors +// +// Parameters: +// pState pointer hash state +// pBuffer pointer to the destination buffer +// bufSize size of the destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsHashPack_rmf,(const IppsHashState_rmf* pState, Ipp8u* pBuffer, int bufSize)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + /* test buffer length */ + IPP_BADARG_RET((int)(sizeof(IppsHashState_rmf))>bufSize, ippStsNoMemErr); + + CopyBlock(pState, pBuffer, sizeof(IppsHashState_rmf)); + IppsHashState_rmf* pCopy = (IppsHashState_rmf*)pBuffer; + HASH_RESET_ID(pCopy, idCtxHash); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashsha1px.c b/plugin/ippcp/library/src/sources/ippcp/pcphashsha1px.c new file mode 100644 index 000000000..c189e6222 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashsha1px.c @@ -0,0 +1,177 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message block processing according to SHA1 +// +// Contents: +// UpdateSHA1() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +#if !((_IPP==_IPP_M5) || \ + (_IPP==_IPP_W7) || (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || (_IPP==_IPP_P8) || \ + (_IPP==_IPP_S8) || (_IPP>=_IPP_G9) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) + +/* +// Magic functions defined in FIPS 180-1 +// +*/ +#define MAGIC_F0(B,C,D) (((B) & (C)) | ((~(B)) & (D))) +#define MAGIC_F1(B,C,D) ((B) ^ (C) ^ (D)) +#define MAGIC_F2(B,C,D) (((B) & (C)) | ((B) & (D)) | ((C) & (D))) +#define MAGIC_F3(B,C,D) ((B) ^ (C) ^ (D)) + +#define SHA1_STEP(A,B,C,D,E, MAGIC_FUN, W,K) \ + (E)+= ROL32((A),5) + MAGIC_FUN((B),(C),(D)) + (W) + (K); \ + (B) = ROL32((B),30) + +#define COMPACT_SHA1_STEP(A,B,C,D,E, MAGIC_FUN, W,K, t) { \ + Ipp32u _T = ROL32((A),5) + MAGIC_FUN((t)/20, (B),(C),(D)) + (E) + (W)[(t)] + (K)[(t)/20]; \ + (E) = (D); \ + (D) = (C); \ + (C) = ROL32((B),30); \ + (B) = (A); \ + (A) = _T; \ +} + +#if defined(_ALG_SHA1_COMPACT_) +__INLINE Ipp32u MagicFun(int s, Ipp32u b, Ipp32u c, Ipp32u d) +{ + switch(s) { + case 0: return MAGIC_F0(b,c,d); + case 2: return MAGIC_F2(b,c,d); + default:return MAGIC_F1(b,c,d); + } +} +#endif + + +/*F* +// Name: UpdateSHA1 +// +// Purpose: Update internal hash according to input message stream. +// +// Parameters: +// uniHash pointer to in/out hash +// mblk pointer to message stream +// mlen message stream length (multiple by message block size) +// uniParam pointer to the optional parameter +// +*F*/ +IPP_OWN_DEFN (void, UpdateSHA1, (void* uinHash, const Ipp8u* mblk, int mlen, const void *uniParam)) +{ + Ipp32u* data = (Ipp32u*)mblk; + + Ipp32u* digest = (Ipp32u*)uinHash; + Ipp32u* SHA1_cnt_loc = (Ipp32u*)uniParam; + + for(; mlen>=MBS_SHA1; data += MBS_SHA1/sizeof(Ipp32u), mlen -= MBS_SHA1) { + int t; + + /* + // expand message block + */ + Ipp32u W[80]; + /* initialize the first 16 words in the array W (remember about endian) */ + for(t=0; t<16; t++) { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + W[t] = data[t]; + #else + W[t] = ENDIANNESS(data[t]); + #endif + } + /* schedule another 80-16 words in the array W */ + for(; t<80; t++) { + W[t] = ROL32(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); + } + + /* + // update hash + */ + { + /* init A, B, C, D, E by the the input hash */ + Ipp32u A = digest[0]; + Ipp32u B = digest[1]; + Ipp32u C = digest[2]; + Ipp32u D = digest[3]; + Ipp32u E = digest[4]; + + #if defined(_ALG_SHA1_COMPACT_) + /* steps 0-79 */ + for(t=0; t<80; t++) + COMPACT_SHA1_STEP(A,B,C,D,E, MagicFun, W, SHA1_cnt_loc, t); + + #else + /* perform 0-19 steps */ + for(t=0; t<20; t+=5) { + SHA1_STEP(A,B,C,D,E, MAGIC_F0, W[t ],SHA1_cnt_loc[0]); + SHA1_STEP(E,A,B,C,D, MAGIC_F0, W[t+1],SHA1_cnt_loc[0]); + SHA1_STEP(D,E,A,B,C, MAGIC_F0, W[t+2],SHA1_cnt_loc[0]); + SHA1_STEP(C,D,E,A,B, MAGIC_F0, W[t+3],SHA1_cnt_loc[0]); + SHA1_STEP(B,C,D,E,A, MAGIC_F0, W[t+4],SHA1_cnt_loc[0]); + } + /* perform 20-39 steps */ + for(; t<40; t+=5) { + SHA1_STEP(A,B,C,D,E, MAGIC_F1, W[t ],SHA1_cnt_loc[1]); + SHA1_STEP(E,A,B,C,D, MAGIC_F1, W[t+1],SHA1_cnt_loc[1]); + SHA1_STEP(D,E,A,B,C, MAGIC_F1, W[t+2],SHA1_cnt_loc[1]); + SHA1_STEP(C,D,E,A,B, MAGIC_F1, W[t+3],SHA1_cnt_loc[1]); + SHA1_STEP(B,C,D,E,A, MAGIC_F1, W[t+4],SHA1_cnt_loc[1]); + } + /* perform 40-59 steps */ + for(; t<60; t+=5) { + SHA1_STEP(A,B,C,D,E, MAGIC_F2, W[t ],SHA1_cnt_loc[2]); + SHA1_STEP(E,A,B,C,D, MAGIC_F2, W[t+1],SHA1_cnt_loc[2]); + SHA1_STEP(D,E,A,B,C, MAGIC_F2, W[t+2],SHA1_cnt_loc[2]); + SHA1_STEP(C,D,E,A,B, MAGIC_F2, W[t+3],SHA1_cnt_loc[2]); + SHA1_STEP(B,C,D,E,A, MAGIC_F2, W[t+4],SHA1_cnt_loc[2]); + } + /* perform 60-79 steps */ + for(; t<80; t+=5) { + SHA1_STEP(A,B,C,D,E, MAGIC_F3, W[t ],SHA1_cnt_loc[3]); + SHA1_STEP(E,A,B,C,D, MAGIC_F3, W[t+1],SHA1_cnt_loc[3]); + SHA1_STEP(D,E,A,B,C, MAGIC_F3, W[t+2],SHA1_cnt_loc[3]); + SHA1_STEP(C,D,E,A,B, MAGIC_F3, W[t+3],SHA1_cnt_loc[3]); + SHA1_STEP(B,C,D,E,A, MAGIC_F3, W[t+4],SHA1_cnt_loc[3]); + } + #endif + + /* update digest */ + digest[0] += A; + digest[1] += B; + digest[2] += C; + digest[3] += D; + digest[4] += E; + } + } +} + +#endif diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashsha256px.c b/plugin/ippcp/library/src/sources/ippcp/pcphashsha256px.c new file mode 100644 index 000000000..b56834e7c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashsha256px.c @@ -0,0 +1,208 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message block processing according to SHA256 +// +// Contents: +// UpdateSHA256() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +#if defined(_ENABLE_ALG_SHA256_) || defined(_ENABLE_ALG_SHA224_) + +#if !((_IPP==_IPP_M5) || \ + (_IPP==_IPP_W7) || (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || (_IPP==_IPP_P8) || \ + (_IPP==_IPP_S8) || (_IPP>=_IPP_G9) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) + +/* +// SHA256 Specific Macros (reference proposal 256-384-512) +*/ +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define SUM0(x) (ROR32((x), 2) ^ ROR32((x),13) ^ ROR32((x),22)) +#define SUM1(x) (ROR32((x), 6) ^ ROR32((x),11) ^ ROR32((x),25)) + +#define SIG0(x) (ROR32((x), 7) ^ ROR32((x),18) ^ LSR32((x), 3)) +#define SIG1(x) (ROR32((x),17) ^ ROR32((x),19) ^ LSR32((x),10)) + +#define SHA256_UPDATE(i) \ + wdat[i & 15] += SIG1(wdat[(i+14)&15]) + wdat[(i+9)&15] + SIG0(wdat[(i+1)&15]) + +#define SHA256_STEP(i,j) \ + v[(7 - i) & 7] += (j ? SHA256_UPDATE(i) : wdat[i&15]) \ + + SHA256_cnt_loc[i + j] \ + + SUM1(v[(4-i)&7]) \ + + CH(v[(4-i)&7], v[(5-i)&7], v[(6-i)&7]); \ + v[(3-i)&7] += v[(7-i)&7]; \ + v[(7-i)&7] += SUM0(v[(0-i)&7]) + MAJ(v[(0-i)&7], v[(1-i)&7], v[(2-i)&7]) + +#define COMPACT_SHA256_STEP(A,B,C,D,E,F,G,H, W,K, r) { \ + Ipp32u _T1 = (H) + SUM1((E)) + CH((E),(F),(G)) + (W)[(r)] + (K)[(r)]; \ + Ipp32u _T2 = SUM0((A)) + MAJ((A),(B),(C)); \ + (H) = (G); \ + (G) = (F); \ + (F) = (E); \ + (E) = (D)+_T1; \ + (D) = (C); \ + (C) = (B); \ + (B) = (A); \ + (A) = _T1+_T2; \ +} + +/*F* +// Name: UpdateSHA256 +// +// Purpose: Update internal hash according to input message stream. +// +// Parameters: +// uniHash pointer to in/out hash +// mblk pointer to message stream +// mlen message stream length (multiple by message block size) +// uniParam pointer to the optional parameter +// +*F*/ +#if defined(_ALG_SHA256_COMPACT_) + +IPP_OWN_DEFN (void, UpdateSHA256, (void* uniHash, const Ipp8u* mblk, int mlen, const void* uniParam)) +{ + Ipp32u* data = (Ipp32u*)mblk; + + Ipp32u* digest = (Ipp32u*)uniHash; + Ipp32u* SHA256_cnt_loc = (Ipp32u*)uniParam; + + for(; mlen>=MBS_SHA256; data += MBS_SHA256/sizeof(Ipp32u), mlen -= MBS_SHA256) { + int t; + + /* + // expand message block + */ + Ipp32u W[64]; + /* initialize the first 16 words in the array W (remember about endian) */ + for(t=0; t<16; t++) { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + W[t] = data[t]; + #else + W[t] = ENDIANNESS( data[t] ); + #endif + } + for(; t<64; t++) + W[t] = SIG1(W[t-2]) + W[t-7] + SIG0(W[t-15]) + W[t-16]; + + /* + // update hash + */ + { + /* init A, B, C, D, E, F, G, H by the input hash */ + Ipp32u A = digest[0]; + Ipp32u B = digest[1]; + Ipp32u C = digest[2]; + Ipp32u D = digest[3]; + Ipp32u E = digest[4]; + Ipp32u F = digest[5]; + Ipp32u G = digest[6]; + Ipp32u H = digest[7]; + + for(t=0; t<64; t++) + COMPACT_SHA256_STEP(A,B,C,D,E,F,G,H, W,SHA256_cnt_loc, t); + + /* update hash*/ + digest[0] += A; + digest[1] += B; + digest[2] += C; + digest[3] += D; + digest[4] += E; + digest[5] += F; + digest[6] += G; + digest[7] += H; + } + } +} + +#else +IPP_OWN_DEFN (void, UpdateSHA256, (void* uniHash, const Ipp8u* mblk, int mlen, const void* uniParam)) +{ + Ipp32u* data = (Ipp32u*)mblk; + + Ipp32u* digest = (Ipp32u*)uniHash; + Ipp32u* SHA256_cnt_loc = (Ipp32u*)uniParam; + + for(; mlen>=MBS_SHA256; data += MBS_SHA256/sizeof(Ipp32u), mlen -= MBS_SHA256) { + Ipp32u wdat[16]; + int j; + + /* copy digest */ + Ipp32u v[8]; + CopyBlock(digest, v, IPP_SHA256_DIGEST_BITSIZE/BYTESIZE); + + /* initialize the first 16 words in the array W (remember about endian) */ + for(j=0; j<16; j++) { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + wdat[j] = data[j]; + #else + wdat[j] = ENDIANNESS( data[j] ); + #endif + } + + for(j=0; j<64; j+=16) { + SHA256_STEP( 0, j); + SHA256_STEP( 1, j); + SHA256_STEP( 2, j); + SHA256_STEP( 3, j); + SHA256_STEP( 4, j); + SHA256_STEP( 5, j); + SHA256_STEP( 6, j); + SHA256_STEP( 7, j); + SHA256_STEP( 8, j); + SHA256_STEP( 9, j); + SHA256_STEP(10, j); + SHA256_STEP(11, j); + SHA256_STEP(12, j); + SHA256_STEP(13, j); + SHA256_STEP(14, j); + SHA256_STEP(15, j); + } + + /* update digest */ + digest[0] += v[0]; + digest[1] += v[1]; + digest[2] += v[2]; + digest[3] += v[3]; + digest[4] += v[4]; + digest[5] += v[5]; + digest[6] += v[6]; + digest[7] += v[7]; + } +} +#endif + +#endif +#endif /* IPP_ALG_HASH_SHA256 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashsha512px.c b/plugin/ippcp/library/src/sources/ippcp/pcphashsha512px.c new file mode 100644 index 000000000..42d5b5949 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashsha512px.c @@ -0,0 +1,215 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message block processing according to SHA512 +// +// Contents: +// UpdateSHA512() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +#if defined(_ENABLE_ALG_SHA512_) || defined(_ENABLE_ALG_SHA384_) || defined(_ENABLE_ALG_SHA512_224_) || defined(_ENABLE_ALG_SHA512_256_) + +#if !((_IPP==_IPP_W7) || (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || (_IPP==_IPP_P8) || \ + (_IPP==_IPP_S8) || (_IPP>=_IPP_G9) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) + +/* +// SHA512 Specific Macros (reference proposal 256-384-512) +// +// Note: All operations act on DWORDs (64-bits) +*/ +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define SUM0(x) (ROR64((x),28) ^ ROR64((x),34) ^ ROR64((x),39)) +#define SUM1(x) (ROR64((x),14) ^ ROR64((x),18) ^ ROR64((x),41)) + +#define SIG0(x) (ROR64((x), 1) ^ ROR64((x), 8) ^ LSR64((x), 7)) +#define SIG1(x) (ROR64((x),19) ^ ROR64((x),61) ^ LSR64((x), 6)) + +#define SHA512_UPDATE(i) \ + wdat[i&15] += SIG1(wdat[(i+14)&15]) + wdat[(i+9)&15] + SIG0(wdat[(i+1)&15]) + +#define SHA512_STEP(i,j) \ + v[(7-i)&7] += (j ? SHA512_UPDATE(i) : wdat[i&15]) \ + + SHA512_cnt_loc[i+j] \ + + SUM1(v[(4-i)&7]) \ + + CH(v[(4-i)&7], v[(5-i)&7], v[(6-i)&7]); \ + v[(3-i)&7] += v[(7-i)&7]; \ + v[(7-i)&7] += SUM0(v[(0-i)&7]) + MAJ(v[(0-i)&7], v[(1-i)&7], v[(2-i)&7]) + +#define COMPACT_SHA512_STEP(A,B,C,D,E,F,G,H, W,K, r) { \ + Ipp64u _T1 = (H) + SUM1((E)) + CH((E),(F),(G)) + (W)[(r)] + (K)[(r)]; \ + Ipp64u _T2 = SUM0((A)) + MAJ((A),(B),(C)); \ + (H) = (G); \ + (G) = (F); \ + (F) = (E); \ + (E) = (D)+_T1; \ + (D) = (C); \ + (C) = (B); \ + (B) = (A); \ + (A) = _T1+_T2; \ +} + +/*F* +// Name: UpdateSHA512 +// +// Purpose: Update internal hash according to input message stream. +// +// Parameters: +// uniHash pointer to in/out hash +// mblk pointer to message stream +// mlen message stream length (multiple by message block size) +// uniParam pointer to the optional parameter +// +*F*/ +#if defined(_ALG_SHA512_COMPACT_) + +IPP_OWN_DEFN (void, UpdateSHA512, (void* uniHash, const Ipp8u* mblk, int mlen, const void* uniPraram)) +{ + Ipp32u* data = (Ipp32u*)mblk; + + Ipp64u* digest = (Ipp64u*)uniHash; + Ipp64u* SHA512_cnt_loc = (Ipp64u*)uniPraram; + + + for(; mlen>=MBS_SHA512; data += MBS_SHA512/sizeof(Ipp32u), mlen -= MBS_SHA512) { + int t; + Ipp64u W[80]; + + /* + // expand message block + */ + /* initialize the first 16 words in the array W (remember about endian) */ + for(t=0; t<16; t++) { + Ipp32u hiX = data[2*t]; + Ipp32u loX = data[2*t+1]; + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + W[t] = IPP_MAKEDWORD(loX, hiX); + #else + W[t] = IPP_MAKEDWORD( ENDIANNESS(loX), ENDIANNESS(hiX) ); + #endif + } + for(; t<80; t++) + W[t] = SIG1(W[t-2]) + W[t-7] + SIG0(W[t-15]) + W[t-16]; + + /* + // update hash + */ + { + /* init A, B, C, D, E, F, G, H by the input hash */ + Ipp64u A = digest[0]; + Ipp64u B = digest[1]; + Ipp64u C = digest[2]; + Ipp64u D = digest[3]; + Ipp64u E = digest[4]; + Ipp64u F = digest[5]; + Ipp64u G = digest[6]; + Ipp64u H = digest[7]; + + for(t=0; t<80; t++) + COMPACT_SHA512_STEP(A,B,C,D,E,F,G,H, W,SHA512_cnt_loc, t); + + /* update hash*/ + digest[0] += A; + digest[1] += B; + digest[2] += C; + digest[3] += D; + digest[4] += E; + digest[5] += F; + digest[6] += G; + digest[7] += H; + } + } +} + +#else +IPP_OWN_DEFN (void, UpdateSHA512, (void* uniHash, const Ipp8u* mblk, int mlen, const void* uniPraram)) +{ + Ipp32u* data = (Ipp32u*)mblk; + + Ipp64u* digest = (Ipp64u*)uniHash; + Ipp64u* SHA512_cnt_loc = (Ipp64u*)uniPraram; + + for(; mlen>=MBS_SHA512; data += MBS_SHA512/sizeof(Ipp32u), mlen -= MBS_SHA512) { + Ipp64u wdat[16]; + int j; + + Ipp64u v[8]; + + /* initialize the first 16 words in the array W (remember about endian) */ + for(j=0; j<16; j++) { + Ipp32u hiX = data[2*j]; + Ipp32u loX = data[2*j+1]; + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + wdat[j] = IPP_MAKEDWORD(loX, hiX); + #else + wdat[j] = IPP_MAKEDWORD( ENDIANNESS(loX), ENDIANNESS(hiX) ); + #endif + } + + /* copy digest */ + CopyBlock(digest, v, IPP_SHA512_DIGEST_BITSIZE/BYTESIZE); + + for(j=0; j<80; j+=16) { + SHA512_STEP( 0, j); + SHA512_STEP( 1, j); + SHA512_STEP( 2, j); + SHA512_STEP( 3, j); + SHA512_STEP( 4, j); + SHA512_STEP( 5, j); + SHA512_STEP( 6, j); + SHA512_STEP( 7, j); + SHA512_STEP( 8, j); + SHA512_STEP( 9, j); + SHA512_STEP(10, j); + SHA512_STEP(11, j); + SHA512_STEP(12, j); + SHA512_STEP(13, j); + SHA512_STEP(14, j); + SHA512_STEP(15, j); + } + + /* update digest */ + digest[0] += v[0]; + digest[1] += v[1]; + digest[2] += v[2]; + digest[3] += v[3]; + digest[4] += v[4]; + digest[5] += v[5]; + digest[6] += v[6]; + digest[7] += v[7]; + } +} +#endif + +#endif +#endif /* IPP_ALG_HASH_SHA512 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashsm3px.c b/plugin/ippcp/library/src/sources/ippcp/pcphashsm3px.c new file mode 100644 index 000000000..892f2f1d7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashsm3px.c @@ -0,0 +1,338 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message block processing according to SM5 +// +// Contents: +// UpdateSM3() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +#if defined(_ENABLE_ALG_SM3_) + +#if !((_IPP32E>=_IPP32E_U8) || (_IPP32E==_IPP32E_N8) ) + +/* +// SM3 Specific Macros +// (reference SM3 Cryptographic Hash Algorithm, +// Chinese Commercial Cryptography Administration Office, 2010.12) +*/ + +/* T1 and T2 are base for additive const generation */ +#define T1 (0x79CC4519) +#define T2 (0x7A879D8A) + +// boolean functions (0<=nr<16) +#define FF1(x,y,z) ((x)^(y)^(z)) +#define GG1(x,y,z) ((x)^(y)^(z)) +// boolean functions (16<=nr<64) +#define FF2(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) +#define GG2(x,y,z) (((x)&(y)) | (~(x)&(z))) + +// P0 permutation: +#define P0(x) ((x) ^ ROL32((x),9) ^ ROL32((x),17)) +// P1 permutation: +#define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) + +// update W +#define WUPDATE(nr, W) (P1(W[((nr)-16)&15] ^ W[((nr)-9)&15] ^ ROL32(W[((nr)-3)&15],15)) ^ ROL32(W[((nr)-13)&15],7) ^ W[((nr)-6)&15]) + +// SM3 steps +#define SM3_STEP1(nr, A,B,C,D,E,F,G,H, Tj, W) { \ + TT1 = FF1(A,B,C) + D + (W[nr&15] ^ W[(nr+4)&15]); \ + TT2 = GG1(E,F,G) + H + W[nr&15]; \ + H = ROL32(A,12); \ + D = ROL32(H + E +Tj, 7); \ + H ^= D; \ + D += TT2; \ + H += TT1; \ + B = ROL32(B, 9); \ + D = P0(D); \ + F = ROL32(F, 19); \ + /*Tj = ROL32(Tj, 1);*/ \ + W[(nr)&15] = WUPDATE(nr, W); \ +} + +#define SM3_STEP2(nr, A,B,C,D,E,F,G,H, Tj, W) { \ + TT1 = FF2(A,B,C) + D + (W[nr&15] ^ W[(nr+4)&15]); \ + TT2 = GG2(E,F,G) + H + W[nr&15]; \ + H = ROL32(A,12); \ + D = ROL32(H + E +Tj, 7); \ + H ^= D; \ + D += TT2; \ + H += TT1; \ + B = ROL32(B, 9); \ + D = P0(D); \ + F = ROL32(F, 19); \ + /*Tj = ROL32(Tj, 1);*/ \ + W[(nr)&15] = WUPDATE(nr, W); \ +} + +#define SM3_STEP3(nr, A,B,C,D,E,F,G,H, Tj, W) { \ + TT1 = FF2(A,B,C) + D + (W[nr&15] ^ W[(nr+4)&15]); \ + TT2 = GG2(E,F,G) + H + W[nr&15]; \ + H = ROL32(A,12); \ + D = ROL32(H + E +Tj, 7); \ + H ^= D; \ + D += TT2; \ + H += TT1; \ + B = ROL32(B, 9); \ + D = P0(D); \ + F = ROL32(F, 19); \ + /*Tj = ROL32(Tj, 1);*/ \ +} + +#define COMPACT_SM3_STEP(A,B,C,D,E,F,G,H, FF, GG, W,Tj, r) { \ + TT1 = FF((r)&0x30, A,B,C) + D + (W[(r)] ^ W[(r)+4]); \ + TT2 = GG((r)&0x30, E,F,G) + H + W[(r)]; \ + \ + _H = ROL32(A,12); \ + _D = ROL32(_H + E +Tj[(r)], 7); \ + _H ^= _D; \ + _D += TT2; \ + _H += TT1; \ + _D = P0(_D);\ + \ + H = G; \ + G = ROL32(F,19); \ + F = E; \ + E =_D; \ + D = C; \ + C = ROL32(B, 9); \ + B = A; \ + A =_H; \ +} + + +/*F* +// Name: UpdateSM3 +// +// Purpose: Update internal hash according to input message stream. +// +// Parameters: +// uniHash pointer to in/out hash +// mblk pointer to message stream +// mlen message stream length (multiple by message block size) +// uniParam pointer to the optional parameter +// +*F*/ +#if defined(_ALG_SM3_COMPACT_) + +__INLINE Ipp32u MagicFF(int s, Ipp32u a, Ipp32u b, Ipp32u c) +{ + switch(s) { + case 0: return FF1(a,b,c); + default:return FF2(a,b,c); + } +} +__INLINE Ipp32u MagicGG(int s, Ipp32u e, Ipp32u f, Ipp32u g) +{ + switch(s) { + case 0: return GG1(e,f,g); + default:return GG2(e,f,g); + } +} + +IPP_OWN_DEFN (void, UpdateSM3, (void* uniHash, const Ipp8u* mblk, int mlen, const void* uniParam)) +{ + Ipp32u* data = (Ipp32u*)mblk; + + Ipp32u* hash = (Ipp32u*)uniHash; + Ipp32u* SM3_cnt_loc = (Ipp32u*)uniParam; + + for(; mlen>=MBS_SM3; data += MBS_SM3/sizeof(Ipp32u), mlen -= MBS_SM3) { + int r; + + /* + // expand message block + */ + Ipp32u W[68]; + /* initialize the first 16 words in the array W (remember about endian) */ + for(r=0; r<16; r++) { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + W[r] = data[r]; + #else + W[r] = ENDIANNESS( data[r] ); + #endif + } + for(; r<68; r++) + W[r] = P1(W[r-16] ^ W[r-9] ^ ROL32(W[r-3],15)) ^ ROL32(W[r-13],7) ^ W[r-6]; + + /* + // update hash + */ + { + /* init A, B, C, D, E, F, G, H by the input hash */ + Ipp32u A = hash[0]; + Ipp32u B = hash[1]; + Ipp32u C = hash[2]; + Ipp32u D = hash[3]; + Ipp32u E = hash[4]; + Ipp32u F = hash[5]; + Ipp32u G = hash[6]; + Ipp32u H = hash[7]; + + Ipp32u TT1, TT2, _H, _D; + for(r=0; r<64; r++) + COMPACT_SM3_STEP(A,B,C,D,E,F,G,H, MagicFF,MagicGG, W, SM3_cnt_loc, r); + + /* update hash */ + hash[0] ^= A; + hash[1] ^= B; + hash[2] ^= C; + hash[3] ^= D; + hash[4] ^= E; + hash[5] ^= F; + hash[6] ^= G; + hash[7] ^= H; + } + } +} + +#else +IPP_OWN_DEFN (void, UpdateSM3, (void* uniHash, const Ipp8u* mblk, int mlen, const void* uniParam)) +{ + Ipp32u* data = (Ipp32u*)mblk; + + Ipp32u* hash = (Ipp32u*)uniHash; + Ipp32u* SM3_cnt_loc = (Ipp32u*)uniParam; + + for(; mlen>=MBS_SM3; data += MBS_SM3/sizeof(Ipp32u), mlen -= MBS_SM3) { + + /* copy input hash */ + Ipp32u A = hash[0]; + Ipp32u B = hash[1]; + Ipp32u C = hash[2]; + Ipp32u D = hash[3]; + Ipp32u E = hash[4]; + Ipp32u F = hash[5]; + Ipp32u G = hash[6]; + Ipp32u H = hash[7]; + + Ipp32u W[16]; + int j; + + + /* initialize the first 16 words in the array W (remember about endian) */ + for(j=0; j<16; j++) { + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + W[j] = data[j]; + #else + W[j] = ENDIANNESS( data[j] ); + #endif + } + + /* apply compression function */ + { + Ipp32u TT1, TT2; + SM3_STEP1( 0, A,B,C,D,E,F,G,H, SM3_cnt_loc[0], W); + SM3_STEP1( 1, H,A,B,C,D,E,F,G, SM3_cnt_loc[1], W); + SM3_STEP1( 2, G,H,A,B,C,D,E,F, SM3_cnt_loc[2], W); + SM3_STEP1( 3, F,G,H,A,B,C,D,E, SM3_cnt_loc[3], W); + SM3_STEP1( 4, E,F,G,H,A,B,C,D, SM3_cnt_loc[4], W); + SM3_STEP1( 5, D,E,F,G,H,A,B,C, SM3_cnt_loc[5], W); + SM3_STEP1( 6, C,D,E,F,G,H,A,B, SM3_cnt_loc[6], W); + SM3_STEP1( 7, B,C,D,E,F,G,H,A, SM3_cnt_loc[7], W); + + SM3_STEP1( 8, A,B,C,D,E,F,G,H, SM3_cnt_loc[ 8], W); + SM3_STEP1( 9, H,A,B,C,D,E,F,G, SM3_cnt_loc[ 9], W); + SM3_STEP1(10, G,H,A,B,C,D,E,F, SM3_cnt_loc[10], W); + SM3_STEP1(11, F,G,H,A,B,C,D,E, SM3_cnt_loc[11], W); + SM3_STEP1(12, E,F,G,H,A,B,C,D, SM3_cnt_loc[12], W); + SM3_STEP1(13, D,E,F,G,H,A,B,C, SM3_cnt_loc[13], W); + SM3_STEP1(14, C,D,E,F,G,H,A,B, SM3_cnt_loc[14], W); + SM3_STEP1(15, B,C,D,E,F,G,H,A, SM3_cnt_loc[15], W); + + SM3_STEP2(16, A,B,C,D,E,F,G,H, SM3_cnt_loc[16], W); + SM3_STEP2(17, H,A,B,C,D,E,F,G, SM3_cnt_loc[17], W); + SM3_STEP2(18, G,H,A,B,C,D,E,F, SM3_cnt_loc[18], W); + SM3_STEP2(19, F,G,H,A,B,C,D,E, SM3_cnt_loc[19], W); + SM3_STEP2(20, E,F,G,H,A,B,C,D, SM3_cnt_loc[20], W); + SM3_STEP2(21, D,E,F,G,H,A,B,C, SM3_cnt_loc[21], W); + SM3_STEP2(22, C,D,E,F,G,H,A,B, SM3_cnt_loc[22], W); + SM3_STEP2(23, B,C,D,E,F,G,H,A, SM3_cnt_loc[23], W); + + SM3_STEP2(24, A,B,C,D,E,F,G,H, SM3_cnt_loc[24], W); + SM3_STEP2(25, H,A,B,C,D,E,F,G, SM3_cnt_loc[25], W); + SM3_STEP2(26, G,H,A,B,C,D,E,F, SM3_cnt_loc[26], W); + SM3_STEP2(27, F,G,H,A,B,C,D,E, SM3_cnt_loc[27], W); + SM3_STEP2(28, E,F,G,H,A,B,C,D, SM3_cnt_loc[28], W); + SM3_STEP2(29, D,E,F,G,H,A,B,C, SM3_cnt_loc[29], W); + SM3_STEP2(30, C,D,E,F,G,H,A,B, SM3_cnt_loc[30], W); + SM3_STEP2(31, B,C,D,E,F,G,H,A, SM3_cnt_loc[31], W); + + SM3_STEP2(32, A,B,C,D,E,F,G,H, SM3_cnt_loc[32], W); + SM3_STEP2(33, H,A,B,C,D,E,F,G, SM3_cnt_loc[33], W); + SM3_STEP2(34, G,H,A,B,C,D,E,F, SM3_cnt_loc[34], W); + SM3_STEP2(35, F,G,H,A,B,C,D,E, SM3_cnt_loc[35], W); + SM3_STEP2(36, E,F,G,H,A,B,C,D, SM3_cnt_loc[36], W); + SM3_STEP2(37, D,E,F,G,H,A,B,C, SM3_cnt_loc[37], W); + SM3_STEP2(38, C,D,E,F,G,H,A,B, SM3_cnt_loc[38], W); + SM3_STEP2(39, B,C,D,E,F,G,H,A, SM3_cnt_loc[39], W); + + SM3_STEP2(40, A,B,C,D,E,F,G,H, SM3_cnt_loc[40], W); + SM3_STEP2(41, H,A,B,C,D,E,F,G, SM3_cnt_loc[41], W); + SM3_STEP2(42, G,H,A,B,C,D,E,F, SM3_cnt_loc[42], W); + SM3_STEP2(43, F,G,H,A,B,C,D,E, SM3_cnt_loc[43], W); + SM3_STEP2(44, E,F,G,H,A,B,C,D, SM3_cnt_loc[44], W); + SM3_STEP2(45, D,E,F,G,H,A,B,C, SM3_cnt_loc[45], W); + SM3_STEP2(46, C,D,E,F,G,H,A,B, SM3_cnt_loc[46], W); + SM3_STEP2(47, B,C,D,E,F,G,H,A, SM3_cnt_loc[47], W); + + SM3_STEP2(48, A,B,C,D,E,F,G,H, SM3_cnt_loc[48], W); + SM3_STEP2(49, H,A,B,C,D,E,F,G, SM3_cnt_loc[49], W); + SM3_STEP2(50, G,H,A,B,C,D,E,F, SM3_cnt_loc[50], W); + SM3_STEP2(51, F,G,H,A,B,C,D,E, SM3_cnt_loc[51], W); + SM3_STEP3(52, E,F,G,H,A,B,C,D, SM3_cnt_loc[52], W); + SM3_STEP3(53, D,E,F,G,H,A,B,C, SM3_cnt_loc[53], W); + SM3_STEP3(54, C,D,E,F,G,H,A,B, SM3_cnt_loc[54], W); + SM3_STEP3(55, B,C,D,E,F,G,H,A, SM3_cnt_loc[55], W); + + SM3_STEP3(56, A,B,C,D,E,F,G,H, SM3_cnt_loc[56], W); + SM3_STEP3(57, H,A,B,C,D,E,F,G, SM3_cnt_loc[57], W); + SM3_STEP3(58, G,H,A,B,C,D,E,F, SM3_cnt_loc[58], W); + SM3_STEP3(59, F,G,H,A,B,C,D,E, SM3_cnt_loc[59], W); + SM3_STEP3(60, E,F,G,H,A,B,C,D, SM3_cnt_loc[60], W); + SM3_STEP3(61, D,E,F,G,H,A,B,C, SM3_cnt_loc[61], W); + SM3_STEP3(62, C,D,E,F,G,H,A,B, SM3_cnt_loc[62], W); + SM3_STEP3(63, B,C,D,E,F,G,H,A, SM3_cnt_loc[63], W); + } + /* update hash */ + hash[0] ^= A; + hash[1] ^= B; + hash[2] ^= C; + hash[3] ^= D; + hash[4] ^= E; + hash[5] ^= F; + hash[6] ^= G; + hash[7] ^= H; + } +} +#endif + +#endif /* _PX/_W7/_T7, _MX/_M7 versions */ +#endif /* IPP_ALG_HASH_SM3 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224.c new file mode 100644 index 000000000..64f5cf877 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA224 +// +// Contents: +// ippsHashStateMethodSet_SHA224() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA224 +// +// Purpose: Setup SHA224 method inside the hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA224, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha224_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha224_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224_ni.c new file mode 100644 index 000000000..650b19dce --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224_ni.c @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA224 +// +// Contents: +// ippsHashStateMethodSet_SHA224_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA224_NI +// +// Purpose: Setup SHA224 method inside the hash state (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNotSupportedModeErr mode disabled by configuration +// ippStsNoErr no errors +// +*F*/ + + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA224_NI, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + pMethod->hashAlgId = ippHashAlg_SHA224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha224_hashInit; + pMethod->hashUpdate = sha256_ni_hashUpdate; + pMethod->hashOctStr = sha224_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +#else + pMethod->hashAlgId = ippHashAlg_Unknown; + pMethod->hashLen = 0; + pMethod->msgBlkSize = 0; + pMethod->msgLenRepSize = 0; + pMethod->hashInit = 0; + pMethod->hashUpdate = 0; + pMethod->hashOctStr = 0; + pMethod->msgLenRep = 0; + + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224_tt.c new file mode 100644 index 000000000..0092d0d6b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha224_tt.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA224 +// +// Contents: +// ippsHashStateMethodSet_SHA224_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA224_TT +// +// Purpose: Setup SHA224 method inside the hash state +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA224_TT, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha224_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha224_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + pMethod->hashUpdate = sha256_ni_hashUpdate; +#endif + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256.c new file mode 100644 index 000000000..10d12f657 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashStateMethodSet_SHA256() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA256 +// +// Purpose: Setup SHA256 method inside the hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA256, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha256_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha256_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256_ni.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256_ni.c new file mode 100644 index 000000000..accb3484e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256_ni.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashStateMethodSet_SHA256_NI() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA256_NI +// +// Purpose: Setup SHA256 method inside the hash state (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instruction set). +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNotSupportedModeErr mode disabled by configuration +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA256_NI, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + pMethod->hashAlgId = ippHashAlg_SHA256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha256_hashInit; + pMethod->hashUpdate = sha256_ni_hashUpdate; + pMethod->hashOctStr = sha256_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + + return ippStsNoErr; +#else + pMethod->hashAlgId = ippHashAlg_Unknown; + pMethod->hashLen = 0; + pMethod->msgBlkSize = 0; + pMethod->msgLenRepSize = 0; + pMethod->hashInit = 0; + pMethod->hashUpdate = 0; + pMethod->hashOctStr = 0; + pMethod->msgLenRep = 0; + + return ippStsNotSupportedModeErr; +#endif +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256_tt.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256_tt.c new file mode 100644 index 000000000..4c6291758 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha256_tt.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsHashStateMethodSet_SHA256_TT() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA256_TT +// +// Purpose: Setup SHA256 method inside the hash state +// (using the Intel® Secure Hash Algorithm - New Instructions (Intel® SHA-NI) instructions set +// if it is available at run time) +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA256_TT, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA256; + pMethod->msgLenRepSize = MLR_SHA256; + pMethod->hashInit = sha256_hashInit; + pMethod->hashUpdate = sha256_hashUpdate; + pMethod->hashOctStr = sha256_hashOctString; + pMethod->msgLenRep = sha256_msgRep; + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) + if(IsFeatureEnabled(ippCPUID_SHA)) + pMethod->hashUpdate = sha256_ni_hashUpdate; +#endif + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha384.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha384.c new file mode 100644 index 000000000..4203d6300 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha384.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA384 message digest +// +// Contents: +// ippsHashStateMethodSet_SHA384() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA384 +// +// Purpose: Setup SHA384 method inside the hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA384, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA384; + pMethod->hashLen = IPP_SHA384_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_384_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_384_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512.c new file mode 100644 index 000000000..bffc44523 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashStateMethodSet_SHA512() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA512 +// +// Purpose: Setup SHA512 method inside the hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA512, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA512; + pMethod->hashLen = IPP_SHA512_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512_224.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512_224.c new file mode 100644 index 000000000..165cd36c3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512_224.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashStateMethodSet_SHA512_224() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA512_224 +// +// Purpose: Return SHA512_224 method inside the hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA512_224, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA512_224; + pMethod->hashLen = IPP_SHA224_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_224_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_224_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512_256.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512_256.c new file mode 100644 index 000000000..fb4fe5b7e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sha512_256.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsHashStateMethodSet_SHA512_256() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SHA512_256 +// +// Purpose: Setup SHA512_256 method inside the hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ + +IPPFUN( IppStatus, ippsHashStateMethodSet_SHA512_256, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SHA512_256; + pMethod->hashLen = IPP_SHA256_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SHA512; + pMethod->msgLenRepSize = MLR_SHA512; + pMethod->hashInit = sha512_256_hashInit; + pMethod->hashUpdate = sha512_hashUpdate; + pMethod->hashOctStr = sha512_256_hashOctString; + pMethod->msgLenRep = sha512_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sm3.c b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sm3.c new file mode 100644 index 000000000..7fc83d653 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashstatemethodset_sm3.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2022 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsHashStateMethodSet_SM3() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" + +/*F* +// Name: ippsHashStateMethodSet_SM3 +// +// Purpose: Setup SM3 method inside the hash state. +// +// Returns: Reason: +// ippStsNullPtrErr pMethod == NULL or pState == NULL +// ippStsNoErr no errors +// +*F*/ +IPPFUN( IppStatus, ippsHashStateMethodSet_SM3, (IppsHashState_rmf* pState, IppsHashMethod* pMethod) ) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pMethod); + + HASH_METHOD(pState) = pMethod; + + pMethod->hashAlgId = ippHashAlg_SM3; + pMethod->hashLen = IPP_SM3_DIGEST_BITSIZE/8; + pMethod->msgBlkSize = MBS_SM3; + pMethod->msgLenRepSize = MLR_SM3; + pMethod->hashInit = sm3_hashInit; + pMethod->hashUpdate = sm3_hashUpdate; + pMethod->hashOctStr = sm3_hashOctString; + pMethod->msgLenRep = sm3_msgRep; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashunpack.c b/plugin/ippcp/library/src/sources/ippcp/pcphashunpack.c new file mode 100644 index 000000000..557086bae --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashunpack.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashUnpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashUnpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pBuffer == NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the source buffer +// pState pointer hash state +// +*F*/ +IPPFUN(IppStatus, ippsHashUnpack,(const Ipp8u* pBuffer, IppsHashState* pState)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + + CopyBlock(pBuffer, pState, sizeof(IppsHashState)); + HASH_SET_ID(pState, idCtxHash); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashunpack_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashunpack_rmf.c new file mode 100644 index 000000000..fe75e2e2a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashunpack_rmf.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashUnpack_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashUnpack_rmf +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pBuffer == NULL +// pState == NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the source buffer +// pState pointer hash state +// +*F*/ +IPPFUN(IppStatus, ippsHashUnpack_rmf,(const Ipp8u* pBuffer, IppsHashState_rmf* pState)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + + CopyBlock(pBuffer, pState, sizeof(IppsHashState_rmf)); + HASH_SET_ID(pState, idCtxHash); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashupdate.c b/plugin/ippcp/library/src/sources/ippcp/pcphashupdate.c new file mode 100644 index 000000000..68ed9b88a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashupdate.c @@ -0,0 +1,137 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// General Functionality +// +// Contents: +// ippsHashUpdate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + + +/*F* +// Name: ippsHashUpdate +// +// Purpose: Updates intermediate hash value based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pSrc==0 but len!=0 +// ippStsContextMatchErr pState->idCtx != idCtxHash +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the Hash context +// +*F*/ +__INLINE int IsExceedMsgLen(Ipp64u maxLo, Ipp64u maxHi, Ipp64u lenLo, Ipp64u lenHi) +{ + int isExceed = lenLo > maxLo; + isExceed = (lenHi+(Ipp64u)isExceed) > maxHi; + return isExceed; +} + +IPPFUN(IppStatus, ippsHashUpdate,(const Ipp8u* pSrc, int len, IppsHashState* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + /* test the context */ + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + /* test input length */ + IPP_BADARG_RET((len<0 && pSrc), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + /* handle non empty input */ + if(len) { + const cpHashAttr* pAttr = &cpHashAlgAttr[HASH_ALG_ID(pState)]; + + /* test if size of message is being processed not exceeded yet */ + Ipp64u lenLo = HASH_LENLO(pState); + Ipp64u lenHi = HASH_LENHI(pState); + lenLo += (Ipp64u)len; + if(lenLo < HASH_LENLO(pState)) lenHi++; + if(IsExceedMsgLen(pAttr->msgLenMax[0],pAttr->msgLenMax[1], lenLo,lenHi)) + IPP_ERROR_RET(ippStsLengthErr); + + else { + cpHashProc hashFunc = HASH_FUNC(pState); /* processing function */ + const void* pParam = HASH_FUNC_PAR(pState); /* and it's addition params */ + int mbs = pAttr->msgBlkSize; /* data block size */ + + /* + // processing + */ + { + int procLen; + + /* test if internal buffer is not empty */ + int n = HASH_BUFFIDX(pState); + if(n) { + procLen = IPP_MIN(len, (mbs-n)); + CopyBlock(pSrc, HASH_BUFF(pState)+n, procLen); + HASH_BUFFIDX(pState) = n += procLen; + + /* block processing */ + if(mbs==n) { + hashFunc(HASH_VALUE(pState), HASH_BUFF(pState), mbs, pParam); + HASH_BUFFIDX(pState) = 0; + } + + /* update message pointer and length */ + pSrc += procLen; + len -= procLen; + } + + /* main processing part */ + procLen = len & ~(mbs-1); + if(procLen) { + hashFunc(HASH_VALUE(pState), pSrc, procLen, pParam); + pSrc += procLen; + len -= procLen; + } + + /* rest of input message */ + if(len) { + CopyBlock(pSrc, HASH_BUFF(pState), len); + HASH_BUFFIDX(pState) += len; + } + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_LENHI(pState) = lenHi; + + return ippStsNoErr; + } + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphashupdate_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphashupdate_rmf.c new file mode 100644 index 000000000..78bbdf207 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphashupdate_rmf.c @@ -0,0 +1,115 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Security Hash Standard +// Generalized Functionality +// +// Contents: +// ippsHashUpdate_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHashUpdate_rmf +// +// Purpose: Updates intermediate hash value based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// ippStsNullPtrErr pSrc==0 but len!=0 +// ippStsContextMatchErr pState->idCtx != idCtxHash +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the Hash context +// +*F*/ +IPPFUN(IppStatus, ippsHashUpdate_rmf,(const Ipp8u* pSrc, int len, IppsHashState_rmf* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxHash), ippStsContextMatchErr); + + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + if(len) { + const IppsHashMethod* method = HASH_METHOD(pState); + hashUpdateF hashFunc = method->hashUpdate; /* processing function */ + int msgBlkSize = method->msgBlkSize; /* messge block size */ + + int procLen; + + int idx = HASH_BUFFIDX(pState); + Ipp64u lenLo = HASH_LENLO(pState); + Ipp64u lenHi = HASH_LENHI(pState); + lenLo += (Ipp64u)len; + if(lenLo < HASH_LENLO(pState)) lenHi++; + + /* if internal buffer is not empty */ + if(idx) { + procLen = IPP_MIN(len, (msgBlkSize-idx)); + CopyBlock(pSrc, HASH_BUFF(pState)+idx, procLen); + idx += procLen; + + /* process complete message block */ + if(msgBlkSize==idx) { + hashFunc(HASH_VALUE(pState), HASH_BUFF(pState), msgBlkSize); + idx = 0; + } + + /* update message pointer and length */ + pSrc += procLen; + len -= procLen; + } + + /* process main part of the input*/ + procLen = len & ~(msgBlkSize-1); + if(procLen) { + hashFunc(HASH_VALUE(pState), pSrc, procLen); + pSrc += procLen; + len -= procLen; + } + + /* store the rest of input in the buffer */ + if(len) { + CopyBlock(pSrc, HASH_BUFF(pState), len); + idx += len; + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_LENHI(pState) = lenHi; + HASH_BUFFIDX(pState) = idx; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac.h b/plugin/ippcp/library/src/sources/ippcp/pcphmac.h new file mode 100644 index 000000000..0eb369165 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac.h @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Hash Message Authentication Code +// Internal Definitions and Internal Functions Prototypes +// +// +*/ + +#if !defined(_PCP_HMAC_H) +#define _PCP_HMAC_H + +#include "pcphash.h" + +/* +// HMAC context +*/ +struct _cpHMAC { + Ipp32u idCtx; /* HMAC identifier */ + Ipp8u ipadKey[MBS_HASH_MAX]; /* inner padding key */ + Ipp8u opadKey[MBS_HASH_MAX]; /* outer padding key */ + IppsHashState hashCtx; /* hash context */ +}; + +/* accessors */ +#define HMAC_SET_CTX_ID(stt) ((stt)->idCtx = (Ipp32u)idCtxHMAC ^ (Ipp32u)IPP_UINT_PTR(stt)) +#define HMAC_RESET_CTX_ID(stt) ((stt)->idCtx = idCtxHMAC) +#define HASH_CTX(stt) ((stt)->hashCtx) +#define HMAC_VALID_ID(stt) ((((stt)->idCtx) ^ (Ipp32u)IPP_INT_PTR((stt))) == (Ipp32u)idCtxHMAC) + +#define IPAD (0x36) /* inner padding value */ +#define OPAD (0x5C) /* outer padding value */ + +#endif /* _PCP_HMAC_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_duplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_duplicate.c new file mode 100644 index 000000000..82d9d1418 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_duplicate.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_Duplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_Duplicate +// +// Purpose: Clone HMAC state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxHMAC +// pDstState->idCtx != idCtxHMAC +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source HMAC state +// pDstState pointer to the target HMAC state +// +// Note: +// pDstState may not to be initialized by ippsHMACInit() +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_Duplicate,(const IppsHMACState* pSrcCtx, IppsHMACState* pDstCtx)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcCtx, pDstCtx); + /* test states ID */ + IPP_BADARG_RET(!HMAC_VALID_ID(pSrcCtx), ippStsContextMatchErr); + + /* copy HMAC state without Hash context */ + CopyBlock(pSrcCtx, pDstCtx, (int)(IPP_UINT_PTR(&HASH_CTX(pSrcCtx)) - IPP_UINT_PTR(pSrcCtx))); + HMAC_SET_CTX_ID(pDstCtx); + /* copy Hash context separately */ + ippsHashDuplicate(&HASH_CTX(pSrcCtx), &HASH_CTX(pDstCtx)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_final.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_final.c new file mode 100644 index 000000000..b478d1ce8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_final.c @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHMAC +// ippStsLengthErr sizeof(DigestMD5) < mdLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the HMAC state +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_Final,(Ipp8u* pMD, int mdLen, IppsHMACState* pCtx)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test MD pointer and length */ + IPP_BAD_PTR1_RET(pMD); + IPP_BADARG_RET(mdLen<=0, ippStsLengthErr); + + { + /* hash specific */ + IppsHashState* pHashCtx = &HASH_CTX(pCtx); + int mbs = cpHashMBS(HASH_ALG_ID(pHashCtx)); + int hashSize = cpHashSize(HASH_ALG_ID(pHashCtx)); + if(mdLen>hashSize) + IPP_ERROR_RET(ippStsLengthErr); + + /* + // finalize hmac + */ + { + /* finalize 1-st step */ + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/8]; + IppStatus sts = ippsHashFinal(md, pHashCtx); + + if(ippStsNoErr==sts) { + /* perform outer hash */ + ippsHashUpdate(pCtx->opadKey, mbs, pHashCtx); + ippsHashUpdate(md, hashSize, pHashCtx); + + /* complete HMAC */ + ippsHashFinal(md, pHashCtx); + CopyBlock(md, pMD, IPP_MIN(hashSize, mdLen)); + + /* ready to the next HMAC computation */ + ippsHashUpdate(pCtx->ipadKey, mbs, pHashCtx); + } + + return sts; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_getsize.c new file mode 100644 index 000000000..83a0ad6f7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_getsize.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_GetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_GetSize +// +// Purpose: Returns size of HMAC state (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSzie == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the HMAC state size +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_GetSize,(int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsHMACState); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_gettag.c new file mode 100644 index 000000000..a4ca40e1e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_gettag.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_GetTag +// +// Purpose: Compute digest with further digesting ability. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHMAC +// ippStsLengthErr size_of_digest < mdLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// mdLen length of the digest +// pState pointer to the HMAC state +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_GetTag,(Ipp8u* pMD, int mdLen, const IppsHMACState* pCtx)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test MD pointer */ + IPP_BAD_PTR1_RET(pMD); + + { /* TBD: consider implementation without copy of context */ + IppStatus sts; + IppsHMACState tmpCtx; + ippsHMAC_Duplicate(pCtx, &tmpCtx); + sts = ippsHMAC_Final(pMD, mdLen, &tmpCtx); + + PurgeBlock(&tmpCtx, sizeof(IppsHMACState)); + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_init.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_init.c new file mode 100644 index 000000000..8a4d815e7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_init.c @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_Init() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_Init +// +// Purpose: Init HMAC state. +// +// Returns: Reason: +// ippStsNullPtrErr pKey == NULL +// pState == NULL +// ippStsLengthErr keyLen <0 +// ippStsNotSupportedModeErr if algID is not match to supported hash alg +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length (bytes) of the secret key +// pState pointer to the HMAC state +// hashAlg hash alg ID +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_Init,(const Ipp8u* pKey, int keyLen, IppsHMACState* pCtx, IppHashAlgId hashAlg)) +{ + //int mbs; + + /* get algorithm id */ + hashAlg = cpValidHashAlg(hashAlg); + /* test hash alg */ + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + //mbs = cpHashMBS(hashAlg); + + /* test pState pointer */ + IPP_BAD_PTR1_RET(pCtx); + + /* test key pointer and key length */ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(0>keyLen, ippStsLengthErr); + + /* set state ID */ + HMAC_SET_CTX_ID(pCtx); + + /* init hash context */ + ippsHashInit(&HASH_CTX(pCtx), hashAlg); + + { + int n; + + /* hash specific */ + IppsHashState* pHashCtx = &HASH_CTX(pCtx); + int mbs = cpHashMBS(hashAlg); + int hashSize = cpHashSize(hashAlg); + + /* copyMask = keyLen>mbs? 0xFF : 0x00 */ + int copyMask = (mbs-keyLen) >>(BITSIZE(int)-1); + + /* actualKeyLen = keyLen>mbs? hashSize:keyLen */ + int actualKeyLen = (hashSize & copyMask) | (keyLen & ~copyMask); + + /* compute hash(key, keyLen) just in case */ + ippsHashUpdate(pKey, keyLen, pHashCtx); + ippsHashFinal(HASH_BUFF(pHashCtx), pHashCtx); + + /* copy either key or hash(key) into ipad- and opad- buffers */ + MASKED_COPY_BNU(pCtx->ipadKey, (Ipp8u)copyMask, HASH_BUFF(pHashCtx), pKey, actualKeyLen); + MASKED_COPY_BNU(pCtx->opadKey, (Ipp8u)copyMask, HASH_BUFF(pHashCtx), pKey, actualKeyLen); + + /* XOR-ing key */ + for(n=0; nipadKey[n] ^= (Ipp8u)IPAD; + pCtx->opadKey[n] ^= (Ipp8u)OPAD; + } + for(; nipadKey[n] = (Ipp8u)IPAD; + pCtx->opadKey[n] = (Ipp8u)OPAD; + } + + /* ipad key processing */ + ippsHashUpdate(pCtx->ipadKey, mbs, pHashCtx); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_message.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_message.c new file mode 100644 index 000000000..e3d41c0d4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_message.c @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_Message() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_Message +// +// Purpose: MAC (MD5) of the whole message. +// +// Returns: Reason: +// ippStsNullPtrErr pMsg == NULL +// pKey == NULL +// pMD == NULL +// ippStsLengthErr msgLen <0 +// keyLen <0 +// size_of_digest < mdLen <1 +// ippStsNotSupportedModeErr if algID is not match to supported hash alg +// ippStsNoErr no errors +// +// Parameters: +// pMsg pointer to the input message +// msgLen input message length +// pKey pointer to the secret key +// keyLen secret key length +// pMD pointer to message digest +// mdLen MD length +// hashAlg hash alg ID +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_Message,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pKey, int keyLen, + Ipp8u* pMD, int mdLen, + IppHashAlgId hashAlg)) +{ + /* get algorithm id */ + hashAlg = cpValidHashAlg(hashAlg); + /* test hash alg */ + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + + /* test secret key pointer and length */ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET((keyLen<0), ippStsLengthErr); + + /* test input message pointer and length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + /* test MD pointer and length */ + IPP_BAD_PTR1_RET(pMD); + IPP_BADARG_RET(0>=mdLen || mdLen>cpHashSize(hashAlg), ippStsLengthErr); + + { + __ALIGN8 IppsHMACState ctx; + IppStatus sts = ippsHMAC_Init(pKey, keyLen, &ctx, hashAlg); + if(ippStsNoErr!=sts) goto exit; + + sts = ippsHashUpdate(pMsg,msgLen, &HASH_CTX(&ctx)); + if(ippStsNoErr!=sts) goto exit; + + sts = ippsHMAC_Final(pMD, mdLen, &ctx); + + exit: + PurgeBlock(&ctx, sizeof(IppsHMACState)); + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_pack.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_pack.c new file mode 100644 index 000000000..1188ebb94 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_pack.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_Pack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_Pack +// +// Purpose: Copy initialized context to the buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pCtx == NULL +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer keyed hash state +// pBuffer pointer to the destination buffer +// bufSize size of destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_Pack,(const IppsHMACState* pCtx, Ipp8u* pBuffer, int bufSize)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + /* test the context */ + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + + { + int ctxSize; + ippsHMAC_GetSize(&ctxSize); + /* test buffer length */ + IPP_BADARG_RET(ctxSize>bufSize, ippStsNoMemErr); + + CopyBlock(pCtx, pBuffer, ctxSize); + + /* Reset IppsHMACState context id */ + IppsHMACState* pCopy = (IppsHMACState*)pBuffer; + HMAC_RESET_CTX_ID(pCopy); + /* Reset context id for IppsHashState, which is the part of IppsHMACState */ + IppsHashState* pHashCopy = (IppsHashState*)&HASH_CTX(pCopy); + HASH_RESET_ID(pHashCopy,idCtxHash); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_rmf.h b/plugin/ippcp/library/src/sources/ippcp/pcphmac_rmf.h new file mode 100644 index 000000000..9ddb5ce07 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_rmf.h @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// Hash Message Authentication Code +// Internal Definitions and Internal Functions Prototypes +*/ + +#if !defined(_PCP_HMAC_RMF_H) +#define _PCP_HMAC_RMF_H + +#include "pcphash_rmf.h" + +/* +// HMAC context +*/ +struct _cpHMAC_rmf { + Ipp32u idCtx; /* HMAC identifier */ + Ipp8u ipadKey[MBS_HASH_MAX]; /* inner padding key */ + Ipp8u opadKey[MBS_HASH_MAX]; /* outer padding key */ + IppsHashState_rmf hashCtx; /* hash context */ +}; + + +#endif /* _PCP_HMAC_RMF_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_unpack.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_unpack.c new file mode 100644 index 000000000..40d045f0b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_unpack.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_Unpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_Unpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pCtx == NULL +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer keyed hash state +// pSize pointer to the packed spec size +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_Unpack,(const Ipp8u* pBuffer, IppsHMACState* pCtx)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + + CopyBlock(pBuffer, pCtx, sizeof(IppsHMACState)); + /* Set IppsHMACState context id */ + HMAC_SET_CTX_ID(pCtx); + /* Set context id for IppsHashState, which is the part of IppsHMACState */ + HASH_SET_ID(&HASH_CTX(pCtx),idCtxHash); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmac_update.c b/plugin/ippcp/library/src/sources/ippcp/pcphmac_update.c new file mode 100644 index 000000000..51295d4ad --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmac_update.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMAC_Update() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMAC_Update +// +// Purpose: Updates intermadiate MAC based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHMAC +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the HMAC state +// +*F*/ +IPPFUN(IppStatus, ippsHMAC_Update,(const Ipp8u* pSrc, int len, IppsHMACState* pCtx)) +{ + /* test state pointers */ + IPP_BAD_PTR1_RET(pCtx); + + /* test state ID */ + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + if(len) + return ippsHashUpdate(pSrc, len, &HASH_CTX(pCtx)); + else + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacca_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacca_rmf.c new file mode 100644 index 000000000..7b080b489 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacca_rmf.c @@ -0,0 +1,107 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACInit_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACInit_rmf +// +// Purpose: Init HMAC state. +// +// Returns: Reason: +// ippStsNullPtrErr pKey == NULL +// pState == NULL +// ippStsLengthErr keyLen <0 +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length (bytes) of the secret key +// pState pointer to the HMAC state +// pMethod hash method +// +*F*/ +IPPFUN(IppStatus, ippsHMACInit_rmf,(const Ipp8u* pKey, int keyLen, + IppsHMACState_rmf* pCtx, + const IppsHashMethod* pMethod)) +{ + /* test pointer */ + IPP_BAD_PTR2_RET(pCtx, pMethod); + + /* test key pointer and key length */ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(0>keyLen, ippStsLengthErr); + + /* set state ID */ + HMAC_SET_CTX_ID(pCtx); + + /* init hash context */ + ippsHashInit_rmf(&HASH_CTX(pCtx), pMethod); + + { + int n; + + /* hash specific */ + IppsHashState_rmf* pHashCtx = &HASH_CTX(pCtx); + int mbs = pMethod->msgBlkSize; + int hashSize = pMethod->hashLen; + + /* copyMask = keyLen>mbs? 0xFF : 0x00 */ + int copyMask = (mbs-keyLen) >>(BITSIZE(int)-1); + + /* actualKeyLen = keyLen>mbs? hashSize:keyLen */ + int actualKeyLen = (hashSize & copyMask) | (keyLen & ~copyMask); + + /* compute hash(key, keyLen) just in case */ + ippsHashUpdate_rmf(pKey, keyLen, pHashCtx); + ippsHashFinal_rmf(HASH_BUFF(pHashCtx), pHashCtx); + + /* copy either key or hash(key) into ipad- and opad- buffers */ + MASKED_COPY_BNU(pCtx->ipadKey, (Ipp8u)copyMask, HASH_BUFF(pHashCtx), pKey, actualKeyLen); + MASKED_COPY_BNU(pCtx->opadKey, (Ipp8u)copyMask, HASH_BUFF(pHashCtx), pKey, actualKeyLen); + + /* XOR-ing key */ + for(n=0; nipadKey[n] ^= (Ipp8u)IPAD; + pCtx->opadKey[n] ^= (Ipp8u)OPAD; + } + for(; nipadKey[n] = (Ipp8u)IPAD; + pCtx->opadKey[n] = (Ipp8u)OPAD; + } + + /* ipad key processing */ + ippsHashUpdate_rmf(pCtx->ipadKey, mbs, pHashCtx); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacduplicate_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacduplicate_rmf.c new file mode 100644 index 000000000..ad5660e7e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacduplicate_rmf.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACDuplicate_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACDuplicate_rmf +// +// Purpose: Clone HMAC state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxHMAC +// pDstState->idCtx != idCtxHMAC +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source HMAC state +// pDstState pointer to the target HMAC state +// +// Note: +// pDstState may not to be initialized by ippsHMACInit_rmf() +// +*F*/ +IPPFUN(IppStatus, ippsHMACDuplicate_rmf,(const IppsHMACState_rmf* pSrcCtx, IppsHMACState_rmf* pDstCtx)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcCtx, pDstCtx); + /* test states ID */ + IPP_BADARG_RET(!HMAC_VALID_ID(pSrcCtx), ippStsContextMatchErr); + + /* copy HMAC state without Hash context */ + CopyBlock(pSrcCtx, pDstCtx, (int)(IPP_UINT_PTR(&HASH_CTX(pSrcCtx)) - IPP_UINT_PTR(pSrcCtx))); + HMAC_SET_CTX_ID(pDstCtx); + /* copy Hash context separately */ + ippsHashDuplicate_rmf(&HASH_CTX(pSrcCtx), &HASH_CTX(pDstCtx)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacfinal_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacfinal_rmf.c new file mode 100644 index 000000000..99504fa80 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacfinal_rmf.c @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACFinal_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACFinal_rmf +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHMAC +// ippStsLengthErr sizeof(DigestMD5) < mdLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the HMAC state +// +*F*/ +IPPFUN(IppStatus, ippsHMACFinal_rmf,(Ipp8u* pMD, int mdLen, IppsHMACState_rmf* pCtx)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test MD pointer and length */ + IPP_BAD_PTR1_RET(pMD); + IPP_BADARG_RET(mdLen<=0, ippStsLengthErr); + + { + /* hash specific */ + IppsHashState_rmf* pHashCtx = &HASH_CTX(pCtx); + const IppsHashMethod* method = HASH_METHOD(pHashCtx); + int mbs = method->msgBlkSize; + int hashSize = method->hashLen; + if(mdLen>hashSize) + IPP_ERROR_RET(ippStsLengthErr); + + /* + // finalize hmac + */ + { + /* finalize 1-st step */ + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/8]; + IppStatus sts = ippsHashFinal_rmf(md, pHashCtx); + + if(ippStsNoErr==sts) { + /* perform outer hash */ + ippsHashUpdate_rmf(pCtx->opadKey, mbs, pHashCtx); + ippsHashUpdate_rmf(md, hashSize, pHashCtx); + + /* complete HMAC */ + ippsHashFinal_rmf(md, pHashCtx); + CopyBlock(md, pMD, IPP_MIN(hashSize, mdLen)); + + /* ready to the next HMAC computation */ + ippsHashUpdate_rmf(pCtx->ipadKey, mbs, pHashCtx); + } + + return sts; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacgetsize_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacgetsize_rmf.c new file mode 100644 index 000000000..736e6ffe1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacgetsize_rmf.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACGetSize_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACGetSize_rmf +// +// Purpose: Returns size of HMAC state (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSzie == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the HMAC state size +// +*F*/ +IPPFUN(IppStatus, ippsHMACGetSize_rmf,(int* pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsHMACState_rmf); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacgettag_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacgettag_rmf.c new file mode 100644 index 000000000..ef4e363c8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacgettag_rmf.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACGetTag_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACGetTag_rmf +// +// Purpose: Compute digest with further digesting ability. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHMAC +// ippStsLengthErr size_of_digest < mdLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// mdLen length of the digest +// pState pointer to the HMAC state +// +*F*/ +IPPFUN(IppStatus, ippsHMACGetTag_rmf,(Ipp8u* pMD, int mdLen, const IppsHMACState_rmf* pCtx)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test MD pointer */ + IPP_BAD_PTR1_RET(pMD); + + { /* TBD: consider implementation without copy of context */ + IppStatus sts; + IppsHMACState_rmf tmpCtx; + ippsHMACDuplicate_rmf(pCtx, &tmpCtx); + + sts = ippsHMACFinal_rmf(pMD, mdLen, &tmpCtx); + + PurgeBlock(&tmpCtx, sizeof(IppsHMACState_rmf)); + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacmessage_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacmessage_rmf.c new file mode 100644 index 000000000..e47d77248 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacmessage_rmf.c @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACMessage_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACMessage_rmf +// +// Purpose: MAC (MD5) of the whole message. +// +// Returns: Reason: +// ippStsNullPtrErr pMsg == NULL +// pKey == NULL +// pMD == NULL +// ippStsLengthErr msgLen <0 +// keyLen <0 +// size_of_digest < mdLen <1 +// ippStsNotSupportedModeErr if algID is not match to supported hash alg +// ippStsNoErr no errors +// +// Parameters: +// pMsg pointer to the input message +// msgLen input message length +// pKey pointer to the secret key +// keyLen secret key length +// pMD pointer to message digest +// mdLen MD length +// pMethod hash method +// +*F*/ +IPPFUN(IppStatus, ippsHMACMessage_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pKey, int keyLen, + Ipp8u* pMD, int mdLen, + const IppsHashMethod* pMethod)) +{ + /* test method pointer */ + IPP_BAD_PTR1_RET(pMethod); + /* test secret key pointer and length */ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET((keyLen<0), ippStsLengthErr); + /* test input message pointer and length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + /* test MD pointer and length */ + IPP_BAD_PTR1_RET(pMD); + IPP_BADARG_RET(0>=mdLen || mdLen>pMethod->hashLen, ippStsLengthErr); + + { + __ALIGN8 IppsHMACState_rmf ctx; + IppStatus sts; + + ippsHMACInit_rmf(pKey, keyLen, &ctx, pMethod); + + sts = ippsHashUpdate_rmf(pMsg,msgLen, &HASH_CTX(&ctx)); + if(ippStsNoErr!=sts) goto exit; + + sts = ippsHMACFinal_rmf(pMD, mdLen, &ctx); + + exit: + PurgeBlock(&ctx, sizeof(IppsHMACState_rmf)); + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacpack_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacpack_rmf.c new file mode 100644 index 000000000..9a6a05d8a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacpack_rmf.c @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACPack_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACPack_rmf +// +// Purpose: Copy initialized context to the buffer. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pBuffer == NULL +// ippStsNoErr no errors +// +// Parameters: +// pCtx pointer keyed hash state +// pBuffer pointer to the destination buffer +// bufSize size of destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsHMACPack_rmf,(const IppsHMACState_rmf* pCtx, Ipp8u* pBuffer, int bufSize)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + /* test the context */ + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + + { + int ctxSize; + ippsHMACGetSize_rmf(&ctxSize); + /* test buffer length */ + IPP_BADARG_RET(ctxSize>bufSize, ippStsNoMemErr); + + CopyBlock(pCtx, pBuffer, ctxSize); + + /* Reset IppsHMACState_rmf context id */ + IppsHMACState_rmf* pCopy = (IppsHMACState_rmf*)pBuffer; + HMAC_RESET_CTX_ID(pCopy); + /* Reset context id for IppsHashState_rmf, which is the part of IppsHMACState_rmf */ + IppsHashState_rmf* pHashCopy = (IppsHashState_rmf*)&HASH_CTX(pCopy); + HASH_RESET_ID(pHashCopy,idCtxHash); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacunpack_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacunpack_rmf.c new file mode 100644 index 000000000..2aec54527 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacunpack_rmf.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACUnpack_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACUnpack_rmf +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pBuffer == NULL +// pCtx == NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the source buffer +// pSize pointer to the packed spec size +// +*F*/ +IPPFUN(IppStatus, ippsHMACUnpack_rmf,(const Ipp8u* pBuffer, IppsHMACState_rmf* pCtx)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + + CopyBlock(pBuffer, pCtx, sizeof(IppsHMACState_rmf)); + + /* Set IppsHMACState_rmf context id */ + HMAC_SET_CTX_ID(pCtx); + /* Set context id for IppsHashState_rmf, which is the part of IppsHMACState_rmf */ + HASH_SET_ID(&HASH_CTX(pCtx),idCtxHash); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcphmacupdate_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcphmacupdate_rmf.c new file mode 100644 index 000000000..898b21361 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcphmacupdate_rmf.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HMAC General Functionality +// +// Contents: +// ippsHMACUpdate_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphmac.h" +#include "pcphmac_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsHMACUpdate_rmf +// +// Purpose: Updates intermadiate MAC based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxHMAC +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the HMAC state +// +*F*/ +IPPFUN(IppStatus, ippsHMACUpdate_rmf,(const Ipp8u* pSrc, int len, IppsHMACState_rmf* pCtx)) +{ + /* test state pointers */ + IPP_BAD_PTR1_RET(pCtx); + + /* test state ID */ + IPP_BADARG_RET(!HMAC_VALID_ID(pCtx), ippStsContextMatchErr); + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + if(len) + return ippsHashUpdate_rmf(pSrc, len, &HASH_CTX(pCtx)); + else + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmask_ct.h b/plugin/ippcp/library/src/sources/ippcp/pcpmask_ct.h new file mode 100644 index 000000000..0dc033d60 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmask_ct.h @@ -0,0 +1,162 @@ +/******************************************************************************* +* Copyright (C) 2018 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Constant time Mask operations +// +// +*/ + +#if !defined(_PCP_MASK_CT_H) +#define _PCP_MASK_CT_H + +#include "owncp.h" +#include "pcpbnuimpl.h" + +/* +// The following functions test particular conditions +// and returns either 0 or 0xffffffff. +// +// The result is suitable for boolean and masked operations. +// +// Inspite of operation below are using BNU_CHUNK_T operand(s) it can be applied to Ipp32u, Ipp32s, Ipp16u, Ipp16s, Ipp8u and Ipp8s too. +// For example, if +// Ipp32u uns_int; +// Ipp32s sgn_int; +// Ipp8u uns_char; +// Ipp8s sgn_char; +// then +// cpIs_msb_ct((Ipp32s)uns_int) tests 31 bit of uns_int +// cpIs_msb_ct( sgn_int) tests 31 bit of sgn_int +// cpIs_msb_ct((Ipp8u)uns_char) tests 7 bit of uns_char +// cpIs_msb_ct( sgn_char) tests 7 bit of sgn_char +*/ + + +/* Disable optimization for Clang compiler to produce constant execution time code */ +#if defined( __clang__ ) && !defined (__INTEL_COMPILER) + #pragma clang optimize off +#endif + +/* replace under mask: dst[] = replaceFlag? src[] : dst[] */ +__INLINE void cpMaskedReplace_ct(BNU_CHUNK_T* dst, const BNU_CHUNK_T* src, int len, BNU_CHUNK_T replaceMask) +{ + BNU_CHUNK_T dstMask = ~replaceMask; + int n; + for(n=0; n> (sizeof(a) * 8 - 1)); +} + +#if defined( __clang__ ) && !defined (__INTEL_COMPILER) + #pragma clang optimize on +#endif + +/* tests if LSB(a)==1 */ +__INLINE BNU_CHUNK_T cpIsLsb_ct(BNU_CHUNK_T a) +{ + return (BNU_CHUNK_T)0 - (a & 1); +} + +/* tests if a is odd */ +__INLINE BNU_CHUNK_T cpIsOdd_ct(BNU_CHUNK_T a) +{ + return cpIsLsb_ct(a); +} + +/* tests if a is even */ +__INLINE BNU_CHUNK_T cpIsEven_ct(BNU_CHUNK_T a) +{ + return ~cpIsLsb_ct(a); +} + +/* tests if a==0 */ +__INLINE BNU_CHUNK_T cpIsZero_ct(BNU_CHUNK_T a) +{ + return cpIsMsb_ct(~a & (a - 1)); +} + +/* tests if a==b */ +__INLINE BNU_CHUNK_T cpIsEqu_ct(BNU_CHUNK_T a, BNU_CHUNK_T b) +{ + return cpIsZero_ct(a ^ b); +} + +/* test if aidCtx != idCtxMD5 +// pDstState->idCtx != idCtxMD5 +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source MD5 state +// pDstState pointer to the target MD5 state +// +// Note: +// pDstState may to be uninitialized by ippsMD5Init() +// +*F*/ +IPPFUN(IppStatus, ippsMD5Duplicate,(const IppsMD5State* pSrcState, IppsMD5State* pDstState)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcState, pDstState); + IPP_BADARG_RET(!HASH_VALID_ID(pSrcState, idCtxMD5), ippStsContextMatchErr); + + /* copy state */ + CopyBlock(pSrcState, pDstState, sizeof(IppsMD5State)); + HASH_SET_ID(pDstState, idCtxMD5); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmd5final.c b/plugin/ippcp/library/src/sources/ippcp/pcpmd5final.c new file mode 100644 index 000000000..4d4dd8e1e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmd5final.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// ippsMD5Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpmd5stuff.h" + +/*F* +// Name: ippsMD5Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxMD5 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the MD5 state +// +*F*/ +IPPFUN(IppStatus, ippsMD5Final,(Ipp8u* pMD, IppsMD5State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxMD5), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + + cpFinalizeMD5(HASH_VALUE(pState), HASH_BUFF(pState), HASH_BUFFIDX(pState), HASH_LENLO(pState)); + CopyBlock(HASH_VALUE(pState), pMD, sizeof(DigestMD5)); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + md5_hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmd5getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpmd5getsize.c new file mode 100644 index 000000000..b931f5696 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmd5getsize.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// ippsMD5GetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsMD5GetSize +// +// Purpose: Returns size (bytes) of IppsMD5State state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to size +// +*F*/ +IPPFUN(IppStatus, ippsMD5GetSize,(int* pSize)) +{ + /* test pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsMD5State); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmd5gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpmd5gettag.c new file mode 100644 index 000000000..f772a60f1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmd5gettag.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// ippsMD5GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpmd5stuff.h" + +/*F* +// Name: ippsMD5GetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxMD5 +// ippStsLengthErr max_MD5_digestLen < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the MD5 state +// +*F*/ +IPPFUN(IppStatus, ippsMD5GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsMD5State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxMD5), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen<1)||(sizeof(DigestMD5)idCtx != idCtxMD5 +// ippStsNoErr no errors +// +// Parameters: +// pState pointer hash state +// pBuffer pointer to the destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsMD5Pack,(const IppsMD5State* pState, Ipp8u* pBuffer)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxMD5), ippStsContextMatchErr); + + CopyBlock(pState, pBuffer, sizeof(IppsMD5State)); + IppsMD5State* pCopy = (IppsMD5State*)pBuffer; + HASH_RESET_ID(pCopy, idCtxMD5); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmd5stuff.h b/plugin/ippcp/library/src/sources/ippcp/pcpmd5stuff.h new file mode 100644 index 000000000..f5a86bc48 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmd5stuff.h @@ -0,0 +1,100 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// MD4 methods and constants +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +#if !defined(_PCP_MD5_STUFF_H) +#define _PCP_MD5_STUFF_H + +/* MD5 constants */ +static const Ipp32u md5_iv[] = { + 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476}; + +static __ALIGN16 const Ipp32u md5_cnt[] = { + 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, + 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, + 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, + 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, + + 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, + 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, + 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, + 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, + + 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, + 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, + 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, + 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, + + 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, + 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, + 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, + 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 +}; + +IPP_OWN_DEFN (static void, md5_hashInit, (void* pHash)) +{ + /* setup initial digest */ + ((Ipp32u*)pHash)[0] = md5_iv[0]; + ((Ipp32u*)pHash)[1] = md5_iv[1]; + ((Ipp32u*)pHash)[2] = md5_iv[2]; + ((Ipp32u*)pHash)[3] = md5_iv[3]; +} + +IPP_OWN_DEFN (static void, md5_hashUpdate, (void* pHash, const Ipp8u* pMsg, int msgLen)) +{ + UpdateMD5(pHash, pMsg, msgLen, md5_cnt); +} + +IPP_OWN_DEFN (static void, md5_hashOctString, (Ipp8u* pMD, void* pHashVal)) +{ + /* md5 does not need conversion into big endian */ + ((Ipp32u*)pMD)[0] = ((Ipp32u*)pHashVal)[0]; + ((Ipp32u*)pMD)[1] = ((Ipp32u*)pHashVal)[1]; + ((Ipp32u*)pMD)[2] = ((Ipp32u*)pHashVal)[2]; + ((Ipp32u*)pMD)[3] = ((Ipp32u*)pHashVal)[3]; +} + +IPP_OWN_DEFN (static void, md5_msgRep, (Ipp8u* pDst, Ipp64u lenLo, Ipp64u lenHi)) +{ + IPP_UNREFERENCED_PARAMETER(lenHi); + lenLo <<= 3; + ((Ipp64u*)(pDst))[0] = lenLo; +} + +#define cpFinalizeMD5 OWNAPI(cpFinalizeMD5) + IPP_OWN_DECL (void, cpFinalizeMD5, (DigestMD5 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u processedMsgLen)) + +#endif /* #if !defined(_PCP_MD5_STUFF_H) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmd5unpack.c b/plugin/ippcp/library/src/sources/ippcp/pcpmd5unpack.c new file mode 100644 index 000000000..94b3c08ab --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmd5unpack.c @@ -0,0 +1,60 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// ippsMD5Unpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsMD5Unpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pBuffer == NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the input buffer +// pState pointer hash state +// +*F*/ +IPPFUN(IppStatus, ippsMD5Unpack,(const Ipp8u* pBuffer, IppsMD5State* pState)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + + CopyBlock(pBuffer, pState, sizeof(IppsMD5State)); + HASH_SET_ID(pState, idCtxMD5); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmd5update.c b/plugin/ippcp/library/src/sources/ippcp/pcpmd5update.c new file mode 100644 index 000000000..ea1ab76f9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmd5update.c @@ -0,0 +1,116 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to MD5 +// (derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm) +// +// Equivalent code is available from RFC 1321. +// +// Contents: +// ippsMD5Update() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpmd5stuff.h" + +/*F* +// Name: ippsMD5Update +// +// Purpose: Updates intermadiate digest based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxMD5 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the MD5 state +// +*F*/ +IPPFUN(IppStatus, ippsMD5Update,(const Ipp8u* pSrc, int len, IppsMD5State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxMD5), ippStsContextMatchErr); + + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + /* + // handle non empty message + */ + if(len) { + int procLen; + + int idx = HASH_BUFFIDX(pState); + Ipp8u* pBuffer = HASH_BUFF(pState); + Ipp64u lenLo = HASH_LENLO(pState) + (Ipp64u)len; + + /* if non empty internal buffer filling */ + if(idx) { + /* copy from input stream to the internal buffer as match as possible */ + procLen = IPP_MIN(len, (MBS_MD5 -idx)); + CopyBlock(pSrc, pBuffer+idx, procLen); + + /* update message pointer and length */ + idx += procLen; + pSrc += procLen; + len -= procLen; + + /* update digest if buffer full */ + if( MBS_MD5 == idx) { + UpdateMD5(HASH_VALUE(pState), pBuffer, MBS_MD5, md5_cnt); + idx = 0; + } + } + + /* main message part processing */ + procLen = len & ~(MBS_MD5-1); + if(procLen) { + UpdateMD5(HASH_VALUE(pState), pSrc, procLen, md5_cnt); + pSrc += procLen; + len -= procLen; + } + + /* store rest of message into the internal buffer */ + if(len) { + CopyBlock(pSrc, pBuffer, len); + idx += len; + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_BUFFIDX(pState) = idx; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmgf1ca_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcpmgf1ca_rmf.c new file mode 100644 index 000000000..02af6d8df --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmgf1ca_rmf.c @@ -0,0 +1,99 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// HASH based Mask Generation Functions +// +// Contents: +// ippsMGF1_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsMGF1 +// +// Purpose: Mask Generation Functios. +// +// Returns: Reason: +// ippStsNullPtrErr pMask == NULL +// pMethod ==NULL +// ippStsLengthErr seedLen <0 +// maskLen <0 +// ippStsNoErr no errors +// +// Parameters: +// pSeed pointer to the input stream +// seedLen input stream length (bytes) +// pMaske pointer to the ouput mask +// maskLen desired length of mask (bytes) +// pMethod hash method +// +// +// Note. +// MGF1 defined in the IEEE P1363 standard. +// MGF1 defined in the ANSI X9.63 standard and frequently called KDF (key Generation Function). +// The fifference between MGF1 and MGF2 is negligible - counter i runs from 0 (in MGF1) and from 1 (in MGF2) +*F*/ +IPPFUN(IppStatus, ippsMGF1_rmf,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, const IppsHashMethod* pMethod)) +{ + IPP_BAD_PTR2_RET(pMask, pMethod); + IPP_BADARG_RET((seedLen<0)||(maskLen<0), ippStsLengthErr); + + { + /* hash specific */ + int hashSize = pMethod->hashLen; + + int i, outLen; + + __ALIGN8 IppsHashState_rmf hashCtx; + ippsHashInit_rmf(&hashCtx, pMethod); + + if(!pSeed) + seedLen = 0; + + for(i=0,outLen=0; outLen>24) & 0xFF); + cnt[1] = (Ipp8u)((i>>16) & 0xFF); + cnt[2] = (Ipp8u)((i>>8) & 0xFF); + cnt[3] = (Ipp8u)(i & 0xFF); + + ippsHashUpdate_rmf(pSeed, seedLen, &hashCtx); + ippsHashUpdate_rmf(cnt, 4, &hashCtx); + + if((outLen + hashSize) <= maskLen) { + ippsHashFinal_rmf(pMask+outLen, &hashCtx); + outLen += hashSize; + } + else { + Ipp8u md[MAX_HASH_SIZE]; + ippsHashFinal_rmf(md, &hashCtx); + CopyBlock(md, pMask+outLen, maskLen-outLen); + outLen = maskLen; + } + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmgf2ca_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcpmgf2ca_rmf.c new file mode 100644 index 000000000..8ee272fe6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmgf2ca_rmf.c @@ -0,0 +1,100 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// HASH based Mask Generation Functions +// +// Contents: +// ippsMGF2_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsMGF2 +// +// Purpose: Mask Generation Functios. +// +// Returns: Reason: +// ippStsNullPtrErr pMask == NULL +// pMethod ==NULL +// ippStsLengthErr seedLen <0 +// maskLen <0 +// ippStsNoErr no errors +// +// Parameters: +// pSeed pointer to the input stream +// seedLen input stream length (bytes) +// pMaske pointer to the ouput mask +// maskLen desired length of mask (bytes) +// pMethod hash method +// +// +// Note. +// MGF1 defined in the IEEE P1363 standard. +// MGF1 defined in the ANSI X9.63 standard and frequently called KDF (key Generation Function). +// The fifference between MGF1 and MGF2 is negligible - counter i runs from 0 (in MGF1) and from 1 (in MGF2) +*F*/ + +IPPFUN(IppStatus, ippsMGF2_rmf,(const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, const IppsHashMethod* pMethod)) +{ + IPP_BAD_PTR2_RET(pMask, pMethod); + IPP_BADARG_RET((seedLen<0)||(maskLen<0), ippStsLengthErr); + + { + /* hash specific */ + int hashSize = pMethod->hashLen; + + int i, outLen; + + __ALIGN8 IppsHashState_rmf hashCtx; + ippsHashInit_rmf(&hashCtx, pMethod); + + if(!pSeed) + seedLen = 0; + + for(i=1,outLen=0; outLen>24) & 0xFF); + cnt[1] = (Ipp8u)((i>>16) & 0xFF); + cnt[2] = (Ipp8u)((i>>8) & 0xFF); + cnt[3] = (Ipp8u)(i & 0xFF); + + ippsHashUpdate_rmf(pSeed, seedLen, &hashCtx); + ippsHashUpdate_rmf(cnt, 4, &hashCtx); + + if((outLen + hashSize) <= maskLen) { + ippsHashFinal_rmf(pMask+outLen, &hashCtx); + outLen += hashSize; + } + else { + Ipp8u md[MAX_HASH_SIZE]; + ippsHashFinal_rmf(md, &hashCtx); + CopyBlock(md, pMask+outLen, maskLen-outLen); + outLen = maskLen; + } + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_exp_bufsize.h b/plugin/ippcp/library/src/sources/ippcp/pcpmont_exp_bufsize.h new file mode 100644 index 000000000..4b52c2dbf --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_exp_bufsize.h @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// DL over Prime Field +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpdlp.h" +#include "pcptool.h" + +/* +// Size of scratch buffer, involved in MontExp operation +// +// nExponents - number of exponents +// expBitSize - (max) sizeof exponent (in bits) +// modulusBitSize - size of modulus (bits) +*/ +static cpSize cpMontExpScratchBufferSize(cpSize modulusBitSize, cpSize expBitSize, cpSize nExponents) +{ + /* sizeof table element */ + cpSize elmDataSize = BITS_BNU_CHUNK(modulusBitSize) * (Ipp32s)sizeof(BNU_CHUNK_T); + /* get window_size */ + cpSize w = (nExponents == 1) ? cpMontExp_WinSize(expBitSize) : /* use optimal window size, if single-scalar operation */ + nExponents; /* or pseudo-oprimal if multi-scalar operation */ + + /* number of table entries */ + cpSize nPrecomputed = 1 << w; + + cpSize bufferSize = elmDataSize*nPrecomputed + (CACHE_LINE_SIZE - 1); + return bufferSize; +} \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_expbinbnu.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expbinbnu.c new file mode 100644 index 000000000..35038bdc1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expbinbnu.c @@ -0,0 +1,117 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Modular Exponentiation (binary version) +// +// Contents: +// cpMontExpBin_BNU() +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" + +/*F* +// Name: cpMontExpBin_BNU +// +// Purpose: computes the Montgomery exponentiation with exponent +// BNU_CHUNK_T *dataE to the given big number integer of Montgomery form +// BNU_CHUNK_T *dataX with respect to the modulus gsModEngine *pModEngine. +// +// Returns: +// Length of modulus +// +// +// Parameters: +// dataX big number integer of Montgomery form within the +// range [0,m-1] +// dataE big number exponent +// pModEngine Montgomery modulus of IppsMontState. +/ dataY the Montgomery exponentation result. +// +// Notes: IppsBigNumState *r should possess enough memory space as to hold the result +// of the operation. i.e. both pointers r->d and r->buffer should possess +// no less than (m->n->length) number of 32-bit words. +*F*/ + +IPP_OWN_DEFN (cpSize, cpMontExpBin_BNU, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nsE, gsModEngine* pModEngine)) +{ + cpSize nsM = MOD_LEN( pModEngine ); + + /* + // test for special cases: + // x^0 = 1 + // 0^e = 0 + */ + if( cpEqu_BNU_CHUNK(dataE, nsE, 0) ) { + COPY_BNU(dataY, MOD_MNT_R( pModEngine ), nsM); + } + else if( cpEqu_BNU_CHUNK(dataX, nsX, 0) ) { + ZEXPAND_BNU(dataY, 0, nsM); + } + + /* general case */ + else { + /* Montgomery engine buffers */ + const int usedPoolLen = 1; + BNU_CHUNK_T* dataT = gsModPoolAlloc(pModEngine, usedPoolLen); + if(NULL == dataT) + return -1; + + { + /* execute most significant part pE */ + BNU_CHUNK_T eValue = dataE[nsE-1]; + int n = cpNLZ_BNU(eValue)+1; + + /* expand base and init result */ + ZEXPAND_COPY_BNU(dataT, nsM, dataX, nsX); + COPY_BNU(dataY, dataT, nsM); + + eValue <<= n; + for(; nsqr(dataY, dataY, pModEngine); + + /* and multiply R = R*X mod Modulus */ + if(eValue & ((BNU_CHUNK_T)1<<(BNU_CHUNK_BITS-1))) + MOD_METHOD( pModEngine )->mul(dataY, dataY, dataT, pModEngine); + } + + /* execute rest bits of E */ + for(--nsE; nsE>0; nsE--) { + eValue = dataE[nsE-1]; + + for(n=0; nsqr(dataY, dataY, pModEngine); + + if(eValue & ((BNU_CHUNK_T)1<<(BNU_CHUNK_BITS-1))) + MOD_METHOD( pModEngine )->mul(dataY, dataY, dataT, pModEngine); + } + } + } + + gsModPoolFree(pModEngine, usedPoolLen); + } + + return nsM; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_expbinbnu_sscm.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expbinbnu_sscm.c new file mode 100644 index 000000000..15da4fb41 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expbinbnu_sscm.c @@ -0,0 +1,122 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Modular Exponentiation (binary version) +// +// Contents: +// cpMontExpBin_BNU_sscm() +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcpmask_ct.h" + +#if defined(_USE_IPP_OWN_CBA_MITIGATION_) +/* +// The reason was to mitigate "cache monitoring" attack on RSA +// +// This is improved version of modular exponentiation. +// Current version provide both either mitigation and perrformance. +// This version in comparison with previous (Intel(R) Integrated Performance Primitives (Intel(R) IPP) 4.1.3) one ~30-40% faster, +// i.e the the performance stayed as was for pre-mitigated version +// +*/ + +/*F* +// Name: cpMontExpBin_BNU_sscm +// +// Purpose: computes the Montgomery exponentiation with exponent +// BNU_CHUNK_T *dataE to the given big number integer of Montgomery form +// BNU_CHUNK_T *dataX with respect to the modulus gsModEngine *pModEngine. +// +// Returns: +// Length of modulus +// +// +// Parameters: +// dataX big number integer of Montgomery form within the +// range [0,m-1] +// dataE big number exponent +// pMont Montgomery modulus of IppsMontState. +/ dataY the Montgomery exponentation result. +// +*F*/ +IPP_OWN_DEFN (cpSize, cpMontExpBin_BNU_sscm, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nsE, gsModEngine* pMont)) +{ + cpSize nsM = MOD_LEN(pMont); + + /* + // test for special cases: + // x^0 = 1 + // 0^e = 0 + */ + if( cpIsGFpElemEquChunk_ct(dataE, nsE, 0) ) { + COPY_BNU(dataY, MOD_MNT_R(pMont), nsM); + } + else if( cpIsGFpElemEquChunk_ct(dataX, nsX, 0) ) { + ZEXPAND_BNU(dataY, 0, nsM); + } + + /* general case */ + else { + /* Montgomery engine buffers */ + const int usedPoolLen = 2; + BNU_CHUNK_T* dataT = gsModPoolAlloc(pMont, usedPoolLen); + if(NULL == dataT) + return -1; + + BNU_CHUNK_T* sscmB = dataT + nsM; + + /* mont(1) */ + BNU_CHUNK_T* pR = MOD_MNT_R(pMont); + + /* copy base */ + ZEXPAND_COPY_BNU(dataT, nsM, dataX, nsX); + /* init result, Y=1 */ + COPY_BNU(dataY, pR, nsM); + + /* execute bits of E */ + for(; nsE>0; nsE--) { + BNU_CHUNK_T eValue = dataE[nsE-1]; + + int n; + for(n=BNU_CHUNK_BITS; n>0; n--) { + /* sscmB = ( msb(eValue) )? X : mont(1) */ + BNU_CHUNK_T mask = cpIsMsb_ct(eValue); + eValue <<= 1; + cpMaskedCopyBNU_ct(sscmB, mask, dataT, pR, nsM); + + /* squaring Y = Y^2 */ + MOD_METHOD(pMont)->sqr(dataY, dataY, pMont); + /* and multiplication: Y = Y * sscmB */ + MOD_METHOD(pMont)->mul(dataY, dataY, sscmB, pMont); + } + } + + gsModPoolFree(pMont, usedPoolLen); + } + + return nsM; +} + +#endif /* _USE_IPP_OWN_CBA_MITIGATION_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_expsafebinary.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expsafebinary.c new file mode 100644 index 000000000..e8f999473 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expsafebinary.c @@ -0,0 +1,341 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Modular Exponentiation (binary version) +// +// Contents: +// cpSafeMontExp_Binary() +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" + +//tbcd: temporary excluded: #include + +/*F* +// Name: cpSafeMontExp_Binary +// +// Purpose: Binary method of Exponentiation +// +// +// Parameters: +// pX big number integer of Montgomery form within the +// range [0,m-1] +// pE big number exponent +// pMont Montgomery modulus of IppsMontState. +/ pY the Montgomery exponentation result. +// +*F*/ + +#if !defined(_USE_VERSION1_CBA_MITIGATION_) && !defined(_USE_IPP_OWN_CBA_MITIGATION_) // unsafe version +void cpSafeMontExp_Binary(IppsBigNumState* pY, + const IppsBigNumState* pX, const IppsBigNumState* pE, + IppsMontState* pMont) +{ + int k; + + /* if E==0 then Y=R mod m */ + if (pE->size == 1 && pE->number[0] == 0) { + int len = IPP_MULTIPLE_OF(pMont->n->size, BNUBASE_TYPE_SIZE); + cpMemset32u(pMont->wb->number, 0, len); + pMont->wb->number[len] = 1; + + cpMod_BNU(pMont->wb->number, len + 1, pMont->n->number, pMont->n->size, &pY->size); + + cpMemcpy32u(pY->number, pMont->wb->number, pY->size); + pY->sgn = ippBigNumPOS; + return; + } + + else { + Ipp32u* r_number = pY->workBuffer; + int r_size = pY->size; + + int flag=1; + Ipp32u power = pE->number[pE->size-1]; + + for( k = 31; k >= 0; k-- ) { + Ipp32u powd = power & 0x80000000;/* from top to bottom*/ + power <<= 1; + + if((flag == 1) && (powd == 0)) + continue; + + else if (flag == 0) { + #if defined(_USE_NN_MONTMUL_) + cpMontMul(r_number, r_size, r_number,r_size, + pMont->n->number, pMont->n->size, + r_number,&r_size, pMont->n0, pMont->wb->number); + #else + cpMontMul(r_number, r_size, r_number,r_size, + pMont->n->number, pMont->n->size, + r_number,&r_size, pMont->n0, pMont->wb->number, pMont->pBuffer); + #endif + if (powd) + #if defined(_USE_NN_MONTMUL_) + cpMontMul(r_number, r_size, pX->number,pX->size, + pMont->n->number, pMont->n->size, + r_number,&r_size, pMont->n0, pMont->wb->number); + #else + cpMontMul(r_number, r_size, pX->number,pX->size, + pMont->n->number, pMont->n->size, + r_number,&r_size, pMont->n0, pMont->wb->number, pMont->pBuffer); + #endif + } + + else { + int i; + flag = 0; + r_size = pMont->n->size; + if( pX->size < pMont->n->size ) + for(i = r_size - 1; i >= pX->size; i-- ) + r_number[i] = 0; + + for( i = pX->size - 1; i >= 0; i-- ) + r_number[i] = pX->number[i]; + } + } + + if (pE->size > 1) { + struct BNU { + Ipp32u *number; + int *size; + } BNUs[2]; + BNUs[0].number = r_number; + BNUs[0].size = &r_size; + BNUs[1].number = pX->number; + BNUs[1].size = &(((IppsBigNumState*)pX)->size); + + for( k = pE->size - 2; k >= 0; k-- ) { + int j; + Ipp32u powd = 0; + power = pE->number[k]; + + for( j = 31; j >= 0; j-- ) { + #if defined(_USE_NN_MONTMUL_) + cpMontMul(r_number, r_size, BNUs[powd].number, *(BNUs[powd].size), + pMont->n->number, pMont->n->size, + r_number,&r_size, pMont->n0, pMont->wb->number); + #else + cpMontMul(r_number, r_size, BNUs[powd].number, *(BNUs[powd].size), + pMont->n->number, pMont->n->size, + r_number,&r_size, pMont->n0, pMont->wb->number, pMont->pBuffer); + #endif + powd = ((power >> j) & 0x1) & (powd ^ 1); + j += powd; + } + } + } + + for(k=r_size-1; k>= 0; k--) + pY->number[k] = r_number[k]; + + pY->sgn = ippBigNumPOS; + pY->size = r_size; + + while((pY->size > 1) && (pY->number[pY->size-1] == 0)) + pY->size--; + + return; + } +} +#endif /* _USE_VERSION1_CBA_MITIGATION_, _xUSE_IPP_OWN_CBA_MITIGATION_ */ + + +#if defined(_USE_VERSION1_CBA_MITIGATION_) +/* +// The version below was designed according to recommendation +// from Crypto experts. +// The reason was to mitigate "cache monitoring" attack on RSA +// Note: this version slower than pre-mitigated version ~ 30-40% +*/ + + +#define SET_BNU(dst,val,len) \ +{ \ + int n; \ + for(n=0; n<(len); n++) (dst)[n] = (val); \ +} + +#define AND_BNU(dst,src1,src2,len) \ +{ \ + int n; \ + for(n=0; n<(len); n++) (dst)[n] = (src1)[n] & (src2)[n]; \ +} + +/*F* +// Name: cpSafeMontExp_Binary +// +// Purpose: Binary method of Exponentiation +// +// +// Parameters: +// pX big number integer of Montgomery form within the +// range [0,m-1] +// pE big number exponent +// pMont Montgomery modulus of IppsMontState. +/ pY the Montgomery exponentation result. +// +*F*/ + +void cpSafeMontExp_Binary(IppsBigNumState* pY, + const IppsBigNumState* pX, const IppsBigNumState* pE, + IppsMontState* pMont) +{ + Ipp32u* eData = BN_NUMBER(pE); + int eSize = BN_SIZE(pE); + + /* + // if e==0 then r=R mod m (i.e MontEnc(1)) + */ + if (eSize == 1 && eData[0] == 0) { + cpBN_copy(MNT_1(pMont), pY); + return; + } + + /* + // modulo exponentiation + */ + if(pY!=pX) /* init result */ + cpBN_copy(pX, pY); + + { + Ipp32u eValue; + int nBits; + + Ipp32u* pModulus = BN_NUMBER(MNT_MODULO(pMont)); + int mSize = BN_SIZE(MNT_MODULO(pMont)); + Ipp32u* pHelper = MNT_HELPER(pMont); + + Ipp32u* yData = BN_NUMBER(pY); + Ipp32u* xData = BN_BUFFER(pY); + int ySize = BN_SIZE(pY); + + Ipp32u* tData = BN_NUMBER(MNT_PRODUCT(pMont)); + Ipp32u* pBuffer = BN_BUFFER(MNT_PRODUCT(pMont)); + Ipp32u* pMontOne= BN_NUMBER(MNT_1(pMont)); + + /* expand Mont(1) */ + ZEXPAND_BNU(pMontOne, BN_SIZE(MNT_1(pMont)), mSize); + + /* copy base */ + ZEXPAND_COPY_BNU(yData,ySize, xData,mSize); + + + /* execute most significant part pE */ + eValue = eData[eSize-1]; + nBits = 32-NLZ32u(eValue); + eValue <<= (32-nBits); + + nBits--; + eValue <<=1; + for(; nBits>0; nBits--, eValue<<=1) { + Ipp32u carry; + + /* squaring: R^2 mod Modulus */ + #if defined(_USE_NN_MONTMUL_) + cpMontMul(yData, ySize, + yData, ySize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer); + #else + cpMontMul(yData, ySize, + yData, ySize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer, MNT_BUFFER(pMont)); + #endif + + /* T = (X-1)*bitof(E,j) + 1 */ + SET_BNU(pBuffer, ((Ipp32s)eValue)>>31, mSize); + carry = cpSub_BNU(tData, xData, pMontOne, mSize); + AND_BNU(tData, tData, pBuffer, mSize); + carry = cpAdd_BNU(tData, tData, pMontOne, mSize); + + /* multiply: Y*T mod Modulus */ + #if defined(_USE_NN_MONTMUL_) + cpMontMul(yData, ySize, + tData, mSize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer); + #else + cpMontMul(yData, ySize, + tData, mSize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer, MNT_BUFFER(pMont)); + #endif + } + + /* execute rest bits of E */ + eSize--; + for(; eSize>0; eSize--) { + eValue = eData[eSize-1]; + + for(nBits=32; nBits>0; nBits--, eValue<<=1) { + Ipp32u carry; + + /* squaring: R^2 mod Modulus */ + #if defined(_USE_NN_MONTMUL_) + cpMontMul(yData, ySize, + yData, ySize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer); + #else + cpMontMul(yData, ySize, + yData, ySize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer, MNT_BUFFER(pMont)); + #endif + + /* T = (X-1)*bitof(E,j) + 1 */ + SET_BNU(pBuffer, ((Ipp32s)eValue)>>31, mSize); + carry = cpSub_BNU(tData, xData, pMontOne, mSize); + AND_BNU(tData, tData, pBuffer, mSize); + carry = cpAdd_BNU(tData, tData, pMontOne, mSize); + + /* multiply: R*T mod Modulus */ + #if defined(_USE_NN_MONTMUL_) + cpMontMul(yData, ySize, + tData, mSize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer); + #else + cpMontMul(yData, ySize, + tData, mSize, + pModulus, mSize, + yData, &ySize, + pHelper, pBuffer, MNT_BUFFER(pMont)); + #endif + } + } + + BN_SIZE(pY) = ySize; + } +} +#endif /* _USE_VERSION1_CBA_MITIGATION_ */ \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_expwinbnu.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expwinbnu.c new file mode 100644 index 000000000..179e2e966 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expwinbnu.c @@ -0,0 +1,161 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Contents: +// cpMontExpWin_BN() +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "gsscramble.h" + +#if defined(_USE_WINDOW_EXP_) + +IPP_OWN_DEFN (static void, gsMul_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, const BNU_CHUNK_T* pY, cpSize len, BNU_CHUNK_T* pKbuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pKbuffer); + cpMul_BNU_school(pR, pX, len, pY, len); +} +IPP_OWN_DEFN (static void, gsSqr_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, cpSize len, BNU_CHUNK_T* pKbuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pKbuffer); + cpSqr_BNU_school(pR, pX, len); +} + +IPP_OWN_FUNPTR (void, gsMul, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, const BNU_CHUNK_T* pY, cpSize len, BNU_CHUNK_T* pKbuffer)) +IPP_OWN_FUNPTR (void, gsSqr, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, cpSize len, BNU_CHUNK_T* pKbuffer)) + +/*F* +// Name: cpMontExpWin_BN +// +// Purpose: Binary method of Exponentiation +// +// +// Parameters: +// pX big number integer of Montgomery form within the +// range [0,m-1] +// pE big number exponent +// pMont Montgomery modulus of IppsMontState. +/ pY the Montgomery exponentation result. +// pResource pointer to resource +// +*F*/ + +IPP_OWN_DEFN (void, cpMontExpWin_BN, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsBigNumState* pE, gsModEngine* pMont, BNU_CHUNK_T* pResource)) +{ + BNU_CHUNK_T* dataX = BN_NUMBER(pX); + cpSize nsX = BN_SIZE(pX); + + BNU_CHUNK_T* dataE = BN_NUMBER(pE); + cpSize nsE = BN_SIZE(pE); + + BNU_CHUNK_T* dataY = BN_NUMBER(pY); + cpSize nsM = MOD_LEN(pMont); + + /* + // test for special cases: + // x^0 = 1 + // 0^e = 0 + */ + if( cpEqu_BNU_CHUNK(dataE, nsE, 0) ) { + COPY_BNU(dataY, MOD_MNT_R(pMont), nsM); + } + else if( cpEqu_BNU_CHUNK(dataX, nsX, 0) ) { + ZEXPAND_BNU(dataY, 0, nsM); + } + + /* general case */ + else { + /* Montgomery engine buffers */ + const int usedPoolLen = 2; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pMont, usedPoolLen); + if(NULL == pBuffer) + return; + + BNU_CHUNK_T* pKBuffer = pBuffer + nsM; + + /* mul & sqr functions */ + gsMul mulFun = gsMul_school; + gsSqr sqrFun = gsSqr_school; + + /* fixed window param */ + cpSize bitsizeE = BITSIZE_BNU(dataE, nsE); + cpSize window = cpMontExp_WinSize(bitsizeE); + BNU_CHUNK_T mask = (1<>shift) &mask; + + /* initialize result */ + COPY_BNU(dataY, pResource+windowVal*(BNU_CHUNK_T)nsM, nsM); + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do square window times */ + for(n=0,windowVal=0; n>shift) &mask; + + if(windowVal) { + /* extract precomputed value and muptiply */ + mulFun(pBuffer, dataY, pResource+windowVal*(BNU_CHUNK_T)nsM, nsM, pKBuffer); + cpMontRed_BNU(dataY, pBuffer, pMont); + } + } + } + gsModPoolFree(pMont, usedPoolLen); + } + + FIX_BNU(dataY, nsM); + BN_SIZE(pY) = nsM; + BN_SIGN(pY) = ippBigNumPOS; +} + +#endif /* _USE_WINDOW_EXP_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_expwinbnu_sscm.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expwinbnu_sscm.c new file mode 100644 index 000000000..ec5be55ce --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_expwinbnu_sscm.c @@ -0,0 +1,171 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Contents: +// cpMontExpWin_BN_sscm() +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "gsscramble.h" + +#if defined(_USE_WINDOW_EXP_) + +IPP_OWN_DEFN (static void, gsMul_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, const BNU_CHUNK_T* pY, cpSize len, BNU_CHUNK_T* pKbuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pKbuffer); + cpMul_BNU_school(pR, pX, len, pY, len); +} +IPP_OWN_DEFN (static void, gsSqr_school, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, cpSize len, BNU_CHUNK_T* pKbuffer)) +{ + IPP_UNREFERENCED_PARAMETER(pKbuffer); + cpSqr_BNU_school(pR, pX, len); +} + +IPP_OWN_FUNPTR (void, gsMul, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, const BNU_CHUNK_T* pY, cpSize len, BNU_CHUNK_T* pKbuffer)) +IPP_OWN_FUNPTR (void, gsSqr, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pX, cpSize len, BNU_CHUNK_T* pKbuffer)) + +/*F* +// Name: cpMontExpWin_BN_sscm +// +// Purpose: Binary method of Exponentiation +// +// +// Parameters: +// pX big number integer of Montgomery form within the +// range [0,m-1] +// pE big number exponent +// pMont Montgomery modulus of IppsMontState. +/ pY the Montgomery exponentation result. +// +*F*/ + +IPP_OWN_DEFN (void, cpMontExpWin_BN_sscm, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsBigNumState* pE, gsModEngine* pMont, BNU_CHUNK_T* pResource)) +{ + BNU_CHUNK_T* dataX = BN_NUMBER(pX); + cpSize nsX = BN_SIZE(pX); + + BNU_CHUNK_T* dataE = BN_NUMBER(pE); + cpSize nsE = BN_SIZE(pE); + + BNU_CHUNK_T* dataY = BN_NUMBER(pY); + cpSize nsM = MOD_LEN(pMont); + + /* + // test for special cases: + // x^0 = 1 + // 0^e = 0 + */ + if( cpEqu_BNU_CHUNK(dataE, nsE, 0) ) { + COPY_BNU(dataY, MOD_MNT_R(pMont), nsM); + } + else if( cpEqu_BNU_CHUNK(dataX, nsX, 0) ) { + ZEXPAND_BNU(dataY, 0, nsM); + } + + /* general case */ + else { + /* Montgomery engine buffers */ + const int usedPoolLen = 2; + BNU_CHUNK_T* pBuffer = gsModPoolAlloc(pMont, usedPoolLen); + if(NULL == pBuffer) + return; + + BNU_CHUNK_T* pKBuffer = pBuffer + nsM; + + /* mul & sqr functions */ + gsMul mulFun = gsMul_school; + gsSqr sqrFun = gsSqr_school; + + /* fixed window param */ + cpSize bitsizeE = BITSIZE_BNU(dataE, nsE); + cpSize window = cpMontExp_WinSize(bitsizeE); + BNU_CHUNK_T mask = (1<>shift) &mask); + + /* initialize result */ + //cpScrambleGet((Ipp32u*)dataY, nsM*sizeof(BNU_CHUNK_T)/sizeof(Ipp32u), ((Ipp8u*)pResource)+windowVal*chunkSize, chunkSize); + gsScrambleGet_sscm(dataY, nsM, pResource, windowVal, window); + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do squaring window-times */ + for(n=0,windowVal=0; n>shift) &mask); + + /* exptact precomputed value and muptiply */ + //cpScrambleGet((Ipp32u*)dataT, nsM*sizeof(BNU_CHUNK_T)/sizeof(Ipp32u), ((Ipp8u*)pResource)+windowVal*chunkSize, chunkSize); + gsScrambleGet_sscm(dataT, nsM, pResource, windowVal, window); + + mulFun(pBuffer, dataY, dataT, nsM, pKBuffer); + cpMontRed_BNU(dataY, pBuffer, pMont); + } + } + + gsModPoolFree(pMont, usedPoolLen); + } + + FIX_BNU(dataY, nsM); + BN_SIZE(pY) = nsM; + BN_SIGN(pY) = ippBigNumPOS; +} + +#endif /* _USE_WINDOW_EXP_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_getsize.c new file mode 100644 index 000000000..30931fac4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_getsize.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpMontGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" + +#include "pcptool.h" + +/*F* +// Name: cpMontGetSize +// +// Purpose: Specifies size of buffer in bytes. +// +// Returns: Reason: +// ippStsNoErr no errors +// +// Parameters: +// poolLength length of pool +// maxLen32 max modulus length (in Ipp32u chunks) +// pCtxSize pointer to size of context +// +*F*/ + +IPP_OWN_DEFN (IppStatus, cpMontGetSize, (cpSize maxLen32, int poolLength, cpSize* pCtxSize)) +{ + { + int size = 0; + int maxBitSize = maxLen32 << 5; + gsModEngineGetSize(maxBitSize, poolLength, &size); + + *pCtxSize = (Ipp32s)sizeof(IppsMontState) + + (cpSize)size; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_init.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_init.c new file mode 100644 index 000000000..f59b32c47 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_init.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpMontInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: cpMontInit +// +// Purpose: Initializes the symbolic data structure and partitions the +// specified buffer space. +// +// Returns: Reason: +// ippStsNoErr no errors +// +// Parameters: +// poolLength length of pool +// maxLen32 max modulus length (in Ipp32u chunks) +// pMont pointer to Montgomery context +// +*F*/ + +IPP_OWN_DEFN (IppStatus, cpMontInit, (int maxLen32, int poolLength, IppsMontState* pMont)) +{ + { + int maxBitSize = ((maxLen32) << 5); + + MNT_ROOM( pMont ) = INTERNAL_BNU_LENGTH(maxLen32); + MNT_ENGINE ( pMont ) = (gsModEngine*)((Ipp8u*)pMont + sizeof(IppsMontState)); + + MNT_SET_ID(pMont); + + gsModEngineInit(MNT_ENGINE(pMont), NULL, maxBitSize, poolLength, gsModArithMont()); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_multiexp_fast.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_multiexp_fast.c new file mode 100644 index 000000000..aa527b92e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_multiexp_fast.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// cpFastMontMultiExp() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" + + +static cpSize GetIndex(const Ipp8u** ppE, cpSize numItems, cpSize nBit) +{ + cpSize shift = nBit%BYTESIZE; + cpSize offset= nBit/BYTESIZE; + cpSize index = 0; + + cpSize n; + for(n=numItems; n>0; n--) { + const Ipp8u* pE = ppE[n-1] + offset; + Ipp8u e = pE[0]; + index <<= 1; + index += (e>>shift) &1; + } + return index; +} + +/* +// Computes multi-exponentiation +// y = x[0]^e[0] * x[1]^e[1] *...* x[numItems-1]^e[numItems-1] mod M +// +// Input: +// - table pTbl of precomuted values pTbl[i] = x[0]^i[0] * x[1]^i[1] *...* x[numItems-1]^i[numItems-1] mod M, +// where i[0], i[1], ..., i[numItems-1] are bits of i value; +// each entry has sizeM length (i.e. equial to modulo M size) +// - array of pointers to the BNU exponents e[0], e[1],...,e[numItems-1] +// - pointer to the Montgomery engine +*/ +IPP_OWN_DEFN (void, cpFastMontMultiExp, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pPrecomTbl, const Ipp8u** ppE, cpSize eItemBitSize, cpSize numItems, gsModEngine* pModEngine)) +{ + cpSize sizeM = MOD_LEN(pModEngine); + + /* find 1-st non zero index */ + cpSize eBitNumber; + cpSize tblIdx; + for(eBitNumber=eItemBitSize-1, tblIdx=0; !tblIdx && eBitNumber>=0; eBitNumber--) + tblIdx =GetIndex(ppE, numItems, eBitNumber); + + COPY_BNU(pY, pPrecomTbl+tblIdx*sizeM, sizeM); + + for(; eBitNumber>=0; eBitNumber--) { + cpMontMul_BNU(pY, + pY, + pY, + pModEngine); + + tblIdx = GetIndex(ppE, numItems, eBitNumber); + + if(tblIdx) + cpMontMul_BNU(pY, + pY, + pPrecomTbl+tblIdx*sizeM, + pModEngine); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_multiexpinitarray.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_multiexpinitarray.c new file mode 100644 index 000000000..02ed6bae8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_multiexpinitarray.c @@ -0,0 +1,87 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// cpMontMultiExpInitArray() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// +*/ +/* +// Initialize multi-exponentiation computation +// y = x[0]^e[0] * x[1]^e[1] *...* x[numItems-1]^e[numItems-1] mod M +// +// Output: +// - table pTbl of precomuted values pTbl[i] = x[0]^i[0] * x[1]^i[1] *...* x[numItems-1]^i[numItems-1] mod M, +// where i[0], i[1], ..., i[numItems-1] are bits of i value; +// +// Input: +// - array of pointers to the BNU bases x[0], x[1],...,x[numItems-1] +// - pointer to the Montgomery engine +*/ +IPP_OWN_DEFN (void, cpMontMultiExpInitArray, (BNU_CHUNK_T* pPrecomTbl, const BNU_CHUNK_T** ppX, cpSize xItemBitSize, cpSize numItems, gsModEngine* pModEngine)) +{ + cpSize sizeM = MOD_LEN(pModEngine); + + cpSize i, base; + cpSize sizeX = BITS_BNU_CHUNK(xItemBitSize); + + /* buff[0] = mont(1) */ + COPY_BNU(pPrecomTbl, MOD_MNT_R(pModEngine), sizeM); + /* buff[1] = X[0] */ + ZEXPAND_COPY_BNU(pPrecomTbl+sizeM, sizeM, ppX[0], sizeX); + + for(i=1,base=2*sizeM; i=0; k--) { + const BNU_CHUNK_T* pXterm = ppX[k]; + + BNU_CHUNK_T* pBufferBase = pPrecomTbl+base; + int n; + for(n=1; n<=nPasses; n++, pBufferBase+=2*step) { + cpMontMul_BNU_EX(pBufferBase+step, + pBufferBase, sizeM, + pXterm, sizeX, + pModEngine); + } + + nPasses *= 2; + step /= 2; + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_packctx.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_packctx.c new file mode 100644 index 000000000..e1f80156f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_packctx.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpPackMontCtx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: cpPackMontCtx +// +// Purpose: Serialize mont context +// +// Parameters: +// pCtx context +// pBuffer buffer +*F*/ + +IPP_OWN_DEFN (void, cpPackMontCtx, (const IppsMontState* pCtx, Ipp8u* pBuffer)) +{ + /* size of context (bytes) */ + int ctxSize = sizeof(IppsMontState); + CopyBlock(pCtx, pBuffer, ctxSize); + + pBuffer = (Ipp8u*)pBuffer + sizeof(IppsMontState); + + gsPackModEngineCtx(MNT_ENGINE(pCtx), pBuffer); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_set.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_set.c new file mode 100644 index 000000000..90f3627c6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_set.c @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpMontSet() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + + +/* Auxilirary function */ +__INLINE int cpGetBitSize(Ipp32u offset, Ipp32u val) +{ + int bitSize = 31; + if (val == 0) return 0; + while ((val & (1 << bitSize)) == 0) bitSize--; + return (int)offset + bitSize; +} + +/*F* +// Name: cpMontSet +// +// Purpose: Setup modulus value +// +// Returns: Reason: +// ippStsBadModulusErr (pModulus[0] & 1) == 0 +// ippStsOutOfRangeErr ((Ipp32u)MNT_ROOM(pMont) < INTERNAL_BNU_LENGTH(len32)) +// ippStsLengthErr len32<1 +// ippStsNoErr no errors +// +// Parameters: +// pModulus pointer to the modulus buffer +// len32 length of the modulus (in Ipp32u chunks). +// pMont pointer to the context +*F*/ + +IPP_OWN_DEFN (IppStatus, cpMontSet, (const Ipp32u* pModulus, cpSize len32, IppsMontState* pMont)) +{ + IPP_BADARG_RET(len32<1, ippStsLengthErr); + + /* modulus is not an odd number */ + IPP_BADARG_RET((pModulus[0] & 1) == 0, ippStsBadModulusErr); + IPP_BADARG_RET(MNT_ROOM(pMont)<(int)(INTERNAL_BNU_LENGTH(len32)), ippStsOutOfRangeErr); + + { + const int poolLen = MOD_MAXPOOL(MNT_ENGINE(pMont)); + int modulusBitSize = cpGetBitSize((Ipp32u)((len32 - 1) << 5), pModulus[len32-1]); + + gsModEngineInit(MNT_ENGINE(pMont), pModulus, modulusBitSize, poolLen, gsModArithMont()); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmont_unpackctx.c b/plugin/ippcp/library/src/sources/ippcp/pcpmont_unpackctx.c new file mode 100644 index 000000000..f05bd8379 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmont_unpackctx.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// cpUnpackMontCtx() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: cpUnpackMontCtx +// +// Purpose: Deserialize mont context +// +// Parameters: +// pCtx context +// pBuffer buffer +*F*/ + +IPP_OWN_DEFN (void, cpUnpackMontCtx, (const Ipp8u* pBuffer, IppsMontState* pCtx)) +{ + /* size of context (bytes) */ + int ctxSize = sizeof(IppsMontState); + CopyBlock(pBuffer, pCtx, ctxSize); + + pBuffer = (Ipp8u*)pBuffer + sizeof(IppsMontState); + + gsUnpackModEngineCtx(pBuffer, MNT_ENGINE(pCtx)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontexp.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontexp.c new file mode 100644 index 000000000..ef9bc65a6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontexp.c @@ -0,0 +1,82 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMontExp() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: ippsMontExp +// +// Purpose: computes the Montgomery exponentiation with exponent +// IppsBigNumState *pE to the given big number integer of Montgomery form +// IppsBigNumState *pA with respect to the modulus IppsMontState *pCtx. +// +// Returns: Reason: +// ippStsNoErr Returns no error. +// ippStsNullPtrErr Returns an error when pointers are null. +// ippStsBadArgErr Returns an error when a or b is a negative integer. +// ippStsScaleRangeErr Returns an error when a or b is more than m. +// ippStsOutOfRangeErr Returns an error when IppsBigNumState *r is larger than +// IppsMontState *m. +// ippStsContextMatchErr Returns an error when the context parameter does +// not match the operation. +// +// +// Parameters: +// pA big number integer of Montgomery form within the +// range [0,m-1] +// pE big number exponent +// pCtx Montgomery modulus of IppsMontState +/ pR the Montgomery exponentation result. +// +// Notes: IppsBigNumState *r should possess enough memory space as to hold the result +// of the operation. i.e. both pointers r->d and r->buffer should possess +// no less than (m->n->length) number of 32-bit words. +*F*/ + +IPPFUN(IppStatus, ippsMontExp, (const IppsBigNumState* pA, const IppsBigNumState* pE, IppsMontState* pCtx, IppsBigNumState* pR)) +{ + IPP_BAD_PTR4_RET(pA, pE, pCtx, pR); + + IPP_BADARG_RET(!MNT_VALID_ID(pCtx), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pE), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + IPP_BADARG_RET(BN_ROOM(pR) < MOD_LEN( MNT_ENGINE(pCtx) ), ippStsOutOfRangeErr); + /* check a */ + IPP_BADARG_RET(BN_NEGATIVE(pA), ippStsBadArgErr); + IPP_BADARG_RET(cpCmp_BNU(BN_NUMBER(pA), BN_SIZE(pA), MOD_MODULUS( MNT_ENGINE(pCtx) ), MOD_LEN( MNT_ENGINE(pCtx) )) >= 0, ippStsScaleRangeErr); + /* check e */ + IPP_BADARG_RET(BN_NEGATIVE(pE), ippStsBadArgErr); + + cpMontExpBin_BN(pR, pA, pE, MNT_ENGINE( pCtx) ); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontexp_winsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontexp_winsize.c new file mode 100644 index 000000000..3db2cb8d0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontexp_winsize.c @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2003 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Contents: +// cpMontExp_WinSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "gsscramble.h" + + +#if !defined(_USE_WINDOW_EXP_) +IPP_OWN_DEFN (cpSize, cpMontExp_WinSize, (int bitsize)) +{ + IPP_UNREFERENCED_PARAMETER(bitsize); + return 1; +} + +#else +/* +// returns (optimal) window width +// Because of safety Window width depend on CACHE LINE size: +// P4,EM64T, ITP - 64 bytes +// XScale - 32 bytes +// Blend - no cache +*/ +#if !((_IPP==_IPP_W7) || (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || (_IPP==_IPP_P8) || \ + (_IPP==_IPP_S8) || (_IPP>=_IPP_G9) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) +IPP_OWN_DEFN (cpSize, cpMontExp_WinSize, (int bitsize)) +{ + IPP_UNREFERENCED_PARAMETER(bitsize); + return 1; +} +#endif + +#if ((_IPP==_IPP_W7) || (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || (_IPP==_IPP_P8) || \ + (_IPP==_IPP_S8) || (_IPP>=_IPP_G9) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E==_IPP32E_N8) || (_IPP32E>=_IPP32E_E9)) +IPP_OWN_DEFN (cpSize, cpMontExp_WinSize, (int bitsize)) +{ + return + //bitsize>3715? 8 : /*limited by 6 or 4 (LOG_CACHE_LINE_SIZE); we use it for windowing-exp imtigation */ + //bitsize>1434? 7 : + #if (_IPP !=_IPP_M5) + bitsize> 539? 6 : + bitsize> 197? 5 : + #endif + bitsize> 70? 4 : + bitsize> 25? 3 : + bitsize> 9? 2 : 1; +} +#endif + +#endif /* _USE_WINDOW_EXP_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontform.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontform.c new file mode 100644 index 000000000..567587e5d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontform.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMontForm() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: ippsMontForm +// +// Purpose: Converts input into Montgomery domain. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx==NULL +// pA==NULL +// pR==NULL +// ippStsContextMatchErr !MNT_VALID_ID(pCtx) +// !BN_VALID_ID(pA) +// !BN_VALID_ID(pR) +// ippStsBadArgErr A < 0. +// ippStsScaleRangeErr A >= Modulus. +// ippStsOutOfRangeErr R can't hold result +// ippStsNoErr no errors +// +// Parameters: +// pA pointer to the input [0, modulus-1] +// pCtx Montgomery context +// pR pointer to the output (A*R mod modulus) +*F*/ +IPPFUN(IppStatus, ippsMontForm,(const IppsBigNumState* pA, IppsMontState* pCtx, IppsBigNumState* pR)) +{ + IPP_BAD_PTR3_RET(pCtx, pA, pR); + + IPP_BADARG_RET(!MNT_VALID_ID(pCtx), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + IPP_BADARG_RET(BN_SIGN(pA) != ippBigNumPOS, ippStsBadArgErr); + IPP_BADARG_RET(cpCmp_BNU(BN_NUMBER(pA), BN_SIZE(pA), MOD_MODULUS( MNT_ENGINE(pCtx) ), MOD_LEN( MNT_ENGINE(pCtx) )) >= 0, ippStsScaleRangeErr); + IPP_BADARG_RET(BN_ROOM(pR) < MOD_LEN( MNT_ENGINE(pCtx) ), ippStsOutOfRangeErr); + + { + const int usedPoolLen = 1; + cpSize nsM = MOD_LEN( MNT_ENGINE(pCtx) ); + BNU_CHUNK_T* pDataA = gsModPoolAlloc(MNT_ENGINE(pCtx), usedPoolLen); + IPP_BAD_PTR1_RET(pDataA); // pDataA can be NULL, stop processing + + ZEXPAND_COPY_BNU(pDataA, nsM, BN_NUMBER(pA), BN_SIZE(pA)); + + MOD_METHOD( MNT_ENGINE(pCtx) )->encode(BN_NUMBER(pR), pDataA, MNT_ENGINE(pCtx)); + + FIX_BNU(BN_NUMBER(pR), nsM); + BN_SIZE(pR) = nsM; + BN_SIGN(pR) = ippBigNumPOS; + + gsModPoolFree(MNT_ENGINE(pCtx), usedPoolLen); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontget.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontget.c new file mode 100644 index 000000000..cb874f17a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontget.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMontGet() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: ippsMontGet +// +// Purpose: Extracts modulus. +// +// Returns: Reason: +// ippStsNullPtrErr pMont==NULL +// pModulus==NULL +// pSize==NULL +// ippStsContextMatchErr !MNT_VALID_ID() +// ippStsNoErr no errors +// +// Parameters: +// pModulus pointer to the modulus buffer +// pSize pointer to the modulus length (in Ipp32u chunks). +// pMont pointer to the context +*F*/ +IPPFUN(IppStatus, ippsMontGet,(Ipp32u* pModulus, int* pSize, const IppsMontState* pMont)) +{ + IPP_BAD_PTR3_RET(pMont, pModulus, pSize); + + IPP_BADARG_RET(!MNT_VALID_ID(pMont), ippStsContextMatchErr); + + { + cpSize len32 = MOD_LEN(MNT_ENGINE(pMont))*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)); + Ipp32u* bnData = (Ipp32u*) MOD_MODULUS( MNT_ENGINE(pMont) ); + + FIX_BNU32(bnData, len32); + COPY_BNU(pModulus, bnData, len32); + *pSize = len32; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontgetsize.c new file mode 100644 index 000000000..d154913c3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontgetsize.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMontGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: ippsMontGetSize +// +// Purpose: Specifies size of buffer in bytes. +// +// Returns: Reason: +// ippStsNullPtrErr pSize==NULL +// ippStsLengthErr length < 1 +// length > BITS2WORD32_SIZE(BN_MAXBITSIZE) +// ippStsNoErr no errors +// +// Parameters: +// method selected exponential method (unused parameter) +// length max modulus length (in Ipp32u chunks) +// pSize size of context +// +// Notes: Function always use method=ippBinaryMethod, +// so this parameter is ignored +*F*/ +IPPFUN(IppStatus, ippsMontGetSize, (IppsExpMethod method, int length, int* pSize)) +{ + IPP_BAD_PTR1_RET(pSize); + IPP_BADARG_RET(length<1 || length>BITS2WORD32_SIZE(BN_MAXBITSIZE), ippStsLengthErr); + + IPP_UNREFERENCED_PARAMETER(method); + + { + return cpMontGetSize(length, MONT_DEFAULT_POOL_LENGTH, pSize); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontgomery.h b/plugin/ippcp/library/src/sources/ippcp/pcpmontgomery.h new file mode 100644 index 000000000..e0b4c637f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontgomery.h @@ -0,0 +1,285 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// +*/ + +#if !defined(_CP_MONTGOMETRY_H) +#define _CP_MONTGOMETRY_H + +#include "pcpbn.h" +#include "gsmodstuff.h" + +#define MONT_DEFAULT_POOL_LENGTH (6) + +/* +// Montgomery spec structure +*/ +struct _cpMontgomery +{ + Ipp32u idCtx; /* Montgomery spec identifier */ + cpSize maxLen; /* Maximum length of modulus being stored */ + gsModEngine* pEngine; /* Modular arith engine structure */ +}; + +/* accessory macros */ +#define MNT_SET_ID(eng) ((eng)->idCtx = (Ipp32u)idCtxMontgomery ^ (Ipp32u)IPP_UINT_PTR(eng)) +#define MNT_ROOM(eng) ((eng)->maxLen) +#define MNT_ENGINE(eng) ((eng)->pEngine) + +#define MNT_VALID_ID(eng) ((((eng)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((eng))) == (Ipp32u)idCtxMontgomery) + +/* default methos */ +#define EXPONENT_METHOD (ippBinaryMethod) + +/* alignment */ +#define MONT_ALIGNMENT ((int)(sizeof(void*))) + + +/* +// Pacp/unpack Montgomery context +*/ +#define cpPackMontCtx OWNAPI(cpPackMontCtx) + IPP_OWN_DECL (void, cpPackMontCtx, (const IppsMontState* pCtx, Ipp8u* pBuffer)) +#define cpUnpackMontCtx OWNAPI(cpUnpackMontCtx) + IPP_OWN_DECL (void, cpUnpackMontCtx, (const Ipp8u* pBuffer, IppsMontState* pCtx)) + +/* +// Montgomery reduction, multiplication and squaring +*/ +__INLINE void cpMontRed_BNU(BNU_CHUNK_T* pR, + BNU_CHUNK_T* pProduct, + gsModEngine* pModEngine) +{ + MOD_METHOD( pModEngine )->red(pR, pProduct, pModEngine); +} + +__INLINE void cpMontMul_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, + const BNU_CHUNK_T* pB, + gsModEngine* pModEngine) +{ + MOD_METHOD( pModEngine )->mul(pR, pA, pB, pModEngine); +} + +__INLINE cpSize cpMontMul_BNU_EX(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, cpSize nsA, + const BNU_CHUNK_T* pB, cpSize nsB, + gsModEngine* pModEngine) +{ + const int usedPoolLen = 1; + cpSize nsM = MOD_LEN( pModEngine ); + BNU_CHUNK_T* pDataR = pR; + BNU_CHUNK_T* pDataA = gsModPoolAlloc(pModEngine, usedPoolLen); + if(NULL == pDataA) + return -1; + + ZEXPAND_COPY_BNU(pDataA, nsM, pA, nsA); + ZEXPAND_COPY_BNU(pDataR, nsM, pB, nsB); + + MOD_METHOD( pModEngine )->mul(pDataR, pDataA, pDataR, pModEngine); + + gsModPoolFree(pModEngine, usedPoolLen); + return nsM; +} + +__INLINE void cpMontSqr_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, + gsModEngine* pModEngine) +{ + MOD_METHOD( pModEngine )->sqr(pR, pA, pModEngine); +} + +__INLINE void cpMontSqr_BNU_EX(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pA, cpSize nsA, + gsModEngine* pModEngine) +{ + cpSize nsM = MOD_LEN( pModEngine ); + ZEXPAND_COPY_BNU(pR, nsM, pA, nsA); + + MOD_METHOD( pModEngine )->sqr(pR, pR, pModEngine); +} + +/* +// Montgomery encoding/decoding +*/ +__INLINE cpSize cpMontEnc_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pXreg, + gsModEngine* pModEngine) +{ + cpSize nsM = MOD_LEN(pModEngine); + + MOD_METHOD( pModEngine )->encode(pR, pXreg, pModEngine); + + FIX_BNU(pR, nsM); + return nsM; +} + +__INLINE cpSize cpMontEnc_BNU_EX(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pXreg, cpSize nsX, + gsModEngine* pModEngine) +{ + cpSize nsM = MOD_LEN(pModEngine); + + ZEXPAND_COPY_BNU(pR, nsM, pXreg, nsX); + + MOD_METHOD( pModEngine )->encode(pR, pR, pModEngine); + + FIX_BNU(pR, nsM); + + return nsM; +} + +__INLINE cpSize cpMontDec_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pXmont, cpSize nsX, + gsModEngine* pModEngine) +{ + cpSize nsM = MOD_LEN( pModEngine ); + + ZEXPAND_COPY_BNU(pR, nsM, pXmont, nsX); + + MOD_METHOD( pModEngine )->decode(pR, pR, pModEngine); + + FIX_BNU(pR, nsM); + return nsM; +} + +__INLINE void cpMontMul_BN(IppsBigNumState* pRbn, + const IppsBigNumState* pXbn, + const IppsBigNumState* pYbn, + gsModEngine* pModEngine) +{ + cpSize nsM = cpMontMul_BNU_EX(BN_NUMBER(pRbn), + BN_NUMBER(pXbn), BN_SIZE(pXbn), + BN_NUMBER(pYbn), BN_SIZE(pYbn), + pModEngine); + + FIX_BNU(BN_NUMBER(pRbn), nsM); + BN_SIZE(pRbn) = nsM; + BN_SIGN(pRbn) = ippBigNumPOS; +} + +__INLINE void cpMontEnc_BN(IppsBigNumState* pRbn, + const IppsBigNumState* pXbn, + gsModEngine* pModEngine) +{ + cpSize nsM = cpMontEnc_BNU_EX(BN_NUMBER(pRbn), + BN_NUMBER(pXbn), BN_SIZE(pXbn), + pModEngine); + + BN_SIZE(pRbn) = nsM; + BN_SIGN(pRbn) = ippBigNumPOS; +} + +__INLINE void cpMontDec_BN(IppsBigNumState* pRbn, + const IppsBigNumState* pXbn, + gsModEngine* pModEngine) +{ + cpSize nsM = MOD_LEN(pModEngine); + cpMontDec_BNU(BN_NUMBER(pRbn), BN_NUMBER(pXbn), BN_SIZE(pXbn), pModEngine); + + BN_SIZE(pRbn) = nsM; + BN_SIGN(pRbn) = ippBigNumPOS; +} + +/* +// Montgomery exponentiation (binary) "fast" and "safe" versions +*/ +#define cpMontExpBin_BNU OWNAPI(cpMontExpBin_BNU) + IPP_OWN_DECL (cpSize, cpMontExpBin_BNU, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pX, cpSize nsX, const BNU_CHUNK_T* pE, cpSize nsE, gsModEngine* pModEngine)) +#define cpMontExpBin_BNU_sscm OWNAPI(cpMontExpBin_BNU_sscm) + IPP_OWN_DECL (cpSize, cpMontExpBin_BNU_sscm, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pX, cpSize nsX, const BNU_CHUNK_T* pE, cpSize nsE, gsModEngine* pModEngine)) + +__INLINE void cpMontExpBin_BN_sscm(IppsBigNumState* pYbn, + const IppsBigNumState* pXbn, + const IppsBigNumState* pEbn, + gsModEngine* pMont) +{ + BNU_CHUNK_T* pX = BN_NUMBER(pXbn); + cpSize nsX = BN_SIZE(pXbn); + BNU_CHUNK_T* pE = BN_NUMBER(pEbn); + cpSize nsE = BN_SIZE(pEbn); + BNU_CHUNK_T* pY = BN_NUMBER(pYbn); + cpSize nsY = cpMontExpBin_BNU_sscm(pY, pX,nsX, pE,nsE, pMont); + FIX_BNU(pY, nsY); + BN_SIZE(pYbn) = nsY; + BN_SIGN(pYbn) = ippBigNumPOS; +} + +__INLINE void cpMontExpBin_BN(IppsBigNumState* pYbn, + const IppsBigNumState* pXbn, + const IppsBigNumState* pEbn, + gsModEngine* pModEngine) +{ + BNU_CHUNK_T* pX = BN_NUMBER(pXbn); + cpSize nsX = BN_SIZE(pXbn); + BNU_CHUNK_T* pE = BN_NUMBER(pEbn); + cpSize nsE = BN_SIZE(pEbn); + BNU_CHUNK_T* pY = BN_NUMBER(pYbn); + cpSize nsY = cpMontExpBin_BNU(pY, pX,nsX, pE,nsE, pModEngine); + FIX_BNU(pY, nsY); + BN_SIZE(pYbn) = nsY; + BN_SIGN(pYbn) = ippBigNumPOS; +} + +/* +// Montgomery exponentiation (fixed window) +*/ +#define cpMontExp_WinSize OWNAPI(cpMontExp_WinSize) + IPP_OWN_DECL (cpSize, cpMontExp_WinSize, (int bitsize)) + +#if defined(_USE_WINDOW_EXP_) +#define cpMontExpWin_BN_sscm OWNAPI(cpMontExpWin_BN_sscm) + IPP_OWN_DECL (void, cpMontExpWin_BN_sscm, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsBigNumState* pE, gsModEngine* pMont, BNU_CHUNK_T* pPrecompResource)) +#define cpMontExpWin_BN OWNAPI(cpMontExpWin_BN) + IPP_OWN_DECL (void, cpMontExpWin_BN, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsBigNumState* pE, gsModEngine* pMont, BNU_CHUNK_T* pPrecompResource)) +#endif + +/* +// Montgomery multi-exponentiation +*/ +/* precompute table for multi-exponentiation */ +#define cpMontMultiExpInitArray OWNAPI(cpMontMultiExpInitArray) + IPP_OWN_DECL (void, cpMontMultiExpInitArray, (BNU_CHUNK_T* pPrecomTbl, const BNU_CHUNK_T** ppX, cpSize xItemBitSize, cpSize numItems, gsModEngine* pMont)) + +/* multi-exponentiation */ +#define cpFastMontMultiExp OWNAPI(cpFastMontMultiExp) + IPP_OWN_DECL (void, cpFastMontMultiExp, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pPrecomTbl, const Ipp8u** ppE, cpSize eItemBitSize, cpSize numItems, gsModEngine* pMont)) +/* +// Montgomery inversion +*/ +#define cpMontInv_BNU OWNAPI(cpMontInv_BNU) + IPP_OWN_DECL (BNU_CHUNK_T*, cpMontInv_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, IppsMontState* pMont)) +#define cpRegInv_BNU OWNAPI(cpRegInv_BNU) + IPP_OWN_DECL (BNU_CHUNK_T*, cpRegInv_BNU, (BNU_CHUNK_T* pR, const BNU_CHUNK_T* pA, IppsMontState* pMont)) + + +/* +// Montgomery internal GetSize/Init functions +*/ +#define cpMontGetSize OWNAPI(cpMontGetSize) + IPP_OWN_DECL (IppStatus, cpMontGetSize, (cpSize maxLen32, int poolLength, cpSize* pCtxSize)) +#define cpMontInit OWNAPI(cpMontInit) + IPP_OWN_DECL (IppStatus, cpMontInit, (int maxLen32, int poolLength, IppsMontState* pMont)) +#define cpMontSet OWNAPI(cpMontSet) + IPP_OWN_DECL (IppStatus, cpMontSet, (const Ipp32u* pModulus, cpSize len32, IppsMontState* pMont)) + +#endif /* _CP_MONTGOMETRY_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontinit.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontinit.c new file mode 100644 index 000000000..e500ef5b5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontinit.c @@ -0,0 +1,61 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMontInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: ippsMontInit +// +// Purpose: Initializes the symbolic data structure and partitions the +// specified buffer space. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// ippStsLengthErr length < 1 +// length > BITS2WORD32_SIZE(BN_MAXBITSIZE) +// ippStsNoErr no errors +// +// Parameters: +// method selected exponential method (unused parameter) +// length max modulus length (in Ipp32u chunks) +// pCtx pointer to Montgomery context +*F*/ +IPPFUN(IppStatus, ippsMontInit,(IppsExpMethod method, int length, IppsMontState* pCtx)) +{ + IPP_BADARG_RET(length<1 || length>BITS2WORD32_SIZE(BN_MAXBITSIZE), ippStsLengthErr); + + IPP_BAD_PTR1_RET(pCtx); + + IPP_UNREFERENCED_PARAMETER(method); + + { + return cpMontInit(length, MONT_DEFAULT_POOL_LENGTH, pCtx); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontmul.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontmul.c new file mode 100644 index 000000000..012433261 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontmul.c @@ -0,0 +1,96 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Contents: +// ippsMontMul() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcptool.h" + +/*F* +// Name: ippsMontMul +// +// Purpose: Computes Montgomery modular multiplication for positive big +// number integers of Montgomery form. The following pseudocode +// represents this function: +// r <- ( a * b * R^(-1) ) mod m +// +// Returns: Reason: +// ippStsNoErr Returns no error. +// ippStsNullPtrErr Returns an error when pointers are null. +// ippStsBadArgErr Returns an error when a or b is a negative integer. +// ippStsScaleRangeErr Returns an error when a or b is more than m. +// ippStsOutOfRangeErr Returns an error when IppsBigNumState *r is larger than +// IppsMontState *m. +// ippStsContextMatchErr Returns an error when the context parameter does +// not match the operation. +// +// Parameters: +// pA Multiplicand within the range [0, m - 1]. +// pB Multiplier within the range [0, m - 1]. +// pCtx Modulus. +// pR Montgomery multiplication result. +// +// Notes: The size of IppsBigNumState *r should not be less than the data +// length of the modulus m. +*F*/ +IPPFUN(IppStatus, ippsMontMul, (const IppsBigNumState* pA, const IppsBigNumState* pB, IppsMontState* pCtx, IppsBigNumState* pR)) +{ + IPP_BAD_PTR4_RET(pA, pB, pCtx, pR); + + IPP_BADARG_RET(!MNT_VALID_ID(pCtx), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pA), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pB), ippStsContextMatchErr); + IPP_BADARG_RET(!BN_VALID_ID(pR), ippStsContextMatchErr); + + IPP_BADARG_RET(BN_NEGATIVE(pA) || BN_NEGATIVE(pB), ippStsBadArgErr); + IPP_BADARG_RET(cpCmp_BNU(BN_NUMBER(pA), BN_SIZE(pA), MOD_MODULUS( MNT_ENGINE(pCtx) ), MOD_LEN( MNT_ENGINE(pCtx) )) >= 0, ippStsScaleRangeErr); + IPP_BADARG_RET(cpCmp_BNU(BN_NUMBER(pB), BN_SIZE(pB), MOD_MODULUS( MNT_ENGINE(pCtx) ), MOD_LEN( MNT_ENGINE(pCtx) )) >= 0, ippStsScaleRangeErr); + IPP_BADARG_RET(BN_ROOM(pR) < MOD_LEN( MNT_ENGINE(pCtx) ), ippStsOutOfRangeErr); + + { + const int usedPoolLen = 2; + cpSize nsM = MOD_LEN( MNT_ENGINE(pCtx) ); + BNU_CHUNK_T* pDataR = BN_NUMBER(pR); + BNU_CHUNK_T* pDataA = gsModPoolAlloc(MNT_ENGINE(pCtx), usedPoolLen); + IPP_BAD_PTR1_RET(pDataA); // pDataA can be NULL, stop processing + + BNU_CHUNK_T* pDataB = pDataA + nsM; + + ZEXPAND_COPY_BNU(pDataA, nsM, BN_NUMBER(pA), BN_SIZE(pA)); + ZEXPAND_COPY_BNU(pDataB, nsM, BN_NUMBER(pB), BN_SIZE(pB)); + + MOD_METHOD( MNT_ENGINE(pCtx) )->mul(pDataR, pDataA, pDataB, MNT_ENGINE(pCtx)); + + gsModPoolFree(MNT_ENGINE(pCtx), usedPoolLen); + + FIX_BNU(pDataR, nsM); + BN_SIZE(pR) = nsM; + BN_SIGN(pR) = ippBigNumPOS; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpmontred.c b/plugin/ippcp/library/src/sources/ippcp/pcpmontred.c new file mode 100644 index 000000000..cf6ab1cd6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpmontred.c @@ -0,0 +1,70 @@ +/******************************************************************************* +* Copyright (C) 2010 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +*/ + +#include "owncp.h" +#include "pcpbnuarith.h" + + +#if !((_IPP==_IPP_W7) || \ + (_IPP==_IPP_T7) || \ + (_IPP==_IPP_V8) || \ + (_IPP==_IPP_P8) || \ + (_IPP>=_IPP_G9) || \ + (_IPP==_IPP_S8) || \ + (_IPP32E==_IPP32E_M7) || \ + (_IPP32E==_IPP32E_U8) || \ + (_IPP32E==_IPP32E_Y8) || \ + (_IPP32E>=_IPP32E_E9) || \ + (_IPP32E==_IPP32E_N8)) || \ + defined(_USE_C_cpMontRedAdc_BNU_) + +#define cpMontRedAdc_BNU OWNAPI(cpMontRedAdc_BNU) + +IPP_OWN_DEFN (void, cpMontRedAdc_BNU, (BNU_CHUNK_T* pR, BNU_CHUNK_T* pProduct, const BNU_CHUNK_T* pModulus, cpSize nsM, BNU_CHUNK_T m0)) +{ + BNU_CHUNK_T carry; + BNU_CHUNK_T extension; + + cpSize n; + for(n=0, carry = 0; n<(nsM-1); n++) { + BNU_CHUNK_T u = pProduct[n]*m0; + BNU_CHUNK_T t = pProduct[nsM +n +1] + carry; + + extension = cpAddMulDgt_BNU(pProduct+n, pModulus, nsM, u); + ADD_AB(carry, pProduct[nsM+n], pProduct[nsM+n], extension); + t += carry; + + carry = t 4096? 6 : /* 4096- .. . */ + bitsize> 2666? 5 : /* 2666 - 4095 */ + #endif + bitsize> 717? 4 : /* 717 - 2665 */ + bitsize> 178? 3 : /* 178 - 716 */ + bitsize> 41? 2 : 1; /* 41 - 177 */ + #else + IPP_UNREFERENCED_PARAMETER(bitsize); + return 1; + #endif +} + +/* +// Montgomery encoding/decoding +*/ +__INLINE cpSize gsMontEnc_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pXreg, cpSize nsX, + const gsModEngine* pMont) +{ + cpSize nsM = MOD_LEN( pMont ); + ZEXPAND_COPY_BNU(pR, nsM, pXreg, nsX); + MOD_METHOD( pMont )->encode(pR, pR, (gsModEngine*)pMont); + return nsM; +} + +__INLINE cpSize gsMontDec_BNU(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* pXmont, + gsModEngine* pMont) +{ + cpSize nsM = MOD_LEN(pMont); + MOD_METHOD( pMont )->decode(pR, pXmont, (gsModEngine*)pMont); + return nsM; +} + +__INLINE void gsMontEnc_BN(IppsBigNumState* pRbn, + const IppsBigNumState* pXbn, + gsModEngine* pMont) +{ + BNU_CHUNK_T* pR = BN_NUMBER(pRbn); + cpSize nsM = MOD_LEN(pMont); + + gsMontEnc_BNU(pR, BN_NUMBER(pXbn), BN_SIZE(pXbn), pMont); + + FIX_BNU(pR, nsM); + BN_SIZE(pRbn) = nsM; + BN_SIGN(pRbn) = ippBigNumPOS; +} + +/* exponentiation buffer size */ +#define gsMontExpBinBuffer OWNAPI(gsMontExpBinBuffer) + IPP_OWN_DECL (cpSize, gsMontExpBinBuffer, (int modulusBits)) +#define gsMontExpWinBuffer OWNAPI(gsMontExpWinBuffer) + IPP_OWN_DECL (cpSize, gsMontExpWinBuffer, (int modulusBits)) + +/* exponentiation prototype */ +IPP_OWN_FUNPTR (cpSize, ngMontExp, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +IPP_OWN_FUNPTR (cpSize, ngMontDualExp, (BNU_CHUNK_T* dataY[2], const BNU_CHUNK_T* dataX[2], cpSize nsX[2], const BNU_CHUNK_T* dataE[2], gsModEngine* pMont[2], BNU_CHUNK_T* pBuffer)) + +/* +// "fast" and "safe" binary montgomery exponentiation ("fast" version) +*/ +#define gsMontExpBin_BNU OWNAPI(gsMontExpBin_BNU) + IPP_OWN_DECL (cpSize, gsMontExpBin_BNU, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +#define gsModExpBin_BNU OWNAPI(gsModExpBin_BNU) + IPP_OWN_DECL (cpSize, gsModExpBin_BNU, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) + +#define gsMontExpBin_BNU_sscm OWNAPI(gsMontExpBin_BNU_sscm) + IPP_OWN_DECL (cpSize, gsMontExpBin_BNU_sscm, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pX, cpSize nsX, const BNU_CHUNK_T* pE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +#define gsModExpBin_BNU_sscm OWNAPI(gsModExpBin_BNU_sscm) + IPP_OWN_DECL (cpSize, gsModExpBin_BNU_sscm, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pX, cpSize nsX, const BNU_CHUNK_T* pE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) + +/* +// "fast" and "safe" fixed-size window montgomery exponentiation +*/ +#define gsMontExpWin_BNU OWNAPI(gsMontExpWin_BNU) + IPP_OWN_DECL (cpSize, gsMontExpWin_BNU, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +#define gsModExpWin_BNU OWNAPI(gsModExpWin_BNU) + IPP_OWN_DECL (cpSize, gsModExpWin_BNU, (BNU_CHUNK_T* pY, const BNU_CHUNK_T* pX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) + +#define gsMontExpWin_BNU_sscm OWNAPI(gsMontExpWin_BNU_sscm) + IPP_OWN_DECL (cpSize, gsMontExpWin_BNU_sscm, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +#define gsModExpWin_BNU_sscm OWNAPI(gsModExpWin_BNU_sscm) + IPP_OWN_DECL (cpSize, gsModExpWin_BNU_sscm, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nbitsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) + +#endif /* _CP_NG_MONT_EXP_STUFF_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx2.c b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx2.c new file mode 100644 index 000000000..1efd129c6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx2.c @@ -0,0 +1,682 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#if (_IPP32E>=_IPP32E_L9) + +#include "pcpbnuimpl.h" +#include "pcpbnumisc.h" + +#include "pcpngmontexpstuff.h" +#include "pcpngmontexpstuff_avx2.h" +#include "gsscramble.h" +#include "pcpmask_ct.h" + + +//tbcd: temporary excluded: #include +/* + converts regular (base = 2^32) representation (pRegular, regLen) + into "redundant" (base = 2^DIGIT_SIZE) represenrartion (pRep, repLen) + + return 1 + + note: + 1) repLen >= (bitsize +DIGIT_SIZE-1)/DIGIT_SIZE for complete conversion + 2) regular representation should expanded by at least one zero value, + pre-requisite: pRegular[regLen] == 0 to make conversion correct + 3) caller must provide suitable lengths of regular and redundant respresentations + so, conversion does correct +*/ +static int regular_dig27(Ipp64u* pRep27, int repLen, const Ipp32u* pRegular, int regLen) +{ + /* expected number of digit in redundant representation */ + int n = cpDigitNum_avx2(regLen*BITSIZE(Ipp32u), EXP_DIGIT_SIZE_AVX2); + + //tbcd: temporary excluded: assert(pRegular[regLen]==0); /* test pre-requisite */ + + { + int redBit; /* output representatin bit */ + int i; + for(i=0, redBit=0; i>= shift; + pRep27[i] = x & EXP_DIGIT_MASK_AVX2; + } + + /* expands by zeros if necessary */ + for(; i=NORM_DIGSIZE_AVX2) { + pRegular[idx++] = (Ipp32u)(x & NORM_MASK_AVX2); + x >>= NORM_DIGSIZE_AVX2; + shift -= NORM_DIGSIZE_AVX2; + } + } + + if(idx0; nsE--) { + eValue = dataE[nsE-1]; + + for(n=0; n0; nsE--) { + BNU_CHUNK_T eValue = dataE[nsE-1]; + + int n; + for(n=BNU_CHUNK_BITS; n>0; n--) { + /* T = ( msb(eValue) )? X : mont(1) */ + BNU_CHUNK_T mask = cpIsMsb_ct(eValue); + eValue <<= 1; + cpMaskedCopyBNU_ct(redT, mask, redX, redR, redLen); + + /* squaring: Y = Y^2 */ + cpMontSqr_avx2(redY, redY, redM, redLen, k0, redBuffer); + #ifdef _EXP_AVX2_DEBUG_ + debugToConvMontDomain(dbgValue, redY, redM, redLen, dataM, dataRR, nsM, k0, redBuffer); + #endif + /* and multiply: Y = Y * T */ + cpMontMul_avx2(redY, redY, redT, redM, redLen, k0, redBuffer); + } + } + + /* convert result back to regular domain */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + cpMontMul_avx2(redY, redY, redT, redM, redLen, k0, redBuffer); + dig27_regular((Ipp32u*)dataY, nsM*sizeof(BNU_CHUNK_T)/sizeof(ipp32u), redY, redLen); + + return nsM; +} + +#endif /* !_USE_WINDOW_EXP_ */ + + +#if defined(_USE_WINDOW_EXP_) +/* +// "fast" fixed-size window montgomery exponentiation +// +// scratch buffer structure: +// precomuted table of multipliers[(1< bitSizeE > 0), + it is checked in initialization phase by (ippsRSA_GetSizePublickey() and ippsRSA_InitPublicKey). + Buffer "redE" assigned for copy of dataE, is 1 (64-bit) chunk longer than size of RSA modulus, + therefore the access "*((Ipp32u*)((Ipp16u*)redE+ eBit/BITSIZE(Ipp16u)))" is always inside the boundary. + */ + /* extract 1-st window value */ + Ipp32u eChunk = *((Ipp32u*)((Ipp16u*)redE+ eBit/BITSIZE(Ipp16u))); + int shift = eBit & 0xF; + cpSize windowVal = (cpSize)((eChunk>>shift) &wmask); + + /* initialize result */ + COPY_BNU(redY, redTable+windowVal*redLen, redLen); + #ifdef _EXP_AVX2_DEBUG_ + debugToConvMontDomain(dbgValue, redY, redM, redLen, dataM, dataRR, nsM, k0, redBuffer); + #endif + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do squaring window-times */ + for(n=0; n>shift) &wmask); + + /* precomputed value muptiplication */ + if(windowVal) { + cpMontMul_avx2(redY, redY, redTable+windowVal*redLen, redM, redLen, k0, redBuffer); + #ifdef _EXP_AVX2_DEBUG_ + COPY_BNU(redT, redTable+windowVal*redBufferLen, redBufferLen); + cpMontMul_avx2(redY, redY, redT, redM, redLen, k0, redBuffer); + debugToConvMontDomain(dbgValue, redY, redM, redLen, dataM, dataRR, nsM, k0, redBuffer); + #endif + } + } + } + #ifdef _EXP_AVX2_DEBUG_ + debugToConvMontDomain(dbgValue, redY, redM, redLen, dataM, dataRR, nsM, k0, redBuffer); + #endif + + /* convert result back */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + cpMontMul_avx2(redY, redY, redT, redM, redLen, k0, redBuffer); + dig27_regular((Ipp32u*)dataY, nsM*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(ipp32u)), redY, redLen); + + return nsM; +} + +/* +// "safe" fixed-size window montgomery exponentiation +// +// scratch buffer structure: +// precomuted table of multipliers[(1<>shift) &wmask); + + /* initialize result */ + gsScrambleGet_sscm(redY, redLen, redTable, windowVal, window); + #ifdef _EXP_AVX2_DEBUG_ + debugToConvMontDomain(dbgValue, redY, redM, redLen, dataM, dataRR, nsM, k0, redBuffer); + #endif + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do squaring window-times */ + for(n=0; n>shift) &wmask); + /* exptact precomputed value and muptiply */ + gsScrambleGet_sscm(redT, redLen, redTable, windowVal, window); + cpMontMul_avx2(redY, redY, redT, redM, redLen, k0, redBuffer); + #ifdef _EXP_AVX2_DEBUG_ + debugToConvMontDomain(dbgValue, redY, redM, redLen, dataM, dataRR, nsM, k0, redBuffer); + #endif + } + } + #ifdef _EXP_AVX2_DEBUG_ + debugToConvMontDomain(dbgValue, redY, redM, redLen, dataM, dataRR, nsM, k0, redBuffer); + #endif + + /* convert result back */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + cpMontMul_avx2(redY, redY, redT, redM, redLen, k0, redBuffer); + dig27_regular((Ipp32u*)dataY, nsM*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(ipp32u)), redY, redLen); + + return nsM; +} +#endif /* _USE_WINDOW_EXP_ */ + +#endif /* _IPP32E_L9 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx2.h b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx2.h new file mode 100644 index 000000000..e4c0adbd9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx2.h @@ -0,0 +1,100 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions of AVX2 Montgomery Exp +// +*/ +#include "owncp.h" + +#if (_IPP32E>=_IPP32E_L9) + +#include "pcpbnuimpl.h" +#include "pcpngmontexpstuff.h" + +#define RSA_AVX2_MIN_BITSIZE (1024) +#define RSA_AVX2_MAX_BITSIZE (13*1024) + +#define NORM_DIGSIZE_AVX2 (BITSIZE(Ipp32u)) +#define NORM_BASE_AVX2 ((Ipp64u)1<=_IPP32E_K1) +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#pragma warning(disable: 4310) // cast truncates constant value in MSVC +#endif + +#include "pcptool.h" + +#include "pcpbnuimpl.h" +#include "pcpbnumisc.h" + +#include "pcpngmontexpstuff.h" +#include "pcpngmontexpstuff_avx512.h" +#include "gsscramble.h" +#include "pcpmask_ct.h" + +/* ams functions */ +IPP_OWN_FUNPTR (void, cpAMM52, (Ipp64u* out, const Ipp64u* a, const Ipp64u* b, const Ipp64u* m, Ipp64u k0, int len, Ipp64u* res)) + +static void AMM52(Ipp64u* out, const Ipp64u* a, const Ipp64u* b, const Ipp64u* m, Ipp64u k0, int len, Ipp64u* res) +{ + #define NUM64 ((Ipp32s)(sizeof(__m512i)/sizeof(Ipp64u))) + + __mmask8 k1 = (__mmask8)_mm512_kmov(0x02); /* mask of the 2-nd elment */ + + __m512i zero = _mm512_setzero_si512(); /* zeros */ + + int n; + int tail = len & (NUM64 -1); + int expLen = len; + if(tail) expLen += (NUM64 - tail); + + /* make sure not inplace operation */ + //tbcd: temporary excluded: assert(res!=a); + //tbcd: temporary excluded: assert(res!=b); + + /* set result to zero */ + for(n=0; n>= EXP_DIGIT_SIZE_AVX512; + } + } +} + +static void AMM52x20(Ipp64u* out, const Ipp64u* a, const Ipp64u* b, const Ipp64u* m, Ipp64u k0, int len, Ipp64u* res) +{ + __mmask8 k2 = (__mmask8)_mm512_kmov(0x0f); /* mask of the 0-3 elments */ + + /* load a */ + __m512i A0 = _mm512_loadu_si512(a); + __m512i A1 = _mm512_loadu_si512(a+NUM64); + __m512i A2 = _mm512_maskz_loadu_epi64(k2, a+2*NUM64); + + /* load m */ + __m512i M0 = _mm512_loadu_si512(m); + __m512i M1 = _mm512_loadu_si512(m+NUM64); + __m512i M2 = _mm512_maskz_loadu_epi64(k2, m+2*NUM64); + + /* R0, R1, R2 holds temporary result */ + __m512i R0 = _mm512_setzero_si512(); + __m512i R1 = _mm512_setzero_si512(); + __m512i R2 = _mm512_setzero_si512(); + + __m512i ZERO = _mm512_setzero_si512(); /* zeros */ + __m512i K = _mm512_set1_epi64((Ipp64s)k0); + + IPP_UNREFERENCED_PARAMETER(len); + IPP_UNREFERENCED_PARAMETER(res); + + __mmask8 k1 = (__mmask8)_mm512_kmov(0x01); /* mask of the 0 elment */ + int i; + for(i=0; i<20; i++) { + __m512i Bi = _mm512_set1_epi64((Ipp64s)b[i]); /* bloadcast(b[i]) */ + __m512i Yi = _mm512_setzero_si512(); /* Yi = 0 */ + __m512i tmp; + + R0 = _mm512_madd52lo_epu64(R0, A0, Bi); /* R += A*Bi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, A1, Bi); + R2 = _mm512_madd52lo_epu64(R2, A2, Bi); + + Yi = _mm512_madd52lo_epu64(ZERO, K, R0); /* Yi = R0*K */ + Yi = _mm512_permutexvar_epi64(ZERO, Yi); /* broadcast Yi */ + + R0 = _mm512_madd52lo_epu64(R0, M0, Yi); /* R += M*Yi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, M1, Yi); + R2 = _mm512_madd52lo_epu64(R2, M2, Yi); + + /* shift R */ + tmp = _mm512_maskz_srli_epi64(k1, R0, EXP_DIGIT_SIZE_AVX512); + R0 = _mm512_alignr_epi64(R1, R0, 1); + R1 = _mm512_alignr_epi64(R2, R1, 1); + R2 = _mm512_alignr_epi64(ZERO, R2, 1); + R0 = _mm512_add_epi64(R0, tmp); + + R0 = _mm512_madd52hi_epu64(R0, A0, Bi); /* R += A*Bi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, A1, Bi); + R2 = _mm512_madd52hi_epu64(R2, A2, Bi); + + R0 = _mm512_madd52hi_epu64(R0, M0, Yi); /* R += M*Yi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, M1, Yi); + R2 = _mm512_madd52hi_epu64(R2, M2, Yi); + } + + /* store de-normilized result */ + _mm512_storeu_si512(out, R0); + _mm512_storeu_si512(out+NUM64, R1); + _mm512_mask_storeu_epi64(out+2*NUM64, k2, R2); + + /* normalize result */ + { + Ipp64u acc = 0; + #if !defined(_MSC_VER) || defined(__INTEL_COMPILER) // unkonwn for msvc + #pragma nounroll + #endif + for(i=0; i<20; i++) { + acc += out[i]; + out[i] = acc & EXP_DIGIT_MASK_AVX512; + acc >>= EXP_DIGIT_SIZE_AVX512; + } + } +} + +static void AMM52x40(Ipp64u* out, const Ipp64u* a, const Ipp64u* b, const Ipp64u* m, Ipp64u k0, int len, Ipp64u* res) +{ + /* load a */ + __m512i A0 = _mm512_loadu_si512(a); + __m512i A1 = _mm512_loadu_si512(a+NUM64); + __m512i A2 = _mm512_loadu_si512(a+2*NUM64); + __m512i A3 = _mm512_loadu_si512(a+3*NUM64); + __m512i A4 = _mm512_loadu_si512(a+4*NUM64); + + /* load m */ + __m512i M0 = _mm512_loadu_si512(m); + __m512i M1 = _mm512_loadu_si512(m+NUM64); + __m512i M2 = _mm512_loadu_si512(m+2*NUM64); + __m512i M3 = _mm512_loadu_si512(m+3*NUM64); + __m512i M4 = _mm512_loadu_si512(m+4*NUM64); + + /* R0, R1, R2, R3, R4 holds temporary result */ + __m512i R0 = _mm512_setzero_si512(); + __m512i R1 = _mm512_setzero_si512(); + __m512i R2 = _mm512_setzero_si512(); + __m512i R3 = _mm512_setzero_si512(); + __m512i R4 = _mm512_setzero_si512(); + + __m512i ZERO = _mm512_setzero_si512(); /* zeros */ + __m512i K = _mm512_set1_epi64((Ipp64s)k0); + + IPP_UNREFERENCED_PARAMETER(len); + IPP_UNREFERENCED_PARAMETER(res); + + __mmask8 k1 = (__mmask8)_mm512_kmov(0x01); /* mask of the 0 elment */ + int i; + for(i=0; i<40; i++) { + __m512i Bi = _mm512_set1_epi64((Ipp64s)b[i]); /* bloadcast(b[i]) */ + __m512i Yi = _mm512_setzero_si512(); /* Yi = 0 */ + __m512i tmp; + + R0 = _mm512_madd52lo_epu64(R0, A0, Bi); /* R += A*Bi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, A1, Bi); + R2 = _mm512_madd52lo_epu64(R2, A2, Bi); + R3 = _mm512_madd52lo_epu64(R3, A3, Bi); + R4 = _mm512_madd52lo_epu64(R4, A4, Bi); + + Yi = _mm512_madd52lo_epu64(ZERO, K, R0); /* Yi = R0*K */ + Yi = _mm512_permutexvar_epi64(ZERO, Yi); /* broadcast Yi */ + + R0 = _mm512_madd52lo_epu64(R0, M0, Yi); /* R += M*Yi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, M1, Yi); + R2 = _mm512_madd52lo_epu64(R2, M2, Yi); + R3 = _mm512_madd52lo_epu64(R3, M3, Yi); + R4 = _mm512_madd52lo_epu64(R4, M4, Yi); + + /* shift R */ + tmp = _mm512_maskz_srli_epi64(k1, R0, EXP_DIGIT_SIZE_AVX512); + R0 = _mm512_alignr_epi64(R1, R0, 1); + R1 = _mm512_alignr_epi64(R2, R1, 1); + R2 = _mm512_alignr_epi64(R3, R2, 1); + R3 = _mm512_alignr_epi64(R4, R3, 1); + R4 = _mm512_alignr_epi64(ZERO, R4, 1); + R0 = _mm512_add_epi64(R0, tmp); + + R0 = _mm512_madd52hi_epu64(R0, A0, Bi); /* R += A*Bi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, A1, Bi); + R2 = _mm512_madd52hi_epu64(R2, A2, Bi); + R3 = _mm512_madd52hi_epu64(R3, A3, Bi); + R4 = _mm512_madd52hi_epu64(R4, A4, Bi); + + R0 = _mm512_madd52hi_epu64(R0, M0, Yi); /* R += M*Yi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, M1, Yi); + R2 = _mm512_madd52hi_epu64(R2, M2, Yi); + R3 = _mm512_madd52hi_epu64(R3, M3, Yi); + R4 = _mm512_madd52hi_epu64(R4, M4, Yi); + } + + /* store de-normilized result */ + _mm512_storeu_si512(out, R0); + _mm512_storeu_si512(out+NUM64, R1); + _mm512_storeu_si512(out+2*NUM64, R2); + _mm512_storeu_si512(out+3*NUM64, R3); + _mm512_storeu_si512(out+4*NUM64, R4); + + /* normalize result */ + { + Ipp64u acc = 0; + #if !defined(_MSC_VER) || defined(__INTEL_COMPILER) // unkonwn for msvc + #pragma nounroll + #endif + for(i=0; i<40; i++) { + acc += out[i]; + out[i] = acc & EXP_DIGIT_MASK_AVX512; + acc >>= EXP_DIGIT_SIZE_AVX512; + } + } +} + +static void AMM52x60(Ipp64u* out, const Ipp64u* a, const Ipp64u* b, const Ipp64u* m, Ipp64u k0, int len, Ipp64u* res) +{ + __mmask8 k2 = (__mmask8)_mm512_kmov(0x0f); /* mask of the 0-3 elments */ + + /* load a */ + __m512i A0 = _mm512_loadu_si512(a); + __m512i A1 = _mm512_loadu_si512(a+NUM64); + __m512i A2 = _mm512_loadu_si512(a+2*NUM64); + __m512i A3 = _mm512_loadu_si512(a+3*NUM64); + __m512i A4 = _mm512_loadu_si512(a+4*NUM64); + __m512i A5 = _mm512_loadu_si512(a+5*NUM64); + __m512i A6 = _mm512_loadu_si512(a+6*NUM64); + __m512i A7 = _mm512_maskz_loadu_epi64(k2, a+7*NUM64); + + /* load m */ + __m512i M0 = _mm512_loadu_si512(m); + __m512i M1 = _mm512_loadu_si512(m+NUM64); + __m512i M2 = _mm512_loadu_si512(m+2*NUM64); + __m512i M3 = _mm512_loadu_si512(m+3*NUM64); + __m512i M4 = _mm512_loadu_si512(m+4*NUM64); + __m512i M5 = _mm512_loadu_si512(m+5*NUM64); + __m512i M6 = _mm512_loadu_si512(m+6*NUM64); + __m512i M7 = _mm512_maskz_loadu_epi64(k2, m+7*NUM64); + + /* R0, R1, R2, R3, R4, R5, R6, R7 holds temporary result */ + __m512i R0 = _mm512_setzero_si512(); + __m512i R1 = _mm512_setzero_si512(); + __m512i R2 = _mm512_setzero_si512(); + __m512i R3 = _mm512_setzero_si512(); + __m512i R4 = _mm512_setzero_si512(); + __m512i R5 = _mm512_setzero_si512(); + __m512i R6 = _mm512_setzero_si512(); + __m512i R7 = _mm512_setzero_si512(); + + __m512i ZERO = _mm512_setzero_si512(); /* zeros */ + __m512i K = _mm512_set1_epi64((Ipp64s)k0); + + IPP_UNREFERENCED_PARAMETER(len); + IPP_UNREFERENCED_PARAMETER(res); + + __mmask8 k1 = (__mmask8)_mm512_kmov(0x01); /* mask of the 0 elment */ + int i; + for(i=0; i<60; i++) { + __m512i Bi = _mm512_set1_epi64((Ipp64s)b[i]); /* bloadcast(b[i]) */ + __m512i Yi = _mm512_setzero_si512(); /* Yi = 0 */ + __m512i tmp; + + R0 = _mm512_madd52lo_epu64(R0, A0, Bi); /* R += A*Bi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, A1, Bi); + R2 = _mm512_madd52lo_epu64(R2, A2, Bi); + R3 = _mm512_madd52lo_epu64(R3, A3, Bi); + R4 = _mm512_madd52lo_epu64(R4, A4, Bi); + R5 = _mm512_madd52lo_epu64(R5, A5, Bi); + R6 = _mm512_madd52lo_epu64(R6, A6, Bi); + R7 = _mm512_madd52lo_epu64(R7, A7, Bi); + + Yi = _mm512_madd52lo_epu64(ZERO, K, R0); /* Yi = R0*K */ + Yi = _mm512_permutexvar_epi64(ZERO, Yi); /* broadcast Yi */ + + R0 = _mm512_madd52lo_epu64(R0, M0, Yi); /* R += M*Yi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, M1, Yi); + R2 = _mm512_madd52lo_epu64(R2, M2, Yi); + R3 = _mm512_madd52lo_epu64(R3, M3, Yi); + R4 = _mm512_madd52lo_epu64(R4, M4, Yi); + R5 = _mm512_madd52lo_epu64(R5, M5, Yi); + R6 = _mm512_madd52lo_epu64(R6, M6, Yi); + R7 = _mm512_madd52lo_epu64(R7, M7, Yi); + + /* shift R */ + tmp = _mm512_maskz_srli_epi64(k1, R0, EXP_DIGIT_SIZE_AVX512); + R0 = _mm512_alignr_epi64(R1, R0, 1); + R1 = _mm512_alignr_epi64(R2, R1, 1); + R2 = _mm512_alignr_epi64(R3, R2, 1); + R3 = _mm512_alignr_epi64(R4, R3, 1); + R4 = _mm512_alignr_epi64(R5, R4, 1); + R5 = _mm512_alignr_epi64(R6, R5, 1); + R6 = _mm512_alignr_epi64(R7, R6, 1); + R7 = _mm512_alignr_epi64(ZERO, R7, 1); + R0 = _mm512_add_epi64(R0, tmp); + + R0 = _mm512_madd52hi_epu64(R0, A0, Bi); /* R += A*Bi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, A1, Bi); + R2 = _mm512_madd52hi_epu64(R2, A2, Bi); + R3 = _mm512_madd52hi_epu64(R3, A3, Bi); + R4 = _mm512_madd52hi_epu64(R4, A4, Bi); + R5 = _mm512_madd52hi_epu64(R5, A5, Bi); + R6 = _mm512_madd52hi_epu64(R6, A6, Bi); + R7 = _mm512_madd52hi_epu64(R7, A7, Bi); + + R0 = _mm512_madd52hi_epu64(R0, M0, Yi); /* R += M*Yi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, M1, Yi); + R2 = _mm512_madd52hi_epu64(R2, M2, Yi); + R3 = _mm512_madd52hi_epu64(R3, M3, Yi); + R4 = _mm512_madd52hi_epu64(R4, M4, Yi); + R5 = _mm512_madd52hi_epu64(R5, M5, Yi); + R6 = _mm512_madd52hi_epu64(R6, M6, Yi); + R7 = _mm512_madd52hi_epu64(R7, M7, Yi); + } + + /* store de-normilized result */ + _mm512_storeu_si512(out, R0); + _mm512_storeu_si512(out+NUM64, R1); + _mm512_storeu_si512(out+2*NUM64, R2); + _mm512_storeu_si512(out+3*NUM64, R3); + _mm512_storeu_si512(out+4*NUM64, R4); + _mm512_storeu_si512(out+5*NUM64, R5); + _mm512_storeu_si512(out+6*NUM64, R6); + _mm512_mask_storeu_epi64(out+7*NUM64, k2, R7); + + /* normalize result */ + { + Ipp64u acc = 0; + #if !defined(_MSC_VER) || defined(__INTEL_COMPILER) // unkonwn for msvc + #pragma nounroll + #endif + for(i=0; i<60; i++) { + acc += out[i]; + out[i] = acc & EXP_DIGIT_MASK_AVX512; + acc >>= EXP_DIGIT_SIZE_AVX512; + } + } +} + +static void AMM52x79(Ipp64u* out, const Ipp64u* a, const Ipp64u* b, const Ipp64u* m, Ipp64u k0, int len, Ipp64u* res) +{ + __mmask8 k2 = (__mmask8)_mm512_kmov(0x7f); /* mask of the 0-7 elments */ + + /* load a */ + __m512i A0 = _mm512_loadu_si512(a); + __m512i A1 = _mm512_loadu_si512(a+NUM64); + __m512i A2 = _mm512_loadu_si512(a+2*NUM64); + __m512i A3 = _mm512_loadu_si512(a+3*NUM64); + __m512i A4 = _mm512_loadu_si512(a+4*NUM64); + __m512i A5 = _mm512_loadu_si512(a+5*NUM64); + __m512i A6 = _mm512_loadu_si512(a+6*NUM64); + __m512i A7 = _mm512_loadu_si512(a+7*NUM64); + __m512i A8 = _mm512_loadu_si512(a+8*NUM64); + __m512i A9 = _mm512_maskz_loadu_epi64(k2, a+9*NUM64); + + /* load m */ + __m512i M0 = _mm512_loadu_si512(m); + __m512i M1 = _mm512_loadu_si512(m+NUM64); + __m512i M2 = _mm512_loadu_si512(m+2*NUM64); + __m512i M3 = _mm512_loadu_si512(m+3*NUM64); + __m512i M4 = _mm512_loadu_si512(m+4*NUM64); + __m512i M5 = _mm512_loadu_si512(m+5*NUM64); + __m512i M6 = _mm512_loadu_si512(m+6*NUM64); + __m512i M7 = _mm512_loadu_si512(m+7*NUM64); + __m512i M8 = _mm512_loadu_si512(m+8*NUM64); + __m512i M9 = _mm512_maskz_loadu_epi64(k2, m+9*NUM64); + + /* R0, R1, R2, R3, R4, R5, R6, R7, R8, R9 holds temporary result */ + __m512i R0 = _mm512_setzero_si512(); + __m512i R1 = _mm512_setzero_si512(); + __m512i R2 = _mm512_setzero_si512(); + __m512i R3 = _mm512_setzero_si512(); + __m512i R4 = _mm512_setzero_si512(); + __m512i R5 = _mm512_setzero_si512(); + __m512i R6 = _mm512_setzero_si512(); + __m512i R7 = _mm512_setzero_si512(); + __m512i R8 = _mm512_setzero_si512(); + __m512i R9 = _mm512_setzero_si512(); + + __m512i ZERO = _mm512_setzero_si512(); /* zeros */ + __m512i K = _mm512_set1_epi64((Ipp64s)k0); + + IPP_UNREFERENCED_PARAMETER(len); + IPP_UNREFERENCED_PARAMETER(res); + + __mmask8 k1 = (__mmask8)_mm512_kmov(0x01); /* mask of the 0 elment */ + int i; + for(i=0; i<79; i++) { + __m512i Bi = _mm512_set1_epi64((Ipp64s)b[i]); /* bloadcast(b[i]) */ + __m512i Yi = _mm512_setzero_si512(); /* Yi = 0 */ + __m512i tmp; + + R0 = _mm512_madd52lo_epu64(R0, A0, Bi); /* R += A*Bi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, A1, Bi); + R2 = _mm512_madd52lo_epu64(R2, A2, Bi); + R3 = _mm512_madd52lo_epu64(R3, A3, Bi); + R4 = _mm512_madd52lo_epu64(R4, A4, Bi); + R5 = _mm512_madd52lo_epu64(R5, A5, Bi); + R6 = _mm512_madd52lo_epu64(R6, A6, Bi); + R7 = _mm512_madd52lo_epu64(R7, A7, Bi); + R8 = _mm512_madd52lo_epu64(R8, A8, Bi); + R9 = _mm512_madd52lo_epu64(R9, A9, Bi); + + Yi = _mm512_madd52lo_epu64(ZERO, K, R0); /* Yi = R0*K */ + Yi = _mm512_permutexvar_epi64(ZERO, Yi); /* broadcast Yi */ + + R0 = _mm512_madd52lo_epu64(R0, M0, Yi); /* R += M*Yi (lo) */ + R1 = _mm512_madd52lo_epu64(R1, M1, Yi); + R2 = _mm512_madd52lo_epu64(R2, M2, Yi); + R3 = _mm512_madd52lo_epu64(R3, M3, Yi); + R4 = _mm512_madd52lo_epu64(R4, M4, Yi); + R5 = _mm512_madd52lo_epu64(R5, M5, Yi); + R6 = _mm512_madd52lo_epu64(R6, M6, Yi); + R7 = _mm512_madd52lo_epu64(R7, M7, Yi); + R8 = _mm512_madd52lo_epu64(R8, M8, Yi); + R9 = _mm512_madd52lo_epu64(R9, M9, Yi); + + /* shift R */ + tmp = _mm512_maskz_srli_epi64(k1, R0, EXP_DIGIT_SIZE_AVX512); + R0 = _mm512_alignr_epi64(R1, R0, 1); + R1 = _mm512_alignr_epi64(R2, R1, 1); + R2 = _mm512_alignr_epi64(R3, R2, 1); + R3 = _mm512_alignr_epi64(R4, R3, 1); + R4 = _mm512_alignr_epi64(R5, R4, 1); + R5 = _mm512_alignr_epi64(R6, R5, 1); + R6 = _mm512_alignr_epi64(R7, R6, 1); + R7 = _mm512_alignr_epi64(R8, R7, 1); + R8 = _mm512_alignr_epi64(R9, R8, 1); + R9 = _mm512_alignr_epi64(ZERO, R9, 1); + R0 = _mm512_add_epi64(R0, tmp); + + R0 = _mm512_madd52hi_epu64(R0, A0, Bi); /* R += A*Bi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, A1, Bi); + R2 = _mm512_madd52hi_epu64(R2, A2, Bi); + R3 = _mm512_madd52hi_epu64(R3, A3, Bi); + R4 = _mm512_madd52hi_epu64(R4, A4, Bi); + R5 = _mm512_madd52hi_epu64(R5, A5, Bi); + R6 = _mm512_madd52hi_epu64(R6, A6, Bi); + R7 = _mm512_madd52hi_epu64(R7, A7, Bi); + R8 = _mm512_madd52hi_epu64(R8, A8, Bi); + R9 = _mm512_madd52hi_epu64(R9, A9, Bi); + + R0 = _mm512_madd52hi_epu64(R0, M0, Yi); /* R += M*Yi (hi) */ + R1 = _mm512_madd52hi_epu64(R1, M1, Yi); + R2 = _mm512_madd52hi_epu64(R2, M2, Yi); + R3 = _mm512_madd52hi_epu64(R3, M3, Yi); + R4 = _mm512_madd52hi_epu64(R4, M4, Yi); + R5 = _mm512_madd52hi_epu64(R5, M5, Yi); + R6 = _mm512_madd52hi_epu64(R6, M6, Yi); + R7 = _mm512_madd52hi_epu64(R7, M7, Yi); + R8 = _mm512_madd52hi_epu64(R8, M8, Yi); + R9 = _mm512_madd52hi_epu64(R9, M9, Yi); + } + + /* store de-normilized result */ + _mm512_storeu_si512(out, R0); + _mm512_storeu_si512(out+NUM64, R1); + _mm512_storeu_si512(out+2*NUM64, R2); + _mm512_storeu_si512(out+3*NUM64, R3); + _mm512_storeu_si512(out+4*NUM64, R4); + _mm512_storeu_si512(out+5*NUM64, R5); + _mm512_storeu_si512(out+6*NUM64, R6); + _mm512_storeu_si512(out+7*NUM64, R7); + _mm512_storeu_si512(out+8*NUM64, R8); + _mm512_mask_storeu_epi64(out+9*NUM64, k2, R9); + + /* normalize result */ + { + Ipp64u acc = 0; + #if !defined(_MSC_VER) || defined(__INTEL_COMPILER) // unkonwn for msvc + #pragma nounroll + #endif + for(i=0; i<79; i++) { + acc += out[i]; + out[i] = acc & EXP_DIGIT_MASK_AVX512; + acc >>= EXP_DIGIT_SIZE_AVX512; + } + } +} + +/* ======= degugging section =========================================*/ +//#define _EXP_AVX512_DEBUG_ +#ifdef _EXP_AVX512_DEBUG_ +#include "pcpmontred.h" +void debugToConvMontDomain(BNU_CHUNK_T* pR, + const BNU_CHUNK_T* redInp, const BNU_CHUNK_T* redM, int almMM_bitsize, + const BNU_CHUNK_T* pM, const BNU_CHUNK_T* pRR, int nsM, BNU_CHUNK_T k0, + BNU_CHUNK_T* pBuffer) +{ + Ipp64u one[32] = { + 1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0 + }; + Ipp64u redT[32]; + int redLen = NUMBER_OF_DIGITS(almMM_bitsize, EXP_DIGIT_SIZE_AVX512); + AMM52(redT, redInp, one, redM, k0, redLen, pBuffer); + dig52_regular(pR, redT, almMM_bitsize); + + //cpMontMul_BNU(pR, should be changed + // redT, nsM, + // pRR, nsM, + // pM, nsM, k0, + // pBuffer, 0); + cpMul_BNU(pBuffer, pR,nsM, pRR,nsM, 0); + cpMontRed_BNU_opt(pR, pBuffer, pM, nsM, k0); +} +#endif +/* ===================================================================*/ + +IPP_OWN_DEFN (cpSize, gsMontExpBinBuffer_avx512, (int modulusBits)) +{ + cpSize redNum = numofVariable_avx512(modulusBits); /* "sizeof" variable */ + cpSize redBufferNum = numofVariableBuff_avx512(redNum,8); /* "sizeof" variable buffer */ + return redBufferNum *8; +} + +#if defined(_USE_WINDOW_EXP_) +IPP_OWN_DEFN (cpSize, gsMontExpWinBuffer_avx512, (int modulusBits)) +{ + cpSize w = gsMontExp_WinSize(modulusBits); + + cpSize redNum = numofVariable_avx512(modulusBits); /* "sizeof" variable */ + cpSize redBufferNum = numofVariableBuff_avx512(redNum,8); /* "sizeof" variable buffer */ + + cpSize bufferNum = CACHE_LINE_SIZE/(Ipp32s)sizeof(BNU_CHUNK_T) + + gsGetScrambleBufferSize(redNum, w) /* pre-computed table */ + + redBufferNum *7; /* addition 7 variables */ + return bufferNum; +} +#endif /* _USE_WINDOW_EXP_ */ + +/* +// "fast" binary montgomery exponentiation +// +// scratch buffer structure: +// redX[redBufferLen] +// redT[redBufferLen] +// redY[redBufferLen] +// redM[redBufferLen] +// redBuffer[redBufferLen*3] +*/ +IPP_OWN_DEFN (cpSize, gsMontExpBin_BNU_avx512, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +{ + const BNU_CHUNK_T* dataM = MOD_MODULUS(pMont); + const BNU_CHUNK_T* dataRR= MOD_MNT_R2(pMont); + cpSize nsM = MOD_LEN(pMont); + BNU_CHUNK_T k0 = MOD_MNT_FACTOR(pMont); + + cpSize nsE = BITS_BNU_CHUNK(bitsizeE); + + int modulusBitSize = BITSIZE_BNU(dataM, nsM); + int cnvMM_bitsize = NUMBER_OF_DIGITS(modulusBitSize, BITSIZE(BNU_CHUNK_T)) * BITSIZE(BNU_CHUNK_T); + int almMM_bitsize = cnvMM_bitsize+2; + int redLen = NUMBER_OF_DIGITS(almMM_bitsize, EXP_DIGIT_SIZE_AVX512); + int redBufferLen = numofVariableBuff_avx512(redLen,8); + + /* allocate buffers */ + BNU_CHUNK_T* redX = pBuffer; + BNU_CHUNK_T* redT = redX+redBufferLen; + BNU_CHUNK_T* redY = redT+redBufferLen; + BNU_CHUNK_T* redM = redY+redBufferLen; + BNU_CHUNK_T* redBuffer = redM+redBufferLen; + + cpAMM52 ammFunc; + switch (modulusBitSize) { + case 1024: ammFunc = AMM52x20; break; + case 2048: ammFunc = AMM52x40; break; + case 3072: ammFunc = AMM52x60; break; + case 4096: ammFunc = AMM52x79; break; + default: ammFunc = AMM52; break; + } + + /* convert modulus into reduced domain */ + ZEXPAND_COPY_BNU(redBuffer, redBufferLen, dataM, nsM); + regular_dig52(redM, redBufferLen, redBuffer, almMM_bitsize); + + /* compute taget domain Montgomery converter RR' */ + ZEXPAND_BNU(redBuffer, 0, redBufferLen); + SET_BIT(redBuffer, (4*redLen*EXP_DIGIT_SIZE_AVX512- 4*cnvMM_bitsize)); + regular_dig52(redY, redBufferLen, redBuffer, almMM_bitsize); + + ZEXPAND_COPY_BNU(redBuffer, redBufferLen, dataRR, nsM); + regular_dig52(redT, redBufferLen, redBuffer, almMM_bitsize); + ammFunc(redT, redT, redT, redM, k0, redLen, redBuffer); + ammFunc(redT, redT, redY, redM, k0, redLen, redBuffer); + + /* convert base to Montgomery domain */ + ZEXPAND_COPY_BNU(redY, redBufferLen/*nsX+1*/, dataX, nsX); + regular_dig52(redX, redBufferLen, redY, almMM_bitsize); + ammFunc(redX, redX, redT, redM, k0, redLen, redBuffer); + + /* init result */ + COPY_BNU(redY, redX, redLen); + + FIX_BNU(dataE, nsE); + { + /* execute most significant part pE */ + BNU_CHUNK_T eValue = dataE[nsE-1]; + int n = cpNLZ_BNU(eValue)+1; + + eValue <<= n; + for(; n0; nsE--) { + eValue = dataE[nsE-1]; + + for(n=0; n0; nsE--) { + BNU_CHUNK_T eValue = dataE[nsE-1]; + + int n; + for(n=BNU_CHUNK_BITS; n>0; n--) { + /* T = ( msb(eValue) )? X : mont(1) */ + BNU_CHUNK_T mask = cpIsMsb_ct(eValue); + eValue <<= 1; + cpMaskedCopyBNU_ct(redT, mask, redX, redR, redLen); + + /* squaring: Y = Y*Y */ + ammFunc(redY, redY, redY, redM, k0, redLen, redBuffer); + /* and multiply: Y = Y * T */ + ammFunc(redY, redY, redT, redM, k0, redLen, redBuffer); + } + } + + /* convert result back to regular domain */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + ammFunc(redY, redY, redT, redM, k0, redLen, redBuffer); + dig52_regular(dataY, redY, cnvMM_bitsize); + + return nsM; +} + +#endif /* !_USE_WINDOW_EXP_ */ + + +#if defined(_USE_WINDOW_EXP_) +/* +// "fast" fixed-size window montgomery exponentiation +// +// scratch buffer structure: +// precomuted table of multipliers[(1< bitSizeE > 0), + it is checked in initialization phase by (ippsRSA_GetSizePublickey() and ippsRSA_InitPublicKey). + Buffer "redE" assigned for copy of dataE, is 1 (64-bit) chunk longer than size of RSA modulus, + therefore the access "*((Ipp32u*)((Ipp16u*)redE+ eBit/BITSIZE(Ipp16u)))" is always inside the boundary. + */ + /* extract 1-st window value */ + Ipp32u eChunk = *((Ipp32u*)((Ipp16u*)redE+ eBit/BITSIZE(Ipp16u))); + int shift = eBit & 0xF; + cpSize windowVal = (cpSize)((eChunk>>shift) &wmask); + + /* initialize result */ + ZEXPAND_COPY_BNU(redY, redBufferLen, redTable+windowVal*redLen, redLen); + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do squaring window-times */ + for(n=0; n>shift) &wmask); + + /* extract precomputed value and muptiply */ + if(windowVal) { + ammFunc(redY, redY, redTable+windowVal*redLen, redM, k0, redLen, redBuffer); + } + } + } + + /* convert result back */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + ammFunc(redY, redY, redT, redM, k0, redLen, redBuffer); + dig52_regular(dataY, redY, cnvMM_bitsize); + + return nsM; +} + +/* +// "safe" fixed-size window montgomery exponentiation +// +// scratch buffer structure: +// precomuted table of multipliers[(1<>shift) &wmask); + + /* initialize result */ + gsScrambleGet_sscm(redY, redLen, redTable, windowVal, window); + #ifdef _EXP_AVX512_DEBUG_ + debugToConvMontDomain(dbgValue, redY, redM, almMM_bitsize, dataM, dataRR, nsM, k0, redBuffer); + #endif + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do squaring window-times */ + for(n=0; n>shift) &wmask); + + /* exptact precomputed value and muptiply */ + gsScrambleGet_sscm(redT, redLen, redTable, windowVal, window); + /* muptiply */ + ammFunc(redY, redY, redT, redM, k0, redLen, redBuffer); + } + } + + /* convert result back */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + ammFunc(redY, redY, redT, redM, k0, redLen, redBuffer); + dig52_regular(dataY, redY, cnvMM_bitsize); + + return nsM; +} +#endif /* _USE_WINDOW_EXP_ */ + +#endif /* _IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx512.h b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx512.h new file mode 100644 index 000000000..97d2a2e2c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_avx512.h @@ -0,0 +1,171 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions of AVX512 Montgomery Exp +// +*/ +#include "owncp.h" + +#if (_IPP32E>=_IPP32E_K1) + +#include "pcpbnuimpl.h" +#include "pcpngmontexpstuff.h" + +#define RSA_AVX512_MIN_BITSIZE (1024) +#define RSA_AVX512_MAX_BITSIZE (13*1024) + +#define EXP_DIGIT_SIZE_AVX512 (52) +#define EXP_DIGIT_BASE_AVX512 (1<0; strLen--) { + digit <<= 8; + digit += (Ipp64u)(pStr[strLen-1]); + } + return digit; +} + +/* regular => redundant conversion */ +static void regular_dig52(Ipp64u* out, int outLen /* in qwords */, const Ipp64u* in, int inBitSize) +{ + Ipp8u* inStr = (Ipp8u*)in; + + for(; inBitSize>=(2*EXP_DIGIT_SIZE_AVX512); inBitSize-=(2*EXP_DIGIT_SIZE_AVX512), out+=2) { + out[0] = (*(Ipp64u*)inStr) & EXP_DIGIT_MASK_AVX512; + inStr += 6; + out[1] = ((*(Ipp64u*)inStr) >> 4) & EXP_DIGIT_MASK_AVX512; + inStr += 7; + outLen -= 2; + } + if(inBitSize>EXP_DIGIT_SIZE_AVX512) { + Ipp64u digit = getDig52(inStr, 7); + out[0] = digit & EXP_DIGIT_MASK_AVX512; + inStr += 6; + inBitSize -= EXP_DIGIT_SIZE_AVX512; + digit = getDig52(inStr, BITS2WORD8_SIZE(inBitSize)); + out[1] = digit>>4; + out += 2; + outLen -= 2; + } + else if(inBitSize>0) { + out[0] = getDig52(inStr, BITS2WORD8_SIZE(inBitSize)); + out++; + outLen--; + } + for(; outLen>0; outLen--,out++) out[0] = 0; +} + +/* + converts "redundant" (base = 2^DIGIT_SIZE) representation + into regular (base = 2^64) +*/ +__INLINE void putDig52(Ipp8u* pStr, int strLen, Ipp64u digit) +{ + for(; strLen>0; strLen--) { + *pStr++ = (Ipp8u)(digit&0xFF); + digit >>= 8; + } +} + +static void dig52_regular(Ipp64u* out, const Ipp64u* in, int outBitSize) +{ + int i; + int outLen = BITS2WORD64_SIZE(outBitSize); + for(i=0; i=(2*EXP_DIGIT_SIZE_AVX512); outBitSize-=(2*EXP_DIGIT_SIZE_AVX512), in+=2) { + (*(Ipp64u*)outStr) = in[0]; + outStr+=6; + (*(Ipp64u*)outStr) ^= in[1] << 4; + outStr+=7; + } + if(outBitSize>EXP_DIGIT_SIZE_AVX512) { + putDig52(outStr, 7, in[0]); + outStr+=6; + outBitSize -= EXP_DIGIT_SIZE_AVX512; + putDig52(outStr, BITS2WORD8_SIZE(outBitSize), (in[1]<<4 | in[0]>>48)); + } + else if(outBitSize) { + putDig52(outStr, BITS2WORD8_SIZE(outBitSize), in[0]); + } + } +} + +/* exponentiation buffer size */ +#define gsMontExpBinBuffer_avx512 OWNAPI(gsMontExpBinBuffer_avx512) + IPP_OWN_DECL (cpSize, gsMontExpBinBuffer_avx512, (int modulusBits)) +#define gsMontExpWinBuffer_avx512 OWNAPI(gsMontExpWinBuffer_avx512) + IPP_OWN_DECL (cpSize, gsMontExpWinBuffer_avx512, (int modulusBits)) + +/* exponentiations */ +#define gsMontExpBin_BNU_avx512 OWNAPI(gsMontExpBin_BNU_avx512) + IPP_OWN_DECL (cpSize, gsMontExpBin_BNU_avx512, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +#define gsMontExpWin_BNU_avx512 OWNAPI(gsMontExpWin_BNU_avx512) + IPP_OWN_DECL (cpSize, gsMontExpWin_BNU_avx512, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +#define gsMontExpBin_BNU_sscm_avx512 OWNAPI(gsMontExpBin_BNU_sscm_avx512) + IPP_OWN_DECL (cpSize, gsMontExpBin_BNU_sscm_avx512, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +#define gsMontExpWin_BNU_sscm_avx512 OWNAPI(gsMontExpWin_BNU_sscm_avx512) + IPP_OWN_DECL (cpSize, gsMontExpWin_BNU_sscm_avx512, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize nsE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) + +/* dual exponentiation buffer size */ +#define gsMontDualExpWinBuffer_avx512 OWNAPI(gsMontDualExpWinBuffer_avx512) + IPP_OWN_DECL (cpSize, gsMontDualExpWinBuffer_avx512, (int modulusBits)) + +/* dual exponentiation */ +#define gsMontDualExpWin_BNU_sscm_avx512 OWNAPI(gsMontDualExpWin_BNU_sscm_avx512) + IPP_OWN_DECL(cpSize, gsMontDualExpWin_BNU_sscm_avx512, (BNU_CHUNK_T* dataY[2], const BNU_CHUNK_T* dataX[2], cpSize nsX[2], const BNU_CHUNK_T* dataE[2], gsModEngine* pMont[2], BNU_CHUNK_T* pBuffer)) + +#endif /* _IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_bin.c b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_bin.c new file mode 100644 index 000000000..3266986e6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_bin.c @@ -0,0 +1,122 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Modular Exponentiation +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" + +IPP_OWN_DEFN (cpSize, gsMontExpBinBuffer, (int modulusBits)) +{ + cpSize nsM = BITS_BNU_CHUNK(modulusBits); + cpSize bufferNum = nsM; + return bufferNum; +} + +IPP_OWN_DEFN (cpSize, gsMontExpBin_BNU, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer) ) +{ + cpSize nsM = MOD_LEN(pMont); + cpSize nsE = BITS_BNU_CHUNK(bitsizeE); + + /* + // test for special cases: + // x^0 = 1 + // 0^e = 0 + */ + if (cpEqu_BNU_CHUNK(dataE, nsE, 0)) { + COPY_BNU(dataY, MOD_MNT_R(pMont), nsM); + } + else if (cpEqu_BNU_CHUNK(dataX, nsX, 0)) { + ZEXPAND_BNU(dataY, 0, nsM); + } + + /* general case */ + else { + /* allocate buffers */ + BNU_CHUNK_T* dataT = pBuffer; + + /* copy and expand base to the modulus length */ + ZEXPAND_COPY_BNU(dataT, nsM, dataX, nsX); + /* copy */ + COPY_BNU(dataY, dataT, nsM); + + FIX_BNU(dataE, nsE); + + /* execute most significant part pE */ + { + BNU_CHUNK_T eValue = dataE[nsE - 1]; + int n = cpNLZ_BNU(eValue) + 1; + + eValue <<= n; + for (; nsqr(dataY, dataY, pMont); + /* and multiply R = R*X mod Modulus */ + if (eValue & ((BNU_CHUNK_T)1 << (BNU_CHUNK_BITS - 1))) + MOD_METHOD(pMont)->mul(dataY, dataY, dataT, pMont); + } + + /* execute rest bits of E */ + for (--nsE; nsE>0; nsE--) { + eValue = dataE[nsE - 1]; + + for (n = 0; nsqr(dataY, dataY, pMont); + + if (eValue & ((BNU_CHUNK_T)1 << (BNU_CHUNK_BITS - 1))) + MOD_METHOD(pMont)->mul(dataY, dataY, dataT, pMont); + } + } + } + } + + return nsM; +} + +/* +// "fast" binary montgomery exponentiation +// +// - input/output are in Regular Domain +// - possible inplace mode +// +// scratch buffer structure: +// dataT[nsM] copy of base (in case of inplace operation) +*/ +IPP_OWN_DEFN (cpSize, gsModExpBin_BNU, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +{ + cpSize nsM = MOD_LEN(pMont); + + /* copy and expand base to the modulus length */ + ZEXPAND_COPY_BNU(dataY, nsM, dataX, nsX); + /* convert base to Montgomery domain */ + MOD_METHOD(pMont)->encode(dataY, dataY, pMont); + + /* exponentiation */ + gsMontExpBin_BNU(dataY, dataY, nsM, dataE, bitsizeE, pMont, pBuffer); + + /* convert result back to regular domain */ + MOD_METHOD(pMont)->decode(dataY, dataY, pMont); + + return nsM; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_bin_sscm.c b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_bin_sscm.c new file mode 100644 index 000000000..434291290 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_bin_sscm.c @@ -0,0 +1,112 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Modular Exponentiation +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpmask_ct.h" + +IPP_OWN_DEFN (cpSize, gsMontExpBin_BNU_sscm, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +{ + + cpSize nsM = MOD_LEN(pMont); + cpSize nsE = BITS_BNU_CHUNK(bitsizeE); + + /* + // test for special cases: + // x^0 = 1 + // 0^e = 0 + */ + if (cpEqu_BNU_CHUNK(dataE, nsE, 0)) { + COPY_BNU(dataY, MOD_MNT_R(pMont), nsM); + } + else if (cpEqu_BNU_CHUNK(dataX, nsX, 0)) { + ZEXPAND_BNU(dataY, 0, nsM); + } + + /* general case */ + else { + + /* allocate buffers */ + BNU_CHUNK_T* dataT = pBuffer; + BNU_CHUNK_T* sscmB = dataT + nsM; + + /* mont(1) */ + BNU_CHUNK_T* pR = MOD_MNT_R(pMont); + + /* copy and expand base to the modulus length */ + ZEXPAND_COPY_BNU(dataT, nsM, dataX, nsX); + /* init result */ + COPY_BNU(dataY, MOD_MNT_R(pMont), nsM); + + /* execute bits of E */ + for (; nsE>0; nsE--) { + BNU_CHUNK_T eValue = dataE[nsE-1]; + + int n; + for(n=BNU_CHUNK_BITS; n>0; n--) { + /* sscmB = ( msb(eValue) )? X : mont(1) */ + BNU_CHUNK_T mask = cpIsMsb_ct(eValue); + eValue <<= 1; + cpMaskedCopyBNU_ct(sscmB, mask, dataT, pR, nsM); + + /* squaring Y = Y^2 */ + MOD_METHOD(pMont)->sqr(dataY, dataY, pMont); + /* and multiplication: Y = Y * sscmB */ + MOD_METHOD(pMont)->mul(dataY, dataY, sscmB, pMont); + } + } + } + + return nsM; +} + +/* +// "safe" binary montgomery exponentiation +// +// - input/output are in Regular Domain +// - possible inplace mode +// +// scratch buffer structure: +// dataT[nsM] +// sscm[nsM] +*/ +IPP_OWN_DEFN (cpSize, gsModExpBin_BNU_sscm, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +{ + cpSize nsM = MOD_LEN(pMont); + + /* copy and expand base to the modulus length */ + ZEXPAND_COPY_BNU(dataY, nsM, dataX, nsX); + + /* convert base to Montgomery domain */ + MOD_METHOD(pMont)->encode(dataY, dataY, pMont); + + /* exponentiation */ + gsMontExpBin_BNU_sscm(dataY, dataY, nsM, dataE, bitsizeE, pMont, pBuffer); + + /* convert result back to regular domain */ + MOD_METHOD(pMont)->decode(dataY, dataY, pMont); + + return nsM; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_sse2.c b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_sse2.c new file mode 100644 index 000000000..7b17a788f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_sse2.c @@ -0,0 +1,879 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" + +#if (_IPP>=_IPP_W7) + +#include "pcpbnuimpl.h" +#include "pcpbnumisc.h" + +#include "pcpngmontexpstuff.h" +#include "pcpngmontexpstuff_sse2.h" +#include "gsscramble.h" +#include "pcpmask_ct.h" + + +//tbcd: temporary excluded: #include +/* + converts regular (base = 2^32) representation (norm, normLen) + into "redundant" (base = 2^EXP_DIGIT_SIZE_SSE2) represenrartion (red, redLen) + + return 1 + + note: + 1) repLen >= (bitsize +DIGIT_SIZE-1)/DIGIT_SIZE for complete conversion + 2) regular representation should expanded by at least one zero value, + pre-requisite: pRegular[regLen] == 0 to make conversion correct + 3) caller must provide suitable lengths of regular and redundant respresentations + so, conversion does correct +*/ +static int regular_dig27(Ipp64u* pRep27, int repLen, const Ipp32u* pRegular, int regLen) +{ + /* expected number of digit in redundant representation */ + int n = cpDigitNum_sse2(regLen*BITSIZE(Ipp32u), EXP_DIGIT_SIZE_SSE2); + + //tbcd: temporary excluded: assert(pRegular[regLen]==0); /* test pre-requisite */ + + { + int redBit; /* output representatin bit */ + int i; + for(i=0, redBit=0; i>= shift; + pRep27[i] = x & EXP_DIGIT_MASK_SSE2; + } + + /* expands by zeros if necessary */ + for(; i= NORM_DIGSIZE_SSE2) { + pRegular[idx++] = (Ipp32u)(x & NORM_MASK_SSE2); + x >>= NORM_DIGSIZE_SSE2; + shift -= NORM_DIGSIZE_SSE2; + } + } + + if(idx>= EXP_DIGIT_SIZE_SSE2; + } + return tmp; +} + +/* + Montgomery multiplication of the redundant operands +*/ +static void cpMontMul_sse2(Ipp64u* pR, const Ipp64u* pA, const Ipp64u* pB, const Ipp64u* pModulus, int mLen, BNU_CHUNK_T k0, Ipp64u* pBuffer) +{ + int extLen = mLen+1; /* len extension */ + int i; + + __m128i v_k0 = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)k0), 0x44); + __m128i v_digMask = _mm_srli_epi64(_mm_set1_epi32(-1), 64-EXP_DIGIT_SIZE_SSE2); + __m128i lowQword = _mm_srli_si128(_mm_set1_epi32(-1), sizeof(Ipp64u)); + __m128i v_b0, v_y0, v_ac; + + /* clear buffer */ + v_ac = _mm_setzero_si128(); + for(i=0; i1; pB+=2, mLen-=2) { + __m128i v_b1, v_y1; + + /* v_b0 = {pB[i]:pB[i]}, v_b1 = {pB[i+1]:pB[i+1]} */ + v_b1 = _mm_load_si128((__m128i*)pB); + v_b0 = _mm_shuffle_epi32(v_b1, 0x44); + /* v_ac = {pA[1]:pA[0]} */ + v_ac = _mm_load_si128((__m128i*)pA); + + v_b1 = _mm_shuffle_epi32(v_b1, 0xEE); + + /* v_ac = {pA[1]:pA[0]} * {pB[i]:pB[i]} + {pR[1]:pR[0]} */ + v_ac = _mm_add_epi64(_mm_mul_epu32(v_ac, v_b0), ((__m128i*)pBuffer)[0]); + /* v_y0 = {v_ac[0]:v_ac[0]} * {k0:k0} ) & {digMask:digMask} */ + v_y0 = _mm_mul_epu32(_mm_shuffle_epi32(v_ac, 0x44),v_k0); + v_y0 = _mm_and_si128(v_y0, v_digMask); + /* v_ac += v_y0 * {pM[1]:pM[0]}*/ + v_ac = _mm_add_epi64(v_ac, _mm_mul_epu32(v_y0, ((__m128i*)pModulus)[0])); + + /* v_ac = {0: v_ac[1]+v_ac[0]>>EXP_DIGIT_SIZE_SSE2}*/ + v_ac = _mm_add_epi64(_mm_srli_si128(v_ac, sizeof(Ipp64u)), + _mm_srli_epi64(_mm_and_si128(v_ac, lowQword), EXP_DIGIT_SIZE_SSE2)); + /* v_ac += {0: pA[0]} * v_b1 */ + v_ac = _mm_add_epi64(v_ac, _mm_mul_epu32(v_b1, _mm_cvtsi64_si128((IPP_INT64)pA[0]))); + + /* v_y1 = (v_ac * v_k0) & v_digMask */ + v_y1 = _mm_and_si128(_mm_mul_epu32(v_ac, v_k0), v_digMask); + + /* v_ac += pM[0] * v_y1 */ + v_ac = _mm_add_epi64(v_ac, _mm_mul_epu32(_mm_cvtsi64_si128((IPP_INT64)pModulus[0]), v_y1)); + + v_y1 = _mm_shuffle_epi32(v_y1, 0x44); + + /* pR[2] += (v_ac>>EXP_DIGIT_SIZE_SSE2) */ + v_ac = _mm_add_epi64(_mm_srli_epi64(v_ac, EXP_DIGIT_SIZE_SSE2), ((__m128i*)pBuffer)[1]); + _mm_store_si128(((__m128i*)pBuffer)+1, v_ac); + + for(i=2; i1; pProduct+=2, mLen-=2) { + __m128i v_y1; + + /* v_ac = {pProd[1]:pProd[0]} */ + v_ac = _mm_load_si128((__m128i*)pProduct); + + /* v_y0 = {v_ac[0]:v_ac[0]} * {k0:k0} ) & {digMask:digMask} */ + v_y0 = _mm_mul_epu32(_mm_shuffle_epi32(v_ac, 0x44),v_k0); + v_y0 = _mm_and_si128(v_y0, v_digMask); + + /* v_ac += v_y0 * {pMod[1]:pMod[0]}*/ + v_ac = _mm_add_epi64(v_ac, _mm_mul_epu32(v_y0, ((__m128i*)pModulus)[0])); + + /* v_ac = {0: v_ac[1]+v_ac[0]>>EXP_DIGIT_SIZE_SSE2}*/ + v_ac = _mm_add_epi64(_mm_srli_si128(v_ac, sizeof(Ipp64u)), + _mm_srli_epi64(_mm_and_si128(v_ac, lowQword), EXP_DIGIT_SIZE_SSE2)); + + /* v_y1 = (v_ac * v_k0) & v_digMask */ + v_y1 = _mm_and_si128(_mm_mul_epu32(v_ac, v_k0), v_digMask); + + /* v_ac += pM[0] * v_y1 */ + v_ac = _mm_add_epi64(v_ac, _mm_mul_epu32(_mm_cvtsi64_si128((IPP_INT64)pModulus[0]), v_y1)); + + v_y1 = _mm_shuffle_epi32(v_y1, 0x44); + + /* pProd[2] += (v_ac>>EXP_DIGIT_SIZE_SSE2) */ + v_ac = _mm_add_epi64(_mm_srli_epi64(v_ac, EXP_DIGIT_SIZE_SSE2), ((__m128i*)pProduct)[1]); + _mm_store_si128(((__m128i*)pProduct)+1, v_ac); + + for(i=2; i>EXP_DIGIT_SIZE_SSE2 */ + v_ac = _mm_add_epi64(v_ac, _mm_srli_epi64(_mm_shuffle_epi32(v_ac, 0x44), EXP_DIGIT_SIZE_SSE2)); + _mm_store_si128(((__m128i*)pProduct), v_ac); + + for(i=2; i1; i+=4,hcounter-=2, tmpa+=4,ps+=4) { + __m128i t; + __m128i a0 = _mm_shuffle_epi32(_mm_cvtsi64_si128 ((IPP_INT64)tmpa[0]), 0x44); /* {a0:a0} */ + __m128i a2 = _mm_shuffle_epi32(_mm_cvtsi64_si128 ((IPP_INT64)tmpa[2]), 0x44); /* {a2:a2} */ + + __m128i s0 = _mm_load_si128((__m128i*)ps); + __m128i s2 = _mm_load_si128((__m128i*)(ps+2)); + + __m128i d0 = _mm_load_si128((__m128i*)(pDbl+i+2)); + __m128i d2 = _mm_load_si128((__m128i*)(pDbl+i+4)); + + /* px[2*i] += a0*s00; px[2*i+1] += a0*s01; */ + _mm_storeu_si128((__m128i*)(px+2*i), _mm_add_epi64(_mm_mul_epu32(a0,s0), _mm_loadu_si128((__m128i*)(px+2*i)))); + + /* px[2*i+2] += a0*d00; px[2*i+3] += a0*d01; */ + _mm_storeu_si128((__m128i*)(px+2*i+2), _mm_add_epi64(_mm_mul_epu32(a0,d0), _mm_loadu_si128((__m128i*)(px+2*i+2)))); + + /* px[2*i+4] += a0*d20 + a2*s20; px[2*i+5] += a0*d21 + a2*s21; */ + t = _mm_add_epi64(_mm_mul_epu32(a0,d2), _mm_mul_epu32(a2,s2)); + _mm_storeu_si128((__m128i*)(px+2*i+4), _mm_add_epi64(t, _mm_loadu_si128((__m128i*)(px+2*i+4)))); + + for(j=i+6; j0; nsE--) { + eValue = dataE[nsE-1]; + + for(n=0; n0; nsE--) { + BNU_CHUNK_T eValue = dataE[nsE-1]; + + + int n; + for(n=BNU_CHUNK_BITS; n>0; n--) { + /* T = ( msb(eValue) )? X : mont(1) */ + BNU_CHUNK_T mask = cpIsMsb_ct(eValue); + eValue <<= 1; + cpMaskedCopyBNU_ct((BNU_CHUNK_T*)redT, mask, (BNU_CHUNK_T*)redX, (BNU_CHUNK_T*)redR, redLen*sizeof(Ipp64u)/sizeof(BNU_CHUNK_T)); + + /* squaring: Y = Y^2 */ + cpMontSqr_sse2(redY, redY, redM, redLen, k0, redBuffer); + /* and multiply: Y = Y * T */ + cpMontMul_sse2(redY, redY, redT, redM, redLen, k0, redBuffer); + } + } + + /* convert result back to regular domain */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + cpMontMul_sse2(redY, redY, redT, redM, redLen, k0, redBuffer); + dig27_regular((Ipp32u*)dataY, nsM*sizeof(BNU_CHUNK_T)/sizeof(ipp32u), redY, redLen); + + return nsM; +} +#endif /* !_USE_WINDOW_EXP_ */ + + +#if defined(_USE_WINDOW_EXP_) +/* +// "fast" fixed-size window montgomery exponentiation +// +// scratch buffer structure: +// precomuted table of multipliers[(1<>shift) &wmask); + + /* initialize result */ + COPY_BNU(redY, redTable+windowVal*redLen, redLen); + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do squaring window-times */ + for(n=0; n>shift) &wmask); + + /* precomputed value muptiplication */ + if(windowVal) { + COPY_BNU(redT, redTable+windowVal*redLen, redLen); + cpMontMul_sse2(redY, redY, redT, redM, redLen, k0, redBuffer); + } + } + } + + /* convert result back */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + cpMontMul_sse2(redY, redY, redT, redM, redLen, k0, redBuffer); + dig27_regular((Ipp32u*)dataY, nsM*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(ipp32u)), redY, redLen); + + return nsM; +} + +/* +// "safe" fixed-size window montgomery exponentiation +// +// scratch buffer structure: +// pre-computed table +// redM[redBufferLen] +// redY[redBufferLen] +// redT[redBufferLen] +// redBuffer[redBufferLen*3] +// redE[redBufferLen] +*/ +IPP_OWN_DEFN (cpSize, gsMontExpWin_BNU_sscm_sse2, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataE, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +{ + const BNU_CHUNK_T* dataM = MOD_MODULUS(pMont); + const BNU_CHUNK_T* dataRR= MOD_MNT_R2(pMont); + cpSize nsM = MOD_LEN(pMont); + BNU_CHUNK_T k0 = MOD_MNT_FACTOR(pMont); + + cpSize nsE = BITS_BNU_CHUNK(bitsizeE); + + int modulusBitSize = MOD_BITSIZE(pMont); + int convModulusBitSize = cpDigitNum_sse2(modulusBitSize, BITSIZE(BNU_CHUNK_T)) * BITSIZE(BNU_CHUNK_T); + int modulusLen32 = BITS2WORD32_SIZE(modulusBitSize); + int redLen = cpDigitNum_sse2(convModulusBitSize+2, EXP_DIGIT_SIZE_SSE2); + int redBufferLen = numofVariableBuff_sse2(redLen); + + cpSize window = gsMontExp_WinSize(bitsizeE); + cpSize nPrecomute= 1<>shift) &wmask); + + /* initialize result */ + gsScrambleGet_sscm((BNU_CHUNK_T*)redY, redLen*(Ipp32s)(sizeof(Ipp64u)/sizeof(BNU_CHUNK_T)), (BNU_CHUNK_T*)redTable, windowVal, window); + + for(eBit-=window; eBit>=0; eBit-=window) { + /* do squaring window-times */ + for(n=0; n>shift) &wmask); + /* exptact precomputed value and muptiply */ + gsScrambleGet_sscm((BNU_CHUNK_T*)redT, redLen*(Ipp32s)(sizeof(Ipp64u)/sizeof(BNU_CHUNK_T)), (BNU_CHUNK_T*)redTable, windowVal, window); + cpMontMul_sse2(redY, redY, redT, redM, redLen, k0, redBuffer); + } + } + + /* convert result back */ + ZEXPAND_BNU(redT, 0, redBufferLen); + redT[0] = 1; + cpMontMul_sse2(redY, redY, redT, redM, redLen, k0, redBuffer); + dig27_regular((Ipp32u*)dataY, nsM*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(ipp32u)), redY, redLen); + + return nsM; +} +#endif /* _USE_WINDOW_EXP_ */ + +#endif /* _IPP_W7 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_sse2.h b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_sse2.h new file mode 100644 index 000000000..c1e6d4157 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_sse2.h @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions of SSE Montgomery Exp +// +*/ +#include "owncp.h" + +#if (_IPP>=_IPP_W7) + +#include "pcpbnuimpl.h" +#include "pcpngmontexpstuff.h" + +#define RSA_SSE2_MIN_BITSIZE (256) +#define RSA_SSE2_MAX_BITSIZE (13*1024) + +#define NORM_DIGSIZE_SSE2 (BITSIZE(Ipp32u)) +#define NORM_BASE_SSE2 ((Ipp64u)1<mul(pTable+n*nsM, pTable+(n-1)*nsM, dataTT, pMont); + } + + /* expand exponent*/ + ZEXPAND_COPY_BNU(dataEE, nsE+1, dataExp, nsE); + bitsizeE = ((bitsizeE+winSize-1)/winSize) *winSize; + + /* exponentiation */ + { + /* position of the 1-st (left) window */ + int eBit = bitsizeE-winSize; + + /* Note: Static analysis can generate error/warning on the expression below. + + The value of "bitSizeE" is limited, ((modulusBitSize > bitSizeE > 0), + it is checked in initialization phase by (ippsRSA_GetSizePublickey() and ippsRSA_InitPublicKey). + Buffer "dataEE" assigned for copy of dataExp, is 1 (64-bit) chunk longer than size of RSA modulus, + therefore the access "*((Ipp32u*)((Ipp16u*)dataEE+ eBit/BITSIZE(Ipp16u)))" is always inside the boundary. + */ + /* extract 1-st window value */ + Ipp32u eChunk = *((Ipp32u*)((Ipp16u*)dataEE + eBit/BITSIZE(Ipp16u))); + int shift = eBit & 0xF; + Ipp32u winVal = (eChunk>>shift) &mask; + + /* initialize result */ + COPY_BNU(dataY, pTable+winVal*(Ipp32u)nsM, nsM); + + for(eBit-=winSize; eBit>=0; eBit-=winSize) { + /* do square window times */ + for(n=0,winVal=0; nsqr(dataY, dataY, pMont); + } + + /* extract next window value */ + eChunk = *((Ipp32u*)((Ipp16u*)dataEE + eBit/BITSIZE(Ipp16u))); + shift = eBit & 0xF; + winVal = (eChunk>>shift) &mask; + + /* muptiply precomputed value */ + MOD_METHOD( pMont )->mul(dataY, dataY, pTable+winVal*(Ipp32u)nsM, pMont); + } + + } + } + + return nsM; +} + +/* +// "fast" fixed-size window montgomery exponentiation +// - input/output are in Regular Domain +// - possible inplace mode +*/ +IPP_OWN_DEFN (cpSize, gsModExpWin_BNU, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataExp, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +{ + cpSize nsM = MOD_LEN(pMont); + + /* copy and expand base to the modulus length */ + ZEXPAND_COPY_BNU(dataY, nsM, dataX, nsX); + + /* convert base to Montgomery domain */ + MOD_METHOD(pMont)->encode(dataY, dataY, pMont); + + /* exponentiation */ + gsMontExpWin_BNU(dataY, dataY, nsM, dataExp, bitsizeE, pMont, pBuffer); + + /* convert result back to regular domain */ + MOD_METHOD(pMont)->decode(dataY, dataY, pMont); + + return nsM; +} + +#endif /* _USE_WINDOW_EXP_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_win_sscm.c b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_win_sscm.c new file mode 100644 index 000000000..42021c192 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngmontexpstuff_win_sscm.c @@ -0,0 +1,149 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Modular Exponentiation (windowed "safe" version) +*/ + +#include "owncp.h" + +#if defined(_USE_WINDOW_EXP_) + +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpmask_ct.h" + +/* +// "safe" fixed-size window montgomery exponentiation +// +// - input/output are in Montgomery Domain +// - possible inplace mode +// +// scratch buffer structure: +// precomuted table of multipliers[(1<mul(dataTT, dataTT, dataRR, pMont); + gsScramblePut(pTable, n, dataTT, nsM, winSize); + } + + /* expand exponent*/ + ZEXPAND_COPY_BNU(dataEE, nsM+1, dataExp, nsE); + bitsizeE = ((bitsizeE+winSize-1)/winSize) *winSize; + + /* exponentiation */ + { + /* position of the 1-st (left) window */ + int eBit = bitsizeE-winSize; + + /* extract 1-st window value */ + Ipp32u eChunk = *((Ipp32u*)((Ipp16u*)dataEE + eBit/BITSIZE(Ipp16u))); + int shift = eBit & 0xF; + Ipp32u winVal = (eChunk>>shift) &mask; + + /* initialize result */ + gsScrambleGet_sscm(dataY, nsM, pTable, (int)winVal, winSize); + + for(eBit-=winSize; eBit>=0; eBit-=winSize) { + /* do square window times */ + for(n=0,winVal=0; nsqr(dataY, dataY, pMont); + } + + /* extract next window value */ + eChunk = *((Ipp32u*)((Ipp16u*)dataEE + eBit/BITSIZE(Ipp16u))); + shift = eBit & 0xF; + winVal = (eChunk>>shift) &mask; + + /* exptact precomputed value and muptiply */ + gsScrambleGet_sscm(dataTT, nsM, pTable, (int)winVal, winSize); + + MOD_METHOD( pMont )->mul(dataY, dataY, dataTT, pMont); + } + } + } + + return nsM; +} + +/* +// "safe" fixed-size window exponentiation +// - input/output are in Regular Domain +// - possible inplace mode +*/ +IPP_OWN_DEFN (cpSize, gsModExpWin_BNU_sscm, (BNU_CHUNK_T* dataY, const BNU_CHUNK_T* dataX, cpSize nsX, const BNU_CHUNK_T* dataExp, cpSize bitsizeE, gsModEngine* pMont, BNU_CHUNK_T* pBuffer)) +{ + cpSize nsM = MOD_LEN(pMont); + + /* copy and expand base to the modulus length */ + ZEXPAND_COPY_BNU(dataY, nsM, dataX, nsX); + + /* convert base to Montgomery domain */ + MOD_METHOD(pMont)->encode(dataY, dataY, pMont); + + /* exponentiation */ + gsMontExpWin_BNU_sscm(dataY, dataY, nsM, dataExp, bitsizeE, pMont, pBuffer); + + /* convert result back to regular domain */ + MOD_METHOD(pMont)->decode(dataY, dataY, pMont); + + return nsM; +} + +#endif /* _USE_WINDOW_EXP_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngrsa.h b/plugin/ippcp/library/src/sources/ippcp/pcpngrsa.h new file mode 100644 index 000000000..b15a08a02 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngrsa.h @@ -0,0 +1,123 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions and +// Internal ng RSA Function Prototypes +// +// +*/ + +#if !defined(_CP_NG_RSA_H) +#define _CP_NG_RSA_H + +#include "pcpbn.h" +#include "pcpmontgomery.h" +#include "pcpngmontexpstuff.h" + +struct _cpRSA_public_key { + Ipp32u id; /* key ID */ + int maxbitSizeN; + int maxbitSizeE; + int bitSizeN; /* RSA modulus bitsize */ + int bitSizeE; /* RSA public exp bitsize */ + + BNU_CHUNK_T* pDataE; /* public exp */ + gsModEngine* pMontN; /* montgomery engine (N) */ +}; + +#define RSA_PUB_KEY_SET_ID(x) ((x)->id = (Ipp32u)idCtxRSA_PubKey ^ (Ipp32u)IPP_UINT_PTR(x)) +/* access */ +#define RSA_PUB_KEY_MAXSIZE_N(x) ((x)->maxbitSizeN) +#define RSA_PUB_KEY_MAXSIZE_E(x) ((x)->maxbitSizeE) +#define RSA_PUB_KEY_BITSIZE_N(x) ((x)->bitSizeN) +#define RSA_PUB_KEY_BITSIZE_E(x) ((x)->bitSizeE) +#define RSA_PUB_KEY_E(x) ((x)->pDataE) +#define RSA_PUB_KEY_NMONT(x) ((x)->pMontN) + +#define RSA_PUB_KEY_VALID_ID(x) ((((x)->id) ^ (Ipp32u)IPP_UINT_PTR((x))) == (Ipp32u)idCtxRSA_PubKey) +#define RSA_PUB_KEY_IS_SET(x) (RSA_PUB_KEY_BITSIZE_N((x))>0) + +/* alignment */ +#define RSA_PUBLIC_KEY_ALIGNMENT ((int)(sizeof(void*))) + +struct _cpRSA_private_key { + Ipp32u id; /* key ID */ + int maxbitSizeN; + int maxbitSizeD; + int bitSizeN; /* RSA modulus bitsize */ + int bitSizeD; /* RSA private exp bitsize */ + int bitSizeP; /* RSA p-factor bitsize */ + int bitSizeQ; /* RSA q-factor bitsize */ + + BNU_CHUNK_T* pDataD; /* private exp */ + BNU_CHUNK_T* pDataDp; /* dp private exp */ + BNU_CHUNK_T* pDataDq; /* dq private exp */ + BNU_CHUNK_T* pDataQinv; /* qinv coeff in residue domain */ + + gsModEngine* pMontP; /* montgomery engine (P) */ + gsModEngine* pMontQ; /* montgomery engine (Q) */ + gsModEngine* pMontN; /* montgomery engine (N) */ +}; + +#define RSA_PRV_KEY1_SET_ID(x) ((x)->id = (Ipp32u)idCtxRSA_PrvKey1 ^ (Ipp32u)IPP_UINT_PTR(x)) +#define RSA_PRV_KEY2_SET_ID(x) ((x)->id = (Ipp32u)idCtxRSA_PrvKey2 ^ (Ipp32u)IPP_UINT_PTR(x)) +/* access */ +#define RSA_PRV_KEY_MAXSIZE_N(x) ((x)->maxbitSizeN) +#define RSA_PRV_KEY_MAXSIZE_D(x) ((x)->maxbitSizeD) +#define RSA_PRV_KEY_BITSIZE_N(x) ((x)->bitSizeN) +#define RSA_PRV_KEY_BITSIZE_D(x) ((x)->bitSizeD) +#define RSA_PRV_KEY_BITSIZE_P(x) ((x)->bitSizeP) +#define RSA_PRV_KEY_BITSIZE_Q(x) ((x)->bitSizeQ) +#define RSA_PRV_KEY_D(x) ((x)->pDataD) +#define RSA_PRV_KEY_DP(x) ((x)->pDataDp) +#define RSA_PRV_KEY_DQ(x) ((x)->pDataDq) +#define RSA_PRV_KEY_INVQ(x) ((x)->pDataQinv) +#define RSA_PRV_KEY_PMONT(x) ((x)->pMontP) +#define RSA_PRV_KEY_QMONT(x) ((x)->pMontQ) +#define RSA_PRV_KEY_NMONT(x) ((x)->pMontN) + +#define RSA_PRV_KEY1_VALID_ID(x) ((((x)->id) ^ (Ipp32u)IPP_UINT_PTR((x))) == (Ipp32u)idCtxRSA_PrvKey1) +#define RSA_PRV_KEY2_VALID_ID(x) ((((x)->id) ^ (Ipp32u)IPP_UINT_PTR((x))) == (Ipp32u)idCtxRSA_PrvKey2) +#define RSA_PRV_KEY_VALID_ID(x) (RSA_PRV_KEY1_VALID_ID((x)) || RSA_PRV_KEY2_VALID_ID((x))) +#define RSA_PRV_KEY_IS_SET(x) (RSA_PRV_KEY_BITSIZE_N((x))>0) + +/* alignment */ +#define RSA_PRIVATE_KEY_ALIGNMENT ((int)(sizeof(void*))) + +#define MOD_ENGINE_RSA_POOL_SIZE (2) + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ +#define rsaMontExpGetSize OWNAPI(rsaMontExpGetSize) + IPP_OWN_DECL (void, rsaMontExpGetSize, (int length, int* pSize)) + +/* +// pubic and private key operations +*/ +#define gsRSApub_cipher OWNAPI(gsRSApub_cipher) + IPP_OWN_DECL (void, gsRSApub_cipher, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsRSAPublicKeyState* pKey, BNU_CHUNK_T* pScratchBuffer)) +#define gsRSAprv_cipher OWNAPI(gsRSAprv_cipher) + IPP_OWN_DECL (void, gsRSAprv_cipher, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsRSAPrivateKeyState* pKey, BNU_CHUNK_T* pScratchBuffer)) +#define gsRSAprv_cipher_crt OWNAPI(gsRSAprv_cipher_crt) + IPP_OWN_DECL (void, gsRSAprv_cipher_crt, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsRSAPrivateKeyState* pKey, BNU_CHUNK_T* pScratchBuffer)) + +#endif /* _CP_NG_RSA_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpngrsamethod.h b/plugin/ippcp/library/src/sources/ippcp/pcpngrsamethod.h new file mode 100644 index 000000000..59593aabb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpngrsamethod.h @@ -0,0 +1,76 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// Internal Definitions and +// Internal ng RSA methods +*/ + +#if !defined(_CP_NG_RSA_METHOD_H) +#define _CP_NG_RSA_METHOD_H + +#include "pcpngmontexpstuff.h" + +/* +// declaration of RSA exponentiation +*/ +IPP_OWN_FUNPTR (cpSize, ngBufNum, (int modulusBits)) + +typedef struct _gsMethod_RSA { + int loModulusBisize; // application area (lowew + int hiModulusBisize; // and upper) + ngBufNum bufferNumFunc; // pub operation buffer in BNU_CHUNK_T + ngMontExp expFun; // exponentiation + ngMontDualExp dualExpFun; // dual exponentiation +} gsMethod_RSA; + + +/* GPR exponentiation */ +#define gsMethod_RSA_gpr_public OWNAPI(gsMethod_RSA_gpr_public) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_gpr_public, (void)) +#define gsMethod_RSA_gpr_private OWNAPI(gsMethod_RSA_gpr_private) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_gpr_private, (void)) + +/* SSE2 exponentiation */ +#if (_IPP>=_IPP_W7) +#define gsMethod_RSA_sse2_public OWNAPI(gsMethod_RSA_sse2_public) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_sse2_public, (void)) +#define gsMethod_RSA_sse2_private OWNAPI(gsMethod_RSA_sse2_private) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_sse2_private, (void)) +#endif /* _IPP_W7 */ + +/* AVX2 exponentiation */ +#if (_IPP32E>=_IPP32E_L9) +#define gsMethod_RSA_avx2_public OWNAPI(gsMethod_RSA_avx2_public) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_avx2_public, (void)) +#define gsMethod_RSA_avx2_private OWNAPI(gsMethod_RSA_avx2_private) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_avx2_private, (void)) +#endif /* _IPP32E_L9 */ + +/* AVX512 exponentiation */ +#if (_IPP32E>=_IPP32E_K1) +#define gsMethod_RSA_avx512_public OWNAPI(gsMethod_RSA_avx512_public) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_avx512_public, (void)) +#define gsMethod_RSA_avx512_private OWNAPI(gsMethod_RSA_avx512_private) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_avx512_private, (void)) +#define gsMethod_RSA_avx512_crt_private OWNAPI(gsMethod_RSA_avx512_crt_private) + IPP_OWN_DECL (gsMethod_RSA*, gsMethod_RSA_avx512_crt_private, (int privExpBitSize)) +#endif /* _IPP32E_K1 */ + +#endif /* _CP_NG_RSA_METHOD_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpp192r1precomca.c b/plugin/ippcp/library/src/sources/ippcp/pcpp192r1precomca.c new file mode 100644 index 000000000..ddb9b6604 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpp192r1precomca.c @@ -0,0 +1,1937 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (P192r1 precomputed) +// +// +*/ +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +#define OPERAND_BITSIZE (192) +#define LEN_P192 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* P192 affine point */ +typedef struct{ + BNU_CHUNK_T X[LEN_P192]; + BNU_CHUNK_T Y[LEN_P192]; +} P192_POINT_AFFINE; + +extern const __ALIGN64 P192_POINT_AFFINE ec_p192r1_precomputed[28][64]; + + +#if defined ( _IPP_DATA ) + +#if !defined(_DISABLE_ECP_192R1_HARDCODED_BP_TBL_) +/* see ippcp_baseptbl.cpp test for generation details */ + +const __ALIGN64 P192_POINT_AFFINE ec_p192r1_precomputed[28][64] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0x332fa108,0x0d8cb30c),LL(0x76d12909,0x8a4bd3f7),LL(0xf3d218f7,0x954cc8f9), LL(0x1e422289,0x7b12a337),LL(0x8966f05e,0xde22b524),LL(0x6aeda84d,0x6a293d83), + LL(0x91fae7b3,0x04a5cf09),LL(0xa7838baa,0xd7fb036c),LL(0x3e00e321,0xae53f3bb), LL(0xf5bc34a6,0x369ef507),LL(0x09d7bb36,0x7d5170c4),LL(0xad59278a,0x241e55c9), + LL(0x230c0249,0x56b3fd7f),LL(0x42bebbf4,0x3386809f),LL(0x770c581a,0x53b5ad45), LL(0x7fb74b1e,0x6be17b49),LL(0x50d91fbd,0x16445c48),LL(0x43dc19c0,0x228f18e2), + LL(0x9a01a832,0xda417f6b),LL(0xd148d209,0x8a42d66e),LL(0x60c3ed50,0xe544900a), LL(0x0fc71a62,0xc79d34b6),LL(0x8733ef53,0xe640e166),LL(0x69803121,0xc1084635), + LL(0x1d8490a8,0x69bca784),LL(0x4d92a6ad,0xa7c43520),LL(0x7012b11d,0x4ec31c34), LL(0x843e401c,0x6261825c),LL(0x6a65a2da,0x102b7a93),LL(0x2d96f43a,0xdf00083f), + LL(0xd6f1d9ee,0xae494b37),LL(0x81585220,0x4708a709),LL(0xed8612f6,0x3c3a183d), LL(0xda5571cc,0x8d3ab905),LL(0xf6131ada,0x8c11bd0f),LL(0xe556b1ea,0x83f240b8), + LL(0xe5efca73,0xeb8ad91f),LL(0x1650b841,0x4c83fc44),LL(0xa63ebb45,0xeea07d43), LL(0xcc6ab309,0x2c8262c8),LL(0xca1e7327,0x44a67081),LL(0x66147372,0x6fef6d88), + LL(0x5264d6fe,0x7afb70b5),LL(0x1e79609b,0x8f728a49),LL(0xeae172bd,0x441912c0), LL(0x8ec468d4,0x96163a6d),LL(0x07b3dc14,0xbd51c5c7),LL(0x707ae554,0xca743b38), + LL(0x449ce446,0x9f27848b),LL(0xed6f60e4,0xedc613b6),LL(0x33ef2855,0xd028dc5c), LL(0x97566f06,0x32bbfe7f),LL(0x529bebe5,0xaee52dfc),LL(0xdbd304ac,0x7dfad9da), + LL(0xcb9cdc1c,0x301800ef),LL(0xa4c0645f,0x01c6df1b),LL(0xd2c1c6da,0x7c2b2dca), LL(0x91015dd9,0x92fe0217),LL(0x43f5e36d,0x94ec3870),LL(0xfae24bbd,0x3400d9bd), + LL(0xf19ed4f9,0x44a299cc),LL(0x3ec18b4b,0x5ce790e3),LL(0x3898e8a1,0x34de50ac), LL(0x52948777,0xa2641e2f),LL(0x538eff35,0xa5037393),LL(0x38e46331,0xf1b6bb32), + LL(0xa53425b9,0xa02e1119),LL(0x9dfe0d6b,0x6a2f4991),LL(0x360f54c1,0xda626cb7), LL(0x39cdd976,0xc224f8ac),LL(0x21725fbe,0x5b23f190),LL(0x164b3680,0xf305458e), + LL(0x0f8904a9,0x153f3b78),LL(0x14a75349,0x44a7bd96),LL(0xd85d4a3f,0x4093735f), LL(0x3f7db015,0xed1d5ed0),LL(0x1fff90b3,0x174975f7),LL(0xdcd47496,0x9838d562), + LL(0x24fc4afc,0xf299b94a),LL(0x1cc29901,0x4bb0fffe),LL(0x3eb21741,0x6cd077ba), LL(0x95c82991,0x6e97b4f9),LL(0x8209cb7d,0x848b6921),LL(0xa082e4c9,0x34d09e8b), + LL(0xb0cf681b,0xc373e084),LL(0x6610b602,0x7da92737),LL(0xf098041b,0x46cadc98), LL(0x6cdec872,0xd3e0adf8),LL(0xa7842f28,0x50d43591),LL(0xcdf46778,0xa35efdc3), + LL(0x7944ad9c,0x90c57eb8),LL(0x1e7a0999,0xb9c5cf4b),LL(0xee3159ba,0xe0315bd7), LL(0x06a19eaf,0x17e47405),LL(0x4be877f9,0x5abccc61),LL(0x22195568,0x427706fb), + LL(0xe7056d4e,0xcfdba265),LL(0xa9b98e89,0xc9d1189c),LL(0xa4a88eff,0x3e1cd309), LL(0xd040ec58,0x8b2429c3),LL(0x7859d5e6,0x6967afd6),LL(0xa5fbf616,0xcdf1095b), + LL(0xfe4697b7,0x78060e67),LL(0x2648e5f8,0x1ed0242c),LL(0x4f235455,0x687ef0c6), LL(0x80964fe2,0x95a99ec5),LL(0xa71449df,0xe59296c6),LL(0xe31fca8c,0x6e0faa87), + LL(0x417692ee,0x37b23549),LL(0x7a4db977,0x3fafb8db),LL(0x5d550c5c,0xc85fef61), LL(0xc591dfcc,0x88f70525),LL(0xadbba7d1,0x20d82c9e),LL(0x3bc105c7,0x34bdc150), + LL(0x312e2b25,0xa96781ce),LL(0xc28a98fb,0x21d19734),LL(0xb32fbb94,0x33d91d89), LL(0xf1a39faa,0x4b423b1e),LL(0xd6d73b09,0xd6b91a11),LL(0x5cf7ee7b,0x1d5bbc7d), + LL(0xc7b622a0,0x09a14d89),LL(0x04ac07cd,0x719fb611),LL(0x485b1f75,0x487f1ad3), LL(0xf779459c,0x6604b185),LL(0x79ffa446,0x633d924a),LL(0xe2ed4e42,0x0a48ac49), + LL(0x97a2ac99,0x8f8141df),LL(0x559a156a,0x2f85aea4),LL(0x0de172c5,0x045569d1), LL(0x70195a60,0xd31e98ed),LL(0x31901571,0x639f8252),LL(0x017861e5,0xddfb3017), + LL(0x8d76bd59,0x791db75f),LL(0xa5c667f8,0x664088fb),LL(0x5a1f032a,0x7cc0335c), LL(0xbf031b03,0xabb460b3),LL(0xc8f559b0,0xcb61b85e),LL(0xfed307dc,0x282335ba), + LL(0xe9b47661,0x398b31e5),LL(0x4785fbe8,0x17a770ad),LL(0x2bf4567e,0xdb5e0ce3), LL(0xc82fa654,0xd8db9c86),LL(0x1b760f9c,0xdc7dbdfc),LL(0x65df38f7,0x7dc26c5a), + LL(0xbfd973a2,0x422b5a19),LL(0x7de885a1,0xe637c08a),LL(0x28af843c,0x493d27a7), LL(0x27d0f709,0x0635af16),LL(0xa46b8241,0xfaa0731d),LL(0xde8513de,0x30152936), + LL(0xc2c6a98b,0xe5b1f5c5),LL(0xdd1f1a85,0x9999e0ab),LL(0xf09f0de9,0x0f017d6e), LL(0xffad11c5,0x2cd84536),LL(0x97ac8fd1,0xc150b469),LL(0xf4a156d0,0x7275b4b6), + LL(0xdea3626f,0xeaa0614e),LL(0x51b201c7,0xb0778899),LL(0xbc24cf40,0xe1e17ccf), LL(0x6f6a4f09,0x5b9a2356),LL(0x81b35be5,0x6b43dd89),LL(0x8eb6864b,0x7134a900), + LL(0x6256a868,0x1fbfbc8d),LL(0x3b84fa71,0xc3c97795),LL(0x75676360,0xaf1330f2), LL(0x5ab6bd0c,0xaa33c244),LL(0xbd5e407e,0xece4da7e),LL(0x2f438421,0x8e4be95e), + LL(0x267c3b3b,0xb550886c),LL(0x072ada2a,0xe4ef0b6a),LL(0x16cf9337,0xefb23bc9), LL(0x035d6cdd,0xf4945a35),LL(0x24d8682c,0x7c2fbc75),LL(0xb35b5932,0xb4b6f148), + LL(0x1704593e,0x5ea32695),LL(0x487113d8,0xcb897688),LL(0x48e6fb62,0x9a382e50), LL(0x59da6a81,0x845eeeee),LL(0x72ab659e,0x427e258f),LL(0x0186211c,0x8d145e39), + LL(0xc1a83d71,0xa5549752),LL(0x07c519da,0xe9b2c58f),LL(0x286a27e2,0x6f5e6aee), LL(0x7cfc6dd4,0x99cece8d),LL(0xbbc24c84,0x18c9b5f7),LL(0xd5a88338,0x7e5875ca), + LL(0xde0dd9bb,0x655f1b75),LL(0x2ef38753,0x19df3f60),LL(0xeceb06b1,0x7a25bb17), LL(0xce909ba8,0x1359f3db),LL(0x65603d61,0xaa2802b7),LL(0xe147b10c,0xf7070a53), + LL(0x4fbffaeb,0x41095e96),LL(0x8b3c6012,0x422337e2),LL(0x563eef5d,0xb731e12b), LL(0xc07cc789,0x7e950bdd),LL(0x9d9cc3aa,0xf97c2753),LL(0x5a7f7345,0x7af21a9a), + LL(0xe3a0c0e2,0x7e91f2d6),LL(0x54a1cd29,0xa286afb7),LL(0xa6160c29,0x8c0ddde8), LL(0x8c5398c8,0xb03e8586),LL(0xfe6503e1,0x4db7075d),LL(0x7ec6bed6,0x999eec3e), + LL(0x16036842,0xb35bcfb0),LL(0xecedc764,0x036d725d),LL(0x2c6f8668,0xcbcb0161), LL(0x1b04bc1a,0x0348f719),LL(0xe1e99a42,0x0b2d84f8),LL(0x9c1ec6e6,0xf098e97a), + LL(0x3f5a8497,0x17f2106b),LL(0xf56d582b,0xc4c8ac85),LL(0x514207b2,0xde518ab8), LL(0x2e30b7c4,0x33018834),LL(0x643786e1,0xf867de48),LL(0x735735ab,0x72d64984), + LL(0x2775c0c5,0x9d83fd01),LL(0x065da96c,0x8658cc5a),LL(0x604210f1,0x466cf509), LL(0xe8fc750b,0xdc4d8237),LL(0x1477a111,0xb13663ff),LL(0x4252c38b,0x6a0ef58f), + LL(0xe5bcf759,0x717f1389),LL(0xa8ecb8d4,0x2146493b),LL(0x3e3c9d15,0xd51427c9), LL(0x77c1c32f,0x7ec8afc4),LL(0xf63856de,0xfa0a577e),LL(0x32750be7,0x95a6c860), + LL(0xcaa33960,0x49b1bb22),LL(0xe647c5a4,0x45871855),LL(0x167d6801,0x6d71e970), LL(0xa2764f1f,0xbbeae386),LL(0x1284c39a,0xc7df73b8),LL(0xe8a8b423,0x3ddc63be), + LL(0x6c2484c5,0x4cf0be08),LL(0xbff601e9,0x59028533),LL(0xcc241c87,0x94453c36), LL(0x0b18c6d5,0xb6e2065d),LL(0xfb4927d4,0xafde2953),LL(0x51875c38,0x69d1f3bc), + LL(0x6709fe0c,0xc4bdbeb2),LL(0x2aa46589,0x86c2f225),LL(0x1c6d96c6,0x6e215f98), LL(0x1900c952,0x3b102255),LL(0x0b476bea,0x09b6f447),LL(0x1643c833,0x88877356), + LL(0xe1f4c47f,0x897e15e4),LL(0x3deb58b0,0x9055b4df),LL(0x5d73f210,0xb189fd7b), LL(0x344e98cb,0xabbc3bfa),LL(0x17fe8809,0x355345a8),LL(0xb8a63413,0x848ea408), + LL(0x0ee8588b,0x111d94b7),LL(0x1cae2230,0x5f7ba2ed),LL(0x8b428b68,0xd1119eb2), LL(0xc5901d8a,0x5ac72be9),LL(0x1a7e213d,0xd11c39be),LL(0xae1574db,0x5eba5216), + LL(0x78e7a47d,0x2c6b4874),LL(0x03871f7c,0x5cbfeb97),LL(0x8dfcd4af,0xdb875c76), LL(0x6202ffc6,0x922461a3),LL(0xf1463db1,0x084e44fe),LL(0xa6b3ba89,0x55a890d4), + LL(0x0d359302,0xbbb38087),LL(0x3bf7212f,0xe0c552b5),LL(0xce70eda4,0x6873aa54), LL(0xf0dcd6fe,0x42eb0476),LL(0x202c6fba,0xe354ae37),LL(0xbb182481,0xd2eeb9a4), + LL(0xac565505,0xfb13f470),LL(0xe0d9811e,0x8e6be184),LL(0xb7fb0ea8,0xc727bd2b), LL(0x2a49df43,0xe0cc92d4),LL(0x6c43c82b,0x551ef99f),LL(0x449a2247,0x50d3acd2), + LL(0x8959dc53,0x2e246f36),LL(0x3f449349,0xc6882bd2),LL(0x52d56c22,0xfbcda062), LL(0x037c14b7,0xaf1525bc),LL(0xf51db774,0x79f2c364),LL(0x397c0db5,0x51d5156e), + LL(0x88ea2408,0x15fdfc20),LL(0xc31c09fc,0x39ad6859),LL(0xa7479cce,0x23bf58d5), LL(0x6df4616c,0x200420e7),LL(0x0bb71847,0x6516f75d),LL(0x60976e77,0x478ec1a4), + LL(0x2d623962,0x38f56704),LL(0xb8e018b4,0x1d5927f2),LL(0xb7159417,0x60f41495), LL(0xe71a9c08,0xa531058e),LL(0xc4427fd5,0x038edfcf),LL(0x16bcd9b9,0xf40f0c3f), + LL(0x4e8b0660,0x5c3875f8),LL(0xba508d58,0x4835397b),LL(0xa986f017,0x28f855c2), LL(0x947b88a2,0xab86055f),LL(0x4038096a,0xf6aab3c8),LL(0xc66df877,0x5babb42e), + LL(0x218251e9,0xbc40bae0),LL(0xff92ffab,0x86a6f175),LL(0x15c92a68,0xc538fbe8), LL(0xce8e05fa,0x94b037e5),LL(0x38df007b,0x1e23b8c7),LL(0x6dfc21b0,0xcf60919b), + LL(0xeaab0281,0x88c58a61),LL(0xfd515dfa,0xbdef49bd),LL(0x7b29a823,0xafb4049d), LL(0x51fb148d,0x803b4141),LL(0xefcde52e,0xa607366b),LL(0x756dd392,0xdc243912), + LL(0x07b07222,0x6c66ac7c),LL(0xabbb5a7e,0x7a2251bf),LL(0xea506766,0x6898eec1), LL(0x0c8100c3,0x8ee773e9),LL(0xb5ac1e10,0xe267812a),LL(0x45ea2616,0x51d3e17e), + LL(0xc5d7bcee,0xec435b31),LL(0x692565f6,0x45068195),LL(0xee8a64da,0xabbe69a5), LL(0xf3259fd4,0x10b23048),LL(0x6cf98be2,0x0df0afcf),LL(0xce0764fa,0xf317669c), + LL(0xab0c2496,0xe0cad6d0),LL(0x3e58a13e,0xad9d4a4b),LL(0xcb2f20c6,0xb4009b9f), LL(0xfbd04c92,0xf586adaa),LL(0x65e4a2c2,0x27f06af1),LL(0xe6ac820a,0x5efc658f), + LL(0x24c1a379,0x14a80bf6),LL(0xab134b06,0x0879a1fe),LL(0xe46fa8bc,0x6425c07b), LL(0xf328660c,0x626b781e),LL(0xa6f4006e,0x32c537fd),LL(0xa5cee8a3,0x3de55b30), + LL(0x45111281,0xd072005c),LL(0xc6dd923a,0xc38687f7),LL(0xe7e55c30,0xc5493c3b), LL(0x1e7bcaf3,0xc801a0dd),LL(0x66af003d,0x7d896378),LL(0x5c5fc040,0x88c92d2e), + LL(0xb5ac249b,0xd7ac3494),LL(0xd031be50,0x646f3e8c),LL(0x925d3ebe,0x6a6d2984), LL(0x0e7ed329,0x4696646d),LL(0x1822a37a,0xe4167a29),LL(0x3f6245b2,0x9419d1d2), + LL(0x489578d4,0x752de436),LL(0x6c0f251c,0x0ade8b1c),LL(0x59ad5609,0x29b34ffc), LL(0x857c870b,0xd4af9bf6),LL(0xe6b0527e,0xb779fab3),LL(0x70ef261f,0x20970dfe), + LL(0x392b4efc,0x2bcf9ad9),LL(0x8a796449,0x24ce4be0),LL(0xdc2b03ad,0x099a3cad), LL(0x223fe0fc,0x35749d6b),LL(0x8c2e618e,0xe9a66616),LL(0x3910e994,0xc7df5779), + LL(0x14729183,0x4af80891),LL(0x2650cc8e,0x44458190),LL(0x587ad69a,0x738c0bd4), LL(0xefc4b5e7,0xdab8713a),LL(0x902363c0,0x7d6d6ae3),LL(0x45acff6b,0xad593898), + LL(0xedc9ecd6,0x4c3723e7),LL(0x9731c5bf,0xc8fa6afb),LL(0xcc9bf5cb,0x162d7a77), LL(0xd28f51e8,0x623c7ce2),LL(0x45d36aad,0xb68fedf5),LL(0x2e95d0ea,0xc840c399), + LL(0xa5542c7d,0xcc1674d5),LL(0x1fb770dd,0xc8ebdbdd),LL(0x0a3b16ce,0x7d70a1ed), LL(0x685db534,0xa74f8148),LL(0x37c0b157,0xa0eab0ad),LL(0xa3971e22,0xcd8063a7), + LL(0x794542c1,0x9bded711),LL(0x3360a470,0xa56154fa),LL(0x79e1003c,0xf0bdb57b), LL(0x36c1f48f,0x48e694c5),LL(0x0eb1a568,0x3b71c023),LL(0x6090a9d3,0x4f574953), +}, +/* digit=1 base_pwr=2^7 */ +{ + LL(0xb3da4d9d,0x9cb08eb5),LL(0x8c573da9,0x95707fee),LL(0xe85fccd9,0xa5ad07fb), LL(0x769af379,0x5d3b50b3),LL(0xb9761267,0x79e01d7e),LL(0xee770876,0xdd24ac5b), + LL(0x492d1c7c,0x7808129c),LL(0x6b626f03,0x97ad42c7),LL(0x5d974059,0xbf9a52c8), LL(0xeaa619c8,0xa888802d),LL(0xbbe19555,0x171450c4),LL(0xb980305f,0x173483c8), + LL(0xa8a831fc,0xa5fa35ab),LL(0xf7ffad71,0xe4f05b10),LL(0x3f8d1cc3,0xc1ed613b), LL(0x6c60e44a,0x9d0f2a96),LL(0xfc64d797,0x8ece4c89),LL(0x8a315b0e,0x6fbdadb4), + LL(0xc352becd,0x824863da),LL(0xa2c14e2f,0xd5d43090),LL(0x46bc9bb9,0x85272175), LL(0xaa9a25da,0x75eb8695),LL(0x85c7c93c,0x4a05c961),LL(0xa9043492,0xcb5861df), + LL(0x62da9c26,0x0a04a3c6),LL(0x6e6542fd,0x9907614b),LL(0x8e9ada48,0x39c0b3b7), LL(0xe51bb6c4,0xf7dffbcc),LL(0xe566dea8,0x0316edb7),LL(0xb0ac507f,0x8b1a59cd), + LL(0xd1581b68,0xbfa7fc59),LL(0xdd5c0d6d,0xdd9906b2),LL(0xfadb3203,0x50570aa0), LL(0xb207b0c6,0x026b8114),LL(0xcf4b11ff,0xf3829145),LL(0xc3abfb69,0x97eef9fe), + LL(0x82a8e3aa,0x3ced44cc),LL(0x8cfe1e20,0x991f72d1),LL(0xeed3e6cb,0xce242a8b), LL(0xf6a15c38,0x70905e2f),LL(0x1a2a9a53,0x0d5db763),LL(0xa414c46c,0xe60a8854), + LL(0xaf1c73a9,0x0b6b1174),LL(0xc0678153,0xaef24601),LL(0x63cc9eb3,0x5dac22ed), LL(0xa0f27800,0x80606754),LL(0xf3dc2a70,0xe3154503),LL(0xec01fbfa,0x6ba23ce4), + LL(0xdc5f2b20,0x53cf654b),LL(0x3e7d94fb,0x4203ff82),LL(0x43547670,0x1f39db20), LL(0xf6716d31,0xbf42ccca),LL(0xa8ef535f,0x7be941f0),LL(0xaaac51de,0x890245d9), + LL(0x2c853305,0x3aba1480),LL(0x43e3e158,0xd4554887),LL(0x135360e9,0xcbae9038), LL(0x6e23c4f0,0xe8d3054b),LL(0xe66d94c6,0x19bd813e),LL(0xafcd895d,0xf4397ee0), + LL(0xc23cf227,0x5526335b),LL(0x6e23ef80,0x1053b920),LL(0x06c75842,0x656efa8a), LL(0x6397c380,0x7b7d1a0a),LL(0xe8cbe845,0xfea5cd22),LL(0x47a7e673,0x620c0df1), + LL(0x7aaf742d,0x8d07f60f),LL(0xeda0b762,0x74469872),LL(0xe237de09,0x3f90d096), LL(0xf4d8b55e,0x679535d3),LL(0xbc04ae92,0xa463084f),LL(0xf1202dff,0x2a0d536d), + LL(0x3ac85f57,0x27649c81),LL(0x235fa2cf,0x8b41bf96),LL(0x9df79933,0xe866618f), LL(0xadc59139,0x6d476615),LL(0xd404e889,0x09b1345f),LL(0x0f7eb70f,0x6bd51082), + LL(0xdc3366d9,0x63fe2f64),LL(0x7732bce9,0xf48f309a),LL(0x6f637459,0xbcd3fb82), LL(0xa9255eaf,0x6d9b5c4b),LL(0x2e1fdd05,0x01ff5ae4),LL(0x72e33bef,0x66e45b33), + LL(0xe080d6b8,0x1d521fcf),LL(0x14f56cf4,0x4e5d581b),LL(0x9a50ece4,0xea6d7579), LL(0xe1c8a0af,0x2d34a6d6),LL(0x28e5f588,0xd459901c),LL(0xf52fe058,0x8d41ab2b), + LL(0x436cba75,0x780fd8f6),LL(0x09f798f7,0x7216f9a2),LL(0xa3720506,0x72c9e7a9), LL(0xfa919d28,0x72cbdd01),LL(0x053500b6,0x045474ba),LL(0xaf3af74d,0x6630329d), + LL(0x5fa22efe,0x548b87c5),LL(0x62b464fe,0xcf449871),LL(0x7637a7dc,0x1eb2ccd0), LL(0x693b51ae,0x6ae5b6b1),LL(0x0a635765,0xcd15e6cc),LL(0x32160012,0xb8139da2), + LL(0x88eff9b5,0xf4477fb6),LL(0x9b8264aa,0x1abe49f0),LL(0x6f59e67b,0x2ed2f447), LL(0x598889ff,0x71460c4d),LL(0x94f3f05f,0x04b1e2ed),LL(0xf04b29b7,0x9b1b5eef), + LL(0x0a36430d,0x2de30220),LL(0x00e9adf9,0xe1df5595),LL(0x1d56ee5c,0x4642ab6f), LL(0x321cd0e6,0x32675e76),LL(0xbd822a36,0x37eaa735),LL(0xff9b1023,0xb807c5a0), + LL(0xb77035f4,0xc1637964),LL(0x2e67810c,0x627deaa6),LL(0xe68721d1,0x11c73b51), LL(0xddd6a178,0x00b6c78f),LL(0x43326826,0x63414a2f),LL(0x9370cb95,0x3f3157a5), + LL(0x28cac9b8,0xa6f2bedb),LL(0xdb9143d1,0xa8d660f1),LL(0xff740aca,0x28161efc), LL(0x81b9607f,0x6a8c99b0),LL(0x3379b6fd,0x6f6991fb),LL(0x54b4b97f,0x3463ae20), + LL(0x5901b54f,0x85e79db9),LL(0x55a0c83e,0xffbd105b),LL(0xef647c2f,0x3b871868), LL(0x18cedd8a,0x5aa96847),LL(0xb6ac9ecc,0xabd9b3d6),LL(0x93bddbd9,0x707f61d7), + LL(0xfcf1d3f7,0xa3e82462),LL(0x0b854fa4,0x619933c3),LL(0xd12e3bed,0xdceb86e0), LL(0x5ac77287,0x8e500715),LL(0x65cf6840,0xe5cb2c78),LL(0xc874ed06,0x6a2fcd3a), + LL(0x75c74d72,0xa9af4af2),LL(0x7df05ffc,0x0f341f15),LL(0x31713e68,0x13bae06e), LL(0xd8e1e3c0,0xbeb2661f),LL(0x9d5b5ff4,0xffe49ef1),LL(0x61d5cae6,0x04eac206), + LL(0xedd6a166,0x2f4fee08),LL(0x2eb29647,0x646cc729),LL(0x4f0f6cd5,0xb5a3c6bb), LL(0x2779dead,0xd1a9c06b),LL(0x4aed0996,0x066e3452),LL(0xbdc98d70,0xcbab5149), + LL(0x88f89e9b,0xf4185c2e),LL(0xf9985e9e,0xc8e5dd64),LL(0xbb24492e,0xb8d5b8d3), LL(0x0fab80d7,0xad79a272),LL(0x5b3133e3,0xb766095b),LL(0x8b2b7fda,0xc83eaf38), + LL(0x4448648e,0xedc5a97c),LL(0x6ae43bdd,0x2658d407),LL(0x48a8e439,0x766de9f3), LL(0x127fb314,0xca58b583),LL(0xb49667b5,0x65246221),LL(0x99398ac5,0x5b180e85), + LL(0xcdf0d01f,0x75910da1),LL(0xae61cd5f,0xb0fbade7),LL(0x17e45ebd,0x0e94c843), LL(0x72944c2a,0xe13b1cad),LL(0xa8546c01,0x80e5d5cc),LL(0xd98df1d8,0x8cb5077e), + LL(0x8e8cdd4c,0xc73d42b7),LL(0xf107a930,0x3a4ade51),LL(0x0da1e241,0x775acdae), LL(0xe97e3d45,0x1919504b),LL(0xb09e94e4,0x15d0774a),LL(0x4d58aaf7,0x3bd3c7f9), + LL(0x7998dd8f,0x07eb2872),LL(0x2cf2179a,0xe9813bff),LL(0x06921a45,0xfa9171da), LL(0xcf58180f,0xb8c04797),LL(0x8721e9b4,0x31db6313),LL(0x91b2c60c,0x381c63f7), + LL(0x66013a01,0x11b0d72b),LL(0x6c92f9e0,0xaf00d7aa),LL(0x47dcc4fb,0x2a4a91be), LL(0x0fa92641,0xb049b8d4),LL(0x448bd3a0,0x069abbac),LL(0xe74c7a8c,0xca288262), + LL(0x385633ba,0xdffd6286),LL(0x19ddfcd5,0xdad4d394),LL(0x4bc0ef1f,0xe90ccfaa), LL(0xc1fc6f55,0x016bf2e9),LL(0xab3c2edb,0x879b641f),LL(0x89695f01,0xd5a122fc), + LL(0xc302a272,0x12a1065f),LL(0x782cef51,0x368397a3),LL(0xbc4ad296,0xebac9fb3), LL(0xe0227d62,0x0caffee7),LL(0x88e685f2,0x63679dcd),LL(0x6aff1b35,0x85ced1a6), + LL(0xa3155a1c,0x8b4e0205),LL(0x8310b45e,0x53afa029),LL(0xce35c0c9,0xa7571202), LL(0x06f892ac,0xa0b7a35a),LL(0x796af8cf,0xe4fbab54),LL(0x9d086c19,0x14ac6bfc), + LL(0xc6267432,0x2e6b041b),LL(0xd1a15019,0x60267755),LL(0x50c3b7c6,0x7d6c36c2), LL(0x9bbe459a,0xf25437d5),LL(0x23468209,0xe1eff41c),LL(0x046c931a,0xe95608fd), + LL(0x3a8012a2,0xd410363c),LL(0x62137413,0x2c5a7c08),LL(0x711e77de,0xaeca7f42), LL(0x08ce5358,0x492fb4fb),LL(0x48f0de03,0x715abe73),LL(0x5f625701,0x726faa61), + LL(0x739b9455,0x2262f752),LL(0x511abdd2,0x8cd71649),LL(0xdeb366db,0x6765aca3), LL(0x3e0a005c,0x686587e3),LL(0x33f1710e,0x029b3605),LL(0x828cc559,0xf7b50e02), + LL(0x66442cbd,0xe50f5b8e),LL(0x84763a5c,0xf27cc25d),LL(0x3120d35d,0xa92103eb), LL(0xfcef0800,0x91c0542f),LL(0x2d72f1ce,0x8bd12bb5),LL(0xf8086d1d,0xe97d290f), + LL(0x4ef89505,0xab4b24f7),LL(0xfe72dd92,0x2bc14e79),LL(0xc60af192,0x94226552), LL(0xfd45454c,0x474c2b8d),LL(0xc7753a83,0xac99b5d3),LL(0xc8f1d3ae,0x6946a61d), + LL(0x0c6a72ee,0xcb9c16c5),LL(0x64f9d8b2,0x96e95912),LL(0xdaf45f48,0x7c59cb24), LL(0x79b6515b,0xe520df3f),LL(0xded63e3c,0xb79c6ab5),LL(0xec685103,0x49767609), + LL(0x6d892dae,0xbae68558),LL(0x3e48a96b,0xf07e8b59),LL(0x49e4d777,0xa7115219), LL(0x56e5e52c,0x724d7d29),LL(0x6fe58f07,0xb2483de9),LL(0x67836a1d,0xb28ffc89), + LL(0x507bc006,0xaebcc451),LL(0xce8569b0,0x27b4e0db),LL(0x02bf59f6,0x579ae452), LL(0x5cff7495,0xc53b052a),LL(0x4cc9201b,0xc816b206),LL(0x540dd63b,0xd3c7350a), + LL(0x26022a40,0xd9df51ca),LL(0x92be30ea,0xc1842bc2),LL(0xfa161a61,0xcdd5cee3), LL(0x554031f4,0xdaefdb75),LL(0x4935fd8a,0xd28afc65),LL(0x0a32f4c9,0x439d6d68), + LL(0xeb1dc395,0xbe55112c),LL(0x531a3e8c,0x90def44c),LL(0xf77a7b59,0xf5b9ef12), LL(0x4c8ce124,0xc3ec1edf),LL(0x1c16391a,0x4edffe21),LL(0xe9ada0cf,0x40b8ec6f), + LL(0xae68790a,0xc586619e),LL(0x0e0ba4ca,0x5bbe744a),LL(0x70ee1ec0,0x21a82b73), LL(0x7b9850f1,0x82066320),LL(0xee9bcc2c,0x2a7536c0),LL(0x9d661f43,0x9632c632), + LL(0x1724c849,0x6d3b65ad),LL(0x8cfb77ce,0x3bef3b0e),LL(0x71fb5452,0x670e88e5), LL(0x1035a015,0x82d57c5f),LL(0x23736115,0x340c145b),LL(0xb1c2dc13,0xf1a704ea), + LL(0x0ed1952e,0xd3aa33da),LL(0x9a32b9c9,0x459e7596),LL(0x15d05a80,0x15dcd976), LL(0x75895b93,0x85eea023),LL(0xc2fcd91d,0x8daa32c3),LL(0xba5669ce,0x2290ba90), + LL(0x66e7e5af,0x85ac1742),LL(0x05bff18e,0x9ba521e0),LL(0x556a9133,0x9f081540), LL(0x929cd03f,0xb913fd04),LL(0xf46a514d,0x3065b31b),LL(0xe351ba04,0xe2fe761d), + LL(0x139c5933,0xaf1e2230),LL(0xc129bd42,0x0c6c8096),LL(0xf4cf79c9,0x56f406b5), LL(0x4e86f542,0x772cb3d0),LL(0x843d10bd,0xbe007c1b),LL(0xe8e6693c,0xd3a201f5), + LL(0xcfee362e,0x5a6556de),LL(0xa9264918,0x00dafb80),LL(0xc2ab4fcd,0x608dfd33), LL(0x091a15a3,0x29946cea),LL(0xfcbef4a0,0xb8caca39),LL(0x27c3eb56,0xb0c39fce), + LL(0x21b66fdb,0x9fad053d),LL(0x74192d67,0xb529c9b6),LL(0xf21d3c4f,0x34c31800), LL(0x33cb3cc5,0x80797948),LL(0xb20d1f9b,0x18c66091),LL(0xe49755a6,0xc9fe30a8), + LL(0x4beb71b8,0x90ae4d45),LL(0x4083ee91,0x2fc24099),LL(0xab8d6bb8,0xbcb9c603), LL(0xbca4c1b4,0x72d50046),LL(0x1a6be188,0xbc5fbf1c),LL(0x3da03c7d,0x4bc93b91), + LL(0x3931092b,0xcbc53ee8),LL(0x9af003b5,0x455bb703),LL(0x9ac0e7d7,0x8da6de21), LL(0x9ccbcb20,0x6a4900cb),LL(0x73963c8e,0x3146af37),LL(0xd86a3d10,0xfc9469ab), + LL(0x8078ecda,0xcd49df84),LL(0x45a4ff92,0x9caf52e4),LL(0x5a8fc8e7,0x4e8bd802), LL(0xdfeff51d,0x4339ea5f),LL(0xc4433bd8,0x25169385),LL(0xebe52ca1,0xdb3a7ae3), + LL(0x09e9bb4b,0x8cb174c9),LL(0x224cf62c,0x44657124),LL(0xe1f6dbe1,0x70c991d3), LL(0xb10cd328,0x561771b8),LL(0xb5242c51,0x4e08ed68),LL(0x9e7d3968,0xd3eb6498), + LL(0xbef053e4,0xaef71aa7),LL(0x49740ae4,0x3c3c52b5),LL(0x8eca22b9,0x5b6f510e), LL(0xf2645282,0xf1b861ae),LL(0xe96d07f6,0x670312de),LL(0x0c04dcfb,0x413388fe), + LL(0x7734d6a7,0x7b924e76),LL(0xa86fc636,0x3616aaaa),LL(0xb9d584ca,0xd600f983), LL(0x67c54321,0x6324b5b2),LL(0x843f1742,0xee50247c),LL(0xde7f93af,0xf92e7c7a), + LL(0x0aab4e71,0x1e668209),LL(0x236d6f67,0x76b4b879),LL(0x1fe85adc,0x8358a8ae), LL(0x550e1974,0x7567b0d6),LL(0xbd316399,0x3d193081),LL(0x92a0d80d,0x383ef613), + LL(0x26ad5111,0x04a8ee34),LL(0x2efe5eeb,0x56e28325),LL(0xcd888cec,0x88e3f877), LL(0x0de0fb50,0x9ce73666),LL(0x7be9e17e,0xc84bc9e9),LL(0xbc67f215,0xf3a496a6), + LL(0x41f7e964,0x548c525b),LL(0xafc8296f,0x18b03c78),LL(0xc171d822,0x14e4c1df), LL(0x03b39f89,0x090e2c4e),LL(0xe157c072,0xaf0feb62),LL(0x77227f20,0xe10a4331), + LL(0xc72c5d07,0x40314b18),LL(0x1407f165,0xb2b01e30),LL(0x512cd1ec,0x4ad000d1), LL(0xcf5ce913,0xd7310420),LL(0x865fb1f8,0xa38701df),LL(0xb1db3c80,0xac4c2674), + LL(0x36bf878b,0x07697637),LL(0x6ddd10b4,0x662c148d),LL(0x8d97a563,0x75b55463), LL(0x7f1198b4,0x34bf8bd9),LL(0x643001f6,0x31155240),LL(0x0d3f4f13,0xda176596), + LL(0xcdcf7cab,0x44c61a3b),LL(0xecb257b3,0xcda79f8f),LL(0x8a15332d,0x7f701080), LL(0x4472224a,0x6f48e031),LL(0x31fafaff,0x3e89e0e6),LL(0xbfc3f192,0x1f066674), + LL(0xa2df8c34,0x132f7d0e),LL(0xbc28bb95,0x66d020ad),LL(0xa0c4325a,0xb942cb64), LL(0x07a82d3a,0x4922c971),LL(0xad5d63e9,0x22ce594b),LL(0xc2e553d3,0xdf369ada), +}, +/* digit=2 base_pwr=2^14 */ +{ + LL(0xa96c5146,0x773311a3),LL(0xafc15c15,0x8ff8dce1),LL(0x3e382d13,0x59b9e79c), LL(0x3e0a552a,0x0ed1f12e),LL(0xce4662af,0x487503ec),LL(0x7000683e,0x624bc8ab), + LL(0x58cb54ac,0x59ffacde),LL(0x492dc39c,0xef64164f),LL(0x337cd1ec,0x16b13c76), LL(0x47ca44a2,0x1e2033a7),LL(0x193743a8,0x8477b54e),LL(0x8e016823,0x557a7155), + LL(0x5da83913,0x96d2f426),LL(0xc427cf5a,0x41062046),LL(0x1dd15a14,0x8016f670), LL(0x78840ddb,0xacd78288),LL(0x7feae4af,0x21529372),LL(0xc77acb08,0xdb65ffee), + LL(0x9f1f177a,0x23d068f6),LL(0xbec8525d,0x508a8bed),LL(0xabb44bb0,0xa9de104e), LL(0xaef83c7c,0xb1ad4ce8),LL(0x9b842889,0xf045e04d),LL(0xa931cb25,0xca1ba541), + LL(0x87b11b0a,0x377c8c86),LL(0x70d0248a,0x4eb952ff),LL(0xec2537f4,0xbde06ebe), LL(0x48f400cf,0xfc17552b),LL(0x84cd18c3,0x73e1b8a5),LL(0x4e54b85c,0xa3a8b445), + LL(0xa64a281a,0xa9a806ba),LL(0x7b3bc32a,0xbc16fb01),LL(0x8ab7aede,0x8d2a8d5a), LL(0x2d7db806,0x7db641a7),LL(0x2d8c945e,0x8afe3e84),LL(0x1aefc1de,0x3e700391), + LL(0xf8271efc,0xd9e4e55a),LL(0xecac958d,0xd50a0d2a),LL(0x3293a393,0xc58b1b30), LL(0xca65ac88,0x3dfed217),LL(0x13dbff4e,0xe308b3d8),LL(0x7a70bcfa,0x185024cb), + LL(0x73d7e444,0xd7ca2cc9),LL(0x5d9cfe00,0x2ab7d94e),LL(0xd1333221,0x24a41faa), LL(0x6b27127b,0x9ce62b32),LL(0x20aca054,0xf66d0897),LL(0x079bb62d,0x41f3f259), + LL(0xc11087c3,0xd74686ed),LL(0x99d4d141,0xd199b1e3),LL(0xdb7b97dc,0x2e3a551d), LL(0x8910fa3f,0xb59f58e6),LL(0x7ecfc3ef,0xdef98365),LL(0x349b65ff,0x29ec545a), + LL(0x0598f0ef,0x7fc08cb5),LL(0x4400c739,0xa5208904),LL(0x4c9f98b7,0xb02f25b3), LL(0x901fc002,0x4d9901cf),LL(0x49babf27,0xdde7d571),LL(0xf2d65888,0x13b3e92c), + LL(0xb6dc4b6d,0xd55436e9),LL(0xc04a2f37,0x746c5407),LL(0x4485d943,0x84d53bb7), LL(0x16b241f8,0x0ba98680),LL(0xf8feecce,0xbdd3b788),LL(0x87dd6420,0x1801aa7c), + LL(0xcd59a045,0x047bdddb),LL(0xb8464ecc,0x0b74793b),LL(0x37cce6df,0x95661e95), LL(0xfc3170e4,0x20d1535b),LL(0x68c8b253,0x14546482),LL(0xc42e9c3d,0xbae5cef0), + LL(0xe87e6d86,0x0201464f),LL(0xbd67f280,0x1bab0e73),LL(0x64600ebe,0x69b188cb), LL(0x5f9c98da,0x3641dea5),LL(0x9aa645be,0x94d2a2cd),LL(0xbd545f72,0x1ef74b42), + LL(0x914d779c,0x19faba59),LL(0x27ba5f19,0x90007928),LL(0xe1ee88ff,0x46f12e72), LL(0x726a44cc,0xa9e0848d),LL(0x285108c9,0x13d4e943),LL(0xdf77e165,0xb5721271), + LL(0x492ca661,0xa444123a),LL(0x8e0769ae,0x9ff4a82c),LL(0x718014db,0xc6786b05), LL(0x19f577ac,0x702027a5),LL(0x56e9b5ef,0x349ca959),LL(0x4f6e4b5a,0x1f746299), + LL(0x4f0efa59,0xb23ca413),LL(0x15a3b35c,0x003f4a5b),LL(0xe4a4d655,0xa0fe8a5a), LL(0x9e5467af,0x044479ec),LL(0x6d4b3c89,0x5abb290c),LL(0x1c2f5364,0xfd845d3c), + LL(0x6837a39b,0x21cdab37),LL(0xf18d4f99,0x7037f403),LL(0x6621328c,0x964d48a7), LL(0x930c4f4e,0xd70553ec),LL(0x5274352b,0xca35a6fd),LL(0x6199ce61,0xff584ff2), + LL(0x479ebc39,0x60a7a4ce),LL(0xaa703602,0xaf3c24ce),LL(0x89689136,0xfe79ffc9), LL(0xc7ede59c,0xaab98ecc),LL(0xbf5659bd,0x933f24a2),LL(0x1d702fc6,0x68fd0d06), + LL(0xedbb3147,0xbb51d576),LL(0x5d358026,0x038e2a2c),LL(0x45ed9fed,0x10fef0db), LL(0x55be7ba9,0x78b92751),LL(0x69bd1f87,0xae493919),LL(0x186699c2,0x632e8ffd), + LL(0x9085fbe9,0xb0b4b604),LL(0x808be4f0,0xf93f9bf1),LL(0x6d8bf009,0x2b58f977), LL(0xd6188f6c,0x020fe5ea),LL(0xd25805ca,0x85d4a860),LL(0x07bb3697,0x7547f724), + LL(0xe0b4ea32,0xb225b950),LL(0x33f7d58d,0xbc6e0982),LL(0xcb7418f4,0xb81e161f), LL(0xc0020282,0xfa1572b5),LL(0x8ab14fe1,0x3fababab),LL(0x08b2a18e,0x3a033779), + LL(0x6495bacb,0xe816e0fb),LL(0x5d8888be,0x238bd498),LL(0xe3df2fc2,0x7ab0b8ca), LL(0x978404d8,0x88ee40ec),LL(0x26a463b7,0xbc3d1a07),LL(0x65d21535,0xa4c92dcd), + LL(0x2928f5f1,0x819bd554),LL(0xbf6255d1,0x82906c78),LL(0x406326b1,0xc710bf1a), LL(0x09f4cd28,0x3a9bbfcb),LL(0xded76f80,0x83e41584),LL(0xbbe53844,0xca1c61fe), + LL(0xae17eaf5,0x80c38892),LL(0x61b16da4,0x3670cf14),LL(0xa795a9c9,0x9f9ddd50), LL(0x1255afff,0x6f1841d7),LL(0xb69e10fc,0xc733cd3f),LL(0xdaf931ce,0x515ff527), + LL(0xcc8a9a7a,0x14969bd6),LL(0x2c1d2761,0x579c2fb7),LL(0xf09d2a18,0xb0bfb370), LL(0x073b22bd,0x0baf361d),LL(0x1a52d79f,0xb5e11353),LL(0x22d425c2,0x9d475b0d), + LL(0xecdc5b6e,0x24d4fea9),LL(0x1731ad86,0x8b3af04e),LL(0x7dfe43b4,0x0a1c0e04), LL(0xaf2af7bb,0x5cf225bc),LL(0x69ef4bed,0xb0885ab2),LL(0x830333e4,0x90999bc9), + LL(0x985d6058,0xa8c2e9f0),LL(0xd1b5a3f0,0x8e9e9162),LL(0x3e407711,0x1055feff), LL(0xaaba085f,0x5a33934f),LL(0x23b30a1b,0xf961622f),LL(0x6dafb1dc,0xb1a2ee28), + LL(0xa448ee27,0xe49caf6b),LL(0x4560f7a7,0xb8552bfb),LL(0x93f90be8,0xb68fd6ca), LL(0x1f2499d1,0xbb85cfca),LL(0x093c01a1,0x1a51059e),LL(0xd231b79e,0xdf98052f), + LL(0xc076155c,0xf696a525),LL(0xf93ce35a,0x3a519224),LL(0x2e706fd0,0x2771d43b), LL(0x51a451c7,0xde78cd08),LL(0xae569dba,0xc9a60017),LL(0x22a0b1b7,0xa3cafd39), + LL(0x422b409c,0x4afddf96),LL(0x75f5eb64,0x6313a926),LL(0x626ac381,0xf9420ee7), LL(0xe9858ee9,0xfbe23e3f),LL(0x3c678a64,0x658013be),LL(0xf2ad2c6c,0xbbcfddc5), + LL(0xd05334aa,0xf9303aca),LL(0xd7626b98,0xad3e45cf),LL(0x8ca3a1f8,0x56c81f5d), LL(0x4aab3342,0xe892a0b4),LL(0xa1db86fc,0xf8a3f244),LL(0x97566251,0xdee7ed3e), + LL(0x5efced68,0x0c65a22c),LL(0x9ce653ac,0xfa181866),LL(0x1e590014,0xa46d7d86), LL(0xc79656dc,0x69d234da),LL(0x00d2b7a7,0x4dbb31d4),LL(0x3452ca10,0xc9636e5d), + LL(0x0778d7f8,0x5850e572),LL(0x31b9202b,0x4323e55b),LL(0x5e8d8006,0xaea618dd), LL(0x999bf27e,0xe0f4408d),LL(0x8fab0cc5,0x4bd06762),LL(0x5a75c171,0xddb647f2), + LL(0x452f35a5,0x6ce09fdf),LL(0x91938a04,0xe6f5d9dd),LL(0x4cab01a5,0x79821593), LL(0xdc0ff9f5,0x054bf7a2),LL(0x613b5386,0xdb52d927),LL(0xf35b7179,0x661fe231), + LL(0xa035b792,0x8a4adcd0),LL(0x2790ce5c,0x854bed6f),LL(0xac3fa847,0x64b0eee2), LL(0xfeb32887,0x7b752cc2),LL(0x09fcfa29,0x5e34ee86),LL(0xac0cd2e1,0xd06594aa), + LL(0x10995206,0x6151e607),LL(0x93bb033b,0x93532d80),LL(0x7a33bd69,0x0beac8c5), LL(0xfb8f97c6,0x6f85d5ec),LL(0x0517b3eb,0x661303e8),LL(0xbc3f62c8,0xe17cc0cf), + LL(0x4f4d78fb,0x279803d5),LL(0x66c81c4e,0xca63bac0),LL(0xc854f59a,0x6ec15cd1), LL(0x0f159ecf,0xb345c1f6),LL(0x3763e854,0x84807c78),LL(0x8cc6374a,0x691abd9b), + LL(0xe4f37f9a,0x77c0e93d),LL(0x611d93dc,0xc60578c7),LL(0x1aff93a6,0x7c98f95b), LL(0x5bb698ce,0x534f1e2d),LL(0xd8bad550,0x0cdc34b6),LL(0x16afd591,0x597794f0), + LL(0x571c8a4e,0xb795a174),LL(0xe651a52f,0x15ce6b83),LL(0xf49edec9,0x9394c28a), LL(0xf091dfa7,0x0f74e17e),LL(0x65c44142,0xcc9e8180),LL(0xa4df670a,0xc33d77e9), + LL(0xc1633318,0x44536321),LL(0xc0b9deff,0xefb782b9),LL(0xc6b86a19,0x24fda05e), LL(0xf868535b,0xba601337),LL(0x91c21fc3,0xd3d126a5),LL(0x0663ffb0,0x10b1b7b1), + LL(0x7fa1153d,0x8162598c),LL(0x688e7c55,0xc3c97288),LL(0x89c8fc1b,0xb0c2872d), LL(0xa859461e,0xfbc2a074),LL(0x82f7d203,0x91591a5e),LL(0xa909de2c,0xe278dac7), + LL(0x7d4e49c7,0xad689f7f),LL(0x940bf215,0x12072de0),LL(0xde694ba0,0x7ec61fdc), LL(0xfed04942,0x4a4ee787),LL(0x0f665159,0x0497d6c5),LL(0x94136075,0xe9e08707), + LL(0x19850a32,0x391c4103),LL(0x50d61027,0x0ad15740),LL(0xd883b3e7,0x9ca3e6c7), LL(0xf0d758fb,0x76891ec0),LL(0x04d6f53d,0x89ae897b),LL(0xcffefb93,0x77e9b63a), + LL(0x216ee99a,0xf201c95e),LL(0x4fb9bed8,0x65648551),LL(0xda5d4d62,0xda9c97f4), LL(0x6aab7149,0xfae41f2e),LL(0x56aa67d1,0xfb649545),LL(0xc024449c,0x493a5061), + LL(0x4df4c709,0xd0aa84eb),LL(0x06a93789,0x69c9246f),LL(0x917b88eb,0xe19b7340), LL(0x9fd99349,0x7f7cfe6c),LL(0xa8ebc191,0x6c82e590),LL(0xade7110e,0x7c50c13d), + LL(0x50ffdce6,0x17155bf9),LL(0x5281bb39,0xab2bb8dd),LL(0xc4ba3181,0xe73086fe), LL(0xa736d737,0x41d9f1f7),LL(0x3df7fbbd,0x831b8099),LL(0x3b6ffde2,0x566467da), + LL(0x36bb3e58,0x6cb9c1b9),LL(0xb8a84147,0x450324ab),LL(0x8bedffc5,0x99535f56), LL(0xa7e14db3,0xb0a718ef),LL(0x304dcfa7,0x65a62f9f),LL(0xd623bb6e,0xfb2f289a), + LL(0x9d546bd5,0x0888c3e7),LL(0x772582a9,0x1a97b3cb),LL(0x7645a4c8,0x50937134), LL(0x93ea1519,0x70d77533),LL(0x079ff6e5,0x5837b53c),LL(0x45bcc030,0x8f5c8745), + LL(0x1370e46d,0x28549138),LL(0x0bcf90ad,0xf0c3a434),LL(0x639db090,0x4d42664a), LL(0x0158f802,0x345c315a),LL(0x0463e159,0xef82afb0),LL(0xd3e83b12,0xfcf2c419), + LL(0x9e3fc0b3,0xe04ea5a2),LL(0x37fd1788,0x98b3901d),LL(0x2d603830,0xc6326a28), LL(0xbe5e9c25,0x6e6c5c6b),LL(0x0fc60fb7,0xac753036),LL(0x12b1dad0,0xc4cf690c), + LL(0x46768f3f,0x273e19a9),LL(0x4414d65a,0x93aa3754),LL(0x5fabe262,0x4ecff706), LL(0x7ff1403d,0x6d9cfcee),LL(0x33284115,0xf6e4192e),LL(0x5e218033,0x80aa8768), + LL(0x485363f3,0x0067ee42),LL(0xfab8b185,0x5fcd61f5),LL(0x8e63d384,0xe3c345c8), LL(0x23ff551f,0x80847073),LL(0xe339aa9e,0x6a804b17),LL(0x6bb64f96,0xb9142088), + LL(0x7679428f,0x855916bb),LL(0x9c4cf460,0xbab9e9be),LL(0x55dad941,0x0c3bdf26), LL(0xfedb73be,0x6b8e8c3a),LL(0x0355a4c2,0x07fdbfa0),LL(0x5e3c1b3d,0x8e9137e5), + LL(0x57927722,0xb4afd653),LL(0x5f997d66,0xd48cbfc8),LL(0x7719d80d,0x5125ce07), LL(0x654d2350,0x19d47bce),LL(0x4d7a3060,0xfc671097),LL(0x15d775f7,0xddad1eae), + LL(0xc6a285a3,0x9e8ea16e),LL(0xc535adfb,0xc2f0c22d),LL(0x217f73ce,0x3fc464b9), LL(0x73a8ee71,0xc543babb),LL(0x0da708c9,0xce410235),LL(0xc2f48649,0x99849442), + LL(0xc83b501e,0x6b420f3d),LL(0x642f062d,0xe08c411c),LL(0xf03d2cf5,0xc79fd495), LL(0x07236a83,0x2184fa72),LL(0xc9a0ea3b,0x31b0e4f4),LL(0x5b82a3b3,0xd7795d4b), + LL(0x3fe60842,0xb2520494),LL(0x45bdeed9,0x751336f1),LL(0x9718fa41,0x1b66bb31), LL(0xda9a21c4,0x5a50a96b),LL(0x615dcdec,0x94cc1fb5),LL(0xe39c3066,0x556b641f), + LL(0x15ea6075,0x69d00e4c),LL(0x83005a21,0x3e707e72),LL(0x767ca1f8,0x84e2a469), LL(0x3f8c4c84,0x94b82739),LL(0x81a2db60,0xe00dd19b),LL(0xd7cabd28,0x16f30fec), + LL(0x6305314b,0xb08563f9),LL(0x7ac22e44,0x73d8fb6a),LL(0x55919896,0x9b969f2f), LL(0xa3460685,0xcc9dd3fa),LL(0x1226dbee,0x377b5d9e),LL(0xaaa83ccc,0x0b4bbd51), + LL(0x61f910de,0x929c87b0),LL(0x5f2bdd34,0x0595e87f),LL(0xb587735f,0xa5b54a4e), LL(0x6ac0195c,0xa3bbb78b),LL(0x1d44758a,0xe6b38b87),LL(0xac01f679,0xfd575f0c), + LL(0xb21a6382,0x223f54eb),LL(0x672c43f7,0xf6f79b9d),LL(0xb8b258f5,0xcf8054d3), LL(0xa119b37d,0x88ec08ee),LL(0xafda5f1f,0x4b0fd837),LL(0xad4546ad,0xc0dde1b4), + LL(0xe673eb95,0xbf7186d6),LL(0xc9d6a6a8,0xa324e752),LL(0xc117d914,0x5ebf8238), LL(0xad6715dc,0x9c33641e),LL(0x1d597adb,0x99439b58),LL(0x9c6a2ef6,0x83ba580e), + LL(0xb17b3816,0xbf87295c),LL(0xee1db90d,0x05c753ce),LL(0x2554bda2,0xa31eccaa), LL(0x81176cf2,0x66691105),LL(0xb4e7bb4c,0x67eb9bec),LL(0xc294982a,0x6443f703), + LL(0xd0ab699f,0x86c4e0ba),LL(0x748ed429,0xce3d72f1),LL(0x53e24aed,0x0ed09a39), LL(0x4db6e8ed,0x0ac3cda5),LL(0xeed93b68,0x26b6ee99),LL(0x2d53c5f0,0x3707c0fb), +}, +/* digit=3 base_pwr=2^21 */ +{ + LL(0xc3bba334,0x549606d0),LL(0x013ca242,0x6dcb5519),LL(0xdcf78255,0x784d65cc), LL(0xdbd76716,0x73d0de0c),LL(0x1010fb15,0x2bc13bf7),LL(0xe8d77e91,0x21d2c3cc), + LL(0xa396d29f,0xf8efa6ac),LL(0x767470ec,0x33ec678b),LL(0x7241f5fc,0x23f69526), LL(0xd2a4a560,0xd0338dfe),LL(0x9d30be61,0xce5baa02),LL(0x4db7b6e5,0xb39ee0e3), + LL(0x4268d7ee,0x93adf307),LL(0x2c9a12bf,0xfcbae0f0),LL(0x534822a7,0xb76859b8), LL(0xf961bd84,0xab38334c),LL(0xd09e4e94,0xb17e54bd),LL(0x43d3a64a,0x0fe2b812), + LL(0x9577e8d9,0xe17445a1),LL(0xd2d34121,0x330f6634),LL(0xa1aa8076,0xcea03741), LL(0xfcfafd3e,0xfddda6ff),LL(0xe05b9369,0x440df5db),LL(0xbb0d7ca7,0x51fbac8e), + LL(0xc9b4ce1e,0x320accbd),LL(0x99292bb2,0x3798c1f3),LL(0xa402db93,0x8371a2e6), LL(0x65d07e1c,0x716af227),LL(0x23851a3e,0xd06eaa2f),LL(0x61f48045,0xc42ee506), + LL(0xc40da094,0x538f7dc5),LL(0x54a44890,0x4c651fc4),LL(0xee59f9d2,0x80876d6c), LL(0x66c8ac59,0xad6aff6e),LL(0x257e1b91,0x32b4e3ba),LL(0xec717e05,0x957bedc7), + LL(0x7459bbfe,0xe45216bb),LL(0x2ef69f90,0x3dac0bfe),LL(0x6161cb8b,0x2cc6a2b9), LL(0xf6e7e3b3,0x472e91fd),LL(0x304e8482,0x4d2e40f0),LL(0xaf1042aa,0xf4afc219), + LL(0xd64583ec,0xffc53726),LL(0xeef5bce9,0x6b462381),LL(0x24829cb3,0x753a4bef), LL(0x404af02f,0x976d6897),LL(0x448a7822,0x93313219),LL(0x399e5d55,0x79449ea9), + LL(0xc5ecabd1,0x3574a11c),LL(0x34e48369,0x11ee8559),LL(0x915873b6,0x7fa30b5d), LL(0x2ae5b9b4,0xe1a71608),LL(0x2e04edad,0x57296722),LL(0x30d27fbf,0x84cdfbff), + LL(0xbe3bd4b2,0x0c29de57),LL(0x2898b5b6,0xfdc6a64c),LL(0xc8bb55be,0x5604fc5b), LL(0x2e98dac3,0x1e6f616c),LL(0x8e9baefb,0x494a5143),LL(0x5501fe87,0x251c23c9), + LL(0x6cdda2c2,0xebcbef56),LL(0xe3ee721e,0x85b1e422),LL(0x9dcdd732,0x32bcca8f), LL(0x72410bf8,0x182e8ce7),LL(0x36f1dca3,0xaa7f4322),LL(0xdcd402ab,0x893d6417), + LL(0x43cd1278,0x87f47e84),LL(0xe1831ddd,0xc8b878ac),LL(0x093ba446,0x4d0a3597), LL(0x40080bf9,0xafc47c89),LL(0x3832f14c,0x3157bb67),LL(0xb8eb8baf,0x2abb24b3), + LL(0x063399bf,0x30752625),LL(0x2979063f,0x47abe9c9),LL(0x55165854,0x01c9def8), LL(0x6fb4555d,0x0bab44d6),LL(0x567eb3a7,0x8a53411f),LL(0x726f9e4e,0xb8aab552), + LL(0x2440a85b,0xad782e43),LL(0x2fbb1ce6,0xfa5a74b7),LL(0x1ae20947,0xc49e442b), LL(0x772117aa,0xd3fca276),LL(0x6115a3ed,0x303be2dc),LL(0x1a6f32b8,0x3b808eb6), + LL(0x71faca97,0x673ae260),LL(0x086041a0,0x32f3b688),LL(0x1367ca73,0x26acc3be), LL(0x8c66b759,0x48400913),LL(0x9b73c0e4,0xc88e5241),LL(0xd44b961b,0x17a8a61d), + LL(0xe56aeb1a,0x0a3a7387),LL(0x461fdd3f,0xa4010610),LL(0x016484bb,0x601e6822), LL(0x04bbe3e8,0xde403502),LL(0x9f071625,0x6a1b8c7d),LL(0xdd3f60b3,0xd1e9028a), + LL(0x1496f098,0x7b626130),LL(0xbf161daa,0x62dffbe1),LL(0x9c44fcc7,0x401ddc78), LL(0xb9872e73,0xc81c3a33),LL(0xc751f26b,0x0e48c326),LL(0xa0829b6c,0xffaeec0e), + LL(0x77a5b096,0xf5530fa7),LL(0x19734245,0xb008b72c),LL(0x848b3785,0x7462bc45), LL(0x6cf9e5f2,0x29fa43a4),LL(0x9854d78b,0xd8b27b11),LL(0x9097f3d4,0x6f8fe5a5), + LL(0x30c97aa5,0x63ec5b71),LL(0xc6488713,0xfa8462af),LL(0xd7b335fa,0x51f2d273), LL(0xcd075cb1,0xf2891fbd),LL(0xd007c58e,0xffe2576c),LL(0xd8bc9492,0xaeec8e91), + LL(0x6f905b81,0x305b6908),LL(0xbf19b3bd,0x5d023c2e),LL(0x22ae8649,0x9c503cbe), LL(0x25255b41,0xde8be78f),LL(0xe809567c,0xb1e4b2de),LL(0xb09e4638,0x986a2fd5), + LL(0x213fb6cf,0x0b36dcd5),LL(0x834d7c84,0x5f340cf2),LL(0x42696c00,0xf835cd54), LL(0x71e8739d,0x7f02199e),LL(0xb4f38aed,0x0663d540),LL(0x1f7c9176,0xed21b27e), + LL(0xbc7e8681,0x1810377d),LL(0x1545ee0d,0x242d18eb),LL(0x45281613,0x3360ba32), LL(0x808ebc75,0xb14e805f),LL(0xad26b94c,0x965c6c59),LL(0xebf7f5e2,0x24e3cd91), + LL(0xc0623d66,0x493d0777),LL(0x05131c2a,0xafe840f2),LL(0xfe23fc98,0xb282512d), LL(0x3735071c,0x47342277),LL(0x105f0570,0xfe0900ce),LL(0xad56ac6e,0x7f80e17f), + LL(0x7da80215,0x5509a924),LL(0xe2039096,0x0d1b8304),LL(0x32330f7c,0xb8d360d9), LL(0x866bf185,0x8b6b538a),LL(0x60f48919,0x65565d06),LL(0x4a88485d,0x457d3e36), + LL(0xb4d530a4,0x21ffdbfe),LL(0x134babd4,0xb68a01ac),LL(0x3c545d8d,0xeac3a42a), LL(0x525bd6e8,0x2ec4920e),LL(0x11415be9,0x91d90569),LL(0xc859b9a9,0x27f2bf78), + LL(0x3a492c73,0xdef766d6),LL(0xbd647210,0xd395535f),LL(0x7a9398e6,0x2cf03d25), LL(0xa10ca7f8,0x00d0d0ec),LL(0x05dde357,0x384e9692),LL(0x66d09f76,0x86dfa64d), + LL(0x97c72efb,0x949c71bd),LL(0x3942aaad,0xeaebb176),LL(0x6b83fb91,0x2998f398), LL(0xccd511b6,0xa3fa1c7e),LL(0x8636cb8b,0x30452ba9),LL(0x0c63c213,0xfd01b34f), + LL(0x654f4b1f,0x161634df),LL(0xba6b7612,0x786d3d9b),LL(0xa3f145c5,0x7b731aff), LL(0x81bf5f5d,0x318ec0fd),LL(0x28ec1847,0x5aac3946),LL(0xef3f2a56,0xb5b34960), + LL(0x8a25550d,0xb8603afb),LL(0xca58e8f8,0x7d76ca1f),LL(0x52edd227,0xb124c5a5), LL(0x749a0bb0,0x4ff6045a),LL(0x166a72cb,0x9d1c4729),LL(0x18c9dd50,0xa1165c3d), + LL(0x32ec01e6,0xaf916e4f),LL(0x74270c7a,0x9b18b797),LL(0x2bde0960,0xc31c12bd), LL(0xe3a52afc,0x6fdbedeb),LL(0x99dcd3e1,0x2fcf26c9),LL(0x2ec4570a,0x15d634a7), + LL(0x02e98f6e,0xe27fb84e),LL(0x016e8348,0x19815362),LL(0x5ee51a3d,0x72e0c390), LL(0x36959aff,0x5f3ea99c),LL(0xe880a6fb,0xec5b0f2d),LL(0xac887faf,0xaecf25fd), + LL(0xca7c485f,0xd0640e47),LL(0x8c826885,0xa0eae2dd),LL(0xf0750194,0xfcd0e169), LL(0xe05f5115,0x04c965ed),LL(0xd7ba9d0d,0xe9482a7a),LL(0xd261b83f,0xf2660cd3), + LL(0xf53ab896,0x722e7324),LL(0x83e9fccc,0xcabeeaad),LL(0x0886fae1,0x332ff124), LL(0xfa23970c,0x0e8c2e7d),LL(0x433ab568,0x26f580ee),LL(0xcdcf0e3e,0x7cdcc1f4), + LL(0x513d4695,0x83ac29d5),LL(0x9101ca09,0x525837bc),LL(0xe8e10f27,0xecd93292), LL(0xeea1edfd,0x312f9d84),LL(0x83f862a3,0xdf9354ea),LL(0x15909df4,0x0f9f120a), + LL(0x5c61ed01,0x16fa2ab0),LL(0x816f7ce0,0xeab42f96),LL(0xf1cbe36b,0x1aca9b66), LL(0x1763d0c8,0x7fb3d70e),LL(0x7c64a8fc,0x5fb8567b),LL(0x45fb302c,0x08b686bd), + LL(0x6270b30e,0x0124d430),LL(0xcf5b5235,0x566f1fd2),LL(0xbee07063,0x923da430), LL(0xe2c6736c,0x2ecebb06),LL(0xad6d6ee4,0x3a3fdafe),LL(0x82bd6945,0x16522430), + LL(0xd6d11f78,0x0d162ae9),LL(0x69047eb7,0xddb375c5),LL(0x926e0966,0xd125f66b), LL(0x100fb84c,0x1cfafcac),LL(0x40c50ecf,0x1f4c7fd4),LL(0x499513b2,0xbd8ac3ec), + LL(0x5feaf69f,0x937412eb),LL(0x641cace4,0x760d3378),LL(0x203e5367,0x9bcec28e), LL(0x45fa3774,0x457f3a0d),LL(0xdf85b5f1,0xec51fd4f),LL(0x37d174ba,0x47390235), + LL(0x0a893990,0x7df7dee7),LL(0x8f08f682,0xa525af4c),LL(0xfae95f9b,0x9edbb45a), LL(0xcdc01949,0x58f3b29d),LL(0x773a1cde,0x9afdfd03),LL(0x8b16ab71,0xd6077f9e), + LL(0x13611c0d,0xc96eabbc),LL(0x7581f50a,0x8af0d512),LL(0x93c963cd,0xf75a7835), LL(0x9060a883,0xb7487030),LL(0x17ceb72c,0xfc03c9b1),LL(0x79773be4,0x64773851), + LL(0xd416e391,0x8f73e056),LL(0xb0289136,0xf9c29801),LL(0x1ebcb0de,0x85fd38b0), LL(0xf0af703b,0x9928f60a),LL(0xbbd1143a,0xd77a236c),LL(0x2b99b61f,0x120472d4), + LL(0x5f4a504c,0x0e448282),LL(0x5cc9b39f,0x1fca16bf),LL(0xdf0166de,0x4e47e87a), LL(0x76644e8f,0xf11ccae7),LL(0x4b20ddcf,0x84113220),LL(0xe274c42f,0xae2e75b4), + LL(0xf97bdda6,0x604a226f),LL(0xadbee2bb,0xadd35dc6),LL(0x986e403e,0x8b7db9ea), LL(0x6ad6318f,0x9007482c),LL(0x891688d9,0x22b19d05),LL(0x4d848a95,0xe974ab42), + LL(0x88cc05d4,0x339df4aa),LL(0x5855f83a,0x14e21ec8),LL(0xd790d568,0xddcd7ff2), LL(0xcf09873b,0x5c8a6e40),LL(0x134b7a3c,0xb76d74a0),LL(0x07549e84,0xd05b80d6), + LL(0xc5f26048,0x845e4b79),LL(0xeac9a450,0xcb338886),LL(0x9b807f9a,0x78f027d1), LL(0xb02ce220,0xf81fb903),LL(0xcd541a4a,0x2bc100d8),LL(0xb3d3cbfd,0xf10cf19f), + LL(0xb198d5f3,0x74645ba6),LL(0xcebf9671,0x9fbabd70),LL(0x5d7a8816,0x57cf26bc), LL(0xc18901bd,0x415d9e95),LL(0x08448312,0xa71715a6),LL(0xe80f10b3,0xbb1d05fa), + LL(0x488ffac2,0x6065bcb2),LL(0x21393e2d,0x02526899),LL(0x4f000282,0x259f0d34), LL(0xf12f0afa,0x10a4333c),LL(0x62a1dba3,0xaa0b50d7),LL(0x8cf13d7e,0xe09542dd), + LL(0xc2ba51fa,0xf15ba587),LL(0xcdcc4e52,0x72f2bc15),LL(0xe3ca3356,0xd1c3673d), LL(0x3028612e,0xabbfd1f0),LL(0x9def1d98,0x4ab9792d),LL(0x4815b9f7,0x02e11fbf), + LL(0xf804ca53,0x24940965),LL(0xd69ecbb9,0x5073162c),LL(0xdccb4f88,0xe078c3a3), LL(0x1f34a5f8,0x06f13d89),LL(0xfca14e1e,0xa848dd8e),LL(0x8c4c3fac,0xb989d0a4), + LL(0x3f31ee3d,0x670aa037),LL(0xc8999458,0xf72dfbba),LL(0x4698301e,0x36e3a8b0), LL(0x1a579aef,0x26b32ad4),LL(0x98b2b956,0xdff0c7ec),LL(0x77953721,0xa732a2c4), + LL(0x436265d5,0x0ff83c66),LL(0x06547c6f,0xfa5166e1),LL(0x5bfd456d,0x03018748), LL(0xf306cdd5,0x1b4ec2b6),LL(0x4b56f91f,0xe064b766),LL(0xa5805ee3,0xfdeb932d), + LL(0xc49208e8,0xa583f200),LL(0x369d91c7,0x34a07e82),LL(0xa89b1fd5,0x3fe43f6f), LL(0xb439d920,0x76aecf08),LL(0x4547896e,0xf76a9539),LL(0x3019148f,0x3c69e2e4), + LL(0x41fc2ca3,0x79e74959),LL(0x6a5af93e,0x09a99e14),LL(0x8293aacb,0x6610c0ad), LL(0x84dff17a,0xc56e9614),LL(0x0ff4cf52,0x0a4f0290),LL(0x35902cdb,0x50fd4a21), + LL(0x7297ff6b,0xc526cdd2),LL(0x47459c97,0x2c8409af),LL(0xb7537567,0xbd3097f3), LL(0xb47675e9,0x5b29ab79),LL(0xfd4e344a,0xded7e0b2),LL(0x0eb1e2c4,0x40324c92), + LL(0x9c381ce8,0x617df28b),LL(0x4475066c,0x6771e091),LL(0x82a57c2e,0x7ffb1259), LL(0x90dbf30a,0x6997a10e),LL(0x4603a795,0xa412e99c),LL(0x6da0de96,0xfb49f3ca), + LL(0x24c43f70,0x28fb7939),LL(0x9b346573,0xa7d31444),LL(0x20545584,0xdf8f9b6b), LL(0x8a9b1477,0x54464b03),LL(0xad8c0fa5,0x623ad546),LL(0xae0601f7,0x5cf44ed1), + LL(0x0f36e763,0xbdc4a6e7),LL(0xd3fb2441,0xaa5058c6),LL(0xbd11e44f,0x7603b5a1), LL(0x6c72527d,0x65a896f3),LL(0xd59c82f0,0x214ffbf2),LL(0x0ec375a1,0xf886b405), + LL(0x6933ecb2,0x12e89a15),LL(0x2c1f2f43,0x3ed0ad89),LL(0xe0d5c6de,0xcafb442c), LL(0xe8cd1af4,0xb06cf2fd),LL(0x9c4265bc,0xb06e7452),LL(0xa73a0639,0x6af8b9d8), + LL(0x513e4297,0xc18ced3e),LL(0x7fab97a1,0xb4f2f3ca),LL(0x79cc3e70,0x16a64cee), LL(0x64e9eb0e,0x1f3006b4),LL(0xfedf5a33,0xf997d410),LL(0xffe83ec6,0x7fed67a8), + LL(0x3d30aa08,0x2452d81d),LL(0x1cd85802,0xcac330c3),LL(0x79a76f43,0x9a89abac), LL(0x17c27a7a,0xa965909b),LL(0xa62a311a,0xa1534cd2),LL(0x71a72a64,0xe4fe0317), + LL(0x261133ef,0x2d7c475e),LL(0xff4f2dd3,0x37952ead),LL(0xe360fb3a,0x10b0a5a5), LL(0xea3f4d28,0xb88323f0),LL(0xebeff23e,0xf1488cef),LL(0x8d265c93,0xa3b9477f), + LL(0xb76e90d9,0x57b098a1),LL(0x0449bf9c,0x988fbb42),LL(0x062f911b,0x95642d7d), LL(0x61b08116,0x788996fd),LL(0x09d205af,0x5b02272e),LL(0xb3d8f31e,0xdea85f72), + LL(0x09b907f5,0xdcc15267),LL(0xf7971f9b,0x784511d8),LL(0x20119354,0xe309478a), LL(0x4ce572f8,0x4d5e16a3),LL(0x2c62f607,0x7eb6eeed),LL(0x57f7d26b,0x6bcb2bff), + LL(0xd75c445c,0x2559d692),LL(0xb7443959,0x49d40028),LL(0x55e49cd0,0x5ee0d518), LL(0x33bb1b6d,0x0cade75f),LL(0x32bf7888,0xd8bac375),LL(0xa0531d90,0xa47d4b3b), +}, +/* digit=4 base_pwr=2^28 */ +{ + LL(0x58d5549f,0x881d4415),LL(0x7328bce3,0xed748e21),LL(0x2f1f8481,0x56f0d441), LL(0x021c9c2c,0x74ff865e),LL(0x93500f82,0xbaa63b47),LL(0xc2e3b807,0x0c40fade), + LL(0x9568fad3,0x6f93d120),LL(0x7ff0a77f,0x291875f3),LL(0xdd42f359,0x0608b32f), LL(0x644f9985,0xfee522d9),LL(0x05996cc8,0x4beb2bfd),LL(0x769aa367,0x5a77212a), + LL(0x504a6f07,0x96957fc9),LL(0x6acad37b,0xfd75c98d),LL(0x548f17da,0x2cc5e7b2), LL(0x7bdfaedc,0x039b865d),LL(0x1970dc2b,0x1ed21afd),LL(0xb4169fbc,0x93b309be), + LL(0xc373ba13,0xca0eaf9d),LL(0x798e41ad,0xe25f5f11),LL(0x1eca3ea4,0x5af4b3c7), LL(0xa23b9c8a,0x47bc86f1),LL(0xfae9d7b2,0xe9768f07),LL(0xed3e806e,0xf94f89f5), + LL(0xe4f24c73,0x43f87b32),LL(0x643fb20c,0x41c6cddb),LL(0x602b32c9,0x7093785c), LL(0xa13dc1f1,0xdf9d7247),LL(0xd42502e0,0x3a967995),LL(0x4df43de6,0xa0e28ce3), + LL(0xf53d962a,0xf3011fff),LL(0x1767f31f,0x9ef38fb2),LL(0x5f883ec2,0xa11413c6), LL(0x4c344917,0x84383633),LL(0x3f5cae22,0xca855976),LL(0x15b2fddf,0x929a1484), + LL(0xccfc0e1d,0x58946718),LL(0x809ffae5,0x651d4a6d),LL(0x87a653a0,0x6eeb8892), LL(0x6881e966,0x2c4c3c55),LL(0x6dfb6d35,0xbdb6d87e),LL(0x92113e28,0x7cf86719), + LL(0x6203f1ec,0x6451f3e3),LL(0xab59d68f,0x40681d08),LL(0x66af6fee,0xd0bf9608), LL(0xc1e4b6a6,0x5df24a1f),LL(0x5e6a069f,0x64c1b0f2),LL(0x63fbf5bd,0x124e2748), + LL(0xedf146a2,0xe6cbf0bf),LL(0x085c71de,0x85e47e89),LL(0x603e3ba3,0x39330eae), LL(0x6841460f,0xbcd9f912),LL(0x55ffa24e,0x4212f2ba),LL(0x3fb12ad2,0xadf49ddb), + LL(0xadb7dfa6,0xfb02103e),LL(0xbabeeea2,0x4dce5edb),LL(0x622cfe41,0xe4e76c1e), LL(0x5d2cde0b,0x318e8d34),LL(0x4448a054,0x5d3e168a),LL(0xa23e5457,0x444ff058), + LL(0xa8083fb8,0x06020b4b),LL(0x73e1d9fe,0xc6d07af1),LL(0x137f9872,0x2056f42e), LL(0x523b9b18,0x5ee31758),LL(0x39042106,0x58771cbe),LL(0xa0e5b696,0x114531cf), + LL(0x8a9552c6,0xa4eedc90),LL(0x6eb5fedf,0x23be4e8c),LL(0x5ad0744a,0xe5f6ada1), LL(0x4ca7d6f4,0x373a4a9e),LL(0x57cea5a6,0xb5a5a64d),LL(0x7f48cb04,0x3a65f463), + LL(0xc83aaf37,0x73506b7f),LL(0xd4bce539,0x9785f792),LL(0x7df31e2d,0xebbfa1b8), LL(0xd5a2ea75,0x3b66c6b3),LL(0xf2196549,0x32ac5d33),LL(0xf8082490,0x89d1486d), + LL(0xf9fe7377,0xc0c2ec19),LL(0x39415cfb,0x07911ff1),LL(0xa1c91f71,0x1b54a66d), LL(0xd4f59851,0x29646a9e),LL(0xe209ab6d,0x0a7fcf62),LL(0xfca0de15,0x6ea260fe), + LL(0x5fcc220a,0xd026ef4d),LL(0xd9364e42,0x7303fde9),LL(0xd35f5fad,0xcf2f621c), LL(0xd439a9f6,0x6e346476),LL(0xccf2de6e,0xb108eab2),LL(0x6d3db6c6,0xca46cb58), + LL(0x1de59604,0xc89fccf4),LL(0x59f8e37a,0x72ee2825),LL(0xd52aa0eb,0x9423de94), LL(0x1110f4b8,0xb6837166),LL(0x5e0ca5e7,0x00b22047),LL(0x7f72b3f8,0x79573c27), + LL(0xe67b0c29,0x6dfbc44f),LL(0x05177565,0xa0a8e62f),LL(0xbf5b1bbb,0x7f494f35), LL(0xd472f2c7,0xcc727439),LL(0x48ea2e18,0xcafc4607),LL(0xc5b2f1e5,0x25499b27), + LL(0x86c1e086,0x83fb7e04),LL(0xafbb1111,0x19eeb012),LL(0xa0c8df49,0x620d5c9f), LL(0xd8adc0b6,0x85368dc4),LL(0x0c2f7efe,0x174dcd3c),LL(0x52fe89c3,0x71d50509), + LL(0xbbeb2341,0x03ec18cc),LL(0xc49153aa,0xf386e999),LL(0xd01e004b,0x58b7a90b), LL(0x3bf5753d,0x66713f74),LL(0x23ce4a5f,0x96fa5445),LL(0xa7a2e6a6,0x06b17741), + LL(0x1fa5345b,0x93e18885),LL(0x2b10748b,0xc3faca64),LL(0xdf987dbc,0xc1b82b06), LL(0x205e25f4,0x8f3aa4d9),LL(0xb7dc364e,0x31bdcd03),LL(0xb91f4dfe,0x5a21cbcc), + LL(0xbc5b1ae6,0xc9f8dd3e),LL(0x09390a2d,0xfd14096e),LL(0xd6fbd5f0,0xcf2461e3), LL(0x02a263e4,0xaa775c22),LL(0x0fbb901d,0xc7829c8b),LL(0x1840557a,0x338e09b6), + LL(0x1c6d5d1d,0x6aa505da),LL(0x5646e930,0xf7906394),LL(0xa52fc317,0xfc0035dd), LL(0xb185221a,0x9fefcec6),LL(0x49de64e9,0x692267cc),LL(0xc316de61,0x2d105157), + LL(0xd4e3b784,0x57ac5de5),LL(0x13ab394f,0xac9c4222),LL(0x027f1648,0x5aa27972), LL(0xc83390e1,0x7a4b5ae2),LL(0xa1a47d58,0xba9ff075),LL(0x4a3d0cd8,0xf9ad2400), + LL(0xede14e49,0x70ac2786),LL(0xbdf4b5ad,0xd79e0890),LL(0x01edd96f,0x7b6dd833), LL(0x565fd682,0x1b4f533d),LL(0x474f71f9,0x9222c9a2),LL(0x83ebda25,0xa56581a9), + LL(0x25ee5573,0x7050f5eb),LL(0xdb88f4cd,0x4758c876),LL(0xc852b937,0x9abc5336), LL(0xa5b25a0b,0x88d32963),LL(0xf471412c,0x3e117bb5),LL(0x081986d4,0xf4fe7f16), + LL(0x976cf433,0x1a1189da),LL(0x7202a031,0x8d95553c),LL(0x844752a4,0x59d33ccf), LL(0xb361b89b,0x8145a133),LL(0x43423d20,0xf78e0d37),LL(0x61a44de5,0x522e94dd), + LL(0x8e540c0b,0x7c2237f8),LL(0xe30c14a2,0x89d8e57c),LL(0xbf6aa5e6,0x456a042a), LL(0xf3216fe6,0x22ab0e28),LL(0x5cb9a52f,0x54763652),LL(0x0b10595d,0x5ee60169), + LL(0x3800818b,0x06cc9e76),LL(0x7f5020ad,0x426cc669),LL(0x18577c5f,0x53ff7b9e), LL(0x30789f9e,0xbecc9a3d),LL(0xac798e8a,0x685f1d84),LL(0xcf85daa7,0x3c0745ce), + LL(0xdfd3615b,0xd516bc63),LL(0x9ad06650,0x36e8a2de),LL(0x9a930d91,0x71f2ade0), LL(0x88d6e03e,0xe237231a),LL(0x80cd199b,0x8af22a7b),LL(0x68638e0e,0x999ac96b), + LL(0x3b855f82,0x92421da5),LL(0x229553e1,0xdf39524a),LL(0x389ff1eb,0x388c4741), LL(0x49806f26,0xb73b3db2),LL(0x116a75da,0x0066ae14),LL(0x7d37c100,0x224f589b), + LL(0x4defbdd3,0xc60c22e1),LL(0x5449bd64,0x6d574468),LL(0x46ea4c3b,0xee1e887e), LL(0xc608f1e7,0x16b1d73e),LL(0x87301c1a,0x30a39cb8),LL(0x76725f2b,0x5e7728f2), + LL(0xbeda23d1,0xd3a7aed2),LL(0xaf09fa81,0x2d4adeac),LL(0xf998500d,0xcc705a59), LL(0x97b62945,0x2ec67209),LL(0x2156a3f4,0xfefbf4e8),LL(0x0a5fb347,0x20684eab), + LL(0x785d1eb6,0xeb66a59a),LL(0x82fd2480,0x98279fc5),LL(0x1a00554b,0x6b259c82), LL(0x913e2492,0xa46b9ebf),LL(0xea3691cc,0xc3524af6),LL(0x6746a57e,0x00ec234a), + LL(0x71718339,0x33a6b51e),LL(0x206c1075,0xbffbd973),LL(0x0461a56a,0xd7489944), LL(0x5ee41c8e,0xb4440567),LL(0x7b86fe5a,0x2bf38abf),LL(0x8cd45ef5,0xf70c63a1), + LL(0x845aa2a3,0x80c95a21),LL(0xd508e765,0x4882eaac),LL(0xcb5bb20c,0xc5f7b8fe), LL(0x104b3369,0x96426128),LL(0xd131d49d,0x23598393),LL(0x27af509a,0x059d6d87), + LL(0x330dc205,0xecb4bd8d),LL(0x793b3824,0x3934dce1),LL(0xf505c154,0x2b8cedbe), LL(0x7a873a69,0xba92295b),LL(0x386ee396,0x8449398b),LL(0x4717b4b5,0x72584bae), + LL(0x73765fd1,0xa18a909b),LL(0x7db9952c,0x2494a304),LL(0xe91c490d,0x2747b58d), LL(0xb6d10153,0x1178cdf0),LL(0xbf4c5889,0x35235125),LL(0x90f823d5,0xdf63fa73), + LL(0x4066c1a7,0x38748fb7),LL(0xf5cf90a5,0xfbfbb8e2),LL(0x9b83fd71,0xa828018b), LL(0xb34ce140,0x3de7f633),LL(0xd54824f7,0xd760a3e5),LL(0x94e2e012,0xea872fd7), + LL(0x479fbc3f,0xd2aa4fdf),LL(0x1979cfcb,0x11a9a799),LL(0x03e344fe,0x01733a8f), LL(0xb5b3cc49,0x0c61b034),LL(0x10c7d2cf,0x27483deb),LL(0x1884d1f1,0x6dc92d21), + LL(0xdce73a42,0xebf1943b),LL(0xa62405be,0x91a018b4),LL(0x5684989d,0x844d759b), LL(0x4678912e,0xbdc609b4),LL(0xd12582c1,0x4b151529),LL(0x7f8e1390,0x7ac0cfc4), + LL(0x987acd67,0x5245ca01),LL(0xf023cfd4,0xd4688d7c),LL(0x4b96af1c,0x799e7c06), LL(0x0a9e14c2,0xa96c4571),LL(0x2ded73d6,0xc2dc67eb),LL(0x2783e2b5,0x43588841), + LL(0xeef15ae5,0xa3b115c6),LL(0x87b86741,0xf305a27e),LL(0x4711a4a3,0xa5fdc849), LL(0x7b6ef648,0xeb58f0f1),LL(0x6f3ea084,0xdccddcbe),LL(0xa1b862a7,0x6f7470fd), + LL(0xd88e9f3d,0x141947dd),LL(0xfbb2d23f,0x1b677675),LL(0x16da518b,0x12a4c8c1), LL(0x032c0bc7,0x1cccf6b7),LL(0x20ed64ed,0x5b7cfe57),LL(0x5269cf39,0x7d427f2c), + LL(0x8d53b039,0x7faea5da),LL(0xacb5b11a,0xf19f5f61),LL(0xfe27af9c,0xfd679e18), LL(0xc0e391aa,0xbe29ec0c),LL(0x8cef3cd7,0x42a815d2),LL(0x42c2564f,0x3dd43747), + LL(0x6370d284,0xbaa0ccdf),LL(0xeb70e670,0xb68dae3c),LL(0x9917aadb,0x5e25db51), LL(0x57c8020e,0x27888369),LL(0x0cd601a7,0x4ca76fa7),LL(0x4509eeb6,0x46794e0a), + LL(0x4538b5b5,0x9f21619a),LL(0xd6754ebf,0x6c1f3f7b),LL(0xb7b2f926,0xa2a0e2e7), LL(0x42728394,0xc5747d30),LL(0x0a0328e3,0x2662cd33),LL(0x3bfbcc49,0x89c445cf), + LL(0x96bba2f7,0xce07c166),LL(0x93dfae9a,0x6828eab6),LL(0x4036abaf,0xa907dcce), LL(0x6cd5853d,0x61e23034),LL(0x331dc277,0x541d6f4e),LL(0x82796b5a,0xdaa10e8c), + LL(0xfac61d43,0x339d6949),LL(0x75b34910,0xedc8bc2f),LL(0x1ee6f866,0x4c686fe9), LL(0x5f02368e,0x9bc462bf),LL(0x638abf60,0xc3902774),LL(0xb7ed5413,0xc403b179), + LL(0x664e0b41,0x35bf0ed9),LL(0x889af4e3,0xc3ad5755),LL(0x5153a58d,0x14291828), LL(0x64798a76,0xb3d9c453),LL(0x827c237a,0x71e6ce15),LL(0x41e52b67,0xbbcce06b), + LL(0x1a05cd67,0x523df124),LL(0xf104c7c7,0x969598b8),LL(0x7f7b1fa6,0xc16d7bc1), LL(0xfb1a2aa4,0x935b18e9),LL(0x4f99ebf4,0xba7ff2a2),LL(0x862cab62,0x0613fa7b), + LL(0xd8d26e75,0x02f5cfb1),LL(0x98906c57,0x5e0d4363),LL(0x1032e39f,0xca80873c), LL(0x204c0680,0x2fa5b881),LL(0x7c178dd3,0xca227906),LL(0xdf2e321b,0xba33bb48), + LL(0xd9a13914,0x4cbde5bb),LL(0x621b5b3c,0xaa89d2d4),LL(0x75821515,0x66fd1db4), LL(0x66154f11,0x3e616070),LL(0xed85f2f5,0x2dde1732),LL(0x528e1b57,0xfa1fe78f), + LL(0x600e571d,0xb51f5c95),LL(0x15059c58,0x13f0e99e),LL(0x72e8f443,0xe2a1a34e), LL(0x2285a044,0x5c484292),LL(0x908d9855,0xac4b6bdd),LL(0x8cffdb0a,0x4b4ac5ae), + LL(0xd691153c,0xf8f74a29),LL(0xd21533bb,0xc0cb0e05),LL(0x86067d1d,0x52ceb52e), LL(0x9cd93bda,0xeb021228),LL(0xd7c98d3b,0x27d7ef30),LL(0x78fae7b9,0x7c18f1bf), + LL(0x5ef7655c,0x1b3562c7),LL(0xb552fd07,0x62ce6adb),LL(0xb9c6217d,0xac6f179d), LL(0x7fb8394e,0x3b329c45),LL(0x9b340753,0x418d2ac5),LL(0x68c5c9d3,0x5adca639), + LL(0x15b71702,0xbfd6f204),LL(0x569ed998,0x292bfd32),LL(0x003d0141,0x5b5d5b09), LL(0xefcd36d1,0xd512f4d8),LL(0x16c87812,0xc81f1c34),LL(0x1777dcaa,0xa54cef3e), + LL(0x76585d99,0x53830298),LL(0x30d1c285,0xe2d41a7b),LL(0xad60f2ff,0xb6eabff3), LL(0x3d361b12,0x073639c4),LL(0x16f921f3,0x10e605bf),LL(0x3394e5eb,0xff665c90), + LL(0x359bf1b9,0xadae33b1),LL(0x61554e45,0x183beb7e),LL(0x559e3f90,0x28d50fcb), LL(0x4bc0b8cd,0xa9a26299),LL(0xb403463a,0x25b24e6a),LL(0xf076ebd6,0x715055a6), + LL(0xd381a2e0,0xa6b7fe33),LL(0x6b248193,0xc2aacec9),LL(0xc9d6ba70,0x1f617084), LL(0xcd06c9a1,0xce945304),LL(0x1b4c3d5b,0xb957b98b),LL(0xfa6b8f04,0x50c61d1f), + LL(0xdaa47b46,0xbd69e6d9),LL(0x7a9479bb,0xc12cbd8a),LL(0xa8b92f63,0xf07cbcd9), LL(0x27d2f85e,0x4998f584),LL(0xbf43ba36,0x0ab2e076),LL(0xbad0d0a2,0xbed73de0), + LL(0xad129e1b,0x3e02902b),LL(0xa008c72c,0xd2e0bd57),LL(0x30e61c2b,0xe88a075a), LL(0x5d9402a8,0x136e1b7f),LL(0x7bc0a653,0xaa06f30f),LL(0x068e6e0b,0x51b52693), + LL(0x695404da,0x0bb86a49),LL(0xb1059de5,0x339cbbca),LL(0xdfc1bfa7,0xd45db64b), LL(0xa98831bc,0xad07e52d),LL(0x51a7a71a,0x5ef54a92),LL(0xee02c742,0x7fda785f), + LL(0x6686a65a,0x05b7848e),LL(0x6f478ff9,0xc12a7893),LL(0x2d137586,0xf1f54c31), LL(0xd50ea873,0xfe8799f4),LL(0x5fabdd98,0x62d996af),LL(0x5181afce,0xf0fe39fd), + LL(0xef010cef,0x646b35f9),LL(0x7d54d120,0xa63852dd),LL(0xadec6e34,0x3e5c14f4), LL(0xc2f4b7e6,0x030270aa),LL(0xec560a92,0xdedf4875),LL(0x9da64c53,0xd6d97f65), +}, +/* digit=5 base_pwr=2^35 */ +{ + LL(0x1386b66e,0x18754788),LL(0x9a2eb0d8,0x783dc08a),LL(0xf074e5e1,0xfe2682d1), LL(0xcbf4f5b8,0xb6ab7696),LL(0x6da5b0aa,0x382401e6),LL(0x0f93d45d,0xfd5a6375), + LL(0x6fefd17e,0x51d517b8),LL(0x18fba339,0x35e97b40),LL(0xcf221c7b,0xbdc8467c), LL(0x9eaee11c,0xba6035ff),LL(0x18128100,0xb417857d),LL(0x4f40acec,0x383235c3), + LL(0x4197bc61,0xdcfc9f38),LL(0xfe9c1104,0xeb61eb5e),LL(0x5486c84c,0x7ba40c29), LL(0x1377a769,0x2f6a8ebc),LL(0x914c369a,0xe4e70f07),LL(0x57afc5f6,0x8d954007), + LL(0x0fa7e4d2,0x56b010d6),LL(0x1d9544ef,0x91cd7d72),LL(0x48b3fb02,0xe2c51636), LL(0x683588bd,0xa2440769),LL(0x98239b52,0x7054bb40),LL(0x3bb5090c,0x2019db99), + LL(0xf043605e,0x6da23d19),LL(0x69d16792,0x4f2d4a4f),LL(0x6d5127a3,0x5061d4c8), LL(0x71c846bd,0xa0ef332c),LL(0xca929e1f,0x7948a241),LL(0x0baf2f1a,0x4152aec5), + LL(0xdc72a138,0xf15dd5cb),LL(0x91a32dbf,0x6d2d2597),LL(0xfd5852dc,0x7f46cffd), LL(0xd817364b,0xda270e8e),LL(0xa1df99e0,0x97e5e85f),LL(0x5a90c0ae,0xc77a3a0a), + LL(0x19a3eb23,0x1636651c),LL(0x12294385,0x34a5e78a),LL(0xec25d3d6,0x71cac725), LL(0xe5aa03cc,0x98956393),LL(0xf1d2e766,0xcda62f63),LL(0xf7c046ed,0xb8c8909f), + LL(0x1578b888,0xb68a6a3a),LL(0x30e1dbfd,0x01e39894),LL(0x71dafb3f,0x03ca0487), LL(0xf8241fab,0x7690a577),LL(0xe64d2bb7,0xac71ef0b),LL(0x3eae3938,0x4fd69e13), + LL(0xa2e02fc2,0x7a04ff5d),LL(0x75b01d9c,0x11114bbf),LL(0xe08f4299,0x1233f026), LL(0xf491d93a,0xd888bb1c),LL(0x07c1f414,0x7c6fc026),LL(0x97d8d7df,0x753a2913), + LL(0xea21ec86,0x0fe566b4),LL(0x75ddae93,0x743f5133),LL(0xee43927e,0x0173fdd9), LL(0x8b3a99d1,0xe9491f6e),LL(0x90e9d60e,0x6af11d34),LL(0x373fafeb,0x7ca50de3), + LL(0xb53b609f,0x3a3eaa6d),LL(0x1cf1fa53,0xcafff213),LL(0x2cc998b7,0xb64116ef), LL(0x8eac5d3a,0x63148b28),LL(0x1dc633b7,0xff5f7662),LL(0xc94b635d,0xf174dcd1), + LL(0x013644fb,0xdf0f0994),LL(0x526fa9f2,0x77369779),LL(0x4197eb1b,0x41ef1970), LL(0x22cb653d,0x7bf4bf00),LL(0xb7dd509f,0x94f0f226),LL(0xbe77682f,0x5fd7dd2b), + LL(0xf658d2b2,0x80435f56),LL(0x5f8cc779,0x1e864847),LL(0x8b56aaf0,0xdd4cb7e9), LL(0x72c3024f,0x458c8bb7),LL(0x8cffdca0,0xa5c186c5),LL(0x377f96ba,0xc0022799), + LL(0x1f7d9343,0x7e4d4404),LL(0x299cd36e,0xa496646a),LL(0x600decf3,0x06372825), LL(0x08bf05fa,0xe19b609d),LL(0x1b7e153a,0xfe6a7182),LL(0x9808f5c7,0xfe191f76), + LL(0x2a8c6b66,0x2c13eeb6),LL(0x0fcafcfc,0xcd3cc6d3),LL(0x236f08ff,0xb85a615d), LL(0x14e4e83c,0x92187d5e),LL(0x21979d04,0x5fdaaa79),LL(0xe519147a,0xed2d2008), + LL(0x02fe620c,0xd8083896),LL(0xde8984fb,0x277803e8),LL(0x7058d34c,0x2698ed9f), LL(0xbce1dcc3,0x00b9c0d3),LL(0xbc2c1c85,0x356b310e),LL(0x67cacabb,0x41e412dd), + LL(0x2790dc4a,0x396267ca),LL(0xd5bfe8c6,0x5d4593a3),LL(0x335a7f8d,0x5fddd3d4), LL(0xab0ac92c,0x92f002c0),LL(0x6226c031,0x590a93b2),LL(0xdfe775be,0xb3c10c49), + LL(0x85889144,0x0209bd99),LL(0xb9b83e2d,0x77df1ced),LL(0x4cca6a2d,0xbf9f5870), LL(0x35978ee6,0x2c4f310e),LL(0xeae8acff,0x98debae5),LL(0x778c9461,0xf2f40fc1), + LL(0x9d363814,0x4c6c9e7e),LL(0x7b9d3d53,0x52fe5e06),LL(0x9cecbe7a,0x19bd3915), LL(0x272c9325,0xcbce0a07),LL(0x6a7c9eaa,0x48336f5c),LL(0x77a17578,0xd234b427), + LL(0x3ca7e0eb,0xb22492a2),LL(0xc5a32881,0x91ba7704),LL(0x00d1425b,0x5a2a7f1e), LL(0xbc09eeae,0x6b15d61f),LL(0x86b7bff1,0x2e8f822c),LL(0x32c4dd9e,0x56357b66), + LL(0x51e3d663,0x74a1f2c6),LL(0xa42a3633,0xf42faf2f),LL(0xf6e193fb,0x1b1be8b6), LL(0x4200b0ee,0xb647f284),LL(0x02d4935e,0x0950b424),LL(0x4deee646,0xdbdd7c52), + LL(0x77c3a95a,0x15c8ddba),LL(0x6ba71f9c,0x901a11bd),LL(0x440741f5,0x54fc905b), LL(0xf1358db4,0x4b6b0fc5),LL(0x6ed93612,0x3c4c39a3),LL(0x395cb400,0xa764c9a8), + LL(0x2b54f47d,0x089cc68e),LL(0x4fa19e45,0xd6f94042),LL(0x62803448,0x52875bc1), LL(0xdf571d9b,0x1f43a201),LL(0xff9a0750,0x9e8645cd),LL(0x61a710d0,0xa177f4bb), + LL(0xddae695a,0xd55cc687),LL(0xe7471217,0x90d2c914),LL(0x917d18a0,0x884f4e6d), LL(0x744d11d9,0xd2871c7d),LL(0x02972782,0xef60b7d8),LL(0x2531f9a0,0x491aa401), + LL(0x8f0f3404,0xf881970a),LL(0xe6a7678b,0xb681fd66),LL(0x45c5eec8,0x673a8192), LL(0x216460f1,0x39e65db1),LL(0xee6d42eb,0x28cd720e),LL(0x08badd82,0xcf155154), + LL(0xf5c7d936,0x35ab0302),LL(0x7eee29e7,0x0a6d5f94),LL(0x7ed08644,0x03232350), LL(0x6d2a8356,0x505064a6),LL(0x979af3f3,0x6e9937d1),LL(0x0758cb3d,0xec148fcc), + LL(0xa047cb43,0x46a50ee9),LL(0x2c02de4c,0x6c6b569f),LL(0x3d95c934,0xcd21154d), LL(0xd55720da,0x3a14afa6),LL(0x5512e601,0x6ceee63b),LL(0x4c47b641,0xafe6bbff), + LL(0xf19e974d,0x717ac089),LL(0xf71eadf4,0xfb0cebe8),LL(0xe85c30e2,0x503535ba), LL(0x072130ee,0x05e57133),LL(0xa8037e5f,0xf33e81ed),LL(0x3f0c555a,0x4b33d96d), + LL(0xd71f6adf,0x47ff2d79),LL(0x7a985d02,0x88a9de0d),LL(0xb2dc0cc5,0xc9cc2822), LL(0xfbc2972b,0x38052b28),LL(0xbc8465ba,0xdaecc9da),LL(0x7ff5a249,0xaaffa0d1), + LL(0x60361946,0x4f326618),LL(0xae1695c7,0xe7eaffff),LL(0x1311036b,0xa7aed10b), LL(0x9eb2dfa7,0x6eb81e71),LL(0xf680fea3,0xeda95d34),LL(0x83630d7a,0xd2ab66c5), + LL(0xb891fc22,0xa7433cf1),LL(0x1111e0db,0xdbea5480),LL(0x658341c1,0x823a8595), LL(0xe2d8917b,0x7a171afa),LL(0xe713e015,0x79e4154d),LL(0x3ebc430e,0xbd07aa2c), + LL(0x0523f8b0,0x091a19d2),LL(0x0950ab93,0x9fbf9c8c),LL(0xfbb731ea,0xd8377e50), LL(0x18b26813,0xe3b8b5bd),LL(0x1bc1257d,0x78a16f16),LL(0xcfd383ea,0x837106a0), + LL(0x11c7579c,0x01e9427c),LL(0x1580ef3e,0x24504560),LL(0x0b447ba0,0xd7408db5), LL(0x0e1cfc39,0x6749f5e6),LL(0xdfe158ad,0xd26d7dbf),LL(0xe7b17909,0x66d731fa), + LL(0xea86e123,0x46d3addc),LL(0xe46c37d8,0x3b52f72b),LL(0x8036a8e6,0xda02c7ee), LL(0xfeeaba0d,0x9f141b52),LL(0x0049be34,0x7a66cbac),LL(0xb9de2e84,0xc5b5d9d0), + LL(0x6d15b711,0x190e0e24),LL(0xc7ca01a7,0x4eec20f0),LL(0x7803ca5d,0x12ff14dd), LL(0xd59fb3a4,0x84991c92),LL(0xc64b50b6,0x86a00ae1),LL(0x175bbf50,0x6bf38341), + LL(0x5310953f,0x3cd33d82),LL(0xef7027f4,0xcf3d011e),LL(0x3eee08ca,0x10779dfa), LL(0x31f432ec,0x2c3228c4),LL(0x7f319ca8,0x94c51072),LL(0x3cfe5d7c,0x2ac3a2fe), + LL(0x4acc7cc4,0xe2ccc5e9),LL(0xff58443f,0xfedc0da8),LL(0x9567fea7,0x776014d0), LL(0xa2b90e62,0xbca6d7b2),LL(0x164be21a,0x11148f7f),LL(0xfec4a5f1,0xebbdf677), + LL(0xca5a2ef0,0x4bd9a436),LL(0xfd095c81,0x320744ae),LL(0xc307a816,0x3da008cf), LL(0x2f6801e7,0xc5cc3ff9),LL(0x4407869e,0xf0ba2f46),LL(0x213338b4,0x6eed1a15), + LL(0x274dd179,0x7fa61ef4),LL(0xa631cf50,0x6e6453fd),LL(0xb86291a1,0xaf1017f5), LL(0x9cf7ace4,0x757564ec),LL(0x2535cbaa,0x0fa1ec1c),LL(0xbc9b95bd,0xc03cec64), + LL(0x7686669e,0xfbcb2d77),LL(0x6cdcb0f1,0xf9bed26f),LL(0xb5a8f081,0x37aff505), LL(0x6053e4cc,0x1f258d7c),LL(0x45bc699e,0x86384c5f),LL(0x25a2f865,0xe0025c0a), + LL(0xb24a8eb1,0xea42c8e1),LL(0xdc2dd956,0xf670d8ea),LL(0x035bfb42,0x71d4c32b), LL(0xe7824aa9,0x213fce6d),LL(0x4b22f111,0x9b34d5b0),LL(0x3a14d9cd,0xa299994c), + LL(0x7ba4a4bd,0x975d551f),LL(0x32d65fb4,0x862bc216),LL(0x151762af,0xfaaf16ad), LL(0xcd1fe1b3,0x931eac72),LL(0x00f9e6e2,0xcd730742),LL(0x85ccbcf2,0x581b13c3), + LL(0x559cb856,0x013ed0f3),LL(0xd22cf5f3,0x5c1af1b5),LL(0x3badc3ca,0x11b231ec), LL(0x68ce4eac,0xc22972b9),LL(0x1a2f55b5,0xcb92e129),LL(0x038e230a,0xa61289eb), + LL(0x309e8cec,0x625ac394),LL(0x49b13bac,0x99dab1a7),LL(0xdf48a436,0x77940cbf), LL(0x78881636,0x963cb651),LL(0x7541e4c5,0x889ac28e),LL(0x5407fbf2,0x39918bd5), + LL(0x69209c9c,0x63d26894),LL(0x255dc3aa,0xb6b122cb),LL(0x932b582c,0x12866e42), LL(0xc373f8ad,0x0b0a7dd0),LL(0x1fe0f36b,0x2fed9f9a),LL(0x2345d1f2,0x6dbbf47f), + LL(0xdefc4c20,0xdf69b818),LL(0x2e3eb2cb,0xf31ff9a8),LL(0x0be0bfa6,0x946578a6), LL(0xe8b31f47,0xbecddbf2),LL(0xa45fadaa,0x86e3594c),LL(0x999c547a,0x56d2d2e3), + LL(0x3b5a1df0,0xcfe909ee),LL(0x94fd4014,0x4b62c64a),LL(0x258a8f81,0x7d6e3ae9), LL(0x5804ee7d,0xfc15381b),LL(0x71710702,0x3b444911),LL(0x5f18965e,0x46497ae3), + LL(0x33dd9555,0xfbb99cfe),LL(0xfcbeecde,0xc6e14198),LL(0x51da2e20,0x8d4e83b3), LL(0x75a0719b,0x2bc54a6b),LL(0x56b03328,0x1aba20d3),LL(0xede40907,0xd84a7db6), + LL(0xeae9291d,0x6f52a996),LL(0x33d0f1a3,0x507c3701),LL(0xafebeab2,0xb7809c3c), LL(0x80b978c3,0x301a5ed5),LL(0xd10f0edd,0x1ba9c42c),LL(0x150d6504,0x0e9f9f93), + LL(0xee90dfeb,0x56ff221e),LL(0xc6815c60,0x279a7940),LL(0x1b0208a3,0xa119572a), LL(0xd2710835,0x5bb04e27),LL(0x67414bf2,0x61d8d945),LL(0x6aec6a5c,0x440a1d39), + LL(0x1ecc000e,0x07e60a25),LL(0xe6efdc85,0x2325aab6),LL(0xf4872ceb,0x29438ae3), LL(0xe8d10241,0xeea2a3f2),LL(0x548a7556,0xd2ff366b),LL(0x2a6e27bf,0x85e8ada2), + LL(0x11a6e295,0xb10332e7),LL(0x609a424a,0x44c9ba0e),LL(0x986e93f0,0x08f222e9), LL(0x9dcb7c9b,0xeb8bea94),LL(0x1d5aa8a0,0x36e44e93),LL(0xa3e0dccc,0xe0deccc6), + LL(0xc22e314b,0x92be41b1),LL(0xaabbe524,0x388494bc),LL(0xbde2517d,0xaaf52dfe), LL(0x186fedfc,0x4ce61d88),LL(0x300b7bc2,0x9f29e844),LL(0xedab8ca6,0x03a2221d), + LL(0xda0cae4d,0x7c3f687b),LL(0xe7da757e,0x84dc6167),LL(0x85d25286,0xc0c08f69), LL(0xb4889367,0x17f7921d),LL(0xf81fddec,0x223c9181),LL(0xa6a05bf7,0x3b72e938), + LL(0x60326fa4,0x0ff61ea1),LL(0x97c51293,0xa54cc228),LL(0xf976ab17,0x7d25531f), LL(0xa8f84662,0x1e8c3f37),LL(0x007ac2f1,0x4d8c3063),LL(0x4598d053,0x80c8de31), + LL(0xe4198b95,0x3ed83a96),LL(0x90ef6fa9,0x4435dc6a),LL(0x9ab2a2d6,0x47791ebf), LL(0x1564b80a,0x3e0c8b07),LL(0xa0ec1ad9,0xb4079d88),LL(0xee9bfef8,0x6fc566af), + LL(0x7f1a5c21,0xbfc3ee41),LL(0x2727a00a,0xe3694ec6),LL(0xa4087b70,0x3ff4d181), LL(0x37de763e,0xda656043),LL(0x8a50ec66,0xc2da4f75),LL(0xb94a5c19,0x096c88ff), + LL(0x3121ec7a,0x05e200b8),LL(0xf23f234f,0xc5f282e5),LL(0x94aebbc2,0x0d95e5bc), LL(0x6922306e,0x389ff8bd),LL(0x0c458f95,0x949a4362),LL(0xa8a67759,0x2ed544e9), + LL(0xd643944f,0x46d3e81e),LL(0xa5cfb8de,0x36211db8),LL(0x95b4f959,0x8a5ee9eb), LL(0xcd19ebcd,0xc3d6941b),LL(0x61306b29,0x4bc41c81),LL(0xeac1ab81,0x0093af39), + LL(0xe6622883,0x301a7d6e),LL(0x270ac148,0x5c49e719),LL(0x4bbec99b,0xff3296f0), LL(0x80061376,0x880c775d),LL(0x322403c9,0x587357fe),LL(0xc24a4307,0x4db2f9fb), + LL(0x76f5e74e,0x3a8b93a4),LL(0xaa1b2dd8,0x5e9e5474),LL(0x5ad377ae,0x43c84363), LL(0x8b7ef6de,0x3ef3ceea),LL(0x7be9f363,0xa3457c60),LL(0x6c4f30eb,0x8a0c2c94), + LL(0x3eef5158,0xc50fa97a),LL(0x86d6a054,0x52c0d8a2),LL(0x3be5c327,0xebdf472b), LL(0x0852c07e,0xc34b020b),LL(0x42fa2f1c,0x5b2b3552),LL(0x3a4f7817,0xbff68be9), + LL(0x959b0d24,0x2cf2220a),LL(0x56dd4a59,0xeb164f48),LL(0x9d8fff97,0xd9927903), LL(0x233eaa77,0x0ddf5e1b),LL(0x7969f9e5,0xf32d29d8),LL(0x5562cc50,0x26ee53ae), + LL(0xf53c8cf7,0xcbc8f03f),LL(0xc7ff11a2,0xb6321218),LL(0xb9346795,0xb37d632a), LL(0xaf7e83a5,0xbc24e219),LL(0xe6dbd3da,0x95b4863a),LL(0xcfb3f25e,0xc3f00af4), +}, +/* digit=6 base_pwr=2^42 */ +{ + LL(0x097b6df3,0x807a7671),LL(0x0fb780e0,0x41faf5e2),LL(0x157c3ef1,0xdaa12450), LL(0xd7cb0c23,0x31d72356),LL(0xb251a877,0xd5d2c185),LL(0x92fa894a,0xdbdaee99), + LL(0x98704ce6,0x85e18802),LL(0x306d7501,0x25a349dc),LL(0x03de69b2,0x6c5ba821), LL(0xc403903d,0x9fd2d533),LL(0xbf5698ac,0xe3b96ca6),LL(0xcc20c102,0x7d5e41c1), + LL(0xcc888fdc,0x6d434dd0),LL(0xed221a04,0x47e731b4),LL(0xa107a3c9,0xda0d85b5), LL(0xebf163d0,0x489780a7),LL(0x9892bf9b,0x1ddd62aa),LL(0x04e0db7d,0x7f988bcb), + LL(0xe492a9fc,0xb55c1496),LL(0x597a9eb3,0xd0cd80f2),LL(0x9f1d8391,0xeaf34b51), LL(0x785286c4,0x81e7ca50),LL(0x6c0c5297,0x5b63c071),LL(0xb1b52561,0xa09ca533), + LL(0x19fafaf2,0x082de97f),LL(0x25cc03ed,0x92de16ec),LL(0x0fabb7cf,0x415b7e1c), LL(0x721659a0,0xb121761c),LL(0x4a3f2f1d,0x2c646d3f),LL(0x13cef73d,0x6c441f7c), + LL(0x26cc7cca,0x7d4281a3),LL(0xe302e412,0xf9d8fdf7),LL(0xed1531b3,0x9b29a767), LL(0x8daae632,0x9713865b),LL(0x51561f0a,0x5c4d8193),LL(0x74daf2a8,0x786d917a), + LL(0x08c24f78,0xf4b82a3f),LL(0xe3565350,0x82c57c65),LL(0xc56bf74b,0x92213214), LL(0x066173e2,0x51cf2f2a),LL(0x22931b9e,0xb67e7f28),LL(0x0e448ae2,0x87983d74), + LL(0xcd93498b,0xa08d39d8),LL(0x81fb94c6,0x98c24fae),LL(0xe2ec50b6,0x2c1f6da0), LL(0x703366fa,0x96b60285),LL(0x6ce66461,0xa46d2ed9),LL(0xc7bef52c,0xaf14665e), + LL(0x614dfb0d,0x03487de0),LL(0x950342d5,0xae8d0e16),LL(0x77195a73,0x4f2ab2f7), LL(0x9757d4ae,0x0cfdcfec),LL(0xe42519f0,0x20cca44c),LL(0x4b2eb661,0x3a973637), + LL(0xf0c80fdb,0x5ed30224),LL(0x9d39980f,0xb74201d0),LL(0xc2a6b759,0x705dd1b2), LL(0x080941d1,0xd6535dc8),LL(0xd279a85b,0x0d532b08),LL(0xa6c95800,0x55279407), + LL(0xed2f99c0,0xa5e5dccd),LL(0x26335c8f,0x1d51b65a),LL(0x08067e36,0x930c04c4), LL(0x0583c23c,0xb14d764c),LL(0xe5be4e67,0xe9f1f8b8),LL(0xd3b9a111,0x2b684b5a), + LL(0xce971c7a,0x9420fabb),LL(0xc95e25ab,0x3ade0eab),LL(0xa490d8c4,0x350f2e80), LL(0x3f6eb3a6,0xa76804d4),LL(0xe63fd72e,0xd2ce7028),LL(0x85be7c39,0xb27222e2), + LL(0xfccf002e,0xe372c921),LL(0x514dc3ea,0x96a39294),LL(0xdad77509,0x4e6aeb46), LL(0xd37b54ed,0x9a5799a8),LL(0xfc0e43fe,0x64a87cee),LL(0x753b6b4a,0x7f05b1aa), + LL(0x549af75f,0x807a2862),LL(0xd359bf07,0x1c8b5f7e),LL(0x95d01de7,0xf52d3291), LL(0x5ffe6146,0x7a461465),LL(0xe83b1659,0x224a8202),LL(0x470e8470,0x01236b76), + LL(0x61865ca5,0x6208d875),LL(0x9571dfd5,0xa1a42854),LL(0x2d2d7940,0x6d5edb28), LL(0x6ff2b93c,0x8af66e50),LL(0x1baad60c,0xb6eb8e7d),LL(0x4a16a63e,0xbe114d2c), + LL(0x388a91ae,0xbb783662),LL(0xc9cc2382,0x34e00a1b),LL(0x2aa28a74,0x66d0d031), LL(0x6fbf826c,0x5c0cc1a7),LL(0xc1ac7477,0x78033af5),LL(0x9a21f372,0x1d7e2839), + LL(0x5af2db66,0x036516b8),LL(0xab38cfc3,0xd3fec155),LL(0x416d0d54,0xa6e7d1b4), LL(0xb397c8ca,0x9d762998),LL(0x4467324b,0x73e4c3a2),LL(0xbf7ada2d,0x9f7dd282), + LL(0xc9c10ad9,0x3f452c2a),LL(0xb2609a4d,0x7a827181),LL(0xe31734f3,0xfb87d393), LL(0x2bbf4efe,0xdafffdda),LL(0x9837686b,0x53193aba),LL(0xd61a044e,0x17401c18), + LL(0xf7fe6834,0x8561d6d5),LL(0x040422c5,0x20eee370),LL(0xc924342e,0xa16cd1c2), LL(0x0aba73e6,0xc017dbd6),LL(0x9e7b1683,0x209b1479),LL(0xf14b41af,0x4a639bbb), + LL(0x0be4ccf0,0x59308c11),LL(0x49cc5fa5,0xa69616fd),LL(0x35696487,0xed6dfed1), LL(0x1657ce60,0xdef27e77),LL(0xab4a8d76,0x346c3382),LL(0x98a008a6,0x54c10f0e), + LL(0x9d792671,0xbda7a3ff),LL(0xae4fafb1,0xab2ba801),LL(0x79f9c043,0xe27406e3), LL(0x14bcd570,0xefff1790),LL(0x80a00e1c,0xae57b991),LL(0x7b38c603,0x63b01e35), + LL(0x388ceb24,0x7f1b2eef),LL(0xadc25ce7,0xbf81721a),LL(0x6ae36f35,0x1fd0c684), LL(0xfa611602,0xdae9c8db),LL(0x3f40a562,0x9d7b2264),LL(0x9e4cec86,0x64de9a7e), + LL(0x396229d2,0x413e342b),LL(0x0afa76eb,0x97291d8c),LL(0x790ad9ca,0x18f63384), LL(0x307ad8f6,0x90deccfd),LL(0xcc49b61a,0xefb21d4b),LL(0x3d724666,0xcda971d5), + LL(0xb10df2cb,0xe1a0e3dc),LL(0xe9334feb,0xe5509cd4),LL(0x38f21828,0x4dae1419), LL(0xe9309400,0x932c62f1),LL(0x289fd6f2,0x14acca95),LL(0x4e1325f1,0x92934423), + LL(0x0edb12da,0xbc9bd40a),LL(0x3cd6bd8d,0x78f3256c),LL(0x644bdf08,0xb8fe8191), LL(0x314f2c73,0x3ba94523),LL(0xf3d8e905,0x33ddf165),LL(0xdd9721f4,0x603ecb74), + LL(0x04e15cb9,0xa1a8d802),LL(0xe4eef1ba,0xb3bf09c2),LL(0xf7ea8116,0xfcaecf4f), LL(0xe68eb8dd,0x72f4dc39),LL(0x761271cf,0xeab7abaa),LL(0x51b8259a,0xfe99e9d8), + LL(0x625f396b,0x6325bcfc),LL(0x7ad03440,0x36560d57),LL(0xaa639416,0x76246bab), LL(0x8fd064b6,0x381de8c9),LL(0x95537e9e,0xe4c3f8ac),LL(0x6e56f0e3,0x0dd1b6fa), + LL(0xf065498d,0x96a10f94),LL(0x0038c2dc,0xf88a1867),LL(0xc58b18bc,0x0de21830), LL(0x9a5da75f,0xc86e1dd4),LL(0xb092c397,0x05e00843),LL(0x3154c419,0x2839c7bd), + LL(0x18ef22bc,0xf6457fe0),LL(0x1df42e96,0xbb096001),LL(0xdef286c9,0x1a337c91), LL(0x4580b8e7,0xd4bb225d),LL(0xa2ce3586,0x6bba9b93),LL(0xf2d150c2,0x9d51106c), + LL(0x943953ef,0x0a3f8284),LL(0xe9c8b50e,0xa6f7e5d6),LL(0x1bfa459d,0xe75546eb), LL(0x34529d4a,0x3846abb5),LL(0xe1da3b07,0xbbbd1f98),LL(0xfc1e8935,0x05a92469), + LL(0x6e52f511,0x3edb02c2),LL(0xe6cea9d0,0x0306e54f),LL(0x5fe7cc33,0x1944a8aa), LL(0x53fd6127,0x3da98252),LL(0xce628fe6,0x9d5fa436),LL(0xb3f9ba33,0xe7ccb20b), + LL(0x2b5eabc9,0x22d21323),LL(0x8ddb58d2,0xfa85732a),LL(0xc0a4b7a7,0xf80ab9d0), LL(0xefe1b0aa,0xe505f00a),LL(0xd93f46b0,0x1388c1d5),LL(0x94416a57,0xf44495f8), + LL(0xd1b9d175,0x3e5e07cd),LL(0x28229715,0x713fb4a2),LL(0x750b4e8c,0x6a1dc0df), LL(0xb1837ba8,0x2b9fe39c),LL(0x8a4e51e1,0xad0b8e77),LL(0xed0e4aae,0x823a02e0), + LL(0x5f16b838,0x8a9de11c),LL(0x95820340,0xfda67f12),LL(0xe5b3813a,0xaf424ffa), LL(0x1961cfba,0x8eccd1ab),LL(0xf3022e67,0xacea8ccc),LL(0x1522dd90,0x799ce2cb), + LL(0x85c6d5b4,0xad3a9564),LL(0x11a4286d,0xbf57a898),LL(0x86df6b27,0xeb453d87), LL(0x4baef190,0x676b9e41),LL(0xa947a521,0xf94b92ee),LL(0x71257aaf,0xdc1c303e), + LL(0xe1f3b4df,0x84384afe),LL(0xc6f889c1,0xb9f7ae71),LL(0x0dc943bb,0x2f227f6c), LL(0x994e3369,0xd7a6ccfd),LL(0x4042431f,0xf4480749),LL(0x54ff110a,0x4abda3ff), + LL(0x9882e341,0xd50de25e),LL(0xed0228e4,0x7e68284a),LL(0x794de327,0xcb751d4a), LL(0x99ac62a1,0xb3cb0de3),LL(0x0001de50,0x870815cf),LL(0x82c9f5fd,0x7957d4ee), + LL(0xbda3fcde,0x8760035a),LL(0x5734a5bc,0xf131439d),LL(0x1de171b9,0xbef8fa6e), LL(0xb076e2ab,0x35d32607),LL(0x8bfa83eb,0xb132de84),LL(0x1b272008,0x7ca46b88), + LL(0x4437ac91,0xbc0e5b55),LL(0x7381e979,0xd7cb1a53),LL(0xd154616b,0x906abe2a), LL(0x4c1b6f06,0xebc02151),LL(0xf2e0afa1,0x6ede04a9),LL(0xa50c46b3,0x7f666548), + LL(0x4abfde1a,0xda143ed3),LL(0x5fb5c163,0x968f5f5c),LL(0xc56b0f29,0xe9641696), LL(0x40766adb,0xcaade44d),LL(0x41a6905e,0xfac69f2b),LL(0x96dd9b54,0x8a2a6278), + LL(0xead8c9c2,0x3a498bf3),LL(0x38527bb3,0x3f5fdc4f),LL(0x5a898416,0x78259bc3), LL(0xd2bc2a01,0xd7f94979),LL(0x058e4b40,0xb28701a4),LL(0xddf1c2fa,0x9908452f), + LL(0xd85e5adf,0x30be2fcb),LL(0x492081e6,0x740f18cf),LL(0xd2f40d30,0x4d4090f9), LL(0xf3be491b,0x3770d2ac),LL(0xd47a45ef,0xad71d7b8),LL(0x85b820f4,0x0b2cd763), + LL(0xa83085f6,0x1d1f6f65),LL(0xf7b897d7,0x4643738e),LL(0x209fede2,0xa9ae5e94), LL(0x929a2b44,0xf63bafe4),LL(0xef7d17e3,0xeb605e21),LL(0x526ff05c,0xa858b5cb), + LL(0x3d3a82b9,0xd365dd2e),LL(0xcc2cfd70,0xfeccda5c),LL(0x344ed0f5,0x36ffafe6), LL(0x04ae99a2,0x934a88f7),LL(0xc20491ef,0x0af5b488),LL(0x7a66a1c8,0xcda2acb7), + LL(0xdd5e1098,0x2b25a1ea),LL(0x909058c4,0x345012e3),LL(0xb5670aae,0x965a49e2), LL(0x1766fa93,0xc31d4480),LL(0xd3941b2a,0xd6f8bac6),LL(0x6eb3985e,0x46cd2776), + LL(0xbf004633,0x4c45b908),LL(0xdec0c1bf,0xe6b9457e),LL(0x78c0aa4f,0x2c6f62d8), LL(0xf80fdbd0,0x32bd6508),LL(0x97f86a7a,0xaa4f54c5),LL(0x2eee225e,0xc3186238), + LL(0xca5d7fb0,0xc11da036),LL(0x79e6d224,0x2bc98024),LL(0x779b9f68,0xed3b8e2b), LL(0x2c18b348,0xac7614f9),LL(0x36c756d6,0xc2072c63),LL(0x35e4340e,0xa6c5e629), + LL(0x8d338dff,0x09c64919),LL(0x8d7f5e34,0x347f9f9d),LL(0x8044621a,0xd3012dad), LL(0x27327013,0x4520210b),LL(0xe20f7a66,0x9f76824c),LL(0x7b70408e,0xa136be56), + LL(0x455a2af9,0x4b1f9940),LL(0x48945af9,0x1385b4c9),LL(0xac68fc09,0x3da47592), LL(0x5f05a04d,0x533995d0),LL(0xd7c5146e,0xc20d45f0),LL(0x22d2ae20,0x351ffb64), + LL(0x7ab5d0f9,0xb5eb2af1),LL(0x7762a3a5,0xc5cc2409),LL(0x6b374f6a,0xc65f2281), LL(0x0f46e6ce,0x440d2fe0),LL(0xb868814b,0xde15331e),LL(0xee22f041,0xd1d2f6c0), + LL(0xee1b9004,0x9ff4734b),LL(0x2e67a085,0x062dc3a3),LL(0xde8f3162,0xb7ea5b38), LL(0x824c31e7,0x19ce04cd),LL(0xbc61fd9e,0x4252601c),LL(0xf45482d3,0x95c7e121), + LL(0x31057137,0xde58e0a9),LL(0x0cac0d1b,0x30c96d91),LL(0x9104641a,0x0daab9d7), LL(0x1fd0668e,0x9ea156fc),LL(0x977683f4,0x0f6b404b),LL(0xa30e9a24,0x7966c84d), + LL(0xbff9caf0,0xe79728e1),LL(0x90e27f5d,0x82d66ec6),LL(0xbc650306,0x5ea57c74), LL(0xb2a82b96,0xcbe5e4ba),LL(0xfdfca395,0x24199d5f),LL(0x06991511,0x0ccbd94e), + LL(0x7876e2ff,0x4c91e7e0),LL(0x5d650fe2,0xba74af49),LL(0x5c7b9759,0x6f6df70a), LL(0xed511d0e,0xa5be2df5),LL(0x0c9af38f,0x0f540f6d),LL(0xb785f2e4,0x646f1fef), + LL(0xcb1eb7ef,0xf07cd946),LL(0xdd475a7a,0x41582424),LL(0xeccd0cd0,0xecabb646), LL(0x20672fdc,0xb08c9043),LL(0xd4fabfa8,0x0a0e852e),LL(0x08465cac,0x2df86c08), + LL(0xaddeb802,0x4a9d718e),LL(0x19257426,0x442b8a24),LL(0xf292c043,0xe1bf4df6), LL(0xf420119a,0xd846f55a),LL(0xb81b55b6,0x883b5be3),LL(0x7fa04e04,0xd233b497), + LL(0xb25f824c,0xa72a9e9b),LL(0x148d4350,0xcd9fa1a4),LL(0xe649b6b6,0xfe7be423), LL(0x1f055a16,0x54ff5456),LL(0x99348b7f,0xc73dc1b8),LL(0xb58ae286,0x072f9ae0), + LL(0xa2f354be,0x17fbb428),LL(0x8e54a9f4,0xf07c8cc9),LL(0x26d6dff2,0xc5dce60a), LL(0xfb7068ab,0x73ba83b1),LL(0xd6ccfb08,0x7f786cdc),LL(0x298a0fd6,0x57ea8ba3), + LL(0x6c93cbfc,0xb4637d1a),LL(0xbdb72d64,0x3b43839c),LL(0xa8ecb34f,0x80874787), LL(0xd5e642b2,0x57d9b566),LL(0x7a9c42a5,0x923772c0),LL(0xff8b1b47,0x24629516), + LL(0x07ceeae9,0x120c441a),LL(0x07740927,0xe82c0626),LL(0x91dda975,0x82b56342), LL(0xe8904b5f,0x5ccadd6d),LL(0x72da2998,0x55dc6fed),LL(0x5595c1fd,0xa6d506c2), + LL(0xeab8eea0,0x1a6a3b0f),LL(0xcafabd92,0xdf46f04a),LL(0x297dbb29,0xc5e2814d), LL(0x71d1e312,0x39d8e04c),LL(0x265b4075,0xc7017a13),LL(0xf78fbd26,0x4c21493b), + LL(0x0b9f158c,0x5c28c603),LL(0x9a07acaf,0x33de6098),LL(0x0e9c4c73,0x7b77cebd), LL(0x498db066,0x62e1c44c),LL(0xe28af701,0x57f684b7),LL(0x1f8b8dfd,0xac841f0c), + LL(0x6bc2d75f,0x9ca86d3a),LL(0xe7876500,0xab63e1ca),LL(0x436712c4,0xab42a0ee), LL(0x1d001327,0x8aead0f1),LL(0xf0a70715,0xf563e655),LL(0x6f079f79,0x58f26dd9), + LL(0x2922bad4,0x2b795683),LL(0x83b5370a,0x16a63631),LL(0x2638ee32,0x530fec6c), LL(0x44d0b441,0x23b918a6),LL(0x4b00c9b9,0xf1ebe8e2),LL(0x5e410b3b,0x77681a00), +}, +/* digit=7 base_pwr=2^49 */ +{ + LL(0x1db6b479,0x22b1c723),LL(0x39e84714,0xd62f06f1),LL(0xe23256f7,0xdee9ec7e), LL(0x95968194,0xe889db11),LL(0xa9e6d7d7,0x11d66cd0),LL(0x62416021,0x09b2418b), + LL(0x6adf5658,0x0be70575),LL(0x73b1138c,0x17f6b55a),LL(0x2a9fc1a8,0xce3bcb88), LL(0x01211935,0x4edfa8ef),LL(0x9b82e1b6,0x8972dc1c),LL(0x3e9d7b44,0x84866f69), + LL(0xcee3c64a,0x3f2da340),LL(0xf63dc83e,0xfcedb4bf),LL(0x56ff2a25,0xdedd2aac), LL(0x250762ff,0x9b5af4ff),LL(0xcbf6e216,0xd67cbdc0),LL(0xae6521ed,0x1b147e2c), + LL(0xcfcb0905,0x5315d6ee),LL(0x1a685aaa,0x269200d9),LL(0xc1f724bd,0x96f1c3a3), LL(0x3025b425,0x3a231812),LL(0x39d51119,0xff7672e6),LL(0x85a58c8f,0x1280679d), + LL(0x1ee4c1e9,0xe004f1c3),LL(0x6695e2c7,0x51f5f62b),LL(0xad1a015a,0x4c8db9dd), LL(0x0175ea4c,0x141a6846),LL(0xdb97814c,0xf8e3d91e),LL(0xf678fa80,0xdb30a211), + LL(0x0a4bf8e8,0x6e08e548),LL(0x95d4a1f9,0xd1e1533e),LL(0x74eb6623,0x01c6b2d2), LL(0x584b99ba,0x9e3dcf2f),LL(0x44a872c9,0x1211df9b),LL(0x13cf855a,0x44d0a919), + LL(0x7a71a32a,0x689a8dc1),LL(0x0969c604,0x6862a375),LL(0xbe398e22,0xd324e9b9), LL(0xfe84fe60,0x2175c004),LL(0xa817cdb4,0xa607ef1f),LL(0x721cb883,0xcd9d9495), + LL(0x3a36ef0d,0x4f8ebef8),LL(0xf4ef55c3,0x5c910c5a),LL(0x2a959873,0x8ce26809), LL(0x376d6a96,0xc2132558),LL(0x026083f4,0xa6c1cfb2),LL(0x0d455653,0x46c5dbd9), + LL(0x8ba48c45,0x48969551),LL(0xc643319e,0xba14588e),LL(0x6164409f,0x79cc5f79), LL(0x7cd52144,0xbbcfa5ac),LL(0x01be08de,0x291192cf),LL(0x1b5535ee,0xe09fcd9b), + LL(0x8b222a3d,0x4e761342),LL(0x9ee6a22d,0x874f88e9),LL(0xdbb503a4,0xfb29bb24), LL(0x27a88472,0x1e5923d8),LL(0x27cc978b,0x968ac6a8),LL(0xb31d7b22,0x8cd1a928), + LL(0x0643e7f0,0xc14f22a2),LL(0x97a5e590,0xa920ca01),LL(0x2c3fef97,0x4e4e7c4b), LL(0x8e7baa94,0x0200b159),LL(0x16b1757c,0x24b9c68b),LL(0x6ca9d309,0x51ff6499), + LL(0x96b7c630,0x7b132fca),LL(0x63d2264b,0x8df911e7),LL(0x164dbc12,0xff71dd08), LL(0xcd036c72,0x2f7b92af),LL(0x24d891cc,0xf1336105),LL(0x66b47dc3,0xe614aee7), + LL(0x12ead645,0x1c53214c),LL(0x3c7f65a7,0x32aa24b9),LL(0x118a5225,0xfd7b67e9), LL(0xdad33487,0xf58a2515),LL(0x3a563a0b,0xa9ce4387),LL(0xd92455a8,0xad5dc427), + LL(0xaca6b802,0xfa852455),LL(0x26bfb5b4,0x448d6d2d),LL(0x0accc4e4,0xa76981e9), LL(0xfbedc1b3,0x2c43f05a),LL(0xdfa0cdbc,0x684e84d3),LL(0xb07a9af9,0x60fa3028), + LL(0x46cbf3c2,0x55adc2d2),LL(0x0ab9aba5,0x5ddaea63),LL(0xf06d91eb,0x457318d3), LL(0x3face92b,0x210c0bda),LL(0xc8cca904,0xcb6be0b9),LL(0xac932c9e,0xcc059269), + LL(0x3b076836,0x35440607),LL(0xcfbc594d,0x6e139ab7),LL(0x0f818173,0x24c24eb1), LL(0x4c3d9a9f,0x26b87e2a),LL(0x1fcc4242,0x03671da7),LL(0x643cbca5,0xd08f6b5e), + LL(0x69cce513,0x3b1962bf),LL(0xbbceb26d,0xe0091d0c),LL(0xf374c0a2,0xda304365), LL(0xa099ddf8,0x27a29bfc),LL(0x969c677a,0x5f53ba53),LL(0xf0627255,0x77b8d2a7), + LL(0x3819f9dd,0x221375dd),LL(0xe08b0ca2,0x04a971e7),LL(0xd46c54ac,0x5f7345a7), LL(0x93d0f966,0x8f01f13d),LL(0x6ef17236,0xf5cf276c),LL(0x0dd038f0,0xca0bba4c), + LL(0x525bd2b0,0x86ab6164),LL(0xa0a0d81f,0x0fddac9e),LL(0xe3827450,0xc5322927), LL(0x7081e340,0x5965a1a9),LL(0x427b0701,0x46c3aef7),LL(0x6692b94a,0x98a9fa7c), + LL(0xa495e99e,0xd2932e7f),LL(0xd82f6584,0xdeb528fd),LL(0xbe305394,0x93b3c1c1), LL(0x7d8622a3,0xa4cb19b6),LL(0xb6d5eb26,0x7b46a163),LL(0x9239f879,0x247e327b), + LL(0x57a9df34,0xa102051f),LL(0x1aaf0cff,0xe1fbc51e),LL(0x9fd0f53a,0xe533029e), LL(0x75a0f971,0xda45f13c),LL(0xfe0d2922,0xadee768d),LL(0xfc9bca7d,0xdcf7b7bb), + LL(0x39f2a51e,0xa84b4adc),LL(0xa4c4231a,0x9c257e5f),LL(0xe6835319,0x5dd04181), LL(0x276cf633,0xb2ea7ce6),LL(0xd0c18fe5,0xf245702e),LL(0xb338e5a9,0x994cccff), + LL(0x33e5c5c0,0x6ba4e93a),LL(0x258e8029,0xa7b7d1f8),LL(0xad202aff,0x304ea934), LL(0x54bb2c25,0x7b28d6b0),LL(0x50b1a4e9,0x624bdf85),LL(0x7ddc1ccd,0x2c1079d6), + LL(0x7bc06924,0xd757678b),LL(0x4a9230a8,0x761f6494),LL(0xa38af7ae,0x4a74e816), LL(0x55556207,0x5cb7e1ad),LL(0xf5417b00,0x51a88664),LL(0x78c7935e,0x48886cf1), + LL(0xc5ae666d,0x112a047b),LL(0xe0d72464,0xe3e8915c),LL(0x88f740ce,0x18fd8fe6), LL(0x67d49be0,0xa5843ed0),LL(0x91b85641,0x44616e3f),LL(0x40e3c66c,0xfc394c04), + LL(0xce689251,0x4d6ed19e),LL(0xf28dfceb,0x81078128),LL(0xc82c2dd5,0x71bade6c), LL(0xc7bf5e3a,0x20cfbae4),LL(0xd1983380,0x0d1c23fb),LL(0xfb5cb3bc,0xd56434b8), + LL(0x496c7720,0xdbdd0273),LL(0xd7c99031,0x20b010b3),LL(0x06d61176,0xf5ff610c), LL(0xd3631b15,0xa0b6ea34),LL(0xe950e355,0x1528b1e0),LL(0xf0c84a6d,0x6e27fab8), + LL(0xf55bab95,0x8e66ed20),LL(0xbc6b300a,0x63e73fb5),LL(0xab652058,0x753ebe56), LL(0x46319ffa,0x0d97e216),LL(0xfbb99b70,0xf605457b),LL(0x8829b2aa,0x03a28a89), + LL(0x0073b797,0x3eac149e),LL(0x9bfeb2fd,0x95792d96),LL(0x7dc85ebc,0x0ccf0041), LL(0xecc61042,0x449bf3dc),LL(0x986664d6,0xaa4fce55),LL(0xa8c146ef,0xbc5ee8ae), + LL(0x1ff1dcbf,0xd904f9b2),LL(0x5d8a1197,0x35a18d0d),LL(0x6e3d4745,0x3341db2d), LL(0x4b050939,0x6b1eec19),LL(0xd70a0a15,0x9c1fe3f4),LL(0xcdfdd83e,0x654fc4dd), + LL(0xe9ba38d1,0x4ebcf740),LL(0x7de3b4a7,0xb42141e4),LL(0x58b093ca,0x09454a65), LL(0xa475ef3c,0xa87bd8d2),LL(0xcd2de97b,0xa1e89c23),LL(0xcb134c1e,0xe3000fa9), + LL(0xe03d89fc,0x56e13148),LL(0x560317fc,0x737b874d),LL(0xaee37ff7,0x28ce8556), LL(0x600002bd,0x21a8f876),LL(0xd20a7373,0x11a46449),LL(0x849772fb,0x280be2ee), + LL(0x44d8341d,0x81aa4216),LL(0xcfc93e1e,0x413bbc51),LL(0x5cbb96ed,0xc61e7fbd), LL(0x348b93bf,0x183ffd78),LL(0x1a6cac3d,0xbc237f9a),LL(0x075f2c01,0xcbe09c38), + LL(0x05a97f5f,0x337c5514),LL(0xf04dfeee,0xc2e77233),LL(0x5bb4ca71,0x400f4852), LL(0x8553221b,0x9626c894),LL(0xb57b0765,0x11aa8bb3),LL(0xa12d3f73,0x543ce8fa), + LL(0x8faba6a0,0xf77adb46),LL(0x435376cf,0x1174ee49),LL(0xedd2bd00,0x19430a06), LL(0xe4cbbaef,0xbfdb0a6f),LL(0xfe5c89b0,0x3b520354),LL(0xbb7ab998,0x8acd5ed9), + LL(0x28bc63d9,0x4358e216),LL(0x6d84054f,0x1d99f606),LL(0x923248e3,0x8e24aa2e), LL(0x2d2082d7,0x004093da),LL(0x0c19a153,0x180e72ac),LL(0xa4539eb7,0xb4d8b7b3), + LL(0xab583068,0x850a27b8),LL(0xeacb954e,0x85790f5d),LL(0x533b4d63,0x49567edd), LL(0x2c83d758,0xeedc0e79),LL(0xfcced827,0xe007c1d7),LL(0x2000bb00,0x68232c77), + LL(0x2ab39a53,0xdce3a7d4),LL(0xe408976d,0x5401ad0e),LL(0xb9ffd974,0xfcd5a5e8), LL(0x06214587,0x6adae145),LL(0x3b0e57df,0x15d783fc),LL(0x35f73e2f,0x8d4a1061), + LL(0xb2e9c8be,0xf6b94404),LL(0xe122287a,0x57269f9d),LL(0x7f0b3575,0x3f9849e2), LL(0x691d4ea8,0x1d85bc98),LL(0xc811fe44,0xbf34f840),LL(0x6fdeeca9,0x188d1f53), + LL(0xda6d3dcf,0x78294002),LL(0xaddf5b48,0x3f86f8c4),LL(0x6f8761ea,0xca9c8dbb), LL(0xb56d54cf,0x6d4be379),LL(0x3d32e3d0,0x9504874e),LL(0x1b4d470d,0xe0959574), + LL(0x60c89192,0x03618e26),LL(0xec22e3da,0xa067fbde),LL(0x202d430d,0x5656229a), LL(0xc7703466,0x1f782bd8),LL(0xa0026a97,0x3b278178),LL(0xf1c08768,0xc86a636a), + LL(0x754cbc65,0x175ae3ec),LL(0x4f765d06,0xc6f3677d),LL(0xa11dc7c6,0x699a40ca), LL(0xc2c20678,0xf85e4e41),LL(0x3ee230c1,0xc4fd583c),LL(0xf604d6e1,0xfbf97e3e), + LL(0xc6e43d77,0xc2a7b60e),LL(0x5e09cfba,0x5c44a7ab),LL(0x20323a01,0x31279294), LL(0xd83e9122,0xbef510c2),LL(0x910635c8,0xce89cd72),LL(0x6525654f,0x40c3123c), + LL(0xabb9fa3a,0xe5efa39c),LL(0xd54d0553,0x0dd062d8),LL(0x5f654ea6,0x2447ebea), LL(0xb205ee7f,0xc6b30d78),LL(0x6b327d54,0xac800865),LL(0x2d494627,0x3564831f), + LL(0xbf996e35,0xe5612ddb),LL(0xb2c8a71e,0x82b679c1),LL(0xb8522766,0xadfb7763), LL(0x6edb7f6b,0x31f681bc),LL(0x6c1396b8,0x0ac77865),LL(0xc16391a7,0x4fec5edc), + LL(0x6a8ba5e0,0x79be8744),LL(0x76a3f5dc,0x9cad48d3),LL(0xd3a4a677,0x3b4ddd6a), LL(0x2427a393,0x53d9dd5a),LL(0x99061179,0xe3992757),LL(0xc5ab35de,0x9a76a0ad), + LL(0x270ecf31,0x18e8dbf5),LL(0x3f3da910,0x6723152b),LL(0xe687db02,0x74b53e35), LL(0x89fccc8e,0x72dd231b),LL(0x6ca0a007,0xdf98fe28),LL(0x9b8fc127,0x5c469a08), + LL(0xf7c47e53,0x3d45d6b3),LL(0x2bca9e62,0x830867c6),LL(0xcef81d38,0x84276d68), LL(0xcc30ac2b,0x60d227cc),LL(0xaa747e61,0x514c1992),LL(0x4ed869e9,0x90083817), + LL(0xf15ff76b,0x9c199d37),LL(0x4a4fc2fd,0x0e5ab91a),LL(0x25ed5ca0,0x142d9700), LL(0xc7398261,0x417bd5e9),LL(0xca5133ba,0x074f5397),LL(0xbbf69817,0xda80ec1f), + LL(0x29f549a1,0x66cc5bce),LL(0xd6af775a,0xbe183389),LL(0x7b066b44,0x492f66bf), LL(0x431fc807,0x0f1397b4),LL(0xe83dd557,0xb6f675ba),LL(0x62489a2a,0x972d9038), + LL(0x8eff888d,0x71c228f7),LL(0x75586fd7,0xcd59c5d1),LL(0xdd3143e7,0xa966bb14), LL(0xbf353a1f,0xa7f87d54),LL(0xf484d5f8,0xf9cbceff),LL(0xb68ff698,0x698dae86), + LL(0x6f3235f2,0x66286731),LL(0x1579c24d,0xcba86933),LL(0xba144ac8,0x8864f364), LL(0x3ffd19b1,0xaad3e749),LL(0x6fdf894e,0x148d7a44),LL(0xb448c223,0x3aefa6dc), + LL(0x84e0548b,0xc6c90b42),LL(0xa6072bb0,0x9234d1be),LL(0xafb14b2a,0x3b28ca69), LL(0xcfbcc4d3,0x80eda096),LL(0xac4275fd,0x8bf29e73),LL(0xa9e0838e,0x10655c00), + LL(0x8eff3cbe,0x75e78f0c),LL(0xb0a9ad9e,0x2d549d6a),LL(0x50d83c74,0xd9179f56), LL(0x45988bd0,0xdf61dfe9),LL(0xe8f87cbb,0xb76286ea),LL(0x033c1c00,0xa64bca3d), + LL(0x664f67a7,0xd82e91bd),LL(0x19c561de,0x7329573d),LL(0xce6bab53,0x5faf92d6), LL(0xcc978c65,0x715cc536),LL(0xe1e82686,0x843e802e),LL(0xbb3c2514,0xd7a82374), + LL(0x46e3c384,0x7dec5bcc),LL(0xb5c8409d,0x874ece30),LL(0x0fb8869d,0xbc0f588d), LL(0x65d88ad2,0x11c4d95d),LL(0x349f7fc1,0xef6a5587),LL(0x5d3c89c7,0x8ceb5e7b), + LL(0xfdbac03d,0x8326fccd),LL(0xc0e3814f,0x8592d5ac),LL(0x92780f4e,0x4c4f9181), LL(0xcbd77d47,0xdfa95b95),LL(0x116d8d69,0x5c695658),LL(0x45d71633,0x3b9e5958), + LL(0x1f933a54,0xf15d931e),LL(0x572c2915,0x16a8e689),LL(0x6078e8b9,0xe37672fe), LL(0xb7252a68,0x37af9fd5),LL(0x6b8ac148,0x9e17b01d),LL(0x942a5a17,0x5ad4c09c), + LL(0xef904c15,0xcf9f44da),LL(0x1b8bd3f2,0xfd9b0973),LL(0x1a01c966,0xa2209dbc), LL(0x4d678467,0x0878c83b),LL(0x41418cd8,0xdfcce3e9),LL(0x24b1f3e9,0x10ed020b), + LL(0x6eb0a25e,0x1d05d913),LL(0x6ba1b2f1,0xd8dfea69),LL(0x4570c9ce,0x224f88a7), LL(0xb8c5a0d1,0x82087d08),LL(0xcdf8086e,0x2d689252),LL(0x33330715,0x7f5cbba0), + LL(0x143708d2,0x793030ec),LL(0x3aa671de,0xe1e44a09),LL(0x6d0c6b60,0xf8d14831), LL(0x4c6b4751,0x43814c65),LL(0x07c35ce6,0x23531a9b),LL(0x30f97153,0xec6a9878), + LL(0xa300f8ce,0xd0ced276),LL(0x1ef83f9a,0x7eb2f7db),LL(0x3ff788a7,0x8bdc98f4), LL(0x29e0e1c2,0x8c5f9af2),LL(0x7ac14e4e,0xb6cd8700),LL(0x073f9d19,0x54909c4d), + LL(0x3fb6efd9,0x9481d096),LL(0xb50cc9b5,0x04a156f3),LL(0x8baffff7,0x4b8e541d), LL(0xdb644174,0xe7f5e90c),LL(0x530c3696,0x754d867a),LL(0xf47978bb,0xfb20bb76), + LL(0xd5e0c70e,0x16986cc1),LL(0x52e7e6c7,0x42ce3058),LL(0xa618254e,0xf31ea341), LL(0xae1ae829,0xaf2001d4),LL(0xd97c4da7,0x3f93eca5),LL(0x8b5c3229,0x01dd7a1c), +}, +/* digit=8 base_pwr=2^56 */ +{ + LL(0x0c6a351e,0x6c78a1f4),LL(0x807a4e21,0x5192b2cf),LL(0x72479dc8,0x531cf1e5), LL(0x15863b65,0x78f3e85f),LL(0x6f917ccf,0x008524f6),LL(0xd0dccb94,0x531192d9), + LL(0xc490a7f0,0xf7d5ce6e),LL(0x06cc1312,0x646319a8),LL(0xbc37af6c,0x01d71545), LL(0x7f32c096,0x92077f6a),LL(0x02223fa6,0x3c4192cf),LL(0x0b59de1f,0x72b36fe0), + LL(0xee192ea3,0x6cc9d6a8),LL(0x4008c57e,0x951ca552),LL(0x0ccb74a8,0x0906ec42), LL(0x09e39599,0x80c4c111),LL(0xa5246b67,0x4a79b1c3),LL(0x5ead0c0f,0xff7242ea), + LL(0xf2d97c8d,0x9138c2cd),LL(0x2650a9b4,0x3caecb47),LL(0xf8760ddf,0x23a73447), LL(0xc1d98546,0x1ebf0619),LL(0xcc7f0b0a,0xd9f11b6e),LL(0xde8d96f1,0x16ab2c05), + LL(0xeffca98d,0x0dd3b147),LL(0xe1abc2a9,0x10c4fdcc),LL(0xf74f036e,0xc4b7b199), LL(0x7301d513,0x6db9d5ac),LL(0x774b8020,0x154acf22),LL(0xa60f3784,0x0030085f), + LL(0x859de975,0x6b73749b),LL(0x67883183,0xc97b9ead),LL(0xbfb919b1,0xaaae5948), LL(0xf5c8912d,0x8150189a),LL(0x67fe0faf,0x6b988a5c),LL(0xf5839146,0x21d1f6d9), + LL(0xa3635200,0xaf8c2c49),LL(0x1d377a92,0x0400e2f7),LL(0xfa0d421c,0xaa0ec06c), LL(0x0b0d997b,0x6e3c3b69),LL(0x6756ee3e,0x7d3832dd),LL(0xe78e3204,0x30d62b54), + LL(0x5174cd2b,0xcb5e1dcb),LL(0x18f6e4b5,0x8984cb7b),LL(0x72a12150,0x363d0f1f), LL(0xcc62f17b,0xb5c36272),LL(0x3a2f964b,0x4a992731),LL(0x4e8f1ce1,0xbca57238), + LL(0xff1a436b,0xdfcf7d1d),LL(0xee098e33,0xf6028d75),LL(0x85091828,0xf98fd92a), LL(0x8cbf1897,0x535e81c3),LL(0x100e48e4,0x4b9286c9),LL(0xa517213e,0x6dcb2c57), + LL(0xb451f187,0x1bb72786),LL(0xac01e718,0xbfa69395),LL(0x9acebb3e,0x2c1852ea), LL(0xddabfc41,0x5eae9e20),LL(0x1bd561f4,0x661e7254),LL(0x270a6fa5,0x71f20425), + LL(0x961036e2,0x15abdd47),LL(0x35b92111,0xe3edb318),LL(0xfeae7403,0x6a5f093b), LL(0x1595973a,0x4bca351b),LL(0x3a5ff8b1,0x10b5c69d),LL(0x826996cd,0x61699ca4), + LL(0x78bdb771,0xef90144f),LL(0xa6fa7f1d,0xc15f7dab),LL(0xb45483c8,0x367a4d90), LL(0x770b4b1a,0x3524f21b),LL(0x0446fddb,0x31111556),LL(0xf304737e,0x77b6be1c), + LL(0xabde9561,0x37c8901e),LL(0x122cf2de,0x607d5c3b),LL(0x8479673d,0x31a6f869), LL(0xf1df773f,0x1bc908c7),LL(0x6e7f32aa,0xb13f1008),LL(0xd9fc2d4c,0xd0b64b4e), + LL(0xf338ea23,0x4c0c5170),LL(0x49fbff41,0xb0639fbf),LL(0x6cdb87d1,0x0c71578a), LL(0x5d00e5a8,0x6a0fac6e),LL(0xfb624d14,0xf923d1e7),LL(0x65ec474b,0xe2af600c), + LL(0x0afa00ec,0x96a0e907),LL(0xe93d5449,0xa58ae31f),LL(0x1e050306,0xf0090575), LL(0xce3c1478,0x3570e2bc),LL(0xd154329a,0x6c779b82),LL(0x8a7caddf,0x2e65670c), + LL(0x428ffdee,0x7850b688),LL(0x1e3103a7,0x5630065c),LL(0xdc08408c,0xd774279e), LL(0x6eaf0bcb,0x85499490),LL(0x72f72173,0xb1954318),LL(0x4ac8220e,0x2e5e8eda), + LL(0xe86f4f00,0xbd47e5b5),LL(0x8338414d,0x312a0a57),LL(0x5dc0dd30,0x8832fc40), LL(0x8be0076e,0x5b2ec051),LL(0x45348887,0x3064cc96),LL(0x61596442,0x9d0e00fe), + LL(0x747e8db9,0xa49b588c),LL(0x1c9851ef,0x91bd49ac),LL(0x21c7c36b,0x547ad2e7), LL(0xcf0a07e7,0x91725ea2),LL(0xcbbcb82e,0xf7fc5911),LL(0x5646ba9c,0xd5f7714f), + LL(0x8edccbb0,0x0f86777c),LL(0x7068d3ce,0x4df433f8),LL(0x77731ed1,0xfd2d02a0), LL(0x1f323ab3,0x9ce12310),LL(0xabf47059,0xab127e12),LL(0x4257eed4,0xe37b4198), + LL(0x61b7a7bc,0x96bff478),LL(0x24a24d11,0xf70c91dc),LL(0x2ed5f8ef,0xf25c49f7), LL(0x8b8cd0bb,0x66103231),LL(0x337a16a3,0x9af494be),LL(0xbcdf06c9,0x8c8b1723), + LL(0xb8d9c7fd,0x5370d17d),LL(0x1320d963,0xa9848001),LL(0x3ab21366,0x4b08ede7), LL(0x8ee6ae31,0x3640d969),LL(0x7deca729,0x782297a2),LL(0x8cf1b471,0xb99c1450), + LL(0xc55e2971,0x3a206eb5),LL(0xe3b5b1a3,0xe65b0a7a),LL(0x7f789c24,0x611ca3ef), LL(0xaee050b4,0xffbed20f),LL(0xf7561895,0x81e86366),LL(0xc2fa8046,0x64671984), + LL(0x0c3c9013,0xade34ec5),LL(0x5eb41025,0x50bd68e1),LL(0x0d4894dc,0x78808518), LL(0x7c29a657,0x7ed39b6b),LL(0x241517d5,0xbafdbdd0),LL(0x188218bf,0xd6f50092), + LL(0xf03ef732,0x81177e12),LL(0x56a3507b,0x1574fe49),LL(0xab053718,0x6e960496), LL(0xc3a21218,0xbcd97662),LL(0x3bf70829,0x0cf68dea),LL(0x25b800e2,0x32d30c54), + LL(0xc9428b22,0x95452160),LL(0x72a22c82,0xc2622e6b),LL(0x5b27cb42,0xb6731ec6), LL(0x4fce33d5,0x0f8a1fc2),LL(0x6407716e,0xa9838902),LL(0xfa98bc54,0x5e553dc0), + LL(0xcaa69408,0x59683c61),LL(0x6598df18,0x82bc08db),LL(0x6634b238,0x154e5197), LL(0x43fc4c77,0x70ad310c),LL(0x835272f8,0xf9144e70),LL(0x9b7d0d58,0xf41beaab), + LL(0x7a860980,0x7aef7397),LL(0x7175ed79,0xab751037),LL(0x797c12f0,0x7dd8fb29), LL(0xebd2f077,0xa63e2440),LL(0xce865a7d,0x645fe5ce),LL(0x317de834,0x5e57db53), + LL(0x2bb8134c,0xc28c2ef9),LL(0x520d82a8,0x3cfa28dc),LL(0x7103b732,0xc31217da), LL(0xfef50290,0x9daf07ed),LL(0xb5fbffea,0x5b6cc3a2),LL(0x710a59db,0x98d2a6f3), + LL(0x9174bf48,0x44b0ff44),LL(0xeef16e79,0xb5562ba6),LL(0xea9adffa,0x129bbad4), LL(0x8ccd2a64,0xc93aa7fc),LL(0x2ce754e9,0x0c252964),LL(0x88a4559c,0xbaf7f806), + LL(0x548d0e57,0x924da3ef),LL(0xbe13e6c9,0xde8c8973),LL(0xd73979cb,0xe5dc0c62), LL(0xf5d1e78f,0xc2f92566),LL(0x95a8fdc6,0x3152a7cc),LL(0xdc528326,0x6601c017), + LL(0xd38d9fea,0x1235bcd4),LL(0xd899201d,0xe4d00d99),LL(0x2709bee4,0xf0a9da65), LL(0xf33d4d62,0x69266ab1),LL(0x7a7c073b,0xc5c102a1),LL(0x1fddcaa7,0x42e277b8), + LL(0x176de7d5,0xa3b38048),LL(0x3ae77e40,0xcc01f3c4),LL(0x1b8310bc,0xec1be1f1), LL(0xb0b6554b,0xbdc976c3),LL(0x9c4bcd13,0xd86117f4),LL(0xd41ce646,0x9feb9193), + LL(0x2120685b,0x7d1547dd),LL(0x610034f4,0xb3b1ec97),LL(0x947b29d6,0xe98a9207), LL(0xdb48b264,0x3dfa24b2),LL(0xa5afaebc,0x6c8e33db),LL(0x0db735ad,0xfcad214a), + LL(0x3a1e3514,0xbc366d47),LL(0xd584ab3c,0x67228d9c),LL(0x90009ee1,0xd8abe402), LL(0x68d15f9b,0xb06fcb6e),LL(0x3cbc8586,0x9f4fab36),LL(0xac1ca214,0xeb6fc7d3), + LL(0x212701d8,0x644ffbc6),LL(0x3e7f5a64,0x0dd77816),LL(0xbba949bd,0x4182d12c), LL(0x9dd68a5b,0x566f707c),LL(0x3374e3d4,0xc32b41f7),LL(0x33a887f2,0xe25506ae), + LL(0x7d747270,0x6809dda9),LL(0x34b9c161,0xe0ff644d),LL(0x5735d1ce,0xedce5894), LL(0x3c299049,0x9a14955a),LL(0xe770315b,0xdf5340ba),LL(0x09ab6581,0x21d8b57d), + LL(0xa3a84876,0x6e2ebe98),LL(0x33705d95,0xb25b877f),LL(0x17be7330,0xfb32cded), LL(0xb3db892e,0x91cd62d6),LL(0x782eca61,0xca99ae59),LL(0xf953f71e,0xe927b38e), + LL(0xfdefd2fc,0x932d6c0e),LL(0xd45bc513,0xc02f4213),LL(0x97a9f940,0xb9554eff), LL(0xe0f84e1a,0x4e5d7ebe),LL(0x2f4302e3,0x77035f14),LL(0x9555b2f5,0x45bcd681), + LL(0xb757b6a7,0x55313f4d),LL(0xf62039e3,0xc1b3ca66),LL(0xa68faba3,0xbc76d877), LL(0x5fc39ebe,0x8addb47a),LL(0x2205e6df,0x52e4f8b8),LL(0xe999baf6,0xa4963df4), + LL(0x01e9090d,0x43ec78a5),LL(0x670ed5c0,0xada7c41a),LL(0xca0ccd63,0xf441fc60), LL(0x9f8a35c9,0x2b6b14cb),LL(0xd67b0c7a,0xea90296f),LL(0x475bfd04,0x9ec66ada), + LL(0xae9c5b50,0x785fcd1c),LL(0x43f8004f,0x1793f480),LL(0xff4b7c93,0x4ac0e11d), LL(0xbdbd07ff,0xfe1f7829),LL(0xb36c82d1,0x928d4b94),LL(0xedb0863e,0x9afbd51b), + LL(0x35ef7543,0x45b8e6c7),LL(0xefcbf15e,0x04bedfec),LL(0xd26c073f,0xe5d2b221), LL(0x9eeedb4d,0xbb74aed4),LL(0x8329872b,0xbdeee909),LL(0xd5027bee,0xde0ef4fd), + LL(0xfdec460d,0x4373d235),LL(0x5367ccc3,0x889db5d3),LL(0x6ba366f2,0x75b7adbd), LL(0x59e47152,0xda4f82c6),LL(0x74645dce,0x2f5d2404),LL(0x72715896,0x73bc8042), + LL(0xc2538c33,0xd97aa542),LL(0xc4176743,0xb0d4f42f),LL(0xd9117f2c,0x4e46a104), LL(0xa1dbb89c,0x749b728c),LL(0xbb2d1a5c,0xc91c80f8),LL(0xc41a94ef,0x3668d74b), + LL(0xc88dbe72,0x64a248da),LL(0x8c9c23c7,0x90d78a4c),LL(0xa56cbc8b,0xd49e40ab), LL(0x305322ae,0x764a4a3b),LL(0xd2f6d2ca,0xf13655d0),LL(0x0ad04588,0x5e206b78), + LL(0xa4e2f277,0xb295d1f4),LL(0x2b0f59d4,0x1d49ae57),LL(0xfc85f875,0x77ccdf3f), LL(0x40f7816d,0x98ca5c5e),LL(0x2cb0558a,0xea990a23),LL(0x7a723586,0x76ef8645), + LL(0xd4b23830,0x1618d79d),LL(0x0f9647c2,0x0a1387ea),LL(0x166ce29c,0xd2ba4d03), LL(0xacf33156,0xcc88e78f),LL(0xcaf5f200,0x57da063f),LL(0xae63a300,0xa5cbc1c3), + LL(0x017ded2b,0x8abdda43),LL(0x02c5993c,0xabbe3891),LL(0xfd7ffd34,0x52df96de), LL(0xd7e89e8c,0x6c4d980c),LL(0xbd659dc7,0x8e3c41be),LL(0xfe1fe1f8,0x7f6f7496), + LL(0xa4a51425,0xecae5b7b),LL(0xdd9d83af,0x81e2c971),LL(0xf7b85342,0x39b1d2a3), LL(0xfa8bf8c0,0xc45ad2c1),LL(0x7f18d82c,0xf495b15f),LL(0x9ccdc3b1,0x8b260d45), + LL(0x1d241682,0x5a2e6fa8),LL(0xa49fd352,0x313e6fc8),LL(0xa7ddd234,0x75139843), LL(0xd3d7609e,0x6549aefc),LL(0x8f6fd0cd,0x1b477e03),LL(0x70f7a7f4,0x6140a881), + LL(0x6718b3b6,0xaf1106f1),LL(0x44eaa8c1,0x767e6522),LL(0xf735f07a,0x527f2eed), LL(0x14ea415a,0x45ad0cfb),LL(0xabde5ef6,0xc09636ac),LL(0x9fcee205,0x88d7fa8d), + LL(0x95543299,0x004861d5),LL(0xa61e24e5,0xd594bc3c),LL(0xb3b7cffa,0x2bcafd63), LL(0x5669358b,0xcb375694),LL(0xcb56b897,0xc5c022e4),LL(0x12de2824,0xb2b30bdf), + LL(0x2cfdf68c,0xce6b8b13),LL(0x910076c2,0x942efa8e),LL(0x4719c7c3,0x661fc5fb), LL(0x82ebe6b8,0xcfdf4b8d),LL(0x3bb3c18e,0xdeee7446),LL(0xd641180b,0x00ed3964), + LL(0xcb3382da,0x1a1ea271),LL(0x30bf39fb,0x0256f492),LL(0xaf66aa74,0xc817dad0), LL(0xf968fb2d,0x2b653957),LL(0xf0fbf6ca,0x5d0b99f4),LL(0x80454299,0xe59af736), + LL(0xc2755f73,0xec4992e6),LL(0x4ca484fc,0xdfc3c447),LL(0x7217c264,0xa1f98659), LL(0x6549d8ea,0x43da1644),LL(0xee1b8b43,0x5a967704),LL(0xd404bff3,0x2a8a337d), + LL(0xbe4b6d8b,0x94c51eb5),LL(0xc07e4713,0x8fbc9eb8),LL(0xd390eddc,0xa19d59bb), LL(0xe0be24bf,0x0ccb795a),LL(0x340f70c0,0x84f1de5a),LL(0x582c2b9b,0xa699c480), + LL(0x7414a8d3,0x5eb36220),LL(0xe5364537,0xf828a75c),LL(0xc830d477,0x1082ff06), LL(0x037d83d0,0xd1528c4d),LL(0x45baf298,0x2b40c250),LL(0x35ee8eae,0xe2e4f82d), + LL(0x12e4391e,0x6d36ed91),LL(0x4f322b3c,0x1ea89876),LL(0xfbc19d19,0x60200183), LL(0xda185be5,0xea5a5069),LL(0x248f835b,0x0e2393fc),LL(0x15ee6f20,0x61d051fa), + LL(0xe1b5b6fb,0xf886470a),LL(0x60b4fdb1,0xda09259d),LL(0xf88455b3,0x088e9c86), LL(0xbc2676c1,0x52c2860a),LL(0xd1a102f0,0x6d6fa953),LL(0x7cc062e0,0x9299dce6), + LL(0xf1a2b5ca,0x812c18ab),LL(0x21bc03a1,0x9b74e2b7),LL(0xc81ccc62,0xbca14295), LL(0x05d9bf48,0xfb6c986d),LL(0xb169ef26,0xc284d240),LL(0x901172ad,0x6292fc73), + LL(0x5ef17d8f,0xeddaa5d3),LL(0x7c406cd1,0x15267457),LL(0x9531e2d8,0x2e303a5e), LL(0x75ca396a,0xf7bf1c5f),LL(0xc12acc0d,0xb10e432e),LL(0xeac37f33,0x2ffed1db), + LL(0x8e561f72,0x1fef1ecd),LL(0xdd1089ac,0x38fe7b1b),LL(0x3bc9bed2,0x2f24cac2), LL(0x8beb4a49,0x0d99d3cd),LL(0x9f925b5f,0x7dd5cfb6),LL(0xfd9b7744,0xa23894f0), + LL(0x14747d9d,0x1f353554),LL(0x75836ce2,0x31bcdf39),LL(0xf2ace220,0xea43017e), LL(0x0246a810,0x55ea2317),LL(0x4ad388ad,0x14671291),LL(0x6a13372a,0x93633c21), + LL(0x3a2d7c85,0xcb969eff),LL(0x73683dda,0xe59df301),LL(0xd6450189,0x07e6d627), LL(0x5bb295f6,0xdddae32b),LL(0xe18b49b4,0x6746310c),LL(0x9b220769,0x828865f2), +}, +/* digit=9 base_pwr=2^63 */ +{ + LL(0x06290b5b,0x76334d9f),LL(0x1c02aaf4,0x096fa00d),LL(0xb1c345b9,0xb29c7abc), LL(0xdb7dfee2,0x91b1e9d2),LL(0x28848019,0x0c63c40d),LL(0x3e9d93a9,0xa131323f), + LL(0xf13eb9c2,0x1935ea95),LL(0x2c20a03b,0x37b07e4b),LL(0x2897bd62,0x7ccebf49), LL(0xae088f35,0x671df286),LL(0x1a339948,0x9b826c19),LL(0x5b176e1c,0x2e503224), + LL(0x6ba550e2,0x674ed6b8),LL(0x1cda326c,0xccbad8d2),LL(0x99aa3448,0xd1542f83), LL(0xbf457736,0xcf8eee5d),LL(0xcebef35d,0x40007023),LL(0x3c3cacd6,0x4f6c8f17), + LL(0x4971b9d2,0x5794be45),LL(0x22f3503e,0x64a2a44e),LL(0x337993cc,0x62069df9), LL(0x8cf5aa65,0xb5a8be91),LL(0x4266a4f2,0xdcf77c1c),LL(0x479a02fc,0xbbe137f3), + LL(0xf8b77a15,0xbd930e7c),LL(0x565819b0,0x1f604624),LL(0xc4a43c29,0x9a01433c), LL(0x8a108d0f,0x8cb9e675),LL(0x86e761d4,0xa4cf1e24),LL(0x30951662,0xf54b8c4e), + LL(0xa45636a1,0x5b66a405),LL(0xaaad9d66,0xaaddb23d),LL(0xb2f86dd3,0x896cbfcb), LL(0xdb9ca210,0x01d8e6d4),LL(0x6cca4804,0x6623a1bd),LL(0x51bacaa2,0xf657c1fc), + LL(0x3447e4e1,0x94172f67),LL(0x9c87c415,0x54f322cc),LL(0x9e98c65c,0xdc8ef479), LL(0x45d91721,0xd3538e9b),LL(0x1506e6bd,0x6291aa36),LL(0x13f2dbec,0xf61e47e5), + LL(0x1a8522ff,0x95dc6196),LL(0xb2a0c2fd,0x7800e4de),LL(0x493d2023,0xb2d8b5c9), LL(0xb3d564a2,0x2c595ab6),LL(0x4e856f46,0xee5106ea),LL(0x0d824ff7,0xdf6ac56c), + LL(0x8d5303f8,0x0cc840ed),LL(0x019b0602,0xb756ad36),LL(0x723c0494,0xe56dfdab), LL(0xd268efe1,0x8ba759dd),LL(0xc3466388,0x6c72c1b7),LL(0x85cf6c47,0x7a5f5d09), + LL(0x4fe757ec,0xdbab4d4a),LL(0xdb01add0,0xfb7fb787),LL(0x6922f7b1,0x521bd604), LL(0x6b994d8e,0x4c317222),LL(0x9e46ab73,0xa7a17e9e),LL(0x20326632,0xa39d84d6), + LL(0xa2841ffc,0xa302b6c0),LL(0x4e85da4c,0x4809d2c3),LL(0x16eeee34,0xf8bea692), LL(0xfda40073,0x049d0306),LL(0xbffc68be,0xe8956671),LL(0x21e27827,0xf5ae3b98), + LL(0xe56f2481,0xcf5a16d7),LL(0xcb81a7ba,0x3def2594),LL(0x032f3df9,0xe07beed8), LL(0xc369a737,0xab17091a),LL(0x438b3620,0x0956e828),LL(0x10f465fc,0xab6ecf14), + LL(0x6b2649d8,0x6e182bdb),LL(0xb09ecfad,0xc7601742),LL(0xeb6286a3,0xb43cc8c7), LL(0xb948e18a,0x89b48a00),LL(0x42ed648d,0xe337b779),LL(0xe4fc127d,0x1da0987e), + LL(0x88ae8b76,0x45aa621b),LL(0x3162f9f7,0xb127ad6f),LL(0xc8f2cb42,0xeb56c7f7), LL(0xcddb2b13,0x6b7993cd),LL(0xfba0d637,0x6f2f2d51),LL(0xb16542d8,0xcabe79c9), + LL(0xbde530d9,0x6753d960),LL(0x9b8986a8,0x77b91029),LL(0x9cefc1c4,0x5af09d8a), LL(0xa78c0b08,0xb396dcb1),LL(0xb5928a9c,0x44dc48ef),LL(0x2f48a964,0x9fafb33c), + LL(0x408cae9b,0xa2a98dd1),LL(0x61c6bec6,0xb3ff192c),LL(0x3ead88da,0x607b0c64), LL(0x63184290,0x0039f8e6),LL(0x6dd9836f,0x0b9f09db),LL(0xc51a47fa,0x5d9d8f22), + LL(0x166920d2,0xe9cf521f),LL(0xbec39b63,0xaf5b1d19),LL(0xee934b22,0x3099fced), LL(0x959116f1,0xef6f72af),LL(0xacea8ba9,0xf710ef28),LL(0x13990b15,0x588d2bbc), + LL(0x86049369,0xcbe2755c),LL(0x46e988e6,0x738787b9),LL(0x4a2e3319,0x520ae3e4), LL(0x932e0896,0xf7e43ece),LL(0x2d3989f8,0x906f0e67),LL(0x9e24fec1,0xc4ce28e2), + LL(0x9519aaac,0xd4391f09),LL(0x1c2d3eb4,0x923a951d),LL(0xeaa8d831,0xbba9e206), LL(0x3b0369ed,0x86a8f819),LL(0x84f45ee3,0xf08f5db8),LL(0xc7fd4306,0xde9d97b7), + LL(0x82162e5e,0x4abae764),LL(0x820c91df,0xda046c14),LL(0xcac95307,0x9be5686d), LL(0x1926ce21,0x8d90109e),LL(0xa11ddecb,0x346eafc4),LL(0xd72ecc75,0x3ce252dd), + LL(0x3d30e9b1,0xb559793c),LL(0x21faa664,0xcf651f10),LL(0x0af936f8,0x58827716), LL(0x3390af36,0x2e460004),LL(0x2e93e7e8,0x355c08cc),LL(0xda2c6727,0x84eb137e), + LL(0x2625e961,0x9e901d5b),LL(0x499b3624,0x53244f50),LL(0x3c07fdd0,0xf7b5e924), LL(0xc8b4fccb,0x5e1b6db8),LL(0xd9a4ede5,0x4d6122ee),LL(0xf719582d,0x96df7864), + LL(0xc9be27d1,0xeafcb131),LL(0x985a8e07,0x86458dd3),LL(0x63ff40d4,0x3e039563), LL(0xd1407667,0x2541540f),LL(0xd9795e3f,0x8b27f2d9),LL(0xd60d0743,0x5dbbd4b3), + LL(0x605be24c,0x2b496309),LL(0x496bfcf4,0x3afbea78),LL(0x46ed79bc,0xfe6069c6), LL(0xad7bb67a,0x3cbeb331),LL(0x37463aa4,0xeedcaf16),LL(0x7c12f87f,0xc41a07ca), + LL(0x2fccd260,0xbd41b63e),LL(0xc658b3a5,0x3bb5676c),LL(0x15c9ccb5,0x84c591dd), LL(0xa5fcc6ca,0xc5573715),LL(0x9fcba543,0xf1800487),LL(0x63da6fef,0xfb887cbf), + LL(0x9f37dc0e,0xfd99db21),LL(0x5783e53d,0x85bbbefe),LL(0x09d5d09d,0xa10360ba), LL(0x3cc09837,0x12e9679e),LL(0x793efd44,0x81a4b2dd),LL(0x8153dba4,0x0c93ed4d), + LL(0x2883764f,0xb7b5a250),LL(0x75b781bc,0xd3ca90ea),LL(0xc5198673,0x8da40a3f), LL(0x237103fa,0x434744ad),LL(0xcbd65a76,0x16d7466c),LL(0x9d0ce6ec,0x97f5ff82), + LL(0xc3b3f666,0x0134d746),LL(0x7c3910eb,0x62a3254f),LL(0x6906613f,0x989510d0), LL(0xe75bfea7,0xa63aead6),LL(0xf6f48b5d,0x2c7bb201),LL(0x0cf11cdd,0x17c485c4), + LL(0x01346a36,0x44072775),LL(0xeccf5986,0xd81f9e8b),LL(0xffca3195,0xcedbaa7d), LL(0x5744e89d,0xeea2a618),LL(0xad358476,0x65f3b598),LL(0x49cae477,0x31ef0e2a), + LL(0x82f6a471,0x0f618b7c),LL(0x437cc826,0xac49eab7),LL(0x7209d33e,0x6ac9e2b8), LL(0xa161856e,0x14857b21),LL(0x638a1099,0x2c515ae8),LL(0xe8f5e86f,0xd34ba334), + LL(0xdf15afb4,0x96dc51a8),LL(0x5b39ee73,0x0db5cc4d),LL(0x59face85,0xb166ae3d), LL(0xb3c9bf88,0x94ee7aca),LL(0x34ba27bc,0x0724cb81),LL(0x8aa869b4,0xac1a10a4), + LL(0x621e0951,0xe85de117),LL(0xf75855ac,0x7b464098),LL(0x53d1abe6,0x06b33c28), LL(0xb538c2cf,0x095bdc74),LL(0xd859366c,0xa64b61e0),LL(0xe9922d24,0xa5c92136), + LL(0xc221fe54,0xa1285a95),LL(0x7964a5fc,0x50c3e10e),LL(0x497b1e90,0xdbaa4092), LL(0xa9408c0f,0x3f4e7d97),LL(0x92b70f2b,0x1e83c2f5),LL(0x6911dac9,0x2ed8ab9c), + LL(0x73b888d5,0x0bc16a46),LL(0x8a011451,0x4305504a),LL(0x5de19cb5,0xea5d6a02), LL(0xa7166a08,0x8571e2f0),LL(0x6ea97470,0x9edcb0ba),LL(0xd6fc7b1d,0x1ed74e9b), + LL(0x48e4b5fe,0x960652fe),LL(0xd0e6f19c,0x391d4162),LL(0xb59dd2ef,0x8c6e00ef), LL(0x95fd71ce,0x0cc08f13),LL(0x8fedafc2,0x6d81789b),LL(0xe498c253,0x3ec56b1a), + LL(0xb7edb5da,0xb9bf335a),LL(0x693e2fe3,0x1a3b9636),LL(0x94c320a4,0xb12ae440), LL(0x35ef6698,0xf7d1986e),LL(0x273f0a93,0xc1db1a91),LL(0xadbd81a4,0x72fd29a3), + LL(0x1dcb4e55,0x57a9af55),LL(0xa46743c4,0xa430b677),LL(0x4459d987,0x2e2d09e0), LL(0xc1831698,0x58bc26b8),LL(0x8e8a86f9,0x02cdfd4d),LL(0x86532393,0x81824a71), + LL(0xfdf7070a,0x4b7d4311),LL(0x46b2d2cd,0x790ff04e),LL(0xa669dca9,0x5f194b6e), LL(0x6ee0a73c,0x8d27f077),LL(0x3f03f66f,0x7db8300e),LL(0x52542218,0x894792c2), + LL(0x320a391f,0x709e970a),LL(0xd301afda,0xffc55682),LL(0x187a421b,0x8c7c2ac7), LL(0x05c2a76b,0xb9413568),LL(0x50d693ea,0x4ce64d45),LL(0xf8118a62,0x133a1d85), + LL(0x1634f569,0xb78ee791),LL(0x0985837d,0xc8fdd735),LL(0x42337dc2,0xb40ab147), LL(0x2ece8062,0x58ee37a9),LL(0xb4fb1ae1,0x1b80e3de),LL(0xddf42642,0x55797958), + LL(0x3a4a5d2b,0x4ced5be1),LL(0xf46469b5,0x537cc02f),LL(0x9140aadc,0x369faf66), LL(0xbba54c56,0x91646050),LL(0xf1627bac,0xb6ae4660),LL(0x03bf4ace,0xd39a1183), + LL(0x5ad40b74,0x9a746086),LL(0x09825b65,0x8d116e80),LL(0x4c9e508b,0x66642780), LL(0xca3af3bd,0x10c1db38),LL(0x67df4e51,0x91ca8866),LL(0xadf6517e,0x3b4ebf22), + LL(0x69754168,0x906ece9b),LL(0x3842db37,0x78a4999a),LL(0x45118f97,0xa54934b5), LL(0xd6600715,0x17c76b7f),LL(0xfef1a9a9,0xec8d0be6),LL(0xdaf01223,0x80902814), + LL(0xe7382aa9,0x8ffad587),LL(0x64489fbc,0xff48de9c),LL(0xc8d3ef62,0xe539dabd), LL(0x6e44245a,0x037fa21e),LL(0x6ffc89e7,0x44aeb6c6),LL(0xc24d18dd,0x903826c9), + LL(0xfa798920,0x7e6202ad),LL(0x97dc220c,0xa69a704f),LL(0x27b68255,0xd7e7cafe), LL(0x52b2a274,0xa6aa0342),LL(0xe49cef76,0x72ecec87),LL(0x82afed60,0xee4bbb4a), + LL(0x7c8213f0,0xb7bfa6d1),LL(0xe2e5eb2d,0x55e77d8a),LL(0xecb57d00,0xde5c925a), LL(0x91bfc135,0xc67d7eea),LL(0x14df6915,0x6915f948),LL(0x8e5e081a,0xbc1fffee), + LL(0x4f0a6b86,0x1ca04a6c),LL(0x07a69d26,0x3f736642),LL(0x8eb91e1c,0xbcf425f5), LL(0xf7a230eb,0x0ee5e1c6),LL(0x11f1574d,0xafdd21cd),LL(0x31d6dc6d,0xb5ef9bf3), + LL(0x7cc6bcf3,0x6774ed5f),LL(0x0a75d23e,0x6feadf8b),LL(0x81ec8c8a,0x5898828e), LL(0x414cd64b,0x3e9103bb),LL(0x1542efe4,0x703f0fb2),LL(0x7388d6c8,0x3df2c7c6), + LL(0x60a7e99b,0x02e73081),LL(0x7986406b,0x1b3db98b),LL(0x3fff6009,0x9959bac0), LL(0x75e1d2fa,0x80625a36),LL(0xa198da2b,0x95492b2e),LL(0x59742464,0x81018f71), + LL(0x3cdf8db3,0xc1fc725f),LL(0x59326d48,0xd58228f1),LL(0x1d74eaaa,0x4c0a442e), LL(0x1b886d60,0xa814c005),LL(0xfaa58d26,0x9756df79),LL(0x176bed0c,0xc17f3346), + LL(0x7ec82b2a,0x874840bd),LL(0x1e1e2156,0x8b253112),LL(0xd1a58bca,0x8264f8ad), LL(0x23a4105c,0xc2a71227),LL(0xf0882599,0x8add8a3d),LL(0xd491e94b,0xfadbbc8e), + LL(0x0f86b5cf,0x8d48becb),LL(0xdd83a12b,0x700c6428),LL(0x87164a6a,0x9175e238), LL(0x300636b7,0xdd10d85e),LL(0x080c01ea,0xec0b0e20),LL(0x18c937fc,0x5b27d26f), + LL(0xaba54a99,0xe45deb1a),LL(0x88f0f0e9,0xea11e26a),LL(0x8d1c5c7c,0x3f29d26a), LL(0x261af059,0xaad1697c),LL(0x8bc6950e,0x65b29644),LL(0x3940ae67,0x33e4b7c4), + LL(0x18f510ad,0xe7e52f31),LL(0x4aba84d1,0xecf901f6),LL(0x1d0d87ae,0xe6d9492c), LL(0xf4371e3c,0x21861ebd),LL(0xac94b579,0xd7f34636),LL(0xe45e7910,0x72e22e1d), + LL(0x0d44e5c0,0xe0a30cd5),LL(0x672259aa,0x2d74d417),LL(0x48769d5d,0x208c07a6), LL(0x3ab04b13,0x0182f535),LL(0xd1493acf,0xa88ddf33),LL(0xe65f0e82,0xd692f755), + LL(0x200e00e2,0x57480257),LL(0x80f4a13a,0xd24d38be),LL(0x8b6535bd,0xe2d4702a), LL(0x6d6d0cd9,0x597abaed),LL(0x1a32e8b7,0x2eaf61f2),LL(0x06a3acc5,0x48a99a4d), + LL(0x39489527,0x25304144),LL(0x832761c7,0xb36d9b74),LL(0xaa187256,0xe33bc0a7), LL(0xa72fb33d,0x4d4e2c96),LL(0x7ed273fe,0x1dba3ef7),LL(0x577de798,0x2b9978d8), + LL(0x54644ced,0x467e81b5),LL(0xc2a02440,0xd4ef3e1b),LL(0x15b3a380,0x0df99eec), LL(0x250b43d1,0x549afec6),LL(0x1598f520,0x0c4fc7e2),LL(0x67422c36,0x9f8e42d7), + LL(0x6c0213e3,0x3a3886aa),LL(0x8b5b752a,0xc12533ce),LL(0x814f4729,0xbe235906), LL(0xbffc94e3,0xdf45bc94),LL(0xf2a001db,0xccdad604),LL(0xb8cdcec3,0x11ddcaa6), + LL(0x25ddf146,0x7eee967e),LL(0x0bf6e4d3,0x9a2d1d73),LL(0xabd48b07,0x57a43f05), LL(0x32b3a8a7,0x77d9ad80),LL(0x55872fbd,0xfbab22cf),LL(0xd02e7501,0x2100eede), + LL(0x25faa7bf,0xf4f4c899),LL(0xaa9fc84a,0x235a5736),LL(0xfae4fdb9,0x37647c20), LL(0xa26ae472,0xfc3f8ca6),LL(0xa2f519e3,0x01c6ea11),LL(0xc2fc610f,0x1ce14f58), + LL(0xb767a1fd,0xb6f923fc),LL(0x07e07c0c,0x31a760f3),LL(0x6a7085a9,0xe913fcfb), LL(0x40442930,0x86adb2bb),LL(0xe41a1b14,0xc8c20759),LL(0xd8d1924a,0x399d5ad6), + LL(0x76ac6874,0x6f0508e8),LL(0xafba3d82,0xd96bd7cd),LL(0x56cc2c07,0x336b813e), LL(0xb0c7906c,0x0fca9b73),LL(0x232e056d,0xb85518fe),LL(0xd1c21ece,0xa97bdc68), + LL(0xfbc66efc,0xf3327dfd),LL(0x34a1c591,0xa401731e),LL(0x3371b4b7,0x8c1ca43a), LL(0x526198b2,0x835393dc),LL(0x686e9c85,0xa8d2d86f),LL(0x7a0c3d07,0xa4491de7), +}, +/* digit=10 base_pwr=2^70 */ +{ + LL(0x309b2b98,0x790e100d),LL(0x50a4f09b,0xaf54cb0b),LL(0x956ec705,0xbfd5af9f), LL(0x3bab82f5,0x4692a125),LL(0xec637260,0xac0be759),LL(0x580441bf,0xaf835bc0), + LL(0x513c3f3c,0x80ab94a2),LL(0x77e64a9c,0x39c245d0),LL(0xa7543bd5,0xc3ba4002), LL(0x7eacb224,0x6658e2bd),LL(0x1f419c54,0x7e005bba),LL(0x58b62644,0xd54bc0f7), + LL(0x9194cd13,0x5c1c461d),LL(0x95f13f43,0x843427bf),LL(0xba86794a,0x6844d36f), LL(0x393e443b,0x90e5c334),LL(0x9f72ba01,0x8cec77f9),LL(0x145d81fc,0x28ef5fba), + LL(0xdd9dc934,0xa6b331c2),LL(0xde2f138b,0x32a15ddf),LL(0x2b7697a8,0x490117ee), LL(0xb3b1e935,0x5eaf7f20),LL(0x9b807876,0x4b750ed0),LL(0x864be6f5,0x98f1673d), + LL(0x9a5d2cee,0x4a36329f),LL(0x373aae9d,0xd6288e69),LL(0xd918ee97,0xbf2fd4fb), LL(0x870b1cdd,0x020ef080),LL(0x22a9b3e7,0x5578e9ae),LL(0xeb392f0b,0x8887e7e2), + LL(0xf5b8a656,0x533c438d),LL(0xbc6d32ae,0x98531dda),LL(0x1af7184c,0xc8e1927f), LL(0x393cf3c4,0xb9f8c2c8),LL(0x73ac1607,0x37cffce8),LL(0x3312e5ff,0x76d8c894), + LL(0x2b57f886,0x9a855c17),LL(0x3f649b7d,0xa334a009),LL(0x6e284b9c,0x90468704), LL(0x008bb313,0x633d15c5),LL(0x0ec3ca93,0x384f430f),LL(0x83b412c8,0x109e0fec), + LL(0x1a53d7a9,0x53582049),LL(0xf0099876,0xa35696c9),LL(0xfab32bde,0x34991882), LL(0x9092df43,0xa6e48215),LL(0x0f2f3443,0xf674d02f),LL(0x4d862a69,0xeeb91808), + LL(0x8ece35fc,0xdc9c1776),LL(0x9ab87051,0x7e6e4720),LL(0x7fd83120,0xf6d82143), LL(0xa0bcd27e,0x7ee28542),LL(0xd6a86383,0x5e5835d3),LL(0x3ddae47d,0x1b6caf5f), + LL(0x48ce8d7a,0x66cc8b26),LL(0x5f4e54c1,0xb8f25b70),LL(0x8abade9b,0x9c222105), LL(0xe91600e2,0x6a5880be),LL(0x55c01418,0xd8214454),LL(0x3e0670f2,0x1510a747), + LL(0xefd35bbf,0xe70de601),LL(0x01575c49,0x23fea84f),LL(0x04ef42e0,0xc9dc4bb5), LL(0xb139d368,0x01d78685),LL(0x4c1d31f0,0x6acc3ed7),LL(0xbeac2fcd,0x7ebf6809), + LL(0x8b17cc56,0xb221b461),LL(0x6c918f42,0x3a388a6c),LL(0x61ec2c4a,0x43b22feb), LL(0xdd8892c4,0x1f31f72b),LL(0x7aae5ed6,0xff9e63db),LL(0xc5aa19b7,0xcf33f8e0), + LL(0xb6d01e70,0xb2b290ae),LL(0x70c988ca,0x32377051),LL(0x5c47c52d,0xb49ee722), LL(0x73ed265f,0xa41919e1),LL(0xf4708b44,0x41428dd0),LL(0xda4fedfa,0x15d760a1), + LL(0xe8537c4b,0xfed502b6),LL(0xfc7dde03,0x8bab770b),LL(0x7d1f76d0,0x05c46da4), LL(0xc0db9267,0xc8dcbdf0),LL(0xcf6393d4,0x01cc7b6a),LL(0xeaf6dc69,0xab93ff59), + LL(0x9da53ff6,0xc026d3db),LL(0xd6c5a028,0x6b07911d),LL(0x9f01eec9,0xf2e88f7a), LL(0x35fb3be7,0x30ac879a),LL(0x9c8e073c,0x92871e9a),LL(0x44eb456d,0xc18518f1), + LL(0xe32b5a2f,0x2ca049f6),LL(0x3c2dc1f8,0x164d195b),LL(0x0eafa9d1,0xd1364e77), LL(0x59bac901,0x87a85a1f),LL(0x31b28912,0x040599eb),LL(0x73989f3d,0xe5138d57), + LL(0x59e18159,0xda271207),LL(0x87bdce2f,0x62d2e07e),LL(0x9c9da191,0x00bc160e), LL(0x9f9f3edd,0xc2aa6fab),LL(0x3e0cc568,0xd0bd4459),LL(0x6d2f3dbc,0x80621f6a), + LL(0x2608caf0,0xc02d8317),LL(0x3b8d5f88,0xb2b7cf8e),LL(0x97aa5235,0xe268620c), LL(0x53373262,0xc5d88092),LL(0xcbdc45c7,0xb80c631a),LL(0x3758fbc8,0xa82fa7f0), + LL(0x61946f84,0x71ca7112),LL(0x26f634dc,0xdbb91c74),LL(0x48b33bf4,0xc61feaa2), LL(0x0f0b622c,0x8c1f4e50),LL(0x4a976276,0x54a1b037),LL(0x9ac35cd3,0x46fdaca0), + LL(0x62a4a464,0xa78d6498),LL(0xbe50e07c,0x8185cc99),LL(0x046a15b3,0xe0df6a84), LL(0xb1747017,0x3fbd2fe4),LL(0xd8a28d37,0x40bd174e),LL(0x3ba62fe3,0xeb67a57c), + LL(0x9cd4dbf3,0xc674a040),LL(0x8ef4b42f,0x342823c9),LL(0x82a815c3,0x51bb59b7), LL(0x56fc0c39,0x4b239627),LL(0xc5f5d825,0x28ec23b4),LL(0x6c8e1e27,0xf7c1b3d8), + LL(0x27ec4b30,0x9635ffa2),LL(0x100ea34e,0xc42039eb),LL(0x90076fbc,0xd912642e), LL(0x1f77514a,0xaafcaa31),LL(0x0fb82d1f,0x79d17151),LL(0xb2f1317a,0x7c0989e3), + LL(0x89f462e7,0xb4998e80),LL(0xe6fbd086,0xb36cee42),LL(0x2313e077,0xc8121a21), LL(0x2726f97c,0x5989f410),LL(0xcd4d494f,0x0186977b),LL(0x5a5b30ab,0xc3fb6b78), + LL(0x424d3124,0xf9bb1829),LL(0x22c5cfed,0x4def4592),LL(0x116b8380,0x635090f0), LL(0xedc582ce,0xdc36aaf6),LL(0xcb88543f,0x8c97c600),LL(0x79d7d839,0xea4cedf6), + LL(0x3a7fe603,0x8e22dd53),LL(0xb6e13252,0x4f6646e7),LL(0xcc10cc0b,0xecb71522), LL(0x8fe0bd6f,0xb14b31d5),LL(0x7a6c5efb,0x2fe52f94),LL(0x1d6b6945,0x46144410), + LL(0x41fe4d44,0xd9cc6cd5),LL(0x3e28dc8d,0x358e33f3),LL(0x521ff50b,0x1a26ddf8), LL(0xa3eab01f,0x3ee649e8),LL(0x03050e22,0x98968099),LL(0x12ed1dd8,0x49721509), + LL(0x1e67197b,0x384a1493),LL(0x56c98a4b,0x0d7943cf),LL(0xaf2f7e74,0x23d774ac), LL(0x79355a55,0x2c21ca0b),LL(0x1fad2d85,0xf5e43dea),LL(0xa8d0b6bd,0x57ab8f61), + LL(0xd56cc2a3,0x0e518afc),LL(0xe2dc0d52,0xc6a83b40),LL(0x809ea39f,0x6f5059aa), LL(0x2721bc4d,0x94390dc2),LL(0xfb429338,0x879b35f1),LL(0x14546ddd,0x3891b090), + LL(0xc56f4571,0x7b43040e),LL(0x5fa40c73,0x0b5a0144),LL(0x274f5c74,0xbe5cf035), LL(0x9af86d27,0x9e879540),LL(0xd3c0d8b2,0x77e49fb8),LL(0xc770f9db,0x61fb43b6), + LL(0x92022253,0x4ad13b39),LL(0x71a9d129,0x8396b4e5),LL(0xdce6f688,0x8182898f), LL(0x9bab196f,0xfc0794cd),LL(0x7d4e5580,0x4100be42),LL(0x73474464,0x1417be29), + LL(0x0b909777,0x50d8f53e),LL(0xb81656d9,0x9e5bcdce),LL(0x68e77a3f,0xd3e75c90), LL(0x22b5d762,0x3e315195),LL(0x1511374c,0x1fe3bea5),LL(0x39e43804,0x7dcf6bb6), + LL(0x98b4883d,0xaa84b4ab),LL(0x5003afb8,0xfb1203a4),LL(0xf113ef60,0x49b549bd), LL(0x421a26db,0xb8a534eb),LL(0x4176bcfa,0xae3abef5),LL(0xc9fd2e50,0x65ad7ddc), + LL(0xc9927e31,0x32999234),LL(0xc5f17855,0xcbc9be39),LL(0x91ce524e,0x4189b3bb), LL(0xedfa4e44,0xc72add92),LL(0xfa0ae77e,0x59dfa5aa),LL(0xd3b54994,0x1bc2e1a2), + LL(0x743258e5,0xc7638300),LL(0x4e7252c9,0x508d7943),LL(0x39297969,0x882f689a), LL(0x5a87da5a,0x87d951d3),LL(0x24116564,0x21c31a28),LL(0xbf2be0ff,0x76451670), + LL(0x500e0aee,0xeb561121),LL(0x89b20709,0x1d9b8fb4),LL(0xc9f555ae,0x7ba3f437), LL(0x276c8c91,0xc08e6586),LL(0x6d0f76b9,0x7daa15eb),LL(0x3c2bff70,0x1769cb69), + LL(0x242a43b4,0xbd62fc3b),LL(0xe4ceb019,0x853d3ce1),LL(0x267cdfd1,0x81780739), LL(0x9cd6475c,0x60ecb687),LL(0x48a209f2,0xf3e199ed),LL(0x02dae3a1,0x3cf6b9f3), + LL(0xe7cec18a,0xb0e37780),LL(0x98f8a592,0xaa6eb4e7),LL(0x2d0d06e7,0x0427150e), LL(0x911cd620,0xef4a40dc),LL(0x6e271737,0x71162ad1),LL(0x700d088c,0x82437eca), + LL(0xf1cc972e,0xee1967ba),LL(0xd4eddaa0,0x920e2ab5),LL(0x985d7040,0x5c5ee245), LL(0x3950b6ed,0xb0b435d4),LL(0x364257b2,0x3d814c4e),LL(0xec06a200,0x5baa5fcd), + LL(0x79c5f683,0xea62de1d),LL(0xf682ff65,0x02d1dab0),LL(0xad34060a,0x001e1565), LL(0xbc38c15a,0x09c411dd),LL(0xda6f1853,0x5f688345),LL(0xdd138b16,0x3a60f9df), + LL(0x0bcf4074,0xb21d2687),LL(0x66ea60fa,0xcb9d6c7f),LL(0x86febc79,0x33b4a213), LL(0x9bb71bf2,0x6c5e209c),LL(0x63580404,0x53f871bf),LL(0x0c55bce3,0x4c4a3634), + LL(0x50a5c1d5,0xd05e1b75),LL(0xeda43a63,0xac2eb90d),LL(0xff9c26a8,0x66eba3d3), LL(0x3c837bb1,0xe4f6c13e),LL(0x6e9b77ce,0xee6c1ed4),LL(0xf727fe74,0x7107e1fe), + LL(0x88d7d553,0xbd0548b8),LL(0x4afe5186,0x78876c17),LL(0xa7285f30,0x621d5e10), LL(0x5a304147,0x051e0777),LL(0x334a494d,0x5390f3bd),LL(0x4579e150,0xbebd4f2a), + LL(0xc9672b55,0x0aa436fe),LL(0xaf1550c6,0x52a75c26),LL(0x3858b864,0xd0cbe739), LL(0x0d008d67,0x8f10eef9),LL(0x72b9fc05,0x8f75f104),LL(0x364e6b20,0x143ef589), + LL(0x533b4c98,0x2be2a8f3),LL(0xc7ae49a0,0x982b2540),LL(0xefebfa00,0x546e27b9), LL(0x900dd378,0xb5d294cc),LL(0x3658dbf4,0x3be2150d),LL(0xb34a20e7,0x02874ed2), + LL(0x40cc25ec,0x478a065c),LL(0xada695ef,0xbeaf90cb),LL(0x862215ea,0x4aae42ff), LL(0x165174a2,0x381fc293),LL(0x3d459c99,0xe86a1fe7),LL(0x401dd67b,0xe890d568), + LL(0x82e7aada,0xb46876e1),LL(0xd804209c,0xecca3439),LL(0x1d006b77,0x2c44843b), LL(0x8dd030ac,0x61576007),LL(0xfcb53cac,0x43b0a3df),LL(0xdebeb1f9,0xc5ca915d), + LL(0x0ca9fabd,0x261ec1c6),LL(0xcd7cb986,0xef1e6df1),LL(0x2bbbbc23,0xa827cc65), LL(0xcbd255f5,0xbe5fb899),LL(0x512312f5,0x909568d8),LL(0xa6726a82,0x681dd29a), + LL(0x488ad19a,0x0de34649),LL(0xa836d120,0xaedbbf66),LL(0xc3d2bb79,0x3db458a5), LL(0xf1b23abb,0xa516213a),LL(0x1fb13cf4,0x57cb0ebe),LL(0x2a71fb5b,0xb43b7de1), + LL(0x5a77c99c,0x4136b8b1),LL(0x8ea5e01e,0x7e568b1a),LL(0x63a9ae35,0x218b1234), LL(0xe124bab5,0x31875171),LL(0xccc750f2,0x8b5a214c),LL(0x085b0bf6,0xcda64152), + LL(0x65aa7c4a,0x823a1144),LL(0xd237a179,0x887834cc),LL(0x79b0e325,0xa2884253), LL(0x71245d03,0x05200952),LL(0xefa5fe27,0x6b7e9f1d),LL(0xd8acec2b,0xda6faffe), + LL(0xf6bd56f2,0x8136bac4),LL(0x996005c4,0x13e6d8cc),LL(0xa4d43df3,0xd7ea43e1), LL(0x2f377e2d,0xfc227ad7),LL(0xa8878d26,0x90549e9b),LL(0x4aa1f76a,0xb578b012), + LL(0x4a188fe4,0x42ca87e7),LL(0x5d8e390f,0x4ba3638d),LL(0x9476562a,0xb3568c45), LL(0x0c0a6cc4,0x0c426680),LL(0x3e63129f,0x64115513),LL(0xcec9a6eb,0x711c89d3), + LL(0xd14dddc5,0x923db3a9),LL(0x7dac544b,0xd001ba98),LL(0x692ca6d5,0xc5b16136), LL(0xcdf3aa4c,0x105a9b51),LL(0x52023455,0x909991a3),LL(0xe71eda94,0x8699a77a), + LL(0x20abff43,0xde5a86c2),LL(0x5e0fe305,0x51a3ccb0),LL(0x9ea73b83,0xb76c1d2b), LL(0xf9a975a1,0x9ecfed6c),LL(0xfb0c036d,0x9c0332e0),LL(0x6889bbce,0x4e7d344a), + LL(0xeff8ef6a,0x4f5b02ba),LL(0x165b7828,0xca84ea74),LL(0x6fd1b432,0xc50328c5), LL(0x4166147f,0x56d815b8),LL(0x3da09b08,0xabfb8a90),LL(0x2d02b8d2,0x6b35b6b2), + LL(0x398c7dbd,0xbd664dac),LL(0xd96e1ba7,0xf61eb365),LL(0x65e6672a,0x4063219c), LL(0x8c7ea7dc,0x4bacb326),LL(0x40eb1485,0xcb7c53dc),LL(0xc8724e95,0x75993332), + LL(0xb8af3e69,0x65ace7ac),LL(0x92a2146c,0xc1b257bf),LL(0xcd5a446f,0x5901f7b5), LL(0x8c135291,0xfd4954c0),LL(0x7287802d,0xf9489d56),LL(0x79ca70bb,0xe671da6c), + LL(0x7342afb2,0xcf1f68a7),LL(0xd2662b38,0xb7c95d16),LL(0xb90fd0c0,0xfb1d7741), LL(0x836a9bb4,0xfd7f66be),LL(0x3f666fd7,0x9196236b),LL(0xf2666854,0x97d5dc11), + LL(0x13be0faf,0x53b96191),LL(0x4aad75e2,0x8984caab),LL(0x8c638642,0x5f016b43), LL(0xfe4962b3,0xbe9ab98b),LL(0xf41d7325,0xce94bc4e),LL(0x2727019c,0xa8761364), + LL(0xae07f4a8,0xbb80b445),LL(0x8294ccdf,0xe5881e44),LL(0xad112cda,0x3a4c8e39), LL(0x35d8c72f,0xa5340d8e),LL(0x48955a80,0x47142cce),LL(0x86d4ad66,0xb5ddcf06), + LL(0x2ba33bbf,0xdf4d64b8),LL(0x38311d97,0xb562f723),LL(0x3ae0b587,0x9f7f5f29), LL(0xc4c06982,0x7233a026),LL(0x72ac8ffe,0xe33867b4),LL(0x508eade6,0xf85acdb1), + LL(0x67a2a49a,0x8261c3a7),LL(0x9775813d,0xcb58ffc5),LL(0x932bb91b,0x06c28465), LL(0xb5e56211,0xd07de2e2),LL(0x8f5bfd9a,0x6e0b5a38),LL(0x6f9d74ef,0x1cccc9f7), + LL(0xe3a75abb,0x48de8e6e),LL(0x39374610,0x0ebaaa1e),LL(0x2106e8ab,0x003aaedd), LL(0x92e2817c,0x6ae46c78),LL(0xfbd7d633,0xc52e217b),LL(0xc280871c,0x804476ea), + LL(0x8f4ad647,0x1399bf87),LL(0x2f0e2288,0x81692c0a),LL(0x4c8fbcb7,0x4eb07838), LL(0xe3874f86,0xdb2f862c),LL(0x89f62e6a,0x9e0ee74a),LL(0xb8e8633f,0xa0fef663), +}, +/* digit=11 base_pwr=2^77 */ +{ + LL(0x596b6e25,0x3628c4e5),LL(0xe3c48c5e,0xc4406956),LL(0x2e8ae234,0xe7c4cb00), LL(0x2ed43c07,0xa11d2ed3),LL(0x77b2799d,0xc33b975f),LL(0xcaefccd6,0x3715cc2d), + LL(0x29a801e4,0x98e5a9fd),LL(0xd84bf0a4,0xfa4d3abb),LL(0x2c426bed,0x8f4dc6f8), LL(0x1b83f02d,0x9decebac),LL(0x31afcc78,0x27563177),LL(0x28657c91,0x25efdee0), + LL(0x10bed657,0x44f7577b),LL(0x05089a71,0xd2686801),LL(0x687d749e,0x44e84ecc), LL(0x2ffe47f3,0xeba9b10c),LL(0x977d2767,0xed6470da),LL(0x70a6ec4e,0x7568cede), + LL(0x5fdc4b62,0xb3dfb691),LL(0x55109b96,0xd851f390),LL(0x24e13631,0x55c4dac4), LL(0xb02dcba6,0x12c87918),LL(0xb6a6220f,0x082a25d8),LL(0xcc90ccd7,0xf8abc990), + LL(0xb4ca91b2,0xef95af0a),LL(0xa99a156c,0x693d8362),LL(0x4cc32c97,0x8b1f5532), LL(0xf16e87af,0xff44233f),LL(0x09622892,0x6fffb3de),LL(0x676ed99f,0x9c976523), + LL(0x19ea3118,0x486075b2),LL(0xe8b84a78,0x288a821c),LL(0x603792cd,0x53ce6139), LL(0xcd02301a,0xcc3dfb91),LL(0xafc2d623,0xd6745a56),LL(0x2bdb691f,0x55aa143c), + LL(0x38ddf5e1,0xb104e58a),LL(0x2b17bd48,0x504256db),LL(0x1af21432,0x9e5bdc70), LL(0x364f820d,0x478233b6),LL(0x6c7d0127,0x150c2f89),LL(0xd8d44844,0xdf664b62), + LL(0x15f1c173,0x5dd16958),LL(0xc46a9115,0x3312d6a3),LL(0xfe869bbc,0xc9527a68), LL(0xf6cbcbb4,0x6e5effcd),LL(0x362c0478,0x35bd9c75),LL(0x55bb0376,0x02094198), + LL(0x86c1d92c,0x20c0085c),LL(0xb4122bba,0xbd007e1e),LL(0x25befafd,0xd7c99c19), LL(0xa3ef65e4,0xf07b6cd4),LL(0xcfed174f,0x670355d0),LL(0xd9b990a8,0xff36e219), + LL(0xdc2a6498,0xdc527d73),LL(0x6e1a780d,0x08934ec0),LL(0x70e3a7c9,0xc2577255), LL(0xc59481bd,0x3e9b3c1c),LL(0x33ca9c3c,0x148a477f),LL(0xdf421578,0x5ac5a917), + LL(0x0d689c44,0xecd077c7),LL(0xb91f2750,0xb9946fa4),LL(0xf06d9aee,0x6a48a5de), LL(0x09b44876,0x90d6c760),LL(0x8d0df7fc,0x4768b79a),LL(0x528d023b,0x894c061b), + LL(0xeb1f23e5,0xc155c9fc),LL(0x87fb0d4d,0x30da65cc),LL(0xfe29aaf9,0x39ddc6f1), LL(0x9b7d2157,0xe1559681),LL(0x62eec022,0xe62ee793),LL(0xa973795b,0x6841ff58), + LL(0x8c5f6a6f,0x5041ffe5),LL(0xa1e49e9e,0xb047d430),LL(0xa1870cf1,0x55c67f67), LL(0xfdc4137f,0xa52cc630),LL(0xeeacaf6a,0x708f8900),LL(0xf29a770c,0x4489b888), + LL(0x427f459d,0xa9893015),LL(0x3af11c58,0x29c3a358),LL(0x3159a1a0,0x9fe19047), LL(0x16e111ce,0x3590c6ca),LL(0xb144f41e,0xbb21fd6b),LL(0x48ff3048,0x668bc4a8), + LL(0xcd902ca6,0xf80a9619),LL(0xf2ba49cb,0x75608dc6),LL(0x0d7ead99,0x1ac32280), LL(0x7b3c121e,0x0f8cc5ca),LL(0x541e43fb,0x70c044bb),LL(0x6838ded3,0xfb10ee49), + LL(0x3fe39fff,0x75b96345),LL(0xf45a96d7,0xb4aeb917),LL(0x8932cc8f,0xcc29a1ee), LL(0x682514c2,0xd1317dff),LL(0xa9ef556d,0x5cecce58),LL(0x80d7dfc4,0x51b5fe83), + LL(0x496e1c06,0xef91106b),LL(0xf293c76e,0x28e0bd07),LL(0x504a0bfc,0x42b5d427), LL(0x507248f9,0xe4090019),LL(0x391b523a,0xf41922a2),LL(0xa9b23a0a,0xf8bf6bbc), + LL(0x03c42d14,0x4538e84f),LL(0x125c5ecc,0xc3304e31),LL(0x0528582e,0xdb87c51f), LL(0x63617411,0xd5eb0dd8),LL(0xbab74fe4,0xf4502fb9),LL(0xbda4957c,0xce6a62a7), + LL(0xcc524a7e,0xa34e113a),LL(0x0e326637,0x256f2404),LL(0xe9251c73,0xeb005bad), LL(0xd5be4e06,0x3ac0298f),LL(0x97f2b09f,0xb76eb4f5),LL(0x71ef690a,0x93965d52), + LL(0xc620384d,0x1050467a),LL(0x466e292b,0x8b677cf7),LL(0xe11cabe6,0xf2ac4850), LL(0xb63594f1,0xcec62350),LL(0xe4d91805,0x9afedaa5),LL(0x27dff452,0xd7455a8e), + LL(0x1f700bc7,0x19af1010),LL(0xc8359c70,0x5cd5ad5d),LL(0x70f71fce,0xc8be23e9), LL(0x467d70f8,0x80764bb7),LL(0xf6206a40,0x62069652),LL(0xdd25262a,0x17473085), + LL(0x1ba99063,0x32fe5625),LL(0xdb47d5bd,0xac325742),LL(0x30faac68,0x1621ec3c), LL(0x1c66729b,0x1956c250),LL(0x073aef1f,0xb76bcafe),LL(0x5159e850,0xeea7292a), + LL(0x090f7e37,0xc1a04582),LL(0x3f65d4c2,0x8a13821a),LL(0x10d83d97,0xce32c6c5), LL(0x26738cf6,0xedabac6c),LL(0x1200113a,0xf2615b30),LL(0x4c0415f6,0x7cee46f2), + LL(0x6d603672,0xabe36235),LL(0x4bf4eb2c,0x5f4f1ae8),LL(0xa26e6c0e,0x9a8e44c8), LL(0x167b41d3,0x0944d401),LL(0x76f5c7d2,0xb60f0fd0),LL(0x0f6051df,0x5efdc9a4), + LL(0xd2fd3d8c,0x456e8957),LL(0x5374a59a,0x22dbddfd),LL(0x2a3a89ab,0xbac78cef), LL(0xc10c1d79,0x9c3ba82a),LL(0xa3dd19d1,0x1f935fcc),LL(0x1919803f,0xeb08bb8f), + LL(0x6500b9f4,0xddb31f74),LL(0xe0649288,0xaf383638),LL(0x861c8b10,0xe0dbe97a), LL(0x76552cfe,0xca7ec939),LL(0xfe33f78b,0x7aec0efb),LL(0x11123c97,0xf4548120), + LL(0x53e3f6a8,0x900bdaa4),LL(0x03a79d16,0xbe717d84),LL(0x5f55a064,0x3c99d359), LL(0x7553c946,0xdfd860a0),LL(0xf4133310,0xb4480bb2),LL(0x4f946025,0x6401d83d), + LL(0x1f75cad5,0xa03d7c76),LL(0xf4042451,0x97da3fcd),LL(0xcbdbfbe2,0x6a1b945d), LL(0x7a8cce9d,0x516a95b8),LL(0x30905cc3,0xb16e3a1e),LL(0xfcfc0d25,0x6adefe9e), + LL(0xae7626a8,0x3d86d527),LL(0xfeb4e78c,0xdecc9c13),LL(0xf94a1fd5,0x3ba67e62), LL(0x8e7a588c,0xf5ac7572),LL(0x0fd2201e,0x2b741d8f),LL(0x20073536,0x3be1b453), + LL(0xcba034d7,0xe2b80fd1),LL(0xb0031b65,0x6edad8d5),LL(0x927a36ec,0x3aee1cb4), LL(0xe39b9efd,0xbb88d751),LL(0xc92d3641,0x0129b42f),LL(0xd09b53ac,0x4b434faa), + LL(0xdde24bc8,0x15b64975),LL(0xb1d4c6ee,0x481df832),LL(0xb358244d,0xae6cc85d), LL(0x6e6afac6,0xd54043d7),LL(0xc89eec23,0x50af2efc),LL(0xb2d29f99,0xf5fab1cc), + LL(0xb6f646fa,0x41e0d32a),LL(0x6faa2688,0xec8093eb),LL(0x42550962,0x991ad76f), LL(0x07681a7f,0xcd41aff9),LL(0x0304701d,0x1316c11d),LL(0x133a0046,0xcce7ab79), + LL(0x79249a06,0x34db09fa),LL(0x48f2c060,0xf3356247),LL(0xfc942369,0xe8272db6), LL(0x9849b02d,0x2b844d9c),LL(0x5af3f78c,0x8cc29c86),LL(0x79d64275,0x0bf13430), + LL(0x5c5ea1b6,0xa299919b),LL(0xd6ef8e0e,0xb6184c83),LL(0xf2084644,0x3628b342), LL(0xe68eb3e3,0x017b62a9),LL(0x6f608feb,0x6d5b1e74),LL(0x8218965a,0x1b45f2e2), + LL(0x3529b0e2,0x76707d69),LL(0x60a070db,0x64fb0f14),LL(0x83396a82,0x42737c50), LL(0x3b5d56c9,0x74698c2d),LL(0x284fca9f,0xa8fceed2),LL(0xe3d44208,0x30c3e857), + LL(0xe3bfd480,0x78614fa4),LL(0xa0e38787,0x51ce5be0),LL(0x4d57abb0,0xa92d75fa), LL(0x9fad5db2,0x8d4d97f2),LL(0x1ed2bf25,0x701a80b0),LL(0x3a2db6d9,0x8bac6dfd), + LL(0x3bb9e4df,0x092ecae1),LL(0x1a72623d,0xb57cfcce),LL(0xdac4d79c,0x38943831), LL(0x1340b17f,0x7bf10d57),LL(0x89300f7c,0xac6ec65d),LL(0xf71b46d5,0x1d4109cb), + LL(0xcb8aeb3f,0xa00a19e7),LL(0x18b1c766,0x850b5102),LL(0x6318ebe3,0x3ec2566d), LL(0x42b9bbaf,0x8e70f71f),LL(0xb35f50b3,0x777d9ed5),LL(0xccf46394,0x332280ce), + LL(0x87ceef93,0xf49974f8),LL(0x371f9494,0x06bef26e),LL(0xe9ac3207,0xa5e9736d), LL(0x9df3a98e,0x83769455),LL(0x8dd1f6f9,0x1ccdbfca),LL(0xe399f893,0x8b554d16), + LL(0xefc22c30,0x36752ea8),LL(0xff7e7724,0x104614bf),LL(0x3a74e7a5,0x306ea93d), LL(0x1c1b929a,0xae54fe5c),LL(0x289c4ec7,0xd8ed29e0),LL(0x105ca5d9,0x6153b2a0), + LL(0x29494bd7,0x5e854f89),LL(0x04a28ba0,0x85a970a5),LL(0x394d6453,0x9422f2ac), LL(0x4df93f6b,0x8e084e65),LL(0x9cbe0ba0,0x3963ac8e),LL(0x84ce0da3,0xd8aec4c5), + LL(0x9cb36f40,0xd3d12931),LL(0x36f44ee4,0x5868644a),LL(0x92d4f69a,0xa2106e73), LL(0xa33cf53e,0x2987838c),LL(0xe1a0a530,0x8085e7c7),LL(0x906c8b5a,0xfe92589b), + LL(0x0056310a,0x67d14723),LL(0x9e76d3b8,0xbb0a63ad),LL(0x299a1026,0xe8012f4b), LL(0x9d1ee6ac,0x620ecb4b),LL(0xd16c0542,0xd7f0c277),LL(0xe42209e3,0x8dc7db24), + LL(0xb0f70b40,0xbc708816),LL(0x979dc8d3,0xefe99e05),LL(0xc18443d4,0x80932dc0), LL(0xd18a619c,0xea8bf51a),LL(0x9468aa4b,0xbc18f6ca),LL(0xc3414f98,0xa296c07d), + LL(0xe4242d98,0x6cf05251),LL(0x656af78b,0x3e220300),LL(0x23a061af,0x0fdbbc02), LL(0xe31e3724,0xcd04e892),LL(0x629b6426,0xf5c0c669),LL(0xf4bf0309,0x9499d7ec), + LL(0x685aa7b3,0x0e8c0c01),LL(0xd6abde69,0xf9179568),LL(0x8273d4cf,0x9bab3bd4), LL(0x90b3b1df,0x21b5831c),LL(0xfe3fe362,0xa86800a5),LL(0x244e7750,0x1b1f0560), + LL(0x6ec31a03,0x45e0b747),LL(0xe1072284,0xe2ebe7fd),LL(0xec603fd9,0x9f5c1060), LL(0xf78eec39,0xab1556b3),LL(0x9ad1144b,0xbc3da215),LL(0x3ac47d57,0x84785cf3), + LL(0x49ffcfa9,0x9c91a508),LL(0x609ea085,0xc6f3b880),LL(0x673b6c64,0x9883274f), LL(0x8302014d,0x3b40d18c),LL(0x599dff26,0x9c68a876),LL(0x1d6601fc,0x689e6aea), + LL(0xac0742df,0x80d1dbe3),LL(0x08f7ebbd,0xba614de7),LL(0x9d2a62b1,0x69a683fb), LL(0xc964cf44,0x2c1a9700),LL(0x6bdd35c1,0xeb51e86a),LL(0x02fff771,0xcea21c66), + LL(0x42d0fe7d,0x89b1dfdd),LL(0x85376650,0xa2a98bb3),LL(0x94d35fef,0x4f94ad00), LL(0xbd9991f1,0xe483a5b9),LL(0xce3c5861,0x8a2f4bb3),LL(0x9b125141,0x0fa548d3), + LL(0x914022da,0xec7c9526),LL(0x44ce5265,0x21974559),LL(0x11bbfb98,0xfdc0f3b4), LL(0x077f573e,0x59c23e06),LL(0x4c97db66,0xf09dfcc0),LL(0x56abb779,0x537a65cc), + LL(0x08a4b325,0x11440278),LL(0x0980ea50,0xf848026a),LL(0x676accd3,0x4c3ebe77), LL(0xb9eaeece,0x560720d4),LL(0x0940b1b7,0x78f3fbdb),LL(0x3d9d9db6,0xed41f518), + LL(0xd0762b40,0x7098160c),LL(0xd83f532c,0xb70a2692),LL(0xa861e3ae,0x4d388dfa), LL(0xb6eb9422,0x4c663b91),LL(0x867c33b3,0x16423348),LL(0xa8a6c969,0x291f41c6), + LL(0xd5028ec8,0xd9ad7bad),LL(0x02886a38,0xdaaa8d81),LL(0x2a6977bc,0xa1f8c88c), LL(0xad4366c0,0xad549474),LL(0xae44ac0b,0x36c0cffa),LL(0xeff81937,0x98fbbad5), + LL(0x23a08ab0,0xbe19d7e3),LL(0xf3339f11,0xc5d656d6),LL(0x1c1ecd0d,0xf11fa3f3), LL(0x3cadfca3,0xe59f4653),LL(0xaeb0abcb,0x6901c263),LL(0x46ba47b6,0xe409428d), + LL(0x3e3c4443,0xec64fc99),LL(0xefabc7a2,0x906e0f24),LL(0xcb0e7955,0xd3d83a34), LL(0x2801f179,0x932e43c1),LL(0xecfcc1d0,0xa02e934b),LL(0xea7f5e30,0xfe881c78), + LL(0x96e7b595,0x2be7b0b5),LL(0xc93de911,0x87aed5b7),LL(0xf98e09ee,0xe0574143), LL(0x84396d55,0x7dca05ee),LL(0xbe0f509b,0xf643767c),LL(0xc4d026c7,0x3e216685), + LL(0x4bf02e63,0xbd80154b),LL(0x9eb6f151,0x195227a0),LL(0x3ea46c97,0x07e13a17), LL(0x2363d5e9,0x9dcd5c80),LL(0x48c4488f,0x511f8482),LL(0x6cad16d3,0x7c333567), + LL(0x46373252,0x2b07ac5a),LL(0xa0decd5f,0x90999421),LL(0xb9e96cce,0x96747330), LL(0x5632ceab,0x82d5a2c1),LL(0x636dddf2,0x73828eca),LL(0xf65213f2,0xd6797c5d), + LL(0x64911f54,0x20daab28),LL(0xc600c4de,0x01e50c2a),LL(0x63487592,0x2111ded1), LL(0x8f857962,0xcd1073ae),LL(0xb7ae56ad,0xb4caf0a9),LL(0xd86137f2,0x416f957f), + LL(0x11b1bc91,0x8f563687),LL(0xaa0794bf,0x4e72baac),LL(0x91c1bc51,0x932208a9), LL(0x2ae20dc1,0x5e2bb84b),LL(0xea1e042f,0x598ceb61),LL(0x5004d259,0xd635344b), + LL(0x1a52940d,0xed0255c2),LL(0xe03eca1f,0x4150996f),LL(0x23f5b4d1,0x3aacce4e), LL(0xed0cf35f,0xcb550cd0),LL(0xa494561e,0xea36f4b7),LL(0xebef6e80,0x41cb8c5f), + LL(0x879159f8,0xb73d9294),LL(0x7ca6da8e,0xc9eb2492),LL(0x1844cdd2,0xba2e5973), LL(0x7f9e35dc,0x544261cc),LL(0xea359cba,0xd5e6aff7),LL(0x24c0084a,0x066e78f8), + LL(0xeedeaac4,0xd7604eb4),LL(0xa5c24ee9,0xaf1638b2),LL(0xfa90be8f,0xe4a2346d), LL(0x3004fb1e,0xbd43097a),LL(0xb073fbcc,0x442aafb2),LL(0xfdc31cd4,0x290829b1), +}, +/* digit=12 base_pwr=2^84 */ +{ + LL(0x514a7898,0xe8d780ad),LL(0x4494b63e,0x328ab404),LL(0x8744b64b,0xd2f0e876), LL(0x04b2c586,0xbd70e64c),LL(0xf8a4ba4f,0x5658ddee),LL(0x6ac85e37,0x3219d4c7), + LL(0xa9c333d1,0xfc159a9c),LL(0x40607a08,0x02ba3b00),LL(0xbab9d4d1,0x6912063f), LL(0xdfb380c0,0x206a4fc7),LL(0x9a973b24,0xdaf80877),LL(0xb68651e7,0x95fd7ff4), + LL(0xe8792caa,0x188e1e12),LL(0x02bc1f2b,0x5fa2294a),LL(0x69b0d8b0,0xe3949d79), LL(0x216824ea,0x7d86c141),LL(0x8b1e5097,0x7f37c42b),LL(0x92789c7b,0x08d30e6e), + LL(0xa1ef9f43,0x07cfa020),LL(0x930de093,0xc17f6f2a),LL(0x241ddea8,0x9589ec4c), LL(0xf3c510a8,0xfd97e3b2),LL(0x182c452d,0xbce604aa),LL(0x40027066,0xf22902d5), + LL(0x3293d199,0xc5644219),LL(0xf219caa6,0x393795af),LL(0xd5c761c5,0x7db08017), LL(0x3853454c,0x8d7e1f84),LL(0x29caaa33,0xe327130c),LL(0xb25301f0,0x5f09f900), + LL(0x4e8c95fc,0xf87caee2),LL(0xd0ce4d35,0x631480fd),LL(0x79b8b374,0x4449a646), LL(0xd413863e,0x1eed07c7),LL(0x013cba81,0x0f3da431),LL(0xbc56baf3,0x8cc5bf37), + LL(0x70315569,0x15bb751f),LL(0x676c5956,0xdff9fa34),LL(0x9e87acdf,0x0f196a3c), LL(0xf121946f,0xab7ac330),LL(0xab0ad7f7,0x5e9ba277),LL(0xd0c2d9c0,0x4951ba09), + LL(0x9ed1500e,0x22bf13fb),LL(0x59f5da53,0x67273921),LL(0xfe704a34,0xe840d89a), LL(0xda4b1fa3,0xb4d02cc7),LL(0x2895a3f9,0xba32df4e),LL(0xdea82804,0x6986cfc6), + LL(0x5da22871,0xe56de760),LL(0xa8a67254,0xe13cb688),LL(0xcdcd1ae1,0x3834e31a), LL(0xf18fd6d9,0x9c68e6a3),LL(0xfc21c435,0x695c7ff0),LL(0xe7b0f948,0x99254013), + LL(0xebb3db6a,0x229fd0ae),LL(0x22db0b74,0xae94f977),LL(0xae623467,0xa05744c8), LL(0x8556c819,0x3bbcfbe2),LL(0x60bdc20c,0x39d79df9),LL(0x59b1b053,0xdc97b133), + LL(0xd4d6ee50,0x9f703270),LL(0xa184f3ed,0xd444c71d),LL(0x978e07a9,0x7918b4b1), LL(0xbc8d8792,0x970363af),LL(0x02b0f92e,0x17f5dc50),LL(0xc8c384c4,0x2554094f), + LL(0x2ccd5235,0x9637b2a2),LL(0x27e2ac09,0x75dba5f0),LL(0xbae90634,0xda15c76b), LL(0xe38c9c8e,0xa8374267),LL(0x2c3af338,0x062f336b),LL(0x66c7b787,0x2fa98651), + LL(0x0837c3ac,0xc2a0d764),LL(0x62680588,0x43ba0369),LL(0x5c8c094c,0x8ec53f20), LL(0x5e289f3c,0x0ff5b7bb),LL(0xa5268547,0x8785c02f),LL(0xf5cd3301,0x1f17344d), + LL(0x6269e364,0x8b71131f),LL(0xe5772b51,0xe8bda70e),LL(0x9ec4dbc0,0x76ca9cf6), LL(0x6b091b64,0xe6f8b934),LL(0x8b563cf7,0xda109f46),LL(0x4b3bb11d,0xb109f7e0), + LL(0x0beddcf4,0xf97b7930),LL(0x9c3c946b,0x342f1b05),LL(0x0204a23f,0x4a73cecf), LL(0xe3adbd26,0x15f75cd1),LL(0x41c9110c,0xf09a81fb),LL(0xf5d8cda5,0x88dc3f03), + LL(0x8c96a49d,0x960481f1),LL(0x464ab9fc,0xc6b88ef5),LL(0x8849c44e,0x67e3f698), LL(0x5956b294,0x32068517),LL(0xd22cadb5,0x3705b95a),LL(0x836f6d0e,0x567b470d), + LL(0xcd97cefe,0x441ff140),LL(0x54db07ef,0x659b7aa0),LL(0xfe435aa3,0x8784a63a), LL(0xf04a616d,0x1d970140),LL(0x53af3b98,0xe29b21bb),LL(0x6bb3c12a,0xe6d0f2b8), + LL(0x368f5fc6,0x02132f5d),LL(0x66fdcb81,0x49d6a524),LL(0x9c2be80a,0x05aa3ab5), LL(0xc2500560,0xb7b2f0f3),LL(0x37df204b,0x6359ab2c),LL(0x6d32b4ab,0x25a10b66), + LL(0xf6591fb3,0x03360968),LL(0xc52b20c7,0x16a7fad4),LL(0xb2062758,0x4140a2e8), LL(0xd82f2254,0x905dee52),LL(0x53363565,0x29405a93),LL(0x416c034d,0x1ba1ab88), + LL(0xddd5cfd7,0x8bc8af26),LL(0xc77da82b,0x658c496b),LL(0x1827a062,0xd77384a1), LL(0xfce01201,0xee17f994),LL(0x2d3b276d,0x46605636),LL(0xff5d6088,0x02a31f1b), + LL(0x9e7536a0,0xdb49e057),LL(0x99c35008,0xbcc58d33),LL(0xb687e5e3,0x1f8bc7f4), LL(0x72027d06,0x8638a410),LL(0x2049ced9,0x0c6a070f),LL(0x69ef4623,0xd2729607), + LL(0x3355ca14,0x32aef267),LL(0x848620d7,0x8bbdfbda),LL(0xb0bcc374,0x65eccd58), LL(0x0370119b,0x15730aad),LL(0x349eba95,0xc7d99e64),LL(0x27105839,0xd30d076f), + LL(0x9f258a16,0xcccc32e2),LL(0x535d3667,0x1dacc394),LL(0x81f623e7,0x3f955c62), LL(0x38cb46b2,0xfe599a1f),LL(0x831c4abc,0x88fa6156),LL(0x1708497b,0xb9242cc8), + LL(0xffd874ce,0x9bf9b706),LL(0xa0f974f9,0xf632747c),LL(0xd17df676,0x3f1263b7), LL(0x44df1a8a,0xd7c0eb1a),LL(0x382c181a,0xaaac2337),LL(0xef3d9b5d,0x8cf66156), + LL(0x5bd8a32b,0x1d1d11dc),LL(0x8663b96a,0x57cdb2bf),LL(0xd7aca4c0,0x0983005a), LL(0x50c2f986,0xb3cffa36),LL(0x65f29ae6,0x069eb437),LL(0xec49900e,0xd896f1aa), + LL(0x455dcf4f,0x7152f4c1),LL(0x238cda30,0xa6b6e460),LL(0x2b553cad,0xb4b732b3), LL(0xe87524d0,0xa6d73263),LL(0x378032e6,0x6d48d14c),LL(0x0366d951,0xde0def0d), + LL(0x258e8fa1,0xf3647476),LL(0xd3d8e3c9,0x11f581d6),LL(0x3da389c4,0xf95d4219), LL(0xdd4c30f4,0xfe37e7d7),LL(0xcf2e5808,0x9a47035d),LL(0xbcccbd4e,0xe167952c), + LL(0xf19a3807,0x26816e58),LL(0x34036c34,0xbcdfe39a),LL(0x559a4898,0xa9d96a3c), LL(0x5922653b,0x2be83f20),LL(0xdb63d585,0x31e57750),LL(0x90d8cdb6,0xe25a5789), + LL(0x07016f2e,0x7598794f),LL(0x5b52794b,0x8631b406),LL(0x0473326c,0x4a7a3e13), LL(0x38098ff0,0xfa8445dc),LL(0x224ae6d5,0xe0829d6c),LL(0xa34dbb8b,0xb4ecb6ec), + LL(0x41a5e88e,0x505e3c0d),LL(0x3428e632,0xedcfa76d),LL(0x7378d468,0x1a6892e9), LL(0x3387bfd7,0xcf8f2e12),LL(0xcfedce94,0x75c21720),LL(0x64252690,0x92bd9a2d), + LL(0x7db48f12,0xb3dc859a),LL(0xa7e11cf8,0xf26b3a7f),LL(0x4b8bcf8c,0x38994648), LL(0xf70596d4,0xbe5e497b),LL(0x475a1d46,0xb0e98337),LL(0xb6229496,0x15d374ea), + LL(0xaffa1419,0x10c53832),LL(0xca139934,0x41d4f8c7),LL(0x2df85ac8,0x39e8b454), LL(0x835eedf8,0x8c98e7d9),LL(0xa2d40a9b,0xd931771c),LL(0x7f3156e2,0xf172ea3d), + LL(0x85791984,0x551aa33e),LL(0x5a936719,0xe7900736),LL(0x706f62f6,0x6cf471c1), LL(0x35562192,0xee2f4edb),LL(0x23457cb9,0xa3b54c39),LL(0xbfa40e0a,0x893cc476), + LL(0x84db691f,0x9fdf4d5a),LL(0x1b4ae453,0x9c0411b9),LL(0xa116f967,0x49d4f2d8), LL(0x0b67725e,0x76a1f188),LL(0xc88bd7ed,0xe7d9ffcd),LL(0x68698380,0xc0d8b68d), + LL(0x689cd83d,0xa6a6cba8),LL(0x9cff9c33,0x2f3e63e2),LL(0x86212397,0xf4698015), LL(0x84afdbb8,0xbdda0fc7),LL(0x582808e9,0x03350c9b),LL(0xb37b0173,0x2682ff4a), + LL(0xbc9fa923,0x8bd44537),LL(0x62a20c38,0x68ce391a),LL(0xa248616b,0x22585962), LL(0xe3f811fb,0x5dd9a480),LL(0x8909e98b,0xea0859e8),LL(0xa790c444,0x5f7e1b54), + LL(0x62155fc6,0xb10a93d1),LL(0x0700ee23,0x32320e65),LL(0xc17d480b,0x9eb37705), LL(0xae0b68e3,0x21f11ede),LL(0xda53ea55,0x999286c3),LL(0xa359fe14,0x97dee225), + LL(0x1f39aaa7,0xa59acbcd),LL(0xaaf5a212,0x5386d1a7),LL(0xcbc7628e,0xbda27b0b), LL(0x8a7e5aa7,0x6bd51dca),LL(0x59bbf399,0xb7dbe2e2),LL(0x81cc4d35,0xc15c94bf), + LL(0xaeb9c83c,0x600a3d7b),LL(0x8659b786,0x2b13cbc2),LL(0x5cc8f7f6,0xeac2aed7), LL(0x6bf18dea,0xfc7f4bb5),LL(0x11ea3f69,0xc2d16cb7),LL(0x341cbeea,0x69784d06), + LL(0xbe212759,0x5b823c92),LL(0x0f3cd127,0xa65cc417),LL(0xe67e7aeb,0xd7ba38a5), LL(0xe796850c,0x4e572182),LL(0xf9fc752f,0x36463b09),LL(0x1b698241,0x26827970), + LL(0x7c17865d,0x4cb9ca41),LL(0x7e6cfd97,0x214fe7d9),LL(0x4f587903,0x61d96b63), LL(0xec411bc5,0xb0101b58),LL(0x77f687cf,0x36692f2c),LL(0xcc9bfb45,0xe54d3eac), + LL(0x99723bab,0x121bfab7),LL(0x0884ebfb,0x893ab325),LL(0x6502d3f7,0x0e6788ad), LL(0xb7a108f2,0xb0513c5b),LL(0x4b2eef9c,0xa4f73e16),LL(0x6a483c20,0x342415c6), + LL(0xe752defe,0x39a27b3f),LL(0x9126ae15,0x0d86022f),LL(0x68883326,0xd8ba4a8e), LL(0x3b100c9a,0x715f52c8),LL(0x4addc384,0x336e496a),LL(0x8a6f3e95,0xec21f02c), + LL(0x7769257d,0x2894dfef),LL(0x5ac4bb61,0x2fd58cea),LL(0x708fac5f,0x3cf6d8b6), LL(0xe836e867,0xa76d99fc),LL(0x42a369eb,0x0d863adf),LL(0x15d821ff,0x82c333e2), + LL(0x4042c21a,0x9143b876),LL(0xc737f640,0x0c242403),LL(0xc719ca5a,0x7c397a93), LL(0x022b09e8,0xcf7897df),LL(0x12178c00,0x5c92e3dc),LL(0x4bd00abc,0x4fb2687d), + LL(0x911220ce,0x5750f3ec),LL(0xfb86ec9f,0x58bb4fbf),LL(0x94d00517,0xe33fcc7d), LL(0x5d9eefa0,0xa09ae695),LL(0x9756d5a4,0x3a331936),LL(0xf5c16f2c,0xc6da863b), + LL(0x07532fc8,0x05c5e926),LL(0x9d0d96bb,0xfe0c58e9),LL(0xcff62c16,0x98056d33), LL(0x346a4ec2,0x77cbe60b),LL(0xf43fd4c2,0x40989b21),LL(0xfd0645ec,0x1a3c47ee), + LL(0x5f51dc39,0x91089174),LL(0xb5a23122,0x7cbbe6a0),LL(0x8c2818e7,0x83b5abb0), LL(0xb9e654d4,0x24081e1a),LL(0x5ba06cb3,0x63528af7),LL(0x69d7dcc6,0xf570710c), + LL(0xb34b5890,0x583afeef),LL(0xc813cc91,0x6095edb9),LL(0xd3c329f1,0x166a5e48), LL(0x33293a13,0xee878e89),LL(0xeb1ad806,0xe6c0325e),LL(0x210c80b5,0x8add3663), + LL(0x3811f849,0x6b9517b7),LL(0x9d8bad91,0xd0aa5e75),LL(0x3160bda4,0xf70a8172), LL(0x916ce0d5,0x24b52ea7),LL(0xac05f7b8,0x13da7006),LL(0xbd773df2,0x1213f1bf), + LL(0x72d96f4d,0x22b2b776),LL(0x98ecfb1e,0xb0c964b2),LL(0xba7dd824,0xed9d0828), LL(0x869c0f63,0x6faddff3),LL(0xf8b13355,0x2b409d2c),LL(0x31237c9a,0x53431320), + LL(0x72a9170c,0xde41027d),LL(0x3a82f137,0x40f7b012),LL(0x099b7d4a,0x343a36ac), LL(0x2606178e,0xbe82d933),LL(0x19c93f1e,0x741f76ea),LL(0x27fd9465,0xd13d492f), + LL(0xf2518396,0x9b09dc67),LL(0x14669921,0xa79dc92b),LL(0xbea82992,0x0eb149ce), LL(0x13c60cbc,0x62ff22de),LL(0x6141a946,0x610724f4),LL(0x0793021b,0xf57b976b), + LL(0xc699a47f,0x0e516c18),LL(0x5d6f8d8f,0xd719adfb),LL(0xbdb43f6e,0xf067a17e), LL(0x0b490085,0xce5eb760),LL(0xcfebbb1d,0x15113e6a),LL(0xee6d2951,0x2194fd0a), + LL(0xd1abb57b,0x0bddf14e),LL(0x3416ad68,0xe0e768c2),LL(0xc4534e1b,0x0326b07d), LL(0x3da9b4be,0x796b6192),LL(0x474dbec9,0x85976f8b),LL(0x64001998,0xe1b892ef), + LL(0x3ddc43d1,0xb387d9c2),LL(0xdcc58653,0xd879f295),LL(0x316adb79,0x680e4335), LL(0x771da848,0x6ebecfdd),LL(0x98e7ae92,0x21e44da1),LL(0x2a3e21ba,0xf7db9238), + LL(0x6d480c11,0x7be805ba),LL(0x5ed87195,0x657824d5),LL(0x152a427d,0xad9bb855), LL(0xd479e14d,0x54fa5b2b),LL(0x967d66b3,0x393ff9fd),LL(0x1f8cde27,0x2e20e269), + LL(0xced8a78d,0xbc607c2a),LL(0xa8eed88d,0x191f87df),LL(0x5861efa0,0xae1d6b52), LL(0xcafa53fe,0x57c60dc3),LL(0x67c35922,0xb27b8932),LL(0x9b29125d,0x0fa6246f), + LL(0xb808e2df,0x50a069c2),LL(0x9a88a445,0x84e557c0),LL(0x38d713c5,0x27e6460d), LL(0x3c86b058,0x7b410b71),LL(0xb1b113ec,0x93fa53b8),LL(0x7441167f,0xc634cba5), + LL(0x282c12ce,0x1e671bc2),LL(0xa604f3aa,0x39b311ce),LL(0x78a148f0,0x98bd47d2), LL(0x371a0da8,0x5e27388b),LL(0x0fd9e315,0xfa513fbd),LL(0x34376073,0x611e38e3), + LL(0xb58100d4,0xd5ebd78f),LL(0x6e9f40fc,0x274fae3f),LL(0x8942e656,0xc1a74338), LL(0x46604337,0x6c53a23e),LL(0x660df2a9,0x2ed93bd4),LL(0xbf37f8e3,0xdfa53649), + LL(0xa0632b8b,0x02511435),LL(0x3a69fc4e,0xdf7abcb9),LL(0xd9e52727,0x6717e277), LL(0x929a903a,0x990834f2),LL(0x80c4abbb,0x8b89a584),LL(0x94e5ac4c,0xd57fcb53), + LL(0x6acebef8,0x7293af18),LL(0xdc7aa8d3,0x12646628),LL(0x409608e9,0x89165145), LL(0x01ea6183,0x9086b84f),LL(0x78ce39d6,0xc508268d),LL(0x6ff226ec,0x1d30f560), + LL(0xdd6833a4,0x49bf690d),LL(0xa575c955,0xf290aff6),LL(0x7bfea4f5,0x0e0b673b), LL(0x8e59e02b,0x3fa210fa),LL(0xbbfb09d6,0xc1cecbf6),LL(0x670a5aa4,0xa76eef60), +}, +/* digit=13 base_pwr=2^91 */ +{ + LL(0x01c06ca9,0xa1498bce),LL(0x7a08bab0,0x21c01611),LL(0xca17bd74,0x2c85a0b7), LL(0x37d0f77a,0x7b903162),LL(0x6e81e65b,0xd14898cd),LL(0x218cd115,0xe0ed1f2f), + LL(0x1731d3e6,0x78c6c92d),LL(0x7d3b6343,0xee373594),LL(0x614f0ed3,0xc8e90901), LL(0x680df68d,0x9dd54b4b),LL(0x983f94c5,0xd0c3cba6),LL(0xe9dd9140,0x80983823), + LL(0x9da2d6f5,0x3de0421a),LL(0xe135d7df,0x933d779e),LL(0x45fbc83f,0xdcc10777), LL(0x552833c4,0x437d64cc),LL(0x581bf745,0x616eb481),LL(0xaf9d7fdf,0xc3d7614b), + LL(0x4b010379,0x72673639),LL(0xb40b8ccd,0x784d95cd),LL(0x32191a11,0x3647d089), LL(0x83ad425e,0x1383335b),LL(0x5ed3ff39,0x3c5b0250),LL(0xa814df0f,0xf1f78c9e), + LL(0xd81332fb,0x48ee4921),LL(0x75c4a231,0x62f08af2),LL(0x52b5815b,0x81cee592), LL(0x47ff2530,0x5ee938f3),LL(0xbb73d595,0x9a58ec1e),LL(0x29b94b64,0x473405f4), + LL(0x0f89bcf3,0x423677b2),LL(0x3746d402,0xaafec85e),LL(0x8cec15af,0xb61ce3f8), LL(0x5ba02dd3,0x7618d63f),LL(0xc28a6515,0x4f774238),LL(0xe74d6f15,0xf6a3b5c5), + LL(0x0a141a66,0x695b4444),LL(0x09e7251e,0x9b502847),LL(0xa2883803,0x52285abb), LL(0x5f2f7fb4,0x71858bb4),LL(0xa5943828,0xbf5eef5c),LL(0x81bbe54b,0xb29d0c74), + LL(0xaa092e25,0x83536ebb),LL(0xb4e5d213,0x4768e469),LL(0x8289c98b,0xb540b589), LL(0x080c0531,0x350a6e40),LL(0x590b38c3,0x94d12807),LL(0x40fe5f65,0x83badade), + LL(0xe86caac6,0xd77e33c7),LL(0xb8ead427,0xd1935c95),LL(0x5183cc83,0xde18e630), LL(0x261521a1,0xbdcd00f1),LL(0xc82809bb,0xbd18e1d9),LL(0xf960fc2b,0xe142711a), + LL(0x1da8931c,0xdfe9e3bf),LL(0x6e1829f7,0xeb943b45),LL(0xe6eeee44,0xa1c817bb), LL(0x4fdd6559,0x0f852c30),LL(0xa27f2549,0xd9ad9b4d),LL(0xfb111f65,0x266fb914), + LL(0x917fc712,0xa20f882d),LL(0xf7566719,0xd05d7f13),LL(0x12c11721,0xd5c196b9), LL(0xc566b104,0x3eba0c8a),LL(0xecae1039,0xe301bd90),LL(0xfb24c348,0xd64eb499), + LL(0xb4738f00,0xa0c38991),LL(0xe4dd35c2,0x63bc012b),LL(0xf72495e7,0x980e89b0), LL(0x68ad6dd8,0xb530252c),LL(0x2642e8d1,0x35d6d8ef),LL(0xc235ef4f,0x1309691e), + LL(0x7262cd15,0x64a61d20),LL(0x04da445b,0xf2916951),LL(0x4ed50bd4,0x3beb5815), LL(0xe0204220,0x35638863),LL(0x69f21c08,0x8929e2ab),LL(0x14756735,0x5f273190), + LL(0x819c11ec,0x47befaa3),LL(0x90deb435,0x3bcfa2d2),LL(0x19569f95,0x4caca5ba), LL(0xd48453ad,0xbc78fd0f),LL(0xfa2100f2,0x7e4c3646),LL(0xf96c19da,0xc75a1a82), + LL(0xed646507,0x6e45f6c3),LL(0x86558b67,0xae0601e1),LL(0x3ccec830,0x20634c8e), LL(0x7c87c192,0xc3fea47e),LL(0xb66a402d,0xf14aba2e),LL(0x5bb3f7e1,0x8dcecf35), + LL(0x9751dc6a,0x33396804),LL(0x1c107cd8,0xc56b5879),LL(0x5b41235b,0xd8a41e90), LL(0x35971626,0xa956148b),LL(0x79168709,0x185bfe69),LL(0xeba02351,0x32829b76), + LL(0x39f2bf71,0x28f979a3),LL(0x53316bad,0x212c0931),LL(0xc1f8d9f1,0xf02710c6), LL(0xbb871267,0x6e6cbf36),LL(0x9c425ef5,0x11c79382),LL(0xb94f8b01,0x6ce18819), + LL(0xbd5bf1f3,0xd9a44d46),LL(0xda2c3d1d,0x662f70a1),LL(0xb13563ca,0x43d5374b), LL(0xcbcce692,0x8f4ad04c),LL(0x0c72e84b,0x3151ee4d),LL(0x5accc2ed,0x50c80454), + LL(0x74697919,0xdce044f6),LL(0xedbef994,0xfce0b586),LL(0x8b92c529,0x0d47e307), LL(0x6ac46081,0x64904019),LL(0xad80c124,0x6f52cad2),LL(0x996d42ee,0x02f7e44d), + LL(0x6aa2e142,0x257eae2c),LL(0xba53beb1,0x747a167a),LL(0xa8f5eba2,0x3b3ac5e3), LL(0xb6fa720b,0x6c6ee79a),LL(0x3a7bd99a,0xf6dc5ff5),LL(0x1a36d3b5,0x2447970d), + LL(0x7b6c6e86,0xd717e889),LL(0xc64d98d4,0xb808d76c),LL(0x7f8c0bca,0x9a06f942), LL(0xb253f5b4,0x58b8b04b),LL(0x0c103d51,0x82d27325),LL(0x1810ceba,0x7dd6d9a6), + LL(0xa27bfff3,0x0a1f1bb3),LL(0x3f63695b,0x3ba841c4),LL(0x4dba6a84,0x0e4c6ef4), LL(0xc6d82a09,0xe283f321),LL(0x78f4a01f,0xd8bcb661),LL(0x504f48b4,0xf527ac07), + LL(0x750dfc07,0xade1c74f),LL(0xa0611072,0xb8acc3bd),LL(0xad13e407,0x3886a58c), LL(0x0011bec7,0xdf6dd4c5),LL(0x350b7b68,0x01d96ff3),LL(0x76a879ea,0x2be73b43), + LL(0xca38d7cf,0xc1eca6c4),LL(0xe4217860,0xed1d926b),LL(0x0c476828,0xffc2433d), LL(0xf0c18d59,0xee65a719),LL(0x0ca1dca8,0x6a00e59f),LL(0x10811b54,0xc137d01e), + LL(0x66442ac3,0x74f38545),LL(0x1ecdd1f4,0x4947a37b),LL(0x5407e0c6,0xdaf73a23), LL(0x14140508,0x1b6175f0),LL(0x7b23a861,0x628c409f),LL(0x60c7c2f4,0x2550fdb1), + LL(0xd23a25b8,0x0e026ec7),LL(0x2b9ed7bc,0x435dbf9e),LL(0x027cd584,0x16c87162), LL(0xd7f56db4,0xa3ab5d25),LL(0x7f477034,0x8c9fa8ef),LL(0xac46696a,0x2eb3909a), + LL(0x7bc6b191,0x6f288477),LL(0x72cf52e6,0x7857879c),LL(0x4438a334,0x9ccb9b67), LL(0x0110d13e,0x016f2b86),LL(0xa623a4ce,0x7355fff7),LL(0x88c1b0b9,0x1dd555dd), + LL(0x543e3d58,0xecc48b76),LL(0x63049aab,0x251ea3ca),LL(0x1753f7aa,0xd091864f), LL(0xd65af237,0x0fd2d1af),LL(0x0ac895b0,0x70403da1),LL(0xa89e9386,0x6c3bb93a), + LL(0x48e9bf38,0x4d1df04d),LL(0x36a1b91c,0x4d05792d),LL(0x6405251a,0xd07633cc), LL(0x3ef7d87d,0x0077621d),LL(0x0c74697c,0xb35da825),LL(0x2698f465,0x521ee502), + LL(0xf4454069,0x2f0af2e4),LL(0x0799d8f7,0x1c6595ad),LL(0x57d14169,0x8cc1b16b), LL(0x660a073c,0x6ef9a078),LL(0xcad9cb79,0x4d04db63),LL(0x2d73e47f,0xbd1843d6), + LL(0x9838b1cc,0xc34b6a45),LL(0xe4d57b01,0x37705ff3),LL(0x8dde6264,0x7b15a361), LL(0x7bf8c818,0x22c4dd55),LL(0xfccc811a,0x404bd481),LL(0x601ccc8a,0x6f6b37a1), + LL(0xd8ecaa77,0x033ee5b1),LL(0x59bdb383,0x4a6fbaa6),LL(0x991bd043,0x98d656cd), LL(0xc754b213,0x489d8614),LL(0xf6bcf12a,0xc57d54b4),LL(0x1023de85,0xd8b7ed83), + LL(0xdc84066f,0xcc88e0d0),LL(0x112d5d04,0x563deb7a),LL(0xe6715a55,0xcf71acb5), LL(0x29268b7f,0xf49a247f),LL(0x5b36fd67,0x8e53cf14),LL(0x06da22fa,0xa4093a91), + LL(0x2dfb4f20,0xfbe6fb96),LL(0xd6946271,0xadb8875c),LL(0xc95a344b,0x50528b99), LL(0xd2627469,0xd7442d08),LL(0x47e943cf,0xb8b049e1),LL(0x65cd148f,0xa47b0b3a), + LL(0x50579b69,0x1cd28588),LL(0xbb9f9f10,0x38acf2f6),LL(0x0b35f238,0x67eaec1e), LL(0x00a3119a,0x72fc9c42),LL(0x39f88c39,0xa1cfc76e),LL(0x14c7fda2,0x67b702d8), + LL(0xeeafce5a,0xe782ecf6),LL(0x5eccfbde,0x16b562b4),LL(0x2a70e93b,0x23a8eaf5), LL(0x64855ed4,0x0fb734f6),LL(0x2bd5f2b8,0xde37f9b5),LL(0x959a5858,0x3d01215d), + LL(0x667d4abf,0x5a4a7d0c),LL(0x68d13116,0xf4f05c66),LL(0xdb565813,0x09cc67cd), LL(0xb34d0f55,0x53d0e496),LL(0x5a179043,0xa4f11437),LL(0x39b26f7e,0xf4ed66b3), + LL(0xbf723512,0xc670ce6a),LL(0xb17e4ba3,0x5bbf65a7),LL(0x16e38386,0xb5ddc6ff), LL(0xb0dd0439,0x9c28d121),LL(0x66dfee98,0x06d89034),LL(0xf7d33983,0x547138ac), + LL(0x92a04c6b,0x8503bf04),LL(0x008a5092,0x8761e5ef),LL(0x13902f4b,0xfa9bfa8d), LL(0xd7c9b5cb,0xbc37af37),LL(0x9f7a27b8,0xcfb05e37),LL(0x1d5b124f,0x81418e4d), + LL(0x03353c76,0x0d57da43),LL(0xdd7feecd,0x3f36caaf),LL(0xdb56957c,0xdcaadf69), LL(0xb652acff,0x2c36792e),LL(0x4213d519,0xc5d03a97),LL(0x98734fe1,0x11c6aa92), + LL(0xf714efdd,0xeca42e87),LL(0x9655a0c3,0x9d65e8e3),LL(0xe741a619,0x5be55b09), LL(0x1066c180,0x53b47016),LL(0x805e1ebf,0xe9ddc1b3),LL(0x79a748ef,0xc1057ad9), + LL(0x66d0174b,0xb2d62622),LL(0x37c05be2,0x10a0512c),LL(0x63e47f0e,0xc2eeab52), LL(0x6f08ceef,0xce6e28b5),LL(0x2f1a5a13,0x7716afb7),LL(0xc55ab74e,0x83942c61), + LL(0x6539037b,0xcef92b51),LL(0xdc615b4b,0x04a4f1e8),LL(0x49e546ee,0x0d56014a), LL(0x94d44546,0xbc1437a1),LL(0x147375c2,0xfb1e3aca),LL(0xdfc71c1d,0xb0f2abf0), + LL(0x44424b7c,0xb5679c9d),LL(0x36c89cc1,0xde54d53d),LL(0xd9a702ed,0x23252ab5), LL(0xf775d90f,0xdccb09e3),LL(0x15cac902,0x28e652e9),LL(0x08ca0b18,0x193bd66a), + LL(0x7abafda3,0xb81c2e5e),LL(0xbe90ac49,0x34a1192a),LL(0x9d1512b5,0x5d6945d3), LL(0x9cb6c182,0x0184a059),LL(0x868f5d65,0x329ea8fd),LL(0x66410f60,0x03783cc2), + LL(0x1f3d38ad,0x8524ab85),LL(0x3ad4fe62,0x58a7ccec),LL(0x37ece281,0x6a00a442), LL(0x16a1a2ac,0xfa3d6fc3),LL(0xb727b625,0xf6fc8af9),LL(0x4c3b3361,0x42699573), + LL(0x22414f66,0x2f55c436),LL(0x512968a1,0x8869eec6),LL(0xd98ecda1,0x925a1ae7), LL(0x9fb914fe,0xf112e9e3),LL(0x60e41857,0x16496689),LL(0xc8f300d8,0x1f93ed91), + LL(0xc8208043,0xb3e2c2fc),LL(0x7f1acebb,0x19f61c61),LL(0xc1e96d31,0x1ff2f9dd), LL(0xf44de6f3,0xd956fdfb),LL(0x0685ff3a,0x101656c8),LL(0xb98bc38c,0xe725cebe), + LL(0x354b318c,0x77e2edcd),LL(0xe1580079,0x9ac1cfbd),LL(0xedff64a0,0xc3c197e8), LL(0xaa113966,0xa2da7af6),LL(0x0aa54ff6,0x8f9df560),LL(0x88555266,0x5aaaa100), + LL(0x4885a4fa,0x01e3a2fe),LL(0xc469f05d,0x4aea2d91),LL(0xb3ea443c,0xf5947f39), LL(0x34d7b0fc,0x6f22b634),LL(0x93042129,0xc843cc3e),LL(0x2f14f438,0xf884bf04), + LL(0xa710c7fe,0xa0a19c29),LL(0x3057ad61,0x7fabfd39),LL(0xfe6ff084,0x94e9125d), LL(0x100a8cf8,0xd4fdf49a),LL(0x55eac3de,0x1839418e),LL(0x1aa6a2ce,0x59253c55), + LL(0xee768081,0xe01ff1f4),LL(0x144d7219,0x083342a6),LL(0x51fe8705,0x34cfa650), LL(0x75c5938a,0x499516d1),LL(0xf2c8f347,0x6350e5fe),LL(0x73f4eb28,0xe030f2a7), + LL(0x035b04cd,0xcd5808db),LL(0xc6f54f17,0x93d6ac3f),LL(0xbae00379,0x56d72b91), LL(0xc7448e15,0x211f276f),LL(0xaecaad32,0x979d0736),LL(0xe64e8a11,0xe581cfa6), + LL(0x2904cb1e,0x94ac596c),LL(0x626952e7,0x53e1e42d),LL(0x775ae6d8,0xcc989b89), LL(0x44343d68,0x0fb5c605),LL(0x0f175322,0x87608356),LL(0x6db60843,0x182f1dd6), + LL(0xe8867c7c,0x0ad3c4a8),LL(0x103cb06f,0x5479684c),LL(0x14756b01,0xe2961491), LL(0x9dfc5ad6,0x5207d54f),LL(0x3c865a45,0x184260a4),LL(0xbea2f905,0xd1158cb4), + LL(0xc78b0c7f,0x9de51643),LL(0x31357d76,0x1a3b3589),LL(0x60f16852,0xc2175848), LL(0x4d90d2d7,0x5eb827a7),LL(0x79abe6d4,0xe83be898),LL(0xb0974ddc,0x7c03935b), + LL(0xd54dae93,0x7ae1a72b),LL(0x0144c969,0xd4c8e333),LL(0xac7744c4,0xb3b92e3c), LL(0x751865f4,0x81a6f8e6),LL(0xb9b51064,0x11e0f64a),LL(0x8cfce4fc,0xedbcfd08), + LL(0xfe811795,0xe33545de),LL(0x33edeb4a,0x663a0fc4),LL(0x23e2eaeb,0x0fb9d61f), LL(0x99b52602,0xf136b9ba),LL(0x766a8136,0x6a15e5ae),LL(0x05333f8f,0x5a1a79b6), + LL(0x5a85d6be,0xda1cb3bb),LL(0x835d8007,0x28e30bff),LL(0xef4cb0ee,0x6a8c3d85), LL(0xd6781054,0xe8517460),LL(0x48b0c592,0xa0234065),LL(0x4d7b7aa5,0x5cf1f874), + LL(0x9e511ada,0x007bf10f),LL(0x8687e7c5,0xc5edcfb1),LL(0x047a613c,0x507ca4c5), LL(0x8f117e83,0x3c8707d9),LL(0xe75c9755,0xda6e38e5),LL(0x6dbd6711,0xb3ffd623), + LL(0xb9e2ce9a,0x8530669d),LL(0x020d181a,0xffc85696),LL(0x02c1a8c3,0xfa2f2979), LL(0xee4a1a98,0x989146d8),LL(0x76ac6289,0xc3f98bc9),LL(0x76d28437,0x1d491a8a), + LL(0x3fb6cb28,0xf9d04b0c),LL(0xbc28bce9,0xf246e5c6),LL(0x48fd1173,0xd3d455ed), LL(0xe3e9d40a,0x00ea713a),LL(0xf5af8e29,0x4d4c9262),LL(0x9e95cf17,0xd5e49303), + LL(0x685350ef,0x9f5fe067),LL(0x788ffe11,0xe22b2f70),LL(0xe6ff086f,0x74d4e6e8), LL(0xa937a949,0xef631c8e),LL(0xd122a378,0x707bb8ff),LL(0xff54817b,0xc1ee7dda), + LL(0xfebc7fc2,0x328f6f5a),LL(0xd933fdc0,0x8333e284),LL(0x51ee741b,0x9c135c87), LL(0x90923a1a,0x856760be),LL(0x44a46bc0,0xbe7905c7),LL(0x77415a22,0xbdc7248e), +}, +/* digit=14 base_pwr=2^98 */ +{ + LL(0xd646c05b,0xd1893bfc),LL(0xa963fee4,0x4e61d76b),LL(0xbdcc95da,0x71adc08a), LL(0xdf5decf2,0x42f481e9),LL(0x0872ca53,0xbdfbba8b),LL(0x21ece5ce,0x0eabd6ac), + LL(0x45d4fc03,0xb2367fe3),LL(0x75cbdc62,0xb115bdad),LL(0xef8b952a,0x07522180), LL(0xfd23c45d,0xc0448864),LL(0x87eb202e,0x8c068193),LL(0x313c2e61,0x7fe87505), + LL(0xf2ede850,0xbfa39552),LL(0x93cab795,0xa40a845d),LL(0x09e97bd9,0x56ca4f4e), LL(0xccbdb84b,0x207a1e71),LL(0x1893a956,0xd0ce1e11),LL(0x84c34b10,0x7a22a433), + LL(0xe404586f,0x48becb6a),LL(0xf5d6372a,0xa136232d),LL(0x87ba83a5,0x438af2bd), LL(0xf4e459ff,0x37075ede),LL(0x582d1ce8,0xaa42aae7),LL(0x0daeb82b,0x973dba33), + LL(0xc40861a3,0x48bc98ae),LL(0xefd9a196,0xc100f037),LL(0x052eb352,0xda4029f6), LL(0xef34169d,0xd61b4933),LL(0xa357cc0b,0xcedde9cc),LL(0x4d006fcc,0x8983c01e), + LL(0x92f2a1c1,0x31ad5f19),LL(0x924bcb08,0x7c7a6319),LL(0xd0c36056,0xcbee249b), LL(0x5ac4f6eb,0x63135518),LL(0x37f8cd7c,0x8b2aaaed),LL(0x0b9bcd79,0xe71c855a), + LL(0x5828ecb9,0x1f12da90),LL(0xbed745a9,0xbd094b68),LL(0x59a321b0,0x27d4a84e), LL(0x71683549,0xd05c2695),LL(0xc9c9f2ae,0x56e4dcf2),LL(0x199abda7,0xdfff6393), + LL(0x576fff20,0xc28ae07c),LL(0xb9024805,0x88ed10b6),LL(0x851ed43d,0x81944c6a), LL(0x158549cd,0x31192f87),LL(0xff08eac3,0x36dce6e4),LL(0x9ffacd59,0x7837d3e2), + LL(0xc8329917,0xe820d2e4),LL(0xed56083c,0xc343156c),LL(0x67c118a9,0x60116d83), LL(0x699583a8,0xbf2c1598),LL(0xc03c3370,0x77da3db5),LL(0x88522e50,0x35b0e741), + LL(0x3e4cf4e3,0xcb945a8b),LL(0x45fbb1c3,0x1ac37aba),LL(0x7e016a40,0x05b3d362), LL(0x93c0799e,0x175cb9f3),LL(0x9102d347,0xad1068c4),LL(0x8c6b55d4,0x01200565), + LL(0x1fcfd55e,0x6396a275),LL(0xc76eb5a2,0x26c5c201),LL(0xc49cc617,0x9eafc039), LL(0x62fdc2b8,0xecf4f6fd),LL(0x73f3babc,0x795af8b3),LL(0xb456ddc8,0x9d6380f0), + LL(0x00481dbf,0x8435b4c8),LL(0x586fec04,0xd68ed151),LL(0xbad5a7ec,0x904b3a7d), LL(0x755a599b,0x5ac0c68f),LL(0xeed07240,0x8202bd5e),LL(0xc2111eb1,0x50108f7a), + LL(0x64114206,0x7966f061),LL(0x08252097,0xc7e5a500),LL(0x4a27d84f,0x1efdcfb5), LL(0x992fb0b4,0x05327d63),LL(0x109f651f,0x33c1800c),LL(0x4858bb75,0xe90ccb5c), + LL(0xdfd79c9e,0x3f05f6b9),LL(0x94808d4d,0xb0db9df5),LL(0xda56ea30,0x170d0bfa), LL(0x46ea52b5,0xfc08aa5f),LL(0xd7247824,0xf5eb81e2),LL(0x26357344,0xab23fe73), + LL(0xb37efb0c,0x8d9e1ced),LL(0xd7b33644,0x3b126789),LL(0xa25195f0,0xee7f591f), LL(0xe6380d90,0x5572f635),LL(0x6381422f,0x570f7d77),LL(0xe69759c5,0x44378d7d), + LL(0xa08babdc,0x1b30b2aa),LL(0x3cc52896,0x9ad9a870),LL(0xd7cb91be,0xd1afe3d1), LL(0x4a5535b4,0x1f838c05),LL(0xcfab1e86,0x86b14aaa),LL(0x6f77d53e,0xe64af8a4), + LL(0xebdc38c4,0x2028f1f2),LL(0xf31ac53e,0x534fc79a),LL(0x1a0e531f,0x987d5d41), LL(0x76fd27ac,0xf9d7d8c3),LL(0x40a77dbd,0x930da5d5),LL(0x57ef7f4f,0x2c9fae32), + LL(0xdb6f852a,0x7232dd8f),LL(0xddea21cd,0xcacd16a9),LL(0x21f8ec9e,0xf04c4671), LL(0x4688eec7,0xfec90470),LL(0xba277998,0xd49d9514),LL(0xb4cf1ab4,0xbec829aa), + LL(0xe594415f,0x6fb54104),LL(0x2c3a2383,0xcd39d8af),LL(0xe44a8388,0xd50673e0), LL(0xf14f72d0,0x55137ed9),LL(0x1abb3c7b,0x4475a031),LL(0x246ece39,0x73e9fa03), + LL(0xee6222b2,0x7017567a),LL(0x03448302,0x603051f2),LL(0x5aaa55f0,0x8e7a299a), LL(0xc61d2cb5,0x6a43ef05),LL(0xd1923efe,0xc780996b),LL(0x29e3847b,0x71c3dd7d), + LL(0xfdc2519e,0x34bff2b3),LL(0x4e5b30b6,0x55e13340),LL(0xdf3b31e6,0xf0159d7d), LL(0xffa85b11,0xe041606a),LL(0x437094a8,0xc9438445),LL(0x8b1d800e,0x13df929b), + LL(0xdf21b623,0x0e2925cb),LL(0x9010bc70,0x24051cf5),LL(0x891c2a68,0xc2176b95), LL(0x01e795a1,0x991bf219),LL(0x30ef7d3d,0xc069d0c2),LL(0x1bc05ca1,0x6021da66), + LL(0x1e52bf74,0xfcf4cf04),LL(0xd74c9731,0xd7cb6e14),LL(0x7e857c02,0x7628ac80), LL(0x126c5b91,0x0cc391d5),LL(0x7e2d15bd,0x731062b4),LL(0xabdfd049,0x1e87cea9), + LL(0x363f0203,0x10006c7d),LL(0xf63971b4,0x51ea9151),LL(0x80734bc5,0xd951b96d), LL(0x89a7c10f,0x1d164750),LL(0xcae9c4ae,0x488652d2),LL(0x185669d2,0xb4ca6a36), + LL(0xbb8f19e9,0x6e84424a),LL(0xc9d19687,0x8b9aa75e),LL(0x0b88d08b,0xc120a35c), LL(0x2a8cf8ec,0xdeeb61da),LL(0x6bebce59,0xfcc8ccf8),LL(0x8de4133a,0x679e7f58), + LL(0xe3c5a444,0x0f3eb897),LL(0x5751461e,0xce575c28),LL(0xdc20e60f,0xe8d1e5b3), LL(0x7d07536e,0x9dc103d7),LL(0x2f685999,0x86a2a40a),LL(0x47c6f8fe,0x15ae9ff4), + LL(0xaa9b291a,0x885babc0),LL(0xfedd2942,0xe3f51080),LL(0xb5d39214,0x304ccff4), LL(0x0a3b3582,0xf107db2f),LL(0xea86a325,0xe2fa620c),LL(0x6b20d46f,0xa0b718ec), + LL(0x72969183,0x9d14762b),LL(0xfce848f5,0x6b2baf0b),LL(0x968f6133,0xe7660ec7), LL(0x8299819f,0xc6ee65e4),LL(0xef1b9b29,0xb57828af),LL(0xa50176ea,0x5b1c99f3), + LL(0x62f3aae5,0xc35057fa),LL(0x46f3c966,0xa5437e70),LL(0x8864f29f,0x6bc5d22a), LL(0x86323fd9,0x143c464b),LL(0xd1570c61,0x30852173),LL(0xb5b6f3d4,0xc188ba63), + LL(0xc8406bdc,0x8b26d419),LL(0x3fafc9be,0xc0c95def),LL(0x5d5eb753,0xcd58ca48), LL(0x57e8a8a8,0xb937d969),LL(0x8d184ad0,0x8c18d5f4),LL(0xf5485ef3,0xbd764f21), + LL(0xecb39885,0xc5483510),LL(0x705df629,0xf0122752),LL(0x93d33824,0xe43d6cca), LL(0x49923c5e,0xe00a9514),LL(0xd8080e76,0x6993aecc),LL(0x633b9fba,0x4dc6d79e), + LL(0xefcd68d8,0xa33bbb48),LL(0xe68f5543,0xacaebe65),LL(0xa37a2bbd,0x7383a726), LL(0x770555c6,0x5d3e8c9c),LL(0x9b90f1ad,0x86e220c9),LL(0xab26ba0b,0xfc32885e), + LL(0x89e7a1a1,0x35837dd0),LL(0x08889b69,0xb8c46a1e),LL(0x1957ef47,0xbf3d0f2f), LL(0xf0a25602,0x7b89c2b9),LL(0x0656bcd8,0xab5068da),LL(0xf4298e4b,0x0c5c3a38), + LL(0xcaf9bcee,0xd20c9cc5),LL(0xbd6c6fd4,0x783987bd),LL(0x93ba43c5,0x696e2d85), LL(0x391285c2,0x356cbc57),LL(0xb533c31e,0x536b15a5),LL(0xc4c4ba41,0xc375dc50), + LL(0x405fe9b5,0xb961c694),LL(0xd5283673,0xb3983e9c),LL(0x96e95f05,0xd455be9e), LL(0xc75e8014,0xb38412e7),LL(0x96860cdb,0x1033ac0e),LL(0x00b0a103,0x303881b4), + LL(0xb3b3e63d,0xd1fc3bf7),LL(0xda50174a,0x35ab8665),LL(0x01a402c8,0x2944d50f), LL(0x4d26ddfc,0xba75bddb),LL(0x80efbf29,0x530839a3),LL(0xb93462eb,0xbf8adca3), + LL(0x84d08e74,0xd534a5d0),LL(0x4efdf525,0x436eb254),LL(0xdca89d2b,0xc653af06), LL(0x41a37013,0x0895e017),LL(0x91294447,0xb9f0b192),LL(0xb7f407e1,0xfd2cb9b0), + LL(0xe6cc78dc,0xc5323fdc),LL(0x2a74ed72,0x9c863011),LL(0x1aa90d73,0x86d391c8), LL(0x308de318,0xae9c2f27),LL(0xcc2d2cad,0x133f4d65),LL(0x42a244ba,0x0bfd5ed6), + LL(0xa7843758,0xb5b22ff6),LL(0xd93d7ed0,0xbdd3456d),LL(0xe0432d41,0x4bb279a7), LL(0x14acb55c,0x375da883),LL(0xad01ebbf,0xf9493a0b),LL(0xf0543ccf,0x5063d083), + LL(0xac19b11f,0x5c97aefb),LL(0x820ab407,0x253042d0),LL(0x550d30a7,0xf6b2204e), LL(0xa702ecbd,0xa091b635),LL(0xb34417cf,0xbd011942),LL(0xd3f92344,0xcb969929), + LL(0xeca70aa5,0x46c47688),LL(0x383cfca9,0x057cd161),LL(0x7ea5b03d,0xe538b089), LL(0xf15b8704,0x0f3fc549),LL(0xc4be9475,0x0bdcf648),LL(0x40851b7d,0x31fb0690), + LL(0x7b90be33,0x8dcd148f),LL(0xb5e956ad,0x3720de48),LL(0x2a303f7c,0xa0ce39c4), LL(0x89d0fdb7,0x054206d6),LL(0xb76fa220,0xe9991e88),LL(0xbac4c9ee,0xa0eb60ae), + LL(0x01065ebf,0x9feaf043),LL(0x23e6a889,0x001f921d),LL(0x526d4d12,0xbe2a6e6a), LL(0x762aaed0,0xae7aa8bd),LL(0xde1e43cb,0xa8aa4f13),LL(0x626356ac,0xea279354), + LL(0xc65bd80c,0x54727769),LL(0xf135559b,0x0f18555c),LL(0xc8a92ba2,0x3ef9e205), LL(0xf4e4b870,0x32f97cc9),LL(0x9fdfc295,0x764e6c3b),LL(0xa0be0176,0x97f95ca0), + LL(0x3547707f,0xa25af6ad),LL(0xae94e108,0xc46e1845),LL(0x3a29996f,0x481c7fd4), LL(0x1aac0d60,0x4e9a38c3),LL(0x2d811b3d,0x40172f5e),LL(0x58ba5cdb,0x69750750), + LL(0xd402cb8c,0x29404a7b),LL(0xc4a0deb6,0x8698ab1c),LL(0xf10f49fa,0xb0336bae), LL(0x4d34533b,0x27cbe364),LL(0x53d57740,0xb22e812c),LL(0x90f4aa01,0x82b80434), + LL(0x479f2e14,0x1b20606f),LL(0xb817e38d,0x5fa6e4bb),LL(0xcedd7aac,0x860fdf9c), LL(0xb63a00f6,0x66fa3783),LL(0x73c45ad2,0x2719710a),LL(0x64de62a2,0xa3db3619), + LL(0xf04aa960,0xb2e191c9),LL(0xf57411c2,0xd419a1dd),LL(0xa4a57d93,0xd860a8ea), LL(0xc1f433bb,0x5001230c),LL(0x8ec92a7f,0xf28ce31b),LL(0x9a4d25a6,0x8c582d34), + LL(0x96219ee4,0xf2826086),LL(0x4b4f0c24,0x0c21e1e2),LL(0x387213d6,0xd1804821), LL(0x1cce49ca,0xfa342c74),LL(0x4341ef6f,0x880ea569),LL(0xe968aa8c,0xa6fdc07f), + LL(0x91a41ded,0x293a6180),LL(0xe5d87356,0x51412d3b),LL(0xf0b2d509,0x925d4c9e), LL(0xd251fb90,0x80c77ead),LL(0x90e53a2d,0x1d6e3cd3),LL(0xf9a2ab15,0x6e11e4d0), + LL(0x1d009ea4,0x3535dc7b),LL(0x75c6c6f0,0xb6b48635),LL(0x72e3c50c,0x12ac6480), LL(0x6464430a,0x6d71a720),LL(0xe1dfdda2,0xf553de43),LL(0xcc6c345d,0xa1ee9a4e), + LL(0x2ac5a8c8,0x46f7bd04),LL(0x063f2739,0x62c11b7e),LL(0x69a36c58,0xaa7522c7), LL(0x06a4df65,0x6a10fbe0),LL(0xdf06bc54,0xd5f96d18),LL(0x38151768,0x545f76b0), + LL(0x712eb633,0xe9dd6bff),LL(0xf6972761,0x6c1e035a),LL(0x7a4d81a8,0x060bfcaf), LL(0xd2653839,0xa262cba7),LL(0x95a4c747,0x561af30d),LL(0xe33e339a,0xb9a3b8ac), + LL(0x5f371d0d,0x2fc5342b),LL(0xefbb2027,0xf9654b68),LL(0xf7520a2a,0x14820afb), LL(0x43d0ea24,0xb24c0b99),LL(0xc37df573,0xa1a8898f),LL(0x7bed1103,0xa1c07bb8), + LL(0xc4d993a3,0x664a8ae7),LL(0xfe44732b,0x1c2e8847),LL(0xb2426ed1,0xdb1e5a22), LL(0x7a45d008,0x2bdd7cb9),LL(0xf3d91e11,0x59477a34),LL(0x4cd742a4,0xf53dcb02), + LL(0x6c709f3b,0xa28f6d2b),LL(0x9ac0b1d9,0x479b31b7),LL(0xd568d9ff,0xe8237a0f), LL(0x0580975a,0x6895a188),LL(0x7b234cf3,0x450b5fe5),LL(0x70629bf6,0x1b4e0f89), + LL(0xe5bcec01,0x455ac64e),LL(0xc6bf296c,0xaf051300),LL(0x2306584f,0x119cb4c6), LL(0x7c0dee75,0x3242a0e6),LL(0xae1fd52a,0xd09fce7c),LL(0x2d5cf9ca,0x53608dc2), + LL(0xc8506617,0xaf6edd22),LL(0x3241e286,0x5ed21b88),LL(0x81282c66,0xf27d3439), LL(0x308d6ca8,0xbd393fac),LL(0x9032cca3,0x5155e229),LL(0x56a04a1c,0x29acd1b2), + LL(0xf78b6573,0x95c60d2b),LL(0xed576414,0xe53bb875),LL(0x452f8871,0x389200b3), LL(0x5af9dd53,0x69a42e38),LL(0xbf0327d1,0x01e3b18e),LL(0xba8d03df,0x985d811f), + LL(0x559c7bda,0x0cfef9cf),LL(0x5bb4cd8c,0x5096e369),LL(0xc8011afa,0x8d16d0e2), LL(0xf25b0ff3,0xa816a8be),LL(0x2f161a22,0x7edbd05e),LL(0x8ba1f83c,0x1ae570e5), + LL(0x690bc4ad,0x7c0084c0),LL(0xad2fd216,0xe0a5451c),LL(0xb130c417,0xb4926a84), LL(0x9309e50a,0x39e4ec36),LL(0x5c1bc674,0x094fb1e0),LL(0x67878735,0x19572f99), + LL(0xd011ed00,0x8f62726f),LL(0x0793cd2b,0x430d8c6c),LL(0xb8f172e8,0x26226dc9), LL(0x11935136,0x550ff9fa),LL(0x8c9798d3,0xb415bbd9),LL(0x83b3b2c1,0xb136921d), + LL(0x669e0918,0x940bce84),LL(0x298448d1,0xca050170),LL(0xa8e4042d,0x1fa3041a), LL(0x1e2abce5,0x0f73a3aa),LL(0x448c4fcf,0xe5196a8a),LL(0x2774a5b1,0xfe25d513), + LL(0x7192ab9c,0x6799b1b3),LL(0x7f02ea02,0xfd1cd774),LL(0x01b1e71f,0x1b4e5cd1), LL(0x13c4b9f9,0xb09c08b2),LL(0x87870c13,0x6be2f294),LL(0x3c2d5610,0xb74d7045), +}, +/* digit=15 base_pwr=2^105 */ +{ + LL(0x7c1f0b12,0x950114b6),LL(0xd9406636,0x4862f5b4),LL(0xe79e2ad1,0x4b94f772), LL(0x2162024c,0x283df03b),LL(0x1eae9865,0x730f9f5b),LL(0x1260cbf5,0x70b3f304), + LL(0xe16c6f09,0x850addcf),LL(0x5592d8d7,0x36a07642),LL(0x74af4f32,0xcdbf2690), LL(0xf354ed72,0xf452488f),LL(0xa99eb244,0x8ceb8c62),LL(0x92a47252,0x471774a0), + LL(0xf938b030,0xc7285307),LL(0x51cc80fd,0x81689ad0),LL(0x483aeb1a,0xbb8e3d60), LL(0x8286229d,0x6dec5453),LL(0x0cc83f74,0x3edd27c2),LL(0x152e37a2,0x1cd6ed5f), + LL(0xd377bce5,0x537244ab),LL(0x92bbe196,0x333760b5),LL(0xd7b6c795,0x373f1920), LL(0xb99b6824,0xd28c3c25),LL(0x501ea35f,0x14e96723),LL(0x8bebdafd,0xb3c3f757), + LL(0xd82a0a63,0x4a680526),LL(0x0558bb75,0xeeb46a35),LL(0x7589e42c,0xc27b9513), LL(0x59267a86,0xaf5a87ec),LL(0x5c4b67d0,0xbbf1e057),LL(0x09598a27,0xe37e471c), + LL(0x2a71504c,0x894af9cd),LL(0xd1e8512f,0x38e0d48f),LL(0xfc2cdbf4,0x96db568c), LL(0xeac2f293,0x911f7b8d),LL(0x5c965527,0x5821420d),LL(0x078559b0,0x832e957e), + LL(0xfbf84029,0xff114368),LL(0xd21a72b0,0xd8dd9e2d),LL(0x057c15f6,0x4ba812a4), LL(0x64fa748e,0x976cf8b5),LL(0x73812963,0x1801ab26),LL(0x394d2cf3,0x4a748d37), + LL(0xb8ffb76d,0x6b23479d),LL(0x898a63b9,0x401bf60b),LL(0xdc64023e,0xee58a7ae), LL(0x6c70a3b4,0xd288cadf),LL(0x5cf80831,0xc1da3aea),LL(0x5ee941bf,0x941b411d), + LL(0x1029b199,0xc4cccd83),LL(0x6d56502f,0x683863df),LL(0x43f9e9f5,0xe362783b), LL(0xa34a9ef2,0xb224d946),LL(0x72b438e0,0xccabcf49),LL(0xc4af3f0f,0x78d92dda), + LL(0xceee3620,0x123b5621),LL(0x90e8a27d,0x513add4e),LL(0xe45a02ac,0xaf127aef), LL(0xc0d7ba62,0x21a78e17),LL(0xf98d0ce5,0xcf09e816),LL(0xae64e8c5,0xc28cab36), + LL(0xef7a2cc1,0x0912071a),LL(0x3b451d17,0xd3f2bc6c),LL(0x35ea478f,0xf3796f91), LL(0xc9c756e8,0x9b5e64d7),LL(0x2d58e1bc,0x7ed6f7fe),LL(0xeae6b6de,0x503d9af2), + LL(0x5e314295,0x57cc1308),LL(0x89230510,0x74c77119),LL(0x9968ac6f,0xa314891f), LL(0xf033b995,0x8dd4df22),LL(0xe0d71497,0x7ffe0a44),LL(0xac968d35,0x5c5f54f3), + LL(0x406b0bca,0x246a971a),LL(0xd805a357,0x90eedbcb),LL(0x5c690ec1,0xa6dbc124), LL(0x7bc65cbe,0xbe369f3d),LL(0x96065417,0xe0ff616a),LL(0x337f567d,0x3654f681), + LL(0x9bf8c833,0xffa30743),LL(0xafe911c4,0x6bd11b77),LL(0x6762a958,0x30eee614), LL(0xa9e63f35,0xfba9fbc0),LL(0x332389bf,0x70edc028),LL(0xb9798769,0xb5d35ca9), + LL(0xb8c620c1,0xcde63d0f),LL(0x06942335,0xcdeaad60),LL(0xbdef1579,0xefb74b79), LL(0xd8b128a9,0x13dd5771),LL(0x56343492,0x00e9fe16),LL(0xd6baa45a,0xf4ffba1d), + LL(0x19d575fd,0xfdb1ece3),LL(0x61ad3345,0x231c53ac),LL(0x523e013e,0x3f3df394), LL(0x71c3b97d,0x254a291f),LL(0x396eb0c1,0x645a1aea),LL(0x0282f254,0x680b79e1), + LL(0xf3ef6b21,0xcededfad),LL(0x577a8e6e,0xa57437f5),LL(0xf5f051f3,0x413575b4), LL(0x4d1ca0ed,0xd88fe7f3),LL(0xdcceffdf,0x1849d754),LL(0x141422af,0x40e7733f), + LL(0x00721b87,0xcd5a690a),LL(0x0b2801ae,0xf0e84ac9),LL(0x17c73f20,0xaf0765ff), LL(0x33595f95,0x976d23d8),LL(0x72c8f457,0xdece9d39),LL(0x6604f618,0x3dddbfa2), + LL(0x2bb19559,0xef6c219c),LL(0xd57790b8,0xfbf7ac31),LL(0xc8f6c246,0x676751ad), LL(0x4c3b7ff6,0x0f4384d0),LL(0x39ee5f11,0x040a4f5a),LL(0x698f2f7f,0x30c58138), + LL(0x0d1a6b11,0x097f5ccf),LL(0xf9b7701b,0xf6cdd1f6),LL(0x4786ad28,0xb965d0ce), LL(0x70cd6a22,0xadd506d0),LL(0xd6299b81,0x9c4667a5),LL(0x1c032341,0x64056720), + LL(0xeb125185,0xfd01d07b),LL(0x48235596,0xbec6636b),LL(0x293de94e,0x9017825d), LL(0xe499b69d,0x888e08c6),LL(0x3b6a7ced,0x4f4a6117),LL(0x58f8d42c,0xd6d2a6fc), + LL(0x79062ff2,0x66a2ad0a),LL(0x9bc01a36,0xf187ed18),LL(0xb3f3d332,0x4fce4f5a), LL(0x38533148,0x903af8c9),LL(0xd058ab8e,0x34ff5da6),LL(0x6b2b6b4d,0x8fc66e30), + LL(0xd4eb310c,0x7e0843bb),LL(0xbefbb992,0xcd48672b),LL(0x75c258ee,0x839c6b0b), LL(0xd70a705e,0x11733171),LL(0x15042807,0x92fb3004),LL(0x9ca0a17a,0xe091def9), + LL(0xaa917028,0x48c33a95),LL(0xb87bb667,0xdef22091),LL(0x106fa5c7,0xb6223052), LL(0x6934d6e3,0x12491351),LL(0xbce2aa51,0x55c0b4d5),LL(0xb70985ca,0x734ec89c), + LL(0xbc8fd35d,0x000e0cd7),LL(0xb50502f2,0x05b488af),LL(0x1252793c,0xb56958a5), LL(0x8a310520,0x4e8c9cc1),LL(0x7f1db7bd,0x0a6e45d6),LL(0x5ecdeb31,0x72d3eb5a), + LL(0x85f7d20f,0x1ac14fe9),LL(0xb430d3cc,0x0e020f68),LL(0x409668ed,0x273e515f), LL(0x78e0031b,0xbf622f1b),LL(0x9bf7fcd7,0x5aa6dd5e),LL(0xb6b977f5,0x30573193), + LL(0x275d217e,0x7c4023a7),LL(0xcca3f6f1,0xac6a6b67),LL(0xf0fcc9b9,0x176bacc3), LL(0xb0858d73,0xb280416f),LL(0x6fec46e4,0xe48e3c6d),LL(0xf3235cfd,0x9aeb3a09), + LL(0xa486a8eb,0x33c068c6),LL(0x5def6704,0xc60c21cb),LL(0xbefdd067,0xff4ac34f), LL(0xe174348b,0x4f1427e6),LL(0x9f27fd60,0xc80afd96),LL(0x35955ccc,0x1799ed29), + LL(0xddebd485,0xdbf71628),LL(0x4b8207f2,0x13897ccd),LL(0xfd8365e9,0xe12c2822), LL(0xb003566c,0x705fe026),LL(0xf12863e8,0x8a97247d),LL(0x1748fc9e,0x698a3477), + LL(0x0669c4d8,0x90917d8d),LL(0x80746165,0xc65e4aa5),LL(0x12c0f44c,0x96763d21), LL(0x97318a9b,0x00a7db8f),LL(0x5fd1a0e9,0x29079037),LL(0xa9b6ec4f,0x2f4f1c47), + LL(0x0bd63292,0xd861004e),LL(0xca40a1da,0x0176d94c),LL(0x59fb9a7d,0x5e91abe8), LL(0xf6d4f1ff,0xa881a8f5),LL(0xa24ce9a9,0xded77256),LL(0xc492f4f1,0xacf4db67), + LL(0x391ca168,0x7146928e),LL(0x11e6bfe4,0x11981f6f),LL(0x32f997ad,0xfce0f814), LL(0xe85cd202,0x7cf18ed9),LL(0x03c315e4,0xa94f2b6d),LL(0xb5f8a4d2,0xe2a93315), + LL(0x2fab5a21,0xcd259208),LL(0x928dcc30,0x3d24f816),LL(0x9d66a41a,0x779e1c36), LL(0xc2e41af4,0xa8248120),LL(0x06fc8b0e,0x243a6bbb),LL(0xed8d12b1,0xb9de9d41), + LL(0x30f64b0e,0x23ff17d9),LL(0x8f083ea7,0x1eab5984),LL(0x554ae817,0x9965f2c0), LL(0xf4d8956a,0xb0a399b6),LL(0x0ebf134d,0x315694aa),LL(0x7fde4077,0x53567f64), + LL(0x5c71762b,0xfdfeb029),LL(0x1eb1144d,0x968d0bd7),LL(0x1f08b2a6,0x171297f4), LL(0x897a2666,0x7944101d),LL(0xda77b1a1,0xf4936746),LL(0x44547953,0x0e752c75), + LL(0x492b2fa0,0x69d5b44f),LL(0x5d483119,0xda5f6651),LL(0xac522988,0x40814f2b), LL(0x4e1f60df,0x344aeee8),LL(0x5ff6f053,0x2ddba5e0),LL(0xa4008621,0x4453d9ee), + LL(0x179e2967,0x37ab4aec),LL(0xba87af44,0xe91479f7),LL(0x0b55c02f,0x4b292d1e), LL(0xb69ad1a8,0x9deeddd2),LL(0xe91e913c,0xb610d598),LL(0x912b8e9d,0xa6b91331), + LL(0x20cdff63,0xaa819620),LL(0xaa6d0ed4,0x8d70fbba),LL(0xcb318c6a,0x5c951edc), LL(0x57b1fd8f,0xa4cc6573),LL(0xe00bbceb,0xd7a23636),LL(0x8d179500,0x33bb3513), + LL(0xe0168751,0x86da6dfe),LL(0x66604b83,0x940ba0c2),LL(0x22e9e186,0x15a8aa02), LL(0x65a6f19d,0xe5b39c58),LL(0x32f441b2,0xf591dc15),LL(0x9d3a2de0,0xb85cad59), + LL(0xfb422575,0x35abc7e2),LL(0x4b8acd9c,0x517b6718),LL(0x2ee6263b,0x3e303015), LL(0x7393f470,0x51c8c440),LL(0x974d3dad,0x032cce2d),LL(0x4c104799,0x68e57ee5), + LL(0xc0514589,0xb95807db),LL(0x0402a3fb,0x09a79c01),LL(0xd3fdd054,0x92bf681e), LL(0x393adbfc,0x9f2f00f4),LL(0x1ca244f6,0x13789212),LL(0x00d3a9db,0xe2f45a02), + LL(0x207a53c9,0x29ea3e07),LL(0x163549d5,0x61213e9a),LL(0x4656d770,0xe0b025d0), LL(0xbd0d85da,0x050f7501),LL(0xe3b43784,0xe95027f4),LL(0xf1a6b6b5,0xca3907cc), + LL(0x4a7a00be,0x670062e7),LL(0xace7ec67,0x9ea4759e),LL(0xc1d92037,0xf5d29365), LL(0x9c39e2de,0x6d421c87),LL(0x1593c52d,0xb3e3d2c7),LL(0xcd74d083,0x6733eb50), + LL(0x5ad1d924,0x30029e9b),LL(0x84925a40,0xc15c63d1),LL(0x17e5f0bb,0xb2c098b9), LL(0xda6f02f1,0x2646d78b),LL(0xb8ae8095,0x1f8b74a3),LL(0xb03283d5,0x2bfdcbee), + LL(0xb7d7ef7f,0xc78a8e01),LL(0x574b90f6,0x7e0a26ab),LL(0x26861a59,0x9be1c8b4), LL(0xc787cf5d,0x5dddc986),LL(0x217b8936,0x77e06114),LL(0x94d79885,0x0b58deb0), + LL(0x6ef1f554,0xb89d079b),LL(0xf1deef2a,0x87ee6d78),LL(0x7a7b9098,0x8985bc42), LL(0x165957c3,0x0843395d),LL(0xccf6daf8,0x11293e7b),LL(0xfce740f4,0xb2527ca8), + LL(0x12fbd080,0x54f19e66),LL(0x4aed0e22,0x82f0835d),LL(0xb56935f6,0x5f73c822), LL(0x5b0f4a59,0x4b255bef),LL(0x6b23634c,0xc2542ee4),LL(0x858eb55c,0x41a4fe31), + LL(0x70d71c90,0x5c19755b),LL(0xdee1b0d6,0xb15b8f0d),LL(0xeab4b7ef,0x07e40808), LL(0x6faa90c6,0x9f4f2665),LL(0x9fcb51fb,0x9e72096a),LL(0x541dbffb,0x1660e2f9), + LL(0x9aff8d55,0xfb1cf7e0),LL(0x7a1815da,0x7276df1a),LL(0x913d43ca,0x604cd6bf), LL(0xe0227dec,0x4f016034),LL(0x0e990a9e,0xb70eb020),LL(0x83b0d458,0x9db0e5f0), + LL(0x4bda5c36,0x137d2ba6),LL(0xc9d84ed7,0xf2ad5444),LL(0xb4878d48,0x37ba4976), LL(0x0c6237c0,0xe3518c97),LL(0xb5e9c50f,0x32e71c0a),LL(0xa325250d,0xfa2c1d25), + LL(0x80be6431,0xfa8cf7f2),LL(0xe5a2035e,0x74e8f698),LL(0x03eff799,0xa032a4e4), LL(0xc53ac08f,0xbdfd91ab),LL(0xebf217bc,0xe17b20eb),LL(0xdf84edd2,0x40de3e73), + LL(0xdf81c5d3,0x4110f517),LL(0x53f20019,0xbefb623d),LL(0xf346f4d3,0x67061890), LL(0x26ff57dc,0x096120d3),LL(0xccb068a2,0x00b49cf6),LL(0xf00d1e3e,0x613293d4), + LL(0x467e8604,0x248b65d5),LL(0x3ab4a1b3,0xcd983257),LL(0x1e96833c,0x1dc552b2), LL(0x89592574,0x851b4255),LL(0x1da99f23,0x62d85452),LL(0x401ba0d8,0x4cdbe71f), + LL(0x9760901c,0xdd6660af),LL(0xb8ad97c4,0x503a92d0),LL(0x6fbd51d5,0xdd313e4e), LL(0x6e919a43,0x441e5529),LL(0x65e9a71d,0x8613c8d8),LL(0x3d2336b4,0xc0c8b396), + LL(0x7b97021e,0x811cc3a9),LL(0xf50aa806,0x6d1a1d14),LL(0xf7f8f8f8,0x85a4588e), LL(0xe67b610a,0x23ba0ee5),LL(0xe3f78d9b,0x77df65eb),LL(0x99a02de1,0x0295f1aa), + LL(0xae21de63,0xd3284a43),LL(0x6e23bdc6,0xa976e9a5),LL(0xa757b390,0xcc8cfb98), LL(0xa4697fde,0x5e6a1ae0),LL(0x5aafbacc,0x5c62485d),LL(0x27e4f7d3,0x804597be), + LL(0x53bc971a,0xea91a442),LL(0x436f90ba,0x41484d9b),LL(0xd87d03a9,0x21b57dab), LL(0x8f1888f0,0x935c940c),LL(0x4c82401f,0xe1c2a3eb),LL(0x7847c8a6,0xf42fb0f8), + LL(0xb4347b62,0xa649770f),LL(0xb29590ef,0x3bf77343),LL(0x6a205e84,0x92b6e5a1), LL(0x63cac357,0x8c973844),LL(0x7e8ab06a,0x058f0f22),LL(0x58d62ed7,0xaddca6e4), + LL(0x1160ca95,0xf4b969c6),LL(0x0d73f647,0x60e6b905),LL(0x9b98ce7e,0xd8413d40), LL(0x9ec67398,0xebd6924f),LL(0x628424b1,0xe4c95b85),LL(0xc7f2b86c,0x157759fb), + LL(0x195680a9,0xd6f1e165),LL(0x965d62c7,0xd433c1dd),LL(0xd3dd177d,0x0890fc5d), LL(0x8c44dbc2,0x3e0f43d4),LL(0x9cb07f9d,0xaa0c14ed),LL(0x6ff8b939,0x6d7feea2), + LL(0xc17b0751,0xa1c5b89f),LL(0x46164d7b,0xf47724f4),LL(0x60ec3b26,0x9b1dd929), LL(0xcb50b27b,0x6c3c835c),LL(0xf86980fd,0x259fde39),LL(0xde92e229,0x84e73227), + LL(0xd05a1ec4,0x1f1e9817),LL(0xe6e48ece,0x2692c83d),LL(0xf4903352,0xa2c5bd53), LL(0xaf3eb235,0xa1f9c3ff),LL(0x71158432,0x52c141c2),LL(0x16d971ea,0xeddd3c85), + LL(0x3724189a,0x7554e3b9),LL(0x2e63e62b,0x5eea6e3b),LL(0xe23434b0,0xe28ad863), LL(0x5f932bc7,0x6016f1e8),LL(0x7d76d1fd,0x1240c223),LL(0x5124123a,0x2ce14c4f), + LL(0x6d50fbd1,0x6c89d0a8),LL(0x31779189,0x4a38b313),LL(0x8d8124b8,0xa1718ddc), LL(0x0e02b2d0,0x58f48b51),LL(0x6114c7e3,0xd38936a6),LL(0x1b70ec0a,0xb5e924e8), +}, +/* digit=16 base_pwr=2^112 */ +{ + LL(0x1f47a973,0xcf447109),LL(0x627fd943,0x24c191c4),LL(0x32c6da19,0x4f5f134d), LL(0x9d08667d,0x1b92e5f9),LL(0x1d9684b0,0xe6b9a4e8),LL(0x553bcb2a,0xd60fdeba), + LL(0x46cc2ad3,0x840f76a1),LL(0x6235d7a8,0x63b85026),LL(0xb2ef5ad3,0x5616a569), LL(0xc3f03ea7,0xa056663a),LL(0x38ce234b,0xd93ddef0),LL(0x57a8650d,0x0f729e40), + LL(0x360595c1,0x1b437776),LL(0x080dc311,0x6aa3a75d),LL(0x11147932,0xd1288177), LL(0x8a241c89,0x8c953ffc),LL(0x7de54cc4,0x7de8a558),LL(0xa5a3ed5a,0xa8dc2b2f), + LL(0x084ee344,0xf6b53652),LL(0x4048d28e,0xb51a92cb),LL(0xd688ff26,0x58fb44be), LL(0x9247a804,0x136a7d51),LL(0x3ef5f22c,0xf2176fba),LL(0xa999af5d,0xb4a457be), + LL(0xf23f79c8,0xb4cf845c),LL(0x1ad85366,0x8233b3b2),LL(0x78e68d8c,0x4efef3d6), LL(0x22c7941c,0x17b1e851),LL(0x761dde7d,0x40a27661),LL(0xcbd06300,0xac29e1a1), + LL(0x0ced7008,0xff48c690),LL(0xebfce074,0xbed07115),LL(0x27aa6e6f,0x4ac10aa5), LL(0x5e777e33,0x7652ebb3),LL(0x4dd30e6c,0x255c16ab),LL(0x9159219a,0xc0e1b073), + LL(0xec32e62a,0x6d2fc306),LL(0xe70096e4,0x426dd67b),LL(0x70d9383d,0x994877cc), LL(0xd011ca1f,0x8bc75d3a),LL(0xaa1362ae,0xcb18fa82),LL(0x2c292316,0x54fb1473), + LL(0x8c720bd1,0x45aa7854),LL(0xc5257a6e,0xceba0e5d),LL(0x796e4320,0x0e924974), LL(0x866fc34b,0xf2ce13c7),LL(0x6a58601d,0xbe8606f3),LL(0xbf56d38c,0xa25d6005), + LL(0xbdbaa117,0x9432504c),LL(0xba422130,0x4dfc9c38),LL(0x500ef320,0x32d66ac1), LL(0x0679d51e,0x1a38a920),LL(0x93a9c6f2,0x3e2a3c53),LL(0x0a59702f,0xe0b71451), + LL(0x4cefcb03,0x04e4087a),LL(0x4ab1d062,0x68686886),LL(0xdd24b69f,0x67054513), LL(0xa89e5edb,0x21d5ff58),LL(0xd8e0f856,0x9412a213),LL(0x3faa0ffa,0x1a05bd39), + LL(0x14033a58,0xee2aec92),LL(0x5161890c,0x38e267ef),LL(0x8c51e740,0x2f0ae797), LL(0xea57871c,0x6d2143ac),LL(0xc5475c3e,0xef3ce79b),LL(0x1fa55fd9,0xdd9cfa6a), + LL(0x412965e9,0x6ae0ef90),LL(0xe9188107,0x2430c1f0),LL(0x42b98992,0x9682e74d), LL(0xb638ccb1,0x3094b342),LL(0x16948a40,0x6aa863ef),LL(0x60f1cca5,0x2ef984e5), + LL(0x694a80f4,0x4980d35b),LL(0x2c3d3326,0x4dbbe36d),LL(0x1c899dfb,0x1c719190), LL(0xe9938032,0x96febca8),LL(0xa63775ac,0x7b17130d),LL(0xd12cfb2c,0x17e68ea4), + LL(0xfde8a210,0xf111a32f),LL(0x83b56b17,0xc3d61a7e),LL(0x22b86813,0x48125662), LL(0x410c959f,0x1ddf2f99),LL(0x68591a75,0x886a1893),LL(0xa21da760,0x92dc4bbf), + LL(0xb9b71c82,0xa2d0b7f2),LL(0xe59c5616,0x206fb318),LL(0xa9f1f448,0x01112ace), LL(0xd40341f9,0xbc6ee063),LL(0x90590590,0xe2c50a8d),LL(0x795c4ef5,0x3aa25a83), + LL(0xf5016294,0x582102f1),LL(0x8ecaf2bb,0x6c6a8cc5),LL(0x9e733710,0x7887a218), LL(0x82da339d,0x18ea2c41),LL(0xef8def66,0x428afd13),LL(0x5f923e0a,0x171ec875), + LL(0x98756704,0xd9233e20),LL(0x86a8b3bb,0x5b3a223a),LL(0x216d0c55,0x844ef9e9), LL(0xb7f4d4b6,0xb8a1a350),LL(0x64bb191f,0xf70cb37c),LL(0xefb8ae25,0x7c42a6c0), + LL(0xc8074a8b,0xf789197b),LL(0xbd20de1c,0xf7984f1b),LL(0x50eb451d,0xc0b1f821), LL(0xa88538d0,0xeb36fa99),LL(0xaa22b727,0x87c78bb1),LL(0x3644f1eb,0xfe697599), + LL(0x6fb08720,0x775050a3),LL(0x7c92825b,0x6547216d),LL(0x4a525878,0xe4c237f8), LL(0x63d4f3fd,0x584a8f77),LL(0x80b593cd,0xfefbf7fb),LL(0x89778016,0x8f52fc2a), + LL(0x275beb93,0xdf1d7c82),LL(0x7512f5a7,0x4e3e1e22),LL(0x833674bc,0x0a8c3404), LL(0xabc4edcb,0x92c482d9),LL(0x9fc05328,0x90d5620d),LL(0x72e82254,0x49facc26), + LL(0x2ecb1fc1,0xc5acdaaf),LL(0x6e74dd57,0x2a6d3302),LL(0xda6dfd6a,0x7ac86ef8), LL(0x4074218a,0x24edf1a2),LL(0xf9162dd2,0x9010034e),LL(0xae5e58fb,0x035ed18c), + LL(0x55f3fe0b,0xa961e6d8),LL(0x46a86b10,0xcd5156e2),LL(0xc2988880,0xc4fc85c9), LL(0x5e00c084,0x68c21329),LL(0x9af42336,0x505ffd96),LL(0x2d4346e2,0x2d3d12ff), + LL(0x81aaf463,0x19a0b708),LL(0xe4d6eec0,0xc956aa02),LL(0x897c0465,0xa8dba669), LL(0xbee2b8a9,0x5c8a3e27),LL(0x80c032bf,0x8ae8552d),LL(0x482aaf27,0xe7526fc1), + LL(0xc12240f9,0x4767cb3f),LL(0xfe66cca2,0xa31fe2bb),LL(0x0c03119a,0x15f6f333), LL(0x9283ee27,0x67a68e9a),LL(0x53e4d988,0xe2d7d349),LL(0x0150cf1a,0xaf919ee4), + LL(0x4bc9e09b,0xcd0b84c0),LL(0x8f7286bb,0x0e18d19f),LL(0x5aa9039c,0xf51f3b13), LL(0xb25604be,0xe0bf876a),LL(0x60e8118a,0xaf35db67),LL(0x6dca47f8,0xd6f2ebd8), + LL(0xe4942689,0xdb226347),LL(0xd061e06d,0xda1e15d6),LL(0x3d043dec,0x2a99ad74), LL(0x7a5cac1c,0x78a33189),LL(0xd8bfd02e,0xb3b6c52b),LL(0x7aaec4f4,0xcae776f5), + LL(0xe13ee1b0,0x00bd80ca),LL(0x5570567c,0x678837f3),LL(0xe22c402b,0x379e4e13), LL(0xb68e8230,0x7f51fdac),LL(0x5d23aa66,0xc76acd65),LL(0x2caaa8e7,0x4b8a0d89), + LL(0xb2c47709,0xeeb913e9),LL(0x01b76a21,0xc2683d5a),LL(0xec8c8ce7,0x58e53311), LL(0x0654cd8a,0x0a179454),LL(0x5999ac6c,0x011152f5),LL(0xc8b4fa8f,0x15eb6f48), + LL(0xfdb6b880,0xe5363d68),LL(0x3ad457bf,0xef83e507),LL(0x6fd08edd,0x63874010), LL(0x85975c5f,0x64b77762),LL(0xbed19eac,0x11cf13e2),LL(0x19f07470,0x823d8c2e), + LL(0xdc4e8957,0xd091f448),LL(0xcf0950b8,0x9825fdfb),LL(0x0d1e5204,0x1e297e4b), LL(0x499cbea9,0xab53b2a8),LL(0x4917c840,0xca4a1f80),LL(0x2a785cab,0xe6506492), + LL(0x0f900918,0x9c532f97),LL(0xcb00118b,0xfc209bf8),LL(0x6290d47a,0xdd4a28aa), LL(0xcb4c67cc,0x8a7aa0f1),LL(0x3a3a7acc,0x1d7cc682),LL(0x504f910f,0x085b0335), + LL(0xc3978c89,0x2a3e44bc),LL(0x3724d81a,0xbbc69641),LL(0x8e42053e,0x8cd0bcf6), LL(0xebd9205c,0x9a84e877),LL(0x8bbf687b,0x6c153f89),LL(0xdee7732a,0x730b14c7), + LL(0x3e54212a,0x71f21e01),LL(0x2044a858,0x2fce6291),LL(0xd5b7e3b0,0xb3b630f4), LL(0x59a7edb1,0x42ceac09),LL(0xbddf2781,0x6a40528a),LL(0x8954daf0,0x68b67f7b), + LL(0xd4cc9c00,0x6f07450a),LL(0x243d9b91,0xac4f418f),LL(0xb3930836,0x862c4d7c), LL(0xb829804c,0xad9509d4),LL(0x35d6a88a,0x5448355a),LL(0xa02a8977,0xb1fd6cf6), + LL(0x12fda311,0x926dc0b6),LL(0xa713c6b6,0x3858aa1e),LL(0xb59d713b,0x32532f12), LL(0x0f81bc84,0xe0a3bd86),LL(0x34b57212,0x28bfc374),LL(0x59e6b4f4,0xc1d92564), + LL(0xd1adc5f0,0x749961eb),LL(0x6897fc6f,0x070b3de4),LL(0xb71a0ade,0x0b95a35d), LL(0x4c6cf54f,0x993a0e3f),LL(0x07030f4a,0x57dd5c90),LL(0x12298384,0x191f3d38), + LL(0xfe98a51d,0xd30028ba),LL(0xf0f77aef,0x536fceb1),LL(0x15f7d4d9,0x58a8d8cd), LL(0xafa42baa,0x498dd178),LL(0x8ad8d1db,0x107ae753),LL(0xf4a6e0d7,0x79957dae), + LL(0x098aa8a4,0xdefb4a06),LL(0x5a536615,0xd45f01be),LL(0x2175624e,0xdfb9ab8f), LL(0x432b8122,0xb7f76e8a),LL(0x66ba6ee3,0x838ee280),LL(0x275d1fcf,0xe6911bea), + LL(0xe82bfc51,0x5ddd5dc2),LL(0x126dd7dc,0x36994ad7),LL(0x520c3a43,0xa3be5780), LL(0x6b94a716,0x093dec86),LL(0x9ba657b4,0x5189af95),LL(0x2c605098,0x188fb2ee), + LL(0xb76392f7,0x14886c31),LL(0xdecb5423,0x304dd2c9),LL(0x0214664e,0x853a2344), LL(0xca815581,0xa150c793),LL(0x5edee2f8,0x1334dabe),LL(0x58d437d1,0xfa263569), + LL(0x31b3f896,0x348804e5),LL(0x4bc1df4d,0xf9778c68),LL(0x5ba2cff5,0x9174fb72), LL(0x3156fc57,0xdae23f11),LL(0x0eaf5c36,0x146fe941),LL(0x6954d2fa,0xa756199e), + LL(0xfc879267,0xd875fdac),LL(0xeac024c1,0x504843c3),LL(0x9abdbb10,0x2880c735), LL(0x3b9acd44,0x45f8969d),LL(0x6261a810,0x86744967),LL(0xda56c33d,0x2889aa10), + LL(0xcca4b465,0x4cd3e586),LL(0x0438f6dc,0xb9858004),LL(0xff4ba237,0x5ecb0167), LL(0x2de8c238,0xbf2dfbac),LL(0x86067a4e,0xd1a1f341),LL(0x514110d5,0x6e001905), + LL(0x32515872,0xcc0b6188),LL(0x9db67e8d,0x8a5a4765),LL(0x4032cd76,0xfc5572bd), LL(0x4ced4c98,0xa8148877),LL(0x7e29acf7,0x3a3f4af1),LL(0x4878a56e,0x19e7ba4b), + LL(0x6ffe2a99,0x7d54fa14),LL(0x602fe247,0xd9f414c7),LL(0x284f46df,0x31abd712), LL(0xe6a9ef58,0xf55a66ce),LL(0xb2d9463d,0x8d76dacb),LL(0xc14ace92,0xac7aebc3), + LL(0x7fc941bf,0xa7b46744),LL(0x3f70d808,0x0c420029),LL(0x177bab8e,0x3da5d17e), LL(0xb3a67013,0x3ce9a56e),LL(0x34c0d947,0x4fc18745),LL(0x4571d7d0,0x1295a40c), + LL(0x59a9c46e,0x55635c3d),LL(0xbfe9682c,0x425f4119),LL(0x47824565,0xd6486529), LL(0x8a96f0bc,0x741c7a34),LL(0x382a3617,0x9cb36316),LL(0x7e0bb8c3,0xe8704d9b), + LL(0x261438fc,0xba5fc6e5),LL(0x304dce0b,0xd455c9e0),LL(0x5d776157,0x2c5cd9cc), LL(0x58000464,0x2ad5cc3e),LL(0x9efd5253,0x88b007d4),LL(0x031f40e8,0xc5024b19), + LL(0x89f85ced,0x43e291bc),LL(0x2565e514,0x704c3d56),LL(0x6f19bf54,0x401941da), LL(0xc42b17b9,0x407ffe45),LL(0xee6116a1,0x68753698),LL(0x0f1e7e3c,0xf69c5def), + LL(0x59d50565,0x7e95369e),LL(0xc3f575f3,0x089278bf),LL(0xd7d4ed14,0xfbf02dc1), LL(0xc063b9b3,0xe98848a5),LL(0xb3d74962,0x49058917),LL(0x937ac3e7,0xbaee0b60), + LL(0x9517cd36,0xd3f4711d),LL(0x5ab34ba6,0x72055716),LL(0x8054f1b6,0x55781094), LL(0x854d305f,0xe3ad29bc),LL(0xa21b9037,0xc6f2e79f),LL(0x0478e475,0xa01b493a), + LL(0xf078fc36,0x80124211),LL(0x203d5414,0x29e04253),LL(0x1a40dfb6,0x53737763), LL(0x19d3137d,0x698334c3),LL(0x22b7e891,0x02c4658d),LL(0x285de1ab,0xe33063e7), + LL(0xe76c0ac6,0x56eb9f2e),LL(0x90aef3e0,0x3898b635),LL(0x3e409c12,0x016a7234), LL(0x32cd68c5,0x488d72fe),LL(0x809dd2bd,0xc9cfcd28),LL(0x0b99c1d2,0xec284a02), + LL(0xaf16bcb5,0x7cc64eaf),LL(0xdb4ffe42,0x6a629feb),LL(0x2d775fbd,0xdf4a9495), LL(0x41ee0c37,0xde89a2db),LL(0x2b89d6f5,0x4bcb9b55),LL(0xaa29912c,0xabeefb50), + LL(0xde0b2010,0x026c18f7),LL(0x43b3d1d2,0x39495f8b),LL(0x30288eb8,0x63546dd7), LL(0x68b69732,0x0a49e9b2),LL(0x0ffd4a14,0x9ef54b7e),LL(0xd1fd4c67,0x834add8b), + LL(0x95444724,0xaf5a35ac),LL(0x98374f56,0xa4f56e13),LL(0xbad358c4,0x779136c5), LL(0x0b77d7db,0xda98e86d),LL(0xd83f4464,0x664c97a2),LL(0xa95543ed,0x9e4c6820), + LL(0xa63fde03,0x4189250d),LL(0x252242a2,0xfdf0c2da),LL(0x04072ae9,0xc46d8769), LL(0x6679d6e8,0xac1026c9),LL(0x30b3ab9e,0x2932cf08),LL(0x52f5c3ef,0x543f55db), + LL(0x14b85fd4,0xbea36af7),LL(0x5bcce101,0x32771ea0),LL(0x798ec0fd,0xd9a59a8c), LL(0x4d437c35,0x165e1bfe),LL(0xedfb6d49,0xb55f1e8b),LL(0xec21ec21,0x362e3826), + LL(0xd4c60ba2,0x3aebfb11),LL(0xc7e3f014,0x77426fe0),LL(0x8a27fdc3,0xe457c3e5), LL(0x5e5bc8a5,0xb301854c),LL(0xd258898f,0xe6b8c9d9),LL(0x415129b5,0x3a7ead26), + LL(0x1e2c52bd,0xe3760794),LL(0x36b33409,0x383b64a3),LL(0xe476721f,0x3e25c3ed), LL(0x636f7572,0x209893c6),LL(0xe5f8134f,0x7e26bf15),LL(0x155ae70b,0x27e0a220), + LL(0x9e9f2836,0x8f6b7ae3),LL(0xf9826937,0xf5eb2b96),LL(0x27c80d30,0x6b213e6c), LL(0x5320af31,0x52d85c63),LL(0x719df6d3,0x468df649),LL(0x2744251b,0x69403a14), + LL(0xd9a2d948,0x28b1b9c5),LL(0x8e0c0b46,0x171331b5),LL(0xc359284b,0x84749e1b), LL(0x2e820b7b,0x184eb606),LL(0x740d7291,0x4f45113f),LL(0xaacb8d25,0xd1743386), + LL(0xf464caa0,0x003c4b6d),LL(0x6280078a,0xe1e5b15f),LL(0xbfdf8ef2,0x2c0ace42), LL(0xbdcc429b,0x695d68df),LL(0xc9b7c777,0xb9a74231),LL(0xe2ee83bc,0x72976a32), + LL(0x649ab654,0x72625a05),LL(0x40672830,0x4c950283),LL(0x6265499f,0xaa52b9e0), LL(0x9e60c50f,0x82c299fa),LL(0x697cef66,0x32ed0262),LL(0xf4c1412d,0xa5fad068), +}, +/* digit=17 base_pwr=2^119 */ +{ + LL(0xa11d1043,0x5db5f2ac),LL(0x3144df6d,0xb1054ec2),LL(0x484fcf47,0x4d5655f8), LL(0x9dbb1826,0x0650cfdb),LL(0x21f5feda,0x27dd6048),LL(0xd7202fb5,0x0ac68e0b), + LL(0x1af46fd9,0xc42442cd),LL(0xfcf7cac7,0xb01213f0),LL(0x7eee2308,0x36e25d39), LL(0x17b3a506,0xcbf7331b),LL(0xcbb09169,0x9cb57ff6),LL(0x2928d485,0x819296b4), + LL(0x8f4e94b8,0x22111a83),LL(0xb5d0778a,0x808a8a94),LL(0xe721738a,0x6dc353a0), LL(0x622c3cad,0xfbc21338),LL(0x2a4f4740,0x33ad7aa1),LL(0x7bd23daf,0xc3ce2ea5), + LL(0x17755e9d,0x5214c0df),LL(0x22952389,0xd0989763),LL(0x2069bb1e,0x51accd0b), LL(0xe9cdd0be,0xe8ff9789),LL(0xbb212bd4,0x7e57a08a),LL(0x31edf24e,0x6b3e08ed), + LL(0x6be00a20,0xf20543a1),LL(0x190d57cb,0xb8bcaa66),LL(0xef2b91a2,0xdd7c09be), LL(0x5592a7fb,0xd0e3d7f0),LL(0xa4e5380b,0x71dd3f1f),LL(0x7ad60960,0xe1a6c123), + LL(0xd3ca68f9,0x57bc69bd),LL(0x52100876,0x4ada2eed),LL(0x8c3bb3a7,0x2e966e5b), LL(0xe177995d,0x507cdf48),LL(0x62dec6cf,0xa34769db),LL(0x615eb17f,0xd9cd4150), + LL(0x7de68ea6,0x0135519a),LL(0xe8a86804,0xe966ae0c),LL(0x4d390e2d,0x63738258), LL(0x91e8e57c,0xfd018375),LL(0xd49915f4,0x31e5d307),LL(0xd1e1542b,0x173b719a), + LL(0xfc46d6d5,0xb492fccc),LL(0x46eddcd3,0x973958f7),LL(0xb0f21fba,0x7222fff6), LL(0x41f0f218,0x8eb1db20),LL(0x9d5451aa,0x7353ea3b),LL(0xf054ffc5,0xf2cd3afc), + LL(0x25b37d1b,0x148268ee),LL(0x6c58898f,0x9d597241),LL(0x5ef964a3,0x516c6871), LL(0x73756f60,0x777d95dd),LL(0xce04cb87,0x79b9b5e6),LL(0x371ab2f1,0xdbe50dca), + LL(0xb9c32a0e,0xc12a3617),LL(0xa6d8dedd,0xd368a553),LL(0xef101236,0xdf472f4d), LL(0xa749514e,0xd6bc5900),LL(0xc2a203dd,0x7531976c),LL(0x983e67ab,0xa5bbf91a), + LL(0x5ee73780,0xad4ada0e),LL(0x41fe693b,0xdf363734),LL(0x1a88c54c,0x996727c5), LL(0x6f0cd51a,0x635e6cd5),LL(0x4e75f89b,0x93d7e6cd),LL(0x2326e236,0x761b08f9), + LL(0x27a21294,0x719c6065),LL(0x0f25f450,0x5fd2859d),LL(0xd52b85df,0xd10bf835), LL(0x40de93c0,0xa6fd2831),LL(0xf7c3a0d4,0x89c1bd7d),LL(0xefebe6be,0x75fed863), + LL(0x17c97de1,0x921b88ad),LL(0x2cd59e91,0xb48dc81c),LL(0x73f3504e,0xda03b882), LL(0x5f2ee761,0x39ff606f),LL(0x5ad4f4de,0x608772a2),LL(0xc72d7dbc,0x2b4d5732), + LL(0x17a8bdb6,0xd5d5f3d4),LL(0xde7a418e,0xcdadbfcd),LL(0x73f2b0da,0x2fbe10bc), LL(0xdd2b933a,0xcc436783),LL(0x120a26f4,0x7d464c7e),LL(0x3295a8b8,0x2e25a06a), + LL(0x4edfcc33,0xce566ba6),LL(0xb883585e,0x72ced5ee),LL(0xe257f582,0xc7a1597f), LL(0x42dd036e,0x469e4698),LL(0xcf916dd4,0xf534e335),LL(0x5409b755,0x2a1a0ac7), + LL(0x9c7ba23a,0x2ee09586),LL(0x2d9a1fbb,0xd9dae4aa),LL(0x0701d2cc,0xad876506), LL(0x35d64ab2,0xb9eaf2f9),LL(0xa2ca2cf4,0xc8a57b67),LL(0x0938f8b2,0x7e81d43e), + LL(0xf1f4c06c,0x517ac75d),LL(0xd2fb833a,0xebd83a3b),LL(0xd0ceba1a,0xe14412b0), LL(0xc203df53,0x14bfd5f7),LL(0xa3cc4222,0x8eddee82),LL(0xe0413bc6,0x987370db), + LL(0x2c70f714,0xc3aa5190),LL(0x1e87511c,0x35550f45),LL(0x207b35cc,0xacdb541a), LL(0xddc40e1e,0xd645313b),LL(0x5d7745fb,0xfadf08df),LL(0x63f5d14b,0x34c4a2da), + LL(0x74f5662b,0x3bf9a89c),LL(0xc3293614,0x26fa24f5),LL(0x93645819,0x2232f2bc), LL(0xb642a3d2,0xae2493be),LL(0x4354eadc,0x67888dfb),LL(0xd5a343ce,0x7917ebd9), + LL(0x22e18ac9,0x83f1a578),LL(0x96227250,0x754ac8ad),LL(0x02f84593,0x8720c7b5), LL(0x6077017a,0xbe8034ce),LL(0x125f0aba,0x0e38bcc9),LL(0xd7c001b7,0x491175d9), + LL(0xdc6d9d65,0xdc830479),LL(0x8402b7f8,0xd961ba98),LL(0x85d31cef,0x9a870f49), LL(0x747a1a30,0x3f08d97d),LL(0x5e845976,0xf5cd0560),LL(0x39c404c9,0x34b2e606), + LL(0x479f9f28,0xc6be3e89),LL(0x8639cfd5,0x277e7391),LL(0x6eac029f,0x90018430), LL(0xccc296ef,0xdeebdb98),LL(0x6c909542,0x225d9267),LL(0x37a527ab,0xcf151ac4), + LL(0xa65460ad,0x40e22878),LL(0xd388bcc5,0x0a345fb2),LL(0x01c72449,0xfdbb8d02), LL(0xb73e0d19,0xeef0f1e3),LL(0xbbfdd87f,0x4ec39f63),LL(0x5ef57d3b,0x79501995), + LL(0x60873c20,0xd6dbf138),LL(0x6715b03a,0xeee2c9aa),LL(0xa7482c51,0x2f5e5ce2), LL(0xc3dd1233,0x927e5fb2),LL(0xd64c61c6,0x72dde264),LL(0xcd32e0b4,0x605f8de1), + LL(0x5b9091af,0x8ca120c2),LL(0x0f0fb8bb,0x6f7fa55e),LL(0x87264d00,0x78e97110), LL(0xd0f9cca4,0x63be0590),LL(0xe863c20c,0x4825ad2d),LL(0x12449414,0x4c34ba2d), + LL(0x21fd0243,0x0256c27d),LL(0xa2406f04,0xbe85c36f),LL(0xb457d240,0xa30e427f), LL(0x3b4a0eb7,0x4bc8ea0f),LL(0xbfb3b1d4,0xf84a988b),LL(0x20a37ec6,0x1e9d2665), + LL(0xb27e7722,0x07d6c0ef),LL(0x6729edd8,0xb81d03e2),LL(0xecf969a0,0x75b9e7d4), LL(0x72ad86dd,0xef9c8251),LL(0x9292331b,0xe609a51d),LL(0x35e1a81c,0x0df83add), + LL(0xc5478838,0x73e31c76),LL(0x44828fc8,0x1a131a98),LL(0xb5e70dd2,0x14e09dce), LL(0x4a72dd31,0xb38126a3),LL(0x5b0e772f,0x3d06723b),LL(0xb7d1198d,0xca600717), + LL(0x57b91e05,0x047cb901),LL(0x7e21d7a5,0x1946f1b6),LL(0xccec26a7,0x042e3eca), LL(0xfd416a33,0x0d9f9119),LL(0x49019bf8,0xdf57814c),LL(0x6527b664,0xe01c04b8), + LL(0x359b599d,0xc0fb1444),LL(0xbd4e90c3,0x09858bf6),LL(0xe4adda27,0x1ad5019b), LL(0xe2069275,0xa8229db9),LL(0x2e9a9c96,0x4af49c04),LL(0x32909ac0,0x2eba27df), + LL(0xba29ac20,0x44771234),LL(0xa8f7d70a,0x91271936),LL(0x35e3439b,0x1d2553dd), LL(0x66de658c,0xa35e4915),LL(0x5505ca57,0x958c5d53),LL(0xefac11c3,0x5806c454), + LL(0x68947de6,0x480af451),LL(0x20ed7c76,0x1970a51c),LL(0xfd273a2b,0x13be8cf8), LL(0xde3fb216,0xdaa99fc9),LL(0x007e796d,0x9e1ecd60),LL(0x1145bac9,0x0d61162b), + LL(0x1a7240fd,0xd324f3e5),LL(0x02dead6f,0xb652ceb5),LL(0x945e4927,0x9d2efe09), LL(0x09d3fe5a,0x505409cd),LL(0xd0b1d40f,0x4068d39b),LL(0x3d2add11,0xb169ceb8), + LL(0xf87110f6,0x95209c85),LL(0x9d8c8473,0xce5e933a),LL(0x2dac6c5c,0x50e9c87d), LL(0x6c95d63f,0x5ad288c5),LL(0xc2e80fdb,0x9801bde5),LL(0xcf50ed4c,0x6d577a05), + LL(0x5c341a0f,0xb2952c0b),LL(0x08fc2f1a,0x5296d67b),LL(0x595be428,0xb671036e), LL(0xf1974091,0xca815a34),LL(0xd7822f17,0xe4a2f88a),LL(0xaeba3ed7,0xdfc557f7), + LL(0xf1f5523e,0x78c30cae),LL(0xa828197b,0x467ad201),LL(0x41532182,0xccf347b4), LL(0x84ef4bc9,0x67c4ff37),LL(0x98cade6e,0xebeb3d71),LL(0xa59ab992,0x979dba66), + LL(0x0a363201,0x5ff9bcb7),LL(0xcc8b691a,0xb6995231),LL(0x62797899,0xc9aa7830), LL(0xcf5ece20,0x57d1c888),LL(0x963c0086,0x688d3d70),LL(0xc85a248d,0x91091fbe), + LL(0xe39ec208,0x4d6e7182),LL(0x8d5cf62a,0xda235ace),LL(0xde7dbbdb,0x33f70b00), LL(0xe66a3b86,0x60f841c4),LL(0x42d7e874,0xbf8660af),LL(0x80f2c57c,0x073c5f84), + LL(0xbc4f1599,0xd80d4f36),LL(0x185811a7,0xfd5e23b6),LL(0x7ac38f06,0xc8b0fa81), LL(0x43e96490,0x652d79b3),LL(0x73d98971,0xe222aa1d),LL(0xd121248f,0x4b6278dc), + LL(0x3c14b2d0,0xce20c25e),LL(0x98193e2e,0xd1379c97),LL(0x6d804130,0x21102482), LL(0xf20fb7a3,0x577f8229),LL(0xb4f08660,0xdef46260),LL(0xe4dffb3e,0x8bb54fac), + LL(0xc0ecadfb,0xbc45d692),LL(0xd3435c47,0x2d92602f),LL(0xa5dfe7a5,0x29e826c0), LL(0x42a0c989,0x9272dc04),LL(0xe3b3a440,0xc1eddc74),LL(0x65741581,0x741fa074), + LL(0x75dbc772,0x0e2a8f97),LL(0xcc5e88b1,0xed5c6a60),LL(0x715808ac,0x099753c4), LL(0x9cd4d1fa,0x515d4892),LL(0x78393560,0xc4e5c9fe),LL(0x59206312,0x7ce9ac16), + LL(0xba61c10c,0x05e139c7),LL(0x56285997,0x83c2806d),LL(0x80f93027,0xf308c086), LL(0x3d95ff97,0x192570cb),LL(0xb69f20a2,0xd7677bc9),LL(0x9a9416a8,0xfea2554b), + LL(0x2ac3e62c,0xe26cdbf8),LL(0xb719cfa9,0x99cfefda),LL(0x7c7c2f30,0x67fc003a), LL(0x529cd8a8,0xfb8eb991),LL(0x8902bddd,0xe63830d5),LL(0x87d9a82d,0x8d0dd890), + LL(0xcdd4c46f,0x239f32f2),LL(0x4de15fb1,0xf9517e3f),LL(0xbb8c38ff,0xc8183a19), LL(0x4f41bc08,0xefe4c3ef),LL(0x36ec7fd4,0x900d74fe),LL(0xfbf56005,0x49b24c64), + LL(0x2aae4376,0x8c1c4bb0),LL(0xf9c1a936,0xe9eadc2b),LL(0x9b62791b,0xea437c5a), LL(0xafe6482d,0xb43a409d),LL(0x5ae0e629,0x405189df),LL(0xb6b6e06a,0xb60dbb63), + LL(0x122f06d7,0x015b080a),LL(0xe52d69ac,0x8fe18e03),LL(0xbe34ac7f,0x54894766), LL(0xd5131f42,0x60d01c43),LL(0x24b2ae7b,0x179b14a6),LL(0x6e7c925c,0x2478209d), + LL(0x7667ec3c,0x037b49bb),LL(0x0ddcd693,0xb4751c25),LL(0xe82b8e88,0xa9933bfb), LL(0x741344e2,0x14f812fc),LL(0x25e24d12,0x7253361b),LL(0x071df26d,0xaba4f18b), + LL(0x05bcc791,0xfe1f3f2f),LL(0x33608ce5,0xe3ae1232),LL(0x672aa21b,0x3325659b), LL(0x9a01ebde,0x6d572c9a),LL(0xa10425ad,0x733c2067),LL(0xf7e7b67a,0x80f1da8b), + LL(0x2e21e1c3,0xdcba0c7d),LL(0x79eb4307,0x08883499),LL(0x27cd2b91,0x5a5ee0f8), LL(0x13a4c6d0,0xcc6494e2),LL(0xb3270d14,0xdc1c75e3),LL(0x66eb04f8,0x64e17db8), + LL(0x3e232e2c,0x1b8e2672),LL(0x0e99fc0c,0x1553fed2),LL(0x3c3d73af,0xe4e6608a), LL(0x3ed25820,0x8dc28c2a),LL(0xcadc377d,0x5f375146),LL(0x4b113c00,0x09e1c08d), + LL(0x2d096c20,0x567cec1c),LL(0x9c346dd2,0x0b3fb247),LL(0x79a71044,0x1e4c1e43), LL(0xd86defcc,0x4980b895),LL(0x7175491a,0x9ee53061),LL(0x979cdece,0x28b5bb15), + LL(0x16b49afc,0x36cb6dd6),LL(0x9372557b,0x498a1aef),LL(0xfa192344,0x4e51a28e), LL(0x6cdd93bc,0xf5a4373e),LL(0xec6a751e,0x54a73a75),LL(0x841194aa,0x9a563884), + LL(0x91ad93f9,0xa95a8a06),LL(0x540e0c19,0xb0681b8a),LL(0x4f815aec,0xb0cb9c4d), LL(0x9b9c744a,0x5acf61c1),LL(0xfa7f4dc9,0x72c1126c),LL(0xcc2a7aa2,0xa5afea44), + LL(0xf614aace,0x5a9fbecf),LL(0x794afb09,0x2e940ee6),LL(0x0ecaf20e,0xcc5a62de), LL(0x7a41866c,0x57634449),LL(0x4335ac0c,0x365bb619),LL(0x537165fb,0xe8c5699a), + LL(0x0db61f1e,0x61966988),LL(0xf31a42d9,0x9a86bd4a),LL(0x93826e9b,0x712f2cdb), LL(0x17d5867b,0xd8edee16),LL(0x8710c50b,0x1e25628f),LL(0x7daab4cc,0x4f0c8f12), + LL(0xd3fea70e,0x0ec1ef9f),LL(0x6591a1bc,0xdff00f61),LL(0x126ace6d,0xb680207f), LL(0xc5b9722e,0xfaa3fd69),LL(0x0b3e7f42,0x4a46ce3d),LL(0x49ba8836,0xdb76aec5), + LL(0x77738737,0xeaa46cad),LL(0xe1b12f15,0x5c0f2ebd),LL(0x0ca12f78,0x1b07bf63), LL(0x8dd854dc,0xbe19584f),LL(0x11c1c918,0x9ac8971a),LL(0xb3600069,0x72f4b00d), + LL(0x43f232a4,0x8c0c1e19),LL(0x6a116ed0,0xbd774022),LL(0xbebaeb71,0xee2ead3a), LL(0x861ab743,0xf224296d),LL(0x650a381e,0x37b4d979),LL(0x8d64e6f5,0x7a8da726), + LL(0xd9e956fe,0x528c8c28),LL(0xa1f5f87c,0x1bb92006),LL(0xff91e588,0xf2e662c7), LL(0xbb5cfe01,0x36ad72ae),LL(0x19e772d5,0xf489b95d),LL(0x8b6ddd88,0x77675dbf), + LL(0xf10d59a9,0xa40a5023),LL(0x250fb5de,0x15965ab7),LL(0xb539afcc,0x27808277), LL(0x8cab9918,0xf7f7ee31),LL(0x6c0353bf,0xd5b05608),LL(0x5255c6a1,0x20a150e8), + LL(0x192fc198,0xdc6a57e6),LL(0xc3c7ed17,0x3506fc9d),LL(0xa4a271bc,0x916219f6), LL(0x964b3816,0x03f8b160),LL(0xf1a09190,0x454bae16),LL(0x6fab73b1,0x6d316b41), + LL(0x5c22fc9b,0x768669f6),LL(0xe0219ce7,0xc2bbb0c5),LL(0xaf224185,0x77d99a44), LL(0xcead6ae8,0x1bdcaaa5),LL(0x80bcad3d,0xa0015109),LL(0xac464ccb,0xde74800f), + LL(0x7c5f58b6,0x419fcc04),LL(0x423d4004,0xa28d071d),LL(0x30014ed7,0x2b51b7b8), LL(0x1e910824,0x51d2e74a),LL(0x049aba24,0x46142c53),LL(0x1c4c9bfc,0xeee290c9), +}, +/* digit=18 base_pwr=2^126 */ +{ + LL(0x3d7eba56,0x1432c61d),LL(0x9f3bcbe3,0x3e5748be),LL(0x70d4b4cf,0xd060396a), LL(0xd56cbe10,0x5cf4dd3a),LL(0x8c26eccd,0x6e120e45),LL(0xd44782b8,0x5a349466), + LL(0xece48d34,0x0aa69704),LL(0x72c3e801,0x5ae78e58),LL(0xdbbf3257,0x8cae7cdf), LL(0xad51d342,0x7f33e06d),LL(0x8c54f76e,0x842b3c9b),LL(0xd9738bf1,0x27439730), + LL(0x8d92d2ec,0x606dcdf3),LL(0x47bce9e6,0x80661389),LL(0x20424ac9,0xf9e37e1c), LL(0x1d4308c4,0xb4271df8),LL(0x2524d693,0x32991fcb),LL(0x3eb1eb87,0x1b3e3739), + LL(0xb01d8c67,0x1366f4ea),LL(0x12c079e1,0xfc0e2aaa),LL(0xc73eb944,0xde8828da), LL(0x4fb7452a,0x1be389c3),LL(0x3ab20ed9,0x1b47de61),LL(0xe88a74b5,0x0a0e4dd5), + LL(0x9f3a0e52,0x42086dea),LL(0xdea9b529,0x2b27362c),LL(0x0f6b324a,0xa601b101), LL(0x8d8999b3,0x50deb5db),LL(0x0f97d636,0xb5146466),LL(0x7452ad66,0xe400edf5), + LL(0xf40e2c2a,0xcea8e0f5),LL(0x5c7a6851,0xd7a70dcf),LL(0x3c3eef95,0xb07f27bf), LL(0x6b31486d,0xebeaedec),LL(0xae6fd833,0xa6218332),LL(0x4c2f458c,0x19ce8eaa), + LL(0xb1bfa9ec,0xfaae66f3),LL(0x2742714b,0xc7b516dd),LL(0x8f55fcc6,0x6bd999fa), LL(0x1b07a49e,0xbdf9e3dc),LL(0xdb922eb3,0x8c8fe856),LL(0xe3b05757,0xf0e446dc), + LL(0xcab82ecb,0x12bfbae5),LL(0xe279d4d5,0xae24cbb6),LL(0xaaa064ed,0x2ae08e15), LL(0x053194f4,0xe4f4d9f8),LL(0x4fb349c2,0x66627f60),LL(0x7d673df8,0xa57270c4), + LL(0x8de75f76,0x79c8e28f),LL(0xb5103e06,0xc46d7632),LL(0xb99c0669,0xee23de7a), LL(0x112100cb,0xb6a05082),LL(0x559c6fe6,0xd3aaf2ba),LL(0x310d9cda,0x1fa98099), + LL(0xd68c0cdd,0x66b15c32),LL(0x316bb565,0xc1a8dcd1),LL(0x66388e62,0xfe124230), LL(0x6aa0caf8,0x87421a82),LL(0x45ae8aba,0x163ed8a0),LL(0xf8869a95,0x799ecc06), + LL(0xb1f08b18,0x9b5f811f),LL(0x8a8e6e51,0x21df77e4),LL(0x41906e3b,0x0ece8f82), LL(0xb358dbd7,0xcc8f1a7f),LL(0x348f81d2,0x7eae1659),LL(0xba2fc496,0xaeb9bf86), + LL(0xe8ee3475,0x1d24ece4),LL(0x0333898d,0x3a9629c6),LL(0xaa4b4d26,0x51fe2f63), LL(0x45450f91,0x65713078),LL(0xed53b1a6,0x9fe570de),LL(0xccfc903e,0x49d5947a), + LL(0xd12646d4,0xd1a4ee1f),LL(0x108a021d,0x8be0f550),LL(0x0c9a397c,0xadca94e2), LL(0x7a116b52,0x443e40d2),LL(0x4a7e4f8c,0x8922a749),LL(0x11b9faaf,0x13dd25d4), + LL(0x677337c6,0x23169fd1),LL(0xf4275e2f,0xe8b155ff),LL(0xaa432608,0x199fd451), LL(0xd6a8a707,0x43fae1e4),LL(0x22598f5c,0x30b74dae),LL(0x4412a37e,0x3231c5fb), + LL(0xa6ef8dc3,0x242076a6),LL(0x3531d9ba,0xa91fa776),LL(0x15395cc0,0x77f95454), LL(0xc333f3fd,0x2d82f42d),LL(0xd57091bf,0x0ebcdf5c),LL(0x04a7020c,0xced34ce1), + LL(0x8a8c3087,0x996010a0),LL(0x8731577a,0x2e13009d),LL(0xfb82ff62,0x4a13fc99), LL(0x54ffd5e2,0x03887d55),LL(0x72a2d703,0x81a63ca5),LL(0x61a70095,0xffd0fd49), + LL(0xa9ab8d73,0x08cb1949),LL(0x30fcdafe,0xbcd463e1),LL(0xcb2946e3,0x1bd9c440), LL(0x7b685a62,0x67df0c20),LL(0xe6a0b599,0xc85033b3),LL(0xdad9fc5e,0xc26cb4c0), + LL(0xd189ee56,0x2915b334),LL(0x7df4385e,0xec153690),LL(0x74e10903,0x78c1233a), LL(0x99e6424b,0x1aad36db),LL(0x8e6c1b2a,0xf0985d3c),LL(0x94d7d170,0x2378ac4b), + LL(0x4f4a6728,0x2b339c66),LL(0x682d8695,0xb36bf9a0),LL(0xea6efc7f,0xe5077906), LL(0x8c8272d1,0xbe19ad2b),LL(0x80ba118b,0x2273dd26),LL(0xbc2ebef4,0x1afaebc8), + LL(0xd967a41e,0xebfd1e2b),LL(0xc3fded13,0xf89bd7eb),LL(0x5e968c2e,0xfa2e6197), LL(0xd2842061,0x75e0b500),LL(0x81e69daa,0x484219aa),LL(0xe5989ba9,0x3a9fc283), + LL(0x827deaa4,0xc54392cb),LL(0xf39f1cc6,0x09b5364b),LL(0xd2711eb8,0xccce7212), LL(0x9b8acd72,0xd4aab549),LL(0x0cb6dec2,0x030af88b),LL(0xc5188526,0x9852b073), + LL(0x8119cabd,0x0cd88f26),LL(0x92f36a37,0x09ad060f),LL(0xea4ffb39,0x60e5c4a0), LL(0x44aa9c46,0x29530c7c),LL(0x98565223,0xbc1d4e89),LL(0xd46de9ba,0x1aa44a30), + LL(0x2ac56598,0x33cdcbc5),LL(0xdb40e83e,0xe16fab9e),LL(0xa7fb4b01,0x2e90d12b), LL(0xfe18a04f,0x80c85443),LL(0xf59d5ddb,0x27fae391),LL(0xa121c824,0xd75f7ffa), + LL(0x21d0d7f1,0xacf5993c),LL(0x04b7c788,0x159623b7),LL(0x35cea4b4,0xc631a623), LL(0x36f64979,0xc75060d1),LL(0xde81f49b,0x93d67ee5),LL(0xb1c080dd,0xc8b7ddec), + LL(0x88fc80b3,0x86602cee),LL(0xa52e2b85,0x8d378408),LL(0x7b43597c,0xb66f2489), LL(0x34ead5db,0x8fa5fe75),LL(0x872b559f,0xa91b7b3d),LL(0x969b74d2,0x34007f49), + LL(0x31a991bc,0x7ac027f0),LL(0x231f0bd6,0xce3e5a83),LL(0xa724434a,0x6059c8c4), LL(0xbf199050,0x3949f4fc),LL(0x50f4c59e,0xc8d1ce42),LL(0x2c2e840e,0x406e976e), + LL(0xff33a74e,0x70c69777),LL(0xbce579fb,0x0caa3c59),LL(0xe3cc09ca,0xcba746d0), LL(0x7493a1a1,0xe544dacb),LL(0x74ebeba1,0x84d251ac),LL(0x7b5a26cb,0x24c351ad), + LL(0x438babd3,0x882cde8d),LL(0x4a0c3725,0xc88a8ff9),LL(0xa80a190f,0xee17ee44), LL(0xb11442f3,0x50337a67),LL(0x7f7eed2a,0xc6803f55),LL(0x36750d2d,0xee2e0425), + LL(0xe5eccbeb,0x9614df9b),LL(0x6d8a00a6,0xa42fa89b),LL(0x5cb36d70,0x90d5f6eb), LL(0x06790958,0xcc2994e9),LL(0xbda37f56,0x4c4820a0),LL(0x109395c2,0x4ac16bf5), + LL(0x4d5e93c7,0x57f12bfa),LL(0xae11e7bf,0x6f57c3c7),LL(0x805ee169,0xe0c53938), LL(0x27da73c9,0xb1ea61d1),LL(0xf1ca8fcf,0x812387b6),LL(0x9aaad2cb,0x812bbf9b), + LL(0x673f3249,0x103ab65e),LL(0xf91c5bac,0xbccd32cd),LL(0xb7502b99,0x2cd17117), LL(0xc6ee643f,0xacbc6b98),LL(0x7e3a9007,0xe45beed2),LL(0x39540d2d,0xd6e7cbb3), + LL(0x735d7a7e,0xf5ba275a),LL(0x939bb080,0x7d56e5bb),LL(0xa316d8f3,0x632ae0df), LL(0x44834265,0xb16f0da3),LL(0xc0e774a9,0x2ac41378),LL(0x963763b2,0x2d1368a7), + LL(0x2910cb9b,0xbb909572),LL(0x7ec8764f,0x9b97d7d3),LL(0x0a1f7187,0x45ed9127), LL(0x91607114,0x4911eae6),LL(0xbec9af64,0x5a3283f3),LL(0x24181e7a,0xfad12d4a), + LL(0x304aa2f6,0x7130416a),LL(0xa93ea2a4,0x3d8ec32a),LL(0xb42283de,0xf746be9c), LL(0xfaf3861d,0x122fff14),LL(0xfc5c58f9,0x85c1a762),LL(0xa1051cf0,0x096434ec), + LL(0x7f5300f5,0x991bef56),LL(0xdb18ccbb,0x8a974cb7),LL(0xd51e5e8d,0x95e6464d), LL(0xb24414cc,0x7891a137),LL(0x78ca6881,0x614852b1),LL(0x11512b7e,0x8ce344f9), + LL(0x14180a17,0x225c5475),LL(0xe0402e95,0x20f7198f),LL(0x7dc14a78,0x834328aa), LL(0xf00864aa,0xf9f3f9d9),LL(0x5c929f4e,0xc14ac9fd),LL(0x67caed5a,0x565edd57), + LL(0xa3116bfd,0xc3febfae),LL(0x25b0091a,0xd28b9297),LL(0x43d43e9d,0x71940761), LL(0xa6743cde,0x0b0dcd52),LL(0x85916ef5,0x0d9c9307),LL(0xed0ea307,0x16d7fa15), + LL(0xd874f8fb,0xcd73c3b4),LL(0xdd4872db,0x89f049a0),LL(0xd6c574e0,0xa3c1e344), LL(0x1501c2b5,0x42aa48a1),LL(0x4379b187,0x08c07386),LL(0xdb94daef,0x651b8ea0), + LL(0x2a46e40e,0xb29008a4),LL(0xafe5ce10,0xf8cfacfa),LL(0x1f36cf21,0xc20de58c), LL(0x77586b4e,0x1667beb5),LL(0xdb697901,0x549fbdad),LL(0xbec7838a,0x05d84e16), + LL(0x86573220,0xca40cc00),LL(0xce72bdb3,0x2b43ccde),LL(0xf187d609,0xd8d285d3), LL(0xcbb90bdf,0x975d5583),LL(0xdb3ce7c8,0xd8e1edb1),LL(0x1be6a0d8,0xf24a6f87), + LL(0xc5db734e,0x72d204bf),LL(0x1ead06dd,0x4b794609),LL(0xd899503a,0xab7e900a), LL(0x808698fa,0x682a67a7),LL(0x81d2be81,0x8d5f7a3f),LL(0x6db17983,0x5ac7f636), + LL(0xf5d8bc59,0x58e88381),LL(0xbc6677a0,0x0c14b7eb),LL(0x75f0beea,0x26d7fb70), LL(0x3c789c7d,0xf71d6c28),LL(0x31a64d6a,0x0e1c3ef5),LL(0x3a025a05,0x930f15cb), + LL(0xf84e9a66,0xa848b469),LL(0x0a6acdfb,0x8b3620ef),LL(0xc0f3c653,0x803dc9e4), LL(0x70d4aaad,0x87b9452d),LL(0x2e5341df,0xd2039635),LL(0xcee3e654,0x1518ec72), + LL(0x75e30599,0xd89bb62e),LL(0x358eb463,0xffb8be40),LL(0xac2b9c1d,0xcc7b8c90), LL(0xbe967747,0x14076fcd),LL(0x9e9118cc,0x4c590a0d),LL(0x7fdedab7,0x255af971), + LL(0x0bf36a0e,0x7cb0703b),LL(0x2f6e1ad6,0x9d4f60d3),LL(0x80851e9d,0x0ddfa57d), LL(0x320a950b,0x0d7e34d2),LL(0x3cf9b367,0x344c00bb),LL(0x7f5fb665,0xbf5c2104), + LL(0x5c85310d,0x01355f1f),LL(0x430840fb,0xa17a28ca),LL(0xbddb8e53,0x1573b14f), LL(0x1be8bb25,0xb6e9f88e),LL(0x68f882ed,0xf8283ea2),LL(0x9f8a6c36,0x97b1f85c), + LL(0xf96965eb,0x16d8df1e),LL(0xc2b9fd6d,0x347159dd),LL(0xc973dc04,0x5a8ff74e), LL(0xe385ad6d,0x6b89c04a),LL(0x76c7bedd,0x1604bc1a),LL(0x09914658,0xc1e216de), + LL(0xe5d7f3b0,0xe285c4b9),LL(0xde0ec465,0x340ea40f),LL(0x51eaa759,0xddc7e286), LL(0x2a2118e1,0x3d1f99a9),LL(0x99fa6ada,0xf8dbccb1),LL(0x2e831534,0xdcb7d5d1), + LL(0xa33e53ea,0x90c5048d),LL(0xc03b6f58,0xe68e4543),LL(0x0585ccce,0x2c9860a2), LL(0x15f92a46,0x948b7875),LL(0xa62a0f0f,0x913f01ea),LL(0xa35eeb9b,0x06623f96), + LL(0x9c77ae5f,0x403740c1),LL(0xd975126c,0x25df8030),LL(0xaf1bd02a,0x762b3d5f), LL(0x7a17ca9e,0xa9ef424f),LL(0x5bbdefcb,0xf0e425ee),LL(0x6ed00a8b,0xafa22cf9), + LL(0xfdcc0852,0xdcb9848b),LL(0xe4e8b45d,0x22851be9),LL(0x195c527a,0x25543398), LL(0xc4ffcb5c,0x39a1709a),LL(0xc84717ea,0x9d6bc1dc),LL(0x3080227e,0xc5a9436a), + LL(0xafcc481e,0xfcc2dbcb),LL(0xe8bdacd0,0x936af760),LL(0xa208d23c,0x37762746), LL(0xcf4cfb3d,0x7c32898d),LL(0xbe8d86f7,0x4c7103db),LL(0x29137736,0x0e8e29e9), + LL(0x5fb1f4df,0x4dddcd9d),LL(0xf8e40af7,0xcee0b177),LL(0xd5ed5e8c,0x2d5eed04), LL(0x4436fde2,0x8c57cd9f),LL(0x59431816,0x6d9ae88a),LL(0xfcd05844,0x410d80be), + LL(0x4f2e214e,0x72cb7d76),LL(0x50149bdc,0x84aecdf4),LL(0x29a10599,0x55c54af4), LL(0xff356cf8,0x15b4a13c),LL(0x94c1cdb7,0xe251ef48),LL(0x3c294aa2,0x3d868b7d), + LL(0x38ac42ad,0x61562246),LL(0x9857cdde,0x35bea87c),LL(0x3bff3a31,0xe288cd86), LL(0xfeff112b,0x6de40901),LL(0xfb86b4fa,0x4c3ff10e),LL(0xa2760141,0xefb2ebbb), + LL(0xb651d24d,0xfe675b81),LL(0x1bf57d70,0x58decfa4),LL(0x3e407d11,0x6d577314), LL(0xc363e64b,0x99100a53),LL(0xd5b05ad2,0x3700486d),LL(0x3d16a4f6,0xd725f452), + LL(0x4369d7d0,0x7987446d),LL(0x082a8d9a,0x6f73c9d4),LL(0x90c45db8,0x50f2643b), LL(0xa8b8a26e,0xc0547960),LL(0x0419c5f9,0xcf0cc729),LL(0xa88c242d,0x36ec0c68), + LL(0xab61869c,0xc39acd0f),LL(0x52d501d6,0xb3676312),LL(0xe963c20d,0xcce446cb), LL(0xd5427311,0x171ef8f9),LL(0x0a43e236,0xd2250f20),LL(0xbf664fa3,0x3734c3a6), + LL(0x3a865bc1,0x4debd2e7),LL(0xbffefe51,0x48d3b6e2),LL(0x39246490,0x63d793f1), LL(0x07251f37,0xf2e568cb),LL(0xb86ac8ba,0x0543ce7c),LL(0xf0233d6d,0x34c94bb8), + LL(0x6b22f5d4,0x825d20cc),LL(0x87e8b87c,0x3008f0d6),LL(0x6fe24ecc,0x1f179a44), LL(0x3732b8f4,0x45b86fc1),LL(0x5bf33be2,0x280c34e0),LL(0xacc6b35b,0x3656ee7c), + LL(0x3de8e3cf,0xef5aea9a),LL(0x13295f9a,0xdaf53c2f),LL(0x37faa7d5,0xef4cb920), LL(0x7b389099,0x7cc42259),LL(0xf4bbc5ab,0xa229e4b0),LL(0x369283c9,0x75a6dd11), + LL(0x208de900,0x2472c7bd),LL(0xfe199477,0xa707b3a7),LL(0xe84304aa,0x4eeabcfd), LL(0x69fb0f07,0x8a125707),LL(0xcff32ccb,0x8146ef85),LL(0x6874ae86,0x924e6627), + LL(0x5baf5149,0x7ebfdd60),LL(0x6fd26802,0x060d10ff),LL(0x433383ae,0xed4cab01), LL(0x6ae53b2f,0xf6529a62),LL(0x17680c05,0xfb786ea5),LL(0x6a368e73,0xe22d7ea8), + LL(0xd5b48338,0x52e49947),LL(0x0b58cffa,0x70575502),LL(0x3097c699,0x0f568fcf), LL(0x2ebb3f51,0x3a78100a),LL(0x6ebf4f52,0x8ca651ed),LL(0xaf034c4a,0xc21be721), +}, +/* digit=19 base_pwr=2^133 */ +{ + LL(0xb439db86,0x318e0141),LL(0x6ba0c36d,0x24dccf9d),LL(0x278f654b,0xe30ecdee), LL(0xcc96cfd2,0x3b53ec8b),LL(0xffdef7f9,0xb15365ab),LL(0xb77c2bdb,0x2886538d), + LL(0xdd6dd374,0x16beccc0),LL(0xe0de912b,0xab022ba4),LL(0x9fa6c113,0x0fa1e066), LL(0x5602f255,0xa62f3440),LL(0xde5080c3,0xf1744743),LL(0x959de74a,0x5dc10f57), + LL(0x30bcd508,0x3fea4a00),LL(0xd7784a23,0xc4b99502),LL(0x22777f72,0xc2aae8e2), LL(0xb738b26a,0x0998acd7),LL(0x284a4687,0x01c21758),LL(0x60aa1544,0x86331b2c), + LL(0x044902c4,0xb138ec30),LL(0xbbc5aa92,0xedbb10a5),LL(0x8cf968b8,0x78dab5f0), LL(0x5582adf1,0xc522aa4d),LL(0x757f6d77,0x27b2cad3),LL(0x8496e06e,0xd99cc418), + LL(0x14b10f6b,0x353a03a9),LL(0xd618e82c,0x0e0360ad),LL(0x5c8ba6c1,0xe95b9c21), LL(0xa2aca406,0x420fcef8),LL(0x3d0af393,0x511e7327),LL(0x4d7c2d87,0x240d0932), + LL(0x0431f61e,0x72bc67e3),LL(0x35cbaced,0xe0b8c3f5),LL(0x811b966d,0xec526634), LL(0xedbca0fb,0x994e956d),LL(0xec733f7b,0x1d1d456a),LL(0x10d8156a,0x481983f5), + LL(0x25b3e1e1,0x2d4c36da),LL(0x63bd55c6,0xf81e5e71),LL(0x1d80e9a3,0x8ebaa53f), LL(0x5d2b6568,0xe162ca96),LL(0x58264463,0xae3e0e1d),LL(0xca65ecfa,0x4d50c694), + LL(0x2b0d1ddf,0x9dbc08f7),LL(0xabf627f7,0xe9e345da),LL(0xa7badd66,0x110cebe6), LL(0x48702def,0x8055893e),LL(0x987a98ba,0x04470e1b),LL(0x1d380312,0xc27475da), + LL(0x9fea7b29,0x8a275184),LL(0xcaf14cdd,0xdc9a9a94),LL(0x5aa56285,0x6c8859b5), LL(0x242a5eee,0x9eede9fa),LL(0x0b4d4c44,0xb738b0f2),LL(0xda57c6cc,0xcd8174f8), + LL(0x3cb5df38,0x32b55a3c),LL(0x0cbf8de1,0x2bf1c097),LL(0x9b7812a9,0x1f27c2f2), LL(0xbb4241cd,0x41cfb699),LL(0xb8cefac0,0xf25fb9ad),LL(0x4b462fe6,0x0e8ea882), + LL(0xb2fa7ed3,0x6d1fe0cd),LL(0xb805f909,0xa5afec06),LL(0x50929ff7,0x7114c77f), LL(0x41e73d2a,0xb70a0449),LL(0x412afd6a,0x17353c86),LL(0xe777054a,0x4b1ab341), + LL(0xb6b4736a,0x205f30a3),LL(0xec96f97b,0xdc57c0dc),LL(0x50892f3d,0x6026e016), LL(0x9872ee46,0x5587a900),LL(0xea0f599b,0xfa2e40d1),LL(0x5698483e,0xd0dfe28e), + LL(0xc978c548,0x96ea419d),LL(0xd41fdcca,0xc78106e5),LL(0x2c3d871f,0x1fcd9bd6), LL(0x8f18504e,0xde3a3b13),LL(0x147e11bb,0x41af768d),LL(0xbea88154,0x57db2d46), + LL(0x359605ca,0xa03b50ed),LL(0x8d2e6f9e,0x102d624a),LL(0x021fbaee,0x75846c7d), LL(0xfde66141,0x7ce93a17),LL(0xcb75846b,0xff36566b),LL(0xdfe8687b,0x13f15dbc), + LL(0xb6900145,0xa1762cdc),LL(0xd04f6298,0xc52758d8),LL(0x05fb29ed,0x2388b649), LL(0x952caba9,0xf559602d),LL(0x612d83d0,0x7a57aa1c),LL(0x798f6741,0xb0a70b52), + LL(0x718b8cfc,0xd977e424),LL(0x9724fb0c,0x0bd2e7ad),LL(0xb4b77d96,0x62055643), LL(0xf3b93b52,0xabe7d1ae),LL(0x29f1f8a5,0x2573a99e),LL(0xf1ae95ae,0x9d861485), + LL(0xf37551bf,0xff5d9174),LL(0xeed4fbcc,0x2120b50e),LL(0x61f2e529,0xe442a255), LL(0x2f0b3221,0x1991c2ac),LL(0x598ea6d0,0x39e9fba8),LL(0x38f4004e,0x3e215ecb), + LL(0x7112f48d,0xab373c03),LL(0x0cbf0146,0xb36e09a1),LL(0xf8d04ac7,0x750d400d), LL(0x1a257ba4,0x7a522a7e),LL(0xa6fe3d3c,0x19d94e30),LL(0xab24c6d5,0x8f563b6d), + LL(0xce3f76db,0x4e8f7ae4),LL(0x951e6883,0xf041cd61),LL(0x677e20c7,0xd5346ef4), LL(0x4f2fa361,0x2ecde00a),LL(0x24e52b5a,0xda39ea83),LL(0xa4037195,0xf13a1d6a), + LL(0x8122da8e,0xc4ef50c0),LL(0x1e4dfe54,0x44245ba2),LL(0x549eb736,0x51a3afe6), LL(0x149e53e2,0xb389a041),LL(0x019f7f33,0x59e1806e),LL(0x207e8b03,0xf0bf62ca), + LL(0xf023e16c,0x2afa74f0),LL(0xe45110c3,0xc0e3985f),LL(0xef4dc058,0x30d3c844), LL(0x0932e063,0x74a8fe78),LL(0x8d089afd,0x1694b37f),LL(0xc02cfea5,0x688b8d05), + LL(0x00b00b60,0x82d73a13),LL(0xec1be174,0x9914b5f8),LL(0x260cca25,0x4b3aa37e), LL(0xdb9eedcc,0x80edd7e4),LL(0xfac065fd,0xd734f788),LL(0x95ca6a6d,0x3bad348e), + LL(0x394ac74a,0xcc754ddb),LL(0xfdf2392c,0x499071de),LL(0xbcd3b3a9,0x64980287), LL(0x8ac174ca,0xf9ad94b1),LL(0x48adbfcc,0x7d8487b5),LL(0xeaa22b97,0x3b94b5a7), + LL(0xd830a7f8,0xdd6a5e09),LL(0x0a707d6b,0xe88ab4ee),LL(0x6f282e77,0x65064114), LL(0x05630c1d,0x732b3f5f),LL(0xa32278e4,0xedc7f608),LL(0x40aa906b,0xf9cc5a48), + LL(0x84cb7f2e,0x22cc8910),LL(0x492f6b49,0xe72c3a7e),LL(0xd9172542,0xcdfb7abb), LL(0x5379490b,0x332ca313),LL(0xc019dc08,0x74e34e7e),LL(0xffac012c,0xae01f427), + LL(0x6589755c,0x28a5ee38),LL(0xf5484971,0xc3c09b28),LL(0xebdc2e2d,0x98c22f2b), LL(0xb739eaf1,0xf34f7446),LL(0x40de5322,0x71c9f8f5),LL(0x8cf40eb6,0x94ace574), + LL(0x660ffcd8,0x14a05e05),LL(0x384c2a8e,0x13f0de7d),LL(0x192dd045,0xa52ddb4d), LL(0xea4aaf10,0xf4d36e86),LL(0xe77d2f45,0xfd9db24d),LL(0x904e7b10,0x55f85a8b), + LL(0x260ee499,0x315e7fcb),LL(0x15cbbecf,0xa3bb055e),LL(0xfda09d93,0x2634a003), LL(0x71c4d7c5,0x5b3c4fe2),LL(0xc9380c8d,0x6805f34b),LL(0xc8a539f9,0x587eeb71), + LL(0x51635be4,0xdd9571b7),LL(0x9e7aabb0,0x321a0e22),LL(0x55781706,0x8b2b23f5), LL(0xaea3c730,0x7cca33ac),LL(0xf95cb480,0x3f6401d1),LL(0x26a55858,0xa5ef93a5), + LL(0xc8b7c736,0x1eaf9f4c),LL(0xeb5b2b70,0x1dcb1722),LL(0x65aab50b,0x0d948725), LL(0x15e7c8ef,0x193c8d06),LL(0x6c391c08,0xf7745835),LL(0x897265d5,0xcbd15810), + LL(0xb54eb895,0x205436fe),LL(0x059b35b6,0x4300c84f),LL(0x9d231cce,0xab267da3), LL(0x20fa381d,0x25239fea),LL(0x004d10be,0x5781e9de),LL(0x14641496,0x36c78b47), + LL(0x99963302,0x0c2bd51b),LL(0x6afdcb5d,0x1958d45e),LL(0x25a00883,0xaa86d186), LL(0xe705abde,0x14852c1f),LL(0xc056e6f3,0x352304ed),LL(0x83c10ff8,0xd05eedf0), + LL(0x702067ff,0xd0cd6dc3),LL(0xd3d111ac,0x3ee83612),LL(0x5ef57788,0xad67877e), LL(0xff6b4f08,0xda249b82),LL(0xd696f4f4,0x9dbbe132),LL(0x51804942,0xfe5ba023), + LL(0x060154d9,0xdc19d20b),LL(0x522b27ce,0x2c6233ef),LL(0x20fde2af,0x8b235bec), LL(0x3bb960c1,0x2adcfe01),LL(0x603b8fb9,0xc79aa84e),LL(0x6b460288,0xe204af13), + LL(0x21d24338,0xe9c83cec),LL(0x644ee8c2,0x768ea11b),LL(0x94fcc664,0x59088ada), LL(0x9374c03c,0x900c7bb8),LL(0x43cb2818,0xad48000f),LL(0x9145786e,0xa2041cca), + LL(0x02582993,0x1765e1a6),LL(0x34c86e0f,0xe74f0372),LL(0x2bfc967b,0x5ba6c193), LL(0x154fde15,0xa09688b9),LL(0xd02973ed,0xcc002cb5),LL(0x92f64238,0x01037f55), + LL(0x8597bf52,0xcef12f0f),LL(0x323d2edc,0xd1bbb357),LL(0x6cac9c11,0x06254d2f), LL(0xa913fbcd,0x13b6a932),LL(0xa97bee41,0x9865d3ba),LL(0x224479fb,0xab2a703b), + LL(0xbe515d1a,0xfd4472bf),LL(0x1dc983d4,0x7ca21984),LL(0x2a2db967,0x1f62c4c0), LL(0xcf71a671,0x4bcade52),LL(0xdfadf5eb,0x50fdda39),LL(0x650fac39,0xb020e598), + LL(0x6d401575,0x05292bde),LL(0x1448bd42,0x0c3c2b31),LL(0x526536c1,0xa76d46cd), LL(0x2a839d2c,0xaa0c74ff),LL(0x62f94ad3,0x7283bfb0),LL(0xe710c108,0x063159c2), + LL(0x11840343,0xbf96687c),LL(0xd26b7f84,0x36468056),LL(0x362582a6,0x6ab84c43), LL(0x7d43997a,0x3bb7a3cb),LL(0x19bc5d68,0xfafa8874),LL(0x042ff6c3,0x73dd38cb), + LL(0xe5d2eb17,0xab12eac0),LL(0x07bac547,0x4b8a41cb),LL(0xffa6df36,0xe9bfd303), LL(0x3c9a6423,0x6bb4517b),LL(0x9ca20f86,0xd393d1f0),LL(0x2231716f,0xb8e17b6c), + LL(0x35417747,0x4a3a2eeb),LL(0xc8c6b7c4,0x9b638e84),LL(0x16cbe067,0xc1215698), LL(0x322fa78f,0xfe96edae),LL(0x35c0584c,0x7b161bc3),LL(0xb32db702,0x86d59110), + LL(0xdc2fd5f6,0x232b8b24),LL(0x3c7926e0,0x082d2045),LL(0xb2c6285b,0xa73041dc), LL(0x8dcded40,0x60172712),LL(0x04a70ed1,0xc62c9174),LL(0x962a378d,0x6fb37121), + LL(0x823c3d77,0xb6f17b32),LL(0x9f7e5c97,0x5c45e3a8),LL(0xc3396a05,0x2daa3c77), LL(0xb063c7fa,0xbb2c63d7),LL(0x2ce90d3a,0x7a1c8227),LL(0xe4b3c32a,0x109b4b69), + LL(0x35f82f23,0xfdf6efba),LL(0x35381294,0x805d2980),LL(0x35aa14e0,0x894b62fa), LL(0x83d15a96,0x9b0d470a),LL(0x562cbafe,0x16a073f7),LL(0xdd734859,0x7851278e), + LL(0xd678f3a7,0xd0bf1f91),LL(0x5c227a14,0xe3d6d2e9),LL(0xf043aca3,0xd262c755), LL(0xee561894,0x60988c89),LL(0x73ca3bc8,0x64ec6b35),LL(0xc42baa7e,0x69a377b3), + LL(0xc96115ea,0x71695d26),LL(0x5b21f1d3,0x72271453),LL(0x39bafd21,0x8697c31b), LL(0x90197919,0xbd705026),LL(0x24ac9116,0x3bd494e4),LL(0xdfc15b14,0xc80bb868), + LL(0xf71afdd8,0x279ba623),LL(0x033c4ae8,0x9f980a73),LL(0x470c4517,0x21606d51), LL(0xe11ef4db,0x6d179aa7),LL(0xf1ca7162,0x869eac72),LL(0x86deb5b6,0xbc4a973d), + LL(0x200897e5,0x162b8299),LL(0xfccd9352,0xd6d516d0),LL(0xabe7feae,0x77eb73ea), LL(0xc3484609,0x8c10355c),LL(0x3426fefb,0xeea4f0b5),LL(0x1520bff2,0x140ba2d5), + LL(0xa781a4b6,0x8e02c736),LL(0xc1a1dc16,0x42c46ee6),LL(0x40321197,0xcae4633e), LL(0x98f07389,0xf04c64f2),LL(0x037c647a,0x6ee9ba3c),LL(0x48084ba5,0x4b003962), + LL(0xe74b1cd4,0x858e1b6d),LL(0x32cb7b0f,0x1d3abad5),LL(0xed92d1b4,0x5b519e77), LL(0xc30f4257,0x1c92c6d0),LL(0x4987bf78,0x5f383d3b),LL(0x4a7f80cc,0xd1c583d1), + LL(0xb56713fe,0x93af26d2),LL(0xa2ab05fd,0xc1226000),LL(0x7254b6e9,0x841945df), LL(0x5061c175,0xc5109d82),LL(0x00ff256d,0x62d1e3dd),LL(0xf0de138f,0x843b00ee), + LL(0xf374c5cf,0xf615bb55),LL(0x48c4c8a3,0xf0ad394d),LL(0x4d11c95a,0xdc7346c8), LL(0x4c5c8014,0x458a607e),LL(0xa5494d82,0xfe616aeb),LL(0xec4b9fb5,0xb0b346d1), + LL(0x06273f56,0x69c25150),LL(0x0c65034e,0x67589cbf),LL(0x93836375,0xd9a2c967), LL(0xa738e250,0x65e7cf03),LL(0xf4d22339,0x96e92577),LL(0x81400fed,0x4bfc9f81), + LL(0xbe5747bd,0x6e69c9c5),LL(0x2c6c18e6,0xe0472ac1),LL(0x083b884c,0xba3a6bdf), LL(0x52e63728,0x68985297),LL(0xeec09362,0x953f2dd9),LL(0xf975e840,0x3f3a2694), + LL(0x3edfaffd,0x77325f02),LL(0xff7d543b,0xc74420f8),LL(0xf9f15b53,0xb3944991), LL(0x0aac0254,0x86959454),LL(0x3b374e03,0x6f43d3e6),LL(0xb30e1624,0x844012c1), + LL(0x65028b0a,0xd064ea02),LL(0x3b4d2ee7,0x806c09ba),LL(0x7fe4f230,0x8a1f8901), LL(0xeda1696a,0xbd498bb0),LL(0x3bc968a5,0xe51465d8),LL(0x2bd1dae9,0xd28bdafe), + LL(0xf62ea381,0x65982b48),LL(0xcd73058f,0x4807eaa8),LL(0x240c2f9b,0x345875b6), LL(0x65a17c9e,0x778bc20a),LL(0x23054c23,0x6fe407b8),LL(0x75ba53f6,0xfae57b0f), + LL(0x78d45156,0x32fbbcb8),LL(0x71e3fd03,0xaefa78d7),LL(0x0f74090b,0xd7c46ea4), LL(0xcc57cee3,0x89b357ff),LL(0x5840243b,0x9e5cedb2),LL(0x0d0e8ac0,0x98a48d58), + LL(0x610ce375,0xcff03f53),LL(0xc9bfbd54,0x7b3c5728),LL(0xcd327836,0xeb868866), LL(0xae712c4e,0x79819aee),LL(0xd7f04c0b,0x0b11d0e4),LL(0xf8a5a59a,0x95bd124d), + LL(0xcfda2cc6,0x924e7e79),LL(0x212e1d27,0x3ec19199),LL(0xe70982f2,0x596b8e05), LL(0x08cd6128,0xd664a1a5),LL(0xa30c9229,0x374d9700),LL(0xdea4ef83,0x44226abe), + LL(0x49136355,0x9b6659c1),LL(0xc404424c,0x138972a0),LL(0x38bb5edb,0x75c55b59), LL(0x16af7574,0xcf1bc9c8),LL(0x3386b6af,0xaad6e8c6),LL(0x76fe803f,0x5d136ae2), + LL(0x9d03f245,0x3912bca6),LL(0xc3a1fb1b,0xe6ff0efa),LL(0xbb5db166,0x7876e5c1), LL(0xf0b460b5,0x23c904b1),LL(0xe69528b2,0xee8e2bf6),LL(0x5191c468,0x2e8d3640), + LL(0x06516227,0x980138d8),LL(0x861c3973,0x2b71e24d),LL(0x5ca35d8d,0x2580dd9c), LL(0x5c9c05ae,0xac4df0a9),LL(0x3c68c54a,0x63916a87),LL(0xf536c869,0x3a6ffdbe), +}, +/* digit=20 base_pwr=2^140 */ +{ + LL(0xe9cb9264,0x1012e415),LL(0x14ab08a4,0x4f91e85d),LL(0x35df1c1d,0x61431287), LL(0xe79281d7,0xbbd3824f),LL(0xaf54a4fc,0x99d4e30c),LL(0x642e1333,0xc4948701), + LL(0xbae8e3bd,0xe93eda3e),LL(0xf46b38aa,0x4ef30da4),LL(0x4151dbfa,0xd6cab5b2), LL(0xcf5c0161,0x04fd2b14),LL(0x80166092,0x7c8a0389),LL(0xd94e32be,0x47096659), + LL(0x6156b873,0xf7feeab3),LL(0x5be66206,0x4a2f2b83),LL(0xdcfc9038,0xdf3277f1), LL(0xf1d66fb4,0x9b170776),LL(0x076dcabf,0x25ebdd78),LL(0x38b46ab5,0xa7c6ee6f), + LL(0x79f1a500,0x4cfc4785),LL(0xaf098654,0x3ba69756),LL(0xc21ecc8e,0x41491597), LL(0x0c8f0d93,0x4982c841),LL(0x2b324495,0x03c63423),LL(0x697188c1,0x7c3952ab), + LL(0x56b9ce4d,0xe770f45f),LL(0xa9a47842,0x07148130),LL(0xced2b9b0,0xbc38458c), LL(0x047d7534,0xbe545be0),LL(0x1c6ff074,0x6768b949),LL(0xde3dbd8d,0x1dca8c16), + LL(0xcc3bcbc4,0x0636cefc),LL(0x5159e643,0xc92b9ff8),LL(0x91bb0476,0x00a152ac), LL(0x42dea60d,0x3fc87a4d),LL(0x64d6fc10,0x6803f0e3),LL(0xf9f370c8,0x99409032), + LL(0x5826fd73,0xc6616960),LL(0x5517ee73,0xf1955831),LL(0x51c70ff4,0x88b7cec6), LL(0x366d0443,0xb0888a9e),LL(0x3af869e2,0xa9181fd0),LL(0x0a248328,0x26076aef), + LL(0xbaed8f78,0xad53d93a),LL(0xd71de257,0xa0b9be84),LL(0x603a33a2,0x4630f086), LL(0xb911d04a,0x5b44638b),LL(0x6e3fa849,0x02150fde),LL(0x4184d866,0x8421d2e5), + LL(0xe5897526,0x52557cb2),LL(0x502c34ec,0xdfe0933e),LL(0x72eb3dba,0x4c1d921f), LL(0xc524a1ed,0x1989729a),LL(0x18b3826f,0xc702ac61),LL(0x0d5cd8f7,0xaa34f109), + LL(0xfa609590,0xe4ef5cf9),LL(0x6f3d8102,0x215b5177),LL(0xccb2d3ca,0xb1886914), LL(0x65884534,0xcda19104),LL(0x870769b4,0x2cf8baf3),LL(0x7339dc8e,0x22f2d15b), + LL(0x21a810cf,0x35c9c17a),LL(0xfb6bdd26,0x24cd74b4),LL(0x1a7c7f5a,0x6786a13c), LL(0x817609c4,0xec7e4bb7),LL(0x256f4592,0x6de1e630),LL(0x8326a507,0x923f4ca6), + LL(0xb5bfac37,0xbe78c4a0),LL(0x197cb928,0xedbb3fc8),LL(0x8b563167,0x477ac821), LL(0xd224f360,0x70cb3ee4),LL(0x53d0e1fe,0xe1b338d6),LL(0xf10e26d1,0x7a5c3f25), + LL(0x745f0869,0xb0c7846e),LL(0xc667523a,0x50becb24),LL(0x14521b55,0xc6acff6b), LL(0x0c4a3c6a,0x70ed855c),LL(0x8e159fe3,0x1ec2b9d5),LL(0x74b5c29a,0x06249cb5), + LL(0x2dd180d8,0x0f3b2f65),LL(0x7b859a81,0x56200850),LL(0x4b18d95c,0x9d0f51df), LL(0x6f0b29af,0xe82ce6d3),LL(0x2a4310d4,0x75a0fcf0),LL(0xc7bed80c,0xdeebf877), + LL(0x64d180d0,0xcf0d6afa),LL(0xa6434a9a,0xb8f7c1c9),LL(0x8cfb2948,0x6cdb576a), LL(0x863bb933,0xed57f57a),LL(0x4df11d72,0xc7f06882),LL(0x4c2b933c,0xe29a2fa1), + LL(0xa17d0463,0xbba79104),LL(0x5a81b9f9,0xd7cbed07),LL(0x4e242aa9,0x20e07b74), LL(0xbb9e790d,0xb9d12856),LL(0x47c00f37,0x45bdbce1),LL(0x898b8efb,0xa0ed2b72), + LL(0xb466dfb9,0xe8318ed6),LL(0x94a4baab,0x9faa662b),LL(0x051206c6,0x01503060), LL(0x3c19ae55,0xa2ebeefc),LL(0x84d2a9c1,0x210ae455),LL(0x82e43956,0x562df0b5), + LL(0x17080cf3,0x89be703d),LL(0xf1ca3642,0xe83c11cb),LL(0x13271110,0xe61d20e1), LL(0xd21d05b8,0xd631b1d8),LL(0x6452ed8c,0x620fc76f),LL(0xe58a415b,0xcc6794e6), + LL(0x15a94078,0x0a5c8a7e),LL(0x86688f1d,0xd4226082),LL(0xa85bc83e,0x8ede9371), LL(0x0df393c7,0xecd1f5e2),LL(0xd2fc7359,0xc32847c6),LL(0x08190efe,0x1e9fd4bc), + LL(0xeea5827a,0x83dd7278),LL(0xcbc88ba5,0x1ddaadd7),LL(0x218e4199,0x588e4903), LL(0xc8310baf,0xb685d516),LL(0x74bb3deb,0xc9aa64ca),LL(0x931bdaa3,0x0cb7a0ea), + LL(0xcdf5ecc3,0xc1ecf641),LL(0xf8c7946c,0xdeac2eff),LL(0x02ca92e6,0x73c8e009), LL(0x7361770a,0x19bc9700),LL(0xacc0e88b,0x455770d3),LL(0x7ddafde7,0xf7cd145c), + LL(0x3d17e97a,0xa33b896c),LL(0x30a84be8,0x238a70a9),LL(0x044f68ec,0xb629bdd9), LL(0x5614b150,0x6d180693),LL(0x7fde6cd3,0x54ba0757),LL(0x4980c20b,0x19edd13b), + LL(0x1073d079,0x4b1584e9),LL(0xa794787f,0x6e60302e),LL(0x8088839b,0xfeb8358c), LL(0x1a701ad3,0x86f51cbf),LL(0xd07f6815,0x61b9c974),LL(0x653f1425,0x00a0d546), + LL(0x11894381,0xf75ced35),LL(0x319c7001,0x49e325d8),LL(0xa67066ad,0xd20b2435), LL(0x4c608028,0xdd23ebc4),LL(0xba2205ea,0x51d78928),LL(0xfb1fb5cc,0x737b9cb1), + LL(0xc03586f9,0xbbb8ad72),LL(0xd27fea7c,0x402a9fff),LL(0x5dda8a10,0x831e331a), LL(0x1eb0456e,0x6d5a2c5e),LL(0x9f7b81ed,0x65290756),LL(0xbec1e59d,0x976b7327), + LL(0x419baf59,0xea1a80a5),LL(0x57278748,0xbc517958),LL(0x32e85407,0x29245035), LL(0xc0d421ac,0x812b0397),LL(0xd7a01665,0xa9f235bf),LL(0x24652cd8,0x9d164236), + LL(0x7f2c6c70,0xbf6ae2aa),LL(0xee9e0e91,0xa021d9a9),LL(0xf1766121,0x409464f1), LL(0x4a73446a,0xe180eb42),LL(0xc5f86d28,0xe7e1ed8b),LL(0x903583e2,0x2e4a2f9a), + LL(0xc5e91397,0xba644637),LL(0xd74dad5e,0xfc63ab71),LL(0x824f5cb0,0x1baa70ad), LL(0x72783f79,0x5f89e95b),LL(0x3813fcb5,0x45bb2a10),LL(0xf3165835,0xab43fa7f), + LL(0x14c22638,0xb7c86dac),LL(0xdae71747,0x3656ca1f),LL(0xc534e20e,0x85da5ae4), LL(0x49153a00,0x3aa49d12),LL(0xbd68b553,0x34857651),LL(0x47329cb6,0xe4fb4c67), + LL(0xd2659f96,0xf91390b8),LL(0xae3ada10,0x507dcc75),LL(0xea42c05c,0xec3156e1), LL(0x28627de0,0xa851f6db),LL(0x3f5bd276,0x10f1771e),LL(0x29bb086a,0xda6fb38d), + LL(0x72b97a47,0x9bdec367),LL(0x657aba3c,0x033db4d1),LL(0x0a26ba3d,0x6d7dcdad), LL(0xb13b21c6,0x93253eae),LL(0xf3e1e435,0xf49e4546),LL(0xfc1d9651,0xda2f3b67), + LL(0x98a48009,0xf35a51b4),LL(0x74249dd0,0x6d03d805),LL(0xcb813640,0x3a2ea471), LL(0x8fb0ba2e,0xf40ccd7e),LL(0x967a4bda,0xe1511909),LL(0x9c401b43,0x92f26a91), + LL(0x9b338eaa,0xc7019ac8),LL(0x1ff7bf17,0x9d084573),LL(0x565ad4f0,0x64807759), LL(0x0a7bdf41,0x1c42c251),LL(0x9e01efd3,0x63caad5e),LL(0xc624e5ba,0x55785f80), + LL(0xee0bde78,0x7db8ae10),LL(0xb62c8387,0x0e6313ac),LL(0xcd166c86,0xd4ec5c51), LL(0x39448747,0x1a9c939d),LL(0x731d066a,0x3a75230d),LL(0x73962926,0x91bf93ae), + LL(0x61e7a7be,0x1485af16),LL(0x71c2640c,0x112d3d53),LL(0xcbbb3b9b,0x277a24c5), LL(0xfa95ddae,0xa17a1980),LL(0x7a40ef8e,0x4ae12d96),LL(0xfb1c3fd7,0x339601a8), + LL(0x74e8c96d,0x05fc1df3),LL(0x8ad8de59,0x004fd161),LL(0x747f9809,0x0ab94cbb), LL(0x341b687f,0xc689e96d),LL(0x03d6ec78,0xc3ed2540),LL(0xc677b947,0x58414ee5), + LL(0x79d557f9,0xd4b38421),LL(0xb80fd2ca,0xe5f1e680),LL(0x5b2a650d,0x403029fa), LL(0x6ea522b1,0xbc0c8825),LL(0xa186a767,0xcaa2d945),LL(0x254875d3,0xb85ecf45), + LL(0xf6031493,0x098fe2ee),LL(0x95f3b2dd,0xd8a4c0c1),LL(0xf565fbfa,0x84d7151f), LL(0x0d46e2ab,0xab92d636),LL(0x7fcbe589,0x822ee95c),LL(0xd061506c,0x855320c5), + LL(0xd8c4c89b,0x82458f67),LL(0x4a55190e,0xb7f499f0),LL(0x2be3b154,0x8f90b016), LL(0x13d9c5d2,0xf943056e),LL(0xdf50c757,0x7de98cd6),LL(0xc1785279,0x97d69ee8), + LL(0x3fe0c0ab,0x140bc9a7),LL(0x0452da51,0xbf26b0db),LL(0xdad75d1d,0x31658423), LL(0xeb0c6035,0x0f75fa69),LL(0xe800bb3f,0x4cbb16f7),LL(0x66429e7b,0x4892f0a7), + LL(0x4c6c9c18,0x218c66a2),LL(0x08cad414,0x97355790),LL(0xb15e573a,0x3b5b1298), LL(0x0e6834ba,0x7aca61bf),LL(0x3f5ac90a,0x025883d3),LL(0x9dff4949,0x6462025c), + LL(0x701e063f,0x6370b52c),LL(0xfcbed6d5,0x575b74fa),LL(0x54464ddc,0x87196ca2), LL(0x6aded252,0xabf56ac6),LL(0xe859df43,0x195e68db),LL(0xd3b0c609,0xd7d0b724), + LL(0xc7d916d9,0x68fee7bc),LL(0xd2261a1d,0x7c342ab5),LL(0x2d528b45,0x6dc620c3), LL(0x0ae80fdf,0x74e628a7),LL(0xc87865c1,0xb6024eaa),LL(0xb87c19a5,0xcfbcc11e), + LL(0x7fc82526,0x16e10271),LL(0x4e53a7eb,0x1894ff31),LL(0xd6fd2213,0x483dd45d), LL(0xe86573ca,0xf832f47b),LL(0x93e56334,0x3fba3845),LL(0xedd7db47,0x88af40db), + LL(0x48c963ee,0x478c4ff6),LL(0x41711eb6,0xe3c63604),LL(0x40ebd5fb,0xdc23721b), LL(0x38c5e8a3,0x73b730cb),LL(0xa14de57f,0x379e6a4b),LL(0xc789f412,0xed816ee8), + LL(0x0ce5eda0,0x22553add),LL(0xae4119b5,0x2cced448),LL(0xaa185ab7,0x2a352ea6), LL(0x29a2bdee,0x01bd04b4),LL(0xe26e2a0c,0xf76ade92),LL(0xd94aaa8d,0xda8577d6), + LL(0x07d56f07,0xc7f17e2f),LL(0x7d87d713,0xc5e3f9d2),LL(0x20f51bc9,0x1497d098), LL(0xed2a6960,0xf4d19f47),LL(0xc38a9534,0x1c57c5ec),LL(0x18c80df7,0xdbffd9a1), + LL(0x5f168647,0xf0cc9844),LL(0x1593d662,0x2e63ed9f),LL(0x0ac8146a,0xf5fa425d), LL(0xce76be64,0x67f11299),LL(0xf7727692,0xd42902cf),LL(0xf1f0d4a5,0x06ce330a), + LL(0x799a13c8,0xfd425657),LL(0xcf29d9a8,0x2c8a973c),LL(0x1e78973e,0x40ec7ae0), LL(0x78699406,0x4d9856a5),LL(0x08dfdad4,0x7247ba62),LL(0xa468c80b,0xc9427c34), + LL(0x3aeaaf13,0xe79cd000),LL(0x9ec3462c,0x6018f62b),LL(0x2ace3a5a,0x1192c3d9), LL(0x64a64ae3,0x715b684d),LL(0x34bf6e70,0x9d318356),LL(0xfdc656ed,0xa23a9958), + LL(0x77357c1f,0xe6acb14b),LL(0xe9438466,0x554e9c51),LL(0x8ba9a286,0x97a5abd9), LL(0xd3eed3bb,0xfc1cd0de),LL(0x700f6eee,0xf311fa4a),LL(0x8a99cd1d,0x4dd6d73d), + LL(0x6b41a2bb,0x43f68039),LL(0x083ab1a3,0xba3ca572),LL(0x1b173556,0xea841d92), LL(0x928c1fd4,0xb23978ab),LL(0xb985008a,0xd6d7c468),LL(0x2248ceb2,0xa6d40f4e), + LL(0xb9ad7efa,0xc9627a3a),LL(0x6759753d,0xbebc0a32),LL(0x7cf0a0fb,0xa3bacd1a), LL(0xdb7cc4c0,0x4ac922fd),LL(0xd7afe1c2,0xfc69f5fa),LL(0x7afcfb11,0x6dde5c15), + LL(0xbbd42505,0x9df0ef70),LL(0x464d44cf,0xa4274df4),LL(0x57e809eb,0x8113b3de), LL(0xc10dcf7e,0xaeab98c6),LL(0x1e6f2975,0x58a34894),LL(0x8f9ccf40,0x9cb5ea9d), + LL(0xb579d154,0x1c4eac89),LL(0x4b706046,0xafbc0bf0),LL(0x7f6fc44a,0x5ecdfe60), LL(0x0030d612,0x3d9c58e8),LL(0x7811ca4f,0x3d9b1e58),LL(0x78e80d2a,0xd3ace80a), + LL(0x48e70c10,0x5a2c98a4),LL(0x1f1028cf,0xa72ad42e),LL(0x2fe8c440,0x30739ff7), LL(0x5fe64d92,0xe83f9edf),LL(0x2fd3764b,0x7cb62281),LL(0x51ab555f,0x9f114c85), + LL(0xba081442,0x3a838e28),LL(0x27db39bd,0x71ea2048),LL(0xaf2896ba,0x3cdb99dc), LL(0x962c484b,0x00d6fcb4),LL(0xcd7377d4,0xe72a7bcf),LL(0x5164a634,0x3b6505a3), + LL(0x8bddb5d0,0xaec6f498),LL(0x7f02675d,0x92b09fb7),LL(0xa83cefd0,0x79345be5), LL(0x1f828e29,0xea0f3427),LL(0x7cadddfa,0x1ea0786e),LL(0xd159e1b8,0x75ca82d5), + LL(0x62c0533a,0xaaaf5a5c),LL(0xe510bc9f,0xa96e494b),LL(0xf2debee9,0x46b1aedc), LL(0xf98911db,0xedd51f34),LL(0xf9056ce1,0x83a0eab8),LL(0x7eae269d,0xa541abff), + LL(0xd5d26026,0xb68b8dce),LL(0x28bf2023,0x6ceb559f),LL(0x74bc843f,0x7dd76130), LL(0x35f97a24,0x79c99ea9),LL(0x7b478eaf,0xcc786699),LL(0xc10dc8c8,0x7788ee3c), + LL(0xbcba6716,0x88ad66c4),LL(0x95300687,0x2bdf72c8),LL(0xb8fa1b0f,0xdd8629e6), LL(0xe183a10a,0x93d5a8e4),LL(0xae5d5956,0xe3e2d85f),LL(0xddd1b643,0x8b623a95), + LL(0x8cc90e24,0xfaf59c8f),LL(0x7f1c7245,0xb7173e32),LL(0x9baad443,0x568e30bf), LL(0x718cbe51,0x7eb7c7cb),LL(0xc1f0f949,0x2a3a214d),LL(0x96a84ad4,0x21a777be), + LL(0xb2081c31,0xcdb78081),LL(0x7a9d57b5,0x2bfa8d65),LL(0xb750969c,0x9db52d99), LL(0x645d4012,0x6ebcd855),LL(0x86245e59,0xbcd2fcd1),LL(0x812b3b4b,0x8fff22a6), + LL(0x6ffb620b,0x1130ffec),LL(0x22eb38ff,0x279544f9),LL(0x940699a7,0xaeb474fd), LL(0x4c85071c,0x33329bf0),LL(0xaf3d6bd2,0x56b019ec),LL(0x8b3cf686,0xc4aaaf7c), +}, +/* digit=21 base_pwr=2^147 */ +{ + LL(0xac2ec7bf,0x8824e17f),LL(0x9bc85814,0x131057c0),LL(0xdbe08716,0x7e43698b), LL(0xab93ba96,0x42ad5ab0),LL(0x7c518be6,0x1ecf5fda),LL(0x673d6c18,0x1a02e6f8), + LL(0xb3503cee,0xbf0f89da),LL(0x331d9e6b,0x9169467b),LL(0x3b1900fc,0xe3aa5241), LL(0x3f13a573,0xae45a71e),LL(0x1940c9af,0xec133c7c),LL(0x55c2087c,0x0409942c), + LL(0x24e5717c,0xbac3bea8),LL(0x9b83ae02,0xebbc708e),LL(0x7e9ea1f2,0xfa57a0ad), LL(0x704d566a,0x107a38cd),LL(0x85e59024,0x18e24faf),LL(0x0f84a27a,0xec3157c2), + LL(0x58b3bb0c,0x17889e93),LL(0xb4031a98,0xbaa2495a),LL(0xb10778db,0x5d3a3a63), LL(0x8f7c139d,0x2fd443d8),LL(0x5ea5ad03,0x83c71634),LL(0xce562cfd,0xaba81b6a), + LL(0xd98102aa,0x73e43632),LL(0xc1c41614,0x86932d35),LL(0xeec41de3,0x1c66a427), LL(0x72427be4,0xef9616dc),LL(0xd48ea6d2,0x206de291),LL(0x8160c0e5,0x755f3ab3), + LL(0x376fc02d,0x23668837),LL(0xde1f643f,0xc4608c43),LL(0x05775439,0x6f04d8d7), LL(0x0f5452a2,0xb32fa6bc),LL(0x3b09e219,0x6a200395),LL(0xfb0a3adb,0xf58e4d28), + LL(0x5f9f2818,0x56285629),LL(0x594adc3c,0x19ba097b),LL(0x0d5212fe,0x6a73f84f), LL(0xb0680c11,0x5106510c),LL(0x13904ea1,0x4d287906),LL(0x8ed4bb25,0x9e4b6db5), + LL(0x3efd07b3,0x5c58a701),LL(0x8a62c9c4,0x5569ea8b),LL(0xe3eb4a21,0xbabcab23), LL(0x2ed936e5,0x9f05b68c),LL(0x25d25b7a,0x5b8fcbe4),LL(0x40745f94,0x5104d275), + LL(0xe96ebb1c,0xbf9a348a),LL(0xadcee8f6,0xde39269a),LL(0x1891395c,0x92012c94), LL(0x6584db0f,0x3b71f247),LL(0x8f7e3a23,0x9fc90016),LL(0xbe7d1077,0xb5f10362), + LL(0x137efed8,0xf06fe20d),LL(0x096f2e2c,0xf037f990),LL(0x416e7f9e,0x7e828e25), LL(0xd17229cc,0xb9066cdf),LL(0x74e2f3cf,0xe1b5d7b4),LL(0xcbc63300,0xa21dc884), + LL(0x73213695,0x09291e46),LL(0x7d591bb2,0x599398e7),LL(0x8693f17f,0xbc316181), LL(0x323b2584,0x29e970f3),LL(0x8253ea0d,0x07db9ebe),LL(0xaf8d9499,0x62d8e321), + LL(0xce2b6bb7,0x468f741b),LL(0x423f1cec,0xb8703663),LL(0xa1385cee,0x045ddc8d), LL(0x9b1abc32,0xfb61bc91),LL(0x8b0a1f38,0xdc221abc),LL(0x5f8c7e7c,0x174b6f77), + LL(0x8aedb4c2,0xf975efc4),LL(0x150dc348,0xb7126f5b),LL(0x8f316668,0x1826a434), LL(0x47b0020f,0x89a0a561),LL(0xddf906f1,0x7c814d16),LL(0x5cbe397c,0xae729976), + LL(0xac73b7b2,0x73507bd6),LL(0xd77d1311,0xdc109e64),LL(0xd07e0b84,0x40745a92), LL(0xeae6ea71,0x80a25d92),LL(0xdba1caf3,0x7d16cdaf),LL(0x178d162b,0x532678a1), + LL(0x89ce3929,0xf04f0f69),LL(0xfccffe8c,0x623a881a),LL(0xc3cc5b57,0xe35d518d), LL(0xd7cbfd70,0xcddb9b25),LL(0x517679db,0xcec3736a),LL(0x3964a183,0xff07c63c), + LL(0x1ee7af47,0xb6f1e8e5),LL(0x774114f6,0xdae8bedd),LL(0xe9b23727,0x7e40fd87), LL(0x4e0b09b4,0x677a0144),LL(0xecabbeea,0x37b376fb),LL(0x05a3a145,0x3d536296), + LL(0xf07be04d,0x0b60e86c),LL(0xb0f7efb6,0x72210de8),LL(0x44de2248,0xe661f7e3), LL(0x5e1a2e6a,0xa50972cd),LL(0xf3c16459,0x8ea7ea6c),LL(0x3d5cc6fa,0xce1eac26), + LL(0x3fb24e2e,0x12057921),LL(0xe703d891,0x2c6418a6),LL(0x85a84ce2,0xba1fdc36), LL(0xd7969f76,0x15c19ded),LL(0xce8a554f,0x0ef1f54f),LL(0x9dae18ed,0x45215796), + LL(0xea05050a,0xe4fb6484),LL(0x249b636e,0xf0ac280e),LL(0xa3b0a746,0x622dc53a), LL(0xc2c4b6e2,0xcbd0132e),LL(0x608cf966,0x71f38ed9),LL(0x47ac6ed1,0x733cdc1c), + LL(0xedbd5f2c,0xeec38461),LL(0xb053878a,0x02367abe),LL(0x366f0019,0xbc7279d2), LL(0x3917f0f2,0x383b04a6),LL(0xd170c6d6,0x7a5ac16b),LL(0x6e32c8f9,0x4f3c4a0e), + LL(0x0bd61a8f,0xcc2c1858),LL(0x34f527e4,0x87c8a389),LL(0xf23dc622,0x618a666d), LL(0x364108ca,0x40fecc5b),LL(0x98a0bf79,0x29742c4f),LL(0x272071ba,0x37d45180), + LL(0x685f2d3f,0x1625e4f4),LL(0x14c1f55c,0x3470dfe8),LL(0x44d91a5a,0x969f3ad2), LL(0x9f30454d,0x6a5be95e),LL(0x7281af65,0xed104a4e),LL(0x36d5ad8c,0xb23076ad), + LL(0x5eb808b3,0x4ed6c763),LL(0x60e8d7fb,0x70f86e24),LL(0xde84f30f,0x2b18c950), LL(0xfaf0ac4d,0x435aaafe),LL(0x3276078f,0x6f3e4e4e),LL(0xb8977a67,0xf3b9b7dc), + LL(0x3bcf4e15,0x28ef1bcf),LL(0x358303c9,0xbe939b53),LL(0x21a319d2,0x204114a7), LL(0xaa81d7a8,0x259ed8fa),LL(0x18fe7097,0x7d9a642b),LL(0x184765b8,0x9acf2e2a), + LL(0x9149e0ef,0x77900481),LL(0x8dfdc1e8,0x0ae5deb5),LL(0xd6f33c8e,0x23b0cfeb), LL(0xa26da632,0x9a6ca40b),LL(0xc537ce62,0x34b9c619),LL(0x5a4ec3f7,0xd37f4428), + LL(0xcbf87088,0x16d03a12),LL(0xb1c521c9,0x872be585),LL(0x1e8e4fc6,0xff44095d), LL(0x5c32815d,0xa7e6bc74),LL(0x8d3db724,0xdf3b021b),LL(0x101b1403,0x6b363726), + LL(0xbe2d31d8,0x4cceb610),LL(0xa171cad9,0x4b4a33ca),LL(0x37cd3a7d,0x8e335bfb), LL(0x5185da89,0xa4922968),LL(0x5914cb63,0x45f929dd),LL(0xa3aa3f6a,0x040366eb), + LL(0x2d373ab6,0x2ae211b1),LL(0x671cfd45,0x81bd0544),LL(0xcb962cdb,0x0c2e8457), LL(0x64ce8ebd,0x58fa7e29),LL(0xcdb6f3cd,0xfdc40b43),LL(0x1c69bac1,0x17d10e47), + LL(0x86421e7c,0x292c5ae4),LL(0x6758a6b1,0x32584cff),LL(0xaf7a9c3f,0x0288b16a), LL(0xeba67e24,0x03aadb8c),LL(0xc87df2d4,0x0f3e777b),LL(0xbb91d9ea,0x6ba2d690), + LL(0x404ff38f,0x4a5352c0),LL(0x5340d952,0x0f04982f),LL(0x2798c5c2,0xcfa86bde), LL(0x94dd1186,0x1ab8b19e),LL(0xccfd8af2,0x83ce68ee),LL(0x06cb2c1b,0xb6f99034), + LL(0x6ecd5c6a,0xadfb667e),LL(0x59a0fb16,0xb5401239),LL(0x5b9e22cb,0xe1100936), LL(0x21d0430d,0x34d54f0a),LL(0xa6197440,0xcb34b278),LL(0xc927d3c9,0x1c07cf85), + LL(0x31e24e54,0xa386ba5c),LL(0xa48e552b,0xdfa72d1c),LL(0x075794d0,0xcb7594cc), LL(0x0b3dc6ce,0xa52aceb3),LL(0xc6d190de,0x16c80954),LL(0x203a1303,0x7cd54e57), + LL(0xd5313dd9,0x72983edf),LL(0x4bf35d2e,0x7557de74),LL(0xfde38dd0,0x29719af0), LL(0x6838b644,0xe3ce6ea4),LL(0x39486a01,0x70976ef8),LL(0xb7d8d84d,0x7b16d6b6), + LL(0xc80b2253,0x44cffea0),LL(0x53e978f5,0x39b12203),LL(0x76e654ca,0x6efe5c6c), LL(0xf5ecd362,0x9ce55175),LL(0x32904094,0x945bc283),LL(0x419b4c47,0x16be694e), + LL(0xb25ff2d8,0xc6d695b8),LL(0xfbc1c346,0x95848769),LL(0xf78df5b6,0x4cd68253), LL(0x07a395a6,0x366208a9),LL(0xb300e26e,0x6a100464),LL(0x2c4c9774,0xcd75f9ef), + LL(0x58587dee,0xa6dde508),LL(0xaba27af9,0x1fb5756e),LL(0x2435fdfc,0x886588cb), LL(0xafa3a40b,0x8836939e),LL(0x23550a04,0x8e4ea6e4),LL(0x13129070,0x1f60a305), + LL(0xafd87664,0xcd87217f),LL(0x62eaab37,0x33999750),LL(0x63e77715,0xc5c71386), LL(0xadc2dc58,0x8f7ec765),LL(0x06ec10e5,0x0166d81b),LL(0x4bab2eec,0xd978b136), + LL(0xabc9d990,0x518d8792),LL(0x848bc38a,0xb5e9214e),LL(0x890c38ca,0xbc62bb10), LL(0xa5d74a39,0x24395eb5),LL(0xe81ca0ef,0xbaacb032),LL(0xf968482f,0xaa7d10d1), + LL(0x3c8d1134,0x55fb3866),LL(0xc866fb41,0x2f0c11d9),LL(0x60d9da04,0x470f0d0c), LL(0x30199fda,0x2ce76abb),LL(0xf1754859,0x68239b6e),LL(0x36c8db28,0xabcbfa61), + LL(0x15fd8cdd,0x59bc69c7),LL(0x7dc71686,0x8c35acbe),LL(0xdf56f4b5,0xa864fdf4), LL(0x73cb6096,0x7b019a3f),LL(0x6d0212a9,0x9bec6ec0),LL(0xd403dbf3,0x96f43d54), + LL(0x25f69dd1,0x1f8ef8de),LL(0xd4c811f4,0x01ea5842),LL(0x7bd1206b,0x6b00713a), LL(0xc77c3c64,0xcc267e59),LL(0xe68a4f20,0x788a8c0d),LL(0xf4b3c37a,0x968e777b), + LL(0xf39053e8,0xef230e41),LL(0x7839732e,0x3acdd9f9),LL(0x815c2a4c,0xa80f263e), LL(0x544f6fe5,0x20c61e68),LL(0x2c146750,0xd0a8228e),LL(0x4770e4ae,0x30857c49), + LL(0x42a4aa18,0xcba4107a),LL(0x68f36209,0xe72e3f7e),LL(0xf0a19740,0x42a02b75), LL(0x9946daf5,0xd4783068),LL(0x862f2de7,0xc01f64b0),LL(0x6209f44c,0xf00cfcca), + LL(0x7beb13fe,0x69d1c1f7),LL(0xfa01681f,0xf547c381),LL(0xfe808e67,0xe7fbdc0a), LL(0xc9b56b2e,0xa0fe9ead),LL(0xb2682ce9,0x1c53a580),LL(0x556a1034,0xe6cae9a2), + LL(0x7ff5d034,0xf4497140),LL(0xd0b40f9d,0x95b5f6f9),LL(0xc68600e2,0xec27b942), LL(0xdbb02501,0xd8f6e734),LL(0xf3ced49b,0x1e62a674),LL(0xd9620b28,0xd64cb872), + LL(0x418878cc,0x4506163a),LL(0xa5575e5a,0x96d1754d),LL(0x9a25f013,0xbf853bbe), LL(0x03c3aa89,0xfd8c5194),LL(0x14a549d4,0x0eb1954d),LL(0x0dbe140e,0xa88b972e), + LL(0x476facb7,0x5b45ac78),LL(0xcb7dbe77,0x8dc145b4),LL(0x4e47ee7a,0x0dd76bfc), LL(0xc1569361,0x06f554cf),LL(0xf665649a,0xbd841afa),LL(0x6e9773f4,0xe27421d7), + LL(0xe76c5baf,0x65ee7fbc),LL(0xb8dfe92d,0x6ddd2b14),LL(0xda22cc76,0xb9f4b2b4), LL(0xd9c02353,0x36ffd8da),LL(0xb62c010e,0xc23f7f57),LL(0x3308d355,0x00c51af6), + LL(0xa8fb84f5,0x7cdc4353),LL(0xbd3b9efa,0x431a25d9),LL(0xe921fd8b,0xe357451e), LL(0xa7d0d22c,0x3607231e),LL(0x7ebf0d0b,0xd8d0370f),LL(0xc5ac6f7c,0xfdbb3c4f), + LL(0xc826f1d9,0xfaa73e4f),LL(0x3e954cb4,0x95f6b20c),LL(0xc5935901,0x56f618ef), LL(0xc1141c9f,0x3a55c846),LL(0x27edf041,0xbc5bd1dc),LL(0x0e373045,0x51933533), + LL(0xb5f4dca2,0xacf42b35),LL(0x7eac22dd,0x0eedba21),LL(0x75502f43,0x2945fad0), LL(0x04c50653,0x94995ef4),LL(0x373f4e93,0x7992d051),LL(0x1b1c94b7,0x8a7c3436), + LL(0xaa607973,0xe636537b),LL(0x4e2f86bb,0x1c845ea2),LL(0x81f6999a,0x99f38921), LL(0xfed9173e,0xc1716d20),LL(0x1e801b36,0x792b9ffc),LL(0xca8f7a6b,0x06765f7d), + LL(0x79b19761,0xc6771baa),LL(0x29433d11,0x80d67617),LL(0x6b423d37,0x196fe0e0), LL(0x47bec8f6,0xe752e3bd),LL(0x52fbbe1c,0xd63ec3fc),LL(0x2ebe6309,0x30d727b9), + LL(0x1d17b14e,0xd9f486d8),LL(0x6761b05a,0x47c47d53),LL(0x7041158f,0xdf1f5e86), LL(0xac78e6bd,0x626756b3),LL(0xd777224d,0x01aedca6),LL(0x4a443a1f,0x025d3c43), + LL(0x5634214b,0xa12d740e),LL(0x375af247,0x4bc99161),LL(0xbe3e2882,0x346bf9f0), LL(0x4211297b,0xdad14a72),LL(0x1c532542,0x6554266b),LL(0x15d18e75,0x030daf54), + LL(0x51583335,0x7cdc99eb),LL(0x4e821ee0,0xd2239bce),LL(0xb41ded13,0x8974b1a0), LL(0xfe676f40,0x17dcd329),LL(0x9d22a9f9,0xc3253117),LL(0x36c57e47,0xdd5a6256), + LL(0xeb7827f5,0x04fcaeb7),LL(0x97baafab,0xcbba55a8),LL(0xd29a034b,0xccd2a2c8), LL(0x34045d21,0x37a19e21),LL(0x20ebeb66,0x1319ad06),LL(0xaa2041fe,0xfed9eef7), + LL(0x5ef2c6ce,0xa3fa82ba),LL(0x60524b3f,0x764801ce),LL(0x714ec445,0xdcc5c27d), LL(0x885e5fc2,0x5cdbaa30),LL(0xc779e89b,0x0aa6c9a8),LL(0xb797f8a8,0x9db3b836), + LL(0xa3ddb5c8,0x8c8b5a06),LL(0xc17aa963,0x1904c79d),LL(0x4a40b438,0xd6e2cd45), LL(0xa689e7d5,0x90b1ed27),LL(0x3f834964,0x350a4374),LL(0x1d9e5301,0x4c0cbe62), + LL(0x193559c9,0x9959ff0e),LL(0x3a77311c,0x0a6908c4),LL(0x714d000c,0x93d61072), LL(0xe471b9f7,0xc054c8c1),LL(0xfb602066,0x78534fd5),LL(0x614fcf16,0x9a5f7b8b), + LL(0xc459f1a8,0xd1d42f2a),LL(0xb574b235,0x9403a4ae),LL(0x42ef8a7f,0x1335a414), LL(0x6a4e1b79,0x4eb9a067),LL(0xd7a319db,0x90dd6eca),LL(0x8cfa5579,0xd54bf9e1), + LL(0x72331044,0x063b4a7e),LL(0xc4e13d1e,0xb82357d4),LL(0x38e9b37d,0xfb4981b7), LL(0xee950c17,0x0c64d898),LL(0xa553cc9d,0x16ac1d7c),LL(0x6e7d9643,0x27624002), + LL(0x62dc7931,0x70e5badb),LL(0x3d4149b7,0x92048bb3),LL(0x626d709c,0xa45d15d5), LL(0xe83bc3f4,0xc1e9c751),LL(0x07a26fe9,0x35bb7bd8),LL(0xb8fee30d,0x2713c9e1), + LL(0xc4895195,0xb26a41dd),LL(0xbec62d17,0x3695b237),LL(0x5bd95196,0x272d55e9), LL(0x89b5e05f,0xcb659d58),LL(0xa5687e17,0xcba46e22),LL(0x623cf306,0x2ece876a), +}, +/* digit=22 base_pwr=2^154 */ +{ + LL(0xce363c03,0xd16b25a3),LL(0x69b561cd,0xe21621f4),LL(0xabf845bf,0x03a8e393), LL(0x45c545c4,0xf68a5989),LL(0x492c1276,0x0d669f1b),LL(0x239a2436,0x762cdc78), + LL(0x4e33515c,0x32e5a4ad),LL(0x107349fc,0xfaf120c4),LL(0x42b588b2,0x18f529a5), LL(0xad41f013,0x53afbf6a),LL(0xfce98199,0x7e107d23),LL(0x49fc022a,0xb3e6ca6e), + LL(0xf43c63d0,0x2f0fa15f),LL(0x3c5f1062,0x2ee7972b),LL(0x1251d981,0x217bc709), LL(0x4f44f67b,0x869cc500),LL(0x6e74d49a,0x410ce8d8),LL(0x295b72ee,0xa2668d2e), + LL(0xc2e1ab9c,0x377d1c96),LL(0xf02f335e,0xc4d44912),LL(0x17483b67,0x91a1b453), LL(0x0a35ed35,0xd87bfb05),LL(0x06388074,0xda51aa7f),LL(0x3bc985d2,0xe8eded68), + LL(0x62093566,0x53a65438),LL(0xd40d4ada,0x1a184bde),LL(0xb1ce835f,0xcf398a06), LL(0x2e3db6b2,0x3e0368f2),LL(0x768efcf7,0x5b1e672f),LL(0xce1191fc,0xcde23025), + LL(0x1965b94c,0x7d18a84c),LL(0x42798e4d,0xa92514b7),LL(0xffa944d6,0x6df7a966), LL(0xc415a2b6,0x7c9cf75d),LL(0x0048e5ed,0xac0c7c55),LL(0xe02f7dae,0xd5c826e6), + LL(0xf728251a,0xee934c6f),LL(0xbd48f9f8,0xb7ec512a),LL(0x2ec83189,0xc5f704a8), LL(0xed82fce0,0x3c184301),LL(0x378c8f4d,0x8cbc0d6f),LL(0xa97c2ab3,0xc0ff9d1b), + LL(0xd18c264e,0xa6c6c290),LL(0x768df841,0xe5061160),LL(0x519df852,0x7913aaad), LL(0xf67253ef,0x61958563),LL(0xd45ffadd,0x36c367f5),LL(0x9e16d8cd,0xf1b45f01), + LL(0xec831ea0,0x3d1cecd3),LL(0xfa15690f,0x2bde5c72),LL(0x38b353ee,0xba0efaa9), LL(0xe8d4b6ee,0x15f17a68),LL(0x954159dd,0x9699e58a),LL(0xe8f17b7a,0x819578f2), + LL(0x61ee7443,0xc7eeaf29),LL(0x1b16a9dd,0xfa9c2747),LL(0x45e6c8f4,0xf723daa8), LL(0x80e39749,0x2c263cb4),LL(0xe1796ef8,0x69b29a11),LL(0x41cf69fe,0x71b39ec0), + LL(0xc93aacf4,0x277c0653),LL(0x90aa54e4,0xe7cedf79),LL(0xfbb3e9e4,0x5f3dacd8), LL(0xd0335cd7,0xebf8b3d2),LL(0x54b9f51a,0x320526dc),LL(0xda07d715,0x670feaee), + LL(0xc815957e,0xed31303c),LL(0x9dc47dbd,0xe3fd01ce),LL(0x7796d887,0x69884abe), LL(0x91801969,0x5eeac021),LL(0x1fede637,0x3f7f3b0a),LL(0xb577b6b1,0x94177a5d), + LL(0xeab50a36,0xffccab96),LL(0xc61d85f9,0x0d130c6e),LL(0x7da399fb,0xef804dc2), LL(0xa18f07c8,0x24faa196),LL(0x04fcf0bf,0x64bb949f),LL(0xd5aeb209,0xb1fcfc87), + LL(0x32651bcd,0xf00f320d),LL(0x06c32d6c,0x9df50f13),LL(0x5f7039a8,0xe5521172), LL(0x637e1a26,0x1ea8cc96),LL(0xe1edd4f0,0x2b163456),LL(0x0a1c1b35,0xf5bf574c), + LL(0xe6a6c9d7,0xd11076c0),LL(0x892f314b,0xc2f5ad9a),LL(0x5737733a,0x1ce795fb), LL(0x7ff3d547,0x2ea960a2),LL(0x1b76089a,0x44189130),LL(0xa3a6506c,0x6ef7149a), + LL(0x1032f79c,0x5903c244),LL(0xdcc0e2de,0xf21d72a3),LL(0x1762ce11,0x9ba803fb), LL(0xca5ae539,0x76e31b74),LL(0x9fd4f343,0x4e502c66),LL(0xd2eaa2ab,0xb6a9a1fc), + LL(0x073efd81,0x5888451f),LL(0x9927bf88,0x398711b5),LL(0x018be818,0xbb190a8b), LL(0x79e61240,0xc797d10a),LL(0x3beaa53f,0x8696dba6),LL(0xcfb7766d,0xb542db1a), + LL(0xd903933d,0x6f4e1530),LL(0xcd7c2795,0x12359176),LL(0x5a5fca32,0x755f299a), LL(0xc4a38b20,0xd72339f0),LL(0x842195c0,0x375cc0c0),LL(0x30d23f6c,0xbc55da2b), + LL(0x9aac817d,0xce0ba5f7),LL(0xa1a45388,0x3b669115),LL(0xf409cf17,0x1dedbc8b), LL(0x3ffa552b,0x31a461a0),LL(0x382ba937,0x86758b16),LL(0x795dc73f,0x4a479210), + LL(0x48aba8e6,0x83c44b08),LL(0x62517119,0x17c26d0a),LL(0xd01e1f9d,0x5b018ac9), LL(0xe9efcfe5,0x4397fd63),LL(0xfe0829a3,0xca651042),LL(0x13eb60a0,0x46cee0c3), + LL(0x8600caea,0x27529486),LL(0x35717139,0xd38810c6),LL(0x41461bde,0x63178e7e), LL(0x045c484c,0x227b3172),LL(0x97348e92,0xbcfee10d),LL(0xa51d3833,0x3fde1f78), + LL(0xf10b4b60,0x50b3debe),LL(0xa5ad595f,0x7901e0b9),LL(0x47e58c1f,0x87df2160), LL(0xfa209201,0xad4fd6ef),LL(0xa55d0556,0x9335bbb9),LL(0x00fee680,0xe8d815f3), + LL(0xd99bdf5c,0x3e3ecfe1),LL(0x9bc2df7b,0xcf690949),LL(0x102d61ba,0x7e6008b1), LL(0xe00329c7,0xc1283828),LL(0xeb7b35fd,0x5b105f4e),LL(0x3dcb3985,0x9509ed61), + LL(0x81c63288,0x045a1445),LL(0x76cc9ac1,0xa4e7b140),LL(0x48acdd5e,0xa2f07d10), LL(0xa2b81e15,0x90c45e5f),LL(0x308acd63,0xa933ffa1),LL(0xd7e46f9d,0x17365897), + LL(0x466f886f,0x8852a2bf),LL(0x4d14f3d8,0x4ace368b),LL(0xe440d441,0x8d94e2a7), LL(0x72866999,0xfcb3c915),LL(0x1b47c102,0x9760bf19),LL(0xe720c285,0x6611674e), + LL(0x11d915d4,0xdcb98a2d),LL(0x6beac9be,0xf990fa0f),LL(0x6dd7048a,0x681bfe50), LL(0x689f0ae5,0xb41ece47),LL(0x44ff0641,0xe6fdbd83),LL(0x0e9753dd,0x42e0fbcc), + LL(0x3ffa710c,0xc7877d3d),LL(0x9919eb3c,0x7f0c21c6),LL(0x290c9014,0xc85786a5), LL(0x5689cb11,0x093aae39),LL(0xb5d01c9f,0xfb777943),LL(0x8cebd9c1,0x319aaf33), + LL(0x1a2fd277,0x902b0342),LL(0x9af2dbda,0x0912afff),LL(0x48589a78,0x15e0d236), LL(0x1fa3327f,0xf8b35812),LL(0xec713d1d,0x8990816e),LL(0x8e343f2d,0x5e1a860b), + LL(0x3614d67e,0xf61322f7),LL(0x29935fae,0x4d6b23b9),LL(0xf4a58207,0x5c8bdcc6), LL(0x9265fa5c,0x750d615a),LL(0x40ca78a9,0x2022ff1f),LL(0x19732ba7,0xd9585db6), + LL(0xf29d3bbc,0x694abdf0),LL(0x24a568a9,0x03a757fe),LL(0xeb85bcf9,0x69e64a5f), LL(0x3a6d438e,0x11c2527c),LL(0xe22585b6,0x4aa39cb8),LL(0x20f51f14,0x696f234b), + LL(0xcd374897,0x796f3388),LL(0x747f55ca,0x9cae05cb),LL(0xc3244db7,0x0178bf8f), LL(0xcad92264,0x2cf6b0b2),LL(0xd9851a5c,0xa5eaffed),LL(0xe5613e1a,0x677ef509), + LL(0xb8a7827b,0xd774ccd5),LL(0x30c2fdb5,0x1a9035d8),LL(0x634655f8,0xeed95b80), LL(0x56b0b0bc,0xc2b700c0),LL(0xc9f0aa76,0x37259c87),LL(0x4c9ae4a6,0x7f6b6b1a), + LL(0xf72a765b,0x23bfe902),LL(0x838d2dcf,0xf220ca7d),LL(0xfa8c5fe9,0x6aa1a258), LL(0xdd1fbec2,0x80a3ac57),LL(0xbfd1c7fa,0xa9d70cd6),LL(0x997ee6ac,0x6c5953bc), + LL(0x6a40f84b,0x3b3747a2),LL(0xb83105a1,0xfd1a969b),LL(0xbbcb761d,0x3c5c4b12), LL(0xda6bebae,0x7c7f4e65),LL(0xa14f1495,0x7a4fdbf2),LL(0x49b37a93,0x7f59536b), + LL(0x3240d78b,0x0c50a5f1),LL(0xb32a0cce,0xb51ad026),LL(0x53101002,0x4ccf9cdb), LL(0x0073f0a9,0x2fa22f3b),LL(0xbd1d7831,0x3a7fe366),LL(0x740322c6,0x5f31b6ce), + LL(0x013aca29,0x5cbc9486),LL(0xe542ffae,0x03e60edc),LL(0x8457faa5,0x80539a8f), LL(0x6355b3b2,0xeba394b1),LL(0x2249fcd3,0x0bd1b305),LL(0x4e3f192b,0x5454e867), + LL(0x4416b978,0x78e9316d),LL(0x81c4173a,0xf2a15f86),LL(0xb6731547,0xa6971d20), LL(0x98dbfdb5,0x2c5b69c5),LL(0xfeac68cc,0xf7b1130c),LL(0x0e84299e,0xb1cbec33), + LL(0xc44d578e,0xb354773a),LL(0x712087f3,0xcc55ac98),LL(0xba9554a8,0xd9b75e7a), LL(0xe80e95c0,0x93eb6a79),LL(0x99fb7e95,0x667e67eb),LL(0x14b32858,0x105a22cd), + LL(0x6f70ee86,0x0ded3bd7),LL(0xc1a43b13,0x7e0e5a6c),LL(0xc41e1afa,0x893c3ede), LL(0xeaed250c,0x21e88f45),LL(0x93d3ef9c,0x2cfc36f3),LL(0x7da31990,0x5b4e1c71), + LL(0xc4126c1f,0x1b61be56),LL(0x5abc20ba,0x274763f8),LL(0xed1afb78,0xb49d2c4d), LL(0x3df52e62,0x1bdeb4ea),LL(0xfff32461,0x8dcdd1d1),LL(0xbb1ca9df,0xe3e523f7), + LL(0x809ca4e9,0x4672ae1d),LL(0xdde4d528,0x58d55485),LL(0x8b74e2f5,0x19428043), LL(0x203314f7,0x1745d62a),LL(0xd4c37bee,0x6157bba4),LL(0x7dd72c9f,0x49805c53), + LL(0xa37d788c,0xca78b3b0),LL(0xf475a121,0x17a44e3f),LL(0x1ad2fff6,0xe5c1c959), LL(0x70139e2b,0xd0312c1e),LL(0x8b27ca8c,0x6724a7cc),LL(0xd962035e,0xaf28caf8), + LL(0x9570d848,0xbcc2ea7f),LL(0x7f265e1e,0x05fc9759),LL(0x244ce79b,0xb4954372), LL(0x084d1046,0x164e75ef),LL(0x89adc16e,0x4defb358),LL(0xfa4dc623,0x550e503a), + LL(0x5564a17f,0x370b2b55),LL(0x55a566cf,0xe074512c),LL(0x78ab0d7a,0x110463ca), LL(0x5d2460f6,0xefd6c296),LL(0x9c33b5d1,0x9abe3d42),LL(0x08c3f981,0x4e016175), + LL(0xc21b36dc,0xbf03ca84),LL(0x0b8c07f1,0xf34003bf),LL(0x63eb0039,0xc537b09e), LL(0xb82887e2,0xcacbf643),LL(0xbd3bdbf4,0x9d053615),LL(0x61dda14a,0x5c36ffc2), + LL(0x528c2064,0xe1664301),LL(0xbcae3cc1,0x2e16357e),LL(0x52311eed,0x025d8360), LL(0x2f0a83b4,0x76f15854),LL(0x06dc8ff7,0x10d87d9e),LL(0xf989d477,0xaded98a6), + LL(0xa52127c0,0x3ed6c171),LL(0xa69dee80,0x0847d132),LL(0xd8445a15,0xb2e7e29f), LL(0x71f974e1,0x156e4663),LL(0xe5bd0273,0xd7512685),LL(0xc73100df,0x6f515794), + LL(0xc2ab5306,0x951131c1),LL(0x6c73f4f5,0x89255bf9),LL(0xe69b21c9,0x6ac84582), LL(0x0ab9dce0,0x018b49af),LL(0x7954a835,0x27e5b722),LL(0xb1229414,0x865a648f), + LL(0xc8dd070b,0x388cdc70),LL(0xf52522ad,0x75642aeb),LL(0xcc49bc29,0xe25ec387), LL(0x41ee6cb0,0x214f62c1),LL(0x041d74c3,0xc5ee3195),LL(0x449dbc9b,0x04d43b7f), + LL(0xc7e8f6b2,0xb3a64235),LL(0x323a93a3,0xeeb2edcd),LL(0x4938cf75,0x67e22e11), LL(0xa914b04d,0xd64b0693),LL(0x88b818df,0x688fa54c),LL(0x591d0c01,0xd481be4f), + LL(0xcf3d8ba4,0xaecd7d60),LL(0xa97c0b6b,0xc7a415c8),LL(0xeebbc7e4,0x3839dd69), LL(0xe2ff8cc5,0x0691d0ee),LL(0xe92d7a4a,0x0c253257),LL(0x36ca20eb,0x740e2dd7), + LL(0x2a1939f7,0x5d07cf91),LL(0x5cf3ecae,0x3f6c26a8),LL(0xcb547d04,0x92001c06), LL(0xdf774ad1,0x4175ff52),LL(0x6b5f9c2c,0x7abd12ff),LL(0x4d6d8453,0x1658d69d), + LL(0x40729414,0xcd926583),LL(0x8ebcd09c,0x8a3d6ad5),LL(0x95dc70c7,0x83f72907), LL(0xb5be9edc,0x200031c9),LL(0xd05c8986,0x472b56e6),LL(0x07e0faca,0x9899422b), + LL(0xf88b02ea,0xd7bf0be1),LL(0x9bffc69c,0xb622e02a),LL(0xbc6df9ca,0x1e5b8cb4), LL(0x350dfef3,0x048f54ec),LL(0x0a312a13,0xe1f864f8),LL(0xd6ca4ce3,0xd4bfba4d), + LL(0xb0c052cf,0xc3ff21f8),LL(0xfdfba872,0x19f1a2b6),LL(0x5b694edc,0xd6f10827), LL(0x68a8a596,0x6097aff6),LL(0x954b1904,0x518e1cd2),LL(0x7c51ccd6,0xfd80ae29), + LL(0x1a7e9066,0xbc7a7b59),LL(0x23db5c12,0xcce91b75),LL(0xa3c0a935,0xba7bf0ae), LL(0xda23595c,0x653f64a6),LL(0x08f45389,0x2ae29a0f),LL(0x88589fca,0x724f46cd), + LL(0x3372c3ee,0x45b34ad7),LL(0x985555fa,0x0f609319),LL(0x9f3dcb8f,0x7fd63b9f), LL(0x0bd28eba,0x13a518c5),LL(0xf5706481,0x57cffe62),LL(0xd032721f,0x11718aca), + LL(0x9dd7bfaa,0x32ef81d0),LL(0x7adeeac3,0x3ed2d217),LL(0x6157a51e,0xac2de8bf), LL(0x4d16615b,0x7a7ca0e7),LL(0x217f0fad,0x5bdd6a51),LL(0x099a123e,0xae2064e5), + LL(0x6f3b0a4c,0xd8eb2d51),LL(0x59883368,0x556551c4),LL(0x5f48ad2f,0x6c8195a1), LL(0x62de8d83,0x0a88379b),LL(0xd0b6ecc9,0xaaa811b2),LL(0x83c9d046,0xba49bf0f), + LL(0xe6eed978,0x11f53192),LL(0x41560616,0x0cdd4a81),LL(0x55689932,0x106a49de), LL(0xa791e389,0x79fdb67e),LL(0xe28a67d9,0xba7af653),LL(0xc7aa61e7,0x44db5d83), + LL(0xfee81242,0xe86f2877),LL(0xe05b4568,0x1ebfa60c),LL(0x66c639bb,0x6131750f), LL(0x3da39228,0x2f9b4000),LL(0xb25c8ded,0x8e37e3c0),LL(0xaa3c48d1,0x8c3858ea), + LL(0x37de8469,0x98bf7c76),LL(0x9d051f00,0xd78e0afb),LL(0xc71691e0,0x4553e903), LL(0x539040a0,0x807d903d),LL(0xf73fcb62,0x30fdeee9),LL(0xcc1519f0,0x9c01a657), + LL(0x0b7f4996,0xc5c73b26),LL(0x50750843,0x2ca19471),LL(0x5a92f717,0xe4d8d372), LL(0x4abe9028,0x832ebb12),LL(0xe09a7f03,0x7f0123dd),LL(0xe8c1d6a0,0xa8456dbc), + LL(0x28302bb6,0xc8639947),LL(0x037bebfc,0x1fc1410a),LL(0x9f0b40a6,0x7432946a), LL(0xe06af4e8,0xff9565e1),LL(0x8b9882d9,0x02d05ead),LL(0x13e179cd,0x6e5ca86c), +}, +/* digit=23 base_pwr=2^161 */ +{ + LL(0x4584bdf6,0x5fd3ebe9),LL(0x847693d1,0xd8a4299d),LL(0x40b5d01a,0xc9c0c5d6), LL(0x3afa9eda,0x70b51263),LL(0x805fb55b,0xde94920e),LL(0xb5a46cc6,0xf0c432e1), + LL(0xf6dcaedc,0x0ce0859d),LL(0x3a3f7708,0xa55b2e15),LL(0xc0a8b787,0x200ce3fc), LL(0x3c7bddae,0x9e0f9782),LL(0x0b81aa87,0xe9d43e19),LL(0x4666b8f8,0x9c47c1bb), + LL(0x228ed42e,0xa9c19cef),LL(0xc0249ead,0x22c955e1),LL(0x264c2cb1,0x40d5d287), LL(0xa4070d06,0x420e5723),LL(0xc0604717,0xc2a3bf15),LL(0x4a963f1c,0x7ab3da61), + LL(0xda80e5fc,0x739b4f37),LL(0xcf587883,0xb45a6fe6),LL(0xcadd521f,0xe4a9b791), LL(0x57562a1c,0x27e1b300),LL(0x2fd0f712,0xb04af2a5),LL(0x93409099,0x12cd55e1), + LL(0xad7c2bed,0xe518dc8f),LL(0x65eedead,0x52acef20),LL(0xb2efa9d0,0x4227e093), LL(0x99c38a81,0x8b7ca42d),LL(0x4c509cec,0x30c1a73e),LL(0x51635a28,0x3dc9300c), + LL(0x46be452b,0x92d5ea3d),LL(0x215ba744,0x40841923),LL(0x9930df86,0xd8335b49), LL(0x92c4868b,0x12da53b2),LL(0x60a4383f,0x2400365b),LL(0xe190b71c,0x646771ed), + LL(0xf14687de,0x30e142c5),LL(0x9403fa68,0xad298203),LL(0x2c2dd3e0,0x3e98cfd3), LL(0x5bd48575,0xe2426602),LL(0xc9d41416,0xc7a5a2b7),LL(0x4ade8bbf,0xdcaa3d31), + LL(0x5f6b0fff,0xb8792b08),LL(0xfac1431d,0x17e00f0f),LL(0x479b79be,0xcb5f6f9f), LL(0x32c49e8c,0xbfecbd08),LL(0x654100b0,0x6a6be7f1),LL(0x0890c3b8,0x2e545747), + LL(0xb07447fd,0xa559c912),LL(0x56728d8c,0xb33a2b44),LL(0xf526bd48,0xa027ee4c), LL(0xc58f6af2,0x12d8001f),LL(0x374fa755,0x79e6db7c),LL(0xf25a1455,0x2cbc98cc), + LL(0xd10a0b59,0x597f4f1e),LL(0x84bc0000,0xe166c79f),LL(0xf74bc520,0x5ae7890a), LL(0x8660d37d,0x3303f3aa),LL(0x405c0955,0x2d0ab6f5),LL(0x1f6fea86,0xe98a1550), + LL(0xb1fec6f3,0x58dac0ba),LL(0x0018597d,0xc24ea4df),LL(0xebe0dd78,0x9ec12302), LL(0x2bec23bd,0xfa749d3c),LL(0xd47a29a6,0x91a607e5),LL(0x273be752,0xb0e81d66), + LL(0xb3a95f3e,0x6975c26e),LL(0x1d7290dd,0xcb4ee68d),LL(0x4c6ba170,0x8120bbe9), LL(0x1a407679,0xf428065b),LL(0xc12ea429,0x92b64255),LL(0x56d99374,0xc94c96d3), + LL(0x0103f0e7,0x1bd6a47d),LL(0x1affc26a,0xce0f3821),LL(0x1b702d5d,0x284426b0), LL(0xc65050e4,0xe5ba26be),LL(0x77a391dd,0x29e14db3),LL(0x8ee16508,0xb917678f), + LL(0x0ddf3f74,0x18c4fe3a),LL(0xd8e5db90,0x477e39cb),LL(0x56614560,0xaf43028b), LL(0x8c492bee,0xffdf3688),LL(0xac548919,0x595987ef),LL(0x74dc2b98,0x4d0d250a), + LL(0x3c574a92,0x25fa0aa2),LL(0xfaa1a418,0x89be8ba2),LL(0xb69739a1,0x1b002c0d), LL(0xe3f5b3a7,0xa6b854ef),LL(0x1204504d,0xcaa17499),LL(0xa58cedd3,0xad836998), + LL(0xc4d5d262,0x3cddb768),LL(0x4251792d,0x0a0801ad),LL(0x0d3897eb,0xd704ec49), LL(0x9c91baee,0x0e13d4f4),LL(0x82831726,0x090f2c69),LL(0x76422a7f,0x829b8edd), + LL(0x49398523,0xe83170b2),LL(0x1b62a533,0x253100b2),LL(0x5e36efc0,0xc18431d0), LL(0xc4c34823,0x26325714),LL(0x628d7b24,0x74c3cfd0),LL(0x9d919045,0xa961e996), + LL(0x41d95f75,0xe3a642ca),LL(0xf0a8d5c1,0x4c53ea80),LL(0xa9d3eedc,0x07463073), LL(0xc4e66d00,0xa1439f9e),LL(0xb0694462,0x451a25c4),LL(0x8dfe8fe6,0x713bf4e8), + LL(0xc9e24326,0xae9ef904),LL(0xe8bfd9ba,0xe039837f),LL(0x59511a8e,0xaca967be), LL(0x7acac091,0xd2386b22),LL(0xe9d27517,0x63bdb595),LL(0xce41bbd3,0x51f95292), + LL(0x9ec42924,0xee0ee680),LL(0xb77fdef0,0x4af753cb),LL(0x7cb4d8a9,0x15078aba), LL(0xb4177c3e,0xe19806b9),LL(0x88f090af,0x3e1d4fc5),LL(0xeeb90099,0xc7b2cc43), + LL(0xae6a6f66,0x24b3ffd7),LL(0x308cc05f,0xab2000ed),LL(0x107b362e,0xd89d6e75), LL(0x1fa91ce6,0x835736db),LL(0x390c487c,0x6429da58),LL(0x0d312fc5,0xbaed5289), + LL(0x4a018455,0x0feb44af),LL(0xad578332,0x1af273ce),LL(0x5f625cc3,0x31349adb), LL(0x2d2f3877,0x3848e62e),LL(0x1bfe8dd6,0x620372c5),LL(0x16c9a24e,0xbcc4d459), + LL(0x0a45de42,0x40c8630c),LL(0x30cc053a,0x74488edb),LL(0x119b7194,0x9cdb7fad), LL(0xd629e05d,0x02121283),LL(0xfa4bbe6d,0x727585f8),LL(0xea1f9677,0xc2a6e653), + LL(0xbc14220c,0x4656ea75),LL(0x00b087d6,0xc70a76ac),LL(0x3d83a9ec,0x037ac35f), LL(0xaac1649a,0xf8f1e014),LL(0x4c5f804f,0xaa6de597),LL(0x7d523732,0x8cd45ec3), + LL(0xa04c2d63,0x4540fa7b),LL(0x9eb857a9,0x544d7dec),LL(0xe8f40c8a,0x8ada66ad), LL(0x4598d9e3,0xb8c4fa18),LL(0x516e5110,0xd3ef8a28),LL(0xd56843a4,0xb761d4d5), + LL(0x91f59c5b,0x0aed399e),LL(0x43f5de7f,0xe4868fd3),LL(0xe58c53b6,0x01b524d0), LL(0x712c183e,0x77219f8f),LL(0x036dd938,0x6371e9d4),LL(0xa8cc4985,0xd4de675a), + LL(0xc894130a,0x7da252c3),LL(0x85384ea0,0x9e4041cc),LL(0xeba418c6,0xd0a69993), LL(0xaf043892,0x9a9ebb66),LL(0xc703f8bc,0x9baa32db),LL(0x0bf6fcfd,0xc250e1c4), + LL(0xf56a38f1,0x5913cd6a),LL(0x61ecfa22,0x1e16a4f0),LL(0xb5c22ada,0xeb036c2e), LL(0x95892d2d,0xca1a39c5),LL(0xd31c9856,0x4688a1cc),LL(0x29e69ad8,0x3a6ea062), + LL(0xda5d2bab,0x283f3d5c),LL(0xa82a537d,0xc4f0d483),LL(0x81e8516a,0x953f037a), LL(0x5a8f3330,0x6bf902cd),LL(0x9216e842,0xda96e730),LL(0xd1f1d62f,0xa8ca4ed6), + LL(0x50bbcd76,0xd9521c88),LL(0x5533084d,0x3d8ab30a),LL(0x40a22bb5,0x4328e72f), LL(0x680fccc1,0x6594e079),LL(0xbd6afc46,0xc578705e),LL(0x724db349,0x677a7e9e), + LL(0x77b5d2f3,0x376f9327),LL(0xc9b18afe,0x87bd1401),LL(0x7395cc2c,0x8f06b3fb), LL(0x0f11a8a7,0x5d2d7a7c),LL(0xa3a0d64e,0x84cc49c1),LL(0xf720e6f2,0x0b5a5743), + LL(0x80df0a37,0xaeedece7),LL(0x9fa00fed,0x78b407d3),LL(0xfb5d3331,0x8ada177e), LL(0x8af3669a,0xa526660c),LL(0x26f37f61,0x95b36f2f),LL(0x1e1206f2,0x21aeaae2), + LL(0xade1a30f,0x0fbc3955),LL(0x70682b66,0x27c9b059),LL(0x2bfa453b,0x2fce5ba7), LL(0x1316e4e1,0xc90c4a00),LL(0x761c39fd,0xd6355b7b),LL(0x2532c4da,0xf0e4ff59), + LL(0xd62425cc,0xa9d571ca),LL(0x842bd560,0xdce97426),LL(0xc461be1b,0xbb38f10b), LL(0x822d623f,0x3d2249f7),LL(0xe1eeb405,0x202ec2c7),LL(0xb64d9541,0x4527855d), + LL(0xc433bf19,0x6fb57a38),LL(0x2a004581,0xa01483cc),LL(0xf1fb8cac,0x7cb982cf), LL(0x7ea92be5,0x8e24b22a),LL(0xc526028a,0x44dc6883),LL(0xc3c10ecd,0x3ccba012), + LL(0x6e378a16,0xfe5d98dd),LL(0xd7a9f035,0x959df6be),LL(0x856a9b08,0x9123863f), LL(0x4a4861a1,0x37a49207),LL(0xe726e927,0xf3abe482),LL(0xe950eead,0x80ca1765), + LL(0xf21dac1d,0xa899447b),LL(0x62bb8a55,0xca34599d),LL(0x599442ee,0x3ace3361), LL(0x9b2bdec8,0x19fb35d6),LL(0x1ba85c82,0x60e552f0),LL(0x0ecd12b9,0xe293d542), + LL(0xa2c1ef2f,0x6effd23e),LL(0x114661d2,0x5cd387d8),LL(0xdffe2dc7,0x8e8c7a48), LL(0x16c4945a,0xa2c03c10),LL(0x9644389a,0x9d7fd950),LL(0x30888d62,0x64455c93), + LL(0x910d7674,0xfda175a4),LL(0x233d1789,0xa7147ea4),LL(0x9013a09d,0xf101e4a2), LL(0x07139a87,0x67af7675),LL(0xf5941b5c,0x94837a17),LL(0x2afba5b9,0x8d2a3dc4), + LL(0xbfe0067a,0xe2c65840),LL(0xe666562e,0xd0b29ae1),LL(0x3f69d5ff,0x994f3344), LL(0xb38b5225,0x4895550c),LL(0x67443db8,0x317f6133),LL(0x6a3efbb9,0xe78c5ffd), + LL(0xf20ec153,0xb98ff8ef),LL(0x54026d0e,0xbb891684),LL(0xe7d12956,0x54ec1dc1), LL(0x8a5739e8,0x9c22e187),LL(0x2ada1917,0x1afc3eb0),LL(0xc839e43b,0xff8822a3), + LL(0x7425abda,0x9d4a9d18),LL(0x7bd3fdc1,0xf8e9fbc5),LL(0x9ebefe1b,0x697f7987), LL(0x1e6ed20f,0xa9e72448),LL(0xcdf74ccf,0xa345725d),LL(0xbe698fa7,0x7896df8e), + LL(0x3ba72507,0xa0c0c8b7),LL(0x0fa2a2a3,0x65954bbd),LL(0x16257ac3,0xa5e65d96), LL(0xbba0d229,0x3818228d),LL(0x021796d5,0xb8be11d8),LL(0xb97dc1f3,0xe6c3332a), + LL(0xdfda1f51,0xb405e455),LL(0xcbe599bf,0xa82537f5),LL(0x9f755190,0xb60bf1e8), LL(0x32a7e242,0x38f7bb06),LL(0x98acbf9b,0x3212ccc5),LL(0xe7ff0a94,0xeebc9ac0), + LL(0xd6c9a5f3,0xbb8969ed),LL(0x5bd66149,0x12b8c0a4),LL(0xd0b87b2f,0xb58f5e63), LL(0xd834d568,0x3567a0dd),LL(0x19662011,0x9a569d08),LL(0xf86f6443,0x089e7840), + LL(0x632d7db6,0xbdbee0e9),LL(0xc3b20b5a,0x6d9f02c0),LL(0x998a8d90,0x1050c608), LL(0x2f06ab1d,0xd8d0282e),LL(0xab0aa37e,0x4c54a44d),LL(0xd082d2ae,0x6e1b0aa1), + LL(0x25ecff7f,0xfeabb634),LL(0xd1a47294,0x97ef1829),LL(0x45d079b6,0x478931f1), LL(0x90a34a1a,0x0c0a2fa3),LL(0x25caf0d5,0x152a763f),LL(0x0e40b542,0x35d8af73), + LL(0x2007d582,0xc49fbdb0),LL(0x26d43be1,0xbba36d92),LL(0xd8e1f054,0x4e8feb86), LL(0xdf679100,0x2d7a4eb1),LL(0xa594368f,0xd99cc183),LL(0x7a3bbb39,0x5953cee1), + LL(0x8b7ac847,0x9db6811e),LL(0x2196bcd8,0x611682a4),LL(0xab14055b,0x5d9d1f5a), LL(0xec03a248,0xde8b16e7),LL(0xd7f2292b,0x8fdd20f4),LL(0x55aedc44,0x0ab41c2a), + LL(0x4c2182b6,0xdcca73f6),LL(0x236096b4,0x8fb4b87f),LL(0xd5653730,0xce326270), LL(0x76943c44,0x5c9e40b8),LL(0x0ab1c0c4,0xde4cd5b3),LL(0x3940c729,0xf6ed23bd), + LL(0x77a7afa6,0x5c07d98d),LL(0x5fb74010,0x3b469a44),LL(0xd7860cfb,0xfd595617), LL(0x59e07d3b,0x98976412),LL(0xba3430ef,0x90454a37),LL(0x0a3e1885,0x46a2a6dd), + LL(0xfb32d876,0x25adf7fa),LL(0x774e5344,0x256577cf),LL(0x1805d5e4,0xfd44d54d), LL(0x8fb4e6b6,0x92207fea),LL(0x11c5d5d5,0x4a220d0a),LL(0xf8e91bdc,0x3be12723), + LL(0xc245b8f3,0x2ca7da35),LL(0xa88aee56,0x2870eaac),LL(0x46354fd1,0x550b013d), LL(0x79eff102,0x42ddcbc1),LL(0x111f871c,0x66a3ed1f),LL(0x3e002a53,0xbddf6a08), + LL(0x89d6175b,0xdadeac86),LL(0xdedeed02,0xedba73cd),LL(0x5fae1ea3,0xf56ed9fa), LL(0x46fb11d2,0xd27a3c2e),LL(0x8111c477,0xe8196e09),LL(0x4511b448,0xff123cde), + LL(0xe26a279a,0x0f843c1c),LL(0xa3576554,0xc5e0d5bb),LL(0x41361ba5,0x23b9fb1b), LL(0xe963cc9e,0x23b72bfd),LL(0xb847fc14,0xdce7e767),LL(0xf14fcef9,0x162fc75f), + LL(0x5495b1c0,0x835fb910),LL(0x9d67f026,0x4bf8073b),LL(0x8899fab2,0xbf47587e), LL(0x82303583,0x5d3d606d),LL(0x3016c2cb,0x8dc9e515),LL(0x70ad2ecd,0x1941fb0d), + LL(0xaaf9bf1a,0x52d3382e),LL(0xd97fd623,0x82ca0b62),LL(0x421adaf5,0xd415fb55), LL(0x5bae728f,0x9e737a64),LL(0xa226fda8,0x8bb1f7ec),LL(0xc8fc211a,0xbbe52052), + LL(0x98b18dd9,0x111f6855),LL(0xfc1a8284,0x07963287),LL(0x049bc41f,0xadd96aeb), LL(0xa4b9431a,0xf9cdc9cf),LL(0x3186f178,0xed472952),LL(0x9e6b099c,0x7c483bff), + LL(0xecf00f66,0x0f259f0b),LL(0xdc4d7da1,0x42adeebe),LL(0x8347831b,0xa84be35a), LL(0x1cb75e95,0xfcc87599),LL(0xaf570741,0x4d352430),LL(0x560a12e1,0x3985430b), + LL(0x269c3158,0x0d101d88),LL(0x62a2e7c9,0xf4f4fd03),LL(0x5bd4e966,0x2868c3a9), LL(0x3f2fe7d2,0x28560f6f),LL(0x9f97e5c5,0x33e9acc4),LL(0xaa6fdb21,0x13e585da), + LL(0xa9d10acd,0x8c93261c),LL(0x39ee8556,0xaa0c4ecf),LL(0xa1ae594e,0x24174c20), LL(0xe22539a2,0x3741dd7f),LL(0x592618e2,0x2d22e571),LL(0xdf3458f1,0x2f7bfd39), + LL(0xd69e123f,0x0a50b744),LL(0x16a94796,0x64461277),LL(0xe18a1d4d,0xd71b262f), LL(0x5e180b7b,0xd9040b30),LL(0x47d6ce9d,0x26f0f403),LL(0x67a15aa3,0x78d16700), + LL(0x31529faa,0xa97d1af6),LL(0x2ce2270e,0x6598f797),LL(0xb178d3c3,0xfeb8f446), LL(0x16f5a2ab,0xa967e2c7),LL(0x04b96d78,0x205fdcb6),LL(0xe986b7e7,0x0e580f2a), + LL(0x2dd71da3,0x5b769229),LL(0x88f598fb,0xfaf8b016),LL(0x143492ae,0x8f8d4b70), LL(0x96a9c03f,0xa7f5e617),LL(0xa0c34682,0x6bd67a8e),LL(0xa12c32cc,0x7b459945), +}, +/* digit=24 base_pwr=2^168 */ +{ + LL(0x4fee65e2,0x00b598c5),LL(0xf18f37b1,0xf85f1a2c),LL(0xe3b72548,0x8659b393), LL(0x696e8d4b,0x3f89080e),LL(0x219f661f,0x4b0794d1),LL(0xa6fda57a,0x95783cf3), + LL(0xacf31bb7,0xd47dbc28),LL(0x44076b4a,0x228ba361),LL(0xeff372cb,0xc98f0d65), LL(0xed79eb73,0x73179523),LL(0x9c75c7fb,0xc172348a),LL(0xfd4dc8f8,0x56a7598b), + LL(0x611e59a4,0x59648973),LL(0xa9f595e0,0x2151777b),LL(0xf5551b53,0x4c47c966), LL(0x3972a3d3,0x021253a3),LL(0xb4befe84,0x90bc0c61),LL(0x77515e8a,0x16d84bd2), + LL(0x94f40d96,0x5c350e2e),LL(0xa5864e3f,0xdfcbcae9),LL(0xfb5d92bb,0x9a2e4e30), LL(0x44281abe,0xd9bde421),LL(0xea539b37,0xa7f9d3a7),LL(0x27b92e31,0x61c3ae50), + LL(0xf2aa70a9,0x2244e258),LL(0x35be44a9,0x73df3f53),LL(0xa6238039,0xdcefe8bb), LL(0xe47497a3,0x3a811b6d),LL(0x25465973,0x620c900a),LL(0x4aa632c7,0xe81d4109), + LL(0x81a533c4,0x49894327),LL(0x9c521884,0xb510e537),LL(0xd2db22d8,0x8e091dec), LL(0x2112921b,0xe40883cb),LL(0x3023be06,0x77a182a5),LL(0x344bcdce,0x9406af56), + LL(0x5f5b1245,0xb0c7d9e5),LL(0x01cd2020,0xf2cae30e),LL(0x4f24138a,0x300d3991), LL(0xe5eb6668,0xb1a3ab1f),LL(0x1468e662,0x1c21f927),LL(0xe4627789,0x2cd78fd3), + LL(0xa2475808,0x6bb937ce),LL(0x89fbe7fa,0x190dea20),LL(0xa4a879ab,0x2b19299e), LL(0x02e58d85,0xd08bb8b3),LL(0x44d8e850,0x5f3c807f),LL(0xa807b92b,0x7163052b), + LL(0xf139c859,0x33e3fbb7),LL(0xb61d1651,0xae851c86),LL(0x711ebfa9,0xd19bb9d2), LL(0xab556ef8,0x04eb2dec),LL(0x26e75498,0xa90032a2),LL(0xad236dde,0x1b6e1eac), + LL(0x72b36422,0x45e0d154),LL(0x440553f6,0x505c7e2a),LL(0xcfaf2624,0x51c21ee7), LL(0xeead1c76,0x28cfa503),LL(0x21322f7a,0xe7e08256),LL(0xca8f7baf,0xb50012c8), + LL(0x0e8b3583,0x3ec7b6f2),LL(0x40191db4,0x75562e4b),LL(0xd97200b3,0x2de64fe8), LL(0x67766784,0x9035e032),LL(0x00818616,0x5f64b295),LL(0x9d38c296,0xd62bff91), + LL(0x20e7da86,0xc1c38d7c),LL(0xaa79a592,0x29d1701d),LL(0xcb4964c4,0x43853290), LL(0x558d0744,0x157c8a28),LL(0xd845fdae,0x9359aa13),LL(0x0c16e633,0x6938504e), + LL(0x303aaf9c,0x7551d181),LL(0xa6ee9450,0x4f75790a),LL(0x5a5ee5ae,0x30cda47c), LL(0xcaeeda67,0x5cecbe96),LL(0xb6acf1ec,0xbb304fb4),LL(0x23d4e0e9,0xa8d438de), + LL(0x55bbf072,0xe3c174cd),LL(0x096526d5,0x4c192612),LL(0xa3622362,0x72b1886e), LL(0x38ad3224,0xf9ff34ac),LL(0xde248da9,0x3c0e6f03),LL(0x904019ba,0xaed9b48d), + LL(0xeb4c2fe6,0x8b931dfc),LL(0x6fb1fd3f,0xb59385ae),LL(0xcdbf8b2c,0x34d15d09), LL(0x501dfe27,0x354fb5bd),LL(0x8678f10a,0x3244c239),LL(0xdefc3322,0x27fb966c), + LL(0xd835d9d2,0xa7bfa23b),LL(0x3d77d0c6,0xe2e0879f),LL(0x7198caba,0xcd307f9f), LL(0x8ef6dc8a,0xaaf47ac7),LL(0xe089b5a0,0x79d488a1),LL(0xd3898ccd,0x9c5910d1), + LL(0x99fedbbc,0xe1a69186),LL(0x8c8fedb7,0x1cb035cb),LL(0xb456f31c,0x2cd27f26), LL(0xde4d4827,0x5fe6041c),LL(0xc126f7bf,0x3566eaa3),LL(0x4361f83f,0xafba18a2), + LL(0x5b63f6d1,0x79cf0a94),LL(0xd989b598,0x00ce6a85),LL(0x03f0b2c6,0x0f8d928b), LL(0x018ff12d,0x4a4299b9),LL(0x5f379fa7,0x59ab07e4),LL(0x5381194b,0x5e5deef5), + LL(0x3c4ab2c9,0x6e7f659c),LL(0x65654e5a,0x8a446f62),LL(0x6327f61a,0xc3cccd42), LL(0xd14cb9b1,0xc9e4ca54),LL(0x6bde8567,0xeee5364e),LL(0xdd7a0868,0xac8150fc), + LL(0x5f134595,0xa719652f),LL(0xae508424,0xfcfec81c),LL(0x11ba658e,0x9e16ae3f), LL(0x60511e27,0x88494b81),LL(0x66979b9a,0x495d153e),LL(0x49fad3d1,0x55611c7a), + LL(0x8e3ffac8,0xfc730512),LL(0x83da2d11,0x1b6bf5a3),LL(0xac075bc5,0x99558261), LL(0x7587269d,0xd44f89c7),LL(0xdee8b114,0x05413990),LL(0xe309d884,0x35258a3c), + LL(0x6a76d0d3,0xba07c28f),LL(0x5067e16c,0x18a52a08),LL(0xc175e5e2,0x6ae1d870), LL(0x9b314f1f,0x5404c2f8),LL(0xb85b02be,0x22c45028),LL(0x69fe8fb5,0xbfa91557), + LL(0xd5e20541,0xf420471f),LL(0x93b4597e,0xb7cd0563),LL(0x9e8fced4,0xcd762134), LL(0x667246ed,0x93f1a293),LL(0xcc37aa97,0xa67f1015),LL(0xccc76489,0x54ecfc1d), + LL(0xffed38d3,0x2867d280),LL(0x339ff836,0x34e2e617),LL(0x843d9ee5,0x90c7a0a0), LL(0x0bc5ad9d,0x38be6f0d),LL(0x61784c24,0x5be128b1),LL(0xf5c92d27,0x6d1d7024), + LL(0xf28e8e61,0xb93c9e42),LL(0x2e7b7f4b,0x1cb53b6a),LL(0xe4e0fef9,0xe1f605e9), LL(0x1f88f7d1,0x069d28f6),LL(0x22c71a8d,0x96265f16),LL(0xdab828ef,0xac157d26), + LL(0x341a67b9,0x98b3a5ed),LL(0x3f3639df,0x9aaa605c),LL(0x8b92ce1e,0x59297d2f), LL(0x36504280,0xb9812805),LL(0xa4416a3d,0xe5ae2be0),LL(0x41919442,0xb31daa16), + LL(0x0feb1f18,0x1634ffbc),LL(0xd33d0a9d,0xa51dcbe0),LL(0x767a41f1,0x0e03bb87), LL(0x148212a0,0x01041281),LL(0x0e55fb63,0x07f9ce13),LL(0x9bbfabe9,0x9dcfb9b9), + LL(0x4eb575e2,0x3ac5febc),LL(0xc5aedbca,0x8aaae188),LL(0xd5870b65,0xc14938bb), LL(0x37600276,0x05a4c6b7),LL(0x6227e53f,0xa3b7f153),LL(0x4703e577,0x3b37d9f1), + LL(0x6aea82a4,0x7354429d),LL(0xd061ccd4,0xa8b693b4),LL(0x52d0b458,0x3120ff37), LL(0x92f80ea7,0x254dbf7f),LL(0x89430f4b,0xd229a339),LL(0x94de0c1e,0x97b253ff), + LL(0xe4b60a58,0x6556cb19),LL(0xf3b79531,0xaf91e209),LL(0x5bd7c1e7,0x4600c789), LL(0x4100417e,0xe92bfc4e),LL(0xb6d8a9d9,0x772261d9),LL(0xa9a6916b,0x2e573e06), + LL(0x98b95e3a,0x05709266),LL(0x1dbd0d3c,0xef67fdbf),LL(0x7552cee7,0x950e2fa7), LL(0xf4ae00d3,0x03b57561),LL(0x46ba7e71,0xf070c70a),LL(0xe39a20da,0x196843b1), + LL(0x60091a66,0x4213bea2),LL(0xa0e25486,0xbed0b79e),LL(0xe5c60f95,0xd2bc9dfb), LL(0x3ce65338,0x7aa159d5),LL(0xc8ec70b6,0xef1f0d85),LL(0x28d23ccb,0xb47100d7), + LL(0x2f8c540a,0x7c602da6),LL(0x854edfb6,0x9e3193eb),LL(0xa18a05e6,0xd1b97d97), LL(0xc430fcd8,0xff9bdf8d),LL(0x3b7fb6c4,0xdfde4b67),LL(0xa97725fd,0x3d8b2185), + LL(0x0cd2fdea,0x20f59fe1),LL(0x5923a8af,0xfe8a4dc0),LL(0xfa9e9992,0xf9d94a99), LL(0xd35b2020,0xb9c441eb),LL(0x07668b98,0xcce38d28),LL(0x2bf90eab,0x582f54bd), + LL(0xab0e3f41,0x9f1d9413),LL(0x3a412ee4,0x5e8c119b),LL(0xf030ad58,0x8879b87f), LL(0xde74321c,0xe48dc015),LL(0xf6cee695,0x522fb0ae),LL(0xb8d5054e,0x40162c77), + LL(0xc129d829,0x2f8ae88f),LL(0x3f3ab771,0x999f091f),LL(0xffb12ab6,0xa7e1a5ad), LL(0x6c51306e,0xbf7d078b),LL(0x3307b832,0xb084c854),LL(0x64450a20,0x46824c00), + LL(0xff4b278e,0xafad7324),LL(0xb780a046,0xf2aa88cf),LL(0x03143e85,0x429e746d), LL(0x91dc0962,0x5727ab2b),LL(0x67771a60,0x489517bd),LL(0xd28b48a1,0x2d01a677), + LL(0x68e73dfd,0xcecba270),LL(0xcdb43f75,0x2988378a),LL(0x8a6f1487,0x617e4cc8), LL(0x77958a86,0x7b3bbea4),LL(0x00baf816,0x097fa14d),LL(0xf3dd7875,0xaad04d0d), + LL(0x6ac04cd8,0x03d57abe),LL(0xc1971431,0xe65c48d6),LL(0x57dbcf69,0xc762049d), LL(0x408042bd,0x967f3d11),LL(0x0ff3e3b8,0x8b9583ed),LL(0x11593e70,0xafcb3c34), + LL(0xc3f9b58c,0x41df50a9),LL(0x55f9cc35,0x259d92b8),LL(0x2f2195a7,0x670ff896), LL(0x242e6aed,0x1a7c5825),LL(0x0b8b7fa6,0x04cc2dba),LL(0x0f24c794,0x20eb7a8c), + LL(0xab8c47fd,0xbb5b87fa),LL(0xe425d990,0x24a897b6),LL(0x680c630a,0x86cc5725), LL(0x31fb1789,0x98095baf),LL(0xe7c13217,0xc3655f2e),LL(0xf43a1aa1,0x014736b8), + LL(0x52deee88,0x62bcaf35),LL(0x5b973eba,0xb396c4e7),LL(0xbda679ab,0x51c1903d), LL(0xd5c3a5aa,0xae30078a),LL(0x40876de9,0x8b17d5cd),LL(0x86473f13,0x150e6256), + LL(0x09da0150,0x3afdb04f),LL(0xa6c1fbb6,0x944dc9f4),LL(0xd6d37139,0xf978d7e1), LL(0xd7688302,0x294df22d),LL(0x050fc353,0xcb4a2989),LL(0x4d693ea6,0xb7355cc1), + LL(0x705e6c1d,0x603b9990),LL(0x6e20c02e,0xbc22cb07),LL(0xda4a714d,0xcf26fedd), LL(0xc5f7dd2d,0x499a5020),LL(0x870ff472,0xd5f6d465),LL(0xd7242e9f,0x64105bcd), + LL(0xdfc15966,0xe8651d8a),LL(0x3f36c08c,0x65f62567),LL(0xd7cc1614,0x7e1b118a), LL(0x5f8c1b51,0xe547ba77),LL(0x40fd1c4a,0xbe829b43),LL(0x7393994c,0x27ef6fa1), + LL(0xf06e1517,0x47b06a9b),LL(0x9538a94f,0xfc4162b2),LL(0x8787dbb2,0xda0b09f1), LL(0x69ed3599,0xaf40f743),LL(0x20668861,0xd0539dd8),LL(0x4d25d347,0xd97dd381), + LL(0x8ed5efa1,0xf37b0062),LL(0xf0d1e9a1,0x33b8ee0e),LL(0x4e88bddd,0xfc5ed264), LL(0xebc6518d,0x9c8a10bf),LL(0xed07b158,0x3bacc4d1),LL(0x38679a57,0xf3a21ff7), + LL(0x28d869ca,0xb696e37a),LL(0x5e14048e,0x1c92d21f),LL(0x09011d46,0xbd612912), LL(0x344de336,0x4253b283),LL(0xb1b9160e,0xc5500601),LL(0xe5dcbf35,0x6a09d20c), + LL(0x94adc78d,0x0d0de35b),LL(0x0dc1d07c,0x77e19853),LL(0x0bdd2c5b,0x34b0dc75), LL(0x753ad557,0xfb35d357),LL(0x63471eb9,0x5d25872a),LL(0xc1012690,0x0deb74f6), + LL(0xaaab12f1,0x8af62a30),LL(0x1013c549,0xb94f6b3e),LL(0xe29c422c,0xc66fd2e8), LL(0x5ac31b52,0xf14b58ae),LL(0x222c930c,0x341a40c6),LL(0x79810099,0x97a887df), + LL(0x4d81c717,0xd365310a),LL(0x01f352f5,0x03f4d8f5),LL(0x7eea6a1f,0xf252f189), LL(0xf8638d81,0xb159cdf9),LL(0xe3f109b7,0x984ed9c3),LL(0x782d6bf4,0xef2542fb), + LL(0x587be148,0xd0c19f88),LL(0x86172fd1,0x607cef08),LL(0x75ee2bbe,0x7d46f8eb), LL(0xf39fe2f1,0x0d243305),LL(0x362a46ff,0x595aba8f),LL(0xe19fa4d4,0x5a9e9116), + LL(0x9d07c0e7,0x7c3998c0),LL(0x3ab74d57,0x5dab40f7),LL(0xc6ea1153,0xb0deb5d1), LL(0xdba8086e,0x2f3a9092),LL(0x9dd0d434,0xdf0db996),LL(0x30e52883,0x63af92c7), + LL(0xfb8379d7,0xce592f6b),LL(0x57237edd,0xf182db14),LL(0xa33ff0fb,0x435ce079), LL(0x16e22f7b,0xf67443b4),LL(0xd01a4364,0x1a603d76),LL(0x0d3849b6,0xf37e32ca), + LL(0xe6dac621,0x2456397b),LL(0x1585b538,0xa98d7499),LL(0xd2fb419a,0x249b8fe2), LL(0x2d722c8e,0x1971929c),LL(0xeb0dfb04,0xb835ed94),LL(0x7786927d,0xe0ec2ab9), + LL(0x96808ab1,0xda420127),LL(0xae1677d6,0x9d1d0cfe),LL(0x4381a97e,0x641b4256), LL(0xcf4f8245,0x57a2072c),LL(0x24192acf,0xc038aab8),LL(0x6ee05997,0xf708b6d9), + LL(0x82628553,0xd0f52e74),LL(0x96add683,0xd6dfc4ae),LL(0xe70500d4,0x5197189e), LL(0x82ee5eac,0x28fe6d10),LL(0x24145176,0x6c314538),LL(0x7a0ce5ad,0x0b507a03), + LL(0xbf1b56ed,0x28341dba),LL(0x2bd1775a,0xa704c00d),LL(0xcd969de8,0xe8c68f7f), LL(0xad40ac8e,0x64fd4b91),LL(0xfbb5f7b8,0xbc8f2d47),LL(0xb0338932,0x43d6bbe3), + LL(0x81bc04b1,0x72af7125),LL(0x4e2f9274,0x88d535a1),LL(0x3974e880,0xf0578277), LL(0x15b341a6,0x1539a26b),LL(0xb3e593cb,0x603717a3),LL(0x7d61dcd7,0x477f833b), + LL(0x032e59e7,0xee7a6462),LL(0x3532e58d,0x70ac18e5),LL(0x0e36ad7b,0x9382dda0), LL(0xf911a5a7,0xf4c500c9),LL(0x800f8273,0x6d46aa73),LL(0x3e10963e,0x670e4f56), + LL(0x29429437,0x4164dbd4),LL(0x41281f62,0xd9358c9b),LL(0xcbf5eb0a,0x176d1b60), LL(0x2ccdd253,0x3a70e691),LL(0xa25d63e9,0xc53385f2),LL(0x2388d4cf,0xecfe446a), + LL(0xbc93d305,0x5fe1afcf),LL(0xf307c07f,0x59c6b4d8),LL(0xec492ace,0xa805d89d), LL(0x7c31b553,0x572efc64),LL(0xd5bf85fd,0xb15afb14),LL(0xfa431d83,0xb8a6a24c), + LL(0x3057e6e1,0x031dd1e6),LL(0x919f1a50,0xac205cef),LL(0x6bf4b8fe,0x3236d945), LL(0xd11eb95a,0x3cdc048e),LL(0x2b4d6ce2,0xaaa916ac),LL(0x7d395898,0x381aca94), + LL(0x9ec42177,0xc5146299),LL(0x2d66626c,0x6b043df3),LL(0x82ea3769,0x9ed7174d), LL(0x9da03903,0xf8f18beb),LL(0xcd642f4c,0x72c11f7a),LL(0xd4de2f90,0x4bdad457), +}, +/* digit=25 base_pwr=2^175 */ +{ + LL(0x58d3510e,0x5641060f),LL(0x364db85d,0x8e313a7f),LL(0x5cafd58c,0x203122d9), LL(0xccb848a1,0xf79b8cdf),LL(0x67e06429,0xda00c247),LL(0x50dbd8ef,0xe8ddf520), + LL(0xd06db4a0,0x13b4d6c6),LL(0x1c320a37,0x9ca098dd),LL(0x4660ce85,0x23635473), LL(0x70e85a9d,0xcb8bdc7f),LL(0x92b6fa4b,0xd96a49de),LL(0x6f48c32b,0xd22ee1cc), + LL(0x526a7a48,0xbaf0570d),LL(0xfd4d36d1,0x9436cae8),LL(0x24fac988,0x44427e92), LL(0xb39cb050,0x935deddc),LL(0x95237984,0x2db73da9),LL(0xe0403a31,0x6d812614), + LL(0xa4968444,0xf1cb1e84),LL(0x15156d72,0x8624f8a4),LL(0x66276ea6,0x83d9f12a), LL(0x3b28aaa8,0xd15883d2),LL(0x06aba758,0x4043aea5),LL(0x19ad8608,0x3b9cffbe), + LL(0x71c764ac,0x19b195dd),LL(0x16c89a6f,0xb10cdd8e),LL(0xdee07ce5,0x51f783dc), LL(0xbf7febaa,0x05b98ceb),LL(0x0026e40f,0xcbdf20ec),LL(0x8ea46069,0xf4ff428d), + LL(0x19829b4e,0x204f3d40),LL(0xfa6cc5ed,0xd37d49f5),LL(0x07a5325c,0x55bfb8db), LL(0x7c3cffdf,0x349c9305),LL(0x44e85a40,0x15868ca4),LL(0xe664b649,0xab792855), + LL(0xa8931c2a,0x1488def0),LL(0x93e47cf2,0x20b6b035),LL(0xc9c0e09a,0xfd90bf99), LL(0x9e4cf905,0x28fe0815),LL(0x48dbf990,0xf397729a),LL(0xb09e4e66,0x82000550), + LL(0x152fdc18,0x7c7b2c74),LL(0x81529a8b,0x2e09d47c),LL(0xdffec896,0x116d1ef9), LL(0x9ea4077e,0x448891e4),LL(0x9566eb00,0xadad99e4),LL(0x9df75199,0x7d6c3d02), + LL(0x1d7fffc5,0xbc3f75a2),LL(0x741fd001,0x47e4ce19),LL(0x45b7d08c,0x24659725), LL(0xc74dcf3a,0x1a4b43cd),LL(0xdc7dd457,0xa1e3c71d),LL(0xe49194dc,0x37aeb7d2), + LL(0xbe8af7ed,0xf6372965),LL(0x2e04049f,0x4e36da0e),LL(0x34f4f1d8,0xcc4e4c0f), LL(0x387c3ce4,0x185a80da),LL(0xf81efae2,0x999c4880),LL(0xa0cc97d1,0xd2002692), + LL(0x2a469d56,0x97b45c6f),LL(0x4932fa9a,0x0c918aab),LL(0x43aff643,0xc2a2d43e), LL(0x33806c7d,0x685eab5b),LL(0x69645ab9,0xa44c2171),LL(0xa8df46a4,0x128ed8da), + LL(0x650a4592,0x561ca2b2),LL(0x3ca61b0b,0x01673084),LL(0x680d8c8f,0x79ebf7d1), LL(0xc216ae2a,0x33cd5c09),LL(0x260a7797,0xdc44dbeb),LL(0xe5886569,0x80046982), + LL(0x01f3457c,0x6ffe44e9),LL(0xcbd42d4f,0x9f2fb631),LL(0x77426e19,0x372de1ab), LL(0xb5b9cfe8,0xe73bea79),LL(0x105e1632,0xd2af87d0),LL(0x91def158,0x562e0ebb), + LL(0xe8eadc48,0xb3051141),LL(0x214796b8,0xe9797985),LL(0xb0cf5916,0xc7174b9f), LL(0x7c17697a,0xccdaf130),LL(0xe6a3f8cb,0x2ff86ffa),LL(0xe0e4d911,0x655d7ff4), + LL(0x7f8a7546,0xeb590d5a),LL(0xd84598ae,0x2e33657c),LL(0x1cf22291,0x6865f925), LL(0x80d54d83,0xf33b0db7),LL(0xd095724d,0xd2045fa3),LL(0x37a729ca,0x2a65650a), + LL(0x9b7d8eb7,0xe5a6dff7),LL(0xdd67daf1,0x104734b8),LL(0x503bfa5d,0x49050eee), LL(0x49376195,0xa3422472),LL(0xd85aa682,0x9d58a5f9),LL(0x27b209d1,0xef14a582), + LL(0x10c74322,0x72142664),LL(0x161a9f7f,0xed4f37db),LL(0x5f7f95dc,0x0f64b4a6), LL(0x3907231a,0x66c0fe9a),LL(0xc7664836,0xeeadbbaa),LL(0x7907bf1b,0xece73bcd), + LL(0x9c17a6d5,0x16aded71),LL(0x08ca25bb,0x2a92a505),LL(0xe1061e03,0x180b69be), LL(0xd61b7fbe,0xad3ee8dc),LL(0xe5e8b274,0xf8d14495),LL(0x3bb4fd37,0xa5269565), + LL(0xfb62dc03,0x170bf89b),LL(0x18b9c79a,0x1fe9859a),LL(0x839e677b,0x7605d9e1), LL(0xaa1b4663,0x6d265c97),LL(0x48202008,0xb34d878c),LL(0xa03d375a,0x2b696896), + LL(0x166a71cd,0x789e3b3d),LL(0x10983ef5,0xa9f4f3ca),LL(0xdb908c7d,0xf634e8df), LL(0x8192d652,0x0375b69c),LL(0x7e4b6e1c,0x2f5cbad4),LL(0x45be1a16,0x4518ff99), + LL(0x408d39c0,0xb664989d),LL(0x2e4280b7,0xa947849c),LL(0xece6ea89,0xbad0f997), LL(0x3a7571ed,0x434fd6c9),LL(0xcf47df20,0x46da8ae4),LL(0x638076c4,0x7708eff6), + LL(0xc63c8ac2,0x17e1b4e7),LL(0x36830de3,0x0fff916b),LL(0x55092352,0x2fe8eb88), LL(0xd0af6ad5,0x8b72540b),LL(0xf26f7df4,0xf41a415f),LL(0xb3259e07,0xb7be4c73), + LL(0xb3b6ce27,0x4d668949),LL(0xf8705df2,0x332b0818),LL(0x2b168b67,0x11736e3f), LL(0x96ab51a4,0xb7a67c69),LL(0x57e547e7,0x00855b88),LL(0x17aac6bc,0xe9ff07b6), + LL(0x2efd47f8,0xeebd36d2),LL(0x288c8f9e,0x4fe7bc31),LL(0x034e796a,0xe82f1e28), LL(0xf0e8922a,0xd25c0279),LL(0xf0f8dcb2,0x9ec4ded4),LL(0x860e5a78,0xa66ac462), + LL(0xb8a729d3,0xef72f5c5),LL(0x13b9c03c,0xb6915595),LL(0x2ed45b90,0xa4e66b65), LL(0x0845bf8a,0x763c3414),LL(0xac93c4fb,0x13ac686d),LL(0x2095313b,0x923efc3c), + LL(0x3349c905,0xac570164),LL(0x5ca04e5a,0xc85ebcd6),LL(0x6a5d9dc0,0x616a35c7), LL(0x68d2818e,0xfbce6895),LL(0x59769d61,0xd85a342b),LL(0x025ba76e,0x0aa5703c), + LL(0xe391b459,0x205537fb),LL(0x5d410558,0x8d2a3d0b),LL(0x64a2d47d,0x71444a23), LL(0x822b0c30,0x0c86c2f6),LL(0x64c2f548,0x8b276842),LL(0x94dbb24c,0x51a73b54), + LL(0x29e9c4f7,0xf0ead209),LL(0xe1401652,0x5eddd090),LL(0x190c1898,0x6d6b0600), LL(0xef639412,0x762be19e),LL(0xe78dd0d2,0xe322a3e9),LL(0x824c6d20,0xde53b7e9), + LL(0xc90500e8,0xc6b2dd77),LL(0x5a53da9e,0x3a399dc1),LL(0xd09ab46b,0x0969d406), LL(0x249ac549,0x526ec7ed),LL(0x1a09dad3,0x4ae8309f),LL(0xb0c3ad12,0x143165c0), + LL(0x610d6c08,0xd1d7d354),LL(0xd1dbf837,0x12d3da0b),LL(0x01a98f82,0x73fb7218), LL(0xa8666766,0x71fe7d63),LL(0xdc316634,0x74ea9c07),LL(0x55aa5452,0xad9f5798), + LL(0x92ab7a01,0xeb52fc54),LL(0xfa5e4eea,0x6ec23c07),LL(0x01a397ea,0xa9cb3e84), LL(0x69945c66,0xebcac5af),LL(0x3f194ceb,0xdf57e59f),LL(0xa296c88e,0xb5ec451f), + LL(0x794f2a13,0x9cf79425),LL(0x310e1c2d,0xff079313),LL(0x5317d195,0x4d8c0f20), LL(0xf670d56c,0x0d854923),LL(0x31cfadcf,0x7564177d),LL(0x0845bd19,0x67d58b2f), + LL(0x6ce7d0f0,0xed2fd628),LL(0xa2ff8523,0x0a338e2e),LL(0x6968e5ed,0x4cd9123a), LL(0xf2f06ab4,0x14edcc8f),LL(0x6e52fb45,0x23c39e14),LL(0x41a9c448,0x529a89d3), + LL(0xfa8c503f,0x436e8ebc),LL(0xc7ec91f5,0x2d692350),LL(0x2f6a42f3,0xe847216b), LL(0xa68613e7,0xe12297b3),LL(0x10dbc984,0x16e343fb),LL(0x16d59123,0x7dbec088), + LL(0xd64ff51c,0xf3e6abe1),LL(0xd3afe2c2,0x87accfb2),LL(0x4dba0813,0x57b5f905), LL(0xb3b8c3fe,0x17038f08),LL(0x247ea7e7,0xfe435876),LL(0xa6d8a7a0,0x61415630), + LL(0x72efb994,0x685e474d),LL(0x495c513e,0x05b09ce3),LL(0x36da77db,0xf03f489e), LL(0xd1920e81,0x5bce5842),LL(0x4ba12592,0xc3fe249f),LL(0x0a5eed91,0x9671b08a), + LL(0xaac51e01,0x387fcc9a),LL(0x9c3e2419,0xf8c9ecb3),LL(0x754e0ecb,0x1017d74c), LL(0x9a76367c,0xb1528d0c),LL(0xa2e5c47a,0x4dcd49c1),LL(0x3751eba3,0x7b635160), + LL(0xae011f19,0x3879777a),LL(0xf839016e,0x6a63aafe),LL(0xe3944a17,0x199a76e4), LL(0xb399afa0,0xa0455c72),LL(0xf9479065,0x95450e12),LL(0x82b89c67,0x90479fcb), + LL(0xe392cb40,0xdc585a30),LL(0xafe2f1cd,0xbd161799),LL(0xaf671659,0xf0794ecb), LL(0x3e558726,0x7144b4e9),LL(0x0e8fb051,0x61aa80d1),LL(0x0a97d49b,0xd2a41b0b), + LL(0x0a74e744,0x10f7c811),LL(0x96ab89c0,0xdd94a330),LL(0x53525096,0xb617d078), LL(0xcfdfa40c,0x2e5b46f0),LL(0xcedc53d0,0x6edea8ab),LL(0x6399837f,0xaee682f0), + LL(0xf2adc050,0x398c7fd2),LL(0xc7638b0a,0x1030cdae),LL(0x8867f1d6,0x1cd2be4b), LL(0x1ba68d19,0x2f97a204),LL(0x18cd2ec7,0x47f3b28a),LL(0x8e77c014,0xf164c987), + LL(0xc33772e4,0x8489b718),LL(0x2f4128d3,0x08ac1911),LL(0xda0369a0,0x8370f1f5), LL(0xf1d75833,0x50ff1409),LL(0x0f83a8e7,0xa314c13c),LL(0x5a766258,0x776de80d), + LL(0x77ba6858,0xffe94ccf),LL(0xcc2a35c8,0x1b87cbeb),LL(0x57a1fa64,0xd5528288), LL(0x5937abfc,0x2e32d797),LL(0x284ca1f0,0x89a76fe3),LL(0x482441bc,0xdbeb8eda), + LL(0x397926fd,0x6bd5d9e9),LL(0xf5fbd488,0x3e97744f),LL(0x4ff64738,0x020f694d), LL(0x968aa895,0x34b3915d),LL(0xb88572cd,0x60b03cd4),LL(0x67dcf49f,0x0cd44b01), + LL(0xac9b8b5f,0xc6f1228c),LL(0x7822905f,0x5f49fb8e),LL(0x950e82e9,0xa61a8520), LL(0x6f44f547,0xec78c658),LL(0xaa640c3e,0x86d54b78),LL(0x54c16691,0xf6aab7a4), + LL(0x44fbab19,0x0cae07b3),LL(0xcc4d821d,0x61e61d3c),LL(0x5beae87e,0x5c2ff6ed), LL(0x9ba67712,0x719d81cf),LL(0xcb1e1329,0x8fb7e1c8),LL(0x32f7e9b7,0x82a0507a), + LL(0x0d8af7c0,0x94bf5956),LL(0x3dde66aa,0xeb94e708),LL(0xcc491968,0x2924bca4), LL(0x1bae682d,0x348c6486),LL(0x0da0931b,0x5490288c),LL(0xa923db17,0x79cae045), + LL(0x4ed8cc93,0x99ae0e06),LL(0x1f211af5,0xe0dca803),LL(0x54413c07,0x3e0da321), LL(0xd2e5771c,0x11bf91ee),LL(0x5d9efe6d,0xde57fde7),LL(0x2bae2eca,0x140cd249), + LL(0xebe25fb3,0x8c25772c),LL(0x5ae86876,0x9ebd7151),LL(0x227c8fc6,0x9e01abfa), LL(0xe8279d68,0x10316800),LL(0xa07da963,0x394a6fff),LL(0xc8b9c7e0,0xd8316e12), + LL(0x4866b100,0xe34a3346),LL(0x64640c51,0xbe82e03e),LL(0x8c26b45a,0x2228e85c), LL(0xaaec11b1,0x4f53739a),LL(0xed773bc3,0xedcebe7c),LL(0xfcef0ce2,0xfee917ad), + LL(0x44c7c595,0xdf6dca1f),LL(0x374d0d04,0x421ac2e7),LL(0x9e3ed6ef,0x842f0ded), LL(0xe9dcc612,0x0e20b04a),LL(0x2040e59d,0xbe403a6f),LL(0x8611c050,0x0ed4eb43), + LL(0x559e8de2,0x8479f4bf),LL(0x851f7b34,0xb12ebeb5),LL(0x3a3d71ea,0xc34bfd18), LL(0x24e9273c,0x56d9d399),LL(0xb9f63b13,0x7f404c7f),LL(0xe50afb2d,0x9b679748), + LL(0x09f98b35,0x9be55951),LL(0xff869a57,0xde925893),LL(0x21a9054e,0x387f817a), LL(0x70ee95b2,0x1e674786),LL(0x36b7d89e,0x628421b4),LL(0xe95fc254,0x5c66493f), + LL(0x3f27517a,0x68f7f079),LL(0xa2634bb9,0x44e0f99f),LL(0xc49ed6bb,0xff40ec9d), LL(0xd4c15f22,0x308b3e76),LL(0xddaa3039,0xb3f77d17),LL(0x7ea641c5,0x3dc87e6e), + LL(0x004a3af7,0x8d01afc4),LL(0x5cb71d7c,0x118e5970),LL(0x48ba3691,0x4facd336), LL(0xa796a7d3,0x30530fed),LL(0xcc7913f8,0x437ad3b9),LL(0x8adebd12,0xe0c151c6), + LL(0x2e553c5f,0xf37ea5cf),LL(0x45ebc28e,0xd35512e6),LL(0x05331492,0xd4f2b6b1), LL(0xaba58423,0x0ab0b63f),LL(0xd8791541,0x0c6d3499),LL(0x81abb7ed,0xc911fda1), + LL(0x53f134aa,0x4316e48a),LL(0x492e43e8,0xc26f2068),LL(0x126d373f,0xaea01397), LL(0x37d4baed,0xdfb016dc),LL(0x68550352,0x70fd4cd9),LL(0x90c02756,0x82a6c302), + LL(0x66cf543d,0xbbfbd662),LL(0x9f372f9c,0x9198ae05),LL(0x0d3c6392,0x548bc0b0), LL(0x71100572,0x5e227e8c),LL(0x189496d9,0xbd10e2ef),LL(0xb6a6798f,0x66b7ddd2), + LL(0x1d9b4627,0xdbfa89d2),LL(0xe9722687,0xa4144f05),LL(0x62a9f0b3,0xa03a6658), LL(0x09a6ee11,0x11e24e34),LL(0x610d808b,0x02a2f96d),LL(0xb68d12eb,0x3434da69), + LL(0x420733a0,0x224f3f9b),LL(0x99244104,0xa3f7e5c2),LL(0x9dd4dd08,0x2018ee4f), LL(0x230f84ef,0xb993d248),LL(0x69d385df,0xbb1c8f5b),LL(0xddffd0f2,0x9242e20a), + LL(0x09654b6a,0x6d842a62),LL(0xfe652314,0x2f79695e),LL(0x193c89e2,0x0c65ea9f), LL(0x6b79b085,0x009cf4f9),LL(0x2268da91,0x390256cc),LL(0xb23a9a13,0x9a5602a1), + LL(0xc087ed5f,0x7e6b4f66),LL(0xa1c63549,0x14a8e4d1),LL(0xfed4b006,0x01ca8c96), LL(0x6933bc42,0x1f5e13f7),LL(0xcc727c9e,0xd642cd3f),LL(0xa4a52672,0x60a81922), + LL(0xcb37c6b1,0x21d4016a),LL(0x6aaea4e2,0xbf9c3ad6),LL(0x4d227e29,0x9bd42e82), LL(0x66fe8ded,0x7b43dfb3),LL(0x4f6d7cab,0xccc64f49),LL(0x709cf722,0x9fb84f64), + LL(0x99a34b60,0x657bba39),LL(0x5bf3ff4c,0x54c86454),LL(0x6a3fc2c9,0x91cab991), LL(0x9d937181,0xad3baab9),LL(0xa318a96e,0x9b39648e),LL(0xd5a8dd54,0x416fe984), +}, +/* digit=26 base_pwr=2^182 */ +{ + LL(0x10e89d46,0xa5d2d3fc),LL(0x267decf4,0x426ccb6f),LL(0xf65161a7,0xc430a435), LL(0x45ff08ed,0xf32e4fd9),LL(0x52fce424,0x29bd88e4),LL(0x7df49592,0xb58dca75), + LL(0x2de63b4f,0x08b2eb9d),LL(0xc5a70a53,0x2dd60214),LL(0x183b9f0a,0x8bf59ae3), LL(0xa4d75e6a,0x127db136),LL(0x2dd19a85,0x70a4c22d),LL(0x6bb9e133,0xa04ca68b), + LL(0x1e0ac0de,0x7c1f8f54),LL(0xcc70b75d,0x33fa9eda),LL(0x1661ad09,0x190f2578), LL(0xc6af0599,0xc8d29939),LL(0xd76f1d21,0x8f0f6073),LL(0x28d0432c,0xda9f9fbc), + LL(0x9c65f79d,0xa73ce4f4),LL(0xcb12b4d2,0x81728494),LL(0x34a30e52,0xb3709952), LL(0xcc5be142,0x34e61905),LL(0x0d1b9183,0x0237c5ce),LL(0x51d9f58a,0xcd502078), + LL(0xb77a9580,0x5935c009),LL(0x60590762,0x109f262c),LL(0xa9bef637,0x40cd7b02), LL(0xe1e887cb,0xbcf02172),LL(0x22fc3d18,0x23ab267e),LL(0x2b110de6,0xbb9632d8), + LL(0x1e71e027,0x939849be),LL(0x0916d6dc,0x04493ee8),LL(0x7a4c25ff,0x2456a4fa), LL(0x80e2c3af,0xbd7a130d),LL(0x19ebceb4,0x63b50b49),LL(0xca679a32,0xcf3af9f6), + LL(0x568806a1,0x8bf5ebcd),LL(0xd6906912,0x9d9e980d),LL(0x2224ffdf,0xbc01567e), LL(0x9b382f20,0xec45fad8),LL(0x2ae9b081,0xc81ce8e7),LL(0x98932797,0xe492d96d), + LL(0x29a231ea,0x5d2a1162),LL(0x59e196df,0xa3a8d097),LL(0x7f4b3fb1,0xe049a755), LL(0xc6316d29,0x5a3a8033),LL(0x927eae96,0xcfa30505),LL(0xbe935448,0x08b8a76c), + LL(0xedc1da3d,0xae5b906d),LL(0xe511be7d,0x7e4c4f50),LL(0xbf36de87,0x8d50de21), LL(0x0ed128b9,0xa3e529b5),LL(0x39d260df,0x902d56ab),LL(0x5e3d15b3,0xaafa263e), + LL(0x0e6cecf4,0x201392c1),LL(0x49f3f177,0xf3e51d03),LL(0xcb103c3c,0xa778f941), LL(0x7666e871,0x663a85f9),LL(0x67c98f13,0xa46b0c85),LL(0x3d7ea941,0x3419ecca), + LL(0x0cd251b9,0x6e9c319c),LL(0x740ebef4,0xe03a5e58),LL(0xeb45dea1,0xef0db2a0), LL(0xe6e4e097,0x12e7626f),LL(0x19914347,0x27cfc38c),LL(0x6046e4f4,0x92b17248), + LL(0xfd260bad,0xad9a809e),LL(0x84cf1f3c,0x0faa61f5),LL(0x6afd71d3,0x7b60a72c), LL(0xd1fd427b,0x67f98a21),LL(0x45809f86,0x55e94be4),LL(0x8e08a8fc,0x55f38c03), + LL(0x78ac4a59,0xe1bd82eb),LL(0x80599bf6,0xc195517f),LL(0xcba34b90,0xd57d73bd), LL(0x68e80682,0x70b22ccf),LL(0xfbe46433,0x9ef082ba),LL(0x4e1de964,0x0e3b2665), + LL(0x629523a0,0x40c1bd3d),LL(0xb3c7fa46,0x55c4d1e4),LL(0xc3ac04c5,0xe731d1dd), LL(0xb98ea38f,0xee1fa82d),LL(0xc3da8420,0x2a53d82c),LL(0xf22acfea,0x368c36c9), + LL(0x29b755d0,0x0266ab97),LL(0xcd211255,0xf06c3dd8),LL(0xda4b92c3,0x815c935c), LL(0x7c35910f,0xc8b3d452),LL(0xe14a590c,0x0f3aed26),LL(0x8e1ce1c0,0xf6ecbf3a), + LL(0x574f2fbb,0x552b5d7a),LL(0x8de8d85f,0xfa3986c3),LL(0x9614d372,0xaa53bc82), LL(0xc58f40f9,0x1118e769),LL(0xe3a00d02,0xa39c3653),LL(0x92267b25,0xb0de6989), + LL(0xc7b64858,0xa306b7c8),LL(0xb64b2f3b,0xf22489d0),LL(0x277347b5,0xb4d82d56), LL(0xb3c23db8,0xc6120600),LL(0xeb1d672f,0xdd104bc6),LL(0x91821d86,0xf46c3e19), + LL(0x182aa649,0xbd1809b8),LL(0x9def0d8a,0xa14bcb07),LL(0x150bc2b2,0xbc355f52), LL(0x303a6966,0x9b74419e),LL(0xeb2b3cb5,0xf922f6bf),LL(0x18f7ca08,0x5d7aa60c), + LL(0x0be5968b,0x42346530),LL(0x2a740a40,0xe0a37f25),LL(0xe665427d,0x03bd64c1), LL(0xe4074164,0xe3911c26),LL(0x7960eb4e,0xc9770b1c),LL(0x5c67feb2,0xbe470d6d), + LL(0x3894d144,0x3b30ad55),LL(0x16768125,0x51da7959),LL(0xbed864b3,0xe8cfebda), LL(0x833b7cb3,0x49a98925),LL(0x6f174ec4,0x830c736e),LL(0xcda2e7e0,0xf9efa80a), + LL(0x376e70ba,0x01f86bbf),LL(0x0eddf0bb,0x686b6cb6),LL(0x64d59f33,0xdc9eec10), LL(0xa46828be,0xdb7037cf),LL(0xd2c7ca5a,0xceeb8c28),LL(0xe6196bda,0xe40cbf09), + LL(0x8bd42f71,0x0ac2d045),LL(0xb62d83fe,0xd4215f7e),LL(0x03acf7bd,0xaab77a58), LL(0xc2eeb2e0,0x7e1aa3e8),LL(0xd86c3480,0x16dbe858),LL(0x8a7fb0b3,0x65a386cd), + LL(0x8894f88b,0xc426e3e1),LL(0x4593936f,0xa748da73),LL(0xca40633d,0x9e640d2a), LL(0x02ac44dc,0x84fd2be4),LL(0xd437cf7f,0x0471f362),LL(0x7306c123,0x8f4155e7), + LL(0x21dd0f82,0xc9871691),LL(0x28d633a3,0x2bd96ea5),LL(0xfc2ba2af,0x1906ae24), LL(0x1ee92586,0x2b4efac7),LL(0xf7f07861,0x4b97cbfa),LL(0xf7281f7e,0x4dbf54e2), + LL(0x25b5b11c,0xc39fffbf),LL(0x98a6b660,0x41973093),LL(0x0f7b07f8,0xd02dcfda), LL(0xfacfc8d6,0x42bd5635),LL(0xfa119a0d,0x49c754a0),LL(0x7a67703b,0xf3900a31), + LL(0xb7648cd6,0xffe76894),LL(0x973e597b,0xa790612b),LL(0xd6d78341,0x5a817ff0), LL(0xc9960802,0xe4a6c1a8),LL(0x6884bf58,0xa296fc0a),LL(0xcaee199c,0x8387842f), + LL(0x78a21751,0x505a5fbc),LL(0x04338ed3,0x8d557dd4),LL(0xf8316933,0xc6daa6eb), LL(0x9fbe57c9,0xce8b52fc),LL(0x82ffca53,0x93375f08),LL(0xe48a4172,0xd2e09822), + LL(0x2d8b1f67,0x59d6d11a),LL(0xf984b355,0x3df9851e),LL(0xeef602c2,0xfad1f4e1), LL(0x1df4b332,0x6c07fd2b),LL(0x0a339f9f,0x1672e0ae),LL(0x3e2e73f1,0xa7aac7c0), + LL(0x53de8d30,0xd015e91f),LL(0xdeee9e90,0x9cef3987),LL(0x9b54ea0f,0xcae1fbee), LL(0x0b2e4bfc,0x5541f0dd),LL(0x00c1a228,0x15f9dffc),LL(0xd9dfb7f7,0xeed05a2b), + LL(0xf8bcb7fb,0xbeb350fb),LL(0x3fb74891,0xa6a2efe1),LL(0x4216f4a5,0x1cfaf6a0), LL(0xccd45bce,0xd268b24b),LL(0xe3db6dfa,0x5c85e954),LL(0xf04e8161,0x127ce38c), + LL(0xfc6c17ef,0x749016b3),LL(0xc849c80f,0x840e079d),LL(0x55aebfa6,0xef3493b4), LL(0xbdddb794,0x5645586b),LL(0x0a0da6a8,0x1e1ddb6d),LL(0x33397277,0xbd31053b), + LL(0x257efe71,0x64c4bcd5),LL(0xf7abc98c,0xd35b6fad),LL(0x49479a50,0x3b0df461), LL(0x0c01f68e,0x7aa9ea28),LL(0xfc247d85,0xa37c8d40),LL(0x82d5d062,0x4214db8f), + LL(0xd4665035,0x615f976f),LL(0xb2fd9161,0x39f27e8e),LL(0xce638414,0xa1ae7fee), LL(0xbee083df,0x0717218c),LL(0x80a73a7f,0x66d2bccf),LL(0x77555a78,0xc1cfe44c), + LL(0x151f9185,0xab6467ac),LL(0x25664569,0x6df53a18),LL(0x466dd4b8,0xa54fbfd4), LL(0x8b3c8dc6,0x6f063338),LL(0x41623458,0x64adde6f),LL(0x112ad869,0x08056bf1), + LL(0x3434a31e,0xfdd32b7a),LL(0x04cdeecc,0x5728361d),LL(0x3a7b8da1,0x2aa81490), LL(0x09a2731d,0x87c2d7d2),LL(0x89ebca03,0x1f3344b9),LL(0x19158d11,0x3b4eb6aa), + LL(0x4aea58b5,0xc2bc01be),LL(0x19f12b28,0xf7d53cd7),LL(0xdf3da230,0x475fcd61), LL(0x09990316,0xeb3dd742),LL(0x28ea4a85,0xb1c62ec2),LL(0x71770efc,0xd9ca3e02), + LL(0x285cb4ae,0x92099143),LL(0x0d8f3f4f,0xfac421c8),LL(0x31e4afb4,0xb20b6d02), LL(0x41735275,0xb896f118),LL(0xe7a40b45,0x9f8d1d92),LL(0xc574911e,0x578117a2), + LL(0xc8ab5906,0xe049b850),LL(0x90ebe14c,0x3dc8761d),LL(0x3d9b21b1,0x01b959ad), LL(0xa1be26d8,0x69e0edfb),LL(0x90bffa45,0x23061d51),LL(0x5432258c,0x12c49398), + LL(0xec1ab63d,0xcf6318e5),LL(0x78baa5c1,0xfabf5dcc),LL(0x6529af85,0x6fe5da1b), LL(0x0d696bed,0xc02b8cbe),LL(0xc83d0478,0x5865de25),LL(0xf422a123,0xaef1328d), + LL(0x700b22a4,0x0895f5d0),LL(0xf78d8bb2,0xb52e7e2d),LL(0xe0972d87,0x5771d2c8), LL(0xa67e68d5,0x45181514),LL(0x29446b80,0x11ad6a2c),LL(0x3c18bc56,0x17b2b4e7), + LL(0x075ee3b2,0x3d4755d1),LL(0x0fcec9d9,0x1505789c),LL(0x398f0c91,0x6e00b31e), LL(0x57048d0c,0x54cea710),LL(0x6443fcff,0xf40ba9be),LL(0x05b2a1b2,0x04075b8f), + LL(0xf3aa488f,0xcb23f2f6),LL(0xb3aa9bab,0xd48b8a3e),LL(0xa8b58c26,0xe1dfa993), LL(0x58d04b7c,0xe2641538),LL(0x32ad4a3c,0x1159caa2),LL(0x00256f11,0xa19210d5), + LL(0xeb897a63,0x52787df1),LL(0x3afae814,0xe4f787d2),LL(0x9a665638,0x3c391a2a), LL(0x49d18f8c,0xa7cbf5cb),LL(0xd351d0bd,0xb159a6c2),LL(0x57b9faae,0xe501bee6), + LL(0x7ffa6fb7,0xfd21c745),LL(0x6eb966ff,0x9f082577),LL(0x6cf4bbb6,0x7bc7fd6a), LL(0xadae7e60,0x01fbbec5),LL(0xdb5201fd,0x8ede95fa),LL(0x505dc527,0xfe027d78), + LL(0x4ab8d622,0x556427f0),LL(0x2d8a1b65,0xac06be29),LL(0xc1517a5a,0x24ffe89e), LL(0xbb687bbe,0x8ed6619f),LL(0x5e6229f5,0xc391ab29),LL(0x6668e363,0xc6accdea), + LL(0x2236abab,0xaa1a8aae),LL(0xbbbb5c34,0x7ff0f90e),LL(0xcdbbe595,0x342421e1), LL(0x158fa276,0x3a43eb45),LL(0xb1c8d9e2,0x3f206b59),LL(0xd1fb731b,0x926495ee), + LL(0x772ae335,0x64dee795),LL(0x27bb58cf,0x5536e14e),LL(0x68065d10,0x559824cb), LL(0x5fca59f5,0x6780d28c),LL(0xc5672db7,0xb1f51778),LL(0xe64c87fb,0xc295e9dc), + LL(0x6a759ba8,0x43aa71ca),LL(0xed6e67a5,0x296cde1c),LL(0x2481f6c7,0x97eff2f8), LL(0xee4bf211,0x311c89d7),LL(0x20c5e8fb,0xa03cf7db),LL(0xa30c9a13,0xf181425c), + LL(0xef8041bd,0xe9164a69),LL(0xf14e75d4,0x10616709),LL(0x31432c48,0x3d0fda80), LL(0xedfce733,0xff34f02e),LL(0x97785106,0x47e53d79),LL(0x0c42b429,0xb73df841), + LL(0x16d00d56,0x430590ae),LL(0x0b6db145,0xb36bf8a4),LL(0x631b8af0,0xf0fbf1b8), LL(0x7c97735a,0xd285813a),LL(0x233bbcb4,0x3be81538),LL(0xece4421e,0x5dce4f9e), + LL(0x115acbd2,0xdf3aafe8),LL(0x4e168fd2,0x01352bc5),LL(0xafcfd633,0x7948b02b), LL(0x559eebfe,0xd8976862),LL(0x8de4fafd,0x752a202a),LL(0x47600461,0xf9964960), + LL(0x45629c12,0xd8e2a4f5),LL(0x0e8d9c56,0x53d8b1f9),LL(0xce8a7e4b,0x69f85fa3), LL(0x50234689,0x78e35e04),LL(0x8ffbcfd7,0xe0274e82),LL(0x0c75b636,0x3bed2d8f), + LL(0x373fcc37,0x5ad6f7e7),LL(0x347b8ead,0x3ae4bbd9),LL(0xdf9414dd,0x3ef24805), LL(0xed9355e0,0x5d655d51),LL(0x12d96970,0x93e831a1),LL(0xa1cc5116,0x9d02f97d), + LL(0xc8216057,0xad5bc00d),LL(0xa7efc99a,0x7aa8806c),LL(0x63fe1b91,0x1abc67a2), LL(0xe3315539,0xdcef61b3),LL(0xbd3f1ea2,0x31a563f8),LL(0xb76036c6,0x86e84857), + LL(0xc967c01d,0x22a2bca9),LL(0x6184d879,0x15300b29),LL(0x24018b6c,0xcb4eece3), LL(0x4bebca46,0xee715ca1),LL(0x0bbbd9c5,0x8d9daf6a),LL(0xd918c1bd,0x683a7647), + LL(0x53eb0ffd,0xeda60e7d),LL(0x71a51e14,0x537aefa1),LL(0xcd7ff005,0x7927da15), LL(0xf7f04011,0x6191e2df),LL(0x4bba4547,0x7bedb9cb),LL(0x89b2a74a,0xa50562a9), + LL(0x606c84ad,0x17eb0b47),LL(0x7c97dbb9,0xab88aa51),LL(0xd1818d8b,0x07ea03ae), LL(0x9374b72b,0xf73e2f04),LL(0x86858702,0xcb29129c),LL(0x98608a71,0x3620afda), + LL(0x716a5874,0xb810b51e),LL(0xa889add3,0x9ec17162),LL(0x19089d83,0xfd276227), LL(0xbb1c7343,0x063aee05),LL(0xe784bbe9,0x87cb9fc6),LL(0xd7489e40,0x782d098e), + LL(0x8f090898,0x7c43b0a9),LL(0xbdca71ed,0xf8f3b085),LL(0x3f9f4e6e,0xc9b19fd1), LL(0xc47961e6,0x6e42f7f0),LL(0x31020f60,0x45aaf72a),LL(0x2550f424,0x661616e1), + LL(0x20db7e4a,0xb16f561f),LL(0xa4281dd3,0x83f2a22b),LL(0x43f5d715,0x31f11530), LL(0x1a9f9532,0xbb3cc73e),LL(0xf1fe503c,0xe86e672b),LL(0x6997be05,0xf4c9b96c), + LL(0xe3cb641a,0x4b0bb45e),LL(0xb5ddb389,0x741adc8d),LL(0xbc920f0d,0xd87c5699), LL(0x15b6ef33,0x55bcf8a4),LL(0x1245ec9c,0x68eb1b09),LL(0x4c03f712,0x7b692b42), + LL(0x829adb45,0x835194bf),LL(0xe4bd2b50,0x5f3fed6a),LL(0xfffe5c2e,0x32e24c5e), LL(0xb9a052b8,0xed361d44),LL(0x0b43353b,0x512fea09),LL(0xd5a71bbb,0x1d35cd1f), + LL(0x05b5e6d9,0xba48388b),LL(0x3b0b203b,0x07136b21),LL(0x765b8607,0x8ab4af31), LL(0x74816f5a,0x5107c05c),LL(0x4a5d27b7,0x8d7cfad6),LL(0xd9c2aa8d,0xbc507c9c), + LL(0x467fe1f2,0x6ed919c9),LL(0xfb1bf823,0x9a75c404),LL(0xfefebd90,0x5eff17b8), LL(0x521a3668,0xa8b6ed77),LL(0x251c6e8c,0x0f8b8ae7),LL(0x631669c0,0xe45c3453), +}, +/* digit=27 base_pwr=2^189 */ +{ + LL(0x65fd193b,0x443763e3),LL(0x98d2ccd9,0x23523a88),LL(0xff0d967e,0x0a6f8f92), LL(0x009db3b0,0x1263e468),LL(0xbd562f47,0xee4dc8c1),LL(0xafc849c5,0x76f03c5c), + LL(0x99bd9bfe,0x8d976c26),LL(0x58ed4760,0xb19a85a7),LL(0x1e34868e,0x13dca814), LL(0x54cc6d8a,0x056e40ad),LL(0x8fcf3241,0x861dc2cf),LL(0xd3afc6cd,0xa6a8a21d), + LL(0x7b77442c,0xe6eeae3d),LL(0x8aa82aef,0x057453a1),LL(0x9a9a0869,0x5a1dd863), LL(0x8372157f,0x15b34a60),LL(0x892b8e9a,0xc35f2257),LL(0xcdd030f9,0x0476b29a), + LL(0x490b43e5,0x1f623ab9),LL(0x6d3b5faa,0x0fb153e0),LL(0x126be417,0x11ecf7af), LL(0xf9d44cdb,0xc5588fe3),LL(0x80576c99,0x93bd13f4),LL(0xf7cca387,0x458f50aa), + LL(0x05cadd86,0x33e0840f),LL(0x1288d2ab,0xa4ceb96c),LL(0x2574cecd,0xf18de0a1), LL(0xbd606235,0xb1eecb58),LL(0x243a5639,0x46f1c0e3),LL(0x2f8617f4,0xfbf9ada6), + LL(0xfdc33e8a,0x29778c36),LL(0x7c7a4b81,0xe96d19b3),LL(0x87bd6ef2,0x011f2a94), LL(0x7b36e1c8,0xd84b0388),LL(0x6e6d91ea,0x5f21366d),LL(0x670039fe,0x0c884a47), + LL(0x5485e744,0xdff19ddb),LL(0x826523ab,0xb626116c),LL(0x10d50cd3,0x2f4f0fd8), LL(0x24125350,0x5dfd1acb),LL(0x53f2ab5e,0x09c128b0),LL(0x4f9b2256,0x9f940ced), + LL(0x917ef295,0x347c7bb6),LL(0xe7525a0c,0x3578fbbf),LL(0xdaade6c5,0xd64bdb43), LL(0xeff35295,0xdb9014a1),LL(0x8bd89301,0x1c18a193),LL(0x8573ec51,0xccd8059d), + LL(0xff89a745,0xd263620d),LL(0x8b578c94,0x485093e4),LL(0x831165c3,0x6cc8df06), LL(0x72a1e4bb,0x623c1f86),LL(0x1ae4359b,0x1857c157),LL(0xf8c83db9,0x51252b88), + LL(0xf3eaa85f,0x75c0f153),LL(0x296331ba,0x8524e8a3),LL(0xf153b5e3,0xbdfb652d), LL(0xf3645389,0x650adac3),LL(0xe5150ccd,0x59382d93),LL(0x40e57d00,0xf3310865), + LL(0x3135c8cc,0x43c89d80),LL(0x8ef6e51f,0x5f0b989e),LL(0xe67cd4d4,0xc6b0f722), LL(0x2433fada,0x35eb83b7),LL(0x688247c4,0xb18db37b),LL(0x51703d00,0x0a444f19), + LL(0x57840670,0x8361e5ab),LL(0x42af05a2,0x4f46eb2d),LL(0x4520d223,0x34632e05), LL(0x66bdbe8a,0x4aa80691),LL(0xb5742363,0x467d5d3a),LL(0x0894ba88,0x5af9783e), + LL(0x0cb7f96b,0x84644ff9),LL(0x522d6aaf,0x0ae33ac3),LL(0x2cc8944b,0x017c4b01), LL(0x6a2ddda6,0x9923bca6),LL(0x8c9b621e,0x6627fcc2),LL(0x17bdfa4f,0xa29f1b1e), + LL(0x1cad89b6,0x534ff925),LL(0xc2042459,0x0863e52b),LL(0xaf25d3a6,0x5306b082), LL(0xbbbd9f5b,0xabb1a0b0),LL(0xb65cde23,0x7e3bd9f2),LL(0xc228a0ec,0x001c50b1), + LL(0xb9339a10,0x86cb78d0),LL(0x1caa6cdf,0xa4b51028),LL(0x21d335bb,0xc52bad81), LL(0xc2fe7de5,0x4301dba7),LL(0x7d6b198e,0xc7b39fd3),LL(0x2a96f21b,0x28e0fdea), + LL(0xbabe8679,0x59373e25),LL(0x9fd9ed30,0xd44cef09),LL(0x58210099,0xfafb37c0), LL(0x1174c9f1,0x19aea5a6),LL(0xaa0d14c2,0x95527d4f),LL(0xabaf1d12,0x3f19e7e2), + LL(0xcb8a82f6,0xe6d77312),LL(0x63ded2df,0x1e5c2945),LL(0xa2eb913f,0xe6eba908), LL(0xd2a8cdaf,0xe7a562f9),LL(0xa209420a,0xc659bdc9),LL(0xc59d4edf,0x9d016dd4), + LL(0x74da1b13,0x4bdd6da2),LL(0xe9df9fa8,0xcdee393f),LL(0x2e6bac46,0x64890274), LL(0xb2d61427,0x8843a6bd),LL(0x6efc5b51,0xfd6c2073),LL(0x035128e4,0x12029497), + LL(0xbe06abde,0x680d1bf9),LL(0x452f6c1c,0xb37decb2),LL(0x6ec32edc,0x981e840c), LL(0x84360e72,0xd5257167),LL(0x18300091,0x558abf57),LL(0x72ecaad4,0x3a7b592d), + LL(0xf7312883,0xcdc53ab7),LL(0x0571634d,0x69af637c),LL(0xc7cc70ca,0xec10a5e8), LL(0x424399ce,0xa90c48d4),LL(0x341ddfbc,0xe05856ae),LL(0xd3e4c39c,0x3a1976b2), + LL(0x90220209,0x9ed5893d),LL(0x81b6ced6,0x45ae0a2a),LL(0x546a8d70,0xe929ce12), LL(0x455cdddf,0x267c3d5b),LL(0xcea5169b,0x4d9fa92f),LL(0xe94a3b42,0xb925af46), + LL(0xe118cce2,0xe404af85),LL(0x8fc5766e,0xd5a91ab7),LL(0x5e924307,0x71c251eb), LL(0xf7a25052,0xe3cb6d55),LL(0x18b850c9,0x968fed5f),LL(0x2174cb4b,0x623893ba), + LL(0xd3d0e873,0x67d096e1),LL(0x2541a85b,0x4487615c),LL(0xfa518d4c,0xe87a5c0f), LL(0x8371fee6,0xb0b2a717),LL(0xf0d1d1fa,0x0c2e5455),LL(0x11189a5d,0x42cf786c), + LL(0x0075ca1a,0x6477d9cb),LL(0x0bada61a,0xff28d896),LL(0x7d671caf,0xea81a421), LL(0xe5e640ea,0x40762d23),LL(0xd43891af,0xfda94df7),LL(0x527b4662,0x6349fb9b), + LL(0x3b2603b3,0x3b5ff95f),LL(0xf23c44e6,0x6b633ea1),LL(0xe90ab3cb,0xb54db154), LL(0x37f6bcde,0xa92deb1d),LL(0x4eb88b8c,0x7b328bf5),LL(0xde5545e4,0x4ce336ee), + LL(0x1750434d,0x072846ed),LL(0xef744765,0xef46faee),LL(0xf439980c,0x7a858840), LL(0x6aecf70c,0xec75222e),LL(0x1a4ef06e,0x2ece8f59),LL(0x3d233bad,0x82784973), + LL(0x3b3b6956,0xaee6f0e5),LL(0xf4eb1f77,0x04ceab91),LL(0xdcbb09d4,0xc6977800), LL(0xc8203c8b,0x8948d95e),LL(0x4f31a369,0xa354e6e3),LL(0x42785a63,0x10e7ebf6), + LL(0x426a2da6,0x5c233e59),LL(0x5aff8031,0xfc7c21ac),LL(0xae2b7618,0x713ae9f6), LL(0x8ffa178c,0x958babfe),LL(0x404c1ece,0xb21fe414),LL(0x1e4f7c28,0x1fd8cf6a), + LL(0x482a1f04,0xb68bc919),LL(0xfbee302f,0x7ff1f4be),LL(0x6f98c545,0x5d510b76), LL(0x04a84a52,0x0a54942b),LL(0x8d306d4d,0xdc70958c),LL(0x638a365c,0xd5564cd0), + LL(0x295ed5b7,0x7275aaed),LL(0xa7a642b1,0xc6c05b8a),LL(0xa499ac12,0x5572818c), LL(0x038c961d,0xdf0a6fa3),LL(0x798ec56d,0x7ed5630f),LL(0x4acc0009,0x206c39e3), + LL(0x63cc9e62,0xc371e275),LL(0x6e06e663,0x425ae991),LL(0x155a4978,0xa2aa623a), LL(0x82b7846e,0x021e0916),LL(0x07ccc4b1,0x0500f013),LL(0x891bba46,0xd62661e5), + LL(0xd612756b,0x38909c56),LL(0x090f7ae5,0xd362d7a3),LL(0x9a871772,0xaf3ba39c), LL(0x575c94d9,0x28dfce6b),LL(0xfaf575ae,0xb556c52c),LL(0x710956bf,0x6c0131b7), + LL(0x071961ab,0x33ce3aed),LL(0x69b35991,0x226aa630),LL(0x2398b3af,0xc42f173d), LL(0xfc2e6625,0x5d4d9cca),LL(0x4790b7b4,0x767e6911),LL(0x184e1458,0x81a0782f), + LL(0x4a451326,0x77aab96a),LL(0xe916fe1d,0x8ba50ba3),LL(0xea83134c,0x4e839eec), LL(0x10e0b57b,0xc1f0f693),LL(0xe2b978ff,0xfd32f86a),LL(0x207746dd,0xa4737150), + LL(0xa3db3bbd,0x454c0df4),LL(0xb0f36f88,0x0edad6a0),LL(0x5dcf2b92,0xe233816f), LL(0x53dab969,0x25098373),LL(0x102254b6,0x436f8133),LL(0x4eedcc6f,0x9ce8f3ae), + LL(0x4b60ac27,0xf64e0fad),LL(0xe3f9cebf,0xea44c9f8),LL(0x84fe9a3a,0x719d958b), LL(0x27bf9bd3,0x5a5e47e8),LL(0xf50de48a,0x6f8c6ee1),LL(0x1971c6f2,0x5dc81c5f), + LL(0xe435f073,0x1e41a11d),LL(0x49ef9817,0x7b20a534),LL(0x111d8548,0x1ab1fb5a), LL(0x43450972,0x40d481ef),LL(0xddcf8585,0x28382f8b),LL(0x1b0f6b65,0x5a75f9e6), + LL(0xb1f8052b,0x41ac6def),LL(0xff4c9377,0xc417b22b),LL(0x3ba0240f,0x1c7a1067), LL(0xc99883cb,0x61005fe1),LL(0x6433295e,0xde900b52),LL(0x97d9ccb1,0x1eb1f666), + LL(0x65928ad1,0x86410ced),LL(0x05383f3a,0x281a9d46),LL(0x11cdecb0,0xa2b718a9), LL(0x6fb1cbee,0x67043aa6),LL(0x94dc2a31,0x5e2de7f3),LL(0x18e2d13b,0x7796cacb), + LL(0x413f1989,0x18e05e2d),LL(0x3e5cc915,0x2b2b27e9),LL(0x8836a712,0xa32587cf), LL(0x34c64b87,0x0cf77bb0),LL(0x6cafe545,0xf4d7f7ca),LL(0xa18bc173,0xf2191e2f), + LL(0xaf600892,0xc338b3de),LL(0x35ee6915,0x43c76ec6),LL(0x5564fc33,0x4fdad82e), LL(0xd93b474f,0x089a676d),LL(0x62b06515,0x44a02780),LL(0x2067dba5,0x65fe8051), + LL(0xf6549736,0xf1c24fd9),LL(0xc063acd4,0xf9d94656),LL(0x95a57c69,0x20c24772), LL(0x8993633e,0x91f7d4d6),LL(0x4444d45b,0xe9d75b4d),LL(0xb5bcc9cf,0x3b5a8bf8), + LL(0x1b093e28,0xf93e1494),LL(0xfcd88fcf,0x8ce5f30d),LL(0xbfcff34f,0x8fe20824), LL(0x7eec26d2,0x23a22164),LL(0x72404851,0x9b0f8456),LL(0x0e6c550f,0x135ff4a9), + LL(0x6ef7ad8c,0x70a42efc),LL(0xd82f0cec,0x2f6af7cd),LL(0x7a83b569,0xa0e0549b), LL(0xd3adf095,0xf580e86c),LL(0x8712a121,0x3c2d891a),LL(0xb9d07525,0xf1f2cd22), + LL(0x461ab8fe,0x7e90bc98),LL(0xc3e7e4df,0xf27a52f3),LL(0xe71da883,0x99813684), LL(0x5c5d56d6,0x2bc98a5a),LL(0x9d789345,0x17248209),LL(0x7dd92590,0x3312dfe6), + LL(0x26c45ea7,0xfeb5bd64),LL(0xea91cffa,0xfd9bbc06),LL(0xb59f6e6f,0x8be51e9c), LL(0x12663168,0x2082f3c9),LL(0xb78ce9a5,0xe57a2832),LL(0xe4f54287,0xb0d7aac6), + LL(0x338a630c,0xdad61bc3),LL(0xe66f4efa,0xcffda1bb),LL(0xa61cc9ef,0xccb2e20e), LL(0x3e09551f,0x8d2efcc4),LL(0x617bb37e,0x4e8f46b8),LL(0x2d9b4751,0xc516bc0f), + LL(0x8992f590,0x753b4f58),LL(0x994a51af,0x55461379),LL(0x0d16de56,0x9f0a37e6), LL(0x204a2e7c,0xb346ff69),LL(0xce235822,0xfaef890d),LL(0x98b923c7,0x5b046b64), + LL(0x29e950a8,0xb55daedf),LL(0xd3a1ff37,0x79b58c3a),LL(0xec3ed694,0x72c9d2d9), LL(0x9ddf8225,0xd119d76b),LL(0xce66c9a2,0x330952af),LL(0xb0e5e0dc,0xe062e16a), + LL(0x2d1cc8bd,0xe8cd1c24),LL(0x799a5052,0xf2f0da35),LL(0xbe0be8af,0xe52e337a), LL(0x6a2cbabf,0xeae205cf),LL(0x0acc8002,0xdddc1a94),LL(0x3d1031df,0xf559ec0f), + LL(0xefc11888,0x5d22ffc2),LL(0x4ff02455,0xdbb1c1ef),LL(0xc63b8f6f,0x543b4752), LL(0x883a7c99,0xd08ef2e5),LL(0xf38b3b3c,0x58ac93a0),LL(0xd8cac2ad,0x3c6c8105), + LL(0xdf1587c5,0x538bffc6),LL(0xa1a2eb88,0x0d5a4dd0),LL(0xc155f055,0xb9730932), LL(0xb9b8cd61,0xa21c36d2),LL(0x5320c28d,0xc435c223),LL(0x38120687,0x3230ce02), + LL(0xc37ce54a,0xea0530df),LL(0x06b232a0,0xb1894861),LL(0xf018336a,0xca2122b1), LL(0x38a380e9,0x08135d85),LL(0xe3028bd7,0xf256c6e5),LL(0x663fdf24,0xdacc9271), + LL(0x053cff11,0x31da52c7),LL(0xcc61252b,0x39051bad),LL(0x317a0ba8,0xf380f3e8), LL(0xd42451b7,0x212de129),LL(0x98e4747e,0x146f3c25),LL(0x2acac2c4,0x844da479), + LL(0x4cabc97f,0x9b8a6fb0),LL(0x0fbc8135,0xba6da1e3),LL(0x561f0e02,0xb076c93d), LL(0xf54d9d7d,0x2f940cf1),LL(0xec9daef2,0x14a542cb),LL(0x19d5ffa1,0x0579ad14), + LL(0xd4065d34,0xf8f179dd),LL(0x30ff0d6d,0x355fc75d),LL(0xc8fac2e6,0x91f6f5fb), LL(0x3e3fd917,0x8baf55f3),LL(0x077d4cef,0x6c4a7378),LL(0x192e1ce6,0x16be9fa8), + LL(0x92e5aec0,0xa3a9011c),LL(0xf37a5ab0,0x4fa0764f),LL(0xb1e1e01a,0x75ffe5ac), LL(0x51756cb8,0x3cd4ee19),LL(0xe2636498,0xc557a98c),LL(0x2c691a68,0x53a49769), + LL(0x752dbe26,0xdcdf8e6f),LL(0x7564740f,0xeaa9a260),LL(0x31a5df7f,0x9298d7e2), LL(0xa1b1f37a,0x47cdc94f),LL(0x3c25a836,0x26578ece),LL(0xec817acd,0x0aab1d74), + LL(0x5911f2ae,0xdd0678c2),LL(0x126b83a4,0xb903d7a7),LL(0xecd46d83,0x4efeef39), LL(0xb0d49ea1,0xbb4b0af7),LL(0xb6c2ae9c,0xc62fa8f1),LL(0x3e453617,0x897a8d06), + LL(0x54820219,0x335e7a19),LL(0x9104367e,0x8ae7926b),LL(0xcf0f8e5e,0xae2225b5), LL(0xd3fddb3b,0xc276e1af),LL(0x6a507a40,0x7b05028e),LL(0xef73bdac,0x85d2bd18), + LL(0xc71dd981,0x6953e0e2),LL(0x0e9a352f,0x7f739d63),LL(0xbe280f30,0xb6620388), LL(0xd020979e,0x89d5450f),LL(0x66d59c07,0x0370df8a),LL(0x0e91d327,0x76a60330), + LL(0x12f802fb,0x56161a39),LL(0x2ca0151f,0xe9e9e58c),LL(0xde14a0f7,0xc6da98d6), LL(0xe70f9647,0xdc21514c),LL(0x523f5cb8,0xa95c863d),LL(0x25f1c818,0x3e1cc20c), + LL(0x8d6f8ca1,0xeb6c9c82),LL(0xb9d65ec1,0xc57e3312),LL(0x0f121596,0x8b4328c3), LL(0x067036a8,0x1affe768),LL(0xe3091467,0x42586aa8),LL(0x30b7ad74,0x12de5d18), + LL(0x34933969,0x06705f70),LL(0x7267ab88,0x4ce99cd6),LL(0x1f916ab1,0x2bc4cfb9), LL(0xcd9b8de7,0xe458fea7),LL(0xedafc50a,0x59778ef8),LL(0x86ea0de9,0x58651c07), +} +}; +#endif /* _DISABLE_ECP_192R1_HARDCODED_BP_TBL_ */ +#endif /* _IPP_DATA */ + + +IPP_OWN_DEFN (const cpPrecompAP*, gfpec_precom_nistP192r1_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 7, + /* select function */ p192r1_select_ap_w7, + /* precomputed data */ (BNU_CHUNK_T*)ec_p192r1_precomputed + }; + return &t; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpp224r1precomca.c b/plugin/ippcp/library/src/sources/ippcp/pcpp224r1precomca.c new file mode 100644 index 000000000..4e752a592 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpp224r1precomca.c @@ -0,0 +1,4489 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (P224r1 precomputed) +// +// +*/ +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +#define OPERAND_BITSIZE (224) +#define LEN_P224 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* P192 affine point */ +typedef struct{ + BNU_CHUNK_T X[LEN_P224]; + BNU_CHUNK_T Y[LEN_P224]; +} P224_POINT_AFFINE; + +extern const __ALIGN64 P224_POINT_AFFINE ec_p224r1_precomputed[33][64]; + + +#if defined ( _IPP_DATA ) + +#if !defined(_DISABLE_ECP_224R1_HARDCODED_BP_TBL_) +/* see ippcp_baseptbl.cpp test for generation details */ + +#if ((_IPP_ARCH == _IPP_ARCH_EM64T) || (_IPP_ARCH == _IPP_ARCH_LP64) || (_IPP_ARCH == _IPP_ARCH_LRB) || (_IPP_ARCH == _IPP_ARCH_LRB2)) +const __ALIGN64 P224_POINT_AFFINE ec_p224r1_precomputed[33][64] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0x6d0a4aea,0xbc905226),LL(0x6018bfaa,0x85259736),LL(0xf96bec05,0x6dd3af9b),L_(0xa21b5e60), LL(0xeff3ede8,0x2edca1e5),LL(0x05335a6b,0xf8cd672b),LL(0x03dfe878,0xaea9c5ae),L_(0x614786f1), + LL(0xe722ff54,0x4ca9a1ec),LL(0x5650df9b,0xd704f84f),LL(0x2a0f1689,0x10c911f7),L_(0xcafb50f5), LL(0x95a24e5e,0x02aac79b),LL(0xc90ae186,0x518c11b1),LL(0x76cc101a,0x0c84ced0),L_(0x5cabb880), + LL(0x86614a9a,0xe37710d7),LL(0xe0b02223,0x24c17ffc),LL(0xc3cf1c5b,0x00505bb6),L_(0xaf8b6496), LL(0x73e4e25d,0x9a73b173),LL(0x04144e62,0x70501632),LL(0x357940ac,0xafe10c35),L_(0x6dfa492c), + LL(0x840f10e9,0x0a72faf6),LL(0x0860856c,0x3c2dbf31),LL(0xcb021706,0x4256e88a),L_(0x89f0c6a0), LL(0x8c1f2b39,0x6743e273),LL(0x98933269,0xd8933d1c),LL(0x2058f0ba,0x7ee104d3),L_(0x8c87db62), + LL(0xd42fac58,0x0b10cc50),LL(0xf8dfc283,0xd80cdd0a),LL(0x975a451e,0x39211b77),L_(0xf7f4fe95), LL(0x64fade9e,0x2b552e73),LL(0x61a9e695,0x5e5610f3),LL(0x11bcf038,0x42b54f79),L_(0xc858da82), + LL(0xde4901db,0xde577c0d),LL(0x1a8aec73,0x09e4f789),LL(0xe0cd01d4,0x1addb3a1),L_(0xf25fe17c), LL(0xdc7c211c,0x5fae6c32),LL(0x0f5c7709,0x5603672c),LL(0xf2d2c41c,0x9b6731a6),L_(0x162f9e1c), + LL(0x899abac2,0x90462820),LL(0x68646e35,0xc6adf683),LL(0x1e2526ba,0xc81df812),L_(0x7ed50814), LL(0x5dd6407c,0x610f2185),LL(0x1fb32889,0x3f3879aa),LL(0xed8ceeee,0xce5eb25e),L_(0x0e5952e3), + LL(0xde1707ec,0xb4c9d865),LL(0x7bd696a2,0x3fcec855),LL(0xa3bebfe9,0x8e4a5712),L_(0x1b59038c), LL(0x29a5f205,0x1bc1ff36),LL(0x7558734a,0x0efc11fd),LL(0x09762590,0xc4e19066),L_(0x2199c364), + LL(0x7b94d3c7,0x1c1ecc77),LL(0x743eda4a,0x23767b5f),LL(0x2f993a50,0x94f5e9ba),L_(0x79d4095a), LL(0x8f776409,0xe07e55b6),LL(0x909bf3f1,0x2b57fa61),LL(0x77e1db6d,0xe733d627),L_(0x5114ac9d), + LL(0xa53cb542,0xb808145c),LL(0xb4f2672c,0x8d51557e),LL(0x3e8abf6a,0xc1f86e2c),L_(0x9d0cdd53), LL(0x8dd67e37,0xccddceff),LL(0x02883b6f,0x94892c1d),LL(0x873d7e4c,0xdbc0f8ee),L_(0x2a687506), + LL(0x6c6825d9,0xac358ca8),LL(0xe1bdd5ca,0x71f50674),LL(0xd0dee306,0x0f060758),L_(0xd6d89093), LL(0xf1b7227e,0x649ea142),LL(0x08181c2c,0x87d166a2),LL(0x6c63713a,0xc1182bf0),L_(0x45e48d79), + LL(0x8f86d9da,0xf6495da1),LL(0xa37b7441,0x5dc634c9),LL(0x2b0b8e1a,0x571d38d9),L_(0x517af941), LL(0x92dd72b5,0x1305b612),LL(0x8cf21835,0x8db28ab1),LL(0x5f59deb1,0xbc243af0),L_(0xa71404ae), + LL(0x3a1f6a38,0x489c8db2),LL(0xffbe563f,0x4943a5ae),LL(0xbc99fb0b,0x68ade63c),L_(0x398eacf0), LL(0xed549cc4,0x83fdacb5),LL(0x800df824,0xb6ab4a8b),LL(0x442ed616,0xb4dc6bf8),L_(0x3f8060b4), + LL(0xb83ee7d6,0xf4109221),LL(0xcdbd6eec,0x565559e4),LL(0x1ef814eb,0xf4550d2e),L_(0xb3a9b5e4), LL(0x6d218d7b,0x1544e90e),LL(0x3f51f9f9,0x31b0bc68),LL(0x825b5795,0x6516bbc3),L_(0x3d1419d2), + LL(0xe977f339,0x55bfd519),LL(0xb16ed1af,0x5cd307d1),LL(0xd91345bb,0xc5e26f62),L_(0x64a35d22), LL(0xa243f1ee,0x05015842),LL(0x70203aa0,0x6fa10db3),LL(0x05a83a63,0xdaf3972b),L_(0x9422f10e), + LL(0x73b437e2,0x6a4bd1f9),LL(0xb3f66de6,0xbb0f749a),LL(0xfdf9a0e9,0x471a2a7f),L_(0xb9c51b5f), LL(0x44574243,0xfa29681a),LL(0x9c409bd0,0x9522774b),LL(0x169405c3,0x48be80cb),L_(0xf22d3fc0), + LL(0xf845831a,0x86ade48b),LL(0x79cec3fb,0x473e361f),LL(0xb9622253,0x5523244b),L_(0x538d543e), LL(0xf8570c03,0x12bb38bf),LL(0xb4e20b8c,0x784e1b25),LL(0xe6873448,0x2a2e7758),L_(0x2954321a), + LL(0x47b54bc5,0x3591891e),LL(0x27a72a86,0x3ca319e3),LL(0x482460f6,0x70114363),L_(0x3b204e52), LL(0xcca0ee1f,0xd5f98053),LL(0xc4a1a96b,0xd84149c4),LL(0x0c0e97bb,0x6bc4b6e9),L_(0xfb212c8c), + LL(0x1bfad739,0x716b6add),LL(0xea007122,0x0e68b721),LL(0x08a75056,0x4e35e1f6),L_(0xe28f8fa3), LL(0x93c21468,0x7393ad16),LL(0x4e27959e,0x4533e928),LL(0x433c708d,0xe5b33144),L_(0x4c003b64), + LL(0x32804a04,0xc57bd47a),LL(0x238addb6,0x5ae81313),LL(0x703c82d5,0xa0691b17),L_(0x14a5d58e), LL(0x825037c4,0xf9cefcb5),LL(0xfd4764c3,0x38e801b7),LL(0x7b23c9fe,0x23cf8d21),L_(0x1d7b0c07), + LL(0x8738f5d4,0x869c61a1),LL(0x8d8b998b,0xe83f1dc1),LL(0x5cc8116d,0x1f271989),L_(0xa8992ade), LL(0x88f6e037,0xb2334f8e),LL(0x1fadf19a,0x9fcaafe1),LL(0x71d5904e,0x939bd9ec),L_(0x534ec549), + LL(0xa2cbcd92,0x22be0a44),LL(0xb12549d7,0x275cd50c),LL(0xb64feadd,0xfa13b698),L_(0xd61f5f42), LL(0xedfc9326,0x7ea2fed9),LL(0xd797283d,0xdbd2171d),LL(0x5e1f2529,0x113c4da8),L_(0x4d22be7a), + LL(0xd7a234b5,0x746daf5f),LL(0x210782c4,0x8d13c8a1),LL(0x358ace9d,0x1008fd0f),L_(0xaf231c63), LL(0xeedf77aa,0x17203da0),LL(0x3534d554,0x0974abbe),LL(0x30962d48,0xf7552ee7),L_(0xa1ab0080), + LL(0x77890e5b,0x7708ee68),LL(0x981a94f1,0x624e8fe3),LL(0x50822536,0x2632b017),L_(0x21031b41), LL(0x0b603325,0xa43cc164),LL(0xfb24577f,0xc20ef5b2),LL(0x67a5fdbd,0x583ccbb4),L_(0xdf198e9a), + LL(0x2390b30d,0xec729f5b),LL(0x347bddd0,0x5467eb45),LL(0x4576657b,0x79a42c59),L_(0x3a4d5c62), LL(0x871cf39c,0x72672c8d),LL(0x34edf6de,0x22af9ec1),LL(0xc615c176,0x264b7c52),L_(0x6b6c91f7), + LL(0x3dc0652c,0x3c93deb4),LL(0x454fe5e1,0x83476556),LL(0xdaedb455,0x895933d6),L_(0xc3d92afc), LL(0xbabeca3c,0x62afc582),LL(0xb1ad4196,0xd877f8d1),LL(0x122626f8,0x56df6aa3),L_(0x88c5db33), + LL(0xc8d94c12,0xb5862dd8),LL(0xfb7f7ec7,0x3488de74),LL(0xf9ca08fd,0xf3fb356b),L_(0xa3379ec2), LL(0x27d39af3,0x5680ab94),LL(0x1f4b780d,0x4aa3a013),LL(0x181ad0f0,0x9c77acf2),L_(0xc5ed6c19), + LL(0xa57812ca,0x57cdf956),LL(0x2e235ce3,0xec26e698),LL(0x3b66736f,0x02924c24),L_(0x9611c7f6), LL(0x20dcabee,0x2cd39c40),LL(0x0ca01257,0x6c0fb396),LL(0x36cea89c,0x576c9d6d),L_(0xc0386b9b), + LL(0x69c717f0,0x3ff1d620),LL(0xb26ad028,0x975088a3),LL(0x3395a449,0xbb9b7453),L_(0xac8575b5), LL(0x0cb11f18,0x19b52294),LL(0x61b7e04c,0x84cd1038),LL(0xea595a3a,0xb7e04864),L_(0xf641867a), + LL(0x68c289a6,0xf9c67812),LL(0x0d5cd555,0x64da8983),LL(0x15609314,0x071a1814),L_(0xcec729a1), LL(0x2725b13c,0xd82b0a63),LL(0xe9fd6113,0xba49569c),LL(0xf4a523e8,0x095fdd3b),L_(0x601388e8), + LL(0x382f2331,0x5d150588),LL(0x6e0c12f8,0xabac1d43),LL(0xcc4b0247,0xe25d613a),L_(0x98b62cd3), LL(0xc09181c3,0xca8e4ca9),LL(0x1f7fb23f,0xae6dcc27),LL(0x41da9f53,0x44527d49),L_(0x9e1f47c6), + LL(0xbf5c291a,0xb17f74ec),LL(0xe460275b,0x7fe47107),LL(0x56dc0e69,0xaef13524),L_(0x055bebff), LL(0x85eeba4b,0x5a0a6115),LL(0x52aae002,0xd72b6016),LL(0x65c91bf7,0x55229ca9),L_(0x837c7497), + LL(0x05073659,0x724287d6),LL(0x86eb5493,0x266f1738),LL(0x70786420,0x72b46e9e),L_(0x0bd8afe8), LL(0x2e7a6b37,0xeea543b6),LL(0x7400cd52,0x1221cd6e),LL(0x0a6c2e1c,0x9604a54b),L_(0xe2c2c60a), + LL(0xaacc2f1d,0x771d897e),LL(0x80cd8b3c,0xa4304d46),LL(0x3b961927,0x56c6e625),L_(0x8d0c1d5a), LL(0xf0576bd1,0x4b4c8802),LL(0xee49b988,0xd528b6a1),LL(0x617aabd8,0xb63d84cc),L_(0xb309e31a), + LL(0x21a4d862,0x6ef3ab05),LL(0xfbca1b97,0x7fe6fa59),LL(0xd8911f8e,0x639e011c),L_(0xb731d607), LL(0x654578a1,0x0706cd08),LL(0x8e5b6703,0x5d08a7fc),LL(0x4d443d17,0xdc2ea468),L_(0xccc5dbca), + LL(0x2986a64c,0xf86e4ee6),LL(0xb38b3cb9,0xb2a50e4f),LL(0xd001bff6,0xad920b0c),L_(0x5f833048), LL(0xceab268e,0x3c687112),LL(0x9cac7077,0xb6207b74),LL(0x2bf74e82,0x92b4f4b1),L_(0xfcfe6f73), + LL(0x4a1a48c2,0x9afdccc1),LL(0xf2645ccf,0x9befe15b),LL(0x170bc3de,0xc06a289b),L_(0x8b3174cc), LL(0xcb55af1c,0xc289c4c5),LL(0xfcbc66cf,0x73ec1671),LL(0xea32e7fb,0xfdc7bcec),L_(0x2d89d32d), + LL(0xc3672949,0x31801b58),LL(0xcf102dd0,0x2e36c7e0),LL(0x28f8286a,0x1600629e),L_(0x6d3edc02), LL(0x16920812,0xf21cabe6),LL(0x31851ac8,0xf3657a9a),LL(0x037f5693,0x3f33781d),L_(0xb0a0ce6c), + LL(0x15c4b334,0x4821f125),LL(0x43b3629d,0x3a678868),LL(0x33190540,0xa3b32151),L_(0x4038845d), LL(0xcf5706d9,0xedfaa06c),LL(0x00044014,0x08de20a4),LL(0xd5eb20d6,0x1a8a108b),L_(0x38cb0a6b), + LL(0x15f2ae4d,0xb6e363d4),LL(0xa45c3df2,0x80d28480),LL(0x00c26ab1,0x85098966),L_(0x6d03e325), LL(0x36056e89,0x8eec84d1),LL(0x9134e03a,0xce2d0f6b),LL(0xbbc8d92d,0x4ffdb217),L_(0x6e97a4bb), + LL(0xb60e66c5,0x231d20c5),LL(0xa36c8848,0x89bcc285),LL(0xcb7e8b54,0xc4b2c9f8),L_(0x2f8b6de0), LL(0x243f2d3f,0xb8860525),LL(0xfdcf530d,0x945673bf),LL(0x49da0f6b,0xefc627b6),L_(0x4e9fb807), + LL(0x21bc7f20,0x64eae113),LL(0x23074bd5,0x2718ea4a),LL(0xb246633c,0xefdb4759),L_(0xc6af484b), LL(0xcdbec413,0xe5997f28),LL(0x8979b2ec,0x82bcb2f5),LL(0x530f4963,0x55ee3298),L_(0xccf127a1), + LL(0xba2c7ded,0x687018fc),LL(0x7c723f5d,0xcc9d7b65),LL(0x2221f721,0x93828714),L_(0x13d720d3), LL(0xe6d02ad4,0xe61c9b05),LL(0xc198db55,0x72b115de),LL(0xbe38af8f,0x621f284e),L_(0x18f09bf6), + LL(0x7c8299c2,0x65cd0db6),LL(0xbb33fff7,0x7d479cee),LL(0x44ac0a56,0x7a9b66be),L_(0xc9308cae), LL(0x43b7cc76,0x1b4048cb),LL(0x5b7ecc1b,0x0b2ccca8),LL(0x7fa30aae,0x7e09ad23),L_(0xff1f76e3), + LL(0x13e6bef2,0xa178a33a),LL(0xdd724842,0x7d66c450),LL(0xa5d7a87c,0x30befc70),L_(0x69874db8), LL(0x3ef58d85,0xcfcdbfce),LL(0xe3d6346a,0x9fa94e38),LL(0x84c65476,0xde39cef5),L_(0xe4efb3c1), + LL(0x5b582473,0x493ae0ba),LL(0xbc282cc0,0x8c93a914),LL(0xa024a0ea,0xfa3a15cd),L_(0x240e6a89), LL(0x572dde87,0xbba5d02d),LL(0x95b6f1e0,0x2f1b39cd),LL(0x15b8172f,0x158b8956),L_(0x5eb7385c), + LL(0x4b30aee1,0x92f507cd),LL(0x9137f80a,0xa95f0372),LL(0xcb924116,0x2be56c53),L_(0x0703cdda), LL(0xbf64ed3a,0x0b8faa7f),LL(0xb73eae3f,0x9943cbed),LL(0xf227ad25,0xdbca2fc4),L_(0x06231927), + LL(0x92d256df,0x5983f1a7),LL(0xee7ac222,0x640d13e7),LL(0x48c69cc0,0xa7dc8e21),L_(0xbd701252), LL(0xaa2ef84d,0x483083a1),LL(0xc0d30797,0x560bf32f),LL(0xd4ec2e63,0xbda6fdc0),L_(0x15074c14), + LL(0xc0aebb53,0x29e4a335),LL(0x600e1a17,0x155e8020),LL(0xa542f638,0x556905e7),L_(0xc7209080), LL(0xf57b447b,0x0b55b0fd),LL(0xa6cf1f95,0xc37cde3e),LL(0x9d44e115,0x1acfe880),L_(0xe820af09), + LL(0x08d29dee,0xc0bba382),LL(0x02857752,0x40ac12bb),LL(0x8b30f556,0xf120846d),L_(0xac6401e1), LL(0x41706845,0xcb20c290),LL(0x84fbf362,0x6005431c),LL(0xecddc9db,0xe1839421),L_(0x63952a13), + LL(0x93d07eac,0x24f4b135),LL(0xf0524e07,0xfc097ef4),LL(0x138ee6ed,0x1770de3d),L_(0xedc6985e), LL(0x34e15a3c,0x997ae14f),LL(0xb5a50098,0xa168adf0),LL(0x05ed2b31,0xe84702e1),L_(0x4701e013), + LL(0x991691d6,0xa2d01aa3),LL(0x5c0291c5,0xe3a7de4e),LL(0x87f294c6,0xdc575065),L_(0xf7c66733), LL(0x1ae8eb0b,0x236da942),LL(0xb2bb31c0,0xd46c809a),LL(0xefda656f,0x0d4ba22a),L_(0xd90a6c4a), + LL(0x009f6ea1,0xd7b84536),LL(0x6ae52eb4,0x52644093),LL(0x4989ea92,0x58155fb2),L_(0x51865588), LL(0xd29d86e0,0xb2f24a3e),LL(0x4a65a557,0x6e88be4d),LL(0xc5c558ab,0x39d391fe),L_(0x71637238), + LL(0x551e6187,0xc6f1655b),LL(0xda9557a2,0x49fef895),LL(0xad9724f5,0x02bd8dec),L_(0x286ae065), LL(0x519ec0a6,0x66f88628),LL(0x409bbff9,0xb11907a8),LL(0xa035e3ce,0xfa9ce7d1),L_(0xb11a05b6), + LL(0x835832b0,0x7d3144d7),LL(0xeeb7e587,0xca5729ee),LL(0x63105e87,0x24b31279),L_(0x358ad95d), LL(0x44854e57,0x8b96f12f),LL(0xa1f8699a,0x43d92d9e),LL(0x36720d2f,0x19da3cf7),L_(0x0c3e259d), + LL(0x4f9b1862,0x3ebef321),LL(0x18a10476,0x898e24fc),LL(0x93fc7b18,0x2dd5dfa6),L_(0x453f9b19), LL(0x9fe968bd,0x2e375ef1),LL(0xde52e14c,0xc56e3c8e),LL(0xb86d2dac,0xcdf1057b),L_(0x8978f37a), + LL(0xa47a47e4,0x01ae0872),LL(0xf209f351,0x1ffda591),LL(0x1c3d4f64,0xfd2dee37),L_(0x23082359), LL(0x92135e7e,0x226bc4e4),LL(0xc1dc2c14,0x68af001c),LL(0x4a88888d,0xd11ebfc0),L_(0x5bb60dfa), + LL(0xbdac7377,0x6d7442e6),LL(0x1a37fe3d,0x111de286),LL(0x64b6847f,0x54c71408),L_(0x9321abab), LL(0x605934d9,0x8f6064c1),LL(0x0fe08518,0xab526e1f),LL(0x48846076,0x18d88b42),L_(0x5027824f), + LL(0x58d7da2d,0x2fefa18a),LL(0x0a5f6d1a,0x28fd1689),LL(0xaeecb1e4,0xe2cc44ed),L_(0x1a3c357a), LL(0x0093ad3c,0xe129986c),LL(0x78fb4e9b,0x8691e9c2),LL(0x6b166a07,0x1f456692),L_(0x55649b1b), + LL(0x9465a494,0xbb9f7822),LL(0x0c7e73f7,0x720482c7),LL(0x4c6140bb,0x1d71b6bb),L_(0xc0d4cee9), LL(0x846e827c,0x8f080a16),LL(0xf403aa8c,0xa7eed738),LL(0xb53cebd4,0x45561f5f),L_(0x176891fe), + LL(0xd85db49c,0xffa27852),LL(0x4d6d2499,0xebaf8c05),LL(0xb5248259,0x5a3e6570),L_(0xb7125d0c), LL(0xf6311485,0x37979bfc),LL(0x785afdfc,0x732a179e),LL(0x1a4c7732,0xe1b6b02f),L_(0xa84e1866), + LL(0x70e07038,0x11dbcdcd),LL(0x4243fd62,0xf7e91887),LL(0x9892ddcf,0xdc0c4d01),L_(0x5638c3c1), LL(0x71bade10,0xa42313ce),LL(0xfcf531d5,0xe28bc38a),LL(0x1417aa25,0x7e0b8323),L_(0x41b2315e), + LL(0xac4962cb,0xd6c61ac1),LL(0x9d056208,0xb7765b3a),LL(0xa70e6aa2,0x566c60a7),L_(0x483b996a), LL(0x05f2cab3,0xa38d32bc),LL(0xc38fefeb,0x21c5e288),LL(0x57f15c48,0x689ae7bd),L_(0x3e0d8010), + LL(0xbb871aa2,0x2587df14),LL(0x904f01e9,0xc5d6ae2a),LL(0xbce7f04f,0x88aa4d08),L_(0xd7f1a354), LL(0x75d9b4b6,0x5bfae677),LL(0x299925d3,0xf0375024),LL(0x6a708cd7,0x74d5a757),L_(0x97968c25), +}, +/* digit=1 base_pwr=2^7 */ +{ + LL(0x44a6cdeb,0xd1a6df98),LL(0x084a7e0f,0x89ef410c),LL(0x0b68659d,0xdf5b6590),L_(0xe1cee8dc), LL(0xb48fcec5,0xf5210071),LL(0xccbda01d,0x01031fdf),LL(0x4c7a3392,0x01bb7a1c),L_(0xa7484df7), + LL(0x698ab732,0xcb74232b),LL(0xb62e25de,0x4f40ee59),LL(0xc5c8bed1,0xfb8ee6c4),L_(0x4617192d), LL(0x626b516c,0xeaf8b0a3),LL(0xdc2453a5,0x0f8cc094),LL(0x4d7f2e28,0xf43e697c),L_(0x2e81523e), + LL(0x212c04e5,0x37eb6d84),LL(0x29543b70,0xa63887c8),LL(0xe67d4662,0xbf221e31),L_(0xde581875), LL(0x5a447606,0xc3db23ff),LL(0x82bba001,0x0b2a5765),LL(0x60a68af2,0x5e5ccc27),L_(0x619f6149), + LL(0x008cfd4a,0xe80619b5),LL(0x25f0799b,0xd4f88882),LL(0xeb6dfe0d,0x9bf5f7d0),L_(0x63a366a0), LL(0x3703627a,0x927212be),LL(0x02c160de,0xbd5509cb),LL(0x09ea0af6,0xfe05e98d),L_(0xbae9ad71), + LL(0xb26352aa,0x65b1d33d),LL(0x7f5ed157,0x84979794),LL(0x1ed1728d,0x39babd58),L_(0x0137cf58), LL(0x836ccdc1,0x2546cd9b),LL(0xd0dfb090,0xbfa9bb59),LL(0xb59a51ab,0x6476def4),L_(0xc5dce06b), + LL(0xceaa7c3c,0x23138239),LL(0x80c0cfc1,0xa694e0b5),LL(0x27734f88,0x587454f5),L_(0xb527a9af), LL(0xee6f2afb,0x049823f2),LL(0x25a1f7dc,0xe574bc64),LL(0xb3ea257d,0x1d11fd76),L_(0xafd0ae51), + LL(0x9b56a4c2,0xc1bc485c),LL(0x407824fd,0xbe617f5c),LL(0xa0e87d81,0x71256aba),L_(0x76217f94), LL(0x3e2877fa,0x8b3e508b),LL(0xe501c9b4,0xbda0977d),LL(0x08a19d4e,0xfb512fa2),L_(0x59ab4cb8), + LL(0x71544a12,0xe4756696),LL(0xaf2eb7f6,0x93d2ed81),LL(0x5c0e9df7,0xc52db668),L_(0x2b7064bd), LL(0xded1b829,0x43184720),LL(0xd4b9fc59,0xad215e80),LL(0x1343040b,0x88ef261a),L_(0xb9864942), + LL(0x8eee1fca,0x0f601216),LL(0xc3ce93c3,0x8e99383b),LL(0x40d758a5,0xc0aa59c7),L_(0x54ae6327), LL(0x9df0859e,0x111b9e3c),LL(0x09cd3a96,0x2e522f76),LL(0x6bcd40ef,0xb04993c8),L_(0xbcda6d48), + LL(0x0deb6f15,0xbabee791),LL(0x030c3495,0x66179f3c),LL(0xd426f7b5,0x457bca6d),L_(0x81319526), LL(0xd35cd40e,0x2498c158),LL(0x0b2bd04a,0xaec4ff20),LL(0x12985a92,0xcff74849),L_(0x837d8e0e), + LL(0xf9b841f9,0x139de2db),LL(0xf41adf6c,0xf5c32cc1),LL(0xb7dc7dc5,0xede2ea87),L_(0x6e2033f0), LL(0x706a5efb,0xcd213864),LL(0x287f4ece,0xdccf34ae),LL(0x50f400e9,0x0fc6614f),L_(0x89db6d9e), + LL(0x4782e689,0xc42a6b83),LL(0x9e9a2ddd,0xa767b1e1),LL(0xf3f5ab2e,0xabdd54a4),L_(0xc69f9a88), LL(0x5eeb634c,0x8affd662),LL(0xb4602516,0x434e3998),LL(0xc75f7a3f,0xfbd56bb7),L_(0xe4aa58aa), + LL(0xfdddeaed,0xbb083ae3),LL(0x96aff3db,0x8b900a50),LL(0x2d9b4c87,0x77208838),L_(0x2b1d390f), LL(0xeb40774a,0x408ee7f4),LL(0xc9a98c1e,0x491fbb55),LL(0xb6789b9e,0xf0a9cf2d),L_(0xcc0aecb1), + LL(0x4d8759b7,0xf99e1bc1),LL(0xf9d97ac1,0xe489d308),LL(0x31242e73,0xe520dfcf),L_(0xba519709), LL(0x502d066a,0xaada88da),LL(0xdf453d98,0x2db805ff),LL(0x48d83f43,0xa35584c3),L_(0x7efe383e), + LL(0x1ce90c15,0x18351405),LL(0x987fc6a6,0x16ded7d8),LL(0xf2b213ba,0x17bc0ecf),L_(0xd5c3d1eb), LL(0x4a42fef2,0xc603801c),LL(0x037728cd,0xbe4db3d6),LL(0xc5cf397d,0xde6243a1),L_(0xaf004bfd), + LL(0xee10b9c9,0x81c21906),LL(0x140e4fb4,0x5c74da45),LL(0xb07d29b4,0x65c368fc),L_(0x6829786b), LL(0x7aba9db1,0x7c01e8b7),LL(0x5c2ad4ba,0x597dbeb5),LL(0x8b692603,0xca528c39),L_(0x09175739), + LL(0xd1bd09d7,0x3e778b35),LL(0x332aa21b,0x97ef919b),LL(0x7761d7c9,0xf6af5223),L_(0xded7e546), LL(0xe8470307,0xde909622),LL(0x254a8b2a,0xe9be14c8),LL(0x6fa060cc,0x7cccaea0),L_(0x723e3222), + LL(0x6fa0e5d8,0x00e54d7e),LL(0x80274626,0x53d70b13),LL(0xf63104d3,0x448cb4f0),L_(0x86f7822c), LL(0x567fec1a,0x635d1d19),LL(0x74c9d852,0xad5841d3),LL(0x2f27a18d,0xa7638f56),L_(0x7df0f814), + LL(0x2f7d4c38,0xe3919fa1),LL(0x11b8e6be,0x426c3ac2),LL(0x2038bc39,0x1a7c24cb),L_(0x547f1d30), LL(0xad339016,0x4937319b),LL(0x14498e9f,0xe9acdbc9),LL(0xd9e8ae36,0x71231dd7),L_(0x099cc29c), + LL(0x0f0c5086,0xbfa21d69),LL(0x9934b257,0x0d29b38c),LL(0x2552b462,0xfad28b1a),L_(0x87244f2d), LL(0x042aa2fb,0xe091c63b),LL(0x224579d6,0x86f0f8da),LL(0x7927774b,0xa4177fae),L_(0x39e5970f), + LL(0x8ecd5fa1,0xf8a953db),LL(0x00e1559f,0x8ef3b9f7),LL(0xa70e63b9,0xf8851e82),L_(0x48191bdc), LL(0xefc3b637,0x6d398f41),LL(0xc96682f5,0x40655248),LL(0xc2927516,0xd7d600fe),L_(0x6435359a), + LL(0x4a966ff2,0x43c60bf9),LL(0xbe98cc32,0x94a73ea6),LL(0xe899fd7f,0x6f6a67d4),L_(0x4805ca93), LL(0x49a69773,0x532ddf8d),LL(0xb5f6725b,0x4785c103),LL(0x9818fcf0,0xa6151612),L_(0xa9419c51), + LL(0x351340ab,0x544bdd84),LL(0xf568cb9c,0x1359eeae),LL(0xe070e7d3,0xa9680c77),L_(0xf00849de), LL(0x3f049e65,0xc159fff4),LL(0x9f8b9614,0xc00e514e),LL(0x0503644f,0xf325f0bc),L_(0x58ef4f26), + LL(0x0afb5680,0xbb5a090b),LL(0x2a905098,0x29e6e124),LL(0xeb89d752,0xb46f0674),L_(0xc23b6e08), LL(0x7d46e8c8,0x84d934a5),LL(0x7446341f,0x814623ef),LL(0x2d200178,0x428fe6ef),L_(0x663531ec), + LL(0xc36811cc,0xf0622226),LL(0xe7d3d99c,0x26dbef18),LL(0x87323666,0x0421f1d4),L_(0xb81113de), LL(0x2f1ac158,0x121ae440),LL(0x14b9bfe5,0x7f1d1f81),LL(0xab8ce457,0xfb0b5381),L_(0xeebf8b75), + LL(0x1ed0f16e,0x4ab996f9),LL(0x3bca93de,0xf3972d52),LL(0x9c224825,0x51f0a250),L_(0x4390fa94), LL(0x52d41c04,0xa17f9bcf),LL(0x87ca94cd,0x1da254f1),LL(0x8eb876e4,0x8c10d532),L_(0x6ab8e456), + LL(0x251d18df,0x00191031),LL(0xbe58c480,0xfb757330),LL(0xf0df6b45,0x51d6cd1a),L_(0x3a2b0d2e), LL(0x72d910fc,0x6e0dcc32),LL(0x17ad59a0,0xd56ef620),LL(0x24ff8cf7,0xb1342fd7),L_(0x514eda6b), + LL(0x3d2d0473,0xaede35a8),LL(0x43fadb36,0xc3bc4ec3),LL(0xda078971,0x89ff847e),L_(0x757ad40d), LL(0x3367d69b,0x063bed04),LL(0xfbec9b9f,0x96916bd1),LL(0xa2938401,0xed5c65dd),L_(0xd3c116f5), + LL(0x4ab81e63,0xbf6d76ab),LL(0x4a94b590,0x92ace598),LL(0x43e3ebf0,0x6d7848f4),L_(0xe0fe0161), LL(0xd3008b3b,0x503ad71b),LL(0x14c43727,0x1bf34193),LL(0xafbcb091,0xbb5f8c82),L_(0x3bf8d893), + LL(0x9e3f46b2,0xa2d0d277),LL(0xd8be2204,0x6e8eb285),LL(0xc9fa15ec,0xac17e25a),L_(0x91b10a2f), LL(0x897ae118,0x12c8ef7f),LL(0x087fa01d,0x919f4309),LL(0xb6f728bd,0xd198666a),L_(0xcef80aee), + LL(0xf8d94d59,0x6112903c),LL(0x89add916,0xda5061e7),LL(0x1c13960f,0xf15aa481),L_(0x48b52034), LL(0x16623c8b,0x2d1bf700),LL(0xb5d87e2f,0x9a5f3c4f),LL(0xc7e5ba8d,0x6e4a90fb),L_(0xfd04fbda), + LL(0x16d9fe00,0xce2f6f2e),LL(0xae50cdc8,0x205e3401),LL(0x5c73b50f,0x59a0da00),L_(0x6b833239), LL(0xb1b01bc6,0x54c575fa),LL(0xfdd6dfac,0x38a3a688),LL(0x761a3a3e,0xb3095407),L_(0xca8c1a6e), + LL(0x2aa45623,0x56e12b9e),LL(0xa3fc4119,0xd0bffaa7),LL(0xf5bdb564,0xe34b58ec),L_(0x178622a7), LL(0xcda19c33,0x9e9ffc05),LL(0xfbbaa19e,0x51b7b9c6),LL(0x42f09c2b,0xb2d6157b),L_(0x0c83351e), + LL(0x80fda4ab,0x623598c1),LL(0xae4a61b7,0x488f724a),LL(0x47014b1c,0xddd6a618),L_(0xc1476c47), LL(0xbc2cc2d5,0x7eb38a43),LL(0x31a26c96,0x7b20f4d7),LL(0xc5ea2b2a,0xa5a136e8),L_(0x13b6043f), + LL(0x3199bbf6,0x07cb2293),LL(0x210180c0,0xe5a1b306),LL(0x782987ea,0xab40f28e),L_(0x4a4f4f9e), LL(0x95fa6103,0x591b5ef8),LL(0xf6832896,0xb357ced7),LL(0x38f56fa2,0x5abb2a56),L_(0x5a65a98b), + LL(0xf1c770e6,0xca04bf7b),LL(0x022f4557,0x88cfe334),LL(0x657a19e3,0xc772f98c),L_(0xa19ab123), LL(0x3ab78500,0x82db0eac),LL(0xd6b0ec00,0xf668d4b5),LL(0xdeadd9cc,0x9dab24ce),L_(0x1c2e2051), + LL(0x0ac55884,0x7647407a),LL(0x489801b8,0xfa51e70a),LL(0x56034023,0x26d5313c),L_(0x29b7a999), LL(0x834f99e6,0x6f0fc77c),LL(0xfdc7c2f1,0x647839fb),LL(0x006982c9,0xcb5af1f9),L_(0x9323d960), + LL(0x91a088be,0x76954497),LL(0xa4de751e,0x393750b7),LL(0x6dc8702a,0x805eb5f7),L_(0x1cfb5ce3), LL(0xaa971870,0x94bbb1b2),LL(0x43b64965,0x939fd8c5),LL(0xaf8d3158,0xc4fd0925),L_(0xeb438d66), + LL(0x0e5bf508,0xc7a170c1),LL(0xb2973b56,0x43a0c49d),LL(0x9e4dbaca,0x2cb87666),L_(0xcf3bacaf), LL(0xef7d14b1,0xa2effdce),LL(0x20a60ee8,0x586540be),LL(0x60509402,0x676121bd),L_(0x745c0ff2), + LL(0x6d713b1e,0x3407acc5),LL(0xb6d85b13,0x4730880c),LL(0x7e9049e1,0x9fc877ce),L_(0x64c1005f), LL(0xe9cfd783,0xb606ab7b),LL(0xe272e2ce,0xc2eb602b),LL(0x97ac2d38,0x954f3f1f),L_(0xa0e40e6d), + LL(0x479a41f2,0xdf2474e7),LL(0x1f05663e,0x3574feb4),LL(0x234012a9,0x89989069),L_(0xc2481dbc), LL(0x24c35b2a,0xf495b125),LL(0x452948bf,0x0325369d),LL(0xa43ea9bc,0x280bca9e),L_(0x8a34a29a), + LL(0x2326ccfd,0xae198471),LL(0x848b5387,0x840ea47e),LL(0xcce778e1,0x4288a820),L_(0x34cf4dad), LL(0x53f54930,0x9e011fed),LL(0x30c9f97b,0x29fd0d6f),LL(0xcba3ae4e,0xdb99670d),L_(0x1db11c4c), + LL(0x59d694e8,0x9d825f38),LL(0x2980d39c,0xc504447d),LL(0x5a3ddebc,0x9c96ad62),L_(0x7f86e997), LL(0x516005e5,0xac938f78),LL(0x7a80b2ac,0x3bbc6276),LL(0xe8b1101b,0x055eb004),L_(0x6c8daec0), + LL(0x50fa66d9,0xcaf9f5b8),LL(0x88ad0652,0x4681401f),LL(0x35f6f9f8,0xbced09e3),L_(0x51bdbe8d), LL(0x7b25a089,0xd40e66f7),LL(0xa071947a,0x63257022),LL(0x2ee8b520,0x9757d231),L_(0x4f80de84), + LL(0x822c5f31,0xdf7efaf0),LL(0x3121c652,0x39218972),LL(0xd7749654,0xb988c422),L_(0x493a2d8b), LL(0x76360207,0x98e08450),LL(0x2760de2f,0x8f841286),LL(0xcf07c50e,0xe5f81246),L_(0x1a00e240), + LL(0x9a2b0329,0x9d26d17c),LL(0x89b4fc25,0x9bc053f8),LL(0xc765d35e,0x45f96752),L_(0xbfefae3b), LL(0x6da731c5,0xf9a4089b),LL(0x22ecc154,0xcdbfce36),LL(0x5053964b,0xdcd4205f),L_(0x1e216001), + LL(0x30c80608,0x1db56abf),LL(0x7ae4875c,0xacce82ac),LL(0x4a976988,0x4fa88f83),L_(0xd67fc048), LL(0xd5a17ca7,0x49b6eedb),LL(0xedcaacaf,0x635d8bdf),LL(0xd26b609b,0x29f6f1cc),L_(0xa9ceab78), + LL(0x8a159d18,0xf6f8a0a1),LL(0x95c6ea4c,0x766b602d),LL(0x61916ad2,0x8497eb60),L_(0xb0ce6cae), LL(0x1a0eedff,0x50c80948),LL(0xa31d0581,0x811b1e1b),LL(0x4cec302c,0x0bfcd85b),L_(0x36484967), + LL(0x37db6bc4,0x6e5e0c25),LL(0x6df2fa39,0x21b92740),LL(0x248a89e5,0xdcc52026),L_(0x67b816f2), LL(0xbd55bfd0,0xee7ad3eb),LL(0x5bb4e55c,0x3cdb6fe7),LL(0xdaa70d9f,0xacc63cd9),L_(0x9155d520), + LL(0x868a4cc8,0x6abedf02),LL(0x22a83e65,0xa18aad01),LL(0xb90ac85d,0x088ae4b8),L_(0x65e3e716), LL(0x60fc849a,0xf19b0bfb),LL(0xfbebb9d9,0x9c3ff4ac),LL(0x7355b4ab,0xef331b93),L_(0xfcb3b647), + LL(0xaf2dc94a,0x4e49fdb7),LL(0x76e1b0d3,0xf8a1df9c),LL(0x94293ef4,0x588501b4),L_(0xd8359bfc), LL(0x1ef75655,0x3cd45f3a),LL(0xee63deea,0x2a08f333),LL(0x98af1b2f,0xd1f2806f),L_(0x12a331f8), + LL(0xd2c7e263,0x3577e68b),LL(0x7e2770f6,0x355f7336),LL(0xe8913f4b,0x77ead765),L_(0xe027fdcb), LL(0xac403db5,0x9a6f6902),LL(0xf459aa5e,0x8c922198),LL(0x24bf5d49,0x130316d1),L_(0xd808c825), + LL(0x672ccabd,0xe048c7d8),LL(0x33437c46,0x674f7855),LL(0x2ce661a8,0xe77ba9cf),L_(0x46b5165f), LL(0x9cd0b0e7,0xaa89fa66),LL(0xd3057aed,0xe440af7a),LL(0x142332ba,0xb60e8644),L_(0x3eb16842), + LL(0xa0b4b4f4,0x35fc5d9b),LL(0x9f0177bd,0xc346b37c),LL(0x63dcb419,0x4fc638bc),L_(0x0d4a9edd), LL(0xe8dc39c5,0xd3a1ffca),LL(0x2be34520,0x6520ec71),LL(0x6ee7420c,0x449c7ffa),L_(0xca54fb79), + LL(0x391c4163,0x447c4950),LL(0x07a8fa48,0x212fb092),LL(0xfe67f50a,0x0d70f3ac),L_(0xdbc48919), LL(0xec4b9c9f,0xc5e2455d),LL(0xc9b41ae6,0x306c9f8e),LL(0x1f329372,0xaab1f6eb),L_(0xa76cbb84), + LL(0x50bb236e,0x7f11366c),LL(0xd38d4421,0x865c47f2),LL(0x9815fc32,0x1e6e5fa0),L_(0x42bf5236), LL(0x980283c7,0x15c5a008),LL(0x03ac6a2a,0x13c27e86),LL(0x8f3eaacf,0x9eb61a43),L_(0x1a7ff3ad), + LL(0x0c067d55,0xf6ee6117),LL(0x4446a48b,0xc9f90069),LL(0x08776dbb,0x62dd1551),L_(0x856288fd), LL(0x2c6743db,0xb1d08622),LL(0x59e29beb,0x3e4f8e95),LL(0xca32b4fd,0x1744a1d3),L_(0xad3745b8), + LL(0x4ef78890,0x3831190a),LL(0xaaeece81,0x44c9a76b),LL(0xd465548a,0x6dc6a194),L_(0xdbb627e1), LL(0x18f3c7f1,0x91571bcb),LL(0xf5fb9008,0x31e00308),LL(0xf421b41f,0xeaac6d91),L_(0x01604108), + LL(0x72bdb3aa,0xa2f0a871),LL(0x276d7a20,0x680da72c),LL(0xa823fb58,0x507ee8a9),L_(0xe6fef46d), LL(0x9c541554,0xa385d033),LL(0x2785c811,0xdf53b551),LL(0xbcf3686a,0x8ac8344a),L_(0x3bf9ea41), + LL(0x450260e1,0x8075a440),LL(0xfea1ac4e,0xe6e29d49),LL(0x0fedea77,0xb3c70edf),L_(0x2398f701), LL(0xa3d35062,0xbbbf63ab),LL(0x9c1eb75a,0x62e94dcf),LL(0x9c3a2d57,0xee68eb75),L_(0x4d73d0da), + LL(0xbcef4afe,0xe663f1d7),LL(0x31f69d33,0x6b81992e),LL(0x46cf68c3,0xc7fa33cc),L_(0xb4e3665a), LL(0x0a54ba22,0x48f183b6),LL(0x154b0c79,0x17fddba7),LL(0x32607f61,0x1e044a43),L_(0xc1030470), + LL(0x5565823c,0x25aa9de0),LL(0x88786097,0x3798fe3f),LL(0x045b969a,0x2e64a0a5),L_(0x921c1980), LL(0x89334dcd,0x8b058ded),LL(0xbe46c84c,0xbe78b8bd),LL(0x5b271860,0xfe16e851),L_(0x48f0acc8), + LL(0x11ee6162,0x31bafd7e),LL(0x7c0c6e0d,0xc8efb7fd),LL(0xe2d4fff9,0x2b1da468),L_(0x95ee5ad6), LL(0x82ecd1e6,0xfebeb584),LL(0x307f35dd,0x3c68f532),LL(0x406d6f3a,0xe2245982),L_(0xd6be6d55), + LL(0x979df4a2,0x002c4e27),LL(0x4f02beba,0xf600aa2e),LL(0xc26d73f0,0x21de614f),L_(0x38b705d3), LL(0x13b06b78,0x23429db6),LL(0xf4967923,0xa3e9a4f2),LL(0x198f9eed,0x9eb6af93),L_(0x6bb259cc), +}, +/* digit=2 base_pwr=2^14 */ +{ + LL(0x6f5b4a5a,0xdcabdf3a),LL(0xd382ee31,0x1e2db542),LL(0xeeccf680,0xe97abee6),L_(0xc6941824), LL(0xc6749744,0x47a3192f),LL(0x7f45fc06,0xc0f578ba),LL(0x7b1af995,0x4d9341e8),L_(0x248e916d), + LL(0xdde84f14,0x082378c2),LL(0x4bf3bcae,0xaf15229f),LL(0x82c65899,0xb15f6e52),L_(0x5919e8e7), LL(0x6798e12c,0x6c251212),LL(0xce97fdbe,0x696c3757),LL(0xf8d74875,0x1738524d),L_(0x44e69e4f), + LL(0x9c3b9c4f,0x54e9eb41),LL(0x1bc6447d,0x2ee02fd1),LL(0x65482175,0x63694975),L_(0x72869bff), LL(0xb7191008,0xf6aea0b9),LL(0xa70d16cd,0x5bd0a826),LL(0xa212780d,0x14730725),L_(0xdc25b909), + LL(0x09a50ad3,0x8d673442),LL(0x01c6af2b,0xc4f517cc),LL(0x24e6fbcf,0xc6a67d3a),L_(0xbbe5e1ed), LL(0x8492568c,0x964e75d1),LL(0xb97b0d10,0x09dfd2ce),LL(0x09007531,0x67a932fe),L_(0xc85f611d), + LL(0x7d086ac1,0xfaef942c),LL(0xfc2eb46d,0x4a2d4ce4),LL(0x51096873,0x75df38bf),L_(0x75ab062b), LL(0x6825bc8a,0x1f5151d2),LL(0x587ef818,0x0a14774b),LL(0xf3f93877,0x0eae8822),L_(0x5b5cb708), + LL(0x2f159690,0x36982470),LL(0x165fe970,0x2b470b0b),LL(0x2ff27509,0x89cd99ad),L_(0x98c66330), LL(0xc33eb1a9,0x0397edc7),LL(0xd2a0cfc6,0x868918fb),LL(0x7e36813d,0x722feffe),L_(0x829c6b89), + LL(0x5c8de701,0xe76a6990),LL(0x394ea602,0x568ac304),LL(0x1348f9f4,0x34e40071),L_(0x3b2e0279), LL(0x6e909cab,0x5da0385c),LL(0x0b77484a,0xd9ed956a),LL(0xbbb8ff2e,0x7e2ac222),L_(0xf54f007f), + LL(0xe5f3820b,0x306867f0),LL(0x271f814c,0x5fe6163a),LL(0x455790c2,0x038f4fe6),L_(0x58008770), LL(0x2a2eebb4,0xa3ffa255),LL(0x2ae5134e,0x4eecbe86),LL(0xfa061ce0,0x2bb3a978),L_(0xa4fe1b53), + LL(0xcfa6c306,0x1840dd3f),LL(0x24b14e0e,0xbd1f6ada),LL(0xc72a3b9b,0x5ca5c5d6),L_(0x8625f308), LL(0xdf5f8793,0x6afba384),LL(0x5e8c195d,0xd59557a2),LL(0x6bdd2d33,0x0975350a),L_(0xeff53d99), + LL(0x35527ee1,0x3fb95972),LL(0xc84c9bda,0xaea90e2e),LL(0x172afe3a,0xd069e505),L_(0x2d143bfb), LL(0x7231a957,0xaf5715f4),LL(0x9c2db5f2,0x7e8468f0),LL(0x6e7b80b4,0x71ec23d9),L_(0x4f3f9687), + LL(0x1034850b,0xf5d591b7),LL(0x0c9c04f2,0x3e07210b),LL(0x6d31163d,0x530f24db),L_(0x66c42b68), LL(0x7457ed53,0x1378c67e),LL(0x777097e8,0x8164d6d2),LL(0x3f1062b9,0x9ee5175c),L_(0xb09a9492), + LL(0x20bad002,0x12b71603),LL(0x0ee3063d,0xd5045d6c),LL(0x2261149a,0x853772f7),L_(0x8f349671), LL(0x9ec1ef24,0xdd3b39e1),LL(0x3acb7c05,0x02d7c1cd),LL(0x34c3e767,0x9381a0b0),L_(0x74081fec), + LL(0xfcd9c832,0x49667bc0),LL(0xd57108d0,0x9658b33b),LL(0x6834cfcd,0xf7fb9009),L_(0x9b0baa9c), LL(0x352f5036,0xd797b7f8),LL(0x13c1353f,0x3152ce4a),LL(0x6f581f80,0x48a60c42),L_(0x7f9e960b), + LL(0x00259aa6,0x474d3703),LL(0xcfd42398,0xd3db7f63),LL(0x1c1a54ad,0x3c4fd36b),L_(0xd3eac930), LL(0x79efe57a,0x7c4dc3a3),LL(0xdce7096a,0xfbb39dec),LL(0x732dfde0,0xa1787513),L_(0xe804b476), + LL(0x0535a13e,0x926b6b5c),LL(0xe5f713d5,0x96e21c9c),LL(0x3d019dde,0xd52c15ec),L_(0x3e7f7e62), LL(0x883a0c0e,0x6609394e),LL(0x694f2696,0x9ff80d9a),LL(0x69aa76bd,0x07cee438),L_(0x234e3949), + LL(0xae230adf,0x90a49b52),LL(0xf501aeb8,0xdfc8b644),LL(0xc50fe003,0x8b89e79b),L_(0xa04a6f7a), LL(0xc225c287,0xff3922dd),LL(0xc4ed1911,0x0cd4b29f),LL(0x0ce76929,0x8af23a3e),L_(0x918974b5), + LL(0x3d52ecd2,0xdfd72a7f),LL(0xdea21ead,0x7da62126),LL(0x8e3f7ba7,0x1f678c3b),L_(0x6df4e74e), LL(0x22dc8168,0xc5a010e6),LL(0xd7eea56a,0x54e30f4f),LL(0x389d8453,0xc6ed7b9d),L_(0x2e489cfc), + LL(0x80f6e62d,0x914f8bfd),LL(0xbcee9591,0xa0be9a1f),LL(0x7fab5561,0xec5af129),L_(0xd4d265a9), LL(0x3327e887,0xc74bfc93),LL(0xd2bab14c,0xe716458b),LL(0xe6b2e9c5,0x77d00d82),L_(0x161eafab), + LL(0xe139a461,0x8fb0ef8c),LL(0x5b2aa48c,0x622967d6),LL(0xe9937cc2,0x00ef4c97),L_(0xb862b86d), LL(0x42bfb0a9,0x97617d08),LL(0xfe0c2928,0x4f55cab8),LL(0xce44e424,0x625a38ef),L_(0x8594c3af), + LL(0x239b2f0b,0x1b735668),LL(0xbbf9ef82,0x066337ae),LL(0x754e211c,0xf058688a),L_(0x95864d69), LL(0x39a1596b,0x8beee136),LL(0x9150359b,0xd3b81681),LL(0x0ab949fd,0x3f4ac39d),L_(0xf6d5f8ee), + LL(0xad05618b,0x4aaed3cb),LL(0xb594cda0,0x3d341ce5),LL(0x0216bf14,0x9e271d0d),L_(0x7efe2b03), LL(0x68f95031,0x6a084fdc),LL(0x824376da,0xcda2825c),LL(0x6acd2b86,0x2deabee7),L_(0x55b4713a), + LL(0x7d01995f,0x9b5408d1),LL(0x5ffa275a,0x5103e5b4),LL(0xfa6d3b64,0x3f3eff6d),L_(0x5bf0abda), LL(0x13a776d1,0x97b27239),LL(0xcf4c8232,0x22a3f2f2),LL(0x170c8de4,0x047d7294),L_(0x43f7fc78), + LL(0xab797a07,0x0b00d0bd),LL(0x4d42a1fe,0x92ead9f6),LL(0xc3907782,0xd65498ad),L_(0x716502c0), LL(0x814b71a4,0xaa83d0a9),LL(0xd8e4c681,0xaf90bf17),LL(0xb2730e91,0x3b7c8d6f),L_(0xc3d966b3), + LL(0x8da671b5,0xfee99849),LL(0x2e099be3,0xdbbe577f),LL(0x5f8e6df6,0x31915ae6),L_(0x2ba98b17), LL(0x0d5b6ffc,0xe2f20ab0),LL(0x791aa104,0xdc69cc94),LL(0x2ae23401,0x5c5045ab),L_(0xd646c528), + LL(0x93077179,0x50b8339a),LL(0x2874cd90,0x05d7c4a6),LL(0xcb1961a7,0x221ee1b5),L_(0x43f06891), LL(0x0a41aae9,0xf9998038),LL(0xeac42395,0xd6ac7543),LL(0x042a0af5,0x36489fc2),L_(0x5fdad7bc), + LL(0x3c56133d,0x9f01cd48),LL(0xc0ba445f,0x29263bac),LL(0x3e5d8713,0xc6107ee1),L_(0xecfad04a), LL(0xb648509b,0x45f6365f),LL(0xeda195e8,0x4716fd8d),LL(0x2f2caf71,0x4fc9d505),L_(0x0c644ae1), + LL(0x510aa881,0xbc63e799),LL(0x658bc0b0,0x4716a31d),LL(0x2713db77,0xabf827dd),L_(0x12824e7f), LL(0x5c30bb60,0xb2616194),LL(0xfcdeef4c,0xf6fd28f3),LL(0x3fa68909,0xe9395e01),L_(0x42dfc220), + LL(0x91f7da3d,0xe6bee7b8),LL(0xb1959a03,0x303e2e61),LL(0x9b779901,0xe7e57056),L_(0x1c2d553f), LL(0x9abaa6a1,0x47995b48),LL(0xab4d653f,0x6d28c851),LL(0xf8e40f18,0xb70d2132),L_(0xbaae5b9b), + LL(0xc8d7fa04,0x325e475b),LL(0x8ad5b01f,0x8d0c0363),LL(0x8fb55f0b,0xa691b273),L_(0xee832613), LL(0x3a711dab,0xb146b4e3),LL(0x748d793c,0x81182539),LL(0x2911a867,0xdb940971),L_(0x24df2ed3), + LL(0x0b071d1f,0x25961d64),LL(0x87754320,0xc47ba4de),LL(0x15d5a2ff,0xee280f81),L_(0xfc4877e3), LL(0x1fbba89c,0xd08afabd),LL(0x8dd2825d,0xc881c4eb),LL(0xa36fe3f2,0x20840934),L_(0x398c3272), + LL(0x13806339,0x51502992),LL(0x5f9bec8a,0x1bb87fb3),LL(0x878f8530,0xbcaa2cbf),L_(0xe99dba0e), LL(0xde118aef,0x7a185dc3),LL(0x7f95d77f,0x2ea5905d),LL(0x3f419246,0x2b04f2d5),L_(0x7b04c078), + LL(0x0fd96b35,0x597ba0a8),LL(0x0eb981ea,0xb6624fc6),LL(0xe6e26240,0xbfc4dac6),L_(0x35dd20af), LL(0x61745187,0xe7b40563),LL(0x8d381cfb,0x554c1adc),LL(0x4013b9ec,0x354e81ee),L_(0x50a8d84c), + LL(0x098f1196,0xccc6dc56),LL(0xe6735e77,0xe9fcb8bf),LL(0x629efebf,0x2ffffa9f),L_(0xc520680b), LL(0x6d812701,0x732a53da),LL(0x4d7d1ede,0x248c465e),LL(0xa1f8c1a5,0x3dffe6e5),L_(0xc519ac0b), + LL(0xcaf0a9d6,0xaef46030),LL(0xdd8a57c6,0x739000fd),LL(0xb0540672,0x8ef45968),L_(0x7dc6abd9), LL(0x33da5d1c,0x5aafa6a3),LL(0x60865fae,0x6662d3dc),LL(0x9c28cea0,0xd3cb6b76),L_(0xbbb47176), + LL(0x93070274,0xfe93910c),LL(0x86c3c000,0xd939b811),LL(0xe4bdec34,0xa7194bcc),L_(0x308782a6), LL(0x640b22a9,0x710f1668),LL(0x1c395e5f,0xec57d6a5),LL(0x2f41d5d8,0xe7981956),L_(0x53f886b7), + LL(0x67aad45f,0x6d08786e),LL(0x2cc15260,0x8bf6b065),LL(0x84169282,0xa53ab3f4),L_(0x49111025), LL(0x714a4d69,0x8db73ccf),LL(0x49ee5fc0,0xaec354d3),LL(0xeb0a609a,0x26497f34),L_(0x752e2221), + LL(0xbc1c0e24,0x23ccf8a7),LL(0xb6e96781,0x8d254256),LL(0x183ac489,0x907018f8),L_(0xf0ef92fc), LL(0xc98e1d84,0xac3eb092),LL(0x63c56eb0,0x61b00609),LL(0xf8deac28,0x95f55a52),L_(0x5ae62b60), + LL(0xa101bad5,0x8575f396),LL(0x643e6356,0x75613315),LL(0x3b84d8ca,0x87159fb6),L_(0xb1bb3787), LL(0xeb901a9a,0x04257ae5),LL(0x76cc23a1,0xc722a719),LL(0xf70dd339,0xd9298acd),L_(0x91c26db4), + LL(0xbcfc15f8,0xac24fa28),LL(0xa4b011f9,0x9cf8c10a),LL(0x77f2a9a2,0x897d9044),L_(0x0ed14d52), LL(0xe210939f,0xa6397972),LL(0xe2308c70,0xc34aac84),LL(0x72030316,0x664a26ca),L_(0x291e9903), + LL(0xd67a8d4c,0xd3c9cb6a),LL(0x38755541,0x115ea4ff),LL(0x4ad0effb,0x5c237f2b),L_(0x75646bb1), LL(0x1c0c1001,0xa07ca1d3),LL(0x7f647322,0xc00e9dcd),LL(0xe24ec66d,0x819d18b8),L_(0x95c255a0), + LL(0xd48e2f95,0x8209864f),LL(0xddb2d835,0x9d8a81eb),LL(0x41d055f3,0x92d42e0f),L_(0xe2f17df9), LL(0xdaf29a59,0xc2c8d2a6),LL(0x061a667a,0xd108615b),LL(0xcc790c1c,0x0eb1df27),L_(0x6dc9536e), + LL(0x5d7251ce,0xf7ca409f),LL(0x55a94793,0x8791f913),LL(0x6bbc768b,0x1ef210b3),L_(0x166d8931), LL(0x24baa65a,0xa0bcf014),LL(0x621f63a2,0xa8abe2d3),LL(0xf790fc9d,0x60203dd4),L_(0x667b1fa7), + LL(0x77f64ca2,0x2884e5da),LL(0xc59a883c,0x38a09cd0),LL(0x47f89d65,0x780aeefd),L_(0xd528d23d), LL(0x9945faad,0x90523929),LL(0x6e9ee32f,0xa460502a),LL(0xb5fe2f01,0x1d21d327),L_(0x2883e925), + LL(0xc3ff6cb2,0x8d7cbdb6),LL(0x32e5cd9d,0x2baad720),LL(0x2385860f,0x43f0f911),L_(0x4b6038f7), LL(0xe096aed9,0x8ece6e04),LL(0x40da7078,0x964d3a26),LL(0xa20a6649,0x1a09dbaf),L_(0x709cfd74), + LL(0x4a5af8b1,0xa2ce00d8),LL(0xa63a8b02,0x57b8f935),LL(0x35cb5ede,0x706b0821),L_(0x4173e4a2), LL(0x74594a56,0xaae1c286),LL(0xaa0caca3,0xc1e054bb),LL(0x3c3b3e24,0x34698533),L_(0xe3b66255), + LL(0xcb1b2f2a,0x4bf57c51),LL(0x164519e7,0x6b4ba459),LL(0xb55fe2b9,0xd37e29a7),L_(0x68e8549f), LL(0x9b0eb441,0x9f4b4c99),LL(0x8f691f6b,0x59078e54),LL(0xa382964e,0x49524978),L_(0x7d3fe7f2), + LL(0x3a14e17c,0xb90d4bd4),LL(0x087b646e,0xac93ca7a),LL(0x53865f43,0x2d659d4e),L_(0xb9db500d), LL(0xdc91bb2e,0x17597d7a),LL(0x6ae5d43e,0xb1613ba6),LL(0x3a5e9fe1,0x4204e314),L_(0xd91a271a), + LL(0xbf7ca431,0xcfce86aa),LL(0x16c2854c,0x51585545),LL(0x3999a9a1,0x5fd18a95),L_(0xa1e55106), LL(0xd29f7bb5,0xd7192594),LL(0x7c17c721,0xb7a8c7e2),LL(0xf6856acd,0xdb82b841),L_(0x39017815), + LL(0xe9631773,0xf155113d),LL(0xc2b2be30,0x09bb3adb),LL(0x1e571839,0xa98b5f59),L_(0x17a7266e), LL(0xde672c40,0x02e9f20a),LL(0x9c53a705,0x68d00619),LL(0x476b9b10,0x144091ad),L_(0x98e56e88), + LL(0x4746f916,0x02f6a9c6),LL(0x461d2e37,0x6a692ac8),LL(0x6fe1c2f9,0x8835c958),L_(0xaae29f67), LL(0xaa57aa25,0x1573f8b0),LL(0x2aae0885,0x8359860b),LL(0xc9a1230d,0x930776e9),L_(0xd3f32fd7), + LL(0xda3f170d,0xdbf89586),LL(0xfeac4726,0x6f39cb19),LL(0xe907285f,0x084c5773),L_(0xc72ade03), LL(0x2f55c6f0,0x155c7e90),LL(0xe4fb90c2,0x50f9f0f0),LL(0x833af29a,0x87b3ac91),L_(0xeeb712d2), + LL(0x1b2f2123,0x08fa5175),LL(0xad400dee,0xe9ac51f9),LL(0xdb50d10c,0x8bbf71ad),L_(0x1322cb4e), LL(0x3efa91c3,0xb7ef36d2),LL(0xa5571f80,0x4c6187ca),LL(0x938aa540,0x6a106d1c),L_(0xfee7b99f), + LL(0xc717d42e,0x0d738fbd),LL(0x9340ad37,0xf74cbf89),LL(0x923ef854,0x1a934a84),L_(0xdc9bcb14), LL(0xf0ce91b3,0x3ed1d40f),LL(0x3e3d69c5,0x35833a46),LL(0x8cf302d1,0x60492caf),L_(0xee0ad716), + LL(0xf9f98ca9,0x310d3206),LL(0xc40b6b35,0x67ddb804),LL(0xf6b370b9,0xcf2da667),L_(0x4a7e6061), LL(0x57730157,0xd8d48240),LL(0x186ae81f,0x002b8bc3),LL(0x2133c198,0xa42e3f3d),L_(0xf8b9b6ca), + LL(0x1ba04233,0x9ac56b2a),LL(0x55759656,0x927ea140),LL(0xd47c70b0,0x0f258220),L_(0x06bffc7e), LL(0xe94dda94,0x453179d9),LL(0x92ffe53d,0x2b54517d),LL(0x2ac0af28,0xb924dbee),L_(0x7afd903c), + LL(0x7c5bc163,0x7d2123b3),LL(0x61435520,0x1d58d680),LL(0x2b094145,0xeb4a95b5),L_(0x09b8c6a3), LL(0x3c690f29,0x54e52454),LL(0x646b89b4,0x6bd00cf3),LL(0x2640a633,0x17b930ad),L_(0xa457233d), + LL(0x05fb72f6,0xbfa90c2b),LL(0xfad26494,0x9f2c3cd4),LL(0xbfe60269,0xcd907456),L_(0xb3e48eca), LL(0x6374f2bd,0xdf9ab844),LL(0x94fe7551,0x36c69779),LL(0x8ed01908,0x5a97c45a),L_(0x5dbf5641), + LL(0xa14499cb,0x9dc2ad99),LL(0xe9019e0a,0x64554a27),LL(0x588acbee,0xfff03f99),L_(0xc48117a2), LL(0x46bb4b9c,0x6e713362),LL(0x59d13072,0xfb7747ec),LL(0xc63c7628,0xefa02cb7),L_(0x39d7f934), + LL(0x69d702d8,0x5f6d09ba),LL(0x2361ada1,0x920262ae),LL(0x5419445e,0x6f750612),L_(0xa30fa392), LL(0xcf460268,0xd59c34bc),LL(0x32785073,0x76b69628),LL(0x72c99605,0xb431b539),L_(0xeec4de29), + LL(0xc39fd75e,0x97507c26),LL(0x0c5debbb,0xd82ad3a6),LL(0x3c42310d,0xa01f4d9e),L_(0x5fdffd07), LL(0xd1fedd01,0x5e2bab3e),LL(0x4ce43e20,0x8abe3a41),LL(0xe71cd8a2,0x0c4858ed),L_(0x8bd12b19), + LL(0xbb2c8805,0xb6380f03),LL(0x59339488,0x7a463ca9),LL(0x920e2111,0x0fbdd870),L_(0xcf927c12), LL(0x9fa1e546,0x4ea01a50),LL(0x20ee4123,0x38b747c2),LL(0xeeedf23b,0x65fa7940),L_(0x82b08346), + LL(0x6a22e6e3,0x34651055),LL(0x1098cb76,0x269d82cd),LL(0xd6a624c2,0x5fd458b6),L_(0xb856ae59), LL(0x6c36cae7,0xd687ba3d),LL(0x33a82abc,0x6963f047),LL(0xa949d735,0x1de89776),L_(0xc44fd2cc), + LL(0x23ce7894,0xc54039f7),LL(0x1ad9c99d,0xaba8109a),LL(0xa0ae59e6,0x5269a308),L_(0x65e4eb8f), LL(0x63914a92,0xe212c370),LL(0x2c3e1f0e,0xcaf748c2),LL(0x8869d4e8,0xc88e85fd),L_(0xbc2a9592), + LL(0x0874ad96,0x0f4e6e42),LL(0x2bfeb37b,0x3e5a96cd),LL(0x6bb45b1b,0x53c918ad),L_(0xb8bd0546), LL(0xfd07d3ba,0x0e33f7bc),LL(0x9e58beb5,0x58f58e4a),LL(0x26578e47,0x986f5206),L_(0x90135d8a), +}, +/* digit=3 base_pwr=2^21 */ +{ + LL(0x089bae53,0x4190a603),LL(0xec5c8b6b,0xa64a64f3),LL(0x8bca6d9c,0xba9eddb4),L_(0x3ebc0dcc), LL(0x9555731f,0xa709d0a0),LL(0xc3d3be2f,0xa147a9eb),LL(0xdae0ded6,0xf474acd5),L_(0x965b8988), + LL(0xa9158749,0xfb05e5ec),LL(0x7df5ec60,0x5b8ef888),LL(0x2d8170fd,0xd08f651c),L_(0xe08fb325), LL(0x1ccffe04,0xa2b2a173),LL(0x20fa30ea,0xe5f33422),LL(0xd169c10d,0xc7e20c19),L_(0x366327ee), + LL(0x5d85ed76,0xf62aa1bd),LL(0xe359773b,0x38737578),LL(0x2b782c08,0x31df9439),L_(0x80e166af), LL(0x673b4b07,0xa7a7bd40),LL(0x50ca47c9,0x95ad7602),LL(0x8ed45ebe,0x4a7eebb4),L_(0x03e9fc9d), + LL(0x33fde338,0xaba113fc),LL(0x0e6fb34d,0xc0022adf),LL(0xe2da2a97,0x491a39ca),L_(0x54e2ec96), LL(0xb883d291,0x3d0946d9),LL(0x6f792b36,0xd8794d71),LL(0xd78ca8ec,0x13094248),L_(0x286898ab), + LL(0x0c894527,0xb354ae4c),LL(0xf18c6f77,0xa39fcad9),LL(0xf685126a,0x7bd039dc),L_(0xfb3809c0), LL(0xe8ec1ffb,0xc99f8944),LL(0x7c71a341,0x08ed706a),LL(0x21f4ed22,0x4c371e86),L_(0xa650cd97), + LL(0x64586632,0x8e7cfcb0),LL(0xfcae4f5c,0xe83d4510),LL(0x62196ce2,0xc9a4fa0c),L_(0x83e1de7b), LL(0x4871e08f,0x8f0bc09a),LL(0xfa78f5d2,0x1e32cbe6),LL(0xda32a5ee,0x23d217eb),L_(0xf8df814e), + LL(0xefdc00b8,0x80a1f116),LL(0x670e56db,0x0b205db0),LL(0xd1c521ab,0xcaa4c48a),L_(0x41b37b7f), LL(0xde1b3d20,0xf6421dce),LL(0xafa1a3e7,0x906ec304),LL(0x5c6bc442,0xbc2935cf),L_(0xbe169cc3), + LL(0xa597c946,0xe5876159),LL(0x308bf446,0xcc637e99),LL(0x8047e56a,0xdb6a36f6),L_(0xe8293346), LL(0x51f3fb7c,0x93a30fbd),LL(0xcd2f5b41,0x3e0a22c7),LL(0x0b7b25a0,0x3d9fe740),L_(0xaafd7816), + LL(0xe59f76ea,0xc167cd8d),LL(0x0d3f30f7,0x07b77d41),LL(0x3b140b84,0x6554fb45),L_(0xc105ccc8), LL(0x72d13268,0x69c72227),LL(0xf0450467,0x0ba87831),LL(0x88e4350b,0x1e0bbd29),L_(0x6f9f2dff), + LL(0x8eb3482c,0x1e9d015e),LL(0xf4db6e3d,0x3a6f5318),LL(0x60df1945,0x91e766b6),L_(0x2499a2cf), LL(0xe58a4308,0x0468acbe),LL(0x7a3c83da,0x9eeaeaca),LL(0xfeedfeca,0x95c8fd77),L_(0x9f35aedd), + LL(0xdf4b1836,0x1d85a174),LL(0xefd882f6,0x2cdd973c),LL(0xfcbc0529,0xff17a943),L_(0x6d3cb4e6), LL(0x7dbddba8,0x1d223311),LL(0x680691e3,0x6b1fb1d6),LL(0x2d7d7413,0x3d6056c3),L_(0xf379f1df), + LL(0x75f0d3c3,0x5a2e3385),LL(0x66a60d5f,0xa99c6fca),LL(0x08231783,0x2621fe6f),L_(0x282e92dc), LL(0x9beb8a2d,0xa53267dc),LL(0x48813229,0x2abc54c5),LL(0x18f63ff9,0x25a10917),L_(0x06fdd515), + LL(0xd5250739,0x866c8a6c),LL(0xb47ff8e8,0xe99cef30),LL(0x360eff22,0x64925640),L_(0x392f59d5), LL(0x58d96359,0x18c35e2f),LL(0xe8c753dd,0x5ea13624),LL(0xeef6fc01,0xdf425955),L_(0x3afc5278), + LL(0x6599bea3,0xedc68cb7),LL(0x69d044d7,0x3950ba3f),LL(0xb3b58152,0x8eb64dda),L_(0x49c378c0), LL(0xfcacec23,0xaf6b16d6),LL(0x47e931cc,0xbc7d2577),LL(0xcb7189bc,0xa9051236),L_(0x2aca5249), + LL(0xb4223fb7,0xad339986),LL(0x9bcc65a5,0xe221979a),LL(0x278964b2,0x7810f1da),L_(0xf8f2be96), LL(0x225ed2c6,0x7e983036),LL(0x59fa9f23,0xfcfa0c31),LL(0xbc86f69d,0x918a9c4a),L_(0xb726eddd), + LL(0xcabaac34,0xac70d023),LL(0xe4e20984,0x7fc6e9c4),LL(0x0ffac935,0xcce8d103),L_(0x6efdaa99), LL(0xd5d8263d,0xea3876d9),LL(0xa0b5e29a,0x1319056a),LL(0x65ae7e78,0x9fa645d3),L_(0x93cb4927), + LL(0x09cc8e5f,0xac6cb27b),LL(0x414e945f,0xb503f62a),LL(0x73d9e98e,0x4809a03f),L_(0x2d14c85e), LL(0xbf213bd6,0x0b05bc27),LL(0x74a3b39b,0x4314e710),LL(0x003b8462,0xed2336e3),L_(0xc6f085ad), + LL(0x3c7d36a1,0xd9687e2e),LL(0xd82a965c,0x7a3f9fe9),LL(0x088401a6,0x068fa075),L_(0x07ba4f19), LL(0x0f0c8a66,0xf91cec2f),LL(0xb6cda991,0xb14b14fb),LL(0xa7b1febe,0x50d069b1),L_(0x5d3d8cd6), + LL(0x10626da8,0xf8949e74),LL(0x5c71b954,0xbe5cd298),LL(0x28006acc,0x6ba62a11),L_(0xe08cb4da), LL(0xe8cb22bc,0xc4d932f1),LL(0x9059e525,0xb085b630),LL(0x72f4258d,0x4cc4c854),L_(0x0a971745), + LL(0x1acb63c1,0xdaf48ca2),LL(0xa543ba94,0xe2648935),LL(0xd71707e5,0x809ef386),L_(0xe30d9ba3), LL(0x12555c2b,0x69eeeae4),LL(0x6910f9ee,0xea668f6a),LL(0xe8c90ba6,0x1896385f),L_(0x12c1a610), + LL(0x9f5a846d,0x2d268c8b),LL(0xd0a57e22,0xf1a092e2),LL(0x907afb7b,0x927d9d98),L_(0x4fb8839b), LL(0x54540741,0x967900e2),LL(0xa9ff207a,0x628af581),LL(0xee9dbe19,0x1bad27e2),L_(0x37d4f91b), + LL(0xd5bb2ea9,0x6069565b),LL(0x7e61e032,0x973dd1c6),LL(0x1034f977,0xa6921003),L_(0xf41e571f), LL(0x58bdabb3,0xeaa8bfa5),LL(0x77a67171,0xe71c31a6),LL(0xf9f34af4,0xa78106eb),L_(0x7aed89ac), + LL(0x9de5d621,0x8c1c931d),LL(0x2befbabd,0x5b08557f),LL(0x7e64aafe,0xb97c5d4d),L_(0xf99509a4), LL(0x10d5a953,0x7372eddc),LL(0x47ce48d3,0x24c1d7d6),LL(0x28b7f369,0x1fd874f8),L_(0xfdab8a95), + LL(0x886ba3df,0x7f6337ce),LL(0xe5943606,0x7b3e3023),LL(0x21b5b09f,0xa28353d5),L_(0x917b4519), LL(0xd1005ca4,0xfd5ad004),LL(0x73dbf462,0xc7335825),LL(0x7f25c9d4,0x3b50b66b),L_(0x35b3bf78), + LL(0x9b2e5ded,0x4b668d6b),LL(0xbe5e047a,0xd58c1f6d),LL(0x2bc0144b,0xee508f32),L_(0x9d2116d4), LL(0x7efb1e4f,0x5d9a5637),LL(0x8ab6e9cc,0xcd52f6ad),LL(0x954172ff,0x7ca23907),L_(0x9fe1053c), + LL(0x0b042690,0x711be7f8),LL(0x4c525b55,0x549592f5),LL(0xac72c62f,0x962efa73),L_(0x92c58056), LL(0xe8cda600,0xa38c53ed),LL(0x917ebbe6,0xd1e2d2e6),LL(0x6ab0ae35,0x25682606),L_(0x0603c2dc), + LL(0xd25fb822,0xb1a2e953),LL(0x22b420c7,0x030fabe0),LL(0xffe309b6,0xda6ba55a),L_(0xdce7859f), LL(0x9c46c82d,0x96d10a75),LL(0x057f1caa,0xd24573e9),LL(0x72ae9f6f,0x8794d9eb),L_(0xab64c20f), + LL(0xfc0d12fe,0xb289f4d7),LL(0xd9e2a94a,0x133fa143),LL(0x4c9fd385,0xecfdb1d1),L_(0x0675dcf1), LL(0xa5804aec,0xaccd6ef1),LL(0xfad7706e,0x577c5c78),LL(0x0667c6b3,0x7a5f797a),L_(0x2207359c), + LL(0x03a638e7,0xf3f519e2),LL(0x06628ac7,0x06647de5),LL(0xe38c99a3,0x86774ade),L_(0x8f775fea), LL(0xe57995ae,0x1bf25ffc),LL(0xf9325842,0xcccd3a9f),LL(0x34f4502c,0xabcab086),L_(0x064e829c), + LL(0x27f04a80,0x5fefab0b),LL(0x06295d26,0x2a4f8979),LL(0x234674d8,0x9c70b1f8),L_(0x01e05c18), LL(0x49f25ab4,0x352749e2),LL(0xee248ea9,0x9909ef81),LL(0x3b3c0b4c,0x7556a699),L_(0x4df0080e), + LL(0xeb394e8f,0xc8a345b1),LL(0xaf868ebc,0xbf72406a),LL(0x9a7fcfbb,0x959c94fa),L_(0xea271ece), LL(0xb72d1e17,0x1ea91da8),LL(0x252b7410,0x004276b7),LL(0x560e8135,0x8ada4812),L_(0x4d0eaa23), + LL(0x857c7d7b,0x11e78f96),LL(0x55ff3762,0xcd19ea8e),LL(0xa90b8b11,0xb557ab25),L_(0x98bfd175), LL(0x436277e5,0x453f5ec0),LL(0xbd8cc123,0x74f19c3e),LL(0xe53f50d1,0xaf6d61de),L_(0xb809c27b), + LL(0x70f6cada,0x22d1e307),LL(0xcafcf6b1,0xc39e2653),LL(0xb5d40ef0,0x602ae873),L_(0xb5bef707), LL(0x37b8abfa,0x47aa28a0),LL(0xc7e7a44e,0xfe824073),LL(0x9f424f8c,0x39a88470),L_(0x08171c6a), + LL(0x80811691,0xd43ff3e6),LL(0x5bfd96fc,0xb502656b),LL(0xa9d5f891,0xeb92efe6),L_(0x5ac4853d), LL(0x1f5ef580,0x90443655),LL(0xe8ead180,0xb1c5c5f0),LL(0x84a289e5,0x98bbea4f),L_(0x8bd0878a), + LL(0x7035018f,0xd233645a),LL(0x2cec3fe7,0x567fe1b2),LL(0xc6974f80,0xc7a73902),L_(0x0b481a08), LL(0x9adde606,0x9eb32485),LL(0x9b2ec275,0x16392d5c),LL(0xdb3bea46,0x0653d374),L_(0xab7f0ce3), + LL(0xe1cac3cf,0x89e007fd),LL(0xa77a41f1,0x3300e242),LL(0x6059351c,0xed2ec819),L_(0x02bfa9e8), LL(0xba1e89c6,0xa9065e31),LL(0xd4e23efc,0x6a1da501),LL(0x9c16b8bc,0x465d2c9d),L_(0xa1b1cda1), + LL(0x9ecf8570,0x54df839d),LL(0xb93666fd,0xb9514f4e),LL(0x1fed47ac,0x7e8268de),L_(0xbda2efca), LL(0x5da57404,0x428af14c),LL(0x9ee2b07c,0x1471974b),LL(0xda44c29f,0xfffd22e4),L_(0x296f1761), + LL(0x917860b8,0xb42b17e2),LL(0x6d4c5ddd,0xf2571ed2),LL(0xabe94b27,0x89be3310),L_(0xde98e510), LL(0x346eec5a,0x9d4ca35e),LL(0x96df2661,0x11588b07),LL(0xb28f2b86,0x96395d9e),L_(0xc8d9fdcf), + LL(0x031a12c5,0xdbc075c3),LL(0x54d26d6d,0x6ab8c6ef),LL(0x23c171f2,0xca47c96b),L_(0xecedbb06), LL(0x8c7cf280,0x31539156),LL(0xe9bac065,0xb7662b30),LL(0x552f0920,0xef1cbf3a),L_(0x2cb42440), + LL(0x9fba2bd9,0xed539df1),LL(0xd5c7355c,0x718a4f45),LL(0x5ced43ea,0x10d60144),L_(0x9618c03b), LL(0x55e1556d,0x8b9bcb4a),LL(0xe3767fbb,0xf1a46d41),LL(0x2a5c6f77,0x8a009344),L_(0xa23cb6b8), + LL(0x0db9a0c8,0xfd4a0f59),LL(0x7ea78a85,0x4d12f34e),LL(0x258d360e,0x951a2674),L_(0x7b3935b0), LL(0x4a231357,0x75e447f0),LL(0x80a9bfbf,0xc988c231),LL(0x8cd933d2,0x1c914702),L_(0x8da2914d), + LL(0xbe785bb8,0xbb8f1e8e),LL(0xbb61ba00,0xa9e04405),LL(0x018ee54b,0xf3ed084b),L_(0x9b33e2c5), LL(0x796aad53,0x90c49201),LL(0xdac991d0,0x9174f367),LL(0x06286fbc,0xfa92d2f7),L_(0x8e51716d), + LL(0xce4d1ca0,0xcd0c67a7),LL(0xe3fcc974,0x5197d346),LL(0x4936eae1,0x38aec941),L_(0x49b20db5), LL(0xf9c12e70,0x8806a867),LL(0xfd73d3b4,0xfe592936),LL(0x8553e67e,0xbb731824),L_(0x5f399b3f), + LL(0x7afb78c1,0x04dbb078),LL(0xd2ce86a5,0xbe71dc62),LL(0x636ee6c6,0x5c029f32),L_(0x90ef1fcb), LL(0xa90f74fc,0x05c18efb),LL(0x812addf4,0x86cc7880),LL(0xdf2ff660,0x34c03bb8),L_(0xb1740945), + LL(0x642146f4,0x18fd7ff7),LL(0x8a416ad5,0x8b9a8120),LL(0xb7d2ecb8,0x8226e0af),L_(0xbb5fb220), LL(0x7d62e2a5,0xcaee42bb),LL(0xb76b0d06,0x9ae1502d),LL(0x31322587,0x678f208f),L_(0xa07b89ea), + LL(0xdd6c08b2,0x5899ed84),LL(0x45083585,0x50d7aafb),LL(0x7217b173,0x04f9e7f1),L_(0x59198da1), LL(0x5dd6befe,0x11d6cf0e),LL(0x908d5768,0xa9128791),LL(0x51f15b45,0x7dd32a0d),L_(0x58045077), + LL(0xafc5b319,0x885c6636),LL(0xf7bef8ba,0xc50dd479),LL(0x478b8ac8,0x58aa9fce),L_(0x9d21686d), LL(0xe233d315,0x541006e3),LL(0xdfc86dcf,0xdfefb8ef),LL(0xe98f7f2c,0x73e745a7),L_(0xfc620932), + LL(0xbda630b0,0xd49816e2),LL(0x68c388d9,0xabd8c48b),LL(0x741de91e,0x3b976a04),L_(0xf24259fb), LL(0x5a923f4f,0xcbbf2684),LL(0x56659522,0x8a51b8af),LL(0xea31954e,0x43c8b17e),L_(0x3d1de35f), + LL(0x1067b268,0xddd685da),LL(0xa178f2e3,0xe840e9b4),LL(0x859daa46,0xc3965546),L_(0x65f74f36), LL(0x3ebc87fc,0x31952a50),LL(0xd0b694c6,0x2ba1d2d4),LL(0x4f51b3a3,0x20b2748b),L_(0x54b61458), + LL(0x450b7ea8,0x91be987e),LL(0x92390774,0x530b2e3f),LL(0x31cf3730,0xd8dc53f9),L_(0x490c450f), LL(0xe4e70ece,0x604fd792),LL(0xb689243f,0xa20bf532),LL(0xb2d8f482,0xdc31ef3b),L_(0x506dd3c6), + LL(0x89cb2010,0x1196c48c),LL(0x6755b53e,0x59cee16a),LL(0x6a0e74ef,0x2da63e64),L_(0xaa8ea0cd), LL(0x661a0e7f,0xb013649e),LL(0x1ab0635d,0x56e8f0f1),LL(0x9858a79d,0x65938865),L_(0x3acb5b92), + LL(0xf39d8f51,0x28b2de13),LL(0x6b120542,0xd10ea1ae),LL(0x5ea493a4,0xbe9b2f46),L_(0xcdd3cbfb), LL(0x9af8b9c3,0x543265a5),LL(0xf3a605c4,0xe8ee990d),LL(0x92bcbe09,0x1d71ae8b),L_(0x4ad0176d), + LL(0x77ad60e7,0x183493f0),LL(0x3e8ef423,0x4d9cc856),LL(0x065effba,0xa9ccf6fd),L_(0xb0500b2e), LL(0x122bf6db,0xfb31da5d),LL(0xe16bd325,0x3de8eb0a),LL(0x2bb46b58,0xcdab125c),L_(0x8179b8bc), + LL(0x72f249a0,0x54823e45),LL(0x263960f2,0xb1c1bcb0),LL(0x21ab8a5f,0x193b2d98),L_(0xb940533d), LL(0xc80b7cd9,0x7586193c),LL(0x671090ab,0x40d0049f),LL(0x216acee5,0x6bb91540),L_(0xcc4fc3a7), + LL(0xc26826e4,0x0e69184d),LL(0xe86f6c8e,0xfa8a33b4),LL(0xe88688e1,0x9beec95a),L_(0xd008257c), LL(0xa638dd0b,0x35395ef4),LL(0xacddfb2b,0x005b4fcb),LL(0x086efe98,0x8a1a0ad3),L_(0xb4d51fd4), + LL(0x9613f782,0xd8510368),LL(0xd5dedcbd,0x7ea65e3d),LL(0xab06f6a4,0xbd599498),L_(0xc5aa099e), LL(0xf3eb18eb,0x32f40f7b),LL(0xad93fbe0,0xfde611a8),LL(0x40b951f1,0xf5751752),L_(0xfc37b6e1), + LL(0xc4dba0cc,0xaae77bea),LL(0x58b91be1,0x7a9f5f3a),LL(0x6ad767a4,0x9b47cd71),L_(0x24d37cee), LL(0x7268bfef,0x70ac8b25),LL(0x2da13b60,0x16423d93),LL(0xbadf18ad,0x62a037c8),L_(0x78224e07), + LL(0x334baa48,0x6a2f2198),LL(0x1578e706,0x50c74263),LL(0xa273c223,0xe95f128a),L_(0x2b3feceb), LL(0x0c8d88cc,0x4d1450aa),LL(0x247fea5e,0xb5c004a3),LL(0xcc56e421,0x32f2d692),L_(0x001d3250), + LL(0x63905c2b,0x3d1a2b08),LL(0x1192eb20,0x7a96aa59),LL(0x194cd936,0xcbfbf813),L_(0xe3ba3ce4), LL(0xdc1fe33e,0x8d6355cd),LL(0x36393a36,0x3c74701a),LL(0x6d3b3d2c,0x50d98fcf),L_(0x2da52d36), + LL(0xa9690fb6,0xd68d0be2),LL(0x87600722,0x2fa3c8b8),LL(0x6a898b0f,0x64b1c25c),L_(0xf26df29e), LL(0x18b74321,0x0562d2ac),LL(0x116fb9cd,0x1b89331d),LL(0xadee6e40,0x19e073f7),L_(0xdcd869ef), + LL(0x39df6bf7,0xd9747842),LL(0x484e4a18,0x9ca1c1ce),LL(0x2181acfd,0x09d6f90f),L_(0xae25cfad), LL(0xc2644ecc,0xb6aa912f),LL(0xeb2922c9,0x767976e7),LL(0xbe3728a6,0x3b8ce6be),L_(0x04eb6141), + LL(0xd6e6d0b5,0x618ad07e),LL(0xc862e8d5,0x926d38e4),LL(0xca247f9d,0xaa268736),L_(0xbded92f5), LL(0x1a6031fd,0x9481e659),LL(0x42b36d96,0xc8b3617c),LL(0xabfa2ad2,0xd3f46f02),L_(0x1cbbeccc), + LL(0x2057edf3,0x2b94f0fe),LL(0x608a4b71,0x7ca57706),LL(0xdd35cef8,0x236745ba),L_(0xb4d5d169), LL(0x99412994,0x03f0b33a),LL(0x826e0d5f,0x0c5801a2),LL(0x31eb9951,0xf2cc0540),L_(0xd954458a), + LL(0xf649bf08,0x2c486c0b),LL(0xa5afc024,0x9417e436),LL(0xb063a531,0x38aa1ed3),L_(0x1558aff7), LL(0x004fbb10,0x904e9ed7),LL(0x3494f0b6,0xd2555c07),LL(0x365e3d05,0x0f32df2c),L_(0x5c8f30d5), +}, +/* digit=4 base_pwr=2^28 */ +{ + LL(0x2f432139,0x6a7ebdd1),LL(0x676d690b,0x25d6c68a),LL(0xf169ac1a,0x70ef4a18),L_(0x3fe9e66e), LL(0xa193f6f9,0x9b515115),LL(0x6b6b0581,0x4399b66b),LL(0xd0e88db2,0x52c4fcf1),L_(0x31c324fa), + LL(0x62e391aa,0x403677bb),LL(0xe67af8a2,0xcd3fd0e0),LL(0x0b4be307,0xdcb51813),L_(0x88ce9bf6), LL(0xe4877d66,0x0f788e98),LL(0x8400154f,0x1742afd0),LL(0x768edb4a,0x80428f26),L_(0x277da6c6), + LL(0x0b15cc70,0x6933e246),LL(0x8f4bec34,0x8bc92958),LL(0x13b62772,0xc9121c92),L_(0x543662c4), LL(0x4549aa77,0x1090a59c),LL(0xc62e7c6f,0x066a0956),LL(0xa38394a8,0x19c57ed5),L_(0x4823e8cf), + LL(0x003e564b,0x61b100d2),LL(0x416f9398,0xaf3087cc),LL(0x8d0f5a48,0x11e5f34b),L_(0xe047da80), LL(0xe946d928,0xc598885a),LL(0x455959c9,0x838b9ed4),LL(0xe69bdd02,0x6bdbe44c),L_(0xd3377883), + LL(0xd1de4464,0xe93c7baa),LL(0x23daaa17,0xb54baf63),LL(0xcf91e74b,0x64e1431b),L_(0x1ae9e235), LL(0x43fd6c3d,0x2c00590f),LL(0x0ba0b46e,0x98d151a0),LL(0x1ee4dc18,0xe61cc51e),L_(0x93805289), + LL(0x15b970a3,0xa33f496c),LL(0xc65b315e,0x3f6d708b),LL(0x25723787,0x2ca2c551),L_(0xc7e943c6), LL(0x9a10432d,0x1845a431),LL(0xb33bb1fe,0x81764017),LL(0xf5b5a1e6,0xbb41c15a),L_(0xf5bd0a9c), + LL(0x042a23c5,0xe9864244),LL(0x73ab2381,0xbb7b2648),LL(0x0ed12b18,0xe3536d47),L_(0x0a040c86), LL(0x9c5a68b2,0x550f5800),LL(0xa16b2d10,0xfa0aebe0),LL(0xd20e3020,0x40239ea3),L_(0x13feb317), + LL(0x8e882fb8,0x12206859),LL(0xd53242c9,0x3e1a95f6),LL(0x1c2921f5,0x765eedc1),L_(0x84f582be), LL(0x525bb499,0xf8de62be),LL(0xf9eee520,0xd0a27199),LL(0x209f3c9d,0x721633cd),L_(0xc2e9678c), + LL(0xc8a35690,0x852acfe8),LL(0x92b626ca,0xdde1d1be),LL(0xf571ade2,0x918c76fa),L_(0x5b7490f5), LL(0x38c8b0c0,0xdf1662bd),LL(0xbb1e6d8b,0x470868d3),LL(0xd821c745,0x9a06de8a),L_(0xcaec5c2c), + LL(0x64f233d6,0xc1321d2a),LL(0x74538108,0x30546bc8),LL(0x2f1d65e6,0xc8d1c486),L_(0x8ecd7a1e), LL(0xccea4b95,0x3466245a),LL(0x700ed4ab,0xf5d50910),LL(0xfa32badf,0xb5a66db1),L_(0xfc4883b2), + LL(0xb4589512,0x962b479c),LL(0xc4a7efe4,0xb97069b4),LL(0xa0d20fc9,0xd0ef4040),L_(0x76eabbd4), LL(0x38b07e76,0x17a75081),LL(0x4bc6d910,0x3d3dbafe),LL(0xff0f721e,0x36e896fb),L_(0x6146e5ef), + LL(0xab1ff699,0x6fd3001f),LL(0xe508cb13,0x5b228934),LL(0x80a73390,0xcc02c93c),L_(0x6ad8073c), LL(0x9444deec,0x5f92bcf6),LL(0x8847a6eb,0x06c7d42b),LL(0x758f4aa4,0x40b45a83),L_(0xdb4ada91), + LL(0x0083de14,0xfff55c75),LL(0x661c826d,0x317fc21d),LL(0xb311e146,0x6bdaa80c),L_(0xcad158e9), LL(0x69952fc9,0x4502f454),LL(0x239ecee1,0x74f37d8f),LL(0x2b344eb3,0x161e1cf8),L_(0x02ce3f80), + LL(0x645e7684,0x0009b919),LL(0x53d14c44,0x8105efea),LL(0xcbb0101a,0xdf767e4c),L_(0xecc4eabb), LL(0x0c2ac7fe,0x70cf6d6c),LL(0x0ede1159,0x17089527),LL(0x4162258f,0x5ed679cb),L_(0x5e706cdc), + LL(0xcd1206e2,0x33b4ee64),LL(0x78fd4645,0xcab93e67),LL(0xb807ac0a,0x7e760bcf),L_(0x923934bf), LL(0xfa2159f5,0xaf2ed832),LL(0x918e957c,0xe1d5b548),LL(0xdf411692,0xde9c3716),L_(0x2c76553a), + LL(0x3d4c49ae,0xd3a72d08),LL(0xa5e4f840,0x03aca3cc),LL(0xd9bcbe83,0xf00706d6),L_(0x986b79c3), LL(0x412a3304,0xefb01a68),LL(0xa0bb40d2,0x19e3729e),LL(0x2d182974,0x57b4bca1),L_(0x43c566de), + LL(0xb3db024c,0x2f1c7c7b),LL(0xfb3c8bb1,0x86b88161),LL(0x1addae50,0x29206628),L_(0xa115d8d7), LL(0xc7b9fa3c,0xcf3f272c),LL(0xf2a0db00,0xb0b04d71),LL(0x1a242dce,0x048ec06d),L_(0xbe72542f), + LL(0xc6eb32f1,0x515f5aba),LL(0x995a0552,0x9e89cf10),LL(0x809459ef,0x2a52fccb),L_(0x4bf08352), LL(0x31a7e6c7,0x94c73471),LL(0x507e309b,0xc1732a6e),LL(0x006ea760,0xd3410c08),L_(0xde332d38), + LL(0xe9a863af,0x05608149),LL(0x971e9a21,0x80261bb1),LL(0xcf890a46,0x607c23ca),L_(0x8c2f3995), LL(0xee178996,0xb8358125),LL(0xc384ccce,0x8630d610),LL(0x62e3cda6,0x637377fe),L_(0x36145889), + LL(0xebe66e5d,0xa7ccaba3),LL(0x66ee0e61,0xe5d23ef3),LL(0x8b52d5b2,0x9b192439),L_(0xe2507e26), LL(0xdebe6661,0xf0320f46),LL(0x164afe7b,0x06272a4d),LL(0xa9cd4c00,0x53be168f),L_(0xbd05717a), + LL(0xb9a090f6,0x82377241),LL(0x84720302,0x8cab5c0e),LL(0x3e8eab14,0x8131dcb9),L_(0x8dffb402), LL(0xe82db9aa,0xca87536f),LL(0x7476d50d,0xc99eb71b),LL(0x40036a93,0xad40e0b3),L_(0xae5c279a), + LL(0x203e82ae,0xce0565d4),LL(0x4590aef4,0xf8303097),LL(0x813e461c,0x4d52d217),L_(0x64b75926), LL(0x1774cb88,0x51483218),LL(0x4046569c,0x804c4220),LL(0xbd282e8b,0x394837d5),L_(0x5a6b2c1e), + LL(0x7eb4bbcf,0x58408340),LL(0xa28c5b85,0x9cd1f588),LL(0xac9ddd98,0xdf706c18),L_(0x62a72bba), LL(0x1ecd1293,0x7437fa2c),LL(0xafe0e361,0x5b13b49c),LL(0x29283b54,0x0c099515),L_(0x469c2258), + LL(0x611af3b1,0x1869604e),LL(0x69cd9356,0xb7d10b48),LL(0x161651d5,0x8a8472c4),L_(0xa23f6947), LL(0x8a84a570,0x9ca82d05),LL(0xdd9ffcc5,0xbdf0cb1e),LL(0x7c9cfaaf,0x8b227092),L_(0xc52e4c68), + LL(0x344a8ce2,0x66b5d593),LL(0x661a0707,0x277d6af9),LL(0xf0ed8bfb,0x9f814a89),L_(0x68ff82da), LL(0xff4e0f6a,0x54b6136e),LL(0x125a9d0a,0xe9e8996a),LL(0xdbfa6d51,0x0914dd93),L_(0xacae0da7), + LL(0x326565a3,0x41cc5966),LL(0x8e32f402,0xa314cfc5),LL(0x99f4bcb7,0x0ba8496e),L_(0xcbcf93d4), LL(0x58afb0bc,0xf2f01549),LL(0x22877383,0x775e4843),LL(0xf270905d,0xfeb2c8a5),L_(0x15d8ffe9), + LL(0x111a2a90,0xc56f7437),LL(0x435cbc99,0x64f9c9bd),LL(0xedb87fdc,0xc1d19083),L_(0x702066e8), LL(0xc8dbc37a,0x2c1c4233),LL(0x672ee8b0,0xc183ca5e),LL(0xfc342416,0xaa518aba),L_(0x34e2bf87), + LL(0x13de8a41,0x3bd53f9f),LL(0x38707713,0x326f7696),LL(0x6251ddca,0x4c9a0c1a),L_(0xe7e323fd), LL(0x6876f934,0xd33612f2),LL(0x93f34e7a,0x1b94f160),LL(0x0c42a981,0xdc0b91ab),L_(0x548c92c1), + LL(0x4cbbb4e6,0x72ed1d97),LL(0x0de1c184,0x5a3987bf),LL(0x86904dc8,0x45379ece),L_(0xbe4c089a), LL(0x87ac4c8e,0x6d5238ae),LL(0xa27b3f88,0xbf067204),LL(0x21e17b1e,0x122542d6),L_(0xd6e7acc3), + LL(0x84631900,0x01b419d0),LL(0xdb03ac70,0x4d15d553),LL(0xc5304466,0x5f684940),L_(0x11655587), LL(0x8f896988,0x196f70de),LL(0x771ca6aa,0x79277c70),LL(0x4a94022c,0xb69fe2d3),L_(0x076b1dc4), + LL(0xb8ac3536,0xecd18f22),LL(0x225dd231,0x86439125),LL(0x23c21f5b,0x43b63acb),L_(0xf5b2b43c), LL(0x9b9dfcde,0x7ec7a341),LL(0x362a2c90,0xd7db9d5b),LL(0x308c8fcb,0x608d86ad),L_(0x8858eb99), + LL(0x89b3a627,0x82f0ce08),LL(0x8ffc3544,0x4c9d1c88),LL(0x1414581d,0xf2cd74da),L_(0x2ab74c29), LL(0x47673821,0xd4c61a1b),LL(0x8b9a0584,0x4166899a),LL(0xd7114188,0x7b53c8e6),L_(0x4e91e1e4), + LL(0x83a918f0,0xe472f5b7),LL(0x120a4cb4,0xa54211cb),LL(0xd29feaef,0xa568a4a5),L_(0x1f0a0815), LL(0x80033652,0x52d9147c),LL(0x1dd52d78,0x73e66c07),LL(0x99e7538c,0x25ad4a06),L_(0x8a35cc7c), + LL(0x45837327,0x3daaae35),LL(0x214d493c,0x0495de90),LL(0xc0f2cff5,0x5e7107a4),L_(0x46024f37), LL(0x4ceabd92,0x0f39120b),LL(0xd7f5199d,0x26eb2e5e),LL(0x2dba9f4d,0x2755fd79),L_(0x54915591), + LL(0xf3749f34,0xbd4c1fd7),LL(0xbe148855,0x0fc24339),LL(0x7f36ce43,0x41ceba92),L_(0x40c686c2), LL(0xd073af02,0xa2355b2f),LL(0xeb937195,0xa16c5398),LL(0xa1f3ab05,0xf7d38672),L_(0x90828e20), + LL(0x7c7ef0f9,0x37b7db08),LL(0x4de172b0,0x2ce3e250),LL(0x3f8b6d32,0x1253fef8),L_(0xc76ebff6), LL(0x54208a07,0xc53e233e),LL(0x9a8ef0b3,0x6f68e154),LL(0x2d43fb48,0x9a94edf5),L_(0xc8891237), + LL(0x85578ac6,0xf170445f),LL(0x115d7eb6,0xd46f93ef),LL(0x71666f11,0xdfdf4d27),L_(0xcd09d0bd), LL(0x742f2abc,0x658ac044),LL(0xe75c6300,0x0f93b4da),LL(0xa0de2978,0x5ea75aec),L_(0xd9cc6143), + LL(0x7e1b6b82,0x2a662d9d),LL(0xcd959485,0x38780971),LL(0x5ee58f00,0x69a1ad5b),L_(0x417599f7), LL(0xfe8f4d61,0xc5110167),LL(0x471554ab,0x3201dfa1),LL(0x4e2c7d96,0xa6a4af88),L_(0xe49c13ae), + LL(0x44dc3bbe,0x0a1a147d),LL(0x23d766f5,0x3c2cbc33),LL(0x5446ea58,0x737348f7),L_(0x49f6d997), LL(0x2488e5f7,0x17464a0c),LL(0xf5ac023b,0x5e39103b),LL(0x1c89d9f7,0x5a4700e1),L_(0x918b1cd7), + LL(0x1a52af4c,0xd9c4d8a5),LL(0xfb136a04,0x62eae24c),LL(0x627e23b3,0x2a546df5),L_(0x9518b383), LL(0xc577abda,0xe74b275b),LL(0x9e8dd1b3,0xbe223e4a),LL(0xb28d50a9,0xc1bf5392),L_(0xf0c4dae3), + LL(0x12450901,0x60cd114e),LL(0x19f30dd8,0xb57b5e92),LL(0x0a04952b,0xa5b0d428),L_(0x9fbf17a2), LL(0x998f1456,0xdc88c74f),LL(0x2eaf445d,0x39f1ad33),LL(0x24d076c8,0xb7cb2b9f),L_(0x4da895c0), + LL(0x2bde5f9c,0x296bb0ce),LL(0x1e460fe9,0x8b7ed12e),LL(0x0a2b9d60,0x779ddda6),L_(0x70ad87c8), LL(0xda6b433e,0x1216c7ea),LL(0x015e5322,0xfbda2b1c),LL(0x08a2c2b4,0x5c4f2da2),L_(0xda0125d8), + LL(0x7e27d6a4,0x5cbb2271),LL(0x0e27b02e,0xf69dabcb),LL(0x651b4dc0,0xf5b545b4),L_(0x89864ae4), LL(0xe7bf1ebd,0xbfa85080),LL(0x0162c99f,0x358c27ef),LL(0xc148b34a,0x39fddb94),L_(0x7de290f5), + LL(0xbe0c0f85,0x8d61f3ca),LL(0xe4f10dce,0x4cbdbb45),LL(0xd40a9135,0xdb4a6076),L_(0x869e961b), LL(0x191ed5b2,0xc8ea7a1c),LL(0xaed2c272,0xe62f26a5),LL(0xdd267430,0x49228bdc),L_(0x196c9b69), + LL(0xda4dc900,0x5f4b0d32),LL(0x357d26fc,0x47de3ca9),LL(0x8bc3e1fc,0x44a306a1),L_(0x6ebde62d), LL(0xc4fcbc98,0x66c5b1ca),LL(0xc2a2d52f,0x6365559c),LL(0x67f40398,0x6a1916f6),L_(0x9eb2b762), + LL(0xd3f693c6,0x97ae197e),LL(0xe2705942,0x4294f4ca),LL(0xb717c180,0xfe30cc2e),L_(0x7aa89b4d), LL(0xb42643a1,0x3d1c1e8b),LL(0x1731a1a7,0x4e550c0f),LL(0x4cdde0b3,0x85e85391),L_(0xab7103b7), + LL(0xe4b061b6,0x39f1ba7e),LL(0x21c91792,0xcfcb8f5f),LL(0xd1e29983,0x8102c46e),L_(0xaa0fed15), LL(0xf3e438cb,0x1df20d6a),LL(0x659104e2,0x43818f1f),LL(0xd4f49239,0x3a84be64),L_(0xca582a23), + LL(0x3118786e,0xce03f04a),LL(0x827606a4,0x107aaf6b),LL(0x10bcfdd2,0x277b88b9),L_(0xf2e4c5e4), LL(0xb9b85218,0xb9213c6d),LL(0x161c54e8,0xebb4f0be),LL(0x2814c386,0x859e6045),L_(0xac244cf4), + LL(0x7292e148,0xd6446675),LL(0xab795487,0x71b2851d),LL(0x5a242339,0x899b5dad),L_(0x8520bc7b), LL(0x72df7577,0xa366ee1a),LL(0xc17b463a,0x30d222b1),LL(0xa0af7c17,0xddf53842),L_(0x85b5501f), + LL(0x124bc359,0xc8d63689),LL(0xcd7b3fe1,0xbfb69ae2),LL(0x124ab94c,0x6971b236),L_(0x961e282f), LL(0x7f403da9,0xb92ac7ad),LL(0xc76e5b2f,0x5d04c417),LL(0x8df11606,0x0055901f),L_(0x666181f1), + LL(0xf49645d2,0x96fcbeb8),LL(0x745bf74b,0xe0b2a4ea),LL(0x24675bb4,0x531c5deb),L_(0xff3b4dca), LL(0x560275f8,0xd74deba2),LL(0x97100731,0x02589d49),LL(0xa26f7f22,0xb1b02a6f),L_(0x396cb1a0), + LL(0x7de707a4,0xc6165fe0),LL(0xc07709d3,0x6be7081c),LL(0xfdb883bd,0xb1a5a67b),L_(0xfd535ec8), LL(0x25257079,0x8234b458),LL(0x45bb7b81,0x9c1b3f29),LL(0x1f4c2d8a,0xa1cee750),L_(0xcf55f516), + LL(0x206c7d17,0x0e3c9acd),LL(0x75c44136,0xd3de8638),LL(0xbe92eabc,0xf4ca1355),L_(0x9e459c32), LL(0xbf750404,0x4bc1af9e),LL(0xc06b8bfe,0x20fc4197),LL(0xe0b85f76,0x7d557c99),L_(0xff091685), + LL(0xbe45dd17,0x90ad8901),LL(0x5513303a,0x62ba8a0a),LL(0x9b18a004,0x8286d6c6),L_(0x73c22592), LL(0x126eaadf,0xf6402ecc),LL(0x2bbee8cd,0xa309b99e),LL(0xab06f9cc,0x42089652),L_(0xc4a5e5a0), + LL(0xe1391274,0x6925cad9),LL(0x6d3b1102,0xe366ed4c),LL(0x2e19a20a,0x1593ba2f),L_(0x8c091708), LL(0x9083afa5,0x711ad8d6),LL(0x1a65086c,0x5e8645a5),LL(0xc052325d,0x182117dd),L_(0x865d46f7), + LL(0x6f70a66e,0xfb548313),LL(0x7a6b6eef,0xae61c7f4),LL(0xec447933,0x6a3d4ff3),L_(0x74866913), LL(0x35042671,0x38316d02),LL(0xb9635b34,0x6a9889f8),LL(0x2db27177,0xac233369),L_(0x567be1c0), + LL(0xbe9b9347,0xcf5edce0),LL(0xa18e3f0f,0xe93ce044),LL(0x05816a5b,0xa26ca8e1),L_(0x00da101c), LL(0xacb5542b,0xe04bccb7),LL(0xa1f2efbe,0x470e98a4),LL(0x67b00a65,0xdd0dbd8b),L_(0xc0be2197), + LL(0x788904b0,0xe5a39b63),LL(0x0a586a5d,0xc10656ab),LL(0xe22752b9,0xfc9ab49c),L_(0x72fc1c09), LL(0x31249974,0x8b426974),LL(0xd51e5946,0x0c7e10a4),LL(0xa79d2b5d,0x8d8169eb),L_(0xe4ca8644), + LL(0x93ac6205,0x923206a9),LL(0xd8894d89,0x311a6950),LL(0x992f9c30,0xd0679c8b),L_(0x0cde00fd), LL(0x5d5f7311,0xf07baea8),LL(0x3f8e094d,0x00100a63),LL(0x3d3b3316,0xbfbe9e92),L_(0xd269b8cc), + LL(0x3357ad87,0x88e7f567),LL(0x8dcb5c06,0x7dc56ca1),LL(0xc8f6e06c,0xa6e90095),L_(0x905b4a44), LL(0x99de2654,0x63aa3a4e),LL(0x1e51e461,0x486476c9),LL(0x5fb4cf43,0x35d139e9),L_(0x8725096b), + LL(0x016940d8,0x2005767b),LL(0x95ce3a0f,0x0dce7b68),LL(0xb593a6ed,0x2c5a09aa),L_(0x762f3669), LL(0xe1f753d0,0x52242366),LL(0x88d38ecc,0x05e8fe24),LL(0x759292df,0x8843ff7b),L_(0x041ca14a), + LL(0x8edf1adc,0x0062aa12),LL(0x4bff8a1d,0xb1aa7c7a),LL(0x28b33bc2,0x966aee37),L_(0xb4b3e7e7), LL(0x2d9ceec2,0x7f31f05a),LL(0xc7be6aaf,0x10ae244f),LL(0xc2c97f7b,0x7401d050),L_(0x1475b928), + LL(0xd008f9fc,0x3150b4aa),LL(0xd53ede1b,0xef6ad2c4),LL(0xe427c40d,0xf4e2d20a),L_(0xe5dd8b02), LL(0xb370a814,0xac4f8ba7),LL(0xaaacf4ec,0x44dbb479),LL(0x8e6b2784,0xd9aeb4f2),L_(0x4019cd79), + LL(0x004de7f7,0x680b826b),LL(0xc0a2ee02,0xc1ff25d4),LL(0xb25a4e2a,0x8b33b701),L_(0x3a2939d0), LL(0x9621d94e,0xe6feb01b),LL(0xd1311810,0xca0e2b81),LL(0xa701c8f2,0xdbcecc81),L_(0xeee95871), +}, +/* digit=5 base_pwr=2^35 */ +{ + LL(0x22d3206b,0xb5c4c69b),LL(0xf507ee25,0x886af51e),LL(0x454a0f10,0xf21fe543),L_(0x29d7720a), LL(0x22d2999a,0x7c33ec2a),LL(0xb4054a86,0xa4d8106e),LL(0xdb971595,0x8a74b5b0),L_(0x8850caf4), + LL(0x3bc6ae19,0xa04cb662),LL(0xf30acc6a,0x4f889fa2),LL(0xd7560ec2,0xb8b6110c),L_(0x4f8fab99), LL(0x6bc71596,0x4308e608),LL(0x2c9d6af5,0x10d12c43),LL(0xca6486c0,0x64c7b963),L_(0x28ca7953), + LL(0xb662cfb6,0xbcc43ce9),LL(0x3055b2de,0x39c5bde1),LL(0x68461c60,0x4caf7c30),L_(0x84c1743c), LL(0xab0e6d70,0xb5b3a77f),LL(0x0e121552,0xa5bc5e90),LL(0xc38f8d3d,0x6cee1666),L_(0xe3236cdc), + LL(0x88d7b871,0x4220e847),LL(0xa785596f,0xc1fb7864),LL(0xfa4258dc,0xf4276ec4),L_(0xfc15e9f1), LL(0x293a6fc6,0xa58a670d),LL(0x9382335f,0xd56aed8a),LL(0x3477647c,0x311f9766),L_(0x4f5dbddc), + LL(0x6de91978,0x69933c7b),LL(0x21ea5af6,0xf13eda55),LL(0x4b132119,0x12e00aff),L_(0x0ff8497a), LL(0x3253a2e3,0xb8a8554d),LL(0x7d054f07,0x9338ab00),LL(0xb896b1fc,0x91dbc7f3),L_(0x6470c920), + LL(0x51929e02,0xc7b39de9),LL(0x93ff36ec,0x2b86f570),LL(0xa6f2dced,0x802aa4a0),L_(0xdbd9b943), LL(0xa8bbc105,0x8c1a0edb),LL(0x7cecf63b,0x54aa43d1),LL(0x54af7ee1,0x78b1b385),L_(0x0498d501), + LL(0xe2a3944b,0xf34b8646),LL(0xe5ba9123,0x61656a11),LL(0xc14ff9dd,0x42cbd03c),L_(0x2891aad9), LL(0xd76dd4f7,0xf01f7308),LL(0x55808c68,0x793b012a),LL(0x2ceb5051,0x9d313349),L_(0x2f3b809e), + LL(0x1cd0a45c,0x59881514),LL(0x919ddc75,0xa32929ee),LL(0xf87e0bab,0x3037e369),L_(0xa090d36b), LL(0xb3841cb6,0x579ffa96),LL(0x38e224e4,0x904c8cca),LL(0x2cadda68,0x702d5e89),L_(0x12eff4f2), + LL(0x92015c38,0x52239088),LL(0xfabf2649,0xd339e361),LL(0xe9f6b8df,0xe84977d6),L_(0x3f58519b), LL(0xaa4bb20f,0x4357d0b8),LL(0x6c5351ad,0x8521ac57),LL(0x1253d822,0x9524c5cc),L_(0xfbce31d7), + LL(0xc07ab316,0x2e93f070),LL(0xfcee759c,0x25c23713),LL(0x132e8c43,0x6a329ada),L_(0xec4a7a29), LL(0xe8c7f287,0xd5e2b374),LL(0x36a40bf0,0xcf0c0149),LL(0x9da99c9f,0x25e16e85),L_(0x7730bda6), + LL(0x4bd943c9,0x4e15a70d),LL(0x37a376cc,0x82e59c18),LL(0xad1329bc,0xe14b9f7a),L_(0xac8b6391), LL(0x60924a1b,0xe412693b),LL(0xb1a885d1,0x20e7bad4),LL(0xdd7cdcc0,0x06667f09),L_(0xfb4d7bf2), + LL(0xb6cb033c,0x350411eb),LL(0xc83be0ea,0x4b4e8d93),LL(0xc7612043,0xbb338804),L_(0xfb1e56ce), LL(0xef5ca7d8,0x4b75557b),LL(0xfed92eee,0x5e0d7736),LL(0xc3259e9d,0x61eea795),L_(0xc28b498a), + LL(0xbe56f422,0x7363a98e),LL(0xe21a8af4,0xb0ad92ac),LL(0x2ee0c526,0x081ad4e5),L_(0x50ce73f9), LL(0xecb59a8c,0xfce29612),LL(0x52824a9e,0xdcb3b781),LL(0xb689cfc9,0xac6e83b5),L_(0x006e1f4f), + LL(0x1f147d23,0xd0a972a8),LL(0xe471b9e4,0x346ed362),LL(0xcfd1906e,0xd7accdbc),L_(0x293a4390), LL(0x79ac99cd,0x86a243d8),LL(0x06c24954,0xca928f18),LL(0x3453aba8,0x25495810),L_(0x36f891b2), + LL(0xd91398ce,0xba90aff9),LL(0x4d72eeba,0x14e030a4),LL(0x81c31d9d,0xe70f3373),L_(0xa716b2aa), LL(0x2213b99f,0x42ac4252),LL(0x6f657c45,0x415aca82),LL(0x7d074644,0x461026d7),L_(0x0dde683d), + LL(0xa01e18e0,0x4b805781),LL(0x8dd02690,0x35c19d90),LL(0x1d04223e,0x83277841),L_(0x7ea96551), LL(0xe06c5996,0x4c78c04d),LL(0x70dde026,0xc34eaf3c),LL(0xb58c0bf7,0xae645b00),L_(0x3afcf537), + LL(0x76eb1d35,0x708a8083),LL(0x5f7d6f8d,0xc51a45c7),LL(0x141c5fc5,0x61a1cb60),L_(0x78ecbf19), LL(0xba4b17cb,0x4cb03ebc),LL(0x9be1423d,0xf30899fe),LL(0xd63cb771,0x51acdaa0),L_(0xa32591dd), + LL(0x88195009,0x8de09e86),LL(0x76e08928,0x70957a85),LL(0xa653c234,0x59256cc9),L_(0xd8d51507), LL(0x5d7b9252,0x47309994),LL(0x0f159c21,0x3ff7ccc1),LL(0xfe9fe5bc,0x0339c473),L_(0x16784f00), + LL(0x24c3bafd,0xf2b37280),LL(0x1cbd8aaf,0x2790844b),LL(0x8a600a73,0x2324a737),L_(0x644765ee), LL(0x4ad1ba6a,0xb4dd3d30),LL(0xa23d1c2e,0x9d90ab4e),LL(0x953388e0,0x864110e9),L_(0xe9be065f), + LL(0x9dfdba3f,0x9c32af38),LL(0x69ee0a06,0xf93a2f14),LL(0x1fd2a13b,0x38105c26),L_(0xfe12d778), LL(0x3947424e,0xd4a50774),LL(0xd5b96217,0x8f7c85be),LL(0x0f0582fb,0x9f4dc144),L_(0x87629c9c), + LL(0x6470ccfc,0x377dc9b6),LL(0x9e11a84c,0x09816331),LL(0x610e3f5c,0x9becf104),L_(0x87cc9a9b), LL(0x62783e9f,0xbefa56b8),LL(0x89fa53e3,0x18a4bfcc),LL(0x0b3ed787,0xdb99856d),L_(0x68d6dbd1), + LL(0x9620574e,0xdd0b49af),LL(0x7e561904,0x68703702),LL(0x3056fb70,0xab404bf8),L_(0x4911d8a5), LL(0x0f24dcd1,0x91807631),LL(0x606c33cb,0x6847c0d5),LL(0x791f57f0,0x525adb32),L_(0x818f0a1f), + LL(0xa84199ec,0x1094f386),LL(0xd1afe50b,0x558c85a0),LL(0xab294ef9,0x69998dcc),L_(0xe0d8fa53), LL(0xa8d822a6,0x6ccabafd),LL(0x64a8c67c,0x4f2dce66),LL(0xd4a601a5,0x8082a5ca),L_(0x1c89a181), + LL(0x49e538af,0x4855546c),LL(0x6d3c05ab,0x11f89f31),LL(0x44996dfb,0x9e6dd61e),L_(0xe5054752), LL(0x053ae779,0x4c1c7978),LL(0xa7675178,0x49d3b92e),LL(0x72b800a4,0x307c1a34),L_(0xafc9ca2a), + LL(0x73bd9113,0xf1254531),LL(0x1e52b09c,0xb3c304d4),LL(0xfc186009,0x579623ed),L_(0x0b5f7250), LL(0x0a3ddce4,0xa4d79ef7),LL(0xff4c374a,0xd69618ef),LL(0x252cb608,0xf8e76342),L_(0xfcc58682), + LL(0x1cbe9e0c,0x586d393a),LL(0x480cf461,0x2e2acea1),LL(0x13a215d4,0xe3cf0a14),L_(0x82460da2), LL(0x38bbf760,0x188125b7),LL(0xcd5956cb,0xa80c3de5),LL(0x9e63be59,0xbfc652be),L_(0x275a3495), + LL(0xccb821df,0x965c6e19),LL(0x0b8b60d7,0x03204648),LL(0xd6030341,0xc11f7050),L_(0x4e201a9c), LL(0x5815f324,0xdd1a6a75),LL(0x73f70f06,0x7aaff126),LL(0xebc85955,0x11a05e07),L_(0x0cd2e37d), + LL(0x34fb8b2f,0x7afa362d),LL(0xf7c5f96b,0x995871ed),LL(0xfa20c1e4,0x6be4e8e8),L_(0x02b63df7), LL(0xf9949e2f,0x3453fb74),LL(0xf6fdf958,0x376ae7a8),LL(0x502b7475,0xadf32795),L_(0x20557243), + LL(0xb1daffbe,0x446cdc61),LL(0x8eb329bf,0xefdaaa71),LL(0x369f125e,0x6c894dd3),L_(0x9db7bb62), LL(0x4dd5f542,0xc4277490),LL(0x31b2dbea,0xfe4eccd1),LL(0xb650ae0a,0x20fa0957),L_(0x29da364e), + LL(0x937b1868,0x3d0c5313),LL(0xaa1e00ca,0xb2ed18b4),LL(0xe23097a6,0x18e7fcd5),L_(0x790fdadc), LL(0xf18eb299,0x00c47190),LL(0xf4068839,0x1797157e),LL(0x5b080743,0x257f4df1),L_(0xd4b97dd1), + LL(0xcf771fe7,0x9e9f2679),LL(0x7fa3e72a,0x0a76d555),LL(0xec547443,0x303f3000),L_(0x74ba5f3a), LL(0x56040059,0xe1305459),LL(0xf97b4e0b,0x58cce0ba),LL(0x7b3e3dc5,0xb3342459),L_(0x849b0cbe), + LL(0xc043c4d3,0x156bffa3),LL(0xef4fdf72,0xc568dd1a),LL(0x0fb07e25,0x373456aa),L_(0x0c136024), LL(0x9c743fd6,0x75063485),LL(0x09872cea,0x512889e4),LL(0x1f75eff7,0x2982d676),L_(0x46918abe), + LL(0x19d6d0db,0x62d87801),LL(0x8ac63776,0xe6ac10ed),LL(0x3df57bb4,0xfb67a75d),L_(0x872c8f87), LL(0xb22e582b,0x49548c67),LL(0xa4ab6141,0x6cb6b04c),LL(0x5ae2f1d3,0xccb21fe7),L_(0xcc4c5d51), + LL(0x95de93f8,0x552b1d5a),LL(0xc91b6f0a,0xf6ce5a61),LL(0x26244e6c,0xebe1c6fb),L_(0xec4bbe5c), LL(0x4fe79929,0x35cfef8c),LL(0x09fa8c0f,0xc7ce6957),LL(0x77fdabaa,0x4bbc3792),L_(0x94421437), + LL(0xa29405cd,0x820d6808),LL(0x9b55ccda,0xf32ab874),LL(0x1046f37c,0xed3f6fb8),L_(0x07a02e6b), LL(0x6ed01e06,0x6676830d),LL(0xf82f2f79,0x1cd99760),LL(0x35492433,0x79d53ab5),L_(0x16a996a8), + LL(0x1f2f75b4,0xaa0f7a8f),LL(0xe4d29021,0x44a728bb),LL(0x9b86e6e0,0xdb26a514),L_(0xf567f4e0), LL(0x47f066f6,0xc1decce5),LL(0x9de6495a,0xbb842ffb),LL(0xda23fbb5,0x6557417b),L_(0x7d23ff08), + LL(0x5767ef80,0xc3c2aab8),LL(0x2e3254ff,0xb5203eb2),LL(0x48576b69,0x2e3a1aff),L_(0x4e27496a), LL(0xd5e96792,0x497974dc),LL(0xb0b36f57,0x8169a5cf),LL(0x1d0467dd,0xbd12d521),L_(0xee061337), + LL(0xa2a324b7,0x3a9a26ff),LL(0xfa637395,0x664652b4),LL(0xbc2048f0,0xf8ae9c4f),L_(0x7229d31e), LL(0x499224d1,0xd86d5de2),LL(0xd7e8cbb1,0x33a4a4fb),LL(0xa98c305e,0x382a852f),L_(0x7668edae), + LL(0xdf02b971,0x6d33747e),LL(0x6bae97b0,0x468b6590),LL(0xc0b8420d,0x0d1395e0),L_(0x5d523a37), LL(0xb00603ce,0xf196c7bc),LL(0x940889f2,0x7b8dc7b3),LL(0xa914e0ea,0xce35713d),L_(0xcb59a392), + LL(0x5a648ea8,0x984bd24c),LL(0x17b7b322,0x88be2da8),LL(0x33279a92,0xa03ade42),L_(0x3ac696ec), LL(0xa75e5e17,0x36f23ece),LL(0x4faba2b9,0x7b477179),LL(0xf70fdee7,0x7bbc4522),L_(0xeb035a5f), + LL(0x52c14e4f,0x5ddc6b6c),LL(0x150eef02,0xffc4fbef),LL(0xdd3f93bb,0x3696d783),L_(0x15012933), LL(0xe0cad04f,0xff6e69b5),LL(0xc84755b9,0xd70bfdb4),LL(0x118ab913,0x2da1eb13),L_(0x99325702), + LL(0x0bcc9e8a,0xdfd09cd8),LL(0xd7ddee82,0xf1564d08),LL(0x93460444,0x87b5bd4a),L_(0x0d5541f4), LL(0x87dcbe2a,0x2e83bcba),LL(0xd3e283ed,0xd947e2cf),LL(0xe52b803b,0xb28eb570),L_(0x4a8c77d7), + LL(0x7f6e4fa5,0x76362059),LL(0x18df4a69,0x41a44792),LL(0x70a8c001,0xf96be149),L_(0x69d0bc39), LL(0xef115578,0x59f09aa4),LL(0x53e28bf7,0xc1354a01),LL(0x3ef52081,0x28ac324e),L_(0xa781c57c), + LL(0xf28899e9,0xb145dd4d),LL(0xf8de49f2,0xc929d158),LL(0x7a359488,0xa5fe71f0),L_(0xea4e5a13), LL(0x62263448,0x8252a9a9),LL(0x9870bd6d,0xa478d63b),LL(0xd7e75649,0x73608571),L_(0xb0499f6c), + LL(0xf3fc02d9,0x63626f38),LL(0xee89a981,0xecb2dedb),LL(0x45b932da,0x25321bbf),L_(0xdd6b2382), LL(0x73c34e68,0xbd649606),LL(0xdbca6a1d,0xf7cc4ce3),LL(0x1e699d4b,0x940460cb),L_(0x7938144e), + LL(0x6625374c,0xa571f0bd),LL(0x50d17043,0x67316b9e),LL(0x7b24e59a,0x15047c8b),L_(0xe06a40d9), LL(0x71fd751b,0x5bc5aeb6),LL(0xaeb386d4,0x77f99ebe),LL(0x40fabb40,0x62bdfdf5),L_(0x6aace159), + LL(0x2c7b8857,0xde610cbe),LL(0xf6b35535,0xd1d9c553),LL(0xb7d2826b,0xb4edc29d),L_(0x03e1e5e0), LL(0x05ce2cac,0x789b199e),LL(0x03331148,0x44bc5992),LL(0xa966c64a,0x0851cfcf),L_(0x1622ec1d), + LL(0xb82bff1a,0x888b7c2b),LL(0x07cb3e37,0xade27f4e),LL(0xb017d5a9,0x7f7c933f),L_(0x42119d1d), LL(0x2b1e659a,0x5ef83e45),LL(0x0109f6b8,0x91081a86),LL(0x6e139181,0x1b624dea),L_(0xa2bd127f), + LL(0xa90158d0,0x54ae0fcd),LL(0x9a79307a,0x5d77cf42),LL(0x6d342e22,0xb177e174),L_(0x2e3ee119), LL(0xf32ebada,0x5e84ad5e),LL(0x08e8f89c,0x1f21876e),LL(0x425e69c5,0x42b47533),L_(0x0b2e547d), + LL(0x8c73ff85,0x041c2bca),LL(0xd43f468a,0xdff69743),LL(0x497dff29,0x58417877),L_(0x9551c8f0), LL(0xea9a5efb,0x1e1b3a51),LL(0x7aa44dae,0x62164b97),LL(0x82e3854e,0xe5d6128d),L_(0x2f25adda), + LL(0xce69fd62,0x92365b99),LL(0xdd4e8322,0x64c55482),LL(0xe083981e,0xbf7947a0),L_(0x5b678747), LL(0xe12f61e8,0xc98f9109),LL(0x0ca71f21,0x7084eee8),LL(0xe31a901e,0x922f7c66),L_(0xeed6566d), + LL(0x830c51a8,0x274ea5de),LL(0x52fe1ee1,0x6f8c93f7),LL(0x7dc25d86,0xd6285877),L_(0xda84cd8b), LL(0x48aed2f0,0xbb649ac1),LL(0x1e3ba4b5,0x6976562f),LL(0x6f9c137d,0xbd251ef1),L_(0x5e5495d3), + LL(0x239cae69,0x8392e4dc),LL(0xdc8ee05c,0x79a24fdc),LL(0x4eeeb0db,0x0d91ecaf),L_(0x31e89bf7), LL(0x4b9c499d,0xeca9047c),LL(0xee9a09ba,0x2d00d0dc),LL(0x81d64f7f,0xea9e0b50),L_(0xc7b60917), + LL(0xb40fe472,0xb48d4d3e),LL(0xb23798db,0x4985b85c),LL(0x4a87382d,0x829e3bb6),L_(0x492aac4a), LL(0x59bdf861,0xf58a6463),LL(0x96935f47,0x28f41a65),LL(0x3396e951,0x6d21b8d5),L_(0xe244afe7), + LL(0xe019d807,0x890b3389),LL(0x01b0423f,0xaf7bf53a),LL(0x6d8cdb00,0x68218ce9),L_(0x7809fc35), LL(0xd3b4c83e,0x446c771a),LL(0xaae3f3c1,0x8e7a1eda),LL(0xfb834953,0x89128662),L_(0xff1c7590), + LL(0xb5425304,0xe1d9d533),LL(0x52f4f30f,0xdcd37dd8),LL(0x3a3e06d4,0x6d0d3574),L_(0x9ec8c4a0), LL(0x48b20906,0x06630324),LL(0x8d559ed9,0x334cec45),LL(0x295b5edf,0xd0a2d07d),L_(0x8d6e5cd0), + LL(0x2b1a895f,0x42c70b2b),LL(0x4f4ae671,0x36254863),LL(0x536e7d65,0xfaa3003d),L_(0x94dc0a21), LL(0xc4355888,0x1592950e),LL(0xb4369ba0,0x6d4496df),LL(0x5f932085,0x6309e764),L_(0xe5462315), + LL(0xe10bf24d,0x08fa6e2e),LL(0xec60e2f4,0x4a8f6f4a),LL(0xa152beaf,0xcc5f8968),L_(0xbce9a53b), LL(0xedca75db,0x076de5d8),LL(0x31df6025,0xfb2b47e7),LL(0xce591c62,0xead89b13),L_(0x52e8a741), + LL(0x94fdce56,0x179fcba0),LL(0xc81fc0c7,0xa0dcd6da),LL(0x8eb90798,0xbdb2ded4),L_(0x820ef61d), LL(0x9c335535,0x2b8a3cbb),LL(0xf522badb,0x7214d9a1),LL(0x93d7057a,0x0ff17306),L_(0x70098d33), + LL(0x50cac57f,0x8e019361),LL(0x2f914dd7,0xa3854afa),LL(0x2acdf295,0x2848b0db),L_(0x0f138ea9), LL(0x8c64c319,0x4ea1b039),LL(0x49ae634d,0x47440022),LL(0x113138a5,0x8ed0557e),L_(0x2b0adbad), + LL(0x931ca67d,0xb33942ae),LL(0x1ecf958e,0xc163a1f5),LL(0xc66d2148,0x1f27ea10),L_(0x011365d7), LL(0x267a659a,0xc4208dd5),LL(0xb8f4d08e,0x61b362a6),LL(0x3e553027,0x29499eb7),L_(0xea028ba1), + LL(0xd2551fb7,0xa6f2df89),LL(0x5bf03737,0x40fa3c8b),LL(0x924c5819,0xce383c9e),L_(0x910aeacb), LL(0x641dc85b,0xbfdc9b58),LL(0xe45c96a9,0xd63db8d5),LL(0x726cada6,0x8177cf88),L_(0xa738df5c), + LL(0x0cdee643,0x21f30c42),LL(0x8cd0ef97,0xf0f5ccbd),LL(0xe6a63e2e,0xd4df1941),L_(0x57a01e9c), LL(0x498e2890,0x9c025c36),LL(0xdc96eafb,0xc9df9cce),LL(0x95fe2aa2,0xae8f18c9),L_(0x239e5894), + LL(0x52954a16,0x9c68e7cc),LL(0x22874bf5,0xac850b44),LL(0x64db3074,0x3b1f7071),L_(0xa14665fa), LL(0x87ef6099,0x78fc6e68),LL(0x77eb0618,0x1edffe76),LL(0x6d531161,0xf5f0fda1),L_(0x429c094e), +}, +/* digit=6 base_pwr=2^42 */ +{ + LL(0x0a953500,0x570bd76b),LL(0x42617e4e,0x493624f9),LL(0xec1fce2d,0xbd807766),L_(0x5098d9d8), LL(0xcbc6ada2,0x468a4f16),LL(0xada13650,0xb78fc3ac),LL(0xb5aa694d,0x1dce66de),L_(0x5318219a), + LL(0xfedbc51c,0xd30a5800),LL(0x97115f9f,0x2745e2b8),LL(0xbb10a57f,0xeff5c174),L_(0xadf87884), LL(0x589f5f94,0x162e3c5b),LL(0xa2bc843d,0x16aad5e5),LL(0x25478287,0xd6f94dfb),L_(0x31bb4258), + LL(0xc180bac0,0x6c5c8427),LL(0x46351cc8,0xdf01fd21),LL(0xb964daab,0xdd1d4004),L_(0xc4d0e945), LL(0x72fb966c,0xb82dabad),LL(0x7d7ac429,0x2268903b),LL(0xeed99c4c,0x7dafa986),L_(0xcbdad15b), + LL(0x60c5d65f,0xe5e0aad8),LL(0xc7b54b13,0xc4b812b6),LL(0xe9d8af38,0x008e0bc3),L_(0x71a411c5), LL(0x27cb0dc7,0xc482b232),LL(0x07289ac0,0x5042230e),LL(0x68d763c4,0xa128b566),L_(0xc589940b), + LL(0x62562a0c,0x533b21ed),LL(0xb86a434f,0x398ba505),LL(0x5f1dadf5,0x5b2f618e),L_(0x35caca2b), LL(0xcaf4b249,0x74cf7bbc),LL(0xb14dae65,0xd924780d),LL(0x27c04cc6,0xf5af0266),L_(0xc41f13b5), + LL(0xfd136860,0x5727ef4b),LL(0x9fcc3538,0x2af297df),LL(0x957682ab,0xe33ed1c3),L_(0x9f83349f), LL(0x64693518,0x5961423c),LL(0x5148178e,0x8650191e),LL(0x66e2c6e6,0x5986c53b),L_(0xd5c63ac2), + LL(0x11b49c5a,0x9082e761),LL(0x5661867b,0x1815dbbc),LL(0x8ece3938,0x30442089),L_(0xeddde973), LL(0xbf2eb7b4,0x3e2f678f),LL(0xd4f64e91,0x15fb42e7),LL(0x49fdfa46,0x0b104178),L_(0x78b6687a), + LL(0x391a31fe,0x9f724691),LL(0x0ca4bf22,0x79581fa0),LL(0x730e0882,0x4bbc9bf5),L_(0x91d1e24a), LL(0xd756f110,0x26de9371),LL(0xd72ae23c,0xf050810b),LL(0x6ca80e46,0x75b289b3),L_(0x777ca3a2), + LL(0x8185a290,0x7d3fcac6),LL(0xebb7ace4,0x1f109f32),LL(0x48bb32eb,0x0be22833),L_(0x3f76d58e), LL(0x1868a043,0x8e3df32b),LL(0x00f1bf36,0xd5e2b1fa),LL(0x8b204654,0xdaeaa58b),L_(0x3263322d), + LL(0x742ad365,0x648b273d),LL(0x2e05e12c,0x9a066a23),LL(0x3a732a3d,0x691aae3b),L_(0x6cd91464), LL(0x04fe3ff0,0x208c6c3b),LL(0xe4c05b8f,0x61fcbdb4),LL(0xd9e2218e,0x59cd9a06),L_(0x835930df), + LL(0x33eb0d51,0xd984c49e),LL(0x888fc640,0xd7d25d0d),LL(0x9bb00fea,0x4da4ce0e),L_(0xaffa26c5), LL(0x72396942,0x2307b843),LL(0xc6cd9202,0xc1d18e97),LL(0x3f8ed768,0x518df91e),L_(0xeadd2347), + LL(0xc1d3ad41,0xaf9c00eb),LL(0xb90b0248,0x6b575b77),LL(0x45a5507d,0x2e1dac5f),L_(0x8db688a8), LL(0xab53ef89,0xa655bbf0),LL(0x0fdb8f93,0xea6e6754),LL(0xfdb2b439,0x9751d174),L_(0xaef8bdee), + LL(0x0aa602c4,0xb601c379),LL(0xdaadd78b,0x3a6533ad),LL(0xb65d4dfb,0xb3e4d63b),L_(0x653e4965), LL(0xf35d8a67,0x8cbfa3ec),LL(0xbaaa17fd,0xd9cd6c4a),LL(0xe29a388e,0x50eade40),L_(0x2ec73453), + LL(0xd1812921,0xbac1435a),LL(0xaa859487,0xf5d2dc01),LL(0xb5b2445b,0xe22a73a2),L_(0xaa1116ed), LL(0x39d4f53c,0xf9d72a85),LL(0x616cb03b,0x27cfb1ab),LL(0xcdf54ee8,0x4cf9a426),L_(0xe0208859), + LL(0x0749a748,0x5300262c),LL(0x7faf0467,0xbb0d7807),LL(0xff47f117,0x93b14cbc),L_(0x484a66c2), LL(0x91118c52,0x654db6c9),LL(0x20220d13,0x6b9ef224),LL(0x1162cfdf,0x897e3ec2),L_(0xf29d6809), + LL(0xf7481883,0x2c67eef0),LL(0x1a833a88,0x49af9414),LL(0x8aa0f2d7,0x5fc1c69f),L_(0x9f06aae9), LL(0x2b6f561b,0x4ecfeaa5),LL(0x17fda35e,0xbf5973f7),LL(0x338ff3e0,0x0013029b),L_(0xe6215b79), + LL(0x45cc9ed7,0x45530707),LL(0x3d6ab800,0xa1f8d140),LL(0x34dca331,0x5aa02638),L_(0x4dc086c8), LL(0x5be308ce,0x6df633bb),LL(0x90bbb8d8,0xd7e74378),LL(0xc7c28c06,0x8dcb3bae),L_(0xa0c24314), + LL(0x2b4b775f,0x7f227ccf),LL(0x8cd51cfe,0x8cb18663),LL(0x68ea58e3,0x9f7bcc04),L_(0x3003cc72), LL(0xdb7fa1bc,0x5b982b6a),LL(0xd5ebd68b,0x64a1222b),LL(0x675b50df,0x9679336c),L_(0xa8fee552), + LL(0x1db92746,0xe51e0a9e),LL(0x75eb0c92,0x584f0a75),LL(0x9af943f8,0xa54c748c),L_(0x28a759fb), LL(0x59c61e20,0x1cea2c6d),LL(0xb0384781,0xd54f4a86),LL(0xf0f73ecd,0xb65d1ecc),L_(0xd26a77df), + LL(0x6f8d4351,0xcb23a541),LL(0x51dd59db,0x3cb31aea),LL(0x24f458a5,0x7d0b3dda),L_(0x26b341e1), LL(0xb5440aa5,0x80d2e582),LL(0x9e2fd334,0x1b5ad25e),LL(0x114215cd,0x794f6e44),L_(0xe3bb54b5), + LL(0x119ef86c,0x01429cdc),LL(0x7fb2c053,0x994ee3e5),LL(0xee0b3bcd,0xcf236537),L_(0xca6a0781), LL(0x9d76f90c,0x28ee066e),LL(0xe18e5f40,0x18225dd3),LL(0xb1e0ccfd,0x2a9ed4ef),L_(0xa109a3af), + LL(0x9f94c8a8,0xad211acd),LL(0xe621f731,0xfa0ba148),LL(0x072030c8,0xa71de5a1),L_(0x106812c7), LL(0x57d3fed5,0xeac9452f),LL(0x4ce2ef8a,0xff6172a2),LL(0xac163954,0x778bc2dd),L_(0x2e5cbdab), + LL(0x6d06223c,0x0baf79a2),LL(0x9c81a4be,0xe2bee5ec),LL(0x9363638d,0x8a4d69e0),L_(0x687f0dee), LL(0xdceee166,0xa6d3323c),LL(0x202ed4a9,0x354badbe),LL(0x1c483cb2,0x5bbe8c1a),L_(0x433b79ed), + LL(0x2c4c3668,0x3828dbf7),LL(0xb8a0c6af,0x17810cb9),LL(0x9f12e96e,0xdd7d6cea),L_(0xe595dcab), LL(0x5b28c732,0xad54b44b),LL(0xe8aa36bb,0xb904d92f),LL(0x11dcc1c4,0xcbe63415),L_(0xeff9d401), + LL(0x29014f0c,0xfef9f39e),LL(0x1d099df3,0x4d9cac37),LL(0xbf9c0427,0xe387610f),L_(0x0cce0331), LL(0x95f296eb,0x31cb09c4),LL(0xd62d1375,0x7a5fdf3c),LL(0x53290cd4,0xa90e25d2),L_(0xf1396054), + LL(0x83b59271,0xf603ca7e),LL(0xe57e3a51,0xa2fe4449),LL(0x547b9c97,0x5234c386),L_(0x44edaf6d), LL(0x6f332534,0xcea690d6),LL(0xf13946cc,0xdad5199c),LL(0x6ad6bb4e,0x9374003a),L_(0x36c2bacd), + LL(0x9a4d019e,0x341c30ad),LL(0x7e1c2c9b,0x96ee26ce),LL(0x17e56dfd,0xb65db139),L_(0x9888703d), LL(0x4d9f2cbf,0xe07d7042),LL(0x3e36f84d,0x2223785f),LL(0xb4b9c74d,0xbbd020f9),L_(0xed1bc384), + LL(0x08bd06c5,0x4432f2cf),LL(0xa3a488e9,0xec0de874),LL(0x9efd00d7,0xd17c4829),L_(0xf5128936), LL(0x83542187,0x35e93b48),LL(0xae41e05a,0x22977d11),LL(0xe030a465,0x41a1010a),L_(0x1db1bce3), + LL(0xe96cbfbc,0x6fb1c1be),LL(0xfe5cfb57,0x46e0f43b),LL(0x401be370,0x29b356b7),L_(0xef6ca52e), LL(0x1769847a,0x131c52a8),LL(0x3084c2e8,0x9a3bea64),LL(0x58a36c5b,0x8cfd7a22),L_(0xa076e835), + LL(0xc50d8952,0x74382b8b),LL(0xecf54e6c,0x22c47953),LL(0x80a6564f,0x3378864a),L_(0xf29ac0df), LL(0x87ce0bb5,0x9549b954),LL(0x71036c3c,0xfdefd453),LL(0xd3203c72,0x57b0b3ec),L_(0x7ee244a8), + LL(0xc911b9a4,0x2a2ae110),LL(0xe00edfa7,0xc23eb58f),LL(0x6b68f39e,0x8f5215f7),L_(0x0b132723), LL(0x750f7a6d,0xe7d50418),LL(0x85673786,0xd615c040),LL(0x231c0709,0x487f22bb),L_(0xf5e2a237), + LL(0x2e68e2c2,0x95692ad2),LL(0x0b27bb26,0x72e6eaf5),LL(0x090be6f6,0x8b45b55f),L_(0xea84dd7c), LL(0x8e110b28,0x928497fa),LL(0x971d5f28,0x100a822e),LL(0x6339a104,0x9ddbd5c4),L_(0x3fe08c7f), + LL(0xdbfc1ac8,0x987de692),LL(0x1683a455,0xee7012c8),LL(0xb38e1de8,0xdd0a3684),L_(0xf01af5d9), LL(0x1923ae0d,0x86ab28a0),LL(0xd4b30cec,0x3a16a7ed),LL(0x22c7c599,0x01cadc9e),L_(0xb5dd36ac), + LL(0xa274d3dd,0x8baf2808),LL(0x60cc335f,0x7c5d7b61),LL(0xa633db28,0x732a899d),L_(0x7f9cd569), LL(0xe146b7a9,0x04bce2d5),LL(0x1f59a0d7,0x8db165c3),LL(0x6d10e528,0xcbb166ea),L_(0x7fe10619), + LL(0xa561b19d,0x04d81b3f),LL(0x88a7293b,0x9822961c),LL(0x1732c2f0,0x057b8676),L_(0x320d8861), LL(0x8a935dc3,0x5bfbc590),LL(0x3e5d907e,0x1bdbcf0b),LL(0x2b35a3ff,0x1597d44b),L_(0x7605acfa), + LL(0xe27abdf0,0x6112f38e),LL(0xf5ab47b4,0x12fd1d52),LL(0x5984ae07,0x4fccb7e8),L_(0x81972b3a), LL(0x95532439,0x5d4f964b),LL(0x905ded37,0x60b2cf53),LL(0x6a31fa69,0xfb6ad50f),L_(0xd83dca88), + LL(0x8f19b88b,0x1b0ac422),LL(0x711dde1a,0x9363a89c),LL(0xb5e309b2,0xac0aec46),L_(0x17ee236d), LL(0x5719b962,0x600531c2),LL(0xce093e55,0xee69dc7c),LL(0xec04dd4e,0x59639b52),L_(0xb9e01d45), + LL(0xca086bb7,0x1b94ace6),LL(0xb0fee2ec,0x3ed113f9),LL(0x5c0b8f2f,0xdfd59ee2),L_(0x6a154d90), LL(0x462e146c,0x8fb75d59),LL(0xb692d5e7,0xc31c3f9e),LL(0x080f7773,0x1fbd50fb),L_(0xa4f8f9e4), + LL(0x7b7f1009,0xf63f6da7),LL(0x2aa45a5e,0xf59e459b),LL(0x2d7d0b41,0x29c1bc69),L_(0x8aabebdc), LL(0xaf1dea2d,0xb0063dbe),LL(0xc38e3c41,0x335900c9),LL(0x661ba0dd,0x99541913),L_(0xc19809da), + LL(0x7540a87d,0xff252d35),LL(0xa1530a6c,0xaffcab72),LL(0xc8e9b570,0x9793a371),L_(0x3489107c), LL(0xdcf94c42,0xf0b49c6c),LL(0x879022b6,0x35c46e5c),LL(0x069dd468,0x2c618b82),L_(0x64bde16d), + LL(0x4335b182,0x2d08df94),LL(0xed7d7c9a,0x919ddb27),LL(0xe80a7f85,0x357baf28),L_(0xbb968f21), LL(0xbcb38a46,0x8315da92),LL(0x96e91923,0x925476f6),LL(0x4e306972,0xc5ed2a12),L_(0x950bbe41), + LL(0xcd3c90b3,0x39668cb5),LL(0x077167b6,0xaea10320),LL(0xfce255b9,0xb37bc6b8),L_(0xf3809a3f), LL(0x860aeccb,0x7f61816d),LL(0x44d57109,0x80e57881),LL(0xb19cf5fd,0xdb202875),L_(0x42100d63), + LL(0x5a155cef,0xaf246d29),LL(0x7f3965a6,0x329527e8),LL(0x8d8e3138,0x26bde524),L_(0x11b1a769), LL(0x66b0792b,0xd87dfaed),LL(0x707808be,0x02a38ada),LL(0x04bb89d1,0xe52cbe87),L_(0x7ec2d88f), + LL(0xded9227f,0x5423908e),LL(0x43d7285e,0xa6f72d9e),LL(0x49363917,0x6a49fc82),L_(0xf5d8d60b), LL(0x067bfaaf,0xa0f34345),LL(0x665a2267,0x19294466),LL(0x1ac20d98,0xffa2e5fc),L_(0x4e6d33c1), + LL(0x558d4d1f,0x9731dc1f),LL(0xf1f7a37e,0x6a85be9c),LL(0x69d32744,0xea51b61d),L_(0x05851633), LL(0xa0b1e63d,0x04e8d8ba),LL(0x1c8bd021,0xa75506f1),LL(0xef76ca45,0xf099b725),L_(0xd230047c), + LL(0xf47e0086,0x44613936),LL(0x62171491,0x0105d7a8),LL(0xa07a7b6e,0x9015ad40),L_(0x306c9555), LL(0x166467b1,0x18925a9d),LL(0xaac18583,0x8a300595),LL(0x7d220577,0xbbd4708e),L_(0xf151aaec), + LL(0x6807a39d,0x6e04c9ec),LL(0xb57b3b22,0xd4d3310c),LL(0xa3593866,0xa01b71df),L_(0xa63bab57), LL(0x378ccde9,0x773f947b),LL(0xefc9bc76,0xe29288bb),LL(0xcb328f94,0xe12b780c),L_(0xb068b3ce), + LL(0x3bf9b78d,0xc1916a89),LL(0x62555b0b,0xad0d163d),LL(0x00203bb0,0x82d7d36f),L_(0xd8764be5), LL(0x91a430b0,0xf446925f),LL(0xa23e8076,0xedc1e316),LL(0xb903dea6,0x11610026),L_(0xd83fceb2), + LL(0x8f55d6ab,0x2739ed0a),LL(0xcff10abf,0x3b4b462d),LL(0xe0b269ec,0x92761d90),L_(0xc1c0ca0e), LL(0x2403dfd8,0xab5ce41d),LL(0x62aaaef4,0x9ebcf2d7),LL(0x5a3ff0da,0x3aa250ea),L_(0x8f10b784), + LL(0x2fbc9b42,0xe5bbf62c),LL(0xa53f3f3f,0x2c19f9e2),LL(0x27dd1952,0xeada36e1),L_(0x40a88ecc), LL(0x8eac382d,0xca0a31a3),LL(0xd318529b,0xcc8ff4c6),LL(0xefec04d1,0x49d3e4dd),L_(0x55c20eb0), + LL(0x54347369,0xc5f830ce),LL(0xbf310209,0x66ba5a3d),LL(0x1372fe7d,0xab6a0dc0),L_(0xaf6004cc), LL(0x65a2727f,0x8803af60),LL(0xa6088f51,0x91e29b12),LL(0x53f144ad,0xe77f4280),L_(0xd7d06ab8), + LL(0x978295dd,0xc4969a0d),LL(0xdf19cc2f,0xabbb112c),LL(0x8bd7557f,0x554a3a06),L_(0x8fe8b8dc), LL(0x516a1ab6,0xf261d772),LL(0x82e07bc5,0x4d16bca0),LL(0xd1d7da5e,0x45447ad3),L_(0x19044418), + LL(0xe167f824,0x3956922e),LL(0xf66675c8,0xfcc5cc95),LL(0x20469977,0xf5f39465),L_(0x011863a2), LL(0xaf5616e5,0x960a1daa),LL(0x66b9d7bb,0x2c7f8f70),LL(0x074a85f0,0xd9f9bf2e),L_(0x7dd3b230), + LL(0x4e5dc71e,0xe5be9e2a),LL(0xb5995728,0xb7e24b2c),LL(0xa127aac9,0x23c8cef0),L_(0xf11df0db), LL(0xe494dece,0xefcf6a97),LL(0x38cfdd79,0x936e7033),LL(0x899c799e,0x8c265685),L_(0x7cab4cd9), + LL(0xdfd2bdce,0xe6160916),LL(0x480a36fd,0x01a7795c),LL(0x3f7c1b1d,0x91f84a8c),L_(0x85381912), LL(0x14463148,0xb7408da8),LL(0xe263f58c,0xbd7b174a),LL(0x8ca85525,0x8c2f9aa1),L_(0x687fc42f), + LL(0xa86b0be3,0xf5f78e41),LL(0x3455a3e9,0x135a0c71),LL(0x30c1c2c7,0xddf065a7),L_(0x3692f51b), LL(0xebc66e40,0x0f5906c0),LL(0xbfc2af37,0x5229db63),LL(0x5fa05ed1,0xd9f88327),L_(0xfad22122), + LL(0x6a2bd6b4,0xcbee3324),LL(0xe6fcf3f6,0xbfd3822c),LL(0xc3e92fcb,0x7c43be45),L_(0x6def0ea9), LL(0xe2791c4e,0x72baebe0),LL(0xabf2c782,0xad049ecd),LL(0xff1c5bf6,0x21f7b8ae),L_(0xcada1649), + LL(0xa204b629,0x2e618a14),LL(0xe44e287b,0x1ee56452),LL(0x9ec08fe0,0x3cbeeaa0),L_(0x41378416), LL(0x65a854a6,0x3defdbe3),LL(0xdd8dc723,0xe7d6715a),LL(0x6d23302b,0xf1849878),L_(0x922ac03f), + LL(0x826900c1,0xf4361242),LL(0x5150fa93,0xbc384de9),LL(0x1bf1d7e3,0x0106a9fc),L_(0x90827c46), LL(0xb45c094f,0xd4951e89),LL(0x046acfdb,0xf1ea11f5),LL(0x38e792fd,0x2d8ca425),L_(0x07e228cc), + LL(0x2b9cf3d8,0x889c6c44),LL(0x12d9fd78,0xc8a37703),LL(0xa6aed948,0x46f4af45),L_(0x4de1be3f), LL(0x229dbecf,0x932b6857),LL(0x4b284bc1,0xa90d9c3e),LL(0xe27e82bc,0x9200852f),L_(0xe41775aa), + LL(0x762bd870,0x50a8e4b7),LL(0x9d917e78,0xdf55385a),LL(0x4ac6dc2a,0xeb63b95b),L_(0x585b0c05), LL(0xf896eb5a,0x876d7f21),LL(0xdd6e7325,0xbc4c0b28),LL(0x34a78682,0x55d49e0e),L_(0x7de26ccf), + LL(0x0018e94a,0xf3430043),LL(0x09139313,0x6fccb693),LL(0x32e29483,0x9f0a6227),L_(0x1c584d56), LL(0x4da9fbc2,0x11cca785),LL(0x53203116,0x349e04d6),LL(0xb1c8440b,0x0ec04b4a),L_(0xb4fd311a), + LL(0x4e394c99,0x4a367cf0),LL(0x82ea7247,0x419778aa),LL(0x35a8f8e5,0xee0c8d61),L_(0xeb47eaf0), LL(0xb8c3b039,0x7fc38516),LL(0xb4361b1e,0xedd99fe4),LL(0x24e2fb10,0x94b8860e),L_(0x1e4ac934), + LL(0xb83e5822,0x9c7f7bc2),LL(0x85016181,0xec2c9c48),LL(0xae2e08c9,0x1d49bd53),L_(0xd51d0f76), LL(0xe02702a5,0x574b1fa2),LL(0x275045e3,0x4b568161),LL(0xe63f9064,0xb270bab6),L_(0xcbacaf10), +}, +/* digit=7 base_pwr=2^49 */ +{ + LL(0x28c9f54b,0x55cc3b93),LL(0x81366649,0x9f91db20),LL(0x0bb5529e,0x66b83a45),L_(0x020a3d7b), LL(0x84c6fb9a,0x6d9c718d),LL(0x4c39583c,0x6e5e8c08),LL(0x063ccb67,0x8cb7eb45),L_(0x01328b11), + LL(0xc3d2cc22,0x7e06eec9),LL(0x2a100811,0x5a959809),LL(0xf4997f3a,0xf5c07857),L_(0xad98c158), LL(0x5ae7c1cf,0xf408207d),LL(0xdb7d94f4,0x8cd5c2c0),LL(0x6379ef0a,0xf3bfa4da),L_(0xde775bfd), + LL(0xd39752a4,0xd08dfe44),LL(0x9b19df92,0x208bc436),LL(0xfd14af8d,0xcc3f5ace),L_(0x9cb59da4), LL(0x97f49ac2,0x880b584a),LL(0xe1fa2671,0x72d9f8ff),LL(0x76bf0449,0x0c870e3e),L_(0x6fb6d427), + LL(0xbad01fec,0x70db0532),LL(0x12b3f8dd,0xf82bbcfa),LL(0x167ab18c,0x92abaaa2),L_(0x5e4d357c), LL(0x4304ac9f,0x1fb69d3d),LL(0x7bd8f0e1,0x15e5d010),LL(0x47351320,0x84b31510),L_(0x6a03c6b3), + LL(0x739b3599,0x5a2c8035),LL(0x91588e92,0xdac9ebee),LL(0x1b69af1a,0x451b95e7),L_(0x3517cee5), LL(0xb64f8f05,0x1e09f842),LL(0x90930327,0x099f2550),LL(0xefa175e0,0x9e48451e),L_(0xedef520b), + LL(0x43b4b068,0xa2492064),LL(0x1e8946dc,0xeddb27dd),LL(0x9916090e,0x82135311),L_(0x98fdccc1), LL(0x4585ddd8,0x31f673e3),LL(0xd529f3ea,0xac4307ee),LL(0xb119ca51,0x428145ce),L_(0xcf53a57b), + LL(0x3728e89e,0x38640e71),LL(0xa872dbd5,0x745bd8a2),LL(0x8f90052e,0xffeb6e87),L_(0x9a484b77), LL(0xb85a7c0b,0xe045b6ce),LL(0xb3a39b3e,0xafd92044),LL(0xdbc53298,0x462a1b9b),L_(0x60a23eea), + LL(0x050b6e45,0x8a1c84ea),LL(0xc38a15ff,0xc2315710),LL(0x5b502e99,0x67d1f3e4),L_(0xf85c7d6e), LL(0xd3018572,0x7c34a744),LL(0x94062e0f,0x8b89ec47),LL(0x9579c983,0x35f7a266),L_(0x63ed902e), + LL(0xbfd3d5c1,0x7e6607ad),LL(0x54fa21c1,0xbc8c84d5),LL(0x2c3baf13,0x177b275b),L_(0x39001a70), LL(0x71f9447d,0xf4928a3c),LL(0x9356e91a,0xd23bd45a),LL(0x30b1d7ca,0x02772478),L_(0x8c5ecfb7), + LL(0x5717dffc,0xcaa887a3),LL(0x4f7bef32,0xb1687f81),LL(0x5dec8cf9,0x8965403a),L_(0xcc362cae), LL(0xb0dbc045,0x37f6ba20),LL(0x35e7cde5,0x6c266c6c),LL(0x0d54e5e6,0x02d7913b),L_(0xf4a0addb), + LL(0xdde83971,0xcc348a37),LL(0x58983641,0x18fb2236),LL(0x237be719,0xd585a061),L_(0xdb2539f1), LL(0x35a8a0dd,0x403565cc),LL(0x78351808,0x011a3765),LL(0x6202e956,0x7f54736b),L_(0x660d4fb3), + LL(0x90a83185,0x6bc9ce97),LL(0xb22311a5,0xf3cc61c2),LL(0xe993a41b,0x85025abd),L_(0x432e7fa6), LL(0x3a136918,0x42d19cdc),LL(0x18144346,0xe5b41dc3),LL(0x2bd73670,0xede484f4),L_(0xa93261b3), + LL(0x62a3c5f3,0x38a7a728),LL(0x2660c15e,0x05a1c27b),LL(0xcbfe2670,0xe7715ea4),L_(0x803ef610), LL(0xfff730b3,0x6f2eb06b),LL(0x3e73d7f3,0xafffff2e),LL(0x8fe4228f,0x2703c35b),L_(0x801d9246), + LL(0xcf3f9f32,0xa7b3253d),LL(0xb347bed9,0xb88a3be1),LL(0x23367d55,0x50ebab37),L_(0xe6bc8d5f), LL(0xb7d8a5f9,0x9df003d1),LL(0xd78ada2c,0x0bb08555),LL(0x4989b92e,0xf9b3e9f5),L_(0x2dbbe952), + LL(0x1b0c7f5b,0xdc3c1c11),LL(0xfb949b08,0x8d1cf002),LL(0x010b8835,0x69483176),L_(0x73825d94), LL(0x95d368f2,0x7caf4449),LL(0x3cd86c08,0xd50eaa5e),LL(0x8ba59225,0x6d5a74bd),L_(0x1e6e636f), + LL(0xda9ad1f1,0x51eea6ca),LL(0x69de6020,0x3afc7be4),LL(0xf383a0c6,0xa7aeef7a),L_(0xec5ab9f7), LL(0xe3d53f58,0xb56f14b0),LL(0x7b78f2d9,0xda9d3372),LL(0xb4e91769,0x0886a015),L_(0xb8c7fe1f), + LL(0xbb4c1b2b,0x7b2d2c19),LL(0x3f05a7cf,0xc24e67f7),LL(0x8a978fa5,0x2541de9c),L_(0xb09f953f), LL(0xbd943ed2,0xa6872621),LL(0x0275a86c,0x9f103457),LL(0xc3073baf,0xe68e138a),L_(0x70608786), + LL(0x94c887ac,0x22def543),LL(0xc1d1a75a,0x70845389),LL(0x9d05dd03,0x13908388),L_(0xcac954e6), LL(0xcee91dc6,0xfb37d06c),LL(0x42873dd7,0x0976cad9),LL(0x77686ddc,0xbd6e2bfe),L_(0x0a7aae21), + LL(0xf93e73a3,0xd00f349f),LL(0x6d3f30d8,0xbdf0b725),LL(0x793a6f93,0x8e54b8c8),L_(0xa3ebe240), LL(0xef42120a,0xd3635d7e),LL(0x7527fefe,0x954dc6a7),LL(0x7ecf5710,0xe5c193ac),L_(0xc5b359a4), + LL(0xcee954fa,0x6a69e07e),LL(0x904b6a99,0x28557756),LL(0x74691c8a,0x377aafb2),L_(0xf8dfe49e), LL(0xaf1c65b9,0xbc4bbf13),LL(0x32c37416,0xa07e7595),LL(0xa6bc7861,0xb481fbff),L_(0xab667972), + LL(0x4ade6d39,0xd40e7121),LL(0x03318c55,0xe035cb6d),LL(0x5cc23063,0x7d21722c),L_(0x353dafc9), LL(0x57f87e8e,0x47d32da3),LL(0x8e5c3c5f,0xdd769bba),LL(0x4c620a4a,0xc2e2dc49),L_(0x6ac8f16a), + LL(0xe2c62094,0xe0aae2f2),LL(0x27e1fc19,0xe8068cdc),LL(0x9a5089ff,0xd066d3ec),L_(0x83ce796d), LL(0x15285915,0x3d7bd85d),LL(0x2109b271,0xbfaee64f),LL(0x032bfaab,0x4c64918b),L_(0x28f7e9fb), + LL(0xe9c1a122,0x81a3a910),LL(0x1ec15d92,0x1d6baa6b),LL(0x0de6b8aa,0x25d33d78),L_(0xdb94f1aa), LL(0x84537b54,0xcda754fc),LL(0x0aa41bac,0x07667978),LL(0x26a33ede,0xaed5fcc3),L_(0x03b383eb), + LL(0xc6a270c7,0x48a0860f),LL(0xe3c9d6e7,0xe8f8a0be),LL(0x1c9dda6d,0x37a0510c),L_(0x87290f47), LL(0xb746897c,0xe0b9b992),LL(0x04968462,0x691f74eb),LL(0x79bcdef3,0xba7c23dd),L_(0x3c9dfbbc), + LL(0xb9c1ad2a,0x4867362c),LL(0x9b7dcff4,0xea98891d),LL(0xf6be4fd8,0x9dd99069),L_(0xfc837cc5), LL(0xc4b7695b,0xa104db38),LL(0xe73440a8,0xc1d73652),LL(0x557bc30e,0xca38a194),L_(0x0b9107de), + LL(0x08821106,0xf9b3c662),LL(0x0572aa2e,0xa9b0c578),LL(0x6cf8f9ea,0xdc3bb3a4),L_(0x578fa229), LL(0x935620c9,0x7b780978),LL(0xe2e55595,0xaa7bd737),LL(0x1ae5674a,0x7d70eb0e),L_(0x6287e785), + LL(0x8161a173,0x60277149),LL(0x6418b451,0xe9fdf471),LL(0x008c73fe,0xc7a41b44),L_(0xb52d2690), LL(0x6217c51d,0x07d5913e),LL(0x28af32f1,0x584cce8f),LL(0x70ace437,0x249d5a1f),L_(0xe2634904), + LL(0x2aa8ec2f,0x91c3f75e),LL(0x7ac06d6f,0x3279d284),LL(0x8cbbcc96,0x6114dddf),L_(0xb3f952c3), LL(0x18133afe,0x50a376bd),LL(0x95633a5e,0x281108f7),LL(0xf0277529,0x900af3d2),L_(0x2aac428e), + LL(0x34f686e3,0xede089c0),LL(0xafe013ca,0x66ca4aa6),LL(0x24f9b482,0x7d9ab065),L_(0x7064130f), LL(0x59e2f96d,0x88599e65),LL(0x1a8684d1,0x81cccdd4),LL(0x5b828088,0xa7784039),L_(0x274e2738), + LL(0xa482a439,0x04a64674),LL(0xabf54d81,0x3a3f5066),LL(0x46144f06,0xc232e58f),L_(0x30cddd92), LL(0x4aba099f,0xc2b48797),LL(0xfb8c420d,0x6eb5b117),LL(0xb4d97ee4,0x8d97d0d5),L_(0x8101b1e7), + LL(0x3dd4c04f,0x98af21ef),LL(0xcd4340b9,0x57885c4e),LL(0xda56271d,0xcf1eb8ab),L_(0xcfc8c025), LL(0x42508147,0x99747ee9),LL(0xdff889cf,0xbf581471),LL(0x16fb6025,0x22ae0ed8),L_(0x56d4b8ed), + LL(0x3d08ef7e,0x0745f517),LL(0xc7781923,0x732c8246),LL(0x6cd5a87c,0xe1112158),L_(0x734d96e5), LL(0x0ea91035,0xfbc17aeb),LL(0x7d6ae9b9,0x9fdb5814),LL(0x6b340fbc,0x7a81eba8),L_(0xa462be47), + LL(0xd9df5a31,0xbad5359e),LL(0xcc17a45f,0x137fb217),LL(0x3962aaec,0x18daea3d),L_(0x24dea50b), LL(0x585f316e,0x2db980d4),LL(0x94722851,0x890d4e8a),LL(0x17a80fda,0x0cd73f37),L_(0x0ef75926), + LL(0x7ddc10cf,0x2994a0c5),LL(0x0d862f7d,0xe8d6d38f),LL(0xa326bcf2,0xb39a090d),L_(0xebe228c9), LL(0x3fb2d1f5,0x4fe39e13),LL(0x292a329c,0xa1c6d77e),LL(0xa1f5d625,0x3f828ea8),L_(0x70ad621c), + LL(0x997cd647,0xb7237a23),LL(0x94de2084,0xf796b3ba),LL(0x0c93caa4,0xd97e1daa),L_(0xb74fa915), LL(0x4dfd621a,0x146706c7),LL(0x23c7b716,0xd56307f2),LL(0x54c6c8af,0xbe011ca0),L_(0x2ef6e4a4), + LL(0xa3b6fdcc,0x33851601),LL(0xbee34e4c,0xd7da0ee1),LL(0x8e7c506d,0x2b92ce18),L_(0x62b378cc), LL(0xc8c0d60c,0x95f16f73),LL(0x661c0891,0xdc466782),LL(0xf7df962d,0x6fdadac1),L_(0x8f3ef4f4), + LL(0x81a3d47e,0x23206f02),LL(0x235bc318,0xf375259d),LL(0xec43017e,0xc5d4dab6),L_(0xf547238a), LL(0x6f0f9561,0x25d0ebfb),LL(0x8357f1bb,0x8c478548),LL(0xe137e309,0x996a92a8),L_(0x629e8aa7), + LL(0xa2b3a713,0x4a17680e),LL(0xa8c7b143,0xe242039e),LL(0xb84edf8c,0xf2acd3a2),L_(0x8b3a07a1), LL(0x4d9e5baf,0x2f0d5861),LL(0xcd2f47fd,0xe42d316f),LL(0x0d4da406,0x0cd04a92),L_(0x8ec4fcad), + LL(0x6dcda792,0x91a38da5),LL(0x76eb9c38,0xa4b8df93),LL(0x0a5b71ac,0x2d328a16),L_(0xf6122daa), LL(0x9fdf7693,0xa1eceeb6),LL(0xe9555051,0x2371d345),LL(0x55020183,0xae8df945),L_(0xcee3a23b), + LL(0x4fcaf8f6,0x88241ba4),LL(0x6839ac95,0x25f7328a),LL(0xb01a4c73,0x4e73d41b),L_(0xdbce70d9), LL(0x470b6777,0x25457ffa),LL(0x4155bcf6,0x2545dcdb),LL(0x79b75849,0x3c25b38e),L_(0x8c33a19b), + LL(0x5375d125,0xb2bc7aac),LL(0xc7b2eb56,0x434f55ea),LL(0x8112c880,0x15208222),L_(0x612138e3), LL(0xd30babc8,0xa6392e60),LL(0x7fcbfb2b,0xc2c437cd),LL(0xb4541276,0x134be404),L_(0x3de33a7c), + LL(0x2cb35099,0x27c80981),LL(0x6d995371,0x15e5f210),LL(0x1e16c2dd,0x0e59bd58),L_(0xfbad79fb), LL(0x819dc1a9,0x481ca9ce),LL(0x6cb52c72,0x7ae12702),LL(0x7e9afc86,0xfda3af10),L_(0x41a661b7), + LL(0xbab0c519,0xc421cd20),LL(0xb68b5cf7,0x1e9b3f9e),LL(0x107cec0d,0x81208f8b),L_(0x383162ed), LL(0xf0c38656,0x2a8bfdfd),LL(0x0f977619,0xedf48fbf),LL(0x382decc1,0x8e5df4ce),L_(0xf0414c84), + LL(0x3083dd2a,0x15f29276),LL(0x89f9b2a7,0x717244c4),LL(0x817b0a58,0x6ee121aa),L_(0xf56eeafc), LL(0xcb4b4066,0x0bbfabbe),LL(0x52eb19cc,0x3641db33),LL(0xc2b09e5e,0xa82ae35b),L_(0xd9cf95b8), + LL(0x8dada775,0x017073a4),LL(0x4f731dd0,0x7488377c),LL(0xd07b63f1,0x5e605b0d),L_(0x4769aa10), LL(0xf9e533a6,0x26cfa7a4),LL(0xfac43672,0x077deba1),LL(0xbb074c5c,0xe02c4623),L_(0xb6536982), + LL(0x711f0c09,0x0bd8823b),LL(0xca3a4054,0xe696bd3c),LL(0xbee559f1,0xac8c4662),L_(0x54b8d320), LL(0xff20eb5d,0xfc9e136f),LL(0xafaff913,0x7fd1bf6f),LL(0x15a9349a,0x81208c2d),L_(0x0d06fd25), + LL(0x5b98ceba,0xc4906f43),LL(0x3cb8d3d5,0x671d2405),LL(0xef621a84,0x42fee26b),L_(0xcb150abc), LL(0xfa8ba5fe,0x8c081900),LL(0x2e00a64e,0x548ca8ab),LL(0x4b9fa7b4,0x7c4d0b48),L_(0x60c91243), + LL(0x612a3e39,0x36d03f9a),LL(0x7049620b,0xf3a56627),LL(0x29c0b51d,0x50448eab),L_(0x3f0b2dd9), LL(0x673df2ce,0x217c3b7c),LL(0x8eca2e20,0x17355feb),LL(0x20883efb,0x3afc2315),L_(0xc23211b5), + LL(0x4fe29bd3,0x3c1d5c97),LL(0x00ef3bc9,0xb31d8854),LL(0xf1f069cc,0xc5bebf01),L_(0xf661ac1a), LL(0x08af7536,0x54219e41),LL(0x25a7fa91,0x10eb2c79),LL(0xf217cbfb,0xf0d4c0bf),L_(0x4f2df7eb), + LL(0x0daa5bcd,0x8f2773da),LL(0xb21c4cfa,0x88c3cc76),LL(0x52c04b62,0x590a0567),L_(0xf35f4a84), LL(0xdf2a6679,0xcc2e1148),LL(0x04ae8b1c,0x340ba5a3),LL(0x92f66f03,0x4053731c),L_(0x20aba0c9), + LL(0x55e48460,0x0a4bb9e8),LL(0x9ad08ec7,0x4d8d0e03),LL(0x54a4bb3f,0xc9bcb020),L_(0xf5564618), LL(0x0bfda4fa,0x2f0cb8a9),LL(0x64275534,0xc49d2847),LL(0x33405050,0xd7e50869),L_(0xaf97cbcd), + LL(0x6faccf10,0x96f1d3cc),LL(0x9f391b14,0x4db1c834),LL(0x5f6bed3c,0x008d20fd),L_(0xc79a2572), LL(0xe2180f45,0x77d13f01),LL(0xb71f049c,0xf95c462e),LL(0xe088bd21,0xbd449f9b),L_(0x3a76432d), + LL(0x0405bf97,0x12dbb0ce),LL(0x4f53adb9,0x2a497b10),LL(0x13ff9791,0x61674465),L_(0xa80fdde3), LL(0xc0cc1d8e,0x50e102a8),LL(0x28391810,0x621706f7),LL(0xd119b153,0x47aca745),L_(0xeb9f0102), + LL(0xc5273792,0x6dc8e415),LL(0xb01555de,0xe0184e8d),LL(0xc5669efc,0x14d3a409),L_(0x0c68a597), LL(0x41d1a98a,0xed8dbd5f),LL(0xc5474f33,0x98419695),LL(0xd21a5750,0xf6b7aed6),L_(0x0d2d58af), + LL(0x4cd02456,0xb63ca144),LL(0xa81eba20,0x84079574),LL(0xf6e2c559,0x4e439115),L_(0xe8f8d978), LL(0x283b6289,0x8cf406a6),LL(0x23a5c7d1,0x4837878b),LL(0x4e16a72a,0x3db551d5),L_(0x88436ae6), + LL(0x334d8d79,0x32172eb5),LL(0x7d243c47,0x1ed58d88),LL(0x4a4714a6,0xed3510a8),L_(0xfde7f4a6), LL(0xb3d82e22,0x1ed13734),LL(0x4721f266,0xa661cacd),LL(0xf2889694,0x99b1258f),L_(0x45218687), + LL(0xd82826c7,0xe91d500b),LL(0xcf933e7f,0xdfae0ba5),LL(0x2d1ad273,0x572c7767),L_(0x79dbaa6e), LL(0x6b8ab0cc,0x17390031),LL(0x6c991f09,0x81e5fbb5),LL(0xbaab3192,0xfc86b907),L_(0x93c673b6), + LL(0xbe8c8998,0x3543430b),LL(0xc2f96d5f,0x50196f53),LL(0xac730ca9,0x376185cf),L_(0xfeac300d), LL(0xe73fa407,0x96df0a24),LL(0xf035d502,0xcdda229d),LL(0x9ca93571,0xd64df17a),L_(0x01970aaf), + LL(0x7ca6efb8,0x471f2098),LL(0xa5fb90b3,0xd70e4a72),LL(0x2aa370a3,0x09b936b9),L_(0xcfb37658), LL(0x3b357def,0xb2dfe05b),LL(0x1e8ce8f7,0x3594e46b),LL(0xcf8806b7,0xf062523d),L_(0xa1c74034), + LL(0x03cfe393,0x02fd45e8),LL(0xf0d5ce43,0xf575564b),LL(0x86092a2d,0xc28ad111),L_(0x0990658e), LL(0x70cbd16a,0x850acec1),LL(0x097c875b,0xc2704919),LL(0x79052ae9,0x651a1ec4),L_(0xdf5b00e0), + LL(0xd20da620,0x7c4aacf3),LL(0x12306aef,0x51b1a962),LL(0x0369e1f2,0x86d193a6),L_(0x3bdb2181), LL(0x93dcf8af,0x4d9c6a9a),LL(0x2e587a72,0xae32ac0a),LL(0xe30d76a5,0xaf97ed7f),L_(0x20fbaabf), + LL(0x94bc93d0,0x044baaf3),LL(0x04047c5f,0xf8872ab5),LL(0xe4e3879a,0x436ef7e0),L_(0xed64bf04), LL(0x11c91ee8,0xa9c7bdcc),LL(0xc1679bbd,0x006ae67f),LL(0x38ba10d2,0x83b598cb),L_(0xa99537cc), + LL(0x01ef166f,0x18eb43c9),LL(0x5aa367ce,0x93100d60),LL(0x2dc9b947,0x066d6c04),L_(0x3a41602a), LL(0xb9778f57,0xfcc4d377),LL(0x3dbf71fc,0x1d448cab),LL(0xc9ccbaae,0x0aacb390),L_(0x985954f5), + LL(0xa4179427,0x1f6e5aab),LL(0x4d58f138,0x64717e7d),LL(0x72e75855,0x389e7a2b),L_(0x4b5aa1e6), LL(0x12a92070,0x29d90bc2),LL(0xb35b2d2a,0x553f857a),LL(0xaca3b9cc,0x832c687a),L_(0xe2911a57), +}, +/* digit=8 base_pwr=2^56 */ +{ + LL(0xf505ff0a,0x56b1b68c),LL(0xa766a468,0x85630476),LL(0x7f0a8ccb,0x15b9ce0d),L_(0x8bfb375d), LL(0x8741f066,0xe7944b6a),LL(0xe502fd6a,0x8026fb64),LL(0x079ac7ac,0x956dea42),L_(0x3fc3f258), + LL(0xbd407e63,0x7157aab7),LL(0xde649372,0x62a53378),LL(0xec032ca1,0xdc9ac491),L_(0xaf00af85), LL(0x5a1b0fb3,0x3d3a586c),LL(0xb1b4ed91,0x6cce27ca),LL(0x0da4ec47,0x2fb5dda7),L_(0xe69eb235), + LL(0xa2c9ee34,0x4a718a90),LL(0x6813c47e,0xaf44fcce),LL(0xcc1aaacb,0xbae4540e),L_(0xfd6dde20), LL(0xf4786198,0xa1399699),LL(0x47c1ef53,0xabb23a85),LL(0xff24f01d,0xa1779b32),L_(0xafe60f72), + LL(0xa9ef8159,0x6e7fd2ab),LL(0x206a6f14,0x802458a0),LL(0x43a11c7f,0xf31bbf6c),L_(0xe2ff97fb), LL(0x893d191b,0xb83101a9),LL(0x0b2c24c6,0x52ca6e06),LL(0xd00a24aa,0xc5ea4420),L_(0x80054822), + LL(0x3173ee97,0x5d302b85),LL(0xa3ec0bc2,0x275a0fe0),LL(0x7469b929,0xde033220),L_(0x9823907b), LL(0x06ebb14d,0x8d35908d),LL(0x668b8357,0x8a0b74c2),LL(0xcd96886f,0x388da84d),L_(0x8e759b7d), + LL(0x82c45d8b,0xb0068631),LL(0xb87f256b,0x51283056),LL(0xb7562059,0x554d7fad),L_(0x68b8bed1), LL(0xe9ccc163,0x5349ed31),LL(0xaa23f48d,0x0ef896e4),LL(0xac744603,0x125ee820),L_(0x150da1ca), + LL(0x546f326b,0x16a4c78d),LL(0x26b49a2d,0x42a579ae),LL(0x69e5dc3a,0x50449596),L_(0x2af6b2c1), LL(0xde7ccc7f,0x07439dc4),LL(0xf5736c67,0xacbc3d69),LL(0xeeb790dd,0x0cc523dd),L_(0xae2f8bbf), + LL(0xf1c49667,0x1c12b2d5),LL(0x7628ecee,0x7bc41dbb),LL(0x0692cc8d,0x65398808),L_(0x5048f64f), LL(0x2cde35bc,0xd880351d),LL(0xae75c4fc,0x131f80e2),LL(0x3e2ff89e,0x5f9ca860),L_(0x435a454d), + LL(0xfc6b3603,0x1dbe11f0),LL(0x805cdd89,0x0ed82341),LL(0x0562fe66,0x5d6a45d5),L_(0xc9eb9f56), LL(0x02dcc377,0x1fbcb272),LL(0x4b25d574,0x873a72d5),LL(0xb78a31c0,0x1466b27f),L_(0x468c47f5), + LL(0xba96c374,0xb836e3e5),LL(0xf6743281,0x2c1ed972),LL(0x13f41d4f,0xd77d4340),L_(0x397a6846), LL(0x748b4159,0xbd735496),LL(0x6560f3f3,0xeadd97bc),LL(0x61405ead,0x119c162c),L_(0x9870a7f1), + LL(0x7c46ea86,0x4f81eb05),LL(0xdd4548bd,0xaad784b0),LL(0x49ea4452,0xff17a13f),L_(0x54ebcb9f), LL(0x810464d0,0x3e7236a8),LL(0x4d44b2ce,0xfe62fc5f),LL(0xfeac4aaf,0x0d85cf3f),L_(0x7d7cb315), + LL(0x4ea682b5,0xb0f78fa9),LL(0x82bbcdcf,0xa319bd52),LL(0x01559ec4,0x7cdb7afd),L_(0x86ff3957), LL(0xc4e5e26b,0x6c320e71),LL(0x45b1afec,0x8d455eef),LL(0x9d12c298,0x6b93f2de),L_(0x3e21f849), + LL(0xbb797884,0xc12b655d),LL(0x219c2865,0xa6ec705d),LL(0xc6daf8cf,0xf3ec2977),L_(0x10269fa7), LL(0xf0951e7f,0x8de615f1),LL(0xb448dafb,0x0e454e35),LL(0xac03ce6a,0x0fd25b12),L_(0xb96afd44), + LL(0xc1091d62,0x069f14f0),LL(0xc970df0c,0xa04696ef),LL(0x8cddee54,0x0475ddb9),L_(0xac228ae6), LL(0xda3d6fc8,0xc73f5026),LL(0xbdeb5cb1,0x475ad247),LL(0x82098200,0x8694111c),L_(0xc11479ab), + LL(0xf181f7b2,0x0c73fe98),LL(0x4aa502d3,0xe9de471e),LL(0x6c27909f,0x4f620050),L_(0xf76957c1), LL(0xe0c4eaa1,0x1565b30a),LL(0xfba38431,0xb518ef0e),LL(0x65c7038d,0x82a6a124),L_(0xe7db47e4), + LL(0x56f2fd55,0xfdab8dbd),LL(0x773fef23,0x198d2eb9),LL(0x011efbb9,0x8698e8b3),L_(0xa4f63ad2), LL(0x8629eaf2,0x60003ff6),LL(0x5aebc019,0xd2455886),LL(0x00bcb9de,0x859f79cb),L_(0x6a9d21d2), + LL(0x7a576508,0x8a59362e),LL(0x21480f43,0xbd8af994),LL(0x4a37a459,0xe55838d3),L_(0x36aab717), LL(0xd4ef1a0b,0x1d33aa1b),LL(0x86dc1133,0xe457ffeb),LL(0x0a1e4a76,0xf9d8ea27),L_(0x7a9f7b61), + LL(0xc6332530,0xf5ab77c1),LL(0xb7c034fa,0xcae4753a),LL(0x89204639,0xd0dd8159),L_(0x4ba725f9), LL(0xae3159be,0xa510602d),LL(0xc72415fe,0xd6d54251),LL(0xa6bc7ccc,0x7d585ae6),L_(0xc90e9462), + LL(0xb6723f1d,0xaed13815),LL(0x84f02e2a,0x6de52d8b),LL(0xffdbb5f9,0x3c9269f7),L_(0x5c61743e), LL(0xb086030f,0xd5bc6378),LL(0xa9132224,0x607634ca),LL(0x12f65fd8,0x817445f8),L_(0xd0c982b8), + LL(0xfb02a22b,0x40f7fe3d),LL(0xcb5018ef,0x34d86234),LL(0xf32b39b6,0x621a4bd4),L_(0xe7c33edc), LL(0x974f5440,0x7972a383),LL(0x586d4bef,0x8b71269c),LL(0x81211aa8,0x8c46dfe1),L_(0x5b192417), + LL(0xe3e15473,0x30ddafb0),LL(0xe56640a6,0x71464526),LL(0xe01ca53a,0x6b7735ff),L_(0xa4ba7379), LL(0xfee843b7,0x184d5072),LL(0x1f2853f9,0x0b71f2dd),LL(0x0c65322e,0x77546dfc),L_(0x814529cf), + LL(0xbb7e4da9,0xe44092c0),LL(0xdcf36025,0x6e08eec1),LL(0xa38b0382,0x2beaabb1),L_(0x57dab020), LL(0x30b6f340,0x3fc25cd9),LL(0x16190d52,0x0d13ca42),LL(0x632514c8,0xc69b7cce),L_(0xcb82be1e), + LL(0x3eb4e07f,0x79d31336),LL(0x78cc588c,0x986322bf),LL(0x5d3ca505,0x0951b466),L_(0x82b9278f), LL(0x20636a0f,0x6c160f3d),LL(0x308d56c2,0x62ceeabd),LL(0x460ed898,0xcccc63ee),L_(0xd27b55ac), + LL(0x81017a2d,0x2097cb5a),LL(0x6fb48059,0x423d9fb9),LL(0x8b4a82f5,0x3bf0f71b),L_(0xda304a5b), LL(0x0620aba2,0x5d609c9d),LL(0xb32599e2,0x77106961),LL(0xea5b4567,0xc072d5ff),L_(0xf9f2dc57), + LL(0xbe531971,0xdacba735),LL(0xbc32b9c9,0x4c64a7d8),LL(0x154849a8,0x29e4dd9b),L_(0x11dfc29e), LL(0xbaa9dc51,0xc8616f73),LL(0x971ba9a3,0xf61450f4),LL(0x15776b0b,0x8325c930),L_(0x294a4ec5), + LL(0x86967b01,0x16f8969b),LL(0x235d5c34,0x3233bbff),LL(0x57aa97db,0x5c79afae),L_(0x417467c4), LL(0x2f6f6091,0xe7950968),LL(0x59ca92ce,0x9d943f83),LL(0xb1a7c34e,0x6203a921),L_(0x066a9647), + LL(0x759f1a19,0xfb7e2683),LL(0x84d55477,0x96a642c6),LL(0xbdee722d,0x74bfcbf4),L_(0xf514f2bf), LL(0x80d0ae79,0xba7058a3),LL(0x4713d1ae,0x6c24158b),LL(0xa6c17b5f,0x8941ddd8),L_(0x261d9ac7), + LL(0x943bc0de,0xac5e5ce6),LL(0x76370390,0xd093dc4b),LL(0xfce7f694,0x7c34fbe8),L_(0xe3b42849), LL(0x4b4bfe6f,0x8781925a),LL(0xe273ae40,0xfe87a94c),LL(0x777881ae,0x6fc64556),L_(0xb0f8e854), + LL(0x498275e5,0x024a93d4),LL(0xa6b66d66,0x05a83965),LL(0x56c335af,0x0805e125),L_(0xe1e39e4e), LL(0x059f9143,0x9bb438e6),LL(0x0e8dde7c,0x1ec8aae3),LL(0x06a38af8,0xa234eb6c),L_(0xd74870f8), + LL(0x0883fffc,0x05b51c39),LL(0x62d8ac43,0x839148f1),LL(0x8eefcd87,0x3b151865),L_(0x3c047e9d), LL(0x197a8a18,0x76ea2960),LL(0x82998a41,0x8a3902cd),LL(0x110b3b2f,0xbcfe60ba),L_(0x89b19d6d), + LL(0xab6f3543,0x8765ec48),LL(0x36e47913,0x1b75763b),LL(0x767e806b,0x81bc9bd7),L_(0x38103684), LL(0x0f165768,0xb8107b90),LL(0xbe9c24b5,0x54d331ef),LL(0x43623ea1,0xf06a675d),L_(0xcbeab5be), + LL(0x8e21820b,0xd064269b),LL(0x1ccbf4e2,0x7020a8a8),LL(0xe21fbca7,0x5cee0a5c),L_(0x263913a5), LL(0x8a6b9ebd,0xa3fc8bad),LL(0x047f1949,0x838a0019),LL(0xd1a5d116,0x35a0d475),L_(0x9e3419f5), + LL(0x742ad243,0x36c9f808),LL(0x631145ae,0x2db0aada),LL(0x0c423277,0x4bf70210),L_(0x2f1584d5), LL(0x6f50ff50,0xa19699d1),LL(0x8015f024,0xc8530fc5),LL(0xf9755c59,0x25538f41),L_(0x387ddb31), + LL(0x1985efbe,0xe8509933),LL(0x9e321e61,0xb8ff1d78),LL(0x7dc68e42,0xf8206e77),L_(0x58e783b2), LL(0xad8c32f2,0x906883cc),LL(0x6f41c769,0xa42d4644),LL(0xbb9527f5,0x38e2f27d),L_(0xcf17789e), + LL(0xf5dd9f3b,0x1bf5a9f9),LL(0xae648e71,0xe8b2f305),LL(0x3f5f8275,0x93245241),L_(0x80482c3b), LL(0xb0e6f457,0xef9f19aa),LL(0xaa9e665a,0x6dcb7ba1),LL(0xad522975,0xce379c80),L_(0xf8653e32), + LL(0xeea9e807,0x19d1e570),LL(0x4023698a,0x5fb46b4e),LL(0xa19db2ab,0xd2800586),L_(0xaee5fc4c), LL(0xe6f0c329,0x378c9ac9),LL(0xbcb82922,0x142d0bcf),LL(0xc3b8fa15,0x1b19035c),L_(0x1c3a4f74), + LL(0x074cbefd,0xf201d616),LL(0x88de2216,0x703ef032),LL(0x409f13a6,0xfc1697ff),L_(0x1f4ee383), LL(0x4f0ae8bc,0xc70f2c0a),LL(0x596702b2,0xf1e207d2),LL(0xaa0989d3,0xcc60a8c2),L_(0x5ba1fcbb), + LL(0x4e7d0964,0x3f768dfd),LL(0xee929e0b,0x0dda310f),LL(0x171719ee,0x91e6ec5d),L_(0x48549719), LL(0xb61e9fad,0xa3e2860b),LL(0xa30f11a1,0xa7e2c8e0),LL(0xf804fa42,0x58c435e7),L_(0xd81ff657), + LL(0xd7d22038,0x3ee264ba),LL(0x6d74b27a,0xf3577276),LL(0x776b6b64,0xa97538c5),L_(0xdc494d53), LL(0x89e972aa,0xe4acc7fd),LL(0xe5d1ac83,0xf7c63ea2),LL(0xf0a59879,0x9b5f787d),L_(0x0730aa6b), + LL(0x6c13249b,0x5d202340),LL(0x15ca4cef,0xfbbc39ae),LL(0x03078647,0x7cbaad05),L_(0x7a152a3a), LL(0xc0834b0b,0x5c759c2f),LL(0x1d48b5cf,0xc983dd84),LL(0x954731e0,0x67babf9e),L_(0xb890cb9b), + LL(0xeefdbd63,0xfbda2538),LL(0xd314af3a,0x77f9df03),LL(0x333f8c94,0x07bcc285),L_(0xd37bbc81), LL(0xadb373f3,0x7ba7309e),LL(0xe5686c59,0xb6c90f3a),LL(0x96218ea6,0xbfb2d48e),L_(0x7bc6fa2a), + LL(0x5c8452f6,0x91273fc0),LL(0x9f330845,0x12ba358a),LL(0x8d3155c9,0x229515d9),L_(0x4e0d0091), LL(0xaeed3a8c,0x3cca8a70),LL(0xc538ea5c,0x8528e080),LL(0x7f68ef37,0x412db800),L_(0xfc39477c), + LL(0xc1f84a4a,0x202d77cf),LL(0x3f50f1ae,0x94eeda74),LL(0xc9d43dee,0x2163dc89),L_(0x82838e71), LL(0xc916bedb,0x68b2f3b4),LL(0x028beb58,0x32389e93),LL(0x2f67136b,0x63c11941),L_(0xf0576d72), + LL(0x5b467cc7,0x79a7908a),LL(0xfe08b743,0x237e35d8),LL(0xe4c9aa02,0x3121fc40),L_(0xe6d6660d), LL(0x1c0060e4,0xcc2b942e),LL(0x54acd180,0xab155509),LL(0x4b3ac4d5,0xde75824c),L_(0x91ca23fa), + LL(0x4201e6e0,0x46582482),LL(0xa927f3c9,0x78c500df),LL(0xe88a4310,0x1f445777),L_(0x3e33ca59), LL(0x2a806dc7,0x71dd2626),LL(0x54a8126d,0xc14947d3),LL(0x9c986434,0xbec3ed13),L_(0x71db698f), + LL(0x422ef39a,0x731eb54c),LL(0xa93b1752,0x61227804),LL(0x6f7bfa09,0x873d3a45),L_(0x4f66d06f), LL(0x6fc87ed2,0xc97be3e6),LL(0xf6435b79,0x338ab476),LL(0x207b9b6d,0x1c6c74ae),L_(0xb64b6b70), + LL(0xfd951bda,0x74ccc359),LL(0x4be5a10b,0x44c6bf22),LL(0xb790b940,0xc32a94b3),L_(0x098b38b5), LL(0x57ac1bc0,0x4ef7c296),LL(0x18feb7b4,0x82d9c658),LL(0x6f3016a9,0xad72b80e),L_(0xbdf2db87), + LL(0xcffa9aa8,0x0ca1adfd),LL(0xb13f2859,0xed4f750d),LL(0xd393e869,0x277e9cd1),L_(0x90b15b52), LL(0x9386d23f,0xf705f504),LL(0x2c2d2fb1,0x98b6973f),LL(0xf49260e8,0xcb991398),L_(0xfed48a8d), + LL(0xb2b27562,0x2687c047),LL(0xc3ca0fc2,0xe54d1276),LL(0xbb9d5b5b,0xe241d7c5),L_(0xef9d2be9), LL(0xe9d4f361,0xfe8acc56),LL(0xc5011f32,0x5fc31f72),LL(0x8545eca9,0xfa8d83be),L_(0xc270dd4a), + LL(0xe5151a0f,0xb3951e08),LL(0x78a942de,0xdd13a9d6),LL(0x57fae761,0xbc46ee6e),L_(0x83169c42), LL(0x2d1c6395,0x340fc521),LL(0x669821ab,0x24a2322a),LL(0x09548072,0x92a505ce),L_(0x83ec59bb), + LL(0x0a4dfff3,0x3ce8adae),LL(0x41ed0956,0x7f33cce3),LL(0xc0e55577,0xba8eb552),L_(0xa018b90e), LL(0xa0f2bcda,0x67316cff),LL(0x5703fba5,0x58c433f9),LL(0x6078c1e4,0x99f221d3),L_(0x047eec80), + LL(0x41f43d8c,0x81739c7f),LL(0x6f11b810,0xae918a0f),LL(0x1e314860,0x9ddc21df),L_(0x18e4d189), LL(0x558db016,0xe78c5637),LL(0x439dc1dd,0x0de5812f),LL(0xa22acbf8,0x9f469794),L_(0x161460c0), + LL(0xb19e5bf0,0xcd4a85b0),LL(0x7e2cff5d,0xfd828b89),LL(0x998dca20,0x3d5bd0f7),L_(0xbfc65978), LL(0x176f7759,0x388987a0),LL(0x9b689b7c,0xed6c490d),LL(0x3ea487dd,0x5b3b94d0),L_(0xa77864e1), + LL(0xdff87175,0x39413fad),LL(0x796a4cff,0xf20c6ce8),LL(0x978f94f4,0x2c42836e),L_(0xdabb2333), LL(0x344fb7ef,0x683de92c),LL(0x5fe8df50,0xe072aff6),LL(0x705a1d2a,0xf68dcb2c),L_(0x16e49003), + LL(0x04c5b257,0xc7d4f66d),LL(0x02ce592d,0x679405b4),LL(0x449fe24f,0x49708f6f),L_(0xe167be96), LL(0x3f036191,0x7456adb8),LL(0xafdb07bc,0x63213856),LL(0xfc9ec5eb,0xb52ff28e),L_(0x55b069a6), + LL(0x0dfb54c3,0x1b0cec1a),LL(0xf4484ca3,0xa32d497c),LL(0xde798874,0x05b5ac5f),L_(0x87ada89d), LL(0x771e433f,0xbc022aca),LL(0x93b1313e,0x5af43a1b),LL(0xa4d9094a,0x71a6efc0),L_(0xd897f8e5), + LL(0x8e365581,0x5f811bb2),LL(0x9a725a78,0x04edaa41),LL(0x1f6cfcf4,0xe1abeb72),L_(0x6d3872f8), LL(0x6636d80e,0x90cec4c4),LL(0x400da758,0x751efdbb),LL(0x74d4d54d,0x6fed8555),L_(0x4bc5cda0), + LL(0xed247186,0xb4a54351),LL(0xa9b678d4,0x349f3364),LL(0xf079b22c,0xcd89ee25),L_(0xec3738e6), LL(0x9a75388b,0x1754341f),LL(0x3b3edf75,0xe93c6d27),LL(0x46732c66,0xcfead94a),L_(0xa689fe7e), + LL(0x46839b8d,0x91cb6be2),LL(0xa3af0a2d,0x68643eeb),LL(0x37e8c56e,0x44cf93c9),L_(0xc55af358), LL(0xb74e3e18,0x2941f1b6),LL(0x85525c49,0xe580c8b8),LL(0x7fe18358,0x32c35949),L_(0xbf4a513e), + LL(0xf3da6204,0x8adf6261),LL(0x6619bed5,0xe7cd8eab),LL(0x5bb1a013,0xdac22d18),L_(0xe70d7542), LL(0x64ef4466,0x0bfa91a1),LL(0x195a05ff,0xb9ce90fc),LL(0x52bb429e,0x34d0f00f),L_(0x904ed07d), + LL(0x335940e2,0x4331ebb8),LL(0xf071319d,0x6f7c1728),LL(0x05e7c4f2,0x1da3b676),L_(0x7abf809c), LL(0x1a1e3a9f,0x9290a717),LL(0xf68174d5,0xab7b1f25),LL(0xa93e4d8a,0x7f4cbc44),L_(0x93b784f5), + LL(0x5640e88e,0x7b8373a5),LL(0x1bf6e31b,0xcdec2eb7),LL(0xb8888fa2,0x010ee8af),L_(0xa7cd3971), LL(0x2d9ffc40,0x7e33265d),LL(0xc3866a61,0x26755d7a),LL(0x9e1bb3f0,0x9be25bb9),L_(0x1c158895), + LL(0xcbffc265,0x187246e4),LL(0xcb1700db,0xcb116afc),LL(0x3aa73e7a,0x93e55e2b),L_(0xb2ba60e5), LL(0xfa8aa297,0xbcfa0106),LL(0x253d2d5c,0x4919fb96),LL(0x9fa1e7c7,0x04ad0152),L_(0xd483d4ee), + LL(0xce14b1f7,0xd95b8ba8),LL(0x1d6eb61c,0x20d43399),LL(0xc7ef0d06,0x47b3133d),L_(0xf255931e), LL(0x5d5a0b15,0x60b98074),LL(0x2344f6b6,0x8b1f2bd2),LL(0x789f9baa,0x00302e85),L_(0xccdbabda), +}, +/* digit=9 base_pwr=2^63 */ +{ + LL(0xfb42e9d6,0x228b3a54),LL(0xd1e183b4,0x3efd699d),LL(0x4948ad88,0x18288fb9),L_(0xf45f24f0), LL(0x23d7207d,0x37574acd),LL(0xe86d0db8,0x57c32be7),LL(0x1ccef3f9,0x451b09b7),L_(0xee7d7495), + LL(0xa61d5325,0xd52a1c1e),LL(0xd08a8ae3,0xcb34540a),LL(0x750d587a,0x03e86cff),L_(0x27e73149), LL(0x156ef6cf,0x527a9877),LL(0x96f4a96b,0x6ee444f1),LL(0xe4a1f249,0x038153e5),L_(0xd9998bb3), + LL(0x2bb80640,0x281ef606),LL(0xee8331e0,0x73bbb0b4),LL(0x71264953,0xa04c6f5a),L_(0xecfe722b), LL(0x85f7bcc2,0xbb4ca37a),LL(0x8ff53f4b,0x6e5931f6),LL(0x42ab81a0,0xb862be64),L_(0x8ba40994), + LL(0xe1ee20f3,0x3c280032),LL(0xa9734b49,0xc6f2aff8),LL(0xb12f26d4,0x3686d2f0),L_(0xe0111b72), LL(0x8bf62e5c,0x7a48daba),LL(0x069099d5,0x63c661a3),LL(0xaba55aed,0x6cdc05f3),L_(0x4ea7440f), + LL(0x33a9ba23,0x4a15994f),LL(0xe99a66d4,0x022ffe96),LL(0x4d054e49,0x924ebb42),L_(0x155f0d8c), LL(0x4d774618,0xe319a1e3),LL(0xe6d591f2,0x8f71c6dc),LL(0xe9b13d22,0x0834867a),L_(0x39cb42c0), + LL(0x4edd01ad,0xb4a0a7e3),LL(0xd28d49c3,0xb472df44),LL(0xab2cbbd4,0x4cb47055),L_(0xcd15bd1f), LL(0x31800301,0x16ef99e3),LL(0xb349d462,0x78a8538e),LL(0x746c4b41,0x4dce044a),L_(0x56cf52da), + LL(0x7bf3d9bf,0xb1b9c2e9),LL(0x0196cebe,0xaaa33f41),LL(0xdb961af6,0x51023370),L_(0x68f286d7), LL(0x8d6b25f5,0xad763cf9),LL(0xa07bb401,0xe4c3391f),LL(0xab25bfde,0xac71bbe8),L_(0x06a272b6), + LL(0x33ad9d0f,0xd727b458),LL(0x6aab9dfc,0x340cf8e0),LL(0x695de110,0x078f906d),L_(0xa987a86e), LL(0x65ed9ae8,0xd50493d4),LL(0x3eb5588c,0xb2673304),LL(0xce9abc84,0x101a021e),L_(0x2ec773ad), + LL(0x492a4dda,0x7bdb0ab2),LL(0xb55a240a,0x08dd2523),LL(0x06998948,0xf475a7f2),L_(0x04f12f32), LL(0xd2a94b0e,0x688143bd),LL(0x73021050,0x5bdf7bb4),LL(0x325ed38e,0x8114699d),L_(0x467cd567), + LL(0x3e7baca8,0xcbfe120b),LL(0xe69958d1,0x56a88710),LL(0xa2e1385c,0x9586b08e),L_(0x8d8876e4), LL(0xa05f5596,0xe749a357),LL(0x85028619,0x62d3a285),LL(0xf41d9b86,0x8430e884),L_(0xe0fe7436), + LL(0x449eb800,0xe20a701b),LL(0xbc42935f,0x63dac155),LL(0xaf260958,0xb55c4fab),L_(0xb5f1b7b4), LL(0xbaf2a69d,0x3e2c715a),LL(0x61856276,0x158e35b0),LL(0x447c4419,0xfaf57b99),L_(0xa5a859f6), + LL(0xe7457d94,0xa50c7d9f),LL(0xaaf263e7,0x5bd93ac0),LL(0x27bdb99e,0x28bc6b58),L_(0xa291a83e), LL(0xfed995c1,0xe155fe7a),LL(0xa92f7c72,0x441255d1),LL(0xfdebd3d9,0x54ea2480),L_(0x1d9b3247), + LL(0x8cfadc9d,0x3bb14260),LL(0x40205f43,0xf6fea697),LL(0x1e5b99d9,0xf68ea4a3),L_(0x99449ff0), LL(0xc42cccaf,0xb4680c53),LL(0x6506393b,0x1cded754),LL(0x9fa16281,0x355805ad),L_(0xa8869c1e), + LL(0xa2b679a7,0x1fe90870),LL(0x60faf2a7,0x841d50a4),LL(0x74445704,0x97761552),L_(0xc6294a8b), LL(0x88aef1a6,0x8306971e),LL(0x79313f41,0x8a08da74),LL(0x459c33b3,0x5ff5c231),L_(0xa47413df), + LL(0x528acbac,0x8931a009),LL(0x1bb13907,0x64ec461c),LL(0x6e5d6bd9,0xf62b4e1f),L_(0x419ecc6e), LL(0xb5b1b6f0,0x2e05fe26),LL(0xa9d7ebb7,0x5484c570),LL(0x46afc58b,0x2c8381f8),L_(0x243d0786), + LL(0x67588c0e,0xa5a5886a),LL(0xd9832e54,0xf569db1f),LL(0xc764b06f,0x38ed1085),L_(0x7eb63b3e), LL(0x11a2a8db,0x585bdb20),LL(0x8a62c89d,0x3d5436af),LL(0x5e301e9d,0x35b91587),L_(0x4e488867), + LL(0x2e0bb083,0x9471249c),LL(0xcfed9152,0xd02dc9b6),LL(0xf83f6a42,0x859a1f08),L_(0x67c5e1b0), LL(0xfa3c9fbb,0x40557a70),LL(0xa37c1374,0x180e4d9f),LL(0xecd05a92,0x7635cd74),L_(0xccd0d7f7), + LL(0x0ad7acbd,0x02596d63),LL(0x81ed48b5,0xf3957977),LL(0x8ec54e25,0xfd23aeec),L_(0xa7513cf4), LL(0xfa5cf86c,0x8f6097dd),LL(0x2a1c180b,0xea60f2b6),LL(0xacdc4130,0x253dbb93),L_(0x9daa0c3e), + LL(0xece03d73,0x5f61e12d),LL(0x3336043a,0x1b5a6c4a),LL(0xa83c1fea,0x77fedd08),L_(0x64002d5d), LL(0x6ed15df8,0x08aaa0a9),LL(0x210df7fe,0x6ccfd556),LL(0x6b43ad21,0x98ade169),L_(0x42a1a05e), + LL(0x701d31e8,0x6e92d485),LL(0x8a6e2064,0x53a09da0),LL(0xc92637e7,0x4ee89ae2),L_(0xa8cbe2a0), LL(0xc8b9f5ad,0x688111d2),LL(0x1fafd02e,0x75a9c058),LL(0x315d9dc5,0x0cd0654b),L_(0x02890b79), + LL(0x24746253,0x131fab03),LL(0x1ac884b5,0xda0c0ec6),LL(0x8a1a27c7,0x66f76b97),L_(0x254a6db2), LL(0x8c4da1c1,0x17450bac),LL(0xd2c4396b,0x988596ca),LL(0x2691986c,0xd9864a47),L_(0x31c0544b), + LL(0x24fed0d9,0x2f0f74a0),LL(0xf3ddaad3,0x28c66344),LL(0xa0f85074,0x55736fde),L_(0x9f28ac0a), LL(0x0c8f2cd4,0x5b08d2ff),LL(0xaaec443d,0x96848bd3),LL(0x9fd17e0f,0xb4213134),L_(0xf10e3114), + LL(0x0077c0a8,0xd9301e91),LL(0xa6577039,0xdf36f0d6),LL(0x50e6f1b9,0xf5e86ab5),L_(0x58a7b434), LL(0xe0f8d5dc,0x2f0371f4),LL(0x1d3d9546,0xeabede08),LL(0x39c8d544,0x12bf2df1),L_(0x57a123a0), + LL(0x3878d553,0x817dc769),LL(0xfd0338c3,0x60a4d34c),LL(0xb99ba802,0x36e30856),L_(0x1dcffb49), LL(0x8ba72940,0x665a28b4),LL(0xf1016ea1,0x9d6822ea),LL(0x86a30740,0xc3331f1b),L_(0x0205d1d8), + LL(0x69c5e4bf,0x8628180f),LL(0xd7ae93c1,0x7ead547c),LL(0x227716ff,0x736914e5),L_(0x605a49ab), LL(0xec82f273,0xa3fd7cc4),LL(0x99cf069a,0x60d1dc75),LL(0x93c53857,0xdc5b96cb),L_(0x080bcc0e), + LL(0x5adf052d,0xf2335efb),LL(0x398d73b0,0x9cde465e),LL(0x00bb4ee5,0x212ffe0a),L_(0x7ab2ea4d), LL(0x9a9ad333,0xe2f332a2),LL(0xeeeaddc8,0xbb4703c4),LL(0x2962d309,0x143e5fcc),L_(0x49553c63), + LL(0x99cf8b3c,0xc941479d),LL(0x203c4316,0xe6b52643),LL(0x855dab4e,0x717ef700),L_(0x4ed7e83c), LL(0xe00ddd9b,0x494ccfde),LL(0xe90530ff,0x94ed4ea6),LL(0x8222ad9a,0x4430a4d7),L_(0x252e55b2), + LL(0x53d9c3c5,0x96506aa3),LL(0x3f484d6d,0x4d8a0741),LL(0x10e92da9,0xbd490fb2),L_(0xffd03214), LL(0x5fa8cebc,0x95792257),LL(0x7dfe3775,0xe4e706c8),LL(0x9120d23f,0xe2412ec1),L_(0x1de70984), + LL(0xa39f223e,0xcb479a89),LL(0xe7cc4f73,0x0ea9b422),LL(0x1382187c,0x9dc7e0af),L_(0x01c1bd80), LL(0x530c072d,0x7d0256e7),LL(0xbd971088,0xbcc29991),LL(0x7ac3d22e,0x36e29a92),L_(0xecf0d361), + LL(0x28113fdf,0xbb9273c9),LL(0x4c568852,0x6ab4dc1c),LL(0xf3f274f5,0xb258fcff),L_(0xdee7fe95), LL(0xf7dd8fb6,0xea16df71),LL(0x3f7227a1,0xf774dfb9),LL(0x8865b774,0xc554b491),L_(0x10280ec0), + LL(0x32e80670,0x0aaf5932),LL(0x600576a1,0x0829e9bc),LL(0x63228df7,0x7b64399d),L_(0xb12890cc), LL(0xce0e14e3,0xf166eabe),LL(0xa3e9c521,0xa17a6f3d),LL(0x01f649df,0x33266d1a),L_(0xb179110c), + LL(0x0d9efc66,0xaedb7e51),LL(0x2d780714,0x3d4cd6e3),LL(0x76c48d11,0x95533ca3),L_(0xef834a13), LL(0xfcf0269c,0xbb0ea84c),LL(0x8bf5f008,0x2e995288),LL(0x0c5e907a,0x5462d73b),L_(0x1d6aecec), + LL(0x80c6b892,0xb5bf76ef),LL(0x2e91623e,0xaf49e877),LL(0x1415663c,0x15fea421),L_(0x1f1c3707), LL(0x71645fb0,0x03dd8cca),LL(0xb068031e,0x639980b2),LL(0xd50a50f4,0xbde1692d),L_(0xc8df6655), + LL(0xb536b786,0xa49675be),LL(0x923698c8,0x410ff3c8),LL(0x9ea67a42,0x67f23bf8),L_(0x4444d11f), LL(0xbb783ec9,0x05829e19),LL(0x18b3a870,0x79d71996),LL(0x8b8364e8,0x917428eb),L_(0xafd1b685), + LL(0x391fe0d9,0x5cdc38f5),LL(0x8bdefd85,0x653fae2f),LL(0x60854dd0,0x5650f1c2),L_(0x3d41abd0), LL(0xb709cc99,0x338d5d07),LL(0xd45495b6,0x840a9918),LL(0x10d2d56f,0x05c210e8),L_(0x2709cd44), + LL(0xd04c44b0,0x3d513962),LL(0xb778f7da,0xedf97e8d),LL(0x237a1a75,0xb843c30f),L_(0xfe6c9001), LL(0x52dcbf0f,0xb7f1d85e),LL(0xdfc37735,0x3f355190),LL(0x63ca258b,0xbcb01029),L_(0xaad826a1), + LL(0x74f4c74e,0xf2d99edc),LL(0x3824eb60,0xcbcc9613),LL(0x96cabc5a,0xdb4188d8),L_(0xe5012748), LL(0xbf865e18,0x100a7041),LL(0x73b6c9c4,0x922a5abc),LL(0x4b2e4ffc,0x3c179919),L_(0x35fd801d), + LL(0x274742c8,0xfba7fe0c),LL(0x71487144,0x4d838b83),LL(0xa5684725,0xde29806b),L_(0xaf1f4b15), LL(0x3c9d276d,0x0418df98),LL(0x3da078d2,0x970cee18),LL(0x9504ef04,0xd6fca127),L_(0x68282ff5), + LL(0x2c2165ac,0xa4371233),LL(0xf24ea908,0x340a8ba9),LL(0xbf610642,0x751d8536),L_(0x169f256b), LL(0xa6be26ab,0xa7afba2b),LL(0x66d0d844,0x20c6f4fd),LL(0x292f0814,0xb9773f57),L_(0xc95c32ed), + LL(0x975db7a6,0x931f72a8),LL(0x2d2921a4,0x75be82f0),LL(0xaabec6ae,0x93be322a),L_(0xe0530ac5), LL(0x4d6dd8a4,0x21ed4c4a),LL(0x3539fb21,0x702437c5),LL(0x54c5601d,0xff29a4db),L_(0x33f41e0a), + LL(0x957fea7b,0x92370d49),LL(0x2b5f5d00,0x1feb014c),LL(0x9ce3670e,0xc246a235),L_(0xcfeee196), LL(0x58ffdb8b,0xc688f198),LL(0xc992ad9e,0xee953054),LL(0x3828369e,0xc2172706),L_(0x9016c246), + LL(0xf2b16a57,0xd8546f62),LL(0xf288a32a,0xf4996e54),LL(0xd866770d,0xa8e0a566),L_(0x41c5b1a5), LL(0xa81aa974,0xc8eca336),LL(0x06f5713c,0x7317dc66),LL(0xaf5394d4,0x1c420a16),L_(0x05bdbb33), + LL(0x3d683b90,0x8e6a5c3e),LL(0xf167321f,0xd4ab4b02),LL(0x4806da87,0x98fd2767),L_(0x23e3b0df), LL(0xf9faf1d6,0xde00e6e4),LL(0xa65aaac7,0xb82c1e61),LL(0x603b9246,0x39526356),L_(0x6098239e), + LL(0x1471049c,0xdf432ea3),LL(0x989bae16,0x08aae4b3),LL(0xcdff8338,0x1f3f8b31),L_(0xe12f868b), LL(0xa96b85c5,0xc59a6e02),LL(0x3e2e2a6e,0x679432f4),LL(0x35623aa8,0x66bc9d0b),L_(0x419d9c04), + LL(0xd12c1c29,0x3e403fad),LL(0x80a49b71,0xb3fa108c),LL(0xa16aaa21,0xc0552283),L_(0x941ac341), LL(0x5f01091e,0x78d10e07),LL(0x9e2010ad,0x78aaa1d0),LL(0xc3d626dc,0xad4eebe0),L_(0x616d3812), + LL(0x77d51621,0xa85af39f),LL(0xc44a4210,0x41d18ad2),LL(0xd700b9c9,0x00fd9c15),L_(0xaaeaf056), LL(0xcb08ab64,0xcc55572b),LL(0x58e16fee,0xdedd8934),LL(0x224b2130,0x27e82ee6),L_(0xe838331f), + LL(0xc76dfaad,0xf7314697),LL(0xc2d9578c,0x651c0514),LL(0x28f766e4,0xe5782e17),L_(0xdb1237a2), LL(0x6bb64cbb,0xdcb19e7b),LL(0x382be491,0x9ac56c1c),LL(0xf76d352a,0x0749b544),L_(0x7968d6a8), + LL(0x07203eb5,0xceb29d96),LL(0xe4a0f31c,0x3f66d60f),LL(0x62bd6086,0xc9e0da34),L_(0xd2a91a43), LL(0xeb1e3a08,0xf153aa4a),LL(0x13715918,0x07234640),LL(0x5c701eb4,0x3cc2d39d),L_(0x21bc78c7), + LL(0x481eb504,0xd3a03cad),LL(0x5f6a9d91,0x1d390d95),LL(0x3753e069,0x733ae857),L_(0x58532343), LL(0x4de25ac2,0xc858b2c5),LL(0x423a2e5e,0xd0e29a40),LL(0x03c6d3e7,0xbd4e4f93),L_(0xb99af7a6), + LL(0xf347240e,0x74665b47),LL(0x00f3a821,0xd4995fe7),LL(0xbb254497,0xae564546),L_(0x09235190), LL(0x8aa0bb23,0x148c2b64),LL(0x44c9ade6,0xd4712255),LL(0x01120f40,0x2095b0d0),L_(0xc2cfde05), + LL(0x7058189d,0x9096ca15),LL(0x0b95bea1,0xf2ebd4a0),LL(0x92a3cb12,0x403109c3),L_(0x67ede54a), LL(0xc8d15887,0xd330e122),LL(0xe94c1522,0xbc6cec87),LL(0xcf570b75,0x8c60e503),L_(0x7b779c33), + LL(0xc396d1d3,0xb7a09eba),LL(0xb7df5c36,0xa4ad2686),LL(0xda7c16c6,0xea76230d),L_(0xe12538a4), LL(0x5c153671,0x35168d66),LL(0x22a3c5aa,0x7317fdf8),LL(0x90a1a3b8,0x488f516d),L_(0x4a17692d), + LL(0x427a3fed,0x979163af),LL(0x5261367c,0x67750f39),LL(0x2b64c77f,0x121123d3),L_(0x57b5327b), LL(0x1ae75801,0x60be5340),LL(0x4320f770,0x1c82e2fe),LL(0x80d5de38,0xbfa35c85),L_(0x804730a8), + LL(0x7c65d352,0xfec3e94c),LL(0xe49a8416,0xe15daed0),LL(0xebea12bc,0xd561b8e1),L_(0x1b6939a7), LL(0x80b4e8f4,0x689cf9a4),LL(0x0a52d61b,0xe93a4cce),LL(0x2707af62,0x00163171),L_(0x888d6c2f), + LL(0xdaeed59d,0xcfab7c64),LL(0xd2cae7f9,0x5781a043),LL(0x10e60343,0x1e1d00e2),L_(0xb1b2d682), LL(0x8a649d20,0xbc56c4a9),LL(0x87923cc3,0xa8b43dfb),LL(0x05fa3aa6,0x07ea55ed),L_(0x08a82010), + LL(0x208d5b3c,0x5178b723),LL(0x10a520c7,0x2d1f55b2),LL(0xb1fffc0d,0xbbad0a50),L_(0xab6af890), LL(0xce6aec24,0xf8407690),LL(0x2bcfca02,0x1c5424aa),LL(0x56944f46,0xaab35dc1),L_(0xa5c174f8), + LL(0x957be638,0xd8227572),LL(0xfd6ac99b,0x7fcc54ba),LL(0x4081f3db,0x7e998f3d),L_(0x08e76dcc), LL(0x3ffd1f3b,0x1c7b8f2b),LL(0x0551cbe8,0x76e4b694),LL(0x045398f7,0x93712a63),L_(0x31b716ac), + LL(0x9ccd7f23,0xf2590188),LL(0x1074bc24,0x14031de7),LL(0x9d9df6f6,0x1a06a2f7),L_(0xf880ea5b), LL(0x9cc577d5,0xe509ec7a),LL(0xc7021265,0x864b62e6),LL(0xe9189561,0x09271f5a),L_(0x910bdd23), + LL(0x1f12f8d6,0x258fd822),LL(0x28518543,0xa7361b32),LL(0x338b1788,0xc4796256),L_(0x636fbcb3), LL(0x4f5097e8,0x0aff7ca0),LL(0x9306ff92,0x3deb3281),LL(0x6a18552c,0x5ba5cce7),L_(0x563c7d80), + LL(0xf184055c,0x0a2d6941),LL(0x682b34d2,0xba0b737d),LL(0x467f7fe4,0xa7e4e833),L_(0xfb7c4f69), LL(0xceeed886,0xd5513495),LL(0xc4ac863c,0xcc4688b1),LL(0x74229c34,0xd5e5f34b),L_(0x729a99ef), + LL(0x33e6967e,0xca92d3be),LL(0xacf9987e,0x27e6ecfd),LL(0x84c9d53f,0xa434a89c),L_(0x0ac3dbe1), LL(0x3f16aded,0x05a4b104),LL(0xbbe7f4a2,0x9d1faddd),LL(0x2222c720,0x0091add4),L_(0x5e600780), + LL(0x6e5923eb,0xe0a35b29),LL(0x5acac230,0x1ca3d3f2),LL(0x5089506f,0x57de9730),L_(0xf05a525b), LL(0xc963a675,0x8c76bd08),LL(0x74d9f43b,0xdeecdd8c),LL(0xdca2c05b,0x4bcbac2f),L_(0xdc6633b9), + LL(0x60601ff6,0x1bc30bde),LL(0xa7ddd558,0xcac4e4e0),LL(0xe21dd977,0x66baebc4),L_(0xb4d573cb), LL(0x79ee6d3c,0x352d2cee),LL(0x3c8cf82d,0xe3db9857),LL(0x12474a96,0x8d29a0c1),L_(0x55049164), + LL(0x3ff1fac3,0x8806d22d),LL(0x827b3141,0xe5b92d9d),LL(0xc0bcac45,0x45f1bee6),L_(0xe2c1046e), LL(0x368d7809,0x0b973abe),LL(0xc60d4681,0x6f45c847),LL(0x05dd04f4,0x1ae3e5bf),L_(0x64bbe857), +}, +/* digit=10 base_pwr=2^70 */ +{ + LL(0xad2244ee,0xa40697e3),LL(0x6dcf122e,0x379dd18c),LL(0x179d681f,0x177fcb32),L_(0x2e1c6f2e), LL(0xd9f2b14a,0xdfe5e464),LL(0x4c70a028,0xfcfc8017),LL(0x6183ea61,0x4d64db2b),L_(0xd053bce3), + LL(0xa9c848c0,0xe6f3cecd),LL(0x3c37feb1,0x1953cde4),LL(0x857f0263,0xbbc0b11e),L_(0x091b8ddb), LL(0x46acc3ea,0x8541cfa6),LL(0x772c3ab4,0x7c142776),LL(0x71e71be0,0xcd2d8bee),L_(0xd29d11b6), + LL(0xc6b24ae6,0x4b9ffc6a),LL(0x8ee5427c,0x4a42092a),LL(0x997ab138,0xff6b61a7),L_(0x3b574c18), LL(0xd6cb4977,0xbeade6c6),LL(0x315f47ce,0x2e2d5dc5),LL(0xc77bac27,0x39f2d0a5),L_(0x28b192db), + LL(0xa902a170,0xdfa7909e),LL(0x374a8799,0x93925c6a),LL(0x121579dd,0xb4c9c6a6),L_(0x2b2a2fe1), LL(0x421343f7,0x2dec18b9),LL(0x467e925a,0x4a7ce3d6),LL(0x51b39839,0x33d05082),L_(0x6dd45eec), + LL(0xaf22f4e9,0xe4793da0),LL(0xce68ae65,0x6d70ff7a),LL(0xdf1eb924,0x67519764),L_(0xa6d12a17), LL(0x9c9b86f4,0x1e13ad01),LL(0x43f0840b,0xebcc7b33),LL(0x648dece5,0x0b8a73e1),L_(0x9e1099c5), + LL(0x3ee5fb2f,0x00e5b507),LL(0x16e7b26d,0x02eb10ab),LL(0x2fb5b17d,0xf5f94483),L_(0x964b96f7), LL(0xb10c75ea,0xb577452b),LL(0x8083550f,0xcf241d80),LL(0x2f106bf6,0xe11783de),L_(0x0cfd54c0), + LL(0x598729b4,0xd3bf6d02),LL(0x6afe9c51,0xfb3e35f6),LL(0xbb0f1cd8,0xb0816531),L_(0x27df4a0c), LL(0x2f8214c2,0x72f5b39b),LL(0xc24bf200,0xdd44ad34),LL(0x39525315,0x2d46495a),L_(0x758c33c9), + LL(0x6fa7c2c7,0x9c7bf299),LL(0x2cb77bd8,0x4a4734a4),LL(0xb7245ac9,0x0a33b879),L_(0xe50ef27d), LL(0x3e4bd3ce,0xb91f6979),LL(0x1ca8036c,0xf8b8d90d),LL(0xbee50919,0xf053ecd4),L_(0xece7c952), + LL(0xe88a9300,0x990b1bdd),LL(0x0420911c,0x516f881a),LL(0x4138b100,0xafe94d6f),L_(0x24ff9ef4), LL(0x4c68e2d4,0x528a709b),LL(0xa50cb647,0x19ff7b20),LL(0xbb306765,0x907cbbc6),L_(0x74217b89), + LL(0x0a371fe5,0x0bab31b6),LL(0xcccd2b33,0x69aaf848),LL(0x5f8e6b05,0xb7efd33b),L_(0x4cd501f3), LL(0x117abd54,0x83d20ea2),LL(0xf475121c,0xa34d2ec5),LL(0x47427d11,0x6eb988c6),L_(0x7acc59a0), + LL(0x96650b0d,0x591ee335),LL(0x16ee1f0b,0x26a19153),LL(0x27985f50,0x7a51d8bb),L_(0xfe74d9ab), LL(0x276b185c,0xaa92cd9d),LL(0x9ed60020,0xb66c17eb),LL(0x2a0eac87,0x18315901),L_(0x8dbf60b9), + LL(0xe73f9dd1,0xaaf7ef5f),LL(0x3d3b7078,0x315302f9),LL(0xf09fd9b4,0x00b8f278),L_(0xf7dd85ca), LL(0x4140a60e,0x54e7df9d),LL(0xe305da30,0xaef051a2),LL(0x67dd41ab,0x88c0e226),L_(0xc437eba8), + LL(0xaecd7f62,0x938be7f6),LL(0x7f0d8c8a,0xe465c032),LL(0x74f9489c,0xba77e9c0),L_(0x529b3458), LL(0xbea77798,0xfea9f3ec),LL(0x93d7e4fe,0x6ec5677f),LL(0xce0cdb8b,0x1c3846b0),L_(0xe0a036d5), + LL(0xa818d0c9,0x3b25f1dc),LL(0x640f0895,0xf998244a),LL(0x6a36628c,0x0a1631ee),L_(0x22c92416), LL(0x79522c82,0xb5997002),LL(0xa3c8067e,0xbaf242be),LL(0xe28f2eda,0xca50379b),L_(0x0c2d44ef), + LL(0x7e8a5165,0x1879da9a),LL(0xf1be18cc,0x4b28b798),LL(0x5708ec80,0x088da37b),L_(0xa743ca6b), LL(0xa1588631,0xd86f2e95),LL(0x9bf8faf1,0x97dcfd6d),LL(0xae7389fc,0x784c1096),L_(0x1aa41e81), + LL(0xf9a13e9f,0x2380678e),LL(0xe93e1c94,0x3f5ce533),LL(0x68003338,0xa4954b13),L_(0xfa7015a9), LL(0x63905ece,0x3e892821),LL(0x19b8125b,0x4b7bb992),LL(0xd66a6ac0,0x8579e7ef),L_(0x7516c1ae), + LL(0x21560c47,0x8051f521),LL(0xfd3b4b27,0xa4371e4f),LL(0x8947385a,0x8c0cdac3),L_(0xd7eaeef0), LL(0xc46bf169,0x0639dd0c),LL(0x862785aa,0x9ec7e487),LL(0xd61bc685,0xd861b3a5),L_(0x83d3ee5e), + LL(0x930059f4,0xb145ba07),LL(0x2aaf9072,0x30f8ae06),LL(0x2f3077a1,0xbc426169),L_(0xc99c4c21), LL(0x6c57976c,0x6ee68683),LL(0x236b0866,0xb9cd4e70),LL(0xe6b22138,0xaa9f8c57),L_(0xc8cde662), + LL(0xed492587,0xcedbdd1a),LL(0x51eec28a,0xe84b42a7),LL(0xd4deae6d,0x9e368887),L_(0xaded26ea), LL(0x1bd18dec,0xf79fe229),LL(0xa610dbd9,0x0d650fde),LL(0xc8e53036,0x8d4db547),L_(0x6d7b9831), + LL(0xb55dd50b,0x6d88e9da),LL(0xaf929b4d,0xbb1af641),LL(0x09f3ff8a,0x2c88cea6),L_(0x95aa1478), LL(0xf6e2f2aa,0x4d819416),LL(0xe1f9b46c,0xce813081),LL(0x3fdecbde,0x368fe183),L_(0xce1f9cb4), + LL(0x55d27a4e,0xb55224a5),LL(0xc92c61ce,0xbd06485e),LL(0xe42fc5df,0xbae2229f),L_(0x3afc274c), LL(0xa273191e,0x85cd8bfc),LL(0x97118ed0,0x9c9c61a0),LL(0x5e361376,0xaaf47545),L_(0xcad4d556), + LL(0xfb2444ed,0x18d8ff5c),LL(0x18b51ba2,0x3dc74bfd),LL(0xaf0eee18,0xfc1b2868),L_(0xbb73ea5a), LL(0xd68ff57a,0x88d94a2f),LL(0x730a7041,0x162bcf15),LL(0xd183ab03,0x9867c6b2),L_(0xf198711f), + LL(0x817437d0,0xf225ca3a),LL(0xebadfce9,0x2afa4968),LL(0x7b328600,0x09069b77),L_(0x1091afcf), LL(0x82fb3189,0xdcc4bc5d),LL(0xf1844abf,0x49ace070),LL(0xf655f51c,0x7e393926),L_(0xa022dcd5), + LL(0x13b3c6d8,0x32d143d6),LL(0x07002476,0x37eefa5a),LL(0x028e4eac,0xf7ed9d04),L_(0x65e3cb55), LL(0x22c86f9d,0x1cab2511),LL(0xdf940bc6,0x50c1e3f3),LL(0x734bf045,0x2643f52d),L_(0x11593f75), + LL(0xeaec70bc,0x1759457b),LL(0xcee75815,0x1ef41bc8),LL(0xbfd1d973,0x5f64050d),L_(0x6b3087eb), LL(0xda22e615,0xc045345f),LL(0x776dfb51,0x3f9aff61),LL(0x07f4f3a2,0xb17003a3),L_(0xb6a6cf4d), + LL(0x9276438a,0x53f04642),LL(0x8525ef52,0x1397f8d6),LL(0x9a0888e4,0xde6f955e),L_(0xda028b89), LL(0x4292050e,0x2711d946),LL(0xd109e67e,0x70541c9f),LL(0x19b5f6f0,0x75754b8c),L_(0x85c8d6d5), + LL(0x3073bee0,0x0a0de3cd),LL(0x725322a6,0x3ecd54ab),LL(0xabf6f3c4,0xeb4d3502),L_(0x6dfedcca), LL(0x12c56dbf,0x08adcae7),LL(0x33d4bd69,0x0b5e164a),LL(0xcfe1b693,0x659e68b8),L_(0x82c86924), + LL(0xc347067e,0xd351d4d7),LL(0x141df0b6,0x5fe38868),LL(0xaaee8341,0x6a97a114),L_(0xaafe4f6c), LL(0xc0912e86,0x3ce36b09),LL(0x4106201e,0xd6174b63),LL(0x40106385,0xfda3c463),L_(0x9e471096), + LL(0x21aa62bd,0x15f6014c),LL(0xb5217d60,0xf4c26c02),LL(0x421c3d60,0xcc23ecec),L_(0xc0f18f53), LL(0x08c04fe6,0x1ae450ba),LL(0xf66ae880,0x7520566d),LL(0x2e31cf5b,0x1b3a8046),L_(0x916c70ac), + LL(0x47d17a16,0xd287d1ca),LL(0x3e47dc5d,0x291a00ca),LL(0x42cffa9b,0xc6ddb9b7),L_(0xb751c3c5), LL(0x6b576fb2,0x7f3bfdc3),LL(0x8676c057,0x05c5c887),LL(0x2f6a12cc,0x4e43cafd),L_(0x273385a8), + LL(0xae17a9c0,0x1d472cf8),LL(0xb53ac163,0x1569367f),LL(0xf1c57e24,0x5f7dfde3),L_(0x53f9522b), LL(0x45eaeed1,0xf3d29713),LL(0x3c47cbaf,0x7a261ef7),LL(0x561e0755,0xbe952c4a),L_(0x6bcd178c), + LL(0x63cc0fbd,0x24b41db6),LL(0x36a421ac,0x34bd0f29),LL(0xdc178877,0x619cb9a4),L_(0xa266089e), LL(0x7b84d003,0x9fd8767d),LL(0xba9a6d1f,0xa5381512),LL(0x8cbdf583,0x46c198f4),L_(0x23f49a00), + LL(0x65bc3562,0x281cc4e9),LL(0xc3d2804e,0x7562f859),LL(0x22a16679,0x638a7949),L_(0x7ec2aa7b), LL(0xe6c7330d,0x187243a5),LL(0xb99ca6d8,0xee353b2a),LL(0x2d4040d0,0xbd604fb9),L_(0x8cefbced), + LL(0x1fc30151,0xfbd9e1c4),LL(0xd10937a9,0x0f7ffd5e),LL(0x2fa67094,0xe7b103db),L_(0xb57b1840), LL(0x39530ea9,0x1368261d),LL(0x719e1d06,0xc1336cad),LL(0x192c11f5,0xa6cd197f),L_(0x9b41db84), + LL(0x37505def,0xd68a5a49),LL(0xddd06586,0xb0511d2a),LL(0x52664a68,0x2621ebc3),L_(0x6f5736f5), LL(0x2fcaf173,0xd267f258),LL(0xbacb7a85,0xe5e678b7),LL(0x5c0b0c67,0xaa7c18e3),L_(0x166ad375), + LL(0x669558fe,0x9a21bdfe),LL(0x8411fa8b,0x06c5b604),LL(0xde70b24d,0xf5bd9bc8),L_(0xd7443ed1), LL(0x0a439533,0x2b84584e),LL(0x3ea3f8f2,0x2cf8fe06),LL(0x099fde13,0xbc0565bd),L_(0x8fd32c81), + LL(0xc291b778,0x7e78ce16),LL(0x12d214f6,0x6d2b8e47),LL(0x5f204c64,0xaf966aac),L_(0x62d03da4), LL(0xe9be215a,0x0fc086e5),LL(0x14494699,0x77fd96e7),LL(0xcc71f940,0xec60a687),L_(0x65805046), + LL(0x4b6c94b4,0x1ee6996b),LL(0x8eb81a1a,0x5a56077f),LL(0x547ea701,0x71308d2f),L_(0x9126c06e), LL(0x9fdcaccb,0x5fecdc40),LL(0x49cacc43,0xd04d1212),LL(0x89bc7a7f,0x6331b109),L_(0x93db1b8f), + LL(0x2b6470fb,0x18292505),LL(0x93a8f9cc,0xe0d6f3f0),LL(0x8d658c23,0x33eef875),L_(0xc22c9665), LL(0xb09b3b96,0x2081f85d),LL(0xbea17435,0x11959ada),LL(0x6f44daf5,0x5ff2900d),L_(0xdea368bd), + LL(0x224521dd,0xfcb125d5),LL(0x097e443e,0x7d3c0cbb),LL(0x96ff5378,0x0cce254b),L_(0x562b2166), LL(0xc45e09f3,0x73e36236),LL(0x992060e2,0xf844b9b5),LL(0xa968d30e,0x139e42f9),L_(0xe5b89488), + LL(0xb57b80af,0x3e86ab5b),LL(0xb177e3f9,0x8e7a956e),LL(0x95050abc,0x580bb577),L_(0x75270515), LL(0xa96f2da7,0x0ce33d22),LL(0xcab8647e,0xf5e4958e),LL(0x139f525e,0x9b1f28f4),L_(0xa2e38250), + LL(0xf097a8be,0x193d7b50),LL(0xbe57f373,0x326744fe),LL(0x192cee98,0x66699aba),L_(0x69e0895a), LL(0x51e1d17f,0xe787c995),LL(0xb3f66818,0x7acab4f1),LL(0x5ee5c7cd,0xe1645254),L_(0xb7d10719), + LL(0x29d8986c,0x17022e01),LL(0x2f237075,0x0ccc4d78),LL(0x01453fbb,0xba3615f3),L_(0xa703f343), LL(0xf538646c,0xb5aab8cf),LL(0x30b0a7e8,0x4a42c722),LL(0x33588983,0x8a8547cc),L_(0x64a4028c), + LL(0x82ecbbdc,0xbbdec907),LL(0x6c0cb953,0x1807ae9c),LL(0xf8e40104,0xca5b89e3),L_(0x5e56c8f6), LL(0x41f32d88,0x040b1ce4),LL(0x76bd7772,0xbd9bda0d),LL(0x396f023e,0x6bb455f6),L_(0x4243e710), + LL(0x82b34b90,0xff00cfce),LL(0x7a3a34e7,0xfea1370a),LL(0x59745afe,0x13dec9bb),L_(0x00460ef4), LL(0xc0ccb5ce,0x664b5767),LL(0x467ad23b,0xe91ea77c),LL(0xd6ac872c,0xc30f32ed),L_(0x7527a687), + LL(0x4a73f787,0xf2877171),LL(0xa577b4e7,0x05b283db),LL(0x7ac6ab0b,0xbbb22aab),L_(0xce8c4374), LL(0x2cf4237f,0x5d2444bb),LL(0x1362bb86,0x354270cf),LL(0xa58498c9,0x03a3218e),L_(0x4585f77c), + LL(0x17d3d4da,0xe1c0eb99),LL(0xf69271e6,0xde536a3e),LL(0x239476a2,0x3701952a),L_(0xb94d2063), LL(0x25bb5fc2,0x39ed615a),LL(0x44f390c3,0x6a9dd585),LL(0xa4418ea6,0x1ce9df6c),L_(0x76cd5c55), + LL(0xa10e49d6,0xf5dcc900),LL(0x62fd7874,0x2e74ef98),LL(0x74f61b6c,0x9d3a5873),L_(0x10ca6b61), LL(0x470595b7,0x848244dc),LL(0x81922f08,0xf7db6c87),LL(0xbc236621,0xb2a50ed6),L_(0x0cbc779a), + LL(0x274cea83,0x4914c419),LL(0xb8a19540,0x1bc1a1ba),LL(0x957adbf1,0xd2aac8dc),L_(0x64d6ca82), LL(0x96ac9d7f,0xdb015eca),LL(0x42372196,0x03b15d50),LL(0x05451b09,0xe16c7207),L_(0x463bc66d), + LL(0x01c4dfe9,0xfc7e965f),LL(0xb8358066,0x8fc594e9),LL(0xa1915c8c,0x8d26603b),L_(0xfdddd6dc), LL(0xc4b1e185,0x2166a1d2),LL(0x79912871,0xad0b86ad),LL(0xe96aa265,0x98a560dc),L_(0x43b8858b), + LL(0xa1e7a822,0x2d3f3785),LL(0x95813382,0xcc85095a),LL(0x89e2322f,0x3568d961),L_(0xfbe11c03), LL(0xe15474b7,0xb0011b61),LL(0xb6d17af8,0x94e2b66a),LL(0xfa35ee62,0x88f30207),L_(0x496e0cfb), + LL(0x00a8605a,0x233a4ea2),LL(0xed225296,0xfb49bd9b),LL(0x18a0b19f,0x49f70f9b),L_(0xfd4a3974), LL(0x3d19e5f7,0x6935d1e0),LL(0x4ca49b02,0x167ee2db),LL(0x465d1799,0x83dab70c),L_(0x3925587b), + LL(0x06b4ef1a,0xadc74707),LL(0x97b00e28,0x7b776a0d),LL(0x4ea78215,0x29de362e),L_(0xe0075db8), LL(0xd1a8437d,0xcd9ea162),LL(0x4071fbdd,0xd6f65966),LL(0x5861958d,0xb0f23643),L_(0xfb6d160c), + LL(0xe1dbc405,0x1cf01490),LL(0xfd9abd17,0x781604fe),LL(0xfdabdb45,0xfe106ce3),L_(0x28aec19b), LL(0x0765d40f,0x5dea7b0e),LL(0x9dd7eace,0x05e88870),LL(0x7aa326d2,0x58144fba),L_(0x0c0b55eb), + LL(0x4b6bbeb3,0xf492b1fe),LL(0x80211303,0x00d1a0a3),LL(0xa0a42f81,0x812c4f34),L_(0x0513dab5), LL(0x701129ed,0x2b196b3d),LL(0x8292825d,0x14497eea),LL(0xfccdef2f,0x8309d41f),L_(0xa6c098eb), + LL(0x4e01759a,0xe5e506e5),LL(0x34984e59,0x5bdb0568),LL(0xc78ed701,0x023cf8a4),L_(0x8818f370), LL(0xadc05868,0xedb22c00),LL(0x61bbfcfe,0x1eb0f72a),LL(0x4b1c28bf,0x87de5c20),L_(0x13f66db8), + LL(0x2c5c67ae,0x311b814c),LL(0x18478ee8,0x98f391ee),LL(0x5fc08d55,0x3d6c85b2),L_(0x2a4234ef), LL(0xc63b3540,0xef0ad114),LL(0xfa0e9b48,0x19926812),LL(0xded54ff1,0x8d2d8068),L_(0xe6033e94), + LL(0xfcdb3c46,0x567ac24a),LL(0x31e079f2,0x5c7d3b6c),LL(0x876a06e1,0xd77d6297),L_(0xabca81b2), LL(0xcd9c326f,0x27382ebd),LL(0xbd7f7ff0,0x8c9f6089),LL(0xb11d9de0,0x31e36d28),L_(0xba48fe41), + LL(0x8c0ffdf0,0x845700c1),LL(0x659750c3,0x9a4535d8),LL(0xbfa2263b,0x46779254),L_(0x426c9332), LL(0xea64e4f2,0xc0627926),LL(0x919159e1,0xd72486ed),LL(0xb8633c7d,0x62049111),L_(0x57a02e38), + LL(0x6d5a56c1,0xc0ef9c32),LL(0x87339367,0x1398d5b9),LL(0xd690f5fe,0x4cb8372b),L_(0x74004a4c), LL(0xa8b7608c,0x62fc7f7e),LL(0xc75eca95,0x7fcc6560),LL(0x87991514,0x1a3939cc),L_(0x9eeab34e), + LL(0xee335372,0x6dda426f),LL(0xe95ee7c3,0x7a84b92e),LL(0x5637d166,0x0cc0434e),L_(0x108326a5), LL(0x4c69a1c3,0x66908f8e),LL(0x768a4dc5,0x93e7c968),LL(0x24086621,0x0390f0a6),L_(0x34cd95fd), + LL(0xffd9518c,0xa579c74a),LL(0xf4d1cd8b,0x245e5d80),LL(0xa682fc6c,0xcf5b3a95),L_(0x13389ce6), LL(0x8944bc8c,0xc24a47b4),LL(0xf37dbb35,0x67296189),LL(0x9d47aaf7,0x196773ed),L_(0xab42affb), + LL(0x6c1fae2e,0x78457340),LL(0x0583dc84,0xea2de616),LL(0x6a0c10e4,0xbf46a7bb),L_(0xe6adebac), LL(0xb7cad754,0x3e924b67),LL(0xbf5e7329,0x93303eef),LL(0x9cb33af1,0x5460942b),L_(0x1005e77d), + LL(0x5dd3bfdc,0xa399de31),LL(0x867305ce,0xbc0f8f54),LL(0x2200477c,0xd31a5a81),L_(0x9ac2ed5d), LL(0x59ceee51,0xa5a011eb),LL(0x9cb94041,0x53fce407),LL(0xf7a7e8fe,0x26131e4c),L_(0xbcae3bd4), +}, +/* digit=11 base_pwr=2^77 */ +{ + LL(0xe3b818f5,0xe00bddec),LL(0x44e43c61,0x4681ea2b),LL(0xc584d310,0xb6fe7f05),L_(0x951b39e7), LL(0x81eb4c72,0x1eae5fc5),LL(0x518f5441,0xdae90140),LL(0xc505aeda,0x216fb5f2),L_(0xbb781e43), + LL(0x3cf8ec7d,0xf9a62c2a),LL(0xe0d93869,0x23fabd24),LL(0x6d3f0de8,0xb3106bbb),L_(0xb0f77641), LL(0x6c7c7f7d,0x9b298ebb),LL(0x184aed09,0x9f30709a),LL(0x334394d4,0x79c1d22f),L_(0xd95473d2), + LL(0xae76cd6a,0xcb7cb589),LL(0xf3fc070e,0x3ecf8591),LL(0x60dba7d6,0xe19d60f2),L_(0xe420c869), LL(0x59b7cb97,0x097e4daa),LL(0x707e030c,0x7f52c8de),LL(0x0dcda4fd,0x9803c9fe),L_(0x2bbc44ce), + LL(0x2ff400c0,0xfabcb249),LL(0x10355326,0xacc122ab),LL(0x91ed19cf,0x4f316ca1),L_(0xd20efc4e), LL(0x940a18e1,0x1a2e490c),LL(0x2b83ac01,0x029cb6e5),LL(0x0fd81ad0,0x8da694f8),L_(0xfcad677f), + LL(0xb1b32829,0x248ec9b3),LL(0x11ef88d2,0x35de7b93),LL(0xda678713,0x370ca0ea),L_(0x7a293625), LL(0x1a056e86,0xddfa0a4d),LL(0x1f856294,0xfe05d52e),LL(0x6bd2e637,0xf728ccb4),L_(0x91baf444), + LL(0x74014196,0x9e4adc25),LL(0x8981411a,0xf964b6c4),LL(0x7eb4dd2d,0x58e82e86),L_(0x97c312ce), LL(0x153d2149,0xd7b84e08),LL(0xc95c8ff2,0x4e547787),LL(0xd7ac3655,0x7546fc40),L_(0x504a9f59), + LL(0x3f1e5f11,0x9edb0425),LL(0x476b8958,0x63c34818),LL(0xf14565b6,0x4bab1b96),L_(0x3d3ca262), LL(0x18ef180c,0xfd4e9a47),LL(0x0043c8ff,0xa1174dbb),LL(0xafaf8911,0x0b1e0a8d),L_(0xcbeb2d8e), + LL(0x486cbfa7,0xebbefd50),LL(0x44fc634e,0xe20aab71),LL(0x9ddeace8,0x08a9107e),L_(0x909eff4c), LL(0x746a522f,0xf816fa9e),LL(0xefd70514,0x864324da),LL(0x598db9df,0x0094b64c),L_(0xc6634c12), + LL(0xe65d8204,0xd6fb5d4b),LL(0xadb1a9c2,0xec38f10c),LL(0xc8ec0f39,0x1908657d),L_(0xa25710b3), LL(0x87e1d90e,0x311947c3),LL(0xe187cb1c,0x04d9654b),LL(0x1bae3f87,0xafb6e7b5),L_(0x44ea2977), + LL(0xe4a3b821,0xee18a382),LL(0x60b120f0,0x4002bc41),LL(0x91636563,0x29fd66f4),L_(0x6538f012), LL(0x300af347,0xda52b57a),LL(0x9a0bd35b,0xa08ae1b7),LL(0xcee45c95,0xafb1fcae),L_(0x042232d0), + LL(0xe06efe03,0x54397157),LL(0xd06ed8f6,0xf4ce3dfb),LL(0x67644c3e,0xaa8e6af8),L_(0xa26425e0), LL(0xbbd40e3b,0x6fb8009d),LL(0xdfa5a71f,0xbf5753ee),LL(0xc4fb8d84,0x413c2883),L_(0xa71e26d8), + LL(0xe358be61,0xae3de433),LL(0x45610301,0x9f32cd87),LL(0x4ec1365e,0xb95b637d),L_(0x41dbce62), LL(0x0840486b,0x9637a66e),LL(0xc6d80952,0x522810a8),LL(0x928915a0,0x761cc88a),L_(0x1da0d501), + LL(0x208620d1,0x37a59562),LL(0xb4ca54d1,0xc246b32e),LL(0x5128864c,0x8aad87e4),L_(0x559dacdc), LL(0x9d93608a,0x89718ac7),LL(0xea353321,0x48d40286),LL(0x2012406b,0xc599f213),L_(0x1eb2fe94), + LL(0x6807d450,0xba62fad2),LL(0xa7fededf,0x07ea62b0),LL(0xd58195f9,0xd3d6b5bf),L_(0x1ad1505f), LL(0x87583b1c,0x6f93c77a),LL(0xaf96dc4e,0xa959c022),LL(0x20624dad,0x4fa52512),L_(0x3481aabe), + LL(0x9310eef9,0xba1c1390),LL(0x9fb8e966,0xcce0400b),LL(0xb9c0dea0,0xd59d1993),L_(0xe8a99c53), LL(0x243bcc60,0xb44f7477),LL(0x97335f28,0x1bd266f4),LL(0x6f550c82,0x3749bb24),L_(0x67501a21), + LL(0x35f741c9,0x2ddbdad6),LL(0x5e95c8ee,0xbeac98ef),LL(0x74fa6bf8,0xf68aac5d),L_(0xe404df62), LL(0x13d824a6,0xf3252763),LL(0x934f4963,0x4c5b99db),LL(0x65ea023c,0x39f3ad81),L_(0xf2ab45c6), + LL(0x513ad1f3,0x6c9e60dd),LL(0xd82ebdb2,0xeb595e39),LL(0xf4278e99,0xf76b6d5d),L_(0x177bfa74), LL(0xda5b699a,0x0698c8f7),LL(0x8af11d92,0x022b9e4d),LL(0xdcfeb87d,0xdf966b87),L_(0x790b8b3b), + LL(0xe6576cdc,0x0d632c2d),LL(0x82b42706,0xe4079724),LL(0xeb7e23be,0x67d13334),L_(0x6bef8f5e), LL(0xab6f7a84,0x5b9d7907),LL(0xb943b3e3,0x3b2e4de9),LL(0xe1142403,0xe61e180e),L_(0x3186f5ab), + LL(0x54c38bc7,0xee73f3c8),LL(0x1c021526,0xcdd71fb7),LL(0xd5f0330f,0xbcd8ae19),L_(0x34f15f5c), LL(0x3f1e795b,0x0f2d33f8),LL(0xf2452d93,0xe4d47a55),LL(0x0c4b0f70,0x322c677d),L_(0x311431b5), + LL(0xe32f7152,0xd222f30a),LL(0x32c8e92e,0xd5265ce0),LL(0xf9051d2c,0x34079f7e),L_(0xca51b73e), LL(0x752d0df7,0xe4529fd5),LL(0x3ee05e30,0xd39fd02a),LL(0x762211ba,0x957b54a8),L_(0x7bd842d1), + LL(0xca5c5b9b,0x8578a05a),LL(0xf931c6ff,0x5854ceb6),LL(0x9c1a24ae,0xc7ad186b),L_(0x3aae7e80), LL(0x405ad033,0xcd94ffe8),LL(0x02d60546,0xc24532db),LL(0x6d8dfc51,0xf70532cd),L_(0xa7523214), + LL(0xf6e5bcb6,0x3898ac49),LL(0x7ef15aa2,0x0dc0b7cb),LL(0xc92d3e61,0x6f146470),L_(0x20a65e93), LL(0xa99d1e34,0x40c2ff2e),LL(0x5f5f4b1f,0x8bce3569),LL(0xef24d37f,0xf5eb8c60),L_(0xd0f3625a), + LL(0x770ff147,0x04af9657),LL(0x0ddb7f8a,0x5d6a9432),LL(0xf5679a0e,0xfa164f3a),L_(0x75f9e25f), LL(0xb341ef73,0xd2b96f53),LL(0xc75b8bfb,0x111da06d),LL(0x141dae1e,0xf86c989c),L_(0x1a015ae9), + LL(0xd89c49d6,0x7440165b),LL(0x252d3538,0xbc50c381),LL(0xc7935e6e,0xfc485299),L_(0xafc2b1d4), LL(0x7b5b7847,0x8b5606a8),LL(0x8714fa4e,0xc8ca9e3a),LL(0xd015855f,0x03679b60),L_(0x14d9de29), + LL(0x5d13fc8a,0x7fd6372a),LL(0x1fc76dfc,0xd3c20f3f),LL(0x835ac98b,0xec54c6b2),L_(0x98cbc171), LL(0xe5e2a3e4,0x7ab5c98a),LL(0x577a8e9f,0x6c990ebd),LL(0x84028fa5,0xed0d2362),L_(0xb28e8d67), + LL(0x277610eb,0xd8c85ac2),LL(0x8e20b175,0xc11f2394),LL(0xbc82df9f,0x763f7da0),L_(0xc32cc81d), LL(0x85f8381c,0xb02c89cd),LL(0xd305dbab,0x2a33f683),LL(0x7f0a99f0,0xd40823f0),L_(0xf958bb39), + LL(0x08d09d3c,0xee84ea33),LL(0xc5f043e5,0xe195e3e9),LL(0x13f7ae30,0x18438628),L_(0xb6ffaed5), LL(0x4012f22a,0x9cb2856d),LL(0x9a5c926d,0x6dd2b787),LL(0xad05632b,0x4d11a1b7),L_(0xf0f2c69d), + LL(0x8e9a6388,0x60b10c54),LL(0x79943f17,0x0474b959),LL(0x15056515,0x70dc2681),L_(0xc9a17b25), LL(0xb6a005e4,0x4d9c29fe),LL(0x5978aada,0x9f751987),LL(0x6e84fa9d,0xb01cfa96),L_(0xd9553cbf), + LL(0xe72b7959,0x14645ddf),LL(0x50569b84,0x6a35f872),LL(0x76814e1a,0x6931ce3c),L_(0xd1694dea), LL(0x9877446f,0x8fb4ec92),LL(0xcbd84ece,0xd0d64612),LL(0x70c2d8a8,0x6f1a63f5),L_(0x2ca687fd), + LL(0x73d59d85,0x66719258),LL(0x78b1b1f1,0x3528fe8e),LL(0x372aba7b,0xf72aecd5),L_(0x049424c7), LL(0x0a8225e9,0x1299651f),LL(0x7a3d9b21,0xcdfa1798),LL(0xeea3b43d,0x6296bed4),L_(0x965623a1), + LL(0xe79e4875,0x19faf24e),LL(0xee2a75e2,0xfce9de0f),LL(0x2608d8d7,0x5dbd9aa4),L_(0x8dd2d8bb), LL(0xa1d5ac1f,0x96024e09),LL(0x59608369,0x88c11a15),LL(0x3109b985,0x4c72f34b),L_(0x073affe7), + LL(0xa7d5999d,0x7163417c),LL(0xe75a8d8d,0x58690b9f),LL(0x34a71e84,0xf46ea0c1),L_(0xa472172f), LL(0xdb5e6f96,0x5941f31e),LL(0x45ef8849,0xff03761f),LL(0x813628f8,0xff6e6be2),L_(0x2f6a6923), + LL(0x37f746c4,0xf2dab7c0),LL(0xee4fac0c,0x94b2339d),LL(0x442b5427,0xd1572489),L_(0x1b63f7f9), LL(0x77b93d36,0x86beafa0),LL(0x931a009d,0x89006e01),LL(0xc54e5dcf,0xce454abb),L_(0xe3d31b67), + LL(0x5dbfaab4,0x2bfb9672),LL(0x00a46605,0x0f7940ce),LL(0xd0e900f4,0xac391030),L_(0x56b396f4), LL(0xd65db7d6,0x111e6518),LL(0x0e375257,0x574c6063),LL(0x0569eb0d,0x6386031f),L_(0xa43939dc), + LL(0xe79fa54d,0x790064ff),LL(0x19bae3a4,0x040699eb),LL(0x278b676c,0x2bfc1210),L_(0x5fd221ef), LL(0xc41696b3,0xaddaabbc),LL(0x3e58e744,0x4ef37496),LL(0x86211a5e,0x27a20439),L_(0x06b96609), + LL(0xa9a97859,0x31e7bef8),LL(0x6b521dbf,0x39d7de6d),LL(0xbb74a0f3,0x41f4bd94),L_(0x79699c57), LL(0xfd6b25ba,0x6af2b090),LL(0xb9a903de,0x17aa75d4),LL(0x250d78d4,0x565e3c29),L_(0x674edb33), + LL(0x580583bb,0xfa502a79),LL(0x4f9ab886,0x9fc3a870),LL(0xb5e6f604,0xcd18776f),L_(0xf25cc6e4), LL(0xea80a2a0,0x9822aa1a),LL(0x2c1f0788,0x3a8b80d3),LL(0xb4be8a38,0x671f0157),L_(0x5b11123b), + LL(0x9b6b4d48,0x54914216),LL(0x1256ef4e,0xb5f866f9),LL(0x075b53ab,0x5ecb1889),L_(0x56e20726), LL(0x69455333,0x09f26254),LL(0xd571b91b,0x2b2fad5a),LL(0x328d62f6,0xde6fb9c6),L_(0xe065c610), + LL(0xfd0dd09b,0x45144de7),LL(0xdc428059,0x74b10792),LL(0x9aff2cca,0x9af32379),L_(0x7429380e), LL(0x49635e31,0xe3565603),LL(0xdea72af4,0xe2386988),LL(0x2bf6a43f,0x5a2add5c),L_(0x6b6ae6f7), + LL(0x13448c75,0x9ab52f76),LL(0x061d7ef8,0x4392015e),LL(0x010840be,0xae0d756d),L_(0x97508e7b), LL(0xd15d5084,0xadc78971),LL(0x4d5b80a4,0x7c713bfc),LL(0xf9aaef5c,0x256809bb),L_(0xa1ec2e50), + LL(0xfbb42651,0x74a6dd49),LL(0x0393f719,0x977434ad),LL(0x4e57160b,0xac7e00ee),L_(0xe124fa0e), LL(0x7a6f9567,0x2389bd87),LL(0x80b4129f,0xfb1db8c0),LL(0x0e8aaba3,0x1051debe),L_(0x4a190f97), + LL(0x477f6b19,0x2156959b),LL(0x37e2ab37,0x910a6757),LL(0xfe9b7158,0x540652e0),L_(0xd3215a27), LL(0x7976f02e,0xc0c597ef),LL(0xceb6dd56,0xe44ded06),LL(0x09436cb3,0x07e11a08),L_(0xc752116d), + LL(0xf6b2fb7d,0xe154e3b5),LL(0x3dd689de,0xc3b95a13),LL(0xecec9673,0xf4ebc67c),L_(0xdf67ffb0), LL(0x01c1c880,0x33ce85c6),LL(0x58ffaf1b,0x033751df),LL(0x741f05bf,0x2535c38a),L_(0xffe3294f), + LL(0x308eb02c,0x4c921d98),LL(0x1c787299,0x5bd1a752),LL(0xbf10f0e6,0x4f5e9e39),L_(0xdd4daa07), LL(0x18aefaaa,0x92fcbe07),LL(0xf29c8618,0x200b4b85),LL(0x84305705,0x8d7c9a43),L_(0x19694aa8), + LL(0x3a51e7ce,0x680c4324),LL(0xb1ac0982,0x0b339790),LL(0xa4032aca,0xdf576261),L_(0x92007d10), LL(0x50fc383f,0x755cfb3b),LL(0xb9ea853a,0x702d89aa),LL(0x28725f39,0xa32de41e),L_(0x8310cc56), + LL(0xe3293ae8,0x4319f044),LL(0x6a31f14c,0xd8080331),LL(0xf0a68d54,0xa79121b3),L_(0xf8ad5c75), LL(0x3c85f6ea,0x1aca6f0d),LL(0xd728ef75,0xb8a8d44f),LL(0x66ed37bf,0x244f6df5),L_(0x5253f731), + LL(0x40e52539,0x7e5a8bd2),LL(0x9d03a5af,0x2a775548),LL(0xa4eb71ab,0xa305f15d),L_(0x1dc7fb76), LL(0x68a7c637,0x20487a25),LL(0x6deaadda,0x8c18ae20),LL(0xe0f4999d,0x9bb84678),L_(0xc451bb12), + LL(0x27b6061c,0xc977cb30),LL(0xd39b851a,0x430b3684),LL(0xcd656ca9,0xa19898ab),L_(0xafd81332), LL(0xfa31c77d,0x2bb5e6b0),LL(0xc3157a16,0x60d12981),LL(0x8acd8d9d,0x69cbb158),L_(0x6d76f690), + LL(0xe9d8d3f2,0xc8ff4785),LL(0x2bca8c99,0x2e87c4ea),LL(0xa2caaf78,0xf6be10a7),L_(0x2100372c), LL(0x8cdcc69a,0x761e39c6),LL(0xdb53800d,0xd8745be4),LL(0xc599f6e5,0xc995d474),L_(0xcb2cc9b4), + LL(0x35b78d83,0x39687ef6),LL(0xe8d0ac03,0x91a4e746),LL(0x921b3cbc,0xc64c35ba),L_(0xa500e776), LL(0x4f3feb91,0xe79c45af),LL(0x60ad3863,0xdbd9485d),LL(0x0ce33aaf,0xaee36834),L_(0x4ce8962e), + LL(0x8023ad1d,0xb38c8506),LL(0xc359f6e1,0x0673f87d),LL(0x31837b1d,0x98af1b3a),L_(0xf716fe6e), LL(0x3024d432,0x3830cd5b),LL(0x52930fa5,0x60d8b1ad),LL(0x0ad62261,0x097dfa97),L_(0xebeb447d), + LL(0xf447ab0f,0xe409d4ec),LL(0xe80a1b86,0x58d6899f),LL(0x1aaed1d3,0x9eac7e33),L_(0x80bb831f), LL(0x2a9866ba,0x986f7e0b),LL(0x005a4dc6,0x43a73638),LL(0x52827ff0,0x293c91f5),L_(0xcdd9e93e), + LL(0x691e28ae,0x2c6558ef),LL(0xd0ac15f2,0xe56ad3e9),LL(0xa247b120,0x573e9688),L_(0xd0627f7e), LL(0x375dee4b,0x22887f9e),LL(0xd31e0ba7,0x7d20b431),LL(0x1eea7f55,0x4423561d),L_(0xf9581051), + LL(0xd4243ea6,0x42a54363),LL(0xeb2affe7,0x619c06c6),LL(0x972ce84c,0xaeca0047),L_(0x4d9efd23), LL(0x4e0c1d41,0x173fea08),LL(0x1d890ba5,0x4bd9d779),LL(0xfea0ad92,0x5f0b0f42),L_(0x5619484b), + LL(0xe4e12bd4,0x6cdbcee2),LL(0xc11ff4f3,0xfe8d06f2),LL(0xa260adc3,0x5bb4d1a2),L_(0x33e0dbb6), LL(0x27018d5f,0xcaa2ba14),LL(0x415b8922,0x74b9b719),LL(0xb1fbde1d,0xe7f63f33),L_(0xb014bfff), + LL(0xeb046732,0xab510c97),LL(0xee7b323c,0x9bf44d3f),LL(0x37854732,0x23d6cc1a),L_(0xdbbcc348), LL(0xf773172b,0x64d5f135),LL(0x6fb100cc,0xb0c07c01),LL(0xb27f28f5,0x980b1419),L_(0xca8834c2), + LL(0x01f6b795,0x1b1c75ca),LL(0x8c28e4a6,0x6f2aae0d),LL(0x2cbdb244,0x1341e16e),L_(0x5a726ab8), LL(0xd482dc14,0x32264865),LL(0x4f4a819e,0x1e1e75b0),LL(0xba655f22,0x37367c7d),L_(0xd157593e), + LL(0xaa3ab9fd,0x46d94f54),LL(0xc9397bab,0x3628a867),LL(0x65e56a09,0xf946f4e0),L_(0xa259e975), LL(0x372139d2,0xb5060783),LL(0xccc37d6a,0xeef39a01),LL(0xf709343a,0xfb056c2e),L_(0x89705d36), + LL(0xb9d0b061,0xeb841e0e),LL(0x7663ad0e,0x0dc12b25),LL(0xb1420c31,0x5792fb1a),L_(0xaebf5ced), LL(0xfb7eb601,0xeaecfdd5),LL(0xd5142858,0xc9d7159e),LL(0xe56ab53a,0xdbaff47d),L_(0xb56ba899), + LL(0x64ac917b,0xd69321cf),LL(0xa06234ff,0xe8fd532c),LL(0x98b8cc13,0x4be3eee6),L_(0xadbfb76c), LL(0xb07602f3,0x57f0cdf3),LL(0x01e45447,0xa4676560),LL(0xb307918b,0xa0a5d2a4),L_(0xf7e16814), + LL(0x87a7be06,0x6c92c96b),LL(0x865c8f6c,0x666baece),LL(0xf96358e6,0xc0b20165),L_(0x10dbd508), LL(0xc18e3e53,0x990a46d4),LL(0x1d1a7d70,0x0002a616),LL(0x6c2d572e,0xa87b8f93),L_(0x03a7ba98), + LL(0x8d933af2,0x6d9f3e8c),LL(0x2221d899,0x3a4a28c9),LL(0x7c844ad4,0x142035bd),L_(0x11c04771), LL(0x2de90904,0xf02e1ad1),LL(0x78ab7d85,0x9793442b),LL(0x301c5cee,0x1feac0e2),L_(0x95568955), + LL(0x48a5ccac,0xc5b0ee88),LL(0xf045ebf3,0x1ecaeea9),LL(0xc1ea77c4,0x4e10f859),L_(0xa44993af), LL(0xf6bfe532,0x38d373de),LL(0x5c460d85,0x9d4beaec),LL(0x2bdad16c,0x264105cb),L_(0xb8fc3b3e), + LL(0xd715e784,0x2edb771c),LL(0xd4ae16cd,0x5451781f),LL(0xc8055a0a,0xdee3f3e2),L_(0xc08d1ca2), LL(0x3a1c4bfb,0x4252a1b8),LL(0x6d687314,0xbca7011a),LL(0xba935b81,0x3b383652),L_(0x52c1b85d), +}, +/* digit=12 base_pwr=2^84 */ +{ + LL(0x793c7e62,0xb92b8aef),LL(0x6354d2c9,0xd358ac7c),LL(0x5a4d9e35,0x0381968a),L_(0x52d9f13a), LL(0x36ed6955,0xc63b9fe6),LL(0x3743142f,0x726db145),LL(0x6e186e53,0xaea91efc),L_(0x3de25aa0), + LL(0x4c1ff250,0xf8921757),LL(0xced4216d,0xb6db16c1),LL(0x28cf0cfe,0xd524c877),L_(0x03bdd0b5), LL(0xdfd0f98a,0xd91831dd),LL(0xd131c59b,0x980f4d7d),LL(0x47533185,0xf492c767),L_(0x63c30af1), + LL(0x0cc8e4dd,0x79a5ddcb),LL(0x495cdcc7,0x26e26606),LL(0x7f199f53,0x9d2ff41e),L_(0xbe613bf2), LL(0x36bd8348,0x967f0753),LL(0x76c36728,0xc4ce6462),LL(0x02af3c45,0xee5a166b),L_(0x0bda3025), + LL(0xff47da80,0x63718529),LL(0x473e976c,0xa699d496),LL(0x88aeb436,0x368ce839),L_(0x94aabe19), LL(0x0bf4b797,0xb19a3ec6),LL(0x7d50b7ff,0xcd07cc98),LL(0x81c2bf46,0x8c4eb78c),L_(0xb0a7cd1f), + LL(0x2ddf8350,0x56f0849c),LL(0x5739e59e,0x4be4bf01),LL(0x1fc6493a,0x8b91a3a3),L_(0xd401b24b), LL(0xe89ec9f3,0x9decd9c5),LL(0x17f178e9,0xe63f9369),LL(0xfa904473,0x7a09efc0),L_(0xca5c00a9), + LL(0xe3f640d4,0x6aca6f60),LL(0x4bda0113,0x574789e1),LL(0x12ccd894,0xb4db3fdf),L_(0xb39be04f), LL(0xf1e4603b,0xb4705565),LL(0xccbe5154,0xef713fb6),LL(0xd84fec44,0x11964906),L_(0x9ceede3f), + LL(0x0244c62d,0x13111bdb),LL(0x175d3f77,0x14dda4d9),LL(0xe0971342,0x21244b52),L_(0xd6fa5642), LL(0x2ee8560d,0x68da34f1),LL(0xb9933942,0x387164b3),LL(0xd7d7f791,0xee292b1d),L_(0x4382d48d), + LL(0x2a7dfaac,0xe877a208),LL(0xaf9b8432,0x77afbba8),LL(0x1257224a,0xbb09b923),L_(0x1501cefc), LL(0x38985dbe,0xe061421f),LL(0xaa863b6a,0x00e2d3d6),LL(0x2733782a,0x1a9bf0b7),L_(0x6912b5aa), + LL(0x70c5c0c6,0x38d01224),LL(0xa0259e70,0x84a934e4),LL(0x8e85d7ef,0xfd49df96),L_(0x6bb4a230), LL(0xa15b7d76,0x58b99e52),LL(0x3c2be4ba,0x2dc32c4c),LL(0xe49fcb40,0x4937a76d),L_(0xdc9b73dc), + LL(0x5ce8f858,0xa516c9ed),LL(0x41610138,0xd3f7221c),LL(0x71d5b83a,0x8795351f),L_(0x9a45e682), LL(0xef8c4cff,0x9edacc8d),LL(0x17bd9c0b,0x9166ced1),LL(0x871cc69c,0x57013f03),L_(0xb6b7b6e2), + LL(0xf3f01792,0x4855e4b1),LL(0x124c67e8,0x7556de49),LL(0xd4d7f50b,0x494ae118),L_(0xf16b9834), LL(0xab9ad587,0x3a6a8d30),LL(0x18d69af9,0xa950fac0),LL(0x7f8ed091,0x9daffa88),L_(0xba6e7c59), + LL(0x8f831a7c,0x011788f5),LL(0x9c64aa0c,0xf480aaea),LL(0xf896522c,0xcc8f1ea7),L_(0x772627b7), LL(0xe1227c86,0x72bb812a),LL(0x57f8a759,0x6e202e06),LL(0xc7e7a397,0x4c06faeb),L_(0xeea7a14b), + LL(0x46853977,0x0c456e84),LL(0xbacf3d29,0x94a82d15),LL(0x861ef909,0x17a88c53),L_(0x25d01a4d), LL(0xaa44d1ac,0x0b6e87fe),LL(0x066301cc,0xce900509),LL(0x51763eac,0xe4c44c3a),L_(0x243f5364), + LL(0xf02ccf3e,0x69fe2b3e),LL(0x623f7c06,0xa6634ac0),LL(0xa81b9914,0xba6dd8e5),L_(0xd33612e7), LL(0xcf35703c,0xc948497c),LL(0x7184b686,0x3725232b),LL(0xd5e74279,0xfa105e4b),L_(0x4bfe5bea), + LL(0xbbed4591,0x03d46274),LL(0xfcb464d3,0xc3c74b90),LL(0xdcb4ccb3,0xf6934477),L_(0xbdf563a1), LL(0xdae24867,0x7c07acc7),LL(0x4d4331eb,0x05fd6424),LL(0x768b2706,0x022d151f),L_(0xf65a4027), + LL(0xfff51bbb,0x5cbe2653),LL(0x32707706,0xbec1f2c5),LL(0x9739588e,0x1d1ff202),L_(0xe51c696a), LL(0xfa60c3f4,0xdd740417),LL(0x25fcc7e6,0x6a0e351e),LL(0xac2dfbc7,0x0d72b69e),L_(0x1ff6f6ad), + LL(0x3eaa7b81,0x3ade75e7),LL(0x3ac64888,0x4036d025),LL(0xd957b110,0x7be01ff5),L_(0x33f835d6), LL(0xc6af558a,0x45081b72),LL(0x0c08887d,0x137ffdce),LL(0x4fc01e35,0x84d416f7),L_(0x15716e5d), + LL(0xb47ca6c4,0xc4cafbc2),LL(0xcd118e18,0xac25eb7f),LL(0x78d7034b,0x4d198a7c),L_(0x9ba63f25), LL(0xdb8a8725,0x81c83f82),LL(0x9eb5e40b,0xdd6d729d),LL(0x3b1941e5,0x27b87b90),L_(0xb7229f73), + LL(0x492e405b,0x59afdea3),LL(0xf6e5451f,0x74cd3ea2),LL(0x3c7977fd,0x8262d80b),L_(0x0ff79532), LL(0xd5eea209,0x85d46815),LL(0x41a59faa,0xe5277e25),LL(0x815bfdff,0xf25c4d84),L_(0x26a648ca), + LL(0x1ce66149,0xc47be93e),LL(0x8807158f,0x150ece78),LL(0x71da23a8,0xf790aca9),L_(0x26957d5b), LL(0xeaf83d16,0x571af637),LL(0x3a3ff68a,0xbbf0d967),LL(0xb02eef0e,0x78555759),L_(0x1609b893), + LL(0x38ec85bb,0xa99f1706),LL(0x7a4aae59,0x12f3c66b),LL(0xc84493c2,0xf1b134ce),L_(0x8f2fb8ff), LL(0xbfc251dd,0x8f6f7a7f),LL(0x73cd2591,0x7b6bc242),LL(0xf68459a2,0xf4b9ddab),L_(0x1d8a7278), + LL(0x995f94c3,0xa1fd53d1),LL(0x3ad117de,0xae71c050),LL(0x75e31939,0x58a5dfbd),L_(0x3251c208), LL(0xda1a36d0,0x8436c37c),LL(0x65ab378a,0x80258188),LL(0x3a685733,0xe6172e78),L_(0xfa11b001), + LL(0x54abde7c,0x18e18996),LL(0x48c2dc2c,0x3b62d97b),LL(0x814d21da,0x198afe84),L_(0xf76ecf91), LL(0x0ca9c69a,0xb918572e),LL(0xf53020dd,0x249d565a),LL(0x365cb3e0,0xa6a9ebf4),L_(0xf8ad1ad6), + LL(0xb5e96d0f,0xf1859230),LL(0xcb1be872,0x64eca0e1),LL(0xfaa10d6a,0x11273c1d),L_(0x240336fa), LL(0xe56d43c3,0x6bfe9508),LL(0x88653660,0x12a7c212),LL(0x7b0d301c,0xd427be59),L_(0xbd85a9ef), + LL(0xbc70a5f7,0x72600cd7),LL(0xe9cae1c4,0xee97ffd5),LL(0x3d1457c8,0x96865fe9),L_(0x9a1bc1e7), LL(0x1518b86c,0x7727a4f5),LL(0x09a2a9db,0x1ed0a203),LL(0x028d0a99,0x9656e0c0),L_(0x7f3b01db), + LL(0xcb2d1081,0xb1f41608),LL(0x060c3752,0xf5804976),LL(0x6efb7250,0x0bd8bd31),L_(0x79016736), LL(0xc3ebc844,0x8739f62c),LL(0xf14247f9,0xb2896f39),LL(0x29b78fc9,0x5b2e893a),L_(0x5f2b1e7f), + LL(0x058470b5,0x380ddadd),LL(0x014c7c14,0xddf90df8),LL(0xc2d7837b,0x78897ca3),L_(0x5567dd34), LL(0xe3308b08,0x00642d55),LL(0xf735f752,0x9ca8b38a),LL(0x8afd8b87,0x6eb02b4e),L_(0x120f5319), + LL(0x2f0ecf3f,0x8fc31698),LL(0x41d511e3,0x8873639c),LL(0xbdc4fb65,0x9841bbd5),L_(0x207bfaea), LL(0x8e82da75,0x38fcb8d9),LL(0x6ba5dcee,0x05619b1f),LL(0x21f2d336,0xf78fd1c0),L_(0xc6f634fd), + LL(0x8258ddc6,0x09a676ca),LL(0x414f2daa,0x23041ee7),LL(0x4cbc9d7b,0x3b973302),L_(0xb409e95d), LL(0x7027e9ce,0xd16a5ca8),LL(0xf92a6554,0x473c41d1),LL(0x153e5025,0xa08470dd),L_(0xae4dfb2b), + LL(0xb57dcbad,0x5b3c44c3),LL(0x45031642,0x1130bf58),LL(0x335c400b,0xd4b606ca),L_(0x6b34a475), LL(0xbd2244f8,0xf3ab94fe),LL(0x746295e2,0x68723d0a),LL(0x4b9b612a,0x9d957566),L_(0x510e67f8), + LL(0x9a9a5ab2,0xdc56f264),LL(0x9f7dfe87,0x8565f7b7),LL(0xe3386448,0x104ea5b5),L_(0xac4c4feb), LL(0x5964e7d7,0xb2f8650c),LL(0x186e3514,0xf781aadb),LL(0x58c2701b,0x81927ca6),L_(0x81220e7e), + LL(0x6cffb688,0x727a95e9),LL(0xfb0e9702,0x83b28617),LL(0xcca5f38c,0xdb71dd75),L_(0xad31c5dd), LL(0xf33897ae,0x3ff02651),LL(0x683b0e57,0x380268df),LL(0xc6e32a5b,0x4ab25a51),L_(0x283f183b), + LL(0x48906979,0x08ea3767),LL(0xf7f76eae,0x744d1934),LL(0x222dd487,0x5b8927a0),L_(0xdc4a955f), LL(0xf36b1f09,0x605b6b77),LL(0xc80579f6,0xc4a4588d),LL(0x4cf36f45,0x94402fad),L_(0x0a226060), + LL(0xe0e79649,0x77db1b5d),LL(0x4fe36153,0xd0b5aff6),LL(0xb32ea8ef,0xa09373a7),L_(0xd4f68719), LL(0x116381ec,0xd8828433),LL(0x8c0026e9,0x7e2c0fab),LL(0x16af4c4a,0x8f7a154b),L_(0xd4672394), + LL(0x32df0ada,0xe432397e),LL(0xd0196172,0xd07b25cb),LL(0x114f01ee,0x12143827),L_(0x2f06e8aa), LL(0x9a3c110f,0x00bcfcbc),LL(0x76ee873b,0xb9f30c05),LL(0x8ff02da4,0x786da906),L_(0x7e7e6c65), + LL(0x0cb411eb,0xc8866c5b),LL(0x0d7b5118,0x5022b82e),LL(0xef5be83e,0xb37c41ce),L_(0x4b76c64d), LL(0x17ee0e9a,0x3d28da11),LL(0x8ef7cb6d,0xdd638761),LL(0xa3c8a2d5,0x4369465e),L_(0xc8c85ab8), + LL(0x5cda4d54,0x08818978),LL(0x17f1f556,0x62350317),LL(0x251cc26a,0x686c57b8),L_(0x865fb805), LL(0xe9b31ebe,0x19c7f60e),LL(0x23566eda,0x56fbedbe),LL(0x47f95f9f,0x867b619f),L_(0x1958dbaa), + LL(0x6427adad,0xfc7b0692),LL(0x44b01395,0x899725d1),LL(0x0d676d87,0x075607b2),L_(0xe2ae6225), LL(0xf9c3cc31,0x56d68f4a),LL(0x7e636075,0xb883986d),LL(0x1ffba2be,0x5c1ff02f),L_(0xc237448d), + LL(0x06c3092f,0xc3ea5575),LL(0x52c5f87e,0x2926437b),LL(0xf135c025,0x593535ee),L_(0xe0965b4b), LL(0x33672517,0x54fedc17),LL(0x28d4b11a,0x39103346),LL(0xe5297d9a,0xb0d741c2),L_(0x39caed90), + LL(0xf87698f2,0x340fdc0a),LL(0x1b8201fc,0x4ba2f34c),LL(0x248c333c,0x5f236490),L_(0x12ee4946), LL(0x52913c22,0xcbc6b04f),LL(0xee23385a,0xe9ac2163),LL(0x630f7175,0x0000016a),L_(0x3f6e71ce), + LL(0x953882bf,0xc6c3de30),LL(0xf99b211a,0x34fd7b9c),LL(0x549ffc42,0x5ffb8aa4),L_(0xbc4e1e52), LL(0x8cc9069f,0xe552f859),LL(0xf54af34b,0xe153c954),LL(0xd61618d2,0x5bb20166),L_(0x5776aea6), + LL(0x546f1f93,0x535ea11d),LL(0x565a5471,0x3aceac15),LL(0x4200ddef,0x8ee2aacd),L_(0x2493fe70), LL(0xd0228894,0x048f6036),LL(0xc2e41220,0x37388c77),LL(0x3193a2ea,0x3c56b2e4),L_(0xc4609ea4), + LL(0xcae3c391,0x4276f085),LL(0x57d5dc17,0x5fbdd403),LL(0xa8a6408a,0xd70d74f7),L_(0x98acac12), LL(0x75cbb8e7,0x93cd39a9),LL(0xb4c10685,0xe460014e),LL(0x56a7276e,0x2685e5f9),L_(0x3eeed659), + LL(0x4c4c8866,0x2d701e0d),LL(0x22e61da3,0x73a590ba),LL(0x45111480,0x403fd833),L_(0x6080d968), LL(0x41cddacd,0x2957083a),LL(0x38eb9ccb,0xed0801ce),LL(0x1be2ace4,0x726301f8),L_(0x002d8909), + LL(0xdf6a5e6d,0xd1f92359),LL(0xf591d929,0x221a78d5),LL(0xdc207a6c,0x5e691f61),L_(0x20b8f8e8), LL(0xa52ee137,0xaeb5ac09),LL(0x7eacabb9,0x95e85345),LL(0x0985df07,0x04b8e782),L_(0xf8047be0), + LL(0x2128e372,0x84928309),LL(0x4f347f1e,0x62f5aa58),LL(0x7d0fc140,0xf365c6c6),L_(0xa0e662a2), LL(0x7f46460f,0x8d246f44),LL(0x9dcc1860,0x05e6f03d),LL(0x5bfa3ba3,0xd9a27ded),L_(0xb281e327), + LL(0x5bf0784f,0x6bab642b),LL(0xbff128cd,0x0d3bef83),LL(0x268f3894,0xfc73c613),L_(0xcd24728c), LL(0xdefd474c,0xd40e3e59),LL(0xf065f5d7,0xb7f90c59),LL(0x15d0cf49,0x4ad712bb),L_(0x70e00818), + LL(0xd2fe399c,0xf1c993ca),LL(0xa2f0722e,0x4e4c53ef),LL(0xe7c142ac,0x8af34ce1),L_(0xce47aba3), LL(0x7f0fff87,0xb6c1f1fe),LL(0x49dac9d9,0x0f23c16d),LL(0x1baa4d4d,0xdbfb3b98),L_(0xd927e1a8), + LL(0xe7a09b61,0xde4413aa),LL(0xad27b0b5,0xbaf8e054),LL(0x0077242e,0x5d3ac419),L_(0xe50d3185), LL(0xb407f82a,0x6b5c4ee9),LL(0x4a8b1fad,0x6d04cfb4),LL(0x30ac4e43,0xe0253dce),L_(0xf07461c4), + LL(0x5a25f143,0x01947898),LL(0x818e99b8,0x35e2c880),LL(0x05ed8f7c,0x09f78f1a),L_(0x2fb78a6e), LL(0xc9d82b2c,0x4c2f0ccd),LL(0xfdd48d7b,0xaf9e328c),LL(0xe380dbfc,0x9600539c),L_(0xbb3a3bc6), + LL(0x54969bd7,0xea2bbe07),LL(0x394029b6,0x262c8bfa),LL(0xc8ab0425,0x90339a91),L_(0xda368bdd), LL(0xd540c3e3,0x0fe39b20),LL(0xc20f1366,0x5dbdfc74),LL(0x8075ba9a,0xdc668935),L_(0xa20bdd31), + LL(0x457e42b6,0x513bd423),LL(0x02a9ea32,0x37ec475b),LL(0xe477baa7,0x52b0bc16),L_(0x4583bc9a), LL(0xcce869a0,0x287b6484),LL(0xf11b84b0,0xe1aa5cec),LL(0x7925b118,0x4ab367b2),L_(0x8ff3e481), + LL(0xe318b3c1,0xb6f137ff),LL(0x0ffc4673,0x73596e44),LL(0xf9b0dfda,0x2bd4103b),L_(0x56acfc3b), LL(0xd8a47cb2,0xa87de433),LL(0x046c39cd,0x69413a97),LL(0xdebd1720,0x11fa933d),L_(0x3f6c6fec), + LL(0x47ed0eca,0xae4601fc),LL(0x06034734,0x110171a4),LL(0x104d85dd,0xca3c77a5),L_(0x8bca0d2e), LL(0xaee2efa8,0xc78c356e),LL(0x70ae3402,0xcedf0097),LL(0x322e72ad,0x07c1fe3f),L_(0xd0253c44), + LL(0x26e6bed6,0xc2f400a6),LL(0x2291a21d,0x7258c335),LL(0x287eac13,0x1680907d),L_(0x03a00f86), LL(0x4aa4df86,0xbadddbc2),LL(0xc5e15b28,0xc0fcaacd),LL(0xf30664e1,0xb1606671),L_(0xc87b6603), + LL(0x81f0973b,0x1873a8e4),LL(0x5f55c7e2,0xecb9e193),LL(0x33f083bf,0x95c9fed8),L_(0xe416fc1c), LL(0x13f90aa7,0x02778f81),LL(0x07eef5cc,0xc73195fa),LL(0xa94149e0,0xc8c44cfd),L_(0x2d270d3f), + LL(0x1a3813b8,0x7ca9f957),LL(0xdb514ec8,0xb674cd7d),LL(0x9718dd0a,0xe2bf5a99),L_(0x325fe3bd), LL(0x25692bfa,0x4f0b0620),LL(0x78990d74,0x5191688d),LL(0x5e70b57e,0xdfbda68c),L_(0x6e9d11e2), + LL(0x134142aa,0xd61361ba),LL(0xf97cf589,0xb62b767a),LL(0x7b21af77,0xf64ebc1a),L_(0x03a72d66), LL(0x6883434c,0x4b021c90),LL(0x39df1cca,0x2fe04352),LL(0xb84c6c06,0x9b6a3082),L_(0x62692bf5), + LL(0x33f0c495,0x94bf9bf4),LL(0x79c2f57b,0x85cdb0a8),LL(0xe0d00e0a,0x49f82bc9),L_(0xb9c9a088), LL(0xce773e24,0x1f589bd0),LL(0x11cd1677,0x1892643b),LL(0x8f952d00,0xb5eec978),L_(0x016b826e), + LL(0x87c07fe6,0x8cd03f0a),LL(0xf4d9e042,0xa3443289),LL(0xb07e4630,0x361c9252),L_(0x5bbca5ce), LL(0xb600853c,0xe687c31f),LL(0x7bd9a485,0x90550b79),LL(0xe200e18a,0x0e254cdc),L_(0x50dce2e6), + LL(0x3c92fc46,0x4b5e8398),LL(0x284e641b,0xf7347214),LL(0x0556fa64,0xa75c4fae),L_(0x4cc4b972), LL(0xaebb3e9c,0x90fa7977),LL(0x6a40b04c,0xa133ea2d),LL(0x97401c28,0x613bfe61),L_(0x443845a0), + LL(0xe2f9a715,0x532b2d67),LL(0x482b7779,0x065c4d2c),LL(0x123aa16e,0x6886e7e9),L_(0x9147c317), LL(0x40c6dfd4,0x1530f2ae),LL(0xaed04ac0,0xd86577c2),LL(0xa4111d16,0xd86157ff),L_(0x7406594c), + LL(0x23598a12,0xafae6c6e),LL(0xed33d4b3,0xa2858c95),LL(0x008ec0c9,0xfe186e4e),L_(0x7e4ed374), LL(0x9cb08278,0x2534f6e7),LL(0x798a9b30,0xe5f0b67d),LL(0xfcf997cc,0xb58b2b67),L_(0x2f620d55), + LL(0x3d465f68,0xe8013df7),LL(0x5dcfcfb0,0x3e4bfa75),LL(0x7a765b73,0xe0fbd7bb),L_(0x4e7374be), LL(0x186b6aed,0xfe9b1e77),LL(0x375f54f1,0xf7011562),LL(0x55dc463e,0x202fbb6d),L_(0x8d697af5), +}, +/* digit=13 base_pwr=2^91 */ +{ + LL(0xe165ca1e,0xbcdbe444),LL(0xcb4a833d,0x76643977),LL(0xb07c1b51,0xef7d725e),L_(0xdc3b82a8), LL(0x21f29146,0xaa5a7ac8),LL(0x01e0c54e,0xa51481d9),LL(0x2b2d5197,0xd220aca6),L_(0x736d91c9), + LL(0x87d54b6b,0x74d6d0ba),LL(0x9af89e67,0x723937b3),LL(0xada42e0e,0xda49ba83),L_(0x83b9c4ec), LL(0xa3055000,0x12dfdcad),LL(0x7e0a2cb4,0xa98d5243),LL(0xf7e3a9a3,0x6ed0d332),L_(0x1f8c692d), + LL(0x6e661a1d,0x634cef8a),LL(0xff5ab01d,0x35d65531),LL(0x6fe3ecd9,0xc1015db1),L_(0xfcc7ca4c), LL(0x769b7e20,0x795d4926),LL(0xed944d52,0x6db9a053),LL(0xf5f4129a,0x8f02bb95),L_(0x4007343b), + LL(0x75cd1b48,0xab70364f),LL(0x6b243c97,0xf0408ddf),LL(0x8b9a0873,0x0ef0ffd5),L_(0xb6e8c899), LL(0xbe3a87dc,0x2e1c11d8),LL(0x154379bf,0x6ed01611),LL(0x4382cb75,0xc876e0d3),L_(0xc42ec7d1), + LL(0x0e4e37cf,0x1ce64f93),LL(0xa2eb2c00,0x1061f84c),LL(0xe1a22446,0x450ed02e),L_(0x4205e69b), LL(0x644aa51b,0xc76dda32),LL(0x62db01d8,0xb244a09f),LL(0x633bdf3e,0x95c86470),L_(0xf9a6b309), + LL(0xab41ec83,0x71aba88e),LL(0x590711c2,0x3366c35b),LL(0x0b6ab428,0x87bfe939),L_(0x1d7e1090), LL(0x1d44d3e7,0x7ebcdd74),LL(0x2a937fd4,0x42a83b75),LL(0x3da3197e,0xc4155a57),L_(0xf1cea938), + LL(0xb74ca945,0x6a4807e3),LL(0xc0c52eb7,0x474fa11d),LL(0x12ba26fc,0xda7a7914),L_(0x001d4756), LL(0x34ddd360,0xce833467),LL(0x3290dbb2,0x0e517e33),LL(0x2b0a342a,0x579c91eb),L_(0xc27c2657), + LL(0xb129c61a,0x6983b44b),LL(0xf27d3e69,0x463c956f),LL(0xe4a043b6,0x5a97c010),L_(0xc8f8a3c7), LL(0x6cfa78d3,0xb9a3137c),LL(0x5655ed33,0xfc8d858e),LL(0x0b6dca4a,0xc1a3c9bb),L_(0x630b3026), + LL(0xe0a6194c,0x082a09e7),LL(0xffe89fc6,0x8699cb3c),LL(0x9f4f85f6,0x0b13732a),L_(0xba6e1981), LL(0xa2917bd0,0x26eb2b17),LL(0xa4afe844,0x0b4bc106),LL(0x91a5d7b8,0xeeac1c21),L_(0xe71f5fe0), + LL(0x2f9e0c0c,0x3f0bf1e3),LL(0x031e908e,0xbd33fa00),LL(0xbc16afc6,0x6e2d4301),L_(0x90a23e58), LL(0x99df250f,0x2549fd20),LL(0x52f4ef15,0xa724a018),LL(0x5b4c8dd8,0x1a5fbbc3),L_(0x7457c84e), + LL(0xbdbe5cc7,0xa3742f59),LL(0xe0a87786,0x6287ad4f),LL(0xe7aa9e66,0xba62daa3),L_(0x65327959), LL(0xa06c023b,0x7da31b20),LL(0x7fbf3e8d,0x94bea960),LL(0xe1a7865a,0x877c379e),L_(0xea576b89), + LL(0xca000d60,0xaa616a39),LL(0x662a3f35,0xcacdc37a),LL(0xdd7d18e3,0xee30f511),L_(0xf25f9c46), LL(0x7bee7ee6,0x3e51e652),LL(0x81e804d2,0xdd692c2b),LL(0xb0aaaab1,0xa52da544),L_(0x89ee1376), + LL(0x3e7d3b9f,0x97063082),LL(0xf2d42cdd,0x846e4346),LL(0x9cb9423c,0x6ed009de),L_(0x746461d4), LL(0xd30da2a3,0x6b0d52f7),LL(0xe78fe609,0x0b06f17a),LL(0x6887a9cd,0x8730c3cd),L_(0x0f586a94), + LL(0x91370dc2,0xf21a3a39),LL(0x38aa8cf8,0x4835ded5),LL(0x3dd4e3e5,0xf1f81f18),L_(0xee849585), LL(0x8aa2dfcc,0xb30df028),LL(0x1e4514ba,0x24f52ca4),LL(0x757e6772,0x3b2305c3),L_(0xa3525eaa), + LL(0x0e45f1c6,0xb94b1aa1),LL(0xebe6c1cc,0xa3e2b74f),LL(0x1c4d6e37,0xfa33270b),L_(0x5d3856a1), LL(0x62ec6306,0x77b4e047),LL(0x63f53943,0x36b59c35),LL(0x7466b59e,0xaea29806),L_(0xb1050d57), + LL(0x4fc503ac,0x0fd330ac),LL(0x0f394d0b,0xd80c9e62),LL(0xe4d013eb,0x99b62540),L_(0xaa1c17a9), LL(0x0a2e0bc8,0x8f6f2742),LL(0x7366a618,0x3a715ba2),LL(0x88e9ae3e,0x8818aa14),L_(0xd2fe924a), + LL(0x1cf5fda8,0xfd68c56e),LL(0xd02cd00e,0x77ce9ac0),LL(0x5f260a21,0x9c693311),L_(0x7c1f3266), LL(0x878fca42,0x5b2551ab),LL(0x9f545dde,0x365af76c),LL(0x19f87afe,0x019bf350),L_(0x58397798), + LL(0x2ced9c6c,0x46ea826a),LL(0xc4da4263,0xe4112274),LL(0x43744264,0xbfc3581d),L_(0xcc933457), LL(0xb80bff4c,0x9cbecb36),LL(0xe0071ca1,0xb9509e61),LL(0xcf0cfc02,0x67a2c9e1),L_(0x2f9bd24a), + LL(0x48a08314,0xa57e540e),LL(0xd472cc15,0xd2110f43),LL(0x0b60e719,0xcd92d76f),L_(0xca1c9c30), LL(0x44377160,0x8103a772),LL(0xa305744b,0xf08411da),LL(0x54b38b68,0xd6e1cdb8),L_(0xb252c82f), + LL(0xf1e98090,0x935833d6),LL(0xd0e4995f,0x530418e5),LL(0x87f60eef,0x933733ca),L_(0x379092ba), LL(0x423ea862,0xd4945af5),LL(0x60eeff1a,0x165baec1),LL(0x1d6d1df0,0x4bee290d),L_(0xe87f42f5), + LL(0xcf66861f,0xb222f293),LL(0x080ba4e8,0xb45f15c2),LL(0x8ed3f3c1,0xfdee70ba),L_(0x58ce1c82), LL(0x46cc54a7,0x8490a252),LL(0x6ed1e744,0x7d319886),LL(0x0602a509,0x585e149e),L_(0x7fa41773), + LL(0xcd741439,0xf0a3e291),LL(0x74dc9c31,0x41b8528c),LL(0xc78baacd,0x01ba1bb0),L_(0xe5b73558), LL(0x1ce4898f,0x9cf50575),LL(0x5421bd61,0x5a0b632c),LL(0x241cb4c7,0xc421cfb2),L_(0x9ba297a8), + LL(0x9bac4e41,0xf0b66ab7),LL(0xd87b31c9,0x9f0067bf),LL(0xcf835fb0,0x2f9c67c3),L_(0xaee5e6cf), LL(0x228157ee,0xd04298dd),LL(0x0411e445,0xeac052a3),LL(0xbec90b82,0xe6adb2bb),L_(0xb30b9c0e), + LL(0xdcd6bf3b,0xda605905),LL(0x5f01a30b,0x0b1bb0c1),LL(0x7c053c41,0x40f7d79d),L_(0xc39feb03), LL(0x98a4669a,0x3d73c359),LL(0xe472e81d,0x4a94f93e),LL(0xdea2bf34,0xed66fd6f),L_(0xddc57518), + LL(0x904c89ad,0x7095dc91),LL(0x07f66d27,0x2423fe30),LL(0x9c4ec652,0xfd209ae0),L_(0x35803afd), LL(0x94522cf2,0x51ed5eae),LL(0xc9356091,0xb3740f2a),LL(0x19e52bee,0x0676dac6),L_(0xd87e6c27), + LL(0x4ef0a025,0x83877c70),LL(0x39e61abc,0x09e709b4),LL(0xa88e05f1,0x7885ad28),L_(0x53bfba53), LL(0x9b73b3c4,0x8e433b9e),LL(0xd6a78477,0x7394d932),LL(0xcefdc6a1,0x3ce9d748),L_(0x27d9ed71), + LL(0xda4320d3,0xe57aeaa8),LL(0x7dbbbc39,0x06fa3110),LL(0x5c942e4e,0x7d7aed19),L_(0xe660d0ba), LL(0xadbc0281,0xff40dd89),LL(0xcdf314b5,0xb1ee8372),LL(0xa625d183,0x9d4344c2),L_(0x54f2035c), + LL(0x73c8d3ee,0xd120f88d),LL(0xe3275570,0x060ff4c7),LL(0xe344b66d,0x8d5e8c7f),L_(0x1cdb23ae), LL(0x23a7070c,0xce526de2),LL(0xe64e6355,0x4b694305),LL(0x5edf30dc,0x7e00559a),L_(0x3501ee2b), + LL(0x93c5d80a,0xa6698b0c),LL(0x91c3e912,0xd21b90b5),LL(0xbb24391d,0xe1e797f6),L_(0x0526a13b), LL(0xe2efd168,0x41e4a8d3),LL(0x63a82271,0x92a0c47e),LL(0xf6fd3e09,0xd1ade148),L_(0x85041faa), + LL(0xd58b2165,0x7675921a),LL(0xb30c5e67,0xa292beda),LL(0x9a004497,0xb5aac131),L_(0xcaf13420), LL(0xa8c50521,0xced86c69),LL(0xc60fb50a,0x9774900b),LL(0x8cd4dd3d,0xdec98657),L_(0x5092d4ea), + LL(0x829ecf62,0x9fb10f97),LL(0x67b904af,0xef94ed3f),LL(0xeebc687c,0xdae52182),L_(0x13aadd13), LL(0x964738db,0x59a01f8a),LL(0xc7db8080,0x608e9fae),LL(0x5433ce08,0x8b26a71a),L_(0x0c3a71bb), + LL(0x09326b40,0xd29e534e),LL(0x215aa2f4,0x727f40f5),LL(0x5f00b26c,0x3c54a3cb),L_(0x71ec2585), LL(0x14b424a2,0x4c553b92),LL(0xf86c23e2,0x06c97184),LL(0xdd6cfc3e,0x0fb40ab0),L_(0x4647a750), + LL(0xb818ca3b,0xa51a2b16),LL(0x1bbce0ea,0xb716ceb6),LL(0x7e78ccf9,0xc6736591),L_(0xbaa1d2e3), LL(0xe68eaa6c,0x6b8866a9),LL(0xc5b9e6fb,0xa4607970),LL(0xc39a4975,0x712336e6),L_(0x86d2dbfa), + LL(0x37f2fc9e,0x106db861),LL(0xc495534c,0x4b840f41),LL(0x75c25359,0x05a076ec),L_(0xf2a1fa9b), LL(0x22526757,0xbab703f5),LL(0x2b054aeb,0x8e748f87),LL(0x9e9ed0df,0x42646b39),L_(0xd95a6334), + LL(0x22dfe0f7,0xbcf088fd),LL(0x373df018,0x58f99bf3),LL(0x2646d8ce,0xa20f1b7c),L_(0x3bc4db1d), LL(0xc7206a4f,0xf3f061d0),LL(0x7fc330d4,0x97fe5b1c),LL(0xd64fa0dc,0x93be4afe),L_(0x239a905a), + LL(0x465eb830,0x9491ca54),LL(0x3a2368e4,0x096991e5),LL(0x840339bc,0x60229ac3),L_(0x0f74bf45), LL(0x167045a8,0x6bb23f63),LL(0x6df7548f,0x7c1e871a),LL(0xbd4ae1af,0xa5c7651d),L_(0x85fa24af), + LL(0xc10316ff,0xd9ea606e),LL(0x72e722f7,0x1d7722d9),LL(0x02dae11f,0x6f289df9),L_(0x4f148db1), LL(0xb66ca6f2,0xe8df6026),LL(0x0dc6bfc0,0x6f25ab93),LL(0xc2c848fa,0x726e5bf2),L_(0x0bc8372a), + LL(0x29431ba8,0xe513cc60),LL(0xb368f5d3,0xf213ba74),LL(0x2acdbaae,0x077919ee),L_(0x69129848), LL(0x3dbdea30,0x5c03af05),LL(0x6892cac4,0x81b53f34),LL(0x13156876,0x86df2c46),L_(0x15d63bed), + LL(0x20319c6f,0x85ef7365),LL(0x7ea45182,0x2f38b49b),LL(0x7d4f7ca6,0x2e79b2d0),L_(0x5befddd6), LL(0xcfcb5a29,0xeb6e8177),LL(0xd7c05293,0xeb5b17b7),LL(0xfebc1ad3,0xc2ef9919),L_(0x5ef848b7), + LL(0x628b133f,0xec0fd6a2),LL(0x4834ba2e,0x71d618c4),LL(0x70062560,0xee7cbb5c),L_(0xa240c28a), LL(0x0c5f4e11,0xe8bfcc1d),LL(0x36f2363a,0xdaf65ead),LL(0x2c7fdead,0xee2e792a),L_(0xfe7f2c9f), + LL(0xb9045bc3,0x21f1b865),LL(0x7a207076,0xf7c65eaf),LL(0xa289580c,0x26c6a4fb),L_(0xac8c38be), LL(0x2c1dd729,0x603a204c),LL(0xc96f5b0f,0x7ec2e50b),LL(0x07974ac0,0xdd93d467),L_(0xd384c831), + LL(0x27da0d82,0x130cf277),LL(0xb2d57bad,0x7cd69a13),LL(0x2e92cb98,0x0b8251c6),L_(0x04325b28), LL(0x35f746a8,0x630e8e9d),LL(0xcda5985f,0xe5c307ba),LL(0xf6775b8c,0x9cc53c03),L_(0x466530c7), + LL(0x660bcc85,0x9b3d46a0),LL(0x6911dd6e,0xfec92d25),LL(0xf5c72cad,0xaf7d9d93),L_(0x53a3ea3c), LL(0x244c7ae6,0xd879f3e1),LL(0xeaba3d43,0x57858904),LL(0x4c921338,0x3b59edc0),L_(0x7ee8ea79), + LL(0x0d019290,0x64c557a0),LL(0x70b7979e,0xa66689a7),LL(0x482d3b9a,0x08f6017c),L_(0xecf693f0), LL(0x90c3c46a,0xe8816977),LL(0x7c8670c4,0xf94ce04b),LL(0x05b8eed1,0xa8713371),L_(0x0ebddf9f), + LL(0xe8f0dfc1,0x50dc1442),LL(0x884f22ec,0x104f20a7),LL(0x5f885c0b,0x4da67f62),L_(0x6b4ecc34), LL(0x8460d391,0x0181b70c),LL(0x3f227a67,0xffedd7e8),LL(0xafb114cc,0x5b40835b),L_(0x2f5bb436), + LL(0x2da90ee3,0xdaec76bb),LL(0x6deef6a5,0x05e4b337),LL(0xe70560f3,0x8e70fab8),L_(0xdf0c450d), LL(0x76bc05d5,0x916202a7),LL(0x05568dde,0x84cf17af),LL(0x89f0919f,0xb5670da6),L_(0x97387cce), + LL(0x54cdc952,0xc269a349),LL(0xae4d60ad,0xa15fdc88),LL(0x27a5a550,0x560e5ad7),L_(0xfd2940f8), LL(0x23e1393c,0x86446f69),LL(0x2f2ee978,0x918a434e),LL(0xa481c71a,0xd1f9e2af),L_(0x99fe0c80), + LL(0xecc46dd9,0x4c354b31),LL(0x9d2731ca,0x5917267d),LL(0x9583d77a,0x549fab4d),L_(0x20743202), LL(0xfa4579de,0xc9afa8d5),LL(0x6ee70bf6,0x679e9b14),LL(0x71181b55,0x34dfc171),L_(0x186cb701), + LL(0x92faa6da,0x784904dc),LL(0xef91aeb1,0x99e8f15a),LL(0x466ca745,0x9dba0e94),L_(0x3efbbed0), LL(0x9c629c4a,0x818f1160),LL(0x238404b3,0x1649074d),LL(0x7f378102,0x9026e5ef),L_(0xd9ddeb02), + LL(0xcb042e26,0x50f516e2),LL(0x359a1ffe,0xf69c04f0),LL(0xea7c7fb8,0x2be043ec),L_(0xe26d37f4), LL(0x4f292184,0xd8d23c81),LL(0x97f967f3,0xa3d950fe),LL(0xf97e68cf,0x0cf39dbb),L_(0x0f3321ca), + LL(0xf1e4bd62,0xd200dfdf),LL(0x890af600,0x9e7aabf2),LL(0x1e4962b1,0xd80a6211),L_(0x78562fa6), LL(0x2ca32240,0xdb5a70a7),LL(0x68abbf8d,0xb27e8e16),LL(0xbffea5c8,0x99114570),L_(0x6e5308c1), + LL(0x4fe00738,0xdfd77bdc),LL(0x16448af4,0x0bebe0b7),LL(0xcb49f26a,0x9f4c424c),L_(0x7c95aa03), LL(0x84b25349,0xd5948dce),LL(0x93acdc43,0xa92b381d),LL(0x7efb93e4,0xa8e311a0),L_(0xe08e348f), + LL(0x8f67c168,0x96c4f394),LL(0xfa10af74,0x457899a3),LL(0x489d01bc,0x1a4d0c16),L_(0x5457e489), LL(0x5c85d68a,0x1331b4d9),LL(0x84eb66f4,0x97024d48),LL(0x8054cf7a,0xb191cf89),L_(0x3e7eb0cb), + LL(0xd307d077,0x8d0cc3ce),LL(0xa6a534ca,0xa8bd8bc1),LL(0xa917d88e,0xc01d22dc),L_(0xba878e3c), LL(0x6dc0cccd,0x927b4947),LL(0xfb3f69e6,0x8cef47b8),LL(0x44185c64,0x586c00a9),L_(0x151ed75b), + LL(0x2be07ecc,0x72a46aa9),LL(0x519ea031,0x5b289abe),LL(0x75f6f741,0x1a09f429),L_(0x0df7057c), LL(0xe83d8445,0x0511f341),LL(0xb8c291d5,0xcd82da51),LL(0xbd814e25,0xa548461b),L_(0xdfcbbc5c), + LL(0x481967d8,0xf029f707),LL(0x3ec594c8,0x9b2f8b93),LL(0xaacdcc45,0x76cebcbf),L_(0x6e7c6e83), LL(0xaec54ae3,0xa2a8a4fe),LL(0xb47c1c29,0xea7ebbf6),LL(0xebdc1ae0,0xed49a01f),L_(0x63ac12b4), + LL(0x532eddda,0xaa4b3b46),LL(0x7e957ed9,0x54c46d48),LL(0xe3393b10,0xde08b775),L_(0x8522afee), LL(0x04a30d0e,0x5f73d8d1),LL(0x39d26476,0xa070b5a5),LL(0x7e58e0f3,0x213036c0),L_(0xa0e99b0f), + LL(0x180c99f6,0x8a626b91),LL(0xbe1888a3,0xa37b0a55),LL(0xc627fd2e,0xd55c88b6),L_(0x75c0ce87), LL(0x143ea75e,0x96806d01),LL(0xdce56555,0xb31db013),LL(0xa0f7c5ea,0x286d7145),L_(0xd7ff4a5f), + LL(0x7eb22eef,0x9f5793c8),LL(0xf0bdad25,0x3795ea86),LL(0xde77b0de,0x308c67ea),L_(0x506de99f), LL(0xa761521a,0x9d70efe9),LL(0xf8b6908d,0xbeee111a),LL(0xa22f9208,0xabb48b09),L_(0x305250b9), + LL(0x54347d1c,0x04d51ba3),LL(0x69790978,0x0cf10a39),LL(0x55c72c45,0x340e8617),L_(0xcd9b6116), LL(0x897f38e5,0x80b0004a),LL(0x8b257151,0xa9ff195d),LL(0xae7d889b,0xd95f9a8b),L_(0xf7035183), + LL(0xf9445254,0x96f17da2),LL(0x21e71bcf,0x87497b69),LL(0x1dde1b45,0x3f515a1d),L_(0x1f620fc3), LL(0xbb05c2ca,0xd2651945),LL(0xa7f48789,0x5426bd20),LL(0xa9e9b7f9,0x048d20b9),L_(0x2efd58e7), + LL(0xfddc7154,0x095a8f25),LL(0x6fa2edc8,0x675fd35e),LL(0xad7dc081,0xf2b8fbbb),L_(0x88a7b80f), LL(0x6cabea84,0x2ca3a2a5),LL(0x00c09332,0x1047dcd4),LL(0x0d577a61,0x54d150a9),L_(0x1837cf45), + LL(0xe243bea6,0xec967631),LL(0x281b5c05,0x7c40da6a),LL(0x580362ba,0x832277a8),L_(0x702cc617), LL(0x1ca409f6,0x7335bdc8),LL(0x26119f95,0x735f11ed),LL(0xa27ab674,0xc7055ffb),L_(0x652580b5), + LL(0x3dba43f3,0x8c6adeda),LL(0xebd0f498,0xa42d63e8),LL(0x993107d0,0xb75b4edf),L_(0x0232f8ad), LL(0x720ca302,0xa2592945),LL(0x48d03da4,0x473bf917),LL(0xda871c01,0x8ff4aaa7),L_(0x746e818b), +}, +/* digit=14 base_pwr=2^98 */ +{ + LL(0x3e28ba8b,0x23800fab),LL(0x8b12655a,0x99a4d041),LL(0x66a4179d,0x33023ec9),L_(0x1205108d), LL(0xdbb13a66,0xa87c96ac),LL(0x402e3b9a,0x98998891),LL(0xd3dbe7de,0x6b327511),L_(0x5723ac5b), + LL(0xa70cb5da,0x7ab235bd),LL(0xbede2315,0xac5f3af5),LL(0x5f9a6aaf,0xe6d56464),L_(0x357d2d21), LL(0x3156d6fe,0x95a60b40),LL(0x49f4f0e2,0x9e63e29f),LL(0xdca3ea62,0x4c739342),L_(0xa16d4457), + LL(0xe1948d0e,0xdcc5b89a),LL(0x463327ef,0xd5a2f46b),LL(0xadb9328a,0xbfce0e4d),L_(0x0d62b545), LL(0x1dd89a4b,0x349d4bd5),LL(0xa76133fc,0xc19125f9),LL(0xb4284724,0xf5a817aa),L_(0xf7ca3909), + LL(0x7fc121e6,0x0655039e),LL(0xbc44db37,0x42a0f87f),LL(0x3d4e983e,0x67d89bbe),L_(0x85435ace), LL(0x18346e4d,0xbe29cd2e),LL(0xed39f9e8,0xe8b5a373),LL(0x55cac6ca,0x3d4406d2),L_(0xde2aeda4), + LL(0x6b7d56c0,0x8fabc04a),LL(0xc39c7ee8,0xbb51ed42),LL(0xc619fe58,0x0816fbf5),L_(0xf268e46c), LL(0xe0f981bd,0x3b1bba1f),LL(0xce226865,0x27136de9),LL(0x4f9ab1d9,0xfcbc42d6),L_(0x13efb949), + LL(0x4f54831f,0xf8119c34),LL(0x75d60569,0x24503e1c),LL(0xb3a82995,0x063e48b4),L_(0xc7bc1aec), LL(0xf21ff6a7,0xd626619e),LL(0xa7f182b8,0x5a64395d),LL(0x533f72eb,0x1d2aa02e),L_(0x69953a2d), + LL(0x64b57fc3,0x91516c9b),LL(0x0913a322,0xb1936549),LL(0xa0961a2f,0xa7d10cb1),L_(0x06e4869d), LL(0x8f465d18,0xdc8793e6),LL(0x9f17e3a2,0x9a3dd9de),LL(0x06fc6243,0xe925133a),L_(0xb7622bbe), + LL(0x784462ed,0x84e7489a),LL(0xc981ba62,0xe5d5e019),LL(0x792db847,0xa77e3ed1),L_(0xf4b6792a), LL(0x36f5a622,0xed208d22),LL(0xfc7dc4a1,0x953f894f),LL(0x87c2b024,0x095b0ea7),L_(0x88016bc4), + LL(0x486f7168,0x59119396),LL(0x4b8755e3,0xb37c8ef0),LL(0x19aa2514,0x554f2e58),L_(0x1d544a58), LL(0xaa9858fe,0x1d4dba6e),LL(0xcc8e5a35,0xa400007e),LL(0x4036ed62,0xf70ca123),L_(0x0fd793e9), + LL(0x292ba598,0x269da084),LL(0x2503b0ce,0xdd28f9d0),LL(0xb3025472,0xeb061c62),L_(0xfe9ae248), LL(0x79d8d16b,0xd2906b24),LL(0xeaa5d6f9,0xdee30126),LL(0xaf62d50d,0xc2b140a8),L_(0x4dbbcce0), + LL(0x57f41736,0xa7cf5774),LL(0x3293ff9c,0x238c8acf),LL(0x1f10127e,0x739c1785),L_(0xc01f9711), LL(0x761037ad,0x68df6a03),LL(0x50fcfcf4,0xc797349c),LL(0x340f3712,0x53cced84),L_(0xba988480), + LL(0xc57ef65f,0xed47d3b7),LL(0x6051e486,0x623f7228),LL(0x2e29a4c3,0xfb40723c),L_(0x77353f89), LL(0xda6cb60f,0xf4eea8fd),LL(0x672e091a,0xd086a7ab),LL(0xef34d20e,0x96e8e707),L_(0x2e5db0f7), + LL(0xd47d7453,0x089e80e8),LL(0x259bf71c,0x99cb2528),LL(0xcd52c81c,0x9b67f891),L_(0x106aa44c), LL(0xb3fd57c9,0x84cca31f),LL(0x492159ac,0xd208e111),LL(0x99fc08c2,0x9a577c2f),L_(0xde194e1f), + LL(0x3ffcd5a2,0x1a869e94),LL(0xac2dd0d1,0x0101716e),LL(0x0d98495e,0x926fca45),L_(0x230d5720), LL(0xd7a376f8,0xda97aa6f),LL(0xe0f36b43,0x043a0c8c),LL(0xbdee74a9,0x9f4f1e97),L_(0x616d2e77), + LL(0xc462e14f,0x4ce190f6),LL(0xe408ab06,0x8983aaf7),LL(0xaec26bc8,0xea864657),L_(0xa9c6ad27), LL(0xe823a8e1,0xab862943),LL(0x327c78b5,0x42d64507),LL(0x751ec6f1,0x18bed81e),L_(0x1c240eff), + LL(0xc5905237,0x291c3272),LL(0x766b4a0b,0x7507a05b),LL(0x6e56a096,0xafb97a2d),L_(0xe3cbbbe3), LL(0x44beffab,0x2369de34),LL(0x4c78c1e4,0x287f5c70),LL(0x698e8f90,0x14e1a4eb),L_(0xa87a74e8), + LL(0x4ca2c62e,0x0fb3705f),LL(0xcbf75eae,0xe59c7ef1),LL(0x58dee01f,0x1a149a9e),L_(0x67ff1a09), LL(0xa2bee6a8,0xf63b9864),LL(0x7e111af7,0x602716b7),LL(0xf6f23814,0xc6967a32),L_(0x682916a3), + LL(0x94c36bb8,0x53aa5941),LL(0x7dc26ca6,0x57977663),LL(0x3a7f3859,0x4c6d1720),L_(0x87d2b98e), LL(0xce189ddd,0x379e4e5c),LL(0xc6bec0ca,0xafc9ee7e),LL(0x69db9b01,0x4e3aaa80),L_(0x4f1a3e1f), + LL(0x9f2327ea,0x948cf978),LL(0xe1a7d9ed,0x932e601a),LL(0xabd060c2,0xe2c8026f),L_(0xd02845ba), LL(0x4568e0ed,0xd2fcd20c),LL(0x9fc8ca8b,0x224394d0),LL(0x0b403598,0xfa897231),L_(0xd2ef4cab), + LL(0x61ffdada,0xc9608223),LL(0xd3a9e728,0xbfde5d50),LL(0x9fcf28b0,0x23db313b),L_(0xe226f1f0), LL(0xc362ae30,0xdd26c697),LL(0xa3a7479f,0xbe0de20e),LL(0x4871cbd5,0xc0ad648f),L_(0x30414c9b), + LL(0x93a58cef,0xe22f8df4),LL(0xdef38d08,0x40b0ba7f),LL(0xfacc23b1,0x7b3f5e97),L_(0x00fb9a2e), LL(0x926c141d,0xa6cbdc36),LL(0x87cb811c,0xefb43047),LL(0x6214d9f5,0x06806fd9),L_(0x5ba8f23b), + LL(0xc5b2ff25,0x86e33c2c),LL(0x23423298,0xde9bc0ea),LL(0xf6e30434,0xc242970e),L_(0xbf53cf6b), LL(0x3df6ea77,0x84f61ee9),LL(0x8140c42b,0x1d03d30e),LL(0xe917c40a,0x70d1d6e0),L_(0x95de99fd), + LL(0xca391889,0x396774da),LL(0xc249bd59,0xc8c93775),LL(0x24f81111,0xfe365e8c),L_(0xdcd6e625), LL(0x680035a8,0xe01d308c),LL(0x65e9e9bf,0xe2741d32),LL(0x5cab99f6,0x441a1645),L_(0xf759c45d), + LL(0x858ad4cf,0x1d7326e1),LL(0x52fad307,0x7ee589d6),LL(0x3aa389bc,0x9cfd5023),L_(0x3feb82b3), LL(0x03b8a60e,0x4a98e744),LL(0x22a198b9,0x2c871f83),LL(0x5fd22f5d,0x95dcd425),L_(0xe40ca457), + LL(0xb6c77ce3,0x0baec1d0),LL(0x899726d2,0xe604c5b2),LL(0x9503a4a3,0x8faff5a9),L_(0x735bcc96), LL(0x6c5c0a3c,0x294b5dc8),LL(0x27659e3e,0x63327cba),LL(0xb11539c5,0xf82de3fd),L_(0xdafe9d6c), + LL(0x2b031402,0xb712f885),LL(0x4ba7d548,0xc6d1f271),LL(0x627d0816,0xebc722ce),L_(0x4e21b679), LL(0x2f1104b0,0x3d488791),LL(0x654d615e,0x7a45f251),LL(0x38e30e5a,0xbe0c2b4a),L_(0xd07392c8), + LL(0xc3944e46,0x91582e10),LL(0x245a5f24,0xbf72cd72),LL(0x1d74fe95,0x32fc2d8c),L_(0x8d68efa6), LL(0xc63d3e55,0xb73ed81a),LL(0xd7c363e3,0x81d7988d),LL(0x4b18aee3,0x8563cd35),L_(0xf296ee0a), + LL(0xde9cd058,0x6115b5de),LL(0x12e07056,0x494a27b8),LL(0xab33f925,0xdadb7f44),L_(0x9611fc0f), LL(0x7c525248,0x135db673),LL(0x0014d0b2,0x13d5d03c),LL(0x34df44be,0x498b5aab),L_(0x3b9bf0a3), + LL(0xb6d60031,0x8b47b859),LL(0x7583945e,0xd5d1a023),LL(0xe1eb9f0d,0xdc6bf5ac),L_(0x7f50540d), LL(0xd48c1aad,0x7dcd0fa2),LL(0xd6e884e8,0x7ff3b8ae),LL(0x0fda3c41,0x42d34849),L_(0x156b5074), + LL(0xf41aefe8,0x9db1951d),LL(0x6f1aaef3,0xc78e5a0a),LL(0xe07d36c2,0xaf67c45f),L_(0x598114fb), LL(0x491a5763,0x1883388f),LL(0xb079f72e,0xfa868602),LL(0xee4b11df,0x20bd4ca5),L_(0x9dd3598b), + LL(0x4fe58726,0x2f515e06),LL(0x0a130c64,0x03928fde),LL(0x21d929ee,0xed92766f),L_(0x2370b592), LL(0x26410775,0x461ee104),LL(0x11fd327c,0xbf2200cc),LL(0xaac6ed8b,0xaad362f8),L_(0xe2c21338), + LL(0xa0369424,0x7702c304),LL(0x90cc96b4,0x88180dc5),LL(0xec9108c9,0xea844162),L_(0x79d4d2e8), LL(0xf7c7120d,0x9b79933f),LL(0x9b1c7dfd,0x73191637),LL(0xf8a798d5,0x4a0a1e22),L_(0x7439503e), + LL(0xa7716be7,0x25112356),LL(0x41a91a95,0xf0234300),LL(0x12be9cf2,0xa09c00f4),L_(0x87b213f6), LL(0xb0626c0f,0x3cc23f7c),LL(0xa44cb6f8,0xee84c654),LL(0xda068194,0x999bf774),L_(0xe19968dc), + LL(0x20c86fd9,0xa3bbb5a6),LL(0xe07280d1,0xdced85e1),LL(0xf0df9658,0xbd50dd87),L_(0x4715fc8b), LL(0x90915daf,0xf3d02094),LL(0x64a96f25,0x5a8039b5),LL(0x661822c3,0x8b298e54),L_(0xd8ec764d), + LL(0x4146852b,0xcef9767a),LL(0x3dfab91a,0x3b280141),LL(0x85522368,0xdbf3bb79),L_(0x79b36fcb), LL(0x730e7127,0x05fa18c1),LL(0xdbafd1f2,0xf1172af0),LL(0xdd549dff,0x83c7657f),L_(0xd82dc78f), + LL(0x35ef27c5,0xad652989),LL(0x58b32f27,0xeb421196),LL(0x976af3d3,0x4b505f2e),L_(0x64c1cfc3), LL(0xf3dae0f8,0x59913cfd),LL(0xbab37657,0x2039f0fc),LL(0xf066519c,0x8887e569),L_(0x3d975cff), + LL(0xb1eb152a,0x425ddccb),LL(0xd5368e78,0xe11b71d6),LL(0x12b23c3e,0x33076aa1),L_(0x4e626b1c), LL(0x4b18cb13,0x23f1e78c),LL(0xe86079cd,0x875b887a),LL(0x908738ce,0x244ce9b9),L_(0xe51d741d), + LL(0xd6758071,0xb2d63b63),LL(0xf0e2cdd8,0x30007109),LL(0x90f8143d,0x75829dd6),L_(0x2d23a43f), LL(0x5e5327c1,0x47ca8667),LL(0xa526104e,0xf04921aa),LL(0x85467645,0xb0f0e275),L_(0xafc61eeb), + LL(0x87b4b9ac,0x7ee79f80),LL(0xf367484b,0x27ef21cc),LL(0xbfc8c258,0x7fe068cc),L_(0x7c8262c2), LL(0x572f615c,0xc96069f0),LL(0xd5c6e6e1,0x5f2c8d88),LL(0xd8f70ecc,0x24073300),L_(0xc55f13ed), + LL(0x33b47b28,0x82d22a51),LL(0xe38ffddd,0x480198ae),LL(0x03df60cb,0xa964fa9d),L_(0x9bfb3890), LL(0xee5cec96,0x96707a63),LL(0xf9f9338a,0x22ae2467),LL(0x5d9e9ac0,0x0acd29e1),L_(0x854609dd), + LL(0xb29eb007,0x84bcad3a),LL(0x9a527f75,0x761f8288),LL(0xc16f294f,0xdaf38a99),L_(0xfdebcc4a), LL(0x9c537eba,0x8a1d04d0),LL(0x760244a9,0x03627bce),LL(0x97af96d2,0x79ecc48b),L_(0xebf508a7), + LL(0xa6400e31,0xa9338a43),LL(0x4ccbe898,0x4312a928),LL(0xf79ce659,0xa7f6528b),L_(0x0efdd8f6), LL(0x0c3ef14c,0x7002f54a),LL(0x859eefc9,0xacd6c70b),LL(0x3146204e,0x25b282fd),L_(0x9e570ac1), + LL(0x7cfc8794,0x50227a05),LL(0x96cc2182,0x5a9a9895),LL(0xed491384,0xa5e9dc33),L_(0xef480409), LL(0xf767a743,0x48fc5412),LL(0x7b84b8b7,0xb18a17fb),LL(0x22c04cfa,0xa2e99567),L_(0x5b8dc942), + LL(0x45e7789f,0xb80a1876),LL(0x7a0670f5,0xaff77eda),LL(0x99c0dcff,0xceba003e),L_(0x737b1478), LL(0x169db41d,0x88ff60f7),LL(0xa8a91790,0xe2c4f8ba),LL(0xd0c75bfd,0x8ebfd0f8),L_(0xaf779b34), + LL(0x0401de06,0x62fec3e1),LL(0xd969780a,0x99a90daf),LL(0xafc171d9,0x647f2bf8),L_(0x16ea68f8), LL(0x41dbf4ac,0x83f12d02),LL(0xb63e2588,0xa64d6924),LL(0xb69cbad9,0x08b7948f),L_(0x1a740ee4), + LL(0x4eff7cff,0xd3ad093d),LL(0x97774b8e,0x520858a7),LL(0x1438ff5b,0x90acd42f),L_(0x0c55b2c6), LL(0xdb613141,0xf3524dc0),LL(0x1f19f151,0x4d56c7a8),LL(0xc5b4f62c,0xe1899b7c),L_(0x7240d638), + LL(0xeb1a717d,0xf9ad69aa),LL(0x9a96c604,0x32f476a8),LL(0xd851c4f0,0x816d9822),L_(0xf895d68e), LL(0x6f708c56,0x914c2f2f),LL(0xdd941975,0x64e1cdce),LL(0x1765af52,0x9bdc107c),L_(0x770ebc8f), + LL(0xc745e953,0xe5bd052c),LL(0x70e13a7c,0x1d26e2b6),LL(0x0c4379c6,0x0121f8bc),L_(0x71124e71), LL(0x87d6954b,0xe43a3a54),LL(0xd9134113,0x9bfa2ae6),LL(0xbbbe7daf,0x3a1c2b24),L_(0x3950f72a), + LL(0x6a18f59a,0xa71550b0),LL(0xdab1491f,0x73428fb9),LL(0x12caa6e9,0xb08da5e0),L_(0xf505a6eb), LL(0x3f48afb0,0x79842176),LL(0xcf510150,0x2962dfb0),LL(0xafdce054,0x87a8f6f2),L_(0x8158b7f4), + LL(0x438e4a3a,0xe2eb279d),LL(0x6af97a49,0x42b5d181),LL(0xd6c5159e,0xcf78aa46),L_(0x572c05de), LL(0x50428178,0x0bf9ef59),LL(0x5b7148bf,0x479ccacb),LL(0xbe4b9632,0x101cdc13),L_(0x7ed1a6b8), + LL(0xf0214364,0xb580b66f),LL(0xc6feaf5c,0x4e810e3e),LL(0xa5cb0934,0x02cfec16),L_(0xc2e35b6b), LL(0xddb45407,0x6e09365d),LL(0x5b4d0976,0x76d217cd),LL(0x405714ef,0x892fc650),L_(0x75be4796), + LL(0xf30d07fb,0xe024a3b5),LL(0xffdc8787,0xe4416883),LL(0xbb8a1baa,0x16ab4631),L_(0xf8688223), LL(0x2f0f8322,0x09c1692b),LL(0x0dd7a6f9,0x13a2837f),LL(0x3a94d17d,0x784e210d),L_(0x58b82c4e), + LL(0x75a9d2ec,0x4df5c032),LL(0xa0b09f2e,0x9989a169),LL(0x8ad59d7f,0x92ef323e),L_(0x9dfd994c), LL(0x641354fe,0x9c294c51),LL(0x0784cc2a,0xa2a1bccd),LL(0xa7c397c2,0x9d3b5c1e),L_(0x5217298a), + LL(0x1d43acad,0x5fffdecb),LL(0x15425166,0xd4c107c2),LL(0x3ad2c54b,0x29b56266),L_(0xcbfffc28), LL(0x2c3f6f4b,0xb4051ff3),LL(0xe925b548,0x65af8f85),LL(0xd94421d3,0x61d3c552),L_(0x0c2f7520), + LL(0x6d77a3b7,0x70ed4768),LL(0xfa81c450,0x9fe1ff87),LL(0xbb762aa7,0x72d6d774),L_(0x7b08eae2), LL(0x7dbd50f7,0x1432d1e1),LL(0xc28ea0a8,0xd0acc833),LL(0x57bf54b2,0x163d3f1c),L_(0x996fa17f), + LL(0x4583d724,0xb5fbaafe),LL(0x53d923d7,0x051dd3b4),LL(0x8aeef402,0xc59594fb),L_(0xd7267ef5), LL(0x5e8a7497,0xede0bede),LL(0xb019e637,0x6171e5a5),LL(0x1be98aa9,0xb69b47a8),L_(0xd848486b), + LL(0xddef3d83,0x95f000be),LL(0xc417bef7,0x615e1192),LL(0xef4c07bd,0x74d082e1),L_(0xc8cd53f2), LL(0xc2fe846c,0xfb026020),LL(0xaab1ecd2,0x31978a04),LL(0x47b08bd0,0xf6ef41f3),L_(0x386f4e41), + LL(0x0974e562,0x806b3be2),LL(0xd292e87d,0xb4c666b3),LL(0xb31604a0,0x08cba3d2),L_(0x5a2daba1), LL(0xd6e9ea3f,0xff881f9f),LL(0x4da3f147,0xbaac2563),LL(0x8b3ea4f6,0x7f14ef98),L_(0x931e6a5d), + LL(0x09ed1548,0xe8b9b58f),LL(0x3a4e460d,0xbdf4bff4),LL(0x410540d4,0xba715bf7),L_(0x9faf6e57), LL(0x58d1763d,0x13d8563b),LL(0x83a48da3,0x3effa46a),LL(0xbc420fce,0x54fecfb6),L_(0x8ea8b02c), + LL(0xcc8fc2ff,0x9f084f50),LL(0x15421912,0x4d3ec704),LL(0x69e1810f,0xa93a4b35),L_(0x66d7f71e), LL(0x75523ca2,0x9b5d9b14),LL(0x85c36f3f,0x8615c97c),LL(0xf837f0c4,0x1acc3982),L_(0x4526c2f7), + LL(0x61301784,0x91bdbe3d),LL(0x5c462b80,0xe5304d0f),LL(0x16f4a53a,0x2452c556),L_(0xf2ad5a49), LL(0x92965e0e,0x961c76d6),LL(0x92031bde,0x3e75de1d),LL(0x43fc1b46,0xba2806c7),L_(0x7ea59306), + LL(0xe2e84c48,0xaf7fedc1),LL(0x44f370ac,0x7473cfd6),LL(0x7fa03a08,0x366491a9),L_(0x65caef0d), LL(0x8b501288,0x3a469595),LL(0x6dc5f00f,0x67981e43),LL(0x87cfba83,0xebb7f488),L_(0x1fc8150f), + LL(0x0adc88a9,0x70a3e6c5),LL(0xf79b97ae,0xc2b70fcd),LL(0x0c92525b,0xfd612292),L_(0x1f877d7a), LL(0x2017f6eb,0x2b249ae0),LL(0x78a6422a,0x083dff80),LL(0x0659a5e4,0x12934c87),L_(0x7a1fca11), + LL(0x2ef56139,0xe4d85de6),LL(0x0b0acedc,0xf2c33f4b),LL(0x6091bc19,0x04526cb6),L_(0xac1ce3ea), LL(0x24bfc4bb,0xb54024a6),LL(0x57196c24,0x909d86a2),LL(0x42e04322,0x1b1d5d2a),L_(0xbb31992a), +}, +/* digit=15 base_pwr=2^105 */ +{ + LL(0xb476bc0f,0x5f4861c3),LL(0x9a1b156b,0xed89263c),LL(0x45b930e9,0xbeb5a955),L_(0x29358e8a), LL(0xaad0495f,0x7923968b),LL(0x127f5983,0x3abc6adf),LL(0xf5aef19c,0x22713358),L_(0x0329be36), + LL(0x97c8de6b,0x842632ce),LL(0xd5e766ad,0xfcb4c194),LL(0xbab1e908,0xdb59f894),L_(0xa103e5b9), LL(0xe0644e8b,0xc4c67972),LL(0x2cd3e628,0x340af5c5),LL(0xe2690b88,0x787c5ec2),L_(0x153e0f49), + LL(0x7e2abe1e,0x01d9f5c6),LL(0x9acab18d,0x4187566a),LL(0x96fbb4bc,0x43543f3e),L_(0x19e99acc), LL(0x911c12bc,0x4d4f6942),LL(0x2373babd,0x05a419a8),LL(0x0c662933,0xdd524336),L_(0x60570f05), + LL(0x5607a4f3,0x98a32e87),LL(0x9cbcb156,0x841d648d),LL(0x00a72b88,0x85f705a8),L_(0xb60a7751), LL(0x30e3dc7e,0x3ef7d9b6),LL(0xc5078f17,0xeec26796),LL(0x20110dec,0xb521d60e),L_(0x324aa16f), + LL(0x547a71b7,0x7053cd14),LL(0xc75d38b5,0x3ecd5cad),LL(0xff26fb53,0xfa6fa1ea),L_(0x89904b74), LL(0xba1aaedf,0xb9800605),LL(0x0d1c07cb,0x517f26e6),LL(0x7605e424,0xe982130b),L_(0xc4ed9c66), + LL(0x06117460,0xb3f704f4),LL(0x2c1c043d,0xed0726e9),LL(0x3e68dbd8,0xbe354e8d),L_(0xa6382386), LL(0xa4136478,0x26378a40),LL(0x04646666,0xcc8a8909),LL(0x88fbb7ce,0xc603785d),L_(0xb1f815a2), + LL(0xee89450b,0x43fe75c8),LL(0x9a29229c,0x16a051c0),LL(0x9b1a9170,0x7d4b9fc3),L_(0x133dd4ca), LL(0x738df325,0x53ac8646),LL(0x6dcfad8d,0x5c600cb6),LL(0xe4115708,0x6ff11203),L_(0xbc9689c3), + LL(0xaab0cefc,0xd81789dc),LL(0x7b457d74,0x67ca91b0),LL(0x5a87275f,0x096f997d),L_(0x5d4f53a6), LL(0x3d1c72aa,0xc86a176a),LL(0x0c5247ba,0xbb03ebf7),LL(0xb389c0f5,0x325d67b1),L_(0xdc511ddb), + LL(0xe0e68838,0xa0dc02ac),LL(0xca8b2e56,0xcb1f32e9),LL(0x59515fbd,0x152ad207),L_(0xa0ec8c40), LL(0xaf08ac54,0x990ce0e8),LL(0x094829b8,0x62062c81),LL(0xdb93ce78,0x53af9d31),L_(0x980f663f), + LL(0xa663c4b2,0x0afcea40),LL(0x1410da31,0xeb72dea5),LL(0xc4dd3dce,0xefc18ea4),L_(0xc844e9d6), LL(0x827776e0,0xb2b1ab80),LL(0x89238185,0xeef3941c),LL(0xc007c089,0xcc238164),L_(0x10df0d3c), + LL(0xccb1a15d,0xd9103e73),LL(0xec1702f8,0x34d31501),LL(0x67e64440,0x4b15a941),L_(0xaf4f5d2e), LL(0x8b86c479,0x82fa4170),LL(0xbc874d39,0xb17316c7),LL(0x63f968d3,0x7b71afa1),L_(0xc6c567c6), + LL(0x8941fa38,0x1b353d4b),LL(0xfbfeb69e,0x76d964d5),LL(0xaecee209,0xdaae33fb),L_(0xc8d8f5e9), LL(0x47c07e3b,0x4e52dc91),LL(0x87741a88,0x92359ae5),LL(0xa5009004,0x72c650f3),L_(0xc505e3b9), + LL(0x660afa5f,0x2c204e5a),LL(0x9f6af3aa,0x70aa9a5d),LL(0x0423f2f9,0xa67cf879),L_(0xe29129c8), LL(0x58a3703e,0x47ebe4a0),LL(0xc220fd1a,0x8f060a95),LL(0xa34e4a66,0x1fd2a0dc),L_(0x7c1fb322), + LL(0x1bfb2217,0xcad10b11),LL(0xca3e4b04,0xc1ab5423),LL(0x00ce7df7,0x9c84d269),L_(0xa1f31fb1), LL(0x8a721b19,0x45e72360),LL(0xf80ab752,0xa59a87d1),LL(0x38935f38,0x36966819),L_(0xebd1b2a6), + LL(0x657a1f10,0x28dbeb1d),LL(0x4f41e2ad,0xafbe6ad3),LL(0x1c0782c2,0x60b0cb1e),L_(0xb609d7c2), LL(0xae37eb9c,0x403c7b8e),LL(0x3d308948,0x374fa1b2),LL(0xd8503866,0x0326fd01),L_(0xd472fecf), + LL(0xa5b224c1,0x98673100),LL(0x35c900a8,0x7e857bdd),LL(0xdb5df675,0x63415d28),L_(0x6b676a73), LL(0x04cd81e5,0x3e21afd0),LL(0xa33929eb,0x2e610def),LL(0x717e43a4,0x6bf414b5),L_(0x9c7a3c47), + LL(0xd475f817,0xf9ea4384),LL(0x6b738d34,0x671b40ad),LL(0xac317163,0xd197efee),L_(0x2438948a), LL(0x66a989c1,0xebcc3f73),LL(0x1fc5f207,0x7913fae7),LL(0x9fdbdbb6,0xddc39008),L_(0x663a5b4e), + LL(0xe781f5a2,0xa670dec4),LL(0xaeb71ef5,0xb1196ff6),LL(0xa4973f38,0xf981cb1a),L_(0xe1b496e0), LL(0xcfa69883,0x8185f4e4),LL(0xdcd9014d,0xfea1489d),LL(0x01c7c910,0x33bfde50),L_(0x0a1d6d42), + LL(0x0b6d7bc6,0x0c74186c),LL(0xf93c6e65,0x21c134ed),LL(0x5c4b9d40,0x9b7f55b4),L_(0x62194b5f), LL(0xf0967474,0x07af0f2c),LL(0xead94ac6,0x43b53483),LL(0xfc351f8f,0x6a02d6dc),L_(0x96c34c95), + LL(0x8a77d8e2,0x06eb2a9e),LL(0xb29f094a,0x5a50f6db),LL(0x8cc86e58,0x40844e37),L_(0x2f8aef05), LL(0x3ed6ee27,0x864a532f),LL(0x8ade6f97,0xbafa3f05),LL(0x78f8e230,0xadc126ed),L_(0x8c70fd00), + LL(0x61f69a9b,0xecdb5c0e),LL(0x3c35a3f6,0xac81a7f8),LL(0xe0f4235e,0x49ad3737),L_(0x162c0cf0), LL(0x9bbaae92,0x6d262e32),LL(0x3611d970,0x92ea2e05),LL(0x56f9b02c,0x569e559b),L_(0xd700ade3), + LL(0x1248f104,0xab2f2393),LL(0xf45846e5,0x2e1305dc),LL(0xaa46d2c4,0x1222d842),L_(0xf5f64176), LL(0xfa36ca68,0x1b067c95),LL(0xb8990097,0xbdbafd4f),LL(0xd2f67212,0xe2b50ce3),L_(0x7ac5ce8c), + LL(0x2f610f1e,0x754843cd),LL(0x77e241fc,0xeb4f1114),LL(0xa0d9cbeb,0x55cb5b7b),L_(0x98136c68), LL(0x4f9041bc,0xef262223),LL(0x523e661c,0x38002545),LL(0x30661570,0x3e7c7958),L_(0x5ea1ccfb), + LL(0x43726846,0x736e6684),LL(0xa762a548,0x4ea61054),LL(0x4ea95a8f,0xa90f1dd7),L_(0xf1a7ecac), LL(0x052ff525,0xdb175bab),LL(0x176f58b3,0x113349c6),LL(0x66d2f2dd,0xf30e4d83),L_(0x047e3e70), + LL(0x3053884b,0x2523bfbe),LL(0xdb1ab97e,0x32d988c1),LL(0xa7f43905,0xed30067f),L_(0xe0063138), LL(0x315aac55,0x0fe3afe0),LL(0xef7cd5f9,0x25c62d9c),LL(0xbceebc63,0x7475ff1c),L_(0x37aef5f2), + LL(0xd9f33d01,0x21d9dd88),LL(0xfe303f84,0x0e4f3aea),LL(0x403a10c7,0xdc250e4e),L_(0xcf99ada4), LL(0x20afdb06,0x16293016),LL(0xdf77e00f,0x21ef71a7),LL(0x017aea99,0xb51701db),L_(0xb9a51f04), + LL(0xb223220b,0xaefa0a3e),LL(0x3c6160d1,0xd7af87c7),LL(0xb6871dd0,0xcb336211),L_(0x30015933), LL(0x605c6481,0x87d9707a),LL(0x18fd4882,0x367d0209),LL(0xf138a307,0xeeb3123d),L_(0xce3f684e), + LL(0x1ad5ce5f,0xdb674dfd),LL(0xd843e892,0xc8958516),LL(0xedfd1c19,0xc7988b87),L_(0x3bdd2895), LL(0x9b80b679,0x09bd2af2),LL(0x294ff4e2,0x3150d204),LL(0x2ad4535f,0x2fc2c26d),L_(0x1ebd13d4), + LL(0x0284d812,0x0bdfba7b),LL(0x94e42bd5,0xabd7b483),LL(0x512c1be7,0x10be5ddc),L_(0x6bc6d702), LL(0x0bf271cb,0xd21e8820),LL(0x636561c6,0x0b1793f9),LL(0xe4ef4a35,0xda161673),L_(0x3d69a37a), + LL(0xf8513215,0xc206f7b0),LL(0xa0f11bca,0x9944badb),LL(0x23eeb3f7,0xe6050ed7),L_(0x98889901), LL(0x2ce1ebe3,0xc76ba3ec),LL(0x4edc3ee6,0x3e534941),LL(0xaab7f4a9,0xc6e7d7b5),L_(0xf6442856), + LL(0x6d4746dd,0x5b3638e6),LL(0xd78b290a,0x6b3e0d8f),LL(0x77aef8ca,0xfac422d4),L_(0x0feb906d), LL(0x3bc30209,0xdc0b9001),LL(0x331327a2,0xe68c779f),LL(0x5d146cb4,0x6fb5da21),L_(0x3f887bb5), + LL(0x13fd6d90,0xb80d181c),LL(0x2be6d108,0x288db1c9),LL(0xb342ddca,0x7004d85b),L_(0xbe7db7ec), LL(0x0ba4c981,0xc1d565da),LL(0xb82063a3,0xaf5c7b86),LL(0xaa90bf00,0xbf4ed46e),L_(0x3a15f177), + LL(0x7f0b547c,0x49eb74f8),LL(0x146e10ea,0x95205278),LL(0x1256c788,0x346ea27d),L_(0x3f761b6a), LL(0x6a1a4872,0x4ec42ca7),LL(0x150f9515,0xec53ab18),LL(0xda268f4d,0xe31f64a6),L_(0xe4706b89), + LL(0x331bfc4e,0x0b4a9c48),LL(0xc8ae2f2d,0xa61d3700),LL(0x58cc7b40,0x3e9cb1a4),L_(0x31facd26), LL(0x10a69f57,0x3b34d496),LL(0xd018498f,0xb4f2bc1e),LL(0xcbad3ed9,0xa8867a65),L_(0x0fb7952a), + LL(0x060d829d,0xe832b583),LL(0xa4bc1e98,0x376e4266),LL(0x4ca3a485,0x2da2b54a),L_(0xbbcd02db), LL(0xce23e38a,0xd59bf323),LL(0x02c44a56,0x71d50f01),LL(0x366f36f1,0x0dbb411d),L_(0xf30d32a2), + LL(0x000bf15a,0x52b2e706),LL(0x19599554,0x83c05edb),LL(0xe133dbc2,0x659be3d5),L_(0x90ee1c4f), LL(0xe38dcd45,0x70cd081f),LL(0xba72fb3b,0xc7e5be8d),LL(0xff5688ad,0x3ae40925),L_(0xb751810a), + LL(0x7b159833,0x071a076f),LL(0x01bb4b01,0x67a90721),LL(0xd05cc7e4,0xc3b59e15),L_(0x14e1dc86), LL(0xbb61bd7a,0x1ee66adf),LL(0x743d3ae3,0xdf5f0047),LL(0x75487d37,0xb272a24e),L_(0x18ad2d25), + LL(0xecfd1c78,0x69935fe6),LL(0xefec1497,0x0149938a),LL(0xb3e61f40,0x1edeaf36),L_(0x2b4abccf), LL(0xe6be1d5b,0x6554f5f2),LL(0x0fe91c0b,0x443c9e6c),LL(0x613c238b,0xf8ba68b0),L_(0x0b0ae516), + LL(0xed42491a,0xbf0bc611),LL(0x9c608ede,0x7040894e),LL(0xc0f244de,0x0b0057eb),L_(0xd601464b), LL(0xf956aa49,0x825a361b),LL(0x4ff78a4b,0xb7556c66),LL(0x6aed48bf,0x1ae6fb3a),L_(0xba8a9318), + LL(0x87f39f99,0x09e379b4),LL(0x9e14e886,0x3fce44cd),LL(0x2fb4d3e3,0x75711ae3),L_(0x036fce90), LL(0x85e9ac2b,0x2542f70e),LL(0xa4a903d2,0x8303b7ee),LL(0x95852fe8,0x637b247b),L_(0x012141cc), + LL(0x2165af3e,0x9af74288),LL(0x41ab3d86,0x8945cab0),LL(0x29c26ab0,0xcccef77c),L_(0xea5535b0), LL(0x8648e931,0xc11f99b1),LL(0xb7f340c5,0x7dcfe320),LL(0xfc229594,0x8f5c0876),L_(0xf20b5874), + LL(0x48b7cd0a,0xba865a55),LL(0x6fae5df7,0xf611d6ed),LL(0x2fe39b65,0x8329316a),L_(0xc07b24cb), LL(0xdf303162,0xd09a26e9),LL(0x1af7d473,0xb6a75d27),LL(0x375af56e,0x62993ad0),L_(0x957236cb), + LL(0xd5155d78,0x3e2c48a3),LL(0x427f5e06,0x0f15720c),LL(0x25837ce2,0xcae65a88),L_(0x966e8b1e), LL(0x78a5dd4d,0x9e77f90a),LL(0x306bd895,0xd3918029),LL(0xd4ed09b8,0xa2585522),L_(0x47a8a9ab), + LL(0xd18d6ff6,0x1e6ed174),LL(0x8c957fe6,0xfb94845d),LL(0x54818bf4,0x2495a8a9),L_(0xdd977b92), LL(0x5993b230,0x05a5967d),LL(0x2647b9d2,0x3902c0f8),LL(0x53df8e0c,0x496697af),L_(0x5247a639), + LL(0x7b7c8590,0x8424e43f),LL(0x682c252e,0xf452918a),LL(0x0bb6bcff,0x17581f41),L_(0x040d50d1), LL(0x91b07886,0xd070dc3a),LL(0x686cbe64,0x9e8c81ee),LL(0x3485fd98,0xdfd534bf),L_(0xf0aec283), + LL(0xc3e77fdc,0x4458831d),LL(0xbfa63a77,0xdcd45b1b),LL(0xe6ad6640,0xeffc865e),L_(0xa2922966), LL(0xf55dbb61,0xae34f5fe),LL(0xec39a211,0xcad5ffd6),LL(0x5d5de65c,0x1ffcbe06),L_(0xae549602), + LL(0xc0237c46,0xf7d9eb1a),LL(0x008bf1c7,0x578b9779),LL(0xdce3e9ef,0x7341adb2),L_(0xe6aba225), LL(0xbfdcbb1f,0x52473c28),LL(0x58df1458,0xcea6114e),LL(0xcbca23e4,0x64a68f69),L_(0xdc93a2bf), + LL(0x2ad64bbf,0x12f4285d),LL(0x289cd434,0xe31b4490),LL(0x2614d391,0x5132c5c4),L_(0xd24f8d84), LL(0x0a9c7374,0xb496fb6f),LL(0x945d4d6b,0xaa619fb0),LL(0x64d58ea0,0x226ba20e),L_(0x78fadda9), + LL(0x328976b5,0x15c734ef),LL(0x71f5ab8b,0x49d5ba93),LL(0xd644b74d,0x8a5a08f7),L_(0x5b9eaf3f), LL(0xcd33e0a1,0x40783f59),LL(0xfc35396c,0x91276e7f),LL(0xdf4e44eb,0x698ace20),L_(0x85de5335), + LL(0xbe2724e6,0x4ca6d828),LL(0xc01805fa,0xab7f4b0a),LL(0x9b659d62,0xb0bfec7f),L_(0x21ba53df), LL(0xcb83946a,0x3ca3ffdb),LL(0xaaee16f0,0xe089ddef),LL(0x2829c022,0x8266c12f),L_(0x570a8b63), + LL(0x7f62cdfb,0x27c7435e),LL(0xc2862c3c,0x56a78e59),LL(0x577136cc,0xeb454a5e),L_(0x41bf3bc1), LL(0x76737cb9,0xd5ff2a5c),LL(0xce2b3472,0xa9a9af2c),LL(0xabfed878,0xdae3ae7c),L_(0x076254af), + LL(0x8125e260,0xfbee92e0),LL(0x288eeccf,0xeb8bf90b),LL(0x9cfb5c57,0x059c298f),L_(0x53598af7), LL(0xc5e99b56,0x888186ae),LL(0x3084705f,0x696f873d),LL(0x86f1d164,0xc59e084e),L_(0xa44fd074), + LL(0xeb77883e,0xd2343b34),LL(0xa40a6bf8,0xc2267f63),LL(0x798ceee2,0x27b865e6),L_(0xe4570eb1), LL(0x60596c23,0x8f87d684),LL(0xf0ce5967,0x06984779),LL(0x66b1f5c5,0xcbcc053f),L_(0x2f8869b5), + LL(0x7620dc06,0x0d7b69de),LL(0x17f0c4dc,0x9d39bfa6),LL(0xa20e8614,0xabbfb492),L_(0xc7dc6a2c), LL(0xe61a635a,0x2759d405),LL(0xcc56f093,0x966b6ab3),LL(0x049b5aa5,0x4e1f566b),L_(0xbec87c76), + LL(0x57acbf9f,0x40e840f5),LL(0x1f1c6ca8,0x0ffd84c8),LL(0x2d21e27b,0x9ca6123e),L_(0x1d5e2c46), LL(0xda38f612,0x5531352e),LL(0x009d49a6,0x3be34fe2),LL(0x43dffb38,0xd020075d),L_(0x2f8a3d38), + LL(0x89bc38a6,0x5ded0d34),LL(0xd70c960d,0x82054d24),LL(0x08b78436,0xbcbebb9e),L_(0x662ab949), LL(0xea6945f0,0x1d7a378c),LL(0xcd6abb3b,0x2b017a9f),LL(0x991364b4,0x4dbff4b2),L_(0x6e088465), + LL(0xca476359,0xf7fff479),LL(0x8b812163,0xe17baaee),LL(0xad939c3e,0xd700d28b),L_(0xe8837ac3), LL(0xbb3a964c,0x26712ef2),LL(0xd89edbf6,0xe0390b08),LL(0xeaa73bdc,0x536ef396),L_(0x19770554), + LL(0xb20e2aec,0x7f3d231f),LL(0xe904178b,0xa6924ffd),LL(0x7ff297bf,0xad6fdd69),L_(0x6deef5b5), LL(0x6c6f7f42,0xda650bfd),LL(0xc9fb4677,0x702cfe74),LL(0xd99a935f,0x93d1a532),L_(0xbfdd1320), + LL(0x49e4811b,0x0e07db7d),LL(0xfed77923,0x0dbb53c0),LL(0x0f05670c,0x112a7ade),L_(0x6e79da66), LL(0x3436a7c3,0x201e8aa2),LL(0x567d0dd8,0xd3bae1e2),LL(0x9a0b34dd,0x6a730912),L_(0x5c656713), + LL(0x8ee826b6,0x9522c2ac),LL(0x1cf99a2e,0x6bbbf4b2),LL(0xbfb9ae13,0x1fe851c4),L_(0x91215bb4), LL(0x8e9f0b90,0xbf89747c),LL(0x6286cdba,0x0e20c83e),LL(0x792aeb4f,0x25b00fa8),L_(0x61f48d5b), + LL(0x5762ff25,0xa1ce4a2b),LL(0xbe45da68,0xe3b7ba58),LL(0x63ee425c,0x98b17978),L_(0xd26e1784), LL(0x8832d22b,0x5fcc8cf0),LL(0xecb80c24,0x54bb743c),LL(0x3e21c95d,0x1df7f32b),L_(0xb9cc6c4a), + LL(0xc522b190,0x61766f4c),LL(0xa5778295,0x2fc3322e),LL(0x34307914,0x57f4defb),L_(0x71c105c8), LL(0xe02ecefc,0x2096768e),LL(0xce51bf21,0xad887721),LL(0x3117821e,0xf475048e),L_(0x2b073db2), + LL(0xa7c80b61,0x7067894f),LL(0x4426eaf6,0x99c9ba1c),LL(0xd1c53be2,0x68f854e3),L_(0xce0157db), LL(0x5b23fe91,0x5112a49d),LL(0xa0471f83,0x97b550cf),LL(0x87e0a2d1,0x9f64998d),L_(0x344b223b), + LL(0xb77380be,0x3ad984a7),LL(0x3bd4bc94,0x216f1748),LL(0xc17ca930,0x4aee7a72),L_(0xfcd30768), LL(0x02746210,0xa1f41f76),LL(0x6fdb5587,0x670f4013),LL(0x3c2763bb,0x0145b604),L_(0x6e18b2a2), +}, +/* digit=16 base_pwr=2^112 */ +{ + LL(0xca8e1890,0xa72d343b),LL(0x006aff79,0x07464235),LL(0x1ec739c9,0x136d5ba5),L_(0xce9ce64b), LL(0x721071fb,0xb11ea220),LL(0x7bfe943d,0xfb7789dc),LL(0x57dad905,0xac86bd3f),L_(0x5eeba8a6), + LL(0xac243d83,0xb0b49013),LL(0x31f50c04,0x6bbaa790),LL(0xd8fab554,0x1d543cec),L_(0x2fb0a285), LL(0x15602d83,0x3256cf69),LL(0xf3bd35dd,0x4a5d9d40),LL(0x8a264f24,0x7dff3a00),L_(0x24830923), + LL(0x4400cf66,0x3267fa61),LL(0x7dfb1e52,0xfe343741),LL(0x34e86055,0x552bcdda),L_(0x131f5b56), LL(0x6065029d,0x40256e8c),LL(0x61212776,0x6fac4167),LL(0x3807bd7c,0xbba74ace),L_(0xa2ce6ab3), + LL(0x954e93a7,0xfd51954f),LL(0xd0706483,0xbe73a498),LL(0x89215ea5,0x45e8a87b),L_(0xf3cf4080), LL(0xcdccb303,0x85c8552d),LL(0x09212e02,0xdb8ab951),LL(0x10c2badf,0x19c8db39),L_(0x7b08661c), + LL(0xdafc0f6f,0x9e15fa46),LL(0x148c6f0e,0x89a68d97),LL(0xdb00031e,0x4cc0f2bb),L_(0xc3df9d3a), LL(0x340e9460,0x1ff47bb7),LL(0x620b581f,0x7ef8908d),LL(0x57588030,0x4277ac9d),L_(0xfc122be2), + LL(0x5631310d,0x1336d2ba),LL(0xcd5bed69,0x039396d8),LL(0xedd85963,0xac1f77dc),L_(0xea62aa43), LL(0x40cf73fd,0xf970f801),LL(0x25fc53f3,0x7927be46),LL(0xf9d1654e,0x9f9753cc),L_(0xb61c3720), + LL(0x1f400c41,0x96dca6f7),LL(0x6461f973,0x29585547),LL(0x1f57a9e0,0xb90ca0df),L_(0xb010f7d3), LL(0xd1cf0605,0x21188094),LL(0xf21e0d4d,0xcfd8c7ab),LL(0x5f3468a5,0xde0d0f24),L_(0x4e99f334), + LL(0x0e472341,0x70d9012f),LL(0x7c2bf741,0x876213ff),LL(0x47c7e115,0xb309c07a),L_(0x977513df), LL(0x7682fd32,0xbe1ac3e8),LL(0xb7e947d5,0x1c6b708a),LL(0x09c3181e,0x41e0c220),L_(0x8b26dfc1), + LL(0x4c02bbfb,0xfa332320),LL(0xbb0f1fc0,0x1dd657b9),LL(0x68034aed,0x784ebda5),L_(0x58fb05ab), LL(0x0677d37f,0x32cca1fc),LL(0x83e2269c,0x2c9407c6),LL(0xea0312b9,0x33fa100f),L_(0x1761c87e), + LL(0x40a8cd2a,0xf4f00cb5),LL(0x58c8e52b,0x05e2b3e0),LL(0x99489e99,0x5593b9ee),L_(0x7924f02b), LL(0x464ae656,0x0334e2ed),LL(0x2a2bf206,0x55ec8d2c),LL(0x41ac277d,0xa7b08209),L_(0x0c5c176d), + LL(0x3ac595c7,0x1aabcb3f),LL(0x1450434d,0x93706f44),LL(0xcf82a49f,0x0e6c721c),L_(0xec192907), LL(0x92676891,0xfecc2ffd),LL(0x451e72f3,0xc8f49751),LL(0x81bf062a,0xe8852ddc),L_(0xf84db443), + LL(0xb1dfeb18,0x32a2e886),LL(0x8b6ac261,0x074b9898),LL(0x3c40d7a6,0x1ea4ca4c),L_(0xf7653f1d), LL(0x6940eab6,0x2b2347ff),LL(0x56338adb,0xca0ffd59),LL(0x314b0e58,0x8e442705),L_(0x79527139), + LL(0xbe4dbd9f,0xd63c1700),LL(0x1101a669,0x9b252cda),LL(0xd06390a9,0x501cc189),L_(0x0fb428cd), LL(0x8dcdeb0d,0x0a3108aa),LL(0x47aa9e0e,0x71a44ce5),LL(0x9c9d8b17,0xe86804cc),L_(0x61ad5482), + LL(0xfe987606,0x4432954f),LL(0xebe782ea,0x4d668855),LL(0x11e7dc71,0xf9379d6a),L_(0xfb5f9f2d), LL(0xebb7e729,0x98c8071e),LL(0x3aaef819,0x23ed5017),LL(0x3d2ba5a3,0x0cd97039),L_(0x2ceebe22), + LL(0xf7bd7afe,0x6646c443),LL(0xc3bd60cf,0x242cedce),LL(0x7c4048fa,0x5e74dbe8),L_(0xd29b1f65), LL(0xc5c513c7,0x91eb1130),LL(0xbb7b08f7,0x9edbdadd),LL(0x3c5f214f,0x6e37d0fb),L_(0x85ea7863), + LL(0x46abff2c,0x87af66ad),LL(0x26b2f70c,0x6dfaf224),LL(0x5494f6a8,0xf84408cd),L_(0xa24b6575), LL(0xb3e6fa13,0xfb2baa35),LL(0x7fdee2e4,0x48b82a51),LL(0x82709ae1,0xd231d3ab),L_(0x8897d9e8), + LL(0x9b54a957,0x43e3a795),LL(0xc93592ff,0x7df94193),LL(0x9aebe35d,0x3c64092f),L_(0x1d7432bf), LL(0xd212a26f,0x608467be),LL(0x61dd14ba,0x92d589f9),LL(0x1c6431e0,0xb4aaeed1),L_(0x53076cd4), + LL(0x20a03c9c,0x064ac09e),LL(0x3e9b39b0,0xe7dae697),LL(0xd8bc5839,0xc348b809),L_(0x8ab0974b), LL(0xcf8f0968,0xf886797d),LL(0x9cb572eb,0xeaa08b56),LL(0x9a9ce85b,0xa4a7eaf7),L_(0x0e1605e0), + LL(0x7cf927b4,0xbe868d7f),LL(0xeca36ddb,0xd5b365e4),LL(0x86bfcb64,0x9b8656b8),L_(0x2ab84426), LL(0x82271896,0x01fe86cb),LL(0x15f75f0e,0x672910dd),LL(0x4c2d70f5,0xf239468a),L_(0x365ce9d3), + LL(0xfbc74fe2,0xd342696f),LL(0xe0e930b3,0x1de7ca12),LL(0xcb67c28f,0x163565e8),L_(0x312a9e2c), LL(0x197ec1e3,0x54d76d68),LL(0x3b508871,0x11c4ebab),LL(0x71ee55a2,0x4dfa9969),L_(0x0a025c8a), + LL(0xe7055396,0xc327e039),LL(0xf0b0b5d0,0x5f514a6a),LL(0xb462d687,0xa70b2c73),L_(0x842f549f), LL(0x161da539,0x864e3870),LL(0x0b583d9c,0xde80546e),LL(0x1693a8f3,0x5135df56),L_(0xadecd5ac), + LL(0xc575df9d,0xe8f3d99a),LL(0x04c439d1,0xbba7ca9c),LL(0x79057450,0xed15dbf2),L_(0x557c06cf), LL(0x7e76a8b5,0x09b41a1e),LL(0x0bdc4dcf,0xf356b834),LL(0xf085eab4,0xdab0c931),L_(0xb48d6df1), + LL(0x2605d170,0x4a27c44b),LL(0x2e80ab05,0x5425f3dc),LL(0xdd9e1376,0x242b815a),L_(0xa910e496), LL(0x8b98999a,0x3f111c1c),LL(0x0c5343f8,0x29db22da),LL(0x10be67ce,0xf1c6ef62),L_(0x4ae541a2), + LL(0xbec6e451,0xc5669a27),LL(0xff0e3e5f,0xabcdf52c),LL(0xe911fae7,0x85cd9be2),L_(0x4150b30c), LL(0x9e505adc,0xab441ae6),LL(0x92888eaf,0x3ad89345),LL(0x0dd62a7e,0x1b7b37eb),L_(0xe9e642a8), + LL(0xc78817e4,0x15d73eae),LL(0x70f4b3ee,0x4965b1f3),LL(0x70ff29ef,0xe8787785),L_(0xe5dce106), LL(0x6012d2ef,0x36b7ab1a),LL(0x21a140c0,0x943b6ec7),LL(0xffda816f,0x9bd299e0),L_(0x5968ca97), + LL(0x6cb8a41d,0xb0d9d8cc),LL(0x6b2cc953,0xa58bcb0c),LL(0x932fd885,0x8fc62139),L_(0xb782380e), LL(0x5794203a,0x83692f14),LL(0xb2525747,0x8e1b841e),LL(0x2213b2d6,0xc34bb49f),L_(0x0270ba84), + LL(0x4fa6af14,0x3b925a7e),LL(0xe649f779,0x23113463),LL(0xa3785af0,0x20ce9dd7),L_(0xdc5dbf9f), LL(0x3c0ce37f,0xa5d677f4),LL(0xcdc8d1f8,0x793a5749),LL(0xd8d3e9cd,0xb698eb06),L_(0x5cbd0981), + LL(0xfe510f94,0x1e752015),LL(0xf090a1eb,0x65fa8e80),LL(0xfc5f6857,0x111a1741),L_(0xbaf89d9f), LL(0x4cc335c5,0x1b1a1910),LL(0xbfa9551b,0x24829f96),LL(0x24a70dba,0xc5ef4f06),L_(0x17130b26), + LL(0x1febf14a,0xfcb5b042),LL(0x911935f4,0x2a9fcf44),LL(0x53ed6fc0,0x90634826),L_(0x4421e383), LL(0x98983bff,0xc4143e7a),LL(0x12ccf145,0xfc4163c9),LL(0x5bf8b6c9,0x4f765081),L_(0x73883a6d), + LL(0xef044be0,0x997c821a),LL(0xe367cf8a,0x3560d6df),LL(0x3d0455b7,0xe8c7bcd6),L_(0x92643ab4), LL(0x26239fb1,0x547dbeb1),LL(0xb5294491,0x2538d97d),LL(0x07450e45,0x472a47f1),L_(0x5e3d3784), + LL(0x23d0e3a3,0x6372566a),LL(0x4d62de9c,0x9858907c),LL(0x7a323978,0x78458eba),L_(0x4b2a04ff), LL(0xae2094af,0x6819a84c),LL(0x0eccbf7e,0xe0c337be),LL(0xb93eec58,0x2a02a086),L_(0x03b76658), + LL(0xbfc94c0f,0x6aa0f607),LL(0x0cbee27c,0x4123775a),LL(0xae1d1601,0xbbef8dbb),L_(0xe7149786), LL(0xf56932af,0xbe686d03),LL(0x91ce3c48,0x3e33d4ba),LL(0x3d6535b6,0xa72c8f85),L_(0x2c9fb75e), + LL(0x4a47050e,0x39dd7c74),LL(0xeebc8c18,0x2f4a6be4),LL(0xa2f0fb3a,0xba0f68a4),L_(0x1c5cad2c), LL(0x85d6ef4d,0x3f59abfa),LL(0x3a302769,0x47cf5f7e),LL(0xed44c056,0xcd7fd1b9),L_(0x2e974b80), + LL(0x691eccfe,0xc8f85c87),LL(0xf503e456,0x34a4ce86),LL(0xb53e74a3,0x8eb76194),L_(0xc4c55423), LL(0x22da99fd,0x153fefba),LL(0xdbbf4e12,0x5438e1b0),LL(0x80b3f694,0x65187422),L_(0x9f8c212c), + LL(0xab8f55ff,0x0fcf5a38),LL(0x6da81ce6,0x0b057c12),LL(0xdff4777f,0x4a9fa32b),L_(0x602640c6), LL(0x2624de9e,0xa3b241c6),LL(0x2a545f4f,0x0dd2feaa),LL(0x4cf94266,0x8a894ff1),L_(0xb5260296), + LL(0x2194d8b6,0x7320211c),LL(0x391c4f62,0xd2de2551),LL(0x6d039386,0xbaa68de6),L_(0xc3a5b977), LL(0xf3b1162b,0xbca0bb5c),LL(0x3643a502,0xd1a3ad93),LL(0xe1f5b66b,0xa430cadc),L_(0xb32e7ba4), + LL(0x4c8d2ee8,0xd36efcf0),LL(0xb6b2c682,0xc22137cd),LL(0x1024c516,0x8688f303),L_(0x99e728ff), LL(0x3fb84765,0x777d2fde),LL(0xd972734f,0x9a00c6af),LL(0x25251454,0xf34097fd),L_(0x424404cf), + LL(0xdfdcead3,0x3079239d),LL(0xb5ff46f3,0x80c77858),LL(0x36a3735f,0xc9986723),L_(0xd572091f), LL(0x6645ed98,0x0dabffd5),LL(0x0da45042,0x4b0c6093),LL(0xf6ffaf50,0xbffef0a3),L_(0xbc330b9d), + LL(0x7d149925,0x3b961737),LL(0x8d236f27,0xc18d27e0),LL(0xa5f014ae,0xee0ae6b2),L_(0xe50d6b9c), LL(0xc1b92639,0x2b5f008e),LL(0x36e3aea7,0x8996a3a6),LL(0x2f8e4e4e,0x5ccc02df),L_(0x9f683f7c), + LL(0x3a45a099,0x7caa8790),LL(0x6c2cdda1,0xf82f4e65),LL(0xa9cdf2c5,0xb634f00e),L_(0xd5eec010), LL(0x4012fecf,0xa6a18c31),LL(0xde736bf0,0x153b6c27),LL(0xc1059186,0xb7a29e2b),L_(0x9b23923d), + LL(0xc90ac0c7,0x7000c5a2),LL(0xb80400e7,0x2f6fc4cf),LL(0x147ccc10,0x9e3b070e),L_(0xfef094f1), LL(0x0ab36cd7,0xefcc38e0),LL(0xf5b77a62,0xa70d4a46),LL(0x2c523e42,0x02efb3f7),L_(0x210639da), + LL(0xda4106f5,0x330449c9),LL(0x7b06f635,0x30d85516),LL(0x9efabcec,0xe879f10c),L_(0x3bd206ba), LL(0x75c081fb,0x0312bdf3),LL(0x88e64b25,0xb372be76),LL(0x3a8f90eb,0x3e832f84),L_(0x14f38ac0), + LL(0xc7331aa0,0x4bafc9dc),LL(0xb6461cb6,0xae9ec59c),LL(0x266ba391,0xf40aa6ef),L_(0x4715355a), LL(0x33ae64ed,0x1adab377),LL(0x716f224c,0x04c2b6cd),LL(0x32b71c3a,0x7e89026d),L_(0xccbd7f4e), + LL(0x095925d5,0x7de43130),LL(0x0bbfe1df,0xa8605297),LL(0x10701822,0x0bc2e01c),L_(0xf68b86eb), LL(0x816f32a8,0xad3f4af4),LL(0x67e192cc,0xe9dc6c49),LL(0xd5fef609,0x52b649b2),L_(0xf428af30), + LL(0x9f45ede9,0xe78176a5),LL(0x0b536242,0x0ba30aad),LL(0xdbdd8b20,0x503b274a),L_(0x51151bfa), LL(0x4d7ac01b,0x393d4fa5),LL(0xdc4e6926,0x8e9d7c61),LL(0xe68387c4,0xaaf0a35e),L_(0x06168aa4), + LL(0x35b79ca0,0x2143ebc0),LL(0x4be98451,0x85664008),LL(0x1016322a,0x5db7c140),L_(0x8229e729), LL(0x4e10aefd,0xc19bdf57),LL(0xc8df52e4,0x07fc2589),LL(0x89b605d1,0x2a200cdd),L_(0x0c94090c), + LL(0x02211b9e,0x4588f75f),LL(0x0c217b21,0x90c9218a),LL(0x90f7c009,0xef37649d),L_(0xddfaf799), LL(0x35885f85,0x3d0294b0),LL(0x510fffdd,0xe646d7e9),LL(0x4a21ba9d,0x6c9d2cfa),L_(0xa7ada78e), + LL(0xcf1bb365,0x1db377d9),LL(0x63e01d3e,0x8b74ddb8),LL(0x8c9ad4b9,0x6bb31b8b),L_(0x2b26fec2), LL(0x858449ed,0xfeaf9d41),LL(0xe2652b65,0x700223fb),LL(0x03b48402,0xee2505a9),L_(0x2438e370), + LL(0x9e8ea415,0x900098e5),LL(0xd8a6e8e7,0xe478cc9a),LL(0xd8452a93,0x2e2cd25b),L_(0x569bbc5f), LL(0x5d22bbf4,0x80e8caa9),LL(0x3f76b251,0x10dc6eaf),LL(0xeba89ffb,0x18acb601),L_(0xf763dfc0), + LL(0xfed0a316,0x24370f95),LL(0xf5f4a36c,0xc06ba373),LL(0x527f5322,0x43417948),L_(0xe0b12bf9), LL(0xa7bf2afb,0x6aa04127),LL(0xb3183162,0x87eaa68e),LL(0x1070f9c1,0xe002ccee),L_(0x5b0c2b4a), + LL(0xc7a653c7,0xfca649b9),LL(0xb223ef3b,0xf66cb526),LL(0x4aa0b0e6,0x10592f0a),L_(0x3d9b366f), LL(0x61473660,0xab61a041),LL(0xaa721fec,0x1b173f43),LL(0x0a96a721,0x06be6fd2),L_(0xb3b3cccc), + LL(0x87a37531,0xfda2de36),LL(0xd8576cc3,0x94a1bbc9),LL(0x22b5be7f,0xaad70136),L_(0xc40c9235), LL(0xfb07dd6f,0x9edbb744),LL(0x501faa81,0xccf5dbd3),LL(0x60c831a6,0x6f69ca6e),L_(0x813a83b7), + LL(0xa96bdf09,0xdbe3e245),LL(0x4f871623,0xacfa6c70),LL(0xd2c645ee,0x18c48541),L_(0xc037f50e), LL(0xcb36c731,0x08342ef7),LL(0x68cc0cb0,0x4e89abf4),LL(0x0c4fa826,0x186c66ac),L_(0x8f28f4b4), + LL(0x2d46a77a,0x837493ce),LL(0xf41079e1,0x15f6dc1a),LL(0x1a861704,0x0e538567),L_(0x03e474ae), LL(0xa4564b51,0xa188c7ea),LL(0x76610ad6,0x3c36716c),LL(0x706eb273,0x8025f126),L_(0xb5435d24), + LL(0x28638fa1,0xc4faeda2),LL(0xd9ddd6dd,0xcb83b696),LL(0xe2be7ac0,0x4eea6f06),L_(0x2e6abaae), LL(0xaad7f53d,0x99f8dc45),LL(0xc8502a73,0x8477e1b0),LL(0xa0aa0199,0xcbc5ed2a),L_(0x38689f49), + LL(0xd7981750,0xfbd4773e),LL(0xb3548b14,0x01d933bf),LL(0x18cea1f5,0xb3c65f79),L_(0x3bc435fc), LL(0x3414a439,0x0706d138),LL(0xca5b9f90,0xb2166606),LL(0x14b87e77,0x864343f5),L_(0x8a82e1fd), + LL(0xa2f61a19,0x18cc1c82),LL(0x0026972b,0x0e88aaf9),LL(0x1da022c6,0x2265f4c6),L_(0xb898d6b7), LL(0xc0e9ecae,0xa53eabdc),LL(0xef23c0bd,0xd1e853a6),LL(0x98e844f5,0x05f9b046),L_(0x7d2e87fd), + LL(0xf9a4fe94,0xe7c2033d),LL(0x1c9b4b3f,0x3037306e),LL(0xf61d0ee2,0xdb5834bf),L_(0x28b5943b), LL(0x4c22b3ea,0x5de6ece6),LL(0xf70c350f,0xa4e1deaa),LL(0x1c3bfb3c,0xd4c8be79),L_(0xe75564bc), + LL(0x16c64cef,0xab2cc7d7),LL(0xa4b41a9f,0xa5534f63),LL(0x912b7248,0xe6362cfb),L_(0x6a214d2e), LL(0x9c7005e2,0xc25479e5),LL(0xf1652743,0x6a7f2578),LL(0x3bcb10e6,0x9be1e8e0),L_(0xbede8ea6), + LL(0x459cf3fc,0x31630308),LL(0x706d16a7,0xf60bf227),LL(0x9f2f55c9,0xed0db8c6),L_(0xaf0d2787), LL(0x6dd2c868,0xb9e7f043),LL(0xce8001ee,0xa2ee914c),LL(0xb8247bef,0x658e5458),L_(0x78f60572), + LL(0x6bc3d716,0x5c6843cd),LL(0xacaada1c,0x1bd0e72e),LL(0xcabaa3a2,0x36370b66),L_(0x507a17a3), LL(0xebae3c4d,0x481b026d),LL(0x48821bb8,0x4cd76456),LL(0x5ed8e5b9,0x78f46113),L_(0x6817009d), + LL(0x029887e4,0x7560c538),LL(0x75119a00,0x92989cd8),LL(0xe00d03bb,0xef71ab39),L_(0xb863df63), LL(0x5f6dd06c,0xfedea07c),LL(0xddc4f0d5,0xd3b8a96e),LL(0xc43e8f08,0x36d08634),L_(0x9efb1f02), + LL(0x3215c001,0xba05b2e5),LL(0x949d9990,0xa3503f0e),LL(0x76e4e629,0x6c281fa8),L_(0xdccad172), LL(0xbcf0bc10,0x6b13eba6),LL(0x70f4d75c,0x1b941283),LL(0xd34756fd,0x70986d34),L_(0x8f71b0bd), + LL(0x2576d875,0xe10a7afc),LL(0x0a9b3e69,0x411dab1f),LL(0xf0719c41,0x046cc610),L_(0x9d1611b2), LL(0x1ba334cc,0x6b7a1ff0),LL(0x24d9cfba,0x47e8a2e5),LL(0x5bd30854,0xa740e80a),L_(0x1159e67f), +}, +/* digit=17 base_pwr=2^119 */ +{ + LL(0x7c2ca549,0x5898fc38),LL(0xa3566efe,0xa757b52e),LL(0x24bb02bf,0x91ab4316),L_(0x00e46ee0), LL(0x9ec42857,0x8c02881c),LL(0x1d20ad25,0xb9a28540),LL(0xb01ce79f,0x40d6ae86),L_(0x40b2c06e), + LL(0x4fd7f402,0x259779c5),LL(0xafc1d993,0x3aa4fd10),LL(0x86dcdc83,0x77170d32),L_(0x8441f4f3), LL(0x9892b126,0x46144a81),LL(0x58df739b,0xc6549963),LL(0x344ddb0c,0x01761502),L_(0xd9bcbeb6), + LL(0xaf8e61b1,0x66de5a2d),LL(0xbc92b6dd,0xcb8a0bac),LL(0x1127f258,0x3d18ed03),L_(0x3982ee92), LL(0x8ca9b244,0x0deb6e5b),LL(0xcf198f32,0x7cefc1f3),LL(0xdbaf1a5d,0x373c1801),L_(0xf524b8bb), + LL(0x746fcfe2,0x1bb01e23),LL(0xdc5e2b63,0x38352329),LL(0x5df11c5b,0x68e597b5),L_(0x44ec319c), LL(0x84b36d32,0x0e27f5b0),LL(0xe5706d53,0x06c3753d),LL(0xe67b3281,0xa7111b5d),L_(0x8fa5ee02), + LL(0x5141455b,0xe429fedc),LL(0x0035c84e,0x353b3d90),LL(0x2ea6f135,0xa3e74746),L_(0xb9e352c0), LL(0xa8f82237,0x220bb555),LL(0xb02520ea,0xecc581df),LL(0xe4b94f8e,0x16dbb87f),L_(0xfbff49d6), + LL(0xc2eb5b9f,0xda91cf48),LL(0xdb33cda7,0x821b171b),LL(0x006b3e24,0x489cbfa3),L_(0x4461fe49), LL(0xc4e7389d,0x4d93f4e1),LL(0xfe8e5310,0xf28f63e5),LL(0xf3d0d29d,0x94deaf7c),L_(0x3d33e2ad), + LL(0x1e948480,0x453d6838),LL(0x8f1b71e2,0xd842ed96),LL(0x92302500,0xf76bc681),L_(0x17e6ad54), LL(0x5d04302d,0x66dcecf9),LL(0xe97810bb,0x37c278e5),LL(0x13de9f06,0x30c9e7f2),L_(0xf16b622f), + LL(0xe415829a,0x436d6b94),LL(0x794d49e6,0x541c7bda),LL(0x702ede17,0x5afaacb1),L_(0x3b5ca68c), LL(0xc9496ea8,0x9ca7b73f),LL(0x50a1e66e,0xc5ce627a),LL(0x762e4f6f,0xc90185b1),L_(0x6705418b), + LL(0x52188496,0x52070a5e),LL(0x9065afef,0x510e288b),LL(0xe6df0c7e,0x441709b3),L_(0xa1396423), LL(0xa8018a37,0x66868b26),LL(0x14f84f84,0x28ce78c1),LL(0x1fa90793,0x19c083f9),L_(0xfd8d88ee), + LL(0x2458c92b,0x5330a979),LL(0x77ea9ee9,0xdba786fa),LL(0xce00962f,0xae5f476a),L_(0x05915824), LL(0x1219b9cd,0x8cdf0300),LL(0x660a19e4,0xdc707120),LL(0xc70e0b11,0xfdd0563d),L_(0x41d445a6), + LL(0x6102cfd1,0x53d54a0a),LL(0xa5729cf8,0x4fc590fa),LL(0xea907455,0xea0c5a91),L_(0x59a871ce), LL(0xb4020096,0xe025ffb0),LL(0x7e7fb9d6,0x140025ac),LL(0xb7954f0e,0x46ca7ee6),L_(0x010dbf77), + LL(0x6a28fa6b,0x2d7e46eb),LL(0x034b69ed,0x1ae23996),LL(0x51bc6b67,0x3c25755a),L_(0xe9bf6717), LL(0x579d75fc,0x06b03b1f),LL(0xfc3e6ce3,0xe0b2026f),LL(0x723756d9,0x58938357),L_(0xb4731ae9), + LL(0x5cbab1e2,0x42ddfb70),LL(0x33bbd9fd,0x6d346512),LL(0xeb7aa22f,0x725fdf2d),L_(0x88eb52e0), LL(0x48e63519,0xf1fc169f),LL(0x297a7972,0x91aa8dc7),LL(0xb92c9671,0x9c2b4849),L_(0xa557aadd), + LL(0x4fe2181c,0x58182a19),LL(0x27b6bd7a,0x0c4b58a3),LL(0x1c72e55a,0xd4f2f098),L_(0x6b53e542), LL(0x0bdee531,0xb5e11022),LL(0xa8f7b191,0xa8bb8315),LL(0xe62460d4,0xbdf84150),L_(0x74ea071f), + LL(0x1ca83a09,0xe03c9ae4),LL(0x54fef132,0x7e2ef688),LL(0xa900e0bd,0x1a602274),L_(0x3698f6bb), LL(0xc6654794,0x57e365a9),LL(0xbb500025,0x2b39b18b),LL(0xf16e71f6,0xa0dfe4bb),L_(0x9d6899d1), + LL(0x1d2f288c,0x8e577078),LL(0x8e833532,0x8ebb1ef6),LL(0xfb9fbcd0,0xf5ead3c9),L_(0xe31f0c20), LL(0xf16fa294,0xc462ce8b),LL(0x6466c045,0xc1068645),LL(0x85e7447b,0x3e1abc03),L_(0xbba798a0), + LL(0x41e55979,0x122d19ea),LL(0x158f4312,0xfd5b3495),LL(0x297c5747,0xa7b750fd),L_(0x735aa3f7), LL(0xd2156123,0x312d6128),LL(0x31e8bfa3,0x4456ccf3),LL(0xcc9cdadc,0x5094cff5),L_(0x9ea9beca), + LL(0x1ea96169,0x616ee979),LL(0x78257a1a,0x60b3f06d),LL(0xec98f98d,0x609d2d2d),L_(0xd1b3e514), LL(0x1100f9ce,0x2e59e232),LL(0x8087f780,0x34e1a9a4),LL(0x0b40b853,0x95c2865d),L_(0x8fa97627), + LL(0x297f6423,0x1eac58fa),LL(0x7eb748d9,0x6fa36840),LL(0x0d0b673e,0x955ae146),L_(0x72be4e8e), LL(0xb20412e2,0x22b08d06),LL(0xa4616bf8,0x57a2dcba),LL(0xc55b68a6,0x42138fbd),L_(0x8fa529ef), + LL(0xdb26dfa2,0xf1766b07),LL(0xdfd72d39,0x050e85e5),LL(0xad6b741f,0x59466485),L_(0x5fceaf74), LL(0xbc9edaeb,0x0c6b2254),LL(0x453c9eae,0xfca1477c),LL(0x9c00d050,0xa3817166),L_(0xa87cf553), + LL(0xdbbc12a2,0xad146ff5),LL(0x39990110,0x33dcec4a),LL(0x3d48a808,0xfe9fea01),L_(0x8c4aac12), LL(0x2cefb34a,0x0ad5c79b),LL(0x0a9a20f7,0xaca81076),LL(0x942b38be,0x9475c474),L_(0x218031b5), + LL(0xc173f9cf,0x4c0dcf94),LL(0xcc4c491e,0x61d12afb),LL(0xfa790f55,0x12a6c289),L_(0x37abf7be), LL(0xd04d2ae3,0xcb586fd2),LL(0x192166df,0x3c04c5b4),LL(0x7ee1f233,0xbba9c768),L_(0xb69b46cc), + LL(0x7c1e6077,0x1443ddcc),LL(0x6345a210,0x70d81228),LL(0x5f035127,0xc8273e38),L_(0xdafd6230), LL(0xcf227ac1,0x4e794379),LL(0xb3e2d215,0x916e6825),LL(0x138aca38,0x4afb3539),L_(0x4ce64d55), + LL(0x463d181b,0x6b581764),LL(0xc440084f,0xa9bac44f),LL(0x088767cd,0xf0d004bb),L_(0x94e1ba30), LL(0x55abae1e,0xa1a18412),LL(0xa732c539,0x6d71f955),LL(0x896710ea,0x3608f75d),L_(0xa067bb07), + LL(0xbc080af4,0x9891098f),LL(0x65c3a1bc,0x00befda2),LL(0x3321e866,0xb04ac43d),L_(0x438e5b9d), LL(0x5fd8c4d4,0xe260d024),LL(0xc4dcba5f,0x19886f71),LL(0x5e5f5f4c,0x37b1a0c5),L_(0xd3c102f6), + LL(0x58ee2dea,0x4e2d8d4c),LL(0xe6546299,0x8042631e),LL(0x262d0cb2,0x2df96d37),L_(0x349292cc), LL(0x04a3c0d5,0x2fddedd3),LL(0x452a0a52,0xd5418050),LL(0x2293a069,0xc6053861),L_(0xfe3040eb), + LL(0x3a50a7c9,0x02a166d5),LL(0x861af22b,0x8a435126),LL(0x449c202c,0xb053bb62),L_(0xbb664aff), LL(0x9083b8c2,0xd6f78a70),LL(0x14a57ed2,0x8e5943f4),LL(0x6c5eedb1,0x591d0e00),L_(0x0f079d9e), + LL(0x2036fb32,0x4ee2bac6),LL(0xc62978b5,0xce8c9892),LL(0x0ee684b9,0x56d30723),L_(0xb8993d5e), LL(0x2fee5c92,0xfc172755),LL(0xc8622a7c,0x43c48f91),LL(0x4279a0bd,0x78cfee0e),L_(0x3826553c), + LL(0x4315c335,0x9060272c),LL(0xe29ecb65,0x5d0bbf12),LL(0xdd976fea,0x53d3e99f),L_(0x278ebed1), LL(0x7fc69ec0,0x7a33fe7e),LL(0x13d33afb,0x9b8a7301),LL(0x19d16dca,0xe09a47ad),L_(0x6e0ed440), + LL(0xd0327c5a,0xb55799e4),LL(0xf145e8f9,0x7408bf29),LL(0x97e6d3d7,0x4580043d),L_(0x5f599a51), LL(0x517f2eda,0x38414d94),LL(0xe09d35b1,0x37f611a1),LL(0x31551461,0xce073290),L_(0x1044bab9), + LL(0x24eb973b,0x045e586d),LL(0x4d8f2d61,0xa3318071),LL(0x1d2b5b32,0xb68b7f81),L_(0x10bccde6), LL(0xcd3e0e0e,0x0578898c),LL(0x1e460079,0x927cc37b),LL(0x31bad31c,0x3d22477a),L_(0x8c371b62), + LL(0xa374b8d9,0xbc19767b),LL(0x3ed7db29,0xa97161c1),LL(0xcc843c60,0x45c30a38),L_(0x508e3e86), LL(0x433b6dbe,0x1457fcb6),LL(0xd8c78825,0xed4ed464),LL(0xc3997703,0x2b88e6d2),L_(0xa1f2140c), + LL(0x953f63bf,0x2a452961),LL(0x62444dca,0x6a62e296),LL(0x2d1e976e,0x1d95f51c),L_(0x2bbeb1e0), LL(0x62f53f4b,0x052daa65),LL(0x827170a2,0x5cb51b06),LL(0xc319b1bb,0x3a8ec55d),L_(0xda0c72a5), + LL(0x71e73523,0x898419da),LL(0x35d9c257,0x49a774fb),LL(0x55758231,0x4e49ddae),L_(0xd5c3703e), LL(0x4d4edb63,0x28d3f23e),LL(0xa38dc679,0x41807b47),LL(0x749ea0b8,0x15724faa),L_(0x68bb7f4b), + LL(0x5af98b88,0x0f227def),LL(0x24af0afb,0x27396d04),LL(0x1cd97cef,0xa2ad5165),L_(0x678f117f), LL(0xce22032e,0x03432db3),LL(0x5cb93ad2,0x92eb23b1),LL(0xcc96e20a,0x47d3d48c),L_(0x5f1e84c2), + LL(0x163136e0,0xc4293aee),LL(0x7f0db6e5,0xca0a189e),LL(0x9069c8c2,0xa088318f),L_(0xf4210d55), LL(0xb0d80206,0x13bd2b27),LL(0x34f3150f,0xcd0efd69),LL(0xe152eb4e,0x0fcf1527),L_(0x32e6885b), + LL(0xcb923f09,0xed8906b9),LL(0x7eba0ca2,0x95cab4ce),LL(0xc91dbf27,0xcf44aa02),L_(0xf0948c8c), LL(0x1a9b31dd,0xbe7b7487),LL(0x88539394,0xc84b72c8),LL(0x938fd6cd,0x15b31f6a),L_(0x1a1c6b6b), + LL(0xce67988c,0xc2869ed0),LL(0x61ab3c9f,0x882c2379),LL(0x3bb8c353,0xb69781cd),L_(0x95d9d719), LL(0xedcef064,0x3de229ea),LL(0xc3895533,0x84ff6e10),LL(0xb6955022,0x5ac0d29e),L_(0x6e2ba9f7), + LL(0x3cc87419,0xfe2a24c3),LL(0xe3406a2f,0x3d474db8),LL(0x67beb236,0xf6867bb0),L_(0x5b2cd123), LL(0x74e31d6b,0x2ff473bf),LL(0xed6d88b5,0xeadd2ad4),LL(0x046a1f51,0x9b3025d4),L_(0xf4a61d8b), + LL(0x40eaccf0,0x99e19903),LL(0x7e9f5e57,0x1b67fa53),LL(0x00b84a60,0xbabc0faa),L_(0x6de1d67d), LL(0x06fe7a95,0x04041366),LL(0x06672f11,0x5f522ae3),LL(0x0dd51cb4,0xd4012aa6),L_(0xd5ce357e), + LL(0xfbc38722,0x538e45da),LL(0x5f595162,0xf57a7cab),LL(0xe917805d,0x56a8bf52),L_(0xf639993d), LL(0x31ba0865,0xe876b4e9),LL(0x3eaf3c58,0xb08987af),LL(0x0ef4538a,0xbd9e742b),L_(0x95404cfd), + LL(0x9eb63b57,0x1453ad21),LL(0xf6e400ed,0x627008e7),LL(0xa4ababfc,0xd78f1c8d),L_(0x4ebc5852), LL(0xcc21b23c,0x4e1ef090),LL(0x7415270e,0xb8b3701a),LL(0x921cd6ee,0x472b1f2f),L_(0x765126f0), + LL(0x59e9fe85,0xade7ead3),LL(0x1b413797,0xb8da2677),LL(0xeabbca1c,0xdb705e2f),L_(0xa1e12595), LL(0x65e95e7d,0xd1990099),LL(0x79fa6f2e,0x2b7f7bbd),LL(0x4d4d9e0a,0xbde588b7),L_(0xc0ac97e6), + LL(0x20ff9acf,0x23cf39f7),LL(0xca0fac28,0x1f72fbb4),LL(0x4b179b83,0xb04c01ae),L_(0xfaca0fdf), LL(0x7173749c,0x7b3cc769),LL(0x3d2bf7fd,0x0cbf34b6),LL(0xf3f2fea4,0x6369c1d9),L_(0x866e7f8e), + LL(0xb873e85f,0x6eb23ad8),LL(0x8b9475ca,0x2855072f),LL(0x22d9fd01,0x4e9a3adc),L_(0x813270cc), LL(0xfbf27bf5,0x292b8bdc),LL(0x3db7f857,0xe9f00375),LL(0xf6ba5b62,0x1b8a570a),L_(0xe20966e7), + LL(0x05a5a71b,0x19b8e7ac),LL(0xe13277a1,0x9a4abf1f),LL(0x6d26fe41,0x8f8b7d68),L_(0x0ce42976), LL(0xaa0c781d,0x48e32e14),LL(0x0ee98d37,0x13c9b527),LL(0x3bb6c2c9,0x4db74aeb),L_(0x208cd0d9), + LL(0xc2685698,0x47ef78f2),LL(0x6c1b0959,0x9bb6bd13),LL(0x2ccd97f7,0xa303c278),L_(0xf9abf5b1), LL(0xafdb9d40,0x0276fd8a),LL(0x2be1d396,0xdb26cd04),LL(0x726beb4a,0xe09517f7),L_(0x4e0b499e), + LL(0x6f715206,0x5979197a),LL(0x82ffa270,0xb44c8267),LL(0x52cb678a,0x260e7e25),L_(0xc541f700), LL(0x18439449,0x33983071),LL(0xb1d2f59c,0x19d945b4),LL(0x11eef46b,0xf2b04fe3),L_(0x9fba737f), + LL(0x214431d6,0xbcadb425),LL(0x4d1d9a21,0x941b766d),LL(0xe2a1f314,0x2170c6a6),L_(0xc15b9466), LL(0x6c1b9a4b,0xd605b2bc),LL(0x1578a3c5,0x65c9904b),LL(0x96b6befc,0xbe0b58ef),L_(0xc4f7e33c), + LL(0x5a93994e,0x3fcf43e1),LL(0xb19e11a6,0xf5f793fc),LL(0x5ad2ed77,0x6ff2a142),L_(0xe587c79f), LL(0x23c53b77,0xb2ee2d92),LL(0xa6fa95d1,0x023b2c75),LL(0xac5ec115,0x67b40c94),L_(0x41c55249), + LL(0x05d09dcb,0x6b551c3c),LL(0xc6c2dc20,0x2e81c56f),LL(0x1b5233cb,0x0e6faafe),L_(0x4565862d), LL(0x43368b7b,0x08edb0b1),LL(0xb2d31417,0x29c77be9),LL(0xa0fa599c,0x77052491),L_(0xb2ac3ec1), + LL(0x3a2c0bb0,0x0302d5f3),LL(0x04cf0b83,0xfda301ea),LL(0xbd701c39,0xfb565431),L_(0x5eee993f), LL(0x2230bcaa,0xb5c3681a),LL(0x5d285d50,0xa9dd4df3),LL(0x8618542b,0x8c1d7c52),L_(0xd80996cc), + LL(0x85ebe7cd,0xf0fe462f),LL(0x12c3c8ab,0x752eb1b0),LL(0xb6349271,0x2f148e5a),L_(0xc0513e4e), LL(0xdaa709f7,0xd043e9e0),LL(0x340f7e04,0x7842c3a1),LL(0xb4acedf4,0x5d6d0c14),L_(0xfa56de6f), + LL(0x807fa877,0x435b6be9),LL(0xdb7a9959,0x65c2c690),LL(0x24fae090,0x3cd0982b),L_(0xcc274d62), LL(0x721b08d7,0x02f3dea6),LL(0x2a9bf937,0x052c0001),LL(0xadae4c04,0x61de7f6d),L_(0xba3c48a3), + LL(0xdfe50f8c,0x2faaf032),LL(0x7e8bb31a,0x51dbadf4),LL(0xd937aa83,0x072c01c9),L_(0xbfe57ab1), LL(0x5d66c435,0x87c5d208),LL(0x4ce95747,0xfb211069),LL(0x7ee66e9b,0xf01cc54c),L_(0x48478c99), + LL(0xb35f128c,0x957c7ee6),LL(0x50dc83b5,0xf963430c),LL(0xf0f63a80,0xb4578760),L_(0x842ee70e), LL(0x57d57cbd,0xc891093b),LL(0x24bc2867,0xa548c5ff),LL(0x0f85fa2f,0x47bb6a4a),L_(0x18cd7a2e), + LL(0x813aaaa5,0x40773919),LL(0x798cdd8c,0xb6d9db4e),LL(0x68858372,0xd2c5ede9),L_(0xb240c94c), LL(0x79a51f60,0x62fa25b7),LL(0x89e94f52,0xac054f6f),LL(0x0332347b,0xf207ad5e),L_(0x9e15c0d4), + LL(0x19041ef2,0x6d748e07),LL(0x298a62fb,0x3b9bdf40),LL(0x8f7fb37f,0x35f944a9),L_(0x92926ab1), LL(0x51a4355a,0xdc488cfe),LL(0x3f355ad1,0x814db3fc),LL(0x84b0d885,0x29d8cb57),L_(0x98d39682), + LL(0xfe4b50e2,0x07c8c799),LL(0x4957a527,0x3418ab11),LL(0xec94fd37,0x601424db),L_(0xf147c20f), LL(0x420c1861,0x1adc80ee),LL(0x7d9440bd,0x09ee96a9),LL(0xee7355ab,0xd1adde68),L_(0xba4d5d2f), + LL(0x14379251,0x4dc18b12),LL(0xebadf0ef,0xfee19a43),LL(0xbc8d4cc9,0x8da37771),L_(0xd555d58a), LL(0xd71b4107,0x42fdc281),LL(0x2e05719e,0xac68f304),LL(0xdc3ed2bf,0x4c1b070d),L_(0x03356492), + LL(0x0c94988c,0x8da99bff),LL(0xa1e580f6,0xe79a8b42),LL(0xcf6d6c6e,0xfdabb4f2),L_(0x80f7da41), LL(0x1a4121f1,0x6a7dfe84),LL(0x36467882,0x6b06eea9),LL(0x30e07e6a,0x943abc5d),L_(0x8ae444d2), + LL(0x2f87568d,0x2441fb99),LL(0x0599179e,0xe8a9e90a),LL(0x54669582,0x47767b19),L_(0x6fa66e89), LL(0x19290f64,0x4596bd1b),LL(0x93f0e068,0x9dab54b3),LL(0xe4e3af20,0xff7a84e2),L_(0x951ce962), + LL(0x0b49df59,0x466ca295),LL(0x16afa866,0xc6b06127),LL(0x1f38aad5,0xf4e1677b),L_(0x672e7252), LL(0x29732848,0x3a4e5076),LL(0xfcdff811,0xcc6ceb5b),LL(0xfe6adcac,0x8a4243ce),L_(0xb04666fc), + LL(0xe74fffdd,0xc1e32f38),LL(0xd93030cb,0xf9561e97),LL(0x15f3f603,0x39bbca36),L_(0x90c8c914), LL(0x3734c1a1,0xa53fc681),LL(0xb0c4475f,0x158ec0bb),LL(0xed39d189,0xa57cf95c),L_(0xd562a81e), +}, +/* digit=18 base_pwr=2^126 */ +{ + LL(0x5cfdbf76,0x02c6b679),LL(0xace24453,0x8195dc3a),LL(0xa58b929b,0xbe2f8e64),L_(0x9a3a7efb), LL(0x9f7af479,0x7fa4b042),LL(0x8ad04303,0xb747bbcf),LL(0x426eb7ce,0xa67998c5),L_(0xdb040e40), + LL(0x7d551504,0x3bfd76b2),LL(0x0361658a,0xa3a2cf8c),LL(0xa3b9f1bd,0x66db4cfa),L_(0x4799c86b), LL(0x27afe24e,0x01c04fa0),LL(0x0689618b,0xaa0383bc),LL(0x5b052124,0x524802bb),L_(0x25748110), + LL(0xfd9c3522,0xb542168a),LL(0xf1dd3dc0,0x435f3e05),LL(0x3556cca8,0xf3b21a79),L_(0x0d1838e7), LL(0x0a1d87d1,0xbbfa360f),LL(0x43bd0f7a,0xdcacc277),LL(0xfdb15d31,0xa293f5a9),L_(0xf9285692), + LL(0x960b1fe7,0x7da35372),LL(0xefe3b9e7,0xb15275ca),LL(0x08b0fe30,0x9c0da2e3),L_(0xcef9bd5d), LL(0xfc9156e7,0x087c3eea),LL(0x4386ea9f,0x13e94876),LL(0x5543dce0,0x057ad0af),L_(0xc5162840), + LL(0xf9c98a4a,0xfeb313d1),LL(0x398fba1b,0x0e02712b),LL(0x52f53c92,0x98909181),L_(0xfa320278), LL(0xebd66101,0x906d44a0),LL(0x427688fa,0xc8c39420),LL(0x1c7282db,0x3901fb30),L_(0xaea2389a), + LL(0x6775078d,0x1424671a),LL(0xd8f3ae0f,0x4ebcdd7f),LL(0x80279f72,0xd5a77238),L_(0x602ce4df), LL(0xc083918a,0x12e9402d),LL(0xdd095d1b,0x02858419),LL(0x6cb15ad2,0x0927adfc),L_(0xa38c1285), + LL(0xfc6fbaf6,0xec392752),LL(0x1ec20f01,0xeed1ebd2),LL(0x5cac318e,0x47520f8c),L_(0x407d9032), LL(0x8ec0f4fd,0xe2f3dac1),LL(0x43dd79ec,0x35a74b40),LL(0x9236a81d,0x6bccf29e),L_(0x00ac0a42), + LL(0xc4755991,0x163c66e0),LL(0x849061a0,0xdd950bf5),LL(0x70208a9e,0x7bf95257),L_(0x07a10de2), LL(0xb0813c25,0x45c2891a),LL(0x15468f60,0x450f087f),LL(0x73d5ebe9,0x387e234b),L_(0xa32ac9f8), + LL(0xe8ff8e91,0x962ab070),LL(0x570fcd62,0xd3ce94dc),LL(0xb1757c3e,0x1ad55d1b),L_(0x7fa592e8), LL(0xa8ad3f09,0x76fcda7d),LL(0x73d3b392,0x348ab2da),LL(0xd6cf8e99,0xca16fca1),L_(0xac456eec), + LL(0xc7486909,0x5f929900),LL(0x240b92b4,0x27ccfc23),LL(0x0f7d51a1,0x632731fb),L_(0xf12e9902), LL(0x735b1778,0x47671b3c),LL(0x985803eb,0xec4d7c8a),LL(0x63e1c219,0x608cf2d5),L_(0x109df03c), + LL(0x09438c99,0xb25c71f5),LL(0x0829cedc,0xbe60921f),LL(0x483d485d,0x15305f6f),L_(0x60591120), LL(0xba32c7ab,0xbcdea716),LL(0xbeeee884,0x2b65df3c),LL(0x88e6ef43,0xc3d80182),L_(0x4b2dd1d3), + LL(0x1bdc3884,0x482c3679),LL(0x6b421466,0x6f172c00),LL(0xa58b570f,0x2587649f),L_(0x3e4ee4bd), LL(0xef99f5b4,0xf5a1388a),LL(0x98494de5,0x5a8f54da),LL(0x8f25a37c,0x50e9cc72),L_(0x1ce8e0f0), + LL(0x72cca43e,0x119587d3),LL(0x8e668562,0xa3b06524),LL(0x0554888c,0xd291f0fd),L_(0xae58bc85), LL(0xd1139d9b,0x48a506c1),LL(0x034f448b,0x04ec28f0),LL(0x94dd32bc,0x2bd2abc9),L_(0xb9e588a6), + LL(0x4988c3b7,0xe1e13901),LL(0x24b16627,0x4231b66d),LL(0x4f52ca62,0x749a749b),L_(0x8bb11e14), LL(0x03150154,0x3dfafe07),LL(0x71bdac04,0x73419c6b),LL(0x40bd5232,0x1587ab8c),L_(0x7d2d4a5e), + LL(0xf231ad9a,0xe7ffdae6),LL(0x0f11fde4,0xa13a1e41),LL(0xc78059f3,0xf4713c18),L_(0x2d2f0ff7), LL(0xfde9d338,0x5fe86c6a),LL(0xa381beae,0x9d423777),LL(0x734b9092,0x77f56796),L_(0x82131b3f), + LL(0x3a2c7153,0x612650a1),LL(0xc29b399c,0x72e7ea2b),LL(0xd673cbc5,0x60425f21),L_(0xece9a8ea), LL(0xfd08bc21,0x394b09dd),LL(0x1b69fef5,0x58e594d5),LL(0x141fc2ff,0xeab0baec),L_(0x85999248), + LL(0x5c8c18cf,0xf4b4d1ab),LL(0xe1f44cb9,0xdca5073e),LL(0xd86fbb1f,0x32861f51),L_(0x242811d3), LL(0x038cf05a,0x20b39e70),LL(0xc64c1332,0xd6198042),LL(0xeb68ae09,0x93c66ba1),L_(0x7aee0eb8), + LL(0xc4c03565,0xf47a18f7),LL(0x992398ea,0x808ebaad),LL(0x7414fdc9,0x325c8a8e),L_(0x42a7e664), LL(0x0900ad27,0x9f053caf),LL(0xc8869d15,0x2b52f07a),LL(0x1878089f,0x11f347a4),L_(0x19ee0c05), + LL(0xf8345a24,0x3e51ac6c),LL(0xb254a9d3,0x57f4ec7a),LL(0xe2b48c1d,0x916d1214),L_(0x3732c0ab), LL(0x5045ad37,0x0cb5ec90),LL(0x010093ba,0x1eea394a),LL(0x4a4cfff6,0x4aaf2a44),L_(0x7feda10c), + LL(0x370622e3,0x58625a1a),LL(0xea895fc8,0xe2d5d70a),LL(0xcac0e4d3,0x53bc48b9),L_(0x1d43df08), LL(0x681301c8,0xee75a210),LL(0xe1a8bb95,0x097c56b0),LL(0x7e7b6ce5,0x4a384a6d),L_(0x26d0db83), + LL(0x3ebba7eb,0x2bb95cad),LL(0x9e42faba,0x5398a161),LL(0x0f33c612,0xf67c4703),L_(0x6ef93df3), LL(0xbb0fa5e1,0x8ad685b2),LL(0x8655685c,0xb1c226c7),LL(0xdd2eb2bd,0x5e194627),L_(0x523e0fd5), + LL(0x3d42f37f,0x301fcb42),LL(0x80fb78c3,0x647b20c7),LL(0xfaa1d374,0x3d0a850d),L_(0x051bb6db), LL(0xbe9d92c9,0xc7fc5cad),LL(0x38f0078b,0xae641b58),LL(0x91a544af,0x0c9540c5),L_(0x6cae5443), + LL(0x33b2702e,0x93ebe56e),LL(0x71946cb7,0xff835a5d),LL(0xc82366c4,0xbfe6dc77),L_(0x27a97fdc), LL(0x2bb71ad5,0x80d9e527),LL(0x16d42ed2,0x21ce1d14),LL(0x18abf494,0x0398f8d3),L_(0xa190c5d3), + LL(0x87b49d63,0x495ac575),LL(0x6bf10350,0xb50a8115),LL(0x2674f39c,0x90ac41f9),L_(0xaedc843c), LL(0x20e79ef7,0x60ca4b9c),LL(0x2b7ba708,0x67e85483),LL(0xc070ae10,0x2e4b0764),L_(0x0c3aa1f7), + LL(0x9b6c96e8,0x555cdffb),LL(0xd2310fa6,0x1116970b),LL(0x42f99112,0x9d84f404),L_(0x8d7bdc74), LL(0x452face1,0x43e3cff2),LL(0x1c149edf,0xf602e240),LL(0x442dde2f,0x1288dcc9),L_(0xb3089de8), + LL(0x1ad5fcdc,0x3fe61e5f),LL(0x20fa93a3,0x2e793d8a),LL(0xb50f92b7,0xbfce0907),L_(0x632ab7a5), LL(0x8a0e5e0a,0xc89531e2),LL(0x6f57401d,0x4059a329),LL(0xf7bd6eb0,0x5942987b),L_(0xceffd87f), + LL(0xacfc439f,0x74161b3d),LL(0x647fc617,0x3b17df59),LL(0xac7f6cc8,0xc485b2c8),L_(0x0414a8d3), LL(0x69c118ce,0xd7de72d0),LL(0x1d6064d4,0x1eff6d80),LL(0x9fd6a735,0x8ee9cb9d),L_(0xf104d7a9), + LL(0x252fb3dd,0x776f7b1a),LL(0x2b058af6,0xb6f63fd9),LL(0x0d06abe2,0xb0461b36),L_(0x90f6c358), LL(0x5c9d58a0,0x9a72e438),LL(0x24e0b184,0xce596569),LL(0x6facf219,0x5f6753e5),L_(0x5f23a218), + LL(0x87cb85e1,0x4fd2cc25),LL(0xadb7e3c5,0x53c5cae5),LL(0x4cc67b4e,0x4c80d589),L_(0x6a578011), LL(0x4f08551a,0xc04163a3),LL(0x41978a17,0x52d7161e),LL(0x4701d626,0x7acb9d4e),L_(0x7040eb22), + LL(0x25c4f3fa,0xb117faf3),LL(0x734cd26d,0xb2bfac77),LL(0x071d299e,0x1ad0de2a),L_(0x826417df), LL(0x1049bb39,0x487c15ef),LL(0x5432a8df,0x74da9484),LL(0xa5c29870,0xe2f76737),L_(0x89d1f699), + LL(0xe58a9a06,0xe366cc79),LL(0xcd96f1e7,0x497f4836),LL(0x19aa24f5,0xbe89a16c),L_(0xea6d5b99), LL(0x4105a3ce,0x1afa0bd4),LL(0x8da4ca09,0x4aa54b7f),LL(0xb278c556,0x07697581),L_(0xea0b2435), + LL(0x69260167,0x233ddda4),LL(0xbce451f2,0x055176b1),LL(0xe21ca9dd,0x33fc9573),L_(0x608477ee), LL(0xb1111c08,0x37f4a8b6),LL(0x2f253ba7,0x60c86d48),LL(0xec1f4a44,0x3ae7c4bb),L_(0x1c649260), + LL(0x418877ba,0xf186ffa7),LL(0xca88dd8a,0xe435d41d),LL(0x2e8c5c07,0xd65638d7),L_(0x8d28689a), LL(0x50763ccc,0xa2ef4b71),LL(0xfa5e89e0,0xbab1be9a),LL(0xea4b66ad,0x2a17ea7b),L_(0x5744fef5), + LL(0x511ae7ab,0x1c88c915),LL(0xd377e6af,0x55991086),LL(0xbd38c04f,0x43c62134),L_(0x7e11eacb), LL(0x715ff436,0x3aa19a12),LL(0xe65b9643,0xc019b147),LL(0x0069d240,0x7d7a8265),L_(0xc6fc4f7d), + LL(0x00db9dd8,0xb94a17c8),LL(0x95308d83,0xb2b6edac),LL(0x88fbad84,0xd14a8ca8),L_(0xcec36252), LL(0x7824a283,0xf71bccba),LL(0xd90035ec,0xd172d468),LL(0x55a73d3d,0x07f0cdbc),L_(0x6c21797b), + LL(0x3b33cd4c,0x5162797e),LL(0xa87e9702,0x6fc60b78),LL(0x2ab93ff3,0xe2a31c19),L_(0x4288abf4), LL(0x297e2ccf,0x80be51bb),LL(0x388680ed,0x058de4bc),LL(0x8dedbe92,0x7da1a829),L_(0xbffcb08c), + LL(0x7008c033,0xac1e2c00),LL(0x1d6fb3ed,0xd70668f0),LL(0x9f1545b9,0xfb03795c),L_(0xbfecfd6e), LL(0x83ab63e2,0xac0e74d0),LL(0xcbb46331,0x481489c9),LL(0x01849565,0x79c317d8),L_(0x9186b0db), + LL(0x1b42ef85,0xe3b9e5c1),LL(0xa44cb510,0x4bcaad24),LL(0xc72bcdea,0xd47f22e3),L_(0x23ac79ad), LL(0xffacee46,0x1062a849),LL(0xd5193e66,0xfb9adffd),LL(0xbb25e4cf,0x600c0353),L_(0x5ab3c0ce), + LL(0xd8f9674f,0x1f36e1c6),LL(0x2a414d7c,0xc2f2d11a),LL(0x23202a91,0xbdd27859),L_(0xd77095b4), LL(0xe447fde6,0xe5a99ae1),LL(0xd0fffc9e,0x5835b80b),LL(0x490dac48,0xacfdbe9c),L_(0x9079d090), + LL(0x65c70a3a,0x550c3e82),LL(0x448361bb,0x40b9aa3e),LL(0xfeab6ae4,0x41969a52),L_(0x74461138), LL(0x37a53426,0x47381f18),LL(0x2be030b8,0xd6e199e3),LL(0xb091abda,0x4da4cd53),L_(0x7df8f1e3), + LL(0xb6274829,0x9fea92c3),LL(0xab2fcd01,0xcf88fa14),LL(0xd804cba2,0xed8709e8),L_(0x19141717), LL(0x820090bf,0x88fb9ad9),LL(0xe105506b,0x370d09cc),LL(0x8cb2c13e,0x4e6bda23),L_(0xcaba970f), + LL(0x5ad6bf8f,0x9fcd4871),LL(0x160191eb,0xa47d5c67),LL(0x826242d1,0x99634c20),L_(0xdfe7289d), LL(0xbd0af1f7,0x4e07eba8),LL(0xc0910d55,0x18abee83),LL(0x7e042c87,0x6d7f5229),L_(0xd74d6e82), + LL(0x4747a07d,0x6efbc0e2),LL(0xcc3c4e8e,0x9088fde2),LL(0xf21ea1eb,0x05c108d8),L_(0x37aae682), LL(0x0d08ac9d,0xf2c37fd2),LL(0x9a51bef8,0x4d3bd6c1),LL(0x5ac834a7,0x2a412b12),L_(0xac985dae), + LL(0xf5833d2b,0x39bd0099),LL(0xb0ef3648,0x886d33b3),LL(0xc1936e74,0x97226670),L_(0x3eb64bfc), LL(0x408e784b,0xfa065545),LL(0x6cb29cd8,0x96246832),LL(0x010fbc36,0x6b24b9f4),L_(0x72e08b5c), + LL(0xaa5c541e,0xe0daf350),LL(0x2fb0ee94,0x86c5cee7),LL(0xac57f680,0xb753971e),L_(0x6b0ccf83), LL(0xbcb76004,0xc3b1be67),LL(0x48b857e0,0x3f637d0f),LL(0x81e2b0c6,0x595ebecb),L_(0x7151293e), + LL(0x9a2c561d,0xb788bb43),LL(0x65e9c6ef,0x6cf04373),LL(0x10062256,0x891a7719),L_(0xe6f377fd), LL(0x9d5d462c,0x7355204a),LL(0xe23556ab,0x08f2e4fc),LL(0x188872ce,0x84eba15d),L_(0xea03bca4), + LL(0x37bcd5fb,0x159bb9de),LL(0x08807416,0x412b6267),LL(0x496eba6c,0x5b5b2f5c),L_(0xff4f34bf), LL(0xd57ab42b,0x376ec0fc),LL(0xe48904ea,0x62f02fea),LL(0x96bf9fdc,0x9b04b325),L_(0x003a468c), + LL(0x85de6fe5,0x3d1be5ab),LL(0x62509881,0xf11ef926),LL(0x65d5f607,0x244caa05),L_(0xc38d7540), LL(0xc1a149a8,0x0b239ba6),LL(0x19b8e994,0x53224bb3),LL(0x1f25f647,0xd2cd0a34),L_(0x7f481820), + LL(0x303ac802,0xdceb71b5),LL(0xf395c0f2,0x9bd5860b),LL(0x6febd95b,0x01d8efcf),L_(0x0b358ed0), LL(0xc95f4540,0xdadfd46c),LL(0xdc5d961e,0xc1f026dd),LL(0x221b24a2,0x6d21a125),L_(0xc0f16b10), + LL(0x03e43472,0x3ece8318),LL(0x54252e96,0x430e9b3f),LL(0x97edd631,0x020e1e99),L_(0x90685aae), LL(0xad7d0431,0xb7771434),LL(0x6df64310,0x9647f95c),LL(0xa647e2b0,0xd6ddd8f3),L_(0x52ff5927), + LL(0xe48eb4a9,0x3fd7f726),LL(0xbb02013a,0xcd6dd255),LL(0x6e17def8,0x5ef8f2c6),L_(0x1b970bb2), LL(0x867ed64e,0x1236fa4f),LL(0xf7a7e274,0x459207e6),LL(0xffa4c978,0x5a8179b1),L_(0x99219388), + LL(0xcb87940a,0x4b407e59),LL(0x844408fa,0xa05e3d79),LL(0x742669b3,0x0751f86d),L_(0xb00b365a), LL(0x7860c6e5,0x3a8360fb),LL(0x4147cefc,0x10209a6b),LL(0x0393026e,0x7a7f6231),L_(0x2e39fa34), + LL(0xe7f6f33d,0x149f6c77),LL(0xbbcd3afa,0x9a9bdb39),LL(0x742b5b3a,0x899f0118),L_(0xb8dc2766), LL(0x573badd0,0x14c00e4c),LL(0x6924c12d,0x190dfe39),LL(0x4e4111e9,0xdf09100c),L_(0x2987ca68), + LL(0xe5fa2136,0x65fad088),LL(0x01cff054,0x9c1c2f99),LL(0x3002769e,0xdb9e3912),L_(0xe9ad46db), LL(0xa7493cf2,0x6e70449f),LL(0x34ab7ab5,0x1ed50609),LL(0xfda4dfd0,0x91982d5a),L_(0x89e4ea03), + LL(0xb358f84b,0x132822e9),LL(0x1ad76044,0x9d9ae4a1),LL(0x3e8a1d95,0xb981b100),L_(0x37f04df1), LL(0x364692e2,0x0b17bd09),LL(0x0b34cd00,0x5d63a307),LL(0x447278ad,0x07bde57a),L_(0x6e16122f), + LL(0xa6d64780,0x3221832c),LL(0x8fc6ce6c,0x3dbd0cb9),LL(0x6582853a,0x9cdf65d9),L_(0x708e9258), LL(0xf6bfe6cf,0x273611ec),LL(0xef43a507,0xa78d98b3),LL(0x86406043,0x88f84624),L_(0x4396769b), + LL(0xbca28b2c,0x25903255),LL(0x6b8a2c7e,0x255e1a29),LL(0x567e51fc,0x06f1e0ff),L_(0xdbcad515), LL(0xf590a256,0xe7fa9d15),LL(0x627c717b,0xe236aabd),LL(0x3efff1d7,0xa592bf53),L_(0xe58ce7d7), + LL(0x47f49527,0x6bc49db6),LL(0x2993ad98,0xc9fd48de),LL(0xcd8ed14b,0x104437d1),L_(0x419b6d76), LL(0x80c19d84,0x5ceae531),LL(0x2692fc9f,0x7b8ba2ce),LL(0x96208c12,0x5f17f19b),L_(0x34a83cc6), + LL(0x35c24843,0x3d238cb1),LL(0x6bb879b5,0x818fcd3b),LL(0xeaa5d8cb,0x137d82f5),L_(0x769e2a68), LL(0x1bcbebc0,0x0ddf279d),LL(0x2ae26372,0xda0b62e6),LL(0x79e90c0c,0x27e773c7),L_(0x3451edcf), + LL(0x8b2767f2,0x65ddd79a),LL(0x34988e35,0x9ab07761),LL(0xd93aac10,0x814a0e96),L_(0x76ec0b96), LL(0x802069a0,0xe6639b9a),LL(0x9143cd9d,0x23a6da3d),LL(0xfb9b096c,0x77b915d6),L_(0x4353464a), + LL(0xc93ba38f,0x103b0148),LL(0x52d3720b,0x9d45cf17),LL(0x3c3a2d72,0x0ddae18b),L_(0x3543af35), LL(0x10ee7a77,0x90846157),LL(0x51cb6d6c,0xa8824c71),LL(0x5541df28,0x9f0df2e6),L_(0xa96cf0e6), + LL(0xdb058979,0x51a147b3),LL(0xbd4c751a,0xba41fdd4),LL(0x5b132575,0x81839452),L_(0x9b0ddfdb), LL(0x785de02d,0x2e14f24c),LL(0x54dad63a,0x052a799c),LL(0xd7c22290,0xdcbca7aa),L_(0x77c13acc), + LL(0xe8859b95,0x4c326ed2),LL(0xe3bb354a,0x57333802),LL(0xa148004d,0xb7008ce3),L_(0x85367d7f), LL(0x2d4febd4,0xe73d1a3f),LL(0x93d871ad,0x1f4f245d),LL(0x7768c969,0xd9c87876),L_(0xb38a617a), + LL(0x085dbc17,0xaf8f400d),LL(0x2a94dc1a,0x93399c4a),LL(0xf8d2e936,0x370e4c06),L_(0xca35bd61), LL(0x0fb73083,0x2c1682bc),LL(0x00b6e1a8,0x4742b84d),LL(0x6d92e1f4,0x9bb1736d),L_(0x3e9b6293), +}, +/* digit=19 base_pwr=2^133 */ +{ + LL(0x2a85b5cc,0x6c35afbc),LL(0xf6f30e96,0xb02b80b7),LL(0x669a8252,0x4dd8bbbe),L_(0xb9b1b311), LL(0x28535ef6,0xbbcbf46b),LL(0xe4d59c99,0x20d09a27),LL(0x63242255,0x877172dc),L_(0x853f9c6a), + LL(0x432984a1,0xd5de71e9),LL(0xe7f42edd,0xb421581f),LL(0x0b9c53bf,0xc8c4ee60),L_(0x82b1e37e), LL(0x51492ea8,0x4a10fc29),LL(0x7502a8c1,0x69016e9c),LL(0x2dc30077,0xcd3e0527),L_(0x2e0b7f76), + LL(0x161f4880,0xc21b4aab),LL(0x95f715ce,0x44db3fe0),LL(0xff0073cd,0xdb4528e5),L_(0xdbc69fc1), LL(0x5161785c,0x8bfc4101),LL(0xe2c44c67,0x22e31d16),LL(0xa7624b31,0x1b45072c),L_(0xebf2704a), + LL(0xfd1ff163,0x540d3ef9),LL(0xe3c8a7e4,0xd48da416),LL(0x39e285d6,0xccac1ee5),L_(0x8d098605), LL(0x09862475,0xaae2485c),LL(0x424cb101,0x4df1fb56),LL(0xd81ebf03,0xe045acd6),L_(0xec4b922d), + LL(0x3fbc727e,0xe3ace3b3),LL(0xfb5f0701,0x39644794),LL(0x1534cde5,0x25904a79),L_(0xf9421b0d), LL(0xd3275fa8,0x0528f7ca),LL(0x8a9c39d8,0xdea09c8b),LL(0xdd383932,0x458a7c5f),L_(0xbaf06aaf), + LL(0x1adf0fac,0x193b780b),LL(0x5abd6eef,0x5042f2da),LL(0xd76b78fd,0x06442ef6),L_(0x0cdf9e58), LL(0xfef055d2,0x8a5c2657),LL(0xfae0a442,0x0bf16e33),LL(0x6c2b778b,0xb5adbc98),L_(0xf374d05a), + LL(0x846ef971,0x0c6f4ae2),LL(0xb657d5f6,0xd2466841),LL(0xabf1920f,0x70a6775e),L_(0x15909e3c), LL(0xcede3a4d,0xe0c73f43),LL(0x563843f3,0x15282f23),LL(0xe15912d0,0x2e80308d),L_(0xd16c8835), + LL(0x767329dd,0xb00d2849),LL(0x96ae8e24,0x10d39711),LL(0x118cc563,0x4ed443bf),L_(0x9157acc3), LL(0x755122ae,0x14b54c12),LL(0x07d6ccc1,0x4fd87692),LL(0x05ec4685,0xf50f2de3),L_(0x1a923061), + LL(0x3480f7d1,0xc692cc02),LL(0xbe07dcf7,0x71999891),LL(0x5f04bf18,0x0d99300c),L_(0xa062deba), LL(0xb9eb55fc,0xa3451ea5),LL(0x02666d4c,0x1acb5351),LL(0x2fc90780,0x564f33fe),L_(0xa2bd47b9), + LL(0xb70680a0,0x6da6ee27),LL(0xdab5f17d,0x76f48c1f),LL(0x36f25faf,0x16a32d1e),L_(0xbe5fdc6d), LL(0xcd1b3276,0xd0d79fc8),LL(0x0ee979a6,0x2e5c89f7),LL(0xc670e327,0x6435ef83),L_(0x55425ae2), + LL(0x8e0dd4c4,0xcf395e16),LL(0xd8954092,0x86079f76),LL(0x516938e6,0xc57f3db0),L_(0xe85d4e50), LL(0x4eabd92c,0x611ea78f),LL(0xfafbe19a,0x8d26fbc1),LL(0xe5ff8f07,0xe41d9e6e),L_(0x9e9c0da2), + LL(0xcfcf1446,0x86e3cdb5),LL(0x8cb41178,0x3fbc43f0),LL(0x5615e2b5,0x74d58d7a),L_(0x4e6b82ce), LL(0x0c36a5a8,0xd4c6f917),LL(0x374bbfd9,0xc3b3ae3b),LL(0x15aadf46,0x363a6cec),L_(0x30dd6649), + LL(0xe325634b,0xe43c3ade),LL(0x120bb9ae,0xb587b6a1),LL(0x73ef55fc,0xbe8a8508),L_(0xbb18ab2b), LL(0xc135e4d5,0x84facee1),LL(0xb277aa2c,0x67fba354),LL(0x742a25ca,0x1cc06cae),L_(0xd0d24d20), + LL(0x3aa2917b,0x0714ac71),LL(0x2ffe0519,0x178aa56a),LL(0x843d58c9,0x7eddcb6d),L_(0x1e60abe4), LL(0x4b221bdc,0xb10fd184),LL(0xccf9c609,0x113f37e1),LL(0xa0d4b627,0xe398ed34),L_(0x7b6aa811), + LL(0x95472b76,0xa960c0c2),LL(0x735c5d62,0xf7232900),LL(0x0f8b2a35,0x54dfa089),L_(0x0b186f7a), LL(0x7962dd9a,0x3e7eb8a1),LL(0xc1614c55,0x0188ff65),LL(0x8c7e1e1d,0x390e7c1c),L_(0xf9b0b2f9), + LL(0x66e2227a,0x11277d69),LL(0xd9cc122b,0x5181f585),LL(0x3f2ab21d,0x2cbd87e4),L_(0x494cfb1e), LL(0xd57e150f,0xae7bbb8f),LL(0x9977c3ac,0xee685251),LL(0x397ea438,0xb224446c),L_(0x7ed9dec7), + LL(0x3c14cf6c,0xc59accd1),LL(0xb5432f0f,0xb6446b96),LL(0x8b88a937,0xc5589b93),L_(0x02d9f9ac), LL(0x007ea9ac,0x8302d1bb),LL(0x43908c95,0x087096dc),LL(0xb05f1092,0x83349c39),L_(0x5061c674), + LL(0xf6734878,0xf0350dc8),LL(0x9371eb01,0x4edf29b1),LL(0xce86a9ba,0x47861a0c),L_(0x9aad7247), LL(0x16443994,0xa559d5e8),LL(0x979093ec,0xa58da55e),LL(0x0fe17efc,0xb512322d),L_(0xae7b8c8e), + LL(0xf66cc404,0x3ad82960),LL(0x9f1ec261,0x07a3082c),LL(0x77a36e96,0x3914c9d2),L_(0x9b1a4daf), LL(0x238844ea,0xec701058),LL(0xcfa77625,0xc70140df),LL(0xe60b3f2a,0x0c5b4abf),L_(0x138b4b1c), + LL(0xa5d35437,0x174442e5),LL(0x1802aa28,0x2aa23227),LL(0x26f71e89,0x4a4c5681),L_(0x7ae33021), LL(0x7106d5d6,0x5d0cad43),LL(0x2893d185,0xe47a47cc),LL(0x7e9947d1,0xc9f7bf57),L_(0xf2c79dea), + LL(0x607d7e89,0x3a838f3a),LL(0xfbe1be02,0xf73959fe),LL(0x229d491d,0x207a3044),L_(0x9f62e957), LL(0xd08dcf90,0x2e1d3c53),LL(0x86b7e5aa,0x229a31a5),LL(0x3fbda02f,0x7c96f0d5),L_(0xbda44f9b), + LL(0x6e006c73,0xf1aeae69),LL(0xae77f574,0x08648f34),LL(0x0423c397,0xf1f4d153),L_(0x47451433), LL(0xcd40d0b0,0x3a807b62),LL(0xe8e961f8,0xa745762a),LL(0xd89c3d2a,0x467e86a7),L_(0x6ac80359), + LL(0xb9798433,0xb36ecce6),LL(0x3b7324a4,0x5be87e7d),LL(0xbb9babf8,0x98c1904a),L_(0xf1e380ce), LL(0x03c9dc36,0x01b08224),LL(0x2eeb6052,0x1ae12594),LL(0xd0d4fef9,0x19322045),L_(0x256a539e), + LL(0xdcff0296,0xc94659b0),LL(0x2f0568f5,0x39aab164),LL(0xed8a79a8,0x50d8c266),L_(0x757c7d99), LL(0x4445c1ec,0x66c509e4),LL(0xb792533a,0x70d28954),LL(0x9e0c5aad,0x34caeea9),L_(0xe5b193ca), + LL(0x8188c9ad,0x195602fb),LL(0x701a9997,0x76ac1458),LL(0x3992cbca,0xe1e8b8e7),L_(0x8ec536e5), LL(0x4d168e61,0x29c79b39),LL(0x29bff6f9,0xca81be8e),LL(0x596ff95f,0x0a0ae347),L_(0x661b4a6c), + LL(0xd0970633,0x8e767a03),LL(0x473ec4b4,0x7b96613b),LL(0xeb4d7d16,0x98a8ebb4),L_(0xc4e28600), LL(0x1487660b,0x6beb5ab7),LL(0x1ef6cbd4,0x71463757),LL(0x83dde9df,0x1762ff65),L_(0x9ddef882), + LL(0x0d56a9f5,0xe6f97e52),LL(0x2cfac1c4,0xe924c291),LL(0x9480052a,0x61546993),L_(0xcee96715), LL(0x4783b246,0xdc612b8a),LL(0x01036872,0x40ce9da3),LL(0x9e6d56f5,0x0543bf02),L_(0x40b8eb7d), + LL(0xaa29fa33,0xbb67b973),LL(0xd7ceddb4,0x733e1da7),LL(0x7bd3859f,0xe95a7ea2),L_(0xc85424d7), LL(0xc42d076f,0x5d21362a),LL(0x2591a7e7,0x8674ee1d),LL(0x52817220,0xc9d8453d),L_(0xa286acd4), + LL(0x7fece4b3,0xaf830115),LL(0x6e587151,0x0a71eb17),LL(0x3d8da1f0,0x7afbb075),L_(0xf8e3bab4), LL(0xea1fecf8,0x3ab8344c),LL(0x6bb840b0,0xb4392fd5),LL(0xae7bd8be,0x73177038),L_(0xed8b2ca2), + LL(0x50dfe6f9,0xadd91143),LL(0x680d82d3,0x88a2c506),LL(0x88f503de,0x37393204),L_(0x746b676f), LL(0xc6591d03,0xaf979503),LL(0x5a9be716,0x79a8b931),LL(0x0e682183,0x609ab748),L_(0xfe8299c8), + LL(0xc3535c6b,0x193fd320),LL(0x8682c4c0,0xff4f04b8),LL(0xd566872d,0x1407f3c3),L_(0x16439d5d), LL(0xac2e95ba,0xd6726481),LL(0xb7bc2fb3,0xb0b0ea32),LL(0xb4c2b53d,0xfeaaece6),L_(0x4349edc0), + LL(0x649e4b51,0xae9bd277),LL(0x6c678048,0x4268b40c),LL(0x52da3782,0xae4a71b1),L_(0x1e1cd89e), LL(0x4f079bbd,0x2f691fc6),LL(0xf69884c3,0xfe5d33d3),LL(0x19020a41,0xdda1c483),L_(0x77d02be4), + LL(0x7ea53289,0x8529164c),LL(0x5d80aafd,0xd09dfaea),LL(0x1e830c7c,0xa9f0f09e),L_(0xfc3140e2), LL(0x5135dc82,0xdc2ab04a),LL(0x59befe02,0xa0b35f50),LL(0xa44595d6,0xc1e15529),L_(0xf19abe7c), + LL(0x3a5d5f42,0xa12bcced),LL(0xb9b8ec3a,0xb87d7dc6),LL(0xad1e4dcf,0xb63e0921),L_(0xfcf65288), LL(0x0c0e6332,0x863fe95a),LL(0x5cd2ee3e,0x42a677d4),LL(0x60da7b43,0xb8a5bd09),L_(0xc426f7df), + LL(0x51ea4dd8,0x6e5213a1),LL(0xfd69d7c4,0xdf5f1e1a),LL(0xd30cf23b,0x37d44e1e),L_(0x7097147f), LL(0x321e5347,0x12d98f14),LL(0x32dad5dc,0x76d7e7b8),LL(0xdfe1a803,0xc8d86798),L_(0xeccd5411), + LL(0xa7aae910,0x74006fc6),LL(0xd7d803d8,0xa34c1849),LL(0xec84dc01,0xae309a70),L_(0xa34e0e32), LL(0x42af799e,0x235ed631),LL(0xcfee558c,0x8802c5f3),LL(0xcd97224f,0x1640e7f8),L_(0x92280213), + LL(0x535c56a8,0xc7ccf419),LL(0xd687e53b,0x31ef82e6),LL(0x9a24176e,0x01470242),L_(0x01aae44b), LL(0xf12919c6,0x9fcc8bac),LL(0xc772707a,0x2bbb2bc0),LL(0xeeb32998,0x1fd556e7),L_(0x6b1da8b4), + LL(0x10943f72,0x3fe0c227),LL(0x929fe46b,0xf1163a98),LL(0x55829b86,0xb0593728),L_(0x46968b3a), LL(0x98063840,0x861c28fa),LL(0x49238b1c,0x238ae42f),LL(0xe2c2f08f,0xc3669826),L_(0xd635b05a), + LL(0x0b716b89,0x1cbd7071),LL(0xac172491,0x9bedfd64),LL(0x70337bd6,0x5806f542),L_(0xba62de08), LL(0xff8ac4cd,0xc789f899),LL(0x778e6f6e,0xcabb9b96),LL(0x7cb61f89,0x9e11ca0e),L_(0x54802afa), + LL(0xb4f60ac0,0xa293c1cf),LL(0x98d81eae,0x3ce25589),LL(0x4a05fd65,0xf7776c88),L_(0x31edd830), LL(0x7102bdbe,0x6b003741),LL(0x530442c5,0x619c469b),LL(0x2717506f,0x993316f5),L_(0x977de534), + LL(0x731f0430,0x1f4b647b),LL(0x63a5f62f,0xa8649b7d),LL(0x184bd1bf,0x9eb8bb02),L_(0xd878238c), LL(0x2268c556,0xee715bb4),LL(0x0c09795f,0x5ba6433a),LL(0x4a0ef111,0x5e80a1d2),L_(0xa6ed70be), + LL(0x1a0ec85a,0x02e27463),LL(0x66b5fa13,0x7351bd1f),LL(0xf1afa0ff,0x262f06e4),L_(0x55328bec), LL(0x17a8c5cc,0x359db888),LL(0x56654a88,0xbbf24e90),LL(0x31866e60,0xe08705c4),L_(0x615a5b05), + LL(0x2741b093,0xd9bae789),LL(0xa18e5f26,0x959b66a0),LL(0xfb66461f,0x52d89638),L_(0xf79de1ee), LL(0x3b41960d,0x63f080c4),LL(0xf0c1209c,0x1356ad3c),LL(0x8927edab,0x1cca87fa),L_(0x0d7779de), + LL(0xed47b255,0x4ffe196c),LL(0x591b255f,0x0bda5bcf),LL(0xf529da71,0xa919472f),L_(0xc172114d), LL(0x4edb3f70,0x727df75d),LL(0x0b0bba01,0x7a3418a3),LL(0x18ae3fad,0x7de531b5),L_(0x60f6010b), + LL(0xeec6a320,0xc8ab7f39),LL(0x4d9c100a,0x42812137),LL(0xb3ed07de,0x2ce9d1a7),L_(0xf4f877cc), LL(0xbf31e6a0,0xe5d2ab30),LL(0x7ebabf38,0xc0c95215),LL(0xce3cfa6e,0x85ffa6d1),L_(0xfa3306d0), + LL(0xfe179a15,0x014e69fa),LL(0xe40ec6e7,0x949a6258),LL(0x8f04f43e,0xf3db5670),L_(0xb9883ee7), LL(0xf31a374c,0xeab3fc5d),LL(0xedf8720a,0x70831223),LL(0xf1d8e66c,0x32cbb568),L_(0xc1af6691), + LL(0x955bb333,0xb78b642a),LL(0x65a42ec3,0x18885922),LL(0xdde23959,0x216642c3),L_(0xcdc7c4de), LL(0x4a6ce38f,0x82ee3788),LL(0xec771036,0xd5430b69),LL(0xefdcbefc,0xe82b1033),L_(0x5b9fd0f1), + LL(0x856e9dad,0xd7c8b168),LL(0x94661f99,0x034f792d),LL(0x968a0514,0x5e1f223f),L_(0xf2936613), LL(0x9468ee68,0xf109d747),LL(0x8c1958b8,0x35d5c367),LL(0xd1baaa07,0x58b0e5bd),L_(0x04265560), + LL(0x03eb3ddb,0x3c1c78f2),LL(0x73aa994d,0x77b06810),LL(0x9d13c879,0x5ffbf962),L_(0x329365bf), LL(0xeb311f82,0x151d1b5b),LL(0x9b162681,0xa0010f38),LL(0x67d4adbd,0x2d7119cb),L_(0x112111da), + LL(0x3a3f8979,0x8de63a52),LL(0x0bc054e9,0xcecf35b9),LL(0xac3474f8,0xd39c2e22),L_(0x8a24d244), LL(0xe1c3169e,0x72de5749),LL(0xf7cd28ca,0x1f3311ce),LL(0xaba378ca,0xacf3d959),L_(0xc4c178a4), + LL(0x41028a7a,0x4c196a71),LL(0xeddb3096,0x07052fa2),LL(0x78d05008,0x4a5cea44),L_(0x4e82cf55), LL(0xe4836382,0xbc157855),LL(0x42628bb0,0x6906bb4c),LL(0x3bec9a03,0x414298ee),L_(0x71c76fb4), + LL(0x2dc6d80f,0x451c89a8),LL(0x0eb5ca81,0xb205946f),LL(0x85231812,0xdd102f79),L_(0xcfe70175), LL(0x79cbba78,0x74f5620f),LL(0xa68f72ba,0x925ad282),LL(0x107305c7,0xa0b90dac),L_(0x71b34217), + LL(0xd11e6b55,0xdf55e61e),LL(0x74013fe7,0x39b4240c),LL(0x384b1c58,0x117f4d5d),L_(0xb417f0cc), LL(0xdee67f19,0xa5e101d1),LL(0x6a59354e,0x057e8fde),LL(0xdd613a29,0x3d053f50),L_(0x49698601), + LL(0x0e1e0dac,0xbc28da28),LL(0x350510df,0x6476441e),LL(0xa5492aa3,0x488b3ebb),L_(0x7335580b), LL(0xe4198903,0x150fa7db),LL(0x5080e530,0x1e0113ef),LL(0x41fe0adc,0x151c555b),L_(0xefba1701), + LL(0x4e602721,0xda6ab8ed),LL(0x01c286ca,0x82be4f7e),LL(0x8f870fa0,0x67983e93),L_(0x011517ba), LL(0xd1bb4bf4,0x2ffdf949),LL(0xb8ff2b68,0x4a318fa3),LL(0x57a7f08b,0x2df51505),L_(0x7f4a552d), + LL(0xc07ee494,0x8a38d900),LL(0x15f78485,0xd40347a2),LL(0x40936fbc,0xdc403083),L_(0x26d9bf80), LL(0x87df50e9,0x6682494a),LL(0x658eecc3,0x88a94156),LL(0xe2c9cc47,0xf4a7dc3b),L_(0x6742c074), + LL(0x58b3b3f6,0xaf6f6f61),LL(0x1be73cf3,0xb37f3459),LL(0x74ffb428,0xb29ede9a),L_(0x92e686e4), LL(0xa4431924,0xdfa5e88f),LL(0xe1001a22,0x01fe6a9c),LL(0xf029cdcc,0x55c88ddd),L_(0xd03747ad), + LL(0xc359e1a8,0x69bc7a5b),LL(0x0a7f469b,0x79ced652),LL(0x8cb61ff4,0x860090cf),L_(0x25e6acf5), LL(0x5ae7246e,0x7c9a5e58),LL(0xd04ea633,0x62e6dab4),LL(0x3dccdf35,0x679b9a9c),L_(0xe0d5601a), + LL(0x9f6c163f,0x75393ffa),LL(0x503ff7fc,0x8a5ba74c),LL(0xad84a980,0x6a8d3ebd),L_(0xb711116c), LL(0xdb3d29d6,0x508cd2da),LL(0x298e39d1,0xadc29bed),LL(0xd182ffce,0xf35bcd9e),L_(0x56f60d5a), + LL(0x18ec5621,0xbb37476c),LL(0x126c6b62,0x00881f6d),LL(0x12e961ae,0xc23fa1b7),L_(0x620a85d2), LL(0x116a94f1,0x18d50f3c),LL(0x90b6bf4d,0xc1b565ee),LL(0xcce6cb44,0xb9db57be),L_(0x43232f2b), + LL(0x7e516745,0x33f18556),LL(0x34242913,0x303ca557),LL(0xecfa2caa,0xe5298223),L_(0x54c9b89f), LL(0x5a38eea9,0x2bb85e07),LL(0x3640c336,0xbe45ca34),LL(0x23f72dcc,0xe33bfd7f),L_(0x1138d09f), + LL(0x2532b3de,0x9635cec4),LL(0x99decb38,0xecdd16cc),LL(0xb6e94853,0xc90493fd),L_(0xe03d588e), LL(0x7c31a9ad,0xbbcd5eac),LL(0x1a5efdc4,0x24031f80),LL(0xbd3e5f35,0xc0bbee30),L_(0x91354a2e), + LL(0x46fe272f,0xe4fe7dd5),LL(0x40ccc046,0xcb3af2d4),LL(0xef734198,0xe37fbe0f),L_(0xd7d730ce), LL(0xc1b5100f,0xe81b74b4),LL(0xccbbf03c,0xfbbba07c),LL(0xaf1eca00,0xb202f7d1),L_(0x6c3a5371), + LL(0xb759588a,0x3c293b4f),LL(0x50ebe82c,0xccc60f4b),LL(0xe5c199da,0x9c0164e0),L_(0x09ae68d1), LL(0xdbb33342,0xe57a6b34),LL(0x764aa682,0x71131364),LL(0xd2b124d2,0xc37e19f6),L_(0x0684de69), +}, +/* digit=20 base_pwr=2^140 */ +{ + LL(0x2e5b54d1,0x3a2fc0ae),LL(0x3a0ae219,0x810b8800),LL(0x71d39325,0xeb53d991),L_(0x1b364d9f), LL(0xc225e922,0xe634fa4b),LL(0xfa979c3b,0x48c1302d),LL(0x0315e213,0x7a46c430),L_(0x7d3dfc00), + LL(0xf75af9f3,0x69c6dab4),LL(0xcad74055,0xbd0a143f),LL(0x5f980b30,0xf457bc61),L_(0x08ab6cd4), LL(0xa472e295,0x5a3b5bb9),LL(0x4a0eec60,0x1e647946),LL(0xa4e2c617,0xeb13a610),L_(0xea8ba726), + LL(0xb1f39e26,0x8208d95b),LL(0x1d126957,0xd33801fe),LL(0x38314570,0x2b3db8bc),L_(0x68f43b86), LL(0x06523bb4,0x2fa1baa7),LL(0xb3650b8b,0x7b7200e3),LL(0x222d46b5,0x5ab609c3),L_(0xe25b7f78), + LL(0xf09c3b4a,0x2601c0c2),LL(0x10c7e593,0xb71c88f8),LL(0xd433020b,0x163a4b4f),L_(0x6ea15982), LL(0xd7a199df,0x559abf4b),LL(0x168cc6db,0x8c58a3fd),LL(0x5e92d42d,0xcad8eab0),L_(0x0f718cd3), + LL(0x5222ebab,0x1eccb2dd),LL(0x45eee5ae,0x6cca2e8f),LL(0xf0f806c3,0x93a2e216),L_(0x0b896b9f), LL(0x2753730f,0x21ac6aa6),LL(0xe860a374,0x93ff82bd),LL(0xa6d03d5f,0xc336e305),L_(0x5a3ad08c), + LL(0x05094bb6,0x7e65ba97),LL(0x927ff44f,0x69a96369),LL(0xcfc2ebd4,0x8e5841d8),L_(0xcd919ed2), LL(0x7d67ba45,0xd72479fa),LL(0xf9079703,0xb458951d),LL(0x11b2590d,0x12b5f89b),L_(0x9e78739c), + LL(0xb68ddf1d,0x64971999),LL(0xcc5dc1ba,0x0f78a155),LL(0xc7f1ee3f,0xbbfeebe2),L_(0xa475b47a), LL(0xae6b1a67,0xd00f3342),LL(0xaa2739d6,0xcbc8eae8),LL(0x6bcba57f,0x08421638),L_(0xf50c5c89), + LL(0x21fce16e,0x56ea720e),LL(0xc14eb574,0xb07c02a7),LL(0xe5e93b80,0x1a141ce9),L_(0xf206da59), LL(0x400443af,0xff6ca106),LL(0x85cacb30,0xe7e89a41),LL(0xe54c35f6,0x73777848),L_(0xeecb8a06), + LL(0x27098970,0x27c35c5a),LL(0x88bff7c0,0xd3495797),LL(0x2aa31cbd,0x84083f2a),L_(0xee8007b7), LL(0xd736e6e1,0x7c2ce5db),LL(0x46d1faf9,0x7eccf318),LL(0x0d96af5f,0x7894ccc6),L_(0x143733e6), + LL(0x38e5c20b,0xf8d1a779),LL(0x74b4b8c0,0x1407c96c),LL(0xaa226358,0x0f677dc4),L_(0xbce88332), LL(0xae06373b,0xa1eff8f8),LL(0x6f4d4505,0x46e8175d),LL(0x37fa6b50,0x12414006),L_(0x078af83c), + LL(0xaa9911e2,0x6038786a),LL(0x043fa7bc,0x9ec4cf47),LL(0x39594053,0xeeffb86e),L_(0xf30130d5), LL(0x93573962,0x8e9bddbb),LL(0x6b822690,0xa5656b7e),LL(0xfd18acdc,0xf63c9ead),L_(0xa29c50ef), + LL(0x7a68f812,0x875129d8),LL(0x23706eff,0x43107ab7),LL(0x343d01b4,0x0f0278ce),L_(0xd1d2ff3f), LL(0x947dc2e4,0x62e80eed),LL(0x76f993b1,0xb237e733),LL(0xd8eb588f,0xc6cb2916),L_(0x3e93bfcf), + LL(0x2323cfa1,0x40dc414f),LL(0x02fc59aa,0x81bf9064),LL(0xf4b7afef,0x2f863790),L_(0xdf1eb2ce), LL(0x2da3a955,0xc2be20ad),LL(0x05119c9a,0x826e16e4),LL(0xa27da69d,0x59ba9dd2),L_(0x50be3370), + LL(0x702f4a30,0xe5b817ac),LL(0x62b0b4a9,0x732be8dd),LL(0x0b744a18,0x49eb11c0),L_(0xdb8066e2), LL(0x61315a81,0x60bc3f3b),LL(0x9db8094e,0xa033694a),LL(0x1a336970,0xe5728d57),L_(0x98764bb8), + LL(0xa31f05a5,0x471336b0),LL(0xc97e0c25,0xe1b3c5c4),LL(0x40016340,0xd00385b4),L_(0x8681b939), LL(0xf3dbd1c9,0xfb0504e6),LL(0x190db5e8,0xf84aaa64),LL(0x73d7879b,0x5e7d8612),L_(0x8f037a48), + LL(0x4bb632f0,0xb920e089),LL(0x81a11e46,0x5fd26f9a),LL(0xad7ce91c,0xd873ff38),L_(0x463f5eef), LL(0xe973b348,0xa997a44a),LL(0x67e4b48b,0x7c4b4d96),LL(0x76b8b69f,0xc007a35a),L_(0x0ebb0cc7), + LL(0x066bf5fc,0xc6331e3d),LL(0xd49fdc60,0x01bb84a6),LL(0x3f1c848c,0xae53c6d2),L_(0xa68e50ed), LL(0x64a19a00,0xa6271228),LL(0x1c7298ae,0x6345be32),LL(0x34a3a582,0x6666c91c),L_(0x1bb3ce87), + LL(0xe3fc9fee,0xabcce7ab),LL(0xfa1beb7d,0xdf35c272),LL(0x9cab965d,0x7c86ce27),L_(0x145e311e), LL(0xadb37a6d,0x3f4563ca),LL(0xbd40ee7b,0xc5e44069),LL(0x077a6fa1,0x6ab23a8b),L_(0xdc9e2258), + LL(0xe14e323f,0x27ccdc44),LL(0x8d1e93bc,0x9fd47cad),LL(0xac370974,0xf5fc7d6a),L_(0xbb95cf97), LL(0x3c654b26,0x65e7b71e),LL(0x0d3d8936,0x69b3aaf9),LL(0x6cfc89cd,0xcfd74f9d),L_(0x46c8cccc), + LL(0xe59aef1b,0x82c35cac),LL(0x4b6e4cd2,0xd343c61a),LL(0x5bf959ed,0x77b74152),L_(0x14153467), LL(0xabc9828c,0xc645fe14),LL(0x44ed7180,0x251c7bd5),LL(0xb00a2c9f,0x94c68e2e),L_(0xcd40eadd), + LL(0x90c9c5ec,0xdb397bc5),LL(0x0bb14c2d,0x0029fc46),LL(0x2727c32b,0xbdde6547),L_(0xf5120538), LL(0x8748603f,0xca65a20c),LL(0xb71dac7a,0x79d195d6),LL(0x7b4ac903,0xf1e5f556),L_(0x83bcccf1), + LL(0xd8d5a0e2,0x35177eb8),LL(0xb2a6346d,0xe17edde4),LL(0xcdb1c427,0xc5c607ff),L_(0xf6acdcca), LL(0x7045642b,0xf198276e),LL(0x5ddfa215,0xa8387d90),LL(0xc1a3402a,0xc070af80),L_(0x0cf324a8), + LL(0x89428955,0x4be4c6c0),LL(0xddf4319c,0x076b38c2),LL(0xcc96208b,0xd1d87cd0),L_(0xc3e2cfee), LL(0xb63b328c,0x1fa3dfb1),LL(0x89c310af,0xbcb33f40),LL(0xab955eb2,0x1e3849a6),L_(0x4e9da2a4), + LL(0x572060d6,0x4a409b86),LL(0x4a32be16,0x01fee4f3),LL(0x5593d29d,0x1f66b255),L_(0xa18a71de), LL(0xdc92993c,0x871121b8),LL(0xd5a52a49,0x2885efde),LL(0xdb77ca39,0x35178007),L_(0xe87f7b56), + LL(0xb0b54185,0x7b11bf25),LL(0x78cced92,0x5f580048),LL(0x568cf974,0x1aebc2f4),L_(0x90437303), LL(0x380e1852,0xe1d4cf60),LL(0x81708f04,0x335221a8),LL(0xfcd5e396,0xe8e310f1),L_(0x67164e9b), + LL(0x5cc646e4,0x4435eb3f),LL(0x309bf5d1,0xc4516a98),LL(0xfa094c38,0x0f0f519b),L_(0xa7712b6a), LL(0x063b90c9,0x13b443e8),LL(0x3fc80f73,0x588eabab),LL(0xc2640659,0x6f1b036b),L_(0xcc979824), + LL(0x15f68a6c,0x2c10fe82),LL(0xfd4280b4,0x4be94dbf),LL(0x0f01bc51,0x8ebbdd0a),L_(0xe8a94761), LL(0xf5c8cf6e,0x3331db35),LL(0xe9e32c12,0xee34fb22),LL(0xdfdd390f,0x7d9acfa0),L_(0xf46a833d), + LL(0x4db03d63,0xb1f7d640),LL(0x50d5c66d,0x77b9e67a),LL(0xd311bbb8,0x2df06964),L_(0x4d4065dd), LL(0xb1ba8be7,0xc5f2e7e7),LL(0xa84be5a0,0x3c7c5264),LL(0x704fb715,0x72ab97c4),L_(0xe211a72c), + LL(0xde6eb928,0x22e459d0),LL(0x262ef282,0x78e351ef),LL(0xcdae125f,0x400cd2e5),L_(0xc83f210b), LL(0x1982c6e5,0xb3e5fe6c),LL(0x87c8591a,0x13591995),LL(0x83fd93d2,0x072fa5b0),L_(0x7d701f58), + LL(0xae57420d,0x2dda42fb),LL(0xa6490705,0x0c8f6d52),LL(0x5e3ec836,0x974661b3),L_(0x77bc552c), LL(0xca185c95,0xf43d8647),LL(0x351407f7,0x3094919d),LL(0x93522ec1,0x2effc179),L_(0x49a92d02), + LL(0xad6aa522,0x1178f9fd),LL(0x88ddd25b,0x7c35a7b4),LL(0x4985102d,0x0d3de452),L_(0xf0277afe), LL(0x9952ce22,0xf3571744),LL(0x53a80f8c,0x33bbd8c5),LL(0xa11d84cd,0x8cf3c9a4),L_(0x7920692b), + LL(0x19d5d3aa,0x3259f507),LL(0x8dd2cea1,0xfaa534d0),LL(0xb1de59c3,0x964e43aa),L_(0xd9cd158a), LL(0xb8fe9ccf,0xf7812a29),LL(0x483a8ca3,0x5a40b462),LL(0xf93b681f,0xeafa2982),L_(0x22d0852e), + LL(0xccafe782,0x4e3898e7),LL(0x178b364e,0x122c0954),LL(0x1e46cbf3,0x07005a6a),L_(0x017cc249), LL(0x1f834707,0xe3d63870),LL(0x9df8269b,0x84c46f73),LL(0xf32797a5,0x1360de40),L_(0x70a39a32), + LL(0xe6611eb8,0x58005efe),LL(0xefaea42e,0x9d406314),LL(0xcdf53ee0,0x8d9f77b8),L_(0x2be3de21), LL(0x3152090c,0x219fc4d6),LL(0xdfbb4054,0x2e867eb0),LL(0x370b0058,0x0df48ecb),L_(0x67c50061), + LL(0xd35d5628,0x7d760756),LL(0x3cb96c10,0xaff6e332),LL(0x87378266,0xc87eb4e6),L_(0xbb1b1686), LL(0x719b7dba,0xf625cc5d),LL(0x7f6f6bfb,0xc5c21343),LL(0xd1702bfc,0xd7459a05),L_(0xb5757892), + LL(0x07b102d7,0x2285b7c5),LL(0x77777ad0,0x90a0453e),LL(0x2a9f4627,0xa5cb03f7),L_(0xbdaaa412), LL(0xd6bb4325,0x6fb99eeb),LL(0x8aa2c4b5,0xc61bae52),LL(0xec729246,0x9b9f8d87),L_(0x995887b7), + LL(0x714a54b4,0x786ccb7c),LL(0xae2ffd66,0x1df96294),LL(0xb5661480,0x0b294654),L_(0x42cc5e69), LL(0xc6f02a04,0x1634f1da),LL(0x21f0caa7,0x75d2244a),LL(0x80410ce5,0x6597b349),L_(0xb9e50c3a), + LL(0xd19e2b9f,0xbefea27e),LL(0xca541338,0x53b70277),LL(0x0bc9bd26,0xd300e1fc),L_(0xed2c5b84), LL(0x935f9273,0x731c6b5d),LL(0x10fed3e2,0xac105b56),LL(0x6d0357ab,0x30c7c4b6),L_(0xfdf04b77), + LL(0x32c68e8f,0x6198d0bf),LL(0x49f0ac87,0x02928249),LL(0x5908bfa6,0x2b72f231),L_(0x1e0626b8), LL(0x87d56448,0xb70c5fdd),LL(0xaffd0d74,0xc8176ae0),LL(0x30464156,0xbe7c0da7),L_(0xf7d2ffb9), + LL(0xffa548f9,0xd71029f6),LL(0x2ac8267b,0x5922838c),LL(0x4f8afc3b,0x2d787218),L_(0x10f9a786), LL(0xb358d2a8,0xf19c8b54),LL(0x5209c3c7,0xf590721f),LL(0x0212109d,0x4e16a382),L_(0x3cd77b54), + LL(0xef4b9410,0x4e89b491),LL(0x77501651,0x417ff9fd),LL(0xdbb5243c,0xd24a6908),L_(0xc09c5df1), LL(0x2c39f4c4,0xeb16d02d),LL(0xb28822ac,0x4cd4a553),LL(0xbf46b5bb,0xde8a18e1),L_(0x47566077), + LL(0x0937292b,0xa4a4f179),LL(0xdff0cf1f,0x01b86895),LL(0x34f0c71b,0x3fe5a3b7),L_(0xae1fff30), LL(0xe080e0da,0x95b01982),LL(0x5317a578,0x3064e918),LL(0x8872e118,0x154f511a),L_(0x28ad7f46), + LL(0x9dbd0087,0x3c4162c3),LL(0x88636424,0x58631293),LL(0x69f32e25,0xf3a9fd92),L_(0x049b5c0f), LL(0x8d93c391,0xd8613d4d),LL(0xcf94b297,0x74bd10f5),LL(0xf99f0a15,0xf6d69ab3),L_(0x8d722881), + LL(0x67ba729a,0x2829f720),LL(0xc6f3cc19,0x88fffa70),LL(0xf0c5f76b,0x0d44b294),L_(0xda7df6fd), LL(0x033be0dd,0x35516898),LL(0x4c9c487f,0x50dfac1a),LL(0x312edd81,0x14a64ecf),L_(0x2db649b2), + LL(0x4933ac70,0x4e65d480),LL(0x17bb4dfc,0x8f9141c2),LL(0x7b8827b2,0x6ffab99a),L_(0x788afe5d), LL(0x15192ba1,0x6ed82d80),LL(0x75adf2d6,0x7be9df26),LL(0x99ce22b1,0x957976c9),L_(0xf8f37372), + LL(0x2204ff70,0x3ad3db41),LL(0xa4617ca1,0x7ca2697e),LL(0x8f228ced,0xc881f9da),L_(0x86ddd01a), LL(0x6e35e7e8,0xd1467d74),LL(0x41eb80aa,0xa4eadfce),LL(0x875ce5dd,0xaf17e700),L_(0x398d4c2f), + LL(0x3e59ab08,0x165575cd),LL(0x7c2f636f,0x55e6cf6d),LL(0x89f1290e,0xeeb00b1e),L_(0x2cccc148), LL(0x264e5c6c,0x7200e28c),LL(0x5409cce2,0xaf2b4dc4),LL(0xf8e920e1,0x3586fdc4),L_(0x11976312), + LL(0xab519f43,0x45934ad0),LL(0xa0a5bb1b,0x0eda4d94),LL(0xbcff29b2,0x9f749e30),L_(0x2f73a7d6), LL(0x2a833e74,0x9ed5bbc8),LL(0x111b6548,0x83945e37),LL(0x7b77f3f9,0x9b568171),L_(0xf1563350), + LL(0x999312c1,0xbde3fb88),LL(0xaa153efc,0x4ead50eb),LL(0xf24dc769,0x91718221),L_(0x3207691f), LL(0x1445f929,0xa962b883),LL(0x8a1416f3,0x6db04bb2),LL(0x2992be20,0x388328fb),L_(0xa7c4a359), + LL(0x92efc55b,0x709d7f62),LL(0xf678058c,0x08e33ff6),LL(0x9db19687,0x8d882bae),L_(0x81afb521), LL(0x462b58d3,0xce4ef2a4),LL(0xc6ecf132,0x21f09167),LL(0xab9bbd79,0x3831d678),L_(0x4c11a697), + LL(0xda7c3371,0x8a72049c),LL(0xc3e5138e,0xc7decc6d),LL(0x9235657e,0xf870194a),L_(0xeddbefb7), LL(0x306c9631,0x85d843d8),LL(0x912ed2a5,0x27180693),LL(0xdb45568f,0x453cbf16),L_(0x410259cc), + LL(0x3f11cacd,0x10263ac7),LL(0x69fa2805,0xb832a378),LL(0x6120289b,0x86d5285d),L_(0xece730a0), LL(0xabd38f00,0xbf1197bb),LL(0x286f4724,0xdbbb1a26),LL(0x0b0ef425,0xf397181d),L_(0x24bb4f4f), + LL(0xe24a9a47,0x162331a8),LL(0x536a5ea6,0x2bfbcebe),LL(0x88c29411,0x3da5a14f),L_(0x9cb76097), LL(0x5145ce76,0xef6b8093),LL(0x59e86f3c,0xe0a56e13),LL(0x817764eb,0x58eed1b6),L_(0x8010fc3d), + LL(0x0b1262b6,0x9a5b60b7),LL(0x108b3068,0x14ec42e4),LL(0x1312c3e2,0x8dd4b81a),L_(0x0253e9dc), LL(0x253ff39b,0x5eadccd1),LL(0xbd75013a,0x87febbae),LL(0xc60daeca,0x20b2a500),L_(0xbea0d3fb), + LL(0x20482528,0xfb3fb2a4),LL(0x72db2c7a,0x3620dd94),LL(0x864ce0ff,0xe0956799),L_(0x2d7ec9e2), LL(0x86bb3cca,0xdfc7056e),LL(0x77bfd4dc,0xf75d4a37),LL(0x0f42ffde,0x110fb370),L_(0xf2040e52), + LL(0x38389a23,0x2100e0ba),LL(0x6fd68890,0xbf38ce28),LL(0x67978ca8,0xb3a94049),L_(0x279171ad), LL(0x4b5e0e0d,0x0230458f),LL(0x41165c1f,0xb73bda2e),LL(0x8eadb8c9,0xe9eaef42),L_(0x2345e24e), + LL(0x9fe296bd,0x41f15f29),LL(0xaa889c09,0x8ccda12e),LL(0x6adf563e,0x559edd7a),L_(0xdd414cb0), LL(0x84d15464,0xad8084b6),LL(0xbef296d5,0x3238cf0a),LL(0x0ee342aa,0x074068ff),L_(0xc9f3a4e6), + LL(0x374364db,0x4db1a4b3),LL(0x983e29af,0x190ecab8),LL(0xc26d69a7,0x8e174c76),L_(0x2739f19a), LL(0xea361aa4,0x4c902613),LL(0xcd082b89,0xbbc1e2c1),LL(0xa0661a39,0xd0352acc),L_(0x6d5bd738), + LL(0x6b165ee3,0x0f46deb2),LL(0xe05a9d3e,0xbaae3236),LL(0x68d899f5,0x2fcbd485),L_(0xd426fbf8), LL(0xfce9e8db,0x70b0b8e7),LL(0xbb075381,0x24c285b0),LL(0xeb323221,0x933c7339),L_(0x90f21e83), + LL(0xa437ec78,0x65c3ea6f),LL(0x26f5292f,0x16eebdc4),LL(0x2f10ff0d,0xd0e0dfce),L_(0xe59106aa), LL(0x47d3151e,0x334ef2fb),LL(0xe1d13288,0xa14975cc),LL(0xb2dd6c80,0xe941b704),L_(0x428af6d0), + LL(0xac3814f9,0xf4357fa6),LL(0xe9634ed9,0x3e28518f),LL(0x92f270b2,0xb8fe4e04),L_(0x4ce90044), LL(0xc454c0af,0x9137e5a6),LL(0xb5cf536c,0xff154124),LL(0xaa1f4551,0x0024f90b),L_(0x981784b9), + LL(0x9e485500,0xb04608de),LL(0x5269aa1a,0x6eb17af7),LL(0x8ce1ebee,0x3d279465),L_(0xc66381e8), LL(0x0b5ed745,0xc4fa7ed6),LL(0xdeb29303,0x601d19f0),LL(0x510a3c8d,0x2ce166ff),L_(0xaa227120), + LL(0x1c8b8392,0x992398c6),LL(0xa3c32177,0x98eae201),LL(0xcd19850d,0x70b1a326),L_(0x9505296f), LL(0x958225ae,0x41bcad26),LL(0x0d11515a,0x938c115e),LL(0x04883b49,0x5a5bf602),L_(0x72d1e180), + LL(0x597adc60,0x5898ed4e),LL(0x63896a2f,0xa9c6e64f),LL(0x82a0ed92,0x71349776),L_(0x71b9b0ee), LL(0x216fc62a,0xd360630c),LL(0xbd440771,0xa2285bdf),LL(0xa49907da,0x28e79328),L_(0xad498ec7), +}, +/* digit=21 base_pwr=2^147 */ +{ + LL(0x9dfbcf8e,0x5e338a94),LL(0x0324aba6,0x9f1b5252),LL(0x970769c2,0x32ea5aeb),L_(0x82c3b64b), LL(0xfeabe87b,0x80346bd1),LL(0x98111ddd,0x63f11cc5),LL(0x2ef9e31e,0x75819a03),L_(0x6e0e0fd4), + LL(0xead2c5e0,0xd481d37a),LL(0x676ef7cb,0x83660242),LL(0x6ddd542a,0x4bcdf56d),L_(0x0807b6ee), LL(0x88b2540c,0x99cfbaa1),LL(0x440a4586,0x92cdeb4c),LL(0xaab76f82,0x62bde53d),L_(0x31ca293a), + LL(0x88edf264,0x279a665d),LL(0xc73f3e56,0x4837e985),LL(0x51cce02b,0x925d55fe),L_(0xba48033b), LL(0xfbc2fa3e,0x3c3ccfff),LL(0x09219d1a,0xa32d9d41),LL(0x7bba7cbf,0xf5c59984),L_(0x1f9a5c08), + LL(0x1175b9ba,0x4079f189),LL(0x150e6d32,0xe9e1ab30),LL(0x8b6cc92b,0x2d425400),L_(0x274ec0c2), LL(0x8f0527d9,0x6d261b01),LL(0x4ef086f3,0x63cc5685),LL(0x29dec1b9,0x7f963f71),L_(0xea97e94e), + LL(0xd50b2092,0x9e517139),LL(0xf9867b99,0x32ba3680),LL(0xbd760d63,0xafdf07e9),L_(0xa9b6e9ec), LL(0x8b644aef,0x6d61dc07),LL(0x93df1b2e,0xe8d9afc6),LL(0x3387d03a,0x32d7f165),L_(0x759fb34d), + LL(0x41d99c15,0x08345264),LL(0x34f3b1e1,0x17c124bd),LL(0x20468107,0xc8425e31),L_(0xa035ed92), LL(0x19019adc,0x15129a66),LL(0xd78546b5,0x4c880bae),LL(0x2a03f320,0x04faf0ec),L_(0xf88d60ed), + LL(0xcbda1d0c,0x99a20d9a),LL(0x31f03c7f,0xc7f9c96f),LL(0xbdab0f5d,0xcfc1004b),L_(0xc665b5f0), LL(0x24cf476d,0x57bee516),LL(0xbaab1072,0xcf987028),LL(0x64de4da0,0xa4efa899),L_(0xb3c284d3), + LL(0xec9ac930,0xb6ef6e4f),LL(0x7bd6b2eb,0xf97982f6),LL(0xb87b9f50,0x3506344d),L_(0xe38cc59c), LL(0x0df2358f,0x98614bb4),LL(0x4daab44e,0xa73a33ba),LL(0x3957de53,0xc680567a),L_(0xcfa42f96), + LL(0x6e9aa82b,0xad09cde6),LL(0x89749594,0x88dae77c),LL(0x686f22a8,0xe7736848),L_(0xd741b21a), LL(0x9e20d489,0x08ab4cce),LL(0xb87c7bef,0xcc175c96),LL(0x982331fd,0x177b6473),L_(0x63140d6e), + LL(0xb3fe0b33,0x061731af),LL(0x785b32f1,0xdee055b2),LL(0xc296cafa,0x1de52e72),L_(0xb10ce663), LL(0xc5a7f1be,0xc6a06418),LL(0x50016567,0x1713586c),LL(0x4502900b,0x2c001a59),L_(0x450b28d5), + LL(0xcab8d38d,0xc5913490),LL(0x9e1e0ce7,0x343c325b),LL(0xc5f9091b,0xe7590273),L_(0x44739896), LL(0xee5b12cc,0x449da236),LL(0x3913a8d2,0xd0e8b775),LL(0xd9db43d7,0x0204d37f),L_(0xbcc28709), + LL(0xfda66aba,0x0ba00094),LL(0x00c25d60,0x034594b0),LL(0xb0ccb9b4,0xaecf0812),L_(0xebecd41b), LL(0x95fb80f1,0xe2cb6f9c),LL(0xe9f56be8,0x33f77310),LL(0xab12b176,0x77e2c3e0),L_(0xa7a303fc), + LL(0xaa4bbfa4,0x0ca6bd41),LL(0x829f1bab,0x9f37381d),LL(0xf8aa85f0,0x63a37ba6),L_(0xe64c6ed3), LL(0xb1db7703,0x9ba22c56),LL(0x14c74bf2,0x26369a5a),LL(0x57cdabdc,0xa2f36ff4),L_(0x69603458), + LL(0xd1e5c2d6,0x049ce7f9),LL(0xdda045cf,0x6a8702d5),LL(0xae642723,0x444a4ca8),L_(0xc9e8efd0), LL(0xbc74c0b8,0xee8ff912),LL(0xa5f0a182,0x7cacfd02),LL(0xf34c0a0e,0x0bdcdecc),L_(0xf174835c), + LL(0xad6aaeda,0x262941fe),LL(0x50dd89e9,0x052230cb),LL(0x52bfaad6,0x3d3651a5),L_(0x42da9f6d), LL(0x1803593d,0x72f24771),LL(0xfb5c67bc,0xf8d5c69c),LL(0x6f3ebdef,0xa8074e96),L_(0x5d95664e), + LL(0x3cfb3680,0xfbd1a191),LL(0x14bfa4e1,0xd4f7de76),LL(0xf38ce345,0xfcdb2abd),L_(0x45ebd21e), LL(0x1d84093e,0xb59f480a),LL(0x3957e934,0xcc218197),LL(0x7c1b8e5b,0xe4604f76),L_(0xc58f2c48), + LL(0xd2d407e1,0xc8a88d72),LL(0x21606f53,0x9385e572),LL(0xfba9c9f7,0xfb7d83f0),L_(0xf57dce48), LL(0x37eda284,0xfb80fd4f),LL(0xc8023a07,0xf3549107),LL(0x71a25cd3,0x7a9a0b44),L_(0xb3c48734), + LL(0x885801a9,0xf3798b62),LL(0x9856b7c0,0x08f77ad9),LL(0x04ab2722,0x471ef449),L_(0xe5f3587d), LL(0xc09f1c74,0x21b96d5c),LL(0xb0c73d23,0x5e2a228b),LL(0xa3366107,0x69323a1b),L_(0x759bf017), + LL(0x11492138,0x80978740),LL(0x4e3559fa,0x456876b0),LL(0xe7559081,0x56ad6e70),L_(0xdd9852be), LL(0x8ce4faa0,0x0e7594de),LL(0xe4523a8a,0x3999a1a1),LL(0x4a40d4e5,0x8ca5687b),L_(0xfaf902fd), + LL(0x854da328,0xd2ade9c1),LL(0x683ea003,0xb2369f45),LL(0x6bbf8ead,0x26a2a12e),L_(0x65fa7d53), LL(0x44971ebd,0x6154c3a8),LL(0xd7f809d8,0x9e3b11ad),LL(0x20ed9167,0x24d19af8),L_(0xa692a83a), + LL(0x26ad917a,0xd8e0ff42),LL(0x90e27172,0xd10a1313),LL(0xa90bf44d,0x8cb2abd0),L_(0x130d21df), LL(0xea4790cd,0xa3cb4c6a),LL(0x65186f8e,0xfd47c901),LL(0x0c9c373c,0x3514478f),L_(0x5307b692), + LL(0x80001060,0xd8568305),LL(0x34f0a25d,0x6a578b8b),LL(0x039f50cc,0x0eadf2ee),L_(0x6a3cf739), LL(0x8ca51f3b,0x6a9a2a61),LL(0x5c707fb6,0x92f53d4f),LL(0x22360abf,0x756df232),L_(0xa7a12676), + LL(0xa54ee092,0x232b0eae),LL(0xfac26fa0,0x2030a397),LL(0x91c0d8b3,0xc85b9885),L_(0xcd36972d), LL(0xf99f3cb8,0x2b28cccb),LL(0xa2197bb4,0xd5dc11dd),LL(0xb00034b6,0x22200d9d),L_(0x398b8d08), + LL(0x48067657,0x3e7e898a),LL(0x14230734,0x429f6872),LL(0x7bef4c47,0xe3a1abc8),L_(0xb3564180), LL(0xb41998c2,0xeed81406),LL(0xa7ce6e62,0xe40d75be),LL(0xf02dd5b1,0x9d22967d),L_(0xa3ff259d), + LL(0x669ca4f5,0x25d2230b),LL(0x2d777318,0x7178f19a),LL(0x80147bac,0x6f460f52),L_(0x22279805), LL(0x7e64abfe,0x20550e61),LL(0x7880c924,0x79d1e82f),LL(0x6428d5fc,0x9a19cfda),L_(0xd1beb76b), + LL(0xba10e2eb,0xe36b37d3),LL(0x5d87cbda,0x2be422df),LL(0x404781e8,0xc8f5e0fe),L_(0xa1bc9eda), LL(0xd68a56ff,0x23299058),LL(0x970d11fc,0x7d7df62c),LL(0x785e8445,0x8ed8b412),L_(0xbad1345d), + LL(0xea68889d,0xce7aa168),LL(0xd74f6437,0x77a09f9a),LL(0x1f1dc772,0xf497718e),L_(0x36827efd), LL(0x53f8a4a5,0x978b617c),LL(0x4cb29feb,0x11c9e4d8),LL(0x6a64b734,0xe04077a2),L_(0x86b8cf3a), + LL(0x81d83b84,0xed710d97),LL(0x3a39d170,0x9d798cd7),LL(0xef236d5b,0x0683a7e0),L_(0xb9141322), LL(0x295bb2f8,0x05109f73),LL(0xdade7c00,0xb994c8eb),LL(0xf251df45,0xc11452de),L_(0xb48e9a05), + LL(0xab19c0be,0x4aaf45f4),LL(0x17039bf0,0x12b12bdf),LL(0xb97b72ee,0x30ce8053),L_(0xa7a81755), LL(0xa5e18f4a,0xc81db67a),LL(0x80753cae,0x1c4a9982),LL(0xe3019a4d,0xd1c81400),L_(0x80f8c3da), + LL(0xeb75d498,0x165046c8),LL(0x030a06a1,0x232d37a1),LL(0x09c6053c,0x3932bda3),L_(0xcb39f998), LL(0x95de7723,0x87fe7976),LL(0x0499f81d,0x216feab0),LL(0x7ae298d0,0x2959c264),L_(0x1edb6b93), + LL(0x916476f9,0x6ab52744),LL(0xdc732139,0x45a91c78),LL(0xbd7da6c3,0x5ac1ef95),L_(0xe2e0217e), LL(0x874209cf,0x63f9997a),LL(0x5cecf1c0,0x9d1320f0),LL(0x5082d35e,0x7b11e2cc),L_(0x04cc9aa3), + LL(0x481e157c,0xfecff2a6),LL(0x4f8b44cc,0xa01ff932),LL(0xd783714c,0x9c0232a4),L_(0x90d1c36e), LL(0xad070ffb,0xbd5e004d),LL(0xf22c1c14,0xec3d0dd1),LL(0x77b24ec6,0xc4fac858),L_(0xf15be1db), + LL(0xa4425706,0xfa634b73),LL(0xc11ab7e2,0xe2196b67),LL(0x39a0b0f1,0xa62656eb),L_(0xdf5e8e89), LL(0x10e754f8,0x35af495a),LL(0x059e7fc2,0x8885a6c4),LL(0x5721bb41,0xfcc7a8b4),L_(0x18530aec), + LL(0xce8caf63,0x1efc0864),LL(0x7e7fb20d,0x45a5d6d7),LL(0x319cbee0,0x32603543),L_(0x216780a7), LL(0x728ec24d,0x771c5008),LL(0x332b0e8d,0x88a3ec11),LL(0x27842539,0xfd61d211),L_(0x176fee74), + LL(0x636c68f5,0x6d5e6c03),LL(0x8f5f36df,0x99e754bc),LL(0xff864830,0x04fc8d4b),L_(0x35ae923b), LL(0x8c2df569,0xd03159ad),LL(0x6c4574ce,0x802cc48f),LL(0x95e44ad6,0xecc940e1),L_(0xacd13e60), + LL(0xaeaeda46,0x24bc05c7),LL(0x55d8d9f7,0x6d33fac1),LL(0xba1700c6,0xb1dbe56e),L_(0x12671c92), LL(0xa3906992,0x7c873618),LL(0x28f4b581,0x5d43aa50),LL(0xc27395ee,0x31a82a43),L_(0x84bd2bdf), + LL(0x85fa613e,0x19e04eb7),LL(0xd6d7b2f3,0xacf5f895),LL(0x7d71e73c,0x5dd55589),L_(0x6b4ddaaf), LL(0x5cbbc28d,0xb3874051),LL(0xb395499e,0xf0404258),LL(0x56ce4cbb,0x5961b289),L_(0x2960f1ca), + LL(0x08af573f,0x739615c5),LL(0x72405988,0xdcdfa5f7),LL(0x03300371,0xe254b688),L_(0x6195855d), LL(0xe4e87561,0xd298a295),LL(0xf9205a13,0x156d1dbc),LL(0x11ffb781,0xe00ca07c),L_(0xd638a7b0), + LL(0x9e23a234,0x970fe955),LL(0x62d115d2,0x4374bbb8),LL(0x4db47695,0xb3652081),L_(0x6565367b), LL(0x49a6f033,0x53a17dff),LL(0xbb00a05a,0xef6118bc),LL(0xc7f0a623,0x2971e39b),L_(0x091d591c), + LL(0xde40fbc4,0x3c51221c),LL(0xd273fed4,0xda08dbf2),LL(0x7eaf4c1f,0xc3cadac4),L_(0x155b21cd), LL(0x8e6c2580,0x824bf439),LL(0x6d0eb93f,0x16f47b06),LL(0x2b5af50d,0xe79201e3),L_(0x50f56685), + LL(0x2cbaab9e,0xaf65e93d),LL(0x64cb8361,0xdcc125a4),LL(0x2b08724e,0x5d31d941),L_(0x128434b7), LL(0x11800db2,0xd87b7933),LL(0x6349bb61,0x41b8d379),LL(0x8eabd8ce,0x46f9abc2),L_(0xf5ec4590), + LL(0x226b273d,0xde41b0d7),LL(0xfcdd55ff,0x16980cb0),LL(0x5f8a8d74,0xad3ba05b),L_(0x5c84894a), LL(0x8dc5f338,0x1041454e),LL(0x7425541f,0xc1a5e43c),LL(0xf6c08550,0xbe1bce56),L_(0x48f611af), + LL(0xf3ceb53f,0x31e207aa),LL(0x505aaa25,0x7b5d7c2b),LL(0x9df3ed0d,0x6ff3aa7e),L_(0xecdfa689), LL(0xe6296cd5,0x4660e301),LL(0xaac1b188,0x8e86f81b),LL(0xe2709e66,0x1690d7e4),L_(0x9ad43bd5), + LL(0x31a8090d,0x9e4966d9),LL(0xe9803ed7,0x2923afcc),LL(0x94a51c0a,0xc6ffb2f1),L_(0xac8d73e5), LL(0x7e9362e3,0x87ee51c6),LL(0x0f2f29a5,0x9df72731),LL(0xcf07fe4d,0xf7993328),L_(0x11a086fc), + LL(0x366308d2,0x482c8576),LL(0x7008cc6c,0x04061b0e),LL(0x4ea34321,0xea139dd1),L_(0x0db793be), LL(0xd163362c,0x2f88c485),LL(0x46daeb88,0x20d2b379),LL(0xa9529777,0x8fc9a2fe),L_(0x685903b2), + LL(0x4733e75d,0x160fbbaf),LL(0x85dc20a6,0x8dfd433f),LL(0x40ce263c,0x33ee3772),L_(0xf18c955f), LL(0xbc745c54,0x7c56f68e),LL(0x629b2ed0,0x7ba316a5),LL(0xd3751f88,0x9be35b3d),L_(0x87658375), + LL(0x65718fca,0x4c71f19d),LL(0x2e6a930b,0x58ad9bf9),LL(0x6ce370be,0x9c7c9090),L_(0x9fe1a225), LL(0xd3e1755a,0xdfc19acc),LL(0xbc4095c2,0xeb61289d),LL(0x102343b7,0xa07aed0a),L_(0x75593f8f), + LL(0x892da157,0x6e87ec4f),LL(0xe6abe1ed,0xe3973fff),LL(0x32e1d48d,0x9c1aa3b0),L_(0xbc16fee9), LL(0x64341200,0x1a098c5d),LL(0xa549cfc8,0xabb4ca0a),LL(0xdccd7aa4,0xe2b2179c),L_(0xf0addee3), + LL(0xa357e9f5,0xec32e6a1),LL(0x4e4d505b,0x0d55532a),LL(0xd584c5e2,0x708100e5),L_(0xf05981fa), LL(0x9188d927,0xff71c065),LL(0x30b8c50e,0x099da401),LL(0xa5cf657a,0x00705bdb),L_(0x003593a1), + LL(0x634a3d0c,0x1e13fadd),LL(0xbfa0d04d,0xbc86e569),LL(0xcc81bd28,0x39bdb34f),L_(0x7ba2330c), LL(0xa09b0aa7,0xb5b45e68),LL(0xf331bfd7,0xf478e7fb),LL(0xdd8ec1b5,0xb3f734e7),L_(0x9064cd97), + LL(0x156f54eb,0x6a4afc5f),LL(0x4194a70e,0x4e2a403a),LL(0x523cff28,0x03d08e2c),L_(0xa27e7edc), LL(0x994e73a6,0xfc7c7e86),LL(0x38873c54,0xa0320256),LL(0x805abf3c,0x414e3976),L_(0x93991ee1), + LL(0xcf5e586e,0xa5d47503),LL(0xb3fe93fc,0xcd1bfca9),LL(0xb7d168b6,0x4a438e8c),L_(0x581ebd7a), LL(0xbbc7084b,0x1e7c3d14),LL(0x7749a42d,0x66b2f40c),LL(0x86e109ed,0x853c9b29),L_(0x069c5f0b), + LL(0x51236167,0x2fb43299),LL(0x2b3c8790,0x48986b12),LL(0xc7e0dd08,0x9d9741bf),L_(0x51f341ad), LL(0x9e792a48,0x6eb8a76d),LL(0x1cd0ce38,0x20f5141d),LL(0x2698a77b,0x3099a97a),L_(0x6b8968f5), + LL(0xdcec6ecf,0x5f3a4ac2),LL(0xf86e098a,0x8c8b8e0a),LL(0x3194f379,0xc98e48aa),L_(0x886d05b8), LL(0xe568b10f,0xbd9be136),LL(0x488df6bf,0xa20174d8),LL(0x9833b00c,0xfb9f6810),L_(0x5fb8ce68), + LL(0xb887fe68,0x0996c579),LL(0xe74e34d6,0xdd48ea52),LL(0xbc8f1cc6,0x49ddbd76),L_(0x3e421dda), LL(0xd57b1ea4,0x2fcb399b),LL(0xf599d67b,0xde52325a),LL(0x1de7c3a8,0x60ffdfcb),L_(0x41018e1d), + LL(0xda8c07fc,0x5803c900),LL(0x1834f6f5,0xab321f3b),LL(0x0269aa98,0x51b8942e),L_(0xbd9cdd7b), LL(0xad131077,0xf11dba7e),LL(0x62d1e404,0xf313e57d),LL(0xa355486e,0x3e7a1a96),L_(0xa6d151c2), + LL(0x7855f86c,0x5bfcbb65),LL(0xd3cf6d12,0x06e90560),LL(0x509c593c,0x36beb1c6),L_(0x50bb9be7), LL(0x89a08a0b,0x461e9080),LL(0xf6ebcef8,0x278adf68),LL(0x53fb4ce1,0x1d3a4bb3),L_(0x84afbe92), + LL(0xda5ddb0e,0x36690883),LL(0x66809ebd,0xa2cf5571),LL(0x6d7b75a0,0xb7561328),L_(0x7a0b342b), LL(0xdbdf8401,0xc6b75bd0),LL(0x8b464a87,0xbcc0ebce),LL(0x145091bc,0x33cace99),L_(0x723fe6fa), + LL(0xcfc2a3f9,0xfa386bf6),LL(0x5ea0874e,0x7749b51c),LL(0xa8387298,0xbc4e6a04),L_(0x02c73e59), LL(0x42c5707c,0xa4b7c2f1),LL(0x2fdbbf21,0xea7c0fdd),LL(0xb933bbc7,0x874e47bf),L_(0x4c88b532), + LL(0xc90a29b6,0xb79dad0a),LL(0x94b27e28,0x833287b1),LL(0x47dac83a,0xb3a5c35a),L_(0xace3bd6b), LL(0x318b5daa,0x0d91b2e7),LL(0x00f91b6c,0x2490c7d0),LL(0xd6d7f96d,0x390f1d25),L_(0x92ea6b8b), + LL(0x4f12bc87,0xa7f8fb95),LL(0xf0e6068b,0x6fd2151b),LL(0xed56b92b,0x64cd2ac4),L_(0xd3d78730), LL(0x6abfc96c,0xf0d95041),LL(0x8db9e812,0xa3638d2c),LL(0x6447eba8,0xd45b6fa7),L_(0x3b769af7), + LL(0x54f9cda5,0x26f167e9),LL(0x8aa2617b,0x869821a5),LL(0x52ead3d1,0x41988291),L_(0x5273a693), LL(0x32358d32,0x18ca4d80),LL(0xb1bbd253,0xb8619557),LL(0x58878e33,0x64d8aee8),L_(0xe8908e43), + LL(0x64ed9a67,0x5a517622),LL(0x6d83d019,0x742a30e3),LL(0x969711c0,0xa7fc9902),L_(0x225d81d7), LL(0x8b9e5575,0x25981f3f),LL(0xe02b87e7,0x78b544b4),LL(0xaec410d7,0x35630262),L_(0xb1115eaa), + LL(0xb95b1070,0x83f05d8d),LL(0x4dc83cf2,0x225fcf2b),LL(0x523db1cd,0x09d299d6),L_(0xe968d6f7), LL(0xb132ecd5,0xa5406081),LL(0xc545ab6a,0x645c2ab4),LL(0xcf6e254a,0x592bcabb),L_(0x599530e8), +}, +/* digit=22 base_pwr=2^154 */ +{ + LL(0xda598881,0xa46f08d8),LL(0xb9fe1aa5,0x4cf987a8),LL(0x32c26e96,0x1b37edc0),L_(0xcc6e653e), LL(0x8ea05891,0x37d78fa4),LL(0x44dcd6fa,0xb6453df3),LL(0x637ed305,0x72834a3e),L_(0x6cab1cc9), + LL(0x1ff1de02,0x2efe30a1),LL(0xd9e804cc,0xfc2c0f38),LL(0xb9c440fa,0xb6ba8131),L_(0xd2f7d77a), LL(0x60e1b4f3,0x88842b69),LL(0x96f7f20a,0x008db8f2),LL(0x9a618fff,0xf13ceac5),L_(0x6577f60c), + LL(0xd0b89306,0xbd482556),LL(0x1653fafd,0xc3361427),LL(0x39c09ddd,0x10b62eeb),L_(0x79f6d014), LL(0xd744c03c,0x78d81b00),LL(0xe8963c96,0xec51067e),LL(0x8c8f6a4c,0x63b70385),L_(0x551fa28d), + LL(0xf611c717,0x433a33e9),LL(0x2417a7ce,0x5f8001f9),LL(0x1d9155b1,0x7a6ca298),L_(0xd78e16eb), LL(0xc11dfcf9,0x3ab289c1),LL(0xee48adb0,0x14996507),LL(0xc998c5c9,0x8dd6fbf2),L_(0x959f66af), + LL(0x82c3a705,0x23a0b239),LL(0x63c09a4f,0xa1f25d1e),LL(0x021b685f,0x7c69331c),L_(0xb1b0820e), LL(0xf86bcb46,0x81992f9e),LL(0x370cbdbc,0x0d158241),LL(0xeecaf1b3,0xaeba071a),L_(0x5ebd44d9), + LL(0x17d040bb,0x193df858),LL(0x7a008e70,0x858d93f7),LL(0x8d7ec281,0x81377001),L_(0x3062b2db), LL(0xffd70fd5,0x11e91ce3),LL(0xdb62847d,0xf3cecc63),LL(0x9a492d59,0x42b1e033),L_(0x3c5e448f), + LL(0x9609b50b,0x48abe62e),LL(0xf00a790d,0x5b827b1e),LL(0xe9c56ab8,0xcfc6643d),L_(0x7a101d9e), LL(0x63e008bb,0xe901d5c6),LL(0xc8b5cd29,0x26d03ac2),LL(0x5a6c0d3c,0xf3eacfba),L_(0x437c7e62), + LL(0x42de8327,0x7ef25e15),LL(0xc3c0b7b4,0xf84d2f14),LL(0x2d411980,0x9d372287),L_(0xb86b3e9a), LL(0x7f225094,0x6682e29b),LL(0xc7ddb5da,0x7638e99e),LL(0x80ad8746,0xc5272ca9),L_(0x67e42112), + LL(0xb19ef327,0x2db21213),LL(0x26d65fa2,0xa797a69c),LL(0x27bc92ce,0x780c1507),L_(0x62bfbfb4), LL(0x02fe91fa,0x90f53f41),LL(0x306b2065,0xd9ad25ed),LL(0x70add874,0x97f0fe05),L_(0xef3f82de), + LL(0xf3beb3c0,0xdb734eed),LL(0x49ac57da,0x4035d15e),LL(0x0575235f,0x12e6b4bb),L_(0x84ba90a7), LL(0x2a740735,0x2e72cdc8),LL(0xde178a6e,0x32f40243),LL(0x2c8f9b53,0x04316bb2),L_(0x4d9021c4), + LL(0xbcf71c73,0x4a88c71f),LL(0x7c1da7fb,0x646fc8a7),LL(0x7be262ad,0x26f4415e),L_(0x8d16df29), LL(0xbe32e30e,0x6e047967),LL(0xf7050746,0x935f128c),LL(0x40048ee7,0x671c053f),L_(0x7e714450), + LL(0xa89d04f2,0x126208fb),LL(0xc3f913fb,0xcea88f22),LL(0x81ebbd24,0xfbf9d09c),L_(0x60be0397), LL(0x554a7a99,0xab78592d),LL(0xee7a8b54,0xbca7876a),LL(0x58636e68,0x5cb0cea7),L_(0x56d9eb18), + LL(0xf22ebb87,0xe2adb3e2),LL(0xe08bf721,0x9944dfb5),LL(0xcf7b1348,0x88809e01),L_(0x9dd0883a), LL(0x57335ddf,0xfb2d7aec),LL(0x9e8ac3f6,0x91eff023),LL(0x3aa9be67,0x87a97238),L_(0x56210cb7), + LL(0x88f902c7,0x515e6712),LL(0x989ff215,0x47c3afa5),LL(0x8011a541,0x16b0e517),L_(0xc8b38bfd), LL(0x4bc31c65,0x23c98753),LL(0xc13358b8,0x3b82c767),LL(0x5edc147b,0xae944131),L_(0xbf36526b), + LL(0x8561f47c,0xbb74f4a2),LL(0xf57da9fb,0x4788db1a),LL(0xe6c34f9a,0xae99e920),L_(0x72b76a37), LL(0xbdc2a795,0xd46a4b66),LL(0x377b9f4d,0x1b102f7a),LL(0x2dbc27cc,0x1c0d51f0),L_(0x63d0ccbb), + LL(0xf20ce9cb,0x76b14e73),LL(0x5173ac48,0xe87b13ab),LL(0xac29f6c0,0xde2af466),L_(0xbf4405a4), LL(0x5cd87093,0xe0a96171),LL(0xc72bdfba,0x6f175bde),LL(0x14f78dd7,0x2c991165),L_(0xf55ecef7), + LL(0x94e2d286,0x6d393d5e),LL(0x05e626ee,0x250d4b04),LL(0x225ed4d7,0x53d41ea6),L_(0x5d5b37e5), LL(0x6770d691,0x70c4e492),LL(0xf4527dfb,0xdeeb2466),LL(0x1522deea,0x333509e1),L_(0xad711cce), + LL(0x5bd9660b,0x072fecfa),LL(0xba0c11d9,0xeac96039),LL(0xa6fa784d,0xa105395f),L_(0x3a914aba), LL(0x7ecb3cf0,0x5b5ec37c),LL(0x6c8c0e8b,0x8123cd86),LL(0x79696f79,0x69daa4dd),L_(0xbf1748ba), + LL(0xa78decff,0x16919c0f),LL(0x43014c2d,0xfbc474bc),LL(0xd14b6a12,0x6d705b75),L_(0x395d7526), LL(0xa7378944,0x4c3aec7f),LL(0x3f4fd283,0x8737fb98),LL(0x4114b4f9,0x6a63c71b),L_(0xcf962aae), + LL(0x99ce3cf2,0x085cede3),LL(0x39a2603a,0x87ec3837),LL(0xb203a75d,0xbdc1e809),L_(0xf3640f89), LL(0xd93d4aae,0x8d9d5264),LL(0xd480817b,0xd455e58c),LL(0x8492b58b,0xe3368ba5),L_(0x24b8bfe6), + LL(0x5ec2512d,0x64ef9737),LL(0x6907b7bc,0x78d38667),LL(0xf6e9c509,0x33b42737),L_(0x55ab9706), LL(0xfaa748d1,0xf586dde6),LL(0x76b6d961,0x154becfd),LL(0xad1c2111,0x13031322),L_(0x1f36dd8c), + LL(0xa1af32ba,0xe83a229c),LL(0xe6ae70d0,0x4ec7d7fe),LL(0x5b9ca0d3,0x06479e73),L_(0x17cdf808), LL(0xad7c2138,0xd020f0ab),LL(0xca397995,0x85bbbbc2),LL(0x70369103,0x3d37e46a),L_(0x67d7bcef), + LL(0xb1610c52,0x920986d3),LL(0x9e2b8580,0xbe1fdaa6),LL(0x1a1086a7,0xf038b9fd),L_(0x76630d46), LL(0x62b5dc1c,0xf2780d63),LL(0x479ba46d,0x97c26f70),LL(0x41a1c690,0x953b6640),L_(0xeee5927b), + LL(0x50cfff54,0x7a6dcf7f),LL(0x2905feea,0xd9932f1f),LL(0x5bba1fd8,0xd274195e),L_(0x596a73e6), LL(0xd4297f7a,0xfa2e2812),LL(0x83723184,0xc5b16141),LL(0x21f09629,0x7ce090e3),L_(0xb6dc2849), + LL(0x7d63db18,0xb254b1d4),LL(0xfee577f0,0xaf830093),LL(0x6accfc0b,0x775f693f),L_(0x483bf6a8), LL(0x0e851bfe,0x74582d9f),LL(0x6731bfc7,0x7ffa6bf2),LL(0xf7d39569,0xa67faa6c),L_(0xc9418804), + LL(0xf9316a6d,0xb5eb4f28),LL(0x7a12fe1e,0x8cfe6abf),LL(0x4a7fc70e,0xd820b6bc),L_(0x319719c3), LL(0x54fb2143,0xbd26f428),LL(0x66648099,0x64ab8443),LL(0xb662d063,0x7fbe15d7),L_(0xf16d93b4), + LL(0x0457afa4,0x951453e4),LL(0x8f99c3ae,0xfd74995c),LL(0x422aab2c,0xec8547fb),L_(0x73be771b), LL(0xe916d5c5,0x49e82e71),LL(0x7b15c573,0x3a725205),LL(0xaa7e7ca5,0xfd867aa0),L_(0x58e19238), + LL(0x31434cbf,0x31e49c5c),LL(0x2d0ee2e6,0xaf660f6c),LL(0x3aaf91fd,0x271cbc87),L_(0xcb833e79), LL(0x520b6d31,0x36952e46),LL(0xf7a6bc06,0x6695996b),LL(0xda163497,0x1f6ccb97),L_(0xb5f271bf), + LL(0xa5259a0d,0x606962f8),LL(0x82d18205,0xf314ac21),LL(0x4a97cf98,0xde06a403),L_(0x23969744), LL(0x43ff18b9,0xba5e083d),LL(0x22229508,0x3789db89),LL(0x376f004b,0x1c53a79e),L_(0x8ecb5e4a), + LL(0x3757ad7d,0xfde8f5af),LL(0xdaab7a45,0x313f26c0),LL(0x6cba2e40,0x0b7de7e1),L_(0x31db2861), LL(0x90144bb6,0xf98e6b34),LL(0xa8d3e811,0x0ec080af),LL(0xc4961d3b,0x4bad9114),L_(0x10d64cdd), + LL(0x1ff6dfd6,0xadd9fbd0),LL(0xca3624bb,0x4c069f73),LL(0x73a43aed,0x91301b03),L_(0xc382f632), LL(0x9d2aab1b,0x83cfddff),LL(0xf9e8d9a9,0x66a4ad61),LL(0xb9fbd92f,0x25a8b014),L_(0x760229d4), + LL(0xc29bf199,0x95ce63b8),LL(0x225d1531,0x1e469d80),LL(0xf1862d72,0x143d1930),L_(0x89faba0c), LL(0xac073163,0x36978268),LL(0x2f3bfacc,0x077ad847),LL(0x8ecd6948,0x817ba1fc),L_(0xad14a0f1), + LL(0x4b5edd16,0x9cf6404b),LL(0x0fcc7993,0xf9fdd94b),LL(0x94227ce7,0x36c49b8b),L_(0x1add1a97), LL(0x06eb3245,0xddf10442),LL(0x478ddbe9,0xd0e75910),LL(0x598d307b,0xa7d77b58),L_(0x7c2d4285), + LL(0x640b82b6,0x6ae40efb),LL(0x7296f54f,0xc265b407),LL(0xbb8c6473,0xa3248f4d),L_(0x096d9531), LL(0xb52d1b77,0x72de2ce6),LL(0x71d14af5,0x2df2b5bc),LL(0x8bb3132f,0xd5a9918e),L_(0x1ee08068), + LL(0x7efa31af,0x3a3e84c4),LL(0xdb4c764e,0x41d38660),LL(0x06967d91,0x9a2fe8e7),L_(0x3d0cd72c), LL(0x81428c4a,0x663d93ab),LL(0xd9a81336,0x463057c2),LL(0xe092d510,0x7d2f5c90),L_(0x45eb443a), + LL(0x482cdab4,0x29b44f02),LL(0x09859196,0x88f3dd7a),LL(0x274e7582,0x8a9337d3),L_(0xe9cba9ed), LL(0x30787ea1,0xab1d6ae1),LL(0x1aa44fa6,0x72445ee4),LL(0x8201c08b,0x2f9c1703),L_(0xd128d342), + LL(0xdf8f55c0,0x04dbb488),LL(0x4b130afb,0xa603695f),LL(0x010d7b25,0xf211bcec),L_(0xb7f03740), LL(0xf354eee1,0x24a2aec6),LL(0xf116e286,0x473d0ffe),LL(0x4b6af9fa,0x974e5b38),L_(0x19cbf327), + LL(0x3d701f1c,0x8816e065),LL(0x52f1347b,0xd04d2137),LL(0x733b5b5e,0xe33961b0),L_(0x8db340e4), LL(0x02cb30d8,0x8fdad9c6),LL(0xb3cc8f09,0x63fea3f5),LL(0x36371a82,0x36432409),L_(0x9dd5d017), + LL(0x3ac09ce0,0xc45e9f48),LL(0xce25491e,0x0b828bf6),LL(0xf8ea793c,0x27eb6c22),L_(0x6371b206), LL(0xb1d7932a,0x80e32e78),LL(0x61eaf6df,0x8cf6f356),LL(0xdc4f44ca,0x387b7804),L_(0x4b85bf6e), + LL(0x1b431c86,0x2c7dc474),LL(0x18a6a123,0x6c31f68d),LL(0x53665bca,0xaa43dbfb),L_(0x8d40fe26), LL(0x7d646aab,0x6723ea8e),LL(0xbade3e08,0xcd9dea27),LL(0xc7adbb73,0x2f3a4dc9),L_(0xa74a2565), + LL(0x7fa9020f,0x9ab672ef),LL(0x9cc7bfa2,0xa0040dfb),LL(0x2ac7eb07,0x368be66e),L_(0x5665ccf4), LL(0xba527a40,0xb250a7ab),LL(0x465d7f98,0xa9c591cc),LL(0x8d2b97aa,0x7b979097),L_(0xa50d476d), + LL(0x4b3aef47,0x8b68fb1a),LL(0x542fb7f1,0xadc18f71),LL(0xd96b7a34,0xb020cf53),L_(0xdb72531d), LL(0xdf800c86,0xc73ecdcb),LL(0x1c4cd34a,0x47adcb2b),LL(0x039494e8,0xd23f79c7),L_(0xa21edcfd), + LL(0x849075c6,0x17c4dc71),LL(0x5ce9dcb0,0xe5cdb7bf),LL(0x25936d77,0xebe08b04),L_(0x70fc7789), LL(0x25213d26,0x7f3546f4),LL(0x7563a201,0xc56c68df),LL(0x10bfdb20,0xdb570af0),L_(0xeb5d3434), + LL(0x106086c7,0xef345020),LL(0xd0e87d76,0x18e51b40),LL(0x222e0b10,0xe86e0a88),L_(0x6fa3b5c9), LL(0x410e6c90,0x9da8796a),LL(0xabdf6b2a,0x4fe0bb39),LL(0x7ead1796,0xbbc76905),L_(0x8c71560c), + LL(0x7da50c4d,0x890d8ce1),LL(0xb5cc05b2,0x2a181e5a),LL(0x7de1e29b,0x866cd575),L_(0xfc749a26), LL(0x41ec00b6,0x7eaa0bb5),LL(0x886271b4,0x2328a91e),LL(0xed069b46,0x65bd26ca),L_(0x2f59240d), + LL(0x4df1cae4,0xd954621f),LL(0xcbae178c,0xdf03015e),LL(0xe71c4857,0x70950b7d),L_(0xc8f7ab52), LL(0xc0de4c81,0x52a1a22d),LL(0x24d86b6f,0x23da02f5),LL(0x70b94a09,0xd450bfb1),L_(0x0d983cdd), + LL(0x3e6f9967,0x5619c34a),LL(0x77d8a74f,0x47b1c13c),LL(0x71f4dc89,0xfa0612da),L_(0xb127ccb2), LL(0xcca647d0,0x879fb15f),LL(0x205b4589,0x5e51a2db),LL(0xe8b6c8f4,0xaad791a8),L_(0x1490d5ca), + LL(0x1b020bba,0x32c5bb8f),LL(0x28810885,0xc2383a3f),LL(0x2ceffdff,0x14a9a0ad),L_(0x7970ea64), LL(0xc1169c12,0x8708e80a),LL(0xbbf83ccb,0x5a067425),LL(0x5cc8baac,0x800c8eba),L_(0x98c8b359), + LL(0x8f103cfd,0x22c84664),LL(0xdbd93971,0x993bf6c5),LL(0x697a6de7,0x6f50eaa6),L_(0x87cb9042), LL(0x9314a935,0x5f70b39d),LL(0x2af4f24a,0xc319862f),LL(0xd8a16a0e,0x8f4571e4),L_(0xa7b9ed81), + LL(0xf4ec13c6,0x6e1de980),LL(0x725de358,0x0fffcef7),LL(0x85652ca3,0x50b9f863),L_(0xd5f0033d), LL(0x312ea9c7,0x19c015bb),LL(0x948391b7,0x92417df8),LL(0xaf6e5ed6,0x33c66538),L_(0x96bfa703), + LL(0xab942a96,0x069d03c0),LL(0x47f60293,0xc848a1bd),LL(0xc32780f6,0x3bfeba8e),L_(0xc2e0eb4e), LL(0x4521b895,0x29bd4112),LL(0xc233f03a,0xe259118f),LL(0x574da3b6,0xf4f6a7ac),L_(0xae0e0260), + LL(0x16cf432a,0xbb8f2924),LL(0x5a087018,0x455c67ee),LL(0x8c5485dd,0x351ad0f1),L_(0xf7d7679e), LL(0x318e4ede,0x2bdc4896),LL(0x277bcf81,0x8b26b0fb),LL(0xf147c5b4,0x87185cc7),L_(0xdf48c9e6), + LL(0x196afebb,0xdb75cc0f),LL(0x17222dc7,0x225c2aa1),LL(0x3dd256a1,0x3a012a3b),L_(0x7ec5696a), LL(0x25bf2c5f,0x9381bed5),LL(0x4f4cdfd3,0x0f7e0324),LL(0x7b5b13a4,0xbf5f2e84),L_(0x2639cce3), + LL(0xf2e480ae,0xdb334a58),LL(0x6da64943,0xe10cd107),LL(0xfce96a35,0x6ad5dfad),L_(0xa599a89e), LL(0x26a35a0e,0xeddc6625),LL(0x2ef746d1,0x5f6fe79f),LL(0xa912c3f0,0xd6859ab6),L_(0x1ac3aba5), + LL(0x705906c9,0x0e5c7c8c),LL(0xb050ceeb,0x5f2aa907),LL(0x53e4bd2f,0x710688b3),L_(0x19a215e7), LL(0xb2485b2a,0x9a042c99),LL(0xd22cc140,0xf04c2421),LL(0xb5f7e2eb,0x7f1f59f8),L_(0x154453dd), + LL(0xc0354be0,0x9473341b),LL(0x9f33393e,0xb5b4c257),LL(0xb3dc51a3,0x09fb2116),L_(0x0ee5b84f), LL(0x3e9814a0,0xf91ac675),LL(0x816d6ca6,0x506f79fd),LL(0xc0c5edef,0x0cfcd5ed),L_(0xb71c05e5), + LL(0x400799f5,0x17c9bd2a),LL(0x4c0897b1,0xd4538ae6),LL(0x7a16a169,0x0f41e0dd),L_(0xa88a35f1), LL(0x4037d80f,0x5e5fc718),LL(0x85b8baf5,0xee15dcea),LL(0xd33b70cd,0x5dd4f3b8),L_(0x5ddf49c1), + LL(0x0095bcdb,0x795a3892),LL(0xedb3e7f2,0x6c1761f4),LL(0x33c80575,0x26818153),L_(0xf7414144), LL(0x943d7d31,0x6f311ca0),LL(0x24d6e452,0xe928eca1),LL(0xe7193165,0x66d1a963),L_(0x89fa62a1), + LL(0x8faef020,0x375aa47c),LL(0x70c638b9,0xc033edb6),LL(0xf167acbd,0xddf9d01a),L_(0x364bf41a), LL(0xf8bb63ab,0x7d82f66c),LL(0x8862080b,0xedb30cf7),LL(0x0448ac9c,0x4dbdd638),L_(0x971eaebd), + LL(0xad55ab2a,0x30f6e053),LL(0x4b4739f2,0xa878cbee),LL(0xd62b9aef,0x3bbafe26),L_(0xb84b80ac), LL(0xc8ef692b,0xd03fc3fd),LL(0xb6803cd9,0xe63bac37),LL(0x81afcd95,0x205a14b1),L_(0x7a0ade0e), + LL(0xff50050c,0x2d735063),LL(0x4b1c54dd,0xab849fa5),LL(0xda4629d6,0xe95c14ae),L_(0x6f216326), LL(0x74ba5b90,0x2fae20c6),LL(0x3112101e,0x5e3d1209),LL(0xbce52748,0xfcd465ea),L_(0x53fd0b9b), + LL(0x2d491553,0x068c0d92),LL(0x1f9856a8,0x37cee3f9),LL(0x3408da24,0xc9b9b412),L_(0xc63b4cb7), LL(0x74b30760,0xb7836b39),LL(0x200fd925,0x339dec72),LL(0x55a6ddf0,0x2b7f407e),L_(0x0fb2a9d1), + LL(0xa824468a,0xe36962f5),LL(0xfae22eee,0x0a42cdab),LL(0xfe866c3e,0x8acadf81),L_(0xa3f599f7), LL(0xcdd076d7,0xe8b6b61e),LL(0xb4b13551,0x46d40c51),LL(0xcdd8f22e,0xb9099888),L_(0xe1b8ed2e), + LL(0x60051d31,0x7e8f146e),LL(0x3818b39f,0x4cd2aa83),LL(0x16886905,0xf677bde6),L_(0x022ae138), LL(0x98b45d19,0x5746a458),LL(0xacf62d52,0x70f9fca7),LL(0x63279bc6,0x4ee46705),L_(0xfd285b9c), +}, +/* digit=23 base_pwr=2^161 */ +{ + LL(0xf0d700ae,0xbad78996),LL(0xc931bee3,0x1b3ef234),LL(0xe3c1a2d8,0x7cd507de),L_(0x58fc32e1), LL(0x83e229c6,0x01135f5f),LL(0xfb8b7b35,0x8d5e43a4),LL(0x413750b4,0x2dffb3fe),L_(0x6a265953), + LL(0x8c78030e,0x796bb2af),LL(0x56c1932c,0x7d56b42a),LL(0xf443c29c,0x6ff56bc3),L_(0xbdd22bb5), LL(0x95857542,0x21178547),LL(0x22575d25,0xbdc732f6),LL(0x7ffb29d7,0x4ffc71d3),L_(0xd6ef14c3), + LL(0x3a92228c,0xbc9613ab),LL(0x5920119c,0x304f1f53),LL(0xc3d2b2e2,0x9633ba13),L_(0xe7d31665), LL(0xc95ebff4,0xe622933c),LL(0xec5df7bb,0x9abfde78),LL(0x50f7f156,0x7feb42b1),L_(0xeb17ef8e), + LL(0x25b9b992,0x1a08721f),LL(0xeeddf997,0xbf152cb2),LL(0xb6ad560a,0x3c761d64),L_(0x52dd9f57), LL(0xc0d79f78,0x39b5966e),LL(0xca15f167,0x562740a0),LL(0xea78b847,0xd9642afb),L_(0x37eea476), + LL(0xd57560f1,0xda4b72e5),LL(0xa3072640,0x68c344ac),LL(0x36a057e0,0x4754e3c5),L_(0x4faa9820), LL(0xe786962f,0xf20160bd),LL(0xa80ee38d,0x77ea80d1),LL(0xc8e173dc,0x665dbf2e),L_(0x2aba1be0), + LL(0xb6e8e52b,0x228ed7a9),LL(0x2d501abf,0x5d4bca44),LL(0xe4f5d2f6,0x3dad807b),L_(0x0b4aa28f), LL(0x006c4c0f,0xe672b21f),LL(0x0888b653,0x614c5f64),LL(0xa3e477ae,0x226f83cd),L_(0x0afdcedc), + LL(0xd5a1f5d3,0xe7476654),LL(0x562eb536,0x7a0ad378),LL(0x7f5bedc0,0x2887f756),L_(0x8581b7e9), LL(0x9986fd24,0x160c3504),LL(0xdde60b62,0x06b5ca84),LL(0x8a8ca29b,0xb94770da),L_(0x3ecfeca1), + LL(0x28c355ca,0xb615d5a7),LL(0x8ea9ecfb,0x2c8d2d4f),LL(0x6be624fe,0x7f81ee5d),L_(0x45035a93), LL(0x97611fa5,0xc3d23100),LL(0xe9c562fc,0x3ccce59a),LL(0xf451c22a,0x6ee17a32),L_(0x932ddcfa), + LL(0xfa127ca0,0x6337e908),LL(0xe970ce2d,0x839c1246),LL(0x58d5ae88,0x253afb1a),L_(0x88db9fe4), LL(0x4550894d,0x3d74de43),LL(0xa90b033e,0x46e1ab37),LL(0x132dd86c,0xed163aa4),L_(0xc88fa0d9), + LL(0xf244b8ec,0xa0e34d4b),LL(0xa5b69894,0x9ac53a57),LL(0x495e2cc1,0x987653cd),L_(0x5e895b41), LL(0xf2fd1824,0xf289cc20),LL(0xc41882ef,0x6ce96956),LL(0x3329b3be,0x4acf73b8),L_(0x9efd2db0), + LL(0x3bb5fbc8,0xdd8e91ba),LL(0xf8f6f870,0x8acac0fe),LL(0x728bf4b5,0x93d4067d),L_(0xb9c4891b), LL(0xaef29279,0xf8bf9b95),LL(0x1e5e8506,0xdf786531),LL(0x11821ebf,0x99083ad2),L_(0x7e9d0c84), + LL(0x83dcfec2,0x85547390),LL(0x48ab6926,0xc7ed1aa0),LL(0x1badb306,0xdd5f7613),L_(0x4641e82a), LL(0xf53ff561,0x3d43a296),LL(0x58c32dfb,0x7b2e7561),LL(0x3ffcd8f7,0xc250c17a),L_(0xfacc3394), + LL(0xda8507d4,0x99456e76),LL(0xe9a40562,0x9ba62d11),LL(0xa165351f,0xd0dd1798),L_(0xbabb6293), LL(0x853dcb7c,0xb83a079a),LL(0xa5cd33ea,0x26c9aa1e),LL(0xf120f051,0x6109e625),L_(0x774354d8), + LL(0x14c27c7a,0x8d82b0bc),LL(0xbafdf31f,0xe88bea46),LL(0x7639e998,0xd2a8308f),L_(0x3be638b1), LL(0xc5e7e09d,0x54bc114e),LL(0xeb650088,0xd1baff80),LL(0xebdef489,0x902bb33d),L_(0xc3e46171), + LL(0x45911106,0xc86362a5),LL(0x56cc1bef,0xce560fcf),LL(0x3b4b4fc8,0xf9436f6d),L_(0x370a01fd), LL(0xa8fad83b,0x632c516d),LL(0x916aa8c7,0xae217497),LL(0xe3ad18e9,0xe18b971a),L_(0x72c7e5a4), + LL(0x9b05d089,0xb483969f),LL(0xf8cf3d39,0xcfd11869),LL(0x1d89563e,0xa602a006),L_(0x91cd1395), LL(0x71d49ace,0xdbdaa432),LL(0x0966d0a9,0x1c3623ed),LL(0x166bebe1,0xf1b4da0f),L_(0x433f9113), + LL(0x86d4180d,0x6fb1d5d9),LL(0xd89da757,0x031c30db),LL(0x2939bdad,0xa42134e8),L_(0x6b13fefc), LL(0x1baf8cf7,0xb37f662e),LL(0x413f92df,0xed2b1683),LL(0x985c742a,0x1de586e7),L_(0x5f4904de), + LL(0x01f2ea9b,0x03906d91),LL(0xb13c4090,0x9d1c566b),LL(0xf3affee6,0x6830a295),L_(0xb7fc1017), LL(0xa0a0056c,0x45d24eb6),LL(0xcb2d95c2,0x622219f3),LL(0x8c20bcd3,0x3379e3da),L_(0x6dc4634a), + LL(0x3e8ae0a0,0xaefdff77),LL(0x97e82574,0xe4ee96dc),LL(0x112d1838,0x20061ca4),L_(0x0060cd67), LL(0x20825ad2,0x11499a1e),LL(0x8b6913cb,0x1c239b7a),LL(0x67ff5e87,0x1680aa3a),L_(0xe823c3ec), + LL(0xd6ad0217,0xd3ac8a55),LL(0xd2b4232a,0xf6ddec57),LL(0x1b8abf52,0x2fcb86b4),L_(0x19bc7365), LL(0x1f2c9fd1,0xa051bf99),LL(0x1aec4d94,0x5a88054d),LL(0xfbc4f987,0xa954ceb9),L_(0x05b104cc), + LL(0x4ccd6345,0x40690896),LL(0x4799ff54,0x3b0d618b),LL(0xbc95c20a,0xc0b5b3de),L_(0x290686c2), LL(0x488b692d,0xca443d1d),LL(0x6b65747b,0x823770ad),LL(0xf2987b72,0xf039026d),L_(0xb9b37c0a), + LL(0x8dd8e6e6,0xd360d772),LL(0xd81505e8,0x994209e4),LL(0x40816745,0xc9836e31),L_(0x9dca53d3), LL(0x07ea2add,0xd820c03f),LL(0xb45d3f5d,0x33d13943),LL(0xedf3a3c9,0xe0ce5e44),L_(0x459a2236), + LL(0x3f40e1dd,0x35ffc3c1),LL(0x273c8e42,0x9e607b7b),LL(0xfecec30d,0xda6a8389),L_(0x8e8dc1c3), LL(0xe7f0596c,0x6fe132fd),LL(0xc3565543,0x8889d9c6),LL(0x951334fa,0x770ed88f),L_(0x4d1d476c), + LL(0x542a815c,0x20e67927),LL(0x488e81fb,0x7f7fe269),LL(0xd968afb4,0xb0057d32),L_(0xb8d04c1b), LL(0x85a86d34,0xee01ab82),LL(0xef38d717,0x5e5709d8),LL(0x830deaea,0xfba87128),L_(0xbf20a3cb), + LL(0x9efe5459,0x15750d83),LL(0x8d8facef,0x4d132c09),LL(0xef0f3af1,0xd1a4206b),L_(0x64ebf883), LL(0x5e56d99d,0x5b6d2c3b),LL(0x3c48ef20,0xce5ccc62),LL(0x153580c5,0x534ba912),L_(0xa02f889c), + LL(0x349d9804,0x1f2a638d),LL(0xcb233fe2,0x9d44fa20),LL(0x792d0e00,0x62d03b08),L_(0xd6646af8), LL(0x180ef2f5,0x4a8172cc),LL(0x82199f97,0x401272d5),LL(0xf879213c,0x8048de29),L_(0x51bdf94f), + LL(0x9c9a3b84,0x75f12d75),LL(0x743c75d7,0xaadd691d),LL(0xc13528c2,0x0f8f0fc7),L_(0x969b010e), LL(0x9b8f4442,0x2acbaab0),LL(0xdfc6ee9c,0x4678a76c),LL(0x23ac3530,0xc00ef611),L_(0xdfc77ba6), + LL(0x3fe1d500,0xd561d679),LL(0xac256d68,0x7e3b2fc9),LL(0xb7f44d84,0x1d8cc6f2),L_(0xddd4acc6), LL(0xccec3e4c,0x83d18ef0),LL(0x6b5fbe51,0xf9877554),LL(0xe616da91,0x04e7aef1),L_(0x7079d8b4), + LL(0xacf8b8b3,0xc0f7d69f),LL(0x2242759d,0x0a034401),LL(0x9949d06b,0xde898701),L_(0x8b24618f), LL(0xa9a593b3,0x3976254d),LL(0xb0bd22ab,0x776af23a),LL(0x2125ed2b,0xa5f28d83),L_(0xa1c543ea), + LL(0x4bd74e55,0xe7ee1b28),LL(0xf2a06317,0xec3c82fa),LL(0x784961c1,0xf759d96d),L_(0x5670b8e7), LL(0x2db86f19,0xafedb099),LL(0x8fbfe519,0x19d6aa87),LL(0x7246a16a,0x7503e23c),L_(0x23ac9af3), + LL(0x952bc75c,0x87836e61),LL(0xc31169c7,0x278dc1c5),LL(0x111050a4,0xa7810165),L_(0x446bda32), LL(0x490d4091,0xa876bcf8),LL(0x32692fd4,0x7e43410e),LL(0xd11e3c6f,0xe2aece33),L_(0xd325fefc), + LL(0x209ded15,0x8c31bbf9),LL(0x0e3623bf,0x818a6e0b),LL(0xbb5c266d,0xc5f4aaef),L_(0xa7179b54), LL(0x15383b16,0xed087186),LL(0x375cb291,0xbbe070e0),LL(0x047af636,0x73198d27),L_(0x8f1c0b06), + LL(0x4cc95bc4,0x77e38347),LL(0xc22c3ac3,0x83e4ab76),LL(0xea1c777a,0xab8de890),L_(0x8b9d1132), LL(0x959ae60a,0x2a2fde96),LL(0x78f20c5e,0x6184d8f4),LL(0xa11f0041,0x302a6212),L_(0xba7689dc), + LL(0x376e162d,0x8c2d9e1f),LL(0x50cda9df,0x7ba9efe3),LL(0xa6158df9,0xadbbeaa9),L_(0x4778c93d), LL(0x4165d3a8,0xd1a49e09),LL(0x6eb6664c,0x276faed0),LL(0xb72ac28c,0xb8fb2671),L_(0xfc493918), + LL(0x3f2f65a3,0xe846a0c3),LL(0xc3ffb873,0xb4100b80),LL(0xd98b14c7,0xcd3fcccf),L_(0xec8c8522), LL(0xde06d3b7,0x27093099),LL(0xc435552e,0x5b30c12f),LL(0x731b5ca4,0x6d3545bb),L_(0xcf95c612), + LL(0x06a11b1f,0x67e83944),LL(0x77e47a85,0x840987d9),LL(0x41b4a73c,0xf14ab27f),L_(0x45673153), LL(0x5e20b8e1,0x29737735),LL(0x3a31ee99,0xdcbc9d02),LL(0x89cb9a71,0x3c610ccb),L_(0x92d6ab9e), + LL(0x7dc21a89,0x24dd0312),LL(0xfe3af3cf,0xbd1479bd),LL(0x1fa695ef,0x49e9da9d),L_(0x35d8485e), LL(0x4caa0416,0x1be78d4d),LL(0x9a8e5ede,0x06a82fad),LL(0xdb4e20a3,0xb9902b0e),L_(0x762073cc), + LL(0x26109f70,0xba8c73ab),LL(0xfd983b8b,0xe8f78dd1),LL(0x3921c9f7,0x9c6ee5d8),L_(0x7f5a5177), LL(0x14bbc8be,0xab53e7b2),LL(0x7db07019,0xfff92c17),LL(0x01f9a8fb,0x2588492a),L_(0x9ea1e98d), + LL(0x924eb396,0x31997788),LL(0xa9a0407f,0xbc33538a),LL(0x26fdd725,0xa3068d9c),L_(0x2aba0c14), LL(0xfb38ce06,0x6d07282f),LL(0x2d5ed5c3,0x0f9417d3),LL(0x52b3241d,0xdbd63903),L_(0x11f4b8bc), + LL(0x88a000ac,0x35994c37),LL(0xccc2b918,0x337027af),LL(0xf27570cb,0x870c688b),L_(0x8c91a8af), LL(0x458bc212,0x5459f2f5),LL(0x9157cd7c,0x7d5dcbea),LL(0x021d9845,0xdbbbf2c4),L_(0x3319b3fc), + LL(0x4a370724,0xaeba325e),LL(0xaecdc264,0xaa40e67e),LL(0x9b24587f,0x859c1b6a),L_(0xf7648c83), LL(0x9da1346e,0x7005a3f3),LL(0xdf465967,0x7311149a),LL(0x2411ca0d,0xd689abfe),L_(0x1452c503), + LL(0x2a06a445,0xcc290bf3),LL(0xf34968d7,0x65fd04ce),LL(0x7228d7c1,0x48e02e21),L_(0x17e25b2b), LL(0x20f72ec8,0xa53a154b),LL(0x1035d2b6,0x8b5f77f7),LL(0xe8ab36c6,0xbcf0eb3e),L_(0x63fa883e), + LL(0xa46b410c,0x0b53b1cd),LL(0x2088982f,0x44825888),LL(0x21364c98,0x45bf87a7),L_(0xeeb978c5), LL(0x77561ed1,0x4e53377b),LL(0x093e9c15,0xe15699a0),LL(0xd8249f4f,0x02b46436),L_(0x64f236ee), + LL(0x5bf80f33,0x3940ee66),LL(0x6164d05e,0x98afb7d2),LL(0xb0056da3,0x872642d0),L_(0xa7bd3d66), LL(0xc227063a,0xce37f406),LL(0xd8371363,0x97040937),LL(0x90362154,0x009ca301),L_(0xe59d0b2d), + LL(0x812ca945,0xcf247bdf),LL(0x73b26b51,0xb0c27a65),LL(0xdf33ad4d,0x1f6d55bd),L_(0x4ed64955), LL(0xc4a11d3d,0xa18aee15),LL(0x8ca23082,0xbd802f68),LL(0x20da76f8,0x2453f147),L_(0x4606958c), + LL(0xfa30299c,0x99950738),LL(0x06b63065,0xbe157ae3),LL(0x9853453b,0x88e04e19),L_(0x456e72cc), LL(0xfcb616c9,0xb168037b),LL(0xd3c22f8d,0xce3f0f0a),LL(0xd989f0f6,0x9699fc87),L_(0x273ac5b1), + LL(0x85664bdc,0x273a933d),LL(0x24f52dc3,0xfcf79a03),LL(0x36bc3c34,0x3e91b0cc),L_(0x61de4790), LL(0x58e3b120,0x8f4b6789),LL(0x44bdcadc,0xb12252e0),LL(0x830bedee,0xbb9ac7e8),L_(0xbda5fd11), + LL(0x44861e3d,0x37a97134),LL(0x079c1b7a,0x6798891d),LL(0xeaf11509,0x3012e200),L_(0x61b63246), LL(0xa87c42aa,0xc0246bd8),LL(0xb92f89e2,0xed286525),LL(0x3fff4a96,0x44cf1045),L_(0x6e70ae3f), + LL(0x5068198a,0x6615d342),LL(0xb3a83dd9,0x0e23ae21),LL(0x0c4c00f7,0x6cbcc29c),L_(0x84d9fe95), LL(0x5e865fd0,0x30e1885b),LL(0x82a4da98,0x5fcfdb20),LL(0xbcc23ab7,0x259db6ce),L_(0x306cf56e), + LL(0x3622f7f7,0x08624c7b),LL(0x32c9c5fc,0x01b193ac),LL(0x38295bfb,0xfb49c594),L_(0xdcfe3634), LL(0x103965ff,0x832aec92),LL(0xe5cda111,0xdb928d8e),LL(0x98fc1728,0xac496bac),L_(0x3f057842), + LL(0x69b7107b,0x7bdd13e7),LL(0x189dee30,0x5aa65303),LL(0x01cf6016,0x02a07254),L_(0x7f6053e7), LL(0x409cab89,0xc9d79b48),LL(0xd467929d,0xe17deac4),LL(0x2a4257b0,0x3ed68c3c),L_(0x0209a951), + LL(0xde7ecacc,0xb50fa3a8),LL(0x568377b7,0x7926440e),LL(0x992fa9d6,0xf3995e07),L_(0xf09351e3), LL(0xaf199c40,0xde00386c),LL(0x7c21c039,0xacbcdf7b),LL(0x983e3f5f,0x970f1581),L_(0xfde7bb8d), + LL(0x31d0cb64,0xa5991d35),LL(0x727713ca,0x20cf37ff),LL(0x81781a16,0x946557d9),L_(0x8b2de3fc), LL(0xd1639576,0xb61c0935),LL(0xefe6ec67,0xcaf4adb1),LL(0x0483381f,0xbfd4710c),L_(0x3cb8617a), + LL(0x19bcb25a,0xfb2c55b6),LL(0x83398c47,0xe6a45901),LL(0xfc55bdd9,0xd6aad463),L_(0x733b8806), LL(0x4da45d48,0x600c9640),LL(0x72a69c3e,0x7bb5666e),LL(0x25c8da01,0xa863f55c),L_(0x6b73f445), + LL(0x8ff6b908,0xb5811bfb),LL(0xdea6b1b8,0x3864ff6e),LL(0x6f29d6ab,0x244c832f),L_(0xb885707b), LL(0x6b307d64,0x19847d9d),LL(0xbb7684f6,0x85f7c9ef),LL(0xc0f2d53c,0x20ef5736),L_(0x9e06880d), + LL(0x8c5dd4e2,0x9a3cdc81),LL(0x6fd2d1fe,0x6a09971a),LL(0xfe48b29f,0xa14e785b),L_(0x7afeb3e3), LL(0xb175e3fc,0x15c1eebf),LL(0xdc5c271b,0xc21625b9),LL(0xd51bbdf3,0x4095982d),L_(0xea6a656f), + LL(0x3418b0dc,0x8df3827e),LL(0xad96082c,0xae05d810),LL(0x0c7308d4,0x747332eb),L_(0x3e790568), LL(0xf43bfba5,0xb410e2a5),LL(0xa45bcc07,0x6ea69371),LL(0x34e11697,0x68990fab),L_(0xd0d95f71), + LL(0x46088da2,0x2b70f4c2),LL(0x95663747,0x2b81bbe7),LL(0x18e76686,0x0510d4ae),L_(0xa806fc64), LL(0x718b9269,0x74a39c45),LL(0x11681c31,0x39edf452),LL(0x7f1ee73e,0xd70c5b25),L_(0x145296c5), + LL(0x38adcbf7,0xb90e977c),LL(0xa73e17c7,0x589db798),LL(0x3b0459aa,0xd910c80d),L_(0x4a996387), LL(0xa2014673,0x09cc1462),LL(0x4ff007ad,0x9deb8885),LL(0x6f3bf601,0x9137e94d),L_(0x3d0461a8), + LL(0x49eeb574,0xdf5e90f6),LL(0x03f3fdc3,0xf38e094e),LL(0x2f05f4ba,0xefe1e30f),L_(0x5dab20a6), LL(0x25f380be,0xfbe83a6a),LL(0x815eac18,0x96d53b04),LL(0x2c89a65a,0x13f75b6a),L_(0x326a87f4), + LL(0xb57a062a,0x99fa6314),LL(0x29c19e9b,0x29ce4a74),LL(0x5d5a6ffb,0x84d62c60),L_(0x4e8640e3), LL(0x63890d47,0x01830a3e),LL(0xa50855ff,0x86e7548d),LL(0xb9b3fb5b,0xbf0727b4),L_(0xa1cac932), + LL(0x93078c89,0x08fe3e54),LL(0x7f8ba9f8,0xa70bd6a5),LL(0xfff3b260,0xa621223a),L_(0xda5b8cc0), LL(0x5c0ab9e1,0xb352caaf),LL(0x52e875c5,0x57c08401),LL(0x888687cb,0xd159fefe),L_(0x788f0705), + LL(0x50a69ca4,0xe7ee73d3),LL(0x71f9e278,0x50682750),LL(0x0511bea3,0x147b2ef8),L_(0x908389b2), LL(0x0d09e4fb,0xb9505161),LL(0x7ab5b1bb,0xf8cfd83f),LL(0xa16a5843,0xeb15fb80),L_(0x8840233d), + LL(0xedb21e1a,0xfbf89123),LL(0xb350235f,0xba1f0507),LL(0x601ae7a3,0x487a5b44),L_(0x168cfefc), LL(0x1632dc61,0x27f10999),LL(0x3f7f4917,0x224754d4),LL(0x576cbe66,0x93695572),L_(0x1697b707), +}, +/* digit=24 base_pwr=2^168 */ +{ + LL(0x897a6b26,0x1aa93494),LL(0x07822bd8,0x0eecf33d),LL(0x690a0450,0x411c39e9),L_(0xddfd5a23), LL(0x752f4021,0x5d8da0af),LL(0x74dcec38,0xc6e5a1f0),LL(0xa51c46ee,0x6b77f2b0),L_(0x1367898a), + LL(0x10f0de19,0xd8b1efba),LL(0x5d75e9ca,0x831a06cb),LL(0xdea9f60f,0x7af3d6fd),L_(0x95065ae4), LL(0x379b23db,0xe0c7e800),LL(0x22ced186,0x5d673e52),LL(0xc6698d7f,0x95367fa5),L_(0x9310a67e), + LL(0x288d3aae,0x7322a3b2),LL(0x1b5b3f21,0xbe251fd5),LL(0x1fe6e87b,0xcad2ee21),L_(0xb5fd4e5b), LL(0x91f82182,0xe5ae89d4),LL(0xc2853eeb,0x3262d99e),LL(0x9036d2d0,0xcb159584),L_(0x45627827), + LL(0xf3073506,0xf3411909),LL(0x2470f5ee,0x94dcf7c1),LL(0xf0be84fe,0xade34d2c),L_(0x90636c20), LL(0xb2827737,0x180fa04c),LL(0x2db09b0f,0x26143ea2),LL(0x0a0909aa,0x83bcc559),L_(0x281cf9aa), + LL(0xb3d17628,0x38d6fee0),LL(0x8f859667,0x5ac1dd54),LL(0x86559609,0xca6e59bf),L_(0x6854b4e8), LL(0x61f3a762,0x23a24b87),LL(0x5840ce8a,0x0173425e),LL(0x946b6bbd,0x00fd3d85),L_(0x8a095b45), + LL(0x156ebcbc,0x74d544f1),LL(0x4c355669,0x3127ea7e),LL(0x1ea60e82,0x099e116c),L_(0xd960a70d), LL(0xd32fd59f,0xd60a4a59),LL(0x305faf07,0x3cf7063d),LL(0x61b80d24,0xe6b8e5c2),L_(0xd428e0cc), + LL(0x22dd5fee,0x26d21295),LL(0x5d2ed352,0xd4c31ad3),LL(0x3daf91ee,0x44afa3c4),L_(0xd529e7b2), LL(0x17333fb8,0xd7ed0b47),LL(0xcc9faccf,0xe9201771),LL(0xc98aa7de,0xc9757998),L_(0xce2c4e14), + LL(0x1ae8d0a4,0x098fc503),LL(0x3d3f8532,0x41d10295),LL(0x50253fa1,0x23d266c8),L_(0xb38286d6), LL(0xfb63eee1,0x99903092),LL(0x48a64b98,0x9100a99c),LL(0xbc43643a,0xfe159bd8),L_(0x2f08eae4), + LL(0xb10e23d2,0x5b31f9b6),LL(0xc558d554,0x5c151d19),LL(0xe3c46403,0x19a6f592),L_(0x2211131c), LL(0xbb6a51b6,0x4d8f19e7),LL(0x8c4d4f34,0x551259ee),LL(0x347e8cae,0xad36aa89),L_(0x5a959e3c), + LL(0x9f2c968b,0x178db2dd),LL(0x8674b5e1,0xc9ba55bc),LL(0xce21dcf1,0xd3884f45),L_(0x7664513a), LL(0xbb703b97,0x7a1b3e56),LL(0xc9e299e2,0xc4a588c4),LL(0xe96de0f0,0x8d3f0ffc),L_(0x5aba434e), + LL(0x8685946b,0x3206b59f),LL(0xbf15b53c,0x7e914149),LL(0x2fff52c6,0xfec55940),L_(0xc3791f65), LL(0x78dad0a9,0x394de0c1),LL(0x5c5fed8c,0x72c6919f),LL(0x674b4d59,0x0e57743b),L_(0xd7315975), + LL(0x3dad8066,0x7fa4f80a),LL(0xc574aafe,0x60f2414d),LL(0x25994c45,0x15293405),L_(0xa00f9231), LL(0x0f201926,0xf98edea5),LL(0xd0bcf974,0xaf5b2ad4),LL(0xa3c74ad6,0x448873ac),L_(0x8ff67b2d), + LL(0x75e7728e,0x510cb9a4),LL(0xbaf15c58,0x54d76825),LL(0x234a8fab,0x0023d4d4),L_(0x9d6e89b9), LL(0x2cce0b43,0x374850ff),LL(0x6bf4faef,0x32a29d1b),LL(0xdd164002,0x799cb3ee),L_(0xfc7797a7), + LL(0x26f100f7,0x34261e54),LL(0xcf17aa4d,0x589b344b),LL(0x801ccc35,0x0c7a04fa),L_(0x762b3408), LL(0x9578af64,0x002ca131),LL(0x0870f41d,0xe0fba28a),LL(0x70686201,0x276eaa26),L_(0xf592842e), + LL(0xcf7ff5db,0xb78b71bc),LL(0xa79ca9e4,0x625166ca),LL(0xe7aab4c3,0x095aa863),L_(0x980df4d9), LL(0xfc336519,0x75ac5ed8),LL(0xcc69d2f9,0xf211966f),LL(0x429f98f1,0x10ce7510),L_(0x5736d4ee), + LL(0xf3b848f9,0x8da51d84),LL(0xb2abe419,0xc9d1a3db),LL(0xefa624dc,0xc275c72e),L_(0x8b684df9), LL(0xc682bec0,0x75f1bf6e),LL(0xfc8f823d,0x3f9f9e0a),LL(0xa497166b,0xb3363382),L_(0x3241d9b6), + LL(0xe748b559,0x9a65f283),LL(0x47d0d598,0xeb923237),LL(0x600f8097,0xdfc5d530),L_(0x06c1d340), LL(0x8c26801d,0x409b596b),LL(0xe50cc47b,0x2d0a1f78),LL(0x71018c42,0x4f9b2683),L_(0x2de345b4), + LL(0x2273bfc3,0xd352b3d9),LL(0xfb7e2c37,0xb02762b6),LL(0xfb5035dc,0xc27af22c),L_(0xe5cf5a24), LL(0x304d3903,0xf2e49e03),LL(0x31c42940,0x8e2941f7),LL(0xb3e476b2,0x3130439d),L_(0x729a7e6b), + LL(0x2fb4a6c0,0x554fbba4),LL(0x1228460b,0xcbf47250),LL(0xda7db077,0xf5e0be2b),L_(0x8a989e94), LL(0xbed3a180,0xe15aded1),LL(0x56931b09,0x2a994a1d),LL(0x7fb6175b,0x36407d3f),L_(0x785ad12c), + LL(0x7466b3e3,0x296e5cc4),LL(0x6178d140,0x29e191e4),LL(0x9088d05b,0x1f9dc468),L_(0x631396d3), LL(0x2665b7af,0x86ffc6cd),LL(0x04f52e9a,0x099491df),LL(0x4b21e0a9,0x27375e3f),L_(0x242c7c60), + LL(0x974f4c4b,0x064ca079),LL(0xa02c0b2b,0xba3c8a64),LL(0xa1558503,0x13a69d2a),L_(0x3d67919d), LL(0x148d5568,0x2bfc83bf),LL(0x3a653e93,0x1054b748),LL(0x69ae9c83,0x0a4cc47c),L_(0xf624d321), + LL(0xacbde616,0x9e3e45cf),LL(0xd947c8c7,0x6374e6b2),LL(0xa439634d,0x5b100526),L_(0x7b5067f8), LL(0xb742e1b9,0xfc26652d),LL(0x701d8d64,0x6746e242),LL(0x277501f0,0x262c9dad),L_(0xd3dd957f), + LL(0x09a69072,0x9f4be9d7),LL(0xcf4ac2d6,0x20d76239),LL(0xe04b6795,0xf3257cbf),L_(0xec24a41c), LL(0x48529c37,0xb3eb3d13),LL(0xcc1689ae,0x35003a26),LL(0x8712e8c7,0xafd7b5e3),L_(0x868af920), + LL(0x620ac627,0xd27017eb),LL(0x75a3408c,0x28e8bc69),LL(0x7de280af,0xfab61ca0),L_(0xb76f92d0), LL(0x3e502b01,0x528c5328),LL(0xffede226,0x05139646),LL(0x9bf76d0b,0x4d2256e2),L_(0xdd96e876), + LL(0x4eb92472,0xe00a0552),LL(0x896685cb,0xfa213a96),LL(0xf0d4a520,0xe8f5fdb6),L_(0x0f380c61), LL(0x5288ae5e,0x4d63b6c6),LL(0xca87cdad,0x7d544fbe),LL(0x69639e2d,0x941d9935),L_(0xed61f0e4), + LL(0x31d063fa,0x72ebb946),LL(0x43d0a9df,0xa9c082ad),LL(0x53424334,0x10a77134),L_(0xdf849ce1), LL(0x5a1815d9,0xdf56c5f3),LL(0x58feabaa,0x6bbd3105),LL(0x787ed1e2,0xa802a275),L_(0xa542b49b), + LL(0x70042e82,0x0646662b),LL(0x33793ddc,0x6dfd5259),LL(0x873a716b,0x3ae6c62d),L_(0xd34ef5f0), LL(0xb3489aa8,0x9974e0c1),LL(0x5b201375,0xae617d06),LL(0x25cf8d2d,0xfac50e53),L_(0xf5028682), + LL(0x82900f26,0x20822d19),LL(0xdb5b7f7b,0xc050b43f),LL(0x610bf8a8,0xe4e5ddab),L_(0x59f6f46f), LL(0x0bd3d213,0xd3a9f7a0),LL(0x29ffdb56,0x8a060b79),LL(0x1aed0fa9,0x7cd570f8),L_(0xa1cdd0bb), + LL(0x0f6923b1,0xb9d66a95),LL(0xf9463b5d,0x6b4aafc6),LL(0x9dcb5191,0x7e8de98d),L_(0x3a174474), LL(0xafeb6788,0xd8a6df5b),LL(0xb00ae812,0x1127ce66),LL(0x595dbbd9,0xab858cbb),L_(0x20456b6d), + LL(0xf945d541,0x6e092bb4),LL(0x4b66cf94,0x27b14454),LL(0x7eca44eb,0x6daca5c9),L_(0x44fbdf91), LL(0xfc99b4f1,0xcb39349a),LL(0x9f292892,0x611f2265),LL(0x7d2e1348,0xb91c9d21),L_(0x2511f796), + LL(0x8d960ed0,0xc742fe68),LL(0xaeca436c,0x7a253140),LL(0xa736c99b,0x7053b3ba),L_(0x4df3a08c), LL(0x1c4bf5fd,0x35ff874b),LL(0xa50437d0,0x85d7a155),LL(0xbb3ee79c,0x28f141d8),L_(0xa309d53a), + LL(0x18a6fdae,0x052107c1),LL(0x4c1843ed,0x7a4941a3),LL(0x5b395717,0x10eeec3a),L_(0x41bed6c7), LL(0xc77d493c,0xe3bf062d),LL(0xe2632a75,0x99abf215),LL(0xccb37627,0xf5482813),L_(0x65bddca7), + LL(0x86262170,0x97f943dd),LL(0xe4f707eb,0x28ad9142),LL(0x1fca8434,0xe200b711),L_(0x5979d82e), LL(0x7eeaf938,0xa0864853),LL(0x073f049c,0xdcbbbd26),LL(0xefca8545,0x5e115ac7),L_(0x81b25231), + LL(0xfa392d8c,0x0b83214e),LL(0x6e208498,0x5535cb0e),LL(0xd7f17a61,0x9d606b9f),L_(0xf9ff6be9), LL(0x532d4992,0x78a1ebcc),LL(0x8412a690,0xc80751aa),LL(0x3fc39e84,0xa4039f18),L_(0x16cc85fa), + LL(0xb6b3e3bf,0xb29dd0f5),LL(0x3f372e07,0xfc4475a6),LL(0x1010f76a,0x499ca40b),L_(0xc9d3a123), LL(0x505bb647,0x1a039620),LL(0x898b067c,0x71c1fd31),LL(0x8fba57f2,0x920244b9),L_(0x2f20dfbe), + LL(0x09e67c8d,0xadba6513),LL(0xf1db6fa1,0x004a0b2d),LL(0x780eff8e,0x6530b59a),L_(0xdcf21d60), LL(0x8ecdce5b,0x767463fd),LL(0x65b13c4b,0x70cc1a2b),LL(0xaf0f593a,0xb10b6a9a),L_(0x05c89578), + LL(0x040645b4,0xae7f7819),LL(0x678205ed,0x421d2a1d),LL(0xcc32c0b0,0x2492206a),L_(0x43d4ee55), LL(0xb779e43f,0x2296a21f),LL(0xd485f134,0x5fce8d33),LL(0x7dae00fa,0xd7fd8f23),L_(0x9c357857), + LL(0xc2d0a0f7,0x683b4c52),LL(0xd1014606,0x457af899),LL(0x2de4b78e,0xed10d363),L_(0xe5547d1b), LL(0x84fc2002,0x40cf6189),LL(0x1fa00e4b,0x6b948df1),LL(0x2643b489,0xa90cf1b7),L_(0x862ff071), + LL(0xf9cd4743,0x2c263fe3),LL(0x3df3e881,0x7af59647),LL(0x4a452825,0xf8b4e248),L_(0xff9860e0), LL(0xe9e940c2,0xfaa7bd3a),LL(0x4dcae86a,0x829a4b08),LL(0x0392152c,0x8e97fa6c),L_(0xfc62b042), + LL(0xf8c2cf32,0x38ca48d4),LL(0xc8c6f843,0xb6e872e4),LL(0x1a5701ad,0x8137a142),L_(0x3332d11c), LL(0xd8632d31,0xf65f8d02),LL(0xc57e0eee,0xed896e7d),LL(0x84c4a8f0,0x474d64c3),L_(0x9a310ea4), + LL(0x1facebce,0x90943f9c),LL(0xabcd06f1,0xc0153740),LL(0x4bf7868b,0x2460277b),L_(0xf15a1c15), LL(0xe70f731b,0xbbc3520f),LL(0xa0084581,0x1881feb6),LL(0x8c12c484,0x4461e279),L_(0x2cb0b794), + LL(0x420f669d,0xc6234887),LL(0x1336960e,0x961fd208),LL(0x6690aec7,0x8dcc7988),L_(0xea8d5acf), LL(0x6a7ab2c0,0xad19e666),LL(0x221a923e,0xf44304de),LL(0x3d295ba2,0x840fc746),L_(0xa849c9c6), + LL(0xffb23eb2,0x796ddb67),LL(0x7f2ece47,0xb74ebddd),LL(0xfa40fdb7,0x6e9b86f6),L_(0x3753a599), LL(0x517edc52,0xb0d32903),LL(0x9ce52e22,0x4e38e3ff),LL(0x609b3583,0xbd4bbc16),L_(0x470387a5), + LL(0xc2767e71,0xb5992b12),LL(0x15e316ec,0x722e7585),LL(0x331c37c2,0x4f66d67c),L_(0x5a547f8e), LL(0xad349dda,0x2343f37d),LL(0xc7ecc98e,0x991a0d20),LL(0x2f36fbc0,0x32fd452b),L_(0xbcd300ae), + LL(0xe9e7130e,0x3965b7db),LL(0xfbb383d5,0xa434d230),LL(0xd5ddeb7e,0x5de1379b),L_(0x89236512), LL(0x26844221,0x71474c32),LL(0x359ac63d,0x86ab382d),LL(0x6a2a41ee,0xb41d45a2),L_(0x4543bf02), + LL(0xc03175e0,0xdd45b154),LL(0x51a93461,0xc32e33b5),LL(0x8e87a379,0x6030bb55),L_(0xe0f74319), LL(0x1ee1fb1c,0x180c566b),LL(0xf64d3bd0,0xd5501439),LL(0x117f7e05,0x9fe6d9b3),L_(0x276cdeae), + LL(0x79701f00,0x90d2c4af),LL(0x8ee8e755,0x19fa045c),LL(0x34e9da6a,0xea446558),L_(0x56f8560b), LL(0x22273b04,0xf104982d),LL(0x7a1b70ed,0x0b6be603),LL(0x5df6c184,0xb3a79a2f),L_(0x3e690209), + LL(0xb6a58003,0x506cdad2),LL(0x1cd413bf,0xcc9e3e86),LL(0x5af9735a,0x4669ee32),L_(0xf133df4e), LL(0xa97f8799,0x343b9133),LL(0xd2df1205,0x5ed1097e),LL(0xc0f593eb,0xe1f7e724),L_(0x03f70d2b), + LL(0xfbde70cb,0xe1aefce0),LL(0x28e77727,0x953078f3),LL(0xea43f71f,0xb1afcd33),L_(0xe72f4294), LL(0x42df1489,0x5c609190),LL(0xd85d4064,0x9d39f16a),LL(0xd4734dcb,0xc6a7ed93),L_(0x73444dba), + LL(0xc80deb54,0x786041c5),LL(0x2e784b12,0x73806b24),LL(0xa5394485,0xd5ed489c),L_(0x7c1354f6), LL(0xc98caa8f,0x6f5aed20),LL(0x04a2cef9,0x343f789d),LL(0x6a61903c,0x0943ad59),L_(0x74525b1c), + LL(0xdd468a2b,0x41295f9e),LL(0x79058179,0x767bb930),LL(0x8356b028,0x8630275b),L_(0x7d99704d), LL(0x9677c30c,0xfe64fec1),LL(0xb6ad9348,0x7bfdd07e),LL(0x323c5204,0xff571db9),L_(0xabd2794c), + LL(0xc6bef1c2,0x39e5ddd7),LL(0xa00ac9eb,0x4166efe7),LL(0x08022d52,0xec00b4ca),L_(0x89c305e2), LL(0xdff9eb38,0x2f6d8e32),LL(0x1c9dee31,0x38a38882),LL(0x063cbbc8,0xd453f2df),L_(0x500b8e1b), + LL(0x2a4b58b5,0x0d2d67f5),LL(0x704fba9c,0xb9671248),LL(0x3b601783,0xc86eeaf3),L_(0x3a076280), LL(0xc6604758,0x057735ba),LL(0x3c7fe621,0xa0f157e0),LL(0xba90bf98,0x7ea681b4),L_(0xc697f17d), + LL(0xf242b313,0x2fb2d012),LL(0x8b404954,0x301b1ef8),LL(0x3864cc2c,0xe8bf6c74),L_(0x27928a4a), LL(0x37e42bc1,0x129459b3),LL(0xb079e9c8,0x95c688c9),LL(0xa8c506fd,0x2be35d42),L_(0xabd7b8a2), + LL(0x8d7f03a4,0x0c337ebf),LL(0x9f5cd253,0x2b5789a5),LL(0x3bc3df04,0x808378fd),L_(0x57ce1b57), LL(0x8394999d,0x9173aca8),LL(0x29069aea,0x68a97a68),LL(0x172c5e76,0xd7f9c6b8),L_(0x2bb82de1), + LL(0x26324b43,0x069b62db),LL(0x3a04b8c8,0x2d6c75c6),LL(0xbb1fb7ef,0x8e5dc130),L_(0xdf0fbfa5), LL(0x427bae31,0x8d6bb598),LL(0xae962471,0x4a1d29d8),LL(0x6a0b5064,0x1f5aad58),L_(0xcb90fbe1), + LL(0xf5f95663,0x99c6500a),LL(0x182ee0a7,0xfc57412c),LL(0x9acab63a,0xd7a3f799),L_(0x579dffc7), LL(0xb294554e,0x2e7244f9),LL(0x7a563978,0xc577a189),LL(0xd9421c12,0x4a33607f),L_(0xca35ca5e), + LL(0xcf4cc636,0x476c2c16),LL(0x84dd3019,0x40d43930),LL(0x9f6a9cbb,0x8de41867),L_(0xa0782cd2), LL(0x8e9807cc,0x335870d6),LL(0x873bb057,0x237820cd),LL(0xd2763265,0x817bb568),L_(0xac61e5ba), + LL(0x277845cc,0xb4216df3),LL(0x28a00ba3,0x4ae7f387),LL(0x8d18d55a,0x83dc382b),L_(0x9929ba4b), LL(0xace5a497,0xc4acbdd9),LL(0x1a149f46,0xfee31905),LL(0x03677afd,0x7f382dd5),L_(0x038b4fd6), + LL(0x39c19776,0x7b1469c5),LL(0x770906b4,0xefd3e00c),LL(0x39b76a30,0xb757175c),L_(0x77b00db2), LL(0xea73fb31,0x00e5eb12),LL(0x564b2b5a,0x5dec4d76),LL(0x16670a8b,0x6cedfc0a),L_(0xfc26f8d3), + LL(0x0f967635,0x5f72f035),LL(0x492f15fb,0x9fbbd203),LL(0x8a57f34e,0xca278cc2),L_(0x136d3def), LL(0x3233be88,0x56bc1e3d),LL(0xb7d079d2,0x167694bb),LL(0xb849beca,0xc12eafab),L_(0xf42c9064), + LL(0xc22b8b50,0x35110b41),LL(0x3593434b,0xc03f7534),LL(0x2a685ee5,0x38e7d616),L_(0xd80d02e7), LL(0x681060ac,0x47c0e163),LL(0xa5dbbbef,0xaf6a4e94),LL(0x58c7a38b,0x00b0f102),L_(0xbe4a965e), + LL(0xa0bfdebf,0x00ea08c9),LL(0x0a49eb36,0x19299c59),LL(0x4a5b799c,0x1389e249),L_(0x6bb607bd), LL(0x003f62bb,0x21dd6f70),LL(0x648ac9f7,0x0d28002f),LL(0x46ddb53c,0x123f4a38),L_(0x0b454608), + LL(0x6cd705df,0xdc0b4f05),LL(0xa26650ba,0x584543cc),LL(0x9623d15d,0x52a5b5a4),L_(0x8530847b), LL(0x95176358,0x2b9634a4),LL(0x88564796,0xb76d8613),LL(0x8cd268e3,0xdd09c6f7),L_(0xfbbf3c6c), +}, +/* digit=25 base_pwr=2^175 */ +{ + LL(0x40600691,0x076ba1e2),LL(0xaf9141d1,0x3cbbece3),LL(0x90d62387,0xeae39108),L_(0x39ae931a), LL(0xef1b81b3,0x7c192920),LL(0x51f12b8a,0x07e50a2b),LL(0xf1cfbc63,0xaa15f8c6),L_(0x26ff0bea), + LL(0x9f2ac6a5,0x5ac7dc31),LL(0x5a5fa2f2,0xd3536baf),LL(0x918f6160,0x19e26cfd),L_(0x3d611b68), LL(0x58b92257,0xfbe0d264),LL(0xa4b3a16e,0x6f69ee33),LL(0xab7e3e38,0xfb87b2d4),L_(0xe4cf7a53), + LL(0x4428fe8d,0x28c21968),LL(0xe6afbadf,0x82133ac1),LL(0x08d0d89a,0x79f622a4),L_(0xfc61f01d), LL(0x0f6397fa,0x9afa4014),LL(0x1819a677,0x8b6b825f),LL(0x9e89a4ea,0xf6189381),L_(0x4c306973), + LL(0x16b5009f,0xd0fd8e2d),LL(0x85f596e9,0x75cd4af4),LL(0xc650d10a,0xc0ff364a),L_(0xaa432f6b), LL(0xb9e1fd35,0x60cd9ff6),LL(0xa81387b4,0xf5ffdf83),LL(0x1fb57eae,0x0f74dad8),L_(0x77ebce28), + LL(0xcd3d74f0,0xe7801dbf),LL(0xc705f5f3,0x4cae30c4),LL(0x892e14fd,0xee1d51c0),L_(0x235f35c6), LL(0xcb840ec4,0xc690d3bf),LL(0x496db46c,0x6a393aed),LL(0xf95db976,0xa0c8c115),L_(0x3a2ff859), + LL(0xad9729df,0x21208e24),LL(0x50a51554,0x8a669134),LL(0x76da2c79,0x739f33c4),L_(0x47f7655f), LL(0x3faf5d73,0x6df3da71),LL(0xda653a05,0x23d729bd),LL(0xe0dbba03,0x7efefa7f),L_(0x8546d123), + LL(0xa29be43b,0x63a12c13),LL(0x81bccb17,0x0f3de027),LL(0xb8ad1f49,0x2ee0f6a0),L_(0xeca64ff4), LL(0x2a0247bd,0x6c14c6a4),LL(0x27d0478a,0x15b008e7),LL(0x9dc8b9de,0xe6cf3269),L_(0xde4a727b), + LL(0x8a41f62f,0xe9139920),LL(0xafcf2338,0xe343f86a),LL(0x8626eb92,0x330ff008),L_(0x62bc5b8f), LL(0x770a0f51,0x9ed3ab3d),LL(0xacdfce8c,0x87533c3f),LL(0x198a1e9a,0x36ceed7d),L_(0x366edc66), + LL(0xad4f0edd,0x9eb6ef96),LL(0xa0790c0e,0x8f2b7875),LL(0x8212d5cc,0xa20f0405),L_(0x2e6749a5), LL(0x43c2e598,0x0b5bf3aa),LL(0xf0598778,0x695b110e),LL(0x6b2a153e,0xacd67e10),L_(0x9a4287cf), + LL(0xc9194ba8,0x1df015df),LL(0x5545ae11,0xe5e57b96),LL(0xf86d852d,0x34894ebb),L_(0x61b42915), LL(0xaab92979,0xb25bf6b0),LL(0x2f858332,0xf88d9382),LL(0x082b80c9,0xa64fc13d),L_(0xdb34263a), + LL(0x4fc8d228,0x6c1819aa),LL(0x46f4e2d8,0x790019d3),LL(0x3e6d5835,0x31b5f8c4),L_(0x0471eabf), LL(0xd70615ba,0x7377bdb1),LL(0x4f0b793d,0x3d8b3ee2),LL(0x1e0b124d,0x8be72522),L_(0xcb228953), + LL(0xd05e1a54,0x3d345d79),LL(0x4e4eb11a,0x9b0c74e2),LL(0x4f7cb301,0xd3f60831),L_(0x9b37cac3), LL(0xdd153410,0xd42ac14a),LL(0x4b82b6e1,0x67daba89),LL(0x062085e8,0x293aa2ea),L_(0xdafbaa02), + LL(0x57e823a2,0x66dc4352),LL(0xeee6c065,0x9d1334ad),LL(0xe974bd6b,0x51129e57),L_(0xc6e911b2), LL(0x4a591897,0x143fbbc0),LL(0xe567aa72,0xfcf32ecc),LL(0xd98a2bac,0x985f3567),L_(0x4940de3e), + LL(0x810e3b3c,0xabba8dd8),LL(0xbc9b4d54,0xd024fdfa),LL(0x09ce7445,0x56df5156),L_(0x869985ec), LL(0xa279f60b,0xd64936f1),LL(0xf9f4dd90,0x147e3ae6),LL(0xb0502e71,0x9b4a0a61),L_(0x2b7784e2), + LL(0x10ea913e,0x228b551a),LL(0x132cf6ee,0xd39b6d23),LL(0xb41622ce,0x1166f594),L_(0x4f82b870), LL(0x771a8cbc,0xc4a0434c),LL(0x1f3f48d6,0x4e8415e6),LL(0x185bfa20,0x0549b016),L_(0xab597880), + LL(0x8f78c75c,0x7783a236),LL(0xcacbfea9,0x185d7d80),LL(0x37384da3,0xd767d6c6),L_(0x1b40ecf0), LL(0xb58df6c4,0xcb35e135),LL(0x1bdb10dc,0xdede089c),LL(0x51f82512,0x032e4873),L_(0x86fff3dd), + LL(0xae08ea09,0x993762bf),LL(0x3c5e8711,0xe9e1ac75),LL(0xc3fb58ec,0x5942a654),L_(0xdc39e05c), LL(0x6f00a879,0x4c7c1a57),LL(0x76f183b7,0xb5b4e070),LL(0x02f3f5a3,0xc7635031),L_(0x95a5b1bf), + LL(0x1973898f,0x44aeebfb),LL(0x6fdec0d8,0x22963505),LL(0x4dccb72d,0xc61c3dc6),L_(0x29d98bbe), LL(0xc79d4f82,0x0b4d124c),LL(0x60e1bdf3,0xab61b974),LL(0x60907706,0x502b0c26),L_(0x52fb8b7c), + LL(0x9cc7f5da,0xa0c27cd2),LL(0xa30b225d,0x39c837e6),LL(0x14e5e017,0x90beb6db),L_(0xca71c799), LL(0x3452a918,0x6406e7a2),LL(0x8b449af9,0x44086ede),LL(0xd95a3674,0xe83116d2),L_(0xc945cb30), + LL(0x757467e5,0x195a49f1),LL(0x19bb9a9f,0xbd375548),LL(0xdd63e900,0x32a666f4),L_(0xbb5bae80), LL(0xb06e326c,0x71975390),LL(0x7200d75c,0xa8071dcb),LL(0x9bb8f1f0,0x34371f37),L_(0xd14c5988), + LL(0x9fc79376,0x330b4d2c),LL(0x4766d5c5,0x89487193),LL(0x96d443b1,0xb683d913),L_(0x55cd4038), LL(0x25e49098,0x0b19d841),LL(0x4de7c5cc,0xc211c53d),LL(0xb34627f6,0x63d637ee),L_(0x05d48e84), + LL(0x2fb2a30d,0xa9ab961d),LL(0x587b4227,0x7f2e1082),LL(0x9bacdb2f,0xf2fed11b),L_(0x4327e6c8), LL(0xf5f7ca94,0x59f2340a),LL(0xdae690d8,0xa241b47f),LL(0x20f9a82b,0x04266881),L_(0xb60ba27e), + LL(0xfc8a6083,0x4b7ea198),LL(0xf7bd165d,0x0439da93),LL(0xaff22d2a,0x6e2c180a),L_(0x5fa28be1), LL(0xb5422e8a,0x8d8de819),LL(0x8623fa12,0x1c7aa689),LL(0xf1b013b4,0xecdeea2c),L_(0x1412065d), + LL(0x1b8b14e9,0x949b80c2),LL(0x9e45f562,0x7634d5e7),LL(0xeacf4d90,0x89e47023),L_(0xed86f825), LL(0x2a28ee33,0xa46549d3),LL(0xcc9d20c3,0x91467c95),LL(0xb5aaafc8,0xaad820ff),L_(0xfa9b0b7b), + LL(0x3a989cf8,0x56a19c64),LL(0x694699c4,0x6a9264c2),LL(0x2172bedd,0xfcd8d182),L_(0x71a622e6), LL(0xabaee9e8,0x096356a3),LL(0x5df0e982,0xb3c8273f),LL(0xbff93f13,0x15499fe5),L_(0x035d8bec), + LL(0xe7f02675,0x8665d519),LL(0x0b392d7e,0x3114f640),LL(0xda3e7314,0x27724fe5),L_(0xb0000497), LL(0x9626e05c,0x92676514),LL(0x86de4867,0x70fdd068),LL(0xbfb7e396,0xc9127734),L_(0xec308376), + LL(0x889048c2,0x13351e00),LL(0x9ee3edde,0x8a42c8c0),LL(0xe9b0df44,0x039a9289),L_(0x3ba48603), LL(0x9ba675fa,0x1bc5a4ed),LL(0x28dbe0e2,0xc1c91604),LL(0x33d13a46,0x683a466a),L_(0x6f0e40d3), + LL(0x6f169f5d,0x49b1e542),LL(0x5467b60c,0x6be4fa18),LL(0x63a775bc,0xf10e3ad8),L_(0x555978a5), LL(0x2b932386,0xe2647c33),LL(0x2d98173b,0xc10e0d58),LL(0xa46de613,0xd4d665e8),L_(0x8c2f942e), + LL(0x76f88409,0x83f96957),LL(0x11159549,0xb83760f5),LL(0xa26fb69f,0xada04407),L_(0xe1ffa9b1), LL(0x7985249d,0xf63dc16c),LL(0xb8212592,0xa9f05a9e),LL(0x8f2b706f,0xa84d6d60),L_(0x0952d255), + LL(0x9ef2ca53,0xc1ad35cf),LL(0x8063b121,0xf54f3d1d),LL(0x2c69c142,0x2eddbe16),L_(0xe20cbf04), LL(0x58b9d3e5,0xc6a6486c),LL(0x5f1b4348,0x30a9fb2a),LL(0xaa7af663,0xbd211312),L_(0xf09747fa), + LL(0x6aeadb7e,0xb3384570),LL(0xad4b300b,0x80077723),LL(0x7e0408aa,0x92c8f393),L_(0xcdb75950), LL(0x91a66b10,0x01c71c42),LL(0x98806233,0xd3e2ebf9),LL(0x4ccfab0f,0x2c91c51d),L_(0x0daddeb0), + LL(0xa5136305,0x1656bed1),LL(0xf9475d4e,0xd5bd811f),LL(0x29f67636,0x71b2886d),L_(0xce5ffc47), LL(0xf8ec4c6c,0xed19aefd),LL(0x00fbe22e,0x3a69ea47),LL(0x1a593c52,0xed7635e4),L_(0xfea5dbc5), + LL(0xb6a32091,0x0a800d89),LL(0x3e952cbe,0xe00a730d),LL(0xb849574d,0x95e45fa4),L_(0xd0b6f06f), LL(0xc0b38793,0xca47bacc),LL(0x3aea6517,0xa1c9b9db),LL(0x98d62545,0xf79f468d),L_(0xe75cf2cd), + LL(0x6d96b85c,0x92cfaed8),LL(0x8aa22d94,0xe9d09bd1),LL(0x951cb3e9,0xcdf3e590),L_(0xc6443f1d), LL(0x5ee4705a,0xa83030bd),LL(0x4ab4bb2e,0xbbdfbd6c),LL(0x126bf8d3,0xab5c4613),L_(0x78abc625), + LL(0x1d099c24,0xb14045e9),LL(0x75f0192a,0xc8658ab0),LL(0x66a1d69f,0x488c7367),L_(0x27671771), LL(0x10f50e10,0x41dc68c8),LL(0xdbf2b527,0x56c509b4),LL(0xaa6e15c2,0xc052c755),L_(0x6264eb14), + LL(0xf102c97a,0x361df88d),LL(0x8133758d,0xfcb2818c),LL(0x89d87e0a,0x8313147e),L_(0x156564f5), LL(0x92996691,0x0305e3bb),LL(0xb530ebe1,0x3ea90757),LL(0x75ed509b,0xe3da205e),L_(0x8810aa6d), + LL(0x0936433b,0x66bf33ad),LL(0x5cdc1d84,0x20489613),LL(0x40fff511,0x02569cc0),L_(0xa46f7fa8), LL(0x6bea5f0b,0x03ae7465),LL(0x6ca8cba2,0xa43eaabe),LL(0x9d34e4a3,0x338f15f5),L_(0xf175cde9), + LL(0x37a46a76,0x43fb29da),LL(0x0f113fed,0x1e4e18be),LL(0xc9bc3624,0x0891f557),L_(0xf2de428e), LL(0x6cb133b6,0x72c78284),LL(0x0bca6469,0x920b91e7),LL(0x4ad07f92,0x9aca547e),L_(0x254d2e0c), + LL(0x48b9afe1,0xbedf71c7),LL(0xfdf235a0,0x7b745717),LL(0x707d37d5,0x519516e4),L_(0xb70d0d1d), LL(0xf179e489,0x026e2e98),LL(0x7b9cd555,0xa64e85e9),LL(0x05a8ce5e,0x490bbe2c),L_(0xfd0ac7d5), + LL(0x5ef0e444,0x4518decb),LL(0x5704b61f,0x84b0fcd7),LL(0x05e3a6d4,0x761243d0),L_(0x09fdcc95), LL(0xf157aba1,0x52cc970f),LL(0x2f40eec4,0x545ea4c0),LL(0x3cfbc5b3,0x82e0b382),L_(0xd24582c3), + LL(0x3def68b9,0x91b73501),LL(0x63a13aee,0xf4c2f983),LL(0x64a186c4,0xd30674ab),L_(0xae849f85), LL(0xd639edb0,0xbd3a7bd8),LL(0x4e22b52c,0xcf732f2a),LL(0xdee6130a,0xa16934a2),L_(0xa208c2f8), + LL(0xee275071,0xacddc898),LL(0xdcfd6055,0xc137eacf),LL(0x4226123c,0x22c7c6d7),L_(0x18caa3b3), LL(0x575ea43d,0x27a1cc63),LL(0xcfd9c842,0x1d810b5b),LL(0x435cc5b0,0x98cdd25d),L_(0x03338f7f), + LL(0x1bca7595,0x39e40f6e),LL(0xa3f28110,0xf4b9f93a),LL(0xbb9b4a37,0x6d2f9be1),L_(0xc7ef39dd), LL(0x288d64fa,0xb0848ac0),LL(0x9e6a4583,0xe3934b4d),LL(0x65ecc897,0x7961633c),L_(0x12939ce7), + LL(0x69332018,0xdf1e1997),LL(0x0eb1a850,0x55fdefde),LL(0xcfe64a91,0x6d23295e),L_(0xf848ec96), LL(0x6ccd6db0,0x8a058163),LL(0x4a1159c7,0x8e9a68bc),LL(0x145557f9,0x44e87592),L_(0x744a6684), + LL(0x570af433,0xd2524bb7),LL(0x71ee45c1,0xe5696936),LL(0xae2e62f4,0x90655f39),L_(0x4aa6dd85), LL(0xce93159e,0x170e2563),LL(0xcd77d544,0xb60f5503),LL(0x1637c5b9,0xbbddebd8),L_(0x116cc13c), + LL(0xa79f3d54,0xda76037a),LL(0xe567b31a,0x1b943930),LL(0x81454a32,0x8ce526e9),L_(0xa68887d1), LL(0x7c692a2a,0x5ccae9e7),LL(0x2aa4281c,0xbad7967a),LL(0x27a06af9,0x67a8cecd),L_(0xb0666bd6), + LL(0x18d87b3d,0x3bf215b9),LL(0xf3b762b4,0x13a2d20a),LL(0xc7ded91e,0xf2dddefc),L_(0x491f86d1), LL(0x9175dde7,0x1a33ec16),LL(0xbfa502ae,0xde7bc4a6),LL(0x8b90c1c4,0x011d4fdb),L_(0xae49e966), + LL(0x339d5841,0x30030ab7),LL(0x9b2323cb,0x93a59a0c),LL(0x3dfca103,0x6d677f76),L_(0x615cef3a), LL(0x5b19bbca,0xd8927084),LL(0x143864e2,0x0d3dc8c8),LL(0xe2a53ef5,0x7bfce607),L_(0x98d95aec), + LL(0xbfe42fd9,0xe4480a82),LL(0x674699df,0xa3a3e505),LL(0xf6bd5725,0xa3bae3b5),L_(0x93074bef), LL(0x2f753cf5,0xc278e6d8),LL(0x9075dc94,0x042fbabf),LL(0x66f70e54,0x2912d169),L_(0x77ae21bf), + LL(0x8e1def19,0xba0002d6),LL(0x9d21da23,0xa31c1302),LL(0xc9cb3757,0xc0b1cdab),L_(0x478c82a0), LL(0x8ebd0b98,0x708a627c),LL(0x95df97f0,0x00716397),LL(0x036873bf,0x9b0c552c),L_(0x31bdcc00), + LL(0xa7f4f676,0xdb1b2796),LL(0x16f6892d,0x287bb1a9),LL(0x513e742d,0x83e7ad99),L_(0x5ba54190), LL(0xd83035ed,0x3ab45168),LL(0xd55025e1,0xc5e72511),LL(0x57264580,0xa5b527ed),L_(0x246fe503), + LL(0x2956f5b6,0x9456aa98),LL(0x72287d14,0x2d9d56ca),LL(0xbd98da03,0x783e5a79),L_(0x1c038840), LL(0x278213f9,0x44dd9214),LL(0x8abbd0fb,0x1ae00f0f),LL(0x546492b8,0x9365b6f9),L_(0x638f9886), + LL(0x2772a4d8,0xe568c53d),LL(0x56dd3ec8,0xc5798254),LL(0xad2418b2,0x40cc9856),L_(0x5fe0c00d), LL(0xcc8ceaa1,0x1cdd7255),LL(0x17304349,0xd65e8630),LL(0xe17ec8e0,0xb4dc2a26),L_(0x62eb4c57), + LL(0xb31137c7,0xdb4ee5e0),LL(0xa85ff057,0x79aa7312),LL(0x0fb19074,0xf1a5850d),L_(0xb1c8c20f), LL(0xa65022af,0x407175d5),LL(0xc25f5ad9,0x1debba7b),LL(0x0ed43d07,0xa2739236),L_(0x55db40b6), + LL(0xeb7ff1d6,0xbb91225a),LL(0xb6ec7895,0x7915895d),LL(0xec277689,0x53e7c8ad),L_(0x503d01fd), LL(0x427cc57e,0xff30aa1b),LL(0x789118fb,0x28a3c0f3),LL(0x45dce70e,0x7758b97b),L_(0x2ad05594), + LL(0x79df6beb,0x64d25f38),LL(0x7c1271cb,0x1d5f4772),LL(0xafba6d13,0x24a4fbdb),L_(0x68588b5a), LL(0x9bd0327d,0x4408d2f3),LL(0xb9962d65,0x0c0efa60),LL(0x1adff959,0x3e504930),L_(0x1a7248ef), + LL(0xc91f5609,0x50371a5d),LL(0x10a09de0,0x8f3d868e),LL(0x544a1f87,0x05603976),L_(0x9bb49da7), LL(0x4f023f6b,0x2686c470),LL(0x22de25c7,0xad3c86da),LL(0x7b318aae,0x0e37c5eb),L_(0x6e0af008), + LL(0x9cc2caa4,0xc4103bd9),LL(0x28c77b28,0x2b106e89),LL(0xc44c9d88,0x02942cad),L_(0x045b3511), LL(0xae7c29af,0x985fde90),LL(0x3e691e0d,0x5ea3d69a),LL(0x66200341,0xa7fa897a),L_(0xc1b7c5c2), + LL(0xf2dba47e,0x858b20b7),LL(0x94f1ad67,0x80c7e010),LL(0xcb454e18,0xe75e697e),L_(0xea8630aa), LL(0xa6af9eed,0x7a69400e),LL(0x7d8e1f8e,0x73d9d6c2),LL(0x87354e0a,0xd949265a),L_(0xddd78248), + LL(0xd65411f3,0xbb95794c),LL(0x56456f06,0xdb7b7288),LL(0xb5869a96,0x7de9cd89),L_(0x4dd26048), LL(0x235bdd25,0x6b7c47bf),LL(0x3a2f738b,0xb8e2adff),LL(0x43a158b6,0x6452e6ec),L_(0xb59a08ed), + LL(0x3b9a55fb,0xfd294202),LL(0xd446ba91,0x77e86f2f),LL(0x0bfb0e2c,0xb347e482),L_(0xda5432f0), LL(0x811a63d8,0xda7568f2),LL(0xfd584f1c,0x32ddb6b6),LL(0x3e5b388e,0xfbef98fa),L_(0xa2090daa), + LL(0x29e9bf1c,0xebc6de84),LL(0x8601a460,0x77ae022e),LL(0x0fe7b2f5,0x51718d1f),L_(0x768e05f3), LL(0x8f61fd67,0x107bee81),LL(0xdafff971,0x45e70a15),LL(0x775aa267,0xf5af9168),L_(0xa74ac1aa), + LL(0xcc4ccaf5,0x7770d24c),LL(0x6c27e8ad,0x931b3ac4),LL(0x0c21256b,0x5eb3480c),L_(0x24df253e), LL(0xd60ece5b,0x32c4c950),LL(0x304257df,0xfa6d0590),LL(0x3821aab8,0xcfd48043),L_(0xe9ed7945), + LL(0xa563da21,0xf927be40),LL(0xa625fc39,0x65697957),LL(0xc708ccff,0xc7c05c00),L_(0xe3551df0), LL(0x1db01e2b,0x4a824ae6),LL(0x00aff255,0x21fd2abf),LL(0xdc1865ba,0x489f78db),L_(0xc47678ec), +}, +/* digit=26 base_pwr=2^182 */ +{ + LL(0xa7314858,0x4d52ad98),LL(0x44075a5f,0xa2ad3d54),LL(0x5f264197,0xa5da6ace),L_(0x1bd94b24), LL(0x1046d21c,0xaddbfb84),LL(0x9deccfa5,0xdb3e6a82),LL(0x38b0cd4d,0x0ae5bd28),L_(0xcdefc743), + LL(0x11028ec7,0x9f68d2fc),LL(0xdb80636b,0xda67d396),LL(0x399cbe22,0x058ae3aa),L_(0x9a20e964), LL(0xa4afe4c5,0x0655d446),LL(0x82be9278,0xd1f696f1),LL(0x02a07951,0x78c7207b),L_(0x5473af3e), + LL(0xa430f529,0x48532007),LL(0xe1daa6d9,0xf9c913ed),LL(0x8ffcdbb0,0xbd0a98e5),L_(0x9b2bdde3), LL(0x3eec4099,0x58bd4134),LL(0x4dcdfb2b,0x524e44ad),LL(0x29153443,0x7457124c),L_(0x9190c343), + LL(0x0c51f106,0xe34c46c7),LL(0x1a8f4562,0xa808bcef),LL(0x6cddda1e,0xb1bb8fc9),L_(0xa502ea7e), LL(0x9e63e9ac,0x9421a0eb),LL(0x124b21a9,0x09abe1ac),LL(0x634ea315,0xfc9b2b69),L_(0x4d2d4d06), + LL(0xd47adb81,0xa4e345b6),LL(0x370847bf,0xc8a3f346),LL(0x242713b8,0x10782ff2),L_(0xbc286c44), LL(0x0501d40b,0xbe6fa011),LL(0x72197eb9,0xe784765d),LL(0x23d8a846,0x9c366368),L_(0xe57509e0), + LL(0xb79e2ec1,0x9344ebd4),LL(0x41626ac2,0xee0983f2),LL(0xb61e001b,0x1c404975),L_(0x05deb3c3), LL(0xafd8bc28,0x10e30e79),LL(0x4f5429b7,0x90c587f7),LL(0x0cc2b3bc,0xe64edacb),L_(0x2a32f215), + LL(0x683db291,0xa18ec5e3),LL(0x597408da,0x0cdbd7b0),LL(0xb4dc90d1,0x9e4003b1),L_(0xf0377012), LL(0x99f01d42,0x2f737bf9),LL(0x138b7393,0x2c744a14),LL(0xbf91bb7d,0x4390dd24),L_(0xd3eb9506), + LL(0x7da97135,0x1f5f9c08),LL(0xcbb88522,0x60a61939),LL(0x590e948d,0xd63bd64a),L_(0x45a94350), LL(0xc3f04dfe,0x8b9c0e7f),LL(0xc46a6c09,0x24ed2a64),LL(0xe5cb409f,0x6aa2f787),L_(0x90fd8928), + LL(0xa6f20c60,0xc519de26),LL(0xc3ac3715,0xb2ee7698),LL(0x915329a3,0x0ca44fa0),L_(0xe61346f3), LL(0x22cc3439,0xe4d76c97),LL(0x37f7afee,0x360a76e2),LL(0x6bdfe1ff,0x536926c2),L_(0xc048c2a4), + LL(0x33feb155,0x57103466),LL(0x9e779a72,0xf0ac4da3),LL(0xf0cf02a3,0xc4a65bf2),L_(0xc464a2f5), LL(0x9f49b51f,0x771064c3),LL(0x545f80d2,0xf119551c),LL(0x142107aa,0xc2378a52),L_(0x233fc912), + LL(0xd5e26db1,0x2c57b6eb),LL(0xe31036a2,0x2260e245),LL(0x18945c38,0xa0a4a4f0),L_(0xa70971ce), LL(0x51a8f045,0x78d2269e),LL(0x3f54f031,0x08084351),LL(0xd1a3f072,0xcf63943b),L_(0x1bbad8a4), + LL(0x450a90c1,0x7535f2ce),LL(0x2202c2ff,0x29cb37b3),LL(0xad07269a,0xc576098a),L_(0x233792b7), LL(0x368c1c44,0x5864342f),LL(0x02886c17,0x2dca7f73),LL(0xb1a39467,0x74bab9ee),L_(0xe841def5), + LL(0x8df7b590,0x7f584614),LL(0x0ec350c2,0x3c0acdb3),LL(0x2da65636,0xb160863f),L_(0xe9a43081), LL(0xb0ebfa84,0xce3663d0),LL(0xafbf1395,0x69ff1f32),LL(0xdfa06d4c,0x9aa85d56),L_(0x4f103987), + LL(0xc94ce26f,0x7df657b9),LL(0xf5ac31c8,0x0b939fc2),LL(0x1a02ac9f,0xd28fa99b),L_(0x6407f45c), LL(0x9ca2e994,0x06494081),LL(0xe60e26a5,0x6719d6cd),LL(0x44cfce93,0x4db05d61),L_(0xf189ccff), + LL(0x665df7e1,0x16a82c07),LL(0xd179a921,0x85dffbcc),LL(0x51227dd4,0x1d15b312),L_(0x129de8ff), LL(0x28e8d109,0xe117dd1d),LL(0x3f1a519b,0x3db3c554),LL(0xd473a86f,0xe470bd93),L_(0x48ca17dc), + LL(0x2cd73074,0xce23cb8f),LL(0x025cce52,0x27d52714),LL(0x7128e28f,0x60a7af16),L_(0xee37af3a), LL(0x291c3d92,0x228c1193),LL(0x8bcaaced,0x559ca84b),LL(0x60835724,0x5f7c29e2),L_(0x42db013e), + LL(0x80630e79,0xd7266cd9),LL(0x5ce7356c,0xb190aae6),LL(0xc0bdd70b,0x086e72f7),L_(0x3319c072), LL(0xef5d0e48,0x4ae3ba69),LL(0x086343f9,0x95fb3fdf),LL(0x80bc2aba,0xbf3ecc51),L_(0x37cadfe3), + LL(0xaab46c1f,0x66dd80d9),LL(0x32cd82a6,0xaf92ed97),LL(0x11e8daf7,0x6268a0b4),L_(0xbd297ce7), LL(0x1771ff6b,0x971bdef8),LL(0x8c4eabfb,0x446b9cea),LL(0xcbfa339f,0x83d9f14e),L_(0xbd36bd3d), + LL(0x38641225,0xe3a86074),LL(0xf0d2a9f0,0x46459726),LL(0x68a87b42,0x27fad851),L_(0x465da389), LL(0x6ec9b313,0xa438dfac),LL(0x1024a804,0x2f7651af),LL(0x3e3b2c83,0x9e904c3e),L_(0xb0cbbf5a), + LL(0x3daddf8b,0x4f3cafc7),LL(0x4571821c,0xc7f93897),LL(0xb59cdc87,0x564a1eff),L_(0xd3fc8e11), LL(0x32b8d1f1,0x210954cc),LL(0x485b3e16,0x0b89424a),LL(0xa39a8650,0xc71b961e),L_(0x50587567), + LL(0x938ffcc2,0x3f39a45a),LL(0x39ff9b1a,0x22ec814a),LL(0xe9320257,0x293c62a7),L_(0x30d60ad1), LL(0xfe028f50,0x51699000),LL(0xecc36d79,0x687388c0),LL(0x782811c0,0xb9b6100c),L_(0xd4aec2a8), + LL(0x4fa8529f,0xbf6700b9),LL(0xdb67bc3c,0xb75d6fc1),LL(0x81a05a44,0x2a63deb4),L_(0x2c00d649), LL(0x4f57cb6a,0xc429bae2),LL(0x962a325d,0x45995d71),LL(0xf818f011,0x07c3cde9),L_(0x8b0fa963), + LL(0x1767b13e,0xdcf6f7fc),LL(0xd9cd3792,0x4c91cbcf),LL(0xa1b347a0,0x9daa99a0),L_(0x6b0d6566), LL(0xe85fb43d,0x448838bb),LL(0xe794fda6,0x9a62c0b7),LL(0xb6b1fe7b,0xc0cb0a63),L_(0xd09a8df9), + LL(0x0510ae51,0x4c395b4e),LL(0x8e70bc90,0x49d7c304),LL(0x04b3e853,0x9d40e63f),L_(0x4a2dc6ce), LL(0x6ec0b89c,0x36339e46),LL(0x385a4594,0xb1a1676b),LL(0x455a09ad,0x9304dd88),L_(0xc6ff5bf9), + LL(0x7502d288,0xe085cdf7),LL(0x187b4002,0xa35b991a),LL(0x4c4e720e,0xab690dee),L_(0x86287cf7), LL(0x05d1c250,0xe2c63b4e),LL(0x9adbcac5,0x6b60d74e),LL(0xddd28bc7,0x4248e502),L_(0xef074338), + LL(0xc29777cd,0x896670f3),LL(0x08020d96,0x3a144e73),LL(0xe06c4b5f,0x9786e6bf),L_(0x3da82523), LL(0x4a099ef4,0x4fe3491e),LL(0x99758e3b,0x14bb92ff),LL(0x0c3b82b6,0xbab9fec3),L_(0x45c4baf6), + LL(0xc471a0d6,0xb5a9a1df),LL(0x4e7e7ab2,0x56e0f739),LL(0xce6cd002,0x7c86bb7d),L_(0xcadc14a3), LL(0xf7d0edab,0xbef7e6fa),LL(0xbff62993,0xd5068119),LL(0x0a2850cc,0xc5820cdd),L_(0x92bdfe5c), + LL(0x8c84d27f,0x484daaee),LL(0xd799a2f4,0x612b63b1),LL(0x550daad1,0xef0ac41a),L_(0x8fbf8f4e), LL(0x377207e9,0x84f7e136),LL(0x7bdb6e8f,0xfd5152ed),LL(0xd89df99b,0x395821cc),L_(0x20d76719), + LL(0x3fd703c0,0xae387d38),LL(0x760e59a1,0x28b52395),LL(0x97e8f74f,0xbc044138),L_(0xa21350e4), LL(0x86d227b5,0x02533549),LL(0xe3e6583e,0x2b3bb618),LL(0xc654b122,0xa829cd8c),L_(0x39c79315), + LL(0xe57a78bc,0x040ffaef),LL(0xb7bea5b5,0x0bea9607),LL(0xdb5241af,0x372d1796),L_(0x940a8a94), LL(0x4374d692,0xf1499afd),LL(0xcabac4a3,0x4a7889cd),LL(0xb861df89,0x0cb6a234),L_(0xa96fe9bb), + LL(0x7682c515,0x5eedd184),LL(0x4434f8b6,0x5b6b1177),LL(0x2a8d7505,0x86f300e0),L_(0x0e35d724), LL(0x5d047332,0xfaf29ff0),LL(0x4c814382,0xea27ade1),LL(0x141d9196,0xd1bc5f13),L_(0xade4deb9), + LL(0x5fdcb5d6,0x406ace5b),LL(0x1ea243b0,0x088fb509),LL(0xd6070207,0x22934b39),L_(0xd9cd49e0), LL(0x0d4662d6,0x4d0f3174),LL(0xc755b33c,0x4eef4ac5),LL(0xf8e1a986,0xc50467c8),L_(0x18a3ef6a), + LL(0x747a7c15,0x4607dcec),LL(0x614bcea6,0x5f5ba78f),LL(0x68ae9194,0xf3906a4b),L_(0x42d006dc), LL(0xde1842dc,0x4cb64b0d),LL(0x9dbec629,0xba893ced),LL(0x0bf6a2f2,0x057751b4),L_(0xa9fae60b), + LL(0x6b278395,0x3c12fc74),LL(0x017d14d0,0xc71b3f43),LL(0xc6c97422,0xa51b04ab),L_(0x626c81c6), LL(0x3b8a9b8d,0x238bcf03),LL(0x5e266a2a,0x6ca507ab),LL(0x23764003,0x51803104),L_(0x5f7162bf), + LL(0xfae6aeea,0xa5dd759e),LL(0x522db1a2,0x5e4a05cb),LL(0x09f2baed,0xf85a6ac1),L_(0x323304d4), LL(0x5e98632e,0x1360791b),LL(0x1db93b31,0xb1ea2fc8),LL(0x1b768230,0xabf3fed8),L_(0x87d85b61), + LL(0x79a68d97,0x761f1b7c),LL(0x0b49a02f,0x3ccdde40),LL(0xbb854598,0x77637e3e),L_(0x0022290f), LL(0xdfc1715a,0xf0700420),LL(0xe0410aa3,0x4a5a58b2),LL(0x6d34be85,0xf6bc18c0),L_(0x46cdba65), + LL(0xe6b65986,0xb9773b59),LL(0xc5228020,0xd35b5bb3),LL(0x453c7ac2,0xf11276b9),L_(0x7df2cd47), LL(0xcbee2352,0xf5a8c36a),LL(0x179c274d,0xba21cd5c),LL(0xa5c5bb12,0x11df901f),L_(0xe17d00c3), + LL(0xb8d6f9d0,0x3ed4c79a),LL(0x8883a1db,0x60bbaf97),LL(0xfdd5776e,0x2f54ff27),L_(0xcb776738), LL(0x589db69e,0x9a98b106),LL(0x79c8cc7c,0x9590d453),LL(0xdc2c596a,0xc7ee141c),L_(0x6b47161b), + LL(0xb554abc5,0x543685f9),LL(0xc2395393,0x329ac98a),LL(0x9a0b36b0,0xaae1a4bd),L_(0xd5d4e38e), LL(0x0637ec30,0xc2e17c96),LL(0xd7e5c5cf,0x54bb5d81),LL(0x2bef0600,0x9ed78a64),L_(0x561fb810), + LL(0x4b821219,0x2fe8fb71),LL(0x1a1e9b3b,0x4feedce1),LL(0x3925b0ea,0xbfb2449b),L_(0xb054dfbe), LL(0x29864158,0x28647223),LL(0xa5055940,0xe2ec01b2),LL(0x31e1b9a5,0x23b5a4c4),L_(0x195035c8), + LL(0xbdf1c841,0xcc50c48c),LL(0x209f3af8,0x1489a642),LL(0x181662d4,0x4b465365),L_(0x91296676), LL(0x9e845d49,0x138dff73),LL(0xed5f5189,0xe47473ab),LL(0xc0ded518,0x40df6431),L_(0x723fb4ad), + LL(0x38970226,0x112db661),LL(0x3569136f,0x7a1d7c16),LL(0xb8e53775,0xdd45fe78),L_(0xfaa04e8d), LL(0xb657c7ea,0xf6371e53),LL(0x86806849,0xf29213b2),LL(0xf4779601,0x4c858ecd),L_(0xa4992880), + LL(0x77e1f87e,0x89673149),LL(0x156e1198,0x03cb4796),LL(0x39eb8237,0xecde7783),L_(0x6d9c66e5), LL(0xe3363ded,0xd2f38b47),LL(0x3fba7225,0x0a4d15cb),LL(0x088944d2,0x4f8035c2),L_(0x33f1f404), + LL(0xa1983b54,0x51cb66d5),LL(0x58d0680a,0xaf231cb5),LL(0xcb3e58aa,0x1d2325d3),L_(0x13427358), LL(0x6d4b8ce2,0x7dbb0bf1),LL(0x85f983bc,0x3bec3e74),LL(0x0f88839b,0x8a991a31),L_(0x6b3985b4), + LL(0xf774901f,0xdf68b707),LL(0xde5b911a,0x0c634df4),LL(0xeed92206,0xfc74f9a9),L_(0xbcecf38d), LL(0x3a74e355,0x96e739bf),LL(0x0a6c0e27,0x9a315c68),LL(0x82400ede,0xbba8f32c),L_(0x27d5bb2b), + LL(0xa27fb54f,0x3131df10),LL(0x042f1a03,0xac9267a7),LL(0xe003b634,0xa22e7895),L_(0x6dd1e8b0), LL(0x4591bb21,0x90518b2b),LL(0x5efe4007,0x9c565a5c),LL(0x88b87e5d,0x63c085ee),L_(0xf6155e0f), + LL(0x9a0ef584,0x841e4add),LL(0x1f02ab50,0x7b5e812b),LL(0x67a50be5,0xe6f206a7),L_(0xf1e42056), LL(0x737ad369,0x2febb4c6),LL(0x657a0dc7,0x93b35fb8),LL(0xbbf3484b,0xea4f285b),L_(0x020b154e), + LL(0xa95bc0c4,0xdbbe1817),LL(0x91e4e9f4,0x8583001a),LL(0xbf43b7fd,0xe4667773),L_(0x52865635), LL(0xec4299f7,0x5962ba86),LL(0x28fe8ab8,0x3849c7d1),LL(0xd449338b,0xd636805c),L_(0xa1efd1c9), + LL(0xa552a401,0xdfd448aa),LL(0xb92e258d,0x3f8fa817),LL(0x35b6d45c,0xa42ce187),L_(0x0d195771), LL(0x0ca7ae66,0x672eaebb),LL(0x60feb26e,0x34d002fc),LL(0x94989870,0xb3b0ede4),L_(0xc41d2caa), + LL(0x75191aa5,0x5261f5a6),LL(0x330e8a48,0xce0728c4),LL(0xf61c72d3,0x33ca48fd),L_(0xffeebdb0), LL(0x7973a221,0x7ae9478e),LL(0x73383a11,0x2d6cf157),LL(0xafb5d296,0x689cfdb3),L_(0x32706d23), + LL(0x5b0f9106,0x0bd73e3b),LL(0x62c3a48b,0x2c31c735),LL(0x0c0a3d1e,0xacf48d35),L_(0x48c97582), LL(0x9aa2cb41,0x01b5bb28),LL(0xaf780b08,0xd14e0836),LL(0x2a0a2d75,0xabcaf322),L_(0x13f7f83f), + LL(0xf123c708,0xb992a79f),LL(0x19a0cf96,0xada9dff4),LL(0x98adc9dd,0x6a4d3e6c),L_(0x40f8faf2), LL(0x676dfe03,0xef011d37),LL(0x7e67e105,0xb029aa6b),LL(0x87eb4d53,0x45add6b3),L_(0xce77f195), + LL(0xfdc3ee1e,0x3d9993bb),LL(0x8adaa277,0x9c19b8ff),LL(0x1fca3093,0x7433657e),L_(0x8caf0d86), LL(0xcbbc468c,0x85112380),LL(0x3dbd4315,0xa4c53f5c),LL(0x9d410bfb,0x374f5e1e),L_(0xf2fcce49), + LL(0x058ab78a,0x532b7587),LL(0xd3243b22,0xf94c79ad),LL(0x11c1365e,0xb045d4a7),L_(0xb70776bc), LL(0x35abd993,0xadb798da),LL(0xe29a9f85,0x449472ae),LL(0x04e83977,0x4ef414c2),L_(0xd94bbca4), + LL(0xe9445da7,0x69a5c563),LL(0x189faa10,0x013c6f09),LL(0x11ff4092,0x270bddfa),L_(0x13f400ef), LL(0xab739108,0x54c1f415),LL(0x5467f97f,0xb88a9ecf),LL(0x8a19f9f7,0xd713b7c7),L_(0xbecb24c4), + LL(0xa9451b5f,0xd9e41b7c),LL(0x154bb407,0xb69c99b7),LL(0x9e3d7f55,0x0a7b54c7),L_(0x135359b7), LL(0xd2d3aed3,0x84d9fef7),LL(0x5d18cdb1,0x61c13355),LL(0x142d7261,0x1cba3904),L_(0xac50bd6c), + LL(0xb8b1ee7a,0x709ebb7d),LL(0xec49c916,0xd7ba31a4),LL(0x16f1cdf7,0x9b4ca4e1),L_(0xd65f4a10), LL(0xad080359,0xf98d2d14),LL(0x03b182b1,0xe7c36b4e),LL(0x060b7206,0xb11e15e8),L_(0x6d96c56b), + LL(0xf8d054a3,0x8f77e5e4),LL(0x72cd83b6,0x93dad056),LL(0x25a5b5bf,0x25a2e699),L_(0x6fdd7673), LL(0x0063d830,0x90a6d4fe),LL(0xd576b9f6,0x3c44f207),LL(0xbcb25092,0xad2b4418),L_(0xefb79bc4), + LL(0x01e94264,0xfba463c6),LL(0x67359a81,0xfc726fd8),LL(0x2c69efd6,0x280e7df6),L_(0x74569519), LL(0xa6c619bb,0xe2c76093),LL(0xb18f6667,0x8f9466f6),LL(0xbd326eec,0x88831553),L_(0x87869f49), + LL(0x88c46f2f,0xbaa57c7c),LL(0x3b207add,0x7299422c),LL(0x4ed0514a,0xb373586a),L_(0x309bffcc), LL(0xc5186b1b,0x461b005b),LL(0xc0f53c53,0xbbee060f),LL(0xc558624a,0xcda6e3b1),L_(0x6faa11b6), + LL(0x1f345075,0xf0680ab2),LL(0xcbfa17ef,0xe657cfab),LL(0xcddb5b82,0x41c78a0d),L_(0x20234c33), LL(0x65c9a0da,0xc2fe9028),LL(0xf4f1f1bc,0x14464393),LL(0xfc36a9bc,0x75517f43),L_(0x7adc3f7c), + LL(0xc9f99571,0xba51387a),LL(0x49c36869,0xfba899b3),LL(0x03e373c6,0xb8b4767a),L_(0xb07a3f0c), LL(0x7fc1b90f,0xe85c5039),LL(0x808f702e,0x94d61e9d),LL(0xdddd86d9,0x7011d76f),L_(0xfae1c7e7), + LL(0xf98efe50,0x80fa818b),LL(0x31e4ef2b,0xf1aadc09),LL(0x68d478dc,0xb3f48a44),L_(0x7630fe61), LL(0xaa830a4a,0xf7c94ece),LL(0x9a533238,0x04218b55),LL(0x5e7ce696,0x3b49d1b1),L_(0x52a95933), + LL(0xc81b286e,0x0d20898e),LL(0x9d1c985c,0x3f1398f8),LL(0xc62ed966,0xce3b7676),L_(0xeb820161), LL(0x4dd1834e,0x60f14618),LL(0xe6d270e0,0x16b9b346),LL(0x80e6594b,0x9e645987),L_(0x879e807c), +}, +/* digit=27 base_pwr=2^189 */ +{ + LL(0xe215ad69,0x0703230b),LL(0x9c23cc7f,0xcb4845fc),LL(0xa6d601b3,0x3f2e4ff0),L_(0x8b1b5936), LL(0xd006b554,0xe0882f46),LL(0x402ec9ab,0xd39b85a4),LL(0x47de2c7e,0x555b4d4e),L_(0xeaa5bf4d), + LL(0xc42ab049,0xf78b555a),LL(0x971ade84,0x9092aa3c),LL(0x4e8a2ef9,0x5ad4ea73),L_(0x0425d602), LL(0x2b7e58ba,0x791d9122),LL(0x227d0459,0xf3147395),LL(0xc9d765a1,0xe4f1346c),L_(0x28b65397), + LL(0xceec40d6,0xe7d16970),LL(0x871eef82,0x361a2299),LL(0xb5fdd432,0xb27a33c5),L_(0x1d066c2a), LL(0x1d4d340e,0xe97230fd),LL(0x862b60db,0x5852f3b4),LL(0x593d4118,0x539f6530),L_(0x8436da66), + LL(0xe5f6d86b,0x2425af9e),LL(0xead58c17,0xe4dac347),LL(0xb5cbb50e,0xccdd8dd9),L_(0x86b3650e), LL(0x95382a07,0xdc320634),LL(0xa3e665cd,0xe9848376),LL(0x1e2d319e,0x33fae415),L_(0xeca579c1), + LL(0x372307a3,0x6a9d1fc4),LL(0x89b65031,0x50fbf109),LL(0x23a987e1,0xfde88e7a),L_(0x2dd37a50), LL(0x2947bdb3,0xcebc549b),LL(0x820f3f12,0xab66e245),LL(0xb7bcaa87,0x694bc71e),L_(0x8e6e09c1), + LL(0xc6572555,0xfe8a98ef),LL(0x63ff767a,0x71371393),LL(0xc5f7f4d1,0x0e5335e1),L_(0x7cfba5a2), LL(0x96ccd504,0x77da1976),LL(0x67e59eaa,0x16544c87),LL(0x504acfd5,0x96be881c),L_(0xbeef988a), + LL(0x3faff788,0x82325976),LL(0x575e852e,0x05c5a091),LL(0x2c72e2f2,0xe0cc66d6),L_(0x1927e387), LL(0xb872a6ad,0x4d0b0121),LL(0x7da1cf59,0x5bcfc963),LL(0x26204672,0xdb25f5a7),L_(0x0a8b1258), + LL(0xe8b35d2e,0x7d69f703),LL(0x20d3988b,0xc271bab1),LL(0x6c24b0c1,0xaab259f9),L_(0x5e65b843), LL(0x51fcf150,0x75e5c2e1),LL(0xea29f462,0x8993613b),LL(0x1834a191,0x8c9eae94),L_(0xf967c0ea), + LL(0x41292928,0x7e9bdb88),LL(0x00adf08d,0xc2ca609c),LL(0xa0138acf,0x8dfb7875),L_(0xd93b37ee), LL(0x3666deb2,0x749de945),LL(0xbfd574b2,0xe95a61ae),LL(0xe75abd5a,0x67c65b64),L_(0x13366a27), + LL(0x21088150,0xb08be400),LL(0xe06fcef2,0x86d73e23),LL(0xe0ba359f,0x607c14ca),L_(0x382ff71f), LL(0xe5594024,0x6404f03c),LL(0x3f8a49f7,0x148ec4e9),LL(0x7853702e,0x4887d191),L_(0x04d3f5e6), + LL(0xd2a149ac,0x67857251),LL(0xdb805369,0x8e8ea485),LL(0xd63c66e4,0xa73ff057),L_(0x587ee86f), LL(0xfb2b3fde,0xa10a6759),LL(0xbd927cb1,0xfc748cd7),LL(0xc799e97c,0x6f65ee19),L_(0x4703e5a8), + LL(0xa25a7805,0xaa2f24f7),LL(0xba32a728,0x7fcf37bf),LL(0xb7ad366d,0xa0ac6a50),L_(0xb220a09e), LL(0xcb955e95,0xd5db1087),LL(0x44a3150c,0x65f007ad),LL(0x09784fd1,0xf6f05498),L_(0xc1e6c0b0), + LL(0xc19f511e,0x06b7160e),LL(0xbb692e48,0xc84c111e),LL(0x15498ecf,0xb77b124d),L_(0xbb092f5d), LL(0xc61f57ba,0x74e3ca97),LL(0x7b0969cb,0xd5839144),LL(0xf86a2cf8,0x6d59ed66),L_(0xdeabc883), + LL(0x9f404ee0,0x17174a2e),LL(0x852eae73,0x1bb80f22),LL(0x1e348f1a,0x0374bff3),L_(0xeacc5568), LL(0x8d863212,0x5585a76c),LL(0xa921615e,0x66b5bc71),LL(0x1b74c1fd,0x26867d50),L_(0x52fb37fb), + LL(0xd2f49002,0xb96496b7),LL(0xe996dbee,0xa5746d1f),LL(0x39670ef3,0x8094e471),L_(0x9c159e05), LL(0x286d79a8,0x4226465a),LL(0xb7fd505e,0xbf1aca6c),LL(0xf2355f67,0xe46e77c4),L_(0xe0fbfc8b), + LL(0xea2be4c9,0xc386d032),LL(0x16b11ec1,0x828f0d4f),LL(0x75da11d8,0x94c7a19f),L_(0xfda19041), LL(0xd7f40cb4,0xcd2bfd30),LL(0x0e5ba2ee,0xb240b8db),LL(0x2339d87a,0x375d7766),L_(0x24af1974), + LL(0xd5cb473f,0x0c7c5c0e),LL(0x06c1fc0c,0xb684879d),LL(0x1d94e717,0xb65c6a50),L_(0x0b30821a), LL(0xd7821eb5,0xefa6a39d),LL(0x6459b552,0x727bdd40),LL(0xb7d7e4b6,0x18598afa),L_(0x00b319ed), + LL(0x703608d7,0xf884841c),LL(0x8dad7679,0xe15515c9),LL(0xb306db5d,0xb36c0754),L_(0x5229df9a), LL(0x979aad60,0xaadea0d7),LL(0x970bb22c,0x6c1b7c90),LL(0x298689dc,0xf3b57c01),L_(0x89fe17ad), + LL(0x428e4fe4,0x76218fd4),LL(0xceff7d9d,0x975a4605),LL(0x63a383cf,0x238b4e91),L_(0x99f29b16), LL(0xccf0edbc,0xe11ea485),LL(0x7ae47927,0x93601402),LL(0x7cd7a8d0,0x0d9f157a),L_(0xb3fa2b87), + LL(0x9e4d4311,0xff049f88),LL(0x85fe8244,0xcf8e1ceb),LL(0x5d2ff231,0xef0f5b1a),L_(0x63ccdc00), LL(0x959a2ad3,0x8ba95ec0),LL(0xa8a44260,0xbd876759),LL(0x6ed75cfa,0x3e43af21),L_(0x8464e573), + LL(0x444c26f1,0x65d29b4c),LL(0x1583a353,0xee5f7609),LL(0x43193114,0x92998e59),L_(0x704abb0e), LL(0x99be8a63,0x2a7e16f6),LL(0x4c98adbf,0xe1fc70da),LL(0xa5a25fbe,0x44dc73bb),L_(0x8fc488f7), + LL(0xa3bfed42,0x784f9377),LL(0xe7bcd034,0x07fc5bf3),LL(0x89f2f24f,0xbec66d27),L_(0x4917e013), LL(0x3a3c1ba3,0xf0cde4d7),LL(0x0961875a,0x69bd4eb3),LL(0xa260b4df,0x59faeb8c),L_(0xbeeb1631), + LL(0x21f06827,0x280f3962),LL(0xa088a1e1,0xcf16263e),LL(0x1dbee473,0x1692a131),L_(0x05a158ea), LL(0x283c279b,0x0a11b121),LL(0x0e13e263,0x8ed3889a),LL(0xdee544e9,0x5dcaae12),L_(0x8f1fbb34), + LL(0x87dc2c5f,0x5d2e90ad),LL(0xb9ad99ac,0xed6943f8),LL(0x0c329529,0xaa459865),L_(0x96ffc387), LL(0x34567b61,0x13516c2e),LL(0xa0aa883b,0x39122bf4),LL(0xbfa72fcc,0xa825f1f8),L_(0x97da099b), + LL(0x67b5c14e,0x14bced82),LL(0xf4fdf535,0xff66cf51),LL(0x689f6f0d,0x71814baa),L_(0x5b8ff385), LL(0x247c8262,0x9c1ba7ce),LL(0x907e4e69,0x4b578253),LL(0xff0ce18c,0x2458cb25),L_(0xef5cd0aa), + LL(0xb909db13,0xfee8b8ef),LL(0xa4710d21,0x1107af8a),LL(0x54895b98,0xb541a6b0),L_(0x526b0ca4), LL(0xa7097ce7,0x16947322),LL(0x31b294e5,0x29af3ae4),LL(0x1b4cb2b5,0x98687802),L_(0xfbcc3509), + LL(0x1586105f,0xb150cf07),LL(0xe16b93aa,0xa4bbc36a),LL(0x253eb0dd,0x984df68e),L_(0x87118c04), LL(0xcb079f80,0x480076ec),LL(0x0dcde0c7,0x6b489d1e),LL(0x18bdffd8,0x16aa0174),L_(0x1f265d34), + LL(0x59614a61,0xee0e75bd),LL(0x5617d582,0x52348cb9),LL(0x3e671da9,0x0190d33a),L_(0x3bee1eff), LL(0xaa01d03e,0xe617dbcb),LL(0x09cde5ef,0x84c57057),LL(0x888eade7,0xfc85f3d6),L_(0x359daa39), + LL(0xd48bf3db,0xb342c647),LL(0x4a00b224,0x40b2d73f),LL(0xb894175c,0x58a94e88),L_(0x70cf2206), LL(0xb4cd9a9f,0xf20b5560),LL(0xdca48b9e,0x1a01b8da),LL(0x7707c57e,0xa0a1a133),L_(0xc33e6b03), + LL(0x727e08d2,0x9c8970a1),LL(0x4c16f18a,0xf1b1124a),LL(0x57b552ca,0xda495e0b),L_(0x1a9ee7da), LL(0xe079a731,0x1ad4dac4),LL(0x06f7634a,0xf219d184),LL(0x1b77c61d,0x110655eb),L_(0xd5bf028c), + LL(0xf20ff378,0x21c59244),LL(0x51b05ff6,0x7d017e8f),LL(0xaf13b9eb,0x2b5c0017),L_(0x4aa9bdff), LL(0x2371404f,0x703d8718),LL(0xaf5e4830,0x1cdec0ba),LL(0x52cc936a,0xf59d1925),L_(0x013abb12), + LL(0x0e22d6ca,0x1082f990),LL(0x2c9f0b9e,0xf4898bd8),LL(0x666e06e5,0x703ab683),L_(0x6f1b6308), LL(0x2a6a3005,0xc8b722db),LL(0xd103845d,0x3ef671a0),LL(0x2459c28d,0xd0ce016b),L_(0x60884f40), + LL(0x59320b15,0x7f7ba17f),LL(0xe194bda2,0x52a3af1a),LL(0xbb90a873,0x2977890c),L_(0x3dc3fa11), LL(0x13cb3938,0x1ec1818b),LL(0x2f976a14,0x813e2d47),LL(0x6ef670b1,0x547bbc14),L_(0x7a6392b3), + LL(0xbee8917d,0xfa44c4a2),LL(0xd1652cf8,0x11ddbdcd),LL(0x7b98c98d,0xeeaab800),L_(0xb60ccb53), LL(0x699cc945,0x20bc5779),LL(0x3d3d111a,0x5d171d19),LL(0xf1c69a57,0x4586a0f5),L_(0x047748d6), + LL(0xcb2dd3a2,0xbfb2046d),LL(0x1ba40992,0x4ab9b7d4),LL(0x492e1976,0x8fa3d075),L_(0xb62a0315), LL(0x9faa1011,0x08bcfaa8),LL(0x55ee388d,0xa8201ba0),LL(0xb50f4e76,0x48d16444),L_(0x947b5775), + LL(0x7bb21f8c,0x27f91139),LL(0x9933e071,0x7328102f),LL(0x16712a5a,0xc739c006),L_(0x75d0d886), LL(0x0d97d602,0x95eed6e2),LL(0x5fd2d047,0x4657933f),LL(0xfa45dd80,0x9d54f1fb),L_(0x741b92d0), + LL(0x4b499dd3,0xe5114e38),LL(0xc2275c0e,0xc9aa88b0),LL(0xb4d5582b,0x3e016601),L_(0x25741fdf), LL(0xe08edbac,0x4514d2eb),LL(0xc4ccb66a,0x16e96390),LL(0xb57016cb,0x59b84d70),L_(0xf83fe7e5), + LL(0x697291df,0x7a6974e3),LL(0xcecae61e,0x747d2ddd),LL(0xa93265cf,0x1f1fb9f1),L_(0xf3c9e95d), LL(0x05b8ad90,0x76333190),LL(0x5ef96caf,0x2e7e8b35),LL(0x26204dea,0x66ec9969),L_(0x8ee499c3), + LL(0x7d3e7f82,0x1abe8df3),LL(0x0e4c49fd,0xf5621bfb),LL(0x5430fd38,0x5d968105),L_(0xb2efc301), LL(0x7fa73503,0xde3d9216),LL(0x191e5b5e,0x358512db),LL(0x32722378,0xa0892090),L_(0xd92f1352), + LL(0xfec9743d,0x757c94ef),LL(0x9649e576,0xf290f932),LL(0x79587916,0x8be7ad8d),L_(0xadd01304), LL(0x61f6de8f,0x29445ca0),LL(0x285b7eef,0x1426c1d9),LL(0xae55ea09,0x962f7357),L_(0x983ad1c5), + LL(0xdfa17534,0x40d7b215),LL(0x3897f22b,0x4a689975),LL(0x0a2968a8,0xae9ce773),L_(0x5eeabf53), LL(0xb2a472ce,0xd7707d10),LL(0x3f8692b7,0x11cc24bf),LL(0x416e3f6c,0x0e77bce9),L_(0xf53b376e), + LL(0xe52b9bd7,0x211044a2),LL(0xb9dbcba3,0x32202391),LL(0x7e52000c,0x2961ea4a),L_(0x12e1a413), LL(0xae4f775c,0xc87793ae),LL(0x36916c16,0xadc59df4),LL(0x93f3db96,0xf4f9dbfb),L_(0x2bfda0b4), + LL(0x04c1afdd,0xbbbbeb9c),LL(0xcc1030ad,0x0de0dfaa),LL(0x49bedb1d,0x1869975f),L_(0x6a004fbc), LL(0x0b0e188c,0x51c16437),LL(0x71e53119,0x3e18f624),LL(0x5e139c48,0x60f866a3),L_(0x0784d6e0), + LL(0xc173ecc1,0x97f340e7),LL(0xa61d043f,0x444c1c32),LL(0x4c35a67a,0x8581b05b),L_(0x44182222), LL(0x731fc41e,0x45bca0e4),LL(0x8bf96ead,0x853c2a7b),LL(0x7c86a091,0x2ad3d962),L_(0x7ea985d4), + LL(0x5d1d3e02,0x1ef28f3e),LL(0xcbf512f8,0x72330e86),LL(0xdc8ed43f,0x516f1183),L_(0xec32dc2b), LL(0xd7b96122,0xc45e5ada),LL(0x505156da,0xdf67ff42),LL(0x983acb8c,0x30958d17),L_(0xe6ec6def), + LL(0x569438de,0x1072cfdf),LL(0xaaf2a64f,0xda01f192),LL(0x33454609,0x8b880e7d),L_(0xa7a46a05), LL(0x35cc6b77,0x7354fe07),LL(0xd5821805,0xa74b9400),LL(0x0fc1cbb1,0x0e58985d),L_(0x9f7a9dad), + LL(0x84ac106e,0x9dc30814),LL(0xe1ebef86,0xcd23c165),LL(0x852da87b,0xed5cdd01),L_(0x21bc828d), LL(0xce6842d7,0x5aadc859),LL(0xe522baaa,0xe89ad998),LL(0x608b4b16,0xee466b6e),L_(0x0c33a24a), + LL(0x8243d368,0x4e1fae12),LL(0xf397b191,0xe6b7d57c),LL(0x2940f1c8,0x47dd818f),L_(0x68c77c89), LL(0xe08f2ebf,0xba40969e),LL(0x8ffaa799,0x102a6172),LL(0x712df945,0x997feef1),L_(0x4da4261d), + LL(0x455b0c0c,0x1b0afa51),LL(0x69fea568,0xf8ba1286),LL(0xdfc334a6,0xa2587e32),L_(0xf61b674f), LL(0x060208cb,0x62eb8d23),LL(0xdd643088,0xa1a3f3bd),LL(0x5cde0036,0x53b8bdc0),L_(0x1c5ce488), + LL(0xb0c1bb5a,0xa64a20a5),LL(0xd22b7f88,0xf22948de),LL(0x0628283c,0x75129c40),L_(0x6efeb06e), LL(0x4000d1fd,0x76f8c148),LL(0x181e8b58,0x7b823883),LL(0xc758648b,0x3d1fbafb),L_(0x069f31f1), + LL(0x2b15bfdf,0x78f3872c),LL(0xbba94fb7,0x49778942),LL(0x852ef997,0x48ddef24),L_(0x066ad60c), LL(0x38c99352,0xc1ba735f),LL(0x790d395b,0x30382b1c),LL(0x7616ea81,0x61b408b8),L_(0x9278e0eb), + LL(0xc0f1bdbb,0x15c9a84f),LL(0xae384504,0x1419e604),LL(0xf4814e2b,0x1b8b0e26),L_(0x2b97a1b4), LL(0xf8656f5b,0x260ef3d0),LL(0x5db22d7e,0xc76c3691),LL(0x2e7c6bf8,0x7c1471d1),L_(0x7bdec3b1), + LL(0xa27bd94f,0xb71fd22e),LL(0x7f17f289,0xbbacb216),LL(0xd4564a47,0x34b284d4),L_(0xb75a3120), LL(0x09622583,0x986c8a28),LL(0x197cc0c1,0x208425a0),LL(0xcc3ae593,0x7da4599c),L_(0x54ebd08e), + LL(0x2d21c888,0x9addab68),LL(0xbd0c6b5c,0xcad27cf0),LL(0x7ec99646,0xaa918115),L_(0x8ee2e6eb), LL(0xea74e73d,0xd9db5cd3),LL(0x2d90dfec,0x719d6c8b),LL(0xf48ec5bb,0x7732d381),L_(0x2daa3783), + LL(0xfe67cafa,0x4087fb31),LL(0x64d12677,0xa7b372c6),LL(0xd6d5d34f,0x5aa57c66),L_(0xeebb82c5), LL(0x03f99f8c,0x0b3a848f),LL(0x4bcc334e,0x3076a517),LL(0xafc73b46,0xbdc15e76),L_(0xba3353c1), + LL(0x666e86e2,0x3f49b089),LL(0xe4f392d0,0xb96b8ccf),LL(0xc0bd57d7,0x4a84d25e),L_(0x8b9c3a47), LL(0xdd447511,0x88262b51),LL(0x5d6233aa,0xf3ee05e8),LL(0x1da165fe,0xba39a0b7),L_(0x56569118), + LL(0x4b2743e8,0x55aff6c3),LL(0xffb26779,0x0356100f),LL(0x581f3f38,0xc259ed17),L_(0x0527ce42), LL(0x9f2d81ee,0xeb967185),LL(0x592962f6,0x58f98402),LL(0xbc866b82,0x9a5ee9a2),L_(0xb8fcf82b), + LL(0x50d6a742,0x7b7d67a1),LL(0x6bed8eca,0x0cc91aac),LL(0x74e18696,0x3ac5ac85),L_(0x4777aaae), LL(0xfcd5973d,0xaf83cba8),LL(0x114e541f,0x44df12cc),LL(0x49c90e0c,0x6ffe97ac),L_(0xd22caea2), + LL(0xf6ec95c0,0xad0a7c5c),LL(0xcf68be2d,0xef894370),LL(0x46042df0,0x44cc34c3),L_(0x83baaad0), LL(0xda2df354,0xe5be5f7b),LL(0x232306d2,0x09c99b41),LL(0x30e3711b,0x7b102ef8),L_(0x90ca6b87), + LL(0x9041d06a,0x24f85c28),LL(0x1c82027d,0xc05d59fb),LL(0xc82c4968,0xf294dde1),L_(0xa0dabc8e), LL(0xc334c99a,0xeadad609),LL(0xa2d74908,0x47f2b704),LL(0xea64f015,0x3b0536e3),L_(0x948d4413), + LL(0x90fcfab4,0x4cd8e163),LL(0x7e58fb10,0x9bc6ae53),LL(0x3a2788f9,0xc860f6b9),L_(0x673a28d4), LL(0x95e581f4,0xc5e46853),LL(0x62c5a4e9,0x6d07718f),LL(0x059005a0,0x5a617a3d),L_(0x06267ff2), + LL(0xe3e68d85,0x2af744e2),LL(0xae8162d5,0x16487042),LL(0xbe28dd7a,0x950dd089),L_(0xcd76243e), LL(0x6a083312,0x887a306e),LL(0xc5cf5f6e,0x963509bb),LL(0x6076457e,0xd58cb75e),L_(0xa5a9063c), + LL(0xe722f017,0x6f63cd75),LL(0xa7571852,0x216d76b1),LL(0x2ab669d0,0xd42dd087),L_(0xee6f2f6d), LL(0x097743cb,0x0a7d1e20),LL(0xfa5d28f5,0x21dad6f5),LL(0x9441fb90,0x8466e082),L_(0x4a673507), + LL(0x55c0ab69,0x980ae610),LL(0xc6222c7e,0x5c17d9ff),LL(0x3030f359,0x9b8f42e0),L_(0xbbf50262), LL(0xd0aba7f0,0x469ee64e),LL(0x3ef5e0ea,0x45ce7ede),LL(0x0e1c1519,0xb57bce91),L_(0x806bb655), +}, +/* digit=28 base_pwr=2^196 */ +{ + LL(0x18e92c63,0x4760716e),LL(0x789ae13c,0x03cdfbf4),LL(0xf578d1e6,0xc6470ce9),L_(0xd42e2969), LL(0x4db766a1,0x5f1cf230),LL(0x733456c6,0x1237a68d),LL(0x592bb19a,0x91e21ef9),L_(0x8814ad36), + LL(0x91a052d2,0xbefb4b7b),LL(0x6eb484b6,0xf5d7b19f),LL(0xa01ef7f5,0xdc02e33e),L_(0xf8ac22f1), LL(0x1ee85810,0x0cbad014),LL(0xc2d60cca,0x0ecada19),LL(0x78a4abe0,0x375f545c),L_(0xbb2518b8), + LL(0xe924bce1,0xe94cf6cf),LL(0x721159cc,0x3c03f7b7),LL(0xd001dacc,0xba328884),L_(0x6ca68824), LL(0x99214785,0x857c60d0),LL(0x3e1c1a16,0x6d9d01de),LL(0x4e3a8a4a,0xe5100cc6),L_(0x2fadd498), + LL(0x21699c26,0x96e332c1),LL(0xba35b5c5,0x3b2527e2),LL(0x32a3227e,0x3d572604),L_(0x3287caa4), LL(0xfa83e20a,0xd3d8aa48),LL(0xd8f05722,0x42872cdc),LL(0x211c6e5e,0x789832b8),L_(0xd7095c24), + LL(0x76f2859a,0x8e5e0a08),LL(0xa554b8a7,0x49d7fe17),LL(0x3cfefa32,0xde9b7d08),L_(0xb712685d), LL(0x3f072319,0xd942a6e3),LL(0xc242dae3,0x105e78a0),LL(0x5c2986c1,0xca0a3ad3),L_(0x58984f5a), + LL(0x90f303c9,0xbb8f3d66),LL(0x75e4f894,0x9f67adfd),LL(0x597d61ec,0xc5900752),L_(0xbb05ff05), LL(0x608daf57,0x78265562),LL(0x8bb8c320,0x31f9a44f),LL(0x2afed365,0x9604812d),L_(0x2ecd08d1), + LL(0x254ed32d,0x4f8511c4),LL(0xf62b6ad5,0x437b9a4f),LL(0xe0ab6bd6,0x9849b3b9),L_(0x437c1eb4), LL(0x99f67517,0x60c66156),LL(0xe2da9ad4,0xe7f23f9d),LL(0xc72b155a,0xe933cc08),L_(0xad7576ea), + LL(0x83df61c0,0x019aa18e),LL(0x06661e71,0x159ba381),LL(0x2a662ce2,0xc9069497),L_(0x5ff8cdb7), LL(0x90a3120f,0x22ef5986),LL(0x62a400b7,0x4c18595b),LL(0xb2915c27,0x1fe38da6),L_(0xffba34b0), + LL(0xeb9b1c9e,0x6335b063),LL(0x6133838a,0xfc5ad1b9),LL(0x76c52676,0xce767a1c),L_(0x5e465185), LL(0x3794090c,0x93f4d92f),LL(0xce0d54ed,0x25dd3904),LL(0x742e50dc,0xabc94edc),L_(0x78bba80f), + LL(0x887eb7e0,0x4b83b6cd),LL(0x81b49586,0x1b46a818),LL(0x1fa505f1,0xae4acd7d),L_(0x832817ef), LL(0xc574766b,0xd6ef910f),LL(0xd59182a2,0x2419996a),LL(0x764ce5bd,0x323e203f),L_(0x63236d14), + LL(0xf567e8d7,0x118cb519),LL(0x8ea6b928,0x1c12c8c9),LL(0x56dd68b6,0x395935d8),L_(0xbd116bcd), LL(0xfc1ac8c8,0x5ced4a6b),LL(0xbb4ec3a0,0x5a7b4c09),LL(0x63f4b4af,0x1f24cb4f),L_(0xf9b9d0b1), + LL(0x596243e7,0x18a50232),LL(0x25f531db,0xaa27b297),LL(0x8b3f0f16,0xa0701098),L_(0x6a6aef50), LL(0x60fe4fb4,0xfb3a537d),LL(0x8c64961c,0xd4b3fc26),LL(0x83f4d9b6,0x440a2f19),L_(0x7696fcba), + LL(0xf34d3bad,0xc0f2402b),LL(0x5360ffc2,0x2a9eb601),LL(0x8d33aed5,0x7da3a904),L_(0x4dde5b44), LL(0x3a35e974,0x6c75adbb),LL(0x0c9938a7,0xd7a77183),LL(0xf4ef9f5d,0x30114b89),L_(0xbb08ab61), + LL(0x80255f87,0xdf042ef7),LL(0x481cae35,0x2a918359),LL(0x6fed5580,0x3de7d914),L_(0xa4e1bcfb), LL(0xcd8bcdde,0x85cd2cff),LL(0x4370738c,0x03a1d543),LL(0xf95a95e6,0x9814d14c),L_(0xe0fd8dcb), + LL(0xf9193246,0xc27ed927),LL(0x655d6ffb,0xe4ef91cd),LL(0x43a4fc18,0xde7270a7),L_(0xcba9f29e), LL(0xa246b9ef,0x2e139df8),LL(0x5cc92d84,0xc362ff6d),LL(0xc5a596a0,0x6a5bdae7),L_(0xd5e4697c), + LL(0xdd86fb5f,0xa1aad671),LL(0xf4cdb11a,0x2ccfca9e),LL(0x35eb1979,0x06b67d2c),L_(0xd3a50661), LL(0xcf9afa3f,0x47a43129),LL(0x2c80dfe0,0x0f28c072),LL(0x1e137541,0x2528a436),L_(0x4a30bc3a), + LL(0xb7a122bc,0xa27429d1),LL(0xac029aa3,0x8704523f),LL(0xe555d79c,0xc26117ae),L_(0xeee94c98), LL(0xd57ea228,0xb5866e80),LL(0x3b83d3dc,0x8fda3fab),LL(0x497236f4,0xa896a908),L_(0xc1eba30c), + LL(0xa3fc2c9c,0x0b1d2a88),LL(0x6a45073a,0x8af7a77a),LL(0x72b5edce,0xc7a3b1fe),L_(0xac5268b4), LL(0x018d5428,0x8589b539),LL(0x25c0f37d,0x22f0783b),LL(0x8cf1d803,0x9d3fe1d2),L_(0x15093e7c), + LL(0x8d1c5128,0xac83f07c),LL(0x6eba86a7,0x4ddb4944),LL(0x7769b4f0,0xce08325a),L_(0x306da9b2), LL(0xe9629e93,0x9fd70869),LL(0xbe70ef68,0xa27b01af),LL(0x9649ac38,0x59634c20),L_(0x260c709f), + LL(0x32f4b675,0xe36b9e35),LL(0x56c9f551,0x59ec0560),LL(0x9a19b345,0x7b1c335b),L_(0xb90484f8), LL(0x2e951d15,0x0b5ef9ec),LL(0x8c6e220c,0xac2613e4),LL(0x4ddb2066,0xe5c29249),L_(0x2b898fcc), + LL(0x90d06a78,0xb7d4dedc),LL(0x3cc11efc,0xf6a2c79e),LL(0xc5d55aae,0xebad4304),L_(0x139832e2), LL(0x73f6f29a,0x0089eaff),LL(0xb6ab35e5,0xa043d1f1),LL(0x35af18a2,0x363f80f9),L_(0x8c8c5655), + LL(0x800e76ab,0x3cad20e2),LL(0xd54cc179,0xd6ee4412),LL(0xc7630400,0x8ece816d),L_(0x4347fa49), LL(0x46a3c678,0xe22f3ed6),LL(0x83d72b28,0x5e7ffb13),LL(0xa89efb1f,0xc07fe6b1),L_(0xf679cfd6), + LL(0x1e9baa6c,0xdd4159b6),LL(0x90409ff6,0xc1a8d493),LL(0x0509d403,0x0d946df5),L_(0x46153d5b), LL(0x2b496957,0x1229cd0e),LL(0x25841f04,0xac5550dc),LL(0x163487ec,0x1f5ac4bb),L_(0x7a894b16), + LL(0xf830d51c,0xd0fd0fde),LL(0x95e0fb87,0x393b8885),LL(0x12d4a0db,0xbac4ce3b),L_(0x4aecb41e), LL(0x949595c3,0xf6b866b2),LL(0xc85cee8f,0xadac3140),LL(0x929c773e,0x22cf7705),L_(0xf90855df), + LL(0x05ee1c57,0xb938eeef),LL(0x054fb615,0x87e5ccbf),LL(0x7d1ce423,0x624c46af),L_(0xc8279b91), LL(0x70e96354,0x6fc664fb),LL(0x957fa9ea,0x0ec18ae0),LL(0x86d71f58,0x8216ab5f),L_(0x4fdcf503), + LL(0x6a1895bd,0x99acbf5f),LL(0xea1c792e,0x2f4551f2),LL(0x3d4924d2,0x09c0ca0b),L_(0xb94190da), LL(0xa95f5a84,0xaccafdf8),LL(0x6c1aa007,0x7635c97f),LL(0xe4eccac7,0x07821f33),L_(0x3125c30a), + LL(0x9eee4fb3,0x76375e85),LL(0xa2da6002,0x6d9d3924),LL(0x851663d2,0x903300d5),L_(0xe4304412), LL(0x16885ea2,0xf13f93d6),LL(0xac6cc7e1,0x765c7a8f),LL(0xc233fc52,0xfa884feb),L_(0x889b7699), + LL(0xea0d9656,0x649b4877),LL(0xb98eb821,0x0e89d083),LL(0xda85057d,0xe8c391ca),L_(0xc53a37ec), LL(0x5ab13638,0x3c241d52),LL(0x1c63bf16,0xe5732bef),LL(0xe6f1e93f,0x882db63a),L_(0xacf7e8f4), + LL(0xb0ae8194,0xd18b015c),LL(0xf734d021,0xe38e3807),LL(0x62b04fde,0xea71f882),L_(0xe9f4d402), LL(0xb7452054,0x3d8f7744),LL(0xad9abc71,0x68a3e02d),LL(0x088ad020,0x25dfde15),L_(0x250f4123), + LL(0x5076af69,0xe0e96eac),LL(0x46b7097a,0xd8c13c78),LL(0x19ddbba5,0x3ecd0bd0),L_(0x1b6e3a84), LL(0x74eefc3e,0xfc22adbe),LL(0xbae23185,0xad1b79ab),LL(0x09ed4ed6,0x062eb7e7),L_(0xe1ce81e7), + LL(0x06e9bfca,0x4649146e),LL(0x91702d2f,0xb30f9778),LL(0xbfdaf3cb,0xcf8f23f1),L_(0xd403a4bb), LL(0x13bbb0cb,0x33bbb504),LL(0x5d48ee37,0x17c9202c),LL(0x79ec8717,0x5a9ca7a8),L_(0x76092de3), + LL(0xfe5a3569,0x1f9e6c97),LL(0x17ed7898,0x2727d871),LL(0x668c28ad,0x745aa2ed),L_(0xcf9ce234), LL(0x83f03768,0x4a783728),LL(0xbf5955af,0xadfd1b46),LL(0x92891a4a,0xea43a792),L_(0xc67457a9), + LL(0x44cf762b,0xb8dd47fc),LL(0xff42200e,0xe06ffe0d),LL(0xa70a5da7,0x6cbd4092),L_(0x6d058c66), LL(0x0f9eb44c,0x110c3a99),LL(0x67048ffd,0x990449de),LL(0x82fc6b0f,0x30242c32),L_(0xa769318b), + LL(0x2521a3f3,0xbb708ced),LL(0x7620c902,0xe32cd4d5),LL(0x75832ff6,0x3a89190f),L_(0x4632df7f), LL(0xc48dd2c2,0x48e4bd13),LL(0x62dc813c,0x4888006f),LL(0x9c55f000,0x36a4457f),L_(0xa330078b), + LL(0xb664f023,0xc1f3d1a9),LL(0xe37d1ff2,0xa5e8a776),LL(0xed06b0a5,0xb1d3c33d),L_(0x939c8f4c), LL(0x836de412,0xf53390d9),LL(0x9e6ebae1,0x35e4cf7b),LL(0x28276f39,0xd69e1327),L_(0x19f5bac2), + LL(0x7885d34d,0xafd90d23),LL(0x0e84e363,0xbf4cd59c),LL(0xabb80eda,0x07e40274),L_(0x95656580), LL(0x0b980b41,0xa8a767b0),LL(0xc90af857,0x560c2286),LL(0x465bb86e,0xbf658fdd),L_(0x7eb455a7), + LL(0x49a8618f,0xda192000),LL(0xad70ec43,0xd0fca141),LL(0xcb55de32,0x7d66c4af),L_(0xa952a38d), LL(0x06ab4e56,0xdceb099e),LL(0xed3e0675,0xa87bfc4d),LL(0x635a862a,0xb9f4c7da),L_(0x8d6f1c2a), + LL(0xfd911863,0x6f166fdc),LL(0x0c46e6e4,0x31dda475),LL(0x0813e798,0x9066cff4),L_(0x2f759557), LL(0x65e21d85,0xbd44613d),LL(0x06317041,0x5b7e81b6),LL(0x6879039b,0x6853d2d8),L_(0x80566bad), + LL(0xe802ae6d,0xd83655d3),LL(0x7c1a0bb8,0x58e0b41c),LL(0xa5228881,0x00c5e925),L_(0xe9c51c0b), LL(0x0ab1b93f,0x0234b858),LL(0x9a00e742,0xe3d995c9),LL(0xf774358e,0x0eb69043),L_(0xd46eb256), + LL(0xe178f2a2,0xe386daab),LL(0x9a305482,0xe1fa3e14),LL(0x7957d9d7,0xf3f52055),L_(0xd1a9ce7b), LL(0xd284eae6,0x303b5ae8),LL(0xac2ad67a,0x7abad7f1),LL(0xb7b58e09,0x7dc5f5f1),L_(0x6c99d250), + LL(0xc25aa814,0x29507cf4),LL(0x37c15d8e,0xa6beff47),LL(0x738d9ba6,0xeb76b42c),L_(0x0b91ab81), LL(0x0d166346,0xac1dd9b7),LL(0xb974e300,0x5e6f1484),LL(0xd55b5832,0x9748b154),L_(0xbfcdc886), + LL(0x767c2496,0xaa791b18),LL(0xb611f73f,0x6dd24074),LL(0x6fd43d11,0xde586616),L_(0xff2a1da0), LL(0xd73b7439,0x7da57054),LL(0x5051af3a,0x9ca8008f),LL(0xa7d98205,0x80c04759),L_(0xd4db7bec), + LL(0xaef4ac4b,0x9051c152),LL(0xd36418fc,0x3e90a332),LL(0x2adcc4ec,0xa2d25b82),L_(0xf9315c6a), LL(0x062c149b,0x6fec476a),LL(0xbdd2e105,0xb614d883),LL(0xdc2bc2a6,0xd473b242),L_(0x9d87dbe8), + LL(0xadf54761,0x4031a20d),LL(0x5001f11c,0x908ea1cd),LL(0x86e3fa8d,0xa7c80719),L_(0x36408819), LL(0x4573ac01,0xaf0e8125),LL(0x430d59f8,0xcf05666d),LL(0x5b426c42,0x1c62cb71),L_(0x1a2c3f95), + LL(0x840aabc5,0x42998c5b),LL(0x9b1ab1ad,0x41b44d81),LL(0xe7ad335c,0xd2f18816),L_(0x9b21d6a9), LL(0x31ed5509,0x09dc1280),LL(0xc3771787,0x5bacd41e),LL(0x69b13c81,0x5419b128),L_(0x472d8eda), + LL(0x47816cca,0xc26aa120),LL(0xb9665455,0xd20f8647),LL(0x3bac4cd2,0x4b96b490),L_(0x15632e30), LL(0x82eca1ec,0x03c2ca5f),LL(0xeac8678b,0x8d2f8677),LL(0x5772568c,0xbef62c1e),L_(0x3b53ce81), + LL(0xee48fbfb,0xbe66a12a),LL(0x753cb0aa,0xe362e842),LL(0x38781cdd,0xcf1c41a4),L_(0xab22df0a), LL(0xb208a69c,0x7e4c97e4),LL(0x3869cfcb,0x72ee6ffc),LL(0xb43a4e85,0x6ab97c59),L_(0x35c0f24a), + LL(0x98013b12,0x292f0d68),LL(0x3e2b7aaa,0x42f99c9b),LL(0xe2ba5f7b,0x77ff29a4),L_(0xe21d90f9), LL(0xd9c0cb58,0xbc0b01cf),LL(0xe3677335,0x4d244a26),LL(0x8fee4b54,0x2b1a301a),L_(0x5d1511ed), + LL(0xa5f95387,0xe5e95789),LL(0xd73285ea,0x392f5392),LL(0x2e506fa2,0xecb1a91e),L_(0x79d54bca), LL(0xbdc25307,0x7bf48edd),LL(0x9f75d7b8,0xe8a12662),LL(0x08014deb,0xaf188a86),L_(0xbfada230), + LL(0xd011c31b,0xa63e4dbc),LL(0xe55bd873,0xd7f84005),LL(0xbe01f07e,0x1b09710f),L_(0x6e6cb66a), LL(0x5fc5038d,0x955bdbc5),LL(0xcecf1493,0xca6b6d16),LL(0x861a0878,0x084d6464),L_(0x0d0e35ed), + LL(0x5abc70f8,0xcdca5ed4),LL(0xdb335ec9,0x1e0fc344),LL(0xa8df4bea,0xcaea8450),L_(0xf564ec58), LL(0x361561bd,0xffeefed9),LL(0x193c8457,0xd89a00be),LL(0xddabba77,0xc99c9580),L_(0xa8ec469f), + LL(0x0423395a,0xf3c9cc68),LL(0xa888f556,0x852e0732),LL(0xaaa99a77,0x79ee145a),L_(0x4760cde2), LL(0x7dbf680b,0xd543c51b),LL(0x4d61119d,0xef9d767f),LL(0xb57c70b1,0x6d605846),L_(0x8392010f), + LL(0x4f6c403d,0x79dcc934),LL(0xd988c0b3,0x48395681),LL(0x66a38840,0x4cdffd50),L_(0x026d6f1b), LL(0x0fd100a8,0xd01d8faf),LL(0xc2150428,0x37a79216),LL(0x453f0c92,0xff7a816c),L_(0x84b14e80), + LL(0x8f9b1871,0xa7823318),LL(0xab4b5d45,0xe70810de),LL(0x1d9dae80,0xce1d1836),L_(0x1f8f6e55), LL(0x3fe286a2,0x8d6bd5d6),LL(0xd272957e,0xe02405c8),LL(0xc59f4815,0x15f1375a),L_(0x1dcaf5b0), + LL(0xd83c608e,0x6c316cb3),LL(0x5f19c736,0x28464849),LL(0x9bb6aded,0xadea31b9),L_(0x1090e65a), LL(0x3ad3fb92,0xfec08eda),LL(0xad397892,0xf01270f2),LL(0xb2c262c0,0xe12a0551),L_(0xcd11a65d), + LL(0xd00f765f,0x5db707b5),LL(0xf10d38e7,0x7a2ef5be),LL(0x5bbaa9f8,0x1692548b),L_(0xa34228d1), LL(0x2a6743e2,0x654e5d41),LL(0xf2342e4d,0xbe7af05e),LL(0x53e19ef6,0x254b33f9),L_(0x2609459a), + LL(0x0a41c216,0x7007f545),LL(0xefba2361,0xd7626b6f),LL(0x72c3ffc3,0x600f4b0f),L_(0x68bfc655), LL(0x0f831a13,0x13f14da7),LL(0x6efd514e,0x9b2809ea),LL(0xcc761584,0x949da3c4),L_(0xd3524443), + LL(0xab16d7fb,0xeca99655),LL(0x98853678,0xf946fea2),LL(0x959586ec,0x2b4d5496),L_(0x882a160e), LL(0x7fe0f8f3,0xdf2a1b88),LL(0x52e13aac,0x0f3ca0d4),LL(0x4a5dde81,0xc432a9d8),L_(0xcafd8d25), + LL(0xae4273ff,0x39455fc9),LL(0x0c20053d,0x2cb371b8),LL(0x04a4c142,0x14b7b1d1),L_(0x38e2582a), LL(0xbc61e230,0x20e68183),LL(0xd15dab61,0x5cc3f0a5),LL(0xba541287,0x62766fdb),L_(0x6619e0a4), + LL(0xf1589655,0x3bc818e2),LL(0x746af8f1,0x7a905de6),LL(0xbbe6fd69,0x53589554),L_(0x446a9ab9), LL(0x42c6c834,0xc30fa665),LL(0xf4d47c43,0x8776e4e7),LL(0x431ea6ae,0x9dafb227),L_(0x4ff395ed), + LL(0xe3b10ef9,0x2c57d4e0),LL(0xa4cceb3e,0xf2b56f06),LL(0xff6cbcb5,0x8918c037),L_(0x268bc00c), LL(0x782ed32e,0xa92f2fb0),LL(0x76415814,0x5aed9645),LL(0x6859753a,0x0a6cac9a),L_(0x399773b8), + LL(0x115dc4ae,0x7652379c),LL(0xc59e872e,0xfceb6ec3),LL(0x1fa3657f,0xa77b28fb),L_(0xa7619402), LL(0x26333b61,0xa85f48be),LL(0xe180ae18,0x671848d6),LL(0x68f2c963,0x3145c6a2),L_(0xe4d30712), + LL(0x71516dad,0xb3ff7310),LL(0x00082b09,0xb2aa0684),LL(0x0de3deec,0x33ecf9d4),L_(0xab6cc532), LL(0xeb77b453,0xd8a0ae1b),LL(0x2a618d55,0xab8ca810),LL(0x3993ca70,0x0f2549ab),L_(0xcc02ada7), + LL(0xe8cde28b,0xb5a7fc92),LL(0xec8a7e38,0x130ca680),LL(0x786e2a86,0x882cb9d7),L_(0x103bbacc), LL(0xc662b5a7,0x7395bf15),LL(0x4be2ec80,0x5a3d7841),LL(0xb287766f,0x4eb9dbc0),L_(0x54c7f36b), +}, +/* digit=29 base_pwr=2^203 */ +{ + LL(0x11dfaf3f,0x663a8bf5),LL(0xf1bd6f1b,0x5a8b6d6f),LL(0x2de2cf36,0x4f49967b),L_(0x49fde755), LL(0x1ea11bab,0x9956f1ec),LL(0x69f14061,0xf4e97d30),LL(0xc5c29863,0x516db87b),L_(0xd4456e50), + LL(0x6d6d1495,0x78b8a6b8),LL(0x5019a365,0x9a15b171),LL(0x025726c3,0xd611e283),L_(0x68f7b67f), LL(0x9367aca7,0xb4e7c5cf),LL(0x5ed6c698,0xfb9fa295),LL(0x6ea9c71d,0x2c0dd03d),L_(0x6ad6ab61), + LL(0x74645aca,0xc1c1b8cc),LL(0xa1ea038f,0x6422554f),LL(0x9d8f1f3b,0x5e44aefb),L_(0xbc0d302a), LL(0xd0763fa0,0x47ec400c),LL(0x9049574e,0x3240a34f),LL(0x9778ebf4,0xe0adc015),L_(0xe0348d22), + LL(0x42b0ea67,0x2b432e4e),LL(0x97be15f2,0x51920440),LL(0xfb123348,0x752805f0),L_(0x095f8861), LL(0x428d08f5,0xe4fd179c),LL(0xbfe10a89,0x4c2603c8),LL(0xc1a95174,0xb5e94f0f),L_(0x38bffbb7), + LL(0xfa8bbea8,0x31d5bf10),LL(0x3b628b52,0x747269c9),LL(0x9f017556,0x50b6b23f),L_(0x2051232c), LL(0xf36708ff,0x18b1fb8b),LL(0x58660126,0x731cf4a4),LL(0x85343658,0xcdefb5cb),L_(0xee7c02af), + LL(0x517736b8,0x842b9439),LL(0x79b770df,0x017ab239),LL(0x2ca8d23d,0x29cf116b),L_(0xd89fd3b6), LL(0xa037ebda,0x20362fb9),LL(0x17dff9f9,0xd010fe68),LL(0xb8350a9e,0xcbd44b83),L_(0x3adbe1f1), + LL(0x3d4cc86b,0x171138f4),LL(0xd002fd82,0x7c670c94),LL(0xed715f0d,0x14d543b9),L_(0x770fe818), LL(0x684456e3,0x2c123603),LL(0x3f8f258d,0xba0fe630),LL(0xa3564d33,0x9d216804),L_(0x435f77e5), + LL(0xa6e5dc69,0xabe6aeac),LL(0x5e84d762,0xde0a4f86),LL(0x538499e7,0x1d74cb44),L_(0xbfb3e36a), LL(0xbbcfa69a,0x198dddb7),LL(0xfcbe1984,0x873a7f1f),LL(0xb7b8bbcc,0x80cf7321),L_(0x00ac08de), + LL(0x78482416,0xe874537f),LL(0xbbb4692e,0x221e1e86),LL(0x02f17d20,0xe7057c36),L_(0xec132fea), LL(0x45b4351e,0x89b168f7),LL(0x7f9c9480,0x9d1de6f5),LL(0xf9e94168,0xf34e2409),L_(0x13e022d0), + LL(0xc854b8a6,0x243d2e96),LL(0x358d9af4,0x8938cb33),LL(0xb47467ae,0x81a7eea1),L_(0x470b2dab), LL(0x7063770a,0x3d8103c4),LL(0x9a2755c4,0xafa79d2a),LL(0x9228b07c,0x5b3e4741),L_(0xbc9b37bd), + LL(0xd005caa3,0x8739f51c),LL(0x3e9880c9,0x48357287),LL(0xe30595ad,0x9d3ff1f0),L_(0x4b286b55), LL(0xcc729699,0x89be0141),LL(0xe2576d49,0x27c29e5a),LL(0x00a64de8,0x1e63717f),L_(0x0c898bea), + LL(0x020255bf,0xd89a7c51),LL(0x489bd20b,0x1abc0a1a),LL(0xe7ac0a69,0xf9bbb011),L_(0xbe7ead5c), LL(0xfd43757d,0x5bf6715d),LL(0x2573c5cb,0x74bb4d9c),LL(0x30483451,0x7ccb3fa6),L_(0x0071ca44), + LL(0x4c06b933,0x83211263),LL(0xd01481a8,0x868c1469),LL(0x48c43d0d,0xd5277f78),L_(0x32c5572b), LL(0xd4224814,0xb34b30d1),LL(0x780e2016,0x750a0da3),LL(0x43e3806b,0xd4ad90ce),L_(0x97399684), + LL(0x31b3565e,0xe410e718),LL(0xb76d2e77,0x78c21e10),LL(0x0df8f583,0x6f7bfcdc),L_(0x210d7777), LL(0x740c2b91,0x04ef15f1),LL(0x87836a34,0x03a4d422),LL(0x44c267d1,0x2fbcd218),L_(0xbb549183), + LL(0xe76d9d5d,0xa541189c),LL(0x3029c3b6,0xd7480312),LL(0x277c1d19,0x761b9d9e),L_(0xd09fd429), LL(0x0b301fd2,0x8fe5cbdf),LL(0xf3cbac6c,0x42373c0c),LL(0xcbbe3e5d,0x4dd89b19),L_(0x75e821e8), + LL(0x9cbc0a32,0xf92173f5),LL(0x3b6ebbae,0xca2337d8),LL(0x44ad6eda,0x49918d50),L_(0x71e12775), LL(0xfc7a6248,0x7c6c9ea3),LL(0xa76fc6d0,0xe1e9ac5f),LL(0x95bb0f9e,0x0e5cdfb0),L_(0x3505e20d), + LL(0x1671e3f6,0xc0a26f33),LL(0xf36a466b,0x6a156434),LL(0x769bd94c,0x96b0b77f),L_(0xbaa9cde2), LL(0xec341956,0x961d12a2),LL(0xe383e51b,0xb1257ac5),LL(0xb680bdbd,0xfbf75271),L_(0x1f5805cf), + LL(0xa993566d,0x205ad8c6),LL(0x84ebf013,0x1874691d),LL(0xf24e1951,0x749aace4),L_(0xaaf03f06), LL(0x49610345,0x33c5f5b4),LL(0x378cf813,0x9fbc337a),LL(0x8ac53e4c,0x9b1441f3),L_(0x0113566b), + LL(0x2f5bdd05,0x8145a740),LL(0xd10f5321,0x525fb54c),LL(0xe73eb2a8,0x4da9ccbf),L_(0xf35011e6), LL(0xe92c65ec,0x375da80a),LL(0x3b493784,0xc35b0096),LL(0xe99fa1c1,0xbfcdd019),L_(0xfcd0fffb), + LL(0x3783ad2b,0x44724690),LL(0x6169a512,0xbbc2508f),LL(0xb54ae1fa,0x97426a68),L_(0x84a843c6), LL(0x1439b1e1,0x57ee4649),LL(0x9fa3b852,0x224d6e57),LL(0xcf4188dd,0xb9fbee93),L_(0xc6f126b9), + LL(0xa302b5dc,0xa34571c9),LL(0x48662048,0xb1b8b7f2),LL(0xfa26591d,0xf6f0b8d2),L_(0xc7f51cd9), LL(0x58d23928,0x5bc438ce),LL(0x66200c18,0x69768b41),LL(0xe6f1c95d,0x6844e3a4),L_(0x6e17cd42), + LL(0xcf358165,0xddd1ff7d),LL(0xf244b120,0x73e9c17f),LL(0xe6046902,0x40c26687),L_(0x1691fe67), LL(0x933ab02a,0x6e105d9c),LL(0x9b50eded,0x02d570b4),LL(0x00b6a88f,0xe9b08b55),L_(0x4b82631a), + LL(0xa09f3f50,0x04530c1e),LL(0xf4435606,0x5195314d),LL(0x9b79c17b,0x9f045501),L_(0x839380ae), LL(0x1cbc90d3,0x2d608e31),LL(0x9b83bfd2,0x913acbf4),LL(0x10db4136,0x22cc1949),L_(0x3a2e7962), + LL(0xd3e26092,0xec19a27b),LL(0xe5ad9b86,0xddac453d),LL(0xc7d0db50,0xb0a1794d),L_(0x12340a6f), LL(0x20e8dc2d,0x8bcb0707),LL(0x54438da3,0xe23756c5),LL(0x33597066,0x68e9b910),L_(0x192ee4ac), + LL(0x64c640f8,0x6b3b3e11),LL(0x6076299f,0xe52af985),LL(0x210c46f7,0x11bcefd8),L_(0x4c36d81d), LL(0x5bed674c,0xd49ab218),LL(0xb72e4c99,0x32664eea),LL(0x0e9348eb,0xa88c581f),L_(0xd67c4ee9), + LL(0x2d66a175,0xe899e96c),LL(0xb64bf9de,0x5fb2ed8e),LL(0x43b5e3af,0xa7cc5c88),L_(0x656b15b3), LL(0xdd7873f4,0xc5c4e24a),LL(0x112512c6,0x6324347c),LL(0x26ff024e,0xccd67ae6),L_(0x4f8c1dc8), + LL(0xe0a8b3e4,0x95b13b3d),LL(0x9e553300,0x85e3e1dc),LL(0x7fafd447,0xf8451257),L_(0x6a113d4a), LL(0x65687ab1,0xedde7f06),LL(0xaf37550f,0x901e09b8),LL(0x0b1d7c55,0x69e02d8f),L_(0xcfd6985a), + LL(0xe1246244,0xecd3e1aa),LL(0xbe482681,0xfb799ecf),LL(0x47798831,0x9fac48a4),L_(0xafbbf20e), LL(0x3d17bb47,0xd6f1c5bc),LL(0xfe2c6138,0x1b8d361a),LL(0xd3d7cf0a,0x0fdeccc7),L_(0xa05a2e1d), + LL(0x3a510fa4,0x6b3cd8ac),LL(0xa16dcddd,0xaee76b4c),LL(0x0fdf0fc4,0x3cb7db3e),L_(0x5144175e), LL(0x2669bf74,0xdaa284b0),LL(0xb41e11e0,0xa0a2a2a4),LL(0x334a53c5,0xb6f86d54),L_(0xea0526d6), + LL(0x142fbd3e,0xef18bf5c),LL(0x268ce667,0xc11a8ae3),LL(0x70f67534,0xb9cffb18),L_(0xc3038e8d), LL(0x941d9303,0x29b2c2c3),LL(0x4d1a3a20,0x4205ec1c),LL(0xe2c18665,0x5ab3157b),L_(0x7a60e7b3), + LL(0xf39b6495,0x1c5c3f1d),LL(0x28e72014,0x609a5ec7),LL(0x32068427,0x47c37b5e),L_(0x94c1b6e7), LL(0x39767baa,0x5f5b4e71),LL(0x77567891,0x05496c1a),LL(0x55a4f7f2,0xc6f93ff6),L_(0x8f654b8b), + LL(0xdb846749,0x8fa02752),LL(0xfcbae4b8,0xc21478c8),LL(0xcff78948,0x22632d48),L_(0x70d86a48), LL(0xa8b86e1b,0x00132e4f),LL(0x3721a7ea,0x0457eac2),LL(0xdcc0060a,0x0c2cbce2),L_(0x38fb42c3), + LL(0x802a7a9c,0x5ea4abc7),LL(0x5f3751e3,0x2aa4c525),LL(0xac364b4b,0x495dd3d3),L_(0xa6c1d838), LL(0x89d692f9,0xba68755b),LL(0x465b3970,0x72a043d5),LL(0xfe4e336e,0xfc16f7fe),L_(0x2c759722), + LL(0x3d83071b,0xdd3a0176),LL(0xcb5a7236,0x61809f55),LL(0xa2bbecb2,0x1f553745),L_(0x46d5deeb), LL(0x2602bcbb,0x4c542035),LL(0xa92075fc,0xc39e8592),LL(0xa99e29ec,0x31176d99),L_(0x7ca41c07), + LL(0xb54001ac,0x39ce1948),LL(0xbff084c9,0xe3b4d5e5),LL(0x43984570,0x05ef0ee6),L_(0x0a861937), LL(0xa8b0d940,0x1288a0c3),LL(0x52997092,0x3fa9ab6b),LL(0x24210cbf,0xec238c31),L_(0x9e2872c4), + LL(0x30423d94,0x40fd474a),LL(0x5b8538a3,0xec2ead24),LL(0x0d208047,0x1cb60ff4),L_(0x761298e8), LL(0x213bda9b,0x1b6d44ff),LL(0xbcf74593,0x5ddf4ac8),LL(0x746b2f76,0x679d4dee),L_(0x32233e28), + LL(0x1482adcb,0x0c718f19),LL(0x66cd9b3c,0x03bfd19e),LL(0x3b3a6f85,0xa9ef5cce),L_(0xca539a7c), LL(0xd847f363,0xed44fad7),LL(0x4db83c78,0xe9c8d39e),LL(0x5a9002ed,0x57ef09d7),L_(0x47b485ec), + LL(0x7d5b0115,0xe4537555),LL(0x4cc9c9c5,0x6d1d53a0),LL(0xec59f90b,0x55f05058),L_(0xaa97605c), LL(0xc10edab1,0x66f84f5d),LL(0x8c26f4dc,0x9097a136),LL(0xff1f32e7,0xda9cb1ce),L_(0x92d5f2c4), + LL(0x918a45ed,0x5ec4e734),LL(0xffb048ed,0x861a69b7),LL(0xb9ca6eb1,0x4f8b9e40),L_(0x089b9558), LL(0xd5b022cc,0x43e91e88),LL(0xcca4bf58,0xe5fa6721),LL(0x21a8592f,0x2180b560),L_(0xa9e4e373), + LL(0x73dd816a,0x95e834c2),LL(0x85c32c46,0x52b23dc2),LL(0xad18d469,0xd0c03244),L_(0xf46c7fff), LL(0xdbde0560,0xde2297b5),LL(0x8c32b174,0x8f0937ea),LL(0x28635d97,0x8b431269),L_(0x47d44429), + LL(0xc8d22f39,0x28c78e40),LL(0x93181781,0x61fdf274),LL(0xcb623c4d,0x98d40a79),L_(0xdda4b06c), LL(0xd808e325,0x3b688d0d),LL(0xfe3fd141,0xd51bdb7c),LL(0xedd15e12,0x3a965d08),L_(0xf3097f75), + LL(0xde0a2f39,0xbda9cc54),LL(0xa6bfe2fa,0xa29b11da),LL(0xf02a2f58,0x1b6a851d),L_(0xcb819b77), LL(0x8a57fd87,0x30780f8e),LL(0x9f0d56af,0x2b7ce89d),LL(0xf8a06fed,0x27c807cb),L_(0xb99605d9), + LL(0x46b40b76,0x6786d96f),LL(0x72255ae1,0x80ccf20e),LL(0xc29277a1,0xb9deb14f),L_(0xb01102d2), LL(0xaeb5c04b,0x1c8e7e81),LL(0xaf4a6e1a,0xaec9e1df),LL(0x06c802c5,0x4637b70a),L_(0x21f2e3c1), + LL(0x9ffc5f28,0xb4a7c608),LL(0x3a6619c7,0x4be0db0a),LL(0x5deb2377,0x24dd90ec),L_(0x7e94da01), LL(0x31617c3e,0x3788bd2b),LL(0x80b9433f,0x0c1368f4),LL(0xd49fdafb,0x47c8e8f1),L_(0x2be1c836), + LL(0x5ef0901d,0x7f036146),LL(0xf5f17b3f,0xdca93bb1),LL(0x45a7571b,0x4e68fb20),L_(0x68857bb8), LL(0x62732201,0xa24d2c8c),LL(0x2d13dee5,0xed2b0948),LL(0x88581796,0x118e784d),L_(0xf0493f53), + LL(0xa0e66eb2,0x58d860e3),LL(0x8971f724,0x9083bee2),LL(0xb4f43e7e,0xb5941f8a),L_(0xb537d4a0), LL(0xb975e31d,0xa327b762),LL(0x0a0d438e,0x9be00cfd),LL(0x23118e99,0x2345f880),L_(0xe40f8c30), + LL(0xe9728c3b,0xcbd96a38),LL(0x1197dd6b,0xe0af89d0),LL(0xb47615a0,0x381bf7e1),L_(0x251a8f8f), LL(0x008018e9,0xad578807),LL(0x34717cff,0x2b57e965),LL(0x5fbc83f2,0xa4f9d4fb),L_(0x64b6d093), + LL(0x69093077,0xf183d4de),LL(0xf6acf5ed,0xbaeb9a58),LL(0x0cc30970,0x181d2aa6),L_(0x53b37c4b), LL(0xce44dcb5,0x2ce916ba),LL(0x38654a56,0x59bee1db),LL(0xaba6d625,0x09ca53b2),L_(0xcdfe1968), + LL(0x91d466d2,0x9e6894a8),LL(0xf7c98ba1,0x7219e547),LL(0x8e28cba4,0xe28c0250),L_(0xdc432b47), LL(0x43c25678,0x52a05293),LL(0xff3120b7,0x789cbfc0),LL(0xd4520462,0x3107ac59),L_(0x92fc422a), + LL(0x41f9db9c,0x378db33c),LL(0x1b7e14c2,0x6dc570a1),LL(0x2e5d4aaf,0x536bff4a),L_(0x885f68ab), LL(0xf657a8f3,0xeaff53c3),LL(0x8ea881df,0xe2da9fbd),LL(0xce5d6df3,0x037450b2),L_(0x6899f186), + LL(0xa41f3714,0xe8227713),LL(0xb158373d,0xc20b72bd),LL(0x73e5ad11,0x0d1473e2),L_(0x963a9a91), LL(0xc3c89f91,0x6796b002),LL(0x32ad74a8,0x978ceeca),LL(0xcad42d90,0xa157eba3),L_(0x64fb791b), + LL(0x6d7b048c,0x91b7250b),LL(0xb6fc8bc6,0x1b7c37d7),LL(0x207504d2,0xa04f258e),L_(0x35b71223), LL(0x69296811,0x000189fb),LL(0x8cf221df,0xf5202462),LL(0xe9692259,0xc7e62afa),L_(0x2482c08d), + LL(0xb34b2712,0xa6fa3a44),LL(0xe579dd13,0x77c307c4),LL(0x8643df69,0x57d9dfb8),L_(0x9f01f782), LL(0x5573d8e5,0xb5c2c766),LL(0xbb840380,0xe0195f6a),LL(0x99e8ca50,0x6c698864),L_(0x31b4df34), + LL(0xc836d70e,0xfa87a978),LL(0x6e27995c,0x2d67fe21),LL(0xc806a202,0xc065a04b),L_(0x93cff90b), LL(0x6731446f,0xbb867036),LL(0x9cdfc841,0xe8066219),LL(0x0a935f1c,0xa9d96eb8),L_(0xc15bd4d8), + LL(0x60b97b73,0xd003f54a),LL(0xa4a49d7a,0x63dd3e3b),LL(0xa79d7693,0xa15f7dc6),L_(0xbd4d523d), LL(0x1e02bb50,0x6dbfe7b7),LL(0xcc88e7c3,0xb0a1bb28),LL(0x8264318f,0x5e5fd5b2),L_(0x5f2fa1e2), + LL(0xe76ef3c7,0xec0ebc09),LL(0x1936faf8,0xd297aff2),LL(0xc8c40d08,0x01dd06de),L_(0x54d85f2a), LL(0x2bc0d559,0x8e9d926c),LL(0xcbcea653,0x99783016),LL(0x37d07340,0x0beb45e4),L_(0x3de7fc81), + LL(0x564ba5a3,0x32058809),LL(0x9850a91e,0x3af0e1db),LL(0x5464c544,0x1452f874),L_(0xb9637ddd), LL(0xeb527a99,0x7298be18),LL(0xdf5911d2,0x16aa8506),LL(0xf6dfd8a8,0x8bb252ea),L_(0x839f8d56), + LL(0x89f63fb2,0xc7fe9490),LL(0xa2fc5db9,0x99c60e8f),LL(0x47b2b00a,0x142e5001),L_(0x557178b5), LL(0x081ac8ff,0x7281e45c),LL(0x80053d16,0x92d81832),LL(0x335bfb8b,0x3285f848),L_(0xe9e17269), + LL(0xdbe51600,0xd38c0683),LL(0xd98fa793,0x990e1e00),LL(0x14117a61,0x0d3b9c08),L_(0x3e3d6538), LL(0x7a4ddb24,0x374f82aa),LL(0x538b9bf1,0x0c5bcaf1),LL(0x1cc16fb8,0xe0c1bced),L_(0xc0de70fa), + LL(0xd35b0a61,0x96448e89),LL(0x98c48df5,0x8846f415),LL(0x50f58327,0x4770c98e),L_(0x197ced21), LL(0x5ff2d0d7,0x1af1733c),LL(0x2bca7ffe,0xa04c1cce),LL(0xeac8a367,0x13278f06),L_(0x5dd0431b), + LL(0xd19368fc,0xa83c536e),LL(0x02379421,0x118f2771),LL(0x218d25f6,0x90caeeec),L_(0xf254a0e4), LL(0xc0dc699c,0x44d824bf),LL(0x0bbdc5a2,0x5903a15f),LL(0x21933c71,0xec2c7cff),L_(0x0a756aae), + LL(0x97dfc53d,0xd8438b57),LL(0x1d02bb13,0x42584478),LL(0x25ef520b,0x3dd8667d),L_(0xe3e22c9e), LL(0xc5d6139c,0x0d51408e),LL(0x0227f2bc,0xd3e4dd71),LL(0x090e4a02,0x2fc23bc1),L_(0xf9171e03), + LL(0x11deaeb1,0x8d85409b),LL(0xd1184135,0x617f0460),LL(0xf357dae1,0x7b364c45),L_(0xb9d690d1), LL(0x4d915f34,0x0c5f601c),LL(0xcb872f3a,0xe0fe9ec0),LL(0xbccb4f0f,0xf7bfadef),L_(0x9f017f8b), + LL(0x83cff561,0x15442e1c),LL(0x62cd98e6,0xab89d9c9),LL(0x58dcba94,0x7426c5f8),L_(0x80d0a8cf), LL(0x449af58b,0x52648e23),LL(0x3a628b1d,0xdb61eac8),LL(0xf0844217,0x9c140c5f),L_(0xb3cc7bfa), +}, +/* digit=30 base_pwr=2^210 */ +{ + LL(0xd6e670a1,0xf0426be1),LL(0xb4f44241,0x14838573),LL(0xefc4394a,0x80845fb2),L_(0x90205f0f), LL(0x99c56ec6,0x8a6cba70),LL(0x4345224a,0x6149abf7),LL(0xfc80d60c,0x9c7703f2),L_(0x3d5a7643), + LL(0x730ebcfd,0xe4b299d2),LL(0x79702991,0x6cdbe6f3),LL(0xad58884b,0xff023a31),L_(0x18b5c6ce), LL(0x51fd8a3b,0x433c522f),LL(0x3e4907b4,0xc1579271),LL(0x3c1c0282,0xe4454779),L_(0xb4df9ee5), + LL(0x48953bf7,0x658675d7),LL(0xdf2f4ac2,0x8faf514a),LL(0xdde660e1,0x50213318),L_(0x64826f9f), LL(0x8433d7fa,0xadcc3e45),LL(0xbc26833e,0xcc5ad72a),LL(0xde547aae,0x619251e2),L_(0xf96f73d1), + LL(0x548b77dd,0xba3e8f2e),LL(0x728cadb5,0x21cbbb1a),LL(0x0feebd0a,0xdb740393),L_(0xdcffa1d6), LL(0xb6848db5,0xa742cd6f),LL(0x549a4fca,0x39f63442),LL(0x3d24aeeb,0x426c42e9),L_(0xb67d7f28), + LL(0x408e3341,0x96cc626e),LL(0xd2b3305b,0x6a9bb18a),LL(0x355d47d4,0x33f53993),L_(0x960f4207), LL(0x16218c03,0x329378d3),LL(0x1004c020,0x70de3eb8),LL(0xa9117cf1,0x0e5dbd85),L_(0x73f55c21), + LL(0xb9a63bdd,0x456357c9),LL(0x1b3ded00,0x8e077f94),LL(0x0f0f2d4f,0x51648f45),L_(0xab4e5da6), LL(0x3963e9df,0xe96f0202),LL(0xcb55e2cd,0x3b87f53b),LL(0x7b3cc4d5,0x0090498b),L_(0xdfb4de74), + LL(0x98927a32,0xba64358f),LL(0x757e6fbb,0xccb5e233),LL(0x95336360,0x50d4d37c),L_(0xac96f5a7), LL(0x93c38d36,0x53008bb8),LL(0x33869046,0x5e587a5b),LL(0xfb1262f2,0x1e3e57ec),L_(0x407af3f6), + LL(0xc458ba03,0x9d6ad457),LL(0x78e956e9,0x82640533),LL(0xb94af545,0x32977879),L_(0xd20f35a3), LL(0x6224b353,0x9c65ff21),LL(0x5c8f99f9,0x4a46fdf7),LL(0x4ce9a00e,0x307b3d8d),L_(0x798d2cf9), + LL(0x77b2fb3b,0x3b8e6ef5),LL(0xb6ca3273,0xe32b3b97),LL(0xe260b8d0,0x9c66c2a4),L_(0x05eb84cf), LL(0xaf957b78,0xbe1f3ecf),LL(0x1e35adca,0x9d69d314),LL(0xa175edc2,0x4681a0ae),L_(0xc6715ff6), + LL(0xee864b12,0xe9c88636),LL(0x32143c93,0xf0c1e0f3),LL(0x434818e2,0x25a929c9),L_(0x4c806ec9), LL(0x20527edc,0xfe3e80ac),LL(0xa0372526,0xd5fc27b6),LL(0x5279eb8a,0xee97419a),L_(0x98dbe31d), + LL(0xcbc47797,0xe8bb79d3),LL(0xa6d3938a,0xf225d84a),LL(0x0b2f88a1,0xf279df50),L_(0x59a54b2e), LL(0x8cd34576,0x1390a7ac),LL(0xc9c37e25,0x1130b1eb),LL(0x0777586f,0x3aa2516a),L_(0x42cece95), + LL(0x3964d2a4,0xa47e21c1),LL(0x5f9875c7,0xf918e47e),LL(0x2ecbc86c,0x4ac56066),L_(0x5ea26fc2), LL(0xa5a826e0,0x31e429d6),LL(0x944c3736,0xd7082b19),LL(0xcf2fc959,0x02c3927e),L_(0x3bb33cf9), + LL(0x27da5082,0xcf56d753),LL(0x64f98e4d,0xd40b530a),LL(0x1c7766cc,0xb20cfe07),L_(0xe351283a), LL(0x18e30244,0xdc9dc465),LL(0x3bee62a5,0xcccf7fb0),LL(0xb2e1f645,0xfe54699d),L_(0x18ee6ea1), + LL(0xdf71a0f1,0xd2fe136d),LL(0xe5f658a8,0x5a88e4dd),LL(0xd83b5473,0x94a1a0d2),L_(0x586d7529), LL(0x1d163bf2,0x0748fda6),LL(0xe98d9b7d,0x69880bc0),LL(0xf0def9e5,0xc4e12cd5),L_(0xf40402da), + LL(0x585fff04,0x2956c762),LL(0x257681d9,0x3ba8ab0b),LL(0x696e0262,0xfd84ba5b),L_(0x0675debf), LL(0xa783c064,0xef9b82a5),LL(0xe38868a1,0xdaa2e717),LL(0xcdcdf922,0x292fb9c9),L_(0x269d71d2), + LL(0x477cabed,0xb5fae58e),LL(0x55622b3a,0x6ba8e28a),LL(0xff23a08d,0x56c2b54e),L_(0x866ba05b), LL(0x037720d9,0xa737dae5),LL(0xdc5131fd,0xb93a1d0b),LL(0xbb1176e6,0x860b7b0d),L_(0xf51c76d2), + LL(0x5845cd10,0x6bd647f2),LL(0xe811642e,0x9a4283ed),LL(0x0776f557,0x2c9fb90d),L_(0xb8cebf02), LL(0xb1612f57,0x643fb865),LL(0xc4902b6c,0x88ea78f7),LL(0x74aac273,0xfd2878e7),L_(0x1a76b1b7), + LL(0xb6983e76,0xf609c0af),LL(0x0cfea42c,0x123027ca),LL(0x7a72c3c7,0xb9872dc7),L_(0x1ae5bcf6), LL(0x57a545e2,0x9fe44848),LL(0x2a90f4d7,0x24f2f0f2),LL(0xdcdd6bf2,0x32eb5ac2),L_(0x939219ad), + LL(0x2540ecf0,0x267059b6),LL(0x2669c8c4,0x6d717377),LL(0xb6ba656d,0xc80a4182),L_(0xa67b63ae), LL(0xac5cdbce,0x7acd503b),LL(0x98520b74,0xf8884f71),LL(0x0688ae94,0x47fc66da),L_(0xacf9786e), + LL(0x9b68b84a,0xde210bb3),LL(0x74430a09,0x98b4770a),LL(0xf0e810c7,0x85cefd4f),L_(0xba1cac0a), LL(0xe9e74a58,0x35194ff1),LL(0x6452e158,0x520f3a2b),LL(0x8ed85e25,0xd8535bc9),L_(0x3bc32918), + LL(0xd77f4a13,0xd3467c72),LL(0x3046a69b,0x3a350288),LL(0x996236b5,0xf02f1b90),L_(0xdbce524f), LL(0x3a7711d1,0xdcc369a6),LL(0xa2eda832,0x81b1b5d5),LL(0xcb12490a,0x33444c56),L_(0xb4685d00), + LL(0x69d66472,0x6fe5a181),LL(0xa316d37d,0x11b6d85b),LL(0x75ec9a2b,0x8b98fad0),L_(0x0c5e4465), LL(0xde810eaf,0xbd855a8d),LL(0x7661287b,0x436e58d0),LL(0x9b044bfa,0x0f23ddbb),L_(0x7abd77aa), + LL(0xc57c3228,0xe7d89f58),LL(0x490f55aa,0x2e88de2d),LL(0x3aa72314,0xdea3a145),L_(0x159c120c), LL(0x5f68084a,0x840bb946),LL(0x1516983e,0xdcbbb7b4),LL(0x527c0f73,0x0d4d39e1),L_(0xe3846304), + LL(0x1fed9837,0x56c53d5f),LL(0x8c3176ff,0x752789ed),LL(0x26489626,0x94c341e1),L_(0xa5b14d8d), LL(0x3cb481d4,0xb4f1f612),LL(0x1a2f793c,0x94eb82ca),LL(0x600ebda4,0x6ba99e2b),L_(0xd1571ee0), + LL(0x960bacd7,0x122b6639),LL(0x41a70d6d,0xbaf725d5),LL(0x50c3e831,0x37bdeb4c),L_(0x948ab46f), LL(0x7cc81d1e,0x1a55a55a),LL(0x3b20c1e6,0xa6276eba),LL(0x81e5763b,0x4ddc462f),L_(0xffa876e2), + LL(0x8d1558c7,0x62e4c32c),LL(0x7f945839,0xfc3257d8),LL(0xa1e798f7,0xfe755aec),L_(0x5524084e), LL(0xcebab559,0x02c2a9e2),LL(0xdc627b0e,0xf8a1716c),LL(0x7c827c47,0xbcf0b634),L_(0x677ad978), + LL(0xe3c947ec,0x74af562c),LL(0x8713ce0f,0x1493b8fd),LL(0x6951ea3a,0x23d2ab0f),L_(0x761f3a78), LL(0xb7530283,0x098fb6af),LL(0xeb48e791,0xccff2003),LL(0x160c9294,0xf1992cc6),L_(0x2ed7be4f), + LL(0xff03f6d9,0x02ad20b1),LL(0x30165084,0x17295d20),LL(0xb8bee43f,0x67757e6c),L_(0x0eedd6d6), LL(0x61ba2edd,0x5acf9123),LL(0x8dee8798,0x4442dc9a),LL(0xa4c9925a,0x9970bc21),L_(0x54e339cf), + LL(0x250b4244,0x7f335cdf),LL(0x5019bc77,0xa892b382),LL(0x15ce5f7d,0x4f31c43e),L_(0xfa69d995), LL(0xae609392,0x1d57d52c),LL(0x20dc7c66,0x6e6a7489),LL(0x01a82796,0xa8fa2376),L_(0x861ac30c), + LL(0xadcafee5,0x56acbf11),LL(0x7b20a0c7,0xa63a1d19),LL(0xbec3d69c,0x5e324e3c),L_(0xd3d97b66), LL(0x64b971b3,0xc585e140),LL(0x2b8e18cf,0xd08772ba),LL(0xe0b2513f,0x6e7d6c03),L_(0x7e1a6116), + LL(0x9bc4e6f4,0x23bf2ce8),LL(0x82122cee,0x0b5f01ee),LL(0x318ba204,0xa93e44d4),L_(0xd2180b18), LL(0xd6ef00ac,0xd9d85de8),LL(0xd7d06345,0x3062eb10),LL(0x5bea35e9,0x952d933c),L_(0x72bd41e8), + LL(0x72791646,0x60e9cb5e),LL(0x107232fb,0x644a5b6e),LL(0x004f8684,0xa23e4299),L_(0xefa3c56b), LL(0x964aa750,0xad436903),LL(0xbb576a94,0x041c2a91),LL(0xbd787460,0x3513e3fe),L_(0x4066ae12), + LL(0x09a3d049,0x627d1807),LL(0x7365dc29,0xe00d7aec),LL(0x0dec445a,0x96d5022f),L_(0xf4343e09), LL(0x515a9b8f,0x00d16dd6),LL(0xeeaa6e35,0x97242fab),LL(0x220f953e,0x91ecc397),L_(0xaf714cd0), + LL(0x79198e5a,0x6dd11272),LL(0xce83daf3,0x9169c8b8),LL(0x6ce5dec2,0xce89d045),L_(0xbafd94a5), LL(0x1563c0ce,0x577ca0e0),LL(0x1e36fd91,0x5a836e51),LL(0x060d3970,0x729ba81d),L_(0x8b7e4fbb), + LL(0x16781a85,0xdbaa195f),LL(0xb43de333,0xec92b939),LL(0x2ccf4a4e,0x036ff9cf),L_(0xafc236c4), LL(0x6221e156,0xd7468cbb),LL(0x9a645200,0xffcbfaac),LL(0x5b2deae6,0xb553572e),L_(0xd4efa381), + LL(0xd257958d,0xc9536b4a),LL(0x10222aaa,0x9ab6a135),LL(0x84934c38,0xdf7ca8e3),L_(0x5e5dc148), LL(0x93660c96,0x4d98778c),LL(0xb7c8140c,0xd69648d2),LL(0x69c09498,0xb0ea1d36),L_(0x7e0cd235), + LL(0x62e6becb,0xe9443a72),LL(0x94747e78,0xd494860b),LL(0x2415da80,0xf50cdd9d),L_(0x65d2fa97), LL(0x48dbba8d,0x3ca3104f),LL(0xaf39be74,0xbd695019),LL(0x0441383f,0x393e3175),L_(0x4e5bd1d4), + LL(0xf6d61041,0x70145555),LL(0xc463ec32,0x8fa5018e),LL(0x1e5a98cb,0x59b3adf7),L_(0xeb7c80fc), LL(0x529f5fa8,0x5234550b),LL(0x4eb610a4,0x2ac1098d),LL(0xdc8db9bb,0x52106057),L_(0xbc3a065e), + LL(0x62bb8d08,0x6e360f55),LL(0xee7f7e1c,0xe795bf91),LL(0x7411bd70,0x627a5d54),L_(0xb191903e), LL(0x323d2db5,0x6bb808ed),LL(0x484c498f,0xded0b935),LL(0x3cef8b7c,0xcc379eda),L_(0xe1f0ee29), + LL(0x106cde5b,0x21a0558f),LL(0x2ea40699,0x84c5579e),LL(0x057a8487,0x5834fcc4),L_(0xb35b630b), LL(0x6779af9f,0x2d1d0e72),LL(0x6560d0d6,0xd90a0248),LL(0xeb026a8b,0x4d572129),L_(0x720991c7), + LL(0x22ee217f,0x657c8db7),LL(0x5e4f7ccd,0x12f06bfb),LL(0x8351fe6c,0xa43443b2),L_(0x48c1ec10), LL(0x01489ccd,0xb376d6e2),LL(0xc77d6dfd,0x727638f2),LL(0x0f953513,0xeae9d0a1),L_(0x91a7a744), + LL(0xb85754e4,0x59454f27),LL(0xd2c2004d,0xe70796e3),LL(0xacc344aa,0x775a61d7),L_(0x1c186106), LL(0xa1656bbb,0xdcf00b60),LL(0x4e3f081c,0x1af1503d),LL(0xcaa9cad3,0x1e4e523b),L_(0x816a09ca), + LL(0x0b303a9c,0xd468c096),LL(0x86aa5ecf,0x1910f732),LL(0x26d08884,0xe43dffa8),L_(0x6501f291), LL(0xa597567a,0x88248cd9),LL(0x4711c711,0x5263d7c9),LL(0xa4245344,0xcfde7c18),L_(0x4111cd00), + LL(0x7d78f32c,0x0df3b4b0),LL(0x9cf9b276,0xf4191861),LL(0x9dd92d6a,0x6444967a),L_(0x5f3bbd8f), LL(0xa9ba118e,0x1a4b4820),LL(0x2d798278,0x2aa6dcc4),LL(0xe9681e55,0x0ce3d37c),L_(0x739d5ad5), + LL(0xdd02bc4d,0xcf20f024),LL(0xf4697953,0x90e93ff7),LL(0x789e6af7,0x1050c0c2),L_(0x383c22fa), LL(0x60720c41,0x5cc2adcc),LL(0x2ace7063,0xf57806de),LL(0xf6f6aaf0,0x31c60f20),L_(0x7b350e28), + LL(0xcc10306b,0xf49e5f61),LL(0x1a92eddc,0x58cb04a9),LL(0x365a5041,0xc89ba67e),L_(0xa32fc59f), LL(0x65f980db,0xdb9db26b),LL(0x09322a72,0x93261bc9),LL(0x3fda4217,0xc6c63b34),L_(0xddeb9986), + LL(0x148cbb74,0x77b280f1),LL(0xc18c7395,0x7ee57ca3),LL(0x4cd0382a,0x37436f93),L_(0x66528f8e), LL(0x6e4b7e57,0x2dd6704a),LL(0x83b283eb,0x7f7d547a),LL(0x54972ce8,0xbca75a4c),L_(0xa9f10506), + LL(0x7605a526,0xee53ff2e),LL(0x5105c866,0x09187c91),LL(0x02b0042e,0x1f9de3bb),L_(0x4f9500fd), LL(0x880380ec,0x8cb6dd5c),LL(0xaa04e960,0x2a74a12c),LL(0xa0112a70,0xec0e66ff),L_(0xec305363), + LL(0x4b9381fc,0xa014524b),LL(0x400fd142,0xcb74eb3a),LL(0xf02c64c2,0xd9684416),L_(0x8da612c7), LL(0x06a80727,0x4e54713b),LL(0x7cde46af,0xfe9ec578),LL(0x8380cc14,0x5013084d),L_(0x80963cc8), + LL(0x349f5079,0x6dcbbe48),LL(0x6b6125b6,0xceefada1),LL(0x67b840bc,0x16c79367),L_(0x570c02ad), LL(0x361a38dd,0x8552cefd),LL(0xa8167ca5,0x286e6e20),LL(0x3636e865,0x9c4305d9),L_(0x43d5af7e), + LL(0x7f9a80cd,0x413cd659),LL(0x9c95b00e,0x310a2a72),LL(0x64a28802,0x6ef01bfc),L_(0x858e4b79), LL(0xb1565b88,0x113a4fdb),LL(0xd390a92a,0xc04a736a),LL(0x774c1209,0x63557ff4),L_(0x54e47eaa), + LL(0x940daa93,0x27760c7d),LL(0x9e3147b9,0xd15d7a6a),LL(0xb9bb9711,0x89363a50),L_(0xe852edfe), LL(0x94740e26,0x43ee10a5),LL(0x2d6acef6,0xaa297031),LL(0x03fc12e9,0x20890385),L_(0x2d45580b), + LL(0x87453ec7,0x4101d16f),LL(0xbebb2e76,0xf89a5338),LL(0x533638ee,0x05bdd7f6),L_(0x92a0bd39), LL(0x56483d09,0x4c760096),LL(0x81c6243b,0x37294333),LL(0x5119eebb,0x049c6a06),L_(0xc410f246), + LL(0xd5e79013,0x51167f9a),LL(0x12be7d2f,0x90e63900),LL(0xa41ce391,0x0572301a),L_(0x0a761ede), LL(0x8bb599f2,0xe5dca064),LL(0x3dad4d6c,0x88bd9756),LL(0x82d548d7,0x79a33fd1),L_(0x76d2d77b), + LL(0x801eaf93,0x77f53014),LL(0xa4c2daab,0xd48faf97),LL(0x40a7d787,0x604bbbf3),L_(0xcc41bd91), LL(0x9de9fab8,0x4c6757d4),LL(0xe55da08f,0x9a37321e),LL(0xf50459ca,0xf8d3a03d),L_(0x8252e5cb), + LL(0xc0ad0a5d,0xaaca1be1),LL(0xb4f7cd9f,0x6f65ac78),LL(0xfae3835d,0xf685dd47),L_(0x6c5b897b), LL(0x8e631946,0x03e5ac2e),LL(0x71afc215,0x4dafffd8),LL(0xce6c64d0,0xa1bdc366),L_(0xe59eacca), + LL(0xcde53a1b,0x28e18006),LL(0x428bd7b1,0xec3e3023),LL(0x3bf0eb6c,0x69ce21e0),L_(0xfbe09c69), LL(0xc6ab638b,0xf7c3e582),LL(0x3283bc61,0xe88ef77b),LL(0x20ead3f8,0x1f935f24),L_(0x3b040b57), + LL(0x20008407,0xa23c1b84),LL(0x41a0017c,0xa6773559),LL(0xc09598e5,0xffd68469),L_(0x1da39b13), LL(0x221c586e,0xb19fcd20),LL(0xe71a0fa0,0xa76b6f70),LL(0x83e812db,0xb605b69d),L_(0x0efdfc84), + LL(0x28c66881,0x656d6dd0),LL(0x58a3f7d2,0x7540ad09),LL(0x1396fe6c,0x52fddb17),L_(0x39edad21), LL(0xa2cc1fe5,0xfb57f569),LL(0x1072b4e0,0xddfbbf25),LL(0x94372dad,0x0a26aff2),L_(0x88f38fd7), + LL(0x8fdfcf33,0x6d4895a3),LL(0xff2438e1,0x19da7037),LL(0x67f22bef,0x3cfaa48e),L_(0x6bf9fc2b), LL(0x0a03dd57,0x7b4df30e),LL(0x956e9ec2,0xd632b168),LL(0xe6cb0b1c,0xfc98eaec),L_(0x7dbf18a3), + LL(0x8b21bd41,0xf20afcc8),LL(0x9b4028ed,0x9fb97c45),LL(0x4e476a55,0x6bf05b58),L_(0x2b0c488d), LL(0xec47e2f5,0x01d3ca74),LL(0xc0d6bd28,0x7a3a23e0),LL(0x95f353c8,0x010298ee),L_(0x034e53ca), + LL(0x6fa3f957,0x80ff52bb),LL(0x50412d11,0xf58be861),LL(0xbe2f9f7b,0xe84a58ad),L_(0x83284261), LL(0xa5a7f060,0xc605b12b),LL(0x5da82b44,0x86fa207e),LL(0x837f9c22,0x10d656cc),L_(0x454d1413), + LL(0xb270f308,0xde3d1dc4),LL(0x6619a39c,0xf9fa04cf),LL(0xaaa9723b,0x3910ae67),L_(0x86fdb715), LL(0x1046b659,0x3782c29a),LL(0x5c35eb01,0xd10183f6),LL(0x76b4be96,0xdd570ea6),L_(0xf56b5810), + LL(0x237ac7ff,0x9ec12515),LL(0x3f080f23,0xed07ceb7),LL(0xc3509a49,0x08bba00b),L_(0x07998613), LL(0xd7bef81a,0x5c36ecb2),LL(0x75c6840a,0x9bd57323),LL(0x3e8f5265,0x2c678e3c),L_(0xc7f1cc73), +}, +/* digit=31 base_pwr=2^217 */ +{ + LL(0x0993fc0d,0x2409728c),LL(0x2d5fd352,0x7af57f46),LL(0x28f3cb14,0xee72bd56),L_(0x21c2f494), LL(0xf22e2fef,0xac73118d),LL(0x283e1b56,0x490bb371),LL(0xf00c3802,0xaa6c7b0a),L_(0xee304f23), + LL(0x2619d224,0x5b89b52b),LL(0x433d8d17,0x1df61e0b),LL(0xec27bd08,0x49353c25),L_(0xf18b23f5), LL(0xc525714f,0x2c798eec),LL(0x91011438,0x6bd787c1),LL(0xfaa77bac,0x6e2db36a),L_(0x2a3b730b), + LL(0xf5bd48f0,0xea09f154),LL(0x18c36c89,0x45e66f63),LL(0xff1cf2a0,0x1d069cd7),L_(0x672fde0f), LL(0x07bd9cc6,0xf1f4e5b9),LL(0x86238146,0xa40cdc9d),LL(0xcdc7fd6b,0x00bcd404),L_(0x51a105eb), + LL(0xd8d6b178,0x348659fa),LL(0x0afc95de,0x724963c6),LL(0x478c3432,0x1f2f8d2f),L_(0xaa0e8781), LL(0x49e60cff,0xbf3811fe),LL(0x526d1fb9,0x50f264cd),LL(0xf802b4ae,0xf613e178),L_(0xd3df21bc), + LL(0x45bfb8c0,0x40af4179),LL(0x3b133f03,0x6e8997cf),LL(0x9b5dda1d,0xc2f372b3),L_(0x3948b7d7), LL(0x55f88793,0x99028593),LL(0xbcf7e27f,0x405ba3c5),LL(0x1de8aa5f,0xb2fc7cd3),L_(0xaadbe95a), + LL(0xd00dadb4,0xff2c8be9),LL(0x26721264,0x8d199a29),LL(0xbd6c65e6,0x7f2093a5),L_(0x21e5d488), LL(0x03e74b8c,0xa000a3ec),LL(0x68530945,0xeb8e9efa),LL(0xd1f6fc3c,0x3f15aab2),L_(0x9b5d8cbb), + LL(0xb9fa3849,0x45f74205),LL(0x97a4da7b,0x121a4ca8),LL(0x6d246547,0x819c4b2d),L_(0x8255bc16), LL(0x156c1f2a,0xf9d396e1),LL(0x5502b719,0xe8758b6d),LL(0x8b9b6ca8,0x94965c57),L_(0x3c7a5ffc), + LL(0x75175beb,0xc11d6984),LL(0xbad3d4ba,0x3c966d66),LL(0x67c5bea4,0xb82cec9b),L_(0x93b6322c), LL(0x1f09f72e,0x9661c046),LL(0x769c204a,0x12a03826),LL(0x35880fdc,0xc215f2cd),L_(0x4f5bf77f), + LL(0x4fdd677c,0x8bce7ecf),LL(0x847b9ee6,0x62abc7d2),LL(0x8cb1f02b,0xfffe0edc),L_(0x62c22364), LL(0x48727496,0xdcd7d51d),LL(0xa9cd4c50,0xfe1661b1),LL(0x30edb5dc,0x82ea29e2),L_(0xcc4403d4), + LL(0xc5db9960,0xed02ad3a),LL(0x66e7f904,0x194f3505),LL(0x2877668b,0xe7bcfa22),L_(0x873070fa), LL(0xf3636bf8,0xf013615b),LL(0x2fe9dfb1,0xeec498a2),LL(0x51ff974b,0x56961e83),L_(0xcd87825f), + LL(0xb4807fe6,0x5b989bd9),LL(0x2f915297,0x161be465),LL(0xcf0387e7,0x80e7dd9f),L_(0x2e7c6dd7), LL(0xb221d5c4,0x861c2ffd),LL(0x1df12d2f,0x36db9960),LL(0x048668bc,0x9b862a1d),L_(0x2b64be2a), + LL(0x02a0d3cc,0x644173f7),LL(0xc3611806,0x2103668f),LL(0x78a6d7ae,0xe22b26dd),L_(0x1dd89345), LL(0x39193a47,0xd1587982),LL(0x7692c1c8,0x9106104e),LL(0xecf6b1c4,0x0a975fb0),L_(0x0d6babd5), + LL(0xf550f1a0,0x4222b0ec),LL(0xb5c91a5b,0x78338ceb),LL(0x0ec3e064,0x9d0d2af2),L_(0x660e553e), LL(0x1d9a4d16,0xa632918f),LL(0xff1f387c,0x7bd6a5fc),LL(0xd795c509,0x67e40e1b),L_(0xdada8e3d), + LL(0x7f1d2d28,0x6eb26316),LL(0x4e1593ef,0x93bd25dd),LL(0x8698f986,0x2d0a715c),L_(0x8e8b3499), LL(0x41550af3,0x0b43672a),LL(0x132c1c9a,0xad35a8ca),LL(0xfd973661,0xea97e0b3),L_(0x3b811a56), + LL(0x87e35efe,0x3edb12df),LL(0xf66872e6,0x31c81b67),LL(0xc41cad87,0x0cfa43fd),L_(0x43f4aa49), LL(0x209b0e7b,0xcfa7ab7a),LL(0xafd31516,0xe582ff27),LL(0xc78d7ba1,0xea786f69),L_(0x2090d8fa), + LL(0x073b3ba4,0x7ee5008f),LL(0x28c86852,0xf81d75be),LL(0xd457685a,0xc2987502),L_(0xe596765e), LL(0xd0f9d913,0xfb631b84),LL(0x42aaadd8,0xe5cce6ba),LL(0xf7d72923,0x2257f5b6),L_(0x260ae885), + LL(0x6ca309b3,0xdb84c9b9),LL(0xdbb13e44,0x0f9da41e),LL(0xa7294694,0xc1443c26),L_(0xe02af6c2), LL(0xfe44c5f2,0x293f667a),LL(0x52bbc8cd,0x5f04fc4a),LL(0x7e1de72e,0x6907cdc1),L_(0xf8a9aeab), + LL(0xa3dd55e7,0x3fade182),LL(0xd7401dde,0x03aa0312),LL(0xc85449b7,0xc47549c9),L_(0x6ec51217), LL(0x55e72225,0xae146938),LL(0x4bbe9886,0x7c810544),LL(0xee349410,0x9f320ada),L_(0x4fdf9e41), + LL(0x2f1465cb,0xf506f849),LL(0xf58881e9,0xb38fe4e3),LL(0xd6feb622,0xedfd3c65),L_(0xb163b10b), LL(0x1345454b,0xb8f8a7bb),LL(0xb10b02be,0x11df874d),LL(0x1e5816ca,0x0ad84066),L_(0x9cd4eb66), + LL(0x4f8d4868,0x413431bb),LL(0x9ea4aaec,0xd1ee0d6b),LL(0x135f5f2b,0x9e4519f3),L_(0xd3e6e8f7), LL(0x7803a8e3,0xfa8179f8),LL(0x318fb330,0x53800116),LL(0xe0cb106b,0x95e1ca87),L_(0xfb4ce48c), + LL(0xec15776f,0xf3d74e54),LL(0xb7fb663d,0x4fd65071),LL(0x6706a48f,0x7f8a7cfb),L_(0x52d7353d), LL(0x811679af,0xc42a9ef3),LL(0x5bd192eb,0x5ed520f8),LL(0x2b1ff6c1,0xaa53702a),L_(0x5388fa6f), + LL(0x2813a7fe,0x423e53a3),LL(0x0baae890,0x3d22e91f),LL(0x08234191,0x9bfec6fd),L_(0xc8f4d373), LL(0xfbdbc5c1,0x119e3476),LL(0x19587b51,0xfeed51b0),LL(0x1c276e15,0x951dd485),L_(0x98048932), + LL(0x21e06022,0xbe2d77e9),LL(0x67d742de,0x0c1663f5),LL(0x7983fd13,0x7115e508),L_(0xb9406bb8), LL(0x4eba1a04,0xe45eb297),LL(0xdf3a7991,0x5693a9fc),LL(0x03ba9fe5,0x25d8f862),L_(0x6ea3053f), + LL(0x93e92c0c,0xefbe9105),LL(0x266e3900,0x1cee1814),LL(0xe042e34f,0xbec6b919),L_(0x5cb15a6f), LL(0xd41a287a,0x7568673f),LL(0xfe7b7595,0x4deaa29d),LL(0x3e67572e,0x2d437dfd),L_(0x03299218), + LL(0xfea564c7,0xc2d6c313),LL(0x3d460901,0x3e809da5),LL(0x591fe51a,0xeb85aa17),L_(0x44d65538), LL(0x45dff18c,0xea596f90),LL(0x48a2f0df,0x4708877e),LL(0xc2cabfd0,0x17f7dae8),L_(0x31a2b7ff), + LL(0x21d1b602,0xb389e984),LL(0xb19669c8,0x806cbce5),LL(0x729a4109,0x53062f9c),L_(0x779cbefe), LL(0x3bd3b5fd,0xa29b29ca),LL(0x6119b4c5,0xd386838e),LL(0xeb10107e,0x91c7a000),L_(0xd43d23aa), + LL(0xa2b87da8,0xb2465acd),LL(0x954d5e2a,0x935ce923),LL(0xcc9f7e66,0xa5432c5d),L_(0xd4ffbeb9), LL(0x02a952ef,0x686dc22d),LL(0xb3aa6ec4,0x272f791c),LL(0xf9a59b07,0xd8d7140f),L_(0x94e1344f), + LL(0x63bd0826,0x7dd1f80d),LL(0x241f38ad,0x61111bf9),LL(0x72ffb980,0xff97f61b),L_(0xa3d97bc2), LL(0x29de7bfe,0xd4e6e73a),LL(0xb4b19841,0xf25ef407),LL(0x5fd346b8,0xa14d6ec3),L_(0x366b72b2), + LL(0x700b11e0,0xb6fe5b75),LL(0xe3a6e8d3,0xf936e40c),LL(0x4ed1cc1b,0x9f69a8a4),L_(0xe6f9dbe8), LL(0xf722e6ee,0xa4d858ef),LL(0x00a65edd,0x39a6e0aa),LL(0x9733fc57,0xd4ab5744),L_(0x38f910bb), + LL(0xf3acc856,0x338c1ad4),LL(0x4a664d78,0x9d2c02fd),LL(0xd6ec4c42,0xaee2829b),L_(0xededd826), LL(0xb9a4651d,0x417e0805),LL(0x2c83b6ff,0x1f17faef),LL(0x65e8562a,0x54ffde80),L_(0x8972a5fc), + LL(0x639320ae,0x49c2561a),LL(0xd2b48b48,0x05a4bc45),LL(0x38241d91,0x7dc5afe2),L_(0xc399df03), LL(0x01fe9bae,0xc98d8a83),LL(0x666e5386,0xb711940d),LL(0x33895285,0xb43f7afa),L_(0xb804c149), + LL(0x4d95806d,0xd0681518),LL(0x93423c26,0x537054cb),LL(0xc2eabb37,0xea12b99c),L_(0x9297a177), LL(0x791e1723,0xddfee3a2),LL(0x4de65e15,0x21639c41),LL(0x7f3bad81,0xe43ae1fc),L_(0x7af9ba54), + LL(0x1981ac7c,0x13762e73),LL(0x5afe2e21,0x76679941),LL(0xa21b9a1b,0xd03deaed),L_(0xd498e9f2), LL(0xc88d2fa4,0x6ae69ee8),LL(0x749eed42,0x14c5a38c),LL(0x5f4c63df,0x95aa2f5a),L_(0x890e5e3e), + LL(0xda52bcab,0xdea7e049),LL(0xbf3bb703,0x6a4a37e1),LL(0xc64a209c,0xddb56124),L_(0x6858318b), LL(0xb063f261,0x9e3a0203),LL(0xf0dbd02b,0xf2de2a02),LL(0xa216442b,0x5ebba836),L_(0xc0cbf7a0), + LL(0xc6f7be46,0x9bdf3b81),LL(0xe5bfa2bd,0x471a44c8),LL(0xef3da843,0x7b3913de),L_(0x107bba5b), LL(0xd5502ac9,0xda5362cd),LL(0x81eecff8,0x51e4974d),LL(0x151060a4,0xd9ea79af),L_(0xe89b5db6), + LL(0x176cf8de,0x310d44fc),LL(0x4509feca,0x8d199332),LL(0x25aa7254,0xd40c4268),L_(0xa958ef77), LL(0x4c15f926,0x5dae221b),LL(0x71fc93e9,0xb47feada),LL(0xc3e3cb95,0x0f45640e),L_(0x6b7cb33b), + LL(0x2033fbaf,0xc74fe8dc),LL(0x8c9ef406,0x8a528a60),LL(0xb6fe758c,0x04aa9cd6),L_(0x4f8b3877), LL(0xbbebde8e,0x9f568191),LL(0x65aed657,0x88ffeed7),LL(0x85d0ebdf,0x7968220e),L_(0x04b5f3d4), + LL(0x2004c53a,0x275a3075),LL(0x3a2a339d,0x686f881e),LL(0x8a7f68a5,0x5e03cf06),L_(0xd663fea8), LL(0x5c2f3d32,0x83dd1968),LL(0x6151157a,0xbccda799),LL(0x620979ba,0x6d82e1aa),L_(0x3ac652d1), + LL(0x4bd23c39,0x9f8e323d),LL(0xed2fa4ec,0xaa59f591),LL(0x554cf5e9,0x14820bd1),L_(0xc72e2e81), LL(0x9ce69d25,0xe15fa1bd),LL(0x5f0c938d,0x6c3a0be6),LL(0xdf2d997a,0x33617c0a),L_(0x3087e812), + LL(0x5df1d007,0x7f81aff5),LL(0xd6ea063d,0xbe630797),LL(0x631cf97e,0x46b66ca3),L_(0x3bfc14a4), LL(0xd751c657,0x3a379a18),LL(0xaa5dfd05,0x87fb3d3b),LL(0xf3af9e8f,0x95b8ff29),L_(0x928c3c53), + LL(0xcfeb637a,0xe65a2e0c),LL(0xa11c784f,0xe52dcc1f),LL(0xd33e59b1,0x2f4c50c4),L_(0xe15fe3e7), LL(0x8e0494e2,0xe61d0a02),LL(0xdff24b95,0xa0c563a3),LL(0xd0e84cbb,0xc9c516d5),L_(0xbc6f5dd3), + LL(0x6f4d5a61,0x828d8489),LL(0x55c5a959,0xe0f2a11a),LL(0xed8f7fcb,0x2be30973),L_(0x0b24dc92), LL(0x835ad623,0xc98877f5),LL(0xd599613c,0x62b30316),LL(0x43a0bc0b,0x34b1b90a),L_(0xa8edd1ca), + LL(0x25bb0089,0x126c6d31),LL(0xb92a7bd7,0xb4a63c35),LL(0xd9952b28,0xb5f3accf),L_(0xd21fa7b1), LL(0x470e5d4b,0x6ac1deda),LL(0x7d8ef38b,0x7ddc00b8),LL(0x26d207ac,0xc01bf44b),L_(0x58c8cee8), + LL(0x43e06d65,0x5d2a899b),LL(0x94d31b36,0x787531d0),LL(0x3050256d,0xd6d74149),L_(0xaa4efe0c), LL(0xa5994d61,0x9b7a733e),LL(0x491dc4d2,0xab4d4ef7),LL(0x7540af9a,0x358ed8d5),L_(0x17dc58f7), + LL(0x2cf09935,0xb13a4f1f),LL(0x4d20428f,0xaa77cf17),LL(0xf17077d7,0x27509ac6),L_(0x58852489), LL(0xdeaa5893,0x64ad83cf),LL(0xc965f9f3,0xeb7c2c1c),LL(0x9a3903b0,0x2677b45a),L_(0x45839bea), + LL(0x1b4a3efd,0x6c1eb10c),LL(0x24b30b08,0x30469bc0),LL(0x44f85d04,0x688bbe3b),L_(0xc74ccccb), LL(0x40ec199e,0x94d1ce02),LL(0x14d9a43c,0x1e8a57b2),LL(0xc940698d,0xf3a40155),L_(0xefe2f127), + LL(0x7ced76b7,0x9378bdc8),LL(0xfbd86f1e,0xd3de6697),LL(0x38c7a9cc,0x965226a4),L_(0x434dbb0c), LL(0x1d9de00e,0xb9259728),LL(0xc36bf7c6,0xe5e2b0b4),LL(0x0a12f12b,0xb21834ca),L_(0x0134eeee), + LL(0x2cbf4902,0xad55e742),LL(0xa30d570d,0xceb87a93),LL(0xdaaa178c,0x525f0059),L_(0xf38af4e6), LL(0xf041ead7,0xa001bb9f),LL(0xa05f60e2,0x951d1144),LL(0x701418ea,0xfd38f820),L_(0x27e433c5), + LL(0x4f2b74e1,0xcf1f6417),LL(0x3570870f,0x2d368dff),LL(0x85875e05,0x96e8ab61),L_(0xefc6f006), LL(0x139ced83,0x0206e9aa),LL(0x6f6540da,0x1f1ac51c),LL(0x2a1b80e0,0x9caa872e),L_(0x895193a8), + LL(0xbe7a3924,0x40d4de6c),LL(0x288f99a9,0xa9bbbd0c),LL(0x74a2cf89,0xad2e6432),L_(0x52ddf73d), LL(0x50719c7b,0xef978612),LL(0xbb41a387,0x44b2c373),LL(0x319f4bf7,0x40e92907),L_(0x9884b224), + LL(0xcb2e3230,0xe2fde7bc),LL(0x282179db,0xb286e49e),LL(0x7897f73f,0x14a26c02),L_(0x07ab717c), LL(0x0974c087,0xb3e012dd),LL(0xa65b35a3,0xb211a759),LL(0xb888ddca,0xc0879433),L_(0x8819e222), + LL(0xa98ed0e0,0x32acb172),LL(0x9f902cc1,0x30fb222b),LL(0x2ea4f419,0xec378b71),L_(0xd036aa23), LL(0xfc7c459e,0x0f8fe474),LL(0x3e16c057,0xea879818),LL(0x134bd529,0xee28b685),L_(0x867d1b08), + LL(0x7f52225a,0x49cdbae9),LL(0x5c1f02d0,0x22253ab0),LL(0xd83d7d9e,0x1b0a0f31),L_(0x2c287cd4), LL(0xa7c8e376,0xf27c6df7),LL(0x74534873,0xb5e78384),LL(0x5a696a14,0x8118c158),L_(0xfc06292e), + LL(0xa94b2f8a,0x5e909156),LL(0xbd1a69f7,0x0e89f809),LL(0x703cb9be,0x5a474912),L_(0xcedd645a), LL(0xfc513c30,0xdeeac8ab),LL(0x2ed53772,0x8d081de8),LL(0x5e6b86ab,0xc7b731bc),L_(0x5ce1f8a0), + LL(0xa68e3ae6,0xcc023bb5),LL(0xdf3b4492,0xd2e02e8e),LL(0x87e45b7d,0x0ae46dae),L_(0xe1f7eac7), LL(0xe31f07c6,0xb2f3733a),LL(0x72718cd2,0x58504950),LL(0x85e9b624,0x626b0871),L_(0xc20aa08f), + LL(0x3383e911,0x44129030),LL(0x8b7e591b,0x1fa18b39),LL(0xc7753dad,0xf476b49f),L_(0x2fc4d6c3), LL(0x43355b4f,0xe26efb18),LL(0x4dd384fc,0xb345e6e0),LL(0x478d3761,0xc574295c),L_(0x421851ef), + LL(0xc576e693,0x92253e01),LL(0x5a61d65d,0xa9b92c8f),LL(0xd4924563,0x1e712886),L_(0x2dd1532f), LL(0x502854fc,0xa3f1ded9),LL(0x39cdfbfc,0xb3758c76),LL(0xb32cde92,0x57960c59),L_(0x40ad0b76), + LL(0x7c7eb74a,0x33392cdf),LL(0x52977c85,0x3035bc66),LL(0x147af937,0x6dd913b5),L_(0x4ec4b1c5), LL(0x3cd27826,0x699ab1e8),LL(0x438d69df,0x674459d8),LL(0xdf94b6a0,0xbc60bb02),L_(0x60dae203), + LL(0x98237ec1,0x01cf54f3),LL(0xc3cf28be,0xc86cd9e7),LL(0xfa448ad2,0xf8c1cf70),L_(0x59baadb3), LL(0x6e0c6ab4,0xb0a595fa),LL(0x60b75e6c,0xaef06103),LL(0xb92101cb,0x99833d0b),L_(0x4be8d444), + LL(0x76a063e0,0xedd8ac9f),LL(0xcb571bbf,0xfbb746f6),LL(0x5a13acc6,0x68203714),L_(0x79914deb), LL(0x698725d3,0x5c3bbaeb),LL(0x211e58cd,0x8019d5ed),LL(0xdef6ac5e,0x776cb363),L_(0x93cb4804), + LL(0x2c9e2d1e,0x7d49d5cb),LL(0x55e82125,0xb44a7110),LL(0xa13cee20,0x7e46156a),L_(0x7d7e5719), LL(0x293b532f,0x629c9b2f),LL(0x5fd28ac1,0x4766f7bb),LL(0xdc393f35,0x8ea6f6e3),L_(0x289c68b1), + LL(0xf29e017b,0x63596f57),LL(0x31f49f27,0xb9a200a0),LL(0x7c86680a,0x0b1f95fd),L_(0x02fc0e10), LL(0x61a4ad54,0x8f2843cd),LL(0xca4cab38,0x5392a44e),LL(0xace069cf,0xf56c80ff),L_(0x270d9677), + LL(0x8e969ba3,0x6352c6f5),LL(0x67e09224,0xd3d5c18a),LL(0x5be06f9a,0x14efc35d),L_(0x38c6a0a2), LL(0x0263394a,0xbe2d9aa3),LL(0x6d0b11a9,0x72815d01),LL(0x6c28404f,0x5538c4c6),L_(0x0af532d8), + LL(0x27afc27a,0x588f5f00),LL(0xb4277028,0x7fd91a63),LL(0x2477f29e,0x5fe5d31d),L_(0x68c2db2a), LL(0x3c6bab6a,0x2a5ebb99),LL(0x7b9c3f49,0x8847424d),LL(0xbf734579,0xbf266e3b),L_(0xfe65a7a9), +}, +/* digit=32 base_pwr=2^224 */ +{ + LL(0x390f347f,0xb7478766),LL(0xeaa013ed,0x69774be3),LL(0x1cf3e562,0xe8c99b44),L_(0x142c4251), LL(0x6addc55a,0x5ac149fb),LL(0x9c824754,0x251be20c),LL(0x6b1233b2,0xb9c09eeb),L_(0xc5afba96), + LL(0x772d2e43,0xb7c40ccd),LL(0xbf4d6687,0x4a5ac532),LL(0x88025f52,0x80c953d4),L_(0xe3dc6d83), LL(0xa265b97a,0xb7668ae2),LL(0x50faab59,0xa19f0872),LL(0x235fc5b5,0xac299c46),L_(0x1378e170), + LL(0xe16661d5,0xb43ccb67),LL(0x47792f74,0x13fe8d1f),LL(0x3dbeda1c,0xb688499b),L_(0x5b9b5ea1), LL(0x6ec4def3,0x6f26a9f6),LL(0xc4515542,0x45056f3c),LL(0x8e4ebca1,0x1f557c40),L_(0xd6441259), + LL(0xa24e4556,0xea6ea3c9),LL(0xc6c1108f,0xb4010098),LL(0xcc83bf8e,0x2c30408f),L_(0x7aa17b0c), LL(0x89219d24,0x06aed6af),LL(0xc003650d,0xbe94120f),LL(0x72d853fe,0x66238f2e),L_(0xf46a15a7), + LL(0xf0756f21,0xf16a11ac),LL(0xccc9dc6a,0xc74dff4d),LL(0x71ab7d63,0x54c72750),L_(0x5a001c63), LL(0xcf7f1e0d,0x226cb517),LL(0xb6f26d84,0x09440d66),LL(0x3fc36947,0x9f9ee30a),L_(0xa1549b9d), + LL(0x9d51f064,0x4a2b2246),LL(0xa65e1e3b,0xfddd99d1),LL(0x671cf2f3,0x6b9d08f0),L_(0x162efd24), LL(0x4fa36b3d,0x3316fc3e),LL(0x84ae1987,0xd5adf51b),LL(0x7d0dc886,0xdbe094f5),L_(0xc7b0730d), + LL(0xb0e743f2,0x1bb62b05),LL(0xe8e8411e,0x6fd286a0),LL(0xd192f8c2,0xe45573f0),L_(0xc1f3a5f2), LL(0x96b5af59,0x26419174),LL(0x6c1325f6,0x50d9352d),LL(0x2f81e001,0xa91d228e),L_(0x0ff7a9b2), + LL(0x1a7e3bbc,0x88e39d85),LL(0x42262241,0xc7cb4750),LL(0x3ad07ade,0x918fdfa4),L_(0xcb771a46), LL(0xd39e0dbc,0x18ba36b7),LL(0xeb29d84d,0x3f5d4732),LL(0x1383d57f,0xf57833f6),L_(0xfda5e179), + LL(0x024fa042,0x47af4689),LL(0x6f69c44b,0xe8d6a5c3),LL(0x5e4d4fa0,0xd6821d55),L_(0x46eb8384), LL(0xc59ebc7b,0xcdeb889d),LL(0x871d5809,0xeaf69758),LL(0x1029a1da,0x5cf9245d),L_(0x1bcc2546), + LL(0x491af658,0xfd8a4d1e),LL(0xdb1de26b,0x677407f1),LL(0x8aa6deb0,0x12fee6da),L_(0x1e010832), LL(0xeb1d6fd4,0xd9702487),LL(0x9e928c81,0x0d5e0508),LL(0x79014b3a,0x844adfba),L_(0xa7623853), + LL(0x6333a497,0x2e0124e6),LL(0x2b6dbd37,0xacc3158a),LL(0xcb4fc42b,0xd7cdda0b),L_(0xd5d8f543), LL(0x1a1d4227,0x485584ae),LL(0xdd6eb7f3,0xa25706fd),LL(0x2e41e3f8,0x65859cc9),L_(0xeca30c9e), + LL(0xef4c8e5d,0xd5f8805d),LL(0x66979e6c,0xc2437937),LL(0x1b2ea5ec,0xf8ebb830),L_(0x416a9eb2), LL(0x87c226a3,0x6e8ad20c),LL(0x15ff6e9d,0x784bfc8d),LL(0x0865593f,0xee384b9b),L_(0xe0eeda2c), + LL(0x148e4a75,0x642f55af),LL(0xbfeb8487,0xc162ad9e),LL(0xfa3ad249,0x7145f39b),L_(0xd0f1abf1), LL(0x4053c61b,0x4defbbd5),LL(0x893a0505,0x1244854d),LL(0xf3e2f26d,0xf54c27a7),L_(0x6f12b38f), + LL(0xa1ac9684,0x5d26514a),LL(0x7cad1aa3,0x3b5e65fa),LL(0x74faf86d,0xfeab4314),L_(0x645cca78), LL(0x3c8ed8d4,0x43f00055),LL(0xb72096cb,0x8df847ba),LL(0x7a1950ed,0x071d954a),L_(0x5337fbf2), + LL(0x33140bfb,0xb32000f6),LL(0x5f6dea95,0x27eab135),LL(0xf4446577,0x19091ccf),L_(0x74118cb1), LL(0x765e46b5,0x9210256d),LL(0x9aacef2c,0x3ce74727),LL(0x1ca9b6d8,0xb1ab02c7),L_(0xa870996c), + LL(0x36f1ae02,0x308cbf7f),LL(0x552396fc,0x748ef11b),LL(0x7b2fda3a,0x4146f800),L_(0xaebf97a3), LL(0xb4291275,0x61fb1316),LL(0xf1c9012c,0x894b0da7),LL(0x0142bd07,0x9b191445),L_(0xbab9da1b), + LL(0xe1f1f426,0x5e508e4a),LL(0xfa8ca29d,0x4b94de05),LL(0x27a0f674,0x4cfdd6de),L_(0xee0206bb), LL(0x4b46ce88,0x978ed51e),LL(0xa6bbc41f,0x6bee5364),LL(0xe52c7867,0x006c7072),L_(0x32478f51), + LL(0x5382793a,0x217f1202),LL(0x04851e7d,0x3c689851),LL(0xd7767c09,0x75b3d632),L_(0x4c08238d), LL(0xab3ed287,0x3858c44e),LL(0xcd97e8ec,0x0c103d5b),LL(0x62318c47,0x93355b9b),L_(0xe2405794), + LL(0xe36e5cd7,0xde835c5d),LL(0x92a463c3,0x1eba7f4e),LL(0x3b10b96a,0x4b4acd48),L_(0x5f5bd93b), LL(0xd4e11813,0xf537b955),LL(0xedc9c8f4,0xf31bab45),LL(0xf2362c8d,0xe58a0000),L_(0x970cf697), + LL(0xc005e339,0x8e7b1729),LL(0x882e0b3e,0xf8b77b70),LL(0xbf2d6013,0x490fbccd),L_(0xc0848551), LL(0x5c4916a2,0x73f7a7d8),LL(0x17b850e8,0xde0ad5e0),LL(0xfcc68ded,0x9cbe988b),L_(0x8d09bdd2), + LL(0xf00570c3,0x6266d7a9),LL(0x7f0f6292,0x4291a62a),LL(0x47c40355,0x1cfc61e3),L_(0x7a59e7d3), LL(0x4ce6c101,0xbddfbabb),LL(0x84b7a613,0xe92b59c0),LL(0x89396fd0,0x0f5147ce),L_(0x2b7f355a), + LL(0x9d82dd91,0x8af9951f),LL(0x4d2ceb91,0x78598c17),LL(0xcc451e87,0x6d59d3b5),L_(0xc116fdef), LL(0xd20d8318,0x79ead74d),LL(0x813a5852,0x8ba20d33),LL(0xc12ffcbc,0xcd67731a),L_(0x3fdf17e1), + LL(0x5e3aff2a,0x764582dd),LL(0xefaccc05,0x05c889a6),LL(0x63018ab6,0x6f606211),L_(0x6b706f5e), LL(0xac9cf98f,0x2663583f),LL(0x2a01814c,0xde1ab3e0),LL(0xe29eede6,0x756a8f01),L_(0x10f5f095), + LL(0x363dd819,0xa38d34f9),LL(0x591f8fe0,0xc1ebeead),LL(0xc31b8775,0xae2b4a7d),L_(0x55de9380), LL(0xd500cd22,0x63877737),LL(0x566cf0c3,0x04743650),LL(0x1ad0462c,0x5c1a2a83),L_(0xcfd11aad), + LL(0x4c679d95,0xbc66bc8e),LL(0x9f39feb3,0xd84b8c56),LL(0x21f0dec8,0xd2ff18e6),L_(0x99e3e6c4), LL(0x08b2eebe,0xcce55b7e),LL(0xf3fabc3c,0xb0ed283f),LL(0x5c869424,0x4f7a9f81),L_(0xc660df04), + LL(0xd868008a,0x302b25d6),LL(0xfbdef76c,0xd9a10be6),LL(0x97f6ff80,0xcc0decf0),L_(0x26e1f975), LL(0xbb6408c0,0x4f37e254),LL(0x61eee678,0x9682814e),LL(0x6a0d8fc5,0xd84014df),L_(0xb7e3a2d4), + LL(0xaa81602b,0xde3d73e7),LL(0x3178216e,0xe66f2866),LL(0x2f89efcd,0xdcbe0246),L_(0xb937b3c2), LL(0x72d505b5,0xacaa30cf),LL(0x7f06975e,0x66c190f4),LL(0x714b6102,0xd23f9579),L_(0xc1321142), + LL(0x3c07cee1,0x8271dfd0),LL(0x6e2e57bd,0x85e2b2d2),LL(0xec736ab9,0xbcfb4116),L_(0x1cc014d1), LL(0x57b0096e,0x02178015),LL(0xbcc0c7bd,0xda722aae),LL(0xdf2643e7,0xedc952bb),L_(0x36ab26fe), + LL(0x76041355,0xc562a324),LL(0xccd2af21,0xa955496c),LL(0x8cbd4ea2,0x9f800082),L_(0x7bbad5e0), LL(0x53fd9c07,0xbfd65f54),LL(0xfa87a290,0xd0f0709a),LL(0xd25d631b,0xe063926d),L_(0x0f3d4539), + LL(0xd48fa29e,0x6bf5b024),LL(0x1a63c568,0xea32fa48),LL(0x7bad1c42,0x62df4304),L_(0x38b54b11), LL(0x97d1cfa8,0x94995152),LL(0x7f7b64f5,0x9e00e462),LL(0xd25d1128,0xbdbbd673),L_(0x4703bb51), + LL(0x304a08ec,0x2509ad1a),LL(0x9885b7f4,0x9877088f),LL(0xf70447a7,0x9bfc053a),L_(0x1b77852c), LL(0xaf70aa1f,0x7dc9ba14),LL(0xa43807b7,0xff3589c4),LL(0x02c669a5,0x220e1871),L_(0x991d8093), + LL(0x86209a7e,0xc434b863),LL(0x6c74aee9,0x10b6d0ca),LL(0x072efedb,0x19982c91),L_(0xac91d19f), LL(0xbfb13837,0xbc64a3c6),LL(0xcea49a1b,0xab8a0475),LL(0xe25c1282,0x37f9ab3c),L_(0x57709b27), + LL(0x422a938d,0x63a0bab7),LL(0xbdede240,0x2dffb3e9),LL(0x8ec0a031,0xbbb0cddc),L_(0xf6b96225), LL(0xfa46994b,0x3dff08ca),LL(0xf46b51e6,0xb21694f6),LL(0xfac7173a,0x3f2c5530),L_(0xe5090eda), + LL(0x5e18c4f3,0x585b98ed),LL(0x4cb0c03a,0x2784af9f),LL(0xb6dc9a2d,0x126ee071),L_(0x3331172f), LL(0x56db8dc6,0xba3aa739),LL(0x71ac411d,0x16a260a5),LL(0x816a4f1b,0xa88c4198),L_(0xe409dbda), + LL(0x5fd428ad,0xccb6c49d),LL(0xa20ba7c3,0xe7066136),LL(0x6782fea2,0x83b7b5ce),L_(0xf28c836e), LL(0x4fe78dbc,0x64f82fd1),LL(0x523afba8,0xe21bc6e2),LL(0x024ddda9,0x65d29391),L_(0x4cec16d6), + LL(0xfd04b964,0xaff84dd9),LL(0x1594f62b,0x4eb6067b),LL(0xa8de453c,0xeb65c1b7),L_(0x30a103ff), LL(0x6903c7e6,0xf76afad7),LL(0xa91cd374,0x2f9fd25b),LL(0xa33359fe,0x0b99c0c0),L_(0x9015867f), + LL(0x8a65619a,0xb366fcc7),LL(0xdde98289,0xec03d9a8),LL(0xe45737f9,0x30c2ee70),L_(0xa6bb364a), LL(0x67ffeeef,0xe00c866a),LL(0x8177a004,0xac4b7104),LL(0x49205953,0x0106e5ac),L_(0x5d4c1327), + LL(0x2e836cb7,0xdebcecc7),LL(0xfdc46d5f,0x9b0df65d),LL(0xa125951c,0x5633f2c4),L_(0x04c2afc1), LL(0x89476731,0xacd14df8),LL(0xb5f970f1,0x9f48abbc),LL(0x0973ccd0,0x236b3580),L_(0x02b2c84a), + LL(0x88394318,0xcb13811c),LL(0x0d2dd5a3,0x9bbda12c),LL(0xd8b5d0f6,0x4f399d9a),L_(0xa46887b9), LL(0x2ae73578,0x10165160),LL(0xddf54326,0xc04d1a88),LL(0xf080be9c,0xeee34275),L_(0x047237fe), + LL(0x7aab908a,0x11fceb11),LL(0xfaf4fbdf,0x96bea707),LL(0x66bfd60d,0x442c2a46),L_(0x28cf0358), LL(0x6d51778b,0x4cebfe24),LL(0x6c01d714,0xaf283f0e),LL(0x11d66f5a,0x8cc29c26),L_(0xcf7771ef), + LL(0x76ad7d8f,0xf90d16be),LL(0xb89933d4,0x2a97f299),LL(0xc8f0695f,0x5a6af165),L_(0x82274dbf), LL(0x1826ea5a,0x225b8bb2),LL(0x5e138d61,0x16c62f5f),LL(0x3e2273d1,0x6b42f9f3),L_(0xaa4b331c), + LL(0x5659f40e,0xa9d80f3d),LL(0x6773ac5a,0x6ed38547),LL(0x970b6067,0x78700052),L_(0x2f129047), LL(0x4d7032cd,0x0393eefa),LL(0x04368569,0x98e16738),LL(0x5180fe6f,0x3014d2a0),L_(0x6bd99185), + LL(0x1988a375,0x299011dd),LL(0xe9270a23,0x40dded09),LL(0x54a9528b,0x7af57c36),L_(0x8e613981), LL(0xb388faf2,0xff5fc081),LL(0xd7dd7f17,0x2ccd8f6a),LL(0x421cb6c5,0x590b13ce),L_(0x8f9e6852), + LL(0xe7870572,0x6513f9c8),LL(0xd5bf1a5d,0x2f88c206),LL(0x1942fc9b,0x6ec5f13f),L_(0x70273957), LL(0xf1998de6,0x5bb80bbb),LL(0xcededd82,0x923e0aaa),LL(0xa7c7ee32,0xfa06b05d),L_(0x86a8080f), + LL(0xe016efc2,0x9510adb0),LL(0x8a998afb,0x9a9168be),LL(0xfaf28d30,0x0863e4f3),L_(0xdcf64ed3), LL(0xa0beb82c,0x1ea72a0f),LL(0x78d5ce7b,0x932f17af),LL(0xafe82b0c,0xde25a969),L_(0x1f0a50fe), + LL(0x496b6eb7,0x3d5e21a1),LL(0xddb5610d,0x36b95de4),LL(0x435cd100,0xcc34b698),L_(0xf7218db6), LL(0xf643607b,0xc23a0cb7),LL(0x3b787bdf,0x2299d421),LL(0x71fcc010,0xb0e2a897),L_(0xd6c69c33), + LL(0x0241244a,0x1cd5d5da),LL(0xe94a402b,0xf0ca4eca),LL(0x26944f06,0x737d6c5b),L_(0xd0af2018), LL(0xc1e2ad0c,0x1b523220),LL(0xa8a984b3,0xc8ebc391),LL(0x39663eef,0xbf4b3e0e),L_(0x0297dfd1), + LL(0x0ac5f597,0xc8d20d13),LL(0xf915a4c4,0x00b7e16a),LL(0x2921fb10,0x6b467b73),L_(0x226421aa), LL(0xf2ede5a3,0xf4bdad8c),LL(0xb5512d8c,0xce15cba2),LL(0x2df92000,0x4979cf5a),L_(0xd5159856), + LL(0x7ac29a8f,0xffb25428),LL(0xad4ff433,0x6903617b),LL(0x22c48ae6,0xdcdd2832),L_(0xee468cb2), LL(0x6769e2fd,0xad56cbbc),LL(0x1ac2be8d,0xc8f4bea8),LL(0x11bdfbf2,0x4c080ea0),L_(0xd326fcc1), + LL(0x264b7510,0x3c2a21b2),LL(0x4c900a2e,0x10bf375c),LL(0x540b6e6d,0x40c9b00d),L_(0xf0db08ca), LL(0x1f0e8e4f,0x75ea8b18),LL(0x23e0167d,0x4ae7f6f7),LL(0x3ce76be8,0xc2578bd9),L_(0x274ef866), + LL(0x2d2787bd,0x06e96b07),LL(0xa0cc2074,0x3859e8e4),LL(0x2181d378,0xbc50ac87),L_(0x46b62277), LL(0xc39d3dd1,0x66a073ee),LL(0xbc771f86,0x2bf462de),LL(0x47275780,0xa7216ad9),L_(0xd3c1c667), + LL(0x359b7048,0x37e5b8f4),LL(0xfea02084,0x16126c46),LL(0xe9a5f0b8,0xbf587847),L_(0x53933d2b), LL(0x1c7944f6,0x492b64e3),LL(0x8257b251,0xf2983977),LL(0x8d9ec843,0xfe9686a0),L_(0xeeea3972), + LL(0xac24ef0b,0xb93a8f55),LL(0xf5712604,0xfa720e89),LL(0x6981acc8,0xf73a981c),L_(0x86cc6e25), LL(0xd19071bc,0xa6c75878),LL(0x18cf2a94,0x15519e91),LL(0x5737dd50,0x4c1f9f0e),L_(0x3114afeb), + LL(0xec690133,0xbbc2c60e),LL(0x19e92b39,0x1a4e7efe),LL(0xb3de20d1,0x43d40348),L_(0x693597af), LL(0x9b86b502,0xa7c941f1),LL(0x4568fdc8,0x38d7607d),LL(0x92d2afed,0x50493b74),L_(0xa510adc1), + LL(0x29a4b55c,0x60867e2e),LL(0xab4d38b7,0xc6a2be65),LL(0x0b8a018f,0x2c774449),L_(0xc11883d8), LL(0x3703e4c4,0xa50bce89),LL(0x9bcfd81b,0xc601a985),LL(0xf5811bc5,0x80f1e9c2),L_(0xe9b876e5), + LL(0xb21301b8,0x368a0741),LL(0x7cf8b51b,0x57d524cc),LL(0x85f0eb37,0xb5926249),L_(0x08e70a34), LL(0xdd6d17da,0xe9a1940d),LL(0x4d61fee9,0x905e7d89),LL(0x24af91e7,0xa85a5970),L_(0x41f4907d), + LL(0xa38b5cfe,0x33182545),LL(0x7b2ef570,0x10b61fe2),LL(0x2a780101,0x8d1180df),L_(0xab954cb9), LL(0x8b6a7232,0x88d81ace),LL(0x0d62a965,0xa35ed73b),LL(0xaa16f924,0x2bc7cca4),L_(0x2d99dcc8), + LL(0x3c5881cd,0xb1395709),LL(0x21c56351,0xe2ce53b6),LL(0x41b20f4e,0x067af3fb),L_(0xbd9ab15f), LL(0x2f06e7bc,0x1523f3df),LL(0x9de5e7e4,0xb26c33fb),LL(0xef0cf37f,0x6c9e48d4),L_(0xc9fc2851), + LL(0xcb75ecba,0xb81124f0),LL(0xea0ed825,0xad146b33),LL(0xf4f08526,0x8e19f5c1),L_(0x820a4f79), LL(0xa1d54353,0x6eaedecb),LL(0xefe607bc,0xe5ecca5d),LL(0x75968ada,0x21596aa9),L_(0xcdf9ca14), + LL(0x4cdb6b68,0xdaef28c2),LL(0x2be4550b,0xdd0b6f86),LL(0xee673998,0x8162c783),L_(0x4e1fb36c), LL(0x58a6ed93,0xab7e3385),LL(0xb682150c,0x3081637e),LL(0x02a0814f,0x9c692620),L_(0x3bb22aea), + LL(0x6bc24027,0xa03f91a5),LL(0xd356a2bd,0x0f664f1a),LL(0x04625b5a,0xf350f847),L_(0x2eacfb01), LL(0x4e04629e,0x63af93f4),LL(0xba005c26,0x8ec3c009),LL(0x7964a6f9,0xc56edb4d),L_(0x14b146d7), + LL(0x64910001,0xcae5ffdd),LL(0x51fbb8f7,0x657b3f67),LL(0xa961e968,0xbe43f447),L_(0x2a774b0b), LL(0xbfbe3d28,0x4e174bef),LL(0xb12fde0a,0x11d92d90),LL(0x85b59e4f,0x421eac26),L_(0x4c480a51), + LL(0x83f1230c,0xc3a1a862),LL(0xfe8ceef6,0xbef83f8d),LL(0x0469540a,0xd231a2a4),L_(0x0828f4c0), LL(0xc896c8cb,0x2c034efa),LL(0x1744d906,0xc9a26995),LL(0x2a85a8d6,0x28f5775a),L_(0x58717292), + LL(0x12ab27ce,0xf12dc791),LL(0xbcc5e464,0xec36c787),LL(0xb881c819,0x2bfca9a4),L_(0x7e60531f), LL(0xd8af4418,0x28ea4eef),LL(0x9ef6ada6,0xe0a7044d),LL(0xf56fbcf0,0x534e2057),L_(0x9857c41f), +} +}; +#else +const __ALIGN64 P224_POINT_AFFINE ec_p224r1_precomputed[33][64] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0xbc905227,0x6018bfaa),LL(0xf22fe220,0xf96bec04),LL(0x6dd3af9b,0xa21b5e60),L_(0x92f5b516), LL(0x2edca1e6,0x05335a6b),LL(0xe8c15513,0x03dfe878),LL(0xaea9c5ae,0x614786f1),L_(0x100c1218), + LL(0x4ca9a1ed,0x5650df9b),LL(0xbe27f7a3,0x2a0f1689),LL(0x10c911f7,0xcafb50f5),L_(0x18dd00ac), LL(0x02aac79c,0xc90ae186),LL(0xe72e600f,0x76cc1019),LL(0x0c84ced0,0x5cabb880),L_(0x6a5db1a2), + LL(0xe37710d8,0xe0b02223),LL(0xab22ca96,0xc3cf1c5a),LL(0x00505bb6,0xaf8b6496),L_(0x799eb566), LL(0x9a73b174,0x04144e62),LL(0xe434f88f,0x357940ab),LL(0xafe10c35,0x6dfa492c),L_(0x8c1b1da3), + LL(0x0a72faf7,0x0860856c),LL(0xc03cd01a,0xcb021705),LL(0x4256e88a,0x89f0c6a0),L_(0x7bf0ef17), LL(0x6743e274,0x98933269),LL(0x64b26855,0x2058f0ba),LL(0x7ee104d3,0x8c87db62),L_(0x73e0d4c7), + LL(0x0b10cc51,0xf8dfc283),LL(0xac3c8962,0x975a451e),LL(0x39211b77,0xf7f4fe95),L_(0x2bd053a8), LL(0x2b552e74,0x61a9e695),LL(0xc350ef91,0x11bcf037),LL(0x42b54f79,0xc858da82),L_(0x9b052162), + LL(0xde577c0e,0x1a8aec73),LL(0xe82df964,0xe0cd01d3),LL(0x1addb3a1,0xf25fe17c),L_(0x21b6fe25), LL(0x5fae6c33,0x0f5c7709),LL(0x327f8848,0xf2d2c41c),LL(0x9b6731a6,0x162f9e1c),L_(0x2383dee4), + LL(0x90462821,0x68646e35),LL(0x5048b145,0x1e2526ba),LL(0xc81df812,0x7ed50814),L_(0x7665453e), LL(0x610f2186,0x1fb32889),LL(0x9d0eba26,0xed8ceeed),LL(0xce5eb25e,0x0e5952e3),L_(0xa229bf84), + LL(0xb4c9d866,0x7bd696a2),LL(0x1de5d041,0xa3bebfe9),LL(0x8e4a5712,0x1b59038c),L_(0x21e8f814), LL(0x1bc1ff37,0x7558734a),LL(0x38a20402,0x0976258f),LL(0xc4e19066,0x2199c364),L_(0xd65a0dfb), + LL(0x1c1ecc78,0x743eda4a),LL(0x9f0b4f26,0x2f993a4f),LL(0x94f5e9ba,0x79d4095a),L_(0x846b2c39), LL(0xe07e55b7,0x909bf3f1),LL(0xbacf5e6a,0x77e1db6c),LL(0xe733d627,0x5114ac9d),L_(0x70889bf7), + LL(0xb808145d,0xb4f2672c),LL(0x328e0ac0,0x3e8abf6a),LL(0xc1f86e2c,0x9d0cdd53),L_(0x5ac34abe), LL(0xccddcf00,0x02883b6f),LL(0x225faa54,0x873d7e4c),LL(0xdbc0f8ee,0x2a687506),L_(0x722981c9), + LL(0xac358ca9,0xe1bdd5ca),LL(0xde5d2c4d,0xd0dee305),LL(0x0f060758,0xd6d89093),L_(0x9397da27), LL(0x649ea143,0x08181c2c),LL(0x79888920,0x6c63713a),LL(0xc1182bf0,0x45e48d79),L_(0x0e48dd82), + LL(0xf6495da2,0xa37b7441),LL(0xed4d0ea3,0x2b0b8e19),LL(0x571d38d9,0x517af941),L_(0x70792626), LL(0x1305b613,0x8cf21835),LL(0x208ffd66,0x5f59deb1),LL(0xbc243af0,0xa71404ae),L_(0x6d228d4b), + LL(0x489c8db3,0xffbe563f),LL(0x83630fe6,0xbc99fb0a),LL(0x68ade63c,0x398eacf0),L_(0xc5e095c8), LL(0x83fdacb6,0x800df824),LL(0xa3ffe74f,0x442ed616),LL(0xb4dc6bf8,0x3f8060b4),L_(0x12ab633c), + LL(0xf4109222,0xcdbd6eec),LL(0x0e9441ba,0x1ef814eb),LL(0xf4550d2e,0xb3a9b5e4),L_(0x47c1182a), LL(0x1544e90f,0x3f51f9f9),LL(0x9ed249e3,0x825b5794),LL(0x6516bbc3,0x3d1419d2),L_(0x92de7285), + LL(0x55bfd51a,0xb16ed1af),LL(0x464afb0a,0xd91345bb),LL(0xc5e26f62,0x64a35d22),L_(0x16880cc7), LL(0x05015843,0x70203aa0),LL(0x11e4ffa1,0x05a83a63),LL(0xdaf3972b,0x9422f10e),L_(0x5dbc0e12), + LL(0x6a4bd1fa,0xb3f66de6),LL(0x2ec3ac7c,0xfdf9a0e9),LL(0x471a2a7f,0xb9c51b5f),L_(0x8c4bc81e), LL(0xfa29681b,0x9c409bd0),LL(0xd979b98e,0x169405c2),LL(0x48be80cb,0xf22d3fc0),L_(0xbba8bdbd), + LL(0x86ade48c,0x79cec3fb),LL(0x3f83b939,0xb9622253),LL(0x5523244b,0x538d543e),L_(0x07ba7ce6), LL(0x12bb38c0,0xb4e20b8c),LL(0x70a52728,0xe6873448),LL(0x2a2e7758,0x2954321a),L_(0x07a8f3fd), + LL(0x3591891f,0x27a72a86),LL(0x845865a8,0x482460f5),LL(0x70114363,0x3b204e52),L_(0xb84ab43b), LL(0xd5f98054,0xc4a1a96b),LL(0xa4e237e3,0x0c0e97bb),LL(0x6bc4b6e9,0xfb212c8c),L_(0x335f11e1), + LL(0x716b6ade,0xea007122),LL(0x2a638e5a,0x08a75055),LL(0x4e35e1f6,0xe28f8fa3),L_(0xe40528c7), LL(0x7393ad17,0x4e27959e),LL(0xd8f5fd90,0x433c708c),LL(0xe5b33144,0x4c003b64),L_(0x6c3deb98), + LL(0xc57bd47b,0x238addb6),LL(0x8d685d17,0x703c82d4),LL(0xa0691b17,0x14a5d58e),L_(0xcd7fb5fc), LL(0xf9cefcb6,0xfd4764c3),LL(0xbb38397b,0x7b23c9fd),LL(0x23cf8d21,0x1d7b0c07),L_(0x7dafc83c), + LL(0x869c61a2,0x8d8b998b),LL(0x6f781395,0x5cc8116d),LL(0x1f271989,0xa8992ade),L_(0x78c70a2c), LL(0xb2334f8f,0x1fadf19a),LL(0x28c19018,0x71d5904e),LL(0x939bd9ec,0x534ec549),L_(0x77091fc9), + LL(0x22be0a45,0xb12549d7),LL(0xca28a29e,0xb64feadc),LL(0xfa13b698,0xd61f5f42),L_(0x5d34326e), LL(0x7ea2feda,0xd797283d),LL(0xc9ceaa43,0x5e1f2529),LL(0x113c4da8,0x4d22be7a),L_(0x12036cda), + LL(0x746daf60,0x210782c4),LL(0x64b5fd56,0x358ace9d),LL(0x1008fd0f,0xaf231c63),L_(0x285dcb4b), LL(0x17203da1,0x3534d554),LL(0xf8542368,0x30962d47),LL(0xf7552ee7,0xa1ab0080),L_(0x11208856), + LL(0x7708ee69,0x981a94f1),LL(0xd9d79e3e,0x50822535),LL(0x2632b017,0x21031b41),L_(0x8876f1a5), LL(0xa43cc165,0xfb24577f),LL(0xcd6f28d7,0x67a5fdbc),LL(0x583ccbb4,0xdf198e9a),L_(0xf49fccdb), + LL(0xec729f5c,0x347bddd0),LL(0x77f89e52,0x4576657a),LL(0x79a42c59,0x3a4d5c62),L_(0xdc6f4cf3), LL(0x72672c8e,0x34edf6de),LL(0xa9cc925d,0xc615c175),LL(0x264b7c52,0x6b6c91f7),L_(0x78e30c64), + LL(0x3c93deb5,0x454fe5e1),LL(0xc107ca82,0xdaedb454),LL(0x895933d6,0xc3d92afc),L_(0xc23f9ad4), LL(0x62afc583,0xb1ad4196),LL(0x9336c30d,0x122626f8),LL(0x56df6aa3,0x88c5db33),L_(0x454135c4), + LL(0xb5862dd9,0xfb7f7ec7),LL(0xfd622a86,0xf9ca08fc),LL(0xf3fb356b,0xa3379ec2),L_(0x3726b3ee), LL(0x5680ab95,0x1f4b780d),LL(0x72773b06,0x181ad0ef),LL(0x9c77acf2,0xc5ed6c19),L_(0xd82c650d), + LL(0x57cdf957,0x2e235ce3),LL(0x919ef962,0x3b66736f),LL(0x02924c24,0x9611c7f6),L_(0x5a87ed36), LL(0x2cd39c41,0x0ca01257),LL(0x8cec5f84,0x36cea89b),LL(0x576c9d6d,0xc0386b9b),L_(0xdf235412), + LL(0x3ff1d621,0xb26ad028),LL(0x0117a093,0x3395a449),LL(0xbb9b7453,0xac8575b5),L_(0x9638e810), LL(0x19b52295,0x61b7e04c),LL(0x917e2f50,0xea595a39),LL(0xb7e04864,0xf641867a),L_(0xf34ee0e8), + LL(0xf9c67813,0x0d5cd555),LL(0xcd9d1329,0x15609313),LL(0x071a1814,0xcec729a1),L_(0x973d765a), LL(0xd82b0a64,0xe9fd6113),LL(0xe16f07d8,0xf4a523e7),LL(0x095fdd3b,0x601388e8),L_(0xd8da4ec4), + LL(0x5d150589,0x6e0c12f8),LL(0xe3db4074,0xcc4b0246),LL(0xe25d613a,0x98b62cd3),L_(0xc7d0dccf), LL(0xca8e4caa,0x1f7fb23f),LL(0x6eff4dea,0x41da9f53),LL(0x44527d49,0x9e1f47c6),L_(0x3f6e7e3d), + LL(0xb17f74ed,0xe460275b),LL(0x3f409a21,0x56dc0e69),LL(0xaef13524,0x055bebff),L_(0x40a3d6e6), LL(0x5a0a6116,0x52aae002),LL(0x5d1a1a61,0x65c91bf7),LL(0x55229ca9,0x837c7497),L_(0x7a1145b5), + LL(0x724287d7,0x86eb5493),LL(0x2b764d91,0x7078641f),LL(0x72b46e9e,0x0bd8afe8),L_(0xfaf8c9a7), LL(0xeea543b7,0x7400cd52),LL(0x409c38a5,0x0a6c2e1b),LL(0x9604a54b,0xe2c2c60a),L_(0xd18594c9), + LL(0x771d897f,0x80cd8b3c),LL(0x4efc7c63,0x3b961927),LL(0x56c6e625,0x8d0c1d5a),L_(0x5533d0e3), LL(0x4b4c8803,0xee49b988),LL(0xc5802272,0x617aabd8),LL(0xb63d84cc,0xb309e31a),L_(0x0fa8942f), + LL(0x6ef3ab06,0xfbca1b97),LL(0xa18bd2bb,0xd8911f8d),LL(0x639e011c,0xb731d607),L_(0xde5b279e), LL(0x0706cd09,0x8e5b6703),LL(0xc24e209d,0x4d443d16),LL(0xdc2ea468,0xccc5dbca),L_(0x9aba875f), + LL(0xf86e4ee7,0xb38b3cb9),LL(0xdc2bb49b,0xd001bff5),LL(0xad920b0c,0x5f833048),L_(0xd67959b4), LL(0x3c687113,0x9cac7077),LL(0x84cba202,0x2bf74e82),LL(0x92b4f4b1,0xfcfe6f73),L_(0x3154d972), + LL(0x9afdccc2,0xf2645ccf),LL(0xe60a2a1d,0x170bc3dd),LL(0xc06a289b,0x8b3174cc),L_(0xb5e5b73e), LL(0xc289c4c6,0xfcbc66cf),LL(0x3f41c58d,0xea32e7fb),LL(0xfdc7bcec,0x2d89d32d),L_(0x34aa50e4), + LL(0x31801b59,0xcf102dd0),LL(0xf19df129,0x28f82869),LL(0x1600629e,0x6d3edc02),L_(0x3c98d6b7), LL(0xf21cabe7,0x31851ac8),LL(0x09f782ac,0x037f5693),LL(0x3f33781d,0xb0a0ce6c),L_(0xe96df7ee), + LL(0x4821f126,0x43b3629d),LL(0x502c3b9c,0x3319053f),LL(0xa3b32151,0x4038845d),L_(0xea3b4ccc), LL(0xedfaa06d,0x00044014),LL(0xd835277d,0xd5eb20d5),LL(0x1a8a108b,0x38cb0a6b),L_(0x30a8f927), + LL(0xb6e363d5,0xa45c3df2),LL(0x96c532cd,0x00c26ab0),LL(0x85098966,0x6d03e325),L_(0xea0d51b3), LL(0x8eec84d2,0x9134e03a),LL(0x04327df4,0xbbc8d92d),LL(0x4ffdb217,0x6e97a4bb),L_(0xc9fa9177), + LL(0x231d20c6,0xa36c8848),LL(0x3fcb294a,0xcb7e8b54),LL(0xc4b2c9f8,0x2f8b6de0),L_(0x49f1993b), LL(0xb8860526,0xfdcf530d),LL(0xb895a0fe,0x49da0f6a),LL(0xefc627b6,0x4e9fb807),L_(0xdbc0d2c1), + LL(0x64eae114,0x23074bd5),LL(0x48d5696a,0xb246633b),LL(0xefdb4759,0xc6af484b),L_(0xde4380e0), LL(0xe5997f29,0x8979b2ec),LL(0x507b7708,0x530f4963),LL(0x55ee3298,0xccf127a1),L_(0x32413bed), + LL(0x687018fd,0x7c723f5d),LL(0x86c9f952,0x2221f721),LL(0x93828714,0x13d720d3),L_(0x45d38213), LL(0xe61c9b06,0xc198db55),LL(0x598140b2,0xbe38af8f),LL(0x621f284e,0x18f09bf6),L_(0x192fd52c), + LL(0x65cd0db7,0xbb33fff7),LL(0xf9ca36b0,0x44ac0a55),LL(0x7a9b66be,0xc9308cae),L_(0x837d663e), LL(0x1b4048cc,0x5b7ecc1b),LL(0x4ee4991e,0x7fa30aad),LL(0x7e09ad23,0xff1f76e3),L_(0xbc48338a), + LL(0xa178a33b,0xdd724842),LL(0x914d8342,0xa5d7a87b),LL(0x30befc70,0x69874db8),L_(0xec19410e), LL(0xcfcdbfcf,0xe3d6346a),LL(0xde9edbbd,0x84c65475),LL(0xde39cef5,0xe4efb3c1),L_(0xc10a727b), + LL(0x493ae0bb,0xbc282cc0),LL(0xe7ebcd87,0xa024a0e9),LL(0xfa3a15cd,0x240e6a89),L_(0xa4a7db8d), LL(0xbba5d02e,0x95b6f1e0),LL(0x86491854,0x15b8172e),LL(0x158b8956,0x5eb7385c),L_(0xa8d22179), + LL(0x92f507ce,0x9137f80a),LL(0xf48fb253,0xcb924115),LL(0x2be56c53,0x0703cdda),L_(0xb4cf511f), LL(0x0b8faa80,0xb73eae3f),LL(0x58a8b927,0xf227ad25),LL(0xdbca2fc4,0x06231927),L_(0x409b12c6), + LL(0x5983f1a8,0xee7ac222),LL(0xf6df6ac6,0x48c69cbf),LL(0xa7dc8e21,0xbd701252),L_(0x6d2da921), LL(0x483083a2,0xc0d30797),LL(0x003aeb7c,0xd4ec2e63),LL(0xbda6fdc0,0x15074c14),L_(0x55d107b3), + LL(0x29e4a336,0x600e1a17),LL(0xd60d3b73,0xa542f637),LL(0x556905e7,0xc7209080),L_(0x3f5144ad), LL(0x0b55b0fe,0xa6cf1f95),LL(0xb8f822b9,0x9d44e115),LL(0x1acfe880,0xe820af09),L_(0x0a84bb85), + LL(0xc0bba383,0x02857752),LL(0x497eb0a9,0x8b30f555),LL(0xf120846d,0xac6401e1),L_(0xf72d6212), LL(0xcb20c291,0x84fbf362),LL(0xa175ab61,0xecddc9da),LL(0xe1839421,0x63952a13),L_(0xbe8f97bb), + LL(0x24f4b136,0xf0524e07),LL(0x8fd9fda0,0x138ee6ed),LL(0x1770de3d,0xedc6985e),L_(0x6c2f8154), LL(0x997ae150,0xb5a50098),LL(0xd64a082c,0x05ed2b30),LL(0xe84702e1,0x4701e013),L_(0xcb1ea5c4), + LL(0xa2d01aa4,0x5c0291c5),LL(0x7cbe7024,0x87f294c6),LL(0xdc575065,0xf7c66733),L_(0x66e96e2a), LL(0x236da943,0xb2bb31c0),LL(0xef556ba5,0xefda656e),LL(0x0d4ba22a,0xd90a6c4a),L_(0xe51714f5), + LL(0xd7b84537,0x6ae52eb4),LL(0x5303af34,0x4989ea91),LL(0x58155fb2,0x51865588),L_(0xff60915f), LL(0xb2f24a3f,0x4a65a557),LL(0x4126452d,0xc5c558ab),LL(0x39d391fe,0x71637238),L_(0x2d627920), + LL(0xc6f1655c,0xda9557a2),LL(0x9f1d5a1c,0xad9724f4),LL(0x02bd8dec,0x286ae065),L_(0xaae19e79), LL(0x66f88629,0x409bbff9),LL(0x02b7c84e,0xa035e3ce),LL(0xfa9ce7d1,0xb11a05b6),L_(0xae613f5a), + LL(0x7d3144d8,0xeeb7e587),LL(0x4daf5c9e,0x63105e87),LL(0x24b31279,0x358ad95d),L_(0x7ca7cd50), LL(0x8b96f130,0xa1f8699a),LL(0x885e7bf5,0x36720d2e),LL(0x19da3cf7,0x0c3e259d),L_(0xbb7ab1a9), + LL(0x3ebef322,0x18a10476),LL(0xd9293d5e,0x93fc7b17),LL(0x2dd5dfa6,0x453f9b19),L_(0xb064e79e), LL(0x2e375ef2,0xde52e14c),LL(0x6557a54b,0xb86d2dac),LL(0xcdf1057b,0x8978f37a),L_(0x60169743), + LL(0x01ae0873,0xf209f351),LL(0xc477ed75,0x1c3d4f63),LL(0xfd2dee37,0x23082359),L_(0x5b85b81c), LL(0x226bc4e5,0xc1dc2c14),LL(0xfac25e9a,0x4a88888c),LL(0xd11ebfc0,0x5bb60dfa),L_(0x6deca182), + LL(0x6d7442e7,0x1a37fe3d),LL(0xceca55fd,0x64b6847e),LL(0x54c71408,0x9321abab),L_(0x42538c89), LL(0x8f6064c2,0x0fe08518),LL(0x0baba2f8,0x48846076),LL(0x18d88b42,0x5027824f),L_(0x9fa6cb27), + LL(0x2fefa18b,0x0a5f6d1a),LL(0x81d4f0b6,0xaeecb1e3),LL(0xe2cc44ed,0x1a3c357a),L_(0xa72825d3), LL(0xe129986d,0x78fb4e9b),LL(0x872596fe,0x6b166a06),LL(0x1f456692,0x55649b1b),L_(0xff6c52c4), + LL(0xbb9f7823,0x0c7e73f7),LL(0x066a275b,0x4c6140bb),LL(0x1d71b6bb,0xc0d4cee9),L_(0x6b9a5b6c), LL(0x8f080a17,0xf403aa8c),LL(0x2c5d59b4,0xb53cebd4),LL(0x45561f5f,0x176891fe),L_(0x7b917d84), + LL(0xffa27853,0x4d6d2499),LL(0xc40d40a1,0xb5248259),LL(0x5a3e6570,0xb7125d0c),L_(0x27a24b64), LL(0x37979bfd,0x785afdfc),LL(0x695b2c23,0x1a4c7732),LL(0xe1b6b02f,0xa84e1866),L_(0x09ceeb7b), + LL(0x11dbcdce,0x4243fd62),LL(0x68c988bf,0x9892ddcf),LL(0xdc0c4d01,0x5638c3c1),L_(0x8f1f8fc8), LL(0xa42313cf,0xfcf531d5),LL(0x5446a19a,0x1417aa25),LL(0x7e0b8323,0x41b2315e),L_(0x8e4521f0), + LL(0xd6c61ac2,0x9d056208),LL(0x63bfbe05,0xa70e6aa2),LL(0x566c60a7,0x483b996a),L_(0x53b69d35), LL(0xa38d32bd,0xc38fefeb),LL(0x27b8ad3b,0x57f15c47),LL(0x689ae7bd,0x3e0d8010),L_(0xfa0d354d), + LL(0x2587df15,0x904f01e9),LL(0x815dc8cc,0xbce7f04f),LL(0x88aa4d08,0xd7f1a354),L_(0x4478e55e), LL(0x5bfae678,0x299925d3),LL(0x661104da,0x6a708cd7),LL(0x74d5a757,0x97968c25),L_(0x8a264b4a), +}, +/* digit=1 base_pwr=2^7 */ +{ + LL(0xd1a6df99,0x084a7e0f),LL(0xce960ef7,0x0b68659c),LL(0xdf5b6590,0xe1cee8dc),L_(0xbb593215), LL(0xf5210072,0xccbda01d),LL(0xb592eea4,0x4c7a3391),LL(0x01bb7a1c,0xa7484df7),L_(0x4b70313b), + LL(0xcb74232c,0xb62e25de),LL(0xb8cba58b,0xc5c8bed0),LL(0xfb8ee6c4,0x4617192d),L_(0x967548ce), LL(0xeaf8b0a4,0xdc2453a5),LL(0x71f81200,0x4d7f2e27),LL(0xf43e697c,0x2e81523e),L_(0x9d94ae94), + LL(0x37eb6d85,0x29543b70),LL(0xc7648cad,0xe67d4661),LL(0xbf221e31,0xde581875),L_(0xded3fb1b), LL(0xc3db2400,0x82bba001),LL(0x656ecd6b,0x60a68af1),LL(0x5e5ccc27,0x619f6149),L_(0xa5bb89fa), + LL(0xe80619b6,0x25f0799b),LL(0xd58585cc,0xeb6dfe0c),LL(0x9bf5f7d0,0x63a366a0),L_(0xff7302b6), LL(0x927212bf,0x02c160de),LL(0xf4586c45,0x09ea0af5),LL(0xfe05e98d,0xbae9ad71),L_(0xc8fc9d86), + LL(0x65b1d33e,0x7f5ed157),LL(0x36faea3e,0x1ed1728d),LL(0x39babd58,0x0137cf58),L_(0x4d9cad56), LL(0x2546cd9c,0xd0dfb090),LL(0x4316891a,0xb59a51ab),LL(0x6476def4,0xc5dce06b),L_(0x7c93323f), + LL(0x2313823a,0x80c0cfc1),LL(0x753f5cf1,0x27734f88),LL(0x587454f5,0xb527a9af),L_(0x315583c4), LL(0x049823f3,0x25a1f7dc),LL(0xd3e3e75f,0xb3ea257d),LL(0x1d11fd76,0xafd0ae51),L_(0x1190d505), + LL(0xc1bc485d,0x407824fd),LL(0x59b8241e,0xa0e87d81),LL(0x71256aba,0x76217f94),L_(0x64a95b3e), LL(0x8b3e508c,0xe501c9b4),LL(0xfbc90f77,0x08a19d4d),LL(0xfb512fa2,0x59ab4cb8),L_(0xc1d78806), + LL(0xe4756697,0xaf2eb7f6),LL(0x05273793,0x5c0e9df7),LL(0xc52db668,0x2b7064bd),L_(0x8eabb5ee), LL(0x43184721,0xd4b9fc59),LL(0x8bf316a9,0x1343040b),LL(0x88ef261a,0xb9864942),L_(0x212e47d7), + LL(0x0f601217,0xc3ce93c3),LL(0x1d875805,0x40d758a5),LL(0xc0aa59c7,0x54ae6327),L_(0x7111e036), LL(0x111b9e3d,0x09cd3a96),LL(0xcc42b514,0x6bcd40ee),LL(0xb04993c8,0xbcda6d48),L_(0x620f7a62), + LL(0xbabee792,0x030c3495),LL(0x74030e51,0xd426f7b4),LL(0x457bca6d,0x81319526),L_(0xf21490eb), LL(0x2498c159,0x0b2bd04a),LL(0x8221d32e,0x12985a92),LL(0xcff74849,0x837d8e0e),L_(0x2ca32bf2), + LL(0x139de2dc,0xf41adf6c),LL(0xef7b6eba,0xb7dc7dc5),LL(0xede2ea87,0x6e2033f0),L_(0x0647be07), LL(0xcd213865,0x287f4ece),LL(0x4d3993a9,0x50f400e9),LL(0x0fc6614f,0x89db6d9e),L_(0x8f95a105), + LL(0xc42a6b84,0x9e9a2ddd),LL(0xeeea986a,0xf3f5ab2d),LL(0xabdd54a4,0xc69f9a88),L_(0xb87d1977), LL(0x8affd663,0xb4602516),LL(0xa2399ce4,0xc75f7a3e),LL(0xfbd56bb7,0xe4aa58aa),L_(0xa1149cb4), + LL(0xbb083ae4,0x96aff3db),LL(0x896df53d,0x2d9b4c87),LL(0x77208838,0x2b1d390f),L_(0x02221513), LL(0x408ee7f5,0xc9a98c1e),LL(0x3460329f,0xb6789b9e),LL(0xf0a9cf2d,0xcc0aecb1),L_(0x14bf88b6), + LL(0xf99e1bc2,0xf9d97ac1),LL(0x32112cbf,0x31242e73),LL(0xe520dfcf,0xba519709),L_(0xb278a649), LL(0xaada88db,0xdf453d98),LL(0x7de50c69,0x48d83f42),LL(0xa35584c3,0x7efe383e),L_(0xafd2f996), + LL(0x18351406,0x987fc6a6),LL(0x33c7e3ed,0xf2b213b9),LL(0x17bc0ecf,0xd5c3d1eb),L_(0xe316f3eb), LL(0xc603801d,0x037728cd),LL(0x0890b2c8,0xc5cf397d),LL(0xde6243a1,0xaf004bfd),L_(0xb5bd010e), + LL(0x81c21907,0x140e4fb4),LL(0x4a85940e,0xb07d29b4),LL(0x65c368fc,0x6829786b),L_(0x11ef4637), LL(0x7c01e8b8,0x5c2ad4ba),LL(0xd4385c66,0x8b692602),LL(0xca528c39,0x09175739),L_(0x8545624f), + LL(0x3e778b36,0x332aa21b),LL(0x69ac9b72,0x7761d7c9),LL(0xf6af5223,0xded7e546),L_(0x2e42f629), LL(0xde909623,0x254a8b2a),LL(0xd20517cf,0x6fa060cc),LL(0x7cccaea0,0x723e3222),L_(0x17b8fcf9), + LL(0x00e54d7f,0x80274626),LL(0xc377f0eb,0xf63104d2),LL(0x448cb4f0,0x86f7822c),L_(0x905f1a28), LL(0x635d1d1a,0x74c9d852),LL(0x03d82ded,0x2f27a18d),LL(0xa7638f56,0x7df0f814),L_(0xa98013e6), + LL(0xe3919fa2,0x11b8e6be),LL(0x71e986fa,0x2038bc38),LL(0x1a7c24cb,0x547f1d30),L_(0xd082b3c8), LL(0x4937319c,0x14498e9f),LL(0x96e06bdf,0xd9e8ae36),LL(0x71231dd7,0x099cc29c),L_(0x52cc6fea), + LL(0xbfa21d6a,0x9934b257),LL(0x1c360412,0x2552b461),LL(0xfad28b1a,0x87244f2d),L_(0xf0f3af7a), LL(0xe091c63c,0x224579d6),LL(0x8b1b9bd5,0x7927774a),LL(0xa4177fae,0x39e5970f),L_(0xfbd55d05), + LL(0xf8a953dc,0x00e1559f),LL(0x1dc11998,0xa70e63b9),LL(0xf8851e82,0x48191bdc),L_(0x7132a05f), LL(0x6d398f42,0xc96682f5),LL(0x3029087f,0xc2927516),LL(0xd7d600fe,0x6435359a),L_(0x103c49c9), + LL(0x43c60bfa,0xbe98cc32),LL(0xdf3dae98,0xe899fd7e),LL(0x6f6a67d4,0x4805ca93),L_(0xb569900e), LL(0x532ddf8e,0xb5f6725b),LL(0x912c5876,0x9818fcef),LL(0xa6151612,0xa9419c51),L_(0xb659688d), + LL(0x544bdd85,0xf568cb9c),LL(0x486d2f59,0xe070e7d2),LL(0xa9680c77,0xf00849de),L_(0xcaecbf55), LL(0xc159fff5,0x9f8b9614),LL(0xff12efb3,0x0503644e),LL(0xf325f0bc,0x58ef4f26),L_(0xc0fb619b), + LL(0xbb5a090c,0x2a905098),LL(0x34e237a4,0xeb89d751),LL(0xb46f0674,0xc23b6e08),L_(0xf504a980), LL(0x84d934a6,0x7446341f),LL(0xfe8d0cb7,0x2d200177),LL(0x428fe6ef,0x663531ec),L_(0x82b91738), + LL(0xf0622227,0xe7d3d99c),LL(0xea4400e4,0x87323665),LL(0x0421f1d4,0xb81113de),L_(0x3c97ee34), LL(0x121ae441,0x14b9bfe5),LL(0xae37e0d9,0xab8ce456),LL(0xfb0b5381,0xeebf8b75),L_(0xd0e53ea8), + LL(0x4ab996fa,0x3bca93de),LL(0x12681ec0,0x9c224825),LL(0x51f0a250,0x4390fa94),L_(0xe12f0e92), LL(0xa17f9bd0,0x87ca94cd),LL(0x707670f5,0x8eb876e3),LL(0x8c10d532,0x6ab8e456),L_(0xad2be3fc), + LL(0x00191032,0xbe58c480),LL(0x20928c0f,0xf0df6b45),LL(0x51d6cd1a,0x3a2b0d2e),L_(0xdae2e721), LL(0x6e0dcc33,0x17ad59a0),LL(0x4848071c,0x24ff8cf7),LL(0xb1342fd7,0x514eda6b),L_(0x8d26ef04), + LL(0xaede35a9,0x43fadb36),LL(0x00e95336,0xda078971),LL(0x89ff847e,0x757ad40d),L_(0xc2d2fb8d), LL(0x063bed05,0xfbec9b9f),LL(0xc9f9426c,0xa2938400),LL(0xed5c65dd,0xd3c116f5),L_(0xcc982965), + LL(0xbf6d76ac,0x4a94b590),LL(0xdd6503fb,0x43e3ebef),LL(0x6d7848f4,0xe0fe0161),L_(0xb547e19d), LL(0x503ad71c,0x14c43727),LL(0xeef3ccce,0xafbcb090),LL(0xbb5f8c82,0x3bf8d893),L_(0x2cff74c5), + LL(0xa2d0d278,0xd8be2204),LL(0x0ccdf937,0xc9fa15ec),LL(0xac17e25a,0x91b10a2f),L_(0x61c0b94e), LL(0x12c8ef80,0x087fa01d),LL(0x1b1a2421,0xb6f728bd),LL(0xd198666a,0xcef80aee),L_(0x76851ee8), + LL(0x6112903d,0x89add916),LL(0xd329af40,0x1c13960f),LL(0xf15aa481,0x48b52034),L_(0x0726b2a7), LL(0x2d1bf701,0xb5d87e2f),LL(0xb0c178da,0xc7e5ba8c),LL(0x6e4a90fb,0xfd04fbda),L_(0xe99dc375), + LL(0xce2f6f2f,0xae50cdc8),LL(0x37383201,0x5c73b50e),LL(0x59a0da00,0x6b833239),L_(0xe9260200), LL(0x54c575fb,0xfdd6dfac),LL(0xea53c24e,0x761a3a3d),LL(0xb3095407,0xca8c1a6e),L_(0x4e4fe43a), + LL(0x56e12b9f,0xa3fc4119),LL(0xfb6450ca,0xf5bdb563),LL(0xe34b58ec,0x178622a7),L_(0xd55ba9dd), LL(0x9e9ffc06,0xfbbaa19e),LL(0x1f5955f9,0x42f09c2b),LL(0xb2d6157b,0x0c83351e),L_(0x325e63cd), + LL(0x623598c2,0xae4a61b7),LL(0xc98d16f5,0x47014b1b),LL(0xddd6a618,0xc1476c47),L_(0x7f025b55), LL(0x7eb38a44,0x31a26c96),LL(0x374db7ac,0xc5ea2b2a),LL(0xa5a136e8,0x13b6043f),L_(0x43d33d2b), + LL(0x07cb2294,0x210180c0),LL(0x173b6efc,0x782987ea),LL(0xab40f28e,0x4a4f4f9e),L_(0xce66440a), LL(0x591b5ef9,0xf6832896),LL(0x49522fda,0x38f56fa2),LL(0x5abb2a56,0x5a65a98b),L_(0x6a059efd), + LL(0xca04bf7c,0x022f4557),LL(0x7a97541a,0x657a19e3),LL(0xc772f98c,0xa19ab123),L_(0x0e388f1a), LL(0x82db0ead,0xd6b0ec00),LL(0x312059b5,0xdeadd9cc),LL(0x9dab24ce,0x1c2e2051),L_(0xc5487b00), + LL(0x7647407b,0x489801b8),LL(0x05173f8e,0x56034023),LL(0x26d5313c,0x29b7a999),L_(0xf53aa77c), LL(0x6f0fc77d,0xfdc7c2f1),LL(0xe7c7d3e1,0x006982c8),LL(0xcb5af1f9,0x9323d960),L_(0x7cb0661a), + LL(0x76954498,0xa4de751e),LL(0xcad7d975,0x6dc87029),LL(0x805eb5f7,0x1cfb5ce3),L_(0x6e5f7742), LL(0x94bbb1b3,0x43b64965),LL(0x3e36f135,0xaf8d3158),LL(0xc4fd0925,0xeb438d66),L_(0x5568e790), + LL(0xc7a170c2,0xb2973b56),LL(0x51fcb9a5,0x9e4dbac9),LL(0x2cb87666,0xcf3bacaf),L_(0xf1a40af8), LL(0xa2effdcf,0x20a60ee8),LL(0x47e2556f,0x60509402),LL(0x676121bd,0x745c0ff2),L_(0x1082eb4f), + LL(0x3407acc6,0xb6d85b13),LL(0xb4a1c32a,0x7e9049e0),LL(0x9fc877ce,0x64c1005f),L_(0x928ec4e2), LL(0xb606ab7c,0xe272e2ce),LL(0xacbb37ae,0x97ac2d38),LL(0x954f3f1f,0xa0e40e6d),L_(0x1630287d), + LL(0xdf2474e8,0x1f05663e),LL(0x7d0f40a6,0x234012a8),LL(0x89989069,0xc2481dbc),L_(0xb865be0e), LL(0xf495b126,0x452948bf),LL(0x27e891c7,0xa43ea9bb),LL(0x280bca9e,0x8a34a29a),L_(0xdb3ca4d6), + LL(0xae198472,0x848b5387),LL(0xa735717b,0xcce778e0),LL(0x4288a820,0x34cf4dad),L_(0xdcd93303), LL(0x9e011fee,0x30c9f97b),LL(0x7df2569f,0xcba3ae4d),LL(0xdb99670d,0x1db11c4c),L_(0xac0ab6d0), + LL(0x9d825f39,0x2980d39c),LL(0x1edad965,0x5a3ddebc),LL(0x9c96ad62,0x7f86e997),L_(0xa6296b18), LL(0xac938f79,0x7a80b2ac),LL(0x8d1c685b,0xe8b1101a),LL(0x055eb004,0x6c8daec0),L_(0xae9ffa1b), + LL(0xcaf9f5b9,0x88ad0652),LL(0x977ba6f8,0x35f6f9f7),LL(0xbced09e3,0x51bdbe8d),L_(0xaf059927), LL(0xd40e66f8,0xa071947a),LL(0xde4b10ab,0x2ee8b51f),LL(0x9757d231,0x4f80de84),L_(0x84da5f77), + LL(0xdf7efaf1,0x3121c652),LL(0xbb4de8a3,0xd7749653),LL(0xb988c422,0x493a2d8b),L_(0x7dd3a0cf), LL(0x98e08451,0x2760de2f),LL(0x05ba148d,0xcf07c50e),LL(0xe5f81246,0x1a00e240),L_(0x89c9fdf9), + LL(0x9d26d17d,0x89b4fc25),LL(0x35eb5721,0xc765d35e),LL(0x45f96752,0xbfefae3b),L_(0x65d4fcd7), LL(0xf9a4089c,0x22ecc154),LL(0x3b66fffb,0x5053964b),LL(0xdcd4205f,0x1e216001),L_(0x9258ce3b), + LL(0x1db56ac0,0x7ae4875c),LL(0xdd9688b4,0x4a976987),LL(0x4fa88f83,0xd67fc048),L_(0xcf37f9f8), LL(0x49b6eedc,0xedcaacaf),LL(0x38ff0886,0xd26b609b),LL(0x29f6f1cc,0xa9ceab78),L_(0x2a5e8359), + LL(0xf6f8a0a2,0x95c6ea4c),LL(0x0080fd45,0x61916ad2),LL(0x8497eb60,0xb0ce6cae),L_(0x75ea62e8), LL(0x50c80949,0xa31d0581),LL(0x9b2a0c1a,0x4cec302b),LL(0x0bfcd85b,0x36484967),L_(0xe5f11201), + LL(0x6e5e0c26,0x6df2fa39),LL(0x59949304,0x248a89e4),LL(0xdcc52026,0x67b816f2),L_(0xc824943c), LL(0xee7ad3ec,0x5bb4e55c),LL(0xfa312fb7,0xdaa70d9e),LL(0xacc63cd9,0x9155d520),L_(0x42aa4030), + LL(0x6abedf03,0x22a83e65),LL(0x2814f9c9,0xb90ac85d),LL(0x088ae4b8,0x65e3e716),L_(0x7975b338), LL(0xf19b0bfc,0xfbebb9d9),LL(0xfd3c7946,0x7355b4aa),LL(0xef331b93,0xfcb3b647),L_(0x9f037b66), + LL(0x4e49fdb8,0x76e1b0d3),LL(0xa7cfa8e6,0x94293ef4),LL(0x588501b4,0xd8359bfc),L_(0x50d236b6), LL(0x3cd45f3b,0xee63deea),LL(0x49004988,0x98af1b2e),LL(0xd1f2806f,0x12a331f8),L_(0xe108a9ab), + LL(0x3577e68c,0x7e2770f6),LL(0x08275599,0xe8913f4b),LL(0x77ead765,0xe027fdcb),L_(0x2d381d9d), LL(0x9a6f6903,0xf459aa5e),LL(0x38d25f4d,0x24bf5d49),LL(0x130316d1,0xd808c825),L_(0x53bfc24b), + LL(0xe048c7d9,0x33437c46),LL(0xce7c4312,0x2ce661a7),LL(0xe77ba9cf,0x46b5165f),L_(0x98d33543), LL(0xaa89fa67,0xd3057aed),LL(0x81116061,0x142332ba),LL(0xb60e8644,0x3eb16842),L_(0x632f4f19), + LL(0x35fc5d9c,0x9f0177bd),LL(0x63fb6870,0x63dcb419),LL(0x4fc638bc,0x0d4a9edd),L_(0x5f4b4b0c), LL(0xd3a1ffcb,0x2be34520),LL(0x4dfd2636,0x6ee7420c),LL(0x449c7ffa,0xca54fb79),L_(0x1723c63b), + LL(0x447c4951,0x07a8fa48),LL(0x5a4bf1f5,0xfe67f509),LL(0x0d70f3ac,0xdbc48919),L_(0xc6e3be9d), LL(0xc5e2455e,0xc9b41ae6),LL(0x1cb83c2d,0x1f329372),LL(0xaab1f6eb,0xa76cbb84),L_(0x13b46361), + LL(0x7f11366d,0xd38d4421),LL(0xd7176b60,0x9815fc31),LL(0x1e6e5fa0,0x42bf5236),L_(0xaf44dc92), LL(0x15c5a009,0x03ac6a2a),LL(0xabc5024d,0x8f3eaace),LL(0x9eb61a43,0x1a7ff3ad),L_(0x67fd7c39), + LL(0xf6ee6118,0x4446a48b),LL(0xd5ff7dbe,0x08776dba),LL(0x62dd1551,0x856288fd),L_(0xf3f982ab), LL(0xb1d08623,0x59e29beb),LL(0x6ab6d270,0xca32b4fc),LL(0x1744a1d3,0xad3745b8),L_(0xd398bc25), + LL(0x3831190b,0xaaeece81),LL(0x93c12ffb,0xd4655489),LL(0x6dc6a194,0xdbb627e1),L_(0xb1087770), LL(0x91571bcc,0xf5fb9008),LL(0x4ad3caf9,0xf421b41e),LL(0xeaac6d91,0x01604108),L_(0xe70c380f), + LL(0xa2f0a872,0x276d7a20),LL(0xdacb5ad6,0xa823fb57),LL(0x507ee8a9,0xe6fef46d),L_(0x8d424c56), LL(0xa385d034,0x2785c811),LL(0x7ba7caa5,0xbcf3686a),LL(0x8ac8344a,0x3bf9ea41),L_(0x63abeaac), + LL(0x8075a441,0xfea1ac4e),LL(0x2be4fe2a,0x0fedea77),LL(0xb3c70edf,0x2398f701),L_(0xbafd9f1f), LL(0xbbbf63ac,0x9c1eb75a),LL(0x06bc9e31,0x9c3a2d57),LL(0xee68eb75,0x4d73d0da),L_(0x5c2caf9e), + LL(0xe663f1d8,0x31f69d33),LL(0x2870e42c,0x46cf68c3),LL(0xc7fa33cc,0xb4e3665a),L_(0x4310b502), LL(0x48f183b7,0x154b0c79),LL(0x225295c9,0x32607f60),LL(0x1e044a43,0xc1030470),L_(0xf5ab45de), + LL(0x25aa9de1,0x88786097),LL(0x8cfe807b,0x045b9699),LL(0x2e64a0a5,0x921c1980),L_(0xaa9a7dc4), LL(0x8b058dee,0xbe46c84c),LL(0x47ac068a,0x5b271860),LL(0xfe16e851,0x48f0acc8),L_(0x76ccb233), + LL(0x31bafd7f,0x7c0c6e0d),LL(0xdade195f,0xe2d4fff8),LL(0x2b1da468,0x95ee5ad6),L_(0xee119e9e), LL(0xfebeb585,0x307f35dd),LL(0xbf55c718,0x406d6f39),LL(0xe2245982,0xd6be6d55),L_(0x7d132e1a), + LL(0x002c4e28,0x4f02beba),LL(0x8d9e9ed0,0xc26d73f0),LL(0x21de614f,0x38b705d3),L_(0x68620b5e), LL(0x23429db7,0xf4967923),LL(0xb79a106a,0x198f9eec),LL(0x9eb6af93,0x6bb259cc),L_(0xec4f9488), +}, +/* digit=2 base_pwr=2^14 */ +{ + LL(0xdcabdf3b,0xd382ee31),LL(0x8d88ff9c,0xeeccf67f),LL(0xe97abee6,0xc6941824),L_(0x90a4b5a6), LL(0x47a31930,0x7f45fc06),LL(0x876a0ffe,0x7b1af995),LL(0x4d9341e8,0x248e916d),L_(0x398b68bc), + LL(0x082378c3,0x4bf3bcae),LL(0x8cfd71b3,0x82c65899),LL(0xb15f6e52,0x5919e8e7),L_(0x2217b0ec), LL(0x6c251213,0xce97fdbe),LL(0xd1051883,0xf8d74874),LL(0x1738524d,0x44e69e4f),L_(0x98671ed4), + LL(0x54e9eb42,0x1bc6447d),LL(0xcb1bcc20,0x65482174),LL(0x63694975,0x72869bff),L_(0x63c463b1), LL(0xf6aea0ba,0xa70d16cd),LL(0x12e9b82e,0xa212780d),LL(0x14730725,0xdc25b909),L_(0x48e6eff8), + LL(0x8d673443,0x01c6af2b),LL(0xce9a229f,0x24e6fbce),LL(0xc6a67d3a,0xbbe5e1ed),L_(0xf65af52d), LL(0x964e75d2,0xb97b0d10),LL(0x8e72295a,0x09007530),LL(0x67a932fe,0xc85f611d),L_(0x7b6da974), + LL(0xfaef942d,0xfc2eb46d),LL(0xc735b7a5,0x51096872),LL(0x75df38bf,0x75ab062b),L_(0x82f7953f), LL(0x1f5151d3,0x587ef818),LL(0x723a33d5,0xf3f93876),LL(0x0eae8822,0x5b5cb708),L_(0x97da4376), + LL(0x36982471,0x165fe970),LL(0x5a5ca19b,0x2ff27508),LL(0x89cd99ad,0x98c66330),L_(0xd0ea6970), LL(0x0397edc8,0xd2a0cfc6),LL(0x49c7caa4,0x7e36813d),LL(0x722feffe,0x829c6b89),L_(0x3cc14e57), + LL(0xe76a6991,0x394ea602),LL(0xb318aa05,0x1348f9f3),LL(0x34e40071,0x3b2e0279),L_(0xa37218ff), LL(0x5da0385d,0x0b77484a),LL(0x487e3215,0xbbb8ff2e),LL(0x7e2ac222,0xf54f007f),L_(0x916f6355), + LL(0x306867f1,0x271f814c),LL(0x45d99845,0x455790c2),LL(0x038f4fe6,0x58008770),L_(0x1a0c7df5), LL(0xa3ffa256,0x2ae5134e),LL(0x791baa3a,0xfa061cdf),LL(0x2bb3a978,0xa4fe1b53),L_(0xd5d1144c), + LL(0x1840dd40,0x24b14e0e),LL(0x8cc62de0,0xc72a3b9b),LL(0x5ca5c5d6,0x8625f308),L_(0x30593cfa), LL(0x6afba385,0x5e8c195d),LL(0xb4f4df35,0x6bdd2d33),LL(0x0975350a,0xeff53d99),L_(0x20a0786d), + LL(0x3fb95973,0xc84c9bda),LL(0xe3fb8d0f,0x172afe39),LL(0xd069e505,0x2d143bfb),L_(0xcaad811f), LL(0xaf5715f5,0x9c2db5f2),LL(0xf0b61247,0x6e7b80b3),LL(0x71ec23d9,0x4f3f9687),L_(0x8dce56a9), + LL(0xf5d591b8,0x0c9c04f2),LL(0x4e3ba616,0x6d31163c),LL(0x530f24db,0x66c42b68),L_(0xefcb7af5), LL(0x1378c67f,0x777097e8),LL(0xf5bcc425,0x3f1062b8),LL(0x9ee5175c,0xb09a9492),L_(0x8ba812ad), + LL(0x12b71604,0x0ee3063d),LL(0xf5bf2d6e,0x22611499),LL(0x853772f7,0x8f349671),L_(0xdf452ffe), LL(0xdd3b39e2,0x3acb7c05),LL(0xa199b0f1,0x34c3e766),LL(0x9381a0b0,0x74081fec),L_(0x613e10dc), + LL(0x49667bc1,0xd57108d0),LL(0x93327b6d,0x6834cfcd),LL(0xf7fb9009,0x9b0baa9c),L_(0x032637ce), LL(0xd797b7f9,0x13c1353f),LL(0x66821e80,0x6f581f7f),LL(0x48a60c42,0x7f9e960b),L_(0xcad0afca), + LL(0x474d3704,0xcfd42398),LL(0xd4011a09,0x1c1a54ac),LL(0x3c4fd36b,0xd3eac930),L_(0xffda655a), LL(0x7c4dc3a4,0xdce7096a),LL(0x75a38366,0x732dfde0),LL(0xa1787513,0xe804b476),L_(0x86101a86), + LL(0x926b6b5d,0xe5f713d5),LL(0x9c17bdda,0x3d019ddd),LL(0xd52c15ec,0x3e7f7e62),L_(0xfaca5ec2), LL(0x6609394f,0x694f2696),LL(0x283219a8,0x69aa76bd),LL(0x07cee438,0x234e3949),L_(0x77c5f3f2), + LL(0x90a49b53,0xf501aeb8),LL(0x8debc123,0xc50fe003),LL(0x8b89e79b,0xa04a6f7a),L_(0x51dcf521), LL(0xff3922de,0xc4ed1911),LL(0xcefa7526,0x0ce76928),LL(0x8af23a3e,0x918974b5),L_(0x3dda3d79), + LL(0xdfd72a80,0xdea21ead),LL(0xbaf90df8,0x8e3f7ba6),LL(0x1f678c3b,0x6df4e74e),L_(0xc2ad132e), LL(0xc5a010e7,0xd7eea56a),LL(0x77bf90b7,0x389d8452),LL(0xc6ed7b9d,0x2e489cfc),L_(0xdd237e98), + LL(0x914f8bfe,0xbcee9591),LL(0x21b5804c,0x7fab5561),LL(0xec5af129,0xd4d265a9),L_(0x7f0919d3), LL(0xc74bfc94,0xd2bab14c),LL(0x1a3e2e12,0xe6b2e9c5),LL(0x77d00d82,0x161eafab),L_(0xccd81779), + LL(0x8fb0ef8d,0x5b2aa48c),LL(0x43630c37,0xe9937cc2),LL(0x00ef4c97,0xb862b86d),L_(0x1ec65b9f), LL(0x97617d09,0xfe0c2928),LL(0x92157b61,0xce44e423),LL(0x625a38ef,0x8594c3af),L_(0xbd404f57), + LL(0x1b735669,0xbbf9ef82),LL(0x29fe66b9,0x754e211b),LL(0xf058688a,0x95864d69),L_(0xdc64d0f5), LL(0x8beee137,0x9150359b),LL(0x0d596fec,0x0ab949fd),LL(0x3f4ac39d,0xf6d5f8ee),L_(0xc65ea695), + LL(0x4aaed3cc,0xb594cda0),LL(0xea397e70,0x0216bf13),LL(0x9e271d0d,0x7efe2b03),L_(0x52fa9e75), LL(0x6a084fdd,0x824376da),LL(0x369bd28d,0x6acd2b86),LL(0x2deabee7,0x55b4713a),L_(0x9706afcf), + LL(0x9b5408d2,0x5ffa275a),LL(0xce057f13,0xfa6d3b63),LL(0x3f3eff6d,0x5bf0abda),L_(0x82fe66a1), LL(0x97b2723a,0xcf4c8232),LL(0x364b69c3,0x170c8de3),LL(0x047d7294,0x43f7fc78),L_(0xec58892f), + LL(0x0b00d0be,0x4d42a1fe),LL(0x3e6453fd,0xc3907782),LL(0xd65498ad,0x716502c0),L_(0x548685f9), LL(0xaa83d0aa,0xd8e4c681),LL(0x30dc30bb,0xb2730e91),LL(0x3b7c8d6f,0xc3d966b3),L_(0x7eb48e5c), + LL(0xfee9984a,0x2e099be3),LL(0x6964c934,0x5f8e6df6),LL(0x31915ae6,0x2ba98b17),L_(0x72598e4b), LL(0xe2f20ab1,0x791aa104),LL(0xe9c53c90,0x2ae23400),LL(0x5c5045ab,0xd646c528),L_(0xf2a49004), + LL(0x50b8339b,0x2874cd90),LL(0x98df361f,0xcb1961a6),LL(0x221ee1b5,0x43f06891),L_(0x6cf88e87), LL(0xf9998039,0xeac42395),LL(0xe0ee202c,0x042a0af4),LL(0x36489fc2,0x5fdad7bc),L_(0xf5be5517), + LL(0x9f01cd49,0xc0ba445f),LL(0x657c4ee9,0x3e5d8712),LL(0xc6107ee1,0xecfad04a),L_(0xc3a9ecc3), LL(0x45f63660,0xeda195e8),LL(0xfd5f4e28,0x2f2caf70),LL(0x4fc9d505,0x0c644ae1),L_(0x49b7af65), + LL(0xbc63e79a,0x658bc0b0),LL(0x98214b9e,0x2713db76),LL(0xabf827dd,0x12824e7f),L_(0xaef5577f), LL(0xb2616195,0xfcdeef4c),LL(0x532de453,0x3fa68909),LL(0xe9395e01,0x42dfc220),L_(0xa3cf44a0), + LL(0xe6bee7b9,0xb1959a03),LL(0xc236089e,0x9b779900),LL(0xe7e57056,0x1c2d553f),L_(0x6e0825c3), LL(0x47995b49,0xab4d653f),LL(0x07e36ef2,0xf8e40f18),LL(0xb70d2132,0xbaae5b9b),L_(0x6545595f), + LL(0x325e475c,0x8ad5b01f),LL(0x55e3fd67,0x8fb55f0b),LL(0xa691b273,0xee832613),L_(0x372805fc), LL(0xb146b4e4,0x748d793c),LL(0xbb8942e4,0x2911a866),LL(0xdb940971,0x24df2ed3),L_(0xc58ee255), + LL(0x25961d65,0x87754320),LL(0xcf82c1fd,0x15d5a2fe),LL(0xee280f81,0xfc4877e3),L_(0xf4f8e2e1), LL(0xd08afabe,0x8dd2825d),LL(0xe83d6d87,0xa36fe3f1),LL(0x20840934,0x398c3272),L_(0xe0445764), + LL(0x51502993,0x5f9bec8a),LL(0x2f38e2ec,0x878f852f),LL(0xbcaa2cbf,0xe99dba0e),L_(0xec7f9cc7), LL(0x7a185dc4,0x7f95d77f),LL(0x0cb71b4c,0x3f419246),LL(0x2b04f2d5,0x7b04c078),L_(0x21ee7511), + LL(0x597ba0a9,0x0eb981ea),LL(0xc63bbafb,0xe6e2623f),LL(0xbfc4dac6,0x35dd20af),L_(0xf02694cb), LL(0xe7b40564,0x8d381cfb),LL(0xb6c06c63,0x4013b9eb),LL(0x354e81ee,0x50a8d84c),L_(0x9e8bae79), + LL(0xccc6dc57,0xe6735e77),LL(0xf38bca55,0x629efebe),LL(0x2ffffa9f,0xc520680b),L_(0xf670ee6a), LL(0x732a53db,0x4d7d1ede),LL(0x920d6d5f,0xa1f8c1a4),LL(0x3dffe6e5,0xc519ac0b),L_(0x927ed8ff), + LL(0xaef46031,0xdd8a57c6),LL(0x3e80aad3,0xb0540672),LL(0x8ef45968,0x7dc6abd9),L_(0x350f562a), LL(0x5aafa6a4,0x60865fae),LL(0x9a3d30f8,0x9c28ce9f),LL(0xd3cb6b76,0xbbb47176),L_(0xcc25a2e4), + LL(0xfe93910d,0x86c3c000),LL(0x6c40ba85,0xe4bdec34),LL(0xa7194bcc,0x308782a6),L_(0x6cf8fd8c), LL(0x710f1669,0x1c395e5f),LL(0x5062f94e,0x2f41d5d8),LL(0xe7981956,0x53f886b7),L_(0x9bf4dd57), + LL(0x6d08786f,0x2cc15260),LL(0xf3a184c4,0x84169281),LL(0xa53ab3f4,0x49111025),L_(0x98552ba1), LL(0x8db73cd0,0x49ee5fc0),LL(0x200da23c,0xeb0a609a),LL(0x26497f34,0x752e2221),L_(0x8eb5b297), + LL(0x23ccf8a8,0xb6e96781),LL(0x4941507a,0x183ac489),LL(0x907018f8,0xf0ef92fc),L_(0x43e3f1dc), LL(0xac3eb093,0x63c56eb0),LL(0x2b3e238d,0xf8deac28),LL(0x95f55a52,0x5ae62b60),L_(0x3671e27c), + LL(0x8575f397,0x643e6356),LL(0x1662edea,0x3b84d8ca),LL(0x87159fb6,0xb1bb3787),L_(0x5efe452b), LL(0x04257ae6,0x76cc23a1),LL(0xb2b2c1b3,0xf70dd339),LL(0xd9298acd,0x91c26db4),L_(0x146fe566), + LL(0xac24fa29,0xa4b011f9),LL(0x59f4d702,0x77f2a9a2),LL(0x897d9044,0x0ed14d52),L_(0x4303ea08), LL(0xa6397973,0xe2308c70),LL(0xa55b4023,0x72030316),LL(0x664a26ca,0x291e9903),L_(0x1def6c61), + LL(0xd3c9cb6b,0x38755541),LL(0xe7d9324b,0x4ad0effa),LL(0x5c237f2b,0x75646bb1),L_(0x298572b4), LL(0xa07ca1d4,0x7f647322),LL(0xdc1aadce,0xe24ec66c),LL(0x819d18b8,0x95c255a0),L_(0xe3f3efff), + LL(0x82098650,0xddb2d835),LL(0x7218b180,0x41d055f3),LL(0x92d42e0f,0xe2f17df9),L_(0x2b71d06b), LL(0xc2c8d2a7,0x061a667a),LL(0xabfafbb4,0xcc790c1c),LL(0x0eb1df27,0x6dc9536e),L_(0x250d65a7), + LL(0xf7ca40a0,0x55a94793),LL(0xe5044ae1,0x6bbc768a),LL(0x1ef210b3,0x166d8931),L_(0xa28dae32), LL(0xa0bcf015,0x621f63a2),LL(0xcd66892d,0xf790fc9c),LL(0x60203dd4,0x667b1fa7),L_(0xdb4559a6), + LL(0x2884e5db,0xc59a883c),LL(0xb096e972,0x47f89d64),LL(0x780aeefd,0xd528d23d),L_(0x8809b35e), LL(0x9052392a,0x6e9ee32f),LL(0x3da64ad7,0xb5fe2f01),LL(0x1d21d327,0x2883e925),L_(0x66ba0553), + LL(0x8d7cbdb7,0x32e5cd9d),LL(0xefaa43d2,0x2385860e),LL(0x43f0f911,0x4b6038f7),L_(0x3c00934e), LL(0x8ece6e05,0x40da7078),LL(0x76e3e8ff,0xa20a6649),LL(0x1a09dbaf,0x709cfd74),L_(0x1f695127), + LL(0xa2ce00d9,0xa63a8b02),LL(0xa213f1e6,0x35cb5edd),LL(0x706b0821,0x4173e4a2),L_(0xb5a5074f), LL(0xaae1c287,0xaa0caca3),LL(0x36399f11,0x3c3b3e24),LL(0x34698533,0xe3b66255),L_(0x8ba6b5aa), + LL(0x4bf57c52,0x164519e7),LL(0x3666d383,0xb55fe2b9),LL(0xd37e29a7,0x68e8549f),L_(0x34e4d0d6), LL(0x9f4b4c9a,0x8f691f6b),LL(0xf4164295,0xa382964d),LL(0x49524978,0x7d3fe7f2),L_(0x64f14bbf), + LL(0xb90d4bd5,0x087b646e),LL(0xe6a8abf6,0x53865f42),LL(0x2d659d4e,0xb9db500d),L_(0xc5eb1e84), LL(0x17597d7b,0x6ae5d43e),LL(0x8df2f6d4,0x3a5e9fe1),LL(0x4204e314,0xd91a271a),L_(0x236e44d2), + LL(0xcfce86ab,0x16c2854c),LL(0x10d4f976,0x3999a9a1),LL(0x5fd18a95,0xa1e55106),L_(0x40835bcf), LL(0xd7192595,0x7c17c721),LL(0x8a484397,0xf6856acd),LL(0xdb82b841,0x39017815),L_(0x2d60844b), + LL(0xf155113e,0xc2b2be30),LL(0xf31e524e,0x1e571838),LL(0xa98b5f59,0x17a7266e),L_(0x169ce88d), LL(0x02e9f20b,0x9c53a705),LL(0x47373259,0x476b9b10),LL(0x144091ad,0x98e56e88),L_(0x2198d3c0), + LL(0x02f6a9c7,0x461d2e37),LL(0xb1b023de,0x6fe1c2f8),LL(0x8835c958,0xaae29f67),L_(0xb8b906ea), LL(0x1573f8b1,0x2aae0885),LL(0x2db13030,0xc9a1230d),LL(0x930776e9,0xd3f32fd7),L_(0x55a855db), + LL(0xdbf89587,0xfeac4726),LL(0x4978e226,0xe907285f),LL(0x084c5773,0xc72ade03),L_(0x25c0e8f3), LL(0x155c7e91,0xe4fb90c2),LL(0x804fb7e0,0x833af299),LL(0x87b3ac91,0xeeb712d2),L_(0xd0aa3910), + LL(0x08fa5176,0xad400dee),LL(0x04db731c,0xdb50d10c),LL(0x8bbf71ad,0x1322cb4e),L_(0xe4d0dedd), LL(0xb7ef36d3,0xa5571f80),LL(0x8b5c198d,0x938aa53f),LL(0x6a106d1c,0xfee7b99f),L_(0xc1056e3d), + LL(0x0d738fbe,0x9340ad37),LL(0xbe6493b7,0x923ef854),LL(0x1a934a84,0xdc9bcb14),L_(0x38e82bd2), LL(0x3ed1d410,0x3e3d69c5),LL(0x2651cbf9,0x8cf302d1),LL(0x60492caf,0xee0ad716),L_(0x0f316e4d), + LL(0x310d3207,0xc40b6b35),LL(0x61d744ad,0xf6b370b9),LL(0xcf2da667,0x4a7e6061),L_(0x06067357), LL(0xd8d48241,0x186ae81f),LL(0x579e8d1a,0x2133c197),LL(0xa42e3f3d,0xf8b9b6ca),L_(0xa88cfea9), + LL(0x9ac56b2b,0x55759656),LL(0xae1ee373,0xd47c70af),LL(0x0f258220,0x06bffc7e),L_(0xe45fbdcd), LL(0x453179da,0x92ffe53d),LL(0x14a22c11,0x2ac0af28),LL(0xb924dbee,0x7afd903c),L_(0x16b2256c), + LL(0x7d2123b4,0x61435520),LL(0x99b497e3,0x2b094144),LL(0xeb4a95b5,0x09b8c6a3),L_(0x83a43e9d), LL(0x54e52455,0x646b89b4),LL(0xa8391c1c,0x2640a632),LL(0x17b930ad,0xa457233d),L_(0xc396f0d7), + LL(0xbfa90c2c,0xfad26494),LL(0xa527afca,0xbfe60268),LL(0xcd907456,0xb3e48eca),L_(0xfa048d0a), LL(0xdf9ab845,0x94fe7551),LL(0x9a3b8a36,0x8ed01907),LL(0x5a97c45a,0x5dbf5641),L_(0x9c8b0d43), + LL(0x9dc2ad9a,0xe9019e0a),LL(0x0599e3f2,0x588acbee),LL(0xfff03f99,0xc48117a2),L_(0x5ebb6635), LL(0x6e713363,0x59d13072),LL(0x42329388,0xc63c7628),LL(0xefa02cb7,0x39d7f934),L_(0xb944b464), + LL(0x5f6d09bb,0x2361ada1),LL(0xfbd96586,0x5419445d),LL(0x6f750612,0xa30fa392),L_(0x9628fd28), LL(0xd59c34bd,0x32785073),LL(0x45fc9890,0x72c99605),LL(0xb431b539,0xeec4de29),L_(0x30b9fd98), + LL(0x97507c27,0x0c5debbb),LL(0x9bcaab04,0x3c42310d),LL(0xa01f4d9e,0x5fdffd07),L_(0x3c6028a2), LL(0x5e2bab3f,0x4ce43e20),LL(0x5cbd1742,0xe71cd8a2),LL(0x0c4858ed,0x8bd12b19),L_(0x2e0122ff), + LL(0xb6380f04,0x59339488),LL(0x3572c4ae,0x920e2111),LL(0x0fbdd870,0xcf927c12),L_(0x44d377fb), LL(0x4ea01a51,0x20ee4123),LL(0xd8592d08,0xeeedf23a),LL(0x65fa7940,0x82b08346),L_(0x605e1aba), + LL(0x34651056,0x1098cb76),LL(0x90c069b0,0xd6a624c1),LL(0x5fd458b6,0xb856ae59),L_(0x95dd191d), LL(0xd687ba3e,0x33a82abc),LL(0xd59abb2e,0xa949d734),LL(0x1de89776,0xc44fd2cc),L_(0x93c93519), + LL(0xc54039f8,0x1ad9c99d),LL(0xcf76892e,0xa0ae59e5),LL(0x5269a308,0x65e4eb8f),L_(0xdc31876c), LL(0xe212c371,0x2c3e1f0e),LL(0x2e889354,0x8869d4e8),LL(0xc88e85fd,0xbc2a9592),L_(0x9c6eb56e), + LL(0x0f4e6e43,0x2bfeb37b),LL(0x46cf4463,0x6bb45b1a),LL(0x53c918ad,0xb8bd0546),L_(0xf78b526a), LL(0x0e33f7bd,0x9e58beb5),LL(0x55fd6204,0x26578e47),LL(0x986f5206,0x90135d8a),L_(0x02f82c46), +}, +/* digit=3 base_pwr=2^21 */ +{ + LL(0x4190a604,0xec5c8b6b),LL(0xaee61346,0x8bca6d9b),LL(0xba9eddb4,0x3ebc0dcc),L_(0xf76451ad), LL(0xa709d0a1,0xc3d3be2f),LL(0x369d1d0a,0xdae0ded6),LL(0xf474acd5,0x965b8988),L_(0x6aaa8ce1), + LL(0xfb05e5ed,0x7df5ec60),LL(0x04a47fd1,0x2d8170fd),LL(0xd08f651c,0xe08fb325),L_(0x56ea78b7), LL(0xa2b2a174,0x20fa30ea),LL(0x02c33226,0xd169c10d),LL(0xc7e20c19,0x366327ee),L_(0xe33001fc), + LL(0xf62aa1be,0xe359773b),LL(0x95f962ee,0x2b782c07),LL(0x31df9439,0x80e166af),L_(0xa27a128a), LL(0xa7a7bd41,0x50ca47c9),LL(0xfce8c109,0x8ed45ebd),LL(0x4a7eebb4,0x03e9fc9d),L_(0x98c4b4f9), + LL(0xaba113fd,0x0e6fb34d),LL(0xf4000e17,0xe2da2a96),LL(0x491a39ca,0x54e2ec96),L_(0xcc021cc8), LL(0x3d0946da,0x6f792b36),LL(0x90fd2002,0xd78ca8ec),LL(0x13094248,0x286898ab),L_(0x477c2d6f), + LL(0xb354ae4d,0xf18c6f77),LL(0xb0291000,0xf6851269),LL(0x7bd039dc,0xfb3809c0),L_(0xf376bad9), LL(0xc99f8945,0x7c71a341),LL(0xf1d99065,0x21f4ed21),LL(0x4c371e86,0xa650cd97),L_(0x1713e005), + LL(0x8e7cfcb1,0xfcae4f5c),LL(0x4c95ab42,0x62196ce2),LL(0xc9a4fa0c,0x83e1de7b),L_(0x9ba799ce), LL(0x8f0bc09b,0xfa78f5d2),LL(0x66a4ac75,0xda32a5ed),LL(0x23d217eb,0xf8df814e),L_(0xb78e1f71), + LL(0x80a1f117,0x670e56db),LL(0xfafc5e68,0xd1c521aa),LL(0xcaa4c48a,0x41b37b7f),L_(0x1023ff48), LL(0xf6421dcf,0xafa1a3e7),LL(0x6e8a0024,0x5c6bc442),LL(0xbc2935cf,0xbe169cc3),L_(0x21e4c2e0), + LL(0xe587615a,0x308bf446),LL(0x71fb47df,0x8047e56a),LL(0xdb6a36f6,0xe8293346),L_(0x5a6836ba), LL(0x93a30fbe,0xcd2f5b41),LL(0x8ffe1e43,0x0b7b259f),LL(0x3d9fe740,0xaafd7816),L_(0xae0c0484), + LL(0xc167cd8e,0x0d3f30f7),LL(0xed56f42b,0x3b140b83),LL(0x6554fb45,0xc105ccc8),L_(0x1a608916), LL(0x69c72228,0xf0450467),LL(0x7e79aa99,0x88e4350a),LL(0x1e0bbd29,0x6f9f2dff),L_(0x8d2ecd98), + LL(0x1e9d015f,0xf4db6e3d),LL(0xc9229b44,0x60df1944),LL(0x91e766b6,0x2499a2cf),L_(0x714cb7d4), LL(0x0468acbf,0x7a3c83da),LL(0x84752dd2,0xfeedfeca),LL(0x95c8fd77,0x9f35aedd),L_(0x1a75bcf8), + LL(0x1d85a175,0xefd882f6),LL(0x0c28af72,0xfcbc0529),LL(0xff17a943,0x6d3cb4e6),L_(0x20b4e7ca), LL(0x1d223312,0x680691e3),LL(0xe8dd8d7e,0x2d7d7412),LL(0x3d6056c3,0xf379f1df),L_(0x82422458), + LL(0x5a2e3386,0x66a60d5f),LL(0x1f8d438d,0x08231783),LL(0x2621fe6f,0x282e92dc),L_(0x8a0f2c3d), LL(0xa53267dd,0x48813229),LL(0xc6a7def2,0x18f63ff8),LL(0x25a10917,0x06fdd515),L_(0x641475d3), + LL(0x866c8a6d,0xb47ff8e8),LL(0xbec1f669,0x360eff22),LL(0x64925640,0x392f59d5),L_(0x2adaf8c7), LL(0x18c35e30,0xe8c753dd),LL(0xb77a997d,0xeef6fc00),LL(0xdf425955,0x3afc5278),L_(0xa7269ca7), + LL(0xedc68cb8,0x69d044d7),LL(0x9eea78e2,0xb3b58151),LL(0x8eb64dda,0x49c378c0),L_(0x9a66415d), LL(0xaf6b16d7,0x47e931cc),LL(0xb92a119a,0xcb7189bc),LL(0xa9051236,0x2aca5249),L_(0x035313dd), + LL(0xad339987,0x9bcc65a5),LL(0x9643d751,0x278964b2),LL(0x7810f1da,0xf8f2be96),L_(0x4bddc049), LL(0x7e983037,0x59fa9f23),LL(0x1f58def7,0xbc86f69d),LL(0x918a9c4a,0xb726eddd),L_(0xdda12d3a), + LL(0xac70d024,0xe4e20984),LL(0x4a8195f8,0x0ffac935),LL(0xcce8d103,0x6efdaa99),L_(0x354553cc), LL(0xea3876da,0xa0b5e29a),LL(0xe8f12ba7,0x65ae7e77),LL(0x9fa645d3,0x93cb4927),L_(0x2a27d9c3), + LL(0xac6cb27c,0x414e945f),LL(0xbed08489,0x73d9e98d),LL(0x4809a03f,0x2d14c85e),L_(0xf63371a1), LL(0x0b05bc28,0x74a3b39b),LL(0x023622e6,0x003b8462),LL(0xed2336e3,0xc6f085ad),L_(0x40dec42a), + LL(0xd9687e2f,0xd82a965c),LL(0xb6bcd68a,0x088401a5),LL(0x068fa075,0x07ba4f19),L_(0xc382c95f), LL(0xf91cec30,0xb6cda991),LL(0xc0579f61,0xa7b1febd),LL(0x50d069b1,0x5d3d8cd6),L_(0xf0f3759a), + LL(0xf8949e75,0x5c71b954),LL(0xcebf4040,0x28006acb),LL(0x6ba62a11,0xe08cb4da),L_(0xef9d9258), LL(0xc4d932f2,0x9059e525),LL(0x9950d8ec,0x72f4258d),LL(0x4cc4c854,0x0a971745),L_(0x1734dd44), + LL(0xdaf48ca3,0xa543ba94),LL(0xfd2fecf6,0xd71707e4),LL(0x809ef386,0xe30d9ba3),L_(0xe5349c3f), LL(0x69eeeae5,0x6910f9ee),LL(0xfcbbeb95,0xe8c90ba5),LL(0x1896385f,0x12c1a610),L_(0xedaaa3d5), + LL(0x2d268c8c,0xd0a57e22),LL(0x90fb174f,0x907afb7b),LL(0x927d9d98,0x4fb8839b),L_(0x60a57b93), LL(0x967900e3,0xa9ff207a),LL(0xb6defcc2,0xee9dbe18),LL(0x1bad27e2,0x37d4f91b),L_(0xababf8bf), + LL(0x6069565c,0x7e61e032),LL(0x6cf9006f,0x1034f977),LL(0xa6921003,0xf41e571f),L_(0x2a44d157), LL(0xeaa8bfa6,0x77a67171),LL(0x3fd9dd59,0xf9f34af4),LL(0xa78106eb,0x7aed89ac),L_(0xa742544d), + LL(0x8c1c931e,0x2befbabd),LL(0xf8ee2ba0,0x7e64aafd),LL(0xb97c5d4d,0xf99509a4),L_(0x621a29df), LL(0x7372eddd,0x47ce48d3),LL(0x35978129,0x28b7f368),LL(0x1fd874f8,0xfdab8a95),L_(0xef2a56ad), + LL(0x7f6337cf,0xe5943606),LL(0x03a9d402,0x21b5b09f),LL(0xa28353d5,0x917b4519),L_(0x77945c21), LL(0xfd5ad005,0x73dbf462),LL(0x9833b4c9,0x7f25c9d4),LL(0x3b50b66b,0x35b3bf78),L_(0x2effa35c), + LL(0x4b668d6c,0xbe5e047a),LL(0x70ba7d5a,0x2bc0144b),LL(0xee508f32,0x9d2116d4),L_(0x64d1a213), LL(0x5d9a5638,0x8ab6e9cc),LL(0x4c4e14fc,0x954172ff),LL(0x7ca23907,0x9fe1053c),L_(0x8104e1b1), + LL(0x711be7f9,0x4c525b55),LL(0x5f99b985,0xac72c62e),LL(0x962efa73,0x92c58056),L_(0xf4fbd970), LL(0xa38c53ee,0x917ebbe6),LL(0xbab078e6,0x6ab0ae35),LL(0x25682606,0x0603c2dc),L_(0x17325a00), + LL(0xb1a2e954,0x22b420c7),LL(0xd56f6402,0xffe309b5),LL(0xda6ba55a,0xdce7859f),L_(0x2da047de), LL(0x96d10a76,0x057f1caa),LL(0x6e8c3c16,0x72ae9f6f),LL(0x8794d9eb,0xab64c20f),L_(0x63b937d3), + LL(0xb289f4d8,0xd9e2a94a),LL(0x0f4cb441,0x4c9fd385),LL(0xecfdb1d1,0x0675dcf1),L_(0x03f2ed02), LL(0xaccd6ef2,0xfad7706e),LL(0xfcfca764,0x0667c6b2),LL(0x7a5f797a,0x2207359c),L_(0x5a7fb514), + LL(0xf3f519e3,0x06628ac7),LL(0x0a0ab6cc,0xe38c99a2),LL(0x86774ade,0x8f775fea),L_(0xfc59c719), LL(0x1bf25ffd,0xf9325842),LL(0xb246d04d,0x34f4502c),LL(0xabcab086,0x064e829c),L_(0x1a866a52), + LL(0x5fefab0c,0x06295d26),LL(0x523fd3f9,0x234674d7),LL(0x9c70b1f8,0x01e05c18),L_(0xd80fb580), LL(0x352749e3,0xee248ea9),LL(0xe2fc4a35,0x3b3c0b4b),LL(0x7556a699,0x4df0080e),L_(0xb60da54c), + LL(0xc8a345b2,0xaf868ebc),LL(0xaaab8ef9,0x9a7fcfbb),LL(0x959c94fa,0xea271ece),L_(0x14c6b171), LL(0x1ea91da9,0x252b7410),LL(0xb76f94ce,0x560e8134),LL(0x8ada4812,0x4d0eaa23),L_(0x48d2e1e9), + LL(0x11e78f97,0x55ff3762),LL(0x52966809,0xa90b8b11),LL(0xb557ab25,0x98bfd175),L_(0x7a838285), LL(0x453f5ec1,0xbd8cc123),LL(0xb8541423,0xe53f50d0),LL(0xaf6d61de,0xb809c27b),L_(0xbc9d881b), + LL(0x22d1e308,0xcafcf6b1),LL(0x3494f12d,0xb5d40ef0),LL(0x602ae873,0xb5bef707),L_(0x8f093526), LL(0x47aa28a1,0xc7e7a44e),LL(0x363aec6d,0x9f424f8c),LL(0x39a88470,0x08171c6a),L_(0xc8475406), + LL(0xd43ff3e7,0x5bfd96fc),LL(0x35837bfc,0xa9d5f891),LL(0xeb92efe6,0x5ac4853d),L_(0x7f7ee96f), LL(0x90443656,0xe8ead180),LL(0xd124bb70,0x84a289e4),LL(0x98bbea4f,0x8bd0878a),L_(0xe0a10a80), + LL(0xd233645b,0x2cec3fe7),LL(0xc6b4e341,0xc6974f7f),LL(0xc7a73902,0x0b481a08),L_(0x8fcafe71), LL(0x9eb32486,0x9b2ec275),LL(0xb1171362,0xdb3bea45),LL(0x0653d374,0xab7f0ce3),L_(0x652219fa), + LL(0x89e007fe,0xa77a41f1),LL(0x14cba611,0x6059351c),LL(0xed2ec819,0x02bfa9e8),L_(0x1e353c31), LL(0xa9065e32,0xd4e23efc),LL(0x243c2ec7,0x9c16b8bc),LL(0x465d2c9d,0xa1b1cda1),L_(0x45e1763a), + LL(0x54df839e,0xb93666fd),LL(0x5820d4be,0x1fed47ac),LL(0x7e8268de,0xbda2efca),L_(0x61307a90), LL(0x428af14d,0x9ee2b07c),LL(0x72170b4f,0xda44c29e),LL(0xfffd22e4,0x296f1761),L_(0xa25a8bfc), + LL(0xb42b17e3,0x6d4c5ddd),LL(0x83cf7f8a,0xabe94b27),LL(0x89be3310,0xde98e510),L_(0x6e879f48), LL(0x9d4ca35f,0x96df2661),LL(0x45c77761,0xb28f2b85),LL(0x96395d9e,0xc8d9fdcf),L_(0xcb9113a6), + LL(0xdbc075c4,0x54d26d6d),LL(0x6dd2d9b4,0x23c171f1),LL(0xca47c96b,0xecedbb06),L_(0xfce5ed3b), LL(0x31539157,0xe9bac065),LL(0x43e31db0,0x552f0920),LL(0xef1cbf3a,0x2cb42440),L_(0x73830d80), + LL(0xed539df2,0xd5c7355c),LL(0x11447b1e,0x5ced43ea),LL(0x10d60144,0x9618c03b),L_(0x6045d427), LL(0x8b9bcb4b,0xe3767fbb),LL(0x4785c2ae,0x2a5c6f77),LL(0x8a009344,0xa23cb6b8),L_(0xaa1eaa93), + LL(0xfd4a0f5a,0x7ea78a85),LL(0x5acc9416,0x258d360d),LL(0x951a2674,0x7b3935b0),L_(0xf2465f38), LL(0x75e447f1,0x80a9bfbf),LL(0x13abd588,0x8cd933d2),LL(0x1c914702,0x8da2914d),L_(0xb5dceca9), + LL(0xbb8f1e8f,0xbb61ba00),LL(0x68589fbd,0x018ee54b),LL(0xf3ed084b,0x9b33e2c5),L_(0x4187a448), LL(0x90c49202,0xdac991d0),LL(0x0adfa0ba,0x06286fbc),LL(0xfa92d2f7,0x8e51716d),L_(0x869552ad), + LL(0xcd0c67a8,0xe3fcc974),LL(0x1fe4efe6,0x4936eae1),LL(0x38aec941,0x49b20db5),L_(0x31b2e360), LL(0x8806a868,0xfd73d3b4),LL(0xf81a57a6,0x8553e67e),LL(0xbb731824,0x5f399b3f),L_(0x063ed190), + LL(0x04dbb079,0xd2ce86a5),LL(0x396d5523,0x636ee6c6),LL(0x5c029f32,0x90ef1fcb),L_(0x8504873f), LL(0x05c18efc,0x812addf4),LL(0x2fdbed7c,0xdf2ff660),LL(0x34c03bb8,0xb1740945),L_(0x56f08b04), + LL(0x18fd7ff8,0x8a416ad5),LL(0xefbbc814,0xb7d2ecb7),LL(0x8226e0af,0xbb5fb220),L_(0x9bdeb90c), LL(0xcaee42bc,0xb76b0d06),LL(0x184432d2,0x31322587),LL(0x678f208f,0xa07b89ea),L_(0x829d1d5b), + LL(0x5899ed85,0x45083585),LL(0x2e43b3ad,0x7217b173),LL(0x04f9e7f1,0x59198da1),L_(0x2293f74e), LL(0x11d6cf0f,0x908d5768),LL(0x06e9468f,0x51f15b45),LL(0x7dd32a0d,0x58045077),L_(0xa2294102), + LL(0x885c6637,0xf7bef8ba),LL(0x74d38792,0x478b8ac8),LL(0x58aa9fce,0x9d21686d),L_(0x503a4ce7), LL(0x541006e4,0xdfc86dcf),LL(0xc2238c04,0xe98f7f2c),LL(0x73e745a7,0xfc620932),L_(0x1dcc2ceb), + LL(0xd49816e3,0x68c388d9),LL(0x697ef53b,0x741de91e),LL(0x3b976a04,0xf24259fb),L_(0x4259cf50), LL(0xcbbf2685,0x56659522),LL(0xe4e3f7fe,0xea31954d),LL(0x43c8b17e,0x3d1de35f),L_(0xa56dc0b1), + LL(0xddd685db,0xa178f2e3),LL(0xf8a89c1c,0x859daa45),LL(0xc3965546,0x65f74f36),L_(0xef984d98), LL(0x31952a51,0xd0b694c6),LL(0x6a5e5ad0,0x4f51b3a2),LL(0x20b2748b,0x54b61458),L_(0xc1437804), + LL(0x91be987f,0x92390774),LL(0x9816ace7,0x31cf372f),LL(0xd8dc53f9,0x490c450f),L_(0xbaf48158), LL(0x604fd793,0xb689243f),LL(0x86f30400,0xb2d8f482),LL(0xdc31ef3b,0x506dd3c6),L_(0x1b18f132), + LL(0x1196c48d,0x6755b53e),LL(0xe39a017a,0x6a0e74ee),LL(0x2da63e64,0xaa8ea0cd),L_(0x7634dff0), LL(0xb013649f,0x1ab0635d),LL(0xbd02ff70,0x9858a79c),LL(0x65938865,0x3acb5b92),L_(0x99e5f181), + LL(0x28b2de14,0x6b120542),LL(0xc4ac30ff,0x5ea493a4),LL(0xbe9b2f46,0xcdd3cbfb),L_(0x0c6270af), LL(0x543265a6,0xf3a605c4),LL(0x83e752d0,0x92bcbe09),LL(0x1d71ae8b,0x4ad0176d),L_(0x6507463d), + LL(0x183493f1,0x3e8ef423),LL(0xc54a293d,0x065effb9),LL(0xa9ccf6fd,0xb0500b2e),L_(0x88529f19), LL(0xfb31da5e,0xe16bd325),LL(0x5014e1e5,0x2bb46b57),LL(0xcdab125c,0x8179b8bc),L_(0xedd40925), + LL(0x54823e46,0x263960f2),LL(0x24b40650,0x21ab8a5f),LL(0x193b2d98,0xb940533d),L_(0x8d0db660), LL(0x7586193d,0x671090ab),LL(0x08db8178,0x216acee5),LL(0x6bb91540,0xcc4fc3a7),L_(0x37f48327), + LL(0x0e69184e,0xe86f6c8e),LL(0xbcf25a98,0xe88688e1),LL(0x9beec95a,0xd008257c),L_(0x3d97d91c), LL(0x35395ef5,0xacddfb2b),LL(0xa6942cd6,0x086efe97),LL(0x8a1a0ad3,0xb4d51fd4),L_(0x59c722f5), + LL(0xd8510369,0xd5dedcbd),LL(0x14ba55bf,0xab06f6a4),LL(0xbd599498,0xc5aa099e),L_(0x69ec087e), LL(0x32f40f7c,0xad93fbe0),LL(0xf1d12a93,0x40b951f1),LL(0xf5751752,0xfc37b6e1),L_(0x0c14e715), + LL(0xaae77beb,0x58b91be1),LL(0x3f7b0006,0x6ad767a4),LL(0x9b47cd71,0x24d37cee),L_(0x3b245f34), LL(0x70ac8b26,0x2da13b60),LL(0x88aafd82,0xbadf18ac),LL(0x62a037c8,0x78224e07),L_(0x8d974011), + LL(0x6a2f2199,0x1578e706),LL(0x8412ecab,0xa273c222),LL(0xe95f128a,0x2b3feceb),L_(0xccb455b8), LL(0x4d1450ab,0x247fea5e),LL(0xc24d8d6f,0xcc56e420),LL(0x32f2d692,0x001d3250),L_(0xf3727734), + LL(0x3d1a2b09,0x1192eb20),LL(0xde270684,0x194cd935),LL(0xcbfbf813,0xe3ba3ce4),L_(0x9c6fa3d5), LL(0x8d6355ce,0x36393a36),LL(0x18945358,0x6d3b3d2c),LL(0x50d98fcf,0x2da52d36),L_(0x23e01cc2), + LL(0xd68d0be3,0x87600722),LL(0xd90cd86e,0x6a898b0e),LL(0x64b1c25c,0xf26df29e),L_(0x5696f04a), LL(0x0562d2ad,0x116fb9cd),LL(0x3440763e,0xadee6e3f),LL(0x19e073f7,0xdcd869ef),L_(0xe748bcdf), + LL(0xd9747843,0x484e4a18),LL(0xd6812dc5,0x2181acfc),LL(0x09d6f90f,0xae25cfad),L_(0xc6209409), LL(0xb6aa9130,0xeb2922c9),LL(0x38ddc5b3,0xbe3728a6),LL(0x3b8ce6be,0x04eb6141),L_(0x3d9bb134), + LL(0x618ad07f,0xc862e8d5),LL(0x69540999,0xca247f9d),LL(0xaa268736,0xbded92f5),L_(0x29192f4b), LL(0x9481e65a,0x42b36d96),LL(0xe3139379,0xabfa2ad1),LL(0xd3f46f02,0x1cbbeccc),L_(0xe59fce03), + LL(0x2b94f0ff,0x608a4b71),LL(0x9cfd64f9,0xdd35cef7),LL(0x236745ba,0xb4d5d169),L_(0xdfa8120d), LL(0x03f0b33b,0x826e0d5f),LL(0xa5992b36,0x31eb9950),LL(0xf2cc0540,0xd954458a),L_(0x66bed66c), + LL(0x2c486c0c,0xa5afc024),LL(0x8a61a33e,0xb063a531),LL(0x38aa1ed3,0x1558aff7),L_(0x09b640f8), LL(0x904e9ed8,0x3494f0b6),LL(0xd2a51717,0x365e3d04),LL(0x0f32df2c,0x5c8f30d5),L_(0xffb044f0), +}, +/* digit=4 base_pwr=2^28 */ +{ + LL(0x6a7ebdd2,0x676d690b),LL(0x5519e7c3,0xf169ac19),LL(0x70ef4a18,0x3fe9e66e),L_(0xd0bcdec7), LL(0x9b515116,0x6b6b0581),LL(0xe52dad64,0xd0e88db1),LL(0x52c4fcf1,0x31c324fa),L_(0x5e6c0907), + LL(0x403677bc,0xe67af8a2),LL(0x3023628a,0x0b4be307),LL(0xdcb51813,0x88ce9bf6),L_(0x9d1c6e56), LL(0x0f788e99,0x8400154f),LL(0xfbca2d36,0x768edb49),LL(0x80428f26,0x277da6c6),L_(0x1b78829a), + LL(0x6933e247,0x8f4bec34),LL(0x96def5c8,0x13b62771),LL(0xc9121c92,0x543662c4),L_(0xf4ea3390), LL(0x1090a59d,0xc62e7c6f),LL(0x4bb3b3cd,0xa38394a7),LL(0x19c57ed5,0x4823e8cf),L_(0xbab65589), + LL(0x61b100d3,0x416f9398),LL(0xaf6ede17,0x8d0f5a47),LL(0x11e5f34b,0xe047da80),L_(0xffc1a9b5), LL(0xc598885b,0x455959c9),LL(0x6cd277fc,0xe69bdd02),LL(0x6bdbe44c,0xd3377883),L_(0x16b926d8), + LL(0xe93c7bab,0x23daaa17),LL(0x8729f3c7,0xcf91e74b),LL(0x64e1431b,0x1ae9e235),L_(0x2e21bb9c), LL(0x2c005910,0x0ba0b46e),LL(0xdccebddd,0x1ee4dc17),LL(0xe61cc51e,0x93805289),L_(0xbc0293c3), + LL(0xa33f496d,0xc65b315e),LL(0x5526e12e,0x25723786),LL(0x2ca2c551,0xc7e943c6),L_(0xea468f5d), LL(0x1845a432,0xb33bb1fe),LL(0x1b868344,0xf5b5a1e6),LL(0xbb41c15a,0xf5bd0a9c),L_(0x65efbcd3), + LL(0xe9864245,0x73ab2381),LL(0xbfa54a0d,0x0ed12b17),LL(0xe3536d47,0x0a040c86),L_(0xfbd5dc3b), LL(0x550f5801,0xa16b2d10),LL(0x96655492,0xd20e3020),LL(0x40239ea3,0x13feb317),L_(0x63a5974e), + LL(0x1220685a,0xd53242c9),LL(0xcca2c5ae,0x1c2921f4),LL(0x765eedc1,0x84f582be),L_(0x7177d048), LL(0xf8de62bf,0xf9eee520),LL(0x22fe2632,0x209f3c9d),LL(0x721633cd,0xc2e9678c),L_(0xada44b67), + LL(0x852acfe9,0x92b626ca),LL(0xa685284e,0xf571ade2),LL(0x918c76fa,0x5b7490f5),L_(0x375ca970), LL(0xdf1662be,0xbb1e6d8b),LL(0x7fd11993,0xd821c744),LL(0x9a06de8a,0xcaec5c2c),L_(0xc7374f40), + LL(0xc1321d2b,0x74538108),LL(0x95469f9e,0x2f1d65e5),LL(0xc8d1c486,0x8ecd7a1e),L_(0x9b0dcc2a), LL(0x3466245b,0x700ed4ab),LL(0xc2bf54a5,0xfa32badf),LL(0xb5a66db1,0xfc4883b2),L_(0x3315b46b), + LL(0x962b479d,0xc4a7efe4),LL(0x6dc8fec6,0xa0d20fc9),LL(0xd0ef4040,0x76eabbd4),L_(0x4ba76aee), LL(0x17a75082,0x4bc6d910),LL(0x75ee3974,0xff0f721d),LL(0x36e896fb,0x6146e5ef),L_(0xc74f818a), + LL(0x6fd30020,0xe508cb13),LL(0x06427fcd,0x80a73390),LL(0xcc02c93c,0x6ad8073c),L_(0x54e00967), LL(0x5f92bcf7,0x8847a6eb),LL(0x9b0cb317,0x758f4aa3),LL(0x40b45a83,0xdb4ada91),L_(0x6bbb2114), + LL(0xfff55c76,0x661c826d),LL(0x3203a031,0xb311e145),LL(0x6bdaa80c,0xcad158e9),L_(0xff7c21ec), LL(0x4502f455,0x239ecee1),LL(0xde88ad58,0x2b344eb2),LL(0x161e1cf8,0x02ce3f80),L_(0x966ad037), + LL(0x0009b91a,0x53d14c44),LL(0xe564666e,0xcbb01019),LL(0xdf767e4c,0xecc4eabb),L_(0x9ba1897c), LL(0x70cf6d6d,0x0ede1159),LL(0x23335d25,0x4162258e),LL(0x5ed679cb,0x5e706cdc),L_(0xf3d53802), + LL(0x33b4ee65,0x78fd4645),LL(0x97cb4549,0xb807ac0a),LL(0x7e760bcf,0x923934bf),L_(0x32edf91e), LL(0xaf2ed833,0x918e957c),LL(0xdbf70f3d,0xdf411692),LL(0xde9c3716,0x2c76553a),L_(0x05dea60b), + LL(0xd3a72d09,0xa5e4f840),LL(0x40f8ed7a,0xd9bcbe82),LL(0xf00706d6,0x986b79c3),L_(0xc2b3b652), LL(0xefb01a69,0xa0bb40d2),LL(0x5b0da5a2,0x2d182973),LL(0x57b4bca1,0x43c566de),L_(0xbed5ccfc), + LL(0x2f1c7c7c,0xfb3c8bb1),LL(0x3a9383ad,0x1addae50),LL(0x29206628,0xa115d8d7),L_(0x4c24fdb4), LL(0xcf3f272d,0xf2a0db00),LL(0x786a47ad,0x1a242dce),LL(0x048ec06d,0xbe72542f),L_(0x384605c4), + LL(0x515f5abb,0x995a0552),LL(0x65750201,0x809459ef),LL(0x2a52fccb,0x4bf08352),L_(0x3914cd0f), LL(0x94c73472,0x507e309b),LL(0xf31b1135,0x006ea75f),LL(0xd3410c08,0xde332d38),L_(0xce581939), + LL(0x0560814a,0x971e9a21),LL(0x69ce7f60,0xcf890a46),LL(0x607c23ca,0x8c2f3995),L_(0x16579c51), LL(0xb8358126,0xc384ccce),LL(0x74485fa6,0x62e3cda6),LL(0x637377fe,0x36145889),L_(0x11e8766a), + LL(0xa7ccaba4,0x66ee0e61),LL(0xd1b8ad50,0x8b52d5b2),LL(0x9b192439,0xe2507e26),L_(0x141991a3), LL(0xf0320f47,0x164afe7b),LL(0xe4e590ae,0xa9cd4bff),LL(0x53be168f,0xbd05717a),L_(0x2141999f), + LL(0x82377242,0x84720302),LL(0x464bed04,0x3e8eab14),LL(0x8131dcb9,0x8dffb402),L_(0x465f6f0a), LL(0xca875370,0x7476d50d),LL(0xb1cc70c5,0x40036a93),LL(0xad40e0b3,0xae5c279a),L_(0x17d24656), + LL(0xce0565d5,0x4590aef4),LL(0x186eb345,0x813e461c),LL(0x4d52d217,0x64b75926),L_(0xdfc17d52), LL(0x51483219,0x4046569c),LL(0x97c10da8,0xbd282e8a),LL(0x394837d5,0x5a6b2c1e),L_(0xe88b3478), + LL(0x58408341,0xa28c5b85),LL(0x1b86b157,0xac9ddd98),LL(0xdf706c18,0x62a72bba),L_(0x814b4431), LL(0x7437fa2d,0xafe0e361),LL(0x79e0c72f,0x29283b53),LL(0x0c099515,0x469c2258),L_(0xe132ed6d), + LL(0x1869604f,0x69cd9356),LL(0x18ebfef9,0x161651d5),LL(0x8a8472c4,0xa23f6947),L_(0x9ee50c4f), LL(0x9ca82d06,0xdd9ffcc5),LL(0x4875708e,0x7c9cfaaf),LL(0x8b227092,0xc52e4c68),L_(0x757b5a90), + LL(0x66b5d594,0x661a0707),LL(0x5bc7f7db,0xf0ed8bfa),LL(0x9f814a89,0x68ff82da),L_(0xcbb5731e), LL(0x54b6136f,0x125a9d0a),LL(0xe936a8d4,0xdbfa6d51),LL(0x0914dd93,0xacae0da7),L_(0x00b1f096), + LL(0x41cc5967,0x8e32f402),LL(0xd57a3568,0x99f4bcb6),LL(0x0ba8496e,0xcbcf93d4),L_(0xcd9a9a5d), LL(0xf2f0154a,0x22877383),LL(0xd00df8ff,0xf270905c),LL(0xfeb2c8a5,0x15d8ffe9),L_(0xa7504f44), + LL(0xc56f7438,0x435cbc99),LL(0x7613f44d,0xedb87fdb),LL(0xc1d19083,0x702066e8),L_(0xeee5d570), LL(0x2c1c4234,0x672ee8b0),LL(0x8a5f8dd8,0xfc342416),LL(0xaa518aba,0x34e2bf87),L_(0x37243c86), + LL(0x3bd53fa0,0x38707713),LL(0x464e00d7,0x6251ddc9),LL(0x4c9a0c1a,0xe7e323fd),L_(0xec2175bf), LL(0xd33612f3,0x93f34e7a),LL(0x840bea94,0x0c42a980),LL(0xdc0b91ab,0x548c92c1),L_(0x978906cc), + LL(0x72ed1d98,0x0de1c184),LL(0xa6f53ca5,0x86904dc7),LL(0x45379ece,0xbe4c089a),L_(0xb3444b1a), LL(0x6d5238af,0xa27b3f88),LL(0x46b2be92,0x21e17b1e),LL(0x122542d6,0xd6e7acc3),L_(0x7853b372), + LL(0x01b419d1,0xdb03ac70),LL(0xd178ee53,0xc5304465),LL(0x5f684940,0x11655587),L_(0x7b9ce700), LL(0x196f70df,0x771ca6aa),LL(0x08b0e5f8,0x4a94022c),LL(0xb69fe2d3,0x076b1dc4),L_(0x70769678), + LL(0xecd18f23,0x225dd231),LL(0x3eefc65b,0x23c21f5b),LL(0x43b63acb,0xf5b2b43c),L_(0x4753caca), LL(0x7ec7a342,0x362a2c90),LL(0x73799a39,0x308c8fcb),LL(0x608d86ad,0x8858eb99),L_(0x64620322), + LL(0x82f0ce09,0x8ffc3544),LL(0xd650c2af,0x1414581c),LL(0xf2cd74da,0x2ab74c29),L_(0x764c59d9), LL(0xd4c61a1c,0x8b9a0584),LL(0x88cdc1bb,0xd7114187),LL(0x7b53c8e6,0x4e91e1e4),L_(0xb898c7df), + LL(0xe472f5b8,0x120a4cb4),LL(0x28eb2abb,0xd29feaef),LL(0xa568a4a5,0x1f0a0815),L_(0x7c56e710), LL(0x52d9147d,0x1dd52d78),LL(0xf3e9a259,0x99e7538b),LL(0x25ad4a06,0x8a35cc7c),L_(0x7ffcc9ae), + LL(0x3daaae36,0x214d493c),LL(0x4a1951b7,0xc0f2cff4),LL(0x5e7107a4,0x46024f37),L_(0xba7c8cd9), LL(0x0f39120c,0xd7f5199d),LL(0x73d5ebf0,0x2dba9f4c),LL(0x2755fd79,0x54915591),L_(0xb315426e), + LL(0xbd4c1fd8,0xbe148855),LL(0x0336e26d,0x7f36ce43),LL(0x41ceba92,0x40c686c2),L_(0x0c8b60cc), LL(0xa2355b30,0xeb937195),LL(0x71e0029a,0xa1f3ab05),LL(0xf7d38672,0x90828e20),L_(0x2f8c50fe), + LL(0x37b7db09,0x4de172b0),LL(0xa962d349,0x3f8b6d31),LL(0x1253fef8,0xc76ebff6),L_(0x83810f07), LL(0xc53e233f,0x9a8ef0b3),LL(0xc3896b5b,0x2d43fb47),LL(0x9a94edf5,0xc8891237),L_(0xabdf75f9), + LL(0xf1704460,0x115d7eb6),LL(0x59c71eb5,0x71666f11),LL(0xdfdf4d27,0xcd09d0bd),L_(0x7aa8753a), LL(0x658ac045,0xe75c6300),LL(0x83c2df96,0xa0de2977),LL(0x5ea75aec,0xd9cc6143),L_(0x8bd0d544), + LL(0x2a662d9e,0xcd959485),LL(0xb69374f3,0x5ee58eff),LL(0x69a1ad5b,0x417599f7),L_(0x81e4947e), LL(0xc5110168,0x471554ab),LL(0x30912d02,0x4e2c7d96),LL(0xa6a4af88,0xe49c13ae),L_(0x0170b29f), + LL(0x0a1a147e,0x23d766f5),LL(0x8108f7f1,0x5446ea57),LL(0x737348f7,0x49f6d997),L_(0xbb23c442), LL(0x17464a0d,0xf5ac023b),LL(0x82c1f632,0x1c89d9f6),LL(0x5a4700e1,0x918b1cd7),L_(0xdb771a09), + LL(0xd9c4d8a6,0xfb136a04),LL(0x7d3d9198,0x627e23b2),LL(0x2a546df5,0x9518b383),L_(0xe5ad50b4), LL(0xe74b275c,0x9e8dd1b3),LL(0x8399ea24,0xb28d50a9),LL(0xc1bf5392,0xf0c4dae3),L_(0x3a885426), + LL(0x60cd114f,0x19f30dd8),LL(0xc7c06793,0x0a04952a),LL(0xa5b0d428,0x9fbf17a2),L_(0xedbaf6ff), LL(0xdc88c750,0x2eaf445d),LL(0xd380c189,0x24d076c7),LL(0xb7cb2b9f,0x4da895c0),L_(0x6670ebaa), + LL(0x296bb0cf,0x1e460fe9),LL(0xb75d30ca,0x0a2b9d5f),LL(0x779ddda6,0x70ad87c8),L_(0xd421a064), LL(0x1216c7eb,0x015e5322),LL(0xd6456e5a,0x08a2c2b4),LL(0x5c4f2da2,0xda0125d8),L_(0x2594bcc2), + LL(0x5cbb2272,0x0e27b02e),LL(0x74c5826f,0x651b4dc0),LL(0xf5b545b4,0x89864ae4),L_(0x81d8295c), LL(0xbfa85081,0x0162c99f),LL(0x1d4b46ac,0xc148b34a),LL(0x39fddb94,0x7de290f5),L_(0x1840e143), + LL(0x8d61f3cb,0xe4f10dce),LL(0x0ac9caca,0xd40a9135),LL(0xdb4a6076,0x869e961b),L_(0x41f3f07b), LL(0xc8ea7a1d,0xaed2c272),LL(0xff4dfc57,0xdd26742f),LL(0x49228bdc,0x196c9b69),L_(0xe6e12a4e), + LL(0x5f4b0d33,0x357d26fc),LL(0x222c05a9,0x8bc3e1fc),LL(0x44a306a1,0x6ebde62d),L_(0x25b23700), LL(0x66c5b1cb,0xc2a2d52f),LL(0x28621234,0x67f40398),LL(0x6a1916f6,0x9eb2b762),L_(0x3b034368), + LL(0x97ae197f,0xe2705942),LL(0x168b8890,0xb717c180),LL(0xfe30cc2e,0x7aa89b4d),L_(0x2c096c3a), LL(0x3d1c1e8c,0x1731a1a7),LL(0x027b4fb0,0x4cdde0b3),LL(0x85e85391,0xab7103b7),L_(0x4bd9bc5f), + LL(0x39f1ba7f,0x21c91792),LL(0xb47bf115,0xd1e29983),LL(0x8102c46e,0xaa0fed15),L_(0x1b4f9e4a), LL(0x1df20d6b,0x659104e2),LL(0x3765c7ea,0xd4f49239),LL(0x3a84be64,0xca582a23),L_(0x0c1bc735), + LL(0xce03f04b,0x827606a4),LL(0x419327d9,0x10bcfdd1),LL(0x277b88b9,0xf2e4c5e4),L_(0xcee78792), LL(0xb9213c6e,0x161c54e8),LL(0xa56d42d6,0x2814c386),LL(0x859e6045,0xac244cf4),L_(0x4647ade8), + LL(0xd6446676,0xab795487),LL(0xe4456665,0x5a242338),LL(0x899b5dad,0x8520bc7b),L_(0x8d6d1eb8), LL(0xa366ee1b,0xc17b463a),LL(0xa3b19828,0xa0af7c16),LL(0xddf53842,0x85b5501f),L_(0x8d208a89), + LL(0xc8d6368a,0xcd7b3fe1),LL(0xd2025e3b,0x124ab94b),LL(0x6971b236,0x961e282f),L_(0xedb43ca7), LL(0xb92ac7ae,0xc76e5b2f),LL(0xdc4501c0,0x8df11605),LL(0x0055901f,0x666181f1),L_(0x80bfc257), + LL(0x96fcbeb9,0x745bf74b),LL(0xd548eabc,0x24675bb4),LL(0x531c5deb,0xff3b4dca),L_(0x0b69ba2e), LL(0xd74deba3,0x97100731),LL(0x585b1341,0xa26f7f21),LL(0xb1b02a6f,0x396cb1a0),L_(0xa9fd8a08), + LL(0xc6165fe1,0xc07709d3),LL(0xe9ce0fc0,0xfdb883bc),LL(0xb1a5a67b,0xfd535ec8),L_(0x8218f85c), LL(0x8234b459,0x45bb7b81),LL(0xc140afa2,0x1f4c2d89),LL(0xa1cee750,0xcf55f516),L_(0xdada8f87), + LL(0x0e3c9ace,0x75c44136),LL(0xf44b034f,0xbe92eabb),LL(0xf4ca1355,0x9e459c32),L_(0xdf9382e9), LL(0x4bc1af9f,0xc06b8bfe),LL(0xe071459b,0xe0b85f75),LL(0x7d557c99,0xff091685),L_(0x408afbfc), + LL(0x90ad8902,0x5513303a),LL(0x21006721,0x9b18a004),LL(0x8286d6c6,0x73c22592),L_(0x41ba22e9), LL(0xf6402ecd,0x2bbee8cd),LL(0xb578647d,0xab06f9cb),LL(0x42089652,0xc4a5e5a0),L_(0xed915521), + LL(0x6925cada,0x6d3b1102),LL(0xc49fffc0,0x2e19a20a),LL(0x1593ba2f,0x8c091708),L_(0x1ec6ed8c), LL(0x711ad8d7,0x1a65086c),LL(0xef09f54a,0xc052325c),LL(0x182117dd,0x865d46f7),L_(0x6f7c505b), + LL(0xfb548314,0x7a6b6eef),LL(0x1dd26e62,0xec447933),LL(0x6a3d4ff3,0x74866913),L_(0x908f5992), LL(0x38316d03,0xb9635b34),LL(0x9f9cb069,0x2db27176),LL(0xac233369,0x567be1c0),L_(0xcafbd98f), + LL(0xcf5edce1,0xa18e3f0f),LL(0xa7d8738b,0x05816a5b),LL(0xa26ca8e1,0x00da101c),L_(0x41646cb9), LL(0xe04bccb8,0xa1f2efbe),LL(0xf3c3eccf,0x67b00a64),LL(0xdd0dbd8b,0xc0be2197),L_(0x534aabd5), + LL(0xe5a39b64,0x0a586a5d),LL(0x398f5b5b,0xe22752b9),LL(0xfc9ab49c,0x72fc1c09),L_(0x8776fb50), LL(0x8b426975,0xd51e5946),LL(0x3da2aa18,0xa79d2b5c),LL(0x8d8169eb,0xe4ca8644),L_(0xcedb668c), + LL(0x923206aa,0xd8894d89),LL(0xc4c6cb55,0x992f9c2f),LL(0xd0679c8b,0x0cde00fd),L_(0x6c539dfb), LL(0xf07baea9,0x3f8e094d),LL(0x5d6f7d74,0x3d3b3315),LL(0xbfbe9e92,0xd269b8cc),L_(0xa2a08cef), + LL(0x88e7f568,0x8dcb5c06),LL(0xb11d1a28,0xc8f6e06b),LL(0xa6e90095,0x905b4a44),L_(0xcca85279), LL(0x63aa3a4f,0x1e51e461),LL(0xe2429d1d,0x5fb4cf42),LL(0x35d139e9,0x8725096b),L_(0x6621d9ac), + LL(0x2005767c,0x95ce3a0f),LL(0x0f37bc40,0xb593a6ec),LL(0x2c5a09aa,0x762f3669),L_(0xfe96bf28), LL(0x52242367,0x88d38ecc),LL(0xe7e051f4,0x759292de),LL(0x8843ff7b,0x041ca14a),L_(0x1e08ac30), + LL(0x0062aa13,0x4bff8a1d),LL(0x40899756,0x28b33bc2),LL(0x966aee37,0xb4b3e7e7),L_(0x7120e524), LL(0x7f31f05b,0xc7be6aaf),LL(0x3e4b1311,0xc2c97f7a),LL(0x7401d050,0x1475b928),L_(0xd263113e), + LL(0x3150b4ab,0xd53ede1b),LL(0xbf73ccc0,0xe427c40d),LL(0xf4e2d20a,0xe5dd8b02),L_(0x2ff70604), LL(0xac4f8ba8,0xaaacf4ec),LL(0xf84c5c8d,0x8e6b2783),LL(0xd9aeb4f2,0x4019cd79),L_(0x4c8f57ec), + LL(0x680b826c,0xc0a2ee02),LL(0xc24d0dcb,0xb25a4e29),LL(0x8b33b701,0x3a2939d0),L_(0xffb21809), LL(0xe6feb01c,0xd1311810),LL(0x603004cf,0xa701c8f2),LL(0xdbcecc81,0xeee95871),L_(0x69de26b2), +}, +/* digit=5 base_pwr=2^35 */ +{ + LL(0xb5c4c69c,0xf507ee25),LL(0xab3e1589,0x454a0f0f),LL(0xf21fe543,0x29d7720a),L_(0xdd2cdf95), LL(0x7c33ec2b,0xb4054a86),LL(0xc7aaaa08,0xdb971594),LL(0x8a74b5b0,0x8850caf4),L_(0xdd2d6666), + LL(0xa04cb663,0xf30acc6a),LL(0x8b4f4dbb,0xd7560ec1),LL(0xb8b6110c,0x4f8fab99),L_(0xc43951e7), LL(0x4308e609,0x2c9d6af5),LL(0x7c9841d9,0xca6486bf),LL(0x64c7b963,0x28ca7953),L_(0x9438ea6a), + LL(0xbcc43cea,0x3055b2de),LL(0xf0288d97,0x68461c5f),LL(0x4caf7c30,0x84c1743c),L_(0x499d304a), LL(0xb5b3a780,0x0e121552),LL(0x50cacc00,0xc38f8d3d),LL(0x6cee1666,0xe3236cdc),L_(0x54f19290), + LL(0x4220e848,0xa785596f),LL(0x4ad330d5,0xfa4258dc),LL(0xf4276ec4,0xfc15e9f1),L_(0x7728478f), LL(0xa58a670e,0x9382335f),LL(0xfea55d50,0x3477647b),LL(0x311f9766,0x4f5dbddc),L_(0xd6c5903a), + LL(0x69933c7c,0x21ea5af6),LL(0x5f27f3cd,0x4b132119),LL(0x12e00aff,0x0ff8497a),L_(0x9216e688), LL(0xb8a8554e,0x7d054f07),LL(0xc58c4de3,0xb896b1fb),LL(0x91dbc7f3,0x6470c920),L_(0xcdac5d1d), + LL(0xc7b39dea,0x93ff36ec),LL(0x7d199372,0xa6f2dcec),LL(0x802aa4a0,0xdbd9b943),L_(0xae6d61fe), LL(0x8c1a0edc,0x7cecf63b),LL(0xfd6604d6,0x54af7ee0),LL(0x78b1b385,0x0498d501),L_(0x57443efb), + LL(0xf34b8647,0xe5ba9123),LL(0x4408fe5c,0xc14ff9dd),LL(0x42cbd03c,0x2891aad9),L_(0x1d5c6bb5), LL(0xf01f7309,0x55808c68),LL(0x50a8d621,0x2ceb5051),LL(0x9d313349,0x2f3b809e),L_(0x28922b09), + LL(0x59881515,0x919ddc75),LL(0xbff9ce4a,0xf87e0baa),LL(0x3037e369,0xa090d36b),L_(0xe32f5ba4), LL(0x579ffa97,0x38e224e4),LL(0x43d0a980,0x2cadda68),LL(0x702d5e89,0x12eff4f2),L_(0x4c7be34a), + LL(0x52239089,0xfabf2649),LL(0x653b3f99,0xe9f6b8df),LL(0xe84977d6,0x3f58519b),L_(0x6dfea3c8), LL(0x4357d0b9,0x6c5351ad),LL(0x2f6d5e66,0x1253d822),LL(0x9524c5cc,0xfbce31d7),L_(0x55b44df1), + LL(0x2e93f071,0xfcee759c),LL(0xe63cea29,0x132e8c42),LL(0x6a329ada,0xec4a7a29),L_(0x3f854cea), LL(0xd5e2b375,0x36a40bf0),LL(0xb7d3f3d0,0x9da99c9f),LL(0x25e16e85,0x7730bda6),L_(0x17380d79), + LL(0x4e15a70e,0x37a376cc),LL(0xcebedfe1,0xad1329bb),LL(0xe14b9f7a,0xac8b6391),L_(0xb426bc37), LL(0xe412693c,0xb1a885d1),LL(0x817a04ef,0xdd7cdcbf),LL(0x06667f09,0xfb4d7bf2),L_(0x9f6db5e5), + LL(0x350411ec,0xc83be0ea),LL(0x021990cf,0xc7612043),LL(0xbb338804,0xfb1e56ce),L_(0x4934fcc4), LL(0x4b75557c,0xfed92eee),LL(0x4d6a1f0e,0xc3259e9d),LL(0x61eea795,0xc28b498a),L_(0x10a35828), + LL(0x7363a98f,0xe21a8af4),LL(0x6f0486ce,0x2ee0c526),LL(0x081ad4e5,0x50ce73f9),L_(0x41a90bde), LL(0xfce29613,0x52824a9e),LL(0xc969520d,0xb689cfc9),LL(0xac6e83b5,0x006e1f4f),L_(0x134a6574), + LL(0xd0a972a9,0xe471b9e4),LL(0x53835085,0xcfd1906d),LL(0xd7accdbc,0x293a4390),L_(0xe0eb82dd), LL(0x86a243d9,0x06c24954),LL(0x443f28e5,0x3453aba8),LL(0x25495810,0x36f891b2),L_(0x86536633), + LL(0xba90affa,0x4d72eeba),LL(0xedf3c972,0x81c31d9c),LL(0xe70f3373,0xa716b2aa),L_(0x26ec6732), LL(0x42ac4253,0x6f657c45),LL(0x636e8421,0x7d074643),LL(0x461026d7,0x0dde683d),L_(0xddec4661), + LL(0x4b805782,0x8dd02690),LL(0xd5dfb670,0x1d04223d),LL(0x83277841,0x7ea96551),L_(0x5fe1e720), LL(0x4c78c04e,0x70dde026),LL(0xa3bb08d2,0xb58c0bf7),LL(0xae645b00,0x3afcf537),L_(0x1f93a66a), + LL(0x708a8084,0x5f7d6f8d),LL(0x3c0562fc,0x141c5fc5),LL(0x61a1cb60,0x78ecbf19),L_(0x8914e2cb), LL(0x4cb03ebd,0x9be1423d),LL(0xad53b1c9,0xd63cb771),LL(0x51acdaa0,0xa32591dd),L_(0x45b4e835), + LL(0x8de09e87,0x76e08928),LL(0xf8aeca8e,0xa653c233),LL(0x59256cc9,0xd8d51507),L_(0x77e6aff7), LL(0x47309995,0x0f159c21),LL(0x9d735f13,0xfe9fe5bb),LL(0x0339c473,0x16784f00),L_(0xa2846dae), + LL(0xf2b37281,0x1cbd8aaf),LL(0x4c543f48,0x8a600a72),LL(0x2324a737,0x644765ee),L_(0xdb3c4503), LL(0xb4dd3d31,0xa23d1c2e),LL(0xe86265b8,0x953388df),LL(0x864110e9,0xe9be065f),L_(0xb52e4596), + LL(0x9c32af39,0x69ee0a06),LL(0x9737e953,0x1fd2a13b),LL(0x38105c26,0xfe12d778),L_(0x620245c1), LL(0xd4a50775,0xd5b96217),LL(0xc8c3c80c,0x0f0582fa),LL(0x9f4dc144,0x87629c9c),L_(0xc6b8bdb2), + LL(0x377dc9b7,0x9e11a84c),LL(0x6df2302d,0x610e3f5b),LL(0x9becf104,0x87cc9a9b),L_(0x9b8f3304), LL(0xbefa56b9,0x89fa53e3),LL(0x7b1cfe6b,0x0b3ed786),LL(0xdb99856d,0x68d6dbd1),L_(0x9d87c161), + LL(0xdd0b49b0,0x7e561904),LL(0xfe908e50,0x3056fb6f),LL(0xab404bf8,0x4911d8a5),L_(0x69dfa8b2), LL(0x91807632,0x606c33cb),LL(0x776c9da6,0x791f57ef),LL(0x525adb32,0x818f0a1f),L_(0xf0db232f), + LL(0x1094f387,0xd1afe50b),LL(0xfdce1f8c,0xab294ef8),LL(0x69998dcc,0xe0d8fa53),L_(0x57be6614), LL(0x6ccabafe,0x64a8c67c),LL(0xf805f10c,0xd4a601a4),LL(0x8082a5ca,0x1c89a181),L_(0x5727dd5a), + LL(0x4855546d,0x6d3c05ab),LL(0x5bddd7e0,0x44996dfa),LL(0x9e6dd61e,0xe5054752),L_(0xb61ac751), LL(0x4c1c7979,0xa7675178),LL(0x4f0ea0a7,0x72b800a3),LL(0x307c1a34,0xafc9ca2a),L_(0xfac51887), + LL(0xf1254532,0x1e52b09c),LL(0x278095e7,0xfc186009),LL(0x579623ed,0x0b5f7250),L_(0x8c426eed), LL(0xa4d79ef8,0xff4c374a),LL(0xe0d3f5d3,0x252cb607),LL(0xf8e76342,0xfcc58682),L_(0xf5c2231c), + LL(0x586d393b,0x480cf461),LL(0x4ae96cad,0x13a215d3),LL(0xe3cf0a14,0x82460da2),L_(0xe34161f4), LL(0x188125b8,0xcd5956cb),LL(0xe0c83545,0x9e63be58),LL(0xbfc652be,0x275a3495),L_(0xc74408a0), + LL(0x965c6e1a,0x0b8b60d7),LL(0xcfd86827,0xd6030340),LL(0xc11f7050,0x4e201a9c),L_(0x3347de21), LL(0xdd1a6a76,0x73f70f06),LL(0xd2c5e44a,0xebc85954),LL(0x11a05e07,0x0cd2e37d),L_(0xa7ea0cdc), + LL(0x7afa362e,0xf7c5f96b),LL(0xce53fd1c,0xfa20c1e3),LL(0x6be4e8e8,0x02b63df7),L_(0xcb0474d1), LL(0x3453fb75,0xf6fdf958),LL(0x30ff85d7,0x502b7475),LL(0xadf32795,0x20557243),L_(0x066b61d1), + LL(0x446cdc62,0x8eb329bf),LL(0xa1b5aa2f,0x369f125e),LL(0x6c894dd3,0x9db7bb62),L_(0x4e250042), LL(0xc4277491,0x31b2dbea),LL(0x4c24c213,0xb650ae0a),LL(0x20fa0957,0x29da364e),L_(0xb22a0abe), + LL(0x3d0c5314,0xaa1e00ca),LL(0x4668311c,0xe23097a6),LL(0x18e7fcd5,0x790fdadc),L_(0x6c84e798), LL(0x00c47191,0xf4068839),LL(0x0925c817,0x5b080743),LL(0x257f4df1,0xd4b97dd1),L_(0x0e714d67), + LL(0x9e9f267a,0x7fa3e72a),LL(0xd9edf53c,0xec547442),LL(0x303f3000,0x74ba5f3a),L_(0x3088e019), LL(0xe130545a,0xf97b4e0b),LL(0xaed0e113,0x7b3e3dc4),LL(0xb3342459,0x849b0cbe),L_(0xa9fbffa7), + LL(0x156bffa4,0xef4fdf72),LL(0x85aca1ed,0x0fb07e25),LL(0x373456aa,0x0c136024),L_(0x3fbc3b2d), LL(0x75063486,0x09872cea),LL(0xed9cc9ba,0x1f75eff6),LL(0x2982d676,0x46918abe),L_(0x638bc02a), + LL(0x62d87802,0x8ac63776),LL(0x0082e1c8,0x3df57bb4),LL(0xfb67a75d,0x872c8f87),L_(0xe6292f25), LL(0x49548c68,0xa4ab6141),LL(0x1ee50877,0x5ae2f1d3),LL(0xccb21fe7,0xcc4c5d51),L_(0x4dd1a7d5), + LL(0x552b1d5b,0xc91b6f0a),LL(0x8cacee59,0x26244e6c),LL(0xebe1c6fb,0xec4bbe5c),L_(0x6a216c08), LL(0x35cfef8d,0x09fa8c0f),LL(0x17b60280,0x77fdabaa),LL(0x4bbc3792,0x94421437),L_(0xb01866d7), + LL(0x820d6809,0x9b55ccda),LL(0x95bebe41,0x1046f37c),LL(0xed3f6fb8,0x07a02e6b),L_(0x5d6bfa33), LL(0x6676830e,0xf82f2f79),LL(0x8ba9b566,0x35492432),LL(0x79d53ab5,0x16a996a8),L_(0x912fe1fa), + LL(0xaa0f7a90,0xe4d29021),LL(0x63d69e6f,0x9b86e6df),LL(0xdb26a514,0xf567f4e0),L_(0xe0d08a4c), LL(0xc1decce6,0x9de6495a),LL(0x037496f1,0xda23fbb5),LL(0x6557417b,0x7d23ff08),L_(0xb80f990a), + LL(0xc3c2aab9,0x2e3254ff),LL(0x0c882e32,0x48576b69),LL(0x2e3a1aff,0x4e27496a),L_(0xa8981080), LL(0x497974dd,0xb0b36f57),LL(0x57530d61,0x1d0467dd),LL(0xbd12d521,0xee061337),L_(0x2a16986e), + LL(0x3a9a2700,0xfa637395),LL(0x08e9776b,0xbc2048f0),LL(0xf8ae9c4f,0x7229d31e),L_(0x5d5cdb49), LL(0xd86d5de3,0xd7e8cbb1),LL(0x7d36c9cc,0xa98c305d),LL(0x382a852f,0x7668edae),L_(0xb66ddb2f), + LL(0x6d33747f,0x6bae97b0),LL(0x258e1f01,0xc0b8420d),LL(0x0d1395e0,0x5d523a37),L_(0x20fd468f), LL(0xf196c7bd,0x940889f2),LL(0x2b93cb81,0xa914e0ea),LL(0xce35713d,0xcb59a392),L_(0x4ff9fc32), + LL(0x984bd24d,0x17b7b322),LL(0xe322bc50,0x33279a91),LL(0xa03ade42,0x3ac696ec),L_(0xa59b7158), LL(0x36f23ecf,0x4faba2b9),LL(0x22a5cf90,0xf70fdee7),LL(0x7bbc4522,0xeb035a5f),L_(0x58a1a1e9), + LL(0x5ddc6b6d,0x150eef02),LL(0x52864a3e,0xdd3f93bb),LL(0x3696d783,0x15012933),L_(0xad3eb1b1), LL(0xff6e69b6,0xc84755b9),LL(0xb7d6ce03,0x118ab913),LL(0x2da1eb13,0x99325702),L_(0x1f352fb1), + LL(0xdfd09cd9,0xd7ddee82),LL(0xfd22eb92,0x93460443),LL(0x87b5bd4a,0x0d5541f4),L_(0xf4336176), LL(0x2e83bcbb,0xd3e283ed),LL(0x6124a0f9,0xe52b803b),LL(0xb28eb570,0x4a8c77d7),L_(0x782341d6), + LL(0x7636205a,0x18df4a69),LL(0xc1129737,0x70a8c000),LL(0xf96be149,0x69d0bc39),L_(0x8091b05b), LL(0x59f09aa5,0x53e28bf7),LL(0xb0469f79,0x3ef52081),LL(0x28ac324e,0xa781c57c),L_(0x10eeaa88), + LL(0xb145dd4e,0xf8de49f2),LL(0xbbb26b41,0x7a359488),LL(0xa5fe71f0,0xea4e5a13),L_(0x0d776617), LL(0x8252a9aa,0x9870bd6d),LL(0x069f0a83,0xd7e75649),LL(0x73608571,0xb0499f6c),L_(0x9dd9cbb8), + LL(0x63626f39,0xee89a981),LL(0xe0aee1b4,0x45b932da),LL(0x25321bbf,0xdd6b2382),L_(0x0c03fd27), LL(0xbd649607,0xdbca6a1d),LL(0x6b8f9b4b,0x1e699d4b),LL(0x940460cb,0x7938144e),L_(0x8c3cb198), + LL(0xa571f0be,0x50d17043),LL(0xcd56a2ea,0x7b24e599),LL(0x15047c8b,0xe06a40d9),L_(0x99dac8b4), LL(0x5bc5aeb7,0xaeb386d4),LL(0xe9f713d9,0x40fabb3f),LL(0x62bdfdf5,0x6aace159),L_(0x8e028ae5), + LL(0xde610cbf,0xf6b35535),LL(0xfe554daa,0xb7d2826a),LL(0xb4edc29d,0x03e1e5e0),L_(0xd38477a9), LL(0x789b199f,0x03331148),LL(0x4a8a863e,0xa966c649),LL(0x0851cfcf,0x1622ec1d),L_(0xfa31d354), + LL(0x888b7c2c,0x07cb3e37),LL(0x660e7e68,0xb017d5a9),LL(0x7f7c933f,0x42119d1d),L_(0x47d400e6), LL(0x5ef83e46,0x0109f6b8),LL(0xbc268020,0x6e139180),LL(0x1b624dea,0xa2bd127f),L_(0xd4e19a66), + LL(0x54ae0fce,0x9a79307a),LL(0x06792812,0x6d342e22),LL(0xb177e174,0x2e3ee119),L_(0x56fea730), LL(0x5e84ad5f,0x08e8f89c),LL(0x12504248,0x425e69c5),LL(0x42b47533,0x0b2e547d),L_(0x0cd14526), + LL(0x041c2bcb,0xd43f468a),LL(0x6c6a96c8,0x497dff29),LL(0x58417877,0x9551c8f0),L_(0x738c007b), LL(0x1e1b3a52,0x7aa44dae),LL(0x4cb0aa92,0x82e3854e),LL(0xe5d6128d,0x2f25adda),L_(0x1565a105), + LL(0x92365b9a,0xdd4e8322),LL(0x332f51e4,0xe083981e),LL(0xbf7947a0,0x5b678747),L_(0x3196029e), LL(0xc98f910a,0x0ca71f21),LL(0x51b450d0,0xe31a901e),LL(0x922f7c66,0xeed6566d),L_(0x1ed09e18), + LL(0x274ea5df,0x52fe1ee1),LL(0xf298e59f,0x7dc25d85),LL(0xd6285877,0xda84cd8b),L_(0x7cf3ae58), LL(0xbb649ac2,0x1e3ba4b5),LL(0xb225291f,0x6f9c137c),LL(0xbd251ef1,0x5e5495d3),L_(0xb7512d10), + LL(0x8392e4dd,0xdc8ee05c),LL(0x9d3efe45,0x4eeeb0da),LL(0x0d91ecaf,0x31e89bf7),L_(0xdc635197), LL(0xeca9047d,0xee9a09ba),LL(0x789d1a79,0x81d64f7e),LL(0xea9e0b50,0xc7b60917),L_(0xb463b663), + LL(0xb48d4d3f,0xb23798db),LL(0xfd959cce,0x4a87382c),LL(0x829e3bb6,0x492aac4a),L_(0x4bf01b8e), LL(0xf58a6464,0x96935f47),LL(0x82b212c6,0x3396e950),LL(0x6d21b8d5,0xe244afe7),L_(0xa642079f), + LL(0x890b338a,0x01b0423f),LL(0x8f95cd41,0x6d8cdb00),LL(0x68218ce9,0x7809fc35),L_(0x1fe627f9), LL(0x446c771b,0xaae3f3c1),LL(0x622ee718,0xfb834953),LL(0x89128662,0xff1c7590),L_(0x2c4b37c2), + LL(0xe1d9d534,0x52f4f30f),LL(0x9215d0dc,0x3a3e06d4),LL(0x6d0d3574,0x9ec8c4a0),L_(0x4abdacfc), LL(0x06630325,0x8d559ed9),LL(0x7bfef54b,0x295b5ede),LL(0xd0a2d07d,0x8d6e5cd0),L_(0xb74df6fa), + LL(0x42c70b2c,0x4f4ae671),LL(0x613fd1c2,0x536e7d64),LL(0xfaa3003d,0x94dc0a21),L_(0xd4e576a1), LL(0x1592950f,0xb4369ba0),LL(0x3179ef67,0x5f932085),LL(0x6309e764,0xe5462315),L_(0x3bcaa778), + LL(0x08fa6e2f,0xec60e2f4),LL(0x2b9b6197,0xa152beaf),LL(0xcc5f8968,0xbce9a53b),L_(0x1ef40db3), LL(0x076de5d9,0x31df6025),LL(0xe8f5bdc2,0xce591c62),LL(0xead89b13,0x52e8a741),L_(0x12358a25), + LL(0x179fcba1,0xc81fc0c7),LL(0x35daa530,0x8eb90798),LL(0xbdb2ded4,0x820ef61d),L_(0x6b0231aa), LL(0x2b8a3cbc,0xf522badb),LL(0x0e482ed6,0x93d7057a),LL(0x0ff17306,0x70098d33),L_(0x63ccaacb), + LL(0x8e019362,0x2f914dd7),LL(0xf4501079,0x2acdf294),LL(0x2848b0db,0x0f138ea9),L_(0xaf353a81), LL(0x4ea1b03a,0x49ae634d),LL(0xd3a8c33b,0x113138a4),LL(0x8ed0557e,0x2b0adbad),L_(0x739b3ce7), + LL(0xb33942af,0x1ecf958e),LL(0x54804872,0xc66d2148),LL(0x1f27ea10,0x011365d7),L_(0x6ce35983), LL(0xc4208dd6,0xb8f4d08e),LL(0x882dc840,0x3e553026),LL(0x29499eb7,0xea028ba1),L_(0xd9859a66), + LL(0xa6f2df8a,0x5bf03737),LL(0x134f5c42,0x924c5819),LL(0xce383c9e,0x910aeacb),L_(0x2daae049), LL(0xbfdc9b59,0xe45c96a9),LL(0x3a5b8130,0x726cada6),LL(0x8177cf88,0xa738df5c),L_(0x9be237a5), + LL(0x21f30c43,0x8cd0ef97),LL(0xfdd4b300,0xe6a63e2d),LL(0xd4df1941,0x57a01e9c),L_(0xf32119bd), LL(0x9c025c37,0xdc96eafb),LL(0x136dc55e,0x95fe2aa2),LL(0xae8f18c9,0x239e5894),L_(0xb671d770), + LL(0x9c68e7cd,0x22874bf5),LL(0xff1a555a,0x64db3073),LL(0x3b1f7071,0xa14665fa),L_(0xad6ab5ea), LL(0x78fc6e69,0x77eb0618),LL(0xa6cf5f0f,0x6d531160),LL(0xf5f0fda1,0x429c094e),L_(0x78109f67), +}, +/* digit=6 base_pwr=2^42 */ +{ + LL(0x570bd76c,0x42617e4e),LL(0x53cb59f9,0xec1fce2c),LL(0xbd807766,0x5098d9d8),L_(0xf56acb00), LL(0x468a4f17,0xada13650),LL(0x8356714e,0xb5aa694d),LL(0x1dce66de,0x5318219a),L_(0x3439525e), + LL(0xd30a5801,0x97115f9f),LL(0x2621a7d4,0xbb10a57f),LL(0xeff5c174,0xadf87884),L_(0x01243ae4), LL(0x162e3c5c,0xa2bc843d),LL(0x6f4a3579,0x25478286),LL(0xd6f94dfb,0x31bb4258),L_(0xa760a06c), + LL(0x6c5c8428,0x46351cc8),LL(0xa082b7e1,0xb964daab),LL(0xdd1d4004,0xc4d0e945),L_(0x3e7f4540), LL(0xb82dabae,0x7d7ac429),LL(0x956426a7,0xeed99c4b),LL(0x7dafa986,0xcbdad15b),L_(0x8d046994), + LL(0xe5e0aad9,0xc7b54b13),LL(0x257de915,0xe9d8af38),LL(0x008e0bc3,0x71a411c5),L_(0x9f3a29a1), LL(0xc482b233,0x07289ac0),LL(0x780d30d5,0x68d763c3),LL(0xa128b566,0xc589940b),L_(0xd834f239), + LL(0x533b21ee,0xb86a434f),LL(0x9be1cf11,0x5f1dadf4),LL(0x5b2f618e,0x35caca2b),L_(0x9da9d5f4), LL(0x74cf7bbd,0xb14dae65),LL(0xa4192a56,0x27c04cc6),LL(0xf5af0266,0xc41f13b5),L_(0x350b4db7), + LL(0x5727ef4c,0x9fcc3538),LL(0x2806003f,0x957682ab),LL(0xe33ed1c3,0x9f83349f),L_(0x02ec97a0), LL(0x5961423d,0x5148178e),LL(0xeab94e36,0x66e2c6e5),LL(0x5986c53b,0xd5c63ac2),L_(0x9b96cae8), + LL(0x9082e762,0x5661867b),LL(0x29ca7816,0x8ece3937),LL(0x30442089,0xeddde973),L_(0xee4b63a6), LL(0x3e2f6790,0xd4f64e91),LL(0xd529fa9b,0x49fdfa45),LL(0x0b104178,0x78b6687a),L_(0x40d1484c), + LL(0x9f724692,0x0ca4bf22),LL(0xb272519e,0x730e0881),LL(0x4bbc9bf5,0x91d1e24a),L_(0xc6e5ce02), LL(0x26de9372,0xd72ae23c),LL(0xc7a7721b,0x6ca80e46),LL(0x75b289b3,0x777ca3a2),L_(0x28a90ef0), + LL(0x7d3fcac7,0xebb7ace4),LL(0xa09641c2,0x48bb32ea),LL(0x0be22833,0x3f76d58e),L_(0x7e7a5d70), LL(0x8e3df32c,0x00f1bf36),LL(0xee4b523d,0x8b204653),LL(0xdaeaa58b,0x3263322d),L_(0xe7975fbd), + LL(0x648b273e,0x2e05e12c),LL(0x0e313d88,0x3a732a3d),LL(0x691aae3b,0x6cd91464),L_(0x8bd52c9b), LL(0x208c6c3c,0xe4c05b8f),LL(0x66fafda4,0xd9e2218d),LL(0x59cd9a06,0x835930df),L_(0xfb01c010), + LL(0xd984c49f,0x888fc640),LL(0x0bbd6a5e,0x9bb00fea),LL(0x4da4ce0e,0xaffa26c5),L_(0xcc14f2af), LL(0x2307b844,0xc6cd9202),LL(0x340af7d9,0x3f8ed768),LL(0x518df91e,0xeadd2347),L_(0x8dc696be), + LL(0xaf9c00ec,0xb90b0248),LL(0x2d2b08b8,0x45a5507d),LL(0x2e1dac5f,0x8db688a8),L_(0x3e2c52bf), LL(0xa655bbf1,0x0fdb8f93),LL(0x95c256dd,0xfdb2b439),LL(0x9751d174,0xaef8bdee),L_(0x54ac1077), + LL(0xb601c37a,0xdaadd78b),LL(0x450b3671,0xb65d4dfa),LL(0xb3e4d63b,0x653e4965),L_(0xf559fd3c), LL(0x8cbfa3ed,0xbaaa17fd),LL(0xcd2af6b1,0xe29a388e),LL(0x50eade40,0x2ec73453),L_(0x0ca27599), + LL(0xbac1435b,0xaa859487),LL(0xc7540522,0xb5b2445b),LL(0xe22a73a2,0xaa1116ed),L_(0x2e7ed6df), LL(0xf9d72a86,0x616cb03b),LL(0x61a4a6e7,0xcdf54ee7),LL(0x4cf9a426,0xe0208859),L_(0xc62b0ac4), + LL(0x5300262d,0x7faf0467),LL(0xc2571f4f,0xff47f116),LL(0x93b14cbc,0x484a66c2),L_(0xf8b658b8), LL(0x654db6ca,0x20220d13),LL(0xfcb07e76,0x1162cfde),LL(0x897e3ec2,0xf29d6809),L_(0x6eee73ae), + LL(0x2c67eef1,0x1a833a88),LL(0x40f7ac97,0x8aa0f2d7),LL(0x5fc1c69f,0x9f06aae9),L_(0x08b7e77d), LL(0x4ecfeaa6,0x17fda35e),LL(0xeac8ca12,0x338ff3df),LL(0x0013029b,0xe6215b79),L_(0xd490a9e5), + LL(0x45530708,0x3d6ab800),LL(0xe7c57017,0x34dca330),LL(0x5aa02638,0x4dc086c8),L_(0xba336129), LL(0x6df633bc,0x90bbb8d8),LL(0x33ca4c46,0xc7c28c06),LL(0x8dcb3bae,0xa0c24314),L_(0xa41cf732), + LL(0x7f227cd0,0x8cd51cfe),LL(0xb7fcfdc2,0x68ea58e2),LL(0x9f7bcc04,0x3003cc72),L_(0xd4b488a1), LL(0x5b982b6b,0xd5ebd68b),LL(0x4020c3e7,0x675b50df),LL(0x9679336c,0xa8fee552),L_(0x24805e44), + LL(0xe51e0a9f,0x75eb0c92),LL(0x760831bb,0x9af943f7),LL(0xa54c748c,0x28a759fb),L_(0xe246d8ba), LL(0x1cea2c6e,0xb0384781),LL(0x2f1568a6,0xf0f73ecd),LL(0xb65d1ecc,0xd26a77df),L_(0xa639e1e0), + LL(0xcb23a542,0x51dd59db),LL(0xac405e3b,0x24f458a4),LL(0x7d0b3dda,0x26b341e1),L_(0x9072bcaf), LL(0x80d2e583,0x9e2fd334),LL(0xd09edd03,0x114215cc),LL(0x794f6e44,0xe3bb54b5),L_(0x4abbf55b), + LL(0x01429cdd,0x7fb2c053),LL(0xaaeddc51,0xee0b3bcc),LL(0xcf236537,0xca6a0781),L_(0xee610794), LL(0x28ee066f,0xe18e5f40),LL(0xb59956df,0xb1e0ccfc),LL(0x2a9ed4ef,0xa109a3af),L_(0x628906f4), + LL(0xad211ace,0xe621f731),LL(0x99a069f0,0x072030c8),LL(0xa71de5a1,0x106812c7),L_(0x606b3758), LL(0xeac94530,0x4ce2ef8a),LL(0x57357177,0xac163954),LL(0x778bc2dd,0x2e5cbdab),L_(0xa82c012b), + LL(0x0baf79a3,0x9c81a4be),LL(0x4fc50828,0x9363638d),LL(0x8a4d69e0,0x687f0dee),L_(0x92f9ddc4), LL(0xa6d3323d,0x202ed4a9),LL(0x123a8f24,0x1c483cb2),LL(0x5bbe8c1a,0x433b79ed),L_(0x23111e9a), + LL(0x3828dbf8,0xb8a0c6af),LL(0x43cd4321,0x9f12e96d),LL(0xdd7d6cea,0xe595dcab),L_(0xd3b3c998), LL(0xad54b44c,0xe8aa36bb),LL(0x142da061,0x11dcc1c4),LL(0xcbe63415,0xeff9d401),L_(0xa4d738ce), + LL(0xfef9f39f,0x1d099df3),LL(0x769dfb43,0xbf9c0426),LL(0xe387610f,0x0cce0331),L_(0xd6feb0f4), LL(0x31cb09c5,0xd62d1375),LL(0x10527627,0x53290cd4),LL(0xa90e25d2,0xf1396054),L_(0x6a0d6915), + LL(0xf603ca7f,0xe57e3a51),LL(0x26b3d6ba,0x547b9c97),LL(0x5234c386,0x44edaf6d),L_(0x7c4a6d8f), LL(0xcea690d7,0xf13946cc),LL(0x4a083ed0,0x6ad6bb4e),LL(0x9374003a,0x36c2bacd),L_(0x90ccdacc), + LL(0x341c30ae,0x7e1c2c9b),LL(0x313b286c,0x17e56dfd),LL(0xb65db139,0x9888703d),L_(0x65b2fe62), LL(0xe07d7043,0x3e36f84d),LL(0x6fc2a51e,0xb4b9c74c),LL(0xbbd020f9,0xed1bc384),L_(0xb260d341), + LL(0x4432f2d0,0xa3a488e9),LL(0xf4caef39,0x9efd00d6),LL(0xd17c4829,0xf5128936),L_(0xf742f93b), LL(0x35e93b49,0xae41e05a),LL(0xa5eb9e98,0xe030a464),LL(0x41a1010a,0x1db1bce3),L_(0x7cabde79), + LL(0x6fb1c1bf,0xfe5cfb57),LL(0x304db3f7,0x401be370),LL(0x29b356b7,0xef6ca52e),L_(0x16934044), LL(0x131c52a9,0x3084c2e8),LL(0xb1a56ede,0x58a36c5a),LL(0x8cfd7a22,0xa076e835),L_(0xe8967b86), + LL(0x74382b8c,0xecf54e6c),LL(0xe7d202a5,0x80a6564e),LL(0x3378864a,0xf29ac0df),L_(0x3af276ae), LL(0x9549b955,0x71036c3c),LL(0x85bde008,0xd3203c72),LL(0x57b0b3ec,0x7ee244a8),L_(0x7831f44b), + LL(0x2a2ae111,0xe00edfa7),LL(0x8b506f33,0x6b68f39e),LL(0x8f5215f7,0x0b132723),L_(0x36ee465c), LL(0xe7d50419,0x85673786),LL(0x4b253aad,0x231c0709),LL(0x487f22bb,0xf5e2a237),L_(0x8af08593), + LL(0x95692ad3,0x0b27bb26),LL(0xa14fcdb7,0x090be6f5),LL(0x8b45b55f,0xea84dd7c),L_(0xd1971d3e), LL(0x928497fb,0x971d5f28),LL(0x9e1b8d56,0x6339a103),LL(0x9ddbd5c4,0x3fe08c7f),L_(0x71eef4d8), + LL(0x987de693,0x1683a455),LL(0xca6c2d90,0xb38e1de8),LL(0xdd0a3684,0xf01af5d9),L_(0x2403e538), LL(0x86ab28a1,0xd4b30cec),LL(0x533a55fa,0x22c7c598),LL(0x01cadc9e,0xb5dd36ac),L_(0xe6dc51f3), + LL(0x8baf2809,0x60cc335f),LL(0x1ed24f3e,0xa633db28),LL(0x732a899d,0x7f9cd569),L_(0x5d8b2c23), LL(0x04bce2d6,0x1f59a0d7),LL(0x6ef81d6c,0x6d10e528),LL(0xcbb166ea,0x7fe10619),L_(0x1eb94857), + LL(0x04d81b40,0x88a7293b),LL(0x3d8447b9,0x1732c2f0),LL(0x057b8676,0x320d8861),L_(0x5a9e4e63), LL(0x5bfbc591,0x3e5d907e),LL(0xa66f2cce,0x2b35a3fe),LL(0x1597d44b,0x7605acfa),L_(0x756ca23d), + LL(0x6112f38f,0xf5ab47b4),LL(0xf577db42,0x5984ae06),LL(0x4fccb7e8,0x81972b3a),L_(0x1d854210), LL(0x5d4f964c,0x905ded37),LL(0xf605f38c,0x6a31fa68),LL(0xfb6ad50f,0xd83dca88),L_(0x6aacdbc7), + LL(0x1b0ac423,0x711dde1a),LL(0x227d6127,0xb5e309b2),LL(0xac0aec46,0x17ee236d),L_(0x70e64775), LL(0x600531c3,0xce093e55),LL(0x458395de,0xec04dd4e),LL(0x59639b52,0xb9e01d45),L_(0xa8e6469e), + LL(0x1b94ace7,0xb0fee2ec),LL(0x08d97fb0,0x5c0b8f2f),LL(0xdfd59ee2,0x6a154d90),L_(0x35f79449), LL(0x8fb75d5a,0xb692d5e7),LL(0x094a540a,0x080f7773),LL(0x1fbd50fb,0xa4f8f9e4),L_(0xb9d1eb94), + LL(0xf63f6da8,0x2aa45a5e),LL(0x711d55a4,0x2d7d0b41),LL(0x29c1bc69,0x8aabebdc),L_(0x8480eff7), LL(0xb0063dbf,0xc38e3c41),LL(0xe276eaf6,0x661ba0dc),LL(0x99541913,0xc19809da),L_(0x50e215d3), + LL(0xff252d36,0xa1530a6c),LL(0x253d53ef,0xc8e9b570),LL(0x9793a371,0x3489107c),L_(0x8abf5783), LL(0xf0b49c6d,0x879022b6),LL(0x12bdba9e,0x069dd468),LL(0x2c618b82,0x64bde16d),L_(0x2306b3be), + LL(0x2d08df95,0xed7d7c9a),LL(0xd4d38ca9,0xe80a7f84),LL(0x357baf28,0xbb968f21),L_(0xbcca4e7e), LL(0x8315da93,0x96e91923),LL(0x4f08013c,0x4e306972),LL(0xc5ed2a12,0x950bbe41),L_(0x434c75ba), + LL(0x39668cb6,0x077167b6),LL(0x7bdd93d3,0xfce255b9),LL(0xb37bc6b8,0xf3809a3f),L_(0x32c36f4d), LL(0x7f61816e,0x44d57109),LL(0x06f0654c,0xb19cf5fd),LL(0xdb202875,0x42100d63),L_(0x79f51335), + LL(0xaf246d2a,0x7f3965a6),LL(0x8caa84d7,0x8d8e3137),LL(0x26bde524,0x11b1a769),L_(0xa5eaa311), LL(0xd87dfaee,0x707808be),LL(0x69540405,0x04bb89d0),LL(0xe52cbe87,0x7ec2d88f),L_(0x994f86d5), + LL(0x5423908f,0x43d7285e),LL(0x85d0501d,0x49363917),LL(0x6a49fc82,0xf5d8d60b),L_(0x2126dd81), LL(0xa0f34346,0x665a2267),LL(0x1fa53f15,0x1ac20d97),LL(0xffa2e5fc,0x4e6d33c1),L_(0xf9840551), + LL(0x9731dc20,0xf1f7a37e),LL(0xc0130bbb,0x69d32743),LL(0xea51b61d,0x05851633),L_(0xaa72b2e1), LL(0x04e8d8bb,0x1c8bd021),LL(0x4806ed2e,0xef76ca45),LL(0xf099b725,0xd230047c),L_(0x5f4e19c3), + LL(0x44613937,0x62171491),LL(0xf583d82e,0xa07a7b6d),LL(0x9015ad40,0x306c9555),L_(0x0b81ff7a), LL(0x18925a9e,0xaac18583),LL(0xa0946d46,0x7d220576),LL(0xbbd4708e,0xf151aaec),L_(0xe99b984f), + LL(0x6e04c9ed,0xb57b3b22),LL(0x3cdad4a9,0xa3593866),LL(0xa01b71df,0xa63bab57),L_(0x97f85c63), LL(0x773f947c,0xefc9bc76),LL(0x1a1f56a4,0xcb328f94),LL(0xe12b780c,0xb068b3ce),L_(0xc8733217), + LL(0xc1916a8a,0x62555b0b),LL(0xe906cdca,0x00203baf),LL(0x82d7d36f,0xd8764be5),L_(0xc4064873), LL(0xf4469260,0xa23e8076),LL(0x7f6613c6,0xb903dea6),LL(0x11610026,0xd83fceb2),L_(0x6e5bcf50), + LL(0x2739ed0b,0xcff10abf),LL(0xcaa11cd8,0xe0b269eb),LL(0x92761d90,0xc1c0ca0e),L_(0x70aa2955), LL(0xab5ce41e,0x62aaaef4),LL(0xc2c0d2af,0x5a3ff0d9),LL(0x3aa250ea,0x8f10b784),L_(0xdbfc2028), + LL(0xe5bbf62d,0xa53f3f3f),LL(0x5bd69524,0x27dd1951),LL(0xeada36e1,0x40a88ecc),L_(0xd04364be), LL(0xca0a31a4,0xd318529b),LL(0x5b3c2cf3,0xefec04d1),LL(0x49d3e4dd,0x55c20eb0),L_(0x7153c7d3), + LL(0xc5f830cf,0xbf310209),LL(0xbaeecda6,0x1372fe7c),LL(0xab6a0dc0,0xaf6004cc),L_(0xabcb8c97), LL(0x8803af61,0xa6088f51),LL(0xf7850d91,0x53f144ac),LL(0xe77f4280,0xd7d06ab8),L_(0x9a5d8d81), + LL(0xc4969a0e,0xdf19cc2f),LL(0x433da709,0x8bd7557f),LL(0x554a3a06,0x8fe8b8dc),L_(0x687d6a23), LL(0xf261d773,0x82e07bc5),LL(0x9e80d756,0xd1d7da5d),LL(0x45447ad3,0x19044418),L_(0xae95e54a), + LL(0x3956922f,0xf66675c8),LL(0xde2dc4b9,0x20469977),LL(0xf5f39465,0x011863a2),L_(0x1e9807dc), LL(0x960a1dab,0x66b9d7bb),LL(0xdbd5a655,0x074a85ef),LL(0xd9f9bf2e,0x7dd3b230),L_(0x50a9e91b), + LL(0xe5be9e2b,0xb5995728),LL(0x0640124a,0xa127aac9),LL(0x23c8cef0,0xf11df0db),L_(0xb1a238e2), LL(0xefcf6a98,0x38cfdd79),LL(0x78034f01,0x899c799e),LL(0x8c265685,0x7cab4cd9),L_(0x1b6b2132), + LL(0xe6160917,0x480a36fd),LL(0xe17a372a,0x3f7c1b1c),LL(0x91f84a8c,0x85381912),L_(0x202d4232), LL(0xb7408da9,0xe263f58c),LL(0xd1c14892,0x8ca85524),LL(0x8c2f9aa1,0x687fc42f),L_(0xebb9ceb8), + LL(0xf5f78e42,0x3455a3e9),LL(0xbbc51854,0x30c1c2c6),LL(0xddf065a7,0x3692f51b),L_(0x5794f41d), LL(0x0f5906c1,0xbfc2af37),LL(0x3df049a3,0x5fa05ed1),LL(0xd9f88327,0xfad22122),L_(0x143991c0), + LL(0xcbee3325,0xe6fcf3f6),LL(0x29ff58e0,0xc3e92fcb),LL(0x7c43be45,0x6def0ea9),L_(0x95d4294c), LL(0x72baebe1,0xabf2c782),LL(0x8f7dbb1b,0xff1c5bf6),LL(0x21f7b8ae,0xcada1649),L_(0x1d86e3b2), + LL(0x2e618a15,0xe44e287b),LL(0xc0ea1a7b,0x9ec08fdf),LL(0x3cbeeaa0,0x41378416),L_(0x5dfb49d7), LL(0x3defdbe4,0xdd8dc723),LL(0x4d7ec600,0x6d23302b),LL(0xf1849878,0x922ac03f),L_(0x9a57ab5a), + LL(0xf4361243,0x5150fa93),LL(0x3ea14eaa,0x1bf1d7e3),LL(0x0106a9fc,0x90827c46),L_(0x7d96ff3f), LL(0xd4951e8a,0x046acfdb),LL(0xa6461b44,0x38e792fd),LL(0x2d8ca425,0x07e228cc),L_(0x4ba3f6b1), + LL(0x889c6c45,0x12d9fd78),LL(0xf4406adb,0xa6aed947),LL(0x46f4af45,0x4de1be3f),L_(0xd4630c28), LL(0x932b6858,0x4b284bc1),LL(0xcbab5b0d,0xe27e82bb),LL(0x9200852f,0xe41775aa),L_(0xdd624131), + LL(0x50a8e4b8,0x9d917e78),LL(0x558110ca,0x4ac6dc2a),LL(0xeb63b95b,0x585b0c05),L_(0x89d42790), LL(0x876d7f22,0xdd6e7325),LL(0xb4e2f682,0x34a78682),LL(0x55d49e0e,0x7de26ccf),L_(0x076914a6), + LL(0xf3430044,0x09139313),LL(0x6fe59fdd,0x32e29482),LL(0x9f0a6227,0x1c584d56),L_(0xffe716b6), LL(0x11cca786,0x53203116),LL(0x82480098,0xb1c8440a),LL(0x0ec04b4a,0xb4fd311a),L_(0xb256043e), + LL(0x4a367cf1,0x82ea7247),LL(0x8fd0c543,0x35a8f8e4),LL(0xee0c8d61,0xeb47eaf0),L_(0xb1c6b367), LL(0x7fc38517,0xb4361b1e),LL(0xa69d501d,0x24e2fb10),LL(0x94b8860e,0x1e4ac934),L_(0x473c4fc7), + LL(0x9c7f7bc3,0x85016181),LL(0xa46af46a,0xae2e08c9),LL(0x1d49bd53,0xd51d0f76),L_(0x47c1a7de), LL(0x574b1fa3,0x275045e3),LL(0x2b7d8406,0xe63f9064),LL(0xb270bab6,0xcbacaf10),L_(0x1fd8fd5b), +}, +/* digit=7 base_pwr=2^49 */ +{ + LL(0x55cc3b94,0x81366649),LL(0xc85bd06b,0x0bb5529d),LL(0x66b83a45,0x020a3d7b),L_(0xd7360ab5), LL(0x6d9c718e,0x4c39583c),LL(0xf32587a2,0x063ccb66),LL(0x8cb7eb45,0x01328b11),L_(0x7b390466), + LL(0x7e06eeca,0x2a100811),LL(0x1e68642b,0xf4997f3a),LL(0xf5c07857,0xad98c158),L_(0x3c2d33de), LL(0xf408207e,0xdb7d94f4),LL(0xe7bd848f,0x6379ef09),LL(0xf3bfa4da,0xde775bfd),L_(0xa5183e31), + LL(0xd08dfe45,0x9b19df92),LL(0xf42316da,0xfd14af8c),LL(0xcc3f5ace,0x9cb59da4),L_(0x2c68ad5c), LL(0x880b584b,0xe1fa2671),LL(0x0ace93c1,0x76bf0449),LL(0x0c870e3e,0x6fb6d427),L_(0x680b653e), + LL(0x70db0533,0x12b3f8dd),LL(0xb2fbdce6,0x167ab18c),LL(0x92abaaa2,0x5e4d357c),L_(0x452fe014), LL(0x1fb69d3e,0x7bd8f0e1),LL(0x58ea7caf,0x4735131f),LL(0x84b31510,0x6a03c6b3),L_(0xbcfb5361), + LL(0x5a2c8036,0x91588e92),LL(0x4e652187,0x1b69af1a),LL(0x451b95e7,0x3517cee5),L_(0x8c64ca67), LL(0x1e09f843,0x90930327),LL(0xbfeeb455,0xefa175df),LL(0x9e48451e,0xedef520b),L_(0x49b070fb), + LL(0xa2492065,0x1e8946dc),LL(0x318fd845,0x9916090e),LL(0x82135311,0x98fdccc1),L_(0xbc4b4f98), LL(0x31f673e4,0xd529f3ea),LL(0xf1c8e5c6,0xb119ca50),LL(0x428145ce,0xcf53a57b),L_(0xba7a2228), + LL(0x38640e72,0xa872dbd5),LL(0xab84c140,0x8f90052d),LL(0xffeb6e87,0x9a484b77),L_(0xc8d71762), LL(0xe045b6cf,0xb3a39b3e),LL(0x68339c4f,0xdbc53298),LL(0x462a1b9b,0x60a23eea),L_(0x47a583f5), + LL(0x8a1c84eb,0xc38a15ff),LL(0xc73cc555,0x5b502e98),LL(0x67d1f3e4,0xf85c7d6e),L_(0xfaf491bb), LL(0x7c34a745,0x94062e0f),LL(0x5e8b71b9,0x9579c983),LL(0x35f7a266,0x63ed902e),L_(0x2cfe7a8e), + LL(0x7e6607ae,0x54fa21c1),LL(0x7c605a96,0x2c3baf13),LL(0x177b275b,0x39001a70),L_(0x402c2a3f), LL(0xf4928a3d,0x9356e91a),LL(0x443518d7,0x30b1d7ca),LL(0x02772478,0x8c5ecfb7),L_(0x8e06bb83), + LL(0xcaa887a4,0x4f7bef32),LL(0x08805f7d,0x5dec8cf9),LL(0x8965403a,0xcc362cae),L_(0xa8e82004), LL(0x37f6ba21,0x35e7cde5),LL(0x1d022cb1,0x0d54e5e6),LL(0x02d7913b,0xf4a0addb),L_(0x4f243fbb), + LL(0xcc348a38,0x58983641),LL(0xf6e35ba7,0x237be718),LL(0xd585a061,0xdb2539f1),L_(0x2217c68f), LL(0x403565cd,0x78351808),LL(0x36c2d842,0x6202e955),LL(0x7f54736b,0x660d4fb3),L_(0xca575f23), + LL(0x6bc9ce98,0xb22311a5),LL(0x84749347,0xe993a41b),LL(0x85025abd,0x432e7fa6),L_(0x6f57ce7b), LL(0x42d19cdd,0x18144346),LL(0x1fc786db,0x2bd73670),LL(0xede484f4,0xa93261b3),L_(0xc5ec96e8), + LL(0x38a7a729,0x2660c15e),LL(0x6845886e,0xcbfe266f),LL(0xe7715ea4,0x803ef610),L_(0x9d5c3a0d), LL(0x6f2eb06c,0x3e73d7f3),LL(0xaff72fe1,0x8fe4228f),LL(0x2703c35b,0x801d9246),L_(0x0008cf4d), + LL(0xa7b3253e,0xb347bed9),LL(0x87c9db13,0x23367d55),LL(0x50ebab37,0xe6bc8d5f),L_(0x30c060ce), LL(0x9df003d2,0xd78ada2c),LL(0xc3892b4e,0x4989b92d),LL(0xf9b3e9f5,0x2dbbe952),L_(0x48275a07), + LL(0xdc3c1c12,0xfb949b08),LL(0xa8296f5d,0x010b8834),LL(0x69483176,0x73825d94),L_(0xe4f380a5), LL(0x7caf444a,0x3cd86c08),LL(0x6ae21350,0x8ba59225),LL(0x6d5a74bd,0x1e6e636f),L_(0x6a2c970e), + LL(0x51eea6cb,0x69de6020),LL(0x15974dd5,0xf383a0c6),LL(0xa7aeef7a,0xec5ab9f7),L_(0x25652e0f), LL(0xb56f14b1,0x7b78f2d9),LL(0xbe7272ca,0xb4e91769),LL(0x0886a015,0xb8c7fe1f),L_(0x1c2ac0a8), + LL(0x7b2d2c1a,0x3f05a7cf),LL(0x7d9a8322,0x8a978fa5),LL(0x2541de9c,0xb09f953f),L_(0x44b3e4d5), LL(0xa6872622,0x0275a86c),LL(0x5ca47329,0xc3073baf),LL(0xe68e138a,0x70608786),L_(0x426bc12e), + LL(0x22def544,0xc1d1a75a),LL(0x054cdb35,0x9d05dd03),LL(0x13908388,0xcac954e6),L_(0x6b377854), LL(0xfb37d06d,0x42873dd7),LL(0xd85fe89f,0x77686ddb),LL(0xbd6e2bfe,0x0a7aae21),L_(0x3116e23a), + LL(0xd00f34a0,0x6d3f30d8),LL(0xb72f2ac8,0x793a6f93),LL(0x8e54b8c8,0xa3ebe240),L_(0x06c18c5d), LL(0xd3635d7f,0x7527fefe),LL(0x848fd8b1,0x7ecf5710),LL(0xe5c193ac,0xc5b359a4),L_(0x10bdedf6), + LL(0x6a69e07f,0x904b6a99),LL(0xf73ecc50,0x74691c89),LL(0x377aafb2,0xf8dfe49e),L_(0x3116ab06), LL(0xbc4bbf14,0x32c37416),LL(0x4f9adb4e,0xa6bc7861),LL(0xb481fbff,0xab667972),L_(0x50e39a47), + LL(0xd40e7122,0x03318c55),LL(0x2b1438a6,0x5cc23063),LL(0x7d21722c,0x353dafc9),L_(0xb52192c7), LL(0x47d32da4,0x8e5c3c5f),LL(0x356f1a48,0x4c620a4a),LL(0xc2e2dc49,0x6ac8f16a),L_(0xa8078172), + LL(0xe0aae2f3,0x27e1fc19),LL(0xcaccad70,0x9a5089ff),LL(0xd066d3ec,0x83ce796d),L_(0x1d39df6c), LL(0x3d7bd85e,0x2109b271),LL(0xd4d73f64,0x032bfaaa),LL(0x4c64918b,0x28f7e9fb),L_(0xead7a6eb), + LL(0x81a3a911,0x1ec15d92),LL(0x072d4b8d,0x0de6b8aa),LL(0x25d33d78,0xdb94f1aa),L_(0x163e5ede), LL(0xcda754fd,0x0aa41bac),LL(0x8bb9f4cc,0x26a33edd),LL(0xaed5fcc3,0x03b383eb),L_(0x7bac84ac), + LL(0x48a08610,0xe3c9d6e7),LL(0xaf9b1185,0x1c9dda6d),LL(0x37a0510c,0x87290f47),L_(0x395d8f39), LL(0xe0b9b993,0x04968462),LL(0x2065fe67,0x79bcdef3),LL(0xba7c23dd,0x3c9dfbbc),L_(0x48b97684), + LL(0x4867362d,0x9b7dcff4),LL(0xa45a3647,0xf6be4fd8),LL(0x9dd99069,0xfc837cc5),L_(0x463e52d6), LL(0xa104db39,0xe73440a8),LL(0x868e9fad,0x557bc30e),LL(0xca38a194,0x0b9107de),L_(0x3b4896a5), + LL(0xf9b3c663,0x0572aa2e),LL(0xb232d67e,0x6cf8f9e9),LL(0xdc3bb3a4,0x578fa229),L_(0xf77deefa), LL(0x7b780979,0xe2e55595),LL(0x3dd1f800,0x1ae5674a),LL(0x7d70eb0e,0x6287e785),L_(0x6ca9df37), + LL(0x6027714a,0x6418b451),LL(0x6b5f95e4,0x008c73fe),LL(0xc7a41b44,0xb52d2690),L_(0x7e9e5e8d), LL(0x07d5913f,0x28af32f1),LL(0xba6493ac,0x70ace436),LL(0x249d5a1f,0xe2634904),L_(0x9de83ae3), + LL(0x91c3f75f,0x7ac06d6f),LL(0x5d22beb3,0x8cbbcc95),LL(0x6114dddf,0xb3f952c3),L_(0xd55713d1), LL(0x50a376be,0x95633a5e),LL(0x402443f5,0xf0277528),LL(0x900af3d2,0x2aac428e),L_(0xe7ecc502), + LL(0xede089c1,0xafe013ca),LL(0x9bc0d189,0x24f9b481),LL(0x7d9ab065,0x7064130f),L_(0xcb09791d), LL(0x88599e66,0x1a8684d1),LL(0xdbafc741,0x5b828087),LL(0xa7784039,0x274e2738),L_(0xa61d0693), + LL(0x04a64675,0xabf54d81),LL(0xdec1f49f,0x46144f05),LL(0xc232e58f,0x30cddd92),L_(0x5b7d5bc7), LL(0xc2b48798,0xfb8c420d),LL(0xb96fbab6,0xb4d97ee3),LL(0x8d97d0d5,0x8101b1e7),L_(0xb545f661), + LL(0x98af21f0,0xcd4340b9),LL(0x955d1c9d,0xda56271c),LL(0xcf1eb8ab,0xcfc8c025),L_(0xc22b3fb1), LL(0x99747eea,0xdff889cf),LL(0x01a895b8,0x16fb6025),LL(0x22ae0ed8,0x56d4b8ed),L_(0xbdaf7eb9), + LL(0x0745f518,0xc7781923),LL(0xb03571c4,0x6cd5a87b),LL(0xe1112158,0x734d96e5),L_(0xc2f71082), LL(0xfbc17aec,0x7d6ae9b9),LL(0xae846849,0x6b340fbb),LL(0x7a81eba8,0xa462be47),L_(0xf156efcb), + LL(0xbad5359f,0xcc17a45f),LL(0xed5f0c48,0x3962aaeb),LL(0x18daea3d,0x24dea50b),L_(0x2620a5cf), LL(0x2db980d5,0x94722851),LL(0xe16c7ff8,0x17a80fd9),LL(0x0cd73f37,0x0ef75926),L_(0xa7a0ce92), + LL(0x2994a0c6,0x0d862f7d),LL(0x66b2e45e,0xa326bcf2),LL(0xb39a090d,0xebe228c9),L_(0x8223ef31), LL(0x4fe39e14,0x292a329c),LL(0xe179a973,0xa1f5d624),LL(0x3f828ea8,0x70ad621c),L_(0xc04d2e0b), + LL(0xb7237a24,0x94de2084),LL(0x91138a01,0x0c93caa4),LL(0xd97e1daa,0xb74fa915),L_(0x668329b9), LL(0x146706c8,0x23c7b716),LL(0x23606a0c,0x54c6c8af),LL(0xbe011ca0,0x2ef6e4a4),L_(0xb2029de6), + LL(0x33851602,0xbee34e4c),LL(0x7b910cad,0x8e7c506d),LL(0x2b92ce18,0x62b378cc),L_(0x5c490234), LL(0x95f16f74,0x661c0891),LL(0xa5073d8e,0xf7df962d),LL(0x6fdadac1,0x8f3ef4f4),L_(0x373f29f4), + LL(0x23206f03,0x235bc318),LL(0x7518fa1b,0xec43017e),LL(0xc5d4dab6,0xf547238a),L_(0x7e5c2b82), LL(0x25d0ebfc,0x8357f1bb),LL(0xfb571aa9,0xe137e308),LL(0x996a92a8,0x629e8aa7),L_(0x90f06a9f), + LL(0x4a17680f,0xa8c7b143),LL(0x84f5aab1,0xb84edf8c),LL(0xf2acd3a2,0x8b3a07a1),L_(0x5d4c58ed), LL(0x2f0d5862,0xcd2f47fd),LL(0x31cb8d1e,0x0d4da406),LL(0x0cd04a92,0x8ec4fcad),L_(0xb261a451), + LL(0x91a38da6,0x76eb9c38),LL(0x12868725,0x0a5b71ac),LL(0x2d328a16,0xf6122daa),L_(0x9232586e), LL(0xa1eceeb7,0xe9555051),LL(0xc35149d8,0x55020182),LL(0xae8df945,0xcee3a23b),L_(0x6020896d), + LL(0x88241ba5,0x6839ac95),LL(0x75c22b80,0xb01a4c72),LL(0x4e73d41b,0xdbce70d9),L_(0xb035070a), LL(0x25457ffb,0x4155bcf6),LL(0x6c514452,0x79b75848),LL(0x3c25b38e,0x8c33a19b),L_(0xb8f49889), + LL(0xb2bc7aad,0xc7b2eb56),LL(0x96c5270f,0x8112c87f),LL(0x15208222,0x612138e3),L_(0xac8a2edb), LL(0xa6392e61,0x7fcbfb2b),LL(0x95cfe395,0xb4541276),LL(0x134be404,0x3de33a7c),L_(0x2cf45438), + LL(0x27c80982,0x6d995371),LL(0x429942a9,0x1e16c2dc),LL(0x0e59bd58,0xfbad79fb),L_(0xd34caf67), LL(0x481ca9cf,0x6cb52c72),LL(0xfc7ee8ab,0x7e9afc85),LL(0xfda3af10,0x41a661b7),L_(0x7e623e57), + LL(0xc421cd21,0xb68b5cf7),LL(0xd94c04b7,0x107cec0c),LL(0x81208f8b,0x383162ed),L_(0x454f3ae7), LL(0x2a8bfdfe,0x0f977619),LL(0xdeb81615,0x382decc1),LL(0x8e5df4ce,0xf0414c84),L_(0x0f3c79aa), + LL(0x15f29277,0x89f9b2a7),LL(0xa1f621ee,0x817b0a57),LL(0x6ee121aa,0xf56eeafc),L_(0xcf7c22d6), LL(0x0bbfabbf,0x52eb19cc),LL(0x018d1b99,0xc2b09e5e),LL(0xa82ae35b,0xd9cf95b8),L_(0x34b4bf9a), + LL(0x017073a5,0x4f731dd0),LL(0x0235def1,0xd07b63f1),LL(0x5e605b0d,0x4769aa10),L_(0x7252588b), LL(0x26cfa7a5,0xfac43672),LL(0x01631f47,0xbb074c5c),LL(0xe02c4623,0xb6536982),L_(0x061acc5a), + LL(0x0bd8823c,0xca3a4054),LL(0x57b5c945,0xbee559f1),LL(0xac8c4662,0x54b8d320),L_(0x8ee0f3f7), LL(0xfc9e1370,0xafaff913),LL(0x7ef2aacc,0x15a9349a),LL(0x81208c2d,0x0d06fd25),L_(0x00df14a3), + LL(0xc4906f44,0x3cb8d3d5),LL(0xc2b5f2bf,0xef621a83),LL(0x42fee26b,0xcb150abc),L_(0xa4673146), LL(0x8c081901,0x2e00a64e),LL(0x4f184ea9,0x4b9fa7b4),LL(0x7c4d0b48,0x60c91243),L_(0x05745a02), + LL(0x36d03f9b,0x7049620b),LL(0x54cfa460,0x29c0b51d),LL(0x50448eab,0x3f0b2dd9),L_(0x9ed5c1c7), LL(0x217c3b7d,0x8eca2e20),LL(0x7e7352b9,0x20883efa),LL(0x3afc2315,0xc23211b5),L_(0x98c20d32), + LL(0x3c1d5c98,0x00ef3bc9),LL(0x03002427,0xf1f069cc),LL(0xc5bebf01,0xf661ac1a),L_(0xb01d642d), LL(0x54219e42,0x25a7fa91),LL(0x199aa1af,0xf217cbfa),LL(0xf0d4c0bf,0x4f2df7eb),L_(0xf7508aca), + LL(0x8f2773db,0xb21c4cfa),LL(0x966e2843,0x52c04b61),LL(0x590a0567,0xf35f4a84),L_(0xf255a433), LL(0xcc2e1149,0x04ae8b1c),LL(0x13360c1c,0x92f66f03),LL(0x4053731c,0x20aba0c9),L_(0x20d59987), + LL(0x0a4bb9e9,0x9ad08ec7),LL(0xa3719263,0x54a4bb3e),LL(0xc9bcb020,0xf5564618),L_(0xaa1b7ba0), LL(0x2f0cb8aa,0x64275534),LL(0xd09acd41,0x3340504f),LL(0xd7e50869,0xaf97cbcd),L_(0xf4025b06), + LL(0x96f1d3cd,0x9f391b14),LL(0xbd5e9744,0x5f6bed3b),LL(0x008d20fd,0xc79a2572),L_(0x905330f0), LL(0x77d13f02,0xb71f049c),LL(0xdb745573,0xe088bd21),LL(0xbd449f9b,0x3a76432d),L_(0x1de7f0bb), + LL(0x12dbb0cf,0x4f53adb9),LL(0x2e4f3aa7,0x13ff9790),LL(0x61674465,0xa80fdde3),L_(0xfbfa4069), LL(0x50e102a9,0x28391810),LL(0x22e32485,0xd119b153),LL(0x47aca745,0xeb9f0102),L_(0x3f33e272), + LL(0x6dc8e416,0xb01555de),LL(0xa53f861f,0xc5669efc),LL(0x14d3a409,0x0c68a597),L_(0x3ad8c86e), LL(0xed8dbd60,0xc5474f33),LL(0xda13401f,0xd21a574f),LL(0xf6b7aed6,0x0d2d58af),L_(0xbe2e5676), + LL(0xb63ca145,0xa81eba20),LL(0xd0d7b9ca,0xf6e2c558),LL(0x4e439115,0xe8f8d978),L_(0xb32fdbaa), LL(0x8cf406a7,0x23a5c7d1),LL(0x7072ea14,0x4e16a729),LL(0x3db551d5,0x88436ae6),L_(0xd7c49d77), + LL(0x32172eb6,0x7d243c47),LL(0x52231b01,0x4a4714a5),LL(0xed3510a8,0xfde7f4a6),L_(0xccb27287), LL(0x1ed13735,0x4721f266),LL(0x5a39f8ef,0xf2889694),LL(0x99b1258f,0x45218687),L_(0x4c27d1de), + LL(0xe91d500c,0xcf933e7f),LL(0xb7d6326c,0x2d1ad273),LL(0x572c7767,0x79dbaa6e),L_(0x27d7d939), LL(0x17390032,0x6c991f09),LL(0xed70ac81,0xbaab3191),LL(0xfc86b907,0x93c673b6),L_(0x94754f34), + LL(0x3543430c,0xc2f96d5f),LL(0x0ea5f8eb,0xac730ca9),LL(0x376185cf,0xfeac300d),L_(0x41737668), LL(0x96df0a25,0xf035d502),LL(0xb519c6a4,0x9ca93571),LL(0xd64df17a,0x01970aaf),L_(0x18c05bf9), + LL(0x471f2099,0xa5fb90b3),LL(0x53b53a2a,0x2aa370a3),LL(0x09b936b9,0xcfb37658),L_(0x83591048), LL(0xb2dfe05c,0x1e8ce8f7),LL(0x70ca625a,0xcf8806b6),LL(0xf062523d,0xa1c74034),L_(0xc4ca8211), + LL(0x02fd45e9,0xf0d5ce43),LL(0xf94539de,0x86092a2c),LL(0xc28ad111,0x0990658e),L_(0xfc301c6d), LL(0x850acec2,0x097c875b),LL(0x333c1a83,0x79052ae9),LL(0x651a1ec4,0xdf5b00e0),L_(0x8f342e96), + LL(0x7c4aacf4,0x12306aef),LL(0x23bf4f82,0x0369e1f2),LL(0x86d193a6,0x3bdb2181),L_(0x2df259e0), LL(0x4d9c6a9b,0x2e587a72),LL(0x420fa4b9,0xe30d76a5),LL(0xaf97ed7f,0x20fbaabf),L_(0x6c230751), + LL(0x044baaf4,0x04047c5f),LL(0x8d43be85,0xe4e3879a),LL(0x436ef7e0,0xed64bf04),L_(0x6b436c30), LL(0xa9c7bdcd,0xc1679bbd),LL(0x12340567,0x38ba10d1),LL(0x83b598cb,0xa99537cc),L_(0xee36e118), + LL(0x18eb43ca,0x5aa367ce),LL(0x94ff23cf,0x2dc9b946),LL(0x066d6c04,0x3a41602a),L_(0xfe10e991), LL(0xfcc4d378,0x3dbf71fc),LL(0xd6bc1c02,0xc9ccbaad),LL(0x0aacb390,0x985954f5),L_(0x468870a9), + LL(0x1f6e5aac,0x4d58f138),LL(0x088912a4,0x72e75855),LL(0x389e7a2b,0x4b5aa1e6),L_(0x5be86bd9), LL(0x29d90bc3,0xb35b2d2a),LL(0x67e8a5ea,0xaca3b9cb),LL(0x832c687a,0xe2911a57),L_(0xed56df90), +}, +/* digit=8 base_pwr=2^56 */ +{ + LL(0x56b1b68d,0xa766a468),LL(0x7a690380,0x7f0a8ccb),LL(0x15b9ce0d,0x8bfb375d),L_(0x0afa00f6), LL(0xe7944b6b,0xe502fd6a),LL(0x0768ebca,0x079ac7ac),LL(0x956dea42,0x3fc3f258),L_(0x78be0f9a), + LL(0x7157aab8,0xde649372),LL(0x1fe5b1db,0xec032ca1),LL(0xdc9ac491,0xaf00af85),L_(0x42bf819d), LL(0x3d3a586d,0xb1b4ed91),LL(0xc6e9377d,0x0da4ec46),LL(0x2fb5dda7,0xe69eb235),L_(0xa5e4f04d), + LL(0x4a718a91,0x6813c47e),LL(0x520eeb02,0xcc1aaacb),LL(0xbae4540e,0xfd6dde20),L_(0x5d3611cc), LL(0xa139969a,0x47c1ef53),LL(0xa02a9c1d,0xff24f01d),LL(0xa1779b32,0xafe60f72),L_(0x0b879e68), + LL(0x6e7fd2ac,0x206a6f14),LL(0x2a13d9f9,0x43a11c7f),LL(0xf31bbf6c,0xe2ff97fb),L_(0x56107ea7), LL(0xb83101aa,0x0b2c24c6),LL(0xdc078721,0xd00a24a9),LL(0xc5ea4420,0x80054822),L_(0x76c2e6e5), + LL(0x5d302b86,0xa3ec0bc2),LL(0x58cdfe77,0x7469b928),LL(0xde033220,0x9823907b),L_(0xce8c1169), LL(0x8d35908e,0x668b8357),LL(0x90f7260f,0xcd96886e),LL(0x388da84d,0x8e759b7d),L_(0xf9144eb3), + LL(0xb0068632,0xb87f256b),LL(0xd3ec8de1,0xb7562058),LL(0x554d7fad,0x68b8bed1),L_(0x7d3ba275), LL(0x5349ed32,0xaa23f48d),LL(0xf8c55847,0xac744602),LL(0x125ee820,0x150da1ca),L_(0x16333e9d), + LL(0x16a4c78e,0x26b49a2d),LL(0x9714ac19,0x69e5dc39),LL(0x50449596,0x2af6b2c1),L_(0xab90cd95), LL(0x07439dc5,0xf5736c67),LL(0x8b3909e8,0xeeb790dd),LL(0x0cc523dd,0xae2f8bbf),L_(0x21833381), + LL(0x1c12b2d6,0x7628ecee),LL(0x6d88b422,0x0692cc8d),LL(0x65398808,0x5048f64f),L_(0x0e3b6999), LL(0xd880351e,0xae75c4fc),LL(0x3ffdb69e,0x3e2ff89d),LL(0x5f9ca860,0x435a454d),L_(0xd321ca44), + LL(0x1dbe11f1,0x805cdd89),LL(0x0b435944,0x0562fe66),LL(0x5d6a45d5,0xc9eb9f56),L_(0x0394c9fd), LL(0x1fbcb273,0x4b25d574),LL(0x8a17364c,0xb78a31bf),LL(0x1466b27f,0x468c47f5),L_(0xfd233c89), + LL(0xb836e3e6,0xf6743281),LL(0xe6b59ce6,0x13f41d4e),LL(0xd77d4340,0x397a6846),L_(0x45693c8c), LL(0xbd735497,0x6560f3f3),LL(0x5f68d915,0x61405ead),LL(0x119c162c,0x9870a7f1),L_(0x8b74bea7), + LL(0x4f81eb06,0xdd4548bd),LL(0x271e6f36,0x49ea4452),LL(0xff17a13f,0x54ebcb9f),L_(0x83b9157a), LL(0x3e7236a9,0x4d44b2ce),LL(0x7f67612f,0xfeac4aaf),LL(0x0d85cf3f,0x7d7cb315),L_(0x7efb9b30), + LL(0xb0f78faa,0x82bbcdcf),LL(0xf1c04007,0x01559ec3),LL(0x7cdb7afd,0x86ff3957),L_(0xb1597d4b), LL(0x6c320e72,0x45b1afec),LL(0x522b415a,0x9d12c298),LL(0x6b93f2de,0x3e21f849),L_(0x3b1a1d95), + LL(0xc12b655e,0x219c2865),LL(0x6265e8e1,0xc6daf8cf),LL(0xf3ec2977,0x10269fa7),L_(0x4486877c), LL(0x8de615f2,0xb448dafb),LL(0xfeda6cb4,0xac03ce69),LL(0x0fd25b12,0xb96afd44),L_(0x0f6ae181), + LL(0x069f14f1,0xc970df0c),LL(0x614fb451,0x8cddee54),LL(0x0475ddb9,0xac228ae6),L_(0x3ef6e29e), LL(0xc73f5027,0xbdeb5cb1),LL(0x2198420f,0x82098200),LL(0x8694111c,0xc11479ab),L_(0x25c29038), + LL(0x0c73fe99,0x4aa502d3),LL(0xdb603ed0,0x6c27909f),LL(0x4f620050,0xf76957c1),L_(0x0e7e084e), LL(0x1565b30b,0xfba38431),LL(0x95ddd9af,0x65c7038d),LL(0x82a6a124,0xe7db47e4),L_(0x1f3b155f), + LL(0xfdab8dbe,0x773fef23),LL(0x70802c0e,0x011efbb8),LL(0x8698e8b3,0xa4f63ad2),L_(0xa90d02ab), LL(0x60003ff7,0x5aebc019),LL(0x586f4378,0x00bcb9de),LL(0x859f79cb,0x6a9d21d2),L_(0x79d6150e), + LL(0x8a59362f,0x21480f43),LL(0x37e25e9c,0x4a37a459),LL(0xe55838d3,0x36aab717),L_(0x85a89af8), LL(0x1d33aa1c,0x86dc1133),LL(0xb94719f6,0x0a1e4a76),LL(0xf9d8ea27,0x7a9f7b61),L_(0x2b10e5f5), + LL(0xf5ab77c2,0xb7c034fa),LL(0x91179a6a,0x89204639),LL(0xd0dd8159,0x4ba725f9),L_(0x39ccdad0), LL(0xa510602e,0xc72415fe),LL(0x85069c0f,0xa6bc7ccc),LL(0x7d585ae6,0xc90e9462),L_(0x51cea642), + LL(0xaed13816,0x84f02e2a),LL(0x24576ca8,0xffdbb5f9),LL(0x3c9269f7,0x5c61743e),L_(0x498dc0e3), LL(0xd5bc6379,0xa9132224),LL(0x10fc37d9,0x12f65fd8),LL(0x817445f8,0xd0c982b8),L_(0x4f79fcf1), + LL(0x40f7fe3e,0xcb5018ef),LL(0x2fdb045f,0xf32b39b6),LL(0x621a4bd4,0xe7c33edc),L_(0x04fd5dd5), LL(0x7972a384,0x586d4bef),LL(0x22c07adc,0x81211aa8),LL(0x8c46dfe1,0x5b192417),L_(0x68b0abc0), + LL(0x30ddafb1,0xe56640a6),LL(0x55279999,0xe01ca53a),LL(0x6b7735ff,0xa4ba7379),L_(0x1c1eab8d), LL(0x184d5073,0x1f2853f9),LL(0x0a5a3694,0x0c65322e),LL(0x77546dfc,0x814529cf),L_(0x0117bc49), + LL(0xe44092c1,0xdcf36025),LL(0x29873c6a,0xa38b0382),LL(0x2beaabb1,0x57dab020),L_(0x4481b257), LL(0x3fc25cda,0x16190d52),LL(0x3dcabd82,0x632514c7),LL(0xc69b7cce,0xcb82be1e),L_(0xcf490cc0), + LL(0x79d31337,0x78cc588c),LL(0xd718033e,0x5d3ca504),LL(0x0951b466,0x82b9278f),L_(0xc14b1f81), LL(0x6c160f3e,0x308d56c2),LL(0x833254cc,0x460ed897),LL(0xcccc63ee,0xd27b55ac),L_(0xdf9c95f1), + LL(0x2097cb5b,0x6fb48059),LL(0xc33f19e6,0x8b4a82f4),LL(0x3bf0f71b,0xda304a5b),L_(0x7efe85d3), LL(0x5d609c9e,0xb32599e2),LL(0x7d311503,0xea5b4566),LL(0xc072d5ff,0xf9f2dc57),L_(0xf9df545e), + LL(0xdacba736,0xbc32b9c9),LL(0x0ab7c149,0x154849a8),LL(0x29e4dd9b,0x11dfc29e),L_(0x41ace68f), LL(0xc8616f74,0x971ba9a3),LL(0xb0be2d45,0x15776b0b),LL(0x8325c930,0x294a4ec5),L_(0x455623af), + LL(0x16f8969c,0x235d5c34),LL(0xb8ca3700,0x57aa97da),LL(0x5c79afae,0x417467c4),L_(0x796984ff), LL(0xe7950969,0x59ca92ce),LL(0xcd03a014,0xb1a7c34d),LL(0x6203a921,0x066a9647),L_(0xd0909f6f), + LL(0xfb7e2684,0x84d55477),LL(0x0c455cdf,0xbdee722d),LL(0x74bfcbf4,0xf514f2bf),L_(0x8a60e5e7), LL(0xba7058a4,0x4713d1ae),LL(0xecf4c404,0xa6c17b5e),LL(0x8941ddd8,0x261d9ac7),L_(0x7f2f5187), + LL(0xac5e5ce7,0x76370390),LL(0x64cf9d29,0xfce7f694),LL(0x7c34fbe8,0xe3b42849),L_(0x6bc43f22), LL(0x8781925b,0xe273ae40),LL(0x49d3a7bb,0x777881ae),LL(0x6fc64556,0xb0f8e854),L_(0xb4b40191), + LL(0x024a93d5,0xa6b66d66),LL(0x4f2aaf4a,0x56c335ae),LL(0x0805e125,0xe1e39e4e),L_(0xb67d8a1b), LL(0x9bb438e7,0x0e8dde7c),LL(0x24683c26,0x06a38af7),LL(0xa234eb6c,0xd74870f8),L_(0xfa606ebd), + LL(0x05b51c3a,0x62d8ac43),LL(0x8c1548ed,0x8eefcd86),LL(0x3b151865,0x3c047e9d),L_(0xf77c0004), LL(0x76ea2961,0x82998a41),LL(0xa3b38ce5,0x110b3b2e),LL(0xbcfe60ba,0x89b19d6d),L_(0xe68575e8), + LL(0x8765ec49,0x36e47913),LL(0xc6e4ab7e,0x767e806a),LL(0x81bc9bd7,0x38103684),L_(0x5490cabd), LL(0xb8107b91,0xbe9c24b5),LL(0x63e98957,0x43623ea0),LL(0xf06a675d,0xcbeab5be),L_(0xf0e9a898), + LL(0xd064269c,0x1ccbf4e2),LL(0xfe422ab3,0xe21fbca6),LL(0x5cee0a5c,0x263913a5),L_(0x71de7df5), LL(0xa3fc8bae,0x047f1949),LL(0x0df59ed6,0xd1a5d116),LL(0x35a0d475,0x9e3419f5),L_(0x75946143), + LL(0x36c9f809,0x631145ae),LL(0xa1db7d1d,0x0c423276),LL(0x4bf70210,0x2f1584d5),L_(0x8bd52dbd), LL(0xa19699d2,0x8015f024),LL(0x37a40f15,0xf9755c59),LL(0x25538f41,0x387ddb31),L_(0x90af00b0), + LL(0xe8509934,0x9e321e61),LL(0xd2850d36,0x7dc68e41),LL(0xf8206e77,0x58e783b2),L_(0xe67a1042), LL(0x906883cd,0x6f41c769),LL(0x51b97936,0xbb9527f5),LL(0x38e2f27d,0xcf17789e),L_(0x5273cd0e), + LL(0x1bf5a9fa,0xae648e71),LL(0xde909240,0x3f5f8275),LL(0x93245241,0x80482c3b),L_(0x0a2260c5), LL(0xef9f19ab,0xaa9e665a),LL(0x1eb26ff8,0xad522975),LL(0xce379c80,0xf8653e32),L_(0x4f190ba9), + LL(0x19d1e571,0x4023698a),LL(0x4e5e5355,0xa19db2ab),LL(0xd2800586,0xaee5fc4c),L_(0x115617f9), LL(0x378c9aca,0xbcb82922),LL(0xfb1dcef8,0xc3b8fa14),LL(0x1b19035c,0x1c3a4f74),L_(0x190f3cd7), + LL(0xf201d617,0x88de2216),LL(0x778baf2f,0x409f13a5),LL(0xfc1697ff,0x1f4ee383),L_(0xf8b34103), LL(0xc70f2c0b,0x596702b2),LL(0x40ecf08e,0xaa0989d3),LL(0xcc60a8c2,0x5ba1fcbb),L_(0xb0f51744), + LL(0x3f768dfe,0xee929e0b),LL(0x5c573a73,0x171719ed),LL(0x91e6ec5d,0x48549719),L_(0xb182f69c), LL(0xa3e2860c,0xa30f11a1),LL(0x5e01688d,0xf804fa42),LL(0x58c435e7,0xd81ff657),L_(0x49e16053), + LL(0x3ee264bb,0x6d74b27a),LL(0xcb2992ae,0x776b6b64),LL(0xa97538c5,0xdc494d53),L_(0x282ddfc8), LL(0xe4acc7fe,0xe5d1ac83),LL(0x81afb14c,0xf0a59879),LL(0x9b5f787d,0x0730aa6b),L_(0x76168d56), + LL(0x5d202341,0x15ca4cef),LL(0x67cf5e49,0x03078647),LL(0x7cbaad05,0x7a152a3a),L_(0x93ecdb65), LL(0x5c759c30,0x1d48b5cf),LL(0x8a07288f,0x954731e0),LL(0x67babf9e,0xb890cb9b),L_(0x3f7cb4f5), + LL(0xfbda2539,0xd314af3a),LL(0x66f79c66,0x333f8c94),LL(0x07bcc285,0xd37bbc81),L_(0x1102429d), LL(0x7ba7309f,0xe5686c59),LL(0x647c832d,0x96218ea6),LL(0xbfb2d48e,0x7bc6fa2a),L_(0x524c8c0d), + LL(0x91273fc1,0x9f330845),LL(0x6f3e8880,0x8d3155c8),LL(0x229515d9,0x4e0d0091),L_(0xa37bad0a), LL(0x3cca8a71,0xc538ea5c),LL(0x34161b0c,0x7f68ef37),LL(0x412db800,0xfc39477c),L_(0x5112c574), + LL(0x202d77d0,0x3f50f1ae),LL(0x56e724be,0xc9d43dee),LL(0x2163dc89,0x82838e71),L_(0x3e07b5b6), LL(0x68b2f3b5,0x028beb58),LL(0xfb4f5d6e,0x2f67136a),LL(0x63c11941,0xf0576d72),L_(0x36e94125), + LL(0x79a7908b,0xfe08b743),LL(0x7ec4b29f,0xe4c9aa01),LL(0x3121fc40,0xe6d6660d),L_(0xa4b98339), LL(0xcc2b942f,0x54acd180),LL(0xc715b5ed,0x4b3ac4d4),LL(0xde75824c,0x91ca23fa),L_(0xe3ff9f1c), + LL(0x46582483,0xa927f3c9),LL(0xbac6e7bf,0xe88a430f),LL(0x1f445777,0x3e33ca59),L_(0xbdfe1920), LL(0x71dd2627,0x54a8126d),LL(0xebc9b59a,0x9c986433),LL(0xbec3ed13,0x71db698f),L_(0xd57f9239), + LL(0x731eb54d,0xa93b1752),LL(0xa3516b9e,0x6f7bfa08),LL(0x873d3a45,0x4f66d06f),L_(0xbdd10c66), LL(0xc97be3e7,0xf6435b79),LL(0xa3533348,0x207b9b6c),LL(0x1c6c74ae,0xb64b6b70),L_(0x9037812e), + LL(0x74ccc35a,0x4be5a10b),LL(0x425bdafc,0xb790b940),LL(0xc32a94b3,0x098b38b5),L_(0x026ae426), LL(0x4ef7c297,0x18feb7b4),LL(0xda85e218,0x6f3016a8),LL(0xad72b80e,0xbdf2db87),L_(0xa853e440), + LL(0x0ca1adfe,0xb13f2859),LL(0xbd4a0fb5,0xd393e869),LL(0x277e9cd1,0x90b15b52),L_(0x30056558), LL(0xf705f505,0x2c2d2fb1),LL(0x2c3d697e,0xf49260e8),LL(0xcb991398,0xfed48a8d),L_(0x6c792dc1), + LL(0x2687c048,0xc3ca0fc2),LL(0x97ff87d8,0xbb9d5b5b),LL(0xe241d7c5,0xef9d2be9),L_(0x4d4d8a9e), LL(0xfe8acc57,0xc5011f32),LL(0x499812d3,0x8545eca9),LL(0xfa8d83be,0xc270dd4a),L_(0x162b0c9f), + LL(0xb3951e09,0x78a942de),LL(0xc228c3e5,0x57fae761),LL(0xbc46ee6e,0x83169c42),L_(0x1aeae5f1), LL(0x340fc522,0x669821ab),LL(0x51be95bf,0x09548071),LL(0x92a505ce,0x83ec59bb),L_(0xd2e39c6b), + LL(0x3ce8adaf,0x41ed0956),LL(0x8981ccd6,0xc0e55576),LL(0xba8eb552,0xa018b90e),L_(0xf5b2000d), LL(0x67316d00,0x5703fba5),LL(0xf9b6f0d3,0x6078c1e3),LL(0x99f221d3,0x047eec80),L_(0x5f0d4326), + LL(0x81739c80,0x6f11b810),LL(0xf085c79b,0x1e31485f),LL(0x9ddc21df,0x18e4d189),L_(0xbe0bc274), LL(0xe78c5638,0x439dc1dd),LL(0x63733145,0xa22acbf7),LL(0x9f469794,0x161460c0),L_(0xaa724fea), + LL(0xcd4a85b1,0x7e2cff5d),LL(0xaf20e779,0x998dca20),LL(0x3d5bd0f7,0xbfc65978),L_(0x4e61a410), LL(0x388987a1,0x9b689b7c),LL(0x04dbc066,0x3ea487dd),LL(0x5b3b94d0,0xa77864e1),L_(0xe89088a7), + LL(0x39413fae,0x796a4cff),LL(0xd204de5d,0x978f94f4),LL(0x2c42836e,0xdabb2333),L_(0x20078e8b), LL(0x683de92d,0x5fe8df50),LL(0x14c267e5,0x705a1d2a),LL(0xf68dcb2c,0x16e49003),L_(0xcbb04811), + LL(0xc7d4f66e,0x02ce592d),LL(0x6c59b80b,0x449fe24e),LL(0x49708f6f,0xe167be96),L_(0xfb3a4da9), LL(0x7456adb9,0xafdb07bc),LL(0xa22499e7,0xfc9ec5ea),LL(0xb52ff28e,0x55b069a6),L_(0xc0fc9e6f), + LL(0x1b0cec1b,0xf4484ca3),LL(0xb1289e3f,0xde798873),LL(0x05b5ac5f,0x87ada89d),L_(0xf204ab3d), LL(0xbc022acb,0x93b1313e),LL(0xd2127d5a,0xa4d90949),LL(0x71a6efc0,0xd897f8e5),L_(0x88e1bcc1), + LL(0x5f811bb3,0x9a725a78),LL(0x9323ffc2,0x1f6cfcf3),LL(0xe1abeb72,0x6d3872f8),L_(0x71c9aa7f), LL(0x90cec4c5,0x400da758),LL(0xdb55d5c9,0x74d4d54c),LL(0x6fed8555,0x4bc5cda0),L_(0x99c927f2), + LL(0xb4a54352,0xa9b678d4),LL(0x21c3a4ea,0xf079b22c),LL(0xcd89ee25,0xec3738e6),L_(0x12db8e7a), LL(0x17543420,0x3b3edf75),LL(0x83b1a5b2,0x46732c66),LL(0xcfead94a,0xa689fe7e),L_(0x658ac775), + LL(0x91cb6be3,0xa3af0a2d),LL(0xaee7da78,0x37e8c56d),LL(0x44cf93c9,0xc55af358),L_(0xb97c6473), LL(0x2941f1b7,0x85525c49),LL(0x9ccf06d0,0x7fe18358),LL(0x32c35949,0xbf4a513e),L_(0x48b1c1e8), + LL(0x8adf6262,0x6619bed5),LL(0xdba7f0af,0x5bb1a013),LL(0xdac22d18,0xe70d7542),L_(0x0c259dfc), LL(0x0bfa91a2,0x195a05ff),LL(0x1ebdd562,0x52bb429e),LL(0x34d0f00f,0x904ed07d),L_(0x9b10bb9a), + LL(0x4331ebb9,0xf071319d),LL(0xa2d5580a,0x05e7c4f1),LL(0x1da3b676,0x7abf809c),L_(0xcca6bf1e), LL(0x9290a718,0xf68174d5),LL(0xc59959c4,0xa93e4d89),LL(0x7f4cbc44,0x93b784f5),L_(0xe5e1c561), + LL(0x7b8373a6,0x1bf6e31b),LL(0x242d1745,0xb8888fa2),LL(0x010ee8af,0xa7cd3971),L_(0xa9bf1772), LL(0x7e33265e,0xc3866a61),LL(0x541559ba,0x9e1bb3ef),LL(0x9be25bb9,0x1c158895),L_(0xd26003c0), + LL(0x187246e5,0xcb1700db),LL(0x97112d61,0x3aa73e7a),LL(0x93e55e2b,0xb2ba60e5),L_(0x34003d9b), LL(0xbcfa0107,0x253d2d5c),LL(0x43a49e2d,0x9fa1e7c7),LL(0x04ad0152,0xd483d4ee),L_(0x05755d69), + LL(0xd95b8ba9,0x1d6eb61c),LL(0xeee8e590,0xc7ef0d05),LL(0x47b3133d,0xf255931e),L_(0x31eb4e09), LL(0x60b98075,0x2344f6b6),LL(0xe87936e7,0x789f9ba9),LL(0x00302e85,0xccdbabda),L_(0xa2a5f4eb), +}, +/* digit=9 base_pwr=2^63 */ +{ + LL(0x228b3a55,0xd1e183b4),LL(0x3a405373,0x4948ad88),LL(0x18288fb9,0xf45f24f0),L_(0x04bd162a), LL(0x37574ace,0xe86d0db8),LL(0x7b9a4c64,0x1ccef3f8),LL(0x451b09b7,0xee7d7495),L_(0xdc28df83), + LL(0xd52a1c1f,0xd08a8ae3),LL(0x7151a72f,0x750d587a),LL(0x03e86cff,0x27e73149),L_(0x59e2acdb), LL(0x527a9878,0x96f4a96b),LL(0x84533bc0,0xe4a1f248),LL(0x038153e5,0xd9998bb3),L_(0xea910931), + LL(0x281ef607,0xee8331e0),LL(0x9f73b6f4,0x71264952),LL(0xa04c6f5a,0xecfe722b),L_(0xd447f9c0), LL(0xbb4ca37b,0x8ff53f4b),LL(0xf450eeb8,0x42ab819f),LL(0xb862be64,0x8ba40994),L_(0x7a08433e), + LL(0x3c280033,0xa9734b49),LL(0xa8e0d0eb,0xb12f26d4),LL(0x3686d2f0,0xe0111b72),L_(0x1e11df0d), LL(0x7a48dabb,0x069099d5),LL(0xefbc8fff,0xaba55aec),LL(0x6cdc05f3,0x4ea7440f),L_(0x7409d1a4), + LL(0x4a159950,0xe99a66d4),LL(0x35d9b8b9,0x4d054e48),LL(0x924ebb42,0x155f0d8c),L_(0xcc5645dd), LL(0xe319a1e4,0xe6d591f2),LL(0xdce90cf4,0xe9b13d21),LL(0x0834867a,0x39cb42c0),L_(0xb288b9e8), + LL(0xb4a0a7e4,0xd28d49c3),LL(0x034fe0f1,0xab2cbbd4),LL(0x4cb47055,0xcd15bd1f),L_(0xb122fe53), LL(0x16ef99e4,0xb349d462),LL(0xaa28568f,0x746c4b40),LL(0x4dce044a,0x56cf52da),L_(0xce7ffcff), + LL(0xb1b9c2ea,0x0196cebe),LL(0x26971900,0xdb961af6),LL(0x51023370,0x68f286d7),L_(0x840c2641), LL(0xad763cfa,0xa07bb401),LL(0x722e5f14,0xab25bfde),LL(0xac71bbe8,0x06a272b6),L_(0x7294da0b), + LL(0xd727b459,0x6aab9dfc),LL(0x67ba95ef,0x695de10f),LL(0x078f906d,0xa987a86e),L_(0xcc5262f1), LL(0xd50493d5,0x3eb5588c),LL(0x1854cdec,0xce9abc84),LL(0x101a021e,0x2ec773ad),L_(0x9a126518), + LL(0x7bdb0ab3,0xb55a240a),LL(0x520772fd,0x06998947),LL(0xf475a7f2,0x04f12f32),L_(0xb6d5b226), LL(0x688143be,0x73021050),LL(0x2e88c6c2,0x325ed38e),LL(0x8114699d,0x467cd567),L_(0x2d56b4f2), + LL(0xcbfe120c,0xe69958d1),LL(0x952433b8,0xa2e1385b),LL(0x9586b08e,0x8d8876e4),L_(0xc1845358), LL(0xe749a358,0x85028619),LL(0x0332f81b,0xf41d9b86),LL(0x8430e884,0xe0fe7436),L_(0x5fa0aa6a), + LL(0xe20a701c,0xbc42935f),LL(0xa8797955,0xaf260957),LL(0xb55c4fab,0xb5f1b7b4),L_(0xbb614800), LL(0x3e2c715b,0x61856276),LL(0xd080dc4d,0x447c4418),LL(0xfaf57b99,0xa5a859f6),L_(0x450d5963), + LL(0xa50c7da0,0xaaf263e7),LL(0x431eb854,0x27bdb99e),LL(0x28bc6b58,0xa291a83e),L_(0x18ba826c), LL(0xe155fe7b,0xa92f7c72),LL(0x42ebeb92,0xfdebd3d9),LL(0x54ea2480,0x1d9b3247),L_(0x01266a3f), + LL(0x3bb14261,0x40205f43),LL(0x83f98334,0x1e5b99d9),LL(0xf68ea4a3,0x99449ff0),L_(0x73052363), LL(0xb4680c54,0x6506393b),LL(0xe10ba403,0x9fa16280),LL(0x355805ad,0xa8869c1e),L_(0x3bd33351), + LL(0x1fe90871,0x60faf2a7),LL(0x26d3ca4b,0x74445704),LL(0x97761552,0xc6294a8b),L_(0x5d498659), LL(0x8306971f,0x79313f41),LL(0x12b7cc1a,0x459c33b3),LL(0x5ff5c231,0xa47413df),L_(0x77510e5a), + LL(0x8931a00a,0x1bb13907),LL(0xb77711c8,0x6e5d6bd8),LL(0xf62b4e1f,0x419ecc6e),L_(0xad753454), LL(0x2e05fe27,0xa9d7ebb7),LL(0x0a367c60,0x46afc58b),LL(0x2c8381f8,0x243d0786),L_(0x4a4e4910), + LL(0xa5a5886b,0xd9832e54),LL(0x5cc2672d,0xc764b06f),LL(0x38ed1085,0x7eb63b3e),L_(0x98a773f2), LL(0x585bdb21,0x8a62c89d),LL(0x4ef6df8a,0x5e301e9c),LL(0x35b91587,0x4e488867),L_(0xee5d5725), + LL(0x9471249d,0xcfed9152),LL(0xfe397a39,0xf83f6a41),LL(0x859a1f08,0x67c5e1b0),L_(0xd1f44f7d), LL(0x40557a71,0xa37c1374),LL(0x124aed5a,0xecd05a92),LL(0x7635cd74,0xccd0d7f7),L_(0x05c36045), + LL(0x02596d64,0x81ed48b5),LL(0xfe6d2634,0x8ec54e24),LL(0xfd23aeec,0xa7513cf4),L_(0xf5285343), LL(0x8f6097de,0x2a1c180b),LL(0xe4bdeb22,0xacdc4130),LL(0x253dbb93,0x9daa0c3e),L_(0x05a30794), + LL(0x5f61e12e,0x3336043a),LL(0x083aa9bd,0xa83c1fea),LL(0x77fedd08,0x64002d5d),L_(0x131fc28d), LL(0x08aaa0aa,0x210df7fe),LL(0xdba1334e,0x6b43ad20),LL(0x98ade169,0x42a1a05e),L_(0x912ea208), + LL(0x6e92d486,0x8a6e2064),LL(0xc3bdcf88,0xc92637e6),LL(0x4ee89ae2,0xa8cbe2a0),L_(0x8fe2ce18), LL(0x688111d3,0x1fafd02e),LL(0x3e63b605,0x315d9dc5),LL(0x0cd0654b,0x02890b79),L_(0x37460a53), + LL(0x131fab04,0x1ac884b5),LL(0xfe807119,0x8a1a27c6),LL(0x66f76b97,0x254a6db2),L_(0xdb8b9dad), LL(0x17450bad,0xd2c4396b),LL(0x24d3388b,0x2691986c),LL(0xd9864a47,0x31c0544b),L_(0x73b25e3f), + LL(0x2f0f74a1,0xf3ddaad3),LL(0x4dc5341d,0xa0f85073),LL(0x55736fde,0x9f28ac0a),L_(0xdb012f27), LL(0x5b08d300,0xaaec443d),LL(0xa313b8a7,0x9fd17e0e),LL(0xb4213134,0xf10e3114),L_(0xf370d32c), + LL(0xd9301e92,0xa6577039),LL(0xdfaeb17e,0x50e6f1b8),LL(0xf5e86ab5,0x58a7b434),L_(0xff883f58), LL(0x2f0371f5,0x1d3d9546),LL(0xcbb7b3e4,0x39c8d544),LL(0x12bf2df1,0x57a123a0),L_(0x1f072a24), + LL(0x817dc76a,0xfd0338c3),LL(0x991da89f,0xb99ba801),LL(0x36e30856,0x1dcffb49),L_(0xc7872aad), LL(0x665a28b5,0xf1016ea1),LL(0x290f4c2a,0x86a30740),LL(0xc3331f1b,0x0205d1d8),L_(0x7458d6c0), + LL(0x86281810,0xd7ae93c1),LL(0xe873393b,0x227716fe),LL(0x736914e5,0x605a49ab),L_(0x963a1b41), LL(0xa3fd7cc5,0x99cf069a),LL(0x4d54cee8,0x93c53857),LL(0xdc5b96cb,0x080bcc0e),L_(0x137d0d8d), + LL(0xf2335efc,0x398d73b0),LL(0xf7bd4b8b,0x00bb4ee4),LL(0x212ffe0a,0x7ab2ea4d),L_(0xa520fad3), LL(0xe2f332a3,0xeeeaddc8),LL(0x55e1d6f7,0x2962d309),LL(0x143e5fcc,0x49553c63),L_(0x65652ccd), + LL(0xc941479e,0x203c4316),LL(0x8084b17f,0x855dab4e),LL(0x717ef700,0x4ed7e83c),L_(0x663074c4), LL(0x494ccfdf,0xe90530ff),LL(0x74fb2c41,0x8222ad9a),LL(0x4430a4d7,0x252e55b2),L_(0x1ff22265), + LL(0x96506aa4,0x3f484d6d),LL(0xa163cb06,0x10e92da8),LL(0xbd490fb2,0xffd03214),L_(0xac263c3b), LL(0x95792258,0x7dfe3775),LL(0x448fd584,0x9120d23f),LL(0xe2412ec1,0x1de70984),L_(0xa0573144), + LL(0xcb479a8a,0xe7cc4f73),LL(0xb248d660,0x1382187b),LL(0x9dc7e0af,0x01c1bd80),L_(0x5c60ddc2), LL(0x7d0256e8,0xbd971088),LL(0x0fcea0be,0x7ac3d22e),LL(0x36e29a92,0xecf0d361),L_(0xacf3f8d3), + LL(0xbb9273ca,0x4c568852),LL(0x92c61bfb,0xf3f274f4),LL(0xb258fcff,0xdee7fe95),L_(0xd7eec021), LL(0xea16df72,0x3f7227a1),LL(0xef526f6f,0x8865b774),LL(0xc554b491,0x10280ec0),L_(0x0822704a), + LL(0x0aaf5933,0x600576a1),LL(0x3b11f02c,0x63228df6),LL(0x7b64399d,0xb12890cc),L_(0xcd17f990), LL(0xf166eabf,0xa3e9c521),LL(0x6f888420,0x01f649df),LL(0x33266d1a,0xb179110c),L_(0x31f1eb1d), + LL(0xaedb7e52,0x2d780714),LL(0x4aebd349,0x76c48d10),LL(0x95533ca3,0xef834a13),L_(0xf261039a), LL(0xbb0ea84d,0x8bf5f008),LL(0x2b897924,0x0c5e907a),LL(0x5462d73b,0x1d6aecec),L_(0x030fd964), + LL(0xb5bf76f0,0x2e91623e),LL(0x3010a109,0x1415663c),LL(0x15fea421,0x1f1c3707),L_(0x7f39476e), LL(0x03dd8ccb,0xb068031e),LL(0xd4fde062,0xd50a50f3),LL(0xbde1692d,0xc8df6655),L_(0x8e9ba050), + LL(0xa49675bf,0x923698c8),LL(0xf646ab4e,0x9ea67a41),LL(0x67f23bf8,0x4444d11f),L_(0x4ac9487a), LL(0x05829e1a,0x18b3a870),LL(0x354f585f,0x8b8364e8),LL(0x917428eb,0xafd1b685),L_(0x4487c137), + LL(0x5cdc38f6,0x8bdefd85),LL(0x9e5f8f08,0x60854dcf),LL(0x5650f1c2,0x3d41abd0),L_(0xc6e01f27), LL(0x338d5d08,0xd45495b6),LL(0x3b1465b1,0x10d2d56f),LL(0x05c210e8,0x2709cd44),L_(0x48f63367), + LL(0x3d513963,0xb778f7da),LL(0xbe45c33d,0x237a1a75),LL(0xb843c30f,0xfe6c9001),L_(0x2fb3bb50), LL(0xb7f1d85f,0xdfc37735),LL(0x9212109f,0x63ca258a),LL(0xbcb01029,0xaad826a1),L_(0xad2340f1), + LL(0xf2d99edd,0x3824eb60),LL(0x40c15d61,0x96cabc5a),LL(0xdb4188d8,0xe5012748),L_(0x8b0b38b2), LL(0x100a7042,0x73b6c9c4),LL(0x51b0b8d4,0x4b2e4ffc),LL(0x3c179919,0x35fd801d),L_(0x4079a1e8), + LL(0xfba7fe0d,0x71487144),LL(0x74cace4b,0xa5684724),LL(0xde29806b,0xaf1f4b15),L_(0xd8b8bd38), LL(0x0418df99,0x3da078d2),LL(0xd3aa1585,0x9504ef03),LL(0xd6fca127,0x68282ff5),L_(0xc362d893), + LL(0xa4371234,0xf24ea908),LL(0x602bf155,0xbf610641),LL(0x751d8536,0x169f256b),L_(0xd3de9a54), LL(0xa7afba2c,0x66d0d844),LL(0xc7851ba8,0x292f0813),LL(0xb9773f57,0xc95c32ed),L_(0x5941d955), + LL(0x931f72a9,0x2d2921a4),LL(0x0d1c3a96,0xaabec6ae),LL(0x93be322a,0xe0530ac5),L_(0x68a2485a), LL(0x21ed4c4b,0x3539fb21),LL(0xbd921069,0x54c5601c),LL(0xff29a4db,0x33f41e0a),L_(0xb292275c), + LL(0x92370d4a,0x2b5f5d00),LL(0xb56aebc7,0x9ce3670d),LL(0xc246a235,0xcfeee196),L_(0x6a801585), LL(0xc688f199,0xc992ad9e),LL(0x47950bdf,0x3828369e),LL(0xc2172706,0x9016c246),L_(0xa7002475), + LL(0xd8546f63,0xf288a32a),LL(0xe74ad8ab,0xd866770d),LL(0xa8e0a566,0x41c5b1a5),L_(0x0d4e95a9), LL(0xc8eca337,0x06f5713c),LL(0x1b3285da,0xaf5394d4),LL(0x1c420a16,0x05bdbb33),L_(0x57e5568c), + LL(0x8e6a5c3f,0xf167321f),LL(0x12138692,0x4806da87),LL(0x98fd2767,0x23e3b0df),L_(0xc297c470), LL(0xde00e6e5,0xa65aaac7),LL(0xb2271037,0x603b9246),LL(0x39526356,0x6098239e),L_(0x06050e2a), + LL(0xdf432ea4,0x989bae16),LL(0x1d1be94f,0xcdff8337),LL(0x1f3f8b31,0xe12f868b),L_(0xeb8efb64), LL(0xc59a6e03,0x3e2e2a6e),LL(0x10ffb8b9,0x35623aa8),LL(0x66bc9d0b,0x419d9c04),L_(0x56947a3b), + LL(0x3e403fae,0x80a49b71),LL(0x85262cb5,0xa16aaa21),LL(0xc0552283,0x941ac341),L_(0x2ed3e3d7), LL(0x78d10e08,0x9e2010ad),LL(0xd7abaaee,0xc3d626db),LL(0xad4eebe0,0x616d3812),L_(0xa0fef6e2), + LL(0xa85af3a0,0xc44a4210),LL(0xb9a6a0f3,0xd700b9c8),LL(0x00fd9c15,0xaaeaf056),L_(0x882ae9df), LL(0xcc55572c,0x58e16fee),LL(0xa9e63498,0x224b2130),LL(0x27e82ee6,0xe838331f),L_(0x34f7549c), + LL(0xf7314698,0xc2d9578c),LL(0x2c89ffc1,0x28f766e4),LL(0xe5782e17,0xdb1237a2),L_(0x38920553), LL(0xdcb19e7c,0x382be491),LL(0x067bb8d7,0xf76d352a),LL(0x0749b544,0x7968d6a8),L_(0x9449b345), + LL(0xceb29d97,0xe4a0f31c),LL(0x468714c4,0x62bd6085),LL(0xc9e0da34,0xd2a91a43),L_(0xf8dfc14b), LL(0xf153aa4b,0x13715918),LL(0xf2418048,0x5c701eb3),LL(0x3cc2d39d,0x21bc78c7),L_(0x14e1c5f8), + LL(0xd3a03cae,0x5f6a9d91),LL(0x6557c299,0x3753e068),LL(0x733ae857,0x58532343),L_(0xb7e14afc), LL(0xc858b2c6,0x423a2e5e),LL(0x1ec4f502,0x03c6d3e7),LL(0xbd4e4f93,0xb99af7a6),L_(0xb21da53e), + LL(0x74665b48,0x00f3a821),LL(0xc7e083f5,0xbb254497),LL(0xae564546,0x09235190),L_(0x0cb8dbf2), LL(0x148c2b65,0x44c9ade6),LL(0x5f11dd78,0x01120f40),LL(0x2095b0d0,0xc2cfde05),L_(0x755f44dd), + LL(0x9096ca16,0x0b95bea1),LL(0x6343ed3d,0x92a3cb12),LL(0x403109c3,0x67ede54a),L_(0x8fa7e763), LL(0xd330e123,0xe94c1522),LL(0x853e450e,0xcf570b75),LL(0x8c60e503,0x7b779c33),L_(0x372ea779), + LL(0xb7a09ebb,0xb7df5c36),LL(0x6843f859,0xda7c16c6),LL(0xea76230d,0xe12538a4),L_(0x3c692e2d), LL(0x35168d67,0x22a3c5aa),LL(0xcf2d3469,0x90a1a3b7),LL(0x488f516d,0x4a17692d),L_(0xa3eac98f), + LL(0x979163b0,0x5261367c),LL(0xa9ef4f26,0x2b64c77e),LL(0x121123d3,0x57b5327b),L_(0xbd85c013), LL(0x60be5341,0x4320f770),LL(0x376a3aff,0x80d5de37),LL(0xbfa35c85,0x804730a8),L_(0xe518a7ff), + LL(0xfec3e94d,0xe49a8416),LL(0x5dc38222,0xebea12bc),LL(0xd561b8e1,0x1b6939a7),L_(0x839a2cae), LL(0x689cf9a5,0x0a52d61b),LL(0x69ef35c2,0x2707af62),LL(0x00163171,0x888d6c2f),L_(0x7f4b170c), + LL(0xcfab7c65,0xd2cae7f9),LL(0x327075e0,0x10e60343),LL(0x1e1d00e2,0xb1b2d682),L_(0x25112a63), LL(0xbc56c4aa,0x87923cc3),LL(0x3318db1b,0x05fa3aa6),LL(0x07ea55ed,0x08a82010),L_(0x759b62e0), + LL(0x5178b724,0x10a520c7),LL(0x4dacb0ee,0xb1fffc0c),LL(0xbbad0a50,0xab6af890),L_(0xdf72a4c4), LL(0xf8407691,0x2bcfca02),LL(0xeabf10ce,0x56944f45),LL(0xaab35dc1,0xa5c174f8),L_(0x319513dc), + LL(0xd8227573,0xfd6ac99b),LL(0x15483af2,0x4081f3db),LL(0x7e998f3d,0x08e76dcc),L_(0x6a8419c8), LL(0x1c7b8f2c,0x0551cbe8),LL(0xb6e1d5cf,0x045398f6),LL(0x93712a63,0x31b716ac),L_(0xc002e0c5), + LL(0xf2590189,0x1074bc24),LL(0xb0d09d0a,0x9d9df6f5),LL(0x1a06a2f7,0xf880ea5b),L_(0x633280dd), LL(0xe509ec7b,0xc7021265),LL(0x2310dabb,0xe9189561),LL(0x09271f5a,0x910bdd23),L_(0x633a882b), + LL(0x258fd823,0x28518543),LL(0xc6491408,0x338b1787),LL(0xc4796256,0x636fbcb3),L_(0xe0ed072a), LL(0x0aff7ca1,0x9306ff92),LL(0x8d3bca69,0x6a18552b),LL(0x5ba5cce7,0x563c7d80),L_(0xb0af6818), + LL(0x0a2d6942,0x682b34d2),LL(0xab8f78d9,0x467f7fe4),LL(0xa7e4e833,0xfb7c4f69),L_(0x0e7bfaa4), LL(0xd5513496,0xc4ac863c),LL(0x9b356137,0x74229c34),LL(0xd5e5f34b,0x729a99ef),L_(0x3111277a), + LL(0xca92d3bf,0xacf9987e),LL(0x5bcd837b,0x84c9d53e),LL(0xa434a89c,0x0ac3dbe1),L_(0xcc196982), LL(0x05a4b105,0xbbe7f4a2),LL(0xdc365bca,0x2222c71f),LL(0x0091add4,0x5e600780),L_(0xc0e95213), + LL(0xe0a35b2a,0x5acac230),LL(0x8afcf7dd,0x5089506e),LL(0x57de9730,0xf05a525b),L_(0x91a6dc15), LL(0x8c76bd09,0x74d9f43b),LL(0xa8508401,0xdca2c05b),LL(0x4bcbac2f,0xdc6633b9),L_(0x369c598b), + LL(0x1bc30bdf,0xa7ddd558),LL(0x2b2504d6,0xe21dd977),LL(0x66baebc4,0xb4d573cb),L_(0x9f9fe00a), LL(0x352d2cef,0x3c8cf82d),LL(0x5dca0593,0x12474a96),LL(0x8d29a0c1,0x55049164),L_(0x861192c4), + LL(0x8806d22e,0x827b3141),LL(0x25ab2860,0xc0bcac45),LL(0x45f1bee6,0xe2c1046e),L_(0xc00e053d), LL(0x0b973abf,0xc60d4681),LL(0xa5d34050,0x05dd04f3),LL(0x1ae3e5bf,0x64bbe857),L_(0xc97287f7), +}, +/* digit=10 base_pwr=2^70 */ +{ + LL(0xa40697e4,0x6dcf122e),LL(0xe4c0167a,0x179d681e),LL(0x177fcb32,0x2e1c6f2e),L_(0x52ddbb12), LL(0xdfe5e465,0x4c70a028),LL(0xd6ef3161,0x6183ea61),LL(0x4d64db2b,0xd053bce3),L_(0x260d4eb6), + LL(0xe6f3cece,0x3c37feb1),LL(0xc31c16a4,0x857f0262),LL(0xbbc0b11e,0x091b8ddb),L_(0x5637b740), LL(0x8541cfa7,0x772c3ab4),LL(0xc2c0eb60,0x71e71bdf),LL(0xcd2d8bee,0xd29d11b6),L_(0xb9533c16), + LL(0x4b9ffc6b,0x8ee5427c),LL(0x10f45410,0x997ab138),LL(0xff6b61a7,0x3b574c18),L_(0x394db51a), LL(0xbeade6c7,0x315f47ce),LL(0x04f8a73c,0xc77bac27),LL(0x39f2d0a5,0x28b192db),L_(0x2934b689), + LL(0xdfa7909f,0x374a8799),LL(0x3c94fdda,0x121579dd),LL(0xb4c9c6a6,0x2b2a2fe1),L_(0x56fd5e90), LL(0x2dec18ba,0x467e925a),LL(0x8c9027cd,0x51b39838),LL(0x33d05082,0x6dd45eec),L_(0xbdecbc09), + LL(0xe4793da1,0xce68ae65),LL(0x1c93f463,0xdf1eb924),LL(0x67519764,0xa6d12a17),L_(0x50dd0b17), LL(0x1e13ad02,0x43f0840b),LL(0x88680227,0x648dece5),LL(0x0b8a73e1,0x9e1099c5),L_(0x6364790c), + LL(0x00e5b508,0x16e7b26d),LL(0x41d10bda,0x2fb5b17c),LL(0xf5f94483,0x964b96f7),L_(0xc11a04d1), LL(0xb577452c,0x8083550f),LL(0x8030936a,0x2f106bf6),LL(0xe11783de,0x0cfd54c0),L_(0x4ef38a16), + LL(0xd3bf6d03,0x6afe9c51),LL(0x54c55faa,0xbb0f1cd8),LL(0xb0816531,0x27df4a0c),L_(0xa678d64c), LL(0x72f5b39c,0xc24bf200),LL(0x0cc6c1f6,0x39525315),LL(0x2d46495a,0x758c33c9),L_(0xd07deb3e), + LL(0x9c7bf29a,0x2cb77bd8),LL(0xb9eef76b,0xb7245ac8),LL(0x0a33b879,0xe50ef27d),L_(0x90583d39), LL(0xb91f697a,0x1ca8036c),LL(0x3704acdb,0xbee50919),LL(0xf053ecd4,0xece7c952),L_(0xc1b42c32), + LL(0x990b1bde,0x0420911c),LL(0x39fa1b1a,0x4138b100),LL(0xafe94d6f,0x24ff9ef4),L_(0x17756d00), LL(0x528a709c,0xa50cb647),LL(0x66685df4,0xbb306764),LL(0x907cbbc6,0x74217b89),L_(0xb3971d2c), + LL(0x0bab31b7,0xcccd2b33),LL(0x73e2182d,0x5f8e6b04),LL(0xb7efd33b,0x4cd501f3),L_(0xf5c8e01b), LL(0x83d20ea3,0xf475121c),LL(0xb4c7ec19,0x47427d10),LL(0x6eb988c6,0x7acc59a0),L_(0xee8542ac), + LL(0x591ee336,0x16ee1f0b),LL(0xbd069c60,0x27985f4f),LL(0x7a51d8bb,0xfe74d9ab),L_(0x699af4f3), LL(0xaa92cd9e,0x9ed60020),LL(0xddd73047,0x2a0eac86),LL(0x18315901,0x8dbf60b9),L_(0xd894e7a4), + LL(0xaaf7ef60,0x3d3b7078),LL(0x1892a0ca,0xf09fd9b4),LL(0x00b8f278,0xf7dd85ca),L_(0x18c0622f), LL(0x54e7df9e,0xe305da30),LL(0xf030f7b0,0x67dd41aa),LL(0x88c0e226,0xc437eba8),L_(0xbebf59f2), + LL(0x938be7f7,0x7f0d8c8a),LL(0x93333f94,0x74f9489c),LL(0xba77e9c0,0x529b3458),L_(0x5132809e), LL(0xfea9f3ed,0x93d7e4fe),LL(0x2d6cdf17,0xce0cdb8b),LL(0x1c3846b0,0xe0a036d5),L_(0x41588868), + LL(0x3b25f1dd,0x640f0895),LL(0xa1b0f513,0x6a36628c),LL(0x0a1631ee,0x22c92416),L_(0x57e72f37), LL(0xb5997003,0xa3c8067e),LL(0x34446f40,0xe28f2eda),LL(0xca50379b,0x0c2d44ef),L_(0x86add37e), + LL(0x1879da9b,0xf1be18cc),LL(0xc9b308fd,0x5708ec7f),LL(0x088da37b,0xa743ca6b),L_(0x8175ae9b), LL(0xd86f2e96,0x9bf8faf1),LL(0x3935839e,0xae7389fc),LL(0x784c1096,0x1aa41e81),L_(0x5ea779cf), + LL(0x2380678f,0xe93e1c94),LL(0x38fe23d2,0x68003338),LL(0xa4954b13,0xfa7015a9),L_(0x065ec161), LL(0x3e892822,0x19b8125b),LL(0xaf0c1860,0xd66a6abf),LL(0x8579e7ef,0x7516c1ae),L_(0x9c6fa132), + LL(0x8051f522,0xfd3b4b27),LL(0xc58d2a96,0x89473859),LL(0x8c0cdac3,0xd7eaeef0),L_(0xdea9f3b9), LL(0x0639dd0d,0x862785aa),LL(0x6333d5f0,0xd61bc685),LL(0xd861b3a5,0x83d3ee5e),L_(0x3b940e97), + LL(0xb145ba08,0x2aaf9072),LL(0xc3f907fa,0x2f3077a0),LL(0xbc426169,0xc99c4c21),L_(0x6cffa60c), LL(0x6ee68684,0x236b0866),LL(0x2624e5dc,0xe6b22138),LL(0xaa9f8c57,0xc8cde662),L_(0x93a86894), + LL(0xcedbdd1b,0x51eec28a),LL(0xd594682e,0xd4deae6d),LL(0x9e368887,0xaded26ea),L_(0x12b6da79), LL(0xf79fe22a,0xa610dbd9),LL(0x29369dca,0xc8e53035),LL(0x8d4db547,0x6d7b9831),L_(0xe42e7214), + LL(0x6d88e9db,0xaf929b4d),LL(0x7078cb4c,0x09f3ff8a),LL(0x2c88cea6,0x95aa1478),L_(0x4aa22af5), LL(0x4d819417,0xe1f9b46c),LL(0xc564232b,0x3fdecbde),LL(0x368fe183,0xce1f9cb4),L_(0x091d0d56), + LL(0xb55224a6,0xc92c61ce),LL(0x12d8c2ac,0xe42fc5df),LL(0xbae2229f,0x3afc274c),L_(0xaa2d85b2), LL(0x85cd8bfd,0x97118ed0),LL(0x3f0f7abe,0x5e361376),LL(0xaaf47545,0xcad4d556),L_(0x5d8ce6e2), + LL(0x18d8ff5d,0x18b51ba2),LL(0x38eb90ea,0xaf0eee18),LL(0xfc1b2868,0xbb73ea5a),L_(0x04dbbb13), LL(0x88d94a30,0x730a7041),LL(0xecbbc48f,0xd183ab02),LL(0x9867c6b2,0xf198711f),L_(0x29700a86), + LL(0xf225ca3b,0xebadfce9),LL(0xac6e8138,0x7b3285ff),LL(0x09069b77,0x1091afcf),L_(0x7e8bc830), LL(0xdcc4bc5e,0xf1844abf),LL(0xcca811f9,0xf655f51b),LL(0x7e393926,0xa022dcd5),L_(0x7d04ce77), + LL(0x32d143d7,0x07002476),LL(0x4ba2c132,0x028e4eab),LL(0xf7ed9d04,0x65e3cb55),L_(0xec4c3928), LL(0x1cab2512,0xdf940bc6),LL(0x738a5390,0x734bf044),LL(0x2643f52d,0x11593f75),L_(0xdd379063), + LL(0x1759457c,0xcee75815),LL(0x09e08c84,0xbfd1d973),LL(0x5f64050d,0x6b3087eb),L_(0x15138f44), LL(0xc0453460,0x776dfb51),LL(0x19bde576,0x07f4f3a2),LL(0xb17003a3,0xb6a6cf4d),L_(0x25dd19eb), + LL(0x53f04643,0x8525ef52),LL(0xa60e3c60,0x9a0888e3),LL(0xde6f955e,0xda028b89),L_(0x6d89bc76), LL(0x2711d947,0xd109e67e),LL(0xb2e621ad,0x19b5f6ef),LL(0x75754b8c,0x85c8d6d5),L_(0xbd6dfaf2), + LL(0x0a0de3ce,0x725322a6),LL(0x6f41138b,0xabf6f3c3),LL(0xeb4d3502,0x6dfedcca),L_(0xcf8c4120), LL(0x08adcae8,0x33d4bd69),LL(0x1e238409,0xcfe1b692),LL(0x659e68b8,0x82c86924),L_(0xed3a9241), + LL(0xd351d4d8,0x141df0b6),LL(0x232a8ee6,0xaaee8341),LL(0x6a97a114,0xaafe4f6c),L_(0x3cb8f982), LL(0x3ce36b0a,0x4106201e),LL(0x96a879e9,0x40106385),LL(0xfda3c463,0x9e471096),L_(0x3f6ed17a), + LL(0x15f6014d,0xb5217d60),LL(0x166ccebf,0x421c3d60),LL(0xcc23ecec,0xc0f18f53),L_(0xde559d43), LL(0x1ae450bb,0xf66ae880),LL(0x7de0a653,0x2e31cf5a),LL(0x1b3a8046,0x916c70ac),L_(0xf73fb01a), + LL(0xd287d1cb,0x3e47dc5d),LL(0x70eb7ae0,0x42cffa9a),LL(0xc6ddb9b7,0xb751c3c5),L_(0xb82e85ea), LL(0x7f3bfdc4,0x8676c057),LL(0x711d3839,0x2f6a12cb),LL(0x4e43cafd,0x273385a8),L_(0x94a8904e), + LL(0x1d472cf9,0xb53ac163),LL(0xc380e03f,0xf1c57e23),LL(0x5f7dfde3,0x53f9522b),L_(0x51e85640), LL(0xf3d29714,0x3c47cbaf),LL(0xc0110dc8,0x561e0754),LL(0xbe952c4a,0x6bcd178c),L_(0xba15112f), + LL(0x24b41db7,0x36a421ac),LL(0x98891ee6,0xdc178876),LL(0x619cb9a4,0xa266089e),L_(0x9c33f043), LL(0x9fd8767e,0xba9a6d1f),LL(0x20bce515,0x8cbdf583),LL(0x46c198f4,0x23f49a00),L_(0x847b2ffd), + LL(0x281cc4ea,0xc3d2804e),LL(0xdb1f2dbb,0x22a16678),LL(0x638a7949,0x7ec2aa7b),L_(0x9a43ca9e), LL(0x187243a6,0xb99ca6d8),LL(0xd4fc6e37,0x2d4040d0),LL(0xbd604fb9,0x8cefbced),L_(0x1938ccf3), + LL(0xfbd9e1c5,0xd10937a9),LL(0x2f42feaf,0x2fa67093),LL(0xe7b103db,0xb57b1840),L_(0xe03cfeaf), LL(0x1368261e,0x719e1d06),LL(0xfa867b56,0x192c11f4),LL(0xa6cd197f,0x9b41db84),L_(0xc6acf157), + LL(0xd68a5a4a,0xddd06586),LL(0xe7a17b19,0x52664a67),LL(0x2621ebc3,0x6f5736f5),L_(0xc8afa211), LL(0xd267f259,0xbacb7a85),LL(0x15b16a2a,0x5c0b0c67),LL(0xaa7c18e3,0x166ad375),L_(0xd0350e8d), + LL(0x9a21bdff,0x8411fa8b),LL(0x6d5b0f02,0xde70b24c),LL(0xf5bd9bc8,0xd7443ed1),L_(0x996aa702), LL(0x2b84584f,0x3ea3f8f2),LL(0x373c9339,0x099fde12),LL(0xbc0565bd,0x8fd32c81),L_(0xf5bc6acd), + LL(0x7e78ce17,0x12d214f6),LL(0x2fbd45bf,0x5f204c64),LL(0xaf966aac,0x62d03da4),L_(0x3d6e4888), LL(0x0fc086e6,0x14494699),LL(0x61bbb841,0xcc71f940),LL(0xec60a687,0x65805046),L_(0x1641dea6), + LL(0x1ee6996c,0x8eb81a1a),LL(0xa5c29c33,0x547ea700),LL(0x71308d2f,0x9126c06e),L_(0xb4936b4c), LL(0x5fecdc41,0x49cacc43),LL(0x7029bedd,0x89bc7a7f),LL(0x6331b109,0x93db1b8f),L_(0x60235335), + LL(0x18292506,0x93a8f9cc),LL(0x0c3b64eb,0x8d658c23),LL(0x33eef875,0xc22c9665),L_(0xd49b8f05), LL(0x2081f85e,0xbea17435),LL(0xc230d670,0x6f44daf4),LL(0x5ff2900d,0xdea368bd),L_(0x4f64c46a), + LL(0xfcb125d6,0x097e443e),LL(0x9f812e98,0x96ff5377),LL(0x0cce254b,0x562b2166),L_(0xddbade23), LL(0x73e36237,0x992060e2),LL(0xbca2c3a8,0xa968d30e),LL(0x139e42f9,0xe5b89488),L_(0x3ba1f60d), + LL(0x3e86ab5c,0xb177e3f9),LL(0x43f6161d,0x95050abc),LL(0x580bb577,0x75270515),L_(0x4a847f51), LL(0x0ce33d23,0xcab8647e),LL(0x9f53c335,0x139f525e),LL(0x9b1f28f4,0xa2e38250),L_(0x5690d259), + LL(0x193d7b51,0xbe57f373),LL(0x22feedbc,0x192cee98),LL(0x66699aba,0x69e0895a),L_(0x0f685742), LL(0xe787c996,0xb3f66818),LL(0xccac8670,0x5ee5c7cc),LL(0xe1645254,0xb7d10719),L_(0xae1e2e81), + LL(0x17022e02,0x2f237075),LL(0x36a4e5e4,0x01453fba),LL(0xba3615f3,0xa703f343),L_(0xd6276794), LL(0xb5aab8d0,0x30b0a7e8),LL(0x3f7b2b8e,0x33588983),LL(0x8a8547cc,0x64a4028c),L_(0x0ac79b94), + LL(0xbbdec908,0x6c0cb953),LL(0x9af46a78,0xf8e40103),LL(0xca5b89e3,0x5e56c8f6),L_(0x7d134424), LL(0x040b1ce5,0x76bd7772),LL(0xff8f0795,0x396f023d),LL(0x6bb455f6,0x4243e710),L_(0xbe0cd278), + LL(0xff00cfcf,0x7a3a34e7),LL(0x8154829a,0x59745afe),LL(0x13dec9bb,0x00460ef4),L_(0x7d4cb470), LL(0x664b5768,0x467ad23b),LL(0xa9eb5d4a,0xd6ac872c),LL(0xc30f32ed,0x7527a687),L_(0x3f334a32), + LL(0xf2877172,0xa577b4e7),LL(0x50267b62,0x7ac6ab0a),LL(0xbbb22aab,0xce8c4374),L_(0xb58c0879), LL(0x5d2444bc,0x1362bb86),LL(0x6236944e,0xa58498c8),LL(0x03a3218e,0x4585f77c),L_(0xd30bdc81), + LL(0xe1c0eb9a,0xf69271e6),LL(0xf6273f18,0x239476a1),LL(0x3701952a,0xb94d2063),L_(0xe82c2b26), LL(0x39ed615b,0x44f390c3),LL(0x90593547,0xa4418ea5),LL(0x1ce9df6c,0x76cd5c55),L_(0xda44a03e), + LL(0xf5dcc901,0x62fd7874),LL(0xcf83396e,0x74f61b6b),LL(0x9d3a5873,0x10ca6b61),L_(0x5ef1b62a), LL(0x848244dd,0x81922f08),LL(0x3ee1023e,0xbc236621),LL(0xb2a50ed6,0x0cbc779a),L_(0xb8fa6a49), + LL(0x4914c41a,0xb8a19540),LL(0x430e8c3d,0x957adbf0),LL(0xd2aac8dc,0x64d6ca82),L_(0xd8b3157d), LL(0xdb015ecb,0x42372196),LL(0x9a5dfacf,0x05451b08),LL(0xe16c7207,0x463bc66d),L_(0x69536281), + LL(0xfc7e9660,0xb8358066),LL(0x918a74d2,0xa1915c8b),LL(0x8d26603b,0xfdddd6dc),L_(0xfe3b2017), LL(0x2166a1d3,0x79912871),LL(0x71bd6832,0xe96aa265),LL(0x98a560dc,0x43b8858b),L_(0x3b4e1e7b), + LL(0x2d3f3786,0x95813382),LL(0x6e6cb17c,0x89e2322f),LL(0x3568d961,0xfbe11c03),L_(0x5e1857de), LL(0xb0011b62,0xb6d17af8),LL(0x76372b21,0xfa35ee62),LL(0x88f30207,0x496e0cfb),L_(0x1eab8b49), + LL(0x233a4ea3,0xed225296),LL(0xfbf21df5,0x18a0b19e),LL(0x49f70f9b,0xfd4a3974),L_(0xff579fa6), LL(0x6935d1e1,0x4ca49b02),LL(0x5398c8d2,0x465d1798),LL(0x83dab70c,0x3925587b),L_(0xc2e61a09), + LL(0xadc74708,0x97b00e28),LL(0x822c5927,0x4ea78214),LL(0x29de362e,0xe0075db8),L_(0xf94b10e6), LL(0xcd9ea163,0x4071fbdd),LL(0xa89e9ce3,0x5861958d),LL(0xb0f23643,0xfb6d160c),L_(0x2e57bc83), + LL(0x1cf01491,0xfd9abd17),LL(0x59f1c903,0xfdabdb45),LL(0xfe106ce3,0x28aec19b),L_(0x1e243bfb), LL(0x5dea7b0f,0x9dd7eace),LL(0x0d4e5c7f,0x7aa326d1),LL(0x58144fba,0x0c0b55eb),L_(0xf89a2bf1), + LL(0xf492b1ff,0x80211303),LL(0x4c3d5f56,0xa0a42f80),LL(0x812c4f34,0x0513dab5),L_(0xb494414d), LL(0x2b196b3e,0x8292825d),LL(0x845aa8d7,0xfccdef2e),LL(0x8309d41f,0xa6c098eb),L_(0x8feed613), + LL(0xe5e506e6,0x34984e59),LL(0xa9dc7b02,0xc78ed700),LL(0x023cf8a4,0x8818f370),L_(0xb1fe8a66), LL(0xedb22c01,0x61bbfcfe),LL(0xcc714f92,0x4b1c28be),LL(0x87de5c20,0x13f66db8),L_(0x523fa798), + LL(0x311b814d,0x18478ee8),LL(0xc54ff99c,0x5fc08d54),LL(0x3d6c85b2,0x2a4234ef),L_(0xd3a39852), LL(0xef0ad115,0xfa0e9b48),LL(0xdfcd9d52,0xded54ff0),LL(0x8d2d8068,0xe6033e94),L_(0x39c4cac0), + LL(0x567ac24b,0x31e079f2),LL(0x595877b2,0x876a06e1),LL(0xd77d6297,0xabca81b2),L_(0x0324c3ba), LL(0x27382ebe,0xbd7f7ff0),LL(0x5a3b92f8,0xb11d9de0),LL(0x31e36d28,0xba48fe41),L_(0x3263cd91), + LL(0x845700c2,0x659750c3),LL(0x265533c8,0xbfa2263b),LL(0x46779254,0x426c9332),L_(0x73f00210), LL(0xc0627927,0x919159e1),LL(0xc1896bdf,0xb8633c7d),LL(0x62049111,0x57a02e38),L_(0x159b1b0e), + LL(0xc0ef9c33,0x87339367),LL(0x80f32c7a,0xd690f5fd),LL(0x4cb8372b,0x74004a4c),L_(0x92a5a93f), LL(0x62fc7f7f,0xc75eca95),LL(0x2883c5ec,0x87991514),LL(0x1a3939cc,0x9eeab34e),L_(0x57489f74), + LL(0x6dda4270,0xe95ee7c3),LL(0x68b80ca0,0x5637d166),LL(0x0cc0434e,0x108326a5),L_(0x11ccac8e), LL(0x66908f8f,0x768a4dc5),LL(0xe0516b2b,0x24086620),LL(0x0390f0a6,0x34cd95fd),L_(0xb3965e3d), + LL(0xa579c74b,0xf4d1cd8b),LL(0x2437af0c,0xa682fc6c),LL(0xcf5b3a95,0x13389ce6),L_(0x0026ae74), LL(0xc24a47b5,0xf37dbb35),LL(0xf06e1e15,0x9d47aaf6),LL(0x196773ed,0xab42affb),L_(0x76bb4374), + LL(0x78457341,0x0583dc84),LL(0x564d9444,0x6a0c10e4),LL(0xbf46a7bb,0xe6adebac),L_(0x93e051d2), LL(0x3e924b68,0xbf5e7329),LL(0x4afb1643,0x9cb33af1),LL(0x5460942b,0x1005e77d),L_(0x483528ac), + LL(0xa399de32,0x867305ce),LL(0x19e34f30,0x2200477c),LL(0xd31a5a81,0x9ac2ed5d),L_(0xa22c4024), LL(0xa5a011ec,0x9cb94041),LL(0xadcbd258,0xf7a7e8fd),LL(0x26131e4c,0xbcae3bd4),L_(0xa63111af), +}, +/* digit=11 base_pwr=2^77 */ +{ + LL(0xe00bdded,0x44e43c61),LL(0x2a3a0320,0xc584d310),LL(0xb6fe7f05,0x951b39e7),L_(0x1c47e70b), LL(0x1eae5fc6,0x518f5441),LL(0x5cd44db2,0xc505aeda),LL(0x216fb5f2,0xbb781e43),L_(0x7e14b38e), + LL(0xf9a62c2b,0xe0d93869),LL(0x60f3a9a1,0x6d3f0de7),LL(0xb3106bbb,0xb0f77641),L_(0xc3071383), LL(0x9b298ebc,0x184aed09),LL(0x0bacf017,0x334394d4),LL(0x79c1d22f,0xd95473d2),L_(0x93838083), + LL(0xcb7cb58a,0xf3fc070e),LL(0xed4652fb,0x60dba7d5),LL(0xe19d60f2,0xe420c869),L_(0x51893296), LL(0x097e4dab,0x707e030c),LL(0xd90a9475,0x0dcda4fc),LL(0x9803c9fe,0x2bbc44ce),L_(0xa6483469), + LL(0xfabcb24a,0x10355326),LL(0xdcb5236b,0x91ed19ce),LL(0x4f316ca1,0xd20efc4e),L_(0xd00bff40), LL(0x1a2e490d,0x2b83ac01),LL(0x96a6cfc6,0x0fd81acf),LL(0x8da694f8,0xfcad677f),L_(0x6bf5e71f), + LL(0x248ec9b4,0x11ef88d2),LL(0xe791a3bc,0xda678712),LL(0x370ca0ea,0x7a293625),L_(0x4e4cd7d7), LL(0xddfa0a4e,0x1f856294),LL(0x180b43b4,0x6bd2e637),LL(0xf728ccb4,0x91baf444),L_(0xe5fa917a), + LL(0x9e4adc26,0x8981411a),LL(0x6d65f85a,0x7eb4dd2d),LL(0x58e82e86,0x97c312ce),L_(0x8bfebe6a), LL(0xd7b84e09,0xc95c8ff2),LL(0x639198d0,0xd7ac3654),LL(0x7546fc40,0x504a9f59),L_(0xeac2deb7), + LL(0x9edb0426,0x476b8958),LL(0xa2e1a729,0xf14565b5),LL(0x4bab1b96,0x3d3ca262),L_(0xc0e1a0ef), LL(0xfd4e9a48,0x0043c8ff),LL(0xba0665c7,0xafaf8910),LL(0x0b1e0a8d,0xcbeb2d8e),L_(0xe710e7f4), + LL(0xebbefd51,0x44fc634e),LL(0x2a776b18,0x9ddeace8),LL(0x08a9107e,0x909eff4c),L_(0xb7934059), LL(0xf816fa9f,0xefd70514),LL(0xfaad7709,0x598db9de),LL(0x0094b64c,0xc6634c12),L_(0x8b95add1), + LL(0xd6fb5d4c,0xadb1a9c2),LL(0xd2967310,0xc8ec0f39),LL(0x1908657d,0xa25710b3),L_(0x19a27dfc), LL(0x311947c4,0xe187cb1c),LL(0x8cbb3e59,0x1bae3f86),LL(0xafb6e7b5,0x44ea2977),L_(0x781e26f2), + LL(0xee18a383,0x60b120f0),LL(0x24a67462,0x91636563),LL(0x29fd66f4,0x6538f012),L_(0x1b5c47df), LL(0xda52b57b,0x9a0bd35b),LL(0xd095d4fe,0xcee45c94),LL(0xafb1fcae,0x042232d0),L_(0xcff50cb9), + LL(0x54397158,0xd06ed8f6),LL(0xd53d3bfe,0x67644c3e),LL(0xaa8e6af8,0xa26425e0),L_(0x1f9101fd), LL(0x6fb8009e,0xdfa5a71f),LL(0x7b2b6229,0xc4fb8d84),LL(0x413c2883,0xa71e26d8),L_(0x442bf1c5), + LL(0xae3de434,0x45610301),LL(0x828b8be8,0x4ec1365e),LL(0xb95b637d,0x41dbce62),L_(0x1ca7419f), LL(0x9637a66f,0xc6d80952),LL(0x5a685913,0x9289159f),LL(0x761cc88a,0x1da0d501),L_(0xf7bfb795), + LL(0x37a59563,0xb4ca54d1),LL(0xe2ccd3ff,0x5128864b),LL(0x8aad87e4,0x559dacdc),L_(0xdf79df2f), LL(0x89718ac8,0xea353321),LL(0xe6676310,0x2012406a),LL(0xc599f213,0x1eb2fe94),L_(0x626c9f76), + LL(0xba62fad3,0xa7fededf),LL(0x6ff23700,0xd58195f8),LL(0xd3d6b5bf,0x1ad1505f),L_(0x97f82bb0), LL(0x6f93c77b,0xaf96dc4e),LL(0x30b1fb3e,0x20624dad),LL(0x4fa52512,0x3481aabe),L_(0x78a7c4e4), + LL(0xba1c1391,0x9fb8e966),LL(0x5ff12f04,0xb9c0dea0),LL(0xd59d1993,0xe8a99c53),L_(0x6cef1107), LL(0xb44f7478,0x97335f28),LL(0x400e3354,0x6f550c81),LL(0x3749bb24,0x67501a21),L_(0xdbc433a0), + LL(0x2ddbdad7,0x5e95c8ee),LL(0xf4a3dab8,0x74fa6bf7),LL(0xf68aac5d,0xe404df62),L_(0xca08be37), LL(0xf3252764,0x934f4963),LL(0x6033be81,0x65ea023b),LL(0x39f3ad81,0xf2ab45c6),L_(0xec27db5a), + LL(0x6c9e60de,0xd82ebdb2),LL(0x3c94302c,0xf4278e99),LL(0xf76b6d5d,0x177bfa74),L_(0xaec52e0d), LL(0x0698c8f8,0x8af11d92),LL(0xdc8707e7,0xdcfeb87c),LL(0xdf966b87,0x790b8b3b),L_(0x25a49666), + LL(0x0d632c2e,0x82b42706),LL(0xca5f0400,0xeb7e23be),LL(0x67d13334,0x6bef8f5e),L_(0x19a89324), LL(0x5b9d7908,0xb943b3e3),LL(0xe69dc86d,0xe1142402),LL(0xe61e180e,0x3186f5ab),L_(0x5490857c), + LL(0xee73f3c9,0x1c021526),LL(0x229aab7e,0xd5f0330f),LL(0xbcd8ae19,0x34f15f5c),L_(0xab3c7439), LL(0x0f2d33f9,0xf2452d93),LL(0x23f2f3b0,0x0c4b0f70),LL(0x322c677d,0x311431b5),L_(0xc0e186a5), + LL(0xd222f30b,0x32c8e92e),LL(0xb855ce32,0xf9051d2c),LL(0x34079f7e,0xca51b73e),L_(0x1cd08eae), LL(0xe4529fd6,0x3ee05e30),LL(0x48ccde21,0x762211ba),LL(0x957b54a8,0x7bd842d1),L_(0x8ad2f209), + LL(0x8578a05b,0xf931c6ff),LL(0x22b12a51,0x9c1a24ae),LL(0xc7ad186b,0x3aae7e80),L_(0x35a3a465), LL(0xcd94ffe9,0x02d60546),LL(0x02a0030e,0x6d8dfc51),LL(0xf70532cd,0xa7523214),L_(0xbfa52fcd), + LL(0x3898ac4a,0x7ef15aa2),LL(0x04a67481,0xc92d3e61),LL(0x6f146470,0x20a65e93),L_(0x091a434a), LL(0x40c2ff2f,0x5f5f4b1f),LL(0x356b539d,0xef24d37f),LL(0xf5eb8c60,0xd0f3625a),L_(0x5662e1cc), + LL(0x04af9658,0x0ddb7f8a),LL(0xd47a8579,0xf5679a0d),LL(0xfa164f3a,0x75f9e25f),L_(0x88f00eb9), LL(0xd2b96f54,0xc75b8bfb),LL(0xc45f8fe0,0x141dae1d),LL(0xf86c989c,0x1a015ae9),L_(0x4cbe108d), + LL(0x7440165c,0x252d3538),LL(0x94ed0d57,0xc7935e6e),LL(0xfc485299,0xafc2b1d4),L_(0x2763b62a), LL(0x8b5606a9,0x8714fa4e),LL(0x44261681,0xd015855f),LL(0x03679b60,0x14d9de29),L_(0x84a487b9), + LL(0x7fd6372b,0x1fc76dfc),LL(0x30d60bc9,0x835ac98b),LL(0xec54c6b2,0x98cbc171),L_(0xa2ec0376), LL(0x7ab5c98b,0x577a8e9f),LL(0x527bb2a1,0x84028fa5),LL(0xed0d2362,0xb28e8d67),L_(0x1a1d5c1c), + LL(0xd8c85ac3,0x8e20b175),LL(0xe895347f,0xbc82df9e),LL(0x763f7da0,0xc32cc81d),L_(0xd889ef15), LL(0xb02c89ce,0xd305dbab),LL(0xb02c2e9f,0x7f0a99ef),LL(0xd40823f0,0xf958bb39),L_(0x7a07c7e4), + LL(0xee84ea34,0xc5f043e5),LL(0xea668125,0x13f7ae2f),LL(0x18438628,0xb6ffaed5),L_(0xf72f62c4), LL(0x9cb2856e,0x9a5c926d),LL(0xade5a9b1,0xad05632a),LL(0x4d11a1b7,0xf0f2c69d),L_(0xbfed0dd6), + LL(0x60b10c55,0x79943f17),LL(0x930f1ce1,0x15056514),LL(0x70dc2681,0xc9a17b25),L_(0x71659c78), LL(0x4d9c29ff,0x5978aada),LL(0x56151f6b,0x6e84fa9d),LL(0xb01cfa96,0xd9553cbf),L_(0x495ffa1c), + LL(0x14645de0,0x50569b84),LL(0x516171cb,0x76814e1a),LL(0x6931ce3c,0xd1694dea),L_(0x18d486a7), LL(0x8fb4ec93,0xcbd84ece),LL(0x694d8a81,0x70c2d8a8),LL(0x6f1a63f5,0x2ca687fd),L_(0x6788bb91), + LL(0x66719259,0x78b1b1f1),LL(0xa8fe9c13,0x372aba7a),LL(0xf72aecd5,0x049424c7),L_(0x8c2a627b), LL(0x12996520,0x7a3d9b21),LL(0xd87c3d81,0xeea3b43c),LL(0x6296bed4,0x965623a1),L_(0xf57dda17), + LL(0x19faf24f,0xee2a75e2),LL(0xe4882684,0x2608d8d7),LL(0x5dbd9aa4,0x8dd2d8bb),L_(0x1861b78b), LL(0x96024e0a,0x59608369),LL(0x2a96c634,0x3109b985),LL(0x4c72f34b,0x073affe7),L_(0x5e2a53e1), + LL(0x7163417d,0xe75a8d8d),LL(0x003ea53c,0x34a71e84),LL(0xf46ea0c1,0xa472172f),L_(0x582a6663), LL(0x5941f31f,0x45ef8849),LL(0xda61e5b5,0x813628f8),LL(0xff6e6be2,0x2f6a6923),L_(0x24a1906a), + LL(0xf2dab7c1,0xee4fac0c),LL(0xcca97a61,0x442b5426),LL(0xd1572489,0x1b63f7f9),L_(0xc808b93c), LL(0x86beafa1,0x931a009d),LL(0x00b9ab37,0xc54e5dcf),LL(0xce454abb,0xe3d31b67),L_(0x8846c2ca), + LL(0x2bfb9673,0x00a46605),LL(0x6d38eb82,0xd0e900f3),LL(0xac391030,0x56b396f4),L_(0xa240554c), LL(0x111e6519,0x0e375257),LL(0x2daa1839,0x0569eb0d),LL(0x6386031f,0xa43939dc),L_(0x29a2482a), + LL(0x79006500,0x19bae3a4),LL(0xeba63f38,0x278b676b),LL(0x2bfc1210,0x5fd221ef),L_(0x18605ab3), LL(0xaddaabbd,0x3e58e744),LL(0x130a0b49,0x86211a5e),LL(0x27a20439,0x06b96609),L_(0x3be9694d), + LL(0x31e7bef9,0x6b521dbf),LL(0xe38156c6,0xbb74a0f2),LL(0x41f4bd94,0x79699c57),L_(0x565687a7), LL(0x6af2b091,0xb9a903de),LL(0x15159b8e,0x250d78d4),LL(0x565e3c29,0x674edb33),L_(0x0294da46), + LL(0xfa502a7a,0x4f9ab886),LL(0xf7c92c2b,0xb5e6f603),LL(0xcd18776f,0xf25cc6e4),L_(0xa7fa7c45), LL(0x9822aa1b,0x2c1f0788),LL(0x250c2373,0xb4be8a38),LL(0x671f0157,0x5b11123b),L_(0x157f5d60), + LL(0x54914217,0x1256ef4e),LL(0x5163b441,0x075b53ab),LL(0x5ecb1889,0x56e20726),L_(0x6494b2b8), LL(0x09f26255,0xd571b91b),LL(0x9475008d,0x328d62f5),LL(0xde6fb9c6,0xe065c610),L_(0x96baaccd), + LL(0x45144de8,0xdc428059),LL(0x71bed82d,0x9aff2cca),LL(0x9af32379,0x7429380e),L_(0x02f22f65), LL(0xe3565604,0xdea72af4),LL(0x2b9bc7b9,0x2bf6a43f),LL(0x5a2add5c,0x6b6ae6f7),L_(0xb69ca1cf), + LL(0x9ab52f77,0x061d7ef8),LL(0x56d68dd3,0x010840bd),LL(0xae0d756d,0x97508e7b),L_(0xecbb738b), LL(0xadc78972,0x4d5b80a4),LL(0x4dce8c80,0xf9aaef5c),LL(0x256809bb,0xa1ec2e50),L_(0x2ea2af7c), + LL(0x74a6dd4a,0x0393f719),LL(0x93285afe,0x4e57160b),LL(0xac7e00ee,0xe124fa0e),L_(0x044bd9af), LL(0x2389bd88,0x80b4129f),LL(0x758d4e27,0x0e8aaba3),LL(0x1051debe,0x4a190f97),L_(0x85906a99), + LL(0x2156959c,0x37e2ab37),LL(0xd889d270,0xfe9b7157),LL(0x540652e0,0xd3215a27),L_(0xb88094e7), LL(0xc0c597f0,0xceb6dd56),LL(0x5dc4dd34,0x09436cb3),LL(0x07e11a08,0xc752116d),L_(0x86890fd2), + LL(0xe154e3b6,0x3dd689de),LL(0xba6c5590,0xecec9673),LL(0xf4ebc67c,0xdf67ffb0),L_(0x094d0483), LL(0x33ce85c7,0x58ffaf1b),LL(0x04f91a5f,0x741f05be),LL(0x2535c38a,0xffe3294f),L_(0xfe3e3780), + LL(0x4c921d99,0x1c787299),LL(0x8c60577e,0xbf10f0e5),LL(0x4f5e9e39,0xdd4daa07),L_(0xcf714fd4), LL(0x92fcbe08,0xf29c8618),LL(0x38ba462f,0x84305704),LL(0x8d7c9a43,0x19694aa8),L_(0xe7510556), + LL(0x680c4325,0xb1ac0982),LL(0x45857f5e,0xa4032ac9),LL(0xdf576261,0x92007d10),L_(0xc5ae1832), LL(0x755cfb3c,0xb9ea853a),LL(0xc129c1e9,0x28725f38),LL(0xa32de41e,0x8310cc56),L_(0xaf03c7c1), + LL(0x4319f045,0x6a31f14c),LL(0xbb313e19,0xf0a68d54),LL(0xa79121b3,0xf8ad5c75),L_(0x1cd6c518), LL(0x1aca6f0e,0xd728ef75),LL(0xf52ecb39,0x66ed37be),LL(0x244f6df5,0x5253f731),L_(0xc37a0916), + LL(0x7e5a8bd3,0x9d03a5af),LL(0x6b5c7a81,0xa4eb71aa),LL(0xa305f15d,0x1dc7fb76),L_(0xbf1adac7), LL(0x20487a26,0x6deaadda),LL(0xf4c07457,0xe0f4999c),LL(0x9bb84678,0xc451bb12),L_(0x975839c9), + LL(0xc977cb31,0xd39b851a),LL(0x6ac13ca0,0xcd656ca8),LL(0xa19898ab,0xafd81332),L_(0xd849f9e4), LL(0x2bb5e6b1,0xc3157a16),LL(0x5b02f0fe,0x8acd8d9d),LL(0x69cbb158,0x6d76f690),L_(0x05ce3883), + LL(0xc8ff4786,0x2bca8c99),LL(0x186098dc,0xa2caaf78),LL(0xf6be10a7,0x2100372c),L_(0x16272c0e), LL(0x761e39c7,0xdb53800d),LL(0x6551227e,0xc599f6e5),LL(0xc995d474,0xcb2cc9b4),L_(0x73233966), + LL(0x39687ef7,0xe8d0ac03),LL(0xc75c74c9,0x921b3cbb),LL(0xc64c35ba,0xa500e776),L_(0xca48727d), LL(0xe79c45b0,0x60ad3863),LL(0x2b1933ee,0x0ce33aaf),LL(0xaee36834,0x4ce8962e),L_(0xb0c0146f), + LL(0xb38c8507,0xc359f6e1),LL(0x8697a59a,0x31837b1c),LL(0x98af1b3a,0xf716fe6e),L_(0x7fdc52e3), LL(0x3830cd5c,0x52930fa5),LL(0x90fd85df,0x0ad62260),LL(0x097dfa97,0xebeb447d),L_(0xcfdb2bce), + LL(0xe409d4ed,0xe80a1b86),LL(0x4d1e34ae,0x1aaed1d3),LL(0x9eac7e33,0x80bb831f),L_(0x0bb854f1), LL(0x986f7e0c,0x005a4dc6),LL(0x6e3f9cf2,0x52827fef),LL(0x293c91f5,0xcdd9e93e),L_(0xd5679946), + LL(0x2c6558f0,0xd0ac15f2),LL(0x4e88fc97,0xa247b120),LL(0x573e9688,0xd0627f7e),L_(0x96e1d752), LL(0x22887f9f,0xd31e0ba7),LL(0xb47ea27c,0x1eea7f54),LL(0x4423561d,0xf9581051),L_(0xc8a211b5), + LL(0x42a54364,0xeb2affe7),LL(0x35c0456c,0x972ce84c),LL(0xaeca0047,0x4d9efd23),L_(0x2bdbc15a), LL(0x173fea09,0x1d890ba5),LL(0x99e5f4ba,0xfea0ad91),LL(0x5f0b0f42,0x5619484b),L_(0xb1f3e2bf), + LL(0x6cdbcee3,0xc11ff4f3),LL(0xe36e32c6,0xa260adc3),LL(0x5bb4d1a2,0x33e0dbb6),L_(0x1b1ed42c), LL(0xcaa2ba15,0x415b8922),LL(0x9bbb4478,0xb1fbde1c),LL(0xe7f63f33,0xb014bfff),L_(0xd8fe72a1), + LL(0xab510c98,0xee7b323c),LL(0x86f8b471,0x37854732),LL(0x23d6cc1a,0xdbbcc348),L_(0x14fb98ce), LL(0x64d5f136,0x6fb100cc),LL(0xa833932c,0xb27f28f5),LL(0x980b1419,0xca8834c2),L_(0x088ce8d5), + LL(0x1b1c75cb,0x8c28e4a6),LL(0x712165a2,0x2cbdb243),LL(0x1341e16e,0x5a726ab8),L_(0xfe09486b), LL(0x32264866,0x4f4a819e),LL(0xf2a151c4,0xba655f21),LL(0x37367c7d,0xd157593e),L_(0x2b7d23ec), + LL(0x46d94f55,0xc9397bab),LL(0xe0636264,0x65e56a08),LL(0xf946f4e0,0xa259e975),L_(0x55c54603), LL(0xb5060784,0xccc37d6a),LL(0x2614d3d3,0xf709343a),LL(0xfb056c2e,0x89705d36),L_(0xc8dec62e), + LL(0xeb841e0f,0x7663ad0e),LL(0xc791db86,0xb1420c30),LL(0x5792fb1a,0xaebf5ced),L_(0x462f4f9f), LL(0xeaecfdd6,0xd5142858),LL(0xc555cb9f,0xe56ab53a),LL(0xdbaff47d,0xb56ba899),L_(0x048149ff), + LL(0xd69321d0,0xa06234ff),LL(0x4da9e4a7,0x98b8cc13),LL(0x4be3eee6,0xadbfb76c),L_(0x9b536e85), LL(0x57f0cdf4,0x01e45447),LL(0x54dd6853,0xb307918b),LL(0xa0a5d2a4,0xf7e16814),L_(0x4f89fd0d), + LL(0x6c92c96c,0x865c8f6c),LL(0xee136cd4,0xf96358e5),LL(0xc0b20165,0x10dbd508),L_(0x785841fa), LL(0x990a46d5,0x1d1a7d70),LL(0xc190e469,0x6c2d572d),LL(0xa87b8f93,0x03a7ba98),L_(0x3e71c1ad), + LL(0x6d9f3e8d,0x2221d899),LL(0xc7dd63bb,0x7c844ad3),LL(0x142035bd,0x11c04771),L_(0x726cc50e), LL(0xf02e1ad2,0x78ab7d85),LL(0xc57c4d2f,0x301c5ced),LL(0x1feac0e2,0x95568955),L_(0xd216f6fc), + LL(0xc5b0ee89,0xf045ebf3),LL(0x6770bb55,0xc1ea77c3),LL(0x4e10f859,0xa44993af),L_(0xb75a3354), LL(0x38d373df,0x5c460d85),LL(0x940bd01e,0x2bdad16c),LL(0x264105cb,0xb8fc3b3e),L_(0x09401ace), + LL(0x2edb771d,0xd4ae16cd),LL(0x2b675fa3,0xc8055a0a),LL(0xdee3f3e2,0xc08d1ca2),L_(0x28ea187c), LL(0x4252a1b9,0x6d687314),LL(0xf6c34d15,0xba935b80),LL(0x3b383652,0x52c1b85d),L_(0xc5e3b405), +}, +/* digit=12 base_pwr=2^84 */ +{ + LL(0xb92b8af0,0x6354d2c9),LL(0x4c952ade,0x5a4d9e35),LL(0x0381968a,0x52d9f13a),L_(0x86c3819e), LL(0xc63b9fe7,0x3743142f),LL(0xa95b1a9a,0x6e186e52),LL(0xaea91efc,0x3de25aa0),L_(0xc91296ab), + LL(0xf8921758,0xced4216d),LL(0x02fb0911,0x28cf0cfe),LL(0xd524c877,0x03bdd0b5),L_(0xb3e00db0), LL(0xd91831de,0xd131c59b),LL(0x77e04707,0x47533185),LL(0xf492c767,0x63c30af1),L_(0x202f0676), + LL(0x79a5ddcc,0x495cdcc7),LL(0x33ab4ae3,0x7f199f52),LL(0x9d2ff41e,0xbe613bf2),L_(0xf3371b23), LL(0x967f0754,0x76c36728),LL(0xfb8be7aa,0x02af3c44),LL(0xee5a166b,0x0bda3025),L_(0xc9427cb8), + LL(0x6371852a,0x473e976c),LL(0xa5e1af16,0x88aeb436),LL(0x368ce839,0x94aabe19),L_(0x00b82580), LL(0xb19a3ec7,0x7d50b7ff),LL(0xd8fc842f,0x81c2bf45),LL(0x8c4eb78c,0xb0a7cd1f),L_(0xf40b4869), + LL(0x56f0849d,0x5739e59e),LL(0x79c44251,0x1fc64939),LL(0x8b91a3a3,0xd401b24b),L_(0xd2207cb0), LL(0x9decd9c6,0x17f178e9),LL(0xcede5d5c,0xfa904473),LL(0x7a09efc0,0xca5c00a9),L_(0x1761360d), + LL(0x6aca6f61,0x4bda0113),LL(0x3b3dcab5,0x12ccd894),LL(0xb4db3fdf,0xb39be04f),L_(0x1c09bf2c), LL(0xb4705566,0xccbe5154),LL(0xe1559ff1,0xd84fec44),LL(0x11964906,0x9ceede3f),L_(0x0e1b9fc5), + LL(0x13111bdc,0x175d3f77),LL(0x17226b06,0xe0971341),LL(0x21244b52,0xd6fa5642),L_(0xfdbb39d3), LL(0x68da34f2,0xb9933942),LL(0x6759bac0,0xd7d7f790),LL(0xee292b1d,0x4382d48d),L_(0xd117a9f3), + LL(0xe877a209,0xaf9b8432),LL(0xa22db654,0x12572249),LL(0xbb09b923,0x1501cefc),L_(0xd5820554), LL(0xe0614220,0xaa863b6a),LL(0x397b3194,0x27337829),LL(0x1a9bf0b7,0x6912b5aa),L_(0xc767a242), + LL(0x38d01225,0xa0259e70),LL(0xf56ef5aa,0x8e85d7ee),LL(0xfd49df96,0x6bb4a230),L_(0x8f3a3f3a), LL(0x58b99e53,0x3c2be4ba),LL(0xcf1ea9c2,0xe49fcb3f),LL(0x4937a76d,0xdc9b73dc),L_(0x5ea4828a), + LL(0xa516c9ee,0x41610138),LL(0x30e01a74,0x71d5b83a),LL(0x8795351f,0x9a45e682),L_(0xa31707a8), LL(0x9edacc8e,0x17bd9c0b),LL(0x80f31bd0,0x871cc69c),LL(0x57013f03,0xb6b7b6e2),L_(0x1073b301), + LL(0x4855e4b2,0x124c67e8),LL(0x6946f5db,0xd4d7f50b),LL(0x494ae118,0xf16b9834),L_(0x0c0fe86e), LL(0x3a6a8d31,0x18d69af9),LL(0x54ebd047,0x7f8ed091),LL(0x9daffa88,0xba6e7c59),L_(0x54652a79), + LL(0x011788f6,0x9c64aa0c),LL(0x8403c566,0xf896522c),LL(0xcc8f1ea7,0x772627b7),L_(0x707ce584), LL(0x72bb812b,0x57f8a759),LL(0x4f42aa8c,0xc7e7a397),LL(0x4c06faeb,0xeea7a14b),L_(0x1edd837a), + LL(0x0c456e85,0xbacf3d29),LL(0xdb2d668c,0x861ef908),LL(0x17a88c53,0x25d01a4d),L_(0xb97ac689), LL(0x0b6e87ff,0x066301cc),LL(0x78d4d6b5,0x51763eac),LL(0xe4c44c3a,0x243f5364),L_(0x55bb2e54), + LL(0x69fe2b3f,0x623f7c06),LL(0x969019fe,0xa81b9914),LL(0xba6dd8e5,0xd33612e7),L_(0x0fd330c2), LL(0xc948497d,0x7184b686),LL(0x065a9367,0xd5e74279),LL(0xfa105e4b,0x4bfe5bea),L_(0x30ca8fc4), + LL(0x03d46275,0xfcb464d3),LL(0x7fb49121,0xdcb4ccb3),LL(0xf6934477,0xbdf563a1),L_(0x4412ba6f), LL(0x7c07acc8,0x4d4331eb),LL(0xe0dfac8b,0x768b2705),LL(0x022d151f,0xf65a4027),L_(0x251db799), + LL(0x5cbe2654,0x32707706),LL(0xbeb70e80,0x9739588e),LL(0x1d1ff202,0xe51c696a),L_(0x000ae445), LL(0xdd740418,0x25fcc7e6),LL(0x646ef912,0xac2dfbc7),LL(0x0d72b69e,0x1ff6f6ad),L_(0x059f3c0c), + LL(0x3ade75e8,0x3ac64888),LL(0x7ee14ba6,0xd957b10f),LL(0x7be01ff5,0x33f835d6),L_(0xc155847f), LL(0x45081b73,0x0c08887d),LL(0xda2f5358,0x4fc01e34),LL(0x84d416f7,0x15716e5d),L_(0x3950aa76), + LL(0xc4cafbc3,0xcd118e18),LL(0x60a29243,0x78d7034b),LL(0x4d198a7c,0x9ba63f25),L_(0x4b83593c), LL(0x81c83f83,0x9eb5e40b),LL(0xb8f7f9c2,0x3b1941e5),LL(0x27b87b90,0xb7229f73),L_(0x247578db), + LL(0x59afdea4,0xf6e5451f),LL(0xbdfb7efd,0x3c7977fc),LL(0x8262d80b,0x0ff79532),L_(0xb6d1bfa5), LL(0x85d46816,0x41a59faa),LL(0xbb16202e,0x815bfdff),LL(0xf25c4d84,0x26a648ca),L_(0x2a115df7), + LL(0xc47be93f,0x8807158f),LL(0x31f52fc1,0x71da23a7),LL(0xf790aca9,0x26957d5b),L_(0xe3199eb7), LL(0x571af638,0x3a3ff68a),LL(0xa6e9167d,0xb02eef0e),LL(0x78555759,0x1609b893),L_(0x1507c2ea), + LL(0xa99f1707,0x7a4aae59),LL(0x4be04c26,0xc84493c1),LL(0xf1b134ce,0x8f2fb8ff),L_(0xc7137a45), LL(0x8f6f7a80,0x73cd2591),LL(0x3b2e141f,0xf68459a2),LL(0xf4b9ddab,0x1d8a7278),L_(0x403dae23), + LL(0xa1fd53d2,0x3ad117de),LL(0x47d15513,0x75e31939),LL(0x58a5dfbd,0x3251c208),L_(0x66a06b3d), LL(0x8436c37d,0x65ab378a),LL(0x5a3fb858,0x3a685733),LL(0xe6172e78,0xfa11b001),L_(0x25e5c930), + LL(0x18e18997,0x48c2dc2c),LL(0x900eb7f7,0x814d21d9),LL(0x198afe84,0xf76ecf91),L_(0xab542184), LL(0xb918572f,0xf53020dd),LL(0x31471cf4,0x365cb3df),LL(0xa6a9ebf4,0xf8ad1ad6),L_(0xf3563966), + LL(0xf1859231,0xcb1be872),LL(0x1ad60df0,0xfaa10d6a),LL(0x11273c1d,0x240336fa),L_(0x4a1692f1), LL(0x6bfe9509,0x88653660),LL(0xf81505d5,0x7b0d301b),LL(0xd427be59,0xbd85a9ef),L_(0x1a92bc3d), + LL(0x72600cd8,0xe9cae1c4),LL(0xab08a5cc,0x3d1457c8),LL(0x96865fe9,0x9a1bc1e7),L_(0x438f5a09), LL(0x7727a4f6,0x09a2a9db),LL(0x33e95a6f,0x028d0a98),LL(0x9656e0c0,0x7f3b01db),L_(0xeae74794), + LL(0xb1f41609,0x060c3752),LL(0xc0ad59f7,0x6efb7250),LL(0x0bd8bd31,0x79016736),L_(0x34d2ef7f), LL(0x8739f62d,0xf14247f9),LL(0x7675377d,0x29b78fc9),LL(0x5b2e893a,0x5f2b1e7f),L_(0x3c1437bc), + LL(0x380ddade,0x014c7c14),LL(0xe37d7ead,0xc2d7837a),LL(0x78897ca3,0x5567dd34),L_(0xfa7b8f4b), LL(0x00642d56,0xf735f752),LL(0x7fd93e92,0x8afd8b87),LL(0x6eb02b4e,0x120f5319),L_(0x1ccf74f8), + LL(0x8fc31699,0x41d511e3),LL(0xb78232db,0xbdc4fb64),LL(0x9841bbd5,0x207bfaea),L_(0xd0f130c1), LL(0x38fcb8da,0x6ba5dcee),LL(0x93e47594,0x21f2d335),LL(0xf78fd1c0,0xc6f634fd),L_(0x717d258b), + LL(0x09a676cb,0x414f2daa),LL(0xa55cfcad,0x4cbc9d7a),LL(0x3b973302,0xb409e95d),L_(0x7da7223a), LL(0xd16a5ca9,0xf92a6554),LL(0xb7642b9f,0x153e5024),LL(0xa08470dd,0xae4dfb2b),L_(0x8fd81632), + LL(0x5b3c44c4,0x45031642),LL(0xc6ae8b05,0x335c400a),LL(0xd4b606ca,0x6b34a475),L_(0x4a823453), LL(0xf3ab94ff,0x746295e2),LL(0x25948202,0x4b9b612a),LL(0x9d957566,0x510e67f8),L_(0x42ddbb08), + LL(0xdc56f265,0x9f7dfe87),LL(0x20005269,0xe3386448),LL(0x104ea5b5,0xac4c4feb),L_(0x6565a54e), LL(0xb2f8650d,0x186e3514),LL(0x50e692b2,0x58c2701b),LL(0x81927ca6,0x81220e7e),L_(0xa69b1829), + LL(0x727a95ea,0xfb0e9702),LL(0xf0b23c9f,0xcca5f38b),LL(0xdb71dd75,0xad31c5dd),L_(0x93004978), LL(0x3ff02652,0x683b0e57),LL(0x2b3b008d,0xc6e32a5b),LL(0x4ab25a51,0x283f183b),L_(0x0cc76852), + LL(0x08ea3768,0xf7f76eae),LL(0xbcdd82ad,0x222dd486),LL(0x5b8927a0,0xdc4a955f),L_(0xb76f9687), LL(0x605b6b78,0xc80579f6),LL(0xb80f7796,0x4cf36f45),LL(0x94402fad,0x0a226060),L_(0x0c94e0f7), + LL(0x77db1b5e,0x4fe36153),LL(0xb19d463f,0xb32ea8ef),LL(0xa09373a7,0xd4f68719),L_(0x1f1869b7), LL(0xd8828434,0x8c0026e9),LL(0x8f8f9197,0x16af4c49),LL(0x8f7a154b,0xd4672394),L_(0xee9c7e14), + LL(0xe432397f,0xd0196172),LL(0x035a30a5,0x114f01ee),LL(0x12143827,0x2f06e8aa),L_(0xcd20f526), LL(0x00bcfcbd,0x76ee873b),LL(0x542f1d14,0x8ff02da4),LL(0x786da906,0x7e7e6c65),L_(0x65c3eef1), + LL(0xc8866c5c,0x0d7b5118),LL(0x5cd6ca19,0xef5be83d),LL(0xb37c41ce,0x4b76c64d),L_(0xf34bee15), LL(0x3d28da12,0x8ef7cb6d),LL(0xf55195fb,0xa3c8a2d4),LL(0x4369465e,0xc8c85ab8),L_(0xe811f166), + LL(0x08818979,0x17f1f556),LL(0xbf0f506b,0x251cc269),LL(0x686c57b8,0x865fb805),L_(0xa325b2ac), LL(0x19c7f60f,0x23566eda),LL(0x40af0c7c,0x47f95f9f),LL(0x867b619f,0x1958dbaa),L_(0x164ce142), + LL(0xfc7b0693,0x44b01395),LL(0xedbed37e,0x0d676d86),LL(0x075607b2,0xe2ae6225),L_(0x9bd85253), LL(0x56d68f4b,0x7e636075),LL(0xb247649e,0x1ffba2be),LL(0x5c1ff02f,0xc237448d),L_(0x063c33cf), + LL(0xc3ea5576,0x52c5f87e),LL(0x2fe94caa,0xf135c024),LL(0x593535ee,0xe0965b4b),L_(0xf93cf6d1), LL(0x54fedc18,0x28d4b11a),LL(0x6c77585d,0xe5297d99),LL(0xb0d741c2,0x39caed90),L_(0xcc98dae9), + LL(0x340fdc0b,0x1b8201fc),LL(0x44198c3e,0x248c333c),LL(0x5f236490,0x12ee4946),L_(0x0789670e), LL(0xcbc6b050,0xee23385a),LL(0x3c3d5d85,0x630f7175),LL(0x0000016a,0x3f6e71ce),L_(0xad6ec3de), + LL(0xc6c3de31,0xf99b211a),LL(0xca35fe5b,0x549ffc41),LL(0x5ffb8aa4,0xbc4e1e52),L_(0x6ac77d41), LL(0xe552f85a,0xf54af34b),LL(0x6e1ccff3,0xd61618d2),LL(0x5bb20166,0x5776aea6),L_(0x7336f961), + LL(0x535ea11e,0x565a5471),LL(0x8f3dcba8,0x4200ddee),LL(0x8ee2aacd,0x2493fe70),L_(0xab90e06d), LL(0x048f6037,0xc2e41220),LL(0x075b150b,0x3193a2ea),LL(0x3c56b2e4,0xc4609ea4),L_(0x2fdd776c), + LL(0x4276f086,0x57d5dc17),LL(0x2aa19794,0xa8a6408a),LL(0xd70d74f7,0x98acac12),L_(0x351c3c6f), LL(0x93cd39aa,0xb4c10685),LL(0x5a2bba35,0x56a7276e),LL(0x2685e5f9,0x3eeed659),L_(0x8a344719), + LL(0x2d701e0e,0x22e61da3),LL(0xbff21920,0x4511147f),LL(0x403fd833,0x6080d968),L_(0xb3b3779a), LL(0x2957083b,0x38eb9ccb),LL(0x2ed5dc9b,0x1be2ace4),LL(0x726301f8,0x002d8909),L_(0xbe322533), + LL(0xd1f9235a,0xf591d929),LL(0x0184d742,0xdc207a6c),LL(0x5e691f61,0x20b8f8e8),L_(0x2095a193), LL(0xaeb5ac0a,0x7eacabb9),LL(0x3b17347c,0x0985df07),LL(0x04b8e782,0xf8047be0),L_(0x5ad11ec9), + LL(0x8492830a,0x4f347f1e),LL(0x841e8dca,0x7d0fc13f),LL(0xf365c6c6,0xa0e662a2),L_(0xded71c8e), LL(0x8d246f45,0x9dcc1860),LL(0x852d364c,0x5bfa3ba2),LL(0xd9a27ded,0xb281e327),L_(0x80b9b9f1), + LL(0x6bab642c,0xbff128cd),LL(0x692c67d2,0x268f3893),LL(0xfc73c613,0xcd24728c),L_(0xa40f87b1), LL(0xd40e3e5a,0xf065f5d7),LL(0x96f653a5,0x15d0cf49),LL(0x4ad712bb,0x70e00818),L_(0x2102b8b4), + LL(0xf1c993cb,0xa2f0722e),LL(0x214a8d8b,0xe7c142ac),LL(0x8af34ce1,0xce47aba3),L_(0x2d01c664), LL(0xb6c1f1ff,0x49dac9d9),LL(0x8e33c0f4,0x1baa4d4c),LL(0xdbfb3b98,0xd927e1a8),L_(0x80f00079), + LL(0xde4413ab,0xad27b0b5),LL(0xa2997bb5,0x0077242e),LL(0x5d3ac419,0xe50d3185),L_(0x185f649f), LL(0x6b5c4eea,0x4a8b1fad),LL(0x210cc7de,0x30ac4e43),LL(0xe0253dce,0xf07461c4),L_(0x4bf807d6), + LL(0x01947899,0x818e99b8),LL(0x9008b9c3,0x05ed8f7b),LL(0x09f78f1a,0x2fb78a6e),L_(0xa5da0ebd), LL(0x4c2f0cce,0xfdd48d7b),LL(0x79765db8,0xe380dbfc),LL(0x9600539c,0xbb3a3bc6),L_(0x3627d4d4), + LL(0xea2bbe08,0x394029b6),LL(0x7ac327d1,0xc8ab0424),LL(0x90339a91,0xda368bdd),L_(0xab696429), LL(0x0fe39b21,0xc20f1366),LL(0x32fec057,0x8075ba9a),LL(0xdc668935,0xa20bdd31),L_(0x2abf3c1d), + LL(0x513bd424,0x02a9ea32),LL(0x7d6a8a11,0xe477baa6),LL(0x52b0bc16,0x4583bc9a),L_(0xba81bd4a), LL(0x287b6485,0xf11b84b0),LL(0xae92c68c,0x7925b118),LL(0x4ab367b2,0x8ff3e481),L_(0x33179660), + LL(0xb6f13800,0x0ffc4673),LL(0x56722205,0xf9b0dfda),LL(0x2bd4103b,0x56acfc3b),L_(0x1ce74c3f), LL(0xa87de434,0x046c39cd),LL(0x41e5b749,0xdebd1720),LL(0x11fa933d,0x3f6c6fec),L_(0x275b834e), + LL(0xae4601fd,0x06034734),LL(0x58ee806e,0x104d85dc),LL(0xca3c77a5,0x8bca0d2e),L_(0xb812f136), LL(0xc78c356f,0x70ae3402),LL(0x7dc1f03f,0x322e72ad),LL(0x07c1fe3f,0xd0253c44),L_(0x511d1058), + LL(0xc2f400a7,0x2291a21d),LL(0x993f820b,0x287eac12),LL(0x1680907d,0x03a00f86),L_(0xd919412a), LL(0xbadddbc3,0xc5e15b28),LL(0x0ba18a53,0xf30664e1),LL(0xb1606671,0xc87b6603),L_(0xb55b207a), + LL(0x1873a8e5,0x5f55c7e2),LL(0x6eaa78ce,0x33f083bf),LL(0x95c9fed8,0xe416fc1c),L_(0x7e0f68c5), LL(0x02778f82,0x07eef5cc),LL(0xdb2aa0a1,0xa94149df),LL(0xc8c44cfd,0x2d270d3f),L_(0xec06f559), + LL(0x7ca9f958,0xdb514ec8),LL(0xd0ace135,0x9718dd09),LL(0xe2bf5a99,0x325fe3bd),L_(0xe5c7ec48), LL(0x4f0b0621,0x78990d74),LL(0x76fa9487,0x5e70b57d),LL(0xdfbda68c,0x6e9d11e2),L_(0xda96d406), + LL(0xd61361bb,0xf97cf589),LL(0xc96cb924,0x7b21af76),LL(0xf64ebc1a,0x03a72d66),L_(0xecbebd56), LL(0x4b021c91,0x39df1cca),LL(0x9863869e,0xb84c6c05),LL(0x9b6a3082,0x62692bf5),L_(0x977cbcb4), + LL(0x94bf9bf5,0x79c2f57b),LL(0xb9be753d,0xe0d00e09),LL(0x49f82bc9,0xb9c9a088),L_(0xcc0f3b6b), LL(0x1f589bd1,0x11cd1677),LL(0xe709a25f,0x8f952cff),LL(0xb5eec978,0x016b826e),L_(0x3188c1dc), + LL(0x8cd03f0b,0xf4d9e042),LL(0x2b04b26f,0xb07e4630),LL(0x361c9252,0x5bbca5ce),L_(0x783f801a), LL(0xe687c320,0x7bd9a485),LL(0x465590b5,0xe200e18a),LL(0x0e254cdc,0x50dce2e6),L_(0x49ff7ac4), + LL(0x4b5e8399,0x284e641b),LL(0x33c76e5a,0x0556fa64),LL(0xa75c4fae,0x4cc4b972),L_(0xc36d03ba), LL(0x90fa7978,0x6a40b04c),LL(0x4fef28c9,0x97401c28),LL(0x613bfe61,0x443845a0),L_(0x5144c164), + LL(0x532b2d68,0x482b7779),LL(0xe955f441,0x123aa16d),LL(0x6886e7e9,0x9147c317),L_(0x1d0658eb), LL(0x1530f2af,0xaed04ac0),LL(0x192c5796,0xa4111d16),LL(0xd86157ff,0x7406594c),L_(0xbf39202c), + LL(0xafae6c6f,0xed33d4b3),LL(0xc5df16a7,0x008ec0c8),LL(0xfe186e4e,0x7e4ed374),L_(0xdca675ee), LL(0x2534f6e8,0x798a9b30),LL(0x82a138f5,0xfcf997cc),LL(0xb58b2b67,0x2f620d55),L_(0x634f7d88), + LL(0xe8013df8,0x5dcfcfb0),LL(0x7b9259dd,0x7a765b72),LL(0xe0fbd7bb,0x4e7374be),L_(0xc2b9a098), LL(0xfe9b1e78,0x375f54f1),LL(0x0f6c804f,0x55dc463e),LL(0x202fbb6d,0x8d697af5),L_(0xe7949513), +}, +/* digit=13 base_pwr=2^91 */ +{ + LL(0xbcdbe445,0xcb4a833d),LL(0x57ca0395,0xb07c1b51),LL(0xef7d725e,0xdc3b82a8),L_(0x1e9a35e2), LL(0xaa5a7ac9,0x01e0c54e),LL(0xc707131f,0x2b2d5196),LL(0xd220aca6,0x736d91c9),L_(0xde0d6eba), + LL(0x74d6d0bb,0x9af89e67),LL(0xfa0e831e,0xada42e0d),LL(0xda49ba83,0x83b9c4ec),L_(0x782ab495), LL(0x12dfdcae,0x7e0a2cb4),LL(0x4c92a243,0xf7e3a9a3),LL(0x6ed0d332,0x1f8c692d),L_(0x5cfab000), + LL(0x634cef8b,0xff5ab01d),LL(0xa43c6f4e,0x6fe3ecd8),LL(0xc1015db1,0xfcc7ca4c),L_(0x9199e5e3), LL(0x795d4927,0xed944d52),LL(0xe4551e73,0xf5f41299),LL(0x8f02bb95,0x4007343b),L_(0x896481e0), + LL(0xab703650,0x6b243c97),LL(0x660da927,0x8b9a0873),LL(0x0ef0ffd5,0xb6e8c899),L_(0x8a32e4b8), LL(0x2e1c11d9,0x154379bf),LL(0x2d0a9ded,0x4382cb75),LL(0xc876e0d3,0xc42ec7d1),L_(0x41c57824), + LL(0x1ce64f94,0xa2eb2c00),LL(0x1eb0301b,0xe1a22445),LL(0x450ed02e,0x4205e69b),L_(0xf1b1c831), LL(0xc76dda33,0x62db01d8),LL(0x168f45ba,0x633bdf3e),LL(0x95c86470,0xf9a6b309),L_(0x9bb55ae5), + LL(0x71aba88f,0x590711c2),LL(0xdea8afde,0x0b6ab427),LL(0x87bfe939,0x1d7e1090),L_(0x54be137d), LL(0x7ebcdd75,0x2a937fd4),LL(0x5fed0f5c,0x3da3197d),LL(0xc4155a57,0xf1cea938),L_(0xe2bb2c19), + LL(0x6a4807e4,0xc0c52eb7),LL(0xfe9c4a62,0x12ba26fb),LL(0xda7a7914,0x001d4756),L_(0x48b356bb), LL(0xce833468,0x3290dbb2),LL(0x432f5193,0x2b0a3429),LL(0x579c91eb,0xc27c2657),L_(0xcb222ca0), + LL(0x6983b44c,0xf27d3e69),LL(0xf7665b89,0xe4a043b5),LL(0x5a97c010,0xc8f8a3c7),L_(0x4ed639e6), LL(0xb9a3137d,0x5655ed33),LL(0x6987fe61,0x0b6dca4a),LL(0xc1a3c9bb,0x630b3026),L_(0x9305872d), + LL(0x082a09e8,0xffe89fc6),LL(0x673fe488,0x9f4f85f6),LL(0x0b13732a,0xba6e1981),L_(0x1f59e6b4), LL(0x26eb2b18,0xa4afe844),LL(0xaddd3cd6,0x91a5d7b7),LL(0xeeac1c21,0xe71f5fe0),L_(0x5d6e8430), + LL(0x3f0bf1e4,0x031e908e),LL(0xecd2060c,0xbc16afc5),LL(0x6e2d4301,0x90a23e58),L_(0xd061f3f4), LL(0x2549fd21,0x52f4ef15),LL(0x4103c527,0x5b4c8dd8),LL(0x1a5fbbc3,0x7457c84e),L_(0x6620daf1), + LL(0xa3742f5a,0xe0a87786),LL(0x20460a16,0xe7aa9e66),LL(0xba62daa3,0x65327959),L_(0x4241a339), LL(0x7da31b21,0x7fbf3e8d),LL(0x352aab9b,0xe1a7865a),LL(0x877c379e,0xea576b89),L_(0x5f93fdc5), + LL(0xaa616a3a,0x662a3f35),LL(0x94cdd0da,0xdd7d18e3),LL(0xee30f511,0xf25f9c46),L_(0x35fff2a0), LL(0x3e51e653,0x81e804d2),LL(0x5957ab11,0xb0aaaab1),LL(0xa52da544,0x89ee1376),L_(0x8411811a), + LL(0x97063083,0xf2d42cdd),LL(0xc2eb7ee5,0x9cb9423b),LL(0x6ed009de,0x746461d4),L_(0xc182c461), LL(0x6b0d52f8,0xe78fe609),LL(0xde14941d,0x6887a9cc),LL(0x8730c3cd,0x0f586a94),L_(0x2cf25d5d), + LL(0xf21a3a3a,0x38aa8cf8),LL(0xd96cec97,0x3dd4e3e4),LL(0xf1f81f18,0xee849585),L_(0x6ec8f23e), LL(0xb30df029,0x1e4514ba),LL(0xaf980c70,0x757e6771),LL(0x3b2305c3,0xa3525eaa),L_(0x755d2034), + LL(0xb94b1aa2,0xebe6c1cc),LL(0xb228a915,0x1c4d6e36),LL(0xfa33270b,0x5d3856a1),L_(0xf1ba0e3a), LL(0x77b4e048,0x63f53943),LL(0x99a1ff3b,0x7466b59d),LL(0xaea29806,0xb1050d57),L_(0x9d139cfa), + LL(0x0fd330ad,0x0f394d0b),LL(0x27d1a20e,0xe4d013eb),LL(0x99b62540,0xaa1c17a9),L_(0xb03afc54), LL(0x8f6f2743,0x7366a618),LL(0x449f676a,0x88e9ae3d),LL(0x8818aa14,0xd2fe924a),L_(0xf5d1f438), + LL(0xfd68c56f,0xd02cd00e),LL(0x94c49868,0x5f260a20),LL(0x9c693311,0x7c1f3266),L_(0xe30a0258), LL(0x5b2551ac,0x9f545dde),LL(0xbdeac1ae,0x19f87afd),LL(0x019bf350,0x58397798),L_(0x787035be), + LL(0x46ea826b,0xc4da4263),LL(0x10febee0,0x43744264),LL(0xbfc3581d,0xcc933457),L_(0xd3126394), LL(0x9cbecb37,0xe0071ca1),LL(0x715c9dad,0xcf0cfc02),LL(0x67a2c9e1,0x2f9bd24a),L_(0x47f400b4), + LL(0xa57e540f,0xd472cc15),LL(0x1ab19257,0x0b60e719),LL(0xcd92d76f,0xca1c9c30),L_(0xb75f7cec), LL(0x8103a773,0xa305744b),LL(0x34bb833a,0x54b38b68),LL(0xd6e1cdb8,0xb252c82f),L_(0xbbc88ea0), + LL(0x935833d7,0xd0e4995f),LL(0x44ed9975,0x87f60eef),LL(0x933733ca,0x379092ba),L_(0x0e167f70), LL(0xd4945af6,0x60eeff1a),LL(0x589a5723,0x1d6d1def),LL(0x4bee290d,0xe87f42f5),L_(0xbdc1579e), + LL(0xb222f294,0x080ba4e8),LL(0x83c59be1,0x8ed3f3c1),LL(0xfdee70ba,0x58ce1c82),L_(0x309979e1), LL(0x8490a253,0x6ed1e744),LL(0xc3fded2d,0x0602a508),LL(0x585e149e,0x7fa41773),L_(0xb933ab59), + LL(0xf0a3e292,0x74dc9c31),LL(0x0f2c66c5,0xc78baacd),LL(0x01ba1bb0,0xe5b73558),L_(0x328bebc7), LL(0x9cf50576,0x5421bd61),LL(0x76efecbb,0x241cb4c6),LL(0xc421cfb2,0x9ba297a8),L_(0xe31b7671), + LL(0xf0b66ab8,0xd87b31c9),LL(0x3aacb600,0xcf835fb0),LL(0x2f9c67c3,0xaee5e6cf),L_(0x6453b1bf), LL(0xd04298de,0x0411e445),LL(0x0d41aa91,0xbec90b82),LL(0xe6adb2bb,0xb30b9c0e),L_(0xdd7ea812), + LL(0xda605906,0x5f01a30b),LL(0xe7f26ffc,0x7c053c40),LL(0x40f7d79d,0xc39feb03),L_(0x232940c5), LL(0x3d73c35a,0xe472e81d),LL(0xe3395fd8,0xdea2bf33),LL(0xed66fd6f,0xddc57518),L_(0x675b9966), + LL(0x7095dc92,0x07f66d27),LL(0xb47087dd,0x9c4ec651),LL(0xfd209ae0,0x35803afd),L_(0x6fb37653), LL(0x51ed5eaf,0xc9356091),LL(0x47c63c1c,0x19e52bee),LL(0x0676dac6,0xd87e6c27),L_(0x6badd30e), + LL(0x83877c71,0x39e61abc),LL(0x58d7a9d9,0xa88e05f0),LL(0x7885ad28,0x53bfba53),L_(0xb10f5fdb), LL(0x8e433b9f,0xd6a78477),LL(0x0f088cf6,0xcefdc6a1),LL(0x3ce9d748,0x27d9ed71),L_(0x648c4c3c), + LL(0xe57aeaa9,0x7dbbbc39),LL(0xe13d51e3,0x5c942e4d),LL(0x7d7aed19,0xe660d0ba),L_(0x25bcdf2d), LL(0xff40dd8a,0xcdf314b5),LL(0x5faa85f3,0xa625d183),LL(0x9d4344c2,0x54f2035c),L_(0x5243fd7f), + LL(0xd120f88e,0xe3275570),LL(0x79d8c8b5,0xe344b66c),LL(0x8d5e8c7f,0x1cdb23ae),L_(0x8c372c12), LL(0xce526de3,0xe64e6355),LL(0x6f104a11,0x5edf30db),LL(0x7e00559a,0x3501ee2b),L_(0xdc58f8f4), + LL(0xa6698b0d,0x91c3e912),LL(0x65e168bf,0xbb24391d),LL(0xe1e797f6,0x0526a13b),L_(0x6c3a27f6), LL(0x41e4a8d4,0x63a82271),LL(0x759095e6,0xf6fd3e09),LL(0xd1ade148,0x85041faa),L_(0x1d102e98), + LL(0x7675921b,0xb30c5e67),LL(0x781de03f,0x9a004497),LL(0xb5aac131,0xcaf13420),L_(0x2a74de9b), LL(0xced86c6a,0xc60fb50a),LL(0x4039952c,0x8cd4dd3d),LL(0xdec98657,0x5092d4ea),L_(0x573afadf), + LL(0x9fb10f98,0x67b904af),LL(0x7233bca1,0xeebc687c),LL(0xdae52182,0x13aadd13),L_(0x7d61309e), LL(0x59a01f8b,0xc7db8080),LL(0xf6d5d889,0x5433ce07),LL(0x8b26a71a,0x0c3a71bb),L_(0x69b8c725), + LL(0xd29e534f,0x215aa2f4),LL(0x7bb1ac35,0x5f00b26b),LL(0x3c54a3cb,0x71ec2585),L_(0xf6cd94c0), LL(0x4c553b93,0xf86c23e2),LL(0x1b7d9626,0xdd6cfc3d),LL(0x0fb40ab0,0x4647a750),L_(0xeb4bdb5e), + LL(0xa51a2b17,0x1bbce0ea),LL(0x6f2f98f1,0x7e78ccf9),LL(0xc6736591,0xbaa1d2e3),L_(0x47e735c5), LL(0x6b8866aa,0xc5b9e6fb),LL(0x8aef23dc,0xc39a4975),LL(0x712336e6,0x86d2dbfa),L_(0x19715594), + LL(0x106db862,0xc495534c),LL(0x83770bdf,0x75c25358),LL(0x05a076ec,0xf2a1fa9b),L_(0xc80d0362), LL(0xbab703f6,0x2b054aeb),LL(0xb0c6f6de,0x9e9ed0de),LL(0x42646b39,0xd95a6334),L_(0xddad98a9), + LL(0xbcf088fe,0x373df018),LL(0x7bd97cea,0x2646d8cd),LL(0xa20f1b7c,0x3bc4db1d),L_(0xdd201f09), LL(0xf3f061d1,0x7fc330d4),LL(0x5f1ec56b,0xd64fa0dc),LL(0x93be4afe,0x239a905a),L_(0x38df95b1), + LL(0x9491ca55,0x3a2368e4),LL(0x4fc84a15,0x840339bb),LL(0x60229ac3,0x0f74bf45),L_(0xb9a147d0), LL(0x6bb23f64,0x6df7548f),LL(0x928eccc2,0xbd4ae1ae),LL(0xa5c7651d,0x85fa24af),L_(0xe98fba58), + LL(0xd9ea606f,0x72e722f7),LL(0xde7a39d8,0x02dae11e),LL(0x6f289df9,0x4f148db1),L_(0x3efce901), LL(0xe8df6027,0x0dc6bfc0),LL(0x25925285,0xc2c848fa),LL(0x726e5bf2,0x0bc8372a),L_(0x4993590e), + LL(0xe513cc61,0xb368f5d3),LL(0x1b56d61c,0x2acdbaae),LL(0x077919ee,0x69129848),L_(0xd6bce458), LL(0x5c03af06,0x6892cac4),LL(0xbf732964,0x13156875),LL(0x86df2c46,0x15d63bed),L_(0xc24215d0), + LL(0x85ef7366,0x7ea45182),LL(0x4f6a510a,0x7d4f7ca5),LL(0x2e79b2d0,0x5befddd6),L_(0xdfce6391), LL(0xeb6e8178,0xd7c05293),LL(0xbb2671e0,0xfebc1ad3),LL(0xc2ef9919,0x5ef848b7),L_(0x3034a5d7), + LL(0xec0fd6a3,0x4834ba2e),LL(0xd4612c03,0x7006255f),LL(0xee7cbb5c,0xa240c28a),L_(0x9d74ecc1), LL(0xe8bfcc1e,0x36f2363a),LL(0xe755acbe,0x2c7fdeac),LL(0xee2e792a,0xfe7f2c9f),L_(0xf3a0b1ef), + LL(0x21f1b866,0x7a207076),LL(0xb0caba72,0xa289580c),LL(0x26c6a4fb,0xac8c38be),L_(0x46fba43d), LL(0x603a204d,0xc96f5b0f),LL(0xaae0bc34,0x07974abf),LL(0xdd93d467,0xd384c831),L_(0xd3e228d7), + LL(0x130cf278,0xb2d57bad),LL(0xa4b0a795,0x2e92cb97),LL(0x0b8251c6,0x04325b28),L_(0xd825f27e), LL(0x630e8e9e,0xcda5985f),LL(0x1bba4e62,0xf6775b8c),LL(0x9cc53c03,0x466530c7),L_(0xca08b958), + LL(0x9b3d46a1,0x6911dd6e),LL(0x64d4f9aa,0xf5c72cad),LL(0xaf7d9d93,0x53a3ea3c),L_(0x99f4337b), LL(0xd879f3e2,0xeaba3d43),LL(0x7bd203ea,0x4c921337),LL(0x3b59edc0,0x7ee8ea79),L_(0xdbb3851a), + LL(0x64c557a1,0x70b7979e),LL(0xb3681c37,0x482d3b99),LL(0x08f6017c,0xecf693f0),L_(0xf2fe6d70), LL(0xe8816978,0x7c8670c4),LL(0x8a10a4b5,0x05b8eed1),LL(0xa8713371,0x0ebddf9f),L_(0x6f3c3b96), + LL(0x50dc1443,0x884f22ec),LL(0xf9400068,0x5f885c0a),LL(0x4da67f62,0x6b4ecc34),L_(0x170f203f), LL(0x0181b70d,0x3f227a67),LL(0x844eab79,0xafb114cc),LL(0x5b40835b,0x2f5bb436),L_(0x7b9f2c6f), + LL(0xdaec76bc,0x6deef6a5),LL(0x338dc21a,0xe70560f2),LL(0x8e70fab8,0xdf0c450d),L_(0xd256f11d), LL(0x916202a8,0x05568dde),LL(0xfb8b1d84,0x89f0919e),LL(0xb5670da6,0x97387cce),L_(0x8943fa2b), + LL(0xc269a34a,0xae4d60ad),LL(0xf62da5da,0x27a5a54f),LL(0x560e5ad7,0xfd2940f8),L_(0xab3236ae), LL(0x86446f6a,0x2f2ee978),LL(0xb56b7c8a,0xa481c719),LL(0xd1f9e2af,0x99fe0c80),L_(0xdc1ec6c4), + LL(0x4c354b32,0x9d2731ca),LL(0x45db9456,0x9583d77a),LL(0x549fab4d,0x20743202),L_(0x133b9227), LL(0xc9afa8d6,0x6ee70bf6),LL(0x61e414f2,0x71181b55),LL(0x34dfc171,0x186cb701),L_(0x05ba8622), + LL(0x784904dd,0xef91aeb1),LL(0x2ce39834,0x466ca745),LL(0x9dba0e94,0x3efbbed0),L_(0x6d055926), LL(0x818f1161,0x238404b3),LL(0xb2aba397,0x7f378101),LL(0x9026e5ef,0xd9ddeb02),L_(0x639d63b6), + LL(0x50f516e3,0x359a1ffe),LL(0xc1a03316,0xea7c7fb8),LL(0x2be043ec,0xe26d37f4),L_(0x34fbd1da), LL(0xd8d23c82,0x97f967f3),LL(0xf3027282,0xf97e68ce),LL(0x0cf39dbb,0x0f3321ca),L_(0xb0d6de7c), + LL(0xd200dfe0,0x890af600),LL(0x905f6954,0x1e4962b1),LL(0xd80a6211,0x78562fa6),L_(0x0e1b429e), LL(0xdb5a70a8,0x68abbf8d),LL(0xdf21b056,0xbffea5c7),LL(0x99114570,0x6e5308c1),L_(0xd35cddc0), + LL(0xdfd77bdd,0x16448af4),LL(0x5bcbe7ef,0xcb49f269),LL(0x9f4c424c,0x7c95aa03),L_(0xb01ff8c8), LL(0xd5948dcf,0x93acdc43),LL(0x2ddd8b66,0x7efb93e4),LL(0xa8e311a0,0xe08e348f),L_(0x7b4dacb7), + LL(0x96c4f395,0xfa10af74),LL(0xd4e05b0b,0x489d01bb),LL(0x1a4d0c16,0x5457e489),L_(0x70983e98), LL(0x1331b4da,0x84eb66f4),LL(0xf38823d2,0x8054cf79),LL(0xb191cf89,0x3e7eb0cb),L_(0xa37a2976), + LL(0x8d0cc3cf,0xa6a534ca),LL(0x7bc55c38,0xa917d88e),LL(0xc01d22dc,0xba878e3c),L_(0x2cf82f89), LL(0x927b4948,0xfb3f69e6),LL(0xfab01485,0x44185c63),LL(0x586c00a9,0x151ed75b),L_(0x923f3333), + LL(0x72a46aaa,0x519ea031),LL(0x8709198a,0x75f6f740),LL(0x1a09f429,0x0df7057c),L_(0xd41f8134), LL(0x0511f342,0xb8c291d5),LL(0xb5c05e96,0xbd814e25),LL(0xa548461b,0xdfcbbc5c),L_(0x17c27bbb), + LL(0xf029f708,0x3ec594c8),LL(0xe348f36b,0xaacdcc44),LL(0x76cebcbf,0x6e7c6e83),L_(0xb7e69828), LL(0xa2a8a4ff,0xb47c1c29),LL(0x994406d9,0xebdc1ae0),LL(0xed49a01f,0x63ac12b4),L_(0x513ab51d), + LL(0xaa4b3b47,0x7e957ed9),LL(0xa7f34b22,0xe3393b0f),LL(0xde08b775,0x8522afee),L_(0xacd12226), LL(0x5f73d8d2,0x39d26476),LL(0xa513c2b3,0x7e58e0f2),LL(0x213036c0,0xa0e99b0f),L_(0xfb5cf2f2), + LL(0x8a626b92,0xbe1888a3),LL(0xbb87a44b,0xc627fd2d),LL(0xd55c88b6,0x75c0ce87),L_(0xe7f3660a), LL(0x96806d02,0xdce56555),LL(0xc75c5771,0xa0f7c5e9),LL(0x286d7145,0xd7ff4a5f),L_(0xebc158a2), + LL(0x9f5793c9,0xf0bdad25),LL(0xb6481975,0xde77b0dd),LL(0x308c67ea,0x506de99f),L_(0x814dd111), LL(0x9d70efea,0xf8b6908d),LL(0x664f6334,0xa22f9208),LL(0xabb48b09,0x305250b9),L_(0x589eade6), + LL(0x04d51ba4,0x69790978),LL(0x61258755,0x55c72c44),LL(0x340e8617,0xcd9b6116),L_(0xabcb82e4), LL(0x80b0004b,0x8b257151),LL(0x337e5242,0xae7d889b),LL(0xd95f9a8b,0xf7035183),L_(0x7680c71b), + LL(0x96f17da3,0x21e71bcf),LL(0x808dcdbd,0x1dde1b45),LL(0x3f515a1d,0x1f620fc3),L_(0x06bbadac), LL(0xd2651946,0xa7f48789),LL(0x0f2c7fea,0xa9e9b7f9),LL(0x048d20b9,0x2efd58e7),L_(0x44fa3d36), + LL(0x095a8f26,0x6fa2edc8),LL(0x653c44b2,0xad7dc081),LL(0xf2b8fbbb,0x88a7b80f),L_(0x02238eac), LL(0x2ca3a2a6,0x00c09332),LL(0x7cf3c758,0x0d577a60),LL(0x54d150a9,0x1837cf45),L_(0x9354157c), + LL(0xec967632,0x281b5c05),LL(0x5e849910,0x580362ba),LL(0x832277a8,0x702cc617),L_(0x1dbc415a), LL(0x7335bdc9,0x26119f95),LL(0x90031be3,0xa27ab673),LL(0xc7055ffb,0x652580b5),L_(0xe35bf60a), + LL(0x8c6adedb,0xebd0f498),LL(0xe1e7a7db,0x993107cf),LL(0xb75b4edf,0x0232f8ad),L_(0xc245bc0d), LL(0xa2592946,0x48d03da4),LL(0xb9489c19,0xda871c00),LL(0x8ff4aaa7,0x746e818b),L_(0x8df35cfe), +}, +/* digit=14 base_pwr=2^98 */ +{ + LL(0x23800fac,0x8b12655a),LL(0xd7cd8acc,0x66a4179c),LL(0x33023ec9,0x1205108d),L_(0xc1d74575), LL(0xa87c96ad,0x402e3b9a),LL(0x744ac2f7,0xd3dbe7de),LL(0x6b327511,0x5723ac5b),L_(0x244ec59a), + LL(0x7ab235be,0xbede2315),LL(0x536bf0cf,0x5f9a6aaf),LL(0xe6d56464,0x357d2d21),L_(0x58f34a26), LL(0x95a60b41,0x49f4f0e2),LL(0xcfbab99d,0xdca3ea61),LL(0x4c739342,0xa16d4457),L_(0xcea92902), + LL(0xdcc5b89b,0x463327ef),LL(0xb7378179,0xadb9328a),LL(0xbfce0e4d,0x0d62b545),L_(0x1e6b72f2), LL(0x349d4bd6,0xa76133fc),LL(0xdf69c044,0xb4284723),LL(0xf5a817aa,0xf7ca3909),L_(0xe22765b5), + LL(0x0655039f,0xbc44db37),LL(0xc2621a65,0x3d4e983d),LL(0x67d89bbe,0x85435ace),L_(0x803ede1a), LL(0xbe29cd2f,0xed39f9e8),LL(0x00ea11c0,0x55cac6ca),LL(0x3d4406d2,0xde2aeda4),L_(0xe7cb91b3), + LL(0x8fabc04b,0xc39c7ee8),LL(0x26cf4402,0xc619fe58),LL(0x0816fbf5,0xf268e46c),L_(0x9482a940), LL(0x3b1bba20,0xce226865),LL(0x080cefa6,0x4f9ab1d9),LL(0xfcbc42d6,0x13efb949),L_(0x1f067e43), + LL(0xf8119c35,0x75d60569),LL(0x73a4c13b,0xb3a82994),LL(0x063e48b4,0xc7bc1aec),L_(0xb0ab7ce1), LL(0xd626619f,0xa7f182b8),LL(0x4c843004,0x533f72eb),LL(0x1d2aa02e,0x69953a2d),L_(0x0de00959), + LL(0x91516c9c,0x0913a322),LL(0x1648e50c,0xa0961a2f),LL(0xa7d10cb1,0x06e4869d),L_(0x9b4a803d), LL(0xdc8793e7,0x9f17e3a2),LL(0x298436f6,0x06fc6243),LL(0xe925133a,0xb7622bbe),L_(0x70b9a2e8), + LL(0x84e7489b,0xc981ba62),LL(0x5e1a4306,0x792db847),LL(0xa77e3ed1,0xf4b6792a),L_(0x87bb9d13), LL(0xed208d23,0xfc7dc4a1),LL(0xcc352f71,0x87c2b023),LL(0x095b0ea7,0x88016bc4),L_(0xc90a59de), + LL(0x59119397,0x4b8755e3),LL(0xfbec0058,0x19aa2513),LL(0x554f2e58,0x1d544a58),L_(0xb7908e98), LL(0x1d4dba6f,0xcc8e5a35),LL(0x4e98597c,0x4036ed62),LL(0xf70ca123,0x0fd793e9),L_(0x5567a702), + LL(0x269da085,0x2503b0ce),LL(0x06549f68,0xb3025472),LL(0xeb061c62,0xfe9ae248),L_(0xd6d45a68), LL(0xd2906b25,0xeaa5d6f9),LL(0x58bbd291,0xaf62d50d),LL(0xc2b140a8,0x4dbbcce0),L_(0x86272e95), + LL(0xa7cf5775,0x3293ff9c),LL(0x7b80a205,0x1f10127d),LL(0x739c1785,0xc01f9711),L_(0xa80be8ca), LL(0x68df6a04,0x50fcfcf4),LL(0x3da76c49,0x340f3712),LL(0x53cced84,0xba988480),L_(0x89efc853), + LL(0xed47d3b8,0x6051e486),LL(0x27be6887,0x2e29a4c3),LL(0xfb40723c,0x77353f89),L_(0x3a8109a1), LL(0xf4eea8fe,0x672e091a),LL(0xaaf35dba,0xef34d20e),LL(0x96e8e707,0x2e5db0f7),L_(0x259349f1), + LL(0x089e80e9,0x259bf71c),LL(0x6e48997b,0xcd52c81c),LL(0x9b67f891,0x106aa44c),L_(0x2b828bad), LL(0x84cca320,0x492159ac),LL(0x860638da,0x99fc08c2),LL(0x9a577c2f,0xde194e1f),L_(0x4c02a837), + LL(0x1a869e95,0xac2dd0d1),LL(0x40fe4710,0x0d98495d),LL(0x926fca45,0x230d5720),L_(0xc0032a5e), LL(0xda97aa70,0xe0f36b43),LL(0xdbdd8384,0xbdee74a8),LL(0x9f4f1e97,0x616d2e77),L_(0x285c8908), + LL(0x4ce190f7,0xe408ab06),LL(0x4de68c46,0xaec26bc8),LL(0xea864657,0xa9c6ad27),L_(0x3b9d1eb1), LL(0xab862944,0x327c78b5),LL(0x2af9ede8,0x751ec6f1),LL(0x18bed81e,0x1c240eff),L_(0x17dc571f), + LL(0x291c3273,0x766b4a0b),LL(0x3a97f292,0x6e56a096),LL(0xafb97a2d,0xe3cbbbe3),L_(0x3a6fadc9), LL(0x2369de35,0x4c78c1e4),LL(0x6d3e5c1b,0x698e8f8f),LL(0x14e1a4eb,0xa87a74e8),L_(0xbb410055), + LL(0x0fb37060,0xcbf75eae),LL(0x323f451f,0x58dee01f),LL(0x1a149a9e,0x67ff1a09),L_(0xb35d39d2), LL(0xf63b9865,0x7e111af7),LL(0x02e5fd5f,0xf6f23814),LL(0xc6967a32,0x682916a3),L_(0x5d411958), + LL(0x53aa5942,0x7dc26ca6),LL(0xec5ae21b,0x3a7f3858),LL(0x4c6d1720,0x87d2b98e),L_(0x6b3c9448), LL(0x379e4e5d,0xc6bec0ca),LL(0x7de28c5b,0x69db9b01),LL(0x4e3aaa80,0x4f1a3e1f),L_(0x31e76223), + LL(0x948cf979,0xe1a7d9ed),LL(0x32518804,0xabd060c2),LL(0xe2c8026f,0xd02845ba),L_(0x60dcd816), LL(0xd2fcd20d,0x9fc8ca8b),LL(0x67ac75bd,0x0b403597),LL(0xfa897231,0xd2ef4cab),L_(0xba971f13), + LL(0xc9608224,0xd3a9e728),LL(0x21de382a,0x9fcf28b0),LL(0x23db313b,0xe226f1f0),L_(0x9e002526), LL(0xdd26c698,0xa3a7479f),LL(0x8170903e,0x4871cbd5),LL(0xc0ad648f,0x30414c9b),L_(0x3c9d51d0), + LL(0xe22f8df5,0xdef38d08),LL(0xd456476e,0xfacc23b0),LL(0x7b3f5e97,0x00fb9a2e),L_(0x6c5a7311), LL(0xa6cbdc37,0x87cb811c),LL(0x82204464,0x6214d9f5),LL(0x06806fd9,0x5ba8f23b),L_(0x6d93ebe3), + LL(0x86e33c2d,0x23423298),LL(0xa44ec00f,0xf6e30434),LL(0xc242970e,0xbf53cf6b),L_(0x3a4d00db), LL(0x84f61eea,0x8140c42b),LL(0x5afabd85,0xe917c409),LL(0x70d1d6e0,0x95de99fd),L_(0xc2091589), + LL(0x396774db,0xc249bd59),LL(0x93024ffe,0x24f81111),LL(0xfe365e8c,0xdcd6e625),L_(0x35c6e777), LL(0xe01d308d,0x65e9e9bf),LL(0x4a7452da,0x5cab99f6),LL(0x441a1645,0xf759c45d),L_(0x97ffca58), + LL(0x1d7326e2,0x52fad307),LL(0x04705ea5,0x3aa389bc),LL(0x9cfd5023,0x3feb82b3),L_(0x7a752b31), LL(0x4a98e745,0x22a198b9),LL(0x303fc591,0x5fd22f5c),LL(0x95dcd425,0xe40ca457),L_(0xfc4759f2), + LL(0x0baec1d1,0x899726d2),LL(0x9ccc4295,0x9503a4a3),LL(0x8faff5a9,0x735bcc96),L_(0x4938831d), LL(0x294b5dc9,0x27659e3e),LL(0xcf8e86f6,0xb11539c4),LL(0xf82de3fd,0xdafe9d6c),L_(0x93a3f5c4), + LL(0xb712f886,0x4ba7d548),LL(0xf1d50673,0x627d0815),LL(0xebc722ce,0x4e21b679),L_(0xd4fcebfe), LL(0x3d488792,0x654d615e),LL(0xa956f701,0x38e30e59),LL(0xbe0c2b4a,0xd07392c8),L_(0xd0eefb50), + LL(0x91582e11,0x245a5f24),LL(0x83071bb8,0x1d74fe95),LL(0x32fc2d8c,0x8d68efa6),L_(0x3c6bb1ba), LL(0xb73ed81b,0xd7c363e3),LL(0x4814d6e2,0x4b18aee3),LL(0x8563cd35,0xf296ee0a),L_(0x39c2c1ab), + LL(0x6115b5df,0x12e07056),LL(0x27e6f810,0xab33f925),LL(0xdadb7f44,0x9611fc0f),L_(0x21632fa8), LL(0x135db674,0x0014d0b2),LL(0x90282284,0x34df44bd),LL(0x498b5aab,0x3b9bf0a3),L_(0x83adadb8), + LL(0x8b47b85a,0x7583945e),LL(0x8ca7a054,0xe1eb9f0d),LL(0xdc6bf5ac,0x7f50540d),L_(0x4929ffcf), LL(0x7dcd0fa3,0xd6e884e8),LL(0x547fd35b,0x0fda3c41),LL(0x42d34849,0x156b5074),L_(0x2b73e553), + LL(0x9db1951e,0x6f1aaef3),LL(0xbba949f2,0xe07d36c2),LL(0xaf67c45f,0x598114fb),L_(0x0be51018), LL(0x18833890,0xb079f72e),LL(0x43a0dd65,0xee4b11df),LL(0x20bd4ca5,0x9dd3598b),L_(0xb6e5a89d), + LL(0x2f515e07,0x0a130c64),LL(0x53781704,0x21d929ed),LL(0xed92766f,0x2370b592),L_(0xb01a78da), LL(0x461ee105,0x11fd327c),LL(0xe5630841,0xaac6ed8a),LL(0xaad362f8,0xe2c21338),L_(0xd9bef88b), + LL(0x7702c305,0x90cc96b4),LL(0x284ea1e9,0xec9108c9),LL(0xea844162,0x79d4d2e8),L_(0x5fc96bdc), LL(0x9b799340,0x9b1c7dfd),LL(0x6ae02844,0xf8a798d5),LL(0x4a0a1e22,0x7439503e),L_(0x0838edf3), + LL(0x25112357,0x41a91a95),LL(0x9794aee7,0x12be9cf2),LL(0xa09c00f4,0x87b213f6),L_(0x588e9419), LL(0x3cc23f7d,0xa44cb6f8),LL(0x9ee73263,0xda068194),LL(0x999bf774,0xe19968dc),L_(0x4f9d93f1), + LL(0xa3bbb5a7,0xe07280d1),LL(0xfdb5f5ba,0xf0df9657),LL(0xbd50dd87,0x4715fc8b),L_(0xdf379027), LL(0xf3d02095,0x64a96f25),LL(0xeb119764,0x661822c2),LL(0x8b298e54,0xd8ec764d),L_(0x6f6ea251), + LL(0xcef9767b,0x3dfab91a),LL(0x7c6e866c,0x85522367),LL(0xdbf3bb79,0x79b36fcb),L_(0xbeb97ad5), LL(0x05fa18c2,0xdbafd1f2),LL(0x64259c17,0xdd549dff),LL(0x83c7657f,0xd82dc78f),L_(0x8cf18ed9), + LL(0xad65298a,0x58b32f27),LL(0x2131395b,0x976af3d3),LL(0x4b505f2e,0x64c1cfc3),L_(0xca10d83b), LL(0x59913cfe,0xbab37657),LL(0x1414d1f4,0xf066519c),LL(0x8887e569,0x3d975cff),L_(0x0c251f08), + LL(0x425ddccc,0xd5368e78),LL(0x93068700,0x12b23c3e),LL(0x33076aa1,0x4e626b1c),L_(0x4e14ead6), LL(0x23f1e78d,0xe86079cd),LL(0xd274538d,0x908738cd),LL(0x244ce9b9,0xe51d741d),L_(0xb4e734ed), + LL(0xb2d63b64,0xf0e2cdd8),LL(0x0675f17a,0x90f8143d),LL(0x75829dd6,0x2d23a43f),L_(0x298a7f8f), LL(0x47ca8668,0xa526104e),LL(0x4e9c496b,0x85467645),LL(0xb0f0e275,0xafc61eeb),L_(0xa1acd83f), + LL(0x7ee79f81,0xf367484b),LL(0xafa3db78,0xbfc8c257),LL(0x7fe068cc,0x7c8262c2),L_(0x784b4654), LL(0xc96069f1,0xd5c6e6e1),LL(0xb65beee4,0xd8f70ecb),LL(0x24073300,0xc55f13ed),L_(0xa8d09ea4), + LL(0x82d22a52,0xe38ffddd),LL(0x7bb613d6,0x03df60ca),LL(0xa964fa9d,0x9bfb3890),L_(0xcc4b84d8), LL(0x96707a64,0xf9f9338a),LL(0x110b10fd,0x5d9e9ac0),LL(0x0acd29e1,0x854609dd),L_(0x11a3136a), + LL(0x84bcad3b,0x9a527f75),LL(0x28be328f,0xc16f294f),LL(0xdaf38a99,0xfdebcc4a),L_(0x4d614ff9), LL(0x8a1d04d1,0x760244a9),LL(0x9fb5fa88,0x97af96d1),LL(0x79ecc48b,0xebf508a7),L_(0x63ac8146), + LL(0xa9338a44,0x4ccbe898),LL(0xe952b759,0xf79ce658),LL(0xa7f6528b,0x0efdd8f6),L_(0x59bff1cf), LL(0x7002f54b,0x859eefc9),LL(0xb915b857,0x3146204d),LL(0x25b282fd,0x9e570ac1),L_(0xf3c10eb4), + LL(0x50227a06,0x96cc2182),LL(0xd7972029,0xed491383),LL(0xa5e9dc33,0xef480409),L_(0x8303786c), LL(0x48fc5413,0x7b84b8b7),LL(0xa8f1bf3e,0x22c04cfa),LL(0xa2e99567,0x5b8dc942),L_(0x089858bd), + LL(0xb80a1877,0x7a0670f5),LL(0xf5def779,0x99c0dcfe),LL(0xceba003e,0x737b1478),L_(0xba188761), LL(0x88ff60f8,0xa8a91790),LL(0xf962acd7,0xd0c75bfc),LL(0x8ebfd0f8,0xaf779b34),L_(0xe9624be3), + LL(0x62fec3e2,0xd969780a),LL(0x9daaebb5,0xafc171d8),LL(0x647f2bf8,0x16ea68f8),L_(0xfbfe21fa), LL(0x83f12d03,0xb63e2588),LL(0xe8295dd0,0xb69cbad8),LL(0x08b7948f,0x1a740ee4),L_(0xbe240b54), + LL(0xd3ad093e,0x97774b8e),LL(0xa107d5a6,0x1438ff5a),LL(0x90acd42f,0x0c55b2c6),L_(0xb1008301), LL(0xf3524dc1,0x1f19f151),LL(0x28b7f8e9,0xc5b4f62c),LL(0xe1899b7c,0x7240d638),L_(0x249ecebf), + LL(0xf9ad69ab,0x9a96c604),LL(0x1e0ee825,0xd851c4f0),LL(0x816d9822,0xf895d68e),L_(0x14e58e83), LL(0x914c2f30,0xdd941975),LL(0xd4525a24,0x1765af51),LL(0x9bdc107c,0x770ebc8f),L_(0x908f73aa), + LL(0xe5bd052d,0x70e13a7c),LL(0xe46ccc09,0x0c4379c5),LL(0x0121f8bc,0x71124e71),L_(0x38ba16ad), LL(0xe43a3a55,0xd9134113),LL(0x23d0c031,0xbbbe7daf),LL(0x3a1c2b24,0x3950f72a),L_(0x78296ab5), + LL(0xa71550b1,0xdab1491f),LL(0xdd5b8553,0x12caa6e8),LL(0xb08da5e0,0xf505a6eb),L_(0x95e70a66), LL(0x79842177,0xcf510150),LL(0x68ab8f60,0xafdce053),LL(0x87a8f6f2,0x8158b7f4),L_(0xc0b75050), + LL(0xe2eb279e,0x6af97a49),LL(0x86441bbb,0xd6c5159d),LL(0xcf78aa46,0x572c05de),L_(0xbc71b5c6), LL(0x0bf9ef5a,0x5b7148bf),LL(0x97df4c43,0xbe4b9631),LL(0x101cdc13,0x7ed1a6b8),L_(0xafbd7e88), + LL(0xb580b670,0xc6feaf5c),LL(0x3ea251a2,0xa5cb0934),LL(0x02cfec16,0xc2e35b6b),L_(0x0fdebc9c), LL(0x6e09365e,0x5b4d0976),LL(0x54866bd4,0x405714ef),LL(0x892fc650,0x75be4796),L_(0x224babf9), + LL(0xe024a3b6,0xffdc8787),LL(0xd74e707e,0xbb8a1baa),LL(0x16ab4631,0xf8688223),L_(0x0cf2f805), LL(0x09c1692c,0x0dd7a6f9),LL(0x42b206a1,0x3a94d17c),LL(0x784e210d,0x58b82c4e),L_(0xd0f07cde), + LL(0x4df5c033,0xa0b09f2e),LL(0x0f337455,0x8ad59d7f),LL(0x92ef323e,0x9dfd994c),L_(0x8a562d14), LL(0x9c294c52,0x0784cc2a),LL(0x06b511cb,0xa7c397c2),LL(0x9d3b5c1e,0x5217298a),L_(0x9becab02), + LL(0x5fffdecc,0x15425166),LL(0xf204b46f,0x3ad2c54a),LL(0x29b56266,0xcbfffc28),L_(0xe2bc5353), LL(0xb4051ff4,0xe925b548),LL(0x91eefed0,0xd94421d2),LL(0x61d3c552,0x0c2f7520),L_(0xd3c090b5), + LL(0x70ed4769,0xfa81c450),LL(0x0d59a33e,0xbb762aa7),LL(0x72d6d774,0x7b08eae2),L_(0x92885c49), LL(0x1432d1e2,0xc28ea0a8),LL(0x4e6a192a,0x57bf54b2),LL(0x163d3f1c,0x996fa17f),L_(0x8242af09), + LL(0xb5fbaaff,0x53d923d7),LL(0x4aa1aad8,0x8aeef401),LL(0xc59594fb,0xd7267ef5),L_(0xba7c28dc), LL(0xede0bedf,0xb019e637),LL(0xbffc5a3c,0x1be98aa8),LL(0xb69b47a8,0xd848486b),L_(0xa1758b69), + LL(0x95f000bf,0xc417bef7),LL(0x3f4d4f15,0xef4c07bd),LL(0x74d082e1,0xc8cd53f2),L_(0x2210c27d), LL(0xfb026021,0xaab1ecd2),LL(0xf4960e70,0x47b08bcf),LL(0xf6ef41f3,0x386f4e41),L_(0x3d017b94), + LL(0x806b3be3,0xd292e87d),LL(0xbe3b4c15,0xb316049f),LL(0x08cba3d2,0x5a2daba1),L_(0xf68b1a9e), LL(0xff881fa0,0x4da3f147),LL(0x91960fa2,0x8b3ea4f6),LL(0x7f14ef98,0x931e6a5d),L_(0x291615c1), + LL(0xe8b9b590,0x3a4e460d),LL(0xc7e1d53c,0x410540d3),LL(0xba715bf7,0x9faf6e57),L_(0xf612eab8), LL(0x13d8563c,0x83a48da3),LL(0x97d11aa7,0xbc420fcd),LL(0x54fecfb6,0x8ea8b02c),L_(0xa72e89c3), + LL(0x9f084f51,0x15421912),LL(0x19ce8a03,0x69e1810f),LL(0xa93a4b35,0x66d7f71e),L_(0x33703d01), LL(0x9b5d9b15,0x85c36f3f),LL(0xfb68061e,0xf837f0c3),LL(0x1acc3982,0x4526c2f7),L_(0x8aadc35e), + LL(0x91bdbe3e,0x5c462b80),LL(0x46606493,0x16f4a53a),LL(0x2452c556,0xf2ad5a49),L_(0x9ecfe87c), LL(0x961c76d7,0x92031bde),LL(0xd10c3c2b,0x43fc1b45),LL(0xba2806c7,0x7ea59306),L_(0x6d69a1f2), + LL(0xaf7fedc2,0x44f370ac),LL(0x575c1c1e,0x7fa03a08),LL(0x366491a9,0x65caef0d),L_(0x1d17b3b8), LL(0x3a469596,0x6dc5f00f),LL(0xf2e830cb,0x87cfba82),LL(0xebb7f488,0x1fc8150f),L_(0x74afed78), + LL(0x70a3e6c6,0xf79b97ae),LL(0xcd939876,0x0c92525a),LL(0xfd612292,0x1f877d7a),L_(0xf5237757), LL(0x2b249ae1,0x78a6422a),LL(0x2855f66b,0x0659a5e3),LL(0x12934c87,0x7a1fca11),L_(0xdfe80915), + LL(0xe4d85de7,0x0b0acedc),LL(0x21b8a084,0x6091bc19),LL(0x04526cb6,0xac1ce3ea),L_(0xd10a9ec7), LL(0xb54024a7,0x57196c24),LL(0xb55d4b5d,0x42e04321),LL(0x1b1d5d2a,0xbb31992a),L_(0xdb403b45), +}, +/* digit=15 base_pwr=2^105 */ +{ + LL(0x5f4861c4,0x9a1b156b),LL(0xa1ffe24b,0x45b930e9),LL(0xbeb5a955,0x29358e8a),L_(0x4b8943f1), LL(0x7923968c,0x127f5983),LL(0xe58cb43e,0xf5aef19b),LL(0x22713358,0x0329be36),L_(0x552fb6a1), + LL(0x842632cf,0xd5e766ad),LL(0x947d9fff,0xbab1e908),LL(0xdb59f894,0xa103e5b9),L_(0x68372195), LL(0xc4c67973,0x2cd3e628),LL(0x146f4450,0xe2690b88),LL(0x787c5ec2,0x153e0f49),L_(0x1f9bb175), + LL(0x01d9f5c7,0x9acab18d),LL(0xbfb21488,0x96fbb4bb),LL(0x43543f3e,0x19e99acc),L_(0x81d541e2), LL(0x4d4f6943,0x2373babd),LL(0x96c02c64,0x0c662932),LL(0xdd524336,0x60570f05),L_(0x6ee3ed44), + LL(0x98a32e88,0x9cbcb156),LL(0xda250980,0x00a72b87),LL(0x85f705a8,0xb60a7751),L_(0xa9f85b0d), LL(0x3ef7d9b7,0xc5078f17),LL(0x1fa64414,0x20110dec),LL(0xb521d60e,0x324aa16f),L_(0xcf1c2382), + LL(0x7053cd15,0xc75d38b5),LL(0x9347ce64,0xff26fb52),LL(0xfa6fa1ea,0x89904b74),L_(0xab858e49), LL(0xb9800606,0x0d1c07cb),LL(0x0b99d5c5,0x7605e424),LL(0xe982130b,0xc4ed9c66),L_(0x45e55121), + LL(0xb3f704f5,0x2c1c043d),LL(0xf3189b49,0x3e68dbd7),LL(0xbe354e8d,0xa6382386),L_(0xf9ee8ba0), LL(0x26378a41,0x04646666),LL(0x709ded81,0x88fbb7ce),LL(0xc603785d,0xb1f815a2),L_(0x5bec9b88), + LL(0x43fe75c9,0x9a29229c),LL(0x052996cb,0x9b1a9170),LL(0x7d4b9fc3,0x133dd4ca),L_(0x1176baf5), LL(0x53ac8647,0x6dcfad8d),LL(0xcfedffdb,0xe4115707),LL(0x6ff11203,0xbc9689c3),L_(0x8c720cdb), + LL(0xd81789dd,0x7b457d74),LL(0x127b60ac,0x5a87275f),LL(0x096f997d,0x5d4f53a6),L_(0x554f3104), LL(0xc86a176b,0x0c5247ba),LL(0xf8205ea1,0xb389c0f4),LL(0x325d67b1,0xdc511ddb),L_(0xc2e38d56), + LL(0xa0dc02ad,0xca8b2e56),LL(0xac05bb21,0x59515fbd),LL(0x152ad207,0xa0ec8c40),L_(0x1f1977c8), LL(0x990ce0e9,0x094829b8),LL(0x110ed8d5,0xdb93ce78),LL(0x53af9d31,0x980f663f),L_(0x50f753ac), + LL(0x0afcea41,0x1410da31),LL(0x91d6a357,0xc4dd3dce),LL(0xefc18ea4,0xc844e9d6),L_(0x599c3b4e), LL(0xb2b1ab81,0x89238185),LL(0x716b0afc,0xc007c089),LL(0xcc238164,0x10df0d3c),L_(0x7d888920), + LL(0xd9103e74,0xec1702f8),LL(0x0184b65e,0x67e64440),LL(0x4b15a941,0xaf4f5d2e),L_(0x334e5ea3), LL(0x82fa4171,0xbc874d39),LL(0x3cf9db40,0x63f968d3),LL(0x7b71afa1,0xc6c567c6),L_(0x74793b87), + LL(0x1b353d4c,0xfbfeb69e),LL(0x001b5f0d,0xaecee209),LL(0xdaae33fb,0xc8d8f5e9),L_(0x76be05c8), LL(0x4e52dc92,0x87741a88),LL(0xd9f61920,0xa5009003),LL(0x72c650f3,0xc505e3b9),L_(0xb83f81c5), + LL(0x2c204e5b,0x9f6af3aa),LL(0xd6b594bc,0x0423f2f8),LL(0xa67cf879,0xe29129c8),L_(0x99f505a1), LL(0x47ebe4a1,0xc220fd1a),LL(0xe7a97ad3,0xa34e4a65),LL(0x1fd2a0dc,0x7c1fb322),L_(0xa75c8fc2), + LL(0xcad10b12,0xca3e4b04),LL(0xdda6763a,0x00ce7df6),LL(0x9c84d269,0xa1f31fb1),L_(0xe404dde9), LL(0x45e72361,0xf80ab752),LL(0x300ca2ea,0x38935f38),LL(0x36966819,0xebd1b2a6),L_(0x758de4e7), + LL(0x28dbeb1e,0x4f41e2ad),LL(0x153889e3,0x1c0782c2),LL(0x60b0cb1e,0xb609d7c2),L_(0x9a85e0f0), LL(0x403c7b8f,0x3d308948),LL(0xe5878d4e,0xd8503865),LL(0x0326fd01,0xd472fecf),L_(0x51c81464), + LL(0x98673101,0x35c900a8),LL(0x2437a09e,0xdb5df675),LL(0x63415d28,0x6b676a73),L_(0x5a4ddb3f), LL(0x3e21afd1,0xa33929eb),LL(0x332e8fd4,0x717e43a3),LL(0x6bf414b5,0x9c7a3c47),L_(0xfb327e1b), + LL(0xf9ea4385,0x6b738d34),LL(0x3b9138c4,0xac317163),LL(0xd197efee,0x2438948a),L_(0x2b8a07e9), LL(0xebcc3f74,0x1fc5f207),LL(0xdfbd84a8,0x9fdbdbb5),LL(0xddc39008,0x663a5b4e),L_(0x9956763f), + LL(0xa670dec5,0xaeb71ef5),LL(0x989b6598,0xa4973f38),LL(0xf981cb1a,0xe1b496e0),L_(0x187e0a5e), LL(0x8185f4e5,0xdcd9014d),LL(0xce47e120,0x01c7c910),LL(0x33bfde50,0x0a1d6d42),L_(0x3059677d), + LL(0x0c74186d,0xf93c6e65),LL(0x2d2eb0b3,0x5c4b9d3f),LL(0x9b7f55b4,0x62194b5f),L_(0xf492843a), LL(0x07af0f2d,0xead94ac6),LL(0x344ba8f7,0xfc351f8f),LL(0x6a02d6dc,0x96c34c95),L_(0x0f698b8c), + LL(0x06eb2a9f,0xb29f094a),LL(0xe4c8cfbd,0x8cc86e57),LL(0x40844e37,0x2f8aef05),L_(0x7588271e), LL(0x864a5330,0x8ade6f97),LL(0xf9d12d2c,0x78f8e22f),LL(0xadc126ed,0x8c70fd00),L_(0xc12911d9), + LL(0xecdb5c0f,0x3c35a3f6),LL(0x0e784293,0xe0f4235e),LL(0x49ad3737,0x162c0cf0),L_(0x9e096565), LL(0x6d262e33,0x3611d970),LL(0x2ea4dc97,0x56f9b02c),LL(0x569e559b,0xd700ade3),L_(0x6445516e), + LL(0xab2f2394,0xf45846e5),LL(0x405bf6e0,0xaa46d2c3),LL(0x1222d842,0xf5f64176),L_(0xedb70efc), LL(0x1b067c96,0xb8990097),LL(0xb7f1c7b7,0xd2f67212),LL(0xe2b50ce3,0x7ac5ce8c),L_(0x05c93598), + LL(0x754843ce,0x77e241fc),LL(0x1ab02032,0xa0d9cbeb),LL(0x55cb5b7b,0x98136c68),L_(0xd09ef0e2), LL(0xef262224,0x523e661c),LL(0x87906701,0x3066156f),LL(0x3e7c7958,0x5ea1ccfb),L_(0xb06fbe44), + LL(0x736e6685,0xa762a548),LL(0x9218789a,0x4ea95a8e),LL(0xa90f1dd7,0xf1a7ecac),L_(0xbc8d97ba), LL(0xdb175bac,0x176f58b3),LL(0x16633eeb,0x66d2f2dc),LL(0xf30e4d83,0x047e3e70),L_(0xfad00adb), + LL(0x2523bfbf,0xdb1ab97e),LL(0x632d110c,0xa7f43904),LL(0xed30067f,0xe0063138),L_(0xcfac77b5), LL(0x0fe3afe1,0xef7cd5f9),LL(0x5720d9f1,0xbceebc62),LL(0x7475ff1c,0x37aef5f2),L_(0xcea553ab), + LL(0x21d9dd89,0xfe303f84),LL(0xe84277eb,0x403a10c6),LL(0xdc250e4e,0xcf99ada4),L_(0x260cc2ff), LL(0x16293017,0xdf77e00f),LL(0x429f4cad,0x017aea98),LL(0xb51701db,0xb9a51f04),L_(0xdf5024fa), + LL(0xaefa0a3f,0x3c6160d1),LL(0x89d2a9d2,0xb6871dd0),LL(0xcb336211,0x30015933),L_(0x4ddcddf5), LL(0x87d9707b,0x18fd4882),LL(0x96d9668a,0xf138a306),LL(0xeeb3123d,0xce3f684e),L_(0x9fa39b7f), + LL(0xdb674dfe,0xd843e892),LL(0xe36b5375,0xedfd1c18),LL(0xc7988b87,0x3bdd2895),L_(0xe52a31a1), LL(0x09bd2af3,0x294ff4e2),LL(0xccd1887d,0x2ad4535e),LL(0x2fc2c26d,0x1ebd13d4),L_(0x647f4987), + LL(0x0bdfba7c,0x94e42bd5),LL(0xae5c8c95,0x512c1be6),LL(0x10be5ddc,0x6bc6d702),L_(0xfd7b27ee), LL(0xd21e8821,0x636561c6),LL(0x170a05c4,0xe4ef4a34),LL(0xda161673,0x3d69a37a),L_(0xf40d8e35), + LL(0xc206f7b1,0xa0f11bca),LL(0x9195ecf0,0x23eeb3f7),LL(0xe6050ed7,0x98889901),L_(0x07aecdeb), LL(0xc76ba3ed,0x4edc3ee6),LL(0x6b353524,0xaab7f4a8),LL(0xc6e7d7b5,0xf6442856),L_(0xd31e141d), + LL(0x5b3638e7,0xd78b290a),LL(0xd885546c,0x77aef8c9),LL(0xfac422d4,0x0feb906d),L_(0x92b8b923), LL(0xdc0b9002,0x331327a2),LL(0x224f79a8,0x5d146cb4),LL(0x6fb5da21,0x3f887bb5),L_(0xc43cfdf7), + LL(0xb80d181d,0x2be6d108),LL(0x3c8b1f59,0xb342ddc9),LL(0x7004d85b,0xbe7db7ec),L_(0xec029270), LL(0xc1d565db,0xb82063a3),LL(0xbb014507,0xaa90beff),LL(0xbf4ed46e,0x3a15f177),L_(0xf45b367f), + LL(0x49eb74f9,0x146e10ea),LL(0x142ba6f4,0x1256c788),LL(0x346ea27d,0x3f761b6a),L_(0x80f4ab84), LL(0x4ec42ca8,0x150f9515),LL(0x566df38a,0xda268f4d),LL(0xe31f64a6,0xe4706b89),L_(0x95e5b78e), + LL(0x0b4a9c49,0xc8ae2f2d),LL(0xd939334e,0x58cc7b3f),LL(0x3e9cb1a4,0x31facd26),L_(0xcce403b2), LL(0x3b34d497,0xd018498f),LL(0xc5995b75,0xcbad3ed8),LL(0xa8867a65,0x0fb7952a),L_(0xef5960a9), + LL(0xe832b584,0xa4bc1e98),LL(0x3d7bc503,0x4ca3a484),LL(0x2da2b54a,0xbbcd02db),L_(0xf9f27d63), LL(0xd59bf324,0x02c44a56),LL(0x3ff8f28b,0x366f36f1),LL(0x0dbb411d,0xf30d32a2),L_(0x31dc1c76), + LL(0x52b2e707,0x19599554),LL(0x83cc5035,0xe133dbc1),LL(0x659be3d5,0x90ee1c4f),L_(0xfff40ea6), LL(0x70cd0820,0xba72fb3b),LL(0xab738bd2,0xff5688ad),LL(0x3ae40925,0xb751810a),L_(0x1c7232bb), + LL(0x071a0770,0x01bb4b01),LL(0xe2be9f54,0xd05cc7e3),LL(0xc3b59e15,0x14e1dc86),L_(0x84ea67cd), LL(0x1ee66ae0,0x743d3ae3),LL(0x9ac0bdc1,0x75487d37),LL(0xb272a24e,0x18ad2d25),L_(0x449e4286), + LL(0x69935fe7,0xefec1497),LL(0xee46b002,0xb3e61f3f),LL(0x1edeaf36,0x2b4abccf),L_(0x1302e388), LL(0x6554f5f3,0x0fe91c0b),LL(0x2afabbc7,0x613c238b),LL(0xf8ba68b0,0x0b0ae516),L_(0x1941e2a5), + LL(0xbf0bc612,0x9c608ede),LL(0x5d82d268,0xc0f244de),LL(0x0b0057eb,0xd601464b),L_(0x12bdb6e6), LL(0x825a361c,0x4ff78a4b),LL(0xb0ac16af,0x6aed48bf),LL(0x1ae6fb3a,0xba8a9318),L_(0x06a955b7), + LL(0x09e379b5,0x9e14e886),LL(0xc7c1e466,0x2fb4d3e2),LL(0x75711ae3,0x036fce90),L_(0x780c6067), LL(0x2542f70f,0xa4a903d2),LL(0x08ed6419,0x95852fe8),LL(0x637b247b,0x012141cc),L_(0x7a1653d5), + LL(0x9af74289,0x41ab3d86),LL(0xaaab79ee,0x29c26aaf),LL(0xcccef77c,0xea5535b0),L_(0xde9a50c2), LL(0xc11f99b2,0xb7f340c5),LL(0x0418cc51,0xfc229594),LL(0x8f5c0876,0xf20b5874),L_(0x79b716cf), + LL(0xba865a56,0x6fae5df7),LL(0x3ec9a3f7,0x2fe39b65),LL(0x8329316a,0xc07b24cb),L_(0xb74832f6), LL(0xd09a26ea,0x1af7d473),LL(0x95d78e89,0x375af56e),LL(0x62993ad0,0x957236cb),L_(0x20cfce9e), + LL(0x3e2c48a4,0x427f5e06),LL(0xe42acf84,0x25837ce1),LL(0xcae65a88,0x966e8b1e),L_(0x2aeaa288), LL(0x9e77f90b,0x306bd895),LL(0x4c375d76,0xd4ed09b8),LL(0xa2585522,0x47a8a9ab),L_(0x875a22b3), + LL(0x1e6ed175,0x8c957fe6),LL(0xcd21f453,0x54818bf4),LL(0x2495a8a9,0xdd977b92),L_(0x2e72900a), LL(0x05a5967e,0x2647b9d2),LL(0x92967328,0x53df8e0b),LL(0x496697af,0x5247a639),L_(0xa66c4dd0), + LL(0x8424e440,0x682c252e),LL(0x6fcf171a,0x0bb6bcff),LL(0x17581f41,0x040d50d1),L_(0x84837a70), LL(0xd070dc3b,0x686cbe64),LL(0x303cfa74,0x3485fd98),LL(0xdfd534bf,0xf0aec283),L_(0x6e4f877a), + LL(0x4458831e,0xbfa63a77),LL(0xa0bbdaf7,0xe6ad6640),LL(0xeffc865e,0xa2922966),L_(0x3c188024), LL(0xae34f5ff,0xec39a211),LL(0xc033bb37,0x5d5de65c),LL(0x1ffcbe06,0xae549602),L_(0x0aa2449f), + LL(0xf7d9eb1b,0x008bf1c7),LL(0x17af13bf,0xdce3e9ef),LL(0x7341adb2,0xe6aba225),L_(0x3fdc83ba), LL(0x52473c29,0x58df1458),LL(0x8e82cc6d,0xcbca23e4),LL(0x64a68f69,0xdc93a2bf),L_(0x402344e1), + LL(0x12f4285e,0x289cd434),LL(0x0df1904f,0x2614d391),LL(0x5132c5c4,0xd24f8d84),L_(0xd529b441), LL(0xb496fb70,0x945d4d6b),LL(0xb4fe1324,0x64d58e9f),LL(0x226ba20e,0x78fadda9),L_(0xf5638c8c), + LL(0x15c734f0,0x71f5ab8b),LL(0x7c5f3148,0xd644b74c),LL(0x8a5a08f7,0x5b9eaf3f),L_(0xcd76894b), LL(0x40783f5a,0xfc35396c),LL(0x5e5b4f20,0xdf4e44eb),LL(0x698ace20,0x85de5335),L_(0x32cc1f5f), + LL(0x4ca6d829,0xc01805fa),LL(0x69a66ff0,0x9b659d62),LL(0xb0bfec7f,0x21ba53df),L_(0x41d8db1a), LL(0x3ca3ffdc,0xaaee16f0),LL(0xac0d7259,0x2829c022),LL(0x8266c12f,0x570a8b63),L_(0x347c6b96), + LL(0x27c7435f,0xc2862c3c),LL(0xd60a5c54,0x577136cb),LL(0xeb454a5e,0x41bf3bc1),L_(0x809d3205), LL(0xd5ff2a5d,0xce2b3472),LL(0x201d2be5,0xabfed878),LL(0xdae3ae7c,0x076254af),L_(0x898c8347), + LL(0xfbee92e1,0x288eeccf),LL(0x6cb1db6b,0x9cfb5c57),LL(0x059c298f,0x53598af7),L_(0x7eda1da0), LL(0x888186af,0x3084705f),LL(0x2f592293,0x86f1d164),LL(0xc59e084e,0xa44fd074),L_(0x3a1664aa), + LL(0xd2343b35,0xa40a6bf8),LL(0xad9e07a1,0x798ceee2),LL(0x27b865e6,0xe4570eb1),L_(0x148877c2), LL(0x8f87d685,0xf0ce5967),LL(0x66f1b39c,0x66b1f5c4),LL(0xcbcc053f,0x2f8869b5),L_(0x9fa693dd), + LL(0x0d7b69df,0x17f0c4dc),LL(0x135a9bac,0xa20e8614),LL(0xabbfb492,0xc7dc6a2c),L_(0x89df23fa), LL(0x2759d406,0xcc56f093),LL(0x7c85ce0d,0x049b5aa5),LL(0x4e1f566b,0xbec87c76),L_(0x19e59ca6), + LL(0x40e840f6,0x1f1c6ca8),LL(0x67aa4467,0x2d21e27a),LL(0x9ca6123e,0x1d5e2c46),L_(0xa8534061), LL(0x5531352f,0x009d49a6),LL(0x161c45f4,0x43dffb38),LL(0xd020075d,0x2f8a3d38),L_(0x25c709ee), + LL(0x5ded0d35,0xd70c960d),LL(0x0bc185ca,0x08b78436),LL(0xbcbebb9e,0x662ab949),L_(0x7643c75a), LL(0x1d7a378d,0xcd6abb3b),LL(0x156ac08f,0x991364b4),LL(0x4dbff4b2,0x6e088465),L_(0x1596ba10), + LL(0xf7fff47a,0x8b812163),LL(0xabc30e47,0xad939c3e),LL(0xd700d28b,0xe8837ac3),L_(0x35b89ca7), LL(0x26712ef3,0xd89edbf6),LL(0x9b73a154,0xeaa73bdc),LL(0x536ef396,0x19770554),L_(0x44c569b4), + LL(0x7f3d2320,0xe904178b),LL(0x58a07ae9,0x7ff297bf),LL(0xad6fdd69,0x6deef5b5),L_(0x4df1d514), LL(0xda650bfe,0xc9fb4677),LL(0xdc9c7db6,0xd99a935e),LL(0x93d1a532,0xbfdd1320),L_(0x939080be), + LL(0x0e07db7e,0xfed77923),LL(0x579fd4db,0x0f05670b),LL(0x112a7ade,0x6e79da66),L_(0xb61b7ee5), LL(0x201e8aa3,0x567d0dd8),LL(0x07f189a5,0x9a0b34dd),LL(0x6a730912,0x5c656713),L_(0xcbc9583d), + LL(0x9522c2ad,0x1cf99a2e),LL(0xfaa41b68,0xbfb9ae12),LL(0x1fe851c4,0x91215bb4),L_(0x7117d94a), LL(0xbf89747d,0x6286cdba),LL(0x9cbfd3ce,0x792aeb4e),LL(0x25b00fa8,0x61f48d5b),L_(0x7160f470), + LL(0xa1ce4a2c,0xbe45da68),LL(0x3b1ab97d,0x63ee425c),LL(0x98b17978,0xd26e1784),L_(0xa89d00db), LL(0x5fcc8cf1,0xecb80c24),LL(0xdcee4667,0x3e21c95c),LL(0x1df7f32b,0xb9cc6c4a),L_(0x77cd2dd5), + LL(0x61766f4d,0xa5778295),LL(0xf4e5e3be,0x34307913),LL(0x57f4defb,0x71c105c8),L_(0x3add4e70), LL(0x2096768f,0xce51bf21),LL(0x8db7461d,0x3117821e),LL(0xf475048e,0x2b073db2),L_(0x1fd13104), + LL(0x70678950,0x4426eaf6),LL(0x4191c57d,0xd1c53be2),LL(0x68f854e3,0xce0157db),L_(0x5837f49f), LL(0x5112a49e,0xa0471f83),LL(0xf2d94f60,0x87e0a2d0),LL(0x9f64998d,0x344b223b),L_(0xa4dc016f), + LL(0x3ad984a8,0x3bd4bc94),LL(0xd8e29806,0xc17ca92f),LL(0x4aee7a72,0xfcd30768),L_(0x488c7f42), LL(0xa1f41f77,0x6fdb5587),LL(0x6983a223,0x3c2763ba),LL(0x0145b604,0x6e18b2a2),L_(0xfd8b9df0), +}, +/* digit=16 base_pwr=2^112 */ +{ + LL(0xa72d343c,0x006aff79),LL(0xd1d45ac5,0x1ec739c8),LL(0x136d5ba5,0xce9ce64b),L_(0x3571e770), LL(0xb11ea221,0x7bfe943d),LL(0x6d87fbd7,0x57dad905),LL(0xac86bd3f,0x5eeba8a6),L_(0x8def8e05), + LL(0xb0b49014,0x31f50c04),LL(0x17dee513,0xd8fab554),LL(0x1d543cec,0x2fb0a285),L_(0x53dbc27d), LL(0x3256cf6a,0xf3bd35dd),LL(0x5fbdcac3,0x8a264f23),LL(0x7dff3a00,0x24830923),L_(0xea9fd27d), + LL(0x3267fa62,0x7dfb1e52),LL(0x423506a7,0x34e86055),LL(0x552bcdda,0x131f5b56),L_(0xbbff309a), LL(0x40256e8d,0x61212776),LL(0xd0114404,0x3807bd7b),LL(0xbba74ace,0xa2ce6ab3),L_(0x9f9afd63), + LL(0xfd519550,0xd0706483),LL(0x53c2383f,0x89215ea5),LL(0x45e8a87b,0xf3cf4080),L_(0x6ab16c59), LL(0x85c8552e,0x09212e02),LL(0xa9576c54,0x10c2badf),LL(0x19c8db39,0x7b08661c),L_(0x32334cfd), + LL(0x9e15fa47,0x148c6f0e),LL(0x64a29d06,0xdb00031e),LL(0x4cc0f2bb,0xc3df9d3a),L_(0x2503f091), LL(0x1ff47bb8,0x620b581f),LL(0xb30724ed,0x5758802f),LL(0x4277ac9d,0xfc122be2),L_(0xcbf16ba0), + LL(0x1336d2bb,0xcd5bed69),LL(0x59c4c7e5,0xedd85962),LL(0xac1f77dc,0xea62aa43),L_(0xa9cecef3), LL(0xf970f802,0x25fc53f3),LL(0xb9f73243,0xf9d1654d),LL(0x9f9753cc,0xb61c3720),L_(0xbf308c03), + LL(0x96dca6f8,0x6461f973),LL(0x48986188,0x1f57a9df),LL(0xb90ca0df,0xb010f7d3),L_(0xe0bff3bf), LL(0x21188095,0xf21e0d4d),LL(0xa1a7cdb0,0x5f3468a5),LL(0xde0d0f24,0x4e99f334),L_(0x2e30f9fb), + LL(0x70d90130,0x7c2bf741),LL(0x95a93740,0x47c7e114),LL(0xb309c07a,0x977513df),L_(0xf1b8dcbf), LL(0xbe1ac3e9,0xb7e947d5),LL(0x92ee6dbc,0x09c3181d),LL(0x41e0c220,0x8b26dfc1),L_(0x897d02ce), + LL(0xfa332321,0xbb0f1fc0),LL(0x69d913b4,0x68034aec),LL(0x784ebda5,0x58fb05ab),L_(0xb3fd4405), LL(0x32cca1fd,0x83e2269c),LL(0x330bdb45,0xea0312b8),LL(0x33fa100f,0x1761c87e),L_(0xf9882c81), + LL(0xf4f00cb6,0x58c8e52b),LL(0x468b810a,0x99489e98),LL(0x5593b9ee,0x7924f02b),L_(0xbf5732d6), LL(0x0334e2ee,0x2a2bf206),LL(0x9c377382,0x41ac277c),LL(0xa7b08209,0x0c5c176d),L_(0xb9b519aa), + LL(0x1aabcb40,0x1450434d),LL(0xce36050b,0xcf82a49e),LL(0x0e6c721c,0xec192907),L_(0xc53a6a39), LL(0xfecc2ffe,0x451e72f3),LL(0x5b5bffe2,0x81bf062a),LL(0xe8852ddc,0xf84db443),L_(0x6d98976f), + LL(0x32a2e887,0x8b6ac261),LL(0xb92b83b0,0x3c40d7a5),LL(0x1ea4ca4c,0xf7653f1d),L_(0x4e2014e8), LL(0x2b234800,0x56338adb),LL(0x3350e80f,0x314b0e58),LL(0x8e442705,0x79527139),L_(0x96bf154a), + LL(0xd63c1701,0x1101a669),LL(0x5972ea79,0xd06390a9),LL(0x501cc189,0x0fb428cd),L_(0x41b24261), LL(0x0a3108ab,0x47aa9e0e),LL(0xff7237f2,0x9c9d8b16),LL(0xe86804cc,0x61ad5482),L_(0x723214f3), + LL(0x44329550,0xebe782ea),LL(0x4bfefe5b,0x11e7dc71),LL(0xf9379d6a,0xfb5f9f2d),L_(0x016789fa), LL(0x98c8071f,0x3aaef819),LL(0x0fa53740,0x3d2ba5a3),LL(0x0cd97039,0x2ceebe22),L_(0x144818d7), + LL(0x6646c444,0xc3bd60cf),LL(0x1bea68cc,0x7c4048fa),LL(0x5e74dbe8,0xd29b1f65),L_(0x08428502), LL(0x91eb1131,0xbb7b08f7),LL(0x64a0eea4,0x3c5f214f),LL(0x6e37d0fb,0x85ea7863),L_(0x3a3aec39), + LL(0x87af66ae,0x26b2f70c),LL(0xb4a6f150,0x5494f6a7),LL(0xf84408cd,0xa24b6575),L_(0xb95400d4), LL(0xfb2baa36,0x7fdee2e4),LL(0xfc9f2464,0x82709ae0),LL(0xd231d3ab,0x8897d9e8),L_(0x4c1905ed), + LL(0x43e3a796,0xc93592ff),LL(0x194deaea,0x9aebe35d),LL(0x3c64092f,0x1d7432bf),L_(0x64ab56a9), LL(0x608467bf,0x61dd14ba),LL(0x64e82c68,0x1c6431e0),LL(0xb4aaeed1,0x53076cd4),L_(0x2ded5d91), + LL(0x064ac09f,0x3e9b39b0),LL(0x087b2333,0xd8bc5839),LL(0xc348b809,0x8ab0974b),L_(0xdf5fc364), LL(0xf886797e,0x9cb572eb),LL(0xba2f94be,0x9a9ce85b),LL(0xa4a7eaf7,0x0e1605e0),L_(0x3070f698), + LL(0xbe868d80,0xeca36ddb),LL(0x52ac8d98,0x86bfcb64),LL(0x9b8656b8,0x2ab84426),L_(0x8306d84c), LL(0x01fe86cc,0x15f75f0e),LL(0xe9502973,0x4c2d70f4),LL(0xf239468a,0x365ce9d3),L_(0x7dd8e76a), + LL(0xd3426970,0xe0e930b3),LL(0x19af19f4,0xcb67c28f),LL(0x163565e8,0x312a9e2c),L_(0x0438b01e), LL(0x54d76d69,0x3b508871),LL(0x2b43ad8e,0x71ee55a1),LL(0x4dfa9969,0x0a025c8a),L_(0xe6813e1d), + LL(0xc327e03a,0xf0b0b5d0),LL(0x46569e00,0xb462d687),LL(0xa70b2c73,0x842f549f),L_(0x18faac6a), LL(0x864e3871,0x0b583d9c),LL(0xf49df9a7,0x1693a8f2),LL(0x5135df56,0xadecd5ac),L_(0xe9e25ac7), + LL(0xe8f3d99b,0x04c439d1),LL(0x811daa39,0x79057450),LL(0xed15dbf2,0x557c06cf),L_(0x3a8a2063), LL(0x09b41a1f,0x0bdc4dcf),LL(0x71cd60e9,0xf085eab4),LL(0xdab0c931,0xb48d6df1),L_(0x8189574b), + LL(0x4a27c44c,0x2e80ab05),LL(0x7a2bc54c,0xdd9e1375),LL(0x242b815a,0xa910e496),L_(0xd9fa2e90), LL(0x3f111c1d,0x0c5343f8),LL(0xb573bc74,0x10be67cd),LL(0xf1c6ef62,0x4ae541a2),L_(0x74676666), + LL(0xc5669a28,0xff0e3e5f),LL(0x6a94d97d,0xe911fae7),LL(0x85cd9be2,0x4150b30c),L_(0x41391baf), LL(0xab441ae7,0x92888eaf),LL(0xd928ee21,0x0dd62a7d),LL(0x1b7b37eb,0xe9e642a8),L_(0x61afa524), + LL(0x15d73eaf,0x70f4b3ee),LL(0x10edc9d7,0x70ff29ef),LL(0xe8787785,0xe5dce106),L_(0x3877e81c), LL(0x36b7ab1b,0x21a140c0),LL(0xf44e41b6,0xffda816e),LL(0x9bd299e0,0x5968ca97),L_(0x9fed2d11), + LL(0xb0d9d8cd,0x6b2cc953),LL(0x12446f29,0x932fd885),LL(0x8fc62139,0xb782380e),L_(0x93475be3), LL(0x83692f15,0xb2525747),LL(0xe5afa458,0x2213b2d5),LL(0xc34bb49f,0x0270ba84),L_(0xa86bdfc6), + LL(0x3b925a7f,0xe649f779),LL(0x72b7e377,0xa3785aef),LL(0x20ce9dd7,0xdc5dbf9f),L_(0xb05950ec), LL(0xa5d677f5,0xcdc8d1f8),LL(0xb5473ac8,0xd8d3e9cc),LL(0xb698eb06,0x5cbd0981),L_(0xc3f31c81), + LL(0x1e752016,0xf090a1eb),LL(0x644b9e14,0xfc5f6857),LL(0x111a1741,0xbaf89d9f),L_(0x01aef06c), LL(0x1b1a1911,0xbfa9551b),LL(0x7145d55b,0x24a70db9),LL(0xc5ef4f06,0x17130b26),L_(0xb33cca3b), + LL(0xfcb5b043,0x911935f4),LL(0x4a8bc08e,0x53ed6fbf),LL(0x90634826,0x4421e383),L_(0xe0140eb6), LL(0xc4143e7b,0x12ccf145),LL(0x94d99fc8,0x5bf8b6c9),LL(0x4f765081,0x73883a6d),L_(0x6767c401), + LL(0x997c821b,0xe367cf8a),LL(0x246522bf,0x3d0455b7),LL(0xe8c7bcd6,0x92643ab4),L_(0x10fbb420), LL(0x547dbeb2,0xb5294491),LL(0x4b5c792e,0x07450e44),LL(0x472a47f1,0x5e3d3784),L_(0xd9dc604f), + LL(0x6372566b,0x4d62de9c),LL(0xbc29741f,0x7a323977),LL(0x78458eba,0x4b2a04ff),L_(0xdc2f1c5d), LL(0x6819a84d,0x0eccbf7e),LL(0x8ee3cc6d,0xb93eec58),LL(0x2a02a086,0x03b76658),L_(0x51df6b51), + LL(0x6aa0f608,0x0cbee27c),LL(0x00ecc369,0xae1d1601),LL(0xbbef8dbb,0xe7149786),L_(0x4036b3f1), LL(0xbe686d04,0x91ce3c48),LL(0x339d0769,0x3d6535b6),LL(0xa72c8f85,0x2c9fb75e),L_(0x0a96cd51), + LL(0x39dd7c75,0xeebc8c18),LL(0x799170f2,0xa2f0fb39),LL(0xba0f68a4,0x1c5cad2c),L_(0xb5b8faf2), LL(0x3f59abfb,0x3a302769),LL(0xcda64ecb,0xed44c055),LL(0xcd7fd1b9,0x2e974b80),L_(0x7a2910b3), + LL(0xc8f85c88,0xf503e456),LL(0x9dc39b84,0xb53e74a2),LL(0x8eb76194,0xc4c55423),L_(0x96e13302), LL(0x153fefbb,0xdbbf4e12),LL(0x77137bad,0x80b3f693),LL(0x65187422,0x9f8c212c),L_(0xdd256603), + LL(0x0fcf5a39,0x6da81ce6),LL(0xb694d211,0xdff4777e),LL(0x4a9fa32b,0x602640c6),L_(0x5470aa01), LL(0xa3b241c7,0x2a545f4f),LL(0x33f7dd48,0x4cf94265),LL(0x8a894ff1,0xb5260296),L_(0xd9db2162), + LL(0x7320211d,0x391c4f62),LL(0xf472fe07,0x6d039385),LL(0xbaa68de6,0xc3a5b977),L_(0xde6b274a), LL(0xbca0bb5d,0x3643a502),LL(0xc554c3be,0xe1f5b66b),LL(0xa430cadc,0xb32e7ba4),L_(0x0c4ee9d5), + LL(0xd36efcf1,0xb6b2c682),LL(0x0eae66b5,0x1024c516),LL(0x8688f303,0x99e728ff),L_(0xb372d118), LL(0x777d2fdf,0xd972734f),LL(0xd9b90e14,0x25251453),LL(0xf34097fd,0x424404cf),L_(0xc047b89b), + LL(0x3079239e,0xb5ff46f3),LL(0x60a4632b,0x36a3735f),LL(0xc9986723,0xd572091f),L_(0x2023152d), LL(0x0dabffd6,0x0da45042),LL(0xb1524e2b,0xf6ffaf4f),LL(0xbffef0a3,0xbc330b9d),L_(0x99ba1268), + LL(0x3b961738,0x8d236f27),LL(0x3ea1c105,0xa5f014ae),LL(0xee0ae6b2,0xe50d6b9c),L_(0x82eb66db), LL(0x2b5f008f,0x36e3aea7),LL(0x4b4fc9df,0x2f8e4e4e),LL(0x5ccc02df,0x9f683f7c),L_(0x3e46d9c7), + LL(0x7caa8791,0x6c2cdda1),LL(0x3274eefe,0xa9cdf2c5),LL(0xb634f00e,0xd5eec010),L_(0xc5ba5f67), LL(0xa6a18c32,0xde736bf0),LL(0x554e6af6,0xc1059185),LL(0xb7a29e2b,0x9b23923d),L_(0xbfed0131), + LL(0x7000c5a3,0xb80400e7),LL(0xf87a8596,0x147ccc0f),LL(0x9e3b070e,0xfef094f1),L_(0x36f53f39), LL(0xefcc38e1,0xf5b77a62),LL(0xb1c0b71d,0x2c523e41),LL(0x02efb3f7,0x210639da),L_(0xf54c9329), + LL(0x330449ca,0x7b06f635),LL(0x0b195c0b,0x9efabcec),LL(0xe879f10c,0x3bd206ba),L_(0x25bef90b), LL(0x0312bdf4,0x88e64b25),LL(0x29334071,0x3a8f90eb),LL(0x3e832f84,0x14f38ac0),L_(0x8a3f7e05), + LL(0x4bafc9dd,0xb6461cb6),LL(0x75d1e03c,0x266ba391),LL(0xf40aa6ef,0x4715355a),L_(0x38cce560), LL(0x1adab378,0x716f224c),LL(0x38711bba,0x32b71c39),LL(0x7e89026d,0xccbd7f4e),L_(0xcc519b13), + LL(0x7de43131,0x0bbfe1df),LL(0xb1b9786c,0x10701821),LL(0x0bc2e01c,0xf68b86eb),L_(0xf6a6da2b), LL(0xad3f4af5,0x67e192cc),LL(0x6b4b9ef1,0xd5fef609),LL(0x52b649b2,0xf428af30),L_(0x7e90cd58), + LL(0xe78176a6,0x0b536242),LL(0xaae8f896,0xdbdd8b1f),LL(0x503b274a,0x51151bfa),L_(0x60ba1217), LL(0x393d4fa6,0xdc4e6926),LL(0xdc183c7c,0xe68387c3),LL(0xaaf0a35e,0x06168aa4),L_(0xb2853fe5), + LL(0x2143ebc1,0x4be98451),LL(0xbb1ddca8,0x10163229),LL(0x5db7c140,0x8229e729),L_(0xca486360), LL(0xc19bdf58,0xc8df52e4),LL(0x560cd486,0x89b605d0),LL(0x2a200cdd,0x0c94090c),L_(0xb1ef5103), + LL(0x4588f760,0x0c217b21),LL(0x92ea3d28,0x90f7c008),LL(0xef37649d,0xddfaf799),L_(0xfddee462), LL(0x3d0294b1,0x510fffdd),LL(0x1bcf376e,0x4a21ba9d),LL(0x6c9d2cfa,0xa7ada78e),L_(0xca77a07b), + LL(0x1db377da,0x63e01d3e),LL(0x5a90911d,0x8c9ad4b9),LL(0x6bb31b8b,0x2b26fec2),L_(0x30e44c9b), LL(0xfeaf9d42,0xe2652b65),LL(0xf5866de8,0x03b48401),LL(0xee2505a9,0x2438e370),L_(0x7a7bb613), + LL(0x900098e6,0xd8a6e8e7),LL(0x830770af,0xd8452a93),LL(0x2e2cd25b,0x569bbc5f),L_(0x61715beb), LL(0x80e8caaa,0x3f76b251),LL(0x6dff2aa3,0xeba89ffa),LL(0x18acb601,0xf763dfc0),L_(0xa2dd440c), + LL(0x24370f96,0xf5f4a36c),LL(0xbf3c4689,0x527f5322),LL(0x43417948,0xe0b12bf9),L_(0x012f5cea), LL(0x6aa04128,0xb3183162),LL(0x2fa9d189,0x1070f9c1),LL(0xe002ccee,0x5b0c2b4a),L_(0x5840d505), + LL(0xfca649ba,0xb223ef3b),LL(0xbe1308ed,0x4aa0b0e6),LL(0x10592f0a,0x3d9b366f),L_(0x3859ac39), LL(0xab61a042,0xaa721fec),LL(0x7c5e75a3,0x0a96a720),LL(0x06be6fd2,0xb3b3cccc),L_(0x9eb8c9a0), + LL(0xfda2de37,0xd8576cc3),LL(0x1c4530fa,0x22b5be7f),LL(0xaad70136,0xc40c9235),L_(0x785c8acf), LL(0x9edbb745,0x501faa81),LL(0xc7fdb942,0x60c831a6),LL(0x6f69ca6e,0x813a83b7),L_(0x04f82291), + LL(0xdbe3e246,0x4f871623),LL(0x56664b79,0xd2c645ee),LL(0x18c48541,0xc037f50e),L_(0x569420f7), LL(0x08342ef8,0x68cc0cb0),LL(0x19c07325,0x0c4fa826),LL(0x186c66ac,0x8f28f4b4),L_(0x34c938cf), + LL(0x837493cf,0xf41079e1),LL(0x433d8394,0x1a861703),LL(0x0e538567,0x03e474ae),L_(0xd2b95886), LL(0xa188c7eb,0x76610ad6),LL(0xe08cbcbd,0x706eb272),LL(0x8025f126,0xb5435d24),L_(0x5ba9b4af), + LL(0xc4faeda3,0xd9ddd6dd),LL(0xf3e74637,0xe2be7abf),LL(0x4eea6f06,0x2e6abaae),L_(0xd79c705f), LL(0x99f8dc46,0xc8502a73),LL(0x2f4fd6ed,0xa0aa0199),LL(0xcbc5ed2a,0x38689f49),L_(0x55280ac3), + LL(0xfbd4773f,0xb3548b14),LL(0xd9714b0f,0x18cea1f4),LL(0xb3c65f79,0x3bc435fc),L_(0x2867e8b0), LL(0x0706d139,0xca5b9f90),LL(0xe62b0a3f,0x14b87e76),LL(0x864343f5,0x8a82e1fd),L_(0xcbeb5bc7), + LL(0x18cc1c83,0x0026972b),LL(0xb17ec512,0x1da022c5),LL(0x2265f4c6,0xb898d6b7),L_(0x5d09e5e7), LL(0xa53eabdd,0xef23c0bd),LL(0x92d24054,0x98e844f5),LL(0x05f9b046,0x7d2e87fd),L_(0x3f161352), + LL(0xe7c2033e,0x1c9b4b3f),LL(0x29dc2f02,0xf61d0ee2),LL(0xdb5834bf,0x28b5943b),L_(0x065b016c), LL(0x5de6ece7,0xf70c350f),LL(0xf1049294,0x1c3bfb3b),LL(0xd4c8be79,0xe75564bc),L_(0xb3dd4c16), + LL(0xab2cc7d8,0xa4b41a9f),LL(0xbc199c52,0x912b7247),LL(0xe6362cfb,0x6a214d2e),L_(0xe939b311), LL(0xc25479e6,0xf1652743),LL(0x06ef2b5a,0x3bcb10e6),LL(0x9be1e8e0,0xbede8ea6),L_(0x638ffa1e), + LL(0x31630309,0x706d16a7),LL(0x3ba8e623,0x9f2f55c9),LL(0xed0db8c6,0xaf0d2787),L_(0xba630c04), LL(0xb9e7f044,0xce8001ee),LL(0x10c159b4,0xb8247bef),LL(0x658e5458,0x78f60572),L_(0x922d3798), + LL(0x5c6843ce,0xacaada1c),LL(0x8794be44,0xcabaa3a1),LL(0x36370b66,0x507a17a3),L_(0x943c28ea), LL(0x481b026e,0x48821bb8),LL(0x3885a0a3,0x5ed8e5b9),LL(0x78f46113,0x6817009d),L_(0x1451c3b3), + LL(0x7560c539,0x75119a00),LL(0x953124bc,0xe00d03ba),LL(0xef71ab39,0xb863df63),L_(0xfd67781c), LL(0xfedea07d,0xddc4f0d5),LL(0x332679da,0xc43e8f08),LL(0x36d08634,0x9efb1f02),L_(0xa0922f94), + LL(0xba05b2e6,0x949d9990),LL(0xd565ff0f,0x76e4e628),LL(0x6c281fa8,0xdccad172),L_(0xcdea3fff), LL(0x6b13eba7,0x70f4d75c),LL(0xd884ce93,0xd34756fc),LL(0x70986d34,0x8f71b0bd),L_(0x430f43f0), + LL(0xe10a7afd,0x0a9b3e69),LL(0x66948394,0xf0719c40),LL(0x046cc610,0x9d1611b2),L_(0xda89278b), LL(0x6b7a1ff1,0x24d9cfba),LL(0x638bd7b1,0x5bd30853),LL(0xa740e80a,0x1159e67f),L_(0xe45ccb34), +}, +/* digit=17 base_pwr=2^119 */ +{ + LL(0x5898fc39,0xa3566efe),LL(0x23845a77,0x24bb02bf),LL(0x91ab4316,0x00e46ee0),L_(0x83d35ab7), LL(0x8c02881d,0x1d20ad25),LL(0x5866ad97,0xb01ce79f),LL(0x40d6ae86,0x40b2c06e),L_(0x613bd7a9), + LL(0x259779c6,0xafc1d993),LL(0x8a7cf112,0x86dcdc82),LL(0x77170d32,0x8441f4f3),L_(0xb0280bfe), LL(0x46144a82,0x58df739b),LL(0x5ee74a89,0x344ddb0c),LL(0x01761502,0xd9bcbeb6),L_(0x676d4eda), + LL(0x66de5a2e,0xbc92b6dd),LL(0x7b186d5d,0x1127f258),LL(0x3d18ed03,0x3982ee92),L_(0x50719e4f), LL(0x0deb6e5c,0xcf198f32),LL(0x09997437,0xdbaf1a5d),LL(0x373c1801,0xf524b8bb),L_(0x73564dbc), + LL(0x1bb01e24,0xdc5e2b63),LL(0xaca4f30b,0x5df11c5a),LL(0x68e597b5,0x44ec319c),L_(0x8b90301e), LL(0x0e27f5b1,0xe5706d53),LL(0x8b76e26f,0xe67b3280),LL(0xa7111b5d,0x8fa5ee02),L_(0x7b4c92ce), + LL(0xe429fedd,0x0035c84e),LL(0x867c82eb,0x2ea6f134),LL(0xa3e74746,0xb9e352c0),L_(0xaebebaa5), LL(0x220bb556,0xb02520ea),LL(0x95bda416,0xe4b94f8e),LL(0x16dbb87f,0xfbff49d6),L_(0x5707ddc9), + LL(0xda91cf49,0xdb33cda7),LL(0x450672ba,0x006b3e24),LL(0x489cbfa3,0x4461fe49),L_(0x3d14a461), LL(0x4d93f4e2,0xfe8e5310),LL(0xb7769c82,0xf3d0d29d),LL(0x94deaf7c,0x3d33e2ad),L_(0x3b18c763), + LL(0x453d6839,0x8f1b71e2),LL(0xf6d77216,0x923024ff),LL(0xf76bc681,0x17e6ad54),L_(0xe16b7b80), LL(0x66dcecfa,0xe97810bb),LL(0x94c6a912,0x13de9f05),LL(0x30c9e7f2,0xf16b622f),L_(0xa2fbcfd3), + LL(0x436d6b95,0x794d49e6),LL(0x3831fe74,0x702ede17),LL(0x5afaacb1,0x3b5ca68c),L_(0x1bea7d66), LL(0x9ca7b740,0x50a1e66e),LL(0x8f17d122,0x762e4f6f),LL(0xc90185b1,0x6705418b),L_(0x36b69158), + LL(0x52070a5f,0x9065afef),LL(0xa326ad21,0xe6df0c7d),LL(0x441709b3,0xa1396423),L_(0xade77b6a), LL(0x66868b27,0x14f84f84),LL(0xd0d002f8,0x1fa90792),LL(0x19c083f9,0xfd8d88ee),L_(0x57fe75c9), + LL(0x5330a97a,0x77ea9ee9),LL(0x00005025,0xce00962f),LL(0xae5f476a,0x05915824),L_(0xdba736d5), LL(0x8cdf0301,0x660a19e4),LL(0xee8a2aed,0xc70e0b10),LL(0xfdd0563d,0x41d445a6),L_(0xede64633), + LL(0x53d54a0b,0xa5729cf8),LL(0xb0c860cb,0xea907454),LL(0xea0c5a91,0x59a871ce),L_(0x9efd302f), LL(0xe025ffb1,0x7e7fb9d6),LL(0xc8022642,0xb7954f0d),LL(0x46ca7ee6,0x010dbf77),L_(0x4bfdff6a), + LL(0x2d7e46ec,0x034b69ed),LL(0x850b3401,0x51bc6b66),LL(0x3c25755a,0xe9bf6717),L_(0x95d70595), LL(0x06b03b20,0xfc3e6ce3),LL(0x384f786b,0x723756d9),LL(0x58938357,0xb4731ae9),L_(0xa8628a04), + LL(0x42ddfb71,0x33bbd9fd),LL(0xc9ef16f4,0xeb7aa22e),LL(0x725fdf2d,0x88eb52e0),L_(0xa3454e1e), LL(0xf1fc16a0,0x297a7972),LL(0xda90c2e0,0xb92c9670),LL(0x9c2b4849,0xa557aadd),L_(0xb719cae7), + LL(0x58182a1a,0x27b6bd7a),LL(0x5c2d70bf,0x1c72e559),LL(0xd4f2f098,0x6b53e542),L_(0xb01de7e4), LL(0xb5e11023,0xa8f7b191),LL(0xb49a6846,0xe62460d3),LL(0xbdf84150,0x74ea071f),L_(0xf4211acf), + LL(0xe03c9ae5,0x54fef132),LL(0x9ad73091,0xa900e0bc),LL(0x1a602274,0x3698f6bb),L_(0xe357c5f7), LL(0x57e365aa,0xbb500025),LL(0xf19ef91f,0xf16e71f5),LL(0xa0dfe4bb,0x9d6899d1),L_(0x399ab86c), + LL(0x8e577079,0x8e833532),LL(0xabea4782,0xfb9fbccf),LL(0xf5ead3c9,0xe31f0c20),L_(0xe2d0d774), LL(0xc462ce8c,0x6466c045),LL(0xb27628d9,0x85e7447b),LL(0x3e1abc03,0xbba798a0),L_(0x0e905d6c), + LL(0x122d19eb,0x158f4312),LL(0x3f408e0e,0x297c5747),LL(0xa7b750fd,0x735aa3f7),L_(0xbe1aa687), LL(0x312d6129,0x31e8bfa3),LL(0x166c2e16,0xcc9cdadc),LL(0x5094cff5,0x9ea9beca),L_(0x2dea9edd), + LL(0x616ee97a,0x78257a1a),LL(0x7f5d51d6,0xec98f98c),LL(0x609d2d2d,0xd1b3e514),L_(0xe1569e97), LL(0x2e59e233,0x8087f780),LL(0x45e2a372,0x0b40b852),LL(0x95c2865d,0x8fa97627),L_(0xeeff0632), + LL(0x1eac58fb,0x7eb748d9),LL(0x9922cc63,0x0d0b673d),LL(0x955ae146,0x72be4e8e),L_(0xd6809bdd), LL(0x22b08d07,0xa4616bf8),LL(0x09a6ef9c,0xc55b68a6),LL(0x42138fbd,0x8fa529ef),L_(0x4dfbed1e), + LL(0xf1766b08,0xdfd72d39),LL(0xe0356587,0xad6b741e),LL(0x59466485,0x5fceaf74),L_(0x24d9205e), LL(0x0c6b2255,0x453c9eae),LL(0xb9402267,0x9c00d050),LL(0xa3817166,0xa87cf553),L_(0x43612515), + LL(0xad146ff6,0x39990110),LL(0x0f98feec,0x3d48a808),LL(0xfe9fea01,0x8c4aac12),L_(0x2443ed5e), LL(0x0ad5c79c,0x0a9a20f7),LL(0xd997c3c0,0x942b38bd),LL(0x9475c474,0x218031b5),L_(0xd3104cb6), + LL(0x4c0dcf95,0xcc4c491e),LL(0x234524ca,0xfa790f55),LL(0x12a6c289,0x37abf7be),L_(0x3e8c0631), LL(0xcb586fd3,0x192166df),LL(0x0c51f097,0x7ee1f233),LL(0xbba9c768,0xb69b46cc),L_(0x2fb2d51d), + LL(0x1443ddcd,0x6345a210),LL(0xecf6729f,0x5f035126),LL(0xc8273e38,0xdafd6230),L_(0x83e19f89), LL(0x4e79437a,0xb3e2d215),LL(0x6090e2e6,0x138aca38),LL(0x4afb3539,0x4ce64d55),L_(0x30dd853f), + LL(0x6b581765,0xc440084f),LL(0xeff7dc6a,0x088767cc),LL(0xf0d004bb,0x94e1ba30),L_(0xb9c2e7e5), LL(0xa1a18413,0xa732c539),LL(0xc31da773,0x896710e9),LL(0x3608f75d,0xa067bb07),L_(0xaa5451e2), + LL(0x98910990,0x65c3a1bc),LL(0xbcc70896,0x3321e865),LL(0xb04ac43d,0x438e5b9d),L_(0x43f7f50c), LL(0xe260d025,0xc4dcba5f),LL(0x79613445,0x5e5f5f4b),LL(0x37b1a0c5,0xd3c102f6),L_(0xa0273b2c), + LL(0x4e2d8d4d,0xe6546299),LL(0xd9309108,0x262d0cb1),LL(0x2df96d37,0x349292cc),L_(0xa711d216), LL(0x2fddedd4,0x452a0a52),LL(0xd9e54125,0x2293a068),LL(0xc6053861,0xfe3040eb),L_(0xfb5c3f2b), + LL(0x02a166d6,0x861af22b),LL(0xc493f8ef,0x449c202b),LL(0xb053bb62,0xbb664aff),L_(0xc5af5837), LL(0xd6f78a71,0x14a57ed2),LL(0x1edcfcb6,0x6c5eedb1),LL(0x591d0e00,0x0f079d9e),L_(0x6f7c473e), + LL(0x4ee2bac7,0xc62978b5),LL(0xeec393c4,0x0ee684b8),LL(0x56d30723,0xb8993d5e),L_(0xdfc904ce), LL(0xfc172756,0xc8622a7c),LL(0x73b2ec23,0x4279a0bc),LL(0x78cfee0e,0x3826553c),L_(0xd011a36e), + LL(0x9060272d,0xe29ecb65),LL(0xa0218247,0xdd976fe9),LL(0x53d3e99f,0x278ebed1),L_(0xbcea3ccb), LL(0x7a33fe7f,0x13d33afb),LL(0x1b5111c1,0x19d16dca),LL(0xe09a47ad,0x6e0ed440),L_(0x80396140), + LL(0xb55799e5,0xf145e8f9),LL(0x443b3b83,0x97e6d3d7),LL(0x4580043d,0x5f599a51),L_(0x2fcd83a6), LL(0x38414d95,0xe09d35b1),LL(0x8975407b,0x31551460),LL(0xce073290,0x1044bab9),L_(0xae80d126), + LL(0x045e586e,0x4d8f2d61),LL(0xc81d17ac,0x1d2b5b31),LL(0xb68b7f81,0x10bccde6),L_(0xdb1468c5), LL(0x0578898d,0x1e460079),LL(0x5fbad189,0x31bad31c),LL(0x3d22477a,0x8c371b62),L_(0x32c1f1f2), + LL(0xbc19767c,0x3ed7db29),LL(0x4ce61a9a,0xcc843c60),LL(0x45c30a38,0x508e3e86),L_(0x5c8b4727), LL(0x1457fcb7,0xd8c78825),LL(0x308a4222,0xc3997703),LL(0x2b88e6d2,0xa1f2140c),L_(0xbcc49242), + LL(0x2a452962,0x62444dca),LL(0xffa24655,0x2d1e976d),LL(0x1d95f51c,0x2bbeb1e0),L_(0x6ac09c41), LL(0x052daa66,0x827170a2),LL(0xbfaa5a51,0xc319b1ba),LL(0x3a8ec55d,0xda0c72a5),L_(0x9d0ac0b5), + LL(0x898419db,0x35d9c257),LL(0xbb8eaa1e,0x55758230),LL(0x4e49ddae,0xd5c3703e),L_(0x8e18cadd), LL(0x28d3f23f,0xa38dc679),LL(0x8ecf56aa,0x749ea0b7),LL(0x15724faa,0x68bb7f4b),L_(0xb2b1249d), + LL(0x0f227df0,0x24af0afb),LL(0x8232f88c,0x1cd97cee),LL(0xa2ad5165,0x678f117f),L_(0xa5067478), LL(0x03432db4,0x5cb93ad2),LL(0x610d26df,0xcc96e20a),LL(0x47d3d48c,0x5f1e84c2),L_(0x31ddfcd2), + LL(0xc4293aef,0x7f0db6e5),LL(0xe03b4f7e,0x9069c8c1),LL(0xa088318f,0xf4210d55),L_(0xe9cec920), LL(0x13bd2b28,0x34f3150f),LL(0x7de6ff6f,0xe152eb4e),LL(0x0fcf1527,0x32e6885b),L_(0x4f27fdfa), + LL(0xed8906ba,0x7eba0ca2),LL(0x615cf3d7,0xc91dbf27),LL(0xcf44aa02,0xf0948c8c),L_(0x346dc0f7), LL(0xbe7b7488,0x88539394),LL(0xe2e6a4a5,0x938fd6cc),LL(0x15b31f6a,0x1a1c6b6b),L_(0xe564ce23), + LL(0xc2869ed1,0x61ab3c9f),LL(0x5693bc05,0x3bb8c353),LL(0xb69781cd,0x95d9d719),L_(0x31986774), LL(0x3de229eb,0xc3895533),LL(0x72ce5e74,0xb6955022),LL(0x5ac0d29e,0x6e2ba9f7),L_(0x12310f9c), + LL(0xfe2a24c4,0xe3406a2f),LL(0x7a0fc1d1,0x67beb235),LL(0xf6867bb0,0x5b2cd123),L_(0xc3378be7), LL(0x2ff473c0,0xed6d88b5),LL(0x5fc0483f,0x046a1f51),LL(0x9b3025d4,0xf4a61d8b),L_(0x8b1ce295), + LL(0x99e19904,0x7e9f5e57),LL(0x5c52c743,0x00b84a5f),LL(0xbabc0faa,0x6de1d67d),L_(0xbf153310), LL(0x04041367,0x06672f11),LL(0x6650a578,0x0dd51cb3),LL(0xd4012aa6,0xd5ce357e),L_(0xf901856b), + LL(0x538e45db,0x5f595162),LL(0xf13e03cd,0xe917805d),LL(0x56a8bf52,0xf639993d),L_(0x043c78de), LL(0xe876b4ea,0x3eaf3c58),LL(0xe2439014,0x0ef45389),LL(0xbd9e742b,0x95404cfd),L_(0xce45f79b), + LL(0x1453ad22,0xf6e400ed),LL(0x0126443e,0xa4ababfc),LL(0xd78f1c8d,0x4ebc5852),L_(0x6149c4a9), LL(0x4e1ef091,0x7415270e),LL(0x84d52256,0x921cd6ee),LL(0x472b1f2f,0x765126f0),L_(0x33de4dc4), + LL(0xade7ead4,0x1b413797),LL(0x12c424fc,0xeabbca1c),LL(0xdb705e2f,0xa1e12595),L_(0xa616017b), LL(0xd199009a,0x79fa6f2e),LL(0x9168da3a,0x4d4d9e09),LL(0xbde588b7,0xc0ac97e6),L_(0x9a16a183), + LL(0x23cf39f8,0xca0fac28),LL(0x40729683,0x4b179b82),LL(0xb04c01ae,0xfaca0fdf),L_(0xdf006531), LL(0x7b3cc76a,0x3d2bf7fd),LL(0x7e32a952,0xf3f2fea3),LL(0x6369c1d9,0x866e7f8e),L_(0x8e8c8b64), + LL(0x6eb23ad9,0x8b9475ca),LL(0xe0c8ef8e,0x22d9fd00),LL(0x4e9a3adc,0x813270cc),L_(0x478c17a1), LL(0x292b8bdd,0x3db7f857),LL(0xe5e27f6a,0xf6ba5b62),LL(0x1b8a570a,0xe20966e7),L_(0x040d840b), + LL(0x19b8e7ad,0xe13277a1),LL(0x9ff0663a,0x6d26fe40),LL(0x8f8b7d68,0x0ce42976),L_(0xfa5a58e5), LL(0x48e32e15,0x0ee98d37),LL(0xbdd62d44,0x3bb6c2c8),LL(0x4db74aeb,0x208cd0d9),L_(0x55f387e3), + LL(0x47ef78f3,0x6c1b0959),LL(0x5e1f13ab,0x2ccd97f7),LL(0xa303c278,0xf9abf5b1),L_(0x3d97a968), LL(0x0276fd8b,0x2be1d396),LL(0x8b026a44,0x726beb4a),LL(0xe09517f7,0x4e0b499e),L_(0x502462c0), + LL(0x5979197b,0x82ffa270),LL(0x23bdd46d,0x52cb678a),LL(0x260e7e25,0xc541f700),L_(0x908eadfa), LL(0x33983072,0xb1d2f59c),LL(0x321cd9fd,0x11eef46a),LL(0xf2b04fe3,0x9fba737f),L_(0xe7bc6bb7), + LL(0xbcadb426,0x4d1d9a21),LL(0xb55fa843,0xe2a1f313),LL(0x2170c6a6,0xc15b9466),L_(0xdebbce2a), LL(0xd605b2bd,0x1578a3c5),LL(0xd1e52a96,0x96b6befb),LL(0xbe0b58ef,0xc4f7e33c),L_(0x93e465b5), + LL(0x3fcf43e2,0xb19e11a6),LL(0x508b2d4a,0x5ad2ed77),LL(0x6ff2a142,0xe587c79f),L_(0xa56c66b2), LL(0xb2ee2d93,0xa6fa95d1),LL(0x260067ec,0xac5ec114),LL(0x67b40c94,0x41c55249),L_(0xdc3ac489), + LL(0x6b551c3d,0xc6c2dc20),LL(0x3452633a,0x1b5233ca),LL(0x0e6faafe,0x4565862d),L_(0xfa2f6235), LL(0x08edb0b2,0xb2d31417),LL(0x6cfe0764,0xa0fa599b),LL(0x77052491,0xb2ac3ec1),L_(0xbcc97485), + LL(0x0302d5f4,0x04cf0b83),LL(0x37cf0d9a,0xbd701c39),LL(0xfb565431,0x5eee993f),L_(0xc5d3f450), LL(0xb5c3681b,0x5d285d50),LL(0xcc0e0a9d,0x8618542a),LL(0x8c1d7c52,0xd80996cc),L_(0xddcf4356), + LL(0xf0fe4630,0x12c3c8ab),LL(0xfb1a997d,0xb6349270),LL(0x2f148e5a,0xc0513e4e),L_(0x7a141833), LL(0xd043e9e1,0x340f7e04),LL(0x52e9cd98,0xb4acedf4),LL(0x5d6d0c14,0xfa56de6f),L_(0x2558f609), + LL(0x435b6bea,0xdb7a9959),LL(0xe6426f07,0x24fae08f),LL(0x3cd0982b,0xcc274d62),L_(0x7f805789), LL(0x02f3dea7,0x2a9bf937),LL(0x774708d8,0xadae4c03),LL(0x61de7f6d,0xba3c48a3),L_(0x8de4f729), + LL(0x2faaf033,0x7e8bb31a),LL(0x31c0bd80,0xd937aa83),LL(0x072c01c9,0xbfe57ab1),L_(0x201af074), LL(0x87c5d209,0x4ce95747),LL(0x5887d49e,0x7ee66e9b),LL(0xf01cc54c,0x48478c99),L_(0xa2993bcb), + LL(0x957c7ee7,0x50dc83b5),LL(0xacc25598,0xf0f63a80),LL(0xb4578760,0x842ee70e),L_(0x4ca0ed74), LL(0xc891093c,0x24bc2867),LL(0xfd1e42bc,0x0f85fa2e),LL(0x47bb6a4a,0x18cd7a2e),L_(0xa82a8343), + LL(0x4077391a,0x798cdd8c),LL(0x381485f3,0x68858372),LL(0xd2c5ede9,0xb240c94c),L_(0x7ec5555b), LL(0x62fa25b8,0x89e94f52),LL(0x25aa6ecf,0x0332347b),LL(0xf207ad5e,0x9e15c0d4),L_(0x865ae0a0), + LL(0x6d748e08,0x298a62fb),LL(0x549ffe32,0x8f7fb37e),LL(0x35f944a9,0x92926ab1),L_(0xe6fbe10e), LL(0xdc488cff,0x3f355ad1),LL(0xd2f1e956,0x84b0d884),LL(0x29d8cb57,0x98d39682),L_(0xae5bcaa6), + LL(0x07c8c79a,0x4957a527),LL(0x3263fbf3,0xec94fd37),LL(0x601424db,0xf147c20f),L_(0x01b4af1e), LL(0x1adc80ef,0x7d9440bd),LL(0x4bfaaf0a,0xee7355aa),LL(0xd1adde68,0xba4d5d2f),L_(0xbdf3e79f), + LL(0x4dc18b13,0xebadf0ef),LL(0x13192c94,0xbc8d4cc9),LL(0x8da37771,0xd555d58a),L_(0xebc86daf), LL(0x42fdc282,0x2e05719e),LL(0x8384340b,0xdc3ed2bf),LL(0x4c1b070d,0x03356492),L_(0x28e4bef9), + LL(0x8da99c00,0xa1e580f6),LL(0xf42f23ce,0xcf6d6c6d),LL(0xfdabb4f2,0x80f7da41),L_(0xf36b6774), LL(0x6a7dfe85,0x36467882),LL(0x8548109a,0x30e07e69),LL(0x943abc5d,0x8ae444d2),L_(0xe5bede0f), + LL(0x2441fb9a,0x0599179e),LL(0x18313f97,0x54669582),LL(0x47767b19,0x6fa66e89),L_(0xd078a973), LL(0x4596bd1c,0x93f0e068),LL(0xb6d46417,0xe4e3af1f),LL(0xff7a84e2,0x951ce962),L_(0xe6d6f09c), + LL(0x466ca296,0x16afa866),LL(0xd1fa4080,0x1f38aad4),LL(0xf4e1677b,0x672e7252),L_(0xf4b620a7), LL(0x3a4e5077,0xfcdff811),LL(0xf5e013a3,0xfe6adcab),LL(0x8a4243ce,0xb04666fc),L_(0xd68cd7b8), + LL(0xc1e32f39,0xd93030cb),LL(0xe0a61e74,0x15f3f603),LL(0x39bbca36,0x90c8c914),L_(0x18b00023), LL(0xa53fc682,0xb0c4475f),LL(0x4cc3825c,0xed39d188),LL(0xa57cf95c,0xd562a81e),L_(0xc8cb3e5f), +}, +/* digit=18 base_pwr=2^126 */ +{ + LL(0x02c6b67a,0xace24453),LL(0xde939bb0,0xa58b929a),LL(0xbe2f8e64,0x9a3a7efb),L_(0xa302408a), LL(0x7fa4b043,0x8ad04303),LL(0x56c2b048,0x426eb7ce),LL(0xa67998c5,0xdb040e40),L_(0x60850b87), + LL(0x3bfd76b3,0x0361658a),LL(0x20f7e490,0xa3b9f1bd),LL(0x66db4cfa,0x4799c86b),L_(0x82aaeafc), LL(0x01c04fa1,0x0689618b),LL(0xd1b3660a,0x5b052123),LL(0x524802bb,0x25748110),L_(0xd8501db2), + LL(0xb542168b,0xf1dd3dc0),LL(0x40fb7327,0x3556cca8),LL(0xf3b21a79,0x0d1838e7),L_(0x0263cade), LL(0xbbfa3610,0x43bd0f7a),LL(0xe6ca4a48,0xfdb15d30),LL(0xa293f5a9,0xf9285692),L_(0xf5e2782f), + LL(0x7da35373,0xefe3b9e7),LL(0x475d95b1,0x08b0fe30),LL(0x9c0da2e3,0xcef9bd5d),L_(0x69f4e019), LL(0x087c3eeb,0x4386ea9f),LL(0x107a9f5d,0x5543dce0),LL(0x057ad0af,0xc5162840),L_(0x036ea919), + LL(0xfeb313d2,0x398fba1b),LL(0x07cbfb75,0x52f53c92),LL(0x98909181,0xfa320278),L_(0x063675b6), LL(0x906d44a1,0x427688fa),LL(0xb499f521,0x1c7282db),LL(0x3901fb30,0xaea2389a),L_(0x14299eff), + LL(0x1424671b,0xd8f3ae0f),LL(0xb631e50c,0x80279f71),LL(0xd5a77238,0x602ce4df),L_(0x988af873), LL(0x12e9402e,0xdd095d1b),LL(0xc30915a3,0x6cb15ad1),LL(0x0927adfc,0xa38c1285),L_(0x3f7c6e76), + LL(0xec392753,0x1ec20f01),LL(0xeb41a6c8,0x5cac318e),LL(0x47520f8c,0x407d9032),L_(0x0390450a), LL(0xe2f3dac2,0x43dd79ec),LL(0xc468403d,0x9236a81c),LL(0x6bccf29e,0x00ac0a42),L_(0x713f0b03), + LL(0x163c66e1,0x849061a0),LL(0xa20a6586,0x70208a9e),LL(0x7bf95257,0x07a10de2),L_(0x3b8aa66f), LL(0x45c2891b,0x15468f60),LL(0xf59044a4,0x73d5ebe8),LL(0x387e234b,0xa32ac9f8),L_(0x4f7ec3db), + LL(0x962ab071,0x570fcd62),LL(0xbcce236d,0xb1757c3e),LL(0x1ad55d1b,0x7fa592e8),L_(0x1700716f), LL(0x76fcda7e,0x73d3b392),LL(0xdd37f1e3,0xd6cf8e98),LL(0xca16fca1,0xac456eec),L_(0x5752c0f7), + LL(0x5f929901,0x240b92b4),LL(0xef15652c,0x0f7d51a0),LL(0x632731fb,0xf12e9902),L_(0x38b796f7), LL(0x47671b3d,0x985803eb),LL(0x5fa89402,0x63e1c219),LL(0x608cf2d5,0x109df03c),L_(0x8ca4e888), + LL(0xb25c71f6,0x0829cedc),LL(0xc7a41eb8,0x483d485c),LL(0x15305f6f,0x60591120),L_(0xf6bc7367), LL(0xbcdea717,0xbeeee884),LL(0xe598a6e7,0x88e6ef42),LL(0xc3d80182,0x4b2dd1d3),L_(0x45cd3855), + LL(0x482c367a,0x6b421466),LL(0x8af36484,0xa58b570e),LL(0x2587649f,0x3e4ee4bd),L_(0xe423c77c), LL(0xf5a1388b,0x98494de5),LL(0x4a294a8e,0x8f25a37c),LL(0x50e9cc72,0x1ce8e0f0),L_(0x10660a4c), + LL(0x119587d4,0x8e668562),LL(0x167d0962,0x0554888c),LL(0xd291f0fd,0xae58bc85),L_(0x8d335bc2), LL(0x48a506c2,0x034f448b),LL(0xd5ffc68b,0x94dd32bb),LL(0x2bd2abc9,0xb9e588a6),L_(0x2eec6265), + LL(0xe1e13902,0x24b16627),LL(0x8bba7a24,0x4f52ca61),LL(0x749a749b,0x8bb11e14),L_(0xb6773c49), LL(0x3dfafe08,0x71bdac04),LL(0x76569dbf,0x40bd5231),LL(0x1587ab8c,0x7d2d4a5e),L_(0xfceafeac), + LL(0xe7ffdae7,0x0f11fde4),LL(0x936bcbdb,0xc78059f3),LL(0xf4713c18,0x2d2f0ff7),L_(0x0dce5266), LL(0x5fe86c6b,0xa381beae),LL(0x9b2c0aaf,0x734b9092),LL(0x77f56796,0x82131b3f),L_(0x02162cc8), + LL(0x612650a2,0xc29b399c),LL(0xad145b7e,0xd673cbc4),LL(0x60425f21,0xece9a8ea),L_(0xc5d38ead), LL(0x394b09de,0x1b69fef5),LL(0x55ee50f6,0x141fc2ff),LL(0xeab0baec,0x85999248),L_(0x02f743df), + LL(0xf4b4d1ac,0xe1f44cb9),LL(0x3931200d,0xd86fbb1f),LL(0x32861f51,0x242811d3),L_(0xa373e731), LL(0x20b39e71,0xc64c1332),LL(0xd9a6709c,0xeb68ae08),LL(0x93c66ba1,0x7aee0eb8),L_(0xfc730fa6), + LL(0xf47a18f8,0x992398ea),LL(0x454ef012,0x7414fdc9),LL(0x325c8a8e,0x42a7e664),L_(0x3b3fca9b), LL(0x9f053cb0,0xc8869d15),LL(0x34539da1,0x1878089e),LL(0x11f347a4,0x19ee0c05),L_(0xf6ff52d9), + LL(0x3e51ac6d,0xb254a9d3),LL(0x5029469e,0xe2b48c1d),LL(0x916d1214,0x3732c0ab),L_(0x07cba5dc), LL(0x0cb5ec91,0x010093ba),LL(0x6f2fe681,0x4a4cfff5),LL(0x4aaf2a44,0x7feda10c),L_(0xafba52c9), + LL(0x58625a1b,0xea895fc8),LL(0x19dbf9ed,0xcac0e4d3),LL(0x53bc48b9,0x1d43df08),L_(0xc8f9dd1d), LL(0xee75a211,0xe1a8bb95),LL(0x718f5878,0x7e7b6ce4),LL(0x4a384a6d,0x26d0db83),L_(0x97ecfe38), + LL(0x2bb95cae,0x9e42faba),LL(0x9254494c,0x0f33c611),LL(0xf67c4703,0x6ef93df3),L_(0xc1445815), LL(0x8ad685b3,0x8655685c),LL(0x6cd1cca8,0xdd2eb2bd),LL(0x5e194627,0x523e0fd5),L_(0x44f05a1f), + LL(0x301fcb43,0x80fb78c3),LL(0xa1be1446,0xfaa1d373),LL(0x3d0a850d,0x051bb6db),L_(0xc2bd0c81), LL(0xc7fc5cae,0x38f0078b),LL(0x6d01ae21,0x91a544af),LL(0x0c9540c5,0x6cae5443),L_(0x41626d37), + LL(0x93ebe56f,0x71946cb7),LL(0x3335ca8b,0xc82366c4),LL(0xbfe6dc77,0x27a97fdc),L_(0xcc4d8fd2), LL(0x80d9e528,0x16d42ed2),LL(0x4d8537e9,0x18abf493),LL(0x0398f8d3,0xa190c5d3),L_(0xd448e52b), + LL(0x495ac576,0x6bf10350),LL(0x3cbf1e78,0x2674f39c),LL(0x90ac41f9,0xaedc843c),L_(0x784b629d), LL(0x60ca4b9d,0x2b7ba708),LL(0x88cff37a,0xc070ae0f),LL(0x2e4b0764,0x0c3aa1f7),L_(0xdf186109), + LL(0x555cdffc,0xd2310fa6),LL(0xac832df3,0x42f99111),LL(0x9d84f404,0x8d7bdc74),L_(0x64936918), LL(0x43e3cff3,0x1c149edf),LL(0x3b328f21,0x442dde2f),LL(0x1288dcc9,0xb3089de8),L_(0xbad0531f), + LL(0x3fe61e60,0x20fa93a3),LL(0x494f3a66,0xb50f92b6),LL(0xbfce0907,0x632ab7a5),L_(0xe52a0324), LL(0xc89531e3,0x6f57401d),LL(0xca680133,0xf7bd6eaf),LL(0x5942987b,0xceffd87f),L_(0x75f1a1f6), + LL(0x74161b3e,0x647fc617),LL(0xe81422f8,0xac7f6cc7),LL(0xc485b2c8,0x0414a8d3),L_(0x5303bc61), LL(0xd7de72d1,0x1d6064d4),LL(0x88c0864e,0x9fd6a734),LL(0x8ee9cb9d,0xf104d7a9),L_(0x963ee732), + LL(0x776f7b1b,0x2b058af6),LL(0xdc25f3b6,0x0d06abe1),LL(0xb0461b36,0x90f6c358),L_(0xdad04c23), LL(0x9a72e439,0x24e0b184),LL(0x2af6be09,0x6facf219),LL(0x5f6753e5,0x5f23a218),L_(0xa362a760), + LL(0x4fd2cc26,0xadb7e3c5),LL(0xdb9150c6,0x4cc67b4d),LL(0x4c80d589,0x6a578011),L_(0x78347a1f), LL(0xc04163a4,0x41978a17),LL(0xa1df6b38,0x4701d625),LL(0x7acb9d4e,0x7040eb22),L_(0xb0f7aae6), + LL(0xb117faf4,0x734cd26d),LL(0xd884a071,0x071d299d),LL(0x1ad0de2a,0x826417df),L_(0xda3b0c06), LL(0x487c15f0,0x5432a8df),LL(0x85244fbd,0xa5c2986f),LL(0xe2f76737,0x89d1f699),L_(0xefb644c7), + LL(0xe366cc7a,0xcd96f1e7),LL(0x2f09e23c,0x19aa24f5),LL(0xbe89a16c,0xea6d5b99),L_(0x1a7565fa), LL(0x1afa0bd5,0x8da4ca09),LL(0x8baaef4d,0xb278c555),LL(0x07697581,0xea0b2435),L_(0xbefa5c32), + LL(0x233ddda5,0xbce451f2),LL(0x6e777818,0xe21ca9dc),LL(0x33fc9573,0x608477ee),L_(0x96d9fe99), LL(0x37f4a8b7,0x2f253ba7),LL(0x11d98950,0xec1f4a44),LL(0x3ae7c4bb,0x1c649260),L_(0x4eeee3f8), + LL(0xf186ffa8,0xca88dd8a),LL(0x25be4bd7,0x2e8c5c07),LL(0xd65638d7,0x8d28689a),L_(0xbe778846), LL(0xa2ef4b72,0xfa5e89e0),LL(0x0b27fb66,0xea4b66ad),LL(0x2a17ea7b,0x5744fef5),L_(0xaf89c334), + LL(0x1c88c916,0xd377e6af),LL(0xa6b3f831,0xbd38c04e),LL(0x43c62134,0x7e11eacb),L_(0xaee51855), LL(0x3aa19a13,0xe65b9643),LL(0x3179a57d,0x0069d240),LL(0x7d7a8265,0xc6fc4f7d),L_(0x8ea00bca), + LL(0xb94a17c9,0x95308d83),LL(0xb3928b84,0x88fbad83),LL(0xd14a8ca8,0xcec36252),L_(0xff246228), LL(0xf71bccbb,0xd90035ec),LL(0x499776eb,0x55a73d3d),LL(0x07f0cdbc,0x6c21797b),L_(0x87db5d7d), + LL(0x5162797f,0xa87e9702),LL(0xaaf9d8c4,0x2ab93ff2),LL(0xe2a31c19,0x4288abf4),L_(0xc4cc32b4), LL(0x80be51bc,0x388680ed),LL(0x2f0c118b,0x8dedbe91),LL(0x7da1a829,0xbffcb08c),L_(0xd681d331), + LL(0xac1e2c01,0x1d6fb3ed),LL(0x470f2923,0x9f1545b9),LL(0xfb03795c,0xbfecfd6e),L_(0x8ff73fcd), LL(0xac0e74d1,0xcbb46331),LL(0xcbbfedab,0x01849564),LL(0x79c317d8,0x9186b0db),L_(0x7c549c1e), + LL(0xe3b9e5c2,0xa44cb510),LL(0x670d9ca9,0xc72bcde9),LL(0xd47f22e3,0x23ac79ad),L_(0xe4bd107b), LL(0x1062a84a,0xd5193e66),LL(0xfb47ce43,0xbb25e4cf),LL(0x600c0353,0x5ab3c0ce),L_(0x005311ba), + LL(0x1f36e1c7,0x2a414d7c),LL(0x9bec3869,0x23202a91),LL(0xbdd27859,0xd77095b4),L_(0x270698b1), LL(0xe5a99ae2,0xd0fffc9e),LL(0x3c7db5f1,0x490dac48),LL(0xacfdbe9c,0x9079d090),L_(0x1bb8021a), + LL(0x550c3e83,0x448361bb),LL(0xa680b478,0xfeab6ae3),LL(0x41969a52,0x74461138),L_(0x9a38f5c6), LL(0x47381f19,0x2be030b8),LL(0x0e86ce09,0xb091abda),LL(0x4da4cd53,0x7df8f1e3),L_(0xc85acbda), + LL(0x9fea92c4,0xab2fcd01),LL(0x85b0423d,0xd804cba2),LL(0xed8709e8,0x19141717),L_(0x49d8b7d7), LL(0x88fb9ada,0xe105506b),LL(0xb90d9a8b,0x8cb2c13d),LL(0x4e6bda23,0xcaba970f),L_(0x7dff6f41), + LL(0x9fcd4872,0x160191eb),LL(0xff541bf6,0x826242d0),LL(0x99634c20,0xdfe7289d),L_(0xa5294071), LL(0x4e07eba9,0xc0910d55),LL(0xd5b6e07a,0x7e042c86),LL(0x6d7f5229,0xd74d6e82),L_(0x42f50e09), + LL(0x6efbc0e3,0xcc3c4e8e),LL(0xd7d09e5f,0xf21ea1ea),LL(0x05c108d8,0x37aae682),L_(0xb8b85f83), LL(0xf2c37fd3,0x9a51bef8),LL(0x5a44835e,0x5ac834a6),LL(0x2a412b12,0xac985dae),L_(0xf2f75363), + LL(0x39bd009a,0xb0ef3648),LL(0x7df070de,0xc1936e74),LL(0x97226670,0x3eb64bfc),L_(0x0a7cc2d5), LL(0xfa065546,0x6cb29cd8),LL(0xd6b2e07d,0x010fbc35),LL(0x6b24b9f4,0x72e08b5c),L_(0xbf7187b5), + LL(0xe0daf351,0x2fb0ee94),LL(0x31222305,0xac57f680),LL(0xb753971e,0x6b0ccf83),L_(0x55a3abe2), LL(0xc3b1be68,0x48b857e0),LL(0xfc1add13,0x81e2b0c5),LL(0x595ebecb,0x7151293e),L_(0x43489ffc), + LL(0xb788bb44,0x65e9c6ef),LL(0x071c9990,0x10062256),LL(0x891a7719,0xe6f377fd),L_(0x65d3a9e3), LL(0x7355204b,0xe23556ab),LL(0xa6502b28,0x188872cd),LL(0x84eba15d,0xea03bca4),L_(0x62a2b9d4), + LL(0x159bb9df,0x08807416),LL(0x78e83862,0x496eba6b),LL(0x5b5b2f5c,0xff4f34bf),L_(0xc8432a05), LL(0x376ec0fd,0xe48904ea),LL(0x386ae415,0x96bf9fdc),LL(0x9b04b325,0x003a468c),L_(0x2a854bd5), + LL(0x3d1be5ac,0x62509881),LL(0x76fd690b,0x65d5f607),LL(0x244caa05,0xc38d7540),L_(0x7a21901b), LL(0x0b239ba7,0x19b8e994),LL(0x14c3955b,0x1f25f647),LL(0xd2cd0a34,0x7f481820),L_(0x3e5eb658), + LL(0xdceb71b6,0xf395c0f2),LL(0xcc104e0d,0x6febd95a),LL(0x01d8efcf,0x0b358ed0),L_(0xcfc537fe), LL(0xdadfd46d,0xdc5d961e),LL(0x8b4f6c1d,0x221b24a2),LL(0x6d21a125,0xc0f16b10),L_(0x36a0bac0), + LL(0x3ece8319,0x54252e96),LL(0x46f2cfb1,0x97edd630),LL(0x020e1e99,0x90685aae),L_(0xfc1bcb8e), LL(0xb7771435,0x6df64310),LL(0x43c4fd8d,0xa647e2b0),LL(0xd6ddd8f3,0x52ff5927),L_(0x5282fbcf), + LL(0x3fd7f727,0xbb02013a),LL(0xb1fc86fe,0x6e17def8),LL(0x5ef8f2c6,0x1b970bb2),L_(0x1b714b57), LL(0x1236fa50,0xf7a7e274),LL(0xcc10de34,0xffa4c977),LL(0x5a8179b1,0x99219388),L_(0x798129b2), + LL(0x4b407e5a,0x844408fa),LL(0x6be5d183,0x742669b3),LL(0x0751f86d,0xb00b365a),L_(0x34786bf6), LL(0x3a8360fc,0x4147cefc),LL(0x88816150,0x0393026d),LL(0x7a7f6231,0x2e39fa34),L_(0x879f391b), + LL(0x149f6c78,0xbbcd3afa),LL(0x8292ce76,0x742b5b3a),LL(0x899f0118,0xb8dc2766),L_(0x18090cc3), LL(0x14c00e4d,0x6924c12d),LL(0x7049ac09,0x4e4111e8),LL(0xdf09100c,0x2987ca68),L_(0xa8c45230), + LL(0x65fad089,0x01cff054),LL(0x821650cf,0x3002769e),LL(0xdb9e3912,0xe9ad46db),L_(0x1a05deca), LL(0x6e7044a0,0x34ab7ab5),LL(0xc61e42fb,0xfda4dfcf),LL(0x91982d5a,0x89e4ea03),L_(0x58b6c30e), + LL(0x132822ea,0x1ad76044),LL(0x50f3dcec,0x3e8a1d95),LL(0xb981b100,0x37f04df1),L_(0x4ca707b5), LL(0x0b17bd0a,0x0b34cd00),LL(0x93aa35e9,0x447278ac),LL(0x07bde57a,0x6e16122f),L_(0xc9b96d1e), + LL(0x3221832d,0x8fc6ce6c),LL(0xe4935439,0x65828539),LL(0x9cdf65d9,0x708e9258),L_(0x5929b880), LL(0x273611ed,0xef43a507),LL(0x9e4d7f82,0x86406043),LL(0x88f84624,0x4396769b),L_(0x09401931), + LL(0x25903256,0x6b8a2c7e),LL(0xe200a555,0x567e51fb),LL(0x06f1e0ff,0xdbcad515),L_(0x435d74d4), LL(0xe7fa9d16,0x627c717b),LL(0xd7c74d13,0x3efff1d7),LL(0xa592bf53,0xe58ce7d7),L_(0x0a6f5daa), + LL(0x6bc49db7,0x2993ad98),LL(0x11f1de05,0xcd8ed14b),LL(0x104437d1,0x419b6d76),L_(0xb80b6ad9), LL(0x5ceae532,0x2692fc9f),LL(0xfc4d4052,0x96208c11),LL(0x5f17f19b,0x34a83cc6),L_(0x7f3e627c), + LL(0x3d238cb2,0x6bb879b5),LL(0xb752157e,0xeaa5d8ca),LL(0x137d82f5,0x769e2a68),L_(0xca3db7bd), LL(0x0ddf279e,0x2ae26372),LL(0xf5d74ea6,0x79e90c0b),LL(0x27e773c7,0x3451edcf),L_(0xe4341440), + LL(0x65ddd79b,0x34988e35),LL(0x25d7df53,0xd93aac10),LL(0x814a0e96,0x76ec0b96),L_(0x74d8980e), LL(0xe6639b9b,0x9143cd9d),LL(0xa3c743dd,0xfb9b096b),LL(0x77b915d6,0x4353464a),L_(0x7fdf9660), + LL(0x103b0149,0x52d3720b),LL(0x668172a6,0x3c3a2d72),LL(0x0ddae18b,0x3543af35),L_(0x36c45c71), LL(0x90846158,0x51cb6d6c),LL(0xb970c6e8,0x5541df27),LL(0x9f0df2e6,0xa96cf0e6),L_(0xef118589), + LL(0x51a147b4,0xbd4c751a),LL(0x9547874d,0x5b132575),LL(0x81839452,0x9b0ddfdb),L_(0x24fa7687), LL(0x2e14f24d,0x54dad63a),LL(0x7d8859c9,0xd7c2228f),LL(0xdcbca7aa,0x77c13acc),L_(0x87a21fd3), + LL(0x4c326ed3,0xe3bb354a),LL(0x3fb8d397,0xa148004d),LL(0xb7008ce3,0x85367d7f),L_(0x177a646b), LL(0xe73d1a40,0x93d871ad),LL(0x4c9f1031,0x7768c968),LL(0xd9c87876,0xb38a617a),L_(0xd2b0142c), + LL(0xaf8f400e,0x2a94dc1a),LL(0x9b975861,0xf8d2e935),LL(0x370e4c06,0xca35bd61),L_(0xf7a243e9), LL(0x2c1682bd,0x00b6e1a8),LL(0x56f9e8d0,0x6d92e1f3),LL(0x9bb1736d,0x3e9b6293),L_(0xf048cf7d), +}, +/* digit=19 base_pwr=2^133 */ +{ + LL(0x6c35afbd,0xf6f30e96),LL(0xdab13683,0x669a8251),LL(0x4dd8bbbe,0xb9b1b311),L_(0xd57a4a34), LL(0xbbcbf46c,0xe4d59c99),LL(0x4923f91d,0x63242254),LL(0x877172dc,0x853f9c6a),L_(0xd7aca10a), + LL(0xd5de71ea,0xe7f42edd),LL(0xf74adcc0,0x0b9c53be),LL(0xc8c4ee60,0x82b1e37e),L_(0xbcd67b5f), LL(0x4a10fc2a,0x7502a8c1),LL(0xba4a9d44,0x2dc30076),LL(0xcd3e0527,0x2e0b7f76),L_(0xaeb6d158), + LL(0xc21b4aac,0x95f715ce),LL(0x5afa8860,0xff0073cc),LL(0xdb4528e5,0xdbc69fc1),L_(0xe9e0b780), LL(0x8bfc4102,0xe2c44c67),LL(0x74449572,0xa7624b30),LL(0x1b45072c,0xebf2704a),L_(0xae9e87a4), + LL(0x540d3efa,0xe3c8a7e4),LL(0xd1ad9579,0x39e285d6),LL(0xccac1ee5,0x8d098605),L_(0x02e00e9d), LL(0xaae2485d,0x424cb101),LL(0x57781fcb,0xd81ebf02),LL(0xe045acd6,0xec4b922d),L_(0xf679db8b), + LL(0xe3ace3b4,0xfb5f0701),LL(0x7920ba12,0x1534cde4),LL(0x25904a79,0xf9421b0d),L_(0xc0438d82), LL(0x0528f7cb,0x8a9c39d8),LL(0xb1c7fc33,0xdd383932),LL(0x458a7c5f,0xbaf06aaf),L_(0x2cd8a058), + LL(0x193b780c,0x5abd6eef),LL(0x6b220286,0xd76b78fc),LL(0x06442ef6,0x0cdf9e58),L_(0xe520f054), LL(0x8a5c2658,0xfae0a442),LL(0x0ae1c405,0x6c2b778b),LL(0xb5adbc98,0xf374d05a),L_(0x010faa2e), + LL(0x0c6f4ae3,0xb657d5f6),LL(0x56b561b2,0xabf1920f),LL(0x70a6775e,0x15909e3c),L_(0x7b91068f), LL(0xe0c73f44,0x563843f3),LL(0xe4066970,0xe15912cf),LL(0x2e80308d,0xd16c8835),L_(0x3121c5b3), + LL(0xb00d284a,0x96ae8e24),LL(0x8746c0ee,0x118cc562),LL(0x4ed443bf,0x9157acc3),L_(0x898cd623), LL(0x14b54c13,0x07d6ccc1),LL(0xc5299940,0x05ec4684),LL(0xf50f2de3,0x1a923061),L_(0x8aaedd52), + LL(0xc692cc03,0xbe07dcf7),LL(0xa61a9062,0x5f04bf17),LL(0x0d99300c,0xa062deba),L_(0xcb7f082f), LL(0xa3451ea6,0x02666d4c),LL(0xd4b6a94d,0x2fc9077f),LL(0x564f33fe,0xa2bd47b9),L_(0x4614aa04), + LL(0x6da6ee28,0xdab5f17d),LL(0x2dfb0cbf,0x36f25faf),LL(0x16a32d1e,0xbe5fdc6d),L_(0x48f97f60), LL(0xd0d79fc9,0x0ee979a6),LL(0xfb77bc6d,0xc670e326),LL(0x6435ef83,0x55425ae2),L_(0x32e4cd8a), + LL(0xcf395e17,0xd8954092),LL(0x1415743a,0x516938e6),LL(0xc57f3db0,0xe85d4e50),L_(0x71f22b3c), LL(0x611ea790,0xfafbe19a),LL(0xdbd2d4ed,0xe5ff8f06),LL(0xe41d9e6e,0x9e9c0da2),L_(0xb15426d4), + LL(0x86e3cdb6,0x8cb41178),LL(0x0f8b5836,0x5615e2b5),LL(0x74d58d7a,0x4e6b82ce),L_(0x3030ebba), LL(0xd4c6f918,0x374bbfd9),LL(0xcfea53e3,0x15aadf45),LL(0x363a6cec,0x30dd6649),L_(0xf3c95a58), + LL(0xe43c3adf,0x120bb9ae),LL(0x98ad19ec,0x73ef55fc),LL(0xbe8a8508,0xbb18ab2b),L_(0x1cda9cb5), LL(0x84facee2,0xb277aa2c),LL(0x29318829,0x742a25ca),LL(0x1cc06cae,0xd0d24d20),L_(0x3eca1b2b), + LL(0x0714ac72,0x2ffe0519),LL(0x522d36e5,0x843d58c8),LL(0x7eddcb6d,0x1e60abe4),L_(0xc55d6e85), LL(0xb10fd185,0xccf9c609),LL(0x5c6153bd,0xa0d4b626),LL(0xe398ed34,0x7b6aa811),L_(0xb4dde424), + LL(0xa960c0c3,0x735c5d62),LL(0x8c6a5476,0x0f8b2a35),LL(0x54dfa089,0x0b186f7a),L_(0x6ab8d48a), LL(0x3e7eb8a2,0xc1614c55),LL(0x7aebdcff,0x8c7e1e1c),LL(0x390e7c1c,0xf9b0b2f9),L_(0x869d2266), + LL(0x11277d6a,0xd9cc122b),LL(0xb86417ff,0x3f2ab21c),LL(0x2cbd87e4,0x494cfb1e),L_(0x991ddd86), LL(0xae7bbb90,0x9977c3ac),LL(0xc3e66760,0x397ea438),LL(0xb224446c,0x7ed9dec7),L_(0x2a81eaf1), + LL(0xc59accd2,0xb5432f0f),LL(0xf2593b02,0x8b88a936),LL(0xc5589b93,0x02d9f9ac),L_(0xc3eb3094), LL(0x8302d1bc,0x43908c95),LL(0x08ef4088,0xb05f1091),LL(0x83349c39,0x5061c674),L_(0xff815654), + LL(0xf0350dc9,0x9371eb01),LL(0x45527229,0xce86a9ba),LL(0x47861a0c,0x9aad7247),L_(0x098cb788), LL(0xa559d5e9,0x979093ec),LL(0xbbd1def2,0x0fe17efb),LL(0xb512322d,0xae7b8c8e),L_(0xe9bbc66c), + LL(0x3ad82961,0x9f1ec261),LL(0xfe0fcc30,0x77a36e95),LL(0x3914c9d2,0x9b1a4daf),L_(0x09933bfc), LL(0xec701059,0xcfa77625),LL(0xea8985c9,0xe60b3f29),LL(0x0c5b4abf,0x138b4b1c),L_(0xdc77bb16), + LL(0x174442e6,0x1802aa28),LL(0xd075865e,0x26f71e88),LL(0x4a4c5681,0x7ae33021),L_(0x5a2cabc9), LL(0x5d0cad44,0x2893d185),LL(0x55811da2,0x7e9947d1),LL(0xc9f7bf57,0xf2c79dea),L_(0x8ef92a2a), + LL(0x3a838f3b,0xfbe1be02),LL(0x57b6d887,0x229d491d),LL(0x207a3044,0x9f62e957),L_(0x9f828177), LL(0x2e1d3c54,0x86b7e5aa),LL(0xf3280135,0x3fbda02e),LL(0x7c96f0d5,0xbda44f9b),L_(0x2f723070), + LL(0xf1aeae6a,0xae77f574),LL(0x7664fba7,0x0423c396),LL(0xf1f4d153,0x47451433),L_(0x91ff938d), LL(0x3a807b63,0xe8e961f8),LL(0x748646da,0xd89c3d2a),LL(0x467e86a7,0x6ac80359),L_(0x32bf2f50), + LL(0xb36ecce7,0x3b7324a4),LL(0x156202b0,0xbb9babf8),LL(0x98c1904a,0xf1e380ce),L_(0x46867bcd), LL(0x01b08225,0x2eeb6052),LL(0x1eab01ca,0xd0d4fef8),LL(0x19322045,0x256a539e),L_(0xfc3623ca), + LL(0xc94659b1,0x2f0568f5),LL(0x16a9b3fa,0xed8a79a8),LL(0x50d8c266,0x757c7d99),L_(0x2300fd6a), LL(0x66c509e5,0xb792533a),LL(0xb5184b40,0x9e0c5aac),LL(0x34caeea9,0xe5b193ca),L_(0xbbba3e14), + LL(0x195602fc,0x701a9997),LL(0xf834de05,0x3992cbc9),LL(0xe1e8b8e7,0x8ec536e5),L_(0x7e773653), LL(0x29c79b3a,0x29bff6f9),LL(0x17984cef,0x596ff95f),LL(0x0a0ae347,0x661b4a6c),L_(0xb2e9719f), + LL(0x8e767a04,0x473ec4b4),LL(0x4c2d676e,0xeb4d7d16),LL(0x98a8ebb4,0xc4e28600),L_(0x2f68f9cd), LL(0x6beb5ab8,0x1ef6cbd4),LL(0x85cd9d62,0x83dde9de),LL(0x1762ff65,0x9ddef882),L_(0xeb7899f5), + LL(0xe6f97e53,0x2cfac1c4),LL(0xf67b6c86,0x94800529),LL(0x61546993,0xcee96715),L_(0xf2a9560b), LL(0xdc612b8b,0x01036872),LL(0x88524fe9,0x9e6d56f4),LL(0x0543bf02,0x40b8eb7d),L_(0xb87c4dba), + LL(0xbb67b974,0xd7ceddb4),LL(0x1d6817da,0x7bd3859f),LL(0xe95a7ea2,0xc85424d7),L_(0x55d605cd), LL(0x5d21362b,0x2591a7e7),LL(0x4aa1f58c,0x52817220),LL(0xc9d8453d,0xa286acd4),L_(0x3bd2f891), + LL(0xaf830116,0x6e587151),LL(0x8a5ecfca,0x3d8da1ef),LL(0x7afbb075,0xf8e3bab4),L_(0x80131b4d), LL(0x3ab8344d,0x6bb840b0),LL(0x9e591ccd,0xae7bd8be),LL(0x73177038,0xed8b2ca2),L_(0x15e01308), + LL(0xadd91144,0x680d82d3),LL(0xd982abff,0x88f503dd),LL(0x37393204,0x746b676f),L_(0xaf201907), LL(0xaf979504,0x5a9be716),LL(0x4001d634,0x0e682183),LL(0x609ab748,0xfe8299c8),L_(0x39a6e2fd), + LL(0x193fd321,0x8682c4c0),LL(0xc2a26123,0xd566872d),LL(0x1407f3c3,0x16439d5d),L_(0x3caca395), LL(0xd6726482,0xb7bc2fb3),LL(0x5cdf7fec,0xb4c2b53d),LL(0xfeaaece6,0x4349edc0),L_(0x53d16a46), + LL(0xae9bd278,0x6c678048),LL(0xa706ff5d,0x52da3781),LL(0xae4a71b1,0x1e1cd89e),L_(0x9b61b4af), LL(0x2f691fc7,0xf69884c3),LL(0x4d64cf90,0x19020a41),LL(0xdda1c483,0x77d02be4),L_(0xb0f86443), + LL(0x8529164d,0x5d80aafd),LL(0x4f432d73,0x1e830c7c),LL(0xa9f0f09e,0xfc3140e2),L_(0x815acd77), LL(0xdc2ab04b,0x59befe02),LL(0xf1e93bd2,0xa44595d5),LL(0xc1e15529,0xf19abe7c),L_(0xaeca237e), + LL(0xa12bccee,0xb9b8ec3a),LL(0xf2dadd08,0xad1e4dce),LL(0xb63e0921,0xfcf65288),L_(0xc5a2a0be), LL(0x863fe95b,0x5cd2ee3e),LL(0x4eb4db06,0x60da7b42),LL(0xb8a5bd09,0xc426f7df),L_(0xf3f19cce), + LL(0x6e5213a2,0xfd69d7c4),LL(0x31496bf2,0xd30cf23b),LL(0x37d44e1e,0x7097147f),L_(0xae15b228), LL(0x12d98f15,0x32dad5dc),LL(0xa8f63aff,0xdfe1a802),LL(0xc8d86798,0xeccd5411),L_(0xcde1acb9), + LL(0x74006fc7,0xd7d803d8),LL(0x4af70159,0xec84dc01),LL(0xae309a70,0xa34e0e32),L_(0x585516f0), LL(0x235ed632,0xcfee558c),LL(0xcab23f91,0xcd97224e),LL(0x1640e7f8,0x92280213),L_(0xbd508662), + LL(0xc7ccf41a,0xd687e53b),LL(0x854bd98e,0x9a24176d),LL(0x01470242,0x01aae44b),L_(0xaca3a958), LL(0x9fcc8bad,0xc772707a),LL(0x1ce44586,0xeeb32998),LL(0x1fd556e7,0x6b1da8b4),L_(0x0ed6e63a), + LL(0x3fe0c228,0x929fe46b),LL(0x01aa7a0a,0x55829b86),LL(0xb0593728,0x46968b3a),L_(0xef6bc08e), LL(0x861c28fb,0x49238b1c),LL(0xbb911c6f,0xe2c2f08e),LL(0xc3669826,0xd635b05a),L_(0x67f9c7c0), + LL(0x1cbd7072,0xac172491),LL(0xa75f68ed,0x70337bd5),LL(0x5806f542,0xba62de08),L_(0xf48e9477), LL(0xc789f89a,0x778e6f6e),LL(0xca466063,0x7cb61f89),LL(0x9e11ca0e,0x54802afa),L_(0x00753b33), + LL(0xa293c1d0,0x98d81eae),LL(0xf1d86049,0x4a05fd64),LL(0xf7776c88,0x31edd830),L_(0x4b09f540), LL(0x6b003742,0x530442c5),LL(0xd29f0459,0x2717506e),LL(0x993316f5,0x977de534),L_(0x8efd4242), + LL(0x1f4b647c,0x63a5f62f),LL(0x1b839fad,0x184bd1bf),LL(0x9eb8bb02,0xd878238c),L_(0x8ce0fbd0), LL(0xee715bb5,0x0c09795f),LL(0x7e0f0890,0x4a0ef110),LL(0x5e80a1d2,0xa6ed70be),L_(0xdd973aaa), + LL(0x02e27464,0x66b5fa13),LL(0x8d608579,0xf1afa0fe),LL(0x262f06e4,0x55328bec),L_(0xe5f137a6), LL(0x359db889,0x56654a88),LL(0xd39b145c,0x31866e5f),LL(0xe08705c4,0x615a5b05),L_(0xe8573a34), + LL(0xd9bae78a,0xa18e5f26),LL(0xbcdd1733,0xfb66461e),LL(0x52d89638,0xf79de1ee),L_(0xd8be4f6d), LL(0x63f080c5,0xf0c1209c),LL(0x4e984349,0x8927edaa),LL(0x1cca87fa,0x0d7779de),L_(0xc4be69f3), + LL(0x4ffe196d,0x591b255f),LL(0xf9220e24,0xf529da70),LL(0xa919472f,0xc172114d),L_(0x12b84dab), LL(0x727df75e,0x0b0bba01),LL(0xc90f5813,0x18ae3fac),LL(0x7de531b5,0x60f6010b),L_(0xb124c090), + LL(0xc8ab7f3a,0x4d9c100a),LL(0x3147c457,0xb3ed07de),LL(0x2ce9d1a7,0xf4f877cc),L_(0x11395ce0), LL(0xe5d2ab31,0x7ebabf38),LL(0x7ffb38b5,0xce3cfa6e),LL(0x85ffa6d1,0xfa3306d0),L_(0x40ce1960), + LL(0x014e69fb,0xe40ec6e7),LL(0x92b1fc6d,0x8f04f43e),LL(0xf3db5670,0xb9883ee7),L_(0x01e865eb), LL(0xeab3fc5e,0xedf8720a),LL(0x639d496f,0xf1d8e66c),LL(0x32cbb568,0xc1af6691),L_(0x0ce5c8b4), + LL(0xb78b642b,0x65a42ec3),LL(0xade40c55,0xdde23958),LL(0x216642c3,0xcdc7c4de),L_(0x6aa44ccd), LL(0x82ee3789,0xec771036),LL(0x1fafeef8,0xefdcbefc),LL(0xe82b1033,0x5b9fd0f1),L_(0xb5931c71), + LL(0xd7c8b169,0x94661f99),LL(0x88be16da,0x968a0513),LL(0x5e1f223f,0xf2936613),L_(0x7a916253), LL(0xf109d748,0x8c1958b8),LL(0xca3eb1cf,0xd1baaa06),LL(0x58b0e5bd,0x04265560),L_(0x6b971198), + LL(0x3c1c78f3,0x73aa994d),LL(0x7b9ba5eb,0x9d13c878),LL(0x5ffbf962,0x329365bf),L_(0xfc14c225), LL(0x151d1b5c,0x9b162681),LL(0x8b322eba,0x67d4adbd),LL(0x2d7119cb,0x112111da),L_(0x14cee07e), + LL(0x8de63a53,0x0bc054e9),LL(0x090ebf32,0xac3474f8),LL(0xd39c2e22,0x8a24d244),L_(0xc5c07687), LL(0x72de574a,0xf7cd28ca),LL(0x00f6286c,0xaba378ca),LL(0xacf3d959,0xc4c178a4),L_(0x1e3ce962), + LL(0x4c196a72,0xeddb3096),LL(0x4807ba1c,0x78d05007),LL(0x4a5cea44,0x4e82cf55),L_(0xbefd7586), LL(0xbc157856,0x42628bb0),LL(0x4d8a1ece,0x3bec9a03),LL(0x414298ee,0x71c76fb4),L_(0x1b7c9c7e), + LL(0x451c89a9,0x0eb5ca81),LL(0xdfcc6c7e,0x85231811),LL(0xdd102f79,0xcfe70175),L_(0xd23927f1), LL(0x74f56210,0xa68f72ba),LL(0x0c268cfa,0x107305c7),LL(0xa0b90dac,0x71b34217),L_(0x86344588), + LL(0xdf55e61f,0x74013fe7),LL(0x0ad28f61,0x384b1c58),LL(0x117f4d5d,0xb417f0cc),L_(0x2ee194ab), LL(0xa5e101d2,0x6a59354e),LL(0xe4650ef7,0xdd613a28),LL(0x3d053f50,0x49698601),L_(0x211980e7), + LL(0xbc28da29,0x350510df),LL(0x729451ca,0xa5492aa2),LL(0x488b3ebb,0x7335580b),L_(0xf1e1f254), LL(0x150fa7dc,0x5080e530),LL(0x021a9cf2,0x41fe0adc),LL(0x151c555b,0xefba1701),L_(0x1be676fd), + LL(0xda6ab8ee,0x01c286ca),LL(0xd11e769f,0x8f870f9f),LL(0x67983e93,0x011517ba),L_(0xb19fd8df), LL(0x2ffdf94a,0xb8ff2b68),LL(0x1becdb97,0x57a7f08b),LL(0x2df51505,0x7f4a552d),L_(0x2e44b40c), + LL(0x8a38d901,0x15f78485),LL(0x94822c36,0x40936fbc),LL(0xdc403083,0x26d9bf80),L_(0x3f811b6c), LL(0x6682494b,0x658eecc3),LL(0x1088923f,0xe2c9cc47),LL(0xf4a7dc3b,0x6742c074),L_(0x7820af17), + LL(0xaf6f6f62,0x1be73cf3),LL(0x0c32e84f,0x74ffb428),LL(0xb29ede9a,0x92e686e4),L_(0xa74c4c0a), LL(0xdfa5e890,0xe1001a22),LL(0xa64183c0,0xf029cdcb),LL(0x55c88ddd,0xd03747ad),L_(0x5bbce6dc), + LL(0x69bc7a5c,0x0a7f469b),LL(0x3d28b7fa,0x8cb61ff4),LL(0x860090cf,0x25e6acf5),L_(0x3ca61e58), LL(0x7c9a5e59,0xd04ea633),LL(0xbdcdff22,0x3dccdf34),LL(0x679b9a9c,0xe0d5601a),L_(0xa518db92), + LL(0x75393ffb,0x503ff7fc),LL(0x29c7bd8b,0xad84a980),LL(0x6a8d3ebd,0xb711116c),L_(0x6093e9c1), LL(0x508cd2db,0x298e39d1),LL(0x88ffc5c3,0xd182ffce),LL(0xf35bcd9e,0x56f60d5a),L_(0x24c2d62a), + LL(0xbb37476d,0x126c6b62),LL(0x1974758e,0x12e961ad),LL(0xc23fa1b7,0x620a85d2),L_(0xe713a9df), LL(0x18d50f3d,0x90b6bf4d),LL(0xd31ffadf,0xcce6cb43),LL(0xb9db57be,0x43232f2b),L_(0xee956b0f), + LL(0x33f18557,0x34242913),LL(0xae8e0c9c,0xecfa2ca9),LL(0xe5298223,0x54c9b89f),L_(0x81ae98bb), LL(0x2bb85e08,0x3640c336),LL(0x187eb8dd,0x23f72dcc),LL(0xe33bfd7f,0x1138d09f),L_(0xa5c71157), + LL(0x9635cec5,0x99decb38),LL(0x120fcaaa,0xb6e94853),LL(0xc90493fd,0xe03d588e),L_(0xdacd4c22), LL(0xbbcd5ead,0x1a5efdc4),LL(0xa034c92d,0xbd3e5f34),LL(0xc0bbee30,0x91354a2e),L_(0x83ce5653), + LL(0xe4fe7dd6,0x40ccc046),LL(0x12391a03,0xef734198),LL(0xe37fbe0f,0xd7d730ce),L_(0xb901d8d1), LL(0xe81b74b5,0xccbbf03c),LL(0xbd70b08b,0xaf1eca00),LL(0xb202f7d1,0x6c3a5371),L_(0x3e4aeff1), + LL(0x3c293b50,0x50ebe82c),LL(0x841f67d5,0xe5c199da),LL(0x9c0164e0,0x09ae68d1),L_(0x48a6a776), LL(0xe57a6b35,0x764aa682),LL(0x4cc646a6,0xd2b124d2),LL(0xc37e19f6,0x0684de69),L_(0x244cccbe), +}, +/* digit=20 base_pwr=2^140 */ +{ + LL(0x3a2fc0af,0x3a0ae219),LL(0xaf66dcd1,0x71d39324),LL(0xeb53d991,0x1b364d9f),L_(0xd1a4ab2f), LL(0xe634fa4c,0xfa979c3b),LL(0x0ae7194f,0x0315e213),LL(0x7a46c430,0x7d3dfc00),L_(0x3dda16de), + LL(0x69c6dab5,0xcad74055),LL(0xb4650e32,0x5f980b30),LL(0xf457bc61,0x08ab6cd4),L_(0x08a5060d), LL(0x5a3b5bba,0x4a0eec60),LL(0xc2d75bdb,0xa4e2c616),LL(0xeb13a610,0xea8ba726),L_(0x5b8d1d6b), + LL(0x8208d95c,0x1d126957),LL(0x852ba024,0x38314570),LL(0x2b3db8bc,0x68f43b86),L_(0x4e0c61da), LL(0x2fa1baa8,0xb3650b8b),LL(0x81c43c97,0x222d46b4),LL(0x5ab609c3,0xe25b7f78),L_(0xf9adc44c), + LL(0x2601c0c3,0x10c7e593),LL(0xa7b8c442,0xd433020b),LL(0x163a4b4f,0x6ea15982),L_(0x0f63c4b6), LL(0x559abf4c,0x168cc6db),LL(0x63fa3ddc,0x5e92d42d),LL(0xcad8eab0,0x0f718cd3),L_(0x285e6621), + LL(0x1eccb2de,0x45eee5ae),LL(0xbeed1a3a,0xf0f806c2),LL(0x93a2e216,0x0b896b9f),L_(0xaddd1455), LL(0x21ac6aa7,0xe860a374),LL(0xbb52f5cc,0xa6d03d5e),LL(0xc336e305,0x5a3ad08c),L_(0xd8ac8cf1), + LL(0x7e65ba98,0x927ff44f),LL(0x6eb2af1f,0xcfc2ebd3),LL(0x8e5841d8,0xcd919ed2),L_(0xfaf6b44a), LL(0xd72479fb,0xf9079703),LL(0x31c04f62,0x11b2590d),LL(0x12b5f89b,0x9e78739c),L_(0x829845bb), + LL(0x6497199a,0xcc5dc1ba),LL(0xc6068072,0xc7f1ee3e),LL(0xbbfeebe2,0xa475b47a),L_(0x497220e3), LL(0xd00f3343,0xaa2739d6),LL(0x7a34054f,0x6bcba57f),LL(0x08421638,0xf50c5c89),L_(0x5194e599), + LL(0x56ea720f,0xc14eb574),LL(0xd278e415,0xe5e93b7f),LL(0x1a141ce9,0xf206da59),L_(0xde031e92), LL(0xff6ca107,0x85cacb30),LL(0x27ecddf0,0xe54c35f6),LL(0x73777848,0xeecb8a06),L_(0xbffbbc51), + LL(0x27c35c5b,0x88bff7c0),LL(0xfa52e107,0x2aa31cbc),LL(0x84083f2a,0xee8007b7),L_(0xd8f67690), LL(0x7c2ce5dc,0x46d1faf9),LL(0x5603d9f9,0x0d96af5f),LL(0x7894ccc6,0x143733e6),L_(0x28c9191f), + LL(0xf8d1a77a,0x74b4b8c0),LL(0x4ced8b77,0xaa226357),LL(0x0f677dc4,0xbce88332),L_(0xc71a3df5), LL(0xa1eff8f9,0x6f4d4505),LL(0xf4ee4e98,0x37fa6b4f),LL(0x12414006,0x078af83c),L_(0x51f9c8c5), + LL(0x6038786b,0x043fa7bc),LL(0x495de129,0x39594053),LL(0xeeffb86e,0xf30130d5),L_(0x5566ee1e), LL(0x8e9bddbc,0x6b822690),LL(0x38bca4e0,0xfd18acdc),LL(0xf63c9ead,0xa29c50ef),L_(0x6ca8c69e), + LL(0x875129d9,0x23706eff),LL(0xbd7972c9,0x343d01b3),LL(0x0f0278ce,0xd1d2ff3f),L_(0x859707ee), LL(0x62e80eee,0x76f993b1),LL(0x46b5aa17,0xd8eb588f),LL(0xc6cb2916,0x3e93bfcf),L_(0x6b823d1c), + LL(0x40dc4150,0x02fc59aa),LL(0xa4e36005,0xf4b7afee),LL(0x2f863790,0xdf1eb2ce),L_(0xdcdc305f), LL(0xc2be20ae,0x05119c9a),LL(0xb011c039,0xa27da69c),LL(0x59ba9dd2,0x50be3370),L_(0xd25c56ab), + LL(0xe5b817ad,0x62b0b4a9),LL(0xe35b330d,0x0b744a17),LL(0x49eb11c0,0xdb8066e2),L_(0x8fd0b5d0), LL(0x60bc3f3c,0x9db8094e),LL(0x0164c3cb,0x1a336970),LL(0xe5728d57,0x98764bb8),L_(0x9ecea57f), + LL(0x471336b1,0xc97e0c25),LL(0x84d2cb69,0x40016340),LL(0xd00385b4,0x8681b939),L_(0x5ce0fa5b), LL(0xfb0504e7,0x190db5e8),LL(0xec267c2d,0x73d7879b),LL(0x5e7d8612,0x8f037a48),L_(0x0c242e37), + LL(0xb920e08a,0x81a11e46),LL(0xab88a28a,0xad7ce91b),LL(0xd873ff38,0x463f5eef),L_(0xb449cd10), LL(0xa997a44b,0x67e4b48b),LL(0x65bf00de,0x76b8b69f),LL(0xc007a35a,0x0ebb0cc7),L_(0x168c4cb8), + LL(0xc6331e3e,0xd49fdc60),LL(0x08277aa2,0x3f1c848b),LL(0xae53c6d2,0xa68e50ed),L_(0xf9940a04), LL(0xa6271229,0x1c7298ae),LL(0xc7e75832,0x34a3a581),LL(0x6666c91c,0x1bb3ce87),L_(0x9b5e6600), + LL(0xabcce7ac,0xfa1beb7d),LL(0xc3326260,0x9cab965d),LL(0x7c86ce27,0x145e311e),L_(0x1c036012), LL(0x3f4563cb,0xbd40ee7b),LL(0x7397bad6,0x077a6fa1),LL(0x6ab23a8b,0xdc9e2258),L_(0x524c8593), + LL(0x27ccdc45,0x8d1e93bc),LL(0x8122aeec,0xac370974),LL(0xf5fc7d6a,0xbb95cf97),L_(0x1eb1cdc1), LL(0x65e7b71f,0x0d3d8936),LL(0xa618f61f,0x6cfc89cc),LL(0xcfd74f9d,0x46c8cccc),L_(0xc39ab4da), + LL(0x82c35cad,0x4b6e4cd2),LL(0xb8deb535,0x5bf959ed),LL(0x77b74152,0x14153467),L_(0x1a6510e5), LL(0xc645fe15,0x44ed7180),LL(0xd0e5fe61,0xb00a2c9e),LL(0x94c68e2e,0xcd40eadd),L_(0x54367d74), + LL(0xdb397bc6,0x0bb14c2d),LL(0x90f3c232,0x2727c32a),LL(0xbdde6547,0xf5120538),L_(0x6f363a14), LL(0xca65a20d,0xb71dac7a),LL(0x0119f615,0x7b4ac903),LL(0xf1e5f556,0x83bcccf1),L_(0x78b79fc1), + LL(0x35177eb9,0xb2a6346d),LL(0xba547ec6,0xcdb1c427),LL(0xc5c607ff,0xf6acdcca),L_(0x272a5f1e), LL(0xf198276f,0x5ddfa215),LL(0x187de1bb,0xc1a3402a),LL(0xc070af80,0x0cf324a8),L_(0x8fba9bd5), + LL(0x4be4c6c1,0xddf4319c),LL(0x90adc217,0xcc96208a),LL(0xd1d87cd0,0xc3e2cfee),L_(0x76bd76ab), LL(0x1fa3dfb2,0x89c310af),LL(0x72ee71cc,0xab955eb2),LL(0x1e3849a6,0x4e9da2a4),L_(0x49c4cd74), + LL(0x4a409b87,0x4a32be16),LL(0x591f45c9,0x5593d29c),LL(0x1f66b255,0xa18a71de),L_(0xa8df9f2a), LL(0x871121b9,0xd5a52a49),LL(0x0518891a,0xdb77ca39),LL(0x35178007,0xe87f7b56),L_(0x236d66c4), + LL(0x7b11bf26,0x78cced92),LL(0x100d41cd,0x568cf974),LL(0x1aebc2f4,0x90437303),L_(0x4f4abe7b), LL(0xe1d4cf61,0x81708f04),LL(0x6b6039fa,0xfcd5e395),LL(0xe8e310f1,0x67164e9b),L_(0xc7f1e7ae), + LL(0x4435eb40,0x309bf5d1),LL(0x2117b17c,0xfa094c38),LL(0x0f0f519b,0xa7712b6a),L_(0xa339b91c), LL(0x13b443e9,0x3fc80f73),LL(0x5eca3c74,0xc2640658),LL(0x6f1b036b,0xcc979824),L_(0xf9c46f37), + LL(0x2c10fe83,0xfd4280b4),LL(0x61dfd82b,0x0f01bc50),LL(0x8ebbdd0a,0xe8a94761),L_(0xea097594), LL(0x3331db36,0xe9e32c12),LL(0xe3fdca90,0xdfdd390f),LL(0x7d9acfa0,0xf46a833d),L_(0x0a373092), + LL(0xb1f7d641,0x50d5c66d),LL(0xc56a23dd,0xd311bbb7),LL(0x2df06964,0x4d4065dd),L_(0xb24fc29d), LL(0xc5f2e7e8,0xa84be5a0),LL(0xee36de4b,0x704fb714),LL(0x72ab97c4,0xe211a72c),L_(0x4e457419), + LL(0x22e459d1,0x262ef282),LL(0x57520b17,0xcdae125f),LL(0x400cd2e5,0xc83f210b),L_(0x219146d8), LL(0xb3e5fe6d,0x87c8591a),LL(0x2cdbe07a,0x83fd93d1),LL(0x072fa5b0,0x7d701f58),L_(0xe67d391b), + LL(0x2dda42fc,0xa6490705),LL(0xbae6af5f,0x5e3ec835),LL(0x974661b3,0x77bc552c),L_(0x51a8bdf3), LL(0xf43d8648,0x351407f7),LL(0xfaacee32,0x93522ec0),LL(0x2effc179,0x49a92d02),L_(0x35e7a36b), + LL(0x1178f9fe,0x88ddd25b),LL(0x29a04cd6,0x4985102d),LL(0x0d3de452,0xf0277afe),L_(0x52955ade), LL(0xf3571745,0x53a80f8c),LL(0xcd0ea6e7,0xa11d84cc),LL(0x8cf3c9a4,0x7920692b),L_(0x66ad31de), + LL(0x3259f508,0x8dd2cea1),LL(0x147b087a,0xb1de59c3),LL(0x964e43aa,0xd9cd158a),L_(0xe62a2c56), LL(0xf7812a2a,0x483a8ca3),LL(0x133f5131,0xf93b681f),LL(0xeafa2982,0x22d0852e),L_(0x47016331), + LL(0x4e3898e8,0x178b364e),LL(0xdedbf0d6,0x1e46cbf2),LL(0x07005a6a,0x017cc249),L_(0x3350187e), LL(0xe3d63871,0x9df8269b),LL(0xa447b67a,0xf32797a4),LL(0x1360de40,0x70a39a32),L_(0xe07cb8f9), + LL(0x58005eff,0xefaea42e),LL(0x83a181cc,0xcdf53ee0),LL(0x8d9f77b8,0x2be3de21),L_(0x199ee148), LL(0x219fc4d7,0xdfbb4054),LL(0x5fd887bc,0x370b0057),LL(0x0df48ecb,0x67c50061),L_(0xceadf6f4), + LL(0x7d760757,0x3cb96c10),LL(0x8354395a,0x87378266),LL(0xc87eb4e6,0xbb1b1686),L_(0x2ca2a9d8), LL(0xf625cc5e,0x7f6f6bfb),LL(0x375d90fd,0xd1702bfc),LL(0xd7459a05,0xb5757892),L_(0x8e648246), + LL(0x2285b7c6,0x77777ad0),LL(0x98514815,0x2a9f4626),LL(0xa5cb03f7,0xbdaaa412),L_(0xf84efd29), LL(0x6fb99eec,0x8aa2c4b5),LL(0x9cd6f177,0xec729246),LL(0x9b9f8d87,0x995887b7),L_(0x2944bcdb), + LL(0x786ccb7d,0xae2ffd66),LL(0x8f43b748,0xb566147f),LL(0x0b294654,0x42cc5e69),L_(0x8eb5ab4c), LL(0x1634f1db,0x21f0caa7),LL(0x3cc24e4e,0x80410ce5),LL(0x6597b349,0xb9e50c3a),L_(0x390fd5fc), + LL(0xbefea27f,0xca541338),LL(0x25552e16,0x0bc9bd26),LL(0xd300e1fc,0xed2c5b84),L_(0x2e61d461), LL(0x731c6b5e,0x10fed3e2),LL(0x3f6fedc9,0x6d0357ab),LL(0x30c7c4b6,0xfdf04b77),L_(0x6ca06d8d), + LL(0x6198d0c0,0x49f0ac87),LL(0x355910d8,0x5908bfa5),LL(0x2b72f231,0x1e0626b8),L_(0xcd397171), LL(0xb70c5fde,0xaffd0d74),LL(0x4feccf28,0x30464156),LL(0xbe7c0da7,0xf7d2ffb9),L_(0x782a9bb8), + LL(0xd71029f7,0x2ac8267b),LL(0x58c7cc85,0x4f8afc3b),LL(0x2d787218,0x10f9a786),L_(0x005ab707), LL(0xf19c8b55,0x5209c3c7),LL(0xa8e944c7,0x0212109d),LL(0x4e16a382,0x3cd77b54),L_(0x4ca72d58), + LL(0x4e89b492,0x77501651),LL(0x30cb8e0d,0xdbb5243c),LL(0xd24a6908,0xc09c5df1),L_(0x10b46bf0), LL(0xeb16d02e,0xb28822ac),LL(0x790e9a17,0xbf46b5ba),LL(0xde8a18e1,0x47566077),L_(0xd3c60b3c), + LL(0xa4a4f17a,0xdff0cf1f),LL(0x0aef91c0,0x34f0c71a),LL(0x3fe5a3b7,0xae1fff30),L_(0xf6c8d6d5), LL(0x95b01983,0x5317a578),LL(0x10e5c9f2,0x8872e118),LL(0x154f511a,0x28ad7f46),L_(0x1f7f1f26), + LL(0x3c4162c4,0x88636424),LL(0xf620131a,0x69f32e24),LL(0xf3a9fd92,0x049b5c0f),L_(0x6242ff79), LL(0xd8613d4e,0xcf94b297),LL(0x0250d486,0xf99f0a15),LL(0xf6d69ab3,0x8d722881),L_(0x726c3c6f), + LL(0x2829f721,0xc6f3cc19),LL(0xf0ba6d0a,0xf0c5f76a),LL(0x0d44b294,0xda7df6fd),L_(0x98458d66), LL(0x35516899,0x4c9c487f),LL(0x541b8cf7,0x312edd80),LL(0x14a64ecf,0x2db649b2),L_(0xfcc41f23), + LL(0x4e65d481,0x17bb4dfc),LL(0xd8c4ee32,0x7b8827b1),LL(0x6ffab99a,0x788afe5d),L_(0xb6cc5390), LL(0x6ed82d81,0x75adf2d6),LL(0x91030ac7,0x99ce22b0),LL(0x957976c9,0xf8f37372),L_(0xeae6d45f), + LL(0x3ad3db42,0xa4617ca1),LL(0x9ea768ee,0x8f228cec),LL(0xc881f9da,0x86ddd01a),L_(0xddfb0090), LL(0xd1467d75,0x41eb80aa),LL(0x1320c7b6,0x875ce5dd),LL(0xaf17e700,0x398d4c2f),L_(0x91ca1818), + LL(0x165575ce,0x7c2f636f),LL(0x94407a75,0x89f1290d),LL(0xeeb00b1e,0x2cccc148),L_(0xc1a654f8), LL(0x7200e28d,0x5409cce2),LL(0xd579aa30,0xf8e920e0),LL(0x3586fdc4,0x11976312),L_(0xd9b1a394), + LL(0x45934ad1,0xa0a5bb1b),LL(0xba2becd7,0xbcff29b1),LL(0x9f749e30,0x2f73a7d6),L_(0x54ae60bd), LL(0x9ed5bbc9,0x111b6548),LL(0xae179cab,0x7b77f3f8),LL(0x9b568171,0xf1563350),L_(0xd57cc18c), + LL(0xbde3fb89,0xaa153efc),LL(0xe84063ac,0xf24dc768),LL(0x91718221,0x3207691f),L_(0x666ced3f), LL(0xa962b884,0x8a1416f3),LL(0x81f644db,0x2992be1f),LL(0x388328fb,0xa7c4a359),L_(0xebba06d7), + LL(0x709d7f63,0xf678058c),LL(0x9bd30551,0x9db19686),LL(0x8d882bae,0x81afb521),L_(0x6d103aa5), LL(0xce4ef2a5,0xc6ecf132),LL(0x681bea3a,0xab9bbd78),LL(0x3831d678,0x4c11a697),L_(0xb9d4a72d), + LL(0x8a72049d,0xc3e5138e),LL(0xa25affde,0x9235657e),LL(0xf870194a,0xeddbefb7),L_(0x2583cc8f), LL(0x85d843d9,0x912ed2a5),LL(0x57849cc4,0xdb45568e),LL(0x453cbf16,0x410259cc),L_(0xcf9369cf), + LL(0x10263ac8,0x69fa2805),LL(0xf7446e45,0x6120289a),LL(0x86d5285d,0xece730a0),L_(0xc0ee3533), LL(0xbf1197bc,0x286f4724),LL(0x878ea926,0x0b0ef425),LL(0xf397181d,0x24bb4f4f),L_(0x542c7100), + LL(0x162331a9,0x536a5ea6),LL(0x0e466905,0x88c29411),LL(0x3da5a14f,0x9cb76097),L_(0x1db565b9), LL(0xef6b8094,0x59e86f3c),LL(0x31eb3c89,0x817764eb),LL(0x58eed1b6,0x8010fc3d),L_(0xaeba318a), + LL(0x9a5b60b8,0x108b3068),LL(0x1ffea59a,0x1312c3e1),LL(0x8dd4b81a,0x0253e9dc),L_(0xf4ed9d4a), LL(0x5eadccd2,0xbd75013a),LL(0xad3eaf49,0xc60daec9),LL(0x20b2a500,0xbea0d3fb),L_(0xdac00c65), + LL(0xfb3fb2a5,0x72db2c7a),LL(0x566902bc,0x864ce0fe),LL(0xe0956799,0x2d7ec9e2),L_(0xdfb7dad8), LL(0xdfc7056f,0x77bfd4dc),LL(0x7e188701,0x0f42ffde),LL(0x110fb370,0xf2040e52),L_(0x7944c336), + LL(0x2100e0bb,0x6fd68890),LL(0xf771684b,0x67978ca7),LL(0xb3a94049,0x279171ad),L_(0xc7c765dd), LL(0x02304590,0x41165c1f),LL(0x0299e83b,0x8eadb8c9),LL(0xe9eaef42,0x2345e24e),L_(0xb4a1f1f3), + LL(0x41f15f2a,0xaa889c09),LL(0x2cb037eb,0x6adf563e),LL(0x559edd7a,0xdd414cb0),L_(0x601d6943), LL(0xad8084b7,0xbef296d5),LL(0xb70a236e,0x0ee342a9),LL(0x074068ff,0xc9f3a4e6),L_(0x7b2eab9c), + LL(0x4db1a4b4,0x983e29af),LL(0x50522f93,0xc26d69a6),LL(0x8e174c76,0x2739f19a),L_(0xc8bc9b25), LL(0x4c902614,0xcd082b89),LL(0xa5f7fd65,0xa0661a39),LL(0xd0352acc,0x6d5bd738),L_(0x15c9e55c), + LL(0x0f46deb3,0xe05a9d3e),LL(0x25c49119,0x68d899f5),LL(0x2fcbd485,0xd426fbf8),L_(0x94e9a11d), LL(0x70b0b8e8,0xbb075381),LL(0x21ac6e8b,0xeb323221),LL(0x933c7339,0x90f21e83),L_(0x03161725), + LL(0x65c3ea70,0x26f5292f),LL(0xbb26aa3c,0x2f10ff0c),LL(0xd0e0dfce,0xe59106aa),L_(0x5bc81388), LL(0x334ef2fc,0xe1d13288),LL(0xe91c8aea,0xb2dd6c7f),LL(0xe941b704,0x428af6d0),L_(0xb82ceae2), + LL(0xf4357fa7,0xe9634ed9),LL(0xea606688,0x92f270b1),LL(0xb8fe4e04,0x4ce90044),L_(0x53c7eb07), LL(0x9137e5a7,0xb5cf536c),LL(0xc36a01d3,0xaa1f4551),LL(0x0024f90b,0x981784b9),L_(0x3bab3f51), + LL(0xb04608df,0x5269aa1a),LL(0x0cf9cff7,0x8ce1ebee),LL(0x3d279465,0xc66381e8),L_(0x61b7ab00), LL(0xc4fa7ed7,0xdeb29303),LL(0x6b7bf135,0x510a3c8c),LL(0x2ce166ff,0xaa227120),L_(0xf4a128bb), + LL(0x992398c7,0xa3c32177),LL(0xb5766593,0xcd19850c),LL(0x70b1a326,0x9505296f),L_(0xe3747c6e), LL(0x41bcad27,0x0d11515a),LL(0x290e370c,0x04883b49),LL(0x5a5bf602,0x72d1e180),L_(0x6a7dda52), + LL(0x5898ed4f,0x63896a2f),LL(0x0341c2af,0x82a0ed92),LL(0x71349776,0x71b9b0ee),L_(0xa68523a0), LL(0xd360630d,0xbd440771),LL(0xc3982209,0xa49907d9),LL(0x28e79328,0xad498ec7),L_(0xde9039d6), +}, +/* digit=21 base_pwr=2^147 */ +{ + LL(0x5e338a95,0x0324aba6),LL(0x3d1721e0,0x970769c2),LL(0x32ea5aeb,0x82c3b64b),L_(0x62043072), LL(0x80346bd2,0x98111ddd),LL(0x629d0540,0x2ef9e31e),LL(0x75819a03,0x6e0e0fd4),L_(0x01541785), + LL(0xd481d37b,0x676ef7cb),LL(0x6e38c822,0x6ddd542a),LL(0x4bcdf56d,0x0807b6ee),L_(0x152d3a20), LL(0x99cfbaa2,0x440a4586),LL(0x1b803f58,0xaab76f82),LL(0x62bde53d,0x31ca293a),L_(0x774dabf4), + LL(0x279a665e,0xc73f3e56),LL(0xd125dbe9,0x51cce02a),LL(0x925d55fe,0xba48033b),L_(0x77120d9c), LL(0x3c3cd000,0x09219d1a),LL(0x9ef0977f,0x7bba7cbf),LL(0xf5c59984,0x1f9a5c08),L_(0x043d05c2), + LL(0x4079f18a,0x150e6d32),LL(0xfb5764ea,0x8b6cc92a),LL(0x2d425400,0x274ec0c2),L_(0xee8a4646), LL(0x6d261b02,0x4ef086f3),LL(0xf2d17e5e,0x29dec1b8),LL(0x7f963f71,0xea97e94e),L_(0x70fad827), + LL(0x9e51713a,0xf9867b99),LL(0x07c55712,0xbd760d63),LL(0xafdf07e9,0xa9b6e9ec),L_(0x2af4df6e), LL(0x6d61dc08,0x93df1b2e),LL(0x743dfab5,0x3387d03a),LL(0x32d7f165,0x759fb34d),L_(0x749bb511), + LL(0x08345265,0x34f3b1e1),LL(0x599ac0d2,0x20468106),LL(0xc8425e31,0xa035ed92),L_(0xbe2663eb), LL(0x15129a67,0xd78546b5),LL(0x6589a68a,0x2a03f31f),LL(0x04faf0ec,0xf88d60ed),L_(0xe6fe6524), + LL(0x99a20d9b,0x31f03c7f),LL(0x93d3e67b,0xbdab0f5d),LL(0xcfc1004b,0xc665b5f0),L_(0x3425e2f4), LL(0x57bee517,0xbaab1072),LL(0xf467b795,0x64de4d9f),LL(0xa4efa899,0xb3c284d3),L_(0xdb30b893), + LL(0xb6ef6e50,0x7bd6b2eb),LL(0xe6144c26,0xb87b9f50),LL(0x3506344d,0xe38cc59c),L_(0x136536d0), LL(0x98614bb5,0x4daab44e),LL(0xb52c6949,0x3957de52),LL(0xc680567a,0xcfa42f96),L_(0xf20dca71), + LL(0xad09cde7,0x89749594),LL(0xf7758fa7,0x686f22a7),LL(0xe7736848,0xd741b21a),L_(0x916557d5), LL(0x08ab4ccf,0xb87c7bef),LL(0x6a38311f,0x982331fd),LL(0x177b6473,0x63140d6e),L_(0x61df2b77), + LL(0x061731b0,0x785b32f1),LL(0x92de60e5,0xc296cafa),LL(0x1de52e72,0xb10ce663),L_(0x4c01f4cd), LL(0xc6a06419,0x50016567),LL(0xdcbb4a2a,0x4502900a),LL(0x2c001a59,0x450b28d5),L_(0x3a580e42), + LL(0xc5913491,0x9e1e0ce7),LL(0xfef505e8,0xc5f9091a),LL(0xe7590273,0x44739896),L_(0x35472c73), LL(0x449da237,0x3913a8d2),LL(0xbf43ca41,0xd9db43d7),LL(0x0204d37f,0xbcc28709),L_(0x11a4ed34), + LL(0x0ba00095,0x00c25d60),LL(0x00ebff6a,0xb0ccb9b4),LL(0xaecf0812,0xebecd41b),L_(0x02599546), LL(0xe2cb6f9d,0xe9f56be8),LL(0xc9f2f401,0xab12b175),LL(0x77e2c3e0,0xa7a303fc),L_(0x6a047f0f), + LL(0x0ca6bd42,0x829f1bab),LL(0x4982f7c1,0xf8aa85f0),LL(0x63a37ba6,0xe64c6ed3),L_(0x55b4405c), LL(0x9ba22c57,0x14c74bf2),LL(0xd812115d,0x57cdabdb),LL(0xa2f36ff4,0x69603458),L_(0x4e2488fd), + LL(0x049ce7fa,0xdda045cf),LL(0x3c6cc5ab,0xae642723),LL(0x444a4ca8,0xc9e8efd0),L_(0x2e1a3d2a), LL(0xee8ff913,0xa5f0a182),LL(0x3921bdba,0xf34c0a0e),LL(0x0bdcdecc,0xf174835c),L_(0x438b3f48), + LL(0x262941ff,0x50dd89e9),LL(0xb28cdfa5,0x52bfaad5),LL(0x3d3651a5,0x42da9f6d),L_(0x52955126), LL(0x72f24772,0xfb5c67bc),LL(0x10d91fd9,0x6f3ebdef),LL(0xa8074e96,0x5d95664e),L_(0xe7fca6c3), + LL(0xfbd1a192,0x14bfa4e1),LL(0x11f314f6,0xf38ce345),LL(0xfcdb2abd,0x45ebd21e),L_(0xc304c980), LL(0xb59f480b,0x3957e934),LL(0xe9a58ad5,0x7c1b8e5a),LL(0xe4604f76,0xc58f2c48),L_(0xe27bf6c2), + LL(0xc8a88d73,0x21606f53),LL(0x6659ed53,0xfba9c9f7),LL(0xfb7d83f0,0xf57dce48),L_(0x2d2bf81f), LL(0xfb80fd50,0xc8023a07),LL(0x2b42338b,0x71a25cd3),LL(0x7a9a0b44,0xb3c48734),L_(0xc8125d7c), + LL(0xf3798b63,0x9856b7c0),LL(0x914f7c82,0x04ab2721),LL(0x471ef449,0xe5f3587d),L_(0x77a7fe57), LL(0x21b96d5d,0xb0c73d23),LL(0x1ec93eff,0xa3366107),LL(0x69323a1b,0x759bf017),L_(0x3f60e38c), + LL(0x80978741,0x4e3559fa),LL(0x56b197e8,0xe7559080),LL(0x56ad6e70,0xdd9852be),L_(0xeeb6dec8), LL(0x0e7594df,0xe4523a8a),LL(0xc67e9c41,0x4a40d4e4),LL(0x8ca5687b,0xfaf902fd),L_(0x731b0560), + LL(0xd2ade9c2,0x683ea003),LL(0x3784426d,0x6bbf8ead),LL(0x26a2a12e,0x65fa7d53),L_(0x7ab25cd8), LL(0x6154c3a9,0xd7f809d8),LL(0xe2d2306a,0x20ed9166),LL(0x24d19af8,0xa692a83a),L_(0xbb68e143), + LL(0xd8e0ff43,0x90e27172),LL(0xf7b7a48d,0xa90bf44c),LL(0x8cb2abd0,0x130d21df),L_(0xd9526e86), LL(0xa3cb4c6b,0x65186f8e),LL(0xe78f59ce,0x0c9c373c),LL(0x3514478f,0x5307b692),L_(0x15b86f33), + LL(0xd8568306,0x34f0a25d),LL(0xea579beb,0x039f50cb),LL(0x0eadf2ee,0x6a3cf739),L_(0x7fffefa0), LL(0x6a9a2a62,0x5c707fb6),LL(0x1f9a5c8a,0x22360abf),LL(0x756df232,0xa7a12676),L_(0x735ae0c5), + LL(0x232b0eaf,0xfac26fa0),LL(0xc57f8429,0x91c0d8b2),LL(0xc85b9885,0xcd36972d),L_(0x5ab11f6e), LL(0x2b28cccc,0xa2197bb4),LL(0xcf7b4e95,0xb00034b6),LL(0x22200d9d,0x398b8d08),L_(0x0660c348), + LL(0x3e7e898b,0x14230734),LL(0x8aa5dec9,0x7bef4c46),LL(0xe3a1abc8,0xb3564180),L_(0xb7f989a9), LL(0xeed81407,0xa7ce6e62),LL(0x98270e80,0xf02dd5b1),LL(0x9d22967d,0xa3ff259d),L_(0x4be6673e), + LL(0x25d2230c,0x2d777318),LL(0xd815968f,0x80147bab),LL(0x6f460f52,0x22279805),L_(0x99635b0b), LL(0x20550e62,0x7880c924),LL(0xf836942d,0x6428d5fb),LL(0x9a19cfda,0xd1beb76b),L_(0x819b5402), + LL(0xe36b37d4,0x5d87cbda),LL(0xe5f505ca,0x404781e7),LL(0xc8f5e0fe,0xa1bc9eda),L_(0x45ef1d15), LL(0x23299059,0x970d11fc),LL(0x54084d2b,0x785e8445),LL(0x8ed8b412,0xbad1345d),L_(0x2975a901), + LL(0xce7aa169,0xd74f6437),LL(0x62092837,0x1f1dc772),LL(0xf497718e,0x36827efd),L_(0x15977763), LL(0x978b617d,0x4cb29feb),LL(0x65c2897d,0x6a64b733),LL(0xe04077a2,0x86b8cf3a),L_(0xac075b5b), + LL(0xed710d98,0x3a39d170),LL(0x1f51c85b,0xef236d5b),LL(0x0683a7e0,0xb9141322),L_(0x7e27c47c), LL(0x05109f74,0xdade7c00),LL(0xe2f07be3,0xf251df44),LL(0xc11452de,0xb48e9a05),L_(0xd6a44d08), + LL(0x4aaf45f5,0x17039bf0),LL(0xbdcaec9d,0xb97b72ed),LL(0x30ce8053,0xa7a81755),L_(0x54e63f42), LL(0xc81db67b,0x80753cae),LL(0xc22c28cc,0xe3019a4c),LL(0xd1c81400,0x80f8c3da),L_(0x5a1e70b6), + LL(0x165046c9,0x030a06a1),LL(0x0ea30c39,0x09c6053c),LL(0x3932bda3,0xcb39f998),L_(0x148a2b68), LL(0x87fe7977,0x0499f81d),LL(0xb74e61d3,0x7ae298cf),LL(0x2959c264,0x1edb6b93),L_(0x6a2188dd), + LL(0x6ab52745,0xdc732139),LL(0xd70d9371,0xbd7da6c2),LL(0x5ac1ef95,0xe2e0217e),L_(0x6e9b8907), LL(0x63f9997b,0x5cecf1c0),LL(0x24552abf,0x5082d35e),LL(0x7b11e2cc,0x04cc9aa3),L_(0x78bdf631), + LL(0xfecff2a7,0x4f8b44cc),LL(0xe83e0eae,0xd783714b),LL(0x9c0232a4,0x90d1c36e),L_(0xb7e1ea84), LL(0xbd5e004e,0xf22c1c14),LL(0x99441dcc,0x77b24ec6),LL(0xc4fac858,0xf15be1db),L_(0x52f8f005), + LL(0xfa634b74,0xc11ab7e2),LL(0x865bc26d,0x39a0b0f1),LL(0xa62656eb,0xdf5e8e89),L_(0x5bbda8fa), LL(0x35af495b,0x059e7fc2),LL(0x996cfbbc,0x5721bb40),LL(0xfcc7a8b4,0x18530aec),L_(0xef18ab08), + LL(0x1efc0865,0x7e7fb20d),LL(0x1432863a,0x319cbee0),LL(0x32603543,0x216780a7),L_(0x3173509d), LL(0x771c5009,0x332b0e8d),LL(0xfb32ae5e,0x27842538),LL(0xfd61d211,0x176fee74),L_(0x8d713db3), + LL(0x6d5e6c04,0x8f5f36df),LL(0xfd53bdb1,0xff86482f),LL(0x04fc8d4b,0x35ae923b),L_(0x9c93970b), LL(0xd03159ae,0x6c4574ce),LL(0x0c5ab9f8,0x95e44ad6),LL(0xecc940e1,0xacd13e60),L_(0x73d20a97), + LL(0x24bc05c8,0x55d8d9f7),LL(0x1be2d507,0xba1700c6),LL(0xb1dbe56e,0x12671c92),L_(0x515125ba), LL(0x7c873619,0x28f4b581),LL(0x00d413e2,0xc27395ee),LL(0x31a82a43,0x84bd2bdf),L_(0x5c6f966e), + LL(0x19e04eb8,0xd6d7b2f3),LL(0x32f059d3,0x7d71e73c),LL(0x5dd55589,0x6b4ddaaf),L_(0x7a059ec2), LL(0xb3874052,0xb395499e),LL(0x4cfc04e5,0x56ce4cbb),LL(0x5961b289,0x2960f1ca),L_(0xa3443d73), + LL(0x739615c6,0x72405988),LL(0xe58efd36,0x03300370),LL(0xe254b688,0x6195855d),L_(0xf750a8c1), LL(0xd298a296,0xf9205a13),LL(0xfa55931d,0x11ffb780),LL(0xe00ca07c,0xd638a7b0),L_(0x1b178a9f), + LL(0x970fe956,0x62d115d2),LL(0xe1985dec,0x4db47694),LL(0xb3652081,0x6565367b),L_(0x61dc5dcc), LL(0x53a17e00,0xbb00a05a),LL(0x390808ef,0xc7f0a623),LL(0x2971e39b,0x091d591c),L_(0xb6590fcd), + LL(0x3c51221d,0xd273fed4),LL(0xb849d7b6,0x7eaf4c1f),LL(0xc3cadac4,0x155b21cd),L_(0x21bf043c), LL(0x824bf43a,0x6d0eb93f),LL(0xa560a086,0x2b5af50c),LL(0xe79201e3,0x50f56685),L_(0x7193da80), + LL(0xaf65e93e,0x64cb8361),LL(0x097bd142,0x2b08724e),LL(0x5d31d941,0x128434b7),L_(0xd3455462), LL(0xd87b7934,0x6349bb61),LL(0x5338e12b,0x8eabd8cd),LL(0x46f9abc2,0xf5ec4590),L_(0xee7ff24e), + LL(0xde41b0d8,0xfcdd55ff),LL(0x390333ed,0x5f8a8d73),LL(0xad3ba05b,0x5c84894a),L_(0xdd94d8c3), LL(0x1041454f,0x7425541f),LL(0x4f6bd774,0xf6c08550),LL(0xbe1bce56,0x48f611af),L_(0x723a0cc8), + LL(0x31e207ab,0x505aaa25),LL(0x6f2c316a,0x9df3ed0d),LL(0x6ff3aa7e,0xecdfa689),L_(0x0c314ac1), LL(0x4660e302,0xaac1b188),LL(0x74b064f0,0xe2709e66),LL(0x1690d7e4,0x9ad43bd5),L_(0x19d6932b), + LL(0x9e4966da,0xe9803ed7),LL(0x5acbb8d9,0x94a51c09),LL(0xc6ffb2f1,0xac8d73e5),L_(0xce57f6f3), LL(0x87ee51c7,0x0f2f29a5),LL(0x1c8a8a14,0xcf07fe4d),LL(0xf7993328,0x11a086fc),L_(0x816c9d1d), + LL(0x482c8577,0x7008cc6c),LL(0x3a6923e0,0x4ea34320),LL(0xea139dd1,0x0db793be),L_(0xc99cf72e), LL(0x2f88c486,0x46daeb88),LL(0xf235e9a5,0xa9529776),LL(0x8fc9a2fe,0x685903b2),L_(0x2e9cc9d4), + LL(0x160fbbb0,0x85dc20a6),LL(0xd5312a9c,0x40ce263b),LL(0x33ee3772,0xf18c955f),L_(0xb8cc18a3), LL(0x7c56f68f,0x629b2ed0),LL(0x381772f9,0xd3751f88),LL(0x9be35b3d,0x87658375),L_(0x438ba3ac), + LL(0x4c71f19e,0x2e6a930b),LL(0xbe1f2bc3,0x6ce370bd),LL(0x9c7c9090,0x9fe1a225),L_(0x9a8e7036), LL(0xdfc19acd,0xbc4095c2),LL(0xbf429df7,0x102343b7),LL(0xa07aed0a,0x75593f8f),L_(0x2c1e8aa6), + LL(0x6e87ec50,0xe6abe1ed),LL(0x6cc4e156,0x32e1d48d),LL(0x9c1aa3b0,0xbc16fee9),L_(0x76d25ea9), LL(0x1a098c5e,0xa549cfc8),LL(0x0fe8dc0a,0xdccd7aa4),LL(0xe2b2179c,0xf0addee3),L_(0x9bcbee00), + LL(0xec32e6a2,0x4e4d505b),LL(0xb0ad3d1f,0xd584c5e1),LL(0x708100e5,0xf05981fa),L_(0x5ca8160b), LL(0xff71c066,0x30b8c50e),LL(0x9b267d28,0xa5cf6579),LL(0x00705bdb,0x003593a1),L_(0x6e7726d9), + LL(0x1e13fade,0xbfa0d04d),LL(0x1fd12275,0xcc81bd28),LL(0x39bdb34f,0x7ba2330c),L_(0x9cb5c2f4), LL(0xb5b45e69,0xf331bfd7),LL(0x9513f2a2,0xdd8ec1b5),LL(0xb3f734e7,0x9064cd97),L_(0x5f64f559), + LL(0x6a4afc60,0x4194a70e),LL(0x63999525,0x523cff27),LL(0x03d08e2c,0xa27e7edc),L_(0xea90ab15), LL(0xfc7c7e87,0x38873c54),LL(0x398075fc,0x805abf3c),LL(0x414e3976,0x93991ee1),L_(0x66b18c5a), + LL(0xa5d47504,0xb3fe93fc),LL(0x9c7a5517,0xb7d168b6),LL(0x4a438e8c,0x581ebd7a),L_(0x30a1a792), LL(0x1e7c3d15,0x7749a42d),LL(0x2279fc57,0x86e109ed),LL(0x853c9b29,0x069c5f0b),L_(0x4438f7b5), + LL(0x2fb4329a,0x2b3c8790),LL(0x99bbcc79,0xc7e0dd07),LL(0x9d9741bf,0x51f341ad),L_(0xaedc9e99), LL(0x6eb8a76e,0x1cd0ce38),LL(0xbf6e3e65,0x2698a77a),LL(0x3099a97a,0x6b8968f5),L_(0x6186d5b8), + LL(0x5f3a4ac3,0xf86e098a),LL(0x6977fcd9,0x3194f379),LL(0xc98e48aa,0x886d05b8),L_(0x23139131), LL(0xbd9be137,0x488df6bf),LL(0x876a25e7,0x9833b00c),LL(0xfb9f6810,0x5fb8ce68),L_(0x1a974ef1), + LL(0x0996c57a,0xe74e34d6),LL(0x95d0e8ba,0xbc8f1cc6),LL(0x49ddbd76,0x3e421dda),L_(0x47780198), LL(0x2fcb399c,0xf599d67b),LL(0xb3cd50fe,0x1de7c3a8),LL(0x60ffdfcb,0x41018e1d),L_(0x2a84e15c), + LL(0x5803c901,0x1834f6f5),LL(0x85be2737,0x0269aa98),LL(0x51b8942e,0xbd9cdd7b),L_(0x2573f804), LL(0xf11dba7f,0x62d1e404),LL(0xa026f5f4,0xa355486e),LL(0x3e7a1a96,0xa6d151c2),L_(0x52ecef89), + LL(0x5bfcbb66,0xd3cf6d12),LL(0x7f3efdcc,0x509c593b),LL(0x36beb1c6,0x50bb9be7),L_(0x87aa0794), LL(0x461e9081,0xf6ebcef8),LL(0xb12b6973,0x53fb4ce0),LL(0x1d3a4bb3,0x84afbe92),L_(0x765f75f5), + LL(0x36690884,0x66809ebd),LL(0x7d2d307f,0x6d7b75a0),LL(0xb7561328,0x7a0b342b),L_(0x25a224f2), LL(0xc6b75bd1,0x8b464a87),LL(0x98a06fcf,0x145091bc),LL(0x33cace99,0x723fe6fa),L_(0x24207bff), + LL(0xfa386bf7,0x5ea0874e),LL(0x470c5915,0xa8387298),LL(0xbc4e6a04,0x02c73e59),L_(0x303d5c07), LL(0xa4b7c2f2,0x2fdbbf21),LL(0x2d418059,0xb933bbc7),LL(0x874e47bf,0x4c88b532),L_(0xbd3a8f84), + LL(0xb79dad0b,0x94b27e28),LL(0x4c3cb167,0x47dac83a),LL(0xb3a5c35a,0xace3bd6b),L_(0x36f5d64a), LL(0x0d91b2e8,0x00f91b6c),LL(0x561c257a,0xd6d7f96c),LL(0x390f1d25,0x92ea6b8b),L_(0xce74a256), + LL(0xa7f8fb96,0xf0e6068b),LL(0xbee4d1a2,0xed56b92a),LL(0x64cd2ac4,0xd3d78730),L_(0xb0ed4379), LL(0xf0d95042,0x8db9e812),LL(0x0e235698,0x6447eba8),LL(0xd45b6fa7,0x3b769af7),L_(0x95403694), + LL(0x26f167ea,0x8aa2617b),LL(0xdb91ef4a,0x52ead3d0),LL(0x41988291,0x5273a693),L_(0xab06325b), LL(0x18ca4d81,0xb1bbd253),LL(0xea972289,0x58878e32),LL(0x64d8aee8,0xe8908e43),L_(0xcdca72ce), + LL(0x5a517623,0x6d83d019),LL(0xd917cb4a,0x969711bf),LL(0xa7fc9902,0x225d81d7),L_(0x9b126599), LL(0x25981f40,0xe02b87e7),LL(0x04539a29,0xaec410d7),LL(0x35630262,0xb1115eaa),L_(0x7461aa8b), + LL(0x83f05d8e,0x4dc83cf2),LL(0xdbbadf9b,0x523db1cc),LL(0x09d299d6,0xe968d6f7),L_(0x46a4ef90), LL(0xa5406082,0xc545ab6a),LL(0x158f1789,0xcf6e254a),LL(0x592bcabb,0x599530e8),L_(0x4ecd132b), +}, +/* digit=22 base_pwr=2^154 */ +{ + LL(0xa46f08d9,0xb9fe1aa5),LL(0x27531029,0x32c26e96),LL(0x1b37edc0,0xcc6e653e),L_(0x25a6777f), LL(0x37d78fa5,0x44dcd6fa),LL(0x44e59684,0x637ed305),LL(0x72834a3e,0x6cab1cc9),L_(0x715fa76f), + LL(0x2efe30a2,0xd9e804cc),LL(0x1c1ded3a,0xb9c440fa),LL(0xb6ba8131,0xd2f7d77a),L_(0xe00e21fe), LL(0x88842b6a,0x96f7f20a),LL(0x616f6de5,0x9a618ffe),LL(0xf13ceac5,0x6577f60c),L_(0x9f1e4b0d), + LL(0xbd482557,0x1653fafd),LL(0x93eea72d,0x39c09ddd),LL(0x10b62eeb,0x79f6d014),L_(0x2f476cfa), LL(0x78d81b01,0xe8963c96),LL(0xc395c6ba,0x8c8f6a4c),LL(0x63b70385,0x551fa28d),L_(0x28bb3fc4), + LL(0x433a33ea,0x2417a7ce),LL(0x5591c910,0x1d9155b1),LL(0x7a6ca298,0xd78e16eb),L_(0x09ee38e9), LL(0x3ab289c2,0xee48adb0),LL(0xd5b76200,0xc998c5c8),LL(0x8dd6fbf2,0x959f66af),L_(0x3ee20307), + LL(0x23a0b23a,0x63c09a4f),LL(0x24b60423,0x021b685f),LL(0x7c69331c,0xb1b0820e),L_(0x7d3c58fb), LL(0x81992f9f,0x370cbdbc),LL(0x05814d87,0xeecaf1b3),LL(0xaeba071a,0x5ebd44d9),L_(0x079434ba), + LL(0x193df859,0x7a008e70),LL(0x9d5dd4b2,0x8d7ec280),LL(0x81377001,0x3062b2db),L_(0xe82fbf45), LL(0x11e91ce4,0xdb62847d),LL(0xf3a5dc38,0x9a492d59),LL(0x42b1e033,0x3c5e448f),L_(0x0028f02b), + LL(0x48abe62f,0xf00a790d),LL(0xf18c3029,0xe9c56ab7),LL(0xcfc6643d,0x7a101d9e),L_(0x69f64af5), LL(0xe901d5c7,0xc8b5cd29),LL(0x8ab0437d,0x5a6c0d3b),LL(0xf3eacfba,0x437c7e62),L_(0x9c1ff745), + LL(0x7ef25e16,0xc3c0b7b4),LL(0x3b2bb23b,0x2d411980),LL(0x9d372287,0xb86b3e9a),L_(0xbd217cd9), LL(0x6682e29c,0xc7ddb5da),LL(0xf55b3a32,0x80ad8745),LL(0xc5272ca9,0x67e42112),L_(0x80ddaf6c), + LL(0x2db21214,0x26d65fa2),LL(0x593699c3,0x27bc92ce),LL(0x780c1507,0x62bfbfb4),L_(0x4e610cd9), LL(0x90f53f42,0x306b2065),LL(0xdcabb7e7,0x70add873),LL(0x97f0fe05,0xef3f82de),L_(0xfd016e06), + LL(0xdb734eee,0x49ac57da),LL(0x33f4851e,0x0575235f),LL(0x12e6b4bb,0x84ba90a7),L_(0x0c414c40), LL(0x2e72cdc9,0xde178a6e),LL(0x5d680978,0x2c8f9b52),LL(0x04316bb2,0x4d9021c4),L_(0xd58bf8cb), + LL(0x4a88c720,0x7c1da7fb),LL(0x2166e51a,0x7be262ad),LL(0x26f4415e,0x8d16df29),L_(0x4308e38d), LL(0x6e047968,0xf7050746),LL(0x5191f59a,0x40048ee7),LL(0x671c053f,0x7e714450),L_(0x41cd1cf2), + LL(0x126208fc,0xc3f913fb),LL(0x77459414,0x81ebbd24),LL(0xfbf9d09c,0x60be0397),L_(0x5762fb0e), LL(0xab78592e,0xee7a8b54),LL(0x11f20203,0x58636e68),LL(0x5cb0cea7,0x56d9eb18),L_(0xaab58567), + LL(0xe2adb3e3,0xe08bf721),LL(0x8b739b3c,0xcf7b1348),LL(0x88809e01,0x9dd0883a),L_(0x0dd14479), LL(0xfb2d7aed,0x9e8ac3f6),LL(0xe9234e02,0x3aa9be66),LL(0x87a97238,0x56210cb7),L_(0xa8cca221), + LL(0x515e6713,0x989ff215),LL(0xd0bcb26c,0x8011a540),LL(0x16b0e517,0xc8b38bfd),L_(0x7706fd39), LL(0x23c98754,0xc13358b8),LL(0x8745e3cc,0x5edc147a),LL(0xae944131,0xbf36526b),L_(0xb43ce39b), + LL(0xbb74f4a3,0xf57da9fb),LL(0xcceacf96,0xe6c34f99),LL(0xae99e920,0x72b76a37),L_(0x7a9e0b84), LL(0xd46a4b67,0x377b9f4d),LL(0xd8d2d70f,0x2dbc27cb),LL(0x1c0d51f0,0x63d0ccbb),L_(0x423d586b), + LL(0x76b14e74,0x5173ac48),LL(0xda87fd76,0xac29f6c0),LL(0xde2af466,0xbf4405a4),L_(0x0df31635), LL(0xe0a96172,0xc72bdfba),LL(0xcbefcc71,0x14f78dd6),LL(0x2c991165,0xf55ecef7),L_(0xa3278f6d), + LL(0x6d393d5f,0x05e626ee),LL(0xb9f01d8a,0x225ed4d6),LL(0x53d41ea6,0x5d5b37e5),L_(0x6b1d2d7a), LL(0x70c4e493,0xf4527dfb),LL(0x465bfaf7,0x1522deea),LL(0x333509e1,0xad711cce),L_(0x988f296f), + LL(0x072fecfb,0xba0c11d9),LL(0x46a2c644,0xa6fa784d),LL(0xa105395f,0x3a914aba),L_(0xa42699f5), LL(0x5b5ec37d,0x6c8c0e8b),LL(0xffef0a76,0x79696f78),LL(0x69daa4dd,0xbf1748ba),L_(0x8134c310), + LL(0x16919c10,0x43014c2d),LL(0xa35261bb,0xd14b6a12),LL(0x6d705b75,0x395d7526),L_(0x58721301), LL(0x4c3aec80,0x3f4fd283),LL(0x2e6f84dc,0x4114b4f9),LL(0x6a63c71b,0xcf962aae),L_(0x58c876bc), + LL(0x085cede4,0x39a2603a),LL(0x21ba7529,0xb203a75d),LL(0xbdc1e809,0xf3640f89),L_(0x6631c30e), LL(0x8d9d5265,0xd480817b),LL(0xad93303a,0x8492b58b),LL(0xe3368ba5,0x24b8bfe6),L_(0x26c2b552), + LL(0x64ef9738,0x6907b7bc),LL(0xd795d794,0xf6e9c508),LL(0x33b42737,0x55ab9706),L_(0xa13daed3), LL(0xf586dde7,0x76b6d961),LL(0x0ff335ce,0xad1c2111),LL(0x13031322,0x1f36dd8c),L_(0x0558b72f), + LL(0xe83a229d,0xe6ae70d0),LL(0xf0770ab8,0x5b9ca0d2),LL(0x06479e73,0x17cdf808),L_(0x5e50cd46), LL(0xd020f0ac,0xca397995),LL(0x3337dcfa,0x70369103),LL(0x3d37e46a,0x67d7bcef),L_(0x5283dec8), + LL(0x920986d4,0x9e2b8580),LL(0x6f80e6f8,0x1a1086a7),LL(0xf038b9fd,0x76630d46),L_(0x4e9ef3ae), LL(0xf2780d64,0x479ba46d),LL(0xfa784b8c,0x41a1c68f),LL(0x953b6640,0xeee5927b),L_(0x9d4a23e4), + LL(0x7a6dcf80,0x2905feea),LL(0x2a632e73,0x5bba1fd8),LL(0xd274195e,0x596a73e6),L_(0xaf3000ac), LL(0xfa2e2813,0x83723184),LL(0x99dae0bb,0x21f09629),LL(0x7ce090e3,0xb6dc2849),L_(0x2bd68086), + LL(0xb254b1d5,0xfee577f0),LL(0x2ce6dbab,0x6accfc0b),LL(0x775f693f,0x483bf6a8),L_(0x829c24e8), LL(0x74582da0,0x6731bfc7),LL(0x8e7f87f0,0xf7d39568),LL(0xa67faa6c,0xc9418804),L_(0xf17ae402), + LL(0xb5eb4f29,0x7a12fe1e),LL(0x862fd52c,0x4a7fc70e),LL(0xd820b6bc,0x319719c3),L_(0x06ce9593), LL(0xbd26f429,0x66648099),LL(0xb9a6a586,0xb662d062),LL(0x7fbe15d7,0xf16d93b4),L_(0xab04debd), + LL(0x951453e5,0x8f99c3ae),LL(0x01cc4900,0x422aab2c),LL(0xec8547fb,0x73be771b),L_(0xfba8505c), LL(0x49e82e72,0x7b15c573),LL(0x238927ca,0xaa7e7ca5),LL(0xfd867aa0,0x58e19238),L_(0x16e92a3b), + LL(0x31e49c5d,0x2d0ee2e6),LL(0xe0a95c2b,0x3aaf91fc),LL(0x271cbc87,0xcb833e79),L_(0xcebcb341), LL(0x36952e47,0xf7a6bc06),LL(0xb8a1069c,0xda163496),LL(0x1f6ccb97,0xb5f271bf),L_(0xadf492cf), + LL(0x606962f9,0x82d18205),LL(0x983a462e,0x4a97cf98),LL(0xde06a403,0x23969744),L_(0x5ada65f3), LL(0xba5e083e,0x22229508),LL(0x7b88f442,0x376f004a),LL(0x1c53a79e,0x8ecb5e4a),L_(0xbc00e747), + LL(0xfde8f5b0,0xdaab7a45),LL(0x6896d43d,0x6cba2e3f),LL(0x0b7de7e1,0x31db2861),L_(0xc8a85283), LL(0xf98e6b35,0xa8d3e811),LL(0x9ed4cc65,0xc4961d3a),LL(0x4bad9114,0x10d64cdd),L_(0x6febb44a), + LL(0xadd9fbd1,0xca3624bb),LL(0x6bfd7f49,0x73a43aec),LL(0x91301b03,0xc382f632),L_(0xe009202a), LL(0x83cfde00,0xf9e8d9a9),LL(0x03cf587c,0xb9fbd92f),LL(0x25a8b014,0x760229d4),L_(0x62d554e5), + LL(0x95ce63b9,0x225d1531),LL(0xe0e28f19,0xf1862d71),LL(0x143d1930,0x89faba0c),L_(0x3d640e67), LL(0x36978269,0x2f3bfacc),LL(0xb38209aa,0x8ecd6947),LL(0x817ba1fc,0xad14a0f1),L_(0x53f8ce9d), + LL(0x9cf6404c,0x0fcc7993),LL(0x455cb661,0x94227ce7),LL(0x36c49b8b,0x1add1a97),L_(0xb4a122ea), LL(0xddf10443,0x478ddbe9),LL(0xd7d28b55,0x598d307a),LL(0xa7d77b58,0x7c2d4285),L_(0xf914cdbb), + LL(0x6ae40efc,0x7296f54f),LL(0x267136bd,0xbb8c6473),LL(0xa3248f4d,0x096d9531),L_(0x9bf47d4a), LL(0x72de2ce7,0x71d14af5),LL(0xe31fd133,0x8bb3132e),LL(0xd5a9918e,0x1ee08068),L_(0x4ad2e489), + LL(0x3a3e84c5,0xdb4c764e),LL(0xc0cdb80f,0x06967d90),LL(0x9a2fe8e7,0x3d0cd72c),L_(0x8105ce51), LL(0x663d93ac,0xd9a81336),LL(0xc772e40c,0xe092d50f),LL(0x7d2f5c90,0x45eb443a),L_(0x7ebd73b6), + LL(0x29b44f03,0x09859196),LL(0xd120b82e,0x274e7581),LL(0x8a9337d3,0xe9cba9ed),L_(0xb7d3254c), LL(0xab1d6ae2,0x1aa44fa6),LL(0xa2bcdd85,0x8201c08a),LL(0x2f9c1703,0xd128d342),L_(0xcf87815f), + LL(0x04dbb489,0x4b130afb),LL(0x8592bf1f,0x010d7b25),LL(0xf211bcec,0xb7f03740),L_(0x2070aa40), LL(0x24a2aec7,0xf116e286),LL(0x3a91fedf,0x4b6af9fa),LL(0x974e5b38,0x19cbf327),L_(0x0cab111f), + LL(0x8816e066,0x52f1347b),LL(0x0dbd4053,0x733b5b5e),LL(0xe33961b0,0x8db340e4),L_(0xc28fe0e4), LL(0x8fdad9c7,0xb3cc8f09),LL(0x66c9d4cd,0x36371a81),LL(0x36432409,0x9dd5d017),L_(0xfd34cf28), + LL(0xc45e9f49,0xce25491e),LL(0x464328d6,0xf8ea793b),LL(0x27eb6c22,0x6371b206),L_(0xc53f6320), LL(0x80e32e79,0x61eaf6df),LL(0x3ece8680,0xdc4f44ca),LL(0x387b7804,0x4b85bf6e),L_(0x4e286cd6), + LL(0x2c7dc475,0x18a6a123),LL(0x87751313,0x53665bc9),LL(0xaa43dbfb,0x8d40fe26),L_(0xe4bce37a), LL(0x6723ea8f,0xbade3e08),LL(0x4b0254d2,0xc7adbb73),LL(0x2f3a4dc9,0xa74a2565),L_(0x829b9555), + LL(0x9ab672f0,0x9cc7bfa2),LL(0x1fad100a,0x2ac7eb07),LL(0x368be66e,0x5665ccf4),L_(0x8056fdf1), LL(0xb250a7ac,0x465d7f98),LL(0x64180c0c,0x8d2b97aa),LL(0x7b979097,0xa50d476d),L_(0x45ad85c0), + LL(0x8b68fb1b,0x542fb7f1),LL(0xf8fc7eb8,0xd96b7a33),LL(0xb020cf53,0xdb72531d),L_(0xb4c510b9), LL(0xc73ecdcc,0x1c4cd34a),LL(0x272dd7b1,0x039494e8),LL(0xd23f79c7,0xa21edcfd),L_(0x207ff37a), + LL(0x17c4dc72,0x5ce9dcb0),LL(0x6a5e2d85,0x25936d77),LL(0xebe08b04,0x70fc7789),L_(0x7b6f8a3a), LL(0x7f3546f5,0x7563a201),LL(0xea8da605,0x10bfdb1f),LL(0xdb570af0,0xeb5d3434),L_(0xdadec2da), + LL(0xef345021,0xd0e87d76),LL(0x2945a207,0x222e0b0f),LL(0xe86e0a88,0x6fa3b5c9),L_(0xef9f7939), LL(0x9da8796b,0xabdf6b2a),LL(0x90ef27c9,0x7ead1795),LL(0xbbc76905,0x8c71560c),L_(0xbef19370), + LL(0x890d8ce2,0xb5cc05b2),LL(0xa7bd2aa7,0x7de1e29a),LL(0x866cd575,0xfc749a26),L_(0x825af3b3), LL(0x7eaa0bb6,0x886271b4),LL(0x6514a9d4,0xed069b45),LL(0x65bd26ca,0x2f59240d),L_(0xbe13ff4a), + LL(0xd9546220,0xcbae178c),LL(0x2cf4cc42,0xe71c4857),LL(0x70950b7d,0xc8f7ab52),L_(0xb20e351c), LL(0x52a1a22e,0x24d86b6f),LL(0xe4b84f76,0x70b94a08),LL(0xd450bfb1,0x0d983cdd),L_(0x3f21b37f), + LL(0x5619c34b,0x77d8a74f),LL(0x86215aa3,0x71f4dc88),LL(0xfa0612da,0xb127ccb2),L_(0xc1906699), LL(0x879fb160,0x205b4589),LL(0x2af7eaab,0xe8b6c8f4),LL(0xaad791a8,0x1490d5ca),L_(0x3359b830), + LL(0x32c5bb90,0x28810885),LL(0xdd3a45f9,0x2ceffdfe),LL(0x14a9a0ad,0x7970ea64),L_(0xe4fdf446), LL(0x8708e80b,0xbbf83ccb),LL(0x1b1d1037,0x5cc8baac),LL(0x800c8eba,0x98c8b359),L_(0x3ee963ee), + LL(0x22c84665,0xdbd93971),LL(0x284c33c2,0x697a6de7),LL(0x6f50eaa6,0x87cb9042),L_(0x70efc303), LL(0x5f70b39e,0x2af4f24a),LL(0x562e2f64,0xd8a16a0e),LL(0x8f4571e4,0xa7b9ed81),L_(0x6ceb56cb), + LL(0x6e1de981,0x725de358),LL(0x04ebe2bd,0x85652ca3),LL(0x50b9f863,0xd5f0033d),L_(0x0b13ec3a), LL(0x19c015bc,0x948391b7),LL(0xc37027bf,0xaf6e5ed5),LL(0x33c66538,0x96bfa703),L_(0xced15639), + LL(0x069d03c1,0x47f60293),LL(0x73dccc53,0xc32780f6),LL(0x3bfeba8e,0xc2e0eb4e),L_(0x546bd56a), LL(0x29bd4113,0xc233f03a),LL(0x277aca24,0x574da3b6),LL(0xf4f6a7ac,0xae0e0260),L_(0xbade476b), + LL(0xbb8f2925,0x5a087018),LL(0x5c2bab18,0x8c5485dc),LL(0x351ad0f1,0xf7d7679e),L_(0xe930bcd6), LL(0x2bdc4897,0x277bcf81),LL(0xbcb4ffd9,0xf147c5b3),LL(0x87185cc7,0xdf48c9e6),L_(0xce71b122), + LL(0xdb75cc10,0x17222dc7),LL(0x3bc7295c,0x3dd256a0),LL(0x3a012a3b,0x7ec5696a),L_(0xe6950145), LL(0x9381bed6,0x4f4cdfd3),LL(0x353d2f83,0x7b5b13a3),LL(0xbf5f2e84,0x2639cce3),L_(0xda40d3a1), + LL(0xdb334a59,0x6da64943),LL(0xd3f151b5,0xfce96a35),LL(0x6ad5dfad,0xa599a89e),L_(0x0d1b7f52), LL(0xeddc6626,0x2ef746d1),LL(0x861341ad,0xa912c3ef),LL(0xd6859ab6,0x1ac3aba5),L_(0xd95ca5f2), + LL(0x0e5c7c8d,0xb050ceeb),LL(0xcf83afd0,0x53e4bd2e),LL(0x710688b3,0x19a215e7),L_(0x8fa6f937), LL(0x9a042c9a,0xd22cc140),LL(0xa2947f4b,0xb5f7e2eb),LL(0x7f1f59f8,0x154453dd),L_(0x4db7a4d6), + LL(0x9473341c,0x9f33393e),LL(0x75ea0e37,0xb3dc51a3),LL(0x09fb2116,0x0ee5b84f),L_(0x3fcab420), LL(0xf91ac676,0x816d6ca6),LL(0x8f078e9d,0xc0c5edee),LL(0x0cfcd5ed,0xb71c05e5),L_(0xc167eb60), + LL(0x17c9bd2b,0x4c0897b1),LL(0x145b24db,0x7a16a169),LL(0x0f41e0dd,0xa88a35f1),L_(0xbff8660b), LL(0x5e5fc719,0x85b8baf5),LL(0x2e4db4f9,0xd33b70cd),LL(0x5dd4f3b8,0x5ddf49c1),L_(0xbfc827f1), + LL(0x795a3893,0xedb3e7f2),LL(0x6cad1ecf,0x33c80574),LL(0x26818153,0xf7414144),L_(0xff6a4325), LL(0x6f311ca1,0x24d6e452),LL(0x7d6669d2,0xe7193165),LL(0x66d1a963,0x89fa62a1),L_(0x6bc282cf), + LL(0x375aa47d,0x70c638b9),LL(0x4fe2ddd6,0xf167acbd),LL(0xddf9d01a,0x364bf41a),L_(0x70510fe0), LL(0x7d82f66d,0x8862080b),LL(0xe66e70a2,0x0448ac9c),LL(0x4dbdd638,0x971eaebd),L_(0x07449c55), + LL(0x30f6e054,0x4b4739f2),LL(0x55ce7718,0xd62b9aef),LL(0x3bbafe26,0xb84b80ac),L_(0x52aa54d6), LL(0xd03fc3fe,0xb6803cd9),LL(0xaf2b1562,0x81afcd95),LL(0x205a14b1,0x7a0ade0e),L_(0x371096d5), + LL(0x2d735064,0x4b1c54dd),LL(0xaad4a4b1,0xda4629d6),LL(0xe95c14ae,0x6f216326),L_(0x00affaf4), LL(0x2fae20c7,0x3112101e),LL(0xd2f76d99,0xbce52747),LL(0xfcd465ea,0x53fd0b9b),L_(0x8b45a470), + LL(0x068c0d93,0x1f9856a8),LL(0x6517f94c,0x3408da23),LL(0xc9b9b412,0xc63b4cb7),L_(0xd2b6eaad), LL(0xb7836b3a,0x200fd925),LL(0xa850f3d2,0x55a6ddef),LL(0x2b7f407e,0x0fb2a9d1),L_(0x8b4cf8a0), + LL(0xe36962f6,0xfae22eee),LL(0xb2671435,0xfe866c3d),LL(0x8acadf81,0xa3f599f7),L_(0x57dbb976), LL(0xe8b6b61f,0xb4b13551),LL(0x14a48328,0xcdd8f22e),LL(0xb9099888,0xe1b8ed2e),L_(0x322f8929), + LL(0x7e8f146f,0x3818b39f),LL(0xacd7c7b4,0x16886904),LL(0xf677bde6,0x022ae138),L_(0x9ffae2cf), LL(0x5746a459,0xacf62d52),LL(0x09ae59c0,0x63279bc6),LL(0x4ee46705,0xfd285b9c),L_(0x674ba2e7), +}, +/* digit=23 base_pwr=2^161 */ +{ + LL(0xbad78997,0xc931bee3),LL(0x0c15f2e2,0xe3c1a2d8),LL(0x7cd507de,0x58fc32e1),L_(0x0f28ff52), LL(0x01135f60,0xfb8b7b35),LL(0x11406d6a,0x413750b4),LL(0x2dffb3fe,0x6a265953),L_(0x7c1dd63a), + LL(0x796bb2b0,0x56c1932c),LL(0x09ceb738,0xf443c29c),LL(0x6ff56bc3,0xbdd22bb5),L_(0x7387fcf2), LL(0x21178548,0x22575d25),LL(0x534ca838,0x7ffb29d7),LL(0x4ffc71d3,0xd6ef14c3),L_(0x6a7a8abe), + LL(0xbc9613ac,0x5920119c),LL(0x6ae141df,0xc3d2b2e1),LL(0x9633ba13,0xe7d31665),L_(0xc56ddd74), LL(0xe622933d,0xec5df7bb),LL(0x641e9e6c,0x50f7f156),LL(0x7feb42b1,0xeb17ef8e),L_(0x36a1400c), + LL(0x1a087220,0xeeddf997),LL(0xe4cee644,0xb6ad5609),LL(0x3c761d64,0x52dd9f57),L_(0xda46466e), LL(0x39b5966f,0xca15f167),LL(0x16fee018,0xea78b847),LL(0xd9642afb,0x37eea476),L_(0x3f286088), + LL(0xda4b72e6,0xa3072640),LL(0x3e38a59d,0x36a057e0),LL(0x4754e3c5,0x4faa9820),L_(0x2a8a9f0f), LL(0xf20160be,0xa80ee38d),LL(0x5f711700,0xc8e173dc),LL(0x665dbf2e,0x2aba1be0),L_(0x187969d1), + LL(0x228ed7aa,0x2d501abf),LL(0x1434af6f,0xe4f5d2f6),LL(0x3dad807b,0x0b4aa28f),L_(0x49171ad5), LL(0xe672b220,0x0888b653),LL(0x61b8ab73,0xa3e477ad),LL(0x226f83cd,0x0afdcedc),L_(0xff93b3f1), + LL(0xe7476655,0x562eb536),LL(0x4facc94b,0x7f5bedc0),LL(0x2887f756,0x8581b7e9),L_(0x2a5e0a2d), LL(0x160c3505,0xdde60b62),LL(0xa03cc7a8,0x8a8ca29a),LL(0xb94770da,0x3ecfeca1),L_(0x667902dc), + LL(0xb615d5a8,0x8ea9ecfb),LL(0x55508319,0x6be624fd),LL(0x7f81ee5d,0x45035a93),L_(0xd73caa36), LL(0xc3d23101,0xe9c562fc),LL(0xd42e053f,0xf451c229),LL(0x6ee17a32,0x932ddcfa),L_(0x689ee05b), + LL(0x6337e909,0xe970ce2d),LL(0x7dae8ee6,0x58d5ae88),LL(0x253afb1a,0x88db9fe4),L_(0x05ed8360), LL(0x3d74de44,0xa90b033e),LL(0x8c323484,0x132dd86b),LL(0xed163aa4,0xc88fa0d9),L_(0xbaaf76b3), + LL(0xa0e34d4c,0xa5b69894),LL(0x8d09f343,0x495e2cc1),LL(0x987653cd,0x5e895b41),L_(0x0dbb4714), LL(0xf289cc21,0xc41882ef),LL(0x5fe6817a,0x3329b3be),LL(0x4acf73b8,0x9efd2db0),L_(0x0d02e7dc), + LL(0xdd8e91bb,0xf8f6f870),LL(0xc680bcc6,0x728bf4b4),LL(0x93d4067d,0xb9c4891b),L_(0xc44a0438), LL(0xf8bf9b96,0x1e5e8506),LL(0x8e6af7aa,0x11821ebf),LL(0x99083ad2,0x7e9d0c84),L_(0x510d6d87), + LL(0x85547391,0x48ab6926),LL(0x4bca1962,0x1badb306),LL(0xdd5f7613,0x4641e82a),L_(0x7c23013e), LL(0x3d43a297,0x58c32dfb),LL(0x706e6ac2,0x3ffcd8f7),LL(0xc250c17a,0xfacc3394),L_(0x0ac00a9f), + LL(0x99456e77,0xe9a40562),LL(0x762b34e5,0xa165351f),LL(0xd0dd1798,0xbabb6293),L_(0x257af82c), LL(0xb83a079b,0xa5cd33ea),LL(0xac07759a,0xf120f050),LL(0x6109e625,0x774354d8),L_(0x7ac23484), + LL(0x8d82b0bd,0xbafdf31f),LL(0xfd4e66c0,0x7639e997),LL(0xd2a8308f,0x3be638b1),L_(0xeb3d8386), LL(0x54bc114f,0xeb650088),LL(0x97a2e01d,0xebdef489),LL(0x902bb33d,0xc3e46171),L_(0x3a181f63), + LL(0xc86362a6,0x56cc1bef),LL(0x13e720d5,0x3b4b4fc8),LL(0xf9436f6d,0x370a01fd),L_(0xba6eeefa), LL(0x632c516e,0x916aa8c7),LL(0x571c4cd2,0xe3ad18e9),LL(0xe18b971a,0x72c7e5a4),L_(0x570527c5), + LL(0xb48396a0,0xf8cf3d39),LL(0x6ad6e8f2,0x1d89563e),LL(0xa602a006,0x91cd1395),L_(0x64fa2f77), LL(0xdbdaa433,0x0966d0a9),LL(0x8e0abebb,0x166bebe0),LL(0xf1b4da0f,0x433f9113),L_(0x8e2b6532), + LL(0x6fb1d5da,0xd89da757),LL(0x89f048e8,0x2939bdac),LL(0xa42134e8,0x6b13fefc),L_(0x792be7f3), LL(0xb37f662f,0x413f92df),LL(0x08daa37a,0x985c742a),LL(0x1de586e7,0x5f4904de),L_(0xe4507309), + LL(0x03906d92,0xb13c4090),LL(0x9f0f4106,0xf3affee5),LL(0x6830a295,0xb7fc1017),L_(0xfe0d1565), LL(0x45d24eb7,0xcb2d95c2),LL(0x02c21f5f,0x8c20bcd3),LL(0x3379e3da,0x6dc4634a),L_(0x5f5ffa94), + LL(0xaefdff78,0x97e82574),LL(0x2379777c,0x112d1838),LL(0x20061ca4,0x0060cd67),L_(0xc1751f60), LL(0x11499a1f,0x8b6913cb),LL(0x3ca5f64c,0x67ff5e86),LL(0x1680aa3a,0xe823c3ec),L_(0xdf7da52e), + LL(0xd3ac8a56,0xd2b4232a),LL(0xcd8aee6e,0x1b8abf52),LL(0x2fcb86b4,0x19bc7365),L_(0x2952fde9), LL(0xa051bf9a,0x1aec4d94),LL(0x79b4a51e,0xfbc4f986),LL(0xa954ceb9,0x05b104cc),L_(0xe0d3602f), + LL(0x40690897,0x4799ff54),LL(0x87dac4d0,0xbc95c209),LL(0xc0b5b3de,0x290686c2),L_(0xb3329cbb), LL(0xca443d1e,0x6b65747b),LL(0xcac2d9da,0xf2987b71),LL(0xf039026d,0xb9b37c0a),L_(0xb77496d3), + LL(0xd360d773,0xd81505e8),LL(0x271af0ca,0x40816745),LL(0xc9836e31,0x9dca53d3),L_(0x7227191a), LL(0xd820c040,0xb45d3f5d),LL(0x3bbb6420,0xedf3a3c8),LL(0xe0ce5e44,0x459a2236),L_(0xf815d523), + LL(0x35ffc3c2,0x273c8e42),LL(0xdda15d58,0xfecec30c),LL(0xda6a8389,0x8e8dc1c3),L_(0xc0bf1e23), LL(0x6fe132fe,0xc3565543),LL(0x707a3332,0x951334fa),LL(0x770ed88f,0x4d1d476c),L_(0x180fa694), + LL(0x20e67928,0x488e81fb),LL(0xd3aa63c5,0xd968afb3),LL(0xb0057d32,0xb8d04c1b),L_(0xabd57ea4), LL(0xee01ab83,0xef38d717),LL(0xe3ff770c,0x830deae9),LL(0xfba87128,0xbf20a3cb),L_(0x7a5792cc), + LL(0x15750d84,0x8d8facef),LL(0xec118062,0xef0f3af0),LL(0xd1a4206b,0x64ebf883),L_(0x6101aba7), LL(0x5b6d2c3c,0x3c48ef20),LL(0x2cb3a5ff,0x153580c5),LL(0x534ba912,0xa02f889c),L_(0xa1a92663), + LL(0x1f2a638e,0xcb233fe2),LL(0xd1e29224,0x792d0dff),LL(0x62d03b08,0xd6646af8),L_(0xcb6267fc), LL(0x4a8172cd,0x82199f97),LL(0x582165ca,0xf879213b),LL(0x8048de29,0x51bdf94f),L_(0xe7f10d0b), + LL(0x75f12d76,0x743c75d7),LL(0x4777a4a1,0xc13528c2),LL(0x0f8f0fc7,0x969b010e),L_(0x6365c47c), LL(0x2acbaab1,0xdfc6ee9c),LL(0xe207ebae,0x23ac352f),LL(0xc00ef611,0xdfc77ba6),L_(0x6470bbbe), + LL(0xd561d67a,0xac256d68),LL(0xbe1d04c9,0xb7f44d83),LL(0x1d8cc6f2,0xddd4acc6),L_(0xc01e2b00), LL(0x83d18ef1,0x6b5fbe51),LL(0xc673b3a0,0xe616da91),LL(0x04e7aef1,0x7079d8b4),L_(0x3313c1b4), + LL(0xc0f7d6a0,0x2242759d),LL(0xb6fbfcb4,0x9949d06a),LL(0xde898701,0x8b24618f),L_(0x5307474d), LL(0x3976254e,0xb0bd22ab),LL(0x211085ed,0x2125ed2b),LL(0xa5f28d83,0xa1c543ea),L_(0x565a6c4d), + LL(0xe7ee1b29,0xf2a06317),LL(0x3813d14f,0x784961c1),LL(0xf759d96d,0x5670b8e7),L_(0xb428b1ab), LL(0xafedb09a,0x8fbfe519),LL(0x478f19a0,0x7246a169),LL(0x7503e23c,0x23ac9af3),L_(0xd24790e7), + LL(0x87836e62,0xc31169c7),LL(0xbcb98921,0x111050a3),LL(0xa7810165,0x446bda32),L_(0x6ad438a4), LL(0xa876bcf9,0x32692fd4),LL(0xc750819f,0xd11e3c6e),LL(0xe2aece33,0xd325fefc),L_(0xb6f2bf6f), + LL(0x8c31bbfa,0x0e3623bf),LL(0xa2285b20,0xbb5c266c),LL(0xc5f4aaef,0xa7179b54),L_(0xdf6212eb), LL(0xed087187,0x375cb291),LL(0xd118abf6,0x047af635),LL(0x73198d27,0x8f1c0b06),L_(0xeac7c4ea), + LL(0x77e38348,0xc22c3ac3),LL(0xd0ae073a,0xea1c7779),LL(0xab8de890,0x8b9d1132),L_(0xb336a43c), LL(0x2a2fde97,0x78f20c5e),LL(0xf71fbefe,0xa11f0040),LL(0x302a6212,0xba7689dc),L_(0x6a6519f6), + LL(0x8c2d9e20,0x50cda9df),LL(0xb3180610,0xa6158df8),LL(0xadbbeaa9,0x4778c93d),L_(0xc891e9d3), LL(0xd1a49e0a,0x6eb6664c),LL(0x68d58278,0xb72ac28b),LL(0xb8fb2671,0xfc493918),L_(0xbe9a2c58), + LL(0xe846a0c4,0xc3ffb873),LL(0xf33f7123,0xd98b14c6),LL(0xcd3fcccf,0xec8c8522),L_(0xc0d09a5d), LL(0x2709309a,0xc435552e),LL(0x393794e6,0x731b5ca4),LL(0x6d3545bb,0xcf95c612),L_(0x21f92c49), + LL(0x67e83945,0x77e47a85),LL(0x8aaaa2f8,0x41b4a73b),LL(0xf14ab27f,0x45673153),L_(0xf95ee4e1), LL(0x29737736,0x3a31ee99),LL(0x3add55e3,0x89cb9a71),LL(0x3c610ccb,0x92d6ab9e),L_(0xa1df471f), + LL(0x24dd0313,0xfe3af3cf),LL(0x3ad69446,0x1fa695ef),LL(0x49e9da9d,0x35d8485e),L_(0x823de577), LL(0x1be78d4e,0x9a8e5ede),LL(0x535233c3,0xdb4e20a2),LL(0xb9902b0e,0x762073cc),L_(0xb355fbea), + LL(0xba8c73ac,0xfd983b8b),LL(0x0f082d41,0x3921c9f7),LL(0x9c6ee5d8,0x7f5a5177),L_(0xd9ef6090), LL(0xab53e7b3,0x7db07019),LL(0x14b4f4d5,0x01f9a8fb),LL(0x2588492a,0x9ea1e98d),L_(0xeb443742), + LL(0x31997789,0xa9a0407f),LL(0x4e820720,0x26fdd725),LL(0xa3068d9c,0x2aba0c14),L_(0x6db14c6a), LL(0x6d072830,0x2d5ed5c3),LL(0x0acce5d9,0x52b3241d),LL(0xdbd63903,0x11f4b8bc),L_(0x04c731fa), + LL(0x35994c38,0xccc2b918),LL(0xbc10285b,0xf27570ca),LL(0x870c688b,0x8c91a8af),L_(0x775fff54), LL(0x5459f2f6,0x9157cd7c),LL(0xc2e98dfc,0x021d9844),LL(0xdbbbf2c4,0x3319b3fc),L_(0xba743dee), + LL(0xaeba325f,0xaecdc264),LL(0xf477eda2,0x9b24587e),LL(0x859c1b6a,0xf7648c83),L_(0xb5c8f8dc), LL(0x7005a3f4,0xdf465967),LL(0x10b24908,0x2411ca0d),LL(0xd689abfe,0x1452c503),L_(0x625ecb92), + LL(0xcc290bf4,0xf34968d7),LL(0x9003a913,0x7228d7c0),LL(0x48e02e21,0x17e25b2b),L_(0xd5f95bbb), LL(0xa53a154c,0x1035d2b6),LL(0xac56a6bf,0xe8ab36c5),LL(0xbcf0eb3e,0x63fa883e),L_(0xdf08d138), + LL(0x0b53b1ce,0x2088982f),LL(0xe8ed9994,0x21364c97),LL(0x45bf87a7,0xeeb978c5),L_(0x5b94bef4), LL(0x4e53377c,0x093e9c15),LL(0x58acb871,0xd8249f4f),LL(0x02b46436,0x64f236ee),L_(0x88a9e12f), + LL(0x3940ee67,0x6164d05e),LL(0xf4a7c705,0xb0056da2),LL(0x872642d0,0xa7bd3d66),L_(0xa407f0cd), LL(0xce37f407,0xd8371363),LL(0x592b0f71,0x90362154),LL(0x009ca301,0xe59d0b2d),L_(0x3dd8f9c6), + LL(0xcf247be0,0x73b26b51),LL(0x31ef23aa,0xdf33ad4d),LL(0x1f6d55bd,0x4ed64955),L_(0x7ed356bb), LL(0xa18aee16,0x8ca23082),LL(0x82214ca5,0x20da76f8),LL(0x2453f147,0x4606958c),L_(0x3b5ee2c3), + LL(0x99950739,0x06b63065),LL(0xb845a47f,0x9853453b),LL(0x88e04e19,0x456e72cc),L_(0x05cfd664), LL(0xb168037c,0xd3c22f8d),LL(0xcaf525d3,0xd989f0f6),LL(0x9699fc87,0x273ac5b1),L_(0x0349e937), + LL(0x273a933e,0x24f52dc3),LL(0x825de5df,0x36bc3c34),LL(0x3e91b0cc,0x61de4790),L_(0x7a99b424), LL(0x8f4b678a,0x44bdcadc),LL(0x0a060400,0x830bedee),LL(0xbb9ac7e8,0xbda5fd11),L_(0xa71c4ee0), + LL(0x37a97135,0x079c1b7a),LL(0xac1ea75a,0xeaf11508),LL(0x3012e200,0x61b63246),L_(0xbb79e1c3), LL(0xc0246bd9,0xb92f89e2),LL(0x95a4a7cf,0x3fff4a96),LL(0x44cf1045,0x6e70ae3f),L_(0x5783bd56), + LL(0x6615d343,0xb3a83dd9),LL(0x5e8bc7ab,0x0c4c00f6),LL(0x6cbcc29c,0x84d9fe95),L_(0xaf97e676), LL(0x30e1885c,0x82a4da98),LL(0xbe563af0,0xbcc23ab6),LL(0x259db6ce,0x306cf56e),L_(0xa179a030), + LL(0x08624c7c,0x32c9c5fc),LL(0x37d48ba3,0x38295bfa),LL(0xfb49c594,0xdcfe3634),L_(0xc9dd0809), LL(0x832aec93,0xe5cda111),LL(0xebcbf38d,0x98fc1727),LL(0xac496bac,0x3f057842),L_(0xefc69a01), + LL(0x7bdd13e8,0x189dee30),LL(0xc45d637e,0x01cf6015),LL(0x02a07254,0x7f6053e7),L_(0x9648ef85), LL(0xc9d79b49,0xd467929d),LL(0x221a964d,0x2a4257b0),LL(0x3ed68c3c,0x0209a951),L_(0xbf635477), + LL(0xb50fa3a9,0x568377b7),LL(0x57a50eda,0x992fa9d6),LL(0xf3995e07,0xf09351e3),L_(0x21813534), LL(0xde00386d,0x7c21c039),LL(0x5bd67bbb,0x983e3f5f),LL(0x970f1581,0xfde7bb8d),L_(0x50e663c0), + LL(0xa5991d36,0x727713ca),LL(0x52a00363,0x81781a15),LL(0x946557d9,0x8b2de3fc),L_(0xce2f349c), LL(0xb61c0936,0xefe6ec67),LL(0x9c584327,0x0483381f),LL(0xbfd4710c,0x3cb8617a),L_(0x2e9c6a8a), + LL(0xfb2c55b7,0x83398c47),LL(0x00610b5b,0xfc55bdd9),LL(0xd6aad463,0x733b8806),L_(0xe6434da6), LL(0x600c9641,0x72a69c3e),LL(0xc959c3b6,0x25c8da00),LL(0xa863f55c,0x6b73f445),L_(0xb25ba2b8), + LL(0xb5811bfc,0xdea6b1b8),LL(0xc85bb876,0x6f29d6aa),LL(0x244c832f,0xb885707b),L_(0x700946f8), LL(0x19847d9e,0xbb7684f6),LL(0xf1284753,0xc0f2d53b),LL(0x20ef5736,0x9e06880d),L_(0x94cf829c), + LL(0x9a3cdc82,0x6fd2d1fe),LL(0xf6676bfc,0xfe48b29e),LL(0xa14e785b,0x7afeb3e3),L_(0x73a22b1e), LL(0x15c1eec0,0xdc5c271b),LL(0x738c09b5,0xd51bbdf3),LL(0x4095982d,0xea6a656f),L_(0x4e8a1c04), + LL(0x8df3827f,0xad96082c),LL(0xe21e88ec,0x0c7308d3),LL(0x747332eb,0x3e790568),L_(0xcbe74f24), LL(0xb410e2a6,0xa45bcc07),LL(0x62e28f16,0x34e11697),LL(0x68990fab,0xd0d95f71),L_(0x0bc4045b), + LL(0x2b70f4c3,0x95663747),LL(0x718a4989,0x18e76685),LL(0x0510d4ae,0xa806fc64),L_(0xb9f7725e), LL(0x74a39c46,0x11681c31),LL(0xab7986bb,0x7f1ee73d),LL(0xd70c5b25,0x145296c5),L_(0x8e746d97), + LL(0xb90e977d,0xa73e17c7),LL(0x914b838f,0x3b0459a9),LL(0xd910c80d,0x4a996387),L_(0xc7523409), LL(0x09cc1463,0x4ff007ad),LL(0x3feccef8,0x6f3bf601),LL(0x9137e94d,0x3d0461a8),L_(0x5dfeb98d), + LL(0xdf5e90f7,0x03f3fdc3),LL(0x3d7cbec2,0x2f05f4ba),LL(0xefe1e30f,0x5dab20a6),L_(0xb6114a8c), LL(0xfbe83a6b,0x815eac18),LL(0xbcc8bbc2,0x2c89a659),LL(0x13f75b6a,0x326a87f4),L_(0xda0c7f42), + LL(0x99fa6315,0x29c19e9b),LL(0xdf48509e,0x5d5a6ffa),LL(0x84d62c60,0x4e8640e3),L_(0x4a85f9d6), LL(0x01830a3f,0xa50855ff),LL(0xea7061d4,0xb9b3fb5a),LL(0xbf0727b4,0xa1cac932),L_(0x9c76f2b9), + LL(0x08fe3e55,0x7f8ba9f8),LL(0x3a13632e,0xfff3b260),LL(0xa621223a,0xda5b8cc0),L_(0x6cf87377), LL(0xb352cab0,0x52e875c5),LL(0xb3cb3de2,0x888687ca),LL(0xd159fefe,0x788f0705),L_(0xa3f5461f), + LL(0xe7ee73d4,0x71f9e278),LL(0xa10ec3f4,0x0511bea2),LL(0x147b2ef8,0x908389b2),L_(0xaf59635c), LL(0xb9505162,0x7ab5b1bb),LL(0x05d9bd3a,0xa16a5843),LL(0xeb15fb80,0x8840233d),L_(0xf2f61b05), + LL(0xfbf89124,0xb350235f),LL(0xa7d12321,0x601ae7a3),LL(0x487a5b44,0x168cfefc),L_(0x124de1e6), LL(0x27f1099a,0x3f7f4917),LL(0x387a3135,0x576cbe65),LL(0x93695572,0x1697b707),L_(0xe9cd239f), +}, +/* digit=24 base_pwr=2^168 */ +{ + LL(0x1aa93495,0x07822bd8),LL(0x98675e63,0x690a044f),LL(0x411c39e9,0xddfd5a23),L_(0x768594da), LL(0x5d8da0b0,0x74dcec38),LL(0x3c14e211,0xa51c46ee),LL(0x6b77f2b0,0x1367898a),L_(0x8ad0bfdf), + LL(0xd8b1efbb,0x5d75e9ca),LL(0x940ae4e4,0xdea9f60e),LL(0x7af3d6fd,0x95065ae4),L_(0xef0f21e7), LL(0xe0c7e801,0x22ced186),LL(0x9502622d,0xc6698d7e),LL(0x95367fa5,0x9310a67e),L_(0xc864dc25), + LL(0x7322a3b3,0x1b5b3f21),LL(0xe6b25a83,0x1fe6e87a),LL(0xcad2ee21,0xb5fd4e5b),L_(0xd772c552), LL(0xe5ae89d5,0xc2853eeb),LL(0xc45afb20,0x9036d2cf),LL(0xcb159584,0x45627827),L_(0x6e07de7e), + LL(0xf341190a,0x2470f5ee),LL(0x87e42cc7,0xf0be84fe),LL(0xade34d2c,0x90636c20),L_(0x0cf8cafa), LL(0x180fa04d,0x2db09b0f),LL(0xd896b5d9,0x0a0909a9),LL(0x83bcc559,0x281cf9aa),L_(0x4d7d88c9), + LL(0x38d6fee1,0x8f859667),LL(0x0e93537c,0x86559609),LL(0xca6e59bf,0x6854b4e8),L_(0x4c2e89d8), LL(0x23a24b88,0x5840ce8a),LL(0x6366e9c0,0x946b6bbc),LL(0x00fd3d85,0x8a095b45),L_(0x9e0c589e), + LL(0x74d544f2,0x4c355669),LL(0x4696a73a,0x1ea60e81),LL(0x099e116c,0xd960a70d),L_(0xea914344), LL(0xd60a4a5a,0x305faf07),LL(0x1026dbdc,0x61b80d24),LL(0xe6b8e5c2,0xd428e0cc),L_(0x2cd02a61), + LL(0x26d21296,0x5d2ed352),LL(0xf7a07ac1,0x3daf91ed),LL(0x44afa3c4,0xd529e7b2),L_(0xdd22a012), LL(0xd7ed0b48,0xcc9faccf),LL(0x00535729,0xc98aa7de),LL(0xc9757998,0xce2c4e14),L_(0xe8ccc048), + LL(0x098fc504,0x3d3f8532),LL(0x5cb9d339,0x50253fa0),LL(0x23d266c8,0xb38286d6),L_(0xe5172f5c), LL(0x99903093,0x48a64b98),LL(0x8c64987d,0xbc43643a),LL(0xfe159bd8,0x2f08eae4),L_(0x049c111f), + LL(0x5b31f9b7,0xc558d554),LL(0x0d2340eb,0xe3c46403),LL(0x19a6f592,0x2211131c),L_(0x4ef1dc2e), LL(0x4d8f19e8,0x8c4d4f34),LL(0x107caba4,0x347e8cae),LL(0xad36aa89,0x5a959e3c),L_(0x4495ae4a), + LL(0x178db2de,0x8674b5e1),LL(0x68e6ec47,0xce21dcf1),LL(0xd3884f45,0x7664513a),L_(0x60d36975), LL(0x7a1b3e57,0xc9e299e2),LL(0x8015c45b,0xe96de0f0),LL(0x8d3f0ffc,0x5aba434e),L_(0x448fc469), + LL(0x3206b5a0,0xbf15b53c),LL(0x0516d5b4,0x2fff52c6),LL(0xfec55940,0xc3791f65),L_(0x797a6b95), LL(0x394de0c2,0x5c5fed8c),LL(0xeba16248,0x674b4d58),LL(0x0e57743b,0xd7315975),L_(0x87252f57), + LL(0x7fa4f80b,0xc574aafe),LL(0x9e9fc1b3,0x25994c44),LL(0x15293405,0xa00f9231),L_(0xc2527f9a), LL(0xf98edea6,0xd0bcf974),LL(0xbe7b43fa,0xa3c74ad5),LL(0x448873ac,0x8ff67b2d),L_(0xf0dfe6da), + LL(0x510cb9a5,0xbaf15c58),LL(0xcabedab3,0x234a8faa),LL(0x0023d4d4,0x9d6e89b9),L_(0x8a188d72), LL(0x37485100,0x6bf4faef),LL(0x5f70a85e,0xdd164001),LL(0x799cb3ee,0xfc7797a7),L_(0xd331f4bd), + LL(0x34261e55,0xcf17aa4d),LL(0x7f8c3542,0x801ccc34),LL(0x0c7a04fa,0x762b3408),L_(0xd90eff09), LL(0x002ca132,0x0870f41d),LL(0x767451ee,0x70686201),LL(0x276eaa26,0xf592842e),L_(0x6a87509c), + LL(0xb78b71bd,0xa79ca9e4),LL(0x31d15ca5,0xe7aab4c3),LL(0x095aa863,0x980df4d9),L_(0x30800a25), LL(0x75ac5ed9,0xcc69d2f9),LL(0xee44fb88,0x429f98f1),LL(0x10ce7510,0x5736d4ee),L_(0x03cc9ae7), + LL(0x8da51d85,0xb2abe419),LL(0xbd89ecd4,0xefa624dc),LL(0xc275c72e,0x8b684df9),L_(0x0c47b707), LL(0x75f1bf6f,0xfc8f823d),LL(0x06225cca,0xa497166b),LL(0xb3363382,0x3241d9b6),L_(0x397d4140), + LL(0x9a65f284,0x47d0d598),LL(0xd2dae790,0x600f8097),LL(0xdfc5d530,0x06c1d340),L_(0x18b74aa7), LL(0x409b596c,0xe50cc47b),LL(0xb9309f95,0x71018c41),LL(0x4f9b2683,0x2de345b4),L_(0x73d97fe3), + LL(0xd352b3da,0xfb7e2c37),LL(0xd29b2279,0xfb5035db),LL(0xc27af22c,0xe5cf5a24),L_(0xdd8c403d), LL(0xf2e49e04,0x31c42940),LL(0xbe767afa,0xb3e476b1),LL(0x3130439d,0x729a7e6b),L_(0xcfb2c6fd), + LL(0x554fbba5,0x1228460b),LL(0xfba91910,0xda7db076),LL(0xf5e0be2b,0x8a989e94),L_(0xd04b5940), LL(0xe15aded2,0x56931b09),LL(0xe96ceb9d,0x7fb6175a),LL(0x36407d3f,0x785ad12c),L_(0x412c5e80), + LL(0x296e5cc5,0x6178d140),LL(0x9e4845c7,0x9088d05a),LL(0x1f9dc468,0x631396d3),L_(0x8b994c1d), LL(0x86ffc6ce,0x04f52e9a),LL(0x2ffa498e,0x4b21e0a8),LL(0x27375e3f,0x242c7c60),L_(0xd99a4851), + LL(0x064ca07a,0xa02c0b2b),LL(0x518bd6af,0xa1558503),LL(0x13a69d2a,0x3d67919d),L_(0x68b0b3b5), LL(0x2bfc83c0,0x3a653e93),LL(0x24e20cb0,0x69ae9c82),LL(0x0a4cc47c,0xf624d321),L_(0xeb72aa98), + LL(0x9e3e45d0,0xd947c8c7),LL(0x1032ccc8,0xa439634d),LL(0x5b100526,0x7b5067f8),L_(0x534219ea), LL(0xfc26652e,0x701d8d64),LL(0x1e89c3fb,0x277501f0),LL(0x262c9dad,0xd3dd957f),L_(0x48bd1e47), + LL(0x9f4be9d8,0xcf4ac2d6),LL(0x2a7df2ab,0xe04b6794),LL(0xf3257cbf,0xec24a41c),L_(0xf6596f8e), LL(0xb3eb3d14,0xcc1689ae),LL(0x7d52d65d,0x8712e8c6),LL(0xafd7b5e3,0x868af920),L_(0xb7ad63c9), + LL(0xd27017ec,0x75a3408c),LL(0x8af38290,0x7de280ae),LL(0xfab61ca0,0xb76f92d0),L_(0x9df539d9), LL(0x528c5329,0xffede226),LL(0x4363c147,0x9bf76d0a),LL(0x4d2256e2,0xdd96e876),L_(0xc1afd4ff), + LL(0xe00a0553,0x896685cb),LL(0x48da5f08,0xf0d4a520),LL(0xe8f5fdb6,0x0f380c61),L_(0xb146db8e), LL(0x4d63b6c7,0xca87cdad),LL(0xcfdcfe1c,0x69639e2c),LL(0x941d9935,0xed61f0e4),L_(0xad7751a2), + LL(0x72ebb947,0x43d0a9df),LL(0xdb90e6a7,0x53424333),LL(0x10a77134,0xdf849ce1),L_(0xce2f9c06), LL(0xdf56c5f4,0x58feabaa),LL(0xc5d546de,0x787ed1e1),LL(0xa802a275,0xa542b49b),L_(0xa5e7ea27), + LL(0x0646662c,0x33793ddc),LL(0xde0180db,0x873a716a),LL(0x3ae6c62d,0xd34ef5f0),L_(0x8ffbd17e), LL(0x9974e0c2,0x5b201375),LL(0x61aa17ae,0x25cf8d2d),LL(0xfac50e53,0xf5028682),L_(0x4cb76558), + LL(0x20822d1a,0xdb5b7f7b),LL(0x42e0c365,0x610bf8a8),LL(0xe4e5ddab,0x59f6f46f),L_(0x7d6ff0da), LL(0xd3a9f7a1,0x29ffdb56),LL(0x95d9dd8c,0x1aed0fa8),LL(0x7cd570f8,0xa1cdd0bb),L_(0xf42c2ded), + LL(0xb9d66a96,0xf9463b5d),LL(0x7ab3d377,0x9dcb5190),LL(0x7e8de98d,0x3a174474),L_(0xf096dc4f), LL(0xd8a6df5c,0xb00ae812),LL(0xc11335ee,0x595dbbd8),LL(0xab858cbb,0x20456b6d),L_(0x50149878), + LL(0x6e092bb5,0x4b66cf94),LL(0x20f71995,0x7eca44eb),LL(0x6daca5c9,0x44fbdf91),L_(0x06ba2abf), LL(0xcb39349b,0x9f292892),LL(0x5db8d756,0x7d2e1348),LL(0xb91c9d21,0x2511f796),L_(0x03664b0f), + LL(0xc742fe69,0xaeca436c),LL(0x07bb4010,0xa736c99b),LL(0x7053b3ba,0x4df3a08c),L_(0x7269f130), LL(0x35ff874c,0xa50437d0),LL(0xa2239752,0xbb3ee79b),LL(0x28f141d8,0xa309d53a),L_(0xe3b40a03), + LL(0x052107c2,0x4c1843ed),LL(0x92f03f51,0x5b395716),LL(0x10eeec3a,0x41bed6c7),L_(0xe7590252), LL(0xe3bf062e,0xe2632a75),LL(0x61293b51,0xccb37627),LL(0xf5482813,0x65bddca7),L_(0x3882b6c4), + LL(0x97f943de,0xe4f707eb),LL(0xaed3b2b2,0x1fca8433),LL(0xe200b711,0x5979d82e),L_(0x79d9de90), LL(0xa0864854,0x073f049c),LL(0x5ba6b65e,0xefca8545),LL(0x5e115ac7,0x81b25231),L_(0x811506c8), + LL(0x0b83214f,0x6e208498),LL(0x4f6ef89a,0xd7f17a61),LL(0x9d606b9f,0xf9ff6be9),L_(0x05c6d274), LL(0x78a1ebcd,0x8412a690),LL(0x1b349b3c,0x3fc39e84),LL(0xa4039f18,0x16cc85fa),L_(0xacd2b66e), + LL(0xb29dd0f6,0x3f372e07),LL(0xb2f85965,0x1010f76a),LL(0x499ca40b,0xc9d3a123),L_(0x494c1c41), LL(0x1a039621,0x898b067c),LL(0xc21db378,0x8fba57f1),LL(0x920244b9,0x2f20dfbe),L_(0xafa449b9), + LL(0xadba6514,0xf1db6fa1),LL(0x0a3087ba,0x780eff8d),LL(0x6530b59a,0xdcf21d60),L_(0xf6198373), LL(0x767463fe,0x65b13c4b),LL(0xff99e886,0xaf0f5939),LL(0xb10b6a9a,0x05c89578),L_(0x713231a5), + LL(0xae7f781a,0x678205ed),LL(0x46236fd1,0xcc32c0af),LL(0x2492206a,0x43d4ee55),L_(0xfbf9ba4c), LL(0x2296a220,0xd485f134),LL(0x17487172,0x7dae00fa),LL(0xd7fd8f23,0x9c357857),L_(0x48861bc1), + LL(0x683b4c53,0xd1014606),LL(0x084b9990,0x2de4b78e),LL(0xed10d363,0xe5547d1b),L_(0x3d2f5f09), LL(0x40cf618a,0x1fa00e4b),LL(0xf090adf3,0x2643b488),LL(0xa90cf1b7,0x862ff071),L_(0x7b03dffe), + LL(0x2c263fe4,0x3df3e881),LL(0x74c2dd8a,0x4a452825),LL(0xf8b4e248,0xff9860e0),L_(0x0632b8bd), LL(0xfaa7bd3b,0x4dcae86a),LL(0x6c838bca,0x0392152c),LL(0x8e97fa6c,0xfc62b042),L_(0x1616bf3e), + LL(0x38ca48d5,0xc8c6f843),LL(0xafab4216,0x1a5701ad),LL(0x8137a142,0x3332d11c),L_(0x073d30ce), LL(0xf65f8d03,0xc57e0eee),LL(0xc5ec9bae,0x84c4a8f0),LL(0x474d64c3,0x9a310ea4),L_(0x279cd2cf), + LL(0x90943f9d,0xabcd06f1),LL(0xdfc2230e,0x4bf7868a),LL(0x2460277b,0xf15a1c15),L_(0xe0531432), LL(0xbbc35210,0xa0084581),LL(0xff9171d1,0x8c12c483),LL(0x4461e279,0x2cb0b794),L_(0x18f08ce5), + LL(0xc6234888,0x1336960e),LL(0xd82f38a5,0x6690aec6),LL(0x8dcc7988,0xea8d5acf),L_(0xbdf09963), LL(0xad19e667,0x221a923e),LL(0x5ebdb79e,0x3d295ba2),LL(0x840fc746,0xa849c9c6),L_(0x95854d40), + LL(0x796ddb68,0x7f2ece47),LL(0xb700fc8f,0xfa40fdb7),LL(0x6e9b86f6,0x3753a599),L_(0x004dc14e), LL(0xb0d32904,0x9ce52e22),LL(0x9fb7c051,0x609b3582),LL(0xbd4bbc16,0x470387a5),L_(0xae8123ae), + LL(0xb5992b13,0x15e316ec),LL(0x34a4f3f6,0x331c37c2),LL(0x4f66d67c,0x5a547f8e),L_(0x3d89818f), LL(0x2343f37e,0xc7ecc98e),LL(0x464eaafa,0x2f36fbc0),LL(0x32fd452b,0xbcd300ae),L_(0x52cb6226), + LL(0x3965b7dc,0xfbb383d5),LL(0x8e1be53e,0xd5ddeb7e),LL(0x5de1379b,0x89236512),L_(0x1618ecf2), LL(0x71474c33,0x359ac63d),LL(0xad2f7a4e,0x6a2a41ed),LL(0xb41d45a2,0x4543bf02),L_(0xd97bbddf), + LL(0xdd45b155,0x51a93461),LL(0x835fa995,0x8e87a379),LL(0x6030bb55,0xe0f74319),L_(0x3fce8a20), LL(0x180c566c,0xf64d3bd0),LL(0xf4320f55,0x117f7e04),LL(0x9fe6d9b3,0x276cdeae),L_(0xe11e04e4), + LL(0x90d2c4b0,0x8ee8e755),LL(0x936a235c,0x34e9da69),LL(0xea446558,0x56f8560b),L_(0x868fe100), LL(0xf104982e,0x7a1b70ed),LL(0x2d932107,0x5df6c183),LL(0xb3a79a2f,0x3e690209),L_(0xddd8c4fc), + LL(0x506cdad3,0x1cd413bf),LL(0x8343be89,0x5af9735a),LL(0x4669ee32,0xf133df4e),L_(0x495a7ffd), LL(0x343b9134,0xd2df1205),LL(0x08509117,0xc0f593eb),LL(0xe1f7e724,0x03f70d2b),L_(0x56807867), + LL(0xe1aefce1,0x28e77727),LL(0x910ee9be,0xea43f71f),LL(0xb1afcd33,0xe72f4294),L_(0x04218f35), LL(0x5c609191,0xd85d4064),LL(0xe01905f3,0xd4734dca),LL(0xc6a7ed93,0x73444dba),L_(0xbd20eb77), + LL(0x786041c6,0x2e784b12),LL(0x3b8e5678,0xa5394485),LL(0xd5ed489c,0x7c1354f6),L_(0x37f214ac), LL(0x6f5aed21,0x04a2cef9),LL(0xfdcc232c,0x6a61903b),LL(0x0943ad59,0x74525b1c),L_(0x36735571), + LL(0x41295f9f,0x79058179),LL(0x53c2435b,0x8356b028),LL(0x8630275b,0x7d99704d),L_(0x22b975d5), LL(0xfe64fec2,0xb6ad9348),LL(0x1275938a,0x323c5204),LL(0xff571db9,0xabd2794c),L_(0x69883cf4), + LL(0x39e5ddd8,0xa00ac9eb),LL(0x0825e1a9,0x08022d52),LL(0xec00b4ca,0x89c305e2),L_(0x39410e3e), LL(0x2f6d8e33,0x1c9dee31),LL(0x189d73ba,0x063cbbc8),LL(0xd453f2df,0x500b8e1b),L_(0x200614c8), + LL(0x0d2d67f6,0x704fba9c),LL(0xe3b26afd,0x3b601782),LL(0xc86eeaf3,0x3a076280),L_(0xd5b4a74b), LL(0x057735bb,0x3c7fe621),LL(0x67519f38,0xba90bf98),LL(0x7ea681b4,0xc697f17d),L_(0x399fb8a8), + LL(0x2fb2d013,0x8b404954),LL(0x225dd20b,0x3864cc2c),LL(0xe8bf6c74,0x27928a4a),L_(0x0dbd4ced), LL(0x129459b4,0xb079e9c8),LL(0xcdaab48a,0xa8c506fc),LL(0x2be35d42,0xabd7b8a2),L_(0xc81bd43f), + LL(0x0c337ec0,0x9f5cd253),LL(0xb8d68d49,0x3bc3df03),LL(0x808378fd,0x57ce1b57),L_(0x7280fc5c), LL(0x9173aca9,0x29069aea),LL(0xec3e1405,0x172c5e75),LL(0xd7f9c6b8,0x2bb82de1),L_(0x7c6b6663), + LL(0x069b62dc,0x3a04b8c8),LL(0x539ec109,0xbb1fb7ee),LL(0x8e5dc130,0xdf0fbfa5),L_(0xd9cdb4bd), LL(0x8d6bb599,0xae962471),LL(0x8c98d809,0x6a0b5063),LL(0x1f5aad58,0xcb90fbe1),L_(0xbd8451cf), + LL(0x99c6500b,0x182ee0a7),LL(0xf250978f,0x9acab63a),LL(0xd7a3f799,0x579dffc7),L_(0x0a06a99d), LL(0x2e7244fa,0x7a563978),LL(0x780bf6d7,0xd9421c12),LL(0x4a33607f,0xca35ca5e),L_(0x4d6baab2), + LL(0x476c2c17,0x84dd3019),LL(0x1020ff66,0x9f6a9cbb),LL(0x8de41867,0xa0782cd2),L_(0x30b339ca), LL(0x335870d7,0x873bb057),LL(0xb2102899,0xd2763264),LL(0x817bb568,0xac61e5ba),L_(0x7167f834), + LL(0xb4216df4,0x28a00ba3),LL(0x72603953,0x8d18d559),LL(0x83dc382b,0x9929ba4b),L_(0xd887ba34), LL(0xc4acbdda,0x1a149f46),LL(0xabc8bd9c,0x03677afd),LL(0x7f382dd5,0x038b4fd6),L_(0x531a5b69), + LL(0x7b1469c6,0x770906b4),LL(0x29957782,0x39b76a30),LL(0xb757175c,0x77b00db2),L_(0xc63e688a), LL(0x00e5eb13,0x564b2b5a),LL(0x486048a7,0x16670a8b),LL(0x6cedfc0a,0xfc26f8d3),L_(0x158c04cf), + LL(0x5f72f036,0x492f15fb),LL(0xaf524838,0x8a57f34d),LL(0xca278cc2,0x136d3def),L_(0xf06989cb), LL(0x56bc1e3e,0xb7d079d2),LL(0x48aa5343,0xb849bec9),LL(0xc12eafab,0xf42c9064),L_(0xcdcc4178), + LL(0x35110b42,0x3593434b),LL(0x826b0084,0x2a685ee5),LL(0x38e7d616,0xd80d02e7),L_(0x3dd474b0), LL(0x47c0e164,0xa5dbbbef),LL(0x177aaf40,0x58c7a38b),LL(0x00b0f102,0xbe4a965e),L_(0x97ef9f54), + LL(0x00ea08ca,0x0a49eb36),LL(0xb9e97b18,0x4a5b799b),LL(0x1389e249,0x6bb607bd),L_(0x5f402141), LL(0x21dd6f71,0x648ac9f7),LL(0x0d6762ea,0x46ddb53b),LL(0x123f4a38,0x0b454608),L_(0xffc09d45), + LL(0xdc0b4f06,0xa26650ba),LL(0xc51c49ab,0x9623d15c),LL(0x52a5b5a4,0x8530847b),L_(0x9328fa21), LL(0x2b9634a5,0x88564796),LL(0x4c84e96b,0x8cd268e3),LL(0xdd09c6f7,0xfbbf3c6c),L_(0x6ae89ca8), +}, +/* digit=25 base_pwr=2^175 */ +{ + LL(0x076ba1e3,0xaf9141d1),LL(0x7d1bf374,0x90d62386),LL(0xeae39108,0x39ae931a),L_(0xbf9ff96f), LL(0x7c192921,0x51f12b8a),LL(0xf7008bde,0xf1cfbc62),LL(0xaa15f8c6,0x26ff0bea),L_(0x10e47e4d), + LL(0x5ac7dc32,0x5a5fa2f2),LL(0x727e3254,0x918f6160),LL(0x19e26cfd,0x3d611b68),L_(0x60d5395b), LL(0xfbe0d265,0xa4b3a16e),LL(0xc823108a,0xab7e3e37),LL(0xfb87b2d4,0xe4cf7a53),L_(0xa746dda9), + LL(0x28c21969,0xe6afbadf),LL(0xc63c394e,0x08d0d899),LL(0x79f622a4,0xfc61f01d),L_(0xbbd70173), LL(0x9afa4015,0x1819a677),LL(0x9acf1a59,0x9e89a4e9),LL(0xf6189381,0x4c306973),L_(0xf09c6806), + LL(0xd0fd8e2e,0x85f596e9),LL(0x8c824b93,0xc650d109),LL(0xc0ff364a,0xaa432f6b),L_(0xe94aff61), LL(0x60cd9ff7,0xa81387b4),LL(0xafe1dcb8,0x1fb57eae),LL(0x0f74dad8,0x77ebce28),L_(0x461e02cb), + LL(0xe7801dc0,0xc705f5f3),LL(0x19eba5b4,0x892e14fd),LL(0xee1d51c0,0x235f35c6),L_(0x32c28b10), LL(0xc690d3c0,0x496db46c),LL(0x35bd49b1,0xf95db976),LL(0xa0c8c115,0x3a2ff859),L_(0x347bf13c), + LL(0x21208e25,0x50a51554),LL(0x37fdbb13,0x76da2c79),LL(0x739f33c4,0x47f7655f),L_(0x5268d621), LL(0x6df3da72,0xda653a05),LL(0x63868730,0xe0dbba02),LL(0x7efefa7f,0x8546d123),L_(0xc050a28d), + LL(0x63a12c14,0x81bccb17),LL(0xb1d9c462,0xb8ad1f48),LL(0x2ee0f6a0,0xeca64ff4),L_(0x5d641bc5), LL(0x6c14c6a5,0x27d0478a),LL(0x3fb250a4,0x9dc8b9dd),LL(0xe6cf3269,0xde4a727b),L_(0xd5fdb843), + LL(0xe9139921,0xafcf2338),LL(0x6d85ee99,0x8626eb92),LL(0x330ff008,0x62bc5b8f),L_(0x75be09d1), LL(0x9ed3ab3e,0xacdfce8c),LL(0xfe5d4b90,0x198a1e99),LL(0x36ceed7d,0x366edc66),L_(0x88f5f0af), + LL(0x9eb6ef97,0xa0790c0e),LL(0x3c7a8752,0x8212d5cc),LL(0xa20f0405,0x2e6749a5),L_(0x52b0f123), LL(0x0b5bf3ab,0xf0598778),LL(0xad1df6a6,0x6b2a153d),LL(0xacd67e10,0x9a4287cf),L_(0xbc3d1a68), + LL(0x1df015e0,0x5545ae11),LL(0xaefec73e,0xf86d852d),LL(0x34894ebb,0x61b42915),L_(0x36e6b458), LL(0xb25bf6b1,0x2f858332),LL(0xa346bcfb,0x082b80c9),LL(0xa64fc13d,0xdb34263a),L_(0x5546d687), + LL(0x6c1819ab,0x46f4e2d8),LL(0xc8c8ebfb,0x3e6d5834),LL(0x31b5f8c4,0x0471eabf),L_(0xb0372dd8), LL(0x7377bdb2,0x4f0b793d),LL(0x1491549c,0x1e0b124d),LL(0x8be72522,0xcb228953),L_(0x28f9ea46), + LL(0x3d345d7a,0x4e4eb11a),LL(0x6b6a8f36,0x4f7cb301),LL(0xd3f60831,0x9b37cac3),L_(0x2fa1e5ac), LL(0xd42ac14b,0x4b82b6e1),LL(0x44efee99,0x062085e8),LL(0x293aa2ea,0xdafbaa02),L_(0x22eacbf0), + LL(0x66dc4353,0xeee6c065),LL(0xf4fb584f,0xe974bd6a),LL(0x51129e57,0xc6e911b2),L_(0xa817dc5e), LL(0x143fbbc1,0xe567aa72),LL(0x474c4763,0xd98a2bac),LL(0x985f3567,0x4940de3e),L_(0xb5a6e769), + LL(0xabba8dd9,0xbc9b4d54),LL(0x51333936,0x09ce7445),LL(0x56df5156,0x869985ec),L_(0x7ef1c4c4), LL(0xd64936f2,0xf9f4dd90),LL(0xb6f830f1,0xb0502e70),LL(0x9b4a0a61,0x2b7784e2),L_(0x5d8609f5), + LL(0x228b551b,0x132cf6ee),LL(0xe485fe61,0xb41622cd),LL(0x1166f594,0x4f82b870),L_(0xef156ec2), LL(0xc4a0434d,0x1f3f48d6),LL(0xc59ea2a2,0x185bfa1f),LL(0x0549b016,0xab597880),L_(0x88e57344), + LL(0x7783a237,0xcacbfea9),LL(0xa7d644dc,0x37384da2),LL(0xd767d6c6,0x1b40ecf0),L_(0x708738a4), LL(0xcb35e136,0x1bdb10dc),LL(0x946bff60,0x51f82512),LL(0x032e4873,0x86fff3dd),L_(0x4a72093c), + LL(0x993762c0,0x3c5e8711),LL(0x97ea967e,0xc3fb58ec),LL(0x5942a654,0xdc39e05c),L_(0x51f715f7), LL(0x4c7c1a58,0x76f183b7),LL(0x24b588e9,0x02f3f5a3),LL(0xc7635031,0x95a5b1bf),L_(0x90ff5787), + LL(0x44aeebfc,0x6fdec0d8),LL(0x3c09be94,0x4dccb72c),LL(0xc61c3dc6,0x29d98bbe),L_(0xe68c7671), LL(0x0b4d124d,0x60e1bdf3),LL(0x72ff08f6,0x60907706),LL(0x502b0c26,0x52fb8b7c),L_(0x3862b07e), + LL(0xa0c27cd3,0xa30b225d),LL(0xd6902dc0,0x14e5e016),LL(0x90beb6db,0xca71c799),L_(0x63380a26), LL(0x6406e7a3,0x8b449af9),LL(0x785b17f6,0xd95a3673),LL(0xe83116d2,0xc945cb30),L_(0xcbad56e8), + LL(0x195a49f2,0x19bb9a9f),LL(0x32abbd2d,0xdd63e900),LL(0x32a666f4,0xbb5bae80),L_(0x8a8b981b), LL(0x71975391,0x7200d75c),LL(0x58755037,0x9bb8f1f0),LL(0x34371f37,0xd14c5988),L_(0x4f91cd94), + LL(0x330b4d2d,0x4766d5c5),LL(0x29100509,0x96d443b1),LL(0xb683d913,0x55cd4038),L_(0x60386c8a), LL(0x0b19d842,0x4de7c5cc),LL(0xe7f655d5,0xb34627f5),LL(0x63d637ee,0x05d48e84),L_(0xda1b6f68), + LL(0xa9ab961e,0x587b4227),LL(0xaee0b38f,0x9bacdb2e),LL(0xf2fed11b,0x4327e6c8),L_(0xd04d5cf3), LL(0x59f2340b,0xdae690d8),LL(0x98397f13,0x20f9a82b),LL(0x04266881,0xb60ba27e),L_(0x0a08356c), + LL(0x4b7ea199,0xf7bd165d),LL(0x00c43b16,0xaff22d2a),LL(0x6e2c180a,0x5fa28be1),L_(0x03759f7d), LL(0x8d8de81a,0x8623fa12),LL(0xd1bcd513,0xf1b013b3),LL(0xecdeea2c,0x1412065d),L_(0x4abdd176), + LL(0x949b80c3,0x9e45f562),LL(0x91bfead0,0xeacf4d8f),LL(0x89e47023,0xed86f825),L_(0xe474eb17), LL(0xa46549d4,0xcc9d20c3),LL(0xbb6f6ac8,0xb5aaafc7),LL(0xaad820ff,0xfa9b0b7b),L_(0xd5d711cd), + LL(0x56a19c65,0x694699c4),LL(0xa52b01ba,0x2172bedc),LL(0xfcd8d182,0x71a622e6),L_(0xc5676308), LL(0x096356a4,0x5df0e982),LL(0x5f771127,0xbff93f13),LL(0x15499fe5,0x035d8bec),L_(0x54511618), + LL(0x8665d51a,0x0b392d7e),LL(0x19051cb5,0xda3e7314),LL(0x27724fe5,0xb0000497),L_(0x180fd98b), LL(0x92676515,0x86de4867),LL(0x0724b0c4,0xbfb7e396),LL(0xc9127734,0xec308376),L_(0x69d91fa4), + LL(0x13351e01,0x9ee3edde),LL(0x12d31182,0xe9b0df44),LL(0x039a9289,0x3ba48603),L_(0x776fb73e), LL(0x1bc5a4ee,0x28dbe0e2),LL(0x5d6f8bfe,0x33d13a46),LL(0x683a466a,0x6f0e40d3),L_(0x64598a06), + LL(0x49b1e543,0x5467b60c),LL(0xdafb9975,0x63a775bb),LL(0xf10e3ad8,0x555978a5),L_(0x90e960a3), LL(0xe2647c34,0x2d98173b),LL(0xeca130de,0xa46de612),LL(0xd4d665e8,0x8c2f942e),L_(0xd46cdc7a), + LL(0x83f96958,0x11159549),LL(0x2f2fe4fe,0xa26fb69f),LL(0xada04407,0xe1ffa9b1),L_(0x89077bf7), LL(0xf63dc16d,0xb8212592),LL(0x23757f3b,0x8f2b706f),LL(0xa84d6d60,0x0952d255),L_(0x867adb63), + LL(0xc1ad35d0,0x8063b121),LL(0x94420770,0x2c69c142),LL(0x2eddbe16,0xe20cbf04),L_(0x610d35ad), LL(0xc6a6486d,0x5f1b4348),LL(0x8963cf0f,0xaa7af662),LL(0xbd211312,0xf09747fa),L_(0xa7462c1b), + LL(0xb3384571,0xad4b300b),LL(0xeaf252a1,0x7e0408a9),LL(0x92c8f393,0xcdb75950),L_(0x95152482), LL(0x01c71c43,0x98806233),LL(0x65895709,0x4ccfab0f),LL(0x2c91c51d,0x0daddeb0),L_(0x6e5994f0), + LL(0x1656bed2,0xf9475d4e),LL(0x7ad0e424,0x29f67636),LL(0x71b2886d,0xce5ffc47),L_(0x5aec9cfb), LL(0xed19aefe,0x00fbe22e),LL(0x335636b3,0x1a593c52),LL(0xed7635e4,0xfea5dbc5),L_(0x0713b394), + LL(0x0a800d8a,0x3e952cbe),LL(0x96ad939e,0xb849574d),LL(0x95e45fa4,0xd0b6f06f),L_(0x495cdf6f), LL(0xca47bacd,0x3aea6517),LL(0x627d416e,0x98d62545),LL(0xf79f468d,0xe75cf2cd),L_(0x3f4c786d), + LL(0x92cfaed9,0x8aa22d94),LL(0x5767542d,0x951cb3e9),LL(0xcdf3e590,0xc6443f1d),L_(0x926947a4), LL(0xa83030be,0x4ab4bb2e),LL(0x1ac42dc6,0x126bf8d3),LL(0xab5c4613,0x78abc625),L_(0xa11b8fa6), + LL(0xb14045ea,0x75f0192a),LL(0xe56f26d4,0x66a1d69e),LL(0x488c7367,0x27671771),L_(0xe2f663dc), LL(0x41dc68c9,0xdbf2b527),LL(0x67ba17c4,0xaa6e15c1),LL(0xc052c755,0x6264eb14),L_(0xef0af1f0), + LL(0x361df88e,0x8133758d),LL(0xedb54b06,0x89d87e0a),LL(0x8313147e,0x156564f5),L_(0x0efd3686), LL(0x0305e3bc,0xb530ebe1),LL(0xd1426de8,0x75ed509a),LL(0xe3da205e,0x8810aa6d),L_(0x6d66996f), + LL(0x66bf33ae,0x5cdc1d84),LL(0x297ed94e,0x40fff510),LL(0x02569cc0,0xa46f7fa8),L_(0xf6c9bcc5), LL(0x03ae7466,0x6ca8cba2),LL(0x102909c9,0x9d34e4a3),LL(0x338f15f5,0xf175cde9),L_(0x9415a0f5), + LL(0x43fb29db,0x0f113fed),LL(0x55f28334,0xc9bc3623),LL(0x0891f557,0xf2de428e),L_(0xc85b958a), LL(0x72c78285,0x0bca6469),LL(0xfebcc59d,0x4ad07f91),LL(0x9aca547e,0x254d2e0c),L_(0x934ecc4a), + LL(0xbedf71c8,0xfdf235a0),LL(0xc42e06f8,0x707d37d4),LL(0x519516e4,0xb70d0d1d),L_(0xb746501f), LL(0x026e2e99,0x7b9cd555),LL(0x97c86a72,0x05a8ce5e),LL(0x490bbe2c,0xfd0ac7d5),L_(0x0e861b77), + LL(0x4518decc,0x5704b61f),LL(0xe3a1e11b,0x05e3a6d3),LL(0x761243d0,0x09fdcc95),L_(0xa10f1bbc), LL(0x52cc9710,0x2f40eec4),LL(0x45b65061,0x3cfbc5b3),LL(0x82e0b382,0xd24582c3),L_(0x0ea8545f), + LL(0x91b73502,0x63a13aee),LL(0x32b2623c,0x64a186c4),LL(0xd30674ab,0xae849f85),L_(0xc2109747), LL(0xbd3a7bd9,0x4e22b52c),LL(0xa5ad1cda,0xdee6130a),LL(0xa16934a2,0xa208c2f8),L_(0x29c61250), + LL(0xacddc899,0xdcfd6055),LL(0xaf5f3b40,0x4226123c),LL(0x22c7c6d7,0x18caa3b3),L_(0x11d8af8f), LL(0x27a1cc64,0xcfd9c842),LL(0x74dfaf98,0x435cc5af),LL(0x98cdd25d,0x03338f7f),L_(0xa8a15bc3), + LL(0x39e40f6f,0xa3f28110),LL(0x10846ecf,0xbb9b4a37),LL(0x6d2f9be1,0xc7ef39dd),L_(0xe4358a6b), LL(0xb0848ac1,0x9e6a4583),LL(0x0c20b047,0x65ecc897),LL(0x7961633c,0x12939ce7),L_(0xd7729b06), + LL(0xdf1e1998,0x0eb1a850),LL(0xbf310ff6,0xcfe64a90),LL(0x6d23295e,0xf848ec96),L_(0x96ccdfe8), LL(0x8a058164,0x4a1159c7),LL(0xfb67d66c,0x145557f8),LL(0x44e87592,0x744a6684),L_(0x93329250), + LL(0xd2524bb8,0x71ee45c1),LL(0x3c745d69,0xae2e62f4),LL(0x90655f39,0x4aa6dd85),L_(0xa8f50bcd), LL(0x170e2564,0xcd77d544),LL(0x84a26aa1,0x1637c5b9),LL(0xbbddebd8,0x116cc13c),L_(0x316cea62), + LL(0xda76037b,0xe567b31a),LL(0xc3337684,0x81454a31),LL(0x8ce526e9,0xa68887d1),L_(0x5860c2ac), LL(0x5ccae9e8,0x2aa4281c),LL(0x3740c0a4,0x27a06af9),LL(0x67a8cecd,0xb0666bd6),L_(0x8396d5d6), + LL(0x3bf215ba,0xf3b762b4),LL(0x2c7b4d47,0xc7ded91d),LL(0xf2dddefc,0x491f86d1),L_(0xe72784c3), LL(0x1a33ec17,0xbfa502ae),LL(0x6ff1a28d,0x8b90c1c4),LL(0x011d4fdb,0xae49e966),L_(0x6e8a2219), + LL(0x30030ab8,0x9b2323cb),LL(0xc742f24d,0x3dfca102),LL(0x6d677f76,0x615cef3a),L_(0xcc62a7bf), LL(0xd8927085,0x143864e2),LL(0x68578492,0xe2a53ef4),LL(0x7bfce607,0x98d95aec),L_(0xa4e64436), + LL(0xe4480a83,0x674699df),LL(0x638814de,0xf6bd5725),LL(0xa3bae3b5,0x93074bef),L_(0x401bd027), LL(0xc278e6d9,0x9075dc94),LL(0x33a4f7b4,0x66f70e53),LL(0x2912d169,0x77ae21bf),L_(0xd08ac30b), + LL(0xba0002d7,0x9d21da23),LL(0x313a021b,0xc9cb3757),LL(0xc0b1cdab,0x478c82a0),L_(0x71e210e7), LL(0x708a627d,0x95df97f0),LL(0x8f2e6f2f,0x036873be),LL(0x9b0c552c,0x31bdcc00),L_(0x7142f468), + LL(0xdb1b2797,0x16f6892d),LL(0xd070a81f,0x513e742c),LL(0x83e7ad99,0x5ba54190),L_(0x580b098a), LL(0x3ab45169,0xd55025e1),LL(0x9e175afe,0x57264580),LL(0xa5b527ed,0x246fe503),L_(0x27cfca13), + LL(0x9456aa99,0x72287d14),LL(0x56f44c80,0xbd98da02),LL(0x783e5a79,0x1c038840),L_(0xd6a90a4a), LL(0x44dd9215,0x8abbd0fb),LL(0x42622308,0x546492b7),LL(0x9365b6f9,0x638f9886),L_(0xd87dec07), + LL(0xe568c53e,0x56dd3ec8),LL(0xecec272c,0xad2418b1),LL(0x40cc9856,0x5fe0c00d),L_(0xd88d5b28), LL(0x1cdd7256,0x17304349),LL(0xa2eb70d1,0xe17ec8e0),LL(0xb4dc2a26,0x62eb4c57),L_(0x3373155f), + LL(0xdb4ee5e1,0xa85ff057),LL(0x2cbbaad9,0x0fb19074),LL(0xf1a5850d,0xb1c8c20f),L_(0x4ceec839), LL(0x407175d6,0xc25f5ad9),LL(0xc43bdd2a,0x0ed43d06),LL(0xa2739236,0x55db40b6),L_(0x59afdd51), + LL(0xbb91225b,0xb6ec7895),LL(0x64957b33,0xec277689),LL(0x53e7c8ad,0x503d01fd),L_(0x14800e2a), LL(0xff30aa1c,0x789118fb),LL(0x6b208671,0x45dce70d),LL(0x7758b97b,0x2ad05594),L_(0xbd833a82), + LL(0x64d25f39,0x7c1271cb),LL(0x973eb35d,0xafba6d12),LL(0x24a4fbdb,0x68588b5a),L_(0x86209415), LL(0x4408d2f4,0xb9962d65),LL(0xa7df2cdd,0x1adff958),LL(0x3e504930,0x1a7248ef),L_(0x642fcd83), + LL(0x50371a5e,0x10a09de0),LL(0x585cdc97,0x544a1f87),LL(0x05603976,0x9bb49da7),L_(0x36e0a9f7), LL(0x2686c471,0x22de25c7),LL(0xfc3ec645,0x7b318aad),LL(0x0e37c5eb,0x6e0af008),L_(0xb0fdc095), + LL(0xc4103bda,0x28c77b28),LL(0xc7d3392d,0xc44c9d87),LL(0x02942cad,0x045b3511),L_(0x633d355c), LL(0x985fde91,0x3e691e0d),LL(0x0d200049,0x66200341),LL(0xa7fa897a,0xc1b7c5c2),L_(0x5183d651), + LL(0x858b20b8,0x94f1ad67),LL(0x73a3848e,0xcb454e18),LL(0xe75e697e,0xea8630aa),L_(0x0d245b82), LL(0x7a69400f,0x7d8e1f8e),LL(0x1a8975af,0x87354e0a),LL(0xd949265a,0xddd78248),L_(0x59506113), + LL(0xbb95794d,0x56456f06),LL(0xb1cf847b,0xb5869a96),LL(0x7de9cd89,0x4dd26048),L_(0x29abee0d), LL(0x6b7c47c0,0x3a2f738b),LL(0xdc3e8b24,0x43a158b5),LL(0x6452e6ec,0xb59a08ed),L_(0xdca422db), + LL(0xfd294203,0xd446ba91),LL(0xb382c52a,0x0bfb0e2b),LL(0xb347e482,0xda5432f0),L_(0xc465aa05), LL(0xda7568f3,0xfd584f1c),LL(0xb3f81a8e,0x3e5b388d),LL(0xfbef98fa,0xa2090daa),L_(0x7ee59c28), + LL(0xebc6de85,0x8601a460),LL(0xa197c14a,0x0fe7b2f4),LL(0x51718d1f,0x768e05f3),L_(0xd61640e4), LL(0x107bee82,0xdafff971),LL(0xd549077c,0x775aa266),LL(0xf5af9168,0xa74ac1aa),L_(0x709e0299), + LL(0x7770d24d,0x6c27e8ad),LL(0x5f6805b9,0x0c21256b),LL(0x5eb3480c,0x24df253e),L_(0x33b3350b), LL(0x32c4c951,0x304257df),LL(0xd07bd3eb,0x3821aab8),LL(0xcfd48043,0xe9ed7945),L_(0x29f131a5), + LL(0xf927be41,0xa625fc39),LL(0x0acd5378,0xc708ccff),LL(0xc7c05c00,0xe3551df0),L_(0x5a9c25df), LL(0x4a824ae7,0x00aff255),LL(0x3fad48ea,0xdc1865b9),LL(0x489f78db,0xc47678ec),L_(0xe24fe1d5), +}, +/* digit=26 base_pwr=2^182 */ +{ + LL(0x4d52ad99,0x44075a5f),LL(0x49de85ac,0x5f264197),LL(0xa5da6ace,0x1bd94b24),L_(0x58ceb7a8), LL(0xaddbfb85,0x9deccfa5),LL(0xeb853c9e,0x38b0cd4c),LL(0x0ae5bd28,0xcdefc743),L_(0xefb92de4), + LL(0x9f68d2fd,0xdb80636b),LL(0xeb6a625d,0x399cbe21),LL(0x058ae3aa,0x9a20e964),L_(0xeefd7139), LL(0x0655d447,0x82be9278),LL(0x76a67bb6,0x02a07951),LL(0x78c7207b,0x5473af3e),L_(0x5b501b3b), + LL(0x48532008,0xe1daa6d9),LL(0x9dfa0916,0x8ffcdbb0),LL(0xbd0a98e5,0x9b2bdde3),L_(0x5bcf0ad7), LL(0x58bd4135,0x4dcdfb2b),LL(0x913a8546,0x29153442),LL(0x7457124c,0x9190c343),L_(0xc113bf67), + LL(0xe34c46c8,0x1a8f4562),LL(0xb45aadf5,0x6cddda1d),LL(0xb1bb8fc9,0xa502ea7e),L_(0xf3ae0efa), LL(0x9421a0ec,0x124b21a9),LL(0xa80fcb58,0x634ea314),LL(0xfc9b2b69,0x4d2d4d06),L_(0x619c1654), + LL(0xa4e345b7,0x370847bf),LL(0x9d1ecec7,0x242713b8),LL(0x10782ff2,0xbc286c44),L_(0x2b85247f), LL(0xbe6fa012,0x72197eb9),LL(0xec864a68,0x23d8a845),LL(0x9c366368,0xe57509e0),L_(0xfafe2bf5), + LL(0x9344ebd5,0x41626ac2),LL(0xa5a7b2b3,0xb61e001b),LL(0x1c404975,0x05deb3c3),L_(0x4861d13f), LL(0x10e30e7a,0x4f5429b7),LL(0x409e441f,0x0cc2b3bc),LL(0xe64edacb,0x2a32f215),L_(0x502743d8), + LL(0xa18ec5e4,0x597408da),LL(0x75198a41,0xb4dc90d0),LL(0x9e4003b1,0xf0377012),L_(0x97c24d6f), LL(0x2f737bfa,0x138b7393),LL(0xc6646756,0xbf91bb7c),LL(0x4390dd24,0xd3eb9506),L_(0x660fe2be), + LL(0x1f5f9c09,0xcbb88522),LL(0xde4f8a6e,0x590e948c),LL(0xd63bd64a,0x45a94350),L_(0x82568ecb), LL(0x8b9c0e80,0xc46a6c09),LL(0xe8dd7862,0xe5cb409e),LL(0x6aa2f787,0x90fd8928),L_(0x3c0fb202), + LL(0xc519de27,0xc3ac3715),LL(0x59e082f8,0x915329a3),LL(0x0ca44fa0,0xe61346f3),L_(0x590df3a0), LL(0xe4d76c98,0x37f7afee),LL(0x58d6ab1b,0x6bdfe1fe),LL(0x536926c2,0xc048c2a4),L_(0xdd33cbc7), + LL(0x57103467,0x9e779a72),LL(0x24aafef8,0xf0cf02a3),LL(0xc4a65bf2,0xc464a2f5),L_(0xcc014eab), LL(0x771064c4,0x545f80d2),LL(0x90630a3b,0x142107aa),LL(0xc2378a52,0x233fc912),L_(0x60b64ae1), + LL(0x2c57b6ec,0xe31036a2),LL(0xf8434ff6,0x18945c37),LL(0xa0a4a4f0,0xa70971ce),L_(0x2a1d924f), LL(0x78d2269f,0x3f54f031),LL(0x59b13396,0xd1a3f071),LL(0xcf63943b,0x1bbad8a4),L_(0xae570fbb), + LL(0x7535f2cf,0x2202c2ff),LL(0x6ed5c874,0xad072699),LL(0xc576098a,0x233792b7),L_(0xbaf56f3f), LL(0x58643430,0x02886c17),LL(0x64569bb7,0xb1a39466),LL(0x74bab9ee,0xe841def5),L_(0xc973e3bc), + LL(0x7f584615,0x0ec350c2),LL(0xca028343,0x2da65635),LL(0xb160863f,0xe9a43081),L_(0x72084a70), LL(0xce3663d1,0xafbf1395),LL(0x1aeb19b6,0xdfa06d4c),LL(0x9aa85d56,0x4f103987),L_(0x4f14057c), + LL(0x7df657ba,0xf5ac31c8),LL(0xd4e08231,0x1a02ac9e),LL(0xd28fa99b,0x6407f45c),L_(0x36b31d91), LL(0x06494082,0xe60e26a5),LL(0x03bcc061,0x44cfce93),LL(0x4db05d61,0xf189ccff),L_(0x635d166c), + LL(0x16a82c08,0xd179a921),LL(0xec3df3ad,0x51227dd3),LL(0x1d15b312,0x129de8ff),L_(0x99a2081f), LL(0xe117dd1e,0x3f1a519b),LL(0x669c965d,0xd473a86e),LL(0xe470bd93,0x48ca17dc),L_(0xd7172ef7), + LL(0xce23cb90,0x025cce52),LL(0x54ac5788,0x7128e28e),LL(0x60a7af16,0xee37af3a),L_(0xd328cf8c), LL(0x228c1194,0x8bcaaced),LL(0x7eb8e5dd,0x60835723),LL(0x5f7c29e2,0x42db013e),L_(0xd6e3c26e), + LL(0xd7266cda,0x5ce7356c),LL(0x31f3b95f,0xc0bdd70b),LL(0x086e72f7,0x3319c072),L_(0x7f9cf187), LL(0x4ae3ba6a,0x086343f9),LL(0x85584e27,0x80bc2aba),LL(0xbf3ecc51,0x37cadfe3),L_(0x10a2f1b8), + LL(0x66dd80da,0x32cd82a6),LL(0x5a4759b6,0x11e8daf7),LL(0x6268a0b4,0xbd297ce7),L_(0x554b93e1), LL(0x971bdef9,0x8c4eabfb),LL(0x5bdd9c55,0xcbfa339e),LL(0x83d9f14e,0xbd36bd3d),L_(0xe88e0095), + LL(0xe3a86075,0xf0d2a9f0),LL(0x7ea9a94b,0x68a87b41),LL(0x27fad851,0x465da389),L_(0xc79beddb), LL(0xa438dfad,0x1024a804),LL(0x9e4004c2,0x3e3b2c82),LL(0x9e904c3e,0xb0cbbf5a),L_(0x91364ced), + LL(0x4f3cafc8,0x4571821c),LL(0x05a71822,0xb59cdc87),LL(0x564a1eff,0xd3fc8e11),L_(0xc2522075), LL(0x210954cd,0x485b3e16),LL(0x3e42143b,0xa39a864f),LL(0xc71b961e,0x50587567),L_(0xcd472e0f), + LL(0x3f39a45b,0x39ff9b1a),LL(0xb67c7e0c,0xe9320256),LL(0x293c62a7,0x30d60ad1),L_(0x6c70033e), LL(0x51699001,0xecc36d79),LL(0x66761810,0x782811c0),LL(0xb9b6100c,0xd4aec2a8),L_(0x01fd70b0), + LL(0xbf6700ba,0xdb67bc3c),LL(0x0705c260,0x81a05a44),LL(0x2a63deb4,0x2c00d649),L_(0xb057ad61), LL(0xc429bae3,0x962a325d),LL(0x94f128db,0xf818f010),LL(0x07c3cde9,0x8b0fa963),L_(0xb0a83496), + LL(0xdcf6f7fd,0xd9cd3792),LL(0x63f97d0d,0xa1b3479f),LL(0x9daa99a0,0x6b0d6566),L_(0xe8984ec2), LL(0x448838bc,0xe794fda6),LL(0x82c274f4,0xb6b1fe7b),LL(0xc0cb0a63,0xd09a8df9),L_(0x17a04bc3), + LL(0x4c395b4f,0x8e70bc90),LL(0x4ee87155,0x04b3e852),LL(0x9d40e63f,0x4a2dc6ce),L_(0xfaef51af), LL(0x36339e47,0x385a4594),LL(0x20622007,0x455a09ad),LL(0x9304dd88,0xc6ff5bf9),L_(0x913f4764), + LL(0xe085cdf8,0x187b4002),LL(0x185e6ba2,0x4c4e720e),LL(0xab690dee,0x86287cf7),L_(0x8afd2d78), LL(0xe2c63b4f,0x9adbcac5),LL(0x7132999e,0xddd28bc6),LL(0x4248e502,0xef074338),L_(0xfa2e3db0), + LL(0x896670f4,0x08020d96),LL(0xfcabc640,0xe06c4b5e),LL(0x9786e6bf,0x3da82523),L_(0x3d688833), LL(0x4fe3491f,0x99758e3b),LL(0x5ec531f3,0x0c3b82b5),LL(0xbab9fec3,0x45c4baf6),L_(0xb5f6610c), + LL(0xb5a9a1e0,0x4e7e7ab2),LL(0x1b52980f,0xce6cd002),LL(0x7c86bb7d,0xcadc14a3),L_(0x3b8e5f2a), LL(0xbef7e6fb,0xbff62993),LL(0xccd76ec4,0x0a2850cc),LL(0xc5820cdd,0x92bdfe5c),L_(0x082f1255), + LL(0x484daaef,0xd799a2f4),LL(0xedb03630,0x550daad0),LL(0xef0ac41a,0x8fbf8f4e),L_(0x737b2d81), LL(0x84f7e137,0x7bdb6e8f),LL(0x34c35ad6,0xd89df99b),LL(0x395821cc,0x20d76719),L_(0xc88df817), + LL(0xae387d39,0x760e59a1),LL(0x688c2755,0x97e8f74e),LL(0xbc044138,0xa21350e4),L_(0xc028fc40), LL(0x0253354a,0xe3e6583e),LL(0xb20dddcd,0xc654b121),LL(0xa829cd8c,0x39c79315),L_(0x792dd84b), + LL(0x040ffaf0,0xb7bea5b5),LL(0xf1650ec3,0xdb5241ae),LL(0x372d1796,0x940a8a94),L_(0x1a858744), LL(0xf1499afe,0xcabac4a3),LL(0x8ded605f,0xb861df88),LL(0x0cb6a234,0xa96fe9bb),L_(0xbc8b296e), + LL(0x5eedd185,0x4434f8b6),LL(0xd1edd68c,0x2a8d7504),LL(0x86f300e0,0x0e35d724),L_(0x897d3aeb), LL(0xfaf29ff1,0x4c814382),LL(0x472c2113,0x141d9196),LL(0xd1bc5f13,0xade4deb9),L_(0xa2fb8cce), + LL(0x406ace5c,0x1ea243b0),LL(0x686c6adf,0xd6070206),LL(0x22934b39,0xd9cd49e0),L_(0xa0234a2a), LL(0x4d0f3175,0xc755b33c),LL(0x5c35ad9b,0xf8e1a985),LL(0xc50467c8,0x18a3ef6a),L_(0xf2b99d2a), + LL(0x4607dced,0x614bcea6),LL(0xd3d623a4,0x68ae9193),LL(0xf3906a4b,0x42d006dc),L_(0x8b8583eb), LL(0x4cb64b0e,0x9dbec629),LL(0x98a17fc9,0x0bf6a2f2),LL(0x057751b4,0xa9fae60b),L_(0x21e7bd24), + LL(0x3c12fc75,0x017d14d0),LL(0x3242c2d8,0xc6c97422),LL(0xa51b04ab,0x626c81c6),L_(0x94d87c6b), LL(0x238bcf04,0x5e266a2a),LL(0xa82fa338,0x23764002),LL(0x51803104,0x5f7162bf),L_(0xc4756473), + LL(0xa5dd759f,0x522db1a2),LL(0x5930b4b5,0x09f2baed),LL(0xf85a6ac1,0x323304d4),L_(0x05195116), LL(0x1360791c,0x1db93b31),LL(0x108292f6,0x1b768230),LL(0xabf3fed8,0x87d85b61),L_(0xa1679cd2), + LL(0x761f1b7d,0x0b49a02f),LL(0xb6746bd7,0xbb854597),LL(0x77637e3e,0x0022290f),L_(0x86597269), LL(0xf0700421,0xe0410aa3),LL(0x2a1bca0c,0x6d34be85),LL(0xf6bc18c0,0x46cdba65),L_(0x203e8ea6), + LL(0xb9773b5a,0xc5228020),LL(0xba11b539,0x453c7ac2),LL(0xf11276b9,0x7df2cd47),L_(0x1949a67a), LL(0xf5a8c36b,0x179c274d),LL(0x860ff0ae,0xa5c5bb12),LL(0x11df901f,0xe17d00c3),L_(0x3411dcae), + LL(0x3ed4c79b,0x8883a1db),LL(0x1992a967,0xfdd5776e),LL(0x2f54ff27,0xcb776738),L_(0x47290630), LL(0x9a98b107,0x79c8cc7c),LL(0xee2e8af1,0xdc2c5969),LL(0xc7ee141c,0x6b47161b),L_(0xa7624962), + LL(0x543685fa,0xc2395393),LL(0xe7ef754f,0x9a0b36af),LL(0xaae1a4bd,0xd5d4e38e),L_(0x4aab543b), LL(0xc2e17c97,0xd7e5c5cf),LL(0x5af349b1,0x2bef05ff),LL(0x9ed78a64,0x561fb810),L_(0xf9c813d0), + LL(0x2fe8fb72,0x1a1e9b3b),LL(0x9b70eefa,0x3925b0e9),LL(0xbfb2449b,0xb054dfbe),L_(0xb47dede7), LL(0x28647224,0xa5055940),LL(0x0c72430a,0x31e1b9a5),LL(0x23b5a4c4,0x195035c8),L_(0xd679bea8), + LL(0xcc50c48d,0x209f3af8),LL(0xd27b6e83,0x181662d3),LL(0x4b465365,0x91296676),L_(0x420e37bf), LL(0x138dff74,0xed5f5189),LL(0x82f8d0f4,0xc0ded518),LL(0x40df6431,0x723fb4ad),L_(0x617ba2b7), + LL(0x112db662,0x3569136f),LL(0xb2b47e3c,0xb8e53774),LL(0xdd45fe78,0xfaa04e8d),L_(0xc768fdda), LL(0xf6371e54,0x86806849),LL(0xa8e9db9c,0xf4779601),LL(0x4c858ecd,0xa4992880),L_(0x49a83816), + LL(0x8967314a,0x156e1198),LL(0x7bad4014,0x39eb8236),LL(0xecde7783,0x6d9c66e5),L_(0x881e0782), LL(0xd2f38b48,0x3fba7225),LL(0xed8353b8,0x088944d1),LL(0x4f8035c2,0x33f1f404),L_(0x1cc9c213), + LL(0x51cb66d6,0x58d0680a),LL(0x50bb5809,0xcb3e58aa),LL(0x1d2325d3,0x13427358),L_(0x5e67c4ac), LL(0x7dbb0bf2,0x85f983bc),LL(0xa937cb56,0x0f88839a),LL(0x8a991a31,0x6b3985b4),L_(0x92b4731e), + LL(0xdf68b708,0xde5b911a),LL(0x03d7de13,0xeed92206),LL(0xfc74f9a9,0xbcecf38d),L_(0x088b6fe1), LL(0x96e739c0,0x0a6c0e27),LL(0xd4a63fbd,0x82400edd),LL(0xbba8f32c,0x27d5bb2b),L_(0xc58b1cab), + LL(0x3131df11,0x042f1a03),LL(0x4f121cf6,0xe003b634),LL(0xa22e7895,0x6dd1e8b0),L_(0x5d804ab1), LL(0x90518b2c,0x5efe4007),LL(0xe1e8157d,0x88b87e5c),LL(0x63c085ee,0xf6155e0f),L_(0xba6e44df), + LL(0x841e4ade,0x1f02ab50),LL(0x156d76af,0x67a50be5),LL(0xe6f206a7,0xf1e42056),L_(0x65f10a7c), LL(0x2febb4c7,0x657a0dc7),LL(0x072e3321,0xbbf3484b),LL(0xea4f285b,0x020b154e),L_(0x8c852c97), + LL(0xdbbe1818,0x91e4e9f4),LL(0x2edec0de,0xbf43b7fd),LL(0xe4667773,0x52865635),L_(0x56a43f3c), LL(0x5962ba87,0x28fe8ab8),LL(0x248c61c8,0xd449338b),LL(0xd636805c,0xa1efd1c9),L_(0x13bd6609), + LL(0xdfd448ab,0xb92e258d),LL(0xe4e24c18,0x35b6d45b),LL(0xa42ce187,0x0d195771),L_(0x5aad5bff), LL(0x672eaebc,0x60feb26e),LL(0x4177b162,0x9498986f),LL(0xb3b0ede4,0xc41d2caa),L_(0xf358519a), + LL(0x5261f5a7,0x330e8a48),LL(0x43204369,0xf61c72d3),LL(0x33ca48fd,0xffeebdb0),L_(0x8ae6e55b), LL(0x7ae9478f,0x73383a11),LL(0xa6e09378,0xafb5d295),LL(0x689cfdb3,0x32706d23),L_(0x868c5ddf), + LL(0x0bd73e3c,0x62c3a48b),LL(0x8741583b,0x0c0a3d1d),LL(0xacf48d35,0x48c97582),L_(0xa4f06efa), LL(0x01b5bb29,0xaf780b08),LL(0x6bf0d377,0x2a0a2d75),LL(0xabcaf322,0x13f7f83f),L_(0x655d34bf), + LL(0xb992a7a0,0x19a0cf96),LL(0x9ecda6fc,0x98adc9dd),LL(0x6a4d3e6c,0x40f8faf2),L_(0x0edc38f8), LL(0xef011d38,0x7e67e105),LL(0x1797a86e,0x87eb4d53),LL(0x45add6b3,0xce77f195),L_(0x989201fd), + LL(0x3d9993bc,0x8adaa277),LL(0x99dda71d,0x1fca3093),LL(0x7433657e,0x8caf0d86),L_(0x023c11e2), LL(0x85112381,0x3dbd4315),LL(0x708185e8,0x9d410bfb),LL(0x374f5e1e,0xf2fcce49),L_(0x3443b974), + LL(0x532b7588,0xd3243b22),LL(0xfed73137,0x11c1365d),LL(0xb045d4a7,0xb70776bc),L_(0xfa754876), LL(0xadb798db,0xe29a9f85),LL(0x7a404c41,0x04e83976),LL(0x4ef414c2,0xd94bbca4),L_(0xca54266d), + LL(0x69a5c564,0x189faa10),LL(0xea80ccb0,0x11ff4091),LL(0x270bddfa,0x13f400ef),L_(0x16bba259), LL(0x54c1f416,0x5467f97f),LL(0x63fe2fd7,0x8a19f9f7),LL(0xd713b7c7,0xbecb24c4),L_(0x548c6ef8), + LL(0xd9e41b7d,0x154bb407),LL(0x5fe1b516,0x9e3d7f55),LL(0x0a7b54c7,0x135359b7),L_(0x56bae4a1), LL(0x84d9fef8,0x5d18cdb1),LL(0x3494e228,0x142d7261),LL(0x1cba3904,0xac50bd6c),L_(0x2d2c512d), + LL(0x709ebb7e,0xec49c916),LL(0x906c201e,0x16f1cdf7),LL(0x9b4ca4e1,0xd65f4a10),L_(0x474e1186), LL(0xf98d2d15,0x03b182b1),LL(0x94cb6ea7,0x060b7206),LL(0xb11e15e8,0x6d96c56b),L_(0x52f7fca7), + LL(0x8f77e5e5,0x72cd83b6),LL(0x8cab24f9,0x25a5b5bf),LL(0x25a2e699,0x6fdd7673),L_(0x072fab5d), LL(0x90a6d4ff,0xd576b9f6),LL(0x3ca8ca37,0xbcb25091),LL(0xad2b4418,0xefb79bc4),L_(0xff9c27d0), + LL(0xfba463c7,0x67359a81),LL(0xfe5bb23c,0x2c69efd5),LL(0x280e7df6,0x74569519),L_(0xfe16bd9c), LL(0xe2c76094,0xb18f6667),LL(0x365a80b1,0xbd326eec),LL(0x88831553,0x87869f49),L_(0x5939e645), + LL(0xbaa57c7d,0x3b207add),LL(0xfb5db15b,0x4ed05149),LL(0xb373586a,0x309bffcc),L_(0x773b90d1), LL(0x461b005c,0xc0f53c53),LL(0x8106712a,0xc558624a),LL(0xcda6e3b1,0x6faa11b6),L_(0x3ae794e5), + LL(0xf0680ab3,0xcbfa17ef),LL(0x058c2020,0xcddb5b82),LL(0x41c78a0d,0x20234c33),L_(0xe0cbaf8b), LL(0xc2fe9029,0xf4f1f1bc),LL(0x7a0fe46d,0xfc36a9bb),LL(0x75517f43,0x7adc3f7c),L_(0x9a365f26), + LL(0xba51387b,0x49c36869),LL(0xc5a22f24,0x03e373c6),LL(0xb8b4767a,0xb07a3f0c),L_(0x36066a8f), LL(0xe85c503a,0x808f702e),LL(0x1497d7ac,0xdddd86d9),LL(0x7011d76f,0xfae1c7e7),L_(0x803e46f1), + LL(0x80fa818c,0x31e4ef2b),LL(0xeb39da59,0x68d478dc),LL(0xb3f48a44,0x7630fe61),L_(0x067101b0), LL(0xf7c94ecf,0x9a533238),LL(0xaea4959f,0x5e7ce695),LL(0x3b49d1b1,0x52a95933),L_(0x557cf5b6), + LL(0x0d20898f,0x9d1c985c),LL(0x072ec166,0xc62ed966),LL(0xce3b7676,0xeb820161),L_(0x37e4d792), LL(0x60f14619,0xe6d270e0),LL(0x648b3694,0x80e6594a),LL(0x9e645987,0x879e807c),L_(0xb22e7cb2), +}, +/* digit=27 base_pwr=2^189 */ +{ + LL(0x0703230c,0x9c23cc7f),LL(0xad5df365,0xa6d601b3),LL(0x3f2e4ff0,0x8b1b5936),L_(0x1dea5297), LL(0xe0882f47,0x402ec9ab),LL(0xa3a23af8,0x47de2c7e),LL(0x555b4d4e,0xeaa5bf4d),L_(0x2ff94aac), + LL(0xf78b555b,0x971ade84),LL(0x54bd5a85,0x4e8a2ef9),LL(0x5ad4ea73,0x0425d602),L_(0x3bd54fb7), LL(0x791d9123,0x227d0459),LL(0x1e92cc4f,0xc9d765a1),LL(0xe4f1346c,0x28b65397),L_(0xd481a746), + LL(0xe7d16971,0x871eef82),LL(0x0506636f,0xb5fdd432),LL(0xb27a33c5,0x1d066c2a),L_(0x3113bf2a), LL(0xe97230fe,0x862b60db),LL(0x75a027c2,0x593d4117),LL(0x539f6530,0x8436da66),L_(0xe2b2cbf2), + LL(0x2425af9f,0xead58c17),LL(0xcad19bb2,0xb5cbb50e),LL(0xccdd8dd9,0x86b3650e),L_(0x1a092795), LL(0xdc320635,0xa3e665cd),LL(0x7ebcad7d,0x1e2d319e),LL(0x33fae415,0xeca579c1),L_(0x6ac7d5f9), + LL(0x6a9d1fc5,0x89b65031),LL(0x881ef8ac,0x23a987e0),LL(0xfde88e7a,0x2dd37a50),L_(0xc8dcf85d), LL(0xcebc549c,0x820f3f12),LL(0xd4ae9ff8,0xb7bcaa86),LL(0x694bc71e,0x8e6e09c1),L_(0xd6b8424d), + LL(0xfe8a98f0,0x63ff767a),LL(0x378e38e8,0xc5f7f4d1),LL(0x0e5335e1,0x7cfba5a2),L_(0x39a8daab), LL(0x77da1977,0x67e59eaa),LL(0xad21218b,0x504acfd4),LL(0x96be881c,0xbeef988a),L_(0x69332afc), + LL(0x82325977,0x575e852e),LL(0x45759819,0x2c72e2f1),LL(0xe0cc66d6,0x1927e387),L_(0xc0500878), LL(0x4d0b0122,0x7da1cf59),LL(0x14427010,0x26204672),LL(0xdb25f5a7,0x0a8b1258),L_(0x478d5953), + LL(0x7d69f704,0x20d3988b),LL(0xab2517df,0x6c24b0c1),LL(0xaab259f9,0x5e65b843),L_(0x174ca2d2), LL(0x75e5c2e2,0xea29f462),LL(0xdb90528b,0x1834a190),LL(0x8c9eae94,0xf967c0ea),L_(0xae030eb0), + LL(0x7e9bdb89,0x00adf08d),LL(0x03f389c4,0xa0138acf),LL(0x8dfb7875,0xd93b37ee),L_(0xbed6d6d8), LL(0x749de946,0xbfd574b2),LL(0x1fc14060,0xe75abd5a),LL(0x67c65b64,0x13366a27),L_(0xc999214e), + LL(0xb08be401,0xe06fcef2),LL(0xa7dfbf73,0xe0ba359e),LL(0x607c14ca,0x382ff71f),L_(0xdef77eb0), LL(0x6404f03d,0x3f8a49f7),LL(0xf9e8050d,0x7853702d),LL(0x4887d191,0x04d3f5e6),L_(0x1aa6bfdc), + LL(0x67857252,0xdb805369),LL(0x612fee31,0xd63c66e4),LL(0xa73ff057,0x587ee86f),L_(0x2d5eb654), LL(0xa10a675a,0xbd927cb1),LL(0xf79fccb5,0xc799e97c),LL(0x6f65ee19,0x4703e5a8),L_(0x04d4c022), + LL(0xaa2f24f8,0xba32a728),LL(0x2229afc4,0xb7ad366d),LL(0xa0ac6a50,0xb220a09e),L_(0x5da587fb), LL(0xd5db1088,0x44a3150c),LL(0x31856642,0x09784fd1),LL(0xf6f05498,0xc1e6c0b0),L_(0x346aa16b), + LL(0x06b7160f,0xbb692e48),LL(0x89eb623c,0x15498ecf),LL(0xb77b124d,0xbb092f5d),L_(0x3e60aee2), LL(0x74e3ca98,0x7b0969cb),LL(0x9ba2e8fe,0xf86a2cf8),LL(0x6d59ed66,0xdeabc883),L_(0x39e0a846), + LL(0x17174a2f,0x852eae73),LL(0xbaf85e02,0x1e348f19),LL(0x0374bff3,0xeacc5568),L_(0x60bfb120), LL(0x5585a76d,0xa921615e),LL(0xf43bee83,0x1b74c1fc),LL(0x26867d50,0x52fb37fb),L_(0x7279cdee), + LL(0xb96496b8,0xe996dbee),LL(0x7868fd21,0x39670ef3),LL(0x8094e471,0x9c159e05),L_(0x2d0b6ffe), LL(0x4226465b,0xb7fd505e),LL(0xe7884414,0xf2355f66),LL(0xe46e77c4,0xe0fbfc8b),L_(0xd7928658), + LL(0xc386d033,0x16b11ec1),LL(0x6cbaf218,0x75da11d8),LL(0x94c7a19f,0xfda19041),L_(0x15d41b37), LL(0xcd2bfd31,0x0e5ba2ee),LL(0x8a34c58f,0x2339d87a),LL(0x375d7766,0x24af1974),L_(0x280bf34c), + LL(0x0c7c5c0f,0x06c1fc0c),LL(0x8c4fcedc,0x1d94e717),LL(0xb65c6a50,0x0b30821a),L_(0x2a34b8c1), LL(0xefa6a39e,0x6459b552),LL(0x49fdfbf5,0xb7d7e4b6),LL(0x18598afa,0x00b319ed),L_(0x287de14b), + LL(0xf884841d,0x8dad7679),LL(0x518b1ea0,0xb306db5d),LL(0xb36c0754,0x5229df9a),L_(0x8fc9f729), LL(0xaadea0d8,0x970bb22c),LL(0x03b629f0,0x298689dc),LL(0xf3b57c01,0x89fe17ad),L_(0x686552a0), + LL(0x76218fd5,0xceff7d9d),LL(0xd9e895e9,0x63a383ce),LL(0x238b4e91,0x99f29b16),L_(0xbd71b01c), LL(0xe11ea486,0x7ae47927),LL(0x605101be,0x7cd7a8d0),LL(0x0d9f157a,0xb3fa2b87),L_(0x330f1244), + LL(0xff049f89,0x85fe8244),LL(0x6ddb5ffc,0x5d2ff231),LL(0xef0f5b1a,0x63ccdc00),L_(0x61b2bcef), LL(0x8ba95ec1,0xa8a44260),LL(0x5321922c,0x6ed75cfa),LL(0x3e43af21,0x8464e573),L_(0x6a65d52d), + LL(0x65d29b4d,0x1583a353),LL(0x32ab9cfa,0x43193114),LL(0x92998e59,0x704abb0e),L_(0xbbb3d90f), LL(0x2a7e16f7,0x4c98adbf),LL(0x7bbafb3d,0xa5a25fbe),LL(0x44dc73bb,0x8fc488f7),L_(0x6641759d), + LL(0x784f9378,0xe7bcd034),LL(0xabbc4935,0x89f2f24e),LL(0xbec66d27,0x4917e013),L_(0x5c4012be), LL(0xf0cde4d8,0x0961875a),LL(0xa3f96a56,0xa260b4de),LL(0x59faeb8c,0xbeeb1631),L_(0xc5c3e45d), + LL(0x280f3963,0xa088a1e1),LL(0xf1068e65,0x1dbee472),LL(0x1692a131,0x05a158ea),L_(0xde0f97d9), LL(0x0a11b122,0x0e13e263),LL(0xb70fb035,0xdee544e8),LL(0x5dcaae12,0x8f1fbb34),L_(0xd7c3d865), + LL(0x5d2e90ae,0xb9ad99ac),LL(0x75457057,0x0c329529),LL(0xaa459865,0x96ffc387),L_(0x7823d3a1), LL(0x13516c2f,0xa0aa883b),LL(0x6d68a755,0xbfa72fcb),LL(0xa825f1f8,0x97da099b),L_(0xcba9849f), + LL(0x14bced83,0xf4fdf535),LL(0x671c909f,0x689f6f0d),LL(0x71814baa,0x5b8ff385),L_(0x984a3eb2), LL(0x9c1ba7cf,0x907e4e69),LL(0x6fd404b5,0xff0ce18b),LL(0x2458cb25,0xef5cd0aa),L_(0xdb837d9e), + LL(0xfee8b8f0,0xa4710d21),LL(0xca118a9d,0x54895b97),LL(0xb541a6b0,0x526b0ca4),L_(0x46f624ed), LL(0x16947323,0x31b294e5),LL(0xd0b8b7cb,0x1b4cb2b4),LL(0x98687802,0xfbcc3509),L_(0x58f68319), + LL(0xb150cf08,0xe16b93aa),LL(0xba41d3c9,0x253eb0dc),LL(0x984df68e,0x87118c04),L_(0xea79efa1), LL(0x480076ed,0x0dcde0c7),LL(0x36503c9e,0x18bdffd8),LL(0x16aa0174,0x1f265d34),L_(0x34f86080), + LL(0xee0e75be,0x5617d582),LL(0xab95d71a,0x3e671da8),LL(0x0190d33a,0x3bee1eff),L_(0xa69eb59f), LL(0xe617dbcc,0x09cde5ef),LL(0x2ec74095,0x888eade7),LL(0xfc85f3d6,0x359daa39),L_(0x55fe2fc2), + LL(0xb342c648,0x4a00b224),LL(0x153ecb1a,0xb894175c),LL(0x58a94e88,0x70cf2206),L_(0x2b740c25), LL(0xf20b5561,0xdca48b9e),LL(0xcecf5379,0x7707c57d),LL(0xa0a1a133,0xc33e6b03),L_(0x4b326561), + LL(0x9c8970a2,0x4c16f18a),LL(0x642f1b1c,0x57b552ca),LL(0xda495e0b,0x1a9ee7da),L_(0x8d81f72e), LL(0x1ad4dac5,0x06f7634a),LL(0xd29378b5,0x1b77c61d),LL(0x110655eb,0xd5bf028c),L_(0x1f8658cf), + LL(0x21c59245,0x51b05ff6),LL(0x6f117207,0xaf13b9eb),LL(0x2b5c0017,0x4aa9bdff),L_(0x0df00c88), LL(0x703d8719,0xaf5e4830),LL(0x40500109,0x52cc9369),LL(0xf59d1925,0x013abb12),L_(0xdc8ebfb1), + LL(0x1082f991,0x2c9f0b9e),LL(0x02ac62a2,0x666e06e5),LL(0x703ab683,0x6f1b6308),L_(0xf1dd2936), LL(0xc8b722dc,0xd103845d),LL(0x6960a1a5,0x2459c28c),LL(0xd0ce016b,0x60884f40),L_(0xd595cffb), + LL(0x7f7ba180,0xe194bda2),LL(0xabd5ba2f,0xbb90a872),LL(0x2977890c,0x3dc3fa11),L_(0xa6cdf4eb), LL(0x1ec1818c,0x2f976a14),LL(0x9509667f,0x6ef670b0),LL(0x547bbc14,0x7a6392b3),L_(0xec34c6c8), + LL(0xfa44c4a3,0xd1652cf8),LL(0xd0c64f4a,0x7b98c98c),LL(0xeeaab800,0xb60ccb53),L_(0x41176e83), LL(0x20bc577a,0x3d3d111a),LL(0xc6b3e65e,0xf1c69a56),LL(0x4586a0f5,0x047748d6),L_(0x966336bb), + LL(0xbfb2046e,0x1ba40992),LL(0x15e78b76,0x492e1976),LL(0x8fa3d075,0xb62a0315),L_(0x34d22c5e), LL(0x08bcfaa9,0x55ee388d),LL(0x47ca2bb1,0xb50f4e76),LL(0x48d16444,0x947b5775),L_(0x6055efef), + LL(0x27f9113a,0x9933e071),LL(0xeeda2fbb,0x16712a59),LL(0xc739c006,0x75d0d886),L_(0x844de074), LL(0x95eed6e3,0x5fd2d047),LL(0x53ef6941,0xfa45dd7f),LL(0x9d54f1fb,0x741b92d0),L_(0xf26829fe), + LL(0xe5114e39,0xc2275c0e),LL(0x14f42683,0xb4d5582b),LL(0x3e016601,0x25741fdf),L_(0xb4b6622d), LL(0x4514d2ec,0xc4ccb66a),LL(0xf7783f3c,0xb57016ca),LL(0x59b84d70,0xf83fe7e5),L_(0x1f712454), + LL(0x7a6974e4,0xcecae61e),LL(0xddefbfbc,0xa93265ce),LL(0x1f1fb9f1,0xf3c9e95d),L_(0x968d6e21), LL(0x76333191,0x5ef96caf),LL(0x343738c5,0x26204de9),LL(0x66ec9969,0x8ee499c3),L_(0xfa475270), + LL(0x1abe8df4,0x0e4c49fd),LL(0x72a09b7d,0x5430fd38),LL(0x5d968105,0xb2efc301),L_(0x82c1807e), LL(0xde3d9217,0x191e5b5e),LL(0xb52c47de,0x32722377),LL(0xa0892090,0xd92f1352),L_(0x8058cafd), + LL(0x757c94f0,0x9649e576),LL(0xf15a6d6f,0x79587916),LL(0x8be7ad8d,0xadd01304),L_(0x01368bc3), LL(0x29445ca1,0x285b7eef),LL(0x761da068,0xae55ea08),LL(0x962f7357,0x983ad1c5),L_(0x9e092171), + LL(0x40d7b216,0x3897f22b),LL(0x2a0a0ea9,0x0a2968a8),LL(0xae9ce773,0x5eeabf53),L_(0x205e8acc), LL(0xd7707d11,0x3f8692b7),LL(0xc470978d,0x416e3f6b),LL(0x0e77bce9,0xf53b376e),L_(0x4d5b8d32), + LL(0x211044a3,0xb9dbcba3),LL(0x174bbf68,0x7e52000c),LL(0x2961ea4a,0x12e1a413),L_(0x1ad46429), LL(0xc87793af,0x36916c16),LL(0x5c151550,0x93f3db96),LL(0xf4f9dbfb,0x2bfda0b4),L_(0x51b088a4), + LL(0xbbbbeb9d,0xcc1030ad),LL(0x12a28f87,0x49bedb1c),LL(0x1869975f,0x6a004fbc),L_(0xfb3e5023), LL(0x51c16438,0x71e53119),LL(0x49270eb0,0x5e139c47),LL(0x60f866a3,0x0784d6e0),L_(0xf4f1e774), + LL(0x97f340e8,0xa61d043f),LL(0x05c008f3,0x4c35a67a),LL(0x8581b05b,0x44182222),L_(0x3e8c133f), LL(0x45bca0e5,0x8bf96ead),LL(0xf85bee99,0x7c86a090),LL(0x2ad3d962,0x7ea985d4),L_(0x8ce03be2), + LL(0x1ef28f3f,0xcbf512f8),LL(0xcf504c88,0xdc8ed43e),LL(0x516f1183,0xec32dc2b),L_(0xa2e2c1fe), LL(0xc45e5adb,0x505156da),LL(0xb7216064,0x983acb8c),LL(0x30958d17,0xe6ec6def),L_(0x28469ede), + LL(0x1072cfe0,0xaaf2a64f),LL(0x30962a70,0x33454609),LL(0x8b880e7d,0xa7a46a05),L_(0xa96bc722), LL(0x7354fe08,0xd5821805),LL(0xdd17ff77,0x0fc1cbb0),LL(0x0e58985d,0x9f7a9dad),L_(0xca339489), + LL(0x9dc30815,0xe1ebef86),LL(0x51cfd1d3,0x852da87b),LL(0xed5cdd01,0x21bc828d),L_(0x7b53ef92), LL(0x5aadc85a,0xe522baaa),LL(0xb7031c6f,0x608b4b16),LL(0xee466b6e,0x0c33a24a),L_(0x3197bd29), + LL(0x4e1fae13,0xf397b191),LL(0x68fba8e4,0x2940f1c8),LL(0x47dd818f,0x68c77c89),L_(0x7dbc2c98), LL(0xba40969f,0x8ffaa799),LL(0xf0b99031,0x712df944),LL(0x997feef1,0x4da4261d),L_(0x1f70d141), + LL(0x1b0afa52,0x69fea568),LL(0x3e151e92,0xdfc334a6),LL(0xa2587e32,0xf61b674f),L_(0xbaa4f3f4), LL(0x62eb8d24,0xdd643088),LL(0xa7a5fc88,0x5cde0035),LL(0x53b8bdc0,0x1c5ce488),L_(0xf9fdf735), + LL(0xa64a20a6,0xd22b7f88),LL(0xa2eb0438,0x0628283c),LL(0x75129c40,0x6efeb06e),L_(0x4f3e44a6), LL(0x76f8c149,0x181e8b58),LL(0xbb830a80,0xc758648a),LL(0x3d1fbafb,0x069f31f1),L_(0xbfff2e03), + LL(0x78f3872d,0xbba94fb7),LL(0x748d4921,0x852ef996),LL(0x48ddef24,0x066ad60c),L_(0xd4ea4021), LL(0xc1ba7360,0x790d395b),LL(0x6901be6e,0x7616ea80),LL(0x61b408b8,0x9278e0eb),L_(0xc7366cae), + LL(0x15c9a850,0xae384504),LL(0xd50ba3bf,0xf4814e2a),LL(0x1b8b0e26,0x2b97a1b4),L_(0x3f0e4245), LL(0x260ef3d1,0x5db22d7e),LL(0xbfd1a5ec,0x2e7c6bf8),LL(0x7c1471d1,0x7bdec3b1),L_(0x079a90a5), + LL(0xb71fd22f,0x7f17f289),LL(0x5e288b65,0xd4564a47),LL(0x34b284d4,0xb75a3120),L_(0x5d8426b1), LL(0x986c8a29,0x197cc0c1),LL(0x29e64b23,0xcc3ae592),LL(0x7da4599c,0x54ebd08e),L_(0xf69dda7d), + LL(0x9addab69,0xbd0c6b5c),LL(0xf7f44578,0x7ec99645),LL(0xaa918115,0x8ee2e6eb),L_(0xd2de3778), LL(0xd9db5cd4,0x2d90dfec),LL(0x5c1253c8,0xf48ec5bb),LL(0x7732d381,0x2daa3783),L_(0x158b18c3), + LL(0x4087fb32,0x64d12677),LL(0xa61b3dc0,0xd6d5d34f),LL(0x5aa57c66,0xeebb82c5),L_(0x01983506), LL(0x0b3a8490,0x4bcc334e),LL(0x347044a3,0xafc73b45),LL(0xbdc15e76,0xba3353c1),L_(0xfc066074), + LL(0x3f49b08a,0xe4f392d0),LL(0x1fda13b1,0xc0bd57d7),LL(0x4a84d25e,0x8b9c3a47),L_(0x9991791e), LL(0x88262b52,0x5d6233aa),LL(0xd1327af9,0x1da165fe),LL(0xba39a0b7,0x56569118),L_(0x22bb8aef), + LL(0x55aff6c4,0xffb26779),LL(0x4e7d53f7,0x581f3f37),LL(0xc259ed17,0x0527ce42),L_(0xb4d8bc18), LL(0xeb967186,0x592962f6),LL(0xf82705f0,0xbc866b81),LL(0x9a5ee9a2,0xb8fcf82b),L_(0x60d27e12), + LL(0x7b7d67a2,0x6bed8eca),LL(0x5d9fc1ee,0x74e18695),LL(0x3ac5ac85,0x4777aaae),L_(0xaf2958be), LL(0xaf83cba9,0x114e541f),LL(0x41b4aa09,0x49c90e0c),LL(0x6ffe97ac,0xd22caea2),L_(0x032a68c3), + LL(0xad0a7c5d,0xcf68be2d),LL(0xe675d930,0x46042df0),LL(0x44cc34c3,0x83baaad0),L_(0x09136a40), LL(0xe5be5f7c,0x232306d2),LL(0xe3f78e95,0x30e3711a),LL(0x7b102ef8,0x90ca6b87),L_(0x25d20cac), + LL(0x24f85c29,0x1c82027d),LL(0x509f2a65,0xc82c4968),LL(0xf294dde1,0xa0dabc8e),L_(0x6fbe2f96), LL(0xeadad60a,0xa2d74908),LL(0x0b27809e,0xea64f015),LL(0x3b0536e3,0x948d4413),L_(0x3ccb3666), + LL(0x4cd8e164,0x7e58fb10),LL(0x2cc3a907,0x3a2788f9),LL(0xc860f6b9,0x673a28d4),L_(0x6f03054c), LL(0xc5e46854,0x62c5a4e9),LL(0x02ecf383,0x059005a0),LL(0x5a617a3d,0x06267ff2),L_(0x6a1a7e0c), + LL(0x2af744e3,0xae8162d5),LL(0xfa2efdc7,0xbe28dd79),LL(0x950dd089,0xcd76243e),L_(0x1c19727b), LL(0x887a306f,0xc5cf5f6e),LL(0x003d3ccd,0x6076457e),LL(0xd58cb75e,0xa5a9063c),L_(0x95f7ccee), + LL(0x6f63cd76,0xa7571852),LL(0x089066c8,0x2ab669d0),LL(0xd42dd087,0xee6f2f6d),L_(0x18dd0fe9), LL(0x0a7d1e21,0xfa5d28f5),LL(0x2b521ac0,0x9441fb8f),LL(0x8466e082,0x4a673507),L_(0xf688bc35), + LL(0x980ae611,0xc6222c7e),LL(0xb1d88568,0x3030f358),LL(0x9b8f42e0,0xbbf50262),L_(0xaa3f5497), LL(0x469ee64f,0x3ef5e0ea),LL(0x167a26ce,0x0e1c1519),LL(0xb57bce91,0x806bb655),L_(0x2f545810), +}, +/* digit=28 base_pwr=2^196 */ +{ + LL(0x4760716f,0x789ae13c),LL(0x1cb72857,0xf578d1e5),LL(0xc6470ce9,0xd42e2969),L_(0xe716d39d), LL(0x5f1cf231,0x733456c6),LL(0x5fef0d2e,0x592bb199),LL(0x91e21ef9,0x8814ad36),L_(0xb248995f), + LL(0xbefb4b7c,0x6eb484b6),LL(0x87780471,0xa01ef7f5),LL(0xdc02e33e,0xf8ac22f1),L_(0x6e5fad2e), LL(0x0cbad015,0xc2d60cca),LL(0x2db33229,0x78a4abdf),LL(0x375f545c,0xbb2518b8),L_(0xe117a7f0), + LL(0xe94cf6d0,0x721159cc),LL(0x2528b498,0xd001dacc),LL(0xba328884,0x6ca68824),L_(0x16db431f), LL(0x857c60d1,0x3e1c1a16),LL(0x06be4963,0x4e3a8a4a),LL(0xe5100cc6,0x2fadd498),L_(0x66deb87b), + LL(0x96e332c2,0xba35b5c5),LL(0x5c8ec408,0x32a3227d),LL(0x3d572604,0x3287caa4),L_(0xde9663da), LL(0xd3d8aa49,0xd8f05722),LL(0x3d0b0ee6,0x211c6e5e),LL(0x789832b8,0xd7095c24),L_(0x057c1df6), + LL(0x8e5e0a09,0xa554b8a7),LL(0xc0ca83b1,0x3cfefa31),LL(0xde9b7d08,0xb712685d),L_(0x890d7a66), LL(0xd942a6e4,0xc242dae3),LL(0x4f659bb9,0x5c2986c0),LL(0xca0a3ad3,0x58984f5a),L_(0xc0f8dce7), + LL(0xbb8f3d67,0x75e4f894),LL(0x305ab1c6,0x597d61ec),LL(0xc5900752,0xbb05ff05),L_(0x6f0cfc37), LL(0x78265563,0x8bb8c320),LL(0x928753a6,0x2afed364),LL(0x9604812d,0x2ecd08d1),L_(0x9f7250a9), + LL(0x4f8511c5,0xf62b6ad5),LL(0x68ca6d7c,0xe0ab6bd5),LL(0x9849b3b9,0x437c1eb4),L_(0xdab12cd3), LL(0x60c66157,0xe2da9ad4),LL(0x81e8b4b4,0xc72b155a),LL(0xe933cc08,0xad7576ea),L_(0x66098ae9), + LL(0x019aa18f,0x06661e71),LL(0x997b0541,0x2a662ce1),LL(0xc9069497,0x5ff8cdb7),L_(0x7c209e40), LL(0x22ef5987,0x62a400b7),LL(0xdcbb6b6a,0xb2915c26),LL(0x1fe38da6,0xffba34b0),L_(0x6f5cedf1), + LL(0x6335b064,0x6133838a),LL(0xe7f5ee57,0x76c52676),LL(0xce767a1c,0x5e465185),L_(0x1464e362), LL(0x93f4d930,0xce0d54ed),LL(0x5d714210,0x742e50db),LL(0xabc94edc,0x78bba80f),L_(0xc86bf6f4), + LL(0x4b83b6ce,0x81b49586),LL(0xa3c55ff8,0x1fa505f0),LL(0xae4acd7d,0x832817ef),L_(0x77814820), LL(0xd6ef9110,0xd59182a2),LL(0xe98e0fd5,0x764ce5bc),LL(0x323e203f,0x63236d14),L_(0x3a8b8995), + LL(0x118cb51a,0x8ea6b928),LL(0x117ab1a0,0x56dd68b6),LL(0x395935d8,0xbd116bcd),L_(0x0a981729), LL(0x5ced4a6c,0xbb4ec3a0),LL(0x569614d1,0x63f4b4af),LL(0x1f24cb4f,0xf9b9d0b1),L_(0x03e53738), + LL(0x18a50233,0x25f531db),LL(0x0389f67e,0x8b3f0f16),LL(0xa0701098,0x6a6aef50),L_(0xa69dbc19), LL(0xfb3a537e,0x8c64961c),LL(0x35b24bda,0x83f4d9b6),LL(0x440a2f19,0x7696fcba),L_(0x9f01b04c), + LL(0xc0f2402c,0x5360ffc2),LL(0x1debf1ae,0x8d33aed5),LL(0x7da3a904,0x4dde5b44),L_(0x0cb2c453), LL(0x6c75adbc,0x0c9938a7),LL(0x11dd5af7,0xf4ef9f5d),LL(0x30114b89,0xbb08ab61),L_(0xc5ca168c), + LL(0xdf042ef8,0x481cae35),LL(0xaab6e2e0,0x6fed557f),LL(0x3de7d914,0xa4e1bcfb),L_(0x7fdaa079), LL(0x85cd2d00,0x4370738c),LL(0xd12da321,0xf95a95e5),LL(0x9814d14c,0xe0fd8dcb),L_(0x32743222), + LL(0xc27ed928,0x655d6ffb),LL(0xde08c413,0x43a4fc18),LL(0xde7270a7,0xcba9f29e),L_(0x06e6cdba), LL(0x2e139df9,0x5cc92d84),LL(0x65a9b95c,0xc5a596a0),LL(0x6a5bdae7,0xd5e4697c),L_(0x5db94611), + LL(0xa1aad672,0xf4cdb11a),LL(0x0a56c5fd,0x35eb1979),LL(0x06b67d2c,0xd3a50661),L_(0x227904a1), LL(0x47a4312a,0x2c80dfe0),LL(0xdec3bab1,0x1e137540),LL(0x2528a436,0x4a30bc3a),L_(0x306505c1), + LL(0xa27429d2,0xac029aa3),LL(0x3ea574fb,0xe555d79c),LL(0xc26117ae,0xeee94c98),L_(0x485edd44), LL(0xb5866e81,0x3b83d3dc),LL(0x6558e1d3,0x497236f4),LL(0xa896a908,0xc1eba30c),L_(0x2a815dd8), + LL(0x0b1d2a89,0x6a45073a),LL(0x2ef3d416,0x72b5edce),LL(0xc7a3b1fe,0xac5268b4),L_(0x5c03d364), LL(0x8589b53a,0x25c0f37d),LL(0x247dcc63,0x8cf1d802),LL(0x9d3fe1d2,0x15093e7c),L_(0xfe72abd8), + LL(0xac83f07d,0x6eba86a7),LL(0xdaf79a6c,0x7769b4ef),LL(0xce08325a,0x306da9b2),L_(0x72e3aed8), LL(0x9fd7086a,0xbe70ef68),LL(0x8bdda042,0x9649ac38),LL(0x59634c20,0x260c709f),L_(0x169d616d), + LL(0xe36b9e36,0x56c9f551),LL(0x8ce0bbd5,0x9a19b344),LL(0x7b1c335b,0xb90484f8),L_(0xcd0b498b), LL(0x0b5ef9ed,0x8c6e220c),LL(0xdabb30f9,0x4ddb2065),LL(0xe5c29249,0x2b898fcc),L_(0xd16ae2eb), + LL(0xb7d4dedd,0x3cc11efc),LL(0x87733216,0xc5d55aae),LL(0xebad4304,0x139832e2),L_(0x6f2f9588), LL(0x0089eb00,0xb6ab35e5),LL(0x143ac48b,0x35af18a2),LL(0x363f80f9,0x8c8c5655),L_(0x8c090d66), + LL(0x3cad20e3,0xd54cc179),LL(0x56fcbabd,0xc7630400),LL(0x8ece816d,0x4347fa49),L_(0x7ff18955), LL(0xe22f3ed7,0x83d72b28),LL(0xa523c18b,0xa89efb1e),LL(0xc07fe6b1,0xf679cfd6),L_(0xb95c3988), + LL(0xdd4159b7,0x90409ff6),LL(0xe0447eff,0x0509d402),LL(0x0d946df5,0x46153d5b),L_(0xe1645594), LL(0x1229cd0f,0x25841f04),LL(0xd79eba33,0x163487eb),LL(0x1f5ac4bb,0x7a894b16),L_(0xd4b696a9), + LL(0xd0fd0fdf,0x95e0fb87),LL(0x316c5da1,0x12d4a0db),LL(0xbac4ce3b,0x4aecb41e),L_(0x07cf2ae4), LL(0xf6b866b3,0xc85cee8f),LL(0x4241c703,0x929c773e),LL(0x22cf7705,0xf90855df),L_(0x6b6a6a3d), + LL(0xb938eef0,0x054fb615),LL(0x8dd3e916,0x7d1ce422),LL(0x624c46af,0xc8279b91),L_(0xfa11e3a9), LL(0x6fc664fc,0x957fa9ea),LL(0x7faaee34,0x86d71f57),LL(0x8216ab5f,0x4fdcf503),L_(0x8f169cac), + LL(0x99acbf60,0xea1c792e),LL(0x995de7af,0x3d4924d1),LL(0x09c0ca0b,0xb94190da),L_(0x95e76a43), LL(0xaccafdf9,0x6c1aa007),LL(0x1f952403,0xe4eccac7),LL(0x07821f33,0x3125c30a),L_(0x56a0a57c), + LL(0x76375e86,0xa2da6002),LL(0x0c8b88d7,0x851663d2),LL(0x903300d5,0xe4304412),L_(0x6111b04d), LL(0xf13f93d7,0xac6cc7e1),LL(0x8ce4d931,0xc233fc51),LL(0xfa884feb,0x889b7699),L_(0xe977a15e), + LL(0x649b4878,0xb98eb821),LL(0xf89766d9,0xda85057c),LL(0xe8c391ca,0xc53a37ec),L_(0x15f269aa), LL(0x3c241d53,0x1c63bf16),LL(0x40246227,0xe6f1e93f),LL(0x882db63a,0xacf7e8f4),L_(0xa54ec9c8), + LL(0xd18b015d,0xf734d021),LL(0x943cb99b,0x62b04fde),LL(0xea71f882,0xe9f4d402),L_(0x4f517e6c), LL(0x3d8f7745,0xad9abc71),LL(0x1fe90081,0x088ad020),LL(0x25dfde15,0x250f4123),L_(0x48badfac), + LL(0xe0e96ead,0x46b7097a),LL(0x2937ebe1,0x19ddbba5),LL(0x3ecd0bd0,0x1b6e3a84),L_(0xaf895097), LL(0xfc22adbf,0xbae23185),LL(0x220a75e9,0x09ed4ed6),LL(0x062eb7e7,0xe1ce81e7),L_(0x8b1103c2), + LL(0x4649146f,0x91702d2f),LL(0xb9f95742,0xbfdaf3ca),LL(0xcf8f23f1,0xd403a4bb),L_(0xf9164036), LL(0x33bbb505,0x5d48ee37),LL(0x2b84d0f7,0x79ec8716),LL(0x5a9ca7a8,0x76092de3),L_(0xec444f35), + LL(0x1f9e6c98,0x17ed7898),LL(0x25820dda,0x668c28ad),LL(0x745aa2ed,0xcf9ce234),L_(0x01a5ca97), LL(0x4a783729,0xbf5955af),LL(0x31ed52ae,0x92891a4a),LL(0xea43a792,0xc67457a9),L_(0x7c0fc898), + LL(0xb8dd47fd,0xff42200e),LL(0x253f7438,0xa70a5da7),LL(0x6cbd4092,0x6d058c66),L_(0xbb3089d5), LL(0x110c3a9a,0x67048ffd),LL(0xa8a2fe2a,0x82fc6b0e),LL(0x30242c32,0xa769318b),L_(0xf0614bb4), + LL(0xbb708cee,0x7620c902),LL(0x084e78c8,0x75832ff6),LL(0x3a89190f,0x4632df7f),L_(0xdade5c0d), LL(0x48e4bd14,0x62dc813c),LL(0x0d15d331,0x9c55f000),LL(0x36a4457f,0xa330078b),L_(0x3b722d3e), + LL(0xc1f3d1aa,0xe37d1ff2),LL(0x5c4d9799,0xed06b0a5),LL(0xb1d3c33d,0x939c8f4c),L_(0x499b0fdd), LL(0xf53390da,0x9e6ebae1),LL(0xb952b38d,0x28276f38),LL(0xd69e1327,0x19f5bac2),L_(0x7c921bee), + LL(0xafd90d24,0x0e84e363),LL(0x37d2a8e9,0xabb80eda),LL(0x07e40274,0x95656580),L_(0x877a2cb3), LL(0xa8a767b1,0xc90af857),LL(0x61a42dc7,0x465bb86d),LL(0xbf658fdd,0x7eb455a7),L_(0xf467f4bf), + LL(0xda192001,0xad70ec43),LL(0x1aa502d0,0xcb55de32),LL(0x7d66c4af,0xa952a38d),L_(0xb6579e71), LL(0xdceb099f,0xed3e0675),LL(0xaf274aa3,0x635a8629),LL(0xb9f4c7da,0x8d6f1c2a),L_(0xf954b1aa), + LL(0x6f166fdd,0x0c46e6e4),LL(0x2f6ebcd8,0x0813e798),LL(0x9066cff4,0x2f759557),L_(0x026ee79d), LL(0xbd44613e,0x06317041),LL(0xc1609f3b,0x6879039a),LL(0x6853d2d8,0x80566bad),L_(0x9a1de27b), + LL(0xd83655d4,0x7c1a0bb8),LL(0x40e36289,0xa5228881),LL(0x00c5e925,0xe9c51c0b),L_(0x17fd5193), LL(0x0234b859,0x9a00e742),LL(0xee8b4f08,0xf774358d),LL(0x0eb69043,0xd46eb256),L_(0xf54e46c1), + LL(0xe386daac,0x9a305482),LL(0xc37330b6,0x7957d9d7),LL(0xf3f52055,0xd1a9ce7b),L_(0x1e870d5e), LL(0x303b5ae9,0xac2ad67a),LL(0x4d3fc2d7,0xb7b58e09),LL(0x7dc5f5f1,0x6c99d250),L_(0x2d7b151a), + LL(0x29507cf5,0x37c15d8e),LL(0x6919a75b,0x738d9ba6),LL(0xeb76b42c,0x0b91ab81),L_(0x3da557ec), LL(0xac1dd9b8,0xb974e300),LL(0x6b8577ca,0xd55b5831),LL(0x9748b154,0xbfcdc886),L_(0xf2e99cba), + LL(0xaa791b19,0xb611f73f),LL(0xe44e650a,0x6fd43d10),LL(0xde586616,0xff2a1da0),L_(0x8983db6a), LL(0x7da57055,0x5051af3a),LL(0x73e374c8,0xa7d98205),LL(0x80c04759,0xd4db7bec),L_(0x28c48bc7), + LL(0x9051c153,0xd36418fc),LL(0xed854f7d,0x2adcc4eb),LL(0xa2d25b82,0xf9315c6a),L_(0x510b53b5), LL(0x6fec476b,0xbdd2e105),LL(0xbc40ed1e,0xdc2bc2a5),LL(0xd473b242,0x9d87dbe8),L_(0xf9d3eb65), + LL(0x4031a20e,0x5001f11c),LL(0x3e83e92e,0x86e3fa8d),LL(0xa7c80719,0x36408819),L_(0x520ab89f), LL(0xaf0e8126,0x430d59f8),LL(0x1479126e,0x5b426c42),LL(0x1c62cb71,0x1a2c3f95),L_(0xba8c53ff), + LL(0x42998c5c,0x9b1ab1ad),LL(0xc5bef946,0xe7ad335b),LL(0xd2f18816,0x9b21d6a9),L_(0x7bf5543b), LL(0x09dc1281,0xc3771787),LL(0x8d9a2927,0x69b13c80),LL(0x5419b128,0x472d8eda),L_(0xce12aaf7), + LL(0xc26aa121,0xb9665455),LL(0x1990f311,0x3bac4cd2),LL(0x4b96b490,0x15632e30),L_(0xb87e9336), LL(0x03c2ca60,0xeac8678b),LL(0x101c2863,0x5772568c),LL(0xbef62c1e,0x3b53ce81),L_(0x7d135e14), + LL(0xbe66a12b,0x753cb0aa),LL(0xd1abe43d,0x38781cdd),LL(0xcf1c41a4,0xab22df0a),L_(0x11b70405), LL(0x7e4c97e5,0x3869cfcb),LL(0x24f71698,0xb43a4e85),LL(0x6ab97c59,0x35c0f24a),L_(0x4df75964), + LL(0x292f0d69,0x3e2b7aaa),LL(0xdafad7ad,0xe2ba5f7a),LL(0x77ff29a4,0xe21d90f9),L_(0x67fec4ee), LL(0xbc0b01d0,0xe3677335),LL(0x26e5157e,0x8fee4b54),LL(0x2b1a301a,0x5d1511ed),L_(0x263f34a8), + LL(0xe5e9578a,0xd73285ea),LL(0xdf28a719,0x2e506fa1),LL(0xecb1a91e,0x79d54bca),L_(0x5a06ac79), LL(0x7bf48ede,0x9f75d7b8),LL(0xa6637969,0x08014deb),LL(0xaf188a86,0xbfada230),L_(0x423dacf9), + LL(0xa63e4dbd,0xe55bd873),LL(0xa80a0320,0xbe01f07e),LL(0x1b09710f,0x6e6cb66a),L_(0x2fee3ce5), LL(0x955bdbc6,0xcecf1493),LL(0x2a3070a3,0x861a0878),LL(0x084d6464,0x0d0e35ed),L_(0xa03afc73), + LL(0xcdca5ed5,0xdb335ec9),LL(0x78cc343c,0xa8df4be9),LL(0xcaea8450,0xf564ec58),L_(0xa5438f08), LL(0xffeefeda,0x193c8457),LL(0x0eaf627b,0xddabba77),LL(0xc99c9580,0xa8ec469f),L_(0xc9ea9e43), + LL(0xf3c9cc69,0xa888f556),LL(0x8951408c,0xaaa99a76),LL(0x79ee145a,0x4760cde2),L_(0xfbdcc6a6), LL(0xd543c51c,0x4d61119d),LL(0x6d5cde8a,0xb57c70b1),LL(0x6d605846,0x8392010f),L_(0x824097f5), + LL(0x79dcc935,0xd988c0b3),LL(0x97a596be,0x66a3883f),LL(0x4cdffd50,0x026d6f1b),L_(0xb093bfc3), LL(0xd01d8fb0,0xc2150428),LL(0x477892be,0x453f0c91),LL(0xff7a816c,0x84b14e80),L_(0xf02eff58), + LL(0xa7823319,0xab4b5d45),LL(0x76a3294f,0x1d9dae80),LL(0xce1d1836,0x1f8f6e55),L_(0x7064e78f), LL(0x8d6bd5d7,0xd272957e),LL(0x20068c6a,0xc59f4815),LL(0x15f1375a,0x1dcaf5b0),L_(0xc01d795e), + LL(0x6c316cb4,0x5f19c736),LL(0x0082a8d7,0x9bb6aded),LL(0xadea31b9,0x1090e65a),L_(0x27c39f72), LL(0xfec08edb,0xad397892),LL(0x2ae66c84,0xb2c262c0),LL(0xe12a0551,0xcd11a65d),L_(0xc52c046e), + LL(0x5db707b6,0xf10d38e7),LL(0x4a3e6c1d,0x5bbaa9f8),LL(0x1692548b,0xa34228d1),L_(0x2ff089a1), LL(0x654e5d42,0xf2342e4d),LL(0xe8e23440,0x53e19ef5),LL(0x254b33f9,0x2609459a),L_(0xd598bc1e), + LL(0x7007f546,0xefba2361),LL(0xe1a42d85,0x72c3ffc2),LL(0x600f4b0f,0x68bfc655),L_(0xf5be3dea), LL(0x13f14da8,0x6efd514e),LL(0xaaab23fd,0xcc761583),LL(0x949da3c4,0xd3524443),L_(0xf07ce5ed), + LL(0xeca99656,0x98853678),LL(0xa45dd69d,0x959586ec),LL(0x2b4d5496,0x882a160e),L_(0x54e92805), LL(0xdf2a1b89,0x52e13aac),LL(0x8f1d99c7,0x4a5dde80),LL(0xc432a9d8,0xcafd8d25),L_(0x801f070d), + LL(0x39455fca,0x0c20053d),LL(0xdaf5e5b7,0x04a4c141),LL(0x14b7b1d1,0x38e2582a),L_(0x51bd8c01), LL(0x20e68184,0xd15dab61),LL(0x1925d2d5,0xba541287),LL(0x62766fdb,0x6619e0a4),L_(0x439e1dd0), + LL(0x3bc818e3,0x746af8f1),LL(0x6be8f43b,0xbbe6fd69),LL(0x53589554,0x446a9ab9),L_(0x0ea769ab), LL(0xc30fa666,0xf4d47c43),LL(0xca3dad1b,0x431ea6ad),LL(0x9dafb227,0x4ff395ed),L_(0xbd3937cc), + LL(0x2c57d4e1,0xa4cceb3e),LL(0xd6667dff,0xff6cbcb5),LL(0x8918c037,0x268bc00c),L_(0x1c4ef107), LL(0xa92f2fb1,0x76415814),LL(0xd31c6973,0x68597539),LL(0x0a6cac9a,0x399773b8),L_(0x87d12cd2), + LL(0x7652379d,0xc59e872e),LL(0x0e493371,0x1fa3657f),LL(0xa77b28fb,0xa7619402),L_(0xeea23b52), LL(0xa85f48bf,0xe180ae18),LL(0x8d4b8437,0x68f2c962),LL(0x3145c6a2,0xe4d30712),L_(0xd9ccc49f), + LL(0xb3ff7311,0x00082b09),LL(0x23fb7431,0x0de3deec),LL(0x33ecf9d4,0xab6cc532),L_(0x8eae9253), LL(0xd8a0ae1c,0x2a618d55),LL(0x97045c63,0x3993ca70),LL(0x0f2549ab,0xcc02ada7),L_(0x14884bad), + LL(0xb5a7fc93,0xec8a7e38),LL(0xfbda890b,0x786e2a85),LL(0x882cb9d7,0x103bbacc),L_(0x17321d75), LL(0x7395bf16,0x4be2ec80),LL(0x20a02de8,0xb287766f),LL(0x4eb9dbc0,0x54c7f36b),L_(0x399d4a59), +}, +/* digit=29 base_pwr=2^203 */ +{ + LL(0x663a8bf6,0xf1bd6f1b),LL(0x6c6b1cae,0x2de2cf35),LL(0x4f49967b,0x49fde755),L_(0xee2050c1), LL(0x9956f1ed,0x69f14061),LL(0x138a98db,0xc5c29863),LL(0x516db87b,0xd4456e50),L_(0xe15ee455), + LL(0x78b8a6b9,0x5019a365),LL(0x0782c606,0x025726c3),LL(0xd611e283,0x68f7b67f),L_(0x9292eb6b), LL(0xb4e7c5d0,0x5ed6c698),LL(0x8f074f3c,0x6ea9c71d),LL(0x2c0dd03d,0x6ad6ab61),L_(0x6c985359), + LL(0xc1c1b8cd,0xa1ea038f),LL(0xd886b019,0x9d8f1f3a),LL(0x5e44aefb,0xbc0d302a),L_(0x8b9ba536), LL(0x47ec400d,0x9049574e),LL(0x02b6e2ef,0x9778ebf4),LL(0xe0adc015,0xe0348d22),L_(0x2f89c060), + LL(0x2b432e4f,0x97be15f2),LL(0x9442eea7,0xfb123347),LL(0x752805f0,0x095f8861),L_(0xbd4f1599), LL(0xe4fd179d,0xbfe10a89),LL(0x8eb30cbd,0xc1a95173),LL(0xb5e94f0f,0x38bffbb7),L_(0xbd72f70b), + LL(0x31d5bf11,0x3b628b52),LL(0x6efe2871,0x9f017556),LL(0x50b6b23f,0x2051232c),L_(0x05744158), LL(0x18b1fb8c,0x58660126),LL(0x6683fda3,0x85343658),LL(0xcdefb5cb,0xee7c02af),L_(0x0c98f701), + LL(0x842b943a,0x79b770df),LL(0x52f1e8f1,0x2ca8d23c),LL(0x29cf116b,0xd89fd3b6),L_(0xae88c948), LL(0x20362fba,0x17dff9f9),LL(0x7048ea42,0xb8350a9e),LL(0xcbd44b83,0x3adbe1f1),L_(0x5fc81426), + LL(0x171138f5,0xd002fd82),LL(0xb9b3d4ff,0xed715f0c),LL(0x14d543b9,0x770fe818),L_(0xc2b33795), LL(0x2c123604,0x3f8f258d),LL(0x22543d13,0xa3564d33),LL(0x9d216804,0x435f77e5),L_(0x97bba91d), + LL(0xabe6aead,0x5e84d762),LL(0x84f02bef,0x538499e7),LL(0x1d74cb44,0xbfb3e36a),L_(0x591a2397), LL(0x198dddb8,0xfcbe1984),LL(0x430a25b9,0xb7b8bbcc),LL(0x80cf7321,0x00ac08de),L_(0x44305966), + LL(0xe8745380,0xbbb4692e),LL(0x9a66429c,0x02f17d1f),LL(0xe7057c36,0xec132fea),L_(0x87b7dbea), LL(0x89b168f8,0x7f9c9480),LL(0xe2d21c13,0xf9e94167),LL(0xf34e2409,0x13e022d0),L_(0xba4bcae2), + LL(0x243d2e97,0x358d9af4),LL(0x518d83d9,0xb47467ae),LL(0x81a7eea1,0x470b2dab),L_(0x37ab475a), LL(0x3d8103c5,0x9a2755c4),LL(0x200b1434,0x9228b07c),LL(0x5b3e4741,0xbc9b37bd),L_(0x8f9c88f6), + LL(0x8739f51d,0x3e9880c9),LL(0x183b3d2a,0xe30595ad),LL(0x9d3ff1f0,0x4b286b55),L_(0x2ffa355d), LL(0x89be0142,0xe2576d49),LL(0xf43534f3,0x00a64de7),LL(0x1e63717f,0x0c898bea),L_(0x338d6967), + LL(0xd89a7c52,0x489bd20b),LL(0x1cbe5fd9,0xe7ac0a68),LL(0xf9bbb011,0xbe7ead5c),L_(0xfdfdaa41), LL(0x5bf6715e,0x2573c5cb),LL(0x71fec319,0x30483451),LL(0x7ccb3fa6,0x0071ca44),L_(0x02bc8a83), + LL(0x83211264,0xd01481a8),LL(0xd292cd9c,0x48c43d0c),LL(0xd5277f78,0x32c5572b),L_(0xb3f946cd), LL(0xb34b30d2,0x780e2016),LL(0x492c55b7,0x43e3806b),LL(0xd4ad90ce,0x97399684),L_(0x2bddb7ec), + LL(0xe410e719,0xb76d2e77),LL(0xaa75746e,0x0df8f582),LL(0x6f7bfcdc,0x210d7777),L_(0xce4ca9a2), LL(0x04ef15f2,0x87836a34),LL(0x77b0ffb3,0x44c267d0),LL(0x2fbcd218,0xbb549183),L_(0x8bf3d46f), + LL(0xa541189d,0x3029c3b6),LL(0xbeb5a06f,0x277c1d19),LL(0x761b9d9e,0xd09fd429),L_(0x189262a3), LL(0x8fe5cbe0,0xf3cbac6c),LL(0x4d675bde,0xcbbe3e5c),LL(0x4dd89b19,0x75e821e8),L_(0xf4cfe02e), + LL(0xf92173f6,0x3b6ebbae),LL(0x66df420a,0x44ad6eda),LL(0x49918d50,0x71e12775),L_(0x6343f5ce), LL(0x7c6c9ea4,0xa76fc6d0),LL(0xde640ea7,0x95bb0f9e),LL(0x0e5cdfb0,0x3505e20d),L_(0x03859db8), + LL(0xc0a26f34,0xf36a466b),LL(0x8087482a,0x769bd94b),LL(0x96b0b77f,0xbaa9cde2),L_(0xe98e1c0a), LL(0x961d12a3,0xe383e51b),LL(0x9d59941b,0xb680bdbd),LL(0xfbf75271,0x1f5805cf),L_(0x13cbe6aa), + LL(0x205ad8c7,0x84ebf013),LL(0xc207bf8a,0xf24e1950),LL(0x749aace4,0xaaf03f06),L_(0x566ca993), LL(0x33c5f5b5,0x378cf813),LL(0xe91d36bf,0x8ac53e4b),LL(0x9b1441f3,0x0113566b),L_(0xb69efcbb), + LL(0x8145a741,0xd10f5321),LL(0x81bb9251,0xe73eb2a7),LL(0x4da9ccbf,0xf35011e6),L_(0xd0a422fb), LL(0x375da80b,0x3b493784),LL(0xac876682,0xe99fa1c1),LL(0xbfcdd019,0xfcd0fffb),L_(0x16d39a14), + LL(0x44724691,0x6169a512),LL(0xf345fdba,0xb54ae1f9),LL(0x97426a68,0x84a843c6),L_(0xc87c52d5), LL(0x57ee464a,0x9fa3b852),LL(0x36872038,0xcf4188dc),LL(0xb9fbee93,0xc6f126b9),L_(0xebc64e1f), + LL(0xa34571ca,0x48662048),LL(0x54bb6dce,0xfa26591d),LL(0xf6f0b8d2,0xc7f51cd9),L_(0x5cfd4a24), LL(0x5bc438cf,0x66200c18),LL(0xc248c469,0xe6f1c95c),LL(0x6844e3a4,0x6e17cd42),L_(0xa72dc6d8), + LL(0xddd1ff7e,0xf244b120),LL(0x431f42e4,0xe6046902),LL(0x40c26687,0x1691fe67),L_(0x30ca7e9b), LL(0x6e105d9d,0x9b50eded),LL(0x961020de,0x00b6a88e),LL(0xe9b08b55,0x4b82631a),L_(0x6cc54fd6), + LL(0x04530c1f,0xf4435606),LL(0xf234709d,0x9b79c17a),LL(0x9f045501,0x839380ae),L_(0x5f60c0b0), LL(0x2d608e32,0x9b83bfd2),LL(0xadf75cc7,0x10db4135),LL(0x22cc1949,0x3a2e7962),L_(0xe3436f2d), + LL(0xec19a27c,0xe5ad9b86),LL(0xb18ea5cf,0xc7d0db50),LL(0xb0a1794d,0x12340a6f),L_(0x2c1d9f6e), LL(0x8bcb0708,0x54438da3),LL(0x032032f2,0x33597066),LL(0x68e9b910,0x192ee4ac),L_(0xdf1723d3), + LL(0x6b3b3e12,0x6076299f),LL(0x49f13a7d,0x210c46f7),LL(0x11bcefd8,0x4c36d81d),L_(0x9b39bf08), LL(0xd49ab219,0xb72e4c99),LL(0x8e53b636,0x0e9348ea),LL(0xa88c581f,0xd67c4ee9),L_(0xa41298b4), + LL(0xe899e96d,0xb64bf9de),LL(0x8d198f03,0x43b5e3ae),LL(0xa7cc5c88,0x656b15b3),L_(0xd2995e8b), LL(0xc5c4e24b,0x112512c6),LL(0x409ca870,0x26ff024e),LL(0xccd67ae6,0x4f8c1dc8),L_(0x22878c0c), + LL(0x95b13b3e,0x9e553300),LL(0x668c95c0,0x7fafd447),LL(0xf8451257,0x6a113d4a),L_(0x1f574c1c), LL(0xedde7f07,0xaf37550f),LL(0xf5868469,0x0b1d7c54),LL(0x69e02d8f,0xcfd6985a),L_(0x9a97854f), + LL(0xecd3e1ab,0xbe482681),LL(0xdc9e0113,0x47798831),LL(0x9fac48a4,0xafbbf20e),L_(0x1edb9dbc), LL(0xd6f1c5bd,0xfe2c6138),LL(0x58a4f161,0xd3d7cf09),LL(0x0fdeccc7,0xa05a2e1d),L_(0xc2e844b9), + LL(0x6b3cd8ad,0xa16dcddd),LL(0xe9387af0,0x0fdf0fc3),LL(0x3cb7db3e,0x5144175e),L_(0xc5aef05c), LL(0xdaa284b1,0xb41e11e0),LL(0xc70c6218,0x334a53c4),LL(0xb6f86d54,0xea0526d6),L_(0xd996408c), + LL(0xef18bf5d,0x268ce667),LL(0xd54a4821,0x70f67533),LL(0xb9cffb18,0xc3038e8d),L_(0xebd042c2), LL(0x29b2c2c4,0x4d1a3a20),LL(0xd6237f1f,0xe2c18664),LL(0x5ab3157b,0x7a60e7b3),L_(0x6be26cfd), + LL(0x1c5c3f1e,0x28e72014),LL(0x5435c35c,0x32068427),LL(0x47c37b5e,0x94c1b6e7),L_(0x0c649b6b), LL(0x5f5b4e72,0x77567891),LL(0x3ebfe7c4,0x55a4f7f1),LL(0xc6f93ff6,0x8f654b8b),L_(0xc6898456), + LL(0x8fa02753,0xfcbae4b8),LL(0x9d98e011,0xcff78948),LL(0x22632d48,0x70d86a48),L_(0x247b98b7), LL(0x00132e50,0x3721a7ea),LL(0xad1058dd,0xdcc00609),LL(0x0c2cbce2,0x38fb42c3),L_(0x574791e5), + LL(0x5ea4abc8,0x5f3751e3),LL(0xaacf3fc1,0xac364b4a),LL(0x495dd3d3,0xa6c1d838),L_(0x7fd58564), LL(0xba68755c,0x465b3970),LL(0xfc76d6ce,0xfe4e336d),LL(0xfc16f7fe,0x2c759722),L_(0x76296d07), + LL(0xdd3a0177,0xcb5a7236),LL(0x9f03a670,0xa2bbecb1),LL(0x1f553745,0x46d5deeb),L_(0xc27cf8e5), LL(0x4c542036,0xa92075fc),LL(0xe9a1424d,0xa99e29eb),LL(0x31176d99,0x7ca41c07),L_(0xd9fd4345), + LL(0x39ce1949,0xbff084c9),LL(0x98f4d791,0x43984570),LL(0x05ef0ee6,0x0a861937),L_(0x4abffe54), LL(0x1288a0c4,0x52997092),LL(0xe85a84ab,0x24210cbe),LL(0xec238c31,0x9e2872c4),L_(0x574f26c0), + LL(0x40fd474b,0x5b8538a3),LL(0x1c70eab8,0x0d208047),LL(0x1cb60ff4,0x761298e8),L_(0xcfbdc26c), LL(0x1b6d4500,0xbcf74593),LL(0x7f1b2563,0x746b2f75),LL(0x679d4dee,0x32233e28),L_(0xdec42565), + LL(0x0c718f1a,0x66cd9b3c),LL(0x18427f69,0x3b3a6f84),LL(0xa9ef5cce,0xca539a7c),L_(0xeb7d5235), LL(0xed44fad8,0x4db83c78),LL(0xc210c701,0x5a9002ed),LL(0x57ef09d7,0x47b485ec),L_(0x27b80c9d), + LL(0xe4537556,0x4cc9c9c5),LL(0xea7854b5,0xec59f90a),LL(0x55f05058,0xaa97605c),L_(0x82a4feeb), LL(0x66f84f5e,0x8c26f4dc),LL(0x51a67be7,0xff1f32e7),LL(0xda9cb1ce,0x92d5f2c4),L_(0x3ef1254f), + LL(0x5ec4e735,0xffb048ed),LL(0x17a4afa4,0xb9ca6eb1),LL(0x4f8b9e40,0x089b9558),L_(0x6e75ba13), LL(0x43e91e89,0xcca4bf58),LL(0xbbaa89ed,0x21a8592f),LL(0x2180b560,0xa9e4e373),L_(0x2a4fdd34), + LL(0x95e834c3,0x85c32c46),LL(0xc68fbf2c,0xad18d468),LL(0xd0c03244,0xf46c7fff),L_(0x8c227e96), LL(0xde2297b6,0x8c32b174),LL(0x6ae73d4a,0x28635d97),LL(0x8b431269,0x47d44429),L_(0x2421faa0), + LL(0x28c78e41,0x93181781),LL(0x2ad021ad,0xcb623c4d),LL(0x98d40a79,0xdda4b06c),L_(0x372dd0c7), LL(0x3b688d0e,0xfe3fd141),LL(0xad24bea1,0xedd15e12),LL(0x3a965d08,0xf3097f75),L_(0x27f71cdb), + LL(0xbda9cc55,0xa6bfe2fa),LL(0x80a54113,0xf02a2f58),LL(0x1b6a851d,0xcb819b77),L_(0x21f5d0c7), LL(0x30780f8f,0x9f0d56af),LL(0xb5d4e624,0xf8a06fec),LL(0x27c807cb,0xb99605d9),L_(0x75a80279), + LL(0x6786d970,0x72255ae1),LL(0xc780fd84,0xc29277a0),LL(0xb9deb14f,0xb01102d2),L_(0xb94bf48a), LL(0x1c8e7e82,0xaf4a6e1a),LL(0x5d7fa22a,0x06c802c5),LL(0x4637b70a,0x21f2e3c1),L_(0x514a3fb5), + LL(0xb4a7c609,0x3a6619c7),LL(0xebdd3a32,0x5deb2376),LL(0x24dd90ec,0x7e94da01),L_(0x6003a0d8), LL(0x3788bd2c,0x80b9433f),LL(0x3d74e532,0xd49fdafa),LL(0x47c8e8f1,0x2be1c836),L_(0xce9e83c2), + LL(0x7f036147,0xf5f17b3f),LL(0x3b99cbce,0x45a7571b),LL(0x4e68fb20,0x68857bb8),L_(0xa10f6fe3), LL(0xa24d2c8d,0x2d13dee5),LL(0x4f9e2b49,0x88581796),LL(0x118e784d,0xf0493f53),L_(0x9d8cddff), + LL(0x58d860e4,0x8971f724),LL(0x316a2d94,0xb4f43e7e),LL(0xb5941f8a,0xb537d4a0),L_(0x5f19914e), LL(0xa327b763,0x0a0d438e),LL(0x5555f01a,0x23118e99),LL(0x2345f880,0xe40f8c30),L_(0x468a1ce3), + LL(0xcbd96a39,0x1197dd6b),LL(0xca22160b,0xb47615a0),LL(0x381bf7e1,0x251a8f8f),L_(0x168d73c5), LL(0xad578808,0x34717cff),LL(0x2bd8024e,0x5fbc83f1),LL(0xa4f9d4fb,0x64b6d093),L_(0xff7fe717), + LL(0xf183d4df,0xf6acf5ed),LL(0x23f4cacf,0x0cc30970),LL(0x181d2aa6,0x53b37c4b),L_(0x96f6cf89), LL(0x2ce916bb,0x38654a56),LL(0x2803be90,0xaba6d625),LL(0x09ca53b2,0xcdfe1968),L_(0x31bb234b), + LL(0x9e6894a9,0xf7c98ba1),LL(0x03ee4c19,0x8e28cba4),LL(0xe28c0250,0xdc432b47),L_(0x6e2b992e), LL(0x52a05294,0xff3120b7),LL(0xbc5f1638,0xd4520461),LL(0x3107ac59,0x92fc422a),L_(0xbc3da988), + LL(0x378db33d,0x1b7e14c2),LL(0xafbf4c3d,0x2e5d4aae),LL(0x536bff4a,0x885f68ab),L_(0xbe062464), LL(0xeaff53c4,0x8ea881df),LL(0xd93248b0,0xce5d6df3),LL(0x037450b2,0x6899f186),L_(0x09a8570d), + LL(0xe8227714,0xb158373d),LL(0x662aa9d1,0x73e5ad11),LL(0x0d1473e2,0x963a9a91),L_(0x5be0c8ec), LL(0x6796b003,0x32ad74a8),LL(0x5b558e5b,0xcad42d90),LL(0xa157eba3,0x64fb791b),L_(0x3c37606f), + LL(0x91b7250c,0xb6fc8bc6),LL(0x88f73c63,0x207504d1),LL(0xa04f258e,0x35b71223),L_(0x9284fb74), LL(0x000189fc,0x8cf221df),LL(0x5e498c73,0xe9692259),LL(0xc7e62afa,0x2482c08d),L_(0x96d697ef), + LL(0xa6fa3a45,0xe579dd13),LL(0x2b0e2ed6,0x8643df69),LL(0x57d9dfb8,0x9f01f782),L_(0x4cb4d8ee), LL(0xb5c2c767,0xbb840380),LL(0x358d384f,0x99e8ca50),LL(0x6c698864,0x31b4df34),L_(0xaa8c271b), + LL(0xfa87a979,0x6e27995c),LL(0xf59ed52f,0xc806a201),LL(0xc065a04b,0x93cff90b),L_(0x37c928f2), LL(0xbb867037,0x9cdfc841),LL(0x4f37a688,0x0a935f1c),LL(0xa9d96eb8,0xc15bd4d8),L_(0x98cebb91), + LL(0xd003f54b,0xa4a49d7a),LL(0xc496b9ae,0xa79d7692),LL(0xa15f7dc6,0xbd4d523d),L_(0x9f46848d), LL(0x6dbfe7b8,0xcc88e7c3),LL(0xcea47678,0x8264318e),LL(0x5e5fd5b2,0x5f2fa1e2),L_(0xe1fd44b0), + LL(0xec0ebc0a,0x1936faf8),LL(0xba06a3b9,0xc8c40d08),LL(0x01dd06de,0x54d85f2a),L_(0x18910c39), LL(0x8e9d926d,0xcbcea653),LL(0xc539056f,0x37d0733f),LL(0x0beb45e4,0x3de7fc81),L_(0xd43f2aa7), + LL(0x3205880a,0x9850a91e),LL(0x913c877e,0x5464c543),LL(0x1452f874,0xb9637ddd),L_(0xa9b45a5d), LL(0x7298be19,0xdf5911d2),LL(0x01fcff9f,0xf6dfd8a8),LL(0x8bb252ea,0x839f8d56),L_(0x14ad8567), + LL(0xc7fe9491,0xa2fc5db9),LL(0x23bc4e41,0x47b2b00a),LL(0x142e5001,0x557178b5),L_(0x7609c04e), LL(0x7281e45d,0x80053d16),LL(0x9af2e131,0x335bfb8a),LL(0x3285f848,0xe9e17269),L_(0xf7e53701), + LL(0xd38c0684,0xd98fa793),LL(0x74f33400,0x14117a61),LL(0x0d3b9c08,0x3e3d6538),L_(0x241aea00), LL(0x374f82ab,0x538b9bf1),LL(0x86a9a615,0x1cc16fb7),LL(0xe0c1bced,0xc0de70fa),L_(0x85b224dc), + LL(0x96448e8a,0x98c48df5),LL(0x5ba1fe76,0x50f58327),LL(0x4770c98e,0x197ced21),L_(0x2ca4f59f), LL(0x1af1733d,0x2bca7ffe),LL(0x003eeda5,0xeac8a367),LL(0x13278f06,0x5dd0431b),L_(0xa00d2f29), + LL(0xa83c536f,0x02379421),LL(0xe322906d,0x218d25f5),LL(0x90caeeec,0xf254a0e4),L_(0x2e6c9704), LL(0x44d824c0,0x0bbdc5a2),LL(0x19e00afb,0x21933c71),LL(0xec2c7cff,0x0a756aae),L_(0x3f239664), + LL(0xd8438b58,0x1d02bb13),LL(0xda3809b5,0x25ef520a),LL(0x3dd8667d,0xe3e22c9e),L_(0x68203ac3), LL(0x0d51408f,0x0227f2bc),LL(0x99baf10d,0x090e4a02),LL(0x2fc23bc1,0xf9171e03),L_(0x3a29ec64), + LL(0x8d85409c,0xd1184135),LL(0x735db311,0xf357dae0),LL(0x7b364c45,0xb9d690d1),L_(0xee21514f), LL(0x0c5f601d,0xcb872f3a),LL(0x2e8ffdf4,0xbccb4f0f),LL(0xf7bfadef,0x9f017f8b),L_(0xb26ea0cc), + LL(0x15442e1d,0x62cd98e6),LL(0x2f59cf2a,0x58dcba94),LL(0x7426c5f8,0x80d0a8cf),L_(0x7c300a9f), LL(0x52648e24,0x3a628b1d),LL(0x1ffce053,0xf0844217),LL(0x9c140c5f,0xb3cc7bfa),L_(0xbb650a75), +}, +/* digit=30 base_pwr=2^210 */ +{ + LL(0xf0426be2,0xb4f44241),LL(0xeb69f614,0xefc43949),LL(0x80845fb2,0x90205f0f),L_(0x29198f5f), LL(0x8a6cba71,0x4345224a),LL(0xfb0f1abd,0xfc80d60b),LL(0x9c7703f2,0x3d5a7643),L_(0x663a913a), + LL(0xe4b299d3,0x79702991),LL(0xdfeaa3f0,0xad58884a),LL(0xff023a31,0x18b5c6ce),L_(0x8cf14303), LL(0x433c5230,0x3e4907b4),LL(0x13551cac,0x3c1c0282),LL(0xe4454779,0xb4df9ee5),L_(0xae0275c5), + LL(0x658675d8,0xdf2f4ac2),LL(0xd8448d41,0xdde660e0),LL(0x50213318,0x64826f9f),L_(0xb76ac409), LL(0xadcc3e46,0xbc26833e),LL(0x508eaf24,0xde547aae),LL(0x619251e2,0xf96f73d1),L_(0x7bcc2806), + LL(0xba3e8f2f,0x728cadb5),LL(0x765732f7,0x0feebd09),LL(0xdb740393,0xdcffa1d6),L_(0xab748823), LL(0xa742cd70,0x549a4fca),LL(0xf07ac1f7,0x3d24aeea),LL(0x426c42e9,0xb67d7f28),L_(0x497b724b), + LL(0x96cc626f,0xd2b3305b),LL(0xab29e4cb,0x355d47d3),LL(0x33f53993,0x960f4207),L_(0xbf71ccbf), LL(0x329378d4,0x1004c020),LL(0x86ffcabb,0xa9117cf0),LL(0x0e5dbd85,0x73f55c21),L_(0xe9de73fd), + LL(0x456357ca,0x1b3ded00),LL(0x47adbb71,0x0f0f2d4f),LL(0x51648f45,0xab4e5da6),L_(0x4659c423), LL(0xe96f0203,0xcb55e2cd),LL(0x74ebdf1a,0x7b3cc4d4),LL(0x0090498b,0xdfb4de74),L_(0xc69c1621), + LL(0xba643590,0x757e6fbb),LL(0x65485c65,0x95336360),LL(0x50d4d37c,0xac96f5a7),L_(0x676d85ce), LL(0x53008bb9,0x33869046),LL(0xf21c0791,0xfb1262f1),LL(0x1e3e57ec,0x407af3f6),L_(0x6c3c72ca), + LL(0x9d6ad458,0x78e956e9),LL(0x46bcbf36,0xb94af545),LL(0x32977879,0xd20f35a3),L_(0x3ba745fd), LL(0x9c65ff22,0x5c8f99f9),LL(0xac6bb14a,0x4ce9a00d),LL(0x307b3d8d,0x798d2cf9),L_(0x9ddb4cad), + LL(0x3b8e6ef6,0xb6ca3273),LL(0x5ade36d2,0xe260b8d0),LL(0x9c66c2a4,0x05eb84cf),L_(0x884d04c5), LL(0xbe1f3ed0,0x1e35adca),LL(0x4cff4e8c,0xa175edc2),LL(0x4681a0ae,0xc6715ff6),L_(0x506a8488), + LL(0xe9c88637,0x32143c93),LL(0xdf482c05,0x434818e2),LL(0x25a929c9,0x4c806ec9),L_(0x1179b4ee), LL(0xfe3e80ad,0xa0372526),LL(0xf64ea692,0x5279eb89),LL(0xee97419a,0x98dbe31d),L_(0xdfad8124), + LL(0xe8bb79d4,0xa6d3938a),LL(0xbdea4fe1,0x0b2f88a1),LL(0xf279df50,0x59a54b2e),L_(0x343b8869), LL(0x1390a7ad,0xc9c37e25),LL(0x9e03f761,0x0777586e),LL(0x3aa2516a,0x42cece95),L_(0x732cba8a), + LL(0xa47e21c2,0x5f9875c7),LL(0x327db722,0x2ecbc86c),LL(0x4ac56066,0x5ea26fc2),L_(0xc69b2d5c), LL(0x31e429d7,0x944c3736),LL(0x7cb051f9,0xcf2fc959),LL(0x02c3927e,0x3bb33cf9),L_(0x5a57d920), + LL(0xcf56d754,0x64f98e4d),LL(0xfbe5a38c,0x1c7766cb),LL(0xb20cfe07,0xe351283a),L_(0xd825af7e), LL(0xdc9dc466,0x3bee62a5),LL(0xe5b281f4,0xb2e1f644),LL(0xfe54699d,0x18ee6ea1),L_(0xe71cfdbc), + LL(0xd2fe136e,0xe5f658a8),LL(0x39fa85ce,0xd83b5473),LL(0x94a1a0d2,0x586d7529),L_(0x208e5f0f), LL(0x0748fda7,0xe98d9b7d),LL(0x869e47b2,0xf0def9e4),LL(0xc4e12cd5,0xf40402da),L_(0xe2e9c40e), + LL(0x2956c763,0x257681d9),LL(0x9408aa0f,0x696e0261),LL(0xfd84ba5b,0x0675debf),L_(0xa7a000fc), LL(0xef9b82a6,0xe38868a1),LL(0x8226a77b,0xcdcdf922),LL(0x292fb9c9,0x269d71d2),L_(0x587c3f9c), + LL(0xb5fae58f,0x55622b3a),LL(0xb3258e77,0xff23a08c),LL(0x56c2b54e,0x866ba05b),L_(0xb8835413), LL(0xa737dae6,0xdc5131fd),LL(0xbcb13de4,0xbb1176e5),LL(0x860b7b0d,0xf51c76d2),L_(0xfc88df27), + LL(0x6bd647f3,0xe811642e),LL(0xf28850fd,0x0776f556),LL(0x2c9fb90d,0xb8cebf02),L_(0xa7ba32f0), LL(0x643fb866,0xc4902b6c),LL(0x3a4ba84e,0x74aac273),LL(0xfd2878e7,0x1a76b1b7),L_(0x4e9ed0a9), + LL(0xf609c0b0,0x0cfea42c),LL(0xc8c86640,0x7a72c3c6),LL(0xb9872dc7,0x1ae5bcf6),L_(0x4967c18a), LL(0x9fe44849,0x2a90f4d7),LL(0x7c9836d4,0xdcdd6bf1),LL(0x32eb5ac2,0x939219ad),L_(0xa85aba1e), + LL(0x267059b7,0x2669c8c4),LL(0x92b26067,0xb6ba656c),LL(0xc80a4182,0xa67b63ae),L_(0xdabf1310), LL(0x7acd503c,0x98520b74),LL(0xa4e52b3f,0x0688ae94),LL(0x47fc66da,0xacf9786e),L_(0x53a32432), + LL(0xde210bb4,0x74430a09),LL(0x341d2f54,0xf0e810c7),LL(0x85cefd4f,0xba1cac0a),L_(0x649747b6), LL(0x35194ff2,0x6452e158),LL(0x3bf68483,0x8ed85e25),LL(0xd8535bc9,0x3bc32918),L_(0x1618b5a8), + LL(0xd3467c73,0x3046a69b),LL(0x11b44c9b,0x996236b5),LL(0xf02f1b90,0xdbce524f),L_(0x2880b5ed), LL(0xdcc369a7,0xa2eda832),LL(0xbc28c7a6,0xcb124909),LL(0x33444c56,0xb4685d00),L_(0xc588ee2f), + LL(0x6fe5a182,0xa316d37d),LL(0x7b8d3ccd,0x75ec9a2a),LL(0x8b98fad0,0x0c5e4465),L_(0x96299b8e), LL(0xbd855a8e,0x7661287b),LL(0x21ef677f,0x9b044bfa),LL(0x0f23ddbb,0x7abd77aa),L_(0x217ef151), + LL(0xe7d89f59,0x490f55aa),LL(0xf4051055,0x3aa72313),LL(0xdea3a145,0x159c120c),L_(0x3a83cdd8), LL(0x840bb947,0x1516983e),LL(0x3c23bffe,0x527c0f73),LL(0x0d4d39e1,0xe3846304),L_(0xa097f7b6), + LL(0x56c53d60,0x8c3176ff),LL(0x95152224,0x26489625),LL(0x94c341e1,0xa5b14d8d),L_(0xe01267c9), LL(0xb4f1f613,0x1a2f793c),LL(0xd1a0049e,0x600ebda3),LL(0x6ba99e2b,0xd1571ee0),L_(0xc34b7e2c), + LL(0x122b663a,0x41a70d6d),LL(0x5102d2ac,0x50c3e831),LL(0x37bdeb4c,0x948ab46f),L_(0x69f45329), LL(0x1a55a55b,0x3b20c1e6),LL(0x22ef8bd8,0x81e5763b),LL(0x4ddc462f,0xffa876e2),L_(0x8337e2e2), + LL(0x62e4c32d,0x7f945839),LL(0x8947b09f,0xa1e798f7),LL(0xfe755aec,0x5524084e),L_(0x72eaa739), LL(0x02c2a9e3,0xdc627b0e),LL(0xc75c26c5,0x7c827c47),LL(0xbcf0b634,0x677ad978),L_(0x31454aa7), + LL(0x74af562d,0x8713ce0f),LL(0xf85d00e9,0x6951ea39),LL(0x23d2ab0f,0x761f3a78),L_(0x1c36b814), LL(0x098fb6b0,0xeb48e791),LL(0x84522286,0x160c9294),LL(0xf1992cc6,0x2ed7be4f),L_(0x48acfd7d), + LL(0x02ad20b2,0x30165084),LL(0x162d53f9,0xb8bee43f),LL(0x67757e6c,0x0eedd6d6),L_(0x00fc0927), LL(0x5acf9124,0x8dee8798),LL(0xa5fd0b77,0xa4c99259),LL(0x9970bc21,0x54e339cf),L_(0x9e45d123), + LL(0x7f335ce0,0x5019bc77),LL(0xcd9df5c6,0x15ce5f7c),LL(0x4f31c43e,0xfa69d995),L_(0xdaf4bdbc), LL(0x1d57d52d,0x20dc7c66),LL(0x1ccb081b,0x01a82796),LL(0xa8fa2376,0x861ac30c),L_(0x519f6c6e), + LL(0x56acbf12,0x7b20a0c7),LL(0x54051bfe,0xbec3d69c),LL(0x5e324e3c,0xd3d97b66),L_(0x5235011b), LL(0xc585e141,0x2b8e18cf),LL(0x3540e46d,0xe0b2513f),LL(0x6e7d6c03,0x7e1a6116),L_(0x9b468e4d), + LL(0x23bf2ce9,0x82122cee),LL(0xa723e8e2,0x318ba203),LL(0xa93e44d4,0xd2180b18),L_(0x643b190c), LL(0xd9d85de9,0xd7d06345),LL(0x0751ebbc,0x5bea35e9),LL(0x952d933c,0x72bd41e8),L_(0x2910ff54), + LL(0x60e9cb5f,0x107232fb),LL(0xd6c371b4,0x004f8683),LL(0xa23e4299,0xefa3c56b),L_(0x8d86e9ba), LL(0xad436904,0xbb576a94),LL(0x9a66d1e1,0xbd78745f),LL(0x3513e3fe,0x4066ae12),L_(0x69b558b0), + LL(0x627d1808,0x7365dc29),LL(0xe9b14b35,0x0dec4459),LL(0x96d5022f,0xf4343e09),L_(0xf65c2fb7), LL(0x00d16dd7,0xeeaa6e35),LL(0xe87ecb3a,0x220f953d),LL(0x91ecc397,0xaf714cd0),L_(0xaea56471), + LL(0x6dd11273,0xce83daf3),LL(0x0a835712,0x6ce5dec2),LL(0xce89d045,0xbafd94a5),L_(0x86e671a6), LL(0x577ca0e1,0x1e36fd91),LL(0x6fe72f1f,0x060d396f),LL(0x729ba81d,0x8b7e4fbb),L_(0xea9c3f32), + LL(0xdbaa1960,0xb43de333),LL(0x030ad3be,0x2ccf4a4e),LL(0x036ff9cf,0xafc236c4),L_(0xe987e57b), LL(0xd7468cbc,0x9a645200),LL(0x61eddc02,0x5b2deae6),LL(0xb553572e,0xd4efa381),L_(0x9dde1eaa), + LL(0xc9536b4b,0x10222aaa),LL(0x6d0e36c2,0x84934c38),LL(0xdf7ca8e3,0x5e5dc148),L_(0x2da86a73), LL(0x4d98778d,0xb7c8140c),LL(0x69fc5568,0x69c09498),LL(0xb0ea1d36,0x7e0cd235),L_(0x6c99f36a), + LL(0xe9443a73,0x94747e78),LL(0x377b44d6,0x2415da80),LL(0xf50cdd9d,0x65d2fa97),L_(0x9d194135), LL(0x3ca31050,0xaf39be74),LL(0x06450aa6,0x0441383f),LL(0x393e3175,0x4e5bd1d4),L_(0xb7244573), + LL(0x70145556,0xc463ec32),LL(0x867b11cf,0x1e5a98cb),LL(0x59b3adf7,0xeb7c80fc),L_(0x0929efbf), LL(0x5234550c,0x4eb610a4),LL(0x7d606935,0xdc8db9ba),LL(0x52106057,0xbc3a065e),L_(0xad60a058), + LL(0x6e360f56,0xee7f7e1c),LL(0x4a514c99,0x7411bd70),LL(0x627a5d54,0xb191903e),L_(0x9d4472f8), LL(0x6bb808ee,0x484c498f),LL(0x110de6ea,0x3cef8b7c),LL(0xcc379eda,0xe1f0ee29),L_(0xcdc2d24b), + LL(0x21a05590,0x2ea40699),LL(0x953235f9,0x057a8486),LL(0x5834fcc4,0xb35b630b),L_(0xef9321a5), LL(0x2d1d0e73,0x6560d0d6),LL(0x4083b1e7,0xeb026a8b),LL(0x4d572129,0x720991c7),L_(0x98865061), + LL(0x657c8db8,0x5e4f7ccd),LL(0x35de8d7a,0x8351fe6b),LL(0xa43443b2,0x48c1ec10),L_(0xdd11de81), LL(0xb376d6e3,0xc77d6dfd),LL(0x73bed5bf,0x0f953512),LL(0xeae9d0a1,0x91a7a744),L_(0xfeb76333), + LL(0x59454f28,0xd2c2004d),LL(0x9f5eebc7,0xacc344aa),LL(0x775a61d7,0x1c186106),L_(0x47a8ab1c), LL(0xdcf00b61,0x4e3f081c),LL(0xbc56bbf8,0xcaa9cad2),LL(0x1e4e523b,0x816a09ca),L_(0x5e9a9445), + LL(0xd468c097,0x86aa5ecf),LL(0x244131ce,0x26d08883),LL(0xe43dffa8,0x6501f291),L_(0xf4cfc564), LL(0x88248cda,0x4711c711),LL(0xf7fb2e43,0xa4245343),LL(0xcfde7c18,0x4111cd00),L_(0x5a68a986), + LL(0x0df3b4b1,0x9cf9b276),LL(0x71920b8d,0x9dd92d6a),LL(0x6444967a,0x5f3bbd8f),L_(0x82870cd4), LL(0x1a4b4821,0x2d798278),LL(0xd460ee52,0xe9681e54),LL(0x0ce3d37c,0x739d5ad5),L_(0x5645ee72), + LL(0xcf20f025,0xf4697953),LL(0x6debfc44,0x789e6af7),LL(0x1050c0c2,0x383c22fa),L_(0x22fd43b3), LL(0x5cc2adcd,0x2ace7063),LL(0x55ea131f,0xf6f6aaf0),LL(0x31c60f20,0x7b350e28),L_(0x9f8df3bf), + LL(0xf49e5f62,0x1a92eddc),LL(0x24db3514,0x365a5041),LL(0xc89ba67e,0xa32fc59f),L_(0x33efcf95), LL(0xdb9db26c,0x09322a72),LL(0xf91f9ca4,0x3fda4216),LL(0xc6c63b34,0xddeb9986),L_(0x9a067f25), + LL(0x77b280f2,0xc18c7395),LL(0x93723817,0x4cd03829),LL(0x37436f93,0x66528f8e),L_(0xeb73448c), LL(0x2dd6704b,0x83b283eb),LL(0xedc8d2d1,0x54972ce7),LL(0xbca75a4c,0xa9f10506),L_(0x91b481a9), + LL(0xee53ff2f,0x5105c866),LL(0x7f1e21b7,0x02b0042d),LL(0x1f9de3bb,0x4f9500fd),L_(0x89fa5ada), LL(0x8cb6dd5d,0xaa04e960),LL(0xb2782218,0xa0112a6f),LL(0xec0e66ff,0xec305363),L_(0x77fc7f14), + LL(0xa014524c,0x400fd142),LL(0x17086d36,0xf02c64c2),LL(0xd9684416,0x8da612c7),L_(0xb46c7e04), LL(0x4e54713c,0x7cde46af),LL(0x0546cc9f,0x8380cc14),LL(0x5013084d,0x80963cc8),L_(0xf957f8d9), + LL(0x6dcbbe49,0x6b6125b6),LL(0x038efe1a,0x67b840bc),LL(0x16c79367,0x570c02ad),L_(0xcb60af87), LL(0x8552cefe,0xa8167ca5),LL(0x5e88a6fd,0x3636e864),LL(0x9c4305d9,0x43d5af7e),L_(0xc9e5c723), + LL(0x413cd65a,0x9c95b00e),LL(0xb0a4ab3f,0x64a28801),LL(0x6ef01bfc,0x858e4b79),L_(0x80657f33), LL(0x113a4fdc,0xd390a92a),LL(0x71a0cef2,0x774c1209),LL(0x63557ff4,0x54e47eaa),L_(0x4ea9a478), + LL(0x27760c7e,0x9e3147b9),LL(0x656b24fd,0xb9bb9711),LL(0x89363a50,0xe852edfe),L_(0x6bf2556d), LL(0x43ee10a6,0x2d6acef6),LL(0x3e9d7e57,0x03fc12e9),LL(0x20890385,0x2d45580b),L_(0x6b8bf1da), + LL(0x4101d170,0xbebb2e76),LL(0x7fdf91ff,0x533638ee),LL(0x05bdd7f6,0x92a0bd39),L_(0x78bac139), LL(0x4c760097,0x81c6243b),LL(0x8d71803c,0x5119eeba),LL(0x049c6a06,0xc410f246),L_(0xa9b7c2f7), + LL(0x51167f9b,0x12be7d2f),LL(0x66cdc913,0xa41ce391),LL(0x0572301a,0x0a761ede),L_(0x2a186fed), LL(0xe5dca065,0x3dad4d6c),LL(0x14733148,0x82d548d7),LL(0x79a33fd1,0x76d2d77b),L_(0x744a660e), + LL(0x77f53015,0xa4c2daab),LL(0x54ae5f2a,0x40a7d787),LL(0x604bbbf3,0xcc41bd91),L_(0x7fe1506d), LL(0x4c6757d5,0xe55da08f),LL(0x38212cd6,0xf50459ca),LL(0xf8d3a03d,0x8252e5cb),L_(0x62160548), + LL(0xaaca1be2,0xb4f7cd9f),LL(0x3012b6d5,0xfae3835d),LL(0xf685dd47,0x6c5b897b),L_(0x3f52f5a3), LL(0x03e5ac2f,0x71afc215),LL(0xdc13191e,0xce6c64cf),LL(0xa1bdc366,0xe59eacca),L_(0x719ce6ba), + LL(0x28e18007,0x428bd7b1),LL(0xba236a3e,0x3bf0eb6c),LL(0x69ce21e0,0xfbe09c69),L_(0x321ac5e5), LL(0xf7c3e583,0x3283bc61),LL(0xaf3a5b06,0x20ead3f8),LL(0x1f935f24,0x3b040b57),L_(0x39549c75), + LL(0xa23c1b85,0x41a0017c),LL(0xc677b960,0xc09598e4),LL(0xffd68469,0x1da39b13),L_(0xdfff7bf9), LL(0xb19fcd21,0xe71a0fa0),LL(0xc987c7de,0x83e812da),LL(0xb605b69d,0x0efdfc84),L_(0xdde3a792), + LL(0x656d6dd1,0x58a3f7d2),LL(0x9e07158a,0x1396fe6b),LL(0x52fddb17,0x39edad21),L_(0xd739977f), LL(0xfb57f56a,0x1072b4e0),LL(0x80c7df0a,0x94372dad),LL(0x0a26aff2,0x88f38fd7),L_(0x5d33e01b), + LL(0x6d4895a4,0xff2438e1),LL(0xa9ba3f6a,0x67f22bee),LL(0x3cfaa48e,0x6bf9fc2b),L_(0x702030cd), LL(0x7b4df30f,0x956e9ec2),LL(0xe0368ebf,0xe6cb0b1b),LL(0xfc98eaec,0x7dbf18a3),L_(0xf5fc22a9), + LL(0xf20afcc9,0x9b4028ed),LL(0x2adb3986,0x4e476a55),LL(0x6bf05b58,0x2b0c488d),L_(0x74de42bf), LL(0x01d3ca75,0xc0d6bd28),LL(0x668206d5,0x95f353c8),LL(0x010298ee,0x034e53ca),L_(0x13b81d0b), + LL(0x80ff52bc,0x50412d11),LL(0x652fe1b8,0xbe2f9f7b),LL(0xe84a58ad,0x83284261),L_(0x905c06a9), LL(0xc605b12c,0x5da82b44),LL(0x2ca210de,0x837f9c22),LL(0x10d656cc,0x454d1413),L_(0x5a580fa0), + LL(0xde3d1dc5,0x6619a39c),LL(0xac6af7d7,0xaaa9723b),LL(0x3910ae67,0x86fdb715),L_(0x4d8f0cf8), LL(0x3782c29b,0x5c35eb01),LL(0xe1483a4f,0x76b4be95),LL(0xdd570ea6,0xf56b5810),L_(0xefb949a7), + LL(0x9ec12516,0x3f080f23),LL(0x108296b6,0xc3509a49),LL(0x08bba00b,0x07998613),L_(0xdc853801), LL(0x5c36ecb3,0x75c6840a),LL(0x73946b3d,0x3e8f5265),LL(0x2c678e3c,0xc7f1cc73),L_(0x284107e6), +}, +/* digit=31 base_pwr=2^217 */ +{ + LL(0x2409728d,0x2d5fd352),LL(0x84897b53,0x28f3cb13),LL(0xee72bd56,0x21c2f494),L_(0xf66c03f3), LL(0xac73118e,0x283e1b56),LL(0x3b39e360,0xf00c3802),LL(0xaa6c7b0a,0xee304f23),L_(0x0dd1d011), + LL(0x5b89b52c,0x433d8d17),LL(0x440ff02f,0xec27bd07),LL(0x49353c25,0xf18b23f5),L_(0xd9e62ddc), LL(0x2c798eed,0x91011438),LL(0x30fcf910,0xfaa77bac),LL(0x6e2db36a,0x2a3b730b),L_(0x3ada8eb1), + LL(0xea09f155,0x18c36c89),LL(0x3ba3b853,0xff1cf2a0),LL(0x1d069cd7,0x672fde0f),L_(0x0a42b710), LL(0xf1f4e5ba,0x86238146),LL(0xabca7963,0xcdc7fd6a),LL(0x00bcd404,0x51a105eb),L_(0xf842633a), + LL(0x348659fb,0x0afc95de),LL(0x4b20153e,0x478c3432),LL(0x1f2f8d2f,0xaa0e8781),L_(0x27294e88), LL(0xbf3811ff,0x526d1fb9),LL(0x9ad871cc,0xf802b4ad),LL(0xf613e178,0xd3df21bc),L_(0xb619f301), + LL(0x40af417a,0x3b133f03),LL(0xb449508f,0x9b5dda1c),LL(0xc2f372b3,0x3948b7d7),L_(0xba404740), LL(0x99028594,0xbcf7e27f),LL(0x96542b58,0x1de8aa5e),LL(0xb2fc7cd3,0xaadbe95a),L_(0xaa07786d), + LL(0xff2c8bea,0x26721264),LL(0x5d2747dd,0xbd6c65e6),LL(0x7f2093a5,0x21e5d488),L_(0x2ff2524c), LL(0xa000a3ed,0x68530945),LL(0xef75ea86,0xd1f6fc3b),LL(0x3f15aab2,0x9b5d8cbb),L_(0xfc18b474), + LL(0x45f74206,0x97a4da7b),LL(0xcc1484f1,0x6d246546),LL(0x819c4b2d,0x8255bc16),L_(0x4605c7b7), LL(0xf9d396e2,0x5502b719),LL(0xfde1aa97,0x8b9b6ca7),LL(0x94965c57,0x3c7a5ffc),L_(0xea93e0d6), + LL(0xc11d6985,0xbad3d4ba),LL(0xb1adc951,0x67c5bea3),LL(0xb82cec9b,0x93b6322c),L_(0x8ae8a415), LL(0x9661c047,0x769c204a),LL(0x31aa2f54,0x35880fdb),LL(0xc215f2cd,0x4f5bf77f),L_(0xe0f608d2), + LL(0x8bce7ed0,0x847b9ee6),LL(0xb2892f4e,0x8cb1f02a),LL(0xfffe0edc,0x62c22364),L_(0xb0229884), LL(0xdcd7d51e,0xa9cd4c50),LL(0x4688d647,0x30edb5dc),LL(0x82ea29e2,0xcc4403d4),L_(0xb78d8b6a), + LL(0xed02ad3b,0x66e7f904),LL(0xdf2ace65,0x2877668a),LL(0xe7bcfa22,0x873070fa),L_(0x3a2466a0), LL(0xf013615c,0x2fe9dfb1),LL(0xe228049a,0x51ff974b),LL(0x56961e83,0xcd87825f),L_(0x0c9c9408), + LL(0x5b989bda,0x2f915297),LL(0xca9c644b,0xcf0387e6),LL(0x80e7dd9f,0x2e7c6dd7),L_(0x4b7f801a), LL(0x861c2ffe,0x1df12d2f),LL(0xe8fd6f24,0x048668bb),LL(0x9b862a1d,0x2b64be2a),L_(0x4dde2a3c), + LL(0x644173f8,0xc3611806),LL(0x23a43a5b,0x78a6d7ad),LL(0xe22b26dd,0x1dd89345),L_(0xfd5f2c34), LL(0xd1587983,0x7692c1c8),LL(0xca1f4a95,0xecf6b1c3),LL(0x0a975fb0,0x0d6babd5),L_(0xc6e6c5b9), + LL(0x4222b0ed,0xb5c91a5b),LL(0x6d847e8b,0x0ec3e064),LL(0x9d0d2af2,0x660e553e),L_(0x0aaf0e60), LL(0xa6329190,0xff1f387c),LL(0x9970f312,0xd795c508),LL(0x67e40e1b,0xdada8e3d),L_(0xe265b2ea), + LL(0x6eb26317,0x4e1593ef),LL(0x12da5305,0x8698f986),LL(0x2d0a715c,0x8e8b3499),L_(0x80e2d2d8), LL(0x0b43672b,0x132c1c9a),LL(0xee8ab3bd,0xfd973660),LL(0xea97e0b3,0x3b811a56),L_(0xbeaaf50d), + LL(0x3edb12e0,0xf66872e6),LL(0xb9ab7a65,0xc41cad86),LL(0x0cfa43fd,0x43f4aa49),L_(0x781ca102), LL(0xcfa7ab7b,0xafd31516),LL(0x061e0da2,0xc78d7ba1),LL(0xea786f69,0x2090d8fa),L_(0xdf64f185), + LL(0x7ee50090,0x28c86852),LL(0xff58b162,0xd4576859),LL(0xc2987502,0xe596765e),L_(0xf8c4c45c), LL(0xfb631b85,0x42aaadd8),LL(0xb6c6bfcd,0xf7d72923),LL(0x2257f5b6,0x260ae885),L_(0x2f0626ed), + LL(0xdb84c9ba,0xdbb13e44),LL(0x7c40add1,0xa7294693),LL(0xc1443c26,0xe02af6c2),L_(0x935cf64d), LL(0x293f667b,0x52bbc8cd),LL(0x5d49c23c,0x7e1de72e),LL(0x6907cdc1,0xf8a9aeab),L_(0x01bb3a0e), + LL(0x3fade183,0xd7401dde),LL(0xa78758f9,0xc85449b6),LL(0xc47549c9,0x6ec51217),L_(0x5c22aa19), LL(0xae146939,0x4bbe9886),LL(0xd2682769,0xee34940f),LL(0x9f320ada,0x4fdf9e41),L_(0xaa18dddb), + LL(0xf506f84a,0xf58881e9),LL(0xe2a44aae,0xd6feb621),LL(0xedfd3c65,0xb163b10b),L_(0xd0eb9a35), LL(0xb8f8a7bc,0xb10b02be),LL(0x2524cc98,0x1e5816c9),LL(0x0ad84066,0x9cd4eb66),L_(0xecbabab5), + LL(0x413431bc,0x9ea4aaec),LL(0x217b55d3,0x135f5f2b),LL(0x9e4519f3,0xd3e6e8f7),L_(0xb072b798), LL(0xfa8179f9,0x318fb330),LL(0xcb83a9f9,0xe0cb106a),LL(0x95e1ca87,0xfb4ce48c),L_(0x87fc571d), + LL(0xf3d74e55,0xb7fb663d),LL(0x3bebc7e0,0x6706a48f),LL(0x7f8a7cfb,0x52d7353d),L_(0x13ea8891), LL(0xc42a9ef4,0x5bd192eb),LL(0xdfeb9aa7,0x2b1ff6c0),LL(0xaa53702a,0x5388fa6f),L_(0x7ee98651), + LL(0x423e53a4,0x0baae890),LL(0x6536911d,0x08234190),LL(0x9bfec6fd,0xc8f4d373),L_(0xd7ec5802), LL(0x119e3477,0x19587b51),LL(0xfac91771,0x1c276e15),LL(0x951dd485,0x98048932),L_(0x04243a3f), + LL(0xbe2d77ea,0x67d742de),LL(0x2df6c417,0x7983fd12),LL(0x7115e508,0xb9406bb8),L_(0xde1f9fde), LL(0xe45eb298,0xdf3a7991),LL(0xa54dc400,0x03ba9fe4),LL(0x25d8f862,0x6ea3053f),L_(0xb145e5fc), + LL(0xefbe9106,0x266e3900),LL(0xb0d74420,0xe042e34e),LL(0xbec6b919,0x5cb15a6f),L_(0x6c16d3f4), LL(0x75686740,0xfe7b7595),LL(0x2204cb17,0x3e67572e),LL(0x2d437dfd,0x03299218),L_(0x2be5d786), + LL(0xc2d6c314,0x3d460901),LL(0x3d26026c,0x591fe51a),LL(0xeb85aa17,0x44d65538),L_(0x015a9b39), LL(0xea596f91,0x48a2f0df),LL(0x8ce8790a,0xc2cabfcf),LL(0x17f7dae8,0x31a2b7ff),L_(0xba200e74), + LL(0xb389e985,0xb19669c8),LL(0xa23e72e7,0x729a4108),LL(0x53062f9c,0x779cbefe),L_(0xde2e49fe), LL(0xa29b29cb,0x6119b4c5),LL(0x0f5a398b,0xeb10107e),LL(0x91c7a000,0xd43d23aa),L_(0xc42c4a03), + LL(0xb2465ace,0x954d5e2a),LL(0x361566cb,0xcc9f7e66),LL(0xa5432c5d,0xd4ffbeb9),L_(0x5d478258), LL(0x686dc22e,0xb3aa6ec4),LL(0x29d8cc0b,0xf9a59b06),LL(0xd8d7140f,0x94e1344f),L_(0xfd56ad11), + LL(0x7dd1f80e,0x241f38ad),LL(0xc4ce241f,0x72ffb97f),LL(0xff97f61b,0xa3d97bc2),L_(0x9c42f7da), LL(0xd4e6e73b,0xb4b19841),LL(0x1c3d7005,0x5fd346b8),LL(0xa14d6ec3,0x366b72b2),L_(0xd6218402), + LL(0xb6fe5b76,0xe3a6e8d3),LL(0x6941f5ec,0x4ed1cc1b),LL(0x9f69a8a4,0xe6f9dbe8),L_(0x8ff4ee20), LL(0xa4d858f0,0x00a65edd),LL(0x30c9c798,0x9733fc57),LL(0xd4ab5744,0x38f910bb),L_(0x08dd1912), + LL(0x338c1ad5,0x4a664d78),LL(0x90d8cb53,0xd6ec4c42),LL(0xaee2829b,0xededd826),L_(0x0c5337aa), LL(0x417e0806,0x2c83b6ff),LL(0xd8bc600c,0x65e85629),LL(0x54ffde80,0x8972a5fc),L_(0x465b9ae3), + LL(0x49c2561b,0xd2b48b48),LL(0x6937dcf3,0x38241d90),LL(0x7dc5afe2,0xc399df03),L_(0x9c6cdf52), LL(0xc98d8a84,0x666e5386),LL(0xb9102fbb,0x33895284),LL(0xb43f7afa,0xb804c149),L_(0xfe016452), + LL(0xd0681519,0x93423c26),LL(0xa105d538,0xc2eabb36),LL(0xea12b99c,0x9297a177),L_(0xb26a7f93), LL(0xddfee3a3,0x4de65e15),LL(0x9a81b364,0x7f3bad80),LL(0xe43ae1fc,0x7af9ba54),L_(0x86e1e8dd), + LL(0x13762e74,0x5afe2e21),LL(0x8fe945bd,0xa21b9a1a),LL(0xd03deaed,0xd498e9f2),L_(0xe67e5384), LL(0x6ae69ee9,0x749eed42),LL(0xdd52d330,0x5f4c63de),LL(0x95aa2f5a,0x890e5e3e),L_(0x3772d05c), + LL(0xdea7e04a,0xbf3bb703),LL(0x449cf48c,0xc64a209c),LL(0xddb56124,0x6858318b),L_(0x25ad4355), LL(0x9e3a0204,0xf0dbd02b),LL(0xa3421c63,0xa216442b),LL(0x5ebba836,0xc0cbf7a0),L_(0x4f9c0d9f), + LL(0x9bdf3b82,0xe5bfa2bd),LL(0x0e12030e,0xef3da843),LL(0x7b3913de,0x107bba5b),L_(0x390841ba), LL(0xda5362ce,0x81eecff8),LL(0x2734c216,0x151060a4),LL(0xd9ea79af,0xe89b5db6),L_(0x2aafd537), + LL(0x310d44fd,0x4509feca),LL(0xa4868c10,0x25aa7253),LL(0xd40c4268,0xa958ef77),L_(0xe8930722), LL(0x5dae221c,0x71fc93e9),LL(0x0095e400,0xc3e3cb95),LL(0x0f45640e,0x6b7cb33b),L_(0xb3ea06da), + LL(0xc74fe8dd,0x8c9ef406),LL(0xaa86860f,0xb6fe758b),LL(0x04aa9cd6,0x4f8b3877),L_(0xdfcc0451), LL(0x9f568192,0x65aed657),LL(0x44ebcd65,0x85d0ebdf),LL(0x7968220e,0x04b5f3d4),L_(0x44142172), + LL(0x275a3076,0x3a2a339d),LL(0x88744d58,0x8a7f68a4),LL(0x5e03cf06,0xd663fea8),L_(0xdffb3ac6), LL(0x83dd1969,0x6151157a),LL(0x18fce4cb,0x620979ba),LL(0x6d82e1aa,0x3ac652d1),L_(0xa3d0c2ce), + LL(0x9f8e323e,0xed2fa4ec),LL(0xf62c31ca,0x554cf5e8),LL(0x14820bd1,0xc72e2e81),L_(0xb42dc3c7), LL(0xe15fa1be,0x5f0c938d),LL(0x0920a90b,0xdf2d997a),LL(0x33617c0a,0x3087e812),L_(0x631962db), + LL(0x7f81aff6,0xd6ea063d),LL(0x1c54d79e,0x631cf97e),LL(0x46b66ca3,0x3bfc14a4),L_(0xa20e2ff9), LL(0x3a379a19,0xaa5dfd05),LL(0x5f4d0392,0xf3af9e8f),LL(0x95b8ff29,0x928c3c53),L_(0x28ae39a9), + LL(0xe65a2e0d,0xa11c784f),LL(0xb5192f99,0xd33e59b1),LL(0x2f4c50c4,0xe15fe3e7),L_(0x30149c86), LL(0xe61d0a03,0xdff24b95),LL(0x2ec9f885,0xd0e84cbb),LL(0xc9c516d5,0xbc6f5dd3),L_(0x71fb6b1e), + LL(0x828d848a,0x55c5a959),LL(0x503ffb7b,0xed8f7fcb),LL(0x2be30973,0x0b24dc92),L_(0x90b2a59f), LL(0xc98877f6,0xd599613c),LL(0xe60dd939,0x43a0bc0a),LL(0x34b1b90a,0xa8edd1ca),L_(0x7ca529dd), + LL(0x126c6d32,0xb92a7bd7),LL(0xda613cbe,0xd9952b27),LL(0xb5f3accf,0xd21fa7b1),L_(0xda44ff77), LL(0x6ac1dedb,0x7d8ef38b),LL(0xc4ea5e03,0x26d207ab),LL(0xc01bf44b,0x58c8cee8),L_(0xb8f1a2b5), + LL(0x5d2a899c,0x94d31b36),LL(0xbc559f35,0x3050256c),LL(0xd6d74149,0xaa4efe0c),L_(0xbc1f929b), LL(0x9b7a733f,0x491dc4d2),LL(0x50e69c58,0x7540af9a),LL(0x358ed8d5,0x17dc58f7),L_(0x5a66b29f), + LL(0xb13a4f20,0x4d20428f),LL(0xd768684c,0xf17077d6),LL(0x27509ac6,0x58852489),L_(0xd30f66cb), LL(0x64ad83d0,0xc965f9f3),LL(0xca2684af,0x9a3903b0),LL(0x2677b45a,0x45839bea),L_(0x2155a76d), + LL(0x6c1eb10d,0x24b30b08),LL(0x4b90dabd,0x44f85d03),LL(0x688bbe3b,0xc74ccccb),L_(0xe4b5c103), LL(0x94d1ce03,0x14d9a43c),LL(0x5f767150,0xc940698c),LL(0xf3a40155,0xefe2f127),L_(0xbf13e662), + LL(0x9378bdc9,0xfbd86f1e),LL(0x50cbdd4e,0x38c7a9cc),LL(0x965226a4,0x434dbb0c),L_(0x83128949), LL(0xb9259729,0xc36bf7c6),LL(0x038090c2,0x0a12f12b),LL(0xb21834ca,0x0134eeee),L_(0xe2621ff2), + LL(0xad55e743,0xa30d570d),LL(0xfb77c395,0xdaaa178b),LL(0x525f0059,0xf38af4e6),L_(0xd340b6fe), LL(0xa001bba0,0xa05f60e2),LL(0x855efc1b,0x701418ea),LL(0xfd38f820,0x27e433c5),L_(0x0fbe1529), + LL(0xcf1f6418,0x3570870f),LL(0x7c6202e0,0x85875e04),LL(0x96e8ab61,0xefc6f006),L_(0xb0d48b1f), LL(0x0206e9ab,0x6f6540da),LL(0x32b7b29f,0x2a1b80df),LL(0x9caa872e,0x895193a8),L_(0xec63127d), + LL(0x40d4de6d,0x288f99a9),LL(0x6835f630,0x74a2cf89),LL(0xad2e6432,0x52ddf73d),L_(0x4185c6dc), LL(0xef978613,0xbb41a387),LL(0x95245fee,0x319f4bf6),LL(0x40e92907,0x9884b224),L_(0xaf8e6385), + LL(0xe2fde7bd,0x282179db),LL(0x7db516ce,0x7897f73f),LL(0x14a26c02,0x07ab717c),L_(0x34d1cdd0), LL(0xb3e012de,0xa65b35a3),LL(0xbb8667e0,0xb888ddc9),LL(0xc0879433,0x8819e222),L_(0xf68b3f79), + LL(0x32acb173,0x9f902cc1),LL(0xda89f30b,0x2ea4f418),LL(0xec378b71,0xd036aa23),L_(0x56712f20), LL(0x0f8fe475,0x3e16c057),LL(0xe703ddb6,0x134bd529),LL(0xee28b685,0x867d1b08),L_(0x0383ba62), + LL(0x49cdbaea,0x5c1f02d0),LL(0xa1775d0a,0xd83d7d9d),LL(0x1b0a0f31,0x2c287cd4),L_(0x80addda6), LL(0xf27c6df8,0x74534873),LL(0x5db066fa,0x5a696a14),LL(0x8118c158,0xfc06292e),L_(0x58371c8a), + LL(0x5e909157,0xbd1a69f7),LL(0xb7d52793,0x703cb9bd),LL(0x5a474912,0xcedd645a),L_(0x56b4d076), LL(0xdeeac8ac,0x2ed53772),LL(0x89595a18,0x5e6b86ab),LL(0xc7b731bc,0x5ce1f8a0),L_(0x03aec3d0), + LL(0xcc023bb6,0xdf3b4492),LL(0x796e6974,0x87e45b7d),LL(0x0ae46dae,0xe1f7eac7),L_(0x5971c51a), LL(0xb2f3733b,0x72718cd2),LL(0x3b6f5116,0x85e9b624),LL(0x626b0871,0xc20aa08f),L_(0x1ce0f83a), + LL(0x44129031,0x8b7e591b),LL(0x5325744a,0xc7753dac),LL(0xf476b49f,0x2fc4d6c3),L_(0xcc7c16ef), LL(0xe26efb19,0x4dd384fc),LL(0xf67b422f,0x478d3760),LL(0xc574295c,0x421851ef),L_(0xbccaa4b1), + LL(0x92253e02,0x5a61d65d),LL(0x6f301322,0xd4924563),LL(0x1e712886,0x2dd1532f),L_(0x3a89196d), LL(0xa3f1deda,0x39cdfbfc),LL(0x039de172,0xb32cde92),LL(0x57960c59,0x40ad0b76),L_(0xafd7ab04), + LL(0x33392ce0,0x52977c85),LL(0xacb473b0,0x147af936),LL(0x6dd913b5,0x4ec4b1c5),L_(0x838148b6), LL(0x699ab1e9,0x438d69df),LL(0xa416d1fe,0xdf94b69f),LL(0xbc60bb02,0x60dae203),L_(0xc32d87da), + LL(0x01cf54f4,0xc3cf28be),LL(0x609058a8,0xfa448ad2),LL(0xf8c1cf70,0x59baadb3),L_(0x67dc813f), LL(0xb0a595fb,0x60b75e6c),LL(0x1cfccbb7,0xb92101cb),LL(0x99833d0b,0x4be8d444),L_(0x91f3954c), + LL(0xedd8aca0,0xcb571bbf),LL(0x7257aad6,0x5a13acc6),LL(0x68203714,0x79914deb),L_(0x895f9c20), LL(0x5c3bbaec,0x211e58cd),LL(0xe9a0fbc0,0xdef6ac5d),LL(0x776cb363,0x93cb4804),L_(0x9678da2d), + LL(0x7d49d5cc,0x55e82125),LL(0xe0e89e2e,0xa13cee1f),LL(0x7e46156a,0x7d7e5719),L_(0xd361d2e2), LL(0x629c9b30,0x5fd28ac1),LL(0x70a24aea,0xdc393f34),LL(0x8ea6f6e3,0x289c68b1),L_(0xd6c4acd1), + LL(0x63596f58,0x31f49f27),LL(0xac40021b,0x7c86680a),LL(0x0b1f95fd,0x02fc0e10),L_(0x0d61fe85), LL(0x8f2843ce,0xca4cab38),LL(0xb53751a2,0xace069ce),LL(0xf56c80ff,0x270d9677),L_(0x9e5b52ac), + LL(0x6352c6f6,0x67e09224),LL(0x626c5d2d,0x5be06f9a),LL(0x14efc35d,0x38c6a0a2),L_(0x7169645d), LL(0xbe2d9aa4,0x6d0b11a9),LL(0x74e4964b,0x6c28404e),LL(0x5538c4c6,0x0af532d8),L_(0xfd9cc6b6), + LL(0x588f5f01,0xb4277028),LL(0xa788dcdd,0x2477f29d),LL(0x5fe5d31d,0x68c2db2a),L_(0xd8503d86), LL(0x2a5ebb9a,0x7b9c3f49),LL(0xc4b2edb7,0xbf734578),LL(0xbf266e3b,0xfe65a7a9),L_(0xc3945496), +}, +/* digit=32 base_pwr=2^224 */ +{ + LL(0xb7478767,0xeaa013ed),LL(0xa2868062,0x1cf3e561),LL(0xe8c99b44,0x142c4251),L_(0xc6f0cb81), LL(0x5ac149fc,0x9c824754),LL(0x8ff9a766,0x6b1233b1),LL(0xb9c09eeb,0xc5afba96),L_(0x95223aa6), + LL(0xb7c40cce,0xbf4d6687),LL(0xc187f375,0x88025f51),LL(0x80c953d4,0xe3dc6d83),L_(0x88d2d1bd), LL(0xb7668ae3,0x50faab59),LL(0x4404c1ec,0x235fc5b5),LL(0xac299c46,0x1378e170),L_(0x5d9a4686), + LL(0xb43ccb68,0x47792f74),LL(0xf564eef4,0x3dbeda1b),LL(0xb688499b,0x5b9b5ea1),L_(0x1e999e2b), LL(0x6f26a9f7,0xc4515542),LL(0xb3ca4e2f,0x8e4ebca0),LL(0x1f557c40,0xd6441259),L_(0x913b210d), + LL(0xea6ea3ca,0xc6c1108f),LL(0x564f45ee,0xcc83bf8e),LL(0x2c30408f,0x7aa17b0c),L_(0x5db1baaa), LL(0x06aed6b0,0xc003650d),LL(0x47b5af33,0x72d853fe),LL(0x66238f2e,0xf46a15a7),L_(0x76de62dc), + LL(0xf16a11ad,0xccc9dc6a),LL(0xb7c36e6e,0x71ab7d63),LL(0x54c72750,0x5a001c63),L_(0x0f8a90df), LL(0x226cb518,0xb6f26d84),LL(0xd8c32b73,0x3fc36946),LL(0x9f9ee30a,0xa1549b9d),L_(0x3080e1f3), + LL(0x4a2b2247,0xa65e1e3b),LL(0x9b2f8a35,0x671cf2f3),LL(0x6b9d08f0,0x162efd24),L_(0x62ae0f9c), LL(0x3316fc3f,0x84ae1987),LL(0x25516058,0x7d0dc886),LL(0xdbe094f5,0xc7b0730d),L_(0xb05c94c3), + LL(0x1bb62b06,0xe8e8411e),LL(0x20b9ca92,0xd192f8c2),LL(0xe45573f0,0xc1f3a5f2),L_(0x4f18bc0e), LL(0x26419175,0x6c1325f6),LL(0xe78ee486,0x2f81e000),LL(0xa91d228e,0x0ff7a9b2),L_(0x694a50a7), + LL(0x88e39d86,0x42262241),LL(0xe249830c,0x3ad07add),LL(0x918fdfa4,0xcb771a46),L_(0xe581c444), LL(0x18ba36b8,0xeb29d84d),LL(0x12fb54ee,0x1383d57f),LL(0xf57833f6,0xfda5e179),L_(0x2c61f244), + LL(0x47af468a,0x6f69c44b),LL(0xeb264605,0x5e4d4f9f),LL(0xd6821d55,0x46eb8384),L_(0xfdb05fbe), LL(0xcdeb889e,0x871d5809),LL(0xb09553d3,0x1029a1da),LL(0x5cf9245d,0x1bcc2546),L_(0x3a614385), + LL(0xfd8a4d1f,0xdb1de26b),LL(0xb08efe49,0x8aa6deaf),LL(0x12fee6da,0x1e010832),L_(0xb6e509a8), LL(0xd9702488,0x9e928c81),LL(0xf87b74dc,0x79014b39),LL(0x844adfba,0xa7623853),L_(0x14e2902c), + LL(0x2e0124e7,0x2b6dbd37),LL(0x0ff6ba21,0xcb4fc42b),LL(0xd7cdda0b,0xd5d8f543),L_(0x9ccc5b69), LL(0x485584af,0xdd6eb7f3),LL(0xbc744924,0x2e41e3f7),LL(0x65859cc9,0xeca30c9e),L_(0xe5e2bdd9), + LL(0xd5f8805e,0x66979e6c),LL(0xb1900794,0x1b2ea5ec),LL(0xf8ebb830,0x416a9eb2),L_(0x10b371a3), LL(0x6e8ad20d,0x15ff6e9d),LL(0x000e2330,0x0865593f),LL(0xee384b9b,0xe0eeda2c),L_(0x783dd95d), + LL(0x642f55b0,0xbfeb8487),LL(0xd5f0f813,0xfa3ad248),LL(0x7145f39b,0xd0f1abf1),L_(0xeb71b58b), LL(0x4defbbd6,0x893a0505),LL(0x52984b68,0xf3e2f26c),LL(0xf54c27a7,0x6f12b38f),L_(0xbfac39e5), + LL(0x5d26514b,0x7cad1aa3),LL(0xdd0afc7e,0x74faf86c),LL(0xfeab4314,0x645cca78),L_(0x5e53697c), LL(0x43f00056,0xb72096cb),LL(0xca87208e,0x7a1950ec),LL(0x071d954a,0x5337fbf2),L_(0xc371272c), + LL(0xb32000f7,0x5f6dea95),LL(0x5afebd30,0xf4446576),LL(0x19091ccf,0x74118cb1),L_(0xccebf405), LL(0x9210256e,0x9aacef2c),LL(0xb3458ddc,0x1ca9b6d7),LL(0xb1ab02c7,0xa870996c),L_(0x89a1b94b), + LL(0x308cbf80,0x552396fc),LL(0xab809f1d,0x7b2fda39),LL(0x4146f800,0xaebf97a3),L_(0xc90e51fe), LL(0x61fb1317,0xf1c9012c),LL(0x3d74201c,0x0142bd07),LL(0x9b191445,0xbab9da1b),L_(0x4bd6ed8b), + LL(0x5e508e4b,0xfa8ca29d),LL(0x2d86d22b,0x27a0f674),LL(0x4cfdd6de,0xee0206bb),L_(0x1e0e0bda), LL(0x978ed51f,0xa6bbc41f),LL(0xb73521ec,0xe52c7866),LL(0x006c7072,0x32478f51),L_(0xb4b93178), + LL(0x217f1203,0x04851e7d),LL(0x8feb118b,0xd7767c08),LL(0x75b3d632,0x4c08238d),L_(0xac7d86c6), LL(0x3858c44f,0xcd97e8ec),LL(0xb74f0fe2,0x62318c46),LL(0x93355b9b,0xe2405794),L_(0x54c12d79), + LL(0xde835c5e,0x92a463c3),LL(0x0228dc25,0x3b10b96a),LL(0x4b4acd48,0x5f5bd93b),L_(0x1c91a329), LL(0xf537b956,0xedc9c8f4),LL(0xc7fcc358,0xf2362c8d),LL(0xe58a0000,0x970cf697),L_(0x2b1ee7ed), + LL(0x8e7b172a,0x882e0b3e),LL(0xb8bd5ea9,0xbf2d6013),LL(0x490fbccd,0xc0848551),L_(0x3ffa1cc7), LL(0x73f7a7d9,0x17b850e8),LL(0x3a53ec82,0xfcc68ded),LL(0x9cbe988b,0x8d09bdd2),L_(0xa3b6e95e), + LL(0x6266d7aa,0x7f0f6292),LL(0x329716ed,0x47c40355),LL(0x1cfc61e3,0x7a59e7d3),L_(0x0ffa8f3d), LL(0xbddfbabc,0x84b7a613),LL(0x36121ac1,0x89396fd0),LL(0x0f5147ce,0x2b7f355a),L_(0xb3193eff), + LL(0x8af99520,0x4d2ceb91),LL(0x15dc69a8,0xcc451e87),LL(0x6d59d3b5,0xc116fdef),L_(0x627d226f), LL(0x79ead74e,0x813a5852),LL(0x5daf904b,0xc12ffcbc),LL(0xcd67731a,0x3fdf17e1),L_(0x2df27ce8), + LL(0x764582de,0xefaccc05),LL(0x640388d0,0x63018ab5),LL(0x6f606211,0x6b706f5e),L_(0xa1c500d6), LL(0x26635840,0x2a01814c),LL(0x8ab7ad6f,0xe29eede6),LL(0x756a8f01,0x10f5f095),L_(0x53630671), + LL(0xa38d34fa,0x591f8fe0),LL(0xf829c6c6,0xc31b8774),LL(0xae2b4a7d,0x55de9380),L_(0xc9c227e7), LL(0x63877738,0x566cf0c3),LL(0xd9750372,0x1ad0462b),LL(0x5c1a2a83,0xcfd11aad),L_(0x2aff32de), + LL(0xbc66bc8f,0x9f39feb3),LL(0x24b329eb,0x21f0dec8),LL(0xd2ff18e6,0x99e3e6c4),L_(0xb398626b), LL(0xcce55b7f,0xf3fabc3c),LL(0xb9a016fd,0x5c869423),LL(0x4f7a9f81,0xc660df04),L_(0xf74d1142), + LL(0x302b25d7,0xfbdef76c),LL(0xb2090c70,0x97f6ff80),LL(0xcc0decf0,0x26e1f975),L_(0x2797ff76), LL(0x4f37e255,0x61eee678),LL(0x51e68a0e,0x6a0d8fc5),LL(0xd84014df,0xb7e3a2d4),L_(0x449bf740), + LL(0xde3d73e8,0x3178216e),LL(0x90f08891,0x2f89efcd),LL(0xdcbe0246,0xb937b3c2),L_(0x557e9fd5), LL(0xacaa30d0,0x7f06975e),LL(0xd99696a9,0x714b6101),LL(0xd23f9579,0xc1321142),L_(0x8d2afa4b), + LL(0x8271dfd1,0x6e2e57bd),LL(0xc1ea81b3,0xec736ab8),LL(0xbcfb4116,0x1cc014d1),L_(0xc3f8311f), LL(0x02178016,0xbcc0c7bd),LL(0x3222341c,0xdf2643e7),LL(0xedc952bb,0x36ab26fe),L_(0xa84ff692), + LL(0xc562a325,0xccd2af21),LL(0x1f595cc1,0x8cbd4ea2),LL(0x9f800082,0x7bbad5e0),L_(0x89fbecab), LL(0xbfd65f55,0xfa87a290),LL(0x24ee0ca1,0xd25d631b),LL(0xe063926d,0x0f3d4539),L_(0xac0263f9), + LL(0x6bf5b025,0x1a63c568),LL(0xbec29ce6,0x7bad1c42),LL(0x62df4304,0x38b54b11),L_(0x2b705d62), LL(0x94995153,0x7f7b64f5),LL(0x35d2b40a,0xd25d1128),LL(0xbdbbd673,0x4703bb51),L_(0x682e3058), + LL(0x2509ad1b,0x9885b7f4),LL(0xc8c1117b,0xf70447a6),LL(0x9bfc053a,0x1b77852c),L_(0xcfb5f714), LL(0x7dc9ba15,0xa43807b7),LL(0xaea633e3,0x02c669a5),LL(0x220e1871,0x991d8093),L_(0x508f55e1), + LL(0xc434b864,0x6c74aee9),LL(0x96d76b48,0x072efeda),LL(0x19982c91,0xac91d19f),L_(0x79df6582), LL(0xbc64a3c7,0xcea49a1b),LL(0x6b3b3cac,0xe25c1282),LL(0x37f9ab3c,0x57709b27),L_(0x404ec7c9), + LL(0x63a0bab8,0xbdede240),LL(0x702a4776,0x8ec0a030),LL(0xbbb0cddc,0xf6b96225),L_(0xbdd56c73), LL(0x3dff08cb,0xf46b51e6),LL(0xac5d2e41,0xfac7173a),LL(0x3f2c5530,0xe5090eda),L_(0x05b966b5), + LL(0x585b98ee,0x4cb0c03a),LL(0x859d7492,0xb6dc9a2c),LL(0x126ee071,0x3331172f),L_(0xa1e73b0d), LL(0xba3aa73a,0x71ac411d),LL(0x6d7dee6b,0x816a4f1a),LL(0xa88c4198,0xe409dbda),L_(0xa924723a), + LL(0xccb6c49e,0xa20ba7c3),LL(0x46da89e3,0x6782fea2),LL(0x83b7b5ce,0xf28c836e),L_(0xa02bd753), LL(0x64f82fd2,0x523afba8),LL(0x3203549e,0x024ddda9),LL(0x65d29391,0x4cec16d6),L_(0xb0187244), + LL(0xaff84dda,0x1594f62b),LL(0x4bbabfdf,0xa8de453c),LL(0xeb65c1b7,0x30a103ff),L_(0x02fb469c), LL(0xf76afad8,0xa91cd374),LL(0x98a39a41,0xa33359fd),LL(0x0b99c0c0,0x9015867f),L_(0x96fc381a), + LL(0xb366fcc8,0xdde98289),LL(0x76693b42,0xe45737f9),LL(0x30c2ee70,0xa6bb364a),L_(0x759a9e66), LL(0xe00c866b,0x8177a004),LL(0x144b5ff3,0x49205953),LL(0x0106e5ac,0x5d4c1327),L_(0x98001111), + LL(0xdebcecc8,0xfdc46d5f),LL(0xc9916314,0xa125951b),LL(0x5633f2c4,0x04c2afc1),L_(0xd17c9349), LL(0xacd14df9,0xb5f970f1),LL(0x289012ed,0x0973ccd0),LL(0x236b3580,0x02b2c84a),L_(0x76b898cf), + LL(0xcb13811d,0x0d2dd5a3),LL(0x23f6e444,0xd8b5d0f6),LL(0x4f399d9a,0xa46887b9),L_(0x77c6bce8), LL(0x10165161,0xddf54326),LL(0xeb345000,0xf080be9b),LL(0xeee34275,0x047237fe),L_(0xd518ca88), + LL(0x11fceb12,0xfaf4fbdf),LL(0x116a3791,0x66bfd60d),LL(0x442c2a46,0x28cf0358),L_(0x85546f76), LL(0x4cebfe25,0x6c01d714),LL(0x1c79b699,0x11d66f5a),LL(0x8cc29c26,0xcf7771ef),L_(0x92ae8875), + LL(0xf90d16bf,0xb89933d4),LL(0xa1457028,0xc8f0695e),LL(0x5a6af165,0x82274dbf),L_(0x89528271), LL(0x225b8bb3,0x5e138d61),LL(0x2eed19b9,0x3e2273d0),LL(0x6b42f9f3,0xaa4b331c),L_(0xe7d915a6), + LL(0xa9d80f3e,0x6773ac5a),LL(0xc52d7955,0x970b6066),LL(0x78700052,0x2f129047),L_(0xa9a60bf2), LL(0x0393eefb,0x04368569),LL(0xe6519a05,0x5180fe6e),LL(0x3014d2a0,0x6bd99185),L_(0xb28fcd33), + LL(0x299011de,0xe9270a23),LL(0x5a66907e,0x54a9528a),LL(0x7af57c36,0x8e613981),L_(0xe6775c8b), LL(0xff5fc082,0xd7dd7f17),LL(0xe0568a5c,0x421cb6c4),LL(0x590b13ce,0x8f9e6852),L_(0x4c77050e), + LL(0x6513f9c9,0xd5bf1a5d),LL(0x170fc778,0x1942fc9b),LL(0x6ec5f13f,0x70273957),L_(0x1878fa8e), LL(0x5bb80bbc,0xcededd82),LL(0x83d79890,0xa7c7ee32),LL(0xfa06b05d,0x86a8080f),L_(0x0e66721a), + LL(0x9510adb1,0x8a998afb),LL(0x7aa85880,0xfaf28d30),LL(0x0863e4f3,0xdcf64ed3),L_(0x1fe9103e), LL(0x1ea72a10,0x78d5ce7b),LL(0x33edcfdb,0xafe82b0c),LL(0xde25a969,0x1f0a50fe),L_(0x5f4147d4), + LL(0x3d5e21a2,0xddb5610d),LL(0x8024cc9b,0x435cd0ff),LL(0xcc34b698,0xf7218db6),L_(0xb6949149), LL(0xc23a0cb8,0x3b787bdf),LL(0x18dd349c,0x71fcc010),LL(0xb0e2a897,0xd6c69c33),L_(0x09bc9f85), + LL(0x1cd5d5db,0xe94a402b),LL(0xf30b7314,0x26944f05),LL(0x737d6c5b,0xd0af2018),L_(0xfdbedbb6), LL(0x1b523221,0xa8a984b3),LL(0x8ace709d,0x39663eef),LL(0xbf4b3e0e,0x0297dfd1),L_(0x3e1d52f4), + LL(0xc8d20d14,0xf915a4c4),LL(0x0b7dd701,0x2921fb0f),LL(0x6b467b73,0x226421aa),L_(0xf53a0a69), LL(0xf4bdad8d,0xb5512d8c),LL(0xc103b145,0x2df92000),LL(0x4979cf5a,0xd5159856),L_(0x0d121a5d), + LL(0xffb25429,0xad4ff433),LL(0xe3c5fc0a,0x22c48ae5),LL(0xdcdd2832,0xee468cb2),L_(0x853d6571), LL(0xad56cbbd,0x1ac2be8d),LL(0x305ea1a5,0x11bdfbf2),LL(0x4c080ea0,0xd326fcc1),L_(0x98961d03), + LL(0x3c2a21b3,0x4c900a2e),LL(0x370aac6c,0x540b6e6c),LL(0x40c9b00d,0xf0db08ca),L_(0xd9b48af0), LL(0x75ea8b19,0x23e0167d),LL(0x69f68546,0x3ce76be7),LL(0xc2578bd9,0x274ef866),L_(0xe0f171b1), + LL(0x06e96b08,0xa0cc2074),LL(0x658170a1,0x2181d377),LL(0xbc50ac87,0x46b62277),L_(0xd2d87843), LL(0x66a073ef,0xbc771f86),LL(0xef91a0af,0x4727577f),LL(0xa7216ad9,0xd3c1c667),L_(0x3c62c22f), + LL(0x37e5b8f5,0xfea02084),LL(0x4baddc8e,0xe9a5f0b7),LL(0xbf587847,0x53933d2b),L_(0xca648fb8), LL(0x492b64e4,0x8257b251),LL(0x0f117e6d,0x8d9ec843),LL(0xfe9686a0,0xeeea3972),L_(0xe386bb0a), + LL(0xb93a8f56,0xf5712604),LL(0xa696fd94,0x6981acc8),LL(0xf73a981c,0x86cc6e25),L_(0x53db10f5), LL(0xa6c75879,0x18cf2a94),LL(0xe6e2104d,0x5737dd4f),LL(0x4c1f9f0e,0x3114afeb),L_(0x2e6f8e44), + LL(0xbbc2c60f,0x19e92b39),LL(0x06b78031,0xb3de20d1),LL(0x43d40348,0x693597af),L_(0x1396fecd), LL(0xa7c941f2,0x4568fdc8),LL(0xd45e157f,0x92d2afec),LL(0x50493b74,0xa510adc1),L_(0x64794afe), + LL(0x60867e2f,0xab4d38b7),LL(0xf04773c1,0x0b8a018e),LL(0x2c774449,0xc11883d8),L_(0xd65b4aa4), LL(0xa50bce8a,0x9bcfd81b),LL(0xfd058e49,0xf5811bc4),LL(0x80f1e9c2,0xe9b876e5),L_(0xc8fc1b3c), + LL(0x368a0742,0x7cf8b51b),LL(0x09e82684,0x85f0eb37),LL(0xb5926249,0x08e70a34),L_(0x4decfe48), LL(0xe9a1940e,0x4d61fee9),LL(0x6dcb9563,0x24af91e7),LL(0xa85a5970,0x41f4907d),L_(0x2292e826), + LL(0x33182546,0x7b2ef570),LL(0xb4417ce0,0x2a780100),LL(0x8d1180df,0xab954cb9),L_(0x5c74a302), LL(0x88d81acf,0x0d62a965),LL(0x2ec9496d,0xaa16f924),LL(0x2bc7cca4,0x2d99dcc8),L_(0x74958dce), + LL(0xb139570a,0x21c56351),LL(0x1f26d583,0x41b20f4e),LL(0x067af3fb,0xbd9ab15f),L_(0xc3a77e33), LL(0x1523f3e0,0x9de5e7e4),LL(0xe1731bb7,0xef0cf37e),LL(0x6c9e48d4,0xc9fc2851),L_(0xd0f91844), + LL(0xb81124f1,0xea0ed825),LL(0x788a57ed,0xf4f08526),LL(0x8e19f5c1,0x820a4f79),L_(0x348a1346), LL(0x6eaedecc,0xefe607bc),LL(0x87c20db0,0x75968ada),LL(0x21596aa9,0xcdf9ca14),L_(0x5e2abcad), + LL(0xdaef28c3,0x2be4550b),LL(0x29e6daee,0xee673998),LL(0x8162c783,0x4e1fb36c),L_(0xb3249498), LL(0xab7e3386,0xb682150c),LL(0x89285111,0x02a0814e),LL(0x9c692620,0x3bb22aea),L_(0xa759126d), + LL(0xa03f91a6,0xd356a2bd),LL(0x7b288f41,0x04625b59),LL(0xf350f847,0x2eacfb01),L_(0x943dbfd9), LL(0x63af93f5,0xba005c26),LL(0xdcc822a7,0x7964a6f8),LL(0xc56edb4d,0x14b146d7),L_(0xb1fb9d62), + LL(0xcae5ffde,0x51fbb8f7),LL(0xca0c3f68,0xa961e967),LL(0xbe43f447,0x2a774b0b),L_(0x9b6effff), LL(0x4e174bf0,0xb12fde0a),LL(0xd1976ab8,0x85b59e4e),LL(0x421eac26,0x4c480a51),L_(0x4041c2d8), + LL(0xc3a1a863,0xfe8ceef6),LL(0x42e96299,0x0469540a),LL(0xd231a2a4,0x0828f4c0),L_(0x7c0edcf4), LL(0x2c034efb,0x1744d906),LL(0x92393260,0x2a85a8d6),LL(0x28f5775a,0x58717292),L_(0x37693735), + LL(0xf12dc792,0xbcc5e464),LL(0xfee1ef55,0xb881c818),LL(0x2bfca9a4,0x7e60531f),L_(0xed54d832), LL(0x28ea4ef0,0x9ef6ada6),LL(0xb9564865,0xf56fbcf0),LL(0x534e2057,0x9857c41f),L_(0x2750bbe8), +} +}; +#endif + +#endif /* _DISABLE_ECP_224R1_HARDCODED_BP_TBL_ */ +#endif /* _IPP_DATA */ + + +IPP_OWN_DEFN (const cpPrecompAP*, gfpec_precom_nistP224r1_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 7, + /* select function */ p224r1_select_ap_w7, + /* precomputed data */ (BNU_CHUNK_T*)ec_p224r1_precomputed + }; + return &t; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpp256r1precomca.c b/plugin/ippcp/library/src/sources/ippcp/pcpp256r1precomca.c new file mode 100644 index 000000000..b7fc21be6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpp256r1precomca.c @@ -0,0 +1,2540 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (P256r1 precomputed) +// +// +*/ +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +#define OPERAND_BITSIZE (256) +#define LEN_P256 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* P256 affine point */ +typedef struct{ + BNU_CHUNK_T X[LEN_P256]; + BNU_CHUNK_T Y[LEN_P256]; +} P256_POINT_AFFINE; + +extern const __ALIGN64 P256_POINT_AFFINE ec_p256r1_precomputed[37][64]; + + +#if defined( _IPP_DATA ) + +#if !defined(_DISABLE_ECP_256R1_HARDCODED_BP_TBL_) +/* see ippcp_baseptbl.cpp test for generation details */ + +const __ALIGN64 P256_POINT_AFFINE ec_p256r1_precomputed[37][64] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0x18a9143c,0x79e730d4),LL(0x5fedb601,0x75ba95fc),LL(0x77622510,0x79fb732b),LL(0xa53755c6,0x18905f76), LL(0xce95560a,0xddf25357),LL(0xba19e45c,0x8b4ab8e4),LL(0xdd21f325,0xd2e88688),LL(0x25885d85,0x8571ff18), + LL(0x10ddd64d,0x850046d4),LL(0xa433827d,0xaa6ae3c1),LL(0x8d1490d9,0x73220503),LL(0x3dcf3a3b,0xf6bb32e4), LL(0x61bee1a5,0x2f3648d3),LL(0xeb236ff8,0x152cd7cb),LL(0x92042dbe,0x19a8fb0e),LL(0x0a5b8a3b,0x78c57751), + LL(0x4eebc127,0xffac3f90),LL(0x087d81fb,0xb027f84a),LL(0x87cbbc98,0x66ad77dd),LL(0xb6ff747e,0x26936a3f), LL(0xc983a7eb,0xb04c5c1f),LL(0x0861fe1a,0x583e47ad),LL(0x1a2ee98e,0x78820831),LL(0xe587cc07,0xd5f06a29), + LL(0x46918dcc,0x74b0b50d),LL(0xc623c173,0x4650a6ed),LL(0xe8100af2,0x0cdaacac),LL(0x41b0176b,0x577362f5), LL(0xe4cbaba6,0x2d96f24c),LL(0xfad6f447,0x17628471),LL(0xe5ddd22e,0x6b6c36de),LL(0x4c5ab863,0x84b14c39), + LL(0xc45c61f5,0xbe1b8aae),LL(0x94b9537d,0x90ec649a),LL(0xd076c20c,0x941cb5aa),LL(0x890523c8,0xc9079605), LL(0xe7ba4f10,0xeb309b4a),LL(0xe5eb882b,0x73c568ef),LL(0x7e7a1f68,0x3540a987),LL(0x2dd1e916,0x73a076bb), + LL(0x3e77664a,0x40394737),LL(0x346cee3e,0x55ae744f),LL(0x5b17a3ad,0xd50a961a),LL(0x54213673,0x13074b59), LL(0xd377e44b,0x93d36220),LL(0xadff14b5,0x299c2b53),LL(0xef639f11,0xf424d44c),LL(0x4a07f75f,0xa4c9916d), + LL(0xa0173b4f,0x0746354e),LL(0xd23c00f7,0x2bd20213),LL(0x0c23bb08,0xf43eaab5),LL(0xc3123e03,0x13ba5119), LL(0x3f5b9d4d,0x2847d030),LL(0x5da67bdd,0x6742f2f2),LL(0x77c94195,0xef933bdc),LL(0x6e240867,0xeaedd915), + LL(0x9499a78f,0x27f14cd1),LL(0x6f9b3455,0x462ab5c5),LL(0xf02cfc6b,0x8f90f02a),LL(0xb265230d,0xb763891e), LL(0x532d4977,0xf59da3a9),LL(0xcf9eba15,0x21e3327d),LL(0xbe60bbf0,0x123c7b84),LL(0x7706df76,0x56ec12f2), + LL(0x264e20e8,0x75c96e8f),LL(0x59a7a841,0xabe6bfed),LL(0x44c8eb00,0x2cc09c04),LL(0xf0c4e16b,0xe05b3080), LL(0xa45f3314,0x1eb7777a),LL(0xce5d45e3,0x56af7bed),LL(0x88b12f1a,0x2b6e019a),LL(0xfd835f9b,0x086659cd), + LL(0x9dc21ec8,0x2c18dbd1),LL(0x0fcf8139,0x98f9868a),LL(0x48250b49,0x737d2cd6),LL(0x24b3428f,0xcc61c947), LL(0x80dd9e76,0x0c2b4078),LL(0x383fbe08,0xc43a8991),LL(0x779be5d2,0x5f7d2d65),LL(0xeb3b4ab5,0x78719a54), + LL(0x6245e404,0xea7d260a),LL(0x6e7fdfe0,0x9de40795),LL(0x8dac1ab5,0x1ff3a415),LL(0x649c9073,0x3e7090f1), LL(0x2b944e88,0x1a768561),LL(0xe57f61c8,0x250f939e),LL(0x1ead643d,0x0c0daa89),LL(0xe125b88e,0x68930023), + LL(0xd2697768,0x04b71aa7),LL(0xca345a33,0xabdedef5),LL(0xee37385e,0x2409d29d),LL(0xcb83e156,0x4ee1df77), LL(0x1cbb5b43,0x0cac12d9),LL(0xca895637,0x170ed2f6),LL(0x8ade6d66,0x28228cfa),LL(0x53238aca,0x7ff57c95), + LL(0x4b2ed709,0xccc42563),LL(0x856fd30d,0x0e356769),LL(0x559e9811,0xbcbcd43f),LL(0x5395b759,0x738477ac), LL(0xc00ee17f,0x35752b90),LL(0x742ed2e3,0x68748390),LL(0xbd1f5bc1,0x7cd06422),LL(0xc9e7b797,0xfbc08769), + LL(0xb0cf664a,0xa242a35b),LL(0x7f9707e3,0x126e48f7),LL(0xc6832660,0x1717bf54),LL(0xfd12c72e,0xfaae7332), LL(0x995d586b,0x27b52db7),LL(0x832237c2,0xbe29569e),LL(0x2a65e7db,0xe8e4193e),LL(0x2eaa1bbb,0x152706dc), + LL(0xbc60055b,0x72bcd8b7),LL(0x56e27e4b,0x03cc23ee),LL(0xe4819370,0xee337424),LL(0x0ad3da09,0xe2aa0e43), LL(0x6383c45d,0x40b8524f),LL(0x42a41b25,0xd7663554),LL(0x778a4797,0x64efa6de),LL(0x7079adf4,0x2042170a), + LL(0x0bc6fb80,0x808b0b65),LL(0x3ffe2e6b,0x5882e075),LL(0x2c83f549,0xd5ef2f7c),LL(0x9103b723,0x54d63c80), LL(0x52a23f9b,0xf2f11bd6),LL(0x4b0b6587,0x3670c319),LL(0xb1580e9e,0x55c4623b),LL(0x01efe220,0x64edf7b2), + LL(0xd53c5c9d,0x97091dcb),LL(0xac0a177b,0xf17624b6),LL(0x2cfe2dff,0xb0f13975),LL(0x6c7a574e,0xc1a35c0a), LL(0x93e79987,0x227d3146),LL(0xe89cb80e,0x0575bf30),LL(0x0d1883bb,0x2f4e247f),LL(0x3274c3d0,0xebd51226), + LL(0x56ada97a,0x5f3e51c8),LL(0x8f8b403e,0x4afc964d),LL(0x412e2979,0xa6f247ab),LL(0x6f80ebda,0x675abd1b), LL(0x5e485a1d,0x66a2bd72),LL(0x8f4f0b3c,0x4b2a5caf),LL(0x1b847bba,0x2626927f),LL(0x0502394d,0x6c6fc7d9), + LL(0xa5659ae8,0xfea912ba),LL(0x25e1a16e,0x68363aba),LL(0x752c41ac,0xb8842277),LL(0x2897c3fc,0xfe545c28), LL(0xdc4c696b,0x2d36e9e7),LL(0xfba977c5,0x5806244a),LL(0xe39508c1,0x85665e9b),LL(0x6d12597b,0xf720ee25), + LL(0xd2337a31,0x8a979129),LL(0x0f862bdc,0x5916868f),LL(0x5dd283ba,0x048099d9),LL(0xfe5bfb4e,0xe2d1eeb6), LL(0x7884005d,0x82ef1c41),LL(0xffffcbae,0xa2d4ec17),LL(0x8aa95e66,0x9161c53f),LL(0xc5fee0d0,0x5ee104e1), + LL(0xc135b208,0x562e4cec),LL(0x4783f47d,0x74e1b265),LL(0x5a3f3b30,0x6d2a506c),LL(0xc16762fc,0xecead9f4), LL(0xe286e5b9,0xf29dd4b2),LL(0x83bb3c61,0x1b0fadc0),LL(0x7fac29a4,0x7a75023e),LL(0xc9477fa3,0xc086d5f1), + LL(0x2f6f3076,0x0fc61135),LL(0xe3912a9a,0xc99ffa23),LL(0xd2f8ba3d,0x6a0b0685),LL(0xe93358a4,0xfdc777e8), LL(0x35415f04,0x94a787bb),LL(0x4d23fea4,0x640c2d6a),LL(0x153a35b5,0x9de917da),LL(0x5d5cd074,0x793e8d07), + LL(0x2de45068,0xf4f87653),LL(0x9e2e1f6e,0x37c7a7e8),LL(0xa3584069,0xd0825fa2),LL(0x1727bf42,0xaf2cea7c), LL(0x9e4785a9,0x0360a4fb),LL(0x27299f4a,0xe5fda49c),LL(0x71ac2f71,0x48068e13),LL(0x9077666f,0x83d0687b), + LL(0x15d02819,0x6d3883b2),LL(0x40dd9a35,0x6d0d7550),LL(0x1d2b469f,0x61d7cbf9),LL(0x2efc3115,0xf97b232f), LL(0xb24bcbc7,0xa551d750),LL(0x88a1e356,0x11ea4949),LL(0x93cb7501,0x7669f031),LL(0xca737b8a,0x595dc55e), + LL(0xd837879f,0xa4a319ac),LL(0xed6b67b0,0x6fc1b49e),LL(0x32f1f3af,0xe3959933),LL(0x65432a2e,0x966742eb), LL(0xb4966228,0x4b8dc9fe),LL(0x43f43950,0x96cc6312),LL(0xc9b731ee,0x12068859),LL(0x56f79968,0x7b948dc3), + LL(0xed1f8008,0x61e4ad32),LL(0xd8b17538,0xe6c9267a),LL(0x857ff6fb,0x1ac7c5eb),LL(0x55f2fb10,0x994baaa8), LL(0x1d248018,0x84cf14e1),LL(0x628ac508,0x5a39898b),LL(0x5fa944f5,0x14fde97b),LL(0xd12e5ac7,0xed178030), + LL(0x97e2feb4,0x042c2af4),LL(0xaebf7313,0xd36a42d7),LL(0x084ffdd7,0x49d2c9eb),LL(0x2ef7c76a,0x9f8aa54b), LL(0x09895e70,0x9200b7ba),LL(0xddb7fb58,0x3bd0c66f),LL(0x78eb4cbb,0x2d97d108),LL(0xd84bde31,0x2d431068), + LL(0x172ccd1f,0x4b523eb7),LL(0x30a6a892,0x7323cb28),LL(0xcfe153eb,0x97082ec0),LL(0xf2aadb97,0xe97f6b6a), LL(0xd1a83da1,0x1d3d393e),LL(0x804b2a68,0xa6a7f9c7),LL(0x2d0cb71e,0x4a688b48),LL(0x40585278,0xa9b4cc5f), + LL(0xcb66e132,0x5e5db46a),LL(0x0d925880,0xf1be963a),LL(0x0317b9e2,0x944a7027),LL(0x48603d48,0xe266f959), LL(0x5c208899,0x98db6673),LL(0xa2fb18a3,0x90472447),LL(0x777c619f,0x8a966939),LL(0x2a3be21b,0x3798142a), + LL(0x3298b343,0xb4241cb1),LL(0xb44f65a1,0xa3a14e49),LL(0x3ac77acd,0xc5f4d6cd),LL(0x52b6fc3c,0xd0288cb5), LL(0x1c040abc,0xd5cc8c2f),LL(0x06bf9b4a,0xb675511e),LL(0x9b3aa441,0xd667da37),LL(0x51601f72,0x460d45ce), + LL(0x6755ff89,0xe2f73c69),LL(0x473017e6,0xdd3cf7e7),LL(0x3cf7600d,0x8ef5689d),LL(0xb1fc87b4,0x948dc4f8), LL(0x4ea53299,0xd9e9fe81),LL(0x98eb6028,0x2d921ca2),LL(0x0c9803fc,0xfaecedfd),LL(0x4d7b4745,0xf38ae891), + LL(0xc5e3a3d8,0xd8c5fccf),LL(0x4079dfbf,0xbefd904c),LL(0xfead0197,0xbc6d6a58),LL(0x695532a4,0x39227077), LL(0xdbef42f5,0x09e23e6d),LL(0x480a9908,0x7e449b64),LL(0xad9a2e40,0x7b969c1a),LL(0x9591c2a4,0x6231d792), + LL(0x0f664534,0x87151456),LL(0x4b68f103,0x85ceae7c),LL(0x65578ab9,0xac09c4ae),LL(0xf044b10c,0x33ec6868), LL(0x3a8ec1f1,0x6ac4832b),LL(0x5847d5ef,0x5509d128),LL(0x763f1574,0xf909604f),LL(0xc32f63c4,0xb16c4303), + LL(0x7ca23cd3,0xb6ab2014),LL(0xa391849d,0xcaa7a5c6),LL(0x75678d94,0x5b0673a3),LL(0xdd303e64,0xc982ddd4), LL(0x5db6f971,0xfd7b000b),LL(0x6f876f92,0xbba2cb1f),LL(0x3c569426,0xc77332a3),LL(0x570d74f8,0xa159100c), + LL(0xdec67ef5,0xfd16847f),LL(0x233e76b7,0x742ee464),LL(0xefc2b4c8,0x0b8e4134),LL(0x42a3e521,0xca640b86), LL(0x8ceb6aa9,0x653a0190),LL(0x547852d5,0x313c300c),LL(0x6b237af7,0x24e4ab12),LL(0x8bb47af8,0x2ba90162), + LL(0xa8219bb7,0x3d5e58d6),LL(0x1b06c57f,0xc691d0bd),LL(0xd257576e,0x0ae4cb10),LL(0xd54a3dc3,0x3569656c), LL(0x94cda03a,0xe5ebaebd),LL(0x162bfe13,0x934e82d3),LL(0xe251a0c6,0x450ac0ba),LL(0xdd6da526,0x480b9e11), + LL(0x8cce08b5,0x00467bc5),LL(0x7f178d55,0xb636458c),LL(0xa677d806,0xc5748bae),LL(0xdfa394eb,0x2763a387), LL(0x7d3cebb6,0xa12b448a),LL(0x6f20d850,0xe7adda3e),LL(0x1558462c,0xf63ebce5),LL(0x620088a8,0x58b36143), + LL(0x4d63c0ee,0x8a2cc3ca),LL(0x0fe948ce,0x51233117),LL(0x222ef33b,0x7463fd85),LL(0x7c603d6c,0xadf0c7dc), LL(0xfe7765e5,0x0ec32d3b),LL(0xbf380409,0xccaab359),LL(0x8e59319c,0xbdaa84d6),LL(0x9c80c34d,0xd9a4c280), + LL(0xa059c142,0xa9d89488),LL(0xff0b9346,0x6f5ae714),LL(0x16fb3664,0x068f237d),LL(0x363186ac,0x5853e4c4), LL(0x63c52f98,0xe2d87d23),LL(0x81828876,0x2ec4a766),LL(0xe14e7b1c,0x47b864fa),LL(0x69192408,0x0c0bc0e5), + LL(0xb82e9f3e,0xe4d7681d),LL(0xdf25e13c,0x83200f0b),LL(0x66f27280,0x8909984c),LL(0x75f73227,0x462d7b00), LL(0xf2651798,0xd90ba188),LL(0x36ab1c34,0x74c6e18c),LL(0x5ef54359,0xab256ea3),LL(0xd1aa702f,0x03466612), + LL(0x2ed22e91,0x624d6049),LL(0x6f072822,0x6fdfe0b5),LL(0x39ce2271,0xeeca1115),LL(0xdb01614f,0x98100a4f), LL(0xa35c628f,0xb6b0daa2),LL(0xc87e9a47,0xb6f94d2e),LL(0x1d57d9ce,0xc6773259),LL(0x03884a7b,0xf70bfeec), + LL(0xed2bad01,0x5fb35ccf),LL(0x1da6a5c7,0xa155cbe3),LL(0x30a92f8f,0xc2e2594c),LL(0x5bfafe43,0x649c89ce), LL(0xe9ff257a,0xd158667d),LL(0xf32c50ae,0x9b359611),LL(0x906014cf,0x4b00b20b),LL(0x89bc7d3d,0xf3a8cfe3), + LL(0x248a7d06,0x4ff23ffd),LL(0x878873fa,0x80c5bfb4),LL(0x05745981,0xb7d9ad90),LL(0x3db01994,0x179c85db), LL(0x61a6966c,0xba41b062),LL(0xeadce5a8,0x4d82d052),LL(0xa5e6a318,0x9e91cd3b),LL(0x95b2dda0,0x47795f4f), + LL(0xd55a897c,0xecfd7c1f),LL(0xb29110fb,0x009194ab),LL(0xe381d3b0,0x5f0e2046),LL(0xa98dd291,0x5f3425f6), LL(0x730d50da,0xbfa06687),LL(0x4b083b7f,0x0423446c),LL(0xd69d3417,0x397a247d),LL(0x387ba42a,0xeb629f90), + LL(0xd5cd79bf,0x1ee426cc),LL(0x946c6e18,0x0032940b),LL(0x57477f58,0x1b1e8ae0),LL(0x6d823278,0xe94f7d34), LL(0x782ba21a,0xc747cb96),LL(0xf72b33a5,0xc5254469),LL(0xc7f80c81,0x772ef6de),LL(0x2cd9e6b5,0xd73acbfe), + LL(0x49ee90d9,0x4075b5b1),LL(0xa06e9eba,0x785c339a),LL(0xabf825e0,0xa1030d5b),LL(0xa42931dc,0xcec684c3), LL(0xc1586e63,0x42ab62c9),LL(0x5ab43f2b,0x45431d66),LL(0x55f7835d,0x57c8b2c0),LL(0xc1b7f865,0x033da338), + LL(0xcaa76097,0x283c7513),LL(0x36c83906,0x0a624fa9),LL(0x715af2c7,0x6b20afec),LL(0xeba78bfd,0x4b969974), LL(0xd921d60e,0x220755cc),LL(0x7baeca13,0x9b944e10),LL(0x5ded93d4,0x04819d51),LL(0x6dddfd27,0x9bbff86e), + LL(0x77adc612,0x6b344130),LL(0xbbd803a0,0xa7496529),LL(0x6d8805bd,0x1a1baaa7),LL(0x470343ad,0xc8403902), LL(0x175adff1,0x39f59f66),LL(0xb7d8c5b7,0x0b26d7fb),LL(0x529d75e3,0xa875f5ce),LL(0x41325cc2,0x85efc7e9), + LL(0x1ff6acd3,0x21950b42),LL(0x53dc6909,0xffe70484),LL(0x28766127,0xff4cd0b2),LL(0x4fb7db2b,0xabdbe608), LL(0x5e1109e8,0x837c9228),LL(0xf4645b5a,0x26147d27),LL(0xf7818ed8,0x4d78f592),LL(0xf247fa36,0xd394077e), + LL(0x488c171a,0x0fb9c2d0),LL(0x13685278,0xa78bfbaa),LL(0xd5b1fa6a,0xedfbe268),LL(0x2b7eaba7,0x0dceb8db), LL(0x9ae2b710,0xbf9e8089),LL(0xa4449c96,0xefde7ae6),LL(0xcc143a46,0x43b7716b),LL(0xc3628c13,0xd7d34194), + LL(0x3b3f64c9,0x508cec1c),LL(0x1e5edf3f,0xe20bc0ba),LL(0x2f4318d4,0xda1deb85),LL(0x5c3fa443,0xd20ebe0d), LL(0x73241ea3,0x370b4ea7),LL(0x5e1a5f65,0x61f1511c),LL(0x82681c62,0x99a5e23d),LL(0xa2f54c2d,0xd731e383), + LL(0x83445904,0x2692f36e),LL(0xaf45f9c0,0x2e0ec469),LL(0xc67528b7,0x905a3201),LL(0xd0e5e542,0x88f77f34), LL(0x5864687c,0xf67a8d29),LL(0x22df3562,0x23b92eae),LL(0x9bbec39e,0x5c27014b),LL(0x9c0f0f8d,0x7ef2f226), + LL(0x546c4d8d,0x97359638),LL(0x92f24679,0x5f9c3fc4),LL(0xa8c8acd9,0x912e8bed),LL(0x306634b0,0xec3a318d), LL(0xc31cb264,0x80167f41),LL(0x522113f2,0x3db82f6f),LL(0xdcafe197,0xb155bcd2),LL(0x43465283,0xfba1da59), + LL(0xb212cf53,0xa0425b8e),LL(0xf8557c5f,0x4f2e512e),LL(0x25c4d56c,0xc1286ff9),LL(0xee26c851,0xbb8a0fea), LL(0xe7d6107e,0xc28f70d2),LL(0xe76265aa,0x7ee0c444),LL(0x1d1936b1,0x3df277a4),LL(0xea9595eb,0x1a556e3f), + LL(0xe7305683,0x258bbbf9),LL(0x07ef5be6,0x31eea5bf),LL(0x46c814c1,0x0deb0e4a),LL(0xa7b730dd,0x5cee8449), LL(0xa0182bde,0xeab495c5),LL(0x9e27a6b4,0xee759f87),LL(0x80e518ca,0xc2cf6a68),LL(0xf14cf3f4,0x25e8013f), + LL(0x7e8d7a14,0x8fc44140),LL(0x9556f36a,0xbb1ff3ca),LL(0x14600044,0x6a844385),LL(0x7451ae63,0xba3f0c4a), LL(0x1f9af32a,0xdfcac25b),LL(0xb1f2214b,0x01e0db86),LL(0xa4b596ac,0x4e9a5bc2),LL(0x026c2c08,0x83927681), + LL(0x7acaca28,0x3ec832e7),LL(0xc7385b29,0x1bfeea57),LL(0xfd1eaf38,0x068212e3),LL(0x6acf8ccc,0xc1329830), LL(0x2aac9e59,0xb909f2db),LL(0xb661782a,0x5748060d),LL(0xc79b7a01,0xc5ab2632),LL(0x00017626,0xda44c6c6), + LL(0xa7ea82f0,0xf26c00e8),LL(0xe4299aaf,0x99cac80d),LL(0x7ed78be1,0xd66fe3b6),LL(0x648d02cd,0x305f725f), LL(0x623fb21b,0x33ed1bc4),LL(0x7a6319ad,0xfa70533e),LL(0xbe5ffb3e,0x17ab562d),LL(0x56674741,0x06374994), + LL(0x5c46aa8e,0x69d44ed6),LL(0xa8d063d1,0x2100d5d3),LL(0xa2d17c36,0xcb9727ea),LL(0x8add53b7,0x4c2bab1b), LL(0x15426704,0xa084e90c),LL(0xa837ebea,0x778afcd3),LL(0x7ce477f8,0x6651f701),LL(0x46fb7a8b,0xa0624998), + LL(0xed8a6e19,0xdc1e6828),LL(0x4189d9c7,0x33fc2336),LL(0x671c39bc,0x026f8fe2),LL(0xbc6f9915,0xd40c4ccd), LL(0xf80e75ca,0xafa135bb),LL(0x22adff2c,0x12c651a0),LL(0x4f51ad96,0xc40a04bd),LL(0xbbe4e832,0x04820109), + LL(0x7f4c04cc,0x3667eb1a),LL(0xa9404f84,0x59556621),LL(0x7eceb50a,0x71cdf653),LL(0x9b8335fa,0x994a44a6), LL(0xdbeb9b69,0xd7faf819),LL(0xeed4350d,0x473c5680),LL(0xda44bba2,0xb6658466),LL(0x872bdbf3,0x0d1bc780), + LL(0xa1962f91,0xe535f175),LL(0xed58f5a7,0x6ed7e061),LL(0x2089a233,0x177aa4c0),LL(0xe539b413,0x0dbcb03a), LL(0xbb32e38e,0xe3dc424e),LL(0x6806701e,0x6472e5ef),LL(0x814be9ee,0xdd47ff98),LL(0x35ace009,0x6b60cfff), + LL(0x9ff91fe5,0xb8d3d931),LL(0xf0518eed,0x039c4800),LL(0x9182cb26,0x95c37632),LL(0x82fc568d,0x0763a434), LL(0x383e76ba,0x707c04d5),LL(0x824e8197,0xac98b930),LL(0x91230de0,0x92bf7c8f),LL(0x40959b70,0x90876a01), + LL(0x05968b80,0xdb6d96f3),LL(0x089f73b9,0x380a0913),LL(0xc2c61e01,0x7da70b83),LL(0x569b38c7,0x95fb8394), LL(0x80edfe2f,0x9a3c6512),LL(0x8faeaf82,0x8f726bb9),LL(0x78424bf8,0x8010a4a0),LL(0x0e844970,0x29672044), +}, +/* digit=1 base_pwr=2^7 */ +{ + LL(0x7a2ad62a,0x63c5cb81),LL(0xac62ff54,0x7ef2b6b9),LL(0xb3ad9db5,0x3749bba4),LL(0x46d5a617,0xad311f2c), LL(0xc2ff3b6d,0xb77a8087),LL(0x367834ff,0xb46feaf3),LL(0x75d6b138,0xf8aa266d),LL(0xec008188,0xfa38d320), + LL(0x696946fc,0x486d8ffa),LL(0xb9cba56d,0x50fbc6d8),LL(0x90f35a15,0x7e3d423e),LL(0xc0dd962c,0x7c3da195), LL(0x3cfd5d8b,0xe673fdb0),LL(0x889dfca5,0x0704b7c2),LL(0xf52305aa,0xf6ce581f),LL(0x914d5e53,0x399d49eb), + LL(0x6ec293cd,0x380a496d),LL(0x8e7051f5,0x733dbda7),LL(0xb849140a,0x037e388d),LL(0x5946dbf6,0xee4b32b0), LL(0xcae368d1,0xb1c4fda9),LL(0xfdb0b2f3,0x5001a7b0),LL(0x2e3ac46e,0x6df59374),LL(0x39b3e656,0x4af675f2), + LL(0x39949296,0x44e38110),LL(0x361db1b5,0x5b63827b),LL(0x206eaff5,0x3e5323ed),LL(0xc21f4290,0x942370d2), LL(0xe0d985a1,0xf2caaf2e),LL(0x7239846d,0x192cc64b),LL(0xae6312f8,0x7c0b8f47),LL(0x96620108,0x7dc61f91), + LL(0xc2da7de9,0xb830fb5b),LL(0x0ff8d3be,0xd0e643df),LL(0x188a9641,0x31ee77ba),LL(0xbcf6d502,0x4e8aa3aa), LL(0x9a49110f,0xf9fb6532),LL(0x2dd6b220,0xd18317f6),LL(0x52c3ea5a,0x7e3ced41),LL(0x7d579c4a,0x0d296a14), + LL(0xed4c3717,0x35d6a53e),LL(0x3d0ed2a3,0x9f8240cf),LL(0xe5543aa5,0x8c0d4d05),LL(0xdd33b4b4,0x45d5bbfb), LL(0x137fd28e,0xfa04cc73),LL(0xc73b3ffd,0x862ac6ef),LL(0x31f51ef2,0x403ff9f5),LL(0xbc73f5a2,0x34d5e0fc), + LL(0x08913f4f,0xf2526820),LL(0xeac93d95,0xea20ed61),LL(0x6ca6b26c,0x51ed38b4),LL(0xea4327b0,0x8662dcbc), LL(0x725d2aaa,0x6daf295c),LL(0x8e52dcda,0xbad2752f),LL(0x0b17dacc,0x2210e721),LL(0xd51e8232,0xa37f7912), + LL(0x44cc3add,0x4f7081e1),LL(0x87be82cf,0xd5ffa1d6),LL(0x0edd6472,0x89890b6c),LL(0x3ed17863,0xada26e1a), LL(0x63483caa,0x276f2715),LL(0x2f6077fd,0xe6924cd9),LL(0x0a466e3c,0x05a7fe98),LL(0xb1902d1f,0xf1c794b0), + LL(0x82a8042c,0xe5213688),LL(0xcd278298,0xd931cfaf),LL(0xf597a740,0x069a0ae0),LL(0xeb59107c,0x0adbb3f3), LL(0x5eaa8eb8,0x983e951e),LL(0x11b48e78,0xe663a8b5),LL(0x8a03f2c5,0x1631cc0d),LL(0x11e271e2,0x7577c11e), + LL(0x08369a90,0x33b2385c),LL(0x190eb4f8,0x2990c59b),LL(0xc68eac80,0x819a6145),LL(0x2ec4a014,0x7a786d62), LL(0x20ac3a8d,0x33faadbe),LL(0x5aba2d30,0x31a21781),LL(0xdba4f565,0x209d2742),LL(0x55aa0fbb,0xdb2ce9e3), + LL(0x168984df,0x8cef334b),LL(0x33879638,0xe81dce17),LL(0x263720f0,0xf6e6949c),LL(0xf593cbec,0x5c56feaf), LL(0xfde58c84,0x8bff5601),LL(0x2eccb314,0x74e24117),LL(0x4c9a8a78,0xbcf01b61),LL(0x544c9868,0xa233e35e), + LL(0x8bd7aff1,0xb3156bf3),LL(0x1d81b146,0x1b5ee4cb),LL(0xd628a915,0x7ba1ac41),LL(0xfd89699e,0x8f3a8f9c), LL(0xa0748be7,0x7329b9c9),LL(0xa92e621f,0x1d391c95),LL(0x4d10a837,0xe51e6b21),LL(0x4947b435,0xd255f53a), + LL(0xf1788ee3,0x07669e04),LL(0xa86938a2,0xc14f27af),LL(0xe93a01c0,0x8b47a334),LL(0xd9366808,0xff627438), LL(0xca2a5965,0x7a0985d8),LL(0xd6e9b9b3,0x3d9a5542),LL(0x4cf972e8,0xc23eb80b),LL(0x4fdf72fd,0x5c1c33bb), + LL(0x74a86108,0x0c4a58d4),LL(0xee4c5d90,0xf8048a8f),LL(0xe86d4c80,0xe3c7c924),LL(0x056a1e60,0x28c889de), LL(0xb214a040,0x57e2662e),LL(0x37e10347,0xe8c48e98),LL(0x80ac748a,0x87742862),LL(0x186b06f2,0xf1c24022), + LL(0x5f74040a,0xac2dd4c3),LL(0xfceac957,0x409aeb71),LL(0x55c4ec23,0x4fbad782),LL(0x8a7b76ec,0xb359ed61), LL(0xed6f4a60,0x12744926),LL(0x4b912de3,0xe21e8d7f),LL(0xfc705a59,0xe2575a59),LL(0xed2dbc0e,0x72f1d4de), + LL(0xeb7926b8,0x3d2b24b9),LL(0xcdbe5509,0xbff88cb3),LL(0xe4dd640b,0xd0f399af),LL(0x2f76ed45,0x3c5fe130), LL(0x3764fb3d,0x6f3562f4),LL(0x3151b62d,0x7b5af318),LL(0xd79ce5f3,0xd5bd0bc7),LL(0xec66890f,0xfdaf6b20), + LL(0x6063540c,0x735c67ec),LL(0xe5f9cb8f,0x50b259c2),LL(0x3f99c6ab,0xb8734f9a),LL(0xa3a7bc85,0xf8cc13d5), LL(0xc5217659,0x80c1b305),LL(0x4ec12a54,0xfe5364d4),LL(0x681345fe,0xbd87045e),LL(0x582f897f,0x7f8efeb1), + LL(0xd5923359,0xe8cbf1e5),LL(0x539b9fb0,0xdb0cea9d),LL(0x49859b98,0x0c5b34cf),LL(0xa4403cc6,0x5e583c56), LL(0xd48185b7,0x11fc1a2d),LL(0x6e521787,0xc93fbc7e),LL(0x05105b8b,0x47e7a058),LL(0xdb8260c8,0x7b4d4d58), + LL(0x46eb842a,0xe33930b0),LL(0x7bdae56d,0x8e844a9a),LL(0x13f7fdfc,0x34ef3a9e),LL(0x636ca176,0xb3768f82), LL(0x4e09e61c,0x2821f4e0),LL(0xa0c7cddc,0x414dc3a1),LL(0x54945fcd,0xd5379437),LL(0xb3555ff1,0x151b6eef), + LL(0x6339c083,0xb31bd613),LL(0xdfb64701,0x39ff8155),LL(0xe29604ab,0x7c3388d2),LL(0xa6b10442,0x1e19084b), LL(0xeccd47ef,0x17cf54c0),LL(0x4a5dfb30,0x89693385),LL(0x47daf9f6,0x69d023fb),LL(0x7d91d959,0x9222840b), + LL(0x803bac62,0x439108f5),LL(0x379bd45f,0x0b7dd91d),LL(0xca63c581,0xd651e827),LL(0x509c104f,0x5c5d75f6), LL(0x1f2dc308,0x7d5fc738),LL(0xd98454be,0x20faa7bf),LL(0xa517b031,0x95374bee),LL(0x642692ac,0xf036b9b1), + LL(0x39842194,0xc5106109),LL(0x49d05295,0xb7e2353e),LL(0xefb42ee0,0xfc8c1d5c),LL(0x08ce811c,0xe04884eb), LL(0x7419f40e,0xf1f75d81),LL(0xa995c241,0x5b0ac162),LL(0xc4c55646,0x120921bb),LL(0x8d33cf97,0x713520c2), + LL(0xe98c5100,0xb4a65a5c),LL(0x2ddd0f5a,0x6cec871d),LL(0x9ba2e78b,0x251f0b7f),LL(0xce3a2a5f,0x224a8434), LL(0x25f5c46f,0x26827f61),LL(0x48545ec0,0x6a22bedc),LL(0xb1bb5cdc,0x25ae5fa0),LL(0xfcb9b98f,0xd693682f), + LL(0x91e5d7d3,0x32027fe8),LL(0x73a07678,0xf14b7d17),LL(0xc0dfdd61,0xf88497b3),LL(0x2a8c4f48,0xf7c2eec0), LL(0x3756e621,0xaa5573f4),LL(0x1825b948,0xc013a240),LL(0x63878572,0x1c03b345),LL(0x653a4184,0xa0472bea), + LL(0x0ac69a80,0xf4222e27),LL(0xf51e54f6,0x34096d25),LL(0x8fffa591,0x00a648cb),LL(0x69b6527f,0x4e87acdc), LL(0xe285ccb4,0x0575e037),LL(0x50ddcf52,0x188089e4),LL(0x870ff719,0xaa96c9a8),LL(0x1fc7e369,0x74a56cd8), + LL(0x1726931a,0x41d04ee2),LL(0x3660ecfd,0x0bbbb2c8),LL(0x24818e18,0xa6ef6de5),LL(0xe7d57887,0xe421cc51), LL(0xbea87be6,0xf127d208),LL(0xb1cdd682,0x16a475d3),LL(0x439b63f7,0x9db1b684),LL(0xf0f113b6,0x5359b3db), + LL(0x8bf06e31,0xdfccf1de),LL(0xdd383901,0x1fdf8f44),LL(0x5017e7d2,0x10775cad),LL(0x58d11eef,0xdfc3a597), LL(0xb1ecff10,0x6ec9c8a0),LL(0x28400549,0xee6ed6cc),LL(0x1b4f8d73,0xb5ad7bae),LL(0xe00aaab9,0x61b4f11d), + LL(0xd4eff2d7,0x7b32d69b),LL(0x4288b60f,0x88ae6771),LL(0x37a1e723,0x159461b4),LL(0x570aae8c,0x1f3d4789), LL(0x7f9871da,0x869118c0),LL(0xf635e278,0x35fbda78),LL(0xe1541dac,0x738f3641),LL(0xc0dae45f,0x6794b13a), + LL(0x09cc0917,0x065064ac),LL(0xc68540fd,0x27c53729),LL(0xef227671,0x0d2d4c8e),LL(0xa1785a04,0xd23a9f80), LL(0x52650359,0x98c59528),LL(0x74a1acad,0xfa09ad01),LL(0x0b55bf5c,0x082d5a29),LL(0x419b8084,0xa40f1c67), + LL(0xdcc18770,0x3a5c752e),LL(0x8825c3a5,0x4baf1f2f),LL(0x21b153ed,0xebd63f74),LL(0xb2f64723,0xa2383e47), LL(0x2646d19a,0xe7bf620a),LL(0x03c83ffd,0x56cb44ec),LL(0x4f6be9f1,0xaf7267c9),LL(0xc06bb5e9,0x8b2dfd7b), + LL(0xa672c5c7,0xb87072f2),LL(0x0d53c5e2,0xeacb11c8),LL(0xff435932,0x22dac29d),LL(0x4408693c,0x37bdb99d), LL(0x2899c20f,0xf6e62fb6),LL(0x447ece24,0x3535d512),LL(0xff577ce3,0xfbdc6b88),LL(0x190575f2,0x726693bd), + LL(0xab4b35a2,0x6772b0e5),LL(0xf5eeaacf,0x1d8b6001),LL(0x795b9580,0x728f7ce4),LL(0x41fb81da,0x4a20ed2a), LL(0x4fec01e6,0x9f685cd4),LL(0xa7ff50ad,0x3ed7ddcc),LL(0x0c2d97fd,0x460fd264),LL(0xeb82f4f9,0x3a241426), + LL(0x6a8ea820,0x17d1df2c),LL(0xf22cc254,0xb2b50d3b),LL(0xb7291426,0x03856cba),LL(0x04f5ee39,0x87fd26ae), LL(0x02bee4ba,0x9cb696cc),LL(0x06820fd6,0x53121804),LL(0x0212e985,0xa5dfc269),LL(0x160f9a09,0x666f7ffa), + LL(0xbccd9617,0xc503cd33),LL(0xba7730a3,0x365dede4),LL(0x5ddb0786,0x798c6355),LL(0xfc9cd3bc,0xa6c3200e), LL(0xe5e35efd,0x060ffb2c),LL(0x5555a1c1,0x99a4e25b),LL(0xf70b3751,0x11d95375),LL(0x160e1bf6,0x0a57354a), + LL(0xf8e4b065,0xecb3ae4b),LL(0x2e53022b,0x07a834c4),LL(0x8692ed96,0x1cd300b3),LL(0x61ee14ec,0x16a6f792), LL(0x6a8649ed,0x8f1063c6),LL(0x869f3e14,0xfbcdfcfe),LL(0x00a7b3ec,0x2cfb97c1),LL(0x7130c2f1,0xcea49b3c), + LL(0xe9d96488,0x462d044f),LL(0x8182a0c1,0x4b53d52e),LL(0x0391e9e9,0x84b6ddd3),LL(0xb1741a09,0x80ab7b48), LL(0x27d3317f,0xec0e15d4),LL(0x1a64671e,0x8dfc1ddb),LL(0xd49c5b92,0x93cc5d5f),LL(0x3674a331,0xc995d53d), + LL(0x090090ae,0x302e41ec),LL(0xedb06830,0x2278a0cc),LL(0xfbc99690,0x1d025932),LL(0xb80d68da,0x0c32fbd2), LL(0xf341a6c1,0xd79146da),LL(0x1bef68a0,0xae0ba139),LL(0x8d774b3a,0xc6b8a563),LL(0x880ba4d7,0x1cf307bd), + LL(0x19803511,0xc033bdc7),LL(0x8888c3be,0xa9f97b3b),LL(0x85c6d05e,0x3d68aebc),LL(0x193919eb,0xc3b88a9d), LL(0xc48b0ee3,0x2d300748),LL(0x07a746c1,0x7506bc7c),LL(0x6e6d57f3,0xfc48437c),LL(0xcfeaa91a,0x5bd71587), + LL(0xc1bc5225,0xa4ed0408),LL(0x2719226d,0xd0b946db),LL(0x758d2d43,0x109ecd62),LL(0x2751759b,0x75c8485a), LL(0x9ce4177a,0xb0b75f49),LL(0x79c10c3d,0x4fa61a1e),LL(0xa167fcd7,0xc062d300),LL(0x750f0fa8,0x4df3874c), + LL(0x83dfedc9,0x29ae2cf9),LL(0x8d87631a,0xf8437134),LL(0x7429c8d2,0xaf571711),LL(0x146d9272,0x18d15867), LL(0x69769bb7,0x83053ecf),LL(0xc479ab82,0xc55eb856),LL(0x21b0f4b2,0x5ef7791c),LL(0x3d491525,0xaa5956ba), + LL(0x9fe20eba,0x407a96c2),LL(0xe52a5ad3,0xf27168bb),LL(0xbf1d9d89,0x43b60ab3),LL(0x710e727a,0xe45c51ef), LL(0x099b4221,0xdfca5276),LL(0x2557a159,0x8dc6407c),LL(0x91035895,0x0ead8335),LL(0x9c55dc32,0x0a9db957), + LL(0xdf61bc76,0xe40736d3),LL(0x3f778cdb,0x13a619c0),LL(0xc56ea28f,0x6dd921a4),LL(0x2fa647b4,0x76a52433), LL(0xac5bdc5d,0x23591891),LL(0xbac7dc01,0xff4a1a72),LL(0x62df8453,0x9905e261),LL(0xe63b265f,0x3ac045df), + LL(0xad53dba7,0x8a3f341b),LL(0x837b625a,0x8ec269cc),LL(0x3ae31189,0xd71a2782),LL(0x55e96120,0x8fb4f9a3), LL(0xff9875cf,0x804af823),LL(0x5d442a9b,0x23224f57),LL(0xecc62679,0x1c4d3b9e),LL(0xa0e7ddb1,0x91da22fb), + LL(0x6c04a661,0xa370324d),LL(0x5e376d17,0x9710d3b6),LL(0x3044e357,0xed8c98f0),LL(0x6422701c,0xc364ebbe), LL(0x7733d61c,0x347f5d51),LL(0xcea826c3,0xd55644b9),LL(0x55a25548,0x80c6e0ad),LL(0x844220a7,0x0aa7641d), + LL(0x31810660,0x1438ec81),LL(0xde4b4043,0x9dfa6507),LL(0xcc3e0273,0x10b515d8),LL(0x28d8cfb2,0x1b6066dd), LL(0x9c9efebd,0xd3b04591),LL(0xa21c1ff4,0x425d4bdf),LL(0xd57607d3,0x5fe5af19),LL(0x54481084,0xbbf773f7), + LL(0x94b03ed1,0x8435bd69),LL(0x634cc546,0xd9ad1de3),LL(0x00e420ca,0x2cf423fc),LL(0xa03096dd,0xeed26d80), LL(0xa4db09d2,0xd7f60be7),LL(0x960622f7,0xf47f569d),LL(0x7296c729,0xe5925fd7),LL(0x26ca2715,0xeff2db26), + LL(0xb913e759,0xa6fcd014),LL(0x8ff4de93,0x53da4786),LL(0xc32068e1,0x14616d79),LL(0xccdf352e,0xb187d664), LL(0x1dc90b59,0xf7afb650),LL(0x7daa1b26,0x8170e943),LL(0x700c0a84,0xc8e3bdd8),LL(0x6482bdfa,0x6e8d345f), + LL(0xc5c5ea50,0x84cfbfa1),LL(0x67960681,0xd3baf14c),LL(0x0dd50942,0x26398403),LL(0x4716a663,0xe4b7839c), LL(0xe7de6dc0,0xd5f1f794),LL(0x622aa7ce,0x5cd0f4d4),LL(0x59acfeec,0x5295f3f1),LL(0x953e0607,0x8d933552), + LL(0x776c5722,0xc7db8ec5),LL(0x2b5f290c,0xdc467e62),LL(0x4ff425a9,0xd4297e70),LL(0x0cf7bb72,0x4be924c1), LL(0xa1892131,0x0d5dc5ae),LL(0xa705c992,0x8bf8a8e3),LL(0x7a305ac5,0x73a0b064),LL(0x9a8c77a8,0x00c9ca4e), + LL(0x83774bdd,0x5dfee80f),LL(0x85734485,0x63131602),LL(0x914a69a9,0xa1b524ae),LL(0xd4e300d7,0xebc2ffaf), LL(0x7cfa46a5,0x52c93db7),LL(0x21653b50,0x71e6161f),LL(0xa4bc580a,0x3574fc57),LL(0xe1bc1253,0xc09015dd), + LL(0xd174d7aa,0x4b7b47b2),LL(0xf3a15d04,0x4072d8e8),LL(0xd6fa07ed,0xeeb7d47f),LL(0xedbdafb1,0x6f2b9ff9), LL(0x3760fe8a,0x18c51615),LL(0xf06c6c13,0x7a96e6bf),LL(0x0ea2d071,0x4d7a0410),LL(0x0be2a5ce,0xa1914e9b), + LL(0xd8a3c5cf,0x5726e357),LL(0x2abb2b13,0x1197ecc3),LL(0x31ae88dd,0x6c0d7f7f),LL(0xfdbb3efe,0x15b20d1a), LL(0x70584039,0xcd06aa26),LL(0xa7dc9747,0x2277c969),LL(0x7855d815,0xbca69587),LL(0x5188b32a,0x899ea238), + LL(0x760c1c9d,0x37d9228b),LL(0x9b5c18da,0xc7efbb11),LL(0x19f6dbc5,0x7f0d1bc8),LL(0x07e6905b,0x4875384b), LL(0x3ba8cd86,0xc7c50baa),LL(0xc2905de0,0xb0ce40fb),LL(0x7a231952,0x70840673),LL(0xcf43de26,0xa912a262), + LL(0xeb5b76c1,0x9c38ddcc),LL(0x26fc0ab4,0x746f5285),LL(0xd62c269f,0x52a63a50),LL(0x99458621,0x60049c55), LL(0x3c2f7c9e,0xe7f48f82),LL(0x917d5cf3,0x6bd99043),LL(0x8701f469,0xeb1317a8),LL(0x9a449fe0,0xbd3fe2ed), + LL(0x12ef3d36,0x421e79ca),LL(0x3e7ea5de,0x9ee3c36c),LL(0xcdff36f7,0xe48198b5),LL(0xc6b82228,0xaff4f967), LL(0xc47adb7e,0x15e19dd0),LL(0x032e7dfa,0x45699b23),LL(0x1fae026a,0x40680c8b),LL(0x550dbf4d,0x5a347a48), + LL(0x3cef0d7d,0xe652533b),LL(0x2bbb4381,0xd94f7b18),LL(0x0e80f500,0x838752be),LL(0x9e9c9bfb,0x8e6e2488), LL(0x16caca6a,0xc9751697),LL(0x38531ad9,0x866c49d8),LL(0x7151ade1,0xc917e239),LL(0x6037c407,0x2d016ec1), + LL(0x00eac3f9,0xa407ccc9),LL(0xe2ed4748,0x835f6280),LL(0x1cc98e0d,0xcc54c347),LL(0xdcb572eb,0x0e969937), LL(0x8f30c9cb,0x1b16c8e8),LL(0x373c4661,0xa606ae75),LL(0x35502cab,0x47aa689b),LL(0x4d9bb64f,0xf89014ae), + LL(0x31c71f7b,0x202f6a9c),LL(0x296ffe5c,0x01f95aa3),LL(0x53cec3a3,0x5fc06014),LL(0x5f498a45,0xeb991237), LL(0x5d91ba87,0xae9a935e),LL(0x0b564a19,0xc6ac6281),LL(0x3bd44e69,0x8a8fe81c),LL(0x9dd11d45,0x7c8b467f), + LL(0xea5b8e69,0xf772251f),LL(0xc5b75fbc,0xaeecb3bd),LL(0x887ff0e5,0x1aca3331),LL(0x19f0a131,0xbe5d49ff), LL(0xe5c8646f,0x582c13aa),LL(0x20e19980,0xdbaa12e8),LL(0xf7abbd94,0x8f40f31a),LL(0x1dfc7663,0x1f13f5a8), + LL(0xaceb4fc0,0x5d81f1ee),LL(0x5e6f0f42,0x36256002),LL(0x751370c8,0x4b67d6d7),LL(0x03e80589,0x2608b698), LL(0x05268301,0xcfc0d2fc),LL(0x40309212,0xa6943d39),LL(0x1fd0e1c2,0x192a90c2),LL(0x37f1dc76,0xb209f113), + LL(0x97bf1298,0xefcc5e06),LL(0x219d639e,0xcbdb6730),LL(0xb81e8c6f,0xd009c116),LL(0x1a7ce2e5,0xa3ffdde3), LL(0xa914d3ba,0xc53fbaaa),LL(0x88df85ee,0x836d500f),LL(0x66ee0751,0xd98dc71b),LL(0x714516fd,0x5a3d7005), + LL(0x39eedbba,0x21d3634d),LL(0x0455a46d,0x35cd2e68),LL(0xf9d7eb0c,0xc8cafe65),LL(0x00cefb3e,0xbda3ce9e), LL(0x2c9cf7a4,0xddc17a60),LL(0x7bcb8773,0x01572ee4),LL(0x8c7548df,0xa92b2b01),LL(0xa84600e3,0x732fd309), + LL(0x16543a40,0xe22109c7),LL(0xfede3c6c,0x9acafd36),LL(0x6824e614,0xfb206852),LL(0xda25dca0,0x2a4544a9), LL(0x91d60b06,0x25985262),LL(0x28753545,0x281b7be9),LL(0x90f13b27,0xec667b1a),LL(0x940e2eb4,0x33a83aff), + LL(0xd5d721d5,0x80009862),LL(0x5bd3a182,0x0c3357a3),LL(0x7aa2cda4,0x27f3a83b),LL(0xf6f83085,0xb58ae74e), LL(0x2e6dad6b,0x2a911a81),LL(0xf43d6c5b,0xde286051),LL(0xf996c4d8,0x4bdccc41),LL(0x0ae1e24e,0xe7312ec0), +}, +/* digit=2 base_pwr=2^14 */ +{ + LL(0x6e6485b3,0xf8d112e7),LL(0x771c52f8,0x4d3e24db),LL(0x684a2f6d,0x48e3ee41),LL(0x21d95551,0x7161957d), LL(0xcdb12a6c,0x19631283),LL(0x2e50e164,0xbf3fa882),LL(0x3166cc73,0xf6254b63),LL(0xaee8cc38,0x3aefa7ae), + LL(0x3b36f9fd,0x79b0fe62),LL(0xfde19fc0,0x26543b23),LL(0x958482ef,0x136e64a0),LL(0x9b095825,0x23f63771), LL(0xb6a1142e,0x14cfd596),LL(0x335aac0b,0x5ea6aac6),LL(0xf3081dd5,0x86a0e8bd),LL(0x003dc12a,0x5fb89d79), + LL(0xf72e34d4,0xf615c33a),LL(0x110eec35,0x0bd9ea40),LL(0xc1dea34e,0x1c12bc5b),LL(0x49ae4699,0x686584c9), LL(0x8c97b942,0x13ad95d3),LL(0x4e5c7562,0x4609561a),LL(0xf2737f89,0x9e94a4ae),LL(0x371c78b6,0xf57594c6), + LL(0xe3779ee3,0x0f0165fc),LL(0xbd495d9e,0xe00e7f9d),LL(0x20284e7a,0x1fa4efa2),LL(0x47ac6219,0x4564bade), LL(0xc4708e8e,0x90e6312a),LL(0xa71e9adf,0x4f5725fb),LL(0x3d684b9f,0xe95f55ae),LL(0x1e94b415,0x47f7ccb1), + LL(0x8d946581,0x7322851b),LL(0xbdf4a012,0xf0d13133),LL(0x6584dae0,0xa3510f69),LL(0x3c9f6c6d,0x03a7c171), LL(0xe475381a,0x5be97f38),LL(0x85823334,0xca1ba422),LL(0x0be17dda,0xf83cc5c7),LL(0x0b918c0f,0x158b1494), + LL(0x522e6b69,0xda3a77e5),LL(0xbbcd6c18,0x69c908c3),LL(0xd924fd56,0x1f1b9e48),LL(0xaa4bb3f7,0x37c64e36), LL(0xee478d7d,0x5a4fdbdf),LL(0x0193f7a0,0xba75c8bc),LL(0x56cd16df,0x84bc1e84),LL(0x46fad151,0x1fb08f08), + LL(0x842e9f30,0x8a7cabf9),LL(0x5eab83af,0xa331d4bf),LL(0x017f2a6a,0xd272cfba),LL(0x83aba0e3,0x27560abc), LL(0x0e3a6b75,0x94b83387),LL(0x6b9f50f5,0x25c6aea2),LL(0xb5fdf6d0,0x803d691d),LL(0xe6333514,0x03b77509), + LL(0x61a341c1,0x36178903),LL(0x0cfd6142,0x3604dc60),LL(0x8533316c,0x022295eb),LL(0x44af2922,0x3dbde4ac), LL(0x1c7eef69,0x898afc5d),LL(0xd14f4fa1,0x58896805),LL(0x203c21ca,0x05002160),LL(0x40ef730b,0x6f0d1f30), + LL(0x196224f8,0x8e8c44d4),LL(0x374d079d,0x75a4ab95),LL(0x7d48f123,0x79085ecc),LL(0x1bf65ad8,0x56f04d31), LL(0xbda602b2,0xe220bf1c),LL(0xf9612c69,0x73ee1742),LL(0x084fd06b,0x76008fc8),LL(0xf11380d1,0x4000ef9f), + LL(0x12cfe297,0x48201b4b),LL(0x292f74e5,0x3eee129c),LL(0xc9e874e8,0xe1fe114e),LL(0x92c5fc41,0x899b055c), LL(0x3a39c8cf,0x4e477a64),LL(0x78963cc9,0x82f09efe),LL(0xd333f863,0x6fd3fd8f),LL(0xdc949c63,0x85132b2a), + LL(0x516eb17b,0x7e06a3ab),LL(0xd2c7372b,0x73bec06f),LL(0xba896da6,0xe4f74f55),LL(0x8e9eb40f,0xbb4afef8), LL(0xe61d66b0,0x2d75bec8),LL(0xef29300b,0x02bda4b4),LL(0x026baa5a,0x8bbaa8de),LL(0xa07f4440,0xff54befd), + LL(0xbe7a2af3,0xbd9b8b1d),LL(0x4fb74a72,0xec51caa9),LL(0x63879697,0xb9937a4b),LL(0xec2687d5,0x7c9a9d20), LL(0x6ef5f014,0x1773e44f),LL(0xe90c6900,0x8abcf412),LL(0x8142161e,0x387bd022),LL(0xfcb6ff2a,0x50393755), + LL(0xed6def63,0x9813fd56),LL(0x7d53106c,0x53cf6482),LL(0x431f7ac1,0x991a35bd),LL(0x63e65faf,0xf1e274dd), LL(0x44cc7880,0xf63ffa3c),LL(0x7c256981,0x411a426b),LL(0x93a420e0,0xb698b9fd),LL(0xae53f8fe,0x89fdddc0), + LL(0x32398baa,0x766e0722),LL(0x5cfca031,0x205fee42),LL(0x7a029cf2,0xa49f5341),LL(0x4023890d,0xa88c68b8), LL(0x7337aaa8,0xbc275041),LL(0x0eb384f4,0x9ed364ad),LL(0x29aba92f,0xe0816f85),LL(0x04e38a88,0x2e9e1941), + LL(0x3dafd2d5,0x57eef44a),LL(0x97ed98d8,0x35d1fae5),LL(0x2307f9b1,0x50628c09),LL(0xd6cba5c6,0x09d84aae), LL(0x88aaa691,0x67071bc7),LL(0xafe6cb03,0x2dea57a9),LL(0x3d78ac01,0xdfe11bb4),LL(0x7fd7aa51,0x7286418c), + LL(0x77f7195a,0xfabf7709),LL(0xadeb838f,0x8ec86167),LL(0xbb4f012d,0xea1285a8),LL(0x9a3eab3f,0xd6883503), LL(0x309004c2,0xee5d24f8),LL(0x13ffe95e,0xa96e4b76),LL(0xbd223ea4,0x0cdffe12),LL(0xb6739a53,0x8f5c2ee5), + LL(0xdd968198,0x5cb4aaa5),LL(0x72413a6c,0xfa131c52),LL(0x9536d903,0x53d46a90),LL(0x48606d8e,0xb270f0d3), LL(0xa053a3bc,0x518c7564),LL(0x1a86caef,0x088254b7),LL(0x0ab5efd0,0xb3ba8cb4),LL(0x4605945d,0x5c59900e), + LL(0xa1887395,0xecace1dd),LL(0x932a65de,0x40960f36),LL(0x3aa95529,0x9611ff5c),LL(0x7c1e5a36,0xc58215b0), LL(0xf0e1a524,0xd48c9b58),LL(0xf590dfb8,0xb406856b),LL(0x9cd95662,0xc7605e04),LL(0xa33ecf82,0x0dd036ee), + LL(0xc33156b3,0xa50171ac),LL(0x4a80172e,0xf09d24ea),LL(0x76dc8eef,0x4e1f72c6),LL(0x5e3d44ee,0xe60caadc), LL(0x979b1d8f,0x006ef8a6),LL(0x97788d26,0x60908a1c),LL(0x266feec0,0x6e08f95b),LL(0x22e8c94e,0x618427c2), + LL(0x59145a65,0x3d613339),LL(0xfa406337,0xcd9bc368),LL(0x2d8a52a0,0x82d11be3),LL(0x97a1c590,0xf6877b27), LL(0xf5cbdb25,0x837a819b),LL(0xde090249,0x2a4fd1d8),LL(0x74990e5f,0x622a7de7),LL(0x7945511b,0x840fa5a0), + LL(0x6558842d,0x30b974be),LL(0x17f3d0a6,0x70df8c64),LL(0x7542e46d,0x7c803520),LL(0xe4ecc823,0x7251fe7f), LL(0x5e9aac9a,0xe59134cb),LL(0xf0045d71,0x11bb0934),LL(0xdbcb1d4e,0x53e5d9b5),LL(0x92defc91,0x8d97a905), + LL(0x7946d3f9,0xfe289327),LL(0x07472273,0xe132bd24),LL(0x1eb6ae86,0xeeeb510c),LL(0xf0595067,0x777708c5), LL(0x1297029e,0x18e2c8cd),LL(0xbbf9305e,0x2c61095c),LL(0x6b85d6d9,0xe466c258),LL(0xda1ea530,0x8ac06c36), + LL(0xa1304668,0xa365dc39),LL(0x07f89606,0xe4a9c885),LL(0xacc7228d,0x65a4898f),LL(0x84ca8303,0x3e2347ff), LL(0xea7d23a3,0xa5f6fb77),LL(0x672a71cd,0x2fac257d),LL(0x7e6a44d3,0x6908bef8),LL(0x891d3d7a,0x8ff87566), + LL(0x6b0cf82e,0xe58e90b3),LL(0x2615b5e7,0x6438d246),LL(0x669c145a,0x07b1f8fc),LL(0x36f1e1cb,0xb0d8b2da), LL(0xd9184c4d,0x54d5dadb),LL(0xf93d9976,0x3dbb18d5),LL(0xd1147d47,0x0a3e0f56),LL(0xa0a48609,0x2afa8c8d), + LL(0xbc36742c,0x275353e8),LL(0xeea0ed90,0x898f427e),LL(0x3e477b00,0x26f4947e),LL(0x308741e3,0x8ad8848a), LL(0xd74a2a46,0x6c703c38),LL(0x9ba17ba2,0x5e3e05a9),LL(0x4ab9a9e4,0xc1fa6f66),LL(0x3841d6ec,0x474a2d9a), + LL(0x653ae326,0x871239ad),LL(0xa74cbb43,0x14bcf72a),LL(0x20d4c083,0x8737650e),LL(0x110ed4af,0x3df86536), LL(0xb53ca555,0xd2d86fe7),LL(0xabd5d538,0x688cb00d),LL(0x1ad38468,0xcf81bda3),LL(0xf01167b6,0x7ccfe3cc), + LL(0x6c4c1fe6,0xcf4f47e0),LL(0x298bbb79,0x557e1f1a),LL(0x30d45a14,0xf93b974f),LL(0x0baf97c4,0x174a1d2d), LL(0xc51fbf53,0x7a003b30),LL(0xee68b225,0xd8940991),LL(0x1c0f4173,0x5b0aa7b7),LL(0xa20a7153,0x975797c9), + LL(0xe3533d77,0x26e08c07),LL(0x2e341c99,0xd7222e6a),LL(0x8d2dc4ed,0x9d60ec3d),LL(0x7c476cf8,0xbdfe0d8f), LL(0x1d056605,0x1fe59ab6),LL(0x86a8551f,0xa9ea9df6),LL(0x47fb8d8c,0x8489941e),LL(0x4a7f1b10,0xfeb874eb), + LL(0x7ee0d98f,0xfe5fea86),LL(0xdbf61864,0x201ad34b),LL(0x37c031d4,0x45d8fe47),LL(0x795f0822,0xd5f49fae), LL(0xc7f4a40c,0xdb0fb291),LL(0x730ddd92,0x2e69d9c1),LL(0x49d76987,0x754e1054),LL(0x7662db87,0x8a24911d), + LL(0x60a71676,0x61fc1810),LL(0xf66a8ad1,0xe852d1a8),LL(0x6417231e,0x172bbd65),LL(0x3babb11f,0x0d6de7bd), LL(0xc8e347f8,0x6fde6f88),LL(0x9bd99cc3,0x1c587547),LL(0x34076950,0x78e54ed0),LL(0x796e83ba,0x97f0f334), + LL(0x4924867a,0xe4dbe1ce),LL(0x60b84917,0xbd5f51b0),LL(0x3cb09a79,0x37530040),LL(0xff1743d8,0xdb3fe0f8), LL(0x556fa9db,0xed7894d8),LL(0x23412fbf,0xfa262169),LL(0xba7b9291,0x563be0db),LL(0x0c9fb234,0x6ca8b8c0), + LL(0xbd763802,0xed406aa9),LL(0x65303da1,0xc21486a0),LL(0xc7e62ec4,0x61ae291e),LL(0xdf99333e,0x622a0492), LL(0xbb7a8ee0,0x7fd80c9d),LL(0x6c01aedb,0xdc2ed3bc),LL(0x08be74ec,0x35c35a12),LL(0x469f671f,0xd540cb1a), + LL(0xcf84f6c7,0xd16ced4e),LL(0x2d090f43,0x8561fb9c),LL(0x6f239db4,0x7e693d79),LL(0x77bd0d94,0xa736f928), LL(0x2c1950ee,0x07b4d929),LL(0x56dc11b3,0xda177543),LL(0x7a6a878e,0xa5dfbbaa),LL(0x4decb08a,0x1c70cb29), + LL(0x6f0f7c50,0xfba28c8b),LL(0x854dcc6d,0xa8eba2b8),LL(0x36b78642,0x5ff8e89a),LL(0xf6873adf,0x070c1c8e), LL(0x6484d2e4,0xbbd3c371),LL(0x0d414129,0xfb78318f),LL(0x6ad93b0b,0x2621a39c),LL(0xa9e917f7,0x979d74c2), + LL(0x61fb0428,0xfc195647),LL(0xbee624d4,0x4d78954a),LL(0xb8ae86fd,0xb94896e0),LL(0xc91c8b13,0x6667ac0c), LL(0x43bcf832,0x9f180512),LL(0xa0010137,0xfbadf8b7),LL(0xb3ba8aa7,0xc69b4089),LL(0xe687ce85,0xfac4bacd), + LL(0x977eab40,0x9164088d),LL(0x2760b390,0x51f4c5b6),LL(0x340dd553,0xd238238f),LL(0xdb1d31c9,0x358566c3), LL(0x5068f5ff,0x3a5ad69e),LL(0xdaff6b06,0xf31435fc),LL(0xd6debff0,0xae549a5b),LL(0x75e01331,0x59e5f0b7), + LL(0x98559acf,0x5d492fb8),LL(0x4db79b50,0x96018c2e),LL(0x609f66aa,0x55f4a48f),LL(0x4900a14f,0x1943b3af), LL(0x15a40d39,0xc22496df),LL(0x4c20f7c5,0xb2a44684),LL(0x3b98404c,0x76a35afa),LL(0xff5d1b77,0xbec75725), + LL(0xbea06444,0xb67aa163),LL(0xf724b6f2,0x27e95bb2),LL(0xd238c8ab,0x3c20e3e9),LL(0xddd6ae17,0x1213754e), LL(0x716e0f74,0x8c431020),LL(0xffc095c2,0x6679c82e),LL(0xd0ac2932,0x2eb3adf4),LL(0x01bb7a76,0x2cc970d3), + LL(0x740f0e66,0x70c71f2f),LL(0x2b6b23cc,0x545c616b),LL(0xb40a8bd7,0x4528cfcb),LL(0x2ab27722,0xff839633), LL(0x025ac99a,0x049127d9),LL(0x2b63e33b,0xd314d4a0),LL(0x28d84519,0xc8c310e7),LL(0xb3bc84ba,0x0fcb8983), + LL(0x38634818,0x2cc52261),LL(0xb44c2e0b,0x501814f4),LL(0x54dfdba3,0xf7e181aa),LL(0xe759718c,0xcfd58ff0), LL(0xd3b507a8,0xf90cdb14),LL(0xc50bdad8,0x57bd478e),LL(0x50e5f9aa,0x29c197e2),LL(0xe40bc855,0x4db6eef8), + LL(0xd1fc0654,0x2cc8f21a),LL(0x81269d73,0xc71cc963),LL(0x077f49f9,0xecfbb204),LL(0xca56b793,0xdde92571), LL(0xf97ad8f7,0x9abed6a3),LL(0x924de3bd,0xe6c19d3f),LL(0xa140a800,0x8dce92f4),LL(0x1337af07,0x85f44d1e), + LL(0x09d64c52,0x5953c08b),LL(0xf5df9749,0xa1b5e49f),LL(0x52735f7d,0x336a8fb8),LL(0x9add676b,0xb332b6db), LL(0xb4511aa4,0x558b88a0),LL(0xdbd5cc55,0x09788752),LL(0xd8cd52bd,0x16b43b9c),LL(0xc2a2696b,0x7f0bc5a0), + LL(0xc11f61ef,0x146e12d4),LL(0x3a83e79e,0x9ce10754),LL(0x6cbfca15,0x08ec73d9),LL(0x5b49653f,0x09ff29ad), LL(0xe7da946e,0xe31b72bd),LL(0xee80a4f2,0xebf9eb3b),LL(0x17598ce4,0xd1aabd08),LL(0x53f37e80,0x18b5fef4), + LL(0x5958cd79,0xd5d5cdd3),LL(0x1d373114,0x3580a1b5),LL(0xfa935726,0xa36e4c91),LL(0xef20d760,0xa38c534d), LL(0x2ff5845b,0x7088e40a),LL(0xbd78177f,0xe5bb40bd),LL(0x857f9920,0x4f06a7a8),LL(0xe968f05d,0xe3cc3e50), + LL(0xe5682d26,0x1d68b7fe),LL(0xaec7f87c,0x5206f76f),LL(0x041951ab,0x41110530),LL(0xd4b5a71a,0x58ec52c1), LL(0x0f75cf9a,0xf3488f99),LL(0xba82d0d5,0xf411951f),LL(0x618895ab,0x27ee75be),LL(0x6d8aab14,0xeae060d4), + LL(0x7fb54dc2,0x9ae1df73),LL(0x25963649,0x1f3e391b),LL(0xfe055081,0x242ec32a),LL(0x8491c9bd,0x5bd450ef), LL(0x981eb389,0x367efc67),LL(0x3a0550d5,0xed7e1928),LL(0xab3ce75c,0x362e776b),LL(0x1f24c523,0xe890e308), + LL(0xfeccef76,0xb961b682),LL(0x8bba6d92,0x8b8e11f5),LL(0x2b2375c4,0x8f2ccc4c),LL(0xe2f86cfa,0x0d7f7a52), LL(0x9efe5633,0xfd94d30a),LL(0x5451f934,0x2d8d246b),LL(0x244e6a00,0x2234c6e3),LL(0xddec8c50,0xde2b5b0d), + LL(0xbf776f5b,0x2ce53c5a),LL(0x60357b05,0x6f724071),LL(0x71bf3f7a,0xb2593717),LL(0x440c4a9f,0x87d2501c), LL(0x87b05340,0x440552e1),LL(0x21624c32,0xb7bf7cc8),LL(0x22facddb,0x4155a6ce),LL(0x889837ef,0x5a4228cb), + LL(0xfd4fd671,0xef87d6d6),LL(0xc2daa10e,0xa233687e),LL(0x03c0eb96,0x75622244),LL(0x8bf19be6,0x7632d184), LL(0x40735ff4,0x05d0f8e9),LL(0xc00931f1,0x3a3e6e13),LL(0xdafe3f18,0x31ccde6a),LL(0xcfe51207,0xf381366a), + LL(0x60167d92,0x24c222a9),LL(0x7529f18c,0x62f9d6f8),LL(0x0353b114,0x412397c0),LL(0xef808043,0x334d89dc), LL(0x2a4383ce,0xd9ec63ba),LL(0x5cf92ba0,0xcec8e937),LL(0xc8be74c0,0xfb8b4288),LL(0x105d4391,0x67d6912f), + LL(0x1b913149,0x7b996c46),LL(0x3a4e02da,0x36aae2ef),LL(0x972de594,0xb68aa003),LL(0x4ec6d545,0x284ec70d), LL(0x61391d54,0xf3d2b2d0),LL(0xfe114e92,0x69c5d5d6),LL(0xb4482dff,0xbe0f00b5),LL(0xf5bf33c5,0xe1596fa5), + LL(0x96a71cba,0x10595b56),LL(0xfdcadeb7,0x944938b2),LL(0xfccd8471,0xa282da4c),LL(0x0d37bfe1,0x98ec05f3), LL(0x0698304a,0xe171ce1b),LL(0x21bdf79b,0x2d691444),LL(0x1b21dec1,0xd0cd3b74),LL(0x16a15f71,0x712ecd8b), + LL(0x00fd56e1,0x8d4c00a7),LL(0xf9527c18,0x02ec9692),LL(0x4a3e42e1,0x21c44937),LL(0x1392ae0a,0x9176fbab), LL(0x44b7b618,0x8726f1ba),LL(0xf1de491c,0xb4d7aae9),LL(0x07b582c0,0xf91df7b9),LL(0xef60aa3a,0x7e116c30), + LL(0x466265d7,0x99270f81),LL(0x4df7adf0,0xb15b6fe2),LL(0xf9738f7f,0xfe33b2d3),LL(0xd6d70f95,0x48553ab9), LL(0xc21e94db,0x2cc72ac8),LL(0xbdc0bbee,0x795ac38d),LL(0x2e40478f,0x0a1be449),LL(0x052bde55,0x81bd3394), + LL(0x56b3c4f2,0x63c8dbe9),LL(0x904177cc,0x017a99cf),LL(0x4d010fc1,0x947bbddb),LL(0xbb2c9b21,0xacf9b00b), LL(0x47173611,0x2970bc8d),LL(0xac7d756f,0x1a4cbe08),LL(0x67d541a2,0x06d9f4aa),LL(0x59c2cf44,0xa3e8b689), + LL(0x4d88f1dd,0xaad066da),LL(0x7ad35dea,0xc604f165),LL(0x4478ca67,0x7edc0720),LL(0xba02ce06,0xa10dfae0), LL(0xaf36f4e4,0xeceb1c76),LL(0xaf3f8f48,0x994b2292),LL(0x77c8a68c,0xbf9ed77b),LL(0x51744c9d,0x74f544ea), + LL(0x8113a757,0x82d05bb9),LL(0x8a9885e4,0x4ef2d2b4),LL(0x1aa7865f,0x1e332be5),LL(0x290d1a52,0x22b76b18), LL(0x44351683,0x308a2310),LL(0xa3f22840,0x9d861896),LL(0x841ed947,0x5959ddcd),LL(0x154b73bf,0x0def0c94), + LL(0x4c7c15e0,0xf0105417),LL(0x3a277c32,0x539bfb02),LL(0xf9dccf5f,0xe699268e),LL(0x0247a3bd,0x9f5796a5), LL(0x4f157269,0x8b839de8),LL(0x7a30196b,0xc825c1e5),LL(0xdc8a5a91,0x6ef0aabc),LL(0x498b7fe6,0xf4a8ce6c), + LL(0x70cbac78,0x1cce35a7),LL(0xf6b23958,0x83488e9b),LL(0xd76cb011,0x0341a070),LL(0xae1b2658,0xda6c9d06), LL(0xdd648c52,0xb701fb30),LL(0x52fb9fd1,0x994ca02c),LL(0x6f563086,0x06933117),LL(0x17856bab,0x3d2b8100), + LL(0x5963a46e,0xe89f48c8),LL(0xa99e61c7,0x658ab875),LL(0x4b8517b4,0x6e296f87),LL(0xfc1bc656,0x36c4fcdc), LL(0xa3906def,0xde5227a1),LL(0x62418945,0x9fe95f57),LL(0xfdd96cde,0x20c91e81),LL(0xda4480de,0x5adbe47e), + LL(0x396de2b6,0xa009370f),LL(0xf0ecc7bd,0x98583d4b),LL(0xe51d0672,0xf44f6b57),LL(0x556b1984,0x03d6b078), LL(0xb0b64912,0x27dbdd93),LL(0x15687b09,0x9b3a3434),LL(0x51ec20a9,0x0dba6461),LL(0xff28187c,0xec93db7f), + LL(0x66e48bdd,0x00ff8c24),LL(0x11ccd78e,0x2514f2f9),LL(0xe1250603,0xeba11f4f),LL(0x243fa156,0x8a22cd41), LL(0xb283e4c6,0xa4e58df4),LL(0x8b39783f,0x78c29859),LL(0xa5259809,0x5235aee2),LL(0x0e0227dd,0xc16284b5), + LL(0x1338830d,0xa5f57916),LL(0xd2123fca,0x6d4b8a6b),LL(0xf9c546f8,0x236ea68a),LL(0xfa608d36,0xc1d36873), LL(0x8d436d13,0xcd76e495),LL(0x8fb080af,0xd4d9c221),LL(0xe8ad3fb5,0x665c1728),LL(0xb3d572e0,0xcf1ebe4d), + LL(0x584c5e20,0xa7a8746a),LL(0xb9dc7035,0x267e4ea1),LL(0xb9548c9b,0x593a15cf),LL(0x4bd012f3,0x5e6e2135), LL(0x8c8f936e,0xdf31cc6a),LL(0xb5c241dc,0x8af84d04),LL(0x345efb86,0x63990a6f),LL(0xb9b962cb,0x6fef4e61), +}, +/* digit=3 base_pwr=2^21 */ +{ + LL(0x25722608,0xf6368f09),LL(0x131cf5c6,0x131260db),LL(0xfab4f7ac,0x40eb353b),LL(0x37eee829,0x85c78880), LL(0xc3bdf24e,0x4c1581ff),LL(0xf5c3c5a8,0x5bff75cb),LL(0xa14e6f40,0x35e8c83f),LL(0x0295e0ca,0xb81d1c0f), + LL(0xf43a730f,0xfcde7cc8),LL(0x33ab590e,0xe89b6f3c),LL(0xad03240b,0xc823f529),LL(0x98bea5db,0x82b79afe), LL(0x962fe5de,0x568f2856),LL(0x60c591f3,0x0c590adb),LL(0x4a28a858,0x1fc74a14),LL(0xb3203f4c,0x3b662498), + LL(0x6c39765a,0x91e3cf0d),LL(0xac3cca0b,0xa2db3acd),LL(0xcb953b50,0x288f2f08),LL(0xcf43cf1a,0x2414582c), LL(0x60eee9a8,0x8dec8bbc),LL(0x729aa042,0x54c79f02),LL(0x6532f5d5,0xd81cd5ec),LL(0xcf82e15f,0xa672303a), + LL(0x719c0563,0x376aafa8),LL(0xbc5fc79f,0xcd8ad2dc),LL(0xcb750cd3,0x303fdb9f),LL(0x4418b08e,0x14ff052f), LL(0x3e2d6520,0xf75084cf),LL(0x144ed509,0x7ebdf0f8),LL(0xd3f25b98,0xf43bf0f2),LL(0xa354d837,0x86ad71cf), + LL(0x26f43572,0xb827fe92),LL(0x5d824758,0xdfd3ab5b),LL(0x539094c1,0x315dd23a),LL(0x66623d68,0x85c0e37a), LL(0x7be19ae0,0x575c7972),LL(0xdf0d36b5,0x616a3396),LL(0x26b1ff7e,0xa1ebb3c8),LL(0x140ad453,0x635b9485), + LL(0xda430c0b,0x92bf3cda),LL(0x3a96dac6,0x4702850e),LL(0x15ac326a,0xc91cf0a5),LL(0xab8c25e4,0x95de4f49), LL(0xe265c17c,0xb01bad09),LL(0x087b3881,0x24e45464),LL(0xe1fac5ca,0xd43e583c),LL(0x6ead97a6,0xe17cb318), + LL(0x74dcec46,0x6cc39243),LL(0x54c2b73f,0x33cfc02d),LL(0xf26cd99c,0x82917844),LL(0xd1773f89,0x8819dd95), LL(0x0871f427,0x09572aa6),LL(0xf6f01c34,0x8e0cf365),LL(0xbff1f5af,0x7fa52988),LL(0xe75e8e50,0x4eb357ea), + LL(0x868af75d,0xd9d0c8c4),LL(0x45c8c7ea,0xd7325cff),LL(0xcc81ecb0,0xab471996),LL(0x611824ed,0xff5d55f3), LL(0x1977a0ee,0xbe314541),LL(0x722038c6,0x5085c4c5),LL(0xf94bb495,0x2d5335bf),LL(0xc8e2a082,0x894ad8a6), + LL(0xada35438,0x5c3e2341),LL(0x049b8c4e,0xf4a9fc89),LL(0x9f17cf34,0xbeeb355a),LL(0x6c91fe10,0x3f311e0e), LL(0x92ab9891,0xc2d20038),LL(0x3e8ce9a9,0x257bdcc1),LL(0x88c53bee,0x1b2d9789),LL(0xcdba143a,0x927ce89a), + LL(0x523db280,0xb0a32cca),LL(0x50d43783,0x5c889f8a),LL(0x4897d16f,0x503e04b3),LL(0x08f5f2e8,0x8cdb6e78), LL(0x179c8e74,0x6ab91cf0),LL(0x48211d60,0xd8874e52),LL(0xea851200,0xf948d4d5),LL(0xe6f9840a,0x4076d41e), + LL(0x47b517ea,0xc20e263c),LL(0x30685e5e,0x79a448fd),LL(0xf90631a0,0xe55f6f78),LL(0xa79e6346,0x88a790b1), LL(0x80969fe8,0x62160c7d),LL(0x41491bb9,0x54f92fd4),LL(0x5c957526,0xa6645c23),LL(0xbea3ce7b,0xf44cc5ae), + LL(0x8b1e68b7,0xf7628327),LL(0x303f29d3,0xc731ad7a),LL(0x57d03ecb,0xfe5a9ca9),LL(0x41bc97a7,0x96c0d50c), LL(0x9b4f7f24,0xc4669fe7),LL(0x3d9967ef,0xfdd781d8),LL(0x5d2c208d,0x7892c7c3),LL(0xae545cb3,0x8bf64f7c), + LL(0x467be912,0xc01f862c),LL(0xc73d30cc,0xf4c85ee9),LL(0x6ab83ec7,0x1fa6f4be),LL(0x4e3e3cf9,0xa07a3c1c), LL(0x0c00beb3,0x87f8ef45),LL(0x000d4c3e,0x30e2c2b3),LL(0xfe08bf5b,0x1aa00b94),LL(0x9224ef52,0x32c133aa), + LL(0x32e5685d,0x38df16bb),LL(0x58e6f544,0x68a9e069),LL(0xcdc5ebc6,0x495aaff7),LL(0x378b135f,0xf894a645), LL(0x09e27ecf,0xf316350a),LL(0x58f7179d,0xeced201e),LL(0xe97861ba,0x2eec273c),LL(0xd693be2e,0x47ec2cae), + LL(0xf68367ce,0xfa4c97c4),LL(0xbe5a5755,0xe4f47d0b),LL(0xb298a979,0x17de815d),LL(0xc177dc7d,0xd7eca659), LL(0x49ded0a3,0x20fdbb71),LL(0xfb34d3c5,0x4cb2aad4),LL(0x60858a33,0x2cf31d28),LL(0xa24aa40f,0x3b6873ef), + LL(0x2c11bb37,0x540234b2),LL(0xed4c74a3,0x2d0366dd),LL(0xeec5f25d,0xf9a968da),LL(0x67b63142,0x36601068), LL(0x68d7b6d4,0x07cd6d2c),LL(0x0c842942,0xa8f74f09),LL(0x7768b1ee,0xe2751404),LL(0xfe62aee4,0x4b5f7e89), + LL(0x89070d26,0xc6a77177),LL(0xdd1c8bc7,0xa1f28e4e),LL(0x469e1f17,0xea5f4f06),LL(0xfbdb78e0,0x78fc242a), LL(0x8b0588f1,0xc9c7c592),LL(0x1535921e,0xb6b7a0fd),LL(0xbde5ae35,0xcc5bdb91),LL(0x12ff1864,0xb42c485e), + LL(0xdbab98aa,0xa1113e13),LL(0xa17b1024,0xde9d469b),LL(0xc0462d3a,0x23f48b37),LL(0x7c5c078d,0x3752e537), LL(0x15544eb9,0xe3a86add),LL(0x80fba279,0xf013aea7),LL(0xf22001b5,0x8b5bb76c),LL(0xf02891ab,0xe617ba14), + LL(0x936219d3,0xd39182a6),LL(0xae51cb19,0x5ce1f194),LL(0xbf07a74c,0xc78f8598),LL(0x22cbf1bc,0x6d7158f2), LL(0xe300ce18,0x3b846b21),LL(0x2d11275d,0x35fba630),LL(0xa0239b9b,0x5fe25c36),LL(0xdf05d940,0xd8beb35d), + LL(0x1f7e320d,0x4db02bb0),LL(0x6da320ea,0x0641c364),LL(0x821389a3,0x6d95fa5d),LL(0x8fcd8e3d,0x92699748), LL(0xceb6c143,0x316fef17),LL(0xd933762b,0x67fcb841),LL(0x118b17f8,0xbb837e35),LL(0x9fd24821,0x4b92552f), + LL(0x46aca793,0xae6bc70e),LL(0xe579311b,0x1cf0b0e4),LL(0x5802f716,0x8dc631be),LL(0xbddbee4d,0x099bdc6f), LL(0x0caf8b05,0xcc352bb2),LL(0x72d63df2,0xf74d505a),LL(0x91c4f408,0xb9876d4b),LL(0x9e229b2d,0x1ce18473), + LL(0x83abdb4a,0x49507597),LL(0xdee84b18,0x850fbcb6),LL(0x609e67dc,0x6325236e),LL(0x9336c6d8,0x04d831d9), LL(0xfa12d45d,0x8deaae3b),LL(0x4746e246,0xe425f8ce),LL(0x24f5f31e,0x8004c175),LL(0xad62c3b7,0xaca16d8f), + LL(0x9152f934,0x0dc15a6a),LL(0xed0e12c1,0xf1235e5d),LL(0xda477dac,0xc33c06ec),LL(0xb2ea0006,0x76be8732), LL(0x0c0cd313,0xcf3f7831),LL(0xa614260d,0x3c524553),LL(0xcab22d15,0x31a756f8),LL(0x77827a20,0x03ee10d1), + LL(0x1994ef20,0xd1e059b2),LL(0x638ae318,0x2a653b69),LL(0x2f699010,0x70d5eb58),LL(0x09f5f84a,0x279739f7), LL(0x8b799336,0x5da4663c),LL(0x203c37eb,0xfdfdf14d),LL(0xa1dbfb2d,0x32d8a9dc),LL(0x77d48f9b,0xab40cff0), + LL(0xd20b42d5,0xc018b383),LL(0x9f78845f,0xf9a810ef),LL(0xbdba9df0,0x40af3753),LL(0x131dfdf9,0xb90bdcfc), LL(0xf01ab782,0x18720591),LL(0x6af12a88,0xc823f211),LL(0x0dc14401,0xa51b80f3),LL(0xfb2dfbe3,0xde248f77), + LL(0x0cafe751,0xef5a44e5),LL(0xd4dcd221,0x73997c9c),LL(0xde854024,0x32fd86d1),LL(0xa09b84bb,0xd5b53adc), LL(0xdcedd8d1,0x008d7a11),LL(0x74b32c84,0x406bd1c8),LL(0x05dde8b1,0x5d4472ff),LL(0xfce2b32f,0x2e25f2cd), + LL(0x29dfc254,0xbec0dd5e),LL(0x2b98b267,0x4455fcf6),LL(0xc72df2ad,0x0b4d43a5),LL(0x48a75397,0xea70e6be), LL(0x5820f3bf,0x2aad6169),LL(0x9e37f68f,0xf410d2dd),LL(0x7be5ac83,0x70fb7dba),LL(0x36ec3eec,0x636bb645), + LL(0x9754e21c,0x27104ea3),LL(0x8d63c373,0xbc87a3e6),LL(0x4109db9a,0x483351d7),LL(0x60134da7,0x0fa724e3), LL(0xb0720b16,0x9ff44c29),LL(0x06aceead,0x2dd0cf13),LL(0xe26929a6,0x5942758c),LL(0xb766a92b,0x96c5db92), + LL(0x5f18395e,0xcec7d4c0),LL(0x1f80d032,0xd3f22744),LL(0xcb86075b,0x7a68b37a),LL(0xafef92db,0x074764dd), LL(0x7bc7f389,0xded1e950),LL(0xb9756460,0xc580c850),LL(0x7da48157,0xaeeec2a4),LL(0x82c587b3,0x3f0b4e7f), + LL(0xa9f19c53,0x231c6de8),LL(0x6974e34e,0x5717bd73),LL(0xf1508fa9,0xd9e1d216),LL(0xdadaa124,0x9f112361), LL(0x823b7348,0x80145e31),LL(0xac634069,0x4dd8f0d5),LL(0x2297c258,0xe3d82fc7),LL(0x9cee7431,0x276fcfee), + LL(0x2bc0aea9,0x8eb61b5e),LL(0xde329431,0x4f668fd5),LL(0x38e4b87e,0x03a32ab1),LL(0x73d0ef0b,0xe1374517), LL(0x853ac983,0x1a46f7e6),LL(0x68e78a57,0xc3bdf42e),LL(0x2ea96dd1,0xacf20785),LL(0xf1638460,0xa10649b9), + LL(0x879fbbed,0xf2369f0b),LL(0xda9d1869,0x0ff0ae86),LL(0x56766f45,0x5251d759),LL(0x2be8d0fc,0x4984d8c0), LL(0xd21008f0,0x7ecc95a6),LL(0x3a1a1c49,0x29bd54a0),LL(0xd26c50f3,0xab9828c5),LL(0x51d0d251,0x32c0087c), + LL(0x0c1cdb26,0x9bac3ce6),LL(0x557ca205,0xcd94d947),LL(0x9db1fdcd,0x1b1bd598),LL(0xa3d8b149,0x0eda0108), LL(0x56152fcc,0x95066610),LL(0xe7192b33,0xc2f037e6),LL(0xc92e05a4,0xdeffb41a),LL(0xc2f6c62e,0x1105f6c2), + LL(0x8733913c,0x68e73500),LL(0x3f3adc40,0xcce86163),LL(0x38a278e9,0xf407a942),LL(0x2ab21292,0xd13c1b9d), LL(0x1c74cf5c,0x93ed7ec7),LL(0xf1a4c1b4,0x8887dc48),LL(0x4b3a11f1,0x3830ff30),LL(0x58937cb6,0x358c5a3c), + LL(0x89022829,0x027dc404),LL(0x3b798f79,0x40e93977),LL(0x38be6ead,0x90ad3337),LL(0xf34c0a5d,0x9c23f6bc), LL(0xfbffd8bb,0xd1711a35),LL(0x1949d3dd,0x60fcfb49),LL(0x7825d93a,0x09c8ef4b),LL(0xa0a8c968,0x24233cff), + LL(0xe6d982af,0x67ade46c),LL(0xe7544d7c,0xebb6bf3e),LL(0x3d8bd087,0xd6b9ba76),LL(0x4dc61280,0x46fe382d), LL(0xb5bdbd75,0xbd39a7e8),LL(0xb8f228fe,0xab381331),LL(0xce1c4300,0x0709a77c),LL(0xf337ceac,0x6a247e56), + LL(0x636288be,0x8f34f21b),LL(0xc8a7c305,0x9dfdca74),LL(0xea919e04,0x6decfd1b),LL(0x8e1991f8,0xcdf2688d), LL(0xd0f8a67e,0xe607df44),LL(0x0b58d010,0xd985df4b),LL(0x0c24f8f4,0x57f834c5),LL(0xa0bf01ae,0xe976ef56), + LL(0xa1c32373,0x536395ac),LL(0x734c0a13,0x351027aa),LL(0x5e6bd5bc,0xd2f1b5d6),LL(0x223debed,0x2b539e24), LL(0x0eaa1d71,0xd4994cec),LL(0x661dcf65,0x2a83381d),LL(0x7b54c740,0x5f1aed2f),LL(0xd6dda5ee,0x0bea3fa5), + LL(0x36cc6134,0x9d4fb684),LL(0xc0a443dd,0x8eb9bbf3),LL(0x383b7d2a,0xfc500e2e),LL(0x5b775257,0x7aad621c), LL(0x0a8f7cc0,0x69284d74),LL(0x07562d65,0xe820c2ce),LL(0x499758ee,0xbf9531b9),LL(0x6ee0cc2d,0x73e95ca5), + LL(0xfbaf50a5,0xf61790ab),LL(0x684e0750,0xdf55e76b),LL(0xf176b005,0xec516da7),LL(0x7a2dddc7,0x575553bb), LL(0x553afa73,0x37c87ca3),LL(0x4d55c251,0x315f3ffc),LL(0xaf3e5d35,0xe846442a),LL(0x6495ff28,0x61b91149), + LL(0xfa326dc3,0x23cc95d3),LL(0x18fc2cea,0x1df4da1f),LL(0xd0a37d59,0x24bf9adc),LL(0x320d6e1e,0xb6710053), LL(0x618344d1,0x96f9667e),LL(0xa06445af,0xcc7ce042),LL(0xd68dbc3a,0xa02d8514),LL(0x280b5a5b,0x4ea109e4), + LL(0xb40961bf,0x5741a7ac),LL(0x6aa56bfa,0x4ada5937),LL(0x02b765d1,0x7feb9145),LL(0xe6ad1582,0x561e97be), LL(0xda3982f5,0xbbc4a5b6),LL(0xb546f468,0x0c2659ed),LL(0x59612d20,0xb8e7e6aa),LL(0xac19e8e0,0xd83dfe20), + LL(0xb835398c,0x8530c45f),LL(0xb38a41c2,0x6106a8bf),LL(0x35f5dcdb,0x21e8f9a6),LL(0xcae498ed,0x39707137), LL(0xd8249f00,0x70c23834),LL(0xab2537a0,0x9f14b58f),LL(0x5f61c0c2,0xd043c365),LL(0x09a194a7,0xdc5926d6), + LL(0x8e77738a,0xddec0339),LL(0xfba46426,0xd07a63ef),LL(0xee7f6e86,0x2e58e79c),LL(0xff32d241,0xe59b0459), LL(0x20fa0338,0xc5ec84e5),LL(0xeaff5ace,0x97939ac8),LL(0xb4a38313,0x0310a4e3),LL(0x8f9d9885,0x9115fba2), + LL(0x5fadf8c3,0x8dd710c2),LL(0xce19c0e2,0x66be38a2),LL(0x4cfe5022,0xd42a279c),LL(0x0e24e1b8,0x597bb530), LL(0xc153ca7f,0x3cde86b7),LL(0x707d63bd,0xa8d30fb3),LL(0xbd60d21e,0xac905f92),LL(0x7b9a54ab,0x98e7ffb6), + LL(0xe9726a30,0xd7147df8),LL(0xafce3533,0xb5e216ff),LL(0x2ff1ec40,0xb550b799),LL(0xa1e953fd,0x6b613b87), LL(0x792d5610,0x87b88dba),LL(0xa190fbe1,0x2ee1270a),LL(0x2ef581da,0x02f4e2dc),LL(0xeff82a95,0x016530e4), + LL(0x8fd6ee89,0xcbb93dfd),LL(0x46848fff,0x16d3d986),LL(0x1da47adf,0x600eff24),LL(0x0ad47a71,0x1b9754a0), LL(0x70c33b98,0x8f9266df),LL(0xdf34186e,0xaadc87ae),LL(0x4ad24132,0x0d2ce8e1),LL(0x19946eba,0x8a47cbfc), + LL(0x62b5f3af,0x47feeb66),LL(0x0abb3734,0xcefab561),LL(0x19f35cb1,0x449de60e),LL(0x157f0eb9,0x39f8db14), LL(0x3c61bfd6,0xffaecc5b),LL(0x41216703,0xa5a4d41d),LL(0x224e1cc2,0x7f8fabed),LL(0x871ad953,0x0d5a8186), + LL(0xd22da9a9,0xf10774f7),LL(0xcc8a9b0d,0x45b8a678),LL(0xbdc32cff,0xd9c2e722),LL(0x337202a5,0xbf71b5f5), LL(0x69fc4db9,0x95c57f2f),LL(0x765d01e1,0xb6dad34c),LL(0xcb904635,0x7e0bd13f),LL(0x763a588c,0x61751253), + LL(0x81af2c2d,0xd85c2997),LL(0x81b9d7da,0xc0f7d9c4),LL(0x08533e8d,0x838a34ae),LL(0x311d8311,0x15c4cb08), LL(0x8e121e14,0x97f83285),LL(0x85000a5f,0xeea7dc1e),LL(0x5d256274,0x0c6059b6),LL(0xb95075c0,0xec9beace), + LL(0x1df97828,0x173daad7),LL(0xa8937877,0xbf851cb5),LL(0x01646f3c,0xb083c594),LL(0x50c6d352,0x3bad30cf), LL(0x496bbcea,0xfeb2b202),LL(0x18a1e8ba,0x3cf9fd4f),LL(0x1c066029,0xd26de7ff),LL(0x4e9ed4f8,0x39c81e9e), + LL(0x7b390d35,0xd8be0cb9),LL(0x964aab27,0x01df2bbd),LL(0xc3ef64f8,0x3e8c1a65),LL(0x716ed1dd,0x567291d1), LL(0x5f5406d3,0x95499c6c),LL(0x5ba8e23f,0x71fdda39),LL(0xd5096ece,0xcfeb320e),LL(0xca66dd16,0xbe7ba92b), + LL(0xc6fb5a7d,0x4608d36b),LL(0x6d2dd0e0,0xe3eea15a),LL(0x8f97a36a,0x75b0a3eb),LL(0x1c83de1e,0xf59814cc), LL(0x1c33c23f,0x56c9c5b0),LL(0x6faa4136,0xa96c1da4),LL(0xde316551,0x46bf2074),LL(0x1f756c8f,0x3b866e7b), + LL(0x1495ed6b,0x727727d8),LL(0xb682dce7,0xb2394243),LL(0x758610f3,0x8ab8454e),LL(0x857d72a4,0xc243ce84), LL(0xdbbf370f,0x7b320d71),LL(0x78e0f7ca,0xff9afa37),LL(0xea7b523f,0x0119d1e0),LL(0x058c7d42,0xb997f8cb), + LL(0x37bbb184,0x285bcd2a),LL(0xa45d1fa6,0x51dcec49),LL(0xe29634cb,0x6ade3b64),LL(0x26b86ef1,0x080c94a7), LL(0x2283fbe3,0xba583db1),LL(0x5a9315ed,0x902bddc8),LL(0x86964bec,0x07c1ccb3),LL(0xb6258301,0x78f4eacf), + LL(0x56f90823,0x4bdf3a49),LL(0x741d777b,0xba0f5080),LL(0xf38bf760,0x091d71c3),LL(0x9b625b02,0x9633d50f), LL(0xb8c9de61,0x03ecb743),LL(0x5de74720,0xb4751254),LL(0x74ce1cb2,0x9f9defc9),LL(0x00bd32ef,0x774a4f6a), + LL(0x73848f22,0xaca385f7),LL(0xf3f8558e,0x53dad716),LL(0x93c471f9,0xab7b34b0),LL(0x19644bc7,0xf530e069), LL(0xdd59d31a,0x3d9fb1ff),LL(0x08daa795,0x4382e0df),LL(0xd5cc88d7,0x165c6f4b),LL(0x4a18c900,0xeaa392d5), + LL(0x648024ee,0x94203c67),LL(0x8c2fabcd,0x188763f2),LL(0xbbaec835,0xa80f87ac),LL(0xf29d8d54,0x632c96e0), LL(0x4c00a95e,0x29b0a60e),LL(0xe011e9fa,0x2ef17f40),LL(0x15b77223,0xf6c0e1d1),LL(0x14b04e32,0xaaec2c62), + LL(0x3d84e58c,0xd35688d8),LL(0x958571db,0x2af5094c),LL(0x760682a6,0x4fff7e19),LL(0xe39a407c,0x4cb27077), LL(0x4ff0e321,0x0f59c547),LL(0x1b34c8ff,0x169f34a6),LL(0x52bc1ba7,0x2bff1096),LL(0x83583544,0xa25423b7), + LL(0x0ac8b782,0x5d55d5d5),LL(0x2db3c892,0xff6622ec),LL(0x6b8bb642,0x48fce741),LL(0x69d7e3dc,0x31d6998c), LL(0xcadcaed0,0xdbaf8004),LL(0xd81d053c,0x801b0142),LL(0x59630ec6,0x94b189fc),LL(0xaf762c8e,0x120e9934), + LL(0xfdc6a404,0x53a29aa4),LL(0xa1909948,0x19d8e01e),LL(0xd7e89681,0x3cfcabf1),LL(0x4e132d37,0x3321a50d), LL(0xe9a86111,0xd0496863),LL(0x06a3bc65,0x8c0cde61),LL(0xfc9f8eef,0xaf866c49),LL(0xff7f5141,0x2066350e), + LL(0xe56ddfbd,0x4f8a4689),LL(0xfe32983a,0xea1b0c07),LL(0x873cb8cb,0x2b317462),LL(0x2d93229f,0x658deddc), LL(0x0f64ef58,0x65efaf4d),LL(0x730cc7a8,0xfe43287d),LL(0x3d047d70,0xaebc0c72),LL(0xd92d26c9,0x92efa539), + LL(0x94b56526,0x06e78457),LL(0x0961002d,0x415cb80f),LL(0x76dcb10f,0x89e5c565),LL(0xff9259fe,0x8bbb6982), LL(0x9abc2668,0x4fe8795b),LL(0x1e678fb1,0xb5d4f534),LL(0x7b7da2b9,0x6601f3be),LL(0xa13d6805,0x98da59e2), + LL(0x01799a52,0x190d8ea6),LL(0xb86d2952,0xa20cec41),LL(0x7fff2a7c,0x3062ffb2),LL(0x79f19d37,0x741b32e5), LL(0x4eb57d47,0xf80d8181),LL(0x16aef06b,0x7a2d0ed4),LL(0x1cecb588,0x09735fb0),LL(0xc6061f5b,0x1641caaa), +}, +/* digit=4 base_pwr=2^28 */ +{ + LL(0x20151427,0x7f99824f),LL(0x92430206,0x206828b6),LL(0xe1112357,0xaa9097d7),LL(0x09e414ec,0xacf9a2f2), LL(0x27915356,0xdbdac9da),LL(0x001efee3,0x7e0734b7),LL(0xd2b288e2,0x54fab5bb),LL(0xf62dd09c,0x4c630fc4), + LL(0x1ac2703b,0x8537107a),LL(0x6bc857b5,0xb49258d8),LL(0xbcdaccd1,0x57df14de),LL(0xc4ae8529,0x24ab68d7), LL(0x734e59d0,0x7ed8b5d4),LL(0xc495cc80,0x5f8740c8),LL(0x291db9b3,0x84aedd5a),LL(0x4fb995be,0x80b360f8), + LL(0x5fa067d1,0xae915f5d),LL(0x9668960c,0x4134b57f),LL(0xa48edaac,0xbd3656d6),LL(0xfc1d7436,0xdac1e3e4), LL(0xd81fbb26,0x674ff869),LL(0xb26c33d4,0x449ed3ec),LL(0xd94203e8,0x85138705),LL(0xbeeb6f4a,0xccde538b), + LL(0xa61a76fa,0x55d5c68d),LL(0xca1554dc,0x598b441d),LL(0x773b279c,0xd39923b9),LL(0x36bf9efc,0x33331d3c), LL(0x298de399,0x2d4c848e),LL(0xa1a27f56,0xcfdb8e77),LL(0x57b8ab70,0x94c855ea),LL(0x6f7879ba,0xdcdb9dae), + LL(0x019f2a59,0x7bdff8c2),LL(0xcb4fbc74,0xb3ce5bb3),LL(0x8a9173dd,0xea907f68),LL(0x95a75439,0x6cd3d0d3), LL(0xefed021c,0x92ecc4d6),LL(0x6a77339a,0x09a9f9b0),LL(0x7188c64a,0x87ca6b15),LL(0x44899158,0x10c29968), + LL(0xed6e82ef,0x5859a229),LL(0x65ebaf4e,0x16f338e3),LL(0x5ead67ae,0x0cd31387),LL(0x54ef0bb4,0x1c73d228), LL(0x74a5c8c7,0x4cb55131),LL(0x7f69ad6a,0x01cd2970),LL(0xe966f87e,0xa04d00dd),LL(0x0b7b0321,0xd96fe447), + LL(0x88fbd381,0x342ac06e),LL(0x5c35a493,0x02cd4a84),LL(0x54f1bbcd,0xe8fa89de),LL(0x2575ed4c,0x341d6367), LL(0xd238202b,0xebe357fb),LL(0xa984ead9,0x600b4d1a),LL(0x52436ea0,0xc35c9f44),LL(0xa370751b,0x96fe0a39), + LL(0x7f636a38,0x4c4f0736),LL(0x0e76d5cb,0x9f943fb7),LL(0xa8b68b8b,0xb03510ba),LL(0x9ed07a1f,0xc246780a), LL(0x6d549fc2,0x3c051415),LL(0x607781ca,0xc2953f31),LL(0xd8d95413,0x955e2c69),LL(0x7bd282e3,0xb300fadc), + LL(0x87e9189f,0x81fe7b50),LL(0xf42dda27,0xdb17375c),LL(0xcf0a5904,0x22f7d896),LL(0xebe348e6,0xa0e57c5a), LL(0xf40e3c80,0xa61011d3),LL(0x8db705c5,0xb1189321),LL(0x50fedec3,0x4ed9309e),LL(0x4d6d5c1d,0xdcf14a10), + LL(0x55691342,0x056c265b),LL(0x91049dc7,0xe8e08504),LL(0xc9bae20a,0x131329f5),LL(0xd9dccdb4,0x96c8b3e8), LL(0xfb4ee6b4,0x8c5ff838),LL(0x41e8ccf0,0xfc5a9aeb),LL(0xfae050c6,0x7417b764),LL(0x00452080,0x0953c3d7), + LL(0x38dfe7e8,0x21372682),LL(0x2bb79d4b,0xea417e15),LL(0x76e7cf2d,0x59641f1c),LL(0xea0bcfcc,0x271e3059), LL(0x7253ecbd,0x624c7dfd),LL(0x4fca6186,0x2f552e25),LL(0x4d866e9c,0xcbf84ecd),LL(0xf68d4610,0x73967709), + LL(0xc27901b4,0xa14b1163),LL(0x899b8bf3,0xfd9236e0),LL(0xcbc6da0a,0x42b091ec),LL(0x5ad1d297,0xbb1dac6f), LL(0xa91cf76e,0x80e61d53),LL(0xd31f1ee7,0x4110a412),LL(0x13efcf77,0x2d87c3ba),LL(0xdf450d76,0x1f374bb4), + LL(0x0d188dab,0x5e78e2f2),LL(0xf4b885ef,0xe3968ed0),LL(0x7314570f,0x46c0568e),LL(0x01170521,0x31616338), LL(0x4f0c8afe,0x18e1e7e2),LL(0xdeea78da,0x4caa75ff),LL(0x7c5d8a51,0x82db67f2),LL(0x6f505370,0x36a44d86), + LL(0x0333974f,0xd72c5bda),LL(0x27a70146,0x5db516ae),LL(0x210ef921,0x34705281),LL(0x0c9c38e5,0xbff17a8f), LL(0x12476da1,0x78f4814e),LL(0x33c16980,0xc1e16613),LL(0x424d4bca,0x9e5b386f),LL(0xc85740de,0x4c274e87), + LL(0x6c2f5226,0xb6a9b88d),LL(0x550d7ca8,0x14d1b944),LL(0x1fc41709,0x580c85fc),LL(0x54c6d519,0xc1da368b), LL(0xd5113cf7,0x2b0785ce),LL(0x5a34708f,0x0670f633),LL(0x15cc3f88,0x46e23767),LL(0x50c72c8f,0x1b480cfa), + LL(0x4147519a,0x20288602),LL(0x26b372f0,0xd0981eac),LL(0xa785ebc8,0xa9d4a7ca),LL(0xdbdf58e9,0xd953c50d), LL(0xfd590f8f,0x9d6361cc),LL(0x44e6c917,0x72e9626b),LL(0x22eb64cf,0x7fd96110),LL(0x9eb288f3,0x863ebb7e), + LL(0x6aca8ee7,0x6e6ab761),LL(0xd7b40358,0x97d10b39),LL(0x1e5feb0d,0x1687d377),LL(0x8265a27a,0xc83e50e4), LL(0xc954b313,0x8f75a9fe),LL(0x310d1f61,0xcc2e8f47),LL(0x6557d0e0,0xf5ba81c5),LL(0x3eaf6207,0x25f9680c), + LL(0x4354080b,0xf95c6609),LL(0x7bf2fe1c,0x5225bfa5),LL(0x5c7d98fa,0xc5c004e2),LL(0x019aaf60,0x3561bf1c), LL(0xba151474,0x5e6f9f17),LL(0xb04f6eca,0xdec2f934),LL(0x269acb1e,0x64e368a1),LL(0x0cdda493,0x1332d9e4), + LL(0xdf23de05,0x60d6cf69),LL(0x009339a0,0x66d17da2),LL(0x0a693923,0x9fcac985),LL(0xed7c6a6d,0xbcf057fc), LL(0xf0b5662c,0xc3c5c8c5),LL(0xdcba4f24,0x25318dd8),LL(0x082b69ff,0x60e8cb75),LL(0x1e728c01,0x7c23b3ee), + LL(0x097e4403,0x15e10a0a),LL(0x19854665,0xcb3d0a86),LL(0xd67d4826,0x88d8e211),LL(0x0b9d2839,0xb39af66e), LL(0xbd475ca8,0xa5f94588),LL(0xc077b80b,0xe06b7966),LL(0xda27c26c,0xfedb1485),LL(0xfe0fd5e0,0xd290d33a), + LL(0xf34fb0fa,0xa40bcc47),LL(0x1fb1ab09,0xb4760cc8),LL(0xa273bfe3,0x8fca0993),LL(0xf70b213c,0x13e4fe07), LL(0xfdb05163,0x3bcdb992),LL(0x0c2b19b6,0x8c484b11),LL(0xaaf2e3e2,0x1acb815f),LL(0xb89ff1b4,0xc6905935), + LL(0x586e74e1,0xb2ad6f9d),LL(0x67b80484,0x488883ad),LL(0x369c3ddb,0x758aa2c7),LL(0x9f9afd31,0x8ab74e69), LL(0x5e21beb1,0x10fc2d28),LL(0x318c42f9,0x3484518a),LL(0x53cf40c3,0x377427dc),LL(0x391bc1d9,0x9de0781a), + LL(0x693807e1,0x8faee858),LL(0x4e81ccc7,0xa3865327),LL(0x6f835b84,0x02c30ff2),LL(0x0d3d38d4,0xb604437b), LL(0x5ca1823d,0xb3fc8a98),LL(0x03be0324,0xb82f7ec9),LL(0xcf684a33,0xee36d761),LL(0x9f29bf7d,0x5a01df0e), + LL(0x1306583d,0x686202f3),LL(0x437c622e,0x05b10da0),LL(0x076a7bc8,0xbf9aaa0f),LL(0x8f8f4e43,0x25e94efb), LL(0xfa3dc26d,0x8a35c9b7),LL(0x96ff03c5,0xe0e5fb93),LL(0xebc394ce,0xa77e3843),LL(0x8361de60,0xcede6595), + LL(0xa1993545,0xd27c22f6),LL(0x24d671ba,0xab01cc36),LL(0xa169c28e,0x63fa2877),LL(0x2eb08376,0x925ef904), LL(0x53aa0b32,0x3b2fa3cf),LL(0x71c49d7a,0xb27beb5b),LL(0xd105e27f,0xb60e1834),LL(0x4f68570d,0xd6089788), + LL(0xd6fbc2ac,0x23094ce0),LL(0x815ff551,0x738037a1),LL(0x6bef119c,0xda73b1bb),LL(0xeef506ba,0xdcf6c430), LL(0xe3ef104a,0x00e4fe7b),LL(0x0a065628,0xebdd9a2c),LL(0x8792043e,0x853a81c3),LL(0xb3b59108,0x22ad6ece), + LL(0x39cd297d,0x9fb813c0),LL(0x05bda5d9,0x8ec7e16e),LL(0x0d104b96,0x2834797c),LL(0x7c511510,0xcc11a2e7), LL(0x96ee6380,0x96ca5a53),LL(0xcea38742,0x054c8655),LL(0xd54dfa7d,0xb5946852),LL(0x1f4ab207,0x97c422e7), + LL(0x0c22b540,0xbf907509),LL(0xb7c267d4,0x2cde42aa),LL(0x5ab0d693,0xba18f9ed),LL(0x6e4660d9,0x3ba62aa6), LL(0xab9ea96a,0xb24bf97b),LL(0xe3b60e32,0x5d039642),LL(0x7c4d9bd5,0x4e6a4506),LL(0x7ed4a6a4,0x666c5b9e), + LL(0x8edbd7cc,0xfa3fdcd9),LL(0xc6ccd753,0x4660bb87),LL(0x21e6b64f,0x9ae90820),LL(0xb36bfb3f,0x8a56a713), LL(0x5726d47f,0xabfce096),LL(0x0b1a9a7f,0x9eed01b2),LL(0x4eb74a37,0x30e9cad4),LL(0x53e9666d,0x7b2524cc), + LL(0x8f4b002f,0x6a29683b),LL(0x41f4fc20,0xc2200d7a),LL(0x3a338acc,0xcf3af47a),LL(0xe7128975,0x6539a4fb), LL(0xc33c7fcf,0xcec31c14),LL(0xc7be322b,0x7eb6799b),LL(0x6646f623,0x119ef4e9),LL(0x54d7299b,0x7b7a26a5), + LL(0x403f46f2,0xcb37f08d),LL(0x1a0ec0c7,0x94b8fc43),LL(0xc332142f,0xbb8514e3),LL(0xe80d2a7a,0xf3ed2c33), LL(0xb639126c,0x8d2080af),LL(0xe3553ade,0xf7b6be60),LL(0x1c7e2b09,0x3950aa9f),LL(0x6410f02b,0x847ff958), + LL(0x678a31b0,0x877b7cf5),LL(0x3998b620,0xd50301ae),LL(0xc00fb396,0x734257c5),LL(0x04e672a6,0xf9fb18a0), LL(0xe8758851,0xff8bd8eb),LL(0x5d99ba44,0x1e64e4c6),LL(0x7dfd93b7,0x4b8eaedf),LL(0x04e76b8c,0xba2f2a98), + LL(0xe8053433,0x7d790cba),LL(0x3d2c9585,0xc8e725a0),LL(0xcdd8f5ed,0x58c5c476),LL(0xefa9fe1d,0xd106b952), LL(0x0eff13a9,0x3c5c775b),LL(0xe057b930,0x242442ba),LL(0xc9b70cbd,0xe9f458d4),LL(0xa3cdb89a,0x69b71448), + LL(0x0e2ed742,0x41ee46f6),LL(0x40067493,0x573f1045),LL(0x9d54c304,0xb1e154ff),LL(0x8d3a7502,0x2ad0436a), LL(0x431a8121,0xee4aaa2d),LL(0x886f11ed,0xcd38b3ab),LL(0x034a0eb7,0x57d49ea6),LL(0xf7e85e58,0xd2b773bd), + LL(0x9b5c1f14,0x4a559ac4),LL(0x3e54df2b,0xc444be1a),LL(0xeda41891,0x13aad704),LL(0x5eb5c788,0xcd927bec), LL(0xe48c8a34,0xeb3c8516),LL(0x4b546669,0x1b7ac812),LL(0x594df8ec,0x1815f896),LL(0x79227865,0x87c6a79c), + LL(0x9b56ddbd,0xae02a2f0),LL(0x8a2f1cf3,0x1339b5ac),LL(0x839dff0d,0xf2b569c7),LL(0xfee9a43d,0xb0b9e864), LL(0x77bb064e,0x4ff8ca41),LL(0xfd249f63,0x145a2812),LL(0xf86f689a,0x3ab7beac),LL(0x01d35f5e,0x9bafec27), + LL(0x4265aa91,0x28054c65),LL(0x035efe42,0xa4b18304),LL(0x9639dec7,0x6887b0e6),LL(0x3d52aea5,0xf4b8f6ad), LL(0x971a8a13,0xfb9293cc),LL(0x4c934d07,0x3f159e5d),LL(0x09acbc29,0x2c50e9b1),LL(0x7154d129,0x08eb65e6), + LL(0x30b75c3e,0x4feff589),LL(0x94491c93,0x0bb82fe2),LL(0x89af62bb,0xd8ac377a),LL(0x9685e49f,0xd7b51490), LL(0x04497f19,0xabca9a7b),LL(0x1a7ad13f,0x1b35ed0a),LL(0x3ec86ed6,0x6b601e21),LL(0xce0c76f1,0xda91fcb9), + LL(0xd7ab27e1,0x9e28507b),LL(0x63945b7b,0x7c19a555),LL(0xaafc9827,0x6b43f0a1),LL(0x3aa55b91,0x443b4fbd), LL(0x6962c88f,0x962b2e65),LL(0xce0db0ca,0x139da8d4),LL(0x1b8d6c4f,0xb93f05dd),LL(0x180b9824,0x779cdff7), + LL(0xae57c7b7,0xbba23fdd),LL(0x1b932522,0x345342f2),LL(0x556d4aa3,0xfd9c80fe),LL(0x6525bb61,0xa03907ba), LL(0xff218933,0x38b010e1),LL(0xaa52117b,0xc066b654),LL(0x94f2e6ea,0x8e141920),LL(0x0d32f2b2,0x66a27dca), + LL(0x048b3717,0x69c7f993),LL(0xb178ae1c,0xbf5a989a),LL(0x564f1d6b,0x49fa9058),LL(0xd31fde4e,0x27ec6e15), LL(0x7276e7fc,0x4cce0373),LL(0x89d6bf02,0x64086d79),LL(0x4ccdd979,0x5a72f046),LL(0x47775631,0x909c3566), + LL(0x75dd7125,0x1c07bc6b),LL(0x87a0428d,0xb4c6bc97),LL(0xfdeb6b9d,0x507ece52),LL(0xb2c95432,0xfca56512), LL(0xd0e8bd06,0x15d97181),LL(0xc6bb46ea,0x384dd317),LL(0x3952b624,0x5441ea20),LL(0x4e7dc2fb,0xbcf70dee), + LL(0x6628e8c3,0x372b016e),LL(0xb60a7522,0x07a0d667),LL(0x0a344ee2,0xcf05751b),LL(0x118bdeec,0x0ec09a48), LL(0xd83dce46,0x6e4b3d4e),LL(0x99d2fc6e,0x43a6316d),LL(0x56cf044c,0xa99d8989),LL(0xae3e5fb7,0x7c7f4454), + LL(0xfbabbe92,0xb2e6b121),LL(0xe1330076,0x281850fb),LL(0x97890015,0x093581ec),LL(0x75ff77f5,0x69b1dded), LL(0xab105105,0x7cf0b18f),LL(0xa89ccfef,0x953ced31),LL(0xeb914009,0x3151f85f),LL(0x88ed48ad,0x3c9f1b87), + LL(0x4a7eadcb,0xc9aba1a1),LL(0x522e71cf,0x928e7501),LL(0x3a2e4f83,0xeaede727),LL(0x1ce3bbd3,0x467e10d1), LL(0xb955dcf0,0xf3442ac3),LL(0xd3d5e527,0xba96307d),LL(0xfd77f474,0xf763a10e),LL(0x6a6e1ff0,0x5d744bd0), + LL(0xa777899e,0xd287282a),LL(0xd03f3cde,0xe20eda8f),LL(0x50b07d31,0x6a7e75bb),LL(0x6f379de4,0x0b7e2a94), LL(0x19f593cf,0x31cb64ad),LL(0x1e76ef1d,0x7b1a9e4f),LL(0xb62d609c,0xe18c9c9d),LL(0xe779a650,0x439bad6d), + LL(0xe032f144,0x219d9066),LL(0xe8b2ec6a,0x1db632b8),LL(0xfda12f78,0xff0d0fd4),LL(0x2a25d265,0x56fb4c2d), LL(0x255a03f1,0x5f4e2ee1),LL(0xe96af176,0x61cd6af2),LL(0xd068bc97,0xe0317ba8),LL(0x264b988e,0x927d6bab), + LL(0xe90fb21e,0xa18f07e0),LL(0xbba7fca1,0x00fd2b80),LL(0x95cd67b5,0x20387f27),LL(0xd39707f7,0x5b89a4e7), LL(0x894407ce,0x8f83ad3f),LL(0x6c226132,0xa0025b94),LL(0xf906c13b,0xc79563c7),LL(0x4e7bb025,0x5f548f31), + LL(0xeac6d113,0x2b4c6b8f),LL(0x0e813c76,0xa67e3f9c),LL(0x3fe1f4b9,0x3982717c),LL(0x26d8050e,0x58865819), LL(0xf7f06f20,0x99f3640c),LL(0x2a66ebc2,0xdc610216),LL(0x767a1e08,0x52f2c175),LL(0x5999871b,0x05660e1a), + LL(0x6d3c4693,0x6b0f1762),LL(0x37ed7bea,0xf0e7d627),LL(0xb75b226d,0xc51758c7),LL(0x1f91613b,0x40a88628), LL(0xbbb38ce0,0x889dbaa7),LL(0xbddcad81,0xe0404b65),LL(0x8bc9671f,0xfebccd3a),LL(0xee1f5375,0xfbf9a357), + LL(0x28f33398,0x5dc169b0),LL(0x72e90f65,0xb07ec11d),LL(0xfaab1eb1,0xae7f3b4a),LL(0x5f17538a,0xd970195e), LL(0x0181e640,0x52b05cbe),LL(0x2643313d,0xf5debd62),LL(0x5df31f82,0x76148154),LL(0x3a9e13c5,0x23e03b33), + LL(0x4fde0c1f,0xff758949),LL(0xe5b6ec20,0xbf8a1abe),LL(0x87e1db6c,0x702278fb),LL(0x35ed658f,0xc447ad7a), LL(0x03d0ccf2,0x48d4aa38),LL(0x819a7c03,0x80acb338),LL(0x6e17cecc,0x9bc7c89e),LL(0x03be1d82,0x46736b8b), + LL(0xc0432f96,0xd65d7b60),LL(0xdeb5442f,0xddebe7a3),LL(0x7dff69a2,0x79a25307),LL(0x02cf3122,0x37a56d94), LL(0xf2350d0a,0x8bab8aed),LL(0x037b0d9a,0x13c3f276),LL(0x44c65cae,0xc664957c),LL(0xc2e71a88,0x88b44089), + LL(0x5cb02664,0xdb88e5a3),LL(0x8686c72e,0x5d4c0bf1),LL(0xa682d53e,0xea3d9b62),LL(0x0b2ad431,0x9b605ef4), LL(0xc69645d0,0x71bac202),LL(0x6a1b66e7,0xa115f03a),LL(0x158f4dc4,0xfe2c563a),LL(0x4d12a78c,0xf715b3a0), + LL(0xd413213a,0x8f7f0a48),LL(0xc04becdb,0x2035806d),LL(0x5d8587f5,0xecd34a99),LL(0x9f6d3a71,0x4d8c3079), LL(0x8d95a8f6,0x1b2a2a67),LL(0xf2110d0d,0xc58c9d7d),LL(0xcf8fba3f,0xdeee81d5),LL(0x0c7cdf68,0xa42be3c0), + LL(0xd43b5eaa,0x2126f742),LL(0xdfa59b85,0x054a0766),LL(0x126bfd45,0x9d0d5e36),LL(0x384f8a8f,0xa1f8fbd7), LL(0xd563fccc,0x317680f5),LL(0xf280a928,0x48ca5055),LL(0x27b578cf,0xe00b81b2),LL(0x2994a514,0x10aad918), + LL(0xb7bdc953,0xd9e07b62),LL(0x5bc086dd,0x9f0f6ff2),LL(0x655eee77,0x09d1ccff),LL(0x5bef7df1,0x45475f79), LL(0x86f702cc,0x3faa28fa),LL(0x0f021f07,0x92e60905),LL(0x7f8fa8c6,0xe9e62968),LL(0xf036ea2c,0xbd71419a), + LL(0x6028da9a,0x171ee1cc),LL(0xc251f573,0x5352fe1a),LL(0x3fa997f4,0xf8ff236e),LL(0xa5749d5f,0xd831b6c9), LL(0xe350e2c2,0x7c872e1d),LL(0x1e0ce403,0xc56240d9),LL(0x6974f5cb,0xf9deb077),LL(0x961c3728,0x7d50ba87), + LL(0x5a3a2518,0xd6f89426),LL(0xc6303d43,0xcf817799),LL(0x619e5696,0x510a0471),LL(0x3a5e307b,0xab049ff6), LL(0xfeb13ec7,0xe4cdf9b0),LL(0x9d8ff90c,0xd5e97117),LL(0x9afa96af,0xf6f64d06),LL(0x9d2012a2,0x00d0bf5e), + LL(0x358bcdc0,0xe63f301f),LL(0x0a9d47f8,0x07689e99),LL(0x4f43d43a,0x1f689e2f),LL(0x90920904,0x4d542a16), LL(0x9ca0a707,0xaea293d5),LL(0x8ac68065,0xd061fe45),LL(0x0090008c,0x1033bf1b),LL(0xc08a6db6,0x29749558), + LL(0xc1d5d034,0x74b5fc59),LL(0x67e215e0,0xf712e9f6),LL(0x860200e6,0xfd520cbd),LL(0x3ea22588,0x0229acb4), LL(0xfff0c82e,0x9cd1e14c),LL(0x59c69e73,0x87684b62),LL(0x96ccb989,0xda85e61c),LL(0xa3d06493,0x2d5dbb02), + LL(0xe86b173c,0xf22ad33a),LL(0xa79ff0e3,0xe8e41ea5),LL(0xdd0d0c10,0x01d2d725),LL(0x032d28f9,0x31f39088), LL(0x7829839e,0x7b3f71e1),LL(0x4502ae58,0x0cf691b4),LL(0xbefc6115,0xef658dbd),LL(0xb3ab5314,0xa5cd6ee5), + LL(0x5f1d2347,0x206c8d7b),LL(0x4cc2253a,0x794645ba),LL(0x58389e08,0xd517d8ff),LL(0x9f847288,0x4fa20dee), LL(0xd797770a,0xeba072d8),LL(0xbf429e26,0x7360c91d),LL(0x80af8279,0x7200a3b3),LL(0x82dadce3,0x6a1c9150), + LL(0xc35d8794,0x0ee6d3a7),LL(0x0356bae5,0x042e6558),LL(0x643322fd,0x9f59698d),LL(0x50a61967,0x9379ae15), LL(0xfcc9981e,0x64b9ae62),LL(0x6d2934c6,0xaed3d631),LL(0x5e4e65eb,0x2454b302),LL(0xf9950428,0xab09f647), +}, +/* digit=5 base_pwr=2^35 */ +{ + LL(0x22248acc,0xb2083a12),LL(0x3264e366,0x1f6ec0ef),LL(0x5afdee28,0x5659b704),LL(0xe6430bb5,0x7a823a40), LL(0xe1900a79,0x24592a04),LL(0xc9ee6576,0xcde09d4a),LL(0x4b5ea54a,0x52b6463f),LL(0xd3ca65a7,0x1efe9ed3), + LL(0x305406dd,0xe27a6dbe),LL(0xdd5d1957,0x8eb7dc7f),LL(0x387d4d8f,0xf54a6876),LL(0xc7762de4,0x9c479409), LL(0x99b30778,0xbe4d5b5d),LL(0x6e793682,0x25380c56),LL(0xdac740e3,0x602d37f3),LL(0x1566e4ae,0x140deabe), + LL(0xafd32acf,0x4481d067),LL(0xe1f71ccf,0xd8f0fcca),LL(0xb596f2da,0xd208dd0c),LL(0x9aad93f9,0xd049d730), LL(0x42ab580e,0xc79f263d),LL(0x23f707b4,0x09411bb1),LL(0x835e0eda,0x8cfde1ff),LL(0x90f03402,0x72707490), + LL(0xc49a861e,0xeaee6126),LL(0xe14f0d06,0x024f3b65),LL(0xc69bfc17,0x51a3f1e8),LL(0xa7686381,0xc3c3a8e9), LL(0xb103d4c8,0x3400752c),LL(0x9218b36b,0x02bc4613),LL(0x7651504a,0xc67f75eb),LL(0xd02aebfa,0xd6848b56), + LL(0xc30fa92b,0xbd9802e6),LL(0x9a552784,0x5a70d96d),LL(0x3f83169b,0x9085c4ea),LL(0x06908228,0xfa9423bb), LL(0xfe97a5b9,0x2ffebe12),LL(0x71b99118,0x85da6049),LL(0x63178846,0x9cbc2f7f),LL(0x9153218e,0xfd96bc70), + LL(0x1782269b,0x958381db),LL(0x2597e550,0xae34bf79),LL(0x5f385153,0xbb5c6064),LL(0xe3088048,0x6f0e96af), LL(0x77884456,0xbf6a0215),LL(0x69310ea7,0xb3b5688c),LL(0x04fad2de,0x17c94295),LL(0x17896d4d,0xe020f0e5), + LL(0x0976505f,0x730ba0ab),LL(0x095e2ec5,0x567f6813),LL(0x6331ab71,0x47062010),LL(0x41d22b9f,0x72cfa977), LL(0x8a2373da,0x33e55ead),LL(0x7ba45a68,0xa8d0d5f4),LL(0x03029d15,0xba1d8f9c),LL(0xfc55b9f3,0x8f34f1cc), + LL(0xbbe5a1a9,0xcca4428d),LL(0x3126bd67,0x8187fd5f),LL(0x48105826,0x0036973a),LL(0xb8bd61a0,0xa39b6663), LL(0x2d65a808,0x6d42deef),LL(0x94636b19,0x4969044f),LL(0xdd5d564c,0xf611ee47),LL(0xd2873077,0x7b2f3a49), + LL(0x300eb294,0x94157d45),LL(0x169c1494,0x2b2a656e),LL(0xd3a47aa9,0xc000dd76),LL(0xa6243ea4,0xa2864e4f), LL(0xdb89842e,0x82716c47),LL(0x61479fb7,0x12dfd7d7),LL(0xe0b2f6dc,0x3b9a2c56),LL(0xd7f85d67,0x46be862a), + LL(0x0f82b214,0x03b0d8dd),LL(0xf103cbc6,0x460c34f9),LL(0x18d79e19,0xf32e5c03),LL(0xa84117f8,0x8b8888ba), LL(0xc0722677,0x8f3c37dc),LL(0x1c1c0f27,0x10d21be9),LL(0xe0f7a0c6,0xd47c8468),LL(0xadecc0e0,0x9bf02213), + LL(0x42b48b99,0x0baa7d12),LL(0x48424096,0x1bcb665d),LL(0xebfb5cfb,0x8b847cd6),LL(0x9ad4d10d,0x87c2ae56), LL(0x0de36726,0xf1cbb122),LL(0x3fdfbd21,0xe7043c68),LL(0x4e79d460,0x4bd0826a),LL(0x4bd1a2cb,0x11f5e598), + LL(0xb7fe7b6e,0x97554160),LL(0x400a3fb2,0x7d16189a),LL(0xe328ca1e,0xd73e9bea),LL(0xe793d8cc,0x0dd04b97), LL(0x506db8cc,0xa9c83c9b),LL(0xcf38814c,0x5cd47aae),LL(0xb64b45e6,0x26fc430d),LL(0xd818ea84,0x079b5499), + LL(0xc1c24a3b,0xebb01102),LL(0x1c161c1a,0xca24e568),LL(0x36f00a4a,0x103eea69),LL(0x76176c7b,0x9ad76ee8), LL(0x538e0ff7,0x97451fc2),LL(0x6604b3b0,0x94f89809),LL(0x3249cfd7,0x6311436e),LL(0x41224f69,0x27b4a7bd), + LL(0xe0ac2941,0x03b5d21a),LL(0xc2d31937,0x279b0254),LL(0xcac992d0,0x3307c052),LL(0xefa8b1f3,0x6aa7cb92), LL(0x0d37c7a5,0x5a182580),LL(0x342d5422,0x13380c37),LL(0xd5d2ef92,0x92ac2d66),LL(0x030c63c6,0x035a70c9), + LL(0x4ce4f152,0xc16025dd),LL(0xf9df7c06,0x1f419a71),LL(0x91e4bb14,0x6d5b2214),LL(0x839fb4ce,0xfc43c6cc), LL(0x925d6b2d,0x49f06591),LL(0x62186598,0x4b37d9d3),LL(0xd01b1629,0x8c54a971),LL(0x51d50e05,0xe1a9c29f), + LL(0x71ba1861,0x5109b785),LL(0xd0c8f93d,0x48b22d5c),LL(0x8633bb93,0xe8fa84a7),LL(0x5aebbd08,0x53fba6ba), LL(0xe5eea7d8,0x7ff27df3),LL(0x68ca7158,0x521c8796),LL(0xce6f1a05,0xb9d5133b),LL(0xfd0ebee4,0x2d50cd53), + LL(0xc5a3ef16,0xc82115d6),LL(0xba079221,0x993eff9d),LL(0x4b5da81c,0xe4da2c5e),LL(0x8033fd85,0x9a89dbdb), LL(0x2b892891,0x60819ebf),LL(0x5d14a4d5,0x53902b21),LL(0xd7fda421,0x6ac35051),LL(0x61c83284,0xcc6ab885), + LL(0xf74cff17,0x14eba133),LL(0xecb813f2,0x240aaa03),LL(0x6f665bee,0xcfbb6540),LL(0xa425ad73,0x084b1fe4), LL(0xd081f6a6,0x009d5d16),LL(0xeef82c90,0x35304fe8),LL(0xaa9eaa22,0xf20346d5),LL(0xac1c91e3,0x0ada9f07), + LL(0x968a6144,0xa6e21678),LL(0x07b31a1e,0x54c1f77c),LL(0x5781fbe1,0xd6bb787e),LL(0xe31f1c4a,0x61bd2ee0), LL(0x781105fc,0xf25aa1e9),LL(0x7b2f8e80,0x9cf2971f),LL(0xcdff919b,0x26d15412),LL(0x34bc896e,0x01db4ebe), + LL(0xb40df1cf,0x7d9b3e23),LL(0x94e971b4,0x59337373),LL(0x669cf921,0xbf57bd14),LL(0x0c1a1064,0x865daedf), LL(0x83279125,0x3eb70bd3),LL(0x34ecdaab,0xbc3d5b9f),LL(0x5f755caf,0x91e3ed7e),LL(0xd41e6f02,0x49699f54), + LL(0xd4a7a15b,0x185770e1),LL(0xeaac87e7,0x08f3587a),LL(0x473133ea,0x352018db),LL(0x04fd30fc,0x674ce719), LL(0x088b3e0e,0x7b8d9835),LL(0x5d0d47a1,0x7a0356a9),LL(0x6474a3c4,0x9d9e7659),LL(0xff66966c,0x61ea48a7), + LL(0x0f3e4834,0x30417758),LL(0x17a9afcb,0xfdbb21c2),LL(0x2f9a67b3,0x756fa17f),LL(0xa245c1a8,0x2a6b2421), LL(0x4af02291,0x64be2794),LL(0x2a5804fe,0xade465c6),LL(0xa6f08fd7,0x8dffbd39),LL(0xaa14403b,0xc4efa84c), + LL(0x442b0f5c,0xa1b91b2a),LL(0xcf997736,0xb748e317),LL(0xcee90e16,0x8d1b62bf),LL(0x0b2078c0,0x907ae271), LL(0x0c9bcddd,0xdf31534b),LL(0x39adce83,0x043fb054),LL(0xd826846a,0x99031043),LL(0xb144f393,0x61a9c0d6), + LL(0x47718427,0xdab48046),LL(0x6e830f8b,0xdf17ff9b),LL(0xe49a1347,0x408d7ee8),LL(0x91c1d4ae,0x6ac71e23), LL(0x1defd73c,0xc8cbb9fd),LL(0xbbbbfec5,0x19840657),LL(0x9e7ef8ea,0x39db1cb5),LL(0x64105f30,0x78aa8296), + LL(0xa3738c29,0xa3d9b7f0),LL(0xbc3250a3,0x0a2f235a),LL(0x445e4caf,0x55e506f6),LL(0x33475f7a,0x0974f73d), LL(0x5ba2f5a8,0xd37dbba3),LL(0x6af40066,0x542c6e63),LL(0xc5d73e2c,0x26d99b53),LL(0x6c3ca33e,0x06060d7d), + LL(0x065fef4a,0xcdbef1c2),LL(0xfd5b92e3,0x77e60f7d),LL(0x26708350,0xd7c549f0),LL(0x34f121bf,0x201b3ad0), LL(0x0334fc14,0x5fcac2a1),LL(0x344552f6,0x8a9a9e09),LL(0x97653082,0x7dd8a1d3),LL(0x79d4f289,0x5fc0738f), + LL(0x17d2d8c3,0x787d244d),LL(0x70830684,0xeffc6345),LL(0xe4f73ae5,0x5ddb96dd),LL(0x172549a5,0x8efb14b1), LL(0x2245ae7a,0x6eb73eee),LL(0xea11f13e,0xbca4061e),LL(0x30b01f5d,0xb577421d),LL(0x782e152c,0xaa688b24), + LL(0xbd3502ba,0x67608e71),LL(0xb4de75a0,0x4ef41f24),LL(0xfd6125e5,0xb08dde5e),LL(0xa409543f,0xde484825), LL(0x65cc2295,0x1f198d98),LL(0x6e0edfa2,0x428a3771),LL(0xadf35fc7,0x4f9697a2),LL(0xf7cac3c7,0x01a43c79), + LL(0x0fd3659a,0xb05d7059),LL(0xbb7f2d9a,0x8927f30c),LL(0x8cf984d3,0x4023d1ac),LL(0x02897a45,0x32125ed3), LL(0x3d414205,0xfb572dad),LL(0xe3fa82a9,0x73000ef2),LL(0xf10a5581,0x4c0868e9),LL(0x6b0b3ca5,0x5b61fc67), + LL(0x7cae440c,0xc1258d5b),LL(0x402b7531,0x21c08b41),LL(0xde932321,0xf61a8955),LL(0x2d1408af,0x3568faf8), LL(0x9ecf965b,0x71b15e99),LL(0xe917276f,0xf14ed248),LL(0x820cf9e2,0xc6f4caa1),LL(0x18d83c7e,0x681b20b2), + LL(0xc6c01120,0x6cde738d),LL(0xae70e0db,0x71db0813),LL(0x74afe18c,0x95fc0644),LL(0x129e2be7,0x34619053), LL(0xdb2a3b15,0x80615cea),LL(0xdb4c7073,0x0a49a19e),LL(0x8fd2d367,0x0e1b84c8),LL(0x033fb8aa,0xd74bf462), + LL(0x533ef217,0x889f6d65),LL(0xc3ca2e87,0x7158c7e4),LL(0xdc2b4167,0xfb670dfb),LL(0x844c257f,0x75910a01), LL(0xcf88577d,0xf336bf07),LL(0xe45e2ace,0x22245250),LL(0x7ca23d85,0x2ed92e8d),LL(0x2b812f58,0x29f8be4c), + LL(0x076fe12b,0xdd9ebaa7),LL(0xae1537f9,0x3f2400cb),LL(0x17bdfb46,0x1aa93528),LL(0x67883b41,0xc0f98430), LL(0x0170911d,0x5590ede1),LL(0x34d4b17f,0x7562f5bb),LL(0x1826b8d2,0xe1fa1df2),LL(0x6bd80d59,0xb40b796a), + LL(0x3467ba92,0xd65bf197),LL(0xf70954b0,0x8c9b46db),LL(0x0e78f15d,0x97c8a0f3),LL(0x85a4c961,0xa8f3a69a), LL(0x61e4ce9b,0x4242660f),LL(0x6ea6790c,0xbf06aab3),LL(0xec986416,0xc6706f8e),LL(0x9a9fc225,0x9e56dec1), + LL(0x9a9898d9,0x527c46f4),LL(0x5633cdef,0xd799e77b),LL(0x7d9e4297,0x24eacc16),LL(0x6b1cb734,0xabb61cea), LL(0xf778443c,0xbee2e8a7),LL(0x29de2fe6,0x3bb42bf1),LL(0x3003bb6f,0xcbed86a1),LL(0xd781cdf6,0xd3918e6c), + LL(0x9a5103f1,0x4bee3271),LL(0xf50eac06,0x5243efc6),LL(0x6adcc119,0xb8e122cb),LL(0xc0b80a08,0x1b7faa84), LL(0x6dfcd08c,0x32c3d1bd),LL(0x0be427de,0x129dec4e),LL(0x1d263c83,0x98ab679c),LL(0xcef64eff,0xafc83cb7), + LL(0x2fa6be76,0x85eb6088),LL(0x1328cbfe,0x892585fb),LL(0xcf618dda,0xc154d3ed),LL(0x3abaf26e,0xc44f601b), LL(0x2be1fdfd,0x7bf57d0b),LL(0x21137fee,0xa833bd2d),LL(0x2db591a8,0x9353af36),LL(0x5562a056,0xc76f26dc), + LL(0x3fdf5a51,0x1d87e47d),LL(0x55c9cab0,0x7afb5f93),LL(0x89e0586e,0x91bbf58f),LL(0x0d843709,0x7c72c018), LL(0x99b5c3dc,0xa9a5aafb),LL(0x3844aeb0,0xa48a0f1d),LL(0xb667e482,0x7178b7dd),LL(0x6e23a59a,0x453985e9), + LL(0x01b25dd8,0x4a54c860),LL(0xfb897c8a,0x0dd37f48),LL(0x0ea90cd9,0x5f8aa610),LL(0x16d5830d,0xc8892c68), LL(0xef514ca5,0xeb4befc0),LL(0xe72c9ee6,0x478eb679),LL(0xdbc40d5f,0x9bca20da),LL(0xdde4f64a,0xf015de21), + LL(0xeaf4b8a5,0xaa6a4de0),LL(0x4bc60e32,0x68cfd9ca),LL(0x7fd15e70,0x668a4b01),LL(0xf27dc09d,0xd9f0694a), LL(0xba708bcd,0xf6c3cad5),LL(0x5bb95c2a,0x5cd2ba69),LL(0x33c0a58f,0xaa28c1d3),LL(0xabc77870,0x23e274e3), + LL(0xdfd20a4a,0x44c3692d),LL(0x81a66653,0x091c5fd3),LL(0x09a0757d,0x6c0bb691),LL(0x667343ea,0x9072e8b9), LL(0x80848bec,0x31d40eb0),LL(0x79fd36cc,0x95bd480a),LL(0x65ed43f5,0x01a77c61),LL(0x2e0d40bf,0xafccd127), + LL(0x1cc1884b,0xeccfc82d),LL(0x5d4753b4,0xc85ac201),LL(0x658e099f,0xc7a6caac),LL(0x04b27390,0xcf46369e), LL(0x506467ea,0xe2e7d049),LL(0x37cdeccc,0x481b63a2),LL(0xed80143a,0x4029abd8),LL(0xbcb00b88,0x28bfe3c7), + LL(0x0643d84a,0x3bec1009),LL(0xabd11041,0x885f3668),LL(0xf83a34d6,0xdb02432c),LL(0x719ceebe,0x32f7b360), LL(0xdad1fe7a,0xf06c7837),LL(0x5441a0b0,0x60a157a9),LL(0xe2d47550,0x704970e9),LL(0x271b9020,0xcd2bd553), + LL(0x33e24a0b,0xff57f82f),LL(0xf2565079,0x9cbee23f),LL(0xeb5f5825,0x16353427),LL(0xe948d662,0x276feec4), LL(0xda10032b,0xd1b62bc6),LL(0xf0e72a53,0x718351dd),LL(0x2420e7ba,0x93452076),LL(0x3a00118d,0x96368fff), + LL(0x150a49e4,0x00ce2d26),LL(0x3f04706b,0x0c28b636),LL(0x58b196d0,0xbad65a46),LL(0xec9f8b7c,0x6c8455fc), LL(0x2d71867e,0xe90c895f),LL(0xedf9f38c,0x5c0be31b),LL(0xd8f6ec04,0x2a37a15e),LL(0x8cd85251,0x239639e7), + LL(0x9c7c4c6b,0xd8975315),LL(0xd7409af7,0x603aa3c0),LL(0x007132fb,0xb8d53d0c),LL(0xa6849238,0x68d12af7), LL(0xbf5d9279,0xbe0607e7),LL(0xaada74ce,0x9aa50055),LL(0xba7e8ccb,0xe81079cb),LL(0xa5f4ff5e,0x610c71d1), + LL(0x5aa07093,0x9e2ee1a7),LL(0xa75da47c,0xca84004b),LL(0x3de75401,0x074d3951),LL(0xbb311592,0xf938f756), LL(0x00a43421,0x96197618),LL(0x07bc78c8,0x39a25362),LL(0x0a171276,0x278f710a),LL(0x8d1a8f08,0xb28446ea), + LL(0xe3b6a661,0x184781bf),LL(0xe6d279f7,0x7751cb1d),LL(0xc59eb662,0xf8ff95d6),LL(0x58d3dea7,0x186d90b7), LL(0xdfb4f754,0x0e4bb6c1),LL(0x2b2801dc,0x5c5cf56b),LL(0x1f54564d,0xc561e452),LL(0xf0dd7f13,0xb4fb8c60), + LL(0x33ff98c7,0xf8849630),LL(0xcf17769c,0x9619fffa),LL(0x1bfdd80a,0xf8090bf6),LL(0x422cfe63,0x14d9a149), LL(0x6f6df9ea,0xb354c360),LL(0x218f17ea,0xdbcf770d),LL(0x79eb3480,0x207db7c8),LL(0x559b6a26,0x213dbda8), + LL(0x29fc81b3,0xac4c200b),LL(0x171d87c1,0xebc3e09f),LL(0x1481aa9e,0x91799530),LL(0x92e114fa,0x051b92e1), LL(0xecb5537f,0xdf8f92e9),LL(0x290c7483,0x44b1b2cc),LL(0x2adeb016,0xa711455a),LL(0x81a10c2c,0x964b6856), + LL(0xcec03623,0x4f159d99),LL(0xef3271ea,0x05532225),LL(0xc5ee4849,0xb231bea3),LL(0x7094f103,0x57a54f50), LL(0x9598b352,0x3e2d421d),LL(0x67412ab4,0xe865a49c),LL(0x1cc3a912,0xd2998a25),LL(0x0c74d65d,0x5d092808), + LL(0x4088567a,0x73f45908),LL(0x1f214a61,0xeb6b280e),LL(0xcaf0c13d,0x8c9adc34),LL(0xf561fb80,0x39d12938), LL(0xbc6edfb4,0xb2dc3a5e),LL(0xfe4d210e,0x7485b1b1),LL(0xe186ae72,0x062e0400),LL(0x6eeb3b88,0x91e32d5c), + LL(0x4be59224,0x6df574d7),LL(0x716d55f3,0xebc88ccc),LL(0xcad6ed33,0x26c2e6d0),LL(0x0d3e8b10,0xc6e21e7d), LL(0x5bcc36bb,0x2cc5840e),LL(0x7da74f69,0x9292445e),LL(0x4e5193a8,0x8be8d321),LL(0x8df06413,0x3ec23629), + LL(0xb134defa,0xc7e9ae85),LL(0x1bb2d475,0x6073b1d0),LL(0x2863c00d,0xb9ad615e),LL(0x525f4ac4,0x9e29493d), LL(0x4e9acf4f,0xc32b1dea),LL(0xa50db88d,0x3e1f01c8),LL(0x04da916c,0xb05d70ea),LL(0xd865803e,0x714b0d0a), + LL(0x9920cb5e,0x4bd493fc),LL(0x92c7a3ac,0x5b44b1f7),LL(0xbcec9235,0xa2a77293),LL(0xcd378553,0x5ee06e87), LL(0xda621607,0xceff8173),LL(0x99f5d290,0x2bb03e4c),LL(0xa6f734ac,0x2945106a),LL(0xd25c4732,0xb5056604), + LL(0xe079afee,0x5945920c),LL(0x6789831f,0x686e17a0),LL(0xb74a5ae5,0x5966bee8),LL(0x1e258d46,0x38a673a2), LL(0x83141c95,0xbd1cc1f2),LL(0x0e96e486,0x3b2ecf4f),LL(0x74e5fc78,0xcd3aa896),LL(0x2482fa7a,0x415ec10c), + LL(0x80503380,0x15234419),LL(0xd314b392,0x513d917a),LL(0x63caecae,0xb0b52f4e),LL(0x2dc7780b,0x07bf22ad), LL(0xe4306839,0xe761e8a1),LL(0x5dd7feaa,0x1b3be962),LL(0x74c778f1,0x4fe728de),LL(0x5e0070f6,0xf1fa0bda), + LL(0x6ec3f510,0x85205a31),LL(0xd2980475,0x2c7e4a14),LL(0x6f30ebfd,0xde3c19c0),LL(0xd4b7e644,0xdb1c1f38), LL(0x5dce364a,0xfe291a75),LL(0x058f5be3,0xb7b22a3c),LL(0x37fea38c,0x2cd2c302),LL(0x2e17be17,0x2930967a), + LL(0x0c061c65,0x87f009de),LL(0xedc6ed44,0xcb014aac),LL(0x3bafb1eb,0x49bd1cb4),LL(0x282d3688,0x81bd8b5c), LL(0xf01a17af,0x1cdab87e),LL(0xe710063b,0x21f37ac4),LL(0x42fc8193,0x5a6c5676),LL(0x56a6015c,0xf4753e70), + LL(0xa15b0a44,0x020f795e),LL(0x8958a958,0x8f37c8d7),LL(0xa4b675b5,0x63b7e89b),LL(0x0fc31aea,0xb4fb0c0c), LL(0xa7ff1f2e,0xed95e639),LL(0x619614fb,0x9880f5a3),LL(0x947151ab,0xdeb6ff02),LL(0xa868dcdb,0x5bc5118c), + LL(0x4c20cea5,0xd8da2055),LL(0x14c4d69a,0xcac2776e),LL(0x622d599b,0xcccb22c1),LL(0x68a9bb50,0xa4ddb653), LL(0x1b4941b4,0x2c4ff151),LL(0x6efba588,0xe1ff19b4),LL(0xc48345e0,0x35034363),LL(0x1e29dfc4,0x45542e3d), + LL(0x349f7aed,0xf197cb91),LL(0x8fca8420,0x3b2b5a00),LL(0x23aaf6d8,0x7c175ee8),LL(0x35af32b6,0x54dcf421), LL(0x27d6561e,0x0ba14307),LL(0xd175b1e2,0x879d5ee4),LL(0x99807db5,0xc7c43673),LL(0x9cd55bcd,0x77a54455), + LL(0x0105c072,0xe6c2ff13),LL(0x8dda7da4,0x18f7a99f),LL(0x0e2d35c1,0x4c301820),LL(0xd9cc6c82,0x06a53ca0), LL(0xf1aa1d9e,0xaa21cc1e),LL(0x4a75b1e8,0x32414334),LL(0x0ebe9fdc,0x2a6d1328),LL(0x98a4755a,0x16bd173f), + LL(0x2133ffd9,0xfbb9b245),LL(0x830f1a20,0x39a8b2f1),LL(0xd5a1f52a,0x484bc97d),LL(0xa40eddf8,0xd6aebf56), LL(0x76ccdac6,0x32257acb),LL(0x1586ff27,0xaf4d36ec),LL(0xf8de7dd1,0x8eaa8863),LL(0x88647c16,0x0045d5cf), +}, +/* digit=6 base_pwr=2^42 */ +{ + LL(0xc005979d,0xa6f3d574),LL(0x6a40e350,0xc2072b42),LL(0x8de2ecf9,0xfca5c156),LL(0xa515344e,0xa8c8bf5b), LL(0x114df14a,0x97aee555),LL(0xfdc5ec6b,0xd4374a4d),LL(0x2ca85418,0x754cc28f),LL(0xd3c41f78,0x71cb9e27), + LL(0x03605c39,0x89105079),LL(0xa142c96c,0xf0843d9e),LL(0x16923684,0xf3744934),LL(0xfa0a2893,0x732caa2f), LL(0x61160170,0xb2e8c270),LL(0x437fbaa3,0xc32788cc),LL(0xa6eda3ac,0x39cd818e),LL(0x9e2b2e07,0xe2e94239), + LL(0x0260e52a,0x6967d39b),LL(0x90653325,0xd42585cc),LL(0x21ca7954,0x0d9bd605),LL(0x81ed57b3,0x4fa20877), LL(0xe34a0bbe,0x60c1eff8),LL(0x84f6ef64,0x56b0040c),LL(0xb1af8483,0x28be2b24),LL(0xf5531614,0xb2278163), + LL(0x5922ac1c,0x8df27545),LL(0xa52b3f63,0xa7b3ef5c),LL(0x71de57c4,0x8e77b214),LL(0x834c008b,0x31682c10), LL(0x4bd55d31,0xc76824f0),LL(0x17b61c71,0xb6d1c086),LL(0xc2a5089d,0x31db0903),LL(0x184e5d3f,0x9c092172), + LL(0xc00cc638,0xdd7ced5b),LL(0x61278fc2,0x1a2015eb),LL(0x6a37f8d6,0x2e8e5288),LL(0xe79933ad,0xc457786f), LL(0x2c51211a,0xb3fe4cce),LL(0x24c20498,0xad9b10b2),LL(0xd28db5e5,0x90d87a4f),LL(0x3aca2fc3,0x698cd105), + LL(0xe91b536d,0x4f112d07),LL(0x9eba09d6,0xceb982f2),LL(0x197c396f,0x3c157b2c),LL(0x7b66eb24,0xe23c2d41), LL(0x3f330d37,0x480c57d9),LL(0x79108deb,0xb3a4c8a1),LL(0xcb199ce5,0x702388de),LL(0xb944a8d4,0x0b019211), + LL(0x840bb336,0x24f2a692),LL(0xa669fa7b,0x7c353bdc),LL(0xdec9c300,0xda20d6fc),LL(0xa13a4f17,0x625fbe2f), LL(0xdbc17328,0xa2b1b61a),LL(0xa9515621,0x008965bf),LL(0xc620ff46,0x49690939),LL(0x8717e91c,0x182dd27d), + LL(0xea6c3997,0x5ace5035),LL(0xc2610bef,0x54259aaa),LL(0x3c80dd39,0xef18bb3f),LL(0x5fc3fa39,0x6910b95b), LL(0x43e09aee,0xfce2f510),LL(0xa7675665,0xced56c9f),LL(0xd872db61,0x10e265ac),LL(0xae9fce69,0x6982812e), + LL(0xce800998,0x29be11c6),LL(0xb90360d9,0x72bb1752),LL(0x5a4ad590,0x2c193197),LL(0x9fc1dbc0,0x2ba2f548), LL(0xe490ebe0,0x7fe4eebb),LL(0x7fae11c0,0x12a0a4cd),LL(0xe903ba37,0x7197cf81),LL(0xde1c6dd8,0xcf7d4aa8), + LL(0x3fd5684c,0x92af6bf4),LL(0x80360aa1,0x2b26eecf),LL(0x00546a82,0xbd960f30),LL(0xf59ad8fe,0x407b3c43), LL(0x249c82ba,0x86cae5fe),LL(0x2463744c,0x9e0faec7),LL(0x94916272,0x87f551e8),LL(0x6ceb0615,0x033f9344), + LL(0x8be82e84,0x1e5eb0d1),LL(0x7a582fef,0x89967f0e),LL(0xa6e921fa,0xbcf687d5),LL(0xd37a09ba,0xdfee4cf3), LL(0xb493c465,0x94f06965),LL(0x7635c030,0x638b9a1c),LL(0x66f05e9f,0x76667864),LL(0xc04da725,0xccaf6808), + LL(0x768fccfc,0xca2eb690),LL(0xb835b362,0xf402d37d),LL(0xe2fdfcce,0x0efac0d0),LL(0xb638d990,0xefc9cdef), LL(0xd1669a8b,0x2af12b72),LL(0x5774ccbd,0x33c536bc),LL(0xfb34870e,0x30b21909),LL(0x7df25aca,0xc38fa2f7), + LL(0xbf81f3f5,0x74c5f02b),LL(0xaf7e4581,0x0525a5ae),LL(0x433c54ae,0x88d2aaba),LL(0x806a56c5,0xed9775db), LL(0xc0edb37d,0xd320738a),LL(0x66cc1f51,0x25fdb6ee),LL(0x10600d76,0xac661d17),LL(0xbdd1ed76,0x931ec1f3), + LL(0x19ee43f1,0x65c11d62),LL(0x60829d97,0x5cd57c3e),LL(0x984be6e8,0xd26c91a3),LL(0x8b0c53bd,0xf08d9309), LL(0xc016e4ea,0x94bc9e5b),LL(0x11d43d2b,0xd3916839),LL(0x73701155,0x886c5ad7),LL(0x20b00715,0xe0377626), + LL(0xaa80ba59,0x7f01c9ec),LL(0x68538e51,0x3083411a),LL(0xe88128af,0x970370f1),LL(0x91dec14b,0x625cc3db), LL(0x01ac3107,0xfef9666c),LL(0xd5057ac3,0xb2a8d577),LL(0x92be5df7,0xb0f26299),LL(0x00353924,0xf579c8e5), + LL(0x1341ed7a,0xb8fa3d93),LL(0xa7b59d49,0x4223272c),LL(0x83b8c4a4,0x3dcb1947),LL(0xed1302e4,0x4e413c01), LL(0xe17e44ce,0x6d999127),LL(0x33b3adfb,0xee86bf75),LL(0x25aa96ca,0xf6902fe6),LL(0xe5aae47d,0xb73540e4), + LL(0x1b4a158c,0x32801d7b),LL(0x27e2a369,0xe571c99e),LL(0x10d9f197,0x40cb76c0),LL(0x3167c0ae,0xc308c289), LL(0xeb7958f2,0xa6ef9dd3),LL(0x300879b1,0xa7226dfc),LL(0x7edf0636,0x6cd0b362),LL(0x7bc37eed,0x4efbce6c), + LL(0x8d699021,0x75f92a05),LL(0x772566e3,0x586d4c79),LL(0x761ad23a,0x378ca5f1),LL(0x1465a8ac,0x650d86fc), LL(0x842ba251,0x7a4ed457),LL(0x42234933,0x6b65e3e6),LL(0x31aad657,0xaf1543b7),LL(0xcbfec369,0xa4cefe98), + LL(0x9f47befb,0xb587da90),LL(0x41312d13,0x6562e9fb),LL(0xeff1cefe,0xa691ea59),LL(0x05fc4cf6,0xcc30477a), LL(0x0b0ffd3d,0xa1632461),LL(0x5b355956,0xa1f16f3b),LL(0x4224ec24,0x5b148d53),LL(0xf977012a,0xdc834e7b), + LL(0xb2c69dbc,0x7bfc5e75),LL(0x03c3da6c,0x3aa77a29),LL(0xca910271,0xde0df03c),LL(0x7806dc55,0xcbd5ca4a), LL(0x6db476cb,0xe1ca5807),LL(0x5f37a31e,0xfde15d62),LL(0xf41af416,0xf49af520),LL(0x7d342db5,0x96c5c5b1), + LL(0xeb4ceb9b,0x155c43b7),LL(0x4e77371a,0x2e993010),LL(0x675d43af,0x1d2987da),LL(0x8599fd72,0xef2bc1c0), LL(0x9342f6b2,0x96894b7b),LL(0x7c8e71f0,0x201eadf2),LL(0x4a1f3efc,0xf3479d9f),LL(0x702a9704,0xe0f8a742), + LL(0xb3eba40c,0xeafd44b6),LL(0xc1c1e0d0,0xf9739f29),LL(0x619d505e,0x0091471a),LL(0x9d7c263e,0xc15f9c96), LL(0x83afbe33,0x5be47285),LL(0x04f1e092,0xa3b6d6af),LL(0x751a9d11,0xe76526b9),LL(0x9a4ae4d2,0x2ec5b26d), + LL(0x02f6fb8d,0xeb66f4d9),LL(0x96912164,0x4063c561),LL(0x80ef3000,0xeb7050c1),LL(0xeaa5b3f0,0x288d1c33), LL(0x07806fd8,0xe87c68d6),LL(0x4bbbf50f,0xb2f7f9d5),LL(0xac8d6627,0x25972f3a),LL(0x10e8c13b,0xf8547774), + LL(0x872b4a60,0xcc50ef6c),LL(0x4613521b,0xab2a34a4),LL(0x983e15d1,0x39c5c190),LL(0x59905512,0x61dde5df), LL(0x9f2275f3,0xe417f621),LL(0x451d894b,0x0750c8b6),LL(0x78b0bdaa,0x75b04ab9),LL(0x458589bd,0x3bfd9fd4), + LL(0xee9120b6,0xf1013e30),LL(0x23a4743e,0x2b51af93),LL(0x48d14d9e,0xea96ffae),LL(0x698a1d32,0x71dc0dbe), LL(0x0180cca4,0x914962d2),LL(0xc3568963,0x1ae60677),LL(0x437bc444,0x8cf227b1),LL(0xc9962c7a,0xc650c83b), + LL(0xfe7ccfc4,0x23c2c7dd),LL(0x1b929d48,0xf925c89d),LL(0x06783c33,0x4460f74b),LL(0xa590475a,0xac2c8d49), LL(0xb807bba0,0xfb40b407),LL(0x69ff8f3a,0x9d1e362d),LL(0xcbef64a4,0xa33e9681),LL(0x332fb4b2,0x67ece5fa), + LL(0x739f10e3,0x6900a99b),LL(0xff525925,0xc3341ca9),LL(0xa9e2d041,0xee18a626),LL(0x29580ddd,0xa5a83685), LL(0x9d7de3cd,0xf3470c81),LL(0x2062cf9c,0xedf02586),LL(0xc010edb0,0xf43522fa),LL(0x13a4b1ae,0x30314135), + LL(0xdb22b94b,0xc792e02a),LL(0xa1eaa45b,0x993d8ae9),LL(0xcd1e1c63,0x8aad6cd3),LL(0xc5ce688a,0x89529ca7), LL(0xe572a253,0x2ccee3aa),LL(0x02a21efb,0xe02b6438),LL(0xc9430358,0xa7091b6e),LL(0x9d7db504,0x06d1b1fa), + LL(0xc4744733,0x58846d32),LL(0x379f9e34,0x40517c71),LL(0x130ef6ca,0x2f65655f),LL(0xf1f3503f,0x526e4488), LL(0x7ee4a976,0x8467bd17),LL(0x921363d1,0x1d9dc913),LL(0xb069e041,0xd8d24c33),LL(0x2cdf7f51,0x5eb5da0a), + LL(0x197b994f,0x1c0f3cb1),LL(0x2843eae9,0x3c95a6c5),LL(0xa6097ea5,0x7766ffc9),LL(0xd723b867,0x7bea4093), LL(0x4db378f9,0xb48e1f73),LL(0xe37b77ac,0x70025b00),LL(0xaf24ad46,0x943dc8e7),LL(0x16d00a85,0xb98a15ac), + LL(0x2743b004,0x3adc38ba),LL(0x334415ee,0xb1c7f4f7),LL(0x1e62d05a,0xea43df8f),LL(0x9d76a3b6,0x32618905), LL(0xa23a0f46,0x2fbd0bb5),LL(0x6a01918c,0x5bc971db),LL(0xb4743f94,0x7801d94a),LL(0x676ae22b,0xb94df65e), + LL(0xaf95894c,0xaafcbfab),LL(0x276b2241,0x7b9bdc07),LL(0x5bdda48b,0xeaf98362),LL(0xa3fcb4df,0x5977faf2), LL(0x052c4b5b,0xbed042ef),LL(0x067591f0,0x9fe87f71),LL(0x22f24ec7,0xc89c73ca),LL(0xe64a9f1b,0x7d37fa9e), + LL(0x15562627,0x2710841a),LL(0xc243b034,0x2c01a613),LL(0x2bc68609,0x1d135c56),LL(0x8b03f1f6,0xc2ca1715), LL(0x3eb81d82,0xc9966c2d),LL(0x8f6df13e,0xc02abf4a),LL(0x8f72b43b,0x77b34bd7),LL(0x360c82b0,0xaff6218f), + LL(0x8d55b9d2,0x0aa5726c),LL(0x99e9bffb,0xdc0adbe9),LL(0xefb9e72a,0x9097549c),LL(0x9dfb3111,0x16755712), LL(0xf26847f9,0xdd8bf984),LL(0xdfb30cb7,0xbcb8e387),LL(0x5171ef9c,0xc1fd32a7),LL(0x389b363f,0x977f3fc7), + LL(0xf4babda0,0x116eaf2b),LL(0xf7113c8e,0xfeab68bd),LL(0xb7def526,0xd1e3f064),LL(0xe0b3fa02,0x1ac30885), LL(0x40142d9d,0x1c5a6e7b),LL(0x30921c0b,0x839b5603),LL(0x36a116a3,0x48f301fa),LL(0xcfd9ee6d,0x380e1107), + LL(0x58854be1,0x7945ead8),LL(0xcbd4d49d,0x4111c12e),LL(0x3a29c2ef,0xece3b1ec),LL(0x8d3616f5,0x6356d404), LL(0x594d320e,0x9f0d6a8f),LL(0xf651ccd2,0x0989316d),LL(0x0f8fdde4,0x6c32117a),LL(0xa26a9bbc,0x9abe5cc5), + LL(0x9723f671,0xcff560fb),LL(0x7f3d593c,0x21b2a12d),LL(0x24ba0696,0xe4cb18da),LL(0xc3543384,0x186e2220), LL(0x88312c29,0x722f64e0),LL(0x17dc7752,0x94282a99),LL(0x5a85ee89,0x62467bbf),LL(0xf10076a0,0xf435c650), + LL(0x43b3a50b,0xc9ff1539),LL(0x1a53efbc,0x7132130c),LL(0xf7b0c5b7,0x31bfe063),LL(0x4ea994cc,0xb0179a7d), LL(0xc85f455b,0x12d064b3),LL(0x8f6e0062,0x47259328),LL(0xb875d6d9,0xf64e590b),LL(0xad92bcc7,0x22dd6225), + LL(0xb9c3bd6d,0xb658038e),LL(0xfbba27c8,0x00cdb0d6),LL(0x1062c45d,0x0c681337),LL(0x2d33407d,0xd8515b8c), LL(0x8cbb5ecf,0xcb8f699e),LL(0xc608d7d8,0x8c4347f8),LL(0xbb3e00db,0x2c11850a),LL(0xecb49d19,0x20a8dafd), + LL(0x45ee2f40,0xbd781480),LL(0x416b60cf,0x75e354af),LL(0x8d49a8c4,0xde0b58a1),LL(0xfa359536,0xe40e94e2), LL(0x62accd76,0xbd4fa59f),LL(0x8c762837,0x05cf466a),LL(0x448c277b,0xb5abda99),LL(0x48b13740,0x5a9e01bf), + LL(0x326aad8d,0x9d457798),LL(0xc396f7e7,0xbdef4954),LL(0xc253e292,0x6fb274a2),LL(0x1cfe53e7,0x2800bf0a), LL(0x44438fd4,0x22426d31),LL(0x5e259f9a,0xef233923),LL(0x03f66264,0x4188503c),LL(0x7f9fdfab,0x9e5e7f13), + LL(0x5fcc1aba,0x565eb76c),LL(0x59b5bff8,0xea632548),LL(0xaab6d3fa,0x5587c087),LL(0x6ce39c1b,0x92b639ea), LL(0x953b135c,0x0706e782),LL(0x425268ef,0x7308912e),LL(0x090e7469,0x599e92c7),LL(0x9bc35e75,0x83b90f52), + LL(0x244975b3,0x4750b3d0),LL(0x11965d72,0xf3a44358),LL(0x9c8dc751,0x179c6774),LL(0xd23d9ff0,0xff18cdfe), LL(0x2028e247,0xc4013833),LL(0xf3bfbc79,0x96e280e2),LL(0xd0880a84,0xf60417bd),LL(0x2a568151,0x263c9f3d), + LL(0x2d2ce811,0x36be15b3),LL(0xf8291d21,0x846dc0c2),LL(0x789fcfdb,0x5cfa0ecb),LL(0xd7535b9a,0x45a0beed), LL(0x96d69af1,0xec8e9f07),LL(0x599ab6dc,0x31a7c5b8),LL(0xf9e2e09f,0xd36d45ef),LL(0xdcee954b,0x3cf49ef1), + LL(0x086cff9b,0x6be34cf3),LL(0x39a3360f,0x88dbd491),LL(0x0dbfbd1d,0x1e96b8cc),LL(0xcb7e2552,0xc1e5f7bf), LL(0x28819d98,0x0547b214),LL(0x7aea9dcb,0xc770dd9c),LL(0x041d68c8,0xaef0d4c7),LL(0x13cb9ba8,0xcc2b9818), + LL(0xfe86c607,0x7fc7bc76),LL(0x502a9a95,0x6b7b9337),LL(0xd14dab63,0x1948dc27),LL(0xdae047be,0x249dd198), LL(0xa981a202,0xe8356584),LL(0x3a893387,0x3531dd18),LL(0xc85c7209,0x1be11f90),LL(0xe2a52b5a,0x93d2fe1e), + LL(0xec6d6b97,0x8225bfe2),LL(0xbd0aa5de,0x9cf6d6f4),LL(0x54779f5f,0x911459cb),LL(0x86aeb1f3,0x5649cddb), LL(0x3f26ce5a,0x32133579),LL(0x550f431e,0xc289a102),LL(0x73b84c6f,0x559dcfda),LL(0xee3ac4d7,0x84973819), + LL(0xf2606a82,0xb51e55e6),LL(0x90f2fb57,0xe25f7061),LL(0xb1a4e37c,0xacef6c2a),LL(0x5dcf2706,0x864e359d), LL(0x7ce57316,0x479e6b18),LL(0x3a96b23d,0x2cab2500),LL(0x8ef16df7,0xed489862),LL(0xef3758b5,0x2056538c), + LL(0xf15d3101,0xa7df865e),LL(0x61b553d7,0x80c5533a),LL(0x4ed14294,0x366e1997),LL(0xb3c0bcd6,0x6620741f), LL(0xedc45418,0x21d1d9c4),LL(0xc1cc4a9d,0x005b859e),LL(0xa1c462f0,0xdf01f630),LL(0xf26820c7,0x15d06cf3), + LL(0x3484be47,0x9f7f24ee),LL(0x4a0c902f,0x2ff33e96),LL(0x5a0bc453,0x00bdf457),LL(0x1aa238db,0x2378dfaf), LL(0x856720f2,0x272420ec),LL(0x96797291,0x2ad9d95b),LL(0x768a1558,0xd1242cc6),LL(0x5cc86aa8,0x2e287f8b), + LL(0x990cecaa,0x796873d0),LL(0x675d4080,0xade55f81),LL(0x21f0cd84,0x2645eea3),LL(0xb4e17d02,0x7a1efa0f), LL(0x037cc061,0xf6858420),LL(0xd5d43e12,0x682e05f0),LL(0x27218710,0x59c36994),LL(0x3f7cd2fc,0x85cbba4d), + LL(0x7a3cd22a,0x726f9729),LL(0x4a628397,0x9f8cd5dc),LL(0xc23165ed,0x17b93ab9),LL(0x122823d4,0xff5f5dbf), LL(0x654a446d,0xc1e4e4b5),LL(0x677257ba,0xd1a9496f),LL(0xde766a56,0x6387ba94),LL(0x521ec74a,0x23608bc8), + LL(0x6688c4d4,0x16a522d7),LL(0x07373abd,0x9d6b4282),LL(0xb42efaa3,0xa62f07ac),LL(0xe3b90180,0xf73e00f7), LL(0x49421c3e,0x36175fec),LL(0x3dcf2678,0xc4e44f9b),LL(0x7220f09f,0x76df436b),LL(0x3aa8b6cf,0x172755fb), + LL(0x446139cc,0xbab89d57),LL(0x5fe0208f,0x0a0a6e02),LL(0x11e5d399,0xcdbb63e2),LL(0xa8977f0b,0x33ecaa12), LL(0xf7c42664,0x59598b21),LL(0xab65d08a,0xb3e91b32),LL(0xf4502526,0x035822ee),LL(0x720a82a9,0x1dcf0176), + LL(0x3d589e02,0x50f8598f),LL(0xb1d63d2c,0xdf0478ff),LL(0x1571cd07,0x8b8068bd),LL(0xd79670cd,0x30c3aa4f), LL(0x941ade7f,0x25e8fd4b),LL(0x32790011,0x3d1debdc),LL(0x3a3f9ff0,0x65b6dcbd),LL(0x793de69c,0x282736a4), + LL(0xd41d3bd3,0xef69a0c3),LL(0x07a26bde,0xb533b8c9),LL(0xdb2edf9f,0xe2801d97),LL(0xe1877af0,0xdc4a8269), LL(0x3d590dbe,0x6c1c5851),LL(0xee4e9357,0x84632f6b),LL(0x79b33374,0xd36d36b7),LL(0x9bbca2e6,0xb46833e3), + LL(0xf7fc0586,0x37893913),LL(0x66bf4719,0x385315f7),LL(0xb31855dc,0x72c56293),LL(0x849061fe,0xd1416d4e), LL(0x51047213,0xbeb3ab78),LL(0xf040c996,0x447f6e61),LL(0x638b1d0c,0xd06d310d),LL(0xbad1522e,0xe28a413f), + LL(0x82003f86,0x685a76cb),LL(0x0bcdbca3,0x610d07f7),LL(0x9ca4c455,0x6ff66021),LL(0xcea10eec,0x7df39b87), LL(0xe22db218,0xb9255f96),LL(0x08a34c44,0x8cc6d9eb),LL(0x859f9276,0xcd4ffb86),LL(0x50d07335,0x8fa15eb2), + LL(0xcf2c24b5,0xdf553845),LL(0x52f9c3ba,0x89f66a9f),LL(0xe4a7ceb3,0x8f22b5b9),LL(0x0e134686,0xaffef809), LL(0x8eb8fac2,0x3e53e1c6),LL(0x28aec98e,0x93c1e4eb),LL(0x32a43bcb,0xb6b91ec5),LL(0xb2d74a51,0x2dbfa947), + LL(0xca84bad7,0xe065d190),LL(0xad58e65c,0xfb13919f),LL(0xf1cb6e31,0x3c41718b),LL(0x06d05c3f,0x688969f0), LL(0x21264d45,0xd4f94ce7),LL(0x7367532b,0xfdfb65e9),LL(0x0945a39d,0x5b1be8b1),LL(0x2b8baf3b,0x229f789c), + LL(0x6f49f15d,0xd8f41f3e),LL(0x907f0792,0x678ce828),LL(0xfca6e867,0xc69ace82),LL(0xd01dcc89,0x106451ae), LL(0x19fc32d2,0x1bb4f7f0),LL(0xb00c52d2,0x64633dfc),LL(0xad9ea445,0x8f13549a),LL(0xfb323705,0x99a3bf50), + LL(0x534d4dbc,0x0c9625a2),LL(0xc2a2fea3,0x45b8f1d1),LL(0xa530fc1a,0x76ec21a1),LL(0x9e5bd734,0x4bac9c2a), LL(0x7b4e3587,0x5996d76a),LL(0x1182d9e3,0x0045cdee),LL(0x1207f13d,0x1aee24b9),LL(0x97345a41,0x66452e97), + LL(0x9f950cd0,0x16e5b054),LL(0xd7fdd075,0x9cc72fb1),LL(0x66249663,0x6edd61e7),LL(0xf043cccb,0xde4caa4d), LL(0x55c7ac17,0x11b1f57a),LL(0x1a85e24d,0x779cbd44),LL(0xe46081e7,0x78030f86),LL(0x8e20f643,0xfd4a6032), + LL(0x0a750c0f,0xcc7a6488),LL(0x4e548e83,0x39bacfe3),LL(0x0c110f05,0x3d418c76),LL(0xb1f11588,0x3e4daa4c), LL(0x5ffc69ff,0x2733e7b5),LL(0x92053127,0x46f147bc),LL(0xd722df94,0x885b2434),LL(0xe6fc6b7c,0x6a444f65), +}, +/* digit=7 base_pwr=2^49 */ +{ + LL(0xc3f16ea8,0x7a1a465a),LL(0xb2f1d11c,0x115a461d),LL(0x6c68a172,0x4767dd95),LL(0xd13a4698,0x3392f2eb), LL(0xe526cdc7,0xc7a99ccd),LL(0x22292b81,0x8e537fdc),LL(0xa6d39198,0x76d8cf69),LL(0x2446852d,0xffc5ff43), + LL(0xa90567e6,0x97b14f7e),LL(0xb6ae5cb7,0x513257b7),LL(0x9f10903d,0x85454a3c),LL(0x69bc3724,0xd8d2c9ad), LL(0x6b29cb44,0x38da9324),LL(0x77c8cbac,0xb540a21d),LL(0x01918e42,0x9bbfe435),LL(0x56c3614e,0xfffa707a), + LL(0xd4e353b7,0x0ce4e3f1),LL(0xef46b0a0,0x062d8a14),LL(0x574b73fd,0x6408d5ab),LL(0xd3273ffd,0xbc41d1c9), LL(0x6be77800,0x3538e1e7),LL(0xc5655031,0x71fe8b37),LL(0x6b9b331a,0x1cd91621),LL(0xbb388f73,0xad825d0b), + LL(0x1cb76219,0x56c2e05b),LL(0x71567e7e,0x0ec0bf91),LL(0x61c4c910,0xe7076f86),LL(0xbabc04d9,0xd67b085b), LL(0x5e93a96a,0x9fb90459),LL(0xfbdc249a,0x7526c1ea),LL(0xecdd0bb7,0x0d44d367),LL(0x9dc0d695,0x95399917), + LL(0x9e240d18,0x61360ee9),LL(0xb4b94466,0x057cdcac),LL(0x2fe5325c,0xe7667cd1),LL(0x21974e3b,0x1fa297b5), LL(0xdb083d76,0xfa4081e7),LL(0xf206bd15,0x31993be6),LL(0x14c19f8c,0x8949269b),LL(0xa9d92357,0x21468d72), + LL(0xa4c506ec,0x2ccbc583),LL(0xd1acfe97,0x957ed188),LL(0x12f1aea2,0x8baed833),LL(0x8325362d,0xef2a6cb4), LL(0x8e195c43,0x130dde42),LL(0x0e6050c6,0xc842025a),LL(0x08686a5d,0x2da972a7),LL(0xe508b4a8,0xb52999a1), + LL(0x10a5a8bd,0xd9f090b9),LL(0x096864da,0xca91d249),LL(0x3f67dbc1,0x8e6a93be),LL(0xf5f4764c,0xacae6fba), LL(0xd21411a0,0x1563c6e0),LL(0xda0a4ad8,0x28fa787f),LL(0x908c8030,0xd524491c),LL(0x4c795f07,0x1257ba0e), + LL(0xceca9754,0x83f49167),LL(0x4b7939a0,0x426d2cf6),LL(0x723fd0bf,0x2555e355),LL(0xc4f144e2,0xa96e6d06), LL(0x87880e61,0x4768a8dd),LL(0xe508e4d5,0x15543815),LL(0xb1b65e15,0x09d7e772),LL(0xac302fa0,0x63439dd6), + LL(0xc14e35c2,0xb93f802f),LL(0x4341333c,0x71735b7c),LL(0x16d4f362,0x03a25104),LL(0xbf433c8e,0x3f4d069b), LL(0xf78f5a7c,0x0d83ae01),LL(0x7c4eed07,0x50a8ffbe),LL(0x76e10f83,0xc74f8906),LL(0x9ddaf8e1,0x7d080966), + LL(0x698e04cc,0xb11df8e1),LL(0x169005c8,0x877be203),LL(0x4f3c6179,0x32749e8c),LL(0x7853fc05,0x2dbc9d0a), LL(0x9454d937,0x187d4f93),LL(0xb4800e1b,0xe682ce9d),LL(0x165e68e8,0xa9129ad8),LL(0xbe7f785b,0x0fe29735), + LL(0x5b9e02b7,0x5303f40c),LL(0x35ee04e8,0xa37c9692),LL(0x34d6632b,0x5f46cc20),LL(0x96ac545b,0x55ef72b2), LL(0x7b91b062,0xabec5c1f),LL(0xbb33e821,0x0a79e1c7),LL(0x3a9f4117,0xbb04b428),LL(0xfd2a475a,0x0de1f28f), + LL(0x3a4434b4,0x31019ccf),LL(0x1a7954dc,0xa3458111),LL(0xe34972a7,0xa9dac80d),LL(0x74f6b8dd,0xb043d054), LL(0x11137b1a,0x021c319e),LL(0xed5cc03f,0x00a754ce),LL(0xcbea5ad4,0x0aa2c794),LL(0x70c015b6,0x093e67f4), + LL(0xc97e3f6b,0x72cdfee9),LL(0xb6da7461,0xc10bcab4),LL(0xb59806b9,0x3b02d2fc),LL(0xa1de6f47,0x85185e89), LL(0x0eb6c4d4,0x39e6931f),LL(0xd4fa5b04,0x4d4440bd),LL(0x34be7eb8,0x5418786e),LL(0x9d7259bc,0x6380e521), + LL(0xd598d710,0x20ac0351),LL(0xcb3a4da4,0x272c4166),LL(0xca71de1f,0xdb82fe1a),LL(0xd8f54b0f,0x746e79f2), LL(0x4b573e9b,0x6e7fc736),LL(0xfd4b5040,0x75d03f46),LL(0x0b98d87b,0x5c1cc36d),LL(0x1f472da1,0x513ba3f1), + LL(0xabb177dd,0x79d0af26),LL(0x7891d564,0xf82ab568),LL(0x72232173,0x2b6768a9),LL(0x8c1f6619,0xefbb3bb0), LL(0xa6d18358,0xb29c11db),LL(0xb0916d3a,0x519e2797),LL(0x9188e290,0xd4dc18f0),LL(0x98b0ca7f,0x648e86e3), + LL(0x983c38b5,0x859d3145),LL(0x637abc8b,0xb14f176c),LL(0xcaff7be6,0x2793fb9d),LL(0x35a66a5a,0xebe5a55f), LL(0x9f87dc59,0x7cec1dcd),LL(0xfbdbf560,0x7c595cd3),LL(0x26eb3257,0x5b543b22),LL(0xc4c935fd,0x69080646), + LL(0x81e9ede3,0x7f2e4403),LL(0xcaf6df0a,0x243c3894),LL(0x1c073b11,0x7c605bb1),LL(0xba6a4a62,0xcd06a541), LL(0x49d4e2e5,0x29168949),LL(0x4af66880,0x33649d07),LL(0xe9a85035,0xbfc0c885),LL(0xfc410f4b,0xb4e52113), + LL(0x78a6513b,0xdca3b706),LL(0x9edb1943,0x92ea4a2a),LL(0xdb6e2dd8,0x02642216),LL(0x9fd57894,0x9b45d0b4), LL(0xc69d11ae,0x114e70db),LL(0x4c57595f,0x1477dd19),LL(0xec77c272,0xbc2208b4),LL(0xdb68f59c,0x95c5b4d7), + LL(0x42e532b7,0xb8c4fc63),LL(0x9ae35290,0x386ba422),LL(0xd201ecbc,0xfb5dda42),LL(0xa0e38fd6,0x2353dc8b), LL(0x68f7e978,0x9a0b85ea),LL(0x2ad6d11f,0x96ec5682),LL(0xe5f6886d,0x5e279d6c),LL(0x3cb1914d,0xd3fe03cd), + LL(0x7ea67c77,0xfe541fa4),LL(0xe3ea810c,0x952bd2af),LL(0x8d01d374,0x791fef56),LL(0x0f11336e,0xa3a1c621), LL(0xc7ec6d79,0x5ad0d5a9),LL(0x3225c342,0xff7038af),LL(0xbc69601b,0x003c6689),LL(0x45e8747d,0x25059bc7), + LL(0xf2086fbf,0xfa4965b2),LL(0x86916078,0xf6840ea6),LL(0x70081d6c,0xd7ac7620),LL(0xb5328645,0xe600da31), LL(0x529b8a80,0x01916f63),LL(0x2d7d6f3e,0xe80e4858),LL(0xd664ca7c,0x29eb0fe8),LL(0xe7b43b0c,0xf017637b), + LL(0x76cb2566,0x9a75c806),LL(0xb24892d9,0x8f76acb1),LL(0x1f08fe45,0x7ae7b9cc),LL(0x6a4907d8,0x19ef7329), LL(0x5f228bf0,0x2db4ab71),LL(0x817032d7,0xf3cdea39),LL(0xdcabe3c0,0x0b1f482e),LL(0xbb86325c,0x3baf76b4), + LL(0x10089465,0xd49065e0),LL(0x8e77c596,0x3bab5d29),LL(0x193dbd95,0x7636c3a6),LL(0xb246e499,0xdef5d294), LL(0x286b2475,0xb22c58b9),LL(0xcd80862b,0xa0b93939),LL(0xf0992388,0x3002c83a),LL(0xeacbe14c,0x6de01f9b), + LL(0xadd70482,0x6aac688e),LL(0x7b4a4e8a,0x708de92a),LL(0x758a6eef,0x75b6dd73),LL(0x725b3c43,0xea4bf352), LL(0x87912868,0x10041f2c),LL(0xef09297a,0xb1b1be95),LL(0xa9f3860a,0x19ae23c5),LL(0x515dcf4b,0xc4f0f839), + LL(0x97f6306a,0x3c7ecca3),LL(0x68a3a4b0,0x744c44ae),LL(0xb3a1d8a2,0x69cd13a0),LL(0x5256b578,0x7cad0a1e), LL(0x33791d9e,0xea653fcd),LL(0x74b2e05f,0x9cc2a05d),LL(0xfd7affa2,0x73b391dc),LL(0xb6b05442,0xddb7091e), + LL(0x8538a5c6,0xc71e27bf),LL(0x89abff17,0x195c63dd),LL(0x1b71e3da,0xfd315285),LL(0xfa680fa0,0x9cbdfda7), LL(0x849d7eab,0x9db876ca),LL(0x3c273271,0xebe2764b),LL(0xf208dcea,0x663357e3),LL(0x565b1b70,0x8c5bd833), + LL(0x9837fc0d,0xccc3b4f5),LL(0xa79cf00f,0x9b641ba8),LL(0xdfdf3990,0x7428243d),LL(0x020786b1,0x83a594c4), LL(0x526c4502,0xb712451a),LL(0x6adb3f93,0x9d39438e),LL(0xe9ff0ccd,0xfdb261e3),LL(0xe07af4c3,0x80344e3c), + LL(0x2fa4f126,0x75900d7c),LL(0x5c99a232,0x08a3b865),LL(0xdb25e0c3,0x2478b6bf),LL(0x71db2edf,0x482cc2c2), LL(0x5f321bb8,0x37df7e64),LL(0x9a8005b4,0x8a93821b),LL(0xcc8c1958,0x3fa2f10c),LL(0x2c269d0a,0x0d332218), + LL(0xe246b0e6,0x20ab8119),LL(0xd349fd17,0xb39781e4),LL(0xb31aa100,0xd293231e),LL(0xbb032168,0x4b779c97), LL(0xc8470500,0x4b3f19e1),LL(0x0c4c869d,0x45b7efe9),LL(0xa1a6bbcc,0xdb84f38a),LL(0xb2fddbc1,0x3b59cb15), + LL(0x3fd165e8,0xba5514df),LL(0x061f8811,0x499fd6a9),LL(0xbfef9f00,0x72cd1fe0),LL(0x79ad7e8a,0x120a4bb9), LL(0x5f4a5ac5,0xf2ffd095),LL(0x95a7a2f0,0xcfd174f1),LL(0x9d17baf1,0xd42301ba),LL(0x77f22089,0xd2fa487a), + LL(0xb1dc77e1,0x9cb09efe),LL(0x21c99682,0xe9566939),LL(0x6c6067bb,0x8c546901),LL(0x61c24456,0xfd378574), LL(0x81796b33,0x2b6a6cbe),LL(0x58e87f8b,0x62d550f6),LL(0x7f1b01b4,0x1b763e1c),LL(0x1b1b5e12,0x4b93cfea), + LL(0x1d531696,0xb9345238),LL(0x88cdde69,0x57201c00),LL(0x9a86afc7,0xdde92251),LL(0xbd35cea8,0xe3043895), LL(0x8555970d,0x7608c1e1),LL(0x2535935e,0x8267dfa9),LL(0x322ea38b,0xd4c60a57),LL(0x804ef8b5,0xe0bf7977), + LL(0xc06fece4,0x1a0dab28),LL(0x94e7b49d,0xd405991e),LL(0x706dab28,0xc542b6d2),LL(0xa91618fb,0xcb228da3), LL(0x107d1cea,0x224e4164),LL(0xd0f5d8f1,0xeb9fdab3),LL(0x0d6e41cd,0xc02ba386),LL(0x9b1f7146,0x676a72c5), + LL(0x4d6cb00b,0xffd6dd98),LL(0xde2e8d7c,0xcef9c5ca),LL(0x641c7936,0xa1bbf5d7),LL(0xee8f772e,0x1b95b230), LL(0xe8ac25b1,0xf765a92e),LL(0x3a18b7c6,0xceb04cfc),LL(0x0acc8966,0x27944cef),LL(0x434c1004,0xcbb3c957), + LL(0xa43ff93c,0x9c9971a1),LL(0xa1e358a9,0x5bc2db17),LL(0xa8d9bc82,0x45b4862e),LL(0x2201e052,0x70ebfbfb), LL(0x92871591,0xafdf64c7),LL(0xb42d0219,0xea5bcae6),LL(0x2ad8f03c,0xde536c55),LL(0xa76aa33c,0xcd6c3f4d), + LL(0x0bca6de3,0xbeb5f623),LL(0xb1e706fd,0xdd20dd99),LL(0xac9059d4,0x90b3ff9d),LL(0x7ccccc4e,0x2d7b2902), LL(0xce98840f,0x8a090a59),LL(0x8410680a,0xa5d947e0),LL(0x923379a5,0x49ae346a),LL(0xb28a3156,0x7dbc84f9), + LL(0x54a1aff2,0xfd40d916),LL(0x3a78fb9b,0xabf318ba),LL(0x3029f95e,0x50152ed8),LL(0xc58ad7fa,0x9fc1dd77), LL(0x13595c17,0x5fa57915),LL(0x8f62b3a9,0xb9504668),LL(0xff3055b0,0x907b5b24),LL(0x9a84f125,0x2e995e35), + LL(0x7e9bbcfb,0x87dacf69),LL(0xe86d96e3,0x95d0c1d6),LL(0x2d95a75c,0x65726e3c),LL(0xacd27f21,0x2c3c9001), LL(0x6c973f57,0x1deab561),LL(0xa5221643,0x108b7e2c),LL(0xc4ef79d4,0x5fee9859),LL(0x40d4b8c6,0xbd62b88a), + LL(0x197c75d6,0xb4dd29c4),LL(0xb7076feb,0x266a6df2),LL(0x4bf2df11,0x9512d0ea),LL(0x6b0cc9ec,0x1320c24f), LL(0x01a59596,0x6bb1e0e1),LL(0xeff9aaac,0x8317c5bb),LL(0x385aa6c9,0x65bb405e),LL(0x8f07988f,0x613439c1), + LL(0x16a66e91,0xd730049f),LL(0xfa1b0e0d,0xe97f2820),LL(0x304c28ea,0x4131e003),LL(0x526bac62,0x820ab732), LL(0x28714423,0xb2ac9ef9),LL(0xadb10cb2,0x54ecfffa),LL(0xf886a4cc,0x8781476e),LL(0xdb2f8d49,0x4b2c87b5), + LL(0x0a44295d,0xe857cd20),LL(0x58c6b044,0x707d7d21),LL(0xf596757c,0xae8521f9),LL(0x67b2b714,0x87448f03), LL(0x5ebcd58d,0x13a9bc45),LL(0x9122d3c1,0x79bcced9),LL(0x9e076642,0x3c644247),LL(0x2df4767d,0x0cf22778), + LL(0x71d444b6,0x5e61aee4),LL(0xc5084a1d,0x211236bf),LL(0x4fd3eaf6,0x7e15bc9a),LL(0xab622bf5,0x68df2c34), LL(0x59bf4f36,0x9e674f0f),LL(0xd7f34d73,0xf883669b),LL(0x31497b1d,0xc48ac1b8),LL(0x5106703b,0x323b925d), + LL(0x74082008,0x22156f42),LL(0xc8482bcb,0xeffc521a),LL(0x12173479,0x5c6831bf),LL(0xc4739490,0xcaa2528f), LL(0x8f1b3c4d,0x84d2102a),LL(0x2d9bec0d,0xcf64dfc1),LL(0x78a546ef,0x433febad),LL(0x7b73cef1,0x1f621ec3), + LL(0x37338615,0x6aecd627),LL(0x01d8edf6,0x162082ab),LL(0x19e86b66,0x833a8119),LL(0xd299b5db,0x6023a251), LL(0xbbf04b89,0xf5bb0c3a),LL(0xae749a44,0x6735eb69),LL(0x4713de3b,0xd0e058c5),LL(0x2c3d4ccd,0xfdf2593e), + LL(0xfdd23667,0x1b8f414e),LL(0xfa2015ee,0xdd52aaca),LL(0xbd9625ff,0x3e31b517),LL(0x8db5918c,0x5ec9322d), LL(0xa96f5294,0xbc73ac85),LL(0x61a0666a,0x82aa5bf3),LL(0xbf08ac42,0x49755810),LL(0x891cedfc,0xd21cdfd5), + LL(0x67f8be10,0x918cb57b),LL(0x56ffa726,0x365d1a7c),LL(0x6532de93,0x2435c504),LL(0x2674cd02,0xc0fc5e10), LL(0x9cbbb142,0x6e51fcf8),LL(0xafc50692,0x1d436e5a),LL(0x3fbcae22,0x766bffff),LL(0xfd55d3b8,0x3148c2fd), + LL(0x233222fa,0x52c7fdc9),LL(0xe419fb6b,0x89ff1092),LL(0x25254977,0x3cd6db99),LL(0x1cf12ca7,0x2e85a161), LL(0xdc810bc9,0xadd2547c),LL(0x9d257c22,0xea3f458f),LL(0x27d6b19b,0x642c1fbe),LL(0x140481a6,0xed07e6b5), + LL(0x86d2e0f8,0x6ada1d42),LL(0x0e8a9fd5,0xe5920122),LL(0x708c1b49,0x02c936af),LL(0x2b4bfaff,0x60f30fee), LL(0x858e6a61,0x6637ad06),LL(0x3fd374d0,0xce4c7767),LL(0x7188defb,0x39d54b2d),LL(0xf56a6b66,0xa8c9d250), + LL(0xb24fe1dc,0x58fc0f5e),LL(0x6b73f24c,0x9eaf9dee),LL(0x33650705,0xa90d588b),LL(0xaf2ec729,0xde5b62c5), LL(0xd3c2b36e,0x5c72cfae),LL(0x034435da,0x868c19d5),LL(0xe17ee145,0x88605f93),LL(0x77a5d5b1,0xaa60c4ee), + LL(0x3b60c472,0xbcf5bfd2),LL(0xeb1d3049,0xaf4ef13c),LL(0xe13895c9,0x373f44fc),LL(0x0cbc9822,0xf29b382f), LL(0x73efaef6,0x1bfcb853),LL(0xa8c96f40,0xcf56ac9c),LL(0x7a191e24,0xd7adf109),LL(0xbf8a8dc2,0x98035f44), + LL(0x1e750c84,0xf40a71b9),LL(0x5dc6c469,0xc57f7b0c),LL(0x6fbc19c1,0x49a0e79c),LL(0xa48ebdb8,0x6b0f5889), LL(0xa07c4e9f,0x5d3fd084),LL(0xab27de14,0xc3830111),LL(0x33e08dcc,0x0e4929fe),LL(0x40bb73a3,0xf4a5ad24), + LL(0x490f97ca,0xde86c2bf),LL(0x67a1ce18,0x288f09c6),LL(0x1844478d,0x364bb886),LL(0xceedb040,0x7840fa42), LL(0x5a631b37,0x1269fdd2),LL(0xa47c8b7d,0x94761f1e),LL(0x481c6266,0xfc0c2e17),LL(0x3daa5fa7,0x85e16ea2), + LL(0x92491048,0xccd86033),LL(0xf4d402d7,0x0c2f6963),LL(0xdf6a865c,0x6336f7df),LL(0xb5c02a87,0x0a2a463c), LL(0xbf2f12ee,0xb0e29be7),LL(0x66bad988,0xf0a22002),LL(0x9123c1d7,0x27f87e03),LL(0x328a8c98,0x21669c55), + LL(0x92f14529,0x186b9803),LL(0x63954df3,0xd3d056cc),LL(0x175a46f6,0x2f03fd58),LL(0x11558558,0x63e34ebe), LL(0x5b80cfa5,0xe13fedee),LL(0xd401dbd1,0xe872a120),LL(0xe8a9d667,0x52657616),LL(0xe08d6693,0xbc8da4b6), + LL(0x1b703e75,0x370fb9bb),LL(0xd4338363,0x6773b186),LL(0xecef7bff,0x18dad378),LL(0x995677da,0xaac787ed), LL(0x0437164b,0x4801ea8b),LL(0x73fe795e,0xf430ad20),LL(0x8ee5eb73,0xb164154d),LL(0x108f7c0e,0x0884ecd8), + LL(0x5f520698,0x0e6ec096),LL(0x44f7b8d9,0x640631fe),LL(0xa35a68b9,0x92fd34fc),LL(0x4d40cf4e,0x9c5a4b66), LL(0x80b6783d,0x949454bf),LL(0x3a320a10,0x80e701fe),LL(0x1a0a39b2,0x8d1a564a),LL(0x320587db,0x1436d53d), + LL(0x6556c362,0xf5096e6d),LL(0xe2455d7e,0xbc23a3c0),LL(0x807230f9,0x3a7aee54),LL(0x22ae82fd,0x9ba1cfa6), LL(0x99c5d706,0x833a057a),LL(0x842315c9,0x8be85f4b),LL(0x66a72f12,0xd083179a),LL(0xcdcc73cd,0x2fc77d5d), + LL(0x5616ee30,0x22b88a80),LL(0xe7ab1083,0xfb09548f),LL(0x511270cd,0x8ad6ab0d),LL(0x6924d9ab,0x61f6c57a), LL(0x90aecb08,0xa0f7bf72),LL(0x0df784a4,0x849f87c9),LL(0xcfaf1d03,0x27c79c15),LL(0xc463face,0xbbf9f675), + LL(0x765ba543,0x91502c65),LL(0x42ea60dd,0x18ce3cac),LL(0x6e43ecb3,0xe5cee6ac),LL(0x68f2aeeb,0x63e4e910), LL(0xc85932ee,0x26234fa3),LL(0x4c90c44d,0x96883e8b),LL(0xa18a50f6,0x29b9e738),LL(0x3f0420df,0xbfc62b2a), + LL(0x6d3e1fa9,0xd22a7d90),LL(0xfe05b8a3,0x17115618),LL(0xbb2b9c01,0x2a0c9926),LL(0xe07e76a2,0xc739fcc6), LL(0x165e439a,0x540e9157),LL(0x6a9063d8,0x06353a62),LL(0x61e927a3,0x84d95594),LL(0xe2e0be7f,0x013b9b26), + LL(0x973497f1,0x4feaec3b),LL(0x093ebc2d,0x15c0f94e),LL(0x33af0583,0x6af5f227),LL(0xc61f3340,0x0c2af206), LL(0x4457397c,0xd25dbdf1),LL(0xcabcbae0,0x2e8ed017),LL(0xc2815306,0xe3010938),LL(0xe8c6cd68,0xbaa99337), + LL(0x3b0ec7de,0x08513182),LL(0x58df05df,0x1e1b822b),LL(0xa5c3b683,0x5c14842f),LL(0x3eba34ce,0x98fe977e), LL(0x0d5e8873,0xfd2316c2),LL(0xbd0d427d,0xe48d839a),LL(0x623fc961,0x495b2218),LL(0xb46fba5e,0x24ee56e7), + LL(0x91e4de58,0x9184a55b),LL(0xdfdea288,0xa7488ca5),LL(0xa8dcc943,0xa723862e),LL(0x849dc0fc,0x92d762b2), LL(0x091ff4a9,0x3c444a12),LL(0x0cada274,0x581113fa),LL(0x30d8eae2,0xb9de0a45),LL(0xdf6b41ea,0x5e0fcd85), + LL(0xc094dbb5,0x6233ea68),LL(0xd968d410,0xb77d062e),LL(0x58b3002d,0x3e719bbc),LL(0x3dc49d58,0x68e7dd3d), LL(0x013a5e58,0x8d825740),LL(0x3c9e3c1b,0x21311747),LL(0x7c99b6ab,0x0cb0a2a7),LL(0xc2f888f2,0x5c48a3b3), +}, +/* digit=8 base_pwr=2^56 */ +{ + LL(0x991724f3,0xc7913e91),LL(0x39cbd686,0x5eda799c),LL(0x63d4fc1e,0xddb595c7),LL(0xac4fed54,0x6b63b80b), LL(0x7e5fb516,0x6ea0fc69),LL(0xd0f1c964,0x737708ba),LL(0x11a92ca5,0x9628745f),LL(0x9a86967a,0x61f37958), + LL(0xaa665072,0x9af39b2c),LL(0xefd324ef,0x78322fa4),LL(0xc327bd31,0x3d153394),LL(0x3129dab0,0x81d5f271), LL(0xf48027f5,0xc72e0c42),LL(0x8536e717,0xaa40cdbc),LL(0x2d369d0f,0xf45a657a),LL(0xea7f74e6,0xb03bbfc4), + LL(0x0d738ded,0x46a8c418),LL(0xe0de5729,0x6f1a5bb0),LL(0x8ba81675,0xf10230b9),LL(0x112b33d4,0x32c6f30c), LL(0xd8fffb62,0x7559129d),LL(0xb459bf05,0x6a281b47),LL(0xfa3b6776,0x77c1bd3a),LL(0x7829973a,0x0709b380), + LL(0xa3326505,0x8c26b232),LL(0xee1d41bf,0x38d69272),LL(0xffe32afa,0x0459453e),LL(0x7cb3ea87,0xce8143ad), LL(0x7e6ab666,0x932ec1fa),LL(0x22286264,0x6cd2d230),LL(0x6736f8ed,0x459a46fe),LL(0x9eca85bb,0x50bf0d00), + LL(0x877a21ec,0x0b825852),LL(0x0f537a94,0x300414a7),LL(0x21a9a6a2,0x3f1cba40),LL(0x76943c00,0x50824eee), LL(0xf83cba5d,0xa0dbfcec),LL(0x93b4f3c0,0xf9538148),LL(0x48f24dd7,0x61744162),LL(0xe4fb09dd,0x5322d64d), + LL(0x3d9325f3,0x57447384),LL(0xf371cb84,0xa9bef2d0),LL(0xa61e36c5,0x77d2188b),LL(0xc602df72,0xbbd6a7d7), LL(0x8f61bc0b,0xba3aa902),LL(0x6ed0b6a1,0xf49085ed),LL(0xae6e8298,0x8bc625d6),LL(0xa2e9c01d,0x832b0b1d), + LL(0xf1f0ced1,0xa337c447),LL(0x9492dd2b,0x800cc793),LL(0xbea08efa,0x4b93151d),LL(0xde0a741e,0x820cf3f8), LL(0x1c0f7d13,0xff1982dc),LL(0x84dde6ca,0xef921960),LL(0x45f96ee3,0x1ad7d972),LL(0x29dea0c7,0x319c8dbe), + LL(0x7b82b99b,0xd3ea3871),LL(0x470eb624,0x75922d4d),LL(0x3b95d466,0x8f66ec54),LL(0xbee1e346,0x66e673cc), LL(0xb5f2b89a,0x6afe67c4),LL(0x290e5cd3,0x3de9c1e6),LL(0x310a2ada,0x8c278bb6),LL(0x0bdb323b,0x420fa384), + LL(0x0eb919b0,0x0ae1d63b),LL(0xa74b9620,0xd74ee51d),LL(0xa674290c,0x395458d0),LL(0x4620a510,0x324c930f), LL(0xfbac27d4,0x2d1f4d19),LL(0x9bedeeac,0x4086e8ca),LL(0x9b679ab8,0x0cdd211b),LL(0x7090fec4,0x5970167d), + LL(0xfaf1fc63,0x3420f2c9),LL(0x328c8bb4,0x616d333a),LL(0x57f1fe4a,0x7d65364c),LL(0x55e5c73a,0x9343e877), LL(0xe970e78c,0x5795176b),LL(0x60533627,0xa36ccebf),LL(0x09cdfc1b,0xfc7c7380),LL(0xb3fec326,0xb39a2afe), + LL(0x6224408a,0xb7ff1ba1),LL(0x247cfc5e,0xcc856e92),LL(0xc18bc493,0x01f102e7),LL(0x2091c727,0x4613ab74), LL(0xc420bf2b,0xaa25e89c),LL(0x90337ec2,0x00a53176),LL(0x7d025fc7,0xd2be9f43),LL(0x6e6fe3dc,0x3316fb85), + LL(0x9ac50814,0x27520af5),LL(0x9a8e4223,0xfdf95e78),LL(0x56bec5a0,0xb7e7df2a),LL(0xdf159e5d,0xf7022f7d), LL(0xcac1fe8f,0x93eeeab1),LL(0x37451168,0x8040188c),LL(0xd967dce6,0x7ee8aa8a),LL(0x3abc9299,0xfa0e79e7), + LL(0x2064cfd1,0x67332cfc),LL(0xb0651934,0x339c31de),LL(0x2a3bcbea,0x719b28d5),LL(0x9d6ae5c6,0xee74c82b), LL(0xbaf28ee6,0x0927d05e),LL(0x9d719028,0x82cecf2c),LL(0xddb30289,0x0b0d353e),LL(0xfddb2e29,0xfe4bb977), + LL(0x640bfd9e,0xbb5bb990),LL(0x82f62108,0xd226e277),LL(0x02ffdd56,0x4bf00985),LL(0x2ca1b1b5,0x7756758a), LL(0x5285fe91,0xc32b62a3),LL(0x8c9cd140,0xedbc546a),LL(0xaf5cb008,0x1e47a013),LL(0x073ce8f2,0xbca7e720), + LL(0x17a91cae,0xe10b2ab8),LL(0x08e27f63,0xb89aab65),LL(0xdba3ddf9,0x7b3074a7),LL(0x330c2972,0x1c20ce09), LL(0x5fcf7e33,0x6b9917b4),LL(0x945ceb42,0xe6793743),LL(0x5c633d19,0x18fc2215),LL(0xc7485474,0xad1adb3c), + LL(0x6424c49b,0x646f9679),LL(0x67c241c9,0xf888dfe8),LL(0x24f68b49,0xe12d4b93),LL(0xa571df20,0x9a6b62d8), LL(0x179483cb,0x81b4b26d),LL(0x9511fae2,0x666f9632),LL(0xd53aa51f,0xd281b3e4),LL(0x7f3dbd16,0x7f96a765), + LL(0x074a30ce,0xa7f8b5bf),LL(0x005a32e6,0xd7f52107),LL(0x50237ed4,0x6f9e0907),LL(0x8096fa2b,0x2f21da47), LL(0xeec863a0,0xf3e19cb4),LL(0x9527620a,0xd18f77fd),LL(0x407c1cf8,0x9505c81c),LL(0x1b6ec284,0x9998db4e), + LL(0xc247d44d,0x7e3389e5),LL(0x3f4f3d80,0x12507141),LL(0x4a78a6c7,0xd4ba0110),LL(0x767720be,0x312874a0), LL(0x75944370,0xded059a6),LL(0x3b2c0bdd,0xd6123d90),LL(0x51c108e3,0xa56b717b),LL(0x070623e9,0x9bb7940e), + LL(0x84ac066c,0x794e2d59),LL(0xe68c69a0,0xf5954a92),LL(0x4fd99dcc,0x28c52458),LL(0xb1012517,0x60e639fc), LL(0x7de79248,0xc2e60125),LL(0xf12fc6d7,0xe9ef6404),LL(0x2a3b5d32,0x4c4f2808),LL(0xc768eb8a,0x865ad32e), + LL(0x13fb70b6,0xac02331b),LL(0x95599b27,0x037b44c1),LL(0x60bd082c,0x1a860fc4),LL(0xc980cd01,0xa2e25745), LL(0x1da0263e,0xee3387a8),LL(0x2d10f3d6,0x931bfb95),LL(0xa1f24a32,0x5b687270),LL(0xca494b86,0xf140e65d), + LL(0xb2f1ac7a,0x4f4ddf91),LL(0x760fee27,0xf99eaabb),LL(0x49c228e5,0x57f4008a),LL(0x1cf713bb,0x090be440), LL(0x5004f022,0xac91fbe4),LL(0x569e1af6,0xd838c2c2),LL(0x0f1daaa5,0xd6c7d20b),LL(0x1bbb02c0,0xaa063ac1), + LL(0x59558a78,0x0938a422),LL(0x8435da2f,0x5343c669),LL(0x034410dc,0x96f67b18),LL(0x84510804,0x7cc1e424), LL(0x16dfbb7d,0x86a1543f),LL(0x5b5bd592,0x921fa942),LL(0xb33dd03c,0x9dcccb6e),LL(0xb843f51e,0x8581ddd9), + LL(0x81d73c9e,0x54935fcb),LL(0x0a5e97ab,0x6d07e979),LL(0xcf3a6bab,0x4dc7b30a),LL(0x170bee11,0x147ab1f3), LL(0x9fafdee4,0x0aaf8e3d),LL(0x538a8b95,0xfab3dbcb),LL(0x6ef13871,0x405df4b3),LL(0x088d5a49,0xf1f4e9cb), + LL(0x66b33f1d,0x9bcd24d3),LL(0x5ce445c0,0x3b97b820),LL(0xba93ff61,0xe2926549),LL(0x4dafe616,0xd9c341ce), LL(0x16efb6f3,0xfb30a76e),LL(0x605b953c,0xdf24b8ca),LL(0xc2fffb9f,0x8bd52afe),LL(0xe19d0b96,0xbbac5ff7), + LL(0x459afccd,0x43c01b87),LL(0xb7432652,0x6bd45143),LL(0x55b5d78e,0x84734530),LL(0x1554ba7d,0x81088fdb), LL(0x1e269375,0xada0a52c),LL(0x2dc5ec10,0xf9f037c4),LL(0x94bfbc11,0xc0660607),LL(0xc9c40d2f,0xc0a630bb), + LL(0xab64c31e,0x5efc797e),LL(0x74507144,0xffdb1dab),LL(0x1ca6790c,0xf6124287),LL(0xe69bf1bf,0xe9609d81), LL(0x00d24fc9,0xdb898595),LL(0xe51fb417,0x9c750333),LL(0xfef7bbde,0x51830a91),LL(0x945f585c,0x0ce67dc8), + LL(0x4763eb50,0x9a730ed4),LL(0xc1ab0d66,0x24a0e221),LL(0x648748f3,0x643b6393),LL(0x6d3c6291,0x1982daa1), LL(0x8bbc5549,0x6f00a9f7),LL(0x7f36384e,0x7a1783e1),LL(0xde977f50,0xe8346323),LL(0xb245502a,0x91ab688d), + LL(0x6d0bdd66,0x331ab6b5),LL(0x64b71229,0x0a6ef32e),LL(0xfe7c352f,0x1028150e),LL(0xce7b39d3,0x27e04350), LL(0xc1070c82,0x2a3c8acd),LL(0x80c9feef,0xfb2034d3),LL(0x709f3729,0x2d729621),LL(0x62cb4549,0x8df290bf), + LL(0xfc2e4326,0x02f99f33),LL(0x5eddf032,0x3b30076d),LL(0x0c652fb5,0xbb21f8cf),LL(0xed91cf7b,0x314fb49e), LL(0x2f700750,0xa013eca5),LL(0x712a4575,0x2b9e3c23),LL(0xaf30fbb0,0xe5355557),LL(0x7c77e771,0x1ada3516), + LL(0x7b135670,0x45f6ecb2),LL(0x7cfc202e,0xe85d19df),LL(0x58d1be9f,0x0f1b50c7),LL(0xead2e344,0x5ebf2c0a), LL(0xabc199c9,0x1531fe4e),LL(0x56bab0ae,0xc7032592),LL(0x6c1fec54,0x16ab2e48),LL(0x04280188,0x0f87fda8), + LL(0x609e4a74,0xdc9f46fc),LL(0xba667f91,0x2a44a143),LL(0xb4d83436,0xbc3d8b95),LL(0xc7bd2958,0xa01e4bd0), LL(0x73483c90,0x7b182932),LL(0xa7c7b598,0xa79c6aa1),LL(0xeaaac07e,0xbf3983c6),LL(0x96e0d4e6,0x8f18181e), + LL(0x051af62b,0x8553d37c),LL(0x0bf94496,0xe9a998eb),LL(0xb0d59aa1,0xe0844f9f),LL(0xe6afb813,0x983fd558), LL(0x65d69804,0x9670c0ca),LL(0x6ea5ff2d,0x732b22de),LL(0x5fd8623b,0xd7640ba9),LL(0xa6351782,0x9f619163), + LL(0xacee5043,0x0bfc27ee),LL(0x2eb10f02,0xae419e73),LL(0x8943fb05,0x19c028d1),LL(0xff13aa2a,0x71f01cf7), LL(0x8887a132,0x7790737e),LL(0x66318410,0x67513309),LL(0x7ddb795e,0x9819e8a3),LL(0xdad100b2,0xfecb8ef5), + LL(0x3021926a,0x59f74a22),LL(0x6f9b4c1c,0xb7c28a49),LL(0x912ad0ab,0xed1a733f),LL(0x01a5659c,0x42a910af), LL(0x7bd68cab,0x3842c6e0),LL(0x76d70ac8,0x2b57fa38),LL(0x3c53aaeb,0x8a6707a8),LL(0x65b4db18,0x62c1c510), + LL(0xb2d09dc7,0x8de2c1fb),LL(0x266bd23b,0xc3dfed12),LL(0xd5b27db6,0x927d039b),LL(0x103243da,0x2fb2f0f1), LL(0x80be7399,0xf855a07b),LL(0x1f9f27a8,0xed9327ce),LL(0x729bdef7,0xa0bd99c7),LL(0x28250d88,0x2b67125e), + LL(0x8670ced7,0x784b26e8),LL(0xc31bd3b4,0xe3dfe41f),LL(0xbcc85cbc,0x9e353a06),LL(0x60178a9d,0x302e2909), LL(0xa6eac16e,0x860abf11),LL(0xaa2b3aac,0x76447000),LL(0x850afdab,0x46ff9d19),LL(0xfdb2d4c1,0x35bdd6a5), + LL(0x7e5c9ce9,0xe82594b0),LL(0x20af346e,0x0f379e53),LL(0xbc65ad4a,0x608b31e3),LL(0x267c4826,0x710c6b12), LL(0x71954cf1,0x51c966f9),LL(0x0d0aa215,0xb1cec793),LL(0x86bd23a8,0x1f155989),LL(0xf9452e86,0xae2ff99c), + LL(0x340ceaa2,0xd8dd953c),LL(0x2e2e9333,0x26355275),LL(0x8586f06d,0x15d4e5f9),LL(0xf7cab546,0xd6bf94a8), LL(0xb76a9af0,0x33c59a0a),LL(0xba095af7,0x52740ab3),LL(0x24389ca0,0xc444de8a),LL(0x706da0cb,0xcc6f9863), + LL(0x6b2515cf,0xb5a741a7),LL(0x9585c749,0x71c41601),LL(0xe683de97,0x78350d4f),LL(0x63d0b5f5,0x31d61524), LL(0xfbce090b,0x7a0cc5e1),LL(0xfbcb2a5b,0xaac927ed),LL(0x20d84c35,0xe920de49),LL(0x22b4de26,0x8c06a0b6), + LL(0xafe7ddf3,0xd34dd58b),LL(0xc1e6e55b,0x55851fed),LL(0x960696e7,0xd1395616),LL(0x5f22705f,0x940304b2), LL(0xb0a2a860,0x6f43f861),LL(0x0e7cc981,0xcf121282),LL(0x0ab64a96,0x12186212),LL(0xb789383c,0x09215b9a), + LL(0x37387c09,0x311eb305),LL(0xf03ee760,0xc5832fce),LL(0x32f7ea19,0x30358f58),LL(0x91d53551,0xe01d3c34), LL(0xda48ea80,0x1ca5ee41),LL(0xcf4fa4c1,0x34e71e8e),LL(0x7af1e1c7,0x312abd25),LL(0x2153f4a5,0xe3afcdeb), + LL(0x00235e9a,0x9d5c84d7),LL(0x8c4c836f,0x0308d3f4),LL(0x89332de5,0xc0a66b04),LL(0x89e566ef,0x610dd399), LL(0xd1ac1635,0xf8eea460),LL(0x20a2c0df,0x84cbb3fb),LL(0xe74a48c5,0x40afb488),LL(0xd326b150,0x29738198), + LL(0xa6d74081,0x2a17747f),LL(0x55a26214,0x60ea4c05),LL(0x1f88c5fe,0x53514bb4),LL(0x7e83426c,0xedd64567), LL(0x96460b25,0xd5d6cbec),LL(0x68dc115e,0xa12fd0ce),LL(0x697840ea,0xc5bc3ed2),LL(0xa6331e31,0x969876a8), + LL(0x472ff580,0x60c36217),LL(0x4ad41393,0xf4229705),LL(0xa03b8b92,0x4bd99ef0),LL(0xc144f4f6,0x501c7317), LL(0x18464945,0x159009b3),LL(0x74c5c6be,0x6d5e594c),LL(0x321a3660,0x2d587011),LL(0x3898d022,0xd1e184b1), + LL(0x4c6a7e04,0x5ba04752),LL(0x45550b65,0x47fa1e2b),LL(0x48c0a9a5,0x9419daf0),LL(0x7c243236,0x66362953), LL(0x5cb12a88,0xcd0744b1),LL(0x2b646188,0x561b6f9a),LL(0x66c2c0c0,0x599415a5),LL(0x0f83f09a,0xbe3f0859), + LL(0xb92041b8,0x9141c5be),LL(0x26477d0d,0x01ae38c7),LL(0xd12c7a94,0xca8b71f3),LL(0x765c70db,0xfab5b31f), LL(0x487443e9,0x76ae7492),LL(0x990d1349,0x8595a310),LL(0x7d460a37,0xf8dbeda8),LL(0x1e45a38f,0x7f7ad082), + LL(0x1059705a,0xed1d4db6),LL(0xe6b9c697,0xa3dd492a),LL(0x6eb38bd5,0x4b92ee3a),LL(0x67cc0bb7,0xbab2609d), LL(0x6e70ee82,0x7fc4fe89),LL(0x13e6b7e3,0xeff2c56e),LL(0x34d26fca,0x9b18959e),LL(0x889d6b45,0x2517ab66), + LL(0xbdefdd4f,0xf167b4e0),LL(0xf366e401,0x69958465),LL(0xa73bbec0,0x5aa368ab),LL(0x7b240c21,0x12148709), LL(0x18969006,0x378c3233),LL(0xe1fe53d1,0xcb4d73ce),LL(0x130c4361,0x5f50a80e),LL(0x7ef5212b,0xd67f5951), + LL(0x9e70c72e,0xf145e21e),LL(0x5566d2fb,0xb2e52e29),LL(0x032397f5,0x44eaba4a),LL(0x7e31a7de,0x5e56937b), LL(0x456c61e1,0x68dcf517),LL(0xa8b0a388,0xbc2e954a),LL(0x60a8b755,0xe3552fa7),LL(0x73ad0cde,0x03442dae), + LL(0xceb26210,0x37ffe747),LL(0x787baef9,0x983545e8),LL(0x86a3de31,0x8b8c8535),LL(0xfacd46db,0xc621dbcb), LL(0x59266fbb,0x82e442e9),LL(0x339d471c,0xa3514c37),LL(0x62cdad96,0x3a11b771),LL(0xecf9bdf0,0xf0cb3b3c), + LL(0x478e2135,0x3fcbdbce),LL(0xbda35342,0x7547b5cf),LL(0x8a677af6,0xa97e81f1),LL(0x28817987,0xc8c2bf83), LL(0x45580985,0xdf07eaaf),LL(0xc93b45cb,0xc68d1f05),LL(0xc77b4cac,0x106aa2fe),LL(0x04a7ae86,0x4c1d8afc), + LL(0x9eb45ab2,0xdb41c3fd),LL(0xd4b22e74,0x5b234b5b),LL(0xf215958a,0xda253dec),LL(0xa04edfa0,0x67e0606e), LL(0xef751b11,0xabbbf070),LL(0xf6f06dce,0xf352f175),LL(0x6839f6b4,0xdfc4b6af),LL(0x9959848e,0x53ddf9a8), + LL(0xc21520b0,0xda49c379),LL(0xdbd5d1b6,0x90864ff0),LL(0x5f49c7f7,0x2f055d23),LL(0xa796b2d8,0xe51e4e6a), LL(0x5c9dc340,0xc361a67f),LL(0xbca7c620,0x5ad53c37),LL(0x32c756d0,0xda1d6588),LL(0x8bb67e13,0xad60d911), + LL(0x0eeec8c6,0xd6c47bdf),LL(0x078a1821,0x4a27fec1),LL(0xc3099524,0x081f7415),LL(0x82cd8060,0x8effdf0b), LL(0x65842df8,0xdb70ec1c),LL(0xd319a901,0x8821b358),LL(0xde42b529,0x72ee56ee),LL(0x236e4286,0x5bb39592), + LL(0xfd6f7140,0xd1183316),LL(0xbd8e81f7,0xf9fadb5b),LL(0x5a02d962,0x701d5e0c),LL(0x1b601324,0xfdee4dbf), LL(0x35d7620e,0xbed17407),LL(0xf48c0012,0x04e3c2c3),LL(0x3455449a,0x9ee29da7),LL(0x91a836c4,0x562cdef4), + LL(0x47701097,0x8f682a5f),LL(0xff88d0c2,0x617125d8),LL(0x57bb86dd,0x948fda24),LL(0x289f7286,0x348abb8f), LL(0x99d94bbd,0xeb10eab5),LL(0x4684d160,0xd51ba28e),LL(0x30c8f41a,0xabe0e51c),LL(0x13254f4a,0x66588b45), + LL(0xfad097a5,0x147ebf01),LL(0x610e815d,0x49883ea8),LL(0x8a11de56,0xe44d60ba),LL(0x827a7a6d,0xa970de6e), LL(0x5e17fc19,0x2be41424),LL(0x01214057,0xd833c657),LL(0x363e723f,0x1375813b),LL(0xe6a52e9b,0x6820bb88), + LL(0xd875d56a,0x7e7f6970),LL(0x51fbf6bf,0xd6a0a9ac),LL(0xa3083c12,0x54ba8790),LL(0x6ae7eb64,0xebaeb23d), LL(0xb99a907a,0xa8685c3a),LL(0x026bf40b,0xf1e74550),LL(0xc802cd9e,0x7b73a027),LL(0x4fef4635,0x9a8a927c), + LL(0x08191224,0xe1b6f60c),LL(0xde4ec091,0xc4126ebb),LL(0x4ae38d84,0xe1dff4dc),LL(0x4f2ef985,0xde3f57db), LL(0xd446a1dd,0x34964337),LL(0x859e77f6,0x7bf217a0),LL(0x8e1d13f5,0x8ff10527),LL(0x74eeae27,0xa304ef03), + LL(0xd19dfa5a,0xfc6f5e47),LL(0x7fad982b,0xdb007de3),LL(0x613715f5,0x28205ad1),LL(0x7889529e,0x251e6729), LL(0x1ae98e78,0x72705184),LL(0x271cac32,0xf818537d),LL(0xb7f410f5,0xc8a15b7e),LL(0x81f62393,0xc474356f), + LL(0xc242316b,0x92dbdc5a),LL(0xdbf4aff5,0xabe060ac),LL(0x909a8ec6,0x6e8c38fe),LL(0x6116cb94,0x43e514e5), LL(0x07d784f9,0x2078fa38),LL(0xf4b5b357,0x1161a880),LL(0x13adea3d,0x5283ce79),LL(0xcc6a910b,0x0756c3e6), + LL(0xaaa79697,0x60bcfe01),LL(0x56391db1,0x04a73b29),LL(0x189b45a0,0xdd8dad47),LL(0x48d5b8d9,0xbfac0dd0), LL(0x7d3d2ec2,0x34ab3af5),LL(0x207bd3af,0x6fa2fc2d),LL(0x66550ded,0x9ff40092),LL(0x1fd5b913,0x719b3e87), + LL(0x6d17fbc7,0xa573a496),LL(0x73d2b24e,0x0cd1a70a),LL(0xb2676937,0x34e2c5ca),LL(0xbf669f21,0xe7050b06), LL(0x1ede9046,0xfbe948b6),LL(0x97662659,0xa0530051),LL(0xf10124c5,0x58cbd4ed),LL(0xdd6c06c8,0xde2646e4), + LL(0x8cad38c0,0x332f8108),LL(0x6bd68ae2,0x471b7e90),LL(0x0d8e27a3,0x56ac3fb2),LL(0x136b4b0d,0xb54660db), LL(0xa6fd8de4,0x123a1e11),LL(0xa37799ef,0x44dbffea),LL(0xce6ac17c,0x4540b977),LL(0xaf60acef,0x495173a8), +}, +/* digit=9 base_pwr=2^63 */ +{ + LL(0x391c2a82,0x9ebb284d),LL(0x158308e8,0xbcdd4863),LL(0x83f1edca,0x006f16ec),LL(0x695dc6c8,0xa13e2c37), LL(0x4a057a87,0x2ab756f0),LL(0xa6b48f98,0xa8765500),LL(0x68651c44,0x4252face),LL(0xe1765e02,0xa52b540b), + LL(0x16a0d2bb,0x4f922fc5),LL(0x1a623499,0x0d5cc16c),LL(0x57c62c8b,0x9241cf3a),LL(0xfd1b667f,0x2f5e6961), LL(0xf5a01797,0x5c15c70b),LL(0x60956192,0x3d20b44d),LL(0x071fdb52,0x04911b37),LL(0x8d6f0f7b,0xf648f916), + LL(0xe60b7cf7,0x6dc1acaf),LL(0x84a9d869,0x25860a50),LL(0xe7ba8ac4,0x56fc6f09),LL(0x6148d29e,0x828c5bd0), LL(0xdc55ae5f,0xac6b435e),LL(0xc0117411,0xa527f56c),LL(0xfd24342c,0x94d5045e),LL(0x70b67c0d,0x2c4c0a35), + LL(0xfac61d9a,0x027cc8b8),LL(0xe3c6fe8a,0x7d25e062),LL(0xe5bff503,0xe08805bf),LL(0x6ff632f7,0x13271e6c), LL(0x232f76a5,0x55dca6c0),LL(0x701ef426,0x8957c32d),LL(0xa10a5178,0xee728bcb),LL(0xb62c5173,0x5ea60411), + LL(0xd0b8892b,0xfc4e964e),LL(0x9301bb74,0x9ea17683),LL(0xfcc48626,0x6265c5ae),LL(0xbb3e9102,0xe60cf82e), LL(0xd4df5531,0x57adf797),LL(0x8deeefe2,0x235b59a1),LL(0x3f306eb1,0x60adcf58),LL(0x3d09492d,0x105c2753), + LL(0xb5def996,0x4090914b),LL(0x233dd1e7,0x1cb69c83),LL(0x9b3d5e76,0xc1e9c1d3),LL(0xfccf6012,0x1f3338ed), LL(0x2f5378a8,0xb1e95d0d),LL(0x2f00cd21,0xacf4c2c7),LL(0xeb5fe290,0x6e984240),LL(0x248088ae,0xd66c038d), + LL(0xf94d70cf,0x804d264a),LL(0x7314bf7e,0xbdb802ef),LL(0x4333ed02,0x8fb54de2),LL(0x285635d9,0x740461e0), LL(0x365e9383,0x4113b2c8),LL(0x3fdef652,0xea762c83),LL(0x47b956c1,0x4eec6e2e),LL(0x65620fa4,0xa3d814be), + LL(0xb4d8bc50,0x9ad5462b),LL(0xa9195770,0x181c0b16),LL(0x78412a68,0xebd4fe1c),LL(0xc0dff48c,0xae0341bc), LL(0x7003e866,0xb6bc45cf),LL(0x8a24a41b,0xf11a6dea),LL(0xd04c24c2,0x5407151a),LL(0xda5b7b68,0x62c9d27d), + LL(0x88cceff6,0x2e964235),LL(0x8b07ed69,0x8594c54f),LL(0xc84d0d0d,0x1578e73c),LL(0xff532868,0x7b4e1055), LL(0xb5ec995a,0xa348c0d5),LL(0x14289a54,0xbf4b9d55),LL(0x58fbd777,0x9ba155a6),LL(0x1a84491d,0x186ed7a8), + LL(0x614c0900,0xd4992b30),LL(0xbd00c24b,0xda98d121),LL(0x7ec4bfa1,0x7f534dc8),LL(0x37dc34bc,0x4a5ff674), LL(0x1d7ea1d7,0x68c196b8),LL(0x80a6d208,0x38cf2893),LL(0xe3cbbd6e,0xfd56cd09),LL(0x4205a5b6,0xec72e27e), + LL(0xa44f77f7,0x15ea68f5),LL(0xb43c52bc,0x7aa5f9fd),LL(0x94f0e609,0x86ff676f),LL(0x2e2d432b,0xa4cde963), LL(0xeee470af,0x8cafa0c0),LL(0x8a3f5ec8,0x84137d0e),LL(0xfaa31231,0xebb40411),LL(0x6f7f7ccf,0xa239c13f), + LL(0xa8afd30b,0x32865719),LL(0x8a826dce,0x86798328),LL(0xc4a8fbe0,0xdf04e891),LL(0xebf56ad3,0xbb6b6e1b), LL(0x471f1ff0,0x0a695b11),LL(0xbe15baf0,0xd76c3389),LL(0xbe96c43e,0x018edb95),LL(0x90794158,0xf2beaaf4), + LL(0xc3076a27,0x152db09e),LL(0xe416545d,0x5e82908e),LL(0x356d6f2e,0xa2c41272),LL(0x31fd74e1,0xdc9c9642), LL(0x519bf615,0x66ceb88d),LL(0x05a2274e,0xe29ecd76),LL(0xbf5e2fa0,0x3a0473c4),LL(0x64284e67,0x6b6eb671), + LL(0xb88756dd,0xe8b97932),LL(0xf17e3e61,0xed4e8652),LL(0x3ee1c4a4,0xc2dd1499),LL(0x597f8c0e,0xc0aaee17), LL(0x6c168af3,0x15c4edb9),LL(0xb39ae875,0x6563c7bf),LL(0x20adb436,0xadfadb6f),LL(0x9a042ac0,0xad55e8c9), + LL(0xb76da1f5,0x975a1ed8),LL(0xa58acb94,0x10dfa466),LL(0xac060282,0x8dd7f7e3),LL(0x572a051e,0x6813e66a), LL(0x350cb901,0xb4ccae1e),LL(0x50cb7822,0xb653d656),LL(0xdfab3b87,0x42484710),LL(0x9b670fd0,0xcd7ee537), + LL(0x523b8bf6,0x0a50b12e),LL(0x8f910c1b,0x8009eb5b),LL(0x4a167588,0xf535af82),LL(0xfb2a2abd,0x0f835f9c), LL(0x2afceb62,0xf59b2931),LL(0x169d383f,0xc797df2a),LL(0x66ac02b0,0xeb3f5fb0),LL(0xdaa2d0ca,0x029d4c6f), + LL(0xafab4bc5,0xd4059bc1),LL(0x56783247,0x833f5c6f),LL(0x8d2d3605,0xb5346630),LL(0xd34d8433,0x83387891), LL(0xadd9419a,0xd973b30f),LL(0xafe3fce8,0xbcca1099),LL(0x0809aac6,0x08178315),LL(0x540f0f11,0x01b7f21a), + LL(0x909523c8,0x65c29219),LL(0xa3a1c741,0xa62f648f),LL(0x60c9e55a,0x88598d4f),LL(0x0e4f347a,0xbce9141b), LL(0x35f9b988,0x9af97d84),LL(0x320475b6,0x0210da62),LL(0x9191476c,0x3c076e22),LL(0x44fc7834,0x7520dbd9), + LL(0xc1ab1bbd,0x6a6b2cfe),LL(0xdc650938,0xef8a65be),LL(0x805d7bc4,0x72855540),LL(0xed11fdfd,0xda389396), LL(0x74660876,0xa9d5bd36),LL(0xb45dff35,0x11d67c54),LL(0xa4f5da94,0x6af7d148),LL(0xc0bbeb31,0xbb8d4c3f), + LL(0xe0a1b12a,0x87a7ebd1),LL(0x770ba95f,0x1e4ef88d),LL(0xdc2ae9cb,0x8c33345c),LL(0x01cc8403,0xcecf1276), LL(0x1b39b80f,0x687c012e),LL(0x35c33ba4,0xfd90d0ad),LL(0x5c9661c2,0xa3ef5a67),LL(0xe017429e,0x368fc88e), + LL(0x196a2fa2,0xd30c6761),LL(0xbd5b312e,0x931b9817),LL(0x72f54a31,0xba01000c),LL(0x66eaa541,0xa203d2c8), LL(0x98939db3,0xf2abdee0),LL(0x3e606c02,0xe37d6c2c),LL(0x521ff643,0xf2921574),LL(0xd7e2fca3,0x2781b3c4), + LL(0x7850ec06,0x664300b0),LL(0x7d3a10cf,0xac5a38b9),LL(0xe34ab39d,0x9233188d),LL(0x5072cbb9,0xe77057e4), LL(0xb59e78df,0xbcf0c042),LL(0x1d97de52,0x4cfc91e8),LL(0x3ee0ca4a,0x4661a26c),LL(0xfb8507bc,0x5620a4c1), + LL(0x049f842c,0x4b44d4aa),LL(0x1540e82b,0xceabc5d5),LL(0x15c6f156,0x306710fd),LL(0x63db1d72,0xbe5ae52b), LL(0x334957f1,0x06f1e7e6),LL(0x31144a70,0x57e388f0),LL(0xdf96447b,0xfb69bb2f),LL(0x73e38a12,0x0f78ebd3), + LL(0x2b7ce542,0xb8222605),LL(0x7472bde1,0xe6d4ce99),LL(0x09d2f4da,0x53e16ebe),LL(0x53b92b2e,0x180ff42e), LL(0x2c34a1c6,0xc59bcc02),LL(0x422c46c2,0x3803d6f9),LL(0x5c14a8a2,0x18aff74f),LL(0x10a08b28,0x55aebf80), + LL(0x7135593f,0x66097d58),LL(0x2be570cd,0x32e6eff7),LL(0x2a8c860d,0x584e6a10),LL(0xa2eb4163,0xcd185890), LL(0x6d97e134,0x7ceae99d),LL(0xdd8447ce,0xd42c6b70),LL(0xb8c50273,0x59ddbb4a),LL(0x3cf34e1e,0x03c612df), + LL(0x04b6c5a0,0x84b9ca15),LL(0x18f0e3a3,0x35216f39),LL(0xbd986c00,0x3ec2d2bc),LL(0xd19228fe,0x8bf546d9), LL(0x4cd623c3,0xd1c655a4),LL(0x502b8e5a,0x366ce718),LL(0xeea0bfe7,0x2cfc84b4),LL(0xcf443e8e,0xe01d5cee), + LL(0x036520f8,0x8ec045d9),LL(0x92d40e98,0xdfb3c3d1),LL(0xcc559a04,0x0bac4cce),LL(0x240ea6b1,0x35eccae5), LL(0xf8a5a0ac,0x180b32db),LL(0xeb699700,0x547972a5),LL(0xca26bca0,0xa3765801),LL(0xa647f25a,0x57e09d0e), + LL(0x2fdd23cc,0xb956970e),LL(0x5682e971,0xb80288bc),LL(0x9ae86ebc,0xe6e6d91e),LL(0x8c9f1939,0x0564c83f), LL(0x39560368,0x551932a2),LL(0x049c28e2,0xe893752b),LL(0xa6a158c3,0x0b03cee5),LL(0x04964263,0xe12d656b), + LL(0x63e3bc1d,0x4b47554e),LL(0x45044ff7,0xc719b6a2),LL(0xe48daa07,0x4f24d30a),LL(0xc8c1edc3,0xa3f37556), LL(0x0700d360,0x9a47bf76),LL(0x822ae4e2,0xbb1a1824),LL(0x89f1fb4c,0x22e275a3),LL(0x9968c5f5,0x72b1aa23), + LL(0xbe063f64,0xa75feaca),LL(0xbce47a09,0x9b392f43),LL(0x1ad07aca,0xd4241509),LL(0x8d26cd0f,0x4b0c591b), LL(0x92f1169a,0x2d42ddfd),LL(0x4cbf2392,0x63aeb1ac),LL(0x0691a2af,0x1de9e877),LL(0xd98021da,0xebe79af7), + LL(0x40e50acf,0xcfdf2a4e),LL(0xaf01d665,0xf0a98ad7),LL(0x1831be1f,0xefb640bf),LL(0x80e9ada0,0x6fe8bd2f), LL(0x6cafbc91,0x94c103a1),LL(0x8308e08c,0x170f8759),LL(0x9780ff4f,0x5de2d2ab),LL(0x45b201f2,0x666466bc), + LL(0xf5b343bc,0x58af2010),LL(0xf2f142fe,0x0f2e400a),LL(0xa85f4bdf,0x3483bfde),LL(0x03bfeaa9,0xf0b1d093), LL(0xc7081603,0x2ea01b95),LL(0x3dba1097,0xe943e4c9),LL(0xb438f3a6,0x47be92ad),LL(0xe5bf6636,0x00bb7742), + LL(0x824297b4,0x136b7083),LL(0x5584455f,0x9d0e5580),LL(0xf1c7d69e,0xab48cedc),LL(0x2a256e76,0x53a9e481), LL(0x65eb2413,0x0402b0e0),LL(0x8fc407a7,0xdadbbb84),LL(0x8d7f5492,0xa65cd5a4),LL(0x74bae294,0x21d44293), + LL(0x3b5f1cc4,0x66917ce6),LL(0xce872e62,0x37ae52ea),LL(0x2905f244,0xbb087b72),LL(0x1e6af74f,0x12077086), LL(0x1058edea,0x4b644e49),LL(0xb638ca1d,0x827510e3),LL(0x6038591c,0x8cf2b704),LL(0xfe635063,0xffc8b47a), + LL(0x1b4d5e63,0x3ae220e6),LL(0x9d961b4b,0xbd864742),LL(0x9bd16bed,0x610c107e),LL(0x1127147b,0x4270352a), LL(0x64cfc50e,0x7d17ffe6),LL(0x1e36cb42,0x50dee01a),LL(0x35dc5f9a,0x068a7622),LL(0xdf53f62c,0x9a08d536), + LL(0x6be5f7de,0x4ed71457),LL(0xc2263c9e,0xd93006f8),LL(0xcacacb36,0xe073694c),LL(0x3ae118ab,0x2ff7a5b4), LL(0xcd871236,0x3cce53f1),LL(0xc2aa6d52,0xf156a39d),LL(0xb198d76d,0x9cc5f271),LL(0x81383d39,0xbc615b6f), + LL(0xde3eee6b,0xa54538e8),LL(0xab910d91,0x58c77538),LL(0x58d278bd,0x31e5bdbc),LL(0xb963acae,0x3cde4adf), LL(0x5302169c,0xb1881fd2),LL(0xa989ed8b,0x8ca60fa0),LL(0xff96a0ee,0xa1999458),LL(0xac6c283d,0xc1141f03), + LL(0x6dfafed3,0x7677408d),LL(0x39661588,0x33a01653),LL(0x0b726fa0,0x3c9c15ec),LL(0x6c9b56da,0x090cfd93), LL(0xa3c40af5,0xe34f4bae),LL(0xd21129f1,0x3469eadb),LL(0x1e207ce8,0xcc51674a),LL(0xc83b1ef9,0x1e293b24), + LL(0x1e6c0bb4,0x17173d13),LL(0x90776d35,0x19004695),LL(0x6de6f922,0xe7980e34),LL(0xf4dd9a22,0x873554cb), LL(0xcbf18a51,0x0316c627),LL(0x3032c081,0x4d93651b),LL(0x3946834d,0x207f2771),LL(0x30cdbf80,0x2c08d7b4), + LL(0x86df2a61,0x137a4fb4),LL(0xecf7b4a2,0xa1ed9c07),LL(0x7bd042ff,0xb2e460e2),LL(0x5f62f5ec,0xb7f5e2fa), LL(0xcc2423b7,0x7aa6ec6b),LL(0xba63eea7,0x75ce0a7f),LL(0xf250a6e1,0x67a45fb1),LL(0xe53cdc9f,0x93bc919c), + LL(0x871942df,0x9271f56f),LL(0x7859ad66,0x2372ff6f),LL(0x33cb1a78,0x5f4c2b96),LL(0x5838aa83,0xe3e29101), LL(0xe4e8110c,0xa7ed1611),LL(0x330198ce,0x2a2d70d5),LL(0x6720efe0,0xbdf132e8),LL(0x66a471bf,0xe61a8962), + LL(0x825808bd,0x796d3a85),LL(0x3fd6e902,0x51dc3cb7),LL(0x916219d1,0x643c768a),LL(0xa2ad7d32,0x36cd7685), LL(0xb22922a4,0xe3db9d05),LL(0xdba29660,0x6494c87e),LL(0xbcd2ebc7,0xf0ac91df),LL(0x45107f8d,0x4deb57a0), + LL(0xc3d12a73,0x42271f59),LL(0xa5c2c51d,0x5f71687c),LL(0x05797bcb,0xcb1f50c6),LL(0xd6d34eb0,0x29ed0ed9), LL(0x4683c2eb,0xe5fe5b47),LL(0x97447c46,0x4956eeb5),LL(0x71207167,0x5b163a43),LL(0x0248c5ef,0x93fa2fed), + LL(0x31f63950,0x67930af2),LL(0x14caa2c9,0xa77797c1),LL(0x27ac7e62,0x526e80ee),LL(0x58b28aec,0xe1e6e626), LL(0xb3c9fef0,0x636178b0),LL(0x6d5f90be,0xaf7752e0),LL(0xeece51cf,0x94ecaf18),LL(0xca806e1f,0x2864d0ed), + LL(0x97c69134,0x6de2e383),LL(0xeb291293,0x5a42c316),LL(0x6a60bae0,0xc7779219),LL(0x6b7599d1,0xa24de346), LL(0xb75d4941,0x49d374aa),LL(0x2d501ff0,0x98900586),LL(0xeb7974cf,0x9f16d40e),LL(0xcdd8c115,0x1033860b), + LL(0x2094cec3,0xb6c69ac8),LL(0x403b770c,0x9976fb88),LL(0x4859590d,0x1dea026c),LL(0x8562d1fd,0xb6acbb46), LL(0x44569d85,0x7cd6c461),LL(0x97f0891d,0xc3190a36),LL(0x48d5a17d,0xc6f53195),LL(0xd749abc8,0x7d919966), + LL(0xdd1c8a20,0x65104837),LL(0x2f683419,0x7e5410c8),LL(0xbe94022e,0x958c3ca8),LL(0x6145dac2,0x605c3197), LL(0x01683d54,0x3fc07501),LL(0x595b1234,0x1d7127c5),LL(0x9481277f,0x10b8f87c),LL(0xe65a1adb,0x677db2a8), + LL(0xddce3345,0xec2fccaa),LL(0x012a4350,0x2a6811b7),LL(0xac598bdc,0x96760ff1),LL(0xd1bf4128,0x054d652a), LL(0x92a21005,0x0a1151d4),LL(0x33110fdf,0xad7f3971),LL(0x1960100f,0x8c95928c),LL(0x7bf03362,0x6c91c825), + LL(0xce309f06,0xc8c8b2a2),LL(0xca27204b,0xfdb27b59),LL(0x0848e32e,0xd223eaa5),LL(0xe7bfaf1e,0xb93e4b2e), LL(0x44aa3ded,0xc5308ae6),LL(0xc015d573,0x317a666a),LL(0x1a979707,0xc888ce23),LL(0x0d5c4958,0xf141c1e6), + LL(0x61906373,0xb53b7de5),LL(0xeb999595,0x858dbade),LL(0xa59e5c36,0x8cbb47b2),LL(0xdcf4e842,0x660318b3), LL(0x12ba4b7a,0xbd161ccd),LL(0xf8c8282a,0xf399daab),LL(0xeeb2130d,0x1587633a),LL(0xda38dd7d,0xa465311a), + LL(0x64d3779b,0x5f75eec8),LL(0xad64c171,0x3c5d0476),LL(0x2a914428,0x87410371),LL(0x90e2fc29,0x8096a891), LL(0x23b3ebc2,0xd3d2ae9d),LL(0xa580cfd6,0x90bdd6db),LL(0xc5b01f6c,0x52dbb7f3),LL(0xe102a2dc,0xe68eded4), + LL(0x99eb6df0,0x17785b77),LL(0x7386b779,0x26c3cc51),LL(0x6417a48e,0x345ed988),LL(0x07d6ef31,0xe990b4e4), LL(0x2586abba,0x0f456b7e),LL(0x59c96e9a,0x239ca6a5),LL(0xe2eb4206,0xe327459c),LL(0xa002b90a,0x3a4c3313), + LL(0xf6a3f6fb,0x2a114806),LL(0x85c251dd,0xad5cad2f),LL(0xf5a784d3,0x92c1f613),LL(0x349766d5,0xec7bfacf), LL(0x3e23cb3b,0x04b3cd33),LL(0xc5a64b2d,0x3979fe84),LL(0x7e589106,0x192e2720),LL(0xa15b527f,0xa60c43d1), + LL(0xbe7cf3a6,0x2dae9082),LL(0xbc967274,0xcc86ba92),LL(0xaea0a8a9,0xf28a2ce8),LL(0x6ee988b3,0x404ca6d9), LL(0x005921b8,0xfd7e9c5d),LL(0x44e79bf9,0xf56297f1),LL(0x0d75ddc2,0xa163b460),LL(0xa1f2be87,0x30b23616), + LL(0xbfe50e2b,0x4b070d21),LL(0xe1bfede1,0x7ef8cfd0),LL(0x2aac4ae0,0xadba0011),LL(0xb9ebd033,0x2a3e7d01), LL(0xe38d9d1c,0x995277ec),LL(0x9c5d2de3,0xb500249e),LL(0xf13ca8c9,0x8912b820),LL(0x877793af,0xc8798114), + LL(0xec3f1dec,0x19e6125d),LL(0x911178da,0x07b1f040),LL(0x904a6738,0xd93ededa),LL(0x0bebedcd,0x55187a5a), LL(0xeb329d41,0xf7d04722),LL(0xf170b391,0xf449099e),LL(0xca99f828,0xfd317a69),LL(0x34a4976d,0x50c3db2b), + LL(0x3757b392,0xe9ba7784),LL(0xaa3ca05a,0x326caefd),LL(0xf1e593d4,0x78e5293b),LL(0x0d98fd13,0x7842a937), LL(0x5f96b10d,0xe694bf96),LL(0x06a8cd05,0x373a9df6),LL(0xe8f0c7fc,0x997d1e51),LL(0x63fd972e,0x1d019790), + LL(0x5499fb32,0x0064d858),LL(0x77a8aeb7,0x7b67bad9),LL(0x2d08eec5,0x1d3eb977),LL(0xcbabae1d,0x5fc047a6), LL(0xe54a64bb,0x0577d159),LL(0xc43497e4,0x8862201b),LL(0x2ce0608d,0xad6b4e28),LL(0x0b167aac,0x8b687b7d), + LL(0x8b2ecfa9,0x6ed4d367),LL(0xa90c3c38,0x24dfe62d),LL(0x3fe5c42b,0xa1862e10),LL(0xd5732a9f,0x1ca73dca), LL(0x76bb87ad,0x35f038b7),LL(0xf242b81f,0x674976ab),LL(0xb0fd90cd,0x4f2bde7e),LL(0xa7fdf092,0x6efc172e), + LL(0x92222f1f,0x3806b69b),LL(0x6cf7ae70,0x5a2459ca),LL(0xa85217ee,0x6789f69c),LL(0xe3dc85ac,0x5f232b5e), LL(0x48e9e516,0x660e3ec5),LL(0x3197eb31,0x124b4e47),LL(0xaafcca23,0x10a0cb13),LL(0x8213224f,0x7bd63ba4), + LL(0x290a7f4f,0xaffad7cc),LL(0x0286b461,0x6b409c9e),LL(0xffa407af,0x58ab809f),LL(0xc68ac073,0xc3122eed), LL(0x4ef24d7e,0x17bf9e50),LL(0x3e2a5811,0x5d929794),LL(0x02902e01,0x519bc867),LL(0x39c8a851,0x76bba5da), + LL(0xda94951e,0xe9f9669c),LL(0x66b8d418,0x4b6af58d),LL(0x17d426a4,0xfa321074),LL(0x9dde6027,0xc78e66a9), LL(0x4a53b964,0x0516c083),LL(0xff602330,0xfc659d38),LL(0x58c5c897,0x0ab55e5c),LL(0x838bc5df,0x985099b2), + LL(0xc52fc238,0x061d9efc),LL(0x6ac1da3f,0x712b2728),LL(0x9283fe08,0xfb658149),LL(0xb8aaa2f7,0x4954ac94), LL(0x7fb2e74f,0x85c0ada4),LL(0xb89926b0,0xee8ba98e),LL(0x23d1af5b,0xe4f9d37d),LL(0xba9b015e,0x14ccdbf9), + LL(0x7bfe7178,0xb674481b),LL(0x65405868,0x4e1debae),LL(0xc48c867d,0x061b2821),LL(0x513b30ea,0x69c15b35), LL(0x36871088,0x3b4a1666),LL(0x1220b1ff,0xe5e29f5d),LL(0x233d9f4d,0x4b82bb35),LL(0x18cdc675,0x4e076333), +}, +/* digit=10 base_pwr=2^70 */ +{ + LL(0xa3e6fced,0x0d53f5c7),LL(0xf45fbdeb,0xe8cbbdd5),LL(0x13339a70,0xf85c01df),LL(0x142ceb81,0x0ff71880), LL(0xbd70437a,0x4c4e8774),LL(0xba0bda6a,0x5fb32891),LL(0xf18bd26e,0x1cdbebd2),LL(0x03a9d522,0x2f9526f1), + LL(0x92c4d684,0x40ce3051),LL(0x7612efcd,0x8b04d725),LL(0x6f9cae20,0xb9dcda36),LL(0xf058856c,0x0edc4d24), LL(0x85427900,0x64f2e6bf),LL(0xdc09dfea,0x3de81295),LL(0x379bf26c,0xd41b4487),LL(0x6df135a9,0x50b62c6d), + LL(0xc72dfe67,0xd4f8e3b4),LL(0x90e19fdf,0xc416b0f6),LL(0x4c13bd35,0x18b9098d),LL(0x15b8cb9e,0xac11118a), LL(0xf0062841,0xf598a318),LL(0x89f356f4,0xbfe0602f),LL(0x30177a0c,0x7ae3637e),LL(0x61136537,0x34097747), + LL(0xd005832a,0x0db2fb5e),LL(0x91042e4f,0x5f5efd3b),LL(0xed70f8ca,0x8c4ffdc6),LL(0xb52da9cc,0xe4645d0b), LL(0xc9001d1f,0x9596f58b),LL(0x4e117205,0x52c8f0bc),LL(0xe398a084,0xfd4aa0d2),LL(0x104f49de,0x815bfe3a), + LL(0x23885e5f,0x97e5443f),LL(0xe8433aab,0xf72f8f99),LL(0xe4d4e604,0xbd00b154),LL(0xe5e173ff,0xd0b35e6a), LL(0x9164722d,0x57b2a048),LL(0x88761ec8,0x3e3c665b),LL(0x3da83832,0x6bdd1397),LL(0x73dafe3b,0x3c8b1a1e), + LL(0x54317cac,0x4497ace6),LL(0x521771b3,0xbe600ab9),LL(0xb0dfe8b8,0xb42e409e),LL(0x3942310f,0x386a67d7), LL(0x4431cc28,0x25548d8d),LL(0x985dc524,0xa7cff142),LL(0x93c4be32,0x4d60f5a1),LL(0xd071c6e1,0x83ebd5c8), + LL(0xb1fd2b0b,0xba3a80a7),LL(0x5bec33e8,0x9b3ad396),LL(0x79743fb3,0xb3868d61),LL(0xfdb462fa,0xcfd169fc), LL(0x9ce0a6af,0xd3b499d7),LL(0xe42d3ff8,0x55dc1cf1),LL(0xc6c3e1b2,0x04fb9e6c),LL(0x6f69a474,0x47e6961d), + LL(0xe548b37b,0x54eb3acc),LL(0x84d40549,0xb38e7542),LL(0x7b341b4f,0x8c3daa51),LL(0x690bf7fa,0x2f6928ec), LL(0x86ce6c41,0x0496b323),LL(0x10adadcd,0x01be1c55),LL(0x4bb5faf9,0xc04e67e7),LL(0xe15c9985,0x3cbaf678), + LL(0x50ca4247,0x8cd12145),LL(0xe7dd30aa,0xba1aa47a),LL(0xe58fee24,0x2f81ddf1),LL(0xeec9b0e8,0x03452936), LL(0x243aea96,0x8bdc3b81),LL(0x15c3d0e5,0x9a2919af),LL(0x10948361,0x9ea640ec),LL(0x6e0bcccf,0x5ac86d5b), + LL(0xc36cf440,0xf892d918),LL(0xc939719c,0xaed3e837),LL(0xc0218b64,0xb07b08d2),LL(0xce9790dd,0x6f1bcbba), LL(0x60919b8e,0x4a84d6ed),LL(0x8ac1f9eb,0xd8900791),LL(0x0dd5daef,0xf84941aa),LL(0x67fd62c5,0xb22fe40a), + LL(0x157f2db3,0x97e15ba2),LL(0x8e28ca9c,0xbda2fc8f),LL(0x37b9f454,0x5d050da4),LL(0x2379d72e,0x3d57eb57), LL(0xfb5ee997,0xe9b5eba2),LL(0xe11538ca,0x01648ca2),LL(0xf6327974,0x32bb76f6),LL(0xff3f4bb7,0x338f14b8), + LL(0xd7ab9a2d,0x524d226a),LL(0x7dfae958,0x9c00090d),LL(0x8751d8c2,0x0ba5f539),LL(0x3ab8262d,0x8afcbcdd), LL(0xe99d043b,0x57392729),LL(0xaebc943a,0xef51263b),LL(0x20862935,0x9feace93),LL(0xb06c817b,0x639efc03), + LL(0x66b4be7a,0x1fe054b3),LL(0x84a37a1e,0x3f25a9de),LL(0x78d75cd9,0xf39ef1ad),LL(0x5062c1b5,0xd7b58f49), LL(0xff563436,0x6f74f9a9),LL(0xe8af51e7,0xf718ff29),LL(0x15e97fec,0x5234d313),LL(0x292f1c0a,0xb6a8e2b1), + LL(0x327720c1,0xa7f53aa8),LL(0xba092cc8,0x956ca322),LL(0x28746c4d,0x8f03d64a),LL(0x66d0d392,0x51fe1782), LL(0x3c832c80,0xd19b34db),LL(0x6da2e3b4,0x60dccc5c),LL(0x0a104ccc,0x245dd62e),LL(0x620b21fd,0xa7ab1de1), + LL(0x3893d123,0xb293ae0b),LL(0xb15ee71c,0xf7b75783),LL(0x42a9468b,0x5aa3c614),LL(0xdb15d744,0xd686123c), LL(0xa7ab4116,0x8c616891),LL(0xa4e6a459,0x6fcd72c8),LL(0x77e5fad7,0xac219110),LL(0x704fa46b,0xfb6a20e7), + LL(0x341d81dc,0xe839be7d),LL(0x32148379,0xcddb6889),LL(0xf7026ead,0xda6211a1),LL(0xf4d1cc5e,0xf3b2575f), LL(0xa7a73ae6,0x40cfc8f6),LL(0x61d5b483,0x83879a5e),LL(0x41a50ebc,0xc5acb1ed),LL(0x3c07d8fa,0x59a60cc8), + LL(0xb1876262,0x1b73bdce),LL(0x12af4ee9,0x2b0d79f0),LL(0xd46e1d07,0x8bcf3b0b),LL(0xe45d152f,0x17d6af9d), LL(0x6d736451,0x73520461),LL(0x56b0bf5a,0x43cbbd97),LL(0xd5999b9d,0xb0833a5b),LL(0xeb72e398,0x702614f0), + LL(0x59c3e9f8,0x0aadf01a),LL(0xce6b3d16,0x40200e77),LL(0xdeddafad,0xda22bdd3),LL(0x310d72e1,0x76dedaf4), LL(0x4bc2e88f,0x49ef807c),LL(0x146dd5a5,0x6ba81291),LL(0x7d8d59e9,0xa1a4077a),LL(0x802db349,0x87b6a2e7), + LL(0x1b4e598e,0xd5679997),LL(0x06fe4b1d,0xf499ef1f),LL(0xfcb267c5,0x3978d3ae),LL(0x235786d0,0xb582b557), LL(0x1715cb07,0x32b3b2ca),LL(0x8480241d,0x4c3de6a2),LL(0xcb571ecd,0x63b5ffed),LL(0xed2fe9a9,0xeaf53900), + LL(0xc3b81990,0xdec98d4a),LL(0x9e0cc8fe,0x1cb83722),LL(0xd2b427b9,0xfe0b0491),LL(0xe983a66c,0x0f2386ac), LL(0xb3291213,0x930c4d1e),LL(0x59a62ae4,0xa2f82b2e),LL(0xf93e89e3,0x77233853),LL(0x11777c7f,0x7f8063ac), + LL(0x59ad2877,0xff0eb567),LL(0x9865c754,0x6f454642),LL(0x236e9a84,0xe6fe701a),LL(0x06e40fc3,0xc586ef16), LL(0x24bafad9,0x3f62b6e0),LL(0x64da906a,0xc8b42bd2),LL(0xda3276a0,0xc98e1eb4),LL(0x06cbf852,0x30d0e5fc), + LL(0xe8b4dfd4,0x1b6b2ae1),LL(0x8301cbac,0xd754d5c7),LL(0x112a39ac,0x66097629),LL(0x93ba4ab9,0xf86b5999), LL(0x99f9d581,0x26c9dea7),LL(0xc2fafeaa,0x0473b1a8),LL(0x3b2505a5,0x1469af55),LL(0xd6a43323,0x227d16d7), + LL(0xad3d97f9,0x3316f73c),LL(0x1f137455,0x52bf3bb5),LL(0x09954e7c,0x953eafeb),LL(0xdd732411,0xa721dfed), LL(0x141d4579,0xb4929821),LL(0xaa3bd435,0x3411321c),LL(0x17fa6015,0xafb355aa),LL(0x18e42f0e,0xb4e7ef4a), + LL(0x59371000,0x604ac97c),LL(0x7f759c18,0xe1c48c70),LL(0xa5db6b65,0x3f62ecc5),LL(0x38a21495,0x0a78b173), LL(0xbcc8ad94,0x6be1819d),LL(0xd89c3400,0x70dc04f6),LL(0xa6b4840a,0x462557b4),LL(0x60bd21c0,0x544c6ade), + LL(0x907a544b,0x6a00f24e),LL(0x313da210,0xa7520dcb),LL(0x11e4994b,0xfe939b75),LL(0xbc275d70,0x918b6ba6), LL(0x644be892,0xd3e5e0fc),LL(0xfdaf6c42,0x707a9816),LL(0xf15c13fe,0x60145567),LL(0xe130a54a,0x4818ebaa), + LL(0x58d2f767,0x28aad3ad),LL(0xd7e7c773,0xdc5267fd),LL(0xc3afcc98,0x4919cc88),LL(0x2db8cd4b,0xaa2e6ab0), LL(0xd0c63eaa,0xd46fec04),LL(0x19ffa832,0xa1cb92c5),LL(0xe43a631f,0x678dd178),LL(0x3dc788b3,0xfb5ae1cd), + LL(0x6e77de04,0x68b4fb90),LL(0xf06dbb97,0x7992bcf0),LL(0xc417c01d,0x896e6a13),LL(0xb956be01,0x8d96332c), LL(0x413aa2b9,0x902fc93a),LL(0xfc98c8a5,0x99a4d915),LL(0x565f1137,0x52c29407),LL(0x21e4f281,0x4072690f), + LL(0x02ff6072,0x36e607cf),LL(0x8ad98cdc,0xa47d2ca9),LL(0xf5f56609,0xbf471d1e),LL(0xf264ada0,0xbcf86623), LL(0xaa9e5cb6,0xb70c0687),LL(0x17401c6c,0xc98124f2),LL(0xd4a61435,0x8189635f),LL(0xa9d98ea6,0xd28fb8af), + LL(0x40c251f8,0xb9a67c2a),LL(0xa2da44be,0x88cd5d87),LL(0xe09b5423,0x437deb96),LL(0x64287dc1,0x150467db), LL(0xcdabb839,0xe161debb),LL(0xf1839a3e,0xa79e9742),LL(0x652d202b,0xbb8dd3c2),LL(0xe9f97d96,0x7b3e67f7), + LL(0xb1cb6ac9,0x5aa5d78f),LL(0xca1d0d45,0xffa13e8e),LL(0x2ba5bf95,0x369295dd),LL(0x39aff05e,0xd68bd1f8), LL(0x26d783f2,0xaf0d86f9),LL(0xfc3aafc1,0x543a59b3),LL(0x7b7da97c,0x3fcf81d2),LL(0xd25dee46,0xc990a056), + LL(0x519cce2c,0x3e6775b8),LL(0xae13d863,0xfc9af71f),LL(0x47c1605c,0x774a4a6f),LL(0x2fd205e8,0x46ba4245), LL(0xd3fd524d,0xa06feea4),LL(0x6de1acc2,0x1e724641),LL(0x334e2b42,0xf53816f1),LL(0x922f0024,0x49e5918e), + LL(0x65c7322d,0x439530b6),LL(0xb3c1b3fb,0xcf12cc01),LL(0x0172f685,0xc70b0186),LL(0x1b58391d,0xb915ee22), LL(0xa317db24,0x9afdf03b),LL(0x17b8ffc4,0x87dec659),LL(0xe4d3d050,0x7f46597b),LL(0x006500e7,0x80a1c1ed), + LL(0x78bf030e,0x84902a96),LL(0x50560148,0xfb5e9c9a),LL(0x63362426,0x6dae0a92),LL(0xa9e30c40,0xdcaeecf4), LL(0x518d0c6b,0xc0d887bb),LL(0xcb985b9d,0x99181152),LL(0xef7bc381,0xad186898),LL(0x9ee46201,0x18168ffb), + LL(0x2502753c,0x9a04cdaa),LL(0x51407c41,0xbb279e26),LL(0xf23564e5,0xeacb03aa),LL(0x71e61016,0x18336582), LL(0xeb809877,0x8684b8c4),LL(0xea0e672e,0xb336e18d),LL(0x34ee5867,0xefb601f0),LL(0x1341cfd1,0x2733edbe), + LL(0x26025c3c,0xb15e809a),LL(0x9350df88,0xe6e981a6),LL(0x8502fd8e,0x92376237),LL(0x0c12be9b,0x4791f216), LL(0x25f02425,0xb7256789),LL(0x7a974443,0xec863194),LL(0xfb41cc52,0x7c0ce882),LL(0xf25c07f2,0xc266ff7e), + LL(0x017025f3,0x3d4da8c3),LL(0xfb9579b4,0xefcf628c),LL(0x1f3716ec,0x5c4d0016),LL(0x6801116e,0x9c27ebc4), LL(0x1da1767e,0x5eba0ea1),LL(0x47004c57,0xfe151452),LL(0x8c2373b7,0x3ace6df6),LL(0x5dbc37ac,0x75c3dffe), + LL(0xddc925fc,0x3dc32a73),LL(0x2f65ee0b,0xb679c841),LL(0x451cbfeb,0x715a3295),LL(0xf76e9a29,0xd9889768), LL(0xb28ad247,0xec20ce7f),LL(0x00894d79,0xe99146c4),LL(0x9f5e3ea7,0x71457d7c),LL(0x38030031,0x097b2662), + LL(0xcf9f82a8,0xdb7f6ae6),LL(0x438f473a,0x319decb9),LL(0x283856c3,0xa63ab386),LL(0xb06a361b,0x13e3172f), LL(0x7d5a006c,0x2959f8dc),LL(0x75fba752,0x2dbc27c6),LL(0x87c22c9e,0xc1227ab2),LL(0x71a268b2,0x06f61f75), + LL(0x04779ce2,0x1b6bb971),LL(0x0aadcb1d,0xaca83812),LL(0xaeaab2d5,0x297ae0bc),LL(0x5bfb9f13,0xa5c14ee7), LL(0xf17a62c7,0xaa00c583),LL(0x173759f6,0x39eb962c),LL(0x86c9a88f,0x1eeba1d4),LL(0xdf016c5e,0x0ab6c37a), + LL(0xa28a0749,0xa2a147db),LL(0xee519165,0x246c20d6),LL(0xd3810715,0x5068d1b1),LL(0x748160b9,0xb1e7018c), LL(0xf380ff62,0x03f5b1fa),LL(0xf3cb2c1e,0xef7fb1dd),LL(0xfc91a7da,0xeab539a8),LL(0xf3f9b561,0x83ddb707), + LL(0xfe7df7a4,0xc550e211),LL(0x063f6f40,0xa7cd07f2),LL(0x2976879c,0xb0de3635),LL(0xe55741da,0xb5f83f85), LL(0xf3d8ac3d,0x4ea9d25e),LL(0x62819f02,0x6fe2066f),LL(0xcef4a564,0x4ab2b9c2),LL(0x5ffa2de3,0x1e155d96), + LL(0xc3a72d00,0x0eb0a19b),LL(0x8513c31b,0x4037665b),LL(0x04c64637,0x2fb2b6bf),LL(0x08cdc639,0x45c34d6e), LL(0xf01fd796,0x56f1e10f),LL(0xfe3667b8,0x4dfb8101),LL(0x9021d0c0,0xe0eda253),LL(0x8a06c6ab,0x7a94e9ff), + LL(0xbb9aa882,0x2d3bb0d9),LL(0xec05fd10,0xea20e4e5),LL(0x1a1ca64e,0xed7eeb5f),LL(0xc6327cbd,0x2fa6b43c), LL(0x3aa91121,0xb577e3cf),LL(0x3a34079b,0x8c6bd5ea),LL(0x60e02fc0,0xd7e5ba39),LL(0x90141bf8,0xf16dd2c3), + LL(0x80101b98,0xb57276d9),LL(0xb82f0f66,0x760883fd),LL(0x4bc3eff3,0x89d7de75),LL(0x5dc2ab40,0x03b60643), LL(0xe05beeac,0xcd6e53df),LL(0xbc3325cd,0xf2f1e862),LL(0x774f03c3,0xdd0f7921),LL(0x4552cc1b,0x97ca7221), + LL(0x1cd19f72,0x5a0d6afe),LL(0xf183fbeb,0xa20915dc),LL(0x832c403c,0x9fda4b40),LL(0xbe425442,0x32738edd), LL(0xb5eccf1a,0x469a1df6),LL(0x28bbe1f0,0x4b5aff42),LL(0x570dfc93,0x31359d7f),LL(0xf0088628,0xa18be235), + LL(0xb00ed3a9,0xa5b30fba),LL(0x73cdf8be,0x34c61374),LL(0xabc56797,0x2c5c5f46),LL(0xb82a8ae2,0x5cecf93d), LL(0xa968fbf0,0x7d3dbe41),LL(0x1a5c7f3d,0xd23d4583),LL(0xc087a9c7,0xf28f69a0),LL(0x474471ca,0xc2d75471), + LL(0x4eb732ec,0x36ec9f4a),LL(0xb1ca6bed,0x6c943bbd),LL(0xf2457892,0xd64535e1),LL(0xf7e2ac06,0x8b84a8ea), LL(0x2499dd5f,0xe0936cd3),LL(0x0ed04e57,0x12053d7e),LL(0xe4305d9d,0x4bdd0076),LL(0x1f67f0a2,0x34a527b9), + LL(0x9cec46ea,0xe79a4af0),LL(0x658b9bc7,0xb15347a1),LL(0x35af2f75,0x6bd2796f),LL(0x4051c435,0xac957990), LL(0xc33a655d,0x2669dda3),LL(0x88514aa3,0x5d503c2e),LL(0x3753dd41,0xdfa11337),LL(0x0b754f78,0x3f054673), + LL(0x496125bd,0xbf185677),LL(0x3775006c,0xfb0023c8),LL(0x3a037899,0xfa0f072f),LL(0x0e4aea57,0x4222b6eb), LL(0x7866d25a,0x3dde5e76),LL(0x4837aa6f,0xb6eb04f8),LL(0x2cf1cdb8,0x5315591a),LL(0x2d4e683c,0x6dfb4f41), + LL(0x48ee1f3a,0x7e923ea4),LL(0x05a2afd5,0x9604d9f7),LL(0x40ea4948,0xbe1d4a33),LL(0xb44cbd2f,0x5b45f1f4), LL(0x4acc757e,0x5faf8376),LL(0x63d68ff7,0xa7cf9ab8),LL(0xdf0e404b,0x8ad62f69),LL(0x12bdafdf,0xd65f33c2), + LL(0xa377b14e,0xc365de15),LL(0x8e39f60c,0x6bf5463b),LL(0x2ce68148,0x62030d2d),LL(0xe6f843a8,0xd95867ef), LL(0xef5ab017,0xd39a0244),LL(0x4ab55d12,0x0bd2d8c1),LL(0x41639169,0xc9503db3),LL(0xf7660c8a,0x2d4e25b0), + LL(0xe224c5d7,0x760cb3b5),LL(0x68616919,0xfa3baf8c),LL(0x8d142552,0x9fbca113),LL(0x7669ebf5,0x1ab18bf1), LL(0x9bdf25dd,0x55e6f53e),LL(0xcb6cd154,0x04cc0bf3),LL(0x95e89080,0x595bef49),LL(0x104a9ac1,0xfe9459a8), + LL(0xcce9bb32,0xad2d89ca),LL(0xf7de8285,0xddea65e1),LL(0xb351bd4b,0x62ed8c35),LL(0x0c0e19a7,0x4150ff36), LL(0x345f4e47,0x86e3c801),LL(0x203a266c,0x3bf21f71),LL(0x855b1f13,0x7ae110d4),LL(0x07262517,0x5d6aaf6a), + LL(0x813d28f1,0x1e0f12e1),LL(0x7ad7a523,0x6000e11d),LL(0xc744a17b,0xc7d8deef),LL(0x14c05a00,0x1e990b48), LL(0x93e976d5,0x68fddaee),LL(0x46610d63,0x696241d1),LL(0x893dda88,0xb204e7c3),LL(0x6a3a6946,0x8bccfa65), + LL(0xc5cd1411,0xb59425b4),LL(0xff3658b1,0x701b4042),LL(0x4784cf93,0xe3e56bca),LL(0x8fe68d60,0x27de5f15), LL(0xf8d53f19,0x4ab9cfce),LL(0xa40a730d,0xddb10311),LL(0x4eee0a8a,0x6fa73cd1),LL(0x5249719d,0xfd548748), + LL(0xa8123ef0,0x49d66316),LL(0xe7f95438,0x73c32db4),LL(0x0d9e7854,0x2e2ed209),LL(0x9d9f0507,0xf98a9329), LL(0x0c6aa20a,0xc5d33cf6),LL(0x75279bb2,0x9a32ba14),LL(0x774a7307,0x7e3202cb),LL(0xe8c42dbd,0x64ed4bc4), + LL(0xd4caed0d,0xc20f1a06),LL(0x171d22b3,0xb8021407),LL(0xd13268d7,0xd426ca04),LL(0x25f4d126,0x92377007), LL(0x71f21a85,0x4204cbc3),LL(0xf82369ba,0x18461b7a),LL(0x3fc858f9,0xc0c07d31),LL(0xe2bab569,0x5deb5a50), + LL(0xd5eea89e,0xd5959d46),LL(0x08437f4b,0xfdff8424),LL(0x3cfe254f,0xf21071e4),LL(0x95468321,0x72417696), LL(0x102cae3e,0x5d8288b9),LL(0xf1965dff,0x2d143e3d),LL(0xa078d847,0x00c9a376),LL(0x26028731,0x6fc0da31), + LL(0xe45083a2,0xa2baeadf),LL(0x5e5b4bcd,0x66bc7218),LL(0xd04b8e7f,0x2c826442),LL(0x6c4b586b,0xc19f5451), LL(0x5b7eeed5,0x60182c49),LL(0x7aa9dfa1,0xd9954ecd),LL(0xc73884ad,0xa403a8ec),LL(0x9bb39041,0x7fb17de2), + LL(0xabb020e8,0x694b64c5),LL(0x19c4eec7,0x3d18c184),LL(0x1c4793e5,0x9c4673ef),LL(0x056092e6,0xc7b8aeb5), LL(0xf0f8c16b,0x3aa1ca43),LL(0xd679b2f6,0x224ed5ec),LL(0x55a205c9,0x0d56eeaf),LL(0x4b8e028b,0xbfe115ba), + LL(0x3927f4fe,0x97e60849),LL(0x759aa7c5,0xf91fbf94),LL(0x6be90a51,0x985af769),LL(0x78ccb823,0xc1277b78), LL(0xe7a75952,0x395b656e),LL(0x928da5f5,0x00df7de0),LL(0x4ca4454f,0x09c23175),LL(0x7aa2d3c1,0x4ec971f4), + LL(0xe75d9ccc,0x45c3c507),LL(0x3dc90306,0x63b7be8a),LL(0x5db44bdc,0x37e09c66),LL(0x6841c6a2,0x50d60da1), LL(0x08df1b12,0x6f9b65ee),LL(0x7ff089df,0x38734879),LL(0x3fe8013d,0x9c331a66),LL(0x5f42fcc8,0x017f5de9), + LL(0xe8e57567,0x43077866),LL(0xf9fcdb18,0xc9f781ce),LL(0x9b12e174,0x38131dda),LL(0x8a03752a,0x25d84aa3), LL(0x4d0c0ce2,0x45e09e09),LL(0x92bebba5,0x1564008b),LL(0xa87284c7,0xf7e8ad31),LL(0x97e7bbaa,0xb7c4b46c), + LL(0x97acf4ec,0x3e22a7b3),LL(0x5ea8b640,0x0426c400),LL(0x4e969285,0x5e3295a6),LL(0xa6a45670,0x22aabc59), LL(0x5f5942bc,0xb929714c),LL(0xfa3182ed,0x9a6168bd),LL(0x104152ba,0x2216a665),LL(0xb6926368,0x46908d03), +}, +/* digit=11 base_pwr=2^77 */ +{ + LL(0x5a1251fb,0xa9f5d874),LL(0xc72725c7,0x967747a8),LL(0x31ffe89e,0x195c33e5),LL(0xe964935e,0x609d210f), LL(0x2fe12227,0xcafd6ca8),LL(0x0426469d,0xaf9b5b96),LL(0x5693183c,0x2e9ee04c),LL(0xc8146fef,0x1084a333), + LL(0xaed1d1f7,0x96649933),LL(0x50563090,0x566eaff3),LL(0xad2e39cf,0x345057f0),LL(0x1f832124,0x148ff65b), LL(0xcf94cf0d,0x042e89d4),LL(0x520c58b3,0x319bec84),LL(0x5361aa0d,0x2a267626),LL(0x8fbc87ad,0xc86fa302), + LL(0x5c8b06d5,0xfc83d2ab),LL(0xfe4eac46,0xb1a785a2),LL(0x846f7779,0xb99315bc),LL(0xef9ea505,0xcf31d816), LL(0x15d7dc85,0x2391fe6a),LL(0xb4016b33,0x2f132b04),LL(0x181cb4c7,0x29547fe3),LL(0x650155a1,0xdb66d8a6), + LL(0xadc1696f,0x6b66d7e1),LL(0x0acd72d0,0x98ebe593),LL(0xcc1b7435,0x65f24550),LL(0xb4b9a5ec,0xce231393), LL(0xdb067df9,0x234a22d4),LL(0xcaff9b00,0x98dda095),LL(0x6100c9c1,0x1bbc75a0),LL(0x939cf695,0x1560a9c8), + LL(0x99e0925f,0xcf006d3e),LL(0x6322375a,0x2dd74a96),LL(0xb56af5ba,0xc58b446a),LL(0xe0b9b4f1,0x50292683), LL(0x1aeaffa3,0xe2c34cb4),LL(0x9b9587c1,0x8b17203f),LL(0xead1350c,0x6d559207),LL(0xfb7f9604,0x2b66a215), + LL(0xfe51bf74,0x0850325e),LL(0x5e460094,0x9c4f579e),LL(0x76da2f25,0x5c87b92a),LL(0x6febef33,0x889de4e0), LL(0x646083ce,0x6900ec06),LL(0xbfe12773,0xbe2a0335),LL(0xc5344110,0xadd1da35),LL(0xb802cd20,0x757568b7), + LL(0x00f7e6c8,0x75559779),LL(0x0facd2f0,0x38e8b94f),LL(0x03fde375,0xfea1f3af),LL(0x75881dfc,0x5e11a1d8), LL(0xc1e2f2ef,0xb3a6b02e),LL(0xc605a6c5,0x193d2bbb),LL(0x339a0b2d,0x325ffeee),LL(0x9e0c8846,0x27b6a724), + LL(0xf1c367ca,0xe4050f1c),LL(0xc90fbc7d,0x9bc85a9b),LL(0xe1a11032,0xa373c4a2),LL(0xad0393a9,0xb64232b7), LL(0x167dad29,0xf5577eb0),LL(0x94b78ab2,0x1604f301),LL(0xe829348b,0x0baa94af),LL(0x41654342,0x77fbd8dd), + LL(0xb964e39a,0xdab50ea5),LL(0xd0d3c76e,0xd4c29e3c),LL(0x56d11964,0x80dae67c),LL(0xe5ffcc2f,0x7307a8bf), LL(0x91708c3b,0x65bbc1aa),LL(0x28bf0eeb,0xa151e62c),LL(0x6fa34db7,0x6cb53381),LL(0xa29403a8,0x5139e05c), + LL(0x94a7cd2e,0x6ff651b4),LL(0x0699336c,0x5671ffd1),LL(0x979a896a,0x6f5fd2cc),LL(0xd8148cef,0x11e893a8), LL(0x65cf7b10,0x988906a1),LL(0xc50d8485,0x81b67178),LL(0x8a35b3de,0x7c0deb35),LL(0xc1d29799,0x423ac855), + LL(0xdac50b74,0xaf580d87),LL(0x5869734c,0x28b2b89f),LL(0x874e28fb,0x99a3b936),LL(0x25f3f73a,0xbb2c9190), LL(0x84a9d5b7,0x199f6918),LL(0x7e770374,0x7ebe2325),LL(0x0738efe2,0xf442e107),LL(0xcf9082d2,0xcf9f3f56), + LL(0x09618708,0x719f69e1),LL(0xc183f9b1,0xcc9e8364),LL(0x366a21af,0xec203a95),LL(0x068b141f,0x6aec5d6d), LL(0x994f04e9,0xee2df78a),LL(0x271245b0,0xb39ccae8),LL(0x97e43f4f,0xb875a4a9),LL(0xdb2cea98,0x507dfe11), + LL(0x489b03e9,0x4fbf81cb),LL(0x6ec414fa,0xdb86ec5b),LL(0xf51b3ae5,0xfad444f9),LL(0x1914e3fe,0xca7d33d6), LL(0x0ae6c4d0,0xa9c32f5c),LL(0x73969568,0xa9ca1d1e),LL(0x1aa7467e,0x98043c31),LL(0xe21b5ac6,0xe832e75c), + LL(0x5232123d,0x314b7aea),LL(0x65ae86db,0x08307c8c),LL(0xaa4668ed,0x06e7165c),LL(0xb4d3ec39,0xb170458b), LL(0xc19bb986,0x4d2e3ec6),LL(0xae0304ed,0xc5f34846),LL(0x6c9f9722,0x917695a0),LL(0x4cab1c0a,0x6c7f7317), + LL(0x9d6d2e8b,0x6295940e),LL(0x549f7c97,0xd318b8c1),LL(0x97713885,0x22453204),LL(0xa8a440fe,0x468d834b), LL(0xbfba796e,0xd81fe5b2),LL(0x6d71f116,0x152364db),LL(0xb5b66e53,0xbb8c7c59),LL(0x2641a192,0x0b12c61b), + LL(0xfcf0a7fd,0x31f14802),LL(0x5488b01e,0x42fd0789),LL(0x9952b498,0x71d78d6d),LL(0x07ac5201,0x8eb572d9), LL(0x4d194a88,0xe0a2a44c),LL(0xba017e66,0xd2b63fd9),LL(0xf888aefc,0x78efc6c8),LL(0x4a881a11,0xb76f6bda), + LL(0xb46c2397,0x187f314b),LL(0x5ded2819,0x004cf566),LL(0x38764d34,0xa9ea5704),LL(0x78084709,0xbba45217), LL(0x1171121e,0x06474571),LL(0xe7c9b671,0xad7b7eb1),LL(0x730f7507,0xdacfbc40),LL(0xc7ad7bd1,0x178cd8c6), + LL(0xb2a67238,0xbf0be101),LL(0xaf9c14f2,0x3556d367),LL(0xa5662075,0x104b7831),LL(0x79d9e60a,0x58ca59bb), LL(0xa569a73b,0x4bc45392),LL(0x5698f6c9,0x517a52e8),LL(0xaeadd755,0x85643da5),LL(0x2a581b84,0x1aed0cd5), + LL(0x80af1372,0xb9b4ff84),LL(0xf1ba5d1f,0x244c3113),LL(0xf5f98d31,0x2a5dacbe),LL(0x4375bc2a,0x2c3323e8), LL(0x5594b1dd,0x17a3ab4a),LL(0xceb4797e,0xa1928bfb),LL(0xe4886a19,0xe83af245),LL(0x72b5a74a,0x8979d546), + LL(0x19f9e967,0xa0f726bc),LL(0xe8fbbf4e,0xd9d03152),LL(0xb7707d40,0xcfd6f51d),LL(0x63f6e6e0,0x633084d9), LL(0x55667eaf,0xedcd9cdc),LL(0x2e44d56f,0x73b7f92b),LL(0x4e962b14,0xfb2e39b6),LL(0xf671fcbf,0x7d408f6e), + LL(0x164a89bb,0xcc634ddc),LL(0x3ef3bd05,0x74a42bb2),LL(0x428decbb,0x1280dbb2),LL(0x402c8596,0x6103f6bb), LL(0x355a5752,0xfa2bf581),LL(0x00946674,0x562f96a8),LL(0x6da0223b,0x4e4ca16d),LL(0x28d3aa25,0xfe47819f), + LL(0xf8dfcf8a,0x9eea3075),LL(0x95669825,0xa284f0aa),LL(0x867d3fd8,0xb3fca250),LL(0x269d691e,0x20757b5f), LL(0x93b8a5de,0xf2c24020),LL(0xebc06da6,0xd3f93359),LL(0xb2739c33,0x1178293e),LL(0xbcd686e5,0xd2a3e770), + LL(0xcd941534,0xa76f49f4),LL(0xe3c71c0e,0x0d37406b),LL(0x3b97f7e3,0x172d9397),LL(0xbd7fd0de,0xec17e239), LL(0x6f496ba2,0xe3290551),LL(0x36ad50e7,0x6a693172),LL(0x83e7eff5,0xc4e539a2),LL(0x18e1b4cf,0x752737e7), + LL(0x68af43ee,0xa2f7932c),LL(0x703d00bd,0x5502468e),LL(0x2fb061f5,0xe5dc978f),LL(0x28c815ad,0xc9a1904a), LL(0x470c56a4,0xd3af538d),LL(0x193d8ced,0x159abc5f),LL(0x20108ef3,0x2a37245f),LL(0x223f7178,0xfa17081e), + LL(0x10c8c0f5,0x27b0fb2b),LL(0x40650547,0x2102c3ea),LL(0x8ac3bfa7,0x594564df),LL(0x509dad96,0x98102033), LL(0xf1d18a13,0x6989643f),LL(0xd7fc5af0,0x35eebd91),LL(0xfaeaafd8,0x078d096a),LL(0xdef3de98,0xb7a89341), + LL(0xecf2a73a,0x2a206e8d),LL(0x8e551994,0x066a6397),LL(0xb98d53a2,0x3a6a088a),LL(0x2d1124aa,0x0ce7c67c), LL(0x759a113c,0x48cec671),LL(0x4f6f67fa,0xe3b373d3),LL(0xfd36727b,0x5455d479),LL(0xa13c0d81,0xe5a428ee), + LL(0x1c86682b,0xb853dbc8),LL(0xb8d02b2a,0xb78d2727),LL(0x8ebc329a,0xaaf69bed),LL(0x293b2148,0xdb6b40b3), LL(0xb8c4961f,0xe42ea77d),LL(0x20e5e0ab,0xb1a12f7c),LL(0x79e8b05e,0xa0ec5274),LL(0xfab60a80,0x68027391), + LL(0x16b1bd5e,0x6bfeea5f),LL(0x4de30ad3,0xf957e420),LL(0x6a353b9e,0xcbaf664e),LL(0x26d14feb,0x5c873312), LL(0xb65f57cb,0x4e87f98c),LL(0x5e0cdd41,0xdb60a621),LL(0xa6881440,0x67c16865),LL(0x46ab52aa,0x1093ef1a), + LL(0x3f4ece64,0xc095afb5),LL(0x7604551a,0x6a6bb02e),LL(0x0b26b8cd,0x55d44b4e),LL(0xf971268a,0xe5f9a999), LL(0x11a7de84,0xc08ec425),LL(0xfda469dd,0x83568095),LL(0x6c6c90a2,0x737bfba1),LL(0xbe229831,0x1cb9c4a0), + LL(0xbb2eec64,0x93bccbba),LL(0xda03adbe,0xa0c23b64),LL(0xe0e86ac4,0x5f7aa00a),LL(0xfc1401e6,0x470b941e), LL(0x9df43574,0x5ad8d679),LL(0x0f65d810,0x4ccfb8a9),LL(0xaa7fbd81,0x1bce80e3),LL(0x9508d20a,0x273291ad), + LL(0x42a92806,0xf5c4b46b),LL(0xa86ab44a,0x810684ec),LL(0xca0bc9f8,0x4591640b),LL(0x5c4b6054,0xb5efcdfc), LL(0x6e9edd12,0x16fc8907),LL(0xd4d792f9,0xe29d0b50),LL(0x9b03116d,0xa45fd01c),LL(0xc81765a4,0x85035235), + LL(0xb4b4b67c,0x1fe2a9b2),LL(0xe8020604,0xc1d10df0),LL(0xbc8058d8,0x9d64abfc),LL(0x712a0fbb,0x8943b9b2), LL(0x3b3def04,0x90eed914),LL(0x4ce775ff,0x85ab3aa2),LL(0x7bbc9040,0x605fd4ca),LL(0xe2c75dfb,0x8b34a564), + LL(0x10358560,0x41ffc94a),LL(0x9e5c28aa,0x2d8a5072),LL(0x4cc7eb15,0xe915a0fc),LL(0x8f6d0f5d,0xe9efab05), LL(0xd19e9b91,0xdbab47a9),LL(0x0276154c,0x8cfed745),LL(0x2cfede0d,0x154357ae),LL(0x19f5a4ef,0x520630df), + LL(0xe382360f,0x25759f7c),LL(0x88bf5857,0xb6db05c9),LL(0x6c58d46c,0x2917d61d),LL(0xfd20cb7a,0x14f8e491), LL(0x11c20340,0xb68a727a),LL(0xaf7ccbb6,0x0386f86f),LL(0xfee09a20,0x5c8bc6cc),LL(0xbb7eea35,0x7d76ff4a), + LL(0xdb15be7a,0xa7bdebe7),LL(0xd89f0302,0x67a08054),LL(0xc1193364,0x56bf0ea9),LL(0x62837ebe,0xc8244467), LL(0x20d841b8,0x32bd8e8b),LL(0xdbb8a54f,0x127a0548),LL(0x63b20236,0x83dd4ca6),LL(0x203491fa,0x87714718), + LL(0xaa8a5288,0x4dabcaaa),LL(0xaf23a1c9,0x91cc0c8a),LL(0x3f220e0c,0x34c72c6a),LL(0x1232144a,0xbcc20bdf), LL(0xa20ede1b,0x6e2f42da),LL(0x74a00515,0xc441f00c),LL(0x734b8c4b,0xbf46a5b6),LL(0x7b56c9a4,0x57409503), + LL(0xe4585d45,0x9f735261),LL(0x6734e642,0x9231faed),LL(0xbe70ee6c,0x1158a176),LL(0x7c3501bf,0x35f1068d), LL(0xa2d26115,0x6beef900),LL(0xef0afee3,0x649406f2),LL(0xbc2420a1,0x3f43a60a),LL(0xd5aee4ac,0x509002a7), + LL(0x3ff3571b,0xb46836a5),LL(0x837927c1,0x24f98b78),LL(0x4533c716,0x6254256a),LL(0xd07ee196,0xf27abb0b), LL(0x5c6d5bfd,0xd7cf64fc),LL(0xf0cd7a77,0x6915c751),LL(0x8798f534,0xd9f59012),LL(0xf81d8b5f,0x772b0da8), + LL(0x2e03fa69,0x1244260c),LL(0x3be1a374,0x36cf0e3a),LL(0xef06b960,0x6e7c1633),LL(0x671f90f6,0xa71a4c55), LL(0x33c673db,0x7a941251),LL(0x73e8c131,0xc0bea510),LL(0xd4f6c734,0x61a8a699),LL(0x341ed001,0x25e78c88), + LL(0x8e2f7d90,0x5c18acf8),LL(0x77be32cd,0xfdbf33d7),LL(0xd2eb5ee9,0x0a085cd7),LL(0xb3201115,0x2d702cfb), LL(0x85c88ce8,0xb6e0ebdb),LL(0x1e01d617,0x23a3ce3c),LL(0x567333ac,0x3041618e),LL(0x157edb6b,0x9dd0fd8f), + LL(0xb57872b8,0x27f74702),LL(0x657d5fe1,0x2ef26b4f),LL(0x57cf3d40,0x95426f0a),LL(0x65a6067a,0x847e2ad1), LL(0x09996a74,0xd474d9a0),LL(0x2a26115c,0x16a56acd),LL(0xd16f4d43,0x02a615c3),LL(0xaadb85b7,0xcc3fc965), + LL(0xce07d1b0,0x386bda73),LL(0x58ad4178,0xd82910c2),LL(0xcd2617f4,0x124f82cf),LL(0xef691770,0xcc2f5e8d), LL(0xb8c30ccc,0x82702550),LL(0x1a8e575a,0x7b856aea),LL(0xb1ab9459,0xbb822fef),LL(0xec24e38e,0x085928bc), + LL(0xba8f4b4d,0x5d0402ec),LL(0x00b4d58b,0xc07cd4ba),LL(0x29227e7a,0x5d8dffd5),LL(0x31bf386f,0x61d44d0c), LL(0x135e6f4d,0xe486dc2b),LL(0xe79410ef,0x680962eb),LL(0xf10088b5,0xa61bd343),LL(0xe2e28686,0x6aa76076), + LL(0x8fb98871,0x80463d11),LL(0xbbc76aff,0xcb26f5c3),LL(0xfbe03614,0xd4ab8edd),LL(0xc0cf2dee,0xc8eb579b), LL(0xc93bae41,0xcc004c15),LL(0x3aeca3b2,0x46fbae5d),LL(0x0f1e9ab1,0x671235cf),LL(0x9ec285c1,0xadfba934), + LL(0xf216c980,0x88ded013),LL(0xf79e0bc1,0xc8ac4fb8),LL(0xfb97a237,0xa29b89c6),LL(0x9922d8e7,0xb697b780), LL(0xddb945b5,0x3142c639),LL(0xe094c3a9,0x447b06c7),LL(0x72266c90,0xcdcb3642),LL(0xa9385046,0x633aad08), + LL(0xb57c6477,0xa36c936b),LL(0xe94dbcc6,0x871f8b64),LL(0xa591a67b,0x28d0fb62),LL(0xc1d926f5,0x9d40e081), LL(0xf2d84b5a,0x3111eaf6),LL(0xa565b644,0x228993f9),LL(0x2c83188b,0x0ccbf592),LL(0x3df3e197,0xf87b30ab), + LL(0x7642bca8,0xb8658b31),LL(0x52800f17,0x1a032d7f),LL(0x79bf9445,0x051dcae5),LL(0x54a2e253,0xeba6b8ee), LL(0xd4485692,0x5c8b9cad),LL(0x8986e9be,0x84bda40e),LL(0x2f0db448,0xd16d16a4),LL(0xa14d4188,0x8ec80050), + LL(0x98fa7aaa,0xb2b26107),LL(0xf073aa4e,0x41209ee4),LL(0xf2d6b19b,0xf1570359),LL(0xfc577caf,0xcbe6868c), LL(0x32c04dd3,0x186c4bdc),LL(0xcfeee397,0xa6c35fae),LL(0xf086c0cf,0xb4a1b312),LL(0xd9461fe2,0xe0a5ccc6), + LL(0x1536189f,0xc32278aa),LL(0xba6df571,0x1126c55f),LL(0xb194560e,0x0f71a602),LL(0x324bd6e1,0x8b2d7405), LL(0x3738be71,0x8481939e),LL(0x1a4d97a9,0xb5090b1a),LL(0xf05ba915,0x116c65a3),LL(0xaae448aa,0x21863ad3), + LL(0xa7aae5d3,0xd24e2679),LL(0x0de5c1c4,0x7076013d),LL(0xbb05b629,0x2d50f8ba),LL(0x6e66efbb,0x73c1abe2), LL(0xf2488af7,0xefd4b422),LL(0x663ba575,0xe4105d02),LL(0x53a69457,0x7eb60a8b),LL(0xc945973b,0x62210008), + LL(0x77a50ec6,0xfb255478),LL(0x0a37a72c,0xbf0392f7),LL(0x4be18e7a,0xa0a7a19c),LL(0x25b1e0af,0x90d8ea16), LL(0xef953f57,0x7582a293),LL(0xbdc5465a,0x90a64d05),LL(0xe2510717,0xca79c497),LL(0x18cb641f,0x560dbb7c), + LL(0x4b66abfb,0x1d8e3286),LL(0x59030900,0xd26f52e5),LL(0x5584941a,0x1ee3f643),LL(0x569f5958,0x6d3b3730), LL(0x4789dba5,0x9ff2a62f),LL(0x72b5c9b7,0x91fcb815),LL(0x6c8f9a0e,0xf446cb7d),LL(0x39b7ecb5,0x48f625c1), + LL(0x1c6219b8,0xbabae801),LL(0x28ac2f23,0xe7a562d9),LL(0x26e20588,0xe1b48732),LL(0x775af051,0x06ee1cad), LL(0xfaff79f7,0xda29ae43),LL(0x652ee9e0,0xc141a412),LL(0x195f4bd0,0x1e127f6f),LL(0x072f34f8,0x29c6ab4f), + LL(0x30448112,0x7b7c1477),LL(0xe4a38656,0x82b51af1),LL(0x2f315010,0x2bf2028a),LL(0x6ea88cd4,0xc9a4a01f), LL(0x257e5818,0xf63e95d8),LL(0xb4519b16,0xdd8efa10),LL(0x0da910bf,0xed8973e0),LL(0x5c0fe4a9,0xed49d077), + LL(0xb7caee1e,0xac3aac5e),LL(0xa7f4da57,0x1033898d),LL(0x5c6669b9,0x42145c0e),LL(0xc1aa2aa0,0x42daa688), LL(0x1a1d885a,0x629cc15c),LL(0xf4b76817,0x25572ec0),LL(0x9c8f8f28,0x8312e435),LL(0x81965490,0x8107f8cd), + LL(0x6fa6110c,0x516ff3a3),LL(0xfb93561f,0x74fb1eb1),LL(0x8457522b,0x6c0c9047),LL(0x6bb8bdc6,0xcfd32104), LL(0xcc80ad57,0x2d6884a2),LL(0x86a9b637,0x7c27fc35),LL(0xadf4e8cd,0x3461baed),LL(0x617242f0,0x1d56251a), + LL(0xc955bef4,0x0b80d209),LL(0x06adb047,0xdf02cad2),LL(0x5ec74fee,0xf0d7cb91),LL(0x1111ba44,0xd2503375), LL(0xdf53cb36,0x9671755e),LL(0x3368551b,0x54dcb612),LL(0xc8a025a4,0x66d69aac),LL(0xe77ef445,0x6be946c6), + LL(0xa995e094,0x719946d1),LL(0xe51e04d8,0x65e848f6),LL(0x6a1e3113,0xe62f3300),LL(0x501de503,0x1541c7c1), LL(0xf4acfade,0x4daac9fa),LL(0x44cd0b71,0x0e585897),LL(0x0a51cd77,0x544fd869),LL(0x0031016d,0x60fc20ed), + LL(0xa4276867,0x58b404ec),LL(0x34f34993,0x46f6c3cc),LL(0xc636e5bd,0x477ca007),LL(0x7c458b47,0x8018f5e5), LL(0xe47b668f,0xa1202270),LL(0xee14f203,0xcef48ccd),LL(0x62ff9b4d,0x23f98bae),LL(0xc589eddd,0x55acc035), + LL(0x64db4444,0x3fe712af),LL(0xbecdd480,0x19e9d634),LL(0xa930978a,0xe08bc047),LL(0xa1280733,0x2dbf24ec), LL(0x2cd706b2,0x3c0ae38c),LL(0x359017b9,0x5b012a5b),LL(0x72e0f5ae,0x3943c38c),LL(0x57176fa3,0x786167ea), + LL(0x594881dc,0xe5f9897d),LL(0xcfb820c1,0x6b5efad8),LL(0xd55018de,0xb2179093),LL(0x0bac56ce,0x39ad7d32), LL(0x2cfc0e81,0xb55122e0),LL(0xf6d89daa,0x117c4661),LL(0xcb64fa09,0x362d01e1),LL(0x3e9c4ddd,0x6a309b4e), + LL(0xabea49b1,0xfa979fb7),LL(0x10e2c6c5,0xb4b1d27d),LL(0x23afde7a,0xbd61c2c4),LL(0x9786d358,0xeb6614f8), LL(0x7f6f7459,0x4a5d816b),LL(0x09360e7b,0xe431a44f),LL(0xc309914c,0x8c27a032),LL(0xcaede3d8,0xcea5d68a), + LL(0x3a0a3f95,0x3668f665),LL(0x7ceba27b,0x89369416),LL(0xe4728fe9,0x89981fad),LL(0x8a093562,0x7102c8a0), LL(0x235d21c8,0xbb80310e),LL(0xbefb7f7b,0x505e55d1),LL(0x12958a67,0xa0a90811),LL(0x4d851fef,0xd67e106a), + LL(0x431dd80e,0xb84011a9),LL(0x73306cd9,0xeb7c7cca),LL(0xd1b3b730,0x20fadd29),LL(0xfe37b3d3,0x83858b5b), LL(0xb6251d5c,0xbf4cd193),LL(0x1352d952,0x1cca1fd3),LL(0x90fbc051,0xc66157a4),LL(0x89b98636,0x7990a638), +}, +/* digit=12 base_pwr=2^84 */ +{ + LL(0x87dec0e1,0xe5aa692a),LL(0xf7b39d00,0x010ded8d),LL(0x54cfa0b5,0x7b1b80c8),LL(0xa0f8ea28,0x66beb876), LL(0x3476cd0e,0x50d7f531),LL(0xb08d3949,0xa63d0e65),LL(0x53479fc6,0x1a09eea9),LL(0xf499e742,0x82ae9891), + LL(0x5ca7d866,0xab58b910),LL(0x3adb3b34,0x582967e2),LL(0xcceac0bc,0x89ae4447),LL(0x7bf56af5,0x919c667c), LL(0x60f5dcd7,0x9aec17b1),LL(0xddcaadbc,0xec697b9f),LL(0x463467f5,0x0b98f341),LL(0xa967132f,0xb187f1f7), + LL(0x214aeb18,0x90fe7a1d),LL(0x741432f7,0x1506af3c),LL(0xe591a0c4,0xbb5565f9),LL(0xb44f1bc3,0x10d41a77), LL(0xa84bde96,0xa09d65e4),LL(0xf20a6a1c,0x42f060d8),LL(0xf27f9ce7,0x652a3bfd),LL(0x3b3d739f,0xb6bdb65c), + LL(0xec7fae9f,0xeb5ddcb6),LL(0xefb66e5a,0x995f2714),LL(0x69445d52,0xdee95d8e),LL(0x09e27620,0x1b6c2d46), LL(0x8129d716,0x32621c31),LL(0x0958c1aa,0xb03909f1),LL(0x1af4af63,0x8c468ef9),LL(0xfba5cdf6,0x162c429f), + LL(0x753b9371,0x2f682343),LL(0x5f1f9cd7,0x29cab45a),LL(0xb245db96,0x571623ab),LL(0x3fd79999,0xc507db09), LL(0xaf036c32,0x4e2ef652),LL(0x05018e5c,0x86f0cc78),LL(0xab8be350,0xc10a73d4),LL(0x7e826327,0x6519b397), + LL(0x9c053df7,0xe8cb5eef),LL(0xb300ea6f,0x8de25b37),LL(0xc849cffb,0xdb03fa92),LL(0xe84169bb,0x242e43a7), LL(0xdd6f958e,0xe4fa51f4),LL(0xf4445a8d,0x6925a77f),LL(0xe90d8949,0xe6e72a50),LL(0x2b1f6390,0xc66648e3), + LL(0x173e460c,0xb2ab1957),LL(0x30704590,0x1bbbce75),LL(0xdb1c7162,0xc0a90dbd),LL(0x15cdd65d,0x505e399e), LL(0x57797ab7,0x68434dcb),LL(0x6a2ca8e8,0x60ad35ba),LL(0xde3336c1,0x4bfdb1e0),LL(0xd8b39015,0xbbef99eb), + LL(0x1711ebec,0x6c3b96f3),LL(0xce98fdc4,0x2da40f1f),LL(0x57b4411f,0xb99774d3),LL(0x15b65bb6,0x87c8bdf4), LL(0xc2eef12d,0xda3a89e3),LL(0x3c7471f3,0xde95bb9b),LL(0xd812c594,0x600f225b),LL(0x2b75a56b,0x54907c5d), + LL(0x8db60e35,0xa93cc5f0),LL(0xfa833319,0x743e3cd6),LL(0xf81683c9,0x7dad5c41),LL(0x9c34107e,0x70c1e7d9), LL(0xa6be0907,0x0edc4a39),LL(0x86d0b7d3,0x36d47035),LL(0x272bfa60,0x8c76da03),LL(0x0f08a414,0x0b4a07ea), + LL(0x45c1dd53,0x699e4d29),LL(0x231debb5,0xcadc5898),LL(0xa77f00e0,0xdf49fcc7),LL(0xa73e5a0e,0x93057bbf), LL(0x027a4cd1,0x2f8b7ecd),LL(0xc614011a,0x114734b3),LL(0x67677c68,0xe7a01db7),LL(0x7e273f4f,0x89d9be5e), + LL(0x089808ef,0xd225cb2e),LL(0xd59e4107,0xf1f7a27d),LL(0x8211b9c9,0x53afc761),LL(0xe6819159,0x0361bc67), LL(0x7f071426,0x2a865d0b),LL(0xe7072567,0x6a3c1810),LL(0x0d6bcabd,0x3e3bca1e),LL(0x408591bc,0xa1b02bc1), + LL(0x31fba239,0xe0deee59),LL(0x98bd91d1,0xf47424d3),LL(0x071a3c1d,0x0f8886f4),LL(0xa819233b,0x3f7d41e8), LL(0xcf6eb998,0x708623c2),LL(0x609a287f,0x86bb49af),LL(0x63c90762,0x942bb249),LL(0x55a9654b,0x0ef6eea5), + LL(0x36f5defe,0x5f6d2d72),LL(0x56f99176,0xfa9922dc),LL(0xf78ce0c7,0x6c8c5ece),LL(0xbe09b55e,0x7b44589d), LL(0x9ea83770,0xe11b3bca),LL(0x2ab71547,0xd7fa2c7f),LL(0x2a1ddcc0,0x2a3dd6fa),LL(0x5a7b7707,0x09acb430), + LL(0x649d4e57,0x4add4a2e),LL(0x1917526e,0xcd53a2b0),LL(0x20b44ac4,0xc5262330),LL(0xbaa2c31d,0x4028746a), LL(0x64291d4c,0x51318390),LL(0xee5ad909,0xbf48f151),LL(0x7b185681,0xcce57f59),LL(0x4854d442,0x7c3ac1b0), + LL(0xc093c171,0x65587dc3),LL(0x24f42b65,0xae7acb24),LL(0x955996cb,0x5a338adb),LL(0x6051f91b,0xc8e65675), LL(0x28b8d0b1,0x66711fba),LL(0xb6c10a90,0x15d74137),LL(0x3a232a80,0x70cdd7eb),LL(0x6191ed24,0xc9e2f07f), + LL(0xf79588c0,0xa80d1db6),LL(0xb55768cc,0xfa52fc69),LL(0x7f54438a,0x0b4df1ae),LL(0xf9b46a4f,0x0cadd1a7), LL(0x1803dd6f,0xb40ea6b3),LL(0x55eaae35,0x488e4fa5),LL(0x382e4e16,0x9f047d55),LL(0x2f6e0c98,0xc9b5b7e0), + LL(0x95762649,0x6b1bd2d3),LL(0xc7aea3f6,0xa9604ee7),LL(0x6dc6f896,0x3646ff27),LL(0x2860bad1,0x9bf0e7f5), LL(0x7cb44b92,0x2d92c821),LL(0xaea9c182,0xa2f5ce63),LL(0x9154a5fd,0xd0a2afb1),LL(0x95801da6,0x482e474c), + LL(0xb611c24b,0xc19972d0),LL(0x60a8f351,0x1d468e65),LL(0x7bcf6421,0xeb758069),LL(0x88fbc491,0xec9dd0ee), LL(0x956c2e32,0x5b59d2bf),LL(0xdcddf94e,0x73dc6864),LL(0xbcee7665,0xfd5e2321),LL(0x5e9a06c4,0xa7b4f8ef), + LL(0x7280f855,0xfba918dd),LL(0x8baec688,0xbbaac260),LL(0x33400f42,0xa3b3f00f),LL(0x66f2e6e4,0x3d2dba29), LL(0x98509375,0xb6f71a94),LL(0xcea423cc,0x8f33031f),LL(0x4807e6fb,0x009b8dd0),LL(0x5cdb954c,0x5163cfe5), + LL(0xcf41c6e8,0x03cc8f17),LL(0x037b925c,0xf1f03c2a),LL(0x66d2427c,0xc39c19cc),LL(0x7b6c18e4,0x823d24ba), LL(0x901f0b4f,0x32ef9013),LL(0xf8941c2e,0x684360f1),LL(0x2c28092e,0x0ebaff52),LL(0x256c932f,0x7891e4e3), + LL(0xac445e3d,0x51264319),LL(0x8ea74381,0x553432e7),LL(0x67e9c50a,0xe6eeaa69),LL(0x62e628c7,0x27ced284), LL(0x7a4afa57,0x3f96d375),LL(0xe484c150,0xde0a14c3),LL(0x38bd9923,0x364a24eb),LL(0xe5177422,0x1df18da0), + LL(0xd8d38a9b,0x174e8f82),LL(0xe7de1391,0x2e97c600),LL(0xa1c175dd,0xc5709850),LL(0x32ae5035,0x969041a0), LL(0x76a2086b,0xcbfd533b),LL(0xd7c2e8fe,0xd6bba71b),LL(0x099dfb67,0xb2d58ee6),LL(0x064a85d9,0x3a8b342d), + LL(0x522f9be3,0x3bc07649),LL(0xdf1f49a8,0x690c075b),LL(0x3854ec42,0x80e1aee8),LL(0x17689dc7,0x2a7dbf44), LL(0x3faf4078,0xc004fc0e),LL(0xdf11862c,0xb2f02e9e),LL(0xa0a1b7b3,0xf10a5e0f),LL(0x8936ec80,0x30aca623), + LL(0x02f40d9a,0xf83cbf05),LL(0x2c318a4d,0x4681c468),LL(0x0e9c2674,0x98575618),LL(0x1847092e,0xbe79d046), LL(0x78bd01e0,0xaf1e480a),LL(0x72a51db9,0x6dd359e4),LL(0xe3afbab6,0x62ce3821),LL(0x17733199,0xc5cee5b6), + LL(0x6ffd9fbb,0xe08b30d4),LL(0x36c610b7,0x6e5bc699),LL(0x9ce262cf,0xf343cff2),LL(0x68b914c1,0xca2e4e35), LL(0x16de36c5,0x011d64c0),LL(0x42e2b829,0xe0b10fdd),LL(0x6685aaf8,0x78942981),LL(0x230ede97,0xe7511708), + LL(0x3b922bf8,0x671ed8fc),LL(0x4c29b133,0xe4d8c0a0),LL(0x3b6e99c4,0x87eb1239),LL(0x8793beba,0xaff3974c), LL(0x2c18df9b,0x03749405),LL(0x91007139,0xc5c3a293),LL(0xe37a0b95,0x6a77234f),LL(0xb661c96b,0x02c29a21), + LL(0x141ecf61,0xc3aaf1d6),LL(0x3bb22f53,0x9195509e),LL(0x22d51357,0x29597404),LL(0x537bed60,0x1b083822), LL(0xe07289f0,0xcd7d6e35),LL(0x6dd86eff,0x1f94c48c),LL(0xeb0f9cfa,0xc8bb1f82),LL(0x1b2eb97d,0x9ee0b7e6), + LL(0x34d74e31,0x5a52fe2e),LL(0x3bf79ab6,0xa352c310),LL(0xabfeeb8f,0x97ff6c5a),LL(0xf5c97305,0xbfbe8fef), LL(0xa7904608,0xd6081ce6),LL(0xc4fca249,0x1f812f3a),LL(0xb9e5e200,0x9b24bc9a),LL(0x38012ee8,0x91022c67), + LL(0x30a713a1,0xe83d9c5d),LL(0x84ef0f93,0x4876e3f0),LL(0xc1fbf928,0xc9777029),LL(0xbce7d2a4,0xef7a6bb3), LL(0xdfa2a659,0xb8067228),LL(0xd877a48f,0xd5cd3398),LL(0x025d0f3f,0xbea4fd8f),LL(0x2eae7c2b,0xd67d2e35), + LL(0xcc5f4394,0x184de7d7),LL(0x4536e142,0xb5551b5c),LL(0xd34aa60a,0x2e89b212),LL(0xf50051d5,0x14a96fea), LL(0x0d12bb0b,0x4e21ef74),LL(0x60b9677e,0xc522f020),LL(0x2df7731d,0x8b12e467),LL(0x7b326d31,0x39f80382), + LL(0x39024a94,0xdfb8630c),LL(0x97319452,0xaacb96a8),LL(0xeda3867c,0xd68a3961),LL(0x77c4ffca,0x0c58e2b0), LL(0x4da919fa,0x3d545d63),LL(0xf15e2289,0xef79b69a),LL(0x808bab10,0x54bc3d3d),LL(0x45f82c37,0xc8ab3007), + LL(0x7c4a658a,0xc12738b6),LL(0x40e72182,0xb3c47639),LL(0x8798e44f,0x3b77be46),LL(0x17a7f85f,0xdc047df2), LL(0x5e59d92d,0x2439d4c5),LL(0xe8e64d8d,0xcedca475),LL(0x87ca9b16,0xa724cd0d),LL(0xa5540dfe,0x35e4fd59), + LL(0xe4bcf6b1,0xf8c1ff18),LL(0x295018fa,0x856d6285),LL(0x3263c949,0x433f665c),LL(0xa1f21409,0xa6a76dd6), LL(0xcc7b4f79,0x17d32334),LL(0x06720e4a,0xa1d03122),LL(0x81d9bed5,0xadb6661d),LL(0x11db15d1,0xf0d6fb02), + LL(0x1fb747d2,0x7fd11ad5),LL(0x3033762b,0xab50f959),LL(0xfbefaf5a,0x2a7e711b),LL(0x3fef2bbf,0xc7393278), LL(0x0df6f9be,0xe29fa244),LL(0x71efd215,0x9092757b),LL(0x4f3d6fd9,0xee60e311),LL(0x0acfb78b,0x338542d4), + LL(0x38961a0f,0x44a23f08),LL(0x986987ca,0x1426eade),LL(0x4a863cc6,0x36e6ee2e),LL(0x628b8b79,0x48059420), LL(0x7396e1de,0x30303ad8),LL(0x38c5aad1,0x5c8bdc48),LL(0x5c8f5066,0x3e40e11f),LL(0x8d246bbd,0xabd6e768), + LL(0x23330a01,0x68aa40bb),LL(0xc34eafa0,0xd23f5ee4),LL(0x5de02c21,0x3bbee315),LL(0xd1d8dd06,0x18dd4397), LL(0x122d7b44,0x3ba1939a),LL(0xa33870d6,0xe6d3b40a),LL(0x1c4fe3f8,0x8e620f70),LL(0xd3a50cbf,0xf6bba1a5), + LL(0xcfc0aee0,0x4a78bde5),LL(0xc08c50bd,0x847edc46),LL(0xad63c9b2,0xbaa2439c),LL(0x10fc2acb,0xceb4a728), LL(0x26da033d,0xa419e40e),LL(0x03e02683,0x6cc3889d),LL(0xfdccf725,0x1cd28559),LL(0x8d13d208,0x0fd7e0f1), + LL(0x1f0df9d4,0x01b9733b),LL(0xa2b5e4f3,0x8cc2c5f3),LL(0x3a304fd4,0x43053bfa),LL(0x0a9f1aa7,0x8e87665c), LL(0xd73dc965,0x087f29ec),LL(0x3e9023db,0x15ace455),LL(0x2bce28b4,0x2370e309),LL(0xb6b1e84a,0xf9723442), + LL(0xb72d9f26,0xbeee662e),LL(0xf0e47109,0xb19396de),LL(0xe13289d0,0x85b1fa73),LL(0x54e58e32,0x436cf77e), LL(0xe990ef77,0x0ec833b3),LL(0x1b11fc25,0x7373e3ed),LL(0x0fc332ce,0xbe0eda87),LL(0x8d7ea856,0xced04970), + LL(0x7e977ca0,0xf85ff785),LL(0xdfdd5d2b,0xb66ee8da),LL(0x905af461,0xf5e37950),LL(0x966d487c,0x587b9090), LL(0x32ba0127,0x6a198a1b),LL(0x141615ac,0xa7720e07),LL(0x996ef2f2,0xa23f3499),LL(0x470bcb3d,0xef5f64b4), + LL(0x92b8c559,0xa526a962),LL(0x69740a0f,0x0c14aac0),LL(0xa6bdc0a5,0x0d41a9e3),LL(0x9c48aef4,0x97d52106), LL(0x3e7c253b,0xcf16bd30),LL(0x47fdedc1,0xcc834b1a),LL(0x373aab2e,0x7362c6e5),LL(0xc5f590ff,0x264ed85e), + LL(0x66d41870,0x7a46d9c0),LL(0x4787ba09,0xa50c20b1),LL(0xe3d44635,0x185e7e51),LL(0x31e2d8dc,0xb3b3e080), LL(0xa179e9d9,0xbed1e558),LL(0x74a76781,0x2daa3f79),LL(0x3a40864f,0x4372baf2),LL(0x4fe75cb5,0x46900c54), + LL(0xf76765d0,0xb95f171e),LL(0x95c87502,0x4ad726d2),LL(0x4d7c99bd,0x2ec769da),LL(0xc36cdfa8,0x5e2ddd19), LL(0xa93e6dea,0xc22117fc),LL(0x93771123,0xe8a2583b),LL(0xfa08a3a2,0xbe2f6089),LL(0x8f0e1112,0x4809d5ed), + LL(0xda7a095e,0x3b414aa3),LL(0x26f5aadd,0x9049acf1),LL(0x6be8b84a,0x78d46a4d),LL(0xb732b9b3,0xd66b1963), LL(0xde6e9555,0x5c2ac2a0),LL(0xb5bd8770,0xcf52d098),LL(0x0fd28921,0x15a15fa6),LL(0x8b27536d,0x56ccb81e), + LL(0x9f4ccbb8,0x0f0d8ab8),LL(0xdb221729,0xed5f44d2),LL(0x00bed10c,0x43141988),LL(0x1d735b8b,0xc94348a4), LL(0x29ef8479,0x79f3e9c4),LL(0x614c693f,0x4c13a4e3),LL(0x8e143a14,0x32c9af56),LL(0xe29ac5c4,0xbc517799), + LL(0x2774856f,0x05e17992),LL(0x6c1bf55f,0x6e52fb05),LL(0xe4f19e16,0xaeda4225),LL(0xaf5ccb26,0x70f4728a), LL(0xb2947f22,0x5d2118d1),LL(0x281d6fb9,0xc827ea16),LL(0x8cf0eabd,0x8412328d),LL(0x03ef9dcf,0x45ee9fb2), + LL(0xbb937d63,0x8e700421),LL(0xcc4b37a6,0xdf8ff2d5),LL(0x5ced7b68,0xa4c0d5b2),LL(0xc7308f59,0x6537c1ef), LL(0x3b37f8e8,0x25ce6a26),LL(0xdeebc6ce,0x170e9a9b),LL(0x8728d72c,0xdd037952),LL(0x850154bc,0x445b0e55), + LL(0x83a7337b,0x4b7d0e06),LL(0xffecf249,0x1e3416d4),LL(0x66a2b71f,0x24840eff),LL(0xb37cc26d,0xd0d9a50a), LL(0x6fe28ef7,0xe2198150),LL(0x23324c7f,0x3cc5ef16),LL(0x769b5263,0x220f3455),LL(0xa10bf475,0xe2ade2f1), + LL(0x458d3671,0x28cd20fa),LL(0x2dc4847b,0x1549722c),LL(0x591941e3,0x6dd01e55),LL(0x27128ccb,0x0e6fbcea), LL(0x3bef0262,0xae1a1e6b),LL(0x8f54e103,0xfa8c472c),LL(0x72c052ec,0x7539c0a8),LL(0x5a3490e9,0xd7b27369), + LL(0x71684349,0x143fe1f1),LL(0x32e19b97,0x36b4722e),LL(0x90980aff,0xdc059227),LL(0x9e13d674,0x175c9c88), LL(0x6e6bfdb1,0xa7de5b22),LL(0xbedb4b46,0x5ea5b7b2),LL(0xd34a6e44,0xd5570191),LL(0xa24ff7e6,0xfcf60d2e), + LL(0x677819e1,0x614a392d),LL(0xaa5a29e8,0x7be74c7e),LL(0x63c85f3f,0xab50fece),LL(0x46cab337,0xaca2e2a9), LL(0x122a6fe3,0x7f700388),LL(0x882a04a8,0xdb69f703),LL(0xcf7aed57,0x9a77935d),LL(0x8d91c86f,0xdf16207c), + LL(0x63ed9998,0x2fca49ab),LL(0xa77ddf96,0xa3125c44),LL(0x24344072,0x05dd8a86),LL(0xfec3fb56,0xa023dda2), LL(0x0c743032,0x421b41fc),LL(0x5e438639,0x4f2120c1),LL(0xc83c1b07,0xfb7cae51),LL(0xcac2171a,0xb2370caa), + LL(0x6cc820fb,0x2eb2d962),LL(0xb85a44bf,0x59feee5c),LL(0x5b6598f0,0x94620fca),LL(0x7e314051,0x6b922cae), LL(0x106bed4e,0xff8745ad),LL(0xdfa1e9ab,0x546e71f5),LL(0x1ec29487,0x935c1e48),LL(0x4d936530,0x9509216c), + LL(0x85c9a2db,0xc7ca3067),LL(0x6be8606f,0xd6ae5152),LL(0xe14c651d,0x09dbcae6),LL(0x9bc32f96,0xc9536e23), LL(0x34521b03,0xa90535a9),LL(0x878756ff,0xf39c526c),LL(0x8aedf03c,0x383172ec),LL(0xefe0c034,0x20a8075e), + LL(0x64026422,0xf22f9c62),LL(0x24b9d076,0x8dd10780),LL(0x3bef2950,0x944c742a),LL(0x88a2b00b,0x55b9502e), LL(0x86a09817,0xa59e14b4),LL(0x47bb4071,0xa39dd3ac),LL(0x3be0592f,0x55137f66),LL(0xc9e63f5b,0x07fcafd4), + LL(0x346eb226,0x963652ee),LL(0xec2facb7,0x7dfab085),LL(0x691add26,0x273bf2b8),LL(0xf2b46c44,0x30d74540), LL(0xf2c2d065,0x05e8e73e),LL(0xd42eeac9,0xff9b8a00),LL(0x97209d22,0x2fcbd205),LL(0xde14ea2c,0xeb740ffa), + LL(0xa8aef518,0xc71ff913),LL(0xfff4cfa2,0x7bfc74bb),LL(0xb6b36048,0x1716680c),LL(0x9ef79af1,0x121b2cce), LL(0xa01eb3d3,0xbff3c836),LL(0x5f79077b,0x50eb1c6a),LL(0xa004bbcf,0xa48c32d6),LL(0x7d64f61d,0x47a59316), + LL(0x93102016,0x6068147f),LL(0x94d12576,0x12c5f654),LL(0xc9bc6b91,0xefb071a7),LL(0x6e23ea95,0x7c2da0c5), LL(0xd4a1dd5d,0xf4fd45b6),LL(0x9122b13c,0x3e7ad9b6),LL(0xe6f57a48,0x342ca118),LL(0x06f8288f,0x1c2e94a7), + LL(0x5a97d231,0x99e68f07),LL(0x4d838758,0x7c80de97),LL(0x05872727,0xbce0f5d0),LL(0x19c4d016,0xbe5d95c2), LL(0x9c2492ee,0x921d5cb1),LL(0x404d6fb3,0x42192dc1),LL(0x32f988d3,0x4c84dcd1),LL(0xa17b8e85,0xde26d61f), + LL(0x137c7408,0xc466dcb6),LL(0x36a266da,0x9a38d7b6),LL(0x83bebf1b,0x7ef5cb06),LL(0x0fd014e3,0xe5cdcbbf), LL(0xf65965a0,0x30aa376d),LL(0xebb3e95e,0x60fe88c2),LL(0x66ee6f20,0x33fd0b61),LL(0x3f41f0a0,0x8827dcdb), + LL(0x0c56c690,0xbf8a9d24),LL(0xddb7641d,0x40265dad),LL(0x3a6b662b,0x522b05bf),LL(0xb1478c9b,0x466d1dfe), LL(0x1484469b,0xaa616962),LL(0x02df8f9f,0x0db60549),LL(0x3cb8bf51,0xc37bca02),LL(0x21371ce8,0x5effe346), + LL(0xff112c32,0xe8f65264),LL(0x7b971fb2,0x8a9c736d),LL(0x7b75080d,0xa4f19470),LL(0x8839c59b,0xfc3f2c5a), LL(0x5aeb49c2,0x1d6c777e),LL(0xda1addfe,0xf3db034d),LL(0x5535affc,0xd76fee5a),LL(0xb92251fd,0x0853ac70), + LL(0x8b2a29d5,0x37e3d594),LL(0x4de00ddb,0x28f1f457),LL(0xf42c328b,0x8083c1b5),LL(0xe493c73b,0xd8ef1d8f), LL(0x41dc61bd,0x96fb6260),LL(0x27ee2f8a,0xf74e8a9d),LL(0x2c946a5d,0x7c605a80),LL(0x3839ccfd,0xeed48d65), + LL(0x3a29467a,0x9894344f),LL(0xc51eba6d,0xde81e949),LL(0xa5e5c2f2,0xdaea066b),LL(0x08c8c7b3,0x3fc8a614), LL(0x06d0de9f,0x7adff88f),LL(0x3b75ce0a,0xbbc11cf5),LL(0xfbbc87d5,0x9fbb7acc),LL(0x7badfde2,0xa1458e26), +}, +/* digit=13 base_pwr=2^91 */ +{ + LL(0xe039c256,0x1cb43668),LL(0x7c17fd5d,0x5f26fb8b),LL(0x79aa062b,0xeee426af),LL(0xd78fbf04,0x072002d0), LL(0xe84fb7e3,0x4c9ca237),LL(0x0c82133d,0xb401d8a1),LL(0x6d7e4181,0xaaa52592),LL(0x73dbb152,0xe9430833), + LL(0xbe24319a,0xf92dda31),LL(0xe095a8e7,0x03f7d28b),LL(0x98782185,0xa52fe840),LL(0x29c24dbc,0x276ddafe), LL(0x1d7a64eb,0x80cd5496),LL(0x7f1dbe42,0xe4360889),LL(0x8438d2d5,0x2f81a877),LL(0x85169036,0x7e4d52a8), + LL(0x1d59715d,0x19e3d5b1),LL(0xd788983e,0xc7eaa762),LL(0xabf1f248,0xe5a730b0),LL(0xfae3fd83,0xfbab8084), LL(0x53765b2f,0x65e50d21),LL(0xfa127f3d,0xbdd4e083),LL(0x397b1b10,0x9cf3c074),LL(0xb1b59fd3,0x59f8090c), + LL(0x615faa8f,0x7b15fd9d),LL(0x968554ed,0x8fa1eb40),LL(0x7aa44882,0x7bb4447e),LL(0x029fff32,0x2bb2d0d1), LL(0x6caa6d2f,0x075e2a64),LL(0x22e7351b,0x8eb879de),LL(0x9a506c62,0xbcd5624e),LL(0xa87e24dc,0x218eaef0), + LL(0x44ddfa35,0x37e56847),LL(0xdab3f747,0x9ccfc5c5),LL(0x1ee96cf4,0x9ac1df3f),LL(0x3b480b8f,0x0c0571a1), LL(0x4b3a7b3c,0x2fbeb3d5),LL(0x5dcdbb99,0x35c03669),LL(0xb2415b3a,0x52a0f5dc),LL(0x4413ed9a,0xd57759b4), + LL(0x3d30a2c5,0x1fe647d8),LL(0xf78a81dc,0x0857f77e),LL(0x131a4a9b,0x11d5a334),LL(0x29d393f5,0xc0a94af9), LL(0xdaa6ec1a,0xbc3a5c0b),LL(0x88d2d7ed,0xba9fe493),LL(0xbb614797,0xbb4335b4),LL(0x72f83533,0x991c4d68), + LL(0xd2f01cb3,0x53258c28),LL(0xd75db0b1,0x93d6eaa3),LL(0xe87d0db4,0x419a2b0d),LL(0xd8fe8493,0xa1e48f03), LL(0xc508b23a,0xf747faf6),LL(0x35d53549,0xf137571a),LL(0xfcf9b838,0x9f5e58e2),LL(0xa7fd3cf5,0xc7186cee), + LL(0xe978a1d3,0x77b868ce),LL(0x7ab92d04,0xe3a68b33),LL(0x87a5b862,0x51029794),LL(0x3a61d41d,0x5f0606c3), LL(0x6f9326f1,0x2814be27),LL(0xc6fe3c2e,0x2f521c14),LL(0xacdf7351,0x17464d7d),LL(0x777f7e44,0x10f5f9d3), + LL(0x269fb37d,0xce8e616b),LL(0x7de62de5,0xaaf73804),LL(0x4fdd4153,0xaba11175),LL(0x3770b49b,0x515759ba), LL(0xaa423a61,0x8b09ebf8),LL(0xcd41fb92,0x592245a1),LL(0x9b4c8936,0x1cba8ec1),LL(0xaf36710e,0xa87e91e3), + LL(0x3d34a2e3,0x1fd84ce4),LL(0xb43b5d61,0xee3759ce),LL(0x619186c7,0x895bc78c),LL(0xcbb9725a,0xf19c3809), LL(0xde744b1f,0xc0be21aa),LL(0x60f8056b,0xa7d222b0),LL(0xb23efe11,0x74be6157),LL(0x0cd68253,0x6fab2b4f), + LL(0x4bf1d725,0xad33ea5f),LL(0x4f6c950f,0x9c1d8ee2),LL(0xa377af06,0x544ee78a),LL(0x94a113e1,0x54f489bb), LL(0x992fb7e8,0x8f11d634),LL(0xa2a44347,0x0169a7aa),LL(0x95020e00,0x1d49d4af),LL(0xe08e120b,0x95945722), + LL(0xa4d32282,0xb6e33878),LL(0x48020ae7,0xe36e029d),LL(0x37a9b750,0xe05847fb),LL(0xb29e3819,0xf876812c), LL(0xd23a17f0,0x84ad138e),LL(0xf0b3950e,0x6d7b4480),LL(0x2fd67ae0,0xdfa8aef4),LL(0x52333af6,0x8d3eea24), + LL(0xb15d5acc,0x0d052075),LL(0xbd815bc4,0xc6d9c79f),LL(0xdfa36cf2,0x8dcafd88),LL(0x38aa9070,0x908ccbe2), LL(0xba35afce,0x638722c4),LL(0xfd6abf0b,0x5a3da8b0),LL(0xc9c335c1,0x2dce252c),LL(0x65aa799b,0x84e7f0de), + LL(0xb99a72cb,0x2101a522),LL(0x87618016,0x06de6e67),LL(0xe6f3653e,0x5ff8c7cd),LL(0xc7a6754a,0x0a821ab5), LL(0x7cb0b5a2,0x7e3fa52b),LL(0xc9048790,0xa7fb121c),LL(0x06ce053a,0x1a725020),LL(0x04e929b0,0xb490a31f), + LL(0x62dd61ad,0xe17be47d),LL(0x6be01371,0x781a961c),LL(0xdae3cbba,0x1063bfd3),LL(0x7f73c9ba,0x35647406), LL(0x2736a129,0xf50e957b),LL(0xed13f256,0xa6313702),LL(0x3a19fcc5,0x9436ee65),LL(0xe7a4c8b6,0xcf2bdb29), + LL(0xc5f95cd8,0xb06b1244),LL(0xf4ab95f4,0xda8c8af0),LL(0xb9e5836d,0x1bae59c2),LL(0x3acffffc,0x07d51e7e), LL(0xc2ccbcda,0x01e15e6a),LL(0x8528c3e0,0x3bc1923f),LL(0xa49fead4,0x43324577),LL(0x2aa7a711,0x61a1b884), + LL(0x700230ef,0xf9a86e08),LL(0xbd19adf8,0x0af585a1),LL(0xf55ad8f2,0x7645f361),LL(0x46c3614c,0x6e676223), LL(0x4e774d3f,0x23cb257c),LL(0xac102d1b,0x82a38513),LL(0x7b126aa5,0x9bcddd88),LL(0xeefd3ee4,0xe716998b), + LL(0xfb167583,0x4239d571),LL(0xd16c8f8a,0xdd011c78),LL(0x69a27519,0x271c2895),LL(0xd2d64b6a,0x9ce0a3b7), LL(0xd5ec6738,0x8c977289),LL(0x8840ef6b,0xa3b49f9a),LL(0x9a453419,0x808c14c9),LL(0x0cf0a2d5,0x5c00295b), + LL(0x1d4bcc76,0x524414fb),LL(0x459a88f1,0xb07691d2),LL(0xf70d110f,0x77f43263),LL(0xb7abf9f3,0x64ada5e0), LL(0x5b544cf5,0xafd0f94e),LL(0xfd2713fe,0xb4a13a15),LL(0x250c74f4,0xb99b7d6e),LL(0x20324e45,0x097f2f73), + LL(0xaffa8208,0x994b37d8),LL(0xdc29aafc,0xc3c31b0b),LL(0x7a3a607f,0x3da74651),LL(0xfe6955d6,0xd8e1b8c1), LL(0xc8418682,0x716e1815),LL(0x7dc91d97,0x541d487f),LL(0xc6996982,0x48a04669),LL(0x83a6502e,0xf39cab15), + LL(0xe68db055,0x025801a0),LL(0xba3338d5,0xf3569758),LL(0xee2afa84,0xb0c8c0aa),LL(0xfb6562d1,0x4f6985d3), LL(0x132ed17a,0x351f1f15),LL(0xc04365fe,0x510ed0b4),LL(0xe5b1f066,0xa3f98138),LL(0x32df03dc,0xbc9d95d6), + LL(0x19abd09e,0xa83ccf6e),LL(0x4ff17edb,0x0b4097c1),LL(0xd64a06ce,0x58a5c478),LL(0x544a58fd,0x2ddcc3fd), LL(0x9e8153b8,0xd449503d),LL(0x7774179b,0x3324fd02),LL(0xdbd9120c,0xaf5d47c8),LL(0x34fa94db,0xeb860162), + LL(0x972f07f4,0x5817bdd1),LL(0xd27bbceb,0xe5579e2e),LL(0x5f11e5a6,0x86847a1f),LL(0x7c3cf048,0xb39ed255), LL(0xa2f62e55,0xe1076417),LL(0x1bcf82a2,0x6b9ab38f),LL(0x7aeb29f9,0x4bb7c319),LL(0x17227a46,0xf6d17da3), + LL(0x0f968c00,0xab53ddbd),LL(0x000c880b,0xa03da7ec),LL(0x6a9ad24d,0x7b239624),LL(0x01ec60d0,0x612c0401), LL(0x109f5df1,0x70d10493),LL(0x80af7550,0xfbda4030),LL(0xc6b9a9b3,0x30b93f95),LL(0x007d9418,0x0c74ec71), + LL(0x6edb951f,0x94175564),LL(0x7f22c282,0x5f4a9d78),LL(0xb38d1196,0xb7870895),LL(0xa228ce7c,0xbc593df3), LL(0x6af3641a,0xc78c5bd4),LL(0x3d9b3dcc,0x7802200b),LL(0x8be33304,0x0dc73f32),LL(0x61ffb79a,0x847ed87d), + LL(0x6d671192,0xf85c974e),LL(0xde16f60f,0x1e14100a),LL(0x95c38797,0x45cb0d5a),LL(0x9b022da4,0x18923bba), LL(0xbbe7e86e,0xef2be899),LL(0x216067bf,0x4a1510ee),LL(0x84d5ce3e,0xd98c8154),LL(0xf92a2b90,0x1af777f0), + LL(0x4ef65724,0x9fbcb400),LL(0x3c0ca6fe,0x3e04a4c9),LL(0x55002994,0xfb3e2cb5),LL(0x5363ecab,0x1f3a93c5), LL(0x3923555b,0x1fe00efe),LL(0x1e1751ea,0x744bedd9),LL(0x6ab69357,0x3fb2db59),LL(0xf5e6618b,0x8dbd7365), + LL(0xdf1ea40e,0x99d53099),LL(0x57d61e64,0xb3f24a0b),LL(0x596eb812,0xd088a198),LL(0x5762940b,0x22c8361b), LL(0xf9c0d95c,0x66f01f97),LL(0x8e43cdae,0x88461172),LL(0xb72b15c3,0x11599a7f),LL(0x420d95cc,0x135a7536), + LL(0x5f7ae2f6,0x2dcdf0f7),LL(0xd7fa6da2,0x15fc6e1d),LL(0xd1d441b6,0x81ca829a),LL(0x04a106b6,0x84c10cf8), LL(0xa73fbbd0,0xa9b26c95),LL(0x4d8f6ee8,0x7f24e0cb),LL(0x1e25a043,0x48b45937),LL(0x036f3dfe,0xf8a74fca), + LL(0xc9f84296,0x1ed46585),LL(0x3bc278b0,0x7fbaa8fb),LL(0x6c4fcbd0,0xa8e96cd4),LL(0x73b60a5f,0x940a1202), LL(0x55a4aec8,0x34aae120),LL(0xdbd742f0,0x550e9a74),LL(0x228c68ab,0x794456d7),LL(0xa4e25ec6,0x492f8868), + LL(0xb2d8f398,0x682915ad),LL(0x5b84c953,0xf13b51cc),LL(0x5bb917d6,0xcda90ab8),LL(0x4ea3dee1,0x4b615560), LL(0x0a52c1c8,0x578b4e85),LL(0x20b75fc4,0xeab1a695),LL(0xaa0bb3c6,0x60c14f3c),LL(0xb8216094,0x220f448a), + LL(0xb0e63d34,0x4fe7ee31),LL(0xa9e54fab,0xf4600572),LL(0xd5e7b5a4,0xc0493334),LL(0x06d54831,0x8589fb92), LL(0x6583553a,0xaa70f5cc),LL(0xe25649e5,0x0879094a),LL(0x10044652,0xcc904507),LL(0x02541c4f,0xebb0696d), + LL(0xb9718710,0x5a171fde),LL(0xf374a9f5,0x38f1bed8),LL(0xba39bdc1,0xc8c582e1),LL(0x908cc0ce,0xfc457b0a), LL(0x883841e2,0x9a187fd4),LL(0x38725381,0x8ec25b39),LL(0x96f84395,0x2553ed05),LL(0x6f6c6897,0x095c7661), + LL(0x4bdc5610,0x917ac85c),LL(0x179eb301,0xb2885fe4),LL(0x8b78bdcc,0x5fc65547),LL(0xe59e4699,0x4a9fc893), LL(0x3ce299af,0xbb7ff0cd),LL(0xadf38b20,0x195be9b3),LL(0xd38ddb8f,0x6a929c87),LL(0xb21a51b9,0x55fcc99c), + LL(0x721a4593,0x2b695b4c),LL(0x768eaac2,0xed1e9a15),LL(0x7489f914,0xfb63d71c),LL(0x78118910,0xf98ba31c), LL(0x9b128eb4,0x80291373),LL(0xd448af4a,0x7801214e),LL(0x55418dd3,0xdbd2e22b),LL(0xd3998242,0xeffb3c0d), + LL(0xc7bf3827,0xdfa6077c),LL(0x47f8238f,0xf2165bcb),LL(0x8564d554,0xfe37cf68),LL(0x0a81fb98,0xe5f825c4), LL(0xffed4d6f,0x43cc4f67),LL(0xb50a34b0,0xbc609578),LL(0x5041faf1,0x8aa8fcf9),LL(0x651773b6,0x5659f053), + LL(0x6044d63b,0xe87582c3),LL(0x0cdb0ca0,0xa6089409),LL(0xbfb2bcf6,0x8c993e0f),LL(0x45985cfc,0xfc64a719), LL(0x83dbedba,0x15c4da80),LL(0x2be67df7,0x804ae112),LL(0xa23defde,0xda4c9658),LL(0x5156e0d3,0x12002ddd), + LL(0x5dd21b96,0xe68eae89),LL(0xcf44624d,0x8b99f28b),LL(0x1ec8897a,0x0ae00808),LL(0x6712f76e,0xdd0a9303), LL(0x4e233de4,0x96237522),LL(0x2b36a8a5,0x192445b1),LL(0x023993d9,0xabf9ff74),LL(0x2aad4a8f,0x21f37bf4), + LL(0xf8bd2bbd,0x340a4349),LL(0x4868195d,0x1d902cd9),LL(0xe5fdb6f1,0x3d27bbf1),LL(0x124f9f1c,0x7a5ab088), LL(0xf7a09e03,0xc466ab06),LL(0x31f2c123,0x2f8a1977),LL(0x041b6657,0xda355dc7),LL(0x8ece2a7c,0xcb840d12), + LL(0x7db32675,0xb600ad9f),LL(0x07a06f1b,0x78fea133),LL(0xb31f6094,0x5d032269),LL(0x83ec37aa,0x07753ef5), LL(0x9c0bea78,0x03485aed),LL(0xbc3f4524,0x41bb3989),LL(0x697f726d,0x09403761),LL(0xdf394820,0x6109beb3), + LL(0x3b6d1145,0x804111ea),LL(0xa8582654,0xb6271ea9),LL(0x24e66562,0x619615e6),LL(0xd7b6ad9c,0xa2554945), LL(0x99bfe35f,0xd9c4985e),LL(0x7b51cdf6,0x9770ccc0),LL(0x92881832,0x7c327013),LL(0x286b26d1,0x8777d45f), + LL(0xd847999d,0x9bbeda22),LL(0xc3525d32,0x03aa33b6),LL(0x28a959a1,0x4b7b96d4),LL(0x31e5d234,0xbb3786e5), LL(0x6961f247,0xaeb5d3ce),LL(0x02f93d3f,0x20aa85af),LL(0xd7a7ae4f,0x9cd1ad3d),LL(0x781adaa8,0xbf6688f0), + LL(0x7469cead,0xb1b40e86),LL(0x309fca48,0x1904c524),LL(0x4b54bbc7,0x9b7312af),LL(0x593affa2,0xbe24bf8f), LL(0xbd98764b,0xbe5e0790),LL(0xa26e299e,0xa0f45f17),LL(0x6b8fe4c7,0x4af0d2c2),LL(0x8ae8a3e6,0xef170db1), + LL(0x29e0ccc1,0x0e8d61a0),LL(0x60ad36ca,0xcd53e87e),LL(0xc8173822,0x328c6623),LL(0xa496be55,0x7ee1767d), LL(0x648945af,0x89f13259),LL(0x25c8009c,0x9e45a5fd),LL(0x1f61ab8c,0xaf2febd9),LL(0x8a275385,0x43f6bc86), + LL(0xf2142e79,0x87792348),LL(0xc6e6238a,0x17d89259),LL(0x4a839d9b,0x7536d2f6),LL(0x76a1fbdc,0x1f428fce), LL(0x0db06dfe,0x1c109601),LL(0x50a3a3cc,0xbfc16bc1),LL(0x9b30f41b,0xf9cbd9ec),LL(0x00138cce,0x5b5da0d6), + LL(0x56ef96a7,0xec1d0a48),LL(0x982bf842,0xb47eb848),LL(0xec3f700d,0x66deae32),LL(0xaa1181e0,0x4e43c42c), LL(0xd1a4aa2a,0xa1d72a31),LL(0xc004f3ce,0x440d4668),LL(0x45fe8a7a,0x0d6a2d3b),LL(0xfb128365,0x820e52e2), + LL(0x25e51b09,0x29ac5fcf),LL(0x2023d159,0x180cd2bf),LL(0xa1ebf90e,0xa9892171),LL(0x7c132181,0xf97c4c87), LL(0xc03dbb7e,0x9f1dc724),LL(0x018cbbe4,0xae043765),LL(0x0767d153,0xfb0b2a36),LL(0x249cbaeb,0xa8e2f4d6), + LL(0xd95ea168,0x172a5247),LL(0x2970764a,0x1758fada),LL(0x1d978169,0xac803a51),LL(0xde77e01b,0x299cfe2e), LL(0xb0a98927,0x652a1e17),LL(0x20014495,0x2e26e1d1),LL(0x7175b56a,0x7ae0af9f),LL(0xd64b9f95,0xc2e22a80), + LL(0xd90a060a,0x4d0ff9fb),LL(0xbaf38085,0x496a27db),LL(0xda776bcf,0x32305401),LL(0x725f209e,0xb8cdcef6), LL(0x436a0bba,0x61ba0f37),LL(0x76860049,0x263fa108),LL(0xda3542cf,0x92beb98e),LL(0xd5849538,0xa2d4d14a), + LL(0x12e9a1bc,0x989b9d68),LL(0x5f6e3268,0x61d9075c),LL(0x99ace638,0x352c6aa9),LL(0x920f43ff,0xde4e4a55), LL(0xd673c017,0xe5e4144a),LL(0x6f6e05ea,0x667417ae),LL(0xdcd1bd56,0x613416ae),LL(0x86693711,0x5eb36201), + LL(0x3a1aa914,0x2d7bc504),LL(0x76dc5975,0x175a1299),LL(0x3fc8125c,0xe900e0f2),LL(0x11198875,0x569ef68c), LL(0x63a113b4,0x9012db63),LL(0x98835766,0xe3bd3f56),LL(0x76412dea,0xa5c94a52),LL(0xaa735e5c,0xad9e2a09), + LL(0x508b65e9,0x405a984c),LL(0x6df1a0d1,0xbde4a1d1),LL(0xdfba80da,0x1a9433a1),LL(0x9440ad2e,0xe9192ff9), LL(0x5099fe92,0x9f649696),LL(0x0b27a54a,0x25ddb65c),LL(0xc590da61,0x178279dd),LL(0xfbde681a,0x5479a999), + LL(0x013fe162,0xd0e84e05),LL(0x632d471b,0xbe11dc92),LL(0xfc0e089f,0xdf0b0c45),LL(0x4c144025,0x04fb15b0), LL(0x13c99927,0xa61d5fc2),LL(0x3de2eb35,0xa033e9e0),LL(0xb8dacbb4,0xf8185d5c),LL(0x8644549d,0x9a88e265), + LL(0x54671ff6,0xf717af62),LL(0x5fa58603,0x4bd4241b),LL(0xe67773c0,0x06fba40b),LL(0x6a2847e9,0xc1d933d2), LL(0x689e2c70,0xf4f5acf3),LL(0x46bafd31,0x92aab0e7),LL(0x3473f6e5,0x798d76aa),LL(0x93141934,0xcc6641db), + LL(0xd31e535e,0xcae27757),LL(0x87c2ee11,0x04cc43b6),LL(0x2e029ffa,0x8d1f9675),LL(0xe4cc7a2c,0xc2150672), LL(0x8d68b013,0x3b03c1e0),LL(0xedf298f3,0xa9d6816f),LL(0xa2804464,0x1bfbb529),LL(0x5db22125,0x95a52fae), + LL(0x0e1cb64e,0x55b32160),LL(0x7e7fc9fe,0x004828f6),LL(0x1bb0fb93,0x13394b82),LL(0x35f1a920,0xb6293a2d), LL(0xd145d2d9,0xde35ef21),LL(0xbb8fa603,0xbe6225b3),LL(0x32cf252d,0x00fc8f6b),LL(0x117cf8c2,0xa28e52e6), + LL(0x4c371e6d,0x9d1dc89b),LL(0x36ef0f28,0xcebe0675),LL(0xa4292f81,0x5de05d09),LL(0x353e3083,0xa8303593), LL(0x7e37a9bb,0xa1715b0a),LL(0x2b8faec3,0x8c56f61e),LL(0x33c9b102,0x52507431),LL(0xa44431f0,0x0130cefc), + LL(0xbd865cfb,0x56039fa0),LL(0xbc5f1dd7,0x4b03e578),LL(0xbabe7224,0x40edf2e4),LL(0x3a1988f6,0xc752496d), LL(0x564beb6b,0xd1572d3b),LL(0x39a1c608,0x0db1d110),LL(0x16f60126,0x568d1934),LL(0xf354af33,0x05ae9668), + LL(0xc92544f2,0x19de6d37),LL(0xa35837d5,0xcc084353),LL(0x1a514ece,0xcbb6869c),LL(0x2e1d1066,0xb633e728), LL(0x936c581c,0xf15dd69f),LL(0x7439c4f9,0x96e7b8ce),LL(0x2e448a5b,0x5e676f48),LL(0xfd916bbb,0xb2ca7d5b), + LL(0xf5024025,0xd55a2541),LL(0xe4c2d937,0x47bc5769),LL(0x0362189f,0x7d31b92a),LL(0xef7816f9,0x83f3086e), LL(0xb587579a,0xf9f46d94),LL(0x30e76c5f,0xec2d22d8),LL(0xb000ffcf,0x27d57461),LL(0x364ffc2c,0xbb7e65f9), + LL(0x6652a220,0x7c7c9477),LL(0xd696c981,0x61618f89),LL(0x89effff3,0x5021701d),LL(0x7c314163,0xf2c8ff8e), LL(0x8efb4d3e,0x2da413ad),LL(0xce176d95,0x937b5adf),LL(0x2a67d51c,0x22867d34),LL(0x18eb3ac9,0x262b9b10), + LL(0xc43ff28b,0x4e314fe4),LL(0x6a664e7a,0x76476627),LL(0xb7a565c2,0x3e90e40b),LL(0xc1acf831,0x8588993a), LL(0x8f938829,0xd7b501d6),LL(0x3edd7d4c,0x996627ee),LL(0x90cd34c7,0x37d44a62),LL(0xf3833e8d,0xa8327499), + LL(0x4bf50353,0x2e18917d),LL(0x556765fb,0x85dd726b),LL(0x93d5ab66,0x54fe65d6),LL(0x915c25fe,0x3ddbaced), LL(0x12f22e85,0xa799d9a4),LL(0x6d06f6bc,0xe2a24867),LL(0x43ca1637,0xf4f1ee56),LL(0x61ece30a,0xfda2828b), + LL(0xa2dee7a6,0x758c1a3e),LL(0x734b2284,0xdcde2f3c),LL(0x4eaba6ad,0xaba445d2),LL(0x76cee0a7,0x35aaf668), LL(0xe5aa049a,0x7e0b04a9),LL(0x91103e84,0xe74083ad),LL(0x40afecc3,0xbeb183ce),LL(0xea043f7a,0x6b89de9f), +}, +/* digit=14 base_pwr=2^98 */ +{ + LL(0xfe67ba66,0x0e299d23),LL(0x93cf2f34,0x91450760),LL(0x97fcf913,0xf45b5ea9),LL(0x8bd7ddda,0x5be00843), LL(0xd53ff04d,0x358c3e05),LL(0x5de91ef7,0xbf7ccdc3),LL(0xb69ec1a0,0xad684dbf),LL(0x801fd997,0x367e7cf2), + LL(0xb0dc8595,0x0ca1f3b7),LL(0x9f1d9f2e,0x27de4608),LL(0xbadd82a7,0x1af3bf39),LL(0x65862448,0x79356a79), LL(0xf5f9a052,0xc0602345),LL(0x139a42f9,0x1a8b0f89),LL(0x844d40fc,0xb53eee42),LL(0x4e5b6368,0x93b0bfe5), + LL(0xc024789c,0x5434dd02),LL(0x41b57bfc,0x90dca9ea),LL(0x243398df,0x8aa898e2),LL(0x894a94bb,0xf607c834), LL(0xc2c99b76,0xbb07be97),LL(0x18c29302,0x6576ba67),LL(0xe703a88c,0x3d79efcc),LL(0xb6a0d106,0xf259ced7), + LL(0xc8de610b,0x0f893a5d),LL(0x67e223ce,0xe8c515fb),LL(0x4ead6dc5,0x7774bfa6),LL(0x925c728f,0x89d20f95), LL(0x098583ce,0x7a1e0966),LL(0x93f2a7d7,0xa2eedb94),LL(0x4c304d4a,0x1b282097),LL(0xc077282d,0x0842e3da), + LL(0x3b9e2d7b,0xe4d972a3),LL(0xc48218ff,0x7cc60b27),LL(0x84149d91,0x8fc70838),LL(0x2f461ecc,0x5c04346f), LL(0x614650a9,0xebe9fdf2),LL(0xc1f666ac,0x5e35b537),LL(0x88babc83,0x645613d1),LL(0xc5e1c93e,0x88cace3a), + LL(0x3de92e23,0x209ca375),LL(0x5fbbb6e3,0xccb03cc8),LL(0xd7b1487e,0xccb90f03),LL(0xc710941f,0xfa9c2a38), LL(0x6724ceed,0x756c3823),LL(0x192d0323,0x3a902258),LL(0xea5e038e,0xb150e519),LL(0xc7427591,0xdcba2865), + LL(0x78890732,0xe549237f),LL(0x53fcb4d9,0xc443bef9),LL(0xeb3480d6,0x9884d8a6),LL(0x3048b186,0x8a35b6a1), LL(0x65e9a90a,0xb4e44716),LL(0x653006c0,0x45bf380d),LL(0x4fe9ae3b,0x8f3f820d),LL(0x979a3b71,0x244a35a0), + LL(0x74cd06ff,0xa1010e9d),LL(0xaca3eeac,0x9c17c7df),LL(0x8063aa2b,0x74c86cd3),LL(0x734614ff,0x8595c4b3), LL(0x990f62cc,0xa3de00ca),LL(0xca0c3be5,0xd9bed213),LL(0xdf8ce9f5,0x7886078a),LL(0x5cd44444,0xddb27ce3), + LL(0x58926ddd,0xed374a66),LL(0x908015b8,0x138b2d49),LL(0xde1f7ab8,0x886c6579),LL(0xc3020b7a,0x888b9aa0), LL(0x3a96e355,0xd3ec034e),LL(0xf30fbe9a,0xba65b0b8),LL(0xff21367a,0x064c8e50),LL(0x0b04b46e,0x1f508ea4), + LL(0x747c866c,0x98561a49),LL(0x0518a062,0xbbb1e5fe),LL(0xecdc3608,0x20ff4e8b),LL(0x20184027,0x7f55cded), LL(0xf38c85f0,0x8d73ec95),LL(0x8bc3b8c3,0x5b589fdf),LL(0x0f12b66f,0xbe95dd98),LL(0x0e338e01,0xf5bd1a09), + LL(0x5e915918,0x65163ae5),LL(0x86f8a46b,0x6158d6d9),LL(0xeeebf99c,0x8466b538),LL(0xbca477ef,0xca8761f6), LL(0x9ebbc601,0xaf3449c2),LL(0xe0c3ae2f,0xef3b0f41),LL(0x5de63752,0xaa6c577d),LL(0x64682a51,0xe9166601), + LL(0xfc15aa1e,0x5a3097be),LL(0xb54b0745,0x40d12548),LL(0x519a5f12,0x5bad4706),LL(0xa439dee6,0xed03f717), LL(0x4a02c499,0x0794bb6c),LL(0xcffe71d2,0xf725083d),LL(0x0f3adcaf,0x2cad7519),LL(0x43729310,0x7f68ea1c), + LL(0xb7ffd977,0xe747c8c7),LL(0x80761a22,0xec104c35),LL(0x5a3ffb83,0x8395ebaf),LL(0xe4b63db7,0xfb3261f4), LL(0xd883e544,0x53544960),LL(0x8cc2eeb8,0x13520d70),LL(0xd3d65f99,0x08f6337b),LL(0x781cf95b,0x83997db2), + LL(0x0dbd2c01,0xce6ff106),LL(0x1f9ce934,0x4f8eea6b),LL(0x0e993921,0x546f7c4b),LL(0x5e753fc7,0x6236a324), LL(0xa16022e9,0x65a41f84),LL(0x43d1dbb2,0x0c18d878),LL(0x2d4cef9c,0x73c55640),LL(0x70444c74,0xa0428108), + LL(0x9afdfb3c,0x68e4f15e),LL(0x5bdfb6df,0x49a56143),LL(0x5f823d97,0xa9bc1bd4),LL(0xea111c2a,0xbceb5970), LL(0xb269bbc4,0x366b455f),LL(0xe9bc5d62,0x7cd85e1e),LL(0x4f18b086,0xc743c41c),LL(0x95294fb9,0xa4b40990), + LL(0x26ee8382,0x9c7c581d),LL(0x359d638e,0xcf17dcc5),LL(0xb728ae3d,0xee8273ab),LL(0xf821f047,0x1d112926), LL(0x50491a74,0x11498477),LL(0xfde0dfb9,0x687fa761),LL(0x7ea435ab,0x2c258022),LL(0x91ce7e3f,0x6b8bdb94), + LL(0x3bf834aa,0x4c5b5dc9),LL(0x4f6c7e4b,0x04371819),LL(0x3736bcad,0xc284e00a),LL(0x21ae8f8d,0x0d881118), LL(0xf48c8e33,0xf9cf0f82),LL(0xa1bf40db,0xa11fd075),LL(0xdc2733e5,0xdceab0de),LL(0x8e986bd7,0xc560a8b5), + LL(0x3929d097,0x48dd1fe2),LL(0x92f188f1,0x3885b290),LL(0xda6fcdac,0x0f2ae613),LL(0xb662a46c,0x9054303e), LL(0x0738042a,0xb6871e44),LL(0xbdaf6449,0x98e6a977),LL(0xd1c9df1b,0xd8bc0650),LL(0x36e098f9,0xef3d6451), + LL(0xb6d72d28,0x03fbae82),LL(0xf5d84080,0x77ca9db1),LL(0xa58efc1c,0x8a112cff),LL(0xc564cb4a,0x518d761c), LL(0xf0d1b5ce,0x69b5740e),LL(0xe9eb1785,0x717039cc),LL(0x22f53382,0x3fe29f90),LL(0x6bc7c95c,0x8e54ba56), + LL(0xf7f91d0f,0x9c806d8a),LL(0xa82a5728,0x3b61b0f1),LL(0x94d76754,0x4640032d),LL(0x47d834c6,0x273eb5de), LL(0x7b4e4d53,0x2988abf7),LL(0xde401777,0xb7ce66bf),LL(0x715071b3,0x9fba6b32),LL(0xad3a1a98,0x82413c24), + LL(0xe0e8ad93,0x5b7fc8c4),LL(0x5fab868d,0xb5679aee),LL(0x2b3946f3,0xb1f9d2fa),LL(0x5685b50a,0x458897dc), LL(0x89d0caf3,0x1e98c930),LL(0x78642e92,0x39564c5f),LL(0x0dbdaf18,0x1b77729a),LL(0x579e82e6,0xf9170722), + LL(0xe4515fa5,0x680c0317),LL(0xfb0c790f,0xf85cff84),LL(0x6d2e0765,0xc7a82aab),LL(0x35c82b32,0x7446bca9), LL(0x6d63184f,0x5de607aa),LL(0x262803a6,0x7c1a46a8),LL(0xaebe8035,0xd218313d),LL(0xc73c51f8,0x92113ffd), + LL(0x12e7e46c,0x4b38e083),LL(0x56126bd5,0x69d0a37a),LL(0x73c07e04,0xfb3f324b),LL(0x8fda7267,0xa0c22f67), LL(0x4d2c7d8f,0x8f2c0051),LL(0xcbe2cae5,0xbc45ced3),LL(0xa8f0f277,0xe1c6cf07),LL(0x1eb99a98,0xbc392312), + LL(0x3cc8ac85,0x75537b7e),LL(0xdd02753b,0x8d725f57),LL(0xb737df2f,0xfd05ff64),LL(0xf6d2531d,0x55fe8712), LL(0x6ab6b01c,0x57ce04a9),LL(0x7cd93724,0x69a02a89),LL(0xcf86699b,0x4f82ac35),LL(0x9cb4b232,0x8242d3ad), + LL(0xd62105e5,0x713d0f65),LL(0x2d29be61,0xbb222bfa),LL(0x6cfbef09,0xf2f9a79e),LL(0xd5d6782f,0xfc24d8d3), LL(0xd4129967,0x5db77085),LL(0xdc3c2a43,0xdb81c3cc),LL(0x05d8d9a3,0x9d655fc0),LL(0x54298026,0x3f5d057a), + LL(0x88c54694,0x1157f56d),LL(0x9b09573e,0xb26baba5),LL(0x22adffd1,0x2cab03b0),LL(0xdd69f383,0x60a412c8), LL(0x54b25039,0xed76e98b),LL(0x687e714d,0xd4ee67d3),LL(0x7b00b594,0x87739648),LL(0xc9ef709b,0xce419775), + LL(0x1c203a40,0x40f76f85),LL(0xeafd8f91,0x30d352d6),LL(0x95578dd2,0xaf196d3d),LL(0x77cc3f3d,0xea4bb3d7), LL(0xb98e782b,0x42a5bd03),LL(0x0624920d,0xac958c40),LL(0xfc56fcc8,0xb838134c),LL(0x89572e5e,0x86ec4ccf), + LL(0x9be47be0,0x69c43526),LL(0xcb28fea1,0x323b7dd8),LL(0x3a6c67e5,0xfa5538ba),LL(0x1d378e46,0xef921d70), LL(0x3c4b880e,0xf92961fc),LL(0x98940a67,0x3f6f914e),LL(0xfef0ff39,0xa990eb0a),LL(0xf0eeff9c,0xa6c2920f), + LL(0x51b8d9a3,0xca804166),LL(0x0ffb0db1,0x42531bc9),LL(0xaa82e7ce,0x72ce4718),LL(0xdf574741,0x6e199913), LL(0xd5d36946,0xd5f1b13d),LL(0xf68f0194,0x8255dc65),LL(0x8710d230,0xdc9df4cd),LL(0x138c1988,0x3453c20f), + LL(0x89a6ef01,0x9af98dc0),LL(0x9857df85,0x4dbcc3f0),LL(0x5c1ad924,0x34805601),LL(0xd0493046,0x40448da5), LL(0x4ee343e2,0xf629926d),LL(0x90e8a301,0x6343f1bd),LL(0x40815b3f,0xefc93491),LL(0xde8f66fb,0xf882a423), + LL(0xe7db9f57,0x3a12d5f4),LL(0x3c384c27,0x7dfba38a),LL(0x6fc660b1,0x7a904bfd),LL(0x2773b21c,0xeb6c5db3), LL(0x1cdfe049,0xc350ee66),LL(0x44540f29,0x9baac0ce),LL(0xa5ec6aad,0xbc57b6ab),LL(0x0a7c1baa,0x167ce8c3), + LL(0x53fb2b56,0xb23a03a5),LL(0x4e057f78,0x6ce141e7),LL(0x89e490d9,0x796525c3),LL(0xa31a7e75,0x0bc95725), LL(0x1220fd06,0x1ec56791),LL(0x408b0bd6,0x716e3a3c),LL(0xe8ebeba9,0x31cd6bf7),LL(0xbee6b670,0xa7326ca6), + LL(0xcd090c43,0x3d9f851c),LL(0xf12c3988,0x561e8f13),LL(0x904b7be4,0x50490b6a),LL(0x0410737b,0x61690ce1), LL(0x0f009052,0x299e9a37),LL(0xf026092e,0x258758f0),LL(0xfdfcdc0f,0x9fa255f3),LL(0xc0e1bcd2,0xdbc9fb1f), + LL(0x24651840,0x35f9dd6e),LL(0xa5c59abc,0xdca45a84),LL(0xecca4938,0x103d396f),LL(0xb97b3f29,0x4532da0a), LL(0x1999a6bf,0xc4135ea5),LL(0x5e6bf2ee,0x3aa9505a),LL(0x3f5be093,0xf77cef06),LL(0xa943152e,0x97d1a0f8), + LL(0x2e1c21dd,0x2cb0ebba),LL(0x2c6797c4,0xf41b29fc),LL(0xb300101f,0xc6e17321),LL(0xd0d79a89,0x4422b0e9), LL(0x92f1bfc4,0x49e4901c),LL(0xe1e10ed9,0x06ab1f8f),LL(0xdb2926b8,0x84d35577),LL(0x356e8ec2,0xca349d39), + LL(0x343bf1a9,0x70b63d32),LL(0x37d1a6b1,0x8fd3bd28),LL(0x316865b4,0x0454879c),LL(0xc458efa2,0xee959ff6), LL(0x9706dc3f,0x0461dcf8),LL(0x164e4b2e,0x737db0e2),LL(0x2f8843c8,0x09262680),LL(0x7745e6f6,0x54498bbc), + LL(0xa29e24af,0x359473fa),LL(0x70aa87a1,0xfcc3c454),LL(0x00573ace,0xfd2c4bf5),LL(0x28dd1965,0xb65b514e), LL(0x2193e393,0xe46ae7cf),LL(0xf5444d97,0x60e9a4e1),LL(0x00ff38ed,0xe7594e96),LL(0x0a0e0f02,0x43d84d2f), + LL(0xee398a21,0x8b6db141),LL(0xe3bcc5be,0xb88a56ae),LL(0x373460ea,0x0a1aa52f),LL(0x160bb19b,0x20da1a56), LL(0x65bf0384,0xfb54999d),LL(0x5d5a180e,0x71a14d24),LL(0x21737b04,0xbc44db7b),LL(0x01dd8e92,0xd84fcb18), + LL(0xfa44b479,0x80de937b),LL(0x5c98fd4f,0x53505499),LL(0x28f08727,0x1edb12ab),LL(0xa5f3ef53,0x4c58b582), LL(0x8327f246,0xbfb236d8),LL(0x4d7df320,0xc3a3bfaa),LL(0xb96024f2,0xecd96c59),LL(0x7f4e0433,0xfc293a53), + LL(0x5acf6e10,0x5341352b),LL(0xafe652c3,0xc50343fd),LL(0x18577a7f,0x4af3792d),LL(0xaf16823d,0xe1a4c617), LL(0x33425d0a,0x9b26d0cd),LL(0x9b7bc47f,0x306399ed),LL(0x706bb20b,0x2a792f33),LL(0x98111055,0x31219614), + LL(0x87f5d28b,0x864ec064),LL(0x962277fd,0x11392d91),LL(0xbb6aed5f,0xb5aa7942),LL(0x47e799d9,0x080094dc), LL(0x208ba19b,0x4afa588c),LL(0x8512f284,0xd3e7570f),LL(0x02f5799a,0xcbae64e6),LL(0x514b9492,0xdeebe7ef), + LL(0xe5c298ff,0x30300f98),LL(0x3678361f,0x17f561be),LL(0x98cb9a16,0xf52ff312),LL(0x5562d490,0x6233c3bc), LL(0x92e3a2cb,0x7bfa15a1),LL(0xe6365119,0x961bcfd1),LL(0x2c8c53b1,0x3bdd29bf),LL(0x822844ba,0x739704df), + LL(0x7e7b754b,0x7dacfb58),LL(0xa806c9b9,0x23360791),LL(0x23504452,0xe7eb88c9),LL(0x852c1783,0x2983e996), LL(0x958d881d,0xdd4ae529),LL(0x262c7b3c,0x026bae03),LL(0x960b52d1,0x3a6f9193),LL(0x92696cfb,0xd0980f90), + LL(0xd5f30851,0x4c1f428c),LL(0x2a4f6630,0x94dfed27),LL(0xfc5d48a4,0x4df53772),LL(0x933260ce,0xdd2d5a2f), LL(0xd44cc7a5,0x574115bd),LL(0xbd12533a,0x4ba6b20d),LL(0x243057c9,0x30e93cb8),LL(0x14de320e,0x794c486a), + LL(0xf21496e4,0xe925d4ce),LL(0xec696331,0xf951d198),LL(0x3e8d812f,0x9810e2de),LL(0x389294ab,0xd0a47259), LL(0x0e3bab66,0x513ba2b5),LL(0xabad306f,0x462caff5),LL(0xaf04c49e,0xe2dc6d59),LL(0xe0b84b0b,0x1aeb8750), + LL(0x2f7d0ca2,0xc034f12f),LL(0xe06acf2f,0x6d2e8128),LL(0x21facc2f,0x801f4f83),LL(0xf40ef607,0xa1170c03), LL(0x7805a99c,0xfe0a1d4f),LL(0xcc26aba5,0xbde56a36),LL(0x35531f40,0x5b1629d0),LL(0x9afa6108,0xac212c2b), + LL(0x15697be5,0x30a06bf3),LL(0x2c63c7c1,0x6f0545dc),LL(0x7ccdadaf,0x5d8cb842),LL(0xac7015bb,0xd52e379b), LL(0xf462c23e,0xc4f56147),LL(0x46bc24b0,0xd44a4298),LL(0xe2856d4f,0xbc73d23a),LL(0x0832bcdf,0x61cedd8c), + LL(0x99f241d7,0x60953556),LL(0x001a349d,0xee4adbd7),LL(0xaa89e491,0x0b35bf6a),LL(0x136f7546,0x7f0076f4), LL(0x9264da3d,0xd19a18ba),LL(0x62a7a28b,0x6eb2d2cd),LL(0x8761c971,0xcdba941f),LL(0xa3be4a5d,0x1550518b), + LL(0x57d0b70c,0xd0e8e2f0),LL(0xcd133ba3,0xeea8612e),LL(0x44416aec,0x814670f0),LL(0x30775061,0x424db6c3), LL(0x16213fd1,0xd96039d1),LL(0x18a3478f,0xc61e7fa5),LL(0xcb0c5021,0xa805bdcc),LL(0x0cc616dd,0xbdd6f3a8), + LL(0x5d97f7e2,0x06009667),LL(0xaf0bf4b6,0x31db0fc1),LL(0x5491627a,0x23680ed4),LL(0x7d741fb1,0xb99a3c66), LL(0x36b1ff92,0xe9bb5f55),LL(0x512b388d,0x29738577),LL(0x50fcf263,0xdb8a2ce7),LL(0x6c4f7b47,0x385346d4), + LL(0x31631f9e,0xbe86c5ef),LL(0x03a57a29,0xbf91da21),LL(0x7b23f821,0xc3b1f796),LL(0x770db354,0x0f7d00d2), LL(0xd8fe79da,0x8ffc6c3b),LL(0xd525c996,0xcc5e8c40),LL(0xcfff632a,0x4640991d),LL(0x67112528,0x64d97e8c), + LL(0x02f1cd1e,0xc232d973),LL(0x1dd212a4,0xce87eacb),LL(0xe69802f7,0x6e4c8c73),LL(0x1fffddbd,0x12ef0290), LL(0x1bcea6e2,0x941ec74e),LL(0x3cb92cbb,0xd0b54024),LL(0x7e8f9d05,0x809fb9d4),LL(0xf2992aae,0x3bf16159), + LL(0xf8a7a838,0xad40f279),LL(0x05615660,0x11aea631),LL(0xa01f6fa1,0xbf52e6f1),LL(0x3dc2aec9,0xef046995), LL(0xd8080711,0x785dbec9),LL(0x9fdedf76,0xe1aec60a),LL(0xfa21c126,0xece797b5),LL(0x05e52732,0xc66e898f), + LL(0x08811fdb,0x39bb69c4),LL(0x2fc7f082,0x8bfe1ef8),LL(0x174f4138,0xc8e7a393),LL(0xd58d1f98,0xfba8ad1d), LL(0xbfd2fd5b,0xbc21d0ce),LL(0x6ee60d61,0x0b839a82),LL(0xafd22253,0xaacf7658),LL(0xaae396b3,0xb526bed8), + LL(0x38564464,0xccc1bbc2),LL(0x8c45bc73,0x9e3ff947),LL(0x58188a78,0xcde9bca3),LL(0xd73bf8f7,0x138b8ee0), LL(0x4123c489,0x5c7e234c),LL(0xfa643297,0x66e69368),LL(0x39a15fa3,0x0629eeee),LL(0xa9e2a927,0x95fab881), + LL(0xeafbb1e1,0xb2497007),LL(0xe75b7a93,0xd75c9ce6),LL(0xefb68d78,0x3558352d),LL(0x223f6396,0xa2f26699), LL(0xe469b17a,0xeb911ecf),LL(0xe72d3ec2,0x62545779),LL(0x82cb113f,0x8ea47de7),LL(0x4e1fa98d,0xebe4b086), + LL(0x8cdfedb1,0xec2d5ed7),LL(0xfe211a74,0xa535c077),LL(0x11d244c5,0x9678109b),LL(0xbe299a76,0xf17c8bfb), LL(0xfb11fbc4,0xb651412e),LL(0x94ab3f65,0xea0b5482),LL(0x0cf78243,0xd8dffd95),LL(0xce0361d4,0x2e719e57), + LL(0x304ddc5b,0x9007f085),LL(0x4daba2ea,0x095e8c6d),LL(0x3f9d28a9,0x5a33cdb4),LL(0xe2283003,0x85b95cd8), LL(0xb9744733,0xbcd6c819),LL(0xfc7f5783,0x29c5f538),LL(0xd59038e4,0x6c49b2fa),LL(0x3bbe1018,0x68349cc1), + LL(0x21830ee5,0xcc490c1d),LL(0xe9bfa297,0x36f9c4ee),LL(0x48de1a94,0x58fd7294),LL(0x4e8f2cdc,0xaadb13a8), LL(0x81313dba,0x515eaaa0),LL(0xc2152dd8,0xc76bb468),LL(0xa653dbf8,0x357f8d75),LL(0xb14ac143,0xe4d8c4d1), + LL(0xb055cb40,0xbdb8e675),LL(0x977b5167,0x898f8e7b),LL(0xb82fb863,0xecc65651),LL(0x6d88f01f,0x56544814), LL(0x263a75a9,0xb0928e95),LL(0x1a22fcda,0xcfb6836f),LL(0x3f3bd37c,0x651d14db),LL(0xb6ad4664,0x1d3837fb), + LL(0xff4f94ab,0x7c5fb538),LL(0x6d7fb8f2,0x7243c712),LL(0xa85c5287,0xef13d60c),LL(0x4bb8dd1b,0x18cfb7c7), LL(0x72908219,0x82f9bfe6),LL(0x9d5144ab,0x35c4592b),LL(0x9cf4b42f,0x52734f37),LL(0x8c60ddc4,0x6bac55e7), + LL(0x94dea0f6,0xb5cd811e),LL(0xe18cc1a3,0x259ecae4),LL(0x15e660f8,0x6a0e836e),LL(0x0e02bff2,0x6c639ea6), LL(0x7e1026fd,0x8721b8cb),LL(0x63261942,0x9e73b50b),LL(0x77f01da3,0xb8c70974),LL(0x8268f57f,0x1839e6a6), + LL(0x5150b805,0x571b9415),LL(0xf92c7097,0x1892389e),LL(0x4a084b95,0x8d69c18e),LL(0xbe5b495c,0x7014c512), LL(0x1b07523c,0x4780db36),LL(0x2c1c64fa,0x2f6219ce),LL(0x602c105a,0xc38b81b0),LL(0x5dc8e360,0xab4f4f20), + LL(0xcf7d62d2,0x20d3c982),LL(0x23ba8150,0x1f36e29d),LL(0x92763f9e,0x48ae0bf0),LL(0x1d3a7007,0x7a527e6b), LL(0x581a85e3,0xb4a89097),LL(0xdc158be5,0x1f1a520f),LL(0x167d726e,0xf98db37d),LL(0x1113e862,0x8802786e), +}, +/* digit=15 base_pwr=2^105 */ +{ + LL(0x36f09ab0,0xefb2149e),LL(0x4a10bb5b,0x03f163ca),LL(0x06e20998,0xd0297045),LL(0x1b5a3bab,0x56f0af00), LL(0x70880e0d,0x7af4cfec),LL(0xbe3d913f,0x7332a66f),LL(0x7eceb4bd,0x32e6c84a),LL(0x9c228f55,0xedc4a79a), + LL(0xc55c4496,0xc37c7dd0),LL(0x25bbabd2,0xa6a96357),LL(0xadd7f363,0x5b7e63f2),LL(0x2e73f1df,0x9dce3782), LL(0xb2b91f71,0xe1e5a16a),LL(0x5ba0163c,0xe4489823),LL(0xf6e515ad,0xf2759c32),LL(0x8615eecf,0xa5e2f1f8), + LL(0xabded551,0x74519be7),LL(0xc8b74410,0x03d358b8),LL(0x0e10d9a9,0x4d00b10b),LL(0x28da52b7,0x6392b0b1), LL(0x0b75c904,0x6744a298),LL(0xa8f7f96c,0xc305b0ae),LL(0x182cf932,0x042e421d),LL(0x9e4636ca,0xf6fc5d50), + LL(0xd64cc78c,0x795847c9),LL(0x9b6cb27b,0x6c50621b),LL(0xdf8022ab,0x07099bf8),LL(0xc04eda1d,0x48f862eb), LL(0xe1603c16,0xd12732ed),LL(0x5c9a9450,0x19a80e0f),LL(0xb429b4fc,0xe2257f54),LL(0x45460515,0x66d3b2c6), + LL(0x822e37be,0x6ca4f87e),LL(0x253bda4e,0x73f237b4),LL(0x41190aeb,0xf747f3a2),LL(0x804cf284,0xf06fa36f), LL(0xfc621c12,0x0a6bbb6e),LL(0x40b80ec6,0x5d624b64),LL(0x7ba556f3,0x4b072425),LL(0x3e2d20a8,0x7fa0c354), + LL(0xe3229d41,0xe921fa31),LL(0x94531bd4,0xa929c652),LL(0xa6d38209,0x84156027),LL(0x6bdb97bd,0xf3d69f73), LL(0x16833631,0x8906d19a),LL(0x03d51be3,0x68a34c2e),LL(0x0e511cd8,0xcb59583b),LL(0xfdc132a8,0x99ce6bfd), + LL(0xffcdb463,0x3facdaaa),LL(0x34a38b08,0x658bbc1a),LL(0xf1a9078d,0x12a801f8),LL(0x6ab855de,0x1567bcf9), LL(0x3572359b,0xe08498e0),LL(0x8659e68b,0xcf0353e5),LL(0x7d23807c,0xbb86e9c8),LL(0x2198e8a2,0xbc08728d), + LL(0x453cadd6,0x8de2b7bc),LL(0xbc0bc1f8,0x203900a7),LL(0xa6abd3af,0xbcd86e47),LL(0x8502effb,0x911cac12), LL(0xec965469,0x2d550242),LL(0x29e0017e,0x0e9f7692),LL(0x65979885,0x633f078f),LL(0x4cf751ef,0xfb87d449), + LL(0xfc25419a,0xe1790e4b),LL(0x4bff3cfd,0x36467203),LL(0x25b6e83f,0xc8db6386),LL(0x6cad6fd2,0x6cc69f23), LL(0x6bc68bb9,0x0219e45a),LL(0x297f7334,0xe43d79b6),LL(0x465dc97c,0x7d445368),LL(0x2a0b949a,0x4b9eea32), + LL(0x6102d021,0x1b96c6ba),LL(0x2f4461ea,0xeaafac78),LL(0xc49f19a8,0xd4b85c41),LL(0xcf538875,0x275c28e4), LL(0xdd2e54e0,0x35451a9d),LL(0x0605618b,0x6991adb5),LL(0x7b36cd24,0x5b8b4bcd),LL(0x56f37216,0x372a4f8c), + LL(0xa6a5da60,0xc890bd73),LL(0xdc4c9ff0,0x6f083da0),LL(0xf0536e57,0xf4e14d94),LL(0xaaec8243,0xf9ee1eda), LL(0x8bdcf8e7,0x571241ec),LL(0x0b041e26,0xa5db8271),LL(0xe3fff040,0x9a0b9a99),LL(0x7c271202,0xcaaf21dd), + LL(0x4f0dd2e8,0xb4e2b2e1),LL(0x0a377ac7,0xe77e7c4f),LL(0x0d7a2198,0x69202c3f),LL(0x28200eb8,0xf759b7ff), LL(0xdcfe314e,0xc87526ed),LL(0x53d5cf99,0xeb84c524),LL(0x515138b6,0xb1b52ace),LL(0x23fca3f4,0x5aa7ff8c), + LL(0xb9791a26,0xff0b13c3),LL(0xcdd58b16,0x960022da),LL(0x57aad2de,0xdbd55c92),LL(0xf30fe619,0x3baaaaa3), LL(0x0d881efd,0x9a4b2346),LL(0x46325e2a,0x506416c0),LL(0x035c18d4,0x91381e76),LL(0xf27817b0,0xb3bb68be), + LL(0x5116f937,0x15bfb8bf),LL(0xc1268943,0x7c64a586),LL(0x8419a2c8,0x71e25cc3),LL(0x8335f463,0x9fd6b0c4), LL(0xe8ee0e0e,0x4bf0ba3c),LL(0x298c21fa,0x6f6fba60),LL(0xae66bee0,0x57d57b39),LL(0x22672544,0x292d5130), + LL(0xbab093b3,0xf451105d),LL(0x02839986,0x012f59b9),LL(0x3474a89c,0x8a915802),LL(0x2de03e97,0x048c919c), LL(0x91071cd5,0xc476a2b5),LL(0x034970a5,0x791ed89a),LL(0xe1b7994b,0x89bd9042),LL(0xa1057ffd,0x8eaf5179), + LL(0xd551ee10,0x6066e2a2),LL(0x727e09a6,0x87a8f1d8),LL(0x2c01148d,0x00d08bab),LL(0x424f33fe,0x6da8e4f1), LL(0xcf9a4e71,0x466d17f0),LL(0x3bf5cb19,0xff502010),LL(0xd062ecc0,0xdccf97d8),LL(0x81d80ac4,0x80c0d9af), + LL(0x033f2876,0xe87771d8),LL(0x7d5cc3db,0xb0186ec6),LL(0x3bc9bc1d,0x58e8bb80),LL(0x6f6ef60e,0x4d1395cc), LL(0x186244a0,0xa73c62d6),LL(0x110a5b53,0x918e5f23),LL(0x741b7eab,0xed4878ca),LL(0xdbe03e51,0x3038d71a), + LL(0xa93c3246,0x840204b7),LL(0xa0b9b4cd,0x21ab6069),LL(0xb1d64218,0xf5fa6e2b),LL(0xf3d56191,0x1de6ad0e), LL(0xff1929c7,0x570aaa88),LL(0x640e87b5,0xc6df4c6b),LL(0xc65f0ccc,0xde8a74f2),LL(0xe6f6cc01,0x8b972fd5), + LL(0x0b846531,0x3fff36b6),LL(0x10a5e475,0xba7e45e6),LL(0x4145b6c5,0x84a1d10e),LL(0x5e046d9d,0xf1f7f91a), LL(0x44de90d7,0x0317a692),LL(0xf199c15e,0x951a1d4a),LL(0xc9d73deb,0x91f78046),LL(0xfab8224f,0x74c82828), + LL(0xe7560b90,0xaa6778fc),LL(0xa7e824ce,0xb4073e61),LL(0xd642eba8,0xff0d693c),LL(0x5dccef38,0x7ce2e57a), LL(0x1df1ad46,0x89c2c789),LL(0x098346fd,0x83a06922),LL(0xda2fc177,0x2d715d72),LL(0x85b6cf1d,0x7b6dd71d), + LL(0x73fa9cb0,0xc60a6d0a),LL(0x328bf5a9,0xedd3992e),LL(0x832c8c82,0xc380ddd0),LL(0xa2a0bf50,0xd182d410), LL(0xd9a528db,0x7d9d7438),LL(0xcaf53994,0xe8b1a0e9),LL(0x0e19987c,0xddd6e5fe),LL(0x190b059d,0xacb8df03), + LL(0x8300129f,0x53703a32),LL(0x68c43bfd,0x1f637662),LL(0x00e54051,0xbcbd1913),LL(0x7bf5a8c5,0x812fcc62), LL(0x29fb85da,0x3f969d5f),LL(0x694759e8,0x72f4e00a),LL(0x790726b7,0x426b6e52),LL(0x3bdbb209,0x617bbc87), + LL(0x97aee317,0x511f8bb9),LL(0xe81536a8,0x812a4096),LL(0x3ac09b9b,0x137dfe59),LL(0xba8c9a7a,0x0682238f), LL(0xaeccb4bd,0x7072ead6),LL(0x692ba633,0x6a34e9aa),LL(0x6fff9d33,0xc82eaec2),LL(0x1d4d2b62,0xfb753512), + LL(0x1d7aadab,0x1a0445ff),LL(0xd5f6a67c,0x65d38260),LL(0x91cfb26f,0x6e62fb08),LL(0x5c7d91d6,0xef1e0fa5), LL(0x33db72cd,0x47e7c7ba),LL(0xfa7c74b2,0x017cbc09),LL(0xf50a503c,0x3c931590),LL(0x616baa42,0xcac54f60), + LL(0xb2369f0f,0x9b6cd380),LL(0x23c76151,0x97d3a70d),LL(0x9862a9c6,0x5f9dd6fc),LL(0x12312f51,0x044c4ab2), LL(0x834a2ddc,0x035ea0fd),LL(0xcc7b826d,0x49e6b862),LL(0x62fce490,0xb03d6883),LL(0xb37e36e9,0x62f2497a), + LL(0xc6458293,0x04b005b6),LL(0xe8d10af7,0x36bb5276),LL(0x8ee617b8,0xacf2dc13),LL(0xb004b3d4,0x470d2d35), LL(0xfeeb1b77,0x06790832),LL(0x85657f9c,0x2bb75c39),LL(0xc0f60004,0xd70bd4ed),LL(0x219b018b,0xfe797ecc), + LL(0x753aebcc,0x9b5bec2a),LL(0xc939eca5,0xdaf9f3dc),LL(0xd095ad09,0xd6bc6833),LL(0xdaa4d2fc,0x98abdd51), LL(0x8d168be5,0xd9840a31),LL(0x2325a23c,0xcf7c10e0),LL(0x7e6ecfaf,0xa5c02aa0),LL(0xb5bfdf18,0x2462e7e6), + LL(0xa0cc3f12,0xab2d8a8b),LL(0xbc672a29,0x68dd485d),LL(0x596f2cd3,0x72039752),LL(0xa0cf3d8d,0x5d3eea67), LL(0xe6602671,0x810a1a81),LL(0x14026c0c,0x8f144a40),LL(0x76b50f85,0xbc753a6d),LL(0x645cd4a4,0xc4dc21e8), + LL(0x521d0378,0xc5262dea),LL(0x05011c6f,0x802b8e0e),LL(0x0b4c19ea,0x1ba19cbb),LL(0xebf0aaec,0x21db64b5), LL(0x70342f9d,0x1f394ee9),LL(0x1bc44a14,0x93a10aee),LL(0x3efd0baa,0xa7eed31b),LL(0x1d154e65,0x6e7c824e), + LL(0x9966e7ee,0xee23fa81),LL(0x05b7920d,0x64ec4aa8),LL(0x2d90aad4,0x2d44462d),LL(0xdf277ad5,0xf44dd195), LL(0xbb46b6a1,0x8d6471f1),LL(0xfd885090,0x1e65d313),LL(0x13a977b4,0x33a800f5),LL(0x0797e1ef,0xaca9d721), + LL(0xfcff6a17,0x9a5a85a0),LL(0x1eca7cee,0x9970a3f3),LL(0xc9504be3,0xbb9f0d6b),LL(0xadd24ee2,0xe0c504be), LL(0x77fcc2f4,0x7e09d956),LL(0x65bb5fc4,0xef1a5227),LL(0x8b9286aa,0x145d4fb1),LL(0x6649028b,0x66fd0c5d), + LL(0x1bf4581c,0x98857ceb),LL(0xaca7b166,0xe635e186),LL(0x659722ac,0x278ddd22),LL(0x1db68007,0xa0903c4c), LL(0x48f21402,0x366e4589),LL(0xb96abda2,0x31b49c14),LL(0xe0403190,0x329c4b09),LL(0xd29f43fe,0x97197ca3), + LL(0x274983d8,0x8073dd1e),LL(0x55717c8f,0xda1a3bde),LL(0x0361f9d1,0xfd3d4da2),LL(0x4c7de1ce,0x1332d081), LL(0xaa6d0e10,0x9b7ef7a3),LL(0xf54f1c4a,0x17db2e73),LL(0x4cd35567,0xaf3dffae),LL(0xe56f4e71,0xaaa2f406), + LL(0x7ace3fc7,0x8966759e),LL(0x45a8d8c6,0x9594eacf),LL(0x91834e0e,0x8de3bd8b),LL(0x548c0421,0xafe4ca53), LL(0xe6ee81c6,0xfdd7e856),LL(0x6b891a3a,0x8f671beb),LL(0xfae63829,0xf7a58f2b),LL(0x9c11ac9f,0x9ab186fb), + LL(0x10b5be76,0x8d6eb369),LL(0xfb040bcd,0x046b7739),LL(0xcb73de88,0xccb4529f),LL(0xcf26be03,0x1df0fefc), LL(0xbcfcd027,0xad7757a6),LL(0xbb3165ca,0xa8786c75),LL(0x7e99a4d9,0xe9db1e34),LL(0xb06c504b,0x99ee86df), + LL(0xc15c9f0a,0x5b7c2ddd),LL(0x4295989e,0xdf87a734),LL(0x03d08fda,0x59ece47c),LL(0xad5fc702,0xb074d3dd), LL(0x51a03776,0x20407903),LL(0x2a608007,0x2bb1f77b),LL(0xe1153185,0x25c58f4f),LL(0x766e6447,0xe6df62f6), + LL(0xed51275a,0xefb3d1be),LL(0x2f0f483f,0x5de47dc7),LL(0x97c2bedf,0x7932d98e),LL(0x0219f8a1,0xd5c11927), LL(0xa73a294e,0x9d751200),LL(0x9dc20172,0x5f88434a),LL(0xa26f506a,0xd28d9fd3),LL(0x9d1dcd48,0xa890cd31), + LL(0x70f4d3b4,0x0aebaec1),LL(0x0ffc8d00,0xfd1a1369),LL(0x57d57838,0xb9d9c240),LL(0x68bac361,0x45929d26), LL(0x25b15ca6,0x5a2cd060),LL(0x6e474446,0x4b3c83e1),LL(0xee1e5134,0x1aac7578),LL(0xc91e2f41,0xa418f5d6), + LL(0x213ed68b,0x6936fc8a),LL(0x510a5224,0x860ae7ed),LL(0xdef09b53,0x63660335),LL(0xcd79c98d,0x641b2897), LL(0x01110f35,0x29bd38e1),LL(0x648b1937,0x79c26f42),LL(0x9d9164f4,0x64dae519),LL(0x0265c273,0xd85a2310), + LL(0x4b07e2b1,0x7173dd5d),LL(0x8d9ea221,0xd144c4cb),LL(0x1105ab14,0xe8b04ea4),LL(0xfe80d8f1,0x92dda542), LL(0xcf03dce6,0xe9982fa8),LL(0x1a22cffc,0x8b5ea965),LL(0x3fad88c4,0xf7f4ea7f),LL(0x6a5ba95c,0x62db773e), + LL(0x93f24567,0xd20f02fb),LL(0x315257ca,0xfd46c69a),LL(0x8bcab987,0x0ac74cc7),LL(0x5ceca2f5,0x46f31c01), LL(0x888b219e,0x40aedb59),LL(0xe1fccd02,0xe50ecc37),LL(0x911f816c,0x1bcd9dad),LL(0x8db9b00c,0x583cc1ec), + LL(0xa483bf11,0xf3cd2e66),LL(0xb1b2c169,0xfa08a6f5),LL(0x4be9fa28,0xf375e245),LL(0x5b6d011f,0x99a7ffec), LL(0xc4ae62da,0x6a3ebddb),LL(0x374aef5d,0x6cea00ae),LL(0x9d4d05bc,0xab5fb98d),LL(0xd560f252,0x7cba1423), + LL(0x208490de,0x49b2cc21),LL(0xbcfb2879,0x1ca66ec3),LL(0x1b6fb16f,0x7f1166b7),LL(0x65fe5db3,0xfff63e08), LL(0x8b2610be,0xb8345abe),LL(0x39de3df4,0xb732ed80),LL(0x211c32b4,0x0e24ed50),LL(0x848ff27d,0xd10d8a69), + LL(0xed4de248,0xc1074398),LL(0x10488927,0xd7cedace),LL(0x85673e13,0xa4aa6bf8),LL(0x6daf30af,0xb46bae91), LL(0xfcef7ad8,0x07088472),LL(0xd4b35e97,0x61151608),LL(0xdde29986,0xbcfe8f26),LL(0xd5a34c79,0xeb84c4c7), + LL(0x164e1214,0xc1eec55c),LL(0xa147bb03,0x891be86d),LL(0x0ba96835,0x9fab4d10),LL(0xa5c1ae9f,0xbf01e9b8), LL(0xb186ebc0,0x6b4de139),LL(0x85b91bca,0xd5c74c26),LL(0xc2d93854,0x5086a99c),LL(0xa7a9dfbc,0xeed62a7b), + LL(0x76b7618a,0x8778ed6f),LL(0x03b66062,0xbff750a5),LL(0xb65186db,0x4cb7be22),LL(0xcc3a6d13,0x369dfbf0), LL(0x7191a321,0xc7dab26c),LL(0x40ed718e,0x9edac3f9),LL(0xd0cfd183,0xbc142b36),LL(0x7c991693,0xc8af82f6), + LL(0x97ce0b2a,0xb3d1e4d8),LL(0xc3a55cdf,0xe6d7c87f),LL(0x68b81afe,0x35846b95),LL(0xd3c239d8,0x018d12af), LL(0x01206e15,0x2b2c6208),LL(0xa3b882c6,0xe0e42453),LL(0xa50162d5,0x854470a3),LL(0x7017a62a,0x08157478), + LL(0x820357c7,0x18bd3fb4),LL(0x6f1458ad,0x992039ae),LL(0x25b44aa1,0x9a1df3c5),LL(0xed3d5281,0x2d780357), LL(0xc77ad4d4,0x58cf7e4d),LL(0xf9df4fc4,0xd49a7998),LL(0x1d71205e,0x4465a8b5),LL(0x649254aa,0xa0ee0ea6), + LL(0xab7bd771,0x4b5eeecf),LL(0x35c262b9,0x6c873073),LL(0x3c9d61e7,0xdc5bd648),LL(0x321460d2,0x233d6d54), LL(0xfc195bcc,0xd20c5626),LL(0x04d78b63,0x25445958),LL(0x17ec8ef3,0xe03fcb3d),LL(0x46b8f781,0x54b690d1), + LL(0x21230646,0x82fa2c8a),LL(0x084f418c,0xf51aabb9),LL(0x1a30ba43,0xff4fbec1),LL(0x743c9df7,0x6a5acf73), LL(0xd635b4d5,0x1da2b357),LL(0xecd5c1da,0xc3de68dd),LL(0xd61af0dd,0xa689080b),LL(0xd665bf99,0xdea5938a), + LL(0xfe637294,0x0231d71a),LL(0xa5a81cd8,0x01968aa6),LL(0x048e63b5,0x11252d50),LL(0x6ca007e9,0xc446bc52), LL(0x96d6134b,0xef8c50a6),LL(0x9e09a05c,0x9361fbf5),LL(0xdca3291a,0xf17f85a6),LL(0xff251a21,0xb178d548), + LL(0xa4df3915,0x87f6374b),LL(0x2fd5d608,0x566ce1bf),LL(0x7de35102,0x425cba4d),LL(0x58c5d5e2,0x6b745f8f), LL(0x63122edf,0x88402af6),LL(0x3b989a89,0x3190f9ed),LL(0xebba3156,0x4ad3d387),LL(0xc7c469a5,0xef385ad9), + LL(0x3f642c29,0xb08281de),LL(0x910ffb88,0x20be0888),LL(0xd5292546,0xf353dd4a),LL(0x8377a262,0x3f1627de), LL(0xeefcd638,0xa5faa013),LL(0x74cc77c3,0x8f3bf626),LL(0xa348f55e,0x32618f65),LL(0x9fefeb9e,0x5787c0dc), + LL(0xd9a23e44,0xf1673aa2),LL(0x4e10690d,0x88dfa993),LL(0x2bf91108,0x1ced1b36),LL(0x3af48649,0x9193ceca), LL(0x2d738fc5,0xfb34327d),LL(0x975fee6c,0x6697b037),LL(0xc04079a5,0x2f485da0),LL(0x2feaa1ac,0x2cdf5735), + LL(0xbd55659e,0x76944420),LL(0x4376090c,0x7973e32b),LL(0x163b591a,0x86bb4fe1),LL(0xc196f0ca,0x10441aed), LL(0x045ad915,0x3b431f4a),LL(0xa4afacb1,0x6c11b437),LL(0x71fdbbd8,0x30b0c7db),LL(0xeda65acd,0xb642931f), + LL(0x9c92b235,0x4baae6e8),LL(0x6b3993a1,0xa73bbd0e),LL(0x693dd031,0xd06d60ec),LL(0x7156881c,0x03cab91b), LL(0x1db3574b,0xd615862f),LL(0x64bb061a,0x485b0185),LL(0xa0181e06,0x27434988),LL(0xc1c0c757,0x2cd61ad4), + LL(0x2ff9f403,0x3effed5a),LL(0x62239029,0x8dc98d8b),LL(0x1f17b70d,0x2206021e),LL(0xbf510015,0xafbec0ca), LL(0x80130dfa,0x9fed7164),LL(0x8a02dcf5,0x306dc2b5),LL(0xfeb10fc0,0x48f06620),LL(0x5a57cf51,0x78d1e1d5), + LL(0x192ef710,0xadef8c5a),LL(0x3b7431f9,0x88afbd4b),LL(0x64250c9e,0x7e1f7407),LL(0xb58bec07,0x6e31318d), LL(0x24f89b4e,0xfd4fc4b8),LL(0x48c36a2a,0x65a5dd88),LL(0xf024baa7,0x4f1eccff),LL(0xcba94650,0x22a21cf2), + LL(0x42a554f7,0x95d29dee),LL(0x002ec4ba,0x828983a5),LL(0x8badb73d,0x8112a1f7),LL(0xa27c1839,0x79ea8897), LL(0xd065fd83,0x8969a5a7),LL(0xb262a0bc,0xf49af791),LL(0xaf2b5127,0xfcdea8b6),LL(0x564c2dbc,0x10e913e1), + LL(0xbc21ef51,0x51239d14),LL(0x4ce57292,0xe51c3ceb),LL(0x47bbcc3b,0x795ff068),LL(0xbd7e11e6,0x86b46e1e), LL(0x80041ef4,0x0ea6ba23),LL(0x6262342e,0xd72fe505),LL(0x31d294d4,0x8abc6dfd),LL(0x1278c2c9,0xbbe017a2), + LL(0xb389328a,0xb1fcfa09),LL(0xd01771b5,0x322fbc62),LL(0x60b045bf,0x04c0d063),LL(0x10e52d01,0xdb652edc), LL(0x03ec6627,0x50ef932c),LL(0xc1ee50e3,0xde1b3b2d),LL(0xdc37a90d,0x5ab7bdc5),LL(0x31e33a96,0xfea67213), + LL(0x4f2999aa,0x6482b5cb),LL(0xb8cbf0dd,0x38476cc6),LL(0x173405bb,0x93ebfacb),LL(0xe52369ec,0x15cdafe7), LL(0xd935b7db,0xd42d5ba4),LL(0x1c99a4cd,0x648b6004),LL(0xa3b5545b,0x785101bd),LL(0x9dd67faf,0x4bf2c38a), + LL(0x4442449c,0xb1aadc63),LL(0x33ad4fb8,0xe0e9921a),LL(0xaa686d82,0x5c552313),LL(0x465d866c,0xdee635fa), LL(0x18ee6e8a,0xbc3c224a),LL(0xed42e02f,0xeed748a6),LL(0xd474cd08,0xe70f930a),LL(0xfff24adf,0x774ea6ec), + LL(0xf3480d4a,0x03e2de1c),LL(0xbc8acf1a,0xf0d8edc7),LL(0x68295a9c,0xf23e3303),LL(0xc546a97d,0xfadd5f68), LL(0x96f8acb1,0x895597ad),LL(0x671bdae2,0xbddd49d5),LL(0x21dd43f4,0x16fcd528),LL(0x6619141a,0xa5a45412), +}, +/* digit=16 base_pwr=2^112 */ +{ + LL(0xc360e25a,0x8ce9b6bf),LL(0x075a1a78,0xe6425195),LL(0x481732f4,0x9dc756a8),LL(0x5432b57a,0x83c0440f), LL(0xd720281f,0xc670b3f1),LL(0xd135e051,0x2205910e),LL(0xdb052be7,0xded14b0e),LL(0xc568ea39,0x697b3d27), + LL(0xfb3ff9ed,0x2e599b9a),LL(0x17f6515c,0x28c2e0ab),LL(0x474da449,0x1cbee4fd),LL(0x4f364452,0x071279a4), LL(0x01fbe855,0x97abff66),LL(0x5fda51c4,0x3ee394e8),LL(0x67597c0b,0x190385f6),LL(0xa27ee34b,0x6e9fccc6), + LL(0x14092ebb,0x0b89de93),LL(0x428e240c,0xf17256bd),LL(0x93d2f064,0xcf89a7f3),LL(0xe1ed3b14,0x4f57841e), LL(0xe708d855,0x4ee14405),LL(0x03f1c3d0,0x856aae72),LL(0xbdd7eed5,0xc8e5424f),LL(0x73ab4270,0x3333e4ef), + LL(0xdda492f8,0x3bc77ade),LL(0x78297205,0xc11a3aea),LL(0x34931b4c,0x5e89a3e7),LL(0x9f5694bb,0x17512e2e), LL(0x177bf8b6,0x5dc349f3),LL(0x08c7ff3e,0x232ea4ba),LL(0xf511145d,0x9c4f9d16),LL(0x33b379c3,0xccf109a3), + LL(0xa1f25897,0xe75e7a88),LL(0xa1b5d4d8,0x7ac6961f),LL(0x08f3ed5c,0xe3e10773),LL(0x0a892dfb,0x208a54ec), LL(0x78660710,0xbe826e19),LL(0x237df2c8,0x0cf70a97),LL(0xed704da5,0x418a7340),LL(0x08ca33fd,0xa3eeb9a9), + LL(0x169bca96,0x49d96233),LL(0x2da6aafb,0x04d286d4),LL(0xa0c2fa94,0xc09606ec),LL(0x23ff0fb3,0x8869d0d5), LL(0xd0150d65,0xa99937e5),LL(0x240c14c9,0xa92e2503),LL(0x108e2d49,0x656bf945),LL(0xa2f59e2b,0x152a733a), + LL(0x8434a920,0xb4323d58),LL(0x622103c5,0xc0af8e93),LL(0x938dbf9a,0x667518ef),LL(0x83a9cdf2,0xa1843073), LL(0x5447ab80,0x350a94aa),LL(0xc75a3d61,0xe5e5a325),LL(0x68411a9e,0x74ba507f),LL(0x594f70c5,0x10581fc1), + LL(0x80eb24a9,0x60e28570),LL(0x488e0cfd,0x7bedfb4d),LL(0xc259cdb8,0x721ebbd7),LL(0xbc6390a9,0x0b0da855), LL(0xde314c70,0x2b4d04db),LL(0x6c32e846,0xcdbf1fbc),LL(0xb162fc9e,0x33833eab),LL(0xb0dd3ab7,0x9939b48b), + LL(0xcb0c9c8c,0x5aaa98a7),LL(0x81c4375c,0x75105f30),LL(0x5ef1c90f,0xceee5057),LL(0xc23a17bf,0xb31e065f), LL(0xd4b6d45a,0x5364d275),LL(0x62ec8996,0xd363f3ad),LL(0x4391c65b,0xb5d21239),LL(0xebb41b47,0x84564765), + LL(0x37107c78,0x20d18ecc),LL(0x570c2a66,0xacff3b6b),LL(0x9bd0d845,0x22f975d9),LL(0xba178fa0,0xef0a0c46), LL(0x76b6028e,0x1a419651),LL(0x248612d4,0xc49ec674),LL(0x7338af55,0x5b6ac4f2),LL(0x7bee5a36,0x06145e62), + LL(0xe75746b5,0x33e95d07),LL(0xc40c78be,0x1c1e1f6d),LL(0x222ff8e2,0x967833ef),LL(0xb49180ad,0x4bedcf6a), LL(0x3d7a4c8a,0x6b37e9c1),LL(0x6ddfe760,0x2748887c),LL(0xaa3a5bbc,0xf7055123),LL(0x7bbb8e74,0x954ff225), + LL(0x97c3dfb9,0xc42b8ab1),LL(0xcf168154,0x55a549b0),LL(0xc1b50692,0xad6748e7),LL(0x6fc5cbcb,0x2775780f), LL(0xe1c9d7c8,0x4eab80b8),LL(0x3fdbcd56,0x8c69dae1),LL(0x9969eace,0x47e6b4fb),LL(0xa705cb5a,0x002f1085), + LL(0x6d3fea55,0x4e23ca44),LL(0xf4810568,0xb4ae9c86),LL(0x2a62f27d,0x47bfb91b),LL(0xd9bac28c,0x60deb4c9), LL(0x7de6c34c,0xa892d894),LL(0x4494587d,0x4ee68259),LL(0x1a3f8a5b,0x914ee14e),LL(0x28700385,0xbb113eaa), + LL(0x2115b4c9,0x81ca03b9),LL(0x8908cad1,0x7c163d38),LL(0xaa18179a,0xc912a118),LL(0x886e3081,0xe09ed750), LL(0x26f516ca,0xa676e3fa),LL(0x8e732f91,0x753cacf7),LL(0x833da8b4,0x51592aea),LL(0x4cbea8aa,0xc626f42f), + LL(0xa7b56eaf,0xef9dc899),LL(0x34ef7316,0x00c0e52c),LL(0xfe818a86,0x5b1e4e24),LL(0xc538be47,0x9d31e20d), LL(0x3ed68974,0x22eb932d),LL(0x7c4e87c4,0xe44bbc08),LL(0x0dde9aef,0x4121086e),LL(0x134f4345,0x8e6b9cff), + LL(0x711b0eb9,0x96892c1f),LL(0x780ab954,0xb905f2c8),LL(0xa20792db,0xace26309),LL(0x0684e126,0xec8ac9b3), LL(0xb40a2447,0x486ad8b6),LL(0x9fe3fb24,0x60121fc1),LL(0x1a8e3b3f,0x5626fccf),LL(0x6ad1f394,0x4e568622), + LL(0x196aa5a1,0xda7aae0d),LL(0x1041b5fb,0xe0df8c77),LL(0x26b318b7,0x451465d9),LL(0x7ab136e9,0xc29b6e55), LL(0x71148463,0x2c2ab48b),LL(0x64454a76,0xb5738de3),LL(0x5a03abe4,0x54ccf9a0),LL(0x0427d58e,0x377c0296), + LL(0x2bb39c1f,0x73f5f0b9),LL(0xe608d8c5,0x14373f2c),LL(0x00fbb805,0xdcbfd314),LL(0x83afdcfb,0xdf18fb20), LL(0x42b3523f,0x81a57f42),LL(0x87f650fb,0xe958532d),LL(0x8b0a7d7c,0xaa8dc8b6),LL(0x150166be,0x1b75dfb7), + LL(0x2d7d1413,0x90e4f7c9),LL(0x9834f597,0x67e2d6b5),LL(0xa808c3e8,0x4fd4f4f9),LL(0xd5281ec1,0xaf8237e0), LL(0x84687cee,0x25ab5fdc),LL(0xa5b26c09,0xc5ded6b1),LL(0xc8ea7650,0x8e4a5aec),LL(0x14cc417f,0x23b73e5c), + LL(0x3037bf52,0x2bfb4318),LL(0x78c725d7,0xb61e6db5),LL(0xbbb3e5d7,0x8efd4060),LL(0xdbac488e,0x2e014701), LL(0x360aa449,0xac75cf9a),LL(0x79634d08,0xb70cfd05),LL(0xfffb15ef,0xa591536d),LL(0xd07c106c,0xb2c37582), + LL(0xf50225f9,0xb4293fdc),LL(0xb0e12b03,0xc52e175c),LL(0xd0a8bf64,0xf649c3ba),LL(0xeb8ae3c6,0x745a8fef), LL(0x58321bc3,0x30d7e5a3),LL(0x0bc4df48,0xb1732be7),LL(0xe9ea5058,0x1f217993),LL(0x3e4fd745,0xf7a71cde), + LL(0x894c5bbb,0x86cc533e),LL(0x69d83082,0x6915c7d9),LL(0x5815c244,0xa6aa2d05),LL(0x49b22ce5,0xaeeee592), LL(0x78135486,0x89e39d13),LL(0x16b76f2f,0x3a275c1f),LL(0xe036e8f5,0xdb6bcc1b),LL(0x5e4709f5,0x4df69b21), + LL(0x2d0f39aa,0xa188b250),LL(0x15a85947,0x622118bb),LL(0xfde0f4fa,0x2ebf520f),LL(0x4860e539,0xa40e9f29), LL(0x22b57f0f,0x7b6a51eb),LL(0x7e80644a,0x849a33b9),LL(0x1cf095fe,0x50e5d16f),LL(0xec55f002,0xd754b54e), + LL(0x236f4a98,0x5cfbbb22),LL(0x066800bb,0x0b0c59e9),LL(0x5a9a7774,0x4ac69a8f),LL(0xd6bec948,0x2b33f804), LL(0x32e6c466,0xb3729295),LL(0x4e599c73,0x68956d0f),LL(0x155c31cc,0xa47a249f),LL(0xe1ce284e,0x24d80f0d), + LL(0x988baf01,0xcd821dfb),LL(0xdbb16647,0xe6331a7d),LL(0x094cb960,0x1eb8ad33),LL(0xc91bbca5,0x593cca38), LL(0x26567456,0x384aac8d),LL(0xc04b6490,0x40fa0309),LL(0xdab6c8f6,0x97834cd6),LL(0x3f91e55f,0x68a7318d), + LL(0xfc4d3157,0xa00fd04e),LL(0x2bf3bdea,0xb56f8ab2),LL(0x4fa57172,0x014f5648),LL(0x450abdb3,0x948c5860), LL(0x0ebd4f08,0x342b5df0),LL(0x0e82938e,0x3e5168cd),LL(0xb0df5dd0,0x7aedc1ce),LL(0xe5732516,0x6bbbc6d9), + LL(0x605daaa6,0xc7bfd486),LL(0xbb9a6c9e,0x46fd72b7),LL(0xa124fb89,0xe4847fb1),LL(0xa2d8ffbc,0x75959cbd), LL(0xc8a588ee,0x42579f65),LL(0xb80b499d,0x368c92e6),LL(0x999a5df1,0xea4ef6cd),LL(0x936fe604,0xaa73bb7f), + LL(0x6457d188,0xf347a70d),LL(0x8b7a388b,0x86eda86b),LL(0x0ccd6013,0xb7cdff06),LL(0xd0053fb2,0xbeb1b6c7), LL(0x99240a9f,0x0b022387),LL(0x776189b2,0x1bbb384f),LL(0x9066193a,0x8695e71e),LL(0x06ffac7e,0x2eb50097), + LL(0x4a7d2caa,0x0654a9c0),LL(0xa5aaa290,0x6f3fb3d1),LL(0xff476e8f,0x835db041),LL(0xc42295e4,0x540b8b0b), LL(0x05e214f5,0xa5c73ac9),LL(0x56a0b638,0x9a74075a),LL(0xce9e680b,0x2e4b1090),LL(0x6b8d9afa,0x57a5b479), + LL(0x26bfe65c,0x0dca48e7),LL(0x7290c307,0x097e391c),LL(0x6669e72e,0x683c462e),LL(0x062559ac,0xf505be1e), LL(0xe3a3035a,0x5fbe3ea1),LL(0x9cd50da8,0x6431ebf6),LL(0x1f6407f2,0xfd169d5c),LL(0x60fce6b8,0x8d838a95), + LL(0x650006f0,0x2a2bfa7f),LL(0x50c0fbb2,0xdfd7dad3),LL(0xccf9ad96,0x92452495),LL(0xd95635f9,0x183bf494), LL(0x4a7bd989,0x02d5df43),LL(0xa5431095,0x505385cc),LL(0xfd43f53e,0xdd98e67d),LL(0x500c34a9,0xd61e1a6c), + LL(0x4a8a3d62,0x5a4b46c6),LL(0x247743d2,0x8469c4d0),LL(0x88f7e433,0x2bb3a13d),LL(0x01be5849,0x62b23a10), LL(0xa63d1a4c,0xe83596b4),LL(0x7d183f3e,0x454e7fea),LL(0x17afb01c,0x643fce61),LL(0x1c4c3638,0x4e65e5e6), + LL(0xef74c45b,0x41d85ea1),LL(0xae328506,0x2cfbfa66),LL(0x3ada7da9,0x98b078f5),LL(0xec752fbb,0xd985fe37), LL(0x5a0148b4,0xeece68fe),LL(0x2d78136d,0x6f9a55c7),LL(0xd2b729ce,0x232dccc4),LL(0x90aafbc4,0xa27e0dfd), + LL(0x12b4603e,0x96474452),LL(0x6b706d14,0xa876c551),LL(0x69a9d412,0xdf145fcf),LL(0x2d479c34,0xe2ab75b7), LL(0x1a23ff97,0x12df9a76),LL(0x5d359d10,0xc6138992),LL(0xfa835f22,0x6e51c7ae),LL(0xc0fcc4d9,0x69a79cb1), + LL(0x594cc7e1,0xf57f350d),LL(0x3350ab79,0x3079ca63),LL(0x9aff594a,0x226fb614),LL(0x6d59a62b,0x35afec02), LL(0x06ed2c6e,0x9bee46f4),LL(0x7d939a57,0x58da1735),LL(0x8fd1797e,0x44c50402),LL(0x5ccea6ca,0xd8853e7c), + LL(0xa35fcd5f,0x4065508d),LL(0x495ccaeb,0x8965df8c),LL(0x12e1a962,0x0f2da850),LL(0xc1cf1cc4,0xee471b94), LL(0x0a08fb75,0xcef19bc8),LL(0x81de3591,0x704958f5),LL(0x3aef4f88,0x2867f8b2),LL(0xea9f9a5f,0x8d749384), + LL(0x8c9049f4,0x1b385537),LL(0x7b92d8b6,0x5be948f3),LL(0xb6e2bd6b,0xd96f725d),LL(0x958c454d,0x37a222bc), LL(0x8809bf61,0xe7c61abb),LL(0x1346f18d,0x46f07fbc),LL(0xe87c0d1c,0xfb567a7a),LL(0x7ef3d07a,0x84a461c8), + LL(0xd9278d98,0x0a5adce6),LL(0x9dfc73e1,0x24d94813),LL(0x054321c3,0x4f3528b6),LL(0x692ea706,0x2e03fdde), LL(0x47b533c0,0x10e60619),LL(0x2ca3c055,0x1a8bc73f),LL(0x1bb62b8f,0xae58d4b2),LL(0x584a24e3,0xb2045a73), + LL(0xbd76e195,0x3ab3d5af),LL(0x6938a810,0x478dd1ad),LL(0x6ee3d5cb,0x6ffab393),LL(0x22b361e4,0xdfb693db), LL(0x51dbf1a7,0xf9694496),LL(0x08a2e762,0xcab4b4ef),LL(0xd39bba9a,0xe8c92f25),LL(0xf1464d96,0x850e61bc), + LL(0xdc09508b,0xb7e830e3),LL(0x74317655,0xfaf6d2cf),LL(0xdf690355,0x72606ceb),LL(0xd0c3ded6,0x48bb92b3), LL(0x5c7cf892,0x65b75484),LL(0xd5d5f01f,0xf6cd7ac9),LL(0x96401d69,0xc2c30a59),LL(0xed921878,0x91268650), + LL(0xb78c558f,0x380bf913),LL(0xc8afdaa9,0x43c0baeb),LL(0x54f169d3,0x377f61d5),LL(0xae5ff20b,0xf8da07e3), LL(0xa8a90ea8,0xb676c49d),LL(0x83a29b21,0x81c1ff2b),LL(0x2ad8d276,0x383297ac),LL(0xba89f982,0x3001122f), + LL(0x6718e448,0xe1d794be),LL(0x7c3e6e13,0x246c1482),LL(0x5d26b5ef,0x56646ef8),LL(0x88069cdd,0x80f5091e), LL(0x724bdd38,0xc5992e2f),LL(0x8471e8c7,0x02e915b4),LL(0x0d0ff2a9,0x96ff320a),LL(0x4384d1a0,0xbf886487), + LL(0xc93f72d6,0xbbe1e6a6),LL(0xcad800ea,0xd5f75d12),LL(0xe7acf117,0xfa40a09f),LL(0x7581a355,0x32c8cdd5), LL(0x7023c499,0x74221992),LL(0x38ec3901,0xa8afe5d7),LL(0xa90e83f0,0x5691afcb),LL(0x0b8f8eac,0x41bcaa03), + LL(0x8d2668d5,0xe38b5ff9),LL(0x7ad81965,0x0715281a),LL(0x03c6ce11,0x1bc8fc7c),LL(0x8b650436,0xcbbee6e2), LL(0x0cdb9808,0x06b00fe8),LL(0xfe3ed315,0x17d6e066),LL(0x4d0b5018,0x2e9d38c6),LL(0x844dcaef,0xab8bfd56), + LL(0x513aed8b,0x42894a59),LL(0x314bd07a,0xf77f3b6d),LL(0x8e42b582,0xbbdecb8f),LL(0xd2390fe6,0xf10e2fa8), LL(0x62a2f201,0xefb95022),LL(0x50ee32b0,0x4d59ea50),LL(0x6da789a8,0xd87f7728),LL(0xf79492c4,0xcf98a2cf), + LL(0x720943c2,0xf9577239),LL(0x3990b9d0,0xba044cf5),LL(0x95f2884a,0x5aa8e823),LL(0x0278a0af,0x834de6ed), LL(0x5f25bd12,0xc8e1ee9a),LL(0x6f7ab271,0x9259ceaa),LL(0x77d00b76,0x7e6d97a2),LL(0xa437832a,0x5c0c6eea), + LL(0x5606b81d,0x5232c20f),LL(0x0d991ee5,0xabd7b375),LL(0x8632d951,0x4d2bfe35),LL(0x98ed9364,0x78f85146), LL(0xf30c3282,0x951873f0),LL(0xa789230b,0x0da8ac80),LL(0x5398967f,0x3ac7789c),LL(0xbdda0fb5,0xa69b8f7f), + LL(0x6add8545,0xe5db7717),LL(0x72c49b66,0x1b71cb66),LL(0x68421d77,0xd8560739),LL(0x83e3afea,0x03840fe8), LL(0x1ec69977,0xb391dad5),LL(0x307f6726,0xae243fb9),LL(0xe8ca160c,0xc88ac87b),LL(0x4ce355f4,0x5174cced), + LL(0xe58ba37d,0x98a35966),LL(0x7817335d,0xfdcc8da2),LL(0x83fbc7bf,0x5b752830),LL(0xd9c96984,0x68e419d4), LL(0x02a40380,0x409a39f4),LL(0x1fe977bc,0x88940faf),LL(0x8f8edea6,0xc640a94b),LL(0xed11547d,0x1e22cd17), + LL(0x59ffc3e2,0xe28568ce),LL(0xc1dee4e7,0x60aa1b55),LL(0x837cb363,0xc67497c8),LL(0x105a2bf2,0x06fb438a), LL(0x500d8e20,0x30357ec4),LL(0x0670db10,0x1ad9095d),LL(0xc73b7cfd,0x7f589a05),LL(0x880d6d28,0xf544607d), + LL(0xa20ef103,0x17ba93b1),LL(0x6ba6577b,0xad859130),LL(0x6fa214a0,0x65c91cf6),LL(0x27990da5,0xd7d49c6c), LL(0x20bb569d,0xecd9ec8d),LL(0xeeffbc33,0xbd4b2502),LL(0x6bed0467,0x2056ca5a),LL(0x5b63728c,0x7916a1f7), + LL(0x53a4f566,0xd4f9497d),LL(0x97b56810,0x89734664),LL(0x0494a621,0xf8e1da74),LL(0x8d011c68,0x82546a93), LL(0xc61ac162,0x1f3acb19),LL(0xabad0d3e,0x52f8fa9c),LL(0xb4b7ea43,0x15356523),LL(0xae608125,0x5a16ad61), + LL(0x4faed184,0xb0bcb87f),LL(0x5029f45f,0x5f236b1d),LL(0x0bc6b1fc,0xd42c7607),LL(0x68aefce3,0xc644324e), LL(0x5c5d8446,0x8e191d59),LL(0x13ae1979,0xc0208077),LL(0x3ba59cc7,0xadcaee55),LL(0xa2cb81ba,0x20ed6d6b), + LL(0xb6efcffc,0x0952ba19),LL(0x97c0b87c,0x60f12d68),LL(0x9caa30bc,0x4ee2c7c4),LL(0x97fbff4e,0x767238b7), LL(0x501b5d92,0xebc73921),LL(0xc2a37737,0x3279e3df),LL(0x6d197543,0x9fc12bc8),LL(0x0a40db4e,0xfa94dc6f), + LL(0x530ccbbd,0x7392b41a),LL(0xea823525,0x87c82146),LL(0x05d98d0c,0xa52f984c),LL(0x5ef6974c,0x2ae57d73), LL(0x3042a6dd,0x9377f7bf),LL(0x19647a64,0xb1a007c0),LL(0x0cca9767,0xfaa9079a),LL(0xf68f72d5,0x3d81a25b), + LL(0xff81578e,0x752067f8),LL(0x9045447d,0x78622150),LL(0x0505aa6f,0xc0c22fcf),LL(0x6bed1c77,0x1030f0a6), LL(0x1f0bd739,0x31f29f15),LL(0xe6debe85,0x2d7989c7),LL(0x8e677e98,0x5c070e72),LL(0x06e81fd5,0x0a817bd3), + LL(0xb0f2ac95,0xc110d830),LL(0xab20e64e,0x48d0995a),LL(0x7729cd9a,0x0f3e00e1),LL(0xdd556946,0x2a570c20), LL(0x4e86214d,0x912dbcfd),LL(0xcf615498,0x2d014ee2),LL(0x3530d76e,0x55e2b1e6),LL(0xfd0fd6d1,0xc5135ae4), + LL(0xd4f3049f,0x0066273a),LL(0xe7087477,0xbb8e9893),LL(0x14c6e5fd,0x2dba1ddb),LL(0x51f57e6c,0xdba37886), LL(0x5a72f2cf,0x5aaee0a6),LL(0x7bea5642,0x1208bfbf),LL(0x67872c37,0xf5c6aa3b),LL(0x43f93224,0xd726e083), + LL(0x061f1658,0x1854daa5),LL(0xdf0cd2b3,0xc0016df1),LL(0x833d50de,0xc2a3f23e),LL(0xbbbd3017,0x73b681d2), LL(0x3ac343c0,0x2f046dc4),LL(0x85716421,0x9c847e7d),LL(0x0917eed4,0xe1e13c91),LL(0x63a1b9c6,0x3fc9eebd), + LL(0x7fe02299,0x0f816a72),LL(0x294f3319,0x6335ccc2),LL(0x4745c5be,0x3820179f),LL(0x922f066e,0xe647b782), LL(0x02cafb8a,0xc22e49de),LL(0xfcc2eccc,0x299bc2ff),LL(0x6e0e8282,0x9a8feea2),LL(0xfe893205,0xa627278b), + LL(0x7933e47b,0xa7e19733),LL(0x2e766402,0xf4ff6b13),LL(0x98440d9f,0xa4d8be0a),LL(0x38938808,0x658f5c2f), LL(0xc95b3b3e,0x90b75677),LL(0x3137b6ff,0xfa044269),LL(0x43c47c29,0x077b039b),LL(0x8a6445b2,0xcca95dd3), + LL(0x2333fc4c,0x0b498ba4),LL(0xf736a1b1,0x274f8e68),LL(0x5f1d4b2e,0x6ca348fd),LL(0xa8f10199,0x24d3be78), LL(0xca14f530,0x8535f858),LL(0x5b982e51,0xa6e7f163),LL(0x36e1bf62,0x847c8512),LL(0x03448418,0xf6a7c58e), + LL(0xf9374ab6,0x583f3703),LL(0x6e564145,0x864f9195),LL(0x22526d50,0x33bc3f48),LL(0x1262a496,0x9f323c80), LL(0x3f046a9a,0xaa97a7ae),LL(0xdf8a039a,0x70da183e),LL(0x52aa0ba6,0x5b68f71c),LL(0x21459c2d,0x9be0fe51), + LL(0xcbc613e5,0xc1e17eb6),LL(0x497ea61c,0x33131d55),LL(0xaf7eded5,0x2f69d39e),LL(0xde6af11b,0x73c2f434), LL(0xa4a375fa,0x4ca52493),LL(0xb833c5c2,0x5f06787c),LL(0x3e6e71cf,0x814e091f),LL(0x8b746666,0x76451f57), +}, +/* digit=17 base_pwr=2^119 */ +{ + LL(0x694db7e0,0x80f9bdef),LL(0xb9fcddc6,0xedca8787),LL(0x03b8dce1,0x51981c34),LL(0x70e10ba1,0x4274dcf1), LL(0x6def6d1a,0xf72743b8),LL(0xebdb1866,0xd25b1670),LL(0x050c6f58,0xc4491e8c),LL(0x87fbd7f5,0x2be2b2ab), + LL(0xd111f8ec,0x3e0e5c9d),LL(0xb7c4e760,0xbcc33f8d),LL(0xbd392a51,0x702f9a91),LL(0xc132e92d,0x7da4a795), LL(0x0bb1151b,0x1a0b0ae3),LL(0x02e32251,0x54febac8),LL(0x694e9e78,0xea3a5082),LL(0xe4fe40b8,0xe58ffec1), + LL(0xd1e0cf9e,0xf85592fc),LL(0xc0e7b2e8,0xdea75f0d),LL(0xc135584e,0xc04215cf),LL(0x2f57092a,0x174fc727), LL(0xeb930bea,0xe7277877),LL(0x5eb02a5a,0x504caccb),LL(0xf5241b9b,0xf9fe08f7),LL(0x8d5ca954,0xe7fb62f4), + LL(0x29c4120b,0xfbb8349d),LL(0xc0d0d915,0x9f94391f),LL(0x5410ba51,0xc4074fa7),LL(0x150a5911,0xa66adbf6), LL(0x34bfca38,0xc164543c),LL(0xb9e1ccfc,0xe0f27560),LL(0xe820219c,0x99da0f53),LL(0xc6b4997a,0xe8234498), + LL(0x9d4c5423,0xcfb88b76),LL(0xb0521c49,0x9e56eb10),LL(0xbe8700a1,0x418e0b5e),LL(0xf93cb58a,0x00cbaad6), LL(0xd92a5e67,0xe923fbde),LL(0x1f347f11,0xca4979ac),LL(0x6bc0585b,0x89162d85),LL(0xac3c70e3,0xdd6254af), + LL(0x516e19e4,0x7b23c513),LL(0xc5c4d593,0x56e2e847),LL(0x5ce71ef6,0x9f727d73),LL(0xf79a44c5,0x5b6304a6), LL(0x3ab7e433,0x6638a736),LL(0xfe742f83,0x1adea470),LL(0x5b7fc19f,0xe054b854),LL(0xba1d0698,0xf935381a), + LL(0x799e9a74,0x546eab2d),LL(0xa949f729,0x96239e0e),LL(0x7090055a,0xca274c6b),LL(0x9020c9b0,0x835142c3), LL(0xa2e8807f,0xa405667a),LL(0x1aa3d39e,0x29f2c085),LL(0x42fc72f5,0xcc555d64),LL(0xfbeacb3c,0xe856e0e7), + LL(0x918e4936,0xb5504f9d),LL(0xb2513982,0x65035ef6),LL(0x6f4d9cb9,0x0553a0c2),LL(0xbea85509,0x6cb10d56), LL(0xa242da11,0x48d957b7),LL(0x672b7268,0x16a4d3dd),LL(0x8502a96b,0x3d7e637c),LL(0x730d463b,0x27c7032b), + LL(0xe4136a14,0xbdc02b18),LL(0x678e32bf,0xbacf969d),LL(0xdd9c3c03,0xc98d89a3),LL(0x23becc4f,0x7b92420a), LL(0xc64d565c,0xd4b41f78),LL(0x10f28295,0x9f969d00),LL(0xb13d051a,0xec7f7f76),LL(0xa92da585,0x08945e1e), + LL(0x5846426f,0x55366b7d),LL(0x247d441d,0xe7d09e89),LL(0x736fbf48,0x510b404d),LL(0xe784bd7d,0x7fa003d0), LL(0x17fd9596,0x25f7614f),LL(0x35cb98db,0x49e0e0a1),LL(0x2e83a76a,0x2c65957b),LL(0xcddbe0f8,0x5d40da8d), + LL(0x050bad24,0xf2b8c405),LL(0xc2aa4823,0x8918426d),LL(0xa38365a7,0x2aeab3dd),LL(0x7c91b690,0x72031717), LL(0x60a94120,0x8b00d699),LL(0xe99eaeec,0x478a255d),LL(0x6f60aafd,0xbf656a5f),LL(0x5dee77b3,0xdfd7cb75), + LL(0xa595939d,0x37f68bb4),LL(0x28740217,0x03556479),LL(0x84ad7612,0x8e740e7c),LL(0x9044695f,0xd89bc843), LL(0x85a9184d,0xf7f3da5d),LL(0x9fc0b074,0x562563bb),LL(0xf88a888e,0x06d2e6aa),LL(0x161fbe7c,0x612d8643), + LL(0xf64085e7,0x465edba7),LL(0x29aa8511,0xb230f304),LL(0xcda2d188,0x53388426),LL(0x4b666649,0x90885735), LL(0x652f54f6,0x6f02ff9a),LL(0x5fae2bf0,0x65c82294),LL(0x62f5eee3,0x7816ade0),LL(0xfcc56d70,0xdcdbdf43), + LL(0x54530bb2,0x9fb3bba3),LL(0xcb0869ea,0xbde3ef77),LL(0x0b431163,0x89bc9046),LL(0xe4819a35,0x4d03d7d2), LL(0x43b6a782,0x33ae4f9e),LL(0x9c88a686,0x216db307),LL(0x00ffedd9,0x91dd88e0),LL(0x12bd4840,0xb280da9f), + LL(0x1635e741,0x32a7cb8a),LL(0x78be02a7,0xfe14008a),LL(0x1b7ae030,0x3fafb334),LL(0x5add0ce9,0x7fd508e7), LL(0xd607ad51,0x72c83219),LL(0x8d40964a,0x0f229c0a),LL(0x1c878da2,0x1be2c336),LL(0xeab2ab86,0xe0c96742), + LL(0x3e538cd7,0x458f8691),LL(0x8e08ad53,0xa7001f6c),LL(0xbf5d15ff,0x52b8c6e6),LL(0x011215dd,0x548234a4), LL(0x3d5b4045,0xff5a9d2d),LL(0x4a904190,0xb0ffeeb6),LL(0x48607f8b,0x55a3aca4),LL(0x30a0672a,0x8cbd665c), + LL(0x42583068,0x87f834e0),LL(0xf3f6e683,0x02da2aeb),LL(0x05c12248,0x6b763e5d),LL(0x65a8aefc,0x7230378f), LL(0x71e8e5ca,0x93bd80b5),LL(0xb3b62524,0x53ab041c),LL(0x6c9c552e,0x1b860513),LL(0xd5524e66,0xe84d402c), + LL(0xf37f5937,0xa37f3573),LL(0xd1e4fca5,0xeb0f6c7d),LL(0xac8ab0fc,0x2965a554),LL(0x274676ac,0x17fbf56c), LL(0xacf7d720,0x2e2f6bd9),LL(0x10224766,0x41fc8f88),LL(0x85d53bef,0x517a14b3),LL(0x7d76a7d1,0xdae327a5), + LL(0xc4818267,0x6ad0a065),LL(0x37c1bbc1,0x33aa189b),LL(0x27392a92,0x64970b52),LL(0x2d1535ea,0x21699a1c), LL(0xc2d7a7fd,0xcd20779c),LL(0x99c83cf2,0xe3186059),LL(0x72c0b8c7,0x9b69440b),LL(0x7b9e0e4d,0xa81497d7), + LL(0x1f5f82dc,0x515d5c89),LL(0x6361079e,0x9a7f67d7),LL(0x11a35330,0xa8da81e3),LL(0x4b18be1b,0xe44990c4), LL(0xaf103e59,0xc7d5ed95),LL(0x8dac9261,0xece8aba7),LL(0x9394b8d3,0xbe82b099),LL(0x16adfe83,0x6830f09a), + LL(0x88172d01,0x250a29b4),LL(0xcaff9e02,0x8b20bd65),LL(0xe8a6329a,0xb8a7661e),LL(0xd3fce920,0x4520304d), LL(0x2b47f7ef,0xae45da1f),LL(0x5bffc540,0xe07f5288),LL(0x3464f874,0xf7997009),LL(0xa6fa1f38,0x2244c2cd), + LL(0x94d7d9b1,0x43c41ac1),LL(0xc82e7f17,0x5bafdd82),LL(0x5fda0fca,0xdf0614c1),LL(0xa8ae37ad,0x74b043a7), LL(0x9e71734c,0x3ba6afa1),LL(0x9c450f2e,0x15d5437e),LL(0x67e242b1,0x4a5883fe),LL(0x2c1953c2,0x5143bdc2), + LL(0xfc5e8920,0x542b8b53),LL(0x9a9cee08,0x363bf9a8),LL(0xc3486e08,0x02375f10),LL(0x8c5e70d2,0x2037543b), LL(0x625640b4,0x7109bccc),LL(0x8bc62c3b,0xcbc1051e),LL(0x803f26ea,0xf8455fed),LL(0xeb372424,0x6badceab), + LL(0x6b53f5f9,0xa2a9ce7c),LL(0x1b176d99,0x64246595),LL(0xb95c081b,0xb1298d36),LL(0x1d9a9ee6,0x53505bb8), LL(0xf2ba70b0,0x3f6f9e61),LL(0x8afad453,0xd07e16c9),LL(0xe7eb4a6a,0x9f1694bb),LL(0x3cb0bc8e,0xdfebced9), + LL(0x53868c8b,0x92d3dcdc),LL(0x386107a6,0x174311a2),LL(0x689b4e64,0x4109e07c),LL(0x2df3dcb6,0x30e4587f), LL(0x0811b3b2,0x841aea31),LL(0x0cce43ea,0x6144d41d),LL(0x2a9a7803,0x464c4581),LL(0x3e158930,0xd03d371f), + LL(0xb1f3390b,0xc676d7f2),LL(0xa5b61272,0x9f7a1b8c),LL(0xc2e127a9,0x4ebebfc9),LL(0x5dd997bf,0x4602500c), LL(0x4711230f,0x7f09771c),LL(0x020f09c1,0x058eb37c),LL(0xfee5e38b,0xab693d4b),LL(0x4653cbc0,0x9289eb1f), + LL(0xd51b9cf5,0xbecf46ab),LL(0x9f0121af,0xd2aa9c02),LL(0xe90dc274,0x36aaf7d2),LL(0x48b95a3c,0x909e4ea0), LL(0x6f32dbdb,0xe6b70496),LL(0x8b030b3e,0x672188a0),LL(0xcfb617e2,0xeeffe5b3),LL(0x7c82709e,0x87e947de), + LL(0x1770f5a7,0xa44d2b39),LL(0x0e44eb82,0xe4d4d791),LL(0x3f69712a,0x42e69d1e),LL(0xac6a820e,0xbf11c4d6), LL(0x42c4224c,0xb5e7f3e5),LL(0x449d941c,0xd6b4e81c),LL(0x5450e878,0x5d72bd16),LL(0xee25ac54,0x6a61e28a), + LL(0xe6f1cd95,0x33272094),LL(0x0d18673f,0x7512f30d),LL(0x5afc1464,0x32f7a4ca),LL(0x6bbb977b,0x2f095656), LL(0xa8226200,0x586f47ca),LL(0x1ac07369,0x02c868ad),LL(0xc613acbe,0x4ef2b845),LL(0x0386054c,0x43d7563e), + LL(0xab952578,0x54da9dc7),LL(0x26e84d0b,0xb5423df2),LL(0x9b872042,0xa8b64eeb),LL(0x5990f6df,0xac205782), LL(0x21f4c77a,0x4ff696eb),LL(0xaab273af,0x1a79c3e4),LL(0x9436b3f1,0x29bc922e),LL(0xd6d9a27a,0xff807ef8), + LL(0x778f22a0,0x82acea3d),LL(0x5b5e7469,0xfb10b2e8),LL(0x2818ee7d,0xc0b16980),LL(0xc91c1a2f,0x011afff4), LL(0xad124418,0x95a6d126),LL(0xe72e295f,0x31c081a5),LL(0xf2f4db75,0x36bb283a),LL(0x7acef462,0xd115540f), + LL(0x33f6746c,0xc7f3a8f8),LL(0xfea990ca,0x21e46f65),LL(0xcaddb0a9,0x915fd5c5),LL(0x78614555,0xbd41f016), LL(0x426ffb58,0x346f4434),LL(0x14dbc204,0x80559436),LL(0x5a969b7f,0xf3dd20fe),LL(0xe899a39a,0x9d59e956), + LL(0x8ad4cf4b,0xf1b0971c),LL(0x2ffb8fb8,0x03448860),LL(0x65340ba4,0xf071ac3c),LL(0xb27fd758,0x408d0596), LL(0x98c364b0,0xe7c78ea4),LL(0x051e8ab5,0xa4aac4a5),LL(0x485d9002,0xb9e1d560),LL(0x88844455,0x9acd518a), + LL(0xd06f56c0,0xe4ca688f),LL(0xdf027972,0xa48af70d),LL(0x5e9a609d,0x691f0f04),LL(0xee61270e,0xa9dd82cd), LL(0xa0ef18d3,0x8903ca63),LL(0x3d6ca3bd,0x9fb7ee35),LL(0xabf47d03,0xa7b4a09c),LL(0x1c67de8e,0x4cdada01), + LL(0x9355a244,0x52003749),LL(0x4f2151a9,0xe77fd2b6),LL(0x66b4efcb,0x695d6cf6),LL(0xda2cfe25,0xc5a0cacf), LL(0xef811865,0x104efe5c),LL(0x9ea5cc3d,0xf52813e8),LL(0x40b58dbc,0x855683dc),LL(0x175fcb11,0x0338ecde), + LL(0x74921592,0xf9a05637),LL(0xb9bb9d31,0xb4f1261d),LL(0x4e9c5459,0x551429b7),LL(0x6ea71f53,0xbe182e6f), LL(0xdfc50573,0xd3a3b07c),LL(0x62be8d44,0x9ba1afda),LL(0x52ab65d3,0x9bcfd2cb),LL(0xa9571802,0xdf11d547), + LL(0x02a2404a,0x099403ee),LL(0x21088a71,0x497406f4),LL(0x5004ae71,0x99479409),LL(0xa812c362,0xbdb42078), LL(0xd8828442,0x2b72a30f),LL(0xfcb5ed1c,0x283add27),LL(0x66a40015,0xf7c0e200),LL(0x08b295ef,0x3e3be641), + LL(0xe038a675,0xac127dc1),LL(0x8c5c6320,0x729deff3),LL(0xa90d2c53,0xb7df8fd4),LL(0x681e7cd3,0x9b74b0ec), LL(0xdab407e5,0x5cb5a623),LL(0x76b340c6,0xcdbd3615),LL(0x7d28392c,0xa184415a),LL(0xe96f7830,0xc184c1d8), + LL(0x81d3a80f,0xc3204f19),LL(0xc8e02432,0xfde0c841),LL(0x8149e0c1,0x78203b3e),LL(0x08053a73,0x5904bdbb), LL(0x101b6805,0x30fc1dd1),LL(0x49aa6d49,0x43c223bc),LL(0x7a174087,0x9ed67141),LL(0xd5997008,0x311469a0), + LL(0x5e43fc61,0xb189b684),LL(0xe0d3ab57,0xf3282375),LL(0xb1181da8,0x4fa34b67),LL(0x99ee52b8,0x621ed0b2), LL(0xad990676,0x9b178de1),LL(0x56d54065,0xd51de67b),LL(0x7538c201,0x2a2c27c4),LL(0x38a40f5c,0x33856ec8), + LL(0xbe6cdcde,0x2522fc15),LL(0x9f0c6f89,0x1e603f33),LL(0x103e30a6,0x7994edc3),LL(0x220c853e,0x033a00db), LL(0xf7bb7fd7,0xd3cfa409),LL(0x462d18f6,0x70f8781e),LL(0x687fe295,0xbbd82980),LL(0x595669f3,0x6eef4c32), + LL(0x2f7e85c3,0x86a9303b),LL(0x71988f9b,0x5fce4621),LL(0xc138acb5,0x5b935bf6),LL(0x25661212,0x30ea7d67), LL(0xe51ab9a2,0xef1eb5f4),LL(0xae067c78,0x0587c98a),LL(0x77ca9ca6,0xb3ce1b3c),LL(0x54b5f057,0x2a553d4d), + LL(0x4da29ec2,0xc7898236),LL(0xb9c57316,0xdbdd5d13),LL(0x2cd80d47,0xc57d6e6b),LL(0xfe9e7391,0x80b460cf), LL(0xf963c31e,0x98648cab),LL(0xcc4d32fd,0x67f9f633),LL(0xfdf7c687,0x0af42a9d),LL(0x0b015ea7,0x55f292a3), + LL(0xcd21ab3d,0x89e468b2),LL(0xc393d392,0xe504f022),LL(0xa5013af9,0xab21e1d4),LL(0xc2c28acb,0xe3283f78), LL(0x226bf99f,0xf38b35f6),LL(0x0e291e69,0xe8354274),LL(0xb20c162d,0x61673a15),LL(0xb04fbdbe,0xc101dc75), + LL(0x255bd617,0x8323b4c2),LL(0x6c2a9154,0x6c969693),LL(0x62679387,0xc6e65860),LL(0xb8c88e23,0x8e01db0c), LL(0x893a5559,0x33c42873),LL(0x47a3e149,0x7630f04b),LL(0xddcf35f8,0xb5d80805),LL(0x77dfe732,0x582ca080), + LL(0x0b1894a0,0x2c7156e1),LL(0xd81c68c0,0x92034001),LL(0xc8b115b5,0xed225d00),LL(0x83b907f2,0x237f9c22), LL(0x4470e2c0,0x0ea2f32f),LL(0x58be4e95,0xb725f7c1),LL(0xb1ae5463,0x0f1dcafa),LL(0x1ba2fc04,0x59ed5187), + LL(0xd0115d4d,0xf6e0f316),LL(0xd3691599,0x5180b12f),LL(0x527f0a41,0x157e32c9),LL(0xa8e0ecc0,0x7b0b081d), LL(0xbf4f0dd0,0x6dbaaa8a),LL(0x4d252696,0x99b289c7),LL(0xdbf864fe,0x79b7755e),LL(0x76cad3ab,0x6974e2b1), + LL(0x06ddd657,0x35dbbee2),LL(0x2ff3a96d,0xe7cbdd11),LL(0x076be758,0x88381968),LL(0x08c91f5d,0x2d737e72), LL(0x86ec3776,0x5f83ab62),LL(0x945fa7a1,0x98aa649d),LL(0x72ef0933,0xf477ec37),LL(0x098c17b1,0x66f52b1e), + LL(0xd803738b,0x9eec58fb),LL(0xe4e86aa4,0x91aaade7),LL(0xa5b51492,0x6b1ae617),LL(0xbbc45974,0x63272121), LL(0x862c5129,0x7e0e28f0),LL(0x3321a4a0,0x0a8f79a9),LL(0x5041c88f,0xe26d1664),LL(0x53233e3a,0x0571b805), + LL(0xc9520711,0xd1b0ccde),LL(0x3c8b84bf,0x55a9e4ed),LL(0xa1fef314,0x9426bd39),LL(0x6eb93f2b,0x4f5f638e), LL(0x2bf9341b,0xba2a1ed3),LL(0x4d42d5a9,0xd63c1321),LL(0x316dc7c5,0xd2964a89),LL(0xca511851,0xd1759606), + LL(0xf9e6ed35,0xd8a9201f),LL(0x6736925a,0xb7b5ee45),LL(0x99581af7,0x0a83fbbc),LL(0x64eeb051,0x3076bc40), LL(0x02dec312,0x5511c98c),LL(0x238dcb78,0x270de898),LL(0x539c08c9,0x2cf4cf9c),LL(0x38d3b06e,0xa70cb65e), + LL(0xcfe57bbd,0xb12ec10e),LL(0x35a0c2b5,0x82c7b656),LL(0x161c67bd,0xddc7d5cd),LL(0xae3a32cc,0xe32e8985), LL(0xd11a5529,0x7aba9444),LL(0x2427fa1a,0xe964ed02),LL(0x24a1770a,0x1528392d),LL(0x12c72fcd,0xa152ce2c), + LL(0x8ec07649,0x714553a4),LL(0x459dd453,0x18b4c290),LL(0x7b64b110,0xea32b714),LL(0x2e6f07a2,0xb871bfa5), LL(0x9e2e3c9b,0xb67112e5),LL(0x44aa90f6,0xfbf250e5),LL(0xbd539006,0xf77aedb8),LL(0xd172a66f,0x3b0cdf9a), + LL(0xf8c51187,0xedf69fea),LL(0x741e4da7,0x05bb67ec),LL(0x08114345,0x47df0f32),LL(0xbb9792b1,0x56facb07), LL(0x8f6229e4,0xf3e007e9),LL(0x526fba0f,0x62d103f4),LL(0xb0339d79,0x4f33bef7),LL(0xb59bfec1,0x9841357b), + LL(0xc34e6705,0xfa8dbb59),LL(0x7fdaa84c,0xc3c7180b),LL(0xa4108537,0xf95872fc),LL(0x932a3e5a,0x8750cc3b), LL(0xb7275d7d,0xb61cc69d),LL(0x2e59b2e9,0xffa0168b),LL(0x6ecbb493,0xca032abc),LL(0x2c9082d8,0x1d86dbd3), + LL(0xe28ef5ba,0xae1e0b67),LL(0xcb18e169,0x2c9a4699),LL(0x1e6bbd20,0x0ecd0e33),LL(0xaf5e81d2,0x571b360e), LL(0x101c1d45,0xcd9fea58),LL(0x18880452,0x6651788e),LL(0x1f8dd446,0xa9972635),LL(0xe37281d0,0x44bed022), + LL(0x33da525d,0x094b2b2d),LL(0x13144fd8,0xf193678e),LL(0xf4c1061d,0xb8ab5ba4),LL(0xdccbe0f4,0x4343b5fa), LL(0x63812713,0xa8702371),LL(0xf7611d93,0x47bf6d2d),LL(0xbd21e1d7,0x46729b8c),LL(0xd629e77d,0x7484d4e0), + LL(0x60dbac1f,0x830e6eea),LL(0xda06a2f7,0x23d8c484),LL(0x50ca535b,0x896714b0),LL(0xebd97a9b,0xdc8d3644), LL(0xb12177b4,0x106ef9fa),LL(0x534d5d9c,0xf79bf464),LL(0xa6ab360b,0x2537a349),LL(0xa00c744f,0xc7c54253), + LL(0xe5911a76,0xb3c7a047),LL(0x647f1ee7,0x61ffa5c8),LL(0x8f56ab42,0x15aed36f),LL(0xa3ff9ac9,0x6a0d41b0), LL(0xcc30d357,0x68f469f5),LL(0x6b72be96,0xbe9adf81),LL(0x903ad461,0x1cd926fe),LL(0xcaca441b,0x7e89e38f), + LL(0xfacf69d4,0xf0f82de5),LL(0x4775344c,0x363b7e76),LL(0xb2e36d04,0x6894f312),LL(0x11d1c9a5,0x3c6cb4fe), LL(0x4008e1f2,0x85d9c339),LL(0x249f326c,0x5e9a85ea),LL(0x678c5e06,0xdc35c60a),LL(0x9f86fba9,0xc08b944f), + LL(0x89f71f0f,0xde40c02c),LL(0xff3da3c0,0xad8f3e31),LL(0x42125ded,0x3ea5096b),LL(0xa7379183,0x13879cbf), LL(0x6b306a0b,0x6f4714a5),LL(0x67646c5e,0x359c2ea6),LL(0x07726368,0xfacf8943),LL(0x65ff431e,0x07a58935), + LL(0x68754ab0,0x24d661d1),LL(0x6f429a76,0x801fce1d),LL(0xa58ce769,0xc068a85f),LL(0x5d5eca2b,0xedc35c54), LL(0xa3f660d1,0xea31276f),LL(0xb8fc7167,0xa0184ebe),LL(0x1d8db0ae,0x0f20f21a),LL(0x56c35e12,0xd96d095f), + LL(0xf8c2a25b,0xedf402b5),LL(0x059204b6,0x1bb772b9),LL(0x19b4e34c,0x50cbeae2),LL(0x3fa0845a,0x93109d80), LL(0x8ef59fb5,0x54f7ccf7),LL(0x88070963,0x3b438fe2),LL(0x31f3ba9b,0x9e28c659),LL(0xead9da92,0x9cc31b46), + LL(0xb733aa5f,0x3c2f0ba9),LL(0xf05af235,0xdece47cb),LL(0xa2ac82a5,0xf8e3f715),LL(0x2203f18a,0xc97ba641), LL(0x09c11060,0xc3af5504),LL(0x46af512d,0x56ea2c05),LL(0xf3f28146,0xfac28daf),LL(0x959ef494,0x87fab43a), +}, +/* digit=18 base_pwr=2^126 */ +{ + LL(0xd4c5105f,0x09891641),LL(0x6d7fbd65,0x1ae80f8e),LL(0xbee6bdb0,0x9d67225f),LL(0x7fc4d860,0x3b433b59), LL(0x93e85638,0x44e66db6),LL(0xe3e9862f,0xf7b59252),LL(0x665c32ec,0xdb785157),LL(0xae362f50,0x702fefd7), + LL(0x0fefb0c3,0x3754475d),LL(0x46d7c35d,0xd48fb56b),LL(0x363798a4,0xa070b633),LL(0x8fdb98e6,0xae89f3d2), LL(0x6363d14c,0x970b89c8),LL(0x67abd27d,0x89817521),LL(0x44d5a021,0x9bf7d474),LL(0xcac72aee,0xb3083baf), + LL(0xbe949a44,0x389741de),LL(0x546a4fa5,0x638e9388),LL(0xa0047bdc,0x3fe6419c),LL(0xaaea57ca,0x7047f648), LL(0x41fbab17,0x54e48a90),LL(0x576bdba2,0xda8e0b28),LL(0xc72afddc,0xe807eebc),LL(0xf42577bf,0x07d3336d), + LL(0xbfe20925,0x62a8c244),LL(0x8fdce867,0x91c19ac3),LL(0xdd387063,0x5a96a5d5),LL(0x21d324f6,0x61d587d4), LL(0xa37173ea,0xe87673a2),LL(0x53778b65,0x23848008),LL(0x05bab43e,0x10f8441e),LL(0x4621efbe,0xfa11fe12), + LL(0x81685d7b,0x047b772e),LL(0xbf34a976,0x23f27d81),LL(0x915f48ef,0xc27608e2),LL(0xa521d5c3,0x3b0b43fa), LL(0x63ca7284,0x7613fb26),LL(0x1d4db837,0x7f5729b4),LL(0x583b526b,0x87b14898),LL(0xbbadd3d1,0x00b732a6), + LL(0x2048e396,0x8e02f426),LL(0x383d9de4,0x436b50b6),LL(0x471e85ad,0xf78d3481),LL(0xd005c8d6,0x8b01ea6a), LL(0x97015c07,0xd3c7afee),LL(0x4e3ba2ae,0x46cdf1a9),LL(0x83d3a1d2,0x7a42e501),LL(0xb541dff4,0xd54b5268), + LL(0x4e23e9bc,0x3f24cf30),LL(0x126e3624,0x4387f816),LL(0x3b0b6d61,0x26a46a03),LL(0x8b2d777c,0xaf1bc845), LL(0x527de79c,0x25c401ba),LL(0x4261bbb6,0x0e1346d4),LL(0x287b4bc7,0x4b96c44b),LL(0x5254562f,0x658493c7), + LL(0xb8a24a20,0x23f949fe),LL(0xf52ca53f,0x17ebfed1),LL(0xbcfb4853,0x9b691bbe),LL(0x6278a05d,0x5617ff6b), LL(0xe3c99ebd,0x241b34c5),LL(0x1784156a,0xfc64242e),LL(0x695d67df,0x4206482f),LL(0xee27c011,0xb967ce0e), + LL(0x21c80b5d,0x65db3751),LL(0xa31ecca0,0x2e7a563c),LL(0x5238a07e,0xe56ffc4e),LL(0x32ced854,0x3d6c2966), LL(0xaf70b885,0xe99d7d1a),LL(0x2d686459,0xafc3bad9),LL(0x0cc8ba5b,0x9c78bf46),LL(0x18955aa3,0x5a439519), + LL(0x5fe4e314,0xf8b517a8),LL(0xfcb8906f,0xe60234d0),LL(0xf2061b23,0xffe542ac),LL(0x6b4cb59c,0x287e191f), LL(0x09d877d8,0x21857ddc),LL(0x14678941,0x1c23478c),LL(0xb6e05ea4,0xbbf0c056),LL(0xb01594fe,0x82da4b53), + LL(0xfadb8608,0xf7526791),LL(0x7b74cdf6,0x049e832d),LL(0xc2b90a34,0xa43581cc),LL(0x9360b10c,0x73639eb8), LL(0xe1e4a71b,0x4fba331f),LL(0x8072f919,0x6ffd6b93),LL(0x65679032,0x6e53271c),LL(0xf14272ce,0x67206444), + LL(0xb2335834,0xc0f734a3),LL(0x90ef6860,0x9526205a),LL(0x04e2bb0d,0xcb8be717),LL(0x02f383fa,0x2418871e), LL(0x4082c157,0xd7177681),LL(0x29c20073,0xcc914ad0),LL(0xe587e728,0xf186c1eb),LL(0x61bcd5fd,0x6fdb3c22), + LL(0xf2f9f8e9,0x30d014a6),LL(0x4fec49d2,0x963ece23),LL(0x9605a8d9,0x862025c5),LL(0x19f8929a,0x39874445), LL(0x12bf476a,0x01b6ff65),LL(0x09cf7d91,0x598a64d8),LL(0x93be56ca,0xd7ec7749),LL(0xcbb33615,0x10899785), + LL(0x02eee3ad,0xb8a092fd),LL(0x30145270,0xa86b3d35),LL(0x8512b675,0x323d98c6),LL(0x62ebb40f,0x4b8bc785), LL(0x413f9cde,0x7d301f54),LL(0x2bab5664,0xa5e4fb4f),LL(0x1cbfec23,0x1d2b252d),LL(0xe177120d,0xfcd576bb), + LL(0x83731a34,0x04427d3e),LL(0xed836e8e,0x2bb9028e),LL(0xb612ca7c,0xb36acff8),LL(0xd3d9c73a,0xb88fe5ef), LL(0xedea4eb3,0xbe2a6bc6),LL(0x488eec77,0x43b93133),LL(0xb17106e1,0xf41ff566),LL(0x654efa32,0x469e9172), + LL(0x41c23fa3,0xb4480f04),LL(0xc1989a2e,0xb4712eb0),LL(0x93a29ca7,0x3ccbba0f),LL(0xd619428c,0x6e205c14), LL(0xb3641686,0x90db7957),LL(0x45ac8b4e,0x0432691d),LL(0xf64e0350,0x07a759ac),LL(0x9c972517,0x0514d89c), + LL(0xa8e67fc3,0x1701147f),LL(0xab2085be,0x9e2e0b8b),LL(0xac284e57,0xd5651824),LL(0x74893664,0x890d4325), LL(0xc55e68a3,0x8a7c5e6e),LL(0x4339c85a,0xbf12e90b),LL(0xf922b655,0x31846b85),LL(0x0bf4d700,0x9a54ce4d), + LL(0xf1a14295,0xd7f4e83a),LL(0xb285d4f9,0x916f955c),LL(0x99ffdaba,0xe57bb0e0),LL(0xeab0d152,0x28a43034), LL(0xb8a9cef8,0x0a36ffa2),LL(0xb9ec051a,0x5517407e),LL(0xea68e672,0x9c796096),LL(0xfb3c77fb,0x853db5fb), + LL(0xe864a51a,0x21474ba9),LL(0x6e8a1b8b,0x6c267699),LL(0x94120a28,0x7c823626),LL(0x8383a5db,0xe61e9a48), LL(0x9f84216d,0x7dd75003),LL(0xad43cd85,0xab020d07),LL(0xda12c659,0x9437ae48),LL(0xe65452ad,0x6449c2eb), + LL(0x2cf9d7c1,0xcc7c4c1c),LL(0xee95e5ab,0x1320886a),LL(0xbeae170c,0xbb7b9056),LL(0xdbc0d662,0xc8a5b250), LL(0xc11d2303,0x4ed81432),LL(0x1f03769f,0x7da66912),LL(0x84539828,0x3ac7a5fd),LL(0x3bccdd02,0x14dada94), + LL(0x7ef6b0d1,0x8b84c321),LL(0x7c933f22,0x52a9477a),LL(0xfd440b82,0x5ef6728a),LL(0x6ce4bd5e,0x5c3bd859), LL(0xf22c2d3e,0x918b80f5),LL(0xb7bb6cc5,0x368d5040),LL(0x2695a11c,0xb66142a1),LL(0xeb19ea70,0x60ac583a), + LL(0x0eab2437,0x317cbb98),LL(0x5e2654c8,0x8cc08c55),LL(0xe6d8307f,0xfe2d6520),LL(0x57428993,0xe9f147f3), LL(0xd2fd6cf1,0x5f9c7d14),LL(0x2d4fcbb0,0xa3ecd064),LL(0x8e7341f7,0xad83fef0),LL(0x3a63115c,0x643f23a0), + LL(0xe65ab743,0xd38a78ab),LL(0x35edc89c,0xbf7c75b1),LL(0x530df568,0x3dd8752e),LL(0xe308c682,0xf85c4a76), LL(0xe68acf37,0x4c9955b2),LL(0xab32af85,0xa544df3d),LL(0xa25cf493,0x4b8ec3f5),LL(0x1a622feb,0x4d8f2764), + LL(0xf0dcbc49,0x7bb4f7aa),LL(0x70bbb45b,0x7de551f9),LL(0x9f2ca2e5,0xcfd0f3e4),LL(0x1f5c76ef,0xece58709), LL(0x167d79ae,0x32920edd),LL(0xfa7d7ec1,0x039df8a2),LL(0xbb30af91,0xf46206c0),LL(0x22676b59,0x1ff5e2f5), + LL(0x6ea51d66,0x11f4a039),LL(0x807d7a26,0x506c1445),LL(0x755a9b24,0x60da5705),LL(0x1f1a319e,0x8fc8cc32), LL(0x9433d67d,0x83642d4d),LL(0x6a7dd296,0x7fa5cb8f),LL(0x9b7bde07,0x576591db),LL(0x419716fb,0x13173d25), + LL(0xd5b340ff,0xea30599d),LL(0xb0fe76c5,0xfc6b5297),LL(0xab8f5adc,0x1c6968c8),LL(0x901c928d,0xf723c7f5), LL(0x9773d402,0x4203c321),LL(0x1b51dd47,0xdf7c6aa3),LL(0x552be23c,0x3d49e37a),LL(0x0b5a6e87,0x57febee8), + LL(0x7bd8e739,0xc5ecbee4),LL(0xae63bf75,0x79d44994),LL(0x38fb8923,0x168bd00f),LL(0xd0533130,0x75d48ee4), LL(0xdb5cdf33,0x554f77aa),LL(0x3c696769,0x3396e896),LL(0xd3fd674e,0x2fdddbf2),LL(0x99d0e3e5,0xbbb8f6ee), + LL(0xcbae2f70,0x51b90651),LL(0x93aaa8eb,0xefc4bc05),LL(0xdd1df499,0x8ecd8689),LL(0x22f367a5,0x1aee99a8), LL(0xae8274c5,0x95d485b9),LL(0x7d30b39c,0x6c14d445),LL(0xbcc1ef81,0xbafea90b),LL(0xa459a2ed,0x7c5f317a), + LL(0x4ef44227,0x01211075),LL(0xdc20f496,0xa17bed6e),LL(0x819853cd,0x0cdfe424),LL(0xf71e2ce7,0x13793298), LL(0xdbbe307b,0x3c1f3078),LL(0x76ee9936,0x6dd1c20e),LL(0x423caa20,0x23ee4b57),LL(0x8efb840e,0x4ac3793b), + LL(0xed1f8ca0,0x934438eb),LL(0x4ebb25a2,0x3e546658),LL(0xc069896f,0xc415af0e),LL(0x9a5aa43d,0xc13eddb0), LL(0xd49eb8f6,0x7a04204f),LL(0xd74f1670,0xd0d5bdfc),LL(0x56fc0558,0x3697e286),LL(0x01cebade,0x10207371), + LL(0x0647a82b,0x5f87e690),LL(0x8f40054f,0x908e0ed4),LL(0x79853803,0xa9f633d4),LL(0x4a28b252,0x8ed13c9a), LL(0x1f460f64,0x3e2ef676),LL(0x36d06336,0x53930b9b),LL(0x8fc4979b,0x347073ac),LL(0x5ecd5597,0x84380e0e), + LL(0xc4fe3c39,0xe3b22c6b),LL(0x6c7bebdf,0xba4a8153),LL(0x25693459,0xf23ab6b7),LL(0x14922b11,0x53bc3770), LL(0x5afc60db,0x4645c8ab),LL(0x20b9f2a3,0xaa022355),LL(0xce0fc507,0x52a2954c),LL(0x7ce1c2e7,0x8c2731bb), + LL(0x18a0339d,0xf39608ab),LL(0x3735436c,0xac7a658d),LL(0xcd992b4f,0xb22c2b07),LL(0xf40dcfd4,0x4e83daec), LL(0x2f39ea3e,0x8a34c7be),LL(0xb0a56d2e,0xef0c005f),LL(0x6edd8038,0x62731f6a),LL(0x4e3cb075,0x5721d740), + LL(0xfbeeee1b,0x1ea41511),LL(0xef1d0c05,0xd1ef5e73),LL(0x73c07d35,0x42feefd1),LL(0x8a329493,0xe530a00a), LL(0xf15ebfb0,0x5d55b7fe),LL(0xd322491a,0x549de03c),LL(0x745b3237,0xf7b5f602),LL(0x1ab6e2b6,0x3632a3a2), + LL(0x0ef59f78,0x0d3bba89),LL(0xc9e52b9a,0x0dfc6443),LL(0x72631447,0x1dc79699),LL(0xb3be20b1,0xef033917), LL(0xb1383948,0x0c92735d),LL(0xc0dd7d7d,0xc1fc29a2),LL(0x403ed068,0x6485b697),LL(0xaac93bdc,0x13bfaab3), + LL(0x0deeaf52,0x410dc6a9),LL(0x4c641c15,0xb003fb02),LL(0x5bc504c4,0x1384978c),LL(0x864a6a77,0x37640487), LL(0x222a77da,0x05991bc6),LL(0x5e47eb11,0x62260a57),LL(0xf21b432c,0xc7af6613),LL(0xab4953e9,0x22f3acc9), + LL(0x8e41d155,0x52934922),LL(0x3ac059ef,0x4d024568),LL(0x4d884411,0xb0201755),LL(0xa59a178f,0xce8055cf), LL(0xf6204549,0xcd77d1af),LL(0xc7066759,0xa0a00a3e),LL(0x0272c229,0x471071ef),LL(0xd3c4b6b0,0x009bcf6b), + LL(0x22305177,0x2a2638a8),LL(0x41645bbf,0xd51d59df),LL(0xc0a7a3c0,0xa81142fd),LL(0x4c7063ee,0xa17eca6d), LL(0x60d9dcec,0x0bb887ed),LL(0x20ad2455,0xd6d28e51),LL(0xa67102ba,0xebed6308),LL(0x8bffa408,0x042c3114), + LL(0x8aa68e30,0xfd099ac5),LL(0x1483513e,0x7a6a3d7c),LL(0xba2d8f0c,0xffcc6b75),LL(0x1e78b954,0x54dacf96), LL(0xa4a9af89,0xf645696f),LL(0x06ac98ec,0x3a411940),LL(0x22a67a20,0x41b8b3f6),LL(0x99dec626,0x2d0b1e0f), + LL(0x40be34e8,0x27c89192),LL(0x91907f35,0xc7162b37),LL(0xa956702b,0x90188ec1),LL(0xdf93769c,0xca132f7d), LL(0x0e2025b4,0x3ece44f9),LL(0x0c62f14c,0x67aaec69),LL(0x22e3cc11,0xad741418),LL(0x7ff9a50e,0xcf9b75c3), + LL(0x4d348272,0x02fa2b16),LL(0x9959d56d,0xbd99d61a),LL(0x18762916,0xbc4f19db),LL(0x49c1ac80,0xcc7cce50), LL(0xd846bd83,0x4d59ebaa),LL(0xa9202849,0x8775a9dc),LL(0x6e1f4ca9,0x07ec4ae1),LL(0xba893f11,0x27eb5875), + LL(0x662cc565,0x00284d51),LL(0x0db4138d,0x82353a6b),LL(0xaa32a594,0xd9c7aaaa),LL(0xa5669c47,0xf5528b5e), LL(0x2f23c5ff,0xf3220231),LL(0x6affa3a1,0xe3e8147a),LL(0x202ddda0,0xfb423d5c),LL(0x6b871bd4,0x3d6414ac), + LL(0xa51a168a,0x586f82e1),LL(0x48ae5448,0xb712c671),LL(0x76233eb8,0x9a2e4bd1),LL(0x78811ca9,0x0188223a), LL(0xf7c18de1,0x553c5e21),LL(0xb27bb286,0x7682e451),LL(0x0e51e929,0x3ed036b3),LL(0xec9cb34f,0xf487211b), + LL(0x0c24efc8,0x0d094277),LL(0xbef737a4,0x0349fd04),LL(0x514cdd28,0x6d1c9dd2),LL(0x30da9521,0x29c135ff), LL(0xf78b0b6f,0xea6e4508),LL(0x678c143c,0x176f5dd2),LL(0x4be21e65,0x08148418),LL(0xe7df38c4,0x27f7525c), + LL(0x748ab1a4,0x1fb70e09),LL(0x5efe4433,0x9cba50a0),LL(0x15f75af2,0x7846c7a6),LL(0x5ee73ea8,0x2a7c2c57), LL(0x3f0a449a,0x42e566a4),LL(0xad90fc3d,0x45474c3b),LL(0x8b61d057,0x7447be3d),LL(0x3a4ec092,0x3e9d1cf1), + LL(0xf380a6e6,0x1603e453),LL(0x9b1437c2,0x0b86e431),LL(0xef29610a,0x7a4173f2),LL(0xf03d57f7,0x8fa729a7), LL(0x6c9c217e,0x3e186f6e),LL(0x91919524,0xbe1d3079),LL(0x153d4fb1,0x92a62a70),LL(0xd68c2f71,0x32ed3e34), + LL(0x9eb1a8b7,0xd785027f),LL(0xc5b22fe8,0xbc37eb77),LL(0xb9d6a191,0x466b34f0),LL(0x9a05f816,0x008a89af), LL(0x7d42c10a,0x19b028fb),LL(0x49b3f6b8,0x7fe8c92f),LL(0xa5a0ade3,0x58907cc0),LL(0x559d1a7c,0xb3154f51), + LL(0xd9790ed6,0x5066efb6),LL(0xa6aa793b,0xa77a0cbc),LL(0x223e042e,0x1a915f3c),LL(0x69c5874b,0x1c5def04), LL(0x73b6c1da,0x0e830078),LL(0xfcd8557a,0x55cf85d2),LL(0x0460f3b1,0x0f7c7c76),LL(0x46e58063,0x87052acb), + LL(0x907eae66,0x09212b80),LL(0x4d721c89,0x3cb068e0),LL(0xdd45ac1c,0xa87941ae),LL(0x0daa0dbb,0xde8d5c0d), LL(0xe3502e6e,0xda421fdc),LL(0x4d89a084,0xc8944201),LL(0xf0c24bfb,0x7307ba5e),LL(0x20bde0ef,0xda212beb), + LL(0xf82ce682,0xea2da24b),LL(0x07f71fe4,0x058d3816),LL(0x5ffad8de,0x35a02462),LL(0xaadcefab,0xcd7b05dc), LL(0x1d9f54ec,0xd442f8ed),LL(0xb2d3b5ca,0x8be3d618),LL(0xe06b2ce2,0xe2220ed0),LL(0x1b0da4c0,0x82699a5f), + LL(0x71c0c3a7,0x3ff106f5),LL(0x0d34180c,0x8f580f5a),LL(0x22d7d375,0x4ebb120e),LL(0xe9513675,0x5e5782cc), LL(0x99c82a70,0x2275580c),LL(0x15ea8c4c,0xe8359fbf),LL(0x7b415e70,0x53b48db8),LL(0x100c6014,0xaacf2240), + LL(0xe4652f1d,0x9faaccf5),LL(0xd56157b2,0xbd6fdd2a),LL(0x6261ec50,0xa4f4fb1f),LL(0x476bcd52,0x244e55ad), LL(0x047d320b,0x881c9305),LL(0x6181263f,0x1ca983d5),LL(0x278fb8ee,0x354e9a44),LL(0x396e4964,0xad2dbc0f), + LL(0x9268b3de,0x723f3aa2),LL(0xe6e0609a,0x0d1ca29a),LL(0x6cf44252,0x794866aa),LL(0x01af87ed,0x0b59f3e3), LL(0x7f4a6c51,0xe234e5ff),LL(0x61dc2f7e,0xa8768fd2),LL(0x0a94d81f,0xdafc7332),LL(0x06938ce1,0xd7f84282), + LL(0x0546063e,0xae0b3c0e),LL(0x5d61abc6,0x7fbadcb2),LL(0x369ac400,0xd5d7a2c9),LL(0xae67d10c,0xa5978d09), LL(0x4f85eaac,0x290f211e),LL(0xfacac681,0xe61e2ad1),LL(0x388384cd,0xae125225),LL(0xccfde30f,0xa7fb68e9), + LL(0x3daed4c2,0x7a59b936),LL(0x2606f789,0x80a9aa40),LL(0xf6a6d90a,0xb40c1ea5),LL(0x514d5885,0x948364d3), LL(0x70985182,0x062ebc60),LL(0x33310895,0xa6db5b0e),LL(0xe329c2f5,0x64a12175),LL(0x90ea237e,0xc5f25bd2), + LL(0x2d0a4c23,0x7915c524),LL(0x6bb3cc52,0xeb5d26e4),LL(0xc09e2c92,0x369a9116),LL(0xcf182cf8,0x0c527f92), LL(0x2aede0ac,0x9e591938),LL(0x6cc34939,0xb2922208),LL(0x99a34361,0x3c9d8962),LL(0xc1905fe6,0x3c81836d), + LL(0xa001ec5a,0x4bfeb57f),LL(0xa0dc5dba,0xe993f5bb),LL(0x724a1380,0x47884109),LL(0x32fe9a04,0x8a0369ab), LL(0x8c927db8,0xea068d60),LL(0x94655741,0xbf5f37cf),LL(0x04b6c7ea,0x47d402a2),LL(0x6af259cb,0x4551c295), + LL(0xed77ee8b,0x698b71e7),LL(0xf309d5c7,0xbddf7bd0),LL(0x34e780ca,0x6201c22c),LL(0x4c295ef4,0xab04f7d8), LL(0x4313a8ce,0x1c947294),LL(0x92ca4cfe,0xe532e4ac),LL(0xd0a7a97a,0x89738f80),LL(0xa580fd5b,0xec088c88), + LL(0x42ce9e51,0x612b1ecc),LL(0xb25fdd2a,0x8f9840fd),LL(0x01e7f839,0x3cda78c0),LL(0xece05480,0x546b3d3a), LL(0x80d30916,0x271719a9),LL(0x584c20c4,0x45497107),LL(0x5bc78608,0xaf8f9478),LL(0x277e2a4c,0x28c7d484), + LL(0x88a2ffe4,0xfce01767),LL(0x28e169a5,0xdc506a35),LL(0x7af9c93a,0x0ea10861),LL(0x03fa0e08,0x1ed24361), LL(0xa3d694e7,0x96eaaa92),LL(0xef50bc74,0xc0f43b4d),LL(0x64114db4,0xce6aa58c),LL(0x7c000fd4,0x8218e8ea), + LL(0x185f8844,0xac815dfb),LL(0x1557abfb,0xcd7e90cb),LL(0xafbfecdf,0x23d16655),LL(0x085cac4a,0x80f3271f), LL(0xd0e62f47,0x7fc39aa7),LL(0x460a48e5,0x88d519d1),LL(0xd28f101e,0x59559ac4),LL(0xca9ae816,0x7981d9e9), + LL(0x9ac38203,0x5c38652c),LL(0x57657fe5,0x86eaf87f),LL(0xe21f5416,0x568fc472),LL(0xe7e597b5,0x2afff39c), LL(0x256d4eab,0x3adbbb07),LL(0x8285ab89,0x22598692),LL(0x041caefe,0x35f8112a),LL(0xa5064c8b,0x95df02e3), + LL(0xc7004bf3,0x4d63356e),LL(0xdb83c7de,0x230a08f4),LL(0x8709a7b7,0xca27b270),LL(0xcb9abd2d,0x0d1c4cc4), LL(0x7550fee8,0x8a0bc66e),LL(0x9cf7247e,0x369cd4c7),LL(0x92b5b7e7,0x75562e84),LL(0x5802af7b,0x8fed0da0), + LL(0xe48fb889,0x6a7091c2),LL(0x7b8a9d06,0x26882c13),LL(0x1b82a0e2,0xa2498663),LL(0x3518152d,0x844ed736), LL(0xd86e27c7,0x282f476f),LL(0x04afefdc,0xa04edaca),LL(0x6119e34d,0x8b256ebc),LL(0x0787d78b,0x56a413e9), +}, +/* digit=19 base_pwr=2^133 */ +{ + LL(0x5a74be50,0x82ee061d),LL(0xdea16ff5,0xe41781c4),LL(0x99bfc8a2,0xe0b0c81e),LL(0x0b547e2d,0x624f4d69), LL(0xbdcc9ae4,0x3a83545d),LL(0x409b1e8e,0x2573dbb6),LL(0xa6c93539,0x482960c4),LL(0x5ae18798,0xf01059ad), + LL(0x3112795f,0x715c9f97),LL(0x984e6ee1,0xe8244437),LL(0xecb66bcd,0x55cb4858),LL(0xabaffbee,0x7c136735), LL(0x5dbec38e,0x54661595),LL(0x388ad153,0x51c0782c),LL(0xc6e0952f,0x9ba4c53a),LL(0x1b21dfa8,0x27e6782a), + LL(0x4ed2dbc2,0x682f903d),LL(0x7c3b2d83,0x0eba59c8),LL(0x9c7e9335,0x8e9dc84d),LL(0x0eb226d7,0x5f9b21b0), LL(0xaf267bae,0xe33bd394),LL(0xbe2e15ae,0xaa86cc25),LL(0x6a8ec500,0x4f0bf67d),LL(0xf9630658,0x5846aa44), + LL(0xe2c2bf15,0xfeb09740),LL(0xa9e99704,0x627a2205),LL(0xc2fbc565,0xec8d73d0),LL(0xc20c8de8,0x223eed8f), LL(0xa8363b49,0x1ee32583),LL(0xc9c2b0a6,0x1a0b6cb9),LL(0x90dbc85c,0x49f7c3d2),LL(0x1ef4c1ac,0xa8dfbb97), + LL(0x65c7c2ab,0xafb34d4c),LL(0xe2c5ea84,0x1d4610e7),LL(0x973c4ab5,0x893f6d1b),LL(0x945ba5c4,0xa3cdd7e9), LL(0x064417ee,0x60514983),LL(0xad6bdf2b,0x1459b23c),LL(0x5cf726c3,0x23b2c341),LL(0x32d6354a,0x3a829635), + LL(0xab192c18,0x294f901f),LL(0x7030164f,0xec5fcbfe),LL(0xe2246ba6,0xe2e2fcb7),LL(0x221a1a0c,0x1e7c88b3), LL(0xc92d88c5,0x72c7dd93),LL(0x1106fb59,0x41c2148e),LL(0xa0f60f14,0x547dd4f5),LL(0x63960f31,0xed9b52b2), + LL(0xb0a5b358,0x6c8349eb),LL(0x9e7e2ed6,0xb154c5c2),LL(0xeda462db,0xcad5eccf),LL(0x2de66b69,0xf2d6dbe4), LL(0x8665e5b2,0x426aedf3),LL(0x7b7f5723,0x488a8513),LL(0x8bcbb386,0x15cc43b3),LL(0xd791d879,0x27ad0af3), + LL(0x846e364f,0xc16c236e),LL(0xdea50ca0,0x7f33527c),LL(0x0926b86d,0xc4810775),LL(0x0598e70c,0x6c2a3609), LL(0xf024e924,0xa6755e52),LL(0x9db4afca,0xe0fa07a4),LL(0x66831790,0x15c3ce7d),LL(0xa6cbb0d6,0x5b4ef350), + LL(0xb6205969,0x2c4aafc4),LL(0xf6c7854f,0x42563f02),LL(0x1d983b48,0x016aced5),LL(0x99949755,0xfeb356d8), LL(0xd1a39bd7,0x8c2a2c81),LL(0xe6934ae9,0x8f44340f),LL(0x447904da,0x148cf91c),LL(0x0f51a926,0x7340185f), + LL(0x7409ab46,0x2f8f00fb),LL(0x80e289b2,0x057e78e6),LL(0xa888e5d1,0x03e5022c),LL(0x9dede4e2,0x3c87111a), LL(0x7809460b,0x5b9b0e1c),LL(0x71c9abc7,0xe751c852),LL(0xc7cc1dc9,0x8b944e28),LL(0x1d3cfa08,0x4f201ffa), + LL(0x3e6721ce,0x02fc905c),LL(0xd0b3674c,0xd52d70da),LL(0x18810da4,0x5dc2e5ca),LL(0x5c69dd99,0xa984b273), LL(0x84de5ca4,0x63b92527),LL(0xc852dec4,0x2f1c9872),LL(0xc2e3de09,0x18b03593),LL(0x9813dc2f,0x19d70b01), + LL(0xa6dc1d29,0x42806b2d),LL(0xf871e144,0xd3030009),LL(0xaaf49276,0xa1feb333),LL(0xc70bc04b,0xb5583b9e), LL(0x95695f20,0x1db0be78),LL(0x89d012b5,0xfc841811),LL(0x05f61643,0x6409f272),LL(0xd5883128,0x40d34174), + LL(0x67419833,0xd79196f5),LL(0x863b7b08,0x6059e252),LL(0x1c56700c,0x84da1817),LL(0xb28d3ec4,0x5758ee56), LL(0x013b0ea6,0x7da2771d),LL(0x54c5e9b9,0xfddf524b),LL(0x24305d80,0x7df4faf8),LL(0x3a97763f,0x58f5c1bf), + LL(0x7c696042,0xa5af37f1),LL(0x4a2538de,0xd4cba22c),LL(0x9ea42600,0x211cb995),LL(0x7b069889,0xcd105f41), LL(0xddb81e74,0xb1e1cf19),LL(0x5157b8ca,0x472f2d89),LL(0xee9db885,0x086fb008),LL(0x0f26d131,0x365cd570), + LL(0xa2be7053,0x284b02bb),LL(0x7ab9a6d6,0xdcbbf7c6),LL(0x20f7a530,0x4425559c),LL(0x188767c8,0x961f2dfa), LL(0x70dc80c4,0xe2fd9435),LL(0xf0784120,0x104d6b63),LL(0x53567122,0x7f592bc1),LL(0xf688ad77,0xf6bc1246), + LL(0x0f15dde9,0x05214c05),LL(0x0d5f2b82,0xa47a76a8),LL(0x62e82b62,0xbb254d30),LL(0x3ec955ee,0x11a05fe0), LL(0x9d529b36,0x7eaff46e),LL(0x8f9e3df6,0x55ab1301),LL(0x99317698,0xc463e371),LL(0xccda47ad,0xfd251438), + LL(0x23d695ea,0xca9c3547),LL(0x16e589b5,0x48ce626e),LL(0xb187d086,0x6b5b64c7),LL(0xb2207948,0xd02e1794), LL(0x7198111d,0x8b58e98f),LL(0xdcf9c3cc,0x90ca6305),LL(0xf34089b0,0x5691fe72),LL(0xfc7c80ff,0x60941af1), + LL(0x22eb51e5,0xa09bc0a2),LL(0xaa9cf09a,0xc0bb7244),LL(0x80159f06,0x36a8077f),LL(0xdddc560e,0x8b5c989e), LL(0x512e1f43,0x19d2f316),LL(0xad08ff62,0x02eac554),LL(0x07d20b4e,0x012ab84c),LL(0xd6d4e4e1,0x37d1e115), + LL(0xab7b19a8,0xb6443e1a),LL(0xdef8cd45,0xf08d067e),LL(0x685e03da,0x63adf3e9),LL(0x4792b916,0xcf15a10e), LL(0xb738a425,0xf44bcce5),LL(0x9636b2fd,0xebe131d5),LL(0x7850d605,0x94068841),LL(0xb40d749d,0x09684eaa), + LL(0x72ba075b,0x8c3c669c),LL(0xba469015,0x89f78b55),LL(0x3e9f8ba8,0x5706aade),LL(0xb32d7ed7,0x6d8bd565), LL(0x805f08d6,0x25f4e63b),LL(0xc3bcc1b5,0x7f48200d),LL(0xb025d847,0x4e801968),LL(0x87cbe0a8,0x74afac04), + LL(0x7e63d690,0x43ed2c2b),LL(0x0223cdb8,0xefb6bbf0),LL(0x2884d3fe,0x4fec3cae),LL(0xd75e25a4,0x065ecce6), LL(0x69f79071,0x6c2294ce),LL(0x044b8666,0x0d9a8e5f),LL(0x17b69d8f,0x5009f238),LL(0xc5dfdaf7,0x3c29f8fe), + LL(0xebae68c4,0x9067528f),LL(0x30c5ba21,0x5b385632),LL(0x1fdd1aec,0x540df119),LL(0xcfba4c78,0xcf37825b), LL(0xbeb11454,0x77eff980),LL(0x60c1b066,0x40a1a991),LL(0xf889a1c7,0xe8018980),LL(0x76c24be0,0xb9c52ae9), + LL(0x45650ef4,0x05fbbcce),LL(0x8aa29ac7,0xae000f10),LL(0x4f04c470,0x884b7172),LL(0x19bb5c25,0x7cd4fde2), LL(0xe8840869,0x6477b22a),LL(0x5fbd0686,0xa8868859),LL(0x1116dfba,0xf23cc02e),LL(0xd87d7776,0x76cd563f), + LL(0xa9d82abf,0xe2a37598),LL(0xe6c170f5,0x5f188ccb),LL(0x5066b087,0x81682200),LL(0xc7155ada,0xda22c212), LL(0xfbddb479,0x151e5d3a),LL(0x6d715b99,0x4b606b84),LL(0xf997cb2e,0x4a73b54b),LL(0x3ecd8b66,0x9a1bfe43), + LL(0x2a67d48a,0x1c312809),LL(0x031fa9e2,0xcd6a671e),LL(0x0e43a34a,0xbec3312a),LL(0x55ef47d3,0x1d935639), LL(0x8fea73ea,0x5ea02489),LL(0xa035afb2,0x8247b364),LL(0x5265b54c,0xb58300a6),LL(0x722c7148,0x3286662f), + LL(0xb4ec4c20,0xb77fd76b),LL(0x0f3fe3fd,0xf0a12fa7),LL(0x41d8c7e8,0xf845bbf5),LL(0x5ec10aa8,0xe4d969ca), LL(0x43e232a3,0x4c0053b7),LL(0x37f8a45a,0xdc7a3fac),LL(0x20d81c8f,0x3c4261c5),LL(0xb00eab00,0xfd4b3453), + LL(0xd36e3062,0x76d48f86),LL(0xa143ff02,0x626c5277),LL(0xaf76f42e,0x538174de),LL(0x6407ceac,0x2267aa86), LL(0x72e572d5,0xfad76351),LL(0xba7330eb,0xab861af7),LL(0x418d8657,0xa0a1c8c7),LL(0x20289a52,0x988821cb), + LL(0xcccc18ad,0x79732522),LL(0xf1a6e027,0xaadf3f8d),LL(0x17c2354d,0xf7382c93),LL(0xd818b689,0x5ce1680c), LL(0xd9ecbee9,0x359ebbfc),LL(0x1cae62ac,0x4330689c),LL(0xc51ac38a,0xb55ce5b4),LL(0xfe238ee8,0x7921dfea), + LL(0x271d1ca5,0x3972bef8),LL(0xe8aabd18,0x3e423bc7),LL(0x44a3e5e3,0x57b09f3f),LL(0x7b444d66,0x5da886ae), LL(0xa9964375,0x68206634),LL(0x699cd0ff,0x356a2fa3),LL(0xdba515e9,0xaf0faa24),LL(0xb321d79a,0x536e1f5c), + LL(0x5c04e4ea,0xd3b9913a),LL(0xd6f11513,0xd549dcfe),LL(0x79fd1d94,0xee227bf5),LL(0xb43f2c67,0x9f35afee), LL(0xf1314f53,0xd2638d24),LL(0xcabcd822,0x62baf948),LL(0x4ef48db0,0x5542de29),LL(0xfc5f6bb2,0xb3eb6a04), + LL(0x1208e16a,0x23c110ae),LL(0xf8363e24,0x1a4d15b5),LL(0x164be00b,0x30716844),LL(0xf6f4690d,0xa8e24824), LL(0x90b170cf,0x548773a2),LL(0x42f191f4,0xa1bef331),LL(0x9247aa97,0x70f418d0),LL(0x48be9147,0xea06028e), + LL(0xdbfb894e,0xe13122f3),LL(0xce274b18,0xbe9b79f6),LL(0xca58aadf,0x85a49de5),LL(0x11487351,0x24957758), LL(0xbb939099,0x111def61),LL(0x26d13694,0x1d6a974a),LL(0xd3fc253b,0x4474b4ce),LL(0x4c5db15e,0x3a1485e6), + LL(0x147c15b4,0xe79667b4),LL(0x7bc61301,0xe34f553b),LL(0x17094381,0x032b80f8),LL(0x723eaa21,0x55d8bafd), LL(0xf1c0e74e,0x5a987995),LL(0xebba289c,0x5a9b292e),LL(0xeb4c8251,0x413cd4b2),LL(0xd162db0a,0x98b5d243), + LL(0x68342520,0xbb47bf66),LL(0xbaa862d1,0x08d68949),LL(0xe906abcd,0x11f349c7),LL(0xed7bf00e,0x454ce985), LL(0xb55b803b,0xacab5c9e),LL(0x31e3c16d,0xb03468ea),LL(0xd273bf12,0x5c24213d),LL(0x71587887,0x211538eb), + LL(0x731dea2d,0x198e4a2f),LL(0x74ed7b2a,0xd5856cf2),LL(0x13a664fe,0x86a632eb),LL(0xbda41291,0x932cd909), LL(0xc0c4ddc0,0x850e95d4),LL(0x347fc2c9,0xc0f422f8),LL(0x86076bcb,0xe68cbec4),LL(0xcd6cd286,0xf9e7c0c0), + LL(0x0f5f27ca,0x65994ddb),LL(0xa80d59ff,0xe85461fb),LL(0x66601023,0xff05481a),LL(0xfc9ebbfb,0xc665427a), LL(0x7587fd52,0xb0571a69),LL(0x8d49efce,0x935289f8),LL(0xea420688,0x61becc60),LL(0x13a786af,0xb22639d9), + LL(0x361ecf90,0x1a8e6220),LL(0x25506463,0x001f23e0),LL(0x0a5c2b79,0xe4ae9b5d),LL(0xd8149db5,0xebc9cdad), LL(0x934aa728,0xb33164a1),LL(0xae9b60f3,0x750eb00e),LL(0x9b9cfbfd,0x5a91615b),LL(0xef45f7f6,0x97015cbf), + LL(0xbf5151df,0xb462c4a5),LL(0xb07118f2,0x21adcc41),LL(0x043fa42c,0xd60c545b),LL(0xe96be1ab,0xfc21aa54), LL(0x4e51ea80,0xe84bc32f),LL(0x259b5d8d,0x3dae45f0),LL(0xc38f1b5e,0xbb73c7eb),LL(0xe8ae617d,0xe405a74a), + LL(0x9f1c56bd,0xbb1ae9c6),LL(0x49f196a4,0x8c176b98),LL(0x6875092b,0xc448f311),LL(0x9f976033,0xb5afe3de), LL(0x145813e5,0xa8dafd49),LL(0xe2b34226,0x687fc4d9),LL(0x4c7ff57f,0xf2dfc92d),LL(0x401f1b46,0x004e3fc1), + LL(0x1430c9ab,0x5afddab6),LL(0x2238e997,0x0bdd41d3),LL(0x418042ae,0xf0947430),LL(0xcdddc4cb,0x71f9adda), LL(0xc52dd907,0x7090c016),LL(0x29e2047f,0xd9bdf44d),LL(0x1b1011a6,0xe6f1fe80),LL(0xd9acdc78,0xb63accbc), + LL(0x1272a95b,0xcfc7e235),LL(0xa6276ac8,0x0c667717),LL(0xe2d7eef7,0x3c0d3709),LL(0x9a685b3e,0x5add2b06), LL(0x14ea5d65,0x363ad32d),LL(0x8d7dd506,0xf8e01f06),LL(0x75b4aac6,0xc9ea2213),LL(0x0d353466,0xed2a2bf9), + LL(0xe9d3a7c3,0x439d79b5),LL(0x81b7f34b,0x8e0ee5a6),LL(0x1dc4ba75,0xcf3dacf5),LL(0xeb3310c7,0x1d3d1773), LL(0x7747ae83,0xa8e67112),LL(0x197d6b40,0x31f43160),LL(0xcd961400,0x0521ccee),LL(0xf6535768,0x67246f11), + LL(0xef0c3133,0x702fcc5a),LL(0x7e16693b,0x247cc45d),LL(0xc729b749,0xfd484e49),LL(0xb218320f,0x522cef7d), LL(0x59ab93b3,0xe56ef405),LL(0x9f181071,0x225fba11),LL(0x15330ed0,0x33bd6595),LL(0x1ddb32f7,0xc4be69d5), + LL(0x0448087c,0x264c7668),LL(0x71432dae,0xac30903f),LL(0x00f9bf47,0x3851b266),LL(0x6cdd6d03,0x400ed311), LL(0xf8fd2424,0x045e79fe),LL(0xfa6da98b,0xfdfd974a),LL(0x0c1e673a,0x45c9f641),LL(0x5b2c5168,0x76f2e733), + LL(0x2a601753,0x1adaebb5),LL(0xc57c2d49,0xb286514c),LL(0x1e0bfd24,0xd8769670),LL(0x04478922,0x950c547e), LL(0xe5d32bfe,0xd1d41969),LL(0x750d6c3e,0x30bc1472),LL(0xe0e27f3a,0x8f3679fe),LL(0xa4a6ee0c,0x8f64a7dc), + LL(0x633dfb1f,0x2fe59937),LL(0x977f2547,0xea82c395),LL(0x661ea646,0xcbdfdf1a),LL(0xb9085451,0xc7ccc591), LL(0x81761e13,0x82177962),LL(0x9196885c,0xda57596f),LL(0x28ffbd70,0xbc17e849),LL(0x2671d36f,0x1e6e0a41), + LL(0x4152fcf5,0x61ae872c),LL(0x9e77e754,0x441c87b0),LL(0xa34dff09,0xd0799dd5),LL(0x88a6b171,0x766b4e44), LL(0x11f1c792,0xdc06a512),LL(0x4be35c3e,0xea02ae93),LL(0xe90c469e,0xe5ca4d6d),LL(0x56e4ff5c,0x4df4368e), + LL(0x4baef62e,0x7817acab),LL(0xa85b91e8,0x9f5a2202),LL(0x6ce57610,0x9666ebe6),LL(0xf73bfe03,0x32ad31f3), LL(0x25bcf4d6,0x628330a4),LL(0x515056e6,0xea950593),LL(0xe1332156,0x59811c89),LL(0x8c11b2d7,0xc89cf1fe), + LL(0x04e60cc0,0x75b63913),LL(0x4625d375,0xce811e8d),LL(0x2d26e562,0x030e43fc),LL(0x608d36a0,0xfbb30b4b), LL(0x48528118,0x634ff82c),LL(0xcd285911,0x7c6fe085),LL(0x99358f28,0x7f2830c0),LL(0x665e6c09,0x2e60a95e), + LL(0x9b785dbf,0x08407d3d),LL(0xa759bce7,0x530889ab),LL(0x52f61239,0xf228e0e6),LL(0x6879be3c,0x2b6d1461), LL(0x51a7bbf7,0xe6902c04),LL(0x76f24a64,0x30ad99f0),LL(0x98bc6da0,0x66d9317a),LL(0xcb596ac0,0xf4f877f3), + LL(0x4c44f119,0xb05ff62d),LL(0xe9b77416,0x4555f536),LL(0x8caed63b,0xc7c0d059),LL(0xc358b2a9,0x0cd2b7ce), LL(0x46945fa3,0x3f33287b),LL(0xd67c8791,0xf8785b20),LL(0x9637bd08,0xc54a7a61),LL(0x18be79d7,0x54d4598c), + LL(0xc46d7ce1,0x889e5acb),LL(0x8b085877,0x9a515bb7),LL(0x0b7a5050,0xfac1a03d),LL(0xf2926035,0x7d3e738a), LL(0x2a6cb0eb,0x861cc2ce),LL(0x8f7adc79,0x6f2e2955),LL(0x33016376,0x61c4d451),LL(0x5ad59090,0xd9fd2c80), + LL(0xb2b836a1,0xe5a83738),LL(0x7c0d6622,0x855b41a0),LL(0x7cc19af1,0x186fe317),LL(0xfdd99acb,0x6465c1ff), LL(0x6974b99e,0x46e5c23f),LL(0xa2717cbe,0x75a7cf8b),LL(0x062be658,0x4d2ebc3f),LL(0x5f209c98,0x094b4447), + LL(0xb940cb5a,0x4af285ed),LL(0x7cc82f10,0x6706d792),LL(0x030526fa,0xc8c8776c),LL(0xa0da9140,0xfa8e6f76), LL(0x591ee4f0,0x77ea9d34),LL(0x40274166,0x5f46e337),LL(0xea671457,0x1bdf98bb),LL(0x862a1fe2,0xd7c08b46), + LL(0x1c08ad63,0x46cc303c),LL(0x4c845e7b,0x99543440),LL(0x48f36bf7,0x1b8fbdb5),LL(0x8c8273a7,0x5b82c392), LL(0x928435d5,0x08f712c4),LL(0x79330380,0x071cf0f1),LL(0xa8da054a,0xc74c2d24),LL(0x43c46b5c,0xcb0e7201), + LL(0xc0b7eff3,0x0ad7337a),LL(0xc5e48b3c,0x8552225e),LL(0x73f13a5f,0xe6f78b0c),LL(0x82349cbe,0x5e70062e), LL(0xe7073969,0x6b8d5048),LL(0xc33cb3d2,0x392d2a29),LL(0x4ecaa20f,0xee4f727c),LL(0x2ccde707,0xa068c99e), + LL(0xb87a2913,0xfcd5651f),LL(0x3cc252f0,0xea3e3c15),LL(0x3b6cd3e4,0x777d92df),LL(0xc5a732e7,0x7a414143), LL(0xa71ff493,0xa895951a),LL(0xbbd37cf6,0xfe980c92),LL(0xdecfeeff,0x45bd5e64),LL(0xa44c43e9,0x910dc2a9), + LL(0xcca9f54d,0xcb403f26),LL(0x9303f6db,0x928bbdfb),LL(0xa9eee67c,0x3c37951e),LL(0xf79961c3,0x3bd61a52), LL(0x395c9a79,0x09a238e6),LL(0x61eb352d,0x6940ca2d),LL(0xc1875631,0x7d1e5c5e),LL(0x1e1b20d1,0x1e19742c), + LL(0x23fc2e6e,0x4633d908),LL(0x08959149,0xa76e29a9),LL(0x84ed7da5,0x61069d9c),LL(0x5dbcad51,0x0baa11cf), LL(0x961849da,0xd01eec64),LL(0xaf3d8c28,0x93b75f1f),LL(0x1ca2ee44,0x57bc4f9f),LL(0x00e00558,0x5a26322d), + LL(0x61a023ef,0x1888d658),LL(0xb9e5246e,0x1d72aab4),LL(0xe5563ec0,0xa9a26348),LL(0xc3439a43,0xa0971963), LL(0xadb9b5b7,0x567dd54b),LL(0xc45a524b,0x73fac1a1),LL(0xfe38e608,0x8fe97ef7),LL(0x3f384f48,0x608748d2), + LL(0xc486094f,0xb0571794),LL(0x8bf3a8d6,0x869254a3),LL(0x310b0e25,0x148a8dd1),LL(0x9aa3f7d8,0x99ab9f3f), LL(0x6706c02e,0x0927c68a),LL(0x69790e6c,0x22b5e76c),LL(0x6c71376c,0x6c325260),LL(0x09ef6657,0x53a57690), + LL(0xedffcf3a,0x8d63f852),LL(0x3c0a6f55,0xb4d2ed04),LL(0x12519b9e,0xdb3aa8de),LL(0x1e0a569a,0x5d38e9c4), LL(0x303747e2,0x871528bf),LL(0xf5b5c18d,0xa208e77c),LL(0xca6bf923,0x9d129c88),LL(0xbf02839f,0xbcbf197f), + LL(0x27323194,0x9b9bf030),LL(0x339ca59d,0x3b055a8b),LL(0x0f669520,0xb46b2312),LL(0x497e5f24,0x19789f1f), LL(0xaaf01801,0x9c499468),LL(0x8b69d59c,0x72ee1190),LL(0xacf4c079,0x8bd39595),LL(0x8e0cd048,0x3ee11ece), + LL(0x1ed66f18,0xebde86ec),LL(0xd61fce43,0x225d906b),LL(0xe8bed74d,0x5cab07d6),LL(0x27855ab7,0x16e4617f), LL(0xb2fbc3dd,0x6568aadd),LL(0x8aeddf5b,0xedb5484f),LL(0x6dcf2fad,0x878f20e8),LL(0x615f5699,0x3516497c), +}, +/* digit=20 base_pwr=2^140 */ +{ + LL(0xfa181e69,0xef0a3fec),LL(0x30d69a98,0x9ea02f81),LL(0x66eab95d,0xb2e9cf8e),LL(0x24720021,0x520f2beb), LL(0x1df84361,0x621c540a),LL(0x71fa6d5d,0x12037721),LL(0x0ff5f6ff,0x6e3c7b51),LL(0xabb2bef3,0x817a069b), + LL(0xb294cda6,0x83572fb6),LL(0xb9039f34,0x6ce9bf75),LL(0x095cbb21,0x20e012f0),LL(0xd063f0da,0xa0aecc1b), LL(0xf02909e5,0x57c21c3a),LL(0x48ce9cdc,0xc7d59ecf),LL(0x8ae336f8,0x2732b844),LL(0x3f4f85f4,0x056e3723), + LL(0x89e800ca,0x8a10b531),LL(0x145208fd,0x50fe0c17),LL(0xb714ba37,0x9e43c0d3),LL(0x34189acc,0x427d200e), LL(0xe616e2c0,0x05dee24f),LL(0xee1854c1,0x9c25f4c8),LL(0x8f342a73,0x4d3222a5),LL(0xa027c952,0x0807804f), + LL(0x4f0d56f3,0xc222653a),LL(0xca28b805,0x961e4047),LL(0x4a73434b,0x2c03f8b0),LL(0xab712a19,0x4c966787), LL(0x864fee42,0xcc196c42),LL(0x5b0ece5c,0xc1be93da),LL(0xc131c159,0xa87d9f22),LL(0xdce45655,0x2bb6d593), + LL(0xb809b7ce,0x22c49ec9),LL(0xe2c72c2c,0x8a41486b),LL(0xfea0bf36,0x813b9420),LL(0xa66dac69,0xb3d36ee9), LL(0x328cc987,0x6fddc08a),LL(0x3a326461,0x0a3bcd2c),LL(0xd810dbba,0x7103c49d),LL(0x4b78a4c4,0xf9d81a28), + LL(0xe4d55941,0x3de865ad),LL(0x30384087,0xdedafa5e),LL(0x4ef18b9b,0x6f414abb),LL(0xfaee5268,0x9ee9ea42), LL(0x37a55a4a,0x260faa16),LL(0x015f93b9,0xeb19a514),LL(0x9e9c3598,0x51d7ebd2),LL(0x1932178e,0x523fc56d), + LL(0xb98fe684,0x501d070c),LL(0x124a1458,0xd60fbe9a),LL(0x92bc6b3f,0xa45761c8),LL(0xfe6f27cb,0xf5384858), LL(0xb59e763b,0x4b0271f7),LL(0x5b5a8e5e,0x3d4606a9),LL(0x05a48292,0x1eda5d9b),LL(0xe6fec446,0xda7731d0), + LL(0x90d45871,0xa3e33693),LL(0x06166d8d,0xe9764040),LL(0x89a90403,0xb5c33682),LL(0x72f1d637,0x4bd17983), LL(0xd5d2c53a,0xa616679e),LL(0xfdcf3b87,0x5ec4bcd8),LL(0xb66a694e,0xae6d7613),LL(0xe3fc27e5,0x7460fc76), + LL(0x95caabee,0x70469b82),LL(0x889501e3,0xde024ca5),LL(0x076ed265,0x6bdadc06),LL(0x5a0ef8b2,0x0cb1236b), LL(0x0972ebf9,0x4065ddbf),LL(0x22aca432,0xf1dd3875),LL(0x744aff76,0xa88b97cf),LL(0xfe8e3d24,0xd1359afd), + LL(0x91502cf3,0x52a3ba2b),LL(0x084db75d,0x2c3832a8),LL(0xde30b1c9,0x04a12ddd),LL(0xe31fd60c,0x7802eabc), LL(0xa37fddab,0x33707327),LL(0xfaafa973,0x65d6f2ab),LL(0x11e6f91a,0x3525c5b8),LL(0x5f46530b,0x76aeb0c9), + LL(0x2f93a675,0xe8815ff6),LL(0x05f48679,0xa6ec9684),LL(0x358ae884,0x6dcbb556),LL(0xe19e3873,0x0af61472), LL(0xa5f696be,0x72334372),LL(0x6f22fb70,0xc65e57ea),LL(0x946cea90,0x268da30c),LL(0x65681b2a,0x136a8a87), + LL(0x0f9f44d4,0xad5e81dc),LL(0x2c46585a,0xf09a6960),LL(0xc447d1b1,0xd1649164),LL(0x879dc8b1,0x3b4b36c8), LL(0x3b6b234c,0x20d4177b),LL(0x1730d9d0,0x096a2505),LL(0xef80531d,0x0611b9b8),LL(0x64bb495d,0xba904b3b), + LL(0x93a3147a,0x1192d9d4),LL(0x9a565545,0x9f30a5dc),LL(0x6ef07212,0x90b1f9cb),LL(0x0d87fc13,0x29958546), LL(0xc17db9ba,0xd3323eff),LL(0xcb1644a8,0xcb18548c),LL(0x4f49ffbc,0x18a306d4),LL(0x4c2e8684,0x28d658f1), + LL(0xa99f8c71,0x44ba60cd),LL(0x4bf742ff,0x67b7abdb),LL(0x914b3f99,0x66310f9c),LL(0xf412c161,0xae430a32), LL(0x88ace52f,0x1e6776d3),LL(0x52d7067d,0x4bc0fa24),LL(0x8f07cd1b,0x03c286aa),LL(0xa985b2c1,0x4cb8f38c), + LL(0x8c3bff36,0x83ccbe80),LL(0x5263e575,0x005a0bd2),LL(0x259bdcd1,0x460d7dda),LL(0xfa5cab6b,0x4a1c5642), LL(0x9fe4fc88,0x2b7bdbb9),LL(0xcc97bbb5,0x09418e28),LL(0xa12321ae,0xd8274fb4),LL(0x5c87b64e,0xb137007d), + LL(0xc63c4962,0x80531fe1),LL(0x981fdb25,0x50541e89),LL(0xfd4c2b6b,0xdc1291a1),LL(0xa6df4fca,0xc0693a17), LL(0x0117f203,0xb2c4604e),LL(0x0a99b8d0,0x245f1963),LL(0xc6212c44,0xaedc20aa),LL(0x520f52a8,0xb1ed4e56), + LL(0xf8547be3,0xfe48f575),LL(0xa9e45f98,0x0a7033cd),LL(0x18c50100,0x4b45d3a9),LL(0xa61d41da,0xb2a6cd6a), LL(0x57933c6b,0x60bbb4f5),LL(0x2b0d7ffc,0xa7538ebd),LL(0x8cd626b6,0x9ea3ab8d),LL(0x3601625a,0x8273a484), + LL(0x0168e508,0x88859845),LL(0x99a94abd,0x8cbc9bb2),LL(0xfab0a671,0x713ac792),LL(0x6c9ebffc,0xa3995b19), LL(0x1239e152,0xe711668e),LL(0xbbb8dff4,0x56892558),LL(0xdbf17963,0x8bfc7dab),LL(0xb3de1253,0x5b59fe5a), + LL(0x34a9f7ae,0x7e3320eb),LL(0xd751efe4,0xe5e8cf72),LL(0xd9be2f37,0x7ea003bc),LL(0xb6c08ef7,0xc0f551a0), LL(0x038f6725,0x56606268),LL(0x6d92d3b6,0x1dd38e35),LL(0xc3cbd686,0x07dfce7c),LL(0x651c5da8,0x4e549e04), + LL(0x08b19340,0x4058f93b),LL(0xcac6d89d,0xc2fae6f4),LL(0x8f159cc7,0x4bad8a8c),LL(0xcb0b601c,0x0ddba4b3), LL(0x1dd95f8c,0xda4fc7b5),LL(0xcea5c255,0x1d163cd7),LL(0x274a8c4c,0x30707d06),LL(0x2802e9ce,0x79d9e008), + LL(0xe6ddd505,0x02a29ebf),LL(0xb50bed1a,0x37064e74),LL(0xa7327d57,0x3f6bae65),LL(0xf83920bc,0x3846f5f1), LL(0x60df1b9b,0x87c37491),LL(0x2d1da29f,0x4cfb2895),LL(0x4ed1743c,0x10a478ca),LL(0x3edd47c6,0x390c6030), + LL(0x8c0a78de,0x8f3e5312),LL(0x1e85df70,0xccd02bda),LL(0xa61b6582,0xd6c75c03),LL(0xfc0eebd1,0x0762921c), LL(0xd85010c0,0xd34d0823),LL(0x0044cf1f,0xd73aaacb),LL(0xa3b5e78a,0xfb4159bb),LL(0xe5826f3f,0x2287c7f7), + LL(0x580b1a01,0x4aeaf742),LL(0x60423b79,0xf080415d),LL(0xa7dea144,0xe12622cd),LL(0x59d62472,0x49ea4996), LL(0x571f3913,0xb42991ef),LL(0xf5b25a8a,0x0610f214),LL(0x30b79e8f,0x47adc585),LL(0x07a065a2,0xf90e3df6), + LL(0x43e2e034,0x5d0a5deb),LL(0x444024aa,0x53fb5a34),LL(0x6b0c9f7f,0xa8628c68),LL(0xac563656,0x9c69c29c), LL(0xbace47b6,0x5a231feb),LL(0x9ea5a2ec,0xbdce0289),LL(0x9463853e,0x05da1fac),LL(0x509e78aa,0x96812c52), + LL(0x57151692,0xd3fb5771),LL(0xd98e1c44,0xeb2721f8),LL(0x32399be1,0xc0506087),LL(0xd979d8b8,0xda5a5511), LL(0xc6f56780,0x737ed55d),LL(0x0dc7a7f4,0xe20d3004),LL(0xf5941a03,0x02ce7301),LL(0xed30f83a,0x91ef5215), + LL(0x4092d85f,0x28727fc1),LL(0x5c49e41a,0x72d223c6),LL(0xba6a4d81,0xa7cf30a2),LL(0xb030d87d,0x7c086209), LL(0xfc588b09,0x04844c7d),LL(0x5874bbb0,0x728cd499),LL(0xe84c0495,0xcc1281ee),LL(0xec31958f,0x0769b5ba), + LL(0xf99c2471,0x665c228b),LL(0x191eb110,0xf2d8a11b),LL(0xd36d7024,0x4594f494),LL(0xcdcb25a1,0x482ded8b), LL(0xdadd4885,0xc958a9d8),LL(0xf1d2b547,0x7004477e),LL(0x2a0af550,0x0a45f6ef),LL(0x2f8d6351,0x4fc739d6), + LL(0x786f08a9,0x75cdaf27),LL(0x42c2737f,0x8700bb26),LL(0x1c4e2670,0x855a7141),LL(0x15076fef,0x810188c1), LL(0xabcd3297,0xc251d0c9),LL(0xf48108eb,0xae4c8967),LL(0x18ceed30,0xbd146de7),LL(0xc986bced,0xf9d4f07a), + LL(0x83fa1e08,0x5ad98ed5),LL(0xbeabd1fb,0x7780d33e),LL(0x903b1196,0xe330513c),LL(0xa47bc8c4,0xba11de9e), LL(0x02c2d064,0x684334da),LL(0xa48de23b,0x7ecf360d),LL(0x0a9089d8,0x57a1b474),LL(0xff36734c,0xf28fa439), + LL(0xea4570b3,0xf2a482cb),LL(0xa5ebcee9,0xee65d68b),LL(0xb9694cd5,0x988d0036),LL(0x37885d32,0x53edd0e9), LL(0xbeb9bc6d,0xe37e3307),LL(0x9f5c6768,0xe9abb907),LL(0x51f2160f,0x4396ccd5),LL(0x47336da6,0x2500888c), + LL(0x926fce43,0x383f9ed9),LL(0x04da2930,0x809dd1c7),LL(0x8a4cb227,0x30f6f596),LL(0x73a56b38,0x0d700c7f), LL(0xab64a065,0x1825ea33),LL(0x1338df80,0xaab9b735),LL(0x9b63f57f,0x1516100d),LL(0x27a6a634,0x2574395a), + LL(0x700a1acd,0xb5560fb6),LL(0xfd999681,0xe823fd73),LL(0x6cb4e1ba,0xda915d1f),LL(0x6ebe00a3,0x0d030118), LL(0x89fca8cd,0x744fb0c9),LL(0xf9da0e0b,0x970d01db),LL(0x7931d76f,0x0ad8c564),LL(0xf659b96a,0xb15737bf), + LL(0xa8b484e7,0xdc9933e8),LL(0x7a26dec7,0xb2fdbdf9),LL(0x9f1f0136,0x2349e9a4),LL(0x70fddddb,0x7860368e), LL(0xf9ad3e18,0xd93d2c1c),LL(0x689f4e79,0x6d6c5f17),LL(0xb24ff1b6,0x7a544d91),LL(0xfe16cd8c,0x3e12a5eb), + LL(0xa56b872f,0x543574e9),LL(0xfcf68ea2,0xa1ad550c),LL(0x3f560ef7,0x689e37d2),LL(0xc9d47a8b,0x8c54b9ca), LL(0x088ac342,0x46d40a4a),LL(0x1576c6d0,0xec450c7c),LL(0x1f9689e9,0xb589e31c),LL(0xb8781718,0xdacf2602), + LL(0xc8cb6b42,0xa89237c6),LL(0xb96ef381,0x1326fc93),LL(0xb5f07825,0x55d56c6d),LL(0x7449e22d,0xacba2eea), LL(0x633c3000,0x74e0887a),LL(0xd7cbcf71,0xcb6cd172),LL(0xc36cf1be,0x309e81de),LL(0x60ae399b,0x07a18a6d), + LL(0x9edce57e,0xb36c2679),LL(0xdf001d41,0x52b892f4),LL(0x16a1f2c6,0xd884ae5d),LL(0xefcc370a,0x9b329424), LL(0xbd2e21df,0x3120daf2),LL(0x02470a99,0x55298d2d),LL(0xa05db32e,0x0b78af6c),LL(0x601f5636,0x5c76a331), + LL(0xf8a4f29c,0xaae861ff),LL(0xd68f8d49,0x70dc9240),LL(0x81b1321c,0x960e649f),LL(0x8792e4ce,0x3d2c801b), LL(0x42521876,0xf479f772),LL(0x416c79b1,0x0bed93bc),LL(0x263e5bc9,0xa67fbc05),LL(0x521db049,0x01e8e630), + LL(0xc6f3431e,0x76f26738),LL(0xe3267541,0xe609cb02),LL(0x818c877c,0xb10cff2d),LL(0x786a13cb,0x1f0e75ce), LL(0x1158544d,0xf4fdca64),LL(0x6cb71ed0,0x5d777e89),LL(0xa9aa4755,0x3c233737),LL(0xe527ab40,0x7b453192), + LL(0x39f05ffe,0xdb59f688),LL(0x6d82574e,0x8f4f4be0),LL(0xee292d1b,0xcce3450c),LL(0x61ccd086,0xaa448a12), LL(0xf7914967,0xabce91b3),LL(0x1908a5ed,0x4537f09b),LL(0xf51042e7,0xa812421e),LL(0xec0b3a34,0xfaf5cebc), + LL(0x4ca6b39a,0x730ffd87),LL(0x02efd342,0x70fb72ed),LL(0xd75c8edb,0xeb4735f9),LL(0xc278aa51,0xc11f2157), LL(0xbf3bfebf,0xc459f635),LL(0x6bd9601f,0x3a1ff0b4),LL(0xc420cb73,0xc9d12823),LL(0x3c2915a3,0x3e9af3e2), + LL(0xb41c3440,0xe0c82c72),LL(0xe3039a5f,0x175239e5),LL(0x558795a3,0xe1084b8a),LL(0xd01e5c60,0x328d0a1d), LL(0xd3788a04,0x0a495f2e),LL(0x66c11a9f,0x25d8ff16),LL(0x9ed692d6,0xf5155f05),LL(0x4f425fe4,0x954fa107), + LL(0xe98aaa99,0xd16aabf2),LL(0x96b0f88a,0x90cd8ba0),LL(0xc154026a,0x957f4782),LL(0x52af56d2,0x54ee0734), LL(0x45b4147a,0xbcf89e54),LL(0x9a52816c,0x3d102f21),LL(0x39b62e77,0x6808517e),LL(0x69169ad8,0x92e25421), + LL(0xbb608558,0xd721d871),LL(0xf6d4ff9b,0x60e4ebae),LL(0x41f2763e,0x0ba10819),LL(0x51ee3247,0xca2e45be), LL(0x2bfd7a5f,0x66d172ec),LL(0x74d0b12d,0x528a8f2f),LL(0xdabe70dc,0xe17f1e38),LL(0x9f93983c,0x1d5d7316), + LL(0xdf423e31,0x51b2184a),LL(0xaedb1a10,0xcb417291),LL(0x625bcab9,0x2054ca93),LL(0xa98998f0,0x54396860), LL(0xa54ae57e,0x4e53f6c4),LL(0xee648e9d,0x0ffeb590),LL(0x6afaf6bc,0xfbbdaadc),LL(0xaa3bfb8a,0xf88ae796), + LL(0xd2359ed9,0x209f1d44),LL(0xf3544ce2,0xac68dd03),LL(0xfd51e569,0xf378da47),LL(0x2cc80097,0xe1abd860), LL(0x343b6e3a,0x23ca18d9),LL(0xb40a1bae,0x480797e8),LL(0x533f3e67,0xd1f0c717),LL(0x06e6cdfc,0x44896970), + LL(0x52a82e8d,0x8ca21055),LL(0x78460cdc,0xb2caf785),LL(0xe9037178,0x4c1b7b62),LL(0xdb514b58,0xefc09d2c), LL(0x9113be5c,0x5f2df9ee),LL(0xb3f9271c,0x2fbda78f),LL(0x8f83fc54,0xe09a81af),LL(0x8afb5141,0x06b13866), + LL(0x43e3865d,0x38f6480f),LL(0x1ddf47d9,0x72dd77a8),LL(0x4c205ff7,0xf2a8e971),LL(0x9d088ad8,0x46d449d8), LL(0x185d706f,0x926619ea),LL(0xc7dd7f62,0xe47e02eb),LL(0x8cbc2031,0xe7f120a7),LL(0x998d4ac9,0xc18bef00), + LL(0x6bdf22da,0x18f37a9c),LL(0x90dc82df,0xefbc432f),LL(0x5d703651,0xc52cef8e),LL(0xd99881a5,0x82887ba0), LL(0xb920ec1d,0x7cec9dda),LL(0xec3e8d3b,0xd0d7e8c3),LL(0x4ca88747,0x445bc395),LL(0x9fd53535,0xedeaa2e0), + LL(0x6cc87475,0x461b1d93),LL(0x6d2383bd,0xd92a52e2),LL(0xd7903546,0xfabccb59),LL(0x3d14b112,0x6111a761), LL(0xb3d5f612,0x0ae584fe),LL(0x60e828ec,0x5ea69b8d),LL(0x54087030,0x6c078985),LL(0xac4821fe,0x649cab04), + LL(0x8bdce214,0x25ecedcf),LL(0x86af7361,0xb5622f72),LL(0x7038b9e2,0x0e1227aa),LL(0xac20fa77,0xd0efb273), LL(0x79df975b,0x817ff88b),LL(0x1999503e,0x856bf286),LL(0x5038ec46,0xb4d5351f),LL(0xfc42af6e,0x740a52c5), + LL(0x2cbb1a3f,0x2e38bb15),LL(0x17a83429,0xc3eb99fe),LL(0xdd66bb74,0xca4fcbf1),LL(0xcde5e8fc,0x880784d6), LL(0xb4e7a0be,0xddc84c1c),LL(0xbd15a72f,0x8780510d),LL(0x81ec30e1,0x44bcf1af),LL(0x0a61073e,0x141e50a8), + LL(0x47be87ae,0x0d955718),LL(0xf76a4372,0x68a61417),LL(0xc607c3d3,0xf57e7e87),LL(0x5252f332,0x043afaf8), LL(0x1552a4d2,0xcc14e121),LL(0xbb4d4ab4,0xb6dee692),LL(0xa03816a4,0xb6ab74c8),LL(0x6f394a29,0x84001ae4), + LL(0xd795fb45,0x5bed8344),LL(0xb79f55a5,0x57326e7d),LL(0x4accdffc,0xc9533ce0),LL(0x3993fa04,0x53473caf), LL(0xa13df4c8,0x7906eb93),LL(0x97cbe46f,0xa73e51f6),LL(0x0ae4ccf8,0xd1ab3ae1),LL(0x8a5b3dbc,0x25614508), + LL(0x11a71b27,0x61eff962),LL(0x6bb7fa39,0xdf71412b),LL(0x2bd7f3ef,0xb31ba6b8),LL(0x69180d29,0xb0b9c415), LL(0x014cdde5,0xeec14552),LL(0x227b4bbb,0x702c624b),LL(0xd3e988f3,0x2b15e8c2),LL(0xa4f7fd04,0xee3bcc6d), + LL(0x42ac6c85,0x9d00822a),LL(0x1df9f2b7,0x2db0cea6),LL(0x42de1e58,0xd7cad2ab),LL(0x2d6fbb61,0x346ed526), LL(0x1a2faf09,0xb3962995),LL(0x7c25612e,0x2fa8a580),LL(0x7cf56490,0x30ae04da),LL(0x0eea3961,0x75662908), + LL(0x3d080847,0x3609f5c5),LL(0x5241d4f6,0xcb081d39),LL(0x77961a63,0xb4fb3810),LL(0x2abb66fc,0xc20c5984), LL(0xf902f245,0x3d40aa7c),LL(0x4e536b1e,0x9cb12736),LL(0x99b3134f,0x5eda24da),LL(0x5cd011af,0xafbd9c69), + LL(0xc7088c7d,0x9a16e30a),LL(0x3207389f,0x5ab65710),LL(0xe7407a53,0x1b09547f),LL(0x4fdc6eab,0x2322f9d7), LL(0x7430de4d,0xc0f2f22d),LL(0xe68ca9a9,0x19382696),LL(0x918e5868,0x17f1eff1),LL(0x586f4204,0xe3b5b635), + LL(0x3fbc4341,0x146ef980),LL(0x5b5eed4e,0x359f2c80),LL(0x7482e41d,0x9f35744e),LL(0xf3b224c2,0x9a9ac3ec), LL(0x91fc50ae,0x9161a6fe),LL(0xc613fa7c,0x89ccc66b),LL(0xc732f15a,0x89268b14),LL(0xb467ed03,0x7cd6f4e2), + LL(0xce56b40e,0xfbf79869),LL(0xc02dde98,0xf93e094c),LL(0xedee2cd7,0xefe0c3a8),LL(0xb268fd42,0x90f3ffc0), LL(0x08241aed,0x81a7fd56),LL(0x00b1afe8,0x95ab7ad8),LL(0x3e310d52,0x40127056),LL(0x09d9fc43,0xd3ffdeb1), + LL(0xd11a8594,0xc8f85c91),LL(0x31cf6db8,0x2e74d258),LL(0x02b5dfd0,0x829c7ca3),LL(0x69143c86,0xe389cfbe), LL(0x941768d8,0xd01b6405),LL(0x03bf825d,0x45103995),LL(0x56cd17e2,0xcc4ee166),LL(0xba037e79,0xbea3c283), + LL(0xd9a47520,0x4e1ac06e),LL(0xaf852404,0xfbfe18aa),LL(0x8087648a,0x5615f8e2),LL(0xb9d150d9,0x7301e47e), LL(0xb299b977,0x79f9f9dd),LL(0xa5b78314,0x76697a7b),LL(0x7d7c90e7,0x10d67468),LL(0x937210b5,0x7afffe03), + LL(0x28c22cee,0x5aef3e4b),LL(0x09fd55ae,0xefb0ecd8),LL(0x0d2a5d6a,0x4cea7132),LL(0x01db6357,0x9cfb5fa1), LL(0xf36e1ac5,0x395e0b57),LL(0x36cafb7d,0x008fa9ad),LL(0x5308c4db,0x8f6cdf70),LL(0x95ed2477,0x51527a37), + LL(0x5bd21311,0xba0dee30),LL(0x909c90d7,0x6ed41b22),LL(0x7c8696d3,0xc5f6b758),LL(0x3ce83a80,0x0db8eaa8), LL(0xb24b4b6f,0xd297fe37),LL(0x522d1f0d,0xfe58afe8),LL(0x8c98dbd9,0x97358736),LL(0x9454a527,0x6bc226ca), + LL(0xce53c2d0,0xa12b384e),LL(0x5e4606da,0x779d897d),LL(0x73ec12b0,0xa53e47b0),LL(0x5756f1ad,0x462dbbba), LL(0xcafe37b6,0x69fe09f2),LL(0xecce2e17,0x273d1ebf),LL(0x3cf607fd,0x8ac1d538),LL(0x12e10c25,0x8035f7ff), +}, +/* digit=21 base_pwr=2^147 */ +{ + LL(0x7e6c5520,0x854d34c7),LL(0xdcb9ea58,0xc27df9ef),LL(0xd686666d,0x405f2369),LL(0x0417aa85,0x29d1febf), LL(0x93470afe,0x9846819e),LL(0xe2a27f9e,0x3e6a9669),LL(0xe31e6504,0x24d008a2),LL(0x9cb7680a,0xdba7cecf), + LL(0x338d6e43,0xecaff541),LL(0x4541d5cc,0x56f7dd73),LL(0x96bc88ca,0xb5d426de),LL(0x9ed3a2c3,0x48d94f6b), LL(0x2ef8279c,0x6354a3bb),LL(0x0b1867f2,0xd575465b),LL(0x95225151,0xef99b0ff),LL(0xf94500d8,0xf3e19d88), + LL(0xe32dd620,0x92a83268),LL(0x627849a2,0x913ec99f),LL(0x2c378882,0xedd8fdfa),LL(0xee6f8cfe,0xaf96f33e), LL(0xdc3fa8a5,0xc06737e5),LL(0xb0b03a1d,0x236bb531),LL(0x89f037b0,0x33e59f29),LL(0xd9a12a53,0x13f9b5a7), + LL(0x51efb310,0x0d0df6ce),LL(0x958df5be,0xcb5b2eb4),LL(0x36158e59,0xd6459e29),LL(0x1466e336,0x82aae2b9), LL(0x411aa636,0xfb658a39),LL(0xd4c0a933,0x7152ecc5),LL(0x49f026b7,0xf10c758a),LL(0xcb09311f,0xf4837f97), + LL(0xc753c45f,0xddfb02c4),LL(0xf9c840fe,0x18ca81b6),LL(0xb0f8a3e6,0x846fd09a),LL(0xe7733dbc,0xb1162add), LL(0x236e3ab6,0x7070ad20),LL(0xb2a56326,0xf88cdaf5),LL(0x997cbc7a,0x05fc8719),LL(0x4b665272,0x442cd452), + LL(0xb71698f5,0x7807f364),LL(0x9f7b605e,0x6ba418d2),LL(0xa03b2cbb,0xfd20b00f),LL(0xda54386f,0x883eca37), LL(0xf3437f24,0xff0be43f),LL(0xa48bb33c,0xe910b432),LL(0x329df765,0x4963a128),LL(0xbe2fe6f7,0xac1dd556), + LL(0x24a0a3fc,0x557610f9),LL(0xe881c3f9,0x38e17bf4),LL(0xed0dac99,0x6ba84faf),LL(0x59eeb918,0xd4a222c3), LL(0x13f542b6,0xc79c1dbe),LL(0xe425d457,0x1fc65e0d),LL(0x1debb779,0xeffb754f),LL(0x9e08af60,0x638d8fd0), + LL(0x626332d5,0x994f523a),LL(0x5561bb44,0x7bc38833),LL(0x3d845ea2,0x005ed4b0),LL(0xc2a1f08a,0xd39d3ee1), LL(0xe7676b0d,0x6561fdd3),LL(0xfb706017,0x620e35ff),LL(0xf264f9a8,0x36ce424f),LL(0xda2681f7,0xc4c3419f), + LL(0x69beb6e8,0xfb6afd2f),LL(0x6d700d03,0x3a50b993),LL(0x0c83a14f,0xc840b2ad),LL(0x54085bef,0x573207be), LL(0x09fe7e5b,0x5af882e3),LL(0x3b40a7e1,0x957678a4),LL(0x543056e2,0x172d4bdd),LL(0x0df13c0a,0x9c1b26b4), + LL(0xf405ff06,0x1c30861c),LL(0x486e828b,0xebac86bd),LL(0x636933fc,0xe791a971),LL(0x7aeee947,0x50e7c2be), LL(0xfa90d767,0xc3d4a095),LL(0xe670ab7b,0xae60eb7b),LL(0x397b056d,0x17633a64),LL(0x105012aa,0x93a21f33), + LL(0xabb88643,0x663c370b),LL(0x22e21599,0x91df36d7),LL(0x8b761671,0x183ba835),LL(0x728f3bf1,0x381eea1d), LL(0x39966e6c,0xb9b2f1ba),LL(0xe7295492,0x7c464a28),LL(0x09b26b7f,0x0fd5f70a),LL(0xfbe009df,0xa9aba1f9), + LL(0x369b87ad,0x857c1f22),LL(0x32fca556,0x3c00e5d9),LL(0x90b06466,0x1ad74cab),LL(0x550faaf2,0xa7112386), LL(0x6d9bd5f5,0x7435e198),LL(0x59c3463f,0x2dcc7e38),LL(0xca7bd4b2,0xdc7df748),LL(0x9dec2f31,0x13cd4c08), + LL(0xe3237710,0x0d3b5df8),LL(0xcbd2f7b0,0x0dadb26e),LL(0xe4aa082b,0x9f5966ab),LL(0x350e966e,0x666ec8de), LL(0xee524216,0x1bfd1ed5),LL(0x41dab0b6,0xcd93c59b),LL(0xd186d6ba,0x658a8435),LL(0x159d1195,0x1b7d34d2), + LL(0x22caf46b,0x5936e460),LL(0x9a96fe4f,0x6a45dd8f),LL(0xb98f474e,0xf7925434),LL(0x0053ef15,0x41410412), LL(0x41de97bf,0x71cf8d12),LL(0xbd80bef4,0xb8547b61),LL(0xc4db0037,0xb47d3970),LL(0xfef20dff,0xf1bcd328), + LL(0x10caad67,0x31a92e09),LL(0x5531a1e1,0x1f591960),LL(0x5f4fc840,0x3bb852e0),LL(0x93a72c6c,0x63e297ca), LL(0x49abad67,0x3c2b0b2e),LL(0xed3db0d9,0x6ec405fc),LL(0x7fef1d40,0xdc14a530),LL(0x280896fc,0xccd19846), + LL(0x9bb81648,0x00f83176),LL(0x653120d0,0xd69eb485),LL(0x4ccabc62,0xd17d75f4),LL(0xb749fcb1,0x34a07f82), LL(0xbbfb5554,0x2c3af787),LL(0x62e283f8,0xb06ed4d0),LL(0xa19213a0,0x5722889f),LL(0xdcf3c7b4,0x162b085e), + LL(0xe0dd3eca,0xbcaecb31),LL(0xe52f13a5,0xc6237fbc),LL(0x27bac297,0xcc2b6b03),LL(0xb917f54a,0x2ae1cac5), LL(0x7845ae4f,0x474807d4),LL(0xce5972e0,0xfec7dd92),LL(0x1d7915bb,0xc3bd2541),LL(0xd94907ca,0x66f85dc4), + LL(0xbdbcf0ca,0xd981b888),LL(0xdf279e9f,0xd75f5da6),LL(0x7054e934,0x128bbf24),LL(0x81db134b,0x3c6ff6e5), LL(0x047d26e4,0x795b7cf4),LL(0x5049ec37,0xf370f7b8),LL(0xced945af,0xc6712d4d),LL(0x095642bc,0xdf30b5ec), + LL(0x4896246e,0x9b034c62),LL(0xee90bbd1,0x5652c016),LL(0x87fedb73,0xeb38636f),LL(0x0135a613,0x5e32f847), LL(0xcf933c83,0x0703b312),LL(0x1a7f47e6,0xd05bb76e),LL(0x949c2415,0x825e4f0c),LL(0x7250d6f8,0x569e5622), + LL(0x6568013e,0xbbe9eb3a),LL(0x22f243fc,0x8dbd203f),LL(0xb342734a,0x9dbd7694),LL(0x46afa984,0x8f6d12f8), LL(0xc9eade29,0xb98610a2),LL(0x47dd0f18,0xbab4f323),LL(0x671c0d46,0x5779737b),LL(0xd3e0a42a,0x10b6a7c6), + LL(0x3035b41c,0xfb19ddf3),LL(0x99c45895,0xd336343f),LL(0x54c857e5,0x61fe4938),LL(0xae4e57d5,0xc4d506be), LL(0xbbc33f75,0x3cd8c8cb),LL(0x9262c77d,0x7281f08a),LL(0xf11a2823,0x083f4ea6),LL(0x9fba2e33,0x8895041e), + LL(0x9c438edf,0xfcdfea49),LL(0x91edba44,0x7678dcc3),LL(0xe2ba50f0,0xf07b3b87),LL(0x43948c1b,0xc13888ef), LL(0x1140af42,0xc2135ad4),LL(0x926ed1a7,0x8e5104f3),LL(0x88f6695f,0xf24430cb),LL(0x6d73c120,0x0ce0637b), + LL(0xfe631e8f,0xb2db01e6),LL(0xd7bdd24b,0x1c5563d7),LL(0x369ad44f,0x8daea3ba),LL(0x8187a9f9,0x000c81b6), LL(0xaae1fd9a,0x5f48a951),LL(0x8d5aed8a,0xe35626c7),LL(0x0498c622,0x20952763),LL(0x773aa504,0x76d17634), + LL(0xeb300f7a,0x36d90dda),LL(0xedb5e801,0x9dcf7dfc),LL(0x74d5244c,0x645cb268),LL(0x348e3aa2,0xa127ee79), LL(0x575f1dbb,0x488acc53),LL(0x80e6161e,0x95037e85),LL(0x292650d0,0x57e59283),LL(0x14938216,0xabe67d99), + LL(0x3f8e1065,0x3c7f944b),LL(0x330e8924,0xed908cb6),LL(0x6f530136,0x08ee8fd5),LL(0xd7ffc169,0x2227b7d5), LL(0xb5cd6dd5,0x4f55c893),LL(0xa62796e8,0x82225e11),LL(0xcb18e12c,0x5c6cead1),LL(0x84f5a51a,0x4381ae0c), + LL(0x7fafa4c8,0x345913d3),LL(0x0491aac0,0x3d918082),LL(0x3e69264c,0x9347871f),LL(0xb4f4f0cd,0xbea9dd3c), LL(0x3eadd3e7,0xbda5d067),LL(0x0573bcd8,0x0033c1b8),LL(0x5da2486c,0x25589379),LL(0x86abbee7,0xcb89ee5b), + LL(0x22532e5d,0x8fe0a8f3),LL(0x727dfc4c,0xb6410ff0),LL(0x226726db,0x619b9d58),LL(0x7a2b2dc7,0x5ec25669), LL(0x4c3beb01,0xaf4d2e06),LL(0x7acea556,0x852123d0),LL(0xf783487a,0x0e9470fa),LL(0x5664b3eb,0x75a7ea04), + LL(0x6798e4ba,0x4ad78f35),LL(0xc7d0e091,0x9214e6e5),LL(0xb1290403,0xc420b488),LL(0xfc295749,0x64049e0a), LL(0x3ae9841f,0x03ef5af1),LL(0xb0b662a6,0xdbe4ca19),LL(0xfa453458,0x46845c5f),LL(0x10b66722,0xf8dabf19), + LL(0xcce2793b,0xb650f0aa),LL(0xc5ec47c1,0x71db851e),LL(0x3b234fa9,0x3eb78f3e),LL(0xfc0106ce,0xb0c60f35), LL(0x774eadbd,0x05427121),LL(0xce323863,0x25367faf),LL(0xcd086976,0x7541b5c9),LL(0xdc507ad1,0x4ff069e2), + LL(0x8776e667,0x74145256),LL(0xb23c6bb5,0x6e76142c),LL(0x1b3a8a87,0xdbf30712),LL(0x98450836,0x60e7363e), LL(0xb7366d80,0x5741450e),LL(0x4837dbdf,0xe4ee14ca),LL(0x69d4316f,0xa765eb9b),LL(0x8ef43825,0x04548dca), + LL(0x5ae888eb,0x9c9f4e4c),LL(0x56e9ac99,0x733abb51),LL(0xba6ac029,0xdaad3c20),LL(0x2ba3e38e,0x9b8dd3d3), LL(0x0bc5d11a,0xa9bb4c92),LL(0x9c5f88a3,0xf20127a7),LL(0x161d3cb8,0x4f52b06e),LL(0x6afaf0a6,0x26c1ff09), + LL(0x7189e71f,0x32670d2f),LL(0x5ecf91e7,0xc6438748),LL(0xdb757a21,0x15758e57),LL(0x290a9ce5,0x427d09f8), LL(0x38384a7a,0x846a308f),LL(0xb0732b99,0xaac3acb4),LL(0x17845819,0x9e941009),LL(0xa7ce5e03,0x95cba111), + LL(0xb00009c4,0x6f3d4f7f),LL(0x8ff28b5f,0xb8396c27),LL(0x1c97975d,0xb1a9ae43),LL(0xe5d9fed5,0x9d7ba8af), LL(0x34f485b6,0x338cf09f),LL(0x64122516,0xbc0ddacc),LL(0x05d471fe,0xa450da12),LL(0x628dd8c9,0x4c3a6250), + LL(0xd1295837,0x69c7d103),LL(0x3807eb2f,0xa2893e50),LL(0xbdb41491,0xd6e1e1de),LL(0x5e138235,0xc630745b), LL(0x48661ae1,0xc892109e),LL(0xea2b2674,0x8d17e7eb),LL(0xc328d6b5,0x00ec0f87),LL(0xf079ff9e,0x6d858645), + LL(0x19115ead,0x6cdf243e),LL(0x4bac4fcf,0x1ce1393e),LL(0x9c29f25b,0x2c960ed0),LL(0x9d388a05,0x59be4d8e), LL(0xd0def72b,0x0d46e06c),LL(0xe0342748,0xb923db5d),LL(0x936d4a3d,0xf7d3aacd),LL(0x0b0b099e,0x558519cc), + LL(0x827097ef,0x3ea8ebf8),LL(0xd054f55d,0x259353db),LL(0x6d2ed089,0x84c89abc),LL(0x8e096a7c,0x5c548b69), LL(0x994b995d,0xd587f616),LL(0xa5845601,0x4d1531f6),LL(0x451fd9f0,0x792ab31e),LL(0x65adf6ca,0xc8b57bb2), + LL(0x1cd5ad73,0x68440fcb),LL(0x6144da4f,0xb9c860e6),LL(0x8462beb8,0x2ab286aa),LL(0xef46797f,0xcc6b8fff), LL(0x20c8a471,0xac820da4),LL(0x77ff7faf,0x69ae05a1),LL(0xbfb5da77,0xb9163f39),LL(0x2c73ab7a,0xbd03e590), + LL(0xb2940d9e,0x7e862b5e),LL(0x4b9af564,0x3c663d86),LL(0xbde3033d,0xd8309031),LL(0xd42c5bc6,0x298231b2), LL(0x552ad093,0x42090d2c),LL(0xff854695,0xa4799d1c),LL(0xd31f0d00,0x0a88b5d6),LL(0xa2f26b46,0xf8b40825), + LL(0xf1bd7218,0xec29b1ed),LL(0x4b24c86e,0xd491c53b),LL(0x3395ea65,0xd2fe588f),LL(0x4456ef15,0x6f3764f7), LL(0xcdc34800,0xdb43116d),LL(0xc1e33955,0xcdbcd456),LL(0x74ab286b,0xefdb5540),LL(0xd18c5d7c,0x948c7a51), + LL(0x7378058e,0xeb81aa37),LL(0x04411154,0x41c746a1),LL(0xfb828ac7,0xa10c73bc),LL(0x9d972b29,0x6439be91), LL(0x43a2fbad,0x4bf3b4b0),LL(0x82b5e840,0x39e6dadf),LL(0x6397bd4c,0x4f716408),LL(0x7f1eeccb,0x0f7de568), + LL(0xd2ffbfc1,0x5865c5a1),LL(0x4ccb6451,0xf74211fa),LL(0xc0b32558,0x66368a88),LL(0x9ad7812e,0x5b539dc2), LL(0x2f3af6f6,0x579483d0),LL(0x99934ece,0x52132078),LL(0xdcc9e983,0x50b9650f),LL(0xaee42b8a,0xca989ec9), + LL(0xd6f62f99,0x6a44c829),LL(0x4c2a7c0c,0x8f06a309),LL(0x98a0cb0a,0x4ea2b3a0),LL(0xbeee8364,0x5c547b70), LL(0x682afe11,0x461d40e1),LL(0x7b41c0a8,0x9e0fc77a),LL(0xe20d5d36,0x79e4aefd),LL(0x32dd9f63,0x2916e520), + LL(0x3f883faf,0xf59e52e8),LL(0x2b868d35,0x396f9639),LL(0x4ca19881,0xc902a9df),LL(0xdb2401a6,0x0fc96822), LL(0x66f1c68d,0x41237587),LL(0xfb476c0d,0x10fc6de3),LL(0x841f5d90,0xf8b6b579),LL(0xfa24f44a,0x2ba8446c), + LL(0xef4a9975,0xa237b920),LL(0x2330435f,0x60bb6004),LL(0xcfb7e7b5,0xd6f4ab5a),LL(0x83435391,0xb2ac5097), LL(0xb0d1ea67,0xf036ee2f),LL(0x74c56230,0xae779a6a),LL(0xab838ae6,0x59bff8c8),LL(0x9b38e6f0,0xcd83ca99), + LL(0xe33deed3,0xbb27bef5),LL(0x001892a8,0xe6356f6f),LL(0x7adfbd3e,0xbf3be6cc),LL(0x33d1ac9d,0xaecbc81c), LL(0xe6e861dc,0xe4feb909),LL(0x53f5f801,0x90a247a4),LL(0x27346e57,0x01c50acb),LL(0x461acc1b,0xce29242e), + LL(0x2f998a91,0x04dd214a),LL(0xd4baf27b,0x271ee9b1),LL(0xe8c26722,0x7e3027d1),LL(0x1820dce5,0x21d1645c), LL(0x7501779c,0x086f242c),LL(0xfa0e8009,0xf0061407),LL(0x60187129,0xf23ce477),LL(0x0fde9bd0,0x05bbdedb), + LL(0x25d98473,0x682f4832),LL(0x5c658427,0xf207fe85),LL(0x4166ffa1,0xb6fdd7ba),LL(0x9eed799d,0x0c314056), LL(0x4107e28f,0x0db8048f),LL(0x41216840,0x74ed3871),LL(0x56a3c06e,0x74489f8f),LL(0x12777134,0x1e1c005b), + LL(0xf37ec3c3,0xdb332a73),LL(0xdd59eba0,0xc65259bd),LL(0xdb4d3257,0x2291709c),LL(0xbd389390,0x9a793b25), LL(0xe43756f0,0xf39fe34b),LL(0x9afb56c9,0x2f76bdce),LL(0x61208b27,0x9f37867a),LL(0x089972c3,0xea1d4307), + LL(0x8bdf623a,0x8c595330),LL(0x8441fb7d,0x5f5accda),LL(0x32ddfd95,0xfafa9418),LL(0x0fde9be7,0x6ad40c5a), LL(0xaeca8709,0x43faba89),LL(0x2c248a9d,0xc64a7cf1),LL(0x72637a76,0x16620252),LL(0x22b8d1bb,0xaee1c791), + LL(0x21a843b2,0xf0f798fd),LL(0x8d005cb1,0x56e4ed4d),LL(0x1f0d8abe,0x355f7780),LL(0x34522326,0x197b04cf), LL(0xfd42c13f,0x41f9b31f),LL(0xb40f933d,0x5ef7feb2),LL(0x5d60bad4,0x27326f42),LL(0x8c92cf89,0x027ecdb2), + LL(0x4e3352fe,0x04aae4d1),LL(0x73591b90,0x08414d2f),LL(0xb7da7d60,0x5ed6124e),LL(0x4d13d4ec,0xb985b931), LL(0x96bf36f9,0xa592d3ab),LL(0xbbdf51df,0x012dbed5),LL(0xdf6c177d,0xa57963c0),LL(0x87ca29cf,0x010ec869), + LL(0xbf926dff,0xba1700f6),LL(0xf4bf6bc2,0x7c9fdbd1),LL(0x64da11f5,0xdc18dc8f),LL(0xd938ae75,0xa6074b7a), LL(0xe84f44a4,0x14270066),LL(0xd27b954e,0x99998d38),LL(0xb4f38e9a,0xc1be8ab2),LL(0x15c01016,0x8bb55bbf), + LL(0x0ea2ab30,0xf73472b4),LL(0xf73d68dd,0xd365a340),LL(0x19c2e1eb,0xc01a7168),LL(0x34061719,0x32f49e37), LL(0x01d8b4d6,0xb73c57f1),LL(0x26b47700,0x03c8423c),LL(0xa4d8826a,0x321d0bc8),LL(0x4bc0e638,0x6004213c), + LL(0xc1c06681,0xf78c64a1),LL(0xef018e50,0x16e0a16f),LL(0xdb42b2b3,0x31cbdf91),LL(0xe0d36f58,0xf8f4ffce), LL(0x4cc5e3e0,0xcdcc71cd),LL(0xa129e3e0,0xd55c7cfa),LL(0x0fb2cbf1,0xccdb6ba0),LL(0xc4bce3cb,0x6aba0005), + LL(0xd232cfc4,0x501cdb30),LL(0xd58a3cef,0x9ddcf12e),LL(0x87e09149,0x02d2cf9c),LL(0x2c976257,0xdc5d7ec7), LL(0x0b50d7dd,0x6447986e),LL(0x807f112a,0x88fdbaf7),LL(0xb00ae9f6,0x58c9822a),LL(0x6d3d27e0,0x6abfb950), + LL(0x8a429f4f,0xd0a74487),LL(0xdb516609,0x0649712b),LL(0xe769b5df,0xb826ba57),LL(0x1fc7aaf2,0x82335df2), LL(0x5c93d995,0x2389f067),LL(0x68677be6,0x59ac367a),LL(0x21d9951b,0xa77985ff),LL(0x85011cce,0x038956fb), + LL(0xbb734e37,0x608e48cb),LL(0x2be5b26f,0xc08c0bf2),LL(0xf9b1a0d9,0x17bbdd3b),LL(0x10483319,0xeac7d898), LL(0xbc1a6dea,0xc95c4baf),LL(0x172aafdb,0xfdd0e2bf),LL(0x8235c41a,0x40373cbc),LL(0xfb6f41d5,0x14303f21), + LL(0x0408f237,0xba063621),LL(0xecd2d1ed,0xcad3b09a),LL(0x52abb6a2,0x4667855a),LL(0xaa8b417b,0xba9157dc), LL(0x4f013efb,0xfe7f3507),LL(0xaa38c4a2,0x1b112c4b),LL(0x9ba64345,0xa1406a60),LL(0x6993c80b,0xe53cba33), + LL(0xded40d23,0x45466063),LL(0x54908e25,0x3d5f1f4d),LL(0x403c3c31,0x9ebefe62),LL(0x0672a624,0x274ea0b5), LL(0x451d1b71,0xff818d99),LL(0x8f79cf79,0x80e82643),LL(0x73ce37f5,0xa165df13),LL(0xfe3a21fd,0xa744ef4f), + LL(0xcf551396,0x73f1e7f5),LL(0x868c676b,0xc616898e),LL(0x8c442c36,0x671c28c7),LL(0x5e0a317d,0xcfe5e558), LL(0x7051f476,0x1242d818),LL(0x14f03442,0x56fad2a6),LL(0x0a44d0f6,0x262068bc),LL(0xce6edf4e,0xdfa2cd6e), + LL(0xd15d1517,0x0f43813a),LL(0x377d44f5,0x61214cb2),LL(0xc639b35f,0xd399aa29),LL(0x54c51c19,0x42136d71), LL(0x08417221,0x9774711b),LL(0x52545a57,0x0a5546b3),LL(0x1150582d,0x80624c41),LL(0xfbc555bc,0x9ec5c418), + LL(0x771849f1,0x2c87dcad),LL(0x01d7bf6f,0xb0c932c5),LL(0x89116eb2,0x6aa5cd3e),LL(0x51ca7bd3,0xd378c25a), LL(0x9e6e3e31,0xc612a0da),LL(0xb68ad5d0,0x0417a54d),LL(0x22c6edb8,0x00451e4a),LL(0xb42827ce,0x9fbfe019), + LL(0xba9384a2,0x2fa92505),LL(0x64ad69c1,0x21b8596e),LL(0x983b35a6,0x8f4fcc49),LL(0x72754672,0xde093760), LL(0xf7bffe6d,0x2f14ccc8),LL(0x5d94263d,0x27566bff),LL(0x2df3ec30,0xb5b4e9c6),LL(0x3e6ea6ba,0x94f1d7d5), + LL(0xaaca5e9b,0x97b7851a),LL(0x56713b97,0x518aa521),LL(0x150a61f6,0x3357e8c7),LL(0xec2c2b69,0x7842e7e2), LL(0x6868a548,0x8dffaf65),LL(0xe068fc81,0xd963bd82),LL(0x65917733,0x64da5c8b),LL(0x7b247328,0x927090ff), +}, +/* digit=22 base_pwr=2^154 */ +{ + LL(0xd298c241,0x214bc9a7),LL(0x56807cfd,0xe3b697ba),LL(0x4564eadb,0xef1c7802),LL(0xb48149c5,0xdde8cdcf), LL(0x5a4d2604,0x946bf0a7),LL(0x6c1538af,0x27154d7f),LL(0xde5b1fcc,0x95cc9230),LL(0x66864f82,0xd88519e9), + LL(0x7cb1282c,0xb828dd1a),LL(0xbe46973a,0xa08d7626),LL(0xe708d6b2,0x6baf8d40),LL(0x4daeb3f3,0x72571fa1), LL(0xf22dfd98,0x85b1732f),LL(0x0087108d,0x87ab01a7),LL(0x5988207a,0xaaaafea8),LL(0x69f00755,0xccc832f8), + LL(0x36ff3bf0,0x964d950e),LL(0xf0b34638,0x8ad20f6f),LL(0xb5d7585f,0x4d9177b3),LL(0xef3f019f,0xcf839760), LL(0x8288c545,0x582fc5b3),LL(0x13116bd1,0x2f8e4e9b),LL(0x332120ef,0xf91e1b2f),LL(0x2a17dd23,0xcf568724), + LL(0xca8d9d1a,0x488f1185),LL(0xd987ded2,0xadf2c77d),LL(0x60c46124,0x5f3039f0),LL(0x71e095f4,0xe5d70b75), LL(0x6260e70f,0x82d58650),LL(0xf750d105,0x39d75ea7),LL(0x75bac364,0x8cf3d0b1),LL(0x21d01329,0xf3a7564d), + LL(0x2f52d2a7,0x182f04cd),LL(0xe2df565a,0x4fde149a),LL(0xa79fb2f7,0xb80c5eec),LL(0x22ddc897,0xab491d7b), LL(0xc6312c7f,0x99d76c18),LL(0x6aa41a57,0xca0d5f3d),LL(0xd15363a0,0x71207325),LL(0xbeb252c2,0xe82aa265), + LL(0xec3128c2,0x94ab4700),LL(0x8e383f49,0x6c76d862),LL(0xc03024eb,0xdc36b150),LL(0x53daac69,0xfb439477), LL(0x8dc79623,0xfc68764a),LL(0xb440fbb2,0x5b86995d),LL(0xccc5ee0d,0xd66879bf),LL(0x95aa8bd3,0x05228942), + LL(0x1e6a75c1,0xb51a40a5),LL(0x0ea7d817,0x24327c76),LL(0x07774597,0x06630182),LL(0x97fa7164,0xd6fdbec3), LL(0x13c90f48,0x20c99dfb),LL(0x686ef263,0xd6ac5273),LL(0xfef64eeb,0xc6a50bdc),LL(0x86fdfc32,0xcd87b281), + LL(0x3fcd3efc,0xb24aa43e),LL(0xb8088e9a,0xdd26c034),LL(0xbd3d46ea,0xa5ef4dc9),LL(0x8a4c6a6f,0xa2f99d58), LL(0x2f1da46c,0xddabd355),LL(0x1afacdd1,0x72c3f8ce),LL(0x92d40578,0xd90c4eee),LL(0xca623b94,0xd28bb41f), + LL(0x745edc11,0x50fc0711),LL(0x3dc87558,0x9dd9ad7d),LL(0xb49d1e64,0xce6931fb),LL(0xc98bd0f9,0x6c77a0a2), LL(0x6baf7cb1,0x62b9a629),LL(0xccf72d22,0xcf065f91),LL(0x79639071,0x7203cce9),LL(0xf9cb732f,0x09ae4885), + LL(0xee8314f3,0x5e7c3bec),LL(0xdbea298f,0x1c068aed),LL(0x7c80acec,0x08d381f1),LL(0xe330495b,0x03b56be8), LL(0x9222882d,0xaeffb8f2),LL(0xc4af8bf7,0x95ff38f6),LL(0x1fc57d8c,0x50e32d35),LL(0x17b444f0,0x6635be52), + LL(0xa5177900,0x04d15276),LL(0xf6858752,0x4e1dbb47),LL(0xc615796c,0x5b475622),LL(0x691867bf,0xa6fa0387), LL(0x2844c6d0,0xed7f5d56),LL(0x03a2477d,0xc633cf9b),LL(0x2d3721d6,0xf6be5c40),LL(0xe9fd68e6,0xaf312eb7), + LL(0xe7417ce1,0x242792d2),LL(0x970ee7f5,0xff42bc71),LL(0x5c67a41e,0x1ff4dc6d),LL(0x20882a58,0x77709b7b), LL(0xbe217f2c,0x3554731d),LL(0x5bb72177,0x2af2a8cd),LL(0x591dd059,0x58eee769),LL(0x4bba6477,0xbb2930c9), + LL(0x7d930cfc,0x863ee047),LL(0x396fd1f4,0x4c262ad1),LL(0x039af7e1,0xf4765bc8),LL(0x5ba104f6,0x2519834b), LL(0xd105f961,0x7cd61b4c),LL(0xd63bca54,0xa5415da5),LL(0x88a1f17c,0x778280a0),LL(0x2329512c,0xc4968949), + LL(0xcecdaa7a,0x174a9126),LL(0x0b13247b,0xfc8c7e0e),LL(0x3484c1c4,0x29c110d2),LL(0x831dfc3b,0xf8eb8757), LL(0xc0067452,0x022f0212),LL(0x7b9b926c,0x3f6f69ee),LL(0xef42daf4,0x09032da0),LL(0x83f80de4,0x79f00ade), + LL(0x81236c97,0x6210db71),LL(0x3ee0781f,0x74f7685b),LL(0xa3e41372,0x4df7da7b),LL(0xb1a1553e,0x2aae38b1), LL(0xf6dd9d1b,0x1688e222),LL(0x5b8b6487,0x57695448),LL(0x4b2edeaa,0x478d2127),LL(0x1e85956a,0xb2818fa5), + LL(0xf176f2c0,0x1e6addda),LL(0xe2572658,0x01ca4604),LL(0x85342ffb,0x0a404ded),LL(0x441838d6,0x8cf60f96), LL(0xc9071c4a,0x9bbc691c),LL(0x34442803,0xfd588744),LL(0x809c0d81,0x97101c85),LL(0x8c456f7f,0xa7fb754c), + LL(0xd51805e1,0xc95f3c5c),LL(0xb299dca8,0xab4ccd39),LL(0x47eaf500,0x3e03d20b),LL(0xd7b80893,0xfa3165c1), LL(0xe160e552,0x005e8b54),LL(0x9019d11f,0xdc4972ba),LL(0x0c9a4a7a,0x21a6972e),LL(0x37840fd7,0xa52c258f), + LL(0xc1e99d81,0xf8559ff4),LL(0xa3c617c0,0x08e1a7d6),LL(0x248c6ba7,0xb398fd43),LL(0xd1283794,0x6ffedd91), LL(0xd629d208,0x8a6a59d2),LL(0x3490530e,0xa9d141d5),LL(0x38505989,0x42f6fc18),LL(0x479d94ee,0x09bf250d), + LL(0xb3822790,0x223ad3b1),LL(0x93b8971c,0x6c5926c0),LL(0x75f7fa62,0x609efc7e),LL(0x1ec2d989,0x45d66a6d), LL(0x987d2792,0x4422d663),LL(0x3eb31d2b,0x4a73caad),LL(0xa32cb9e6,0xf06c2ac1),LL(0x91aeba84,0xd9445c5f), + LL(0xaf71013f,0x6af7a1d5),LL(0x0bedc946,0xe68216e5),LL(0xd27370a0,0xf4cba30b),LL(0x870421cc,0x7981afbf), LL(0x9449f0e1,0x02496a67),LL(0x0a47edae,0x86cfc4be),LL(0xb1feca22,0x3073c936),LL(0x03f8f8fb,0xf5694612), + LL(0x901515ea,0xd063b723),LL(0x749cf038,0x4c6c77a5),LL(0xab9e5059,0x6361e360),LL(0xa76a37c0,0x596cf171), LL(0x6530ae7a,0x800f53fa),LL(0x0792a7a6,0x0f5e631e),LL(0xefdb81c9,0x5cc29c24),LL(0x3f9c40ba,0xa269e868), + LL(0x2cb7191e,0xec14f9e1),LL(0xe5b08ea6,0x78ea1bd8),LL(0x46332bb9,0x3c65aa9b),LL(0xbf80ce25,0x84cc22b3), LL(0xd49d5bf1,0x0098e9e9),LL(0x19087da4,0xcd4ec1c6),LL(0xaef6e357,0x3c9d07c5),LL(0x9f8f64b8,0x839a0268), + LL(0xc6d8607f,0xc5e9eb62),LL(0x6aa995e4,0x759689f5),LL(0xbbb48317,0x70464669),LL(0xe402417d,0x921474bf), LL(0x2a354c8c,0xcabe135b),LL(0x812fa4b5,0xd51e52d2),LL(0x53311fe8,0xec741096),LL(0xb864514b,0x4f774535), + LL(0x5bde48f8,0xbcadd671),LL(0x2189bc7d,0xc9703873),LL(0xc709ee8a,0x5d45299e),LL(0x845aaff8,0xd1287ee2), LL(0xdb1dbf1f,0x7d1f8874),LL(0x990c88d6,0xea46588b),LL(0x84368313,0x60ba649a),LL(0x60d543ae,0xd5fdcbce), + LL(0x810d5ab0,0x90b46d43),LL(0x04d7e5cc,0x6739d8f9),LL(0x0d337c33,0x021c1a58),LL(0x68e67c40,0x00a61162), LL(0x379f0a1f,0x95ef413b),LL(0xe9e2ab95,0xfe126605),LL(0x2f5f199c,0x67578b85),LL(0x2cb84913,0xf5c00329), + LL(0x37577dd8,0xf7956430),LL(0x29c5fe88,0x83b82af4),LL(0xcdbdc132,0x9c1bea26),LL(0x9c04339e,0x589fa086), LL(0xb13799df,0x033e9538),LL(0xd295d034,0x85fa8b21),LL(0xbd9ddcca,0xdf17f73f),LL(0xddb66334,0xf32bd122), + LL(0x858b044c,0x55ef88a7),LL(0x5aa9e397,0x1f0d69c2),LL(0x40d85559,0x55fd9cc3),LL(0x7785ddb2,0xc774df72), LL(0xd3bd2e1c,0x5dcce9f6),LL(0xa85dfed0,0xeb30da20),LL(0xd3ed09c4,0x5ed7f5bb),LL(0x82a9c1bd,0x7d42a35c), + LL(0x9890272d,0xcf3de995),LL(0x3e713a10,0x75f3432a),LL(0xe28227b8,0x5e13479f),LL(0xfefacdc8,0xb8561ea9), LL(0x8332aafd,0xa6a297a0),LL(0x73809b62,0x9b0d8bb5),LL(0x0c63036f,0xd2fa1cfd),LL(0xbd64bda8,0x7a16eb55), + LL(0x78e62ddc,0x3f5cf5f6),LL(0x07fd752b,0x2267c454),LL(0x5e437bbe,0x5e361b6b),LL(0x8354e075,0x95c59501), LL(0xf2b254d9,0xec725f85),LL(0x2cb52b4e,0x844b617d),LL(0xcf425fb5,0xed8554f5),LL(0x2af9f312,0xab67703e), + LL(0x3cf48283,0x4cc34ec1),LL(0x9c8a705e,0xb09daa25),LL(0x5b7d4f84,0xd1e9d0d0),LL(0xdb38929d,0x4df6ef64), LL(0xaa21ba46,0xe16b0763),LL(0xa293f8fb,0xc6b1d178),LL(0xd520aabf,0x0ff5b602),LL(0xc339397a,0x94d671bd), + LL(0x4f5792fa,0x7c7d98cf),LL(0x11215261,0x7c5e0d67),LL(0xa7c5a6d4,0x9b19a631),LL(0x7a45274d,0xc8511a62), LL(0xa5a60d99,0x0c16621c),LL(0xcf5e48cb,0xf7fbab88),LL(0xf7ddee08,0xab1e6ca2),LL(0xe7867f3c,0x83bd08ce), + LL(0x2ac13e27,0xf7e48e8a),LL(0x4eb1a9f5,0x4494f6df),LL(0x981f0a62,0xedbf84eb),LL(0x536438f0,0x49badc32), LL(0x004f7571,0x50bea541),LL(0xdf1c94ee,0xbac67d10),LL(0xb727bc31,0x253d73a1),LL(0x30686e28,0xb3d01cf2), + LL(0x55fd0b8b,0x51b77b1b),LL(0xfeec3173,0xa099d183),LL(0x670e72b7,0x202b1fb7),LL(0xa8e1635f,0xadc88b33), LL(0xf989d905,0x34e8216a),LL(0x29b58d01,0xc2e68d20),LL(0x6fe55a93,0x11f81c92),LL(0x8f296f40,0x15f1462a), + LL(0xea3d62f2,0x1915d375),LL(0x01c8977d,0xa17765a3),LL(0xe47b26f6,0x7559710a),LL(0x535077a5,0xe0bd29c8), LL(0x08d84858,0x615f976d),LL(0x69ced5c1,0x370dfe85),LL(0xa734fa56,0xbbc7503c),LL(0x91ac4574,0xfbb9f1ec), + LL(0x060dd7ef,0x95d7ec53),LL(0x6e657979,0xeef2dacd),LL(0xe2a08235,0x54511af3),LL(0x1f4aea3d,0x1e324aa4), LL(0xe6e67671,0x550e7e71),LL(0xbf52faf7,0xbccd5190),LL(0x223cc62a,0xf880d316),LL(0x2b32eb5d,0x0d402c7e), + LL(0x306a5a3b,0xa40bc039),LL(0x96783a1b,0x4e0a41fd),LL(0x0253cdd4,0xa1e8d39a),LL(0xc7388638,0x6480be26), LL(0x2285f382,0xee365e1d),LL(0xec0b5c36,0x188d8d8f),LL(0x1f0f4d82,0x34ef1a48),LL(0xa487d29a,0x1a8f43e1), + LL(0x77aefb3a,0x8168226d),LL(0x1e72c253,0xf69a751e),LL(0xe9594df1,0x8e04359a),LL(0xd14c0467,0x475ffd7d), LL(0x3844e95c,0xb5a2c2b1),LL(0xdd12ef94,0x85caf647),LL(0xf1063d00,0x1ecd2a9f),LL(0x23843311,0x1dd2e229), + LL(0x73d17244,0x38f0e09d),LL(0x8fc653f1,0x3ede7746),LL(0xdc20e21c,0xae4459f5),LL(0x6a8599ea,0x00db2ffa), LL(0x30cfd905,0x11682c39),LL(0xa5c112a6,0x4934d074),LL(0x568bfe95,0xbdf063c5),LL(0x016c441a,0x779a440a), + LL(0x97d6fbdc,0x0c23f218),LL(0xe0776aac,0xd3a5cd87),LL(0xd712e8db,0xcee37f72),LL(0x26f74e8d,0xfb28c70d), LL(0xb61301a0,0xffe0c728),LL(0xd3724354,0xa6282168),LL(0x768ffedc,0x7ff4cb00),LL(0x03b02de9,0xc51b3088), + LL(0x3902dda5,0xa5a8147c),LL(0xfe6973b4,0x35d2f706),LL(0xc257457e,0x5ac2efcf),LL(0x8700611b,0x933f48d4), LL(0x4912beb2,0xc365af88),LL(0x162edf94,0x7f5a4de6),LL(0x0c32f34b,0xc646ba7c),LL(0xb2091074,0x632c6af3), + LL(0x753e43a9,0x58d4f2e3),LL(0x24d4e23f,0x70e1d217),LL(0xafede6a6,0xb24bf729),LL(0x710c8b60,0x7f4a94d8), LL(0x8d4faa6a,0xaad90a96),LL(0xb066b690,0xd9ed0b32),LL(0x78b6dbfd,0x52fcd37b),LL(0x8bd2b431,0x0b64615e), + LL(0xcfb9fad5,0x228e2048),LL(0x240b76bd,0xbeaa386d),LL(0x90dad7bc,0x2d6681c8),LL(0x06d38f5e,0x3e553fc3), LL(0x9d5f9750,0xf27cdb9b),LL(0xd28c5b0e,0x3e85c52a),LL(0x5247c39b,0x190795af),LL(0xbddd6828,0x547831eb), + LL(0x4a82f424,0xf327a227),LL(0x7e47f89d,0x36919c78),LL(0x43c7392c,0xe4783919),LL(0x2316fefe,0xf101b9aa), LL(0x1c5009d2,0xbcdc9e9c),LL(0x9cd18345,0xfb55ea13),LL(0xa3ce77c7,0xf5b5e231),LL(0xd2f2cb3d,0xde6b4527), + LL(0x9bb26f5f,0x10f6a333),LL(0x044d85b6,0x1e85db8e),LL(0x94197e54,0xc3697a08),LL(0xa7cb4ea8,0x65e18cc0), LL(0xa471fe6e,0xa38c4f50),LL(0x2f13439c,0xf031747a),LL(0xc007318b,0x53c4a6ba),LL(0x1deccb3d,0xa8da3ee5), + LL(0x558216b1,0x0555b31c),LL(0x2f79e6c2,0x90c7810c),LL(0xfe8eed3c,0x9b669f4d),LL(0xe0fac126,0x70398ec8), LL(0xf701b235,0xa96a449e),LL(0xeb94f395,0x0ceecdb3),LL(0xd0cb7431,0x285fc368),LL(0x16a18c64,0x0d37bb52), + LL(0xb880d2dd,0x05110d38),LL(0x65930d57,0xa60f177b),LL(0xf36235f5,0x7da34a67),LL(0x183816b9,0x47f5e17c), LL(0xdb394af4,0xc7664b57),LL(0x7036f789,0x39ba215d),LL(0x2f27b472,0x46d2ca0e),LL(0xf73a84b7,0xc42647ee), + LL(0x64488f1d,0x44bc7545),LL(0xf4cf85d5,0xaa922708),LL(0x53e4df63,0x721a01d5),LL(0x5db46ced,0x649c0c51), LL(0x3cffcb6c,0x6bf0d64e),LL(0x50f71d96,0xe3bf93fe),LL(0xbcc194a0,0x75044558),LL(0x6afdc554,0x16ae3372), + LL(0x5ca48f3f,0xbfc01adf),LL(0xe22a9b84,0x64352f06),LL(0xc1099e4a,0xcee54da1),LL(0xfa1b89c0,0xbbda54e8), LL(0x6f6e55fb,0x166a3df5),LL(0x20176f88,0x1ca44a24),LL(0xdfb7b5ff,0x936afd88),LL(0x8611d4a0,0xe34c2437), + LL(0x86142103,0x7effbb75),LL(0x1f34fc4d,0x6704ba1b),LL(0x10c1b122,0x7c2a468f),LL(0x8c6aace9,0x36b3a610), LL(0x75a0d050,0xabfcc0a7),LL(0x3ce33e32,0x066f9197),LL(0x29fe09be,0xce905ef4),LL(0xa8376351,0x89ee25ba), + LL(0xfd29dc76,0x2a3ede22),LL(0x36f17260,0x7fd32ed9),LL(0x284b4126,0x0cadcf68),LL(0xa7951fc8,0x63422f08), LL(0x0807e199,0x562b24f4),LL(0x22ad4490,0xfe9ce5d1),LL(0x0db2b1b4,0xc2f51b10),LL(0xe4541d0d,0xeb3613ff), + LL(0x2680813b,0xbd2c4a05),LL(0x561b08d6,0x527aa55d),LL(0xa7205558,0xa9f8a40e),LL(0x243d0bec,0xe3eea56f), LL(0xa0ff58b3,0x7b853817),LL(0x1a69e627,0xb67d3f65),LL(0xa869b5d6,0x0b76bbb9),LL(0x546723ed,0xa3afeb82), + LL(0x3e554892,0x5f24416d),LL(0x430e2a45,0x8413b53d),LL(0x9032a2a0,0x99c56aee),LL(0xeec367b1,0x09432bf6), LL(0xdaf0ecc1,0x552850c6),LL(0x5bc92048,0x49ebce55),LL(0x54811307,0xdfb66ba6),LL(0x6f298597,0x1b84f797), + LL(0x8d1d7a0d,0x79590481),LL(0x3a6fa556,0xd9fabe03),LL(0xba9e5d35,0xa40f9c59),LL(0xf6247577,0xcb1771c1), LL(0xe9a6312b,0x542a47ca),LL(0x552dd8c5,0xa34b3560),LL(0x0d794716,0xfdf94de0),LL(0x9c623094,0xd46124a9), + LL(0x68afe8b4,0x56b7435d),LL(0x6c0d8ea1,0x27f20540),LL(0x73186898,0x12b77e14),LL(0x7479490f,0xdbc3dd46), LL(0xc03b0c05,0x951a9842),LL(0x7921bc96,0x8b1b3bb3),LL(0x2b202e0a,0xa573b346),LL(0x47254d56,0x77e4665d), + LL(0xd23e3984,0x08b70dfc),LL(0xebd14236,0xab86e8bc),LL(0x57114ba7,0xaa3e07f8),LL(0xab0ef4f2,0x5ac71689), LL(0x0139d9af,0x88fca384),LL(0x76644af0,0x72733f88),LL(0x65d74f4a,0xf122f72a),LL(0xa5626c7a,0x13931577), + LL(0x70f8d5a4,0xd5b5d9eb),LL(0xd7bbb228,0x375adde7),LL(0x0c1c0b32,0x31e88b86),LL(0x173edbaa,0xd1f568c4), LL(0x5459df02,0x1592fc83),LL(0x0fcd9a7e,0x2beac0fb),LL(0x1b473b0a,0xb0a6fdb8),LL(0x0fe8fc48,0xe3224c6f), + LL(0xe87edf5b,0x680bd00e),LL(0x20e77cf5,0x30385f02),LL(0x4d42d1b2,0xe9ab98c0),LL(0xd3816d77,0x72d191d2), LL(0x0917d9e5,0x1564daca),LL(0x1f8fed7f,0x394eab59),LL(0x7fbb3896,0xa209aa8d),LL(0xbe6ac98e,0x5564f3b9), + LL(0xd73654ef,0xead21d05),LL(0x13d78d74,0x68d1a9c4),LL(0x6d4973a0,0x61e01708),LL(0x46e6d32a,0x83da3500), LL(0x68ae0118,0x6a3dfca4),LL(0xd02da069,0xa1b9a4c9),LL(0xebab8302,0x0b2ff9c7),LL(0x944ba436,0x98af07c3), + LL(0x995f0f9f,0x85997326),LL(0x71b58bc6,0x467fade0),LL(0xbd625a2b,0x47e4495a),LL(0x33c3b8cd,0xfdd2d01d), LL(0xc693f9fa,0x2c38ae28),LL(0x348f7999,0x48622329),LL(0x2161f583,0x97bf738e),LL(0x565e8cc9,0x15ee2fa7), + LL(0x5777e189,0xa1a5c845),LL(0x456f2829,0xcc10bee0),LL(0xda762bd5,0x8ad95c56),LL(0xe9d91da8,0x152e2214), LL(0x7cb23c74,0x975b0e72),LL(0xa90c66df,0xfd5d7670),LL(0x225ffc53,0xb5b5b8ad),LL(0xfaded2ae,0xab6dff73), + LL(0x6f4cbe9d,0xebd56781),LL(0x6a574bd7,0x0ed8b249),LL(0x81a881fa,0x41c246fe),LL(0xc3db9c70,0x91564805), LL(0x5b862809,0xd7c12b08),LL(0x55858d7b,0x1facd1f1),LL(0xaf09e92a,0x7693747c),LL(0x189a425f,0x3b69dcba), + LL(0x967365ef,0x0be28e9f),LL(0xe801f5c9,0x57300eb2),LL(0xd583352f,0x93b8ac6a),LL(0xcd05b2b7,0xa2cf1f89), LL(0x4dcc40cc,0x7c0c9b74),LL(0xada523fb,0xfee38c45),LL(0x1099cc4d,0xb49a4dec),LL(0x69f069c6,0x325c377f), + LL(0x476cc9ff,0xe12458ce),LL(0xc6d4cb63,0x580e0b6c),LL(0x9072289b,0xd561c8b7),LL(0xa619e6da,0x0377f264), LL(0x88e591a5,0x26685362),LL(0x7523ca2b,0xa453a7bd),LL(0xc1df4533,0x8a9536d2),LL(0xbe972f79,0xc8e50f2f), + LL(0x6d3549cf,0xd433e50f),LL(0xfacd665e,0x6f33696f),LL(0xce11fcb4,0x695bfdac),LL(0xaf7c9860,0x810ee252), LL(0x7159bb2c,0x65450fe1),LL(0x758b357b,0xf7dfbebe),LL(0xd69fea72,0x2b057e74),LL(0x92731745,0xd485717a), +}, +/* digit=23 base_pwr=2^161 */ +{ + LL(0xee36860c,0x896c42e8),LL(0x4113c22d,0xdaf04dfd),LL(0x44104213,0x1adbb7b7),LL(0x1fd394ea,0xe5fd5fa1), LL(0x1a4e0551,0x68235d94),LL(0x18d10151,0x6772cfbe),LL(0x09984523,0x276071e3),LL(0x5a56ba98,0xe4e879de), + LL(0x285b9491,0xaaafafb0),LL(0x1e4c705e,0x01a0be88),LL(0x2ad9caab,0xff1d4f5d),LL(0xc37a233f,0x6e349a4a), LL(0x4a1c6a16,0xcf1c1246),LL(0x29383260,0xd99e6b66),LL(0x5f6d5471,0xea3d4366),LL(0xff8cc89b,0x36974d04), + LL(0xcfe89d80,0xc26c49a1),LL(0xda9c8371,0xb42c026d),LL(0xdad066d2,0xca6c013a),LL(0x56a4f3ee,0xfb8f7228), LL(0xd850935b,0x08b579ec),LL(0xd631e1b3,0x34c1a74c),LL(0xac198534,0xcb5fe596),LL(0xe1f24f25,0x39ff21f6), + LL(0x8f929057,0x27f29e14),LL(0xc0c853df,0x7a64ae06),LL(0x58e9c5ce,0x256cd183),LL(0xded092a5,0x9d9cce82), LL(0x6e93b7c7,0xcc6e5979),LL(0x31bb9e27,0xe1e47092),LL(0xaa9e29a0,0xb70b3083),LL(0x3785e644,0xbf181a75), + LL(0x8ead09f7,0xf53f2c65),LL(0x9780d14d,0x1335e1d5),LL(0xcd1b66bc,0x69cc20e0),LL(0xbbe0bfc8,0x9b670a37), LL(0x28efbeed,0xce53dc81),LL(0x8326a6e5,0x0c74e77c),LL(0xb88e9a63,0x3604e0d2),LL(0x13dc2248,0xbab38fca), + LL(0x5c0a3f1e,0x8ed6e8c8),LL(0x7c87c37f,0xbcad2492),LL(0x9ee3b78d,0xfdfb62bb),LL(0xcbceba46,0xeba8e477), LL(0xeeaede4b,0x37d38cb0),LL(0x7976deb6,0x0bc498e8),LL(0x6b6147fb,0xb2944c04),LL(0xf71f9609,0x8b123f35), + LL(0xde79dc24,0xa155dcc7),LL(0x558f69cd,0xf1168a32),LL(0x0d1850df,0xbac21595),LL(0xb204c848,0x15c8295b), LL(0x7d8184ff,0xf661aa36),LL(0x30447bdb,0xc396228e),LL(0xbde4a59e,0x11cd5143),LL(0x6beab5e6,0xe3a26e3b), + LL(0x1402b9d0,0xd3b3a13f),LL(0x2c7bc863,0x573441c3),LL(0x578c3e6e,0x4b301ec4),LL(0x0adaf57e,0xc26fc9c4), LL(0x7493cea3,0x96e71bfd),LL(0x1af81456,0xd05d4b3f),LL(0x6a8c608f,0xdaca2a8a),LL(0x0725b276,0x53ef07f6), + LL(0x7824fc56,0x07a5fbd2),LL(0x13289077,0x34675218),LL(0xe0c48349,0x5bf69fd5),LL(0xb6aa7875,0xa613ddd3), LL(0x5450d866,0x7f78c19c),LL(0x8f84a481,0x46f4409c),LL(0x90fce239,0x9f1d1928),LL(0xb2ce44b9,0x016c4168), + LL(0xc7435978,0xbae023f0),LL(0x20e30e19,0xb152c888),LL(0xe3fa6faf,0x9c241645),LL(0x84823e60,0x735d95c1), LL(0x03955317,0x03197573),LL(0xf03b4995,0x0b4b02a9),LL(0x70274600,0x076bf559),LL(0xaaf57508,0x32c5cc53), + LL(0x60624129,0xe8af6d1f),LL(0x9a5e2b5e,0xb7bc5d64),LL(0x5f082d72,0x3814b048),LL(0xce19677a,0x76f267f2), LL(0xb36eed93,0x626c630f),LL(0x3bf56803,0x55230cd7),LL(0xce2736a0,0x78837949),LL(0xaa6c55f1,0x0d792d60), + LL(0xd5c7c5d2,0x0318dbfd),LL(0x072b342d,0xb38f8da7),LL(0x7b8de38a,0x3569bddc),LL(0xa1c94842,0xf25b5887), LL(0x2946ad60,0xb2d5b284),LL(0xe9d1707e,0x854f29ad),LL(0x2c6a4509,0xaa5159dc),LL(0x57189837,0x899f94c0), + LL(0xf4a55b03,0xcf6adc51),LL(0x35e3b2d5,0x261762de),LL(0x04827b51,0x4cc43012),LL(0xc6021442,0xcd22a113), LL(0x247c9569,0xce2fd61a),LL(0xd152beca,0x59a50973),LL(0x63a716d4,0x6c835a11),LL(0x187dedcf,0xc26455ed), + LL(0x49ce89e7,0x27f536e0),LL(0xcc890cb5,0x18908539),LL(0xd83c2aa1,0x308909ab),LL(0x1ab73bd3,0xecd3142b), LL(0xb3f5ab84,0x6a85bf59),LL(0xf2bea4c6,0x3c320a68),LL(0x6da4541f,0xad8dc538),LL(0xb7c41186,0xeaf34eb0), + LL(0x977c97c4,0x1c780129),LL(0xc57eb9fa,0x5ff9beeb),LL(0xc822c478,0xa24d0524),LL(0x461cd415,0xfd8eec2a), LL(0xf027458c,0xfbde194e),LL(0x1d1be115,0xb4ff5319),LL(0x4866d6f4,0x63f874d9),LL(0xb21ad0c9,0x35c75015), + LL(0x46ac49d2,0xa6b5c9d6),LL(0x83137aa9,0x42c77c0b),LL(0x68225a38,0x24d000fc),LL(0x2fe1e907,0x0f63cfc8), LL(0xc6441f95,0x22d1b01b),LL(0xec8e448f,0x7d38f719),LL(0x787fb1ba,0x9b33fa5f),LL(0x190158df,0x94dcfda1), + LL(0x5f6d4a09,0xc47cb339),LL(0xee52b826,0x6b4f355c),LL(0xf51b930a,0x3d100f5d),LL(0x9f668f69,0xf4512fac), LL(0x206c4c74,0x546781d5),LL(0xcb4d2e48,0xd021d4d4),LL(0xca085c2d,0x494a54c2),LL(0x520850a8,0xf1dbaca4), + LL(0x490a1aca,0x63c79326),LL(0x41526b02,0xcb64dd9c),LL(0xa2979258,0xbb772591),LL(0x48d97846,0x3f582970), LL(0x7c213ba7,0xd66b70d1),LL(0xe8a0ced4,0xc28febb5),LL(0xc10338c1,0x6b911831),LL(0xbf0126f3,0x0d54e389), + LL(0x4af206ee,0x7048d460),LL(0x77e97cb9,0x786c88f6),LL(0xac64802e,0xd4375ae1),LL(0xd53ec11c,0x469bcfe1), LL(0x47062230,0xfc9b340d),LL(0xc5b4a3ac,0xe743bb57),LL(0x59ef45ac,0xfe00b4aa),LL(0x59edf188,0x29a4ef23), + LL(0xb483689b,0x40242efe),LL(0x513ac262,0x2575d3f6),LL(0x0ca6db72,0xf30037c8),LL(0x98864be2,0xc9fcce82), LL(0x0149362d,0x84a112ff),LL(0x1c4ae971,0x95e57582),LL(0x945cf86c,0x1fa4b1a8),LL(0x0b024a2f,0x4525a734), + LL(0x8f338360,0xe76c8b62),LL(0x28edf32b,0x483ff593),LL(0x298b1aec,0x67e8e90a),LL(0x736d9a21,0x9caab338), LL(0x66892709,0x5c09d2fd),LL(0xb55a1d41,0x2496b4dc),LL(0xe24a4394,0x93f5fb1a),LL(0x6fa8f6c1,0x08c75049), + LL(0xc905d85f,0xcaead1c2),LL(0x0733ae57,0xe9d7f790),LL(0xf07cdd94,0x24c9a65c),LL(0xa4b55931,0x7389359c), LL(0x367e45f7,0xf58709b7),LL(0xcb7e7adc,0x1f203067),LL(0xc7b72818,0x82444bff),LL(0xbaac8033,0x07303b35), + LL(0xd13b7ea1,0x1e1ee4e4),LL(0xe0e74180,0xe6489b24),LL(0x7e70ef70,0xa5f2c610),LL(0xbdd10894,0xa1655412), LL(0x7af4194e,0x555ebefb),LL(0x8e89bd9c,0x533c1c3c),LL(0x89895856,0x735b9b57),LL(0x567f5c15,0x15fb3cd2), + LL(0x526f09fd,0x057fed45),LL(0x8128240a,0xe8a4f10c),LL(0xff2bfd8d,0x9332efc4),LL(0xbd35aa31,0x214e77a0), LL(0x14faa40e,0x32896d73),LL(0x01e5f186,0x767867ec),LL(0x17a1813e,0xc9adf8f1),LL(0x54741795,0xcb6cda78), + LL(0x349d51aa,0xb7521b6d),LL(0xe3c7b8e9,0xf56b5a9e),LL(0x32a096df,0xc6f1e5c9),LL(0xa3635024,0x083667c4), LL(0x18087f2f,0x365ea135),LL(0xd136e45d,0xf1b8eaac),LL(0x73aec989,0xc8a0e484),LL(0x142c9259,0xd75a324b), + LL(0x01dae185,0xb7b4d001),LL(0x9b7a94bc,0x45434e0b),LL(0xfbd8cb0b,0xf54339af),LL(0xe98ef49e,0xdcc4569e), LL(0x09a51299,0x7789318a),LL(0xb2b025d8,0x81b4d206),LL(0xfae85792,0xf64aa418),LL(0xacd7baf7,0x3e50258f), + LL(0x2996864b,0xdce84cdb),LL(0x1f485fa4,0xa2e67089),LL(0x534c6a5a,0xb28b2bb6),LL(0xc94b9d39,0x31a7ec6b), LL(0xd6bc20da,0x1d217766),LL(0x86761190,0x4acdb5ec),LL(0x73701063,0x68726328),LL(0x2128c29b,0x4d24ee7c), + LL(0xa19fd868,0xc072ebd3),LL(0xdb8ddd3b,0x612e481c),LL(0x1a64d852,0xb4e1d754),LL(0xc4c6c4ab,0x00ef95ac), LL(0xaa0a6c46,0x1536d2ed),LL(0x43774790,0x61294086),LL(0x343fda10,0x54af25e8),LL(0xfd25d6f2,0x9ff9d98d), + LL(0x468b8835,0x0746af7c),LL(0x730ecea7,0x977a31cb),LL(0xc2cf4a81,0xa5096b80),LL(0x6458c37a,0xaa986833), LL(0xa6bd9d34,0x6af29bf3),LL(0x33c5d854,0x6a62fe9b),LL(0xb7133b5e,0x50e6c304),LL(0x7d6e6848,0x04b60159), + LL(0x5579bea4,0x4cd296df),LL(0x5ceedaf1,0x10e35ac8),LL(0xe3bcc5b1,0x04c4c5fd),LL(0x89412cf9,0x95f9ee8a), LL(0x82b6eb0f,0x2c9459ee),LL(0x95c2aadd,0x2e845765),LL(0xd327fcfe,0x774a84ae),LL(0x0368d476,0xd8c93722), + LL(0xf83e8a3b,0x0dbd5748),LL(0x8d2495f3,0xa579aa96),LL(0xae496e9b,0x535996a0),LL(0xb7f9bcc2,0x07afbfe9), LL(0x5b7bd293,0x3ac1dc6d),LL(0x7022323d,0x3b592cff),LL(0x9c0a3e76,0xba0deb98),LL(0x4b197acb,0x18e78e9f), + LL(0x296c36ef,0x211cde10),LL(0x82c4da77,0x7ee89672),LL(0xa57836da,0xb617d270),LL(0x9cb7560b,0xf0cd9c31), LL(0xe455fe90,0x01fdcbf7),LL(0x7e7334f3,0x3fb53cbb),LL(0x4e7de4ec,0x781e2ea4),LL(0x0b384fd0,0x8adab3ad), + LL(0x53d64829,0x129eee2f),LL(0xa261492b,0x7a471e17),LL(0xe4cb4a2c,0xe4f9adb9),LL(0x97ba2c2d,0x3d359f6f), LL(0x0aacd697,0x346c6786),LL(0x75c2f8a8,0x92b444c3),LL(0xd85df44e,0xc79fa117),LL(0x398ddf31,0x56782372), + LL(0xbbbab3b8,0x60e690f2),LL(0x8b04816b,0x4851f8ae),LL(0x9c92e4d2,0xc72046ab),LL(0x7cf3136b,0x518c74a1), LL(0xf9877d4c,0xff4eb50a),LL(0xa919cabb,0x14578d90),LL(0xac5eb2b6,0x8218f8c4),LL(0x542016e4,0xa3ccc547), + LL(0x327f8349,0x025bf48e),LL(0xf43cb641,0xf3e97346),LL(0x500f1085,0xdc2bafdf),LL(0x2f063055,0x57167876), LL(0x411925a6,0x5bd914b9),LL(0xa1123de5,0x7c078d48),LL(0x182b165d,0xee6bf835),LL(0xba519727,0xb11b5e5b), + LL(0x1eea7b85,0xe33ea76c),LL(0x92d4f85e,0x2352b461),LL(0xafe115bb,0xf101d334),LL(0x889175a3,0xfabc1294), LL(0x5233f925,0x7f6bcdc0),LL(0xe77fec55,0xe0a802db),LL(0x8069b659,0xbdb47b75),LL(0xf98fbd74,0x1c5e12de), + LL(0x4b8457ee,0x869c58c6),LL(0x4f7ea9f7,0xa5360f69),LL(0xf460b38f,0xe576c09f),LL(0x22b7fb36,0x6b70d548), LL(0x3bfae315,0x3fd237f1),LL(0xcbdff369,0x33797852),LL(0x25b516f9,0x97df25f5),LL(0xba38ad2d,0x46f388f2), + LL(0x89d8ddbb,0x656c4658),LL(0x70f38ee8,0x8830b26e),LL(0xde1212b0,0x4320fd5c),LL(0xe4a2edb2,0xc34f30cf), LL(0x56ab64b8,0xabb131a3),LL(0xd99c5d26,0x7f77f0cc),LL(0xbf981d94,0x66856a37),LL(0x738bd76e,0x19e76d09), + LL(0x96238f39,0xe76c8ac3),LL(0xa830b366,0xc0a482be),LL(0x0b4eb499,0xb7b8eaff),LL(0x4bfb4865,0x8ecd83bc), LL(0xa2f3776f,0x971b2cb7),LL(0xf4b88adf,0xb42176a4),LL(0xbe1fa446,0xb9617df5),LL(0xcd031bd2,0x8b32d508), + LL(0x53b618c0,0x1c6bd47d),LL(0x6a227923,0xc424f46c),LL(0xdd92d964,0x7303ffde),LL(0x71b5abf2,0xe9712878), LL(0xf815561d,0x8f48a632),LL(0xd3c055d1,0x85f48ff5),LL(0x7525684f,0x222a1427),LL(0x67360cc3,0xd0d841a0), + LL(0x0b9267c6,0x4245a926),LL(0xcf07f863,0xc78913f1),LL(0x4d0d9e24,0xaa844c8e),LL(0x3d5f9017,0xa42ad522), LL(0xa2c989d5,0xbd371749),LL(0xe1f5e78e,0x928292df),LL(0x0a1ea6da,0x493b383e),LL(0x13aee529,0x5136fd8d), + LL(0xf2c34a99,0x860c44b1),LL(0xbf5855ac,0x3b00aca4),LL(0xfaaf37be,0xabf6aaa0),LL(0x2a53ec08,0x65f43682), LL(0xa11b12e1,0x1d9a5801),LL(0xe20ed475,0x78a7ab2c),LL(0x9a41e0d5,0x0de1067e),LL(0x305023ea,0x30473f5f), + LL(0x169c7d97,0xdd3ae09d),LL(0xcfaef9cd,0x5cd5baa4),LL(0x65a44803,0x5cd7440b),LL(0x47f364de,0xdc13966a), LL(0x2b8357c1,0x077b2be8),LL(0xe9d57c2a,0x0cb1b4c5),LL(0x05ff363e,0x7a4ceb32),LL(0xca35a9ef,0xf310fa4d), + LL(0xf97f68c6,0xdbb7b352),LL(0x0b02cf58,0x0c773b50),LL(0x3c1f96d9,0xea2e4821),LL(0xeee01815,0xffb357b0), LL(0xe0f28039,0xb9c924cd),LL(0x46a3fbe4,0x0b36c95a),LL(0x5e46db6c,0x1faaaea4),LL(0x1928aaff,0xcae575c3), + LL(0xa70dab86,0x7f671302),LL(0x71c58cfc,0xfcbd12a9),LL(0xbee0cb92,0xcbef9acf),LL(0xf8c1b583,0x573da0b9), LL(0x0d41d550,0x4752fcfe),LL(0x2155cffe,0xe7eec0e3),LL(0x545ae248,0x0fc39fcb),LL(0x8065f44e,0x522cb8d1), + LL(0x70cbb96c,0x263c962a),LL(0xbcd124a9,0xe034362a),LL(0x3c2ae58d,0xf120db28),LL(0xfef6d507,0xb9a38d49), LL(0x1ff140fd,0xb1fd2a82),LL(0x20aee7e0,0xbd162f30),LL(0xcb251949,0x4e17a5d4),LL(0x4f7e1c3d,0x2aebcb83), + LL(0x937b0527,0x608eb25f),LL(0xeb7d9997,0xf42e1e47),LL(0xb8a53a29,0xeba699c4),LL(0xe091b536,0x1f921c71), LL(0x5b26bbd5,0xcce29e7b),LL(0x3b61a680,0x7a8ef5ed),LL(0xba1f1c7e,0xe5ef8043),LL(0x18158dda,0x16ea8217), + LL(0x599ff0f9,0x01778a2b),LL(0x8104fc6b,0x68a923d7),LL(0xda694ff3,0x5bfa44df),LL(0xf7667f12,0x4f7199db), LL(0xe46f2a79,0xc06d8ff6),LL(0xe9f8131d,0x08b5dead),LL(0xabb4ce7c,0x02519a59),LL(0xb42aec3e,0xc4f710bc), + LL(0x78bde41a,0x3d77b057),LL(0xb4186b5a,0x6474bf80),LL(0x88c65741,0x048b3f67),LL(0x03c7c154,0xc64519de), LL(0x0edfcc4f,0xdf073846),LL(0x48f1aa6b,0x319aa737),LL(0xca909f77,0x8b9f8a02),LL(0x7580bfef,0x90258139), + LL(0xc0c22719,0xd8bfd3ca),LL(0xc9ca151e,0xc60209e4),LL(0xd9a1a69c,0x7a744ab5),LL(0x14937f8f,0x6de5048b), LL(0xe115ac04,0x171938d8),LL(0x1c6b16d2,0x7df70940),LL(0x7f8e94e7,0xa6aeb663),LL(0x2a2cf094,0xc130388e), + LL(0x77f54e6e,0x1850be84),LL(0x65d60fe5,0x9f258a72),LL(0x6c9146d6,0xff7ff0c0),LL(0xe63a830b,0x039aaf90), LL(0x9460342f,0x38f27a73),LL(0x3f795f8a,0x4703148c),LL(0x9681a97e,0x1bb5467b),LL(0xecaeb594,0x00931ba5), + LL(0x786f337c,0xcdb6719d),LL(0xe704397d,0xd9c01cd2),LL(0x555c2fef,0x0f4a3f20),LL(0x7c0af223,0x00452509), LL(0x84db8e76,0x54a58047),LL(0x93c8aa06,0x3bacf1aa),LL(0xf7919422,0x11ca957c),LL(0x78cdaa40,0x50641053), + LL(0x9f7144ae,0x7a303874),LL(0x43d4acfd,0x170c963f),LL(0x58ddd3ef,0x5e148149),LL(0x9e72dba8,0xa7bde582), LL(0x6fa68750,0x0769da8b),LL(0x572e0249,0xfa64e532),LL(0x2619ad31,0xfcaadf9d),LL(0xa7b349cd,0x87882daa), + LL(0x6c67a775,0x9f6eb731),LL(0xefc5d0b1,0xcb10471a),LL(0xe1b806b2,0xb433750c),LL(0x57b1ae7e,0x19c5714d), LL(0xed03fd3f,0xc0dc8b7b),LL(0x31bc194e,0xdd03344f),LL(0x8c6320b5,0xa66c52a7),LL(0xd0b6fd93,0x8bc82ce3), + LL(0xb35f1341,0xf8e13501),LL(0x25a43e42,0xe53156dd),LL(0x4daeb85c,0xd3adf27e),LL(0xbbeddeb5,0xb81d8379), LL(0x2e435867,0x1b0b546e),LL(0xeba5dd60,0x9020eb94),LL(0x8210cb9d,0x37d91161),LL(0x5c91f1cf,0x4c596b31), + LL(0x0e0b040d,0xb228a90f),LL(0x45ff897f,0xbaf02d82),LL(0x00fa6122,0x2aac79e6),LL(0x8e36f557,0x24828817), LL(0x113ec356,0xb9521d31),LL(0x15eff1f8,0x9e48861e),LL(0xe0d41715,0x2aa1d412),LL(0x53f131b8,0x71f86203), + LL(0x3fd19408,0xf60da8da),LL(0x278d9d99,0x4aa716dc),LL(0xa8c51c90,0x394531f7),LL(0xf59db51c,0xb560b0e8), LL(0xfa34bdad,0xa28fc992),LL(0x9cd4f8bd,0xf024fa14),LL(0x23a9d0d3,0x5cf530f7),LL(0xe28c9b56,0x615ca193), + LL(0x6f73c51e,0x6d2a483d),LL(0xea0dc2dd,0xa4cb2412),LL(0x1eb917ff,0x50663c41),LL(0xeade299e,0x3d3a74cf), LL(0x4a7a9202,0x29b3990f),LL(0xa7b15c3d,0xa9bccf59),LL(0xa5df9208,0x66a3ccdc),LL(0x43f2f929,0x48027c14), + LL(0x40b557f0,0xd385377c),LL(0xcd684660,0xe001c366),LL(0xe2183a27,0x1b18ed6b),LL(0x63210329,0x879738d8), LL(0xbda94882,0xa687c74b),LL(0xa684b299,0xd1bbcc48),LL(0x863b3724,0xaf6f1112),LL(0x2c8ce9f8,0x6943d1b4), + LL(0x098cafb4,0xe044a3bb),LL(0x60d48caf,0x27ed2310),LL(0x3a31b84d,0x542b5675),LL(0xfcddbed7,0xcbf3dd50), LL(0x41b1d830,0x25031f16),LL(0xcb0c1e27,0xa7ec851d),LL(0xb5ae75db,0xac1c8fe0),LL(0x08c52120,0xb24c7557), + LL(0x1d4636c3,0x57f811dc),LL(0x681a9939,0xf8436526),LL(0x9c81adb3,0x1f6bc6d9),LL(0x5b7d80d4,0x840f8ac3), LL(0xf4387f1a,0x731a9811),LL(0xb5156880,0x7c501cd3),LL(0xdfe68867,0xa5ca4a07),LL(0x5fcea120,0xf123d8f0), + LL(0xd607039e,0x1fbb0e71),LL(0xcd3a4546,0x2b70e215),LL(0x53324091,0x32d2f01d),LL(0x180ab19b,0xb796ff08), LL(0x3c57c4aa,0x32d87a86),LL(0xb7c49a27,0x2aed9caf),LL(0x31630d98,0x9fb35eac),LL(0x5c3e20a3,0x338e8cdf), + LL(0x66cde8db,0x80f16182),LL(0x2d72fd36,0x4e159980),LL(0x9b6e5072,0xd7b8f13b),LL(0x3b7b5dc1,0xf5213907), LL(0x8ce4396e,0x4d431f1d),LL(0xa7ed2142,0x37a1a680),LL(0xd01aaf6b,0xbf375696),LL(0xe63aab66,0xaa1c0c54), + LL(0x4ed80940,0x3014368b),LL(0x7a6fcedd,0x67e6d056),LL(0xca97579f,0x7c208c49),LL(0xa23597f6,0xfe3d7a81), LL(0x7e096ae2,0x5e203202),LL(0x24b39366,0xb1f3e1e7),LL(0x2fdcdffc,0x26da26f3),LL(0x6097be83,0x79422f1d), +}, +/* digit=24 base_pwr=2^168 */ +{ + LL(0x9db3b381,0x263a2cfb),LL(0xd4df0a4b,0x9c3a2dee),LL(0x7d04e61f,0x728d06e9),LL(0x42449325,0x8b1adfbc), LL(0x7e053a1b,0x6ec1d939),LL(0x66daf707,0xee2be5c7),LL(0x810ac7ab,0x80ba1e14),LL(0xf530f174,0xdd2ae778), + LL(0x205b9d8b,0x0435d97a),LL(0x056756d4,0x6eb8f064),LL(0xb6f8210e,0xd5e88a8b),LL(0xec9fd9ea,0x070ef12d), LL(0x3bcc876a,0x4d849505),LL(0xa7404ce3,0x12a75338),LL(0xb8a1db5e,0xd22b49e1),LL(0x14bfa5ad,0xec1f2051), + LL(0xb6828f36,0xadbaeb79),LL(0x01bd5b9e,0x9d7a0258),LL(0x1e844b0c,0xeda01e0d),LL(0x887edfc9,0x4b625175), LL(0x9669b621,0x14109fdd),LL(0xf6f87b98,0x88a2ca56),LL(0x170df6bc,0xfe2eb788),LL(0xffa473f9,0x0cea06f4), + LL(0xc4e83d33,0x43ed81b5),LL(0x5efd488b,0xd9f35879),LL(0x9deb4d0f,0x164a620f),LL(0xac6a7394,0xc6927bdb), LL(0x9f9e0f03,0x45c28df7),LL(0xfcd7e1a9,0x2868661e),LL(0xffa348f1,0x7cf4e8d0),LL(0x398538e0,0x6bd4c284), + LL(0x289a8619,0x2618a091),LL(0x6671b173,0xef796e60),LL(0x9090c632,0x664e46e5),LL(0x1e66f8fb,0xa38062d4), LL(0x0573274e,0x6c744a20),LL(0xa9271394,0xd07b67e4),LL(0x6bdc0e20,0x391223b2),LL(0xeb0a05a7,0xbe2d93f1), + LL(0x3f36d141,0xf23e2e53),LL(0x4dfca442,0xe84bb3d4),LL(0x6b7c023a,0xb804a48d),LL(0x76431c3b,0x1e16a8fa), LL(0xddd472e0,0x1b5452ad),LL(0x0d1ee127,0x7d405ee7),LL(0xffa27599,0x50fc6f1d),LL(0xbf391b35,0x351ac53c), + LL(0x4444896b,0x7efa14b8),LL(0xf94027fb,0x64974d2f),LL(0xde84487d,0xefdcd0e8),LL(0x2b48989b,0x8c45b260), LL(0xd8463487,0xa8fcbbc2),LL(0x3fbc476c,0xd1b2b3f7),LL(0xc8f443c0,0x21d005b7),LL(0x40c0139c,0x518f2e67), + LL(0x06d75fc1,0x56036e8c),LL(0x3249a89f,0x2dcf7bb7),LL(0xe245e7dd,0x81dd1d3d),LL(0xebd6e2a7,0xf578dc4b), LL(0xdf2ce7a0,0x4c028903),LL(0x9c39afac,0xaee36288),LL(0x146404ab,0xdc847c31),LL(0xa4e97818,0x6304c0d8), + LL(0xa91f6791,0xae51dca2),LL(0x9baa9efc,0x2abe4190),LL(0x559c7ac1,0xd9d2e2f4),LL(0xfc9f773a,0xe82f4b51), LL(0x4073e81c,0xa7713027),LL(0xfbb596fc,0xc0276fac),LL(0xa684f70c,0x1d819fc9),LL(0xc9f7b1e0,0x29b47fdd), + LL(0x459b1940,0x358de103),LL(0x5b013e93,0xec881c59),LL(0x49532ad3,0x51574c93),LL(0xb37b46de,0x2db1d445), LL(0xdf239fd8,0xc6445b87),LL(0x151d24ee,0xc718af75),LL(0xf43c6259,0xaea1c4a4),LL(0x70be02f7,0x40c0e5d7), + LL(0x721b33f2,0x6a4590f4),LL(0xfedf04ea,0x2124f1fb),LL(0x9745efe7,0xf8e53cde),LL(0x65f046d9,0xe7e10432), LL(0xe4d0c7e6,0xc3fca28e),LL(0x87253b1b,0x847e339a),LL(0x3743e643,0x9b595348),LL(0x4fd12fc5,0xcb6a0a0b), + LL(0x27d02dcc,0xfb6836c3),LL(0x7a68bcc2,0x5ad00982),LL(0x005e912d,0x1b24b44c),LL(0x811fdcfe,0xcc83d20f), LL(0x666fba0c,0x36527ec1),LL(0x14754635,0x69948197),LL(0x556da9c2,0xfcdcb1a8),LL(0x81a732b2,0xa5934267), + LL(0xa714181d,0xec1214ed),LL(0x6067b341,0x609ac13b),LL(0xa545df1f,0xff4b4c97),LL(0x34d2076b,0xa1240501), LL(0x1409ca97,0x6efa0c23),LL(0x20638c43,0x254cc1a8),LL(0xdcfb46cd,0xd4e363af),LL(0x03942a27,0x62c2adc3), + LL(0x56e46483,0xc67b9df0),LL(0x63736356,0xa55abb20),LL(0xc551bc52,0xab93c098),LL(0xb15fe64b,0x382b49f9), LL(0x4dff8d47,0x9ec221ad),LL(0x437df4d6,0x79caf615),LL(0xbb456509,0x5f13dc64),LL(0x191f0714,0xe4c589d9), + LL(0x3fd40e09,0x27b6a8ab),LL(0x77313ea9,0xe455842e),LL(0x1f55988b,0x8b51d1e2),LL(0x062bbbfc,0x5716dd73), LL(0x4e8bf3de,0x633c11e5),LL(0x1b85be3b,0x9a0e77b6),LL(0x0911cca6,0x56510729),LL(0xefa6590f,0x27e76495), + LL(0x070d3aab,0xe4ac8b33),LL(0x9a2cd5e5,0x2643672b),LL(0x1cfc9173,0x52eff79b),LL(0x90a7c13f,0x665ca49b), LL(0xb3efb998,0x5a8dda59),LL(0x052f1341,0x8a5b922d),LL(0x3cf9a530,0xae9ebbab),LL(0xf56da4d7,0x35986e7b), + LL(0xff3513cc,0x3a636b5c),LL(0x3198f7dd,0xbb0cf8ba),LL(0x41f16f86,0xb8d40522),LL(0xde13a7bf,0x760575d8), LL(0x9f7aa181,0x36f74e16),LL(0xf509ed1c,0x163a3ecf),LL(0x3c40a491,0x6aead61f),LL(0xdfe8fcaa,0x158c95fc), + LL(0x13cda46f,0xa3991b6e),LL(0x342faed0,0x79482415),LL(0x666b5970,0xf3ba5bde),LL(0xb26ab6dd,0x1d52e6bc), LL(0x8608dd3d,0x768ba1e7),LL(0xea076586,0x4930db2a),LL(0xe7dc1afa,0xd9575714),LL(0xf7c58817,0x1fc7bf7d), + LL(0xd9eee96c,0x6b47accd),LL(0xe58cec37,0x0ca277fb),LL(0xe702c42a,0x113fe413),LL(0xc47cbe51,0xdd1764ee), LL(0x7b3ed739,0x041e7cde),LL(0x5ce9e1c0,0x50cb7459),LL(0x2925b212,0x35568513),LL(0x001b081c,0x7cff95c4), + LL(0x8088b454,0x63ee4cbd),LL(0x9a9e0c8a,0xdb7f32f7),LL(0x6b2447cb,0xb377d418),LL(0xd370219b,0xe3e982aa), LL(0xc2a2a593,0x06ccc1e4),LL(0x0773f24f,0x72c36865),LL(0x95859423,0xa13b4da7),LL(0x75040c8f,0x8bbf1d33), + LL(0xda50c991,0x726f0973),LL(0x822d6ee2,0x48afcd5b),LL(0x20fd7771,0xe5fc718b),LL(0xfd0807a1,0xb9e8e77d), LL(0x99a7703d,0x7f5e0f44),LL(0x618e36f3,0x6972930e),LL(0x23807bbe,0x2b7c77b8),LL(0xcb27ff50,0xe5b82405), + LL(0xbd379062,0xba8b8be3),LL(0x2dce4a92,0xd64b7a1d),LL(0xb2952e37,0x040a73c5),LL(0xd438aeca,0x0a9e252e), LL(0xc39d3bcb,0xdd43956b),LL(0xb32b2d63,0x1a31ca00),LL(0x5c417a18,0xd67133b8),LL(0x2ef442c8,0xd08e4790), + LL(0x255c0980,0x98cb1ae9),LL(0x2b4a739f,0x4bd86381),LL(0x1e4a45a1,0x5a5c31e1),LL(0x9cb0db2f,0x1e5d55fe), LL(0x8ff5cc29,0x74661b06),LL(0x0eb8a4f4,0x026b389f),LL(0x58848c24,0x536b21a4),LL(0x81dc72b0,0x2e5bf8ec), + LL(0xad886aac,0x03c187d0),LL(0xb771b645,0x5c16878a),LL(0xc74045ab,0xb07dfc6f),LL(0x7800caed,0x2c6360bf), LL(0xb9c972a3,0x24295bb5),LL(0x7c9a6dba,0xc9e6f88e),LL(0x92a79aa6,0x90ffbf24),LL(0x41c26ac2,0xde29d50a), + LL(0xd309cbe6,0x9f0af483),LL(0xe0bced4f,0x5b020d8a),LL(0xb38023e3,0x606e986d),LL(0x1abc6933,0xad8f2c9d), LL(0xe7400e93,0x19292e1d),LL(0x52be5e4d,0xfe3e18a9),LL(0x2e0680bf,0xe8e9771d),LL(0xc54db063,0x8c5bec98), + LL(0x74a55d1f,0x2af9662a),LL(0x046f66d8,0xe3fbf28f),LL(0xd4dc4794,0xa3a72ab4),LL(0x5c7c2dd8,0x09779f45), LL(0xc3d19d8d,0xd893bdaf),LL(0x57d6a6df,0xd5a75094),LL(0x952e6255,0x8cf8fef9),LL(0xda9a8aff,0x3da67cfb), + LL(0x2c160dcd,0x4c23f62a),LL(0x8f90eaef,0x34e6c5e3),LL(0xa9a65d5a,0x35865519),LL(0x8fd38a3d,0x07c48aae), LL(0x50068527,0xb7e7aeda),LL(0x1c90936a,0x2c09ef23),LL(0xe879324c,0x31ecfeb6),LL(0xfb0ec938,0xa0871f6b), + LL(0xd84d835d,0xb1f0fb68),LL(0x861dc1e6,0xc90caf39),LL(0x7594f8d7,0x12e5b046),LL(0x65012b92,0x26897ae2), LL(0xa4d6755d,0xbcf68a08),LL(0x0991fbda,0x403ee41c),LL(0x3bbf17e8,0x733e343e),LL(0x679b3d65,0xd2c7980d), + LL(0xd2e11305,0x33056232),LL(0xf3c07a6f,0x966be492),LL(0xbb15509d,0x6a8878ff),LL(0x0a9b59a4,0xff221101), LL(0xabe30129,0x6c9f564a),LL(0x336e64cf,0xc6f2c940),LL(0x8b0c8022,0x0fe75262),LL(0x6ae8db87,0xbe0267e9), + LL(0x93bc042b,0x22e192f1),LL(0xb237c458,0xf085b534),LL(0x832c4168,0xa0d192bd),LL(0xbdf6271d,0x7a76e9e3), LL(0xb88911b5,0x52a882fa),LL(0xb4db0eb5,0xc85345e4),LL(0x81a7c3ff,0xa3be02a6),LL(0xf0ec0469,0x51889c8c), + LL(0xa5e829e5,0x9d031369),LL(0x1607aa41,0xcbb4c6fc),LL(0x241d84c1,0x75ac59a6),LL(0x8829e0ee,0xc043f2bf), LL(0x8ea5e185,0x82a38f75),LL(0xd87cbd9f,0x8bda40b9),LL(0x2d8fc601,0x9e65e75e),LL(0xa35690b3,0x3d515f74), + LL(0xda79e5ac,0x534acf4f),LL(0x8630215f,0x68b83b3a),LL(0xd085756e,0x5c748b2e),LL(0xe5d37cb2,0xb0317258), LL(0xc5ccc2c4,0x6735841a),LL(0x3d9d5069,0x7d7dc96b),LL(0xfd1754bd,0xa147e410),LL(0xd399ddd5,0x65296e94), + LL(0xbc8fa5bc,0xf6b5b2d0),LL(0x500c277b,0x8a5ead67),LL(0xdfa08a5d,0x214625e6),LL(0x959cf047,0x51fdfedc), LL(0x289fca32,0x6bc9430b),LL(0x9d9bdc3f,0xe36ff0cf),LL(0x58ea0ede,0x2fe187cb),LL(0x5a900b3f,0xed66af20), + LL(0x5fa9f4d6,0x00e0968b),LL(0x37a362e7,0x2d4066ce),LL(0xbd07e772,0xa99a9748),LL(0x06a4f1d0,0x710989c0), LL(0xce40cbd8,0xd5dedf35),LL(0x1743293d,0xab55c5f0),LL(0x8aa24e2c,0x766f1144),LL(0x605fbcb4,0x94d874f8), + LL(0xa518001b,0xa365f0e8),LL(0x9d04ef0f,0xee605eb6),LL(0xba8d4d25,0x5a3915cd),LL(0xb5113472,0x44c0e1b8), LL(0x8b6740dc,0xcbb024e8),LL(0xee1d4f0c,0x89087a53),LL(0x1fc4e372,0xa88fa05c),LL(0xaf8b3af2,0x8bf395cb), + LL(0xdeb8568b,0x1e71c9a1),LL(0x80fb3d32,0xa35daea0),LL(0x2cf8fb81,0xe8b6f266),LL(0x9490696a,0x6d51afe8), LL(0x51803a19,0x81beac6e),LL(0x86219080,0xe3d24b7f),LL(0xdf6f463c,0x727cfd9d),LL(0x72284ee8,0x8c6865ca), + LL(0xb743f4ef,0x32c88b7d),LL(0xe7d11dce,0x3793909b),LL(0x2ff2ebe8,0xd398f922),LL(0xe5e49796,0x2c70ca44), LL(0xcb1131b1,0xdf4d9929),LL(0x25888e79,0x7826f298),LL(0xf1d8740a,0x4d3a112c),LL(0x270afa8b,0x00384cb6), + LL(0x3ab48095,0xcb64125b),LL(0x62d05106,0x3451c256),LL(0xa4955845,0xd73d577d),LL(0xbf9f4433,0x39570c16), LL(0xadecf263,0xd7dfaad3),LL(0xdc76e102,0xf1c3d8d1),LL(0x54c6a836,0x5e774a58),LL(0x3e92d47b,0xdad4b672), + LL(0xf0d796a0,0xbe7e990f),LL(0xdf0e8b02,0x5fc62478),LL(0x030c00ad,0x8aae8bf4),LL(0x9004ba0f,0x3d2db93b), LL(0xd85d5ddc,0xe48c8a79),LL(0x6bb07f34,0xe907caa7),LL(0xa39eaed5,0x58db343a),LL(0xadaf5724,0x0ea6e007), + LL(0xd23233f3,0xe00df169),LL(0x77cb637f,0x3e322796),LL(0x1da0cf6c,0x1f897c0e),LL(0x31d6bbdd,0xa651f5d8), LL(0x1a230c76,0xdd61af19),LL(0xcdaa5e4a,0xbd527272),LL(0xd0abcd7e,0xca753636),LL(0x370bd8dc,0x78bdd37c), + LL(0x17cd93fe,0xc23916c2),LL(0xdadce6e2,0x65b97a4d),LL(0x174e42f8,0xe04ed4eb),LL(0xbb21480a,0x1491ccaa), LL(0x23196332,0x145a8280),LL(0x587b479a,0x3c3862d7),LL(0x01dcd0ed,0x9f4a88a3),LL(0x3ea12f1f,0x4da2b7ef), + LL(0xb126e48e,0xf8e7ae33),LL(0xf494e237,0x404a0b32),LL(0xc55acadb,0x9beac474),LL(0xcbec9fd9,0x4ee5cf3b), LL(0x7df3c8c3,0x336b33b9),LL(0xb76808fd,0xbd905fe3),LL(0xaa45c16a,0x8f436981),LL(0x3dd27b62,0x255c5bfa), + LL(0xc3dd9b4d,0x71965cbf),LL(0xfc068a87,0xce23edbf),LL(0x745b029b,0xb78d4725),LL(0xcefdd9bd,0x74610713), LL(0x1266bf52,0x7116f75f),LL(0x18e49bb6,0x02046722),LL(0x3d6f19e3,0xdf43df9f),LL(0xe685cb2f,0xef1bc7d0), + LL(0x7078c432,0xcddb27c1),LL(0xb77fedb7,0xe1961b9c),LL(0xc2290570,0x1edc2f5c),LL(0x19cbd886,0x2c3fefca), LL(0xc2af389a,0xcf880a36),LL(0xbda71cea,0x96c610fd),LL(0x32aa8463,0xf03977a9),LL(0x8586d90a,0x8eb7763f), + LL(0x2a296e77,0x3f342454),LL(0x42837a35,0xc8718683),LL(0x6a09c731,0x7dc71090),LL(0x51b816db,0x54778ffb), LL(0xaf06defd,0x6b33bfec),LL(0x8592b70b,0xfe3c105f),LL(0x61da6114,0xf937fda4),LL(0x4c266ad7,0x3c13e651), + LL(0x855938e8,0xe363a829),LL(0x9de54b72,0x2eeb5d9e),LL(0x20ccfab9,0xbeb93b0e),LL(0x25e61a25,0x3dffbb5f), LL(0x1acc093d,0x7f655e43),LL(0x3964ce61,0x0cb6cc3d),LL(0xe5e9b460,0x6ab283a1),LL(0xa1c7e72d,0x55d787c5), + LL(0xdeadbf02,0x4d2efd47),LL(0xac459068,0x11e80219),LL(0x71f311f0,0x810c7626),LL(0x4ab6ef53,0xfa17ef8d), LL(0x93e43bff,0xaf47fd25),LL(0x0be40632,0x5cb5ff3f),LL(0x8ee61da3,0x54687106),LL(0xb08afd0f,0x7764196e), + LL(0xf0290a8f,0x831ab3ed),LL(0xcb47c387,0xcae81966),LL(0x184efb4f,0xaad7dece),LL(0x4749110e,0xdcfc53b3), LL(0x4cb632f9,0x6698f23c),LL(0xb91f8067,0xc42a1ad6),LL(0x6284180a,0xb116a81d),LL(0xe901326f,0xebedf5f8), + LL(0x97e3e044,0xf2274c9f),LL(0x11d09fc9,0x42018520),LL(0xd18e6e23,0x56a65f17),LL(0x352b683c,0x2ea61e2a), LL(0x575eaa94,0x27d291bc),LL(0xb8ff522d,0x9e7bc721),LL(0xa7f04d6f,0x5f7268bf),LL(0xaba41748,0x5868c73f), + LL(0x7be0eead,0x9f85c2db),LL(0xff719135,0x511e7842),LL(0xc5ea90d7,0x5a06b1e9),LL(0x26fab631,0x0c19e283), LL(0xe9206c55,0x8af8f0cf),LL(0x3553c06a,0x89389cb4),LL(0xf65f8004,0x39dbed97),LL(0xc508991d,0x0621b037), + LL(0x96e78cc4,0x1c52e635),LL(0x0c06b4a8,0x5385c8b2),LL(0xb0e87d03,0xd84ddfdb),LL(0x934bafad,0xc49dfb66), LL(0x59f70772,0x7071e170),LL(0x3a1db56b,0x3a073a84),LL(0x3b8af190,0x03494903),LL(0xd32920f0,0x7d882de3), + LL(0xb2cf8940,0x91633f0a),LL(0x6f948f51,0x72b0b178),LL(0x782653c8,0x2d28dc30),LL(0xdb903a05,0x88829849), LL(0x6a19d2bb,0xb8095d0c),LL(0x86f782cb,0x4b9e7f0c),LL(0x2d907064,0x7af73988),LL(0x8b32643c,0xd12be0fe), + LL(0x0e165dc3,0x358ed23d),LL(0x4e2378ce,0x3d47ce62),LL(0xfeb8a087,0x7e2bb0b9),LL(0xe29e10b9,0x3246e8ae), LL(0x03ce2b4d,0x459f4ec7),LL(0xbbc077cf,0xe9b4ca1b),LL(0x0e9940c1,0x2613b4f2),LL(0x047d1eb1,0xfc598bb9), + LL(0x45036099,0x9744c62b),LL(0x167c65d8,0xa9dee742),LL(0xdabe1943,0x0c511525),LL(0x93c6c624,0xda110554), LL(0x651a3be2,0xae00a52c),LL(0x884449a6,0xcda5111d),LL(0xff33bed1,0x063c06f4),LL(0x0d3d76b4,0x73baaf9a), + LL(0x7fc63668,0x52fb0c9d),LL(0x0c039cde,0x6886c9dd),LL(0x55b22351,0x602bd599),LL(0x360c7c13,0xb00cab02), LL(0x81b69442,0x8cb616bc),LL(0xb55c3cee,0x41486700),LL(0xf49ba278,0x71093281),LL(0x64a50710,0xad956d9c), + LL(0x638a7e81,0x9561f28b),LL(0x5980ddc3,0x54155cdf),LL(0xd26f247a,0xb2db4a96),LL(0x4787d100,0x9d774e4e), LL(0x078637d2,0x1a9e6e2e),LL(0x5e0ae06a,0x1c363e2d),LL(0xe9cfa354,0x7493483e),LL(0x7f74b98d,0x76843cb3), + LL(0xd4b66947,0xbaca6591),LL(0x04460a8c,0xb452ce98),LL(0x43768f55,0x6830d246),LL(0x7dff12df,0xf4197ed8), LL(0x400dd0f7,0x6521b472),LL(0x4b1e7093,0x59f5ca8f),LL(0x080338ae,0x6feff11b),LL(0xa29ca3c6,0x0ada31f6), + LL(0x94a2c215,0x24794eb6),LL(0x05a57ab4,0xd83a43ab),LL(0x2a6f89fe,0x264a543a),LL(0xdd5ec7c2,0x2c2a3868), LL(0x8439d9b2,0xd3373940),LL(0x0acd1f11,0x715ea672),LL(0xe7e6cc19,0x42c1d235),LL(0xb990585c,0x81ce6e96), + LL(0xd809c7bd,0x04e5dfe0),LL(0x8f1050ab,0xd7b2580c),LL(0xd8a4176f,0x6d91ad78),LL(0x4e2e897c,0x0af556ee), LL(0x921de0ac,0x162a8b73),LL(0x7ea78400,0x52ac9c22),LL(0xefce2174,0xee2a4eea),LL(0x6d637f79,0xbe61844e), + LL(0x789a283b,0x0491f1bc),LL(0x880836f4,0x72d3ac3d),LL(0x88e5402d,0xaa1c5ea3),LL(0xd5cc473d,0x1b192421), LL(0x9dc84cac,0x5c0b9998),LL(0x9c6e75b8,0xb0a8482d),LL(0x3a191ce2,0x639961d0),LL(0x6d837930,0xda3bc865), + LL(0x056e6f8f,0xca990653),LL(0x64d133a7,0x84861c41),LL(0x746abe40,0x8b403276),LL(0xebf8e303,0xb7b4d51a), LL(0x220a255d,0x05b43211),LL(0x02419e6e,0xc997152c),LL(0x630c2fea,0x76ff47b6),LL(0x281fdade,0x50518677), + LL(0xcf902b0b,0x3283b8ba),LL(0x37db303b,0x8d4b4eb5),LL(0x755011bc,0xcc89f42d),LL(0xdd09d19b,0xb43d74bb), LL(0x8adba350,0x65746bc9),LL(0xb51c1927,0x364eaf8c),LL(0x10ad72ec,0x13c76596),LL(0xf8d40c20,0x30045121), + LL(0xea7b979b,0x6d2d99b7),LL(0xe6fb3bcd,0xcd78cd74),LL(0x86cffbfe,0x11e45a9e),LL(0x637024f6,0x78a61cf4), LL(0x3d502295,0xd06bc872),LL(0x458cb288,0xf1376854),LL(0x342f8586,0xb9db26a1),LL(0x4beee09e,0xf33effcf), + LL(0xb30cfb3a,0xd7e0c4cd),LL(0x6c9db4c8,0x6d09b8c1),LL(0x07c8d9df,0x40ba1a42),LL(0x1c52c66d,0x6fd495f7), LL(0x275264da,0xfb0e169f),LL(0xe57d8362,0x80c2b746),LL(0x49ad7222,0xedd987f7),LL(0x4398ec7b,0xfdc229af), +}, +/* digit=25 base_pwr=2^175 */ +{ + LL(0x52666a58,0xb0d1ed84),LL(0xe6a9c3c2,0x4bcb6e00),LL(0x26906408,0x3c57411c),LL(0x13556400,0xcfc20755), LL(0x5294dba3,0xa08b1c50),LL(0x8b7dd31e,0xa30ba286),LL(0x991eca74,0xd70ba90e),LL(0xe762c2b9,0x094e142c), + LL(0x979f3925,0xb81d783e),LL(0xaf4c89a7,0x1efd130a),LL(0xfd1bf7fa,0x525c2144),LL(0x1b265a9e,0x4b296904), LL(0xb9db65b6,0xed8e9634),LL(0x03599d8a,0x35c82e32),LL(0x403563f3,0xdaa7a54f),LL(0x022c38ab,0x9df088ad), + LL(0xbb3fd30a,0xe5cfb066),LL(0xeff0354e,0x429169da),LL(0x3524e36c,0x809cf852),LL(0x0155be1d,0x136f4fb3), LL(0x1fbba712,0x4826af01),LL(0x506ba1a1,0x6ef0f0b4),LL(0x77aea73e,0xd9928b31),LL(0x5eaa244e,0xe2bf6af2), + LL(0x4237b64b,0x8d084f12),LL(0xe3ecfd07,0x688ebe99),LL(0xf6845dd8,0x57b8a70c),LL(0x5da4a325,0x808fc59c), LL(0xa3585862,0xa9032b2b),LL(0xedf29386,0xb66825d5),LL(0x431ec29b,0xb5a5a8db),LL(0x3a1e8dc8,0xbb143a98), + LL(0x12ae381b,0x35ee94ce),LL(0x86ccda90,0x3a7f176c),LL(0x4606eaca,0xc63a657e),LL(0x43cd04df,0x9ae5a380), LL(0xed251b46,0x9bec8d15),LL(0xcaca5e64,0x1f5d6d30),LL(0x9ff20f07,0x347b3b35),LL(0xf7e4b286,0x4d65f034), + LL(0xf111661e,0x9e93ba24),LL(0xb105eb04,0xedced484),LL(0xf424b578,0x96dc9ba1),LL(0xe83e9069,0xbf8f66b7), LL(0xd7ed8216,0x872d4df4),LL(0x8e2cbecf,0xbf07f377),LL(0x98e73754,0x4281d899),LL(0x8aab8708,0xfec85fbb), + LL(0xa5ba5b0b,0x9a3c0dee),LL(0x42d05299,0xe6a116ce),LL(0xe9b02d42,0xae9775fe),LL(0xa1545cb6,0x72b05200), LL(0x31a3b4ea,0xbc506f7d),LL(0x8bbd9b32,0xe5893078),LL(0xe4b12a97,0xc8bc5f37),LL(0x4a73b671,0x6b000c06), + LL(0x765fa7d0,0x13b5bf22),LL(0x1d6a5370,0x59805bf0),LL(0x4280db98,0x67a5e29d),LL(0x776b1ce3,0x4f53916f), LL(0x33ddf626,0x714ff61f),LL(0xa085d103,0x4206238e),LL(0xe5809ee3,0x1c50d4b7),LL(0x85f8eb1d,0x999f450d), + LL(0xe4c79e9b,0x658a6051),LL(0xc66a9fea,0x1394cb73),LL(0xc6be7b23,0x27f31ed5),LL(0x5aa6f8fe,0xf4c88f36), LL(0x4aaa499e,0x0fb0721f),LL(0xe3fb2a6b,0x68b3a7d5),LL(0x3a92851d,0xa788097d),LL(0xe96f4913,0x060e7f8a), + LL(0x1a3a93bc,0x82eebe73),LL(0xa21adc1a,0x42bbf465),LL(0xef030efd,0xc10b6fa4),LL(0x87b097bb,0x247aa4c7), LL(0xf60c77da,0x8b8dc632),LL(0xc223523e,0x6ffbc26a),LL(0x344579cf,0xa4f6ff11),LL(0x980250f6,0x5825653c), + LL(0xbc1aa2b9,0xb2dd097e),LL(0x37a0333a,0x07889393),LL(0x37a0db38,0x1cf55e71),LL(0x792c1613,0x2648487f), LL(0x3fcef261,0xdad01336),LL(0x0eabf129,0x6239c81d),LL(0x9d276be2,0x8ee761de),LL(0x1eda6ad3,0x406a7a34), + LL(0x4a493b31,0x4bf367ba),LL(0x9bf7f026,0x54f20a52),LL(0x9795914b,0xb696e062),LL(0x8bf236ac,0xcddab96d), LL(0xed25ea13,0x4ff2c70a),LL(0x81cbbbe7,0xfa1d09eb),LL(0x468544c5,0x88fc8c87),LL(0x696b3317,0x847a670d), + LL(0x64bcb626,0xf133421e),LL(0x26dee0b5,0xaea638c8),LL(0xb310346c,0xd6e7680b),LL(0xd5d4ced3,0xe06f4097), LL(0x7512a30b,0x09961452),LL(0xe589a59a,0xf3d867fd),LL(0x52d0c180,0x2e73254f),LL(0x333c74ac,0x9063d8a3), + LL(0xd314e7bc,0xeda6c595),LL(0x467899ed,0x2ee7464b),LL(0x0a1ed5d3,0x1cef423c),LL(0x69cc7613,0x217e76ea), LL(0xe7cda917,0x27ccce1f),LL(0x8a893f16,0x12d8016b),LL(0x9fc74f6b,0xbcd6de84),LL(0xf3144e61,0xfa5817e2), + LL(0x0821ee4c,0x1f354164),LL(0x0bc61992,0x1583eab4),LL(0x1d72879f,0x7490caf6),LL(0xf76ae7b2,0x998ad9f3), LL(0xa41157f7,0x1e181950),LL(0xe8da3a7e,0xa9d7e1e6),LL(0x8426b95f,0x963784eb),LL(0x542e2a10,0x0ee4ed6e), + LL(0xac751e7b,0xb79d4cc5),LL(0xfd4211bd,0x93f96472),LL(0xc8de4fc6,0x8c72d3d2),LL(0xdf44f064,0x7b69cbf5), LL(0xf4bf94e1,0x3da90ca2),LL(0xf12894e2,0x1a5325f8),LL(0x7917d60b,0x0a437f6c),LL(0x96c9cb5d,0x9be70486), + LL(0xe1dc5c05,0xb4d880bf),LL(0xeebeeb57,0xd738adda),LL(0xdf0fe6a3,0x6f0119d3),LL(0x66eaaf5a,0x5c686e55), LL(0xdfd0b7ec,0x9cb10b50),LL(0x6a497c21,0xbdd0264b),LL(0x8c546c96,0xfc093514),LL(0x79dbf42a,0x58a947fa), + LL(0x49ccd6d7,0xc0b48d4e),LL(0x88bd5580,0xff8fb02c),LL(0x07d473b2,0xc75235e9),LL(0xa2188af3,0x4fab1ac5), LL(0x97576ec0,0x030fa3bc),LL(0x0b7e7d2f,0xe8c946e8),LL(0x70305600,0x40a5c9cc),LL(0xc8b013b4,0x6d8260a9), + LL(0x70bba85c,0x0368304f),LL(0xa4a0d311,0xad090da1),LL(0x2415eec1,0x7170e870),LL(0x8461ea47,0xbfba35fe), LL(0xc1e91938,0x6279019a),LL(0x1afc415f,0xa47638f3),LL(0xbcba0e0f,0x36c65cbb),LL(0x034e2c48,0x02160efb), + LL(0x615cd9e4,0xe6c51073),LL(0xf1243c06,0x498ec047),LL(0xb17b3d8c,0x3e5a8809),LL(0x0cc565f1,0x5cd99e61), LL(0x7851dafe,0x81e312df),LL(0xa79061e2,0xf156f5ba),LL(0x880c590e,0x80d62b71),LL(0x0a39faa1,0xbec9746f), + LL(0xc8ed1f7a,0x1d98a9c1),LL(0xa81d5ff2,0x09e43bb5),LL(0x0da0794a,0xd5f00f68),LL(0x661aa836,0x412050d9), LL(0x90747e40,0xa89f7c4e),LL(0xb62a3686,0x6dc05ebb),LL(0x308e3353,0xdf4de847),LL(0x9fb53bb9,0x53868fbb), + LL(0xcfdcf7dd,0x2b09d2c3),LL(0x723fcab4,0x41a9fce3),LL(0x07f57ca3,0x73d905f7),LL(0xac8e1555,0x080f9fb1), LL(0x9ba7a531,0x7c088e84),LL(0xed9a147f,0x07d35586),LL(0xaf48c336,0x602846ab),LL(0x0ccf0e79,0x7320fd32), + LL(0xb18bd1ff,0xaa780798),LL(0xafdd2905,0x52c2e300),LL(0x434267cd,0xf27ea3d6),LL(0x15605b5f,0x8b96d16d), LL(0x4b45706b,0x7bb31049),LL(0x743d25f8,0xe7f58b8e),LL(0x87f30076,0xe9b5e45b),LL(0x5d053d5a,0xd19448d6), + LL(0xd3210a04,0x1ecc8cb9),LL(0xdafb5269,0x6bc7d463),LL(0x67c3489f,0x3e59b10a),LL(0x65641e1b,0x1769788c), LL(0xbd6cb838,0x8a53b82d),LL(0x236d5f22,0x7066d6e6),LL(0x6908536e,0x03aa1c61),LL(0x66ae9809,0xc971da0d), + LL(0xc49a2fac,0x01b3a86b),LL(0x3092e77a,0x3b8420c0),LL(0x7d6fb556,0x02057300),LL(0xbff40a87,0x6941b2a1), LL(0x0658ff2a,0x140b6308),LL(0x3424ab36,0x87804363),LL(0x5751e299,0x0253bd51),LL(0x449c3e3a,0xc75bcd76), + LL(0x7f8f875d,0x92eb4090),LL(0x56c26bbf,0x9c9d754e),LL(0x8110bbe7,0x158cea61),LL(0x745f91ea,0x62a6b802), LL(0xc6e7394b,0xa79c41aa),LL(0xad57ef10,0x445b6a83),LL(0x6ea6f40c,0x0c5277eb),LL(0x88633365,0x319fe96b), + LL(0x385f63cb,0x0b0fc61f),LL(0x22bdd127,0x41250c84),LL(0x09e942c2,0x67d153f1),LL(0xc021ad5d,0x60920d08), LL(0x724d81a5,0x229f5746),LL(0x5bba3299,0xb7ffb892),LL(0xde413032,0x518c51a1),LL(0x3c2fd94c,0x2a9bfe77), + LL(0x3191f4fd,0xcbcde239),LL(0xd3d6ada1,0x43093e16),LL(0x58769606,0x184579f3),LL(0xd236625c,0x2c94a8b3), LL(0x5c437d8e,0x6922b9c0),LL(0xd8d9f3c8,0x3d4ae423),LL(0x2e7090a2,0xf72c31c1),LL(0xd76a55bd,0x4ac3f5f3), + LL(0x6b6af991,0x342508fc),LL(0x1b5cebbd,0x0d527100),LL(0xdd440dd7,0xb84740d0),LL(0x780162fd,0x748ef841), LL(0xdfc6fafb,0xa8dbfe0e),LL(0xf7300f27,0xeadfdf05),LL(0xfeba4ec9,0x7d06555f),LL(0x9e25fa97,0x12c56f83), + LL(0xd39b8c34,0x77f84203),LL(0x3125eddb,0xed8b1be6),LL(0xf6e39dc5,0x5bbf2441),LL(0x6a5d678a,0xb00f6ee6), LL(0x57d0ea99,0xba456ecf),LL(0x17e06c43,0xdcae0f58),LL(0x0f5b4baa,0x01643de4),LL(0xd161b9be,0x2c324341), + LL(0xe126d468,0x80177f55),LL(0x76748e09,0xed325f1f),LL(0xcfa9bdc2,0x6116004a),LL(0x3a9fb468,0x2d8607e6), LL(0x6009d660,0x0e573e27),LL(0x8d10c5a1,0x3a525d2e),LL(0x3b9009a0,0xd26cb45c),LL(0xde9d7448,0xb6b0cdc0), + LL(0xe1337c26,0x949c9976),LL(0xd73d68e5,0x6faadebd),LL(0xf1b768d9,0x9e158614),LL(0x9cc4f069,0x22dfa557), LL(0xbe93c6d6,0xccd6da17),LL(0xa504f5b9,0x24866c61),LL(0x8d694da1,0x2121353c),LL(0x0140b8c6,0x1c6ca580), + LL(0xe964021e,0xc245ad8c),LL(0x032b82b3,0xb83bffba),LL(0x47ef9898,0xfaa220c6),LL(0x982c948a,0x7e8d3ac6), LL(0xbc2d124a,0x1faa2091),LL(0x05b15ff4,0xbd54c3dd),LL(0xc87c6fb7,0x386bf3ab),LL(0xfdeb6f66,0xfb2b0563), + LL(0x5b45afb4,0x4e77c557),LL(0xefb8912d,0xe9ded649),LL(0x42f6e557,0x7ec9bbf5),LL(0x62671f00,0x2570dfff), LL(0x88e084bd,0x2b3bfb78),LL(0xf37fe5b4,0xa024b238),LL(0x95649aee,0x44e7dc04),LL(0x5e7ec1d8,0x498ca255), + LL(0xaaa07e86,0x3bc766ea),LL(0xf3608586,0x0db6facb),LL(0xbdc259c8,0xbadd2549),LL(0x041c649f,0x95af3c6e), LL(0x02e30afb,0xb36a928c),LL(0x008a88b8,0x9b5356ad),LL(0xcf1d9e9d,0x4b67a5f1),LL(0xa5d8d8ce,0xc6542e47), + LL(0x7adfb6cc,0x73061fe8),LL(0x98678141,0xcc826fd3),LL(0x3c80515a,0x00e758b1),LL(0x41485083,0x6afe3247), LL(0xb6ae8a75,0x0fcb08b9),LL(0x4acf51e1,0xb8cf388d),LL(0x6961b9d6,0x344a5560),LL(0x6a97fd0c,0x1a6778b8), + LL(0xecc4c7e3,0xd840fdc1),LL(0x16db68cc,0xde9fe47d),LL(0xa3e216aa,0xe95f89de),LL(0x9594a8be,0x84f1a6a4), LL(0x5a7b162b,0x7ddc7d72),LL(0xadc817a3,0xc5cfda19),LL(0x78b58d46,0x80a5d350),LL(0x82978f19,0x93365b13), + LL(0x26a1fc90,0x2e44d225),LL(0x4d70705d,0x0d6d10d2),LL(0xd70c45f4,0xd94b6b10),LL(0xb216c079,0x0f201022), LL(0x658fde41,0xcec966c5),LL(0x7e27601d,0xa8d2bc7d),LL(0xff230be7,0xbfcce3e1),LL(0x0033ffb5,0x3394ff6b), + LL(0x8132c9af,0xd890c509),LL(0x361e7868,0xaac4b0eb),LL(0xe82d15aa,0x5194ded3),LL(0x23ae6b7d,0x4550bd2e), LL(0xea5399d4,0x3fda318e),LL(0x91638b80,0xd989bffa),LL(0xa14aa12d,0x5ea124d0),LL(0x3667b944,0x1fb1b899), + LL(0x44c44d6a,0x95ec7969),LL(0x57e86137,0x91df144a),LL(0x73adac44,0x915fd620),LL(0x59a83801,0x8f01732d), LL(0x3aa0a633,0xec579d25),LL(0xc9d6d59c,0x06de5e7c),LL(0xb1ef8010,0xc132f958),LL(0xe65c1a02,0x29476f96), + LL(0xd34c3565,0x336a77c0),LL(0x1b9f1e9e,0xef1105b2),LL(0xf9e08002,0x63e6d08b),LL(0xc613809e,0x9aff2f21), LL(0x3a80e75d,0xb5754f85),LL(0x6bbda681,0xde71853e),LL(0x8197fd7a,0x86f041df),LL(0x127817fa,0x8b332e08), + LL(0xb9c20cda,0x05d99be8),LL(0xd5cd0c98,0x89f7aad5),LL(0x5bb94183,0x7ef936fe),LL(0xb05cd7f2,0x92ca0753), LL(0x74a1e035,0x9d65db11),LL(0x13eaea92,0x02628cc8),LL(0x49e4fbf2,0xf2d9e242),LL(0xe384f8b7,0x94fdfd9b), + LL(0x63428c6b,0x65f56054),LL(0x90b409a5,0x2f7205b2),LL(0xff45ae11,0xf778bb78),LL(0xc5ee53b2,0xa13045be), LL(0x03ef77fe,0xe00a14ff),LL(0xffef8bef,0x689cd59f),LL(0x1e9ade22,0x3578f0ed),LL(0x6268b6a8,0xe99f3ec0), + LL(0xea1b3c3e,0xa2057d91),LL(0xb8823a4a,0x2d1a7053),LL(0x2cca451e,0xabbb336a),LL(0x2218bb5d,0xcd2466e3), LL(0xc8cb762d,0x3ac1f42f),LL(0x7690211f,0x7e312aae),LL(0x45d07450,0xebb9bd73),LL(0x46c2213f,0x207c4b82), + LL(0x375913ec,0x99d425c1),LL(0x67908220,0x94e45e96),LL(0xcd67dbf6,0xc08f3087),LL(0xc0887056,0xa5670fbe), LL(0x66f5b8fc,0x6717b64a),LL(0x786fec28,0xd5a56aea),LL(0xc0ff4952,0xa8c3f55f),LL(0x457ac49b,0xa77fefae), + LL(0x98379d44,0x29882d7c),LL(0x509edc8a,0xd000bdfb),LL(0xe66fe464,0xc6f95979),LL(0xfa61bde0,0x504a6115), LL(0xeffea31a,0x56b3b871),LL(0xf0c21a54,0x2d3de26d),LL(0x834753bf,0x21dbff31),LL(0x69269d86,0xe67ecf49), + LL(0x151fe690,0x7a176952),LL(0x7f2adb5f,0x03515804),LL(0xd1b62a8d,0xee794b15),LL(0xaae454e6,0xf004ceec), LL(0xf0386fac,0x0897ea7c),LL(0xd1fca751,0x3b62ff12),LL(0x1b7a04ec,0x154181df),LL(0xfb5847ec,0x2008e04a), + LL(0x41dbd772,0xd147148e),LL(0x22942654,0x2b419f73),LL(0xe9c544f7,0x669f30d3),LL(0xc8540149,0x52a2c223), LL(0x634dfb02,0x5da9ee14),LL(0xf47869f3,0x5f074ff0),LL(0xa3933acc,0x74ee878d),LL(0x4fe35ed1,0xe6510651), + LL(0xf1012e7a,0xb3eb9482),LL(0xa8a566ae,0x51013cc0),LL(0x47c00d3b,0xdd5e9243),LL(0x946bb0e5,0x7fde089d), LL(0xc731b4b3,0x030754fe),LL(0x99fda062,0x12a136a4),LL(0x5a1a35bc,0x7c1064b8),LL(0x446c84ef,0xbf1f5763), + LL(0xa16d4b34,0xed29a56d),LL(0xdca21c4f,0x7fba9d09),LL(0x6d8de486,0x66d7ac00),LL(0x73a2a5e1,0x60061987), LL(0x9da28ff0,0x8b400f86),LL(0x43c4599c,0x3133f708),LL(0xee28cb0d,0x9911c9b8),LL(0x8e0af61d,0xcd7e2874), + LL(0x72ed91fc,0x5a85f0f2),LL(0x9cd4a373,0x85214f31),LL(0x1925253c,0x881fe5be),LL(0x91e8bc76,0xd8dc98e0), LL(0x585cc3a2,0x7120affe),LL(0x735bf97a,0x724952ed),LL(0x3eb34581,0x5581e7dc),LL(0xe52ee57d,0x5cbff4f2), + LL(0x87d8cc7b,0x8d320a0e),LL(0xf1d280d0,0x9beaa7f3),LL(0x9beec704,0x7a0b9571),LL(0x5b7f0057,0x9126332e), LL(0x8ed3bd6d,0x01fbc1b4),LL(0xd945eb24,0x35bb2c12),LL(0x9a8ae255,0x6404694e),LL(0x8d6abfb3,0xb6092eec), + LL(0xcc058865,0x4d76143f),LL(0x6e249922,0x7b0a5af2),LL(0x6a50d353,0x8aef9440),LL(0x64f0e07a,0xe11e4bcc), LL(0xa14a90fa,0x4472993a),LL(0xba0c51d4,0x7706e20c),LL(0x1532672d,0xf403292f),LL(0x21829382,0x52573bfa), + LL(0x3b5bdb83,0x6a7bb6a9),LL(0xa4a72318,0x08da65c0),LL(0x63eb065f,0xc58d22aa),LL(0x1b15d685,0x1717596c), LL(0xb266d88b,0x112df0d0),LL(0x5941945a,0xf688ae97),LL(0x7c292cac,0x487386e3),LL(0x57d6985c,0x42f3b50d), + LL(0x6a90fc34,0x6da4f998),LL(0x65ca8a8d,0xc8f257d3),LL(0x6951f762,0xc2feabca),LL(0x74c323ac,0xe1bc81d0), LL(0x251a2a12,0x1bc68f67),LL(0xbe8a70dc,0x10d86587),LL(0xf0f84d2e,0xd648af7f),LL(0x6a43ac92,0xf0aa9ebc), + LL(0x27596893,0x69e3be04),LL(0x45bf452b,0xb6bb02a6),LL(0xf4c698c8,0x0875c11a),LL(0xbece3794,0x6652b5c7), LL(0x4f5c0499,0x7b3755fd),LL(0xb5532b38,0x6ea16558),LL(0xa2e96ef7,0xd1c69889),LL(0x61ed8f48,0x9c773c3a), + LL(0x9b323abc,0x2b653a40),LL(0xf0e1d791,0xe26605e1),LL(0x4a87157a,0x45d41064),LL(0xcbbce616,0x8f9a78b7), LL(0xc407eddd,0xcf1e44aa),LL(0xa35b964f,0x81ddd1d8),LL(0xfd083999,0x473e339e),LL(0x8e796802,0x6c94bdde), + LL(0x8545d185,0x5a304ada),LL(0x738bb8cb,0x82ae44ea),LL(0xdf87e10e,0x628a35e3),LL(0xa15b9fe3,0xd3624f3d), LL(0x14be4254,0xcc44209b),LL(0xbdbc2ea5,0x7d0efcbc),LL(0x04c37bbe,0x1f603362),LL(0x56a5852c,0x21f363f5), + LL(0xa8501550,0xa1503d1c),LL(0xd8ab10bb,0x2251e0e1),LL(0x6961c51c,0xde129c96),LL(0x81910f68,0x1f7246a4), LL(0x5f2591f2,0x2eb744ee),LL(0x5e627157,0x3c47d33f),LL(0x22f3bd68,0x4d6d62c9),LL(0xcb8df856,0x6120a64b), + LL(0x7b5d07df,0x3a9ac6c0),LL(0x7ef39783,0xa92b9558),LL(0xab3a9b4f,0xe128a134),LL(0xb1252f05,0x41c18807), LL(0x80ba9b1c,0xfc7ed089),LL(0xc532a9dd,0xac8dc6de),LL(0x55246809,0xbf829cef),LL(0x5b4ee80f,0x101b784f), + LL(0xb6f11603,0xc09945bb),LL(0x41d2801e,0x57b09dbe),LL(0xa97534a8,0xfba5202f),LL(0xc17b9614,0x7fd8ae5f), LL(0x78308435,0xa50ba666),LL(0xd3868c4d,0x9572f77c),LL(0x2dd7aab0,0x0cef7bfd),LL(0x2c7c79ff,0xe7958e08), + LL(0x25346689,0x81262e42),LL(0xb07c7004,0x716da290),LL(0xb7950ee3,0x35f911ea),LL(0x261d21b5,0x6fd72969), LL(0x08b640d3,0x52389803),LL(0x887f12a1,0x5b0026ee),LL(0x742e9311,0x20e21660),LL(0x5ff77ff7,0x0ef6d541), + LL(0xf9c41135,0x969127f0),LL(0x68a64993,0xf21d60c9),LL(0xe541875c,0x656e5d0c),LL(0xa1d3c233,0xf1e0f84e), LL(0x06002d60,0x9bcca359),LL(0x06191552,0xbe2da60c),LL(0x61181ec3,0x5da8bbae),LL(0x65806f19,0x9f04b823), + LL(0xd4b79bb8,0xf1604a7d),LL(0x52c878c8,0xaee806fb),LL(0x8d47b8e8,0x34144f11),LL(0x949f9054,0x72edf52b), LL(0x2127015a,0xebfca84e),LL(0x9cb7cef3,0x9051d0c0),LL(0x296deec8,0x86e8fe58),LL(0x41010d74,0x33b28188), +}, +/* digit=26 base_pwr=2^182 */ +{ + LL(0x171b445f,0x01079383),LL(0x8131ad4c,0x9bcf21e3),LL(0xc93987e8,0x8cdfe205),LL(0xc92e8c8f,0xe63f4152), LL(0x30add43d,0x729462a9),LL(0xc980f05a,0x62ebb143),LL(0x3b06e968,0x4f3954e5),LL(0x242cf6b1,0xfe1d75ad), + LL(0xaf8685c8,0x5f95c6c7),LL(0x2f8f01aa,0xd4c1c8ce),LL(0x2574692a,0xc44bbe32),LL(0xd4a4a068,0xb8003478), LL(0x2eca3cdb,0x7c8fc6e5),LL(0xec04d399,0xea1db16b),LL(0x8f2bc5cf,0xb05bc82e),LL(0xf44793d2,0x763d517f), + LL(0x08bd98d0,0x4451c1b8),LL(0x6575f240,0x644b1cd4),LL(0x7375d270,0x6907eb33),LL(0xfa2286bd,0x56c8bebd), LL(0xc4632b46,0xc713d2ac),LL(0xafd60242,0x17da427a),LL(0xc95c7546,0x313065b7),LL(0xbf17a3de,0xf8239898), + LL(0x4c830320,0xf3b7963f),LL(0x903203e3,0x842c7aa0),LL(0xe7327afb,0xaf22ca0a),LL(0x967609b6,0x38e13092), LL(0x757558f1,0x73b8fb62),LL(0xf7eca8c1,0x3cc3e831),LL(0xf6331627,0xe4174474),LL(0xc3c40234,0xa77989ca), + LL(0x44a081e0,0xe5fd17a1),LL(0xb70e296a,0xd797fb7d),LL(0x481f719c,0x2b472b30),LL(0xfe6f8c52,0x0e632a98), LL(0xc5f0c284,0x89ccd116),LL(0x2d987c62,0xf51088af),LL(0x4c2de6cf,0x2a2bccda),LL(0xf679f0f9,0x810f9efe), + LL(0x7ffe4b3e,0xb0f394b9),LL(0xe5fa5d21,0x0b691d21),LL(0x9dfbbc75,0xb0bd7747),LL(0xfaf78b00,0xd2830fda), LL(0x52434f57,0xf78c249c),LL(0x98096dab,0x4b1f7545),LL(0x8ff8c0b3,0x73bf6f94),LL(0x454e134c,0x34aef03d), + LL(0xb7ac7ec5,0xf8d151f4),LL(0xe50da7d5,0xd6ceb95a),LL(0xdc3a0eb8,0xa1b492b0),LL(0xb3dd2863,0x75157b69), LL(0xc5413d62,0xe2c4c74e),LL(0xbc5fc4c7,0xbe329ff7),LL(0x60fa9dda,0x835a2aea),LL(0x7445cb87,0xf117f5ad), + LL(0xb0166f7a,0xae8317f4),LL(0xceec74e6,0xfbd3e3f7),LL(0xe0874bfd,0xfdb516ac),LL(0xc681f3a3,0x3d846019), LL(0x7c1620b0,0x0b12ee5c),LL(0x2b63c501,0xba68b4dd),LL(0x6668c51e,0xac03cd32),LL(0x4e0bcb5b,0x2a6279f7), + LL(0x6ae85c10,0x17bd69b0),LL(0x1dfdd3a6,0x72946979),LL(0x2c078bec,0xd9a03268),LL(0xbfd68a52,0x41c6a658), LL(0x0e023900,0xcdea1024),LL(0xb10d144d,0xbaeec121),LL(0x058ab8dc,0x5a600e74),LL(0xbb89ccdd,0x1333af21), + LL(0x3aaba1f1,0xdf25eae0),LL(0x3b7144cf,0x2cada16e),LL(0x71ab98bc,0x657ee27d),LL(0x7a6fc96e,0x99088b4c), LL(0x3549dbd4,0x05d5c0a0),LL(0xf158c3ac,0x42cbdf8f),LL(0x87edd685,0x3fb6b3b0),LL(0x86f064d0,0x22071cf6), + LL(0xff2811e5,0xd2d6721f),LL(0xfe7fae8c,0xdb81b703),LL(0xd3f1f7bb,0x3cfb74ef),LL(0x16cdeb5d,0x0cdbcd76), LL(0x566a808c,0x4f39642a),LL(0x340064d6,0x02b74454),LL(0x0528fa6f,0xfabbadca),LL(0xd3fc0bb6,0xe4c3074c), + LL(0xb796d219,0xb32cb8b0),LL(0x34741dd9,0xc3e95f4f),LL(0x68edf6f5,0x87212125),LL(0xa2b9cb8e,0x7a03aee4), LL(0xf53a89aa,0x0cd3c376),LL(0x948a28dc,0x0d8af9b1),LL(0x902ab04f,0xcf86a3f4),LL(0x7f42002d,0x8aacb62a), + LL(0xf62ffd52,0x106985eb),LL(0x5797bf10,0xe670b54e),LL(0xc5e30aef,0x4b405209),LL(0x4365b5e9,0x12c97a20), LL(0x1fe32093,0x104646ce),LL(0x3907a8c9,0x13cb4ff6),LL(0xd46e726b,0x8b9f30d1),LL(0xaba0f499,0xe1985e21), + LL(0x10a230cd,0xc573dea9),LL(0xcd30f947,0x24f46a93),LL(0xabe2010a,0xf2623fcf),LL(0x73f00e4f,0x3f278cb2), LL(0x50b920eb,0xed55c67d),LL(0x8e760571,0xf1cb9a2d),LL(0x0895b709,0x7c50d109),LL(0x190d4369,0x4207cf07), + LL(0xc4127fe1,0x3b027e81),LL(0x3ae9c566,0xa9f8b9ad),LL(0xacbfbba5,0x5ab10851),LL(0x569556f5,0xa747d648), LL(0x2ba97bf7,0xcc172b5c),LL(0xbcfa3324,0x15e0f77d),LL(0x7686279d,0xa345b797),LL(0xe38003d3,0x5a723480), + LL(0x8f5fcda8,0xfd8e139f),LL(0xbdee5bfd,0xf3e558c4),LL(0xe33f9f77,0xd76cbaf4),LL(0x71771969,0x3a4c97a4), LL(0xf6dce6a7,0xda27e84b),LL(0x13e6c2d1,0xff373d96),LL(0xd759a6e9,0xf115193c),LL(0x63d2262c,0x3f9b7025), + LL(0x317cd062,0xd9764a31),LL(0x199f8332,0x30779d8e),LL(0x16b11b0b,0xd8074106),LL(0x78aeaed8,0x7917ab9f), LL(0x28fb1d8e,0xb67a9cbe),LL(0x136eda33,0x2e313563),LL(0xa371a86c,0x010b7069),LL(0x6744e6b7,0x44d90fa2), + LL(0xd6b3e243,0x68190867),LL(0x59048c48,0x9fe6cd9d),LL(0x95731538,0xb900b028),LL(0x32cae04f,0xa012062f), LL(0x9399d082,0x8107c8bc),LL(0x41df12e2,0x47e8c54a),LL(0xb6ef3f73,0x14ba5117),LL(0x81362f0b,0x22260bea), + LL(0x1a18cc20,0x90ea261e),LL(0x2321d636,0x2192999f),LL(0xe311b6a0,0xef64d314),LL(0x3b54a1f5,0xd7401e4c), LL(0x6fbca2ba,0x19019983),LL(0x8fbffc4b,0x46ad3293),LL(0x3786bf40,0xa142d3f6),LL(0xb67039fc,0xeb5cbc26), + LL(0x252bd479,0x9cb0ae6c),LL(0x12b5848f,0x05e0f88a),LL(0xa5c97663,0x78f6d2b2),LL(0xc162225c,0x6f6e149b), LL(0xde601a89,0xe602235c),LL(0xf373be1f,0xd17bbe98),LL(0xa8471827,0xcaf49a5b),LL(0x18aaa116,0x7e1a0a85), + LL(0x270580c3,0x6c833196),LL(0xf1c98a14,0x1e233839),LL(0xae34e0a5,0x67b2f7b4),LL(0xd8ce7289,0x47ac8745), LL(0x100dd467,0x2b74779a),LL(0x4ee50d09,0x274a4337),LL(0x83608bc9,0x603dcf13),LL(0xc89e8388,0xcd9da6c3), + LL(0x355116ac,0x2660199f),LL(0xb6d18eed,0xcc38bb59),LL(0x2f4bc071,0x3075f31f),LL(0x265dc57e,0x9774457f), LL(0xc6db88bb,0x06a6a9c8),LL(0x4ec98e04,0x6429d07f),LL(0x05ecaa8b,0x8d05e57b),LL(0x7872ea7b,0x20f140b1), + LL(0xca494693,0xdf8c0f09),LL(0xf252e909,0x48d3a020),LL(0x57b14b12,0x4c5c29af),LL(0xbf47ad1c,0x7e6fa37d), LL(0x49a0c938,0x66e7b506),LL(0x6be5f41f,0xb72c0d48),LL(0xb2359412,0x6a6242b8),LL(0x8e859480,0xcd35c774), + LL(0x87baa627,0x12536fea),LL(0xf72aa680,0x58c1fec1),LL(0x601e5dc9,0x6c29b637),LL(0xde9e01b9,0x9e3c3c1c), LL(0x2bcfe0b0,0xefc8127b),LL(0x2a12f50d,0x35107102),LL(0x4879b397,0x6ccd6cb1),LL(0xf8a82f21,0xf792f804), + LL(0xa9b46402,0x509d4804),LL(0xc10f0850,0xedddf85d),LL(0x4b6208aa,0x928410dc),LL(0x391012dc,0xf6229c46), LL(0x7727b9b6,0xc5a7c41e),LL(0xaa444842,0x289e4e4b),LL(0xe9a947ea,0x049ba1d9),LL(0x83c8debc,0x44f9e47f), + LL(0x611f8b8e,0xfa77a1fe),LL(0xf518f427,0xfd2e416a),LL(0x114ebac3,0xc5fffa70),LL(0x5d89697b,0xfe57c4e9), LL(0xb1aaf613,0xfdd053ac),LL(0xea585a45,0x31df210f),LL(0x24985034,0x318cc10e),LL(0x5f1d6130,0x1a38efd1), + LL(0x0b1e9e21,0xbf86f237),LL(0x1dbe88aa,0xb258514d),LL(0x90c1baf9,0x1e38a588),LL(0xbdb9b692,0x2936a01e), LL(0x6dd5b20c,0xd576de98),LL(0x70f98ecf,0xb586bf71),LL(0xc42d2fd7,0xcccf0f12),LL(0xfb35bd7b,0x8717e61c), + LL(0x35e6fc06,0x8b1e5722),LL(0x0b3e13d5,0x3477728f),LL(0xaa8a7372,0x150c294d),LL(0x3bfa528a,0xc0291d43), LL(0xcec5a196,0xc6c8bc67),LL(0x5c2e8a7c,0xdeeb31e4),LL(0xfb6e1c51,0xba93e244),LL(0x2e28e156,0xb9f8b71b), + LL(0x968a2ab9,0xce65a287),LL(0x46bbcb1f,0xe3c5ce69),LL(0xe7ae3f30,0xf8c835b9),LL(0xff72b82b,0x16bbee26), LL(0xfd42cd22,0x665e2017),LL(0xf8b1d2a0,0x1e139970),LL(0x79204932,0x125cda29),LL(0x49c3bee5,0x7aee94a5), + LL(0x89821a66,0x68c70160),LL(0x8f981669,0xf7c37678),LL(0x48cc3645,0xd90829fc),LL(0xd70addfc,0x346af049), LL(0x370bf29c,0x2057b232),LL(0x42e650ee,0xf90c73ce),LL(0xa126ab90,0xe03386ea),LL(0x975a087b,0x0e266e7e), + LL(0x0fca65d9,0x80578eb9),LL(0x16af45b8,0x7e2989ea),LL(0xcac75a4e,0x7438212d),LL(0x4fef36b8,0x38c7ca39), LL(0xd402676a,0x8650c494),LL(0xf72c7c48,0x26ab5a66),LL(0xce3a464e,0x4e6cb426),LL(0x2b72f841,0xf8f99896), + LL(0x1a335cc8,0x8c318491),LL(0x6a5913e4,0x563459ba),LL(0xc7b32919,0x1b920d61),LL(0xa02425ad,0x805ab8b6), LL(0x8d006086,0x2ac512da),LL(0xbcf5c0fd,0x6ca4846a),LL(0xac2138d7,0xafea51d8),LL(0x344cd443,0xcb647545), + LL(0xbd7d9040,0x0429ee8f),LL(0x819b9c96,0xee66a2de),LL(0xdea7d744,0x54f9ec25),LL(0x671721bb,0x2ffea642), LL(0x114344ea,0x4f19dbd1),LL(0xfd0dbc8b,0x04304536),LL(0x29ec7f91,0x014b50aa),LL(0xbb06014d,0xb5fc22fe), + LL(0x1ee682e0,0x60d963a9),LL(0xfe85c727,0xdf48abc0),LL(0x2e707c2d,0x0cadba13),LL(0xa645aeff,0xde608d3a), LL(0xedafd883,0x05f1c28b),LL(0xbd94de1f,0x3c362ede),LL(0x13593e41,0x8dd0629d),LL(0x766d6eaf,0x0a5e736f), + LL(0xf68cf9d1,0xbfa92311),LL(0xc1797556,0xa4f9ef87),LL(0x5601c209,0x10d75a1f),LL(0x09b07361,0x651c374c), LL(0x88b5cead,0x49950b58),LL(0x6fa9dbaa,0x0ef00058),LL(0x4e15f33a,0xf51ddc26),LL(0x2ef46140,0x1f8b5ca6), + LL(0xee9523f0,0x343ac0a3),LL(0x975ea978,0xbb75eab2),LL(0x107387f4,0x1bccf332),LL(0x9ab0062e,0x790f9259), LL(0x1e4f6a5f,0xf1a363ad),LL(0x62519a50,0x06e08b84),LL(0x7265f1ee,0x60915187),LL(0x93ae985e,0x6a80ca34), + LL(0xaaba4864,0x81b29768),LL(0x8d52a7d6,0xb13cabf2),LL(0x8ead03f1,0xb5c36348),LL(0x81c7c1c0,0xc932ad95), LL(0xcae1e27b,0x5452708e),LL(0x1b0df648,0x9dac4269),LL(0xdfcdb8bc,0x233e3f0c),LL(0xec540174,0xe6ceccdf), + LL(0x95081181,0xbd0d845e),LL(0x699355d5,0xcc8a7920),LL(0xc3b375a8,0x111c0f6d),LL(0xfd51e0dc,0xfd95bc6b), LL(0x6888523a,0x4a106a26),LL(0xcb01a06d,0x4d142bd6),LL(0xadb9b397,0x79bfd289),LL(0xe9863914,0x0bdbfb94), + LL(0x1660f6a6,0x29d8a229),LL(0x551c042d,0x7f6abcd6),LL(0x0ac3ffe8,0x13039deb),LL(0xec8523fb,0xa01be628), LL(0x0ca1c328,0x6ea34103),LL(0xb903928e,0xc74114bd),LL(0x9e9144b0,0x8aa4ff4e),LL(0x7f9a4b17,0x7064091f), + LL(0xe447f2c4,0xa3f4f521),LL(0x604291f0,0x81b8da7a),LL(0x7d5926de,0xd680bc46),LL(0x34a1202f,0x84f21fd5), LL(0x4e9df3d8,0x1d1e3181),LL(0x39ab8d34,0x1ca4861a),LL(0x5b19aa4a,0x809ddeec),LL(0x4d329366,0x59f72f7e), + LL(0x386d5087,0xa2f93f41),LL(0xdd67d64f,0x40bf739c),LL(0x66702158,0xb4494205),LL(0x73b1e178,0xc33c65be), LL(0x38ca6153,0xcdcd657c),LL(0xdc791976,0x97f4519a),LL(0xcd6e1f39,0xcc7c7f29),LL(0x7e3c3932,0x38de9cfb), + LL(0x7b793f85,0xe448eba3),LL(0xf067e914,0xe9f8dbf9),LL(0xf114ae87,0xc0390266),LL(0xcd6a8e2a,0x39ed75a7), LL(0x7ffba390,0xadb14848),LL(0x6af9bc09,0x67f8cb8b),LL(0x9c7476db,0x322c3848),LL(0x52a538d6,0xa320fecf), + LL(0xb2aced2b,0xe0493002),LL(0x616bd430,0xdfba1809),LL(0xc331be70,0x531c4644),LL(0x90d2e450,0xbc04d32e), LL(0x0f9f142d,0x1805a0d1),LL(0x47ee5a23,0x2c44a0c5),LL(0x3989b4e3,0x31875a43),LL(0x0c063481,0x6b1949fd), + LL(0xbe0f4492,0x2dfb9e08),LL(0xe9d5e517,0x3ff0da03),LL(0xf79466a8,0x03dbe9a1),LL(0x15ea9932,0x0b87bcd0), LL(0xab1f58ab,0xeb64fc83),LL(0x817edc8a,0x6d9598da),LL(0x1d3b67e5,0x699cff66),LL(0x92635853,0x645c0f29), + LL(0xeabaf21c,0x253cdd82),LL(0x2241659e,0x82b9602a),LL(0x2d9f7091,0x2cae07ec),LL(0x8b48cd9b,0xbe4c720c), LL(0x6f08d6c9,0x6ce5bc03),LL(0xaf10bf40,0x36e8a997),LL(0x3e10ff12,0x83422d21),LL(0xbcc12494,0x7b26d3eb), + LL(0xc9469ad6,0xb240d2d0),LL(0x30afa05b,0xc4a11b4d),LL(0xdd6ba286,0x4b604ace),LL(0x3ee2864c,0x18486600), LL(0x8d9ce5be,0x5869d6ba),LL(0xff4bfb0d,0x0d8f68c5),LL(0x5700cf73,0xb69f210b),LL(0x6d37c135,0x61f6653a), + LL(0x5aff5a48,0xff3d432b),LL(0x72ba3a69,0x0d81c4b9),LL(0xfa1899ef,0xee879ae9),LL(0x2d6acafd,0xbac7e2a0), LL(0x1c664399,0xd6d93f6c),LL(0x5bcb135d,0x4c288de1),LL(0x9dab7cbf,0x83031dab),LL(0x3abbf5f0,0xfe23feb0), + LL(0xcdedca85,0x9f1b2466),LL(0x1a09538c,0x140bb710),LL(0x5e11115d,0xac8ae851),LL(0x6f03f59e,0x0d63ff67), LL(0x7d234afb,0x755e5551),LL(0x7e208fc1,0x61c2db4e),LL(0xf28a4b5d,0xaa9859ce),LL(0x34af030f,0xbdd6d4fc), + LL(0x3be01cb1,0xd1c4a26d),LL(0x243aa07c,0x9ba14ffc),LL(0xb2503502,0xf95cd3a9),LL(0x7d2a93ab,0xe379bc06), LL(0xd4ca8d68,0x3efc18e9),LL(0x80bb412a,0x083558ec),LL(0x9645a968,0xd903b940),LL(0x9ba6054f,0xa499f0b6), + LL(0xb8349abe,0x208b573c),LL(0x30b4fc1c,0x3baab3e5),LL(0xcb524990,0x87e978ba),LL(0xccdf0e80,0x3524194e), LL(0x7d4bcc42,0x62711725),LL(0xb90109ba,0xe90a3d9b),LL(0x1323e1e0,0x3b1bdd57),LL(0x5eae1599,0xb78e9bd5), + LL(0x9e03d278,0x0794b746),LL(0xd70e6297,0x80178605),LL(0x99c97855,0x171792f8),LL(0xf5a86b5c,0x11b393ee), LL(0xd8884f27,0x48ef6582),LL(0xbf19ba5f,0xbd44737a),LL(0xa42062c6,0x8698de4c),LL(0x61ce9c54,0x8975eb80), + LL(0xd7fe71f3,0xd50e57c7),LL(0xbc97ce38,0x15342190),LL(0x4df07b63,0x51bda2de),LL(0x200eb87d,0xba12aeae), LL(0xa9b4f8f6,0xabe135d2),LL(0xfad6d99c,0x04619d65),LL(0x7994937c,0x4a6683a7),LL(0x6f94f09a,0x7a778c8b), + LL(0x20a71b89,0x8c508623),LL(0x1c229165,0x241a2aed),LL(0xaaf83a99,0x352be595),LL(0x1562bac8,0x9fbfee7f), LL(0x5c4017e3,0xeaf658b9),LL(0x15120b86,0x1dc7f9e0),LL(0x4c034d6f,0xd84f13dd),LL(0xeaea3038,0x283dd737), + LL(0xcd85d6a2,0x197f2609),LL(0xfae60177,0x6ebbc345),LL(0x4e12fede,0xb80f031b),LL(0x07a2186b,0xde55d0c2), LL(0x24dcdd5a,0x1fb3e37f),LL(0x7ed191fb,0x8d602da5),LL(0x76023e0d,0x108fb056),LL(0x459c20c0,0x70178c71), + LL(0x3fe54cf0,0xfad5a386),LL(0x02bbb475,0xa4a3ec4f),LL(0x919d94d7,0x1aa5ec20),LL(0xa81e4ab3,0x5d3b63b5), LL(0x5ad3d2af,0x7fa733d8),LL(0xd1ac7a37,0xfbc586dd),LL(0x40779614,0x282925de),LL(0xe74a242a,0xfe0ffffb), + LL(0x906151e5,0x3f39e67f),LL(0x55e10649,0xcea27f5f),LL(0xc17cf7b7,0xdca1d4e1),LL(0x2fe2362d,0x0c326d12), LL(0x7dd35df3,0x05f7ac33),LL(0xc396dbdf,0x0c3b7639),LL(0x03b7db1c,0x0912f5ac),LL(0x5c9ed4a9,0x9dea4b70), + LL(0xaae3f639,0x475e6e53),LL(0xfc278bac,0xfaba0e7c),LL(0x9490375f,0x16f9e221),LL(0xa5a7ed0a,0xaebf9746), LL(0xf41ad5d6,0x45f9af3f),LL(0xb2e99224,0x03c4623c),LL(0xb3cf56aa,0x82c5bb5c),LL(0x34567ed3,0x64311819), + LL(0x8be489ac,0xec57f211),LL(0xb9a1104b,0x2821895d),LL(0x6064e007,0x610dc875),LL(0x5b20d0fe,0x8e526f3f), LL(0x5b645aee,0x6e71ca77),LL(0x800e10ff,0x3d1dcb9f),LL(0x189cf6de,0x36b51162),LL(0x6bb17353,0x2c5a3e30), + LL(0x2a6c6fbf,0xc186cd3e),LL(0x4bf97906,0xa74516fa),LL(0x279d6901,0x5b4b8f4b),LL(0x2b573743,0x0c4e57b4), LL(0xb6e386b6,0x75fdb229),LL(0x99deac27,0xb46793fd),LL(0xcf712629,0xeeec47ea),LL(0xcbc3b2dd,0xe965f3c4), + LL(0x425c6559,0x8dd1fb83),LL(0x0af06fda,0x7fc00ee6),LL(0x33d956df,0xe98c9225),LL(0x4fbdc8a2,0x0f1ef335), LL(0xb79b8ea2,0x2abb5145),LL(0xbdbff288,0x40fd2945),LL(0xd7185db7,0x6a814ac4),LL(0xc084609a,0xc4329d6f), + LL(0xed1be45d,0xc9ba7b52),LL(0xe4cd2c74,0x891dd20d),LL(0x824139b1,0x5a4d4a7f),LL(0xb873c710,0x66c17716), LL(0x2843c4e0,0x5e5bc141),LL(0xb97eb5bf,0xd5ac4817),LL(0x450c95c7,0xc0f8af54),LL(0x318406c5,0xc91b3fa0), + LL(0xab9d97f8,0x360c340a),LL(0x90a2d611,0xfb57bd07),LL(0xa6a6f7e5,0x4339ae3c),LL(0x2feb8a10,0x9c1fcd2a), LL(0xc7ea7432,0x972bcca9),LL(0x308076f6,0x1b0b924c),LL(0x2a5b4ca5,0x80b2814a),LL(0x61ef3b29,0x2f78f55b), + LL(0xc18a414f,0xf838744a),LL(0x903d0a86,0xc611eaae),LL(0x2a453f55,0x94dabc16),LL(0x14efb279,0xe6f2e3da), LL(0x9320dc3c,0x5b7a6017),LL(0x8df6b5a4,0x692e382f),LL(0x2d40fa90,0x3f5e15e0),LL(0x643dd318,0xc87883ae), + LL(0x53544774,0x511053e4),LL(0x3adba2bc,0x834d0ecc),LL(0xbae371f5,0x4215d7f7),LL(0x6c8663bc,0xfcfd57bf), LL(0xd6901b1d,0xded2383d),LL(0xb5587dc3,0x3b49fbb4),LL(0x07625f62,0xfd44a08d),LL(0x9de9b762,0x3ee4d65b), +}, +/* digit=27 base_pwr=2^189 */ +{ + LL(0x0d63d1fa,0x64e5137d),LL(0x02a9d89f,0x658fc052),LL(0x50436309,0x48894874),LL(0xd598da61,0xe9ae30f8), LL(0x818baf91,0x2ed710d1),LL(0x8b6a0c20,0xe27e9e06),LL(0x1c1a6b44,0x1e28dcfb),LL(0xd6ac57dc,0x883acb64), + LL(0xc2c6ff70,0x8735728d),LL(0xc5dc2235,0x79d6122f),LL(0x19e277f9,0x23f5d003),LL(0xdded8cc7,0x7ee84e25), LL(0x63cd880a,0x91a8afb0),LL(0x3574af60,0x3f3ea7c6),LL(0x02de7f42,0x0cfcdc84),LL(0xb31aa152,0x62d0792f), + LL(0x8a5807ce,0x8e1b4e43),LL(0xe4109a7e,0xad283893),LL(0xafd59dda,0xc30cc9cb),LL(0x3d8d8093,0xf65f36c6), LL(0xa60d32b2,0xdf31469e),LL(0x3e8191c8,0xee93df4b),LL(0x355bdeb5,0x9c1017c5),LL(0x8616aa28,0xd2623185), + LL(0xdec31a21,0xb02c83f9),LL(0x6ad9d573,0x988c8b23),LL(0xa57be365,0x53e983ae),LL(0x646f834e,0xe968734d), LL(0x5da6309b,0x9137ea8f),LL(0xc1f1ce16,0x10f3a624),LL(0xca440921,0x782a9ea2),LL(0x5b46f1b5,0xdf94739e), + LL(0xcce85c9b,0x9f9be006),LL(0xa4c7c2d3,0x360e70d6),LL(0xaefa1e60,0x2cd5beea),LL(0x8c3d2b6d,0x64cf63c0), LL(0xe1cf6f90,0xfb107fa3),LL(0xd5e044e6,0xb7e937c6),LL(0xce34db9f,0x74e8ca78),LL(0x3e210bd0,0x4f8b36c1), + LL(0x34a35ea8,0x1df165a4),LL(0x4d4412f6,0x3418e0f7),LL(0x518836c3,0x5af1f8af),LL(0x130e1965,0x42ceef4d), LL(0x543a1957,0x5560ca0b),LL(0x886cb123,0xc33761e5),LL(0xfe98ed30,0x66624b1f),LL(0x1090997d,0xf772f4bf), + LL(0x4885d410,0xf4e540bb),LL(0x9ba5f8d7,0x7287f810),LL(0xde98dfb1,0x22d0d865),LL(0xbcfbb8a3,0x49ff51a1), LL(0x6bc3012e,0xb6b6fa53),LL(0x170d541d,0x3d31fd72),LL(0x4b0f4966,0x8018724f),LL(0x87dbde07,0x79e7399f), + LL(0xf4f8b16a,0x56f8410e),LL(0xc47b266a,0x97241afe),LL(0x6d9c87c1,0x0a406b8e),LL(0xcd42ab1b,0x803f3e02), LL(0x04dbec69,0x7f0309a8),LL(0x3bbad05f,0xa83b85f7),LL(0xad8e197f,0xc6097273),LL(0x5067adc1,0xc097440e), + LL(0x3524ff16,0x730eafb6),LL(0x823fc6ce,0xd7f9b51e),LL(0x443e4ac0,0x27bd0d32),LL(0x4d66f217,0x40c59ad9), LL(0x17c387a4,0x6c33136f),LL(0xeb86804d,0x5043b8d5),LL(0x675a73c9,0x74970312),LL(0xf16669b6,0x838fdb31), + LL(0x418e7ddd,0xc507b6dd),LL(0x472f19d6,0x39888d93),LL(0x0c27eb4d,0x7eae26be),LL(0xfbabb884,0x17b53ed3), LL(0x2b01ae4f,0xfc27021b),LL(0xcf488682,0x88462e87),LL(0x215e2d87,0xbee096ec),LL(0xd242e29b,0xeb2fea9a), + LL(0xb821fc28,0x5d985b5f),LL(0xdc1e2ad2,0x89d2e197),LL(0x9030ba62,0x55b566b8),LL(0x4f41b1c6,0xe3fd41b5), LL(0xb9a96d61,0xb738ac2e),LL(0x369443f4,0x7f8567ca),LL(0xf803a440,0x8698622d),LL(0x8fe2f4dc,0x2b586236), + LL(0x56b95bce,0xbbcc00c7),LL(0x616da680,0x5ec03906),LL(0x72214252,0x79162ee6),LL(0x86a892d2,0x43132b63), LL(0x2f3263bf,0x4bdd3ff2),LL(0x9cd0a142,0xd5b3733c),LL(0x44415ccb,0x592eaa82),LL(0x8d5474ea,0x663e8924), + LL(0x5236344e,0x8058a25e),LL(0xbda76ee6,0x82e8df9d),LL(0x11cc3d22,0xdcf6efd8),LL(0x3b4ab529,0x00089cda), LL(0xbd38a3db,0x91d3a071),LL(0xef72b925,0x4ea97fc0),LL(0xea3edf75,0x0c9fc15b),LL(0xa4348ed3,0x5a6297cd), + LL(0xce7c42d4,0x0d38ab35),LL(0x82feab10,0x9fd493ef),LL(0x82111b45,0x46056b6d),LL(0x73efc5c3,0xda11dae1), LL(0x5545a7fb,0xdc740278),LL(0x40d507e6,0xbdb2601c),LL(0x7066fa58,0x121dfeeb),LL(0x39ae8c2a,0x214369a8), + LL(0x06e0956c,0x195709cb),LL(0x010cd34b,0x4c9d254f),LL(0x0471a532,0xf51e13f7),LL(0x1e73054d,0xe19d6791), LL(0xdb5c7be3,0xf702a628),LL(0xb24dde05,0xc7141218),LL(0xf29b2e2e,0xdc18233c),LL(0x85342dba,0x3a6bd1e8), + LL(0xb311898c,0x3f747fa0),LL(0xcd0eac65,0xe2a272e4),LL(0xf914d0bc,0x4bba5851),LL(0xc4a43ee3,0x7a1a9660), LL(0xa1c8cde9,0xe5a367ce),LL(0x7271abe3,0x9d958ba9),LL(0x3d1615cd,0xf3ff7eb6),LL(0xf5ae20b0,0xa2280dce), + LL(0xcf640147,0x56dba5c1),LL(0x5e83d118,0xea5a2e3d),LL(0xda24c511,0x04cd6b6d),LL(0xe854d214,0x1c0f4671), LL(0x69565381,0x91a6b7a9),LL(0xdecf1f5b,0xdc966240),LL(0xfcf5d009,0x1b22d21c),LL(0x9021dbd5,0x2a05f641), + LL(0xd4312483,0x8c0ed566),LL(0x643e216f,0x5179a95d),LL(0x17044493,0xcc185fec),LL(0x54991a21,0xb3063339), LL(0x0081a726,0xd801ecdb),LL(0x4fa89bbb,0x0149b0c6),LL(0x4391b6b9,0xafe9065a),LL(0xd633f3a3,0xedc92786), + LL(0xae6a8e13,0xe408c24a),LL(0x9f3897ab,0x85833fde),LL(0xd81a0715,0x43800e7e),LL(0xb44ffc5f,0xde08e346), LL(0xcdeff2e0,0x7094184c),LL(0x165eaed1,0x49f9387b),LL(0x777c468a,0x635d6129),LL(0x538c2dd8,0x8c0dcfd1), + LL(0x7a6a308b,0xd6d9d9e3),LL(0x4c2767d3,0x62375830),LL(0xf38cbeb6,0x874a8bc6),LL(0xccb6fd9e,0xd94d3f1a), LL(0xba21f248,0x92a9735b),LL(0x6cd1efb0,0x272ad0e5),LL(0x05b03284,0x7437b69c),LL(0x6948c225,0xe7f04702), + LL(0xcba2ecec,0x8a56c04a),LL(0xe3a73e41,0x0c181270),LL(0x03e93725,0x6cb34e9d),LL(0x496521a9,0xf77c8713), LL(0xfa7f9f90,0x94569183),LL(0x8c9707ad,0xf2e7aa4c),LL(0x26c1c9a3,0xced2c9ba),LL(0x40197507,0x9109fe96), + LL(0xe9adfe1c,0x9ae868a9),LL(0x314e39bb,0x3984403d),LL(0xf2fe378f,0xb5875720),LL(0xba44a628,0x33f901e0), LL(0x3652438c,0xea1125fe),LL(0x9dd1f20b,0xae9ec4e6),LL(0xbebf7fbd,0x1e740d9e),LL(0x42dbe79c,0x6dbd3ddc), + LL(0xedd36776,0x62082aec),LL(0xe9859039,0xf612c478),LL(0x032f7065,0xa493b201),LL(0x4ff9b211,0xebd4d8f2), LL(0xaac4cb32,0x3f23a0aa),LL(0x15ed4005,0xea3aadb7),LL(0xafa27e63,0xacf17ea4),LL(0xc11fd66c,0x56125c1a), + LL(0x3794f8dc,0x266344a4),LL(0x483c5c36,0xdcca923a),LL(0x3f9d10a0,0x2d6b6bbf),LL(0x81d9bdf3,0xb320c5ca), LL(0x47b50a95,0x620e28ff),LL(0xcef03371,0x933e3b01),LL(0x99100153,0xf081bf85),LL(0xc3a8c8d6,0x183be9a0), + LL(0xd6bbe24d,0x4e3ddc5a),LL(0x53843795,0xc6c74630),LL(0x65ec2d4c,0x78193dd7),LL(0xcd3c89b2,0xb8df26cc), LL(0x5a483f8d,0x98dbe399),LL(0x7dd3313a,0x72d8a957),LL(0xab0bd375,0x65087294),LL(0x7c259d16,0xfcd89248), + LL(0x7613aa81,0x8a9443d7),LL(0x85fe6584,0x80100800),LL(0x7fb10288,0x70fc4dbc),LL(0xe86beee8,0xf58280d3), LL(0x7c978c38,0x14fdd82f),LL(0x0de44d7b,0xdf1204c1),LL(0x4160252f,0xa08a1c84),LL(0xc17646a5,0x591554ca), + LL(0xa05bd525,0x214a37d6),LL(0x07957b3c,0x48d5f09b),LL(0xd7109bc9,0x0247cdcb),LL(0x30599ce7,0x40f9e4bb), LL(0xf46ad2ec,0xc325fa03),LL(0xc3e3f9ee,0x00f766cf),LL(0xd43a4577,0xab556668),LL(0x3ee03b93,0x68d30a61), + LL(0x77b46a08,0x7ddc81ea),LL(0xc7480699,0xcf5a6477),LL(0x6633f683,0x43a8cb34),LL(0x92363c60,0x1b867e6b), LL(0x1f60558e,0x43921114),LL(0x2f41450e,0xcdbcdd63),LL(0xcc630e8b,0x7fc04601),LL(0x97038b43,0xea7c66d5), + LL(0x04e99fd8,0x7259b8a5),LL(0x4785549a,0x98a8dd12),LL(0x840552e1,0x0e459a7c),LL(0x4bb0909e,0xcdfcf4d0), LL(0x53758da7,0x34a86db2),LL(0xeac997e1,0xe643bb83),LL(0x530c5b7e,0x96400bd7),LL(0xb41c8b52,0x9f97af87), + LL(0xfbeee3f9,0x34fc8820),LL(0x49091afd,0x93e53490),LL(0x9a31f35c,0x764b9be5),LL(0x57e3d924,0x71f37864), LL(0x943aa75e,0x02fb34e0),LL(0xab8ff6e4,0xa18c9c58),LL(0x33cf0d19,0x080f31b1),LL(0x083518a7,0x5c9682db), + LL(0xb709c3de,0x873d4ca6),LL(0x3575b8f0,0x64a84262),LL(0x020154bb,0x6275da1f),LL(0xd17cf1ab,0x97678caa), LL(0x951a95c3,0x8779795f),LL(0x50fccc08,0xdd35b163),LL(0x33d8f031,0x32709627),LL(0x498dd85c,0x3c5ab10a), + LL(0x41dca566,0xb6c185c3),LL(0xd8622aa3,0x7de7feda),LL(0x901b6dfb,0x99e84d92),LL(0x7c4ad288,0x30a02b0e), LL(0x2fd3cf36,0xc7c81daa),LL(0xdf89e59f,0xd1319547),LL(0xcd496733,0xb2be8184),LL(0x93d3412b,0xd5f449eb), + LL(0x25fe531d,0x7ea41b1b),LL(0x6a1d5646,0xf9797432),LL(0x2bde501a,0x86067f72),LL(0x0c85e89c,0xf91481c0), LL(0xf8b05bc6,0xca8ee465),LL(0x02e83cda,0x1844e1cf),LL(0xb4dbe33b,0xca82114a),LL(0x4eabfde2,0x0f9f8769), + LL(0x38b27fe2,0x4936b1c0),LL(0xaba402df,0x63b6359b),LL(0x656bdbab,0x40c0ea2f),LL(0x6580c39c,0x9c992a89), LL(0x2a60aed1,0x600e8f15),LL(0xe0bf49df,0xeb089ca4),LL(0x2d42d99a,0x9c233d7d),LL(0x4c6bc2fa,0x648d3f95), + LL(0xe1add3f3,0xdcc383a8),LL(0x4f64a348,0xf42c0c6a),LL(0x0030dbdb,0x2abd176f),LL(0x7d6c215e,0x4de501a3), LL(0x4b9a64bc,0x4a107c1f),LL(0x2496cd59,0xa77f0ad3),LL(0x7688dffb,0xfb78ac62),LL(0x67937d8e,0x7025a2ca), + LL(0xd1a8f4e7,0xfde8b2d1),LL(0x7354927c,0xf5b3da47),LL(0xd9205735,0xe48606a3),LL(0xe177b917,0xac477cc6), LL(0xa883239a,0xfb1f73d2),LL(0xcc8b8357,0xe12572f6),LL(0xfb1f4f86,0x9d355e9c),LL(0xd9f3ec6e,0x89b795f8), + LL(0xb54398dc,0x27be56f1),LL(0x3fedeed5,0x1890efd7),LL(0x9c6d0140,0x62f77f1f),LL(0x596f0ee4,0x7ef0e314), LL(0xcc61dab3,0x50ca6631),LL(0xf4866e4f,0x4a39801d),LL(0xae363b39,0x66c8d032),LL(0x2ead66aa,0x22c591e5), + LL(0xde02a53e,0x954ba308),LL(0xd389f357,0x2a6c060f),LL(0xfbf40b66,0xe6cfcde8),LL(0xc6340ce1,0x8e02fc56), LL(0x73adb4ba,0xe4957795),LL(0xa7b03805,0x7b86122c),LL(0x0c8e6fa6,0x63f83512),LL(0x057d7804,0x83660ea0), + LL(0x21ba473c,0xbad79105),LL(0xded5389d,0xb6c50bee),LL(0xaa7c9bc0,0xee2caf4d),LL(0x8c4e98a7,0xd97b8de4), LL(0xab3bbddb,0xa9f63e70),LL(0x2597815a,0x3898aabf),LL(0xac15b3d9,0x7659af89),LL(0x703ce784,0xedf7725b), + LL(0xe085116b,0x25470fab),LL(0x87285310,0x04a43375),LL(0xe2bfd52f,0x4e39187e),LL(0x7d9ebc74,0x36166b44), LL(0xfd4b322c,0x92ad433c),LL(0xba79ab51,0x726aa817),LL(0xc1db15eb,0xf96eacd8),LL(0x0476be63,0xfaf71e91), + LL(0x641fad98,0xdd69a640),LL(0x29622559,0xb7995918),LL(0xde4199dc,0x03c6daa5),LL(0xad545eb4,0x92cadc97), LL(0x256534e4,0x1028238b),LL(0x8595409a,0x73e80ce6),LL(0xd05dc59b,0x690d4c66),LL(0x981dee80,0xc95f7b8f), + LL(0xd856ac25,0xf4337014),LL(0xac524dca,0x441bd9dd),LL(0x5f0499f5,0x640b3d85),LL(0xd5fda182,0x39cf84a9), LL(0xb2aa95a0,0x04e7b055),LL(0x0ddf1860,0x29e33f0a),LL(0x423f6b43,0x082e74b5),LL(0x0aaa2b0f,0x217edeb9), + LL(0x83cbea55,0x58b83f35),LL(0xbc185d70,0xc485ee4d),LL(0x1e5f6992,0x833ff03b),LL(0xcf0c0dd5,0xb5b9b9cc), LL(0x4e9e8a50,0x7caaee8e),LL(0x6269dafd,0x462e907b),LL(0xfbe791c6,0x6ed5cee9),LL(0xed430790,0x68ca3259), + LL(0x13b5ba88,0x2b72bdf2),LL(0x35ef0ac4,0x60294c8a),LL(0x19b99b08,0x9c3230ed),LL(0x6c2589aa,0x560fff17), LL(0xd6770374,0x552b8487),LL(0x9a56f685,0xa373202d),LL(0x45f175d9,0xd3e7f907),LL(0xd080d810,0x3c2f315f), + LL(0x7b9520e8,0x1130e9dd),LL(0x0af037b5,0xc078f9e2),LL(0x1e9c104c,0x38cd2ec7),LL(0xc472fe92,0x0f684368), LL(0x6247e7ef,0xd3f1b5ed),LL(0x396dfe21,0xb32d33a9),LL(0x4a9aa2c2,0x46f59cf4),LL(0xff0f7e41,0x69cd5168), + LL(0x4b3234da,0x3f59da0f),LL(0xb4579ebe,0xcf0b0235),LL(0x6d2476c7,0x6d1cbb25),LL(0x9dc30f08,0x4f0837e6), LL(0x906f6e98,0x9a4075bb),LL(0xc761e7d1,0x253bb434),LL(0x6e73af10,0xde2e645f),LL(0x0c5f131c,0xb89a4060), + LL(0xb8cc037f,0xd12840c5),LL(0x7405bb47,0x3d093a5b),LL(0x206348b8,0x6202c253),LL(0xc55a3ca7,0xbf5d57fc), LL(0x8c3bef48,0x89f6c90c),LL(0x5a0a960a,0x23ac7623),LL(0x552b42ab,0xdfbd3d6b),LL(0x132061f6,0x3ef22458), + LL(0xc97e6516,0xd74e9bda),LL(0xc230f49e,0x88779360),LL(0x1e74ea49,0xa6ec1de3),LL(0x3fb645a2,0x581dcee5), LL(0x8f483f14,0xbaef2391),LL(0xd137d13b,0x6d2dddfc),LL(0xd2743a42,0x54cde50e),LL(0xe4d97e67,0x89a34fc5), + LL(0x12e08ce5,0x13f1f5b3),LL(0xa7f0b2ca,0xa80540b8),LL(0x01982805,0x854bcf77),LL(0x233bea04,0xb8653ffd), LL(0x02b0b4c9,0x8e7b8787),LL(0x9acb170a,0x2675261f),LL(0x930c14e5,0x061a9d90),LL(0xdef0abea,0xb59b30e0), + LL(0x0200ec7d,0x1dc19ea6),LL(0x0bce132b,0xb6f4a3f9),LL(0xf13e27e0,0xb8d5de90),LL(0x1fade16f,0xbaee5ef0), LL(0xe4c6cf38,0x6f406aaa),LL(0xd1369815,0xab4cfe06),LL(0xefd550c6,0x0dcffe87),LL(0x75ff7d39,0x9d4f59c7), + LL(0x51deb6ad,0xb02553b1),LL(0xb1877749,0x812399a4),LL(0xca6006e1,0xce90f71f),LL(0xb02b6e77,0xc32363a6), LL(0xdc36c64d,0x02284fbe),LL(0xa7e1ae61,0x86c81e31),LL(0xb909d94a,0x2576c7e5),LL(0x818b2bb0,0x8b6f7d02), + LL(0x56faa38a,0xeca3ed07),LL(0x9305bb54,0xa3790e6c),LL(0x7bc73061,0xd784eeda),LL(0x6dd50614,0xbd56d369), LL(0x229a8aa9,0xd6575949),LL(0x4595ec28,0xdcca8f47),LL(0x06ab4fe6,0x814305c1),LL(0x24f43f16,0xc8c39768), + LL(0x523f2b36,0xe2a45f36),LL(0x920d93bb,0x995c6493),LL(0x90f1632b,0xf8afdab7),LL(0x1c295954,0x79ebbecd), LL(0x79592f48,0xc7bb3ddb),LL(0x5f88e998,0x67216a7b),LL(0xbc01193e,0xd91f098b),LL(0xb1db83fc,0xf7d928a5), + LL(0xe991f600,0x55e38417),LL(0x2981a934,0x2a91113e),LL(0x06b13bde,0xcbc9d648),LL(0x0755ff44,0xb011b6ac), LL(0x045ec613,0x6f4cb518),LL(0xc2f5930a,0x522d2d31),LL(0x382e65de,0x5acae1af),LL(0x27bc966f,0x57643067), + LL(0x1c7193f0,0x5e12705d),LL(0x3be8858e,0xf0f32f47),LL(0x96c6dfc7,0x785c3d7d),LL(0xbf31795d,0xd75b4a20), LL(0x342659d4,0x91acf17b),LL(0x44f0378f,0xe596ea34),LL(0xce52129d,0x4515708f),LL(0x79f2f585,0x17387e1e), + LL(0x49dee168,0x72cfd2e9),LL(0x3e2af239,0x1ae05223),LL(0x1d94066a,0x009e75be),LL(0x38abf413,0x6cca31c7), LL(0x9bc49908,0xb50bd61d),LL(0xf5e2bc1e,0x4a9b4a8c),LL(0x946f83ac,0xeb6cc5f7),LL(0xebffab28,0x27da93fc), + LL(0x4821c8c5,0xea314c96),LL(0xa83c15f4,0x8de49ded),LL(0x7af33004,0x7a64cf20),LL(0xc9627e10,0x45f1bfeb), LL(0x54b9df60,0x878b0626),LL(0xa95c0b33,0x5e4fdc3c),LL(0xc2035d8e,0xe54a37ca),LL(0x80f20b8c,0x9087cda9), + LL(0x8319ade4,0x36f61c23),LL(0xde8cfdf8,0x766f287a),LL(0x346f3705,0x48821948),LL(0x16e4f4a2,0x49a7b853), LL(0x5cedadfd,0xb9b3f8a7),LL(0x8db2a815,0x8f562815),LL(0x01f68f95,0xc0b7d554),LL(0x688a208e,0x12971e27), + LL(0xd0ff34fc,0xc9f8b696),LL(0x1222718c,0x20824de2),LL(0x0c95284d,0x7213cf9f),LL(0xdc158240,0xe2ad741b), LL(0x54043ccf,0x0ee3a6df),LL(0xd84412b3,0x16ff479b),LL(0xdfc98af0,0xf6c74ee0),LL(0x52fcd2fb,0xa78a169f), + LL(0x99c930e9,0xd8ae8746),LL(0x49e117a5,0x1d33e858),LL(0x6624759f,0x7581fcb4),LL(0x5bedc01d,0xde50644f), LL(0xcaf3155e,0xbeec5d00),LL(0xbc73e75f,0x672d66ac),LL(0x270b01db,0x86b9d8c6),LL(0x50f55b79,0xd249ef83), + LL(0x73978fe3,0x6131d6d4),LL(0x754b00a1,0xcc4e4542),LL(0x57dfcfe9,0x4e05df05),LL(0x51ef6bf0,0x94b29cdd), LL(0x9bc7edf2,0xe4530cff),LL(0xd3da65f3,0x8ac236fd),LL(0xc8eb0b48,0x0faf7d5f),LL(0x660eb039,0x4d2de14c), + LL(0x60430e54,0xc006bba7),LL(0xda3289ab,0x10a2d0d6),LL(0xd7979c59,0x9c037a5d),LL(0xa116d944,0x04d1f3d3), LL(0x8a0983cd,0x9ff22473),LL(0xc883cabb,0x28e25b38),LL(0x47a58995,0xe968dba5),LL(0x774eebdf,0x2c80b505), + LL(0x4a953beb,0xee763b71),LL(0x1642e7f6,0x502e223f),LL(0x61d5e722,0x6fe4b641),LL(0xdbef5316,0x9d37c5b0), LL(0xf8330bc7,0x0115ed70),LL(0x75a72789,0x139850e6),LL(0xffceccc2,0x27d7faec),LL(0x4fd9f7f6,0x3016a860), + LL(0x4cd8f64c,0xc492ec64),LL(0x279d7b51,0x58a2d790),LL(0x1fc75256,0x0ced1fc5),LL(0x8f433017,0x3e658aed), LL(0x05da59eb,0x0b61942e),LL(0x0ddc3722,0xba3d60a3),LL(0x742e7f87,0x7c311cd1),LL(0xf6b01b6e,0x6473ffee), +}, +/* digit=28 base_pwr=2^196 */ +{ + LL(0x692ac542,0x8303604f),LL(0x227b91d3,0xf079ffe1),LL(0x15aaf9bd,0x19f63e63),LL(0xf1f344fb,0xf99ee565), LL(0xd6219199,0x8a1d661f),LL(0xd48ce41c,0x8c883bc6),LL(0x3c74d904,0x1065118f),LL(0x0faf8b1b,0x713889ee), + LL(0x81a1b3be,0x972b3f8f),LL(0xce2764a0,0x4f3ce145),LL(0x28c4f5f7,0xe2d0f1cc),LL(0xc7f3985b,0xdeee0c0d), LL(0xd39e25c3,0x7df4adc0),LL(0xc467a080,0x40619820),LL(0x61cf5a58,0x440ebc93),LL(0x422ad600,0x527729a6), + LL(0xb1b76ba6,0xca6c0937),LL(0x4d2026dc,0x1a2eab85),LL(0x19d9ae0a,0xb1715e15),LL(0xbac4a026,0xf1ad9199), LL(0x07ea7b0e,0x35b3dfb8),LL(0x3ed9eb89,0xedf5496f),LL(0x2d6d08ab,0x8932e5ff),LL(0x25bd2731,0xf314874e), + LL(0x3f73f449,0xefb26a75),LL(0x8d44fc79,0x1d1c94f8),LL(0x3bc0dc4d,0x49f0fbc5),LL(0x3698a0d0,0xb747ea0b), LL(0x228d291e,0x5218c3fe),LL(0x43c129d6,0x35b804b5),LL(0xd1acc516,0xfac859b8),LL(0x95d6e668,0x6c10697d), + LL(0x0876fd4e,0xc38e438f),LL(0x83d2f383,0x45f0c307),LL(0xb10934cb,0x203cc2ec),LL(0x2c9d46ee,0x6a8f2439), LL(0x65ccde7b,0xf16b431b),LL(0x27e76a6f,0x41e2cd18),LL(0x4e3484d7,0xb9c8cf8f),LL(0x8315244a,0x64426efd), + LL(0xfc94dea3,0x1c0a8e44),LL(0xdad6a0b0,0x34c8cdbf),LL(0x04113cef,0x919c3840),LL(0x15490ffa,0xfd32fba4), LL(0x795dcfb7,0x58d190f6),LL(0x83588baf,0xfef01b03),LL(0xca1fc1c0,0x9e6d1d63),LL(0xf0a41ac9,0x53173f96), + LL(0xba16f73b,0x2b1d402a),LL(0x8cf9b9fc,0x2fb31014),LL(0x446ef7bf,0x2d51e60e),LL(0xb91e1745,0xc731021b), LL(0x4fee99d4,0x9d3b4724),LL(0xfac5c1ea,0x4bca48b6),LL(0xbbea9af7,0x70f5f514),LL(0x974c283a,0x751f55a5), + LL(0xcb452fdb,0x6e30251a),LL(0x50f30650,0x31ee6965),LL(0x933548d9,0xb0b3e508),LL(0xf4b0ef5b,0xb8949a4f), LL(0x3c88f3bd,0x208b8326),LL(0xdb1d9989,0xab147c30),LL(0x44d4df03,0xed6515fd),LL(0xe72eb0c5,0x17a12f75), + LL(0x36cf69db,0x3b59796d),LL(0x56670c18,0x1219eee9),LL(0x7a070d8e,0xfe3341f7),LL(0xa327f90c,0x9b70130b), LL(0x0ae18e0e,0x36a32462),LL(0x46c0a638,0x2021a623),LL(0xc62eb0d4,0x251b5817),LL(0x4c762293,0x87bfbcdf), + LL(0xcdd61d64,0xf78ab505),LL(0xc8c18857,0x8c7a53fc),LL(0x16147515,0xa653ce6f),LL(0xea7d52d5,0x9c923aa5), LL(0x5c18871f,0xc24709cb),LL(0x73b3cc74,0x7d53bec8),LL(0xfdd1d4c4,0x59264aff),LL(0x240da582,0x5555917e), + LL(0x548f5a0e,0xcae8bbda),LL(0x3bbfbbe1,0x1910eaba),LL(0x7677afc3,0xae579685),LL(0x73ff0b5c,0x49ea61f1), LL(0x4f7c3922,0x78655478),LL(0x20c68eef,0x95d337cd),LL(0xdf779ab9,0x68f1e1e5),LL(0xb5cf69a8,0x14b491b0), + LL(0x28e3fe89,0x7a6cbbe0),LL(0xc5aac0eb,0xe7e1fee4),LL(0x697e5140,0x7f47eda5),LL(0xb454921f,0x4f450137), LL(0x95cd8185,0xdb625f84),LL(0xcdb2e583,0x74be0ba1),LL(0xdd5e6de4,0xaee4fd7c),LL(0xe8101739,0x4251437d), + LL(0xac620366,0x686d72a0),LL(0xb6d59344,0x4be3fb9c),LL(0xa1eb75b9,0x6e8b44e7),LL(0x91a5c10c,0x84e39da3), LL(0xb38f0409,0x37cc1490),LL(0x2c2ade82,0x02951943),LL(0x1190a2d8,0x9b688783),LL(0x231182ba,0x25627d14), + LL(0x658a6d87,0x6eb550aa),LL(0xcf9c7325,0x1405aaa7),LL(0x5c8748c9,0xd147142e),LL(0x53ede0e0,0x7f637e4f), LL(0x14ffad2c,0xf8ca2776),LL(0xbafb6791,0xe58fb1bd),LL(0xbf8f93fc,0x17158c23),LL(0x0a4a4655,0x7f15b373), + LL(0xd842ca72,0x39d4add2),LL(0x3ed96305,0xa71e4391),LL(0x6700be14,0x5bb09cbe),LL(0xd8befcf6,0x68d69d54), LL(0x37183bcf,0xa45f5367),LL(0x3370dff7,0x7152b7bb),LL(0xbf12525b,0xcf887baa),LL(0xd6d1e3cd,0xe7ac7bdd), + LL(0x81fdad90,0x25914f78),LL(0x0d2cf6ab,0xcf638f56),LL(0xcc054de5,0xb90bc03f),LL(0x18b06350,0x932811a7), LL(0x9bbd11ff,0x2f00b330),LL(0xb4044974,0x76108a6f),LL(0xa851d266,0x801bb9e0),LL(0xbf8990c1,0x0dd099be), + LL(0xabe32986,0x58c5aaaa),LL(0x50d59c27,0x0fe9dd2a),LL(0x8d307305,0x84951ff4),LL(0x86529b78,0x6c23f829), LL(0x0b136a79,0x50bb2218),LL(0x77a20996,0x7e2174de),LL(0xc0bb4da6,0x6f00a4b9),LL(0xefdde8da,0x89a25a17), + LL(0xc11ee01d,0xf728a27e),LL(0xe5f10dfb,0xf900553a),LL(0x02ec893c,0x189a83c8),LL(0x23f66d77,0x3ca5bdc1), LL(0x97eada9f,0x98781537),LL(0x10256230,0x59c50ab3),LL(0x323c69b3,0x346042d9),LL(0x2c460449,0x1b715a6d), + LL(0x6ae06e0b,0xa41dd476),LL(0x9d42e25f,0xcdd7888e),LL(0x56b25a20,0x0f395f74),LL(0x8700e27e,0xeadfe0ae), LL(0x69950093,0xb09d52a9),LL(0x327f8d40,0x3525d9cb),LL(0x67df886a,0xb8235a94),LL(0x035faec2,0x77e4b0dd), + LL(0x517d7061,0x115eb20a),LL(0x6c2df683,0x77fe3433),LL(0xcdc6fc67,0x6870ddc7),LL(0x0b87de83,0xb1610588), LL(0xd9c4ddbe,0x343584ca),LL(0x3d754be2,0xb3164f1c),LL(0xc1e6c894,0x0731ed3a),LL(0x4f6b904c,0x26327dec), + LL(0x97b5cd32,0x9d49c6de),LL(0xb5eceecd,0x40835dae),LL(0xd9ded7fe,0xc66350ed),LL(0x7a678804,0x8aeebb5c), LL(0x5b8ee9ec,0x51d42fb7),LL(0x8e3ca118,0xd7a17bdd),LL(0x2ef4400e,0x40d7511a),LL(0x875a66f4,0xc48990ac), + LL(0x2199e347,0x8de07d2a),LL(0x2a39e051,0xbee75556),LL(0x916e51dc,0x56918786),LL(0x4a2d89ec,0xeb191313), LL(0x37d341ed,0x6679610d),LL(0x56d51c2b,0x434fbb41),LL(0xd7492dba,0xe54b7ee7),LL(0x59021493,0xaa33a79a), + LL(0xe4bd6d3d,0x49fc5054),LL(0x5ab551d0,0x09540f04),LL(0x4942d3a6,0x8acc9085),LL(0x2d28323b,0x231af02f), LL(0x0992c163,0x93458cac),LL(0x888e3bb4,0x1fef8e71),LL(0xbe8c268c,0x27578da5),LL(0xe805ec00,0xcc8be792), + LL(0xc61c3855,0x29267bae),LL(0x58c1fd3b,0xebff429d),LL(0x8c0b93b8,0x22d886c0),LL(0x2ddb8953,0xca5e00b2), LL(0xc3fed8b7,0xcf330117),LL(0x819c01f6,0xd49ac6fa),LL(0x3c0fbd54,0x6ddaa6bd),LL(0x8049a2cf,0x91743068), + LL(0xaff2ef81,0xd67f981e),LL(0x2818ae80,0xc3654d35),LL(0x1b2aa892,0x81d05044),LL(0x3d099328,0x2db067bf), LL(0x703dcc97,0xe7c79e86),LL(0xe133e215,0xe66f9b37),LL(0xe39a7a5c,0xcdf119a6),LL(0x876f1b61,0x47c60de3), + LL(0xd860f1b2,0x6e405939),LL(0xf5ed4d4a,0x3e9a1dbc),LL(0xc9b6bcbd,0x3f23619e),LL(0x734e4497,0x5ee790cf), LL(0x5bdaf9bb,0xf0a834b1),LL(0x4ca295f0,0x02cedda7),LL(0xcb8e378c,0x4619aa2b),LL(0xcc987ea4,0xe5613244), + LL(0x76b23a50,0x0bc022cc),LL(0x0a6c21ce,0x4a2793ad),LL(0x89cac3f5,0x38328780),LL(0xcba26d56,0x29176f1b), LL(0x4f6f59eb,0x06296187),LL(0x8bdc658e,0x86e9bca9),LL(0x57e30402,0x2ca9c4d3),LL(0x516a09bb,0x5438b216), + LL(0x7672765a,0x0a6a063c),LL(0x0547b9bf,0x37a3ce64),LL(0x98b1a633,0x42c099c8),LL(0x05ee6961,0xb5ab800d), LL(0x11a5acd6,0xf1963f59),LL(0x46201063,0xbaee6157),LL(0xa596210a,0x36d9a649),LL(0x1ba7138c,0xaed04363), + LL(0xa4a82b76,0xcf817d1c),LL(0xf3806be9,0x5586960e),LL(0x09dc6bb5,0x7ab67c89),LL(0x114fe7eb,0x52ace7a0), LL(0xcbbc9b70,0xcd987618),LL(0x604ca5e1,0x4f06fd5a),LL(0x6dbde133,0x90af14ca),LL(0x948a3264,0x1afe4322), + LL(0xc44b2c6c,0xa70d2ca6),LL(0x0ef87dfe,0xab726799),LL(0x2e696377,0x310f64dc),LL(0x4c8126a0,0x49b42e68), LL(0xcea0b176,0x0ea444c3),LL(0xcb269182,0x53a8ddf7),LL(0xbbba9dcb,0xf3e674eb),LL(0xd8669d33,0x0d2878a8), + LL(0xd019b6a3,0x04b935d5),LL(0x406f1e46,0xbb5cf88e),LL(0x5b57c111,0xa1912d16),LL(0x19ebfd78,0x9803fc21), LL(0xc07764a9,0x4f231c9e),LL(0xb75bd055,0xd93286ee),LL(0x8ee6c9de,0x83a9457d),LL(0x6087ec90,0x04695915), + LL(0x58d6cd46,0x14c6dd8a),LL(0x8e6634d2,0x9cb633b5),LL(0xf81bc328,0xc1305047),LL(0x26a177e5,0x12ede0e2), LL(0x065a6f4f,0x332cca62),LL(0x67be487b,0xc3a47ecd),LL(0x0f47ed1c,0x741eb187),LL(0xe7598b14,0x99e66e58), + LL(0x63d0ff12,0x6f0544ca),LL(0xb610a05f,0xe5efc784),LL(0x7cad7b47,0xf72917b1),LL(0xf2cac0c0,0x3ff6ea20), LL(0xf21db8b7,0xcc23791b),LL(0xd7d93565,0x7dac70b1),LL(0x694bdaad,0x682cda1d),LL(0x1023516d,0xeb88bb8c), + LL(0xdfdbeb1b,0xc4c634b4),LL(0xb4ee4dea,0x22f5ca72),LL(0xe6524821,0x1045a368),LL(0x052b18b2,0xed9e8a3f), LL(0xb961f49a,0x9b7f2cb1),LL(0x7b009670,0x7fee2ec1),LL(0x22507a6d,0x350d8754),LL(0x4db55f1d,0x561bd711), + LL(0x320bbcaf,0x4c189ccc),LL(0xdf1de48c,0x568434cf),LL(0x0fa8f128,0x6af1b00e),LL(0x8907583c,0xf0ba9d02), LL(0x32ff9f60,0x735a4004),LL(0xc25dcf33,0x3dd8e4b6),LL(0x42c74cef,0xf2230f16),LL(0x013fa8ad,0xd8117623), + LL(0xf51fe76e,0x36822876),LL(0x11d62589,0x8a6811cc),LL(0x46225718,0xc3fc7e65),LL(0xc82fdbcd,0xb7df2c9f), LL(0xdd7b205b,0x3b1d4e52),LL(0x47a2e414,0xb6959478),LL(0xefa91148,0x05e4d793),LL(0xfd2e9675,0xb47ed446), + LL(0x04c9d9bf,0x1a7098b9),LL(0x1b793048,0x661e2881),LL(0xb01ee461,0xb1a16966),LL(0x2954746f,0xbc521308), LL(0x2477de50,0xc909a0fc),LL(0x7dbd51ef,0xd80bb41c),LL(0x53294905,0xa85be7ec),LL(0x83958f97,0x6d465b18), + LL(0xfb6840fd,0x16f6f330),LL(0x3401e6c8,0xfaaeb214),LL(0xccb5b4f8,0xaf83d30f),LL(0x266dec4b,0x22885739), LL(0x7bc467df,0x51b4367c),LL(0xd842d27a,0x926562e3),LL(0x0fea14a6,0xdfcb6614),LL(0xf2734cd9,0xeb394dae), + LL(0x11c0be98,0x3eeae5d2),LL(0x814e8165,0xb1e6ed11),LL(0xe52bce1c,0x191086bc),LL(0xa75a04da,0x14b74cc6), LL(0x8c060985,0x63cf1186),LL(0x2dbd7f7c,0x071047de),LL(0xce0942ca,0x4e433b8b),LL(0xd8fec61d,0xecbac447), + LL(0xebf3232f,0x8f0ed0e2),LL(0xc52a2edd,0xfff80f9e),LL(0x75b55fdb,0xad9ab433),LL(0xe42e0c11,0x73ca7820), LL(0xe6251b46,0x6dace0a0),LL(0x4c0d932d,0x89bc6b5c),LL(0x095da19a,0x3438cd77),LL(0x8d48bdfb,0x2f24a939), + LL(0x766561b7,0x99b47e46),LL(0x0ed0322a,0x736600e6),LL(0x638e1865,0x06a47cb1),LL(0xcb136000,0x927c1c2d), LL(0x0cc5df69,0x29542337),LL(0x09d649a9,0x99b37c02),LL(0x6aefdb27,0xc5f0043c),LL(0x1be95c27,0x6cdd9987), + LL(0x390420d2,0x69850931),LL(0x0983efa4,0x299c40ac),LL(0xaf39aead,0x3a05e778),LL(0x43a45193,0x84274408), LL(0x91a711a0,0x6bcd0fb9),LL(0x9f52ab17,0x461592c8),LL(0xda3c6ed6,0xb49302b4),LL(0x330d7067,0xc51fddc7), + LL(0xda50d531,0x94babeb6),LL(0xa6a7b9da,0x521b840d),LL(0x404bdc89,0x5305151e),LL(0xd0d07449,0x1bcde201), LL(0x3b76a59a,0xf427a78b),LL(0x07791a1b,0xf84841ce),LL(0xbf91ed1c,0xebd314be),LL(0xbf172943,0x8e61d34c), + LL(0x5541b892,0x1d5dc451),LL(0xfc9d9e54,0xb186ee41),LL(0xd5bf610d,0x9d9f345e),LL(0xf6acca9f,0x3e7ba65d), LL(0xa8369486,0x9dda787a),LL(0x8eb5ba53,0x09f9dab7),LL(0xd6481bc3,0x5afb2033),LL(0xafa62104,0x76f4ce30), + LL(0xf4f066b5,0xa8fa00cf),LL(0x461dafc2,0x89ab5143),LL(0xa3389998,0x44339ed7),LL(0xbc214903,0x2ff862f1), LL(0xb05556e3,0x2c88f985),LL(0x3467081e,0xcd96058e),LL(0xedc637ea,0x7d6a4176),LL(0x36a5acdc,0xe1743d09), + LL(0x7eb37726,0x66fd72e2),LL(0x1481a037,0xf7fa264e),LL(0x45f4aa79,0x9fbd3bde),LL(0x767c3e22,0xed1e0147), LL(0x82e7abe2,0x7621f979),LL(0x45f633f8,0x19eedc72),LL(0x6137bf3a,0xe69b155e),LL(0x414ee94e,0xa0ad13ce), + LL(0x1c0e651a,0x93e3d524),LL(0x02ce227e,0xab1a6e2a),LL(0x4ab27eca,0xe7af1797),LL(0xbd444f39,0x245446de), LL(0x56c07613,0x59e22a21),LL(0xf4275498,0x43deafce),LL(0x67fd0946,0x10834ccb),LL(0x47406edf,0xa75841e5), + LL(0x7b0ac93d,0xebd6a677),LL(0x78f5e0d7,0xa6e37b0d),LL(0x76f5492b,0x2516c096),LL(0x9ac05f3a,0x1e4bf888), LL(0x4df0ba2b,0xcdb42ce0),LL(0x5062341b,0x935d5cfd),LL(0x82acac20,0x8a303333),LL(0x5198b00e,0x429438c4), + LL(0x049d33fa,0x1d083bc9),LL(0x946f67ff,0x58b82dda),LL(0x67a1d6a3,0xac3e2db8),LL(0x1798aac8,0x62e6bead), LL(0xde46c58c,0xfc85980f),LL(0x69c8d7be,0xa7f69379),LL(0x837b35ec,0x23557927),LL(0xe0790c0c,0x06a933d8), + LL(0x077ff55d,0x827c0e9b),LL(0xbb26e680,0x53977798),LL(0x1d9cb54f,0x59530874),LL(0x4aac53ef,0xcca3f449), LL(0xa07eda0f,0x11dc5c87),LL(0xfd6400c8,0xc138bccf),LL(0x13e5da72,0x549680d3),LL(0x4540617e,0xc93eed82), + LL(0x4d0b75c0,0xfd3db157),LL(0x6386075b,0x9716eb42),LL(0x817b2c16,0x0639605c),LL(0xf1e4f201,0x09915109), LL(0x5cca6c3b,0x35c9a928),LL(0x3505c900,0xb25f7d1a),LL(0x630480c4,0xeb9f7d20),LL(0x2a1a501c,0xc3c7b8c6), + LL(0x5a1f8e24,0x3f99183c),LL(0x9dd255f0,0xfdb118fa),LL(0xc27f62a6,0xb9b18b90),LL(0x396ec191,0xe8f732f7), LL(0x0be786ab,0x524a2d91),LL(0x0ac5a0f5,0x5d32adef),LL(0x9725f694,0x9b53d4d6),LL(0x0510ba89,0x032a76c6), + LL(0xebeb1544,0x840391a3),LL(0x3ed73ac3,0x44b7b88c),LL(0x256cb8b3,0xd24bae7a),LL(0xe394cb12,0x7ceb151a), LL(0x5bc1e6a8,0xbd6b66d0),LL(0x090f07bf,0xec70cecb),LL(0x7d937589,0x270644ed),LL(0x5f1dccfe,0xee9e1a3d), + LL(0x745b98d2,0xb0d40a84),LL(0x2556ed40,0xda429a21),LL(0x85148cb9,0xf676eced),LL(0xded18936,0x5a22d40c), LL(0x70e8a4ce,0x3bc4b9e5),LL(0x9eae0379,0xbfd1445b),LL(0x1a0bd47e,0xf23f2c0c),LL(0xe1845531,0xa9c0bb31), + LL(0x0a4c3f6b,0x9ddc4d60),LL(0x2c15ef44,0xbdfaad79),LL(0x7f484acc,0xce55a236),LL(0x055b1f15,0x08653ca7), LL(0x538873a3,0x2efa8724),LL(0xace1c7e7,0x09299e5d),LL(0xade332ba,0x07afab66),LL(0x92dd71b7,0x9be1fdf6), + LL(0x5758b11c,0xa49b5d59),LL(0xc8654f40,0x0b852893),LL(0x52379447,0xb63ef6f4),LL(0x105e690c,0xd4957d29), LL(0x646559b0,0x7d484363),LL(0x49788a8e,0xf4a8273c),LL(0x34ce54a9,0xee406cb8),LL(0xf86fda9b,0x1e1c260f), + LL(0xcf6a4a81,0xe150e228),LL(0x1b488772,0x1fa3b6a3),LL(0xc5a9c15b,0x1e6ff110),LL(0x8ad6aa47,0xc6133b91), LL(0x9dffa978,0x8ac5d55c),LL(0x5f3965f2,0xba1d1c1d),LL(0x7732b52f,0xf969f4e0),LL(0xa5172a07,0xfceecdb5), + LL(0x10f2b8f5,0xb0120a5f),LL(0x5c4c2f63,0xc83a6cdf),LL(0xf8f9c213,0x4d47a491),LL(0xd3f1bbd5,0xd9e1cce5), LL(0xaba7e372,0x0d91bc7c),LL(0xdfd1a2db,0xfcdc74c8),LL(0x374618e5,0x05efa800),LL(0x15a7925e,0x11216969), + LL(0xf6021c5d,0xd4c89823),LL(0xeff14423,0x880d5e84),LL(0x6dcd1396,0x6523bc5a),LL(0x113c978b,0xd1acfdfc), LL(0xbbb66840,0xb0c164e8),LL(0x72b58459,0xf7f4301e),LL(0xa638e8ec,0xc29ad4a6),LL(0x46b78699,0xf5ab8961), + LL(0x0e954750,0x9dbd7974),LL(0x64f9d2c6,0x0121de88),LL(0xd985232e,0x2e597b42),LL(0x53451777,0x55b6c3c5), LL(0x519cb9fb,0xbb53e547),LL(0x8428600d,0xf134019f),LL(0xe081791a,0x5a473176),LL(0x35fb0c08,0x2f3e2263), + LL(0x73d273b0,0xb28c3017),LL(0x7721ef9a,0xccd21076),LL(0xb650dc39,0x054cc292),LL(0x6188045e,0x662246de), LL(0x6b83c0d1,0x904b52fa),LL(0x97e9cd46,0xa72df267),LL(0x899725e4,0x886b43cd),LL(0xd849ff22,0x2b651688), + LL(0x02f34533,0x60479b79),LL(0x0c77c148,0x5e354c14),LL(0xa8537c78,0xb4bb7581),LL(0xefe1495f,0x188043d7), LL(0x8c1d5026,0x9ba12f42),LL(0x93d4aaab,0x2e0c8a26),LL(0xaa57c450,0xbdba7b8b),LL(0x9bbdafef,0x140c9ad6), + LL(0x25ac0f18,0x2067aa42),LL(0x04d1fbf3,0xf7b1295b),LL(0xa4b04824,0x14829111),LL(0x33bd5e91,0x2ce3f192), LL(0x8f2e1b72,0x9c7a1d55),LL(0x302aa243,0xfe932286),LL(0xd4be9554,0x497ca7b4),LL(0xe0547a6e,0xb8e821b8), + LL(0x67e573e0,0xfb2838be),LL(0x4084c44b,0x05891db9),LL(0x96c1c2c5,0x91311373),LL(0xd958444b,0x6aebfa3f), LL(0xe56e55c1,0xac9cdce9),LL(0x2caa46d0,0x7148ced3),LL(0xb61fe8eb,0x2e10c7ef),LL(0xff97cf4d,0x9fd835da), +}, +/* digit=29 base_pwr=2^203 */ +{ + LL(0x081e9387,0xa36da109),LL(0x8c935828,0xfb9780d7),LL(0xe540b015,0xd5940332),LL(0xe0f466fa,0xc9d7b51b), LL(0xd6d9f671,0xfaadcd41),LL(0xb1a2ac17,0xba6c1e28),LL(0xed201e5f,0x066a7833),LL(0xf90f462b,0x19d99719), + LL(0x060b5f61,0xf431f462),LL(0x7bd057c2,0xa56f46b4),LL(0x47e1bf65,0x348dca6c),LL(0x41bcf1ff,0x9a38783e), LL(0xda710718,0x7a5d33a9),LL(0x2e0aeaf6,0x5a779987),LL(0x2d29d187,0xca87314d),LL(0xc687d733,0xfa0edc3e), + LL(0x6a31e09b,0x9df33621),LL(0xc1350e35,0xde89e44d),LL(0x4ca0cf52,0x29214871),LL(0x0b88a538,0xdf379672), LL(0x2591d61b,0xc92a510a),LL(0x585b447b,0x79aa87d7),LL(0xe5287f77,0xf67db604),LL(0x5efe7a80,0x1697c8bf), + LL(0xcb198ac7,0x1c894849),LL(0x0f264665,0xa884a93d),LL(0x9b200678,0x2da964ef),LL(0x009834e6,0x3c351b87), LL(0xe2c4b44b,0xafb2ef9f),LL(0x3326790c,0x580f6c47),LL(0x0b02264a,0xb8480521),LL(0x42a194e2,0x8ba6f9e2), + LL(0x8fb54738,0xfc87975f),LL(0x27c3ead3,0x35160788),LL(0xb74a085a,0x834116d2),LL(0xa62fe996,0x53c99a73), LL(0x5b81c51b,0x87585be0),LL(0xbe0852b7,0x925bafa8),LL(0xa84d19a7,0x76a4fafd),LL(0x585206d4,0x39a45982), + LL(0x5eb03c0e,0x499b6ab6),LL(0x72bc3fde,0xf19b7954),LL(0x6e3a80d2,0xa86b5b9c),LL(0x6d42819f,0xe4377508), LL(0xbb3ee8a3,0xc1663650),LL(0xb132075f,0x75eb14fc),LL(0x7ad834f6,0xa8ccc906),LL(0xe6e92ffd,0xea6a2474), + LL(0x0f8d6758,0x9d72fd95),LL(0x408c07dd,0xcb84e101),LL(0xa5e23221,0xb9114bfd),LL(0xe94e742c,0x358b5fe2), LL(0x95f40e75,0x1c0577ec),LL(0x3d73f3d6,0xf0155451),LL(0xbd1b9b66,0x9d55cd67),LL(0xaf8d63c7,0x63e86e78), + LL(0xd3c095f1,0x39d934ab),LL(0xe4b76d71,0x04b261be),LL(0xe73e6984,0x1d2e6970),LL(0x5e5fcb11,0x879fb23b), LL(0xdfd75490,0x11506c72),LL(0x61bcf1c1,0x3a97d085),LL(0xbf5e7007,0x43201d82),LL(0x798232a7,0x7f0ac52f), + LL(0x6eb564d4,0x2715cbc4),LL(0x9e570e29,0x8d6c752c),LL(0x9ef5fd5d,0xf80247c8),LL(0xd53eb514,0xc3c66b46), LL(0x0f87de56,0x9666b401),LL(0xc6c603b5,0xce62c06f),LL(0x7e4fc942,0xae7b4c60),LL(0x663a9c19,0x38ac0b77), + LL(0x4b049136,0xcb4d20ee),LL(0x356a4613,0x8b63bf12),LL(0x70e08128,0x1221aef6),LL(0x4acb6b16,0xe62d8c51), LL(0x379e7896,0x71f64a67),LL(0xcafd7fa5,0xb25237a2),LL(0x3841ba6a,0xf077bd98),LL(0x3cd16e7e,0xc4ac0244), + LL(0x21fea4ca,0x548ba869),LL(0xf3dfdac1,0xd36d0817),LL(0xf4685faf,0x09d8d71f),LL(0xc52c459a,0x8eff66be), LL(0x0b57235e,0x182faee7),LL(0x0106712b,0xee3c39b1),LL(0xc0fcdcb0,0x5107331f),LL(0xa51054ba,0x669fb9dc), + LL(0x319d7682,0xb25101fb),LL(0x0a982fee,0xb0293129),LL(0x0261b344,0x51c1c9b9),LL(0xbfd371fa,0x0e008c5b), LL(0x0278ca33,0xd866dd1c),LL(0xe5aa53b1,0x666f76a6),LL(0x6013a2cf,0xe5cfb779),LL(0xa3521836,0x1d3a1aad), + LL(0x73faa485,0xcedd2531),LL(0xc0a76878,0xc8ee6c4f),LL(0x2a11667d,0xddbccfc9),LL(0x1c2f695a,0x1a418ea9), LL(0x51f73971,0xdb11bd92),LL(0xda2ed89f,0x3e4b3c82),LL(0xe73e0319,0x9a44f3f4),LL(0x303431af,0xd1e3de0f), + LL(0x50f75f9c,0x3c5604ff),LL(0x7e752b22,0x1d8eddf3),LL(0x3c9a1118,0x0ef074dd),LL(0xccb86d7b,0xd0ffc172), LL(0x037d90f2,0xabd1ece3),LL(0x6055856c,0xe3f307d6),LL(0x7e4c6daf,0x422f9328),LL(0x334879a0,0x902aac66), + LL(0x94cdfade,0xb6a1e7bf),LL(0x7fc6d634,0x6c97e1ed),LL(0xa2fb63f8,0x662ad24d),LL(0xa5928405,0xf81be1b9), LL(0xd14b4206,0x86d765e4),LL(0x8fa0db65,0xbecc2e0e),LL(0xb17fc76c,0xa28838e0),LL(0xe37cf24e,0xe49a602a), + LL(0x567193ec,0x76b4131a),LL(0xe5f6e70b,0xaf3c305a),LL(0x031eebdd,0x9587bd39),LL(0x71bbe831,0x5709def8), LL(0x0eb2b669,0x57059983),LL(0x875b7029,0x4d80ce1b),LL(0x0364ac16,0x838a7da8),LL(0xbe1c83ab,0x2f431d23), + LL(0xf9294dd3,0xe56812a6),LL(0x9b4b0d77,0xb448d01f),LL(0x04e8305c,0xf3ae6061),LL(0x94d8c63e,0x2bead645), LL(0x84fd8b07,0x0a85434d),LL(0xf7a9dee5,0x537b983f),LL(0xef55bd85,0xedcc5f18),LL(0x21c6cf8b,0x2041af62), + LL(0xb940c71e,0x8e52874c),LL(0xdb5f4b3a,0x211935a9),LL(0x301b1dc3,0x94350492),LL(0x29958620,0x33d2646d), LL(0xef911404,0x16b0d64b),LL(0x9a3c5ef4,0x9d1f25ea),LL(0x4a352c78,0x20f200eb),LL(0x4bd0b428,0x43929f2c), + LL(0xc7196e29,0xa5656667),LL(0x9391be48,0x7992c2f0),LL(0x9ee0cd6e,0xaaa97cbd),LL(0x3dc8c9bf,0x51b0310c), LL(0xdd9f22cb,0x237f8acf),LL(0xb585d584,0xbb1d81a1),LL(0x8c416388,0x8d5d85f5),LL(0x42fe474f,0x0d6e5a5a), + LL(0x38235d4e,0xe7812766),LL(0x496e3298,0x1c62bd67),LL(0x3f175bc8,0x8378660c),LL(0x17afdd4d,0x4d04e189), LL(0x85a8068c,0x32a81601),LL(0x92b29a85,0xdb58e4e1),LL(0xc70d8a3b,0xe8a65b86),LL(0x98a0403b,0x5f0e6f4e), + LL(0x69ed2370,0x08129684),LL(0x0871ee26,0x34dc30bd),LL(0x7c9c5b05,0x3a5ce948),LL(0x43a90c87,0x7d487b80), LL(0xdd0e7179,0x4089ba37),LL(0xb4041811,0x45f80191),LL(0x98747ba5,0x1c3e1058),LL(0x6e1ae592,0x98c4e13a), + LL(0xe82c9f9e,0xd44636e6),LL(0xc33a1043,0x711db87c),LL(0xaa8aec05,0x6f431263),LL(0x2744a4aa,0x43ff120d), LL(0xae77779b,0xd3bd892f),LL(0x8cdc9f82,0xf0fe0cc9),LL(0xf1c5b1bc,0xca5f7fe6),LL(0x44929a72,0xcc63a682), + LL(0x09dbe19a,0xc7eaba0c),LL(0x6b5c73c2,0x2f3585ad),LL(0x0ae50c30,0x8ab8924b),LL(0x638b30ba,0x17fcd27a), LL(0x10b3d5a5,0xaf414d34),LL(0x2a9accf1,0x09c107d2),LL(0x946a6242,0x15dac49f),LL(0xd707d642,0xaec3df2a), + LL(0x3f894ae0,0x2c2492b7),LL(0xb75f18ce,0xf59df3e5),LL(0x8f53cad0,0x7cb740d2),LL(0xc4f01294,0x3eb585fb), LL(0x32c7f717,0x17da0c86),LL(0xaf943f4c,0xeb8c795b),LL(0xf67c51d2,0x4ee23fb5),LL(0x68889949,0xef187575), + LL(0x0389168b,0xa6b4bdb2),LL(0xea577d03,0xc4ecd258),LL(0x55743082,0x3a63782b),LL(0xc72f08cd,0x6f678f4c), LL(0x65e58dd8,0x553511cf),LL(0xd402c0cd,0xd53b4e3e),LL(0xa037c14c,0x37de3e29),LL(0xc05712aa,0x86b6c516), + LL(0xb38dff6f,0x2834da3e),LL(0xea636be8,0xbe012c52),LL(0x61dd37f8,0x292d238c),LL(0x8f8142db,0x0e54523f), LL(0x036a05d8,0xe31eb436),LL(0x1e93c0ff,0x83e3cdff),LL(0x50821ddf,0x3fd2fe0f),LL(0xff9eb33b,0xc8e19b0d), + LL(0xb569a5fe,0xc8cc943f),LL(0xd4342d75,0xad0090d4),LL(0xcaeca000,0x82090b4b),LL(0x1bd410eb,0xca39687f), LL(0x65959d77,0xe7bb0df7),LL(0x9c964999,0x39d78218),LL(0xb2415451,0xd87f62e8),LL(0xbed76108,0xe5efb774), + LL(0xe822f0d0,0x3ea011a4),LL(0x5a8704f8,0xbc647ad1),LL(0x50c6820f,0xbb315b35),LL(0xb7e76bec,0x863dec3d), LL(0xf017bfc7,0x01ff5d3a),LL(0x976b8229,0x20054439),LL(0x0bbd0d3b,0x067fca37),LL(0x7f5e3d0f,0xf63dde64), + LL(0x2a4c94e9,0x22dbefb3),LL(0x96f8278a,0xafbff0fe),LL(0x3503793d,0x80aea0b1),LL(0x5f06cd29,0xb2238029), LL(0x8ec3feca,0x65703e57),LL(0x393e7053,0x06c38314),LL(0x7c6734c4,0xa0b751eb),LL(0xc59f0f1e,0xd2e8a435), + LL(0x5e9ca895,0x147d9052),LL(0x972072df,0x2f4dd31e),LL(0xe6c6755c,0xa16fda8e),LL(0xcf196558,0xc66826ff), LL(0x0cf43895,0x1f1a76a3),LL(0x83c3097b,0xa9d604e0),LL(0x66390e0e,0xe1908309),LL(0xb3c85eff,0xa50bf753), + LL(0xf6a70251,0x0696bdde),LL(0x3c6ab16a,0x548b801b),LL(0xa4d08762,0x37fcf704),LL(0xdff76c4e,0x090b3def), LL(0x69cb9158,0x87e8cb89),LL(0x995ece43,0x44a90744),LL(0x0ad9fbf5,0xf85395f4),LL(0x4fb0c82d,0x49b0f6c5), + LL(0xadf7cccf,0x75d9bc15),LL(0xdfa1e1b0,0x81a3e5d6),LL(0x249bc17e,0x8c39e444),LL(0x8ea7fd43,0xf37dccb2), LL(0x907fba12,0xda654873),LL(0x4a372904,0x35daa6da),LL(0x6283a6c5,0x0564cfc6),LL(0x4a9395bf,0xd09fa4f6), + LL(0xaeb19a36,0x688e9ec9),LL(0xc7bfbfb4,0xd913f1ce),LL(0x61c2faa6,0x797b9a3c),LL(0x6a0a9c12,0x2f979bec), LL(0x359679ec,0xb5969d0f),LL(0x079b0460,0xebcf523d),LL(0x10fab870,0xfd6b0008),LL(0x9373a39c,0x3f2edcda), + LL(0x6f568431,0x0d64f9a7),LL(0x02f8898c,0xf848c27c),LL(0x260b5bd5,0xf418ade1),LL(0x6973dee8,0xc1f3e323), LL(0x26c185dd,0x46e9319c),LL(0x546f0ac4,0x6d85b7d8),LL(0x247f9d57,0x427965f2),LL(0xb0035f48,0xb519b636), + LL(0xab87d59c,0x6b6163a9),LL(0x39caaa11,0xff9f58c3),LL(0x3177387b,0x4ac39cde),LL(0x873e77f9,0x5f6557c2), LL(0x36a83041,0x67504006),LL(0x75ef196c,0x9b1c96ca),LL(0xb08c7940,0xf34283de),LL(0x1128c316,0x7ea09644), + LL(0x6aa39dff,0xb510b3b5),LL(0x9f8e4d8c,0x59b43da2),LL(0x9e4c4b9f,0xa8ce31fd),LL(0xc1303c01,0x0e20be26), LL(0xe8ee47c9,0x18187182),LL(0x7db98101,0xd9687cdb),LL(0xa1e14ff6,0x7a520e4d),LL(0x8836d572,0x429808ba), + LL(0x4944b663,0xa37ca60d),LL(0xa3f91ae5,0xf901f7a9),LL(0x9e36e3b1,0xe4e3e76e),LL(0x29d93250,0x9aa219cf), LL(0x056a2512,0x347fe275),LL(0xde65d95c,0xa4d643d9),LL(0x699fc3ed,0x9669d396),LL(0xcf8c6bbe,0xb598dee2), + LL(0xdda9e5c6,0x682ac1e5),LL(0xcaa9fc95,0x4e0d3c72),LL(0x772bea44,0x17faaade),LL(0xab0009c8,0x5ef8428c), LL(0x460ff016,0xcc4ce47a),LL(0x725281cb,0xda6d12bf),LL(0x0223aad2,0x44c67848),LL(0x36256e28,0x6e342afa), + LL(0x93a37c04,0x1400bb0b),LL(0xdd10bd96,0x62b1bc9b),LL(0x0dac46b7,0x7251adeb),LL(0x7be4ef51,0x7d33b92e), LL(0xe61fa29a,0x28b2a94b),LL(0x06422233,0x4b2be13f),LL(0x330d8d37,0x36d6d062),LL(0xb28ca005,0x5ef80e1e), + LL(0x6d16768e,0x174d4699),LL(0x628bf217,0x9fc4ff6a),LL(0x154e490d,0x77705a94),LL(0x8d2d997a,0x9d96dd28), LL(0xce5d72c4,0x77e2d9d8),LL(0xc11c714f,0x9d06c5a4),LL(0x79e4a03e,0x02aa5136),LL(0x030ff28b,0x1386b3c2), + LL(0xfb283f61,0xfe82e8a6),LL(0xf3abc3fb,0x7df203e5),LL(0x3a4d3622,0xeec7c351),LL(0xdf762761,0xf7d17dbf), LL(0x522055f0,0xc3956e44),LL(0x8fa748db,0xde3012db),LL(0xbf1dcc14,0xca9fcb63),LL(0xbe4e2f3a,0xa56d9dcf), + LL(0x8bcec9c2,0xb86186b6),LL(0x680b9f06,0x7cf24df9),LL(0xc0d29281,0xc46b45ea),LL(0x07b10e12,0xfff42bc5), LL(0x4d289427,0x12263c40),LL(0xb4848ec4,0x3d5f1899),LL(0xd040800c,0x11f97010),LL(0x300feb20,0xb4c5f529), + LL(0xde94fdcb,0xcc543f8f),LL(0xc7c2f05e,0xe96af739),LL(0x882692e1,0xaa5e0036),LL(0x950d4ae9,0x09c75b68), LL(0xb5932a7a,0x62f63df2),LL(0xde0979ad,0x2658252e),LL(0xb5e69631,0x2a19343f),LL(0x525b666b,0x718c7501), + LL(0xea40dc3a,0x26a42d69),LL(0xaecc018f,0xdc84ad22),LL(0x3270f04a,0x25c36c7b),LL(0x50fa72ed,0x46ba6d47), LL(0x93e58a8e,0x6c37d1c5),LL(0x120c088c,0xa2394731),LL(0xcb6e86da,0xc3be4263),LL(0x7126d038,0x2c417d36), + LL(0x8b6f8efa,0x5b70f9c5),LL(0x37718536,0x671a2faa),LL(0xb539c92b,0xd3ced3c6),LL(0xa31203c2,0xe56f1bd9), LL(0x9ff3c8eb,0x8b096ec4),LL(0x43491cea,0x2deae432),LL(0x17943794,0x2465c6eb),LL(0x20586843,0x5d267e66), + LL(0xb07159d0,0x9d3d116d),LL(0xc1896210,0xae07a67f),LL(0xbb961579,0x8fc84d87),LL(0x1c1f8dd6,0x30009e49), LL(0xe3132819,0x8a8caf22),LL(0xf23ab4ff,0xcffa197c),LL(0x205dd687,0x58103a44),LL(0x0ded67a2,0x57b796c3), + LL(0xa1779ad7,0x0b9c3a6c),LL(0x357c09c5,0xa33cfe2e),LL(0x3db4a57e,0x2ea29315),LL(0x8ebeb52e,0x91959695), LL(0xe546c879,0x118db9a6),LL(0x6295c8d6,0x8e996df4),LL(0x55ec806b,0xdd990484),LL(0x165c1035,0x24f291ca), + LL(0x440e2229,0xcca523bb),LL(0x73ef4d04,0x324673a2),LL(0x3e11ec39,0xaf3adf34),LL(0xdc5968d3,0x6136d7f1), LL(0xb053a927,0x7a7b2899),LL(0xae067ecd,0x3eaa2661),LL(0x02779cd9,0x8549b9c8),LL(0xc53385ea,0x061d7940), + LL(0xf06d18bd,0x3e0ba883),LL(0xb2700843,0x4ba6de53),LL(0x591a9e4d,0xb966b668),LL(0x7f4fa0ed,0x93f67567), LL(0x4347237b,0x5a02711b),LL(0xe794608e,0xbc041e2f),LL(0x70f73d8c,0x55af10f5),LL(0xbb7564f7,0xd2d4d4f7), + LL(0xb3e93ce7,0xd7d27a89),LL(0x5d3a2c1b,0xf7b5a875),LL(0x255b218a,0xb29e68a0),LL(0x8af76754,0xb533837e), LL(0x579fab2e,0xd1b05a73),LL(0xecd74385,0xb41055a1),LL(0x445e9115,0xb2369274),LL(0xf520274e,0x2972a7c4), + LL(0xf678e68a,0x6c08334e),LL(0x99b057ed,0x4e4160f0),LL(0x52ccb69a,0x3cfe11b8),LL(0x21c8f772,0x2fd1823a), LL(0x3298f055,0xdf7f072f),LL(0xfec74a6e,0x8c0566f9),LL(0x5bb4d041,0xe549e019),LL(0x9208d850,0x7c3930ba), + LL(0xaaa2902b,0xe07141fc),LL(0xe4f69ad3,0x539ad799),LL(0x813f9ffd,0xa6453f94),LL(0x375bc2f7,0xc58d3c48), LL(0x5dc64e96,0xb3326fad),LL(0xb240e354,0x3aafcaa9),LL(0xaca1e7a9,0x1d1b0903),LL(0x1211b8a0,0x4ceb9767), + LL(0xe32a858e,0xeca83e49),LL(0xae907bad,0x4c32892e),LL(0x2eb9b494,0xd5b42ab6),LL(0x1eabae1b,0x7fde3ee2), LL(0xcaf54957,0x13b5ab09),LL(0xe5f5d5d5,0xbfb028be),LL(0x2003e2c0,0x928a0650),LL(0x67476843,0x90793aac), + LL(0xc81710a0,0x5e942e79),LL(0x27ccadd4,0x557e4a36),LL(0x4bcf6d0c,0x72a2bc56),LL(0x26d7b80c,0x09ee5f43), LL(0xd4292f19,0x6b70dbe9),LL(0x63f16b18,0x56f74c26),LL(0x35fbb42a,0xc23db0f7),LL(0x6ae10040,0xb606bdf6), + LL(0x044573ac,0x1eb15d4d),LL(0x556b0ba4,0x7dc3cf86),LL(0xc60df6f7,0x97af9a33),LL(0xa716ce8c,0x0b1ef85c), LL(0xc96958be,0x2922f884),LL(0x35690963,0x7c32fa94),LL(0xeaa00061,0x2d7f667c),LL(0x3547365c,0xeaaf7c17), + LL(0x87032d58,0x1eb4de46),LL(0x5e2c79e0,0xc54f3d83),LL(0x5d04ef23,0x07818df4),LL(0x673d41b4,0x55faa9c8), LL(0x89b95355,0xced64f6f),LL(0xb7415c84,0x4860d2ea),LL(0x050ebad3,0x5fdb9bd2),LL(0x6685a5bf,0xdb53e0cc), + LL(0x9feb6593,0xb830c031),LL(0x6accff17,0xdd87f310),LL(0x9f555c10,0x2303ebab),LL(0x287e7065,0x94603695), LL(0x2e83358c,0xf88311c3),LL(0xeefb0178,0x508dd9b4),LL(0x2dba8652,0x7ca23706),LL(0x0047abe5,0x62aac5a3), + LL(0x8b1ea7b3,0x9a61d2a0),LL(0xae8b1485,0xd495ab63),LL(0x87052f99,0x38740f84),LL(0xb2974eea,0x178ebe5b), LL(0x5b36d17f,0x030bbcca),LL(0xaaf86eea,0xb5e4cce3),LL(0x68f8e9e0,0xb51a0220),LL(0x09eb3e75,0xa4348796), + LL(0xeef1a752,0xbe592309),LL(0x6f2aa1ed,0x5d7162d7),LL(0x0f007dd2,0xaebfb5ed),LL(0xc89edd22,0x255e14b2), LL(0x0303b697,0xba85e072),LL(0xf05720ff,0xc5d17e25),LL(0x5128ebb6,0x02b58d6e),LL(0xd754e113,0x2c80242d), + LL(0xabfae1ca,0x919fca5f),LL(0x1a21459b,0x937afaac),LL(0x1f66a4d2,0x9e0ca91c),LL(0x23ec1331,0x194cc7f3), LL(0x8aa11690,0xad25143a),LL(0x09b59e08,0xbe40ad8d),LL(0xe750860a,0x37d60d9b),LL(0xc6bf434c,0x6c53b008), + LL(0x1356eb80,0xb572415d),LL(0x9578ded8,0xb8bf9da3),LL(0x5e8fb38b,0x22658e36),LL(0x5af8cb22,0x9b70ce22), LL(0x829a8180,0x7c00018a),LL(0xb81ed295,0x84329f93),LL(0x5f3cea83,0x7c343ea2),LL(0x67586536,0x38f8655f), + LL(0x1d3ec517,0xa661a0d0),LL(0x512321ae,0x98744652),LL(0xeca92598,0x084ca591),LL(0x1dcb3feb,0xa9bb9dc9), LL(0x78b4c240,0x14c54355),LL(0x610cafdc,0x5ed62a3b),LL(0x1b38846b,0x07512f37),LL(0xb0e38161,0x571bb70a), + LL(0x2da705d2,0xb556b95b),LL(0xb1a08f98,0x3ef8ada6),LL(0xddecfbe5,0x85302ca7),LL(0x943105cd,0x0e530573), LL(0x21a9255d,0x60554d55),LL(0xf2f3802a,0x63a32fa1),LL(0xcd477875,0x35c8c5b0),LL(0x6ad42da1,0x97f458ea), + LL(0xeb6b242d,0x832d7080),LL(0x3b71e246,0xd30bd023),LL(0xbe31139d,0x7027991b),LL(0x462e4e53,0x68797e91), LL(0x6b4e185a,0x423fe20a),LL(0x42d9b707,0x82f2c67e),LL(0x4cf7811b,0x25c81768),LL(0x045bb95d,0xbd53005e), +}, +/* digit=30 base_pwr=2^210 */ +{ + LL(0x9d8e68fd,0xe5f649be),LL(0x1b044320,0xdb0f0533),LL(0xe0c33398,0xf6fde9b3),LL(0x66c8cfae,0x92f4209b), LL(0x1a739d4b,0xe9d1afcc),LL(0xa28ab8de,0x09aea75f),LL(0xeac6f1d0,0x14375fb5),LL(0x708f7aa5,0x6420b560), + LL(0x6254dc41,0x9eae499c),LL(0x7a837e7e,0x7e293924),LL(0x090524a7,0x74aec08c),LL(0x8d6f55f2,0xf82b9219), LL(0x1402cec5,0x493c962e),LL(0xfa2f30e7,0x9f17ca17),LL(0xe9b879cb,0xbcd783e8),LL(0x5a6f145f,0xea3d8c14), + LL(0x5e0dee6e,0xdede15e7),LL(0xdc628aa2,0x74f24872),LL(0x7861bb93,0xd3e9c4fe),LL(0x6187b2e0,0x56d4822a), LL(0xc59826f9,0xb66417cf),LL(0x2408169e,0xca260969),LL(0xc79ef885,0xedf69d06),LL(0xdc7d138f,0x00031f8a), + LL(0x0ebcf726,0x103c46e6),LL(0x6231470e,0x4482b831),LL(0x487c2109,0x6f6dfaca),LL(0x62e666ef,0x2e0ace97), LL(0x1f8d1f42,0x3246a9d3),LL(0x574944d2,0x1b1e83f1),LL(0xa57f334b,0x13dfa63a),LL(0x9f025d81,0x0cf8daed), + LL(0x00ee11c1,0x30d78ea8),LL(0xb5e3dd75,0xeb053cd4),LL(0xd58c43c5,0x9b65b13e),LL(0xbd151663,0xc3ad49bd), LL(0xb6427990,0x99fd8e41),LL(0x707eae1e,0x12cf15bd),LL(0x1aabb71e,0x29ad4f1b),LL(0x07545d0e,0x5143e74d), + LL(0xc88bdee1,0x30266336),LL(0x5876767c,0x25f29306),LL(0xc6731996,0x9c078571),LL(0xed552951,0xc88690b2), LL(0x852705b4,0x274f2c2d),LL(0x4e09552d,0xb0bf8d44),LL(0x986575d1,0x7628beeb),LL(0x7f864651,0x407be238), + LL(0xa639fc6b,0x0e5e3049),LL(0x86003625,0xe75c35d9),LL(0x5dcc1646,0x0cf35bd8),LL(0x6c26273a,0x8bcaced2), LL(0xb5536742,0xe22ecf1d),LL(0x1a9e068b,0x013dd897),LL(0x8a7909c5,0x17f411cb),LL(0x861dd506,0x5757ac98), + LL(0x1e935abb,0x85de1f0d),LL(0x154de37a,0xdefd10b4),LL(0x369cebb5,0xb8d9e392),LL(0x761324be,0x54d5ef9b), LL(0x74f17e26,0x4d6341ba),LL(0x78c1dde4,0xc0a0e3c8),LL(0x87d918fd,0xa6d77581),LL(0x02ca3a13,0x66876015), + LL(0xf36658f0,0xc7313e9c),LL(0x71f8057e,0xc433ef1c),LL(0x1b6a835a,0x85326246),LL(0x7c86394c,0xc8f05398), LL(0xe983c4a1,0xff398cdf),LL(0x03b7b931,0xbf5e8162),LL(0xb7b9045b,0x93193c46),LL(0xa4a6e46b,0x1e4ebf5d), + LL(0x43a24fe7,0xf9942a60),LL(0xffb3492b,0x29c1191e),LL(0x902fde05,0x9f662449),LL(0x6713c32d,0xc792a7ac), LL(0xb737982c,0x2fd88ad8),LL(0xa21e60e3,0x7e3a0319),LL(0x7383591a,0x09b0de44),LL(0x8310a456,0x6df141ee), + LL(0xe6d6f471,0xaec1a039),LL(0x1198d12e,0x14b2ba0f),LL(0x3aeee5ac,0xebc1a160),LL(0xe0b964ce,0x401f4836), LL(0x4fd03f66,0x2ee43796),LL(0xdd8f3f12,0x3fdb4e49),LL(0x29380f18,0x6ef267f6),LL(0x8da64d16,0x3e8e9670), + LL(0x207674f1,0xbc19180c),LL(0x33ae8fdb,0x112e09a7),LL(0x6aaeb71e,0x99667554),LL(0xe101b1c7,0x79432af1), LL(0xde2ddec6,0xd5eb558f),LL(0x5357753f,0x81392d1f),LL(0x3ae1158a,0xa7a76b97),LL(0x4a899991,0x416fbbff), + LL(0x0d4a9dcf,0x9e65fdfd),LL(0x944ddf12,0x7bc29e48),LL(0x3c856866,0xbc1a92d9),LL(0x6e98dfe2,0x273c6905), LL(0xcdfaa6b8,0x69fce418),LL(0x5061c69f,0x606bd823),LL(0x6af75e27,0x42d495a0),LL(0x6d873a1f,0x8ed3d505), + LL(0x6ab25b6a,0xaf552841),LL(0x2b1a4523,0xc6c0ffc7),LL(0x21c99e03,0xab18827b),LL(0x9034691b,0x060e8648), LL(0x93c7f398,0x5207f90f),LL(0x82f8d10b,0x9f4a96cb),LL(0x3ad0f9e3,0xdd71cd79),LL(0xfc3a54f5,0x84f435d2), + LL(0x8e33787f,0x4b03c55b),LL(0xa6384673,0xef42f975),LL(0x5051b9f0,0xff7304f7),LL(0x741c87c2,0x18aca1dc), LL(0x2d4bfe80,0x56f120a7),LL(0x053e732c,0xfd823b3d),LL(0x7537ca16,0x11bccfe4),LL(0x1b5a996b,0xdf6c9c74), + LL(0x904fc3fa,0xee7332c7),LL(0xc7e3636a,0x14a23f45),LL(0xf091d9aa,0xc38659c3),LL(0xb12d8540,0x4a995e5d), LL(0xf3a5598a,0x20a53bec),LL(0xb1eaa995,0x56534b17),LL(0xbf04e03c,0x9ed3dca4),LL(0xd8d56268,0x716c563a), + LL(0x1d6178e7,0x27ba77a4),LL(0x68a1ff8e,0xe4c80c40),LL(0x0a13f63d,0x75011099),LL(0xa61d46f3,0x7bf33521), LL(0x10b365bb,0x0aff218e),LL(0x0fd7ea75,0x81021804),LL(0xa4b3a925,0x05a3fd8a),LL(0x9b3db4e6,0xb829e75f), + LL(0x4d53e5fb,0x6bdc75a5),LL(0xd52717e3,0x04a5dc02),LL(0xe9a42ec2,0x86af502f),LL(0x2630e382,0x8867e8fb), LL(0xbec9889b,0xbf845c6e),LL(0xcb47c98d,0x54f491f2),LL(0x790c2a12,0xa3091fba),LL(0xc20f708b,0xd7f6fd78), + LL(0xacde5e17,0xa569ac30),LL(0x6852b4d7,0xd0f996d0),LL(0x4609ae54,0xe51d4bb5),LL(0x0daed061,0x3fa37d17), LL(0x34b8fb41,0x62a88684),LL(0x9efb64f1,0x99a2acbd),LL(0x6448e1f2,0xb75c1a5e),LL(0x42b5a069,0xfa99951a), + LL(0x2f3b26e7,0x6d956e89),LL(0xda875247,0xf4709860),LL(0x2482dda3,0x3ad15179),LL(0x017d82f0,0xd64110e3), LL(0xfad414e4,0x14928d2c),LL(0x2ed02b24,0x2b155f58),LL(0xcb821bf1,0x481a141b),LL(0x4f81f5da,0x12e3c770), + LL(0x9fff8381,0xe49c5de5),LL(0x5bbec894,0x11053232),LL(0x454d88c4,0xa0d051cc),LL(0x1f8e531b,0x4f6db89c), LL(0xca563a44,0x34fe3fd6),LL(0x58da8ab9,0x7f5c2215),LL(0x9474f0a1,0x8445016d),LL(0xcb7d8a0a,0x17d34d61), + LL(0x1c474019,0x8e9d3910),LL(0xd52ceefb,0xcaff2629),LL(0xc1622c2b,0xf9cf3e32),LL(0xe9071a05,0xd4b95e3c), LL(0x1594438c,0xfbbca61f),LL(0x04aadedf,0x1eb6e6a6),LL(0x68e14940,0x853027f4),LL(0xdfabda9c,0x221d322a), + LL(0xb7cb179a,0xed8ea9f6),LL(0xb7934dcc,0xdc7b764d),LL(0x5e09180d,0xfcb13940),LL(0xb47dc2dd,0x6629a6bf), LL(0x9f5a915e,0xbfc55e4e),LL(0x6204441e,0xb1db9d37),LL(0x930c5f53,0xf82d68cf),LL(0xcbb605b1,0x17d3a142), + LL(0x308780f2,0xdd5944ea),LL(0x3845f5e4,0xdc8de761),LL(0x7624d7a3,0x6beaba7d),LL(0x304df11e,0x1e709afd), LL(0x02170456,0x95364376),LL(0xc8f94b64,0xbf204b3a),LL(0x5680ca68,0x4e53af7c),LL(0xe0c67574,0x0526074a), + LL(0xecd92af6,0x95d8cef8),LL(0x6cd1745a,0xe6b9fa7a),LL(0xa325c3e4,0x3d546d3d),LL(0x9ae93aae,0x1f57691d), LL(0x9d2e1a33,0xe891f3fe),LL(0xac063d35,0xd430093f),LL(0x5513a327,0xeda59b12),LL(0x5536f18f,0xdc2134f3), + LL(0x5c210286,0xaa51fe2c),LL(0x1cab658c,0x3f68aaee),LL(0xf9357292,0x5a23a00b),LL(0x7efdabed,0x9a626f39), LL(0x199d78e3,0xfe2b3bf3),LL(0x71bbc345,0xb7a2af77),LL(0x1e59802c,0x3d19827a),LL(0xb487a51c,0x823bbc15), + LL(0x99d0a422,0x856139f2),LL(0xf456c6fb,0x9ac3df65),LL(0x701f8bd6,0xaddf65c6),LL(0x3758df87,0x149f321e), LL(0x721b7eba,0xb1ecf714),LL(0x31a3312a,0xe17df098),LL(0xd5c4d581,0xdb2fd6ec),LL(0x8fcea1b3,0xfd02996f), + LL(0x7882f14f,0xe29fa63e),LL(0x07c6cadc,0xc9f6dc35),LL(0xb882bed0,0x46f22d6f),LL(0xd118e52c,0x1a45755b), LL(0x7c4608cf,0x9f2c7c27),LL(0x568012c2,0x7ccbdf32),LL(0x61729b0e,0xfcb0aedd),LL(0xf7d75dbf,0x7ca2ca9e), + LL(0x6f640f62,0xf58fecb1),LL(0x39f51946,0xe274b92b),LL(0x6288af44,0x7f4dfc04),LL(0xeac329e5,0x0a91f32a), LL(0xd6aaba31,0x43ad274b),LL(0x0f6884f9,0x719a1640),LL(0xdaf91e20,0x685d29f6),LL(0x27e49d52,0x5ec1cc33), + LL(0x3b54a059,0x38f4de96),LL(0xefbcfdb3,0x0e0015e5),LL(0x4dbb8da6,0x177d23d9),LL(0x97a617ad,0x98724aa2), LL(0xfdb6558e,0x30f0885b),LL(0xc7899a96,0xf9f7a28a),LL(0x872dc112,0xd2ae8ac8),LL(0x73c3c459,0xfa0642ca), + LL(0xe7dfc8d6,0x15296981),LL(0x1fb5b94a,0x67cd4450),LL(0x0eddfd37,0x0ec71cf1),LL(0x9a8eddc7,0xc7e5eeb3), LL(0x81d95028,0x02ac8e3d),LL(0x70b0e35d,0x0088f172),LL(0xe1881fe3,0xec041fab),LL(0xd99e7faa,0x62cf71b8), + LL(0xe0f222c2,0x5043dea7),LL(0x72e65142,0x309d42ac),LL(0x9216cd30,0x94fe9ddd),LL(0x0f87feec,0xd6539c7d), LL(0x432ac7d7,0x03c5a57c),LL(0x327fda10,0x72692cf0),LL(0x280698de,0xec28c85f),LL(0x7ec283b1,0x2331fb46), + LL(0x2867e633,0xd34bfa32),LL(0x0a9cc815,0x78709a82),LL(0x875e2fa5,0xb7fe6964),LL(0x9e98bfb5,0x25cc064f), LL(0x493a65c5,0x9eb0151c),LL(0x53182464,0x5fb5d941),LL(0xf04618e2,0x69e6f130),LL(0xf89c8ab6,0xa8ecec22), + LL(0xb96209bd,0xcd6ac88b),LL(0xb3e1c9e0,0x65fa8cdb),LL(0x4a8d8eac,0xa47d22f5),LL(0x8d33f963,0x83895cdf), LL(0xb56cd3d1,0xa8adca59),LL(0xdaf38232,0x10c8350b),LL(0xa5080a9f,0x2b161fb3),LL(0x3af65b3a,0xbe7f5c64), + LL(0x97403a11,0x2c754039),LL(0x121b96af,0x94626cf7),LL(0x6a983ec2,0x431de7c4),LL(0x52cc3df7,0x3780dd3a), LL(0x2baf8e3b,0xe28a0e46),LL(0x51d299ae,0xabe68aad),LL(0x647a2408,0x603eb8f9),LL(0x5c750981,0x14c61ed6), + LL(0xc53352e7,0x88b34414),LL(0x1337d46e,0x5a34889c),LL(0xf95f2bc8,0x612c1560),LL(0xd4807a3a,0x8a3f8441), LL(0x5224da68,0x680d9e97),LL(0xc3eb00e9,0x60cd6e88),LL(0x9a6bc375,0x3875a98e),LL(0x4fd554c2,0xdc80f924), + LL(0x6ac77407,0x6c4b3415),LL(0x25420681,0xa1e5ea8f),LL(0x4607a458,0x541bfa14),LL(0x96d7fbf9,0x5dbc7e7a), LL(0x31590a47,0x646a851b),LL(0x15ee6df8,0x039e85ba),LL(0xd7b43fc0,0xd19fa231),LL(0x299a0e04,0x84bc8be8), + LL(0xf20df03a,0x2b9d2936),LL(0x8608d472,0x24054382),LL(0x9149202a,0x76b6ba04),LL(0x3670e7b7,0xb21c3831), LL(0xd6fdee10,0xddd93059),LL(0x78488e71,0x9da47ad3),LL(0xa0fcfb25,0x99cc1dfd),LL(0x64696954,0x42abde10), + LL(0x17eab9fe,0x14cc15fc),LL(0xd3e70972,0xd6e863e4),LL(0x6432112c,0x29a7765c),LL(0x5b0774d8,0x88660001), LL(0x2c088eae,0x3729175a),LL(0x8230b8d4,0x13afbcae),LL(0x915f4379,0x44768151),LL(0xd8d22812,0xf086431a), + LL(0xc298b974,0x37461955),LL(0xf8711e04,0x905fb5f0),LL(0xfe969d18,0x787abf3a),LL(0x6f6a494e,0x392167c2), LL(0x28c511da,0xfc7a0d2d),LL(0xb66a262d,0xf127c7dc),LL(0xfd63fdf0,0xf9c4bb95),LL(0x3913ef46,0x90016589), + LL(0x11aa600d,0x74d2a73c),LL(0x9fb5ab52,0x2f5379bd),LL(0x7fb70068,0xe49e53a4),LL(0x404aa9a7,0x68dd39e5), LL(0x2ecaa9c3,0xb9b0cf57),LL(0xe824826b,0xba0e103b),LL(0x4631a3c4,0x60c2198b),LL(0xfa8966a2,0xc5ff84ab), + LL(0xac95aff8,0x2d6ebe22),LL(0xb5a46d09,0x1c9bb6db),LL(0x53ee4f8d,0x419062da),LL(0xbb97efef,0x7b9042d0), LL(0x830cf6bd,0x0f87f080),LL(0x6ec8a6c6,0x4861d19a),LL(0x202f01aa,0xd3a0daa1),LL(0xf25afbd5,0xb0111674), + LL(0x1afb20d9,0x6d00d6cf),LL(0x40671bc5,0x13695000),LL(0x2485ea9b,0x913ab0dc),LL(0x9eef61ac,0x1f2bed06), LL(0x6d799e20,0x850c8217),LL(0x3271c2de,0x93415f37),LL(0x6c4f5910,0x5afb06e9),LL(0xc4e9e421,0x688a52df), + LL(0xe2a9a6db,0x30495ba3),LL(0x58f9268b,0x4601303d),LL(0x7eb0f04f,0xbe3b0dad),LL(0x4456936d,0x4ea47250), LL(0xd33fd3e7,0x8caf8798),LL(0xeb433708,0x1ccd8a89),LL(0x87fd50ad,0x9effe3e8),LL(0x6b29c4df,0xbe240a56), + LL(0xca0e7ebd,0xec4ffd98),LL(0xe748616e,0xf586783a),LL(0xc77baa99,0xa5b00d8f),LL(0xb4f34c9c,0x0acada29), LL(0x0fe723ac,0x36dad67d),LL(0x39c36c1e,0x1d8e53a5),LL(0x1f4bea41,0xe4dd342d),LL(0xebc9e4e0,0x64fd5e35), + LL(0x57908805,0x96f01f90),LL(0x5ed480dd,0xb5b9ea3d),LL(0x3efd2dd0,0x366c5dc2),LL(0x6e9dfa27,0xed2fe305), LL(0x6e9197e2,0x4575e892),LL(0xab502a5d,0x11719c09),LL(0xe81f213f,0x264c7bec),LL(0x55f5c457,0x741b9241), + LL(0x49a5f4f4,0x78ac7b68),LL(0x9fc45b7d,0xf91d70a2),LL(0xb0f5f355,0x39b05544),LL(0xeef930d9,0x11f06bce), LL(0x038d05e1,0xdb84d25d),LL(0xbacc1d51,0x04838ee5),LL(0x9e8ee00b,0x9da3ce86),LL(0xc36eda1f,0xc3412057), + LL(0x64d9c2f4,0xae80b913),LL(0xa010a8ff,0x7468bac3),LL(0x37359d41,0xdfd20037),LL(0x15efeacc,0x1a0f5ab8), LL(0x659d0ce0,0x7c25ad2f),LL(0x6785cff1,0x4011bcbb),LL(0x7e2192c7,0x128b9912),LL(0x13ccb0e8,0xa549d8e1), + LL(0xc85438b1,0x805588d8),LL(0xbc25cb27,0x5680332d),LL(0x1a4bfdf4,0xdcd1bc96),LL(0x706f6566,0x779ff428), LL(0xf059987a,0x8bbee998),LL(0xcc686de7,0xf6ce8cf2),LL(0x953cfdb2,0xf8ad3c4a),LL(0x2205da36,0xd1d426d9), + LL(0xc781a241,0xb3c0f13f),LL(0xd75362a8,0x3e89360e),LL(0xc8a91184,0xccd05863),LL(0xefa8a7f4,0x9bd0c9b7), LL(0x8a912a4b,0x97ee4d53),LL(0xbcf518fd,0xde5e15f8),LL(0xc467e1e0,0x6a055bf8),LL(0x1587e256,0x10be4b4b), + LL(0x668621c9,0xd90c14f2),LL(0xab9c92c1,0xd5518f51),LL(0xd6d47b3c,0x8e6a0100),LL(0x66716175,0xcbe980dd), LL(0xddd83683,0x500d3f10),LL(0x99cac73c,0x3b6cb35d),LL(0x6083d550,0x53730c8b),LL(0xdf0a1987,0xcf159767), + LL(0x43ad73b3,0x84bfcf53),LL(0x4f035a94,0x1b528c20),LL(0x33eeac69,0x4294edf7),LL(0x817f3240,0xb6283e83), LL(0x0a5f25b1,0xc3fdc959),LL(0x5844ee22,0xefaf8aa5),LL(0xdbdde4de,0xde269ba5),LL(0xc56133bf,0xe3347160), + LL(0x8d9ea9f8,0xc1184219),LL(0xf3fc1ab5,0x090de5db),LL(0x0bf22cda,0x404c37b1),LL(0xf5618894,0x7de20ec8), LL(0xecdaecab,0x754c588e),LL(0x88342743,0x6ca4b0ed),LL(0xf4a938ec,0x76f08bdd),LL(0x91493ccb,0xd182de89), + LL(0xc8a4186a,0xd652c53e),LL(0x946d8e33,0xb3e878db),LL(0x5f37663c,0x088453c0),LL(0xb407748b,0x5cd9daaa), LL(0x586d5e72,0xa1f5197f),LL(0xc443ca59,0x47500be8),LL(0xe2652424,0x78ef35b2),LL(0x6dd7767d,0x09c5d26f), + LL(0xa74d3f7b,0x7175a79a),LL(0xcf5ea459,0x0428fd8d),LL(0xa5d1746d,0x511cb97c),LL(0xe71d1278,0x36363939), LL(0x10350bf4,0xcf2df955),LL(0x60aae782,0xb3817439),LL(0x3e688809,0xa748c0e4),LL(0xd7a5a006,0x98021fbf), + LL(0x0e367a98,0x9076a70c),LL(0x0f62b7c2,0xbea1bc15),LL(0x30fe0343,0x2645a68c),LL(0x699dc14f,0xacaffa78), LL(0x457bf9c4,0xf4469964),LL(0x0d2ead83,0x0db6407b),LL(0xb2c6f3eb,0x68d56cad),LL(0xf376356c,0x3b512e73), + LL(0xfce10408,0xe43b0e1f),LL(0x5a5e257d,0x89ddc003),LL(0x0362e5b3,0xb0ae0d12),LL(0xb0519161,0x07f983c7), LL(0x5d5231e7,0xc2e94d15),LL(0x0b4f9513,0xcff22aed),LL(0x6ad0b0b5,0xb02588dd),LL(0x11d0dcd5,0xb967d1ac), + LL(0xcf777b6c,0x8dac6bc6),LL(0x4c6d1959,0x0062bdbd),LL(0x0ef5cc85,0x53da71b5),LL(0x4006f14f,0x07012c7d), LL(0xac47800d,0x4617f962),LL(0xc102ed75,0x53365f2b),LL(0x4ab8c9d3,0xb422efcb),LL(0x34af31c9,0x195cb26b), + LL(0x05f2c4ce,0x3a926e29),LL(0x9856966c,0xbd2bdecb),LL(0x85527015,0x5d16ab3a),LL(0x4486c231,0x9f81609e), LL(0xda350002,0xd8b96b2c),LL(0xfa1b7d36,0xbd054690),LL(0xe71d79bc,0xdc90ebf5),LL(0x08964e4e,0xf241b6f9), + LL(0x2fe3cd4c,0x7c838643),LL(0xb4bc633c,0xe0f33acb),LL(0x3d139f1f,0xb4a9ecec),LL(0xdc4a1f49,0x05ce69cd), LL(0xf5f98aaf,0xa19d1b16),LL(0x6f23e0ef,0x45bb71d6),LL(0x46cdfdd3,0x33789fcd),LL(0xcee040ca,0x9b8e2978), + LL(0xae0a6828,0x9c69b246),LL(0x7078d5aa,0xba533d24),LL(0x7bb4fbdb,0x7a2e42c0),LL(0x7035385c,0xcfb4879a), LL(0x3281705b,0x8c3dd30b),LL(0x404fe081,0x7e361c6c),LL(0x3f604edf,0x7b21649c),LL(0xe52ffe47,0x5dbf6a3f), + LL(0x4b54d9bf,0xc41b7c23),LL(0x3511c3d9,0x1374e681),LL(0xc1b2b758,0x1863bf16),LL(0x1e9e6a96,0x90e78507), LL(0x5d86f174,0xab4bf98d),LL(0x85e96fe4,0xd74e0bd3),LL(0xcac5d344,0x8afde39f),LL(0xbd91b847,0x90946dbc), + LL(0xfe1a838c,0xf5b42358),LL(0x620ac9d8,0x05aae6c5),LL(0xa1ce5a0b,0x8e193bd8),LL(0x4dabfd72,0x8f710571), LL(0x182caaac,0x8d8fdd48),LL(0x040745cf,0x8c4aeefa),LL(0xf3b93e6d,0x73c6c30a),LL(0x16f42011,0x991241f3), + LL(0xe457a477,0xa0158eea),LL(0xee6ddc05,0xd19857db),LL(0x18c41671,0xb3265224),LL(0x3c2c0d58,0x3ffdfc7e), LL(0x26ee7cda,0x3a3a5254),LL(0xdf02c3a8,0x341b0869),LL(0x723bbfc8,0xa023bf42),LL(0x14452691,0x3d15002a), +}, +/* digit=31 base_pwr=2^217 */ +{ + LL(0x85edfa30,0x5ef7324c),LL(0x87d4f3da,0x25976554),LL(0xdcb50c86,0x352f5bc0),LL(0x4832a96c,0x8f6927b0), LL(0x55f2f94c,0xd08ee1ba),LL(0x344b45fa,0x6a996f99),LL(0xa8aa455d,0xe133cb8d),LL(0x758dc1f7,0x5d0721ec), + LL(0x79e5fb67,0x6ba7a920),LL(0x70aa725e,0xe1331feb),LL(0x7df5d837,0x5080ccf5),LL(0x7ff72e21,0xe4cae01d), LL(0x0412a77d,0xd9243ee6),LL(0xdf449025,0x06ff7cac),LL(0x23ef5a31,0xbe75f7cd),LL(0x0ddef7a8,0xbc957822), + LL(0xb0ce1c55,0x8cf7230c),LL(0x0bbfb607,0x5b534d05),LL(0x0e16363b,0xee1ef113),LL(0xb4999e82,0x27e0aa7a), LL(0x79362c41,0xce1dac2d),LL(0x91bb6cb0,0x67920c90),LL(0x2223df24,0x1e648d63),LL(0xe32e8f28,0x0f7d9eef), + LL(0xfa833834,0x6943f39a),LL(0xa6328562,0x22951722),LL(0x4170fc10,0x81d63dd5),LL(0xaecc2e6d,0x9f5fa58f), LL(0xe77d9a3b,0xb66c8725),LL(0x6384ebe0,0x11235cea),LL(0x5845e24a,0x06a8c118),LL(0xebd093b1,0x0137b286), + LL(0x44ace150,0xc589e1ce),LL(0x4381e97c,0xe0f8d3d9),LL(0x62c5a4b8,0x59e99b11),LL(0xfd0ec9f9,0x90d262f7), LL(0x283e13c9,0xfbc854c9),LL(0xaedc7085,0x2d04fde7),LL(0x47dcbecb,0x057d7765),LL(0x9a76fa5f,0x8dbdf591), + LL(0x0de1e578,0xd0150695),LL(0xe9f72bc6,0x2e1463e7),LL(0x1b39eca5,0xffa68441),LL(0x7c037f2f,0x673c8530), LL(0x747f91da,0xd0d6a600),LL(0xc9cb78e9,0xb08d43e1),LL(0x27b5cef5,0x0fc0c644),LL(0xa60a2fd6,0x5c1d160a), + LL(0x28c8e13b,0xf98cae53),LL(0xb2eddcd1,0x375f10c4),LL(0x5cce06ad,0xd4eb8b7f),LL(0x80a2e1ef,0xb4669f45), LL(0x5bbd8699,0xd593f9d0),LL(0xe7976d13,0x5528a4c9),LL(0x1c7e28d3,0x3923e095),LL(0x3f6bb577,0xb9293790), + LL(0xc42bd6d2,0xdb567d6a),LL(0xbb1f96ae,0x6df86468),LL(0x4843b28e,0x0efe5b1a),LL(0x6379b240,0x961bbb05), LL(0x70a6a26b,0xb6caf5f0),LL(0x328e6e39,0x70686c0d),LL(0x895fc8d3,0x80da06cf),LL(0xb363fdc9,0x804d8810), + LL(0x207f1670,0xbe22877b),LL(0x4e615291,0x9b0dd188),LL(0x97a3c2bf,0x625ae8dc),LL(0x439b86e8,0x08584ef7), LL(0xdcd898ff,0xde7190a5),LL(0x2058ee3d,0x26286c40),LL(0x5f87b1c1,0x3db0b217),LL(0x102a6db5,0xcc334771), + LL(0x2f770fb1,0xd99de954),LL(0x4cd7535e,0x97c1c620),LL(0x3f09cefc,0xd3b6c448),LL(0x5a63b4f8,0xd725af15), LL(0xc01e20ec,0x0c95d24f),LL(0x9ae7121f,0xdfd37494),LL(0xec77b7ec,0x7d6ddb72),LL(0x0353a4ae,0xfe079d3b), + LL(0x2e6ac8d2,0x3066e70a),LL(0x106e5c05,0x9c6b5a43),LL(0xede59b8c,0x52d3c6f5),LL(0xfccec9ae,0x30d6a5c3), LL(0x4fc0a9ef,0xedec7c22),LL(0x95c16ced,0x190ff083),LL(0x94de0fde,0xbe12ec8f),LL(0x852d3433,0x0d131ab8), + LL(0x85701291,0x42ace07e),LL(0x194061a8,0x94793ed9),LL(0xd7f4a485,0x30e83ed6),LL(0xf9eeff4d,0x9eec7269), LL(0x0c9d8005,0x90acba59),LL(0x1e79b9d1,0x5feca458),LL(0x1d506a1e,0x8fbe5427),LL(0x2439cfa7,0xa32b2c8e), + LL(0x73dd0b4e,0x1671c173),LL(0x44a054c6,0x37a28214),LL(0x4e8b53f1,0x81760a1b),LL(0xf9f93b9e,0xa6c04224), LL(0xcf671e3c,0x18784b34),LL(0xcda9b994,0x81bbecd2),LL(0xb2ab3848,0x38831979),LL(0xf2e03c2d,0xef54feb7), + LL(0xfb8088fa,0xcf197ca7),LL(0x4ddc96c5,0x01427247),LL(0x30777176,0xa2d2550a),LL(0x4d0cf71d,0x53469898), LL(0x3a2aaac6,0x6ce937b8),LL(0x5af38d9b,0xe9f91dc3),LL(0xc8bf2899,0x2598ad83),LL(0xb5536c16,0x8e706ac9), + LL(0xf688dc98,0x40dc7495),LL(0x124c4afc,0x26490cd7),LL(0x1f18775c,0xe651ec84),LL(0xb4fdaf4a,0x393ea6c3), LL(0x7f338e0d,0x1e1f3343),LL(0x6053e7b5,0x39fb832b),LL(0x619e14d5,0x46e702da),LL(0xcdeef6e0,0x859cacd1), + LL(0x4462007d,0x63b99ce7),LL(0x4cb5f5b7,0xb8ab48a5),LL(0xf55edde7,0x9ec673d2),LL(0x8cfaefda,0xd1567f74), LL(0x0887bcec,0x46381b6b),LL(0xe178f3c2,0x694497ce),LL(0x1e6266cb,0x5e6525e3),LL(0x697d6413,0x5931de26), + LL(0x0e58d493,0x87f8df7c),LL(0x58b73f12,0xb1ae5ed0),LL(0xdea0c34d,0xc368f784),LL(0x859a91a0,0x9bd0a120), LL(0xcc863c68,0xb00d88b7),LL(0x3d1f4d65,0x3a1cc11e),LL(0x0aa85593,0xea38e0e7),LL(0x7dc4aee8,0x37f13e98), + LL(0xbc947bad,0x10d38667),LL(0x2a36ee2e,0x738e07ce),LL(0xc577fcac,0xc93470cd),LL(0x2782470d,0xdee1b616), LL(0x2e793d12,0x36a25e67),LL(0xe0f186da,0xd6aa6cae),LL(0x80e07af7,0x474d0fd9),LL(0xba8a5cd4,0xf7cdc47d), + LL(0xab15247f,0x28af6d9d),LL(0x493a537f,0x7c789c10),LL(0x23a334e7,0x7ac9b110),LL(0x12c9c277,0x0236ac09), LL(0x1d7a5144,0xa7e5bd25),LL(0xf13ec4ec,0x098b9c2a),LL(0xd3f0abca,0x3639daca),LL(0xa23960f9,0x642da81a), + LL(0x4f7269b1,0x7d2e5c05),LL(0xe287c385,0xfcf30777),LL(0xf2a46f21,0x10edc84f),LL(0x4f43fa36,0x35441757), LL(0xfd703431,0xf1327899),LL(0x16dd587a,0xa438d7a6),LL(0xe9c8352d,0x65c34c57),LL(0x5cc5a24e,0xa728edab), + LL(0x42531689,0xaed78abc),LL(0x010963ef,0x0a51a0e8),LL(0xd717d9b3,0x5776fa0a),LL(0x7dd3428b,0xf356c239), LL(0x8d3a3dac,0x29903fff),LL(0x3d94491f,0x409597fa),LL(0xbf4a56a4,0x4cd7a5ff),LL(0x8adab462,0xe5096474), + LL(0x5c3427b0,0xa97b5126),LL(0xd282c9bd,0x6401405c),LL(0x222c5c45,0x3629f8d7),LL(0xe8d50aed,0xb1c02c16), LL(0xd9635bc9,0xbea2ed75),LL(0x6e24552f,0x226790c7),LL(0x65f1d066,0x3c33f2a3),LL(0x6dfccc2e,0x2a43463e), + LL(0xdb483761,0x8cc3453a),LL(0x65d5672b,0xe7cc6085),LL(0xde3efc87,0x277ed6cb),LL(0x69234eaf,0x19f2f368), LL(0x5c0b800b,0x9aaf4317),LL(0x8b6da6e2,0x1f1e7c89),LL(0xb94ec75e,0x6cfb4715),LL(0x453118c2,0xd590dd5f), + LL(0x1f17a34c,0x14e49da1),LL(0x235a1456,0x5420ab39),LL(0x2f50363b,0xb7637241),LL(0xc3fabb6e,0x7b15d623), LL(0xe274e49c,0xa0ef40b1),LL(0x96b1860a,0x5cf50744),LL(0x66afe5a4,0xd6583fbf),LL(0xf47e3e9a,0x44240510), + LL(0x11b2d595,0x99254343),LL(0xeec8df57,0xf1367499),LL(0x3e73dd05,0x3cb12c61),LL(0x7dac102a,0xd248c033), LL(0xa77739f5,0xcf154f13),LL(0x23d2af42,0xbf4288cb),LL(0x32e4a1cf,0xaa64c9b6),LL(0xc8a208f3,0xee8c07a8), + LL(0x6fe8393f,0xe10d4999),LL(0xe91f3a32,0x0f809a3f),LL(0x802f63c8,0x61096d1c),LL(0x57750d3d,0x289e1462), LL(0x9889feea,0xed06167e),LL(0xe0993909,0xd5c9c0e2),LL(0x56508ac6,0x46fca0d8),LL(0x4f1b8e83,0x91826047), + LL(0x9a4a2751,0x4f2c877a),LL(0xcae6fead,0x71bd0072),LL(0x06aa1941,0x38df8dcc),LL(0x63beeaa8,0x5a074b4c), LL(0xc1cec8ed,0xd6d65934),LL(0xaabc03bd,0xa6ecb49e),LL(0xde8a8415,0xaade91c2),LL(0x691136e0,0xcfb0efdf), + LL(0x23ab3495,0x11af45ee),LL(0x0b77463d,0xa132df88),LL(0x815d06f4,0x8923c15c),LL(0x0d61a436,0xc3ceb3f5), LL(0xe88fb1da,0xaf52291d),LL(0x1da12179,0xea057974),LL(0xd2fef720,0xb0d7218c),LL(0x8e1d8845,0x6c0899c9), + LL(0x752ddad7,0x98157504),LL(0xa1a68a97,0xd60bd74f),LL(0xf658fb99,0x7047a3a9),LL(0x5f8511e4,0x1f5d86d6), LL(0x4b5a6d88,0xb8a4bc42),LL(0x1abefa7d,0x69eb2c33),LL(0x13c9c510,0x95bf39e8),LL(0xd48aab43,0xf571960a), + LL(0x704e23c6,0x7e8cfbcf),LL(0x28aaa65b,0xc71b7d22),LL(0x245e3c83,0xa041b2bd),LL(0xd21854ff,0x69b98834), LL(0x963bfeec,0x89d227a3),LL(0xde7da7cb,0x99947aaa),LL(0xee68a9b1,0x1d9ee9db),LL(0x698ec368,0x0a08f003), + LL(0x78ef2487,0xe9ea4094),LL(0x02cfec26,0xc8d2d415),LL(0xb7dcf328,0xc52f9a6e),LL(0x85b6a937,0x0ed489e3), LL(0xbef3366e,0x9b94986b),LL(0xedddddb8,0x0de59c70),LL(0xeadddbe2,0xffdb748c),LL(0x8266ea40,0x9b9784bb), + LL(0x1a93507a,0x142b5502),LL(0x8d3c06cf,0xb4cd1187),LL(0x91ec3f40,0xdf70e76a),LL(0x4e7553c2,0x484e81ad), LL(0x272e9d6e,0x830f87b5),LL(0xc6ff514a,0xea1c93e5),LL(0xc4192a8e,0x67cc2adc),LL(0x42f4535a,0xc77e27e2), + LL(0xd2b713c5,0x9cdbab36),LL(0xcf7b0cd3,0x86274ea0),LL(0x09af826b,0x784680f3),LL(0x0c72dea3,0xbfcc837a), LL(0xd6529b73,0xa8bdfe9d),LL(0x63a88002,0x708aa228),LL(0xc91d45b9,0x6c7a9a54),LL(0xfd004f56,0xdf1a38bb), + LL(0xb8bad853,0x2e8c9a26),LL(0x3723eae7,0x2d52cea3),LL(0x56ca2830,0x054d6d81),LL(0x9a8dc411,0xa3317d14), LL(0xfd4ddeda,0xa08662fe),LL(0xb55d792b,0xed2a153a),LL(0xbfc6e944,0x7035c16a),LL(0x00171cf3,0xb6bc5834), + LL(0x83d102b6,0xe27152b3),LL(0x0646b848,0xfe695a47),LL(0x916e6d37,0xa5bb09d8),LL(0x0d17015e,0xb4269d64), LL(0x0a1d2285,0x8d8156a1),LL(0x46d26d72,0xfeef6c51),LL(0x4c5434a7,0x9dac57c8),LL(0x59d39e31,0x0282e5be), + LL(0x721c486d,0xedfff181),LL(0xbc58824e,0x301baf10),LL(0x00570031,0x8136a6aa),LL(0x1cddde68,0x55aaf78c), LL(0x59c63952,0x26829371),LL(0x8bc25baf,0x3a3bd274),LL(0xb7e52dc3,0xecdf8657),LL(0xfd78e6c8,0x2dd8c087), + LL(0xf5531461,0x20553274),LL(0x5d95499b,0x8b4a1281),LL(0x1a80f9d2,0xe2c8763a),LL(0x4ddec758,0xd1dbe32b), LL(0x30c34169,0xaf12210d),LL(0x78baa533,0xba74a953),LL(0xa438f254,0x3d133c6e),LL(0x201bef5b,0xa431531a), + LL(0xf669d7ec,0x15295e22),LL(0x357fb515,0xca374f64),LL(0xeaa3fdb3,0x8a8406ff),LL(0xdf3f2da8,0x106ae448), LL(0x33c8e9a1,0x8f9b0a90),LL(0x71ad5885,0x234645e2),LL(0x1c0aed14,0x3d083224),LL(0x7a942d46,0xf10a7d3e), + LL(0x40d5c9be,0x7c11deee),LL(0xba84ed98,0xb2bae7ff),LL(0xaad58ddd,0x93e97139),LL(0x3f6d1fa3,0x3d872796), LL(0x8569ff13,0x483aca81),LL(0x9a600f72,0x8b89a5fb),LL(0xc06f2b86,0x4cbc27c3),LL(0x63ad9c0b,0x22130713), + LL(0x48ac2840,0xb5358b1e),LL(0xecba9477,0x18311294),LL(0xa6946b43,0xda58f990),LL(0x9ab41819,0x3098baf9), LL(0x4198da52,0x66c4c158),LL(0x146bfd1b,0xab4fc17c),LL(0xbf36a908,0x2f0a4c3c),LL(0x58cf7838,0x2ae9e34b), + LL(0x3fa11b1f,0xf411529e),LL(0x974af2b4,0x21e43677),LL(0xc230793b,0x7c20958e),LL(0x16e840f3,0x710ea885), LL(0xc5dc67cf,0xfc0b21fc),LL(0x88405718,0x08d51647),LL(0xcfe49eb7,0xd955c21f),LL(0x56dd4a1f,0x9722a5d5), + LL(0xc861baa5,0xc9ef50e2),LL(0x9505ac3e,0xc0c21a5d),LL(0x8b7c063f,0xaf6b9a33),LL(0x2f4779c1,0xc6370339), LL(0x638167c3,0x22df99c7),LL(0x795db30c,0xfe6ffe76),LL(0xa4854989,0x2b822d33),LL(0x30563aa5,0xfef031dd), + LL(0xd57c667f,0x16b09f82),LL(0xcc0b76f1,0xc70312ce),LL(0xc9118aec,0xbf04a9e6),LL(0x3409d133,0x82fcb419), LL(0xab45d44d,0x1a8ab385),LL(0x617b83a3,0xfba07222),LL(0x58e81b52,0xb05f50dd),LL(0x21ce5aff,0x1d8db553), + LL(0xe344a873,0x3097b8d4),LL(0xfe36d53e,0x7d8d116d),LL(0x7875e750,0x6db22f58),LL(0x43e144ea,0x2dc5e373), LL(0xe799eb95,0xc05f32e6),LL(0x6899e6ec,0xe9e5f4df),LL(0x1fab23d5,0xbdc3bd68),LL(0x73af60e6,0xb72b8ab7), + LL(0x2cecc84a,0x8db27ae0),LL(0x7bdb871c,0x600016d8),LL(0xd7c46f58,0x42a44b13),LL(0xc3a77d39,0xb8919727), LL(0xdafd6088,0xcfc6bbbd),LL(0x6bd20d39,0x1a740146),LL(0x98c41072,0x8c747abd),LL(0xbdf68ea1,0x4c91e765), + LL(0x08819a78,0x7c95e5ca),LL(0xc9587921,0xcf48b729),LL(0xdebbcc7d,0x091c7c5f),LL(0xf0e05149,0x6f287404), LL(0x26cd44ec,0xf83b5ac2),LL(0xcfea250e,0x88ae32a6),LL(0x1d06ebc5,0x6ac5047a),LL(0xd434f781,0xc7e550b4), + LL(0x5c727bd2,0x61ab1cf2),LL(0x1cf915b0,0x2e4badb1),LL(0xf69d3920,0x1b4dadec),LL(0xf14c1dfe,0xe61b1ca6), LL(0xbd6bd51f,0x90b479cc),LL(0x8045ec30,0x8024e401),LL(0x25ef0e62,0xcab29ca3),LL(0x49e4ebc0,0x4f2e9416), + LL(0x0ccced58,0x45eb40ec),LL(0x0da44f98,0x25cd4b9c),LL(0x871812c6,0x43e06458),LL(0x16cef651,0x99f80d55), LL(0xce6dc153,0x571340c9),LL(0xd8665521,0x138d5117),LL(0x4e07014d,0xacdb45bc),LL(0x84b60b91,0x2f34bb38), + LL(0x2ae8921e,0xf44a4fd2),LL(0x892ba1e2,0xb039288e),LL(0xb1c180b2,0x9da50174),LL(0x1693dc87,0x6b70ab66), LL(0xe7057481,0x7e9babc9),LL(0x9c80dc41,0x4581ddef),LL(0x51294682,0x0c890da9),LL(0x3f4736e5,0x0b5629d3), + LL(0xb06f5b41,0x2340c79e),LL(0x4e243469,0xa42e84ce),LL(0x045a71a9,0xf9a20135),LL(0xd27b6fb6,0xefbfb415), LL(0x9d33cd6f,0x25ebea23),LL(0xaa6c0af8,0x9caedb88),LL(0xd9ce6f96,0x53dc7e9a),LL(0x51e0b15a,0x3897f9fd), + LL(0x8e5d788e,0xf51cb1f8),LL(0xe1d490ee,0x1aec7ba8),LL(0xcc58cb3c,0x265991e0),LL(0x9fc3ad31,0x9f306e8c), LL(0x5040a0ac,0x5fed006e),LL(0xfb476f2e,0xca9d5043),LL(0xbeea7a23,0xa19c06e8),LL(0x0edabb63,0xd2865801), + LL(0x6967469a,0xdb92293f),LL(0x8d8a8ed8,0x2894d839),LL(0xbbc77122,0x87c9e406),LL(0x2ea3a26a,0x8671c6f1), LL(0xd7de9853,0xe42df8d6),LL(0xb1f2bcc7,0x2e3ce346),LL(0x899d50cf,0xda601dfc),LL(0xfb1b598f,0xbfc913de), + LL(0xe61f7908,0x81c4909f),LL(0x9bbc7b29,0x192e304f),LL(0xc104b338,0xc3ed8738),LL(0x783f5d61,0xedbe9e47), LL(0x2db30660,0x0c06e9be),LL(0xc0eb7d8e,0xda3e613f),LL(0x322e096e,0xd8fa3e97),LL(0xd336e247,0xfebd91e8), + LL(0xdf655a49,0x8f13ccc4),LL(0x5eb20210,0xa9e00dfc),LL(0xc656b6ea,0x84631d0f),LL(0xd8c0d947,0x93a058cd), LL(0x67bd3448,0x6846904a),LL(0xf394fd5c,0x4a3d4e1a),LL(0xdb225f52,0xc102c1a5),LL(0xfc4f5e9a,0xe3455bba), + LL(0x4b9ad1ce,0x6b36985b),LL(0x5bb7f793,0xa9818536),LL(0x48b1a416,0x6c25e1d0),LL(0x3c81bee7,0x1381dd53), LL(0x7a4a7620,0xd2a30d61),LL(0x39b8944c,0xc8412926),LL(0x7a97c33a,0x3c1c6fbe),LL(0x938664e7,0x941e541d), + LL(0x4a34f239,0x417499e8),LL(0xb90402d5,0x15fdb83c),LL(0x433aa832,0xb75f46bf),LL(0x63215db1,0xb61e15af), LL(0xa127f89a,0xaabe59d4),LL(0x07e816da,0x5d541e0c),LL(0xa618b692,0xaaba0659),LL(0x17266026,0x55327733), + LL(0x95f57552,0xaf53a0fc),LL(0x6cacb0c9,0x32947650),LL(0xc821be01,0x253ff58d),LL(0xa06f1146,0xb0309531), LL(0x05c2e54d,0x59bbbdf5),LL(0x26e8dd22,0x158f27ad),LL(0x397e1e53,0xcc5b7ffb),LL(0x7fc1e50d,0xae03f65b), + LL(0x9c95f0f9,0xa9784ebd),LL(0x24640771,0x5ed9deb2),LL(0x035561c4,0x31244af7),LL(0x7ee857de,0x87332f3a), LL(0x2b9e0d88,0x09e16e9e),LL(0x56a06049,0x52d910f4),LL(0xa9592f48,0x507ed477),LL(0x2365d678,0x85cb917b), + LL(0x4c8998d1,0xf8511c93),LL(0x730ea58f,0x2186a3f1),LL(0xb2029db0,0x50189626),LL(0x02ceb75a,0x9137a6d9), LL(0x748bc82c,0x2fe17f37),LL(0x80469f8c,0x87c2e931),LL(0xbf891aa2,0x850f71cd),LL(0x75ec3d8d,0x0ca1b89b), + LL(0x5e1cd3cd,0x516c43aa),LL(0x9a887c28,0x89397808),LL(0xddea1f9f,0x0059c699),LL(0x8e6868f7,0x7737d6fa), LL(0x60f1524b,0x6d93746a),LL(0xba052aa7,0x36985e55),LL(0xed923ea5,0x41b1d322),LL(0x25852a11,0x3429759f), + LL(0x092e9f41,0xbeca6ec3),LL(0x62256bbd,0x3a238c66),LL(0x70ad487d,0xd82958ea),LL(0x65610d93,0x4ac8aaf9), LL(0x5e4ccab0,0x3fa101b1),LL(0x9de14bfb,0x9bf430f2),LL(0x6531899d,0xa10f5cc6),LL(0xea8ce17d,0x590005fb), + LL(0x24544cb6,0xc437912f),LL(0xd79ac2e3,0x9987b71a),LL(0xc058a212,0x13e3d9dd),LL(0xd2de9606,0x00075aac), LL(0x6cac8369,0x80ab508b),LL(0xf54f6c89,0x87842be7),LL(0x6bc532a4,0xa7ad663d),LL(0x78a91bc8,0x67813de7), + LL(0xc3427239,0x5dcb61ce),LL(0xc56934d9,0x5f3c7cf0),LL(0xe3191591,0xc079e0fb),LL(0xb01aada7,0xe40896bd), LL(0x0492d25f,0x8d466791),LL(0xe7408276,0x8aeb30c9),LL(0x9287aacc,0xe9437495),LL(0x79fe03d4,0x23d4708d), + LL(0xd0c05199,0x8cda9cf2),LL(0xfae78454,0x502fbc22),LL(0xf572a182,0xc0bda9df),LL(0x6158b372,0x5f9b71b8), LL(0x2b82dd07,0xe0f33a59),LL(0x9523032e,0x76302735),LL(0xc4505a32,0x7fe1a721),LL(0xf796409f,0x7b6e3e82), +}, +/* digit=32 base_pwr=2^224 */ +{ + LL(0x35d0b34a,0xe3417bc0),LL(0x8327c0a7,0x440b386b),LL(0xac0362d1,0x8fb7262d),LL(0xe0cdf943,0x2c41114c), LL(0xad95a0b1,0x2ba5cef1),LL(0x67d54362,0xc09b37a8),LL(0x01e486c9,0x26d6cdd2),LL(0x42ff9297,0x20477abf), + LL(0x292a9287,0xa004dcb3),LL(0x77b092c7,0xddc15cf6),LL(0x806c0605,0x083a8464),LL(0x3db997b0,0x4a68df70), LL(0x05bf7dd0,0x9c134e45),LL(0x8ccf7f8c,0xa4e63d39),LL(0x41b5f8af,0xa6e6517f),LL(0xad7bc1cc,0xaa8b9342), + LL(0x1e706ad9,0x126f35b5),LL(0xc3a9ebdf,0xb99cebb4),LL(0xbf608d90,0xa75389af),LL(0xc6c89858,0x76113c4f), LL(0x97e2b5aa,0x80de8eb0),LL(0x63b91304,0x7e1022cc),LL(0x6ccc066c,0x3bdab605),LL(0xb2edf900,0x33cbb144), + LL(0x7af715d2,0xc4176471),LL(0xd0134a96,0xe2f7f594),LL(0xa41ec956,0x2c1873ef),LL(0x77821304,0xe4e7b4f6), LL(0x88d5374a,0xe5c8ff97),LL(0x80823d5b,0x2b915e63),LL(0xb2ee8fe2,0xea6bc755),LL(0xe7112651,0x6657624c), + LL(0xdace5aca,0x157af101),LL(0x11a6a267,0xc4fdbcf2),LL(0xc49c8609,0xdaddf340),LL(0xe9604a65,0x97e49f52), LL(0x937e2ad5,0x9be8e790),LL(0x326e17f1,0x846e2508),LL(0x0bbbc0dc,0x3f38007a),LL(0xb11e16d6,0xcf03603f), + LL(0x7442f1d5,0xd6f800e0),LL(0x66e0e3ab,0x475607d1),LL(0xb7c64047,0x82807f16),LL(0xa749883d,0x8858e1e3), LL(0x8231ee10,0x5859120b),LL(0x638a1ece,0x1b80e7eb),LL(0xc6aa73a4,0xcb72525a),LL(0x844423ac,0xa7cdea3d), + LL(0xf8ae7c38,0x5ed0c007),LL(0x3d740192,0x6db07a5c),LL(0x5fe36db3,0xbe5e9c2a),LL(0x76e95046,0xd5b9d57a), LL(0x8eba20f2,0x54ac32e7),LL(0x71b9a352,0xef11ca8f),LL(0xff98a658,0x305e373e),LL(0x823eb667,0xffe5a100), + LL(0xe51732d2,0x57477b11),LL(0x2538fc0e,0xdfd6eb28),LL(0x3b39eec5,0x5c43b0cc),LL(0xcb36cc57,0x6af12778), LL(0x06c425ae,0x70b0852d),LL(0x5c221b9b,0x6df92f8c),LL(0xce826d9c,0x6c8d4f9e),LL(0xb49359c3,0xf59aba7b), + LL(0xda64309d,0x5c8ed8d5),LL(0x91b30704,0x61a6de56),LL(0x2f9b5808,0xd6b52f6a),LL(0x98c958a7,0x0eee4194), LL(0x771e4caa,0xcddd9aab),LL(0x78bc21be,0x83965dfd),LL(0xb3b504f5,0x02affce3),LL(0x561c8291,0x30847a21), + LL(0x52bfda05,0xd2eb2cf1),LL(0x6197b98c,0xe0e4c4e9),LL(0xf8a1726f,0x1d35076c),LL(0x2db11e3d,0x6c06085b), LL(0x4463ba14,0x15c0c4d7),LL(0x0030238c,0x9d292f83),LL(0x3727536d,0x1311ee8b),LL(0xbeaedc1e,0xfeea86ef), + LL(0x66131e2e,0xb9d18cd3),LL(0x80fe2682,0xf31d974f),LL(0xe4160289,0xb6e49e0f),LL(0x08e92799,0x7c48ec0b), LL(0xd1989aa7,0x818111d8),LL(0xebf926f9,0xb34fa0aa),LL(0xa245474a,0xdb5fe2f5),LL(0x3c7ca756,0xf80a6ebb), + LL(0xafa05dd8,0xa7f96054),LL(0xfcaf119e,0x26dfcf21),LL(0x0564bb59,0xe20ef2e3),LL(0x61cb02b8,0xef4dca50), LL(0x65d30672,0xcda7838a),LL(0xfd657e86,0x8b08d534),LL(0x46d595c8,0x4c5b4395),LL(0x425cb836,0x39b58725), + LL(0x3de9abe3,0x8ea61059),LL(0x9cdc03be,0x40434881),LL(0xcfedce8c,0x9b261245),LL(0xcf5234a1,0x78c318b4), LL(0xfde24c99,0x510bcf16),LL(0xa2c2ff5d,0x2a77cb75),LL(0x27960fb4,0x9c895c2b),LL(0xb0eda42b,0xd30ce975), + LL(0x1a62cc26,0xfda85393),LL(0x50c0e052,0x23c69b96),LL(0xbfc633f3,0xa227df15),LL(0x1bae7d48,0x2ac78848), LL(0x187d073d,0x487878f9),LL(0x967f807d,0x6c2be919),LL(0x336e6d8f,0x765861d8),LL(0xce528a43,0x88b8974c), + LL(0xff57d051,0x09521177),LL(0xfb6a1961,0x2ff38037),LL(0xa3d76ad4,0xfc0aba74),LL(0x25a7ec17,0x7c764803), LL(0x48879bc8,0x7532d75f),LL(0x58ce6bc1,0xea7eacc0),LL(0x8e896c16,0xc82176b4),LL(0x2c750fed,0x9a30e0b2), + LL(0x421d3aa4,0xc37e2c2e),LL(0xe84fa840,0xf926407c),LL(0x1454e41c,0x18abc03d),LL(0x3f7af644,0x26605ecd), LL(0xd6a5eabf,0x242341a6),LL(0x216b668e,0x1edb84f4),LL(0x04010102,0xd836edb8),LL(0x945e1d8c,0x5b337ce7), + LL(0xc055dc14,0xd2075c77),LL(0x81d89cdf,0x2a0ffa25),LL(0x6ffdcbaf,0x8ce815ea),LL(0xfb648867,0xa3428878), LL(0x884655fb,0x277699cf),LL(0x364d3e41,0xfa5b5bd6),LL(0x441e1cb7,0x01f680c6),LL(0xb70a7d67,0x3fd61e66), + LL(0xcc78cf66,0x666ba2dc),LL(0x6fdbff77,0xb3018174),LL(0x168d4668,0x8d4dd0db),LL(0x1dab3a2a,0x259455d0), LL(0xcde3acec,0xf58564c5),LL(0x13adb276,0x77141925),LL(0x8a303f65,0x527d725d),LL(0xe6f38f7b,0x55deb6c9), + LL(0xb1fa70fb,0xfd5bb657),LL(0xd8073a00,0xfa07f50f),LL(0xbca02500,0xf72e3aa7),LL(0x9975740d,0xf68f895d), LL(0x5cae2a6a,0x30112060),LL(0x02874842,0x01bd7218),LL(0x7ce47bd3,0x3d423891),LL(0x789544f6,0xa66663c1), + LL(0x3272d838,0x864d05d7),LL(0xfa6295c5,0xe22924f9),LL(0x6c2fda32,0x8189593f),LL(0xb184b544,0x330d7189), LL(0xbde1f714,0x79efa62c),LL(0xe5cb1a63,0x35771c94),LL(0x641c8332,0x2f4826b8),LL(0xc8cee854,0x00a894fb), + LL(0x36194d40,0xb4b9a39b),LL(0x77612601,0xe857a7c5),LL(0x4ecf2f58,0xf4209dd2),LL(0x5a033487,0x82b9e66d), LL(0xe4e8b9dd,0xc1e36934),LL(0xa42377d7,0xd2372c9d),LL(0x0e3ae43b,0x51dc94c7),LL(0x04474f6f,0x4c57761e), + LL(0x1058a318,0xdcdacd0a),LL(0x78053a9a,0x369cf3f5),LL(0x31c68de2,0xc6c3de50),LL(0x3c4b6d9f,0x4653a576), LL(0xaa4e5c97,0x1688dd5a),LL(0xb7ab3c74,0x5be80aa1),LL(0xbc65c283,0x70cefe7c),LL(0x06867091,0x57f95f13), + LL(0x4415503b,0xa39114e2),LL(0x4cbb17e9,0xc08ff7c6),LL(0xd7dec966,0x1eff674d),LL(0x53376f63,0x6d4690af), LL(0xea74237b,0xff6fe32e),LL(0xcd57508e,0xc436d17e),LL(0xedcc40fe,0x15aa28e1),LL(0x581bbb44,0x0d769c04), + LL(0x34eaacda,0xc240b6de),LL(0x2ba0f1de,0xd9e116e8),LL(0x79438e55,0xcbe45ec7),LL(0x96f752d7,0x91787c9d), LL(0xf129ac2f,0x897f532b),LL(0x5a36e22c,0xd307b7c8),LL(0x749fb8f3,0x91940675),LL(0x157fdb28,0xd14f95d0), + LL(0x6ae55043,0xfe51d029),LL(0x44a87de1,0x8931e98f),LL(0x09e4fee2,0xe57f1cc6),LL(0x4e072d92,0x0d063b67), LL(0xed0e4316,0x70a998b9),LL(0x306aca46,0xe74a736b),LL(0x4fda97c7,0xecf0fbf2),LL(0x3e178d93,0xa40f65cb), + LL(0x16df4285,0x16253604),LL(0xd0c56ae2,0xb0c9babb),LL(0xcfc5cfc3,0x73032b19),LL(0x09752056,0xe497e5c3), LL(0x164bda96,0x12096bb4),LL(0xa0b74da1,0x1ee42419),LL(0x403826ba,0x8fc36243),LL(0xdc09e660,0x0c8f0069), + LL(0xc27253c9,0x8667e981),LL(0x92b36a45,0x05a6aefb),LL(0x9cb7bb46,0xa62c4b36),LL(0x11f7027b,0x8394f375), LL(0x5f109d0f,0x747bc79c),LL(0x5b8cc60a,0xcad88a76),LL(0x58f09e68,0x80c5a66b),LL(0xf6127eac,0xe753d451), + LL(0x5b0ec6f5,0xc44b74a1),LL(0x5289b2b8,0x47989fe4),LL(0x58d6fc73,0x745f8484),LL(0xf61c70ab,0xec362a6f), LL(0xb3a8ad41,0x070c98a7),LL(0x7b63db51,0x73a20fc0),LL(0xf44c35f4,0xed2c2173),LL(0x9acc9dca,0x8a56149d), + LL(0x9ac6e0f4,0x98f17881),LL(0xa413b5ed,0x360fdeaf),LL(0xa300b0fd,0x0625b8f4),LL(0x5b3222d3,0xf1f4d76a), LL(0x587f76b8,0x9d6f5109),LL(0x2317fdb5,0x8b4ee08d),LL(0x8c68b095,0x88089bb7),LL(0x5808d9b9,0x95570e9a), + LL(0x35d33ae7,0xa395c36f),LL(0x50bb5a94,0x200ea123),LL(0x0bafe84b,0x20c789bd),LL(0x0919276a,0x243ef52d), LL(0xe23ae233,0x3934c577),LL(0xa460d1ec,0xb93807af),LL(0xf8fa76a4,0xb72a53b1),LL(0xc3ca4491,0xd8914cb0), + LL(0x3fb42622,0x2e128494),LL(0x500907d5,0x3b2700ac),LL(0x1a95ec63,0xf370fb09),LL(0x31b6dfbd,0xf8f30be2), LL(0x69e55f15,0xf2b2f8d2),LL(0xcc1323e9,0x1fead851),LL(0xd9e5eef6,0xfa366010),LL(0xe316107e,0x64d487b0), + LL(0xd23ddc82,0x4c076b86),LL(0x7e0143f0,0x03fd344c),LL(0x317af2c5,0xa95362ff),LL(0xe18b7a4f,0x0add3db7), LL(0x8260e01b,0x9c673e3f),LL(0x54a1cc91,0xfbeb49e5),LL(0x92f2e433,0x91351bf2),LL(0x851141eb,0xc755e7ec), + LL(0x29607745,0xc9a95139),LL(0xa26f2b28,0x0ca07420),LL(0x4bc6f9dd,0xcb2790e7),LL(0xadcaffc0,0x345bbb58), LL(0xbe0f27a2,0xc65ea38c),LL(0x641fcb56,0x67c24d7c),LL(0xa9e2c757,0x2c25f0a7),LL(0x16f16c49,0x93f5cdb0), + LL(0xc5ee30a1,0x2ca5a9d7),LL(0xb909b729,0xd1593635),LL(0xdadeff48,0x804ce9f3),LL(0xb07c30c3,0xec464751), LL(0x9e49af6a,0x89d65ff3),LL(0x6f3d01bc,0xf2d6238a),LL(0x0bced843,0x1095561e),LL(0xc8a13fd8,0x51789e12), + LL(0x763231df,0xd633f929),LL(0xe7cbddef,0x46df9f7d),LL(0xcb265da8,0x01c889c0),LL(0xaf4336d2,0xfce1ad10), LL(0xfc6a0a7e,0x8d110df6),LL(0x6da425dc,0xdd431b98),LL(0x1834aabe,0xcdc4aeab),LL(0x8439b7fc,0x84deb124), + LL(0x3c2a5998,0x8796f169),LL(0x7947190d,0x9b9247b4),LL(0x11597014,0x55b9d9a5),LL(0x7b1566ee,0x7e9dd70d), LL(0xcbcd5e64,0x94ad78f7),LL(0x9bd4c032,0x0359ac17),LL(0x7cc222ae,0x3b11baaf),LL(0xba78e812,0xa6a6e284), + LL(0x24cea1a0,0x8392053f),LL(0x33621491,0xc97bce4a),LL(0x35399ee9,0x7eb1db34),LL(0xece81ad1,0x473f78ef), LL(0xf63d3d0d,0x41d72fe0),LL(0xafab62fc,0xe620b880),LL(0x93158383,0x92096bc9),LL(0x8f896f6c,0x41a21357), + LL(0xc7dcfcab,0x1b5ee2fa),LL(0x9546e007,0x650acfde),LL(0xb1b02e07,0xc081b749),LL(0xf9eca03d,0xda9e41a0), LL(0x175a54ab,0x013ba727),LL(0xea5d8d10,0xca0cd190),LL(0x95fd96a9,0x85ea52c0),LL(0xbc5c3940,0x2c591b9f), + LL(0x2bad4d5f,0x6fb4d4e4),LL(0xfef0059b,0xfa4c3590),LL(0xf5122294,0x6a10218a),LL(0xa85751d1,0x9a78a81a), LL(0xa98e84e7,0x04f20579),LL(0x4997e5b5,0xfe1242c0),LL(0xca21e1e4,0xe77a273b),LL(0x9411939d,0xfcc8b1ef), + LL(0x92d0487a,0xe20ea302),LL(0x294b91fe,0x1442dbec),LL(0xbb6b0e8f,0x1f7a4afe),LL(0x6889c318,0x1700ef74), LL(0x70f1fc62,0xf5bbffc3),LL(0x69c79cca,0x3b31d4b6),LL(0xa7f6340d,0xe8bc2aab),LL(0xa725e10a,0xb0b08ab4), + LL(0xae340050,0x44f05701),LL(0x1cf0c569,0xba4b3016),LL(0xfbe19a51,0x5aa29f83),LL(0xb71d752e,0x1b9ed428), LL(0xeb4819f5,0x1666e54e),LL(0x9e18b75b,0x616cdfed),LL(0x3ee27b0b,0x112ed5be),LL(0x44c7de4d,0xfbf28319), + LL(0xe0e60d84,0xd685ec85),LL(0x1db7ee78,0x68037e30),LL(0x003c4d6e,0x5b65bdcd),LL(0x93e29a6a,0x33e7363a), LL(0x08d0756c,0x995b3a61),LL(0x2faf134b,0xd727f85c),LL(0x1d337823,0xfac6edf7),LL(0x0439b8b4,0x99b9aa50), + LL(0xe2b4e075,0x722eb104),LL(0x437c4926,0x49987295),LL(0x46a9b82d,0xb1e4c0e4),LL(0x57a006f5,0xd0cb3197), LL(0xd7808c56,0xf3de0f7d),LL(0x51f89772,0xb5c54d8f),LL(0xadbd31aa,0x500a114a),LL(0x295f6cab,0x9afaaaa6), + LL(0x04cf667a,0x94705e21),LL(0x9d3935d7,0xfc2a811b),LL(0x6d09267c,0x560b0280),LL(0xf780e53b,0xf19ed119), LL(0x067b6269,0xf0227c09),LL(0x5caef599,0x967b8533),LL(0x68efeebc,0x155b9243),LL(0xc497bae6,0xcd6d34f5), + LL(0x6cceb370,0x1dd8d5d3),LL(0xa78d7bf9,0x2aeac579),LL(0x70b67a62,0x5d65017d),LL(0x17c53f67,0x70c8e44f), LL(0x86a34d09,0xd1fc0950),LL(0xe7134907,0xe0fca256),LL(0x80fdd315,0xe24fa29c),LL(0xd87499ad,0x2c4acd03), + LL(0x3b5a9ba6,0xbaaf7517),LL(0x12e51a51,0xb9cbe1f6),LL(0x5e154897,0xd88edae3),LL(0x77b66ca0,0xe4309c3c), LL(0xf67f3746,0xf5555805),LL(0xa36401ff,0x85fc37ba),LL(0xd9499a53,0xdf86e2ca),LL(0xecbc955b,0x6270b2a3), + LL(0x974ad33b,0xafae64f5),LL(0xfe7b2df1,0x04d85977),LL(0x4ab03f73,0x2a3db3ff),LL(0x8702740a,0x0b87878a), LL(0x5a061732,0x6d263f01),LL(0xa32a1901,0xc25430ce),LL(0xdb155018,0xf7ebab3d),LL(0x63a9b78e,0x3a86f693), + LL(0xda9f3804,0x349ae368),LL(0xa164349c,0x470f07fe),LL(0x8562baa5,0xd52f4cc9),LL(0x2b290df3,0xc74a9e86), LL(0x43471a24,0xd3a1aa35),LL(0xb8194511,0x239446be),LL(0x81dcd44d,0xbec2dd00),LL(0xc42ac82d,0xca3d7f0f), + LL(0xfdaf4520,0x1f3db085),LL(0x4549daf2,0xbb6d3e80),LL(0x19ad5c42,0xf5969d8a),LL(0xdbfd1511,0x7052b13d), LL(0x682b9060,0x11890d1b),LL(0xac34452c,0xa71d3883),LL(0x783805b4,0xa438055b),LL(0x4725b23e,0x43241277), + LL(0x4901bbed,0xf20cf96e),LL(0xf432a2bb,0x6419c710),LL(0xdfa9cd7d,0x57a0fbb9),LL(0x00daa249,0x589111e4), LL(0x7b60554e,0x19809a33),LL(0xede283a4,0xea5f8887),LL(0x503bfd35,0x2d713802),LL(0x585d2a53,0x151bb0af), + LL(0x43b30ca8,0x40b08f74),LL(0xd9934583,0xe10b5bba),LL(0xb51110ad,0xe8a546d6),LL(0x28e0b6c5,0x1dd50e66), LL(0xcff2b821,0x292e9d54),LL(0x47281760,0x3882555d),LL(0x3724d6e3,0x134838f8),LL(0x22ddcda1,0xf2c679e0), + LL(0x6d2a5768,0x40ee8815),LL(0x1c1e7e2d,0x7f227bd2),LL(0xd04ff443,0x487ba134),LL(0xc614e54b,0x76e2ff3d), LL(0xa3177ec7,0x36b88d6f),LL(0x2328fff5,0xbf731d51),LL(0x49ba158e,0x758caea2),LL(0x02938188,0x5ab8ff4c), + LL(0x35edc56d,0x33e16056),LL(0x7e940d79,0x5a69d349),LL(0x03866dcb,0x6c4fd001),LL(0x4893cdef,0x20a38f57), LL(0xfac3a15b,0xfbf3e790),LL(0x7a4f8e6b,0x6ed7ea2e),LL(0xbc3aca86,0xa663eb4f),LL(0x080d53f7,0x22061ea5), + LL(0xf546783f,0x2480dfe6),LL(0x5a0a641e,0xd38bc6da),LL(0x2ede8965,0xfb093cd1),LL(0xacb455cf,0x89654db4), LL(0x26e1adee,0x413cbf9a),LL(0x373294d4,0x291f3764),LL(0x648083fe,0x00797257),LL(0x208cc341,0x25f504d3), + LL(0xc3a0ee43,0x635a8e5e),LL(0x679898ff,0x70aaebca),LL(0x5dc63d56,0x9ee9f547),LL(0xffb34d00,0xce987966), LL(0x5e26310a,0xf9f86b19),LL(0x382a8ca8,0x9e435484),LL(0xc2352fe4,0x253bcb81),LL(0x4474b571,0xa4eac8b0), + LL(0xc1ad8cf8,0xc1b97512),LL(0x99e0b697,0x193b4e9e),LL(0x01e85df0,0x939d2716),LL(0xcd44eafd,0x4fb265b3), LL(0xe51e1ae2,0x321e7dcd),LL(0xe3d8b096,0x8e3a8ca6),LL(0x52604998,0x8de46cb0),LL(0x39072aa7,0x91099ad8), + LL(0x93aa96b8,0x2617f91c),LL(0x7fca2e13,0x0fc8716b),LL(0x95328723,0xa7106f5e),LL(0x262e6522,0xd1c9c40b), LL(0x42b7c094,0xb9bafe86),LL(0x1543c021,0x1873439d),LL(0x5cbefd5d,0xe1baa5de),LL(0x521e8aff,0xa363fc5e), + LL(0xf862eaac,0xefe6320d),LL(0x22c647dc,0x14419c63),LL(0x4e46d428,0x0e06707c),LL(0x4a178f8f,0xcb6c834f), LL(0xd30f917c,0x0f993a45),LL(0x9879afee,0xd4c4b049),LL(0x70500063,0xb6142a1e),LL(0xa5d9d605,0x7c9b41c3), + LL(0x2f8ba2c7,0xbc00fc2f),LL(0x7c67aa28,0x0966eb2f),LL(0x5a786972,0x13f7b516),LL(0x8a2fbba0,0x3bfb7557), LL(0x5a2b9620,0x131c4f23),LL(0x6faf46be,0xbff3ed27),LL(0x7e172323,0x9b4473d1),LL(0x339f6246,0x421e8878), + LL(0x25a41632,0x0fa8587a),LL(0xa35b6c93,0xc0814124),LL(0x59ebb8db,0x2b18a9f5),LL(0x76edb29c,0x264e3357), LL(0xc87c51e2,0xaf245ccd),LL(0x501e6214,0x16b3015b),LL(0x0a3882ce,0xbb31c560),LL(0xfec11e04,0x6961bb94), + LL(0xeff7a3a0,0x3b825b8d),LL(0xb1df7326,0xbec33738),LL(0x99604a1f,0x68ad747c),LL(0x9a3bd499,0xd154c934), LL(0x1cc7a906,0xac33506f),LL(0x6c560e8f,0x73bb5392),LL(0x263e3944,0x6428fcbe),LL(0x1c387434,0xc11828d5), + LL(0x3e4b12ff,0x3cd04be1),LL(0x2d88667c,0xc3aad9f9),LL(0x248120cf,0xc52ddcf8),LL(0x2a389532,0x985a892e), LL(0x3bb85fa0,0xfbb4b21b),LL(0x8dfc6269,0xf95375e0),LL(0x7ee2acea,0xfb4fb06c),LL(0x309c4d1f,0x6785426e), + LL(0xd8ceb147,0x659b17c8),LL(0xb70a5554,0x9b649eee),LL(0xac6bc634,0x6b7fa0b5),LL(0x1d6e732f,0xd99fe2c7), LL(0x8d3abba2,0x30e6e762),LL(0xa797b799,0x18fee6e7),LL(0xc696464d,0x5c9d360d),LL(0x27bfde12,0xe3baeb48), + LL(0xf23206d5,0x2bf5db47),LL(0x1d260152,0x2f6d3420),LL(0x3f8ff89a,0x17b87653),LL(0x378fa458,0x5157c30c), LL(0x2d4fb936,0x7517c5c5),LL(0xe6518cdc,0xef22f7ac),LL(0xbf847a64,0xdeb483e6),LL(0x92e0fa89,0xf5084558), +}, +/* digit=33 base_pwr=2^231 */ +{ + LL(0xdf7304d4,0xab9659d8),LL(0xff210e8e,0xb71bcf1b),LL(0xd73fbd60,0xa9a2438b),LL(0x5d11b4de,0x4595cd1f), LL(0x4835859d,0x9c0d329a),LL(0x7dbb6e56,0x4a0f0d2d),LL(0xdf928a4e,0xc6038e5e),LL(0x8f5ad154,0xc9429621), + LL(0xf23f2d92,0x91213462),LL(0x60b94078,0x6cab71bd),LL(0x176cde20,0x6bdd0a63),LL(0xee4d54bc,0x54c9b20c), LL(0x9f2ac02f,0x3cd2d8aa),LL(0x206eedb0,0x03f8e617),LL(0x93086434,0xc7f68e16),LL(0x92dd3db9,0x831469c5), + LL(0x8f981354,0x8521df24),LL(0x3588a259,0x587e23ec),LL(0xd7a0992c,0xcbedf281),LL(0x38961407,0x06930a55), LL(0xbe5bbe21,0x09320deb),LL(0x2491817f,0xa7ffa5b5),LL(0x09065160,0xe6c8b4d9),LL(0xfff6d2a9,0xac4f3992), + LL(0x3ae9c1bd,0x7aa7a158),LL(0xe37ce240,0xe0af6d98),LL(0x28ab38b4,0xe54342d9),LL(0x0a1c98ca,0xe8b75007), LL(0xe02358f2,0xefce86af),LL(0xea921228,0x31b8b856),LL(0x0a1c67fc,0x052a1912),LL(0xe3aead59,0xb4069ea4), + LL(0x7fa03cb3,0x3232d6e2),LL(0x0fdd7d88,0xdb938e5b),LL(0x2ccbfc5d,0x04c1d2cd),LL(0xaf3a580f,0xd2f45c12), LL(0x7883e614,0x592620b5),LL(0xbe7c5f26,0x5fd27e68),LL(0x1567e1e3,0x139e45a9),LL(0x44d8aaaf,0x2cc71d2d), + LL(0xe36d0757,0x4a9090cd),LL(0xd9a29382,0xf722d7b1),LL(0x04b48ddf,0xfb7fb04c),LL(0xebe16f43,0x628ad2a7), LL(0x20226040,0xcd3fbfb5),LL(0x5104b6c4,0x6c34ecb1),LL(0xc903c188,0x30c0754e),LL(0x2d23cab0,0xec336b08), + LL(0x1e206ee5,0x473d62a2),LL(0x8c49a633,0xf1e27480),LL(0xe9f6b2c3,0x87ab956c),LL(0x62b606ea,0x61830b48), LL(0xe78e815f,0x67cd6846),LL(0x4c02082a,0xfe40139f),LL(0x952ec365,0x52bbbfcb),LL(0x6b9836ab,0x74c11642), + LL(0x558df019,0x9f51439e),LL(0xac712b27,0x230da4ba),LL(0x55185a24,0x518919e3),LL(0x84b78f50,0x4dcefcdd), LL(0xa47d4c5a,0xa7d90fb2),LL(0xb30e009e,0x55ac9abf),LL(0x74eed273,0xfd2fc359),LL(0xdbea8faf,0xb72d824c), + LL(0x4513e2ca,0xce721a74),LL(0x38240b2c,0x0b418612),LL(0xd5baa450,0x05199968),LL(0x2b0e8c25,0xeb1757ed), LL(0x3dfac6d5,0x6ebc3e28),LL(0x48a237f5,0xb2431e2e),LL(0x52f61499,0x2acb5e23),LL(0xe06c936b,0x5558a2a7), + LL(0xcbb13d1b,0xd213f923),LL(0x5bfb9bfe,0x98799f42),LL(0x701144a9,0x1ae8ddc9),LL(0x4c5595ee,0x0b8b3bb6), LL(0x3ecebb21,0x0ea9ef2e),LL(0x3671f9a7,0x17cb6c4b),LL(0x726f1d1f,0x47ef464f),LL(0x6943a276,0x171b9484), + LL(0x7ef0329c,0x51a4ae2d),LL(0x91c4402a,0x08509222),LL(0xafd45bbc,0x64a61d35),LL(0x3035a851,0x38f096fe), LL(0xa1dec027,0xc7468b74),LL(0x4fc7dcba,0xe8cf10e7),LL(0xf4a06353,0xea35ff40),LL(0x8b77dd66,0x0b4c0dfa), + LL(0xde7e5c19,0x779b8552),LL(0xc1c0256c,0xfab28609),LL(0xabd4743d,0x64f58eee),LL(0x7b6cc93b,0x4e8ef838), LL(0x4cb1bf3d,0xee650d26),LL(0x73dedf61,0x4c1f9d09),LL(0xbfb70ced,0xaef7c9d7),LL(0x1641de1e,0x1ec0507e), + LL(0xcde45079,0xcd7e5cc7),LL(0x516ac9e4,0xde173c9a),LL(0xc170315c,0x517a8494),LL(0x91d8e8fb,0x438fd905), LL(0xc7d9630b,0x5145c506),LL(0xf47d4d75,0x6457a87b),LL(0x0d9a80e8,0xd31646bf),LL(0xcef3aabe,0x453add2b), + LL(0xa607419d,0xc9941109),LL(0xbb6bca80,0xfaa71e62),LL(0x07c431f3,0x34158c13),LL(0x992bc47a,0x594abebc), LL(0xeb78399f,0x6dfea691),LL(0x3f42cba4,0x48aafb35),LL(0x077c04f0,0xedcd65af),LL(0xe884491a,0x1a29a366), + LL(0x1c21f2bf,0x023a40e5),LL(0xa5057aee,0xf99a513c),LL(0xbcab072e,0xa3fe7e25),LL(0x40e32bcf,0x8568d2e1), LL(0xd3f69d9f,0x904594eb),LL(0x07affab1,0x181a9733),LL(0xb6e330f4,0xe4d68d76),LL(0xc75a7fc1,0x87a6dafb), + LL(0xef7d9289,0x549db2b5),LL(0x197f015a,0x2480d4a8),LL(0xc40493b6,0x61d5590b),LL(0x6f780331,0x3a55b52e), LL(0x309eadb0,0x40eb8115),LL(0x92e5c625,0xdea7de5a),LL(0xcc6a3d5a,0x64d631f0),LL(0x93e8dd61,0x9d5e9d7c), + LL(0x206d3ffc,0xf297bef5),LL(0x7d808bd4,0x23d5e033),LL(0xd24cf5ba,0x4a4f6912),LL(0x09cdaa8a,0xe4d8163b), LL(0xd3082e8e,0x0e0de9ef),LL(0x0192f360,0x4fe1246c),LL(0x4b8eee0a,0x1f900150),LL(0xf1da391b,0x5219da81), + LL(0xf7ea25aa,0x7bf6a5c1),LL(0xfbb07d5f,0xd165e6bf),LL(0x89e78671,0xe3539361),LL(0x2bac4219,0xa3fcac89), LL(0xf0baa8ab,0xdfab6fd4),LL(0xe2c1c2e5,0x5a4adac1),LL(0x40d85849,0x6cd75e31),LL(0x19b39181,0xce263fea), + LL(0x07032c72,0xcb6803d3),LL(0x790968c8,0x7f40d5ce),LL(0xdce978f0,0xa6de86bd),LL(0x368f751c,0x25547c4f), LL(0x65fb2a9e,0xb1e685fd),LL(0x1eb9179c,0xce69336f),LL(0x12504442,0xb15d1c27),LL(0xb911a06b,0xb7df465c), + LL(0x315980cd,0xb8d804a3),LL(0xfa3bebf7,0x693bc492),LL(0x2253c504,0x3578aeee),LL(0xcd2474a2,0x158de498), LL(0xcfda8368,0x1331f5c7),LL(0x78d7177e,0xd2d7bbb3),LL(0xf3c1e46e,0xdf61133a),LL(0xd30e7be8,0x5836ce7d), + LL(0x94f834cb,0x83084f19),LL(0x429ed782,0xd35653d4),LL(0x59e58243,0xa542f16f),LL(0x0470a22d,0xc2b52f65), LL(0x18f23d96,0xe3b6221b),LL(0x3f5252b4,0xcb05abac),LL(0x87d61402,0xca00938b),LL(0x411933e4,0x2f186cdd), + LL(0x9a29a5c5,0xe042ece5),LL(0x3b6c8402,0xb19b3c07),LL(0x19d92684,0xc97667c7),LL(0xebc66372,0xb5624622), LL(0x3c04fa02,0x0cb96e65),LL(0x8eaa39aa,0x83a7176c),LL(0xeaa1633f,0x2033561d),LL(0x4533df73,0x45a9d086), + LL(0x3dc090bc,0xe0542c1d),LL(0xaa59c167,0x82c996ef),LL(0x0ee7fc4d,0xe3f735e8),LL(0x7c35db79,0x7b179393), LL(0xf8c5dbfd,0xb6419e25),LL(0x1f327b04,0x4d9d7a1e),LL(0x298dfca8,0x979f6f9b),LL(0x8de9366a,0xc7c5dff1), + LL(0x04c82bdd,0x1b7a588d),LL(0xf8319dfd,0x68005534),LL(0xd8eb9580,0xde8a55b5),LL(0x8d5bca81,0x5ea886da), LL(0x252a0b4d,0xe8530a01),LL(0x35eaa0a1,0x1bffb4fe),LL(0xd8e99563,0x2ad828b1),LL(0x95f9cd87,0x7de96ef5), + LL(0xd77d970c,0x4abb2d0c),LL(0xd33ef9cb,0x03cfb933),LL(0x8b211fe9,0xb0547c01),LL(0xa56ed1c6,0x2fe64809), LL(0xc2ac98cc,0xcb7d5624),LL(0x1a393e33,0x2a1372c0),LL(0x29660521,0xc8d1ec1c),LL(0xb37ac3e9,0xf3d31b04), + LL(0x5ece6e7c,0xa29ae9df),LL(0x0facfb55,0x0603ac8f),LL(0xdda233a5,0xcfe85b7a),LL(0xbd75f0b8,0xe618919f), LL(0x99bf1603,0xf555a3d2),LL(0xf184255a,0x1f43afc9),LL(0x319a3e02,0xdcdaf341),LL(0x03903a39,0xd3b117ef), + LL(0x65d1d131,0xe095da13),LL(0xc37ad03e,0x86f16367),LL(0x462cd8dd,0x5f37389e),LL(0xd67a60e6,0xc103fa04), LL(0xf4b478f0,0x57c34344),LL(0xe117c98d,0xce91edd8),LL(0x231fc12e,0x001777b0),LL(0xb207bccb,0x11ae47f2), + LL(0x20f8a242,0xd983cf8d),LL(0xf22e1ad8,0x7aff5b1d),LL(0x7fc4feb3,0x68fd11d0),LL(0xb0f1c3e1,0x5d53ae90), LL(0xec041803,0x50fb7905),LL(0x14404888,0x85e3c977),LL(0xac628d8f,0x0e67faed),LL(0x6668532c,0x2e865150), + LL(0x6a67a6b0,0x15acaaa4),LL(0xb25cec41,0xf4cdee25),LL(0xe4c6701e,0x49ee565a),LL(0xfc7d63d8,0x2a04ca66), LL(0xef0543fb,0xeb105018),LL(0xd1b0d81d,0xf709a4f5),LL(0x2915d333,0x5b906ee6),LL(0x96f1f0ab,0xf4a87412), + LL(0x4d82f4c2,0xb6b82fa7),LL(0x6804efb3,0x90725a60),LL(0xadc3425e,0xbc82ec46),LL(0x2787843e,0xb7b80581), LL(0xdd1fc74c,0xdf46d91c),LL(0xe783a6c4,0xdc1c62cb),LL(0x1a04cbba,0x59d1b9f3),LL(0x95e40764,0xd87f6f72), + LL(0x317f4a76,0x02b4cfc1),LL(0x91036bce,0x8d2703eb),LL(0xa5e72a56,0x98206cc6),LL(0xcf53fb0f,0x57be9ed1), LL(0xef0b17ac,0x09374571),LL(0xd9181b38,0x74b2655e),LL(0x89935d0e,0xc8f80ea8),LL(0x91529936,0xc0d9e942), + LL(0x1e84e0e5,0x19686041),LL(0xaea34c93,0xa5db84d3),LL(0x7073a732,0xf9d5bb19),LL(0x6bcfd7c0,0xb8d2fe56), LL(0xf3eb82fa,0x45775f36),LL(0xfdff8b58,0x8cb20ccc),LL(0x8374c110,0x1659b65f),LL(0x330c789a,0xb8b4a422), + LL(0x6fe8208b,0x75e3c3ea),LL(0x286e78fe,0xbd74b9e4),LL(0xd7d93a1a,0x0be2e81b),LL(0xdd0a5aae,0x7ed06e27), LL(0x6be8b800,0x721f5a58),LL(0xd846db28,0x428299d1),LL(0x5be88ed3,0x95cb8e6b),LL(0x1c034e11,0xc3186b23), + LL(0x8977d99b,0xa6312c9e),LL(0x83f531e7,0xbe944331),LL(0x18d3b1d4,0x8232c0c2),LL(0xe1247b73,0x617aae8b), LL(0x282aec3b,0x40153fc4),LL(0xf7b8f823,0xc6063d2f),LL(0x3304f94c,0x68f10e58),LL(0xee676346,0x31efae74), + LL(0x40a9b97c,0xbadb6c6d),LL(0x4f666256,0x14702c63),LL(0x5184b2e3,0xdeb954f1),LL(0x94b6ca40,0x5184a526), LL(0x003c32ea,0xfff05337),LL(0x205974c7,0x5aa374dd),LL(0x4b0dd71a,0x9a763854),LL(0xdeb947ec,0x459cd27f), + LL(0x459c2b92,0xa6e28161),LL(0x75ee8ef5,0x2f020fa8),LL(0x30b06310,0xb132ec2d),LL(0xbc6a4530,0xc3e15899), LL(0xaa3f451a,0xdc5f53fe),LL(0xc2d9acac,0x3a3c7f23),LL(0x6b27e58b,0x2ec2f892),LL(0xd742799f,0x68466ee7), + LL(0x1fa26613,0x98324dd4),LL(0xbdc29d63,0xa2dc6dab),LL(0xd712d657,0xf9675faa),LL(0x21fd8d15,0x813994be), LL(0xfd4f7553,0x5ccbb722),LL(0xf3a36b20,0x5135ff8b),LL(0x69559df5,0x44be28af),LL(0x9d41bf30,0x40b65bed), + LL(0x3734e520,0xd98bf2a4),LL(0x209bdcba,0x5e3abbe3),LL(0xbc945b35,0x77c76553),LL(0xc6ef14aa,0x5331c093), LL(0x76b60c80,0x518ffe29),LL(0x7ace16f8,0x2285593b),LL(0xbe2b9784,0xab1f64cc),LL(0xab2421b6,0xe8f2c0d9), + LL(0xc1df065c,0x617d7174),LL(0x5f6578fa,0xafeeb5ab),LL(0x263b54a8,0x16ff1329),LL(0xc990dce3,0x45c55808), LL(0xecc8c177,0x42eab6c0),LL(0x5982ecaa,0x799ea9b5),LL(0xb607ef8e,0xf65da244),LL(0x32a3fc2c,0x8ab226ce), + LL(0x7ea973dc,0x745741e5),LL(0x20888f2e,0x5c00ca70),LL(0x45fd9cf1,0x7cdce3cf),LL(0x5507f872,0x8a741ef1), LL(0x196b4cec,0x47c51c2f),LL(0xc97ea618,0x70d08e43),LL(0x15b18a2b,0x930da15c),LL(0x2f610514,0x33b6c678), + LL(0x07ac9794,0xc662e4f8),LL(0xba06cb79,0x1eccf050),LL(0xe7d954e5,0x1ff08623),LL(0x24cf71c3,0x6ef2c5fb), LL(0x67978453,0xb2c063d2),LL(0x1d654af8,0xa0cf3796),LL(0x7ebdaa37,0x7cb242ea),LL(0xb86747e0,0x206e0b10), + LL(0xd5ecfefc,0x481dae5f),LL(0xc2bff8fc,0x07084fd8),LL(0xea324596,0x8040a01a),LL(0xd4de4036,0x4c646980), LL(0xd65abfc3,0x9eb8ab4e),LL(0x13541ec7,0xe01cb91f),LL(0xfd695012,0x8f029adb),LL(0x3c7569ec,0x9ae28483), + LL(0xa66d80a1,0xa5614c9e),LL(0x75f5f911,0x680a3e44),LL(0xceba4fc1,0x0c07b14d),LL(0xa13071c1,0x891c285b), LL(0x799ece3c,0xcac67ceb),LL(0x41e07e27,0x29b910a9),LL(0xf2e43123,0x66bdb409),LL(0x7ac9ecbe,0x06f8b137), + LL(0x38547090,0x5981fafd),LL(0x85e3415d,0x19ab8b9f),LL(0xc7e31b27,0xfc28c194),LL(0x6fbcbb42,0x843be0aa), LL(0xa6db836c,0xf3b1ed43),LL(0x01a45c05,0x2a1330e4),LL(0x95c1a377,0x4f19f3c5),LL(0x44b5ee33,0xa85f39d0), + LL(0x4ae52834,0x3da18e6d),LL(0x7423dcb0,0x5a403b39),LL(0xf2374aef,0xbb555e0a),LL(0x1e8ca111,0x2ad599c4), LL(0x014b3bf8,0x1b3a2fb9),LL(0xf66d5007,0x73092684),LL(0xc4340102,0x079f1426),LL(0x8fddf4de,0x1827cf81), + LL(0xf10ff927,0xc83605f6),LL(0x23739fc6,0xd3871451),LL(0xcac1c2cc,0x6d163450),LL(0xa2ec1ac5,0x6b521296), LL(0x6e3cb4a5,0x0606c4f9),LL(0x778abff7,0xe47d3f41),LL(0xbe8e3a45,0x425a8d5e),LL(0xa6102160,0x53ea9e97), + LL(0x39cbb688,0x477a106e),LL(0xf3386d32,0x532401d2),LL(0xb1b9b421,0x8e564f64),LL(0x81dad33f,0xca9b8388), LL(0x2093913e,0xb1422b4e),LL(0x69bc8112,0x533d2f92),LL(0xebe7b2c7,0x3fa017be),LL(0xcaf197c6,0xb2767c4a), + LL(0xaedbae9f,0xc925ff87),LL(0x36880a54,0x7daf0eb9),LL(0x9c4d0e71,0x9284ddf5),LL(0x316f8cf5,0x1581cf93), LL(0x3ac1f452,0x3eeca887),LL(0xfb6aeffe,0xb417fce9),LL(0xeefb8dc3,0xa5918046),LL(0x02209400,0x73d318ac), + LL(0x728693e5,0xe800400f),LL(0x339927ed,0xe87d814b),LL(0x57ea9910,0x93e94d3b),LL(0x2245fb69,0xff8a35b6), LL(0x7f200d34,0x043853d7),LL(0x0f653ce1,0x470f1e68),LL(0x59a06379,0x81ac05bd),LL(0x03930c29,0xa14052c2), + LL(0x26bc2797,0x6b72fab5),LL(0x99f16771,0x13670d16),LL(0x1e3e48d1,0x00170052),LL(0xb7adf678,0x978fe401), LL(0xd41c5dd4,0x55ecfb92),LL(0xc7b27da5,0x5ff8e247),LL(0x013fb606,0xe7518272),LL(0x2f547a3c,0x5768d7e5), + LL(0x60017a5f,0xbb24eaa3),LL(0x9c64ce9b,0x6b18e6e4),LL(0x103dde07,0xc225c655),LL(0x7592f7ea,0xfc3672ae), LL(0xd06283a1,0x9606ad77),LL(0xe4d59d99,0x542fc650),LL(0x2a40e7c2,0xabb57c49),LL(0xa8db9f55,0xac948f13), + LL(0xb04465c3,0x6d4c9682),LL(0x6468bd15,0xe3d062fa),LL(0x5f318d7e,0xa51729ac),LL(0x9eb6fc95,0x1fc87df6), LL(0x0591f652,0x63d146a8),LL(0x589621aa,0xa861b8f7),LL(0xce31348c,0x59f5f15a),LL(0x440da6da,0x8f663391), + LL(0xb591ffa3,0xcfa778ac),LL(0x4cdfebce,0x027ca9c5),LL(0x444ea6b3,0xbe8e05a5),LL(0xa78d8254,0x8aab4e69), LL(0xb474d6b8,0x2437f04f),LL(0x045b3855,0x6597ffd4),LL(0xca47ecaa,0xbb0aea4e),LL(0x85c7ebfc,0x568aae83), + LL(0xc73b2383,0x0e966e64),LL(0xd17d8762,0x49eb3447),LL(0x8da05dab,0xde107821),LL(0x016b7236,0x443d8baa), LL(0xea7610d6,0x163b63a5),LL(0xce1ca979,0xe47e4185),LL(0x80baa132,0xae648b65),LL(0x0e0d5b64,0xebf53de2), + LL(0xd3c8c1ca,0x8d3bfcb4),LL(0x5d04b309,0x0d914ef3),LL(0x3de7d395,0x55ef6415),LL(0x26b850e8,0xbde1666f), LL(0xd449ab19,0xdbe1ca6e),LL(0xe89a2672,0x8902b322),LL(0xdacb7a53,0xb1674b7e),LL(0xf52523ff,0x8e9faf6e), + LL(0x9a85788b,0x6ba535da),LL(0xbd0626d4,0xd21f03ae),LL(0xe873dc64,0x099f8c47),LL(0x018ec97e,0xcda8564d), LL(0xde92c68c,0x3e8d7a5c),LL(0x73323cc4,0x78e035a1),LL(0xf880ff7c,0x3ef26275),LL(0x273eedaa,0xa4ee3dff), + LL(0xaf4e18f8,0x58823507),LL(0x0672f328,0x967ec9b5),LL(0x559d3186,0x9ded19d9),LL(0x6cdce39c,0x5e2ab3de), LL(0x11c226df,0xabad6e4d),LL(0x87723014,0xf9783f43),LL(0x1a885719,0x9a49a0cf),LL(0x90da9dbf,0xfc0c1a5a), + LL(0x571d92ac,0x8bbaec49),LL(0x4692517f,0x569e85fe),LL(0xa14ea4af,0x8333b014),LL(0x12e5c5ad,0x32f2a62f), LL(0x06d89b85,0x98c2ce3a),LL(0x2ff77a08,0xb90741aa),LL(0x01f795a2,0x2530defc),LL(0x84b3c199,0xd6e5ba0b), + LL(0x12e4c936,0x7d8e8451),LL(0xbd0be17b,0xae419f7d),LL(0x22262bc9,0xa583fc8c),LL(0x91bfe2bd,0x6b842ac7), LL(0x440d6827,0x33cef4e9),LL(0xef81fb14,0x5f69f4de),LL(0x234fbb92,0xf16cf6f6),LL(0xd9e7e158,0x76ae3fc3), + LL(0xe9740b33,0x4e89f6c2),LL(0x4962d6a1,0x677bc85d),LL(0x68d10d15,0x6c6d8a7f),LL(0x0257b1cd,0x5f9a7224), LL(0x4ad85961,0x7096b916),LL(0xe657ab4a,0x5f8c47f7),LL(0xf7461d7e,0xde57d7d0),LL(0x80ce5ee2,0x7eb6094d), + LL(0x34190547,0x0b1e1dfd),LL(0xf05dd150,0x8a394f43),LL(0x97df44e6,0x0a9eb24d),LL(0x87675719,0x78ca06bf), LL(0x6ffeec22,0x6f0b3462),LL(0x36cdd8fb,0x9d91bcea),LL(0xa105be47,0xac83363c),LL(0x069710e3,0x81ba76c1), + LL(0x28c682c6,0x3d1b24cb),LL(0x8612575b,0x27f25228),LL(0xe8e66e98,0xb587c779),LL(0x405eb1fe,0x7b0c03e9), LL(0x15b548e7,0xfdf0d030),LL(0x38b36af7,0xa8be76e0),LL(0x4f310c40,0x4cdab04a),LL(0xf47ecaec,0x6287223e), + LL(0x8b399320,0x678e6055),LL(0xc01e4646,0x61fe3fa6),LL(0x03261a5e,0xc482866b),LL(0x5c2f244a,0xdfcf45b8), LL(0x2f684b43,0x8fab9a51),LL(0xc7220a66,0xf796c654),LL(0xf5afa58f,0x1d90707e),LL(0x4fdbe0de,0x2c421d97), + LL(0xaf2ebc2f,0xc4f4cda3),LL(0xcb4efe24,0xa0af843d),LL(0x9ccd10b1,0x53b857c1),LL(0x914d3e04,0xddc9d1eb), LL(0x62771deb,0x7bdec8bb),LL(0x91c5aa81,0x829277aa),LL(0x832391ae,0x7af18dd6),LL(0xc71a84ca,0x1740f316), +}, +/* digit=34 base_pwr=2^238 */ +{ + LL(0xeeaf8c49,0x8928e99a),LL(0x6e24d728,0xee7aa73d),LL(0xe72b156c,0x4c5007c2),LL(0xed408a1d,0x5fcf57c5), LL(0xb6057604,0x9f719e39),LL(0xc2868bbf,0x7d343c01),LL(0x7e103e2d,0x2cca254b),LL(0xf131bea2,0xe6eb38a9), + LL(0x8be762b4,0xb33e624f),LL(0x058e3413,0x2a9ee4d1),LL(0x67d805fa,0x968e6369),LL(0x7db8bfd7,0x9848949b), LL(0xd23a8417,0x5308d7e5),LL(0xf3e29da5,0x892f3b1d),LL(0x3dee471f,0xc95c139e),LL(0xd757e089,0x8631594d), + LL(0xde918dcc,0xe0c82a3c),LL(0x26fdcf4b,0x2e7b5994),LL(0x32cb1b2d,0x82c50249),LL(0x7657ae07,0xea613a9d), LL(0xf1fdc9f7,0xc2eb5f6c),LL(0x879fe682,0xb6eae8b8),LL(0x591cbc7f,0x253dfee0),LL(0x3e1290e6,0x000da713), + LL(0x1f095615,0x1083e2ea),LL(0x14e68c33,0x0a28ad77),LL(0x3d8818be,0x6bfc0252),LL(0xf35850cd,0xb585113a), LL(0x30df8aa1,0x7d935f0b),LL(0x4ab7e3ac,0xaddda07c),LL(0x552f00cb,0x92c34299),LL(0x2909df6c,0xc33ed1de), + LL(0x80e87766,0x22c2195d),LL(0x9ddf4ac0,0x9e99e6d8),LL(0x65e74934,0x09642e4e),LL(0xff1ff241,0x2610ffa2), LL(0x751c8159,0x4d1d47d4),LL(0xaf3a9363,0x697b4985),LL(0x87477c33,0x0318ca46),LL(0x9441eff3,0xa90cb565), + LL(0x36f024cb,0x58bb3848),LL(0x36016168,0x85be1f77),LL(0xdc7e07f1,0x6c59587c),LL(0xaf1d8f02,0x191be071), LL(0xcca5e55c,0xbf169fa5),LL(0xf7d04eac,0x3864ba3c),LL(0x8d7d05db,0x915e367f),LL(0xa6549e5d,0xb48a876d), + LL(0x580e40a2,0xef89c656),LL(0x728068bc,0xf194ed8c),LL(0xa47990c9,0x74528045),LL(0x5e1a4649,0xf53fc7d7), LL(0x78593e7d,0xbec5ae9b),LL(0x41db65d7,0x2cac4ee3),LL(0x04a3d39b,0xa8c1eb24),LL(0x03f8f3ef,0x53b7d634), + LL(0x3e07113c,0x2dc40d48),LL(0x7d8b63ae,0x6e4a5d39),LL(0x79684c2b,0x5582a94b),LL(0x622da26c,0x932b33d4), LL(0x0dbbf08d,0xf534f651),LL(0x64c23a52,0x211d07c9),LL(0xee5bdc9b,0x0eeece0f),LL(0xf7015558,0xdf178168), + LL(0x0a712229,0xd4294635),LL(0x09273f8c,0x93cbe448),LL(0x8f13bc83,0x00b095ef),LL(0x8798978c,0xbb741972), LL(0x56dbe6e7,0x9d7309a2),LL(0x5a5d39ec,0xe578ec56),LL(0x851f9a31,0x3961151b),LL(0xe5709eb4,0x2da7715d), + LL(0x53dfabf0,0x867f3017),LL(0xb8e39259,0x728d2078),LL(0x815d9958,0x5c75a0cd),LL(0x16603be1,0xf84867a6), LL(0x70e35b1c,0xc865b13d),LL(0x19b03e2c,0x02414468),LL(0xac1f3121,0xe46041da),LL(0x6f028a7c,0x7c9017ad), + LL(0x0a482873,0xabc96de9),LL(0xb77e54d4,0x4265d6b1),LL(0xa57d88e7,0x68c38e79),LL(0x9ce82de3,0xd461d766), LL(0x64a7e489,0x817a9ec5),LL(0xa0def5f2,0xcc5675cd),LL(0x985d494e,0x9a00e785),LL(0x1b03514a,0xc626833f), + LL(0x83cdd60e,0xabe7905a),LL(0xa1170184,0x50602fb5),LL(0xb023642a,0x689886cd),LL(0xa6e1fb00,0xd568d090), LL(0x0259217f,0x5b1922c7),LL(0xc43141e4,0x93831cd9),LL(0x0c95f86e,0xdfca3587),LL(0x568ae828,0xdec2057a), + LL(0xf98a759a,0xc44ea599),LL(0xf7c23c1d,0x55a0a7a2),LL(0x94c4f687,0xd5ffb6e6),LL(0x12848478,0x3563cce2), LL(0xe7b1fbe1,0x812b3517),LL(0x4f7338e0,0x8a7dc979),LL(0x52d048db,0x211ecee9),LL(0xc86ea3b8,0x2eea4056), + LL(0xba772b34,0xd8cb68a7),LL(0x5f4e2541,0xe16ed341),LL(0x0fec14db,0x9b32f6a6),LL(0x391698be,0xeee376f7), LL(0x83674c02,0xe9a7aa17),LL(0x5843022a,0x65832f97),LL(0x5ba4990f,0x29f3a8da),LL(0xfb8e3216,0x79a59c3a), + LL(0xbd19bb16,0x9cdc4d2e),LL(0xb3262d86,0xc6c7cfd0),LL(0x969c0b47,0xd4ce14d0),LL(0x13e56128,0x1fa352b7), LL(0x973db6d3,0x383d55b8),LL(0xe8e5b7bf,0x71836850),LL(0xe6bb571f,0xc7714596),LL(0x2d5b2dd2,0x259df31f), + LL(0x913cc16d,0x568f8925),LL(0xe1a26f5a,0x18bc5b6d),LL(0xf5f499ae,0xdfa413be),LL(0xc3f0ae84,0xf8835dec), LL(0x65a40ab0,0xb6e60bd8),LL(0x194b377e,0x65596439),LL(0x92084a69,0xbcd85625),LL(0x4f23ede0,0x5ce433b9), + LL(0x6ad65143,0xe8e8f04f),LL(0xd6e14af6,0x11511827),LL(0x8295c0c7,0x3d390a10),LL(0x621eba16,0x71e29ee4), LL(0x63717b46,0xa588fc09),LL(0xe06ad4a2,0x02be02fe),LL(0x04c22b22,0x931558c6),LL(0x12f3c849,0xbb4d4bd6), + LL(0x20efd662,0x54a4f496),LL(0xc5952d14,0x92ba6d20),LL(0xcc9784c2,0x2db8ea1e),LL(0x4b353644,0x81cc10ca), LL(0x4b4d7f6c,0x40b570ad),LL(0x84a1dcd2,0x5c9f1d96),LL(0x3147e797,0x01379f81),LL(0x2bd499f5,0xe5c6097b), + LL(0x328e5e20,0x40dcafa6),LL(0x54815550,0xf7b5244a),LL(0x47bfc978,0xb9a4f118),LL(0xd25825b1,0x0ea0e79f), LL(0x646c7ecf,0xa50f96eb),LL(0x446dea9d,0xeb811493),LL(0xdfabcf69,0x2af04677),LL(0xc713f6e8,0xbe3a068f), + LL(0x42e06189,0x860d523d),LL(0x4e3aff13,0xbf077941),LL(0xc1b20650,0x0b616dca),LL(0x2131300d,0xe66dd6d1), LL(0xff99abde,0xd4a0fd67),LL(0xc7aac50d,0xc9903550),LL(0x7c46b2d7,0x022ecf8b),LL(0x3abf92af,0x3333b1e8), + LL(0x6c491c14,0x11cc113c),LL(0x80dd3f88,0x05976688),LL(0x29d932ed,0xf5b4d9e7),LL(0xa2c38b6d,0xe982aad8), LL(0x8be0dcf0,0x6f925347),LL(0x65ca53f2,0x700080ae),LL(0x443ca77f,0xd8131156),LL(0xec51f984,0xe92d6942), + LL(0x85dfe9ae,0xd2a08af8),LL(0x4d2a86ca,0xd825d9a5),LL(0x39dff020,0x2c53988d),LL(0x430cdc40,0xf38b135a), LL(0x62a7150b,0x0c918ae0),LL(0x0c340e9b,0xf31fd8de),LL(0x4dbbf02e,0xafa0e7ae),LL(0x5eba6239,0x5847fb2a), + LL(0xdccbac8b,0x6b1647dc),LL(0x06f485c8,0xb642aa78),LL(0x7038ecdf,0x873f3765),LL(0xfa49d3fe,0x2ce5e865), LL(0xc98c4400,0xea223788),LL(0xf1fa5279,0x8104a8cd),LL(0x06becfd7,0xbcf7cc7a),LL(0xc8f974ae,0x49424316), + LL(0x84d6365d,0xc0da65e7),LL(0x8f759fb8,0xbcb7443f),LL(0x7ae81930,0x35c712b1),LL(0x4c6e08ab,0x80428dff), LL(0xa4faf843,0xf19dafef),LL(0xffa9855f,0xced8538d),LL(0xbe3ac7ce,0x20ac409c),LL(0x882da71e,0x358c1fb6), + LL(0xfd349961,0xafa9c0e5),LL(0x8421c2fc,0x2b2cfa51),LL(0xf3a28d38,0x2a80db17),LL(0x5d138e7e,0xa8aba539), LL(0x6e96eb8d,0x52012d1d),LL(0xcbaf9622,0x65d8dea0),LL(0xb264f56c,0x57735447),LL(0x1b6c8da2,0xbeebef3f), + LL(0xce785254,0xfc346d98),LL(0xbb64a161,0xd50e8d72),LL(0x49794add,0xc03567c7),LL(0x752c7ef6,0x15a76065), LL(0x961f23d6,0x59f3a222),LL(0x73ecc0b0,0x378e4438),LL(0x5a82fde4,0xc74be434),LL(0xd8b9cf34,0xae509af2), + LL(0x577f44a1,0x4a61ee46),LL(0xb611deeb,0xe09b748c),LL(0xf5f7b884,0xc0481b2c),LL(0x61acfa6b,0x35626678), LL(0xbf8d21e6,0x37f4c518),LL(0xb205a76d,0x22d96531),LL(0x954073c0,0x37fb85e1),LL(0x65b3a567,0xbceafe4f), + LL(0xbe42a582,0xefecdef7),LL(0x65046be6,0xd3fc6080),LL(0x09e8dba9,0xc9af13c8),LL(0x641491ff,0x1e6c9847), LL(0xd30c31f7,0x3b574925),LL(0xac2a2122,0xb7eb72ba),LL(0xef0859e7,0x776a0dac),LL(0x21900942,0x06fec314), + LL(0xf8c22049,0x2464bc10),LL(0x875ebf69,0x9bfbcce7),LL(0x4336326b,0xd7a88e2a),LL(0x5bc2acfa,0xda05261c), LL(0xeba7efc8,0xc29f5bdc),LL(0x25dbbf2e,0x471237ca),LL(0x2975f127,0xa72773f2),LL(0x04d0b326,0xdc744e8e), + LL(0xa56edb73,0x38a7ed16),LL(0x2c007e70,0x64357e37),LL(0x5080b400,0xa167d15b),LL(0x23de4be1,0x07b41164), LL(0x74c89883,0xb2d91e32),LL(0x2882e7ed,0x3c162821),LL(0x7503e482,0xad6b36ba),LL(0x0ea34331,0x48434e8e), + LL(0x2c7ae0b9,0x79f4f24f),LL(0x1939b44a,0xc46fbf81),LL(0x56595eb1,0x76fefae8),LL(0xcd5f29c7,0x417b66ab), LL(0xc5ceec20,0x5f2332b2),LL(0xe1a1cae2,0xd69661ff),LL(0x9b0286e6,0x5ede7e52),LL(0xe276b993,0x9d062529), + LL(0x7e50122b,0x324794b0),LL(0x4af07ca5,0xdd744f8b),LL(0xd63fc97b,0x30a12f08),LL(0x76626d9d,0x39650f1a), LL(0x1fa38477,0x101b47f7),LL(0xd4dc124f,0x3d815f19),LL(0xb26eb58a,0x1569ae95),LL(0x95fb1887,0xc3cde188), + LL(0xf9539a48,0x54e9f37b),LL(0x7408c1a5,0xb0100e06),LL(0xea580cbb,0x821d9811),LL(0x86e50c56,0x8af52d35), LL(0xdbbf698b,0xdfbd9d47),LL(0x03dc1c73,0x2961a1ea),LL(0xe76a5df8,0x203d38f8),LL(0x6def707a,0x08a53a68), + LL(0x1bee45d4,0x26eefb48),LL(0x3c688036,0xb3cee346),LL(0xc42f2469,0x463c5315),LL(0x81378162,0x19d84d2e), LL(0x1c4d349f,0x22d7c3c5),LL(0x163d59c5,0x65965844),LL(0xb8abceae,0xcf198c56),LL(0x628559d5,0x6fb1fb1b), + LL(0x07bf8fe3,0x8bbffd06),LL(0x3467734b,0x46259c58),LL(0x35f7f0d3,0xd8953cea),LL(0xd65b0ff1,0x1f0bece2), LL(0xf3c72914,0xf7d5b4b3),LL(0x3cb53389,0x29e8ea95),LL(0x836b6d46,0x4a365626),LL(0xea174fde,0xe849f910), + LL(0xf4737f21,0x7ec62fbb),LL(0x6209f5ac,0xd8dba5ab),LL(0xa5f9adbe,0x24b5d7a9),LL(0xa61dc768,0x707d28f7), LL(0xcaa999ea,0x7711460b),LL(0x1c92e4cc,0xba7b174d),LL(0x18d4bf2d,0x3c4bab66),LL(0xeb8bd279,0xb8f0c980), + LL(0x324b4737,0x024bea9a),LL(0x32a83bca,0xfba9e423),LL(0xa232dced,0x6e635643),LL(0x2571c8ba,0x99619367), LL(0x54b7032b,0xe8c9f357),LL(0x2442d54a,0xf936b3ba),LL(0x8290c65a,0x2263f0f0),LL(0xee2c7fdb,0x48989780), + LL(0x13d4f95e,0xadc5d55a),LL(0xad9b8500,0x737cff85),LL(0x8a73f43d,0x271c557b),LL(0xe18bc476,0xbed617a4), LL(0x7dfd8ab2,0x66245401),LL(0x3a2870aa,0xae7b89ae),LL(0x23a7e545,0x1b555f53),LL(0xbe057e4c,0x6791e247), + LL(0x324fa34d,0x860136ad),LL(0x4cbeae28,0xea111447),LL(0xbedd3299,0x023a4270),LL(0xc1c35c34,0x3d5c3a7f), LL(0x8d0412d2,0xb0f6db67),LL(0xfcdc6b9a,0xd92625e2),LL(0x4e28a982,0x92ae5ccc),LL(0x47a3ce7e,0xea251c36), + LL(0x790691bf,0x9d658932),LL(0x06b736ae,0xed610589),LL(0xc0d63b6e,0x712c2f04),LL(0xc63d488f,0x5cf06fd5), LL(0xd9588e41,0x97363fac),LL(0x2b93257e,0x1f9bf762),LL(0x667acace,0xa9d1ffc4),LL(0x0a061ecf,0x1cf4a1aa), + LL(0xdc1818d0,0x40e48a49),LL(0xa3621ab0,0x0643ff39),LL(0xe39ef639,0x5768640c),LL(0x04d86854,0x1fc099ea), LL(0xeccd28fd,0x9130b9c3),LL(0x7eec54ab,0xd743cbd2),LL(0xe5b475b6,0x052b146f),LL(0x900a7d1f,0x058d9a82), + LL(0x91262b72,0x65e02292),LL(0xbb0edf03,0x96f924f9),LL(0xfe206842,0x5cfa59c8),LL(0x5eafa720,0xf6037004), LL(0x18d7dd96,0x5f30699e),LL(0xcbab2495,0x381e8782),LL(0xdd8be949,0x91669b46),LL(0x26aae8ef,0xb40606f5), + LL(0xfc6751a4,0x2812b839),LL(0xfba800ef,0x16196214),LL(0x4c1a2875,0x4398d5ca),LL(0x653d8349,0x720c00ee), LL(0xd820007c,0xc2699eb0),LL(0xa39b5825,0x880ee660),LL(0x471f6984,0x70694694),LL(0xe3dda99a,0xf7d16ea8), + LL(0xc0519a23,0x28d675b2),LL(0x4f6952e3,0x9ebf94fe),LL(0xa2294a8a,0xf28bb767),LL(0xfe0af3f5,0x85512b4d), LL(0x99b16a0d,0x18958ba8),LL(0xba7548a7,0x95c2430c),LL(0xa16be615,0xb30d1b10),LL(0x85bfb74c,0xe3ebbb97), + LL(0x18549fdb,0xa3273cfe),LL(0x4fcdb792,0xf6e200bf),LL(0x83aba56c,0x54a76e18),LL(0x89ef6aa2,0x73ec66f6), LL(0xd1b9a305,0x8d17add7),LL(0xb7ae1b9d,0xa959c5b9),LL(0x6bcc094a,0x88643522),LL(0xd7d429b9,0xcc5616c4), + LL(0xe6a33f7c,0xa6dada01),LL(0x9d4e70ad,0xc6217a07),LL(0x09c15b7c,0xd619a818),LL(0x0e80c854,0xea06b329), LL(0xa5f5e7b9,0x174811ce),LL(0x787c65f4,0x66dfc310),LL(0x3316ab54,0x4ea7bd69),LL(0x1dcc0f70,0xc12c4acb), + LL(0x1e407dd9,0xe4308d1a),LL(0x91afa997,0xe8a3587c),LL(0xab77b7a5,0xea296c12),LL(0x673c0d52,0xb5ad49e4), LL(0x7006085a,0x40f9b2b2),LL(0x87bf6ec2,0xa88ff340),LL(0x4e3066a6,0x978603b1),LL(0xb5e486e2,0xb3f99fc2), + LL(0xb2e63645,0x07b53f5e),LL(0x84c84232,0xbe57e547),LL(0x7214d5cf,0xd779c216),LL(0x029a3aca,0x617969cd), LL(0x8a7017a0,0xd17668cd),LL(0xbe9b7ee8,0x77b4d19a),LL(0x9c161776,0x58fd0e93),LL(0xd5968a72,0xa8c4f4ef), + LL(0x67b3de77,0x296071cc),LL(0x634f7905,0xae3c0b8e),LL(0x8a7100c9,0x67e440c2),LL(0xeb4b9b42,0xbb8c3c1b), LL(0xc51b3583,0x6d71e8ea),LL(0x9525e642,0x7591f5af),LL(0x13f509f3,0xf73a2f7b),LL(0x5619ac9b,0x618487aa), + LL(0x9d61718a,0x3a72e5f7),LL(0x7592d28c,0x00413bcc),LL(0x963c35cf,0x7d9b11d3),LL(0xb90a46ed,0x77623bcf), LL(0xdcdd2a50,0xdeef273b),LL(0x0601846e,0x4a741f9b),LL(0x0ec6e929,0x33b89e51),LL(0x8b7f22cd,0xcb02319f), + LL(0x084bae24,0xbbe1500d),LL(0x343d2693,0x2f0ae8d7),LL(0x7cdef811,0xacffb5f2),LL(0x263fb94f,0xaa0c030a), LL(0xa0f442de,0x6eef0d61),LL(0x27b139d3,0xf92e1817),LL(0x0ad8bc28,0x1ae6deb7),LL(0xc0514130,0xa89e38dc), + LL(0xd2fdca23,0x81eeb865),LL(0xcc8ef895,0x5a15ee08),LL(0x01905614,0x768fa10a),LL(0x880ee19b,0xeff5b8ef), LL(0xcb1c8a0e,0xf0c0cabb),LL(0xb8c838f9,0x2e1ee9cd),LL(0x8a4a14c0,0x0587d8b8),LL(0x2ff698e5,0xf6f27896), + LL(0x89ee6256,0xed38ef1c),LL(0x6b353b45,0xf44ee1fe),LL(0x70e903b3,0x9115c0c7),LL(0x818f31df,0xc78ec0a1), LL(0xb7dccbc6,0x6c003324),LL(0x163bbc25,0xd96dd1f3),LL(0x5cedd805,0x33aa82dd),LL(0x7f7eb2f1,0x123aae4f), + LL(0xa26262cd,0x1723fcf5),LL(0x0060ebd5,0x1f7f4d5d),LL(0xb2eaa3af,0xf19c5c01),LL(0x9790accf,0x2ccb9b14), LL(0x52324aa6,0x1f9c1cad),LL(0x7247df54,0x63200526),LL(0xbac96f82,0x5732fe42),LL(0x01a1c384,0x52fe771f), + LL(0xb1001684,0x546ca13d),LL(0xa1709f75,0xb56b4eee),LL(0xd5db8672,0x266545a9),LL(0x1e8f3cfb,0xed971c90), LL(0xe3a07b29,0x4e7d8691),LL(0xe4b696b9,0x7570d9ec),LL(0x7bc7e9ae,0xdc5fa067),LL(0xc82c4844,0x68b44caf), + LL(0xbf44da80,0x519d34b3),LL(0x5ab32e66,0x283834f9),LL(0x6278a000,0x6e608797),LL(0x627312f6,0x1e62960e), LL(0xe6901c55,0x9b87b27b),LL(0x24fdbc1f,0x80e78538),LL(0x2facc27d,0xbbbc0951),LL(0xac143b5a,0x06394239), + LL(0x376c1944,0x35bb4a40),LL(0x63da1511,0x7cb62694),LL(0xb7148a3b,0xafd29161),LL(0x4e2ea2ee,0xa6f9d9ed), LL(0x880dd212,0x15dc2ca2),LL(0xa61139a9,0x903c3813),LL(0x6c0f8785,0x2aa7b46d),LL(0x901c60ff,0x36ce2871), + LL(0xe10d9c12,0xc683b028),LL(0x032f33d3,0x7573baa2),LL(0x67a31b58,0x87a9b1f6),LL(0xf4ffae12,0xfd3ed11a), LL(0x0cb2748e,0x83dcaa9a),LL(0x5d6fdf16,0x8239f018),LL(0x72753941,0xba67b49c),LL(0xc321cb36,0x2beec455), + LL(0x3f8b84ce,0x88015606),LL(0x8d38c86f,0x76417083),LL(0x598953dd,0x054f1ca7),LL(0x4e8e7429,0xc939e110), LL(0x5a914f2f,0x9b1ac2b3),LL(0xe74b8f9c,0x39e35ed3),LL(0x781b2fb0,0xd0debdb2),LL(0x2d997ba2,0x1585638f), + LL(0x9e2fce99,0x9c4b646e),LL(0x1e80857f,0x68a21081),LL(0x3643b52a,0x06d54e44),LL(0x0d8eb843,0xde8d6d63), LL(0x42146a0a,0x70321563),LL(0x5eaa3622,0x8ba826f2),LL(0x86138787,0x227a58bd),LL(0x10281d37,0x43b6c03c), + LL(0xb54dde39,0x6326afbb),LL(0xdb6f2d5f,0x744e5e8a),LL(0xcff158e1,0x48b2a99a),LL(0xef87918f,0xa93c8fa0), LL(0xde058c5c,0x2182f956),LL(0x936f9e7a,0x216235d2),LL(0xd2e31e67,0xace0c0db),LL(0xf23ac3e7,0xc96449bf), + LL(0x170693bd,0x7e9a2874),LL(0xa45e6335,0xa28e14fd),LL(0x56427344,0x5757f6b3),LL(0xacf8edf9,0x822e4556), LL(0xe6a285cd,0x2b7a6ee2),LL(0xa9df3af0,0x5866f211),LL(0xf845b844,0x40dde2dd),LL(0x110e5e49,0x986c3726), + LL(0xf7172277,0x73680c2a),LL(0x0cccb244,0x57b94f0f),LL(0x2d438ca7,0xbdff7267),LL(0xcf4663fd,0xbad1ce11), LL(0xd8f71cae,0x9813ed9d),LL(0x961fdaa6,0xf43272a6),LL(0xbd6d1637,0xbeff0119),LL(0x30361978,0xfebc4f91), + LL(0x2f41deff,0x02b37a95),LL(0xe63b89b7,0x0e44a59a),LL(0x143ff951,0x673257dc),LL(0xd752baf4,0x19c02205), LL(0xc4b7d692,0x46c23069),LL(0xfd1502ac,0x2e6392c3),LL(0x1b220846,0x6057b1a2),LL(0x0c1b5b63,0xe51ff946), +}, +/* digit=35 base_pwr=2^245 */ +{ + LL(0x566c5c43,0x6e85cb51),LL(0x3597f046,0xcff9c919),LL(0x4994d94a,0x9354e90c),LL(0x2147927d,0xe0a39332), LL(0x0dc1eb2b,0x8427fac1),LL(0x2ff319fa,0x88cfd8c2),LL(0x01965274,0xe2d4e684),LL(0x67aaa746,0xfa2e067d), + LL(0x3e5f9f11,0xb6d92a7f),LL(0xd6cb3b8e,0x9afe153a),LL(0xddf800bd,0x4d1a6dd7),LL(0xcaf17e19,0xf6c13cc0), LL(0x325fc3ee,0x15f6c58e),LL(0xa31dc3b2,0x71095400),LL(0xafa3d3e7,0x168e7c07),LL(0x94c7ae2d,0x3f8417a1), + LL(0x813b230d,0xec234772),LL(0x17344427,0x634d0f5f),LL(0xd77fc56a,0x11548ab1),LL(0xce06af77,0x7fab1750), LL(0x4f7c4f83,0xb62c10a7),LL(0x220a67d9,0xa7d2edc4),LL(0x921209a0,0x1c404170),LL(0xface59f0,0x0b9815a0), + LL(0x319540c3,0x2842589b),LL(0xa283d6f8,0x18490f59),LL(0xdaae9fcb,0xa2731f84),LL(0xc3683ba0,0x3db6d960), LL(0x14611069,0xc85c63bb),LL(0x0788bf05,0xb19436af),LL(0x347460d2,0x905459df),LL(0xe11a7db1,0x73f6e094), + LL(0xb6357f37,0xdc7f938e),LL(0x2bd8aa62,0xc5d00f79),LL(0x2ca979fc,0xc878dcb9),LL(0xeb023a99,0x37e83ed9), LL(0x1560bf3d,0x6b23e273),LL(0x1d0fae61,0x1086e459),LL(0x9a9414bd,0x78248316),LL(0xf0ea9ea1,0x1b956bc0), + LL(0xc31b9c38,0x7b85bb91),LL(0x48ef57b5,0x0c5aa90b),LL(0xaf3bab6f,0xdedeb169),LL(0x2d373685,0xe610ad73), LL(0x02ba8e15,0xf13870df),LL(0x8ca7f771,0x0337edb6),LL(0xb62c036c,0xe4acf747),LL(0xb6b94e81,0xd921d576), + LL(0x2c422f7a,0xdbc86439),LL(0xed348898,0xfb635362),LL(0xc45bfcd1,0x83084668),LL(0x2b315e11,0xc357c9e3), LL(0x5b2e5b8c,0xb173b540),LL(0xe102b9a4,0x7e946931),LL(0x7b0fb199,0x17c890eb),LL(0xd61b662b,0xec225a83), + LL(0xee3c76cb,0xf306a3c8),LL(0xd32a1f6e,0x3cf11623),LL(0x6863e956,0xe6d5ab64),LL(0x5c005c26,0x3b8a4cbe), LL(0x9ce6bb27,0xdcd529a5),LL(0x04d4b16f,0xc4afaa52),LL(0x7923798d,0xb0624a26),LL(0x6b307fab,0x85e56df6), + LL(0x2bf29698,0x0281893c),LL(0xd7ce7603,0x91fc19a4),LL(0xad9a558f,0x75a5dca3),LL(0x4d50bf77,0x40ceb3fa), LL(0xbc9ba369,0x1baf6060),LL(0x597888c2,0x927e1037),LL(0x86a34c07,0xd936bf19),LL(0xc34ae980,0xd4cf10c1), + LL(0x859dd614,0x3a3e5334),LL(0x18d0c8ee,0x9c475b5b),LL(0x07cd51d5,0x63080d1f),LL(0xb88b4326,0xc9c0d0a6), LL(0xc234296f,0x1ac98691),LL(0x94887fb6,0x2a0a83a4),LL(0x0cea9cf2,0x56511427),LL(0xa24802f5,0x5230a6e8), + LL(0x72e3d5c1,0xf7a2bf0f),LL(0x4f21439e,0x37717446),LL(0x9ce30334,0xfedcbf25),LL(0x7ce202f9,0xe0030a78), LL(0x1202e9ca,0x6f2d9ebf),LL(0x75e6e591,0xe79dde6c),LL(0xf1dac4f8,0xf52072af),LL(0xbb9b404d,0x6c8d087e), + LL(0xbce913af,0xad0fc73d),LL(0x458a07cb,0x909e587b),LL(0xd4f00c8a,0x1300da84),LL(0xb54466ac,0x425cd048), LL(0x90e9d8bf,0xb59cb9be),LL(0x3e431b0e,0x991616db),LL(0x531aecff,0xd3aa117a),LL(0x59f4dc3b,0x91af92d3), + LL(0xe93fda29,0x9b1ec292),LL(0xe97d91bc,0x76bb6c17),LL(0xaface1e6,0x7509d95f),LL(0xbe855ae3,0x3653fe47), LL(0x0f680e75,0x73180b28),LL(0xeeb6c26c,0x75eefd1b),LL(0xb66d4236,0xa4cdf29f),LL(0x6b5821d8,0x2d70a997), + LL(0x20445c36,0x7a3ee207),LL(0x59877174,0x71d1ac82),LL(0x949f73e9,0x0fc539f7),LL(0x982e3081,0xd05cf3d7), LL(0x7b1c7129,0x8758e20b),LL(0x569e61f2,0xffadcc20),LL(0x59544c2d,0xb05d3a2f),LL(0x9fff5e53,0xbe16f5c1), + LL(0xaad58135,0x73cf65b8),LL(0x037aa5be,0x622c2119),LL(0x646fd6a0,0x79373b3f),LL(0x0d3978cf,0x0e029db5), LL(0x94fba037,0x8bdfc437),LL(0x620797a6,0xaefbd687),LL(0xbd30d38e,0x3fa5382b),LL(0x585d7464,0x7627cfbf), + LL(0x4e4ca463,0xb2330fef),LL(0x3566cc63,0xbcef7287),LL(0xcf780900,0xd161d2ca),LL(0x5b54827d,0x135dc539), LL(0x27bf1bc6,0x638f052e),LL(0x07dfa06c,0x10a224f0),LL(0x6d3321da,0xe973586d),LL(0x26152c8f,0x8b0c5738), + LL(0x34606074,0x07ef4f2a),LL(0xa0f7047a,0x80fe7fe8),LL(0xe1a0e306,0x3d1a8152),LL(0x88da5222,0x32cf43d8), LL(0x5f02ffe6,0xbf89a95f),LL(0x806ad3ea,0x3d9eb9a4),LL(0x79c8e55e,0x012c17bb),LL(0x99c81dac,0xfdcd1a74), + LL(0xb9556098,0x7043178b),LL(0x801c3886,0x4090a1df),LL(0x9b67b912,0x759800ff),LL(0x232620c8,0x3e5c0304), LL(0x70dceeca,0x4b9d3c4b),LL(0x181f648e,0xbb2d3c15),LL(0x6e33345c,0xf981d837),LL(0x0cf2297a,0xb626289b), + LL(0x8baebdcf,0x766ac659),LL(0x75df01e5,0x1a28ae09),LL(0x375876d8,0xb71283da),LL(0x607b9800,0x4865a96d), LL(0x237936b2,0x25dd1bcd),LL(0x60417494,0x332f4f4b),LL(0x370a2147,0xd0923d68),LL(0xdc842203,0x497f5dfb), + LL(0x32be5e0f,0x9dc74cbd),LL(0x17a01375,0x7475bcb7),LL(0x50d872b1,0x438477c9),LL(0xffe1d63d,0xcec67879), LL(0xd8578c70,0x9b006014),LL(0x78bb6b8b,0xc9ad99a8),LL(0x11fb3806,0x6799008e),LL(0xcd44cab3,0xcfe81435), + LL(0x2f4fb344,0xa2ee1582),LL(0x483fa6eb,0xb8823450),LL(0x652c7749,0x622d323d),LL(0xbeb0a15b,0xd8474a98), LL(0x5d1c00d0,0xe43c154d),LL(0x0e3e7aac,0x7fd581d9),LL(0x2525ddf8,0x2b44c619),LL(0xb8ae9739,0x67a033eb), + LL(0x9ef2d2e4,0x113ffec1),LL(0xd5a0ea7f,0x1bf6767e),LL(0x03714c0a,0x57fff75e),LL(0x0a23e9ee,0xa23c422e), LL(0x540f83af,0xdd5f6b2d),LL(0x55ea46a7,0xc2c2c27e),LL(0x672a1208,0xeb6b4246),LL(0xae634f7a,0xd13599f7), + LL(0xd7b32c6e,0xcf914b5c),LL(0xeaf61814,0x61a5a640),LL(0x208a1bbb,0x8dc3df8b),LL(0xb6d79aa5,0xef627fd6), LL(0xc4c86bc8,0x44232ffc),LL(0x061539fe,0xe6f9231b),LL(0x958b9533,0x1d04f25a),LL(0x49e8c885,0x180cf934), + LL(0x9884aaf7,0x89689595),LL(0x07b348a6,0xb1959be3),LL(0x3c147c87,0x96250e57),LL(0xdd0c61f8,0xae0efb3a), LL(0xca8c325e,0xed00745e),LL(0xecff3f70,0x3c911696),LL(0x319ad41d,0x73acbc65),LL(0xf0b1c7ef,0x7b01a020), + LL(0x63a1483f,0xea32b293),LL(0x7a248f96,0x89eabe71),LL(0x343157e5,0x9c6231d3),LL(0xdf3c546d,0x93a375e5), LL(0x6a2afe69,0xe76e9343),LL(0xe166c88e,0xc4f89100),LL(0x4f872093,0x248efd0d),LL(0x8fe0ea61,0xae0eb3ea), + LL(0x9d79046e,0xaf89790d),LL(0x6cee0976,0x4d650f2d),LL(0x43071eca,0xa3935d9a),LL(0x283b0bfe,0x66fcd2c9), LL(0x696605f1,0x0e665eb5),LL(0xa54cd38d,0xe77e5d07),LL(0x43d950cf,0x90ee050a),LL(0xd32e69b5,0x86ddebda), + LL(0xfddf7415,0x6ad94a3d),LL(0x3f6e8d5a,0xf7fa1309),LL(0xe9957f75,0xc4831d1d),LL(0xd5817447,0x7de28501), LL(0x9e2aeb6b,0x6f1d7078),LL(0xf67a53c2,0xba2b9ff4),LL(0xdf9defc3,0x36963767),LL(0x0d38022c,0x479deed3), + LL(0x3a8631e8,0xd2edb89b),LL(0x7a213746,0x8de855de),LL(0xb00c5f11,0xb2056cb7),LL(0x2c9b85e4,0xdeaefbd0), LL(0xd150892d,0x03f39a8d),LL(0x218b7985,0x37b84686),LL(0xb7375f1a,0x36296dd8),LL(0xb78e898e,0x472cd4b1), + LL(0xe9f05de9,0x15dff651),LL(0x2ce98ba9,0xd4045069),LL(0x9b38024c,0x8466a7ae),LL(0xe5a6b5ef,0xb910e700), LL(0xb3aa8f0d,0xae1c56ea),LL(0x7eee74a6,0xbab2a507),LL(0x4b4c4620,0x0dca11e2),LL(0x4c47d1f4,0xfd896e2e), + LL(0x308fbd93,0xeb45ae53),LL(0x02c36fda,0x46cd5a2e),LL(0xbaa48385,0x6a3d4e90),LL(0x9dbe9960,0xdd55e62e), LL(0x2a81ede7,0xa1406aa0),LL(0xf9274ea7,0x6860dd14),LL(0x80414f86,0xcfdcb0c2),LL(0x22f94327,0xff410b10), + LL(0x49ad467b,0x5a33cc38),LL(0x0a7335f1,0xefb48b6c),LL(0xb153a360,0x14fb54a4),LL(0xb52469cc,0x604aa9d2), LL(0x754e48e9,0x5e9dc486),LL(0x37471e8e,0x693cb455),LL(0x8d3b37b6,0xfb2fd7cd),LL(0xcf09ff07,0x63345e16), + LL(0x23a5d896,0x9910ba6b),LL(0x7fe4364e,0x1fe19e35),LL(0x9a33c677,0x6e1da8c3),LL(0x29fd9fd0,0x15b4488b), LL(0x1a1f22bf,0x1f439254),LL(0xab8163e8,0x920a8a70),LL(0x07e5658e,0x3fd1b249),LL(0xb6ec839b,0xf2c4f79c), + LL(0x4aa38d1b,0x1abbc3d0),LL(0xb5d9510e,0x3b0db35c),LL(0x3e60dec0,0x1754ac78),LL(0xea099b33,0x53272fd7), LL(0x07a8e107,0x5fb0494f),LL(0x6a8191fa,0x4a89e137),LL(0x3c4ad544,0xa113b7f6),LL(0x6cb9897b,0x88a2e909), + LL(0xb44a3f84,0x17d55de3),LL(0x17c6c690,0xacb2f344),LL(0x10232390,0x32088168),LL(0x6c733bf7,0xf2e8a61f), LL(0x9c2d7652,0xa774aab6),LL(0xed95c5bc,0xfb5307e3),LL(0x4981f110,0xa05c73c2),LL(0xa39458c9,0x1baae31c), + LL(0xcbea62e7,0x1def185b),LL(0xeaf63059,0xe8ac9eae),LL(0x9921851c,0x098a8cfd),LL(0x3abe2f5b,0xd959c3f1), LL(0x20e40ae5,0xa4f19525),LL(0x07a24aa1,0x320789e3),LL(0x7392b2bc,0x259e6927),LL(0x1918668b,0x58f6c667), + LL(0xc55d2d8b,0xce1db2bb),LL(0xf4f6ca56,0x41d58bb7),LL(0x8f877614,0x7650b680),LL(0xf4c349ed,0x905e16ba), LL(0xf661acac,0xed415140),LL(0xcb2270af,0x3b8784f0),LL(0x8a402cba,0x3bc280ac),LL(0x0937921a,0xd53f7146), + LL(0xe5681e83,0xc03c8ee5),LL(0xf6ac9e4a,0x62126105),LL(0x936b1a38,0x9503a53f),LL(0x782fecbd,0x3d45e2d4), LL(0x76e8ae98,0x69a5c439),LL(0xbfb4b00e,0xb53b2eeb),LL(0x72386c89,0xf1674712),LL(0x4268bce4,0x30ca34a2), + LL(0x78341730,0x7f1ed86c),LL(0xb525e248,0x8ef5beb8),LL(0xb74fbf38,0xbbc489fd),LL(0x91a0b382,0x38a92a0e), LL(0x22433ccf,0x7a77ba3f),LL(0xa29f05a9,0xde8362d6),LL(0x61189afc,0x7f6a30ea),LL(0x59ef114f,0x693b5505), + LL(0xcd1797a1,0x50266bc0),LL(0xf4b7af2d,0xea17b47e),LL(0x3df9483e,0xd6c4025c),LL(0xa37b18c9,0x8cbb9d9f), LL(0x4d8424cf,0x91cbfd9c),LL(0xab1c3506,0xdb7048f1),LL(0x028206a3,0x9eaf641f),LL(0x25bdf6ce,0xf986f3f9), + LL(0x224c08dc,0x262143b5),LL(0x81b50c91,0x2bbb09b4),LL(0xaca8c84f,0xc16ed709),LL(0xb2850ca8,0xa6210d9d), LL(0x09cb54d6,0x6d8df67a),LL(0x500919a4,0x91eef6e0),LL(0x0f132857,0x90f61381),LL(0xf8d5028b,0x9acede47), + LL(0x90b771c3,0x844d1b71),LL(0xba6426be,0x563b71e4),LL(0xbdb802ff,0x2efa2e83),LL(0xab5b4a41,0x3410cbab), LL(0x30da84dd,0x555b2d26),LL(0xee1cc29a,0xd0711ae9),LL(0x2f547792,0xcf3e8c60),LL(0xdc678b35,0x03d7d5de), + LL(0xced806b8,0x071a2fa8),LL(0x697f1478,0x222e6134),LL(0xabfcdbbf,0xdc16fd5d),LL(0x121b53b8,0x44912ebf), LL(0x2496c27c,0xac943674),LL(0x1ffc26b0,0x8ea3176c),LL(0x13debf2c,0xb6e224ac),LL(0xf372a832,0x524cc235), + LL(0x9f6f1b18,0xd706e1d8),LL(0x44cce35b,0x2552f005),LL(0xa88e31fc,0x8c8326c2),LL(0xf9552047,0xb5468b2c), LL(0x3ff90f2b,0xce683e88),LL(0x2f0a5423,0x77947bdf),LL(0xed56e328,0xd0a1b28b),LL(0xc20134ac,0xaee35253), + LL(0x3567962f,0x7e98367d),LL(0x8188bffb,0x379ed61f),LL(0xfaf130a1,0x73bba348),LL(0x904ed734,0x6c1f75e1), LL(0x3b4a79fc,0x18956642),LL(0x54ef4493,0xf20bc83d),LL(0x9111eca1,0x836d425d),LL(0x009a8dcf,0xe5b5c318), + LL(0x13221bc5,0x3360b25d),LL(0x6b3eeaf7,0x707baad2),LL(0x743a95a1,0xd7279ed8),LL(0x969e809f,0x7450a875), LL(0xe5d0338f,0x32b6bd53),LL(0x2b883bbc,0x1e77f7af),LL(0x1063ecd0,0x90da12cc),LL(0xc315be47,0xe2697b58), + LL(0xda85d534,0x2771a5bd),LL(0xff980eea,0x53e78c1f),LL(0x900385e7,0xadf1cf84),LL(0xc9387b62,0x7d3b14f6), LL(0xcb8f2bd2,0x170e74b0),LL(0x827fa993,0x2d50b486),LL(0xf6f32bab,0xcdbe8c9a),LL(0xc3b93ab8,0x55e906b0), + LL(0x8fe280d1,0x747f22fc),LL(0xb2e114ab,0xcd8e0de5),LL(0xe10b68b0,0x5ab7dbeb),LL(0xa480d4b2,0x9dc63a9c), LL(0x4be1495f,0x78d4bc3b),LL(0x9359122d,0x25eb3db8),LL(0x0809cbdc,0x3f8ac05b),LL(0xd37c702f,0xbf4187bb), + LL(0x1416a6a5,0x84cea069),LL(0x43ef881c,0x8f860c79),LL(0x38038a5d,0x41311f8a),LL(0xfc612067,0xe78c2ec0), LL(0x5ad73581,0x494d2e81),LL(0x59604097,0xb4cc9e00),LL(0xf3612cba,0xff558aec),LL(0x9e36c39e,0x35beef7a), + LL(0xdbcf41b9,0x1845c7cf),LL(0xaea997c0,0x5703662a),LL(0xe402f6d8,0x8b925afe),LL(0x4dd72162,0xd0a1b1ae), LL(0x03c41c4b,0x9f47b375),LL(0x0391d042,0xa023829b),LL(0x503b8b0a,0x5f5045c3),LL(0x98c010e5,0x123c2688), + LL(0x36ba06ee,0x324ec0cc),LL(0x3dd2cc0c,0xface3115),LL(0xf333e91f,0xb364f3be),LL(0x28e832b0,0xef8aff73), LL(0x2d05841b,0x1e9bad04),LL(0x356a21e2,0x42f0e3df),LL(0x4add627e,0xa3270bcb),LL(0xd322e711,0xb09a8158), + LL(0x0fee104a,0x86e326a1),LL(0x3703f65d,0xad7788f8),LL(0x47bc4833,0x7e765430),LL(0x2b9b893a,0x6cee582b), LL(0xe8f55a7b,0x9cd2a167),LL(0xd9e4190d,0xefbee3c6),LL(0xd40c2e9d,0x33ee7185),LL(0xa380b548,0x844cc9c5), + LL(0x66926e04,0x323f8ecd),LL(0x8110c1ba,0x0001e38f),LL(0xfc6a7f07,0x8dbcac12),LL(0x0cec0827,0xd65e1d58), LL(0xbe76ca2d,0xd2cd4141),LL(0xe892f33a,0x7895cf5c),LL(0x367139d2,0x956d230d),LL(0xd012c4c1,0xa91abd3e), + LL(0x87eb36bf,0x34fa4883),LL(0x914b8fb4,0xc5f07102),LL(0xadb9c95f,0x90f0e579),LL(0x28888195,0xfe6ea8cb), LL(0xedfa9284,0x7b9b5065),LL(0x2b8c8d65,0x6c510bd2),LL(0xcbe8aafd,0xd7b8ebef),LL(0x96b1da07,0xedb3af98), + LL(0x6295d426,0x28ff779d),LL(0x3fa3ad7b,0x0c4f6ac7),LL(0x8b8e2604,0xec44d054),LL(0x8b0050e1,0x9b32a66d), LL(0xf0476ce2,0x1f943366),LL(0xa602c7b4,0x7554d953),LL(0x524f2809,0xbe35aca6),LL(0xfd4edbea,0xb6881229), + LL(0x508efb63,0xe8cd0c8f),LL(0x6abcefc7,0x9eb5b5c8),LL(0xb441ab4f,0xf5621f5f),LL(0xb76a2b22,0x79e6c046), LL(0xe37a1f69,0x74a4792c),LL(0x03542b60,0xcbd252cb),LL(0xb3c20bd3,0x785f65d5),LL(0x4fabc60c,0x8dea6143), + LL(0xde673629,0x45e21446),LL(0x703c2d21,0x57f7aa1e),LL(0x98c868c7,0xa0e99b7f),LL(0x8b641676,0x4e42f66d), LL(0x91077896,0x602884dc),LL(0xc2c9885b,0xa0d690cf),LL(0x3b9a5187,0xfeb4da33),LL(0x153c87ee,0x5f789598), + LL(0x52b16dba,0x2192dd47),LL(0x3524c1b1,0xdeefc0e6),LL(0xe4383693,0x465ea76e),LL(0x361b8d98,0x79401711), LL(0xf21a15cb,0xa5f9ace9),LL(0xefee9aeb,0x73d26163),LL(0xe677016c,0xcca844b3),LL(0x57eaee06,0x6c122b07), + LL(0x15f09690,0xb782dce7),LL(0x2dfc0fc9,0x508b9b12),LL(0x65d89fc6,0x9015ab4b),LL(0xd6d5bb0f,0x5e79dab7), LL(0x6c775aa2,0x64f021f0),LL(0x37c7eca1,0xdf09d8cc),LL(0xef2fa506,0x9a761367),LL(0x5b81eec6,0xed4ca476), + LL(0x10bbb8b5,0x262ede36),LL(0x0641ada3,0x0737ce83),LL(0xe9831ccc,0x4c94288a),LL(0x8065e635,0x487fc1ce), LL(0xb8bb3659,0xb13d7ab3),LL(0x855e4120,0xdea5df3e),LL(0x85eb0244,0xb9a18573),LL(0xa7cfe0a3,0x1a1b8ea3), + LL(0x67b0867c,0x3b837119),LL(0x9d364520,0x8d5e0d08),LL(0xd930f0e3,0x52dccc1e),LL(0xbf20bbaf,0xefbbcec7), LL(0x0263ad10,0x99cffcab),LL(0xfcd18f8a,0xd8199e6d),LL(0xe9f10617,0x64e2773f),LL(0x08704848,0x0079e8e1), + LL(0x8a342283,0x1169989f),LL(0xa83012e6,0x8097799c),LL(0x8a6a9001,0xece966cb),LL(0x072ac7fc,0x93b3afef), LL(0x2db3d5ba,0xe6893a2a),LL(0x89bf4fdc,0x263dc462),LL(0xe0396673,0x8852dfc9),LL(0x3af362b6,0x7ac70895), + LL(0x5c2f342b,0xbb9cce4d),LL(0xb52d7aae,0xbf80907a),LL(0x2161bcd0,0x97f3d3cd),LL(0x0962744d,0xb25b0834), LL(0x6c3a1dda,0xc5b18ea5),LL(0x06c92317,0xfe4ec7eb),LL(0xad1c4afe,0xb787b890),LL(0x0ede801a,0xdccd9a92), + LL(0xdb58da1f,0x9ac6ddda),LL(0xb8cae6ee,0x22bbc12f),LL(0x815c4a43,0xc6f8bced),LL(0xf96480c7,0x8105a92c), LL(0x7a859d51,0x0dc3dbf3),LL(0x3041196b,0xe3ec7ce6),LL(0x0d1067c9,0xd9f64b25),LL(0x3d1f8dd8,0xf2321321), + LL(0x76497ee8,0x8b5c619c),LL(0xc717370e,0x5d2b0ac6),LL(0x4fcf68e1,0x98204cb6),LL(0x62bc6792,0x0bdec211), LL(0xa63b1011,0x6973ccef),LL(0xe0de1ac5,0xf9e3fa97),LL(0x3d0e0c8b,0x5efb693e),LL(0xd2d4fcb4,0x037248e9), +}, +/* digit=36 base_pwr=2^252 */ +{ + LL(0x1ec34f9e,0x80802dc9),LL(0x33810603,0xd8772d35),LL(0x530cb4f3,0x3f06d66c),LL(0xc475c129,0x7be5ed0d), LL(0x31e82b10,0xcb9e3c19),LL(0xc9ff6b4c,0xc63d2857),LL(0x92a1b45e,0xb92118c6),LL(0x7285bbca,0x0aec4414), + LL(0x1e29a3ef,0xfc189ae7),LL(0x4c93302e,0xcbe906f0),LL(0xceaae10e,0xd0107914),LL(0xb68e19f8,0xb7a23f34), LL(0xefd2119d,0xe9d875c2),LL(0xfcadc9c8,0x03198c6e),LL(0x4da17113,0x65591bf6),LL(0x3d443038,0x3cf0bbf8), + LL(0x2b724759,0xae485bb7),LL(0xb2d4c63a,0x945353e1),LL(0xde7d6f2c,0x82159d07),LL(0x4ec5b109,0x389caef3), LL(0xdb65ef14,0x4a8ebb53),LL(0xdd99de43,0x2dc2cb7e),LL(0x83f2405f,0x816fa3ed),LL(0xc14208a3,0x73429bb9), + LL(0xb01e6e27,0xb618d590),LL(0xe180b2dc,0x047e2ccd),LL(0x04aea4a9,0xd1b299b5),LL(0x9fa403a4,0x412c9e1e), LL(0x79407552,0x88d28a36),LL(0xf332b8e3,0x49c50136),LL(0xe668de19,0x3a1b6fcc),LL(0x75122b97,0x178851bc), + LL(0xfb85fa4c,0xb1e13752),LL(0x383c8ce9,0xd61257ce),LL(0xd2f74dae,0xd43da670),LL(0xbf846bbb,0xa35aa23f), LL(0x4421fc83,0x5e74235d),LL(0xc363473b,0xf6df8ee0),LL(0x3c4aa158,0x34d7f52a),LL(0x9bc6d22e,0x50d05aab), + LL(0xa64785f4,0x8c56e735),LL(0x5f29cd07,0xbc56637b),LL(0x3ee35067,0x53b2bb80),LL(0xdc919270,0x50235a0f), LL(0xf2c4aa65,0x191ab6d8),LL(0x8396023b,0xc3475831),LL(0xf0f805ba,0x80400ba5),LL(0x5ec0f80f,0x8881065b), + LL(0xcc1b5e83,0xc370e522),LL(0x860b8bfb,0xde2d4ad1),LL(0x67b256df,0xad364df0),LL(0xe0138997,0x8f12502e), LL(0x7783920a,0x503fa0dc),LL(0xc0bc866a,0xe80014ad),LL(0xd3064ba6,0x3f89b744),LL(0xcba5dba5,0x03511dcd), + LL(0x95a7b1a2,0x197dd46d),LL(0x3c6341fb,0x9c4e7ad6),LL(0x484c2ece,0x426eca29),LL(0xde7f4f8a,0x9211e489), LL(0xc78ef1f4,0x14997f6e),LL(0x06574586,0x2b2c0910),LL(0x1c3eede8,0x17286a6e),LL(0x0f60e018,0x25f92e47), + LL(0x31890a36,0x805c5646),LL(0x57feea5b,0x703ef600),LL(0xaf3c3030,0x389f747c),LL(0x54dd3739,0xe0e5daeb), LL(0xc9c9f155,0xfe24a4c3),LL(0xb5393962,0x7e4bf176),LL(0xaf20bf29,0x37183de2),LL(0xf95a8c3b,0x4a1bd7b5), + LL(0x46191d3d,0xa83b9699),LL(0x7b87f257,0x281fc8dd),LL(0x54107588,0xb18e2c13),LL(0x9b2bafe8,0x6372def7), LL(0x0d8972ca,0xdaf4bb48),LL(0x56167a3f,0x3f2dd4b7),LL(0x84310cf4,0x1eace32d),LL(0xe42700aa,0xe3bcefaf), + LL(0xd785e73d,0x5fe5691e),LL(0x2ea60467,0xa5db5ab6),LL(0xdfc6514a,0x02e23d41),LL(0xe03c3665,0x35e8048e), LL(0x1adaa0f8,0x3f8b118f),LL(0x84ce1a5a,0x28ec3b45),LL(0x2c6646b8,0xe8cacc6e),LL(0xdbd0e40f,0x1343d185), + LL(0xcaaa358c,0xe5d7f844),LL(0x9924182a,0x1a1db7e4),LL(0x9c875d9a,0xd64cd42d),LL(0x042eeec8,0xb37b515f), LL(0x7b165fbe,0x4d4dd409),LL(0xe206eff3,0xfc322ed9),LL(0x59b7e17e,0x7dee4102),LL(0x8236ca00,0x55a481c0), + LL(0xc23fc975,0x8c885312),LL(0x05d6297b,0x15715806),LL(0xf78edd39,0xa078868e),LL(0x03c45e52,0x956b31e0), LL(0xff7b33a6,0x470275d5),LL(0x0c7e673f,0xc8d5dc3a),LL(0x7e2f2598,0x419227b4),LL(0x4c14a975,0x8b37b634), + LL(0x8b11888c,0xd0667ed6),LL(0x803e25dc,0x5e0e8c3e),LL(0xb987a24a,0x34e5d0dc),LL(0xae920323,0x9f40ac3b), LL(0x34e0f63a,0x5463de95),LL(0x6b6328f9,0xa128bf92),LL(0xda64f1b7,0x491ccd7c),LL(0xc47bde35,0x7ef1ec27), + LL(0xa36a2737,0xa857240f),LL(0x63621bc1,0x35dc1366),LL(0xd4fb6897,0x7a3a6453),LL(0xc929319d,0x80f1a439), LL(0xf8cb0ba0,0xfc18274b),LL(0x8078c5eb,0xb0b53766),LL(0x1e01d0ef,0xfb0d4924),LL(0x372ab09c,0x50d7c67d), + LL(0x3aeac968,0xb4e370af),LL(0xc4b63266,0xe4f7fee9),LL(0xe3ac5664,0xb4acd4c2),LL(0xceb38cbf,0xf8910bd2), LL(0xc9c0726e,0x1c3ae50c),LL(0xd97b40bf,0x15309569),LL(0xfd5a5a1b,0x70884b7f),LL(0xef8314cd,0x3890896a), + LL(0xa5618c93,0x58e1515c),LL(0x77d942d1,0xe665432b),LL(0xb6f767a8,0xb32181bf),LL(0x3a604110,0x753794e8), LL(0xe8c0dbcc,0x09afeb7c),LL(0x598673a3,0x31e02613),LL(0x7d46db00,0x5d98e557),LL(0x9d985b28,0xfc21fb8c), + LL(0xb0843e0b,0xc9040116),LL(0x69b04531,0x53b1b3a8),LL(0x85d7d830,0xdd1649f0),LL(0xcb7427e8,0xbb3bcc87), LL(0xc93dce83,0x77261100),LL(0xa1922a2a,0x7e79da61),LL(0xf3149ce8,0x587a2b02),LL(0xde92ec83,0x147e1384), + LL(0xaf077f30,0x484c83d3),LL(0x0658b53a,0xea78f844),LL(0x027aec53,0x912076c2),LL(0x93c8177d,0xf34714e3), LL(0xc2376c84,0x37ef5d15),LL(0x3d1aa783,0x8315b659),LL(0xef852a90,0x3a75c484),LL(0x16086bd4,0x0ba0c58a), + LL(0x529a6d48,0x29688d7a),LL(0xc2f19203,0x9c7f250d),LL(0x682e2df9,0x123042fb),LL(0xad8121bc,0x2b7587e7), LL(0xe0182a65,0x30fc0233),LL(0xe3e1128a,0xb82ecf87),LL(0x93fb098f,0x71682861),LL(0x85e9e6a7,0x043e21ae), + LL(0x66c834ea,0xab5b49d6),LL(0x47414287,0x3be43e18),LL(0x219a2a47,0xf40fb859),LL(0xcc58df3c,0x0e6559e9), LL(0x0c6615b4,0xfe1dfe8e),LL(0x56459d70,0x14abc8fd),LL(0x05de0386,0x7be0fa8e),LL(0xe9035c7c,0x8e63ef68), + LL(0x53b31e91,0x116401b4),LL(0x4436b4d8,0x0cba7ad4),LL(0x107afd66,0x9151f9a0),LL(0x1f0ee4c4,0xafaca8d0), LL(0x9ee9761c,0x75fe5c1d),LL(0xf0c0588f,0x3497a16b),LL(0x0304804c,0x3ee2bebd),LL(0xc2c990b9,0xa8fb9a60), + LL(0x39251114,0xd14d32fe),LL(0xcac73366,0x36bf25bc),LL(0xdba7495c,0xc9562c66),LL(0x46ad348b,0x324d301b), LL(0xd670407e,0x9f46620c),LL(0xe3733a01,0x0ea8d4f1),LL(0xb0c324e0,0xd396d532),LL(0x03c317cd,0x5b211a0e), + LL(0x5ffe7b37,0x090d7d20),LL(0x1747d2da,0x3b7f3efb),LL(0xb54fc519,0xa2cb525f),LL(0xf66a971e,0x6e220932), LL(0xb486d440,0xddc160df),LL(0x3fe13465,0x7fcfec46),LL(0x76e4c151,0x83da7e4e),LL(0xd8d302b5,0xd6fa48a1), + LL(0x5872cd88,0xc6304f26),LL(0x278b90a1,0x806c1d3c),LL(0xcaf0bc1c,0x3553e725),LL(0xbb9d8d5c,0xff59e603), LL(0x7a0b85dd,0xa4550f32),LL(0x93ecc217,0xdec5720a),LL(0x69d62213,0x0b88b741),LL(0x5b365955,0x7212f245), + LL(0xb5cae787,0x20764111),LL(0x1dfd3124,0x13cb7f58),LL(0x1175aefb,0x2dca77da),LL(0xffaae775,0xeb75466b), LL(0xdb6cff32,0x74d76f3b),LL(0x61fcda9a,0x7440f37a),LL(0xb525028b,0x1bb3ac92),LL(0xa1975f29,0x20fbf8f7), + LL(0xdf83097f,0x982692e1),LL(0x554b0800,0x28738f6c),LL(0xa2ce2f2f,0xdc703717),LL(0x40814194,0x7913b93c), LL(0x1fe89636,0x04924593),LL(0xf78834a6,0x7b98443f),LL(0x5114a5a1,0x11c6ab01),LL(0xffba5f4c,0x60deb383), + LL(0x01a982e6,0x4caa54c6),LL(0x3491cd26,0x1dd35e11),LL(0x7cbd6b05,0x973c315f),LL(0x52494724,0xcab00775), LL(0x6565e15a,0x04659b1f),LL(0x8c8fb026,0xbf30f529),LL(0xa8a0de37,0xfc21641b),LL(0xfa5e5114,0xe9c7a366), + LL(0x52f03ad8,0xdb849ca5),LL(0x024e35c0,0xc7e8dbe9),LL(0xcfc3c789,0xa1a2bbac),LL(0x9c26f262,0xbf733e7d), LL(0xb8444823,0x882ffbf5),LL(0x6bf8483b,0xb7224e88),LL(0x65bef640,0x53023b8b),LL(0xd4d5f8cd,0xaabfec91), + LL(0x079ea1bd,0xa40e1510),LL(0xd05d5d26,0x1ad9addc),LL(0x13e68d4f,0xdb3f2eab),LL(0x640f803f,0x1cff1ae2), LL(0xd4cee117,0xe0e7b749),LL(0x4036d909,0x8e9f275b),LL(0x8f4d4c38,0xce34e31d),LL(0xd75130fc,0x22b37f69), + LL(0xb4014604,0x83e0f1fd),LL(0x89415078,0xa8ce9919),LL(0x41792efe,0x82375b75),LL(0x97d4515b,0x4f59bf5c), LL(0x923a277d,0xac4f324f),LL(0x650f3406,0xd9bc9b7d),LL(0x8a39bc51,0xc6fa87d1),LL(0x5ccc108f,0x82588530), + LL(0x82e4c634,0x5ced3c9f),LL(0x3a4464f8,0x8efb8314),LL(0x7a1dca25,0xe706381b),LL(0x5a2a412b,0x6cd15a3c), LL(0xbfcd8fb5,0x9347a8fd),LL(0x6e54cd22,0x31db2eef),LL(0xf8d8932f,0xc4aeb11e),LL(0x344411af,0x11e7c1ed), + LL(0xdc9a151e,0x2653050c),LL(0x3bb0a859,0x9edbfc08),LL(0xfd5691e7,0x926c81c7),LL(0x6f39019a,0x9c1b2342), LL(0x7f8474b9,0x64a81c8b),LL(0x01761819,0x90657c07),LL(0x55e0375a,0x390b3331),LL(0xb6ebc47d,0xc676c626), + LL(0xb7d6dee8,0x51623247),LL(0x79659313,0x0948d927),LL(0xe9ab35ed,0x99700161),LL(0x8ddde408,0x06cc32b4), LL(0x061ef338,0x6f2fd664),LL(0xc202e9ed,0x1606fa02),LL(0x929ba99b,0x55388bc1),LL(0x1e81df69,0xc4428c5e), + LL(0xf91b0b2a,0xce2028ae),LL(0xf03dfd3f,0xce870a23),LL(0x0affe8ed,0x66ec2c87),LL(0x284d0c00,0xb205fb46), LL(0x44cefa48,0xbf5dffe7),LL(0xa19876d7,0xb6fc37a8),LL(0x08b72863,0xbecfa84c),LL(0x2576374f,0xd7205ff5), + LL(0x8887de41,0x80330d32),LL(0x869ea534,0x5de0df0c),LL(0x3c56ea17,0x13f42753),LL(0x452b1a78,0xeb1f6069), LL(0xe30ea15c,0x50474396),LL(0xc1494125,0x575816a1),LL(0xfe6bb38f,0xbe1ce55b),LL(0x96ae30f7,0xb901a948), + LL(0xd8fc3548,0xe5af0f08),LL(0xd73bfd08,0x5010b5d0),LL(0x53fe655a,0x993d2880),LL(0x1c1309fd,0x99f2630b), LL(0xb4e3b76f,0xd8677baf),LL(0xb840784b,0x14e51ddc),LL(0xbf0092ce,0x326c750c),LL(0xf528320f,0xc83d306b), + LL(0x77d4715c,0xc4456715),LL(0x6b703235,0xd30019f9),LL(0xd669e986,0x207ccb2e),LL(0xf6dbfc28,0x57c824af), LL(0xd8f92a23,0xf0eb532f),LL(0x9bb98fd2,0x4a557fd4),LL(0xc1e6199a,0xa57acea7),LL(0x8b94b1ed,0x0c663820), + LL(0xf83a9266,0x9b42be8f),LL(0x0101bd45,0xc7741c97),LL(0x07bd9ceb,0x95770c11),LL(0x8b2e0744,0x1f50250a), LL(0x1477b654,0xf762eec8),LL(0x15efe59a,0xc65b900e),LL(0x9546a897,0x88c96148),LL(0xc30b4d7c,0x7e8025b3), + LL(0x12045cf9,0xae4065ef),LL(0x9ccce8bd,0x6fcb2caf),LL(0xf2cf6525,0x1fa0ba4e),LL(0xcb72c312,0xf683125d), LL(0xe312410e,0xa01da4ea),LL(0x6cd8e830,0x67e28677),LL(0x98fb3f07,0xabd95752),LL(0xeef649a5,0x05f11e11), + LL(0x9d3472c2,0xba47faef),LL(0xc77d1345,0x3adff697),LL(0xdd15afee,0x4761fa04),LL(0xb9e69462,0x64f1f61a), LL(0x9bfb9093,0xfa691fab),LL(0xa1133dfe,0x3df8ae8f),LL(0x58cc710d,0xcd5f8967),LL(0x16c7fe79,0xfbb88d50), + LL(0xe88c50d1,0x8e011b4c),LL(0xa8771c4f,0x7532e807),LL(0xe2278ee4,0x64c78a48),LL(0x3845072a,0x0b283e83), LL(0x49e69274,0x98a6f291),LL(0x1868b21c,0xb96e9668),LL(0xb1a8908e,0x38f0adc2),LL(0x1feb829d,0x90afcff7), + LL(0x210b0856,0x9915a383),LL(0xdef04889,0xa5a80602),LL(0x7c64d509,0x800e9af9),LL(0xb8996f6f,0x81382d0b), LL(0x81927e27,0x490eba53),LL(0x4af50182,0x46c63b32),LL(0xd3ad62ce,0x784c5fd9),LL(0xf8ae8736,0xe4fa1870), + LL(0xd7466b25,0x4ec9d0bc),LL(0xdb235c65,0x84ddbe1a),LL(0x163c1688,0x5e2645ee),LL(0x00eba747,0x570bd00e), LL(0x128bfa0f,0xfa51b629),LL(0x6c1d3b68,0x92fce1bd),LL(0xb66778b1,0x3e7361dc),LL(0x5561d2bb,0x9c7d249d), + LL(0x0bbc6229,0xa40b28bf),LL(0xdfd91497,0x1c83c05e),LL(0xf083df05,0x5f9f5154),LL(0xeee66c9d,0xbac38b3c), LL(0xec0dfcfd,0xf71db7e3),LL(0x8b0a8416,0xf2ecda8e),LL(0x7812aa66,0x52fddd86),LL(0x4e6f4272,0x2896ef10), + LL(0x0fe9a745,0xff27186a),LL(0x49ca70db,0x08249fcd),LL(0x441cac49,0x7425a2e6),LL(0xece5ff57,0xf4a0885a), LL(0x7d7ead58,0x6e2cb731),LL(0x1898d104,0xf96cf7d6),LL(0x4f2c9a89,0xafe67c9d),LL(0x1c7bf5bc,0x89895a50), + LL(0x573cecfa,0xdc7cb8e5),LL(0xd15f03e6,0x66497eae),LL(0x3f084420,0x6bc0de69),LL(0xacd532b0,0x323b9b36), LL(0x0115a3c1,0xcfed390a),LL(0x2d65ca0e,0x9414c40b),LL(0x2f530c78,0x641406bd),LL(0x833438f2,0x29369a44), + LL(0x903fa271,0x996884f5),LL(0xb9da921e,0xe6da0fd2),LL(0x5db01e54,0xa6f2f269),LL(0x6876214e,0x1ee3e9bd), LL(0xe27a9497,0xa26e181c),LL(0x8e215e04,0x36d254e4),LL(0x252cabca,0x42f32a6c),LL(0x80b57614,0x99481487), + LL(0x40d9cae1,0x4c4dfe69),LL(0x11a10f09,0x05869580),LL(0x3491b64b,0xca287b57),LL(0x3fd4a53b,0x77862d5d), LL(0x50349126,0xbf94856e),LL(0x71c5268f,0x2be30bd1),LL(0xcbb650a6,0x10393f19),LL(0x778cf9fd,0x639531fe), + LL(0xb2935359,0x02556a11),LL(0xaf8c126e,0xda38aa96),LL(0x0960167f,0x47dbe6c2),LL(0x501901cd,0x37bbabb6), LL(0x2c947778,0xb6e979e0),LL(0x7a1a1dc6,0xd69a5175),LL(0x9d9faf0c,0xc3ed5095),LL(0x1d5fa5f0,0x4dd9c096), + LL(0x64f16ea8,0xa0c4304d),LL(0x7e718623,0x8b1cac16),LL(0x7c67f03e,0x0b576546),LL(0xcbd88c01,0x559cf5ad), LL(0x0e2af19a,0x074877bb),LL(0xa1228c92,0x1f717ec1),LL(0x326e8920,0x70bcb800),LL(0x4f312804,0xec6e2c5c), + LL(0x3fca4752,0x426aea7d),LL(0x2211f62a,0xf12c0949),LL(0x7be7b6b5,0x24beecd8),LL(0x36d7a27d,0xb77eaf4c), LL(0xfda78fd3,0x154c2781),LL(0x264eeabe,0x848a83b0),LL(0x4ffe2bc4,0x81287ef0),LL(0xb6b6fc2a,0x7b6d88c6), + LL(0xce417d99,0x805fb947),LL(0x8b916cc4,0x4b93dcc3),LL(0x21273323,0x72e65bb3),LL(0x6ea9886e,0xbcc1badd), LL(0x4bc5ee85,0x0e223011),LL(0xc18ee1e4,0xa561be74),LL(0xa6bcf1f1,0x762fd2d4),LL(0x95231489,0x50e6a5a4), + LL(0xa00b500b,0xca96001f),LL(0x5d7dcdf5,0x5c098cfc),LL(0x8c446a85,0xa64e2d2e),LL(0x971f3c62,0xbae9bcf1), LL(0x8435a2c5,0x4ec22683),LL(0x4bad4643,0x8ceaed6c),LL(0xccccf4e3,0xe9f8fb47),LL(0x1ce3b21e,0xbd4f3fa4), + LL(0xa3db3292,0xd79fb110),LL(0xb536c66a,0xe28a37da),LL(0x8e49e6a9,0x279ce87b),LL(0xfdcec8e3,0x70ccfe8d), LL(0x3ba464b2,0x2193e4e0),LL(0xaca9a398,0x0f39d60e),LL(0xf82c12ab,0x7d7932af),LL(0x91e7e0f7,0xd8ff50ed), + LL(0xfa28a7e0,0xea961058),LL(0x0bf5ec74,0xc726cf25),LL(0xdb229666,0xe74d55c8),LL(0xa57f5799,0x0bd9abbf), LL(0x4dfc47b3,0x7479ef07),LL(0x0c52f91d,0xd9c65fc3),LL(0x36a8bde2,0x8e0283fe),LL(0x7d4b7280,0xa32a8b5e), + LL(0x12e83233,0x6a677c61),LL(0xdcc9bf28,0x0fbb3512),LL(0x0d780f61,0x562e8ea5),LL(0x1dc4e89c,0x0db8b22b), LL(0x89be0144,0x0a6fd1fb),LL(0xca57113b,0x8c77d246),LL(0xff09c91c,0x4639075d),LL(0x5060824c,0x5b47b17f), + LL(0x16287b52,0x58aea2b0),LL(0xd0cd8eb0,0xa1343520),LL(0xc5d58573,0x6148b4d0),LL(0x291c68ae,0xdd2b6170), LL(0x1da3b3b7,0xa61b3929),LL(0x08c4ac10,0x5f946d79),LL(0x7217d583,0x4105d4a5),LL(0x25e6de5e,0x5061da3d), + LL(0xec1b4991,0x3113940d),LL(0x36f485ae,0xf12195e1),LL(0x731a2ee0,0xa7507fb2),LL(0x6e9e196e,0x95057a8e), LL(0x2e130136,0xa3c2c911),LL(0x33c60d15,0x97dfbb36),LL(0xb300ee2b,0xcaf3c581),LL(0xf4bac8b8,0x77f25d90), + LL(0x6d840cd6,0xdb1c4f98),LL(0xe634288c,0x471d62c0),LL(0xcec8a161,0x8ec2f85e),LL(0xfa6f4ae2,0x41f37cbc), LL(0x4b709985,0x6793a20f),LL(0xefa8985b,0x7a7bd33b),LL(0x938e6446,0x2c6a3fbd),LL(0x2a8d47c1,0x19042619), + LL(0xcc36975f,0x16848667),LL(0x9d5f1dfb,0x02acf168),LL(0x613baa94,0x62d41ad4),LL(0x9f684670,0xb56fbb92), LL(0xe9e40569,0xce610d0d),LL(0x35489fef,0x7b99c65f),LL(0x3df18b97,0x0c88ad1b),LL(0x5d0e9edb,0x81b7d9be), + LL(0xc716cc0a,0xd85218c0),LL(0x85691c49,0xf4b5ff90),LL(0xce356ac6,0xa4fd666b),LL(0x4b327a7a,0x17c72895), LL(0xda6be7de,0xf93d5085),LL(0x3301d34e,0xff71530e),LL(0xd8f448e8,0x4cd96442),LL(0x2ed18ffa,0x9283d331), + LL(0x2a849870,0x4d33dd99),LL(0x41576335,0xa716964b),LL(0x179be0e5,0xff5e3a9b),LL(0x83b13632,0x5b9d6b1b), LL(0xa52f313b,0x3b8bd7d4),LL(0x637a4660,0xc9dd95a0),LL(0x0b3e218f,0x30035962),LL(0xc7b28a3c,0xce1481a3), + LL(0x43228d83,0xab41b43a),LL(0x4ad63f99,0x24ae1c30),LL(0x46a51229,0x8e525f1a),LL(0xcd26d2b4,0x14af860f), LL(0x3f714aa1,0xd6baef61),LL(0xeb78795e,0xf51865ad),LL(0xe6a9d694,0xd3e21fce),LL(0x8a37b527,0x82ceb1dd), +} +}; +#endif /* _DISABLE_ECP_256R1_HARDCODED_BP_TBL_ */ +#endif /* _IPP_DATA */ + + +IPP_OWN_DEFN (const cpPrecompAP*, gfpec_precom_nistP256r1_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 7, + /* select function */ p256r1_select_ap_w7, + /* precomputed data */ (BNU_CHUNK_T*)ec_p256r1_precomputed + }; + return &t; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpp384r1precomca.c b/plugin/ippcp/library/src/sources/ippcp/pcpp384r1precomca.c new file mode 100644 index 000000000..a0644d064 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpp384r1precomca.c @@ -0,0 +1,1524 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (P384r1 precomputed) +// +// +*/ +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +#define OPERAND_BITSIZE (384) +#define LEN_P384 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* P384 affine point */ +typedef struct{ + BNU_CHUNK_T X[LEN_P384]; + BNU_CHUNK_T Y[LEN_P384]; +} P384_POINT_AFFINE; + +extern const __ALIGN64 P384_POINT_AFFINE ec_p384r1_precomputed[77][16]; + + +#if defined ( _IPP_DATA ) + +#if !defined(_DISABLE_ECP_384R1_HARDCODED_BP_TBL_) +/* see ippcp_baseptbl.cpp test for generation details */ + +const __ALIGN64 P384_POINT_AFFINE ec_p384r1_precomputed[77][16] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0x49c0b528,0x3dd07566),LL(0xa0d6ce38,0x20e378e2),LL(0x541b4d6e,0x879c3afc),LL(0x59a30eff,0x64548684),LL(0x614ede2b,0x812ff723),LL(0x299e1513,0x4d3aadc2), LL(0x4b03a4fe,0x23043dad),LL(0x7bb4a9ac,0xa1bfa8bf),LL(0x2e83b050,0x8bade756),LL(0x68f4ffd9,0xc6c35219),LL(0x3969a840,0xdd800226),LL(0x5a15c5e9,0x2b78abc2), + LL(0x783dde91,0xc8229e55),LL(0x022b53f0,0x8e6c8f2e),LL(0xff9d48a1,0x3504e6f0),LL(0xf0687f50,0xda821495),LL(0x2de4b506,0x9c90a4fd),LL(0x427460c3,0xdb93b776), LL(0x3140bfda,0x42ea8463),LL(0xc2aaccd8,0xe8e8e4a8),LL(0xdc588258,0x15e4f18b),LL(0x5172bad9,0x09f1fe41),LL(0x00b0e684,0x070d4309),LL(0x123df0c2,0xe34947f7), + LL(0xc1dc4073,0x05e4dbe6),LL(0xf04f779c,0xc54ea9ff),LL(0xa170ccf0,0x6b2034e9),LL(0xd51c6c3e,0x3a48d732),LL(0x263aa470,0xe36f7e2d),LL(0xe7c1c3ac,0xd283fe68), LL(0xc04ee157,0x7e284821),LL(0x7ae0e36d,0x92d789a7),LL(0x4ef67446,0x132663c0),LL(0xd2e1d0b4,0x68012d5a),LL(0x5102b339,0xf6db68b1),LL(0x983292af,0x465465fc), + LL(0xebb68f2c,0x0aae8477),LL(0xee0421e3,0x30594ccb),LL(0x0aecac46,0x2e4f153b),LL(0x736400ad,0x078358d4),LL(0xd685d979,0xfb40f647),LL(0x34179228,0xcfeee6dd), LL(0x9b3a03b2,0x54f3e8e7),LL(0x7bfec97e,0xe74bb7f1),LL(0x4c542ad1,0x8e3e61a3),LL(0x0418c693,0x147162d3),LL(0x3820017d,0xe607b9e3),LL(0x303df319,0x50946875), + LL(0x68f1f0df,0xbb595eba),LL(0xcc873466,0xc185c0cb),LL(0x293c703b,0x7f1eb1b5),LL(0xaacc05e6,0x60db2cf5),LL(0xe2e8e4c6,0xc676b987),LL(0x1d178ffb,0xe1bb26b1), LL(0x7073fa21,0x2b694ba0),LL(0x72f34566,0x22c16e2e),LL(0x01c35b99,0x80b61b31),LL(0x982c0411,0x4b237faf),LL(0x24de236d,0xe6c59440),LL(0xe209e4a3,0x4db1c9d6), + LL(0x7d56dad8,0x7eb5c931),LL(0x39d3413a,0xcb2454b3),LL(0x580d57f2,0xec52930f),LL(0x1bdf6015,0x2a33f666),LL(0x2b02d33b,0x4f0f6a96),LL(0xf0430c40,0xc482e189), LL(0xa7b08203,0x3f62b16e),LL(0x5b3d4dce,0x739ac69d),LL(0xb79e33b0,0x8bd4bffc),LL(0x1b546f05,0x93c9e5f6),LL(0xdf21559a,0x586d8ede),LL(0xaf2a9eba,0xc9962152), + LL(0x7d69222b,0xdf13b9d1),LL(0x874774b1,0x4ce6415f),LL(0x211faa95,0x731edcf8),LL(0x659753ed,0x5f4215d1),LL(0x9db2df55,0xf893db58),LL(0x1c89025b,0x932c9f81), LL(0x7706a61e,0x0996b220),LL(0xa8641c79,0x135349d5),LL(0x50130844,0x65aad76f),LL(0x01fff780,0x0ff37c04),LL(0x693b0706,0xf57f238e),LL(0xaf6c9b3e,0xd90a16b6), + LL(0xdd9bcbba,0x23f60a05),LL(0xae9b587a,0x9e336de5),LL(0x93d7e30f,0x1c5c2e71),LL(0x4f3ddb37,0x1d9aebd6),LL(0x16b66423,0x1c7b5fe1),LL(0x349cd9b1,0x5db4f184), LL(0xe6655a44,0x0d2cfe83),LL(0xb7e55e87,0x836dbb36),LL(0x7d8686e4,0x701754bf),LL(0xa42dbba2,0xe9923263),LL(0xc48ecf0e,0x7008d943),LL(0x0d27ef61,0x3c0c6dd7), + LL(0x2353b92f,0x2f5d200e),LL(0x3fd7e4f9,0xe35d8729),LL(0xa96d745d,0x26094833),LL(0x3cbfff3f,0xdc351dc1),LL(0xdad54d6a,0x26d464c6),LL(0x53636c6a,0x5cab1d1d), LL(0xb18ec0b0,0xf2813072),LL(0xd742aa2f,0x3777e270),LL(0x033ca7c2,0x27f061c7),LL(0x68ead0d8,0xa6ecaccc),LL(0xee69a754,0x7d9429f4),LL(0x31e8f5c6,0xe7706334), + LL(0xc8d99c02,0x845539d3),LL(0xe58d6787,0x2a15a9a6),LL(0xab225fa3,0xe9f6368e),LL(0xeb32cabe,0x54a612d7),LL(0x5c4845ec,0xc2f64602),LL(0xdb1c212e,0xa91a5280), LL(0xe67b5fce,0xbb971f78),LL(0x13b9e85c,0x03a530eb),LL(0x794eabfd,0x592ac0ba),LL(0xcfd7fd1d,0x81961b8c),LL(0x47a9b8aa,0x3e03370a),LL(0xc80174e8,0x6eb995be), + LL(0xb68b8c7d,0xc7708b19),LL(0x44377aba,0x4532077c),LL(0x6cdad64f,0x0dcc6770),LL(0x147b6602,0x01b8bf56),LL(0xf0561d79,0xf8d89885),LL(0x7ba9c437,0x9c19e9fc), LL(0xbdc4ba25,0x764eb146),LL(0xac144b83,0x604fe46b),LL(0x8a77e780,0x3ce81329),LL(0xfe9e682e,0x2e070f36),LL(0x3a53287a,0x41821d0c),LL(0x3533f918,0x9aa62f9f), + LL(0x70313de0,0x3db84772),LL(0x5d970420,0xd4258cc5),LL(0xc8edfee1,0x03aced26),LL(0x35d77d83,0xf67eb422),LL(0xcf9ab45c,0x523c40db),LL(0x9c35b26d,0x627b415f), LL(0x8be55ed8,0xfacc45e4),LL(0x27aa651a,0x80d60af6),LL(0xd0e102ac,0x8c79848f),LL(0x66bed5af,0x40c64a4e),LL(0xf7942f0e,0x0329eab1),LL(0xf9c4af3d,0x0c6e430e), + LL(0x75ccbdfb,0x9b7aeb7e),LL(0xf6749a95,0xb25e28c5),LL(0x33b7d4ae,0x8a7a8e46),LL(0xd9c1bd56,0xdb5203a8),LL(0xed22df97,0xd2657265),LL(0x8cf23c94,0xb51c56e1), LL(0x6c3d812d,0xf4d39459),LL(0x87cae0c2,0xd8e88f1a),LL(0xcf4d0fe3,0x789a2a48),LL(0xfec38d60,0xb7feac2d),LL(0x3b490ec3,0x81fdbd1c),LL(0xcc6979e1,0x4617adb7), + LL(0x8f75244c,0x5865e501),LL(0x01ec909f,0xd02225fb),LL(0xb1f85c2a,0xca6b1af8),LL(0x88957166,0x44ce05ff),LL(0x5710c0c9,0x8058994c),LL(0x32f6b1ba,0x46d227c4), LL(0x03cb68e5,0xbe4b4a90),LL(0x730a99d1,0x540b8b82),LL(0xe11dbbbf,0x1ecc8585),LL(0xd9c3b691,0x72445345),LL(0x13690a74,0x647d24db),LL(0xdefbadf5,0x4429839d), + LL(0x4709f4a9,0x446ad888),LL(0xec3dabd8,0x2b7210e2),LL(0x50e07b34,0x83ccf195),LL(0x789b3075,0x59500917),LL(0xeb085993,0x0fc01fd4),LL(0x4903026b,0xfb62d26f), LL(0x6fe989bb,0x2309cc9d),LL(0x144bd586,0x61609cbd),LL(0xde06610c,0x4b23d3a0),LL(0xd898f470,0xdddc2866),LL(0x400c5797,0x8733fc41),LL(0xd0bc2716,0x5a68c6fe), + LL(0x7c33ed91,0xda6e8a7f),LL(0x0ecdd2d8,0x992afb5b),LL(0x7917652a,0x37cf6551),LL(0x2887d5ff,0x317b63ea),LL(0x13bdc3fa,0x37065f53),LL(0x435abaa1,0xa10896aa), LL(0xefabca26,0x9b21615f),LL(0x230cf00d,0xeb07ddea),LL(0x154d410f,0x914871dc),LL(0xc88ee148,0xb333bdfb),LL(0xa72d1967,0x51c305c6),LL(0x81ef2513,0x659db481), +}, +/* digit=1 base_pwr=2^5 */ +{ + LL(0x8c0a64a4,0xad852b87),LL(0x08f779d5,0x0d784cf2),LL(0xc651b1dd,0x1896b9fc),LL(0x12e8dc87,0xba8953d6),LL(0xa631cfb0,0x3a9865ba),LL(0x626b3d79,0x5dd2a4a0), LL(0x687c20bb,0x1148bc72),LL(0xf2a52bfd,0xa372dfc2),LL(0x9448fd08,0x77315f9e),LL(0x0a2377b6,0x4bcb06f0),LL(0xb35b4ff0,0x73b42725),LL(0xaabca99f,0xc510ad93), + LL(0x8e89b258,0xed4de4f8),LL(0x297a9a37,0x957c980f),LL(0xf8a0580d,0xe04b3d30),LL(0xca57b7bd,0xa309199d),LL(0x3be44d56,0xfc8e87cf),LL(0xd1b30e5c,0x4f5d5ab6), LL(0x30a9325b,0xb213c6a0),LL(0xf091bc01,0x0fd1c52d),LL(0x1090fede,0xfe51bbbf),LL(0x301fe259,0x6d97cabc),LL(0x5ecd3fe8,0x3ee12789),LL(0x9404ca51,0x888b708b), + LL(0x1d15bba7,0xdc529385),LL(0x148840d4,0x8fd61e31),LL(0x52ce08f6,0xee21597e),LL(0x81998af2,0x26de4c65),LL(0x9741eb42,0xcb4aa43c),LL(0x39c18b96,0x8bf3dccc), LL(0xd872984e,0x66e1d5da),LL(0x7dd87c39,0x507e2405),LL(0x305ee4f0,0x8545396f),LL(0xc831254b,0xf9d19ea0),LL(0x5d5680b8,0xcee0842f),LL(0x5a4434a4,0xb257fb6c), + LL(0x8258030f,0xe484fd9f),LL(0xf21af80a,0x0f4fa5ef),LL(0x7c1c3984,0xc0dd449e),LL(0x18eb5195,0xf3133891),LL(0x777a16d2,0x0336aab8),LL(0xc241720a,0xa6661cc4), LL(0xa7efacd0,0x678db970),LL(0x6461e382,0x22896865),LL(0xa022c7a4,0x5d85a0e4),LL(0x34a02a6b,0xb01f1e04),LL(0xa5791ce3,0x2657eedd),LL(0xa277ac5b,0x239dcab2), + LL(0x0b3db49f,0x7f74672d),LL(0xadc8418d,0x026275e9),LL(0xfe7cc4ee,0x18866523),LL(0xbbf36aca,0x3546317b),LL(0x80caf049,0x282313fa),LL(0x9a49d91c,0x08275c9c), LL(0xab71c2a8,0xe41f92ec),LL(0x1dd95aae,0xb5674698),LL(0xa8c4dc57,0x82347685),LL(0xa847fd1e,0xf78b23d6),LL(0xb692f868,0x8194f070),LL(0xa5f2ad03,0xfe0dee06), + LL(0x22abee22,0x61361c06),LL(0x2f42a470,0xe82123bc),LL(0x3c6ceff4,0x2c97dda1),LL(0xadcb0453,0xc2eea21f),LL(0xc78ec9ff,0xdf2a4407),LL(0x9625c735,0x54557c55), LL(0x7c440c0a,0xc693c985),LL(0xe56622c1,0x918e7324),LL(0xa5f0900f,0x8f990d2b),LL(0xc6aeeaef,0xa5b7d193),LL(0x450456e3,0x9f053d95),LL(0xad418ef1,0xdf783b1c), + LL(0xbe6c3221,0x08d2ce13),LL(0x9c0624ea,0x0f53824c),LL(0x5da25412,0xad3ca744),LL(0x93fea7cc,0xecb38a41),LL(0xcba623c4,0x8ae838d8),LL(0x41d85222,0xa75c8da5), LL(0x290807c8,0x9f48b828),LL(0x22f4ab6a,0x4df75f09),LL(0x7cab82a9,0x02511a3e),LL(0x21da354e,0xcc052dc3),LL(0x03ca73e9,0x7db6c1f3),LL(0xcb99244e,0xca1d4279), + LL(0x6ae54da1,0x9a7a5b42),LL(0x7040b022,0xcfcadaab),LL(0x3d9f0e61,0x7539438e),LL(0xe328c2e2,0x013c6719),LL(0xcccbf891,0x7f4a706c),LL(0x735a2d28,0xa335ab82), LL(0x3d984124,0x46694ef0),LL(0xc166b337,0x0e0bdfab),LL(0x423d47e4,0x9d54ed8b),LL(0xf44c9180,0x8075a8cb),LL(0xabe9b384,0xd4f5b184),LL(0x41abdc75,0x424dd00b), + LL(0xf2432ae5,0x36137ae5),LL(0xad5f443d,0x2d941abc),LL(0xee013f80,0xe31e96f2),LL(0x26385266,0x24127d20),LL(0xeae97f8b,0xd4004cf3),LL(0x62527c9e,0xbf3b201a), LL(0xcb8a2a2f,0x0cd0fee1),LL(0x8fdceb43,0x48894469),LL(0x2250a356,0xe67565ba),LL(0x2ccfe7d1,0xbbb5f8ca),LL(0xa350fe88,0x431a268f),LL(0x4e5b64d2,0xd2eb0373), + LL(0xf5d0255f,0x2ad7ae0d),LL(0xd0836f8b,0x4c04dee0),LL(0x4ec33606,0x15e3493e),LL(0x5f5eea30,0x590aefe6),LL(0x2e49ba54,0x09ef5a2e),LL(0x69a0d232,0xf56d447f), LL(0xe2510f5e,0x045f26b6),LL(0x9941083a,0xf90e1888),LL(0xe66f6b9b,0x6e6a3bd6),LL(0x251f82ae,0x637ad390),LL(0x43cdf91a,0xc40374b6),LL(0x2d6c6d88,0x62f5f8ad), + LL(0x11ff6e09,0x3da03590),LL(0xa685c0e8,0x41194047),LL(0x72b9c9ce,0x7c5323ff),LL(0x4f599daf,0xf84ce505),LL(0x5882ef19,0xd0dec10e),LL(0xde1e3a06,0x1ca3449d), LL(0xb09af84a,0x317e4e7f),LL(0x1a46bc75,0x0ebaa2c9),LL(0xc103f200,0x42b00a72),LL(0xc3719155,0x1c30ada5),LL(0x5c1cb58c,0x565bacfa),LL(0x35fa4670,0x374f516c), + LL(0x400f1d87,0x99a710b1),LL(0xee47be8b,0xec3ca386),LL(0x37168fee,0x3a00dcad),LL(0x1765a0df,0x1a69d674),LL(0x917c4909,0x85233afe),LL(0xe9bd6210,0xa3aa97a4), LL(0x310885f3,0x01010526),LL(0xb5007b08,0x21c5de3f),LL(0xee8ddabd,0x5df0c6ef),LL(0x0f6dfdef,0x5d17d45a),LL(0x251c9f79,0xb73d831a),LL(0xcb1df19d,0x397779e6), + LL(0xaf897b90,0xe97f7bcf),LL(0xe05af5ab,0xbaeecdda),LL(0x1b81fd5b,0x3c80856e),LL(0xeca4f983,0xea309bd0),LL(0x22ab76a2,0x534d8950),LL(0x6d620cfe,0xa8d63627), LL(0x6b0cfcfc,0xa13d622c),LL(0x84d9147e,0x584a9d2e),LL(0xd200ea9c,0xf23b9565),LL(0x193d5fe0,0x5f44b61a),LL(0x64b4c78d,0x430a3d3a),LL(0xc91c2b41,0x045dc592), + LL(0xbe13c1e4,0xafd6bf05),LL(0xe2ea8c26,0x256e2b98),LL(0x903983f4,0x06711695),LL(0x217c1577,0xbefbfbcb),LL(0x7324c85c,0xa214b26a),LL(0xdd98b968,0xfa2d4711), LL(0xf5d9cc93,0xed722297),LL(0xd45f8635,0x65cec50f),LL(0xc792e6b3,0x41627e4a),LL(0x228dbb39,0xc254a08c),LL(0xdf6fb26b,0x5b28fd3f),LL(0x4bdc6969,0x1471d353), + LL(0x7c20f79d,0x8600c734),LL(0xca3052ba,0x2bef7d87),LL(0x7b082112,0xc52d0bdf),LL(0x2bf757ca,0x0e649a4b),LL(0xb13eeb84,0x0c1f41bd),LL(0x8ecf9ace,0xd7115e8f), LL(0x1698ba68,0xa62f5e31),LL(0xc862e751,0x6a06d7be),LL(0xf95eee3f,0xd875c1a4),LL(0xa0b2b331,0xb25f8da3),LL(0x1827c037,0x4e52fd11),LL(0x9d72ba3c,0xacd38c2a), + LL(0xd7801edf,0x5e2cb07f),LL(0x3adc065a,0xf9fa2c0b),LL(0xd4de1f25,0xa296c53f),LL(0x838f7169,0xd408060c),LL(0x2e8a6ce7,0x68e19d7b),LL(0x94b58671,0x2cc6e06c), LL(0xc1cb6151,0x93d02a07),LL(0x35003126,0xa10fb4cf),LL(0x1aa3bc4e,0x6aa069f5),LL(0xdd09b142,0x0e44fbf0),LL(0x832e5945,0xe264f343),LL(0x1fc166ac,0x5dca2adc), +}, +/* digit=2 base_pwr=2^10 */ +{ + LL(0xa0eb176a,0x56ad7582),LL(0x6e19aa00,0x085b5a36),LL(0xe2c8b036,0x85f2c6ff),LL(0xfcd7336b,0x55c6d357),LL(0x22a46acd,0xb1ecc56d),LL(0x36277ac7,0x8e0f9767), LL(0x01878921,0xa4ed11e9),LL(0x7f4fb650,0xd3835566),LL(0x266158aa,0x5fdaba45),LL(0x89e0dff0,0x6f0b27fd),LL(0xeb6b02d0,0x32ef7ae2),LL(0xcc1b46e1,0x2f145871), + LL(0xf6e9f82c,0xe65245ce),LL(0xf6da7b5a,0x9e234dff),LL(0xbad2c806,0x5677c121),LL(0x060fcf24,0xc52dec32),LL(0x5d78ccca,0x78d07067),LL(0x1bc8b6fb,0x630002ea), LL(0xeb2e99ae,0xc5cb86be),LL(0x8551d16f,0xf13981e7),LL(0xc92a70d7,0xfbb7cdf2),LL(0xf53cd2a1,0x5a9ff1f1),LL(0x984f1139,0xfdbe6b7a),LL(0xa470a9f1,0x4403d046), + LL(0x8d040c69,0xb5b16cd4),LL(0xf95a2dc4,0xfdaba315),LL(0x61ce4704,0xc9fef349),LL(0xdbb53ed6,0x5fe87a0d),LL(0x73d70f93,0x3f0ccc79),LL(0x46724a1a,0x4601d1bc), LL(0x24f08565,0x5c4a15ae),LL(0xaa577320,0x5eda1e8a),LL(0xbb32d307,0xe31ebb35),LL(0xdc770a0e,0xcdc6f13b),LL(0xc434c2f8,0xbe3ae514),LL(0x3a0ef0d1,0x57c7fdf6), + LL(0x0f547eba,0xeb06571c),LL(0x6246c0dc,0xf292c38d),LL(0x26eed224,0xa1859667),LL(0x6100e387,0x8d9e56e4),LL(0xdc6298d1,0x470506b9),LL(0xf3350ad0,0xb19e084c), LL(0x12abd898,0x83eb62a8),LL(0x2222342c,0x70f152cc),LL(0xe1bd4a82,0xb089e880),LL(0xcaf3b3fc,0xd4d1e70f),LL(0x95ffd65c,0xd0b1ec63),LL(0x9b184ebb,0x79f27f3a), + LL(0xb92a9a13,0xc2467f9a),LL(0x6add349a,0x0c3ee8eb),LL(0x45e99644,0x59250eda),LL(0xc8a2df27,0x22ce0635),LL(0x312e8698,0xec7b643e),LL(0xaebd1587,0x334ccf2e), LL(0x6bca2900,0x0c1c6873),LL(0x09826cb1,0x00beb4c2),LL(0xcde6b725,0x12dbb586),LL(0x66dfed41,0x8d7cee6c),LL(0x014de4c8,0xc38deba2),LL(0x6248442d,0xa3ba6ec7), + LL(0xd42aeb95,0x3c686079),LL(0x85e3ea0f,0xc162e5e9),LL(0x1bbb2455,0x34cf5861),LL(0x8773b064,0x7650de1d),LL(0xd2bab35d,0x3b7562c6),LL(0x33d0741b,0x83191b44), LL(0x3a6bd9cf,0x4b604db0),LL(0x074aed21,0x87cd84db),LL(0xd4f91f9c,0x02a042d2),LL(0xe42c2a67,0x5a5d52e5),LL(0x1d5f216a,0x31291acd),LL(0xcd6203c8,0x9c3971bc), + LL(0xaa1ef488,0x92e4c851),LL(0x846528a9,0x4f91fc22),LL(0x5dc13a84,0xaa2f5d2d),LL(0xf1072d4d,0xba06aa68),LL(0x5e3a2ba9,0xf4f3b17c),LL(0x5e4dde77,0xff36a535), LL(0xae17dddc,0xe8ef143a),LL(0xa1fcd4ec,0xcc82631b),LL(0xc7d3963b,0x97db807e),LL(0x21d85ce2,0xe4aff045),LL(0x74667392,0x2d6480e6),LL(0xa55d0b3f,0xc8ce97f3), + LL(0x4c14ee0e,0xd4277731),LL(0x5e881c3f,0xda8146d1),LL(0x99f1867c,0x6b0746b0),LL(0x602dd4cc,0x1ec73d72),LL(0x38081120,0x27fae515),LL(0x2f8b2f2d,0x6a677bdc), LL(0xd60544e9,0xb924af64),LL(0xdcfc6b16,0x1439e183),LL(0x068565ac,0x4e88e9ae),LL(0xa9a4f146,0x8a3dbd25),LL(0x3f93f734,0xdb4a3e48),LL(0x8f1d33bc,0xb1971c05), + LL(0x56e8d1d1,0x059a5f98),LL(0x5c228e89,0x93a2d2ac),LL(0xfea48feb,0x0bc2c885),LL(0x7b7e188c,0x27fdf3be),LL(0xd399ba6e,0xec579682),LL(0xb3fdb5d0,0x01b12e12), LL(0x742f66b8,0x8e00941b),LL(0x478d8ee4,0xd79bc58f),LL(0x9ad50729,0xefdcd053),LL(0x3bf7bfea,0x8738666f),LL(0xd7afaff1,0x20192810),LL(0xd233e892,0x6c13e29e), + LL(0xff9ae345,0xf1f5df24),LL(0x3dd75336,0x5b8038b9),LL(0x7d2c0058,0x4746c5da),LL(0x51ddd827,0x667b07bd),LL(0x8cfdfd25,0x1b3c67c2),LL(0x06dac0d6,0x058dea06), LL(0x846c847d,0xd19040fd),LL(0x07d00ec6,0x4e5cbe59),LL(0xf1930296,0x2dc442fe),LL(0xfdb583be,0x12f89640),LL(0x5606f66b,0x0694f44f),LL(0xbbef8446,0xa9fcca6c), + LL(0x4b5cb12f,0x0c229fb9),LL(0xe930ff3e,0x0486ba2d),LL(0xb80c37f6,0x00797293),LL(0xb43335e0,0x71be9538),LL(0xda0d9cb7,0x0a604693),LL(0x745cc02e,0xb248f30d), LL(0xd9a3013b,0xfa889343),LL(0x53d6a4d4,0xd8642bc0),LL(0xe216af4b,0x9f89c21a),LL(0x41947320,0x86272900),LL(0xa269c49a,0x06f5f8f7),LL(0x727495ba,0xb3bc6d62), + LL(0xd1066e5a,0xd1de964b),LL(0x749909df,0x26ccad6b),LL(0x0de9eb07,0xbc4b55af),LL(0xa60289bf,0x9f11b995),LL(0x52392c61,0x3e59000c),LL(0x5ccff4fc,0x2128c46a), LL(0xea1e0d5e,0xb28b306b),LL(0xf5cfa47d,0x5f6ef5d5),LL(0xe3f824fa,0x59b0542c),LL(0x2f52b71c,0x70f097b2),LL(0x04c6d263,0x4483b726),LL(0x34d93e5b,0x48720be7), + LL(0x95ad5fe3,0x864bbbb7),LL(0xe8113888,0x24f15dcb),LL(0x6edb61fe,0x968fcf60),LL(0xc7e1aff9,0xbf266d1c),LL(0x3f4a5d91,0xd85a1555),LL(0xf8416ead,0xd5ff238e), LL(0x30d18538,0xcc0e75da),LL(0xb2b91d71,0xcf8a5435),LL(0x027a7e72,0xfae90226),LL(0x627c27f7,0x8e39918c),LL(0x18d454b0,0x5b8235c9),LL(0x44987803,0xef92e643), + LL(0x41ff08a5,0xb39b33ce),LL(0x32450c03,0xaf6dfb28),LL(0x7b45c3f2,0xe21947c5),LL(0xbc35bfdf,0x21b529f6),LL(0x4c5be366,0xc0a26928),LL(0xd366b21e,0x73856f3a), LL(0x3df444f7,0x53e26b66),LL(0x8b9c7ac1,0xb18a295e),LL(0x301f1f11,0x6b9df497),LL(0x7607f372,0x6e77d0e2),LL(0xc311fc01,0xd2e6b296),LL(0x7a396a6c,0x18a224e0), + LL(0x9b97dff2,0x8507c707),LL(0x983d26af,0xacc0b6a5),LL(0x2b62fdb2,0xdcc30fd6),LL(0xa68ab541,0xe9b03755),LL(0x13b6c3a0,0x270bc073),LL(0x649051fc,0x952ec4b9), LL(0xe70ceb83,0x4814c2c2),LL(0xc090e636,0x07632da5),LL(0x11fcdb0b,0x1c340686),LL(0x113f2ce9,0x7b4985d7),LL(0x16da3a7d,0xc3072347),LL(0x0d7d36ab,0xf0575aef), + LL(0x3a7f43c3,0x721bb836),LL(0xc12dca0f,0xab5b3108),LL(0x34853870,0x9cc9a789),LL(0xaf598c4f,0x78b604a7),LL(0x476f27c8,0xd370375e),LL(0x0b15cba5,0x9f0415b8), LL(0xd400dc1f,0x2bcfd9a4),LL(0x4bc62ddd,0x2a6fe03b),LL(0xa211b19f,0xb05a6464),LL(0x9990b504,0xce059d41),LL(0xd94951d3,0x011c5f87),LL(0x00d9c7b0,0x13cec089), +}, +/* digit=3 base_pwr=2^15 */ +{ + LL(0x9b280fd9,0xf365419f),LL(0x46365672,0x13e3b127),LL(0xc41880aa,0x8a91c165),LL(0xf9712fbd,0x3eb27a97),LL(0x76c55678,0xa6587aec),LL(0x02cd79cf,0x7c3a04b7), LL(0xda712eb8,0xfc878f9c),LL(0x0fca3e02,0x076e6117),LL(0xcaf6df5e,0x09a184d8),LL(0xaabcde75,0xd32bf232),LL(0x03de597a,0xf601d0de),LL(0xc5da2858,0x85d2b5fc), + LL(0xae899afa,0xb6029961),LL(0x681b6e1b,0x8eedd66e),LL(0x4df3e5b1,0x82db693b),LL(0xa0c3e357,0xb5131488),LL(0xccb2f577,0xbfb01ff3),LL(0x27a72cc3,0x28ea9470), LL(0xe39e325e,0x26170928),LL(0x84f80188,0x42d4876b),LL(0x4c872d76,0x0bec6a63),LL(0xb14d9c9f,0xa0a7cc90),LL(0x4f6c7778,0x8a32d2c4),LL(0x3b889a4c,0xe7cd346e), + LL(0x437f2efb,0xea95b5c9),LL(0x8e52ce8e,0x67d3e9b5),LL(0x88ff5455,0xfb331024),LL(0xc3101ded,0x883ec9fc),LL(0x0ca5f1f9,0x056218e2),LL(0xbccc65d8,0x4c9b2483), LL(0x123db2ec,0x13199b26),LL(0x9aff90db,0xbc1d8247),LL(0x367516f6,0xc4a9311d),LL(0xcb6e90d6,0x3b40c867),LL(0x4034415c,0xff674ff8),LL(0xa1821e7e,0x2787db45), + LL(0x609683ac,0x860ef794),LL(0x9af1c522,0xf0631ad3),LL(0x2ee7f522,0x322c8366),LL(0x54122af0,0x58ccd95f),LL(0x2bbb2d80,0x7454880c),LL(0x86d8d577,0xea173d82), LL(0xea1cc801,0xd5a3057c),LL(0xbbb2a189,0xfd08d482),LL(0xc3c512f8,0x26aac99e),LL(0x556d891e,0xc3eac036),LL(0xbf9f6112,0x866c3aa7),LL(0xc144f7e9,0x7c4c8fb9), + LL(0x8343f5dd,0xc0c1eb0f),LL(0x0126fa2d,0xa205e66a),LL(0x44fd8be4,0x37530a32),LL(0x96ab64cf,0x3c7af6f6),LL(0x76657202,0x1f043050),LL(0x828f3fb1,0x2c59d31c), LL(0xe7f5926e,0xa61cba51),LL(0x91ebeb81,0xb2de4273),LL(0xbb855476,0x976f2c34),LL(0x269e4f86,0x0c6c02c3),LL(0xe2e01fff,0xc69bed8f),LL(0x480bf7b4,0x19aa421c), + LL(0xb617206b,0xad0d24c7),LL(0x9dd13f59,0xb8be483f),LL(0x7655aa29,0xa55134ff),LL(0x7a5e217e,0xa3d10385),LL(0x3a21b295,0xfbb9eeb5),LL(0xc84a136d,0x1de71555), LL(0x0b7487b3,0x7579398e),LL(0xa14dce87,0xc6ca9575),LL(0x46452257,0x99b32e1e),LL(0x479d8f2c,0x99d54955),LL(0x930b80ef,0xc2a8a6a1),LL(0x656c850b,0x58d9db81), + LL(0xa682508c,0x6c85a0ed),LL(0xedcce6c8,0x8350b515),LL(0x6f95898d,0xa84a6765),LL(0x1e419847,0x55b0ae97),LL(0xdd6a885d,0x11115c6e),LL(0x4fb174a4,0x6f0beaf6), LL(0x815af3af,0xaaae44b2),LL(0x927a2c1c,0xcf0697b9),LL(0xd7d645ee,0x37639d62),LL(0x2effec37,0x157b7eda),LL(0x9b9c66e6,0xb55e5075),LL(0x85f597ec,0x33a66a1f), + LL(0x8f7782b6,0x171898aa),LL(0x499b3a81,0x8b7a706b),LL(0xfdb2c1ba,0xbc0e835f),LL(0x591f5aaf,0x4ee30281),LL(0xcc272c6a,0xfd71de3b),LL(0x6e93f68a,0x532800c4), LL(0x8365c576,0x35ee0804),LL(0xcd4c0221,0x6c2bcc94),LL(0x957b2ff6,0x49f37ff5),LL(0x5ec029c0,0x315d8e7e),LL(0xef324c12,0x33230602),LL(0x966b2578,0xf5847f9b), + LL(0x1453b1e1,0xc29b123e),LL(0x20059b44,0xefb07788),LL(0x9291671e,0x15554ade),LL(0x429dea37,0xeb5a1980),LL(0x6c4b867d,0xf96dacbb),LL(0xabab4d68,0x4f5563d6), LL(0xcbe76297,0xb5b0ecff),LL(0x51d6bd43,0x5a22996a),LL(0xb7e5cfc6,0x0088ec95),LL(0xfe373e05,0x4863a5a1),LL(0xc244d93d,0x42b7925b),LL(0x40117113,0x85bad135), + LL(0xf9daa551,0x86283e21),LL(0x1f696f1b,0x47fd23f8),LL(0xb9784a9a,0x7d029b1b),LL(0xa0c0acb5,0x7c7798be),LL(0x6d7c682b,0x41241c71),LL(0x1d33c2b0,0x11c6c113), LL(0x3565cf32,0x5d469ca2),LL(0xbad4bdbf,0xa949f022),LL(0xa13cf4cd,0x3d054cc2),LL(0x9e3ce279,0x13bd2166),LL(0x8a4beafc,0x01bc70e6),LL(0x8aba087e,0xb39e351d), + LL(0x82357232,0x26072a5d),LL(0x9f0fd2f1,0x3762764e),LL(0x0c16733e,0x9c5813f6),LL(0x718951d4,0xea2e0e03),LL(0x69e63818,0xae195bd4),LL(0xfa2f9a6e,0x241a4afc), LL(0x9165d59a,0x0e97519f),LL(0x58e5af1b,0x416bd373),LL(0x8197b7ec,0xc4e81128),LL(0x9c6ba0d0,0x4145be2c),LL(0x7d40b98a,0xc82cb2a1),LL(0xbccfa8b8,0xc3c28487), + LL(0xa4ee10a1,0x84aa863e),LL(0x87919ccd,0x24d805a6),LL(0xb5c399b2,0x553f3206),LL(0x3cc109bd,0x775b9217),LL(0xfe384088,0x25c01263),LL(0xd5f743cf,0xa3c4418b), LL(0xdf91f1f0,0x3d69705d),LL(0x9ebddad1,0x547d4626),LL(0x2626cebd,0x0198ab1a),LL(0x85b1afe8,0xaf8320f2),LL(0xe17e6efd,0xb9c0968c),LL(0x90215bb6,0xfedc75c2), + LL(0x143ff74d,0x8061d340),LL(0xa23aa7b3,0x59e94fc6),LL(0x914c3b81,0xf7c79a0b),LL(0x702c6ae7,0x5a836211),LL(0x718123c3,0x2570d63c),LL(0xc9f5ce3c,0x7e86d11e), LL(0x17bcce3b,0x80f03f97),LL(0x465a7446,0x073975b1),LL(0xcb357ace,0x29f66de7),LL(0x04894fb0,0xe87bd12c),LL(0x51a0b5ae,0xfc501a26),LL(0x02207a3b,0x20a3170c), + LL(0x5fe63bd4,0x3ee52d8f),LL(0x7a7da77c,0x09f8405c),LL(0x1881a757,0x35ce95c6),LL(0xc13e3707,0x0a8cf9d9),LL(0x48d2d3f6,0xe71258d5),LL(0x0bbe7c0d,0xcf4fd691), LL(0xfb9479f1,0xbd6496e1),LL(0xab8cb3a2,0x711c669a),LL(0x58cfdfb4,0xcbe85013),LL(0x59275b4a,0x655c902b),LL(0x20f722ba,0x7e0ff05b),LL(0x42b17aad,0xcb00031d), + LL(0xd54bf1a4,0x3360ff11),LL(0x5c79494b,0xbab994cb),LL(0x757d7771,0x953ad553),LL(0x68b58ed5,0xf17f14f0),LL(0x7523c422,0x22361531),LL(0x5ebf0d49,0xf0f05f96), LL(0x49182267,0x33866765),LL(0xad71c3eb,0xf87eccc1),LL(0x913d8dca,0xd7708e18),LL(0xb193eef9,0x27fe27e1),LL(0xcc45e65d,0x33376365),LL(0xd700ac20,0x599b4778), + LL(0xed068028,0xda643272),LL(0xa91fb87f,0x86b52135),LL(0x35b43943,0x23865a7c),LL(0x4606bbf2,0x6ac01588),LL(0x1559fb9a,0x9660ab72),LL(0x3ce2f1a5,0x1fcb09e7), LL(0x793d2f0c,0x62af29ab),LL(0x3aee7efc,0xad5aaef5),LL(0x44c11037,0xee9f29b7),LL(0xd36c2571,0xb2a19cf1),LL(0x65b552b7,0xb87d88e2),LL(0xbeb253d4,0xd8b4f172), +}, +/* digit=4 base_pwr=2^20 */ +{ + LL(0x72876ae8,0x31bdb483),LL(0x961ed1bf,0xe3325d98),LL(0x9b6fc64d,0x18c04246),LL(0x15786b8c,0x0dcc15fa),LL(0x8e63da4a,0x81acdb06),LL(0xdada70fb,0xd3a4b643), LL(0xdea424eb,0x46361afe),LL(0x89b92970,0xdc2d2cae),LL(0x615694e6,0xf389b61b),LL(0x872951d2,0x7036def1),LL(0xd93badc7,0x40fd3bda),LL(0x380a68d3,0x45ab6321), + LL(0xce0b5b72,0xc5cf8997),LL(0x9d7154ba,0x350adde1),LL(0x307b254a,0x8139681e),LL(0x75cd94d7,0xcc87fb57),LL(0x78684954,0x90e70274),LL(0x95ceb991,0xc4fdf4c0), LL(0x8762c84c,0x91bbc0ab),LL(0xce09e8ad,0x5e09e226),LL(0x4b93d45f,0x1cb83d70),LL(0xf541da1f,0xe2299024),LL(0x4b7ffd10,0x3eef7ce1),LL(0xb3fc1b9a,0x53ee63bb), + LL(0x81a2703a,0x23c1f744),LL(0xb9859136,0x1a5d075c),LL(0x5afd1bfd,0xa4f82c9d),LL(0xf89d76fe,0xa3d1e9a4),LL(0x75702f80,0x964f7050),LL(0xf56c089d,0x182bf349), LL(0xbe0da6e1,0xe205fa8f),LL(0x0a40f8f3,0x32905eb9),LL(0x356d4395,0x331a1004),LL(0xfdbbdfde,0x58b78901),LL(0x9ba00e71,0xa52a1597),LL(0x55497a30,0xe0092e1f), + LL(0x03682f59,0xe5004e80),LL(0xf642ac0f,0xccdb9cb7),LL(0xbd869f77,0x405f50d1),LL(0xe7ebea2c,0xecffa54d),LL(0xd87620ba,0x3354dc22),LL(0xb1c01ff4,0x01bb2988), LL(0xe16477fd,0xd9370076),LL(0x2e71ba4b,0x45303d2a),LL(0x3291e5c5,0xc0de7627),LL(0xf0a7ca55,0x5cfebd87),LL(0x9e592a30,0xde116280),LL(0xa78ebce4,0xdd26e577), + LL(0x70ee8f39,0x5562a856),LL(0x64e52a9c,0x86b0c117),LL(0x09c75b8c,0xc19f3174),LL(0x24923f80,0x21c7cc31),LL(0x8f5b291e,0xe63fe47f),LL(0x0dc08b05,0x3d6d3c05), LL(0xee0c39a1,0x58ae455e),LL(0x0ad97942,0x78bea431),LL(0x3ee3989c,0x42c7c97f),LL(0xf38759ae,0xc1b03af5),LL(0xbcf46899,0x1a673c75),LL(0x8d508c7d,0x4831b7d3), + LL(0xff1735a8,0x1e9b23b9),LL(0x2b0e4b7b,0xc3bf3d5b),LL(0x59b7721c,0xd4cc00fe),LL(0x9e2f4ceb,0xd5c36f9c),LL(0xc90af70e,0xdeca06ba),LL(0x416ee799,0x42676f12), LL(0x6f748c6f,0x0d7afe1b),LL(0x39c39d55,0x0b7a6de5),LL(0xe6eaed18,0x11e43d6e),LL(0x496087e0,0x5baf8602),LL(0xb1a3a66e,0xf833634f),LL(0x79398677,0x25098c8a), + LL(0xc552e354,0x76512d1b),LL(0x273020fd,0x2b7eb6df),LL(0x025a5f25,0xd1c73aa8),LL(0x5cbd2a40,0x2aba1929),LL(0xc88d61c6,0xb53cadc3),LL(0x098290f3,0x7e66a95e), LL(0xaf4c5073,0x72800ecb),LL(0x9dc63faf,0x81f2725e),LL(0x282ba9d1,0x14bf92a7),LL(0xbd5f1bb2,0x90629672),LL(0xa97c6c96,0x362f68eb),LL(0x7ea9d601,0xb1d3bb8b), + LL(0xd4720770,0xe141e763),LL(0xddb3b450,0xb9739e70),LL(0x96131446,0x46e6cde4),LL(0xcb6c2ef7,0x0458a5d5),LL(0x532f9fd8,0xb7747634),LL(0x16544457,0xf62d3721), LL(0xd3100854,0xbfacb4de),LL(0xb39d3f62,0x70788a31),LL(0xf22d92e4,0x9b543220),LL(0x55723258,0xaa4590f6),LL(0x01ddb8bc,0xc7b6730e),LL(0x69e1e7bd,0xae252cf8), + LL(0xa9c94429,0x73878f7f),LL(0x456ca6d8,0xb35c3bc8),LL(0xf721923a,0xd96f0b3c),LL(0xe6d44fa1,0x28d8f06c),LL(0xd5cd671a,0x94efdcdc),LL(0x3f97d481,0x0299ab93), LL(0x2fd1d324,0xb7ced6ea),LL(0x7e932ec2,0xbd683208),LL(0xcb755a6e,0x24ed31fb),LL(0xe48781d2,0xa636098e),LL(0xf0a4f297,0x8687c63c),LL(0x07478526,0xbb523440), + LL(0xdd4b8d8d,0xc618cf0d),LL(0x40dcfbfb,0x471cda86),LL(0x08882ce6,0xba0dd7ac),LL(0x6cd336e7,0x58e5d2f5),LL(0xaf096540,0xcdda8301),LL(0x3cf31600,0xf6d26846), LL(0x2197efd5,0x6150cd98),LL(0x55fb0877,0x4440fbfa),LL(0x90757f1d,0xca31871c),LL(0xbdd756c8,0xc4a1faac),LL(0xcbb8421e,0xc9d4ac1b),LL(0xb17c43be,0x3c0c2914), + LL(0x34124b56,0x2e5f7419),LL(0x4b3f02ca,0x1f223ae1),LL(0xe8336c7e,0x6345b427),LL(0xf5d0e3d0,0x92123e16),LL(0x45e79f3a,0xdaf0d14d),LL(0x6f3bd0c6,0x6aca6765), LL(0x403813f4,0xf6169fab),LL(0x334a4c59,0x31dc39c0),LL(0xd589866d,0x74c46753),LL(0x984c6a5d,0x5741511d),LL(0x97fed2d3,0xf2631287),LL(0x11614886,0x5687ca1b), + LL(0xaa6fe9ea,0x46fdb65c),LL(0x05494cd9,0xe0d48e5e),LL(0x4afbf837,0x5adef570),LL(0x1c9e2cad,0xc96ba4b9),LL(0x054a158c,0x1e8158f7),LL(0x9e38b88d,0x47be7320), LL(0x6d2993ec,0x9b99971e),LL(0xdf980ecc,0xac9b0bfa),LL(0xd96ca391,0x9da09642),LL(0x9bf4305c,0xd6710536),LL(0xa0dfafae,0x40cc1adf),LL(0xa209699b,0xe27e32f8), + LL(0x33836d4b,0x076d902a),LL(0x24afb557,0xec6c5c43),LL(0xa0516a0f,0xa0fe2d1c),LL(0x00d22ecc,0x6fb8d737),LL(0xdaf1d7b3,0xf1de9077),LL(0xd4c0c1eb,0xe4695f77), LL(0xb4375573,0x5f0fd8a8),LL(0x5e50944f,0x76238359),LL(0x635cd76f,0x65ea2f28),LL(0x25fde7b0,0x08547769),LL(0x51944304,0xb2345a2e),LL(0xa16c980d,0x86efa2f7), + LL(0x36e87d82,0xeaaddeb8),LL(0x1ffd7210,0xc12587a7),LL(0x731f6838,0xf93d2f5c),LL(0xf7097a65,0xb96594e8),LL(0xb016e8d3,0x08d6717a),LL(0x1984d825,0x9c378de8), LL(0xcb2a0c26,0x627d41e7),LL(0xc697ceb1,0x1f447501),LL(0xc760550b,0x8dc40831),LL(0x7fac97b0,0x70ad4870),LL(0x7021c170,0x5ac7f22e),LL(0x929d5931,0xa6f730e4), + LL(0xbf4d1d63,0x4ccbe2d0),LL(0x397366d5,0x32e33401),LL(0x71bda2ce,0xc83afdde),LL(0x478ed9e6,0x8dace2ac),LL(0x763fdd9e,0x3ac6a559),LL(0xb398558f,0x0ffdb04c), LL(0xafb9d6b8,0x6c1b99b2),LL(0x27f815dd,0x572ba39c),LL(0x0dbcf842,0x9de73ee7),LL(0x29267b88,0x2a3ed589),LL(0x15ebbbb3,0xd46a7fd3),LL(0xe29400c7,0xd1d01863), + LL(0xd186cb09,0x7d27d71f),LL(0x3bc213c7,0x67cb7f4e),LL(0x6075b2cf,0x418cafeb),LL(0xd93a06f7,0xc0d691e6),LL(0x9dd001b9,0xc16a9525),LL(0x026f17b9,0xa0583230), LL(0x7845900b,0x4c1041b0),LL(0x47a22aae,0x28740791),LL(0x2c1758e9,0x8d08efd6),LL(0xe6c3229a,0x9cc6f207),LL(0x082d8924,0xec69e902),LL(0xf331dfe7,0x9cfa1dea), +}, +/* digit=5 base_pwr=2^25 */ +{ + LL(0xabe7c60e,0x8ec4335f),LL(0x0a6a9fb5,0x01f198c1),LL(0x01141ab6,0x3ff96de0),LL(0x2eca98a1,0xb21acc2c),LL(0x10fdf648,0x61548490),LL(0xd1403e8b,0x2c01a99c), LL(0x6fa509d7,0xf1a35f30),LL(0xe3f08e9f,0xf7715fe3),LL(0x7fc9a752,0x89c26c07),LL(0x420d48a0,0x8d2535fe),LL(0x52fe2e73,0x80ec5ddd),LL(0x71704f39,0x041b8df0), + LL(0xc65fafce,0x498808ed),LL(0x4e806bc3,0x3676a7cc),LL(0x76c6b964,0x796e25f1),LL(0xac474261,0x1aced64b),LL(0x29a460c1,0xa62470fc),LL(0x5e751e48,0x77501dce), LL(0x6d9e3641,0xcc00053b),LL(0x9a3f5a0b,0x2b5bc4ae),LL(0x3f9ca178,0xddaccc2e),LL(0x0b80d1b0,0xad33f34a),LL(0x64642225,0x6a76df93),LL(0x778e761b,0xc145f36f), + LL(0xc10b43ae,0xdffb03ae),LL(0x9433a54b,0x39b1266e),LL(0xb19fe0db,0x4c262521),LL(0x3d5c7fee,0x0ec1e54f),LL(0x05e68e1e,0x2856510b),LL(0xdc80b8a6,0x49382c1e), LL(0x2471bdd5,0x80a50931),LL(0x81974aa9,0xe8cde185),LL(0x28235c52,0xca6112ee),LL(0x301f9653,0xd28a0eb8),LL(0xe11fcdf8,0x22b11e26),LL(0xe4d735f3,0x97e6fc5d), + LL(0xecc5f6da,0x9c66a32b),LL(0x1719ba2c,0xe4ff4043),LL(0x21e716ef,0x8c6cfab7),LL(0x96ed74e6,0x32c8fccb),LL(0x0b110c83,0x475890dd),LL(0x5cb4eefe,0xdfada95f), LL(0x93240fe1,0x9d7b89a6),LL(0x210b776f,0x6afdb2d0),LL(0xca7a7d52,0xc3f0b55b),LL(0x55d04585,0xa6e56a06),LL(0x4257acc5,0x818e221c),LL(0xfcb8d39e,0x05207b63), + LL(0xac993097,0x00fc2cfe),LL(0x76b4508c,0x4d3532b1),LL(0xa24c9add,0x0887cb17),LL(0x1a9972dd,0x2698a3e0),LL(0x26352346,0xa6f0258b),LL(0x3132792c,0xf6791599), LL(0x92f39495,0x2c3d2ebb),LL(0x3f9e744c,0xf8405894),LL(0x54833968,0xba220301),LL(0xb7936d27,0xa0c5454e),LL(0xb0ca30ec,0xdd9078e1),LL(0x5a80ec29,0xfa5e78ae), + LL(0xe68b9c0c,0xc948333b),LL(0x265cb56b,0x96e30042),LL(0x3c12bd22,0x957516bd),LL(0x0033e495,0x0d328473),LL(0xc9e2117d,0x23ff9704),LL(0xe3d28a72,0x81693f98), LL(0xf8066b56,0x7a0ba6c9),LL(0x332bdbe8,0x0e2e2242),LL(0xe9f4ce83,0x885d3c00),LL(0x8ae96eae,0x3145e5ec),LL(0x91e3d14c,0x8d4b26d4),LL(0xa9ad6fe2,0x17b5782a), + LL(0xcabd9b94,0x39062094),LL(0xc68dc31e,0x20b3910b),LL(0x0b708450,0x7d78a043),LL(0x522bd0d5,0xe113da29),LL(0xf7f27be8,0xc46fa10a),LL(0x295393a0,0x8258b2ce), LL(0x28d958d8,0xf69dc622),LL(0x991261e9,0x97b796c0),LL(0x36482f74,0xaedea55e),LL(0xeec962cd,0x6e4f2e3c),LL(0x2a06b626,0x782f495a),LL(0xfe23dd4b,0x41e32a4d), + LL(0xd8ada6cc,0x0a74da82),LL(0xbea55457,0xc6b98a3c),LL(0x57c2f5ac,0x896c26bb),LL(0x845d45e4,0x981e2f72),LL(0x7e9a7d36,0xca152b87),LL(0x7b582e8f,0x49666d45), LL(0x49fc20b9,0xea3b9bda),LL(0x7c71f153,0x5bcbc84a),LL(0x5748a654,0xd346fc5d),LL(0x622665ee,0x7ac2f217),LL(0xb6f16e27,0xbb5efe7f),LL(0x644c9dc8,0xb1810a70), + LL(0x2e4b40f5,0xe0c7946c),LL(0x7dd0f6de,0x7ef21fe5),LL(0xf81f21f3,0xc2a8cdd8),LL(0xc7ebe7a3,0x6ad73e42),LL(0x5d42a7be,0x3e8099c3),LL(0x6df16d22,0x151c6de8), LL(0x5293c104,0x214a649b),LL(0x56b4d1d3,0x769763d1),LL(0xe3bebab4,0x78b33355),LL(0xc78a804e,0xe10a70ce),LL(0x211f735e,0x985a16fe),LL(0x56605fc0,0xfd50c868), + LL(0x8f646cdb,0x16bcf31c),LL(0x059f65cc,0xe9b4b8a9),LL(0xf8971dbd,0x34a47964),LL(0xcfe021f8,0xd76f597f),LL(0x573891a6,0x23bab19c),LL(0x2645a244,0xdf670285), LL(0x4347674f,0xcc338b2c),LL(0x4c07ab3e,0x1ddd83da),LL(0x31bf757d,0xee6bb102),LL(0x032ec673,0x3f2828c5),LL(0x0cd7c8f8,0xcf0daf5f),LL(0x56eba0e0,0x1b5d1126), + LL(0xdcf6b460,0xd9b864d9),LL(0x5141107c,0xf453164e),LL(0xb019575e,0xac36ccb9),LL(0xa0040dea,0x996c97bb),LL(0x86b7899e,0xf684e539),LL(0x6b00d106,0xb11bb533), LL(0xbe831360,0x86af64aa),LL(0xb21650cc,0xbda68250),LL(0xffd7b0c6,0xc080ad14),LL(0x1a3844b9,0xa7cd582f),LL(0x4531ed01,0x3656ad08),LL(0x0af8481d,0xe12b761e), + LL(0x8532b8e4,0x94a35f64),LL(0x2227ce87,0xc2cf81f8),LL(0x7f8ce7c5,0x2c0a163f),LL(0xba5e1907,0xe9de5d0f),LL(0xc1c14999,0x0a58d572),LL(0xd934e441,0x406a3ecc), LL(0xc315d861,0xf9ef9a75),LL(0x864a28bd,0xa18abeae),LL(0x60831100,0x9e65f3c3),LL(0x2d4749cd,0xf757107b),LL(0xe8d782bb,0x8fec38eb),LL(0xbe94b2ae,0x74b4d444), + LL(0x59480d9b,0x796fc73b),LL(0xe0555912,0x9f33407a),LL(0xbcd9a4bb,0xbc428d52),LL(0x82ac0b57,0xffe3b15b),LL(0xab58a714,0x0f4cbd0a),LL(0x353b82bf,0xe3b57ece), LL(0xf77aa72a,0x67e16b95),LL(0x112a81cc,0x7b5d3eda),LL(0x8d749470,0x6795b775),LL(0xfe097d37,0x334bb4fc),LL(0x64deebc3,0x0489c0ce),LL(0x85092a86,0x0cf28e29), + LL(0x29843096,0x0cc8d80b),LL(0x6aaf8c7c,0x1f5107d7),LL(0xd1647601,0x6fb26e1a),LL(0x2e2ca8c0,0x66da08d5),LL(0x34d9e92a,0xac0a6fbb),LL(0x52203763,0x596cc78b), LL(0x8e88a471,0x145521ab),LL(0x64bde8f6,0x9bdbd482),LL(0x01b4d2ea,0x5a4d25bd),LL(0x6e7152ae,0xef1fc362),LL(0xfba5462d,0xd188389a),LL(0xf01d497c,0x951d4667), + LL(0xbcc5466f,0x294045fb),LL(0x039461a1,0x145c2078),LL(0x2a620ace,0x21c890c8),LL(0x896d0458,0x1ecc5928),LL(0xd3f9fb46,0x14130b9c),LL(0x461506dc,0xf001b3c2), LL(0x97a1b5c2,0xd90a95e2),LL(0xdf6487be,0x9e37948e),LL(0x3b165a95,0x00ce787c),LL(0xe49c468d,0x10d4f2a6),LL(0xacd25333,0xf0f26eb8),LL(0x63f3570b,0x25b513b0), + LL(0x9bc5917b,0x98d08981),LL(0x187fac5d,0x9f90885d),LL(0x7cfc13db,0x651b1828),LL(0x8655a658,0x2d606e4c),LL(0x63c91b71,0xba64d3c5),LL(0xb82a5090,0x36c7d7d8), LL(0xcab1d598,0x2d1dff02),LL(0xbe78f90d,0xa95788d7),LL(0x0ea1fe01,0x1ac2ee6b),LL(0xd5c1273c,0xc100b60c),LL(0xeae603e7,0x4496084c),LL(0x77c2fdfb,0x7fcaaf5f), +}, +/* digit=6 base_pwr=2^30 */ +{ + LL(0x6abdd842,0xe8e3225a),LL(0x3b367b02,0x8c85f18f),LL(0x9f42edb9,0xf147a421),LL(0x0d411d4d,0x6d4bc00d),LL(0x70014bb4,0xa1a13a27),LL(0xfa10166f,0xb896d97b), LL(0x0c302c6d,0xb2a1dfa7),LL(0x808a63a4,0x0a24bd5d),LL(0xf88c7359,0x8409a3a2),LL(0x347726a0,0x071f3838),LL(0x27507bb9,0xd18a551c),LL(0xb359b167,0xe0c4cc34), + LL(0x80e9d9f3,0xa44f6ef8),LL(0x1d14d618,0xaa7621e9),LL(0x0eaf6671,0xcb0e4ed8),LL(0x181514a2,0x2bf485f8),LL(0x0a2927ea,0x74670e18),LL(0x12c14645,0xe1b54616), LL(0x2a67ed61,0x4068c074),LL(0x739063ca,0xd10c7a57),LL(0x698b2816,0x391b651d),LL(0x6da14fa8,0xf310d169),LL(0xd8a578b1,0xa089be6b),LL(0x44389ad7,0xa314b3a8), + LL(0x68ed0760,0x664ff053),LL(0x38fae9fe,0xc3cdc991),LL(0xf1f30a86,0x3fe057aa),LL(0x2d08c72a,0xbae99022),LL(0x6f09e13f,0x4f5faf3f),LL(0x13d26b29,0x44461a44), LL(0xf95418ed,0xc2504c1b),LL(0xdb3ff26c,0x12766ea7),LL(0x07a22399,0x2f956e95),LL(0x5a00cdd3,0x2716e70f),LL(0x0e9fba99,0x80c02014),LL(0x0519875d,0xbe587ac3), + LL(0x70128295,0xba86aec1),LL(0xc12f35ce,0x83a09b65),LL(0x89df2f80,0x8978ff07),LL(0x97a773d5,0x85750cfd),LL(0xfc3f35f6,0x806bb730),LL(0xfed868c9,0x04503422), LL(0x86ffdbae,0xdc0fcde0),LL(0x1860f43b,0x8f4297e1),LL(0x8d3ad6cd,0xfefb7d02),LL(0x97293550,0x5c652b59),LL(0xed5cfbba,0x32e12942),LL(0x98800d22,0x06192aaf), + LL(0x3c9eb0ca,0xccf0fb42),LL(0x4aa03b40,0x8703c669),LL(0x4001af07,0x44c735a7),LL(0x2e874ed1,0x9616dd93),LL(0x474ba621,0x5c2e8520),LL(0xfa93d8b4,0xddf13cd3), LL(0x75df1b67,0xd68c9b45),LL(0x8f80d389,0x4cd24228),LL(0xc09f47fc,0x0f1a16bc),LL(0x9cd4842a,0xc414dc6a),LL(0x1f353c6d,0xbb0fa94f),LL(0x1950d073,0x40512455), + LL(0x4d2edd5f,0x935b9e24),LL(0xefb287b8,0xfeb46fb5),LL(0xf5018b92,0xa51700a3),LL(0x23864e2a,0xc328beba),LL(0x995f70c1,0x113b5c9a),LL(0xda1b5d51,0xc0b11c22), LL(0xf4a360cb,0x9b99b907),LL(0xadf0b094,0xf4ee9995),LL(0xf94b3f0e,0xf67c7cf2),LL(0xdcaf10cc,0x664a51a1),LL(0xe937a669,0xa3709ccc),LL(0x4862f098,0xea97bace), + LL(0xc942a3f5,0x51758334),LL(0x32182ba6,0x7cc01e88),LL(0x74de4fe6,0x772af257),LL(0xe9667bf8,0xb1b3c448),LL(0x8079caf6,0x71cb2738),LL(0x1d823a40,0x48890c64), LL(0x0e9edbda,0x47a5887b),LL(0xbe089e5a,0x916dfb0c),LL(0x1eb42ddf,0x3185090e),LL(0xb7f3af26,0x3c7eaa13),LL(0x9e9963b2,0x940ed8c7),LL(0x3426ac10,0xd85e77db), + LL(0x2efffd95,0x162cdf34),LL(0xd59086e8,0x92111fda),LL(0x454eb977,0x4478d114),LL(0xdea38a67,0x8ce403d8),LL(0x7435728a,0xd459633b),LL(0xa63b0504,0x3a7be4e3), LL(0x335dba3e,0x0c74066b),LL(0xc6ea6ee5,0x4e8fb1d7),LL(0xa99690ed,0x3398b588),LL(0x3ad77562,0x4949517c),LL(0xcbbb60ee,0xf9824f09),LL(0x85660bec,0x9fdcafdf), + LL(0x8875d9e8,0xf26bd861),LL(0xbea9c273,0x22e2380d),LL(0x91995508,0x5f151837),LL(0x648aa1c6,0xb97f40a6),LL(0x3977d848,0x7478f5f8),LL(0x35b57de6,0x21e876ae), LL(0xa93fc7f6,0xf620b180),LL(0x1b148996,0xf49bd07e),LL(0x1c4f60e1,0xfb085726),LL(0x7ad6b84d,0x6a6653af),LL(0x2e05b686,0x913a2d02),LL(0x407dda9a,0x94746629), + LL(0xda684157,0xb8465d16),LL(0xb238faae,0xdadde1ab),LL(0xc6b9bea8,0xe2cd45e7),LL(0x5cf413d5,0x7251d4a1),LL(0xaae1765b,0x615cea8b),LL(0x13f36885,0x75aa8318), LL(0xb8767cc1,0x7d5b0bf7),LL(0x8022968c,0xec38a8ff),LL(0x2a07faeb,0x034805b6),LL(0x33b7321e,0x916f9eb0),LL(0xc0c577ce,0x34963633),LL(0xabb8d3ce,0x8ee07efd), + LL(0xa8a29345,0xa0bd6c0d),LL(0x5d7f5ef9,0xc676b6c5),LL(0x20ad7259,0x303b6d7c),LL(0xd8fe09a7,0x06542a19),LL(0xa959014a,0x5a06653c),LL(0x5bcfe0cb,0xf45fd79a), LL(0x4e583468,0x29058d98),LL(0x0cd7afc0,0xf1bd25e6),LL(0xf7dbe54c,0x2a88246e),LL(0x35e0ef3d,0x680eaff8),LL(0x726e59b9,0x5942c97f),LL(0x8d5c0825,0x43e97139), + LL(0xa406d4d7,0x2daddb11),LL(0xa2a33d81,0xb02b5da5),LL(0x21a6aa89,0xb73ce827),LL(0x467506de,0x10919587),LL(0x428d8daa,0x0927724c),LL(0x7c17adfd,0x0ede991f), LL(0xbf7ddb3d,0x8518dab1),LL(0x2a54e1b8,0x04b091c4),LL(0x89e7a398,0x5943c37f),LL(0xe273f6f3,0x8e63f5e8),LL(0x83143d22,0xc6d0352b),LL(0xebd1628e,0x30e43182), + LL(0x9991167e,0x606658a9),LL(0x72c4b43d,0xb8773e15),LL(0xe025abce,0x6cb364cd),LL(0x0c5a653e,0xafa58e9b),LL(0x134a68bf,0xa7e35a54),LL(0xba4d9db6,0xcb831d42), LL(0xde83ef97,0xae37348e),LL(0x62ddd553,0x4ac64a6a),LL(0x715bb6b4,0x5feb5e0d),LL(0x043424b2,0xf876efae),LL(0xad91a9ef,0x7b56a291),LL(0x356f3ade,0x817c7053), + LL(0x8dff7dff,0x3d6e8d6d),LL(0xd5be4ad1,0x6b6c194a),LL(0xb6fcd08b,0x57b93f2d),LL(0xf3761f23,0x99f09948),LL(0xac8b018f,0x4062f3d6),LL(0xa27af72c,0x4b58ac05), LL(0x04d0cdfd,0x4abcc815),LL(0xbda4b02f,0xa50043e0),LL(0x27a9c083,0xe11297e5),LL(0x9779c5b3,0x2b2d8d52),LL(0xdfdecfed,0x3de3d330),LL(0xae7fc522,0xfe2487ca), + LL(0x8f7a83e5,0x1c2fc508),LL(0xb9970c92,0xa7c56233),LL(0x8bafa66f,0x949c7173),LL(0x5bbb0490,0x1e299b2d),LL(0x18fcb9e8,0xb9a79e7c),LL(0x9cb5cc50,0xe6372ce6), LL(0xf465c6aa,0x114fc628),LL(0x8cb797f6,0xc5539520),LL(0xa73ad211,0x7df94ed7),LL(0x8e0cd008,0x41eb8e1f),LL(0x004cbb0d,0xb028725a),LL(0x372c1656,0x1340186d), + LL(0x978029bb,0x4074ee27),LL(0xbae0d0c0,0xa9394bda),LL(0x72cecb4b,0xaa01d539),LL(0x9a7dd9c4,0x4b0cf127),LL(0x5bc787cf,0x3e3e3f16),LL(0x942de53f,0xdf48f7e1), LL(0x567b9d0e,0x0cc69719),LL(0x8d0d2750,0x631e3315),LL(0x92314a09,0x9fedc1e2),LL(0x14a1adcb,0x7547d226),LL(0x8662b86a,0x405561a4),LL(0xf5480b7d,0x149fa2b1), +}, +/* digit=7 base_pwr=2^35 */ +{ + LL(0xbda4aaa7,0x923d0b44),LL(0xfee29f7b,0xced14ce4),LL(0x9cf5b87d,0x1656be00),LL(0x1d61103d,0x13a37d0d),LL(0xfb652393,0x1d705880),LL(0xed712ed8,0x870a31bb), LL(0xad7c21e3,0x15ad02e6),LL(0xc36c2831,0xf004e447),LL(0xba2b3ffd,0x56aa376c),LL(0x9745443c,0xc3be2b2f),LL(0xeb903660,0x47c8a870),LL(0x6c6c192d,0x976c303e), + LL(0xf4fb80d4,0x148bd39c),LL(0xfff04e65,0x469b208c),LL(0xce548415,0xf397fbe2),LL(0x87fdde9f,0x441e5c2c),LL(0xfee9c179,0x6366b49f),LL(0x2938dc71,0x38d02bd3), LL(0xc49c5444,0x26d450fa),LL(0x2b23d3d7,0x4569f95d),LL(0x298fd876,0x5f68bf4d),LL(0x544768b6,0xe86df047),LL(0xf8491267,0x40b69a32),LL(0xf917c71a,0xcbf3adf9), + LL(0x8125489c,0x32498d4d),LL(0xa5a46ae0,0x965e8d07),LL(0xe96a7e29,0x6cea5e47),LL(0x668039ff,0xf78293a4),LL(0xf63edd32,0x62548a96),LL(0xa83e8256,0xe8e6af95), LL(0x0db6263b,0x76e60c3b),LL(0x21b3d668,0xa1ee4b06),LL(0x9e49b0b5,0xa17dbf8b),LL(0x7eb366fd,0x4b29ba12),LL(0xd29b565f,0x5e0ed781),LL(0x199b36f9,0x8cb50d53), + LL(0x29aa3150,0xa66c7035),LL(0x479e61fc,0xd038a5ab),LL(0xb5ab5410,0xdee33e96),LL(0x7c57d123,0xd068929c),LL(0xf1d6ad37,0x0839a208),LL(0x123f8178,0x8f523dab), LL(0xa67d3840,0xb3e5e524),LL(0x52eb59df,0x88bda75e),LL(0x389f2dd3,0x513a0ab7),LL(0x890bba6f,0x3197a145),LL(0x6f66bf09,0x61add75b),LL(0x4eef1722,0x5c9dfc15), + LL(0x07769b1b,0x66dc2850),LL(0x4d71fac4,0xe07fb741),LL(0xc2abbe60,0x5ae688a6),LL(0xdcbfd296,0x08ae92fa),LL(0xb43044d1,0xbc291256),LL(0x9fcdf213,0x0e1d71ed), LL(0x02485685,0xf0c5b281),LL(0xe3f68f42,0x5d3f9302),LL(0xffe4f036,0xbbbfac50),LL(0x74fdba44,0xb5b5f261),LL(0x0d746760,0x4ebe1d07),LL(0xc37f04b7,0xbb0f7812), + LL(0x6df1199d,0x810b6ab3),LL(0xb4f293b7,0xc229308b),LL(0x89897750,0x3cf838dd),LL(0x7a336c9a,0x3e391e4e),LL(0x176f89c0,0x70148337),LL(0xbc4f1e22,0x54b15bac), LL(0x2c0f2885,0x32b104f9),LL(0x67034f2a,0x2c39cefa),LL(0xbf178ac1,0xb8310437),LL(0xc99370d5,0x722299f5),LL(0x332b93a8,0x0a493cf0),LL(0xa420f719,0x00e0ab41), + LL(0x4cab24da,0xf2592543),LL(0xe7c3b9c5,0x52be9bbc),LL(0x4660d1a0,0xaab7a8b6),LL(0x9a9600f4,0x09738b81),LL(0x37de9e3c,0x58f0c866),LL(0x5db31f4f,0x0aea5cc1), LL(0x499868be,0xe480406f),LL(0xf6913a44,0x0d8fc7f0),LL(0x35f2e14e,0x72823644),LL(0x45e37a93,0xb147b310),LL(0xf15c1af7,0xb1e7aa5b),LL(0xb03e7713,0xa8685068), + LL(0x21c34c2b,0x21feb7fc),LL(0xddb0140e,0xab6a553a),LL(0x24b04e6f,0x03a65576),LL(0x342cb0ad,0x2531f186),LL(0xa24f6426,0x088c4d54),LL(0x06a873ea,0x9a0ee15c), LL(0xd33bc748,0xdbe0253f),LL(0x5db8ac9e,0xdad3339f),LL(0x73e65901,0xeaaf3681),LL(0xccbfa504,0x71f1fab2),LL(0x4b0e163e,0xb7b84522),LL(0x3c779f3b,0xe0fca837), + LL(0x46baf373,0x710988eb),LL(0xb57d5018,0x8cceb935),LL(0xa45fdf17,0x1864603f),LL(0xef48e6d0,0x3dcaae73),LL(0x590322c5,0xadd9420b),LL(0x9b135f67,0x947783e3), LL(0x8bf5049f,0xfde76368),LL(0x2caa4023,0xf00e4c18),LL(0xd355b3d6,0x4d3b0f23),LL(0x20d5799d,0x181fabcc),LL(0xab2ad0af,0x29499b40),LL(0xf9a938aa,0xf6e66328), + LL(0xbcbe922d,0xcd7b3c42),LL(0x95dd1a5c,0x2fe02b3b),LL(0x24ef5c38,0xeb66bcbd),LL(0xe579c309,0x7edcc21c),LL(0x16f6c900,0x7b19d491),LL(0xb6317c2c,0x36019ecd), LL(0x91d9001c,0x554ba553),LL(0x14f31e44,0xa5e30b98),LL(0xffda4032,0x3d1fe33b),LL(0x2306675c,0x5dfec478),LL(0x000c91e7,0xbe59305e),LL(0x25a6b879,0x3c4e52a3), + LL(0xc5ea88ac,0x02fcc14e),LL(0x56d093b6,0xca29bb6d),LL(0x0e6fe94d,0x876aeda9),LL(0xd7225a9d,0xfa11a142),LL(0x3d03fed8,0xfea3ca05),LL(0xc54d5962,0x435854c6), LL(0x54a6dfd5,0xd7707374),LL(0xa3e55d02,0xb8960017),LL(0x04d65c3e,0xd4015a0c),LL(0xe98a1204,0x397f93d1),LL(0x5f3ed850,0xb0efa2e5),LL(0x8a3ec67b,0x18f24469), + LL(0xd62cd9f9,0xa35802f5),LL(0x4148436e,0x0ca9c15d),LL(0x472b9d21,0x261a991d),LL(0xa2f8e875,0xd81a1ed6),LL(0x699b6d63,0x942f213a),LL(0x0ae57758,0x041a12fc), LL(0xbd70aabb,0x61191c82),LL(0xee4c23b3,0x3776eb8b),LL(0x52511222,0xabe23e86),LL(0x30dabb91,0x66dd967d),LL(0x7ed27424,0x77650c59),LL(0xab25a050,0x08ea2ebd), + LL(0xb6cb5a02,0xa410ba3a),LL(0xd07c5c6b,0x6eb40d15),LL(0x07dcc811,0x0de81e91),LL(0x2631b7af,0x996f46eb),LL(0x5b7a22f3,0x5a350ba7),LL(0x634159af,0xf42b24e7), LL(0xc30952fd,0x07bae0ab),LL(0xd644e0b0,0x3488cda2),LL(0xe2111e12,0x23ae40d0),LL(0xc80cdb56,0x650af54e),LL(0x7d4aa2a8,0x0f33a30b),LL(0x442a00e8,0x4e8d3e98), + LL(0x59a8bc95,0xa624ab37),LL(0x1c971228,0x4b7e3fa6),LL(0x73aa694b,0xe8229c42),LL(0x779288ab,0x0cc31029),LL(0x57575e0e,0xf8eff30f),LL(0x7d52803e,0xee5e0194), LL(0x8a78f632,0x32d87e55),LL(0xe454904e,0x48a06031),LL(0x16c6e626,0xaa2cb8dd),LL(0x2c140452,0xadd098ac),LL(0x2d3031b1,0xd25f285d),LL(0x75b59543,0xfb5fbbe1), + LL(0xd7a21503,0x2297041f),LL(0x657f03f0,0xfe7738c2),LL(0x168fa34a,0x994a8deb),LL(0xa53c4fdb,0x0c772e02),LL(0x50124cd3,0x67f835d1),LL(0x6993cbbe,0x0e0d2635), LL(0x5257f11d,0x9857ed84),LL(0xac556942,0xdc23a728),LL(0xdeb32a7f,0xf0e1bb29),LL(0xee0d70f4,0xb8c3c43f),LL(0xc60ad214,0xc294b0ef),LL(0x679067ca,0xa4d438dc), + LL(0x05c755e4,0x520b0bb9),LL(0xf89f0048,0xa2c2c59b),LL(0x73c23975,0x85c1c73a),LL(0x783aabba,0x6e4dec49),LL(0xb0463155,0x69f0c69b),LL(0x9c97b17b,0x61a42b94), LL(0x45d331a3,0x55af24a9),LL(0xf5fe81fd,0x4b0e63f8),LL(0x708671c4,0x4034283d),LL(0x5fd9001a,0x200ddab3),LL(0x342eaf3b,0xe45f28e4),LL(0x1ba936c4,0x3e8375b4), +}, +/* digit=8 base_pwr=2^40 */ +{ + LL(0xec074aea,0xb083ba6a),LL(0x7f0b505b,0x46fac5ef),LL(0xfc82dc03,0x95367a21),LL(0x9d3679d8,0x227be26a),LL(0x7e9724c0,0xc70f6d6c),LL(0xf9ebec0f,0xcd68c757), LL(0x8ff321b2,0x29dde03e),LL(0x031939dc,0xf84ad7bb),LL(0x0f602f4b,0xdaf590c9),LL(0x49722bc4,0x17c52888),LL(0x089b22b6,0xa8df99f0),LL(0xe59b9b90,0xc21bc5d4), + LL(0x51c2bb65,0x6f577529),LL(0x4b874bdb,0x4a0c1c28),LL(0x78b96c6d,0x19a18427),LL(0x2f593505,0xa674f992),LL(0x6b7209d6,0x5abeeec4),LL(0x47cf5fff,0x42d15d01), LL(0xb49e3b4e,0xe24509b7),LL(0x639ee6e8,0x81be939c),LL(0x5761e8e3,0x7f7daf59),LL(0xd420a288,0xed5cfcb8),LL(0x7a0ff696,0x365b29eb),LL(0x99a1ac8f,0x7d146805), + LL(0x8a31973f,0x4936c6a0),LL(0x83b8c205,0x54d442fa),LL(0x5714f2c6,0x03aee8b4),LL(0x3f5ac25a,0x139bd692),LL(0xb5b33794,0x6a2e42ba),LL(0x3ff7bba9,0x50fa1164), LL(0xf7e2c099,0xb61d8643),LL(0xbd5c6637,0x2366c993),LL(0x72eb77fa,0x62110e14),LL(0x3b99c635,0x3d5b96f1),LL(0xf674c9f2,0x956ecf64),LL(0xef2ba250,0xc56f7e51), + LL(0xadcdaa68,0x9ee1ec3a),LL(0xdcbb6548,0xd98c498f),LL(0x88102ac0,0x32b97375),LL(0xc08527f4,0xdd296cf9),LL(0xfae3dfbe,0xb74f8145),LL(0x6cd7cc4f,0x84131eb9), LL(0x927ff15b,0xa0f2fe7a),LL(0xeee1a4b4,0x6b0ade4d),LL(0x0eeb90a7,0x6e7df2d4),LL(0xbe4de684,0xe2f46e20),LL(0x3fdd06bc,0xcd28feba),LL(0xe6d6d9f6,0x8e4205ae), + LL(0xff602c1b,0x246ffcb6),LL(0x6e1258e0,0x1e1a1d74),LL(0x250e6676,0xb4b43ae2),LL(0x924ce5fa,0x95c1b5f0),LL(0xebd8c776,0x2555795b),LL(0xacd9d9d0,0x4c1e03dc), LL(0x9ce90c61,0xe1d74aa6),LL(0xa9c4b9f9,0xa88c0769),LL(0x95af56de,0xdf74df27),LL(0xb331b6f4,0x24b10c5f),LL(0x6559e137,0xb0a6df9a),LL(0xc06637f2,0x6acc1b8f), + LL(0xf4a59550,0x9ad73168),LL(0x8409d7af,0x2a488d69),LL(0x30b3a5f4,0x9e946c2d),LL(0xc89723d5,0x7bc4ced7),LL(0xbd31f607,0x79f514a1),LL(0x3a274341,0x7d493f59), LL(0xd45d55d1,0x7eb01027),LL(0x14735d1e,0x63f76909),LL(0x35be21cb,0x718d760f),LL(0x7c793331,0xba58160b),LL(0x8d30d29e,0xfbc0ce1f),LL(0xc6f4b03a,0x4645c0c2), + LL(0x34b4e381,0xbd8c0868),LL(0x30dff271,0x278cacc7),LL(0x02459389,0x87ed12de),LL(0xdef840b6,0x3f7d98ff),LL(0x5f0b56e1,0x71eee0cb),LL(0xd8d9be87,0x462b5c9b), LL(0x98094c0f,0xe6b50b5a),LL(0x508c67ce,0x26f3b274),LL(0x7cb1f992,0x418b1bd1),LL(0x4ff11827,0x607818ed),LL(0x9b042c63,0xe630d93a),LL(0x8c779ae3,0x38b9eff3), + LL(0xf78d33ef,0x35d47426),LL(0x8440c42c,0x4af25db2),LL(0x2e91bf5e,0xbd6a15e2),LL(0xc08b6b1a,0xe366a84c),LL(0x55b97de8,0x759c122f),LL(0x08a03f29,0xecec558f), LL(0xea9d2060,0xdcc9fca2),LL(0x9f361fe1,0xb3e49b8e),LL(0x9b59cd04,0xdeae3902),LL(0x6f5e5bd4,0xf532ede0),LL(0x36099f4d,0x84fbeeb9),LL(0x088d2052,0x73576b1f), + LL(0x729c5431,0xe8767d36),LL(0xbb94642c,0xa8bd07c0),LL(0x58f2e5b2,0x0c11fc8e),LL(0x547533fe,0xd8912d48),LL(0x230d91fb,0xaae14f5e),LL(0x676dfba0,0xc122051a), LL(0x5ea93078,0x9ed4501f),LL(0xbd4bee0a,0x2758515c),LL(0x94d21f52,0x97733c6c),LL(0x4ad306a2,0x139bcd6d),LL(0x298123cc,0x0aaecbdc),LL(0x1cb7c7c9,0x102b8a31), + LL(0x139a9f83,0x2b85dd03),LL(0xf55cbff9,0x02740ec2),LL(0xdc3bd5f6,0xdca3616a),LL(0xa5da9b2c,0x52843de5),LL(0x1e22c1cb,0x7ee7890a),LL(0x4aee5c76,0xd5cf1511), LL(0xc7234c24,0x86d70af0),LL(0x6b6a709f,0x1735378b),LL(0x423f32e5,0x9989ed21),LL(0xe739b1fd,0x4675a4ff),LL(0x304ce529,0x873edb62),LL(0x7f1db13e,0x60b6624a), + LL(0xfaf46675,0x22a28e59),LL(0x10a31e7d,0x10757308),LL(0x2b4c2f4f,0xc7eeac84),LL(0xb5ef5184,0xba370148),LL(0x8732e055,0x4a5a2866),LL(0xb887c36f,0x14b8dcdc), LL(0x433f093d,0xdba8c85c),LL(0x1c9a201c,0x73df549d),LL(0x70f927d8,0x69aa0d7b),LL(0xd7d2493a,0xfa3a8685),LL(0x0a7f4013,0x6f48a255),LL(0xdd393067,0xd20c8bf9), + LL(0x6b512bc6,0xee43828c),LL(0x50b91e60,0xf73dc9f5),LL(0xf5dbde6b,0x68f23f30),LL(0xddd15e00,0xaf2fe9e3),LL(0x86578d49,0xfbf34dae),LL(0x6c130010,0x68979655), LL(0x09942897,0x137a5fc3),LL(0x9959f06d,0xff1f0bfe),LL(0xbd7ee14b,0x2dd0a04a),LL(0xe54e2161,0x59c46072),LL(0xea7518ad,0xf470bdae),LL(0x40c471cd,0xce556e43), + LL(0x81625e78,0x4ec874ea),LL(0x3fbe9267,0x8b8d8b5a),LL(0x9421ec2f,0xa3d9d164),LL(0x880ea295,0x490e92d9),LL(0xd8f3b6da,0x745d1edc),LL(0x8f18ba03,0x0116628b), LL(0x834eadce,0x0ff6bce0),LL(0x000827f7,0x464697f2),LL(0x498d724e,0x08dccf84),LL(0x1e88304c,0x7896d365),LL(0x135e3622,0xe63ebcce),LL(0xdc007521,0xfb942e8e), + LL(0x829ee0c7,0x6b97dae4),LL(0xf274bc7d,0xcaaad7e3),LL(0x512f7d86,0x87bee424),LL(0x3f7b0dde,0xb5a03e5b),LL(0xf9fca5a8,0xc29db9c1),LL(0xede64af8,0x538a6f8b), LL(0x8b3c715f,0x0e518ba8),LL(0x3cb5b861,0xc1cb4c31),LL(0xc76dbfa0,0x5cd61604),LL(0xffdac22e,0xc557e50d),LL(0xf67b53e8,0x7892fc51),LL(0xea7c141c,0xa42f85c1), + LL(0xa3688621,0xbb155a66),LL(0xf91b52a3,0xed2fd7cd),LL(0xea20cb88,0x52798f5d),LL(0x373f7dd8,0x069ce105),LL(0x8ca78f6b,0xf9392ec7),LL(0x6b335169,0xb3013e25), LL(0x6b11715c,0x1d92f800),LL(0xff9dc464,0xadd4050e),LL(0x8465b84a,0x2ac22659),LL(0x465b2bd6,0x2729d646),LL(0xe4eff9dd,0x6202344a),LL(0xcd9b90b9,0x51f3198f), + LL(0x22b25f2e,0x2ba8c790),LL(0x1af0f4a8,0xf4670a51),LL(0x2fc2451e,0x6842f36a),LL(0xbb91e1e3,0xfc5c9558),LL(0xc3ead762,0x035d1dfc),LL(0x031e5556,0x3d0721cb), LL(0x3af18a2e,0x3af0cc81),LL(0xbd11a363,0x7888cee2),LL(0x6ade1d12,0x80c3de0a),LL(0x93b2dcb5,0xe8c3a5bd),LL(0x90a2214d,0xe3adbd7c),LL(0x1192948d,0xfe8646d5), +}, +/* digit=9 base_pwr=2^45 */ +{ + LL(0xba958101,0x65026297),LL(0x8eef151d,0xbeb4adf9),LL(0x60c8bbf7,0x623763a4),LL(0x8b2a7120,0xfa8f5ad7),LL(0x085497e7,0xfd744bdf),LL(0x2ba35618,0xf9b6f97e), LL(0xf8a15e86,0x0cebfe9d),LL(0x29576088,0x47a6d013),LL(0xfcf19627,0x655817a3),LL(0xc2f11261,0x30ab44f7),LL(0xddf2c850,0xbb001c9d),LL(0x073260c3,0xb45c7eff), + LL(0xe2319f38,0xfa7d1236),LL(0xa551d3fe,0x9ba1a1c0),LL(0xbeb1282b,0x9ea27288),LL(0x07fee8a9,0x1c069efa),LL(0x5870fee9,0x5749c7b5),LL(0xafcec6fa,0xbedca76f), LL(0x4c63c5e2,0xa3f8f1b1),LL(0x94758ac3,0xaa1bb156),LL(0xb59dc06e,0x753329a9),LL(0x98a92c38,0xfa8e5f5b),LL(0x3c2b4662,0x6b6f46fd),LL(0xec04c6c6,0x716f41a1), + LL(0x59b11c7a,0x0430af77),LL(0xd4f47aca,0xf71cc5b1),LL(0x12e9190f,0xe1a7905f),LL(0x12db9e14,0x1c689b70),LL(0x0abaeeac,0x6bdd3dc9),LL(0x504f0319,0x97f1c244), LL(0xa7a54b51,0x874afd61),LL(0xe3d979b8,0xd4604ecb),LL(0xebf4aab1,0x0d33eee1),LL(0x1aa49fe6,0xa3631cac),LL(0xf2217cfd,0x0d8340fb),LL(0x423b7e77,0xf6373284), + LL(0x9563e3bb,0x78a53b5a),LL(0x86af355c,0x19c75eb2),LL(0x019a6f8e,0x3520f427),LL(0xdc3ad0ba,0xde6fcad6),LL(0x79745b7c,0xfec96e4f),LL(0xb133f2dc,0x5e566bbd), LL(0x26561be7,0x50088a2b),LL(0xc5fddfc7,0x16275b4c),LL(0x23ae4b9d,0xf21332ff),LL(0x85246712,0x8cbc659e),LL(0xf50b515e,0x27fa9c8d),LL(0x494ac8b7,0x25ecf745), + LL(0x641e3bd1,0x437b7224),LL(0x80a58460,0x84e39f79),LL(0x09759523,0x68e52927),LL(0xe77f5904,0x0176a3ac),LL(0xe151e242,0xde92fb15),LL(0xeb1438d4,0x79965c9a), LL(0x596700b9,0x318a810a),LL(0xc2198cbe,0xa8a6ec57),LL(0xbf030fd2,0xd7709aaa),LL(0x72f5d326,0xb4320234),LL(0xb03bce50,0xc9945214),LL(0xd4ecba09,0x0bc06d9b), + LL(0x96fffb94,0xa1972c21),LL(0x99d7633b,0xbe040930),LL(0x7e23d66e,0xb116ff40),LL(0x949a19f1,0xcb12b2bb),LL(0x79e49e91,0x75df10ee),LL(0x4890bcf4,0xa3bf9076), LL(0x09a30252,0xcbaa76a6),LL(0x0ee5728e,0x17c224a9),LL(0xf4f3f4cb,0xcbc56e5c),LL(0x4fe868a5,0x8a07110f),LL(0x25e110a2,0x23289f21),LL(0xd7693c45,0x0289c12b), + LL(0xf184c91f,0x06ba6db1),LL(0x45fd0382,0x3c0a348a),LL(0x4434b527,0x0d535b6e),LL(0x692bae0b,0x7bbfa2c8),LL(0xbe7fe51c,0x5c59a08e),LL(0x36e80cb8,0xbaa7d2be), LL(0xbed3cae8,0x8a42d8d1),LL(0x15ff4962,0xd9e0bc0d),LL(0x644c75ff,0xe51fce93),LL(0xb9392d63,0x40222561),LL(0x023b4787,0x8ab1d286),LL(0xa1b3190d,0xfa85c220), + LL(0x2b0c535b,0x29864753),LL(0x70506296,0x90dd6953),LL(0x216ab9ac,0x038cd6b4),LL(0xbe12d76a,0x3df9b7b7),LL(0x5f347bdb,0x13f4d978),LL(0x13e94489,0x222c5c9c), LL(0x2680dc64,0x5f8e796f),LL(0x58352417,0x120e7cb7),LL(0xd10740b8,0x254b5d8a),LL(0x5337dee6,0xc38b8efb),LL(0x94f02247,0xf688c2e1),LL(0x6c25bc4c,0x7b5c75f3), + LL(0x938e2480,0x1213a2fc),LL(0xed7b85a1,0x2dff0ea8),LL(0x0cc9619f,0x4f280c74),LL(0x66678817,0x3a215bc5),LL(0x327985a8,0xa51602ca),LL(0x10f02615,0xd6916920), LL(0x3dc4f2b6,0xd01274aa),LL(0x3ff804d1,0x40feccd7),LL(0xa2100fa4,0xe508a27c),LL(0xd90cc776,0x37cc757e),LL(0xb74827c4,0xaec4884b),LL(0x4ac34a27,0x0c904582), + LL(0xf761baaa,0x6ad3f9d3),LL(0xa5ae6088,0x3936d0d9),LL(0x83a0dd41,0x54d5bff0),LL(0x70cfa7fe,0x418c4b20),LL(0x892317fc,0xdc4d4742),LL(0x265359a1,0x1248e2c0), LL(0x2120ad82,0xa14ee83c),LL(0x89260c26,0x048b7b27),LL(0xb5fe2775,0x637e71d5),LL(0xf3e08f62,0x849213d5),LL(0x5a9faeb1,0x8a8a2da8),LL(0xef96612f,0x57047761), + LL(0x027a3ba4,0x7608efa7),LL(0xcf450422,0x14cb67ad),LL(0x5330ef70,0xc55a7aae),LL(0x64901358,0x3f18a78d),LL(0xfeb668df,0x264d3a5c),LL(0xbcf7c23b,0xdc0569c0), LL(0x6ae18907,0x93af8a9b),LL(0x24b8e961,0x55dd3e3a),LL(0x36171692,0x1c3fcd34),LL(0x2f1f7ca5,0xfc0ab80c),LL(0x564878a7,0x0dadc166),LL(0x000d81f3,0x7d20d34b), + LL(0xb19231b4,0x0e8d03f8),LL(0xdcda852b,0xe4498dbd),LL(0x31a8dddb,0x9963a6bb),LL(0xd949c6cf,0x80bfba33),LL(0x1b6e1ab7,0x72e48395),LL(0x82d7301d,0x35a2a802), LL(0x01edd784,0xcfce9b91),LL(0xcd9bcb9c,0x794ab50e),LL(0xf465c3ca,0xe1f90e0c),LL(0x902b1b57,0xb7ded4b5),LL(0x8a8c27b4,0xe593dafc),LL(0x6f940ca0,0xa80faad4), + LL(0x421e65d3,0x5396fd32),LL(0x15e91d37,0x6c826fe2),LL(0x3cc3d9cb,0x14c80f4a),LL(0x43028c7f,0xdb760a13),LL(0xce1a3e42,0xd7a541bd),LL(0xb81193f1,0x4726a5b7), LL(0xf004d745,0x5c96916d),LL(0xad031ec3,0xc86961c0),LL(0xb8d28a4f,0xb5a73c58),LL(0x7ed16163,0x9a7bcb0e),LL(0x2fbd18f5,0x3f6871f3),LL(0x42155e84,0xebef020a), + LL(0x4cdd5d8c,0xce6c810c),LL(0x078c9bc1,0x9fc290a4),LL(0x96d47e78,0x84debffd),LL(0x143590fe,0xf291d301),LL(0x69111f3a,0x7cc5c36d),LL(0x46311370,0x3a2cdc42), LL(0x9e6f14a7,0xd3d8bb98),LL(0x481e22db,0xfeb97d41),LL(0x462748fe,0xe1e20cfb),LL(0xa2eaf3c7,0xcf8f5dd0),LL(0x302a52d4,0xb4f9acd4),LL(0x8d715c96,0x1c154dcd), + LL(0xb13ddc9c,0x5f492236),LL(0xbabe466c,0xc930fb0e),LL(0x5c017d52,0x21daa0b9),LL(0xea9a6c9b,0xc182a975),LL(0x4fd839af,0x45d3d6c0),LL(0x3d89b744,0x9e4ce10a), LL(0x3a947f16,0x906af540),LL(0xa377f4f3,0xa0f8e1b7),LL(0xe343d7c1,0x268360cc),LL(0xbddbeb1a,0x66fe9eb7),LL(0xc3bafefc,0xf5c80368),LL(0x6664d04e,0x0e183ee0), + LL(0xfda8520e,0x36c9dbbe),LL(0x6ae3ea98,0x573507ce),LL(0x96a8f9f1,0x1ab38db6),LL(0x6b01e6bc,0xe031d235),LL(0x8afc4ada,0x10466ae6),LL(0xed9c44e4,0x3b35df41), LL(0xc7bd99e8,0x61272c12),LL(0x805afd79,0x6a4ae7b4),LL(0x0ecc49eb,0xf4c47a91),LL(0xcbe84d5c,0xeb95dfec),LL(0x8ee497d7,0x43f3b71c),LL(0x4c6fece4,0x2547af52), +}, +/* digit=10 base_pwr=2^50 */ +{ + LL(0xced45039,0xe323ed0c),LL(0xa90aa713,0x04ce0b67),LL(0xe8d68e4e,0x9c092f06),LL(0xd0742e5d,0xd8f5555a),LL(0x00d3df92,0xe2d175bf),LL(0x4f71aeab,0x8ca55f15), LL(0x642d391d,0xd1762d72),LL(0xaec466bd,0x0dfdd3c2),LL(0x6281f2a7,0x2caacb4c),LL(0x3603e53a,0x635ba470),LL(0x49fecf29,0x94a9811d),LL(0x466bf361,0x3a42cf09), + LL(0x11bccf2f,0x0f05710b),LL(0x7aec1bc6,0x7113085a),LL(0x46b8d0e2,0x137da67a),LL(0x698b78cc,0x454b89fc),LL(0x258a9393,0xf2a6e1de),LL(0x16488e69,0x5f1804e7), LL(0x15b3bf35,0x7c6c5502),LL(0xb05c2ec1,0x3b0e09a5),LL(0x92f15247,0x4b9de30e),LL(0x27e70a0a,0x09d4ca93),LL(0x0d149363,0x9c8b1634),LL(0xce642137,0x54a8287c), + LL(0x346a764e,0x49ecd6f3),LL(0x4105e657,0xe46847f1),LL(0x7550f608,0xce9cb2b5),LL(0xf4cf062e,0x45f1a1f7),LL(0x2c27d38a,0xcdb19a11),LL(0x84e50b19,0x36d375b2), LL(0x0dba6405,0xf4369154),LL(0x040354dc,0x4c9dc863),LL(0xa24d09cf,0x7229e70e),LL(0x7cf6831b,0xe72aa86c),LL(0x25392838,0x487fb684),LL(0x430b9b47,0xe88bed04), + LL(0x666fa8a8,0xf8a8499b),LL(0x71bba84a,0xd0f94015),LL(0x515e1328,0xb85e1b1d),LL(0xa941e788,0x88a2636b),LL(0x2b5dd8d8,0xa045241d),LL(0x332f0350,0x161be476), LL(0xa18fac6b,0x96c4b205),LL(0x73fc5337,0x5cbe8d5e),LL(0xd00b6029,0x6fc33fc6),LL(0x89aa3b79,0x07a914ee),LL(0xa4d4dd00,0x35353eb7),LL(0x673e8956,0xc026bdc0), + LL(0x67103852,0xccda3721),LL(0x0c54de53,0xf78d2247),LL(0xafa44aa5,0xebd16036),LL(0x64a24ab9,0x7b880248),LL(0x1c2bc78e,0x86b38e96),LL(0x8d63b295,0xd0aa0d05), LL(0xc62fcbf1,0x24912955),LL(0xb9ac435c,0x77a68156),LL(0x1b360b26,0x432401c7),LL(0x4c58ef8c,0x091f19f3),LL(0x83d46c9d,0x3a4a61f4),LL(0xe8d616cd,0xad0e5c72), + LL(0xcdaa6831,0x33b029bc),LL(0x4c1f9ced,0x2548552d),LL(0xdece1c8c,0x35f1a002),LL(0xacc23aa5,0xc6b87fd7),LL(0xbab029a4,0x0b8bb275),LL(0x30bfb42d,0xf07bc067), LL(0x1f69ce9d,0x1688ff5d),LL(0xdb10585e,0xeedb7b5e),LL(0xd432c197,0xb7a88cf0),LL(0x015a350a,0x20731bdd),LL(0x63223f5c,0x5fa18354),LL(0x8024693f,0xe392e131), + LL(0x0154731e,0xdfaeea0a),LL(0xe15a0388,0x9e53419d),LL(0x25a992c8,0x2ad6a83c),LL(0xe125501a,0xa2ba020f),LL(0xd4dd04dc,0x894ebaf8),LL(0x50765559,0xd48cb958), LL(0x80dec92b,0xf9b58d09),LL(0x9da299d7,0x2a0e1165),LL(0xefe9cb11,0x3c081853),LL(0xa511c5e0,0xb9f3b702),LL(0x70486180,0xa8f7a25f),LL(0x591b3e2f,0xc0358b25), + LL(0xeaddf274,0xf36e8398),LL(0x6a5e4ddb,0xe41553a1),LL(0x4efc5b0c,0x36ab0746),LL(0xd316c434,0xb211e59a),LL(0x16ccf839,0x2515ec9f),LL(0x03dc6a07,0x6ecb7465), LL(0xc65c1b07,0x842b7275),LL(0x35750ab6,0xf7ceeec5),LL(0xcef5255d,0x967d711c),LL(0x5108cb92,0xcd3bfb07),LL(0xec1b9740,0xe50c0d8a),LL(0x1a9e6308,0x9e8d5661), + LL(0xccb8a36a,0x84f8ea13),LL(0xa05709a2,0x5f7aeeff),LL(0x60574f37,0x4942d04e),LL(0xe048b400,0x855b13e9),LL(0xa6b59c09,0x747e4067),LL(0x074d3990,0xc349fb05), LL(0xec2c7e03,0x398e6afa),LL(0xec2d5a4c,0xce361865),LL(0xb6f57d22,0xfc04bf8e),LL(0x759ce6c6,0xf0e0b84c),LL(0x5ee7e528,0xb6514123),LL(0xf5c0f9b9,0x8ca144bd), + LL(0xf6a58536,0xc1370dae),LL(0xc56b0ae9,0x6f2e5b37),LL(0x92f6b6a3,0x5511d682),LL(0xae575249,0x2e9e5034),LL(0x1d14bed7,0x3e5a32f8),LL(0x75efd17a,0xa346a86f), LL(0x0309fd7a,0x4f2510a6),LL(0xd0b1425e,0x689ecd74),LL(0x9f771e24,0x9e9bebe1),LL(0xadc5b48c,0x20188045),LL(0xb845230b,0xe49811b6),LL(0x5a8687f8,0x420855ec), + LL(0xbae1b94d,0xe650e49a),LL(0xe3199794,0xb6b162e6),LL(0xb4ec0480,0xdc706859),LL(0x4b1a06ca,0x28b618c2),LL(0x403acdc2,0x0929a001),LL(0x2da3aefd,0x796dfd97), LL(0xef4c1673,0x16389072),LL(0xfc94a4f5,0x600d8bd7),LL(0xe5f386a9,0xf003214d),LL(0xe62cbb48,0xa7af0499),LL(0xde82bad5,0x750a3b00),LL(0x8e7dc8ee,0x6c615b83), + LL(0xd71543a6,0x283eec26),LL(0xa7627841,0x98fa08be),LL(0x27ad302d,0x269a83b8),LL(0xbde3fdd0,0x225f2f12),LL(0x0130b3a6,0x046fcf38),LL(0xc3ed9043,0xea733c1a), LL(0x70aa08d1,0xf870f14d),LL(0x34391e0b,0x643d18b8),LL(0x847be772,0xf3e1d5f4),LL(0xd0ed73a0,0xa9498223),LL(0x14b3babb,0x6933ccf0),LL(0x37f08f70,0xc2439ae4), + LL(0xf88d049b,0xb643f4e0),LL(0x12682fcf,0x5e0ac1fb),LL(0x9f981c8f,0xeaf7874d),LL(0xb1af779d,0x9c2adfd2),LL(0xdaa8c275,0x9a7abead),LL(0x24cacec4,0x09ad5521), LL(0x0ead1646,0x069cd5c4),LL(0x0a6157d1,0x5186bf19),LL(0x96503506,0xcc222a93),LL(0xbd29686e,0xfeaa7bde),LL(0xa7257c8d,0xb0d65b0d),LL(0x98aa227f,0xc31c0a88), + LL(0x5be1d45b,0xb4b7651f),LL(0x7f0cf680,0x0425200a),LL(0x8960be95,0x200d12b4),LL(0x4945b193,0x02fdd1a1),LL(0x27d046d8,0xedd70e3e),LL(0x83f14e12,0xc1cc086a), LL(0x2629396e,0x1580e72b),LL(0xf9ed73c1,0xc87439db),LL(0xa90c5128,0x5debdf30),LL(0x9fbe14ef,0x0b6c020e),LL(0x0149a0b0,0x168da56a),LL(0x79c58ac6,0xc66a4dbd), + LL(0x330b8e2e,0x800aec84),LL(0x335837bf,0x1a2c033e),LL(0xfe6f6dd9,0xf1a91551),LL(0x1de7360a,0x326c42b2),LL(0x7b66f9d5,0x300e740b),LL(0x68ce95d4,0x53bcc700), LL(0x3d80f228,0xc9e225ac),LL(0x6977dfdb,0x64b2ad4e),LL(0x01f23221,0xac863b08),LL(0xdf11e5f7,0x0517a648),LL(0x68d11050,0xbf7aedcb),LL(0x77b3029c,0x2607e337), + LL(0x206add5d,0x1afa6aa6),LL(0x150ea4c9,0x66cfbbae),LL(0x5d36da4f,0x07fb920b),LL(0x291e774f,0x144d51f9),LL(0xf40d87a8,0x26c2c134),LL(0xa932f1a0,0xc8cf3524), LL(0x5aeb0bde,0x35bb2a42),LL(0xc4be960a,0x5cfcc1da),LL(0xaa1838ed,0x5c40cabf),LL(0xe2855f1f,0xea0c05ff),LL(0xfd525934,0x931ebb02),LL(0x16246fd4,0x31a7b78f), +}, +/* digit=11 base_pwr=2^55 */ +{ + LL(0x6d6ae962,0xcd92906c),LL(0x9807d881,0x62835615),LL(0x1fdc1915,0x0d692978),LL(0x269d611e,0x45d01a8c),LL(0x9665b00a,0xe7bd1e70),LL(0x9bcaa388,0x08638534), LL(0x2dd24299,0x8f189e88),LL(0xb82fb270,0x5f643392),LL(0xc633b111,0xca65bf16),LL(0xd6f1dac8,0xc6adc9c9),LL(0xa3c3381d,0x0df2c293),LL(0x8388cd12,0xdd6ae97d), + LL(0x3863db02,0xffdbd0eb),LL(0x2f57e10f,0x8b825683),LL(0x35e7a3a2,0xc11acead),LL(0x67833028,0x4998cf8c),LL(0x844c7976,0x8f3a346b),LL(0xdb9b1a1c,0x0a9d872c), LL(0xb98d445d,0x8735dabc),LL(0x305fa0a9,0x93790d80),LL(0xd267a01a,0x7c0add49),LL(0xffa20d11,0x2b46c913),LL(0xd8ab2d4a,0xf2acef26),LL(0x3d926080,0x71b701b9), + LL(0xfbf536a1,0x7cae584d),LL(0x5b52faa9,0x0af06fc2),LL(0x2827b872,0x807706dc),LL(0x59903742,0xf029478f),LL(0x85cd7aed,0x0e8c393c),LL(0xa331bee7,0x2e1e6ade), LL(0xcdb7f97a,0xf5d13dad),LL(0x8577c3cc,0xdb22fed1),LL(0x81e39043,0x6f453180),LL(0xa00a806c,0x41d4bb25),LL(0xe28670a7,0xe6064b92),LL(0xa7c63f88,0x733a31c8), + LL(0x5133de8e,0xe9d2a98a),LL(0xb81b8b00,0x37083b60),LL(0xceaf86ae,0xf399325d),LL(0x8f161525,0x03b17c88),LL(0x84211b9d,0xd8ac35c9),LL(0x9050ca48,0x22083784), LL(0xc9fab832,0xa818c44b),LL(0xe5aea7da,0x8882bcce),LL(0xf8715b04,0x633aaf35),LL(0x9d8829a9,0x5463e1b9),LL(0x84a820f1,0xb18df52d),LL(0xd096675d,0x9d5ef891), + LL(0xc2b47dd2,0x394174d0),LL(0x30a87997,0x06b117a8),LL(0x894731e5,0xcfd81d41),LL(0xc84e7d05,0x6476b1af),LL(0x743b8218,0x37069fe2),LL(0xa36173d8,0x93f21550), LL(0xedadef86,0xa8ae70f4),LL(0x76366073,0xdac5d021),LL(0x1c982076,0x4063ba57),LL(0x2d24d61e,0xc3471b5f),LL(0xae4d820f,0x57b69c41),LL(0xc463a391,0xf73e14a4), + LL(0xac60496d,0xd54e2c7c),LL(0x04cd50a4,0xc06d5e5d),LL(0xe60f7f59,0xcb4105e8),LL(0x427483ad,0x705db308),LL(0xf2bff383,0xf73ba98b),LL(0x0220e6e9,0xa945611a), LL(0xd957e12b,0xc01c46b8),LL(0xacb1f371,0x458897b7),LL(0xfa3403e6,0xf738dc0b),LL(0xd2202896,0x098bc687),LL(0x5f882e5e,0xec0c217a),LL(0xa1f4eb13,0x8f25af77), + LL(0x195736e9,0x86e6a8fc),LL(0x1a20620f,0x88099bf3),LL(0x9cdc1db9,0xf3d9998b),LL(0x47042834,0xf36d583e),LL(0x25a0d589,0xcd4519d8),LL(0x1e04a91d,0x78c435ab), LL(0xe44d9e31,0x0428e76e),LL(0xce821aab,0x63994993),LL(0x2625cfce,0xd167ceb7),LL(0x0ddf2b89,0x9f242245),LL(0x717ffb5e,0x182e33d6),LL(0x26de205c,0x3800290e), + LL(0x59ee4124,0x2615c782),LL(0x76532b4b,0x4dc2824c),LL(0x1c84a04b,0x9c3b1d77),LL(0xcb9f9e34,0xb6fc203f),LL(0xc64f7846,0xbed65464),LL(0xeb004248,0x04f520a2), LL(0x4a58fd22,0x5c017727),LL(0xc10d9472,0x25958482),LL(0xaceb0e3a,0xb78c6666),LL(0xfc046f0a,0x18d3c188),LL(0x1baa9595,0x7f3e2f30),LL(0x8a2844e8,0xa574f8cd), + LL(0x4bcc5a81,0x9fd2e524),LL(0xd3f2f80f,0xc73e2598),LL(0x15dc157c,0xff838e9c),LL(0xc522319e,0x0b2491d2),LL(0x909592d6,0x2b65f042),LL(0x849f5dee,0xf113045c), LL(0x9b287c3d,0x84fe31be),LL(0x80097bd0,0xd0481262),LL(0x63660f87,0xaf203cba),LL(0x0ea001b3,0x5621c3d8),LL(0x346ea29b,0x125a5eaa),LL(0x3ca79649,0x3dcec22c), + LL(0x81c2d81f,0xc899eba3),LL(0xf3f0a431,0xb27267d6),LL(0xda55568e,0x607c8629),LL(0x2b1dc1d9,0x6b547228),LL(0xc9c001ff,0x23232311),LL(0x488f8b85,0x207a2eb2), LL(0xdac37a28,0x3867ac9a),LL(0x2584a5f0,0xa36d14d3),LL(0xa74488ff,0x7398c647),LL(0xbe087640,0xf6ed920f),LL(0x6319a571,0x72beddc7),LL(0x6a244aeb,0x55c2cd82), + LL(0x9ede92f1,0x42df5630),LL(0x76503aa7,0xe6957bc4),LL(0xfbec9577,0xe7abfe12),LL(0x274b7f6c,0x9660e762),LL(0x35f12ea2,0xf78af22c),LL(0xb51bec2c,0x73ab1bbb), LL(0x1641f424,0x5e8e40e6),LL(0x0905e4be,0x1af751d9),LL(0x1c033198,0xb5130ade),LL(0xa22f5f19,0x96d47ab2),LL(0x55340d4c,0x5aff3e66),LL(0x1bed65fa,0xab4aa5a7), + LL(0x25f8a53b,0xb7da79c6),LL(0xd331ad8e,0x6b950bdf),LL(0x4aa36d18,0x3481b7b5),LL(0xed0e3091,0x6efeaf88),LL(0xc993074c,0xeb017bdd),LL(0x529dd654,0x8431a6d6), LL(0xbd069585,0xf5177231),LL(0x3ce85096,0x6d753b10),LL(0x4ca26741,0x194d82d3),LL(0xadcd1650,0xeaeffe15),LL(0xaf7758b7,0x4dcec3d9),LL(0x4cc2c819,0xf5fdf666), + LL(0xae850261,0x7e9ad6e8),LL(0x11960968,0xbeb25ca0),LL(0xad4cfa42,0x60c5f0ee),LL(0xeca5c508,0x81714b3f),LL(0xb78a290f,0x810e71d7),LL(0x3260114c,0x03536cec), LL(0x6a16cdf6,0x24d29f0f),LL(0x4a4c964c,0xec45a58a),LL(0xea344b44,0xbaaa5fb3),LL(0xfeb783f6,0xf1b7a68c),LL(0x3ddd7062,0x533c4b72),LL(0x1598b5f7,0x6a33a0dc), + LL(0xa9810744,0x94bdc7f4),LL(0xf045d859,0x464195da),LL(0xd654cb57,0x27e2dab0),LL(0x7a491956,0x1d4e1e53),LL(0x31d5d099,0xa1ef570c),LL(0x295f3de7,0x01cd21ee), LL(0xb8249038,0x8681b00d),LL(0x93781b71,0x17c31bce),LL(0x6a1b5748,0x4324e90c),LL(0x1222e554,0x44f9324c),LL(0xffd53dd0,0xe30ba10f),LL(0xb48eeef0,0x2e5817a8), + LL(0x24b3a9a7,0x6b0ee060),LL(0xd5f6545c,0xcf78c3fe),LL(0xfe0f2ec6,0x050bedaa),LL(0xb3e6b4f8,0x0b7774b8),LL(0x2b4a853e,0x096b9e19),LL(0x0698f7ca,0xa7463661), LL(0xf090c97b,0xe1d1d1be),LL(0x55517a2f,0xbc1e09d9),LL(0x5868ee3d,0xb3e24dd5),LL(0xd7b83619,0xd6103494),LL(0x3b0129b3,0xaf739559),LL(0x3ded9fb3,0xef42bb60), + LL(0xc8fccaa9,0xa349bb66),LL(0x31a53ee7,0x7888755f),LL(0xc18d3750,0xa6e1d891),LL(0xae8d2bfb,0x9985aa4d),LL(0x31b33078,0x8baec9ae),LL(0x98750e94,0xee68295a), LL(0xd6ddf305,0x0d834bf8),LL(0x9762126c,0xab33dff3),LL(0x0c51d098,0x0c22faaa),LL(0xb887a10f,0x32404042),LL(0x248bed32,0x31f6a614),LL(0x1ce0d662,0x311f8630), +}, +/* digit=12 base_pwr=2^60 */ +{ + LL(0xedc9ce62,0xac6dbdf6),LL(0x0f9c006e,0xa58f5b44),LL(0xdc28e1b0,0x16694de3),LL(0xa6647711,0x2d039cf2),LL(0xc5b08b4b,0xa13bbe6f),LL(0x10ebd8ce,0xe44da930), LL(0x19649a16,0xcd472087),LL(0x683e5df1,0xe18f4e44),LL(0x929bfa28,0xb3f66303),LL(0x818249bf,0x7c378e43),LL(0x847f7cd9,0x76068c80),LL(0x987eba16,0xee3db6d1), + LL(0xae658422,0x1238e097),LL(0x568df55f,0xb4631ddb),LL(0xf74c5c50,0x451254e7),LL(0x8805813b,0x238b16d2),LL(0x925e7a6e,0x23987b28),LL(0x2a1a10bc,0x93b72e2d), LL(0x05e44b7f,0x944c784d),LL(0x8c8e3120,0x7d70fd09),LL(0xead45716,0x6bf1ab2a),LL(0x31c04205,0xd5f8f0e6),LL(0xa10b8881,0xac062526),LL(0xfe5505a8,0xa1a83cf0), + LL(0xc42a2f52,0xcbbd8576),LL(0x9d2b06bb,0x9acc6f70),LL(0x2e6b72a4,0xe5cb5620),LL(0x7c024443,0x5738ea0e),LL(0xb55368f3,0x8ed06170),LL(0x1aeed44f,0xe54c99bb), LL(0xe2e0d8b2,0x3d90a6b2),LL(0xcf7b2856,0x21718977),LL(0xc5612aec,0x089093dc),LL(0x99c1bacc,0xc272ef6f),LL(0xdc43eaad,0x47db3b43),LL(0x0832d891,0x730f30e4), + LL(0x37d83369,0xac92ee15),LL(0xfecec65c,0xc968c187),LL(0x6e7a3265,0x29a7ca87),LL(0x8456c9af,0x0f2b7e7a),LL(0x9754326f,0x7471824e),LL(0x364d2ec8,0x498687bf), LL(0x3c6ee351,0x86d8aacd),LL(0xf6f41e85,0x01ee6823),LL(0x1d79f7eb,0x9805fc88),LL(0x0040547d,0x377ac3a4),LL(0x61b4e90b,0xd39215d4),LL(0x4c5fd81b,0x2547416e), + LL(0x0c7fecdb,0x9ffe5563),LL(0xf88101e5,0x55cc67b6),LL(0xcbefa3c7,0x3039f981),LL(0x667bfd64,0x2ab06883),LL(0x4340e3df,0x9007a257),LL(0x5a3a49ca,0x1ac3f3fa), LL(0xc97e20fd,0x9c7be629),LL(0xa3dae003,0xf61823d3),LL(0xe7380dba,0xffe7ff39),LL(0x9facc3b8,0x620bb9b5),LL(0x31ae422c,0x2ddcb8cd),LL(0xd12c3c43,0x1de3bcfa), + LL(0xf6e10789,0x03621d34),LL(0x410c4004,0xc72143b8),LL(0x6ca2933a,0x886d00f6),LL(0xde1494a2,0xd0a22382),LL(0x0bdcdf82,0xb8656c4d),LL(0xc4a58832,0x5199d9d3), LL(0xe1c0f449,0xa982c1aa),LL(0x5a922bdb,0xe9cefb90),LL(0x31390c6d,0xfc268de4),LL(0x8c4fe595,0xea4160e1),LL(0x6790d82f,0x6c427a63),LL(0xfc519907,0xaceb0154), + LL(0xd6e0f9a9,0x8c074946),LL(0x51c3b05b,0x662fa995),LL(0x04bb2048,0x6cdae969),LL(0xd6dc8b60,0x6dec9594),LL(0x54438bbc,0x8d265869),LL(0x1b0e95a5,0x88e983e3), LL(0x60cbf838,0x8189f114),LL(0x771dc46b,0x77190697),LL(0x27f8ec1a,0x775775a2),LL(0x607e3739,0x7a125240),LL(0x4f793e4e,0xafae84e7),LL(0x5bf5baf4,0x44fa17f3), + LL(0x07a6fbf8,0xa10292b9),LL(0x3fa6235b,0x292c1a20),LL(0x73ad7a1f,0x7a36f18f),LL(0x5897b11f,0x8b2c7b0c),LL(0xcb664c61,0xf7b9a272),LL(0x8f81e22c,0xb6d366af), LL(0x8e342bba,0x3b99b211),LL(0xb06ced2b,0x03ce158b),LL(0x001db74b,0x3af1175d),LL(0x7159cb8a,0x526f0846),LL(0xebde4601,0x6a3c6e1f),LL(0x8c232eac,0xfad5963b), + LL(0xd03ac439,0xa21e69a5),LL(0x88aa8094,0x2069c5fc),LL(0x8c08f206,0xb041eea7),LL(0x3d65b8ed,0x55b9d461),LL(0xd392c7c4,0x951ea25c),LL(0x9d166232,0x4b9a1cec), LL(0xfcf931a4,0xc184fcd8),LL(0x063ad374,0xba59ad44),LL(0x1aa9796f,0x1868ad2a),LL(0xdff29832,0x38a34018),LL(0x03df8070,0x01fc8801),LL(0x48dd334a,0x1282cce0), + LL(0x42a993b1,0x21387e8a),LL(0x68b1f2a0,0xbcb65533),LL(0xa5f7e4b9,0x3161d87a),LL(0x1bce0a84,0x927b4130),LL(0x87be0ae9,0x3aabd327),LL(0x0aed169d,0x0163c6aa), LL(0x11584051,0xad1e0f0e),LL(0x74093225,0x1ba46302),LL(0x0a6a1f01,0xed045618),LL(0x6da060ed,0x15d07c63),LL(0xb7e003ae,0xa4584f72),LL(0xa02ec136,0xf6e6b7c4), + LL(0x26d8503c,0x76aa9557),LL(0x6bc3e3d0,0xbe962b63),LL(0x97de8841,0xf5ca93e5),LL(0xaf3f2c16,0x1561b05e),LL(0xd34bff98,0x34be00aa),LL(0xd23d2925,0xea21e6e9), LL(0x394c3afb,0x55713230),LL(0xd6c8beca,0xeaf0529b),LL(0x202b9a11,0xff38a743),LL(0x6d3a398b,0xa13e39fc),LL(0x86e2615a,0x8cbd644b),LL(0x191057ec,0x92063988), + LL(0x74962b2e,0x71503219),LL(0xe1db7ec7,0x3beeaf81),LL(0x445c4e88,0x702784cc),LL(0x9baad7ed,0x7aa58315),LL(0xd044b38a,0x72b76e2f),LL(0x6a7f2101,0x35a2bb8f), LL(0xa14c2bf2,0x5e6ae263),LL(0x34bb719d,0x8fb614c0),LL(0x5dcd7c65,0x7949eeca),LL(0x7670aeb1,0xb198be58),LL(0x93cabf25,0xb2238dfc),LL(0x1a422b95,0x6a6d4555), + LL(0x13f89146,0x787835ce),LL(0x69446c3f,0x7fcd42cc),LL(0x840e679d,0x0da2aa98),LL(0x18779a1b,0x44f20523),LL(0xefbf5935,0xe3a3b34f),LL(0xb9947b70,0xa5d2cfd0), LL(0x27f4e16f,0xae2af4ef),LL(0xb9d21322,0xa7fa70d2),LL(0xb3fd566b,0x68084919),LL(0xd7aad6ab,0xf04d71c8),LL(0x10bc4260,0xdbea21e4),LL(0x8d949b42,0xaa7dc665), + LL(0xf7848707,0x3ddea6d9),LL(0x6dbcf13a,0xc11260d0),LL(0xa16508f0,0x62c5ee60),LL(0xcb56535c,0x4bdfa38f),LL(0x4fa5a6b0,0xd391e786),LL(0x2d4cd296,0x173c3d70), LL(0x5fa3f53c,0x9c5c596f),LL(0x1ddd3732,0x77d39514),LL(0xa5bf4edc,0xca1bb91d),LL(0x1cd98b09,0xb23afd38),LL(0x60bdfa0f,0x198248ed),LL(0xfb69a4b1,0x559dd99c), + LL(0x6ccb8213,0xd8e958a0),LL(0x91900b54,0x118d9db9),LL(0x85e8ced6,0x09bb9d49),LL(0x24019281,0x410e9fb5),LL(0x6d74c86e,0x3b31b4e1),LL(0x020bb77d,0x52bc0252), LL(0x27092ce4,0x5616a26f),LL(0xa08f65cd,0x67774dbc),LL(0xc08bd569,0x560ad494),LL(0xad498783,0xbe26da36),LL(0x7f019c91,0x0276c8ab),LL(0x5248266e,0x09843ada), + LL(0xb1b43eef,0xa54768da),LL(0xe14fda22,0x13e41f47),LL(0xfaef6863,0x774df203),LL(0xbd7471b3,0xf795a034),LL(0xb47de2e9,0xf0958718),LL(0xe1160cff,0xc92f7888), LL(0x0146c790,0x86ded97b),LL(0x480a4b7b,0x015918f5),LL(0x424e8459,0x05588920),LL(0xeecf8b2b,0x37455914),LL(0xb968a6fa,0xe7d3df1f),LL(0xbad0719f,0x07a0ffd6), +}, +/* digit=13 base_pwr=2^65 */ +{ + LL(0x98d23f6f,0x2566021f),LL(0x34ca97ca,0xfb883e12),LL(0xd9f51b69,0x34e047a5),LL(0xf8efa646,0x0b50d91d),LL(0x971f584f,0xc2bbcbb2),LL(0x0907c91c,0x4136f0e4), LL(0xe735cc48,0xa7ebeb0d),LL(0xe113c8fa,0xa7d1bedc),LL(0x3f5c962a,0xc04d9a07),LL(0x3ff74a2f,0x95c155e5),LL(0x3df0749d,0x923c65a5),LL(0x27ae35d0,0x10d5f812), + LL(0xecee6e87,0xd5469c7b),LL(0x33a4c917,0x056180bc),LL(0xa16caa7a,0xf881ca21),LL(0xe6cc7f39,0x221de182),LL(0x31378723,0x10d61ab5),LL(0x520c9660,0xfb763bd9), LL(0x0d6b1541,0x145214cd),LL(0xd70223e7,0xd9f7ff2d),LL(0x0cb1fe69,0x9fce59e3),LL(0x3e299fe7,0x2e6e77fa),LL(0xd5af78cf,0x3a0cf652),LL(0x3e852159,0x50cc42c5), + LL(0xdf764716,0x0791dfa1),LL(0x8c66da07,0x31bf6876),LL(0xccedf4f3,0x49f25b77),LL(0x5d965c05,0x05170ccd),LL(0xd49e6727,0x37d9521b),LL(0x86a00176,0x15482512), LL(0x6c00eb48,0xdab44493),LL(0xe00c5c5d,0x102c6b95),LL(0x4c2506ba,0x43660c3e),LL(0x5ec6f132,0xb2fb2616),LL(0x99ac7691,0xccc4221a),LL(0xa576deb5,0x05b29758), + LL(0xad8c49b7,0x4a873076),LL(0x7146575f,0x891598ce),LL(0x427ea198,0xc1d3042f),LL(0xed259219,0xdc592111),LL(0x234850ca,0x0abdbd16),LL(0x43b6fe8d,0x26b94126), LL(0x36a1cfe9,0xd3c79d17),LL(0x9a2b3baf,0x57638621),LL(0x5a98bf65,0xa736535d),LL(0xab2cdb2b,0xacb3b7dd),LL(0xdaaf89ee,0x37d3743a),LL(0x0b348532,0xf19d9aba), + LL(0xd93c54b2,0xafad01a0),LL(0x95536c49,0x659bff96),LL(0xb9734c15,0x7b91aac2),LL(0x24e02f59,0x55c7f082),LL(0x3a26e551,0xebcb71e7),LL(0x6c6343eb,0x5b7225f7), LL(0x17d5e775,0x021c48fb),LL(0xbd859c87,0x57536a42),LL(0xae2b63e9,0x24852cc0),LL(0xc0ce0ef1,0x21515020),LL(0x8fed825e,0x2ac7336c),LL(0xa0152819,0x4bc87fee), + LL(0x4654712c,0xe7c396d6),LL(0x7a26e994,0x1fa5ea50),LL(0x09012b83,0xaa987687),LL(0xe9b17e98,0xf1ef9792),LL(0x6dc2db10,0x2c22bcb0),LL(0xed4be80e,0xae42ddf6), LL(0x2e743405,0x672080f6),LL(0x5b7821d1,0xa15a7f97),LL(0x47adbf07,0x0cd912f2),LL(0xb6c4ae8f,0x6919c0dc),LL(0x14c6253c,0x62b13edd),LL(0xf8032287,0x66f35919), + LL(0x9d628e1d,0x2713b58c),LL(0xfaa8ba1e,0x3729960a),LL(0xab53bc93,0xc3438130),LL(0xe9c165e7,0xcef9eda5),LL(0xfd02650b,0x9bacd1c3),LL(0x540ece72,0xbb300334), LL(0xd9c4f0ed,0x21f5a5d3),LL(0xf7c19269,0x1ba32e4f),LL(0x2cf320fb,0x8f073beb),LL(0x5599646f,0xb49766c4),LL(0x49e4f200,0x68180d66),LL(0xeaeddb36,0x8203d8ae), + LL(0x2caf088b,0xa68295da),LL(0x5c8709fe,0x23d6439a),LL(0xfe0c3df0,0x8deba0cf),LL(0x3cd00a1a,0x5b4d037b),LL(0xaa0f9088,0xe9edc429),LL(0x5847def7,0x6f5827e3), LL(0x306ad966,0x9739d03d),LL(0xaed51d04,0x7c6b18af),LL(0x1759060a,0xdc3d34ff),LL(0xa7e94dbb,0x029e9aa9),LL(0xf7e8b7f3,0x2a3cdfa0),LL(0xbbd8f6f4,0x42f87bf0), + LL(0xed210253,0x516f138b),LL(0x4433461a,0x5ec2fa32),LL(0xcdaf1280,0x0dbe2c66),LL(0x9fbf3318,0x086b91e5),LL(0x399a1ca6,0xfb0223ee),LL(0x0db5b20f,0xd6f86d9b), LL(0x5752d618,0xec02bca2),LL(0xaf69f3f1,0x952fafca),LL(0x33c4d294,0xf304cb75),LL(0xdac65608,0x78085727),LL(0x840a4466,0x22f302ef),LL(0xc371c31f,0x33fb889d), + LL(0x4f890542,0xaa4711f5),LL(0xeba822c4,0x862421d9),LL(0x848280fc,0x2f667179),LL(0xc201ed75,0x4de16d87),LL(0xc5e61b5d,0xd20e1399),LL(0x9ed67ec7,0x3f7114b4), LL(0x9b5a88f9,0x561fd497),LL(0xd84db2c1,0xb202eb86),LL(0xc8637d3d,0x67d8fb90),LL(0x032b1853,0x3d1d78a1),LL(0xef1af9ac,0xe07bf775),LL(0xa57d6ada,0x691e1dee), + LL(0x3801c65d,0x834701da),LL(0x955aa27d,0x5bb35c48),LL(0xdb7ad387,0x0ef0f375),LL(0x06cd1d53,0xd25e337f),LL(0x90cd91de,0x757a1f9d),LL(0xd61bbd60,0x1604f153), LL(0x8bb95dc4,0x6a01e8cf),LL(0x75bbdb13,0x34b7be62),LL(0x21e9b029,0x0a96b3a1),LL(0x2946df44,0x25615c3b),LL(0x19d04842,0x5eda7d19),LL(0xfba84668,0x08317975), + LL(0xa55a3a4d,0x12474bd8),LL(0x9e471af4,0xe326aaf1),LL(0x8caadaa6,0xf201a930),LL(0x35304341,0x546821f8),LL(0x088353e1,0x7fe452c3),LL(0xfc82566a,0x8f1ff628), LL(0xd99f8967,0x49526f46),LL(0xa4009690,0xb19c80c0),LL(0x1cbc0716,0xeccf9759),LL(0xaf4cbc8b,0x2e13ae2c),LL(0xf32e29ad,0x12b0df13),LL(0x0b1565f0,0xa2005d6e), + LL(0xd06014e0,0xdb891eed),LL(0x03e9970a,0x69685d61),LL(0x02838113,0x3a612db4),LL(0xdcdef0b0,0xc1cd7b3a),LL(0xa41d6c1e,0x612b299d),LL(0x0ed386a0,0x982161ed), LL(0x3ea1bf1e,0xb36bbe2f),LL(0xceb2a5ec,0x0d8c3752),LL(0xec03bddd,0xc02cd7f6),LL(0x52631d9e,0xa87977c1),LL(0x7e398d7e,0x7b546cc3),LL(0x04845671,0x5b1218a8), + LL(0x6cb173d1,0xfa3e43e5),LL(0x4591b5a5,0x2502258d),LL(0x8ca9682a,0xae8c4b55),LL(0xec81a288,0x8cb1ffb4),LL(0xbfc84fd1,0xd11ae888),LL(0xd774577c,0xa3b083a0), LL(0x1da9afc5,0x119b41c1),LL(0x2934e22b,0x44bc7762),LL(0x7c639d6c,0xa04694f3),LL(0x32c5b8ea,0xd5e1ce57),LL(0x9749e8b6,0xd507c39b),LL(0x55255b63,0x16cc0b57), + LL(0x614f6f37,0x71e5df78),LL(0xa0b80bee,0x5cf0e08d),LL(0x1e32051f,0x1f8dae17),LL(0x83bc233b,0x54ae365d),LL(0x1b84aaa6,0x97ea005b),LL(0x64c75139,0xf4766d92), LL(0x41215701,0x9b93bbf2),LL(0x8cf8a865,0xb18f042d),LL(0x0867556f,0x5dfb96dd),LL(0x597fd6a1,0xe9fafbb8),LL(0xfe48bbc6,0x729b2f50),LL(0x7f37ff9b,0x2cf85f6b), + LL(0x378ef62b,0xcd8c2ec9),LL(0x91a7c4b9,0x7f4a3c54),LL(0xdb83e1ab,0xe12386d4),LL(0xbb549bb5,0x9a792032),LL(0x2807c0f1,0xaf81cba6),LL(0xabf2008e,0xd4ad7d87), LL(0x7e9ad6cd,0x9d7a7230),LL(0x8b517b2a,0xb30636b0),LL(0xec900516,0x47c324da),LL(0x7193eb30,0x408cd0d3),LL(0xd315c655,0x8f0bcce2),LL(0x869d6c22,0x540ad4e0), +}, +/* digit=14 base_pwr=2^70 */ +{ + LL(0xdae0ff8b,0x4b5e753d),LL(0xda3d97b5,0xe55c83e4),LL(0x42fa905b,0x4034d75f),LL(0xc33e462b,0x89b85eda),LL(0x058de3bb,0x31f413c3),LL(0x6ba75391,0x66c01c80), LL(0x373e28de,0x3f500202),LL(0x4b9be739,0x5090b33b),LL(0xefa2addd,0x7297aa10),LL(0x1a6566aa,0x3e8ccdbe),LL(0xd7b4f214,0x4dfda07f),LL(0x7cb1cae7,0xa659bd1e), + LL(0x87d11691,0x31796c23),LL(0xa9de506c,0x02991ea2),LL(0x6cb0c301,0x4ff0cb71),LL(0xd1702ca9,0xdd0cdbd7),LL(0xe1a02a90,0x470a26c8),LL(0xd7054625,0xb705b7ba), LL(0xd4a1a268,0xfadc2e86),LL(0x68e9f923,0x0fd97646),LL(0x2951a8fe,0x042b5ebb),LL(0x64197a76,0xe4af9d03),LL(0x249c1b5d,0xdd2c6bb3),LL(0xf01932b1,0x60af89bd), + LL(0x41afcd64,0x4374145d),LL(0x49d21198,0x98b72d60),LL(0xdfde8a41,0xc0ff394b),LL(0xee1ff7a5,0xed1112e5),LL(0xcb5036fc,0x87a920e8),LL(0x2deb225e,0x437123f6), LL(0xb9ad8c58,0x37e527af),LL(0xabfaef38,0x3e3c9998),LL(0x50b2b4e2,0xb656bcc5),LL(0x3bf5699d,0xfacc8a19),LL(0xe616307a,0x98cec74f),LL(0xd3ef8bab,0x34af333d), + LL(0x744ec273,0x9ded9b0d),LL(0x2e79e4d5,0x5bdfe547),LL(0x39393728,0x94f3aaf5),LL(0xa438413e,0x22136862),LL(0x373c7de3,0x449286da),LL(0x29aa1540,0xa709d85d), LL(0x0284a4f6,0x1bd13e41),LL(0xf0799c8b,0x37b54d69),LL(0x6bcd0cb2,0xd43b558f),LL(0x9e610369,0xf5757c0e),LL(0xc16e0651,0x15c80b23),LL(0x001820aa,0xacb2cf64), + LL(0xeec37f48,0x0629e4dd),LL(0xda7de716,0x3f7556a2),LL(0x661662bc,0xcacd8f27),LL(0xeaf01690,0x65d8bc2c),LL(0x7c39c893,0x83ac6647),LL(0xf59440e1,0x353f60db), LL(0x852c575a,0x2597b0d6),LL(0x3a40c2b3,0x410885f7),LL(0x2fcc2488,0x953ab347),LL(0xef4cc6d8,0x9f753e5e),LL(0x97f69e63,0xfc32bb4d),LL(0x87e8c264,0x461c1b0c), + LL(0xac4b62f5,0x2bea7e75),LL(0xc6297871,0xcf255dcd),LL(0x81b25c72,0xdd88db87),LL(0xb617dc04,0x77ad90b3),LL(0x0ed4a7d6,0x65ee1382),LL(0xd9644c8f,0x4c08df9c), LL(0x525a023f,0x072d3784),LL(0xfce399fb,0x1aef69ce),LL(0xd7f29044,0xb07fd78e),LL(0x43043fa7,0xa3754e14),LL(0xff9fe4d9,0x97bdae92),LL(0x700fe6b8,0xad63ba6a), + LL(0xa1ca17db,0xa571929b),LL(0x45e146b8,0xce7a12f5),LL(0xd9eb426d,0x39df1446),LL(0xdc27f268,0x1e48b3f8),LL(0xff548455,0xa2d7dfa1),LL(0x6ef1cc82,0x750068b8), LL(0x667fce62,0x4d699306),LL(0x131c5412,0x98540b9d),LL(0x47c580b0,0xf8a62cd3),LL(0x73795005,0x2b55460f),LL(0x7b8db337,0x3206c025),LL(0xd0dda5a2,0x2280934b), + LL(0x2352478c,0x10a8aabd),LL(0x1364c40f,0x599d9dfa),LL(0x076945a2,0xa009df1a),LL(0x03861f02,0xf869152c),LL(0x9f866a3c,0xc405226e),LL(0x8b41ecbb,0x93bd737d), LL(0x33901eed,0xb5c9ed10),LL(0x99312b80,0x90e4ce8f),LL(0x57589279,0x1a9ef22e),LL(0x7fe2d6aa,0x83ef607d),LL(0x3473dbfa,0xf2da8454),LL(0x57879066,0x14f36d3a), + LL(0x0ea3ce34,0x2c780f22),LL(0x4b8aac72,0x240a211e),LL(0xc2625a99,0x7a266e5d),LL(0x3b30c878,0x1cb15d3e),LL(0x0e1b21d3,0x8cd8ccab),LL(0xadc1a6b3,0x53c64279), LL(0x60bf708d,0xe60d15b9),LL(0x0cb5ad4b,0x6e431c1b),LL(0x82033111,0xec874c3e),LL(0x9141eae5,0x88054a1d),LL(0xddf53a28,0x98438a5a),LL(0xfa12c657,0x168f0b0f), + LL(0x629d7a57,0xd621ce26),LL(0xcc1f8af1,0xbf571de7),LL(0x304adaa3,0x2c5cfaf9),LL(0x3f283b49,0x950addbd),LL(0xee6d1cd1,0x622dc27c),LL(0x1f0863fb,0x26d92004), LL(0xa41ec585,0xe243b2a2),LL(0x2bea6235,0x0dbd9adf),LL(0x6f0820f5,0xcb083c4d),LL(0xd5493931,0x809ecbaf),LL(0x14b7ffa8,0x96470674),LL(0x53fc2224,0x2cdfe22e), + LL(0x7cd74a06,0xc8b1333c),LL(0x271006bf,0x7d5ac4dc),LL(0xc14e0e56,0xe9377d9f),LL(0x7a92ab1f,0xaa8651db),LL(0x5fc11fb5,0x77cee814),LL(0x27870b14,0x1e7c5ca0), LL(0x6f959698,0xdeef4b3f),LL(0x5daa9bda,0x7c59f26e),LL(0xfd312368,0x4d0d5aec),LL(0xb738de68,0x5247a6f3),LL(0x90c04807,0x1c4e8ba9),LL(0xcce126ca,0x0554b41b), + LL(0xa81cc26a,0x3df98ea9),LL(0x83b2c6f3,0x982ed568),LL(0xea6d6976,0xc9cbd1b5),LL(0x7e25ffbc,0x3f9f2319),LL(0x7da6280e,0xbca8e056),LL(0x35cda713,0x7abd3166), LL(0x740ae011,0x46ef321d),LL(0xdb214a33,0xb17f6c75),LL(0x51de4044,0x37b73b4b),LL(0xccd9ba8d,0x5bccf3cc),LL(0xd0f7045b,0xa2ca080d),LL(0x68cf4dcc,0x79caf906), + LL(0xa7b07d22,0xcc3605a9),LL(0xb4ebe4e7,0x4370eb18),LL(0x248867c1,0xbe393039),LL(0xcb1a75ff,0xc8e4851e),LL(0x39cb6da4,0x215f3fbe),LL(0xe41f9a34,0x6f2102ee), LL(0xdfae7c27,0x61d484ab),LL(0x6f1260fc,0xf5143bd2),LL(0x7514bccc,0xa70b6c06),LL(0xd23506f5,0xe71ca833),LL(0xeae03a8e,0xe2f50ba8),LL(0x83c33359,0x2ac3b508), + LL(0x3655cabd,0xe94b930f),LL(0xa342443c,0x6ef6aac4),LL(0xbae255da,0x2feb8005),LL(0xac6e2095,0x4625a15c),LL(0x0ec76c1e,0x75c6311d),LL(0x9b81c6f2,0x896a0740), LL(0x073378bb,0xbad3e2f9),LL(0x29266ec0,0x2984a106),LL(0xa788010a,0xa68a5351),LL(0x017cd052,0x321aa113),LL(0x2f34db5c,0xecfb6175),LL(0xca2b51df,0xfe080ced), + LL(0x03360c88,0xba296908),LL(0x36311812,0x3fb087c0),LL(0xd9ff6a48,0xec5fb10a),LL(0x207dd8e1,0x52f7077f),LL(0x44c02fbc,0x8e65cfb8),LL(0xfbf4bfd5,0x4f4fcde2), LL(0x6cc74320,0xd1ff5415),LL(0xf68b036a,0xf989d544),LL(0x973bd9be,0xafedc2db),LL(0x4785e26a,0x7bdc3569),LL(0x751ae9ba,0x0df36796),LL(0xccdabd95,0xfebde691), + LL(0xc77488cc,0x3499b44b),LL(0xaa8f3c10,0xde000e01),LL(0xc1f517d7,0x30140406),LL(0x82a174e8,0xd4b3c8eb),LL(0xaf2c9b3a,0xc8835b13),LL(0x443716f4,0x2cd7626e), LL(0x9c22de71,0x336c4f4b),LL(0xf2529f60,0x9dd2b277),LL(0x828c34d3,0x6ffba2dc),LL(0x34d0d1f7,0x257a345c),LL(0x6ca4fbce,0xbc1eff05),LL(0x0768349f,0x05b33562), +}, +/* digit=15 base_pwr=2^75 */ +{ + LL(0x10fa53ce,0x5d7afe9a),LL(0x1ff49021,0xe2415b50),LL(0xc6523492,0xe39a067d),LL(0x27557f5d,0x34585275),LL(0x930e9f9d,0x756b8d86),LL(0x040d52d8,0x88df6219), LL(0x5362b045,0x606eb60b),LL(0x9e383cbe,0xd179818c),LL(0xe068d293,0xa6215748),LL(0x2fce158d,0x73fbdca2),LL(0xcb183c8f,0x9cfee07d),LL(0xa5e03c98,0xc0bf2beb), + LL(0xf14a99d9,0x86230934),LL(0x97c1c092,0x1cf9c66e),LL(0x6f595ed3,0x01e186ba),LL(0xe2284a58,0xd3291c3d),LL(0x1b9e5e25,0x03dee231),LL(0x15cc9f53,0xf2e9b4ad), LL(0x9770c29d,0x4fba1567),LL(0x50c4ae2f,0xbf7d6736),LL(0x2532d015,0x86901eb9),LL(0x4e7455de,0x4396fd78),LL(0xbcf811c9,0x2fbcea8f),LL(0xae952b37,0x3981ad15), + LL(0x4caea411,0x5563ba50),LL(0x59297ddc,0x6d06f7ff),LL(0xb2fb7a6e,0x244c00ac),LL(0x35df586e,0x25aac3d4),LL(0xd67be5f9,0x6c6777e4),LL(0x11c24c8a,0x476cbbf1), LL(0x83b496fc,0x60832359),LL(0x09a871a0,0xcc13c191),LL(0x56f78170,0x7c0e049f),LL(0x6eafe939,0x19bda64b),LL(0x09aa41e3,0x04381fb6),LL(0x0b8c4500,0xe4d4dcbb), + LL(0x4cb89afa,0x6bd2c54d),LL(0x36527751,0xe78c8bfa),LL(0xe3eee747,0x27f52654),LL(0x9598d907,0x56f20583),LL(0x27cb3712,0x5f91c2d0),LL(0xa3e33c5b,0xc501819f), LL(0x4eded738,0x248490aa),LL(0x27789065,0xde7ac944),LL(0x74f7d38b,0x20138b3d),LL(0x2fb60214,0xae791f60),LL(0xbd033d4e,0x6b4fb300),LL(0xbdfd1f17,0xc69c25d9), + LL(0x92717482,0x8a5cb7ae),LL(0xc49d53e9,0x3dc97730),LL(0x5302d584,0x07b1e2cc),LL(0x397b46cb,0x06617e8e),LL(0xe8e9f451,0x73426657),LL(0xdd517335,0x82dcb228), LL(0x5cad6d10,0x39cde297),LL(0x2e4b0ebd,0x76991f56),LL(0x5020cfc6,0xf3e3b3b2),LL(0xe51bbaca,0x35a63790),LL(0x4a23f2ec,0x47b21e6f),LL(0x620e0b06,0x964c6fb5), + LL(0xbe832a0c,0x9bd2b68d),LL(0xf1e49e28,0x0efa6b60),LL(0x89586da1,0x67e7f359),LL(0xfd0944ca,0xbc04c8aa),LL(0xf0569b5a,0xb8db5424),LL(0x0cc5546e,0xc27dd125), LL(0xad67b577,0x8f0ef9df),LL(0x9824cbc2,0x1b5d4068),LL(0x4e7329b8,0x2ec1eb64),LL(0xe6896b04,0x3e0e7f37),LL(0xc118b6bf,0xad2bff11),LL(0x40f93fa6,0xe17ec8dc), + LL(0x98692833,0xc7e68075),LL(0xe1257bf1,0x311dd043),LL(0xe6258442,0xd4356992),LL(0x05ddf6d2,0x7868deca),LL(0x95a0951b,0x61b3a961),LL(0x61c6fc20,0x0cda07bf), LL(0x2d061312,0xac9aa65d),LL(0xb65f1a23,0x4d9c4f20),LL(0xb06611a8,0x862e4927),LL(0x6cccfba0,0x0d1c906e),LL(0x6a49234c,0x0c82ac34),LL(0xaadbaea7,0x70f3c70b), + LL(0xbe21a890,0x0c3d2056),LL(0x8fcfba99,0x1c1ffbfb),LL(0x1fbf56ca,0x1b68a98b),LL(0x396e31cd,0x56fd85ff),LL(0x4382c03b,0xd2ca5844),LL(0x7d3ef917,0xc442030a), LL(0x426afafa,0x4129a731),LL(0x5eaae9c6,0xacff17ff),LL(0x653f3b23,0x9e854180),LL(0x9ee066bd,0xe65a1a14),LL(0x362ea5fe,0x3420084e),LL(0xc7911e2e,0x6fe58801), + LL(0x02a97a2b,0x4dd38c42),LL(0xfdb98b51,0x2a8d49c2),LL(0x5cb2e0ca,0x7034c753),LL(0xc4b59d32,0x87e0d6d3),LL(0x35514758,0x9544bb07),LL(0x4ff27eb0,0x9ed743da), LL(0xa0163883,0x1d21a1ad),LL(0x38c57492,0xd6442498),LL(0xf2fd1b7f,0xf46e8acc),LL(0xc8005cfe,0xec9932c5),LL(0xb802c109,0x5fe24f52),LL(0xe3ee9ba7,0x5539c03b), + LL(0x05a95afb,0x4c3f4f49),LL(0xf5db9d6b,0xd53a1d3a),LL(0x1844be86,0x0fbd9bad),LL(0x272afc14,0x6b3b80ee),LL(0xaa40a738,0xd727b0b6),LL(0x4d809a37,0x8a21bf45), LL(0x70767232,0x09fb0640),LL(0x45bf5d89,0xa671a2cc),LL(0xd73a211b,0xa7e5ff8a),LL(0xd9a6b97d,0xccdbf621),LL(0xc89e8f56,0x38448e2c),LL(0x2126da09,0x07e4e9c3), + LL(0x7adcc8b8,0x762e6584),LL(0x7924eafd,0xedef40a7),LL(0x5913e468,0xe1990688),LL(0x289bc581,0x1882db47),LL(0xe6084637,0x680cd99b),LL(0x1adacd71,0x5249f00e), LL(0x933bf6cb,0x0d3b583f),LL(0x9b02a63d,0x51c86774),LL(0x1dc57813,0x0be0ada7),LL(0x1e2c5f9f,0xd4b63964),LL(0x2c77c4e5,0x810b38b0),LL(0x862013cb,0x9f06b31d), + LL(0x6c4be6a0,0x43f0ae67),LL(0x504bffeb,0xabc6a17a),LL(0xdbb4492e,0xd5be6c25),LL(0x84bff97f,0x7efc9ee8),LL(0x062da2e2,0x54fbd9d7),LL(0xc6d2ac32,0x1befeb61), LL(0xcbafef5b,0x14cf6dc0),LL(0x71d12192,0x8e640e47),LL(0xd9a16800,0xd0566543),LL(0xbeb1e28d,0x9cc2ade9),LL(0x38e65833,0xcbfeb450),LL(0xd0f5acb2,0x3852eaac), + LL(0x3b5a25dc,0x8bbac220),LL(0x7deb0149,0x6e216404),LL(0x7ae10837,0x3d6eecea),LL(0xeb944203,0x2ab3cd3d),LL(0x5114d51a,0x8fdcb595),LL(0x92471196,0xfbf0f726), LL(0xb20cdb3f,0x6523ea38),LL(0x5796c8f8,0xc08ad84a),LL(0x71b564cb,0xd7977bc2),LL(0x5d66093e,0x16a9e700),LL(0x144cd814,0x67fb9a6f),LL(0xeecab0d4,0xbf2094bb), + LL(0x6c50f6a1,0x4f10299a),LL(0x69a1caf7,0xa51c6774),LL(0x0cbede41,0x024b18bc),LL(0x6b03ac7d,0x7883c01e),LL(0x1c5213be,0xa7b99e74),LL(0x85a97540,0x529fad7a), LL(0x03125409,0x0b6fe59d),LL(0x76275b90,0xf1581679),LL(0x6ad18919,0xcaa0969d),LL(0xee7761dc,0xc47afe13),LL(0xdfb12539,0xcae681fc),LL(0x02ea65f4,0x58dabc76), + LL(0x35a505bf,0x3f19ec08),LL(0xb0032e38,0x83186122),LL(0x2b3126ec,0xe5c2eac4),LL(0xf752524f,0x4368683f),LL(0x3ab28694,0x03de9cdd),LL(0x61d0253b,0xfc5e70df), LL(0x789a16d4,0x7991742a),LL(0x226ee928,0xefdb8003),LL(0xa4e62a4f,0x0468fe4c),LL(0xd07dd729,0x3ce92ccb),LL(0xfe688c1e,0x447bed93),LL(0xcae39d89,0xd5ff355d), + LL(0xc4650b85,0x5e930d65),LL(0x6350da54,0xbe96b2ae),LL(0xfa08bd49,0xcfac4f7e),LL(0xa6e10f64,0x277e8456),LL(0x407ac162,0x41be3067),LL(0x52a9b68b,0xcfd1d032), LL(0x9c337e0b,0x8d8d216a),LL(0x4e1b9cf5,0xace044dc),LL(0xc60d54c3,0xad9a4102),LL(0x28815187,0xb09420f0),LL(0x0b3b8e59,0x881179c6),LL(0x5b09aba1,0x872685ed), +}, +/* digit=16 base_pwr=2^80 */ +{ + LL(0x5852b59b,0x22313dee),LL(0xb6a0b37f,0x6f56c8e8),LL(0xa76ec380,0x43d6eeae),LL(0x0275ad36,0xa1655136),LL(0xdf095bda,0xe5c1b65a),LL(0x367c44b0,0xbd1ffa8d), LL(0x6b48af2b,0xe2b419c2),LL(0x3da194c8,0x57bbbd97),LL(0xa2baff05,0xb5fbe51f),LL(0x6269b5d0,0xa0594d70),LL(0x23e8d667,0x0b07b705),LL(0x63e016e7,0xae1976b5), + LL(0x236b71dc,0x022aa09d),LL(0xa65a7640,0xb1ce6a0e),LL(0xb38b417a,0x317344c5),LL(0x436451ec,0x29a74cdb),LL(0xa8b1c876,0xd898eb6c),LL(0xb74eeffd,0xf0134f99), LL(0x225d71f7,0x0d9eab64),LL(0xceb3cc2d,0x9679b453),LL(0x14dbff2f,0x37c894ce),LL(0x27065280,0x3704d349),LL(0xba29a0cd,0x9ee435d8),LL(0x09c11c4f,0x675bea14), + LL(0xfbecaaae,0x2fde4893),LL(0x30332229,0x444346de),LL(0x09456ed5,0x157b8a5b),LL(0x25797c6c,0x73606a79),LL(0x33c14c06,0xa9d0f47c),LL(0xfaf971ca,0x7bc8962c), LL(0x65909dfd,0x6e763c51),LL(0x14a9bf42,0x1bbbe41b),LL(0xc49e9efc,0xd95b7ecb),LL(0xb38f2b59,0x0c317927),LL(0xb3c397db,0x97912b53),LL(0x45c7abc7,0xcb3879aa), + LL(0x714a10e8,0x8b3269a2),LL(0xa4a2727e,0x64cef040),LL(0xe428865c,0xbc5ac714),LL(0xfdaba094,0x531dd17f),LL(0x18d657f2,0x86d24057),LL(0x2f99dbbf,0xe807b0d9), LL(0x6848ef88,0xc428a80f),LL(0xd0b73ce5,0xb3ef0709),LL(0x22a5d255,0xa7526919),LL(0x18a18586,0xbfe63923),LL(0xfcf633b3,0x28a0c772),LL(0x3f3c5298,0xad22b4ec), + LL(0x24359b81,0xcd81bdcf),LL(0xdb4c321c,0x6fd326e2),LL(0xf8ebe39c,0x4cb0228b),LL(0xb2cdd852,0x496a9dce),LL(0xd0e9b3af,0x0f115a1a),LL(0xd8eeef8a,0xaa08bf36), LL(0x06e5e739,0x5232a515),LL(0x8407a551,0x21fae9d5),LL(0x8994b4e8,0x289d18b0),LL(0x09097a52,0xb4e346a8),LL(0x324621d0,0xc641510f),LL(0x95a41ab8,0xc567fd4a), + LL(0x7176dd90,0xc8c9b0ae),LL(0x2917d487,0xa9560454),LL(0xe62c508e,0xb03b7946),LL(0xe9fe2321,0x60425926),LL(0x80c1d136,0x73b10bba),LL(0x9d218c9c,0xc30a847d), LL(0x2073859f,0x6ed0c8ef),LL(0x432dd97f,0xa176eabf),LL(0xb9e96167,0x3078096a),LL(0xc473e377,0xb28f0e6c),LL(0x683a3bc8,0xb44e4995),LL(0xd3523796,0x483512ee), + LL(0xd57c8de9,0x261578c7),LL(0x3836c5c8,0xb9bc491f),LL(0x14c8038f,0x993266b4),LL(0xfaa7cc39,0xbacad755),LL(0xd69b7e27,0x418c4def),LL(0xae751533,0x53fdc5cd), LL(0xc3eea63a,0x6f3bd329),LL(0xe53dd29e,0xa7a22091),LL(0xdc4c54ec,0xb7164f73),LL(0x44d3d74e,0xca66290d),LL(0x4c9ea511,0xf77c6242),LL(0x1f714c49,0x34337f55), + LL(0xfa43699c,0x93a62e7c),LL(0x1bc422d9,0xdad73890),LL(0x10cc9544,0x265e3cbb),LL(0x2f37154c,0x28cceb06),LL(0x3bf2e08b,0x6b79b071),LL(0x3ab39091,0x88e025df), LL(0x126522bd,0x50a8d04d),LL(0xb779bacf,0xeabbc1b7),LL(0xc21cc62e,0x3db4336a),LL(0x6fc00450,0x4747f0a3),LL(0x544b2d95,0x067cbf1c),LL(0xfd2be7a7,0x2480b7d8), + LL(0xa64b6c4b,0x5ed2b216),LL(0x3aae640d,0x1c38794f),LL(0x8905794f,0x30bbaee0),LL(0xc8699cfb,0x0d9ee41e),LL(0xcf7b7c29,0xaf38daf2),LL(0x43e53513,0x0d6a05ca), LL(0x2606ab56,0xbe96c644),LL(0xe9eb9734,0x13e7a072),LL(0x5ff50cd7,0xf9669445),LL(0x47da6f1d,0x68ef26b5),LL(0x23687cb7,0xf0028738),LL(0x6217c1ce,0x5ed9c876), + LL(0xb6ba9a0d,0x21965f08),LL(0x06cab532,0xa744f068),LL(0x5d4b9a92,0xd15d5fa4),LL(0x955ee1f4,0xc79fc89b),LL(0x7b2775f6,0x6367e8b2),LL(0xe2294382,0x2076cd8b), LL(0xc9089d2e,0xe5c20ced),LL(0xd76d6424,0xe6097605),LL(0x02b41ca6,0xa69f79eb),LL(0x63e07498,0x9738d39d),LL(0x92974776,0x35c14a6a),LL(0x7270fd02,0x3a000a51), + LL(0x0a3a9691,0x423ba513),LL(0xb3179296,0xf421b1e7),LL(0x1a871e1b,0x6b51bcdb),LL(0x464e4300,0x6e3bb5b5),LL(0xfc6c54cc,0x24171e2e),LL(0xd3e58dc2,0xa9dfa947), LL(0x9de9cfa7,0x175b3309),LL(0x2d1015da,0x707b2529),LL(0x993ea65a,0xcbb95f17),LL(0x0447450d,0x93515063),LL(0x1b2753c9,0x0f47b205),LL(0xe7d427cf,0x4a0bab14), + LL(0x58e996c5,0x2724c535),LL(0xd7453876,0x24010322),LL(0x74818d0b,0x3532b79c),LL(0xb27b07e9,0x1984146e),LL(0x471646df,0x948b0c4f),LL(0x32ef8e08,0x551b1c61), LL(0x25f892bb,0x22c08434),LL(0x4853c594,0x8fd873a8),LL(0xffdf802e,0xff0bdf02),LL(0x8239b779,0x527d6993),LL(0x27ace140,0xed66f25c),LL(0xa1a846a0,0x7389d738), + LL(0xb5aa7ca1,0xa39def39),LL(0xc47c33df,0x591cb173),LL(0x6bbab872,0xa09dac79),LL(0x7208ba2f,0x3ef9d7cf),LL(0x7a0a34fc,0x3cc18931),LL(0xbcc3380f,0xae31c62b), LL(0x0287c0b4,0xd72a6794),LL(0x68e334f1,0x3373382c),LL(0xbd20c6a6,0xd0310ca8),LL(0x42c033fd,0xa2734b87),LL(0x8dce4509,0xa5d390f1),LL(0x3e1afcb5,0xfc84e74b), + LL(0x12e471f2,0xd605097e),LL(0x2bb4aa64,0x8cff86ab),LL(0xea65a755,0x4a878412),LL(0x2f2b55fb,0xfa790b77),LL(0x5098a08f,0xd13fb9b3),LL(0xb359117d,0x39e474d7), LL(0xe8e5a3d5,0xc37499c1),LL(0xc7586167,0x5abf6859),LL(0x310fec8a,0x13143ba8),LL(0x75918fc2,0x3543979f),LL(0xcbb0bde9,0xf55a9b62),LL(0x29359b93,0xd6c1d000), + LL(0xf2cd8a9c,0xb028334d),LL(0x570f76f6,0xb8719291),LL(0x01065a2d,0x662a386e),LL(0x53d940ae,0xdf1634cb),LL(0x8f5b41f9,0x625a7b83),LL(0xee6aa1b4,0xa033e4fe), LL(0x1e42babb,0x51e9d463),LL(0x0d388468,0x660bc2e4),LL(0xfcbb114a,0x3f702189),LL(0xb414ca78,0x6b46fe35),LL(0x4a57316b,0x328f6cf2),LL(0x381ad156,0x917423b5), + LL(0xd52eb122,0x0233e423),LL(0x1154b0c9,0xc2848352),LL(0x6349e35b,0x2ca09cef),LL(0xded2ec54,0x3b70afc3),LL(0x52dded3d,0xc813474d),LL(0x12f00ee0,0x2d3f21bf), LL(0x92f215c6,0xa0908f76),LL(0x4e9c0440,0xb97d60e9),LL(0x34b6a8e0,0x84ad10c1),LL(0x6e7c163e,0x6f37fd95),LL(0xd057e0c3,0x7caae8c8),LL(0x553721a2,0x534f52c2), +}, +/* digit=17 base_pwr=2^85 */ +{ + LL(0x72a041b2,0xa354c1de),LL(0x29d1330a,0xe83df259),LL(0x9d532bbd,0x67661099),LL(0x52011751,0xb7c2f4cf),LL(0xf659e35e,0x6945d34f),LL(0xa1303b7b,0x6217d20b), LL(0x25751bad,0xa200ddba),LL(0x01d3566d,0xa74a7290),LL(0xaa82b46f,0x3018445f),LL(0xfccedc1b,0xc3e6a3ac),LL(0x3353e29f,0xe86ae870),LL(0xfd7e8547,0x1c8085bb), + LL(0xb4dcea78,0x306b63e3),LL(0x13636935,0x4b102092),LL(0x8bdeddea,0x36bb6889),LL(0x67a329ac,0x9331655d),LL(0xba92ccce,0x14c7fe26),LL(0xbe0519b4,0x4e7d6929), LL(0x164d50e2,0x0dc39dbd),LL(0xb1679cc5,0xd4c430a0),LL(0xfa8682ba,0xc7f78818),LL(0xb60aad97,0x43396ead),LL(0xff2c64cc,0x751784d7),LL(0x866af43e,0xd37928be), + LL(0x5a91c9aa,0xf0a69e68),LL(0x05c13197,0x0304d201),LL(0xcd14af1d,0x773a3ab7),LL(0x558d555d,0xc0b88edd),LL(0xd2e63dd6,0xeb12d197),LL(0xbcd9cdb3,0x4a8e849f), LL(0x965eaa14,0x06432985),LL(0x1a5a6f43,0x453d9386),LL(0x4171b9bc,0xbd28f616),LL(0xbbfcf90a,0x37781639),LL(0x3a36084d,0x1f93898f),LL(0xdd00ca75,0x1fefd8b7), + LL(0x2b2f1bcc,0xb9207dbc),LL(0xa3e83ef7,0x6afd6871),LL(0x34ba150b,0x49924e55),LL(0xdfec9972,0x2935ebf1),LL(0xb76f870d,0x34bf5e94),LL(0x4c20385c,0x22d0f32b), LL(0x8ccc8e72,0xc78ac172),LL(0x0ccecb0a,0x7b45b822),LL(0xcfb4b8ba,0x76c67ee4),LL(0xcd8724b6,0xecfaefb2),LL(0x340bc1ef,0xe9bc3d67),LL(0xca5541b5,0xed40b2b9), + LL(0x069e6432,0x9b8a3eb3),LL(0x721397f7,0x43aaa7fc),LL(0xa7e83a71,0x46e23c6c),LL(0x93fa3c25,0x71b261d5),LL(0x0f523a72,0x4a47a105),LL(0x8dcad752,0x31919e89), LL(0x0c5dd2ad,0x4c8b06e7),LL(0x8bdc55e7,0x677ec5f3),LL(0xcb1b5828,0x4372d55d),LL(0xf04dd321,0x7bf054c1),LL(0x2e44584e,0x4e8c1a99),LL(0x51d35d78,0x68078037), + LL(0x81d311b3,0x25ae3499),LL(0x3b16037b,0x8640f52a),LL(0x1d947065,0xac083994),LL(0xe2e693d2,0x3723c75e),LL(0xb66f429e,0x65040a51),LL(0x035a3a53,0x7f582b0b), LL(0x0a166da6,0x20eca9e1),LL(0x2c4cc565,0x45b37e20),LL(0x7a8a96e3,0xeab88295),LL(0xb60a1a1b,0x99e771da),LL(0x23b03965,0x2cdd778c),LL(0x91052478,0x8d4d7a72), + LL(0x7e8f73b5,0xa52d3c2d),LL(0x51842657,0x86d80633),LL(0xb3949eba,0x58f01253),LL(0xe79367d0,0x97689f15),LL(0x0d820328,0x918bf9a3),LL(0x41c959df,0x2d4bc994), LL(0x8c16ee54,0x37392f6e),LL(0xe6f0849b,0x9f726d58),LL(0xb8208f08,0x497de1e4),LL(0xd51a29b3,0x60c51233),LL(0xc9e1d465,0x0f61fb03),LL(0xfbe2613c,0x09494bd0), + LL(0x154d0f99,0x4f293478),LL(0xd07a24b3,0x1b82320d),LL(0x64d55f6f,0x1bf7c94f),LL(0x725c5125,0x4489b57d),LL(0xb1b6a091,0x3aa4d43a),LL(0xcf7a60fa,0x054842bd), LL(0x2aeb4cb6,0xaa918a4d),LL(0xac7d317b,0xcbdaff99),LL(0x6812a03c,0xed0e00a1),LL(0x0b0a1e4b,0xb09acf27),LL(0xac28386b,0xc73a41f7),LL(0xf4cd1321,0x43134dbd), + LL(0xd8c33924,0x08336ffe),LL(0x5140b253,0x15b56cbf),LL(0x306caedb,0x38dcd310),LL(0x47944afd,0x04ecd496),LL(0x68a48f95,0x1280d23f),LL(0x34363c6e,0xf4142204), LL(0xcaa8717f,0xd0a397ea),LL(0xc3994b80,0xb51a1669),LL(0x6c56808b,0xa02eed91),LL(0x83545c3c,0xc3ab55c5),LL(0xfd26114a,0x8b835820),LL(0xffff324c,0xe0cfa4a6), + LL(0x51c0d95e,0xcf63d279),LL(0xac86a014,0x3b170a0b),LL(0x881095e1,0xc21eaaa9),LL(0x6069a3eb,0xed2fda11),LL(0xbd2f1c5a,0x536264b9),LL(0xde312c2c,0x819e1cff), LL(0xdfd6ce38,0x6c30f983),LL(0x980b439e,0x2f32cc4c),LL(0x3b9c03b2,0x9fab10b6),LL(0x011ab74a,0xdfebe34e),LL(0xb80963f6,0x587360e3),LL(0x8692e352,0x3db1f610), + LL(0xfe3d070b,0x63a094c5),LL(0x88515eb1,0xf769b919),LL(0x50d1131d,0xafe86e14),LL(0x6774d3d4,0x6bf27788),LL(0xffd805d0,0x7231d699),LL(0x6304116e,0x05132e5b), LL(0xe34ce5bc,0x3d5e255b),LL(0xc95e3089,0xfd9c3bd0),LL(0xb83cbac9,0x22a24023),LL(0xb0b3b98a,0xfb6d2b6f),LL(0xf7e36fcd,0x74af1115),LL(0xf9da3bf0,0xcfe15eaf), + LL(0xbb2fcdae,0x266d2c1c),LL(0x52be93f2,0xb538d4a2),LL(0x73bd0094,0x774c88ba),LL(0x81a7e042,0x65283a9b),LL(0xd0381625,0xe1438bbf),LL(0x4d0db206,0x450e1f64), LL(0x4e60fc4a,0xb38ae9ef),LL(0x12719817,0x14ce87e1),LL(0x570303f0,0x831d41ec),LL(0x28850444,0x71729170),LL(0xccd609f5,0x2077ea32),LL(0xcd273fdc,0x091d1166), + LL(0x4b2ca517,0xdf216dd8),LL(0xc6b74c4d,0xb3eec4b9),LL(0x1c14e77b,0xf564e6c8),LL(0x2c2c9395,0xcde25f1c),LL(0x049fcc83,0x7e31f7a5),LL(0x9284c753,0x6913707b), LL(0x58e6eb5f,0xb92a6f24),LL(0x95148292,0x85b0cab5),LL(0x7449be92,0xeaad036d),LL(0xeb94a702,0x2f6a2888),LL(0x47d59fb0,0xd7d8773d),LL(0x03c0bf25,0x612d2573), + LL(0x84d2c3bb,0xb872a105),LL(0x39196026,0x44bca571),LL(0x4e352e5d,0x857327d8),LL(0xd925f99f,0xa6c6004a),LL(0xbab79ead,0x48aaf266),LL(0xadab2a3f,0x213ad923), LL(0xf371cc48,0x3be29b6d),LL(0x2385c9f4,0xe732b906),LL(0x23f0a84e,0x562e0be1),LL(0x28c4b0db,0xbb6b0172),LL(0xf4c6d8be,0x71a93ae5),LL(0x551f1fe9,0x76b8bb16), + LL(0xc39926a8,0xbbfaaa94),LL(0x60a138aa,0xb9a59fdb),LL(0x947e30e9,0x217a1aa2),LL(0xc52c9fff,0xcac988c9),LL(0x3bae3c39,0x5676473a),LL(0x857f04c9,0x7d84b353), LL(0xdd324e24,0xdeded30c),LL(0x9c242899,0xf07c678a),LL(0x8cb64f3b,0x956d0553),LL(0x502cb2b0,0x9d34e2f5),LL(0x51dd03b3,0x99e1054a),LL(0x4d60a593,0x86b8bfa5), + LL(0x754d15e9,0x10a53b90),LL(0x5f4c7218,0x6cde9a0c),LL(0xabef2b96,0x740d513f),LL(0xd3f802fd,0xff6cc47c),LL(0xeb0627af,0x1be6825b),LL(0x5886c2dc,0xdb21ede5), LL(0xf5daaed7,0xb6cfb2c6),LL(0xfae29a9c,0x68b61aa8),LL(0x3a5a485b,0x7a1e16f5),LL(0xe7b2223e,0x16b60b92),LL(0x36a13a9b,0x332f33d8),LL(0x876cd1a2,0x4567c313), +}, +/* digit=18 base_pwr=2^90 */ +{ + LL(0x4aea3fa2,0xa896d28e),LL(0x6db06ee9,0xc6137a45),LL(0x06fb15cc,0x1bbafe8c),LL(0x1cdffdad,0x2daab296),LL(0xe1119b3a,0x984defc8),LL(0xde2a25a3,0x9cd44c3c), LL(0x54ed6d73,0xa7f54ece),LL(0x50907054,0xd283017f),LL(0x6a3b9442,0x69130efc),LL(0x6785163b,0x5d17f127),LL(0x172b1d0a,0xc019911b),LL(0x7e3e093c,0xa19c745f), + LL(0xab83d932,0xe185bdc2),LL(0xd7c4e754,0x0a75845d),LL(0xc3fe5695,0x1f6f3397),LL(0x61f6a04f,0x6c9f3a5f),LL(0xb390a92b,0x3c0f9d4b),LL(0x4793b454,0x9e3336b7), LL(0x1472f06b,0x91ad0c34),LL(0x892cbdd7,0x4110047a),LL(0x65d53c83,0xfa24d905),LL(0x4176007d,0xd63e5833),LL(0x2cd1623c,0x741089fd),LL(0x2685d345,0x6b3d9202), + LL(0x3586c802,0x1ac37f31),LL(0xa9cb8662,0x70daca37),LL(0x8d9c7bf6,0x6e57d6a7),LL(0xe97eec9b,0x27069e2c),LL(0x4e877a82,0x16284ceb),LL(0x774f6288,0x30856e26), LL(0xfa33820f,0x88e53ea7),LL(0x715ced07,0xbfe3b89f),LL(0x743b11c6,0x6cf55589),LL(0x2edd201e,0x020f8a09),LL(0xb15c27e0,0xc80afc2c),LL(0xcc53751a,0x56557371), + LL(0xc9cb7f6d,0x1d510157),LL(0x46ab7372,0x532a0773),LL(0xc6dde9e2,0x2ea07e2f),LL(0x37d5bb1f,0xceed9ad9),LL(0x98cc6e28,0x3121994b),LL(0x67ad8fc4,0x67d2fbb5), LL(0xdc9f195d,0x34707fb3),LL(0x1fd5a013,0x6a601f48),LL(0x81ef6cb5,0xfe939b8d),LL(0x1223a9a1,0x5c51e8ab),LL(0xdb74cf37,0x8f6d7993),LL(0x972808e1,0x0b81c5b7), + LL(0xe26e1212,0xcc54c384),LL(0xfee6836b,0xf4c6a3cb),LL(0x91cccc5d,0x62589405),LL(0x135a7e68,0x5ed3f3ce),LL(0xe1994768,0x11cc139f),LL(0x77c07147,0x6386c5c4), LL(0x75fb9b2d,0x444230ae),LL(0x8029bfeb,0xa5972fd9),LL(0xdb5f8291,0x46e687ec),LL(0x0de6d5f7,0xf00bf689),LL(0x36af6be3,0xbf946c50),LL(0xd39dee1d,0xd6d9aaef), + LL(0x3bf921af,0xcb4e8512),LL(0x532e81d3,0x28fc6332),LL(0xf69f907d,0x682d8637),LL(0x5f759a16,0xbd9fa8f4),LL(0x51f03716,0x091ea9fa),LL(0x32c630e9,0xd685a141), LL(0x3d249cf4,0x7600c9ac),LL(0x002cd2b5,0x687e2022),LL(0x55334058,0x7ec205ab),LL(0x3ecf1368,0x9d0d86b1),LL(0xfc7baf6d,0xb3fc17a7),LL(0x361c91cd,0x57939961), + LL(0x37318b6d,0xeb74751b),LL(0x5abe7213,0xb967a3cf),LL(0x02ab79cc,0x80741539),LL(0xafbc3e08,0x11b647ae),LL(0x9e949616,0x3e34458e),LL(0x72591fad,0x6d714d62), LL(0x131b7659,0x813ba91c),LL(0xfd0e295e,0x7f836d36),LL(0xc5d7be99,0x192531f8),LL(0x901e480e,0xce83f561),LL(0xf1bba4dd,0x7b187da4),LL(0xf5c82a33,0x090754d0), + LL(0x010c0754,0x0db33228),LL(0x8eca7c59,0x10635ffa),LL(0x0e8a38fa,0x6efd8538),LL(0x769360d8,0xc1812ea5),LL(0x76f27ef5,0x505723dc),LL(0xf35af2e8,0xd0358e02), LL(0xd99419ee,0x9f7bb7fe),LL(0x430a0e2d,0x87c66e83),LL(0x773eaf7f,0x01187549),LL(0x89d51bda,0x05bbbba4),LL(0x640ccde6,0x52cabb06),LL(0xe7ff387d,0x0d5cb557), + LL(0x526f59f3,0xa338a9f7),LL(0x216004f8,0x9b866285),LL(0xeb6fcc58,0xe94cfd05),LL(0x2432ba24,0xc60b12ea),LL(0xef1227f5,0x3bb7acf1),LL(0x5ec503dd,0x176e0ef7), LL(0x236f9707,0x9c2337f7),LL(0xe029aa27,0xdc2b0f77),LL(0xa5f85372,0xb795424a),LL(0x1485af98,0x2eb6d54b),LL(0x7e3f46c7,0xd2ce87dd),LL(0x830f743c,0xc5eaf6ad), + LL(0x10e06f1a,0x709d61ca),LL(0x78eba75c,0xaa1e9fc5),LL(0x914b2cfc,0xf85d062f),LL(0x9089d85c,0xe73b3baf),LL(0xc4a284b9,0x4ac05fea),LL(0x3acb7268,0x92c78a43), LL(0xee45bb4d,0x7b5586f8),LL(0x6ac0a9e7,0xc39a0d0e),LL(0x4d6f9ab8,0xe4bbe3d5),LL(0x1fd46a08,0x1489463f),LL(0x29dba364,0x3ba31825),LL(0x8138511b,0x94f000d6), + LL(0xee9b6d83,0x9f8eafec),LL(0xf4eac676,0x069d5ad9),LL(0xb5687ebb,0xbf9ccc6e),LL(0x9d213f1d,0x5d0f44be),LL(0x0d0d6e70,0x372b5296),LL(0xf8bb90f3,0xef1466ef), LL(0x949789b2,0x2ec1daae),LL(0xb40be288,0x5c7d9b6d),LL(0xc351e87f,0x48319460),LL(0x5db0fde9,0xfeaa721c),LL(0xd16dc699,0xb33d58e9),LL(0x3ca8d3d6,0xe3f296f2), + LL(0xc39c1cef,0x70187dfb),LL(0x0c50c71e,0xa785216e),LL(0x6a6c0d60,0x30188b81),LL(0x6a27e97b,0xeaeda67d),LL(0x6ba389aa,0x4a519282),LL(0xa2bf1273,0xb96c7c7e), LL(0x267fe714,0x8ff10657),LL(0x996d91b7,0xdff4a271),LL(0x1dc7aed4,0xe34ba3e1),LL(0x38853d61,0xc457048b),LL(0x1ccbf658,0xe89825db),LL(0x6b255edd,0x68c7b455), + LL(0x49d38208,0x2f6f6a0f),LL(0x11ee2340,0x38fbcb5b),LL(0x865a4304,0x06e43b73),LL(0x06d728ad,0x08c696e6),LL(0x961c650b,0xdb82930d),LL(0xc20c5b68,0xf1de8cb5), LL(0xf8e1f9b9,0xd8e3cf7b),LL(0xf3a304ed,0xd6e081ab),LL(0xcd3cb8bb,0xf08d8624),LL(0xb26aa9cb,0xa3fe7742),LL(0x0de295f6,0xa3a9d220),LL(0xb9579b7f,0xfd465046), + LL(0x74871e18,0xdc14cb2a),LL(0xfcb8974a,0x017b1340),LL(0x6e93c20f,0xea5cb054),LL(0xa9e2ad1f,0xa7c078ad),LL(0xbeb26838,0xa37207d4),LL(0xde7ee8ee,0xcd8b3b25), LL(0x2801a7ff,0xdca6606a),LL(0x0f8af3fa,0xad2fedcf),LL(0x9b530c05,0xf27d30b4),LL(0x6b2a4613,0x071fc1c3),LL(0xb72cea9f,0x363aaa99),LL(0x3d350374,0x7a33ed8f), + LL(0xf2f3e9ea,0xac02833f),LL(0x956fb86e,0x43bcbde0),LL(0x95735c62,0xf888696b),LL(0xe7b2fd9e,0xefa03aae),LL(0xe75b2684,0x0e563e92),LL(0xd7f335bd,0xa49d2f31), LL(0x8ac31404,0x08664171),LL(0x07ccf31f,0x35866eab),LL(0x04122373,0x6bca6111),LL(0xcb21398b,0x730c92e5),LL(0xb93102d5,0x283791a8),LL(0x50dc1b38,0x4b41d94d), + LL(0xbb20fabf,0xc377b373),LL(0xf986b847,0x68d3aa52),LL(0xf39b6894,0xd9c2f2ad),LL(0xbd6da22e,0x1bbff106),LL(0x7e09678e,0x3f7e5b8e),LL(0x7ed3ee78,0xad6a8789), LL(0xaf9807b9,0x689e6b31),LL(0xbd1f6ef2,0xeca87778),LL(0xdda78c54,0x17d3277e),LL(0xefb65cb7,0xe686cacc),LL(0x19a30f0c,0x758aa1ab),LL(0xb11f071e,0xb40df97f), +}, +/* digit=19 base_pwr=2^95 */ +{ + LL(0x953b9223,0x16f3708b),LL(0x770e7cf3,0x0d3780f8),LL(0x27bb71a8,0x97a615b2),LL(0x162f8b55,0xa8b9a864),LL(0xd91e3fb9,0x80ee8362),LL(0xf83a4ff6,0xb2009a09), LL(0xc1696281,0x07a7873a),LL(0x23095ddc,0x17ff00c2),LL(0x860d60ba,0x427f683d),LL(0x1f87d32a,0xea995927),LL(0xa050319d,0xb2ac69fa),LL(0xd2d0b9ce,0x30c362b9), + LL(0xf26feef9,0x24480c57),LL(0x3a0e1240,0xc31a2694),LL(0x273e2bc7,0x735002c3),LL(0x3ef1ed4c,0x8c42e9c5),LL(0x7f4948e8,0x028babf6),LL(0x8a978632,0x6a502f43), LL(0xb74536fe,0xf5f13a46),LL(0xd8a9f0eb,0x1d218bab),LL(0x37232768,0x30f36bcc),LL(0x576e8c18,0xc5317b31),LL(0x9bbcb766,0xef1d57a6),LL(0xb3e3d4dc,0x917c4930), + LL(0xaae4bfd4,0xff41d51f),LL(0x17c44fac,0xcf50b141),LL(0x657a1ea4,0x078b808e),LL(0x93c00c55,0xc5aac1a8),LL(0xcc4d1c0f,0xcb99cfd0),LL(0x3fa123a6,0x1d104893), LL(0x023ca92f,0x49646059),LL(0xf3982134,0x5833e326),LL(0xc5781cdd,0x2e0d4bc9),LL(0x8d5e75f5,0x5f7f84ed),LL(0xe1e8a383,0xb6655f1f),LL(0x296e4943,0xcc18514c), + LL(0xb475d8f3,0x53ebbaae),LL(0xff76beda,0x3d6ea31c),LL(0x340986b4,0x3c15f25d),LL(0x3365312a,0xc5925d2e),LL(0x51641f96,0xc35d3ee2),LL(0x984128e4,0x11eb2f75), LL(0x3d04bc99,0xb41a21a8),LL(0x6436c3d0,0xf2d28600),LL(0xfaf5663c,0x4ffcf4c0),LL(0x0a62c9dc,0x889d285a),LL(0xcb2d60c5,0x0908665a),LL(0x0a131be5,0xe2f19c59), + LL(0xb1e46617,0xa93a7dbc),LL(0xd77195a7,0xd0ad4a47),LL(0xe5948165,0x020d8467),LL(0x25267b60,0xa3375bd9),LL(0x8c44e226,0x8cf54ab2),LL(0xf2bf5bfe,0xc4f7f467), LL(0xc414077a,0xde336f92),LL(0xc92d7219,0x92656952),LL(0xc09ee1d9,0x31645a70),LL(0x292630eb,0x8cfe567d),LL(0x7c16c0a8,0xb835edb9),LL(0x48dee1be,0x8ac88e9c), + LL(0x22319bfb,0x318feb4c),LL(0xa1ee9625,0xfd0a1331),LL(0x5b238661,0x1e4a786d),LL(0xa722c591,0x88e04305),LL(0xf406cb01,0x38eb062a),LL(0xe7216364,0x21caa381), LL(0xf0e1f665,0x450c1d29),LL(0x207a1320,0x369af7bf),LL(0x6f6c0680,0xfe46a53a),LL(0x25eac032,0x4553199a),LL(0xffc49722,0x41fa659a),LL(0xbbcb7a29,0xfb9e0c73), + LL(0x7e09207e,0xca53bd85),LL(0xfa171b01,0xa304cf7d),LL(0x881beffa,0xa93499d7),LL(0x95cf1295,0xc0b04ee5),LL(0x90cd1e30,0xe0cf548e),LL(0x821b4efc,0xfa82436e), LL(0x979ab01d,0xbb4d7958),LL(0xd48ca82b,0x4a1c815b),LL(0x627640fd,0xbacf6a1b),LL(0xabd9a758,0x31150946),LL(0x906bea56,0x2c9d7d14),LL(0x17e06ed1,0xd2450bcf), + LL(0x091354ff,0xc0de60f5),LL(0xa1bd1975,0xd7cc38bb),LL(0xe734e2df,0xf4122aa8),LL(0xef773db6,0x08f40f63),LL(0xce2d71c5,0x0a7e9484),LL(0x78a3f825,0xcc791733), LL(0xb47beec9,0x0cac7a5b),LL(0xa3f7b5b6,0x1cbea0e4),LL(0xd3e18145,0xecf19a90),LL(0x0aadf689,0x0d1b062a),LL(0xf3f0acf7,0x42299f1f),LL(0x5ac252b9,0x63a64539), + LL(0x8db83d7d,0xfda26247),LL(0x2ad24ac5,0x3a2d1c29),LL(0xa01d0daa,0x586b6219),LL(0x949dbc96,0xa92f773b),LL(0x5dc355d0,0x89c9668d),LL(0xb5e40672,0x0aaeecdf), LL(0x2c701014,0x5945a47f),LL(0xc5590e89,0x50e4a494),LL(0x7fd21edd,0x307cbd9f),LL(0xb85543b7,0x96005378),LL(0xba214861,0x9f87fddf),LL(0xf9d9d2c7,0xcdd615c5), + LL(0x5bd11a42,0xa4bfe151),LL(0x0ea6729b,0x38920da2),LL(0xa0ee708f,0x41e28260),LL(0xabc9d5f5,0xff4fdff4),LL(0xffaae99e,0x6ed92241),LL(0xc04fe4d9,0x6075ce0d), LL(0x5db066f5,0xf10a173e),LL(0xe75ef129,0xa2edee12),LL(0x8ed02e85,0xd2a0823f),LL(0x2e522dc1,0xffa78cf4),LL(0x00c939fd,0x07041e46),LL(0x3a9a8bba,0x3369357f), + LL(0x1a4e68b1,0x3b202533),LL(0xf7504686,0xa2ead2d7),LL(0xa569cb36,0xb0bb1808),LL(0xc015c68f,0x953f539c),LL(0x9a6fefe1,0x45c876dc),LL(0xbede60ec,0xe87ce8ac), LL(0xf3c69642,0xecfc84dd),LL(0x3a90826b,0xabe549ed),LL(0x57cca429,0x03a29df4),LL(0xb8e72b83,0x08d4e9a1),LL(0x79e7ef57,0x88d9c51b),LL(0xdc075e38,0x48102f0e), + LL(0xba264fa8,0xa1fc20f7),LL(0x4105e64a,0x0f625415),LL(0x8e2e8e16,0x2e5581c2),LL(0x4c456234,0x912c80fa),LL(0xe9e31ad4,0x7fd61fb9),LL(0x1c19e811,0xa5de4e7d), LL(0x2961b64d,0x6a7ab2cc),LL(0x5bb2da03,0xbf06db25),LL(0xab06af4d,0x33f76a85),LL(0x4866378d,0xda387e54),LL(0x56826f8c,0xbb71deb8),LL(0xeb64ecb6,0xbbe3ce38), + LL(0xbb63bdd0,0x2a6f3d84),LL(0xc2792d41,0x8b5becec),LL(0xec9fa26b,0xb0412202),LL(0xbc706607,0xbdaad566),LL(0xd8d361d4,0xd34e3ef1),LL(0xeb3c3f14,0xb4fe020e), LL(0x82656dd4,0xc6bac95d),LL(0x88ffb328,0x8cf56ba0),LL(0xdc84969a,0x33f04dda),LL(0xa5f1d0eb,0x642d93d6),LL(0x93ce88dd,0x122e35f6),LL(0x02c0e82a,0xbcffc369), + LL(0xfd5d084c,0x0e935934),LL(0x9121a6e0,0x7cd4992a),LL(0x8e15d863,0xab773dba),LL(0xcab64644,0x9cea4a51),LL(0x2efff061,0x516754d7),LL(0xcd3a36a4,0xd8af89da), LL(0x4615774e,0xc7d352ac),LL(0x21ae0d27,0xd1bb914b),LL(0x9199938e,0x8a8aed97),LL(0xcd6f3495,0xeb06789a),LL(0x775f93ee,0xc51d7766),LL(0x0a8af851,0x7eb6909f), + LL(0x6a82fd92,0xf6708309),LL(0xfffaccf2,0x08652b2b),LL(0xf0da4c5c,0x8ac0e67b),LL(0xb0fabc5d,0x26c5a4be),LL(0xb1dcad44,0x3e5ad350),LL(0x3aa30664,0xb539e10e), LL(0xa41fef81,0x266f4163),LL(0x78ef116f,0x860401ec),LL(0x3563575b,0xb0fc5cc3),LL(0xd4c9e03a,0xc28a5cb5),LL(0xcc9bbe6c,0x93399eff),LL(0x9c9a84a2,0x50a48cb2), + LL(0x5c1d4586,0x44bfd166),LL(0x8d1d86d6,0x46434e19),LL(0xc3936683,0xe50fcf81),LL(0x8b08680f,0xc9b4eb06),LL(0x2832aab0,0xf90882c5),LL(0xecbf5dda,0x42823cef), LL(0x44ae08f0,0xfd4d51c7),LL(0xbbd21c1c,0xb54a08f1),LL(0xfb187c34,0xb72953db),LL(0xf8ed037f,0x166f7f26),LL(0x097bad45,0xd2b1077a),LL(0x790dd808,0x47794cdc), +}, +/* digit=20 base_pwr=2^100 */ +{ + LL(0xd1d1b007,0xa05c751c),LL(0x0213e478,0x016c213b),LL(0xf4c98fee,0x9c56e26c),LL(0xe7b3a7c7,0x6084f8b9),LL(0xdecc1646,0xa0b042f6),LL(0xfbf3a0bc,0x4a6f3c1a), LL(0x51c9f909,0x94524c2c),LL(0x3a6d3748,0xf3b3ad40),LL(0x7ce1f9f5,0x18792d6e),LL(0xfc0c34fa,0x8ebc2fd7),LL(0x780a1693,0x032a9f41),LL(0x56a60019,0x34f9801e), + LL(0x62c36887,0xa4b957d2),LL(0xfc24cff8,0xaf15a485),LL(0xa271d9e0,0x11575e80),LL(0x4b9367e5,0x0fff68d4),LL(0x2279779f,0xf55ba673),LL(0xd4d68f68,0x9d72cca6), LL(0x590ffe4c,0x01474ab1),LL(0x074d634b,0xd20f44e1),LL(0x36111d25,0x63903a83),LL(0xab531cef,0x37342a5f),LL(0x702ed867,0xd3c93fe7),LL(0x6279f7e1,0x05d14369), + LL(0xf0db3751,0xb398290c),LL(0xba42c976,0x01170580),LL(0x56560b89,0x3e71aa29),LL(0x50e6647b,0x80817aac),LL(0xa0be42da,0x35c833ad),LL(0xf1baba4e,0xfa3c6148), LL(0xcd8f6253,0xc57be645),LL(0xc657ad0d,0x77cee46b),LL(0x0defd908,0x83007731),LL(0x899cba56,0x92fe9bce),LL(0xbceffb5a,0x48450ec4),LL(0xf2f5f4bf,0xe615148d), + LL(0xcbaf4685,0xdccf68bc),LL(0x270a2bcc,0xb333e464),LL(0x254dd3e3,0xe43ae199),LL(0xddce5c84,0xe8526e26),LL(0xea0b4258,0x52bad815),LL(0x094574c4,0x67c12c1b), LL(0x861545b7,0xa5362fcb),LL(0xc2b2eb62,0x3e904c35),LL(0xeeffc2cd,0x0f9312b5),LL(0x14de4e5b,0x5475657b),LL(0xf0233fa5,0x746e67d4),LL(0x35471ec2,0xb5157d7f), + LL(0x90b86166,0xf55edabb),LL(0x075430a2,0x27f7d784),LL(0x9bf17161,0xf53e822b),LL(0xafe808dc,0x4a5b3b93),LL(0xd7272f55,0x590bbbde),LL(0xeaea79a1,0x233d63fa), LL(0xfe1eba07,0xd7042bea),LL(0x10750d7e,0xd2b9aea0),LL(0x31078aa5,0xd8d1e690),LL(0x7e37bc8b,0x9e837f18),LL(0x85008975,0x9558ff4f),LL(0x421fe867,0x93edb837), + LL(0x1f23a0d8,0x3503d937),LL(0xc321dde0,0x64c598a8),LL(0x5b52e0f0,0x67f101ef),LL(0xf955b5fa,0xb6b5b4c2),LL(0x880e0569,0xb5f03d53),LL(0xc99393ef,0x121c3ac1), LL(0x57330666,0x90755bd6),LL(0xd4d71d3d,0x70ae5793),LL(0x9e9ce792,0x326ffd51),LL(0x96ccfa14,0x1b772d73),LL(0x874a22de,0x652710f4),LL(0xdb210342,0x72768469), + LL(0x83d55b5a,0xaa6489df),LL(0x86bf27f7,0xea092e49),LL(0x5fa2efec,0x4d8943a9),LL(0x720e1a8c,0xc9baae53),LL(0x95a4f8a3,0xc055444b),LL(0xa7c1206b,0x93bd01e8), LL(0x714a27df,0xd97765b6),LL(0x193f1b16,0xd622d954),LL(0xf1503b15,0x115cc35a),LL(0xa9fa21f8,0x1dd5359f),LL(0x6dfed1f1,0x197c3299),LL(0xf77f2679,0xdee8b7c9), + LL(0x171c1439,0x58d6998e),LL(0x01feedec,0xfd4a98f4),LL(0x65739fce,0x420b2a01),LL(0x22f7a073,0x5c5db308),LL(0x05042f00,0x016c5478),LL(0xa12413d9,0x5fc73ce2), LL(0xe932aa17,0x8ceb2d70),LL(0x0537afaf,0xb4d66b67),LL(0x339c146b,0x2638d012),LL(0x28ac0555,0x02fbb7b6),LL(0x62d46e63,0x7fcb0c81),LL(0x066d088e,0xeaa9ff4f), + LL(0x394fd855,0x5405179f),LL(0x49fdfb33,0xc9d6e244),LL(0xbd903393,0x70ebcab4),LL(0xa2c56780,0x0d3a3899),LL(0x683d1a0a,0x012c7256),LL(0x80a48f3b,0xc688fc88), LL(0x6f7df527,0x18095754),LL(0x71315d16,0x9e339b4b),LL(0xa956bb12,0x90560c28),LL(0xd42eee8d,0x2becea60),LL(0x50632653,0x82aeb9a7),LL(0xdfa5cd6a,0xed34353e), + LL(0x2d189057,0x8273db99),LL(0xe1b5f8cc,0x4d1b05fc),LL(0x0a7c32d1,0x5fec7c83),LL(0xea9b4d45,0x28ddaf28),LL(0xa2fc58be,0xb6bb62ac),LL(0x4a41852d,0xfc65b7aa), LL(0x1c9e6045,0x6e765194),LL(0xfc116257,0x3acabf28),LL(0x4b5a4ba8,0xc9d5e805),LL(0xcbdcf1eb,0x9a072259),LL(0x439fc8fc,0xc67cf643),LL(0xb4333aa8,0x917ef6f8), + LL(0x91aecce4,0x82154d2c),LL(0x5041887f,0x312c6070),LL(0xfb9fbd71,0xecf589f3),LL(0xb524bde4,0x67660a7d),LL(0x724acf23,0xe99b029d),LL(0x6d1cd891,0xdf06e4af), LL(0x80ee304d,0x07806cb5),LL(0x7443a8f8,0x0c70bb9f),LL(0x08b0830a,0x01ec3414),LL(0x5a81510b,0xfd7b63c3),LL(0x453b5f93,0xe90a0a39),LL(0x9bc71725,0xab700f8f), + LL(0xfc37efed,0x311ebba2),LL(0x60cfd6bc,0x8a6a42d6),LL(0xf2a4871e,0xb4051b3a),LL(0xc2f0ebf0,0x66ce77b8),LL(0x0ad28477,0x84abc948),LL(0x63d9d11a,0xc82e5c62), LL(0x007dcf93,0x99ffc70c),LL(0xd964c822,0x5e974edf),LL(0x513085e3,0x0fee3572),LL(0x46ce8444,0xbe67a880),LL(0x06d17129,0x136ceeb8),LL(0x662d86fd,0x0da512ae), + LL(0xb9f00793,0x9401aec2),LL(0xb997f0bf,0x064ec4f4),LL(0x849240c8,0xdc0cc1fd),LL(0xb6e92d72,0x39a75f37),LL(0x0224a4ab,0xaa43ca5d),LL(0x54614c47,0x9c4d6325), LL(0xc6709da3,0x1767366f),LL(0x23479232,0xa6b482d1),LL(0x84d63e85,0x54dc6ddc),LL(0xc99d3b9e,0x0accb5ad),LL(0xe8aa3abf,0x211716bb),LL(0x69ec6406,0xd0fe25ad), + LL(0x57e0105d,0xe7acaa84),LL(0x3851fd57,0x3c06d3bd),LL(0x2a9c631b,0x23cf3c61),LL(0x33863bf8,0x13888aaa),LL(0x717783ee,0xf2396355),LL(0x36b300e1,0xf21e1a48), LL(0x9d27b4cb,0xa734cb3b),LL(0x796e34b6,0x0a7effed),LL(0x3615cc7a,0xfc586477),LL(0x88844a21,0x1f98ed77),LL(0x7ad4c7bd,0xd6e28940),LL(0xe9331c7e,0xa00d64eb), + LL(0xdf85c705,0x0d5c1769),LL(0xa409dcd1,0x7086c93d),LL(0x0e8d75d8,0x9710839d),LL(0xebdd4177,0x17b7db75),LL(0xf649a809,0xaf69eb58),LL(0x8a84e220,0x6ef19ea2), LL(0x65c278b2,0x36eb5c66),LL(0x81ea9d65,0xd2a15128),LL(0x769300ad,0x4fcba840),LL(0xc8e536e5,0xc2052ccd),LL(0xac263b8f,0x9caee014),LL(0xf9239663,0x56f7ed7a), + LL(0x713b8541,0x17e3d0b8),LL(0xc6b5e839,0xf372b048),LL(0xd0bb1848,0xf8ef0261),LL(0xc71a3bbe,0x9b804cee),LL(0x542a88ae,0x00b7d171),LL(0xe9097b9e,0xf2b8ed10), LL(0x2c0a009a,0xdbad9f12),LL(0x205fb1bf,0x245fc1e9),LL(0xb83debf5,0xa8a4834f),LL(0x637e449b,0xc3ee226d),LL(0xcab82664,0xe3070d93),LL(0xb37320e8,0x24b8094d), +}, +/* digit=21 base_pwr=2^105 */ +{ + LL(0x25059699,0xb506b7b9),LL(0x01ab02e5,0x349fd83f),LL(0x3789281e,0x64b729ad),LL(0xf9af4561,0x69ae8f81),LL(0x56f91860,0x007befe1),LL(0xedc250fb,0xb578c566), LL(0x67ae4801,0x1c16d75a),LL(0xa1d3f592,0x04c35a7e),LL(0x36881f89,0x5dc97da9),LL(0x03a5b1ea,0xaddb6031),LL(0x3e153a0f,0x7eb515b1),LL(0x2b4a1ee2,0xdc3a9219), + LL(0x512cc92a,0xe7365f9e),LL(0x5172a654,0x9efdcf8b),LL(0x8e611fc3,0xbfb389ac),LL(0x699c227d,0xce778fd5),LL(0x3ff2ef17,0xdc1f47b6),LL(0x02672ed4,0x2ae0f683), LL(0xa8e879cb,0x51c63806),LL(0x3909f526,0xd3dfecf0),LL(0xe00e12a2,0x375b3d13),LL(0xbf8df325,0x91f9f750),LL(0x1df5f21a,0xf1ea0e42),LL(0x32c60584,0xaed73e7f), + LL(0xe0728e6d,0x03b07fb5),LL(0x1012234e,0x9e046920),LL(0x35637644,0x272e6449),LL(0xa55bcadf,0x2b6ad1c2),LL(0x5c71c6af,0x86c52776),LL(0xc1678806,0xa25bd60b), LL(0x76bb32f8,0x0cae8294),LL(0x33e03cb2,0x389ce4e6),LL(0x7513dfb6,0x504df833),LL(0x1b351dda,0x4260ee8e),LL(0xdbaf7cd0,0xa473c5d9),LL(0x71e390fd,0x22cb7cb4), + LL(0x26caebd8,0x1d9aa9fa),LL(0x26b7a673,0x6b646869),LL(0x7f167b47,0x7ebed6a1),LL(0x5bd9153d,0x324c13f8),LL(0x4c682ba6,0xe9ea5b73),LL(0x7e3ff6e2,0x2961da7d), LL(0x01a83dad,0x1ed2b050),LL(0xc4a2f60a,0xb232951d),LL(0xd68b8ec6,0xafcea5d3),LL(0x1c6ce0d2,0x21dc058d),LL(0xe719410c,0x0043de75),LL(0xe15cf534,0x4edd792c), + LL(0x3babe09e,0x0f45245f),LL(0xa9f2fac5,0x0959326f),LL(0x5cc136e5,0x7629e7fb),LL(0xe48b7eb0,0x208bd5a6),LL(0xb75a85cb,0x637891d6),LL(0x9f27b57e,0xf0ad9d8d), LL(0xe0454b05,0x437b6944),LL(0x02ed3592,0x022c51d7),LL(0x0dc0a769,0x0f79e2bd),LL(0xd9b81f9b,0x54ace1fd),LL(0xf95ea8dc,0x38611d66),LL(0xf0e6147b,0x52443ca8), + LL(0x8bc272d0,0x857d6855),LL(0xb5be2485,0x4583eeee),LL(0xfe0152ec,0xb83586da),LL(0xe830294a,0x8b0eb223),LL(0xa5b0e880,0x757582b6),LL(0x9cca7fff,0x5140c016), LL(0xe9228f12,0x07a00782),LL(0xd4973080,0xb96e2b5d),LL(0xe88efbe6,0x3cceb9a6),LL(0x73fcdd25,0x9955b630),LL(0x2805d470,0x04f26ab0),LL(0x424da086,0x90b38299), + LL(0xf4f6c5b4,0x73f1ae48),LL(0x4a477f01,0xee5af13d),LL(0xddb93d52,0x274614a2),LL(0xc320aaf5,0x90b0c563),LL(0xef990b0b,0xee2303c8),LL(0x3061f140,0x00d028e7), LL(0xcb3d8eaf,0xff705011),LL(0x62594f4c,0xae1d9908),LL(0xdafea438,0x22a27cec),LL(0xc5962ea9,0xa78e12d5),LL(0x8e65f9cf,0x5bbe9d87),LL(0xf47cefa6,0xa222580c), + LL(0x959abb9e,0xf7aaa732),LL(0x2ebf80b9,0x1222ad0a),LL(0x2e0c286e,0xa1a41737),LL(0x5da3472d,0x3b668502),LL(0x7576f2a2,0xbc0d116b),LL(0xa36a27d4,0xfdbcad95), LL(0x9d54f7ee,0xcdb3f474),LL(0x8a5643a3,0xe2e0f5f9),LL(0x69d4f171,0xc70d11b9),LL(0x6cca4ef7,0xdf96d136),LL(0x2fc6afdf,0x570693db),LL(0x567504da,0x5059e67b), + LL(0x7fe632a2,0x2c8107d4),LL(0xede7bff8,0xfc46c745),LL(0x4650025b,0x2d3b1286),LL(0xe74cd65f,0x815ef3cb),LL(0xa256f01c,0x5431b01b),LL(0x39915cfa,0xe832ff11), LL(0x07d7af84,0x2c106de6),LL(0x6d4753e7,0x67303b78),LL(0x6d75c8de,0x5f886ffa),LL(0x967131cf,0x932a6c20),LL(0x70aebbb0,0x5bc94a91),LL(0xfd56e06d,0xa85b3044), + LL(0xe7eba799,0xc904558a),LL(0xb2fa7331,0x46b6031b),LL(0x0653675c,0x6620e2b5),LL(0x7d2218f7,0xd1373a35),LL(0xaf55a5e7,0x0f4b3ca3),LL(0x714e70c2,0x50774160), LL(0x69188455,0xacc63d14),LL(0x043b8b30,0x89a795fe),LL(0xe1e4b9cf,0xac2fd66c),LL(0x1bf67f26,0xac792702),LL(0x1143d437,0xb9513f0d),LL(0x811f2931,0x02198050), + LL(0x7b480776,0x6d4acdba),LL(0x66dffeb5,0x8b518cd4),LL(0x51918859,0x8826c994),LL(0x38fad835,0xd2b6a7a0),LL(0x6929a870,0xd315417a),LL(0xc5a769e1,0x05d85252), LL(0xec0d091e,0x2fa06335),LL(0x87768c88,0xb0cc3372),LL(0x58a2eb9d,0xacbda5ba),LL(0x76b7b057,0x2a404fc9),LL(0x838c6135,0x073abb71),LL(0x5cfc4f3c,0xbdf89b13), + LL(0x3508675f,0xd00eb9c5),LL(0xa117dc95,0x92ec76a4),LL(0x334ca15c,0xf58d6f85),LL(0x9cee0544,0xeeb52216),LL(0xf21457c2,0x3eb9847f),LL(0x5524c60d,0x547908bc), LL(0x5198709b,0xb5b49d22),LL(0x324abc67,0x718abce6),LL(0x4abd54ba,0xdab8ff2f),LL(0x7184d444,0x98be59e6),LL(0xbabeb4b0,0x45b74b54),LL(0xff71a5ac,0xd8d8bb30), + LL(0x8ec13e6f,0x8aedf7e2),LL(0xd950792d,0x8b952620),LL(0x04918f59,0x36e9dac2),LL(0xd3dd47ed,0x5e49a5a2),LL(0xe863c2bd,0xb17455be),LL(0x326a0d66,0x8caac6a9), LL(0x27bb72e1,0xb6c3f5e4),LL(0xee5fe09b,0x17566c9d),LL(0x5e3db64d,0xfd6bbcc2),LL(0x3189319c,0xd437d07a),LL(0xcd3166a5,0xad00dfc4),LL(0x0bd63003,0xab75927b), + LL(0xafc43be8,0xa7672a39),LL(0xc72f97aa,0xefc49015),LL(0x0e48f2ed,0x81c63c05),LL(0x833a22cc,0x62f39f32),LL(0x72c0c0c4,0xf7a34801),LL(0xa4158538,0x4711cd41), LL(0x1d15f2f3,0xa3c99a4d),LL(0x7bee1b47,0x4b82c1c1),LL(0x9d199f10,0xc7d60b48),LL(0x5f16fa95,0xd1d1f03d),LL(0x32fbeaf2,0x96c780c9),LL(0x376ff106,0x0662e250), + LL(0x78571c8f,0x728e3346),LL(0x6cb339d3,0xd0a886b5),LL(0x0a5671ba,0xf4ea3338),LL(0xa64850a4,0x43823401),LL(0x33117b9d,0xa7729cd5),LL(0x2b78cffb,0x4dd45760), LL(0x5a67d812,0xbe057111),LL(0x5105a3fc,0x7ec6cf92),LL(0x0ccafeec,0x5dbcb4bc),LL(0x803092f8,0xa7587f15),LL(0xa884efad,0x67ee61d5),LL(0xca47d9ca,0xd4ced554), + LL(0x3b03dcbc,0x02c6b608),LL(0x3b9d868a,0x2b20149e),LL(0x4f57eb0c,0xaf5ab01d),LL(0xd750e515,0x59935b94),LL(0x8f89ad68,0x32721b40),LL(0xa7e3ceff,0x673bd755), LL(0xef3b3393,0xbd462fd8),LL(0x0e59a120,0x99142264),LL(0x9263fa61,0x4162da61),LL(0xb6488eb3,0x2ed1f2de),LL(0x725680c4,0xb0bd37a8),LL(0x29ec27b0,0x17218bf0), +}, +/* digit=22 base_pwr=2^110 */ +{ + LL(0x4bd044ef,0xfb09e756),LL(0xbb964fb3,0xdbc9fcdf),LL(0xcdb1f4f5,0x451c5b01),LL(0xf1dd1cf0,0xb02f9068),LL(0x0c687e41,0xd4765e7c),LL(0xd1967bd3,0x89b64981), LL(0xf0439d65,0x06a0e4ec),LL(0xa5abbcec,0x564c387d),LL(0xc651d806,0xc1e9d01a),LL(0x0618a96c,0x5e6ebd83),LL(0xc54ad8ce,0x9ce1aace),LL(0x9953f90f,0xe5248a08), + LL(0xbb296c27,0xda2b0725),LL(0xd341171b,0x1f22ffa4),LL(0x5b132756,0xc721e35a),LL(0xfadb6907,0xe5695e84),LL(0xc283f546,0xbc5a3bf4),LL(0xdde128ae,0x9182cb3e), LL(0x6592e05e,0x179c7fa6),LL(0xf38e8586,0x1e604790),LL(0xa16bad55,0xaf7e83be),LL(0x9137ecd8,0x6f41231e),LL(0x8f30d1ab,0xac87543d),LL(0xb1ee0ee8,0x630a9d87), + LL(0x0850b471,0xd8ccf550),LL(0xf7ebfcd8,0xea8f73d2),LL(0x7f138136,0xfb374f99),LL(0x6cd70e73,0x6b3a1ab8),LL(0x42f40008,0xc4577c13),LL(0xa0517e75,0xb23800f9), LL(0x7088a19b,0x79deaa45),LL(0x702183ed,0xa8410f51),LL(0x2c9f6594,0xe2761fa1),LL(0x52868276,0xed1d0112),LL(0xc22157a4,0x9e9805d7),LL(0xac7653e9,0xbe4aa213), + LL(0x5e4f1914,0x359cbfa0),LL(0xd922176a,0x6992cd48),LL(0x630cbcb5,0x2fd5e90f),LL(0x6ddbf238,0x2b0f6130),LL(0x3af753e6,0x5070970a),LL(0x41727016,0x433d0094), LL(0x9dca97e2,0x2eb15b3b),LL(0x00d96875,0x3a7379cd),LL(0xe930a75c,0x0d4374ae),LL(0x849e7727,0x3cd36046),LL(0x336a19ff,0x9ac3117e),LL(0x433ddc04,0x2d1373c9), + LL(0x13a2a0f2,0xa60026f0),LL(0xd6d8a91c,0x173b08a8),LL(0x2b0ff7fb,0xfa6b3eea),LL(0x4201b05d,0xd5417c7e),LL(0x598f4c56,0x91dacda7),LL(0x0a1513a5,0x00323d9a), LL(0x38bf2619,0x079a4ef1),LL(0xee3512cc,0xfe91faae),LL(0xbc03468f,0xbf9aabdf),LL(0x01d3ca1f,0x0d46d3a2),LL(0x3e677e61,0x6bfad511),LL(0x6dabf925,0x219a70aa), + LL(0x8faa3eca,0x8e145869),LL(0x511c5e09,0x811c0ab1),LL(0xc39fd20b,0x08a52f04),LL(0x5e5f514e,0xa7c22263),LL(0x8507e5c6,0x365701af),LL(0x495177cc,0xba1c1ce2), LL(0xbd3d7f93,0xed128050),LL(0x05af7fa4,0xf5b3a508),LL(0x7eb1e384,0xe27a017c),LL(0x1fbca0a7,0xaa95d99a),LL(0xbaa36562,0x61a459cf),LL(0xb7f845c1,0xc1ee4d7b), + LL(0xa4945d9f,0x164a4fa1),LL(0x8ce7f161,0xf9fb0327),LL(0x9891eb36,0x5284c704),LL(0x9bd23713,0x9ca1ee6b),LL(0xbdc043e0,0xb364fe43),LL(0xae82eb35,0xcf9c9e70), LL(0xbcde9b87,0xa375b9d5),LL(0x6d5ada37,0x55f437d7),LL(0x85bf9126,0x49fc8d72),LL(0xbd83c1bc,0xf13cbab7),LL(0xf847972a,0xc3d75306),LL(0xb1da55aa,0x8c27482a), + LL(0xe4362d67,0x985dcb43),LL(0xa939bea4,0xecb860c2),LL(0x55fbf1d5,0x40597f30),LL(0x43fcd98a,0xb6d166bf),LL(0x15ec99ca,0x59325709),LL(0xc5bdd370,0xe05ae3b9), LL(0x0c7b943b,0xc18f7827),LL(0x4dd572cc,0x84bde9c6),LL(0xf478e56b,0x5d50a89d),LL(0x64d29053,0x242c2f48),LL(0x61cf7e0e,0xcda12c61),LL(0xac8d1d40,0xf8b6890e), + LL(0x37d03584,0x3f2c311e),LL(0xbb91574c,0xb387b3cc),LL(0x8d7aa7af,0xa64914d1),LL(0xea0fb673,0x7586999a),LL(0x14e5014b,0x25ee7a70),LL(0x557fce0f,0x1015b142), LL(0x10cc9d92,0xbb839712),LL(0xabbb3b2a,0x31118426),LL(0xa29866e5,0xc3a4fa6f),LL(0x66310a76,0xbdb3a495),LL(0xa11055e7,0xd397ceb6),LL(0x0240bd0d,0xc8d47e10), + LL(0xfc8d5f6c,0x76624aad),LL(0x0144a0ff,0xb7dbb41a),LL(0x30df5bea,0xd7be190f),LL(0x9ed58b6a,0xb61e3e97),LL(0x14bf09f6,0xce192eb3),LL(0x27ad3fc4,0x3d6632af), LL(0xcdd7c93b,0x51f180e8),LL(0x932c89f0,0x257df031),LL(0xb680f621,0xed1ffbcb),LL(0x34ef3db2,0x6d8be601),LL(0x044b7f8a,0xc32869e3),LL(0x09958ada,0x8db40995), + LL(0x7ebfc0d7,0x004888a9),LL(0x0f90df8a,0x5546c1b1),LL(0xddfb6a92,0x9c73aa4e),LL(0x2782e2a4,0xb492a723),LL(0x2b9b9390,0x5e79ce87),LL(0x2564d95a,0xb8165f79), LL(0xa8f207cb,0x235665e2),LL(0x1087fea6,0xdef16762),LL(0x7b9d891a,0xf4275ea2),LL(0x1f98a6d9,0x70b2662a),LL(0x5fd15926,0x2990c521),LL(0xc30089d5,0x2734975d), + LL(0xb6b11af8,0x7a9a9dd7),LL(0x16a42f8f,0xac4c50dd),LL(0x6726c324,0x1550267b),LL(0x7f841afb,0x12cfb2fd),LL(0x2f046430,0xa41b1905),LL(0xb7d786cb,0x8f5f5373), LL(0x729e09fb,0x7b61b39c),LL(0x2626da4c,0x07a5415f),LL(0x4a348905,0x65d6efb8),LL(0xf2e864b9,0xf377862c),LL(0xab96cdb2,0x3c94000d),LL(0x8efef0f6,0x2176321a), + LL(0xaffedcf4,0xfbd2489f),LL(0x41feb03e,0xe41dfcac),LL(0xe9a86cd1,0xf13f6579),LL(0xb7ff732f,0xfe3c2a91),LL(0x82f008fc,0xd447c728),LL(0x0e1924b1,0xe4e9c054), LL(0x048bb350,0xe0d6bfc3),LL(0x2fb5fc5b,0x5fe1c204),LL(0xaa50972b,0x70799d49),LL(0xd2c42b50,0x7c79c24e),LL(0x5405cd06,0x4ffa2c53),LL(0xc7ba6f8b,0xd890bea7), + LL(0x94747d5c,0xee68456d),LL(0xef40112f,0x5c0312fe),LL(0x0fcb2565,0x57a480bc),LL(0x7c529c68,0x549b31ad),LL(0x402bdb03,0xcfdc5d33),LL(0xbf45407e,0x955bfd5d), LL(0x1fdb20fd,0x8381a1ec),LL(0x4fe0b38e,0x89dafbdc),LL(0x68f59249,0xf33c8706),LL(0x68be67d2,0xb6cc7618),LL(0xea4845b8,0xa7897c7c),LL(0x93f2f9a9,0x6773f08b), + LL(0x14a03fc5,0x642405c1),LL(0x4cf34763,0x5b973584),LL(0x3331c03d,0x9f24c2cc),LL(0x6f9bf4f5,0x56428a37),LL(0x703e5e73,0x2e83d070),LL(0x573c3cf4,0xb8e4e61a), LL(0x8f3e3efe,0x7a18ec58),LL(0xb812e5a7,0xbab02660),LL(0x8289de63,0xee826e36),LL(0xc1a8eb16,0x86d263f9),LL(0xd7b85103,0xee8f3e72),LL(0xe567c787,0xa3627d9b), + LL(0xc1c1bc68,0x8c558000),LL(0x83fd6ca6,0x9e48a67a),LL(0xeb7a35cb,0xacf0d75c),LL(0xf0a93110,0x0fbdce4c),LL(0x9cc50c85,0x82b2d13a),LL(0xcef70d6f,0x696fd259), LL(0x457b88c2,0x1cc9be2e),LL(0x1f04c0bc,0x0d58b34b),LL(0x195a532b,0x52bd479f),LL(0x1ab3605c,0x769fe6ca),LL(0x8a24c1e0,0xba6a63e4),LL(0x99da5d7a,0x86dea462), +}, +/* digit=23 base_pwr=2^115 */ +{ + LL(0x65682820,0x509abccb),LL(0x4ff86137,0xfbfa1d09),LL(0x640bc2f6,0x1ae371bd),LL(0x8f546c68,0xa155c297),LL(0xc08b8cbf,0x8858cadc),LL(0x1d96948b,0xafac5b0a), LL(0x82e25016,0x919cb226),LL(0xb064ffc3,0xd147df4a),LL(0xb4abe560,0x25dd0f1a),LL(0x9cb75bd1,0xc6bbe636),LL(0x47a778e4,0xbb367cf9),LL(0xbde524b3,0x5714aa4d), + LL(0x166915df,0xc6307399),LL(0x5da8a26e,0xb35545bc),LL(0xe3a99321,0x8e0126aa),LL(0xda9308d1,0x0fbfdf76),LL(0x6168e505,0x2163ed6b),LL(0x7500d8bd,0x71f3d008), LL(0x5ac13f65,0xf5715960),LL(0x55172d5b,0xc1cd9a67),LL(0x53d84c65,0x6b225f7e),LL(0x025029da,0x9c031269),LL(0x17d89aed,0x54c1edfa),LL(0x6b435150,0x5b023878), + LL(0x1e94d949,0x1e7ae160),LL(0xe78e6221,0x177dc53e),LL(0x7aeb9882,0x8af29d8f),LL(0x9e3f3906,0x2d9a60fd),LL(0xdf962156,0x6979fcd6),LL(0x7e1e54b8,0xdd2fe588), LL(0x76643453,0x9cccf310),LL(0x4e0643d0,0x94ece1a8),LL(0xc111d8cf,0x745449cb),LL(0xe6cfbd97,0x872afa4a),LL(0x10dfb34e,0x5c27b7ca),LL(0x533480fe,0x505e62bc), + LL(0xae238fa1,0x009ef80a),LL(0x486af6b5,0xb41d9b24),LL(0x685add95,0xab4455ed),LL(0x72c7dac8,0x18f323f6),LL(0xe372f168,0xe7009790),LL(0x067bea99,0x4d5bcba6), LL(0x51a2a9a9,0xf15bdbcc),LL(0x2fac9169,0xde7e4f74),LL(0x4bdbec36,0x2fd62c30),LL(0x1b3ac6c7,0x8b3ea93d),LL(0x9c293889,0xce1c8e5c),LL(0x11564f8b,0x19664dda), + LL(0x175418b2,0x5f266f13),LL(0x03a626f9,0x6bd7a869),LL(0x4a6f11ca,0xc7b53230),LL(0xbfc8cced,0xa216b056),LL(0xb288cb7c,0xa274d5d8),LL(0x924897ad,0x6fc4a35d), LL(0x81fc6940,0x1ea532eb),LL(0x2acbbc45,0x2fcd817e),LL(0x67814fa3,0x45eee93f),LL(0x1229e035,0x3b3da48c),LL(0xefd8e3d7,0xd049a976),LL(0xbf81f314,0x8087dff7), + LL(0xbd366155,0x77faac22),LL(0x282f11b5,0x13cc4038),LL(0x5fbd35ab,0x31ad1dd4),LL(0x45d6d40e,0x7e0de9da),LL(0x39749ef6,0xa16c5f19),LL(0x85691cf2,0x761cd6cf), LL(0x4d59b802,0x156536ad),LL(0x87c4b11d,0xee98dc41),LL(0xd35088fc,0x165a1eac),LL(0x38fb995c,0xce8a7335),LL(0x3293b3a5,0x34d0d331),LL(0x8b570e79,0xfcf548ca), + LL(0xa85af34a,0x7be5946e),LL(0xda6fb0e0,0x420593c9),LL(0x987f9246,0x40b83c00),LL(0xa15d192b,0xac35f4e9),LL(0x776a678c,0x1979bd33),LL(0x8f6068d3,0x0a7d973e), LL(0x7e6298fe,0x71d322e8),LL(0x36af9b65,0xbb23a299),LL(0x6644c50c,0x14e2b970),LL(0x73570bd3,0x5f7f2073),LL(0x9055538b,0x40215c56),LL(0x365500c9,0x91372e64), + LL(0x9af0a75c,0x6a3a2327),LL(0x9f1f250d,0xf832a815),LL(0x22a82d3f,0x17030c33),LL(0x14cbc835,0x24bf18ea),LL(0xb2da2727,0x319dc4ca),LL(0x6d020d4a,0x481df360), LL(0x7fc22ba5,0xaeebdd8a),LL(0xa91e28ab,0xbd0515c6),LL(0x595f361d,0xfc8a2978),LL(0x1ae8fa3c,0xe60dd96c),LL(0xa5341575,0x19c2109a),LL(0x06a0ee48,0xfd6e92bb), + LL(0x77b5c7c5,0x650008f9),LL(0x02a6d087,0x4bcf6002),LL(0x82234273,0x391ebfa3),LL(0x86cd884e,0x9dcb05d3),LL(0x8753b3fa,0x1b5e7afa),LL(0x2d1e513c,0xd453e9b4), LL(0x4b3a74b4,0x3b1a0dea),LL(0x5bebd592,0xf8989aac),LL(0x61dc640b,0xac3ec9f5),LL(0x6c4b301b,0x4ba9dd0a),LL(0x04e48df6,0xf686a5fe),LL(0x0631d1e6,0x8b0d2d76), + LL(0x03c87a20,0x443deaab),LL(0xbb817740,0x57dbd224),LL(0xd51d6acd,0xf88918de),LL(0x7d4ec9be,0x48c9b2f1),LL(0xdfc48a69,0x78b41104),LL(0x78827f54,0x44a81443), LL(0x16a22495,0x74ed7949),LL(0xea92d3e6,0x6b9e9128),LL(0x0d9fe252,0x6fe6449b),LL(0xc14e825a,0x31743d06),LL(0x08690f00,0xd9d4ad8c),LL(0x0e65f748,0x562e2f60), + LL(0xb1befb0a,0xe9e01117),LL(0xd25cb1ae,0x7ce74721),LL(0x2d4437ad,0x946216c6),LL(0xea8b2d85,0x83b03131),LL(0x2c4fa895,0x3614b15d),LL(0xc23c6bf7,0x393317d9), LL(0xdcd80eb4,0xda73495a),LL(0x6338db53,0x850dfb46),LL(0xc9b8943a,0x3329c498),LL(0x0765d94a,0x1ee615b5),LL(0xd67c17b3,0x2d16a6cf),LL(0x6f8a9ed5,0x050d6bfe), + LL(0x8b7f8cb2,0x92501ff8),LL(0x578a4cfd,0xcdaa6c93),LL(0xe5303846,0x95b99a05),LL(0x2543d1a9,0x30a72fdc),LL(0x11808771,0x6648126b),LL(0xeefb8145,0x6980dd99), LL(0xf1949aad,0xd9a87f83),LL(0xf7b8ab95,0x3b4f208d),LL(0xc40122e4,0x3341e118),LL(0x853b291e,0xe513567f),LL(0x3b565bad,0xd4f1bbb7),LL(0xa7658f77,0x86207b43), + LL(0xf87cd72c,0xe5737dce),LL(0x7a1c9f7f,0xdf41230a),LL(0x34e0d519,0x7fe5cfcf),LL(0x26033c9d,0x83cc1da5),LL(0xe16dffd0,0x4195ef1a),LL(0x8af91671,0x7c388f6e), LL(0x62283e40,0xeb1002b8),LL(0xa96be04c,0x08122e57),LL(0xdf9fac7c,0x48cb2d0c),LL(0x41f0946d,0xa3c007ae),LL(0xcec27088,0x4d6fa5c5),LL(0xdcd5fcfa,0xe1fbc03e), + LL(0x9bece059,0xbab37a63),LL(0x7fa28fc3,0x5a60ec87),LL(0x1d4a8f5b,0x69e1086c),LL(0x65814282,0x3a873844),LL(0x2676cc7d,0xb642dc16),LL(0x97e423a0,0x8d152bb9), LL(0x160ff40b,0x66ac1b37),LL(0xf657547a,0x7410ba67),LL(0xadcc6823,0x8f47debb),LL(0xb1536fa1,0x44e9bf64),LL(0x939e5461,0x1cfdd504),LL(0x43bb3b90,0xba5729e1), + LL(0xdd63f6d4,0xb5c26108),LL(0x60229177,0xefb8dfc7),LL(0x23e4cc7d,0x9d980889),LL(0xc211c92b,0x59579ee8),LL(0x35fe17b4,0x6f146300),LL(0x0ca61e4a,0x6c1e7075), LL(0x19d582e1,0x8671156d),LL(0x07230605,0x36a3d858),LL(0xa352dcdc,0xd9314e61),LL(0x4c6bc2b1,0x7a9d0de7),LL(0xc894ab77,0xb57d3f71),LL(0xd4e5a04e,0xb3564bc7), + LL(0xcde5e785,0x2e32f896),LL(0xb9db8f31,0xcd55ae7a),LL(0x8f832885,0x278db1ad),LL(0xadcbd933,0x271d9078),LL(0x4a64f863,0x2208fae3),LL(0x39c89365,0x974046e0), LL(0xb3cd0cd3,0xcb46f272),LL(0x74e59edc,0x31f34e1a),LL(0xedd50418,0x3421d316),LL(0xcabe36ed,0xb1d8a064),LL(0x362efcda,0xdb13e560),LL(0xc71eb3ee,0x567c2b6c), +}, +/* digit=24 base_pwr=2^120 */ +{ + LL(0x70d4d7bc,0x2af8ed81),LL(0xb632435c,0xabc3e15f),LL(0x78219356,0x4c0e726f),LL(0xb87254c4,0x8c1962a1),LL(0xc9e7691a,0x30796a71),LL(0xa75a12ee,0xd453ef19), LL(0x13ae4964,0x535f42c2),LL(0x0da9586a,0x86831c3c),LL(0xe39a7a58,0xb7f1ef35),LL(0xd459b91a,0xa2789ae2),LL(0x02fd429d,0xeadbca7f),LL(0x65290f57,0x94f215d4), + LL(0x4b950889,0xc0855002),LL(0x8ce24da0,0xee99dbfe),LL(0x4318e860,0xdda71d96),LL(0x04fe9b85,0x01d3d396),LL(0xe25e7e20,0xda4bc065),LL(0xe076c81c,0xd3a50b87), LL(0x31e5f494,0x5b9f8219),LL(0xa6a1b821,0x6a140527),LL(0xd8dd159b,0xf52683e4),LL(0x20b18043,0xca9c8887),LL(0x08a0d8f5,0x73c040fa),LL(0x179525c4,0x92e482e8), + LL(0x1cfb79ac,0x37ed2be5),LL(0xe7af84c3,0x801946f3),LL(0xe77c2f00,0xb061ad8a),LL(0x44de16a8,0xe87e1a9a),LL(0x7ee490ff,0xdf4f57c8),LL(0x005993ed,0x4e793b49), LL(0xbccb593f,0xe1036387),LL(0x95e09b80,0xf1749411),LL(0x5ab42f91,0x59cb20d1),LL(0xac0ff033,0xa738a18d),LL(0x2ac1e7f4,0xda501a2e),LL(0x84d8a6e0,0x1b67eda0), + LL(0xa4d2313e,0x3a828904),LL(0x92e66888,0xbf4946b1),LL(0xe5fa19d2,0xc574898a),LL(0x5e1c5fa4,0x0b13dbb6),LL(0x7c390fc2,0xf11343ba),LL(0xd7d32187,0x35b1418f), LL(0x83e7fe7b,0xc92cb1bb),LL(0xd78365c4,0x0b969455),LL(0x672f2af7,0xda69dfe5),LL(0x30932441,0x9c62d7b4),LL(0x94af02d6,0x165672ad),LL(0xcde81c22,0xd2cc734d), + LL(0x1080e90b,0x1d27efce),LL(0x3fd01dc6,0xa2815246),LL(0xcaa26d18,0x99a3fb83),LL(0xb82babbe,0xd27e6133),LL(0xd783dd60,0x61030dfd),LL(0x73c78cb8,0x295a2913), LL(0x68be6a92,0x8707a2cf),LL(0xeeb3474a,0xc9c2fb98),LL(0xa2b176b8,0x7c3fd412),LL(0xc7202101,0xd5b52e2f),LL(0xf0a6d536,0x24a63030),LL(0x04648ec0,0x05842de3), + LL(0x33f4d416,0xd45e3501),LL(0x4bf9131e,0xbb40233a),LL(0xe302483a,0x1532a088),LL(0x2c2485c0,0x3475e8b8),LL(0x969cdbe6,0x08f9ea56),LL(0x253cd738,0x31928645), LL(0xac9836be,0x1cf323a4),LL(0x02b6e4de,0xdf647ccf),LL(0xc06f3d09,0x9a31e84f),LL(0x39efe6d9,0xd326b86e),LL(0x14ac4dec,0x77e3e1df),LL(0xf3e0c582,0xf2d5917a), + LL(0x30577ac9,0x67477cdc),LL(0x244f92a8,0x51dd9775),LL(0x917eec66,0x31fd60b9),LL(0xd66c5c1d,0xacd95bd4),LL(0xbf9508ba,0x2e0551f3),LL(0x688cb243,0x121168e1), LL(0x4540d230,0x8c039740),LL(0x009ecdf9,0xc4ed3cf6),LL(0x44db62af,0x191825e1),LL(0xc4a030da,0x3ee8acab),LL(0x94081504,0x8ab154a8),LL(0x486c9cd0,0x1fe09e4b), + LL(0x02cf37fd,0xe92b56c0),LL(0xf71b34de,0xa75bbcb0),LL(0x50f5c482,0x7754d0ef),LL(0x11fa89fe,0x850a9ef6),LL(0xba4ea7d8,0x97d74b1b),LL(0xaab7ba2e,0xfc757c25), LL(0xf2a67fdd,0x06f30ab0),LL(0x12e72af8,0xb10aba14),LL(0x7a2e053d,0x47580bca),LL(0xdcf0e14c,0x85795598),LL(0xd6f55310,0xc3596781),LL(0x4c9b7e18,0x8ab251b7), + LL(0xd113450b,0x512f82f9),LL(0x2dbc9197,0x5878c901),LL(0xe13f355b,0xdb87412b),LL(0x935b8a5e,0x0a0a4a9b),LL(0xf25a5351,0x818587bd),LL(0x31e3d9c7,0xe8079310), LL(0x611bc1b1,0x8b1d47c7),LL(0x72a823f2,0x51722b58),LL(0x53b36b3e,0x6f97ee8a),LL(0x946dd453,0x6e085aac),LL(0xe65e6533,0x2ec5057d),LL(0x4bb18801,0xf82d9d71), + LL(0x4dbb8798,0x4ab13850),LL(0x72d04cd2,0x0e7980d7),LL(0x0b3271c6,0x1755c566),LL(0x9d9d1468,0x8414efb0),LL(0x1795ce66,0x61a58630),LL(0x232924a1,0xb6a8b393), LL(0xae031bd6,0xa992f0ce),LL(0x2915acc1,0x6747fb5f),LL(0x93e9c0d2,0x03daa266),LL(0x5400d554,0xc18fa364),LL(0x9497e895,0xaf04ff8d),LL(0x50b6b339,0x86c3cfc2), + LL(0x8ba5aa8e,0xad81fa93),LL(0x8f7aa69e,0x723e628e),LL(0xef35937c,0x0ba7c2de),LL(0x6decfb40,0x83a43ec5),LL(0xe60c4f2d,0xf520f849),LL(0x457e3b5e,0x8260e8ae), LL(0xbf1d9ed7,0x7ce874f0),LL(0x7f1a5466,0x5fde3553),LL(0x0c162dbb,0x5a63777c),LL(0xdad87289,0x0fd04f8c),LL(0x640761d5,0xca2d9e0e),LL(0x38501adb,0x4615cff8), + LL(0x04e1e6e3,0x376b2a7f),LL(0xa31774b4,0xea0dcb70),LL(0x5cbdec2e,0xfc7fe4cc),LL(0xf03f459e,0x8568499d),LL(0x8b78900e,0xe9fd8fb2),LL(0xe431bf97,0xd33c6e30), LL(0xc896e766,0xd904b8f5),LL(0x82748cef,0xa8f577cf),LL(0x87e044b3,0x93dd921b),LL(0xf76eebe9,0x23d79837),LL(0xe569feeb,0x5e0a7493),LL(0x414dddb6,0xd0797549), + LL(0x110b4a25,0x9422789b),LL(0x70ad8cc1,0x5c26779f),LL(0xec4f1e14,0x4ee6a748),LL(0x5c7ab5e0,0xfb584a0d),LL(0xfb21ee66,0xed1dcb0b),LL(0x11c6863c,0xdbed1f00), LL(0xb1b1d187,0xd2969269),LL(0xafe964e6,0xf7d0c3f2),LL(0x12bb865e,0xe05ee93f),LL(0xed79118e,0x1afb7bee),LL(0x0f0fe453,0x220af138),LL(0x52782ab9,0x1463aa1a), + LL(0xbfe5b1a7,0xfd9e3542),LL(0x75938cea,0xb42d2a41),LL(0x3befb760,0x74688a15),LL(0x2e33dbe7,0x8daeeaa2),LL(0x3e677801,0xc9c1ea08),LL(0x34effe1e,0x68ecf4e4), LL(0xd294c321,0x927700cc),LL(0xe940afc5,0x9e2e723d),LL(0x7cf6cd43,0xbcfac07a),LL(0xd1006bc3,0xa009ef94),LL(0x373d13e3,0xa02016b0),LL(0xabae5822,0x4e097adb), + LL(0xd7dbe5f9,0x7c139d56),LL(0x0b83685b,0xfc16e611),LL(0x9018463c,0xfa723c02),LL(0x840bf5d7,0xc472458c),LL(0x0af07591,0x4d809359),LL(0x3308dfd9,0x418d8830), LL(0x0c365ae3,0x9b381e04),LL(0xf8190fd1,0x3780bf33),LL(0xdd03e854,0x45397418),LL(0x4e51e491,0xa95d030f),LL(0xe3286cea,0x87c8c686),LL(0x900b5f83,0x01c773bf), + LL(0xc898b8bc,0x8db8b78c),LL(0x502940cd,0x686896da),LL(0x2dde2e3c,0x67e50f02),LL(0x8cbf406c,0x2e2461f3),LL(0xe1f7ff60,0x32182781),LL(0xe30e2688,0x26934b05), LL(0xfc4494f6,0x95adc204),LL(0x161b7499,0x4c7f30c5),LL(0xb7341737,0xd5caf060),LL(0xd128d46c,0xed93187f),LL(0x20fc1e04,0x3f2819cb),LL(0x2b7f70a1,0x48c4086f), +}, +/* digit=25 base_pwr=2^125 */ +{ + LL(0x0ece13ae,0xd74d09c1),LL(0x57a6bd95,0x5e59d9e0),LL(0xe132b940,0xdb1ccfdc),LL(0x843d3c66,0xa0e5309c),LL(0xf9cb3ef4,0x1fbd03a5),LL(0x00ea5177,0xcdc9ef0a), LL(0xcb784a6b,0x1ebf5a15),LL(0x8a0d109a,0xa67382af),LL(0xa0d34d15,0x3256c37a),LL(0x0fca43af,0xee40efa5),LL(0xb9841bde,0xc299bbd4),LL(0x3bef4a0b,0x6df68f60), + LL(0xd9d7c50a,0xe01295fd),LL(0x67f8ef0d,0xaf31b4ea),LL(0x9eaf8eb7,0x2ec9689f),LL(0xc622acc5,0x327b96c5),LL(0xb2757f2a,0xae918f81),LL(0x4fd6606e,0x74927d68), LL(0x18574215,0x09bb7fce),LL(0xe8e68b72,0xfea383bc),LL(0x5fb47511,0xdf2a6f12),LL(0x8e399520,0xbe88faa1),LL(0x3fb1c3a2,0x0166d57e),LL(0xe525f81f,0x5907ef2f), + LL(0x57797e5c,0xf24fab9b),LL(0x3add682c,0xd8500987),LL(0x33ac4fb5,0x75e370e7),LL(0xc8a69765,0xd8d61642),LL(0x5e30aa0e,0xf057f10a),LL(0x4f1e8637,0xaf953087), LL(0x701cd1a0,0x887f06b3),LL(0x8a200082,0xd7c6a9c6),LL(0x6e6483a0,0x4319f7eb),LL(0x475d4bfd,0x44f1aaff),LL(0x0f811fc7,0xa8ee73b5),LL(0x82916f8b,0xbb67bcdc), + LL(0x8a37f660,0xdefe3a7b),LL(0x858f5765,0x7898db8c),LL(0x73d1f9b4,0x7366c26a),LL(0x237ae8b7,0x35d5d718),LL(0xb4478259,0x3efb20fe),LL(0xaa545ee3,0xccd0fed7), LL(0xed22d152,0x750edd05),LL(0xee20d4c6,0x4f8020f9),LL(0x0a9e29dc,0x16e60f37),LL(0xbfbec7f6,0x9cf0a136),LL(0x2e47e143,0xb430a34b),LL(0xc6cdd1a9,0x2e2560bb), + LL(0x2a9af85a,0x2cb5625c),LL(0xfea96b60,0x9ba19601),LL(0xd7549809,0x25dd6aca),LL(0x5b4c31e9,0x9c02e613),LL(0xe09dbb63,0x40c4baea),LL(0xf49beece,0x38455db7), LL(0x5b848716,0xe9846d0d),LL(0xd2ebce35,0x9c63043d),LL(0xbc26a79e,0xedee8e86),LL(0x0869c85f,0x70c46f94),LL(0x7bc49e34,0x34b05934),LL(0xa80d7d8e,0x737fe693), + LL(0xe4161a65,0x799352da),LL(0x56253ce6,0xe5cf7ad8),LL(0x6de32775,0xf606bf79),LL(0x57fce8db,0xddc0f3a3),LL(0x16cf4a47,0x1075fc23),LL(0xb27c5ad8,0x078f0e04), LL(0x3f7100aa,0x9fc47795),LL(0x4673ffa2,0x3ac48925),LL(0xf9cd8348,0xb8263f42),LL(0x68cc92d5,0x5bdfde30),LL(0x1ac37f9c,0x2250927b),LL(0xb33da359,0x26ec8328), + LL(0x236eaa28,0x76923635),LL(0x657d0640,0x5acc650b),LL(0xc20a58ab,0x2652ec7e),LL(0x1a5459f9,0x93385f9f),LL(0x306e2091,0x45952d39),LL(0x34cef2f2,0xb31f5a42), LL(0x1f3c055f,0x0d9b0484),LL(0xae3b1f4d,0x6c5ef8ee),LL(0xbd24becd,0xd3fdb464),LL(0xa2210148,0x49b11a10),LL(0x1472893a,0x73de2855),LL(0x6ee531f7,0x99435b57), + LL(0xc88d568a,0xf186d6bc),LL(0x528535dd,0x872bc4c7),LL(0xdfe64dc3,0xc9e7432e),LL(0xd795ea57,0xd9fc4832),LL(0xc845af2b,0xf4ffdb81),LL(0x2b670517,0x66d7e788), LL(0xd7b7a1c6,0xa7c1be04),LL(0xd5b2a249,0xbed88479),LL(0x03f2ef6d,0x62ff8aba),LL(0x20dc701d,0x60ecaac4),LL(0x4ff10119,0x9f4b559f),LL(0x3cd54fd0,0x0582c931), + LL(0x3940d5dd,0x271f5d70),LL(0x192fb2b6,0x7707d109),LL(0xda210560,0xc6131828),LL(0x0bc534c0,0x21750048),LL(0x23487a61,0xa96593d1),LL(0x0b9c6e92,0xdab1698b), LL(0x1f7abe02,0x8a7951a5),LL(0xecd49e72,0xa9394a4b),LL(0x2f6f53d5,0x95ba141d),LL(0x6cdb90cc,0x03809379),LL(0x0586a3ef,0xa5e0ebf3),LL(0x70606681,0x75f006dd), + LL(0x12bbaeb6,0xea9da8f0),LL(0x8c9f8360,0x3fba06b1),LL(0xb28c0ac3,0xc11bd7ab),LL(0xaa8a01bd,0x1e05af2f),LL(0xf000b1c3,0xae1e99c5),LL(0x53d79930,0x93ee8064), LL(0x4c4f5513,0x5728089e),LL(0xb1f70b76,0x755351f3),LL(0x675f77ef,0x187ac651),LL(0x53067d84,0x5cf7bfb5),LL(0x8174b5c0,0x62929083),LL(0x8d5be74d,0x720e2079), + LL(0x15c26385,0xcdb0e974),LL(0x40c9a381,0x7110dd68),LL(0x8180d82b,0x1fd85657),LL(0xb97cf516,0xa42cad51),LL(0xc8e096e2,0xd0e97506),LL(0xac077c1c,0x9372ac5c), LL(0x528c6d23,0x080cac77),LL(0xc192bee8,0xa62b7b39),LL(0x596c03b4,0xf1b2be68),LL(0x65cdde1a,0x9e367c67),LL(0xa97f58bb,0xdb0a51db),LL(0xc29dbc0d,0xa9b52c4d), + LL(0xf5eb9ad1,0xab8cc09f),LL(0x132edbfe,0x97a4de76),LL(0x8baf6347,0xa2e11c54),LL(0x683cfcf6,0xcee54229),LL(0xdcfc6555,0xe1e993b8),LL(0xbe9df066,0x333bf16a), LL(0x060d62df,0x5207e093),LL(0x69b0f5fa,0xfa32324d),LL(0xd3243d2d,0xef16fbcf),LL(0xf04f8e45,0x540a2e59),LL(0x48317bba,0xb5e70f9c),LL(0x5b35baa1,0x00dbe9b2), + LL(0x04a6bdf1,0xa7c2e951),LL(0x45310414,0xe7b50010),LL(0x250deed3,0x0ad7ac85),LL(0x07fd3b65,0xeb7ad465),LL(0x6bdc321a,0xcac35e8c),LL(0xe992ce8e,0xf773a3e9), LL(0x0f682437,0x99cbc651),LL(0x7ff5f4b3,0x62f7b15d),LL(0x6d131441,0xf3c08dfd),LL(0xfbb0fd4b,0x8b998754),LL(0xe061d5b7,0x88dae889),LL(0x2a346488,0x9f6e8dca), + LL(0xebb512ee,0x0eaed675),LL(0x058efbd5,0x347e0756),LL(0x296d3d47,0xadf792ca),LL(0x4654d012,0x57f00c0a),LL(0xbccc5803,0xa1e08a04),LL(0x5b2f11d1,0x610677f0), LL(0xb81acfd2,0x0d9393d7),LL(0x0587c219,0xb258e157),LL(0xb4ceba47,0x372a1857),LL(0x3ecc1c5d,0xe1ce8bb5),LL(0x922cecd0,0x7efdf301),LL(0x0d8aa653,0xcab8cb17), + LL(0xd85124dd,0xc60f118a),LL(0xa77febb9,0x4a045272),LL(0x45555221,0xbae0edf5),LL(0xab65b900,0x1fb21695),LL(0xd56b9882,0x9179d546),LL(0x006bc680,0xead5f78e), LL(0xed9d8095,0x6c3ef1c1),LL(0xd024f8cd,0xe22832c1),LL(0x157c5363,0x8c783b9d),LL(0x000d3603,0x25c1bd7e),LL(0xe8ff7a81,0x4e76a723),LL(0x4a955196,0xa55cfcb4), + LL(0x79d05497,0x31954a56),LL(0xfe76d4d8,0xc12520b6),LL(0xe37ef1d2,0x8c433ec5),LL(0x75bc3b66,0xcd0f2035),LL(0x249cd98b,0x3723f145),LL(0xea3b42a3,0x1356e0d2), LL(0xf174c7b5,0xf607fee0),LL(0x0127be39,0x318afc5e),LL(0xcea5417f,0xd47b5d74),LL(0x10fca22b,0x6891940a),LL(0x2b635e8b,0x5cea4133),LL(0xb5934fef,0x93db2ed6), +}, +/* digit=26 base_pwr=2^130 */ +{ + LL(0x41b959b5,0xb1f4fead),LL(0xe71890c0,0x6edb53a9),LL(0x2e28aa2a,0x48b47efe),LL(0xb3151d67,0x70dad2e9),LL(0x436a3460,0x87a8178b),LL(0x801f7af7,0x0f86f9f5), LL(0xa982fc14,0xfab462e3),LL(0xcb03e978,0xe29126ba),LL(0xe6681282,0xb4696b3f),LL(0x6a3fdc1d,0x3bd9910a),LL(0x49e37dac,0x44091284),LL(0xcf605fb3,0x3b4bfabc), + LL(0xdf9a9f18,0x57edf71e),LL(0x627a0b79,0xbf834240),LL(0xa6934160,0xb37aba1a),LL(0x5e639a54,0xd45b3d2c),LL(0x70bce957,0x62c6b9ad),LL(0x5d7e87f3,0x16bc35a7), LL(0x66b4a982,0xb0216982),LL(0x0e51c9bc,0xb56050dd),LL(0x478e4b91,0x15aa692b),LL(0xbe3fe25a,0xdd67cf29),LL(0x06bdd4a8,0xf1ef75b0),LL(0x41df627a,0xf71a285b), + LL(0xb7a3ce87,0x3176a43a),LL(0x5f130e73,0x9fa09e97),LL(0x9368e156,0x971cc37b),LL(0xb8981792,0x2cabf535),LL(0x4d0f0bc0,0xaec2862e),LL(0x3ce8c100,0xa1a48c18), LL(0x4af2eae9,0x288f4e69),LL(0x1f9339bd,0x778845f2),LL(0x17dfaa6a,0x1ef5fdfd),LL(0x3483a6fc,0xc784117e),LL(0xf3c5c19e,0xe8c82f05),LL(0x1da87ab6,0xf39b3c1d), + LL(0x8a541be6,0xa58a27c5),LL(0x54fd7683,0xaf669499),LL(0x00079a25,0x24318266),LL(0x2606caf5,0x113f6fcf),LL(0x16cb28c8,0xf6ff2be3),LL(0x3c17caa6,0x8f7fc60e), LL(0x7d35e26c,0x8ea577e0),LL(0xf0628903,0xc3e744c0),LL(0x592a57ee,0x4b28eff4),LL(0x5e3f67b2,0x76e1f87c),LL(0xfb008902,0x40d7a676),LL(0x4b6e6b7e,0x68a9dc76), + LL(0xe4fbe1d8,0xfc14716f),LL(0x88d5fc05,0x711c4f60),LL(0x8ab2552f,0x53df2711),LL(0xb3039434,0xeb4a3587),LL(0x825eba03,0x84223085),LL(0xf69569cf,0x1aff30b7), LL(0x30d38055,0x752a2b25),LL(0x7dc7727e,0x8fb8ef5e),LL(0x679f84b9,0x8f0b8bea),LL(0x004815a9,0x076e7b05),LL(0x65debb2f,0x93275037),LL(0x83a686b0,0x24f92c79), + LL(0xdff082f7,0xf9597802),LL(0xeb44042c,0xb47fcfee),LL(0x8ac1e9a9,0x0e2570c9),LL(0x9168391b,0x144f5763),LL(0xfe49b3b2,0x7c5fe9e6),LL(0xe1202056,0x30dd5a41), LL(0xe5132272,0xb0866f7c),LL(0x199d029c,0xaa2d7c60),LL(0x2bd29ff9,0xb37c3232),LL(0x29bc5c36,0x6c0e511b),LL(0xbaa69a42,0xb64e16b6),LL(0x28545caf,0x9fd7d79b), + LL(0x0c3576d3,0x0620003c),LL(0x31b24876,0xa9608ecd),LL(0x2d83f362,0x7dcb576a),LL(0x7df98941,0x88a3a38a),LL(0xb3596afe,0xdd182e8a),LL(0xe02a5357,0x9c740d01), LL(0xb75d5d3b,0x2fed2fcc),LL(0x8d34ca34,0xd0ea6d50),LL(0x8f4bd1dd,0xfe4b8743),LL(0xb130c5c5,0x73c5acd3),LL(0x2dadbb20,0x9f8b0817),LL(0xc5a59dfc,0x34b74294), + LL(0x12575913,0x76e2751a),LL(0x4a5f8c4a,0x2c605991),LL(0x71fba662,0x58322dfb),LL(0x5e0886af,0x228aec08),LL(0x6aee544c,0x8d83b627),LL(0xe29f9639,0x338f5fb6), LL(0xbf5e19fa,0x1ba4cfe0),LL(0xb9e4f8f6,0x2eea84c5),LL(0xcee95d92,0x7e0eed58),LL(0xbe535540,0x2d29282a),LL(0x07a9a1f4,0x866638b6),LL(0x6ab8dc82,0x91599977), + LL(0xa2144cce,0x6741d444),LL(0x771c7c6c,0x06ce4c04),LL(0xae0ff352,0x3d5bc2d2),LL(0x0e05ca8a,0xa0ae03ba),LL(0x833183d8,0xbf718851),LL(0xccdc956f,0x7095f4d4), LL(0xb3ab0c80,0x23268e4a),LL(0xc16c6dad,0x984cf1eb),LL(0x67120ec8,0xc2333145),LL(0x9cd9a03f,0xc615f60e),LL(0xb3d16871,0xe9e35fd3),LL(0x15e76b83,0xc9b9853d), + LL(0xbb7fefd2,0xd8e314ab),LL(0xaa61ea98,0x74d946ba),LL(0x00fd45fb,0x10cfd8b5),LL(0x357f8e42,0x87dfda88),LL(0x27bf7a3a,0x6dab4a2f),LL(0x03b613f5,0x4dd49a15), LL(0x74f2c1a8,0x1f5491dc),LL(0xcc8ee02e,0x98d17370),LL(0x3f141b03,0x01ef39fe),LL(0x6984d4c3,0xa5b04673),LL(0x4a926cdb,0x10c40183),LL(0xe2af1758,0x3e7bbe18), + LL(0xc2faa336,0xda178c95),LL(0x68d20d12,0xb4ae744b),LL(0x5e066620,0x5b75f4e9),LL(0x41e95800,0x4138315f),LL(0x010c2c6a,0xf5c97da9),LL(0xe07bbf8d,0xbc4ff40f), LL(0x21709050,0xbdd6bc9f),LL(0xc5f7bb78,0xf3f4dcf2),LL(0x9b1da924,0x584ce030),LL(0xec3d9507,0x44b81c48),LL(0x73e1961e,0x1dfab021),LL(0xa77458a8,0x9212120e), + LL(0xf9612455,0x599ece96),LL(0xc725cba4,0xe1c6eb81),LL(0x6373ccee,0x2afc5ba8),LL(0xc64f7261,0xe4556833),LL(0x414ce1ab,0xf29ad540),LL(0x3ee82a77,0x7094e067), LL(0xdc9716fa,0xfa26eaa0),LL(0x9ceb36af,0x340da4be),LL(0x4e1c94bd,0x9570ade5),LL(0x20b0ddbe,0xf4a86d8e),LL(0xdc6eff6f,0x967ab653),LL(0xe8bab7a4,0x48890be5), + LL(0xc96437e8,0x74ee2fe8),LL(0x0bfd2bb3,0xeafe095d),LL(0x103d0a33,0xc75f0e53),LL(0x70f13700,0x22190801),LL(0x101d133f,0x96684d5b),LL(0xf21b224b,0x6c98178f), LL(0x1d59dd67,0xe3003316),LL(0x734e7699,0x933de68f),LL(0xa305ea84,0xa3883631),LL(0x6d66c90f,0x21afb4d0),LL(0x330568ce,0xebeecc72),LL(0x62b5a3ae,0x6b65b757), + LL(0xf637841c,0x4069700f),LL(0xb1c94076,0x6ee84605),LL(0x829e1bc4,0xcd64ecd7),LL(0x45cdda86,0x606944a8),LL(0x58f036ae,0xb0f2d5fe),LL(0xec18a23f,0x0391590a), LL(0x1a82e6c2,0xe29e3891),LL(0x6bd4a55b,0x5489a628),LL(0x7ae6380c,0xf3e7a351),LL(0x6ae0ae07,0xb3272f23),LL(0xe66cd800,0xb605a039),LL(0x2aac1b66,0xd4e522ea), + LL(0x8b153f87,0xbb9d0b1c),LL(0x518a921d,0xa3d52cbe),LL(0x2110cd42,0x232a29d2),LL(0x8a40d59b,0x9083e225),LL(0xaa50f55d,0x3b00382e),LL(0xc02cf900,0x4ad64680), LL(0x36cad5d1,0x2f25bd26),LL(0x64eb9c45,0x9c693e85),LL(0xccf60708,0xe4ea93e5),LL(0xf9270541,0xb932b958),LL(0x5eb454ce,0xee93f51f),LL(0x38840e07,0x1e82e354), + LL(0xaf4d260b,0xa16c79cf),LL(0xfab3c3c8,0xfe853f6c),LL(0xc2f47e68,0xb8bd6aa0),LL(0x2c9b4914,0x277d590f),LL(0x097242a8,0xb6d1c810),LL(0x45f75512,0xcf2f3d8e), LL(0x74a20c3b,0x2176162b),LL(0x2b2bcdda,0xeee8bcb8),LL(0xa503aee7,0xfcf8c0d1),LL(0x7af4dd78,0x5d1f94a5),LL(0x2ab43be4,0x8f0bc1a6),LL(0xba9e071b,0xd22dbf16), +}, +/* digit=27 base_pwr=2^135 */ +{ + LL(0xb4e814b3,0x705bfe37),LL(0x702013c6,0x22f0de61),LL(0xbc456797,0x811e77a9),LL(0x17081a2f,0x4f52c4e6),LL(0x9fe1640e,0x87405d81),LL(0x707711d7,0x53fa82b7), LL(0x0ee4aea6,0xdc6fff83),LL(0xfd60373d,0x8413e22f),LL(0xa9cf3ead,0x0ecb66be),LL(0x87139b8b,0x7418372e),LL(0x5e42b4d7,0x6aaccf29),LL(0x31fc932e,0xb6dc5925), + LL(0xb88ee8f9,0xfa3b4c8e),LL(0xb521ab57,0x1f288e60),LL(0x2e8c4d8c,0x06aa3956),LL(0xcf89935b,0x4981c3e5),LL(0x45fa071e,0xbdbd0c47),LL(0x496073be,0xa78f831c), LL(0xa4e5c001,0x09a72986),LL(0x709cb728,0xac527731),LL(0x988f2781,0x9a64b5b3),LL(0x73b1719d,0x6ac9440d),LL(0xe3d2e807,0x58ad54c7),LL(0x8f06742b,0x1c157448), + LL(0x75c953b2,0x6b5b7b2a),LL(0xa7f1cd5b,0x927ed77c),LL(0x4cba0e5e,0x2e8c5399),LL(0x3f4a941b,0x03aeb14a),LL(0xa1385c8a,0xedbad9a0),LL(0x67fd2258,0x925a49c1), LL(0x3365ffed,0xe7e368ee),LL(0xd106eb87,0xcc4aad2d),LL(0xa980b53b,0x4ce908da),LL(0x16929ac8,0xd3f49540),LL(0xd5c05c32,0x613c804d),LL(0xd7973344,0xa42290cc), + LL(0xa98cf218,0x33952177),LL(0x579ee53a,0x841d9e1f),LL(0x0a285bd5,0x1084d61e),LL(0x71171b1c,0x3935a84e),LL(0xf29b29f9,0x8ac2433c),LL(0x6dd1e9bd,0x5dd868b5), LL(0x8d102390,0x88da0478),LL(0x657400d1,0x1140735a),LL(0x9d5b19e1,0xa792a25f),LL(0x6a27fa79,0x9ee015cb),LL(0x7ba16a8e,0xea3bf8b5),LL(0xc15fde67,0xc5f0cc26), + LL(0xee2c3290,0x2e152d95),LL(0x4a9ceda4,0x8437df2e),LL(0x3c7ebfd1,0x4151754e),LL(0x88f80aea,0x556c59a8),LL(0x8de44dbc,0x8d099c5d),LL(0x77abeecc,0x9ecce7fc), LL(0x3aa311cf,0x5e0a0f38),LL(0xb8f2bff5,0x99ff1eec),LL(0xb5dcf488,0x5ae0b483),LL(0x91483a02,0x11212c45),LL(0x312134a1,0x99fe0738),LL(0xa72745ef,0x3b855db0), + LL(0x892c8eec,0x37f50e43),LL(0x7d85a7e2,0xf06a2f04),LL(0xe1d11150,0x3916af85),LL(0x6785ae1c,0xf56e852f),LL(0xae6ada8c,0xbf8c72ad),LL(0xe13285b2,0x1fcd53e3), LL(0xbd56d348,0x5327920c),LL(0x445658a8,0x82a394fb),LL(0x3caf3792,0xa7132857),LL(0x550ffe1c,0xb15ab34b),LL(0x6a5d4e4f,0x81898066),LL(0x2f854f9d,0x0bda153b), + LL(0x722730fe,0x77a31009),LL(0xd5cdd297,0x93707ac4),LL(0xd3811e8c,0xa290be39),LL(0x92a5cdb7,0x831a9b95),LL(0xe7342270,0xc74cda84),LL(0x3f48affc,0x96466190), LL(0x5520b0f0,0xb0496cca),LL(0xbae930ff,0xc8742cd9),LL(0xeaea703a,0x3a30737a),LL(0xfb758854,0x0a8e6fb7),LL(0x6796f4d1,0x9ab9523e),LL(0xfdf7140f,0x36e6c05d), + LL(0x64ef6a95,0x3b623150),LL(0xaaa5b792,0x97645381),LL(0x56471100,0x4bc2c31c),LL(0x1bae8d2a,0x4a0e73bb),LL(0x8df1f76a,0xbfc0770a),LL(0xa7bb16ca,0x5089916f), LL(0xf31fe82e,0x2afe5b1c),LL(0xf0119977,0x0b06831d),LL(0xa1af2a82,0x97caa333),LL(0xdafed6cd,0x93cb92c5),LL(0x92c3b2e3,0x09553e7e),LL(0x61af2956,0x3d9c4b7d), + LL(0x08f84746,0xd83f574a),LL(0xca07f5f8,0x48fc9715),LL(0xdcc51638,0xb3d5d0d2),LL(0x6153bdcd,0xc2a5e335),LL(0x8aa4ef74,0x8242cd9a),LL(0x0bdaa0d0,0xe71ba25b), LL(0xa4ff172d,0x4342d4bb),LL(0xfc1341a2,0x81db10df),LL(0x7dacb140,0xdd93dd87),LL(0xd12d347f,0x6f8a4e81),LL(0x1bc369be,0x0d4e7e46),LL(0x1fafd0c5,0x3ce10a77), + LL(0xe67145b6,0x5559dd31),LL(0x5b2427e7,0xf2d905b4),LL(0xcaf57d0c,0x0d840fab),LL(0x78742ab6,0x96258665),LL(0x409c1c8e,0xc85482ad),LL(0xadaa6167,0xdca2a058), LL(0x0c8885fd,0xec26ad9a),LL(0x2a600cb2,0x1b93b8a2),LL(0x2539986b,0x340aa7fc),LL(0xa23dee41,0xd7674876),LL(0x2e1a9837,0xa948a929),LL(0x71438da9,0x9ae67d2a), + LL(0xd56bdf1f,0xeac6f447),LL(0xc2b502ff,0xb22e8425),LL(0xfca5a501,0xe1cc9d3d),LL(0xb64baf39,0x8192bc29),LL(0x52ce849e,0xeb2c901a),LL(0x1dd506f1,0x7f5f38b1), LL(0x0f0a1d68,0xfb3684b1),LL(0xe9240ff8,0x16c4aacd),LL(0x5a4d8995,0xffa68243),LL(0x54e4c95d,0x27264ab5),LL(0x4f34ffaa,0x9aa40cdc),LL(0x5fd818ee,0xcb8a30a3), + LL(0xf7f35053,0x39038863),LL(0x328787d2,0x421a17f3),LL(0xf3d8310f,0x38aa682e),LL(0xf4123153,0xb52d41e8),LL(0x7026310b,0x4fbef3dd),LL(0xf6ff5692,0x0c6bd7ad), LL(0xa9be5d0c,0x3831c6b2),LL(0xe8d328b8,0xb5c9ae85),LL(0x6516bba4,0x76d26abc),LL(0x446d35a8,0xc237f9a5),LL(0xf012a8d0,0xb2b16c0f),LL(0x0ee0315b,0xddf2b7fe), + LL(0x056ad6c2,0xbb85b640),LL(0xac074372,0x7c51ef96),LL(0xf10b43fc,0x1c7ce31c),LL(0x26f4d3a4,0x08e4101b),LL(0x3968459f,0xd18511c4),LL(0xd6d07839,0x00e20c3f), LL(0xe4fcdc11,0xd5bcd598),LL(0xc877f6a2,0x99e9a4d0),LL(0xbd491646,0x9c5dd9d0),LL(0x9bfd7a1a,0x83918f60),LL(0x7e2b95a3,0x4bc130cd),LL(0xfbc31c83,0x668825fb), + LL(0x06a9ad54,0x817d77b1),LL(0x89a25eca,0x3a999d7d),LL(0xda68b768,0xd3ac4107),LL(0xbebc4c4d,0x6904bcdd),LL(0xa53d39e9,0xb0d2103c),LL(0x30a5e950,0xdba86bd2), LL(0x4f52208e,0xb0925680),LL(0x28495b2c,0x37c3156a),LL(0xc15855ae,0x2389ab34),LL(0x3017194f,0xc14dfd96),LL(0x1146b838,0x420e0719),LL(0x8fb4b6fc,0x1a9f909b), + LL(0xdd63404d,0x2926ef17),LL(0x1399cc68,0x0e89c4d4),LL(0xf7ec20b8,0x6507fede),LL(0x88c751d6,0x1ac084ff),LL(0xdefe29e6,0x31bc08be),LL(0x4f0692c5,0xd4219971), LL(0x36069bc0,0x4d6ee742),LL(0xff80f3d7,0x3868ef6a),LL(0x5a9c6f4b,0x6df02d7c),LL(0x101abf69,0x2c3096bb),LL(0x8eaacaeb,0x0c2b01ec),LL(0xeb2e687a,0x65914c20), + LL(0x79ed523a,0x13722ab0),LL(0x249d5624,0x33b29bec),LL(0xf76fdaf7,0xd3d0f467),LL(0x12ddfd9a,0x7ce072f9),LL(0x47bdefd3,0xce918a57),LL(0x750e5315,0x14d38ab4), LL(0x3346f647,0x08bbb20e),LL(0x05b26894,0x428b917f),LL(0xca865ba6,0xc8fb5c21),LL(0x2e6e8e6f,0xee6e41e0),LL(0x4c608b60,0xd00ae621),LL(0x6ff685cd,0x65975639), +}, +/* digit=28 base_pwr=2^140 */ +{ + LL(0xa368eff6,0xbbccce39),LL(0x8ceb5c43,0xd8caabdf),LL(0xd2252fda,0x9eae35a5),LL(0x54e7dd49,0xa8f4f209),LL(0x295100fd,0xa56d72a6),LL(0x56767727,0x20fc1fe8), LL(0x0bbaa5ab,0xbf60b248),LL(0x313911f2,0xa4f3ce5a),LL(0xb93dab9c,0xc2a67ad4),LL(0x22d71f39,0x18cd0ed0),LL(0x5f304db2,0x04380c42),LL(0x6729c821,0x26420cbb), + LL(0x0eb008c8,0xca07923c),LL(0x9985912e,0xab79402d),LL(0x3cb02510,0x41e379e8),LL(0xbeb383ef,0xfabac005),LL(0x1076dd0d,0x24d12d9a),LL(0xb208f127,0x95afd46f), LL(0xb1031e46,0x9cc38a60),LL(0x7009f6bc,0x93e21e97),LL(0x8ac219ef,0x6f6360d9),LL(0xaf284c80,0x1edaab3f),LL(0x019e366a,0x9c3b5281),LL(0xbc9e9726,0x6475c579), + LL(0xbdfbcae8,0x26bd07d6),LL(0xdf01a80a,0x10b5173f),LL(0x6798b96c,0xd831c546),LL(0x1d3f3859,0x1d6b4108),LL(0x991b9ec7,0x501d38ec),LL(0xd78431a9,0x26319283), LL(0x118b343c,0x8b85baf7),LL(0x58def7d0,0x4696cddd),LL(0x7acdcf58,0xefc7c110),LL(0x848d5842,0xd9af415c),LL(0x0ac7fdac,0x6b5a06bc),LL(0xa344319b,0x7d623e0d), + LL(0x8d85a25a,0x8410d829),LL(0x4af81a14,0x48ee0135),LL(0x18c25348,0xae460d0d),LL(0x7eb035a3,0x5d0279a0),LL(0x9a114414,0x87e7c128),LL(0xc0744f79,0x17c08a8e), LL(0x025cdbe3,0xb7b2b4f1),LL(0x82d1af60,0x9a74f15d),LL(0xb51ee685,0x124a7395),LL(0xf6122422,0xf2937c4b),LL(0x07f1a7ff,0xb4ec1332),LL(0xf886032e,0xad801112), + LL(0x0c9d3547,0x4c0d7806),LL(0xcf2aed47,0x993f048d),LL(0xe4b57e22,0x5217c453),LL(0xf4172b28,0xb4669e35),LL(0x49f999f8,0x509a3cd0),LL(0x87c69d41,0xd19f8632), LL(0x4c8fded0,0xe14d01e8),LL(0xeafd9e1c,0x342880fd),LL(0x70dc2bf0,0x0e17bff2),LL(0xc0186400,0x46560b7b),LL(0x49a4dd34,0xe28c7b9c),LL(0x0f325d06,0x18211916), + LL(0x7bb5346e,0xdd4eb3d0),LL(0x382e7db7,0x9a46ad01),LL(0xdc1973c7,0x1200285d),LL(0xa0046b98,0xfd342bea),LL(0x1219a7fc,0xd1917349),LL(0xb7caffe5,0x5383d319), LL(0x2e0fa118,0xea5a0c4e),LL(0xa5457b28,0x1cc2de3c),LL(0x6046eeea,0x5b2a16dc),LL(0xcc8e64b1,0x1755e1fe),LL(0x9e7fadda,0x51e4946e),LL(0xfcbf4ec2,0xf805422f), + LL(0xd7e02e18,0x46d70888),LL(0xd9f11fd9,0x7c806954),LL(0x4fbea271,0xe4948fca),LL(0xbd80a9df,0x7d6c7765),LL(0xf3871c71,0x1b470ea6),LL(0x8330a570,0xd62de244), LL(0xc659c3a7,0xdaecddc1),LL(0x077f7afc,0x8621e513),LL(0xcaeeef13,0x56c7cd84),LL(0xc685a356,0xc60c910f),LL(0x9dd93ddc,0xe68bc5c5),LL(0xfeb64895,0xd904e89f), + LL(0xbd08ffaf,0xf877e8c6),LL(0xaf23012f,0x24718fef),LL(0x2b004cfe,0x19ff269f),LL(0x95450f8b,0x8adc5d77),LL(0xe2a7d458,0x688ce8bc),LL(0x97bd7fdc,0x74d7445b), LL(0x41e6abad,0x1b9f4ad6),LL(0xf00e4bf5,0x6652ed05),LL(0x71d83d86,0xabee1f7e),LL(0x25ffc219,0xe693c76d),LL(0xc873f553,0x1c9a84af),LL(0x66d77a55,0x84d27187), + LL(0x8ba7917a,0x75d874fb),LL(0xfd043bd4,0x18fa7f53),LL(0x1fc3979e,0x212a0ad7),LL(0x5d6eac0e,0x5703a7d9),LL(0x017dead5,0x222f7188),LL(0x0f6c1817,0x1ec687b7), LL(0x238bacb6,0x23412fc3),LL(0x54ced154,0xb85d70e9),LL(0xbda674d0,0xd4e06722),LL(0x36f5a0c2,0x3ea5f178),LL(0xf5c6d2ca,0x7e7d79cf),LL(0x3dbb3c73,0x1fff9464), + LL(0x7e5f7121,0xe566dc05),LL(0x2ed07bc3,0xccac74e2),LL(0xc70401b4,0xaabfdfcd),LL(0x6254e0db,0xac9fc449),LL(0x11c7de05,0x358d885f),LL(0xd60772b4,0xb8e6a4a9), LL(0xcfe917ce,0x884272a5),LL(0x9a3d347a,0xdfbe9868),LL(0xc9d1bacc,0x06b90848),LL(0xdb8c6288,0xc4ccedb6),LL(0x79e5683e,0x892878b9),LL(0x243273e3,0x1b521829), + LL(0xf163e4a8,0x916e19d0),LL(0x1489df17,0x1e6740e7),LL(0x339f3a47,0x1eaf9723),LL(0x124b8dad,0x22f0ed1a),LL(0x49c3dd04,0x39c9166c),LL(0xce1e9acc,0x628e7fd4), LL(0x40031676,0x124ddf27),LL(0x1eddb9be,0x00256939),LL(0xd360b0da,0xd39e25e7),LL(0x4aa6c4c9,0x6e3015a8),LL(0x623eda09,0xc6a2f643),LL(0x50aa99fb,0xbeff2d12), + LL(0xbf0c6fbe,0x099369c4),LL(0xfe7d5727,0x976f78b2),LL(0xd18267a9,0x32feb503),LL(0x1a7dd0fe,0x162c4150),LL(0x26b8e969,0x3141e377),LL(0x3b53a94a,0x50497a64), LL(0x607b4cfc,0x96159f41),LL(0x2f111bab,0x1999b704),LL(0x760f2eae,0x3254987c),LL(0x841014fa,0x5308075b),LL(0x4e7adad8,0xc634127e),LL(0x59ffbfe6,0x32a70a60), + LL(0x93ee8089,0x1feef7ce),LL(0x252dd7bd,0xc6b180bc),LL(0x1788f051,0xa16fb20b),LL(0xe046ed39,0xd86fd392),LL(0x9378ce1d,0xda0a3611),LL(0xa5f7a61d,0x121ef3e7), LL(0x92d13cae,0x94d22061),LL(0x77c72e08,0x5076046a),LL(0x7d2308b9,0xf18bc233),LL(0x17f977b1,0x004db3c5),LL(0x0471c11d,0xd05ae399),LL(0x85cd1726,0x86a2a557), + LL(0xa1f857e6,0x7279c369),LL(0x27fb373a,0x029d30ef),LL(0x6827358b,0xe82cbc80),LL(0xa18f57ab,0x2bfe09aa),LL(0xe5503492,0x63bf3145),LL(0xfb28ee43,0x7ea15bea), LL(0x5eec91b8,0x8e6d428f),LL(0x611b1799,0x215e03e9),LL(0x61d476de,0xb9957371),LL(0xe76726a5,0x2320c764),LL(0x8e5e26f5,0xc5de8817),LL(0x9161e0b7,0x24aae069), + LL(0x72107804,0xb8d9b286),LL(0x3303b79b,0xb5a7c413),LL(0x5fa37ded,0x927eef78),LL(0xad67daba,0xa1c5cf1e),LL(0x7360e7c7,0xaa5e3fb2),LL(0x0a0c0993,0x8354e61a), LL(0x7f5458cc,0x2ec73af9),LL(0x48474325,0xde4cb488),LL(0x7209bc69,0x2dd134c7),LL(0x451a2abe,0xb70c5567),LL(0x8e293018,0x2cd1b200),LL(0xd33c0d72,0x15f8da7a), + LL(0x893b9a2d,0x5584cbb3),LL(0x00850c5d,0x820c660b),LL(0x7df2d43d,0x4126d826),LL(0x0109e801,0xdd5bbbf0),LL(0x38172f1c,0x85b92ee3),LL(0xf31430d9,0x609d4f93), LL(0xeadaf9d6,0x1e059a07),LL(0x0f125fb0,0x70e6536c),LL(0x560f20e7,0xd6220751),LL(0x7aaf3a9a,0xa59489ae),LL(0x64bae14e,0x7b70e2f6),LL(0x76d08249,0x0dd03701), +}, +/* digit=29 base_pwr=2^145 */ +{ + LL(0x31cb94c9,0xaff47822),LL(0x803c1af4,0xf1b5a0b7),LL(0x2ef696a9,0xbeb85f8d),LL(0x4fa94fca,0x8ce5baab),LL(0x00d41a43,0x0a32f962),LL(0x74f6e772,0x0f69ad57), LL(0x6ccb5157,0xbe0221af),LL(0x2a4f91ff,0xcb83969a),LL(0xa7e49f39,0x78ff85d6),LL(0xcb5d3c63,0x63006589),LL(0x96eb65f5,0xe8e43835),LL(0xff8adbdf,0x79f59da9), + LL(0x10eeed24,0x082ea61d),LL(0x143fd59d,0x7c9d5ade),LL(0x2e54f5cf,0x7d33df96),LL(0xe39dc6ab,0x340b0d36),LL(0x8d179b13,0xd97a8b84),LL(0x288d388c,0x88184bb0), LL(0xe116ae6d,0x2237e507),LL(0x211b2cf0,0x3e97b063),LL(0x42be7459,0x645f8bcb),LL(0xde2176b6,0xce2b0f54),LL(0xd1e2f09c,0xaf570a09),LL(0x57fdc001,0x110adf56), + LL(0x842e4246,0x9d21c740),LL(0x4ab098a5,0x30f474c4),LL(0xaae5d701,0x57f8b1a3),LL(0x91978d15,0x477e4f88),LL(0x0fb85b1e,0x2913ffb4),LL(0x58489fb4,0x80aedb22), LL(0x0912d86a,0x0e1ab267),LL(0x82933f3a,0xea5e6a41),LL(0x57ab8d86,0xf578ccb6),LL(0x547f64bd,0x339fd796),LL(0x3f3e497e,0x90469394),LL(0x1d864706,0x2cde596c), + LL(0xbcb6db29,0x158bfe27),LL(0x0054d963,0x96721241),LL(0x8e71aca1,0xf07b153b),LL(0x71b11643,0x5e676981),LL(0xd04e2f90,0x77b7dd7d),LL(0xf0dcf109,0x07814aa6), LL(0xfe1d0b1e,0xd3bab2a4),LL(0xbe69e691,0x50abba31),LL(0xc6f53cd9,0x54fe99af),LL(0x628039e4,0x071f2a4f),LL(0xb183aa16,0xf1f44181),LL(0x5010f6f9,0xdf0138e0), + LL(0xaff45947,0x5737f903),LL(0x62c5dfd1,0xe576f8ff),LL(0xe1e379a2,0x2a7d4f18),LL(0xf2f26f8c,0x8596ffaf),LL(0xfab86608,0x12f49653),LL(0x3aab1eaf,0xcc618497), LL(0x865d9611,0x7b5d029f),LL(0xbf6861f5,0x87af2d58),LL(0x31b2d7cf,0xb7653646),LL(0x8be46ef9,0x60f47e05),LL(0xb1c175ce,0xa21106a9),LL(0xdeb065b6,0x21cb0e27), + LL(0xb340f4eb,0xb287e26d),LL(0xb34c2948,0xa397cfd1),LL(0x9a7ead15,0x0d91d763),LL(0x66e88f14,0xd71901b9),LL(0xb4884ac2,0x02447ad3),LL(0xd006f448,0x5e6f7545), LL(0xec5744e3,0x2af6bfee),LL(0xf55cd6ab,0x643f46b1),LL(0x87b2c127,0x13400bc4),LL(0x4629859b,0xd1dddff4),LL(0x20feecb9,0x9710cae0),LL(0xd02d4300,0x594bc27c), + LL(0xaa331700,0xb0233c4d),LL(0x30b3a854,0x3bf63a61),LL(0x49b806e2,0xc269d68b),LL(0xda8ddca6,0x4a079274),LL(0x0db04d76,0x256bc009),LL(0x1f47dfee,0x7395c11c), LL(0x13886ec2,0x51bbcc95),LL(0x244d1f0d,0x9d5377eb),LL(0xff9e6b3a,0xa6e0f054),LL(0x204e5258,0x307f9e93),LL(0x8d34d97b,0x8069c01d),LL(0x43c24997,0x30f785ce), + LL(0x9c77ca60,0xb1e36501),LL(0x01018e14,0xfe084a23),LL(0xa4bfdcec,0xbf451d2c),LL(0xb29cdcfe,0xd210892f),LL(0x94514871,0x5b12bcd8),LL(0x1809b1e3,0xd03ca18c), LL(0x5858e4ea,0x09b24311),LL(0xe57524b4,0x37b30d50),LL(0x5de334b5,0xcef0a16b),LL(0x0b116076,0xfe0bd1e2),LL(0x89ae2bf4,0x54e4b482),LL(0x68c8a937,0xfbcc5e1a), + LL(0x91ae19fb,0xf7473902),LL(0x1bed3f8d,0xc1c228d3),LL(0x6552154e,0x763ba8ee),LL(0xe2063ce7,0xb7b60248),LL(0x178a5184,0xafaf01b8),LL(0x7901d21a,0xe193b834), LL(0x260eb30f,0x1d29f7d6),LL(0xc23b4b94,0x030516c6),LL(0x7dc4a09a,0x30a8046a),LL(0xb5ee1147,0x8414133a),LL(0x4453f1a6,0x7ec8dccf),LL(0x59da8e8d,0xe380e69c), + LL(0x22c77f4b,0x28fdf72f),LL(0x32485220,0xfa077b15),LL(0xd6325081,0xc3801faf),LL(0x891ff5df,0x8dd4e3c9),LL(0xaa73c827,0x6726c5ec),LL(0xe9b9b128,0x12af9707), LL(0xff25cf07,0x5e6ae3cb),LL(0xd7cb7adc,0x0613bef8),LL(0xcef4cd47,0xfd426caa),LL(0xced0e435,0xe14ed3ef),LL(0x6000ec80,0x8323a861),LL(0x941f8071,0x58221041), + LL(0xa83eb17c,0x6f766821),LL(0xbd7ff851,0x91fe58c1),LL(0x9063af8a,0x7ce09f04),LL(0x6c109e02,0x5230b3c6),LL(0x36274fb9,0x501adb33),LL(0x90547af3,0xcfb34bec), LL(0x40f61ec9,0x622d1387),LL(0x0e3e98d1,0xdf26e4c6),LL(0x7c676ee3,0x6b3b3d62),LL(0xf0244737,0x9f841097),LL(0x4fc8dd58,0xcfaf6ead),LL(0xcd534ab4,0x4f5d463b), + LL(0x64be0f56,0xa5023e13),LL(0x0046f45c,0x6a7310e0),LL(0xec8700d3,0xe0af09ae),LL(0xeb2d38f0,0xdea5fb7c),LL(0x859852e6,0xc038eae6),LL(0x8c34f04c,0xd515fb4c), LL(0x1488c207,0x546b778e),LL(0x6258d8ba,0x8cf4f114),LL(0x5182c96c,0x474e60d8),LL(0x3dbde757,0xcd038730),LL(0x76ab01ff,0x387232f8),LL(0x28231392,0x277614f6), + LL(0x80b86bc6,0x930c3c59),LL(0xa06d10a8,0xebc8c144),LL(0x81e55432,0x20743ddd),LL(0x006d3073,0x059521d4),LL(0x12dbc785,0x8d4fe303),LL(0xdf4901d6,0x15a4debc), LL(0xb37b2d8b,0xc9b226b1),LL(0x0fe9bdbf,0x385ac3c9),LL(0xfeaa5bff,0x64df89f7),LL(0x81de42ba,0x67de8e03),LL(0x5bf63f6f,0x12bd8322),LL(0x32b4ec13,0xb499f8ff), + LL(0x9608c827,0xba0800b8),LL(0x47dfcd84,0x560c31f5),LL(0x520dba6e,0xd52e8fdc),LL(0x854fa4ee,0x66a917c2),LL(0xc6e5d664,0xfc543b79),LL(0x32b530aa,0x5b643692), LL(0x563a3933,0x427dc1ef),LL(0x88d5902f,0x4e47c929),LL(0x93eca4fb,0x9eff3a40),LL(0x59260a69,0xc5b396ee),LL(0x48e70137,0x936a5062),LL(0x21bba959,0x69eb44f6), + LL(0xab9f58a2,0x0af34aa7),LL(0x7d150dcb,0x0ba16d98),LL(0xb7c119b4,0x444d5495),LL(0x5ecc3210,0x317a55e5),LL(0xb1aa90c0,0x8fa3b3ce),LL(0x0b2e9392,0x8e7c7539), LL(0xe8921afa,0x5ee5f3e8),LL(0xa3100dd3,0x3934ea8d),LL(0x4c8ae6ce,0x955045b1),LL(0x649897fc,0xa54acb5f),LL(0xe7081246,0x4204fab6),LL(0x6dce3a55,0xec3dc968), + LL(0x3ef5a413,0x309b1eb3),LL(0xa81f43fb,0xa7607981),LL(0xbf8a894c,0x87c2b81e),LL(0x0d293293,0x27a40bce),LL(0xe4bf3714,0x7f4c315b),LL(0x01236895,0x03fdc14e), LL(0xdff053fe,0x319c88f8),LL(0xea3fa121,0x146bb448),LL(0xf0dd1380,0xfcc2a05d),LL(0x4acba9fa,0xc8d55b02),LL(0x5927313e,0x871358de),LL(0x17ce294a,0xfd1d81d3), +}, +/* digit=30 base_pwr=2^150 */ +{ + LL(0xff63ae69,0xd3797831),LL(0xce4c7eaf,0xa753de02),LL(0x11a4e339,0x2ff7a6a6),LL(0x5328043a,0x904f86f0),LL(0x12e9f7dd,0xe29d31c0),LL(0xc0a51904,0x8825a639), LL(0xebfc2cc7,0x070c2696),LL(0xc5f7a943,0xc03ce643),LL(0x12c8a1f5,0x5b970d0c),LL(0xab352a83,0x572aaaa1),LL(0x0c5eb0c7,0x63df45a9),LL(0xd4977599,0x95c951e1), + LL(0xbca07a42,0x2c5b0e42),LL(0x7a0dffa1,0xbe57f359),LL(0x9aa90727,0xace48595),LL(0xf658699b,0x32be886a),LL(0xda3b18e6,0xce75d6c6),LL(0x69caf667,0x9d563e4f), LL(0x065eb772,0xc17c66cf),LL(0x4df9f6ef,0xfbe12381),LL(0x623db4ef,0xceb80041),LL(0xc74762e1,0xe75615b2),LL(0x8671c52f,0xade8a543),LL(0xcacaf2ec,0xb713c401), + LL(0x467eb167,0xe6d039ef),LL(0x74696cf9,0xa7e0959d),LL(0x7078d8a0,0xf3a19b9d),LL(0x07cdc6f6,0x5d4ec99c),LL(0x8386eed8,0x4842d0f9),LL(0x545fc0d5,0x48f5ab80), LL(0x6d39c2f7,0x8906fc62),LL(0x1bf5366a,0x1c050d69),LL(0x9f54d0d6,0xac506c57),LL(0xf9e4b94c,0x9a356a6e),LL(0x08a75e61,0x62632c51),LL(0xc6951dc2,0xfc1b9fa5), + LL(0xa4886619,0xa933aaf7),LL(0x4af13c7f,0x9ec1915f),LL(0x854de496,0x25a9dff8),LL(0x247bec15,0xa8b31d9b),LL(0x4661e58d,0x468a25c8),LL(0x786a0707,0x8989c046), LL(0xbb66922e,0x282db8ca),LL(0x45ca29ff,0x73bf240d),LL(0xeaeda06e,0xa2c40faa),LL(0xadd94b47,0x69632929),LL(0xb0069076,0xc72354f6),LL(0x7878e92c,0x8d197fbf), + LL(0xa83bbb88,0x69a9ebd8),LL(0x29f98875,0xcbab0b5a),LL(0x4e7611f0,0x325e487e),LL(0xd955cc3b,0x90aa24b1),LL(0x3c264d53,0x840e70a1),LL(0xad7f4f81,0x15bcf88b), LL(0x2cf0df0a,0xe47552cc),LL(0x79205ea9,0xcb999733),LL(0x10d5ca45,0x25dc58bd),LL(0x1228b978,0x0947d715),LL(0x4f2c7c4a,0x9a0204da),LL(0x4690052c,0x4377ea4a), + LL(0xb8e79179,0x015c325e),LL(0x5b57dce6,0xf4fc6133),LL(0x78d6858f,0x27a51e5d),LL(0x4dd5f180,0x13babcab),LL(0x847e499e,0xfaa19cb1),LL(0x08aaea61,0xe2688ae6), LL(0xe86100d5,0xe20d7edc),LL(0xed2fedac,0xa9b0d46b),LL(0x1d357ded,0x5e99cc0c),LL(0x723cac89,0x4c1263ab),LL(0xf15e22f4,0xad5f3e6f),LL(0xd77dae65,0xf25f3950), + LL(0x37e8e6b2,0x3c0e2b97),LL(0x575da8b7,0xa2037913),LL(0xb925cbb2,0xeedf0a75),LL(0xc561b405,0x4f28ec1b),LL(0x2901931c,0x368fb274),LL(0x2f26221f,0x52b54eee), LL(0x247812a9,0x381845b6),LL(0x9115a0df,0xf9bcc961),LL(0xcb84d25b,0xef127dfe),LL(0xfa10e0a7,0x4256afe5),LL(0x353a15eb,0x0c08a532),LL(0x6a91e61e,0xbbd15b17), + LL(0x6150771a,0x854b0584),LL(0xd9ca9868,0x35fdd9b4),LL(0x4c32fc71,0xec829389),LL(0x9ec8f90d,0x882fad4c),LL(0xc6c7b9c0,0x2d39990d),LL(0xd71a25e5,0x7fbc201b), LL(0x5166da7d,0x6b852e65),LL(0x3d8c6e36,0xc6bde23a),LL(0x5857f048,0x37001154),LL(0x1ccb9bc8,0x746621fc),LL(0x612bb853,0x97e44e63),LL(0x758da4ed,0xabc3b450), + LL(0xbb44db8a,0x856463a8),LL(0x4baf2f64,0x18ec5abe),LL(0x92980518,0x75efa67d),LL(0x94b03911,0xabd300f8),LL(0xc1cd1cf7,0x4ea44bd4),LL(0x124ef41a,0x525c3583), LL(0x6b3a701c,0x03c18c0a),LL(0xcc7b6885,0x5ef82731),LL(0xa00d0089,0xb3716386),LL(0x741c0ea9,0xed9af50c),LL(0x8a36f03f,0x31f0e49a),LL(0xca724a16,0xce993757), + LL(0x9a90c6b9,0x2b6bf5e2),LL(0xa2c0b35f,0x9b134fc8),LL(0xa6717af8,0xd64157f8),LL(0x45dd16f0,0x7228156c),LL(0xdaa99226,0x0a9ab894),LL(0xbccb07e5,0xa7b130f7), LL(0x4d9243d5,0x2b7ab41f),LL(0x88568fa4,0x570b4ed0),LL(0xc9c84d91,0x666b98be),LL(0x02124f7a,0x2a75793d),LL(0x0aa16891,0x0fb9b82e),LL(0x3cc7f2d7,0x71e94c93), + LL(0xf47211c0,0xb7c13bfb),LL(0xe70929ae,0x738fe4a9),LL(0x423db6f3,0x4cdac99b),LL(0xe4255a4d,0x3883201a),LL(0x9730d749,0x7ffe82d3),LL(0xafbaaabb,0x033ba755), LL(0xf836d62b,0xa302ba65),LL(0x143a88bb,0xc626f604),LL(0x31c16b3f,0xe1d189aa),LL(0x7d68ab17,0x4664c050),LL(0xc02eb56b,0xcffc651c),LL(0x6ab49c24,0x6c52f3c4), + LL(0x8fb415b7,0x58775857),LL(0x9e88dca3,0xab580f15),LL(0xa62265d2,0x86a12e3d),LL(0x72d98b08,0x8ec42786),LL(0xf61e9c85,0xb9da8016),LL(0x800994ce,0xa895aedb), LL(0xe38ef526,0x63d0878c),LL(0x1efb6575,0xa081d714),LL(0x6a1c1efa,0x780b9e12),LL(0xebd0497a,0xeed68d0e),LL(0x9265231e,0xbfeee3d2),LL(0x80e03127,0x46f751da), + LL(0x03e4074c,0x806dce0b),LL(0x6973bc6d,0xd4054700),LL(0xa2897b68,0x8c4d393e),LL(0xc7f9af16,0x7d592d04),LL(0x4f895dbf,0x0625826a),LL(0x37dfc8a1,0x038bed29), LL(0x4799d78a,0x981862da),LL(0x6675c1b3,0xf34c1895),LL(0x8706afd3,0x64de9a5b),LL(0xf74e6ca3,0xc80ff68e),LL(0x83ed8cf2,0x26a90422),LL(0x77a47011,0xc1f5ce53), + LL(0x4aabf727,0x0bd15783),LL(0x54fce3ad,0xfe79d2dd),LL(0x1a77ce78,0x242b1806),LL(0xda7e489c,0x30cf6c32),LL(0xb2966f38,0x854e43f8),LL(0xa2dd4ea3,0x6e5fb045), LL(0xde3c9b7a,0xb2a48aec),LL(0x3625ebd6,0x66ac77e6),LL(0x0bcbabe2,0x332a969b),LL(0x5be51225,0x19de2701),LL(0x5b9b80e6,0xf26c73fc),LL(0x91025007,0x98c9cbf7), + LL(0xbc098b8e,0x1e41874e),LL(0x8a234773,0x758ccd5f),LL(0xc1bc847f,0x47ab76ca),LL(0xc540ceaf,0x377f32e9),LL(0x69c2df21,0xba8897c3),LL(0x233c3a02,0x6afacb01), LL(0xfb54ffb1,0xf1609b45),LL(0xb8f9c150,0xb7a98e5a),LL(0x08b1977e,0x607478b0),LL(0xd48b7a90,0xa9500582),LL(0x32fa7597,0xacd841e3),LL(0xf9333957,0xdf53373d), + LL(0x04926a41,0xd25f6508),LL(0x514045da,0x7236b475),LL(0x08b9b08b,0x0b360311),LL(0x3fe92e91,0x16477aff),LL(0x03189ddc,0x6e5f6cb1),LL(0xc698a38f,0x81ff008e), LL(0xc93adb23,0x02a09218),LL(0x445d8fae,0x71fcecd3),LL(0x8fd6b76c,0x55a15eac),LL(0x11ef96b4,0x1e37ec36),LL(0x30e433b5,0xd1b3b3fc),LL(0x51d174c3,0x49518733), +}, +/* digit=31 base_pwr=2^155 */ +{ + LL(0xb8c9f82e,0x7914213d),LL(0xfc038e90,0x7a3e4e38),LL(0x26a34238,0x6edae5a1),LL(0x701ce8c7,0xe566bf50),LL(0x55656e02,0x3562e875),LL(0xb4e8efbf,0x48325ebf), LL(0x66505ec3,0x5f10a504),LL(0x8da78aec,0xd8b9834b),LL(0xcc2f2e40,0x49d1fc25),LL(0xaf5718c1,0xe973bb1c),LL(0xd2d6b890,0x9b8825da),LL(0xe2f00f12,0x7de7885e), + LL(0x7ef79898,0xe37211be),LL(0x21344d16,0xa8103877),LL(0xa1b9f8b4,0xfdcd7e26),LL(0x7d7f72d5,0x5641e45d),LL(0xc449c920,0x5377c1be),LL(0xefc7b2a1,0xd3edcb0c), LL(0xe14b42fc,0xc657a9ff),LL(0x00831b07,0xc8f858c8),LL(0xd020eaa8,0x6bfcd1bc),LL(0x3f6860c7,0x17534b0a),LL(0x84c7c806,0x8ce57222),LL(0x2bd7456b,0xa1d40eaf), + LL(0xc9aa57ee,0xe0c93007),LL(0x8895a604,0xebb2d47b),LL(0xc4fd6ffe,0xb8aebc49),LL(0x73f300b6,0x2c06e1e5),LL(0x81628b8b,0xa019070d),LL(0xbaf8c1ea,0x2db1690b), LL(0xcc94ccd2,0xb3fce6c8),LL(0x85bcdf4f,0xf3014638),LL(0xe2f82c32,0xb1e62616),LL(0x68295a54,0x85581e24),LL(0xbf51f8fa,0x0f2e2ff5),LL(0x155c1f6f,0x940716f1), + LL(0x4e623856,0xaed02b6b),LL(0x3e1d74cb,0x7a6d2bef),LL(0x654e7c30,0x82226ec4),LL(0xe7034bfd,0x008ac003),LL(0x7fd6b555,0xe343c540),LL(0x1b429d44,0xca1b2907), LL(0x9c3ceea2,0xe0702a33),LL(0x732694c3,0x48079aa9),LL(0xd4652401,0x7e6d72f6),LL(0x35f60043,0xd92655ed),LL(0x273e8cc4,0xa0dbaac6),LL(0x3c3ffb40,0x0bb8f0f9), + LL(0xc95cd23b,0xb41b87b6),LL(0x55e371a4,0xb99714ba),LL(0x6f571ceb,0xb138ee8f),LL(0x80146ec7,0x09c42be4),LL(0xee9aa125,0x275ee21e),LL(0x3a878b59,0x0cef4d6f), LL(0xa801068d,0xd436eb1c),LL(0x762b8a80,0xe2c5448c),LL(0xf3640eca,0x243beee1),LL(0x32bbba7a,0xf979458b),LL(0xa63407d3,0x6bc26cfe),LL(0x392dd1d3,0xd3b6e132), + LL(0x3de4ba2e,0xbc06ecab),LL(0x9e491bcd,0xf51ca063),LL(0x453c94be,0xa6fc6fa0),LL(0xed1a6731,0x5460f943),LL(0x4ec3f1fb,0xeb11656a),LL(0xff1e7d4e,0x2fcb2cab), LL(0x8fea2286,0x59526467),LL(0x4e0bee38,0x838117a3),LL(0x24fd2ce5,0x7bdf5888),LL(0x9f2c2925,0x13df0c83),LL(0xdee97f30,0x1bf621e6),LL(0xebea6641,0xb43b2558), + LL(0x8e729329,0x246c8660),LL(0xd693dac8,0x39fcc41d),LL(0xc062a6c0,0x48a65b54),LL(0x6a5a3101,0x368a5770),LL(0x47ed1988,0xd143600f),LL(0xa764ce3d,0x48466d92), LL(0x5a22cb6b,0xb0500613),LL(0xedea070c,0xf1d77247),LL(0x617f2464,0xb1ddd151),LL(0x28b83fd9,0x79050698),LL(0xd70bf93e,0x021abb26),LL(0xab5a5e1e,0x590b3c42), + LL(0x1cfb991f,0x5906a35c),LL(0x740a7744,0xb62a4f80),LL(0x36f84763,0x65c8ac91),LL(0xbe0f1dd3,0xf73b3deb),LL(0xa2d26c21,0x40358868),LL(0x76792ae7,0xd907e90a), LL(0x668c3d5f,0x3ecea167),LL(0x6754b49c,0x731068f2),LL(0x0e006243,0x6db89109),LL(0xdd94681b,0xd29106e6),LL(0xa85a3de2,0xb40b8694),LL(0x936b86cc,0xc80c7bf1), + LL(0x11913575,0x003d45d0),LL(0x87e1186b,0x866cb2dd),LL(0x46b69a22,0x692f6301),LL(0x8174c1d1,0xd296a55c),LL(0x9f17af00,0x77ef6fbe),LL(0x3aa922e1,0x6b588be9), LL(0x033e6dd7,0x99ecb44f),LL(0x1d22b7cd,0x32edea2c),LL(0xba7006f3,0x3122b027),LL(0xbb6ebc5c,0x8950054b),LL(0x82dab805,0x4f6d6061),LL(0x1bae5f1b,0xc1205518), + LL(0xe08c180f,0x28d33e79),LL(0xf6aec9ce,0x768c7794),LL(0xce683c5b,0x5a749f3b),LL(0x8371fe75,0x717629d9),LL(0x57712c1d,0x5e828fc0),LL(0x7e4c61aa,0xb46c6ed1), LL(0x5bccf95c,0x5d927bad),LL(0xd72f68ec,0x55d6fc80),LL(0x98591dc2,0x560a99a3),LL(0x4836664c,0xc885fe8a),LL(0x26d79298,0xd18acd42),LL(0x185df1d7,0x05e4cd17), + LL(0xfcc83355,0xebc60e21),LL(0xd9119b77,0xc94dbc02),LL(0x2f18ae9a,0xceb05a31),LL(0xb8f69016,0xa8462962),LL(0x8f67b5f4,0x58dde5a4),LL(0xaf3c234d,0xb8bdf9c9), LL(0x80e85df8,0xe95c069f),LL(0xab3aa0e5,0x9d525e1b),LL(0x76276d8b,0x73c8a92f),LL(0x163530ef,0x7feb4abd),LL(0x5ef5ad73,0x8ca949b3),LL(0x2e3d057b,0xe129431e), + LL(0x60dec308,0x9d8a925b),LL(0x6b3ea363,0xb72e3efa),LL(0xdfb534b8,0x4f53ca6d),LL(0x6dd78a32,0x4e64874c),LL(0xc2a146d5,0x336e5b46),LL(0x98395201,0x07c76d63), LL(0x8fe3e815,0xa4c09522),LL(0x3221cc26,0x887e659d),LL(0xc36286ec,0x0ff92f64),LL(0xc3ebb08c,0x57b1b903),LL(0x65f00c30,0xc6bdc9b6),LL(0x9a46d36e,0x82624226), + LL(0x1a0b619a,0xc782c16c),LL(0xbe316086,0x8643d42b),LL(0xc0daa421,0x49d2966b),LL(0xb7b487e0,0x080b1caf),LL(0x144de273,0x1d33bb53),LL(0x6faf7ed9,0x8bafce2d), LL(0x408d4636,0xdafbe3cf),LL(0x7ee8835b,0xf10527df),LL(0xe2e75522,0xe1123f3e),LL(0xebe27d60,0xb388c64b),LL(0xe3f1f55e,0x2cb38dc1),LL(0xe34524d8,0x57ff8e43), + LL(0x85653dc8,0xd67dc92b),LL(0x0bc93ab9,0x8e0970af),LL(0x8b87c0af,0xb6f09baa),LL(0x52760ef4,0x5a8a9030),LL(0x1047bf85,0x2e2ae756),LL(0x85bd4e74,0xd049078f), LL(0x3729f708,0xced11ff8),LL(0xd91068a6,0xdd21cbeb),LL(0x24b3e911,0x83d488ff),LL(0x1afd2196,0x6e166fda),LL(0x4f0d2128,0x66a91211),LL(0x05c9f39c,0xd11078ed), + LL(0xbdbdf0cf,0xd87003d3),LL(0x56c298f1,0xe9750b5b),LL(0xb73ad05d,0xc256c3a2),LL(0x2ee94279,0xe0779a19),LL(0x279626a3,0x31d8b3c6),LL(0x90163bc8,0x469056bb), LL(0x23755853,0xe6aeabc6),LL(0x896a6f4c,0x9fffdfe2),LL(0xa36cf41b,0x15c1ce78),LL(0xeee41941,0xd4c8c025),LL(0x7653be9d,0xf7a917ee),LL(0x59d52222,0xfa3cba96), + LL(0x5f8ab132,0x913f9207),LL(0x5c14080f,0xd5b6792c),LL(0x787c3594,0xefab4e2c),LL(0xe7b7b7dd,0xa55d465f),LL(0x34e28e6a,0x921aaad8),LL(0x12d6a7bc,0xc4f3a35e), LL(0x6115a5ae,0x109803c4),LL(0xe709f9a1,0xc023098c),LL(0x99c5bb66,0x1a8c8bdb),LL(0xbc7c2da7,0x1cd1c2b6),LL(0x5f927eef,0x50189c97),LL(0x229f9410,0x493823d1), +}, +/* digit=32 base_pwr=2^160 */ +{ + LL(0xf0ce2df4,0x11a8fde5),LL(0xfa8d26df,0xbc70ca3e),LL(0xc74dfe82,0x6818c275),LL(0x38373a50,0x2b0294ac),LL(0xe8e5f88f,0x584c4061),LL(0x7342383a,0x1c05c1ca), LL(0x911430ec,0x263895b3),LL(0xa5171453,0xef9b0032),LL(0x84da7f0c,0x144359da),LL(0x924a09f2,0x76e3095a),LL(0xd69ad835,0x612986e3),LL(0x392122af,0x70e03ada), + LL(0x6754f492,0x3ee0a31c),LL(0x96769ff5,0x02636c6b),LL(0xf0fbfa96,0x90a64f4f),LL(0xfafea65a,0x513f054e),LL(0x9cf4b9f9,0x796ba747),LL(0x932a9590,0x3198c068), LL(0x549ee095,0x93af8a65),LL(0xa212760f,0xb8b6f72c),LL(0xc1a46c8f,0x23bc71e9),LL(0x4c9bca72,0x000643af),LL(0x848cea30,0xb6d967c7),LL(0x73312ec2,0xe06b6b4e), + LL(0x67aad17b,0xfeb707ee),LL(0x83042995,0xbb21b287),LL(0x9a0d32ba,0x26de1645),LL(0x1ffb9266,0x9a2ff38a),LL(0x8f578b4a,0x4e5ad96d),LL(0x883e7443,0x26cc0655), LL(0x2ee9367a,0x1d8eecab),LL(0x881de2f8,0x42b84337),LL(0xd758ae41,0xe49b2fae),LL(0x4a85d867,0x6a9a2290),LL(0xe68cba86,0x2fb89dce),LL(0x7f09a982,0xbc252635), + LL(0x1d85a725,0x52ec9956),LL(0xf3208012,0x0f9be000),LL(0x6dcc7816,0xe881337c),LL(0x791f7cf1,0xe4e7b6d9),LL(0x59885a42,0xfaa717aa),LL(0xf9c01e41,0xb1bbb5c7), LL(0xa0361880,0xcf208d58),LL(0x20afa350,0x24426e40),LL(0x264ce04a,0x7261871b),LL(0xcd42026a,0x66be4a86),LL(0x829f99fe,0xc5397b77),LL(0x24578e2b,0xffe4a6bc), + LL(0x8c61aaac,0xadc79436),LL(0x5e926563,0x24c7fd13),LL(0x0406c129,0xef9faaa4),LL(0x8b658d3c,0xf4e6388c),LL(0x1e435baf,0x7262beb4),LL(0xfdaeac99,0x3bf622cc), LL(0x4e1aeddc,0xd359f7d8),LL(0xd78c17b7,0x05dc4f8c),LL(0x29498ba5,0xb18cf032),LL(0x85bf35ad,0xc67388ca),LL(0x62aa4bc8,0x8a7a6aa2),LL(0x72f4627a,0x0b8f458e), + LL(0xf822d5f9,0x0733667a),LL(0x18339700,0xd7f81b9e),LL(0xa7bc265f,0x7ca29b27),LL(0xeb4f0c7a,0x9fefa698),LL(0x01f27630,0x7b6f3513),LL(0xfcfb1133,0x72f0f152), LL(0x5c81eb14,0x9928d9d0),LL(0xed8ff6cb,0xa16ac36b),LL(0xe041bef3,0x7fbd1acb),LL(0xf8d99854,0x7d25159a),LL(0xdb5a0dc5,0x2ec3a7d8),LL(0x87e3e933,0xd86fc4cc), + LL(0xc68e4488,0x3fb812ee),LL(0x60ef7281,0x53c5eaa4),LL(0x8fbefbe4,0xe5724183),LL(0xa4b24a05,0x2b7d49f4),LL(0x710c0a43,0x23b138d0),LL(0xa85ec1db,0x16a5b4c1), LL(0x305feb02,0x7cc1f3d7),LL(0x5b6c1b54,0x52f7947d),LL(0x8f56981c,0x1bda2312),LL(0xb4080a01,0x68663eae),LL(0x9f999b7f,0x8dd7ba7e),LL(0xb686580c,0xd8768d19), + LL(0x4c20e15f,0xba8418f3),LL(0xfb54404e,0x7eed2494),LL(0xbce1e82d,0x4e6438d7),LL(0xb397915b,0x9e489b3e),LL(0xfb4cf659,0xa9baea9f),LL(0x42ef4aff,0x8bc5b2ba), LL(0x7e62a188,0xae3fb533),LL(0x496e8e35,0xcd648493),LL(0xdefe047b,0x89728e28),LL(0xd24e60fe,0x63a8c679),LL(0x470f710c,0xadacbf92),LL(0x5e198d3c,0xd470aeb9), + LL(0x7afdda94,0xbcd0e0ad),LL(0x34a30687,0x95a0dbbe),LL(0x8c5e2665,0xbbe3c3df),LL(0xebf2bc16,0x742becd8),LL(0x3fa163a6,0x300ceb48),LL(0x4663354b,0x0c5d02ee), LL(0xb5e606a4,0xe4fb9ad6),LL(0xcf49ff95,0x93f507b8),LL(0x585c193b,0x9406a90c),LL(0x4ecf9517,0xad1440c1),LL(0x9cea53f1,0x184cb475),LL(0x8ef11302,0x6855c474), + LL(0x7a3e874a,0x8e3807dd),LL(0x89ac3a99,0xc4edb45b),LL(0x4bfd77d2,0x9ba9cdaf),LL(0xb540fffc,0x31d33f59),LL(0x0c60028b,0x404c8779),LL(0x89688c81,0x7f89da71), LL(0x504b862b,0xdd3390e5),LL(0xe937efe3,0xdf1e721b),LL(0x63e6036f,0x5833d0df),LL(0x385fbab4,0x7712527a),LL(0xd210c0d4,0x6347236b),LL(0x8d238e2d,0x12d7733c), + LL(0xedcafa52,0x00ecb523),LL(0x086f69d3,0x0da0ae0e),LL(0xc242f347,0xc384de15),LL(0x848c12b7,0xfb050e6e),LL(0x64e015ce,0x22f67654),LL(0x7ca122f2,0xcbdc2a48), LL(0x445fb02c,0xa940d973),LL(0x3767d89d,0x00f31e78),LL(0x613dabdd,0x2b65a237),LL(0xc875ae09,0x2be0ab05),LL(0xba204f8e,0xb22e54fd),LL(0x0f7687b9,0x65e2029d), + LL(0x302e943f,0x0ecb0723),LL(0x4a443e78,0xd180ca1e),LL(0x23dd2c9e,0x39e78911),LL(0x01fe50bb,0xfa2a4404),LL(0x154d39d1,0x4678e7ed),LL(0xaf513e01,0x64ddaee1), LL(0x634904da,0x6d4c615a),LL(0xba5c900c,0x937c6326),LL(0xeb6c8582,0x70658f5f),LL(0xf3d65166,0x2a04fd51),LL(0xb676eb47,0xcefe7472),LL(0xf597d887,0xd3565a71), + LL(0x1855a71c,0xffd82538),LL(0x438bd8d8,0x26a330b3),LL(0xf9d8c5f9,0x89628311),LL(0x953738a0,0x8d5fb9cf),LL(0xedfcd4e5,0xcb7159c9),LL(0x2064c7c2,0xd64e5230), LL(0x689f3cfe,0xf858ed80),LL(0x56128b67,0x4830e309),LL(0xe0e90688,0x2e1692da),LL(0xca9cc232,0xab818913),LL(0xa5d229a6,0xe2e30c23),LL(0x0e740e23,0xa544e8b1), + LL(0xe5dcba80,0x299520f4),LL(0x2b758045,0x522ad4b5),LL(0x193b36d4,0x54eabe27),LL(0x45e9e442,0xda4d3bff),LL(0x637311f3,0x44cb9252),LL(0x71338ebf,0x4cd620a9), LL(0xcc9524fb,0xec908157),LL(0xa8c955d7,0x2731a11b),LL(0x5cb94009,0x72a5e054),LL(0x9126cfe8,0x7eee8f3b),LL(0x3dd5d5ce,0xc71e2920),LL(0x22069494,0xe886f91a), + LL(0xdc61e6cc,0x1c15e569),LL(0x58fc7800,0x8fd72967),LL(0x37a9dfc5,0xe61e7db7),LL(0x5afd7822,0x3f34a9c6),LL(0x19e80773,0x0a112742),LL(0x4760fc58,0xa353460c), LL(0xb3124c71,0x2fb7deeb),LL(0x2d4009cc,0x48463627),LL(0xc3a10370,0x399d1933),LL(0x54388dbd,0x7eb19450),LL(0x7c2a006a,0x8ecce639),LL(0x55c932a0,0x3d565daf), + LL(0x0db962c0,0x294d2955),LL(0x6d523ab0,0xd6994ef4),LL(0x58f95037,0xfa1a7f91),LL(0x64420c94,0xb1379811),LL(0x093caea8,0x2b686e1e),LL(0xf9e1c340,0xdef10944), LL(0x611d9bf5,0xcd1beecf),LL(0xa1b5267b,0x34696c50),LL(0x2dfc2b16,0xcecbc719),LL(0xcee7e854,0x2cdb955d),LL(0xf2635cc8,0x9fefc321),LL(0x2936f7d3,0x276d2e4f), +}, +/* digit=33 base_pwr=2^165 */ +{ + LL(0x67141724,0x4962c021),LL(0xabe7762f,0x5f81eabe),LL(0xdd189c3f,0x78549a79),LL(0x6ce517a7,0x47675cdd),LL(0x32d6bb97,0x5102294e),LL(0x6ed1a029,0xb19500c6), LL(0xb16a206c,0x3efb54e8),LL(0x0dc135b8,0x7dbdcc25),LL(0x8967fb04,0x955bc294),LL(0xbe04e909,0x373615c9),LL(0x111efad6,0xf1fcf820),LL(0x6fd2e97a,0x8530f97d), + LL(0xb4805410,0x3f2b5bd4),LL(0xf96c5ee7,0x201ca7a9),LL(0x94256fe1,0x532ef2db),LL(0x318ddb03,0xacbfc459),LL(0x5f24c8e1,0x2375f9fd),LL(0x370783db,0xd27c479b), LL(0x56541ae6,0x1bd461e8),LL(0x7f7ea49a,0x78f054a7),LL(0x8845f315,0xc9f8777d),LL(0x97fc92c7,0x81aed296),LL(0x49929540,0x9f2f8d79),LL(0xff5ebfe0,0x7531e78b), + LL(0x543b3e41,0xbd9a66d6),LL(0x2ae73774,0x2948c0a6),LL(0xef38e9b3,0xa75151df),LL(0x754fb3fb,0xa3348ae5),LL(0x13069b72,0x1218fa8f),LL(0x0835dfaf,0x532bb051), LL(0xdf2be3c6,0x2121a98e),LL(0x9e5199bc,0x85980de6),LL(0x1a1eb6ee,0x1b23a4be),LL(0xadeb3ae5,0xb5c48b92),LL(0xedea2b45,0xeebd305d),LL(0xc37198ea,0x20543f04), + LL(0x0fab968c,0xd0960bd8),LL(0xae028db0,0x6899e4fa),LL(0xa9850916,0x975ccc77),LL(0xe5f81554,0xb41bd531),LL(0xc8cff2c8,0xbdf8ab57),LL(0xf5822be3,0xea306a01), LL(0xbefbdbbe,0x1f0ac0e7),LL(0x60519f87,0x72f4b0e9),LL(0xe3cc86ab,0x22bd8b82),LL(0x2b2beaee,0xc43bde8d),LL(0x412617ff,0x8168781e),LL(0xb7ee7096,0xc5610627), + LL(0x40671bd2,0xc4085538),LL(0x599f8eba,0xccb74902),LL(0x8d65e832,0x477a4a09),LL(0xf1241626,0xc620c314),LL(0xe7344054,0x05f2f152),LL(0x6d83320d,0x2483a2d9), LL(0x0e344da8,0x167439d7),LL(0x1002fb36,0xa0c02b1b),LL(0x30afbda2,0x46cb4a70),LL(0x229d4efe,0xe74e3488),LL(0x1cef3aec,0xd371dce2),LL(0x7c3f2521,0x96e0592c), + LL(0xcc5f4a6e,0xdec0e091),LL(0x201108d0,0x055ff295),LL(0xdc202800,0x2b371998),LL(0x0d5f5f9d,0x1b650d83),LL(0xa0226262,0x29be5503),LL(0x185bf3f1,0x0f3681ac), LL(0x8c3e2c4f,0x4f5c44b4),LL(0x717814fd,0xcfe74a51),LL(0x7b52a561,0xb0ce4183),LL(0xee634895,0xde143e3a),LL(0x48d46b2f,0x08f83100),LL(0x6386486d,0x34b79d55), + LL(0xee1388ba,0xa60659c4),LL(0x7eca29dd,0x475a4d06),LL(0x66470e08,0xf1ef88c1),LL(0x687c716a,0x71cac87a),LL(0x86f43fff,0x994fb1ee),LL(0x43384658,0x53ded2ef), LL(0x56c41587,0x317d9024),LL(0x9dea0f26,0x6807f0ad),LL(0xa0b0d53b,0xfee8beaa),LL(0xb0288c94,0x15c06a1f),LL(0x47028bce,0x4b9eab03),LL(0x1446bc6e,0x6d214435), + LL(0x01a8eb44,0x0869457a),LL(0x7a7bedd7,0x52223985),LL(0x00057505,0x2c04b0c6),LL(0x0b09adeb,0x468be6e8),LL(0x6f81474f,0x2f3bf32b),LL(0xa712ccce,0xf54f949d), LL(0x4cdd8f2a,0x292cee42),LL(0x9c221be1,0x3d9fdf6b),LL(0x56f47b2a,0xe54da661),LL(0x840b5d1b,0x2ca76835),LL(0x8a6e8cf6,0xb52adb6a),LL(0xdade153e,0x8b416a6b), + LL(0x3fd55732,0xb8c3a138),LL(0x2fd63498,0x4b348243),LL(0xf52c44d3,0x60cc7a0f),LL(0x9422c87e,0x9787f356),LL(0x60ad9f57,0x0fae6177),LL(0x82e307c4,0xb9ac12d8), LL(0x79416b16,0x52316618),LL(0x91611196,0xe603cb9a),LL(0xe34c3a39,0x0ce22a84),LL(0x5b2dca8b,0xcb191237),LL(0x9e5b750a,0xcb87c227),LL(0x13a02f00,0x7feccba0), + LL(0xa3cd6034,0xd3a66685),LL(0x3a283c3a,0x74ad77ad),LL(0x66644cd0,0x0c903afb),LL(0xc1f90202,0x34e18018),LL(0x0008aa04,0x8fa168e7),LL(0xbe8e35ae,0x871573df), LL(0xf4561f77,0x8841591e),LL(0xc6cd0f01,0x55e3033d),LL(0xfe1fa6ff,0x44327c97),LL(0xdddfcba8,0xed4e69d6),LL(0x52d907ec,0xe82e1e42),LL(0x79064b8d,0x8a5d9a71), + LL(0xc26f1000,0xa47a884c),LL(0x44a4b7cb,0x9f047634),LL(0x89813d5f,0xa5a2bf4e),LL(0xd8e9318d,0x83ce02c9),LL(0x2c86c874,0xf2731254),LL(0x02a0813f,0xb76a3096), LL(0x0c8b505d,0x1fabaa2d),LL(0x4895425b,0xad693de0),LL(0xa55ff754,0xaf7f5848),LL(0xeadfa222,0x098a328f),LL(0x470c5898,0x4c20adfb),LL(0x5d199733,0xe4b23ead), + LL(0x9a605b1a,0x37b29ca7),LL(0x30caed34,0x2ca364f6),LL(0x3c2ff02f,0x1e538aae),LL(0x42c6a320,0xc10c493c),LL(0xa2b9e130,0x92f18f28),LL(0xdd0ed08f,0xaf249c41), LL(0x70285f2f,0x42039a52),LL(0xcfd3ebb0,0x4e502f2e),LL(0x6e39b30f,0x42821914),LL(0x70e820ca,0xdbc809f1),LL(0xd2781e34,0xbccb5567),LL(0xbe3d05dd,0x8c1e3bfc), + LL(0x43eeed0a,0xa29f0b65),LL(0xfd8b3697,0x0b96b6a1),LL(0x88f8755a,0xc2454ada),LL(0xaf85d4ac,0x57202337),LL(0xa7aaef40,0xaddfc388),LL(0xb156a5fc,0xc1495163), LL(0x1f1a8775,0x67abbbcb),LL(0x5958bb8b,0xb83e3dd6),LL(0x36dbf23c,0x17119d02),LL(0xb954337a,0xeb336460),LL(0x6f46dca7,0x9b101001),LL(0xbc991dbe,0xef862ae8), + LL(0x66befae3,0xaa878db5),LL(0x05110c6f,0x28bb9c9e),LL(0x4caa069a,0xc3a57a8c),LL(0x594a2753,0xbb5b550e),LL(0x5187afb8,0x01ab8056),LL(0xb9255f65,0x1f7c9ed3), LL(0x146f6635,0xcd669e2b),LL(0xcb9457a3,0xa8f2d4b6),LL(0x849dba46,0x0f0541aa),LL(0x2cc9c7e9,0x2537bf02),LL(0xd79ac77e,0x872b4f59),LL(0xe0a44aa9,0x705c2219), + LL(0x3849051d,0x03b42dbb),LL(0xf27a63a6,0xe2efcfe3),LL(0xceb478c2,0xf709a5ff),LL(0xc4f7feda,0x2cc86b82),LL(0x066a1c08,0xefa834e4),LL(0x309fd644,0x153b64ef), LL(0xe62168ff,0x8cff4eb0),LL(0x095d9f3b,0x0d7781db),LL(0x10bce338,0x01f8e1af),LL(0x139d8f2b,0x14aa9a02),LL(0x259ec819,0x1985d844),LL(0x3a072e8e,0xd7758b21), + LL(0x8565afc9,0x65f7d2c1),LL(0x70fa7b82,0x764c8971),LL(0x986436f2,0xe268634c),LL(0x33356165,0x6334d8d1),LL(0x9ec7957d,0xf1716426),LL(0xb8093983,0xae834331), LL(0xd2dfcce7,0xedb1fe5c),LL(0x68463e5c,0x6195b863),LL(0xa691b665,0x746e5f4d),LL(0xe1e2727e,0x61171291),LL(0x6f27b029,0xbb4aa8f1),LL(0x7f42c197,0x1037657d), +}, +/* digit=34 base_pwr=2^170 */ +{ + LL(0x0d5b855a,0xfe19901b),LL(0x2f745022,0x5facb955),LL(0x56c4ce5c,0x92fd0125),LL(0x938c89ab,0x23172d65),LL(0xaaa587b1,0xa71f8a33),LL(0xb55c9c50,0x511a3745), LL(0x7185086e,0xec005f6a),LL(0xf894c6ab,0x6dfc2761),LL(0x9e26361f,0x98a4d67f),LL(0x21389c25,0x7f0a2b23),LL(0x95ffbcee,0xd1588207),LL(0x9f36a888,0x4d6b29ab), + LL(0xd0a701a5,0xeccb421e),LL(0xb60cd286,0xad4cb9a5),LL(0x05a53972,0xd344da9e),LL(0x7bc99fea,0x3a8035e0),LL(0xc0f77bf5,0xe0214485),LL(0xe54df78a,0x50ada30e), LL(0x4ec2d576,0xdef45af6),LL(0x5f9a8678,0xa05d6184),LL(0xc337e017,0xa9b17db1),LL(0xb84671d5,0x026a4f66),LL(0x3b7d696d,0x60614234),LL(0x81cfd22a,0x71ed9aaf), + LL(0x439ada39,0x1b76a3c5),LL(0x89236ae5,0x818829cf),LL(0x750f8129,0x2277cb7a),LL(0x4d46502b,0x44aa462a),LL(0x64f06dc8,0x7a12e1e1),LL(0xba5630cf,0xb9a3300d), LL(0x55b05f4b,0xd2cc8d9c),LL(0xa700be7a,0x6d0b0b88),LL(0x9617500c,0xa7be9969),LL(0xc03f8a50,0x2b5b8dea),LL(0x785b3dfd,0x712f703e),LL(0xccf93950,0x96a5a60a), + LL(0xee828fba,0xfeb984b3),LL(0xe2bd188c,0x8273f830),LL(0x3ca0a99f,0x177ef97e),LL(0xacc000ac,0x76d4796d),LL(0xb140f51a,0xbad0fa6e),LL(0x06ebc810,0xb2756567), LL(0xa18cb32f,0xf89eb78f),LL(0xa65285b0,0xcfc37eae),LL(0xb25e9d1b,0xe2b29cfb),LL(0xb4e7aef3,0x9388ea8f),LL(0xe267e845,0xee606c12),LL(0x9f5806d7,0x6b103c54), + LL(0x3766f2ae,0xf418e3f6),LL(0x053ef1c1,0x4a3ad3c8),LL(0x560db262,0xd01e5b5b),LL(0xc02bf4c3,0xa583edc7),LL(0x52f318d3,0x7c9f7060),LL(0x1f5e1ffe,0x0852556f), LL(0xfeb0e63c,0xe1c70aa7),LL(0x89a8c058,0x59f0a3f9),LL(0x1ffc0ade,0x4aa4cf02),LL(0x38a78632,0xbb880e41),LL(0x6f28f096,0x35b0f759),LL(0xd5757d7d,0xf9c4fe17), + LL(0xfd6376eb,0x78b8879c),LL(0xc01e1edb,0x22a76461),LL(0x369cf0c4,0x6a44be39),LL(0x5ae54539,0x6653670d),LL(0x6fb43ad0,0x257bd751),LL(0x12baffdd,0xb3ac3715), LL(0x7548eabb,0x48659d61),LL(0x0cd468cb,0xd8f931f8),LL(0x49e3b531,0x98f02415),LL(0x70df011f,0x90b0d716),LL(0xab98f066,0x26d73c54),LL(0x88475d5e,0x06591ec9), + LL(0x412b84c3,0x627f6328),LL(0xa04545d2,0xd427e977),LL(0x104f25c2,0x5b0145bc),LL(0x2ac7ad62,0xa6931c4f),LL(0x1f8d42f5,0x40761143),LL(0xe7f8a0b3,0xfda5a76b), LL(0xfe0946b9,0x4f1ca5cf),LL(0xbeb2d427,0x6def7b9f),LL(0xc9a0d136,0x984bd4bb),LL(0x5b3af1c1,0xb9a77823),LL(0x38ac2087,0x04ee66ae),LL(0x26d9dbb9,0x63374ed9), + LL(0x44ba39e6,0xcf947c06),LL(0xedfe78d7,0xf5d5216c),LL(0x5f1835c9,0xd00115c0),LL(0xd8c79d90,0xdf084152),LL(0x6db5f791,0xc0c3a684),LL(0x749b18cd,0x40514451), LL(0x734df3f1,0xd314b7d5),LL(0x7f541415,0xbccdd3f0),LL(0x6855a942,0x97ed5af0),LL(0xe9d02ab9,0xea84ae9e),LL(0x3238a5d0,0xb87e9034),LL(0x650a0eab,0xd12d25c3), + LL(0x86a515a9,0x1473b55b),LL(0x3b337c64,0xa9e3230a),LL(0x9db668f1,0x7e8bf904),LL(0xf27f9fc9,0x1db2c25e),LL(0x2d9e467e,0x0c108607),LL(0xa3f00d52,0x4505579a), LL(0x240400a7,0xe2ad661b),LL(0x11af4874,0x8022294c),LL(0x78bba8e8,0x29e90370),LL(0xf6baca04,0xbf0fbf08),LL(0x4101fab0,0x2e46d2b7),LL(0xc61089e6,0x66065490), + LL(0x09f8a1cb,0x2131ce5b),LL(0x8ab129e2,0x7b373ed2),LL(0x77c1292a,0x463cc8d6),LL(0x94ffe9c5,0xa9b7cf65),LL(0xb99bfc4f,0x129125ce),LL(0x9820d323,0x819b4284), LL(0x76541a41,0x3f709763),LL(0xe32c7a7b,0xfd679ae5),LL(0xf65b6b3c,0xc39a208d),LL(0x50002745,0x1c22ebc0),LL(0xe2bcd202,0x268f19dd),LL(0x9c3d4266,0xfeac809c), + LL(0x87dcdbdb,0x07467837),LL(0x320493d8,0x4cce33be),LL(0x713c7746,0x9ab08cbe),LL(0x9c6dc5cb,0xd6f0c1de),LL(0x2ac03761,0x19400538),LL(0xd0547be5,0x3fc11f38), LL(0x819fe3fd,0x66b378ce),LL(0x3700fe7e,0x6a590acc),LL(0x8924b396,0x4c976a72),LL(0x70b9b250,0xa5006d8d),LL(0x12b85f9c,0x2fdce1b2),LL(0x495f8f1c,0x5858f7ce), + LL(0x903ff177,0x357540ab),LL(0x276af514,0x225280b8),LL(0x14d7fed3,0x33d273ac),LL(0xd186ee3d,0xfef6b9ff),LL(0x01a7b1d9,0xa94c2071),LL(0x50bc8bc2,0x4ea36274), LL(0xfa98a918,0xc68959c9),LL(0xc7bdc262,0x8f5eccee),LL(0xe6861310,0x7a73a4fc),LL(0xc828330f,0x19bcac90),LL(0x7ef74fdb,0x73e3b66f),LL(0x52d8f2f4,0x60f76983), + LL(0x7e03a14e,0xab357804),LL(0x8caf673f,0x0f4f2868),LL(0x66530425,0x919e661e),LL(0x91ba47c5,0x28da445c),LL(0x66c394fe,0xd6d05375),LL(0x02e8ae91,0xfe1864a3), LL(0xa753aec4,0xd34baca2),LL(0xa2c8d292,0x43b7ffe7),LL(0x04efb8f1,0x496659eb),LL(0xe0252dfd,0x310ec2a9),LL(0x9168a80e,0x98173d2f),LL(0x31497255,0xa3e018d6), + LL(0xd9d9284a,0x3266c887),LL(0x73646ab7,0x690f818b),LL(0xaf7fc33b,0x67315ec6),LL(0xc30b1ccb,0x181e61ab),LL(0x105a9e1c,0x1b81e6cd),LL(0x5078b9bb,0x62a15daf), LL(0x6fa8cc65,0x74f9840f),LL(0x43388573,0x356b7774),LL(0x06b3fd46,0xba0f7d05),LL(0x92b4fdad,0xb0ac864c),LL(0xef192cde,0xcdeac253),LL(0xc313b4a7,0x0c24810b), + LL(0x1adb09b7,0xef8c40bf),LL(0x0b74992a,0x2efeb49c),LL(0x2b79957f,0x3f0f8a41),LL(0x87a06873,0x08927bfe),LL(0x9288cb9a,0x1f63a410),LL(0xdf2b373a,0x8c66fb70), LL(0x980facae,0x98da4712),LL(0xd819d026,0x15ce5b17),LL(0x749a671a,0x097571a5),LL(0x894dd269,0x85a40804),LL(0x34cb6797,0x3e89c13c),LL(0xd07119a4,0x2d19d5e4), + LL(0xecbafb80,0x58225208),LL(0xaa73d6de,0x4f212035),LL(0x62fe86db,0x1224e455),LL(0x2dc5b2f1,0xa8c8a478),LL(0xc3096555,0x8a957b8d),LL(0xb1591452,0x6a3248b0), LL(0xcb604c18,0x1e563c58),LL(0x9bf1045e,0x32808cb5),LL(0x9462e7a2,0xf8f62de9),LL(0xc2489214,0x6b3dfe91),LL(0x2174639c,0x6c1d8fc4),LL(0xef88d4b5,0xdfca11b8), +}, +/* digit=35 base_pwr=2^175 */ +{ + LL(0x18690ad0,0x5a4a5ce4),LL(0xfe27f51a,0xd0f788e0),LL(0x4efe9a30,0xd459388e),LL(0xef9d074b,0x3a45c11a),LL(0x93ab9cb0,0xf68ab50b),LL(0xecd9a566,0x62fbc397), LL(0xcc587a7e,0xbfb79b7f),LL(0x92870bae,0xfcf4d66f),LL(0x877390f0,0x4f31aa21),LL(0xe314cfb5,0x2de0c645),LL(0x238eab12,0x56d904f6),LL(0xccb4d4f6,0x4d104a42), + LL(0x29358cd3,0x3eb83a87),LL(0xb9c6d430,0xad741295),LL(0x53abe4e9,0x57b8c77a),LL(0xbb9feb82,0x0a14673e),LL(0xf26f922e,0xc0a6cbf7),LL(0xa32e526c,0x213de299), LL(0x7b6ca858,0xca417e67),LL(0xfc2e0900,0x8d6ae0f7),LL(0x62e135dd,0x2bae0e7a),LL(0xa7ee82c7,0x962bdcae),LL(0xe5776c74,0x573d7f6a),LL(0x6ffbefeb,0x9c4de649), + LL(0x09335d38,0x8c962fc8),LL(0xeb38d176,0x26d1bc81),LL(0xc47711ed,0xe1aeb295),LL(0x6cbe3e4e,0x0812b992),LL(0x0ab9805d,0xeecacaf9),LL(0x3521a0ad,0x82fefbaa), LL(0xe2c31b9d,0x3a6948c0),LL(0xe82daf2b,0xb7d3905b),LL(0x25a34c37,0xbd3ac90e),LL(0x61453063,0x55afd99b),LL(0x90b99303,0x56d87cd1),LL(0x97ddb0a3,0xc9bf82dd), + LL(0x68916917,0xcbc0bb19),LL(0x1094bf88,0x0bbb9f92),LL(0xd3806442,0xf62cb350),LL(0x397a7602,0xe4d2f1cc),LL(0x43987d82,0xa54bd48e),LL(0x4f0a19fa,0x77b6f831), LL(0x6e766443,0xfa0c9a45),LL(0xf51ba70b,0x995ae0ff),LL(0x9cbd8d33,0x8e242c5b),LL(0x13d97956,0x1671eb08),LL(0x40da55fa,0xccae388f),LL(0xf376dce5,0x97cc48fa), + LL(0xe8c91718,0x1c2919bb),LL(0x5097bde3,0x9dbb727a),LL(0xf8ea2fb2,0x23f87ae7),LL(0xba310121,0xe1bfffdc),LL(0x75329669,0x5938c50c),LL(0x0549855c,0x716c63e0), LL(0x654814f0,0xe091b0c9),LL(0x0e43daee,0xa20535d1),LL(0x593ddd04,0x16ce68b2),LL(0xf59900bd,0x7813a49a),LL(0xd3e5d232,0xef0d3eec),LL(0x0ee3fd4d,0xe7d12cc4), + LL(0xef01fc5f,0xe54d92cd),LL(0xdda2e25a,0xc46c2ab8),LL(0x849f6142,0x7c907fd2),LL(0xacd0202d,0xbb11dd2d),LL(0x1d92d19a,0xa4913a70),LL(0xcf610677,0xe9a26ae0), LL(0x538943c5,0xfff1e1d5),LL(0xa47b2204,0x5943dcc4),LL(0x92cabf71,0xcafcf33a),LL(0xe329d1ad,0xd571e13c),LL(0x7a9a0e4c,0x7626ad23),LL(0x130d7f86,0xf0aa0d9f), + LL(0x19e6aa7e,0x09df3a44),LL(0x5841b1cd,0xe27ad047),LL(0xbde75934,0x02d2a69f),LL(0xfd9ba435,0xb0e05e53),LL(0xe008c16e,0x4732d88a),LL(0xea72110d,0xdebc4777), LL(0x2e3143ad,0xccb7d993),LL(0xea8cd06a,0x674f3753),LL(0x051562cf,0x56012a7a),LL(0x25f74cd6,0x961df684),LL(0x214d8a95,0x26630e71),LL(0x65d92f84,0x584e8d63), + LL(0xebc5557c,0x8a89daef),LL(0x275e1649,0x7ca71403),LL(0x5b80bb4a,0x48d92377),LL(0xa45b3626,0x0a587c52),LL(0xc75bfe91,0xdaff503c),LL(0x116d07d7,0xd845d3e6), LL(0xa51eeca2,0x6b5a4715),LL(0x74481991,0x34ac02bd),LL(0x595abf8d,0x8f076cfc),LL(0xed0391ce,0xc9de4ce9),LL(0xe1fcabd3,0xaaaad03a),LL(0x87b199ed,0x8d48ec00), + LL(0xae5dd482,0xbd0f2653),LL(0x060032dc,0x59f968dd),LL(0x67283310,0x6bea33e0),LL(0x012aa50c,0xccce88cc),LL(0x66838f46,0xbb6d7f2f),LL(0x05ec9bcb,0xb764c95f), LL(0x51477cca,0xd097b604),LL(0x82b20a85,0xc2fbda7b),LL(0x24e9ca8d,0x75fe07a4),LL(0x0cc40d01,0xfc4fa824),LL(0x0c0e95f7,0x0b17d5f9),LL(0x6e1e46dc,0x285e6e8a), + LL(0xbc9b2654,0xb0641d09),LL(0x8aa8fa35,0xf9fcc2e6),LL(0x00d5ec6e,0xd12a5b4b),LL(0x5569d89a,0x9be1a111),LL(0xffac7208,0x9c0566de),LL(0x7034edf1,0x7a9fd4ff), LL(0x9571c375,0x636aeb6b),LL(0x55cdf187,0x60d05aec),LL(0x734e9d2f,0xf4e2f898),LL(0x5ccdc6bc,0xdaf74219),LL(0x608a4f28,0x9d39249f),LL(0x8820e2c3,0xb5f1bb5e), + LL(0xd9589548,0xd02e9936),LL(0x5341402f,0x8f1bf575),LL(0x057300aa,0x1535a443),LL(0x65d29324,0x3062478e),LL(0xc656a3f3,0x4203351f),LL(0x6569c4ff,0xbeb21b51), LL(0xe1f0f263,0x8113ce70),LL(0x03f9320c,0x59d12939),LL(0xd08f8936,0x95061255),LL(0x97d4b705,0x8be3c0f9),LL(0x827837c2,0x0259742e),LL(0x95c65cda,0xf55ea28d), + LL(0x603dc3dc,0x62024812),LL(0xefd67b57,0x25dc5337),LL(0xd7f033fd,0x86b3eb38),LL(0x32646d6f,0xee3226b2),LL(0xf1dae596,0x8c4825f6),LL(0xa5bcb8e5,0xd2303055), LL(0x3c0baa76,0x904a5349),LL(0xe08646a7,0xe60f6125),LL(0x21d45f89,0xaf6a329f),LL(0x06605546,0xf20ad88a),LL(0x19a93d14,0xcf7a0e96),LL(0x91c97174,0xf1eabcc8), + LL(0x8f02af51,0x72b76e9e),LL(0xd580f95a,0xac94cbf1),LL(0x01d854a4,0x2e9cd748),LL(0x1f08a1bc,0x4ed4e906),LL(0x9d2bd936,0x0a2b2841),LL(0x51c89dda,0xbf863500), LL(0xe3f00bf5,0x9407b0e7),LL(0x28b57ac1,0x6b1f71ff),LL(0xcd28801f,0xc1dfe03f),LL(0xafa55309,0xf3d83d64),LL(0x8af8f76f,0x47aafba2),LL(0x6604b2e9,0x54eed45f), + LL(0x0f3e541f,0x59edd264),LL(0x82b76ba8,0x318674b5),LL(0x4e7f0716,0xbf4a0d30),LL(0x19b88200,0x36fc0e41),LL(0x40da801e,0x91db5602),LL(0x2c72c2c7,0x638371ad), LL(0xd5822da7,0xfe960c25),LL(0x4a7415e1,0x7a7571d1),LL(0xbccc1576,0x5a6480fe),LL(0xc3c88f47,0x72f4e5e5),LL(0x9a7bd8ec,0x224e7e74),LL(0x7631455e,0x3ebbf52c), + LL(0x8608ab37,0xae3c2bc0),LL(0x39f336b6,0x35e3da8c),LL(0x81f44511,0x74136642),LL(0x1d8506e7,0x21ce7c51),LL(0x846165f1,0x9b6718b3),LL(0xf5cabf6a,0x9e455007), LL(0x02611073,0xec582a0e),LL(0x83bf042e,0x269aa18d),LL(0x86306757,0x7c54fb7c),LL(0x1b948faf,0x45333602),LL(0xb7025d73,0xd3a5c508),LL(0x428471e4,0xcd6e555b), + LL(0x11a224e6,0x42c9fad5),LL(0x69b2ac26,0x6b6aeb8b),LL(0xb149854b,0x0cf4c7fd),LL(0x2fc359eb,0x4a7d9000),LL(0x29ec8603,0x9ff0c3ea),LL(0x9b24ee14,0x157ae785), LL(0x8979e9bb,0x638c809a),LL(0x7869d8c5,0x347dfb2e),LL(0xa07ea547,0x2fb1e0f8),LL(0xaecdec3f,0x1e580d32),LL(0x0f74025b,0xbbf89573),LL(0xdd529164,0xeb94d71b), +}, +/* digit=36 base_pwr=2^180 */ +{ + LL(0x8d688e31,0xfa2db51a),LL(0xa09c88d4,0x225b696c),LL(0x6059171f,0x9f88af1d),LL(0x782a0993,0x1c5fea5e),LL(0x4ec710d3,0xe0fb1588),LL(0xd32ce365,0xfaf372e5), LL(0x26506f45,0xd9f896ab),LL(0x8373c724,0x8d350338),LL(0xca6e7342,0x1b76992d),LL(0x6fd0c08b,0x76338fca),LL(0xa00f5c23,0xc3ea4c65),LL(0xb316b35b,0xdfab29b3), + LL(0x04a8313d,0x14f962e4),LL(0x5f1f5a26,0xc6e3e7c4),LL(0x79e777be,0x2c0e11c0),LL(0x4657c31b,0xa1705efb),LL(0x3c494de3,0x02688fd2),LL(0x412a8718,0x75664a84), LL(0x7a422f8a,0x878fc7ad),LL(0x7419bd0a,0xe5d581df),LL(0x704b70c0,0x7c813c4c),LL(0x7323c008,0x98553da8),LL(0x63089f1a,0x4f63cec6),LL(0x9655d291,0x9626d6fa), + LL(0x483aebf9,0x84e5541f),LL(0x49165772,0x8adff7dc),LL(0x9beaad3c,0xe0a43ad6),LL(0xf51c2714,0x97dd1820),LL(0x57ea5b0c,0xac2b4cb4),LL(0xd11767ca,0x87dbd011), LL(0xbfc7957a,0x18ccf36c),LL(0x1bc79227,0xd4a08841),LL(0xd8d292a8,0x9811ce43),LL(0xd58c4ee7,0x72c5fc68),LL(0xd35c65a7,0x5bc0f0be),LL(0xcbbf9669,0x0b446dbc), + LL(0x507f8b27,0x10586ea7),LL(0xa261f7d7,0x1510deb9),LL(0xdfbfa352,0xa42fc4d7),LL(0x1e1c2291,0xbf38c382),LL(0x0e11760a,0x46e40ef6),LL(0xdcb974d7,0xc24f6061), LL(0xa7619027,0x755b105b),LL(0xb8ffa759,0x8004bf09),LL(0x0945db60,0xa630d0b0),LL(0xf2809e1c,0xa160ac9c),LL(0xdc6c95c5,0x38fc1113),LL(0x5d52574f,0x01f54098), + LL(0x9cee9bce,0x7eba3da6),LL(0xd5377750,0x3e2c1248),LL(0x2b93d8b2,0x8c917d98),LL(0x7cad1f75,0xca8fc6ac),LL(0xa0ff150a,0x5f581f19),LL(0xe08327fa,0x872cc14a), LL(0xe9333188,0xc774f187),LL(0x497af7e8,0x528ed4ac),LL(0x8ad72b10,0xce036e9b),LL(0x917986cf,0x463f9ebb),LL(0x1325cf9b,0xbe516328),LL(0xdd7e5fea,0xd28d5c50), + LL(0x0b237b7b,0xa4e9f29f),LL(0x4270ee2d,0x8ed65b09),LL(0x2993359d,0x0e2184e4),LL(0x224d5aa3,0x4f96ce7f),LL(0x3a132c48,0x0862e200),LL(0x0f015f5f,0x5bbc6ad8), LL(0xd7162f5c,0xab9d5149),LL(0x1267e5d2,0xfe657729),LL(0xc1fd96e2,0x4865e671),LL(0x71a703b2,0x7baf4dbe),LL(0x142add10,0x83dd6cf9),LL(0x98461d30,0xab4fc1aa), + LL(0xdd58bbe3,0x714c1d1b),LL(0x039afd0f,0x85ba01ae),LL(0x6951ac80,0x7f23ea3a),LL(0xac00c837,0x5c599290),LL(0xbf24cc1b,0xf6efa2b3),LL(0x1e84462b,0x393d8e42), LL(0xf8b89453,0x9bda627d),LL(0xb23e0d1b,0xe66fff2e),LL(0xc3b94ec2,0xd1ee7089),LL(0x3031699a,0xf75dba6e),LL(0x242b2453,0x8ff75f79),LL(0x289bfed4,0xe721edeb), + LL(0x698ee21c,0xcda68a7e),LL(0x6a5e725e,0xc7414d19),LL(0xdce20b91,0x483be2da),LL(0xfc69dca6,0x7de1601c),LL(0xac4f9891,0x4bec17aa),LL(0x8d479a56,0xe8741dd1), LL(0xac23a286,0xc623cb8d),LL(0x166133f0,0xe20a96b5),LL(0x30dcde61,0xda9bb7c0),LL(0x3a1733fd,0xf84ea327),LL(0xe82fac31,0xd7afb6c3),LL(0xd3897449,0x37ea7d35), + LL(0xc1390fa8,0x083215a1),LL(0x6dce8ce0,0x901d686a),LL(0x837073ff,0x4ab1ba62),LL(0x34beaba5,0x10c287aa),LL(0x46985239,0xb4931af4),LL(0xb053c4dc,0x07639899), LL(0xe721eecd,0x29e7f44d),LL(0x57b3ff48,0x65817182),LL(0x5054e2e0,0x198542e2),LL(0x84616de8,0x923c9e15),LL(0xad465bb9,0x2a9c15e1),LL(0x16319245,0xd8d4efc7), + LL(0xfd028642,0xed85257e),LL(0xb96a2068,0x93657f45),LL(0xa13ac381,0xfef64eda),LL(0x56c557a3,0x108f6ff2),LL(0x9204e3f7,0xe690d92b),LL(0x03ef8640,0x902a3e38), LL(0x6416f50e,0xaefd4922),LL(0xb7eae8f0,0x9b272152),LL(0x29d93d8d,0xa911921f),LL(0x5eeeea56,0x7c6bc499),LL(0x3ca7c720,0xbd3439d8),LL(0xc39b208d,0x2f8cf2e3), + LL(0x9961a674,0x72dc7943),LL(0xa0e13668,0x839a0a52),LL(0x334945ea,0xd7a53fa9),LL(0xe7aa25db,0xdb21db77),LL(0x66e96da3,0xb6675a7d),LL(0xe66f33c0,0x2c31c406), LL(0x6ec7b9cb,0x45020b62),LL(0x0391f267,0xff46e9cd),LL(0x0fa2f221,0x7dabd744),LL(0x9d4a2a3e,0x9a32364b),LL(0x52d2e47a,0xf0f84ae8),LL(0x888f488a,0xd0b872bb), + LL(0x0370327b,0x120649b2),LL(0xcd48cdc6,0x0e76555a),LL(0xca01db03,0x4ed54dec),LL(0xac601d22,0x7be21319),LL(0x01b6576e,0xf7116619),LL(0x4e73537f,0x7839fa06), LL(0xe46e860a,0x169d43ac),LL(0x3078eed9,0xde6d658c),LL(0x5032142b,0x8df73139),LL(0x9b3c76c7,0x6be199b0),LL(0xf8bbffe5,0xc2f385f6),LL(0xd5ffd28c,0x848df7f3), + LL(0xc9790eef,0x531e4cef),LL(0x2b8d1a58,0xf7b5735e),LL(0xef568511,0xb8882f1e),LL(0x86a86db3,0xafb08d1c),LL(0xf54de8c7,0x88cb9df2),LL(0x9a683282,0xa44234f1), LL(0xa6e9ab2e,0xbc1b3d3a),LL(0x87fc99ee,0xefa071fb),LL(0xa102dc0f,0xfa3c737d),LL(0xd6a0cbd2,0xdf3248a6),LL(0x1ecc1bf4,0x6e62a4ff),LL(0xc8f1bc17,0xf718f940), + LL(0xf874628f,0xa342bf65),LL(0xc71a57bd,0x18de3f8a),LL(0x71fc321b,0xb4d12a17),LL(0xa25ebf10,0x96716602),LL(0x1a286d80,0x744f6820),LL(0xe3cf63b8,0xd60bad1d), LL(0x4368da09,0x0c0b1ac4),LL(0x73a6d3be,0x53afeae3),LL(0xa90af331,0x4d2e6ce2),LL(0x88bc0638,0xd797224f),LL(0x9396d893,0x10c60b2d),LL(0xfe45e1a8,0xae3b0c11), + LL(0x4f63f026,0x2c8b0aad),LL(0x50b253cc,0x2aff6238),LL(0x10c4d122,0xcab3e942),LL(0x07cd2816,0x52b59f04),LL(0x982c41fc,0x22322803),LL(0x8cf50b19,0x38844e66), LL(0xbe3264cd,0x42a959f7),LL(0x6c983524,0xbddc24bd),LL(0x462b8640,0xa489eb0c),LL(0x98029be7,0xb7c05092),LL(0xa1addc64,0xd5546b5f),LL(0xa0c655af,0xe7cac1fc), + LL(0xc6a6d6d1,0xa189f30f),LL(0x69665ab8,0xdd674d36),LL(0x7d8da76d,0x307c9ec3),LL(0xc1ea7c10,0xb3e1d006),LL(0xb88c62d4,0xc15e20b3),LL(0x0bff3b3a,0xb0000ec5), LL(0x9ff9aa5c,0x9e330eb1),LL(0xdf578877,0x8663f9fd),LL(0x02e1eb2a,0x157d3cb0),LL(0xf525e4d4,0x638f297b),LL(0x34a3dff1,0xa20f8332),LL(0x45a9c051,0x748ea86b), +}, +/* digit=37 base_pwr=2^185 */ +{ + LL(0xbc266ee3,0xfe9fdde8),LL(0xba18e6c7,0x91668688),LL(0xddde6f6e,0xa65349ac),LL(0x7e54356c,0xc53c29c9),LL(0x5709f73c,0xee15ad94),LL(0xe5429277,0x033b3940), LL(0xd0c3475a,0xf52035cd),LL(0x93f1f1f0,0x9c5bef4d),LL(0xca319bd4,0x26e0b0ce),LL(0x6951fd8d,0x4e7eb67b),LL(0x95c34d6f,0xac3a6f43),LL(0x00f60b59,0x1f2769e6), + LL(0xfb787270,0xbd10b8bf),LL(0xe43aaab6,0x4f0b1566),LL(0xc0c90781,0x9a18be5e),LL(0x1ad167ce,0x3677f4c7),LL(0xa68c1c56,0xccb254e2),LL(0xe2c4d275,0x392493e6), LL(0xd5b63617,0x44958cb1),LL(0x4caa4e7c,0x178f141a),LL(0xa2ffdbd5,0x7445a767),LL(0xb0b6c22d,0x0e789c99),LL(0x5dc92b2e,0x3ff8b656),LL(0xeca98782,0x1623e5c3), + LL(0x78207cef,0xfadf9be9),LL(0x9cb5718e,0x97d5ba56),LL(0x2f995393,0xcbad24ec),LL(0x61203303,0x6236a268),LL(0x6589a4be,0xe4bafc33),LL(0x5e23fa82,0x6cba7718), LL(0x4583e65a,0x8ccbc577),LL(0x4bc2f415,0xe5d88bca),LL(0x41df8dd1,0xe6bc2d58),LL(0x14d31fcd,0xec24e1d9),LL(0xfc26010b,0xacaaf13e),LL(0xe01b92f3,0x7e1da447), + LL(0x899ef333,0x6f6a6104),LL(0x39067165,0x95496f6d),LL(0xb51989e5,0x42fd9a6a),LL(0x68f5b168,0x1b60ce0f),LL(0x56f7fe67,0x97324d87),LL(0x676815a8,0x443812f7), LL(0x685a7260,0x265ee994),LL(0x6c6515f0,0x342c7b2f),LL(0x34b4adb0,0xe9092323),LL(0x1e5a8d18,0xddcd233e),LL(0x5f4f6456,0x3dc5b27c),LL(0x7f421d9b,0x9664533a), + LL(0xff7543c0,0xc48bc829),LL(0x4d72bfaa,0xc0bda14c),LL(0x03be0af1,0x2f470ec7),LL(0x92d37eb4,0xc70f1e8e),LL(0x418f410f,0x08abdd98),LL(0x35386176,0xe38c74ab), LL(0x8c00426c,0x9c07cfdd),LL(0xa998f1ad,0xba74c310),LL(0xb7d2dda8,0x76b45140),LL(0x4948330e,0xa52b5e58),LL(0x8d8efb26,0x9b733234),LL(0x5d19a312,0x5d176373), + LL(0x987cf64a,0x43b58def),LL(0x3d4bcd4e,0xc95b16c6),LL(0xbcd9b923,0x5d1b1373),LL(0x522e052b,0xaf560542),LL(0x83800352,0xc2ff8f75),LL(0x7fe2a4ea,0x11723aa1), LL(0xe94bd9bd,0x28de7668),LL(0x874018a5,0x0ce80e0f),LL(0x8d43e726,0x0fe3755d),LL(0xf9b075c5,0xa78296ac),LL(0x82207423,0x76d58d98),LL(0x1db99205,0x5c5bc697), + LL(0xe3b7e746,0x583ee7df),LL(0xa4fab3a8,0x0b6659e4),LL(0x1946db5d,0x34ee0275),LL(0x1a12eeca,0x5ae3c0ba),LL(0x4ccb83e7,0x36756ed4),LL(0xa80eaf3a,0x973b0861), LL(0x6982ca90,0x969e38f4),LL(0x018d01fc,0x9a9bcd10),LL(0x3272476a,0xb540e953),LL(0x75ab7002,0xcf91dd0a),LL(0x39ceb983,0x2c7d363f),LL(0x974747c7,0x4369c221), + LL(0xf893a2ca,0xbfc40c30),LL(0x0623bad1,0xdf96980e),LL(0xc027511c,0x4fd7b54d),LL(0xcf3484ce,0xf4799284),LL(0x069beea5,0x655ab811),LL(0x7392e280,0x52588bc8), LL(0x4f0c17cb,0x522e7b40),LL(0xc705e9b2,0xc0d88aca),LL(0x77f3913f,0x9cf1b958),LL(0x7dd52514,0x3e06b926),LL(0x2908cbca,0x992e920e),LL(0x6d6ed529,0x13baced2), + LL(0x95ab4944,0x41c59b9c),LL(0xf32dcf4b,0xfacdd4fa),LL(0xef361bc3,0x6401bcb6),LL(0x697706ff,0x8d1fbbf7),LL(0x12fafc26,0xa9dcd2cd),LL(0xced1b64c,0xc1fce537), LL(0x06433b06,0x760b3eb2),LL(0xf6f894d2,0x53a27b08),LL(0x851c8bce,0xb50135cd),LL(0x0e058bf5,0x9bf9a243),LL(0xcc0a78ef,0x231624a6),LL(0xff090623,0x8200be42), + LL(0x67a470ce,0x5a0f6f6b),LL(0x7ccca885,0x7b8c2a88),LL(0x25f812da,0x4421fe13),LL(0xe0833478,0xc7a9c622),LL(0x94829d7c,0x6aff42db),LL(0x37d888fe,0x6fc2f23b), LL(0x64b75c84,0x9cfb8a14),LL(0x46139fee,0x56e1b7d4),LL(0xfe72fca5,0xcc6943b8),LL(0xc3d621cd,0x12e757e1),LL(0x72c1571a,0x6d9d63b0),LL(0x7b300fc6,0xa1fc3db1), + LL(0x393e37ca,0x7d58f7e6),LL(0x5e47e4c4,0x30290d9b),LL(0xa69dc1eb,0x831e5039),LL(0x5a758799,0xe2f42725),LL(0xc8f86525,0xe8166ff7),LL(0xaa85cc41,0x28e08f58), LL(0xe5409138,0x66be9bb7),LL(0xdcbb88ca,0x7d0f8807),LL(0xe7803e98,0x870cd794),LL(0xd59d39c6,0x78fd1eae),LL(0xcc0e56c0,0x1aabe0af),LL(0x5bf0f272,0x7f8de733), + LL(0xfdf88aba,0x36aa63d9),LL(0xcdf43217,0x87198fdc),LL(0xa9a923c9,0xd8fe6f62),LL(0xee2ae4ba,0x85c81a0e),LL(0x32dbcb0b,0x7c20dea0),LL(0x129a31c6,0x08baa938), LL(0xb1d60f99,0xa47b3003),LL(0x6905192e,0x31459993),LL(0x32cf2c7c,0x67e22899),LL(0x3b3c32bc,0x4c5f4375),LL(0xd499aa00,0x8de5d14d),LL(0xa311dac5,0x54875c3f), + LL(0x898dc5c7,0xb6475210),LL(0x080e62b4,0x0f709811),LL(0xbb3bffd9,0x8a0016a7),LL(0xafb97dc7,0xfc56d337),LL(0xca1b43d9,0xff911c89),LL(0x9187747a,0x9f8d40b7), LL(0x5700a9ea,0xf6ba5214),LL(0x8c04b9b7,0x7bc1c0e3),LL(0xa2c924d2,0x2dd3de09),LL(0x717b13cf,0x12378655),LL(0x6e9d0e85,0x090f2556),LL(0x88f728c3,0xf66a337d), + LL(0xe5140e1e,0x1f90b9b6),LL(0xea2d44e5,0x7ab77ce1),LL(0xf4878fcf,0xc8a3343e),LL(0xc544e407,0xbeb73f7c),LL(0xfec32a61,0xdb3a8266),LL(0x38db88f8,0xbe30a82e), LL(0x525080cc,0xf33ad1df),LL(0x1a553e27,0xf66aa44d),LL(0xa9b7b198,0x3194733f),LL(0xb4b9b4c1,0xd87c8145),LL(0x68883c51,0xca7cd392),LL(0xca49b152,0x2d12a779), + LL(0x2c4ffe71,0x407842b5),LL(0xc3f5593b,0xfa9a9143),LL(0x69f25d01,0x97f9f32a),LL(0x4571d150,0x78e3d5fd),LL(0x89878e86,0x8cbd1078),LL(0x633ed774,0xd4a4be53), LL(0xd65d0ef1,0x2e6cf7f0),LL(0x18a2e243,0x5cefa892),LL(0x130c9ba1,0xb2e8ccb6),LL(0xde1ec2f9,0xda209fc8),LL(0xb3448d09,0x64845a36),LL(0x92896b12,0xbde9ae0a), + LL(0xbfc6c637,0x8a46c911),LL(0xe4fa4fe6,0x8dc3d699),LL(0x5cf8e4c9,0xd4ba64f1),LL(0x01cb3488,0x01b3908a),LL(0x38bd7ded,0x69b1fa5d),LL(0x18b2eae1,0x92ad4838), LL(0xb33955b6,0x619324be),LL(0x5c8a6df7,0xc7f37335),LL(0x925b3f69,0xa397f42e),LL(0x5f7e4d11,0x32169a49),LL(0x8d0d9f01,0xc0fa9a54),LL(0x89d8f2e5,0xf52a1f22), +}, +/* digit=38 base_pwr=2^190 */ +{ + LL(0xba8e0a52,0x9c0d5231),LL(0x93e465d7,0x94d0509e),LL(0x98515454,0x67df90dd),LL(0x8dbfb46a,0x223e8b9c),LL(0x6d757ce3,0xf39529a3),LL(0xb4648296,0xffec9175), LL(0xf78aae7b,0x330749e8),LL(0x45f93cc3,0x19e55496),LL(0x94083aa8,0x8c320b34),LL(0x21e321c6,0x1161f5a3),LL(0xde3e7892,0x0980deed),LL(0x6ad76ccc,0x605aa919), + LL(0x180660f7,0x73fa3508),LL(0x2d24936f,0x4cae013e),LL(0x58493d98,0xf64a549f),LL(0xdc79f602,0xd9ceae0a),LL(0xd1512b84,0x6569e37b),LL(0x151c9151,0x11e4c022), LL(0xb55c5813,0x075678c2),LL(0x09d3cb16,0xb26cdb58),LL(0xa57fb969,0x6334dca3),LL(0x223dc3ce,0x0ed90820),LL(0xbd11e277,0x74f9c3ae),LL(0x79c0b8e2,0xaeefed36), + LL(0x2a24c385,0x0e2fc74c),LL(0x34679278,0x836a4740),LL(0x817e2c41,0x25518f16),LL(0xb4b7d3c1,0x8b573a8e),LL(0x4ab56adf,0x012797f9),LL(0xfa2ab690,0x9e0e56d0), LL(0x1c9f6f08,0x009ba1ee),LL(0x2f412e9e,0x8ebf4aac),LL(0x1cfb4e02,0xb143122a),LL(0xcbf2b783,0x988cf0ec),LL(0x57f5be97,0x44a7ed96),LL(0x51804147,0xbdcad872), + LL(0x2f9fbe67,0x378205de),LL(0x7f728e44,0xc4afcb83),LL(0x682e00f1,0xdbcec06c),LL(0x114d5423,0xf2a145c3),LL(0x7a52463e,0xa01d9874),LL(0x7d717b0a,0xfc0935b1), LL(0xd4d01f95,0x9653bc4f),LL(0x9560ad34,0x9aa83ea8),LL(0xaf8e3f3f,0xf77943dc),LL(0xe86fe16e,0x70774a10),LL(0xbf9ffdcf,0x6b62e6f1),LL(0x588745c9,0x8a72f39e), + LL(0xb1bafbc4,0xa96955b9),LL(0x646ece39,0x8dcb55a7),LL(0xeb00e541,0x2b62784f),LL(0x2693249b,0x462f9d7d),LL(0x794c189d,0x8b264697),LL(0x63354e69,0xded6ff55), LL(0xeed1089f,0x7c8ea441),LL(0x1462f461,0xe355f75c),LL(0x1210fd5b,0x87b691f6),LL(0x6983cb27,0x7291bffb),LL(0x92800095,0x9ed83afc),LL(0x1f24d923,0x307a3dc8), + LL(0xd7804b2f,0x7cec60ea),LL(0x45c11441,0x00644643),LL(0x769cd685,0x3c6de88b),LL(0xc7f01232,0x34709186),LL(0xedd2bd0d,0xd9eef41e),LL(0xe427faa9,0x3bafcccd), LL(0xc07e701a,0x33e5350e),LL(0xa87c1fd1,0x9cb2eb47),LL(0x0d5f5b28,0x9fa9a779),LL(0x07ea2e53,0xa2e7076b),LL(0x5c169cf4,0x72f4da32),LL(0x7e751588,0xb7f19294), + LL(0x32dd7a30,0x47eb1335),LL(0xa9db654d,0x9d058169),LL(0x6e7a2b1a,0x375c59df),LL(0x7a35f29f,0x55d37c67),LL(0x493c4cde,0xc78a3678),LL(0x8d83e31b,0xe5f0e2d6), LL(0xe9777bf9,0xf7927002),LL(0xa5afdfc7,0xdd559324),LL(0xb81c08cc,0x077c6c48),LL(0xaa2ef694,0xba1c98cc),LL(0x4c02dd46,0x06c6c954),LL(0x7dd3145e,0x211e50f3), + LL(0x06616d0d,0x2a5f8ecf),LL(0xc7deb373,0xca9b1cb8),LL(0xc59c4301,0x9de31ced),LL(0x0111d998,0x1e0f40b1),LL(0x960d5b95,0xd29d229f),LL(0xd1dabab8,0x10563249), LL(0xa05ecac9,0x7b225cc9),LL(0x78f3b8a0,0xb02e6896),LL(0xf5fb06b2,0x009b52a1),LL(0x842b9081,0x8a575d3f),LL(0xe9272512,0xfddb48af),LL(0x0b452cb7,0xd39b8f1d), + LL(0x67e09987,0x0d6b9c7c),LL(0x0761ad52,0x261a564d),LL(0x9f60925b,0xec462174),LL(0x18529b03,0x83ee0c12),LL(0xfbcfff74,0x72972467),LL(0x6abc4bfb,0x37fc074c), LL(0x54e65e89,0x8b6015bd),LL(0x991583cb,0xde8583eb),LL(0xb4d2c62a,0x379548e1),LL(0x9b24a5e5,0x88024a9a),LL(0xfc03abfc,0x633aa869),LL(0x8fa35283,0xa27657b9), + LL(0x61d9e770,0xde9703b4),LL(0xef4653ef,0x02d4091d),LL(0x576eb5e1,0xefd229aa),LL(0xf77eb987,0xc0b0b243),LL(0xeefe8f71,0xb11309b2),LL(0x68478044,0xfeeacf2f), LL(0x43ac3dd7,0x8dfd8e86),LL(0xb07f95c3,0xc0a24181),LL(0x24be161c,0x551ca096),LL(0xb098cdc3,0x6cb2c1d4),LL(0xe74f84f8,0xbfc74e9b),LL(0x067e3388,0xe58e14d9), + LL(0xf025baa6,0x9eca6f94),LL(0xbcf9c741,0xb2db0741),LL(0x90bb8f56,0xf8e2aab5),LL(0x08762829,0x47729032),LL(0xe2a266c8,0x067a0c5a),LL(0x71b7d7d0,0x22b104c7), LL(0x53e406db,0x4a48cd69),LL(0x24f0070b,0xb85e44d5),LL(0xe10133ff,0x6168262f),LL(0xe4874e8f,0xdfc02315),LL(0xca317e3b,0x20dba2d7),LL(0xe1d2c0c3,0x441c56d2), + LL(0x808dc4b1,0xae10069e),LL(0x8fb3ba73,0x64df30e1),LL(0x7ebaad0b,0xbbe4caf2),LL(0x3dd6119c,0x5907bf37),LL(0x9dfceefe,0x0a723dff),LL(0xf7cffc7e,0x59bff4dd), LL(0x6a6f43c2,0x7bc95fa2),LL(0x3ca0e2b3,0x9001d1d5),LL(0x27b3335b,0x316a7ecd),LL(0x7b8d7d49,0xbf08e672),LL(0xc619058f,0x4b209f93),LL(0x59d8f9ea,0x4c0ca01e), + LL(0xcae69c3b,0x18c452c4),LL(0xef0f00fa,0xf45690ac),LL(0x4f66a5cc,0x3b363aa0),LL(0x47718c52,0x9dd41c0a),LL(0x7e5cd370,0xfa219d7e),LL(0xb2196dfb,0x5d384db7), LL(0x90b4d46b,0x5e14749b),LL(0xd9db9481,0x55796656),LL(0xc8cf353e,0x3bf13d0a),LL(0xa95c485a,0xb89a28a6),LL(0x5da29783,0x568fa3d0),LL(0xd182b1a4,0x4aa008ee), + LL(0xb09fa8f3,0xf7e1ed3b),LL(0x1da5be9e,0xbb4fe6f7),LL(0xf4d1ba21,0xcbab0e01),LL(0x76a5f326,0xb7327410),LL(0x206092af,0xd94d2349),LL(0x728e0e4d,0x739f3cd0), LL(0xf81fd823,0x568644aa),LL(0x6110e2f6,0x510cff6b),LL(0x566c3598,0xef4cf1ac),LL(0x62aae69b,0x2c26f171),LL(0x8964a2a5,0x1e436046),LL(0x3e472c50,0x83c0bbf6), + LL(0xaabd965a,0x79c04804),LL(0x43d0b660,0x9581aab4),LL(0x5ba71d23,0x59bff003),LL(0xb6a0cd80,0x212ecd58),LL(0xbf1ea5d6,0x29bdcd33),LL(0x77a002e1,0x59fd2ff4), LL(0x8d9cd247,0x3c9d2130),LL(0xb1786da3,0x790e9dbc),LL(0x14464d04,0x967ee5e7),LL(0x2b5373af,0xd6f7ebbd),LL(0x39768d40,0x1c0b22d5),LL(0x913f6cc3,0xdfb54983), + LL(0x51b3f1ce,0x167ec88a),LL(0x420024c8,0x19756ee0),LL(0x3877e634,0x10f2e244),LL(0x03462cb3,0x6321bf26),LL(0x9d3afcee,0x1dbd10ee),LL(0x2ca17dcd,0x0726f5f2), LL(0x0bacf018,0x09465266),LL(0xe1feb969,0xc92a9f2d),LL(0x5e1c5912,0x0043b0f9),LL(0x757d3a63,0xa09b94d1),LL(0x9fdef1e0,0x53395652),LL(0xd4fedd41,0x9826886c), +}, +/* digit=39 base_pwr=2^195 */ +{ + LL(0xec65b53e,0x2e75a26e),LL(0x70552fb3,0xfeb630b2),LL(0xee7d8e4a,0x53dfd057),LL(0x8994f449,0xb959110d),LL(0xbb538367,0xb4a16596),LL(0xef82f29c,0xa70917bd), LL(0x43bba6ae,0x5a764300),LL(0xcfbc194a,0xee207476),LL(0x03a4184b,0xc7eab238),LL(0x0f7fcd62,0x60c67ef2),LL(0xdfa8a0c6,0x41e05799),LL(0x04d352b0,0x5d7d05e6), + LL(0x436b59f5,0xc97c01eb),LL(0xef1848ab,0x1d15aca7),LL(0x7fa7d3c2,0xdba1ce80),LL(0x81060874,0x69e6f96e),LL(0x4d7eeead,0x6e3e0df7),LL(0xb0c87f3d,0x8a3b5e85), LL(0xc8a23914,0xc55ae3db),LL(0xbf6d27d9,0x5cdc2a92),LL(0x1de7860a,0xa6008c59),LL(0x6e546731,0x8202f8b6),LL(0xaa1e45d4,0x652f2d07),LL(0x6df5415a,0x146f214f), + LL(0x651ed62d,0x4b01246a),LL(0x0b9eb006,0x9f6824a3),LL(0xba95697f,0x763ae8fe),LL(0xefe2182e,0xeff4f88d),LL(0x74ba79b4,0x2c2ef50c),LL(0x1d23d649,0x319df6c9), LL(0xf6c273a8,0x481f9faf),LL(0x9706dc07,0xe7156457),LL(0x424d5cb9,0x06f0617a),LL(0xa8ad220a,0x6d6b5d8b),LL(0xa2bd8c40,0xa485ca14),LL(0x54cb54f6,0x7a7a15bf), + LL(0xce5fb4d9,0x041c706c),LL(0xb22a79a7,0xddc78cb3),LL(0x839e9d5a,0x7dc4cd27),LL(0xbf3c4c06,0xdfc9db83),LL(0x38b7bd22,0x85b80941),LL(0xd0f4c2da,0x1007dea2), LL(0xc633fba0,0xd7b34006),LL(0x4476e55f,0xa8880acf),LL(0x75236685,0xa340b2c2),LL(0x0113a85f,0x5ddd0551),LL(0x9cb32704,0x7dfc7ab2),LL(0xdabf22ff,0x9a334a33), + LL(0x7e546950,0xa8261c31),LL(0x26706dc1,0x89d19cae),LL(0xedc9af36,0xf8dbf6ca),LL(0x7e446207,0xda79fe4e),LL(0x81cee38d,0x8bbc3195),LL(0xb5be9577,0x9d121e9c), LL(0xcddb5a61,0xdb3fff88),LL(0x3ee86665,0x751cad15),LL(0x3d07abad,0x5c0986df),LL(0x83fe8451,0xf77489b3),LL(0xf90d3e94,0x3546c5a9),LL(0xd8a694b7,0x1ec54bd1), + LL(0xd7d1146b,0x2fbce9be),LL(0xb3980bd2,0xcec9e5d8),LL(0x9f4cbaf0,0x48ea4593),LL(0x2574a3bd,0x56c54009),LL(0xe792c39a,0x84a39630),LL(0xeef81343,0xe5c690f8), LL(0x17655bc9,0xf996760f),LL(0x6c0c191c,0x6009c215),LL(0x966d7027,0xa0ca12e6),LL(0x2e6f7c63,0x92a6d5d5),LL(0x9bd13ead,0x46809d26),LL(0x67aac681,0x3c11fa79), + LL(0xea8edc01,0xca2876f9),LL(0x28d411c8,0x85c1a4ac),LL(0xfb0299a8,0x4d5fca4c),LL(0x17fe8b37,0xa1df6c5a),LL(0xcc062556,0x2ffb3570),LL(0x465ef78f,0x4c59773e), LL(0xb3601ca5,0xea3e39ae),LL(0xb7d30864,0x9806345f),LL(0xe6600e5d,0x428fe41f),LL(0x067a59c0,0x19bd665d),LL(0x908cdb52,0xbd6b8272),LL(0x0b2707d8,0xb6025028), + LL(0xabe2cc87,0x3fc9b3cf),LL(0x514e77fe,0xfd8d64e3),LL(0xfe1ad535,0x2003a58a),LL(0xcb39149f,0xcec4be38),LL(0xbdedf470,0x4d578c99),LL(0x3a356519,0xcd35d7a3), LL(0x8b078d6b,0x7a762f27),LL(0x31ae2701,0x3b6891ed),LL(0x270c508e,0xdc0e817f),LL(0x9fdb29c8,0x5a7be204),LL(0xcb2711d3,0xfa1a0be3),LL(0x3786a0c2,0x5865f55f), + LL(0x23bd1613,0x5f5db9af),LL(0xcfd5bc16,0x0071d2c4),LL(0x81adfd03,0x273d7ad1),LL(0xa0570ffa,0x683508f4),LL(0x611a75fc,0xa49f5c08),LL(0x8fbcfbb1,0xfca5bd12), LL(0x2a4fc49c,0x7eabb339),LL(0xad6e6d32,0xdc5fae69),LL(0xe0b03dce,0x2e599c43),LL(0x7ca7250c,0xf4ad8d3e),LL(0xedeee0fe,0x626c1f7e),LL(0xaab0b3f0,0x2296376f), + LL(0x2f641cff,0x1d0af6b5),LL(0x3648c4a0,0xa932adeb),LL(0xb1ea8fc4,0x67641951),LL(0xb1fae482,0xc0b90064),LL(0x6623477b,0x7012642f),LL(0x5bf019ce,0x1cddc024), LL(0xc2c32737,0xca1f4675),LL(0x97d6b18c,0x11525a5e),LL(0xd3868de9,0x9c034ef2),LL(0x044e0c18,0x0533d921),LL(0xcb5e38c3,0xba6cf14e),LL(0x509d7053,0x438309f3), + LL(0x790b3f68,0x0b82b506),LL(0x12c1f59d,0x75b38ef1),LL(0x4dbdd80b,0x6bc1e007),LL(0xd13bb11c,0xf81480db),LL(0x17259091,0x25131887),LL(0xc61dde4e,0xc5c8823e), LL(0x9b2736d1,0x0ddb06a0),LL(0xa785e570,0x64dfb1fe),LL(0xcc593359,0x6f8f9945),LL(0xd186352c,0xe8e457a9),LL(0x7c342abc,0x389479b6),LL(0x4cc71b3b,0xc73ddfee), + LL(0xc4ff9f0b,0xe164268e),LL(0xe6c36e63,0x6c8e9349),LL(0x78ab17f3,0x734f9794),LL(0x0179ed0e,0x46d468de),LL(0xdfa26867,0x7e68f006),LL(0xe3d0485d,0xe4d4a85d), LL(0xf84c0f8f,0x0913a1d7),LL(0x25a9c9cd,0x4095c8c0),LL(0x49eadd08,0xeeb1a79e),LL(0x7dd8f954,0x433f5e41),LL(0x30bb26d0,0x70a62814),LL(0xff5e8e29,0xad94d8f6), + LL(0x5652a3c0,0x0b614a64),LL(0x34597010,0x89279185),LL(0x810a812f,0x06c97f68),LL(0xbe358e91,0x566120f4),LL(0xc044ff3c,0xcb1f8b75),LL(0x7d1a468b,0x77b3b0b0), LL(0x7d49aad9,0x37a72862),LL(0x8646efd4,0x3ada117b),LL(0x21bac6d0,0xd8626c0d),LL(0xdd2c980c,0x2263d74c),LL(0xfd1b6bda,0x8afd14c0),LL(0xcae64c0b,0x693742cb), + LL(0x9e32c0a4,0x6a352b57),LL(0x77ec7a40,0x5274a082),LL(0x240e6dc5,0xee1f7c7a),LL(0xd313b4a9,0x85d5be62),LL(0x5c01a405,0x1522c5d2),LL(0x960afd5a,0xcfa08aab), LL(0x8e8a93dc,0xa3cb77f3),LL(0x6d1c98c7,0xaacb1676),LL(0x3b93fa9d,0x84090c7d),LL(0x3c0383ad,0xc77f1ee1),LL(0x76f7a220,0x461c93b7),LL(0x04ac0bfc,0x66d63a1d), + LL(0xd2343e0b,0x3d1904c6),LL(0x775f877f,0x8ce038f7),LL(0xd797f231,0xa9d4dce1),LL(0x16c08c2f,0xb6712aa7),LL(0x335ad61a,0x5045b87a),LL(0x7115bb4b,0x44a251fb), LL(0xe66511bc,0x2363cf68),LL(0x81cc48f3,0xed8ab553),LL(0x725c6bae,0x8bf71687),LL(0xc23ab12c,0x16e0d015),LL(0x21f333c0,0xfbdcc064),LL(0x62c9f01d,0xe73df709), + LL(0x4751207f,0x3c7d6b64),LL(0xe440c1a2,0x65e1f96a),LL(0xaa0eaa1e,0x8ed15d20),LL(0xc0eab490,0xe944ad2f),LL(0xf6d9f260,0x71525aa1),LL(0x16146ba3,0x5cd14c88), LL(0x14a41275,0xf9401908),LL(0x2288618d,0x3bb7ea74),LL(0xcab1060a,0x6a4e1c37),LL(0xc8cac96f,0x357fe4d0),LL(0x6a2466ec,0x97a8b8ab),LL(0x9c01be70,0xb6e83fdb), +}, +/* digit=40 base_pwr=2^200 */ +{ + LL(0x2a7aeced,0x5b0b5d69),LL(0x01dc545f,0x4c03450c),LL(0x404a3458,0x72ad0a4a),LL(0x9f467b60,0x1de8e255),LL(0x90634809,0xa4b35705),LL(0x706f0178,0x76f30205), LL(0x4454f0e5,0x588d21ab),LL(0x64134928,0xd22df549),LL(0x241bcd90,0xf4e7e73d),LL(0x2facc7cc,0xb8d8a1d2),LL(0x1d25d2a0,0x483c35a7),LL(0x1ef9f608,0x7f8d2545), + LL(0x22ec7edd,0xa7040160),LL(0xcc9c8ee8,0x19124972),LL(0x2ccb9417,0x697f301f),LL(0x6f00d8aa,0x3ee87764),LL(0x8138a017,0x2b5afaf8),LL(0x832d7543,0xf152b14c), LL(0x383052f9,0x27c27ce2),LL(0xe1dae11b,0x4746c5b5),LL(0x5b752008,0x92dc5ac7),LL(0xe84fe5f1,0xcf382e01),LL(0x7d5929ce,0x90e03419),LL(0x15ca3ffa,0xafee3abb), + LL(0x54ebc926,0xcb51f039),LL(0xb8d4a7bb,0xe235d356),LL(0xb41fe1a6,0x93c8fafa),LL(0xa719f254,0x6297701d),LL(0x644f5cde,0x6e9165bc),LL(0x0c11c542,0x6506329d), LL(0xa92b4250,0xa2564809),LL(0x889c2e3e,0x0e9ac173),LL(0x22b1d1be,0x286a5926),LL(0x6ecdd041,0x86a3d752),LL(0x649f9524,0x4b867e0a),LL(0x0629cb0f,0x1fe7d95a), + LL(0x1c6d03b0,0x11dd860e),LL(0x09eec660,0x30c17008),LL(0x35c0192f,0xd4f8aff6),LL(0xe3a4a900,0x96a727b1),LL(0xde78c8ba,0x1426daff),LL(0x8d1527c4,0xfacaa9bd), LL(0xcd072989,0x0c0d5234),LL(0x918550b5,0x1936c20d),LL(0x3d914fb3,0x4828bee4),LL(0xf3ba26a6,0x8324ea38),LL(0xa94eb26f,0x027590f3),LL(0xacd957bf,0xfd354295), + LL(0xca5baf54,0xf4f66843),LL(0xefe7db78,0x298db357),LL(0x7365712f,0xf607e86e),LL(0x8a822bc0,0xd5882298),LL(0xc61299b3,0x2cfbd63a),LL(0x67167b1a,0x6f713d9b), LL(0xde0b077a,0x750f673f),LL(0xee2178da,0x07482708),LL(0x69123c75,0x5e6d5bd1),LL(0xeab99b37,0x6a93d1b6),LL(0x8caec6a3,0x6ef4f7e6),LL(0xcf3ed818,0x7be411d6), + LL(0x3dfb423c,0x959353be),LL(0x36d41cc8,0x8458e858),LL(0x99d7a4f4,0x6a4826f7),LL(0x52fe4b65,0xab146ece),LL(0x35038573,0x94fc21d7),LL(0xf4d56e84,0x26f50135), LL(0x3162d92d,0xe15ca04d),LL(0x34ed4e84,0x8f652fcd),LL(0x4f21a910,0xef7e7924),LL(0xdcc76132,0x2eecb7e9),LL(0xdbe89048,0x5b484745),LL(0x6e43a2c5,0xbf8c490f), + LL(0x63a0a7d2,0xf92b3073),LL(0x881dc8cf,0x32da431c),LL(0xc578e3a3,0xe51bd5ed),LL(0x9587fa22,0xefda70d2),LL(0x9b2eba85,0xcfec1708),LL(0xaf7ba530,0x6ab51a4b), LL(0x98174812,0x5ac155ae),LL(0xccb076e3,0xcaf07a71),LL(0xc38718a7,0x280e86c2),LL(0xd63745b7,0x9d12de73),LL(0xbf8a79aa,0x0e8ea855),LL(0xbd705bf7,0x5eb2bed8), + LL(0xda756624,0x3ede2484),LL(0x73b13062,0xb22da2ab),LL(0x962a667b,0x56069e93),LL(0x130f2cea,0xc931266b),LL(0xa7366a66,0x4bd6a6fc),LL(0xaa5ac3b1,0x23f30563), LL(0xd7c2b26f,0xa025d0ef),LL(0x62129bc7,0x597ce7d8),LL(0x2b3057f2,0x4809927f),LL(0x1499f884,0xb001c10a),LL(0x30b9a653,0x309d141c),LL(0xbf659d05,0xadddce7d), + LL(0xae16de53,0x33fe9578),LL(0x10bec902,0x3ae85eb5),LL(0x44af850e,0xc4f49658),LL(0x087dd658,0x6ea222b3),LL(0xa51f1447,0xb255e6fd),LL(0x117e3f48,0xb35e4997), LL(0x05616ca1,0x562e813b),LL(0x8a61e156,0xdf5925d6),LL(0x571c728b,0xb2fa8125),LL(0xa2f2d1cf,0x00864805),LL(0x1bccb6ff,0x2dc26f41),LL(0x63ae37dd,0xebd5e093), + LL(0x9303b5b0,0xe448127c),LL(0x7a74ec27,0x6ac65681),LL(0x86f0e7ec,0x05128a52),LL(0x7603a73c,0x9d9f32c1),LL(0x556c51ea,0xb5a799bf),LL(0xa9a9a416,0xea94f169), LL(0xaebde511,0xebb3e549),LL(0xf9cccd3f,0x9037046a),LL(0xf08a8254,0x2a9343a8),LL(0xd40c7f26,0xc5cc43f6),LL(0xb39677d2,0xe1146cdc),LL(0xbe66d4b6,0x6cbfec8b), + LL(0x0a285611,0xd2d68bb3),LL(0xdc8378f2,0x3eae7596),LL(0x6cc688a3,0x2dc6ccc6),LL(0x011f5dfb,0xc45e5713),LL(0x62d34487,0x6b9c4f6c),LL(0x1fc65551,0xfad6f077), LL(0x62b23b52,0x5e3266e0),LL(0xe98f4715,0xf1daf319),LL(0x3ed0ae83,0x064d12ea),LL(0x564125cb,0x5ccf9326),LL(0xc63c1e9f,0x09057022),LL(0xdc9b5d2e,0x7171972c), + LL(0xb0a219fd,0x10867369),LL(0x5ab56581,0xe7efac97),LL(0x7813f6f5,0xde3372e8),LL(0x1d4b8ed3,0x3bbe5977),LL(0x53376573,0xf17f61e5),LL(0x97964b90,0xf719d06d), LL(0xb24d2e4a,0xb1e8c483),LL(0x184379eb,0x53709647),LL(0x8a8fcb83,0xb739eb82),LL(0x60163017,0x5d2f3a4d),LL(0xf823b4af,0xccedf4f4),LL(0xff315eae,0xa6e166a1), + LL(0xeabd21b2,0x2364fd9a),LL(0x9174ad6d,0x3ce5f4bb),LL(0xb38688c0,0xa4d6d5d0),LL(0x6d87fd7d,0x2292a2d2),LL(0x4ca02e54,0x2a7d1b53),LL(0xb4185715,0x7bee6e7e), LL(0x8fc63acd,0x73e54609),LL(0x4064e09d,0xf4d93a12),LL(0x2b92daa5,0xd20e157a),LL(0xc4b81a00,0x90d125db),LL(0x7682de13,0xcb951c9e),LL(0x27987545,0x1abe58f4), + LL(0xe1c01fab,0x76452ac1),LL(0x6bd32f0c,0x167d7326),LL(0x4a283a42,0x72d209c1),LL(0x48ea0ba9,0xd26859b6),LL(0x6369309b,0x7b3e5c46),LL(0x93c9a0b9,0x474a9625), LL(0xc76e25dc,0x676ea3e4),LL(0x71400c71,0xb0c9ccf7),LL(0x36f83518,0xc4295870),LL(0x267f0c25,0xb86c1b39),LL(0x28884a80,0x8a3e3524),LL(0x43ba8e28,0xea182c45), + LL(0x30c70c8d,0x6d351640),LL(0xce2361b8,0x8047d811),LL(0xdf8e2c81,0x3f8b3d4f),LL(0x33fa1f6c,0x5d595477),LL(0xe29b8a91,0xf769fe5a),LL(0xd737b2a2,0x26f0e606), LL(0xb8b31c6a,0x70cbfa5d),LL(0x863d3aea,0x0f883b4a),LL(0xe386ae2f,0x156a4479),LL(0xade8a684,0xa17a2fcd),LL(0xe2a7e335,0x78bdf958),LL(0x3b9e3041,0xd1b4e673), + LL(0xaf2825c1,0xa6c32900),LL(0xd223a04e,0xb37c46c1),LL(0x063de7ea,0x691e7d39),LL(0x10daf9bd,0x998df4e7),LL(0x718b5d7a,0xc7085b9e),LL(0x16b3d4b8,0xd41abcc8), LL(0xf9bc4041,0x4dfce693),LL(0x659ec7a8,0x383677ed),LL(0x4491fb34,0x2c1904bf),LL(0x4552451c,0x7c1bf111),LL(0x3c5e5e40,0x6562cc2c),LL(0xfe0e4372,0x1ecaa2a1), +}, +/* digit=41 base_pwr=2^205 */ +{ + LL(0xf3087bc8,0x84c3630b),LL(0x74be6e26,0x152691e6),LL(0xf61af001,0x5abd125f),LL(0xbfea3525,0x69bca56f),LL(0x00e0cb6e,0x384af199),LL(0xd00475a6,0xb0b13cfe), LL(0x5e394049,0xedafde49),LL(0xdaf2add6,0xd988b558),LL(0x6c8ffcc9,0xf14cf97a),LL(0xe5a9cc5c,0x4d6cec23),LL(0x8a104e05,0xb0d678f8),LL(0x9fb527c1,0x80a7fcba), + LL(0xc22137d2,0x0d6cadbf),LL(0x628a3298,0xb5db59d3),LL(0x4ab19507,0x3b433c73),LL(0x660086b3,0x4fc53405),LL(0xa1eb0f43,0x770ae903),LL(0xf6b5b58d,0x31b5857e), LL(0xd392868e,0xe206e141),LL(0x4b31de04,0x8be6956f),LL(0x47449e07,0xcfbfca2f),LL(0x39fef8e1,0xebaef256),LL(0xc16fc80c,0x959e37b8),LL(0xe911d61b,0x8bb4bdd2), + LL(0x4343bbf8,0xc483d4b2),LL(0x8a0fc95e,0x42aca2e1),LL(0xcbab1fb0,0x5165df6f),LL(0xf6cdfc0c,0xeb284370),LL(0x994320fc,0xab565c00),LL(0x62133e80,0xc0d157fd), LL(0x5b69644a,0x7850cda5),LL(0x806ec8b8,0xe37ae76a),LL(0xc2c82edd,0xd14b805c),LL(0xcf244539,0xcb5468b6),LL(0x25dbe92d,0x97d43ee8),LL(0x89fb8f1e,0x14422436), + LL(0xa0a85236,0xd7bf2ac6),LL(0x7194c46d,0x2921b55c),LL(0x9afa9762,0x162fabaa),LL(0xb62b36ab,0x7b7f1664),LL(0x296a84e9,0x77b9f797),LL(0x7dbd843d,0xfcc1ad65), LL(0xcd77b7f6,0xc6e9c1e1),LL(0x917067c9,0x9cf0e272),LL(0x3bfa90bf,0xfa7fa93d),LL(0xd050e46a,0x55846fe9),LL(0x35c56256,0x473b9a0d),LL(0x2b656a65,0xadd29e33), + LL(0xebc69b0b,0x926c2552),LL(0xd4c7432e,0x953a850f),LL(0xb9359035,0x0ee85e14),LL(0xbde090a5,0x8b10b01a),LL(0xec423943,0xb2878dca),LL(0xf70bde20,0x2571a178), LL(0xf5ebeee5,0x24ed159a),LL(0x043f6539,0x60c202af),LL(0xc8d4ffc3,0xdaaa76f4),LL(0x06eda10f,0x2fc1f1ba),LL(0x88ded556,0xddf159ee),LL(0xe67b1ec4,0xcfa71782), + LL(0xd5d826b0,0x31521f66),LL(0x40787844,0x0a636952),LL(0x9c8f934e,0xc0a3bd05),LL(0x2f0ce835,0x12c57dd4),LL(0x67064213,0x847f6a99),LL(0xa88bd71a,0x1c9e1a7a), LL(0x171e8407,0xc4060eb2),LL(0xed106780,0xdf78d8df),LL(0x0d704729,0xa3d28ceb),LL(0x46ca3912,0x4f8e5232),LL(0x017791f4,0x09e9f852),LL(0x1e6ea97d,0x59400663), + LL(0x83939224,0x547b0d95),LL(0x1e026769,0x3a0823ff),LL(0x25bd43ac,0x60166715),LL(0x18ba5f64,0xb6cf475e),LL(0xc8b6d09d,0xa22f9c92),LL(0x3ccf50ab,0x73055368), LL(0xee6deefe,0xa6de248e),LL(0xacc3ca20,0x32aaf8b2),LL(0xad44e674,0x0e254c5b),LL(0x35f95f98,0x8aa73e65),LL(0x60a2dc1e,0xe6226001),LL(0x9109020a,0xdf948210), + LL(0x2893f2f7,0x372798f0),LL(0x9e5030ca,0x4f62bfac),LL(0x8a1e2567,0x5e64f9a9),LL(0xe70391c8,0x5870254c),LL(0x41f02458,0x2def81a3),LL(0x1d087bed,0x25d4e4dc), LL(0x4fe24a13,0x3557d07d),LL(0xdc3112bc,0x6da49186),LL(0x5f73ba50,0x08c8c567),LL(0x9c7c6706,0x5309050b),LL(0xbd985072,0x2ab67da3),LL(0xe5df4e96,0x9bafa8b1), + LL(0x5c02f173,0x3ac66289),LL(0x76d566e5,0x6a110e38),LL(0xb9577e26,0xd9cc14e2),LL(0xfdfe617e,0x6f3d5df9),LL(0x352bb2ca,0x8fac740f),LL(0xc28e6310,0x50bc8a0c), LL(0x77ac93f7,0x6e572fc4),LL(0x605bb8e9,0x56277377),LL(0x402b8c55,0xad6d0637),LL(0x4509eda7,0xdab37791),LL(0x0854e91b,0xae770abc),LL(0x742b3de8,0x523bd278), + LL(0x17fecb90,0xc2cbd644),LL(0xb32dffdb,0x61616eb3),LL(0x9f5d2095,0xdc4485a2),LL(0x6553371b,0xf7891124),LL(0xbf9b20af,0x4f06ba18),LL(0x1a2c4df1,0x136d4f29), LL(0xfb8b685f,0xc04aca34),LL(0xf2b657bb,0xeec83c20),LL(0x5925a36a,0x4da5d70a),LL(0x72ff2965,0x80608741),LL(0x9f352620,0x2e0dd9ff),LL(0x46d1a7a8,0x5f0afa67), + LL(0xf46aace5,0xa995a95b),LL(0x9eaa630a,0x44ede537),LL(0x00336e3b,0x421f3b35),LL(0xcf47c9ed,0xbf897478),LL(0x259e0827,0xf360ae32),LL(0x2e6a9f6b,0x04e0e3e8), LL(0xa9136702,0xb26eae5f),LL(0x853674b4,0xd6cb15a1),LL(0x748bcbc9,0xf81276e2),LL(0x0a4ca1d7,0x7fc02e22),LL(0xcd82f330,0xf650f48e),LL(0xabaa8859,0xf4ea7c1d), + LL(0x95c746ec,0x1ccd44ff),LL(0x10405763,0xe18914b5),LL(0x21a3a927,0x50ed6443),LL(0x43ef8e8f,0x4f96a1b1),LL(0x77952bf8,0x7f5645e5),LL(0x66dbdf15,0x4bc5c7ab), LL(0x23930a08,0xacc16126),LL(0x504cf9b6,0xbf5ed482),LL(0xd71ecbd7,0xdeb7a798),LL(0x4a4dd859,0xf62e63b1),LL(0xdaf714d9,0x668809a7),LL(0xf3a4329e,0xdd836382), + LL(0xc48f3ad5,0x894bdbd9),LL(0x09e167f6,0x687ff8de),LL(0x30371c43,0xf06104a9),LL(0xce84dd10,0x82fd34b7),LL(0x66ce5abd,0xae122deb),LL(0xfc4a90b2,0x31f041d2), LL(0x9a01c607,0x2589535c),LL(0x695bd7ab,0x231bcc85),LL(0x62e3a31d,0xc67c3062),LL(0x7af3e186,0x31be4475),LL(0x88efa7f1,0x1a2077a3),LL(0x815fad1a,0xffe53e22), + LL(0x66229776,0xdd155913),LL(0xf7882064,0x84093730),LL(0xe50ee337,0x6dddcb14),LL(0x7a1f7e81,0xa8e6ec59),LL(0xf3738a6a,0x8467f998),LL(0xad3f1840,0x70fcc6bc), LL(0x723b3f4b,0xf82eb4be),LL(0x06beec1b,0xf0f39354),LL(0x7ddcb539,0x1b181ea3),LL(0xad6a81b9,0x9c82c4fa),LL(0x5c612c2b,0xcc5ea543),LL(0xbb258d6f,0x63ce7571), + LL(0x0b96547f,0x1b588855),LL(0x65d1a59d,0x4539c9c0),LL(0x26e15084,0xd6c95fea),LL(0x86b96242,0xf84ad9e2),LL(0x451a5486,0x92f57d6d),LL(0x06a9e87e,0x0215cfcb), LL(0xf66e46f3,0xe05b10ea),LL(0x655a0642,0xe7b0e72f),LL(0x7b117f43,0x03503267),LL(0x779ea4a1,0xf5b78105),LL(0xa4adac77,0x28ee00fa),LL(0x6a93a2b1,0x1ea67d71), + LL(0x26882c6c,0x7be81fb1),LL(0xecd25498,0xe2d5a251),LL(0x7a8d1678,0xbb3d40e2),LL(0xd520811e,0x1806c67a),LL(0x86f65d23,0xadd4bb66),LL(0xe20e23d7,0x3a62b1b3), LL(0x6548b3eb,0x208b4700),LL(0xb7ec2809,0x0497f09a),LL(0x121c37e2,0xbd3964f8),LL(0xa598efbb,0xd35ef301),LL(0xc5eef966,0xbd76a276),LL(0x0af64e46,0x64700a7f), +}, +/* digit=42 base_pwr=2^210 */ +{ + LL(0xd3812087,0x169474a2),LL(0x6698ca7a,0x9de300da),LL(0x2ede425b,0x8589de92),LL(0x6df8a890,0x50e03fea),LL(0x4ba8b8e3,0x0d8a5c1c),LL(0x3fffb91a,0xf273aa67), LL(0x75fc8236,0x21cf0544),LL(0x9799c242,0x6ceafacf),LL(0xd0962c81,0xc3237eae),LL(0x213f6004,0x43d6ac34),LL(0xd4148b6b,0x45e619b2),LL(0xea5fb80a,0xfafa18b5), + LL(0x2f063b51,0x9a8580aa),LL(0x1c216613,0xa83c8ff7),LL(0xbe07f781,0xb4da0970),LL(0x712f7b7c,0x0ac2a260),LL(0x436a7b97,0xc9b8ee84),LL(0x11fb2f62,0xd758c20d), LL(0xf170b799,0x5daabed9),LL(0xc46bc387,0x018d2fdd),LL(0xd96cfb8e,0x82d6b5b7),LL(0x44d9e843,0x4d7d0d93),LL(0x91e7da3c,0xfa2a9ea9),LL(0xd531b253,0x8230c1a3), + LL(0x5ec31754,0x82412f52),LL(0x9d32e890,0x42f462c8),LL(0xce897ff2,0x1e7b58ce),LL(0x41164628,0xcfef7852),LL(0xd8bb22ef,0x34ee0422),LL(0x7d32f01b,0x6e0d44ac), LL(0x5a3cc196,0x96825165),LL(0x99eb23d3,0xa26724dc),LL(0xa75f7252,0xdb575faf),LL(0x62a3e5b1,0x778e3330),LL(0x84cccc80,0x8689884e),LL(0xb645502d,0x9883cd19), + LL(0x34220e26,0x4cc41f28),LL(0xa49749c4,0xb5937c6d),LL(0x0fa1ca24,0x70536664),LL(0x91e5edaf,0xeeb40f3b),LL(0xf1d3de14,0xcdf98235),LL(0xff018c43,0xa65e5b7e), LL(0xacee3a6e,0xaa3228e7),LL(0xe08f4ff1,0xb63a6289),LL(0x650b2daa,0x90e90425),LL(0x6d875f17,0xe4a8cad2),LL(0x9ce8a46e,0xc212029c),LL(0x5ed7cfb5,0xce051283), + LL(0x59b79436,0xb0df2261),LL(0xa195be26,0x82bd0daf),LL(0x3398c317,0xbc99a94b),LL(0x3c96ee31,0xbeb44c90),LL(0x664d2e46,0x3c39ad81),LL(0x0a3e0585,0x08178752), LL(0x413e269a,0x9a054b6b),LL(0x98c3b62e,0xbe58891d),LL(0xe5734974,0xe7fa4c4d),LL(0xd0a846a8,0x8ac535f4),LL(0xa651339c,0xea0f95f1),LL(0xd96aa239,0xa255274f), + LL(0x9534047e,0xe23b7b22),LL(0x3a3bd625,0xbd70aea8),LL(0x238db60b,0xf44b05fe),LL(0x0293abcf,0x9c46fb14),LL(0xbfd8875b,0x12cab5d3),LL(0x12dd0c65,0x1f38d4aa), LL(0x2adf9805,0x4bed4157),LL(0x8a56609d,0x3f87da92),LL(0xda02c903,0x10b93363),LL(0x21ce4786,0x7ecc7266),LL(0x1e3da5bf,0x8ae36685),LL(0xd3edee12,0x196040ff), + LL(0xe81508e8,0x4805841f),LL(0xa4808642,0xe2a578d3),LL(0xcd0b2555,0x6bbf10ac),LL(0xaf5cde28,0xc5071eff),LL(0x9a7124a9,0x665e7543),LL(0xc1437981,0x157c11ed), LL(0x7aeddd8b,0x2019367d),LL(0x386e3b8a,0x74a1e104),LL(0xfbe09a42,0xe72d429b),LL(0x061b862e,0xaca96fd9),LL(0x122595f8,0xbb2d2bc8),LL(0xc509d644,0xc90c6503), + LL(0xcff05ada,0xadb5966f),LL(0x5c57284e,0x8ed26c02),LL(0x44693a95,0xa76e73e2),LL(0x5982bbd3,0x14da7435),LL(0x5d2ca132,0x46e982cd),LL(0x24938e76,0x8f390740), LL(0x0a89b09a,0x749206b3),LL(0x93b4a1e5,0x429653c7),LL(0x7025bb7c,0xbee3d156),LL(0x19555c9e,0xe23f0e1e),LL(0x751639ba,0x0dec3837),LL(0x05d43bd0,0xb36cb844), + LL(0x74f90b6e,0xae76a96e),LL(0x24c6789c,0x5fa8e948),LL(0x03abbb81,0x2b3584bb),LL(0x5c451f72,0xe19ce47c),LL(0xd619ac7a,0x35792fba),LL(0x50059bf4,0xfa0282a2), LL(0xdabe692f,0x562bfd14),LL(0x47eeb6c2,0x1aaf542c),LL(0x045d0360,0x392d5bba),LL(0xd80fe998,0x4e7bb31b),LL(0x1111e14d,0x08f62ef3),LL(0x4e9ee1b8,0x4de917b0), + LL(0x67166271,0x8b9d2d58),LL(0x142bab7c,0x658db4ea),LL(0xa4ad2849,0xdf84932f),LL(0x5f6f86a7,0x04b11335),LL(0x50cfcea7,0x2de6b29c),LL(0x9be6a3a3,0x46d8f68a), LL(0xaf0204af,0xfb88cda7),LL(0x26029d72,0x3ece4491),LL(0x3f946dfd,0x69fef1e2),LL(0x01ef7bb5,0x708532fb),LL(0xeb3795a2,0x78d5053d),LL(0x6b36d57b,0x819a6320), + LL(0xe509d19e,0xca07e0c1),LL(0x9f6281b1,0x6c7e42c3),LL(0x77b66728,0x0e2ff439),LL(0x80e76251,0x1d740e78),LL(0x31a0eb23,0x6bfae4c6),LL(0xaa9b0b3b,0xd78ca917), LL(0x991e1781,0xe140c662),LL(0x0dd3cfee,0x6e396b5f),LL(0x6ce7f6c7,0xf0a1d197),LL(0xd5b01564,0xbe10f8ef),LL(0x101a5194,0x865cbd54),LL(0x66861ded,0xf6658852), + LL(0x5b28f7da,0xe4e52e86),LL(0x9a58683f,0xeb43a680),LL(0xb49f2b38,0x73b951bf),LL(0x3f8097cf,0x7b6cb7db),LL(0x328fbf05,0x9dfb8d0b),LL(0xebce6211,0x491635a5), LL(0x90fdd577,0xa31a1523),LL(0x1cd2f39c,0x334120df),LL(0x6b563876,0x1d22834e),LL(0x10ee5a28,0xfd91b30d),LL(0x59aee4ea,0x3d7a282d),LL(0x73300a76,0x36814c6b), + LL(0x6621c251,0x7b584add),LL(0x4233aba3,0x98da669d),LL(0x33aa2065,0x4d652b79),LL(0xdf7b4ed4,0x901bcfb8),LL(0x48012f81,0xb2ce5879),LL(0x3cb71b88,0xc18e2cd6), LL(0xff86279d,0xadb0f2bd),LL(0x5bd15866,0x46d9e5d6),LL(0xc635a4c0,0x11b1fb3e),LL(0x01b1006a,0x8bcd0ad2),LL(0xcbab210b,0x0f6f7502),LL(0x0d6b3995,0xd6cc3e56), + LL(0x137264c5,0xa54a6420),LL(0xf9c2e45e,0xa6ef0e78),LL(0xd58d850c,0xba8b5a73),LL(0x6ef6fc3e,0xc0209ed8),LL(0x91f7518a,0xe39dd0f3),LL(0x42b3eda6,0x74697b89), LL(0xabfc9150,0x2dccac36),LL(0x98b2f5a5,0x80e4fba2),LL(0x771018d5,0xe0e56fd2),LL(0x4c22bb94,0xa31fd168),LL(0x1a66ef21,0x8b0998f7),LL(0xb5a53ddb,0xed483e55), + LL(0xf23978eb,0x95db1c0e),LL(0xf04011f4,0x80ad1612),LL(0x4d7ae83d,0xe76bd182),LL(0x8fc3bd60,0x841d6e66),LL(0x6875e2d0,0xb68e8079),LL(0xd5d9dee7,0xe3965efc), LL(0x58930931,0xc488bb7e),LL(0xa907aa24,0x52f4de19),LL(0x321cc197,0x39aebbdd),LL(0x67de5c66,0xd2f5b1f9),LL(0x8efe3e76,0x60f1a8c2),LL(0xaf988831,0xf40604a0), + LL(0x0acb5935,0x78b5c14c),LL(0x4311d3be,0xd9ec715c),LL(0x09e1759e,0xffa22ab2),LL(0xb4b2f68c,0x5a86263d),LL(0x6b5be7f4,0x71e77c51),LL(0x19844f6d,0xfb5bea3a), LL(0x0890ffab,0x2519d006),LL(0xf0329ef0,0x426a03f0),LL(0x85b3c2a9,0x2c6d74a6),LL(0xc294f449,0x9306f68f),LL(0x2c69fb46,0x552e77c2),LL(0x10bb9886,0x7c7337ad), +}, +/* digit=43 base_pwr=2^215 */ +{ + LL(0x44b133d9,0x3313a9d5),LL(0x2da910dd,0xdb85c25d),LL(0x5e4dd5cd,0xc0fdef91),LL(0xc565dd67,0x902a2a93),LL(0x7fed05ac,0xd8eba4dc),LL(0xe157dae9,0xd453995c), LL(0xf250cb55,0xd655d0b3),LL(0x86119222,0x4194a09e),LL(0x0652872b,0x5b7e525a),LL(0xe68c0ddb,0xaf7968ef),LL(0xf51cb31c,0x2ec02930),LL(0xf2be071e,0x237f3ae4), + LL(0x94d0864f,0x9b23ab4e),LL(0x009c9fc1,0x46356266),LL(0xe798edf9,0xdbe99e51),LL(0x307675c7,0x38547449),LL(0x628c0fb6,0x23ffaf55),LL(0x1698c372,0x56ccd2a3), LL(0x8347ce95,0x39f45a57),LL(0x4f2c6118,0xe0aaec74),LL(0x4af138fc,0x2a89079e),LL(0x2ee4ecc0,0xb86371ea),LL(0x06bbf92f,0x076d256a),LL(0xae3c4c51,0x9073adb8), + LL(0x4c99252c,0xdaa77b43),LL(0x326cb0e1,0x59e38731),LL(0x03ca6c85,0x281a38cc),LL(0x433835a0,0x83565666),LL(0x30a928fd,0x3654ec9e),LL(0x7cb281f8,0x1c82abca), LL(0x13fafa6f,0xbeba0fe5),LL(0x99440e63,0x67432292),LL(0x0034d0cf,0xd62777af),LL(0x9cde52a0,0xd42b95fe),LL(0x6a23630f,0xb5b891bc),LL(0x64594976,0x8e4d2984), + LL(0x743c15d9,0xba2e9543),LL(0x1c99c984,0x7d5812db),LL(0x45bdc19e,0xf94db951),LL(0x382e77bd,0x951d00ae),LL(0xb220b29a,0x9940a5fb),LL(0x58fc91f1,0x6908d50e), LL(0xdd0940fe,0x682e42ea),LL(0xa1d32009,0x2124e23a),LL(0x16294d05,0xbe158100),LL(0x2e326d68,0xaea13fe3),LL(0x15e64fce,0xc0dfe1ef),LL(0xb8237a8a,0x32dbc0b5), + LL(0x663771f8,0xea6f1448),LL(0x9a0906cb,0xbf11f126),LL(0xd1a6a6a5,0x8c08219d),LL(0xdd56f277,0xf2af6e04),LL(0xd569188a,0x8ad26705),LL(0x6e071c9b,0xf0547631), LL(0xfd4aa6ec,0x945f40bd),LL(0x8486987c,0xbd6a8a8d),LL(0xb947b6f2,0x4f577728),LL(0x7aab6bc1,0xe2754a8e),LL(0xfb48a9ab,0x918d02cd),LL(0xbf904200,0x7e3ddaea), + LL(0x0bc28725,0xe59b8002),LL(0x149f8991,0xc6f8fa54),LL(0x5af5b47e,0x8799172a),LL(0x160d7e8d,0xf72c9780),LL(0xb2f9a549,0x1d1ce972),LL(0x4857b44a,0x8fce3f16), LL(0x1ed5e0e5,0x2545bdd7),LL(0xc259176a,0x222c33a7),LL(0x4e23c064,0x5a60343a),LL(0x1d1fd9cd,0x986779f9),LL(0x3570b5b3,0x5bd5611b),LL(0xf9d765a3,0x2758caea), + LL(0x3a16e352,0xd8135f00),LL(0x55d4e996,0xbfc784b2),LL(0x0a6874d0,0x5da46321),LL(0xe8e1e4d0,0xf1635286),LL(0xa0e9c4de,0xe71332b3),LL(0x60fc995e,0x5f076117), LL(0xc19ebb59,0x1c1305d1),LL(0x4603baa2,0x1d5987f2),LL(0xea7c9f9c,0x6b7885b0),LL(0xfe9ba1fc,0x362734e8),LL(0xb3892110,0x49a3ff32),LL(0xd4997512,0x0e5b2166), + LL(0xc36d3f25,0x6ee65a08),LL(0xe393e4d4,0x7b6c811f),LL(0x2876e523,0xc4a2cc38),LL(0xd3bf53aa,0xab7aba26),LL(0xdb7f290c,0x5bf00871),LL(0x1ee6d5bd,0x3cb1cd13), LL(0xde998ada,0x4cafb218),LL(0xf6319101,0xa1ecf36a),LL(0x20b281cc,0xa1fe7855),LL(0x64d9c65e,0xe457198e),LL(0xc5a0e67b,0xa3d1a6d0),LL(0x90cc468a,0x69ddbc32), + LL(0x53a38094,0x3f3cb2a5),LL(0x3b19448a,0xc9308152),LL(0x925ba579,0x9cf32819),LL(0x1801e686,0x44b9590a),LL(0xdf04be40,0xab6b284c),LL(0x2c216ae7,0xc40a58e6), LL(0x018a60e8,0xa6ced619),LL(0x83e5cc65,0x83d4cde1),LL(0xb5a91945,0xe2559f51),LL(0xef0f53ee,0x53d9122b),LL(0x32e40a83,0x474c281b),LL(0x944dfe65,0x332324a7), + LL(0xa1fd057d,0xcb0a3657),LL(0xb4aa013b,0xad79ae60),LL(0x97ed887a,0x0b852109),LL(0x30d9b297,0x5fec3e1f),LL(0x10fb9c74,0x4ce4149f),LL(0x8cbff785,0x4e08b4d9), LL(0x2f07cbae,0x81b0d7b4),LL(0x495230ae,0x08bc321e),LL(0x2b841eb8,0xaec221de),LL(0xd83c22e6,0x62c7d86a),LL(0x85affe91,0x5504dcf8),LL(0xf445481d,0x785a06f1), + LL(0x18670cf4,0x8b68acc4),LL(0xcba49dca,0x64073a95),LL(0x9f508534,0x633757b0),LL(0x916f3a09,0x78ad9df7),LL(0x08617468,0x46187c92),LL(0xc5f77b94,0x48f37eb6), LL(0xd058bb27,0x333224f0),LL(0xd8852abb,0x7f28ace7),LL(0xa2e62327,0x8c9f634f),LL(0xc4116c1b,0x75212283),LL(0xcc0c0851,0xb7723ad0),LL(0x5b72e5aa,0xc8a4cff1), + LL(0x6dadc46f,0xd4ee3f7f),LL(0x5d7febd6,0xa1f3dc92),LL(0x63ebab5b,0x4c0bee13),LL(0x005ec237,0x70e32d77),LL(0xc52fb006,0x302fc73d),LL(0x8f159899,0x1af84c0a), LL(0x0686232a,0x42a5478f),LL(0x8a308687,0xb4fc5634),LL(0xc8378f0d,0x042c4970),LL(0x8e2c86c5,0x70c19575),LL(0x84c7c767,0x61a95e68),LL(0xd6fb43a8,0xd96a8216), + LL(0x1a2db746,0x67f8fa3e),LL(0xba267cad,0x2f041d4a),LL(0x65bafbee,0xdf8126ea),LL(0xfad7b234,0xf63fc68f),LL(0x702db8ab,0x4280e1e1),LL(0x02468fc2,0xbe6122f2), LL(0xc89b74de,0x06b076d0),LL(0x4bbdb7cc,0xc2515543),LL(0x50eb6108,0xae82a08f),LL(0x2f0f3f5e,0xf49da234),LL(0xeca6448e,0x7d1923b2),LL(0x70b144ab,0x9e01d58c), + LL(0xee49a1bf,0xeaf237a8),LL(0x4ea1da86,0x78bf04bf),LL(0x3f251ad5,0x5fbffa47),LL(0xd828578e,0xc40570f6),LL(0xd4e118ad,0x5cc65c0d),LL(0x5da48548,0x9e18ff96), LL(0xef7e714b,0xe27fc2e7),LL(0x13df7524,0x19ff3f7c),LL(0x5e27fb12,0x35a32fa5),LL(0x10003fae,0x7fcfd728),LL(0xf49800c1,0xc74b50a3),LL(0xdbafb2e6,0xbf0732eb), + LL(0xc1238c95,0x1d1b02ab),LL(0xee8c4d2b,0x85b3878a),LL(0xc761afd0,0x23ba366c),LL(0x4f023bb7,0x47324d03),LL(0x388c8e5b,0x75902ccc),LL(0x86e2e6b6,0x374484b9), LL(0x9f548719,0x38360f84),LL(0x41cbc7ef,0xdf999916),LL(0x5091ed27,0xa9cbe298),LL(0xc5f2cb5d,0xcf5a1440),LL(0xd413500d,0x5bdff729),LL(0x373f8b2d,0x55530d56), + LL(0x543c1255,0x0c62fd2d),LL(0xef361a27,0x71ea9c6f),LL(0xcef3f9e3,0x76b0933d),LL(0x9889ffa2,0x51b1ec2d),LL(0x9a3c88d2,0x9e84b2ba),LL(0x1913e52f,0xc8996b96), LL(0xcee43e36,0xbafc5e94),LL(0x70c658b7,0xd9898d24),LL(0xbed17108,0x4e9bcc41),LL(0x6c7a41c8,0x0db5b733),LL(0x795369cd,0xd4be07a7),LL(0x7bd3a934,0xb899f92f), +}, +/* digit=44 base_pwr=2^220 */ +{ + LL(0xde1e4e55,0x3f2eff53),LL(0xe4d3ecc4,0x6b749943),LL(0x0dde190d,0xaf10b18a),LL(0xa26b0409,0xf491b98d),LL(0xa2b1d944,0x66080782),LL(0x97e8c541,0x59277dc6), LL(0x006f18aa,0xfdbfc5f6),LL(0xfadd8be1,0x435d165b),LL(0x57645ef4,0x8e5d2638),LL(0xa0258363,0x31bcfda6),LL(0xd35d2503,0xf5330ab8),LL(0xc7cab285,0xb71369f0), + LL(0x14c5969b,0xf16938f5),LL(0x944b2271,0xde2e3cf0),LL(0x0b6490d6,0x2d509553),LL(0xa28a296a,0x8432fef1),LL(0x8d26415c,0x6f254dd0),LL(0xd50c2865,0x3780eead), LL(0x665b8794,0x4f5bc455),LL(0x56cb7018,0xef31fb9e),LL(0x65e59340,0xbab8dd6e),LL(0xa56dc2ea,0x676baca2),LL(0xeaa90e05,0x38eea06b),LL(0x174bada0,0x26e64224), + LL(0x40acc5a8,0xe6a19dcc),LL(0xdbc6dbf8,0x1c3a1ff1),LL(0xc6455613,0xb4d89b9f),LL(0xa7390d0e,0x6cb0fe44),LL(0x59ea135a,0xade197a4),LL(0x20680982,0xda6aa865), LL(0x5a442c1b,0x03db9be9),LL(0x2bfb93f2,0x221a2d73),LL(0x753c196c,0x44dee8d4),LL(0x0b7c6ff5,0x59adcc70),LL(0x4ca1b142,0xc6260ec2),LL(0x46cbd4f2,0x4c3cb5c6), + LL(0x2cb40964,0xa35e411c),LL(0xc331a3d6,0xdd7d4f4c),LL(0x89a66f2b,0x7c7c859e),LL(0x0def8ecd,0x9908c37e),LL(0x344947b7,0x8274124e),LL(0x568b0ce8,0x0d279f7b), LL(0x866091ec,0xe5291961),LL(0x3a08acc7,0xb056e3bf),LL(0x56bd3a7d,0x60fb39e1),LL(0x268f8562,0xe56a34d6),LL(0x13fd8293,0xb3a1fe16),LL(0x67537fcb,0x6a41e1a9), + LL(0xa417111f,0x8a15d6fe),LL(0x71d93fcc,0xfe4a16bd),LL(0x55bbe732,0x7a7ee38c),LL(0x1ff94a9d,0xeff146a5),LL(0xdd585ab5,0xe572d13e),LL(0x06491a5d,0xd879790e), LL(0x2a58cb2e,0x9c84e1c5),LL(0x6c938630,0xd79d1374),LL(0x385f06c7,0xdb12cd9b),LL(0x7a7759c3,0x0c93eb97),LL(0x683bd706,0xf1f5b0fe),LL(0x85ec3d50,0x541e4f72), + LL(0xc6bb5e5f,0x89e48d8b),LL(0x1ea95a10,0x0880ede0),LL(0x302c0daa,0x60f033d7),LL(0x048eefe3,0x15e4578a),LL(0xb0a72244,0xfd6dec89),LL(0x309489cd,0x1f7cd75e), LL(0xe9aba7fd,0x7cdcc2a0),LL(0xf28ba00f,0xd18dc5c7),LL(0x5812b55f,0xa6300a45),LL(0x2ca31d8c,0x8fa5c415),LL(0x4f3a5b5a,0x36aa3c23),LL(0xc86cf4e0,0xd128739e), + LL(0x81833608,0x9a0e1535),LL(0x6e2833ac,0x5cce871e),LL(0xfb29777c,0xc17059ea),LL(0xe354cafd,0x7e40e5fa),LL(0x4d07c371,0x9cf59405),LL(0xa71c3945,0x64ce36b2), LL(0x56caf487,0x69309e96),LL(0x1ae3454b,0x3d719e9f),LL(0xe25823b6,0xf2164070),LL(0x0bc27359,0xead851bd),LL(0xb0925094,0x3d21bfe8),LL(0x34a97f4e,0xa783b1e9), + LL(0x13575004,0xd9272830),LL(0x20b2275e,0x01a330d6),LL(0x450db713,0x58b9207f),LL(0x23e16d95,0xae953384),LL(0xe60e349c,0x4f10c6d4),LL(0xfeb122bc,0x541d03ec), LL(0x2c648211,0x22548cd2),LL(0xd01354f5,0x5c2dc84c),LL(0xb6167b3c,0xa1c6f912),LL(0x7902d2ba,0x6967bab2),LL(0x36de34ba,0xebbe0b08),LL(0x4b79625e,0x6985b33a), + LL(0x9546491a,0x406b0c26),LL(0xf293c4e5,0x9e5e15e2),LL(0x15b164db,0xc60d6413),LL(0x0c75a78e,0x0da46f53),LL(0xea0c656b,0x7c599bb7),LL(0x1b1a8122,0x0f07a512), LL(0x15172686,0x14c7204a),LL(0x5165625d,0x8faedff8),LL(0x37aede40,0x20f260ce),LL(0x8f357ffe,0xc81f771e),LL(0xb0912557,0x25499197),LL(0x4c739c74,0x736197dc), + LL(0xaefdd5e1,0xf2d015bd),LL(0x4bf9edae,0x33b4e21c),LL(0x64b35fcc,0x4860aadc),LL(0xf13f8112,0x77b657e9),LL(0x90dc84fe,0x65f28625),LL(0xd66be036,0x4eabfd22), LL(0x6ff05dd0,0xb0213123),LL(0xa9fe5d11,0xa104d4aa),LL(0x9b8ae390,0xdc7efe3b),LL(0xeb87fb5c,0x46918b54),LL(0x72b7172a,0xf5771d71),LL(0x13587bf0,0x41e49e47), + LL(0x381b3462,0x6151bab1),LL(0x43dbd344,0x27e5a078),LL(0xa1c3e9fb,0x2cb05bd6),LL(0x27cf2a11,0x2a759760),LL(0xff43e702,0x0adcf9db),LL(0x1f484146,0x4bbf03e2), LL(0x55b6521a,0x0e74997f),LL(0xade17086,0x15629231),LL(0x7493fc58,0x7f143e86),LL(0xaf8b9670,0x60869095),LL(0x7e524869,0x482cfcd7),LL(0x1d454756,0x9e8060c3), + LL(0x9004b845,0x3ec55ddc),LL(0xbe7b06eb,0x5101127c),LL(0xfc4176e9,0xdddafd57),LL(0xe4a31ddc,0xd8cb31c0),LL(0xd42feabb,0x94e83a89),LL(0x2f74ec68,0xd4401def), LL(0x5adb654d,0x9c9defb6),LL(0x5053eeda,0x9a3513f0),LL(0x7cdb455e,0xceab2dec),LL(0x59d24f59,0x99542808),LL(0x31d30504,0x22ead452),LL(0x0521a229,0xe9df48f9), + LL(0xc88b4d3b,0xe495747a),LL(0xae8a948f,0xb7559835),LL(0xdeb56853,0x67eef3a9),LL(0x9dee5adf,0x0e20e269),LL(0x61f0a1aa,0x9031af67),LL(0x683402bc,0x76669d32), LL(0x06718b16,0x90bd2313),LL(0x864efdac,0xe1b22a21),LL(0x6620089f,0xe4ffe909),LL(0x3428e2d9,0xb84c842e),LL(0xfe3871fc,0x0e28c880),LL(0x3f21c200,0x8932f698), + LL(0x441d0806,0x36dd28ea),LL(0x21518207,0x6680c72c),LL(0x0a484dbc,0xc5d40e28),LL(0xa3a2ba6e,0xdb1170c6),LL(0x40a91c7d,0x07290fd1),LL(0x95ee9ca2,0xdd125716), LL(0x07876188,0x595dad63),LL(0x499d4827,0x6fcf18c0),LL(0x206e617d,0xdcd946a3),LL(0xe7bceaef,0x6cf08f51),LL(0xb19a06ac,0x7a85c02d),LL(0x7140a7df,0xf1365fc6), + LL(0x6c90ea5d,0x603f00ce),LL(0x40a2f693,0x64739307),LL(0x2174e517,0xaf65148b),LL(0xf784ae74,0x162fc2ca),LL(0x4d5f6458,0x0d9a8825),LL(0x43aace93,0x0c2d5861), LL(0x9f73cbfc,0xbf1eadde),LL(0x9c68bbca,0xde9c34c0),LL(0x67ef8a1a,0x6d95602d),LL(0xa791b241,0x0af2581b),LL(0x12cad604,0x14f77361),LL(0xe2acd1ad,0x19f2354d), + LL(0x771560ab,0x9e857f33),LL(0x250f109d,0x4ae1ba22),LL(0xff4f6566,0xf8538d68),LL(0xac339148,0x35380f15),LL(0x5ddfc12f,0xfef0bfdd),LL(0x1387d93e,0xf706c6bf), LL(0x5357e131,0x618ce77d),LL(0x236478c4,0xf0921744),LL(0x00dc0da5,0x24eaf06e),LL(0x07603cc7,0x049113be),LL(0x8f6963c7,0x5cf48908),LL(0xede4a300,0xbe5eb9e6), +}, +/* digit=45 base_pwr=2^225 */ +{ + LL(0x5d066c15,0x77e486f8),LL(0x4ed5307d,0x0c05b6c2),LL(0x7df36628,0x322b28ab),LL(0x6704dcd6,0x2d14d131),LL(0xf29a3567,0xd359977a),LL(0xec96d3b6,0xc29bb132), LL(0xe6bfa701,0xfd6e400a),LL(0x4c7e5101,0x03db9924),LL(0x9b8533af,0x62d81c7d),LL(0x8de66eb8,0xefa638c2),LL(0xe86784ee,0x7405a9d7),LL(0xa6c22223,0xafaa74ef), + LL(0xb9d36e91,0xf9b2dba4),LL(0xfda9b2c4,0x5fb4f6ce),LL(0x3b8104ee,0x7692a4f3),LL(0xe4e1896e,0x5da885b0),LL(0x73d2aa36,0xc2a30fec),LL(0x86f60bca,0x7d06e6af), LL(0x87287887,0xbc8bf16d),LL(0x3d701bec,0x6c3dd86a),LL(0x7e35610a,0x8e79e2f3),LL(0x82f9d71c,0x981139f4),LL(0x24e62733,0xf8997ec4),LL(0xa3518061,0x330d989a), + LL(0xca89fbad,0x4e6ef410),LL(0x53933b78,0xe0fc53ba),LL(0xfd41d143,0xa4f03403),LL(0xe0774c37,0x3a507177),LL(0x8ec7484a,0x078e8c56),LL(0xfbb3f66b,0xfb73c6b6), LL(0x3bfbdff6,0x169c9475),LL(0x0a232243,0x44d28606),LL(0x08303114,0x3e8e9685),LL(0xfad0def2,0x7a9797b8),LL(0xefc1c8da,0x0ad14404),LL(0x21ced721,0x6daae4e9), + LL(0x88dd2dc2,0xc7e9ddef),LL(0x19a0c0b5,0x2c21a998),LL(0xb239bb82,0x6bc0746d),LL(0x28ea1341,0xc811a8eb),LL(0x1d1309b0,0x5f714ca7),LL(0xd4eb9b34,0x79eabd20), LL(0xdf0fb30f,0xe0e5afdc),LL(0x8c0814c6,0x1b01a16d),LL(0x84334366,0x670e1e7b),LL(0x0eed1116,0xc8c38f9a),LL(0x619bbd50,0xf914fae2),LL(0x51c1995a,0x1ed062cb), + LL(0xcb583422,0xd4e60e15),LL(0x320f296f,0xc6b1ef90),LL(0xd9bfc834,0x0714bad0),LL(0x9050e2c2,0x5ee2ca8c),LL(0x24f7cf1d,0x074a8ca8),LL(0x10df8516,0xb9750249), LL(0xc2636d2c,0xecee8ab7),LL(0x3b4b7bbd,0x308e5af1),LL(0xee2ae021,0xfed4f27e),LL(0x2065253b,0x7cd4bb19),LL(0x4de525b4,0x6b21a3f8),LL(0xac27fddb,0x0f10e7bd), + LL(0x870e29cb,0xd5068487),LL(0xfc52d5cb,0xf9420b85),LL(0x496d000d,0x50c3265a),LL(0x166bd6b4,0xe605414a),LL(0xc62b2a6c,0x4de8d724),LL(0xa1a11048,0x16af06f2), LL(0x45f43c4c,0x5406bde9),LL(0x751ad18e,0x5e15bf6c),LL(0xb6a59587,0xa846e665),LL(0x1816ac55,0xcdb28a7d),LL(0x819b73f8,0x899b3551),LL(0xbc848d08,0x2d46297b), + LL(0x299127be,0xdc4cc720),LL(0xfaab8165,0x5b34e762),LL(0xb39c120d,0x2289b2f7),LL(0x6e52b913,0x687a78d0),LL(0x2a3ea6a5,0xd2a091dd),LL(0x38eab329,0xc61eced6), LL(0x7887ff2b,0x652231ea),LL(0x0479db4e,0x77a56875),LL(0xd43c5722,0x1ef471c8),LL(0xf3764c34,0xf82bf436),LL(0x0445cafe,0x962af405),LL(0x5ff47259,0xed8b227f), + LL(0xd89594ab,0xde849cd1),LL(0x0ec4fb3a,0x00e2d2b1),LL(0xabe92fba,0x3fbd9e3d),LL(0x3324900a,0x785414d4),LL(0xde20904e,0xdaead1ab),LL(0xaa5f1ba8,0xb493e121), LL(0x6eaea0dc,0xd60a4f2d),LL(0x6fca8596,0x394746b5),LL(0x34efa243,0x163dc789),LL(0x216a8d8c,0x3067dccf),LL(0xa901617b,0x116b6534),LL(0xbbabe51e,0x8c4bd099), + LL(0xac3a082c,0xc8c2df45),LL(0xc8d4c40e,0xc353d074),LL(0x5a3c2de7,0xb214f9c0),LL(0xf86b0214,0x504bc42c),LL(0xd1922a58,0xc82df5cb),LL(0xa5bc3267,0x40887948), LL(0x88ba8bb2,0x04bcd217),LL(0x046fd401,0xe21b3e7f),LL(0x616af5cf,0x8419c338),LL(0xaedfce9d,0x7f24760b),LL(0xddbd519a,0xded8035b),LL(0x1693faab,0x1f1fb0d7), + LL(0xd02ffcf6,0xbb067b49),LL(0x3e657299,0x7cedf8f9),LL(0x406bbfe3,0xc3829961),LL(0x37c12472,0xefe4b5aa),LL(0xfec7dee8,0x7dc01cf9),LL(0x89472f50,0x70a9db23), LL(0xb31bf737,0x29c269f8),LL(0xae3fa7db,0xa26deac3),LL(0x33caca41,0x0046e912),LL(0xb6e78b55,0x3bf4bc8a),LL(0xd9eb5ef1,0xca83bc6c),LL(0xc0c5deff,0x73f25c62), + LL(0x44b4aae8,0x697dc47d),LL(0x782c331c,0xb3525cc0),LL(0x0bd7c78c,0xff71cca4),LL(0x10c0ab69,0x5f3d7766),LL(0xe2ba07e3,0xbdc10267),LL(0xe6373f6e,0xc656f75c), LL(0xb5607b62,0x9e2938b4),LL(0x10b0a0f7,0xa65017d4),LL(0x5cc6ac25,0x8dad3119),LL(0x8ba5d1e6,0x00f8f2d1),LL(0x43305aef,0x608137bc),LL(0xdcb81cb1,0xddad34bb), + LL(0xb1f82ca5,0xe133d941),LL(0xfdf115bf,0x2af8b98b),LL(0x57aaa6f3,0xdc6179c8),LL(0x130ade06,0xabaa83e9),LL(0x0e8bffd1,0x7836b6fb),LL(0xfa103703,0xc479751f), LL(0x9c89963b,0x0ff3c129),LL(0x0b84c24f,0xe6407256),LL(0xf34f6bc9,0xa92a4ea2),LL(0x3197989b,0xba45b305),LL(0x99243aab,0xd12b5a01),LL(0x442af625,0x3015772c), + LL(0xe6f065c5,0xd95fca81),LL(0xfc8655de,0x45e886d5),LL(0x27cff79e,0x35809577),LL(0x625877d9,0x92a39a34),LL(0xdfee17ee,0xdda02684),LL(0x986f635b,0x6354f871), LL(0xd409c182,0xb3a6e9ed),LL(0xc4fbbb3a,0xf0b1c8d9),LL(0x9b77aded,0x28721c01),LL(0xbf94f028,0x3c356df1),LL(0x29a81f1a,0xff221bd2),LL(0x56b20b0d,0x20edf2e8), + LL(0x835fda9e,0x97fff124),LL(0x0bc68512,0xa79ceb2f),LL(0xa2fc3995,0x70ba93d1),LL(0x9e51c5ee,0x62bd28ab),LL(0xd5bbbaa9,0xb95fa624),LL(0x8c1f571e,0x0654dc45), LL(0x65a45ed6,0xb9a4edc6),LL(0x21ad0612,0xbf5ed1bc),LL(0xb1a3551b,0x74adc1a1),LL(0xdbbd6cef,0x3dfa3dc8),LL(0x2fa3afd2,0xce5dd40b),LL(0x30a746ca,0x14894e0f), + LL(0xb8ca2a2c,0x7e729c58),LL(0xcaac04af,0x0f32ea1e),LL(0xbdd549e3,0x47267f13),LL(0x90be3b50,0x35b94406),LL(0x4b27f670,0xad0f2bb1),LL(0x92341803,0xd7e5874e), LL(0x1f9ec462,0x7dc841cf),LL(0x512b2a42,0xebeff994),LL(0x320dc858,0x22998a7f),LL(0x19946f59,0xf08eb5c7),LL(0xa68ea75e,0x228c8dcd),LL(0x7b20dee5,0x40dc6dc3), + LL(0xb3952db4,0x929454f6),LL(0x4d3f69f5,0x412142ec),LL(0xee25c0b0,0xf5b0a7c5),LL(0x2e752295,0x7d3372ff),LL(0x6eacac68,0xd6dadc7d),LL(0xa96a8e3c,0x5f0076cc), LL(0x71725b3a,0xea831db6),LL(0xc29ab454,0x4a286c89),LL(0x72e3c00c,0x5ff817e5),LL(0x2a5fb6ba,0xb022e25d),LL(0xbb392476,0xb611c5bc),LL(0x190485a0,0x062c14dc), +}, +/* digit=46 base_pwr=2^230 */ +{ + LL(0xc419b0aa,0x0372678d),LL(0xc13fdf17,0xf95031d8),LL(0xb79594c3,0xebaebca4),LL(0xaf3b75cf,0xe587850b),LL(0x2c1e09c6,0x534183ac),LL(0xc08204cd,0x3f5b0bfd), LL(0xe297cc77,0xdac2cf06),LL(0xd0487084,0x5e47d9c6),LL(0x90b0f6c2,0xf6f509f4),LL(0xc2c62207,0x3ffc3cd6),LL(0x32ff1887,0xbb21eb11),LL(0xe62ccc6f,0x2116a023), + LL(0x16960728,0x406a7e21),LL(0x5597d8c4,0xd03923f8),LL(0x020748ee,0xd4402eff),LL(0xf39b58db,0x7827442a),LL(0x8d8cfb04,0x77e3f276),LL(0xe45a978f,0xf6eb49c8), LL(0x49247f6a,0x9db08299),LL(0x06669fe5,0xce71a747),LL(0xb82775f5,0xe434ce47),LL(0x63910016,0xe84995ef),LL(0x1e47792f,0xa35e8b97),LL(0x7c6aaeb9,0xc779cb3d), + LL(0xff381db7,0x66428800),LL(0x55574ac6,0xa9b9d019),LL(0xbdf4a86c,0x30cdc21f),LL(0x741c4a26,0x2ec38d35),LL(0x0b6be057,0x35496c23),LL(0x01656b1f,0xaecc67e6), LL(0xf7d70324,0x781af00f),LL(0x5d7ee71e,0xac0e6579),LL(0xa6b14e3a,0x60a35c6c),LL(0x0e6c1c3a,0xacd6813b),LL(0x1faeef73,0xd7f77024),LL(0x23eddf05,0xd2254b8f), + LL(0xaf31ea1d,0x1fa064cf),LL(0x48e8d974,0x2a9547a8),LL(0xfa9d9453,0xda8102a1),LL(0xdc6bd7ea,0x786aecab),LL(0xca2f6044,0xcaf91e3b),LL(0x8573f208,0x67d86ea7), LL(0xc505ae24,0xd309fce9),LL(0x7f86eb8e,0x67ddc5b1),LL(0xf3d53056,0x57791ae0),LL(0x0d1fd61e,0x26b053f0),LL(0x045ebfa6,0x91c962c0),LL(0x076ed979,0xe95246de), + LL(0x5f6e9ea4,0xc49c9989),LL(0xe16ec8e4,0x4a91578b),LL(0x0aeb5ac5,0xa1c54e89),LL(0xee09b9a0,0xa9094b07),LL(0x09a74b27,0x3587752f),LL(0x44bbfed0,0x973bf8b0), LL(0x5636a52e,0x91c26f23),LL(0xeb7e3b41,0x8ac948b8),LL(0xfc457d56,0x14234675),LL(0xc76398a3,0xde98e4fa),LL(0x0f4a46e0,0xa80f7311),LL(0x22b66fa3,0xcba089bd), + LL(0x0746d174,0x156eaf57),LL(0xcda35250,0xa2d4a83d),LL(0x0290fa02,0x60a9f48c),LL(0x5c33b4ac,0x9855d26d),LL(0x97eb1c30,0x06e379c6),LL(0x6e219664,0x4f2e2dbe), LL(0x29006065,0x6b7448f8),LL(0x115062a9,0x237a1f31),LL(0xad92cb24,0x5c635a90),LL(0x2eed977e,0x2e857f8c),LL(0x856dc88a,0x3d512df7),LL(0xe597a27b,0xbde85263), + LL(0x10a98e42,0x0b114aea),LL(0xae19dd14,0x6133aa52),LL(0xa99eb2c5,0x0c235df2),LL(0x7f59582c,0x0085a619),LL(0x8cf7feba,0xf9002bba),LL(0xaf6a3261,0x275742d7), LL(0x249e8e9e,0x302b4823),LL(0xce696f91,0xa142aba9),LL(0x64c37b14,0xdeb28c44),LL(0x0766002f,0x14bb8f23),LL(0xc52fe891,0xafeff88b),LL(0x46faeb2d,0xb9d493ae), + LL(0xe7c03ce4,0x49f24994),LL(0x2aed9ba3,0x274a8c13),LL(0xd5e91bc0,0x897b9103),LL(0xcb404f68,0x63db1efb),LL(0x42f7fc02,0x70efd9d8),LL(0xc6a230af,0xd6e02921), LL(0x11ae0a56,0x8d5b199f),LL(0xce33da6a,0xc98287de),LL(0x504dd889,0xde583d34),LL(0xf823686f,0x03756001),LL(0x95fc73dc,0xf19ab86f),LL(0x93f12f42,0x300406c6), + LL(0xa427d89c,0x68fdb78a),LL(0xa3944c0d,0x84e9ba49),LL(0xc1833422,0x1c3569b1),LL(0x1a01f4b9,0x30773fc0),LL(0x7da01321,0x18b8f17d),LL(0x7198c85e,0x8370fb0f), LL(0x99a898e3,0xda12c8d4),LL(0x8ba82ded,0x7667b46a),LL(0x77e1e31f,0x2aab259b),LL(0xbe71c9bc,0xd03f7708),LL(0x8e43eb38,0x9f784cce),LL(0x21c1208c,0x7ddedc8b), + LL(0x7759701c,0x2f73595f),LL(0x6fe0e0d9,0x8dc2069a),LL(0xc286a65d,0xb7de7114),LL(0x84c0e487,0xfecc429e),LL(0x14344c07,0x51061a2c),LL(0x96869e37,0x4d709725), LL(0x2be9403b,0x8b02781f),LL(0xde3ab5d9,0x6cb6aa02),LL(0xff6bdc9a,0xb013508e),LL(0xe5438c58,0x568d2e84),LL(0xe4206c3b,0x7b35a979),LL(0xb17a8bc7,0x0bb793c0), + LL(0x57ed2360,0x41248052),LL(0x6ba9bd95,0xfc0cb1b6),LL(0x2337a8fd,0x342f16db),LL(0x88099007,0xe1417411),LL(0x8cd74752,0xc96c29ee),LL(0xedf5fb4a,0x376047cc), LL(0x439546c1,0x5f40ce08),LL(0x1a235de8,0x14d2c666),LL(0x98e355f0,0x9b66892d),LL(0xa4bb19e9,0x8a65f6dd),LL(0x046a2581,0xf72848f8),LL(0x8373b2b6,0xfed74b3b), + LL(0xfa4dd561,0x3f896ca9),LL(0xd2de2ecb,0x4b9a98ab),LL(0x600e4e2a,0xd0741632),LL(0x69e702d5,0x87c7db5f),LL(0x53e0df2b,0x1f5a3b80),LL(0xf443dfba,0xe1e24b49), LL(0x5eef3a1d,0xeb90e230),LL(0xd38f73fc,0x8f3fc8a6),LL(0xa5aa335a,0xfb1e8299),LL(0x4197b32a,0xd78504cd),LL(0x6755918e,0x0e7a79cc),LL(0x883b1c72,0xc7c98ae2), + LL(0x969088c1,0x4b74fcbd),LL(0x361a8c96,0x4d16f895),LL(0x760d61fa,0xefcb6ced),LL(0xcc3e8808,0x3f14a7cb),LL(0x664ea335,0x51f5fd2c),LL(0x3a65d305,0xe0cad090), LL(0x031a6911,0x86409de9),LL(0xe5f9715b,0x23ea4aed),LL(0x1f3532c6,0x6e5b8cea),LL(0x11271ead,0x33fc873e),LL(0x5b8131d7,0x842b59a6),LL(0x61b7bf60,0xbd95818a), + LL(0x03d2becc,0x1a12727c),LL(0xc6741372,0x810a37df),LL(0xb7049f39,0x44ac483f),LL(0xa36fc614,0xab73e5e7),LL(0xeeff8aeb,0x298d453f),LL(0x7e1b586b,0x2127dd16), LL(0xe07bd60c,0xeadc5c54),LL(0xf5e2d2e2,0x67cdae00),LL(0xc9d2f10a,0x03fe0446),LL(0x95e38ed2,0x07840987),LL(0xe1a6306e,0x5d348a7c),LL(0x562f5463,0x4903f1b6), + LL(0x4a3862e8,0x906ab8a8),LL(0xb2f5c878,0x8fc76114),LL(0x2035287f,0x2dac3952),LL(0x18af4378,0xaa8372f3),LL(0xdbf64476,0x915050c9),LL(0xe992d0c8,0x896f734d), LL(0x3a35846c,0x5c3e36da),LL(0xac8f4fc3,0xfe774b4a),LL(0xaadd8a59,0x66347050),LL(0x2cd12be8,0xea94ebda),LL(0xdab94de0,0x45b1e7e2),LL(0x264b508c,0x539d580e), + LL(0xb44b1d0c,0xbf66baa5),LL(0xa44f8eda,0xbbed18ed),LL(0xeaaa466c,0x80bc32ab),LL(0xe5f2733b,0x605b7897),LL(0xa2531afa,0xe9e7e3a1),LL(0x3deb8369,0x25d66db3), LL(0xb2f25d10,0x36212ea3),LL(0xa08d303e,0x52d6b3f4),LL(0x444e9e9f,0xefa54b31),LL(0x69530c1b,0x9c2229a1),LL(0x4b79bdd1,0x68feb985),LL(0x8b984cc3,0xd570e84f), +}, +/* digit=47 base_pwr=2^235 */ +{ + LL(0x845f26e4,0xd6a4d25c),LL(0x1b039dff,0x71e554ce),LL(0x1cdedfc0,0x94205973),LL(0x03d6502f,0x0c4e3856),LL(0xe15ce8c8,0x981a4fc5),LL(0x7aca30b7,0x85d1b0f1), LL(0x77bb9e43,0xf2037ef7),LL(0xe87ae187,0xc52804f4),LL(0x71f3e4e3,0x9c98a23c),LL(0xf47b504b,0xa73c8b89),LL(0x023233aa,0xb9e33f54),LL(0xf92c9f68,0xf2bcfc17), + LL(0x7b3b336d,0xba03ba3b),LL(0x28c9c55d,0xe57ce509),LL(0x4f0f60b2,0xf96b8cfe),LL(0x6fcccd96,0xb908d77e),LL(0xe79dd17a,0x7208ef7d),LL(0x3ec3d048,0x73909533), LL(0x1163fe78,0x9c5ad2da),LL(0xcd4a15c2,0x4e2a8685),LL(0x470eb938,0xac999449),LL(0xee7d772f,0xfaaf27fb),LL(0xd0b7ad09,0xfbe402ab),LL(0x57db00a9,0x704d4f0e), + LL(0xe12b4e64,0xe93ee31a),LL(0x662d17f4,0x2ab8e378),LL(0x69516582,0x2544bd99),LL(0x2e1e5485,0x7bf80e4b),LL(0x729d9361,0xf30f0b14),LL(0x8268d40f,0xb3ffb5d1), LL(0xac193a63,0x34605055),LL(0xf8e04d69,0x9e5ca9a9),LL(0x085ecbb2,0xcbbeebc1),LL(0xf340eac4,0xda03b75b),LL(0x84436462,0x3bf9468a),LL(0x0f26f20c,0xdfa8b4c8), + LL(0x3fc14a85,0x10c082a6),LL(0x1c0b14c4,0x59389ebc),LL(0x4cb291a7,0x785d935b),LL(0x13e9ce08,0xfc2ae153),LL(0x4df6f1c4,0x3146fabf),LL(0xc87dd24c,0xa2a4a457), LL(0x1deb49bb,0x85fdd877),LL(0x9b055934,0x2b784370),LL(0x3e7e0297,0xc81d0501),LL(0xb92df904,0xb56ddd1f),LL(0x295ddccb,0x4612df9f),LL(0x0e27cf1d,0xc24bd4cf), + LL(0x422ea2c0,0x5564875b),LL(0x8285b03f,0xabc2e7de),LL(0x733e9f1f,0xfd662091),LL(0x68465da3,0x68f16745),LL(0x38fa6f63,0x965a0a05),LL(0xdfae710d,0x0ed70fee), LL(0x153b24da,0x56c6227f),LL(0x01470f6e,0xf1dcf574),LL(0xf51771cf,0x9992caa8),LL(0x14a9b029,0xa884b481),LL(0x7b9a4062,0xad11cbaa),LL(0xe55533e0,0x60ec99d8), + LL(0x18674f49,0x86d9b060),LL(0x97bb1a7d,0x81b06486),LL(0x27d9d64c,0x9b6e8e7c),LL(0xba04e6ad,0x79bd66ba),LL(0x828abbbe,0x77e4d0b0),LL(0xcc540d04,0xae7548ac), LL(0x869cbebf,0xf5d8a46f),LL(0x38a6cc83,0x99fb1a63),LL(0x563fe6b4,0xb93bb852),LL(0x97cdd04f,0x06bb3ae9),LL(0x8b7de47d,0x07f011d4),LL(0xde78f61c,0x8d90e2e4), + LL(0xd33cb6e2,0x731c6dd6),LL(0x8cce0290,0xa3ea317e),LL(0x1c42206e,0xdca9b2f9),LL(0xd1e5dfd9,0x6acbbce9),LL(0x2fc948cd,0x40745846),LL(0xa82f9cec,0xc7a50d91), LL(0x4c1aa161,0xb906d69e),LL(0x0ebe948e,0x3a9b14be),LL(0xb63aeb70,0x11a9f12c),LL(0xead745f2,0x0365b4cc),LL(0xf9f16c17,0x5f6c2bbd),LL(0xa03e558e,0x89131238), + LL(0xd1944d1b,0x7830460f),LL(0x84350af2,0xc56f08e7),LL(0x307d9c78,0x73bee2aa),LL(0x5aad8b6c,0x1b02af1b),LL(0x03848db5,0x5e318827),LL(0xf230f476,0x4785958b), LL(0x4f80e25d,0x4ea6535d),LL(0xd23c7f72,0x9958c9c7),LL(0x2fd33cab,0x4c197b33),LL(0xc566914f,0x24c7b0b1),LL(0x71952d3b,0x956ce3c3),LL(0xfabae5f2,0x8735694b), + LL(0x40ec913c,0xde37ae28),LL(0x056685b3,0xdc915f83),LL(0xf66a4501,0xf7bc3488),LL(0x6a900e5f,0x30e61042),LL(0xca3cf645,0x505525c1),LL(0xb1f3ed40,0x35338c53), LL(0xd70b7c41,0x6823159a),LL(0x7384ba7c,0x660f518a),LL(0x2482056b,0xc6cf6a4b),LL(0x1df15990,0xb308b215),LL(0xfb5c130b,0xba63b2e3),LL(0x277b7515,0x1c660db8), + LL(0xfddc9fdd,0x8a95e5c1),LL(0x5adab0c3,0x679d4e0f),LL(0xcda40bc0,0x1859df6a),LL(0x8234471d,0xf9097aa5),LL(0x783c0100,0xaddc0c9b),LL(0xfeb7067c,0x55388dc8), LL(0x80a2eac7,0xe3805fd1),LL(0xec886879,0xf800a75c),LL(0x1943a0a0,0xa4599992),LL(0x1dfe627e,0xb47f0619),LL(0xda06515f,0x313d4f09),LL(0x1f54a73e,0xde26052d), + LL(0x6827365d,0x85a1b879),LL(0x667debe8,0x595a6915),LL(0x93a3d50f,0x214670fb),LL(0xb37de08e,0x9dfb028e),LL(0x9c6cf2a9,0xdd077e2f),LL(0xc9b96e8e,0x96897d8f), LL(0xefd39543,0xe6e93c07),LL(0x4454e73d,0x19dcdaa4),LL(0xd7b8c758,0x4a67424f),LL(0xb1e91e2a,0x03d4de0d),LL(0xe887b6b6,0x7c843988),LL(0x6ffdcfff,0x7db4f3da), + LL(0xd8bb43ec,0x0db87bc3),LL(0x13a7b669,0xbf71d27c),LL(0xa3fd2a60,0xea81e9c4),LL(0xc9f017e5,0x190c9c71),LL(0xbcc75768,0x21864180),LL(0x43dbcde6,0x137bd615), LL(0x5d468ff5,0x5b090c71),LL(0x126c6bc6,0x3a622b60),LL(0xa918bf24,0xfef3d268),LL(0xae204f49,0xe10c52c8),LL(0x86d7c356,0xf4be898d),LL(0x2fdb5a17,0x8276da18), + LL(0x7f2ad562,0x89c992af),LL(0xafc83ad3,0x7e1459d9),LL(0x9278dd04,0x4c0d9681),LL(0xd8eebe36,0x4496d9a7),LL(0xb8d4b1a2,0x7c037261),LL(0xbad3d6d7,0x827c49a5), LL(0x836926ae,0xf4d94deb),LL(0x4064af58,0x65417bf6),LL(0xfcdafc9f,0xa79471ac),LL(0x8123312d,0x3f85ccb4),LL(0xa3360be4,0x4d374cad),LL(0xee325a2b,0x56b476d6), + LL(0x41af8c08,0x0079c69d),LL(0xacbe515e,0x7dcfa4f4),LL(0x01396859,0xb8d18666),LL(0x946fbedd,0x08590ca4),LL(0x641aace4,0x7fecd9b9),LL(0x2936a1b6,0xaad5cc44), LL(0xf92c5958,0x925b6235),LL(0x82d6231e,0x7b1442f1),LL(0x8c6fb34a,0x971e663d),LL(0x2fc1c10d,0x543146dc),LL(0x0642b822,0x6e4053c7),LL(0x492e524d,0x4a49f247), + LL(0x17ba53f1,0x1b51f7b4),LL(0x3d5c43bf,0x170ff1eb),LL(0x681f7ee7,0xc2f160f8),LL(0x47814310,0x4c0a54d0),LL(0xa83d061c,0xfc689a13),LL(0x7ff6333d,0x1cbc99b4), LL(0x6581cd16,0xe19fd790),LL(0x9ca37b0c,0x67da79c7),LL(0x63bd0b5c,0x2507d167),LL(0x1befb82b,0x4449985b),LL(0x914699ec,0x6bea3969),LL(0xef202abb,0x9f606dd4), + LL(0x597bd10e,0xca9872e1),LL(0x4aed951f,0x6725cc9a),LL(0x4e05b280,0x96b17cb8),LL(0xfa234d45,0x97987146),LL(0xbb35a7d8,0xba78949e),LL(0x6fc59384,0xb82e9b9f), LL(0x70f165c7,0xa303e54a),LL(0xb9c2cad9,0xfd6bb0dc),LL(0xee722045,0xe57e2de8),LL(0x63e27035,0xa05c1065),LL(0x02d2fe6f,0xaa38e866),LL(0xee2f6aad,0x78e02fa8), +}, +/* digit=48 base_pwr=2^240 */ +{ + LL(0x5e3c647b,0xc0426b77),LL(0x8cf05348,0xbfcbd939),LL(0x172c0d3d,0x31d312e3),LL(0xee754737,0x5f49fde6),LL(0x6da7ee61,0x895530f0),LL(0xe8b3a5fb,0xcf281b0a), LL(0x41b8a543,0xfd149735),LL(0x3080dd30,0x41a625a7),LL(0x653908cf,0xe2baae07),LL(0xba02a278,0xc3d01436),LL(0x7b21b8f8,0xa0d0222e),LL(0xd7ec1297,0xfdc270e9), + LL(0xe2a07891,0x4f120aa7),LL(0xa25d3225,0x9158bab3),LL(0xcfe5f7a8,0xc96bac5e),LL(0xbbf3cec6,0xd4e73d59),LL(0x60361cd5,0xed8d2335),LL(0x562f444c,0x9b1a252c), LL(0xc70f23c2,0xbd37d3cf),LL(0xa52ea19e,0xf13b3b6e),LL(0x3d2f41ed,0x7e35535a),LL(0xe8b1743e,0x0353b52e),LL(0x7b5a2765,0x31d89dfd),LL(0x8d9ea8b8,0x2b7ac684), + LL(0x9f101e64,0x06a67bd2),LL(0xe1733a4a,0xcb6e0ac7),LL(0x97bc62d2,0xee0b5d51),LL(0x24c51874,0x52b17039),LL(0x82a1a0d5,0xfed1f423),LL(0xdb6270ac,0x55d90569), LL(0x5d73d533,0x36be4a9c),LL(0x976ed4d5,0xbe9266d6),LL(0xb8f8074b,0xc17436d3),LL(0x718545c6,0x3bb4d399),LL(0x5c757d21,0x8e1ea355),LL(0x8c474366,0xf7edbc97), + LL(0xc46db855,0x73457010),LL(0xdd579fb8,0xccb68c43),LL(0x9c25fe5b,0x705b0e8c),LL(0x82dd0485,0x40f36ea1),LL(0x27ac2805,0x3d55bc85),LL(0xad921b92,0x15177c6f), LL(0x5ab18cab,0x51586cd5),LL(0xcbb4488c,0xf51b5296),LL(0x84f0abca,0xbb4e605e),LL(0x772dd0da,0x354ef8e3),LL(0x5e4e1d41,0x7f1a8f79),LL(0xde5d8491,0x93461f09), + LL(0x6ea83242,0xec72c650),LL(0x1b2d237f,0xf7de7be5),LL(0x1819efb0,0x3c5e2200),LL(0x8cdde870,0xdf5ab6d6),LL(0x92a87aee,0x75a44e9d),LL(0xbcf77f19,0xbddc46f4), LL(0x669b674d,0x8191efbd),LL(0xed71768f,0x52884df9),LL(0x65cf242c,0xe62be582),LL(0x80b1d17b,0xae99a3b1),LL(0x92de59a9,0x48cbb446),LL(0x2dcb3ce2,0xd3c226cf), + LL(0x9311182c,0xf3899558),LL(0xb657a7b7,0x1bee4c4b),LL(0x2df8d1a7,0x0b1c4fd3),LL(0x76d3fbbf,0xf16bcc23),LL(0xf4fd52bc,0xd5888916),LL(0xd5cde1f0,0x3de6cfb4), LL(0xd4a07dfd,0x764ffffd),LL(0xe2642182,0x5e674426),LL(0xccd57b85,0x34f64762),LL(0x29351062,0x2233a4c3),LL(0xd9c642f3,0xdf076095),LL(0x59f0df34,0xac917a2c), + LL(0x9fd94ec4,0x9580cdfb),LL(0x28631ad9,0xed273a6c),LL(0xc327f3e7,0x5d3d5f77),LL(0x35353c5f,0x05d5339c),LL(0x5c258eb1,0xc56fb5fe),LL(0xedce1f79,0xeff8425e), LL(0xcf83cf9c,0xab7aa141),LL(0x207d6d4f,0xbd2a690a),LL(0x458d9e52,0xe1241491),LL(0xaa7f0f31,0xdd2448cc),LL(0xf0fda7ab,0xec58d3c7),LL(0xc91bba4d,0x7b6e122d), + LL(0x775f516f,0x3bd258d8),LL(0xc715927f,0x4bedebd5),LL(0xe3f966a0,0x5b432512),LL(0x709d0c2d,0x338bfca7),LL(0x49658259,0xd142cc10),LL(0x636b8023,0xfabc6138), LL(0x4d4ef14d,0xa9ef9401),LL(0xc54c570c,0xd5917ac1),LL(0x5cb64487,0xfd2f63c5),LL(0x1cea475b,0xbae949b1),LL(0x1e67a25f,0xa4544603),LL(0xdc6a7a6a,0xa547abc1), + LL(0xb1b48156,0x2a2dedaf),LL(0xbb93db87,0xa0a2c63a),LL(0x08acd99e,0xc6559078),LL(0xfe4ac331,0x03ea42af),LL(0xeb180ed6,0x43d2c14a),LL(0xb1156a1a,0xc2f293dd), LL(0xa9d81249,0x1fafabf5),LL(0x9a8eee87,0x39addead),LL(0x119e2e92,0x21e206f2),LL(0xd74dceb6,0xbc5dcc2e),LL(0x0a73a358,0x86647fa3),LL(0x2f53f642,0xead8bea4), + LL(0xb12c4bb1,0x158d814d),LL(0x2f0cf4fa,0xe52f75d2),LL(0x6141b59c,0xf106023e),LL(0xbeb9d941,0x5eb8b8eb),LL(0x90cf579c,0x1dd39729),LL(0x69ee6efa,0xb273252e), LL(0x3e9947a0,0xe43a3c59),LL(0x6c19dd01,0xd605124f),LL(0x05c578b0,0x8090fdbd),LL(0x622ff18c,0x8e6c535a),LL(0x57d12071,0x3600b0c2),LL(0x78d001d7,0x6d026e5c), + LL(0x91c09091,0x636225f5),LL(0x71bdcfdf,0xccf5070a),LL(0xb9668ee2,0x0ef8d625),LL(0xb5e04e4f,0x57bdf6cd),LL(0x7c75ea43,0xfc6ab0a6),LL(0xf7fd6ef3,0xeb6b8afb), LL(0x2a3df404,0x5b2aeef0),LL(0xb9823197,0x31fd3b48),LL(0x83a7eb23,0x56226db6),LL(0x5bb1ed2f,0x3772c21e),LL(0xcd1aba6a,0x3e833624),LL(0xac672dad,0xbae58ffa), + LL(0xdaff1807,0x00e0a003),LL(0x92c94fd0,0xcb9d1559),LL(0xcebbf905,0x3c2b5c3d),LL(0xd338afa9,0x9c799ec7),LL(0x4e2cfccc,0x60b9908c),LL(0xae3c6f92,0x4bfe1a57), LL(0xfb116150,0x480d310e),LL(0xe3e7888e,0xa1ed6c31),LL(0x720b5196,0x841a11d9),LL(0x8adff37d,0xcc337d17),LL(0x5faa86c5,0x08c66826),LL(0x9dfcc7ad,0x945c90d4), + LL(0x31ba1705,0xce92224d),LL(0xf0197f63,0x022c6ed2),LL(0xa4dc1113,0x21f18d99),LL(0x03616bf1,0x5cd04de8),LL(0x9ff12e08,0x6f900679),LL(0x48e61ddf,0xf59a3315), LL(0xb51bd024,0x9474d42c),LL(0x9051e49d,0x11a0a413),LL(0xdce70edb,0x79c92705),LL(0x34198426,0x113ce278),LL(0xea8616d2,0x8978396f),LL(0xea894c36,0x9a2a14d0), + LL(0x8e2941a6,0x9f9ac960),LL(0x2fc4fe1e,0x43e7ff90),LL(0x6033e041,0x5ec41359),LL(0x6f6ff0f3,0x5ce791c4),LL(0x9d907343,0x8d134b89),LL(0x86304df2,0x7bd15c77), LL(0x77c4a913,0x2cd2ebc7),LL(0x45f07153,0xcd86a39d),LL(0x88bc423b,0xe7e12d2e),LL(0x0b3163f4,0x478e814b),LL(0xbe8ec766,0x78bd9c8a),LL(0x7709ce48,0x6a5763e8), + LL(0x604f6e4a,0x4f1e1254),LL(0x0187d585,0x4513b088),LL(0x19e0f482,0x9022f257),LL(0xe2239dbf,0x51fb2a80),LL(0x998ed9d5,0x49940d9e),LL(0x6c932c5d,0x0583d241), LL(0xf25b73f7,0x1188cec8),LL(0x3b3d06cd,0xa28788cb),LL(0xa083db5a,0xdea194ec),LL(0x22df4272,0xd93a4f7e),LL(0x6a009c49,0x8d84e4bf),LL(0x3e3e4a9e,0x893d8dd9), + LL(0x8d095606,0xd699ea2d),LL(0x1e0ddd3a,0x3cd080c5),LL(0x66a8b35b,0x46604bad),LL(0x4233fccb,0x0c779b62),LL(0xbfd3cf0c,0x578458ac),LL(0x96bf57af,0x6820f665), LL(0xbf1f302c,0xa9724245),LL(0x277a6c3e,0xbbde24da),LL(0xc6be8c14,0x0980a5b8),LL(0x774d62c4,0x6230e3ec),LL(0x4fbde24b,0xda1467d8),LL(0xcc862204,0xd9d68d07), +}, +/* digit=49 base_pwr=2^245 */ +{ + LL(0x7378f90d,0x67c51634),LL(0x66647082,0xbc201a79),LL(0x9ee450cf,0x77fcc8dc),LL(0xb41a3e2f,0x8dd2b318),LL(0x93bf0689,0xdf6a935e),LL(0xa92e5464,0x75edabf3), LL(0x604d208a,0x49afcd9f),LL(0xd465ca48,0x372f0ea7),LL(0xc7ea7810,0xcdbd8ad2),LL(0x550822b2,0xfe61571e),LL(0x86606adc,0x744a4f93),LL(0xd9d4e110,0x6beb3c9c), + LL(0xe700b9f2,0x1fef389c),LL(0x425bc8ab,0x63029466),LL(0x37f04a33,0xbd770a14),LL(0xd0169369,0xc7438e29),LL(0xe2377cc3,0x6b265742),LL(0xc369fa4f,0xdf24bf96), LL(0x0ad94e08,0xdfdbcf47),LL(0x7f75a7dc,0xd101b861),LL(0x2a9c483c,0x5574a0b8),LL(0x2de43228,0x0563fe94),LL(0xead1fabe,0x58ca0e8a),LL(0x66023966,0xdc3d9a84), + LL(0xc3fd20e5,0x383bda07),LL(0x5c29449b,0x9619b1df),LL(0x369f39bf,0x6f3c717d),LL(0x1a5a3900,0x1bb593d1),LL(0x2aec6c2b,0xd0f07ecc),LL(0x4240b202,0x9d72eb2a), LL(0xc50e4a0c,0x35342f6c),LL(0x6b93bf61,0x701b4662),LL(0xccb6a888,0xfcd6eb09),LL(0x85aa42c5,0xabb7a6f7),LL(0xaa4e5895,0x952f8824),LL(0x5c406582,0x49860db8), + LL(0x3955812b,0x3667a720),LL(0x284d1dac,0x0d73483b),LL(0xfc62f791,0xe084535e),LL(0x389faf7f,0x5bc1652b),LL(0x3a71b7f6,0x40cf5168),LL(0xd4f39703,0x8a4b19fa), LL(0x2a8eff13,0x823e754a),LL(0xbffa5afc,0xf01b2021),LL(0x7225b319,0x5639ee02),LL(0xfc282f16,0x7533bc86),LL(0xc69f61ae,0x710009d2),LL(0xbf65e803,0xe30c499d), + LL(0x734b4ec3,0x0da7ac1b),LL(0x12a2afbe,0xf47fc1d0),LL(0x87dce4a2,0xbbbc99be),LL(0xdd5c6378,0xf7264b4e),LL(0xf618ffdc,0xe9409305),LL(0xd1846ac1,0xafadda9b), LL(0xa21850d4,0xe734f9d0),LL(0x8722a316,0x199cb44f),LL(0x38cae89f,0xcfe8704b),LL(0x6b151b57,0x2db1e56b),LL(0x69ce7b2c,0x116ca5cf),LL(0x57de97c8,0xe9b8625f), + LL(0xaf247c49,0x18811bd5),LL(0xe124dbda,0xbc180793),LL(0x21234fc4,0xed978d3a),LL(0x0616ae15,0x516dd9a7),LL(0x74e430b8,0x8f806777),LL(0x06e8fc49,0x90942569), LL(0xa4e61235,0x4ca03fb5),LL(0xb617f361,0xb91de709),LL(0x0ed08bc3,0x0898d82d),LL(0x8cb08146,0x2bd71236),LL(0xe213176d,0x45b92d45),LL(0xf2bf5b9c,0x05894791), + LL(0x2695ea2b,0x0d79cb89),LL(0xc88e538a,0x2cb0f8df),LL(0xa80f36fe,0xc1b8dc3d),LL(0x84f00cc2,0xd756fa66),LL(0x9cb9efb2,0xa6f1cdec),LL(0xa6a21818,0x5c3f15a8), LL(0x6995d09f,0x9a7ee351),LL(0xd70434bf,0x88885463),LL(0x4f7d5d33,0x18cecc6d),LL(0x6b353bd1,0x3f013886),LL(0x0d9ad368,0x53bf798b),LL(0x28dbc3ee,0xeffd465a), + LL(0xb5d98ac1,0xeb29e44c),LL(0x0e227a4f,0xe47e57f8),LL(0x3d2bf688,0xd09c0494),LL(0x47428dd2,0x3ab7799a),LL(0xe9aafac8,0xdc558d6b),LL(0x87f9f6e0,0xc042c4cd), LL(0x89fb4693,0x93842bcd),LL(0x7068fbf7,0x62dbc82f),LL(0x7e6d47b5,0x16455268),LL(0x4c37eeee,0xab304b7a),LL(0x3fc412ce,0xdbb3d4e1),LL(0xa726a2c8,0x4f65dad0), + LL(0x605cdaee,0xb25e01b2),LL(0xbc57969d,0x74abec55),LL(0xcdd9d41a,0x9c57bfab),LL(0x4a9e32a3,0xa3330e3f),LL(0xe5792fd8,0x5929a0d8),LL(0x71ea2cde,0x830b4ea2), LL(0xfd06d246,0x80065ac1),LL(0x32e64a25,0xa2b416e6),LL(0xc0c927a9,0x3950bde7),LL(0x679d9b8c,0x9951f3bd),LL(0x651b6855,0xc235a274),LL(0x5ad97bc1,0xbfe5e08e), + LL(0x744ae145,0x4409a5b6),LL(0x7f620908,0x5e83fa0b),LL(0x2e140aa0,0xfc489bec),LL(0xe3cae337,0x5805a462),LL(0xc2211c21,0xe56e9ff7),LL(0x0c955362,0xb722f2b4), LL(0x41371f33,0xb098a32f),LL(0xbb4923d6,0xe6ccecea),LL(0xd82a311c,0x1cfbe2b3),LL(0x6b98f917,0xcf942893),LL(0x92ef848c,0xd60dc624),LL(0x5adb5228,0x34af446e), + LL(0x796ce1ca,0x0eb7e743),LL(0xd851377c,0x138653e5),LL(0x2b11c8e0,0x69c7c86f),LL(0xcdf2b205,0x878ec1de),LL(0xae0e8562,0x03e6688a),LL(0x935a36a8,0x20810666), LL(0x26635c50,0xc8ab7c7f),LL(0x744a21db,0xe75cdb06),LL(0xd720e198,0x4e26f32f),LL(0xd8cded81,0xa1c6395a),LL(0x6ce4fc04,0xb75dc6ea),LL(0x004623b5,0x71750b33), + LL(0x7e60c447,0xbdef8407),LL(0x2a65acca,0x88570f71),LL(0x0bb6aa79,0xef3d4a40),LL(0x60212976,0x5c9d1890),LL(0x1d96c43c,0x80179ea2),LL(0x53d2948e,0x3f002e6d), LL(0x49d78183,0x14b2cc91),LL(0xb496c279,0x7a549c71),LL(0x44995f6d,0xf4beac3f),LL(0x00bc78fe,0x5a342398),LL(0x60e42da0,0xa874dc1b),LL(0xcf5824d5,0x3a984010), + LL(0xdfb9760c,0xe514ee06),LL(0x77b8951f,0xb8862d75),LL(0xf8ee1141,0x0144676e),LL(0x02eb3e82,0x49561a30),LL(0x4ff9f897,0xb3541c15),LL(0xa7a99791,0x1670edf0), LL(0x64aea7f9,0xd41d6035),LL(0x2b3463b4,0xf66ffd09),LL(0xc3b26fb6,0x0784e015),LL(0xec46f8c8,0x88edce33),LL(0xb6381011,0x1b1e25a3),LL(0xff95ab97,0xbfaadc03), + LL(0x0c7be4e1,0x727a59fe),LL(0xf58ced15,0x75a7d5e3),LL(0x90f569e7,0x146fc0d9),LL(0xb7f1dc54,0x94dbccd2),LL(0xb75bf232,0x0df1ef90),LL(0xa2568190,0x2943a082), LL(0x67837b06,0x75f2f80d),LL(0x24b44b6e,0x07e3506f),LL(0xd0d2231b,0x7c30829a),LL(0x93277abf,0x9ce577ca),LL(0xb17549ec,0xa19d1868),LL(0x25e8c4d7,0x0ad6ff55), + LL(0x1c24d075,0x16b38dfe),LL(0x992959f6,0x3acd4c36),LL(0xac2da7ab,0xdaf2fe88),LL(0x89644935,0x76e8ff0e),LL(0xe85f7076,0xb8547c26),LL(0x1cdea7ce,0x9f149faa), LL(0x9e125d84,0x181a6072),LL(0x18751ce6,0xc4aef9fa),LL(0x0e00f00a,0x451c8466),LL(0xc4e3e6b8,0x662b3e7a),LL(0xc6b64507,0x57b7114e),LL(0x0b37fb70,0x07aeb198), + LL(0x4516234a,0x79d88e00),LL(0x31f9ceda,0x98dd3cb9),LL(0xce7d606e,0xb528000f),LL(0x2fa27fd3,0xc773557e),LL(0xe19436af,0x55b53dd3),LL(0xe10b64c7,0x675084b3), LL(0x56d56374,0xe5832665),LL(0x307e2e60,0xf8f7fd2a),LL(0x7af3e3dc,0x7b93bf53),LL(0xf47d298c,0x94fafa2c),LL(0x21121369,0x94c2ff9a),LL(0x33468ff6,0xa41de95f), +}, +/* digit=50 base_pwr=2^250 */ +{ + LL(0x1b270599,0xbe45d81a),LL(0x97d6c603,0x50696e7d),LL(0xb078ea89,0x63c5a516),LL(0xb4464764,0x9f3efe41),LL(0x101e5232,0x84580e24),LL(0xc8ae8220,0x00850a1a), LL(0xed55c404,0xbff4077d),LL(0xf2e7bf50,0xd74de734),LL(0x07e1c03d,0x4df4eef2),LL(0x6e654d58,0x4ab3d039),LL(0x086f1596,0xb20056cd),LL(0x8acd7cd5,0xe4d08a27), + LL(0xc90b13f5,0x8cd6c9f7),LL(0x52a9d469,0xec0c187d),LL(0x89b8ad2b,0x9c0db0f5),LL(0x0d9c999d,0x692a8db7),LL(0xc9f84ab4,0xa407fd03),LL(0xcc9a906c,0xa5742fd1), LL(0xc8e72867,0x4813a765),LL(0xe2e9a10f,0x9c65943d),LL(0x4fa0a23e,0xca6bf293),LL(0xcb1f8d7a,0x1dfa3af7),LL(0x98d10c53,0x28036f54),LL(0x0e012c13,0x7bfbcaf2), + LL(0x893e8032,0x2d9513a9),LL(0xf4688db4,0x49257f7a),LL(0x3af4d9ac,0x73d8b12c),LL(0x48a13c4d,0x903dc9fa),LL(0x60709433,0x6190753e),LL(0x49387d24,0xa093364e), LL(0x3b261e16,0x0436949e),LL(0x4a3055b6,0x96db3b27),LL(0xe85dfe23,0x514eacc7),LL(0x5d8805c9,0x1538b25c),LL(0x664a20f6,0xd4c6b75b),LL(0x4753292d,0xd1984f21), + LL(0x4ec177f6,0xa53f1a10),LL(0x3faa5ca8,0x4a2ef9aa),LL(0x32976d13,0x30efed85),LL(0x5ee692d1,0xcf5ada16),LL(0x259e7cc1,0x3ceda69d),LL(0x9baab472,0x2aae29e9), LL(0x737cc8bc,0x7ee5baef),LL(0x7fe68ded,0x1717af74),LL(0xcfdaff63,0x9e5c8dda),LL(0xcec07693,0x575c8db9),LL(0xfdfb509d,0x9afc8ae0),LL(0x85651697,0x27836d36), + LL(0x85e79c26,0x9d152839),LL(0xd36ab6f7,0x8d87faad),LL(0xa87afe15,0x08d4fe09),LL(0xfab81fd4,0x1e10b10f),LL(0x93c98a84,0x3cbd17d3),LL(0x246ceed3,0xbd40a4e8), LL(0x9a09d134,0x582d9de0),LL(0x4ee37dec,0x120440c2),LL(0x2f1073e4,0x4d4ff934),LL(0xf45e648d,0x7da76757),LL(0xebcbb80b,0x4427a608),LL(0x30e661a7,0xc6bccb54), + LL(0x135e2a30,0xb7b7628f),LL(0xb526fa7b,0x863552c4),LL(0xe0e30451,0x6ec18d05),LL(0x5769db60,0x1b36c93a),LL(0x170c236c,0xf0fe0007),LL(0x66130046,0xeceb540c), LL(0x3fc4bdbe,0x86a7a74d),LL(0xfbae3320,0x066b097b),LL(0x6e5c21ae,0x78fb5247),LL(0xe1adf398,0x3e19e9fc),LL(0x1a32a745,0x429b9cbd),LL(0x36d1a2b8,0xedd2c40f), + LL(0xceeaeed7,0x993ca8a9),LL(0x62545429,0xb2d28681),LL(0x91cf32d4,0x24003737),LL(0xd88bd4f0,0xda9ef96f),LL(0xe1b2d52a,0x916a4947),LL(0xf31b107c,0x5ef7f9d0), LL(0x62d3d3cb,0x3c424ba8),LL(0x7c3c3bba,0xab155cc2),LL(0x4bae8070,0x6a0404b2),LL(0xdf36677c,0x5f3d0592),LL(0x9a0e4800,0x7c9f2bef),LL(0x97959a09,0x6babbcb4), + LL(0x17eb9264,0xa7342f95),LL(0x0a8a6eef,0x9264a6a0),LL(0x7471c384,0x50e48bf0),LL(0x30827f34,0x729e5ab1),LL(0xea779c23,0x17199191),LL(0x9fa9fd58,0xd13ab853), LL(0x3b1d773e,0x7d579937),LL(0xd196c3df,0x65f8e7c6),LL(0xe8541725,0x253f7d51),LL(0xec720355,0x107a793d),LL(0x6aa16268,0x1c14d056),LL(0x8bbb231b,0x9dc5fca3), + LL(0x897a05a4,0x69935431),LL(0x51eaa290,0x34397b68),LL(0xf58fb7a5,0x90ec1a37),LL(0x50c4d76b,0xf10d0783),LL(0xcc47f990,0xeb9db48c),LL(0x0cea5865,0xef0b97a2), LL(0xd9f94396,0x04708d6f),LL(0x41c21452,0x82ff5771),LL(0xdbb65bdd,0x772d8493),LL(0xddf73c8c,0x561abc8b),LL(0x9830ff05,0x98a56463),LL(0x9f0d4cad,0x73e28296), + LL(0x589cb234,0x7fa7064e),LL(0x65ca4f3c,0xdfa4e846),LL(0x792d5254,0x476b6618),LL(0x583bdaeb,0xc0ce93bc),LL(0xe4ab5dc9,0x30b11dac),LL(0xf5c89e2f,0x237a64e5), LL(0x7dba60b7,0x54339fad),LL(0x084b09ed,0x0072505a),LL(0xb140717a,0x5e89c81f),LL(0xb407595d,0xd56de3a2),LL(0x0aab0d25,0x9f3a6c42),LL(0xa685543d,0x6c2aa69d), + LL(0x6cd00d89,0xda5fcddc),LL(0xac9ef99d,0x0b8c3feb),LL(0xa19298e3,0x16569ca8),LL(0x2783ac1d,0x5d998d56),LL(0xc18ecbdf,0x298c681c),LL(0xe6e13de4,0x209323d1), LL(0xbd75118d,0xe064255e),LL(0x43f945ef,0x78f69fd3),LL(0x95e6ff8f,0x9a4d591f),LL(0x3b378848,0xfa621d46),LL(0xe4d12bb8,0x4c951f31),LL(0x00ebfea6,0xefe8d01b), + LL(0x12b09f53,0xf5689c5e),LL(0x9e87ff7d,0xc1da32e1),LL(0x12eaa533,0x1af879d0),LL(0xd9271e94,0xdba775e6),LL(0x10e63c34,0x60f85073),LL(0xa686a24b,0x445f3e21), LL(0x15bc277e,0xed5ca8fa),LL(0x364ab7ab,0x9839198a),LL(0x6d90a7d4,0xe2ee3942),LL(0xccd37e76,0xe5b3e4cb),LL(0xf1412e0f,0x9013bd08),LL(0xce999048,0x82f5c532), + LL(0xf4bbf123,0xdd7ff816),LL(0xde3e9923,0xbf1a5fd0),LL(0x68d10f94,0x8c388f8c),LL(0x45057388,0x4e9cf0c4),LL(0x8d010855,0xcff64aa3),LL(0x7d8f55fc,0x4b639596), LL(0xbddc00c5,0xca314522),LL(0x3da89cfa,0x95482d72),LL(0x9eb9a710,0xb9bf18b8),LL(0x4651cc5d,0x0936a88e),LL(0xf59d0f45,0xec20ac01),LL(0x8ba74374,0x011a4868), + LL(0xf9c4caf8,0x07252272),LL(0x290ab63f,0x9b016799),LL(0x558d649d,0xeaa616bb),LL(0xa66d8089,0x00f2ef38),LL(0xf72863ae,0x284b0146),LL(0x1968cf45,0x9a207d77), LL(0xbdcbb689,0x33d7bac8),LL(0xe5348dae,0x393f34d5),LL(0x6f524620,0xeb86c8f1),LL(0x610689f8,0x62500c62),LL(0x6b7fa65e,0x66febc05),LL(0xfb836b3e,0x39c8a70b), + LL(0x5e4d0351,0xb91977b5),LL(0x9e8dddf7,0xd8ed39aa),LL(0x9d1b25c3,0x9ae994c2),LL(0x6ca7b19b,0x7369e189),LL(0xec0d7c2c,0x33deb695),LL(0xede6435b,0xddcc6250), LL(0x145a654d,0x44b7ba23),LL(0xd280567e,0x653ee81a),LL(0x0a39d324,0x7694c972),LL(0xe97e1710,0xf0af25b1),LL(0x3ee1a076,0x6e154646),LL(0x7ccfde8c,0x062ce983), + LL(0xf3fe3441,0x61d0e01b),LL(0x2af47609,0x674e5233),LL(0xb362902d,0xd4a4e224),LL(0x9e0a5d16,0x45923c12),LL(0x95e580e9,0x4fc2bdd4),LL(0xa8c3d954,0x6d1d974c), LL(0xd0bbeaaa,0xaeff1135),LL(0x1baafc9e,0x013ab5b3),LL(0xab8f9f31,0x80907d3e),LL(0x6d566c15,0xaf2c1216),LL(0x952e6fa7,0x0082daba),LL(0x2df9e03a,0xa4671003), +}, +/* digit=51 base_pwr=2^255 */ +{ + LL(0x1fd64063,0x5f79f0df),LL(0x81e118ec,0xd2d39dd3),LL(0x11571c5b,0xd631a68e),LL(0x2474faf7,0x6d072b4e),LL(0x862a924a,0x5e043a6d),LL(0xb0fc8d7a,0xcae58bd8), LL(0xb1351f28,0xf54bb7f3),LL(0x0413275e,0x4588b628),LL(0x5909ec04,0x81459f4c),LL(0xabd16460,0xd28cda25),LL(0x8db1c69e,0xbb676d01),LL(0xac5036f4,0xc0056e2d), + LL(0x44ce3ad8,0xdbe04c30),LL(0x4ce8aad5,0x995fbb1b),LL(0x70911457,0xdbf8b546),LL(0x3f7a1757,0x9e683b5b),LL(0x9c7bd62c,0x7b89a08a),LL(0x0b3fc97e,0x448865a4), LL(0x3bb01e94,0x0ac9abfc),LL(0x1e756124,0xa0776042),LL(0xd9deed97,0x0aa6c335),LL(0x72603e08,0xe270580f),LL(0x6c783bb2,0x70857a94),LL(0xcaa929ae,0xa0047774), + LL(0xb25c4d4a,0x292f8874),LL(0x7e79f526,0x54961fd8),LL(0x008c6ec9,0x949a1fae),LL(0x525524fd,0x6ae82f0d),LL(0x2edbcb1a,0xd1f6f4ef),LL(0x977ddffb,0x41617a6d), LL(0x1baf0668,0x6ae38fb7),LL(0xd538ab3c,0xa79ea228),LL(0xfc44e273,0x70babb05),LL(0xbca85910,0x247384fb),LL(0x6a564959,0xdc0e069b),LL(0x1a7438ad,0x37a9c552), + LL(0x8fa06859,0xf071c987),LL(0x1a52390b,0x0083e531),LL(0x61483bc2,0x845eb12a),LL(0x1caf6dd6,0x17471d80),LL(0xddc21b92,0x7b603616),LL(0xb992536d,0xd38fe0f6), LL(0x297c25a4,0x433f0652),LL(0xb1c4bf41,0x03d4d8fc),LL(0xa9adf49b,0xdf617386),LL(0x2cb2944f,0x4bfeb399),LL(0xb3d9c076,0xbf288427),LL(0x965b4576,0x17818c3e), + LL(0x689f43ef,0x2bb798ff),LL(0x5f26ec54,0x5813e441),LL(0x5005c929,0x51f64c49),LL(0x4b42e417,0x60e213a5),LL(0x62cc3734,0xc1528442),LL(0x09d994e1,0x6ecd6c3b), LL(0x83dd047f,0xa6e72f71),LL(0xb0019803,0x3836f663),LL(0x257493cb,0xbcf1265b),LL(0x9e62d78b,0x59b15ff0),LL(0x6cb92ecf,0xaac5ed5b),LL(0x9662651c,0x37e6ad7d), + LL(0xa17e560c,0xce23a19a),LL(0x62550e2b,0x6491b95f),LL(0x1d15a005,0xc7200012),LL(0xf4355a1f,0x15fde735),LL(0x607f7807,0x3849761f),LL(0x18204691,0xcbe322d0), LL(0xa95e8e91,0x75756e4e),LL(0x817a9b8e,0x365959fe),LL(0x3d4ce3dc,0x63123276),LL(0xf1d66e00,0xa769d2fe),LL(0xc28829e6,0x8624ddba),LL(0xd2df06ef,0x03274297), + LL(0x16f01d7b,0x52fced31),LL(0xdaf046aa,0x88c6b172),LL(0xfe7a338e,0x1a189403),LL(0x61798b1e,0x39741ecd),LL(0x2934b879,0x6a47b071),LL(0x828d1e9d,0x3b1a5dd1), LL(0x7f35a7ef,0xd4bd4848),LL(0xc1eebaf8,0x71774b5b),LL(0xd55344ba,0xa86471e5),LL(0x7b8a483a,0xfbf145f1),LL(0xaa53802c,0x70f9b214),LL(0x10b066e1,0x995af930), + LL(0x27a28f9d,0x9ec11597),LL(0xb847cd83,0x96f2c44b),LL(0x31fca111,0xacf794e1),LL(0x96076f45,0x438b9178),LL(0x51732588,0xad71035b),LL(0xa5d910da,0x2db32f32), LL(0xfe1cc184,0xefaad0e8),LL(0x2e00bbed,0x6f0360b5),LL(0x474ce326,0x99402426),LL(0x2aa270da,0xd53b687a),LL(0xd78fa6eb,0x96c8bb78),LL(0x6e699411,0xd07f3bba), + LL(0x361dae4c,0x07276886),LL(0x84c57896,0xb26f2579),LL(0x5f0c2bf4,0xe8b59ef5),LL(0xdd64aaac,0xf544c145),LL(0x9fdcb039,0xa9dc03bb),LL(0x58c44b72,0xeb1e9aeb), LL(0x1d6bf26e,0x39a4fe8e),LL(0xeaf8e241,0x2c4285cc),LL(0x14770f31,0x647ce584),LL(0x062f0912,0xe5bfeb70),LL(0xe8314467,0x7031db80),LL(0xd658d2cd,0xac970937), + LL(0xefe1757b,0x2dfc39e6),LL(0xb5d2cb93,0xab52fbf3),LL(0x313aa477,0x1cf12123),LL(0x9c6acbd1,0x785b025b),LL(0xe4d54177,0xb4aeb5b8),LL(0xd943c1ea,0xde3d28f8), LL(0x5b0b1921,0x7892db85),LL(0x58caff2d,0xc09ff903),LL(0x1cbd3231,0xbdee13c6),LL(0x00b6c34e,0x873e0a77),LL(0xe23de32b,0xb279505a),LL(0xc5a03302,0xf056ffdc), + LL(0x6ba563ee,0x0ac76959),LL(0xb9a51868,0x2053a5fb),LL(0x06178e3c,0x60e2555f),LL(0xc0933775,0x1bc99e72),LL(0xb7d5160e,0x4a2d31b2),LL(0x895d1db8,0x7cc03ff3), LL(0xee53e79f,0x98fb331e),LL(0x8583b893,0xc2f0a93f),LL(0x49802eb4,0x8fa79ed8),LL(0x55ce8dcd,0xe9548175),LL(0x1d4d44f1,0xb5155a21),LL(0x89570a82,0xbb044d28), + LL(0xe1f833e0,0x430b669f),LL(0x6d8127bd,0x1797ac3a),LL(0x4c33493e,0x01ad730c),LL(0xca00ed39,0x8c882c1f),LL(0xd24a5516,0xab2e9c89),LL(0xf5d0327d,0x21a49e0a), LL(0x58a280d1,0x46488bd8),LL(0x772ed759,0xfc4a1e8a),LL(0xaecfac7c,0xf9f60e90),LL(0xac6a9e8c,0x4afd1f5f),LL(0xc98bcda8,0x57a20bf8),LL(0x8b46b998,0xa1107ea0), + LL(0x45fc08c4,0xe931c21b),LL(0x3aca653f,0x13fad41f),LL(0xec1fe395,0xf28a3515),LL(0xcf55cc91,0x191a4f2d),LL(0x90535f59,0x46fb07b7),LL(0xd69686a9,0x76c60cc1), LL(0xc8122c04,0x1e7dec15),LL(0x1b72798c,0x0743fcf0),LL(0x1e5939fd,0xb10c96bd),LL(0x6e8338e5,0x261e6c0a),LL(0xe5cdaa43,0x56148d3c),LL(0xa031239a,0x3f004371), + LL(0x0db0c9c0,0x1f2f6c1f),LL(0xac770b5f,0xca4e1964),LL(0x569c090b,0x20dce4a6),LL(0xdb3986d0,0xe4f7401a),LL(0x85f553ea,0x13897994),LL(0x09026bff,0x119ad50d), LL(0xe265a0a9,0x88067aa7),LL(0x7f749167,0x209c62b4),LL(0x459bf269,0x84165019),LL(0x8b6e76f6,0xec125bd5),LL(0x1f0d2434,0xd636f932),LL(0x8e05e0b0,0xf6023a4c), + LL(0x65ea2b23,0x84c14e31),LL(0x19e93301,0xb68121be),LL(0xb25d9a83,0x9c1a873f),LL(0xd13773f0,0xafb9d04c),LL(0x51c32d57,0xd05014da),LL(0x0904efdc,0xff2e350b), LL(0xa0a01069,0x20bd7d22),LL(0x6c3b3fd8,0x3e74eb0f),LL(0xb743b72c,0x643ea531),LL(0x8e3ae785,0xa2fe7414),LL(0x92e8d320,0xb8fe89bf),LL(0x495f6d28,0x58985dc1), + LL(0x389283ba,0xfe1f11ad),LL(0x0cd91b22,0xc87e20b6),LL(0x3c5babf8,0x99d0015a),LL(0x5929ea0a,0x7e795b4d),LL(0x1dfb7b7e,0xc9cf6833),LL(0xa64992e8,0xc1c07346), LL(0x9889746d,0x0b7e0dd8),LL(0x1c43ea4a,0xa89d7b46),LL(0x34f02b96,0x64023cf0),LL(0x5662f0c8,0xf7dd410a),LL(0xa1058cca,0xa3bb6088),LL(0x4e7801ed,0xedb25dc3), +}, +/* digit=52 base_pwr=2^260 */ +{ + LL(0xdd93d50a,0x140a0f9f),LL(0x83b7abac,0x4799ffde),LL(0x04a1f742,0x78ff7c23),LL(0x195ba34e,0xc0568f51),LL(0x3b7f78b4,0xe9718360),LL(0xf9efaa53,0x9cfd1ff1), LL(0xbb06022e,0xe924d2c5),LL(0xfaa2af6d,0x9987fa86),LL(0x6ee37e0f,0x4b12e73f),LL(0x5e5a1dde,0x1836fdfa),LL(0x9dcd6416,0x7f1b9225),LL(0x677544d8,0xcb2c1b4d), + LL(0xda1c29ab,0x279fd119),LL(0x2b30d40c,0xbd068802),LL(0xda44105d,0xd8f57da4),LL(0x28223fe1,0xb1814b7a),LL(0xe06f2d2e,0xcf2fd241),LL(0x01dfde06,0x99003a02), LL(0xfded7e4b,0x876a31af),LL(0x2f725094,0x1efaf827),LL(0x493a6a0a,0x5117d608),LL(0xa88c03e7,0xdcec8088),LL(0xea916897,0xeae1d352),LL(0x6e8b2c57,0x8cdc2810), + LL(0x9c213d95,0x0254486d),LL(0xcb2f6e94,0x68a9db56),LL(0x000f5491,0xfb5858ba),LL(0x34009fb6,0x1315bdd9),LL(0xc42bde30,0xb18a8e0a),LL(0xf1070358,0xfdcf93d1), LL(0x3022937e,0xbeb1db75),LL(0xcac20db4,0x9b9eca7a),LL(0xe4122b20,0x152214d4),LL(0xaabccc7b,0xd3e673f2),LL(0xaed07571,0x94c50f64),LL(0xe66b4f17,0xd767059a), + LL(0x54e93c1e,0x09f8bb06),LL(0xad81e27c,0xb0045884),LL(0x076e13eb,0x26ebc7b6),LL(0x5d5ac07f,0xbda0b553),LL(0x48ab69e6,0xbcb81322),LL(0x1c0f21fa,0xd3847d2e), LL(0xc834d740,0x7a466528),LL(0xe0823ff2,0x6c67a79a),LL(0x4c1d7cb8,0x85dd1186),LL(0x2d081301,0x096f849f),LL(0x8a5ea0f0,0xb4f503dd),LL(0xd1bf69b2,0x71ee0889), + LL(0xdcd6d14b,0x40336b12),LL(0xe3b4919c,0xf6bcff5d),LL(0x9c841f0c,0xc337048d),LL(0x1d617f50,0x4ce6d025),LL(0x8117d379,0x00fef219),LL(0xf95be243,0x18b7c4e9), LL(0x38df08ff,0x98de119e),LL(0x8d772d20,0xdfd803bd),LL(0x0f9678bd,0x94125b72),LL(0x334ace30,0xfc5b57cd),LL(0xb7e86e04,0x09486527),LL(0x6e552039,0xfe9f8bcc), + LL(0x02a2d1e6,0x4ab7a22c),LL(0x1371d5a4,0x967e19a3),LL(0x078de336,0x20f59f95),LL(0xf7869245,0xfd28fa36),LL(0xcbf1d96f,0x1de42581),LL(0x366e1f0f,0x2e0127d7), LL(0x2258c741,0xbc65fa9d),LL(0xdd6d65f8,0x1f2f3356),LL(0x4a0822a9,0x06384f3a),LL(0xfd05a0aa,0x1c81332b),LL(0xd95ee3ce,0xbfb12361),LL(0x42016d00,0x180aaf06), + LL(0xd6f5a10e,0x3b75c45b),LL(0xc1c35f38,0xfd4680f4),LL(0xf8e0a113,0x5450227d),LL(0x73ddba24,0x5e69f1ae),LL(0x57f24645,0x2007b80e),LL(0x3d159741,0xc63695dc), LL(0x4530f623,0xcbe54d29),LL(0x2869586b,0x986ad573),LL(0x4cc39f73,0xe19f7059),LL(0x2b1b8da9,0x80f00ab3),LL(0x73f68d26,0xb765aaf9),LL(0xe993f829,0xbc79a394), + LL(0x95b3287d,0x0a159f62),LL(0x48cecad0,0xb18f8759),LL(0x1661a23f,0x6d1ab8ee),LL(0xc95c41b3,0xcae7f40e),LL(0x7c51eb56,0xbc3d2040),LL(0xe8754250,0xa7527283), LL(0x1f9e668a,0x81561056),LL(0x900f5912,0xb8aa7296),LL(0x6af2a00c,0xabdbc1bf),LL(0x2d0a56c0,0xe9a94254),LL(0x7bc8959e,0x4774a7b7),LL(0x19cef2f3,0x0a837ff0), + LL(0xf310d2a0,0x9c441043),LL(0xdc5eb106,0x2865ee58),LL(0x9cb8065c,0x71a95922),LL(0xa052af0f,0x8eb3a733),LL(0xb09d716e,0x56009f42),LL(0xabcbe6ad,0xa7f923c5), LL(0xfa375c01,0x263b7669),LL(0x21ef27a2,0x641c47e5),LL(0xb08ffd25,0xa89b474e),LL(0xf0a239f3,0x5be8ec3f),LL(0x242a6c5a,0x0e79957a),LL(0x0c6c75f5,0x1dfb26d0), + LL(0xa084fae6,0x36f3a3d8),LL(0x9a9b0d95,0x75983589),LL(0xcc80fcb6,0x70722186),LL(0x96d84c04,0xf28ed0c7),LL(0xffb63f90,0x95a32263),LL(0x98766034,0xdd7d60a0), LL(0x1d5c387c,0xe193a31f),LL(0xb8310f8b,0x6c5eca7e),LL(0xc083ff47,0xfe61d523),LL(0xcb2944e9,0x90c832db),LL(0x593334b7,0xa9f3f293),LL(0x2d7d1c33,0xe6cde2e1), + LL(0x9dfbf22a,0x2fd97b9b),LL(0x5643532d,0xdec16cc8),LL(0x60fee7c3,0xdf0e6e39),LL(0x545860c8,0xd09ad7b6),LL(0x73fc3b7c,0xcc16e984),LL(0x0d4e1555,0x6ce734c1), LL(0x4b5f6032,0xc6efe68b),LL(0x14f54073,0x3a64f34c),LL(0xac44dc95,0x25da689c),LL(0x5358ad8a,0x990c477e),LL(0xf36da7de,0x00e958a5),LL(0xc9b6f161,0x902b7360), + LL(0xf144b6cc,0xbd079cf1),LL(0xb4f4a764,0x7f86e29b),LL(0xf21f9cbf,0x5b08b290),LL(0x75e3aeb9,0xada0c85b),LL(0x6666c2df,0xd0789f8b),LL(0xd71ec2ec,0xcf5d8a8c), LL(0xe7e4364b,0x6f7780c3),LL(0x85d2eb75,0xdd9a6529),LL(0xd952a38e,0x8222f66b),LL(0x27260a29,0x9dd5f7eb),LL(0x57947178,0xce49b344),LL(0xcdda7e39,0xaa215f82), + LL(0x9347b90a,0x454ab42c),LL(0xa698b02b,0xcaebe64a),LL(0xfb86fa40,0x119cdc69),LL(0xc3109281,0x2e5cb7ad),LL(0xcd0c3d00,0x67bb1ec5),LL(0x83f25bbf,0x5d430bc7), LL(0x5cde0abb,0x69fd84a8),LL(0x9816b688,0x69da263e),LL(0x0e53cbb8,0xe52d93df),LL(0xadd2d5a7,0x42cf6f25),LL(0xc87ca88f,0x227ba59d),LL(0xda738554,0x7a1ca876), + LL(0x3004db31,0xaa44b286),LL(0xd43e4430,0x86f43d7a),LL(0xb0b0240d,0xdc4874cd),LL(0xadc45a06,0x79986a23),LL(0x3cee4631,0xbb275b44),LL(0x63a217aa,0x21daee8a), LL(0xd7b25c02,0x1e7c5397),LL(0xc5e668fa,0xe677d3cb),LL(0xed51b4bf,0xc7c84e28),LL(0x923e5408,0x7ca19e99),LL(0xc3f832e7,0xc6f8a595),LL(0x5fb049a3,0x2d0a789c), + LL(0x1cac82c4,0x3fa5c105),LL(0x8a78c9be,0x23c76087),LL(0x1c5cfa42,0xe98cdad6),LL(0x0a6c0421,0x09c30252),LL(0x42fc61b9,0x149bac7c),LL(0x3004a3e2,0x3a1c22ac), LL(0x202c7fed,0xde6b0d6e),LL(0xe7e63052,0xb2457377),LL(0x3706b3ef,0x31725fd4),LL(0x2b1afdbf,0xe16a347d),LL(0x8c29cf66,0xbe4850c4),LL(0x2939f23c,0x8f51cc4d), + LL(0x44922386,0x114a25c8),LL(0x6d4e8b57,0xdd084d44),LL(0x1e7bd7de,0xc49b6841),LL(0xd6da54db,0x5b0359fa),LL(0x3f0da321,0xa6e6e5f9),LL(0xd640a87e,0xb65ec55c), LL(0xae64020e,0xc1a4f6ce),LL(0x088e1337,0x91e29cd2),LL(0x3c0a631c,0xf44ceb8e),LL(0xb756445f,0x0205b11d),LL(0x5bc8880e,0x04844e84),LL(0xb85e00d3,0xb630ddc0), +}, +/* digit=53 base_pwr=2^265 */ +{ + LL(0xae7ce296,0xe76894c3),LL(0xa6cafc34,0x87737ee2),LL(0xe55cd1e6,0x566dfcfb),LL(0x3a7ad5b9,0x5421a9f2),LL(0x4687a4ef,0xa005838a),LL(0x23a2c423,0x3837219a), LL(0x8a82cd1b,0x4b780012),LL(0xc728b588,0x401c07be),LL(0x37ced8f3,0x2b5f69e9),LL(0x8c1e1eaa,0x306b621d),LL(0xd389cc4d,0x8acbbe71),LL(0xf4ab7774,0x922fa665), + LL(0xd35c2d80,0x2df6f242),LL(0x3493ce97,0xf65a99a9),LL(0x372bcc87,0x9e80232b),LL(0x6e428cc5,0x26ba13b8),LL(0x13a1b763,0x2526ef1f),LL(0xdc97c5f3,0xcef3edcd), LL(0xbde16b73,0x4954867f),LL(0x368ff6cb,0x9817813d),LL(0xbe143027,0x7e39fa69),LL(0xcf54f28b,0x12329463),LL(0x7597c2da,0xcf0991dc),LL(0x52e07099,0x0cda3969), + LL(0xee993749,0xdc9daeef),LL(0x7ff3d775,0xd40c8a54),LL(0xca53d53d,0x206d2271),LL(0x4d1aa50b,0xb0546335),LL(0x88001e99,0x52bca910),LL(0x17fb7aa4,0x25c117c2), LL(0x42685945,0xfff3af95),LL(0x8f4ce0fb,0x083fd4de),LL(0x24753989,0xaac004be),LL(0xe90950c6,0x4a5de2b6),LL(0x738efe5b,0xb46af0ab),LL(0xdb4459f9,0xcf80a17f), + LL(0xf303955d,0x412f64a3),LL(0xbd692593,0xe92bdca9),LL(0xc2e964e0,0xfbe6cdc2),LL(0x0011cb01,0xe9a3b1fd),LL(0xcf228f23,0x6c30762d),LL(0xbe9199a1,0x1270b84a), LL(0xe3c9cbb1,0x732711df),LL(0xd91d9513,0xa3aabe37),LL(0xc6eceba7,0x8ee08ba0),LL(0xf3c3d31d,0xb1711531),LL(0x3c716948,0x65060b63),LL(0x2ff2cadd,0x046b4ea1), + LL(0x961719fe,0xdeb7a462),LL(0x76ba6ed7,0x5e22796d),LL(0x25d22208,0x5907daf2),LL(0x2c21c04c,0xd98260a7),LL(0xe090f349,0x56b24923),LL(0xa31a8f95,0xb5960ad9), LL(0xf8b1da62,0xb6ac57ce),LL(0x9f14f70f,0xe47d0995),LL(0x04dba20b,0x0ba6eb01),LL(0x46b60e27,0x41ca71c8),LL(0x6bf5eeef,0x2bbfdb30),LL(0xf075b238,0x58e16788), + LL(0xbab220c6,0x25d1124f),LL(0x61524e3e,0xcd1423c8),LL(0x0434fb51,0x75e4f45f),LL(0x5180ab2b,0xb5180a8f),LL(0x5b22e388,0x144e214e),LL(0x92263054,0x6b16dad1), LL(0x40863566,0x3ea75907),LL(0xdada3b46,0x372d5abd),LL(0x893d210f,0xb3ff5a3a),LL(0x5e29f3dc,0x39f8d1ce),LL(0x68200e82,0x559186ce),LL(0x1202cb66,0xf4876454), + LL(0xeaf4f2a1,0x699c2db9),LL(0x61c0c17c,0x8cd33227),LL(0x64f16a56,0x971b50d4),LL(0x102bbe10,0xcd00d42b),LL(0xb05f3cac,0x928d0ae2),LL(0x14bcf472,0x245dbe38), LL(0x947c0184,0x43d29526),LL(0x4612a4ea,0x24089968),LL(0x6c2b4541,0xbc763fcd),LL(0xf82448fa,0xb4e7ae0f),LL(0xb02b6459,0x94f1fa15),LL(0x67d39bbd,0xbcafa1ec), + LL(0x8b540904,0x6f178dbf),LL(0x8720472a,0x0264bccd),LL(0x59b46611,0xa6e8b4b4),LL(0xc72b4a58,0xafce8267),LL(0xa45985ad,0x21142175),LL(0xe649d733,0xd23401df), LL(0x85dc7720,0x6bf42fe0),LL(0x40e3f2f5,0xc5c8ab94),LL(0xcd029197,0xb0c8a58a),LL(0x215492e1,0xa73ff329),LL(0xb1b5a5f0,0x895c545e),LL(0x6fcaf49b,0x6dbc2445), + LL(0x44cc852a,0x705ad3d8),LL(0xb80518e0,0x10bb5add),LL(0x0de9f160,0xa34905bb),LL(0x94b1aacd,0x7d45aae3),LL(0x7fd5de7a,0xd30411d0),LL(0x4d0167cd,0xe2fc6206), LL(0x10ce71cf,0xd3b19612),LL(0xb28225fd,0x8e8096b6),LL(0x64a1c849,0x4b46fa80),LL(0xa51364e9,0x160479ac),LL(0xfaa3f0f2,0x9ebb6fdb),LL(0xf1511754,0x9ce029b9), + LL(0x0f2d76a3,0x25ef32d6),LL(0xaf4a7d46,0x540650b9),LL(0xd991d7f4,0x8979a4b8),LL(0x99202400,0xdaa706c2),LL(0xf19d281d,0x8a729680),LL(0x4ec44de2,0xde25bdc4), LL(0xc2054496,0x0fc50832),LL(0x0aaf2941,0xfee72fb6),LL(0xb82ed4f0,0xc8263e64),LL(0x6f49055c,0x91a8cb73),LL(0xf2bb515c,0xb7585458),LL(0xb855e6c6,0x03d2b23a), + LL(0xa0879d68,0x8e11e8e8),LL(0xbf7a84ac,0x2bea77a3),LL(0xa74b45d0,0x98140930),LL(0x810e587c,0x1ce28654),LL(0x8869daac,0x0a30756b),LL(0x39d2fe12,0xbf5e8245), LL(0xcac16a87,0xe6414992),LL(0x437aff7b,0xd2fa182d),LL(0xb6146094,0x4e61412d),LL(0x2f31bb4b,0x30a949ec),LL(0x22dc8ac6,0xf254c71f),LL(0x1ab2a0bd,0x1d9ed85c), + LL(0xcfd3f182,0x09ec1e3d),LL(0xadae7af9,0x1f1c30b5),LL(0x6b454164,0xf3a33f7c),LL(0x94647c4f,0x0318926f),LL(0x87db14ec,0x8e37bdd7),LL(0x2ab364d3,0x811cbd34), LL(0x7c2b369d,0x1dd1e507),LL(0xa28056bd,0x7a57bc46),LL(0x089efe44,0xfca5be4b),LL(0x6dc1290e,0xb3bd84d7),LL(0x8793e6ae,0x40d7af09),LL(0xa3723942,0x4e08e11f), + LL(0xeb73ec7d,0x649eeabb),LL(0x26a9aaf9,0x10983304),LL(0x4e296235,0xf22e4514),LL(0x7b85f801,0x695c8df4),LL(0x3ae7caaa,0xd4553344),LL(0xffbba90e,0x3e35bd47), LL(0x5d13b9ec,0xdd04f7c9),LL(0xe259f70d,0xe39a5d12),LL(0x201ae17c,0x39073063),LL(0x6a85435f,0xdba3eda0),LL(0xe948924a,0x6df48093),LL(0x00e3394f,0x9ffc4dcf), + LL(0x899ffebb,0xca3709ad),LL(0x77c00602,0x1a873778),LL(0xa99b4af0,0x5ff40c2a),LL(0xa80e870c,0x680464e5),LL(0x94e10b1d,0xd2f7f044),LL(0x4e9aa1a7,0xee9b206c), LL(0x96cbe950,0xb536d675),LL(0x9e8305f3,0x84185689),LL(0x369fa255,0xae1b669c),LL(0x7233e1ea,0x62e26026),LL(0x6aa60c24,0xac05c513),LL(0xd2691677,0xdfc6814f), + LL(0x397147d6,0xbe414528),LL(0x42592203,0x74851314),LL(0x0364b0eb,0x9084d330),LL(0x6ad70814,0xf8e5d6d5),LL(0xffb4ac5f,0xfcd4e0e3),LL(0x1fbf8899,0xf652417a), LL(0xccbd7eaa,0xb1165da7),LL(0x6e2d4e8c,0xf5dbd11a),LL(0x32ddcea8,0x5dab120a),LL(0x9892f728,0x30aaa56f),LL(0xd3d73838,0x71c2412d),LL(0xd2e2becb,0xbc0253d1), + LL(0x0a02b0fb,0x8baef5df),LL(0xc2b92b02,0x58a2b06b),LL(0x54c8267a,0x268558d7),LL(0xccf70393,0xf924f795),LL(0xf68ee021,0xe3763f30),LL(0x5c01ba4b,0xc1e856f0), LL(0x722b6bff,0xcc01a3e9),LL(0xed5b3b02,0xd2be4623),LL(0x6c45e33f,0x1ab3512e),LL(0x4ef433f6,0xa978fe48),LL(0x8e21f5af,0x23e2ea01),LL(0x11524a40,0x49647d88), +}, +/* digit=54 base_pwr=2^270 */ +{ + LL(0xd087b788,0xe1d42d94),LL(0xba0e176a,0xfbfb221a),LL(0x83686966,0x5f6698e7),LL(0x74a30dbf,0xbb5e1594),LL(0xcfd20230,0xef86bb5b),LL(0x403b8f8b,0xf055a1c5), LL(0xd9d85ea7,0xf249aac8),LL(0x3d200198,0x7318f7bc),LL(0xefca9a90,0x3b80960c),LL(0x8f449c4b,0xf28e3388),LL(0xf0cfe09e,0x0cdfc61b),LL(0x8b22cd26,0x3b169c63), + LL(0x203bb368,0x923e948c),LL(0x231a80e0,0x58e37a2b),LL(0x6df27deb,0x345a011a),LL(0xd57f4ca2,0xba6784c1),LL(0x114196e9,0xf01b3703),LL(0x1aab426d,0x981a63eb), LL(0x51770c1c,0x2ffdc978),LL(0xefa722fc,0xddd19da6),LL(0x16f09c1e,0x5ca1c012),LL(0x5b9cc0b6,0x612021de),LL(0x5e150569,0x910e10e9),LL(0xe2ab93ea,0xacace9dc), + LL(0x5070e0a9,0x0cdd8372),LL(0xec550783,0x7c5ad562),LL(0x4f3b8d2b,0x9652b847),LL(0xe6e98d73,0xfdd60d93),LL(0xa3479d0b,0xd51cae2c),LL(0xee05c006,0x11b93b6d), LL(0x8a3b40d5,0x9d72b82d),LL(0xa7d24855,0xc6e996fe),LL(0x398603de,0x420672f7),LL(0x9a1af2ce,0xd551b34a),LL(0x13bdce0c,0xdeb8c1d9),LL(0xebbeba7a,0x56ca926d), + LL(0x9db9ca19,0xac58c9e0),LL(0x390054d0,0xd308ea5d),LL(0x2cc42529,0x32ef4afc),LL(0x97c2bdf9,0x08bd48b3),LL(0xa849e19a,0xac8a7803),LL(0x75c31496,0xcd51c0da), LL(0xf0e2d49f,0x733dc7de),LL(0xb44b8cc5,0x7c9caad1),LL(0x47be21a8,0x6d9c5b08),LL(0x5ebf426f,0xfab0fdc5),LL(0xf94e9e5b,0xd60748ca),LL(0x69366089,0x3072e592), + LL(0x007d3d4d,0x8f24cfd9),LL(0xcb27ae66,0x2f4f7195),LL(0x9c1ed35e,0x8166162e),LL(0x4f4bdfd8,0xfdcf7666),LL(0x3b5373ca,0x6dc993bc),LL(0xa3ec42d5,0x2faa34d6), LL(0xc6b6109e,0x1cce84cb),LL(0x43632b7e,0x7a4178ad),LL(0xb2aab55b,0x6899adb5),LL(0x683c1397,0x080e42bd),LL(0x10960bfe,0x34d5e192),LL(0x7223406a,0x65415d21), + LL(0x6254954d,0x8acd0a3e),LL(0x1d8c2442,0x708f9359),LL(0x6dab2ff9,0x85f59135),LL(0x33a9d96a,0x9df92007),LL(0xcaa797ad,0xac9849a7),LL(0xfe95aa38,0xcea2067f), LL(0x995cb879,0x5a3c21b4),LL(0x69d4f07d,0x5c981a5d),LL(0xf0dc9aa6,0x028cf95d),LL(0xc68fd96a,0xcc5cee93),LL(0x0b69676f,0x8a5e73ee),LL(0x832d230b,0x190a7229), + LL(0xd40c5d9f,0xc0ab244b),LL(0xf3ef03ed,0xc05a11cf),LL(0x650ea714,0x1593d8ad),LL(0xfc6a1235,0x1edb6cbd),LL(0x4e451d0b,0xead76e1e),LL(0xae7ee558,0x4759e3c0), LL(0x7c8145e2,0x480627be),LL(0x88a339a2,0x82cec2c7),LL(0x752b0f58,0x17e887b6),LL(0xaa6c9df1,0x91c866d0),LL(0x29b3b1d3,0xd9a54848),LL(0xf641bbc1,0x17ae47ae), + LL(0xf0ef77c5,0xb06c17a3),LL(0x6df6bf59,0xc144e784),LL(0x0038aeb2,0x2440ae99),LL(0x58b402ca,0x83bf711b),LL(0xb577732a,0xb8763e00),LL(0xf651a932,0x509e91ef), LL(0x00ac109e,0xbe02ab9d),LL(0x8dfd78f1,0xfbcb426c),LL(0x4283f80f,0x7ed272f6),LL(0x2365da5e,0x098cf057),LL(0x05dc6beb,0xd90e6f18),LL(0xcf7b9d72,0x09ef177f), + LL(0x199785d5,0xebee13d1),LL(0x92f8f141,0x3d370648),LL(0x15e3a026,0x56595c83),LL(0xe6e5c659,0xa0f4960e),LL(0xc052f5d6,0x27d5bc54),LL(0x8677ef24,0x9c5437dc), LL(0xdb9b78fc,0x28ae53a3),LL(0xd91113f9,0x025b81a7),LL(0x6ac445f9,0xfb423fb3),LL(0x575649cf,0xb555a8b5),LL(0x06ae0cb6,0x3ac93b08),LL(0x8d2e3be1,0x7a706bb5), + LL(0x97c0cb32,0xcabd7301),LL(0x65f83e1d,0x1698cfd3),LL(0x62043a8b,0x44833254),LL(0x3b4c8bac,0x43d1641f),LL(0xe344a05a,0xcc394a5b),LL(0x853c1f6d,0x9e085b71), LL(0xcf627733,0x35a67867),LL(0xeab971dc,0x9d668c2b),LL(0x46c5f3bd,0x458a801d),LL(0x446c5e3b,0xb7b08696),LL(0xc15fc828,0x468ae44a),LL(0xab2761ff,0x9503fd49), + LL(0xce8d4427,0x7278f12f),LL(0xeb15f81f,0x036aef18),LL(0xa58e95ea,0xcbe64b86),LL(0x59b2428c,0xf933a850),LL(0x52f1b0fb,0x8d117bfc),LL(0x0bed33e2,0xba9dbc6f), LL(0x6ece7dc5,0x3e152fb5),LL(0xeb80d7ff,0x90e88871),LL(0xddf09489,0x0aa265aa),LL(0x2476414f,0xa17584cc),LL(0xcb0418ea,0x2d241d33),LL(0xc3a7529b,0x1c40e835), + LL(0xe3e1aee9,0x89b2edba),LL(0xe55e4aca,0x33533137),LL(0x8943fce4,0x1dded9ce),LL(0x5a2ff996,0xaaf07ff4),LL(0xc96e87fe,0x69e60f92),LL(0xb9ee808c,0xc2e5c1d5), LL(0xbe466616,0x79d6d8c6),LL(0xdffe4e28,0x897f6c2f),LL(0x350b7fc9,0xc8a65267),LL(0x8a2abab0,0xe9fcb46d),LL(0x2c4faf7c,0x57c3bfc6),LL(0xa8207c8a,0x41a8cc2a), + LL(0xa74858fb,0xb60e8daa),LL(0x50c7c2f8,0xaa4c8ca5),LL(0x31a39837,0x9eb37096),LL(0x69f44aa5,0x5742fb32),LL(0x51e793a0,0x086aa479),LL(0x55e7c373,0x9bcaf657), LL(0x1b13101d,0x63cee90c),LL(0xe7d42d91,0xbc410452),LL(0x913aa0fb,0x3041007f),LL(0x502be876,0x9a00ad14),LL(0xb8677568,0xa137a443),LL(0x46ca4efa,0x5b26b995), + LL(0xaed60a78,0xe33585b7),LL(0x3cbb2e24,0xd208deea),LL(0x1aca34e8,0xff32cccb),LL(0x7b64d250,0x52ebce07),LL(0x84d8b907,0x93a4d0a1),LL(0x77de8d42,0xd759bef0), LL(0x5d07487d,0xbd60c87a),LL(0xc74f79df,0x63620986),LL(0x4a52f837,0x54f5f2c8),LL(0xf3cec619,0x340a1f53),LL(0xfc85bf85,0x1e922bc4),LL(0xc3bfdf09,0xc92e7b85), + LL(0x0eb9e6bc,0xeb1a37c3),LL(0x4fbf1cb1,0x8c393d89),LL(0xd1f10389,0x6ac9427e),LL(0x7c8caefc,0x77b8cfc1),LL(0x1a61bdd5,0x554ab4af),LL(0xad75e46b,0x661a99f1), LL(0x439a0456,0x11fc01bb),LL(0x8d0046c9,0x5b7fedd2),LL(0xfbece9e3,0xcfded2ef),LL(0x11440124,0x4e4dcb0b),LL(0xdee23c7d,0x2a5fd0fa),LL(0xf662402c,0xaa5f345a), + LL(0xeeb791c4,0x6f101762),LL(0xdf261eff,0x0d942184),LL(0xac1dc827,0x2c58e2aa),LL(0xf835a1b6,0x51410e89),LL(0x629915a4,0x981333a7),LL(0x0c14148d,0x371891b6), LL(0xc0904446,0x4d20b3d3),LL(0x949776d8,0xdda7ecc8),LL(0x2a2645f7,0xa664b68c),LL(0xadd082ea,0x7a6bc857),LL(0x3e5ff206,0xe7467dc6),LL(0x04e2dfcc,0x40a6c340), +}, +/* digit=55 base_pwr=2^275 */ +{ + LL(0x03744726,0xa2354569),LL(0xd8d275ac,0xd2169e6d),LL(0x132c5689,0xab0c247b),LL(0xcc4760bb,0x129a5c9d),LL(0x26ae821b,0x03eba467),LL(0x3df1cf83,0x67a33fda), LL(0xb8421b7a,0x010813cf),LL(0x98cd6d76,0x7b0f5070),LL(0x1fe4b600,0x907320b3),LL(0x98dd3239,0xda3bfeb3),LL(0x41abb34c,0x23f1ed16),LL(0x946f85f1,0x01b30f29), + LL(0x9666f8ea,0x28524830),LL(0xeff6502b,0xd579b3df),LL(0x00e4f78a,0x3a66fa99),LL(0x54a3f7a3,0xfd8a65bb),LL(0x1965a79a,0x505d3f63),LL(0x1891469a,0x9524972c), LL(0x3354da3a,0x78367cbc),LL(0xe4941c6e,0xbfe1fe3d),LL(0xf5af173e,0xe41bb3f6),LL(0x5ca36597,0x57cb03ca),LL(0x7b99f795,0x27f86cb8),LL(0xad4dcef1,0x5cae6514), + LL(0xd87a86c9,0x4952a350),LL(0x034f45f9,0x08ed7da7),LL(0x2bd716d0,0x1e9ff827),LL(0xf1d9331f,0x2471fd15),LL(0xd7370b75,0x0c708362),LL(0xfc1a1051,0xaddedde6), LL(0xdb27b186,0xf4475288),LL(0x3760bc11,0x5be4d46b),LL(0x06d47ee1,0xe44435d9),LL(0xd0b7c8a2,0x865cf7c8),LL(0x8d31a252,0xdb412be0),LL(0x2f24d71c,0x4b90a932), + LL(0x55f0ad9f,0x38a49bf5),LL(0xf3618639,0x1a84c6b8),LL(0x01b2f7c2,0x5f709eca),LL(0x5be8359f,0xc479a650),LL(0xd6646b3f,0x6b6a22bf),LL(0xcc5b711b,0xcce78878), LL(0xb446cc63,0x8e7dbc63),LL(0x218f800f,0x231bd027),LL(0x030271eb,0x2d3a7e04),LL(0xe22fb3c7,0xb08b5978),LL(0x9be0d46c,0x860d6278),LL(0x1d49a915,0x253a31c2), + LL(0x376bdc3f,0xbad6b669),LL(0x23a9ff38,0xc4a8e7bc),LL(0x555fb0a3,0x3f54d8c4),LL(0x2b23db1b,0xfb3d5e1d),LL(0xf0d7eba9,0x6379f78a),LL(0xfa0beffa,0x36004feb), LL(0x334ff01a,0xdf0a373c),LL(0xdff12a1c,0x10314749),LL(0xf184c1b3,0x1d52ddc7),LL(0xab02d404,0x79431663),LL(0x7f4d3795,0x1a6488c1),LL(0x7cca9102,0x3363660f), + LL(0x04dc109c,0x56d65156),LL(0x09c1d307,0xcd740cc8),LL(0x10dfaead,0xef9e049f),LL(0xe30b70b8,0x19750b3a),LL(0x15c6a562,0x11ed8600),LL(0x12097026,0x53bdf97e), LL(0x6c0d908f,0x79559d05),LL(0xb506d527,0x8f1d75ba),LL(0xae8fb3c4,0xd6fd7323),LL(0xa4111f88,0x834639c9),LL(0xa310a683,0xfc69a029),LL(0x255f2e9a,0xa4467bbb), + LL(0xa3526fec,0x5f0a58a8),LL(0x02f028c1,0x849c171b),LL(0x56a5d3b5,0x34d77ce8),LL(0x54d5a92b,0x97016217),LL(0x2cc5b70b,0x0cce35c1),LL(0xe83f1f4a,0xd9d5a00a), LL(0x26a0368b,0x064223f8),LL(0x40e16452,0x328a9f69),LL(0xd305ad2c,0x3a6ac093),LL(0xbeba7c44,0x759d9a16),LL(0x637ce7c8,0x86021de7),LL(0xcc80c1cc,0x276bed61), + LL(0xbbe4bdda,0x66797f56),LL(0xda51b1a2,0xb92a369e),LL(0x31adb034,0x18eef4a5),LL(0x5d185cfc,0xcf1cb5ee),LL(0xbd53c27b,0xf596a59b),LL(0x69002569,0x1e1dd6f5), LL(0x7687e48a,0xd9433e79),LL(0x0cbcb9ce,0x7d8d24c2),LL(0x65d68ecd,0x233cd7ed),LL(0xfb2aded8,0x201bbe09),LL(0xac9b750e,0x987f4975),LL(0x337f7f25,0x949da385), + LL(0x9c7de99f,0x00c2ee1c),LL(0x15e50391,0x28a7461d),LL(0xa1c77952,0x1bdc0e32),LL(0xd53d640d,0xe98242c4),LL(0xcf153c7d,0x1a4724d2),LL(0xba477d46,0x194e5dcc), LL(0x3a0d4ccd,0x871c8cfe),LL(0x9af451fb,0x62010af0),LL(0x6ddec75c,0x9b354f9e),LL(0x680e3511,0xe5db0a5d),LL(0xd247745b,0x183d1270),LL(0xeecf52dc,0x9910867a), + LL(0x0410ca0b,0x6fb6b7bc),LL(0xb3c13935,0x0e16eed2),LL(0x316ff531,0x98ad89d8),LL(0x9894d65f,0x4800ee17),LL(0x48280170,0x034ea3c4),LL(0xc30be537,0x8126d12d), LL(0x5120e525,0x43c2d27e),LL(0xee65df90,0x96a5d498),LL(0x5eaef29a,0x65454010),LL(0x7b678fc7,0x1d8f07a1),LL(0x7b301270,0x54bc6f73),LL(0xe9473365,0xe58a8102), + LL(0x4ac6cf02,0x460c2990),LL(0x420a35b7,0x01482cfa),LL(0x34680972,0xf793933a),LL(0x17e2367b,0x2cd1f500),LL(0x3944f060,0x2411c352),LL(0x11c06b05,0x3d58b974), LL(0xcddebb3b,0x4552e369),LL(0x009aeab9,0xe1c38aec),LL(0x353b6e4f,0x9d34737c),LL(0xb16d7b0c,0xf2c99e2c),LL(0x7bbba6a2,0x57029fa4),LL(0xd13ef64d,0x0565d1bc), + LL(0xa329deb1,0x3561b3fe),LL(0xf1c3c3e4,0xfdca0e34),LL(0x47fb79d6,0x43748313),LL(0xc48002ed,0xa7f497e1),LL(0x2c44dcb0,0x86221cce),LL(0x43785e06,0x65e3f046), LL(0xdf4cf461,0x9ee9061f),LL(0xf022d27a,0xc7479e8c),LL(0x76f7f52b,0x1d8de85b),LL(0x0fd6c65f,0x39a713c9),LL(0x711f8a39,0xf74ca067),LL(0x8ebc640a,0xad1119ad), + LL(0x8ba85dff,0x59753bf6),LL(0xd1c89bce,0xec8b82ef),LL(0xb8b6a683,0xd7f1a651),LL(0x6f84416d,0x9c329bf3),LL(0xe68db225,0xaecbf4b9),LL(0x5a614d23,0x94ec3b0f), LL(0x93a9543d,0xbcb66725),LL(0xf19132ed,0x90c46c46),LL(0x950b080f,0x4767c73c),LL(0x971fd9e5,0x0b9b143e),LL(0x8ec8c68d,0xbce6886f),LL(0xd47f512e,0x167b0f8a), + LL(0xcd74009d,0x1942c2ff),LL(0xe9c286a4,0x71c4d5f5),LL(0x771a5972,0xf3c152b5),LL(0x363c2048,0x4cfb1e74),LL(0x9ddb8da2,0xcd2ce824),LL(0xa5ee443d,0x5d97c8e0), LL(0x68d7b3d5,0x6fa84b3d),LL(0x9ce14ec3,0x97eaa76d),LL(0x8e13869d,0x2e457136),LL(0x96f0f8a1,0x39ac6a0c),LL(0x42d93dc0,0xe24458ac),LL(0x5f60bec9,0x7eb3689d), + LL(0x588360ec,0x29544fe8),LL(0xffb550ea,0xa1aa9b9f),LL(0x4af4d28d,0xe1f6cf99),LL(0x0c6fd477,0x723d48b0),LL(0x5c81b252,0xf51f1b2f),LL(0x4f5a33ee,0x88ec11c0), LL(0x2cd72de4,0x7747f043),LL(0xd71c92c1,0xcca69b0a),LL(0x4e8cc763,0x9455d86e),LL(0xc08444e0,0xc9e0aa1b),LL(0xe8fffa63,0x93803b68),LL(0x2d781b7d,0xc296af29), + LL(0xb08d2d0e,0x514cc1dc),LL(0x30e93536,0x4e6b379e),LL(0x2fc9230f,0xf0e422ac),LL(0x92e23e21,0xaa50a1ad),LL(0x676d1ac0,0x70ac46d8),LL(0xf9f54493,0x698b9991), LL(0x8649519f,0x59a6b86a),LL(0xe3511da4,0xc1f11ad6),LL(0x3192968c,0xd3d9cff1),LL(0x0b342dd8,0x13e700b4),LL(0x3b1da441,0xfd5dc7bb),LL(0x2c883760,0x02426e7c), +}, +/* digit=56 base_pwr=2^280 */ +{ + LL(0x1c4c9d90,0x9e9af315),LL(0xd12e0a89,0x8665c5a9),LL(0x58286493,0x204abd92),LL(0xb2e09205,0x79959889),LL(0xfe56b101,0x0c727a3d),LL(0x8b657f26,0xf366244c), LL(0xcca65be2,0xde35d954),LL(0xb0fd41ce,0x52ee1230),LL(0x36019fee,0xfa03261f),LL(0x66511d8f,0xafda42d9),LL(0x821148b9,0xf63211dd),LL(0x6f13a3e1,0x7b56af7e), + LL(0xcc8998d6,0x3997900e),LL(0xbaa60da1,0x8fa564b7),LL(0x661f3c57,0x71bf5b0a),LL(0xaab1292b,0x44b13388),LL(0xd4d993f2,0xcbe80cb9),LL(0x2203f966,0x0b19b4c9), LL(0x0080f259,0xbc82a652),LL(0xad96dea3,0x870ebc08),LL(0x502f0003,0xa388c7e7),LL(0x56a38f73,0x9c704ef0),LL(0x3487d9b0,0x93cde8a7),LL(0xec11a1f3,0x5e9148b0), + LL(0x5913e184,0x47fe4799),LL(0x82145900,0x5bbe584c),LL(0x9a867173,0xb76cfa8b),LL(0x514bf471,0x9bc87bf0),LL(0x71dcf1fc,0x37392dce),LL(0x3ad1efa8,0xec3efae0), LL(0x14876451,0xbbea5a34),LL(0x6217090f,0x96e5f543),LL(0x9b1665a9,0x5b3d4ecd),LL(0xe329df22,0xe7b0df26),LL(0x0baa808d,0x18fb438e),LL(0xdd516faf,0x90757ebf), + LL(0xa748b8f5,0x63f27a25),LL(0x2cd246c4,0x68c8f3ec),LL(0x65f9ce38,0x5d317cd9),LL(0x635ba300,0x162c92e0),LL(0xfe343662,0x5259f64f),LL(0x8e614ac8,0x4a6b2b66), LL(0x01177c3b,0x97fb55bb),LL(0xa705cb01,0xfb586c21),LL(0x78061824,0xa57e7325),LL(0x6c1e6306,0x892f6b38),LL(0x2367b14c,0xf12e4c07),LL(0xc83a48c5,0x580d5fe2), + LL(0xd5a98d68,0x1e6f9a95),LL(0x849da828,0x759ea7df),LL(0x6e8b4198,0x365d5625),LL(0x7a4a53f9,0xe1b9c53b),LL(0xe32b9b16,0x55dc1d50),LL(0xbb6d5701,0xa4657ebb), LL(0xeacc76e2,0x4c270249),LL(0x162b1cc7,0xbe49ec75),LL(0x0689902b,0x19a95b61),LL(0xa4cfc5a8,0xdd5706bf),LL(0x14e5b424,0xd33bdb73),LL(0xe69eba87,0x21311bd1), + LL(0xea2bafb3,0x6897401c),LL(0x15c56fe4,0x7b96ecc2),LL(0x39e2b43b,0xe511b329),LL(0xbf809331,0x39522861),LL(0xc958f8f4,0x815f6c1d),LL(0xc213e727,0x2abbdf6b), LL(0xc39bc01f,0xeb09ae59),LL(0x676b56a5,0xffe3b831),LL(0xa20f86c6,0x8f4815a2),LL(0x9aa30807,0x748a1766),LL(0x1b758878,0xf1f46a21),LL(0x6f6fc3d7,0xbd421fe7), + LL(0x72a21acc,0x75ba2f9b),LL(0xa28edb4c,0x356688d4),LL(0x610d080f,0x3c339e0b),LL(0x33a99c2f,0x614ac293),LL(0xaa580aff,0xa5e23af2),LL(0xe1fdba3a,0xa6bcb860), LL(0xb43f9425,0xaa603365),LL(0xf7ee4635,0xae8d7126),LL(0x56330a32,0xa2b25244),LL(0x9e025aa3,0xc396b5bb),LL(0xf8a0d5cf,0xabbf77fa),LL(0xea31c83b,0xb322ee30), + LL(0x0d6ded89,0x300b0484),LL(0xc3ab55ed,0x0b1092cb),LL(0x0cc10a74,0x17d9c542),LL(0xeff9d010,0x7f637e84),LL(0x27aa1285,0xd732aa1e),LL(0xe2a77114,0xedb97340), LL(0x5ef4dfb0,0x62acf158),LL(0xba1d7b81,0x1e94fc6e),LL(0x2e6eb2db,0x88bec5d2),LL(0x8d18263d,0xaec27202),LL(0xe4bbd6ac,0x4b687353),LL(0x0ff7e4c0,0x031be351), + LL(0x7890e234,0x04881384),LL(0x672e70c6,0x387f1159),LL(0x7b307f75,0x1468a614),LL(0xed85ec96,0x56335b52),LL(0xd45bcae9,0xda1bb60f),LL(0xf9faeadd,0x4d94f3f0), LL(0xfc78d86b,0x6c6a7183),LL(0x3018dec6,0xa425b5c7),LL(0x2d877399,0xb1549c33),LL(0x92b2bc37,0x6c41c50c),LL(0x83ee0ddb,0x3a9f380c),LL(0xc4599e73,0xded5feb6), + LL(0xf086d06c,0x6c00f388),LL(0x5add0cf4,0x17ee4503),LL(0x07caf89c,0xf96984c7),LL(0x648ed5e9,0x9d49d667),LL(0xa0164881,0x3ef95015),LL(0x7d9c651f,0x39e28e44), LL(0x59f37780,0xb13ad240),LL(0xb9522225,0x08cee349),LL(0x2ba1b214,0x9245ee6f),LL(0xa886d8d2,0x12bedaa9),LL(0xfcb8186f,0xe139ae08),LL(0xfc2ef864,0x99203fb6), + LL(0x0b7f8354,0x14d34c21),LL(0x9177ce45,0x1475a1cd),LL(0x9b926e4b,0x9f5f764a),LL(0x05dd21fe,0x77260d1e),LL(0xc4b937f7,0x3c882480),LL(0x722372f2,0xc92dcd39), LL(0xec6f657e,0xf636a1be),LL(0x1d30dd35,0xb0e6c312),LL(0xe4654efe,0xfe4b0528),LL(0x21d230d2,0x1c4a6820),LL(0x98fa45ab,0x615d2e48),LL(0x01fdbabf,0x1f35d6d8), + LL(0x64c9323d,0x3c292847),LL(0x0491f77d,0x40115a89),LL(0x2d7a05f5,0xec141ade),LL(0x222a5f9f,0x0c35e4d9),LL(0x442a3e9b,0x5ea51791),LL(0xe51b841e,0x17e68ece), LL(0xd6ae9174,0x415c0f6c),LL(0x9ffd7595,0xe6df85f8),LL(0x8dedf59c,0x65fc694f),LL(0xfee92718,0xc609503e),LL(0x97d565ae,0x57d2592e),LL(0x7e20862b,0xb761bf15), + LL(0x3a7b10d1,0xa636eeb8),LL(0xf4a29e73,0x4e1ae352),LL(0xe6bb1ec7,0x01704f5f),LL(0x0ef020ae,0x75c04f72),LL(0x5a31e6a6,0x448d8cee),LL(0x208f994b,0xe40a9c29), LL(0xfd8f9d5d,0x69e09a30),LL(0x449bab7e,0xe6a5f7eb),LL(0x2aa1768b,0xf25bc18a),LL(0x3c841234,0x9449e404),LL(0x016a7bef,0x7a3bf43e),LL(0x2a150b60,0xf25803e8), + LL(0x82376117,0xd443b265),LL(0x1a1beb0d,0xb91087c1),LL(0x45cc5951,0x3fe62a65),LL(0xe6e472d5,0x49c754bc),LL(0x77c424eb,0x7e60bb81),LL(0x830cbb97,0xbcd4088e), LL(0xba26df7b,0x3da5c94e),LL(0xf72b4338,0x508b4f55),LL(0x69ad7784,0x409c5c74),LL(0xfdf44d6a,0x82e5f1b0),LL(0xeed2766f,0x10654a1c),LL(0xa6e83f4a,0xef1e65fa), + LL(0xb215f9e0,0xe44a2a57),LL(0x19066f0a,0x38b34dce),LL(0x40bb1bfb,0x8bb91dad),LL(0xe67735fc,0x64c9f775),LL(0x88d613cd,0xde142417),LL(0x1901d88d,0xc5014ff5), LL(0xf38116b0,0xa250341d),LL(0x9d6cbcb2,0xf96b9dd4),LL(0x76b3fac2,0x15ec6c72),LL(0x8124c1e9,0x88f1952f),LL(0x975be4f5,0x6b72f8ea),LL(0x061f7530,0x23d288ff), + LL(0x5f56dc3c,0xa6e19d0a),LL(0x0b88326a,0xe387e269),LL(0x0ee527a4,0xef738095),LL(0x7c4278a6,0x78b7174b),LL(0xe70798ff,0xc133d867),LL(0x9e9230ca,0x9d0fef75), LL(0x1a955ab9,0x7431eef0),LL(0x8868d922,0x3772e703),LL(0x8d6af3f7,0xf7a4306a),LL(0xbbec076a,0x633bb5a0),LL(0x7a257ca3,0x6d07623e),LL(0x21c00663,0xffb5e165), +}, +/* digit=57 base_pwr=2^285 */ +{ + LL(0xbb71e9b0,0x35ae891b),LL(0x522b77f0,0x1f6ce6ca),LL(0xe63745c4,0xc2dab3ca),LL(0xf218d139,0x55b8c185),LL(0x89f3b0e2,0x6ab039c8),LL(0xc644c3fa,0xd9e25bfd), LL(0x3e2ed47b,0xc8496f20),LL(0x8d67e17c,0xc395ec02),LL(0x92114918,0x5c678392),LL(0xef73f345,0xe962e52f),LL(0x54fcfb22,0x3818baf3),LL(0x9d4bc911,0x4d75d65d), + LL(0x022ea83a,0x7f1f985c),LL(0xa7584e7f,0x90a22662),LL(0x5188fcf6,0xb40a930a),LL(0xa3a82904,0x3fad79ab),LL(0xf3151027,0x7bee8d22),LL(0xc2c3e17b,0x79a1a838), LL(0x33cc3509,0x1fbe06e9),LL(0x9abd5cca,0x629c56aa),LL(0x2d9cf7a5,0xfff290ec),LL(0x9bd062c5,0x5d0dedaa),LL(0xd7d35381,0x080344ab),LL(0xf5cf9eda,0x0848373a), + LL(0xa1b31832,0x170098de),LL(0x2cd8c540,0xc6876bf9),LL(0x8660d773,0x35b1b04b),LL(0x5152ad1e,0x8b4b6c4b),LL(0x4a8e92aa,0x0b0bd1c2),LL(0x88172f4e,0xd814f6f4), LL(0x41ac83d1,0x13a76899),LL(0xf1d80357,0x355933b4),LL(0x3dc17e72,0x4b394f97),LL(0x0a7124b2,0x1b0cd166),LL(0xce8a372c,0x7549880c),LL(0xe712603b,0x79f53f7e), + LL(0x7a0c0bc0,0x31d31f7a),LL(0xb251d2bf,0x7a37a84a),LL(0x52f04d67,0x1793362e),LL(0x21c7b651,0x5808e709),LL(0xed6f47f6,0x33fe9123),LL(0x58f71405,0xdeb1dde9), LL(0xae56b472,0x821d3045),LL(0xe02043ad,0x9f61f761),LL(0x5b2048a9,0x932ddb14),LL(0xd7811330,0x17d989fe),LL(0x128fd85f,0x032ae4cb),LL(0x7d1ef434,0x8f1956b4), + LL(0xce1d819c,0x30cc44e0),LL(0x15a3a414,0x3c2c4f04),LL(0x665b634b,0x7f06d2c2),LL(0x7df0bd69,0xf609fe64),LL(0x6a0dbf94,0x4b0c8c36),LL(0x46e9b487,0xd0a3a752), LL(0x9578a83f,0x7407e157),LL(0xfe0f975f,0xc46ffa4f),LL(0x1efaeccf,0xb086f199),LL(0x64796c18,0xf984b69d),LL(0x8ebfb97d,0x14de44fa),LL(0xf5245ba6,0x47bcb675), + LL(0x0dbafc49,0xed58c1ab),LL(0x6fa8b473,0x41995a5a),LL(0x85450ccb,0x3af3853d),LL(0x601fe529,0x18d1a7be),LL(0xdab2d926,0xd196520f),LL(0x56213ae9,0xd1f2c1e9), LL(0x77ded01d,0x37218255),LL(0xa7905433,0x366c552d),LL(0x7d9430d1,0x023d0373),LL(0x9ddf69ea,0x65d70cb6),LL(0xd4d3fa24,0x6321df7a),LL(0xb91084c3,0x77b1c2bf), + LL(0x0aef0ff7,0x2434dbdf),LL(0x9cc3d2ba,0xca74413e),LL(0x3dcbaeb9,0x0aee0d65),LL(0x4184a72e,0x89568076),LL(0xbe7d4e0f,0x3d7e4f61),LL(0xae441b4c,0x284a8608), LL(0x6a67283c,0x7274fd92),LL(0xc06e0b84,0xa222be15),LL(0xe4623e88,0xa0713cd7),LL(0x4710aa33,0x0ff4a317),LL(0x044dcecd,0xc9a35a65),LL(0xde77a24b,0x7bae1eca), + LL(0x16973cf4,0x070d34e1),LL(0x7e4f34f7,0x20aee08b),LL(0x5eb8ad29,0x269af9b9),LL(0xa6a45dda,0xdde0a036),LL(0x63df41e0,0xa18b528e),LL(0xa260df2a,0x03cc71b2), LL(0xa06b1dd7,0x24a6770a),LL(0x9d2675d3,0x5bfa9c11),LL(0x96844432,0x73c1e2a1),LL(0x131a6cf0,0x3660558d),LL(0x2ee79454,0xb0289c83),LL(0xc6d8ddcd,0xa6aefb01), + LL(0x81069df0,0xda10f552),LL(0x560ea55a,0x70088f4e),LL(0xda8cbaa5,0xdcee31af),LL(0xbe16a7b7,0x1213b76a),LL(0x781114d1,0x4fffa388),LL(0x904479d2,0x2cc19aa9), LL(0x85eec3cd,0xc4ebf9be),LL(0xbaff7431,0x48ea527a),LL(0x52d3ce22,0xa5b6fdca),LL(0x7e139d7a,0xbcb07835),LL(0x5de5de75,0xc7f17551),LL(0x15bcf7aa,0x005ab4d9), + LL(0x41383866,0x041511b0),LL(0xdb9c2b4c,0x7c90692a),LL(0x61deb106,0x736cc6af),LL(0xb5b84abe,0x57d428cb),LL(0x35dbcca9,0x14bc4981),LL(0x37f3ef2e,0xece90041), LL(0x85066bd0,0xe2c33711),LL(0xabef34c2,0x335bd50b),LL(0xb017a337,0x755f513d),LL(0x284445ad,0x28d263e2),LL(0xecb8436e,0x83402ba9),LL(0xf31d28d4,0x66357324), + LL(0xbce3cea0,0x05fb9811),LL(0xdf2b07df,0x74adb5b5),LL(0x0c4e5e2a,0x870e63b8),LL(0xe5fec889,0xe873cba7),LL(0x19cd8a3e,0x28b0e005),LL(0x48112c8c,0xbb16491b), LL(0x5df42faa,0xddb8cfb5),LL(0x2ab1a097,0x35f952ae),LL(0xd2dfa18f,0x35e885e1),LL(0x5b4a0277,0xc3ec2325),LL(0xc5aecee0,0xdbe2e40c),LL(0x0690080a,0x133383c9), + LL(0x7521f457,0xe5d473dc),LL(0xa00be577,0xe9ef09bd),LL(0xb6eaa640,0xf6d0965f),LL(0x75726560,0xeb494868),LL(0x28817302,0x452116d5),LL(0xfbde3597,0xf0424fdb), LL(0xbb454915,0xd6096da3),LL(0x41422141,0xde482808),LL(0x2d19fac0,0x7a135197),LL(0x21393f6f,0xdc9a5ec4),LL(0xeb2c8ada,0xcabcc1e3),LL(0x42d8c4f2,0xd4366431), + LL(0x34246834,0x46c7b438),LL(0x2eb9f9bc,0xa0a570c3),LL(0x586a0fdd,0x3e01db21),LL(0x9d21192c,0x15732b07),LL(0xfd747dd8,0xe544b5c9),LL(0x7ed374fb,0xeee7e104), LL(0x3b75a586,0xfa619086),LL(0xe8a4cfd4,0x9d0909f4),LL(0xccd93fa4,0x30e0e476),LL(0xa14595d4,0x5bdc5c02),LL(0xe245400f,0xf6f8ab6a),LL(0xa4198419,0x7bd194ce), + LL(0x68e190a6,0x713a654c),LL(0x3037a8e6,0x6317f6ab),LL(0x6b6bafef,0x005f412a),LL(0xb53eb41a,0xf67f8201),LL(0xf51ccf93,0x96585fcb),LL(0x045104e0,0x68ed706e), LL(0x40db03d9,0x535dc2a7),LL(0xda583d56,0xb9f0b69d),LL(0x414dc76a,0xeed71cb1),LL(0xc5e7698e,0x7368aabd),LL(0x4689da93,0x3eb6a4f1),LL(0xfcb73b42,0x753fa65a), + LL(0x9b860b0f,0xf5131aad),LL(0xd9bcf9c9,0x19af93ce),LL(0x307ca1ca,0x69b9765d),LL(0x87936c0b,0x0b735808),LL(0x1107f1cb,0x10eaf7ae),LL(0x16dfe03b,0x15211ad5), LL(0xb11c8af6,0x9bde40d5),LL(0xed1fc8be,0x513ea01a),LL(0x5412ab86,0x2f04be27),LL(0x9de582fc,0x2a1adc4a),LL(0x00de0043,0xb0c43235),LL(0x006efb33,0x689e15e4), + LL(0x89e4e449,0x0ed1082f),LL(0x833f2378,0xdb1fb471),LL(0xece77352,0xa35fef0e),LL(0x4bf0c426,0x76adaa46),LL(0xa011b2fb,0xfbab929a),LL(0x9d8cc4d3,0x6f475d5b), LL(0x74351480,0xbe6d7f21),LL(0x93e4a7ae,0x2d1362d1),LL(0x106ceaab,0xc7e2cba5),LL(0x45258697,0xfe94528a),LL(0x075945b0,0x7109b17d),LL(0xcae17f7a,0xfd395b2c), +}, +/* digit=58 base_pwr=2^290 */ +{ + LL(0x310404a8,0xfc1faedc),LL(0xd3bcb128,0xea339148),LL(0x6416defd,0xf0048545),LL(0xc58653e7,0x75de7770),LL(0xe2f6f99e,0xdd2dcbeb),LL(0xd159ac07,0xa4380ef4), LL(0xe4173608,0x45dd713c),LL(0x446a6789,0x44919b61),LL(0x6b962b38,0x3f73756b),LL(0xbffd3f0c,0x3cb9f53b),LL(0x7f08ebae,0xd723c40b),LL(0x0c3cddba,0x998a9b17), + LL(0xf6ba1469,0xf6377e3b),LL(0x09c832d3,0xc334fb6c),LL(0xc21c0cf1,0x7f85ac42),LL(0x857d8edb,0x7a3e31c9),LL(0x27b77ed6,0x2eb10763),LL(0x38dae10b,0x2bfbbdbc), LL(0x7bae3b4f,0xed7c6fb1),LL(0x36d04e6f,0xc5911d9f),LL(0x4569e72f,0x4dc43550),LL(0xbedae3ab,0xaa82fb97),LL(0x4f27e463,0x06d37bef),LL(0xf0c35a11,0xd0dbce6d), + LL(0x661019ec,0x43c78835),LL(0x24e66d29,0x68e916b1),LL(0x24094671,0x02c0f3a2),LL(0xd0f17d86,0xab6f1c05),LL(0xa22d4264,0x6d3bac72),LL(0xf6e5fafe,0xd7b8f152), LL(0x39447eb3,0x95627c63),LL(0x79e1ff93,0xfd159018),LL(0x5ad80806,0x39277c83),LL(0x0d7c7b74,0x758aafc9),LL(0x4cb8bec9,0x605ad8ca),LL(0x5741828a,0x6a90085c), + LL(0xff8b1fbe,0x6edf5561),LL(0xf6eac0c0,0x614b788e),LL(0xd8d66d29,0x7699ae56),LL(0xe9d58eb2,0x5f81602a),LL(0xfaf9176d,0xd0c04874),LL(0x523153b1,0x4b3a0046), LL(0xf6315883,0x9690930f),LL(0xa60ca92d,0xa81c0b44),LL(0x73bcba90,0x2d0e7258),LL(0xe902e329,0x57efe72d),LL(0x76bc27b9,0x3fcd5986),LL(0x93940c09,0x492adf03), + LL(0xf820c195,0x6895dbe2),LL(0x3f6c7b40,0x3787a500),LL(0xac1e90f3,0xdc718243),LL(0xba5d0870,0x352f8c91),LL(0xec0112b5,0xf3d1c53e),LL(0x6b84f64a,0x08a0782f), LL(0x8eedd5d4,0xd659e635),LL(0x29537276,0xfc30df6c),LL(0xa1755ce0,0xbfb09978),LL(0xaa2b4187,0x227f7b12),LL(0x226539d2,0x828730b9),LL(0xb2472c95,0x9051a37c), + LL(0xb39317b8,0x7de743e2),LL(0x2d372acf,0x9205d447),LL(0x3eeb0012,0x8226fc30),LL(0x2af74be6,0xab2a3e05),LL(0x4af91ac0,0xbe476780),LL(0x0ca36bf4,0x98497c71), LL(0x8d6dedb4,0x74fdf7cd),LL(0xa0fc5919,0xb50778ee),LL(0x2fcd7c63,0x5d5ec33f),LL(0x7f33cde0,0x667b8193),LL(0x38364d44,0xce48ae4b),LL(0x223ed67e,0xb8578963), + LL(0x9567f5f4,0x4b20d182),LL(0x18f02b34,0xde7e8149),LL(0xecff9dd7,0xc9a4be7b),LL(0x9812fd3f,0xe2f70bbe),LL(0x9c889263,0x471bf90c),LL(0x3e61f5bf,0xb60d01b5), LL(0xd22d855b,0x258c7f89),LL(0xb75a7d4f,0x35ef5c15),LL(0xb247f27d,0x26d8e1da),LL(0x8d0f7757,0xcf136199),LL(0x3f8e894d,0x31244780),LL(0xe1a3d47d,0x8d2a20ba), + LL(0xc795a2c7,0xc68b641e),LL(0x5a4d6647,0x4fe559b1),LL(0xd89ce668,0xeda98cba),LL(0x6c269d8e,0x15f84dc0),LL(0xcbf34023,0xf0eb685e),LL(0xc032634a,0x3668c530), LL(0xe4531f59,0x2e3d7fff),LL(0x85494d06,0xe6270306),LL(0xa3e050df,0xf02cabcf),LL(0xc001dcd9,0xccd2da67),LL(0x066d2d52,0x50aa3723),LL(0x7224a41f,0xdb075650), + LL(0x43c1e526,0xeaf0b05d),LL(0x5c673e17,0x7eddb25a),LL(0xc1f9bda7,0xfce700de),LL(0x646a1550,0x4e6f4c70),LL(0x8ba60c35,0xae06c3e5),LL(0xc0c89c50,0x1a57101f), LL(0x60a36192,0xdb35b1f3),LL(0x265c3ed1,0xf740a467),LL(0x6175e771,0xeab65a88),LL(0xcbe28ed4,0xd94c8cc6),LL(0x465dd7a8,0xac347e7b),LL(0xca9b899d,0xca927337), + LL(0xdd045c9e,0x3499422e),LL(0x727f1f25,0x5119c675),LL(0xd76e7077,0xf44a89ae),LL(0x8eb17f39,0x9d6967b5),LL(0x2bbed398,0x49b39b81),LL(0x07deb5e9,0x05b3a455), LL(0x62039ba0,0x8fa1ebf3),LL(0x0b650544,0x52c3d14b),LL(0x37d3fd20,0x2603aaf7),LL(0xec70bfc0,0xb6fe1148),LL(0xfeb74df8,0xe68b8475),LL(0xe1f4aba2,0x56fafdcb), + LL(0xa05b2adf,0xd061bce6),LL(0x8b7cf4c6,0xdb6e9324),LL(0x189f7ce1,0x6344c3b6),LL(0x3cfe678d,0x06993dc9),LL(0xb6e22f1b,0xb00b5227),LL(0x780137c1,0x8f836e4c), LL(0x1e9ad145,0xaf822953),LL(0xdfaaa159,0xb438997c),LL(0x904396e6,0x03e27459),LL(0xc8259d86,0xd06a0fdb),LL(0xe040907b,0x8afe766b),LL(0x038fbdba,0x0f5ff265), + LL(0xe1aa5953,0x4b1f8698),LL(0xbf0a531c,0x94af5c0c),LL(0x6536e156,0xba1c49f5),LL(0x09c95a75,0x31c31631),LL(0x0a6d9af1,0x268a308f),LL(0xfa9ca8b7,0x185b9762), LL(0x65035840,0xc3b1cbcd),LL(0xb429c82a,0x17b276c6),LL(0x34396850,0x1b4ec7b3),LL(0x048a6943,0x42f21d5a),LL(0x5b5820bf,0x0bf948f5),LL(0xb48dca58,0xac944487), + LL(0xac575242,0xefa91b2e),LL(0xcdaca77a,0x58280b99),LL(0xcf39d117,0x5c3f8382),LL(0x70e5d17c,0x4d460dba),LL(0x12f6d6ad,0x440b4db8),LL(0x7f3a6bb8,0x14b9b335), LL(0x837833cf,0xfbb3746a),LL(0xda482df0,0xbbf4735b),LL(0x9fbf146f,0x4efe32c0),LL(0x346e3b9e,0x65e5d7c2),LL(0x434ce5d5,0x742e81ce),LL(0x3bb80bd5,0x87e2b772), + LL(0xe02f8540,0x18d0983b),LL(0xe8058c66,0x708654c7),LL(0x92894720,0x0b137f68),LL(0x4345444d,0x0b8b62e9),LL(0xbfd043d0,0x426807d3),LL(0x2a1ac390,0x17ac2e64), LL(0xf2076839,0xd037e79c),LL(0x3ba4d3f2,0x991d4ff0),LL(0xd3724bfa,0x3937247e),LL(0x218413d1,0xb5b50d34),LL(0x28157b81,0x2accc172),LL(0xc472e8b2,0xd07f18b7), + LL(0xca12be15,0x0df64ab2),LL(0xc2f0d0f9,0xdbac68f8),LL(0xa2107d3e,0x5772ba8b),LL(0x76724cfe,0x32c43ac9),LL(0x166229b7,0x6f4a367e),LL(0x230b3527,0x9c8bdb42), LL(0xe71f261d,0x343d644d),LL(0x26283547,0x45c849bf),LL(0xd8e4c7b0,0x3a42b9b8),LL(0x9f8af5c7,0x0aff84ad),LL(0x418cfee8,0x453c3a30),LL(0xa241633a,0x6be57cdb), + LL(0x65b55050,0x04418b59),LL(0xd324aa67,0xa8a797c3),LL(0x7c65a6d9,0x5f87e22c),LL(0x1dbeffe4,0xaac71065),LL(0xbd3cc05c,0xff619d64),LL(0xe65c92c4,0x9a29c966), LL(0xdad7fcbd,0x23af2b21),LL(0x153b817f,0x4950a767),LL(0xc6478c55,0xc34a7efa),LL(0xf6cd140e,0x57cde95a),LL(0xf5a0db2e,0x64b74575),LL(0x75d7fb76,0xd4b5ea52), +}, +/* digit=59 base_pwr=2^295 */ +{ + LL(0x8e72aafb,0x28405062),LL(0x8ea8bf00,0x655bf353),LL(0x05547f7b,0x789d9444),LL(0x3441e472,0x7fa445ed),LL(0x4a44ce87,0xfeb19825),LL(0x129aed14,0xccb5f12c), LL(0xaf94fb34,0x22b05de3),LL(0xd3f03199,0x7422a040),LL(0xa83f7f08,0xfba252ca),LL(0xcefaa757,0x0f6ad6e6),LL(0x6517d806,0xe1ad1871),LL(0x8e9d97ad,0xd16dc8ed), + LL(0xa3736eb6,0xcbb99194),LL(0x36dcf470,0xdd5161cd),LL(0xb6ab6c03,0xd50b24aa),LL(0xbc41f4b7,0x419d2810),LL(0x295496cf,0xe2e88d7a),LL(0xf2457ac0,0x350713f2), LL(0x0427e2ae,0x838e4a36),LL(0x4d974e5a,0x7631472a),LL(0x7a5c5fdc,0x9fa3ab1c),LL(0xde34cb8d,0x324798cd),LL(0x889105fe,0xbfa5a9d0),LL(0xfd0df249,0xd05dad34), + LL(0xcb419fc3,0x536e5657),LL(0x1d271dd1,0xe8c208bc),LL(0x22d2b9ad,0x6a3713bd),LL(0x471d808d,0xa4c761a7),LL(0x7e6dca35,0xd93aafb6),LL(0x8f55ca32,0xc46c0ae3), LL(0xa78bfca0,0x55dc0de7),LL(0x3407d0ca,0xe9cfb301),LL(0xb3256c14,0x777e2a60),LL(0x6d8fee02,0x32b2238c),LL(0x46e43ee8,0xe8b35396),LL(0x247985dd,0x310bc1ba), + LL(0x581f9d3c,0x9974759c),LL(0xe5cb1973,0x9e76a970),LL(0xc64941ca,0x8afec58e),LL(0x01d05575,0x2d7c57fa),LL(0x5c448db5,0xc07c74cc),LL(0x01bb1440,0xa52474ce), LL(0x00115bbb,0x93162d97),LL(0xfd7480f9,0x483b6147),LL(0x6af18ded,0x4f28c57e),LL(0x174a3089,0x36faed8f),LL(0xa3dd6265,0x702dbd64),LL(0x6adc0d7b,0x86a9c43f), + LL(0xb9de7b63,0xa3510710),LL(0x4019c9df,0x9f364ad1),LL(0x9b5bdce3,0x5b66a5d7),LL(0x78b1b385,0x2b2f6951),LL(0x3cfa9f99,0x3e4783d3),LL(0x6bd6bcf4,0x1af51750), LL(0x81d8d7ef,0xf9c0686a),LL(0x37c068d3,0xdc0f22ec),LL(0x93545faf,0xe1b86653),LL(0xa8a52881,0x37ca8501),LL(0x5603e359,0x07ac5c8a),LL(0x542cc937,0x98fb2bab), + LL(0x0c5bbd3e,0x4981be69),LL(0x185fdb55,0xb047df0a),LL(0x74cff00c,0x3168e050),LL(0xb52c7f9c,0x111150a1),LL(0xa51c7986,0x0db2ed84),LL(0xe61272ad,0x7d991630), LL(0x28de14dd,0x7443d936),LL(0xa5daed5f,0xfdf31f41),LL(0x866b5e40,0x71e0ef4e),LL(0xb965a670,0x05c57a45),LL(0x70e1aa77,0x85bdb58c),LL(0x9df3ce32,0xe4d1fe2a), + LL(0x2f722563,0x5d461898),LL(0x567db14c,0x11d22b39),LL(0x6779cd40,0x9a8f004e),LL(0x5473ecd5,0x0812ae3d),LL(0x4e6c296a,0x4ed82862),LL(0x064ee61f,0x2d9ce40c), LL(0xd8a9eb1e,0x4856d586),LL(0x5d1b5e3a,0x2ddd6b12),LL(0x382fba3c,0x0ab5eec0),LL(0xfcf4a9c8,0x302018df),LL(0xab3cdedb,0x7b4e6fd2),LL(0x8f64cb1d,0x266c246a), + LL(0xf5c3af59,0xc41e4aed),LL(0x6de9a78a,0xa0284ad0),LL(0x8ed812d2,0xf5eaab7b),LL(0x1afb58b8,0x7801fbb8),LL(0x71efcc3a,0xbe5cdba6),LL(0xcd10cb91,0xe31a0e3c), LL(0x85dc0bc6,0x882e821e),LL(0xbb32e506,0xd3ad070f),LL(0xd8a0f038,0x3afede2b),LL(0x857fd3a0,0xe20a117c),LL(0x3060f767,0xebaa2aa4),LL(0x2b9d1da1,0x6524aa0d), + LL(0x88cffe33,0x9cc5847c),LL(0x6e8eb6c1,0xff726b0f),LL(0x1bc45d8e,0x9bb2ca16),LL(0xa6d8a5a6,0xe7903009),LL(0x47db2201,0x4f089cc0),LL(0xe6b5928a,0x4135884d), LL(0xe5c017cf,0xb1a86a0a),LL(0xb0a393df,0xb1d9bf6d),LL(0x28bb3277,0x33d9c1c6),LL(0x45b582ce,0xcb05b67b),LL(0xf33792c5,0xa72585fc),LL(0xa7d1ed84,0x78b7c5e8), + LL(0x9346df25,0x70e478fb),LL(0xb4a4ada5,0x01dc0c2e),LL(0x5be36ea7,0xaec82b00),LL(0x6717e06a,0x82618b8f),LL(0x008f1977,0x2db1f6d4),LL(0x16b390d1,0x4e493f3b), LL(0x990a75eb,0xfe86fd4d),LL(0x783f6076,0xa1cf7f99),LL(0x0c049158,0x6cbb23e7),LL(0xed456235,0xd05be7e5),LL(0x9bd836ef,0x60137406),LL(0x32e5f604,0x94ec9644), + LL(0x3d87bfa8,0x3361e1ce),LL(0x8dcca4f0,0x92f235e7),LL(0xbe323fd1,0xc8084cb4),LL(0xc24c6d16,0x3fd481a5),LL(0x2cea81ba,0x9b1bd940),LL(0x0c5aa59f,0xf5091191), LL(0xf81d5e2a,0x4cd8c9ef),LL(0x1550bff4,0x5ad00013),LL(0x8cc32e55,0x29d47b9f),LL(0x11694ece,0x66e3e6f1),LL(0x7950dd7e,0xd5edf701),LL(0x0f6350c6,0x9ccb1096), + LL(0x18f2470c,0x09db138d),LL(0xf613658f,0x63bd2290),LL(0x4feebab9,0x0bb64779),LL(0x7fdb1e71,0xfce4aee1),LL(0xa7f1f65d,0x7d5c0c61),LL(0x8d02d6cd,0x46405b61), LL(0x6fdcb0d0,0x7cac0485),LL(0x2f8ec5af,0x85224c4b),LL(0xdb0aa864,0xb5879a59),LL(0xff94f8b5,0x75f391b8),LL(0x49c97f8e,0xa6c994ae),LL(0xd690b232,0x4d968fad), + LL(0x67e0b4e7,0xf5cd290a),LL(0x7c1594b6,0xaa6fa680),LL(0xb63270be,0xebedfbd7),LL(0xa369bfee,0x574b410b),LL(0x020ea888,0x431cba5a),LL(0x56c71d47,0xd3a3102f), LL(0xa90a853a,0x4894bfe0),LL(0x5f9c4b6b,0xd78bd98b),LL(0xd900c5c1,0x9b1324f6),LL(0x718c2147,0xc65c944d),LL(0xa987f634,0xf661de6b),LL(0x172628d8,0x0315e69f), + LL(0x22ea5f1c,0x07c60c75),LL(0xa36bee4f,0x35beae34),LL(0xdcba8997,0xa8b00a09),LL(0x802ce50c,0xa77f1f3a),LL(0x2a2144b0,0x6c4050df),LL(0xab1b10db,0xf79bfa96), LL(0x433a9b1c,0x9025d470),LL(0x90d9eec8,0xaf3e3917),LL(0x9ae2d535,0xbcad2d62),LL(0xeff0f6a9,0x7a152829),LL(0x925fa5a0,0xe87345cd),LL(0x0e84039c,0x6ce00720), + LL(0x07f6a05a,0xdae449c0),LL(0x5bf26c9e,0xbc1b84f5),LL(0xb1c13820,0xe3b3f9ed),LL(0x4090598b,0x5442ad5b),LL(0x13749e4d,0x794ef656),LL(0x948b71c5,0xde809180), LL(0xe203c5b5,0x4c72dc7d),LL(0x1b349fc4,0x8902b097),LL(0x225a1569,0xa899bedb),LL(0xe6ff3f53,0xeb7da73d),LL(0x7c0be37b,0x6ee8e160),LL(0xa31bf943,0x9ee667d2), + LL(0xdb81146d,0x5017e145),LL(0x45c54db8,0xc7d2086d),LL(0xfa98234a,0x2541059d),LL(0x9985af98,0x4bf344d9),LL(0x7b5b7b1c,0x39737ed6),LL(0x87c411ad,0x8e246919), LL(0xb877a75f,0x2fad8ced),LL(0x17e60ee2,0xe42352df),LL(0x404043f7,0x1a53d856),LL(0x863927a1,0x6c1f07a5),LL(0xb6892121,0x38d3a4f4),LL(0x01976c8f,0xf4c10920), +}, +/* digit=60 base_pwr=2^300 */ +{ + LL(0xc2ec3731,0xbcc88422),LL(0x10dc4ec2,0x78a3e4d4),LL(0x2571d6b1,0x745da1ef),LL(0x739a956e,0xf01c2921),LL(0xe4bffc16,0xeffd8065),LL(0xf36fe72c,0x6efe62a1), LL(0x0f4629a4,0xf49e90d2),LL(0x8ce646f4,0xadd1dcc7),LL(0xb7240d91,0xcb78b583),LL(0x03f8387f,0x2e1a7c3c),LL(0x3200f2d9,0x16566c22),LL(0xaaf80a84,0x2361b14b), + LL(0x246dc690,0x7a1a522b),LL(0x4b61ab70,0xb563cbe1),LL(0x3d4ac4ab,0x41bb4abe),LL(0x37f996e8,0xc52950b3),LL(0x79727761,0x01d991e6),LL(0x978fd7d2,0x35de93bd), LL(0x5706d336,0x86bad5e6),LL(0xe7f26c20,0x10844155),LL(0x05757453,0x58ffeb77),LL(0x3939df77,0xbb186129),LL(0x6a78ea0f,0xbfdd394a),LL(0x6e33e1d3,0x907ff054), + LL(0xb5733309,0xdb1cffd2),LL(0x0f9dd939,0x24bc250b),LL(0xa3c1db85,0xa4181e5a),LL(0xac55d391,0xe5183e51),LL(0xefd270d0,0x2793d5ef),LL(0xc0631546,0x7d56f63d), LL(0x0c1ee59d,0xecb40a59),LL(0xbb5bfa2c,0xe613a9e4),LL(0x6c5830f9,0xa89b14ab),LL(0xa03f201e,0x4dc477dc),LL(0xc88c54f6,0x5604f5da),LL(0x2acfc66e,0xd49264dc), + LL(0x0df93b34,0xa7f29532),LL(0x5c14df30,0x855934f2),LL(0xefae348c,0xd2f54ce9),LL(0xac52758d,0x5acb931c),LL(0xd22961a4,0x287b3e18),LL(0x748f8fe1,0x42a5516d), LL(0x877224ca,0x1b62b341),LL(0xd30a4aa7,0xaff58db3),LL(0xbe8da847,0xbad78dad),LL(0x54f18276,0x85fa7109),LL(0x7c4bfdad,0xe2cc9d28),LL(0x2c75f237,0xbb131f76), + LL(0x1c4dfa95,0x283dd7f0),LL(0x62c0b160,0xb898cc2c),LL(0x870282aa,0xba08c095),LL(0xf4e36324,0xb02b00d8),LL(0x604cecf2,0x53aaddc0),LL(0x84ddd24e,0xf1f927d3), LL(0xe2abc9e1,0x34bc00a0),LL(0x60289f88,0x2da1227d),LL(0xcef68f74,0x5228eaaa),LL(0x3c029351,0x40a790d2),LL(0x8442e3b7,0xe0e9af5c),LL(0xa9f141e0,0xa3214142), + LL(0x03844670,0xcdcdd7d7),LL(0xb4a23f91,0x79ec59af),LL(0xc00ce5c3,0x5923c569),LL(0xc589d0c7,0x099c17ff),LL(0x89fa6fe6,0x0335eeea),LL(0xa4e868c4,0x916bcaca), LL(0xfb687bd5,0xb7037325),LL(0x9853b564,0x57d6bca7),LL(0xd5e26d28,0xdf3132ef),LL(0xde919cbe,0x7ed994b8),LL(0x6fbbb18d,0x12df67cd),LL(0x6baff508,0x516e07c0), + LL(0xf9a58e3d,0x72f4949e),LL(0xa48660a6,0x738c700b),LL(0x092a5805,0x71b04726),LL(0x0f5cdb72,0xad5c3c11),LL(0x554bfc49,0xd4951f9e),LL(0x6131ebe7,0xee594ee5), LL(0x3c1af0a9,0x37da59f3),LL(0xcb040a63,0xd7afc73b),LL(0x4d89fa65,0xd020962a),LL(0x71d824f5,0x2610c61e),LL(0x3c050e31,0x9c917da7),LL(0xe6e7ebfb,0x3840f92f), + LL(0x97e833e4,0xf2ec9ef5),LL(0x34ec7e41,0x97bdef97),LL(0x7d2ac6e3,0x90e2b238),LL(0x0318a3b7,0xcf682b12),LL(0xea84a7a0,0x7fe76089),LL(0x16546d05,0x85c489f9), LL(0x6abdda05,0xf987118f),LL(0xaa4b95fc,0x675cf998),LL(0x888a7e8c,0x544c7774),LL(0x63ec5831,0xbd2647ba),LL(0xfd2fe985,0xb479cea3),LL(0x28d163e8,0xa0421345), + LL(0x8d8b8ced,0x50fbd7fe),LL(0x47d240ae,0xc7282f75),LL(0x1930ff73,0x79646a47),LL(0x2f7f5a77,0x2e0bac4e),LL(0x26127e0b,0x0ee44fa5),LL(0x82bc2aa7,0x678881b7), LL(0x67f5f497,0xb9e5d384),LL(0xa9b7106b,0x8f94a7d4),LL(0x9d329f68,0xbf7e0b07),LL(0x45d192fb,0x169b93ea),LL(0x20dbe8c0,0xccaa9467),LL(0x938f9574,0xd4513a50), + LL(0xe5947c6f,0xd93506a4),LL(0x39b81d08,0x4340d76a),LL(0x17930d30,0x741aee59),LL(0x18fdb81c,0xfea3d99a),LL(0x289bcb07,0x1088ff6b),LL(0xb7c082c6,0xc6b45602), LL(0x453d8d69,0x50e2baab),LL(0xe893e183,0xda9bf561),LL(0xb29a284d,0x0af25f86),LL(0x73e01380,0x0e92e674),LL(0x2be00e59,0xe173a0e3),LL(0xada8954a,0x402d2f3d), + LL(0x054cb874,0x841c96b4),LL(0xa3c26834,0xd75b1af1),LL(0xee6575f0,0x7237169d),LL(0x0322aadc,0xd71fc7e5),LL(0x949e3a8e,0xd7a23f1e),LL(0xdd31d8c7,0x77e2d102), LL(0xd10f5a1f,0x5ad69d09),LL(0xb99d9a0b,0x526c9cb4),LL(0x972b237d,0x521bb10b),LL(0xa326f342,0x1e4cd42f),LL(0xf0f126ca,0x5bb6db27),LL(0xa4a515ad,0x587af22c), + LL(0x0399721d,0xca9cb389),LL(0xa3291479,0x03ad9f4a),LL(0x6dee003d,0xd85b5df5),LL(0x64a4f83a,0xe1fa7b02),LL(0xb73f7324,0x01c4cbfd),LL(0x5cf2ddf4,0x707010d4), LL(0xb12e02f8,0x3c6df430),LL(0x85531489,0x921a2901),LL(0x91d1022c,0x302fc77c),LL(0x342d8f3f,0xc3733ec0),LL(0x6195a665,0xb83bc75f),LL(0xa79f8027,0x4a14b9e7), + LL(0xb12e542f,0x1123a531),LL(0xb9eb2811,0x1d01a64d),LL(0xf2d70f87,0xa4a3515b),LL(0xb4bd0270,0xfa205234),LL(0x5eda26b9,0x74b81830),LL(0x56578e75,0x9305d6e6), LL(0x9f11be19,0xf38e69de),LL(0x44dbe89f,0x1e2a5c23),LL(0xfd286654,0x1077e7bc),LL(0x0fca4741,0xd3669894),LL(0x278f8497,0x893bf904),LL(0xeb3e14f4,0xd6ac5f83), + LL(0xe2a57359,0x9f0e5428),LL(0x14998c16,0xc690a3c7),LL(0xde37e07e,0xd73c3ca2),LL(0xdba0bc0d,0x2ddf91b8),LL(0x7570ae71,0x69d834b2),LL(0x735195a6,0x2ac8bed4), LL(0x3b1fcc5c,0xcd8c51ff),LL(0x1ba6863f,0x7aa8cf4e),LL(0xae70f428,0xebb69e72),LL(0xaa9e936d,0xa29409df),LL(0x5a332b9b,0x43f6ee80),LL(0xc2eab0a9,0x0de49efa), + LL(0x488f5f74,0x327b9dab),LL(0xcab7364f,0x2b44f4b8),LL(0x19b6c6bd,0xb4a6d22d),LL(0xfc77cd3e,0xa087e613),LL(0xb0b49bc7,0x4558e327),LL(0xcd835d35,0x188805be), LL(0xc1dc1007,0x592f293c),LL(0x6af02b44,0xfaee660f),LL(0x904035f2,0x5bfbb3bf),LL(0x79c07e70,0xd7c9ae60),LL(0x234896c2,0xc5287dd4),LL(0xcb0e4121,0xc4ce4523), + LL(0x2310333e,0x04baa176),LL(0x7b9bad46,0xdc75e35f),LL(0xc6cd6108,0xc4a6031d),LL(0x30bf87a5,0xba2534d0),LL(0x31e497cc,0x7ebc6e21),LL(0x851fd665,0x8a2a82b4), LL(0x6d5faf40,0x9ecae011),LL(0x96956ecb,0xfa3a6d7f),LL(0x2fa52782,0x39e8a9c2),LL(0x236d442e,0x74c93801),LL(0xb1c289ce,0x8b21ba23),LL(0x25c769cf,0x7f3e221b), +}, +/* digit=61 base_pwr=2^305 */ +{ + LL(0xca114c4a,0x761e10e2),LL(0x894301b3,0xe39d121d),LL(0x3dbc6fca,0xa0870ff4),LL(0xcbe0ba8a,0x97651286),LL(0xc0f1ff6a,0x47d46075),LL(0x3abeb5b6,0x18669c84), LL(0xad8d9309,0x1234c80e),LL(0x1f6f97ff,0x1ccbe4d5),LL(0xd82ab780,0x399a2d41),LL(0xde426e50,0x8a03afaf),LL(0xca6dde77,0xa2bcb109),LL(0x0618f5ec,0x840e13b0), + LL(0xec645a62,0x15d47e52),LL(0x8d6d4423,0xabe0ddb3),LL(0x70cddb11,0x51226a30),LL(0x2b5a8db7,0x63a253d3),LL(0xbef37d65,0xe8be4d1f),LL(0xc0920b91,0x41e625d9), LL(0xd9d040ec,0x08b713a8),LL(0xc450cdba,0x467fb08d),LL(0x917ee393,0xa8975877),LL(0x1528cd12,0x294792e9),LL(0x37daf6aa,0x4512dc8c),LL(0x197a99b9,0xa83becc9), + LL(0x538d92d8,0x3b21dc1f),LL(0xc005aa86,0xc80b22b3),LL(0x0da87d65,0xf536e5d3),LL(0x0cd999a0,0x4ce10edf),LL(0x50e08f5d,0x89491814),LL(0x526647e6,0x77fd8f2e), LL(0x250099fd,0xcb207ee9),LL(0xfd6aa078,0x03c7d1ab),LL(0x25e0cf15,0x7d4940d2),LL(0x067fa052,0xb688b311),LL(0xa98b2e21,0x89308326),LL(0x72311eab,0x3ee4cc2b), + LL(0x68d7dfcf,0x37be5d3f),LL(0xb945e6f2,0x97bdbd49),LL(0x9d1569e7,0x165a24b5),LL(0xb4e293ab,0x254aaf59),LL(0x6fb7c0a4,0x3c751fbd),LL(0x5018cb18,0x14eda4ba), LL(0x1b5f6aed,0xacb3b897),LL(0x1e4b6b78,0x6d10be44),LL(0x621df6d7,0x245d7258),LL(0x185f0e2a,0x2af0e283),LL(0x8fddbd81,0x1e7edc81),LL(0xc538d02a,0xbd1e6c72), + LL(0xaa006a4f,0x12014812),LL(0x83374604,0xf84aa1a2),LL(0x0ee4a8ae,0x9f8475d9),LL(0x135811df,0x37a1b21d),LL(0x1166af52,0x34143171),LL(0xf5a33016,0x204dd449), LL(0x372b6edd,0xc838d3d5),LL(0x3987611c,0x314f3053),LL(0xd112605c,0x819adbe0),LL(0xf6b32c5c,0x45da01ae),LL(0x7e3b13a9,0x3deb3018),LL(0x79058926,0x0e78a3a2), + LL(0x42adface,0xaab5f0c7),LL(0xcb580132,0x50d9f53f),LL(0xb5fd6ebf,0x68a3c689),LL(0x9cde184a,0xdea2f2ee),LL(0x13a98466,0x8c174c44),LL(0xcb4d921b,0x8c4e2ae1), LL(0x2d4c6d5a,0xba973c6c),LL(0x61d2ec5f,0xc6150714),LL(0x666d8bf9,0x2aba1375),LL(0xd41272cd,0x2fa2768f),LL(0xa0bc34bf,0x49f3b8d7),LL(0xca45e5fc,0x61118166), + LL(0x2665ae2e,0x92f565ea),LL(0x1aefd472,0xaaa91acf),LL(0xfbb062aa,0x3878c718),LL(0x7de3c64d,0xde46e7d8),LL(0xbd506a76,0xff9900a4),LL(0x3daa73b9,0x4e30ed72), LL(0x7cbaff42,0xd6be9446),LL(0x5dd691f4,0x26fe6305),LL(0x6d393800,0x64ef093c),LL(0x7bb8f155,0x2448c67a),LL(0xe5d732d7,0x9da6e75f),LL(0x50b080e0,0xe837a602), + LL(0x844626a2,0x6858b674),LL(0x0cbba6a6,0x610cd40f),LL(0x29d9194d,0x324e674e),LL(0xdcb30a51,0x2dc6fdf6),LL(0x528aa549,0x3f3ecb77),LL(0x23ffaa92,0x0721f8f9), LL(0x27a77538,0xd8efcbd6),LL(0xd6162c9c,0xf4e642bf),LL(0x4cf4a16f,0x04f2b0b7),LL(0xbbf335fd,0xbc0bb49f),LL(0x5a928c36,0xc6b6e5bd),LL(0xd893dd45,0x981b01f4), + LL(0x518f01dc,0x2836b977),LL(0xa06c7362,0x117e833e),LL(0x31152b22,0xcda89f2c),LL(0x34be0102,0x2084c5c4),LL(0x2bfac8c2,0x6478de75),LL(0xebda5ede,0x9f7e901a), LL(0x5aa25b6f,0x5f43adfc),LL(0xcdd0eee3,0xfb719dca),LL(0xf9b16d84,0x14431b2d),LL(0x97f04b2b,0x846261af),LL(0x1edd7d4d,0xcc6100b8),LL(0x87cde5f4,0x6197c87f), + LL(0xa01cb6d9,0x4a9e6281),LL(0x87065307,0x699c0719),LL(0xdffa58be,0xa8ca4971),LL(0x89efaadd,0x8adc304f),LL(0x1f3c79d2,0xeef0af15),LL(0x581587e8,0xb3be9c6c), LL(0xda0be326,0x79010ad2),LL(0x4be00f8b,0x4f361e1e),LL(0xc53f3c74,0x180e66ba),LL(0xb2521c2d,0xa668c3f3),LL(0xabb73a09,0x60bc2fa6),LL(0x4392692f,0x0bda0ff6), + LL(0x9aa349d0,0x2e88f308),LL(0xa7cf751f,0x9f19df26),LL(0x4885be75,0x1e0229c7),LL(0xa32fce2e,0x6770eee2),LL(0x562d99d7,0x448366e4),LL(0x8bc7484a,0x7670bd68), LL(0x92d83c6b,0x15374837),LL(0x14f7c403,0xe0f499f8),LL(0x8a6b78f6,0x4cf02671),LL(0x9849e689,0x75f6e30a),LL(0xcad5065a,0xaf6fe2a5),LL(0x43ba98aa,0x6378401b), + LL(0xd2446552,0x26d6d225),LL(0xd2600e42,0x9b74929e),LL(0x447126d2,0xcef3a052),LL(0x4d1c7e0a,0xcba2f70c),LL(0x020d33a3,0x0250a96f),LL(0xa5e587d9,0x9c946f94), LL(0x86653ae6,0xc7d4343f),LL(0x8884e9c6,0x9c832859),LL(0x1c234f88,0xa44fa8c5),LL(0x987f04dc,0x7193e6db),LL(0x6a25ff37,0x24efebac),LL(0x953b3db8,0xe23f0a14), + LL(0x491d9ba9,0xb13db9bb),LL(0x5556de42,0x7105da91),LL(0xbd48b3d9,0xafa75d3b),LL(0xed6c519c,0x10246797),LL(0x1aa866f5,0x83b27882),LL(0x54f64e96,0x66f4ceaa), LL(0x43c07b18,0xf4f03faf),LL(0xdd18ddec,0x97eed374),LL(0x6c454f23,0x43b702f1),LL(0x3cb61e31,0x3c53810c),LL(0xedcaea49,0x8a50cfe9),LL(0x89a6acd9,0xfb70772b), + LL(0xa01edb12,0xedc09655),LL(0x7ad80675,0xdaa9f823),LL(0xf6a1052d,0xb7f23b6c),LL(0x697dc18b,0x22dc809f),LL(0x6c8bcd69,0x0453593f),LL(0xc9b43cf0,0x80f76d8b), LL(0x8c5b3ba9,0x8e781e17),LL(0x66a0b318,0x66544c7c),LL(0x9d95b620,0xedd99cbd),LL(0xbdf0933e,0xc36c4334),LL(0x8b59acf3,0x3d550b68),LL(0x6ca6a2b7,0xcd7d1701), + LL(0xc3d5ad9a,0x94457602),LL(0x3a7a1abc,0xa1a9608e),LL(0x31a107cb,0x16eb2310),LL(0x987bf106,0x5d921026),LL(0xd2ccc296,0xec2e5789),LL(0xb8f2fbd4,0x87b86d1b), LL(0x6da88d7d,0x939b5802),LL(0xe19707e2,0x22fa6ef8),LL(0xc547ce83,0x8b95bd5d),LL(0xd16fb119,0x91268688),LL(0x6e3627f2,0xbf199148),LL(0xc31ab346,0xd072bdf2), + LL(0xf810465b,0xfb083c2a),LL(0x02ce0dee,0xb66a8de9),LL(0x47a81b95,0x6e4130e7),LL(0x58a98737,0xcd704dc6),LL(0x592829c9,0x842ae329),LL(0xbe20dd63,0x99bedc34), LL(0xd53b2df4,0xabee8e55),LL(0x6010b37c,0x6ce65758),LL(0x467112b9,0x781f39b2),LL(0xbe341038,0x6f06058f),LL(0x12a2f8be,0x5effdca5),LL(0xaf34466e,0xaa9bdad7), +}, +/* digit=62 base_pwr=2^310 */ +{ + LL(0x9c216137,0xab86639e),LL(0x82b18d64,0x45a12fb8),LL(0xd763f0bb,0xb5734418),LL(0x11a9802c,0xd2cc3322),LL(0x81269b8a,0xe41d7db8),LL(0x2ecfa355,0x91072fc1), LL(0x04ce306f,0x59d69125),LL(0xa131b86d,0x916d9d4d),LL(0x8a739738,0x84478b6b),LL(0x1cc83ae3,0xe86ad7d9),LL(0x797ccd97,0xbc9b2084),LL(0x694944c6,0xc1e94af4), + LL(0x895c0318,0x585edee3),LL(0x45e8205b,0x775e142f),LL(0xd85ad31f,0x3bd7924f),LL(0x9124bffa,0x2e7d8f91),LL(0x44c62868,0x885397c0),LL(0x7fda9f5d,0xc0c2dff4), LL(0xc14e693d,0xd302582e),LL(0x6cec31ba,0x53d6e33a),LL(0x63653c06,0xb0216b5b),LL(0x9c70dad4,0x8f08a1ad),LL(0xffbba93d,0xccf014aa),LL(0xa33f12b7,0x900b0d2c), + LL(0x9b8cfa41,0x0dd2395e),LL(0xd4f92a44,0x50e203ab),LL(0x6630023b,0x7280aff1),LL(0x07de820e,0xfcce59dc),LL(0xbc8189ad,0xa686be05),LL(0xaac70b7e,0xac4b59bf), LL(0x7a3c71ac,0xd2c0070e),LL(0x35ac1c47,0x1d550add),LL(0xfb881c1b,0xd42b6389),LL(0xd0dafd42,0x57ca3fcc),LL(0xbe26ccc9,0x909e8284),LL(0xa002235c,0x1abe7595), + LL(0xa6a1913d,0x1e34781a),LL(0x7d0adc38,0x9a8f3228),LL(0x28af85ba,0xfc185ccc),LL(0x3ae9ba11,0xc923d78b),LL(0xa7bdb313,0x7d494d7e),LL(0xaf8f8b87,0xf774dfa5), LL(0x16e863b8,0xc178ccc1),LL(0xa8899691,0x2d472f2a),LL(0x80a50372,0x608747cc),LL(0xe6f90197,0x8147aa90),LL(0x78c2f216,0x4683d4c9),LL(0x552f3b51,0x8323652c), + LL(0xcc2c9a2a,0xa5c08e8b),LL(0x8baaf0fc,0x70e1b405),LL(0x9e36e50c,0xf29e1e5c),LL(0x80f258c5,0xa3d90800),LL(0xecad4498,0xc9ceac25),LL(0xca32f3fe,0xcb73130f), LL(0x48b3863d,0x2dbe620c),LL(0x14ff53bf,0x8c52727f),LL(0x6b45e9b8,0xb60b22a8),LL(0xf6483c5d,0x81e05bc0),LL(0xcd542972,0x217caa6b),LL(0xfa780778,0xffab716a), + LL(0x0d7410d6,0xe5d3e0d8),LL(0x2be432c9,0xcfa9ed74),LL(0xa85a0686,0x60044434),LL(0x6ad6918a,0x93b35716),LL(0x051762be,0x1a3c3e6d),LL(0xb0ab32d6,0x80813589), LL(0xaad403fd,0x64214b92),LL(0x4d3fb746,0x684befc1),LL(0x79515046,0xaca5a514),LL(0x72e84485,0xacdba034),LL(0x287d9e97,0x61aa2834),LL(0xcad222e7,0x07a515a5), + LL(0x8af19670,0xb0309306),LL(0x34c6bf0f,0xd784125a),LL(0x255a8396,0x0b425ee0),LL(0xfb541162,0x91076433),LL(0x86f47a0e,0xc4d81885),LL(0xfd7bc7c1,0x3b767d54), LL(0xbee196e9,0x98b405d3),LL(0xedaccf4a,0x4ef9c511),LL(0x03f4f1a6,0x5a6deb65),LL(0x1b4c5104,0x4a22ca64),LL(0x9145ce41,0x2cce3667),LL(0x3206810d,0xd0518752), + LL(0x037bebad,0x29d81538),LL(0xd9e0b78c,0x76e52c73),LL(0x8783d1fd,0xaa4ace6e),LL(0xf0e3c126,0x9c14ebdd),LL(0x6eca4b71,0x0eb1c08d),LL(0x1c91df35,0xd10c6b96), LL(0xe81bb84a,0xdb8119bb),LL(0x17e3ceef,0xf784d3c1),LL(0x35436f81,0x053c9168),LL(0x9b18d212,0xeb41ccbb),LL(0xb1bc3497,0x93b3fb43),LL(0x8c1ced81,0xd85a7c75), + LL(0x811af84a,0x004105c3),LL(0xa7934a0f,0x01307934),LL(0x9b3226a1,0x179fd49b),LL(0xde6834b4,0x195d9e5c),LL(0x0e6051bd,0xfbb79dc0),LL(0x367f4487,0x354273ed), LL(0x74fb892d,0x4afa9d45),LL(0xa1b7f3bb,0x03ae905e),LL(0x592f6122,0xea32cd5d),LL(0xf1103301,0xa758eed2),LL(0xc59d1cc8,0x9dde4238),LL(0x51022a42,0xe2760bcc), + LL(0xd377d7b0,0x54f84d70),LL(0x3344bc4e,0xb745d190),LL(0x8f33aa53,0x1c693ed0),LL(0x8bfbee7f,0x990ed45f),LL(0xe9b258fb,0xad620c9f),LL(0x1a54bf46,0x465ccb10), LL(0xebc40951,0x5330a0d3),LL(0xa405da61,0x34423e8c),LL(0xb83043b6,0xeef1ce78),LL(0xac06d182,0x99678f22),LL(0x1802f14c,0x9213f57d),LL(0xadf11fda,0xf8549616), + LL(0xb6e392e1,0xf31796d2),LL(0x93b3395e,0x199d6248),LL(0x12f9b763,0xef14c7c2),LL(0x43edb7a5,0x721ebf21),LL(0x5e96f3ba,0xa40b8894),LL(0x4cff8394,0x8770608c), LL(0x8d0def0e,0x990c99ae),LL(0xa15a5649,0x292b26df),LL(0x91ca89d7,0xa98fda2c),LL(0x973e5f5f,0x916cb1b4),LL(0xa72de0bb,0xa2823f13),LL(0x8cd3219d,0x415f7bd2), + LL(0x3ed03d5f,0x521f4af7),LL(0xeaf9064c,0xe3461f66),LL(0xae03777f,0xad099ab7),LL(0xb65f73ff,0x541cadcd),LL(0xa86059b9,0x53430463),LL(0x043e9f82,0x8ff88fe5), LL(0xe42cde45,0xd515f4c7),LL(0xf41c3269,0xf7f3dec3),LL(0x7ef1b8ff,0x7bed5356),LL(0x1295b5fe,0x8782b45f),LL(0x03917627,0xab54ebaa),LL(0x8787ed9f,0x8516beb2), + LL(0x65b68624,0xba7df5a9),LL(0x6e7d58bb,0x30b4d6ed),LL(0xdbb81762,0x67e52341),LL(0x0deeac1d,0xd697ab1b),LL(0x5577ea92,0x01d15e8e),LL(0x98fb38da,0xbb12d724), LL(0x4e04908d,0x302faa6d),LL(0x09b90a9c,0x66cf6cb9),LL(0x98d96736,0xcd665dbd),LL(0xb86f3af4,0xf7d3c528),LL(0x1d8b07f4,0x4844c754),LL(0x1eaf7dc0,0x2a77d7b9), + LL(0x1d70eb73,0x53e59f25),LL(0xe69d0525,0x8aed17af),LL(0x64413768,0x26ddc178),LL(0x5e48c349,0xa7c8d40f),LL(0x87ff01fb,0x29ad92d1),LL(0x965b2de1,0x8f4e1b3b), LL(0x1446eca2,0xb83cfadf),LL(0xe609d416,0x7432bda4),LL(0xf1c7de69,0xcf97e8a3),LL(0x32f55f07,0x45899bd8),LL(0x51175738,0x41a68117),LL(0xb8efff21,0x89eeb115), + LL(0x936c3eba,0x54a01e60),LL(0xec01b12c,0xf326fe96),LL(0x66e4de2e,0xcdfaf003),LL(0x392fd0a8,0xc53dba07),LL(0x6ec46004,0x00d9b80f),LL(0x3ba63f8d,0x84d59be8), LL(0x9dea6062,0xbac4ea43),LL(0xadd568ca,0xb4b4845b),LL(0xd225e2d0,0xa6ca3d34),LL(0xb50070a2,0xce72955d),LL(0x21c78b68,0x56e5c913),LL(0x999488a3,0x888eb198), + LL(0x11c92f34,0x5255508c),LL(0xa294d382,0x9a346cf3),LL(0x3095205b,0xd9765eea),LL(0x2c470ef7,0xfea2ed70),LL(0x9c40bf0a,0xf5e8a0fc),LL(0xe4137a16,0xb572390e), LL(0x2bf2f545,0xb9175371),LL(0x58cd9cc7,0x2c2d0f4c),LL(0x02385486,0xbea6bce9),LL(0xa8bc3a94,0x46208408),LL(0x3ac45044,0x64a87a2a),LL(0x7df70151,0xe40da33c), +}, +/* digit=63 base_pwr=2^315 */ +{ + LL(0x39161b8a,0xee9e25d9),LL(0xe2eead91,0x8763f2a2),LL(0xd2d91300,0xd2fc1157),LL(0xffcbe50f,0xe7597e2f),LL(0xe11d376e,0x4be3814f),LL(0xdbf14562,0x1eab3d7e), LL(0xc0ad183a,0x38a107c0),LL(0x7c753bbf,0x82976626),LL(0xcaebd481,0x18014e09),LL(0xf9ace60d,0xb28c331b),LL(0x211cb8e7,0xe8fba04f),LL(0xe42dc65e,0x41c4b797), + LL(0xc3e88580,0x009dc2f4),LL(0x99db1fb5,0x4a405be8),LL(0xec5d91fe,0xc89bfaa2),LL(0xf160afcb,0x461be9a0),LL(0x7d7566b5,0xfdd084bb),LL(0xe48099a2,0x795275e8), LL(0xfe9815db,0x1b461fc9),LL(0x73627bbc,0x576214cd),LL(0x9f09a206,0x3246332d),LL(0x6941d6ef,0xbde4c0c3),LL(0xf387f5f6,0x44ef03fd),LL(0x57b63400,0x99c8ac01), + LL(0x2f6e4301,0xaa512f20),LL(0xbf94a1cc,0xef668a5f),LL(0x15861b88,0x08713c30),LL(0xc99bb2b6,0x49d47551),LL(0xe2f0258e,0x6db5f812),LL(0x998d7435,0x70c9b299), LL(0x5d176ae0,0x46168e1c),LL(0xf730ec30,0xec3306e4),LL(0xab69c15d,0x49439df3),LL(0xea0143e4,0x1040408b),LL(0xbc549b0a,0xb48ab8ea),LL(0x10f89223,0x4aa38bbf), + LL(0x9598f49a,0x7e485159),LL(0x9629305b,0xbdac3d5e),LL(0xa6fbabfb,0x20de0daf),LL(0x8f09fff7,0x04f01583),LL(0x6a06994f,0x5a056297),LL(0x6e3ccd33,0xf51dac8f), LL(0x3af507b8,0xc087ef9c),LL(0x6a5c6663,0x525ab76e),LL(0xd916ee93,0x4fc04814),LL(0xd23d140b,0x3369c978),LL(0x1662028f,0xb0fcd70f),LL(0xe1e28adb,0x2ca77de2), + LL(0xc512bc71,0x838acd1b),LL(0xdc18afd0,0xac06d6bd),LL(0x9ec45f4b,0xc991c1e3),LL(0xcc27c68e,0x667c5e89),LL(0xed07f829,0x0e059b04),LL(0xcec4b3a7,0xceccf1d4), LL(0xb953f9a1,0x3d9c2dc9),LL(0x2d599b16,0x4be2f7e7),LL(0x97256c26,0x1a2054b1),LL(0x8b4fdfeb,0xcf66fa47),LL(0x8134d7ef,0x896cc1b3),LL(0xd41dadbc,0xa17264ca), + LL(0x37627e56,0xe3ccfe8e),LL(0x7b6b21a6,0x00733a86),LL(0xb605c427,0x3f13e2cb),LL(0xb0d80992,0x5ee12395),LL(0xb9991381,0x4dcaea94),LL(0x8c4c4b6e,0x4cfed7ee), LL(0x7f7f45df,0xd7aad54b),LL(0xb3809bf8,0x2229407f),LL(0x68048fd9,0x6eb31eee),LL(0xd57225fc,0x693842df),LL(0xa88dfd3f,0x3e62cd85),LL(0xd5462cf1,0xc6307d53), + LL(0xf344f5fd,0x2d15615e),LL(0xa7f23989,0xe0ba6a8a),LL(0x1c84e3f2,0xbbfc5804),LL(0x6f4ba826,0x22ffeaae),LL(0x94292682,0x1e9bf274),LL(0x46c02af9,0xc768f891), LL(0x177cdafa,0x894127d6),LL(0x2acdc791,0x8d0523da),LL(0xdc78c3c4,0x71ada9ae),LL(0x2c532a01,0xf21dbbb9),LL(0xacb20fda,0x0c797d5e),LL(0x16cf57b0,0x1ff99d76), + LL(0x493c1d64,0x99b5f150),LL(0xfb74075e,0x3422b656),LL(0xff19bf24,0xe7493900),LL(0x260925ed,0xc82e5b80),LL(0xc0ea1eaf,0x3398d340),LL(0x1287121e,0xe7de2ba1), LL(0x87847031,0xea6dfb0b),LL(0x566af2f2,0x73bed0a1),LL(0x12012999,0xe26678bf),LL(0x32e5cebc,0xb5369e4d),LL(0x6d181e32,0x2304eac8),LL(0x3d364add,0xafdbd954), + LL(0x75da4189,0x5b1a53ca),LL(0x2eb4862b,0xa9048580),LL(0x2783ad6a,0x31942409),LL(0x1a9e025e,0x15a4c5e1),LL(0x13837199,0x841bc533),LL(0xe642954a,0x6e9d3e14), LL(0xd436ec5c,0xf4a02bbd),LL(0xc6d6ad53,0x62fe177b),LL(0xac86425a,0xedbf1e4e),LL(0xd9f752f5,0xff9359c8),LL(0x2d7ad656,0x79c685d9),LL(0xfdde9052,0x8d82c0c4), + LL(0x702f640d,0xf55f868e),LL(0x1dedda11,0xe459aa9b),LL(0xbb5ba193,0xbec0ff9b),LL(0x57724703,0xf7325c49),LL(0x23e0e4fb,0x5ab8f063),LL(0xecb0fd7c,0xfbf02e91), LL(0xa2e5fa31,0xcc72e8da),LL(0x32cb53cf,0x47de2528),LL(0x4252763c,0xbfa646e6),LL(0xb8d81de3,0x7a769efe),LL(0x1e772f00,0xf5ec7003),LL(0x2729aa5e,0x049bea9a), + LL(0x759090d6,0xe987ba54),LL(0x619ef08b,0x904d6901),LL(0x2024a6fc,0x9e16d138),LL(0xa9f3b7e4,0xb6f0459b),LL(0x17ee069a,0x1f2a5308),LL(0x2be31049,0x99403b2e), LL(0xbfb2f288,0xba1663c6),LL(0xc7a92b41,0xf829195c),LL(0x8ae621b1,0x89b915ee),LL(0x50f8ea92,0x3fbbb1e1),LL(0x8c901ddc,0xb1fe7f97),LL(0xbbc69ca4,0x16d1f62c), + LL(0xfda072db,0x51f19bb3),LL(0xe3f7e0a2,0xa815459f),LL(0x987112ca,0x5f7cde2f),LL(0x759de2cb,0xdc51d948),LL(0xed49bd98,0x9d05c410),LL(0x364341fd,0xf063ab99), LL(0xd1aa0a11,0xd7869d68),LL(0x5d862d01,0xc2029106),LL(0xc2591073,0x7f258180),LL(0x6ebc4ebc,0x7b90fc7a),LL(0x3dda1d68,0x5565390f),LL(0xa44e4493,0xae77fca8), + LL(0x47c49ee8,0x97564e48),LL(0xab4ebef5,0xc56bb5a9),LL(0x7b4f86bc,0x80d96941),LL(0x41026cf0,0xa594b4e5),LL(0x5a89ece9,0xd56c8996),LL(0x6a0f922b,0xbcf60931), LL(0x1103475c,0x70259616),LL(0x8a2a2abb,0xb1224fb5),LL(0x715cd61b,0x0a437a03),LL(0x739921ed,0xcbe2d2b2),LL(0x385541c4,0xf3b1b5e9),LL(0xae010520,0x5d0984f4), + LL(0xcfd9295e,0xb4a2742d),LL(0xae929cd0,0x9cd36774),LL(0xdd7fcf4f,0xb15fadcc),LL(0x37d4fcc6,0x0b1fa2b3),LL(0xf01c7ab7,0x242c7b26),LL(0x50574cc9,0x2be8131b), LL(0xbd89a03c,0x6ee50f42),LL(0x005e7765,0xc7f6ff8f),LL(0x8420501b,0x04d13af1),LL(0x1b6e7d2a,0xc22e092b),LL(0xe9516f80,0xa393be7e),LL(0xb80bb5b5,0xa2593652), + LL(0x8b23bebb,0x5caa5da6),LL(0x1fdbbdf4,0xa1ad33e8),LL(0x4e5c1de0,0x18dc93cf),LL(0x5bd9e178,0xc3e6addb),LL(0x7cb8cd03,0xf30d517e),LL(0xf1abc417,0xbb84ce54), LL(0x67699659,0x0774b64c),LL(0xb7d4a401,0x228005b9),LL(0x80b2d3d2,0xd8c2ec5b),LL(0x3450ba7f,0x419c4cd9),LL(0x789286a6,0x520ae681),LL(0xaa8bcfbb,0x24b67ea9), + LL(0x0f74808f,0x9e41b9b7),LL(0x0c061bdb,0x2d835dae),LL(0xf272346c,0x67e50c8c),LL(0xdef57493,0xc98a5ef5),LL(0xa02676fc,0xc2dea8af),LL(0x6ace4659,0x59508de2), LL(0xda6cd733,0xc2b707aa),LL(0x4be7bfb9,0x6c1f226a),LL(0xa778c20b,0x5b580fa2),LL(0x57af166b,0x272c3a1d),LL(0xca78ce62,0xe47a64a9),LL(0x71d35087,0xd12db7d7), +}, +/* digit=64 base_pwr=2^320 */ +{ + LL(0x1a42e5e7,0xc20fb911),LL(0x81d12863,0x075a678b),LL(0x5cc0aa89,0x12bcbc6a),LL(0x4fb9f01e,0x5279c6ab),LL(0x11ae1b89,0xbc8e1789),LL(0xc290003c,0xae74a706), LL(0x79df3f45,0x9949d6ec),LL(0x96c8d37f,0xba18e262),LL(0xdd2275bf,0x68de6ee2),LL(0xc419f1d5,0xa9e4fff8),LL(0xa52b5a40,0xbc759ca4),LL(0x63b0996d,0xff18cbd8), + LL(0x844eefc5,0xf6827150),LL(0x4515ef68,0x002e82c4),LL(0xc51916c4,0xa46c8f55),LL(0x61ee081f,0x98c3524b),LL(0xad64872a,0x5ab7f2c2),LL(0x7e555faa,0x0b503ff0), LL(0xb4c58d29,0x802e0d23),LL(0x2fd917fe,0x12289040),LL(0x7af20d26,0xb56d1908),LL(0x6be50784,0x8d619e21),LL(0x1372b851,0x10fdbb72),LL(0x4935576e,0xf2c1673e), + LL(0xd7dd47e5,0x73c57fde),LL(0xd49a7f5d,0xb0fe5479),LL(0xcfb9821e,0xd25c71f1),LL(0xcf6a1d68,0x9427e209),LL(0xacd24e64,0xbf3c3916),LL(0xbda7b8b5,0x7e9f5583), LL(0xcf971e11,0xe7c5f7c8),LL(0x3c7f035e,0xec16d5d7),LL(0xe66b277c,0x818dc472),LL(0xb2816f1e,0x4413fd47),LL(0x48383c6d,0x40f262af),LL(0x4f190537,0xfb057584), + LL(0x51a135f6,0xd97a9b14),LL(0x97b4df14,0x6d16aaf5),LL(0x54818818,0xc57160c2),LL(0x1d59be44,0x4dbdeab6),LL(0x81f2b247,0xb93a9dad),LL(0xecbcab33,0xe2868cf5), LL(0x83a86711,0x5e1ce828),LL(0x29c55428,0x29a9ca2f),LL(0x2d82b0df,0xe716273a),LL(0xac8ff52f,0xb017f5f6),LL(0x70ea7ccd,0x7563e799),LL(0x3f0e674b,0x5fedf0a6), + LL(0x08962f6b,0x487edc07),LL(0x190a7e55,0x6002f1e7),LL(0x10fdba0c,0x7fc62bea),LL(0x2c3dbf33,0xc836bbc5),LL(0x4f7d2a46,0x4fdfb5c3),LL(0xdca0df71,0x824654de), LL(0x0c23902b,0x30a07676),LL(0x77fbbf37,0x7f1ebb93),LL(0xfacc13db,0xd307d49d),LL(0xae1a261a,0x148d673a),LL(0x52d98650,0xe008f95b),LL(0x9f558fde,0xc7614440), + LL(0xaf907da2,0xd084564b),LL(0x51d4997a,0x5b2ae487),LL(0x3bc7206d,0x24bd4bf6),LL(0xfc3d5772,0xdd37b4ef),LL(0x35c4924f,0x8156d6f6),LL(0x1d1d396e,0x21e067c3), LL(0xd40c7db8,0x977b3b39),LL(0xf5ad63bc,0x7ea4ecb4),LL(0xae811d70,0xe581f9c4),LL(0xa06c7f0d,0xe5441d5c),LL(0x1949d87f,0x0275c92b),LL(0x780469bb,0x511fd3e1), + LL(0x9cb16650,0x17cd6af6),LL(0x69f4eebe,0x86cc27c1),LL(0x78822432,0x7e495b1d),LL(0x1b974525,0xfed338e3),LL(0x86f3ce21,0x527743d3),LL(0xb515c896,0x87948ad3), LL(0xb17f2fb8,0x9fde7039),LL(0xd9b89d96,0xa2fa9a5f),LL(0x36ff74dc,0x5d46600b),LL(0x8302c3c9,0x8ea74b04),LL(0xf744b5eb,0xd560f570),LL(0xfe762402,0xc921023b), + LL(0x88d7b3fb,0xa7f85014),LL(0xec78386e,0x3b5ec513),LL(0x2ad5053d,0xc6586b8a),LL(0xfbcebe43,0x88c09a43),LL(0x20054f16,0xde7f2a4a),LL(0xbbbb147f,0x63daba80), LL(0x7d352b55,0x087e48f3),LL(0x8317ab79,0x997e32a0),LL(0x7f27cac7,0x8ae802ff),LL(0x37b1f6e1,0xb01a131c),LL(0x9a6d1dea,0x3f0d4c2e),LL(0xe7ceef80,0xe06114fc), + LL(0xfff4c8ed,0xa35ab657),LL(0x8a5fabd7,0x017c6124),LL(0x09acda28,0x56463025),LL(0x14cf238a,0x6038d361),LL(0xaf1b9f07,0x1428b1b6),LL(0x7482e95c,0x5827ff44), LL(0x780ff362,0xcb997e18),LL(0xe0bcac1e,0x2b89d702),LL(0xa837ddc8,0xc632a0b5),LL(0x59762647,0xf3efcf1f),LL(0x38b0d60a,0xe9ba309a),LL(0x20b5fb37,0x05deabdd), + LL(0xe5ea795b,0x1e2a4fb1),LL(0x89ef6c3d,0x862616a2),LL(0xf69e2f1d,0x24617f4f),LL(0xffa0eb28,0xe0be24fe),LL(0x4b76a8ad,0x0ffb092f),LL(0x3a0dc9e8,0x21549090), LL(0xe9080e04,0xf255fe06),LL(0x39228e7f,0xd270d25e),LL(0x5d6c6f1c,0x198e45db),LL(0x4373044c,0x6c9060ad),LL(0x61a8cc25,0x3af93464),LL(0xf22bbaa3,0x1945bf59), + LL(0xcb8af047,0xd44e5dba),LL(0x943cfe82,0x15400cb4),LL(0x9df88b67,0xdbd69575),LL(0xb2405a7d,0x8299db2b),LL(0x0b1d80cd,0x46e3bf77),LL(0xe82ba3d9,0xc50cf66c), LL(0xf2f747a9,0xb2910a07),LL(0x5adc89c1,0xf6b669db),LL(0x9052b081,0x3b5ef1a0),LL(0xb594ace2,0x0f5d5ed3),LL(0xd5f01320,0xda30b8d5),LL(0xaafcd58f,0x0d688c5e), + LL(0x359590bf,0x311df84c),LL(0xdf6ca4b4,0xf907d69d),LL(0x82f22c64,0x876fd367),LL(0x9713e68c,0x64c4d14d),LL(0x6b07f539,0xd431858d),LL(0x84990283,0x39dfea33), LL(0x80cf6498,0x6afb8cf0),LL(0xde060e9e,0x327056bc),LL(0x49a71086,0x5103ce4a),LL(0xcdf853ab,0xfc94be75),LL(0x8ca579cd,0x2bfb105f),LL(0x50454b41,0x02d19c3a), + LL(0x2a161074,0x5eee3a31),LL(0xefe2be37,0x6baaae56),LL(0xe3d78698,0xf9787f61),LL(0x50630a30,0xc6836b26),LL(0x1445def1,0x7445b85d),LL(0xd568a6a5,0xd72016a2), LL(0xe355614f,0x9dd6f533),LL(0x91e04588,0x637e7e5f),LL(0xb9fb1391,0x42e142f3),LL(0x41afe5da,0x0d07c05c),LL(0x1394edf1,0xd7cd25c8),LL(0xb99288ee,0xebe6a0fc), + LL(0x7d4867b7,0xd9e2c5ee),LL(0x87873152,0x2c5602e0),LL(0x2c06b73a,0xb3358aa6),LL(0x09063076,0x967aec39),LL(0xd2f654fc,0x94dec534),LL(0xd69f485e,0x119aa4ed), LL(0x35bc085d,0xb7c597b8),LL(0xbdbe0d0c,0x8781396d),LL(0x22f92ef5,0xba688929),LL(0xd438f5ec,0xeece3d4e),LL(0x44faac8b,0x4ead06f8),LL(0x9ef7c5f1,0x86a01ba9), + LL(0xbabbad86,0xb8e63b7b),LL(0x90d66766,0x63226a9f),LL(0x5cf26666,0x26381836),LL(0x4cadd0bf,0xccbd142d),LL(0x9ac29470,0xa070965e),LL(0x25ff23ed,0x6bdca260), LL(0x87dca7b3,0xd4e00fd4),LL(0x9e0e8734,0xa5097833),LL(0x048173a4,0xf73f162e),LL(0x9c3c2fa2,0xd23f9196),LL(0xe4ac397a,0x9ab98b45),LL(0x543f2d4b,0x2baa0300), + LL(0xcde121c7,0xaa03b474),LL(0x55e52c76,0x74a648cb),LL(0xf37b57bc,0xb286ef86),LL(0x2a6371d2,0x95b797eb),LL(0x4077ccbd,0xa489ef89),LL(0x8e99ca6d,0xf46ade04), LL(0x23242d03,0x5cf9e237),LL(0xcb708390,0x33c7d32a),LL(0xba7ba477,0x329523b6),LL(0x57de30bf,0xd406ab87),LL(0x1536ca01,0xaa10e4a2),LL(0xdfa7aac5,0xdcec94f4), +}, +/* digit=65 base_pwr=2^325 */ +{ + LL(0x1f5a9609,0x762a5eec),LL(0x765b337f,0xfe4f5f6a),LL(0xaa4f964a,0x0fd534ae),LL(0xd6526f01,0xcf46648e),LL(0x18d71d72,0xbc62a54a),LL(0x4f8488ea,0x48d94f2a), LL(0xa0c72a86,0x62c40de7),LL(0x725dd2ef,0xd73ac51a),LL(0x6ab19096,0x3a51d746),LL(0x2dd1ad3d,0xf07bea4b),LL(0x2ef88078,0x2a0ec467),LL(0x664e435d,0x92598cb3), + LL(0xb515fff5,0xee6e7006),LL(0x13258ed5,0xaedf6e39),LL(0xfc45111b,0x373adf7d),LL(0x875c23c8,0x0c7535b1),LL(0x97039d49,0x2a7e04f8),LL(0x9afd1a06,0xd76787ae), LL(0x91b6dc89,0x049dd385),LL(0x932dab78,0x8f0c8ad0),LL(0x925498c2,0xdce057b9),LL(0xda25daa3,0x7b9c9bd2),LL(0xd4decb7d,0x6d0b70a3),LL(0x03df76ef,0x099a2183), + LL(0xd8948f95,0x779905b6),LL(0x91cd0206,0x3c7085b5),LL(0x679096db,0xce9af0aa),LL(0xf558913c,0xfdf04f10),LL(0x6f24a2e2,0x05300cb0),LL(0x5d581b35,0xf9d9a2f2), LL(0x6a713751,0x855c8de9),LL(0x0e0c0dfb,0xc9ac24bc),LL(0x97740d65,0x67612a41),LL(0x44c9360d,0x7588a527),LL(0x325cc880,0x928ac910),LL(0xacdd3188,0xa74abdaf), + LL(0xb9d926c2,0x3c6c5618),LL(0x4a9099f9,0x7e14c3ae),LL(0xae2fb830,0xb3259c90),LL(0xec31a504,0xf7cc6e43),LL(0x126230bd,0x83bb13c6),LL(0xff1dae3a,0x5a1f4313), LL(0x49b0b65b,0x0cc6c1a5),LL(0x274a84c2,0x67fa836a),LL(0xe604a58d,0xd454c75f),LL(0x2491f872,0xceadfd91),LL(0x9ce116a5,0x6c5575da),LL(0xb24a4481,0xfaa4903f), + LL(0x5a4703aa,0x7a8a898d),LL(0x1cd6f9d6,0xc59933ea),LL(0xd28124cd,0x703265f5),LL(0x0178d1fe,0xe1c1bee1),LL(0x241262e9,0x9ff31cd4),LL(0xa3c9f80f,0x9174a939), LL(0xbc2a62ee,0x0f7a3d2d),LL(0x62f1b3ac,0x0454051c),LL(0xa2421254,0x83502c9e),LL(0xb684199b,0xb4fa51fc),LL(0xc5e36a44,0x257e9e2b),LL(0x97d8647f,0x14efeed5), + LL(0x5cecb21f,0x6e96a819),LL(0xd8beecae,0x3a58d8b2),LL(0xc0c715a8,0x93c3cbb0),LL(0x541759b7,0xfb06f977),LL(0x771c3d2c,0xf25ba095),LL(0xa3bfd322,0x7560446e), LL(0xa015cb4f,0x7cd99f35),LL(0x0786f235,0xa0e54196),LL(0x8b8e291a,0x0f868f76),LL(0x2f95050b,0xc8260b0b),LL(0xf4c0a462,0xaf38376e),LL(0x98a3395d,0x2b3c0f3b), + LL(0xb9d0bdf0,0x0952b888),LL(0x8ce32fb7,0x3973763c),LL(0x6dd860c7,0x221f0ba5),LL(0xb16ac501,0xbb7a27fe),LL(0xbc8fe58f,0xf113b194),LL(0x65839ffb,0x18f3297a), LL(0x8dc30003,0xa2d4eb7c),LL(0x8e334479,0x3fb4b487),LL(0x1a8310e3,0xa4f32c65),LL(0xf78f46ac,0x944cd644),LL(0xf96fb91f,0x14e40c4a),LL(0x4ddf6e72,0xc31402bd), + LL(0xb45a8002,0xc5ad791e),LL(0xba2d7a40,0x4a23fd68),LL(0x98544bc4,0x673b9e49),LL(0xd273c360,0x934d8f55),LL(0x68a75a8c,0x7fb48d07),LL(0x5e0fac97,0x2e620105), LL(0xf10ed580,0xbe01655f),LL(0x9e96731f,0xd21d52ae),LL(0x53325138,0x74f830de),LL(0xde9f3fc5,0xa7240331),LL(0xa7e01fa5,0x96b25206),LL(0x07eda4b4,0x3fcfedee), + LL(0x9336b8bb,0xf1b08a42),LL(0x9a768ca6,0xbaaa5571),LL(0x2c0a2938,0x70180b4c),LL(0x92dd3c07,0x8e735436),LL(0xe3fd5b1c,0x2dd3af0b),LL(0x1f1af8b8,0x3cf3d179), LL(0xd558c174,0xaff210c6),LL(0xe2560d5e,0x1007938a),LL(0x8f99a78f,0xa625558c),LL(0xc1b91dea,0xa61d5edf),LL(0xdab80815,0xa86a4e5b),LL(0x78283ea3,0x88944bfe), + LL(0x0ee6d492,0xeec9b118),LL(0xb7ef00fc,0xf2bd388f),LL(0x3191c902,0x5c6c0bbf),LL(0xd42366de,0x6796929a),LL(0x3285710d,0xeecb5b3f),LL(0x41bad8a3,0x58d6773d), LL(0xd0f05005,0x7cdbade6),LL(0x0e25444b,0xb117e1ba),LL(0xfe4dc071,0xa52b4926),LL(0xe0669f10,0xce8a1b69),LL(0x0db21d46,0x5e765439),LL(0xd929bfab,0xc5dcdea4), + LL(0xa36aea84,0x67832f48),LL(0xfc78df1d,0x25256118),LL(0x03b8f04d,0x5a085d70),LL(0x108969c2,0x19a25d9c),LL(0xb70b14b7,0xb6fe713b),LL(0xfa6b89d8,0xba23ac4a), LL(0xc2684b8c,0x6a88e4e7),LL(0x6ab59297,0x3e816609),LL(0x30151aaf,0xdb7927fe),LL(0xaa7d95da,0x0fd67681),LL(0x17432b4c,0xc60e5dd5),LL(0xed48ccda,0x3192dc27), + LL(0x8af859e2,0x2116a017),LL(0xbd9f8800,0x8a77a7a2),LL(0xf1f2034d,0xc78836fb),LL(0x3864566b,0x8fd4299a),LL(0x29f9deca,0x0386eead),LL(0x2f1a677c,0x2042ef18), LL(0x2af95cc8,0xed4511c0),LL(0xc93dfbc5,0xdb0a334d),LL(0xb64ab345,0x0d788ac9),LL(0xb20638f2,0xd8410402),LL(0x592448e6,0x8aca5131),LL(0x000de69b,0x3ac508d2), + LL(0x4f9b2400,0x1ee6d3b5),LL(0x00c9c182,0x4c71999a),LL(0x35fc481e,0xd6b1c470),LL(0xf8b5d59c,0xf41ef454),LL(0x2824a13d,0x7edbc3c9),LL(0xb7aa0ade,0xa3baba91), LL(0x2b97b392,0x75c77e71),LL(0x9cc2d53c,0x8ec107d6),LL(0x29322233,0x652146fe),LL(0xe679e990,0x710578df),LL(0x260547db,0x47f838ba),LL(0x23a78365,0xa4e57bec), + LL(0xefb058db,0xe4320313),LL(0x3d04e752,0xaad2377c),LL(0x9865c63e,0x3f8cbca9),LL(0x3009e55d,0xe89238a5),LL(0x12519936,0x58fad5fe),LL(0xb024b695,0x03b16a00), LL(0xf8f3b8c7,0xa556d096),LL(0xd8a599c4,0xce6df197),LL(0x6a13b031,0x45ac8a25),LL(0xca6819e8,0x31af2dcc),LL(0x390418e9,0x7a4dce86),LL(0x4600d7f4,0xdd24b0bd), + LL(0xb96e667f,0x88a8aa87),LL(0x4e704eaa,0xb9a76c18),LL(0x72c924b7,0x25d4edc1),LL(0x16b67f80,0xe56872a8),LL(0xc464e4ff,0xda0dbb11),LL(0xc8cec410,0x0435f391), LL(0x0983fd7a,0x8d9b4043),LL(0xe7ff343c,0x51ec5bc1),LL(0x85994bc9,0x8bc85fc4),LL(0x8806c150,0x69c78834),LL(0x3db3665b,0x542cec89),LL(0xfd720bde,0x931bc4b0), + LL(0x8d5c039f,0x3e6e9381),LL(0x8a8d2cc9,0x80949422),LL(0xb843ec06,0xf2d7c8b4),LL(0xaf8a23f1,0x0055d882),LL(0xd3792335,0xe848010e),LL(0x55e08e74,0x9b41a55f), LL(0x5de83059,0x956ea8e9),LL(0x3263678e,0xf159a997),LL(0xcca1b548,0x5f7b9271),LL(0xf1d0b7f1,0xd41d2281),LL(0x5c9963fb,0xb187047b),LL(0x02536cd8,0x213ff6af), +}, +/* digit=66 base_pwr=2^330 */ +{ + LL(0x0d0fa76c,0xe51a9570),LL(0x4d2e9c8e,0x67c7890e),LL(0xf974d2cb,0xc6160fa2),LL(0x4c6a78de,0xe00474f7),LL(0x0ac89d11,0xee916e51),LL(0xf826f133,0x1adad97a), LL(0x8d2d77f3,0x3fc65d3f),LL(0x0ba6c300,0xda942075),LL(0x0b9196b1,0x5237a82e),LL(0xa572b6f5,0x4975e680),LL(0xb9bed2bc,0x41ea8b92),LL(0x9826825e,0xbe0ad710), + LL(0x9fcaba39,0x8a390dca),LL(0x278d22b3,0x3879f0b4),LL(0xbc5e82f1,0x77bbea69),LL(0x4628d6f1,0x71f02e2d),LL(0xf968e240,0x6260790c),LL(0x665270ee,0x1c7f3df5), LL(0x1a87b1c8,0x33639545),LL(0x4ffd9fb8,0x2011fd21),LL(0x7807ed55,0x69060f86),LL(0x9dfa452c,0x1b0ac011),LL(0x06d27c0d,0xbbdb25fe),LL(0xa60ef90c,0x5c25d23a), + LL(0x734b2e9c,0xd3eb69e4),LL(0xc35ff1b3,0x1c2754e2),LL(0x9f3e8c51,0xa26681e6),LL(0xa2cae737,0x7892ad11),LL(0xcbd8bda6,0x88b1da43),LL(0x419d21c4,0x8a576942), LL(0xc90f4545,0x7c124343),LL(0x26453bae,0xa5a8d93b),LL(0x76ae72e8,0x9a4c08fd),LL(0x7b064e94,0xa08b82d9),LL(0x83725330,0x4f803ba0),LL(0x865235f3,0x33672455), + LL(0xc8110f1f,0x1877dfd0),LL(0x18db27c2,0xea88f59d),LL(0xc78e295e,0x9d089536),LL(0x74a04cc5,0xcbb5d553),LL(0x827f75ed,0xe3666006),LL(0x61e7378c,0x8557b81a), LL(0xed223f48,0x74170170),LL(0xd86ee829,0x84197a6e),LL(0xac1c4a0f,0xd75a30f8),LL(0x3cd92824,0xd7e7be0d),LL(0x1b5e86d4,0x5ea0abdb),LL(0xb3b615ef,0x41146ae1), + LL(0x1ae5e9da,0x570deceb),LL(0xb73ead01,0x5c079c70),LL(0xd2ce6639,0x522a30a6),LL(0xf4056ac9,0x71dc5c3f),LL(0xbaac149f,0xd93c7a2d),LL(0xf1844ceb,0x5c3298b8), LL(0x8c23c0dc,0x282adf40),LL(0x9b646f86,0xbe498189),LL(0x628da9e5,0xe77c1950),LL(0xa1fd5a18,0x38cc27ba),LL(0xaacdca52,0xb5579728),LL(0xc8e1ecbd,0x8d34fdb4), + LL(0xadea7d6a,0x323f2102),LL(0xb694b253,0x035b354e),LL(0x5b8a36c2,0x66dc4e4a),LL(0x71795ca4,0xb6092224),LL(0xd300d80f,0xd8c6d7ee),LL(0xb3b94954,0xf31f258d), LL(0x277ced5b,0x0f2eb679),LL(0xeba40e3f,0x0b16efa3),LL(0x0dca4f36,0x40003507),LL(0x59a9a3a1,0xd34c91cb),LL(0x86da6408,0x5e8fea32),LL(0x03f31728,0xf237959f), + LL(0xbbaaedc6,0x1b5bc630),LL(0xb49cbb3b,0xe7d25088),LL(0x0deb8cf0,0x5622cbf7),LL(0xd309c3ba,0x3b20803c),LL(0xff45e2fc,0x64c2e7de),LL(0x9aab84a5,0xfa730ffb), LL(0x4edfb52e,0xba83cc51),LL(0x748bbd69,0xe05c0140),LL(0x2254ec43,0x27bbb5f5),LL(0x324c8c40,0xca740989),LL(0xd26491b4,0xa21488b1),LL(0x69d8626b,0xe2753a1f), + LL(0x8956146c,0x618ca06b),LL(0x552cdecf,0xd51f1e6f),LL(0xa3b6ce7d,0x981372cc),LL(0x5f14bb57,0xb44a68ee),LL(0x6373abbb,0xfc1167e9),LL(0x767d4c0a,0x3d621f8b), LL(0xf6ecc778,0xc6dcdfeb),LL(0x82d1fbdd,0xddda9262),LL(0xbfcbf2f7,0x477501aa),LL(0x67aa8277,0x0be7228a),LL(0x1daab9cd,0x5de7b833),LL(0x262feb4a,0xb88a4f9a), + LL(0x936fb33f,0x28f18586),LL(0x381bf7bb,0x9809b2ab),LL(0xeac3c252,0xf6e16931),LL(0x5e151187,0x366d1833),LL(0x7a3b6460,0xe5b4c235),LL(0x0a68bc91,0x693a9fa5), LL(0x6a7f8b6e,0xa35f104a),LL(0x688676c4,0x3e5d6981),LL(0x0651a609,0xc0c081b1),LL(0xd77057c9,0x6df5da2d),LL(0xc4602847,0x8bb271bb),LL(0xc4bd07d8,0x322547b3), + LL(0x233d39e4,0x8c283529),LL(0xc6092096,0x96300796),LL(0x5dde766c,0x2c549de5),LL(0xb4151002,0x27e0b444),LL(0xf2f88f1b,0x802e5fc3),LL(0x8ba1956d,0x2af579c2), LL(0xd68196c7,0x52edd04e),LL(0x74a202b0,0x2e22e714),LL(0x8bf66459,0x33894824),LL(0x9e39df55,0x8f0d8c25),LL(0x6c5276d9,0xee4f109e),LL(0xc5dc0bf0,0xc0c893f0), + LL(0xf8482849,0x06054c76),LL(0x5fcca65d,0xc24b4a6a),LL(0xa17ebda3,0x71c27e01),LL(0x1be9dfb8,0x1ffce028),LL(0xebc43854,0x3784c950),LL(0xd5086510,0xcf0ecc2d), LL(0xbe24d8eb,0x86d0fc3c),LL(0x1f21788e,0x5bad0191),LL(0xc49b3a12,0xe2c3bcb9),LL(0xf7d5992d,0x66f82433),LL(0x13969246,0xf7cc5eb9),LL(0x8660a6da,0xe52defd4), + LL(0x53fd1a04,0x7a9623b6),LL(0x3a3b8500,0x13bd35bf),LL(0xe0f8e530,0xf8a5dec9),LL(0x1d65dcd4,0x88bcbe29),LL(0x6739541c,0x09fe3803),LL(0xe716a97a,0xebd04b7f), LL(0x1e5ef7cb,0xbd8e34df),LL(0xd7c4fd6c,0xddfc4243),LL(0x3519411f,0x0183d905),LL(0xf7a3c483,0x63450996),LL(0x01355739,0x18283cea),LL(0x9aaa72f7,0x8c1d72cf), + LL(0x8dc72468,0x551e1b4e),LL(0xa7b2f1ac,0x8a926cb2),LL(0x0fd12fad,0xb873e83b),LL(0xa4e7fb13,0xb6cde14f),LL(0x5befc256,0x81ae4141),LL(0xb4c7631c,0xffb0c636), LL(0x8a2478fe,0x80f1408f),LL(0x44fa7605,0xde6d051d),LL(0x4d44a1e4,0x5a15b1f8),LL(0xa0daafe3,0x1a0031c5),LL(0x597652a7,0x304338dd),LL(0xf257f17a,0x6830dcc7), + LL(0x193aabbc,0x4a67ec76),LL(0xd74761f9,0x3da6dec6),LL(0x0b35bb70,0x751720c9),LL(0x8d9e0f8b,0xe5e04905),LL(0x0858f29c,0x3cd37c84),LL(0xb881733e,0x7ff1abfb), LL(0x0c4f7694,0xa0c2698b),LL(0x96b95e4e,0xc7364192),LL(0x37ece651,0xcfa55c55),LL(0x7cb1e9e1,0xa2bbd6ae),LL(0xa0eb0e8a,0xcd2292b9),LL(0x8d5030d0,0x8aba99e1), + LL(0xdc4a1d3e,0xb7c74c58),LL(0x0331ea39,0xe3ec3016),LL(0x023c8712,0x83afb271),LL(0xc9c82680,0xc2670d56),LL(0xfeca1061,0xd426f350),LL(0xba6edc01,0xe8aee692), LL(0x46e801d9,0xc916fbe5),LL(0x7097286e,0xcb001c37),LL(0x78ee1328,0xfcf79d26),LL(0xb6a4afb3,0xb05b0634),LL(0x306da14f,0x2ab327bb),LL(0xba5ff534,0xc11a0294), + LL(0xe19763dd,0x7b7da028),LL(0x8b98ff78,0x662f54df),LL(0x51f3dbd9,0xc056d83c),LL(0xa91d085a,0xe2f4d46f),LL(0xeb35262d,0x31759c9c),LL(0x0c9dd29e,0x624d0cf2), LL(0x1624b02d,0x108cf9bb),LL(0x345531d6,0xa241444e),LL(0x73d372b2,0xf69816b2),LL(0xd5415e53,0x126575a7),LL(0x306b8b0e,0x546bb4c1),LL(0x4d54ea5e,0x82bb0c12), +}, +/* digit=67 base_pwr=2^335 */ +{ + LL(0xf9474bb7,0xdaa7fcc9),LL(0xafa5db2a,0x3c82e74b),LL(0x9894edce,0xfbf918c5),LL(0xa9ac29a7,0x470c45ed),LL(0xbc372f2c,0xdfd44f6f),LL(0xa1e38d3f,0x73a4790a), LL(0xa9674837,0x23d2400b),LL(0x136a92da,0x3dad71bc),LL(0x48baa4ab,0xc76a4881),LL(0xbc26e6b0,0x73227e4e),LL(0xe8ef5662,0xe732edcf),LL(0x0c5662bb,0xfe96aa5f), + LL(0x139b3239,0x87c7dd7d),LL(0x4d833bae,0x8b57824e),LL(0x9fff0015,0xbcbc4878),LL(0x909eaf1a,0x8ffcef8b),LL(0xf1443a78,0x9905f4ee),LL(0xe15cbfed,0x020dd4a2), LL(0xa306d695,0xca2969ec),LL(0xb93caf60,0xdf940cad),LL(0x87ea6e39,0x67f7fab7),LL(0xf98c4fe5,0x0d0ee10f),LL(0xc19cb91e,0xc646879a),LL(0x7d1d7ab4,0x4b4ea50c), + LL(0xe2fdc88b,0x7e047d9c),LL(0x715be007,0x4f6166d9),LL(0xd0debb0a,0xd9661068),LL(0xc3dafce2,0x82f02fd3),LL(0x00f8df79,0x41a6b644),LL(0x6cedd3a8,0xccd5a798), LL(0xf11431b2,0xb6617354),LL(0x8a677e83,0x116d0274),LL(0x89ef485a,0x2f399390),LL(0x5e2270d2,0x3ee06862),LL(0x06d6c72f,0x8c9a70de),LL(0x4e4497e3,0xd7e69177), + LL(0x7db62b5a,0xcfbcbc4a),LL(0x4ab45dde,0x2919bf51),LL(0x22322f91,0x735de056),LL(0x7662ae23,0xd2590bda),LL(0xd82be7a6,0x63d468fe),LL(0x695ea172,0xc84d0435), LL(0x20a6fccd,0xc50f4941),LL(0x620f44f1,0x2d613990),LL(0x1fd25778,0x680ccd04),LL(0x4a3d0808,0x25ddac44),LL(0xc4684cba,0x41d8b738),LL(0x53963888,0x2611645f), + LL(0xe9f43747,0xffe6bb22),LL(0x22f6cd09,0xf387957b),LL(0x607a4892,0x3eb09302),LL(0xf3d2f552,0x52c733a8),LL(0x741bd215,0xcc935b2e),LL(0x1ae0b28e,0x5fff37e3), LL(0xc2e9bc20,0x4234e33c),LL(0x39ea2555,0x4ee1488e),LL(0x17156a8a,0xb8821daf),LL(0x1af16ade,0xc7b45844),LL(0x5b4fa74d,0xc1009ec7),LL(0x5d7cf8bd,0xe0262e65), + LL(0xb0279be5,0xb05cb834),LL(0xf08c5f93,0x2de7d0eb),LL(0xefa9e4f0,0xf023b5aa),LL(0x9bd075ec,0xb8061e5d),LL(0x1aa41bfb,0x7d2ba50f),LL(0x90865d96,0x8963f3e3), LL(0x4713ec7a,0x7f221a79),LL(0x8500b4c3,0xc83bc517),LL(0xf6ab1540,0x085feb6a),LL(0xdc87cd93,0xfd141024),LL(0x3239dbf6,0x3e196fdb),LL(0xdbcd5364,0xb7cf3e16), + LL(0x41a64252,0x72544edb),LL(0xa6fe493d,0x5f3d376f),LL(0xd635df1e,0x17ae424f),LL(0xdf598c63,0x69cb55a0),LL(0x6ce0f1d5,0x31297f4a),LL(0x1bd11b61,0x4573bb7d), LL(0x45a1e918,0x1d8a65c1),LL(0xe5dc2e63,0x2729ab25),LL(0x3ecc307b,0xa3dd0df0),LL(0x952019dd,0x4856546f),LL(0xc784e4fe,0xf8d39888),LL(0x0043b09e,0xdc6732c7), + LL(0xe03a2fb4,0x1466c9f5),LL(0x862a58a2,0xb866c006),LL(0xb5865550,0x291e8c75),LL(0xe65862cc,0x1ddb7154),LL(0x2b997167,0x285153bc),LL(0x954b6c19,0xe2fce0e7), LL(0x16dc2937,0x985d4506),LL(0xee41d9c3,0xf7f14216),LL(0xfa5fe5e5,0x39e098da),LL(0xf90f231d,0x3fc26046),LL(0x32afd0b5,0xde5d5ced),LL(0x60c09c18,0xad688b1d), + LL(0x8f84e987,0xefd9aed0),LL(0xae8c8308,0x5ee0c707),LL(0x2aafc403,0x4c8a7653),LL(0xa232436a,0xfafb60ce),LL(0x9934f053,0xc641294d),LL(0x30310529,0xc673e5b2), LL(0x9066469d,0x3c8fa99a),LL(0x7c09af37,0x5626038b),LL(0xabd66748,0x6ffd8f9b),LL(0xcea58a67,0x21ced048),LL(0x1496d048,0x31071213),LL(0xa9c28d0d,0xfa575242), + LL(0x0f806b59,0x3720b172),LL(0xf224597b,0x1f696d47),LL(0x5b54eefc,0x03c46e31),LL(0x72b0edaa,0x387e4664),LL(0xee77476e,0xfc59b03d),LL(0x607a7259,0x86854e54), LL(0x3e9320dc,0x1478bcee),LL(0x8c9d87e4,0x4aa825a8),LL(0xcf272ee0,0x71272f72),LL(0x8bd885cd,0x19e3a4a3),LL(0x376ba31c,0x9af6415b),LL(0x807b2b36,0x6394b5a7), + LL(0x77460193,0x1bf6c56b),LL(0x5666ae6d,0xd6f7fabf),LL(0xe3e839d1,0xdf677909),LL(0x08cb9984,0x9124d341),LL(0x86a0c7c3,0xbb6b591d),LL(0x8f527a6a,0x4bf33423), LL(0x26941bfe,0x7d137790),LL(0xcf6e4481,0x15a0b541),LL(0x124d5b9b,0xdf833b87),LL(0xa7fdf95d,0x85827dc5),LL(0x49e520af,0xf05a2c45),LL(0x91e0645a,0xfb506d53), + LL(0xe572e06d,0xdbfcfa75),LL(0x8b7d5653,0xafa019d0),LL(0x67a19b60,0xcc6c851d),LL(0x31ae1a67,0xace88bf4),LL(0x93d1e135,0x74554a61),LL(0x4211890a,0x51ba2cdd), LL(0x9e8d1f02,0x7cb32689),LL(0x8b66ab99,0x29a6b825),LL(0x766e72f3,0x0a672c21),LL(0x880642e3,0x24bb718a),LL(0x184d2b36,0x425dc41d),LL(0x891024ab,0x96a1468e), + LL(0x665fe173,0xeff22b64),LL(0xef2eabea,0x38efdef6),LL(0x21a309df,0x8a1f3791),LL(0x2431e2ed,0xa9cf02cf),LL(0x1d939394,0xf38507dc),LL(0x82fc3178,0xf116b085), LL(0xc7571366,0x4c5460dc),LL(0x978495fd,0x99efd9dd),LL(0xf26e347d,0x5159dd41),LL(0xe97ee9f1,0x692962ce),LL(0x6a288815,0x1e2f3af2),LL(0xa71ade78,0x03512344), + LL(0x26df7050,0x3180789c),LL(0x96cdfd31,0xe375a43e),LL(0xe99e922d,0x7951b895),LL(0x3d0bbe80,0x987ea250),LL(0xe2fe79c0,0x6d2f49f0),LL(0xc2b18d2a,0xc9c2c636), LL(0xd8c8620c,0x707798f3),LL(0xd5c6a0ee,0xc2d603da),LL(0xbc447940,0x46cf1e32),LL(0x38a845f3,0x4dfc1459),LL(0x455e5d92,0x210083fe),LL(0xa1fedc3f,0x6be989ea), + LL(0x9f019162,0x55d4fdc3),LL(0xf1ec4585,0xa8222d08),LL(0x3a0ae4f9,0xd987e3eb),LL(0xa9c7a693,0x07deda59),LL(0xf04ee53f,0xc06567d9),LL(0x71364c4d,0x93945788), LL(0xbaa5bc16,0xbb2a2422),LL(0xbfa3931a,0x89574a5d),LL(0xf300f081,0xf09b331e),LL(0x1a0ff82b,0x644de9b7),LL(0xa5ecdf9b,0xae023ce4),LL(0xc1907aac,0x5b67cf8b), + LL(0xdacc038c,0x72fc8198),LL(0xf1077bbd,0x5fdae1d9),LL(0xd99e3036,0x369198bb),LL(0x0efddfca,0x6b68390a),LL(0xf0914741,0x8c35f3e4),LL(0xca7d7807,0xd2bc54ec), LL(0x3a8695d1,0x564d991e),LL(0x1b0d937d,0x5e1e14c8),LL(0x5d635893,0x51f30dab),LL(0xf944e49a,0x0427e346),LL(0x6a233bc0,0x1e0bf1b5),LL(0x617bf93e,0x75b0ee6c), +}, +/* digit=68 base_pwr=2^340 */ +{ + LL(0xd2e15a8c,0xd23658c8),LL(0x16ba28ca,0x23f93df7),LL(0x082210f1,0x6dab10ec),LL(0xbfc36490,0xfb1add91),LL(0x9a4f2d14,0xeda8b02f),LL(0x56560443,0x9060318c), LL(0x64711ab2,0x6c01479e),LL(0xe337eb85,0x41446fc7),LL(0x71888397,0x4dcf3c1d),LL(0x13c34fd2,0x87a9c04e),LL(0x510c15ac,0xfe0e08ec),LL(0xc0f495d2,0xfc0d0413), + LL(0xc4e81268,0xb097b2c5),LL(0x1d50ca8c,0x7ef17552),LL(0x42099644,0x638266e9),LL(0xff729073,0x43d059de),LL(0x148c3940,0xeebb5fe1),LL(0xdaa8e925,0xb82e73d1), LL(0x254380fd,0xf43c78d8),LL(0xfce37fa0,0x2beabc58),LL(0x6b636357,0xcdd5a7d6),LL(0xe096a954,0x8b70a2eb),LL(0xd0afa2fc,0x011d5419),LL(0x04fb095a,0x3e49eb67), + LL(0x156636c2,0xeb05c516),LL(0x090e93fc,0x2f613aba),LL(0x489576f5,0xcfd573cd),LL(0x535a8d57,0xe6535380),LL(0x671436c4,0x13947314),LL(0x5f0a122d,0x1172fb0c), LL(0xc12f58f6,0xaecc7ec1),LL(0x8e41afd2,0xfe42f957),LL(0x3d4221aa,0xdf96f652),LL(0x2851996b,0xfef5649f),LL(0xd5cfb67e,0x46fb9f26),LL(0xef5c4052,0xb047bfc7), + LL(0x168d5e60,0x88e7ac8e),LL(0x6188a98f,0x53abd569),LL(0x18be419a,0x3b96d529),LL(0xc057621c,0x7e75e354),LL(0x5ce57e59,0xcb1b709f),LL(0x844f2463,0xe78befa2), LL(0x3276d4a0,0x53608199),LL(0x157f2024,0x92636ade),LL(0xe0411414,0x6dd0d348),LL(0x4d73eeae,0x5b28e950),LL(0x690ed85e,0x08439232),LL(0x6da14b58,0xdde1a349), + LL(0xf4484374,0x5cbdc442),LL(0xf92452ef,0x6b156957),LL(0xc118d02a,0x58a26886),LL(0x75aaf276,0x87ff74e6),LL(0xf65f6ec1,0xb133be95),LL(0x4b1b8d32,0xa89b6284), LL(0x09c81004,0xdd8a8ef3),LL(0x0cf21991,0x7f8225db),LL(0x26623faf,0xd525a6db),LL(0xbae15453,0xf2368d40),LL(0x84f89fc9,0x55d6a84d),LL(0x86021a3e,0xaf38358a), + LL(0x33c12f53,0x10520b27),LL(0x9286a1f5,0x97d4ef43),LL(0x8948f78b,0x12468ef8),LL(0x50ad452e,0x40a9d275),LL(0xc1c48470,0x5e382347),LL(0x33e73ace,0x5cd739fd), LL(0x1041f8f3,0x7d83d02f),LL(0xe314ad92,0x32642eb0),LL(0x885679e6,0x6716d448),LL(0xfc95919c,0x0e12bdd5),LL(0x92c2194a,0x7da44204),LL(0x15ffcd2d,0x78956db1), + LL(0xff52e280,0xbd048bdc),LL(0x526a1795,0x8a51d0b2),LL(0xa985ac0f,0x40aaa758),LL(0xf2c7ace9,0x6039bcdc),LL(0x6aec347d,0x712092cc),LL(0x6b5acab7,0x7976d090), LL(0x6eed9617,0x1ebcf80d),LL(0xb0f404a4,0xb3a63149),LL(0xd0b610ef,0x3fdd3d1a),LL(0x98c28ac7,0xdd3f6f94),LL(0x3a59750f,0x650b7794),LL(0x2d3991ac,0xec59bab1), + LL(0x39ed9ec9,0x6cbd2757),LL(0xfe5d4aa8,0x5db68a68),LL(0xe4c58c7b,0x177eaa0b),LL(0x0e488784,0x603551ef),LL(0xdf916b0f,0xc8eba131),LL(0x159732e2,0xd0dbceda), LL(0xb0834afa,0x55acca84),LL(0xb59ffbf5,0xdbe98440),LL(0x3bd3b202,0x162a2c70),LL(0x6ddd8eba,0x4c5e5d25),LL(0x77b1d93d,0x66e7844a),LL(0x110b9dcf,0x1292bc0e), + LL(0x2e552766,0x01f40e88),LL(0x66f5354f,0x1fe3d509),LL(0xb3a8ea7f,0x0e46d006),LL(0xf831cd6a,0xf75ab629),LL(0x91465119,0xdad808d7),LL(0x17ef9b10,0x442405af), LL(0x672bdfcb,0xd5fe0a96),LL(0x355dbdec,0xa9dfa422),LL(0x79b25636,0xfdb79aa1),LL(0xeece8aec,0xe7f26ffd),LL(0x7edd5aa2,0xb5925550),LL(0x8eb3a6c2,0x2c8f6ff0), + LL(0x9341a2e0,0x34a4632c),LL(0xc525bc5a,0x05ca421b),LL(0x4ae3284a,0x441cf2eb),LL(0x146012ab,0x1a57684e),LL(0x30acfd0e,0x23a52ee3),LL(0x7d29e389,0xc3f4d94a), LL(0xb4154640,0xfbd4d48e),LL(0xaf9ec396,0x2352e791),LL(0x7327caee,0x45813e8e),LL(0xd9db7e81,0x977f7a08),LL(0x5f53d15d,0xbe55b630),LL(0x6a23f0dc,0xee182ac6), + LL(0x757d6136,0x88887756),LL(0x88b92e72,0xad9ac183),LL(0x8785d3eb,0x92cb2fc4),LL(0x9319764b,0xd1a542fe),LL(0x626a62f8,0xaf4cc78f),LL(0x26bffaae,0x7f3f5fc9), LL(0x40ae2231,0x0a203d43),LL(0x387898e8,0xa8bfd9e0),LL(0x474b7ddd,0x1a0c379c),LL(0x34fd49ea,0x03855e0a),LL(0xb3ef4ae1,0x02b26223),LL(0xe399e0a3,0x804bd8cf), + LL(0x7cdc2211,0x22723fa3),LL(0x31ddb2bd,0x1d339232),LL(0x46626fe6,0x63f354c1),LL(0xf67a4257,0xd0f68526),LL(0x8d3d00b6,0x79aa889b),LL(0x0de4c413,0xca5fc8a7), LL(0xd2879266,0xe311a966),LL(0x5f21e1dd,0xc8d982fe),LL(0xcbb159ff,0xc51f1604),LL(0x092d83ce,0xb449deb8),LL(0x644fd0be,0x4a5f68f8),LL(0xbffb0088,0xeef3fa4d), + LL(0xde865713,0x11a9f3d0),LL(0xbde98821,0x81e36b6b),LL(0x6aa891d0,0x324996c8),LL(0x395682b5,0x7b95bdc1),LL(0xc1600563,0x47bf2219),LL(0x643e38b4,0x7a473f50), LL(0xf5738288,0x0911f50a),LL(0x6f9c415b,0xdf947a70),LL(0x67a067f6,0xbdb994f2),LL(0x88be96cd,0x3f4bec1b),LL(0xe56dd6d9,0x9820e931),LL(0x0a80f419,0xb138f14f), + LL(0x3b32932e,0x2b4056a4),LL(0xbd8a1cb8,0x1c74deb6),LL(0xb181b5a0,0x09601843),LL(0xdc6a92d8,0x50a92353),LL(0x2d6f4331,0xe86c022c),LL(0x3a3ae821,0x0d9671dc), LL(0xc8228d82,0x3d618a20),LL(0xa5292169,0x20e809c1),LL(0x3803f840,0x3b2fe5e7),LL(0x416eb670,0x1f2978e9),LL(0xc35b795c,0x44dcc410),LL(0x503ce975,0xbf5065c0), + LL(0x0429077a,0xa11a1a8f),LL(0x10351c68,0x2bb1e33d),LL(0x89459a27,0x3c25abfe),LL(0x6b8ac774,0x2d0091b8),LL(0x3b2415d9,0xdafc7853),LL(0x9201680d,0xde713cf1), LL(0x68889d57,0x8e5f445d),LL(0x60eabf5b,0x608b209c),LL(0xf9cfa408,0x10ec0acc),LL(0x4d1ee754,0xd5256b9d),LL(0x0aa6c18d,0xff866bab),LL(0xacb90a45,0x9d196db8), + LL(0xf9e89bea,0x1b66faab),LL(0x3a441284,0xc81c5ddc),LL(0xa675f7c8,0x1a82f3a0),LL(0x30313a71,0x82884a2f),LL(0x58aea9e6,0x7ac5d7b0),LL(0xcd5ff05d,0x1954f075), LL(0x6178d270,0x7c29638d),LL(0x19381929,0x6af7f8ba),LL(0xa17ae3a7,0xe85e3c47),LL(0x7009e38a,0x91b107c7),LL(0xf1f9c52e,0xf3b777d8),LL(0x11b688a0,0x5b7b74ff), +}, +/* digit=69 base_pwr=2^345 */ +{ + LL(0xc0385874,0x4ae3d232),LL(0xcbf96d2a,0x83bda9e6),LL(0xec62fd6a,0xba73c769),LL(0x62a4720c,0xd586ba7f),LL(0x0cc1f491,0x6497cd14),LL(0x7b2ac571,0x8b012b70), LL(0x268fd705,0xa65eabb6),LL(0x1431873d,0x8caf100a),LL(0x231457d7,0x25b31b84),LL(0x901645c5,0xcab62f75),LL(0xb2f7b656,0x2377d74d),LL(0x2d33c95c,0x4008277c), + LL(0xed001c43,0xaae2f448),LL(0xcf4be493,0x08ad1d9b),LL(0x82c1f372,0x3262b2f4),LL(0x351a5f7f,0x5521febd),LL(0x916c75a8,0xf8ec9190),LL(0x2728dfb8,0xf3c258c7), LL(0x8af19574,0x5dd4ff4f),LL(0x5d076b1c,0xefddf579),LL(0xba8b777a,0x318b5b98),LL(0xfb7f8409,0xd971d426),LL(0xb0fd31db,0xed1465e8),LL(0x00f66347,0x80d24d43), + LL(0x1ae586a2,0x5ba5288c),LL(0x1b715821,0x044f1fc6),LL(0x602f3c65,0xc1a9a997),LL(0xe08c0223,0xc5c7512f),LL(0x367e6f1d,0x48a19c3c),LL(0xfb241597,0xa9f2195d), LL(0xb5ba32a6,0x9f674a5f),LL(0x0a312742,0x275a060f),LL(0x03d6f13e,0x5aeb8c43),LL(0x917433fb,0x0fed575d),LL(0x59f53490,0xe4a5ef9a),LL(0xf315e616,0xa9f86145), + LL(0x7e5a59f4,0x315ad7a4),LL(0x543c8b00,0x1c615bfc),LL(0xbaa56473,0xe12f97a8),LL(0x46edcfcb,0xf263db44),LL(0x3c1a968e,0x47cf91d5),LL(0xc15db875,0x1a1165b4), LL(0x3479616a,0x5d35e53a),LL(0x5c59958f,0x649f87b4),LL(0x246da3d3,0x5d3d11ea),LL(0x53f06820,0xc1ddfcc6),LL(0x6610c00f,0x8169d711),LL(0x4bddc8c7,0x15f16ba5), + LL(0x1e548ef0,0xcf19fb2a),LL(0xcc694171,0x8bb6dfa0),LL(0x5c5e390f,0xeb1668ca),LL(0xe1975263,0xf5a3485b),LL(0x442cc850,0x4edfc596),LL(0xf9627d74,0x9901f447), LL(0x84d0413a,0x3a6b85c9),LL(0x67de639c,0x14663661),LL(0x11705bbb,0x9fc9fdcf),LL(0xbff2cf80,0x6d066e2b),LL(0xdc3026fd,0x38dedc2f),LL(0x1b828538,0xad533a98), + LL(0xb7bfa29e,0x6c75bc93),LL(0x18ef6d69,0xf86f22b2),LL(0x36dcadf2,0x90ce6a15),LL(0x7ce50921,0xf11f711c),LL(0x38a479e3,0x0739ceda),LL(0x6ec3dbc6,0x840b825e), LL(0x9fa23481,0x7c36c0a5),LL(0x70cb186d,0xceb61fd1),LL(0x26e4754d,0xac6f7d3c),LL(0xf317b385,0x4076d3b5),LL(0x3fd9e9c7,0x52f1bd72),LL(0xbf316043,0x6649d8b6), + LL(0x243cfbd5,0xdc2870f8),LL(0x1ab496f3,0x000b71b3),LL(0x708f4507,0x53511a3f),LL(0x1949d835,0xbd7bd038),LL(0x938f4db6,0x723a007d),LL(0x2d04e9fd,0x5bc8679e), LL(0x76ec7fc4,0x51ca5fd1),LL(0x988f354e,0x86c4205c),LL(0x2a0a4a90,0x9042e76b),LL(0x4ad44d2d,0x368f52a8),LL(0x912edfb7,0xddc2cab8),LL(0xcde80199,0xde74ccf5), + LL(0x3e455a61,0x8002f458),LL(0x5bea205a,0xafbafd37),LL(0xfb93f735,0xa8ced112),LL(0x196e3084,0x27cb6292),LL(0x77e8c744,0x72395bdd),LL(0xee71f5ff,0x02e018d8), LL(0xc1337a1d,0x7cfc14d9),LL(0xd7b4d86e,0x94e14c0a),LL(0xd213738e,0x66e50129),LL(0xbc0b5ea3,0x7a905d91),LL(0xfca06700,0x92cb630a),LL(0xbf3a0821,0x65e06d5c), + LL(0x55c2369d,0xa81e4a4e),LL(0x60a0f544,0x394de01b),LL(0xa8906e17,0x22acfd07),LL(0xcc9bc4d0,0xf59b37a6),LL(0x7ffec12f,0xdd16a22c),LL(0xd5976455,0x07decc2a), LL(0xabe1d122,0xc5019463),LL(0xe318c92c,0x2bf0ac0c),LL(0xb2bfc47b,0xfa50280a),LL(0xc7cf8bff,0x53354fc5),LL(0xe20ca341,0xaea1d293),LL(0x8b626244,0xec25ecda), + LL(0xfd8ba33e,0x313b66ca),LL(0xfabe27dd,0x10bdb130),LL(0x125e2b8c,0x1181334c),LL(0xdb6f94ba,0x0f4f198f),LL(0xac3f5de9,0xf7000076),LL(0x9d6402ae,0x1a78813d), LL(0xc8a9e758,0x3427f75d),LL(0xb01f791f,0xcdac8b34),LL(0x2a9ebaf5,0x922c36d1),LL(0xb0487cc4,0x195ea05f),LL(0xa808baec,0xe33de901),LL(0x57291d89,0x15e1d5ac), + LL(0xc21cdd1f,0x4e2a05c1),LL(0xdd46e76a,0x8a232097),LL(0xd871b1d6,0x8b55313c),LL(0xaf396bc4,0x976ce5f6),LL(0xafd381b1,0xeb91527d),LL(0x14455ee2,0x6cfd4490), LL(0x1f274d1e,0x8723be9e),LL(0x1999fa9f,0x1c63fd01),LL(0x8049b6f8,0x5f172625),LL(0x99a51b4d,0xe18a3ecd),LL(0xb13d4e65,0x329fc2c1),LL(0x0f18f300,0x94da252b), + LL(0xe28fd10d,0x7b151b98),LL(0x1dd884cf,0x8fc01ce8),LL(0x98d56c2c,0x1f0ffb50),LL(0xb084606d,0xf9df1fa2),LL(0xdc7d2008,0xf86232bf),LL(0xd8751699,0xeae5cb8f), LL(0x83ed54fd,0x70f02298),LL(0x86087697,0xb575283a),LL(0x0302e2c3,0xad219135),LL(0xc4b57e01,0x1c09a0d6),LL(0xc541b9fb,0x0f65e1e1),LL(0xf4fe76c0,0x85493d9b), + LL(0x191c21cc,0x353718ce),LL(0x4ad6bd18,0x08e6edf6),LL(0x4dc5b572,0xc2bb0d6e),LL(0x88193daa,0x328e19df),LL(0x7211c958,0xccc9f6ab),LL(0x58aae5c5,0x377d99ef), LL(0x1c823442,0x40e2ecc9),LL(0x8b0d36ab,0x036d6d52),LL(0xda4d0ad3,0x2fe0cd7e),LL(0xfc8af791,0xb8fc3c7f),LL(0x2b201b20,0xdb7e44a4),LL(0xebcf527d,0xa5176004), + LL(0xfa5256d2,0xe19b7576),LL(0xdb3f8bfd,0x418d5425),LL(0x951a1719,0x00424869),LL(0x533b69b0,0x2383c7a8),LL(0xe67a86fd,0x166a38e2),LL(0x5876c435,0xa6baa01c), LL(0x84a208f5,0x574ddc45),LL(0x26b18dbb,0x8cee30b8),LL(0xe9f6b30d,0xeced99c1),LL(0xa7d34bea,0xb638d88d),LL(0x069adedf,0xa4836806),LL(0x7a07c593,0x62beb7ee), + LL(0x724fb94d,0x5093950b),LL(0x8117ff50,0x10782271),LL(0x9f5961d7,0xdc9e34b5),LL(0x2351a33e,0xfaa2fc01),LL(0xd5fc462e,0xb9e0f1d9),LL(0xdd9c6914,0x276a5b3b), LL(0x75365ca5,0xe6136d17),LL(0xa91eed68,0x228b77e2),LL(0x411e4770,0x5cd6a269),LL(0x17590390,0xd8857b0e),LL(0xa0d45faf,0xe7094f3a),LL(0xf40693e4,0xe52d11dc), + LL(0xe5f5b545,0xe96c4aeb),LL(0x2d4c43b0,0x10a85a00),LL(0x32f9151d,0xf86ad2f6),LL(0x302b99e2,0x05daf874),LL(0x14fd3171,0x4299dbfa),LL(0x812cfc62,0x27cbedd6), LL(0xb8772164,0x42e61536),LL(0x6a5423ef,0x52eecef7),LL(0x548fffa3,0xc34c6c70),LL(0x7b6db825,0x1fbed777),LL(0x4ef2989e,0x850bded4),LL(0x815463ee,0x3b8a542c), +}, +/* digit=70 base_pwr=2^350 */ +{ + LL(0x3079fe2f,0x9decf217),LL(0x7c817f6d,0xc32ec570),LL(0xaeb36b92,0xd5649ce8),LL(0x58fb4dc8,0xab9f77d1),LL(0xb52d60cf,0x66b11fb6),LL(0xeaaa4619,0xe217941d), LL(0x1607c412,0xf3522a9a),LL(0xc2a3d8c9,0xea2eba4f),LL(0x25e38722,0x267997c6),LL(0x2d4595ee,0xed5047b7),LL(0x55e5456c,0xaaa41e5f),LL(0x78cfc6fe,0x891e3d12), + LL(0xd7357a51,0xa438634e),LL(0x18c04d59,0x918f14cd),LL(0xac40dd56,0x2ab4dedf),LL(0x4956a5de,0x758e95ee),LL(0x5113f84d,0xfc11e394),LL(0x6059f16c,0x6d71b673), LL(0xfb357c3f,0xfd8e2236),LL(0x32dca873,0xd7c86812),LL(0x8ea13b44,0x02aeb153),LL(0x013d3827,0xde1275d3),LL(0x659ca201,0x470a7b7e),LL(0x5c77b351,0x862c83c5), + LL(0x05084cfb,0xfc9b800f),LL(0x496f23fc,0x1c4d4510),LL(0xc1d08465,0xfea0003c),LL(0x9af48a41,0xf0281da0),LL(0x44d32eed,0xa5c0d971),LL(0x023a2e31,0x2613b73e), LL(0x7dc8ac1a,0x455013c8),LL(0x5958b3da,0x581b1319),LL(0x2290aaea,0xd293f2f2),LL(0x96f6223b,0xa0682564),LL(0x69410ef6,0x38fd18fa),LL(0x2b2cf629,0x74eaf35f), + LL(0xc7ff5b50,0x281f6e58),LL(0xcf9cd114,0xbc67791e),LL(0xfd89abd8,0xe29fa41a),LL(0x7984feef,0xfcb0b0b0),LL(0xd9d20a64,0x0b0928a6),LL(0x6979ccd5,0x2fd385c4), LL(0x1fbe72e4,0xce9c34c8),LL(0xaad0135f,0x69364344),LL(0x50946a5b,0xd4646352),LL(0xf39f53b9,0xb09a97c6),LL(0xdcbc8b64,0x1d47bc20),LL(0xd458b0d6,0xcda5c7bd), + LL(0x87eff3b3,0xad5b8c28),LL(0x9937833a,0xa8a3917d),LL(0x200c3b49,0xbafdc493),LL(0x972c6fbf,0x9e27aac5),LL(0x0518c97d,0xfd292bb2),LL(0x33515a63,0xa62126db), LL(0x1bcfc875,0x9892a8bb),LL(0xe0b674d1,0x93b066b7),LL(0x7fd3d080,0xcde9b008),LL(0x59401ae8,0x1e285a88),LL(0x82cfea96,0x4679e329),LL(0x23e615d3,0x52406ea0), + LL(0x8b6e9462,0x27de6113),LL(0x473464bf,0xb8ade1dc),LL(0x94dacc08,0x911ad493),LL(0x44252cb1,0xd036f28e),LL(0xd13dc20d,0x3865abf6),LL(0xd528f0ba,0xcea487cd), LL(0x4fc290fe,0x14d77eaf),LL(0xc5084101,0x5106533b),LL(0xcda9eccd,0x11001dc7),LL(0x49fc4a78,0xb79ad4bc),LL(0x4567f8a9,0x4f6369f5),LL(0xdf7ab817,0x64050aa2), + LL(0xde07f615,0xffe057aa),LL(0x342700bd,0xf3f91b55),LL(0x27a839f9,0x294761e1),LL(0x80eafe1c,0x6411a2b4),LL(0x0737b80a,0x4900eb12),LL(0xbb73264c,0xa1134d10), LL(0x0ddbf7f1,0x0ebfad73),LL(0xcd1f73ec,0x57bbe692),LL(0xa20f8944,0x675931fc),LL(0xfad2ad19,0x1950eeff),LL(0x9cdf88a0,0x60d30402),LL(0x33fd2c6e,0x121af89e), + LL(0x295c4db2,0x763e3664),LL(0xdbbaa92d,0x632fd676),LL(0xc66b40e9,0x62ab11a8),LL(0xf384b708,0x06244698),LL(0x69197876,0xe7cdf3bd),LL(0x064f8837,0x9cc79c48), LL(0x9486589e,0x95900a22),LL(0x2ff01639,0x7953f6e7),LL(0xdd3e6e46,0x3f65fbbd),LL(0xbaa2e2a0,0x84f52e06),LL(0xe3852824,0x1dc462a8),LL(0x7e4c032c,0x9be69c3f), + LL(0x70977e01,0xa40afc36),LL(0xa6c3b289,0x965f110d),LL(0x805a8491,0xc4952f87),LL(0x0b65e2d3,0xb36804b8),LL(0xe8cf2b2b,0xd3f6f5ac),LL(0xa4b71938,0x0f37a79d), LL(0x489ef671,0xb2f810d9),LL(0x2df23cd8,0x1feae026),LL(0x21a14e4f,0x7412eee3),LL(0x179d51fa,0x1458b8ad),LL(0xe201509c,0x2156a90e),LL(0x72605867,0x39f29fca), + LL(0xb2e066e3,0x231f70ad),LL(0xbb477a19,0xf09db880),LL(0x907e5c63,0xdfa0e503),LL(0xf97022ad,0x12fe09f4),LL(0x20bce7dd,0xdbf06f36),LL(0xf1371cba,0x0140e197), LL(0x64b0b4b0,0x917b6da4),LL(0x20fe3320,0x9a6f4d9b),LL(0xd66bdf87,0x0981d60e),LL(0x62d3487c,0xb430e4e0),LL(0x34dc4a94,0xc3440fb9),LL(0x09a5e3c9,0xe7972dda), + LL(0x93f47052,0x29d63940),LL(0x847e5937,0xadf04e70),LL(0x731bab6f,0xa0ef4fee),LL(0x6ee7d7bd,0x21de3195),LL(0xbd716777,0x99af4a8d),LL(0xdf4c569e,0x9e15c983), LL(0xe94401ea,0x2ec7bc0c),LL(0x85727722,0xda1835ad),LL(0x5dad81da,0x2b5862ce),LL(0x88dddc2e,0xb2be5081),LL(0x1414286b,0xa0248210),LL(0x8ea33f3f,0xc52c436d), + LL(0x3b24e776,0xcc580ea7),LL(0x9d721d6e,0x0f3a8b18),LL(0xb23480cf,0x8665604f),LL(0x34414689,0x95787cba),LL(0x4d10a945,0x425d7c6f),LL(0xb2f1cc78,0xb5ec2626), LL(0x8658de6b,0x55da8885),LL(0xe9aba03e,0xb50919d1),LL(0xd99e417e,0xc64881d7),LL(0xbf28fba2,0x1eeba5aa),LL(0x504eff80,0x20feb7b3),LL(0x50debfb7,0x9f5f9db6), + LL(0x230923db,0x4eb94584),LL(0x7b3a6929,0xba861128),LL(0xab1d6b31,0x5aa7faa3),LL(0x16ae0966,0x95c1e239),LL(0xa2fe2297,0x98674fd3),LL(0x3c42d488,0xa8da0ee5), LL(0xe0740db0,0x103cabac),LL(0x5bf16882,0xf0b860d4),LL(0x289e48ce,0x03cb0cdc),LL(0x9e52c7d5,0x3c15d375),LL(0x98103ca2,0x524f7319),LL(0xc609ffeb,0x828ed65c), + LL(0x83dfb993,0x518f231b),LL(0x37c0826c,0x4b0987db),LL(0xd5177ead,0x0c34961c),LL(0x452c92da,0x9d882d3e),LL(0x8765bced,0xbfeaf558),LL(0xb9962295,0x83957b62), LL(0x7bb084cf,0x2d1d0175),LL(0xe8cffcfc,0x04c4cfcd),LL(0x8d4536c1,0x2f35e33d),LL(0xd83124cf,0xbebb31cb),LL(0xabb29019,0xe342bed2),LL(0x2692a0d3,0x2af0fcde), + LL(0xc7e3b29f,0xece5d865),LL(0x622839dd,0xe58106a4),LL(0xf2969d76,0xf5272d43),LL(0x2a1a240f,0x90c72c1b),LL(0xaf15e14f,0x1e2aa0ac),LL(0xf1b6b5a0,0xfa2f1c7b), LL(0x880224a5,0xfb5d343d),LL(0xf91881c5,0x47b88a84),LL(0xdd142fe7,0x140f5ee9),LL(0x24b37c44,0x4e76982e),LL(0x578b482b,0x6aaf61e9),LL(0x765bc4e2,0x01950e22), + LL(0xe8a2e8f0,0x20ebf79c),LL(0xaca418a2,0xec040d0d),LL(0x8d630d2a,0x016c07e7),LL(0xfa605dcb,0x20021d57),LL(0x42d04705,0x6190f3e9),LL(0x8974b7e6,0x4e000df5), LL(0x5abcedac,0x6710da6c),LL(0x5f95d37c,0xf31aa496),LL(0xa5830899,0x192c4b8b),LL(0xea7dbcdd,0x171ab8c4),LL(0x8cdf1097,0x715f6081),LL(0x205d10ed,0x0e0135bf), +}, +/* digit=71 base_pwr=2^355 */ +{ + LL(0xc8d2bf7b,0xd2db4d35),LL(0x81571d06,0x52105d09),LL(0x723a57bf,0x447565cc),LL(0xd8ded62c,0xd98c3597),LL(0xde2f1a9e,0x0aeac6d9),LL(0x0a98d3b2,0xd363b0b7), LL(0x02ad9933,0xd9708f07),LL(0x64f5809d,0x93346775),LL(0x49cda010,0x499332cf),LL(0x858467e2,0x546df74a),LL(0x93748e8e,0x8b84a550),LL(0x06f09073,0x9e88ef97), + LL(0x52133095,0xc0a40cac),LL(0x93c162bb,0xfe1b22fd),LL(0x34018741,0x8625898c),LL(0x36d9e57a,0x69c9f3f6),LL(0x378aa211,0x69d9d7f3),LL(0xe7dca168,0x6b03f897), LL(0xf997a48f,0x24d49aeb),LL(0xc149ac40,0x1d984c67),LL(0x576f533f,0x667c1d01),LL(0x9ef82ece,0x372eee19),LL(0xc207c14d,0x577723c0),LL(0x0eed37f6,0x4225907a), + LL(0xc5a5a001,0xb8623f36),LL(0x86878b74,0x21847b80),LL(0xd05ac443,0xd19f57f6),LL(0xb9f8acec,0x9bd22882),LL(0x2b41b60a,0x128186d8),LL(0x71980fd1,0x1772e6b0), LL(0x812dfff5,0x22c5ee68),LL(0x7f952796,0xccbd2fe2),LL(0x7da6d35a,0x0d49bfde),LL(0xc249f319,0x348b48db),LL(0xc16a8c0f,0xdb376657),LL(0x002cf8b4,0x28ef362a), + LL(0xbc0e0903,0xc61db977),LL(0x645c32fb,0xbaf6e4da),LL(0x060b1adb,0xce89b8ca),LL(0x88e2c178,0x41db4481),LL(0x923bdd3c,0xba6339f3),LL(0xd29db42c,0xff25b818), LL(0xe6d6b35d,0x3521116e),LL(0xb22f16ac,0x4e1bd283),LL(0xbd79fe5d,0x9357c984),LL(0x9d45eee4,0x2eda73be),LL(0x6288e01f,0x1a50c59f),LL(0x75018873,0x37baf649), + LL(0x751f66f6,0x431ea808),LL(0xf1b8e577,0x06feeefa),LL(0x488a8eee,0xd109d9f0),LL(0xc69843c5,0xeb826b96),LL(0x8b42da29,0x972272e9),LL(0xa137ee9c,0xa9ea9ad1), LL(0x25163be5,0x0385aa95),LL(0x34c32f2b,0x963e9640),LL(0x4dfd935a,0x9067aa89),LL(0xbc3f5f3c,0x6ab23131),LL(0xf302e0e1,0xb96c3406),LL(0xd65f811a,0xc8caad4e), + LL(0x750261dc,0xf323953b),LL(0x38552a8c,0xb8563bf1),LL(0xbd32cb8c,0x2937dfd9),LL(0x7ecf3538,0x07c4e563),LL(0xb6399415,0xb573960e),LL(0xdd1a4a06,0xc1ced6c1), LL(0x787ddf7a,0xc625f400),LL(0x1ce6778f,0xd998c28b),LL(0x6220f24d,0x66c51e5b),LL(0x27d01c6f,0x9f97d758),LL(0x0412372d,0x60b15724),LL(0x04d55048,0x2253abc1), + LL(0xfad177ed,0x15952eb8),LL(0x05058d9f,0x57aaf91d),LL(0x8ab1b9d9,0x268ba730),LL(0xd5b8f86a,0x7decfc47),LL(0x0879ab02,0x596353e7),LL(0x9a68d5a4,0xa3ff2311), LL(0x7534fb5a,0x257c68a1),LL(0x160ec5ea,0x84f7c9de),LL(0x6754185f,0x1b2b770c),LL(0xa74562f7,0xf321ac71),LL(0x264a1961,0x28bf0a15),LL(0x86a033ae,0x0093db73), + LL(0x097f322f,0xc552c6c6),LL(0x8bc06287,0xdf59a302),LL(0x19610b0c,0xc9ed375c),LL(0xb051dad5,0xf0e7b4eb),LL(0xc6556643,0x7267a304),LL(0xc96dc1d8,0x0044f6d8), LL(0xf4fc3725,0xf0ed5f9a),LL(0x9de8e1ff,0xbbaf9f2c),LL(0xaf5a4b4b,0xef5d66f4),LL(0x20644cf2,0x0b5bed3d),LL(0x75ae23c0,0xf7e4543a),LL(0x41325b66,0x696f60dc), + LL(0xcfc0dd38,0x4fd0b582),LL(0x55b7b68a,0x47fd984f),LL(0x699460ec,0x2722a0cb),LL(0xfa26d4c4,0x81b4afd8),LL(0x941c86e4,0xb921d0d5),LL(0xef4db114,0x7208f094), LL(0x17ddadf8,0x2997f43c),LL(0x21bc290d,0xd1aabdea),LL(0x86182be1,0x64e20e00),LL(0xcbddb8eb,0x9bd11568),LL(0x3ba0e6b5,0x639db1d4),LL(0x429a6b4f,0xb99b11fb), + LL(0xaaa48cd8,0x04ef7ad5),LL(0x8a8ac319,0xb97a6501),LL(0x47591d88,0x9ae38a6a),LL(0x6902edb4,0x27d91254),LL(0x812b143a,0x5dae3d83),LL(0x93a2fdf6,0x02ee1353), LL(0x72410377,0x07a00389),LL(0x56e10c82,0xa2fbd343),LL(0x72b1bcb9,0x3fd6c171),LL(0x2d0033c7,0xa8d70f93),LL(0x2916c28a,0x9ea9eea3),LL(0x423edad7,0xecb7e486), + LL(0xc515bacf,0x5525fbb0),LL(0xa2aa22ba,0x48a72394),LL(0x0b9e3fe3,0x9bcd64c9),LL(0x1975aa86,0xe9e11d17),LL(0xc9dbdaac,0xa435bbf0),LL(0xe30c8911,0xe8451f6c), LL(0x5bc2d12f,0xa1706d89),LL(0x406d4883,0xfe73ff43),LL(0x49d5739c,0xb713efc6),LL(0x05c1ec9a,0xdfd0bbf8),LL(0x5e6b3bd0,0xde17c52c),LL(0x5be196af,0x57e06034), + LL(0x2c20f868,0x9949b33d),LL(0xb5706250,0xdb3aa790),LL(0x88e17f2b,0x88ce71e7),LL(0xda9c0881,0xd851baf2),LL(0x86d8c9e9,0xe869c5ba),LL(0xa01425b6,0x1af68d65), LL(0x9bbd3963,0xeae8b1c6),LL(0xec087425,0xf34900b1),LL(0xc374bb96,0x14942910),LL(0x05487483,0x3e13c457),LL(0x35bc6ee1,0xe0e6fad4),LL(0xb54d247b,0xc7c38dc7), + LL(0x8bd92789,0x420dd8f6),LL(0x4ce541dd,0x3831b0e9),LL(0x31ed7f7f,0xbde477e4),LL(0x29c5557b,0xb46eb7f2),LL(0xc56940e0,0x00a07499),LL(0xabacf00e,0xabb9d567), LL(0xc5ba9d0c,0x9f63b87d),LL(0x708d4f4c,0xf4c5c4a3),LL(0xde7fcf63,0xdbde9879),LL(0x616cf5d6,0xbe88f949),LL(0xd1aa38be,0x17560674),LL(0x9c436175,0x160ec365), + LL(0xb9bd0afb,0x9c85e50a),LL(0xd26ac425,0x2b66a1c0),LL(0x807f33db,0xcb78ce81),LL(0x3db81e06,0x9d337d8a),LL(0x72638d70,0xe223eae4),LL(0x6bf2ebab,0x7f9ea217), LL(0x9b634059,0x2804b59c),LL(0xf3dc8d46,0x1043fbf4),LL(0x7bc6949c,0x321eca1e),LL(0x8f051155,0xbf2906c0),LL(0x9c539f40,0xb802a328),LL(0x073cd808,0x08bcca20), + LL(0xcea8bf63,0x08cb6315),LL(0xb59ee7fa,0x7ac2699d),LL(0x8d1601e0,0x4cd2c8a9),LL(0x7b90d9c3,0x6d7188e3),LL(0x6bfe73d3,0x63486716),LL(0xcf9f30b0,0x49ed7faa), LL(0xc9515fd6,0xf7edf5d6),LL(0x8a8ae607,0xbb3ab848),LL(0x21c5c388,0xe6e6b209),LL(0x5b1e03bc,0x5dca0a1d),LL(0x94a8b174,0x15670f59),LL(0x68c27a97,0x6f79e381), + LL(0xab463fa6,0x6d34bdf6),LL(0x0093b9cb,0x7bb127b6),LL(0x5a3bfdd0,0x61d05113),LL(0xf1296bdd,0x4abab575),LL(0x4d2e9a7c,0x72da6849),LL(0x8d11f03d,0x90267bca), LL(0x3e9b310b,0x47811122),LL(0x1b1920cd,0x8ffe91d3),LL(0x7521898e,0xec293ec6),LL(0x96c1da75,0xf0cf0269),LL(0x80f2c7b3,0xb0dbd4c3),LL(0x34e4baf8,0xe5281755), +}, +/* digit=72 base_pwr=2^360 */ +{ + LL(0xdd14d47e,0xc32730e8),LL(0xc0f01e0f,0xcdc1fd42),LL(0x3f5cd846,0x2bacfdbf),LL(0x7272d4dd,0x45f36416),LL(0x5eb75776,0xdd813a79),LL(0x50997be2,0xb57885e4), LL(0xdb8c9829,0xda054e2b),LL(0xaab5a594,0x4161d820),LL(0x026116a3,0x4c428f31),LL(0xdcd85e91,0x372af9a0),LL(0x673adc2d,0xfda6e903),LL(0xa8db59e6,0x4526b8ac), + LL(0xcecb916f,0x51a033a5),LL(0x8d7de61c,0x2ac62f63),LL(0xa42a266e,0x92eece49),LL(0x82c4d11e,0x87e037db),LL(0x6fbae08a,0x875be141),LL(0xc539478c,0xf348fe26), LL(0xff94c01e,0x51f8b907),LL(0x19695a9d,0xc46cc0e0),LL(0x6c51b9c2,0x2c74bd66),LL(0xee565de8,0x635d3d24),LL(0x8982c8c3,0x6bd65663),LL(0xdaf6a93c,0x5c345b79), + LL(0xe23a8472,0x68fe359d),LL(0x4ce3c101,0x43eb12bd),LL(0xfc704935,0x0ec652c3),LL(0x52e4e22d,0x1eeff1f9),LL(0x083e3ada,0xba6777cb),LL(0x8befc871,0xab52d7dc), LL(0x497cbd59,0x4ede689f),LL(0x27577dd9,0xc8ae42b9),LL(0x7ab83c27,0xe0f08051),LL(0x2c8c1f48,0x1f3d5f25),LL(0xaf241aac,0x57991607),LL(0xb8a337e0,0xc4458b0a), + LL(0x210c3144,0x179c59cf),LL(0x33eebbc4,0xfb613c57),LL(0xba0cf384,0xdda75cfd),LL(0x3a8fbafa,0x94081a5b),LL(0x33384e0b,0xb91de90a),LL(0x27aa2a45,0x7d1f8f40), LL(0x62031148,0x0747bcc1),LL(0xf324160b,0xd2db8e39),LL(0x722484f0,0x9c1ce3e9),LL(0xa62d1dda,0x13a7ee5d),LL(0x3a963bce,0x77fd7934),LL(0x83d2f21b,0xcd3d8717), + LL(0x51dd1ba9,0x3dbb3fa6),LL(0x545e960b,0xe53c1c4d),LL(0x793ce803,0x35ac6574),LL(0x83dbce4f,0xb2697dc7),LL(0xe13cf6b0,0xe35c5bf2),LL(0xb0c4a164,0x35034280), LL(0xd9c0d3c1,0xaa490908),LL(0xcb4d2e90,0x2cce614d),LL(0x54d504e4,0xf646e96c),LL(0xb73310a3,0xd74e7541),LL(0x18bde5da,0xead71596),LL(0xaa09aef7,0x96e7f4a8), + LL(0x2d8bcd6e,0x609deb16),LL(0x2591750d,0xe42f23a9),LL(0xb378305c,0x4a9f3132),LL(0x69275f5e,0xf1017998),LL(0x61b089b5,0x14be7467),LL(0x0c81b0c5,0x05f620d2), LL(0x6cb8412e,0xca90a9c0),LL(0x15b1b0d5,0xfe0f6a89),LL(0x20c71988,0x1b25ac96),LL(0x390aedd0,0xb971b61a),LL(0x79d8cd39,0x995214d7),LL(0x65c6e11a,0xd7fa135b), + LL(0x5d6e5f48,0xa8393a24),LL(0xf9175ce8,0x2c8d7ea2),LL(0x55a20268,0xd8824e02),LL(0xa446bcc6,0x9dd9a272),LL(0x5351499b,0xc929cded),LL(0xcfe76535,0xea5ad9ec), LL(0xdc32d001,0x26f3d7d9),LL(0x43eb9689,0x51c3be83),LL(0x759e6ddb,0x91fdcc06),LL(0xe302b891,0xac2e1904),LL(0xc207e1f7,0xad25c645),LL(0xab3deb4a,0x28a70f0d), + LL(0x0f3ff12d,0xa13f19b4),LL(0x019564aa,0x57ee08b1),LL(0x7044a6f4,0x00ec0c99),LL(0xdca1075c,0xaf5665f8),LL(0x0620ab0c,0xded5ca3f),LL(0xa896deff,0x9b2cb8c7), LL(0x07df2345,0x032ab2b3),LL(0xf1da3f88,0x964d109e),LL(0x25133304,0x2286b6f7),LL(0x977a4567,0x0d16d531),LL(0xf1abae4f,0x00a66036),LL(0x95f0103b,0x5debab1d), + LL(0x03bea8f1,0x922d7f97),LL(0x584570be,0x3ad820d4),LL(0x3cd46b43,0x0ce0a850),LL(0xae66743d,0x4c07911f),LL(0xfda60023,0x66519eb9),LL(0xec2acd9c,0x7f83004b), LL(0xc3117ead,0x001e0b80),LL(0x0722ba25,0xbb72d541),LL(0x6e9a5078,0x3af7db96),LL(0x701b6b4c,0x86c5774e),LL(0x37824db5,0xbd2c0e8e),LL(0xbfac286d,0x3ae3028c), + LL(0x5fb7c5a8,0xfd1b413f),LL(0x0206cba1,0x6152b9de),LL(0xd8f51960,0x487f8e3a),LL(0x033ca1bc,0xac34a23c),LL(0x60258d55,0x90bba98f),LL(0xbd9098f2,0x30421acf), LL(0x89c0ce44,0xd9c601f9),LL(0x2f2f1af1,0x621bda83),LL(0x38c45441,0x14fa7ef6),LL(0xe47faa31,0xbd5dc10f),LL(0x74eeb6a1,0x9dce0dcb),LL(0x06346849,0x2cca3e66), + LL(0xa33e071b,0x83d4d4a8),LL(0x61444bb5,0x881c0a92),LL(0x520e3bc3,0xeea1e292),LL(0x2aaab729,0x5a5f4c3c),LL(0xe63c7c94,0x0b766c5e),LL(0xbb2cc79c,0x62bb8a9f), LL(0xaa5dc49d,0x97adc7d2),LL(0x31718681,0x30cc26b3),LL(0x56e86ede,0xac86e6ff),LL(0xcd52f7f2,0x37bca7a2),LL(0x9ce6d87f,0x734d2c94),LL(0xc2f7e0ca,0x06a71d71), + LL(0x20066faf,0xcdb67ea9),LL(0xc7fb7154,0x929b4d2a),LL(0x7fdeb411,0x5842d968),LL(0xafe55cb9,0x2ddf764a),LL(0x47df3cf4,0x608bf76f),LL(0x5984e339,0x1862463b), LL(0x944d22a2,0x7feea86f),LL(0x281f2b84,0xf8562c30),LL(0xbd358ea4,0x332a54d2),LL(0xe7fe1ede,0xa54dec9f),LL(0x932264d4,0x9c8e52a4),LL(0x89817f5b,0x428acd1a), + LL(0xc6357d33,0x559dcf75),LL(0x652517de,0x4616d940),LL(0x1ccf207b,0x3d576b98),LL(0x1979f631,0x51e2d1ef),LL(0x06ae8296,0x57517ddd),LL(0xd6e7151f,0x309a3d7f), LL(0x0e3a6fe5,0xba2a23e6),LL(0xd28b22c3,0x76cf674a),LL(0xf8b808c3,0xd235ad07),LL(0x6b71213a,0x7bbf4c58),LL(0x93271ebb,0x0676792e),LL(0x05b1fc31,0x2cfd2c76), + LL(0xeda2fa8f,0x42aeebc4),LL(0xe77a9c5b,0xda91ada3),LL(0xc585a572,0x29b9d55f),LL(0xa256353d,0xb0e52414),LL(0x29adbd21,0x1d0e7d5f),LL(0xd057d175,0x7ee5ff9c), LL(0xc9097bf9,0x0bf76fcf),LL(0xfe09f5b3,0x023170f8),LL(0x0799f989,0x8a67c124),LL(0xc6a20819,0x4ce28eeb),LL(0x79502d13,0xfc1d7c91),LL(0xde43f895,0x7922d2d9), + LL(0x37a450f5,0x4258e5c0),LL(0x52d2b118,0xc3245f1b),LL(0x82bc5963,0x6df7b484),LL(0x9c273d1e,0xe520da4d),LL(0x2c3010e5,0xed78e012),LL(0x3c1d4c05,0x11222948), LL(0xc692b490,0xe3dae5af),LL(0xc197f793,0x3272bd10),LL(0xe709acaa,0xf7eae411),LL(0x778270a6,0x00b0c95f),LL(0x220d4350,0x4da76ee1),LL(0xab71e308,0x521e1461), + LL(0x96230a58,0xf2cdae31),LL(0xf304e1ea,0x47cf36b4),LL(0xd750b29b,0x9d14f25a),LL(0xdba15f3e,0x931b9c65),LL(0xbf9fe2dd,0x34db169e),LL(0x52663433,0x8a89e47c), LL(0x026ec31f,0x8859a4f8),LL(0xa913ceea,0xeeb703ea),LL(0x67ac4db7,0x74638d6a),LL(0xbe25d755,0x5c8ea7b2),LL(0x38db10ee,0x8a0f0a87),LL(0xe890bcd3,0x96a26bac), +}, +/* digit=73 base_pwr=2^365 */ +{ + LL(0x64a5e869,0x883533af),LL(0x6973ec23,0xaaa778c2),LL(0x46d0fcf3,0x8f0b5fb5),LL(0x4ab05da7,0x7e6b0a0a),LL(0xc67b6614,0xcd91a869),LL(0x6c6f7cf2,0x7de9f2ff), LL(0xd1ec14c3,0xc072a106),LL(0x42a128ee,0x3f4b9606),LL(0x8f0ce946,0x7378192c),LL(0xd1149441,0xdf2e7b9f),LL(0x14ccf45a,0x4fa17cb6),LL(0x45f03568,0x575680e9), + LL(0x8f458c68,0x8b70e94f),LL(0x4160ecc7,0x29272654),LL(0x4d3ef22f,0xe22219ba),LL(0x1999f948,0x7f8a712a),LL(0xabfe7302,0x25575e96),LL(0x564a1af0,0x21c6ffc6), LL(0x7e8500da,0x045e9c66),LL(0x04ef8ea6,0xef7c3cf7),LL(0xc3db161a,0xdd23b825),LL(0xba33a906,0x05fb173a),LL(0x870e41f2,0x9a8b5ecb),LL(0xccc30d1d,0xf3d9db0b), + LL(0xe873ff0f,0xd9243926),LL(0xf20b0e49,0x2e2a5ab6),LL(0x0e35f201,0xa1bcfeee),LL(0x196f23f3,0xd25be5f3),LL(0xffc1d068,0x298c67f2),LL(0x0c3d950b,0x77dae55c), LL(0x8822c996,0x5e15ab99),LL(0x83f60a98,0x52de2e6d),LL(0x47a7e269,0xa9f82ec9),LL(0x2ac22e49,0xf02af9a2),LL(0xa706f090,0xdfb3103f),LL(0x3cf8dcb0,0x12559962), + LL(0x88ad12b2,0xb7b85625),LL(0x1e44b254,0x81f5958b),LL(0xc91b8ffd,0xb4ebddd5),LL(0x55d38511,0xef815ae1),LL(0x1b0da525,0x98587d55),LL(0x34a9ebbd,0x1d418177), LL(0x1e6057d7,0x844811fb),LL(0x76e5976d,0x0c169771),LL(0xf623789b,0x4b268bb4),LL(0x40498058,0xb26ae5be),LL(0x3c2b435a,0xb47a5ded),LL(0x8fceceb3,0xe15a684b), + LL(0xd09dc3c8,0x122a3eed),LL(0xaefe0819,0x6a19907f),LL(0xda325339,0x057aafa1),LL(0xd42a5345,0x138033bd),LL(0x1a065ebe,0x8ac206af),LL(0x25c31ed6,0x0a46f5ae), LL(0xd7e379db,0x7fc577a9),LL(0x69dcee54,0xc6df6943),LL(0xa8336bc1,0x4c167ba2),LL(0xf3a1339c,0x0fbd9708),LL(0x226f612f,0xc6b8c01f),LL(0xd51332e1,0x5d4ed789), + LL(0x5a1abcd8,0x26aa2c2e),LL(0x9609d9d8,0x2b16a12e),LL(0xa2bee00c,0xe485a551),LL(0xf4f2292e,0xfa28c30b),LL(0xb7358f1b,0x99abef78),LL(0x10a276a1,0xda6b3cdf), LL(0x47c03f71,0xbd3858b7),LL(0xb22d05d1,0x4f0bf5f0),LL(0x8250f760,0x2d80f5d2),LL(0x8cd9666c,0x060f9b27),LL(0xb1b014a9,0x6a6c40b0),LL(0x8c440a9e,0x44537af3), + LL(0x76faaca5,0xb564cfd6),LL(0x920dd223,0x8a6e3925),LL(0xa590a383,0xee59a140),LL(0xa1922ad9,0x9e29b552),LL(0x60a0da63,0x604367de),LL(0x92c35fd0,0xc498aca5), LL(0x250ed8a0,0x74135082),LL(0x6c7c3e77,0x5d109d1a),LL(0xc63dff94,0xf9e2d84d),LL(0xf7aa2b0e,0xca50f5e4),LL(0xd543d389,0x7cba9e87),LL(0xd8fd1292,0xaf5fbbef), + LL(0x4fc11c3a,0x70765683),LL(0x66aac4d1,0x53a94031),LL(0xa6db6169,0x2a935ef0),LL(0x2032d599,0x00292761),LL(0x3a6f1316,0xb5babb2d),LL(0xdb26af51,0x601a7dfa), LL(0x1322d983,0x00c34013),LL(0x2bb507c5,0x45b062ec),LL(0x0f9b3656,0xa1bbe2ed),LL(0x34031d18,0xe17a5d49),LL(0xf8fe1224,0xe3661047),LL(0x623c6cf5,0x0e4f3b3d), + LL(0xca45cccf,0xffaac084),LL(0x061ffe3c,0xaea5cc3d),LL(0xb355f387,0x7c5d7c60),LL(0x99cba92d,0x4bbb2a0c),LL(0x2f7768d6,0x6b4ba3ef),LL(0xcc5f9c40,0xc7484ed2), LL(0x52b57a7e,0x5d4e92fc),LL(0xca2c200b,0xba9f16c4),LL(0x3797ccba,0xebe02a8a),LL(0x38c4133a,0xb6b3f421),LL(0x8153d033,0xad5d85b6),LL(0x5714f269,0x782d6ee8), + LL(0x9c0cf752,0x7845b696),LL(0x5a732acf,0xb82d052b),LL(0x1262877b,0x7760564c),LL(0x8ecc7aa5,0x29b3c57a),LL(0xdf1ebbed,0xb58eccb0),LL(0x3c3a3303,0x86fc1544), LL(0x13060f0e,0x44761ddf),LL(0x7371a5a8,0x5a3dacfd),LL(0xf7cbc2bc,0x846f6faa),LL(0x368caabf,0xf5e098b0),LL(0x10c08769,0xe23ea107),LL(0x1563fcda,0xbc5df1db), + LL(0x142d8955,0x65c3a54e),LL(0xe7814f25,0x5c6583cc),LL(0xd924dc7d,0xbd5a07d8),LL(0xc28f6e8e,0x9f717bd9),LL(0x3b6540a7,0xa0c4ec4e),LL(0x142b3283,0x3153bb2b), LL(0x9b296946,0x53bf403c),LL(0xb1cdb6d2,0x659a828a),LL(0x1369af19,0xe9517d81),LL(0x8990e7a0,0xd8c7a099),LL(0xe535cd04,0xbaa9f59d),LL(0x0f269551,0xbb0cc68e), + LL(0x6a78c6e5,0x3c00ac52),LL(0xdefaa52c,0x9c61aca6),LL(0x39794a09,0x00341289),LL(0x41cd7c0a,0xe08910d1),LL(0xa732e3bc,0xa58ffbb6),LL(0x91fe8fd8,0x87bf51ab), LL(0x4a59e2be,0xc4f4f267),LL(0x438071c8,0xdeb512c7),LL(0xe9cd290b,0xddf82842),LL(0x6ae85fe0,0x3e17311d),LL(0xb41be881,0x6e9236a9),LL(0x53555ebf,0xbb9ddf98), + LL(0x09f3f0be,0xccc163ea),LL(0x6a5b0a63,0x9932b56f),LL(0x9c69668e,0xf89fae91),LL(0x5ce13021,0x555f9821),LL(0x37037aa9,0x4b02693f),LL(0xbde50f35,0xc4afee79), LL(0x02aa6c7a,0x4b0919c2),LL(0x991e15e9,0x3166de2a),LL(0x7077fb38,0x284baa3e),LL(0xa116ddec,0xbb7a6416),LL(0xb7636772,0xe8c89547),LL(0x0ef92c54,0xff940362), + LL(0xe2ce6008,0xd5d81275),LL(0x0b3b9d10,0xc45bdf25),LL(0x6cbc83e2,0x15ab5da3),LL(0xc52a66cb,0x85a18cf8),LL(0xb042c047,0x77e202b8),LL(0xe7e7997e,0xc4dc3de2), LL(0x995fa67a,0xfe9335b1),LL(0x75b96a00,0x809e161d),LL(0xa0c3baea,0xfb03c2a5),LL(0x888c2f77,0x5c7e0523),LL(0x87ad10e2,0xa8fda1c8),LL(0x858a3577,0x90484f78), + LL(0xf9fde126,0x49e41f0a),LL(0x3613d3c2,0xec960044),LL(0x10421d3b,0x2c62a49d),LL(0x8131a0d8,0xe2402464),LL(0xbdf794fc,0x8a7ce188),LL(0x4665b1b6,0x704dea7d), LL(0x4d57c6ba,0xbdb9c18e),LL(0xf669b3c0,0x5288a053),LL(0x78a5e252,0xbf7d01b8),LL(0x26b9cb7d,0xb26cccf9),LL(0x84326c47,0x14191a32),LL(0x91f8425b,0x460ff747), + LL(0xbd27be7b,0x59367582),LL(0x1ab2c596,0x92bf5bbc),LL(0xf6a27741,0x5d96351a),LL(0x7f929e0d,0xeab94db8),LL(0x043f1afb,0x865ba011),LL(0x5fb631dd,0x43acea12), LL(0xb2fd1436,0x192e0652),LL(0x7b38d121,0x44f22ff1),LL(0xb7cae5f6,0x7bcc228d),LL(0x6a828b03,0x02eaeccd),LL(0x91f301aa,0x7c48a2ea),LL(0xf5eb1a07,0x1e090717), +}, +/* digit=74 base_pwr=2^370 */ +{ + LL(0x941948e3,0xdf0ae8df),LL(0x1d010bcd,0x123fee90),LL(0x1dd28691,0xde3717ca),LL(0x709b678e,0x0c1db879),LL(0x400acdc6,0x0288959a),LL(0x5ca2d03a,0x66c69181), LL(0xdbbb75de,0xe52534b3),LL(0x3de927cf,0xe914938c),LL(0x73eece30,0x1a9a34f8),LL(0x642a6799,0x0fb0c7bd),LL(0xeaa7e8a8,0x375cc0cf),LL(0xd00ec238,0x75fb9eb5), + LL(0xb72958eb,0x9ca8cc9d),LL(0x1014f562,0x3c8cd0db),LL(0x059b2bba,0x72115d53),LL(0x730e5dc3,0x8fe7ac30),LL(0x841d8998,0x4e67ef69),LL(0xc8ed37a5,0xfb6439ff), LL(0x26df84c4,0x48164b3e),LL(0x365bc99e,0x37d492ad),LL(0xbeed38ce,0xb7fd4643),LL(0xa3e30b3d,0x993cfa9f),LL(0x01ddd484,0xdcc5e7af),LL(0x6840175d,0x5edf3ac0), + LL(0x0c19c625,0x3ee87e54),LL(0xf4a10f9a,0xe4ae611f),LL(0x0aec21e5,0x27d65512),LL(0x8bea1b16,0x737578f5),LL(0x5fb7a3a2,0x6e2b6bf7),LL(0x14f65000,0xecc59251), LL(0xb8dd544c,0x53e1167c),LL(0xc5862fdc,0xee60e60f),LL(0x6cccabeb,0xc86582cf),LL(0x8b4d37c6,0x849fc15d),LL(0x8f4a87bc,0xaa7960ad),LL(0x3b7f0a6d,0x17fe1082), + LL(0x51d33c11,0x79768e9f),LL(0xa4b24889,0xeec34505),LL(0xbe0c67d7,0xc194821b),LL(0x6909fdfc,0x537a6a4a),LL(0x95ccdda7,0xae6d7051),LL(0x92b3926c,0xed4b7222), LL(0x6b24a3d4,0x2c5dd6af),LL(0xe4386095,0x9282ec39),LL(0x397a3bd3,0xdd3c7388),LL(0x8baf59c2,0x9d176c6a),LL(0x380ec958,0xd5c6219e),LL(0x54e8e315,0x194fc116), + LL(0x79650de1,0x3c67c65c),LL(0x00bfb2ac,0x8e2a220b),LL(0x42f02a3d,0x59d225dc),LL(0x5d60e54f,0xc52ce4b2),LL(0x3f306112,0x8894e3cb),LL(0x50d85aec,0xb78a037b), LL(0x2d85f328,0xeeeb3b40),LL(0xe0406ddd,0x3d391b37),LL(0x0502141b,0x5273ebe9),LL(0xe092bfeb,0xd17023e7),LL(0x282f5aed,0x04564385),LL(0x55d82356,0x7e55a4e2), + LL(0x01ec1432,0x0b7576f9),LL(0xabc5f603,0x84b30eec),LL(0xf4a84b7a,0xdaaf7ba9),LL(0x3bb37a99,0x9e3a5daa),LL(0x80378cff,0x56bd9648),LL(0x8e6ed856,0x2fdeeeb7), LL(0x3c81ac34,0x079014a7),LL(0xb4211c27,0xf8de4004),LL(0x7fe4391e,0x0cee3df9),LL(0x2fd2fc38,0x441aa7fb),LL(0x4d1b575a,0xeba7be86),LL(0x231c2d01,0xca2fb5b7), + LL(0xd205869c,0x8307bc81),LL(0x9388e917,0xdd282809),LL(0xbb572a87,0xdd4cb2de),LL(0x14f0db39,0x5a41595d),LL(0xf4e5c71e,0xd5db5f59),LL(0x4a87f672,0xcc9c9f6f), LL(0x012e65ce,0x4ddce8c3),LL(0xab3a94d3,0xaae28eaf),LL(0x0b333aba,0xd4b95011),LL(0x914eb476,0x3e171506),LL(0x69bbfa63,0x109ee9ab),LL(0x5dff5471,0xbddba098), + LL(0x463a8251,0x0683349e),LL(0x5103e72c,0x97dc4f47),LL(0x50663b9e,0x47c71810),LL(0x9733dac6,0xf327d149),LL(0x292137c5,0x03f55e4a),LL(0xda59e1c7,0xccc6232a), LL(0xadc59cb8,0xbaa8b4dd),LL(0xfe7486e4,0x45370d35),LL(0xb0322df9,0x99a88c1d),LL(0xfd69954f,0x394440a7),LL(0xa5a29889,0x9060473d),LL(0x2f04864a,0xc8ca43e3), + LL(0x9451d422,0xf08c8efc),LL(0xba846ac3,0xc8beae41),LL(0x807df062,0x0157f46c),LL(0xdeaada6a,0x080eac20),LL(0xa3bfddd0,0xdf146f3d),LL(0x617d19d7,0x8ed7c2c6), LL(0x40439488,0x314ea3e7),LL(0xb3e6806f,0x544132c7),LL(0xa215a3a2,0x9b9bb477),LL(0xe33f80b0,0x9310fee9),LL(0xe71769af,0xf277895c),LL(0x7d99d5b9,0xe8218e1a), + LL(0xdd8b9644,0xd5c7241a),LL(0x993116d2,0x45a5f2d1),LL(0x823048df,0xbacacd4a),LL(0x2568547a,0xa278fa04),LL(0xbff72820,0x3a4f2482),LL(0x13e4314a,0x1305d1a7), LL(0x34ba28e3,0x9d84c333),LL(0x6a32fb41,0x9995b5bb),LL(0x520946d8,0xb0f75f3c),LL(0xde98aa63,0xd7c4b8b7),LL(0xba856b6b,0xee5efcf3),LL(0x3324ed66,0x36af3368), + LL(0xbb2af5fb,0x29c741c3),LL(0x89e6241e,0xb9c92da6),LL(0x474b7c0f,0x07dace3c),LL(0xd996b6a8,0xd0b3f9bc),LL(0x07c662de,0xe97e3847),LL(0x6c851030,0xbf6d1e05), LL(0x99f1aade,0x150c5e93),LL(0x9bd848d5,0x9c1e2351),LL(0x09cab3db,0xeb808a55),LL(0x9a49916f,0x1bfbe08d),LL(0x64ab0e4e,0xc6a70ea7),LL(0x7823f505,0x77d189f2), + LL(0x5827fe2c,0x90762c1f),LL(0xeaffda88,0x20160f7a),LL(0x5c47c645,0x7420849f),LL(0x6d72e748,0xb0823195),LL(0x8ee11773,0xaeac683b),LL(0xfb5c550e,0x8c2a0a79), LL(0x6c07cc1e,0x6d986d69),LL(0xba8398b9,0x57269140),LL(0xd94d5223,0xd13e136f),LL(0xed5b01c6,0x1aa75419),LL(0x408fcdcc,0x7c2014b1),LL(0xcffde5ee,0x0680a985), + LL(0x23133885,0xfbe88fce),LL(0x7c5a5c4b,0x3c2e3669),LL(0xbbacc6e1,0xe36cf261),LL(0x96ae3cad,0xa72c7bb1),LL(0x4cb1a375,0x08e37103),LL(0x2a02baee,0x5521f445), LL(0xc157e471,0xda9329ba),LL(0x68470808,0x3f90cad1),LL(0xa657de60,0x24182208),LL(0x67c10d1b,0x17c082b7),LL(0x9928d6fd,0x9e222648),LL(0x36ced38f,0x1578c895), + LL(0x42c5a7ee,0x92fc9a33),LL(0xf9f0ed71,0x8768614a),LL(0x87ebfb66,0x1ea5f7ed),LL(0xd361069c,0x296852de),LL(0x0192498e,0x1cec6f1a),LL(0xa9cca3aa,0xbfd4858f), LL(0x2ef240e8,0xfba98c24),LL(0xab635d9f,0xc8b500e4),LL(0x913a3edd,0x9f49c572),LL(0xd42b2d4d,0xe6181f93),LL(0x6aa77fa3,0xf96b5db2),LL(0xe43558d8,0xdfb2241f), + LL(0x7481cd31,0x8f8a1964),LL(0x17b37aa7,0xd5b8197e),LL(0x7ac0dbf6,0x7cfbcd19),LL(0x93662f46,0x4ecd8954),LL(0x0501365f,0x104a090d),LL(0x7f097083,0x828694cd), LL(0x6dc105dd,0x60b865f3),LL(0x85cd4ed7,0x00549f1b),LL(0xcc197cc9,0xd262e38b),LL(0x9a262b4f,0x5d3271de),LL(0xa953d539,0xc7df47e9),LL(0x5b9a86a6,0xab8f1c8a), + LL(0xedee15a5,0xc7d0abb2),LL(0x228cc4a1,0x72dc0105),LL(0xa80767de,0xeb67defc),LL(0x71820908,0x6fa174d8),LL(0x5674d19a,0x3215df48),LL(0x960a081a,0xf944531a), LL(0xef2cce62,0x93ed7180),LL(0xc8bcfc0d,0xb318edbf),LL(0xfe787e58,0x0909d56e),LL(0x8fe8b96f,0x5ae74fc9),LL(0x35ab6811,0x8fc342c4),LL(0x0b991e0c,0x6fc6cc5c), +}, +/* digit=75 base_pwr=2^375 */ +{ + LL(0x542f4e90,0x55671129),LL(0x0623d4cd,0x43bedccf),LL(0xe99ca16b,0x7e21207c),LL(0x7c7a26b9,0x785fa105),LL(0xc2c3ab00,0x33c28658),LL(0xd79cd59f,0xcce42a48), LL(0xb8c3bc75,0x9a674db4),LL(0x6904e3fe,0xea701d15),LL(0x66bf2c6c,0x990e7221),LL(0xbd4c3791,0xba29affa),LL(0x20696ee1,0xd98510cf),LL(0xf93d26a5,0x722ed471), + LL(0xbc579793,0xe7cf5bac),LL(0xd73f881c,0x11db7ddf),LL(0x04fa8473,0x9c1a531d),LL(0x5780efda,0x399e8484),LL(0x4f62cb5a,0x6e9c12be),LL(0x94a5df3b,0xf21bdc49), LL(0x11da2a4f,0x3c15fe12),LL(0x23e631d1,0xdea123bb),LL(0xbe294c90,0x3ef76da4),LL(0xa99b8398,0x5cf21d5a),LL(0x751b9f6a,0x50679cf8),LL(0x54d0b7bf,0x4b3f3b9c), + LL(0x75a46271,0x6c8d97e0),LL(0x9dbed39f,0x0fa0c4cd),LL(0xde74ac6c,0xfb6da5e2),LL(0xc17c1ec5,0x041ce886),LL(0xd7419105,0xb42941a8),LL(0x002fdfd5,0x79768eee), LL(0x88c8111f,0x64849afd),LL(0x814192d6,0xf425fe14),LL(0x0448fd7e,0xe916e864),LL(0x72ed351f,0x31e224ad),LL(0x7c0183c1,0x73e6e6ac),LL(0x21bf7ceb,0x375657c6), + LL(0x03bdf6d6,0xc84f9172),LL(0x69f60e03,0xcfc47187),LL(0xa05068ea,0xcdc4753b),LL(0x077777ef,0xa177ad14),LL(0x7e4cf44a,0x0b7f54eb),LL(0x1860144e,0x4ee443f9), LL(0x42bb6a93,0x1279ed4d),LL(0x436c1b54,0x511137d7),LL(0xb8cdb6ce,0xebc958fa),LL(0xa0c7614a,0xbc4f93f4),LL(0x7b2c6d8e,0xc5bd6cde),LL(0x8d65f38a,0xecff7dd7), + LL(0xe45543d5,0x9a4af7af),LL(0x6a04c87b,0xb7478fe0),LL(0x66f72454,0x974eebba),LL(0x5901d1ec,0x682578fa),LL(0xe82b048b,0xc3595199),LL(0xbbc19ba2,0x83da52fb), LL(0x90450b02,0x40f337af),LL(0x439c46d7,0xbd1ea60b),LL(0x00d0ed85,0x4f3e4818),LL(0x766d9e20,0x59d0a0a9),LL(0x56a16718,0xe81dc4d6),LL(0xdf3d3d98,0xac872a21), + LL(0xbbaae09b,0x4da7d63a),LL(0x0783fab2,0xcae05f37),LL(0x68841d1e,0x1e8c0016),LL(0xb10366f6,0x0688f485),LL(0x05b121e9,0x38ee34b0),LL(0x14e0dc1e,0x2779f009), LL(0xdbff60ce,0x83c1d44e),LL(0x4105c8c2,0x63fbcf82),LL(0x53715349,0x6b732744),LL(0xc5ca18f6,0x5065bdcd),LL(0x2def86e3,0x677313cf),LL(0x33ebff5d,0x6c54d224), + LL(0x88b3fc7b,0x35361c91),LL(0xc22a219e,0x706cf8c5),LL(0x886348e9,0x545bb34b),LL(0x4594a530,0xf25eef25),LL(0x73843cbb,0x59427ed0),LL(0xbeea8c4d,0x39638f20), LL(0x960e3c28,0x4e7d445f),LL(0xd383df18,0x989abc64),LL(0x04694ba7,0xb4238e02),LL(0x0203d67f,0xa3753137),LL(0x86d01fc1,0x404bc421),LL(0xb162392d,0x1af37190), + LL(0xf65de0f5,0xffec6674),LL(0xd23ad193,0x4043079c),LL(0xee61bc95,0x31811365),LL(0x8948b6e2,0x358bbd6e),LL(0xe31644be,0x1cd9c342),LL(0x60a8a7a7,0xbab3aa8c), LL(0xa375beb6,0xe065519f),LL(0x4439990c,0xf7d0b041),LL(0x8517ae8a,0x8957c03b),LL(0x73750d6e,0xc96a0401),LL(0xb2aee6d7,0x4eb2e364),LL(0xed099114,0x813054fe), + LL(0xec3c19fe,0x79d98e89),LL(0x429341e7,0x860ec5a6),LL(0x25dd60c0,0x80ab8568),LL(0xe47973db,0x7d0b3f3f),LL(0xf7899dfb,0x654435bd),LL(0xe6542b1d,0x54c59689), LL(0xbed69ab6,0x171c6842),LL(0x188a3126,0x82b8024d),LL(0x9c37538d,0x31bf057d),LL(0xcb0be742,0xe079326a),LL(0x29ace4e3,0x0232e981),LL(0xce8596ab,0x7b06fb86), + LL(0xcaada268,0x71714896),LL(0xfd0e302c,0xbb3d05dc),LL(0xfe56d08f,0xb0785f33),LL(0x38a1b2ef,0xdd43e0f6),LL(0x360fc15a,0x2df35cfb),LL(0x90b3ed36,0x97173f0f), LL(0xb720544e,0xd4970bdd),LL(0x94a01944,0xb6075f76),LL(0x4a43c4f3,0xc99e8a3e),LL(0xd9cb4808,0x8013609f),LL(0xecc3d094,0xf3fef0ea),LL(0x8642d223,0x3829fac7), + LL(0x0402156b,0xb7613dab),LL(0x0b20ec7a,0x4ad70f1c),LL(0x9c46dd4d,0xd9189b20),LL(0x4bd5235a,0x4b22485f),LL(0x88822a0d,0x6e972031),LL(0x2c136807,0x3cf8d823), LL(0x0884e550,0x5997fa64),LL(0x293aedb8,0x73110b25),LL(0x35319a22,0x7e820168),LL(0xa6c668ba,0x2222c809),LL(0x31e0bfb8,0x2f316be2),LL(0x0d832198,0x86cf3a2d), + LL(0x684456b1,0xffe3104b),LL(0xf0f49278,0x37ba0db6),LL(0xcca2f150,0x15aaed42),LL(0xc421c694,0x8618aa02),LL(0xfab87b36,0x4d6a091d),LL(0x0e786d5f,0x304eaea0), LL(0x2c114074,0x0be97747),LL(0xad387a8d,0xf57e3a19),LL(0x7a70d421,0x6094823b),LL(0x09de860f,0x59287918),LL(0x6dcf6020,0x7f7fca49),LL(0x5f46086e,0x57580c61), + LL(0x5d89002f,0xeab34616),LL(0x72a01a68,0xb3115628),LL(0xdce0c191,0x2f0ced58),LL(0x1a895760,0xec08b09a),LL(0xae62153c,0x206faa7f),LL(0xcf2895bf,0xc31e3815), LL(0x9ac88636,0xd57fbf57),LL(0xce91affd,0x966f5a84),LL(0x63620a73,0x092458b9),LL(0x50805fc1,0xda7b4910),LL(0x5c561649,0x1fc60a25),LL(0x4f899e20,0x8110a1a9), + LL(0xf0cb1370,0xb509f702),LL(0xc658441f,0xbdfcf4a0),LL(0x7f07f328,0x853d832a),LL(0x8fbdcb83,0x074fdecd),LL(0xd6a4650d,0x80ed8de9),LL(0xa5d68720,0x61c39ce8), LL(0x3177feb4,0xe66666d2),LL(0xafacf38b,0xdbf3fc57),LL(0x0da620fb,0x7e2d9951),LL(0xdf866f77,0x901145ff),LL(0xdb045beb,0x442a37e5),LL(0xbeb1b008,0x0cb0600f), + LL(0x54d7a6af,0x1e6604d3),LL(0x07c97f80,0xba6ae4d0),LL(0x77c527fb,0x5e3d978b),LL(0xe93a0d78,0xd0642c72),LL(0xb3c3c215,0x06d8ae5c),LL(0x4eb9a4c9,0x8bf36e5a), LL(0x4d505a53,0x1ca6403c),LL(0xd2f5c7a3,0x0187be5a),LL(0x9f850eac,0x68cce2ba),LL(0x5805353b,0x81055e4a),LL(0x89b4eb85,0x3c242c1d),LL(0xdda42eb8,0xee4a6691), + LL(0x7c34f095,0xbb39a17a),LL(0x22fbbe61,0x7be330a8),LL(0xb91f1482,0x6be6abe3),LL(0xbd39a2bc,0xf972804f),LL(0xf91d813e,0x06737e54),LL(0x1a87cd4a,0xbd606668), LL(0xf538d56e,0xbf88b2e5),LL(0x34afd68f,0xb8206a81),LL(0xa58af042,0x7a93aedf),LL(0xac0511b0,0x8853cdf6),LL(0x067e2c19,0x9d7f416d),LL(0xf9671d8a,0x5d0bc923), +}, +/* digit=76 base_pwr=2^380 */ +{ + LL(0x204be028,0x2e7d0a16),LL(0xd0e41851,0x4f1d082e),LL(0x3eb317f9,0x15f1ddc6),LL(0x5adf71d7,0xf0275071),LL(0xee858bc3,0x2ce33c2e),LL(0xda73b71a,0xa24c76d1), LL(0x6c70c483,0x9ef6a70a),LL(0x05cf9612,0xefcf1705),LL(0x7502de64,0x9f5bf5a6),LL(0xa4701973,0xd11122a1),LL(0xa2ea7b24,0x82cfaac2),LL(0x0a4582e1,0x6cad67cc), + LL(0x51e4de5e,0x96a1e74f),LL(0xe37f5006,0x72913696),LL(0xbe35109c,0x12449c4f),LL(0x4521d7e6,0x1fad8b30),LL(0x57d00293,0xc85eb23d),LL(0x35f68229,0x4ebd334b), LL(0x2df5acf1,0x7c5b8668),LL(0x5463de2e,0xc2b4da6e),LL(0x757cd570,0x067b0456),LL(0x3a1c866b,0xeaab81be),LL(0xbbba88c0,0x72a6af75),LL(0x0ef567dc,0xaed4dbde), + LL(0xb4dc8600,0x597a26ff),LL(0xf9288555,0x264a09f3),LL(0x5c27f5f6,0x0b06aff6),LL(0xd8d544e6,0xce5ab665),LL(0x99275c32,0x92f031be),LL(0xf42e0e7c,0xaf51c5bb), LL(0x1e37b36d,0x5bb28b06),LL(0x8473543a,0x583fba6a),LL(0xf93fb7dc,0xe73fd299),LL(0x6e2ccad9,0xfcd999a8),LL(0x334d4f57,0xb8c8a6df),LL(0x9a2acc9b,0x5adb28dd), + LL(0x7d221ab6,0x3afdee27),LL(0x47bb619e,0xecf10abc),LL(0xba4a3301,0x340c8ee3),LL(0x2a883b7f,0x1a6ea51a),LL(0xd5d7412b,0x64f27976),LL(0x91251b6e,0x7fcf0ecc), LL(0x365b18b7,0x5f3f8f41),LL(0xe2e13e58,0x38e48b96),LL(0xad61b2cb,0xde3b73d6),LL(0xd542676d,0xf08398d5),LL(0x8e7d712b,0xd373931e),LL(0x7f96e023,0x89325d7a), + LL(0x111792b9,0x5adf3d9a),LL(0x4f1e0d09,0x1c77a305),LL(0xa82d3736,0xf9fbce33),LL(0x718c8aa3,0xf307823e),LL(0x416ccf69,0x860578cf),LL(0x1ef8465b,0xb942add8), LL(0xcd9472e1,0x9ee0cf97),LL(0xb01528a8,0xe6792eef),LL(0xc09da90b,0xf99b9a8d),LL(0xcbf3ccb8,0x1f521c2d),LL(0x91a62632,0x6bf66948),LL(0x854fe9da,0xcc7a9ceb), + LL(0x4b3759cf,0xe44e3f86),LL(0x9d74e3f6,0x90cab0eb),LL(0x01c4e171,0x10042545),LL(0xce52defb,0xc12df68c),LL(0xf363100a,0xb1fae2fb),LL(0x3573235f,0x5016c853), LL(0x1d922e9b,0x8d4deb66),LL(0x17f84ef2,0x8a20d423),LL(0x5a4e118e,0x32498583),LL(0x308772e9,0x5abfa961),LL(0xf54e4876,0x41c7611f),LL(0x1f5867b2,0xc1da40d3), + LL(0x491ccb92,0x46303171),LL(0x2771235b,0xa80a8c0d),LL(0xf172c7cf,0xd8e497ff),LL(0x35b193cf,0x7f7009d7),LL(0xf19df4bc,0x6b9fd3f7),LL(0xb46f1e37,0xada548c3), LL(0xc7a20270,0x87c6eaa9),LL(0xae78ef99,0xef2245d6),LL(0x539eab95,0x2a121042),LL(0x79b8f5cc,0x29a6d5d7),LL(0xb77840dc,0x33803a10),LL(0x11a6a30f,0xfedd3a70), + LL(0x85adde98,0x3c90a59f),LL(0xe5269140,0x35414174),LL(0x1a0d58e2,0x9aca885c),LL(0x6816b009,0x77b9b6dd),LL(0x9ee4718f,0x8e5c1213),LL(0x4e4eac45,0x60ad991e), LL(0x4d71f624,0xc00c3569),LL(0x5bc5fd2a,0xacbf4eb2),LL(0x5eaf3eaa,0xcba1ffc7),LL(0x42a87e32,0x5f99092d),LL(0x6f7a882f,0x2e7b49c7),LL(0x29040512,0x5e9bfc5c), + LL(0x142403d1,0xfa070e22),LL(0x15c6f7f5,0x68ff3160),LL(0x223a0ce8,0xe09f04e6),LL(0x53e14183,0x22bbd018),LL(0xcf45b75b,0x35d9fafc),LL(0x7eceec88,0x3a34819d), LL(0xd33262d2,0xd9cf7568),LL(0x841d1505,0x431036d5),LL(0x9eb2a79a,0x0c800565),LL(0x5f7edc6a,0x8e77d9f0),LL(0x65e800aa,0x19e12d05),LL(0xb7784e7c,0x335c8d36), + LL(0x30a3ada1,0x75cba9d5),LL(0xf8ae9565,0xb69e308b),LL(0xca7b8369,0x990e3425),LL(0xe0a7ad0b,0x9f67567f),LL(0x18bd01b7,0x76ed6fe7),LL(0x2ff95cfe,0x282358aa), LL(0x410f8841,0x28d2ea41),LL(0xccd67c81,0x89d1533f),LL(0xb6a7b8f9,0x969bb272),LL(0x26330782,0x54f8664c),LL(0x1dcd9164,0xb89f3ae8),LL(0x3d962c14,0x54d845b9), + LL(0x6484fd40,0x8b2fc4e9),LL(0xa35d24ea,0xee702764),LL(0xb871c3f3,0x15b28ac7),LL(0xe097047f,0x805b4048),LL(0x647cad2f,0xd6f1b8df),LL(0xdc7dd67f,0xf1d5b458), LL(0x25148803,0x324c529c),LL(0x21274faf,0xf6185ebe),LL(0x95148b55,0xaf14751e),LL(0x28f284f4,0x283ed89d),LL(0x4cbebf1a,0x93ad20e7),LL(0x882935e1,0x5f6ec65d), + LL(0x6c0f3509,0xb3984b17),LL(0xd8b4d6bc,0xf9fa4483),LL(0x7dec20d2,0xf4ac2b67),LL(0xb3dbe034,0x67ef024e),LL(0x0f94f4d7,0x2dcc5118),LL(0x74a51393,0x024cdcfd), LL(0x20e7abcb,0xf1c0fead),LL(0xd3a7414f,0xffc18f81),LL(0x7062cb0b,0xb00ce556),LL(0x817bc8d1,0xeccb0521),LL(0x40411c15,0xa0c0fe60),LL(0x1defbe00,0x05311322), + LL(0xa4dcefe9,0xe222eba4),LL(0xec1ceb74,0x63ad235f),LL(0xe05b18e7,0x2e0bf749),LL(0xb48bdd87,0x547bd050),LL(0xf5aa2fc4,0x0490c970),LL(0x2b431390,0xced5e4cf), LL(0x51d2898e,0x07d82704),LL(0x083b57d4,0x44b72442),LL(0x5037fce8,0xa4ada230),LL(0x50510da6,0x55f7905e),LL(0x8d890a98,0xd8ee724f),LL(0x11b85640,0x925a8e7c), + LL(0x56467257,0xda828fe5),LL(0xd640c2a1,0x5e9abf67),LL(0xc25c696a,0x0eed233c),LL(0xb3e1d84f,0x72483dc5),LL(0x4f114abc,0x30bf1ee3),LL(0xd1f9bce8,0xf58b321e), LL(0x97524f33,0xcb26564c),LL(0x1e453229,0xdc2f105e),LL(0x72a982dd,0x9da43ceb),LL(0xfeef8862,0xecf5649d),LL(0x1fa2f06d,0xd8afda34),LL(0x55035432,0xf0d0ced3), + LL(0x1ca459ed,0x5bfa10cd),LL(0x6dcf56bf,0x593f085a),LL(0xc0579c3e,0xe6f0ad9b),LL(0x2527c1ad,0xc11c95a2),LL(0xcf1cb8b3,0x7cfa71e1),LL(0x1d6dc79d,0xedcff833), LL(0x432521c9,0x581c4bbe),LL(0x144e11a0,0xbf620096),LL(0xbe3a107b,0x54c38b71),LL(0xe2606ec0,0xed555e37),LL(0xd721d034,0x3fb148b8),LL(0x0091bc90,0x79d53dad), + LL(0x08d1be5d,0xcf17f9dc),LL(0xafdfeb23,0xb55de4c8),LL(0xe437b29c,0xa69454ff),LL(0xe27ee9e2,0x6628d789),LL(0xee3af03b,0x56e3b975),LL(0x2f532d62,0x0083fe9c), LL(0xe63e7511,0xcae15213),LL(0x86ed849c,0xdb5384f3),LL(0xfa4d825f,0x902ba959),LL(0x5ae17566,0xbad700d5),LL(0x14c82eb4,0x16b2c5dc),LL(0x36708ea7,0xa4b057a7), +} +}; +#endif /* _DISABLE_ECP_384R1_HARDCODED_BP_TBL_ */ +#endif /* _IPP_DATA */ + + +IPP_OWN_DEFN (const cpPrecompAP*, gfpec_precom_nistP384r1_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 5, + /* select function */ p384r1_select_ap_w5, + /* precomputed data */ (BNU_CHUNK_T*)ec_p384r1_precomputed + }; + return &t; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpp521r1precomca.c b/plugin/ippcp/library/src/sources/ippcp/pcpp521r1precomca.c new file mode 100644 index 000000000..8bb4b55cc --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpp521r1precomca.c @@ -0,0 +1,4057 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (P521r1 precomputed) +// +// +*/ +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +#define OPERAND_BITSIZE (521) +#define LEN_P521 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* P521 affine point */ +typedef struct{ + BNU_CHUNK_T X[LEN_P521]; + BNU_CHUNK_T Y[LEN_P521]; +} P521_POINT_AFFINE; + +extern const __ALIGN64 P521_POINT_AFFINE ec_p521r1_precomputed[105][16]; + + +#if defined ( _IPP_DATA ) + +#if !defined(_DISABLE_ECP_521R1_HARDCODED_BP_TBL_) +/* see ippcp_baseptbl.cpp test for generation details */ + +#if ((_IPP_ARCH == _IPP_ARCH_EM64T) || (_IPP_ARCH == _IPP_ARCH_LP64) || (_IPP_ARCH == _IPP_ARCH_LRB) || (_IPP_ARCH == _IPP_ARCH_LRB2)) +const __ALIGN64 P521_POINT_AFFINE ec_p521r1_precomputed[105][16] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0x81adc101,0xb331a163),LL(0x18e172de,0x4dfcbf3f),LL(0xe0c2b521,0x6f19a459),LL(0x93d17fd4,0x947f0ee0),LL(0x3bf7f3ac,0xdd50a5af),LL(0xb035a69e,0x90fc1457),LL(0x9c829fda,0x214e3240),LL(0xb311cada,0xe6cf1f65),L_(0x00000074), LL(0x5a9e268e,0x28460e4a),LL(0x3b4fe8b3,0x20445f4a),LL(0x43513961,0xb09a9e38),LL(0x809fd683,0x2062a85c),LL(0x4caf7a13,0x164bf739),LL(0x8b939f33,0x340bd7de),LL(0x24abcda2,0xeccc7aa2),LL(0xda163e8d,0x022e452f),L_(0x000001e0), + LL(0x640909df,0x1e90cf08),LL(0x99dd36bc,0xb3fa1f1c),LL(0xb26b07ec,0xa0e797d1),LL(0x1d1ae2d7,0x83d50825),LL(0x6d377aaa,0x4bd9d902),LL(0x82ebb4df,0x1a96372a),LL(0xcd8e6603,0x3a3a0193),LL(0x40a46141,0x3417e594),L_(0x0000013f), LL(0x31fe1b6c,0x813d2ee3),LL(0x6b30fa0d,0x7b8df1ab),LL(0x4af6e07a,0x7a757e5f),LL(0xd4cd1924,0xb5c9c9bf),LL(0xef4f928f,0xddd9f1bb),LL(0x4c836216,0xa05590d1),LL(0x3e26d4bb,0x5ae35a88),LL(0x777769f8,0x8053f9f6),L_(0x00000133), + LL(0x4910f78a,0xbee9cf4d),LL(0x976f1bd6,0x02d2c8ce),LL(0x43161975,0x0dd75a48),LL(0x8b5acff1,0x028ed35e),LL(0x251d2419,0xe8d69f8b),LL(0x0896bd46,0x5cf2d6bd),LL(0x2d891ecd,0x3cda9537),LL(0x325acaca,0xaeec8eb5),L_(0x0000008c), LL(0xee5f7e98,0x72cfa6c0),LL(0x50f74360,0x212fac46),LL(0xde49d2c8,0x867882e4),LL(0x68ef61e3,0xd816ad67),LL(0x67c6e2ba,0x761716ea),LL(0x8fd1aae7,0x8be97c55),LL(0xd4154e81,0x7978aabf),LL(0x63655c0a,0xeccbcfc3),L_(0x0000016e), + LL(0xd92b8ab0,0x798d6d77),LL(0x09438c81,0xf17de43a),LL(0x2d8472d2,0x3350ea81),LL(0x4f83c578,0xa8745c47),LL(0x257f1e83,0x56432cf1),LL(0xaaa0e9e7,0x7e0362ea),LL(0x8e2ff9cd,0x66e30e44),LL(0xa43e4838,0x61aa5a41),L_(0x00000102), LL(0xe109849e,0x86a0825b),LL(0xfe1a3726,0xecf10fa3),LL(0x78234ce8,0xf75dbfd7),LL(0xa854adc2,0xa029127b),LL(0xf2a5d1c2,0xf93cf941),LL(0xf178cc83,0x0dad731f),LL(0x7b737197,0xdb2a90d7),LL(0xc7585a55,0x5b39f00b),L_(0x000000e9), + LL(0xf14a49e9,0x3c194afc),LL(0x4b764798,0x9c6ad5a8),LL(0xf36c498b,0xd194ebf0),LL(0x5789bf3c,0x11b8897f),LL(0x36af180a,0x721c1e06),LL(0x5c78bbd6,0x926781ed),LL(0x7eda9f86,0x5fbd2cb7),LL(0xc8e02758,0x639ede19),L_(0x00000019), LL(0xc6f75980,0x65d6f9bb),LL(0xf46f5848,0xfc0b9e61),LL(0x92b9aa7b,0xbce8f803),LL(0x108e7aff,0xba188aa0),LL(0xe4839679,0x43ddb44b),LL(0xe4d01a38,0x28f6ec0b),LL(0x47439700,0x488e6c7f),LL(0x88a54089,0x764515b9),L_(0x000000eb), + LL(0x75b36d64,0x5cfb915a),LL(0xf6fbc903,0x5711b98d),LL(0xab2bf9c0,0x4617b374),LL(0x11ca98df,0xca70393d),LL(0x0b0a9fb9,0xa92fde65),LL(0x56f25580,0x79cc0a83),LL(0x4bbfeb8e,0xcab11e98),LL(0x7ca24068,0xa9977f9a),L_(0x0000010c), LL(0x6b433193,0x8bf78095),LL(0xbc2c6a27,0x6f0f5666),LL(0x5aae506d,0x101ee3dc),LL(0x26f13a79,0x4efcb64c),LL(0x872b3246,0x4b655b96),LL(0x93100d45,0x47392054),LL(0xb9ed2d40,0x889555dd),LL(0x82a371d8,0x35716e93),L_(0x000001ac), + LL(0x766756df,0x6a15b574),LL(0xc4140b76,0xcd00e756),LL(0xa87ee130,0xe237ca9f),LL(0x986e71dd,0x6c64d36f),LL(0x855fe34c,0x2ec61846),LL(0x617b88a6,0x14780c69),LL(0x747aa419,0x062f9170),LL(0xed05839d,0xa3775b2f),L_(0x000001b1), LL(0xdf66eaa8,0x8d8f4b46),LL(0xe4829292,0x3dae35c5),LL(0x952eef7e,0x2fcf3b38),LL(0xa2c8e70d,0x15ca91d1),LL(0x49e6f64f,0x2ab5e879),LL(0xc51365ef,0x6eb8edec),LL(0x68141278,0x3c5ae2c1),LL(0xbd1ceb42,0x8868ec18),L_(0x00000150), + LL(0x03ed8c07,0x340208b1),LL(0x2a553c67,0x02c37cf5),LL(0xdad37a02,0x0d5ab144),LL(0x0de46bcf,0xf845acc6),LL(0xdc2bcfa4,0xc7adff52),LL(0x82fc1314,0x0545c51d),LL(0xc54d801f,0x2dea714e),LL(0xcb580871,0x31541a41),L_(0x000001b9), LL(0x475550bf,0x0e58cc64),LL(0x788f8bc0,0xa9c56b21),LL(0xa004a389,0x34cf9dd4),LL(0xf832e2bc,0x5ff85d06),LL(0x552c88da,0x78c4f4e0),LL(0x30833bd4,0xada841ef),LL(0xf4f16038,0xcd227c76),LL(0xb73c429d,0x10247ed5),L_(0x00000024), + LL(0x78d67878,0x03d614e2),LL(0x3cb3e5f1,0x330fa2b1),LL(0x5ec2e694,0xc7a7a85d),LL(0x6fb92d18,0x1af9e2ab),LL(0x9cb09a6d,0x32ba14f0),LL(0xa2dc635b,0x4c962558),LL(0x0dcc43a3,0x44769a2a),LL(0x8ab8ab6a,0x13517adf),L_(0x0000010c), LL(0x6326a2bb,0x270a8b98),LL(0x435cd695,0x9a1d5075),LL(0x74944407,0x3eb9b615),LL(0x67a55fec,0x4207fab7),LL(0xbab02bd6,0x3706b4f2),LL(0x131eeda2,0xdb6412dd),LL(0x2a770e75,0xc7184453),LL(0xbd13d749,0xcf85aaaa),L_(0x000000f9), + LL(0xc8af6987,0x90643ae3),LL(0xd0279799,0xcd43ff84),LL(0x8f8d4740,0xf9be1720),LL(0xd4c21049,0x94ced526),LL(0xbc7e6131,0x885163e0),LL(0x588d6d44,0xe1a54923),LL(0xcd604d63,0x66c80ec3),LL(0xdb390f62,0x0efe7f3d),L_(0x00000194), LL(0xae124585,0xacfad765),LL(0x4c09af63,0x0b94aa5e),LL(0x1cb9cfd5,0xf7f9b44b),LL(0xb1ee2bf5,0x5da9b7b0),LL(0xea26cc32,0x695fa9a4),LL(0xc53177b1,0x05d4bfeb),LL(0x0a2128d9,0xb0617759),LL(0xd86515d3,0x4edd7559),L_(0x0000005d), + LL(0x04967f7b,0xcd229d61),LL(0x16ed066d,0x81766070),LL(0x27d264d4,0x4280ae01),LL(0x75f18c88,0x0de8cd8d),LL(0x999331ed,0x2979ede2),LL(0x2a794c8b,0x4aa1f796),LL(0xf6be0bc2,0xe7f6aee3),LL(0xab9da18a,0xaa378d1c),L_(0x000000ff), LL(0x0ff2ee88,0x0425becc),LL(0xc9672464,0xaeac43a7),LL(0x71fa40cd,0x9b6e5640),LL(0x8c8a54a9,0x559c4919),LL(0x8745a152,0x158de454),LL(0xea705cdc,0x49f6974a),LL(0x31085e82,0x149d6eab),LL(0x3b82a7d9,0xc24e8654),L_(0x00000094), + LL(0x3b24fe08,0xc6703677),LL(0xb8dfc216,0x58bdf34a),LL(0xae298494,0x009bba63),LL(0x4d30749c,0x98a3bff7),LL(0xbe1fdc0d,0xd3227485),LL(0xd2cb3b89,0xdb083e7b),LL(0xabcac22b,0x0f40c3a0),LL(0xba4e3fef,0x2ef27d74),L_(0x0000010e), LL(0x651a9249,0xf850122d),LL(0xd1940d8b,0x363cf3d8),LL(0x91127ad7,0x184425d3),LL(0x7ca8dcdb,0xdb660853),LL(0x21ec37e6,0x4beb68c4),LL(0x5fb50be0,0xd22f2025),LL(0xd5b8a4a6,0x23b1ff32),LL(0x81d34165,0x7f1e70e8),L_(0x000001e0), + LL(0x3e6130e5,0xd39f8fa6),LL(0x46997de6,0xfc0c43c2),LL(0x80559c77,0x74a5f61d),LL(0xf3cd5c47,0xb51aa852),LL(0x84701e4c,0x3099622c),LL(0x5f57adc3,0x1c2776e9),LL(0x66f0da61,0x0d49fb9b),LL(0x95a49243,0xce6bc32e),L_(0x00000156), LL(0x3adb5e07,0xe4c23b96),LL(0xfd811538,0xfb948d00),LL(0x57c88bf4,0xe1b0ccf5),LL(0x9a8e5fdd,0x1f936fee),LL(0xac1c5e3b,0x9560deae),LL(0xd72e0f10,0xe34e3d33),LL(0x1c36aa10,0x04676a85),LL(0x6d51f6ad,0xd48d0c93),L_(0x000001f6), + LL(0xf71546c6,0xba61d6f1),LL(0x16e9a196,0xae964f34),LL(0x5c0977df,0x5533b3fb),LL(0x25bde3a2,0x16bcef9f),LL(0x645c4b91,0xccba7e03),LL(0xd5f0598c,0x17ea7d85),LL(0x0a4a08b5,0x68cac5a0),LL(0x7d57c26f,0xd4f0dc66),L_(0x000001b2), LL(0x8d5d76b2,0xa5172924),LL(0xc293806a,0x5f20b34f),LL(0xa9d43e42,0x06adb487),LL(0xf8e899ee,0x2608f44d),LL(0xd8da79ac,0xb1683bc0),LL(0x4dc36bf6,0x350423e7),LL(0x15c728c1,0xfdc23809),LL(0x5dd5da5e,0xe96b3148),L_(0x000001ad), + LL(0x26af2e49,0xaa9adab6),LL(0x9bde5c6d,0x5ef4d7f1),LL(0x4c0f1fc9,0x8ecdc6cb),LL(0x8e47e019,0xff3c3ade),LL(0x13ede807,0x08dc8e67),LL(0x996f8947,0x296b4bda),LL(0x185a0504,0x07dc7de6),LL(0xe2a36a18,0xf820aac7),L_(0x00000032), LL(0x89c55c4e,0x32ed1a36),LL(0x4050a3aa,0xecab1a1a),LL(0x6622355e,0xc9237ec8),LL(0x11964b64,0x4010a471),LL(0x644ca385,0x6abf4831),LL(0x34cba42f,0x5d25b108),LL(0x54dd6906,0xb1ef824b),LL(0x9199f6df,0xb53e7326),L_(0x0000008e), + LL(0x362a2722,0x17f45f44),LL(0x47c0d420,0x299d3628),LL(0x4003ee6e,0x6f86dfae),LL(0xd3cc2b18,0x5072cb2e),LL(0xc430e500,0x294a1ff8),LL(0x69058c45,0x9eeb197c),LL(0x30c97e9f,0x859543fb),LL(0x13563a1d,0x2eed4bed),L_(0x00000168), LL(0x0f160b5d,0x5f1e8dcd),LL(0x7c4de39d,0x99a97139),LL(0x69468c31,0x294f1802),LL(0xd64eccc4,0xd505983a),LL(0x9cc6daa3,0x60e0c170),LL(0x64a5b5c1,0x8763e518),LL(0x61dc006a,0xb9099af2),LL(0xc69e9f34,0x0fe38a58),L_(0x00000180), +}, +/* digit=1 base_pwr=2^5 */ +{ + LL(0x65b4828e,0x4f59ae8d),LL(0x5c3b72b5,0xc123c8ad),LL(0xae6b62e3,0xca4e7ba3),LL(0xeb5d2e8f,0x7633eb4d),LL(0xaee39acb,0xeb750251),LL(0x77dcf2f5,0x1c6dd3f6),LL(0x32a70340,0x9a1f1f0b),LL(0x7ca5d0ad,0x4a21b83d),L_(0x00000123), LL(0xfd346502,0x5511dec3),LL(0x4c8a50ab,0x1b4ae54d),LL(0xb2d5cb0b,0x6fe6cc64),LL(0xe3f5079b,0x5cdba6f0),LL(0xdc0c66eb,0xbef10266),LL(0xe32e16eb,0xb3e0ef80),LL(0x5faff80c,0x347fbdec),LL(0xaff9f041,0x088b1af3),L_(0x0000015c), + LL(0x5f738444,0xa16ae6a8),LL(0xc671907b,0xa0da9ee1),LL(0x014d027e,0x0efad55c),LL(0x0b01f380,0xb9d3e016),LL(0xe2f7ed1b,0x938df5e9),LL(0xe67c4396,0xd65b0a5c),LL(0xd40c305d,0x533f5edd),LL(0x01c97f61,0x68a79ebe),L_(0x00000176), LL(0x3ae123a4,0xad9d235c),LL(0x2c52fc6f,0xea2d78b8),LL(0xedd0329e,0x21e0e0d2),LL(0xf1d7cac0,0x887a53dc),LL(0xd0a846a5,0xc5d60b2d),LL(0x1b4f43d5,0x0e8631dd),LL(0x4597d8ee,0x36cdd8e6),LL(0xbe2bdcac,0xb9d50810),L_(0x00000102), + LL(0x7955b135,0x571ccaa7),LL(0xcc45066e,0x3f9b1980),LL(0x05f6f02b,0x6757639e),LL(0xe84f381f,0x4e03775c),LL(0x5ef348d1,0x4770c353),LL(0x3845ff7f,0x5fb50c57),LL(0xedbd5036,0x5b16a317),LL(0xe0ae9613,0xbda8a1ca),L_(0x0000011c), LL(0xac6debc0,0x2efb5af8),LL(0xce499e42,0xdea5dcca),LL(0xf85f9a34,0x8fc76f8d),LL(0x07899ffe,0x0f62f621),LL(0xbdb94b70,0x648a20af),LL(0xfe99ecf5,0x436c353f),LL(0xd5421253,0x3fcac929),LL(0xe3d53ffd,0xa9413337),L_(0x00000092), + LL(0x967c9f8e,0xf05f3504),LL(0x72b9b7d4,0xdabb5813),LL(0x90711a09,0xa79713f3),LL(0x40b52fc0,0xbea8efb8),LL(0xb43b138e,0xcba724a4),LL(0x7bae703e,0x96698925),LL(0x5de16b6e,0xd41e4b4c),LL(0x80a9811f,0xc1b18e03),L_(0x0000000f), LL(0x7d41aa0a,0x989bdb97),LL(0x0964efd8,0x725e184a),LL(0x049a3954,0x09871a1a),LL(0x92325673,0x462734e1),LL(0x586e4cd6,0x54d24ffa),LL(0xe1d8d7ce,0xb30da7d5),LL(0x69f3efbc,0x416e700f),LL(0xef7de3d3,0xe729987f),L_(0x0000001e), + LL(0x4f9e94f1,0x08a54bd7),LL(0x32ffe09a,0x456c0723),LL(0xd6fc852f,0x40d62750),LL(0x2ffa7f72,0x4aeb61e4),LL(0xe7b77ac3,0x502b124f),LL(0xfe47dfb6,0x4dd6a90a),LL(0x06cd1ac4,0xa6600862),LL(0x47e8bdf2,0x9f7f4801),L_(0x000001f1), LL(0x059ad258,0x0fde861b),LL(0xc7487c32,0x94ff60ca),LL(0x23970cbd,0x72b3e644),LL(0x6984aedb,0xcc2f8476),LL(0x43e3b1aa,0x4e288fca),LL(0xd6b84507,0x5c070a30),LL(0xcde70c2f,0x806889c8),LL(0x9397e29b,0x4c71559f),L_(0x000001e0), + LL(0xb013de1e,0x85707b44),LL(0xfaa21460,0xdf0df8fc),LL(0x6496b635,0xa66cdf1c),LL(0x72a3871c,0x9e220e51),LL(0x55171f57,0x76519fbf),LL(0x2bc7ff1e,0x1fe67c09),LL(0x4f8bd386,0x55ed0240),LL(0xc5765e29,0x1c77281d),L_(0x000001f5), LL(0x85021f4e,0x9e78f5c3),LL(0x38d57586,0x6a14b857),LL(0xa24ce77d,0x956a40cd),LL(0x6eeb21f0,0x384b0097),LL(0x30d4fd92,0x3f99bf29),LL(0xce9aade0,0x0b162be5),LL(0xc168443c,0x056730f0),LL(0x8b3af3cd,0x86e7a481),L_(0x0000012a), + LL(0x5c84256a,0xd9b7e5ae),LL(0xd2292194,0xc11a98a6),LL(0x0b648125,0x59e37b44),LL(0xaf635b08,0x25aea6af),LL(0x19039f0b,0xd7528475),LL(0xd304853b,0x17b80f08),LL(0x08f86bd4,0x16cad388),LL(0x4ba43b52,0xd0f1e285),L_(0x0000005e), LL(0x4e262ae5,0x7719f6ae),LL(0x0e419d0c,0x808c65ad),LL(0x5ed42353,0x2e40948b),LL(0xc831c79b,0x95dfdfbe),LL(0x1f8615c2,0x19810fc6),LL(0xd5083188,0xc73c4dd3),LL(0x9df9fc10,0xb9ee4c0f),LL(0xb094cd65,0x75870f78),L_(0x000000a4), + LL(0x83c0ad6b,0x56757d02),LL(0xc834df00,0xc0d9c745),LL(0xe5caf285,0x91f23599),LL(0x620faea3,0x2d4e48a9),LL(0xb7461523,0x99bdc7a7),LL(0xf47934e5,0xd4dc2fd4),LL(0x4f65ada3,0x4c81e39c),LL(0x3c079897,0x64a2c57e),L_(0x00000010), LL(0xea9cd04f,0x3fa38d40),LL(0x22a435ef,0xc247d609),LL(0xa826a53b,0x3d8a1866),LL(0xcede94d3,0x75ac695c),LL(0x2b9c71de,0x8bcb2e7b),LL(0xd52b9aa7,0x1a8316e1),LL(0x40f2da2b,0xe2a07695),LL(0x49881db4,0x7e4c0ddd),L_(0x00000021), + LL(0x14f3b7ed,0x7118ea7a),LL(0xe663ce23,0xd6a550c8),LL(0x67612dfd,0x45b8de7d),LL(0xd0a752b6,0x1b9bd789),LL(0x60ad3301,0x023b6c29),LL(0xcc26ecce,0xa078b41a),LL(0x61239a1a,0xee942cd7),LL(0x6922505f,0x5e08263e),L_(0x00000187), LL(0xe0703b39,0x1108fef0),LL(0xe9adb593,0xe4610492),LL(0x509096b8,0x26279733),LL(0x4c917c92,0xc7a80802),LL(0x7516cc5c,0x8edbea9c),LL(0x131d3769,0x1db92a9d),LL(0xe32f86b9,0xc3bfb615),LL(0x16237fcf,0xdaad00e7),L_(0x00000105), + LL(0xf41dbbe2,0x726d1da3),LL(0xd0f5eba7,0x5afe82c9),LL(0x00a2bafd,0xa7f8f99a),LL(0x8c282afe,0x5344cf5a),LL(0xa7ab3e18,0xb4f699ab),LL(0x2626fca8,0x345363ae),LL(0xc44f5f11,0x9cac1c3a),LL(0xa135f6b3,0x2cc9c6d3),L_(0x00000083), LL(0xff61db3e,0x90784ad0),LL(0x4491c85e,0xc87a8f35),LL(0x23793bcb,0x9606baed),LL(0xcd6ee91d,0xaa42a14a),LL(0x54d429b3,0x40a29e37),LL(0x89ff244a,0xd4a2c066),LL(0x0bb505cb,0xdc545060),LL(0xfc93a903,0xad7e26a4),L_(0x0000006e), + LL(0x2c4f1dd9,0x8ceb07a2),LL(0x96bcc3d3,0x99d9281c),LL(0x3db83972,0x3ff2e9a3),LL(0x16268498,0x00d03fc3),LL(0xf0d72767,0x974db3bc),LL(0x52e2c15d,0xcfc51b17),LL(0xe4156324,0x10aa8cfe),LL(0x989f0141,0x8e68c302),L_(0x00000148), LL(0xb8c928ab,0xb1ff4858),LL(0x798b01e9,0xb7bcaeeb),LL(0xb107b933,0x0bdcd04d),LL(0x5499a0b1,0x26fd1d2e),LL(0xacddcbd8,0x56837ddc),LL(0xa9081a22,0x3bdf1491),LL(0x05c3276e,0xc07890c9),LL(0x91891ac9,0xa184d413),L_(0x000001ab), + LL(0xfb3d55c4,0x8bff7233),LL(0x91b8350b,0xf62b4383),LL(0xb265f67b,0xc46f7226),LL(0x21d7036a,0xef90907e),LL(0x8034aa28,0xdabc0434),LL(0xd005b709,0xb12cb388),LL(0x06bb608b,0xe65c7159),LL(0xeb7b8a18,0x11e0f987),L_(0x0000019b), LL(0xc295c43f,0x8d53586a),LL(0x0ab2f2c0,0xe3db9e6a),LL(0x80aa8220,0xb7b44599),LL(0x2bea87eb,0xa54e5ad3),LL(0x6c5ac479,0x93b927af),LL(0x83fb3fac,0x62a4775c),LL(0x9c4bd501,0x657b8d9a),LL(0x88136dc2,0x31811cf2),L_(0x00000073), + LL(0x67baa023,0x4d4e2e15),LL(0xa3ad1cf1,0xf792f378),LL(0x7aef7449,0x4d833ce0),LL(0x5394ba78,0x06fcfedb),LL(0xf33fd365,0x76965949),LL(0x9c4ccb42,0x4e9fbd73),LL(0x61aaa0a9,0x9fa1995c),LL(0x3ba114e8,0x462ee846),L_(0x0000008d), LL(0xed8f7990,0x0442839b),LL(0x46e8546b,0x4cfa345f),LL(0x0d411f16,0xc1e9119e),LL(0xf8d99149,0x0deb6f34),LL(0xb98975e2,0x6508c235),LL(0x6e32684a,0x741c5884),LL(0x99583d46,0xacaecb2f),LL(0xd61998e0,0xdc28ccee),L_(0x000001fc), + LL(0x1b2220c8,0x22a3dc2c),LL(0xbc8dbffe,0xf713e616),LL(0xbe6a57a2,0xbe89cc5f),LL(0x5dfb0ead,0xb5bd5287),LL(0x5dba909b,0xff87fb08),LL(0x124b1f29,0xd39afe41),LL(0x8ad8951f,0x0e13a626),LL(0x2f09f744,0x4826695e),L_(0x00000020), LL(0xe7dc7a13,0x89f11d49),LL(0xd8b689b1,0x42cf8f40),LL(0x8f4bb929,0x1093f58a),LL(0x41b6334a,0x5f1b0229),LL(0xcbfc9d3f,0xfa09f9c8),LL(0x4f838812,0x4ae0b40b),LL(0x114194e2,0x6d9844d6),LL(0x69722fe6,0x15e4c6d7),L_(0x0000004f), + LL(0xa12d6b0f,0x2f86d0f6),LL(0xf27fea27,0xb102e317),LL(0xf76070d1,0xb05afc5b),LL(0x1c9d3a3b,0x5dd0f5d9),LL(0x00e4d9fc,0xee4d6689),LL(0x65f0f1c6,0x2a86ba85),LL(0xde562216,0x3e6bfc0d),LL(0xdbfc35a2,0x9af0f242),L_(0x000000da), LL(0xae71ea00,0x941bae5d),LL(0x2b9df6f5,0x5be1e379),LL(0x818b63c5,0x35a1da29),LL(0x7c374ecf,0x81936096),LL(0x91cdc4c0,0x32597a76),LL(0x72e4e5df,0x3e8a2fa3),LL(0x5b7351e8,0x916e7f8d),LL(0x19372aca,0xabd62e9d),L_(0x0000016a), + LL(0x4a1a9b59,0xc98396a0),LL(0x1d4dea3f,0x2852471e),LL(0xf1b1b604,0x9e270a42),LL(0xbff87527,0xe46c1327),LL(0xfe022231,0xfc05c823),LL(0xe4c1b07e,0xa4581988),LL(0x46e86dbf,0xc3803e03),LL(0xf3ea14d7,0x8c2f4163),L_(0x00000069), LL(0x1c64b3b6,0x474df73f),LL(0x3f77cba0,0x82f0ebae),LL(0x9fac52f4,0xeabe2a5c),LL(0x4d046303,0x5a86c777),LL(0xd8716f60,0x16157561),LL(0x76cfe4cf,0x564b6dae),LL(0xf10528e0,0x9113bb26),LL(0x878d8ad6,0x933ccc8b),L_(0x0000002f), +}, +/* digit=2 base_pwr=2^10 */ +{ + LL(0xff6fab57,0x7c6312ff),LL(0xb394c36d,0xd8c526b5),LL(0xae9f8123,0x6b7fb3e1),LL(0x7287a461,0x2d9f22f9),LL(0xd21b31a9,0x895d4a0f),LL(0xd7cbfded,0x81ff2d23),LL(0x5c105748,0xe830bd0b),LL(0x4fe2bd04,0x9dfeb777),L_(0x000001d6), LL(0xf68f023b,0x83b243fc),LL(0x7e7441cd,0xa23e166b),LL(0x5c91b009,0x85f70865),LL(0x122f85c7,0x22e7768c),LL(0x6db40321,0x2fb75185),LL(0xd6df94b8,0x80b31836),LL(0x98df3edc,0xeea7ce80),LL(0x05298e9a,0x048ecb96),L_(0x000000e6), + LL(0xa74584c1,0x8ec6fc14),LL(0x292021e4,0xa9680402),LL(0x9500ecd0,0xed719b16),LL(0x41202339,0xb81e8a19),LL(0xb85440eb,0xd40e8e4d),LL(0x3f6a53c2,0x84a12a31),LL(0x2796c5c6,0x497c0088),LL(0x91636765,0x751837b7),L_(0x0000000c), LL(0xb89a9335,0xd4740897),LL(0xfeb6c7cf,0x05fd0f39),LL(0x66755043,0x24da0165),LL(0x915708d7,0xcde5846c),LL(0xc7bb1c3f,0x0cbcc847),LL(0x5d5c58a4,0xd0093587),LL(0x531dd999,0x178ab52f),LL(0x88ff3f98,0x4485d318),L_(0x0000007c), + LL(0x4bebd902,0x7f523b68),LL(0x91acdac6,0xe5501216),LL(0x656f99d2,0x9d6ec374),LL(0xe158465f,0xf67a8845),LL(0x15ed0b99,0x0ea75aec),LL(0x01226fd6,0xc000f5ba),LL(0x0a951866,0x2eb378e5),LL(0x185feb1f,0x746f4b9e),L_(0x0000008c), LL(0x8a0bff22,0xae887bf0),LL(0xc9deb828,0x2d928546),LL(0x4d8afcb8,0x7759681c),LL(0x47a77426,0x1f2422bc),LL(0x9941fb7f,0xc9c44935),LL(0x3b4f41a6,0x50ea43ef),LL(0x708dbefd,0x5c9f2544),LL(0xcef3425f,0x8d085b3a),L_(0x0000003d), + LL(0xe2354e89,0x4dbc092f),LL(0xa2f27fd6,0xfff03850),LL(0x2ad51407,0x2ffc14aa),LL(0xc4b80840,0xbe516b67),LL(0x4499107f,0x0f027098),LL(0x715688b4,0x5e2c9af3),LL(0xbddce779,0x26ec8f7d),LL(0xcc8a5dc6,0xcc9e1305),L_(0x0000012a), LL(0x6e30ed0c,0xcd14a595),LL(0xce664e13,0x678ff921),LL(0xb7485d5a,0xed6fe685),LL(0xdd61d65f,0x2b7d0453),LL(0xa066d915,0x81e48dc7),LL(0x0c3395f0,0xc1cb1256),LL(0x6053e587,0x630f2cdd),LL(0xc776afca,0xf0d70553),L_(0x00000014), + LL(0xfa927e34,0x71ac09f5),LL(0xd012b2e5,0x9190907b),LL(0xc03bb972,0xab45bb80),LL(0x8ed0d272,0x3b41e8eb),LL(0xaa3449d8,0xd2d64ef1),LL(0x4e6b21d4,0x9f7e0342),LL(0x9eb72363,0xb6336622),LL(0x69f35a65,0x9114adb9),L_(0x0000017e), LL(0x75b2adb4,0x18b88dd7),LL(0x489c82e7,0x1d050011),LL(0x5e1bdb72,0x80ac7d35),LL(0x3a785f6c,0x6bb1ceb8),LL(0x4d0595c0,0x47ba8e65),LL(0xf29ab5dc,0xfba4c7c5),LL(0x768427d3,0xf250f0c9),LL(0x38fed5ff,0x60390918),L_(0x0000018f), + LL(0x41d4c16a,0xd8129c74),LL(0x33a20918,0x56ec57a8),LL(0x44da27b8,0xfe03052c),LL(0x5c69a6e2,0xb8645b34),LL(0x61e0489c,0xedf7eb89),LL(0x0d9cee51,0xb459ccf4),LL(0x4bbdc11a,0x2e3c7f1a),LL(0x22591a2d,0xab74c4c7),L_(0x000001f8), LL(0x97907b5b,0xffdc8f5b),LL(0x9755e96d,0x00d903b0),LL(0x73fc3336,0xa3ed2567),LL(0xa44f5c0a,0x78da9c2e),LL(0x130585a8,0x5d2a5778),LL(0xf488bddc,0x203a9db6),LL(0x0d642fb8,0x49bb8671),LL(0x86aadd4d,0xc216425a),L_(0x000000a8), + LL(0x0f4d050a,0x106b0907),LL(0x6c59b6a4,0x77bee1fa),LL(0x082792c1,0x39609b3e),LL(0x4e300675,0x9586b280),LL(0x41820c34,0xf4b318a9),LL(0x568da4bf,0x504b9f0d),LL(0x18b54e1d,0x7cd449b1),LL(0xea63bc73,0x35d4426b),L_(0x000001d7), LL(0xa3569b00,0x0b6fffaa),LL(0x5b9ffa5e,0xc584b1b6),LL(0xb1ee386e,0x00bfc921),LL(0x2e48b6f0,0xc1a25580),LL(0x90b9e7af,0x232ccaec),LL(0x60d7386e,0xbcde0a94),LL(0x27832dfe,0x20ca19ad),LL(0xa34dad1d,0x2a628682),L_(0x000001ca), + LL(0x86b1f786,0x61a19c36),LL(0x5540d3da,0xde90b954),LL(0xfed5fc9d,0x08cbe546),LL(0x6579be89,0x931292ec),LL(0x31c8bf2b,0xde0b2215),LL(0x64709233,0xf0e33dcf),LL(0xa91e2913,0x99299206),LL(0x933880d8,0xab37b024),L_(0x00000107), LL(0x081c0df1,0x6eb1d587),LL(0x5f29f3ee,0x6f46862b),LL(0x13755e24,0xe2652ae3),LL(0x952c2e51,0xba6a65e2),LL(0x013b9446,0x3fd1b792),LL(0x5e7bffb4,0x96a14917),LL(0x66af7dd8,0x68a41011),LL(0x553d0d5f,0x4ff29cf9),L_(0x000001a3), + LL(0x1c733b58,0x1d7e25bf),LL(0x707d2643,0xb62058b6),LL(0x3eddf1f7,0xcf147bf5),LL(0x09f87dab,0x11a1e31b),LL(0x9b643ba2,0x4287faad),LL(0x31ecf4ec,0xfdf5220a),LL(0xa4f09336,0x8916b869),LL(0xd2c73095,0xe07b7112),L_(0x000001a5), LL(0x46af9424,0xea00c98e),LL(0x31798ea9,0xee9f1bb9),LL(0xa0db3168,0x33aa5ab3),LL(0x5107a1fa,0xbb110cf5),LL(0xccdd22ec,0xedd17aae),LL(0x8bb0cd07,0x610d689f),LL(0xcf178778,0xcca4e56f),LL(0x95d696e3,0xaef30431),L_(0x00000088), + LL(0xf37c6266,0x7352fa9e),LL(0x4590e4bc,0x951e01ab),LL(0x42b51fb7,0x3643ff6f),LL(0x1a3be50c,0xdad9a3a4),LL(0x5c6479b6,0xb0a91741),LL(0x5f9d3ca9,0x841c9d52),LL(0xbed2f70d,0xdc8331dc),LL(0x3fce8436,0x0a312707),L_(0x000000b2), LL(0xa224f65a,0x4d9d7ef9),LL(0xaec9953a,0x62242fd1),LL(0x04665dd7,0x49b9eb5e),LL(0x7d7f1a35,0x6a03ee74),LL(0xcabc639f,0x22cc5c02),LL(0xf26d2603,0xbb312bf5),LL(0x05ee7955,0x10cf1634),LL(0x00c226f0,0x3baa95d6),L_(0x000000bc), + LL(0x56832121,0x968950c6),LL(0xa826a58f,0xe858945d),LL(0x3a7fc7e7,0xd63d6714),LL(0x63d3c677,0xc319d1ba),LL(0x349e7bde,0xb4155a1d),LL(0x03a4c66e,0x3ddc0044),LL(0x77aa278e,0xccce8941),LL(0xd867d113,0x4e46021e),L_(0x00000105), LL(0x2cac2d26,0x6dd54385),LL(0xd8308ab7,0x2e1458d6),LL(0x0d0a4aaf,0x924e3bd4),LL(0x309fb2fb,0x2f7cd47f),LL(0x5161e4da,0xbc75672b),LL(0x27fa09f8,0x0e420bf8),LL(0x6bf78336,0x83d1b09e),LL(0x3c3d3117,0x89323d7e),L_(0x00000197), + LL(0xe5de2792,0xe8b9e5f2),LL(0x9e4c557e,0xa63316be),LL(0xc510883d,0xfba63955),LL(0x58616eed,0x5eba66cb),LL(0x1f901bb5,0x7d93dd07),LL(0xe4c33f46,0xd7520d11),LL(0x9c2288bd,0x3c9b7282),LL(0xa3f22d4f,0xf979cce9),L_(0x00000016), LL(0x6b3408c8,0x69f91fa6),LL(0x1780ab39,0x9f2b3904),LL(0x1e17f9e9,0x0408a22e),LL(0xf102825a,0xe814b39a),LL(0x4077db13,0x717c70c1),LL(0x116e8d04,0x1642fd91),LL(0x5157bba1,0x072760c2),LL(0x223d53fd,0xf596860d),L_(0x00000130), + LL(0x0b6e1126,0xd03914a2),LL(0x1f8fa1cb,0xbc0f726e),LL(0xc55472bc,0x9dcf7393),LL(0xcc596835,0x86ab65ea),LL(0x0c9b7622,0x90362f16),LL(0x8c0ca08c,0xe8de2a3c),LL(0xec48a671,0xbde41568),LL(0x0286ac32,0xd27da64f),L_(0x00000038), LL(0xa6fda916,0xf6c82cd6),LL(0x53a87083,0x3e753ee6),LL(0xab548bed,0x07afab6b),LL(0xc34ddb60,0xc0dc2ddc),LL(0x378f8e85,0x399c4261),LL(0x5087e698,0x6f7e49f2),LL(0x07f39938,0x6345ae4d),LL(0xc730c9c6,0xb6c2765f),L_(0x000001f3), + LL(0x62619340,0xe4292c6d),LL(0xf4cf1a41,0xfb9a8b65),LL(0xf774c321,0x5046d341),LL(0x7b28d6b2,0xfe598075),LL(0xb06becbe,0xc3187f95),LL(0xd220a206,0xc278703d),LL(0x54ba06d2,0xb514e8c6),LL(0xda1d824d,0xc959300e),L_(0x000000df), LL(0xbb2a1c22,0x7fbd13f4),LL(0xec877f9e,0xd0e494f0),LL(0x209c6b0a,0x529b0f0c),LL(0xc6b1073b,0x50fb2f00),LL(0xd17f2e67,0x80cd82a4),LL(0x62378ddb,0x9f57c57d),LL(0x0162b312,0xc234e4cb),LL(0x8483d5e6,0x501d8ec9),L_(0x0000013f), + LL(0x4bb68070,0x0d037502),LL(0xd53d7a18,0x424ed14d),LL(0xd13f986d,0x29de6753),LL(0x3e4dbff0,0x6d33dc1f),LL(0xf6b77dc2,0x87ad5722),LL(0xbf6050c2,0xaea8f254),LL(0x83742064,0xb17406b4),LL(0x7d90e061,0x13b29245),L_(0x00000002), LL(0xb43c52b6,0x7f20e8bb),LL(0x5bf160f5,0x8562b323),LL(0x1d2d2e90,0x4b31d400),LL(0xea7b242c,0x4a1acb5c),LL(0x229d7510,0xc93f9b92),LL(0x3eba408b,0xb068a0e7),LL(0xb0525ab0,0xb376d6b0),LL(0xd96dff43,0xf1b03f82),L_(0x000001b4), + LL(0xd1e5c64c,0x77ddddf5),LL(0x631d2365,0xc4b6db39),LL(0x5fc5e812,0xd1cccab0),LL(0xc38ec807,0x8729f1a1),LL(0x1629e92c,0xc999e406),LL(0x6b4c00d1,0x781d88f5),LL(0x3cac8f29,0xcce3380c),LL(0x16b02141,0xc7e0e0cc),L_(0x00000120), LL(0xd88382b9,0x76234580),LL(0xd02da7d0,0xe2d27b0a),LL(0xcc82cf5a,0x3adad7f2),LL(0x2c08a15c,0x7009305d),LL(0x55fa7b4d,0xde9e632a),LL(0x0b55b693,0x2a821156),LL(0xb565732e,0x3788cf98),LL(0x89f0adb6,0x2d1f6054),L_(0x0000018e), +}, +/* digit=3 base_pwr=2^15 */ +{ + LL(0x5b21bde5,0xb0c6a7b6),LL(0x23a29c73,0x9c3eafc7),LL(0x392643c3,0xf81be3c4),LL(0x88c0b213,0xec734fa3),LL(0x33b98ae3,0x9b26d37a),LL(0x23074268,0x687a332e),LL(0x28354ec1,0x6935b64e),LL(0xf60d4b7e,0x9d55aecf),L_(0x000001a7), LL(0x910afa18,0xd6073362),LL(0x8bcd336b,0x5b5f67fb),LL(0xb6c7a784,0x5633e845),LL(0xdf601730,0xa907be72),LL(0x2814a576,0xfe65734d),LL(0xc7084b86,0x0758f113),LL(0xd7bad9f2,0x5030c22c),LL(0x3ef6af2a,0x7ff1cabc),L_(0x00000164), + LL(0xeb37269e,0x6184cce9),LL(0xac65525f,0x5051a406),LL(0xc9acc4f2,0x651c4a44),LL(0xb637bdd2,0x571fa6bd),LL(0x2ae9ce59,0x4cf1489d),LL(0xf56bdf32,0x61b0a821),LL(0xe5fa827f,0x9dcea620),LL(0x4b46a244,0x7027c9ed),L_(0x00000094), LL(0x0d4d4505,0x0495f1c5),LL(0x27a410cd,0xee6432c2),LL(0xbc9ba135,0x73536858),LL(0x53142570,0x7e39c350),LL(0xd0616e0b,0x316eeb65),LL(0xa694a069,0x55bbe949),LL(0x9aba0dc4,0x1f9d7b76),LL(0x32d36d72,0x1dcb7a1d),L_(0x00000004), + LL(0x4d5e5081,0x0fce6d79),LL(0x49c3fb55,0x3a2f9da5),LL(0x3a8e9a7e,0x44e158ff),LL(0xd771a67e,0x7de21bd3),LL(0xa6180b0e,0x5cf6b900),LL(0x349f9cad,0x53ff2b3f),LL(0x783786f1,0xe350b1ce),LL(0xec23cb86,0x58690faa),L_(0x000001ef), LL(0x09eb4774,0xe8902691),LL(0x4d7ea0cd,0xdfaca68b),LL(0x13648702,0x595a974f),LL(0x5bd316f2,0xbf226a22),LL(0xbb11b239,0xeaee978b),LL(0x2ab1e433,0xc7607b51),LL(0x870c9a0f,0x43795a95),LL(0xe00a29c5,0x53d7cad7),L_(0x00000060), + LL(0xfc15e51c,0x9b30d330),LL(0x8312448f,0x499ca6a8),LL(0x27c12fd1,0xaf5a132e),LL(0xc3fb765e,0x01b2d2a5),LL(0x07951a8d,0xce3517c8),LL(0x97c68ed6,0xe67d936a),LL(0x8cdd161c,0xad5eb28f),LL(0x795d9876,0x6496ac4a),L_(0x00000197), LL(0x4de7c0ea,0x7fd91252),LL(0x6e4dff62,0xe44601e6),LL(0xa96a9194,0x84a673b1),LL(0xf81ccae8,0x06054966),LL(0x2eba8c5d,0x53226945),LL(0x77e70b53,0x17deba76),LL(0x98891e5c,0x2fe55a92),LL(0xccf9a70e,0x8b39032d),L_(0x000000d4), + LL(0x4b1d8796,0x2c87d9f4),LL(0xce45ab56,0x0de1dc21),LL(0xa16d3789,0x72ace7c2),LL(0xe08192c8,0xe7012d3c),LL(0x4840d465,0x2d9fcc09),LL(0xd2d9e7c8,0xb83abe6f),LL(0x4dc89aa4,0x57f505dd),LL(0x58ef6f90,0xc12ca416),L_(0x000000e4), LL(0x0a635439,0x9e8dd733),LL(0x4f047388,0x1231cdd3),LL(0x536cd1c8,0x45523810),LL(0xd1e5a85f,0x4bcff7cb),LL(0x3fceb99e,0x86ad3d2f),LL(0x00ae1467,0xddf93ca7),LL(0xab6574df,0x4160edd9),LL(0x611238b6,0x0bbbbc9e),L_(0x000000eb), + LL(0x2f4ff50a,0x4b9dc9a7),LL(0x4e86b3f7,0xd56a4df5),LL(0xb7fc672c,0xc91daa4c),LL(0x047ac313,0xd8b04fac),LL(0x71df8b53,0xd047ffb7),LL(0x48cf7c44,0xe196a8ad),LL(0xbf663542,0xea4fed68),LL(0x45aa68b0,0xdbd49e0b),L_(0x00000083), LL(0x389e5cb0,0xd77d603e),LL(0x33664de2,0x5ef7dee2),LL(0x994f9685,0xc8ab10b1),LL(0x5e3c5bf8,0xf5ab3d23),LL(0xff2ae5c2,0xdbff37af),LL(0x9d0fd0f4,0x50db50de),LL(0xa6d91d52,0xe2c950fc),LL(0xa742da0b,0x0ec3836f),L_(0x000001c7), + LL(0xccb5796a,0xea3797f2),LL(0x00f8c37d,0x0b3e1166),LL(0xce0936fa,0xb532c55c),LL(0x204a444f,0xeef2ac73),LL(0xa6b09c79,0x31515d9e),LL(0xac9e3e09,0xdd05ab36),LL(0xe9cef435,0x319eb710),LL(0xfa2d9fd3,0x1d7ac545),L_(0x000000bc), LL(0x588c66b6,0x595b4001),LL(0x2f76c04a,0x0f70018c),LL(0x74e5849f,0xa9c62272),LL(0xb2abd908,0xaecd915f),LL(0x5ffbaabb,0x9fa73bfe),LL(0x111c8c5f,0x35b0554e),LL(0x77c9c2a7,0xcc8177e6),LL(0xe83b44a5,0x3bc6ae04),L_(0x000001ec), + LL(0x53c1578f,0x229b222a),LL(0xb1bb114a,0xff59f733),LL(0x887f6c13,0x2679cded),LL(0xbbad5dfb,0xd35dec8b),LL(0xea94d41f,0x90930770),LL(0xd4f0a601,0x2ad07da8),LL(0x2142901c,0x48f142ed),LL(0x692aaa86,0x252e4559),L_(0x00000142), LL(0x47539509,0x9b4f335e),LL(0x78c42f0d,0xc2716105),LL(0xfda89975,0x2c49b195),LL(0x35776137,0x3ac76051),LL(0x4de0d058,0xfcd0c4d5),LL(0x47ffa549,0xe11bc35f),LL(0x31f21817,0x3f57a567),LL(0x46ac2b10,0xcde0cd71),L_(0x00000084), + LL(0x3acc431b,0xaecaf4a5),LL(0xcd468ef8,0x60b977fb),LL(0xbcb8a438,0x3938f4bc),LL(0xcfcf5c2b,0x2c7337c9),LL(0x7bb844f3,0x23c47750),LL(0xdea5e248,0xf126971b),LL(0x47ee8dea,0x6f1d664c),LL(0xd5392932,0x3efa21b6),L_(0x0000018b), LL(0x3e152528,0x5940abfb),LL(0x28ef7f36,0x3e9bee76),LL(0x8f415722,0x360759cd),LL(0x11a30e1c,0x3c8733e8),LL(0x78196a73,0xc43394c7),LL(0xf3a60c7e,0xac3864e9),LL(0x776e1d00,0x0c19158c),LL(0x2e4681b7,0x517321cc),L_(0x00000040), + LL(0xcba05043,0x69bb2a3b),LL(0x59d22ba1,0x18bc1523),LL(0xee4d727c,0xbabfd9ca),LL(0x4c8338aa,0xe3550512),LL(0xa9cc3cca,0xe599b6e8),LL(0x15386807,0xc5ab3c64),LL(0x3919da2f,0xd2ee43d4),LL(0x801a4c6f,0x38ead934),L_(0x000001be), LL(0x64a97d4d,0x8b8c66b5),LL(0x7834d44e,0x74807217),LL(0x690ef307,0x926feb1c),LL(0x54c7151d,0xbe2f1f34),LL(0x456bd03f,0xc48ce8e6),LL(0x04a6964d,0xafec270c),LL(0xe8febbc7,0x483b3a5f),LL(0xd30f159a,0x96cb139a),L_(0x000000ca), + LL(0x77df0935,0x0e87f867),LL(0xf99ad667,0x75faf57c),LL(0x011dcb9c,0x6c05cb53),LL(0x4f1f75a2,0x3556cade),LL(0x2dea9ad0,0x3f87760d),LL(0xb590f7b4,0xe73b9512),LL(0xc497a74f,0x5a5a684b),LL(0x8d18f07d,0x8e2fa89c),L_(0x00000050), LL(0xb516cc59,0xc3adce30),LL(0x12408706,0x4d73c59c),LL(0xcce1c5bc,0x2ddcd22c),LL(0x381eb1ab,0x0b77c42b),LL(0x43827dd9,0xaee2e20f),LL(0x0ecadad8,0x4d7ed6ba),LL(0x141b0bef,0x69fa3aa0),LL(0x9ae275eb,0x3d138706),L_(0x00000114), + LL(0x3d8a013e,0x7fc0e976),LL(0x65d7b1d3,0xc8c06baa),LL(0x608a4b87,0x2e527b8c),LL(0xa2d8c259,0xcc19bb3a),LL(0xb09308aa,0x4ce5b0ad),LL(0x2458761d,0x7a6ee0f4),LL(0xd73d4f70,0xd791c442),LL(0x0d3867f8,0x3ba7a1a6),L_(0x00000094), LL(0xe51b0763,0x0e7ffca3),LL(0x467af3d9,0x60c44d23),LL(0x9427b9fa,0xe4a16358),LL(0xaff54ce0,0x55e4129a),LL(0x275c2816,0xcbefd5ea),LL(0x7c03c7fc,0xb7160ce2),LL(0xc97ca421,0x84bb35f0),LL(0xea69ee6f,0x35e0436e),L_(0x000001ec), + LL(0xfe162d02,0xf585af17),LL(0xbac45c7f,0xf7251745),LL(0xd6aa93a1,0x8a56414c),LL(0x8fa35248,0xf6e64410),LL(0x1720b12e,0x81f59ca8),LL(0x6cb0f80a,0x232a9916),LL(0x205cfe62,0x872efe0b),LL(0xdcba9616,0xa3d26e5c),L_(0x00000021), LL(0x9ac2f018,0x06a36051),LL(0x478ec567,0x7d42157a),LL(0xa110b6a7,0x0c863ff6),LL(0xb1e77441,0xa6979407),LL(0x7c13c78a,0x6a0ad3b6),LL(0x08c47fd0,0x34e0edd0),LL(0xcd2ed5cb,0x8df0c73d),LL(0x41a8e1a2,0x73883967),L_(0x0000012e), + LL(0x94304215,0x7d33b8c9),LL(0xa6572311,0x3fceee3a),LL(0x1482e2ca,0x52560262),LL(0x6d96dfdb,0xa105a9eb),LL(0xbdc41e36,0x8c0fd8b7),LL(0xa2f2edd5,0xb271c58b),LL(0x050043d8,0x4a51907c),LL(0xa79966a3,0x0fa52e13),L_(0x000000ee), LL(0x6d5fc916,0xdac2d706),LL(0x62accbe2,0x0b78e0d4),LL(0x8397028d,0x2c9d107f),LL(0x711b525e,0xfedd5666),LL(0x0c96203d,0x88395725),LL(0x2be09463,0xf9856d0f),LL(0x6dd96c8f,0x9c7a6702),LL(0x4398fe82,0xfc430b6d),L_(0x000001ac), + LL(0x41758c46,0xaa02764f),LL(0x7d06225f,0x36596aaf),LL(0x23dab345,0x0047b230),LL(0x1f940005,0x1c2f1ccf),LL(0xb4fb0f0c,0x82a82a8c),LL(0x589309ef,0xc66190cb),LL(0x19fbd0a3,0x839f41c1),LL(0x0fe2846b,0xcc1c9536),L_(0x0000019c), LL(0x917c26bb,0x729f81c7),LL(0x27782d0b,0x55359881),LL(0x76e1016b,0xcaad48a7),LL(0x26d82543,0xc89767f1),LL(0xcf1f4470,0xd4acb529),LL(0xe5b4bfed,0x7b75fd29),LL(0xae8ee068,0xc3d34db9),LL(0x3b3ffbcb,0x9c535467),L_(0x000001d7), + LL(0xe3f00489,0x9faba8ba),LL(0x5f421abd,0xe82276fc),LL(0x94ac402c,0x91f2efc8),LL(0x7d55bead,0x8241f32e),LL(0xcc1090d2,0xe8bce170),LL(0x19f59df3,0xe27350cb),LL(0x4ac35c2d,0x3e6cfc43),LL(0xd13cf90c,0x84bc2847),L_(0x000000a7), LL(0x54f1aa33,0xfd3f87f7),LL(0x2713cbe9,0x4fd8d338),LL(0x34163c33,0x46cada61),LL(0x7214cbe3,0x6aa94a54),LL(0x30a042dd,0xf7b92358),LL(0xe120acf2,0x09be500b),LL(0x30c3e8d0,0x51dc7f0d),LL(0x6f225e27,0xb7edd06e),L_(0x00000114), +}, +/* digit=4 base_pwr=2^20 */ +{ + LL(0xe47d13c6,0x20c1256f),LL(0x2fd11810,0x5aa78701),LL(0xc4a46931,0xea26a86c),LL(0x056b1163,0xbe00b905),LL(0xa0ac68e4,0x52f1dad4),LL(0xc19c5769,0xc6fde2d8),LL(0xbbc11dae,0x6293f810),LL(0x3a3baf9c,0x5056fba0),L_(0x00000137), LL(0xbfc9af73,0x5973f08b),LL(0x4cc716b5,0x8efce6c1),LL(0xb5b613b1,0x64d3ad94),LL(0x248f005d,0xba83b800),LL(0xa375eb34,0xc9ee4cf2),LL(0x413af2a4,0x68a27d29),LL(0x25ea8722,0x8d12fde5),LL(0xc9c082bd,0x2d233189),L_(0x000000fa), + LL(0xc1b123bb,0x85f1bef2),LL(0xa73fb5cd,0x111a8c9c),LL(0x1a80d76a,0x8d3b7461),LL(0x2e325f88,0x7765b87f),LL(0xc8ad9e3f,0x92e36012),LL(0x2c7cf6c4,0xbf5a9dc4),LL(0x7d5db366,0x6228a81d),LL(0x915359f9,0x725123cd),L_(0x00000172), LL(0x2cfcba5e,0x8b6c7a0e),LL(0xa38cc5da,0xee14f97f),LL(0xb43bb38e,0x770c4afd),LL(0xaa0f15c0,0x138850f3),LL(0x3953b993,0x2658cf7e),LL(0xb70f0779,0x1d447c8b),LL(0xd78fd38c,0x681177a0),LL(0x8e23ebe4,0x704ca751),L_(0x0000009d), + LL(0x527a9d3e,0xba8fa7e4),LL(0x4e9fda74,0x334944db),LL(0x404855f4,0x65201753),LL(0x31df130f,0x19a9846d),LL(0x661cb9d7,0xbc651ab9),LL(0xc04c2995,0x91c2b653),LL(0x1b2c3fb5,0x1b65fb33),LL(0xc90b91d2,0x9233b624),L_(0x0000001f), LL(0x061f9eb8,0xfceac108),LL(0x86d9cc5a,0x4cdd0a2e),LL(0x0e2ec8f9,0x309b7d38),LL(0xf2c40675,0x0d2223f6),LL(0xc1e34e32,0xa3be480d),LL(0xb364f62b,0xec527b72),LL(0x3595753d,0xf6639f06),LL(0x4e283d90,0x67ed0c35),L_(0x000001d5), + LL(0xd4783247,0x5667e2e3),LL(0x2b33e937,0x711cfb9d),LL(0x5cc9c7d0,0xedf0adb9),LL(0xc5aaa7c2,0x610b704f),LL(0x770150b6,0x1107368e),LL(0xf9af2a47,0x06e6cc4e),LL(0xfe1e566d,0x814dd0ca),LL(0x7ca67146,0x6c67f663),L_(0x000001d3), LL(0x3ca6a46e,0xecb744b3),LL(0xd960d19d,0xc0bcfa2a),LL(0x99ff41db,0x933b28a6),LL(0xb97977ca,0x951faf63),LL(0xca3752a7,0x15168f23),LL(0x01e0f16b,0x4ea397d9),LL(0x05f55f96,0x3b374a51),LL(0x813c0d40,0xe408ed3a),L_(0x00000143), + LL(0x0a55f862,0x937586c5),LL(0x83c230d0,0x61062265),LL(0x9c8f1eaf,0x10419f67),LL(0x2c698769,0x8d67dbad),LL(0x4407836e,0x4c3c184d),LL(0x99fd2f81,0x52a37538),LL(0x7825fefa,0x45a721e3),LL(0xfff07585,0xa4b823d5),L_(0x00000098), LL(0xd4ed2584,0x96e376eb),LL(0x6a23fbe4,0x5f76504d),LL(0xb69ec350,0x545afc26),LL(0xfb28fe6b,0x87ed2073),LL(0xaf95f20e,0xa6145047),LL(0x4d27cd1b,0xc4cc53f8),LL(0xa35d865d,0x9ee96b7f),LL(0xb07b711a,0x430aefde),L_(0x000000ec), + LL(0x69146afc,0xc7354ba1),LL(0x9fdb88ca,0xdc64a8c7),LL(0x9f85e2ef,0x7f3a69d0),LL(0x5631012d,0xd2bed232),LL(0xfd4d1f17,0x04dfd89c),LL(0xe64d46be,0xd5598288),LL(0x9f8bf20f,0x1f269d18),LL(0xc11d0864,0x333e29ff),L_(0x000001fc), LL(0xb8320599,0x9cc7dab1),LL(0xbbef8e94,0x5c714223),LL(0x7f10fed7,0xbb61d266),LL(0x09c647b0,0xe823dbf3),LL(0xf58db2b8,0x4601c5a1),LL(0x3a71fa3e,0x344f9c02),LL(0x0b5cbdd6,0x77b11f1a),LL(0xf8df6a65,0x6eb12db5),L_(0x0000007e), + LL(0x2c64c2a6,0x0db94e9f),LL(0x9c4cc346,0x646b9dff),LL(0x339e03c0,0x7ae26f18),LL(0x64dca76c,0x2ba1712f),LL(0x2c804061,0x16950e5f),LL(0xb5bf0fae,0x13d1569e),LL(0x185858b6,0x5b35ba86),LL(0x6880b124,0x3c937406),L_(0x0000019a), LL(0xe1c9646a,0xee5f1c44),LL(0x96f83044,0x10924610),LL(0xe69176fe,0x5cfb2614),LL(0x324a7887,0x825516a8),LL(0xfbad9007,0xc065d69c),LL(0x3d71727b,0x06621f87),LL(0x85c81c53,0xe21856f1),LL(0x3ac1471a,0x68582e4e),L_(0x0000007e), + LL(0xb68f07c0,0x9ace1c67),LL(0x5469124c,0x24f3ddfa),LL(0xccd6db20,0xaadd52b4),LL(0x74a2fc6f,0x24af0765),LL(0x17b27151,0xb5105915),LL(0x118a106b,0x7e240081),LL(0xcffda2d6,0xc6925ec7),LL(0x88b3b39f,0x37b374e2),L_(0x00000120), LL(0x541ec518,0xefd91b81),LL(0x3a683e17,0xa72b7c41),LL(0x952a60ed,0x0495c130),LL(0x9c4b61d8,0xbf06a574),LL(0x872c4bf6,0x0c7cbd39),LL(0xe01cb7ce,0x989f1a82),LL(0x726d7547,0x44906b41),LL(0x52742de9,0x2e02ff37),L_(0x0000009f), + LL(0xeedd6da3,0x8dd4b66d),LL(0x73240fb0,0xb6e39bb1),LL(0x1303b771,0x195468c6),LL(0x7bd7b8e4,0x9c3d4d09),LL(0xa8684e6d,0x724f9017),LL(0x31c9bec6,0x2fd691e3),LL(0x727ff44a,0x5f3d4db7),LL(0x89060924,0x984ffa88),L_(0x000001b0), LL(0xcf998e88,0x0c1bfdeb),LL(0x6d85f7e8,0x4b0cbc59),LL(0xccccc632,0xe1faf1ce),LL(0xc7a0620b,0xf6e95c18),LL(0x0aa71a3a,0x8fa50a9c),LL(0x49a07249,0x8cf3e64b),LL(0xaed36f6a,0x94bd6377),LL(0xa4cf33ed,0xeb0073d7),L_(0x0000013f), + LL(0xadc752d7,0x87c3614b),LL(0x53d1d5ef,0xaa78183f),LL(0x8ea4ef11,0x5c12de26),LL(0x84a5c0b0,0x3315c75e),LL(0x4f1d31e4,0x0d7a1bdb),LL(0x97ef83ed,0x8d2ce325),LL(0x91dd29d3,0x3340be93),LL(0x184b8ada,0x0f8f6087),L_(0x000001c1), LL(0x9fad91c5,0x8ce9dccb),LL(0x96d5b0b9,0x641d29f6),LL(0xb48f1d66,0x50813cfd),LL(0x8881842c,0x7ff13a32),LL(0x3fa7e856,0x78eaa08d),LL(0x7984e336,0xfbc798ef),LL(0x67c2e064,0xb3fc5a0a),LL(0x23e92b2d,0xe38a9115),L_(0x00000008), + LL(0xb65bfdd1,0x3691b2b4),LL(0x9b215aee,0x5cf3f209),LL(0xa1d61cff,0x4a0f639e),LL(0x2783ba69,0x62cddd5b),LL(0x1490682d,0x5648b7c2),LL(0x074ffd3c,0xeb8c7a90),LL(0x0e9bddbd,0xf3751b7e),LL(0xbce879c7,0xa3bfa1d5),L_(0x000000d9), LL(0x8d0510d3,0x20a30aeb),LL(0xe42922b6,0x3498a06c),LL(0xa129b145,0x26cc79e5),LL(0x9d307ed3,0x1c156f64),LL(0x2baf6215,0x14f481b2),LL(0x9b79cac0,0x2eb38c02),LL(0xc564e629,0xde0cf55a),LL(0x24a1582a,0xad5a0f7d),L_(0x000001d5), + LL(0xea9885d3,0xa68ccc39),LL(0x6997bdf9,0x05de1b77),LL(0x553e670c,0xee7e6f6d),LL(0xadae5917,0x199db8cd),LL(0xecf2088a,0xc33572de),LL(0xa41c0fa0,0x7b432d00),LL(0x1dc922e3,0xc58b8529),LL(0xb5615888,0xb9f1df40),L_(0x0000017e), LL(0x8b5496a0,0xe11804a4),LL(0x9626517b,0xb50d5ff0),LL(0x34399d8f,0xeb302429),LL(0x18d0e9c5,0x47c13487),LL(0x18ec316e,0x851d2afc),LL(0x1b701f2c,0x167d9f22),LL(0x883a9116,0xa8f932f6),LL(0xc3a9d8fd,0x0da0e796),L_(0x00000102), + LL(0xd19a69ad,0x029cd0ab),LL(0x5d899070,0xb5278a7b),LL(0xe7ecc032,0xabde08a8),LL(0x9fa79438,0xd3d2c019),LL(0x80363047,0x66ae4725),LL(0x141bc210,0xeab542c4),LL(0xdf1d8696,0xd1c060a0),LL(0x3908c1f0,0xfa788627),L_(0x000001d3), LL(0x31ffefe1,0x677d387d),LL(0x76fb5476,0x05f7c0d8),LL(0x3a298203,0x2097dc46),LL(0xe5119f75,0x1f8bd7b9),LL(0x5996aa0e,0x61982b25),LL(0x92c77df7,0x119a9371),LL(0xac8b008e,0x7f9b0675),LL(0x346bbe9d,0x8f2407d2),L_(0x00000037), + LL(0x68bd6724,0xab5b8457),LL(0x52f7bee1,0xbc2db536),LL(0x07aae0d0,0x58623dce),LL(0xa3e03da9,0xf444f5c3),LL(0xe7b9b75d,0xdb04bbba),LL(0x8fa837de,0xb065c230),LL(0xed346416,0x51909adb),LL(0x16d6222a,0x3c084209),L_(0x000001f1), LL(0xe28ca284,0xdf2f5e19),LL(0xbbb390fd,0x38ba1ac8),LL(0xc03099bd,0xa1e828bc),LL(0x6f1d5124,0xb83c59a2),LL(0xfd863005,0xc17a0d0d),LL(0x97857c15,0x2d92fc6c),LL(0xd53a6942,0xb70e5498),LL(0x36d4d6e3,0x368524fa),L_(0x00000187), + LL(0xb1d0aee2,0xc5143f3d),LL(0xcda50c31,0x34bd47c0),LL(0x5f0ed71c,0x1dee87b7),LL(0x24882cc9,0x7e3bbffb),LL(0xd1c7d1fb,0x1e403329),LL(0x92474fcc,0x53d4ee41),LL(0xbcade2fb,0xbd25257b),LL(0x48035309,0x1ff4afd1),L_(0x000000f3), LL(0x35e3b8a0,0xf76b6465),LL(0x54f67634,0x6c3176f4),LL(0x76970368,0x7bbaa2a0),LL(0xe3ebf308,0xc5082d82),LL(0x65ccfb3f,0xec84bb5f),LL(0xf3b5795a,0x4999273e),LL(0xa51dd238,0x7a764cec),LL(0xe6317658,0xd0cd1c12),L_(0x000000d5), + LL(0xcba7983d,0x440872f1),LL(0x28a369cd,0xf5dafa9c),LL(0x07ce63b6,0xc12c54cd),LL(0x4f79c12d,0x0a67eec8),LL(0xee7a34a0,0xdbc7a4ed),LL(0xff4e7f63,0x40f7ea82),LL(0x50ab4929,0xdc3353f9),LL(0xcd953027,0x1b37a3c6),L_(0x000001e2), LL(0xb77d6e77,0x4c5f758a),LL(0x416ce18f,0xa1adfbab),LL(0xb9e45e70,0xa53a6ae6),LL(0xf8e38074,0x19bbc5ea),LL(0x639d3359,0x66580a40),LL(0x3c3446f8,0xabe333f8),LL(0xf20b5de7,0x703c0639),LL(0xd4a42c48,0x59dbbfad),L_(0x000000d6), +}, +/* digit=5 base_pwr=2^25 */ +{ + LL(0xc7d07442,0xd025b49c),LL(0xa66a4107,0x4a0b9d5c),LL(0x09a27870,0x383562d7),LL(0xb8b27e26,0x8bfb3e1f),LL(0xcd156bc2,0x06132452),LL(0x49ca82ac,0x92d3d9a2),LL(0xa22d3a0e,0xd34655b5),LL(0xa2b19aaf,0x36ff20de),L_(0x0000008d), LL(0x5835a5bc,0x86f6b302),LL(0x1143727c,0x8192a853),LL(0xc5c00385,0x52b2fd4b),LL(0xdaf1da93,0x5e79d62b),LL(0xde7c27d2,0x23c74903),LL(0x18fc4730,0xd6b3ad47),LL(0x3e48286e,0xe1fb2466),LL(0xde5e2dbe,0x558feb16),L_(0x00000057), + LL(0xf7f37af3,0xf33aa997),LL(0x399f83a0,0xac6eebd0),LL(0xf152344e,0x1e36ba58),LL(0xb233cc5d,0xbcb7b01b),LL(0xb95ccb58,0x0e6e01c3),LL(0xbd70b347,0x28b73f3c),LL(0x471f1429,0x192a8fa5),LL(0x72f33fe8,0x51b82a42),L_(0x00000077), LL(0x1a1be232,0x91ea1f80),LL(0x29d67e20,0x9219d0e0),LL(0x355df0fe,0x86128187),LL(0xb88069ec,0x196ceb57),LL(0xc5d6f3e9,0xcb831fc0),LL(0x61a90e72,0x76ccb185),LL(0x875cf514,0x775daca6),LL(0x5e9d0fdc,0xf11fb0d6),L_(0x00000156), + LL(0xc6a99de8,0x4f6f0528),LL(0x8365a540,0xd607f5f7),LL(0xa6130da7,0x85d457a1),LL(0x282ce8f3,0x7a71db8c),LL(0xf22e8e12,0x675b1780),LL(0x1ed981d1,0x54455f27),LL(0x879b7161,0xd4c8d2d0),LL(0xe53f2395,0xfbb885ea),L_(0x0000002f), LL(0x9830814f,0xdd4e8a69),LL(0xc1a29f03,0xd15d6f60),LL(0x620f1843,0x51aa6497),LL(0xb9253703,0x3bdc3d85),LL(0xb15aa83f,0xd5713630),LL(0x38bafd76,0x46f5b250),LL(0xa324c450,0xc7ef0e3a),LL(0x428ff854,0x3074cd9a),L_(0x00000187), + LL(0xda6a189a,0xdb38150e),LL(0x98edde21,0x02c3ed54),LL(0x10e8c4a8,0x92441512),LL(0x5d3d5708,0xf9b009f9),LL(0x785d69a6,0xac80e954),LL(0xa197859e,0x166d8dbf),LL(0x9a954ad6,0x5cac81cf),LL(0xd5536054,0x01aaa83b),L_(0x0000002d), LL(0xc362ba43,0x578a0342),LL(0x2cf62469,0xb8dd8820),LL(0x8c4987d0,0xc2b48e0f),LL(0x3b1becfe,0xd5c621a6),LL(0xa90343a0,0xf668f2b6),LL(0xfe098700,0x9c088bd4),LL(0xbd8fa882,0x3f0936a8),LL(0x67794851,0xae92e720),L_(0x00000133), + LL(0x96b1f8f9,0x45dfbf2f),LL(0x3cd0f06a,0x39d3c154),LL(0xf941b6e2,0x350febe9),LL(0x2d076edd,0x4d560b52),LL(0x55928e0b,0x2b184b05),LL(0x9f1196dc,0x85b25794),LL(0x6b4f0570,0x942eaf69),LL(0xe7c1e0be,0xd7c08589),L_(0x00000017), LL(0xe3a9890c,0x7bc564b2),LL(0x3dbde8c2,0x8d95012a),LL(0xeff3d407,0xa7b28d48),LL(0x08aae60c,0x1b0df773),LL(0xe7d844e8,0xf5cd9389),LL(0xe907a4ac,0x0fa28183),LL(0x6e40930b,0x381dd63b),LL(0x20fcef80,0xa89662a0),L_(0x0000003a), + LL(0xbd48b590,0x33be7ac9),LL(0xf700265a,0xf01390c9),LL(0x82de52e5,0x6ffa798e),LL(0xd0dd94ce,0xd994953e),LL(0x2a40701e,0xdc206da1),LL(0xf9937624,0x9641d8d6),LL(0x68b09fde,0xfb08d3aa),LL(0x515609bd,0xc7a5c685),L_(0x00000107), LL(0x81a858ff,0x34c11eaf),LL(0x007f99c6,0x3e931cb9),LL(0xfb91b432,0x97268272),LL(0xb16a5f9f,0x14f51fca),LL(0x22fdf379,0x448325ce),LL(0xa5ef4116,0x36a8c292),LL(0xb6fe6cbe,0xee4ed4ed),LL(0xd30012d0,0x5ebc5cb5),L_(0x00000061), + LL(0x4947635b,0x6edf3f2a),LL(0xc68eb226,0x00200346),LL(0x880aea4d,0x8d31f029),LL(0x006895c8,0xf085775e),LL(0x89fcfc5e,0xd25cf0d0),LL(0xb2a191ee,0x4508a2eb),LL(0xc9428552,0x90ca4e90),LL(0x22abade9,0x985e1eac),L_(0x000001a8), LL(0x90df5f6c,0x31e5ce6f),LL(0x96705235,0xdb11d250),LL(0xee984de1,0xfa51e382),LL(0x06a31aa7,0x47482dcf),LL(0xb9587e74,0x988048ce),LL(0x51593c99,0xca987f12),LL(0x6fe30df1,0xffd978f6),LL(0xfa604f59,0x8e6925df),L_(0x00000032), + LL(0x4c96e5ee,0x24f8517a),LL(0x039e54c1,0x2549eb0e),LL(0x1ec83d52,0xeb02627a),LL(0x18a8ead8,0x95771e96),LL(0x497c2cef,0xd4f3a6b4),LL(0x1c4917c7,0x080b55a4),LL(0xe8babd80,0x90585b7b),LL(0x6c548c79,0xdabe54a0),L_(0x00000064), LL(0x978d3828,0x2b269bac),LL(0xdf9b98b0,0xc4ed8c6b),LL(0x0247e075,0xd8e1a299),LL(0xbc830716,0x019c94ed),LL(0x3458f33a,0x9c1665fb),LL(0xcd4d82fa,0xff63e700),LL(0x2326e507,0x41c9bbfa),LL(0x5b452b83,0xc9214a3f),L_(0x000000df), + LL(0x23971495,0x3a39f3de),LL(0x6207af25,0x48efebf2),LL(0xe105123f,0xc14c4d56),LL(0xe2f0d038,0xe91d26ba),LL(0x4b6de581,0x4ec88307),LL(0x8f223417,0x0cd6e3f2),LL(0x6ecd94a5,0x986d1a76),LL(0x75765814,0x6e247362),L_(0x000000a2), LL(0xb07a61db,0x8b83a718),LL(0x6e918a1b,0xc07b54ba),LL(0x67b07959,0x22adb8dc),LL(0x96a7a38b,0x2810db83),LL(0xd80ec3cd,0x512687fb),LL(0x3b7485fc,0x6a994329),LL(0x746aec5a,0xd193ecb8),LL(0x6e8d782e,0x72720264),L_(0x000001e3), + LL(0xd528a6e2,0x18efe68e),LL(0x7f9ec076,0xd1c7c3de),LL(0x2cb36021,0x39cd1c50),LL(0x4584b14d,0x997b5332),LL(0x4275cf71,0x8ac5db4a),LL(0x47f829e4,0x0bc80acc),LL(0x41dd84b4,0x93021863),LL(0x498e9e29,0x6c2be4f1),L_(0x000000f7), LL(0x3b0142c7,0xa59f6acf),LL(0x50030fe6,0xbe6f68fb),LL(0x21480f26,0x217fd94a),LL(0x7a75421a,0xfc5b6dc5),LL(0x7f8cd384,0x19e9f3af),LL(0x674a2419,0xd009b54a),LL(0x454fa1ef,0x6bd82b7f),LL(0xf5bea7db,0x31688d56),L_(0x000000fb), + LL(0x5eccd42c,0x24d7621f),LL(0x92168834,0x1fc413da),LL(0x47855bbd,0x13a9e461),LL(0x17199daf,0x4e3536bc),LL(0x42c2a13c,0x2b4a64a6),LL(0xa8670cf2,0x38d86ada),LL(0x6c221d69,0x68ee0d8d),LL(0x91def21c,0xa5126dec),L_(0x000001f3), LL(0x87485e27,0x03f14fd3),LL(0x378bafe9,0xef0ab60c),LL(0x11be6eda,0xe18440ad),LL(0x59ce941a,0xead8d861),LL(0x59cf0928,0xd51985bf),LL(0x608dbb83,0x54f87d88),LL(0xb568f14f,0x15b84493),LL(0xb574903f,0xbc432c12),L_(0x0000006d), + LL(0xe7e4f826,0x79d38b74),LL(0x7eaa6aae,0xf84e0117),LL(0xdb942db5,0x77a0b212),LL(0xd22fb9bf,0xc56ffa35),LL(0x3c3e0310,0xdf48ef3e),LL(0x9f901558,0x372e6e7b),LL(0xa69d9dbe,0x0da5fd74),LL(0xeaa231af,0x1a06775c),L_(0x000001b6), LL(0x0771a3ac,0xd09d3577),LL(0x7802613d,0x61b4d69e),LL(0x19ba2ee8,0xa78fefe1),LL(0x46a7d09b,0x7be0e7b7),LL(0xedbd7a6a,0xed289bee),LL(0x894b4148,0x613e6a64),LL(0x4ced52a0,0xf2a487de),LL(0x58c856b6,0x802d7250),L_(0x00000032), + LL(0xffe70196,0xd1a6df86),LL(0x365ca885,0xca64af53),LL(0xfb62f8cc,0xbd654db8),LL(0x7be4b7f7,0x029300b0),LL(0x8e5d1bd5,0xc892e13f),LL(0x2c67f87f,0xcc4777a4),LL(0x8b3a46c0,0xba6516c2),LL(0x7400b2a4,0x6cbe8178),L_(0x0000003d), LL(0x43d5f5dd,0x24153eca),LL(0x540f05b7,0x19221aa5),LL(0x97f95061,0x09e289a2),LL(0xbba5984c,0xf2867a5f),LL(0xa0f6739b,0x0f075e42),LL(0xa0718647,0xab768457),LL(0xa0b31eb8,0xae89b1c6),LL(0xf7e66ea8,0x127d85c9),L_(0x000000df), + LL(0x49e4dae9,0x6d5a6301),LL(0x8cd94792,0x3dd861e6),LL(0x97b8baf4,0xfe513cef),LL(0x04f520d2,0x71773dad),LL(0x05832bb5,0xe9f256e1),LL(0x644c2754,0x40df1966),LL(0x700981f0,0x9215b453),LL(0x5dacb6f1,0xc1eb3c97),L_(0x000001dd), LL(0xd29b37a5,0xbd504fe7),LL(0x365fddbf,0x8fd2242a),LL(0xc2c35f7a,0x4bda285f),LL(0xc1adbae0,0xe964cfd7),LL(0x9f4dbf4e,0x29f5bb5b),LL(0xebe1db2e,0xaab3521e),LL(0xeb26c679,0x17b1e0d2),LL(0x460499ac,0x5a9383dc),L_(0x0000000a), + LL(0xbe71a28d,0x13ec332c),LL(0xb2a67fff,0xb50e03f5),LL(0x50971210,0xfca3bc03),LL(0xa67e12aa,0x4ad52b09),LL(0xbb90dbda,0xff71aa12),LL(0x0edb116e,0x6d43afd2),LL(0x0827d59a,0x97de7056),LL(0x29d216bb,0x7a131b7f),L_(0x00000160), LL(0x6cd8ac84,0xb922ac22),LL(0xfa7cdb03,0xf832d6ed),LL(0x58c5a459,0xd373c013),LL(0x7af850a7,0xec4706eb),LL(0x2c0a7082,0x67642828),LL(0x10a909d7,0xae5e13c9),LL(0xab317113,0x5697d646),LL(0x62e5e289,0x83fffcd8),L_(0x00000122), + LL(0xf34910df,0x331109fa),LL(0x16fb0987,0x7dc5b06e),LL(0xf23db224,0x62c76a0d),LL(0x3f2f53ef,0xf6843163),LL(0x41397218,0x63cbe6a9),LL(0x6d05ffc2,0xb14a253b),LL(0x7ed103a8,0x8ee0b454),LL(0xf389d693,0x3310d7c6),L_(0x0000014f), LL(0xe61f0fe2,0xe3ae5ea5),LL(0xeba63d9e,0x281cc803),LL(0xff5d7d44,0x5a289454),LL(0xfa26da52,0x8b5bf3e7),LL(0x8b9a0868,0xf6c91ab8),LL(0x565a2877,0x10a39907),LL(0x737c0212,0x1223d6a1),LL(0xe131db55,0x19f277aa),L_(0x00000014), +}, +/* digit=6 base_pwr=2^30 */ +{ + LL(0x77485e2c,0x205e28d0),LL(0x97a1a0b2,0x662c120e),LL(0x6679b5d8,0xd256806d),LL(0x56f0da8b,0x5177882d),LL(0xb3a0c292,0x1fd447d9),LL(0x15eb4fc8,0xd44b077e),LL(0xf15d98b7,0x44ac5bb0),LL(0x2721ac99,0x38b1a539),L_(0x00000164), LL(0xb3161c22,0x2615ec8d),LL(0x7c193099,0x6014ef39),LL(0xde0771a4,0x7929bb3e),LL(0x2d975e02,0xcd3fad00),LL(0xd387bd9d,0x38c634c3),LL(0x4ebf2479,0x08079c3f),LL(0x2c2da2b5,0xe2b2209a),LL(0xd2e85151,0xbb80ad2e),L_(0x000001f4), + LL(0x3d0b9c70,0x8f90c95c),LL(0xb8f686b4,0x17d91844),LL(0xa7467794,0xb498e1e2),LL(0x354bd2f6,0xdf2e61e9),LL(0xaea1ed2a,0xb0db08d1),LL(0xf347f08d,0x02cba497),LL(0x78713784,0x5de0850c),LL(0x51753c73,0xed5b7079),L_(0x000001f9), LL(0x5f819b71,0xd4d045e4),LL(0x91e83186,0xd4180245),LL(0x2f07b1ad,0x059bab68),LL(0x1d467074,0x2b0f371c),LL(0xb0e391ea,0x80e5f219),LL(0xf22e68c2,0xb058f844),LL(0x79b7f960,0x6ca98996),LL(0xd1250203,0x1f63acdb),L_(0x0000008a), + LL(0x8ce35c47,0x6f5a9e54),LL(0xbda97f65,0xaf7af291),LL(0x3726d93c,0x49f05287),LL(0x2f95260a,0x41ba40c2),LL(0x77d547dd,0x957f51b5),LL(0x05f74755,0x8ef3d171),LL(0xabb35056,0x131fa675),LL(0x73e0ad7e,0xf2cdf14a),L_(0x0000000e), LL(0x411ad210,0xe74e4c04),LL(0x5dd32692,0x56454c03),LL(0xbec75c70,0xcf373902),LL(0xf969fbf4,0xcc237598),LL(0xc6be1f8c,0x25a52045),LL(0x1317acb0,0xbd2ef98d),LL(0x4c09bec9,0x87e896e1),LL(0xa4033c40,0x16b064d0),L_(0x000000c5), + LL(0x9acb75bc,0x2223b656),LL(0xf580463d,0x7a55f8bf),LL(0xbd3d896f,0x19d6f3c8),LL(0xdc1bc358,0xf8dfdd32),LL(0xa2786cfc,0x57477a57),LL(0xae5589b6,0x9f47a3b0),LL(0x06de5eae,0x93f21788),LL(0x2c782fcd,0xd9479ee3),L_(0x0000016d), LL(0xbeebc5d3,0x0929435c),LL(0x52a35de2,0x5b11dd83),LL(0x4ce809af,0x080ab8c3),LL(0xe25a76cf,0x50478b1c),LL(0x216bfb22,0x103b3ff7),LL(0xd87f4762,0x99b34133),LL(0x41327480,0x95f627aa),LL(0xa729b689,0x62b3cf30),L_(0x000000fb), + LL(0x2f95c649,0x721c2b47),LL(0x251bc403,0xb04b42b0),LL(0x43b1fedb,0x73ae072d),LL(0xe91e26a3,0x0d23d9bf),LL(0xbe237693,0x40c88f4f),LL(0x3424beb1,0x6a55a156),LL(0xa0854744,0x26b2b7ac),LL(0xd61d14b6,0x4ee7f1ff),L_(0x0000000f), LL(0x0da4f895,0xa08faeb0),LL(0x9b46600b,0xfac400c9),LL(0x541f8756,0xfa469aa7),LL(0x961867a9,0x9f699a76),LL(0xaf3ea90e,0x6fa24828),LL(0x87c1ec18,0xb4eae9ea),LL(0x13538c6c,0xd16f2fd6),LL(0x3f2706c2,0x1ba2b83f),L_(0x00000147), + LL(0x792b76d7,0xbdd4d4a0),LL(0x305ae6fd,0x1d7bb497),LL(0xfd52a449,0x143fec43),LL(0xf6e16ac4,0xebf21b11),LL(0x8a70f179,0xdc6c0238),LL(0xb6be355d,0xd156ead0),LL(0x45178899,0x91cfd7f1),LL(0xdeb4b443,0x63af6554),L_(0x0000001a), LL(0x3a841a01,0xc755678e),LL(0x78e21693,0x747e0d46),LL(0x04110693,0x8c5bb7f8),LL(0x878fdb74,0xb933a4bb),LL(0x90576198,0x4a53f37a),LL(0xb6123d17,0x9e11e3a2),LL(0x6fc61c48,0xf4f2778d),LL(0x0bd5422a,0x78936064),L_(0x0000002a), + LL(0x889e1c3e,0x1cdfc255),LL(0x0e89d4d5,0x620f831a),LL(0x353a0af0,0xb276e069),LL(0x687747f6,0x848dd0c6),LL(0xf27dfd62,0x0bb6c7d1),LL(0x05846ed2,0x561ca5d7),LL(0x17ec1af8,0x39a2756b),LL(0x4280d8ec,0xf4bc9db5),L_(0x0000002c), LL(0xe51a0c90,0x827b9727),LL(0x96e34ce9,0x3fe216b6),LL(0x79c77aa0,0x6720f347),LL(0xfad412f9,0x695ff127),LL(0x74dee9fa,0x5f1b0845),LL(0xe65f23d5,0xbfbfe9e6),LL(0x3e545ad7,0xe1c9f0ed),LL(0x92d8678d,0x9914fd4c),L_(0x00000088), + LL(0x3d108b40,0x479267d4),LL(0x0396f4d9,0x88692b5b),LL(0xb1e5f7f0,0xfd9437e3),LL(0x9509c3c1,0xb9b9b7fa),LL(0x15a75e6c,0xba37b6c1),LL(0x5b42f650,0xdbbc62d0),LL(0x5b3cf510,0x6d5fe62d),LL(0xc6a49bf0,0x824e6593),L_(0x00000049), LL(0x6b1fb538,0xcc7f70f3),LL(0xeb94fc53,0x6a2b34a3),LL(0x82c0e60f,0xea4bc9d4),LL(0x8f42888a,0x7ab9ed31),LL(0xc0fe3ed3,0x1a505ae0),LL(0xe94fad3b,0x545382c9),LL(0xfa0f3128,0x9ae4fb8e),LL(0x44bd4be6,0xa516fe88),L_(0x00000003), + LL(0xb0f06a74,0x5455aac0),LL(0x2a8889b3,0xc9b0d66d),LL(0x1c5bf83e,0x736f64af),LL(0xeb5d7b9e,0xb0411171),LL(0xfd19cd82,0x22d46926),LL(0xdc65529f,0x1a902efa),LL(0x2603fa26,0xa829e75c),LL(0x4e40cf1f,0x25ea27fc),L_(0x0000007d), LL(0x5762e183,0x4b68fce9),LL(0xe6bccc3f,0x83ed8b75),LL(0x047d0099,0x864c3567),LL(0x85060d1b,0x1ddc1dd9),LL(0x3ee4ae76,0x974e9669),LL(0x389206d2,0x6126092a),LL(0x91ac46ae,0xe4c7cd87),LL(0x450710f2,0x9e581f06),L_(0x00000040), + LL(0xa9671b83,0x291b3bd9),LL(0x42264245,0x08f40ce6),LL(0x9254ae8e,0x244beb5d),LL(0x6f14d800,0x0b345a89),LL(0xe0141c82,0xb5b0de4a),LL(0xf52d10c3,0x2ca8fb1f),LL(0xebf183aa,0xdb884d75),LL(0x8611998a,0xd2bb9afb),L_(0x0000019a), LL(0xf19b2de4,0xa6d267bb),LL(0xe6bc257b,0xf0568557),LL(0x2160d875,0x6b9e2dd7),LL(0xb1fad31a,0x9c709714),LL(0xed3d24a8,0xf7d05de5),LL(0x61431dc5,0xdc526178),LL(0x0501b15f,0xe40e89ee),LL(0xb2aa5088,0xf3025f1d),L_(0x000001f8), + LL(0x7bfa3bb6,0x859759f0),LL(0xb249eb45,0xff4d25bf),LL(0xb8020268,0xd9737355),LL(0x9d4a831f,0x84343cef),LL(0xba7e139e,0x5bb5557e),LL(0xb24bfdbf,0x3ab8fb19),LL(0x31a1b161,0x3fa57146),LL(0x4ec60d24,0x01fac245),L_(0x00000125), LL(0x4ddf36d2,0x3e8c0bac),LL(0x5b116d34,0x0f307133),LL(0x62db28ba,0x9a0533b5),LL(0x0939b6eb,0xacf1cf00),LL(0x89d1c401,0x693e7c92),LL(0x4b14c89d,0x0945b630),LL(0x4ed7b53a,0x4b162dc1),LL(0x79a7fa4b,0x3e6b7dc4),L_(0x000001c0), + LL(0x591d8c23,0xb35e8088),LL(0x24bb4a7a,0x9e47ec6e),LL(0x968fd370,0xe7d95582),LL(0x474d55e3,0x783f2538),LL(0x9d35c0f8,0x83b454e1),LL(0x4578fbe5,0x114b724c),LL(0x98f51326,0x97ee546b),LL(0xf190d99b,0x801229b8),L_(0x00000091), LL(0xaa86765c,0x7ee4a0a2),LL(0x8b19b4b6,0xd4f5faa0),LL(0xc220cb11,0x6ad0862b),LL(0xce1c7d42,0xd7a63508),LL(0x3236a72d,0xeaae4777),LL(0x36cda4ac,0xbe3fcce9),LL(0x808ba7a0,0x972c3840),LL(0x79c14a5b,0xcda4655c),L_(0x00000087), + LL(0x4283d37a,0xf72e10a1),LL(0x23f718f8,0x07515abf),LL(0x820e2eb6,0xc81af50b),LL(0xea92c2b4,0x06af11fd),LL(0x71048468,0x755ab069),LL(0x6ada8b6e,0x5f2e0402),LL(0xe7b549c5,0xa45c27e8),LL(0x13b56922,0x1760f8ae),L_(0x00000001), LL(0xc7aa6c54,0xacb0965f),LL(0xc6437d60,0x30e79f87),LL(0x93a0e68a,0xcb0f4dcf),LL(0x3613f9b0,0x02e2383c),LL(0x32355c62,0x3ec75821),LL(0x4a835dde,0x4891bfda),LL(0xa38a3a87,0xd0206185),LL(0x9de0b9b9,0xa9cedb8c),L_(0x000001f4), + LL(0x2fe65202,0x8b5ddb45),LL(0xdc46fb16,0x8166a790),LL(0x41a5e4a7,0xc854c900),LL(0x342b51ba,0xeb4a908e),LL(0x116e0741,0xb76499d7),LL(0xc1551311,0x6cc7399a),LL(0xccaf37b4,0xf2094cc8),LL(0x9c29f265,0xc4a1fb65),L_(0x000000c7), LL(0x0d15a232,0xa4cf272a),LL(0xcfc8b9dd,0x9fd1f1c4),LL(0xb8e8cb4f,0x8ddfade3),LL(0xfd72dadc,0xf084903f),LL(0x764ba410,0x9094e8a7),LL(0xf43466f6,0xb9869fee),LL(0x1564c4ac,0x82a6cc83),LL(0x7742c943,0x89c1b557),L_(0x0000016c), + LL(0x6d728fc3,0x7e25b95d),LL(0x08c1d55c,0x50011066),LL(0x2de90a9b,0x63db375d),LL(0x46d6ba3b,0x2d3fa9bd),LL(0x9ae8aa53,0x9fb12874),LL(0xabf67a35,0xd1f1f45f),LL(0x05d8099d,0xdc479fc0),LL(0xdf2cdfde,0x779d8b52),L_(0x000001a9), LL(0x9e4fbdda,0x8f62ac2a),LL(0x4ab94029,0x56a0908f),LL(0xbb03c1b4,0x9ce0943b),LL(0x6319d2ed,0xe2d743f7),LL(0x910c2363,0x871683b7),LL(0x78ddf2fb,0x43f08ff4),LL(0xb7c5e230,0x2ebe58e7),LL(0x1c175b19,0xc02e1520),L_(0x00000185), + LL(0x39096d41,0xec7786aa),LL(0x70017bcc,0x26576a40),LL(0x926b1ae0,0x5e810d17),LL(0x6c002685,0xdef24d30),LL(0xd826c439,0x78ac55c7),LL(0xe40f66cc,0xfbf9b521),LL(0xe26697c9,0x01aaaf8a),LL(0x46a75caf,0xd094aec3),L_(0x000000a9), LL(0xc1b67b75,0x99a161f4),LL(0xcc3c7e5f,0x88977e72),LL(0xfefa749b,0xd6e24cf4),LL(0x56863737,0x4607a910),LL(0x4dcfe4ed,0x01768685),LL(0xac7bc09c,0x9ec211ac),LL(0xc731394d,0xac76909c),LL(0xd59e4dd8,0x246fb612),L_(0x000001c7), +}, +/* digit=7 base_pwr=2^35 */ +{ + LL(0x31c9da36,0x5592f380),LL(0x0dd54d04,0x44d05f6f),LL(0x298fe241,0xe2d191b2),LL(0xad46274a,0x9113fc1e),LL(0xcc54c590,0x0dea702c),LL(0x763ea8c1,0x74f208c5),LL(0x35441e72,0x578c5736),LL(0x3706b2f2,0x81343695),L_(0x0000003b), LL(0xa85cfcd7,0x88ada464),LL(0x4c2605a5,0xd5464606),LL(0x004bbf31,0xca04e18d),LL(0x03210805,0x998cccf9),LL(0x89627867,0x48398a6f),LL(0x8d2faed1,0xca85dacf),LL(0xde01ea7e,0x92784742),LL(0x0feb7d82,0x9fe5859b),L_(0x000000b8), + LL(0x5f01aa9d,0x05a73aaf),LL(0xe5e08d95,0x18e919ab),LL(0x9fd8bcd3,0x5b386f06),LL(0xd6891589,0x0b5abd07),LL(0x07bc244a,0x339901b0),LL(0xc3693691,0x684cff05),LL(0x179dcef7,0xe69b7993),LL(0xb0125196,0x23db7308),L_(0x00000028), LL(0x6d0d0635,0xf88e8361),LL(0x0c66e267,0x2f9f93bf),LL(0x6d375b82,0x09656c0d),LL(0x6d5dc021,0x0c1fc16b),LL(0xba81db53,0x86bf6541),LL(0xb4caf94b,0x1a6d443c),LL(0x87f59d3c,0x0e10fe1a),LL(0xb72afcd6,0x8d7e1995),L_(0x00000008), + LL(0xcb74d13d,0x3c2640b0),LL(0xef7a7df4,0xf6850378),LL(0x2a55c175,0xed04fb24),LL(0x8b6f667a,0xa7e743ff),LL(0x93061f72,0xdf46d114),LL(0xdaa59d80,0x9d4ed766),LL(0x49c1e1f8,0x4b991a82),LL(0x2fe74922,0x2e41804d),L_(0x00000122), LL(0xa863fded,0xf37b7a2c),LL(0x140444d6,0x8f14ff32),LL(0xf54bdbb6,0x34a9f316),LL(0xde42c24e,0x9515de8e),LL(0x96a88eec,0xf1959aa3),LL(0xdcd09006,0x30671815),LL(0x058c4643,0xb6c6d2af),LL(0x65dac0ec,0xd1a5f578),L_(0x000001f4), + LL(0x50517e7c,0x0a5b8daa),LL(0xd4667616,0x8dcdbdbe),LL(0x16e7a7e7,0x1b0f5e9c),LL(0x9178e1fc,0x3cb9503e),LL(0xf2294c93,0xe6f78b36),LL(0x420442aa,0xfb2d6ec3),LL(0x01e17c7f,0x7d30fddc),LL(0x9c7293b8,0x36bed473),L_(0x00000128), LL(0x2ebfd049,0x4975943e),LL(0x84cf37b8,0xab2857b7),LL(0x645eaa02,0xe12a0d65),LL(0x3d30b0ac,0x267c93aa),LL(0x30be3eff,0x6fa69542),LL(0x903aa7ed,0x2cdb01e1),LL(0x311ae0c8,0xc5056d4c),LL(0x275f0bd3,0x94d54a98),L_(0x00000020), + LL(0x8cee0a0b,0x8c942dd7),LL(0x62d7fcf1,0xc893077d),LL(0x643ea78e,0xda471b28),LL(0x4e9d9fdb,0xfb673df7),LL(0xe64cf76a,0x51536a0a),LL(0xfccba343,0x5fc020fd),LL(0x279bce99,0xdee7d155),LL(0xb7f5fd72,0x68c90549),L_(0x0000012d), LL(0xd5aaeab9,0x4ecec5bb),LL(0xe6b0baf4,0x6a4bc82c),LL(0x18f9ed0f,0x93eb1856),LL(0xdc69912e,0x6f327c7d),LL(0x2be0e2b3,0x52fbc6f3),LL(0xe7e8bfdb,0x24b3acf0),LL(0xd81de1d4,0x62a84326),LL(0xe49b2810,0xc3912b42),L_(0x00000136), + LL(0xa4f2bbd9,0x551c0660),LL(0x2fe061f4,0x91d40c3d),LL(0xa2b6dd70,0x7cc4883d),LL(0xbd2bf743,0x58011dda),LL(0xaee852f2,0x71bdaba7),LL(0x39f463ce,0xbd7c195b),LL(0xfb33b881,0xede085fe),LL(0xbf7d695a,0xf8fa2471),L_(0x00000180), LL(0x83554b40,0xc96eeab9),LL(0x8a6f5a6d,0x07f71f13),LL(0xb29f154f,0x242d7a9e),LL(0xb707d1c7,0xf3c7f1af),LL(0x44aee842,0x0af2896b),LL(0x01f56999,0xc5c5b556),LL(0x1e36ed07,0xcca26786),LL(0x245430fa,0xa78eb214),L_(0x0000016e), + LL(0xa3dd17dc,0x0f4d9fba),LL(0xa4eddc14,0x9ebcb886),LL(0x420f1510,0x3c114b65),LL(0x4e6c23f6,0xba3fc70d),LL(0x5f6bd766,0x718ac792),LL(0x532bdc38,0x5c2b8f46),LL(0x03efcc7f,0x72c3a472),LL(0x5c2b9a45,0x9dc110c9),L_(0x000001f4), LL(0x58ea447d,0x1a6af2f7),LL(0xb5c3ea1c,0x8052b6c2),LL(0xab27ec8a,0xa3cff07f),LL(0x4c92575d,0x00fa9778),LL(0x4b43265d,0xff1e188a),LL(0x6c53a129,0xedc9e95e),LL(0xfcb7ddb8,0xfb7de911),LL(0xc1dd8dd6,0x6e53bbb5),L_(0x00000072), + LL(0xe68e2079,0x7daeaaab),LL(0x6eaee317,0x6e35398b),LL(0xf5c1267a,0xd01bbbbb),LL(0xa2b92ae2,0x3af1a4f4),LL(0x5cdfa4bf,0x5532088e),LL(0x638a58f5,0x2a0ec8ee),LL(0xbce5e7aa,0x79c3f50b),LL(0x46a16448,0x378387c2),L_(0x0000005e), LL(0x84e88e18,0x6769ee88),LL(0x8ec2984b,0x62fea90f),LL(0x1f9e47bd,0xe7522665),LL(0x3d9f9867,0x916cb049),LL(0x5be2cccb,0x1106987f),LL(0x71156e1c,0x7bad869c),LL(0x011576bd,0x945007a5),LL(0x38b76a6e,0xc18de41f),L_(0x000000ae), + LL(0xa84cca21,0x6ee5a7d6),LL(0x2831843a,0x58bef9ba),LL(0xe4f07223,0xd00147a3),LL(0xe1c40e6b,0xd10e53e0),LL(0xe7025e87,0x5d5f797a),LL(0xf0dd838b,0xe3b65b5f),LL(0x16931c80,0xd1ff0eb8),LL(0x42704c55,0xffc29bf2),L_(0x000000d4), LL(0xe3300a5d,0x279cdc4f),LL(0xed03963d,0x51c15682),LL(0x4a0c613e,0xc3d504ac),LL(0x6ef1db42,0xba61ce4e),LL(0xf8742eaf,0x2e74a6d4),LL(0x3efa3cf5,0xd53943f5),LL(0x201c12e1,0x253da54a),LL(0xa468664c,0xa35c5fd4),L_(0x00000012), + LL(0x9c6f67ac,0x687c5994),LL(0x7a229d23,0x8aa53c89),LL(0x118e3e78,0x080e973b),LL(0x15c794e3,0x5a91046f),LL(0x30c0f281,0x5ac04ed5),LL(0xfe35eb92,0x0c5478a4),LL(0xfe18e707,0x7d9c57a1),LL(0x4bf409ce,0xfcd17edd),L_(0x000000aa), LL(0x8174557a,0x3d2850fe),LL(0x23469475,0x2c45c37e),LL(0xc528ec7d,0xf346792a),LL(0xa36bdd41,0xca964be2),LL(0x11d67932,0x3fef3e79),LL(0xc72673a0,0xf0bc0101),LL(0x53d6358e,0xb9caaba6),LL(0x2bf874e2,0xbbcc3188),L_(0x0000005e), + LL(0x5993ad4f,0xf22d90c1),LL(0x24df4deb,0x449aa491),LL(0x37a9290e,0xd1657f10),LL(0xc6bbdf04,0x4ba3ee4b),LL(0x4075fc0e,0xe3e07500),LL(0xf134a6c8,0x7661f086),LL(0x2b3b9213,0xfd4c08de),LL(0x6f51f169,0xcae8fa7f),L_(0x00000104), LL(0xb2f528e4,0x9303da25),LL(0x1e8df3c5,0x6a92d1ac),LL(0xb326f2a6,0xafc6ed8c),LL(0x46ef258d,0xe7d3b364),LL(0x53fe6ba5,0x7b2d91d1),LL(0x669d23c2,0x150f6968),LL(0xc05b6015,0x230a0105),LL(0x376b2356,0x3df6108a),L_(0x00000172), + LL(0x05384e00,0x5490baa5),LL(0x148d7d84,0xae379993),LL(0xd948464c,0xac4f8ace),LL(0xddaf46fe,0x68d1b7c8),LL(0x6c39b672,0x10d4770e),LL(0x5967ac57,0x30a2c195),LL(0x2098b748,0x19047735),LL(0x858d17fe,0xe5071ced),L_(0x00000191), LL(0xb56551f3,0x44b4f003),LL(0x2a7e4193,0x767f8087),LL(0x1262c90a,0x91770fa4),LL(0x25315a97,0x4bc5606e),LL(0x696dd31a,0x6a665041),LL(0x7ec13746,0xbd01da6d),LL(0xac07c562,0x59de1e2c),LL(0x4bc4a92e,0x8f7d2999),L_(0x00000106), + LL(0x5f2d1510,0x37e7ccad),LL(0x0f93acce,0x909c5616),LL(0x3802c7e4,0x50e428ab),LL(0x3b424aa7,0xdee4af73),LL(0xc7e0291d,0x5bbec3a0),LL(0x3889c563,0x7854dc66),LL(0xe5ea7c0c,0x7701185f),LL(0x9cdf7704,0x0b88a64a),L_(0x000001ad), LL(0x6c0c71ab,0xe5481dba),LL(0xc168583c,0xbb4cbf39),LL(0xec84a971,0x16e6876e),LL(0xdde2891b,0x4940610a),LL(0x9e03560a,0x5406bed1),LL(0x992e1390,0x475b7757),LL(0xc2108310,0x7cc85b3f),LL(0xffbf072b,0x82170451),L_(0x000001eb), + LL(0xb05a9bf6,0x9d172698),LL(0x0dde3c4b,0xb8a86057),LL(0x4dad7e2a,0x376d08bb),LL(0x709cc4fe,0x2d396e50),LL(0xb38f91df,0x78138716),LL(0x6a45d957,0x7a064e9a),LL(0xeda47781,0xf79bf83f),LL(0x037062a4,0x2aff8e01),L_(0x000000a1), LL(0xbd0ea3b4,0x49748577),LL(0xa23c2d1e,0xdb9b468c),LL(0x79fc968b,0x9d5d5807),LL(0xb4f35908,0xae7478af),LL(0x7ffb5a37,0x6f6ac1a1),LL(0x0ad6d095,0x35d076fb),LL(0xcc73da49,0x4e896c83),LL(0xf0b38ddd,0xcd942654),L_(0x0000011f), + LL(0xcfb2b4bb,0xf362300f),LL(0x940a7fee,0x0c8996fe),LL(0xff7970e2,0x434f05d2),LL(0x3ed8edff,0xc3ed10ba),LL(0x5ebc5312,0xdee87d6d),LL(0xa445169b,0x12a8674e),LL(0xc4cceb87,0xd8da7725),LL(0x51c6dc7d,0xea8956f4),L_(0x000001af), LL(0x82d880a3,0x7d3585a5),LL(0xa5517351,0x13fe8bb4),LL(0x74f18cb5,0xe68912ee),LL(0x7950c8df,0x1512d84f),LL(0x2fbcbaca,0x7df13019),LL(0x0de4c1a1,0xe29f312a),LL(0xabb943b7,0x656e2b95),LL(0x7ae2e506,0xfc56ddff),L_(0x000000ab), + LL(0x8e947b1a,0xccd06bf8),LL(0xa717a0ac,0x6ceb8a0c),LL(0xb428946c,0x2bd2594e),LL(0x5c199265,0x80688236),LL(0x3a824141,0x74f2f352),LL(0xb634a60c,0x83ce2e27),LL(0xf4680f2b,0x33426806),LL(0x485e159f,0x18c76ca1),L_(0x00000137), LL(0xe0c9dd7b,0x1f63dec4),LL(0xd74bb74e,0x6f95ccb7),LL(0x4a5f0944,0xc75d0662),LL(0xd36f4555,0xd6e7583f),LL(0x23cc2b28,0x783fa303),LL(0x2c0c49bb,0x4f771001),LL(0x907cd3d6,0xac90f899),LL(0xe2c79e69,0x2cb352bd),L_(0x000000c1), +}, +/* digit=8 base_pwr=2^40 */ +{ + LL(0xe05ab80b,0x93bc2a7f),LL(0x46f49f7a,0xcc0b41a2),LL(0x91072db7,0xd30ac7ec),LL(0x53711f97,0x9de685e7),LL(0xef0acc16,0xb8a2ae9a),LL(0x6bded4c6,0x4497e3c4),LL(0x04789cdc,0xb2b2ea26),LL(0xfea082fe,0xe890cba4),L_(0x0000018f), LL(0x50768242,0x66edbc5c),LL(0xa472aca4,0x5ad15298),LL(0xa8066050,0x1b16ca97),LL(0x38b0c1cc,0xa2937bbf),LL(0x4d56c3dd,0x72545fac),LL(0x7e35494b,0x4b5790f0),LL(0x903e9ca7,0xb0c8bc40),LL(0xc4b43111,0x5923f9e9),L_(0x00000146), + LL(0xb73ff4e5,0xc18b52bf),LL(0x6410d489,0x28530a4d),LL(0xae318bb5,0x3f7d7028),LL(0xb534b71f,0x0b21b686),LL(0x1f599597,0xf01ea275),LL(0x663379dd,0x800a1322),LL(0x77c11915,0x6db4beae),LL(0xe3261c47,0xe89c22a1),L_(0x000000e8), LL(0xa7b1dfa3,0xfce16965),LL(0xd6426762,0x2e53d9af),LL(0x532ec13f,0x1e801ed5),LL(0xe9efe413,0x6963e2f9),LL(0x8aecc3c8,0x5f46e509),LL(0xb47801a3,0xc3d8faa2),LL(0x3b6f3406,0x349f37b4),LL(0xadb57971,0x49ef39f4),L_(0x000001d7), + LL(0x126ca585,0xf9dcaceb),LL(0x5a73dec3,0xd887946c),LL(0x0e0ffb30,0xe7e62831),LL(0x84126935,0xe074c83b),LL(0x158a7df5,0x18b04291),LL(0x08eaada2,0xfa20f72a),LL(0x40d05438,0x9aa8c4aa),LL(0x8405e6ac,0xb7559284),L_(0x00000192), LL(0x74e90dac,0x7981326c),LL(0xf1a037a8,0x13ab2cdb),LL(0x9887e290,0x98bd3d86),LL(0xfecffd65,0x3c803a95),LL(0x2fd8393b,0x3e4c5072),LL(0x129b699c,0x5e3c4e70),LL(0xfa72cdd6,0x65f24da0),LL(0x6c0ccbba,0x5325682f),L_(0x00000097), + LL(0xd21b98be,0x728d8231),LL(0xeede07ff,0x52ba3f46),LL(0xc57dc8bc,0xbbd28782),LL(0x49d96a93,0x9e0a7a0e),LL(0x49576560,0xe9fbe4aa),LL(0x79dbfb8a,0xcccb4c5f),LL(0xe1789960,0xd25ebfd5),LL(0x09b74da3,0x56df642b),L_(0x0000002e), LL(0xbe83a30e,0xd17057a2),LL(0xa759ce4d,0xab9d226b),LL(0x57744ef0,0xb7115a63),LL(0xdddc9ee2,0xd77f24c2),LL(0xdfee8900,0x2142ea1a),LL(0xa9d5346a,0x6d500f3f),LL(0xa84ecd7e,0x7a1527e7),LL(0xae35caeb,0x10e6262d),L_(0x00000081), + LL(0xaea7c3e5,0xcd457989),LL(0xbd6196a6,0xdd85ca16),LL(0x6f76c2cb,0xcfd847e9),LL(0xaa25840d,0x8ea001b3),LL(0x444e27ec,0xa898be24),LL(0x8a0c53dd,0xb3e4397d),LL(0xfa5f98a5,0x64ea9863),LL(0xbe8e1973,0x922c6bbf),L_(0x000001bd), LL(0x5084e379,0x0664b7db),LL(0x54735a19,0x990568c9),LL(0x7371d65a,0x52b4c902),LL(0x600bdaf0,0xc2cc9668),LL(0x4697299e,0xbadac668),LL(0xeb4949cf,0x33272f7c),LL(0xeda14ca0,0x3989fbe1),LL(0xd9927092,0x0f1714c9),L_(0x000000a8), + LL(0xd2d2e356,0x00da9fad),LL(0x39d9c06e,0x69b9bebe),LL(0x7878b1c2,0x50e16aa4),LL(0xa0545c03,0x04f7fb31),LL(0x5d57a4d6,0xd233dc43),LL(0x629977c5,0x87e54a59),LL(0xaa747e53,0x0cca577c),LL(0x80698068,0x3aa24734),L_(0x0000007f), LL(0xff177c1c,0xf46ecf72),LL(0x87d84398,0x5b5e3ea0),LL(0xf8e3dbad,0xc29bdf29),LL(0xc86793b7,0x8b4ad4a2),LL(0x337e0dd4,0x34cf9d25),LL(0xc858ea72,0xb282be01),LL(0xe90a676b,0x7590c7bf),LL(0x7d306f50,0x155053c4),L_(0x00000115), + LL(0xbb970cd1,0xfa311b42),LL(0xa08e6727,0x609fc56f),LL(0x6285b2f7,0x07ce1a3e),LL(0xe94807c3,0xc9c1df6d),LL(0x19a317d8,0xd70b9796),LL(0x052a3379,0x870efdde),LL(0xaa7d20b3,0x8f7406db),LL(0xbb6e443d,0x511beafe),L_(0x00000155), LL(0x0634dd62,0xd62e82c9),LL(0x9d51e499,0x9995a224),LL(0x615ca9d8,0xd99162d9),LL(0xab897ac7,0x51034000),LL(0x24f35e95,0xb70ca9d9),LL(0x853be7df,0xff11b526),LL(0x38dc8c8a,0x463b8a66),LL(0x3331fb01,0xb55e7404),L_(0x000000e7), + LL(0xa03485a9,0x508d4f13),LL(0xdd3ccf18,0xf25524c5),LL(0xd8ab1776,0xe0bf0c9e),LL(0x017a54a5,0x1226e24a),LL(0xb9626be8,0xb0e5b1ec),LL(0x8b7b3bc5,0xf24c6acb),LL(0x14da0130,0x46736054),LL(0x7db2f1d9,0x73af8b9c),L_(0x000001ae), LL(0x806025a6,0xb11a4baf),LL(0xf7b99ef6,0x1e9bb68c),LL(0xb7054990,0xa5ca0071),LL(0xe57cc5d4,0x55009f7b),LL(0x501abab5,0x08dbaab6),LL(0x2d17b21b,0xcde35c58),LL(0x9921c7ba,0x9991c48d),LL(0x3f13fb4b,0xc6f664c9),L_(0x00000172), + LL(0x63f229e4,0xaf8f0fbd),LL(0x3fffd972,0x513637b7),LL(0xa381ede6,0x3a907a7b),LL(0xef4d7386,0xdec53a87),LL(0xfaf3ac39,0x6072c595),LL(0x7077416d,0x25742340),LL(0x8d4d4598,0x0272fbab),LL(0xc3dce550,0x44d3c246),L_(0x0000013a), LL(0x95e9dda0,0x8a45d7f7),LL(0xf5989e00,0xa25dc323),LL(0x31cb7128,0xd19e79bc),LL(0x87f0b5cb,0xf782a69b),LL(0x62e18e62,0x4a3bc664),LL(0xacc62f0f,0x8a21efa3),LL(0x855aaaab,0x5dc442d8),LL(0x895a7f3a,0x7fccf9f6),L_(0x0000017f), + LL(0x6c85234b,0xf6a194a7),LL(0x21638407,0x8d081ace),LL(0xe465a985,0x1e6d4f3f),LL(0x596aa1dd,0x800bb059),LL(0xf63247cf,0x88ecdd17),LL(0xd80d0066,0xd6196a9e),LL(0x359a8606,0x6d1c0b4e),LL(0xf12ac0e0,0x1f003c05),L_(0x000000e8), LL(0xfd00b6d4,0xe591e392),LL(0x88389649,0x09f83a93),LL(0x2b4134e0,0x9d2fd6ac),LL(0x3ada50c0,0xd488e638),LL(0xa2f5e7c7,0x6ae6d5dd),LL(0xece41bdd,0x626ed9b1),LL(0x83fc37eb,0x0ec94ba6),LL(0x390a5c6f,0xd316539d),L_(0x00000034), + LL(0x42827af1,0xf8cf81f2),LL(0xdd03c701,0xce67a0a5),LL(0x957637c9,0x4af6b68e),LL(0x49c7193a,0x2b716eb7),LL(0xa9f1106e,0x04a50d86),LL(0x5cdc8e58,0x29fe3e8a),LL(0x404173b6,0x2217e337),LL(0x8d0fe7b4,0x41f85927),L_(0x000000ee), LL(0x6c97abbd,0xf0033298),LL(0x7982223c,0xeed36f1b),LL(0xc078a101,0xc8a52b8f),LL(0x54b52769,0xfd843c12),LL(0x0c71b06d,0xdaa31445),LL(0xd139607d,0x996c457f),LL(0x3373eded,0x0d6abc25),LL(0x616b57db,0x27a4f9a0),L_(0x00000005), + LL(0x1be04a5c,0x24d46da3),LL(0xc28ba5d6,0x84ca0be2),LL(0x69aff480,0xb7d623cf),LL(0xeee1ba2a,0xc4a065a8),LL(0xe236787f,0xd893b3f3),LL(0xaa351426,0x2106fcf4),LL(0xc4d98be5,0xf2dfc4d7),LL(0x534e82e2,0x4f43180c),L_(0x000000bf), LL(0x0a626913,0xea92fe7d),LL(0x3cd0971d,0xb9b4d4bf),LL(0x5fa502b8,0x56e42bc0),LL(0x2f95fd57,0x9a55a6ac),LL(0xefd75261,0x9c01cac4),LL(0xc54d4200,0x8b9c411f),LL(0x9a2d86c0,0x84f22245),LL(0x0123f4e9,0x924fe183),L_(0x00000190), + LL(0x59d5704e,0x5adfc431),LL(0xed2fd11e,0x1a785308),LL(0xb3ad4ad2,0x534b1813),LL(0x19e08445,0x77328159),LL(0x557af465,0xcd28509e),LL(0x114e6813,0x908aacef),LL(0xdd6f9e0a,0xea30d82c),LL(0x5aec37e4,0x56efd94a),L_(0x00000184), LL(0x9ccb322c,0x9a808c1f),LL(0x8215d192,0x00e65251),LL(0x2e216a64,0x8be89e79),LL(0xa21b58aa,0x1bae586d),LL(0xde6dc431,0x6074af45),LL(0xd9ffe269,0x144f7409),LL(0x7968f9ca,0x4c70bef4),LL(0x057ee0b0,0x464dfc55),L_(0x00000158), + LL(0x42555bd7,0xda8f0d55),LL(0xbc3cfc53,0xf7a0b6a9),LL(0xc3851a8d,0xd221e3bc),LL(0x3b6631e9,0x73e218ec),LL(0xd802d5a9,0xbb393674),LL(0x357ad609,0x17e839e5),LL(0x26a2911a,0xfd4ff33d),LL(0xa9163042,0x40c85178),L_(0x00000088), LL(0xd26e52f2,0xebbb0dce),LL(0x628d1685,0xc4b138ed),LL(0xad6058b9,0x1ab4e65c),LL(0xd77f3507,0xa315e387),LL(0x01e25773,0xc1c7fc22),LL(0x5f337f59,0x9dd402d9),LL(0xc4922f4d,0x8947a84e),LL(0x52e76d6f,0x83ef2457),L_(0x0000008b), + LL(0xd7a5547f,0x67dd4533),LL(0xed953e34,0x0ffa9336),LL(0x4fc44042,0xb44d3a69),LL(0x0c1288b1,0x7f745c6a),LL(0x0c5f14a6,0x345f8ac2),LL(0x765ee067,0xcfed50e8),LL(0x659b1874,0x5ef0443b),LL(0x26abda6a,0x894afeee),L_(0x00000163), LL(0x6f34576d,0xabe2ed4e),LL(0x46dcead8,0x196272e0),LL(0x64053114,0x13a8b18e),LL(0xbcb0e703,0xf9b6c7a1),LL(0xaecaa246,0xb17e245a),LL(0xd0c5c4d7,0xce6786b6),LL(0x01f4866b,0x12c94128),LL(0xea713e45,0x75975359),L_(0x00000004), + LL(0x15f3e5c9,0xb900e09c),LL(0xf45b409f,0x7837bf97),LL(0xff4a0108,0x2bcafcbc),LL(0x6b8d204b,0x0da165ec),LL(0x8423a60a,0xb1171697),LL(0xf8295351,0x3eb1f2f7),LL(0x1f58e2d1,0x2b669228),LL(0xbbed8459,0x5f9819ae),L_(0x0000005f), LL(0xd668278e,0x7b7ea077),LL(0x53ee2ff7,0x5b359b96),LL(0x98e8334b,0x87baabe1),LL(0x85a52104,0x95a5886c),LL(0xc237881a,0x809649f4),LL(0x7f95c6f6,0xd3395612),LL(0xed6c6419,0x657d29fa),LL(0xa5be49aa,0x7ae0b376),L_(0x000001a6), +}, +/* digit=9 base_pwr=2^45 */ +{ + LL(0xcbbde736,0x45fb32ba),LL(0x8a721e35,0x5c4674f0),LL(0x584020b4,0x84a774fc),LL(0xadafd3a2,0x477afffe),LL(0x266e1004,0xd6a2c4ec),LL(0x326c6652,0x428066dc),LL(0x0b3a65b9,0x4c7d5c77),LL(0xe355b810,0x4b6af237),L_(0x0000018c), LL(0xca1cffd4,0x1c0b97b7),LL(0xde135822,0xcc7ac435),LL(0x876cab38,0x8f30b09e),LL(0xec654cdc,0xcb3a4f5a),LL(0x26a9da0c,0xb2ac30ca),LL(0x8e2a6fa3,0x77ee1103),LL(0x545c20a5,0xf50fb144),LL(0x97bff8e2,0x58359a6d),L_(0x00000131), + LL(0xcf89d246,0xb2c8ba9c),LL(0xddf8d1b9,0x7f24e874),LL(0x27291ffd,0x563287c7),LL(0xd028bd9d,0xd01bdb48),LL(0x3b0c1265,0x71b99b97),LL(0x618319b9,0xf686050d),LL(0x8420d531,0xc411c3a3),LL(0xaed7c201,0x468eb84c),L_(0x00000197), LL(0x5bf609a2,0xf6eb2fc0),LL(0x1dab9da1,0xc275b73e),LL(0x49847c3a,0x54d322f9),LL(0xf0578805,0xdd0cd2b7),LL(0x4958eafe,0x185bb3e7),LL(0xd9061a48,0x5c6dfcd8),LL(0xf9ac370d,0xa0217866),LL(0xf54cb188,0xa132c3b5),L_(0x0000017a), + LL(0x9e0b2bbd,0xf197825d),LL(0x1340276a,0x4bbcc96d),LL(0xd82fe632,0xcad6233b),LL(0xc290475e,0x0cd8d04a),LL(0x738cce9a,0x8e8e067d),LL(0xaa038ad0,0xd83e4317),LL(0xa7ce55aa,0xd5e91f49),LL(0x856a1887,0x5efeae92),L_(0x00000013), LL(0x035b085a,0x9bfa0b6a),LL(0x3d153ead,0xef7bc585),LL(0xca7f6fb4,0x0b798e2a),LL(0xf8abfbb3,0x53595cf1),LL(0x79182066,0x1774e7d1),LL(0x862d3928,0x8b4548df),LL(0xdb1e4086,0x6e38fc52),LL(0x72153b33,0xe2e4b80e),L_(0x0000012c), + LL(0xdc232332,0xf5595043),LL(0xe1b752f3,0x1b9318d9),LL(0xf6e2b364,0x5c02bb70),LL(0x38d64e0f,0x9d8f2870),LL(0x07542416,0xa62f3a1b),LL(0x3b8c6755,0xd59701bf),LL(0x2b642127,0x20fbe8ba),LL(0xfac17f0c,0x3410177d),L_(0x00000126), LL(0x0c65efbc,0x2b08cc56),LL(0x70680750,0xe532cef6),LL(0x7a1e8980,0x29a4a8b8),LL(0x3b679637,0xcb3a4f19),LL(0x0043db7c,0x92e07ae8),LL(0x346fea83,0x0da35be0),LL(0xef33f7a0,0xcb41f4e9),LL(0x271ea778,0xbb760e77),L_(0x0000016e), + LL(0xe8812fbf,0x120e5ac8),LL(0xcad14e90,0xd45b7941),LL(0x130b3936,0x78bbd634),LL(0x3839fe90,0x8f94ae22),LL(0xfb2c2b29,0xbd4d9761),LL(0xb2caaa91,0xf6e513d3),LL(0x37bd3dff,0xa0f24baa),LL(0x9dd2846a,0x1d27a8db),L_(0x000000ce), LL(0x62a47784,0xd4e2cdab),LL(0x8296eec9,0xee13214a),LL(0xce1e6780,0x6fed4902),LL(0x8ec28ea6,0x28576525),LL(0xa9bf0652,0x0afbfe7d),LL(0x0c66edcd,0x9e743eb7),LL(0xc8ec4a8a,0x64589360),LL(0x09bf2d23,0x7a6453a2),L_(0x0000017a), + LL(0x91c1326b,0x4d44bd26),LL(0x5e7c9a8b,0xfa441738),LL(0x3f4fd525,0x8cdf278d),LL(0x5b1fa4df,0x60600772),LL(0xb7e79779,0x15388443),LL(0x6b7719f4,0xd7a3aeca),LL(0x17dd158d,0x02441c0d),LL(0x3d070ec1,0xd5eb5d02),L_(0x000000c9), LL(0x84252a63,0x0ab898cb),LL(0x01117e64,0xee325365),LL(0x6f680374,0xbc1ae420),LL(0xdaebee10,0x98a23bbf),LL(0xfec8e51b,0xb59efdf3),LL(0xbbf08b12,0xa18137ff),LL(0x1532459f,0x04b7fdbe),LL(0x60238519,0x37b3447b),L_(0x0000000e), + LL(0x2c315da2,0x6b53a82a),LL(0xad2c8749,0x5a5a47d3),LL(0x75f76d03,0x60558c44),LL(0x6ecf38ff,0x957fd8a0),LL(0x7695311e,0xcd47da64),LL(0x215ee9fe,0x35b22e22),LL(0x4796f4b7,0x949a56db),LL(0xf62c912e,0x74debc0c),L_(0x00000191), LL(0x55d8aab4,0x9bd8df8c),LL(0x203b317a,0x637e055c),LL(0x03c45bfe,0x90fbadef),LL(0x1132b50f,0xaf36e7bf),LL(0x20a98c58,0x4f36088b),LL(0xdebbd429,0xcbb98ba8),LL(0x391e4230,0x3091f3e1),LL(0xb3356938,0xd86355bd),L_(0x00000072), + LL(0xc1f9460e,0xf79ba658),LL(0xb48e1df3,0x3eb15b18),LL(0x5fc03a10,0x3bed592a),LL(0x3591ad26,0x127b78a3),LL(0x07e9d80a,0xc0337c7b),LL(0x349dd74f,0x364ed2a0),LL(0xb1a807c5,0x588d4203),LL(0xecd92cca,0x772a1716),L_(0x0000019e), LL(0xf66f295e,0xf6fc1df3),LL(0x42d25980,0x8922f157),LL(0x36f0fdb0,0xa583206a),LL(0x8cc1fe47,0xc73f8816),LL(0x1d279801,0xe1b77767),LL(0x7ac8979c,0x3dba6831),LL(0xa98b4836,0x60d40152),LL(0xc7f36b74,0xc3d46c62),L_(0x000001a1), + LL(0x3a2954f2,0xed4a0395),LL(0x99b5cc1c,0x4cddc23e),LL(0x1d30267a,0x16bee440),LL(0xcd4130db,0x553abd41),LL(0x6652be0e,0x6e659595),LL(0x22061ff2,0xf0c20235),LL(0x72c720f6,0x077f6daf),LL(0x8079b1de,0x1ad9ac77),L_(0x00000151), LL(0x3b6a7cb2,0x6701fea0),LL(0xdd8e0cb1,0x5849b249),LL(0xf395a61b,0xb92466c3),LL(0xc2b702c7,0x77432a31),LL(0xbd7899d3,0x28b4ebc6),LL(0x307f0a10,0x0b06f919),LL(0x5c8246fb,0x7154af20),LL(0x8f032be2,0xc88de5c5),L_(0x00000009), + LL(0x30655c0a,0x344eafa5),LL(0x0a16f77b,0x724f29ca),LL(0xdbafe962,0x94bbb419),LL(0x30985479,0x2b2c87d2),LL(0x3775b2ba,0xe0e3814b),LL(0xbd366c77,0x1130e80c),LL(0x7b644025,0xf10ea539),LL(0xe1da2161,0xf66677b2),L_(0x00000015), LL(0x08673ef7,0x11454e50),LL(0xd8ab26fa,0x45948446),LL(0x2a4b8bd4,0x35518731),LL(0x34c59cba,0xcc005baf),LL(0xbd4d3f49,0x06c483a0),LL(0xa3e5d238,0xd77da187),LL(0xc4657e79,0xa31fff1d),LL(0x33918629,0x0e898785),L_(0x000001c6), + LL(0x48a7aa5d,0xd39844b5),LL(0xc0ae95fc,0x0cd04d32),LL(0x608fd1bf,0x2b33bcf9),LL(0x8e195302,0x3567e13c),LL(0xb9784d4d,0x6f12914d),LL(0xf39a6a6c,0xf4d361ba),LL(0xcf170781,0x366e62a5),LL(0x70b10e90,0xa3bce706),L_(0x000001dc), LL(0x4172b25a,0x65a7fa0b),LL(0xdf710618,0x93abe742),LL(0x7805a257,0x738295fd),LL(0x76e1d4b4,0xcb5b0f15),LL(0xc121708d,0x716ee171),LL(0x14725b57,0xd2227241),LL(0x2e484d37,0x34400369),LL(0xef0bb7f5,0xebdf59e5),L_(0x00000105), + LL(0xf6fa11c3,0xf35d7da4),LL(0x0ee635c0,0x6c91936e),LL(0xdd72a103,0xa9f8eae7),LL(0x2a073b1f,0xff539491),LL(0x6c35942b,0x0a881a03),LL(0x35498b7c,0x67e4af9a),LL(0x59bde411,0xf903d1e5),LL(0x517835ca,0xf0b93b5b),L_(0x00000064), LL(0x3a244f62,0x079d614c),LL(0x550a47c5,0x1c8515d3),LL(0x1f9595ac,0x1557c55d),LL(0xf301c894,0xb5548c2e),LL(0xecc6608b,0x6ed92475),LL(0xf17244f1,0x9b9d35aa),LL(0x9b6083ca,0x82abcca4),LL(0x902eead4,0x45a99fbc),L_(0x000001a2), + LL(0x73c00a9e,0xc92a2f72),LL(0xb4d59736,0x46a97747),LL(0xec9ee773,0x92e9e427),LL(0x54eed174,0xe62769e0),LL(0xb25c6252,0x26eca3d7),LL(0xb5598a2e,0x72728c2b),LL(0x73ee8036,0x6cefdf35),LL(0x4ee8ce4c,0x700d3d8f),L_(0x000001d7), LL(0x35089629,0x2ffb5bc1),LL(0xb8175b8e,0xd9c451df),LL(0xbdb5cc88,0x9445c144),LL(0x846b2eaf,0x92957da0),LL(0x5ff2e582,0x2da50816),LL(0xe7cc1a15,0x4dc70abf),LL(0xe4999b07,0x24220cc0),LL(0x1b3556b4,0xb4413c1d),L_(0x000000e6), + LL(0x8929ee7c,0xb5ee8957),LL(0x45878f54,0x112fbfa1),LL(0x1879f721,0xe9f0dfae),LL(0xb007f421,0xf113817d),LL(0xeb000fbc,0x35d8e979),LL(0x206151d8,0x0bf9caf2),LL(0x258ab3b7,0x6e8e8e3a),LL(0x92a042db,0x7a4dc496),L_(0x000000da), LL(0x28821f85,0x3d64ea94),LL(0x7360c36c,0xbf2b13c7),LL(0xfb77c37c,0x73884c74),LL(0x65a78a55,0x5d8600a0),LL(0x888762bf,0x77475414),LL(0xc8ba0daf,0x975e6be1),LL(0x59f8b668,0x14cf6707),LL(0x185c7c67,0xfef650be),L_(0x00000023), + LL(0xa52fd88f,0x14dc97d9),LL(0xa3e0a482,0xe962fe1d),LL(0x44364f6d,0x19480b73),LL(0x9ffa10f7,0x28fc88ac),LL(0x7993eaa2,0x8a5db808),LL(0xd4bb9db5,0x4464dfad),LL(0x9088a081,0x903605db),LL(0x86f98ca4,0x87bd4fc7),L_(0x000001cc), LL(0x6477a8aa,0xba5ec771),LL(0xec2c3e51,0x3078a6cd),LL(0x1ad83e79,0x66717c17),LL(0xad871d3e,0x8530527c),LL(0x0e3f9442,0x92315ca1),LL(0x49c67cb7,0x2fc5cd79),LL(0x4eb1ba39,0x256788a6),LL(0x10b0e6f6,0xb9cd18a5),L_(0x0000008b), + LL(0xe7fab2a1,0xd61fb046),LL(0x90213473,0x4f9db0e1),LL(0xcbb6e9b8,0x36fcff78),LL(0x6aa8fb8a,0x7cd5e9d1),LL(0x337a00c4,0x2c2601e9),LL(0xfe8445d7,0xbbab713e),LL(0x0681fd15,0x0b2dd233),LL(0x2151cff9,0x00ab444b),L_(0x00000049), LL(0x0ca8289c,0x06de9a88),LL(0xcb8ede52,0x209abe3b),LL(0xe1369e32,0xb711e224),LL(0x53136516,0x533569db),LL(0x59d96525,0x5419656e),LL(0xf2d68025,0x326eee21),LL(0xd59bb004,0x073cca71),LL(0x1cbb722c,0xaa784f93),L_(0x00000066), +}, +/* digit=10 base_pwr=2^50 */ +{ + LL(0x3b1d2404,0x51931359),LL(0x672b4b0a,0x14acc3b3),LL(0x78ea42e6,0x22fe0a9a),LL(0xe72784cd,0xc20faf43),LL(0x8f9c3ea6,0x5e49f303),LL(0x4c50987c,0x12d1fb91),LL(0x0c76e9b9,0x96a89b90),LL(0x74dc2b7b,0x238b29a0),L_(0x000000de), LL(0x7031f728,0xca68ea37),LL(0x06adb168,0x5ecbae96),LL(0xe58dde88,0x4d422e92),LL(0xeba17742,0xa609937c),LL(0x1451998a,0x8f30fc81),LL(0x9eba807b,0xa724c9f9),LL(0x200db6e7,0x651c126e),LL(0xc9db2dc7,0xb58e38f0),L_(0x0000009c), + LL(0x81dfb8c7,0x71e8870b),LL(0x8ea654a6,0xa23dd690),LL(0xc3eb3660,0x673dbdf6),LL(0xa5ddaf70,0x9bbf5d38),LL(0x1e7af5c1,0x0fe1371d),LL(0xcc1eff61,0x1572e30b),LL(0x1308bdd3,0x20ce33cf),LL(0xc60db70b,0x6ab6b3ed),L_(0x00000003), LL(0xd4f22a67,0xae357b86),LL(0x3ce6e16b,0x94e06b89),LL(0xa3849b8d,0xb6058ad8),LL(0xacee1675,0x6add0f99),LL(0x39df12ed,0x43cd380c),LL(0x5c645ff1,0x0481e233),LL(0x94a0f618,0xc84b4bf9),LL(0x805a52a4,0x49a710f4),L_(0x00000098), + LL(0x577d0472,0x99d73698),LL(0x68ebe9cf,0x7fcd4216),LL(0xc625e525,0x4922e8d6),LL(0xe579cc68,0xe272485c),LL(0x58eef2df,0x1aedb9d5),LL(0x6bba0e47,0xf69dbcc2),LL(0x6afac0cf,0xd8f85c14),LL(0x4dfdd56a,0xc7e717e4),L_(0x000000f2), LL(0xe505ba10,0x7d4e9483),LL(0x056cb0ab,0x8a2580c9),LL(0xee676f9d,0x031109c0),LL(0x0e2ecd89,0x784c6d24),LL(0xedf27261,0xeac131cc),LL(0xdb6b9edd,0x9428ee22),LL(0xf59f93aa,0x90347b1c),LL(0xd59691aa,0xcb3849d1),L_(0x0000014c), + LL(0x6fba378b,0xc42ea299),LL(0x33ae1a32,0xd0ddacf9),LL(0xb43b79b9,0x30561bd9),LL(0x0ad2636c,0x12241370),LL(0xd830def9,0x85a779a0),LL(0xda5f6561,0x28b8580f),LL(0x7e785d86,0x8bafa8c6),LL(0x48ce8b18,0xc75df63d),L_(0x000000d2), LL(0xd7e01b7a,0x5a90afd2),LL(0xc72b304c,0x1b4b2e57),LL(0x40d7dec2,0xe0f45d07),LL(0x3eb94cfd,0xaabbfa71),LL(0xae1b3f10,0x37fa8b4f),LL(0xb080d24d,0x6f6447d2),LL(0x142abdb3,0x20453501),LL(0xfd470df7,0x76e433f8),L_(0x0000007e), + LL(0xb1a06043,0x1f809e00),LL(0x9eb8b4e3,0x91e1d4a1),LL(0xa399e369,0x9b1aa8fe),LL(0xf15f9651,0x80a83b4c),LL(0xea343c7b,0x1c2fb2b2),LL(0xc40680cb,0x4d003567),LL(0xe7a338fc,0x65bc46fe),LL(0x4519127e,0x3a269638),L_(0x00000030), LL(0x000ab675,0x8811cc38),LL(0xcd6861c0,0xd2e2abb7),LL(0xccb0e7ea,0xce5461a0),LL(0x8c05450d,0x28a458ea),LL(0xeff9ba00,0x51ce8e58),LL(0x3e543072,0x41ebfad1),LL(0xa43fc5d6,0x2acf8a4f),LL(0xc0d63fae,0xd16efc25),L_(0x00000094), + LL(0x33854823,0x0c31be44),LL(0x25c21bb4,0x171af22e),LL(0x91e02b25,0xa0756859),LL(0x87db4292,0xd07cf03c),LL(0xd52aff6a,0xf2199b54),LL(0x476b6c0b,0x4c50edf5),LL(0x1bd465b7,0xdeb36507),LL(0x9e6301c1,0x957f58a4),L_(0x00000154), LL(0x8e331516,0xf73b742f),LL(0x5e9d3550,0x6b92e894),LL(0x419be8da,0xd785e55e),LL(0x95d412eb,0x6018e5bc),LL(0xadbd35ab,0x079447ae),LL(0x5f3359bd,0x21b9bd0a),LL(0xc4db3315,0x5774802e),LL(0x4978d805,0x18a2368a),L_(0x00000167), + LL(0x6256586d,0xd53479d6),LL(0x5c26f234,0x2d429971),LL(0x107f7e92,0x8c689924),LL(0x334d8841,0x2a5fa3eb),LL(0xe5ebe430,0xc519e325),LL(0xe8291ba7,0xf2242ce5),LL(0x8a0c19be,0x20419cdc),LL(0x804a91ee,0x70dcad32),L_(0x0000017f), LL(0x96b0c9d5,0x78a46e2e),LL(0x18b297a6,0x21fc2dc8),LL(0x3ba036e4,0x30517e2f),LL(0x7a021835,0x49f89605),LL(0x19710681,0x84156ac1),LL(0xd61e5109,0x05c42243),LL(0x31ade9f9,0x7b661ab8),LL(0x83c25735,0x22eb398b),L_(0x000001df), + LL(0x682dd914,0xad081cbd),LL(0x1433b543,0x88d8cd2c),LL(0x94641d24,0x2da0394f),LL(0xd8e36e70,0x48288ca4),LL(0x461fe782,0xa112c8a6),LL(0x6f063613,0xb8624a48),LL(0x77efb66b,0x511d90ff),LL(0x016e8d41,0xce809694),L_(0x000001a1), LL(0x1fc39355,0x36feced9),LL(0x3ecdac71,0x921f42e8),LL(0xee8e2857,0xe82b293d),LL(0x2c3ef9bb,0x182b25ab),LL(0xac32f4bd,0x297ad819),LL(0x74b598de,0xdd15916b),LL(0xd5e666a5,0x51456a24),LL(0x447be0b1,0x4dc25c5c),L_(0x00000179), + LL(0xf9b2eade,0xb1762839),LL(0xba507049,0xed038901),LL(0xdcef710b,0x4b349ec8),LL(0x2489f866,0x37b4ec4e),LL(0x991460d8,0x94e1cecc),LL(0xbf2a63d2,0x33d105a8),LL(0xc7e7415f,0xbf883b5c),LL(0x268241cd,0x2f565fda),L_(0x00000135), LL(0x38741429,0x8bf3904a),LL(0x8e823f54,0x0c2d77f6),LL(0x06de5eb9,0x2c00d580),LL(0x89b51b4d,0x41ce4b94),LL(0x794caf3e,0x177cd9b2),LL(0x7c62716f,0xfe0ae88a),LL(0xb7e50074,0x4d023907),LL(0x49a489fb,0x545f8faa),L_(0x000000b9), + LL(0xbcdfb42e,0x05813dea),LL(0x62545e9a,0xc84039c9),LL(0x70606ec0,0xcdf6907b),LL(0xec7e8e9b,0x2e4e87c0),LL(0x9d6e053f,0xffa08764),LL(0x22a2e351,0xe5b305f1),LL(0x95345fe3,0x65c90711),LL(0x4f24c950,0x139d472c),L_(0x00000144), LL(0xa58aa810,0x9eeab46c),LL(0xac8b67e8,0x267bcc83),LL(0x702c21e5,0x0dac9b29),LL(0xce390fe4,0x60429071),LL(0x6ef71376,0x4a80e0d7),LL(0x47100322,0x0ef6a473),LL(0xdc625a85,0x759024e7),LL(0xea01db5d,0x1e4722a2),L_(0x000000a2), + LL(0x4965f4fd,0x5678bfca),LL(0xb048b1b3,0x5bacba68),LL(0xf518ba8c,0x1626088b),LL(0x7054f024,0xa686c886),LL(0x933a9118,0xbb623954),LL(0x1c3c471e,0xc4da98f0),LL(0xf1b8c9b1,0xa0619dd5),LL(0xaeebf226,0x24b28dc5),L_(0x00000108), LL(0xad3fede9,0x47814012),LL(0x49c3a34f,0x1cf06d59),LL(0xfcdcc300,0x6d4a798d),LL(0xe86df54b,0xa1a4dd57),LL(0x1534b80c,0xaf606d64),LL(0xbdfde769,0xde1cbaa0),LL(0x649c3a2a,0xbf6c9950),LL(0x763574e1,0xaaf6f737),L_(0x00000139), + LL(0xc23c5aa2,0xf687c377),LL(0xca314119,0x3eacfd33),LL(0x2512d094,0x9c0e1850),LL(0xe55f9fd6,0xc3c6ea7e),LL(0xc20685b7,0x66291556),LL(0x4868b07c,0xb5895337),LL(0xf9f339d7,0x9238a109),LL(0x75d6855b,0xac6af37f),L_(0x00000091), LL(0xf49812cf,0x6eb5d5b2),LL(0xe7603bff,0xf7552855),LL(0x8f73b087,0xc19b7320),LL(0xe8f5c0ad,0x55df5442),LL(0xb6aeabd3,0x3a4b8876),LL(0x8dc2b22b,0xf8bca737),LL(0x26f89265,0x3dbb040c),LL(0xfb6645f2,0xb09ab1bb),L_(0x00000138), + LL(0xe9c4fede,0x9e2dc755),LL(0xea8b03a8,0x5618c490),LL(0xd5d01455,0x01a7a348),LL(0x9622ab8a,0xa6b5c4df),LL(0x9adea853,0x303519de),LL(0xa9b99058,0xb3d0934b),LL(0x0fbd9ea2,0x2cdee030),LL(0xe856d6fd,0xa351d2a2),L_(0x0000008b), LL(0x6ac4ec77,0xea40ff5a),LL(0x4859e663,0x906f2d7a),LL(0x71904b77,0x411180a4),LL(0xbd7ebd35,0xe50b9460),LL(0x0ec190c2,0x2e7f4d73),LL(0x4c9e4aac,0x76a98ae4),LL(0x4323017a,0x7f0e29c1),LL(0x22ea8f39,0x31c71758),L_(0x000001e3), + LL(0x0402f8c8,0xcf98bee6),LL(0x54f3df55,0x672d0a69),LL(0xe9759866,0x1addc9d4),LL(0x9c17b622,0x6c819f7f),LL(0xc42650ec,0x6b1209c4),LL(0x6a1aa1b9,0x2b341fef),LL(0xdbcf91bf,0xc99d2b99),LL(0xed76cdf2,0x27467cd2),L_(0x000000ee), LL(0x6ea222ca,0x64754f19),LL(0xc40615cf,0xb8f1e46f),LL(0x9a8d5587,0x540f1fa5),LL(0x804f7dd7,0x21752096),LL(0x2c95388c,0x9444e15c),LL(0x133319bb,0xb1d5a817),LL(0x29552f4e,0x79fc1cba),LL(0x93730e70,0xcae8a131),L_(0x0000011a), + LL(0x2b9c7277,0x88863b50),LL(0xbfdb676e,0xb9545954),LL(0xfcfc0194,0xe74bedd7),LL(0x888694d2,0xe59a14c4),LL(0x236680d1,0x4cd674c0),LL(0xacdf13c1,0x52151e94),LL(0xcdbecfcb,0x6a28bc34),LL(0x641d77e2,0x6293af48),L_(0x000000e3), LL(0xa8fee6f0,0x2e8f361b),LL(0x67004141,0x39634681),LL(0x5db1f02f,0xf975c602),LL(0xe645bd3a,0x8b39a53a),LL(0xfafccb60,0xa58e37f9),LL(0x33ab2637,0xcf611fd4),LL(0x8b8cc6bb,0xe7f89e7f),LL(0x28eb10f6,0x5f527820),L_(0x000001d1), + LL(0x8fcc2459,0x9411ca0d),LL(0x92267e14,0xb385c8ea),LL(0xbbfcc2ab,0xbfd56d29),LL(0x34b29656,0x5f2180a7),LL(0x06f72807,0x6dc34000),LL(0x02310437,0x854af754),LL(0x1bae73e6,0xbc753242),LL(0x06a8d2dd,0x11770a34),L_(0x000001d7), LL(0xb8d63658,0x14476594),LL(0xeb8cb497,0x6ba99aed),LL(0xc86324ad,0xc49863ca),LL(0x8a316428,0x2e5cfc3d),LL(0xcb62d82a,0x79adc3e0),LL(0x9e5f3fda,0xcaddeff7),LL(0xb4f990b6,0xae15a98e),LL(0xb9b0e410,0xedf394c7),L_(0x0000000a), +}, +/* digit=11 base_pwr=2^55 */ +{ + LL(0xf2938b13,0x20c391c2),LL(0x96d1c5f4,0xeaef76b3),LL(0x6bb17f5e,0x7feb16a1),LL(0x3f16a57b,0xcc801552),LL(0x4aadf126,0xcded6e6d),LL(0xe23393c9,0x6848f602),LL(0x2c8dbcb3,0x49f3a9ae),LL(0xf811e23c,0xc0c1ebfa),L_(0x00000130), LL(0xd5da561b,0xaf1b88cd),LL(0xb4c22029,0xaa7f22fc),LL(0x9624d6d5,0xbb120735),LL(0x416db935,0xa8308449),LL(0x85fd3219,0xc467f9f1),LL(0xb4d3e00f,0xa69d57d8),LL(0x187052a8,0x0528c91e),LL(0xb79e6638,0x2a603bc9),L_(0x000001a4), + LL(0x474fe094,0xca26efe1),LL(0xa3ad38a0,0xf5cd529d),LL(0xec34abea,0x94808b1e),LL(0x27c847ac,0x87ade961),LL(0xfa6df215,0x6a43fa8c),LL(0xbcfdb5ad,0x947fbb39),LL(0xdd4d0c9f,0xbca687c5),LL(0xe8772a4e,0x7d79e215),L_(0x00000122), LL(0x81cb032e,0xbf926e1c),LL(0xb04fbc5a,0xb9c12ffd),LL(0x34707ba5,0x4ee8c89b),LL(0x81aa347c,0x367a152d),LL(0x4cd56572,0x74511a3a),LL(0xa6642939,0xd0e3b8f1),LL(0x60ea13e9,0xee14ab42),LL(0x81a19a28,0xea76ba4c),L_(0x0000015d), + LL(0x04a0af27,0x6b0c75c4),LL(0x23a4b0aa,0xdb181c23),LL(0xdc940ab7,0x7b70983d),LL(0x328a76b8,0xd5b473a0),LL(0xadcb9bcd,0x3863dc05),LL(0x646b4949,0xe5090fd0),LL(0x0b996e3d,0xd0261360),LL(0x7c332b20,0xcc6b2f86),L_(0x000001c7), LL(0x3ac008c8,0x28cd5819),LL(0xf08cb2c4,0xfbdf661a),LL(0x9b1c2455,0x2be7d7be),LL(0x38fbe0c1,0xbd91e037),LL(0x84e69e29,0x1cdba496),LL(0xc6f94abf,0xa8445728),LL(0x8e9508e3,0x4a144f07),LL(0x8ee0e340,0xc5b72f6a),L_(0x00000066), + LL(0xfe2f1a3a,0xaff1e1b3),LL(0x87421ab9,0xbbfcc6da),LL(0xa3305ebd,0x4b75a8e1),LL(0x8f4cb778,0x4410056f),LL(0xb5abdc6a,0x4ff65612),LL(0xd83f32f5,0x21c44b1c),LL(0xb989d251,0x80a7bb1f),LL(0x5214abed,0x8f200e11),L_(0x000001ba), LL(0xd63a07ff,0xf4fb8525),LL(0xf5f23c02,0xaa8e02a4),LL(0x405911d9,0x45abb8b1),LL(0x7a6dae03,0x4834d14e),LL(0x4621957b,0xeb31fdc5),LL(0x7cbf9b75,0x26ee5dca),LL(0xee84304e,0x37349cc1),LL(0xcc6a2c7d,0x5a34c3af),L_(0x000001c8), + LL(0x3c425b85,0x9f122c9e),LL(0x71cfc92d,0x9c6ec42c),LL(0xb86c84b7,0xc8d12bf6),LL(0x1c821b85,0xe8432cc5),LL(0x197e0f04,0x4258bc34),LL(0xc4f03c70,0x60ae518c),LL(0x811512ff,0xf050c9b8),LL(0xe8038335,0x0b215595),L_(0x000000f0), LL(0x9423e29c,0x423ac4f7),LL(0xb15c3155,0x2fd13662),LL(0x7684c454,0x5cf8078d),LL(0x1a7bfb14,0x2b928e98),LL(0x1d05b843,0x3bbf2a85),LL(0xeeb1e658,0x356da90c),LL(0x179bc7a9,0x11d26c87),LL(0xf524843e,0xf4159e0d),L_(0x000000ec), + LL(0xc58a5d93,0x08cefac8),LL(0xb1885068,0xe8422939),LL(0x5985dd6e,0xab14cf0e),LL(0xcda94a64,0xc27af983),LL(0xd127851a,0xf24f6eaf),LL(0xbab20f8f,0xda3b25d8),LL(0xa549d9c6,0xed810bd4),LL(0x5bf18f37,0xf630e4c9),L_(0x00000055), LL(0x51ad76d0,0xae18594e),LL(0x52697460,0xf8de9d89),LL(0xaec56660,0x294777cd),LL(0xe3a93a39,0xf7dc98fd),LL(0x63fcc0bd,0xc0c53dc3),LL(0x5d2c2708,0x55da9198),LL(0x3692d050,0xebcde249),LL(0xcdc4d312,0x8d0017f5),L_(0x000000c1), + LL(0x045c6797,0x1d9471ec),LL(0x737ba42a,0xd3401c6a),LL(0x33fd5fca,0x3c2758a5),LL(0xb016b83f,0x79b1c693),LL(0x3409d0d4,0x5f80d853),LL(0x4f2a7005,0x4d1634ee),LL(0x799e106c,0x1e92ef70),LL(0x632dcd5e,0x86232632),L_(0x00000087), LL(0x06622996,0x1acab1e2),LL(0x92c31a31,0x91455009),LL(0x740223dd,0x15a695ed),LL(0xa95f341b,0xe601b98b),LL(0x17db74b3,0x19ccbb77),LL(0xd916a466,0x44573d27),LL(0xc31a7a19,0x093c0363),LL(0x1bb20e06,0x6715c5f0),L_(0x000001e7), + LL(0x5f8496f0,0xa1a3f86e),LL(0x2df7ec8e,0xf1f8f7f3),LL(0xd8551991,0xb16ec397),LL(0xbc80f4ee,0xebe5be1a),LL(0xa1e6cbf5,0xaf8233b8),LL(0x5c403702,0x41483767),LL(0xbf97ecb0,0x2899a5cc),LL(0x58655568,0x0720d399),L_(0x00000028), LL(0xdc27af93,0x88312054),LL(0xd550df72,0xf87e274d),LL(0x193eb1e2,0xa715c43f),LL(0x97773656,0xcb67dce2),LL(0x8a585c6e,0x0aacb5db),LL(0x6332fcd1,0x4f16d92a),LL(0xdeebccba,0x2b8001ac),LL(0x8936c8da,0x7b627657),L_(0x00000181), + LL(0x24e7c452,0x8d63a794),LL(0x35fd304e,0xdd225fc9),LL(0xa6aae952,0xc40c9b7f),LL(0xd5054f16,0x42316d8c),LL(0xf663b3dc,0xb3d7abe3),LL(0x13c94097,0x7aa82bbf),LL(0x78263190,0x2a622ce8),LL(0x819c0b14,0x2b1dba5c),L_(0x0000001a), LL(0x3c259ac8,0xe69bb850),LL(0xdf7bd8ef,0x985f2ed6),LL(0xc76c2599,0x44f156c5),LL(0x46e2c0c0,0x7cfc49ae),LL(0xf5fb07c3,0x6f59a7a0),LL(0x2f48e451,0x1b89eefd),LL(0x88119cbb,0x1c41ec61),LL(0xa18666db,0x53014a3d),L_(0x000001f0), + LL(0x4e03d590,0x792d6d08),LL(0x4d84ecf1,0xe0110c24),LL(0xc93fa7f1,0xc72b1bb4),LL(0x908f695c,0x1730f1b2),LL(0x8d0bc692,0xdb0b36b3),LL(0xe4bf469c,0xa1db29c0),LL(0x1d41428d,0x7a577f2c),LL(0x2cd1253d,0x23b65522),L_(0x0000006a), LL(0x7ebe31ef,0xa4ba5fbd),LL(0x9808ec8a,0xa5383520),LL(0x49718327,0x2c210a5f),LL(0xdc5bb249,0xef53e1db),LL(0x7e38e02e,0xc9d3c171),LL(0x7b41e983,0x3a07d487),LL(0x2d8aedea,0x6c0e3ba1),LL(0xa17e058b,0x22c8be6d),L_(0x000001d0), + LL(0x51500886,0x6a5713b6),LL(0xac6235d1,0x19855a0f),LL(0x32d1869e,0x093a8212),LL(0x8afdb213,0x89861196),LL(0x3402ba32,0xb3676c48),LL(0x5e54b89e,0x53597329),LL(0xbdde3064,0x94cdc873),LL(0xc3d273b6,0xfd911ed5),L_(0x000001f1), LL(0x65cf5cfb,0x0d98f860),LL(0xf6cf3683,0xa681e586),LL(0x6f5c1e3f,0xc6905825),LL(0x7d626d06,0x571b75e4),LL(0x00a44322,0xf9fe1aa4),LL(0x34ece73d,0x3975b815),LL(0x38add31a,0xfa3db092),LL(0x499ecb33,0x2ce86fab),L_(0x000001bf), + LL(0x8aeb123d,0xf5870ab9),LL(0xa353002c,0xa12da044),LL(0x6150f34f,0x0086b83e),LL(0x69e6eea2,0xa2cdf131),LL(0x5e80e0a0,0x528616b2),LL(0x2d13e0cc,0x4a67c598),LL(0x9702e01a,0x83d6e661),LL(0x15b60ef1,0x6f9172f8),L_(0x0000001f), LL(0x6386476a,0x7b2b5776),LL(0xe6acc547,0x055811a0),LL(0xba422b24,0xa9873020),LL(0x8c990991,0x310acf2c),LL(0x96459d45,0x78701ea7),LL(0x917c30ec,0xd1688c83),LL(0xdb51be44,0xb42ce9e9),LL(0x0b514c3b,0x0b03fd87),L_(0x0000008d), + LL(0xb09c0812,0xbcc82868),LL(0x69816459,0x580f7a11),LL(0x9b94ac07,0x11b4de1d),LL(0x120451de,0x8f21a7aa),LL(0xc048b454,0x0f6b490e),LL(0xca8d647e,0x5d0f4e1d),LL(0xf1f7c090,0x3e12d889),LL(0x1ad27c80,0x5b341256),L_(0x000000e5), LL(0x5e7c3d96,0x35f1970a),LL(0x4366eed0,0x1134e984),LL(0x55c0352d,0x7ea259fe),LL(0xfad7d83b,0xda4dcbce),LL(0xdd5f6008,0xb2924c78),LL(0x01b25214,0xac404086),LL(0xf325f997,0x2b613948),LL(0xf37e21a0,0x26e31be0),L_(0x000000b4), + LL(0x40c9bb67,0x017edbd6),LL(0xf483d72a,0xb08491c6),LL(0x58a225c5,0x568a7e71),LL(0x7fde8697,0x821bf73d),LL(0xef4bc022,0xec765e3a),LL(0x8d1daf2f,0xb59a1d2e),LL(0x72d486e7,0x1edfc037),LL(0x2a595f95,0xf1683f88),L_(0x000001ff), LL(0x4c4cc13e,0x55fc5381),LL(0x96f30cc5,0xc6ce2141),LL(0x76a3af64,0x339f5668),LL(0x5449bfff,0xe438adb5),LL(0xf3c48dff,0x1aa59ae8),LL(0xce59b544,0xc0fd6c57),LL(0xb7bdc7b7,0x8e51d10e),LL(0x973b8e1d,0x6427d578),L_(0x0000016a), + LL(0xf61dae1f,0xe76cf424),LL(0x4eac44ab,0x559e7a5a),LL(0x0ddf44f2,0xc58d75d8),LL(0xfb0d499a,0xab62039f),LL(0x6cf6c677,0xd4e76825),LL(0x2e427953,0xa955fdca),LL(0xe1d73f88,0x049f7f5d),LL(0x89dc4a2e,0xd5493485),L_(0x0000015a), LL(0xadae9a0f,0xa5dc86bb),LL(0x2a75769b,0x606d9e57),LL(0x550fb22b,0x260bcabb),LL(0x7bccdd84,0x2e3ee7a3),LL(0xc4b6b979,0x03bd7f7d),LL(0xfc3349bd,0x122b5333),LL(0x95f84290,0x4bdf7095),LL(0x3057b4f5,0x6af3cf31),L_(0x00000022), + LL(0x64c8b352,0x1d055192),LL(0xf272a08c,0x343f766f),LL(0x142d545c,0xb8bd86e9),LL(0x860ef117,0x60c69c66),LL(0xb6de931c,0x1b54e53c),LL(0x9924f2f5,0x878c0c9b),LL(0x0b949095,0xfba7e2a3),LL(0x6916f5f1,0x7da79c3a),L_(0x00000181), LL(0xbd559979,0xe06ad6ba),LL(0xd551de11,0x3b3cbbe6),LL(0x6c45d4c3,0xcc4aa553),LL(0xe3c9e3df,0x1bb5c238),LL(0x05a1e382,0x8dfc012d),LL(0x84d8d463,0x3b856506),LL(0x05b7e241,0xcdcfd8e8),LL(0x27718949,0xc1a85e66),L_(0x000000ef), +}, +/* digit=12 base_pwr=2^60 */ +{ + LL(0x09d8e58c,0x0af6a9bd),LL(0xdca0a6cc,0xfe5f904b),LL(0xd9e6d336,0xd87d0339),LL(0x3b8c9d8b,0x4d463bab),LL(0xfb629c3f,0xc203e46d),LL(0x4ea62ed4,0x998a0ef3),LL(0x64035458,0x62783285),LL(0x7769592c,0x3c56ebb3),L_(0x0000001b), LL(0xb96cc870,0x259a17aa),LL(0xd51ce441,0x8666df8e),LL(0xc62b1c65,0x437c7966),LL(0x74db6999,0x0fecb364),LL(0x7c60998f,0x1f725b1f),LL(0x71fdafc2,0x5b56396c),LL(0xa547fb5a,0x9d888686),LL(0x0f566ae7,0x130033ff),L_(0x000000f4), + LL(0x41a4fd11,0x12a6c73f),LL(0x66164319,0xfe4c8bf4),LL(0x9c6ffbd2,0x42f313ec),LL(0x2869e4fd,0xf8b100ba),LL(0xbae712b9,0x0e18229b),LL(0x61a1f1da,0xffe55501),LL(0x032c80f2,0x3bfaa0e0),LL(0x48f0b1d5,0xb83c7607),L_(0x0000015f), LL(0x3cf7a1fa,0xa0ed3335),LL(0x8b3c031f,0xc141575b),LL(0x53c30e33,0xfa62217c),LL(0xf9f945a8,0x8b667de4),LL(0x889399aa,0x7c4952fb),LL(0xb711abc7,0xabedb6e3),LL(0x59e7e12f,0x5a1b2cb9),LL(0x1857ebfe,0x4206e243),L_(0x00000134), + LL(0x301de7d2,0xa95f9c5a),LL(0x0d937115,0x2ee0eb80),LL(0x4b1412c8,0xdf5a5904),LL(0xe6f39cf3,0xcd50327e),LL(0x9a796b16,0x0841dfd1),LL(0xc493ac5c,0x19d15d79),LL(0x7275eb23,0x4b9d4479),LL(0x1a3b6feb,0xe1eb10df),L_(0x00000142), LL(0x6d17f389,0x7551bac5),LL(0x7a907c78,0x232dc783),LL(0x82e7d67e,0x5acaf222),LL(0x5ebc3c22,0xe17100c9),LL(0x62250256,0x3198b234),LL(0x4beb3ba2,0x16986b8a),LL(0x492d3035,0x973e4135),LL(0xfcc0dd28,0x2e1155d6),L_(0x0000011b), + LL(0x4df6981f,0x1f14d7bc),LL(0xe951da15,0x3d397c45),LL(0x3964143f,0x24be6549),LL(0x2e556c9c,0xe1293e25),LL(0x3aed330a,0x4bfda40e),LL(0xdf82159a,0x3b13e72c),LL(0x514f7b17,0xa5b859ff),LL(0xe20684bf,0x90812f67),L_(0x000001ce), LL(0xe9a0c258,0xbca9abf7),LL(0x3b0b3a0f,0x72194a82),LL(0x11d27090,0x17f5564f),LL(0x9bbb7a7f,0x87f0af99),LL(0x96c01479,0x69d62017),LL(0x45cce25a,0x0c43d35c),LL(0x26584337,0xcbff6e89),LL(0x19a55401,0xb503e2ea),L_(0x000000ea), + LL(0xb5cd512f,0xaecaabc4),LL(0xdeccde50,0x9ffdf34c),LL(0x395d2404,0x25068e1b),LL(0x40559189,0x93fb9ea4),LL(0xd141ad3f,0x2a60ba95),LL(0xc42f76f0,0x414a5981),LL(0x946bf800,0x138c47b5),LL(0x38435023,0xf314147e),L_(0x0000013c), LL(0x9ae19e3e,0xe38bdcc6),LL(0x3cebd917,0x0966bac7),LL(0xc3533788,0x2718c3e8),LL(0x33ee6ede,0x10236ae8),LL(0x4f5b88fd,0x44797bb1),LL(0x485e76bd,0xb2b31296),LL(0x68194c12,0xe45112ba),LL(0x0cb75dc1,0x8574000b),L_(0x000001d8), + LL(0xeea24bcd,0x8f37d315),LL(0xf77a65b3,0x37731160),LL(0xde279622,0x6f06ae65),LL(0x87ebd334,0x25b38b15),LL(0x2a1d2c7a,0xa55c6b9f),LL(0xb1687394,0x0ccf2f34),LL(0x4f27c66a,0xecf3de75),LL(0xa9866c84,0xa4a0f4aa),L_(0x0000014d), LL(0x8dffeb86,0x0366dd8b),LL(0xbfeaeff0,0xfe941121),LL(0xa80b5c3b,0xc3fed2fa),LL(0x18a5b6a4,0x23dfdf47),LL(0x2ef007c6,0xdb0791d2),LL(0xcec61c6b,0x6d79949c),LL(0xe328d9cc,0x0d03e696),LL(0xaa14a153,0xfdb36710),L_(0x00000145), + LL(0x1a8d3cd0,0x736dcfa6),LL(0x77e26493,0x6af49ff9),LL(0x089ee4ac,0x1720bd71),LL(0x2f3b86d6,0x48d2c5df),LL(0xbcc66a78,0xd78e07af),LL(0x1f230a9e,0x077a7ceb),LL(0xd2f61bf5,0xfbf99e70),LL(0x92770c3f,0x7ae5f084),L_(0x00000148), LL(0x64c29961,0xa6ee44c4),LL(0x990f4f03,0x4aacbd8f),LL(0x45377427,0x0ef447b6),LL(0x55b5c873,0xe02e661f),LL(0x11e65ae5,0x99f13f10),LL(0xfe17d3ed,0x393cf4c8),LL(0xdbeb35dd,0x23277110),LL(0x65a7d1cd,0x444802cd),L_(0x000001fb), + LL(0xf621fd74,0xea71a842),LL(0x4c057a1d,0xfc8fb859),LL(0xe1689c80,0xadc9a8e1),LL(0x09c22f52,0xc47b8163),LL(0x0a960c99,0x90c495f0),LL(0x0a0f356d,0x88242e20),LL(0x87494b79,0xb7f9ca6a),LL(0x6fdcd587,0xd76d2c39),L_(0x000001c4), LL(0xd6ecf158,0x1e35970d),LL(0xaee47a26,0x8df13449),LL(0xadfd394c,0x67553f2c),LL(0x71cdfbec,0xa43c6154),LL(0xf09db2ac,0x4606556e),LL(0xf2e04011,0x12eca225),LL(0x9dfb28da,0x87a4c839),LL(0x28812bc5,0x8cba8984),L_(0x000001ab), + LL(0x49041a38,0xcb554ab1),LL(0x3446834e,0x21810284),LL(0x2ab359a6,0xf95fa59b),LL(0xf33f9ef0,0x16db657d),LL(0x0f8d940a,0x38fe2897),LL(0x39b668bf,0xdeba7f4c),LL(0xc6452278,0x7471cf19),LL(0xb96dd1e3,0x732f77c2),L_(0x0000011b), LL(0xfa410fb4,0x745c3f1b),LL(0xbca782f9,0x8bd5ef13),LL(0xc4e21488,0x8211733f),LL(0x8f6c1b78,0x50b780cb),LL(0x4b628b50,0x1a1a0206),LL(0x78e4de6a,0x44975c37),LL(0xf9f51865,0x6ef7e616),LL(0xbadf032d,0x3882a9ad),L_(0x00000084), + LL(0xe4d0aa5a,0xe84ad756),LL(0xf2f7ceab,0x6545847a),LL(0xfb04aded,0xdd4cb1ba),LL(0x87083ecc,0xf4c8bbb0),LL(0x452249b7,0x6531b732),LL(0x868536ed,0x6968e15d),LL(0x1d0209ca,0xf0285aff),LL(0xfaefc194,0xbed23705),L_(0x000000bd), LL(0x6489b527,0x3ea47ce4),LL(0x69374c35,0x2a6d8757),LL(0xdc6375ee,0xc6f768ea),LL(0xaeba5bab,0x327c743e),LL(0xda6790e0,0x9a01ae4a),LL(0x1a9de4f9,0x3ae6cb85),LL(0x9ac5b7b3,0x6d32a174),LL(0xf134b615,0xdf38a0f3),L_(0x000001ec), + LL(0x7d9c19cd,0x688d2325),LL(0x79db6c85,0x5359ff24),LL(0x764f954a,0xc7801c4a),LL(0xfa78e8b8,0x098ede82),LL(0xb52cd1ab,0xd34f03a8),LL(0x66adb2da,0xcfcfe244),LL(0xfc69d130,0xb5e52304),LL(0xf88483bc,0xab73db68),L_(0x000001c7), LL(0x228f1338,0x077d01af),LL(0x7eb9fb07,0x8abf2d7a),LL(0xcb62a0d5,0x37a4ecbb),LL(0x1a28e347,0x06b68356),LL(0x35c05ae1,0xadaac01c),LL(0x2f3d8c6e,0x712aa1f3),LL(0x9ee5907c,0x69606236),LL(0xc9bdbb2c,0x7b2e6894),L_(0x00000011), + LL(0x0c5ccb9d,0x09d420b2),LL(0xccc993bc,0xa3ad7d2a),LL(0xd8b3ee97,0x7986ac14),LL(0x59fa9e76,0x95dc5774),LL(0x9477b42b,0xfbe8e9d7),LL(0x89d7ab26,0x79b03712),LL(0x017b7f94,0x77f9bdea),LL(0xbd8dcef1,0x7a238609),L_(0x000001fe), LL(0x1b9ffcc9,0xaee002b6),LL(0xcdfc127c,0x23640ec5),LL(0xad2abcbc,0xc6dc5bd5),LL(0x05982646,0x20400061),LL(0x3c1c6b9f,0x6ee16a76),LL(0xc943d1fd,0xd619a75d),LL(0xd16a85f5,0xa278715e),LL(0xd8747be6,0x34ec8668),L_(0x000001c0), + LL(0xdaf270b9,0xcec9be5b),LL(0x6f5e16ec,0xfd62380c),LL(0x192223b1,0x27bda6fd),LL(0xe1e75d7c,0x0df8a788),LL(0xd01bccf4,0xbeed1a6b),LL(0x6611a8ed,0x01402436),LL(0x17838dc7,0x7f189fd3),LL(0x615a507f,0x760bd862),L_(0x00000152), LL(0x090f0135,0x791dac6d),LL(0x2bb5aa65,0x0457b859),LL(0xece0f798,0x1a8af3a8),LL(0xde75b69f,0x6625db63),LL(0xcf064060,0xeeda55fc),LL(0x0d8f8c69,0x05536430),LL(0x27c6a431,0xb1dc58b1),LL(0x56c1ac3a,0x0c1a1dab),L_(0x000000ae), + LL(0x18e8414b,0xfb73e1e4),LL(0x0f973c1b,0x6977f355),LL(0xca40d04d,0x2797e4c7),LL(0x01c089b0,0x1b05804b),LL(0x0064b701,0x7b76fc1d),LL(0x9677da0f,0xb0b47105),LL(0xd02ba9e2,0x4fb9b758),LL(0x6b2435ea,0x2fd704c2),L_(0x000001a6), LL(0x2578e31f,0xdc19942f),LL(0x4734e848,0x366f685b),LL(0x6b9e935f,0xb3827f30),LL(0x81e91d77,0x4cce7910),LL(0x36ada690,0xcb031a95),LL(0x227eb763,0x6ac3a0f0),LL(0x527fc0d3,0x7b60ac80),LL(0x404eb0f3,0x2c62b4f1),L_(0x000000c9), + LL(0xfa5ed043,0x95cf6b06),LL(0x69fd4f1d,0xbdef736a),LL(0x9044b8ce,0xd7e44ee1),LL(0x546a5d1c,0xe3ac270c),LL(0xbe0ace78,0xe59e1538),LL(0x27b93218,0xe51fc4ac),LL(0xf26796fb,0x71f9328b),LL(0x9137cac1,0x07a55147),L_(0x00000057), LL(0xedbb99a1,0x9ce1532c),LL(0x37d59c98,0x2c0e5b9e),LL(0x62f632e6,0x55146f87),LL(0x29fd2249,0x402150dd),LL(0x12ea0f69,0xf442153e),LL(0xfa397b38,0x9b5cefd9),LL(0xc5ad174d,0x8cae5294),LL(0xb46b9f16,0xcd8b0a60),L_(0x000001a7), + LL(0x4276a1bd,0x1e614695),LL(0x71344edf,0x2b4a50c1),LL(0xb3013081,0x4896c770),LL(0x2cf314a1,0x96a68659),LL(0x90053fe7,0xd79226d8),LL(0x5847ac79,0x3ada869a),LL(0xf60993a8,0x7d156a5c),LL(0x67e4b5fe,0x7850cdf6),L_(0x000000dd), LL(0x5fb3dea4,0xf35bcbb3),LL(0x4e2d6021,0x9877f0a3),LL(0x90be9398,0x4d6435bb),LL(0x86130340,0xe5919257),LL(0x2710c007,0xcc99d199),LL(0x87d3586c,0xc1451c79),LL(0xe8681c58,0xfa896da8),LL(0x6659a487,0xb1a9e543),L_(0x000001a8), +}, +/* digit=13 base_pwr=2^65 */ +{ + LL(0x73f3ddc5,0xfa295332),LL(0x0b259ba7,0x94f8c958),LL(0xa4092fea,0xbe9d56f6),LL(0x622efd38,0x0f2ba425),LL(0xa4d25a72,0x57c0adb2),LL(0x2498a9ea,0x11f11875),LL(0x893bbb4d,0x195ec41d),LL(0x2f56b02f,0x2ad72c4b),L_(0x000001ca), LL(0x1ab7060a,0x0fa4013f),LL(0x521f983a,0xebae7f17),LL(0x5292b2f1,0xdebce289),LL(0xd6d75002,0xb6cd203a),LL(0x93bfe503,0x3c3592c9),LL(0xa40b351b,0x180f5400),LL(0x9b6bafed,0x291283ae),LL(0xd4d6a9f0,0x036cf95d),L_(0x00000163), + LL(0x5db76801,0xa8cfa5a9),LL(0x33878665,0xa5401cc3),LL(0x809b2a4b,0x6cdc3f0e),LL(0x90d9594f,0x9bbfac67),LL(0xd551d6e9,0xfd836074),LL(0xe874e847,0x13f89d9a),LL(0x264b3b0b,0x7a6ec5fa),LL(0x0a3ac51f,0x6dd250c6),L_(0x0000001d), LL(0xa7747bde,0xd1e14aba),LL(0x7c3196ca,0x1495ef12),LL(0x78a62924,0x0cbcf8af),LL(0x1f4ded5d,0x83d56ec3),LL(0xfa54b15b,0xcc6ef029),LL(0x6f0a12c6,0xae62cc51),LL(0xce830e11,0x964fd2d0),LL(0x88747fe9,0x56076a32),L_(0x00000067), + LL(0x8f89c374,0xb73d3d92),LL(0xc668cfa4,0xda69c4d9),LL(0x97ee2907,0xbf4c3402),LL(0xbf5fb743,0x4034c59c),LL(0xd60ae9cd,0x99bc4b73),LL(0xda82be72,0xda1f7664),LL(0xe3800a84,0xfb007b67),LL(0xb7700f12,0xb546161e),L_(0x00000082), LL(0xd0f66b94,0x4be150bb),LL(0xfc5d0def,0x660c9122),LL(0x1ba0f43d,0x3a5b4550),LL(0x7224e926,0x33c24e5b),LL(0xba92b4ef,0xd249e1b7),LL(0x2b1856c8,0xb2c9aa15),LL(0x5fe68108,0x6e540179),LL(0x2fe766ae,0xa379f58c),L_(0x00000103), + LL(0x32f3278c,0x4d5341f2),LL(0xdff5ad0b,0xbb141c66),LL(0x6270a82e,0x7912e413),LL(0xfc62897d,0x6b16ad87),LL(0x348f2e6b,0x0fe7c18f),LL(0xae57af6d,0x2f22a03b),LL(0x6d2d6ab0,0xefa7a28a),LL(0xd717c3e7,0x73423958),L_(0x000001c6), LL(0xe49ed5e2,0x0b4f0f2c),LL(0x8c6c9219,0xa884b55b),LL(0xaff1be7f,0xde74b331),LL(0x8882c375,0x7a676c7d),LL(0x57c355f3,0x71190b6b),LL(0x180dbbfa,0x599b9c95),LL(0xd7dc77b1,0x8f766481),LL(0x227eba11,0x840229ee),L_(0x000000aa), + LL(0xa6fa0735,0x5d79f380),LL(0xaa1f8835,0xe2b5d59c),LL(0xf1a96e2b,0x281ece14),LL(0x146a87f9,0xb65f19cf),LL(0x24f845c5,0x2f123e45),LL(0x9418bddf,0x90bcee98),LL(0xb6ea99d9,0x64b9ae2d),LL(0xd147e8b2,0xda89ba61),L_(0x0000018f), LL(0x36b11956,0x53c9380f),LL(0x31e35563,0x7d832bdb),LL(0x7117919e,0x5906fec2),LL(0xbdd97ce8,0x069087de),LL(0x015486f6,0x866bf3e5),LL(0x909fd1d8,0x1d61be88),LL(0x770d7f9e,0xa28b013b),LL(0xe7653682,0xddec12fa),L_(0x00000060), + LL(0x37b31659,0x38819383),LL(0x0ad9906f,0x9f83225e),LL(0x089577d6,0x8e97694b),LL(0x264428ce,0x0c33baa6),LL(0x1bf2f80c,0x0823ef0c),LL(0xbf31819a,0x2e4750ee),LL(0x66c7b596,0xd160d5df),LL(0x886455a6,0x575835ea),L_(0x00000070), LL(0x2fd22a9f,0x3c424c86),LL(0x240ffedb,0xd1be1d89),LL(0x3c874c88,0xed147fb3),LL(0xccd38c51,0xbbd7bef5),LL(0x10af1392,0x101c8dcb),LL(0xd85a000f,0x018793c4),LL(0x0b435263,0x24305a2a),LL(0x989d12cc,0x9c061ca0),L_(0x0000013e), + LL(0xef0eb1ed,0x9a069590),LL(0x8dfc3414,0x1912aeb6),LL(0x0b37df44,0x1e30b3df),LL(0xcbe1989a,0xaf9f97dc),LL(0x415de022,0x4e406185),LL(0x01cb0277,0x2eb58373),LL(0xbb545160,0x0ab0a19c),LL(0x1e53639f,0xeecdb49f),L_(0x00000169), LL(0xcd8e8ac0,0x2a5d2526),LL(0x8e8397e0,0xa679b16d),LL(0x44c0a296,0x7dcafbf3),LL(0xee3f4022,0x668a1c15),LL(0x2ca74425,0xea786663),LL(0x4906d981,0xda4fa2cc),LL(0x0bbbb1fb,0x21224a70),LL(0x8859a117,0x8ec6a6f4),L_(0x000001ec), + LL(0x3de6fe08,0xf1507b4b),LL(0x4574b533,0xb56c3906),LL(0x76eaa707,0xa9532376),LL(0x16e5e98a,0x611c9b67),LL(0x12d9a934,0x9eb6a261),LL(0x8430b478,0x3fab6e06),LL(0x50fd9610,0xd215cdde),LL(0x1d509b62,0xc4da786d),L_(0x000000b7), LL(0x6e4be0a7,0x752a0af8),LL(0x3ebf635e,0x680f5838),LL(0x9175f3f7,0x9f1a0d87),LL(0x861b999d,0x04cce1e2),LL(0x75ef231f,0xe86e6afd),LL(0xaf7240e6,0x04734476),LL(0xe887f56c,0x2837e095),LL(0xc194ba35,0x9e3dc524),L_(0x00000146), + LL(0xcb011cc2,0x9a9802d3),LL(0x4d7d0f39,0x0345d8d7),LL(0x5e5fc037,0x6923910c),LL(0x0187070a,0x5e15ce92),LL(0x3e13ac42,0x456e81c2),LL(0xcc3c7cbf,0xfc527716),LL(0xcd65b4f8,0x5fd7c9e9),LL(0x305c5c1a,0x4af9f3b6),L_(0x000000a4), LL(0x3a78773a,0x1b64c99c),LL(0xc01b599b,0x38f68420),LL(0x53fbc68b,0x1b40d8c5),LL(0x91c4f402,0xe87107e9),LL(0x0e78fd77,0x96fc64fc),LL(0xf13016cf,0x438fbd69),LL(0x59324677,0xa8e5ff95),LL(0x50792eee,0xb6a73a20),L_(0x0000015c), + LL(0xb5b9e0e4,0xb1979059),LL(0xaa4d1038,0xf13725c9),LL(0x5751fd0c,0x22f3e709),LL(0xe1b98f3c,0x131dbcec),LL(0x8e66976f,0x64116cc1),LL(0x2dc36526,0xf955db38),LL(0x6f94eedc,0x6bee8490),LL(0x2dc08c31,0x65ce87a2),L_(0x000000c0), LL(0x96bd706c,0xf8a59cff),LL(0x9035a740,0x328c1388),LL(0x61a4c1b8,0x1625b5b4),LL(0x8b1931b4,0xf35b9bbd),LL(0x075bce63,0xfb1707dd),LL(0x7a601744,0x232aecf6),LL(0x50241612,0xa974c9fd),LL(0xf1cae8d5,0x7f4ba9ea),L_(0x00000036), + LL(0xbe01288f,0xe7c06e65),LL(0xa5756aa5,0xd57f322c),LL(0xc48c9811,0xd934c78f),LL(0xf0128bf0,0x15f53184),LL(0xd880ad31,0xadaedd19),LL(0x967dfa08,0x374ad4e4),LL(0x94c0e608,0x389863cb),LL(0xcecf2255,0xe582d71f),L_(0x000000ed), LL(0x45e5581f,0x5b089de0),LL(0xef23aed0,0x89f1eb4b),LL(0xb93d3851,0x8967136f),LL(0x4daacc4f,0x2482bd87),LL(0xd7b99516,0x8a382f79),LL(0x404615c9,0x9daadb4f),LL(0x114144be,0xd38bfc82),LL(0x173ad4ab,0x7f91ad71),L_(0x00000042), + LL(0x4b16b686,0xa28a3c93),LL(0x299c2c3f,0xf2024c1b),LL(0x63be4df6,0xcbefbff9),LL(0x39510e86,0xe4d80ac6),LL(0xf1d2f2e9,0x8653ba64),LL(0x0165880a,0xd4fac73e),LL(0x73ce1252,0x67da578f),LL(0xeb225590,0xc1817050),L_(0x000001bb), LL(0x235f9feb,0xdc671b44),LL(0xa93c7bda,0x82c05dfc),LL(0xcb77f18a,0xaea605e9),LL(0x1df6368b,0x295e78ce),LL(0x67c3474a,0x93547410),LL(0x18ce6948,0x7dc8108a),LL(0x7c67eccb,0x8d3a8c61),LL(0x67a75d98,0xbd7b3b73),L_(0x0000002e), + LL(0x4238f2fc,0xaca4c347),LL(0x9fc92c8d,0x994543ca),LL(0xc6ad228f,0xb218a1c0),LL(0xc58614eb,0x527974b7),LL(0x6ca62054,0x85ffca1f),LL(0xc2129ab9,0xc6c14b3f),LL(0x019b6e5f,0x2ae678d2),LL(0x1e22f90d,0x5b3ee46c),L_(0x00000046), LL(0x8e533ac3,0xd3c4dd26),LL(0x4e855850,0x74af7741),LL(0xf226ab4a,0xe0d7e588),LL(0x332581f0,0xe826c3d6),LL(0x4284a728,0xcdf777fd),LL(0x6bfcaba8,0x5a83f0b7),LL(0x6ddf35c7,0x2fbd194d),LL(0x212fa0d3,0x072b793f),L_(0x00000049), + LL(0x0ef3997d,0x9d02c3bc),LL(0xb7ec87d2,0xe0887e3d),LL(0xb3caff01,0x4d1f3674),LL(0x567cdbdc,0x39e61184),LL(0x3d19e2c3,0xbe0de4f9),LL(0x0c3139a2,0x500e0978),LL(0x7ba6031f,0x6f3470b9),LL(0xf8e9a69a,0x65297bad),L_(0x00000159), LL(0xb53b49bc,0xc7bd9625),LL(0x69eb8288,0xe4ec65aa),LL(0x281d3a84,0x2c8f25ab),LL(0x27426301,0x97e61a91),LL(0x3672bc0b,0x95476b11),LL(0xbfd7d2dd,0xbff37ddc),LL(0x918c4eae,0x82eea309),LL(0xbd19084d,0x26d27fb7),L_(0x000000af), + LL(0x97ab40fc,0xe6cbd721),LL(0x4a4ba674,0xc27ec19d),LL(0xf1234a47,0x16a6532d),LL(0x3cf8bf88,0xe2dbe535),LL(0xbc4dc6be,0x948616ba),LL(0x46216f90,0x76d1a242),LL(0x02af6244,0xd5de4770),LL(0xd85e1029,0x7fda32cb),L_(0x000001f1), LL(0xa684ba28,0x34f944fd),LL(0x944544cd,0x0193b124),LL(0x72b4685a,0xe7601697),LL(0x6ec14591,0x9572360e),LL(0x2184e096,0xffc7295c),LL(0x9127a0f3,0x844306ef),LL(0x818c91ad,0xf603be79),LL(0x81b486bc,0xc1bd26da),L_(0x0000014f), + LL(0x4a982652,0x3c726e7d),LL(0x7d1e874b,0xa513da39),LL(0x8c78c755,0x92677915),LL(0xe62fef13,0xe9e24f3a),LL(0x3d1cf9e1,0xd96cf621),LL(0xf503d4fc,0x0e1204b1),LL(0xf07e39bb,0x71958180),LL(0x7a406c60,0x3b7b9a61),L_(0x0000006d), LL(0x35ac9c86,0xcdb43a8c),LL(0xf37f3857,0xed377a92),LL(0x8ae49b6b,0x0827d789),LL(0xbd50e338,0xdeff6865),LL(0xfdb287e2,0xe758e466),LL(0xa0c560a0,0x54321f3b),LL(0xb418a264,0xd44767fd),LL(0xfaaa26f5,0xcc7b7f8b),L_(0x00000136), +}, +/* digit=14 base_pwr=2^70 */ +{ + LL(0xf16a4fbf,0x580dde02),LL(0x814d149b,0xeaa3b1ca),LL(0x3cc8c599,0x43a45440),LL(0xc98d833d,0xdba29de3),LL(0x6e31f2af,0xab2ff205),LL(0xf81e95cb,0xb530ab3b),LL(0x49419f19,0x8a6e1bb6),LL(0xd0585b64,0x1dfbba1e),L_(0x000001f1), LL(0x6bc60cfa,0x2b473469),LL(0xc0250d4a,0xb9f4e199),LL(0xd4759758,0x326d4e2a),LL(0xc32f68bc,0xa78113ab),LL(0x840b01ce,0xcd248f92),LL(0xbd87644a,0xa8d8d61e),LL(0xe9a32d38,0x58a69c2a),LL(0x6a0c706b,0xf4b942e1),L_(0x00000161), + LL(0xb0a85bf9,0x538c7fcc),LL(0xff198eec,0x4ec043bd),LL(0x29ee8af8,0x125b846f),LL(0xd01572ea,0x280cfc9e),LL(0x4ba80325,0x3f73f265),LL(0x57e3b7be,0x6bcaffbf),LL(0xf83701a2,0x1a2d3724),LL(0x19d20a25,0x410f80b3),L_(0x000001ec), LL(0xdc0e5194,0x3b961197),LL(0xc136f93b,0xc26463d8),LL(0x000ba8d6,0x8d99824e),LL(0x0e084f84,0xcfbb42b2),LL(0x81fef33f,0x138715f7),LL(0x48ed1078,0xca7dbdd0),LL(0x42869724,0x3c66b900),LL(0xcfde2c20,0x89fab2c4),L_(0x00000104), + LL(0xf7cac6a0,0xaf4c0100),LL(0xca7c1c9b,0xd05a1cfa),LL(0x096b7d5f,0x5e939f07),LL(0xc34c35b1,0x11a408f8),LL(0xef94d03f,0x9c1a3053),LL(0xa610576b,0x89fbfdb7),LL(0xce4bec40,0xabf93595),LL(0x66023f5e,0xc5d43f87),L_(0x000000aa), LL(0x2f2e5545,0xa58413e1),LL(0xcbfb3671,0x1874038a),LL(0xd3ca207c,0xb2e8a04a),LL(0xccca2442,0x3073c925),LL(0x3c9baa99,0x554b9664),LL(0x6d9e1787,0x70e99ee9),LL(0x874df9a7,0x312bf341),LL(0x1b8e89dd,0xfdf17994),L_(0x000001a7), + LL(0x7aa46ca1,0x5838bb0c),LL(0xad2e37a1,0x5a28cd2c),LL(0x54d33ad6,0xd4f1caa9),LL(0x44b04b20,0x80e4c9d2),LL(0x8c65ceb1,0x370a13f5),LL(0xecff016c,0xee758816),LL(0x6ad260ae,0x95c36fe1),LL(0xbbdbb7b5,0x4d06dfe8),L_(0x00000094), LL(0x78399219,0xf5c325d6),LL(0x955c2a22,0x79a376a5),LL(0x16640925,0xf8e9390b),LL(0x36b3aac4,0x2a8dbf22),LL(0x034f2b72,0x77b02d94),LL(0xd5de86b9,0x729cfcd8),LL(0xa8bc9f80,0xbe296bcf),LL(0x1dbcbc03,0xec1469f1),L_(0x00000164), + LL(0x6a57e8a6,0x4141a618),LL(0xa7081b57,0x51abc1ef),LL(0x738c30ac,0xb0cb69e4),LL(0x731cd9ef,0x9b0b0c3b),LL(0xf0dc5cc9,0x40e54a92),LL(0xfba2bbb5,0x0dee7871),LL(0x5ee7b5d3,0x540e5eaf),LL(0xad1a2eba,0x7c44af5d),L_(0x000001da), LL(0x235257d1,0x451af808),LL(0x1bf41212,0xacac98b3),LL(0xd6076452,0xed40fc8f),LL(0x868d93c4,0xb7246c52),LL(0xab7c14c6,0x36bab138),LL(0x789fa296,0x330e1a06),LL(0x88e8110a,0x5dbf4ce1),LL(0xff782421,0x9cabebe8),L_(0x0000018f), + LL(0x3aa4041a,0xbf3ef154),LL(0x0cb92f46,0x47026a02),LL(0xe21fd797,0x1dec53c2),LL(0x0b5a2b41,0xcfbf686e),LL(0xdb7c6dc9,0xd6d5c0b4),LL(0xb4a8866b,0xf8283374),LL(0x14d9e7f9,0x4dd48282),LL(0xffba2822,0xf9de17db),L_(0x00000094), LL(0x19ce594f,0x1814c604),LL(0xbe3bf885,0x12bae7dc),LL(0xdf04c3eb,0xe8ee1061),LL(0xc658c3bb,0x8d34f043),LL(0x47642843,0x2916bbb3),LL(0xedee7c23,0x70f93acd),LL(0xc93b4f5c,0x187bf7ea),LL(0x75348b4d,0xffda6e9d),L_(0x000000eb), + LL(0x9c49db1a,0xc855134e),LL(0xdd4ae89b,0x30b7a1ad),LL(0xd9dc0b8c,0xbee0416e),LL(0x67e1dcbc,0x66147ae2),LL(0x7907e5e7,0xb9dea373),LL(0x537d932f,0xf4450461),LL(0x8d5aa671,0x7b0644e6),LL(0x33269776,0x835848af),L_(0x00000089), LL(0xfbbaf49b,0xfdca2fb9),LL(0x400c0893,0xe36e56e3),LL(0x095f6119,0xaaeab6ef),LL(0x07fda371,0xfdbbf61e),LL(0x51034096,0x65d823d3),LL(0xc5284f49,0xcec7f701),LL(0x00cca32d,0x443cce6e),LL(0x13b673ca,0x7c7c1332),L_(0x00000150), + LL(0xaa83f580,0x5f48e2fc),LL(0xfafcc610,0x2c5d9495),LL(0xd34073fc,0x321d1a08),LL(0x30442510,0x3427742e),LL(0x8068ffd8,0x2ec5f97b),LL(0xa7faa8a5,0xac14530d),LL(0x5d010e52,0xf277a140),LL(0x3edf5701,0xcdd53228),L_(0x000000ea), LL(0xb172daf2,0xf8f566cb),LL(0x51771845,0xa7b0e50c),LL(0x66aafeee,0x81cf4ee6),LL(0x8fd52580,0x1bc2c6ec),LL(0x232a19c7,0x6790d250),LL(0xd4c06ab2,0xdc4411be),LL(0xacd06e0b,0xe0fd2a20),LL(0x19734273,0xc9fb738a),L_(0x000001c1), + LL(0x4d908e20,0x2c36a49c),LL(0x346bc599,0xb17c0c24),LL(0x4349ec6d,0x1994a52e),LL(0xc574a60f,0x479b18ee),LL(0x2cf1156f,0x00b04364),LL(0x587d6a8b,0xe20999e4),LL(0xb840bbc5,0xdfbaad24),LL(0x1056fcbe,0xb84e8539),L_(0x00000015), LL(0x182e14f7,0x34b3807b),LL(0xc83300dc,0xcbae472d),LL(0xff64a1e1,0x60ef1e86),LL(0x1368c7ee,0xfa9cecf9),LL(0x1a548595,0x12c62bf5),LL(0xbab6253e,0xc9541d0a),LL(0x2d9ef7be,0x1e1f27f7),LL(0x956cff19,0xba2813eb),L_(0x000000af), + LL(0x7ab859d4,0xdb558004),LL(0xce8d95f8,0x9dc5e59e),LL(0xf1893cb5,0xa7cb9fd4),LL(0x77041349,0x53461897),LL(0xb8f3b00e,0x4b8c1719),LL(0x3acc8d5e,0xe436769f),LL(0x2b51a3ea,0x15adc570),LL(0x5fa4c1f5,0x93a4046f),L_(0x00000081), LL(0x605a315b,0xc6ca2c5f),LL(0x8e92a20f,0xe70ae728),LL(0x9e74b9b9,0x6d7cbd1a),LL(0x8837144f,0x797825f3),LL(0xa10a4e2b,0xd3f2260a),LL(0xbce98f37,0x3d85debd),LL(0x39cb6f79,0xa763a30e),LL(0xb1f85a09,0x15a4a3f3),L_(0x000001b8), + LL(0xb955d85a,0x4df25f56),LL(0xf82561fb,0x9e75f649),LL(0x8c808470,0xd7751a0f),LL(0x0c1dcee3,0x4322644e),LL(0xf53e90ce,0xd68db21e),LL(0x8f8d9278,0x72d07c10),LL(0x94db3061,0x821b176c),LL(0x2c56677c,0x51fa088e),L_(0x000001b6), LL(0xa05bed3e,0xbd496ef4),LL(0x2f3203c7,0x702f0af9),LL(0xf4ee87af,0xdeead7f4),LL(0x1e240ba2,0x6ba4a666),LL(0x45c6b9bc,0x5b558a22),LL(0x69826d07,0x82f16b78),LL(0x1d474e7f,0x1b099f67),LL(0x6f9ab8f0,0x79936b07),L_(0x000000d3), + LL(0xab96e691,0xdcb6ef22),LL(0x8cd18dc5,0x4111e26b),LL(0x563a07bc,0x3482455e),LL(0x0e2f7391,0xcb5ec4ad),LL(0x21483bed,0xc0caacaf),LL(0xa5a48441,0xc9e80f16),LL(0xbffbf280,0x90242b85),LL(0x91f37a76,0xd9544186),L_(0x000000ee), LL(0x1428479a,0xa766d6e3),LL(0xfc4b8794,0x38293f47),LL(0xa81360ec,0x31e9f867),LL(0xbe34d77d,0xdb92af31),LL(0x882df842,0xcd799976),LL(0xd34a906c,0xabb505dd),LL(0x961ddfb3,0xa3a37b0b),LL(0x4fbbb326,0xf7af85a7),L_(0x000001d4), + LL(0x1e66664b,0xbb0940d9),LL(0x3d70435a,0xff491b63),LL(0x1eb2a685,0x22d3c808),LL(0xa380de6e,0x17e44c8f),LL(0xd9df636d,0x2a35379f),LL(0xa903bf9f,0x0f809249),LL(0x387b8a0a,0xabe12175),LL(0x44dbe0cd,0xfd759d00),L_(0x00000123), LL(0x80918078,0x98196ddd),LL(0x019c1122,0x84c5a37e),LL(0x254adbe9,0x3981a4ac),LL(0xbfc928a2,0x62436eb9),LL(0x7ad29c64,0xc99f2914),LL(0x2cc9ceca,0x2f0c2529),LL(0x2d8109c3,0xbda5dcc9),LL(0xe65ae3c9,0x27c8461f),L_(0x0000014c), + LL(0xd774b2bc,0x7f2f4a50),LL(0xdb205fa6,0x977d6dff),LL(0xb6a346a4,0x39b1aa2b),LL(0xc02f5c26,0x6d520bed),LL(0x7e9b3df6,0x9fe2d1ad),LL(0x8060eb41,0xffe8b3d8),LL(0x8de43158,0x6b78c0bc),LL(0xe900b6ef,0xba5607f9),L_(0x00000027), LL(0x1979ffd7,0x656a0930),LL(0xe37eeb37,0xf82e5547),LL(0x817b9a2b,0xebe57826),LL(0x966c6b06,0xd17239c5),LL(0x0d566764,0xb6e7e211),LL(0xb736c18d,0x67f60fe4),LL(0x7f6de467,0x91c330d3),LL(0xdf003076,0x6fe1ff1d),L_(0x00000038), + LL(0xd1c84dca,0xa38e4c83),LL(0xee75b3b5,0x42633219),LL(0x96b76b44,0xa702e22d),LL(0xce624bec,0x45df636e),LL(0x087dc34c,0x00b8ab39),LL(0x7c3b41a0,0xa4c92149),LL(0xbe1f412c,0xc186c0a7),LL(0xa0e6b72f,0x6f9b9c73),L_(0x0000015c), LL(0x5b6e29ff,0x6d958194),LL(0xfceeca76,0xc25f90a1),LL(0xd246f978,0xf7a79529),LL(0x5bdce3f4,0x202fdba0),LL(0x4516ada4,0x9ccb5769),LL(0x22fea769,0x35cd1aca),LL(0x9d5e791d,0x72d93ad7),LL(0x89481217,0xd00224e0),L_(0x000001d6), + LL(0x4b1bfc3c,0x0b6d183b),LL(0xcdd1f50d,0x88770143),LL(0x721cf9d0,0xd247118a),LL(0x5a8338fa,0xfa498ee5),LL(0x33ff454e,0xa8d98087),LL(0x2107a954,0x4eaefaa7),LL(0x39298606,0xc385af5a),LL(0x3e0c503b,0xfc7e0cec),L_(0x0000015c), LL(0x3ea50970,0xa2f6c113),LL(0xbf161ebf,0x48b5f685),LL(0xbb087e9c,0x58eb481e),LL(0x3b7987c9,0xa465a54c),LL(0x6e92e01e,0xa8194344),LL(0x1e66d88b,0xb0c7a894),LL(0x40dc6c71,0x690cafad),LL(0x057f59a3,0xf02679ac),L_(0x00000130), +}, +/* digit=15 base_pwr=2^75 */ +{ + LL(0x9682d5c5,0x3a007995),LL(0x19e3233b,0xcd545767),LL(0xc78c2194,0xc744ff86),LL(0x789e51d3,0xafacd6dd),LL(0x7a5cd253,0x398cb1ba),LL(0x18b56085,0x273c4fb9),LL(0xff1bce38,0x0ba240c9),LL(0xbca7efa9,0x3bb2e372),L_(0x000001a7), LL(0x353d398f,0x563a114b),LL(0xf4adbd1d,0x90284d2d),LL(0xe9ad940e,0xe3af63ef),LL(0x61ffca7f,0x96feaa4e),LL(0xba0669de,0xdbf94ff4),LL(0xd7b8471a,0x696c5279),LL(0x1dda976e,0x0a229117),LL(0x1566b880,0xba44b588),L_(0x0000015f), + LL(0x317311c8,0x29b896b5),LL(0x025efc3b,0x60e34ccb),LL(0xbcd9f85c,0xae29c1d9),LL(0x1e85f821,0x3dcc6356),LL(0x27219e29,0x3f95824c),LL(0x9e01039f,0xd3a9843c),LL(0x8ef0f79f,0xbba44b84),LL(0x9cddb5a3,0xf0a7f537),L_(0x00000011), LL(0x97dedd3c,0xd40be315),LL(0x0d73669d,0x0706daaa),LL(0x90c605d6,0x262a826a),LL(0x2e67d62f,0x90997b0e),LL(0x5ac29c5e,0xa4dc7322),LL(0x9728fe4c,0x46c28be3),LL(0x8656b7a7,0xcf46a3d3),LL(0x318bd5a3,0x0c58ac70),L_(0x0000000a), + LL(0xc8e39791,0xd012d32d),LL(0xb1701460,0x36257f7f),LL(0x712c0989,0xbc1511ff),LL(0x948635e7,0x929c254b),LL(0x950b6b9e,0x88fae008),LL(0xc1ebc649,0xb35e21c2),LL(0x69de590b,0x0c8fd948),LL(0xc534704d,0x03df94d1),L_(0x0000009f), LL(0x7d20c84c,0x417e1367),LL(0xbe538962,0xbaa7a81a),LL(0x6d9ba3b4,0x085df8a2),LL(0x72446606,0xc1a4f077),LL(0x313aa0fe,0x443486a7),LL(0x310facd1,0x4bb29bc8),LL(0xe7424659,0x70dbb24c),LL(0x7a208944,0x2ddd11bb),L_(0x0000016b), + LL(0xe96cd1b5,0x5370e2b4),LL(0xa39d68ac,0x0b26e23e),LL(0xf98a9904,0xbe557ba1),LL(0xcef362a9,0x202765cc),LL(0xa7731e3c,0xa726d7b5),LL(0xcd815e2b,0x1c25faf8),LL(0xa6579cd9,0xdafb2e8b),LL(0xc5ec8fb3,0x648049fa),L_(0x000000f4), LL(0x452046ec,0xa04b6251),LL(0x96110b89,0xd1ddccb2),LL(0x551f88c9,0x0f26d015),LL(0x9b8bbb0b,0xb5bd39d3),LL(0x9d52ffc2,0x2dc18ef7),LL(0xab6d006e,0x142fb527),LL(0x804f61d0,0x391511fa),LL(0x9dbe5992,0xa3e717ea),L_(0x00000015), + LL(0xc1cd48d7,0x9289c640),LL(0x6b7a800c,0xc76b2795),LL(0x581d42f0,0x8ca1e81a),LL(0x4472a2fa,0xbf4b6019),LL(0x6715dfdd,0xb304a936),LL(0xf9366e36,0x391be48c),LL(0x81f74b90,0x6151e36b),LL(0xd32b6b20,0xc48b79a5),L_(0x000000a9), LL(0x366ec558,0x831e89ed),LL(0xfa6f04fa,0x5ebcfa5b),LL(0xec4ecc3d,0x6b2117a0),LL(0x7b376a81,0x90bf1080),LL(0xba3f0166,0x0993a607),LL(0xaf14e2f1,0x8cf72c90),LL(0xef21c633,0xd173a6d3),LL(0x187451c2,0x13ec5f08),L_(0x00000011), + LL(0xc5533330,0x0f29eadd),LL(0x246b16c2,0x9b833212),LL(0x9da31a63,0x297cf150),LL(0x4995a63d,0x90a2a3a8),LL(0x26054531,0x22ca8af6),LL(0x0cdf918d,0x62531849),LL(0xa5ed4b64,0x7ca9de65),LL(0xfa4fec38,0x72b35acf),L_(0x0000010b), LL(0x23d78ecb,0xf96d539b),LL(0x221e3646,0x256f3a4b),LL(0xb6bf83af,0xc408a90f),LL(0x7abd62f0,0xaefff14a),LL(0x4069cdfd,0xae41ce0c),LL(0x29824953,0xb47d1cba),LL(0xa382ab7e,0x9eb440b7),LL(0x957f6459,0x4c148b60),L_(0x0000014a), + LL(0x6b05018a,0x1086c5f8),LL(0x26130fe0,0x7b4b2e70),LL(0x68d46ff5,0x0c407c0a),LL(0x3b8c39a0,0x88577dcf),LL(0x6dc35106,0x5dafbff6),LL(0x66c847b2,0x2d675f1f),LL(0x17ebe229,0x834c9c2b),LL(0x7dd924e2,0xd5b6edf6),L_(0x0000008b), LL(0x62687b75,0xf96321d7),LL(0x6f67acfa,0x9437a2b2),LL(0xf66029f2,0xe7b46c71),LL(0x329167d4,0xb24e796b),LL(0xcf0f34c3,0x9d6e95b5),LL(0x4f9e7abb,0xcb817cb5),LL(0xb5258968,0xe5382677),LL(0xb89d3951,0xb2e2fb7f),L_(0x00000008), + LL(0x85caa712,0xe65a160c),LL(0x79edff6b,0x1ae3af0e),LL(0x7704970c,0x8b957c42),LL(0xb8aa395f,0x5f0f181e),LL(0xbdf3d6c8,0xe7d8f529),LL(0x4e626c58,0xd83fd353),LL(0x770dabfa,0xe5ada98c),LL(0xac3e65d7,0x6430730b),L_(0x00000167), LL(0x73fcec9a,0x09d0476d),LL(0x4dcf97c3,0xab9b5d71),LL(0xa56a3252,0x9648c08c),LL(0xff297fc7,0x897ba609),LL(0xff84306b,0x4c446a06),LL(0xddb64374,0xbc202d01),LL(0x97ee1218,0xf9b0f80f),LL(0xf048db33,0xb5f54bb8),L_(0x000001e8), + LL(0xcc962077,0xa010dba8),LL(0xa2fb38a6,0x31feab78),LL(0x36899fbf,0xacceb7c2),LL(0x5bdd898c,0x14de8e04),LL(0xe42d5076,0x459ea861),LL(0xe51c21c6,0xfbda1b0c),LL(0xdc95445c,0xa7d4e38e),LL(0x7947f71f,0xadcd66a5),L_(0x00000160), LL(0xcc6a9c26,0xdcdf5f99),LL(0xf1467b2f,0x2de2bfcc),LL(0x9c1ae772,0xd43f04fe),LL(0x41471183,0x043333f6),LL(0xc9a3cf00,0xf1a6e8cb),LL(0x7cc8a0c7,0xa8c3f924),LL(0x74a1cf04,0x828052df),LL(0x8be5596b,0x50a45820),L_(0x0000000f), + LL(0xfbb80d1a,0xe9851bfc),LL(0x51c40077,0xbfe0982b),LL(0x87cd565d,0xd372a1cb),LL(0xccd954bd,0xbbff7b4d),LL(0x294b36f6,0x8237c51d),LL(0x4ce0f879,0x261403d6),LL(0x569d6e3c,0xb79e0e60),LL(0xeba6224f,0xc33dd3b5),L_(0x000000d7), LL(0x5a9cfa17,0xaaf054ad),LL(0x5f93dace,0x160bbbee),LL(0x8aa260aa,0xa9f4b722),LL(0xb1b5025d,0x817d1e67),LL(0x81308a04,0xfe002797),LL(0x4afd2f00,0x680cc208),LL(0x154f68e6,0xd4b7eccc),LL(0x4cc6b0f1,0xb8976118),L_(0x000001e2), + LL(0xc8be5e5b,0x7283e8a9),LL(0x8ab94a45,0x0bb733f0),LL(0x642a6645,0x41a534e8),LL(0x57ae42c1,0xd4abc981),LL(0x8be6ea3e,0x7e62f50a),LL(0xb3f01b7e,0x98a38cc8),LL(0x8865f98b,0x7862605c),LL(0xf1a738cf,0xde02b3ce),L_(0x0000000e), LL(0xbe15c345,0xbb74e488),LL(0xc6aa6ad4,0xf6d314f3),LL(0x1691860c,0x97214287),LL(0x625fd28f,0xab878ce4),LL(0xd6ea61fb,0x8ebed709),LL(0x5a22486f,0x6db8fc6f),LL(0x0b71449e,0x46c06119),LL(0x0e8cd622,0xe44026c8),L_(0x000001c7), + LL(0x2b9ea684,0xab7fbeff),LL(0x954c6cef,0x7291b35c),LL(0x062277d6,0x7553137c),LL(0xaf482063,0xb75730d8),LL(0x710c68e8,0xb68d2250),LL(0xbae3e7c1,0xff637a2f),LL(0x6b643e1a,0x1ef002bf),LL(0xdcdc4699,0x38ab4582),L_(0x0000016e), LL(0x0f3758df,0x92bea0d8),LL(0x899ee626,0x4d7631d6),LL(0xcdd2a79a,0x2ee3aea9),LL(0x8162f50f,0x1476eea0),LL(0xc4d433fb,0x27c81475),LL(0xe8214237,0xdc969d9f),LL(0x56c76934,0x6d918c87),LL(0x7533eb08,0x56d2a891),L_(0x00000030), + LL(0xadf83954,0x1b47da4b),LL(0x8a8331e9,0x49ed1362),LL(0x59fa2b27,0x418a7189),LL(0xe8454c56,0xf46859d8),LL(0xb777077d,0xdf895326),LL(0xa1ecfc76,0x7c0bff3a),LL(0xa0d40120,0x4dc72f6f),LL(0x863ee5b0,0x6d7d35d2),L_(0x000001db), LL(0xbc4e28c1,0x51536aa9),LL(0x797cc189,0x992a786b),LL(0x424d6c36,0x0bb1db2f),LL(0x7b4a72f0,0x99596f48),LL(0xd38d470a,0x7d9d8119),LL(0xed3220cb,0x7fe52443),LL(0xd0f7efd8,0xf334c76a),LL(0x5b52a8c0,0x289cf254),L_(0x00000182), + LL(0x496fb553,0x50ef0de9),LL(0x06fa762c,0xf226f768),LL(0x770bcaf6,0x47cff6b0),LL(0xec1a0d3e,0xb780ef8c),LL(0x49872a4e,0x434df874),LL(0x82a505c8,0xfc298963),LL(0x6b56a94d,0xc037f2d4),LL(0x1721c7a5,0xef98ff94),L_(0x00000059), LL(0x5289072e,0xce001c93),LL(0x229e4010,0xb7710f4a),LL(0xb1be023a,0x4f780b68),LL(0x37373fb4,0x44ddc611),LL(0xb6129029,0xeba09ab8),LL(0x3d4bb157,0x52d1be00),LL(0x7557730f,0x5d184bff),LL(0x79506c27,0xabea8b49),L_(0x00000057), + LL(0x59ac2268,0x475e54a3),LL(0xe76ea216,0x641b111e),LL(0xe7b2f367,0x11e8b8cf),LL(0xaa1845af,0x3e44ec0e),LL(0x634d35d6,0xd9e05b86),LL(0x9fef6a5e,0xa66acc79),LL(0x6151a902,0xc7fadad6),LL(0x95ee0cab,0x4f71151e),L_(0x000000c7), LL(0xa387fffe,0xc47ffd5b),LL(0xd5a7577a,0xa66a5bd1),LL(0x1bbdd68c,0x1a4070bb),LL(0xafa4a6f8,0xb0f9b28c),LL(0x67075086,0x966afc2e),LL(0x63512dbd,0xed5912ae),LL(0x8f26597d,0xd092a281),LL(0xa415f451,0xc2ef31e4),L_(0x0000003e), + LL(0xfadaa485,0x4e004498),LL(0xbea3c389,0xaa39f9d0),LL(0xa8f46458,0x0b3654a0),LL(0xf830008b,0x4cd7392b),LL(0xa46a22ca,0xb12eb97a),LL(0x80e1d7af,0xd888b9cb),LL(0xf74c8adc,0xbb6e179c),LL(0x73b51d04,0x968eb224),L_(0x00000150), LL(0xd8317561,0x51f96d03),LL(0x9de9e100,0xfade3749),LL(0xecddcd4f,0xfc72771e),LL(0x7aa9dbdf,0x5e1bb964),LL(0xdc24156b,0xbaddb508),LL(0x0de78eea,0x6facddf4),LL(0xb1c48894,0x4a964d6a),LL(0x49c82382,0x6f258c87),L_(0x000001b1), +}, +/* digit=16 base_pwr=2^80 */ +{ + LL(0x53fa611d,0x32cc508d),LL(0xcd408945,0x60b1057f),LL(0xf3eb54e9,0x77d231ff),LL(0xbd6ea408,0xe5110313),LL(0xb9ee8343,0x85209f6e),LL(0x64924e77,0xe7fa5897),LL(0x32e258b2,0x618a6eb3),LL(0x11e2e038,0x96067c35),L_(0x000000af), LL(0x15c8ff41,0x0f221560),LL(0xef974e44,0xa1b7a3a0),LL(0x8ea1f931,0x72932b48),LL(0x720e4174,0xbb75d745),LL(0x1bf9c803,0x996758e5),LL(0x7f0b3909,0x8d83f97c),LL(0x39d56a48,0x1fac932b),LL(0x55fe1ded,0xaaf43ccf),L_(0x00000199), + LL(0x4f73774f,0x6ffb7834),LL(0xad3e7387,0xd3158a49),LL(0x8771e37a,0xb98ec469),LL(0x6f103f2c,0x1bd53110),LL(0xf8325af3,0xa434959f),LL(0xe47f875b,0xa10264ee),LL(0xcf224bc0,0x9ccf2f61),LL(0x337d33a1,0x86ce6031),L_(0x00000121), LL(0x28697730,0x6706e91f),LL(0x9179c5ea,0x79ba3023),LL(0x9aa4ed38,0x7e239f26),LL(0xaa83eb97,0xef091443),LL(0x82853a90,0x336fc4d2),LL(0x2b260d34,0x56b3a0bb),LL(0x119fbd07,0xe0f16198),LL(0x3453a3a6,0xa2af0802),L_(0x00000016), + LL(0xd1fcc92a,0x8000185b),LL(0x02ebe1f2,0x3ebcda00),LL(0x30d3e5f2,0x75cccaba),LL(0x8ea9d40f,0x108edd48),LL(0x152a6563,0x6028024e),LL(0x732e422c,0x17618296),LL(0x142e6cc1,0x9dea7266),LL(0x5d4e4488,0xb05325e9),L_(0x000000d1), LL(0x40638703,0xf3270a2e),LL(0xc29b5dca,0xbad984d9),LL(0xd2f759d7,0xad7bc046),LL(0x347ff7c2,0xa4e4f59d),LL(0xc16d4c0f,0x0a06be29),LL(0x872d14ff,0x2390bb31),LL(0xb7a5b6ec,0x66be2ce2),LL(0x408ae4cc,0x6b9b1fe0),L_(0x00000100), + LL(0x2cfafd04,0x9cc4cee5),LL(0xa99628d5,0x4764e916),LL(0x4417813a,0x9a05da16),LL(0xe423f0c4,0x2babb644),LL(0x24dca899,0xd179a66e),LL(0x894f6883,0xc157cbef),LL(0xed7756c7,0x44c30131),LL(0xcdff08e1,0x78b0a3e9),L_(0x000000ac), LL(0x3963ba6c,0x43dabd75),LL(0xbe7ba3ec,0x93626426),LL(0xd17b8f8b,0xbfcd2a78),LL(0x486d7ac0,0xaeda53c9),LL(0xfc3c49c2,0xbc99eeae),LL(0x49fb4a9c,0x12ab3d09),LL(0xdb075628,0xc0f863b5),LL(0x3d5da4c6,0x8ec31fe4),L_(0x000001e0), + LL(0xf45825d6,0x098d00b0),LL(0x4acb7a91,0xf4f8175f),LL(0xfe317cf8,0xf8155d16),LL(0x2bc9a77c,0xac3ddeef),LL(0x17520bd7,0x0aeae3c4),LL(0x44ee6fbc,0x1aaae6ff),LL(0xd8c23852,0xf47bc828),LL(0x553f42c9,0xc09b26d0),L_(0x0000012f), LL(0x6897ed6a,0x9a32ac7c),LL(0xc1e669bb,0xc8aca498),LL(0x697322f4,0x43042d46),LL(0x334625a5,0xdf16aa69),LL(0x67bda03c,0xab4b67c2),LL(0x205d341f,0x83a55d6f),LL(0x05daa2bd,0xcdfd94e0),LL(0x9ac9573f,0x1cb76afe),L_(0x000000e8), + LL(0xe51930fc,0xf074fced),LL(0x97863b91,0xc43281c9),LL(0x92d449a3,0x7a68c2d7),LL(0x063c9119,0x3b2de0b3),LL(0x55e1666a,0xf3e7d825),LL(0xf70b4227,0x6aacf427),LL(0x6c04e18d,0xc2b9b616),LL(0xaa4c82c2,0x376fa210),L_(0x0000015a), LL(0x3a29f55c,0x27de0f4a),LL(0x63844f17,0x70941232),LL(0xfd0bec77,0x3b5f4e85),LL(0x68fe79f4,0x5cbc9a57),LL(0x826a7303,0x65bb2328),LL(0xda7d2209,0x40788a77),LL(0x6978fe42,0x14c7cf99),LL(0xc2ae1a05,0x77943ce3),L_(0x0000005e), + LL(0x94afc854,0xdb0d1b45),LL(0x25e9937f,0x14c566a9),LL(0xd1cf3988,0xcd250848),LL(0xcc300694,0xbfd82b6c),LL(0x135bc75f,0xa47db4ae),LL(0x8639e63f,0x2295c1f1),LL(0x30a5e5b3,0x61f91b27),LL(0x2841bb1c,0x1335383b),L_(0x00000145), LL(0xf2dca32f,0xe1df27e3),LL(0x0fb695c7,0x721a9ee4),LL(0xc8c313d1,0x267e9801),LL(0xb288bc93,0x9aafbe12),LL(0x80d7a36a,0x5e34c2b1),LL(0x5e8b79ae,0x22efe6b6),LL(0x7da7f03b,0x552e9134),LL(0xee94e563,0xab16538c),L_(0x0000014a), + LL(0x9e50fadd,0x336db42e),LL(0x49f7546b,0xf6900421),LL(0x57093c06,0x8e00d7d3),LL(0x8d2dbce8,0xd9ede742),LL(0xd004dc4a,0x01940521),LL(0x0d3be2ce,0xdc4ae497),LL(0x1bb5cf60,0x0a6ccb03),LL(0x803df567,0xdf04605d),L_(0x00000164), LL(0xc7d8a77c,0xa05f0fb0),LL(0x1f8ad28a,0x39d0a695),LL(0xe5b908dd,0xd67e92ff),LL(0x4165f76f,0xf281077f),LL(0xc8d52980,0xc9ee2db2),LL(0x9ff0b841,0xe792e9a0),LL(0x9a5850f2,0xd74d1fff),LL(0xdbe9887c,0x468c4978),L_(0x000001aa), + LL(0x1bc8e2f6,0x17cfe85b),LL(0x645a5369,0x96452c88),LL(0xfe80ed90,0xd777343c),LL(0x53d07352,0x57827fb3),LL(0xa6c3e43b,0x80b39b9b),LL(0x2a8365b0,0xaf5a3de0),LL(0xac5e9239,0x181d4337),LL(0xea4d87d6,0x51fe7247),L_(0x000000e4), LL(0xfcc2be5a,0x0dfb5a0c),LL(0x7a7e75fb,0x15428231),LL(0x5c94ba5c,0xdf444166),LL(0xc521d0ff,0x0f639c5d),LL(0x74de2e37,0xdc1e397f),LL(0xc9356e9e,0x93e3e959),LL(0x0c9e3464,0x39201886),LL(0x6a78ad71,0x2c0f3246),L_(0x00000013), + LL(0x41b934a0,0x9207f1ee),LL(0xc358b92f,0xcc5ec219),LL(0x085c3194,0x8df4ef1a),LL(0x71e157f1,0xb527e0ab),LL(0xdd0a2a0d,0xae481b48),LL(0x0e0efe51,0x27b717b7),LL(0x5828b573,0xc2a98225),LL(0x3d2c0ff1,0x099e23ff),L_(0x0000017e), LL(0x7c722916,0xf9a97523),LL(0x11db2059,0x5fbc6f68),LL(0x162229b6,0x08c87928),LL(0xc7000da2,0xa03b55dc),LL(0x3f37b2b0,0x03e27759),LL(0x2abf57b8,0x6d3e3a66),LL(0x3d925762,0xa5335174),LL(0xec43569d,0xb9e4cda0),L_(0x000000a8), + LL(0x0c0bf0ca,0x991bdfe4),LL(0x46da618a,0x0642fbf7),LL(0x2827ab9a,0xcb3c80d7),LL(0xa4c02a4a,0x24ffe39b),LL(0xdd1a385c,0x81fb1f95),LL(0x4fe48911,0x7ed78cb0),LL(0x42514e36,0x12838990),LL(0x2822adf0,0xcd6245c9),L_(0x000001af), LL(0xc2dbb25f,0x682326f4),LL(0xeadeab18,0xa6714b92),LL(0x8194d4d8,0xec34ca02),LL(0xaf1a5a6c,0x18aa0b61),LL(0x21f3603a,0xd56cb67c),LL(0x9e65c6ef,0x64df4053),LL(0x9af9ff17,0x6e1b769a),LL(0x333abb94,0xd74c3bd6),L_(0x00000157), + LL(0xe34d8e25,0x6b395c0b),LL(0xb5b87b52,0x48432467),LL(0x7efdcd9b,0x9d4e858e),LL(0x7c0c8922,0x30d29dcc),LL(0xd7b3a015,0xe0639cac),LL(0x02eb2112,0xa2a88900),LL(0x99cb32dd,0x5ee2bf55),LL(0xe98b88fa,0xa3323b39),L_(0x000000b7), LL(0x51e66e87,0xe5c08a49),LL(0x2cf028a4,0xf8ca8809),LL(0x62209ac3,0xfaac3cb2),LL(0x91bff5ca,0x2cd5c8b2),LL(0x2f2a80df,0x2244abea),LL(0xd2c4cfb9,0x1181848d),LL(0x345b1ca4,0xc35b7b60),LL(0x3093dc03,0x815a0c2b),L_(0x00000134), + LL(0x4da0913f,0x3f060a04),LL(0xc9440b7b,0xf892eb31),LL(0x8c0aafa8,0xc25c561f),LL(0xebcb8c35,0x12770520),LL(0xe63e94d2,0x6d5c16b3),LL(0x1c828d52,0x9bde42a4),LL(0xcafff93a,0x2b7abe51),LL(0xc4851b92,0xa9fcd2b9),L_(0x00000000), LL(0x573073fe,0x24e44af4),LL(0xebda81a0,0xa695bf6c),LL(0xdee85d40,0x76c43176),LL(0xf9ff0671,0x8106e3cf),LL(0x7e8060f0,0x4ce1b2a1),LL(0xa7e23360,0x81d1ed8c),LL(0xbfa62d39,0x47f7b51a),LL(0x4292ca9e,0x9139a437),L_(0x000001ba), + LL(0xfabf78b3,0xa65d9111),LL(0xb4e47850,0x4221510a),LL(0x7528def6,0xeca10d8d),LL(0x12fd7625,0x4560fa05),LL(0x7883ec3b,0x5c64949f),LL(0x2a961e63,0x4df0271f),LL(0x4eacd5e7,0x9af4d45b),LL(0x62f25ceb,0x9ab3bb2a),L_(0x000001e5), LL(0x198ddde1,0x92cdd0ea),LL(0x6860d474,0xae51b5ad),LL(0xc69002e2,0xccd9fe59),LL(0xe138bd08,0x00304cd8),LL(0x9ec62f95,0x329feb5b),LL(0x0928d5e4,0x8a27990e),LL(0x6d9656bc,0x0f0e6792),LL(0xb7989c9a,0x3f1c862c),L_(0x0000010e), + LL(0x9c0279ea,0xa5a66086),LL(0xf622c1ac,0x7ccf9bc1),LL(0x3beaf465,0xa68726c3),LL(0x900cd78d,0x2a903911),LL(0x2be1c512,0x8832203c),LL(0xa8466703,0xbf042dcb),LL(0x1301ba91,0xa8235209),LL(0xfc06ed9e,0xe1aef50a),L_(0x000000d5), LL(0xf153a82e,0x47a0b87c),LL(0x55a0038d,0x9826631d),LL(0x6ef49646,0xe8d54ad8),LL(0x53644562,0xa200feff),LL(0x773835a0,0x5c4408b1),LL(0xb6c0a0e2,0x3199aac7),LL(0x2d23ae2f,0x4f2c5a36),LL(0xdfbd8171,0xccacb296),L_(0x000000c8), + LL(0x568d9b42,0xcf45bc39),LL(0xbca99c74,0x16aa0dee),LL(0xae132b38,0xb713a9d8),LL(0xf8d3fb57,0x139b0131),LL(0xc38156e4,0xc42164bb),LL(0x3293d5ff,0x74da5a53),LL(0x28a54d0e,0x970fceff),LL(0x56246758,0x3ef8fd2b),L_(0x000001cb), LL(0xb3941bc5,0xa0e59886),LL(0xe1a4b217,0xaa3f69ad),LL(0x23117719,0xb7b4e45e),LL(0x118c88c1,0xf1294233),LL(0xd7dfa5c3,0xf1ed8c9d),LL(0xfa2104f8,0x22213ffa),LL(0x89ed7138,0x3ea0a97e),LL(0x2cd0f857,0xf09db9f8),L_(0x00000081), +}, +/* digit=17 base_pwr=2^85 */ +{ + LL(0xb1d8c85f,0x7d77d542),LL(0x6c76648a,0xa16759eb),LL(0xae9936fc,0xd9556eeb),LL(0x239c8db3,0x1fc23af7),LL(0x3df02c8f,0xd956a664),LL(0xfec894e1,0x2a0d5264),LL(0xaaa92f80,0x14a90b90),LL(0x93d756f0,0x53d197ff),L_(0x00000007), LL(0xf62d4dfe,0x06dc80b7),LL(0x026f8974,0xdd1ea5de),LL(0xbf46ad6a,0x1c416858),LL(0x8f0f1c5d,0x6b3d82ce),LL(0xf587ce4d,0xa459159d),LL(0x3b92c19a,0xb6baca47),LL(0xda5bec10,0x600af3c6),LL(0x40e0b4be,0xc81e2b9b),L_(0x000000f6), + LL(0x66942d96,0x7d27dadf),LL(0x34d4f088,0x4ff582d9),LL(0x24ab4a3b,0x151ee4b7),LL(0x58c8094d,0xdf116aee),LL(0x1ceee559,0x6c8ad814),LL(0xf6cc0cd1,0x3d13c277),LL(0x9d41dd2c,0x75e0cd1b),LL(0xf318d63c,0xbb0767f3),L_(0x00000006), LL(0x9ef6b69f,0x1f3f3f36),LL(0x8f1170f9,0x44906780),LL(0x6338ef63,0x7495e6b8),LL(0x66dcb459,0x3f524ab7),LL(0x7ec63428,0xfd773112),LL(0x86373e0a,0x549575be),LL(0xd2af0e3a,0x9dfc2be8),LL(0x6314c681,0xffa7af5c),L_(0x0000017a), + LL(0x894f83b3,0xb01c752e),LL(0x2db47294,0x8755f110),LL(0xefd03152,0x233b9d7e),LL(0x00f8e7a5,0x69c62c75),LL(0x1ee3b5dc,0x551f4471),LL(0xa5e280f0,0xc7dd9d94),LL(0x11042cd8,0x0c2167eb),LL(0xaf8b1437,0x7f4636e4),L_(0x00000180), LL(0xd4828172,0x77598691),LL(0x12f599a0,0xcf61cb84),LL(0x0459d6b4,0x6f27cc0b),LL(0x126405e2,0xbc7fdaf5),LL(0x4a3026dd,0x0cdbba7c),LL(0x658e4a3b,0x25d0b262),LL(0xf2e795bb,0xeec95e90),LL(0xc8766509,0x52259c52),L_(0x000001a4), + LL(0x3b0becbc,0x35410967),LL(0x88f9eb94,0x20da6297),LL(0xae5dfb3d,0x527623e5),LL(0x17557d88,0xc844e99c),LL(0xb4031115,0xb6a57ec3),LL(0x4aff5aa0,0xbe7d0b59),LL(0xea2e84ad,0x1e84a37c),LL(0x947fcbaf,0x048c2935),L_(0x000000e3), LL(0xe275de5d,0x93f58bed),LL(0x503171b0,0x7aaa2b21),LL(0x7b8e1c73,0x6261f263),LL(0x620dfceb,0x1e8e8701),LL(0xdb241dd2,0xce453d37),LL(0x74e79c85,0x7db88257),LL(0x6f92bc71,0x5a2566e6),LL(0x6fb9d9ff,0x4ae0bd7b),L_(0x000001fd), + LL(0x8f215ed1,0xed12288f),LL(0xe57e6348,0x585fa9eb),LL(0xa7abfcec,0xb1b5c7dc),LL(0x12939a1c,0x76c09203),LL(0x48eb6b41,0xc4cc679c),LL(0x2a08cff6,0x4778574b),LL(0x8519401e,0xa530fac0),LL(0x93672b0d,0xe3ed0e37),L_(0x000001c5), LL(0xd47e0778,0xb789e1a5),LL(0x479a986c,0x85a2af38),LL(0x47001e80,0x5a9c69c9),LL(0x623b25fe,0x05944f83),LL(0xecb76557,0x1f6667a7),LL(0x0cb584d5,0xc3bb24b7),LL(0xdaf97923,0x7f09e6d8),LL(0x00ac1be5,0x6d082075),L_(0x000000db), + LL(0x8445a8cc,0xcbbf6efa),LL(0xd82adf79,0x6f9a1c1d),LL(0x1d21df42,0x47e0a609),LL(0x1902bf5b,0x6c507d72),LL(0xd92481e1,0x732e3603),LL(0x4e995e7f,0x0a9f3c6f),LL(0x57c9de5d,0x171e968b),LL(0xace10341,0x27d7d96d),L_(0x00000173), LL(0x415a7d4e,0x093b8c99),LL(0x68806375,0x999003af),LL(0x0227279e,0x62158e85),LL(0xd41629b8,0x3479df9d),LL(0xa2d25c33,0x3570b3aa),LL(0x61de636e,0x4eb04a19),LL(0x71b3bbeb,0x0ce04d19),LL(0x4c30f9b9,0x15492470),L_(0x000000b3), + LL(0x820638ac,0xcc212f6f),LL(0xf1e3cf43,0x2c575c09),LL(0xdd247286,0x0980e757),LL(0x812b4ec0,0x19cba5ed),LL(0x883e3e28,0x4641e487),LL(0x0bb816e7,0x6c96b70b),LL(0x461f03f5,0x26aaf764),LL(0x918835cd,0xe1cfcddb),L_(0x000001a8), LL(0x2da8f566,0xb11711e0),LL(0x3f7282c1,0xed552895),LL(0x44826000,0x25594479),LL(0x065389a8,0x70867768),LL(0x96f127c7,0x52ffb2b6),LL(0xaa1f5abe,0x0831bd74),LL(0x9739a178,0xf0a510a0),LL(0x6154e726,0x36902e78),L_(0x00000177), + LL(0xf7a9efa0,0x42cd0f9e),LL(0x7bbdb010,0xa3fbb175),LL(0x1996a380,0xf39db731),LL(0xbb69e651,0xf3f08146),LL(0xec6679cd,0x8679b0b6),LL(0x60847478,0x90d1ae26),LL(0x883e5a59,0xa5e209ed),LL(0xba61924f,0x3c755c0b),L_(0x000001de), LL(0xebae92ff,0x847c1f82),LL(0x8ace9c6a,0xa1434ccf),LL(0x857d9026,0xad864d4c),LL(0x0ee5b0b7,0xf613e221),LL(0x86a35718,0x91165b2c),LL(0x55984d67,0x080d19fb),LL(0x15401901,0x3389eccf),LL(0xd99a0e8b,0x8b509b98),L_(0x00000060), + LL(0xfa05d78b,0x7c660e1a),LL(0xfd68d650,0x85aa25df),LL(0xe307472b,0x3713d00e),LL(0x3afed55d,0xc091f93d),LL(0xecc3137e,0xa9f9d1a2),LL(0xa3d44f8a,0x32a1cdec),LL(0x4344089c,0xc8d64b46),LL(0xe3575142,0x11bd5244),L_(0x00000102), LL(0xfd1a1cdc,0xe4cb9635),LL(0x8fa8648f,0x3dc52f80),LL(0xdf8e13dd,0x058fc1b8),LL(0xc1ab282d,0x3abf2a6c),LL(0xf290d505,0xfb0841a1),LL(0xea29f4f4,0x3d94894a),LL(0xb691fb1a,0xf7a1cc29),LL(0x0da25d00,0xfc4326f1),L_(0x0000018c), + LL(0x9155b117,0x1b3c8c62),LL(0x1ffd1435,0x58c3116e),LL(0x54a96e6c,0x90a8d92e),LL(0x623a9ece,0x891efe6b),LL(0x66715556,0xe72489c2),LL(0xd3bfc0b3,0x5b00b58c),LL(0x8cf3d04d,0x06c601e4),LL(0x71f460fb,0x26e3ef6c),L_(0x000001d1), LL(0xe91afddb,0x626e2af2),LL(0xa51ff90c,0xec49ef66),LL(0xd3f82493,0x704277da),LL(0x9f0e6e8a,0xca17ce54),LL(0x80cb9b26,0x62bbba3d),LL(0x39fb568b,0x7ff82aae),LL(0x978a0c13,0x9cbfd867),LL(0x6bd90fa9,0x07be1717),L_(0x00000151), + LL(0xc31dd728,0xd809dd1b),LL(0x12107a4a,0xc16d6592),LL(0xdc70467d,0xf8d5c83c),LL(0x273b2243,0x596e052c),LL(0xeab68bd9,0x8aaa0dde),LL(0x11cdb329,0x39baf3e4),LL(0x65459e78,0x004f292b),LL(0xc654b1e0,0x4da9e734),L_(0x0000014a), LL(0x58fc53ab,0x1ee009d1),LL(0x45bc8ab1,0x24563a0d),LL(0xde252f6e,0x04322137),LL(0xd1d577ae,0x29c5297d),LL(0x554880c2,0xf29e1a9e),LL(0xfc0d4b7e,0xa08f14c2),LL(0xe648399e,0xfd1007c8),LL(0x23bed899,0x2a7303ca),L_(0x00000010), + LL(0xa4c512fb,0x2e60230d),LL(0x883ed27b,0xf8aee1ce),LL(0x57a9715e,0x9d84b9da),LL(0xa58cae2e,0x59971acb),LL(0x62ef042b,0x5b1190ec),LL(0xa8c70cf9,0x1ecd90c6),LL(0x1e5cf5d1,0x0a20a7a4),LL(0x3aec3e16,0x7baf5a6c),L_(0x0000006e), LL(0xc8d347ac,0xf18a3f41),LL(0x0debc30a,0xc54674cb),LL(0x2dbc3b83,0xc265a6e5),LL(0xa8033fd7,0xf450415c),LL(0x2a50f527,0x6adf277c),LL(0x81475ec6,0xff0d3a36),LL(0x5f2c676b,0xdffe6c53),LL(0x0c1f159c,0xf5ad7f78),L_(0x00000106), + LL(0x4f0af995,0x00058fc2),LL(0x8bb729ca,0x48246fa7),LL(0xff563f60,0xb23219d5),LL(0x8c64a3a5,0xf34e49ac),LL(0xe82036c1,0x9d2397f6),LL(0xe392c964,0x58216601),LL(0xbeda885c,0x3d7f9573),LL(0xe289f5e8,0xb1917dc6),L_(0x00000169), LL(0x30057807,0x6d9791a6),LL(0x37eb92d1,0x066237a9),LL(0x7995f34e,0x764ae778),LL(0x8d994f01,0xde5ca0e3),LL(0xaff07e24,0x199bd467),LL(0x544454f0,0x4bf2e809),LL(0x603eb80f,0xe5054850),LL(0xc95e16ef,0xa4a6c672),L_(0x000001a9), + LL(0x8c50d780,0xc8db0700),LL(0x32a1b788,0x45d0d169),LL(0xc842373b,0x87531f66),LL(0x674b4407,0xdbe71b0e),LL(0x8189664d,0x42dd8323),LL(0x7cdb6aec,0x8df2c5a6),LL(0x86c397bc,0x86388fa4),LL(0x110db0bc,0xf6d18eb8),L_(0x00000086), LL(0x5a491f30,0x23e50391),LL(0xa2dcf957,0x6ae2419f),LL(0x1c7362d5,0xac9caab7),LL(0xd238a731,0xbef3c44d),LL(0x28f6d7ae,0x5c3ea7d4),LL(0xdacef1fe,0xd654307e),LL(0xb31d909e,0x01625227),LL(0x6d2db310,0xb2421d90),L_(0x000000f9), + LL(0xb66d61ea,0x4083d41b),LL(0xf3bbcb07,0xe8c0bfc8),LL(0x91274928,0x9c0b763c),LL(0xc81b7765,0xbe1076e4),LL(0xbf368625,0x9568943e),LL(0x8c2112ae,0xb0cd4c71),LL(0xf70e5fb5,0x8fe2ec7e),LL(0x76a5c64b,0x867a5527),L_(0x000000b5), LL(0xd3886d7d,0x3faf5b44),LL(0x41c29ed5,0x50ffd8e6),LL(0xcb155068,0xa9b2855c),LL(0x28ae527b,0x9d8e8d01),LL(0x2a092960,0x5cbf1edf),LL(0x66ffe099,0xb212b2a8),LL(0xd340e610,0xfc0600f9),LL(0xa2f5aba0,0xb08ba7b8),L_(0x0000005b), + LL(0x604c6624,0x0ca526cf),LL(0xa9ed0f7a,0x125b33af),LL(0x1dd685ac,0x516f5290),LL(0x17e7ff8f,0x927c416e),LL(0x720475ad,0x0fc77cc9),LL(0x67e1e919,0x3aec0717),LL(0x6652fcb3,0xcb2653df),LL(0xd80f0d48,0x8bf16720),L_(0x0000006c), LL(0x0590fcd7,0x08404c44),LL(0x7f43e4e4,0x9c42e337),LL(0xdefb2272,0xc3b37e10),LL(0xdaf241ae,0xc795c866),LL(0x0a07c892,0xbf4d3079),LL(0xb2425f5f,0xa5db075b),LL(0xb7cb5830,0x0875f161),LL(0x93c95089,0x91cad664),L_(0x00000065), +}, +/* digit=18 base_pwr=2^90 */ +{ + LL(0x7dddacd3,0xc3797559),LL(0x266f6975,0x22dfb9d9),LL(0x599f544c,0xdb081480),LL(0x839c2be6,0xeb8ec462),LL(0xb5cdf12a,0xd9d49cd3),LL(0xa917fb29,0x96146a8b),LL(0x233b216f,0xd936c0b8),LL(0xf0abf1a9,0x8c8a45a2),L_(0x00000187), LL(0x0356029a,0x0f5dd64a),LL(0xd1625aef,0x056528c2),LL(0x5ff56fc7,0x9b293d67),LL(0xa5c323cb,0x02b295cc),LL(0x4d697cbd,0xbc712910),LL(0xe4eb4b02,0xc1e4d83f),LL(0xa4e9327c,0x9c23cdd4),LL(0x5af46cdc,0x94640699),L_(0x0000013f), + LL(0xc9de104f,0x6147414f),LL(0xaed9435d,0xbd16db82),LL(0x62ff16a9,0x3b07e71a),LL(0x52dcaf4a,0xf9456ee7),LL(0xea0d3e3f,0x1d78dd65),LL(0x64901fef,0x31145bf8),LL(0xbc9f4225,0x366fd367),LL(0x81cb13ee,0x290083f4),L_(0x000001e6), LL(0x6e77ebe4,0x5232088e),LL(0xc5e887c8,0xcc7b3f38),LL(0xf005e149,0xe1bede78),LL(0xe8c89874,0x2dfeaf32),LL(0xcb4e28c7,0x3cb0a4d9),LL(0xda48c711,0xaf7daba5),LL(0x1fe289a0,0x0d3633ab),LL(0xbd5d0dc0,0xc0b05c86),L_(0x00000001), + LL(0xd5e4e9c6,0x85849a1c),LL(0x74861653,0xe1eb1a35),LL(0xaf98abe0,0x53b40a6e),LL(0xf083ec36,0x74acbc0b),LL(0x0b5a921d,0x28a65b06),LL(0x5764e30a,0x5588eb5e),LL(0x62277d5e,0xc8da671e),LL(0x39cae462,0x53bbf492),L_(0x000000a9), LL(0x0635b866,0xa6baa014),LL(0xd98a134c,0x31e23fcb),LL(0xdbe32368,0xa8c7a352),LL(0xef82abaa,0xa98ba793),LL(0xcbb55844,0x1a07e161),LL(0xaf3169a7,0x4991ee4a),LL(0x5cfbe290,0x0c980dd6),LL(0x56a21524,0x1c07cd7d),L_(0x000000cd), + LL(0x06de0083,0x07567a7a),LL(0x045155d8,0x351697cf),LL(0xce8bb246,0xcba64633),LL(0xdd5c2900,0x24297174),LL(0xe7f044c7,0x0c3a3851),LL(0x48c830bf,0xd35ff595),LL(0x817a26f0,0x7d923f53),LL(0xd93d8b02,0x2b3dd7ca),L_(0x0000002c), LL(0x924bf9f6,0xcc94cbf6),LL(0x986d299b,0xdf6f5c09),LL(0xf89ccb5a,0x5aee26f4),LL(0x18699f82,0xc1b545bb),LL(0x6595e656,0xb0d22aa5),LL(0xa3953fae,0x6abcba5e),LL(0xa9580b4b,0xd4e240d3),LL(0xef465246,0x13b6fdf7),L_(0x00000186), + LL(0x69351015,0xbd979035),LL(0xf355f70f,0xc5a87f52),LL(0x1b7365b1,0x18c500a7),LL(0x2dd3210c,0xf547e418),LL(0xc57a734c,0x391d8bfc),LL(0x928abb19,0x5ec8dcf1),LL(0x3e6991b5,0x7de9b3d1),LL(0x9e25eac7,0x6ebd2b96),L_(0x00000022), LL(0x77d1be34,0x7d70fd72),LL(0xae0eb8d2,0xf2114ba3),LL(0xb57b0ed4,0xe573b783),LL(0xc65906cc,0x0b2b3d21),LL(0xfac74740,0x9dbb25b7),LL(0x6157bc5c,0x6859f85a),LL(0x21a21340,0x0df614a7),LL(0xbfacee18,0xe4709b5a),L_(0x000001b2), + LL(0x96a37abe,0x15b4091f),LL(0x31ad054c,0xdccd6f0a),LL(0x57e2c372,0x27698a20),LL(0x9a3a4ffe,0xcc03de8d),LL(0xc754fb8f,0xcd17cdf6),LL(0xa956ebe7,0x7cb9ef2e),LL(0x9d18d38c,0x190daaea),LL(0xdc66f2ca,0x7d783383),L_(0x00000030), LL(0xcbc69492,0x727ea062),LL(0xfefa898f,0x773b6e5f),LL(0xfbea71e8,0x7460be92),LL(0xc9254b56,0x318caed7),LL(0xc982d8e5,0x7f1a16b2),LL(0x9a4da06d,0x38233ae7),LL(0xe149d876,0x3b8c2af7),LL(0x70fc3c7a,0xec4a5565),L_(0x00000154), + LL(0x73053e0b,0x5f08f3c6),LL(0xd02192ba,0x05cbe08a),LL(0xbb7b43e6,0x4a339a92),LL(0x2b4034e6,0x1c6eea28),LL(0x0145dd56,0xb3481662),LL(0x819f74ea,0x5fdab086),LL(0x2d08d669,0x401f4d8b),LL(0x87d855a8,0x71a3977d),L_(0x0000007c), LL(0xf6c94b12,0x787e1654),LL(0x7f231760,0x1dcce655),LL(0x2908ba05,0x10acadce),LL(0xe5a3ffa8,0x60f31016),LL(0xe1211553,0x34c2a1c2),LL(0xfe1b8dad,0xa81d35d3),LL(0xe7230bfc,0x37a78d41),LL(0xcfeaf774,0x6e60ae9c),L_(0x000001f5), + LL(0x725af512,0x898a64cd),LL(0xda668233,0xc8516d6d),LL(0x1f40d7d1,0x5fb1f564),LL(0xd5a115e0,0x7906c2d8),LL(0x496ac4ad,0x6f4efe00),LL(0x3643f707,0x6c892d97),LL(0x414f5838,0xe34b14c4),LL(0x7c2d83c2,0xc00d08bc),L_(0x00000037), LL(0x6bebe71b,0xca445165),LL(0x219e2e5b,0xcbf3a3f2),LL(0x118227ea,0xf1a84019),LL(0x6017e2ce,0x58a5f9de),LL(0x1922122d,0xf1ecfa6e),LL(0x98696eb0,0xd3df6fb1),LL(0x54826be2,0x8fefc088),LL(0x02dea006,0x77c29791),L_(0x0000014e), + LL(0x368b75f9,0xe65ce508),LL(0xa5fec659,0x0b177612),LL(0xdd1bcbef,0xfc84b3bf),LL(0xe4569388,0x984ce0ec),LL(0x163caf98,0x9cc1f201),LL(0x3fa88dda,0x39bac4dd),LL(0x6c254803,0x70562e22),LL(0x75a93dd1,0x2cbfcecc),L_(0x00000095), LL(0xfd7cf39c,0x0ce600b2),LL(0xe3dc17db,0x5b060f2c),LL(0x5399ddf1,0xd74988f6),LL(0x83e38dff,0x2b96b9f4),LL(0x87e221d8,0x2c298bc9),LL(0x0753b765,0xd6bd45f4),LL(0x27e5b1a1,0x18ca1da9),LL(0x41853811,0x7849f1e1),L_(0x000001bd), + LL(0x90c22eba,0x226b8a15),LL(0xdb333954,0x4e3975a7),LL(0xaa52c0ba,0x74176c01),LL(0x1fd9d014,0xa1a2b6b0),LL(0xf61b81e1,0x28415db7),LL(0xd3614b3a,0xa0f6000e),LL(0x9e00e5a5,0x5cf34986),LL(0x9efe446d,0x0b69d383),L_(0x0000001b), LL(0x245ecf44,0x2d0c1e46),LL(0x1f77c4cb,0x553d358a),LL(0xe9f129ca,0x071ebad1),LL(0x088b2769,0x8eb8c2d8),LL(0xf3219a51,0x877b3a25),LL(0x17c5431a,0x9c4b8adf),LL(0xeac2ff93,0xffc69d68),LL(0x23d158f5,0x2e0840d4),L_(0x000001fa), + LL(0xb9d98a1d,0x6d2a4e6a),LL(0xb45f9376,0x6e78c290),LL(0xbff42b2f,0x5fb9af74),LL(0x2af23d44,0xaebdf547),LL(0x7deaa238,0x93a6597a),LL(0x25df5576,0x5dcbd040),LL(0x6f6b456f,0xa9249467),LL(0xb63da0b0,0x7f719d63),L_(0x000000c8), LL(0x15e8e55f,0xda677478),LL(0xcb218f05,0xb119afe4),LL(0x3e0b4052,0x816ad70e),LL(0x342ea279,0x14498c92),LL(0x7acbb776,0xc4e09c12),LL(0xbf8e66de,0x0f290835),LL(0x3edfdd90,0x8ca19f41),LL(0x794255ee,0xa1bde671),L_(0x000001cb), + LL(0x5a5b22a9,0x4848eb20),LL(0x80f21ad1,0xde0fb7d6),LL(0x8e50bcbd,0x4c1119fd),LL(0x83d6f607,0xf9f2e435),LL(0xd9961c79,0x765361f1),LL(0x625f26bb,0x008a463e),LL(0x2b47c8db,0x87cd134f),LL(0x328c3977,0x36eea7ef),L_(0x0000009b), LL(0x3894ce29,0x3d664722),LL(0xdfe036fb,0x206e887a),LL(0x67daf1eb,0x72f017c4),LL(0xf7db19b3,0xad33a99e),LL(0x06ea7ba8,0xf55c0da8),LL(0x14bd637e,0x9b12c024),LL(0x59864973,0xd282f3bb),LL(0x55feed3d,0xce69b372),L_(0x000001ec), + LL(0x79ad5e39,0xdf10c34e),LL(0xb43675e3,0xb8ad4110),LL(0x19590538,0x801f28aa),LL(0x239ed388,0xc602d7b2),LL(0x3a5a6ad4,0xbdc9fad5),LL(0x62b5ae49,0x135d222c),LL(0x5042d74a,0xc3f94c1d),LL(0x28ba3dd9,0xe0a1ec48),L_(0x00000110), LL(0x6cd1e311,0xceb5a088),LL(0x77f171c2,0x8f737348),LL(0x31242fc1,0xdbca643a),LL(0xe44bcbd8,0xcd573afd),LL(0xbad62d6a,0xc4c9f268),LL(0x5d49ae75,0x98fad2cf),LL(0x9b8f817e,0xd8431494),LL(0x96bb2753,0xc49e4432),L_(0x000001a8), + LL(0x87036cde,0xa4f9f22d),LL(0x2ccfc8e8,0x4cd46e2b),LL(0xa48136e4,0xa95491dd),LL(0x8818327f,0x6393487e),LL(0x7a069a28,0x98ab19e5),LL(0x5c879344,0x02491e0c),LL(0x82e60002,0x2abf1999),LL(0xc0e10b00,0x82724899),L_(0x000001ed), LL(0x9fd75e21,0x4897df79),LL(0x688c2193,0x43479e7f),LL(0xc705deaf,0x5b79a04e),LL(0x068f9205,0xb2c04a79),LL(0x3a42239d,0x0245715d),LL(0xa99eca86,0x55284faa),LL(0x9f983742,0x07d9bbaa),LL(0x5fe3bb74,0x5a19431d),L_(0x0000014c), + LL(0x0f3f56ca,0x99e63ac2),LL(0xac6175c0,0xcb3bdf62),LL(0x0d4bf222,0xd9e5f622),LL(0x83e1cd77,0x4ca3e4a6),LL(0xde0dce61,0xf80cd49b),LL(0xeac1e293,0xf190c10e),LL(0x901aa7ce,0x30eda1d3),LL(0x25f2f0a6,0xa509dab1),L_(0x00000199), LL(0xe9fb14f7,0x0ab974ef),LL(0x9b6b41ad,0xcc8fc9d8),LL(0x20269236,0x5472afda),LL(0x81034020,0xb7eb7c83),LL(0x26dba78a,0x7c59479d),LL(0x81e829eb,0xb0ba6216),LL(0x1549f5f2,0x843a5c45),LL(0x18302134,0xa2709e3b),L_(0x0000014c), + LL(0xc1370929,0xbde5f81a),LL(0x8f81e9a3,0x7f4da051),LL(0x9720014a,0xa02bf073),LL(0x9ff1f457,0xe074553e),LL(0x3a46ea6b,0x64351eaa),LL(0x7e32f0dd,0xd22b22b2),LL(0xb488462f,0xcafc2c23),LL(0x566dddda,0xfb75908f),L_(0x0000015b), LL(0xb5b9a118,0xe8987332),LL(0xfe94dfd9,0x4f63b44f),LL(0xf9b91bc6,0x0dbd772b),LL(0xecb77f43,0xd580392a),LL(0x2fb67ddf,0x1ddc69fb),LL(0x2fdb69c9,0x9ea2314d),LL(0x754b9b9f,0xe624f23e),LL(0xf3f2e9c2,0xc6e677e1),L_(0x000000a3), +}, +/* digit=19 base_pwr=2^95 */ +{ + LL(0xb1001608,0x14f438f4),LL(0xd13ff0c3,0xb8e45f22),LL(0xd55796ec,0x3dd2e2bb),LL(0xf830ab87,0x9eb71d33),LL(0x14a36478,0x83167e0b),LL(0x46513aa4,0x793502c2),LL(0x03e86d3a,0xb0fe98cb),LL(0x4eb2db2b,0x0404a0ec),L_(0x000000d7), LL(0xc6b60bcc,0x8f4384c5),LL(0x0cd19a5c,0xc19b3257),LL(0x1c33b468,0x9210942f),LL(0x29ccbac3,0x36048a2a),LL(0xd4ffa97d,0x4f69ef5f),LL(0xcd6b0a67,0x82d0ece5),LL(0x13229739,0x4bce1b8b),LL(0x491493bd,0x4d6596bf),L_(0x0000003d), + LL(0x13acae0c,0x560db5e8),LL(0x1117f6d4,0x8e19b583),LL(0x1106059c,0xe8232c57),LL(0xc78f908c,0xd0f09782),LL(0x4a24aa92,0x8bd0fcb6),LL(0xd766becf,0xf59977e3),LL(0x155f53d2,0xfa9a727f),LL(0x49389ae2,0xff877e92),L_(0x00000120), LL(0xd2d44588,0x9985d510),LL(0x3b4e5204,0xe4788dc7),LL(0xaa68342b,0x8a0ca8e6),LL(0x7b14f89c,0x66874892),LL(0xf19eb3e8,0xe17375dd),LL(0x5e5f8b7c,0x652a41d1),LL(0x2912af54,0xa86a7275),LL(0x5ab9a777,0xbaf706d8),L_(0x0000003b), + LL(0x0d6ee2a7,0x8ca944bc),LL(0x4852fbcb,0xbefff557),LL(0x0369a497,0x3e3736fb),LL(0xe2bb7551,0xd21615dc),LL(0xe6d3b727,0xe319eb4c),LL(0xe8de5f7d,0x48fe4856),LL(0x592a3396,0x7516380a),LL(0x80dc9aef,0x51f52af0),L_(0x00000151), LL(0x7aa71f54,0x98c6421f),LL(0x38523c52,0xec51f4f2),LL(0xf58cc95f,0xbc6c8082),LL(0x36ef370c,0x7bc605a3),LL(0x8ac270e3,0x83d78da4),LL(0x0412498a,0x6de54abd),LL(0x66b38131,0xdb62d8c6),LL(0xe06d3c3f,0xf5e45a86),L_(0x00000129), + LL(0x42a7b358,0x4517d395),LL(0x53d2cbb1,0x5b733d69),LL(0x44a3ef5b,0x472126ff),LL(0xee076565,0xa4a1334d),LL(0xb26c37b2,0x12573d17),LL(0xb5b29517,0x129c2c7a),LL(0xd328148c,0xa2c72b08),LL(0x08907f5a,0x1d10e103),L_(0x0000018b), LL(0x154b57d1,0x5e159666),LL(0x9359d888,0x4827d5dd),LL(0x0281b6f1,0xa475f3a4),LL(0x6b19bc4b,0x2eef4469),LL(0xdc6dfbc3,0x782b50db),LL(0x9ef4383e,0x0583236a),LL(0xd7320845,0x7767db3f),LL(0x0dd190b0,0x3c0278a0),L_(0x00000115), + LL(0xc54f57bf,0xb03b1675),LL(0x97e68374,0x1c499646),LL(0xae2f3284,0x74508785),LL(0x0255084b,0xf1921ad5),LL(0x6ea40714,0x2aabd8cb),LL(0x516433de,0xd1c8abdf),LL(0x5d2d8ded,0x8f5d7b6f),LL(0x421e5a19,0x2d6ae9c5),L_(0x0000007b), LL(0x99149c91,0xd9a89463),LL(0x4310dcf0,0x0122d1b0),LL(0xd2489f91,0x4e7b58d3),LL(0x655fdd5d,0x40c4379c),LL(0xc7862d42,0x6da55b4a),LL(0x975cc64c,0x1e1d3862),LL(0x84484f68,0x301cfa3f),LL(0x2a16eb0a,0x20ebbbdb),L_(0x000000e4), + LL(0x5456251b,0xc0ba905f),LL(0x5b3d8d39,0x62a268ee),LL(0xea2a0a44,0x094457cb),LL(0x80f032f3,0xab36ceff),LL(0x8790739b,0x21b0fdf3),LL(0x40209bce,0x38249dc8),LL(0xf0c1c8e0,0x213ecb4d),LL(0x70c51d81,0x2b025e0d),L_(0x0000003c), LL(0x4b899f83,0x493bb32c),LL(0x798bfbf2,0xf622fccb),LL(0x28838277,0xc2594827),LL(0x5cbe5b67,0x2c07c4dd),LL(0x2c4c703c,0x1c19526a),LL(0xdcd0df4c,0xed390177),LL(0x57a743a1,0x3a4c5274),LL(0xac32bea6,0x1c302e78),L_(0x0000015d), + LL(0x0eb650df,0x18bc0976),LL(0xa3094433,0x7cfa690a),LL(0xca509300,0x660a165b),LL(0x9645aafc,0xdcef6d7c),LL(0xd90c6f35,0x07a41bbc),LL(0xad0dd448,0x702e476c),LL(0x5c881f7f,0x2185a821),LL(0x9c91260c,0x0622b914),L_(0x00000063), LL(0xcb1b5333,0xfe64e60a),LL(0x59c3b83d,0x192bd9cf),LL(0x5bdb24df,0x69659379),LL(0xa9cbc111,0x437b31e8),LL(0x2954601b,0xb7b5589c),LL(0x13c392f3,0x97064b9e),LL(0xf1845fb5,0x8d803336),LL(0x7ea9c980,0xea2d2221),L_(0x000001ca), + LL(0x828ff0ba,0x23fc5003),LL(0xa9841f43,0x62407436),LL(0xc6f35f8a,0xfc260a1f),LL(0xf5e9286e,0xe74c4b2d),LL(0x504bfafb,0x7cb3568b),LL(0x3548e504,0x1af9dbcf),LL(0xd92aaad7,0x85e423c5),LL(0x2d182410,0x94d1d884),L_(0x000000f8), LL(0xf29b75d7,0x9975b2a3),LL(0x55f78348,0x0939eec5),LL(0x92b31a41,0x23255263),LL(0x4a1b7bc2,0x65a25c26),LL(0x283464db,0x08fc1aed),LL(0xecd1a9b7,0xea335c70),LL(0x90a7a2a0,0x9f14ffdd),LL(0x7fd21f2e,0x9566dadd),L_(0x000001b4), + LL(0x553ea74d,0x578b8f88),LL(0x2bbf7009,0x8c4ed5a7),LL(0x30e7b9aa,0x30aeacb4),LL(0xe07a93f1,0x58d02f17),LL(0xbcf5fa42,0x7c6f83ed),LL(0x228f3e47,0x91d5ba0c),LL(0x815eef51,0xe37c3b79),LL(0x0528cf82,0x507b5dce),L_(0x000001f2), LL(0x9a97a830,0x5a682d56),LL(0x14eac39b,0x72ce45fa),LL(0x90b36bc5,0x5f62d8bb),LL(0xadbc91ec,0x9d5e2385),LL(0xfae2e6dd,0xef20a2d0),LL(0x380bdc5e,0x9c9037ea),LL(0x2d48d188,0xdd58b76d),LL(0x6a4ce00a,0xb6e3d5d7),L_(0x00000090), + LL(0x545376f5,0xfffa5757),LL(0x64cbfd55,0x1f1c3ae1),LL(0x8a854545,0xd0be9705),LL(0x7272e007,0x2a8f4c49),LL(0x254138ed,0xc97ed736),LL(0x15e864c7,0x83df5162),LL(0xb624fc1b,0xf4114fdb),LL(0xcc0313aa,0x8c7f0423),L_(0x0000007a), LL(0xc8d276d9,0xa4ed76ab),LL(0x3e74f599,0x8b381bfe),LL(0x25d1f92d,0x9e406956),LL(0x06a5a359,0x869bdf5e),LL(0x5afaf671,0xaec86f62),LL(0xbbcc12cd,0x0dd1d724),LL(0xda751689,0x21630603),LL(0x409b6925,0x1f15a18b),L_(0x00000054), + LL(0xcba2ca51,0xc7b9233c),LL(0xff6a30c8,0x6ecefcff),LL(0xf3d40688,0xfad25722),LL(0xc51d4aa6,0xf9c6f8fa),LL(0x3fae03f2,0xc7864470),LL(0x5ca7328e,0x4201ca64),LL(0x4b3ff739,0x08cad454),LL(0xb2721cee,0x43bf4523),L_(0x000001d1), LL(0x2952e7ef,0xaf0e573e),LL(0x2a8f8fba,0x3f5e67f8),LL(0xae4ce46a,0x616a72e1),LL(0x906994c7,0x3a7f4aec),LL(0x055b94c2,0x8bb69b90),LL(0x67e39f74,0x4eead34a),LL(0x7a7cada3,0xf92b70d7),LL(0x9b22abe2,0xca616691),L_(0x00000092), + LL(0x32e5d612,0xd5e1c4e6),LL(0x7ad659b7,0xe2f2a298),LL(0x3f7f338d,0xaaeb06f1),LL(0x6d9b55a5,0xa60e84f2),LL(0x30c6f8b9,0x9d105631),LL(0xd017d58e,0xfa41e760),LL(0x9e20b973,0xb2f4acf3),LL(0x840eaafd,0xec9c6ab5),L_(0x00000101), LL(0xa5a6302a,0x22f4549b),LL(0xb140b897,0xc2510a98),LL(0x3e099225,0x9117bbe6),LL(0x18af31b1,0xba7147bd),LL(0x68bb5c46,0xf0f540e3),LL(0x29d33114,0x1c9aeacf),LL(0xe59588a0,0xeb2d0e67),LL(0x29ef0e25,0x4bb1b8d0),L_(0x0000018e), + LL(0x3f8475bf,0xfaf6783d),LL(0xd0223b63,0x4dcebc43),LL(0x6472ecb7,0x6ff8245b),LL(0x1d3fdb09,0x3439a621),LL(0xa67bac9a,0xd009a2d7),LL(0x94c65387,0xf330caae),LL(0x19a02e17,0xa6f7e5f9),LL(0xb2396a55,0x5fef60ca),L_(0x00000067), LL(0x92275ac6,0xefd6a160),LL(0xefa0d1c9,0xbd7c0837),LL(0x2ede1f4e,0xfcadb9c0),LL(0xf4756366,0x47882726),LL(0xcd42f3e5,0x5c040ce2),LL(0xa61b16f9,0xdb84713f),LL(0xc4ef07e5,0xe43320a0),LL(0xecb2b8ce,0xac70be15),L_(0x00000090), + LL(0xb5440b5f,0x0457915c),LL(0x89a3e1eb,0xe08cc88e),LL(0xed12c670,0x89133ab9),LL(0x1faeab1d,0x15d9bc0c),LL(0x3c4250f6,0x881504d6),LL(0x084c8e8f,0x3ead62cd),LL(0xaf76dbe5,0x49cfac6a),LL(0x85bf1dcc,0x007ea0b8),L_(0x000001c7), LL(0xfc505153,0x47472352),LL(0x123835c7,0x80692fa2),LL(0x67bab29e,0x8379c2a8),LL(0xc2ecca00,0x9065aafb),LL(0x32da9779,0xda605d2e),LL(0x421bbbfb,0x12432283),LL(0xbdc2e115,0x9c126b9d),LL(0x437a9d89,0x7ce3f8d6),L_(0x00000146), + LL(0xa8e68c25,0x5b6dacf5),LL(0x7ae17558,0x1b0157e6),LL(0x314ffaf0,0x03819c6a),LL(0x9d2d7013,0x0e14b9b1),LL(0xc8c2b439,0x91c83635),LL(0x9f636f0b,0x98fed93b),LL(0xe579e47a,0x23b6808c),LL(0xaeb0f547,0x8d044288),L_(0x00000166), LL(0x8b1f49d3,0x891f32da),LL(0xf965270d,0x655e3634),LL(0xe11f64ad,0xacfd673c),LL(0x1b496453,0x68fb4507),LL(0xdf15820b,0x64f7f419),LL(0xd816e8bb,0xfdaf2edc),LL(0x0858d605,0xd9f619c9),LL(0xbbe07451,0xb9e75198),L_(0x00000002), + LL(0x4a1ee705,0xe000c97f),LL(0x5fa6cdb3,0x595ed0a5),LL(0xfd5fcd60,0xa02a23c6),LL(0x76e522bd,0x61844a1d),LL(0xbaf8c003,0x0c6c179e),LL(0xd0a47af4,0x6aa1a6cc),LL(0x71e2a115,0x4eb00620),LL(0x2ca1b0fc,0xc1c5314a),L_(0x000001b4), LL(0x6702b16a,0xcdc04837),LL(0x5b4e8123,0x242a32ef),LL(0xa7d67834,0xccb0fead),LL(0xc2a3bc3a,0xe65ed32f),LL(0xe7119407,0xab8b44e6),LL(0xaeb1712a,0x5a5977e9),LL(0x39ce4f89,0x708cfeb0),LL(0xa19d43ed,0x4957cd1c),L_(0x00000025), +}, +/* digit=20 base_pwr=2^100 */ +{ + LL(0x2f03e91a,0xc29a3fb6),LL(0xcfe3b9a1,0xca033fc3),LL(0x8c5a528b,0xb4bc3e3f),LL(0x23396cd7,0x4bd134e2),LL(0x39c3eb8c,0x565224c7),LL(0x25548c0a,0xf01471ec),LL(0xb0fb17f6,0x5fc65797),LL(0x18aee101,0xc4d69b6d),L_(0x00000048), LL(0x8f600f91,0x0074be70),LL(0xa14b550a,0x52425042),LL(0xf8e6b95a,0x3f438c42),LL(0x0174e981,0x81004aa1),LL(0x34ae4351,0x510cd9a8),LL(0xb1b67e29,0x8cdf2105),LL(0x41438bad,0x8ec5ba91),LL(0xc64d1130,0x00e8c08d),L_(0x00000143), + LL(0x1480c24d,0xb2625d11),LL(0xdcf3505f,0x9962934c),LL(0xc306874b,0x981e8fcd),LL(0x02704410,0x2bd0a650),LL(0x249eb349,0x6a534a84),LL(0x6b6bb40b,0x0c32e132),LL(0xbe5d2914,0xcb2ca52e),LL(0x029956b2,0x77c72251),L_(0x0000018c), LL(0x7c5c4dde,0xfe2b4e07),LL(0x6314442e,0x4431d884),LL(0x66618e79,0xcd3eeea2),LL(0x6a5a933f,0x64415965),LL(0xbda24f06,0x522dc52f),LL(0x82f45dda,0xd412542f),LL(0x0e5075c9,0xff34a66e),LL(0x9a2aba0f,0x512c4a1d),L_(0x00000169), + LL(0x9f6aa554,0xa3dc5b94),LL(0x9872016b,0x2889ccb7),LL(0x1df5e18d,0xe0129254),LL(0xdbcaebf5,0x4cd20b4c),LL(0x63d6c33a,0x1f301089),LL(0xc46a1dad,0x755fc0db),LL(0x2c0e39b6,0x6ef9e694),LL(0xac07fa12,0xd500d36f),L_(0x00000005), LL(0xd19e5fb5,0xf90b5e7b),LL(0x65e8dbbf,0xeb8ecb37),LL(0xe491cc2d,0xd314c068),LL(0xd31ab995,0xe810513a),LL(0xcca181b4,0x9b50dc0f),LL(0x0c1e0526,0x89302958),LL(0xb6453c85,0xde5a7d26),LL(0x3c9a98b2,0x6f7a7718),L_(0x00000138), + LL(0x542368a9,0xd7d861fc),LL(0x7b3c184c,0x5c425a73),LL(0x14a6e3b9,0x85d4a651),LL(0x532f514e,0xb665bb45),LL(0x8b87e598,0xa66a39b0),LL(0xdbcbbabb,0xa46208db),LL(0xa64b561f,0x9520864b),LL(0x05569250,0xde8b31e2),L_(0x00000081), LL(0x4473c211,0xdd1bb6a7),LL(0xe76a8c5d,0xc0f66932),LL(0xc6ee633c,0xc546bb80),LL(0x911f68d0,0x828f4e0c),LL(0xc213a206,0xeb2a4276),LL(0x04a16b2c,0xcbe98cb2),LL(0x38c09aa1,0xbcc1671d),LL(0xa6f3ebee,0x7a684ba9),L_(0x0000012c), + LL(0x89cd7620,0x2ca34639),LL(0x14b160b2,0xe3cc4351),LL(0x57f2d520,0x8707011b),LL(0x1d30ff78,0xb1a346a6),LL(0xd69eda68,0xa84618b8),LL(0x4008115f,0x06f520c0),LL(0xfeeecaa8,0x6a14e30d),LL(0xcc7e0843,0x68bc839c),L_(0x0000005f), LL(0xc998f3f5,0xb3ae58e3),LL(0xd35d5af6,0xf29bb951),LL(0x38625415,0x552cd755),LL(0xb49fd087,0x87ef7e8a),LL(0xde9ebd20,0x76b067b5),LL(0x110309c1,0x1ece1e74),LL(0xb224505a,0x91a5a2d7),LL(0x03ba9629,0x79263dad),L_(0x00000188), + LL(0x89fcda69,0xa71b7e01),LL(0x5ba885f2,0x915b6877),LL(0xb98305b9,0x53769a90),LL(0x10c19b27,0x8d87ac0d),LL(0x8f7acf63,0x583c77c1),LL(0x64d02af2,0x6e04d239),LL(0xe5be9202,0x8f85294d),LL(0x3a5a3099,0xbb22f880),L_(0x000000d2), LL(0x9876e935,0x150daae0),LL(0xf1b9b104,0x500967b9),LL(0xe48eb13c,0xec3e5c4d),LL(0x895cf9cc,0xb6158629),LL(0x7d90f3f7,0x8aa201ea),LL(0xc0cda29f,0x0c9a6e88),LL(0x4c0d7015,0x97d1c62f),LL(0x56ee70bc,0x4fd0f68d),L_(0x0000018e), + LL(0x44d6c8a7,0x413edbb8),LL(0x792ccd3b,0x1564f76a),LL(0x72527a7c,0x2778d6f2),LL(0x45b55b68,0x67ba3cee),LL(0x6e138f21,0x5d96d43a),LL(0x38c932f1,0x63638065),LL(0x4892afee,0x6ed7c45d),LL(0xb82b82f0,0x287b4614),L_(0x000001ee), LL(0xc1bb9d4e,0xb0953f4f),LL(0x5150d18c,0x107a5e99),LL(0x67e23c2e,0x71a733f6),LL(0x2e8bfba0,0xca46066c),LL(0x1d6c6108,0x8cfb4987),LL(0x39bb5a64,0x48164ece),LL(0x0cf34f51,0x336996f4),LL(0xe99b9250,0xd6e08146),L_(0x00000069), + LL(0x921a752c,0x4008e517),LL(0x7a6c13d1,0xc5d69ab8),LL(0xc4597b07,0xc66db12e),LL(0xdbd74a68,0xca40dec9),LL(0x4579d719,0x5a617fff),LL(0x13172539,0xe3835876),LL(0x09e3b946,0x2478942d),LL(0x42d20c85,0x82ecbef7),L_(0x00000079), LL(0xda1602b7,0x5f589886),LL(0xc9ae2bbd,0x8ba22c3f),LL(0x2126ee97,0xe212b5ab),LL(0xff875595,0x389b739e),LL(0x9d6707a2,0x263595af),LL(0x87d12dd7,0x92670f97),LL(0xb014c330,0x00678803),LL(0x692f506a,0x060764da),L_(0x00000167), + LL(0x6fa9c3c0,0xa7daee3e),LL(0x99e57328,0x3e8ff84f),LL(0x8d930fda,0x140c8ff0),LL(0x29def859,0x514bf396),LL(0x6dc6556a,0x917c0e6f),LL(0x1b3aa174,0x2fd52f94),LL(0xbc6b4711,0xec0486f8),LL(0x10164218,0xfc4d6fdb),L_(0x00000087), LL(0x20fc6faa,0x143ce621),LL(0xb9fa1174,0xb63c7e44),LL(0x5ae8a4f3,0xa5424b58),LL(0x8d2b2e47,0x1058f848),LL(0xc653cf99,0x5d72c078),LL(0x9ab7f092,0x5a469db8),LL(0x0eb39c94,0xb34488b0),LL(0xd4f2904e,0xff8c9e4f),L_(0x0000001b), + LL(0x4cffe2f1,0x5b0f1fb8),LL(0x0aa30019,0xcd7cdff0),LL(0xb19b5360,0x2a32083a),LL(0x1a886b29,0x6fd83895),LL(0x3e954ca3,0xfc9e4bd7),LL(0xf6dfbbe3,0xd49474b0),LL(0xbe5e429b,0x6cfc9bf8),LL(0xb282ba89,0xd4f6b8c7),L_(0x000000b0), LL(0x5a179753,0xf0239d41),LL(0x54cf1a20,0xf833aa3b),LL(0xbe4f75ce,0x667c55f3),LL(0x210d085a,0xf20673c4),LL(0x90bc983c,0xe6d37945),LL(0x2b933ece,0x7400e31b),LL(0xa73815a0,0x0016f173),LL(0x2d12b0bb,0x04943106),L_(0x000000cc), + LL(0x258975c7,0xf8f8e68e),LL(0x93b485b5,0xbbae7e17),LL(0x21f99dd4,0xd3ee3730),LL(0x8f41688d,0x869cee4c),LL(0xa7149163,0x7ffdc064),LL(0x1dd2e6f5,0x3e9c9ee6),LL(0x3e5343f8,0x1bea26ce),LL(0xd599de2a,0xc95e92f5),L_(0x00000021), LL(0xce2962a0,0xc38ccf06),LL(0x17914783,0x5b85620d),LL(0x3066f430,0x8a55dcb5),LL(0x73026026,0x8691669e),LL(0xe37b2f3d,0x6c8abb34),LL(0xb0b3d5e7,0xe607781f),LL(0x1d40a38b,0xbd4e966b),LL(0xa4bb9c3f,0xfa1cc8e1),L_(0x00000053), + LL(0x2fc2f08c,0x61cb5b4c),LL(0xa0ed42bb,0xb44afbfd),LL(0x8be8a8dd,0x0621480b),LL(0xe9c3bbe4,0x3bbd013b),LL(0x3dad214a,0xf63413c0),LL(0xf44a0f7a,0xfedcc70e),LL(0xababaa32,0x0bd6ea84),LL(0xd282fada,0x556a1b66),L_(0x00000155), LL(0x4628c72c,0x2eb9a417),LL(0xd244439d,0xe9ea5bcc),LL(0x6a6b06e0,0xc7910063),LL(0x95bae48e,0x065bc250),LL(0x8f84ff6a,0x70b64554),LL(0x1fab9066,0xe0a46dab),LL(0xe07a85ee,0x8bdd86f2),LL(0x832625e0,0x012550fd),L_(0x0000006d), + LL(0x972aea5c,0xafed2f9f),LL(0x24dc0f96,0xe142d2cd),LL(0xa6689657,0xea2d5cc5),LL(0xae481b79,0xd0bdf4f2),LL(0x8a560bee,0x85db3226),LL(0xa5d11f99,0xfd86b657),LL(0x77ab3c4c,0x9ecb073c),LL(0x1fa5f6fb,0x59db760e),L_(0x000000e3), LL(0x246cd3c8,0x09f0d045),LL(0x3533500a,0x2990659d),LL(0x4eb8eebc,0xe68fe462),LL(0x60e87a33,0x48e37752),LL(0xcd62216e,0x703956e1),LL(0x0dcfead1,0x3a09a4d6),LL(0x491340a6,0x49d2c6bb),LL(0x0b013428,0x50df11ed),L_(0x0000013c), + LL(0x46d493a7,0xd8099e2f),LL(0x2aad5a31,0x5920a298),LL(0xb4992465,0x07aa2d85),LL(0x6aeecdc9,0xe712f629),LL(0x2a16e6d8,0x8639dfb4),LL(0x36815fc1,0x2a477d95),LL(0x0b2f5359,0x7c3ca55a),LL(0x896f9530,0x05522116),L_(0x000000ad), LL(0x41d24f09,0x208b956c),LL(0x65da1fcf,0x1c1f9a0d),LL(0x1534c8eb,0x772539f2),LL(0xb39694db,0xbc2cb67e),LL(0xf14a06ea,0xf6e48c27),LL(0x4aa51441,0xe7141d18),LL(0xbd52c5e3,0x7983136e),LL(0x77a0099a,0xd7f96b63),L_(0x000000a5), + LL(0xfe4e08d0,0x0a99ca48),LL(0xd8a3e48d,0xb1ee6ff6),LL(0xa6f4001b,0x2ec4e0b2),LL(0x04f03a29,0xe977781e),LL(0x0605bcbc,0x0f8d3aa3),LL(0xa1ff6ad7,0x052c4409),LL(0x13eedc9a,0x211fe699),LL(0x4cc42df8,0xd70f26db),L_(0x00000057), LL(0x9eae5eec,0x00258026),LL(0x08667174,0x7f49a77b),LL(0xa5dfdb47,0x0446d9f9),LL(0x6b646fc8,0x24ebc0c9),LL(0xb269fd06,0x244a494a),LL(0xd5fd906c,0x9c16866d),LL(0x27e6983d,0x545f39fb),LL(0x798c184b,0x5fdefa1a),L_(0x0000019b), + LL(0xb90f9d0d,0x1e365108),LL(0x765f67fb,0x1aae9f80),LL(0xb1b38d14,0x7a9407e4),LL(0xc8424d69,0x9693e7cc),LL(0x91d93e3f,0xba50e7d2),LL(0x385c13c5,0xd94ecd34),LL(0x6fcf73c9,0x80eb0bb6),LL(0x0d598f4a,0x1c4d4c29),L_(0x00000172), LL(0xbbeb3c79,0x3b0fb9a3),LL(0x326d546e,0x4c6d27ba),LL(0xa848cf09,0x09d2dc18),LL(0x46c0e416,0x6f0069ca),LL(0x9231b926,0x1c4aef79),LL(0xbdbead08,0x9d4dabac),LL(0x272ba195,0x8e216ceb),LL(0xcc49b720,0x83cc03ec),L_(0x000000ba), +}, +/* digit=21 base_pwr=2^105 */ +{ + LL(0xb5250d8d,0xd64c0998),LL(0x7c43b599,0x85a2ec86),LL(0x4c9f6ac7,0x59f29f0d),LL(0xfaa4ec8b,0xf16ae8c0),LL(0x2017604d,0xab8d8f78),LL(0xbb59089d,0x2772bc38),LL(0x38403982,0x6e88e817),LL(0xf3d1571c,0x7d4e8e0c),L_(0x0000007b), LL(0xea0f9192,0x477bc572),LL(0x39b5eb10,0x8d22a645),LL(0x77d71bc8,0xd769223e),LL(0x9734dc62,0xfe2b562c),LL(0x41cdb0ad,0x3173fab2),LL(0x70ddf3ff,0x997d6033),LL(0x70dbbbbd,0x6d59561f),LL(0x998a88a5,0x64aafc32),L_(0x000000be), + LL(0xdeb9f4b8,0x449a64c8),LL(0x674c0fe9,0x81603532),LL(0x01e88fe6,0x595c6e13),LL(0x913b8697,0xf6f513d4),LL(0x3b6d478c,0x88c1e320),LL(0xb2857351,0x90cfb68d),LL(0xdfb9fd43,0x6c4bb93b),LL(0xcc660149,0x3f388af7),L_(0x00000063), LL(0x23175237,0x9a5258fb),LL(0xacae0a8b,0xb741a40d),LL(0xba0560ab,0x795d005e),LL(0x3978bc6a,0xcaa47999),LL(0x1c0b2496,0x1ff04fef),LL(0x6ddcefe7,0x47c3b092),LL(0xf281ff39,0xcc93f3d8),LL(0x23027cc7,0x773c9a3f),L_(0x00000078), + LL(0x01d1f8d5,0x21f6a156),LL(0xc4591dc9,0xf7c15406),LL(0xb36c8aaa,0x3b0d0813),LL(0x287834fd,0x44ef9e76),LL(0x94a18ce5,0x52fb6092),LL(0xbd019877,0xb24d08d9),LL(0xd4816092,0x39d2d32c),LL(0x188b097d,0x5b9f00f2),L_(0x0000013a), LL(0x0979e9da,0xccda9d6f),LL(0x41dad104,0x637d2807),LL(0x4ee619b7,0x0f5a9cc8),LL(0x4f3d7156,0x97bb554b),LL(0x367054b8,0xe890a210),LL(0x3f1f61c3,0x0784aff6),LL(0xb92963c2,0xc9acc43c),LL(0x309317af,0xdadb0d3e),L_(0x000001c1), + LL(0xd52ab832,0x6d5e67b8),LL(0x049665d8,0x19993eb2),LL(0xb56e1ced,0x7a62ba87),LL(0xdfb9c1fc,0x6fc5cf75),LL(0x4712b627,0x554f5dad),LL(0xe0548bd1,0xecba89fb),LL(0x1ee24125,0xfa18f5ad),LL(0x7e176a53,0x8796b526),L_(0x000000e1), LL(0x7a9eb450,0xada0f1a1),LL(0xe4e5f968,0x89107584),LL(0x8e12a3e0,0xd6a2ba69),LL(0x1ee9c73c,0xe23b2a1f),LL(0x43a76e02,0x428e9adc),LL(0xe3d7526f,0xf09d62c6),LL(0x0557ab8a,0x37cd537d),LL(0x2758b1d3,0xe54434b8),L_(0x00000000), + LL(0x2fd63eb2,0x2d008a6b),LL(0xd28295a8,0x6d2db388),LL(0x2d6dd882,0x7d1d9977),LL(0x1f0a2196,0xa51d2cc4),LL(0x5e445be3,0x52abdb6b),LL(0x3146aac1,0x1f1b1ee1),LL(0xfac49408,0x92df369d),LL(0x84b1d832,0xf67ffdf5),L_(0x000000da), LL(0x35058c28,0xba8a7d18),LL(0xfa0e70ac,0xf53c34b6),LL(0x3063c19b,0x4954b990),LL(0xcac557d4,0x2d1447f0),LL(0xc89953df,0xc7aef4e6),LL(0x66df6476,0xcb978dd6),LL(0xc6d8f86c,0xf9c4098f),LL(0x024e891d,0x25468ae2),L_(0x000000aa), + LL(0xcf9cd67b,0x9893947c),LL(0xe7519a11,0xc44aa926),LL(0x9787209d,0xf096efcd),LL(0x743501fd,0xce9a1706),LL(0x1f7551cc,0x684716f6),LL(0x8dae5405,0x149e678c),LL(0x4cc025ce,0xa47c9f5e),LL(0xb9f91415,0x9acbec1a),L_(0x00000058), LL(0xb6fa6da8,0x1acf3849),LL(0x7e3ea9f8,0x0e3c4dae),LL(0x4d104dc4,0xadaff9d7),LL(0x5ec06e69,0x2c84d798),LL(0x553ccd90,0x93c28668),LL(0x32f13211,0x585b3068),LL(0x2907a89a,0xcdceca12),LL(0xb9c0d594,0x128fec44),L_(0x0000015d), + LL(0x7592747c,0x1698ff12),LL(0x50452a3f,0x34e63149),LL(0x70c02b2e,0xa04d3b54),LL(0x3afdb0b0,0x61ed2692),LL(0x91c5ad02,0xd6e4e6a2),LL(0x602aa43c,0x134189db),LL(0x4a9101c1,0xf2cd081d),LL(0x4ee8352b,0xf7a72eda),L_(0x00000199), LL(0xb3ee6207,0x04ba1ce3),LL(0xf4179875,0xa4294fcb),LL(0xe4a0b700,0x05833496),LL(0xb77b6e65,0x8229a64f),LL(0x204eabae,0xe9137cfc),LL(0x4ba1e0a9,0x66c9fb36),LL(0x5ece8d91,0xabbbb589),LL(0x725a0003,0x62522294),L_(0x000001a3), + LL(0xabc70424,0xfe36c3a6),LL(0x11953f80,0xd15f704a),LL(0x0b4cc57c,0x3d3a8bb5),LL(0x347df44d,0xb5099398),LL(0x3789e215,0xd81f3a55),LL(0x5f2bce30,0x853ed011),LL(0x0b7f91f0,0x20d53ac9),LL(0x8d7ec293,0x63e7bfbe),L_(0x0000005b), LL(0x232c6da4,0x56cdcd80),LL(0xc636cf5e,0x21241d8f),LL(0x6e4c3d96,0x6812f9d5),LL(0x81fb84a8,0x7741d3de),LL(0xb50a7928,0xbab3d77e),LL(0x7cc80386,0x8f374862),LL(0x1901afee,0xbf5ceb2a),LL(0xdd95591f,0xed0c8140),L_(0x0000000a), + LL(0xbfe596a3,0xf412c36c),LL(0x0ee07a01,0x426518b8),LL(0x54499ba5,0x89e701b7),LL(0x380c3953,0xf3f8a9a9),LL(0xd8749088,0x809a3666),LL(0xc559f6c7,0xe768213d),LL(0x64aff50b,0xaad0b2e7),LL(0x0535ff88,0x68771b34),L_(0x000000cd), LL(0xa5e475dc,0x7ec42d0f),LL(0x4a3e7bea,0xf9c7931c),LL(0xe0127a41,0xe2d8d114),LL(0x88a09cfa,0xc08a0d23),LL(0xa27150fc,0x052224fb),LL(0x1880e3c3,0xc80a285d),LL(0xc9c2bfb6,0xd52dcb46),LL(0xfd0b235d,0xfb31d609),L_(0x000000df), + LL(0x43934d7a,0x058ee09e),LL(0xf551f7ab,0xd68828a3),LL(0x85ee0c11,0x6925306d),LL(0x45a463ec,0x9d6c7188),LL(0xf851554d,0x962b1441),LL(0x66783d33,0x32aca09e),LL(0x856ca966,0x9146adcd),LL(0x5f7a7608,0xfe631a24),L_(0x0000011f), LL(0xe52c21b8,0x28d6e11e),LL(0x0d442988,0xc65a878d),LL(0x0f8c7ce6,0x332a94e8),LL(0xf933213e,0x0a2bf942),LL(0x055f0bf3,0x0e64c7cf),LL(0x371deac5,0x34d3b9fd),LL(0x384367de,0x6f42cc1a),LL(0x15ed6027,0x8f2a65d1),L_(0x00000198), + LL(0xe7f29199,0x1243edd3),LL(0x7356cd93,0xc68eb0e6),LL(0xfc213d5b,0xa963c442),LL(0xd8a42be8,0x426acfcc),LL(0x4e52c125,0x3019a35c),LL(0xcccbb098,0xcbc21858),LL(0xd433019c,0x687acf0a),LL(0x47525d0f,0xce5e2216),L_(0x0000002f), LL(0x4634f680,0x88d6b26d),LL(0x6dad247f,0xa7f32d3f),LL(0x70a43312,0x340a2808),LL(0xe2da73d8,0xed020b20),LL(0x477f5bf7,0x752a7c57),LL(0x84e84209,0xaf283680),LL(0xdce8d8d1,0xf2a576b8),LL(0x4e1b6410,0x6cfe6e79),L_(0x00000095), + LL(0x24f5d0cd,0xf28c9f4c),LL(0xd2aab695,0x7916e1ca),LL(0x8e97f41e,0xe9e93d40),LL(0x40703872,0xd7c8afdf),LL(0x78640530,0x8fe1f1c7),LL(0xfb5cc433,0x2060da94),LL(0x7302096f,0x953a5bfe),LL(0x62d3763e,0x4947fc61),L_(0x00000033), LL(0xc1869802,0x92108fd5),LL(0x8477b34f,0xe9b6b7e8),LL(0x31f306a1,0x306db354),LL(0xd16d3be6,0xdf966d91),LL(0x0deb9d15,0x62b5d760),LL(0x613eaff2,0x22a569a2),LL(0xae4f8efb,0x0eeb67c4),LL(0x9bca80a4,0xac4e55dc),L_(0x0000015e), + LL(0x0805ca08,0xe7b9391b),LL(0xb559bea1,0xd94e135b),LL(0xbbc93e2a,0xca27f88b),LL(0xda4f9fae,0x9fac28c9),LL(0xe1b8ef16,0x5f1ec2d6),LL(0xfd385151,0x49bb68ca),LL(0xfb07a8a5,0x55e48d66),LL(0x146bc523,0xe1490dad),L_(0x000001ce), LL(0xc95026ef,0xd3c160fa),LL(0xec69a98d,0xf736bcb4),LL(0xb1767df2,0x0bfa04f5),LL(0x48e96045,0x87d98ff0),LL(0x977f6553,0x6992858f),LL(0x17332805,0x22fe39cc),LL(0xe8ffd592,0xc326d64f),LL(0x6551c98c,0x12a83f56),L_(0x00000129), + LL(0xfb1fe590,0xdef70c89),LL(0x5d8bd28a,0xb3dcf1dc),LL(0xe969cb6b,0x157c6b46),LL(0x846f656e,0x30bef44a),LL(0x3e3ab4ad,0x14cc18c8),LL(0x63d1dbea,0x10262f96),LL(0xfe27704f,0xa567503f),LL(0x1ff786bf,0xff184f96),L_(0x000001d0), LL(0xa08df1ab,0x92281a63),LL(0x41b9f732,0x4f7c669f),LL(0x4f4c7a3a,0xd9aab809),LL(0x6fecf938,0xece45010),LL(0xbed97dd7,0x20855b33),LL(0x41c58421,0xda8500b4),LL(0x6bc3ec2e,0xf0a33322),LL(0xa1fd8aed,0xe01eb188),L_(0x000001d3), + LL(0xc846a806,0x1799b47a),LL(0x205f8a25,0x5c7dce04),LL(0x6bc7753c,0x918feeda),LL(0xb0bd3460,0xba66aed0),LL(0xfae70886,0x5d2bdd64),LL(0x37b93501,0xa85e194e),LL(0x12025c5a,0x44f97270),LL(0xb54faac3,0x98c400c5),L_(0x00000094), LL(0x3c93f521,0xabe22aa5),LL(0x3c01512e,0x99aa80de),LL(0xca5be145,0x312f55d9),LL(0x8dbfded4,0x1ca51916),LL(0x3f318a7b,0xa0b3f9fb),LL(0x42abfb1f,0x2303713b),LL(0x195a32bb,0xb6968fd2),LL(0x069ca809,0x52819c4b),L_(0x0000018b), + LL(0x7efc38cc,0x662fcdd0),LL(0xd8b1dbd1,0x66c06c9a),LL(0xaf6b6e15,0x28998a9b),LL(0xca45c4ad,0x2d2005db),LL(0xfcd947b1,0x609acb17),LL(0x6bf7b35f,0x25ebaf2e),LL(0xb8a8aba3,0x599df520),LL(0xe4302e3f,0x2bf9b973),L_(0x0000000d), LL(0x2a3c0c12,0x25aebd11),LL(0x8868630c,0xa5529c40),LL(0xaf7c4f6b,0xf5657b1a),LL(0xc0fd49e0,0x3fa70b84),LL(0x4d86ecda,0x39f53004),LL(0xc59dce6d,0x39513f7e),LL(0xbdaf7343,0x822c2924),LL(0xce22dd61,0xacb0786e),L_(0x00000066), +}, +/* digit=22 base_pwr=2^110 */ +{ + LL(0xf20e8c4b,0x55dedb27),LL(0x5a0fc338,0x03e8af53),LL(0x788ccd88,0xe10cabd0),LL(0xa1f1f7d6,0x5f889d7f),LL(0x0487ee35,0xa583e303),LL(0x1885d800,0x2fc9f3dd),LL(0x09ae9a4a,0x2887b5bf),LL(0xa554fc30,0xd91181d3),L_(0x00000078), LL(0xcdca6316,0x53b146d6),LL(0x52f280d5,0xdfaac466),LL(0xe0b73d63,0x0d77869d),LL(0xa8a399cd,0xba5ffe6a),LL(0x5c61b757,0xaffc1da6),LL(0x71cf6c9e,0x34d27387),LL(0x20ae1248,0xf184b956),LL(0x7f6504de,0x1c974cb4),L_(0x00000176), + LL(0xc1efab45,0x659b9b53),LL(0xd37156ff,0xf8338bab),LL(0xa115d2c7,0x9d1175b5),LL(0xa927371c,0x53c22d6a),LL(0xe5b07da3,0xb79ee37b),LL(0x3585421c,0x8ac92029),LL(0xbe2b0a93,0xd489e47a),LL(0x363622f3,0xccd5811b),L_(0x000000c9), LL(0xf506ac3d,0x41cb54f0),LL(0xbf83fb74,0x527b4fee),LL(0x7d9fa2d5,0x6d4a3597),LL(0xf8ab4037,0xe4619c87),LL(0xd590e945,0xab913b27),LL(0xe8861075,0x389b1da0),LL(0xd8fb707f,0xe0beb49d),LL(0x35140b6f,0x392dd172),L_(0x000001f7), + LL(0xe7bedc7f,0xbf4176d0),LL(0xfe15067e,0x0120bf23),LL(0xc1d45172,0x0cb82143),LL(0xfbe2cf59,0xb0e80076),LL(0xd69fd57c,0xbd9b2caa),LL(0x78503bca,0x99823d72),LL(0x2730e435,0x31cc7be0),LL(0x4b145b24,0x10f8d6e3),L_(0x000000a2), LL(0xad5f8d1e,0x4fc47dab),LL(0x7a72c91b,0x564e5846),LL(0x5530b4bc,0x1837936f),LL(0x9913d2c3,0xdf60105f),LL(0x5f1a5851,0x839ef0be),LL(0x3d6d7b8d,0x05890a65),LL(0x48845fee,0x57eb20fa),LL(0xcc1288ca,0xf7b7e05b),L_(0x000000ac), + LL(0xdf12457e,0x7082a01c),LL(0x50e34426,0x91616bf5),LL(0x27cfd7b1,0x426bd9ae),LL(0xc299bf54,0x5f468d0e),LL(0x0487ca37,0x695e6354),LL(0xb93aa7dc,0x9322f558),LL(0x8f48edec,0x818f0592),LL(0x957ee742,0xaca5b088),L_(0x00000123), LL(0x85008e45,0x11189720),LL(0x45a01307,0x348cb9e4),LL(0x5bf246e5,0xf5c183c6),LL(0x3fd8ccf1,0xe9a40aeb),LL(0x0fbda6f2,0x087abdef),LL(0xdaf09cee,0x90c450f5),LL(0xe33344ee,0x3abe1073),LL(0xa3404424,0x02a065d1),L_(0x0000018f), + LL(0x9dc26b1a,0x5faa9290),LL(0xbd275c4d,0x69ab8c9c),LL(0xebf0d548,0x7a6bc4a9),LL(0xe5ed16cd,0x31faf28e),LL(0x3e681735,0xcf90331c),LL(0xc624be8b,0xfb66de1c),LL(0x42603696,0x2a65b006),LL(0xc07466ec,0x9d7f9688),L_(0x000000f3), LL(0xd25f7e3b,0x44e0d6d8),LL(0x3db25f9e,0xe7ca860d),LL(0xa581c150,0x1c6481b3),LL(0x49e5b0b8,0x62060736),LL(0x82bc7eb1,0x54daac9c),LL(0x376c43d1,0x68353454),LL(0xfb293af5,0x2dde1795),LL(0x7e2ec37f,0xed4ef8f0),L_(0x0000019b), + LL(0x9a308462,0x4adfcff9),LL(0x2b928ce2,0xb2e63ba3),LL(0xd02f461c,0x73336d0f),LL(0x04fd6cc5,0x48e88a3a),LL(0xc377597d,0x56c730e8),LL(0x5ac92cdd,0xaf7486b7),LL(0x0317d853,0xe151b910),LL(0x0978da40,0x86c35051),L_(0x0000000e), LL(0xe9b441de,0xb333edf0),LL(0x1ff77a8a,0xd24f0df5),LL(0xed7f23b9,0xdfae6385),LL(0xaa4f024f,0x2a1af93e),LL(0x2ffef5f6,0x6f45d8a5),LL(0x9aa11e63,0x853bb088),LL(0x2271f40e,0x8ed5445f),LL(0x3ccb38c1,0x24afc179),L_(0x00000027), + LL(0x6a440850,0x57906522),LL(0x85f7ceb0,0xce569864),LL(0x059b3177,0x45f8df95),LL(0x60efada7,0x2ee7a947),LL(0x87aafc1c,0xdce2c588),LL(0x17fd804d,0xdcf2f1ac),LL(0x10e82f62,0x4b1309c3),LL(0xe852efd4,0x0ef30c42),L_(0x0000012f), LL(0x62278fee,0x95ed2fc9),LL(0x55cd2f37,0x5d0e9c83),LL(0x107085fd,0x479d2ac2),LL(0x85ff5e6a,0x7bd3eb35),LL(0xd6ed74ec,0xc8a77d96),LL(0x366d8e34,0x3be40939),LL(0xf0ec3c90,0x11212f04),LL(0xc317d540,0x5743bb20),L_(0x00000152), + LL(0x8145236d,0xffb66d41),LL(0x6ea70c3f,0xc5491789),LL(0xcb17d54f,0x1eaf6e4d),LL(0x7c642a64,0xb15be10c),LL(0x99328296,0x611efe5f),LL(0x30829e9c,0x3cdec049),LL(0x5f18e861,0x1a7c38da),LL(0xab7985a5,0x3536d908),L_(0x0000018f), LL(0x47f989e7,0x8ece50b4),LL(0x5435f6e4,0x13d04672),LL(0x60505d74,0x07efc4e5),LL(0x8a551fa9,0xcc601ad2),LL(0x8fed3391,0x9eeaf4b1),LL(0x4338a854,0x72c52e1a),LL(0x61868d33,0xce70bb6b),LL(0x9c3a511b,0x5c8d75eb),L_(0x0000001f), + LL(0x8d15261e,0x69ee64f3),LL(0x508ada39,0xdd8c7134),LL(0xda598cbd,0x36c545ec),LL(0x05133eca,0x0c3f5caf),LL(0x2df79eab,0x71cd5c2a),LL(0x920bc258,0xfa67ae73),LL(0x1fd1e4a4,0x2ed2d89b),LL(0x48726f90,0xd5a8956c),L_(0x000001ab), LL(0x02aa7b62,0x6f23ba5d),LL(0xb20e4dfc,0x4bab12af),LL(0x5fcc6747,0x0006c88a),LL(0xaa6ea9a8,0xe8e4646f),LL(0x9db86f5a,0x8f1f8a76),LL(0xec7745fa,0x455291dc),LL(0xe15a4259,0x155de9ad),LL(0x6c3a6e93,0xf9fdf6e0),L_(0x000000df), + LL(0xab1b0548,0x3dc752ef),LL(0x14921ae6,0xdad5624e),LL(0xf829dec8,0x1d1460ab),LL(0x5833de5b,0x9c1ff203),LL(0xd5ded33e,0xfac09cf2),LL(0xbb7c2ad4,0x82d6f980),LL(0xf32dbe91,0xad650ca0),LL(0x82ca75ed,0x6c58e180),L_(0x00000033), LL(0x00ff7cd0,0xea9d2225),LL(0xd3ca85cc,0x434cfef1),LL(0x3bb6dff7,0xce357f60),LL(0x56328ba9,0x0e4a179e),LL(0x4a4804e3,0xe56b9eac),LL(0x254a5b01,0x72a81cd7),LL(0x8b35d349,0xe054875e),LL(0xc8c87ac4,0xe8c11607),L_(0x00000015), + LL(0xc31fc004,0x1c6cc43f),LL(0x6f96d167,0x794436fa),LL(0x586761cb,0xd20a52b3),LL(0x3ae24479,0xc24cf7e8),LL(0x5d299550,0x7aabd2b7),LL(0x9cea4b13,0x09feb305),LL(0xd75ffb4e,0x5b6a28d7),LL(0x5d3cd9c7,0x4d85737b),L_(0x00000063), LL(0x1e01bfde,0x743b9f5d),LL(0xe042f5f5,0xe03225a4),LL(0xc7dc3d4b,0xdfce41ae),LL(0x51cdf46c,0xd3c05da2),LL(0x69bf3a35,0xc18cbac7),LL(0xc0889d43,0x51fc0084),LL(0xf694d481,0xbfa4cfd4),LL(0x05438a3a,0xcb44f4a9),L_(0x000001cc), + LL(0x3e7e05df,0x22d68d2a),LL(0x6f65a633,0xd77949bf),LL(0x368db479,0x738f46ed),LL(0xe52e22f5,0x7212d465),LL(0x4758d194,0x8bb783e2),LL(0xd677a59c,0x1b239d33),LL(0x60904604,0x9c2f2775),LL(0x8df6497a,0x9be5339a),L_(0x0000007a), LL(0x08475032,0xb5804d78),LL(0xbd5cd190,0xbfbebfb6),LL(0xd58769b6,0x66d25685),LL(0xf9ea5b23,0x206ac283),LL(0x09d14a84,0x845e93a9),LL(0xe03b612f,0xc6807818),LL(0x061fa312,0xeb980705),LL(0x6b501efd,0xfa3670b6),L_(0x0000003c), + LL(0x6257d98f,0x509702e1),LL(0xaf686102,0xc4201f85),LL(0x800e44cf,0x7e6e7641),LL(0x35e4ed58,0xa3fd838b),LL(0x5af78edd,0x728e86da),LL(0x0effaedc,0x6fd05e38),LL(0xfd668fa4,0x4ebcbbb8),LL(0xe45dbf60,0x21bf82d8),L_(0x0000016c), LL(0x8050d329,0xf066dcdf),LL(0x1ca3b2b7,0x73890298),LL(0x96fc550c,0xcc4f19d8),LL(0xfc004a6a,0xc9fae54f),LL(0xcdd730f4,0xa5e22c5e),LL(0x2754c10a,0xb60dac89),LL(0x49c473e4,0xd5465b8b),LL(0x30fa2831,0x14688f19),L_(0x00000175), + LL(0x4fd6e5bc,0x8f88f135),LL(0x7034290c,0x2f4cd77e),LL(0x61556d3d,0xe5aea948),LL(0xee182466,0xf7fd60b4),LL(0xfaab2132,0x2107919a),LL(0xb164b7c6,0x4909986e),LL(0xb4de2fa4,0xe1076a94),LL(0x331fc36a,0x8fd3234a),L_(0x000000d4), LL(0xee34ec46,0x07524382),LL(0x3f9109b1,0xec9a0d40),LL(0x11cb9eb3,0x7e1084f2),LL(0x1e06d740,0x00717031),LL(0x2928ea89,0x4bde88cb),LL(0xd69d113b,0x20f91a03),LL(0x2ff2dbf3,0x7a3884fc),LL(0xdf24441f,0x198806cf),L_(0x0000012a), + LL(0xf9b6b90b,0x076f7438),LL(0x1544e142,0x15274247),LL(0x022e14c5,0x96077c3c),LL(0x30862489,0x789e3935),LL(0x50c53e4e,0x1141fcf3),LL(0x3047c405,0x2cd7f2a5),LL(0x57a60daf,0x9bc52e3e),LL(0xcd0ce692,0x21830d42),L_(0x000001a9), LL(0x37349784,0x77ac72bb),LL(0x403e48dc,0xad70038c),LL(0xc084214e,0x170491ff),LL(0xf7b0b5fe,0xd8cf2d1c),LL(0x4af0ed5d,0xd8301c30),LL(0x00208a5b,0x33f56a54),LL(0x18e018d4,0xfa224eea),LL(0xef56c21e,0xaa9262c2),L_(0x0000002d), + LL(0x0c9bed5e,0x328296f3),LL(0x4bb11c1f,0x6050199a),LL(0x15b40849,0x53a7ca7c),LL(0x81bc50ce,0x0a2c1da2),LL(0x682873f5,0x52c0e34f),LL(0x44102170,0x9c5ef21f),LL(0x9f354fbc,0x0bba954e),LL(0x6cd7990a,0x02432a32),L_(0x000000a4), LL(0x976d76d3,0x2be6dddd),LL(0xe55cac7b,0x8a3b8a57),LL(0xda37392c,0xec1dc93e),LL(0x2e3fecd4,0xcf4f78c9),LL(0xfedf3f09,0x1ff689fe),LL(0x03374052,0x092dabd5),LL(0xdf4087ca,0xb9e4e110),LL(0x9d02763e,0xf3f329b7),L_(0x00000089), +}, +/* digit=23 base_pwr=2^115 */ +{ + LL(0x016c8d9b,0xbd54382d),LL(0x826f7b17,0x32c36ec7),LL(0xdce64f28,0x22a16680),LL(0xab2193ae,0xaf6a85c2),LL(0x52cc0a0a,0x2f202702),LL(0xcc1335b3,0x2afbf317),LL(0x3743776e,0x0deb4740),LL(0xf9a19900,0x61591f25),L_(0x000000bc), LL(0x2800729e,0x1d84eebf),LL(0xb06a4eb6,0x8bb72608),LL(0xb23e7396,0x2e886104),LL(0x992a3ae8,0x7c8605d2),LL(0x418a91d2,0xe33bec6e),LL(0x5f2b49e6,0xa9d829d4),LL(0xd1f4a3f4,0xeb2f044b),LL(0x28bc4cea,0xb1ef09fa),L_(0x00000063), + LL(0x611f97e2,0x04826845),LL(0x6b1ee54a,0x9240015b),LL(0x608b1dc0,0x25698b8a),LL(0xa1390509,0xb5e532ad),LL(0xdf4acb31,0x30c41c46),LL(0x16e05bee,0x07d190c1),LL(0x642c1273,0xb566eca9),LL(0x1b365a48,0x5c3cffa2),L_(0x0000006d), LL(0x9754189b,0x21b8836b),LL(0xa0057686,0x520f579e),LL(0x7bf51510,0xa43d38cb),LL(0x0a4bbc0c,0xfe21891a),LL(0x687446c9,0x1242b093),LL(0x8feab881,0xcacb6d61),LL(0x7a921f31,0xcf611aa4),LL(0xc5cb09d3,0xfef9a8ef),L_(0x000001d8), + LL(0x304ccf54,0x4375da6c),LL(0x13287748,0x4fda63b3),LL(0xfa3518ec,0xbc16ce7a),LL(0x996ffb04,0xf3ffb5fd),LL(0xf0a2d30e,0x6da8bb6d),LL(0xa23e83a8,0x08e806aa),LL(0x0642e4da,0x0286c1dc),LL(0x84837dcb,0x8196eb23),L_(0x000001ac), LL(0x584182dd,0x1c8d1ec4),LL(0x9c108506,0x77ca438c),LL(0xdc8649fb,0xdbfc198f),LL(0xaf929bb8,0xa5fbf701),LL(0x60078f43,0xe25fdf9d),LL(0x3f03bcb4,0xca36812b),LL(0x53c1eaae,0xb394d3a9),LL(0x1f8445ff,0x78a7b4ab),L_(0x000001eb), + LL(0xf50749b9,0x6d42c81a),LL(0x40e01936,0x7487e815),LL(0xd6072e7b,0x32da913c),LL(0xe7b4156c,0xf1e87478),LL(0xb217423d,0x4880f5cc),LL(0xca344dd5,0x90182347),LL(0x15da2c26,0x87d2337d),LL(0x8d993e28,0x604cc23f),L_(0x00000179), LL(0xc2ec9c0a,0xf9778d40),LL(0xc9dd1808,0x4345027e),LL(0xdcd7b63f,0x198a63ab),LL(0x03bcf65f,0xa7a4c388),LL(0x1130c2d3,0xb476f99f),LL(0xc1ea5019,0x991ad6b9),LL(0x4f67377e,0xa9f5ad13),LL(0xd99047df,0x80641e2f),L_(0x000001dc), + LL(0xdc84c719,0x2a4af296),LL(0xf45a67c1,0x963ea378),LL(0x3fc32889,0xe19e2266),LL(0x2477017e,0x3e1c3af5),LL(0x1bbfecd7,0x9c6aea32),LL(0x03afdf5f,0xdd92f5ef),LL(0xd2ffd177,0xcff66e71),LL(0x22d56579,0xca369a53),L_(0x00000122), LL(0x5689a8bb,0x3ecebaa8),LL(0x87cbd3db,0xfef4d6ca),LL(0x92b7d8a0,0xf81b8c47),LL(0x4e50ecbb,0xdd6768bf),LL(0x916361ed,0xf3c09bf3),LL(0x6b31d1bf,0x54e2879b),LL(0x17c7f544,0x44b470e7),LL(0xb6fa811a,0x32df7372),L_(0x000001e9), + LL(0xfa7af75f,0x83de0d9d),LL(0x7ea57102,0x4652ceba),LL(0xdd543523,0xb8a36856),LL(0xb586f821,0x19e00261),LL(0x6ce309c3,0x1ed079e5),LL(0xe0f75ac3,0x51ff1099),LL(0x2442020d,0x0c077aee),LL(0x248b83fa,0xc85e1f87),L_(0x0000006f), LL(0x8445d10a,0xaf872b79),LL(0x311d3108,0x2ca2a32b),LL(0x5040c97d,0x4fa4c2f0),LL(0x7615703d,0x80d5eb27),LL(0x36c8c169,0xb5f074a5),LL(0x95daa1e3,0xbda91813),LL(0x672dad89,0x395bd4fb),LL(0xf61f3d94,0xc4a2c81e),L_(0x000000b4), + LL(0xa1b80edf,0x04e91ed9),LL(0x861a2094,0x2bca8d77),LL(0xca4ca01a,0x03590793),LL(0xf16fc210,0xc8ad1877),LL(0x48a85346,0x89666be4),LL(0xf0fc0cfc,0x6adba857),LL(0xcd27d0e4,0xdc6000be),LL(0x66de6f3c,0x410cd2f9),L_(0x000001a3), LL(0x97174f70,0x27a30017),LL(0x3566e721,0x523a0305),LL(0x793773f0,0x1ee9afff),LL(0x7fd66850,0xdbc711c7),LL(0x047ae5ad,0x3acae945),LL(0x203bb8df,0xb932a42c),LL(0xfe2439ff,0xd51dba9f),LL(0xe4630688,0x268de595),L_(0x00000036), + LL(0x56ff8468,0xcb924e78),LL(0xf61f664c,0x2e404ee4),LL(0x5ac67cb0,0x6b002de5),LL(0x87550da7,0x537e3c3c),LL(0xb6b43fc4,0xcc36c052),LL(0xb2d5ce01,0x0c5bb204),LL(0x8e7f6d0e,0xf930fde8),LL(0x09c188bb,0x056f87d9),L_(0x00000168), LL(0x68bd3a01,0xbd1106b6),LL(0xe76203aa,0x0182e8dc),LL(0x02fff311,0x1307d3fa),LL(0x96bf7d1e,0x71013392),LL(0x6ed2ca34,0x24a22e45),LL(0x1b668eed,0xe4102d01),LL(0x79cf95e5,0x681d10cb),LL(0x6c6693b0,0xf94e08ac),L_(0x00000155), + LL(0xec2c327b,0x4ea63be4),LL(0x7d917da9,0x5de2c336),LL(0xadecf30f,0x0955c66b),LL(0x81dabb28,0x6e473865),LL(0x19491209,0x1d9702d7),LL(0xa1f53ee2,0xa4bef482),LL(0x26877597,0x0315b12f),LL(0x18b70eae,0xbca15f03),L_(0x00000095), LL(0x28dc543a,0xe0496daa),LL(0x1afe44da,0x518d4571),LL(0x824106af,0xf72d3376),LL(0xa6b1f64c,0x1149d145),LL(0xbe64f34b,0x8c71ca30),LL(0xd7b0b0f7,0x3acfa7a5),LL(0x58a3ea6e,0xcc0bc394),LL(0x5e42d97e,0xe6ba0355),L_(0x0000009f), + LL(0xb9413a50,0xcc323242),LL(0x25b57cdb,0x0afacd89),LL(0x4d31e696,0x075e88b1),LL(0x80ecc1c8,0x4d853d58),LL(0xe213393a,0x5c2d17b4),LL(0x1d02b340,0x29f6c35a),LL(0x7f4eb22a,0x763f945f),LL(0x991b6570,0x38d9e916),L_(0x0000008a), LL(0x8faf74b7,0x919e262a),LL(0xcdb707d0,0x7b3ccd89),LL(0xc28362e2,0xe31adec3),LL(0xd970a8d2,0x2e5340b0),LL(0x11f1ff4f,0xb76d44ac),LL(0x42bd388a,0x528cddee),LL(0x2165e718,0x7cb055f5),LL(0xa8c2384a,0xd81cae87),L_(0x0000003b), + LL(0xca0a6c60,0x95c8885f),LL(0x504d777f,0x6a9d125d),LL(0x327807d9,0xd624f272),LL(0x0e53c679,0x95ea222f),LL(0xe1387ac7,0xb1597752),LL(0x656acd9a,0x352cac8c),LL(0x6190d15d,0x61bf8856),LL(0x01af7e20,0xc719ce43),L_(0x0000007b), LL(0x3f4af185,0x83f36452),LL(0xfdd73cd6,0x314de5cf),LL(0x46e7aa4c,0x50ce899f),LL(0x7424d707,0x38e875fc),LL(0x3221445c,0x9f3a7a99),LL(0x974ba6c9,0xe06eb667),LL(0xcc871495,0xffe48ed2),LL(0xda22c28b,0x34965180),L_(0x000001bd), + LL(0x067ec5b4,0x8ee0ef29),LL(0xfb175926,0x1c82db3e),LL(0x93d33d24,0xb912da50),LL(0xbb15ebc6,0xcea7d557),LL(0x53132904,0x2a95c0c2),LL(0x1728bce5,0xd703338d),LL(0x3e934774,0x9ff62322),LL(0xa4bdaa17,0x5a25267e),L_(0x000001c0), LL(0x490cbf77,0x4db3f1bf),LL(0x49cf21d2,0xa18c0ec0),LL(0x1567c730,0xf359d391),LL(0x8f78c3e0,0xa1bf7eca),LL(0x9f9aa64e,0x4252d4d8),LL(0x5b2ffd6d,0x3cf77a2e),LL(0x70d5197d,0x420f1fde),LL(0xc4ac046e,0xfbaabfd6),L_(0x00000182), + LL(0x114c23ed,0x6f164190),LL(0xacca9818,0xdc3afb13),LL(0x75acc7ba,0xf8e7944e),LL(0xaec6267e,0x266c89d3),LL(0xc0d5983e,0x7a35b6ea),LL(0xc7025ed3,0xcc6f8ba4),LL(0xb3a78dfe,0xe18e7845),LL(0x43ed79a0,0xd3e423c7),L_(0x0000001e), LL(0xf7626a80,0x7ad878cd),LL(0xf2ddd3e7,0x7ad2ccc8),LL(0xdd3af93f,0xe988a2b1),LL(0xc20e3266,0xf31777a1),LL(0xc508e478,0x5f61decf),LL(0x6ca64937,0x38c983d0),LL(0x63f7f656,0xffbb003b),LL(0xff837029,0x32104839),L_(0x00000105), + LL(0xbf81b286,0x0f23d833),LL(0x787960d2,0x1a82d064),LL(0x1e23da2c,0xf31fd1ab),LL(0x632fca0d,0x67beaa32),LL(0x48f5480d,0xb9e45d26),LL(0xbb162f9b,0xd434d563),LL(0x10e02089,0xa10eef01),LL(0x647082d3,0xb7735d1d),L_(0x000000b7), LL(0x701e6ecf,0x40d95b89),LL(0xe61d29d9,0x68b4d3bb),LL(0x1c7d5b4e,0xd78df4bc),LL(0xbd612a5a,0xd83302ca),LL(0x80982747,0x511140b2),LL(0x754f6279,0x16e7211a),LL(0x1d43610e,0xf0dec954),LL(0x3999e665,0xbaca9f0f),L_(0x000000e6), + LL(0x61d2f78d,0x38877144),LL(0x1ee1b012,0xed46bb99),LL(0xf5e943b8,0x376d8b60),LL(0x1bc6b4d7,0x4b6cb863),LL(0x7dc297da,0x216481d0),LL(0x123486d4,0xc754e76d),LL(0xb1c0a1e8,0xdbcf937b),LL(0xadf930fc,0xdaf06ef4),L_(0x0000013b), LL(0x843220dc,0x03210a22),LL(0x979dbfb5,0xd444dbbf),LL(0xd232212a,0xef6c2520),LL(0x35e7b199,0xee0108b0),LL(0x21bd8267,0xe6dba29f),LL(0xc9483241,0x8b0b6ada),LL(0x304a26d8,0xebc36edd),LL(0x88b58b4d,0x0b4cd577),L_(0x0000009d), + LL(0xb2d92526,0xee657257),LL(0x208861aa,0x5d4bf915),LL(0x8adfc02b,0x8b2a8792),LL(0x51bf7839,0xd1929e39),LL(0x6ac2d82c,0x51878fc6),LL(0x2453f26a,0x67c6a197),LL(0x0ebd963c,0x29e6f9cc),LL(0xab6feb88,0x6a8aecc7),L_(0x00000098), LL(0x8df74f15,0x9f30636d),LL(0xe6a5beb0,0x5f6af11d),LL(0x247b3767,0xa04301fc),LL(0x7893d122,0x577167d7),LL(0x4d974f3f,0xea69addd),LL(0x983fc60d,0xd35bf8be),LL(0x627055a8,0x95c80a83),LL(0x51c83aaf,0xa21f06b1),L_(0x0000009a), +}, +/* digit=24 base_pwr=2^120 */ +{ + LL(0x664d27c9,0x1dc1e136),LL(0x3cf04eac,0x1c4f5e85),LL(0x599f9890,0xcbc44867),LL(0x34ff0e3e,0x5a12a7f8),LL(0x851c12ee,0xf066c152),LL(0x7ca61be6,0x73832df9),LL(0x7153da2c,0x14acdbe2),LL(0xb73e882e,0x87567338),L_(0x0000010b), LL(0xde5b00ae,0xd1fe8148),LL(0x05fd56d3,0x49ee53a4),LL(0xe986a7db,0x11101981),LL(0x695cf7bc,0x750760e2),LL(0xb6aca2a9,0x4815cb90),LL(0x9f5ace2a,0xc3dc9f29),LL(0x6b06b61b,0x3b28698d),LL(0x6b2e5c22,0x5687880a),L_(0x0000000b), + LL(0xe5d59cd4,0x1af552c0),LL(0xaaadcddf,0x160c329a),LL(0xf071e91a,0x77f33e93),LL(0xf9cbbaf7,0x6e836178),LL(0x74f3bc69,0x430ecc6d),LL(0x349ec647,0x9e682571),LL(0xbbec63ff,0x3f624e0d),LL(0x64eff8b4,0x0d19e23a),L_(0x00000000), LL(0x84cb54f8,0xce60d534),LL(0x3eff3832,0xe89d00d8),LL(0x12f600da,0xf8745dbd),LL(0x3eb89d2d,0x48217cd8),LL(0xe79b868a,0xc5ce0f8a),LL(0xc2c4ae44,0x0fe94021),LL(0xa980ca2b,0x5ab9482e),LL(0xf0414674,0xcffa33fc),L_(0x000001c2), + LL(0xfd99bf9e,0xb176fd51),LL(0xa2b01fa7,0xbebf27e3),LL(0x1a17875c,0xca98073a),LL(0x1a08df20,0x73873253),LL(0xcea9581c,0xdc360b05),LL(0xbad316bf,0xb8a68986),LL(0x9591db5f,0x6941db20),LL(0x838ce851,0x0df495ad),L_(0x000000d5), LL(0xa5b29337,0xb5d46b24),LL(0xf0d09b27,0xf2b04a4a),LL(0xe34ef392,0xc4e0cb50),LL(0x9c028d0c,0xbe127061),LL(0x60b8995b,0x202d9276),LL(0xa9beaf92,0x3a61c444),LL(0x686effea,0x7cc238c3),LL(0xce321e42,0x09075147),L_(0x000001e6), + LL(0x4c62b53e,0x16e9dd16),LL(0x8a3599a2,0x05317187),LL(0x0821091d,0x24ef2697),LL(0x6ed2cda3,0x4950f2f1),LL(0xeaefd2e9,0xc815b553),LL(0x9f00612d,0x47c1f801),LL(0x930eacc5,0xfd1730a1),LL(0x136fc4a1,0x8252d52d),L_(0x000001b8), LL(0x6c4bee68,0x6b77522a),LL(0x2deb3842,0xaea9f6b1),LL(0xca869197,0x3823d16a),LL(0x187c4319,0xf12c9d38),LL(0xd5cc9828,0xe31f43da),LL(0x436529c3,0x0781728a),LL(0x63d40c6f,0xbfbb0978),LL(0x94da1798,0x7a196933),L_(0x000001e1), + LL(0x820f8b6c,0x95a20633),LL(0x4ce60573,0x98b05888),LL(0xb9e9ac42,0x9f28e7bc),LL(0x770f80c7,0xabb15751),LL(0xd0147212,0xcce75763),LL(0x67296f82,0x8034afbe),LL(0xa2950d9f,0x11791412),LL(0x9731ca6f,0x87c616f9),L_(0x000000bb), LL(0x004bd5df,0xc7f27dc8),LL(0x5fa5d017,0x95bcc4fc),LL(0x9fdb4deb,0x39917e40),LL(0x30051c1e,0xbefa777d),LL(0x3f36dfcf,0x26ebd51f),LL(0xd9696a85,0x16cc089e),LL(0x58a6c0bc,0x6723f03c),LL(0x3193efb5,0xe4f7a675),L_(0x00000177), + LL(0x63cd0fae,0x0082edbf),LL(0x7ff0d41a,0x1522ffb6),LL(0x76aa53cf,0x453dcda7),LL(0x3ac99dda,0x634bcd8a),LL(0xca31a6bf,0xdf09af12),LL(0xda6aee65,0xb96045d3),LL(0xb2e1c131,0x6f3c7e70),LL(0x72188816,0xcb58f8b9),L_(0x00000121), LL(0x1dcdf91d,0x51f3e032),LL(0xd4da7b11,0xcafbe9a8),LL(0xe3a95788,0x39c010af),LL(0x8c87071e,0x05cb3faf),LL(0xafcfc04b,0x08a702fb),LL(0x42c775b7,0x5b3b6187),LL(0x8aab53d6,0xb84f9386),LL(0x8bb27ffb,0x08491b70),L_(0x00000075), + LL(0x4b15dd19,0x2f20328d),LL(0xb581eaa6,0xd269e274),LL(0x8fb2a285,0x604b1779),LL(0x5b26ea89,0x3aa53ad7),LL(0xd5119e93,0x9fa62691),LL(0x3e002a94,0x8ba167e0),LL(0x62921501,0x195dffb0),LL(0xe4ae2796,0xdc1f93ea),L_(0x00000082), LL(0x1f7743f2,0x980977c6),LL(0x654950f7,0x422ba8f7),LL(0x9f0fcf77,0xb7dc1d4c),LL(0x6b970562,0x0b2f7617),LL(0x2de6068f,0x894ad6c1),LL(0xd3457950,0xe569d53d),LL(0xfc63f78f,0x14981ae1),LL(0xf2a90b52,0x902dadf9),L_(0x000001ab), + LL(0xd7474a9e,0x5406fc86),LL(0xc759885f,0x5bd2a491),LL(0x2d4cddc5,0xc35aa122),LL(0xb5461045,0x2154985e),LL(0x188b457a,0xff0dcbe4),LL(0x235148df,0xd70c6a7e),LL(0xa2535a30,0x7d8e9016),LL(0x6be2be33,0x99a19ee9),L_(0x000000f8), LL(0x747030fd,0xa1dc1860),LL(0x519771ba,0xea4c9a1d),LL(0xe6bf7f8d,0xc44825c6),LL(0xfd4b88d5,0x48270d80),LL(0x619d7b16,0xcd7c088d),LL(0x50ac4887,0xcc2ce67f),LL(0xd1ac72f9,0xaafa6b89),LL(0xafdce091,0xb9365de8),L_(0x000000c9), + LL(0xb743d17c,0x7862482b),LL(0x264a6de7,0xcc327c76),LL(0xf0e8036a,0xdd64bd2f),LL(0x58aff74c,0xd63e620b),LL(0x0d34c089,0x792f3b2b),LL(0x3cffd08d,0xb8e40e30),LL(0x2466d774,0x5be025a8),LL(0x83e235d8,0xe9d3cf63),L_(0x000000e7), LL(0xb1498ace,0x93020cb2),LL(0xfef8d504,0x75b3c700),LL(0xa8404df1,0x1f7b3ca4),LL(0x25cfc4f3,0x3dca1055),LL(0x21fc5f18,0x73402205),LL(0x096d5dd9,0xf8afba2b),LL(0xe13c530e,0x23634751),LL(0x7b6b3f2e,0xca1be461),L_(0x00000076), + LL(0x544eb7eb,0x662154b2),LL(0xf439d6d1,0xc1e155ac),LL(0x0ae5f642,0xa2dd72ce),LL(0x55e79db1,0x71c8da23),LL(0x7905f65a,0x29ffbd0d),LL(0x21383ef6,0x39515d47),LL(0x28c8f708,0x739d692e),LL(0x67130a0a,0xe8283125),L_(0x00000098), LL(0x8eb8a388,0xe6e2797b),LL(0x7f499c43,0x57f047a7),LL(0x8571cbc2,0xe0447784),LL(0x8f068f3b,0x85efc6b1),LL(0x9497bb27,0x4b52e9d2),LL(0x5f954c9e,0x896bc179),LL(0x299e982a,0xfe335eac),LL(0x2fe557d1,0x15ed5037),L_(0x000000c8), + LL(0xc3bc83c7,0x45022f8e),LL(0xe4a9bc90,0xcb58c8df),LL(0xd48d6951,0xf9950f95),LL(0x3a67fa88,0xcfc52411),LL(0x8aad81c0,0xea907dba),LL(0x193feef4,0xbcf6e329),LL(0x847c4744,0x51539dcb),LL(0xbfaf49f8,0xe1705ff1),L_(0x00000189), LL(0xe91285a5,0x7e920920),LL(0x93070144,0xf4a966bf),LL(0xebc39792,0x26b6e21a),LL(0x5380b22b,0xe6fd22df),LL(0xf5ce884f,0x866ea333),LL(0xbbd94169,0x3e0f11de),LL(0x3a3c3087,0x2fd9dd8d),LL(0xefe676ed,0x227a4771),L_(0x00000016), + LL(0x429e8a22,0xe1817fcc),LL(0x7ff2aece,0xe4758b83),LL(0x15a3e785,0x768947ca),LL(0x54660e77,0x2c352eca),LL(0x1486538c,0xaac39b78),LL(0x86e8fec5,0xaa608004),LL(0x414e550f,0x32acb85c),LL(0xa6493364,0x2fd7f2f3),L_(0x00000099), LL(0x2b5bf57f,0x92784c4d),LL(0xcdd72f6c,0x18258546),LL(0x7a0d4685,0xabc0f043),LL(0xa00c87a4,0xfab6104e),LL(0xd492feca,0x0edfb4e6),LL(0xd10ae319,0xa0ad3d18),LL(0x74331002,0xb3e27cea),LL(0x1c928b0f,0x43d33a89),L_(0x000001cb), + LL(0x4af6b119,0x7f32173f),LL(0x5c89c248,0x82306719),LL(0xa569342d,0x5318cae6),LL(0xaf11c888,0xb3871b59),LL(0x43ea3a04,0xccb1894e),LL(0x7d6e369f,0x584ca2b8),LL(0x4a0018e5,0x01476d73),LL(0xc7bd79b4,0x6328258d),L_(0x0000017f), LL(0xfc19d3b7,0x607af994),LL(0x27381ef0,0x686aee98),LL(0x28efc122,0xe773f07b),LL(0x1e1202b4,0xb162dfca),LL(0xd4141270,0xfcd08076),LL(0xdb1eed20,0xd4dbdbd9),LL(0xec8f2a2a,0x31a47c86),LL(0x153d8ef2,0x74c6410f),L_(0x00000122), + LL(0x726b7b76,0x0b272d33),LL(0xb7894299,0x2ade0047),LL(0x7215a462,0x8525f896),LL(0xe97dd7d4,0x8faa7fcd),LL(0xf320c207,0x2aaff4f3),LL(0xce32f0aa,0xf98216e5),LL(0xe5a62be1,0x4be7ec71),LL(0x057e6071,0xe8262bc9),L_(0x000000c9), LL(0x43441bd4,0xe0348118),LL(0x1e1c1702,0x67b5b771),LL(0x61dc410d,0x540bfa59),LL(0x52daedcf,0x722428bd),LL(0xa96118aa,0xced4360f),LL(0xaa07a68e,0xd1ae09f8),LL(0x4870992b,0x98c1f34f),LL(0xf97358de,0xea267e80),L_(0x000001e0), + LL(0x7daaa5fc,0xb75d5e00),LL(0xba7367a8,0xcb6a4c5d),LL(0x698ec043,0xc4a8a172),LL(0x58a0e780,0x1c52f090),LL(0x45a0c118,0x7ba85810),LL(0x41f652a4,0x261486ed),LL(0x14a0dead,0xe61b0bd4),LL(0x4a38be55,0x881f7207),L_(0x0000004d), LL(0x46fc26a5,0xb678cf5d),LL(0x8cf0f2b1,0x1c805e0f),LL(0x50bc855f,0x4c9f70d9),LL(0xab5b49a8,0x82a11ee6),LL(0xbf5c0c4e,0xecca8fd8),LL(0x30c1e91a,0x40104321),LL(0x3bccd5ea,0xf20e8305),LL(0x7cc38a3b,0xa89c9d80),L_(0x00000144), + LL(0x18b1bd58,0x6dc98840),LL(0x33535047,0xa105e17e),LL(0xf240ea34,0x0ca7c1ed),LL(0xe0a7225c,0x60ee9bcd),LL(0x8d5abc2e,0xd1b7a04f),LL(0xed201196,0x421fd636),LL(0xee08dcde,0x3a41da5f),LL(0x4d648f1c,0x37a2b18a),L_(0x0000014b), LL(0xd13216ae,0xe2574ca3),LL(0x8f4aa46c,0x42b5000c),LL(0x5e6cb8b1,0x2cc007b3),LL(0xd18aeecc,0x139d4602),LL(0xfad62b8b,0x4857b6e6),LL(0x0b803515,0xaaf5703a),LL(0x7dfe5be4,0x5b88d9b4),LL(0xc7e255f1,0xb42f23b0),L_(0x000000ee), +}, +/* digit=25 base_pwr=2^125 */ +{ + LL(0x035c3bef,0x9827bf41),LL(0xd6c228d6,0x53bd6003),LL(0xac8482db,0xedd6d84e),LL(0x199f6c6c,0x554b59c1),LL(0xc80a2555,0xbb3dd0d5),LL(0x9a255d70,0xb61698fd),LL(0x8ce8ece5,0x01602388),LL(0x0910e4ff,0x21f2b5b4),L_(0x0000008b), LL(0x3956f121,0xba9be6e9),LL(0xe014bad7,0xd6c8e28b),LL(0x7941a6f1,0x983d3be4),LL(0x93e374aa,0xb03efe8a),LL(0x7787501a,0x2ecc1517),LL(0x3863f010,0x8ce1a07f),LL(0x2339ade0,0xb1181652),LL(0x142e138f,0xed660839),L_(0x0000017d), + LL(0x542c405f,0xb7c246de),LL(0xbed2f33b,0xc7b5006a),LL(0xd46decde,0x50c509c6),LL(0x83eafeed,0x09502cf6),LL(0x6c8d2171,0x6fa7b091),LL(0xe284eb82,0x6ef3971c),LL(0x5478a9a0,0x7e812b4b),LL(0xbedbb05d,0xbdf3afd0),L_(0x000001a9), LL(0x519aab50,0x17c0e4a6),LL(0xde9fb976,0x510f0d79),LL(0x2d46f889,0x5085caf9),LL(0x57625cb7,0x63379f4c),LL(0x7679eef9,0x202dc487),LL(0x61e8da06,0xd95a7481),LL(0x933c7094,0x6f198e77),LL(0x7e527ab9,0x3cef9bb6),L_(0x000000a2), + LL(0x1843b506,0x587ef556),LL(0xadb4b17e,0xe6db7725),LL(0x223554b9,0x298840a9),LL(0x8ea40d6a,0xb9987d3e),LL(0x088f1989,0x8c544359),LL(0x98c4e679,0x26877124),LL(0xd4955574,0xaeb47579),LL(0x42531911,0xedd6bd8c),L_(0x00000025), LL(0x84ee90bd,0x17da2be3),LL(0x578452ef,0xf3506ed1),LL(0x26ec7e64,0x400c530b),LL(0x0a9d93fd,0x42c14bcb),LL(0xeec28064,0xdbc44330),LL(0x21d894ab,0x1784b7a3),LL(0x83284ca2,0xbd2fe673),LL(0xbdaabf2c,0x333a314b),L_(0x0000000b), + LL(0x003a62b3,0x6110cba8),LL(0x3dead375,0x261b1296),LL(0x24e572ee,0x4f710c53),LL(0xa4d924c1,0x3234879d),LL(0x2bb72d3a,0xf0242c6b),LL(0x5319d73b,0x56b72596),LL(0x5d438ac3,0x9c1467ec),LL(0xe4eb1ea6,0x40556d55),L_(0x000000ea), LL(0xbfbdc6bd,0x113bb0cf),LL(0xf755482f,0x1fdd8292),LL(0xb750229b,0x36eb56b3),LL(0x8756dd9d,0xd65055f0),LL(0xad24bc9f,0x305fbea1),LL(0x29626eb1,0xfcecb5ba),LL(0xc9855409,0xf6273264),LL(0x81000d0a,0x9d561b22),L_(0x00000124), + LL(0x714f53f7,0xd531bd0b),LL(0x1f33fdc4,0x1e83cdaa),LL(0x527f8e3e,0x867d160e),LL(0xf198e03e,0x1f8e836d),LL(0x319f12f2,0xe5494da5),LL(0x312ddaeb,0x8aa887f2),LL(0x0cacf5c7,0xab111707),LL(0x0ac8def9,0xbe88c645),L_(0x000000aa), LL(0x65f59d0b,0xaae9a35d),LL(0xecaceba5,0x4a0a292e),LL(0xbb26ecc4,0x686acc28),LL(0x1e45b0f2,0x2a87d12e),LL(0x3a62004b,0x0c521e1f),LL(0x1147391e,0x2c697526),LL(0x4d3ecffc,0x940dd92a),LL(0x45f78060,0x3a2ded9e),L_(0x000001cc), + LL(0x33a3e9dc,0xf734ebf4),LL(0x6012408c,0x62256296),LL(0xf1399678,0x6234e097),LL(0x152b073d,0xd0a76b3e),LL(0xbf3c9a35,0x1dc1794f),LL(0xca7a4461,0x0ba3b03d),LL(0xc31edda4,0x3859cdff),LL(0x8b3288b3,0xf848ef1a),L_(0x000001b9), LL(0x178320aa,0x8f1d82f1),LL(0x25e150c8,0x41cecb20),LL(0x4d109c13,0xc9d21d04),LL(0x7441f09e,0x7778b13b),LL(0xe84ff4c4,0xa32c0c4b),LL(0xc5ccc687,0x309d686e),LL(0x4ddb0a19,0x9203c78d),LL(0xba0868c4,0x53181ea2),L_(0x000000d0), + LL(0x65fb7f46,0xe3ff2a58),LL(0x31973b19,0x2a26ad18),LL(0x67b2d91a,0x5fcc6c2f),LL(0xe2db81e3,0x0637d795),LL(0x74742bd8,0x1ed4fcac),LL(0x26659e88,0x30b9bfbf),LL(0x232b6d3c,0xae535c11),LL(0x97bb1796,0x32eef414),L_(0x0000004f), LL(0x356e33eb,0x4a8e4230),LL(0xc9a735e1,0x8c58bcc2),LL(0xa2ae4a3b,0x1cf20755),LL(0xcba626bb,0x30e29d2d),LL(0xc537d49e,0xa170a87e),LL(0x2ce7cb6e,0x6a6c16d0),LL(0x5f03a6b1,0xa45e1673),LL(0xe7f13685,0x5d8c9454),L_(0x00000148), + LL(0xda756c31,0xaf97f8c2),LL(0x16b51e78,0xbb4d7657),LL(0x4d4e4ac9,0x12ece85a),LL(0x2a2be63f,0x2c2556ca),LL(0x191c3b7f,0x12341b0c),LL(0x6c15ecee,0xdf666379),LL(0x2e302dd7,0xce9cb829),LL(0x76d162a4,0xa7f8ba92),L_(0x000001df), LL(0x587aa554,0xd8403973),LL(0x56dae839,0xd9d38a99),LL(0xd9da7dcb,0xb69b8acf),LL(0xd93d0fff,0x4e0adb2a),LL(0xf74f0454,0xbb2ad644),LL(0xb5de013b,0xd489e7d5),LL(0x944ef674,0xa2d2bd3f),LL(0x0ae01d0e,0xdd32d1ec),L_(0x000000ae), + LL(0x1e606163,0xe4705f69),LL(0xcf1b879b,0xacfbcaf7),LL(0x1be6ac8d,0x7318370c),LL(0xdc61b734,0x68c96561),LL(0x0073d96f,0xb94c34d8),LL(0xc1901cf0,0xf081cf45),LL(0xe5c4c386,0xf0fb0845),LL(0xcbb72560,0x26daccc8),L_(0x00000139), LL(0x76c20a0d,0x649de0ae),LL(0x12fe8c98,0x69621218),LL(0xdfb8607d,0x8791c2b5),LL(0xe9d74f1a,0x3844e43f),LL(0x58b63a6e,0xa8d06c72),LL(0x30e1aac8,0xb6d9b103),LL(0xc4264540,0x3d6167d2),LL(0x08191333,0x68c04430),L_(0x00000167), + LL(0xc3017b9d,0x1aa56828),LL(0x0367e359,0x3cdae245),LL(0xb804f8f2,0x72553e1f),LL(0x67c4cfca,0xb65b5da8),LL(0xd9a5c285,0x9a1f0411),LL(0x613cad66,0xba23bbe1),LL(0xf8b4e4e2,0x1cef34cc),LL(0x8c65734b,0x932e9f3f),L_(0x0000015b), LL(0x97a55485,0x0351d0a0),LL(0x59bb05ec,0x31868efa),LL(0x8bafab58,0x0873b1c0),LL(0xec7f2fe3,0x3643b183),LL(0xc1a9b522,0x8e06d826),LL(0x5a21bdcb,0x8e78107b),LL(0xd0770856,0xf66af571),LL(0xb9c9076a,0xc46c020c),L_(0x00000162), + LL(0xce1c46ca,0x5dc8f4b8),LL(0xa33c20bc,0x7ec83bd7),LL(0xd911b15d,0xd15a6121),LL(0x4a74a6f1,0x7ded1664),LL(0x38816e97,0x011743f8),LL(0x3193fcc0,0x2ce300dc),LL(0xda43c181,0x4a353b8c),LL(0x15a04d1c,0xc667d3b1),L_(0x00000185), LL(0x7f19da91,0x0bdf93dd),LL(0xe0cceb86,0x0ead0ff6),LL(0x54678a08,0x869bbb72),LL(0xb18f6184,0x7bd575cd),LL(0x64b65577,0xa032d6e4),LL(0x7c7dc54a,0x322afc12),LL(0x30a518c1,0xb73e6fec),LL(0x94b0be46,0xfb67de43),L_(0x0000016d), + LL(0xe164535f,0x0f962f35),LL(0x9c6f091e,0x29586d09),LL(0xc7324d43,0xf0870634),LL(0xfc9e4d8f,0xa54095ca),LL(0xb869d9b8,0x750af3db),LL(0x6d2001cc,0x1a6baecc),LL(0x24533332,0x4d43331a),LL(0x73cd1354,0xe8c54106),L_(0x00000197), LL(0xadd82371,0x24bca00e),LL(0xe99a79ea,0xbfa3857b),LL(0x6523d1b7,0xf152a797),LL(0x74d5c2b9,0x7c8d0d7e),LL(0xca070e93,0x0c8c05da),LL(0x90e17c3e,0x6e856e17),LL(0xc09e9cee,0x45014958),LL(0x157a95c9,0x8be88b6b),L_(0x0000001d), + LL(0x25cac8a2,0xcdd92148),LL(0x641d359f,0x2502c5ea),LL(0x6f35d51a,0x3893c7d7),LL(0x20bf4812,0x2ac899fa),LL(0xea66bfcf,0x3dd9d780),LL(0x6686f753,0x5853eeec),LL(0x471826dd,0x3f6607f4),LL(0x63551e77,0xab0845ea),L_(0x0000017e), LL(0xa629b455,0xc75e008e),LL(0x1eb5093e,0xf1fc3d61),LL(0x48e575c1,0x02888aae),LL(0x04ab23f0,0xe87f1ead),LL(0xae16fee2,0xb7f7d076),LL(0x3eebdb5c,0x94d4a8d3),LL(0x1d42f789,0x32f711dd),LL(0xb65c5dfe,0xffe8ae2e),L_(0x0000012c), + LL(0x532fb033,0xc71e34a7),LL(0x960dca9f,0xb04fd5f9),LL(0xf94be13b,0xcb350c8c),LL(0xad91afd4,0x507fe2c4),LL(0x64d4307d,0x965e3503),LL(0x5c7ae781,0x150451f8),LL(0x6bf2a6c3,0x730da87b),LL(0x2d1774ae,0x075f7ca9),L_(0x00000198), LL(0x065c4c40,0x7d9d82a2),LL(0xdf7b7ba4,0x9f994c7a),LL(0x02b12659,0xbc50a3bf),LL(0x9dfdd3b8,0x383c8539),LL(0xfd8d4292,0x17ae38e3),LL(0xf28f2f03,0x882096f8),LL(0x5cc24a79,0x4e0ef573),LL(0xf15428a2,0x57f145e4),L_(0x000000e7), + LL(0x73fadf09,0x457824fc),LL(0x185ab84d,0x1253397d),LL(0x8d154628,0x387df8c9),LL(0x6bebdcd0,0x9150bff8),LL(0x556713ef,0xe0119e69),LL(0x47194289,0xea336304),LL(0xaea5316a,0xfcab6f8a),LL(0x32095630,0x9256e44a),L_(0x0000017f), LL(0x78b228b3,0x91535ac7),LL(0x1d1ebf3f,0x100cda53),LL(0x2af14479,0xebfd994d),LL(0x0287bad1,0x075babf0),LL(0x868eb0f1,0x4f27433f),LL(0x59c4864e,0xb3ca6bbe),LL(0x042e0b78,0x36fc642d),LL(0xc718e121,0x457b51e4),L_(0x0000008a), + LL(0xa6b3bf80,0x8e3c3743),LL(0x2cea274d,0x79b2083b),LL(0xf6accb4a,0xf7eff159),LL(0x1a2ac9cf,0xbd1a458b),LL(0xc30597c5,0xdaf5afd8),LL(0x67ad0a34,0xad0ce95f),LL(0xfcb5f547,0xf492633f),LL(0xd42c927e,0xd70d201b),L_(0x00000118), LL(0x14dfd7c4,0x7325271d),LL(0x511be774,0x532d9f83),LL(0xe33f2540,0x0e1e6624),LL(0x6202d9c5,0xf8f4394e),LL(0x9c8fa1b9,0xf8528991),LL(0x2359d3b9,0xd88ed641),LL(0x4c00c9ea,0x054c125a),LL(0xbd626daa,0xe0db1f33),L_(0x00000053), +}, +/* digit=26 base_pwr=2^130 */ +{ + LL(0x658f6179,0xd73be466),LL(0x565e43ad,0x8ce3b9fd),LL(0x4a046e43,0xef2d69e6),LL(0xb337e9ed,0x7f11d4e7),LL(0xb4d2646c,0x09fce23d),LL(0x9cfe36cf,0xf8577ee6),LL(0xd497797f,0x1e1b23f9),LL(0xba0fa9f7,0x813fdfce),L_(0x000000d2), LL(0x4f0db76d,0xbc5801d3),LL(0xba1d6ad8,0xfa8c88b9),LL(0x38f8437e,0x58d2c493),LL(0xdf5755dc,0xa5d4147a),LL(0x9f31388e,0x2454e0d1),LL(0xd880f0ef,0xed7c5174),LL(0xf4ab4400,0x2972f596),LL(0x422f97c0,0xfd1f05bd),L_(0x000001b7), + LL(0xefc5f8ca,0xe5308733),LL(0xcdb37e83,0x48081b75),LL(0x60b5bfda,0x38365296),LL(0x9f69f061,0x88a8974b),LL(0x5fb9ec96,0x75444cc0),LL(0xf252002f,0x899c5a67),LL(0x664675a1,0x11db7cc9),LL(0xc6b6d7be,0xe5e85617),L_(0x00000149), LL(0x4ec0d894,0x650536e0),LL(0x7897a846,0x57bdeceb),LL(0xb8acad39,0x39f416b8),LL(0xbb4ba894,0xde12e814),LL(0x45c679cf,0xfa77e0ef),LL(0xbfcd091b,0xae92f35b),LL(0xf3ea6cc5,0xff4f9db9),LL(0x15f66583,0x67f0fed3),L_(0x000001a8), + LL(0x589109fb,0x647774c8),LL(0xd728f100,0x8216c030),LL(0x7565d29a,0x38976a5d),LL(0x0e8d40b2,0xdebd4cac),LL(0xe6c701d8,0x3dc8c008),LL(0x71a01dd8,0x54f5f816),LL(0x85aadb00,0xe571a7d2),LL(0x66dfeb71,0x0d64dc32),L_(0x000001ff), LL(0xdb3c541c,0x8476568e),LL(0x70c9c24c,0x81e7d6f2),LL(0xdfa45074,0x8ce07818),LL(0xc75e724b,0x17be95c5),LL(0xf85a8c49,0x56216aaf),LL(0x71eb7f6d,0xf60fc3e9),LL(0x4afdaffe,0xb5697356),LL(0x598d1d44,0x2dfe785a),L_(0x00000074), + LL(0x649ccede,0x70487d30),LL(0xa5efc98a,0x56482796),LL(0x86f3d005,0x81ed5742),LL(0x41ac177d,0x693c9188),LL(0x41f63ff3,0x544078e1),LL(0xcb0cceba,0xf396ad9c),LL(0xcd9ca803,0x1f2f8905),LL(0xb9a3b9f8,0x4318691b),L_(0x0000005b), LL(0x5e41a528,0xf876e309),LL(0xb6fd45a8,0xf87881ff),LL(0xa8a0715e,0xb8d73d7d),LL(0x074192a0,0xca88981c),LL(0xdc66d086,0x00f41a80),LL(0x8f279d46,0x34882bbb),LL(0xb5564038,0x10c7a90c),LL(0x5552b11c,0xf89b04d8),L_(0x00000053), + LL(0xa21b2d84,0x3f7dbd38),LL(0xce9c88b4,0xf194c13b),LL(0xdc04befb,0xdd6c7f32),LL(0xd71b8746,0xc7a2d3eb),LL(0xb71fb09e,0x497484b9),LL(0x73e11c5b,0x1fc70d7c),LL(0x9831a6ee,0x15940a74),LL(0xc9a49067,0xe36e9b20),L_(0x00000185), LL(0xa93d18eb,0x54606829),LL(0x7dd8cbe9,0x0d9bdc27),LL(0xc774aae0,0x36955f4f),LL(0xcfe0f91f,0x72271ae4),LL(0x1d88d914,0xc0f2a388),LL(0xe1f3ebda,0x63cec6da),LL(0xf2b86354,0xe4a5ad95),LL(0xed0252cb,0xedde22e8),L_(0x000001c3), + LL(0xa6a3dd08,0x840ba74d),LL(0xab9733bd,0x35000794),LL(0xc171b7dd,0x7a0a699e),LL(0x370bb4fe,0xed68a491),LL(0xfb486be6,0xf15b9567),LL(0x86467e73,0x5a72e34b),LL(0x007fbbba,0x4fc2fd9c),LL(0x07f9990e,0xf83d0453),L_(0x00000009), LL(0xc9c8d9c1,0x3ed4cc4e),LL(0xd0aa85e5,0xfa4eda85),LL(0xcc6de111,0xab8aa3e2),LL(0xd8d585dc,0x43bc8ccf),LL(0x69adf3a0,0x9f03e827),LL(0x2ce58643,0x4e3d11d6),LL(0xf05e13fa,0x2820b6d0),LL(0x7af921ff,0x94e1a5fd),L_(0x000001f3), + LL(0x3e1d6ea7,0x8c47f3dc),LL(0xfd8a756c,0xca9eb3fd),LL(0x31799e67,0x5933facf),LL(0x70399eb0,0xe0504d9d),LL(0xdc761184,0x469e7106),LL(0x8ef17d6d,0xcd5f283f),LL(0xb55ec3df,0xdaa7f2c8),LL(0x7711b93f,0xa9a6a6b5),L_(0x0000000a), LL(0x63eb36f0,0xc75a128f),LL(0x9a94b1bb,0xa3a9b3b6),LL(0x99889957,0xd56e141d),LL(0xc45c74e4,0x969c754a),LL(0x455c4484,0xf069f686),LL(0x7584cae6,0xbd579d45),LL(0x441fc298,0x29bfd918),LL(0xea727ee8,0xb0624772),L_(0x00000027), + LL(0x88792dc3,0x7b2e1e8d),LL(0x3ae58142,0x2e71222e),LL(0x90f869db,0x9d393376),LL(0xb1ce0668,0x2d537bfd),LL(0x1a9bff70,0x47346bbf),LL(0x4aeeb846,0x8a0e90f5),LL(0x73c9dd46,0x54e3afa2),LL(0xb6c871a6,0x5945d8c3),L_(0x00000146), LL(0xf4a5960f,0x100e770a),LL(0xac70e87a,0x1c87dbe4),LL(0x797d6d91,0x961a5c5e),LL(0xc5b533fb,0x548c0001),LL(0xb560cfb8,0xa9d47191),LL(0xa65c8463,0x37d39eec),LL(0xcad37d21,0x716bab4e),LL(0x7b0514ad,0x89ad5bc2),L_(0x00000187), + LL(0x5ac51d4a,0x7c1ff897),LL(0x4bd5aa83,0x73534a22),LL(0xb8d76f5e,0x26abe76b),LL(0x8f3282b7,0x76978114),LL(0x14a5cb17,0x1bff40a3),LL(0xb7375a3c,0xb7209f08),LL(0x91b36a89,0xb4553b1e),LL(0xcebaa86d,0x73824616),L_(0x000001bd), LL(0xc027549b,0xbcb95506),LL(0x36ce8449,0x45813245),LL(0x0d1e1b38,0xd6d0eea3),LL(0x7fd0d6a4,0x14a3ad4b),LL(0x14bcb34d,0x4fc99703),LL(0xf4772d1d,0xe5d8c8d7),LL(0x1d59825b,0x6cc8f63c),LL(0x8d26276f,0xba00b77b),L_(0x000000fb), + LL(0xc8a3d5f2,0x06031f54),LL(0x960c67a1,0x32f38594),LL(0x09357fe4,0x3b745f59),LL(0x2a14d637,0x8fa90857),LL(0x653eeaba,0x65744c6c),LL(0xfa37b71c,0xf85872c8),LL(0x3238cb4d,0x9700049f),LL(0xbb9a7dcb,0x4c8ed8c4),L_(0x0000001a), LL(0xed276d40,0x49db6e5a),LL(0x58e268fc,0x4b45feb2),LL(0x84cf99d5,0x2045f9c6),LL(0x80f4779c,0xf44869f9),LL(0xa220c8fc,0x058ad702),LL(0x7e09b470,0x948098cc),LL(0x5bc02559,0x495b8c3f),LL(0x33da20c4,0x197459a3),L_(0x000000f6), + LL(0x6a04a321,0xd2a33c4e),LL(0xb8c0a18c,0x4edc42cb),LL(0x42d862b6,0xd775f940),LL(0x1e91d30a,0x6703500a),LL(0xba0ea3ff,0xa7531dda),LL(0x2773ec8b,0x39b7bed4),LL(0x2d04e32b,0xb4d1689d),LL(0x9117e556,0xd20ddefd),L_(0x0000019e), LL(0x3a4ba55b,0xa10a2f30),LL(0x55b7005a,0x2bae1e82),LL(0x53323c22,0x2ff6304e),LL(0x397190c6,0xd9f087fd),LL(0xa7a8b69d,0xb68e3037),LL(0x12602cd7,0x25d350ef),LL(0x22bf670f,0x86cdc0d1),LL(0x8a47dde9,0x8ee7e2f2),L_(0x0000009b), + LL(0x693bf308,0xc6dbc583),LL(0xd24b6766,0xd31b0ef8),LL(0x95890706,0xe3a35296),LL(0xc90c51cc,0xb8ed7618),LL(0x7cff3a80,0x4973ebf1),LL(0xd473b1c4,0x3a129c68),LL(0x098525e4,0x5036c9f1),LL(0xc374031f,0x3955ea92),L_(0x000001d3), LL(0x4ce3a370,0xf46f1c31),LL(0x64ddf24c,0x9e1fda40),LL(0x70db5256,0x5ea2c55e),LL(0xf8940530,0xf14297ac),LL(0x034f59d5,0xa46ea96e),LL(0x42888331,0x7dc4622a),LL(0x102ad134,0xe007741a),LL(0xfe88a514,0x1db8ec7c),L_(0x00000046), + LL(0x6b484938,0x514ddbd3),LL(0x40394ddf,0xc9c65dd0),LL(0x539c2910,0x679067ad),LL(0x449575b2,0x3e4b50f3),LL(0x3cba3f07,0x3ae8deca),LL(0xdb855b46,0xde55385b),LL(0x16ac2f4b,0xcf4ed383),LL(0x1d879d47,0x1e8113f4),L_(0x00000036), LL(0xdc02e925,0xce4c202b),LL(0x3d4593d6,0x973ac87d),LL(0xf0b4acfe,0x01434726),LL(0x6764442d,0xfe9274d4),LL(0x6b582005,0xe308fe9e),LL(0xf520a500,0xaae35487),LL(0x99c31e18,0xcdca5ee1),LL(0x1d99ed71,0x0f6491b7),L_(0x00000198), + LL(0xb383837e,0x46f862a6),LL(0x65cb077c,0x631e9559),LL(0x9b939d55,0x25138071),LL(0xf40d4552,0x952fcfe6),LL(0xb308097f,0x0a6a5375),LL(0x2e65e8e6,0x3e9edb80),LL(0x1310ce7e,0x9008e712),LL(0x36b60d2d,0xef767e69),L_(0x0000009a), LL(0x40188cf2,0xfa1dc587),LL(0x32ad8729,0x4064ce9d),LL(0xe1763571,0x56c0be29),LL(0x7963b458,0xde3b2135),LL(0x95d575d7,0x66e40952),LL(0xa842ef1e,0x444bd560),LL(0x5e446834,0x9e4dbf26),LL(0xf024c8aa,0xf4d25cc1),L_(0x000000bb), + LL(0x24d33325,0x31f1b543),LL(0x5b8d2482,0x0ec252b0),LL(0x19b88e25,0x0818329c),LL(0xcd8bbb1b,0xdb10a837),LL(0x02e4893e,0x81192510),LL(0x84cd1c11,0xbe980656),LL(0x6c489430,0x0f675008),LL(0x346cc643,0x57e72ed9),L_(0x00000152), LL(0x09725c08,0x8c9e3525),LL(0xc2a2b6e2,0x50c3fc67),LL(0xaf377b60,0x018ff455),LL(0xd7f347bb,0xcd5a7fd3),LL(0x820f28df,0x7a766a20),LL(0xbaa35047,0x2e3e3c08),LL(0xea0d932e,0x620422f9),LL(0x561b15cb,0x78d9ad76),L_(0x000000ff), + LL(0x8cf07187,0x0f23847d),LL(0xcb2c301d,0x46a3121c),LL(0x24b1883c,0x64fb5faa),LL(0x43263cce,0xc10bc090),LL(0x731fce3c,0xe510506a),LL(0x134986c0,0xd2899a05),LL(0xaa30a907,0xd8592433),LL(0x6671f165,0xa5074a40),L_(0x000000ea), LL(0xf3b369eb,0x39b1d8c9),LL(0x4f03f7bd,0xed9a2887),LL(0x4a870054,0xbd121753),LL(0x510756ad,0x9a0d0a37),LL(0x85faa51a,0x35296053),LL(0xdf5c089f,0x15a5c2ed),LL(0x130a237e,0xbd316fba),LL(0x3774ff2c,0x2c9d3ce1),L_(0x000001ee), +}, +/* digit=27 base_pwr=2^135 */ +{ + LL(0x10f99602,0x45c384b6),LL(0x2d4100e2,0x7187b9e4),LL(0xc5264e57,0x2477a817),LL(0xcb20ec20,0xc146fbb4),LL(0xa5dd079d,0x6c49fc51),LL(0xb66b540f,0xa207dd34),LL(0x18cb3114,0xfc85f364),LL(0x79042a4a,0xa886f4d4),L_(0x00000192), LL(0x9d642bee,0x3c62b595),LL(0x7df28ef3,0x09a83c10),LL(0xc98bc18d,0x61720266),LL(0xe8b908cb,0xbfa40c64),LL(0x3266ed34,0xc5f7d00d),LL(0x785d5c5a,0xed6e6699),LL(0x0fda50cd,0x0528d637),LL(0x9fa7129a,0x226a0134),L_(0x000001f6), + LL(0x020b6b5c,0x854a83b5),LL(0xa6b72500,0x82b8a64e),LL(0xf5cc5dee,0xa44f4310),LL(0x82f7e307,0xa979f999),LL(0x26038361,0x36271c95),LL(0x9d4a6e7e,0x2c2e87bd),LL(0x83121a68,0x801461a1),LL(0xdda0c42c,0xc46dd1bb),L_(0x000001ef), LL(0xc8adce87,0xf5ff9d53),LL(0xac7e6d6f,0xba6044cb),LL(0x8a2a18c9,0x4e0b1c61),LL(0x47645723,0x538c1881),LL(0xff1d071b,0x0d20849f),LL(0x3d943038,0x033ae333),LL(0xd1326f05,0xe89c6421),LL(0x504a49c4,0x0c637164),L_(0x00000064), + LL(0x161f0a4b,0xc4db51e8),LL(0x0ee6ce1d,0x76a9fbe6),LL(0x471be04f,0xaee80fe4),LL(0x63fea5d4,0x13ed56ca),LL(0xbb7b1989,0xff53dd5a),LL(0xbdd30335,0x5aa48cba),LL(0x8830cbd1,0xced46a92),LL(0x6ec07f47,0x4d0d3e16),L_(0x00000103), LL(0xbf5f1b1f,0x85d83aa8),LL(0x030c528b,0x3981ba7e),LL(0xf6347818,0x51c072a5),LL(0x8851b9e3,0x6bc6f46b),LL(0x908af12a,0xab612e82),LL(0x11ae86d1,0x194bfdad),LL(0x855184ce,0x3ed70ec9),LL(0xbc5ba81b,0x36a51b16),L_(0x00000121), + LL(0x7e0c514f,0x89a7c665),LL(0x4ba50604,0xf92c410e),LL(0x03183bca,0x325bb838),LL(0xde751063,0x4a227afa),LL(0x61ce2f62,0x8d611fad),LL(0xe1c057fe,0x63741f27),LL(0x26a80815,0xcc3f4944),LL(0xdc51e188,0x1fb19202),L_(0x00000060), LL(0x35ecd6ea,0x23f5c4ba),LL(0x8b90f284,0xeac00c83),LL(0xecc8f9f7,0xc63ca5b1),LL(0xabd4ae3b,0x61f4eb49),LL(0x5868250a,0xde5e94c7),LL(0x8aa62e59,0x2e205082),LL(0xa27ce17d,0x4d94b7ec),LL(0x3cf7dcd2,0x84ff72ff),L_(0x000000ed), + LL(0x85eddbf9,0xd6250a4d),LL(0xc4c48937,0xb7e17582),LL(0x30cd4a1c,0x663cb672),LL(0x4ecce3f6,0x51a07652),LL(0xe3e24952,0x971076ab),LL(0xb2837d4a,0xcfa04494),LL(0xae48378d,0x2f234848),LL(0x35aa4670,0x5204cd94),L_(0x000000c1), LL(0xc684c134,0xce99c049),LL(0x189c18e6,0x1251a582),LL(0xe65b23d2,0x1ea8f76e),LL(0x50f4154e,0xde65bbaa),LL(0x55d8a624,0xd1acdeb6),LL(0x9745647b,0xdbc7b696),LL(0xa1a36741,0xc3af97df),LL(0x0e06b475,0xcec9f674),L_(0x00000035), + LL(0x13fe9d4a,0x9edae224),LL(0xc93ceb2c,0xc40b8881),LL(0x376b68f1,0x493ec443),LL(0x2fe4d107,0x2613f055),LL(0x2adbc0de,0xc264177a),LL(0x6850f4d4,0x999b4445),LL(0x024b1759,0xb5528e8c),LL(0xa532c490,0xfe9cb25f),L_(0x000000e4), LL(0x7dabddfd,0xea2401de),LL(0x29f2c840,0xae4f0565),LL(0x6004e218,0x9745c833),LL(0x45a26d7d,0x1aa8e8c7),LL(0x2e1e3abc,0xf254366c),LL(0xd176c592,0x5dba9a65),LL(0x75f2ce2f,0xcb70eda5),LL(0xef390121,0xdf3bd7c9),L_(0x000000d4), + LL(0x92a0df5e,0xf2fb4c5a),LL(0x612c5e22,0x90ec0ad8),LL(0x19eef2ca,0xf648d0a0),LL(0xb08c2818,0x56957806),LL(0xc6fa4d71,0xe858889f),LL(0xd381edae,0x0d311c34),LL(0x51c58427,0xc7d13fa9),LL(0x223f6153,0xe7ffd714),L_(0x00000046), LL(0x3ef9a256,0xa9aa9baf),LL(0xd185738b,0xa46d0a8f),LL(0xb3308a45,0x74e9630a),LL(0x50e76c6b,0xa8af0eb5),LL(0xe6d664ef,0xb4263c27),LL(0xd6ff5afe,0x0d5ab8af),LL(0xa29e25ea,0x35f45527),LL(0x9641d328,0x8c614ae7),L_(0x000000e6), + LL(0x338228bd,0xe352f406),LL(0x44f05c5b,0x36069000),LL(0x3a7061d3,0xe7fd3e15),LL(0xd82371f2,0xb123a32e),LL(0xc0c29bdd,0x1a15e8ee),LL(0x0938b2d1,0x9bba46b8),LL(0xa2ae38c1,0x66a69b9b),LL(0x470c4e74,0xe7a0607a),L_(0x000001a8), LL(0x4d513c26,0x04e250e3),LL(0x0d3d6116,0x99aa8990),LL(0x2850e69a,0xe87aacf0),LL(0x0f5ea018,0xa9b70f5d),LL(0xe629958e,0xc9dfec50),LL(0x67ad0ad8,0xa19fef72),LL(0xfbbc4dd8,0x4e913349),LL(0x44ef73af,0x36506a6e),L_(0x00000106), + LL(0x4259e2ef,0x4fc61403),LL(0xbe686c91,0x3b319ce9),LL(0xcaf2c252,0x48b002e1),LL(0xd7142b37,0xfd368034),LL(0x4805818a,0x24a14bab),LL(0xfef62905,0x0f3cee8f),LL(0x8e05459e,0xdd641c3a),LL(0xf8a79ba8,0xda069476),L_(0x00000043), LL(0x796a282e,0x39168c60),LL(0x3f0a7260,0x3e3e3f10),LL(0xefe9a0b6,0x98f31f24),LL(0x029755ad,0x68a3bd55),LL(0x56d48cfc,0x08db9e00),LL(0x180b09d6,0xf41fc496),LL(0x43518b4d,0x0a026b4c),LL(0x53fa9a78,0x49c51679),L_(0x00000006), + LL(0xa0eb14a2,0x04533f2b),LL(0xc6b20735,0xf37cab9f),LL(0x59889c71,0x2957243a),LL(0xee6d3e3b,0xcd4ef031),LL(0xc82e2f33,0xbe1fa792),LL(0x9431aaa2,0xd5df936a),LL(0x5897dee2,0x69038db7),LL(0x3c5c1a27,0x49337ba9),L_(0x000000c1), LL(0x9595fa29,0xdaff077c),LL(0x92632965,0xd489db4e),LL(0x73090129,0x940397cb),LL(0x3ab24c2f,0x08747c46),LL(0xa7844d0f,0x4063f57e),LL(0xde4ab15b,0xdfb6a687),LL(0x7bdc8db9,0xc4b7272d),LL(0x670393c5,0xcc129fac),L_(0x000000b3), + LL(0xcad13624,0xd3620658),LL(0xd490ca01,0x480b6735),LL(0xf6b97c19,0x5a38261b),LL(0xeb8077db,0x3a0d7cfc),LL(0x6cb95b1f,0xd822b66c),LL(0x027f3439,0x204c12b4),LL(0x5b1121d8,0xd1662f63),LL(0x50df8b79,0x5a06b5c4),L_(0x00000003), LL(0x20c440aa,0xdd45df26),LL(0x7d35a477,0xdf45caba),LL(0x37ca8bf1,0xb9d5153b),LL(0xa163bc4d,0x2a09a7c7),LL(0x79721ae6,0xf16f3745),LL(0x4901566b,0x8b7edc54),LL(0xda6d915a,0x2073fe4c),LL(0x59c5233d,0x0e719f5b),L_(0x0000017c), + LL(0x986f86b0,0x34d85352),LL(0xb5e1a9d1,0x04b6fb3b),LL(0x96ed674c,0xc5869197),LL(0x2201eaeb,0xc13b24f0),LL(0x43fe141e,0xd5acb880),LL(0x77717702,0xb4c36b2f),LL(0xf913c28e,0xbd9e8fe1),LL(0xbb8bc0cb,0x871dc376),L_(0x00000014), LL(0x2919d227,0xb3b18239),LL(0x9062a004,0x0d96f561),LL(0x84b9c0aa,0xd38134a4),LL(0x384e6a14,0x62e9b9dd),LL(0x434945b9,0x0d2a3f87),LL(0x26111d5b,0x0558e17c),LL(0xca088afb,0x7e83601c),LL(0x5f4109b6,0xf3372d86),L_(0x000000be), + LL(0x0f6c0054,0x2e8b93c7),LL(0x08562f0b,0xbd858543),LL(0x4642e58a,0xf3108a95),LL(0xe72a8e55,0xc3b6dcd3),LL(0x48efed30,0xbf3f1b76),LL(0xeef47f99,0xbe7c393d),LL(0x7808a959,0xb13004f3),LL(0xab865ef6,0x937fdeea),L_(0x0000015c), LL(0x22a644cb,0xde622870),LL(0x5b036454,0x1435996c),LL(0x253cdb02,0xc939a75b),LL(0x00181ca2,0x497b4076),LL(0xc885fd30,0x89ffccfd),LL(0x5be5d64a,0xd221db4b),LL(0xf3ff67a9,0x7c1814ff),LL(0xe534c2d3,0xdff1b3c3),L_(0x000000de), + LL(0x6b17ac7f,0xc9c5a035),LL(0x6fb80668,0xd3037f61),LL(0xf7001431,0x61783bd7),LL(0x7eb67860,0xa8db044a),LL(0x687c5be2,0xbd63e80e),LL(0x72619e19,0x79bd6dba),LL(0x3f54433d,0xd3da5abb),LL(0x53179eab,0xbeded885),L_(0x000001ce), LL(0xd2236048,0x8c1156c4),LL(0x0e48c339,0x6a8706fa),LL(0xd70c895f,0xdef1e5d8),LL(0x74e0aa32,0x628036e7),LL(0xb31a93a3,0xa6fa3b42),LL(0xe7bb3f2a,0x91ab3f15),LL(0xd667e0a4,0x1d5276ef),LL(0x172f04b6,0xac2e330e),L_(0x000001fd), + LL(0x5905e1da,0xcaeed330),LL(0x3479c8d8,0x774a0f8d),LL(0x2da43aae,0x89fab1e0),LL(0x5a52588d,0x22017d07),LL(0xf2088700,0x3344f84f),LL(0xf666f8bc,0xcded1b00),LL(0x98c10e11,0x385b1f15),LL(0x4a35267e,0x4cb957d9),L_(0x000001db), LL(0xa8120217,0xb7f4f85a),LL(0x70aae220,0x50f81138),LL(0xd0547dcc,0x320d34eb),LL(0xaa86f5d7,0x4627a90c),LL(0x313d3af2,0x0d86c9fe),LL(0x9d1708c0,0x93baaabc),LL(0x4bb0c611,0x5e3713af),LL(0x8c78d7cf,0x23abcabf),L_(0x00000180), + LL(0x1c368201,0x8d760d23),LL(0x2a50426c,0x2fd748bd),LL(0xd4451d72,0x84a5084a),LL(0x7d518774,0x395bd1ac),LL(0x41ad7719,0x5dc03d65),LL(0x54b40eaa,0xf42c68a2),LL(0xc699a962,0x481b2b4d),LL(0x78f2ecdd,0xd9badbf1),L_(0x00000145), LL(0x35684fe0,0x6890c940),LL(0x7a9849bb,0xe8615e51),LL(0x5822be91,0xe3c3e516),LL(0x9ed67ca7,0x5ebee67a),LL(0x5438f44c,0xbf03236f),LL(0xf9e45ec0,0x29c5029e),LL(0x412d0011,0x4fd4f4e3),LL(0x09bad0b6,0x5f591e3c),L_(0x000000e1), +}, +/* digit=28 base_pwr=2^140 */ +{ + LL(0xdd9afd40,0x6867ca62),LL(0xb2e8cc83,0x2abfd678),LL(0xd7d6c96a,0xbb6c702c),LL(0xb7b75f62,0x8eb9ab34),LL(0x2a8eb698,0x67b38227),LL(0xee1d1728,0xbff15e40),LL(0x6f600751,0x4ec3001b),LL(0x30ff996b,0x7fb8efdf),L_(0x0000015d), LL(0x29a2746d,0xfc62d76a),LL(0x1c80dd81,0x4a2f2f09),LL(0xc1a9825d,0x4ae9b61a),LL(0xb05a4fb5,0x71a812fc),LL(0xa7baf2db,0x8bb96eaa),LL(0xcc434e4e,0x53c2dfd9),LL(0x8fce5672,0xceeb8e7b),LL(0xd6b948ee,0xc787b7e9),L_(0x000000ba), + LL(0x87a8f7ef,0x44566d20),LL(0x816dab3c,0xa555ef8d),LL(0x68ad0a5e,0x93fa3eae),LL(0xb45ab760,0xad51a41f),LL(0x14a732bc,0x3c784a11),LL(0xcd96f357,0x7e912d99),LL(0x7808bc95,0x547dff3f),LL(0xd022a461,0xd3f93d98),L_(0x0000009d), LL(0x3bed20dc,0xdcf5792b),LL(0x9e50e443,0x1c5d0319),LL(0xab35921f,0xce7e3777),LL(0x61acb763,0xc69a2c80),LL(0xd5a1f19e,0xd4921d8b),LL(0x86d49b86,0x3effd3f1),LL(0xd287849a,0x969ee2c3),LL(0x2319a1d3,0x7987e8d9),L_(0x0000017e), + LL(0x4a3f3c42,0x66e6b355),LL(0x48d7c646,0x494cec8b),LL(0x4319bb26,0x3c15f132),LL(0xa4923bd5,0xb25b7340),LL(0xe36296a4,0xd2c82187),LL(0x62a70b23,0x3a2676cb),LL(0x3ce0a44b,0x15ada951),LL(0x93e13762,0xcdd5bfa0),L_(0x000000bd), LL(0xc34a522a,0xe16f0577),LL(0xeb1d23f2,0x563bc2d6),LL(0x74b1ae5a,0x22ce417d),LL(0xf0676c19,0x8b56e586),LL(0x64665c8d,0xd3d21118),LL(0x4a9d1f08,0xb5b57a1f),LL(0x9ad18a2e,0x121b1440),LL(0x31f16f69,0xd3dba51f),L_(0x0000015a), + LL(0x6c14c349,0x14a0990f),LL(0x1571f4bd,0x8a12a2ae),LL(0xa7e98142,0x64ea4bd5),LL(0xf548a570,0xc2f56d89),LL(0x3a99f05e,0x24fcfb51),LL(0xb029c28b,0x468881de),LL(0x16eb364a,0x54a22d8c),LL(0x9df6df67,0x8e7ba7c2),L_(0x0000019a), LL(0x0875f9db,0x6d585b84),LL(0x8b87eab6,0xf8f2e668),LL(0x61b8a4ae,0x1b210ab1),LL(0xcd5968d0,0x38c32d9f),LL(0x9469f27a,0x2170203f),LL(0x7e65bf26,0xdf5327ba),LL(0x268e8f3d,0x0d743f23),LL(0xbbd5d6a5,0x6866dcf3),L_(0x000000f7), + LL(0x9ee406f6,0xfe75ceb3),LL(0xc2dbf93c,0x7d044fdd),LL(0x05aa3d0f,0x3459ab15),LL(0x1e4c0404,0xbea051fd),LL(0xeeca2cbf,0xa5c86723),LL(0x428637a5,0x81d9dd90),LL(0xd3aca9d5,0xf6461276),LL(0x78277709,0x5fdc5888),L_(0x0000019e), LL(0xee7c5a7b,0x105fdead),LL(0xb799ae3c,0xc919db59),LL(0x5e3595ac,0x2aa1f7f7),LL(0x4e9b6f6b,0x519dab32),LL(0x1054eecc,0xd70aa0c8),LL(0xdab1fa02,0x45046840),LL(0xe8162c46,0x382d8fac),LL(0x3f7fc117,0xc63a2e34),L_(0x0000019c), + LL(0xca65cbda,0x40f45643),LL(0x5e42072e,0xb22b4730),LL(0x6980bc47,0x0c0959ae),LL(0xd0091f48,0x17382117),LL(0xe76ce6df,0x6fb6755f),LL(0x083b1371,0x8e338195),LL(0x3ce92877,0x57844465),LL(0x22eadd23,0x88650fd1),L_(0x000001f2), LL(0x66b7e9c4,0xb832d4f9),LL(0x40795011,0x2f5eb6ec),LL(0x56106a16,0x439d72fa),LL(0x7a360472,0x9a695980),LL(0x77c4b5ed,0xbd3315f1),LL(0xcd83808f,0xc773b196),LL(0x21f3f41d,0xdcca40dc),LL(0x42518607,0xd975bf10),L_(0x00000120), + LL(0xa0b7f265,0x7643d0a4),LL(0xca61488d,0xc9a4ec9b),LL(0x78d40864,0x08ac32aa),LL(0xd1f91912,0xe2c33dbb),LL(0x4ce17265,0xa6b041d8),LL(0xc73e5e84,0x130222f6),LL(0xcaf07f55,0xbc20bdd0),LL(0x2fe0bc76,0x482195b2),L_(0x00000043), LL(0x45c6a126,0x37f04c87),LL(0xbdd6ee14,0x601822b2),LL(0xb9431fd2,0xf10879b1),LL(0xebee54b7,0xb8d5c027),LL(0x530c61a6,0x52358509),LL(0x3b953e07,0xc05d71ee),LL(0xd055e247,0xfc120f31),LL(0x51f78c21,0xb71a77f5),L_(0x00000040), + LL(0xdd01fc40,0xdcca1655),LL(0xfcdcd83f,0x6f13723c),LL(0x6fe01dad,0x48fc724e),LL(0x10ea92f4,0xe9506b35),LL(0xbacd3171,0x32c50316),LL(0x5b9c3826,0xb525812e),LL(0xb06a2041,0x6095bd35),LL(0x29d1e51d,0x8c9f2aff),L_(0x0000018f), LL(0x9f6b1c54,0xf5e8440d),LL(0x5815a76f,0x4652dd8f),LL(0x0ba6e7eb,0xa2d772d1),LL(0x67d0cfa7,0x2c2c10a3),LL(0x9134fbe1,0xe122408a),LL(0x4d3fc999,0x98396be7),LL(0xf158ed72,0xf1736447),LL(0x2e445a86,0x3589b3e7),L_(0x00000010), + LL(0x1acdbb17,0xaa39db8a),LL(0xcd1bfa5a,0x3f690830),LL(0xf20580fd,0x47516625),LL(0xc02a443b,0x72df9c02),LL(0x37c50805,0x1f658c86),LL(0x70ba4df8,0xb9b7c15e),LL(0x7863af7e,0x4f048a5e),LL(0xac437359,0x985ed711),L_(0x000000f5), LL(0xe24f4c27,0x31deb67a),LL(0xf7ff8403,0x277a75a7),LL(0x9efc9dd1,0x9e038122),LL(0x72ab76fd,0x380f72e2),LL(0xa5bd7ec4,0x55ee2df7),LL(0xe6e012fa,0x8dba5f73),LL(0x3daacbbb,0x7d57b1b9),LL(0x706e065a,0x2a1528ff),L_(0x00000115), + LL(0xac6b647c,0x15c609d6),LL(0xe5366bdb,0xba4c8f5f),LL(0xab004e8e,0xa55c2b8f),LL(0xbe220e5c,0x9b0a693e),LL(0x328cf3bb,0xf0a01098),LL(0x93659056,0xba4d555d),LL(0xa9299fb7,0x705141f5),LL(0xac2b6ea4,0x44c2570f),L_(0x0000008d), LL(0xcb330456,0x4159e7f0),LL(0xda0acb04,0xd0b0f9e2),LL(0x72227853,0x9c81b6a3),LL(0xfca5d947,0xe37b62d0),LL(0x89f8e6a5,0xa2b087c1),LL(0x397e6f2d,0x79ab8dd4),LL(0x0c2f8337,0xe811e1ad),LL(0xaed2062f,0x41fc3c1b),L_(0x0000006e), + LL(0xbb22cb43,0x62da0bcd),LL(0x66e8ec0f,0xa2436a22),LL(0xb2614d9b,0xc4f2fabe),LL(0xd37ba7ca,0x91730356),LL(0xd6947b5c,0x74afd26f),LL(0xf62dae98,0x24fc84c9),LL(0xa5d82a0e,0x01183e91),LL(0x6d7bad82,0x9ae00850),L_(0x00000098), LL(0x11153170,0xf94e5ea9),LL(0x6a5a8c8b,0x370f5efd),LL(0x4a208fd5,0x0abfbfb6),LL(0xd3eba761,0xb4577a64),LL(0xaea020f7,0x9d9fbff8),LL(0xee185b5a,0x7590eb6e),LL(0xde37c8c6,0x110f6564),LL(0x087e5b3d,0xf182e709),L_(0x00000074), + LL(0x6e7e0a27,0x35933656),LL(0x11881664,0x57d6289e),LL(0xb5dfe85d,0xb19a5774),LL(0x03f55586,0x84a3823a),LL(0x83e66aba,0x819d0f7f),LL(0xe6540e46,0x8229f91b),LL(0xf8e60b64,0x0ebba171),LL(0x3cb7174c,0x13a992ea),L_(0x00000132), LL(0x367ca9d0,0x66b10914),LL(0xaf137af3,0x22188a39),LL(0xa99be2ef,0xc9e8bf06),LL(0x9f80153c,0xb82d6f97),LL(0xb70bb797,0x713e0f8f),LL(0x08001bac,0x2900ebf9),LL(0xc349df5c,0x2dc5150c),LL(0xcda05b0f,0x705ef690),L_(0x0000013e), + LL(0x1c93b8d6,0x2275d0c6),LL(0x43c2cbe5,0xb77f7c23),LL(0x426913e3,0xa4d09bcb),LL(0x193a8beb,0x1c330bb2),LL(0x9694aec2,0xf90a1043),LL(0x466c8910,0x47794b4c),LL(0x013120f4,0x92db08ad),LL(0x27504b4e,0xfd2c4ee7),L_(0x0000008c), LL(0xed071468,0x3983eaf2),LL(0x1520fd40,0x43f9f523),LL(0x10ab4804,0xbbc7abbe),LL(0x4c94f219,0xb3da18c6),LL(0x0653b434,0x34410d29),LL(0xa49aa62c,0x475b1588),LL(0x3fb54eff,0x1efe3b74),LL(0xe35ee322,0xb5457582),L_(0x000001fe), + LL(0xc7c8837b,0xdfafafb9),LL(0xd5ac6ec8,0x3e035e11),LL(0xf1bfe6e7,0x0cdfda44),LL(0x99f86b4b,0xd82854c9),LL(0x51eb2ba8,0xe9378d3c),LL(0xfc70edec,0x0488564d),LL(0x78099daa,0x4df1eac2),LL(0x106d93e9,0xfcd2965d),L_(0x00000092), LL(0x7ad3cd26,0xeb73c32f),LL(0x65c6a4f0,0x12e6dfd1),LL(0x613a95bd,0xc4753f02),LL(0x64c8ae6d,0x6ee36689),LL(0x82594975,0x85faeab2),LL(0xff936e47,0xfd968563),LL(0x16aa8dfb,0xfae37039),LL(0x6a6051eb,0x090bfcd6),L_(0x00000077), + LL(0x75c314c8,0x1283d38d),LL(0xab80a4e1,0xab4695b9),LL(0xb05894a6,0x37378243),LL(0x7f2984bd,0x1227f75f),LL(0xdf654236,0xe2ef58d5),LL(0x290dd3fb,0xdf64907f),LL(0x38ba14af,0xf1d428ec),LL(0x0c38bf2f,0xc2c54bbc),L_(0x00000078), LL(0xb37cd388,0x07837c73),LL(0x31dfd968,0xda6621ef),LL(0x28b820a5,0xe6fe2937),LL(0xb934b778,0x2622aba5),LL(0xe627cb53,0xdff94dc8),LL(0xa81ea0cd,0x560bd971),LL(0x9c8b6e45,0x2209f943),LL(0xdbaad845,0x6e9d457d),L_(0x000001fc), + LL(0x64a50e99,0x8402ef56),LL(0xe6626b55,0x5c34e569),LL(0xbb9dc4c8,0x009d6dab),LL(0x6746cac4,0xcf68656c),LL(0x3336b947,0xfe65ab97),LL(0xe266a898,0x0371ecf3),LL(0x5830a2ee,0x1d57e75b),LL(0xc9710982,0x3e097669),L_(0x00000064), LL(0xfec81877,0x78e2ad77),LL(0xddfb754e,0x284311de),LL(0x4aaa3d53,0xac9d56ca),LL(0xfe5f5938,0x19e9ec29),LL(0x24185a04,0xe89e92d3),LL(0x746f628d,0xfd0968c4),LL(0x6959a461,0x2cc1b198),LL(0x7f39e175,0x5c4efa86),L_(0x00000168), +}, +/* digit=29 base_pwr=2^145 */ +{ + LL(0xd3daa6ec,0x15578941),LL(0x1a86314a,0x6a7421e8),LL(0xe2ec4906,0xe975bc97),LL(0xa7485f37,0xd59fd20a),LL(0xe5e712ab,0x5b001318),LL(0x951133a1,0x1259bdca),LL(0x057f57ee,0xcbd3b2c6),LL(0x33dad04a,0xef3153ef),L_(0x000001e7), LL(0x8c6263d5,0x2ed37d50),LL(0xa4e81e7b,0xf8f36d87),LL(0x5a01a3ef,0x0288c3e4),LL(0x8b372673,0x846f5208),LL(0xa991189b,0x6f560651),LL(0x71db52e5,0x431caeef),LL(0x58e36c06,0xa3f98d5e),LL(0xd8d03f83,0x020099b8),L_(0x000000dc), + LL(0xd73f8b8c,0x52ab1b79),LL(0x7e2040bd,0x95a122c6),LL(0x89ab0660,0xf1cb78af),LL(0x01a20058,0xc77cb751),LL(0x31375e35,0x5e133615),LL(0xea159ba6,0x524c75ea),LL(0x7ecbfca3,0xab8ae0fa),LL(0x5719d039,0x623ac91c),L_(0x0000019c), LL(0x49d36dfe,0x6b1430a2),LL(0x8450eb5d,0xc47b9efe),LL(0xafb92b30,0xa9991147),LL(0xf6824bee,0xe1752c3f),LL(0x2b160b39,0x7fd6a625),LL(0x6256f4b4,0x574646e7),LL(0x076f7bff,0xe5bbdfa9),LL(0xcc3f350c,0x4642b5db),L_(0x000001a8), + LL(0x7f151743,0xfa21d74b),LL(0x37719209,0x8cfe5b17),LL(0x00c8bba2,0x1c2878b2),LL(0xa620523f,0x170331c9),LL(0xa5843ac0,0x8cd83b50),LL(0x0381135b,0xb047131d),LL(0xa643b75e,0xd2ab54c3),LL(0xc5ef1464,0x62ed0e42),L_(0x000001f3), LL(0xad15614e,0x91bb20fb),LL(0x78f86132,0x7805c40a),LL(0x895f7e0d,0xa2a8624a),LL(0x3ce4b54c,0x6579a871),LL(0x1b0cde0e,0xd626e2cc),LL(0x6377df41,0x045193c6),LL(0xcd6454de,0x1c3ca349),LL(0x4909db1f,0xb047b0a1),L_(0x00000191), + LL(0xb6bf0f8a,0xf432b93e),LL(0x4a6f35d7,0x611248d4),LL(0x62f74f5a,0xff45509d),LL(0xef98d968,0xf78b11dc),LL(0x540d2d90,0x8e0fdb4e),LL(0xf1948691,0xf839178d),LL(0x775c9c48,0x1546952b),LL(0x2da4516e,0xb05a9a42),L_(0x00000148), LL(0xe7052400,0x5a0e6542),LL(0x5c40801a,0xc9bfcea8),LL(0x8cf4381f,0xecff5ed1),LL(0x04226551,0xe3765708),LL(0x3addaf06,0xbf10bb39),LL(0xe6d6327d,0xa7a94c0b),LL(0xde98dcbd,0xc9cc265a),LL(0x9445d1d2,0x39198006),L_(0x000001d2), + LL(0x8785f128,0x6fd53bcb),LL(0x11b88070,0x89212039),LL(0x0fd4310b,0x7c570d88),LL(0xfb34d160,0xe29cc2db),LL(0x8d8b6c1d,0x98ac6419),LL(0x633a2387,0x48918f6b),LL(0x3767a8fb,0xc7f5fff0),LL(0x1de5bf8a,0x517008cf),L_(0x00000167), LL(0x1a4a980d,0xc8a802dc),LL(0x31a9aa05,0x3f45d1a4),LL(0x955dbbaa,0x019bc5a3),LL(0xf987ec6f,0x7819e65f),LL(0xa521ab1b,0x6a8b4966),LL(0x9db12d33,0x1c418ebe),LL(0x5c25c25e,0xd371d986),LL(0x05758d98,0xcdb745fe),L_(0x000001d1), + LL(0x24e96217,0x82dda7a2),LL(0x8cb7272f,0x285a44b5),LL(0xd0fa019c,0x772202b8),LL(0x256b2dc1,0xf7a1827e),LL(0x70cc578d,0xf561fd03),LL(0xf01369b8,0x4b48b6ea),LL(0xb34eeab3,0xf869dc36),LL(0xf55466de,0x10fbfa49),L_(0x000000d5), LL(0x9e31568f,0xa79b35c8),LL(0x72243fd6,0x48942459),LL(0x6f4d4b6f,0xbe3c7cfe),LL(0x4b050256,0x273326f3),LL(0xccad925d,0xcfe66f8b),LL(0x63feb094,0xd430d816),LL(0xe74dd574,0xf5ea27b5),LL(0x45e6d69a,0xe57442d8),L_(0x0000006a), + LL(0x8867f7e0,0x91a18dca),LL(0x52fb15ad,0x64cc9794),LL(0x889fc872,0x76b7b4b5),LL(0x516a4447,0x7f78f44e),LL(0xe0dc9367,0x03435817),LL(0x6c0ef141,0x3e179290),LL(0xdcc3815b,0xa243fcb3),LL(0x57d2c5d1,0x33e3e4cd),L_(0x000001bf), LL(0x8a5e2af7,0x373d3db8),LL(0x567532fe,0xa4edcdd2),LL(0xe2cdd2ad,0x313da102),LL(0x7dc4c171,0x9b6477b7),LL(0x10610301,0xd6614ed9),LL(0xe5dbb13f,0x093e9d03),LL(0xc78d8181,0x34692c91),LL(0xd1998555,0xfad9c4a4),L_(0x0000013f), + LL(0xdf7c0d81,0x22136d3a),LL(0x5150ed1e,0xf12f4a61),LL(0x48b602d1,0x58c86ca8),LL(0x8f3a438f,0x2ad94dbc),LL(0xfd28616c,0xa1741520),LL(0xfc8f344f,0x97e96926),LL(0xa2867b76,0x3f74f49a),LL(0xc963769f,0x9eafe4ec),L_(0x00000138), LL(0x880c04c5,0x8d3271ab),LL(0xeb904c8b,0x361247ec),LL(0xcf0e8b6b,0x9dc846a9),LL(0xf58b8dfe,0x1bd5a3dc),LL(0x46766ec7,0xabb872ef),LL(0x7028f76a,0x5976ea25),LL(0x7d56cad7,0xa7a4c1e3),LL(0x50e6e410,0xd9ef6dff),L_(0x000000a4), + LL(0xee967d04,0x54ca4d62),LL(0xa4adf367,0x2f1d9120),LL(0x9de3bdf9,0xa199c49a),LL(0x911112e9,0x918e1ab3),LL(0x51c4e324,0x1ab9377d),LL(0xdecbb2fc,0x089f9423),LL(0xfbdc7272,0x61643ec7),LL(0x297b6a31,0x8eafbdcf),L_(0x00000099), LL(0x380cfd3e,0xb9b29381),LL(0x9618730d,0x5c79e6e7),LL(0x984e3379,0x9a017cdf),LL(0x6a46a60e,0xb44ef6fe),LL(0x6fd9e713,0x8cf5836b),LL(0x2e3b6ebb,0x29b6614b),LL(0x741582d0,0xa7c94b36),LL(0xb93abf5a,0xc0822faa),L_(0x000001a6), + LL(0x7dad6b6f,0x6d40ef9f),LL(0x75d98fac,0x52ee8497),LL(0x4f994b00,0xb0754aa8),LL(0xae60032c,0x19b6eb82),LL(0xb89fa32d,0x3aea1e12),LL(0xd3d62cba,0xa47b84ef),LL(0x7b3e3f24,0x3738323f),LL(0xa1811a10,0xa83238ea),L_(0x00000101), LL(0x5a4fc143,0xe600e837),LL(0x2ba5692b,0x25fadbb6),LL(0x8c4ff4f6,0xad437e54),LL(0xfa9d42cd,0x14c8f3b0),LL(0x79e73eb8,0xa0355c3e),LL(0xee8fbd21,0xefee74e8),LL(0xb4ebba9f,0x0e987b86),LL(0x0e79123c,0xa0018bb1),L_(0x00000009), + LL(0xd08fa2ed,0x68def816),LL(0x3f12ff36,0x4b57900c),LL(0x7fffe102,0xd2939213),LL(0x70f61f2a,0x4ecb6d5f),LL(0x351a0540,0xca3d4a8e),LL(0x51a7737d,0x887af4be),LL(0xbc6bf04e,0xfca084af),LL(0xafb6ef2e,0x80de41d0),L_(0x0000010a), LL(0x9d26a31d,0xa72b2fa9),LL(0x9b7182ad,0xa970074e),LL(0x18bf55a2,0x056574a9),LL(0xb8d1ebac,0xeba9a5ac),LL(0x4bbdf7b3,0xd324a4b9),LL(0x20cc2ce0,0x56572fe4),LL(0x1a2b2538,0xf24f0245),LL(0xef07dd5e,0x5ab8b3cb),L_(0x000001cb), + LL(0x120fa71d,0x41cdedbf),LL(0xcbb3dcf6,0x8c3fb216),LL(0x19500d09,0xe213167c),LL(0xe814428b,0xac93cb34),LL(0x1a28a2b6,0x861cf475),LL(0xbc74e6e7,0xcc2d45ad),LL(0x0f8c1d18,0xbd9bdb71),LL(0x6d7baa7c,0x43067701),L_(0x0000017d), LL(0x41e3705a,0x8a8c2d8f),LL(0xc8929c33,0xc43c1d40),LL(0x819f1cba,0xdda7d3c4),LL(0x598c12f3,0xe612ee48),LL(0xaa092a4b,0x97324657),LL(0xd55e9103,0x1b8a4a06),LL(0xd7a8f2d0,0x010537d8),LL(0xf7a0ab83,0x9ae31bf0),L_(0x0000002d), + LL(0xb8878e45,0xf56f7c26),LL(0xac1feb24,0x4df5d838),LL(0x15563b3a,0x1ca4e8a0),LL(0xbf968a88,0x62060557),LL(0x3ca8c519,0x46507367),LL(0x743fec64,0x374e7834),LL(0xd6eda8e3,0xe0db390d),LL(0x64260f14,0x96c53e95),L_(0x0000010a), LL(0x929af276,0xb4ebbd85),LL(0x2786a497,0x2343b68c),LL(0xbc5660f7,0x3871cff1),LL(0xa03e99a5,0x32a3116c),LL(0x91a2e2b2,0x39a66a33),LL(0xf1e21170,0xb4a691a2),LL(0x0b59581c,0x760bf647),LL(0xbf35d6e4,0xccdb4699),L_(0x0000001b), + LL(0x3d62a61e,0x8ea4e81f),LL(0x6f0c46da,0x6349f724),LL(0xa1f6221f,0x3d1cb710),LL(0x801a6d7d,0x9a8daaa8),LL(0xdff7216c,0xaabb78f1),LL(0x0d054787,0x6a1b8dee),LL(0x9342cf54,0x7426ffaf),LL(0x8839548a,0x7e189575),L_(0x00000021), LL(0xbcb9c78b,0x645473ec),LL(0xf45138ac,0xcb977455),LL(0x51f3e82d,0x23de028c),LL(0xcb2096e6,0x1236013a),LL(0xd60fa53f,0x790031f5),LL(0x590da1dc,0x41383462),LL(0xd75ce15d,0xaac7003b),LL(0x5c3cf3c2,0xe97d1507),L_(0x00000100), + LL(0x37acbeda,0x552d3a3e),LL(0xf4eca93b,0xae1c95c5),LL(0xdc45bd28,0x0c12e32d),LL(0x5dd7eb7c,0x50ac538b),LL(0x692eb87e,0xc65147a8),LL(0xa055973b,0x8ff87281),LL(0x23507ab9,0x63636873),LL(0x1c85fb4c,0x794d2027),L_(0x0000017e), LL(0x8016a521,0xfe67d871),LL(0x0c89c0f4,0x7e7fa083),LL(0x3b0ba9a3,0x25bac099),LL(0x1416b2e6,0xcbc2cc9b),LL(0xbbcf2943,0xc5a1f7b3),LL(0x354fa11e,0xb195e363),LL(0x61adb945,0xcce31308),LL(0xfde526a9,0x5e8055b0),L_(0x000000f0), + LL(0x68b19904,0x7e3f21a0),LL(0x83926d83,0x58ff928b),LL(0x46424f50,0x50a21088),LL(0x656540b1,0xd69839e2),LL(0x2172157b,0xc836bb43),LL(0x34535e3b,0x1f818f5d),LL(0x61ec6b27,0xf4cd40aa),LL(0x8714bd57,0xfdb8302a),L_(0x000001c8), LL(0x553a3a34,0x0a6b22f2),LL(0x8b7033af,0xdbf4f3b5),LL(0x213a07cd,0xd71e271e),LL(0xfa9434d1,0xc069f3af),LL(0xd5d23e3a,0xc4ccd448),LL(0xe785990c,0xdd215a3d),LL(0x500536e9,0x43168909),LL(0xe45a1f48,0x9f92d8e2),L_(0x000000d3), +}, +/* digit=30 base_pwr=2^150 */ +{ + LL(0x0d6ad654,0xf661dbbf),LL(0x43121ba6,0x2325e379),LL(0x176edfca,0xf0cef68c),LL(0xa3861e28,0x617ac6ed),LL(0xa77e7f84,0x57535e8c),LL(0xd31f498d,0xf36e23d1),LL(0x546d78b2,0x2c3f8810),LL(0xcfc7d55e,0x156a1cb9),L_(0x00000091), LL(0xf8c0b462,0x974ce76b),LL(0x894a4c0a,0xc178af73),LL(0xe4d65f8f,0x5d4f42d7),LL(0xf71cb940,0xf73dac29),LL(0x1d35c689,0x32814192),LL(0xe3cb66f4,0x753255de),LL(0xaf9effca,0xa9814253),LL(0xd34e3d9e,0x22e23b71),L_(0x00000020), + LL(0x61e9684a,0xaa0bda51),LL(0x62c59939,0x9d4f255c),LL(0x1e39fae8,0x74c49bbe),LL(0x09372aef,0x180fc9e6),LL(0xde724860,0x163da12a),LL(0xfa823f50,0xa72a28de),LL(0x965a30e8,0x3c600eca),LL(0x905cf108,0x9f8b9687),L_(0x000000af), LL(0xd936a7a3,0x26afd7d7),LL(0x13810cfd,0x986aa03b),LL(0x37d1ddbf,0xeede05c2),LL(0x2715d035,0xb7ae0b88),LL(0x95ef9e71,0x08124878),LL(0xe5042346,0x9f87f170),LL(0x3054f163,0xebc09360),LL(0xce2e674e,0x593b42f2),L_(0x00000054), + LL(0x123b05cf,0x673811ec),LL(0x60b858de,0xeb464fae),LL(0x677b9369,0xd5f16b47),LL(0x26383f92,0xc119870e),LL(0x3f8c6fe9,0x5da1cbb2),LL(0xf7124d37,0xf6c7c1d8),LL(0xdb2b9c75,0x96be948d),LL(0x93746dbd,0x9988eb57),L_(0x000000c6), LL(0xd9a7bbb0,0x03e8f45c),LL(0x3d8c21e4,0x9b0b40cd),LL(0xc1186513,0xb44deee2),LL(0xf970a928,0x2d95e66b),LL(0xa6ac8009,0x8387cee5),LL(0xbddad6f7,0xfec87180),LL(0x0d3ded17,0x2404e11c),LL(0x41ea3e64,0x725101e4),L_(0x000001e0), + LL(0xcbc282c9,0xc6a2f3a1),LL(0xa09feeb1,0x180b5e19),LL(0xc54628c6,0xe8c61be2),LL(0x773cefba,0x054eeedc),LL(0x90648d31,0x0005e411),LL(0x36489351,0x44b74925),LL(0x54e90646,0x573a22ca),LL(0xd626639e,0xa6074dac),L_(0x000001b5), LL(0xcb4398c6,0x9e2e1f28),LL(0x11161ac9,0x4f328fba),LL(0xaaf012b0,0xb74a91c1),LL(0xadb60a6c,0x0cf3c48d),LL(0x1b818269,0xf7c4e07d),LL(0x9eb0dacb,0x2e6fbed1),LL(0xaba09048,0x9ea1ef81),LL(0xaab8c6fb,0x4b567809),L_(0x0000016d), + LL(0x492f635a,0xdee1b8d1),LL(0xeadd7be3,0x42ed487b),LL(0xcb4bb355,0x508d338c),LL(0x1d927c01,0x671a9478),LL(0xd1e3ea8e,0x6482584e),LL(0x83bdc72c,0xb63d17da),LL(0xe52363b8,0x49266941),LL(0x4b78813a,0xcb9e3414),L_(0x000001cf), LL(0xfef1ce8d,0x1f691526),LL(0xb7f97367,0x8a234b55),LL(0xb87b73bd,0x107f953d),LL(0x2944bffc,0x7c0ce6fb),LL(0x6166fb64,0xe784fca9),LL(0x0a71a69e,0x864d9dbf),LL(0xa770d1de,0x1d767a82),LL(0x641a01bc,0xcb0ce972),L_(0x0000019b), + LL(0xab3cbf9f,0xc878d60b),LL(0xeb346a1c,0x6b8a06cb),LL(0x38f8292a,0x28e10a9b),LL(0xa02441ad,0x110ae3e5),LL(0x374d8f2e,0x9df680d7),LL(0x622d31b8,0x0be1994b),LL(0x98b8d29a,0x35da2573),LL(0xcf273b8e,0x5a38591a),L_(0x00000099), LL(0x9b98c33f,0x49364b7a),LL(0xd85cd33a,0x18db5402),LL(0x71a1b4e6,0x7ccbb0bd),LL(0xda26853d,0xc76e0476),LL(0x1360631f,0x888e44f3),LL(0xf6b0ad63,0x2c3af0f8),LL(0xbec71f59,0xdbf01e8d),LL(0x723b0fd6,0x92661703),L_(0x0000000b), + LL(0x1651d7c1,0x28ddccde),LL(0x38aeac57,0x4e993e85),LL(0x0db5dd87,0x38abc090),LL(0xb465add4,0x0c1739c3),LL(0x43d0e74a,0x70bd3e21),LL(0x0b277d58,0xac3af0a3),LL(0x7b2c5422,0x770a41ce),LL(0x08580ab5,0x9864e070),L_(0x00000019), LL(0x9dfe51ae,0xe88e2a8f),LL(0x6783af82,0x37cfc10e),LL(0x6261464c,0x8e8c7510),LL(0xcc9c836e,0x503598b9),LL(0x560d6425,0xcf7c6100),LL(0x4d90b834,0xa8db43b7),LL(0x2444a629,0xd2cb3f5e),LL(0xcabe2a81,0x64aa2ef3),L_(0x00000068), + LL(0xb8ee9ddd,0x8b6de757),LL(0xa9eb572b,0xe5a924f4),LL(0x650813f9,0x4cddfbbc),LL(0x0f808102,0x750529ae),LL(0x8dbdc23e,0xfc407a67),LL(0x3db36c6d,0x549e5c64),LL(0xadee9ab1,0x55d46bd9),LL(0xacadd1f8,0xf68182d8),L_(0x000000ed), LL(0xeef3f12f,0x66e2fb66),LL(0x24a72828,0xe75f104b),LL(0x50b3c877,0xe38bb301),LL(0x2f8590fa,0xb7b5535d),LL(0xf87c6208,0xe1b50eae),LL(0x41ba355d,0x3f0d0c45),LL(0x8bfe9602,0xdc159699),LL(0x3cdcf2ea,0xab8c033f),L_(0x00000141), + LL(0x7513c344,0x29dba96e),LL(0xc3f8209e,0xb1d945a2),LL(0x08e3fd6a,0x6511a3da),LL(0x9263ef8c,0x2562d483),LL(0xd579038d,0xc4c88945),LL(0x5094d203,0x75e4003b),LL(0x54ec1258,0xbe6102b0),LL(0xe7874a8c,0x8d34a4cc),L_(0x00000039), LL(0x777964b9,0x018d87b3),LL(0x19a05999,0xaacd7c73),LL(0xd3cb884f,0xe794b313),LL(0x5a8d6b1c,0x598893b1),LL(0x47ab4f51,0x7e862cb6),LL(0xcd145d37,0x58ebff95),LL(0xa0ddf0aa,0xcb716afe),LL(0xa0791796,0xc7f724f2),L_(0x0000009e), + LL(0x69c35453,0x5cadd4b7),LL(0x080a8ec1,0xb97d34b1),LL(0x7709d928,0x24150cc5),LL(0xfda92711,0x9f76ea4a),LL(0xa5dd93a6,0x4e4f7b83),LL(0x826a2138,0xb1f097c8),LL(0xdb8dc9be,0x877e5a70),LL(0xf1a434cb,0xdd51585b),L_(0x00000174), LL(0xdd348044,0x7f07e424),LL(0x166eed95,0x061bf4f5),LL(0x469e3126,0x06b67307),LL(0xacfcc07d,0x87971f8e),LL(0x96d964d3,0xe5aebd3f),LL(0xa4d18cb2,0x5d286291),LL(0x3fbd829f,0x7560bbae),LL(0x277863a6,0x6e83e561),L_(0x000001b3), + LL(0x4a51a459,0x6a2ec0c8),LL(0x6902a948,0x82ea938a),LL(0x1db5acbd,0x9ed742a7),LL(0x26e981b2,0x64d1ad56),LL(0x075f4b10,0x30adf93f),LL(0xfd5008eb,0xdc51091f),LL(0x7f4f1467,0x907912b5),LL(0x0fb17ba1,0x567270fd),L_(0x0000014f), LL(0xf60b44cf,0xbf940606),LL(0x18337830,0xabbf9925),LL(0x7019fd78,0xbb5e1175),LL(0xc937b351,0x1359c463),LL(0xd19eff42,0xfe68dfe8),LL(0xa8892734,0xed1005b7),LL(0x7cc639ba,0x780e1feb),LL(0xb6ff755e,0x1f0082fa),L_(0x000000da), + LL(0x35763b77,0x191bfbe8),LL(0x87367459,0x58859da0),LL(0xd000c521,0x4373d9cc),LL(0x560dbafd,0xfeee235e),LL(0x8d303a3e,0x1fe980f9),LL(0x2a6082ad,0xb5244f01),LL(0x567ed43e,0x8306748e),LL(0xa7eddca6,0x4e531e38),L_(0x00000195), LL(0x65ee7784,0x100101b4),LL(0x4e959563,0x7ab1df8f),LL(0xbcb6c605,0x0218cd6f),LL(0x3a152b14,0x217b7b09),LL(0x9b32670a,0x7924c99c),LL(0x8550cfd6,0xf9af0b38),LL(0xda396f8c,0x27557bfe),LL(0x01351543,0xf74a0d9f),L_(0x0000018c), + LL(0xadf39ad8,0xafc3d641),LL(0x7e899074,0xeac59b4a),LL(0xab6f7e5f,0x9036a3e5),LL(0xd5685de7,0x32b71856),LL(0x6c3ebc40,0xbe82a80b),LL(0x46fa8ac4,0x8d567d33),LL(0x8f1ba3f5,0xe3d61024),LL(0x9622947c,0x175ff060),L_(0x0000006d), LL(0xbeeb648d,0x79460a8f),LL(0x28338621,0xa409e48e),LL(0x6cee22e8,0x04f98fee),LL(0x448a258d,0xb3e86ccf),LL(0xedd8a07d,0x94212741),LL(0xe7c10493,0x0eae65b6),LL(0x72b816f3,0x3c05e156),LL(0xaf3b8cf2,0xbeed59dd),L_(0x00000111), + LL(0x01f1e3a2,0x09ba81aa),LL(0x3d989afa,0xf91b3d7c),LL(0x24d1650d,0xff5c31f0),LL(0xdd5b9bae,0x20976038),LL(0xf21ca860,0x119240c2),LL(0xcea2f4f0,0x317b48b0),LL(0x894a28c8,0x18cdb521),LL(0x70a13f92,0x613d3aff),L_(0x00000022), LL(0xc0c32ed0,0xe8dd6883),LL(0x18e6d135,0xeb2f0e32),LL(0x2b49078e,0xf0a3dbd6),LL(0x80094f8b,0xad97e7ba),LL(0x7ec56e28,0x9e31d818),LL(0x1a28c019,0x2e151983),LL(0x924258ad,0x40e237bd),LL(0x4e48eb49,0x7b03fcb6),L_(0x0000013c), + LL(0x07f62c3d,0x023dd329),LL(0x3dc56c97,0x2622fb40),LL(0x2ec06f52,0xca023e51),LL(0x70809db6,0x4a297188),LL(0x1e390795,0x4a3bacea),LL(0xc30dbed7,0x0824bcd6),LL(0x3a9a9a8c,0x3e051eda),LL(0x98211435,0xbf2fd10b),L_(0x00000065), LL(0x532b9691,0x6a685349),LL(0x272a03cd,0xecc543f9),LL(0x54d18fe3,0xdf8cb8ba),LL(0x9b7c5d19,0x5f3f336d),LL(0x9e4ff288,0x5e647a61),LL(0x2dc0aea7,0xbdca4466),LL(0x24b8d191,0x33cd397e),LL(0x4bd62cf4,0xf66b542f),L_(0x00000030), + LL(0xdea01906,0x6acd9335),LL(0xcbf85583,0x52fb515f),LL(0x7808f963,0x374fc6d2),LL(0x5865c5cb,0xebbbb50f),LL(0xa4d0c81e,0x47f3a5b9),LL(0x29ed702e,0x97b4bc63),LL(0x64f0fada,0xf73be9b2),LL(0xe65e3bbc,0x42f9f14d),L_(0x000001d4), LL(0xd6414f5f,0x4729cdbc),LL(0x47ce590b,0xf363cdb2),LL(0x5be836dd,0x6a8da968),LL(0x5fd32e4b,0x49bdb981),LL(0x076e41c0,0x8d8f7528),LL(0x097db4cb,0x7fc1d50b),LL(0xf829470b,0x75b1cc67),LL(0xd2b6caef,0xd55324b1),L_(0x000000d3), +}, +/* digit=31 base_pwr=2^155 */ +{ + LL(0xcb47b0cc,0xf69ff50f),LL(0xfc1e2456,0x02b84001),LL(0x1c124be7,0xa6c9b545),LL(0x2857f671,0x07337c72),LL(0xb0a89f0e,0x7d3661d0),LL(0xaf022308,0x61f17db2),LL(0xd9b173b2,0xd0457b51),LL(0xf8c65404,0xefc1cd30),L_(0x0000006e), LL(0xfbb3972b,0xfffafb34),LL(0xc5bd6770,0xfc7a7db4),LL(0x0de59815,0x342e8ca8),LL(0x843b5602,0x0e1c9e4f),LL(0x3bfe9122,0x8b0b7c5b),LL(0xa1e2826c,0xe442b313),LL(0x88ce465c,0xf2ef9e99),LL(0x77217ce5,0xa10ff590),L_(0x00000082), + LL(0x3361b6ed,0x9441390c),LL(0x054f8022,0x7143ab58),LL(0x9b74e159,0x8a901ba0),LL(0x116652a4,0x9b4f3635),LL(0x0afb314b,0x45e2ee30),LL(0xd4622886,0x4d2f79f7),LL(0xb66e6167,0x298ff3c1),LL(0x2505aad2,0x27d64009),L_(0x000001d3), LL(0x43f093dc,0x0eb20dd5),LL(0x4b51c2ba,0x74c9cdac),LL(0xbf1d3648,0x10d4063e),LL(0x6b726013,0xc8c6fbaa),LL(0xf8b94ac6,0x6ce6639f),LL(0x91f488ec,0xf454066c),LL(0x24c600b8,0xf37706e5),LL(0x1cff656e,0x434286c2),L_(0x000000a0), + LL(0x6256aa55,0x35d5b009),LL(0x7857cb4d,0x2bf04d1e),LL(0xc85eb560,0xaf5c9697),LL(0x3e426a2c,0x140d9785),LL(0xe234a765,0xfae3a667),LL(0x6a198191,0x6a2fce6c),LL(0x3a779c8f,0x217e7e57),LL(0xb35dd0c7,0xb20040f7),L_(0x000000e8), LL(0x919a22a2,0x36df1d99),LL(0x46ee68e7,0x884f54d7),LL(0x2f9e3760,0x70670755),LL(0x1a8bd746,0xd3fc19b5),LL(0xc34c78ba,0xaf9a102e),LL(0x9b57be0c,0xfe21514a),LL(0x9e7c2e6d,0xde90d865),LL(0xd44207f4,0x19f36d3f),L_(0x000000a7), + LL(0xb1fd44f9,0xd877e284),LL(0x37f60445,0xca4191dc),LL(0x69f0b4df,0x358c7759),LL(0x12aaa285,0x72cf55e1),LL(0x7f71ae31,0x0ffea4f4),LL(0xfc352eb3,0x5b8d412a),LL(0xc7ffc3d9,0xabdbf74b),LL(0x239ccbac,0xd4b6acd1),L_(0x0000010d), LL(0x26f819d4,0xa6870d63),LL(0xd1598751,0xc6b0d1f9),LL(0xc925f0b6,0xa890fd44),LL(0x106c309b,0xcedd20fe),LL(0xc46673f1,0x2408588d),LL(0xebfbcf6f,0xb54153cb),LL(0xa52fed53,0x7b4aaced),LL(0x672bbf3f,0x84a22a21),L_(0x000000d4), + LL(0xe193ed1c,0x2197649c),LL(0xa6098bec,0x132b7114),LL(0xe879a5ea,0xbf33520a),LL(0x5ec11946,0xf7eb2f05),LL(0x76724ae5,0x8b00135e),LL(0xa281ab75,0xe322da16),LL(0x75ecccf9,0xf00478b6),LL(0x5f741662,0x77d420d9),L_(0x000000cf), LL(0x4fbd26f8,0x8deebf19),LL(0x38cf892d,0xdd1ae54e),LL(0x4a486822,0x8e9572bf),LL(0x15d5deb4,0x83965350),LL(0xa31f170a,0x098efd39),LL(0x225bfe44,0x3effcffa),LL(0xd17f63bf,0xf8e3659d),LL(0x72dce9ce,0x561fceba),L_(0x000001b0), + LL(0x6b2523f7,0xaed633fc),LL(0x573eaf11,0xc05113c8),LL(0x5f254d2b,0x283764aa),LL(0xee71c7fd,0x70135776),LL(0x88759ff7,0x33df5ba9),LL(0x84205188,0xd52265da),LL(0x809c0705,0x912507fb),LL(0x641067f4,0x28d91a94),L_(0x000001b6), LL(0x33e3aace,0xc5e6e2ac),LL(0x0000ebfa,0xa6c0565c),LL(0xced796bd,0x6c90c0d4),LL(0x100a3283,0xee187fc8),LL(0x82bcb3d2,0x8d7848e9),LL(0x290e6b62,0x4a59be08),LL(0x5ab586db,0xb9a00808),LL(0xf4b07e2f,0x210d8de2),L_(0x00000156), + LL(0xe2fa8bdb,0x224b3264),LL(0x7213c7fe,0x43204c94),LL(0x13a1a9d8,0xf7f1cdee),LL(0x68201c17,0xd60991d9),LL(0xbe9464cd,0x4334ef4d),LL(0x715fe2ea,0x590e3478),LL(0x7284a69e,0xe07f24de),LL(0x7c088851,0x5ce9bed5),L_(0x0000002c), LL(0x36040931,0x3aeb8798),LL(0x222d178c,0xa01cdb6d),LL(0xe0c1815b,0x29424615),LL(0xec65cc42,0xfd885c8b),LL(0xfd5df228,0xd9564da3),LL(0x9775d121,0xb060eb3c),LL(0xdc43087b,0xbf975586),LL(0x0c723af3,0x941c0856),L_(0x000000ab), + LL(0xfd05258f,0xbf0ac7a2),LL(0x744e57f4,0x8834334c),LL(0x2edb448a,0x4c1f9523),LL(0xc8e4d56a,0x85d4cde6),LL(0x0bd23e3b,0x83063d71),LL(0x45b52f37,0x14ca833d),LL(0x2012d08a,0xff85aaed),LL(0x02ccbe55,0x9fa9b95c),L_(0x00000091), LL(0x646e2555,0x04999b76),LL(0xf355b09a,0x9309a1f5),LL(0x00d64b66,0xb2bd55ad),LL(0x57889605,0x6b121bac),LL(0x20d91b65,0xed693b72),LL(0x1faab888,0x344453ea),LL(0x45d07a30,0x75e36d67),LL(0xf7e7a52e,0x86433618),L_(0x00000079), + LL(0x0a388dcc,0x9079f10e),LL(0x7efb5f88,0x2c050909),LL(0x1cc662d3,0x7e0de0a5),LL(0x5ee0da97,0xb01a8aa9),LL(0x4922eaaa,0xbf868cba),LL(0x64bbc9e2,0xba2129b9),LL(0x0afac1c6,0x38f86242),LL(0xc8be3270,0x7520a9f0),L_(0x00000139), LL(0x304a400c,0x0cf7a18c),LL(0x5d48ee16,0xc85d4499),LL(0x04528b19,0x2452bab5),LL(0x65b2b9c3,0xbcfb2531),LL(0xd43a545f,0xc03362e0),LL(0x07cc670e,0x5d9aafa1),LL(0x58f98004,0xd816f41a),LL(0x324a8340,0x352c0783),L_(0x000001c3), + LL(0xef15b603,0x4b2484fc),LL(0xfc2dc91c,0x3b5be485),LL(0xd7e9f840,0x42217cb5),LL(0x8585ec85,0x3deede9d),LL(0xa1f0053f,0x48c56ddd),LL(0x845902ce,0xb2e99028),LL(0xdbb111fe,0x8f6659bc),LL(0xf1537c2b,0x89960f5b),L_(0x0000015d), LL(0x9799e891,0x88a9e85b),LL(0x39c6986f,0x69af11de),LL(0x0fa555ee,0x0c555b9d),LL(0x411f3b27,0x62266b30),LL(0x0b0e864c,0x784a1194),LL(0x112da824,0xb7ec5b26),LL(0xc56950bf,0x8a57ba0f),LL(0x3866d81f,0x72e0aa00),L_(0x000001b7), + LL(0x74fcfd7a,0xf2f274e7),LL(0x9f7aad66,0xd84871e2),LL(0x040c2554,0x2a4885e0),LL(0x8ddb8ec0,0xbfd317bb),LL(0x2a407fab,0xaa27b70d),LL(0x17f03cf3,0x1bed7718),LL(0x8c3de6bc,0x34f5d378),LL(0x0e550353,0xfef609bb),L_(0x0000014a), LL(0x0902c90e,0xc5275edd),LL(0xd325a149,0x33824d71),LL(0x14d92534,0xba4131f2),LL(0xf74f4dc1,0x81fdb0c7),LL(0xd354ab8c,0xc33be6cd),LL(0x96e68610,0x7d362d2c),LL(0x967ca304,0xad3a9c9c),LL(0x90a06f8b,0xaf6da5b3),L_(0x0000007a), + LL(0xddf9e139,0xc1710f55),LL(0x67ff0e8d,0x7ef6718f),LL(0x601481b6,0xb39b462d),LL(0x57d09ffa,0xad90ba10),LL(0xf83bbbb5,0x918d94f2),LL(0xed4c7a16,0x2bee8d2e),LL(0x9ddb61a1,0xdadd0291),LL(0xde96ab74,0x2e5753e9),L_(0x00000190), LL(0x7de034dc,0xa3926dcd),LL(0x5af3e375,0x827a6eab),LL(0xeb250dce,0x08623cdc),LL(0x52408bd1,0x9a7d0e9c),LL(0x236fdad4,0xf66e3019),LL(0x55ed033a,0x55cf40ab),LL(0x67077bc7,0x33b49be6),LL(0x3d6972e6,0x34396ea4),L_(0x00000153), + LL(0x8bb989ec,0xa4c22061),LL(0x30374f9c,0x83feabc1),LL(0x5043f74b,0xf24a71b6),LL(0x0f58d08b,0x5ac8cda0),LL(0xe7084b9c,0x20120c5a),LL(0xc241d2a2,0xa700c2dd),LL(0x246b4a2f,0xe50e9154),LL(0xe1b127ec,0x240be13a),L_(0x000000aa), LL(0xbc8ef89e,0x0178da07),LL(0x4ac8c26e,0xa3abe616),LL(0xeaa2008e,0x58d98d73),LL(0x16a0bdbf,0xf5f03b56),LL(0x0dd5224a,0xafd2d956),LL(0x656cc265,0xe30a653c),LL(0x896d53dd,0xc8ac8028),LL(0x8038e832,0xe07a2ee0),L_(0x0000005a), + LL(0x20009e51,0xf7671c0c),LL(0xdb94fffe,0x0361d956),LL(0xbca8fdc3,0x860aa7a6),LL(0xff4ebfa5,0xca2b724b),LL(0xd506fbfe,0xe572f34f),LL(0x2e88a7d1,0x430c48ff),LL(0x74822e19,0xeb20b178),LL(0x623c0129,0x07cc6f01),L_(0x000001db), LL(0xa60b4906,0xe9244f5d),LL(0x8954a885,0x2bf3bfbd),LL(0xf3969954,0xa7e331fd),LL(0x80dc93a6,0x16b29c51),LL(0xe85d8098,0xfad960c8),LL(0x7931b35d,0x74ab3a3a),LL(0x2e570f29,0xf4422349),LL(0x54904daa,0x5e1f7007),L_(0x000000f2), + LL(0xa473f03a,0x11b4e5eb),LL(0x5620232e,0x8a138aa8),LL(0x46f706eb,0xa03d24cf),LL(0x6e11ca59,0x7337f5d0),LL(0xad37149e,0xfa3336f2),LL(0xb68bf40b,0xcb9ee77e),LL(0xa7c9f76e,0x8719bf3b),LL(0xf9bd4330,0x45e4e081),L_(0x00000196), LL(0xabe87083,0x4d1bc133),LL(0x8d32cc0d,0x1bd3eff3),LL(0xa11a2038,0xde1eb1a9),LL(0xa2e7f299,0xb382b9cb),LL(0xac50dfdc,0x62fa8c40),LL(0xe2272381,0xa696bb54),LL(0xf025e3e7,0x68bf08ed),LL(0x608f07d7,0x91eb5365),L_(0x0000002b), + LL(0xae8ee138,0xea56e1b7),LL(0x5f8128c4,0x028409b6),LL(0xe5e0d92d,0x8ed0e1c4),LL(0xf3b74f68,0xc55f66d6),LL(0x35d3f9f9,0xdeb2ab80),LL(0x3bde4296,0xa7cb6b64),LL(0x25e29f7e,0x9b9d057f),LL(0x087f5f23,0x17e3fac2),L_(0x000001af), LL(0x23c7d215,0xd463cbb3),LL(0xd926fd3e,0x014b12b6),LL(0xab9ee679,0x3a1bcb9a),LL(0x1f47e609,0x17170593),LL(0xf44f73dc,0x3b0a4387),LL(0xd2a12e51,0x3ce5c7cd),LL(0x473ec3b7,0x7f341e3a),LL(0x6aef1796,0x09a474c8),L_(0x00000038), +}, +/* digit=32 base_pwr=2^160 */ +{ + LL(0x1f0b504d,0xc2dc9808),LL(0x7f1bc655,0xb688a237),LL(0x67de245f,0xd7a61e34),LL(0x30b260cd,0x9aaf28a3),LL(0x9aeae5d8,0xd4e07803),LL(0x53d349d8,0xd7aea422),LL(0x38cabcfe,0x3728bd24),LL(0x25a9960f,0x58af5683),L_(0x000000f6), LL(0x17d640b6,0x816e52ab),LL(0x1bc21ee4,0x31a5819d),LL(0x26613d4c,0x2a5969b3),LL(0x1a8c1407,0xabfa75ee),LL(0xd357015b,0x7c563bc4),LL(0xd2086ecb,0xa4a80425),LL(0x9b8fafb1,0xc2661a2c),LL(0x547ef737,0xe7afb2d6),L_(0x00000020), + LL(0x9838a5e0,0x65726f32),LL(0xb7a9942b,0xa33e2204),LL(0x4a26b80f,0xbbf82a56),LL(0x73c6f40a,0x970dfcc9),LL(0xf9548526,0xf1c38e96),LL(0xd2bbae55,0x2ecb19ab),LL(0x1edd71d6,0x6d97496c),LL(0x2e20adf2,0x17e1cf32),L_(0x000000d9), LL(0xc3991164,0x76aaf44a),LL(0xb67e29ba,0x1031c67b),LL(0x3d1213c2,0xe37fdfde),LL(0xb4f3b345,0xb46f2bbe),LL(0xef5d5bda,0x53442227),LL(0xbdace910,0x75a65c11),LL(0x0e12dac1,0x99010c36),LL(0x58cdb1cf,0x06f25026),L_(0x00000071), + LL(0x49a4961a,0xee441882),LL(0xdeb1c61c,0xf8ff5eb8),LL(0x6080b71c,0x7b2ccc29),LL(0x214b75b5,0xffb3c6aa),LL(0xe80f53b9,0x90a50e70),LL(0xfeb156be,0x0211fd2f),LL(0xa94620e8,0x15422e55),LL(0x085db41e,0x20305265),L_(0x0000015d), LL(0xe6193074,0x139e1933),LL(0x50841313,0x976e986b),LL(0xb6d55898,0x36a0866b),LL(0xa443f795,0xe06bc0b2),LL(0x63ba00b8,0x734e5428),LL(0xdd7a73a3,0x213440e4),LL(0xb2efa382,0xb0905af8),LL(0xe95312ec,0xb084f884),L_(0x000000ef), + LL(0xc6e6f324,0x3f172c5e),LL(0xd8ddaafa,0xeb6e8784),LL(0x785f2ae4,0xf77d65ef),LL(0x4e5db162,0xdec5c58d),LL(0x2375c785,0x4a30bffa),LL(0xc92e0f7f,0x0c920bb7),LL(0x294b17a0,0x26f93d72),LL(0x0a9107e0,0xce9dc095),L_(0x00000111), LL(0x66f1f498,0x2b841c67),LL(0x72452329,0xb0490079),LL(0x0e7ddb4c,0x55646515),LL(0xc3ad47f9,0x4b2a0877),LL(0xd8708db4,0xa4c3de4b),LL(0xb4a9131f,0x938e9d24),LL(0x85e650ae,0x80176c45),LL(0x60bb2e49,0x0248559a),L_(0x00000182), + LL(0x9a9281b2,0x28cef71c),LL(0x2e3e2609,0x5311578b),LL(0xb15a4e84,0x66031c77),LL(0xc30c76cc,0xf2c06ffc),LL(0xc352a0e2,0xea471db8),LL(0x9a687b94,0x2e1e184b),LL(0xb1979864,0x08e1a1c9),LL(0x7d1d84cf,0xa36c823a),L_(0x00000062), LL(0x1fedfb4a,0x47b77555),LL(0x1b0d298e,0xe7833c92),LL(0x071e1319,0xe5e5ae43),LL(0xbf6e6f4c,0x48ff7cbd),LL(0x44726013,0xec042f31),LL(0x861a992a,0x820461f1),LL(0x0e5f80d4,0x5b728532),LL(0x588846b7,0x4edf14c0),L_(0x000001ef), + LL(0x9277436f,0x0f51608c),LL(0x41c6cf4e,0x15b1b366),LL(0x263e7b75,0x6eb6d459),LL(0x041a5063,0x53679a56),LL(0x6ef1d0df,0x9b4abcaa),LL(0xb47a0301,0xae975077),LL(0xd2d427ef,0x62f30c49),LL(0x5a3dfa91,0xc801e565),L_(0x0000018b), LL(0xac347e0b,0x68202783),LL(0x26d59f48,0x4e17501a),LL(0x3895e666,0x202e3866),LL(0xaa8031f4,0xd2af7613),LL(0x8ddf2869,0xa21cc1e5),LL(0xe13d84ff,0x5da3159e),LL(0x8f6eb59a,0xb87bbc9c),LL(0xdc5df9b7,0xb8b6006c),L_(0x00000171), + LL(0x86ea29f3,0x3e6aa5bb),LL(0x9e7a21c0,0xee3c40e2),LL(0x9e430844,0x91ca8307),LL(0x420584b0,0xfb05a033),LL(0x5dc3546a,0x515d7ef6),LL(0xdfae44d0,0x8e97acb0),LL(0xad35608c,0x1c181a0b),LL(0x85a78e5d,0xd8ba90d8),L_(0x000001ca), LL(0x26e7f38c,0x4b1cba50),LL(0x3d89eff9,0x1828d959),LL(0xb8883419,0x9cd1acbe),LL(0xe7788137,0xd9c16250),LL(0xf51b1fc4,0x2f4d66db),LL(0xbf985d68,0xe78a703c),LL(0x98e4fae0,0x8125e5c9),LL(0x9fe12466,0x7096d179),L_(0x0000015c), + LL(0xe90f79af,0x96c267db),LL(0x2de8af3a,0xd7a0da68),LL(0xfc2373c7,0x5ae71058),LL(0x00846c04,0xb05a94e6),LL(0x87910867,0x49ec9a78),LL(0x0df20f65,0xaecf973f),LL(0xd4a6c168,0x30604ed3),LL(0x0b50f6bc,0x2722d421),L_(0x00000134), LL(0x8348ffda,0x3c89badc),LL(0x32767a9d,0x76ac95ea),LL(0xdc1a4baa,0x3eced60d),LL(0x114219cd,0x2d3cddf3),LL(0x557cfa7d,0x4c14e1ea),LL(0xd40b6e23,0x77a3c466),LL(0x24ae1830,0x9bfca752),LL(0x8ee59e15,0x0d62fa0c),L_(0x000000c3), + LL(0xd968b8f1,0x98c15e86),LL(0xdbdbd0e0,0x13fe0c31),LL(0x3f1495d3,0x611ba4e9),LL(0xcaa1f174,0xd93815b9),LL(0xec434016,0x3bdec28e),LL(0xb9edffc7,0x7d039312),LL(0x995ffc03,0x340b94bb),LL(0xf4d0bdad,0xd62628f0),L_(0x00000155), LL(0xe589b818,0x874bb93e),LL(0xd381244e,0xb9a019ce),LL(0x2710057d,0xa746e7f7),LL(0x5f04bc77,0xc973f2cc),LL(0x16b90cee,0x45b7cdcc),LL(0x3bf24131,0xf860483e),LL(0xa97598d3,0xd873a041),LL(0x5da07fc7,0x13ee03df),L_(0x0000007d), + LL(0x4b42de59,0x04785e61),LL(0x6896551c,0xc769142d),LL(0x1f7de113,0xdc5c38a3),LL(0x6f6444e4,0x619b0fe5),LL(0x442a0f4e,0xc1f930e3),LL(0x0e3d13dc,0xc2166fc3),LL(0x16566439,0x1264bd78),LL(0x043b1c6c,0x55bd407b),L_(0x0000011d), LL(0xdab614fa,0x51809e05),LL(0x37cc449e,0xcbcd15b1),LL(0xc268f122,0xde98d3eb),LL(0xd1094f76,0x2f691855),LL(0x38e9385f,0x940e99ca),LL(0xebc0ca85,0x7a41361e),LL(0x633585a2,0xe77d0dba),LL(0xf4c9fedd,0xffae9098),L_(0x0000015e), + LL(0xaabe6909,0xa2f1a549),LL(0xf13eb703,0xc846b81d),LL(0xcf6235f8,0xba752969),LL(0x28bf7176,0xa83689cf),LL(0x4f491b5c,0xac203f35),LL(0xa5c72127,0x17a19c66),LL(0xc5180b7d,0xe3fefda7),LL(0x2a895472,0xbc0194d4),L_(0x000000ca), LL(0x23d607c3,0x854caa47),LL(0x822cdfe0,0x7cac3eb5),LL(0x3c7db833,0x13d80239),LL(0x03909920,0xd8e93f09),LL(0xde83b6de,0xb075d1a2),LL(0x53e966c9,0x372a1d5e),LL(0x5b917dec,0x60dd5294),LL(0x8284dac3,0xff014a15),L_(0x0000013e), + LL(0x9489dc63,0x73b6bc0c),LL(0xf1bfa63a,0x10296f8e),LL(0xabe3e152,0x9dd0aaa4),LL(0xd3d4285b,0x0c15dad8),LL(0x5f828ba3,0x3be85ac5),LL(0x343ddcee,0x2204e02a),LL(0x532735c7,0x7ba86652),LL(0x2a530b1b,0x262994c6),L_(0x000001c1), LL(0xe1b6b90a,0x391a6b29),LL(0x05dfaa4f,0x6b8878ef),LL(0x3e5666ae,0xb1b8a9fa),LL(0xa4a12d5f,0x9ace0b8d),LL(0xc27561ea,0x7b4c8164),LL(0xef8504c5,0xd8cc29d3),LL(0x16570313,0x483fc408),LL(0x3b7b5ec3,0x2f18c762),L_(0x00000183), + LL(0xa9c74e4c,0xb6ecbf65),LL(0x8116e2fc,0x5e8f5e16),LL(0x59e26819,0x5609fad9),LL(0x8fafa607,0x02dca647),LL(0x7fb0c319,0x1e28746a),LL(0x62d45955,0x6e8dafba),LL(0x53e7625a,0x83169dc2),LL(0xe60b1042,0xebf6fde7),L_(0x00000127), LL(0x801f0ca0,0x7b2d8bde),LL(0x5592a1b4,0x1e6bd0f2),LL(0xcdd5271e,0x566eb6fd),LL(0x7f5033b8,0x4ca0b581),LL(0xd99ab0fb,0xb6096f1e),LL(0x3953fc59,0xcf65a6f4),LL(0x1d2ec4b4,0x1920c542),LL(0xd24e43ac,0xbc37795d),L_(0x000000bf), + LL(0x5e44325f,0x154c2ad3),LL(0x9ab5e4b3,0xa83af5c6),LL(0xaf86c5e5,0x17feec16),LL(0xa5cec56c,0x98ec6557),LL(0x84e83213,0x0f7fdcf1),LL(0x4c26d215,0xffda8a76),LL(0x453ea210,0x9ecd3b2e),LL(0x5f3f4d74,0x45856be9),L_(0x000001e9), LL(0x634817f2,0xa68371b9),LL(0x1b7d95b0,0xe827845c),LL(0xee539828,0x8d12cb9b),LL(0xe4618579,0x7d751e1d),LL(0x49a508f4,0xf62e7726),LL(0x71d8ff6b,0x1aa5f1f4),LL(0x1b002961,0xb185989f),LL(0xc7af8411,0x436bb002),L_(0x00000174), + LL(0x8c5980e4,0x83b10389),LL(0x5487e28e,0x6c59c4b1),LL(0xdbe03ec9,0x5812b87f),LL(0x800f9a8d,0xa69e4288),LL(0x0042610f,0xa98baf31),LL(0xa41914ae,0x04c78aca),LL(0xad52d4dd,0x200e6b24),LL(0xe64f0db1,0xef061a8b),L_(0x000001f3), LL(0x93332071,0x9064a4d4),LL(0xf05bb7bd,0xdb0e1035),LL(0x95a8d7b1,0xbed0afed),LL(0x5aa18c8f,0x1db27276),LL(0xbed5ae9a,0x21d6647d),LL(0x87ff9181,0xd1b9171c),LL(0x25ddbbf6,0x6afd3974),LL(0x58651838,0xd5394b3e),L_(0x000001ca), + LL(0xd9ab3528,0x97acef3f),LL(0xdda16fb0,0x1fbdca04),LL(0xe90de335,0xff197a3e),LL(0x7011f9ba,0x10909fc0),LL(0xbf835536,0xa3d538e2),LL(0xd3c214c4,0xd1adfbd9),LL(0x4b2db047,0xa7800e16),LL(0xe30b9e3f,0x3ba0bb0c),L_(0x00000103), LL(0xf015a843,0x3ccb2552),LL(0xb20301de,0xc8c0dcda),LL(0xaf7c3af2,0x06c79c8a),LL(0x7eefe996,0x38fb5284),LL(0x7cb586d6,0x59bf5673),LL(0xec4f260f,0x36f200b1),LL(0x62ff887d,0x39132913),LL(0xe5ed3b69,0xc40f0d7a),L_(0x000000e3), +}, +/* digit=33 base_pwr=2^165 */ +{ + LL(0x5648dadf,0x9d8a516e),LL(0x02a3fb8a,0x5fedd472),LL(0xecb3edff,0x7fb9838f),LL(0x762220d1,0x8b9ac40f),LL(0x23ad98dc,0x59a8311e),LL(0xfb615d6c,0x86c784ed),LL(0xe6c85dc4,0xee5f8f84),LL(0x6bbf81a7,0x58d5bb86),L_(0x000000cc), LL(0x76fcfa36,0xa1d41ef1),LL(0x007acce1,0x20e9778f),LL(0xd8b8126b,0x438944de),LL(0x437a71b3,0x4e76c73c),LL(0x9a1b4b13,0x14a56abd),LL(0xb7385f9b,0x29b4de8d),LL(0x3115d582,0x91b40784),LL(0x15347258,0xba8c32f8),L_(0x00000055), + LL(0xd1af8588,0x99943818),LL(0x2684f683,0x9d27b5d4),LL(0x68a5f913,0xa3ed9c84),LL(0x9f9d03a1,0xe699de7f),LL(0xe3117424,0x6ddd7e41),LL(0x967769d8,0xf6fd89cc),LL(0x0e9e00b5,0x4a6926ea),LL(0x3d7b6393,0x5b068a8b),L_(0x0000011c), LL(0xa86aa414,0x297d21cf),LL(0x9a2aecb4,0xcf147f52),LL(0x251f8677,0xd2a35774),LL(0xf0bbad3b,0xbedc57bb),LL(0xfe5b3790,0xaa31f1db),LL(0xb3cb7422,0x01bb1e75),LL(0x476bcd99,0xb31cdbf6),LL(0x8c278bd8,0x6fb17125),L_(0x0000002a), + LL(0xc3ec92dd,0x19f12734),LL(0x3d48fbed,0xf69ad2bb),LL(0x49bdd26f,0x985b989b),LL(0x61bfbf26,0x451c21eb),LL(0x35f12cad,0xf237a30e),LL(0x680a082d,0x2751a3b3),LL(0x88ebe4c9,0xc7316941),LL(0x0887a8fb,0xa8bdfe94),L_(0x00000103), LL(0xe0d58839,0x356f89f4),LL(0xde19c8b9,0xeab9cd80),LL(0x77afef27,0xf941390d),LL(0x16f538f8,0x8c79f62a),LL(0x9a2c1a2b,0x84a907ee),LL(0xb7aa5d96,0x9877951e),LL(0xfe7d75aa,0x59fbafe1),LL(0xc17b983b,0xb437db42),L_(0x000000ba), + LL(0x577ceafe,0x3a57f7ec),LL(0x4ce56b58,0x1306d958),LL(0xce15377e,0x1e23a49b),LL(0xbad5b26b,0x2d98c317),LL(0xae8b11f4,0xdc523283),LL(0xf50073f0,0xe7af81dd),LL(0xab516099,0x519277c4),LL(0x6a29299e,0x8cb7cfdd),L_(0x0000000d), LL(0x4a1c8223,0xad29a85f),LL(0x9213cb42,0x37030b7e),LL(0x364e5e4a,0xf8a54d03),LL(0x771a3941,0xb7d507ec),LL(0xd6f8ad50,0xddb1def4),LL(0xbd493bf4,0xc65eeab3),LL(0x716822a9,0x7e2f6019),LL(0x1d5d463b,0x062fa75d),L_(0x00000128), + LL(0x635f0819,0x6ebc6aeb),LL(0x755f610d,0x7e269fb2),LL(0xbc7a68af,0x9a7e6748),LL(0x576c91d2,0xaa653529),LL(0x8b42e1e9,0xe03c250b),LL(0x9e921ac8,0xf313cd04),LL(0x500a0736,0x48b57315),LL(0xfbe580a3,0xd15496dd),L_(0x00000070), LL(0xa35133c9,0xe43286f3),LL(0x42537712,0xfad38cc2),LL(0x5ba8dd4a,0xe8e53c49),LL(0x940cf7d8,0x88cb201e),LL(0xe105c906,0x0310db91),LL(0x14eb5137,0xbdf5c752),LL(0x04b87caa,0x73be9996),LL(0x32ce177d,0x545383f4),L_(0x00000129), + LL(0x43d9b9e5,0x181fa26f),LL(0xe91dfab4,0x8f94d28e),LL(0x500e4763,0x031df707),LL(0x2cdd284c,0xfc76fd9e),LL(0xb532df91,0xdbbb6032),LL(0x95140af2,0x0796b18c),LL(0x1a08045a,0xf970af5c),LL(0xb920694c,0x325b81c7),L_(0x000001e7), LL(0xbe6d4fc7,0x6128ccb5),LL(0x68880de0,0x2e3ad7bc),LL(0xb9bdf74f,0x769e9e60),LL(0x43ac2084,0x0eb7035f),LL(0x71aa1b0a,0x443fc7a8),LL(0x9b9cb064,0x8d6eb3bc),LL(0xcda0b792,0x35030dfe),LL(0xcc362ccd,0x29fff962),L_(0x00000029), + LL(0x4b4a6810,0x01f40601),LL(0x78cfd6f2,0x993f944b),LL(0x042c6de6,0xe197b472),LL(0x7bbfb051,0xe877f763),LL(0xa554df58,0x82d5094c),LL(0x5d801ed2,0xd75061e2),LL(0x89c183e2,0x060481cf),LL(0xe8a754c6,0x43706037),L_(0x000000ef), LL(0x5f0ea03b,0xc842ce7d),LL(0x1ecea7b9,0x0c3c295e),LL(0xd56a995a,0x2352f8cc),LL(0x2d519fed,0x7a9172aa),LL(0x95d8bcc3,0x546f4f90),LL(0x6b8cea31,0xaeee4bb3),LL(0x3f188de2,0xb3d9fe63),LL(0x63e62bb8,0x9f32b579),L_(0x000000c1), + LL(0xad0e3d68,0xa42ee214),LL(0xde6a66c4,0x6c6c7d51),LL(0xc1ce9444,0xd2eee21b),LL(0xeaac0d5d,0x8f8f4a8d),LL(0x5914a3e8,0x755296fd),LL(0x6c394520,0xe647dd87),LL(0x3798ebb4,0x696a7a68),LL(0xc9fd6484,0x66ec9d8e),L_(0x000001d8), LL(0x20495f98,0xf4ca34e1),LL(0x01e46446,0x0fc27507),LL(0x4431e6d9,0x0b310d40),LL(0x9766b761,0xe5199614),LL(0x04e26686,0xae7e80f7),LL(0x4f7efe74,0x9829aa76),LL(0xd9535c6d,0x5702e183),LL(0x755a23c2,0x457bd92a),L_(0x000000a0), + LL(0x92e45342,0xf84e8b92),LL(0xa379a575,0xfe2e00bb),LL(0xf17caafe,0xf713e2fe),LL(0xfca28897,0x56bf2a80),LL(0x484598f6,0x6ed19617),LL(0xda495469,0x3fe63788),LL(0x9a48ed8c,0x32c6923d),LL(0xea4ef749,0xdd905e15),L_(0x0000016d), LL(0x948913ad,0xa7aa5cfa),LL(0xcd183286,0xb2b44bda),LL(0xf345a8f6,0xb4add52f),LL(0xfc8c57af,0x001d629f),LL(0x9943972a,0x1f5f64d0),LL(0xee2dc970,0xc7523ceb),LL(0x078e50ed,0xa1b8fb92),LL(0x98c1c85f,0x69d2866f),L_(0x000001f9), + LL(0xc2e67acb,0x225d5458),LL(0xae1049c6,0x1f4012ec),LL(0xe45c8c16,0x89c61650),LL(0xe63f6f74,0x97d5ef6b),LL(0x13c990c2,0x7718d93d),LL(0x3b2af534,0x388b9ecf),LL(0xb4a19bd4,0x53cfc179),LL(0xc67cc8de,0xea4e62f5),L_(0x0000003e), LL(0xa71fbd0c,0xd67d72c3),LL(0xa67e3213,0xb4e77b7d),LL(0x2c9d3a3a,0x77d06f89),LL(0x5e517015,0x66b06c1c),LL(0x79e0be47,0x25f78836),LL(0xacaba839,0xf6cdc997),LL(0x60da7988,0x18ee069c),LL(0x75dac3e5,0x028ed009),L_(0x0000015d), + LL(0xac3a25eb,0x77706fdb),LL(0xce2d42d6,0x121b5db1),LL(0xbfb3bb0d,0xc38da042),LL(0xcc50a951,0x690091d1),LL(0xe0527354,0xad28eb90),LL(0x6d30c1cf,0x4621b3fa),LL(0x72f783b8,0xecc35c39),LL(0x05168f18,0x7e7054f1),L_(0x0000015d), LL(0x1e8042a4,0x437313ab),LL(0xe9455bf8,0xe4a7314e),LL(0x131fad1a,0xb8e1f53e),LL(0xd17720a7,0xbbc2ae3a),LL(0x41e60518,0xde92e4d6),LL(0x53833db7,0xd91c6976),LL(0xa3c1ec67,0x002fce6d),LL(0x353e4fb8,0xf35678d9),L_(0x000000f1), + LL(0x23d51660,0xe8b6d7a1),LL(0xfb16d9c1,0x2d6fbafd),LL(0x4603abda,0xc1c342fe),LL(0xc3174b01,0xf763e29a),LL(0x6ef24fdc,0x081c9b95),LL(0x6ff0c881,0xadc9659b),LL(0xc6c4ce5a,0xb4df1c4c),LL(0x1e8123e9,0x9a4d9154),L_(0x00000087), LL(0x7529564d,0x08513662),LL(0x1126c683,0x7efb0353),LL(0xe6d3af24,0x506609c7),LL(0x31b758c2,0x8f74142c),LL(0x5c5f34e5,0x0a3e4fdd),LL(0x3f4b19a6,0xe42c81b5),LL(0xf8223898,0x57c04ea3),LL(0x21041b37,0x44625a29),L_(0x00000184), + LL(0x46eb3995,0xafb45817),LL(0x273a1b81,0xe782c707),LL(0x122cfd64,0xf60341eb),LL(0x55516c45,0x19dc551b),LL(0x646dbbd6,0x33015a2f),LL(0xc8d289cb,0x1e2ea096),LL(0x01dbc5f5,0x04e60127),LL(0xb40b7fdc,0xaa434764),L_(0x0000016e), LL(0xb59acf0d,0x3cf9666a),LL(0x4a435c55,0xd7f50159),LL(0xa122c995,0xfe948450),LL(0x52defdfc,0xb5bd3afb),LL(0x272ef1f4,0x702b6fc2),LL(0x86c9c7cf,0x578c41a5),LL(0xce279630,0xafedf374),LL(0x57fd35a9,0xdd29b0d6),L_(0x000001c5), + LL(0xa856b3f9,0x8c313c96),LL(0x81430d8f,0xb3ef9728),LL(0x10f97c7d,0x57ddefb8),LL(0x07066ad1,0xca00506e),LL(0x586f421c,0xdaf65ab2),LL(0x2bf4f170,0x2f754fdd),LL(0xf2415152,0x88f0654f),LL(0x18776438,0x5393b3f2),L_(0x000000ff), LL(0x61d716b0,0x560341d5),LL(0xd6250f20,0xce99e680),LL(0x4c66a708,0xd56bd29f),LL(0x440c3774,0x8b248864),LL(0x9f32acf5,0xad54b8ec),LL(0x99d6dad5,0x45a78e51),LL(0xedbfc6a1,0xa505dcaa),LL(0x28bf41f3,0x8a48ad87),L_(0x0000010a), + LL(0x5a6ac292,0x548d3329),LL(0x8505c5bc,0x76050884),LL(0x4dfc2894,0x6b686f2c),LL(0x1e02d4a1,0x9d97a4c0),LL(0x2a447f5a,0x5475b435),LL(0xc828b6cc,0xd2791aa0),LL(0xe6e9d956,0x3b328dfd),LL(0x69ef6cbe,0x988497f9),L_(0x000001b0), LL(0xdf0efa6a,0x628f0906),LL(0x503dd445,0xc52d4b69),LL(0xdd2f1758,0x438796f6),LL(0x16280d32,0xce2abc46),LL(0x2fb22aa7,0xbdfd0070),LL(0xa5833469,0xd5120c6e),LL(0x80d303f0,0x047308c9),LL(0xd719acb8,0x2a731dfc),L_(0x00000036), + LL(0x024c2f1a,0xfb9cf085),LL(0xff178cc9,0x717cdc0a),LL(0xcd1f6670,0x8870fa8c),LL(0xc4d58854,0x99c44c6b),LL(0xd627431a,0xd7a4c31e),LL(0x552f232d,0x85daf88c),LL(0x940140f0,0x1d886818),LL(0x9aa8211a,0x16e4c1b0),L_(0x00000012), LL(0xe6c31591,0x4b6cac59),LL(0x3374279c,0xc878a0ba),LL(0x8991eda2,0x84ea0b3f),LL(0x32e3b4cf,0x5e729a39),LL(0xcc5f3102,0xd47222c0),LL(0xb4346c5b,0xc5c9ba94),LL(0x2995032e,0x41a4babe),LL(0x7ddb493f,0x7b6e042b),L_(0x0000004e), +}, +/* digit=34 base_pwr=2^170 */ +{ + LL(0x982798bf,0xfe921c0f),LL(0x079475b7,0x410ea1a2),LL(0xea0fd52e,0x77d4bbcb),LL(0x212e44af,0x260a54b0),LL(0xc66a7d1f,0x4269af2e),LL(0x4993bda8,0xd04f3479),LL(0x0b15e358,0x0bdfadc5),LL(0x1c67a4d3,0x2250ea3d),L_(0x00000091), LL(0xe7bebfaa,0x2783de4f),LL(0xfb63579e,0xd5ac84fd),LL(0x1abe0cba,0x4b8a145c),LL(0x84082001,0x5d987c51),LL(0xcfadaba8,0xd9eba9aa),LL(0xf5fccfd5,0x82de291a),LL(0x85e551a9,0x372c4557),LL(0x5e2bcee4,0x9d89842d),L_(0x0000009c), + LL(0x088ef390,0xd17b0f39),LL(0x5ae74e03,0xb17b1a43),LL(0xfbdcdaf3,0xe5084910),LL(0x63c90868,0x9102285b),LL(0xd8e63c01,0xd5454d88),LL(0x80d185fe,0x50f99e23),LL(0xf9e19dfe,0xce8d3eba),LL(0x728e09d7,0x51277498),L_(0x00000015), LL(0x031ef4b2,0x777fda1b),LL(0x7188feeb,0xf597fdfd),LL(0x6801e0f6,0x29652f82),LL(0x252e9d17,0x58dec034),LL(0xc6aa0c9d,0x43cc68d0),LL(0x6779b37e,0x9c62a4e7),LL(0x8d509f56,0x0558ca70),LL(0xd90c4133,0x56b5657b),L_(0x00000169), + LL(0x88fe9cc9,0x9ea07210),LL(0xa60d5a9b,0xe0116982),LL(0xb1b1d6d6,0x275ea7bc),LL(0x7f932848,0x607da14c),LL(0x3af5ede1,0x931400f1),LL(0x03040c84,0x3c889175),LL(0x6c5973c9,0xe7a0f614),LL(0x293b333f,0x5267024f),L_(0x000001bc), LL(0x034cc6c9,0x81f51a89),LL(0x99b337fa,0xc1ab5f24),LL(0x9bde774a,0x5f059cb6),LL(0x070a9fc0,0xdd8da34f),LL(0x8499182e,0x7e9ea166),LL(0x829389a7,0xaf460691),LL(0x5d843a97,0x6edc8515),LL(0xf45adbcb,0x1fe7439d),L_(0x000000a0), + LL(0x56937c27,0x8e9008a5),LL(0x241f1037,0x92193f76),LL(0x4e7ecf00,0xf8905d70),LL(0x28097f48,0x6b4870ad),LL(0x389acac8,0x2f86eb6f),LL(0xc3b9a313,0xfe5a3ffb),LL(0x9c6b9598,0x14fb463a),LL(0x2f429f10,0x40890855),L_(0x00000006), LL(0x41024dec,0x530c94ae),LL(0xd0399afa,0xac70ca6d),LL(0x7da5ef17,0x854eb299),LL(0xe2c80b49,0x4afd62b1),LL(0x77d7cf10,0xf0b13757),LL(0xb8dbecfe,0xdfbd794d),LL(0xf21b1b05,0x47404dbf),LL(0x96f1e68e,0x28abdaf2),L_(0x00000009), + LL(0xfb12ce5f,0xe27f7207),LL(0xf97a3f2a,0x787c8ad9),LL(0xd2383086,0x5dd8b1e6),LL(0xfa851816,0x13c110cb),LL(0x0056cac9,0xffc6bc3c),LL(0xca2b8de4,0x9e086187),LL(0xd596553e,0x4495145a),LL(0xa323bbac,0x799ae6f9),L_(0x00000064), LL(0x0aadfb75,0x53c95598),LL(0x813fad43,0x8941d128),LL(0xee24f158,0x81fe1387),LL(0x7ca3f8b2,0xec9a8f90),LL(0xf4bc106e,0x14a7e155),LL(0x9b049dce,0xacb41c88),LL(0xf8e36863,0x1985dcc1),LL(0xc3075358,0xa78ad338),L_(0x00000117), + LL(0x2801b8c1,0x764f13da),LL(0x1663cb94,0xef025b32),LL(0xdbea0296,0xc7c10036),LL(0x846d4ce1,0xa4ebe01c),LL(0xdcd331ba,0x36bdd387),LL(0x165ca514,0xbf0ef724),LL(0x1500e9b6,0xf3d31456),LL(0x2e001ed2,0x0726f097),L_(0x00000169), LL(0xc4ef20e6,0x8451ea7f),LL(0x6ab1aeac,0x04486599),LL(0x2c2e44e3,0x2f540159),LL(0x22a4d1df,0x2edd9124),LL(0x1b2aa406,0x2d29f8fe),LL(0x3d860387,0xaed1f58f),LL(0x2d78d5df,0xbde871a5),LL(0x65a5c46d,0x6c0a2f54),L_(0x000001f5), + LL(0x41cc93dc,0xbc829d92),LL(0xb48b90b7,0x41e85ef8),LL(0x52345df2,0xdc154eba),LL(0x0472e3d9,0xf8b4b2db),LL(0x59486c6e,0xd8c1f468),LL(0x2a84dd3b,0x1d593d50),LL(0xdf33e197,0x775fa504),LL(0x0cadf964,0xa92cc156),L_(0x0000005b), LL(0xe34e3a5e,0x6a0487ca),LL(0xfc3c5102,0x03084458),LL(0x9fa6a745,0xcfa05014),LL(0x51d7c6b7,0x8f18942a),LL(0x8c314152,0x2258ef9c),LL(0x789bb4fe,0x5dcef195),LL(0x1bcd3685,0x2b822a02),LL(0x4e898c2f,0xbded6e36),L_(0x000000f9), + LL(0x8bf4d11d,0xaa163689),LL(0x5ab01bff,0x58bf7fb7),LL(0xba4b1f3e,0x50bc67e3),LL(0xe8b59cab,0xcea4689c),LL(0x0d30cf8a,0xaf1932a3),LL(0xb3d1d8ed,0x92c06e5c),LL(0xfa7949e4,0xb16d8b25),LL(0x6f41db2d,0x10d851b9),L_(0x00000106), LL(0x66676913,0xb154a2b3),LL(0x96d36fe2,0x09d47ca1),LL(0x766e2a61,0xf1863dba),LL(0xa8ef9263,0xe92b5a5b),LL(0xa5da163b,0xcaad9918),LL(0x520c8298,0xf5e79189),LL(0x0a27963a,0x4ab05f91),LL(0x20b8c3b8,0xfd0103c4),L_(0x000001ba), + LL(0x342eb328,0xdd063123),LL(0xa94faf37,0x027545cc),LL(0x751ad636,0x5633398c),LL(0xe2af69a4,0xdb3a42f8),LL(0x9980ca80,0x3ef70c7f),LL(0x2f9f4827,0x03c8083d),LL(0x4bd7694f,0x2297619a),LL(0xcba6106f,0xb857e944),L_(0x00000130), LL(0x5e9d95f6,0xed99704a),LL(0x9b54a475,0xd04dd3a0),LL(0x45640d66,0xe5bc76a8),LL(0xb7f7aff6,0xffcfd663),LL(0x7c51db6e,0x1b1b7d77),LL(0x4ab9daa0,0x312b124a),LL(0xd1e4a043,0xa2044f37),LL(0x1147cf83,0xc70b0257),L_(0x00000184), + LL(0xf3d71f50,0x240110f2),LL(0x7cc2f02a,0xebf0be7a),LL(0x2ac9b5c2,0x24af14f6),LL(0x9a211862,0x782fa4b4),LL(0x50410353,0xf137e0ec),LL(0x1b26ae96,0x241ccb89),LL(0x2cdf1d3c,0x2b213449),LL(0xac6249df,0x063b93cd),L_(0x00000116), LL(0x1cd6f1cd,0x243cd7a1),LL(0xf821c5c8,0xd3358ef9),LL(0x1dea9bcc,0x06149e77),LL(0x744a2dd7,0x76a25a6f),LL(0x510fe3ad,0x126f991b),LL(0x2bff6928,0x9ff56b6f),LL(0x26743e80,0xb7342a0d),LL(0x75a539a6,0x1e395f1d),L_(0x0000018f), + LL(0x6b793a6c,0xc5b17046),LL(0x6c3972f8,0x30453d81),LL(0xa45c6e8c,0xf914e1ed),LL(0x3fd2d983,0x8df9d87a),LL(0x465d7bda,0x0b35e4f5),LL(0x6fe2ce33,0xd6b328dc),LL(0x54ed3799,0xfe08ef94),LL(0x7a45c9eb,0x18e443cd),L_(0x0000001a), LL(0xebd4b819,0x785e8d35),LL(0x203318e2,0x5c35d7f0),LL(0x7b61a2b1,0x652767b2),LL(0x861e2602,0x830e75ba),LL(0x44dc9f10,0x31d6ffa6),LL(0x2ba2cf1f,0x61cf1408),LL(0x6ea5aa79,0x8a5f9d9e),LL(0xc5f5c401,0x983aa3d8),L_(0x0000011d), + LL(0x8d73683d,0xaae3e45f),LL(0xebb6d11c,0x08fdeeb8),LL(0x0f274ee5,0x562c576b),LL(0xee620c83,0x10e47bae),LL(0x88c57185,0x279b8105),LL(0x919ff42e,0x927c894a),LL(0x7edf259b,0x23100a00),LL(0x169d16a2,0x2acb9ccb),L_(0x0000005b), LL(0x9179d06d,0xfee8415a),LL(0x94d74f07,0xcacca4b5),LL(0x4fb6e0e5,0x08cc549b),LL(0x08e788b7,0xc62edae5),LL(0xc2847dc0,0x9b9ef886),LL(0x64c8eee6,0x9deee406),LL(0xed24b57a,0xa5474323),LL(0xca2b9d44,0x16f12261),L_(0x0000006f), + LL(0x5e48d299,0x7ec4af3a),LL(0x1798ff0a,0x06583190),LL(0xce45de42,0xa85d801e),LL(0x661ec8ee,0xe6f87169),LL(0x12391657,0xa304ed8e),LL(0x70c4e172,0x8bed9dc1),LL(0xd437a386,0xa1738ce7),LL(0xd75a62c8,0xfe484c38),L_(0x00000079), LL(0x374f474b,0x9f0ace8e),LL(0xb886c429,0x274adb1a),LL(0x61800342,0x733bc7ba),LL(0x05688d04,0xe49410a8),LL(0x9d06b25e,0x1965c8e7),LL(0x2b710949,0xad70d74f),LL(0x3d588ffa,0x3d3fbe49),LL(0x7220b560,0xe246db1c),L_(0x00000016), + LL(0xff3c0838,0x8d34890c),LL(0x59239eaf,0x15030568),LL(0x6578691d,0xd8dd39f6),LL(0xcb5a2489,0x121c7f85),LL(0xf808f7b5,0x952a8bc8),LL(0x99daec7f,0x84b94629),LL(0xd8fb611d,0xbad11517),LL(0xcd32215c,0x967dfc54),L_(0x000000b7), LL(0xbbc3c9c3,0x4a7b1ca7),LL(0x3e19d6b8,0x4aecc72b),LL(0xc71b44ff,0xa89c3596),LL(0xc6ae9705,0x99c2157d),LL(0x4697a093,0x95d8264e),LL(0xd6e1d1c0,0x6704d656),LL(0x1e3c6190,0xc7b65104),LL(0x91499ef5,0x466ffc24),L_(0x000001d1), + LL(0x540a9b74,0x9b81bb10),LL(0x3ae92664,0x35d0ee3c),LL(0xc1f7e1a2,0x20c5e62f),LL(0x8f740935,0xb7936d32),LL(0x451ab7a1,0xc573c20c),LL(0x126bba09,0x3152bb2a),LL(0xa66454b3,0xb17e342e),LL(0x784051fe,0x3681b560),L_(0x00000027), LL(0x8fd9a547,0x8f5b18c5),LL(0xcc09f617,0x6e34c103),LL(0x22747cab,0xf8a96755),LL(0xde36110e,0x4dcfc108),LL(0x67ee6834,0x342676fc),LL(0x8502fdf2,0x5b48ae34),LL(0x3b4a1019,0x85dba2fb),LL(0x75c0d58b,0xda298efd),L_(0x00000088), + LL(0x42e6e512,0x335496bc),LL(0xd3205850,0x88067d33),LL(0xcf402bd3,0x0074be0b),LL(0x2913e673,0xe8db4e94),LL(0x62a0cb43,0xcf7beef4),LL(0x8c2ead81,0xf06de58a),LL(0x97eccd5d,0x501f23bb),LL(0x1d5954e3,0xa8b8e4e1),L_(0x000000b4), LL(0x025da1b4,0x1d598c1e),LL(0xbf9648fc,0x9987cb09),LL(0xd224f8ad,0xd88fba1f),LL(0x60665a60,0xd86a1d9f),LL(0xf1e7f754,0x26c4ad1d),LL(0x4acf77f7,0x7713e1da),LL(0x938971a2,0x0f78da10),LL(0x3b7fc94e,0x92811d7d),L_(0x00000039), +}, +/* digit=35 base_pwr=2^175 */ +{ + LL(0xbfdb04a0,0x5c665e2b),LL(0x4232c5cb,0x9a24517e),LL(0x26232f5f,0x5981cd79),LL(0x0a27a027,0xe253d4d8),LL(0x783b1d5a,0xd6c00bb7),LL(0x89b5ab0b,0x40ea4c25),LL(0x6c48caf7,0xfc5351cf),LL(0xa482e177,0x2b0e714b),L_(0x000000fd), LL(0x6ac73dd9,0x8552b5ad),LL(0x11881ba7,0xfb2067a3),LL(0x4ccac10c,0x5d449097),LL(0x9013dcbe,0x8873accd),LL(0xb2cf2a8b,0x380d70e5),LL(0x2c281733,0x4631440b),LL(0x7c3b711d,0x3747bc66),LL(0xd6b99662,0x423c70b2),L_(0x00000183), + LL(0x89dc8694,0xa8b11d17),LL(0x2eed227f,0x7fd9a16c),LL(0x916842cb,0xe12a5d02),LL(0x6758564c,0xe59ed474),LL(0x4b48f9be,0x8e675f35),LL(0xece126be,0xf7c75d69),LL(0x8ce3aca2,0x00f88d21),LL(0x9a768d60,0x26ea6ff2),L_(0x0000010f), LL(0xe69e2709,0x5d96ef4c),LL(0xa0efb2f0,0xac3a2f2d),LL(0xa99dc276,0x757c443d),LL(0x23ce0342,0x390d2a5e),LL(0x9b674e3b,0x7e7ea78e),LL(0x32e72b98,0xdca485e1),LL(0xb6c21856,0xda17d0d6),LL(0xee5bed8c,0x220788bd),L_(0x00000037), + LL(0x221d84fe,0x2333e9ce),LL(0x1a6d9a86,0xaadfe3f4),LL(0x56277e4f,0x389e2b48),LL(0xc71ed641,0x5717d1e3),LL(0x5f0642b9,0x56053a56),LL(0x042b6345,0xafc491b1),LL(0x5ee182db,0x9a47e510),LL(0x6ccadf49,0xf6da1632),L_(0x0000010e), LL(0x3d3d8156,0x05064c02),LL(0x708a5ae7,0xd681e121),LL(0x3b41c0e8,0xcbc4f74a),LL(0xe5968e75,0x47ee9e3e),LL(0x6b8f739b,0xe232789d),LL(0xcd2e53fe,0xd5500a30),LL(0xde9e78f3,0x2cad3174),LL(0x4522aa08,0x295cf494),L_(0x000001f4), + LL(0x6ca25a67,0x0e236499),LL(0x8d70cd44,0x61afc7ec),LL(0xd8467c51,0x4c9aa882),LL(0xbc140872,0x62a215cb),LL(0xad6d3cb9,0x6c4986c1),LL(0x912aaf7a,0x83691332),LL(0x6db2702d,0x7d4a1ecd),LL(0x3fa17e01,0xbf2405e9),L_(0x0000012d), LL(0x8090c5e3,0x8a064116),LL(0xe42ae3e6,0x395b06fc),LL(0x39938713,0x5bb1098f),LL(0xca3394a1,0x97734c1b),LL(0xe8c0bedb,0x1edfc62a),LL(0x9b0452cb,0xc661bc2f),LL(0x04c79c90,0xe6253323),LL(0x2a0dada4,0x2e4ae434),L_(0x000000fc), + LL(0x5105e93f,0xd1cc1e71),LL(0x144c819c,0x6629502b),LL(0xbd39770d,0x8c2f7831),LL(0xe5075a30,0x4ec45cef),LL(0x641b65dd,0xa56294ef),LL(0xe6aa4eb3,0x75854d3b),LL(0xbdb743c7,0x3fdd169d),LL(0x5176a409,0x181ac2e1),L_(0x0000003a), LL(0x9af21ff0,0x0ec035b9),LL(0x3f057fe2,0xa4b87bdc),LL(0x3feadb94,0xf7f87024),LL(0x5db56992,0x6a6cdc10),LL(0x57cd02da,0xdd69ecb6),LL(0xc54a8f0e,0xe1da3c2e),LL(0x10cf592f,0x8fe5cc2e),LL(0x3b4989f2,0x37d88e4b),L_(0x0000000f), + LL(0x156252b6,0xb01bd7fc),LL(0xb25b337f,0xe1e660dd),LL(0xac5d025a,0x6a73c379),LL(0xb69c2605,0xdede6af2),LL(0xb7e81b95,0xa1ae9121),LL(0x6cd030d2,0x5f7f754f),LL(0xb47d1e9a,0xc9b7c0f8),LL(0xe925d238,0xd6fa902c),L_(0x00000132), LL(0x3d941846,0xf95ace42),LL(0x6ab6a655,0x709a356f),LL(0x8fa78d47,0x9d32f258),LL(0xc583f5d3,0xab0a90b8),LL(0x5d68b6be,0x8bc51799),LL(0xcae9d65d,0x4a80ea4a),LL(0xd569fb10,0x2cb3b12f),LL(0x67b09db0,0x4b3e1e5f),L_(0x00000062), + LL(0x453b0260,0xf5df84a6),LL(0xcdd9e65f,0xf9cc5322),LL(0x1ae57f11,0x997b8e3d),LL(0x4ec38b17,0x52bddbee),LL(0x99728cf4,0x3daa3db0),LL(0xc592cfa0,0xe99b31ff),LL(0x0d3ad893,0x71adf8f6),LL(0x21a14a01,0x748065a6),L_(0x0000000e), LL(0x85220921,0x313c6b68),LL(0x45073a51,0x4026740f),LL(0xe3c1a79a,0x03ea00aa),LL(0x7f5aaba8,0xae0bdab5),LL(0x1d349675,0x81ecbbfd),LL(0x611cda3e,0x62377d6e),LL(0xc226bbb5,0x4eee5f15),LL(0xf8b5d257,0x8afee162),L_(0x00000002), + LL(0x6dca0b60,0x1e93cbca),LL(0x14655922,0x200324a2),LL(0x6c357ebc,0xfbe29569),LL(0x537e73da,0xf1c77b70),LL(0x59d41573,0x12b0a8e9),LL(0xc50a71dc,0xd18455d9),LL(0x7c9b3656,0x7fcbc173),LL(0xd9283b61,0x6acf8093),L_(0x00000097), LL(0x15b4734e,0xfa8b5737),LL(0xf0027024,0x3b38a173),LL(0x386bfccf,0xbbc99c54),LL(0xbdb95480,0x8bfbf241),LL(0xcc88d566,0x8353dffb),LL(0x7968e885,0xaa2a216b),LL(0xe22f661f,0xf0cc373d),LL(0x0c189437,0x5601679c),L_(0x0000001f), + LL(0x95c17af7,0xb1e74cee),LL(0x969661a7,0x9719c192),LL(0x390ae167,0x76ffd55a),LL(0xe6fc4921,0x17827dab),LL(0xb57cd8f2,0x4435c383),LL(0x16123417,0x1dcf73d3),LL(0x8d4cffd7,0x0c91ecfd),LL(0xe6e70928,0x8412502a),L_(0x00000171), LL(0x066d3430,0x019a0e1b),LL(0xecf807dc,0xfb488f96),LL(0x6c466766,0xedde1e48),LL(0x756a682c,0x37d6152f),LL(0x2661ee25,0x5b6f467e),LL(0x96e2b2d4,0xb97a8d49),LL(0x1c1589d1,0xbcf05602),LL(0xdf83ce24,0x04b7cee0),L_(0x00000197), + LL(0x182c5012,0xfca86967),LL(0x34e40148,0xfa3981f6),LL(0x1c864ffb,0x42879632),LL(0x5079d6d1,0x3e4b6047),LL(0x9eef5744,0x6e1e5a87),LL(0xfd7f7f13,0x38d5d2b8),LL(0x19b63788,0x1c2726dd),LL(0xc17815ed,0xf17abcb4),L_(0x0000002e), LL(0x9895b25d,0x7bb9a599),LL(0x40e55822,0x3d146be1),LL(0x7f28ae92,0x8852f582),LL(0x8cdd00a5,0x60ada16c),LL(0x7def110e,0x8158a85a),LL(0x1d1152d2,0xa55ae5c6),LL(0x4be61bf1,0x0a31606d),LL(0x8fcf413c,0xd625cdfd),L_(0x0000013c), + LL(0x16a0ecdc,0x6c3d008c),LL(0xd11d6fc4,0x0786f8b9),LL(0x26066afc,0x6f28cd76),LL(0x6a57afc2,0x9d41e208),LL(0x2ed8fbfb,0x32ce6027),LL(0xda94edc4,0xf08d764b),LL(0x94110774,0xd4093a46),LL(0x8526b334,0x084fdb6f),L_(0x000000a0), LL(0xe6b29d32,0x652dbbe1),LL(0x75164543,0x605ecb71),LL(0x6687cd0a,0x3962a1b6),LL(0xfe7869a3,0x347a147b),LL(0x1cab34bd,0x634a95b8),LL(0xbb85dfab,0xbfeffee8),LL(0x4995b282,0xf245a753),LL(0x69b18723,0x5d6e7794),L_(0x000001a4), + LL(0xcce2027d,0x643f2f8c),LL(0xcd45c4a5,0x24a0afd5),LL(0xa6b24112,0x2258c4c8),LL(0xfa87a5ca,0x8f855fed),LL(0x3975cb67,0xc55199f4),LL(0x9edc6298,0x5a48e9a3),LL(0x7312684e,0xf55daba0),LL(0xbfadaeb9,0xc9f5f377),L_(0x00000139), LL(0x382a7ced,0x5a3e0968),LL(0xc70ffd11,0xfcccb869),LL(0xba001f2a,0xfe8068fd),LL(0x124107bd,0x06868f7c),LL(0x28b9fe02,0x3821a909),LL(0x33728dac,0xac94afc5),LL(0x3e9edff0,0x7f67565b),LL(0x0bd10c69,0x250773ba),L_(0x000001ea), + LL(0xb6d26941,0x70ff7fb7),LL(0xad0ad081,0x7b1f1709),LL(0x88afd9fd,0x2c52599e),LL(0xa4b49d9d,0x58896d4a),LL(0x6df73899,0x001961cd),LL(0x1c7f535c,0xd4c3ed4d),LL(0x75c903a7,0x4c699591),LL(0xab8339d4,0x939fc682),L_(0x00000026), LL(0xf58af501,0x921bc00d),LL(0xe64a70d3,0x0644b2c5),LL(0xb7245016,0x4fad690f),LL(0x8e863833,0x52268bfe),LL(0xcab84fe2,0xc76f784d),LL(0x75b08768,0xbd5df903),LL(0x97114157,0x49a7a2a6),LL(0x5dbab306,0xb4ae419a),L_(0x00000120), + LL(0x8f91400d,0x24275a2c),LL(0xc241f782,0xba60fbb4),LL(0xc4fd93b4,0x616268c1),LL(0x0872941b,0x107f7964),LL(0x25e04f20,0x831b4388),LL(0x7786625f,0xc5f61924),LL(0x8de20083,0x791c6d52),LL(0xb0abde39,0x75c25ecf),L_(0x0000013b), LL(0x7b9d8c31,0xb58e09f4),LL(0x4c6bc5ce,0xb3112937),LL(0x38e27941,0xcee2666e),LL(0xca0e3235,0x8dbee896),LL(0x9b498dea,0x53066000),LL(0x0f289764,0x58ff5f8f),LL(0xfb5ee444,0xa7b5e140),LL(0xf9fb559a,0xac85e138),L_(0x00000072), + LL(0xc0135106,0x0d7ebeca),LL(0x20feaf54,0x19cc13ae),LL(0x3c5c75ec,0x38ba79ba),LL(0x78f3f1f0,0xf2dc8803),LL(0x911501c4,0x8fb64807),LL(0x6448cf01,0xa8bff66a),LL(0x206b2cb4,0xce9b312c),LL(0x195342ba,0x219fa1d7),L_(0x000000cd), LL(0xa18154da,0xe91053ed),LL(0x41af0398,0xadc91c1f),LL(0x6166dc26,0x5d9c3eef),LL(0x055887cd,0x90ea6dfd),LL(0x3d270166,0xa4280b95),LL(0x206854af,0x7b358dc6),LL(0xa6ae166a,0x03623eb4),LL(0x34af3892,0xe4258201),L_(0x0000013b), + LL(0x93905a5e,0xbb9f0c61),LL(0x99256667,0x3489213e),LL(0x27fdbbfc,0x1218ca33),LL(0x5630d2c7,0x5a83f00e),LL(0xbdc8df91,0x0d628331),LL(0x28ee96b8,0xbfe73e81),LL(0x6a5f7e06,0x2a7cd331),LL(0xdd16364a,0x8cd2a08b),L_(0x00000074), LL(0x51d38008,0x221d90fa),LL(0x814ecb88,0x8b5df20c),LL(0x00fc7920,0x76343a10),LL(0xc99f2520,0x14b68032),LL(0x71413b8a,0x654fe0dc),LL(0x9a173cb4,0xa9acd97c),LL(0x85a386e9,0x14a40bfc),LL(0x87bf160a,0x849e9970),L_(0x00000032), +}, +/* digit=36 base_pwr=2^180 */ +{ + LL(0xc2ffbb23,0x77384b0d),LL(0x16c289b4,0xf9601e0c),LL(0x9eabe48c,0x71ddca51),LL(0xb3f199d6,0x3fce7863),LL(0xa3ecba6f,0x2e01be3e),LL(0x67c58c7d,0xfbf4b701),LL(0x4893679a,0x2cb78d1f),LL(0xe019a436,0x15a3d7fe),L_(0x00000015), LL(0x746e7221,0x25f2840f),LL(0x160c51fc,0x516e72ef),LL(0x97156a16,0xd9625db3),LL(0xbf6e8398,0x3f5b2c0e),LL(0x651404d6,0xfc5b6523),LL(0xd10c4d87,0x8eef476d),LL(0xf40ffa31,0xe5d39771),LL(0xe3788025,0x98fa2547),L_(0x000001c2), + LL(0x658a6253,0xb2523e81),LL(0x8e050759,0x42659aef),LL(0xb0377d50,0x2b36823c),LL(0x419b9ae7,0xff957169),LL(0xf46fc17e,0x59705ceb),LL(0xb61ce7ad,0x2fffbd18),LL(0xa7135b60,0xfe9192a7),LL(0x96f2e092,0x30a3a8e5),L_(0x0000014d), LL(0xad967512,0x667c895e),LL(0x3da48897,0xeb732652),LL(0x467afe86,0x5b7a7cf8),LL(0x393a5ee2,0xf2568e46),LL(0xb15dd000,0xb79a3304),LL(0x203f1569,0xd91a36bd),LL(0xa5e938c0,0x1a346459),LL(0x521da127,0x88c575bf),L_(0x000000c6), + LL(0x633bf04b,0xc8c62a6b),LL(0xeaef0121,0x98cc53c0),LL(0x58d73540,0x925273a9),LL(0xc04448cc,0x73c56bf4),LL(0xc52be46f,0x542b800b),LL(0x39147d47,0x30298d6b),LL(0x44cb5cfe,0xb2312e04),LL(0x9ed4247f,0x4c4d89dd),L_(0x00000105), LL(0x97a9163d,0x460edd6a),LL(0xed4f4d5b,0x9206a582),LL(0xb9ca6130,0x3e18c6dd),LL(0xa3efafa9,0xa68f9bb8),LL(0xb2d783bd,0xb70a52c8),LL(0xc0dda564,0xdbe47728),LL(0x0dc789e7,0xe8a6481c),LL(0xe4119aa3,0x27f421a4),L_(0x000001ed), + LL(0x34050818,0xf301ee13),LL(0x055dadf3,0xd3d6ab94),LL(0x8803374b,0xa078817f),LL(0xc730e431,0xe1298465),LL(0xaae8170a,0xba08da98),LL(0x8b779119,0xf12876bc),LL(0x1b8f7410,0xbe46247c),LL(0x67bc98dc,0x18059808),L_(0x00000176), LL(0xab5cae23,0xf59de67d),LL(0xd0125b70,0x1682d3d2),LL(0x8c5ad3a0,0x9c7c1b26),LL(0x62fcf59a,0xa095cf63),LL(0x6482c8ad,0x5b79b1ed),LL(0xc253c84e,0xd6952b3b),LL(0x56917d1d,0xdfad9c37),LL(0x5c8f439f,0xa63232aa),L_(0x00000051), + LL(0x75e1f132,0x1f3a0552),LL(0x620ca4b5,0x48133bce),LL(0x765c9fcc,0x710e23a7),LL(0x7a6387e5,0xd9c29479),LL(0xa6621b41,0x9fe4eedd),LL(0x3bf9d9ac,0x5df19f73),LL(0x4cb8a304,0x4f51d70e),LL(0x45d5c96c,0x25c50ad2),L_(0x0000001a), LL(0x87a04f68,0xb3acd866),LL(0x4b6a5c45,0x9f7d19bc),LL(0x3f85a2b0,0x0758494b),LL(0xd50f6942,0x554c9337),LL(0x40c2407e,0x0ccb9c2f),LL(0xc5dfc1a6,0x11e7e482),LL(0x6ad44e8b,0x0fea5311),LL(0xedd080e6,0x9fd549f4),L_(0x00000188), + LL(0xef5cdd9d,0x7e7e29c5),LL(0x2b2e558b,0x3e6bc46b),LL(0x4702314f,0x56eeaa30),LL(0x06726fae,0x5ca44a1b),LL(0x2ee6f214,0x0ea8da79),LL(0x829cf968,0x141e7e4c),LL(0x723cb279,0x45b326cd),LL(0xdac514c6,0x5e8e8931),L_(0x0000013d), LL(0x62bd48fc,0x61e5ed08),LL(0x4a34e74e,0x83644940),LL(0xe1d4a984,0x1f65c56b),LL(0x3e5f4500,0x062ee718),LL(0xaa764b8e,0x6a39ef75),LL(0x9012ed64,0xbddef450),LL(0x42837f0e,0xfaa786a7),LL(0xf89ab588,0x474accf0),L_(0x000000d7), + LL(0xadd26e0e,0x1ef31aa7),LL(0x70683b34,0x5ed33b5f),LL(0x2190eb5f,0xf3278604),LL(0x8f6e3b2b,0xdb29e400),LL(0xc911a62c,0xd42f0700),LL(0x688f5189,0x7efff5e3),LL(0xc2de5c25,0xe2d46677),LL(0x6189c193,0x5de47c98),L_(0x000000ca), LL(0x0383ccaa,0xa7dddac1),LL(0xcaddccac,0xcf555803),LL(0x0778df17,0x5faf93e7),LL(0xb029278c,0x7cfbb523),LL(0xa7546c0e,0x33ef004b),LL(0xd52d052d,0xc8957290),LL(0x54a34c36,0xcc555faf),LL(0xa3e1b89d,0x77136cbc),L_(0x00000187), + LL(0x6c20e825,0x4760b5ef),LL(0x30fe1ead,0xd1479bf4),LL(0x3a480e70,0xba684ec7),LL(0x54c97c0a,0x99909719),LL(0xd306cb54,0xea1c5645),LL(0xcc5c264c,0x3d9ecc85),LL(0x39efac32,0x465cbfa7),LL(0xe63b20c4,0xe9cad749),L_(0x0000014e), LL(0x808827e7,0x13242934),LL(0x860bc182,0x41b298a9),LL(0x7a452bdb,0x51ceda44),LL(0x0786c3f6,0x53ca2965),LL(0x7845a5f1,0x7e0cd8cc),LL(0x5913baf8,0x060bc9cd),LL(0x0312de2e,0x79bfb315),LL(0xf7a14442,0xa16f8265),L_(0x000001f8), + LL(0xa3daf9d3,0x350ffc55),LL(0xd2d93315,0xecd8b90d),LL(0x88f5e22f,0x9eccd42a),LL(0xdc1f662e,0xc4f29c7e),LL(0x42b4d8d9,0x4f6798fc),LL(0xe485f1a4,0x46c699bd),LL(0x6c52567f,0xf81e6fde),LL(0xccefcbe0,0xcd5234c4),L_(0x0000015d), LL(0x821ab350,0xc73f9043),LL(0x8ce6bb52,0xbdeaccaa),LL(0x746080b0,0x3424a5b8),LL(0x0eee571d,0x785554a3),LL(0x4bc343de,0x6aadb674),LL(0x44652a58,0x2ff3c998),LL(0x5fd0a875,0x84f6f7fc),LL(0xba89cfbf,0xd08e7a6f),L_(0x00000002), + LL(0xacd3ee5f,0x533b8a60),LL(0x3e2d62d2,0xda0545e5),LL(0x476d9e76,0xb53693d1),LL(0x8749ddb7,0x78864741),LL(0x6623b715,0x737a1960),LL(0xb1899ac7,0xf216ba69),LL(0x057f8862,0xb25babc9),LL(0xcb288274,0x927aa4d0),L_(0x00000028), LL(0x000f8d74,0xd9a6f518),LL(0xfa70c9cf,0xfefa0627),LL(0xcdcaaa25,0xceb9750a),LL(0x15a2f18a,0x9cc57e80),LL(0xba45323a,0x0cadb63b),LL(0xe3f19ccd,0xa55c80d9),LL(0x1e511bb0,0x3bb4df11),LL(0x164359dc,0x3e271d06),L_(0x00000100), + LL(0xd00dafc7,0xaa6cb262),LL(0xb186d04e,0xe56a357b),LL(0x750898af,0xb3fa3a15),LL(0x4d60c192,0xc07d177e),LL(0x9679fa78,0xf75650e4),LL(0x3ad024b4,0xfc2fc8b2),LL(0x0bddcaf6,0x559b0ced),LL(0x604f3f34,0x995261e0),L_(0x0000009d), LL(0x5bdeacb3,0xfb2e6335),LL(0xc5822803,0x102a3be3),LL(0xc4f23418,0x2683d799),LL(0x446dc4f9,0x87d5a82b),LL(0x82fb7bba,0xba06b349),LL(0x859d405f,0xdacb2e84),LL(0xf7fdeed1,0xa51f1588),LL(0x8b67135b,0xc2217c58),L_(0x000000c7), + LL(0xbf16a7c1,0x8ed9d71b),LL(0xf4c69057,0x0ee9b6ca),LL(0xb90a3ad0,0x690215b5),LL(0xe1a72991,0x9dc86f3e),LL(0x4e4042ba,0x076b900e),LL(0x7d9520d4,0xf559233d),LL(0xa6fe5f79,0xd16f05cc),LL(0x6290cb9a,0x2c55a35f),L_(0x00000145), LL(0xa1a2502b,0x02fbcf5d),LL(0xc7fdf1f3,0x78d6c024),LL(0x3c5ac58d,0x180724dc),LL(0xeafba33f,0x0f2d4859),LL(0xa9ec392b,0x9adb7f75),LL(0x10b122b3,0xa1699e54),LL(0x8be6fae5,0xcfb1317b),LL(0x3a96cd81,0x9a5bff09),L_(0x000001c8), + LL(0x4c7da590,0xf6d8c638),LL(0xd287d869,0x6aabc1f2),LL(0x26b0f715,0xbdea2e8a),LL(0x8e33c1dc,0x689a9c3d),LL(0x8c56f036,0xa841ff6c),LL(0x527eaefd,0x10032f78),LL(0x0c199e97,0x6215f00a),LL(0xd8293042,0x0262f60a),L_(0x00000139), LL(0x116acfb2,0x0105c4ab),LL(0xa09207d0,0x2a3ccda5),LL(0x7549d228,0x67ad8625),LL(0x0483ecfd,0x12b83a0c),LL(0x0eee9667,0xe653fd39),LL(0x14bf0bf5,0xdd617912),LL(0x5b9e1025,0x58e59489),LL(0xb42fb14a,0x6b6fe3f4),L_(0x000000f0), + LL(0x332de310,0x82f2b927),LL(0xfe39c03a,0x595b30e1),LL(0xa1ad263a,0xcc294836),LL(0xe59896e0,0x55678ebc),LL(0xdab6cc2a,0x3b48be12),LL(0xf27aff9b,0x1525c60c),LL(0x72f22657,0xbfa65ac2),LL(0xe179fdb5,0x957d9762),L_(0x000001c4), LL(0xbe080757,0xaabb8ddd),LL(0x2e567a04,0xfc24eb81),LL(0xcd0abafe,0x3ab9ba57),LL(0x7ece5b5f,0x94233802),LL(0xfa49f2c9,0x192ad8a9),LL(0x7c6c9e7b,0xd9733712),LL(0x97c62d5b,0x608ec02f),LL(0x3b573c6e,0x90c6dba5),L_(0x000001a7), + LL(0xf559a7d9,0x41a926ac),LL(0xea7b4b5d,0x6a5e3301),LL(0x595fce21,0xee8aa9a4),LL(0x4300c92a,0xeb1b3325),LL(0xfb3d0ddc,0xe7231d36),LL(0xdd2028ea,0x0407b0dc),LL(0xb99d20da,0xf0f51dbb),LL(0xe418d5a9,0x31d74a02),L_(0x00000025), LL(0x6b8d0453,0xf7fd4389),LL(0xbfaf4600,0xe8d861a3),LL(0xf167dda3,0x92cf759f),LL(0xc46df950,0x32d3e4f2),LL(0xb7815d1f,0x91ed2fcf),LL(0x6d421190,0x12864b88),LL(0xf9dfcf39,0x04988ed3),LL(0x74a6a7f4,0x44aba25d),L_(0x00000120), + LL(0x924eb552,0x4033bcc8),LL(0xd518ffb7,0x2da2c2e9),LL(0x1ae0cd73,0x9a4290d6),LL(0x357cfbc1,0x784c1f06),LL(0x3ca1aed8,0x3fe20989),LL(0x85a8dedb,0x2f87969a),LL(0xc8eb2e93,0x550ff529),LL(0xfbbcc740,0x54bf85aa),L_(0x000000f5), LL(0xd7f84381,0xd5bc6372),LL(0x557f4f2e,0xc2efbdc0),LL(0x9d0c30f3,0x262ac2fc),LL(0xd5dddabb,0xa05b87d4),LL(0x769d1cf7,0xfc91e745),LL(0x4d0a4907,0xdcd38c99),LL(0x89250072,0xc453a288),LL(0x0dffae1a,0xe7245800),L_(0x000000a8), +}, +/* digit=37 base_pwr=2^185 */ +{ + LL(0xbc76a5c9,0x06d9177f),LL(0x5e3cbf74,0x39ed5397),LL(0x2f09def0,0x0caf736f),LL(0xbc534da8,0xfcc790fe),LL(0x46448c8e,0xb0ad47e7),LL(0x36b92fa7,0xc7671ca3),LL(0x90e92c64,0x637080ab),LL(0x52dfd8d6,0x5711517b),L_(0x0000012f), LL(0xf4a15818,0x56a0257f),LL(0x24412386,0x77234bc0),LL(0x364971ed,0x9b2d316f),LL(0x0cc8b1d0,0xdf4ae5e0),LL(0x307856bf,0x1468fa8d),LL(0xe3791c04,0xfc69805b),LL(0xfa589236,0x0c1fe733),LL(0x89a33762,0x37b57609),L_(0x000001e7), + LL(0x1a7b432a,0x8a01e6a2),LL(0x71b4886b,0x83120c39),LL(0xdae7cb78,0xf3efe6ce),LL(0xfd659d28,0xe1699713),LL(0x75625028,0x0252af65),LL(0xcd7c4a21,0x81fe2a3a),LL(0x7efc9c5a,0x2fab4ecf),LL(0x8ae2a5f8,0x92444155),L_(0x000001c0), LL(0x93563c95,0x95495dd4),LL(0xdf9b0e72,0xbb0facca),LL(0xab5a8f70,0x01ed29d2),LL(0x6b65b325,0xf439adfe),LL(0x2e9c2436,0x40a6c720),LL(0xbcd403e2,0x97776531),LL(0x4526a2b6,0x90cd1256),LL(0xa61dc2d5,0x170acdcf),L_(0x00000164), + LL(0xbcef9f83,0x8be8d883),LL(0x770de7cc,0x95107be3),LL(0x07c65e3e,0x780e3eca),LL(0xcf6ac96f,0x3d615089),LL(0x2549b641,0xf585b5b2),LL(0xacd5da79,0x4c0d8b5f),LL(0x3c8b5c5a,0x970b49ff),LL(0xadd6dfaa,0xc025c0e7),L_(0x0000005c), LL(0x34154da5,0x0b3c64dd),LL(0xc797b7cd,0xbc308343),LL(0x1f367813,0x138ae118),LL(0xe7bfbf3f,0x1f8c6302),LL(0xe3cc546f,0xef35ea2e),LL(0x904ac34e,0x852c3a0b),LL(0x2596f106,0xb1310ec5),LL(0x1e6e533a,0x763b1938),L_(0x000000bf), + LL(0xdd556b63,0x29b5e462),LL(0xab5e9c2f,0xc87a1f3a),LL(0x40c3ae00,0x8fdfc7cb),LL(0xf72aade9,0xf671ec86),LL(0xaa376ff2,0x369dd7b2),LL(0x0c4b0748,0x1a9eb6f9),LL(0xe5c39e83,0xb8bdb31a),LL(0xc9ef6929,0x5a4c5224),L_(0x00000112), LL(0x8d10b8d5,0x3d80ab90),LL(0x8a32a994,0x0edbbb7c),LL(0x51b7d4fd,0x9eb83ad0),LL(0xbe08eaa8,0x343de0eb),LL(0xc33cc9fb,0xad3c4d0c),LL(0x24b0953f,0x9c30b151),LL(0x582773fc,0x3a021a47),LL(0x75ab2c19,0xddfb8816),L_(0x00000173), + LL(0x334a8fdc,0x8da3d9ef),LL(0x644b8138,0x80531565),LL(0xf0f2d302,0x3bfd457e),LL(0x64c28e98,0x93b685b7),LL(0x24eeda6c,0x2b149454),LL(0x97f74e2b,0x1420398e),LL(0xce3c2017,0x93fa9e0c),LL(0xa9df8bc6,0x0fc6b820),L_(0x000001ae), LL(0x3c5470c1,0x52bf8c38),LL(0x06c9ae45,0x500fd912),LL(0x2fbca6d5,0x5e0fd35b),LL(0xe9e18d3d,0x39985525),LL(0x3bfa858d,0x3a3dab8f),LL(0x0bc682dc,0x51f2882f),LL(0x5632ba53,0xd2912672),LL(0xa5d16cfd,0xefb27960),L_(0x00000061), + LL(0xb762a667,0xf235a5ba),LL(0x39db43f4,0xdd5bbd91),LL(0x4d8ac038,0xc1e864b1),LL(0xbb5ec32b,0x9c3d8682),LL(0x0da419a0,0x7fa3e54d),LL(0xbbcc85f7,0x4911605b),LL(0x16bf46df,0x459ed701),LL(0x42b3919e,0x4a6f67ab),L_(0x0000014e), LL(0x89475032,0x761f44af),LL(0x78dc3aaf,0x7ec577f5),LL(0x443c49b1,0xcedfe95e),LL(0x4ca71a23,0x80d161de),LL(0x88a46fa9,0xa3a812c1),LL(0x8060703c,0x5d69c965),LL(0x52f25061,0xebe46263),LL(0xf14ae427,0x2518ad4d),L_(0x0000018a), + LL(0xce592fac,0xb29db4b3),LL(0x3eb4e951,0x73934c0c),LL(0xd205a31b,0xcde75602),LL(0xf7d9ceca,0x652846c3),LL(0xa5604560,0xf53ed6dc),LL(0xfcef8ee2,0xa3dda8b0),LL(0x73763d47,0x5dcfc88c),LL(0x3f72bc6b,0x61afbead),L_(0x00000062), LL(0x8b3b90f0,0x706c2fef),LL(0xb896e8ba,0x91189666),LL(0xa5f8d9e7,0x6dc25f9d),LL(0x98f8493f,0x29210ade),LL(0x77e1557d,0xc803167f),LL(0x80aaf764,0x746e916c),LL(0x9a02bf22,0x6f8c70cb),LL(0x692f9669,0xe6efe144),L_(0x000001e7), + LL(0x29ca6496,0xd6f014ad),LL(0x10e7e9c3,0x91edf75a),LL(0x042dda6a,0xfbe9047f),LL(0x6df69276,0x497f9141),LL(0xfce4035a,0xab982ab7),LL(0x1e6adadf,0xd973b8b6),LL(0x218a9fd9,0xe2c23f1d),LL(0x9e1c8c04,0x2274d47d),L_(0x000000b1), LL(0x397b98af,0x090ec3de),LL(0x272cecd7,0x6d724d9a),LL(0x50e492db,0xe32d2f19),LL(0x68f82a50,0x6bf40e9c),LL(0x0678afdb,0x4b25727f),LL(0xe6ae7819,0x06b77a36),LL(0xbb096d18,0xeedfa35c),LL(0xf41afd3f,0xc17d9b9f),L_(0x00000057), + LL(0x3437e67a,0xaac42698),LL(0x9e517311,0x90d691a0),LL(0xbbe7b23f,0x3efcc598),LL(0xc5b3ba4a,0xf044505e),LL(0x8a70a012,0x818530c1),LL(0xb73eeaec,0xd4496b66),LL(0x25f453bb,0xabda0862),LL(0x6dcb9832,0x76d60bb1),L_(0x00000060), LL(0x3a78a95d,0xa348f0b1),LL(0xdb8646ed,0x1af6f002),LL(0x451f5839,0x3087f4a7),LL(0xa66aaeeb,0x47adc893),LL(0xbec9934e,0x6e6950e9),LL(0xb35294f1,0x31d5e186),LL(0x7bf79296,0x590c3c8b),LL(0xc1942a2c,0x1b804ef3),L_(0x00000051), + LL(0x6a948f72,0xd23e1c8a),LL(0x01715db9,0x41d8f90c),LL(0xbbc2c6b8,0x4e56a842),LL(0x83c0fc75,0x986646d8),LL(0x4fe3bcf5,0x5fdbc4e4),LL(0x2ada0ebd,0x0e534106),LL(0x8c28b66c,0xb1f981f9),LL(0x56f04488,0x79a1b1cb),L_(0x00000058), LL(0x544a66a2,0x98d4263b),LL(0xb7ee4dad,0xb8425937),LL(0x9ce9983c,0xaff51ac5),LL(0x798d12f4,0x772fa5da),LL(0xb536f2fe,0x9c00b0c8),LL(0xb35431b3,0xf4789358),LL(0x2ee8e687,0x664cbdfe),LL(0x29120ae4,0xfa9435a4),L_(0x000000dc), + LL(0x1cd7048c,0xde30af0b),LL(0x64ca10f1,0x7af2cf68),LL(0xf23265e4,0xcdd4b45d),LL(0x4fc85e40,0x3c687440),LL(0x3ef2a535,0x6a698fc3),LL(0x9efabe8e,0x63e4d298),LL(0x18de82a4,0xb24c2816),LL(0x775b0ff1,0xf09e7eee),L_(0x00000129), LL(0x7c587948,0x1cbca914),LL(0x7dbc5bb9,0xcc9dfa8d),LL(0x432844d1,0xb35c10a9),LL(0xdb4db17a,0xf5e1db87),LL(0xf9910dba,0x86ff1ebc),LL(0xb2c9c01b,0x189bbc27),LL(0xa7d616b4,0x5df3f754),LL(0xe6cc2fbf,0x274e1d3a),L_(0x0000016e), + LL(0xac9d5c5c,0xcbf1d173),LL(0xd9410d43,0xb76d4376),LL(0x656599eb,0x900d071f),LL(0x2fb9b595,0x5fbadcc3),LL(0xe781b5f4,0xc0a2440b),LL(0x50f63654,0xbfcd2d0c),LL(0x1e522100,0x2f21286a),LL(0x4f742889,0x482b198e),L_(0x0000008a), LL(0x54f76137,0xd5622874),LL(0x47efa194,0x1f58794f),LL(0xbd93f7de,0xc2129e69),LL(0x5496a993,0x1b271db6),LL(0x8f7ac06b,0x5b18ae06),LL(0x78e56286,0x6111cab0),LL(0xbf1dc2cb,0x641b9597),LL(0x9c602e3b,0x6826b02e),L_(0x000000e4), + LL(0x391d1890,0xcc35919a),LL(0x2497cb5e,0x94f52d11),LL(0x4ef3c830,0xdf80522a),LL(0x94fd85cb,0xf72be2d7),LL(0x29671043,0x75499b11),LL(0x540e521b,0x0bd6a835),LL(0x5b01c741,0xc2f40e1e),LL(0x4828498e,0xb6d6e72b),L_(0x000000eb), LL(0x68b34fe4,0x87e9147b),LL(0x4ff41c4c,0x7947091e),LL(0x283731b8,0x31294652),LL(0xf259b874,0x0f36636f),LL(0x8ee00f38,0xfc2118ab),LL(0x8017118b,0x5f13103b),LL(0xc3d2d9af,0xc3feb59d),LL(0xca5c4199,0x39888318),L_(0x00000068), + LL(0x6a30f59e,0x5d7424e4),LL(0x59ff2a43,0x6be7810b),LL(0x30694fb4,0x78ec13fc),LL(0x92716d06,0x1d9c5aae),LL(0x8fbb9bb8,0x416a4a81),LL(0x1881c6a4,0x15a0a324),LL(0x489236d7,0x23235b6b),LL(0x685caeab,0xa5c2734b),L_(0x00000066), LL(0xa48020b3,0x383cc04c),LL(0x2d3601e9,0xd66a0119),LL(0xa6e151c6,0x9e61fd22),LL(0x8339ddd5,0x91be32a7),LL(0x235b6f9c,0x7155449c),LL(0x322c55d0,0xa7e5e410),LL(0xbe0a861c,0xce4ac258),LL(0x0323587c,0xd78b88ca),L_(0x00000146), + LL(0xadf63e55,0xb1cdbf59),LL(0x59991ed2,0x646f1d97),LL(0xae034cb5,0xcf9f8f62),LL(0xa6cfbf1e,0x9a35acdb),LL(0xb02eab43,0x0993f86d),LL(0x172ffcec,0xc65c756e),LL(0x1b44bc51,0x5ec6620c),LL(0x19230f70,0xc9e7a1a7),L_(0x00000196), LL(0x3da4f4f7,0xf7bed1a1),LL(0x28d9a36c,0x391142c7),LL(0x3d4288e4,0x0485a093),LL(0xf59f8fae,0x0209a097),LL(0x94df4e25,0x5fdf8f3e),LL(0xbc0be074,0xb3140419),LL(0xba7e0344,0x5cbb3260),LL(0x95c0673b,0x536a91bd),L_(0x000001a6), + LL(0xb05c5499,0x9f78e57a),LL(0x123d2b21,0xa3cf981a),LL(0xecb0183c,0x1eddfd07),LL(0x6998ed9f,0x8f90e3c6),LL(0x0e05152f,0xfad41bb2),LL(0x7dab5c5e,0x939419c7),LL(0xca783006,0xde605b32),LL(0x98ae5cd1,0x3d6039cc),L_(0x00000193), LL(0x5bb2b74c,0x590ae5b0),LL(0x68c4bf82,0xfdf4f711),LL(0x01a66f3e,0xa65b0015),LL(0x241e1da4,0x0665dbdf),LL(0x4c3387ba,0xf15f360d),LL(0xc88fe301,0x8acf4e85),LL(0x061a8e04,0x9ca9957c),LL(0x51bcc011,0x8585dfcf),L_(0x000001ea), +}, +/* digit=38 base_pwr=2^190 */ +{ + LL(0xa59f069c,0x37a0e4fa),LL(0xd96e52e4,0x3aebdd33),LL(0x29f2632f,0x4fd15682),LL(0x2c70c85e,0x4f3be789),LL(0x0a1634de,0xc7d9fb18),LL(0x638b44c2,0x3e6cb175),LL(0xe33499b5,0x0b60dc32),LL(0x2ecdad29,0xcf1fcbab),L_(0x000001d1), LL(0xfb1da9fe,0x5d1854ce),LL(0xb5b7539f,0xb9d47257),LL(0x96df1240,0x561ffc72),LL(0x5e9f9e9a,0x6d945271),LL(0x9f0df30d,0x25aea910),LL(0x1e814b45,0x4c475d52),LL(0x7037d6e7,0x2239acac),LL(0x6b60afbb,0x3a178a1e),L_(0x000001fe), + LL(0x7bee904e,0x3a760e88),LL(0x1c8cff61,0x662259f9),LL(0x3af1d337,0x798ee44c),LL(0x04c2f55a,0x7171b763),LL(0x6b42022c,0x451b89de),LL(0xe995dc45,0x0166754c),LL(0x5d7e90f4,0x45f5e9ea),LL(0x1437fe2c,0x5f81a1be),L_(0x00000183), LL(0xafbcd8ec,0x34c04a7d),LL(0x2e0b1aaf,0x62ecd7d2),LL(0xad928156,0x3ef4d947),LL(0xdc8b88ed,0x90778ccc),LL(0xd0a75501,0x1ea32bf7),LL(0x615d6df4,0x370394ed),LL(0x6cdce7de,0xa5a2d856),LL(0x5b5d94b6,0xb1500a75),L_(0x00000069), + LL(0x3dbc68d8,0x49071d49),LL(0x08ad1120,0x6075e725),LL(0x64ba748d,0xec7f443e),LL(0xf8b1338b,0xe9769df7),LL(0xe04bfcf3,0x276b48ae),LL(0x8c536f3f,0x51362d75),LL(0x91347181,0x7270c649),LL(0x8771d27e,0xd7277846),L_(0x000000b0), LL(0xbe64e850,0xf80d5fba),LL(0xb1ff417a,0x8984b71a),LL(0x7e8990b5,0x052a6765),LL(0xa10e9e6f,0xa3a8ec04),LL(0x68613043,0xf8edeb0d),LL(0x94eee364,0x38d79bc5),LL(0xb9b0283c,0x1f04d202),LL(0x240928e2,0xef3aafdb),L_(0x000001bb), + LL(0xcb0ca3e9,0x7b556d5f),LL(0x0eb6f5de,0xe1fefbb4),LL(0x92b00751,0xadf10d77),LL(0x245d985b,0xa78c0fd8),LL(0x1ec6c5bd,0x197cec62),LL(0x6f653476,0xf59e9de3),LL(0x29578b20,0x48b6a349),LL(0xdd081291,0x858df1e4),L_(0x00000060), LL(0x0140bb6d,0x4a2df7b8),LL(0x72cf54b6,0x702ccf08),LL(0x5ba02c9e,0x4fa2136f),LL(0x4316a469,0x62ca46c9),LL(0x2a601fae,0x6a69d6c7),LL(0xf210ce68,0x3ca9ff0a),LL(0x108647e2,0x7301dc8a),LL(0xbc72d54b,0xc0d011e4),L_(0x0000014f), + LL(0xb93b5399,0xaff92b49),LL(0x3a47424a,0x1313f0d7),LL(0xd74e27bd,0xc984d57a),LL(0xa310f0f4,0x7f2762aa),LL(0xf81b869f,0xc1c0028a),LL(0x73626037,0x16619502),LL(0xb6eafd5a,0x02aa41a3),LL(0x7a26f16a,0xee8393c6),L_(0x00000009), LL(0xa03a118c,0xc3e1533a),LL(0x770bf892,0xe55dcb14),LL(0x37abc785,0x49d52ff8),LL(0x88ea32f9,0xca2e3d46),LL(0xf41fb729,0x28df94aa),LL(0xd1d7fe42,0x6b931662),LL(0x453917fd,0xf0e1ad47),LL(0x15504e62,0xac5c9f2e),L_(0x00000008), + LL(0x320b74eb,0x1643c1a4),LL(0x253c03de,0x2114e9cd),LL(0xd7e1536e,0x1b41ae52),LL(0xc0d640bc,0xe9135dab),LL(0xb1a92fcb,0x5a9ef7aa),LL(0xf491bd34,0xd3e367c8),LL(0x6cfcfac3,0x6970f4aa),LL(0x28093242,0x12bc2a52),L_(0x0000011c), LL(0x174f8a3c,0x68fd0341),LL(0x14138a14,0x1a1ea358),LL(0xd7ebb375,0x0313c60f),LL(0xb31aaf76,0x7f4e2cd8),LL(0x63d1b78f,0x376b2b87),LL(0xea4746f2,0x9adb2628),LL(0x7159cd2f,0x3fee262c),LL(0x45cb3634,0x258e2340),L_(0x0000007d), + LL(0x8e763c10,0x1f614296),LL(0x5dcc4da5,0xa12ada20),LL(0x6dbe5329,0xd7a52ac6),LL(0x2fb42468,0x898121b3),LL(0xe9f5b08e,0x86a37006),LL(0xf5a42f83,0xbe3e6de0),LL(0x271bec98,0xc405b595),LL(0x486c9095,0x9adc363e),L_(0x000001b2), LL(0xc4ad2398,0x3c99889c),LL(0x5b663d6b,0x0c06893d),LL(0xa00328d8,0x8fc3f4f3),LL(0x2578283f,0x3d264389),LL(0x57571710,0x28e44b9a),LL(0xd62bb6bf,0x87dd3c9c),LL(0xd7a2f5d0,0xf55cade8),LL(0xcb792986,0xfa60b3a6),L_(0x000000dc), + LL(0x2139ecb6,0x04c2c927),LL(0x8890056b,0xc5944824),LL(0x319a82e4,0x5d37d95b),LL(0x5a8bd6a5,0xd80dfb73),LL(0xa7edec74,0xdb368732),LL(0x60fac47d,0x4f46dbb9),LL(0xb7d14924,0xe4ae15b9),LL(0x255c8153,0xd6f56370),L_(0x000001d7), LL(0x37f59faa,0x8323077c),LL(0xc814ef11,0x2b965e01),LL(0xd2dfe1b5,0xcad600e8),LL(0x2cdd66c5,0xcd44f8d0),LL(0xad1f4964,0xbb170f04),LL(0x6b03da74,0x09f8b95d),LL(0x721ac428,0xc3ee7059),LL(0xab3fd08d,0x69cd062a),L_(0x000001bd), + LL(0x23bf9a71,0x02685d92),LL(0xb24b23c8,0xbb2912fa),LL(0x700eb07a,0x547f3fb5),LL(0x51442fab,0xf8090af2),LL(0x91ae8f36,0xd9f38784),LL(0x7db330a6,0x213e5f98),LL(0xc4904ecd,0xd61a36f0),LL(0x18124e05,0xdf7f8676),L_(0x0000003c), LL(0xccdc9361,0x2a682aca),LL(0xa540909b,0x1f256aed),LL(0x28d1d810,0x643a464f),LL(0xc1d65b95,0xc56ce322),LL(0xe242b555,0xf79c9363),LL(0x165401c2,0x90b17574),LL(0xb89e030b,0xd9ba6bec),LL(0xad9d3eed,0x3cf323eb),L_(0x00000191), + LL(0xfce984aa,0x68365daf),LL(0x6bf21ffc,0x9e0da99b),LL(0x2a11bae7,0x4b632c36),LL(0xd82e9b91,0x8aba8d4a),LL(0xd3edcc69,0x7bcaa8bf),LL(0x0780abc1,0x4b5bb38e),LL(0xf449e1ff,0xb3a33e0f),LL(0x8bf9427c,0x5f153607),L_(0x00000101), LL(0x2be62f53,0xc25e9667),LL(0xa71cb23b,0xf1192121),LL(0xb5c951ff,0xe5267dca),LL(0xde9bed29,0x45f5f5dc),LL(0x62c0dc77,0x5c58640e),LL(0xb410973e,0xab71fb6e),LL(0x2ca60e2a,0xbd3de2bc),LL(0x91e919a4,0xb16029e8),L_(0x0000002b), + LL(0xf6897f93,0x920ffb1b),LL(0x2f766525,0x5063e19e),LL(0x0c6dbf49,0x2d7c8225),LL(0xc1e5d3a2,0x5919b3b0),LL(0xc8eabb36,0x9bd4d72c),LL(0x7daca33a,0xe43be366),LL(0x6a2d3407,0xd8bf85b2),LL(0xcb065c13,0x74ca1514),L_(0x0000012a), LL(0x69fde12b,0x240e3231),LL(0xdfa8142f,0xbfc4ea2d),LL(0xe35ddb6b,0xac61b3dd),LL(0xf38f22ff,0x0b6750d6),LL(0x6e04a783,0x0ae7817b),LL(0x43182e3c,0x5fc3f142),LL(0x70dd88d4,0x8958a84f),LL(0xe8d996f8,0x988beb73),L_(0x00000076), + LL(0x45a0ae0a,0x2fb883d8),LL(0xae353f2a,0xb61aaafb),LL(0x473d0ade,0x890f51bd),LL(0xd1b37ae3,0x0f0c4103),LL(0xeca49348,0x0087e22d),LL(0xc669a58f,0x3462ae96),LL(0xd7ec27b9,0x71fe3af0),LL(0x345f63a7,0x5d6f6927),L_(0x00000003), LL(0xb6063a3a,0x2047ce82),LL(0x2d78ca1a,0xbf2a2a03),LL(0xffe80d92,0x8144148d),LL(0x41e35712,0xf4375651),LL(0x70453a65,0x4044794e),LL(0x74d6e72f,0xc3b6ed9d),LL(0xc9dec888,0x03c9efa2),LL(0x01d35b17,0x4a8b5ee1),L_(0x00000156), + LL(0x1a111cdf,0xfedb9ea3),LL(0x89f7c11a,0xcc1f90fd),LL(0x930eb52d,0x56a442b3),LL(0xb33c2951,0x6f35d3db),LL(0x189b9ef0,0x5065c93b),LL(0x03375bf3,0xb5e57110),LL(0x9efd6440,0xacf2c750),LL(0xada5967b,0x09a6e279),L_(0x000001b7), LL(0xc686c489,0xdb8bd33e),LL(0x5a1a6302,0x0c057175),LL(0xd07e6a63,0x12ebc219),LL(0xd7415a35,0x5c53acb6),LL(0xffce8b04,0xc61aee58),LL(0xb8a197ba,0x3531c053),LL(0x76809753,0xd0b9df9b),LL(0x5e6fa51d,0xdfc91e09),L_(0x0000004e), + LL(0x3c210d2a,0x8909747e),LL(0x7284d674,0x9a35c4f1),LL(0xaebd8339,0x80afa728),LL(0xcd763811,0xe7b55292),LL(0xbfb44242,0x2f4e7b9f),LL(0xa0832cc1,0x4b2452f9),LL(0xeb50e9df,0xfb6f4f77),LL(0x557d53b4,0x081a5219),L_(0x000001ef), LL(0x5652cac0,0xda08f2ab),LL(0x71ddd646,0xdc6cd83b),LL(0x827b9770,0x2342c2c2),LL(0x40af5e14,0x1b228d0c),LL(0xc507fb1d,0x01646580),LL(0x8f89f75f,0x38a92b52),LL(0xe00b0563,0x154282c5),LL(0x27686a53,0x4f688875),L_(0x0000019d), + LL(0xce950363,0x5b121bb1),LL(0xfd31a6ee,0x6472e541),LL(0x1922fc41,0xcfaa3052),LL(0xffa68d9b,0x6480d380),LL(0xb9a18b55,0xe83a1c00),LL(0xb0e4740a,0x0caf0d03),LL(0x6f130693,0x4ea7894d),LL(0x36b54495,0x3a9ed5ca),L_(0x0000017e), LL(0x3b1453bb,0x6328956b),LL(0x8cad3c5b,0x903ec0c4),LL(0x38be6a97,0x4788849b),LL(0x6a8af4cc,0xb82169df),LL(0x753b96f7,0xf48e2aee),LL(0xbe19a762,0x3765ed66),LL(0xc53900a8,0x5283437e),LL(0x77012317,0x86b0a458),L_(0x00000027), + LL(0xf420ccb1,0xb5408c0e),LL(0x1466bddd,0x7d090375),LL(0x68631831,0x1d77faab),LL(0xfd6f5c35,0xe1c56990),LL(0xed7bc7e6,0x544f54fd),LL(0x65874640,0x9b1f7a03),LL(0xcb87ac9e,0xd060b45a),LL(0x33e1a951,0xd46b22b1),L_(0x000000d4), LL(0x9e1f9ddb,0x7cb30863),LL(0xb9f34068,0xa3dfc88f),LL(0x545e0d0d,0x7b5897e6),LL(0xbbf7c012,0x8cdc1322),LL(0x5bfb3570,0x13ce8bdc),LL(0xe13ad999,0xe1589aef),LL(0xb6cb7333,0x92265f86),LL(0x5f5d1b9d,0x9dfffba1),L_(0x0000005e), +}, +/* digit=39 base_pwr=2^195 */ +{ + LL(0x3521aefd,0x60d3d920),LL(0xe5091b5f,0xae3143dd),LL(0xec304735,0xe360b755),LL(0xf78afe69,0x119298c9),LL(0xe3ed2ff3,0x5c6a7738),LL(0x24d64036,0x06b1298a),LL(0x8b486bf0,0x3448a967),LL(0x81e9050b,0x6d50f02b),L_(0x000000c4), LL(0xa1d8699d,0xf1b1ce68),LL(0x59ff13a9,0xfc1bfb85),LL(0x23011f5e,0x1d2b17a5),LL(0xbec4e57b,0xfdcb9ac6),LL(0x53d5a58e,0x109c3a11),LL(0x4b16461a,0xe6c06b2a),LL(0xa5edc709,0xc93e99c5),LL(0x4ed62c80,0x18529aa9),L_(0x00000102), + LL(0x5ddb9f3a,0xbce7cc65),LL(0x49c78f7a,0xe90f1135),LL(0x6489c7f6,0x7145775f),LL(0xbe8e5262,0xc353f1ce),LL(0x36a4b927,0xda2f29fc),LL(0x3ef5bace,0x3d4c0acc),LL(0xb8074e6a,0x43a9c64f),LL(0x638d3fd6,0x70fffe4c),L_(0x000000c0), LL(0xf57826f1,0x5efbd2cd),LL(0x9bf19e6e,0xe86655bd),LL(0x7942ab0c,0xe82b0e8c),LL(0xb1c0c790,0x2f2b552c),LL(0x9dab8e1e,0x390a098c),LL(0xa67eba46,0x9b4d9810),LL(0x6a4756fc,0xc97785ec),LL(0x8fe8cb25,0xf5f5b6c1),L_(0x00000015), + LL(0x3550c471,0x3e59c5ce),LL(0x3ea8b15a,0xda44d978),LL(0xd1bea64a,0xe489d3d2),LL(0x8d887f59,0xcaf7d8fe),LL(0xf6f90986,0x76e4ba07),LL(0xeeb4dfe6,0x19aece18),LL(0xaf8390c7,0x4b163792),LL(0x8ecf88f9,0xfe44fa1c),L_(0x000001dd), LL(0x787acd3b,0x631704b8),LL(0xceaf9552,0xd06dc6ba),LL(0x319c43cf,0x86d813d4),LL(0xc141f1cb,0x1dcaf56d),LL(0x59594026,0xe9fcecb7),LL(0x7334a724,0xda2f8a7f),LL(0xd2a3a54d,0x40d320ca),LL(0x376b3d8c,0xee9740bc),L_(0x00000190), + LL(0x6b067f95,0xf72bf06c),LL(0x3dcbcaa8,0xcedc2a2b),LL(0x559f9fa4,0x707cbdc6),LL(0x65301ff4,0xb59f1a1d),LL(0xfc409d5e,0xbb9620b3),LL(0x6c53a5fe,0x48b591f7),LL(0x766a3eea,0xc3fc458e),LL(0x1913597e,0xb4cf309e),L_(0x0000005e), LL(0xae5ce891,0x8bb24162),LL(0xdda1da6f,0xcd895e57),LL(0x92393366,0x02de8414),LL(0x59ad0cbc,0x65ce8f07),LL(0x893b6573,0xbcfa2564),LL(0x73186b40,0x4fbea748),LL(0xd0156cb0,0x512a03d4),LL(0x0e490f66,0x328165e7),L_(0x0000016b), + LL(0xcf63e9fb,0xff9d55c9),LL(0xf62fa8e3,0x4867369d),LL(0xa6218d53,0x3d4df374),LL(0x462df770,0x0e4446f3),LL(0x5002dbe2,0xc6146393),LL(0xee0caf51,0x1bc9af4e),LL(0x615e075e,0x2e28e88d),LL(0x750b8016,0xc58c8ffa),L_(0x000001ff), LL(0x98241c37,0x91860ab2),LL(0x88c92592,0x4340d28a),LL(0xa23735bf,0x72c0db10),LL(0x9e762765,0xb8f03780),LL(0xf1edfe96,0x7d6eee09),LL(0x395f70ab,0x2e30082e),LL(0xa5b4a747,0xa42e66ca),LL(0x42b9fa7f,0x3482cf5e),L_(0x000001bb), + LL(0xe7982b9a,0xd1d63dbd),LL(0xe4cd39f5,0x09f98c29),LL(0xaa873723,0x561fec44),LL(0xdc9951ea,0xfd07b42d),LL(0x6c46651a,0x34575586),LL(0x7bf78c6a,0xa447b2e0),LL(0x9284f87c,0x9cdea2ee),LL(0x7235d419,0x677e1753),L_(0x0000009a), LL(0x5010f5fb,0x14229ff9),LL(0xc8f306c8,0xa79e93cb),LL(0x1a7861e7,0x05616521),LL(0x7842d63c,0x95f90f64),LL(0xcf737ed9,0xc0e16cd8),LL(0xff0413e3,0xedcf1408),LL(0xc3a4f30d,0x43a170a9),LL(0x11a0a6b4,0xcc49b5c7),L_(0x000000e0), + LL(0xf95a857d,0xd2ecdcea),LL(0xd4a0eaa9,0x7d01a093),LL(0xc04512bd,0x177d0211),LL(0xa88e2872,0xe8ab8a12),LL(0xf6040bce,0xec0d3b20),LL(0xbaded143,0xef133b8e),LL(0xc0271e57,0x57beaa78),LL(0xa57bec42,0x6cf36a58),L_(0x00000018), LL(0x6a0ef1d6,0x2b962ada),LL(0x54a163f7,0xdc75f9c2),LL(0x9214028b,0xf894f882),LL(0x29ad8172,0x454f24fe),LL(0x0197a015,0xb080990f),LL(0x1b117443,0x1d17b86f),LL(0x15991c9a,0x66059551),LL(0x66f5d53f,0x4e2d70c8),L_(0x000001c7), + LL(0x74d834c4,0x6bac308c),LL(0xd825f740,0x34b0da8d),LL(0x0fbb496f,0xde870fb5),LL(0x365075e1,0x7841bcf2),LL(0xd3c98322,0x3b8e05ff),LL(0xc39c86d8,0x74cbe33d),LL(0xf0fd6d0e,0x8904ae19),LL(0x6ed62a5a,0x2b1e2805),L_(0x000000c3), LL(0x1b67c792,0x97d2a267),LL(0x4c1cde55,0x05031449),LL(0xc0326e91,0x50606033),LL(0x423b1ee1,0xf18317b0),LL(0x398c9c61,0x5cc474ed),LL(0x96a97237,0x7eb4df47),LL(0x96b52ef0,0x1372ae46),LL(0xb1ed9607,0xabf9d1fe),L_(0x000001ff), + LL(0xfbbc04b2,0x31528630),LL(0xd54e33b3,0x4ada5d83),LL(0x74c3835a,0x9759009e),LL(0xdb44c86f,0x44543433),LL(0xb0ab6930,0x244966ca),LL(0x9d760ccb,0xc7b02622),LL(0x48a60f21,0xe78f542a),LL(0xb0eae43b,0x57db1786),L_(0x0000002e), LL(0x41c0d91e,0xabc5cfbf),LL(0x88276635,0x5fba9138),LL(0xcf1d1a57,0x568aba80),LL(0x955f0fe2,0x9cc142b7),LL(0x00c55c57,0x897ffd8e),LL(0x15579a99,0xb910a1ec),LL(0x58a539a3,0x68c6e345),LL(0xa76c02ea,0x37272cb2),L_(0x0000015b), + LL(0x8f19059c,0x9045b8e2),LL(0x054435bd,0xe377c286),LL(0x12ddcca1,0xd747b1a8),LL(0x3eb9f510,0x775c0ea6),LL(0x4fcce9d3,0x5865c783),LL(0xd37d19f7,0x2eb67bba),LL(0xbbc7cb40,0x53271117),LL(0xd5530a0f,0x600a1a8b),L_(0x00000108), LL(0x02132c61,0xddabbe5e),LL(0xb10fe3c6,0x3587db17),LL(0x11b65599,0x1c163208),LL(0xad78aa4f,0xe7539751),LL(0x51c18792,0xc229bfb7),LL(0x5719f77d,0xf84f03ce),LL(0xdd5c3eed,0xbb9c60b9),LL(0xc4b8c257,0xe60da1b9),L_(0x00000145), + LL(0xf591a021,0xe70fa9ae),LL(0x80aea17a,0x3cc6237a),LL(0xa1a05142,0xbfbb8572),LL(0x82ef4062,0x1a092a36),LL(0x584063eb,0x083d9b48),LL(0x0ca19b36,0xd64fde39),LL(0x92047044,0x84e4f4c7),LL(0x3a0049a4,0x025a777c),L_(0x000000e3), LL(0x1e4d1a64,0xa8f92448),LL(0x1e5063b2,0xfb85d333),LL(0x72d2c93b,0x0f374579),LL(0x6c2c1440,0x599d4bd1),LL(0xf99fc78f,0xf8d879ab),LL(0x7157a6f4,0x24350117),LL(0x6511ce35,0xf5039be6),LL(0x3e9cc395,0xa82c44a2),L_(0x00000156), + LL(0x35779ea3,0xe6e7d409),LL(0x83ea2a70,0x4c9ba2b5),LL(0x137328e5,0xd4654390),LL(0xb93501ec,0xd733683a),LL(0x118e98e5,0x89f374dd),LL(0x00d407bd,0x5295b907),LL(0x13b0afb6,0x57db6bfc),LL(0x6b480958,0x95fc47c6),L_(0x00000108), LL(0x42737627,0xaa37df30),LL(0x84543a49,0x5c127536),LL(0xaf148309,0xbf08a1c2),LL(0xcb7176db,0xbab267dc),LL(0xa7bbd2fb,0xabd6efdf),LL(0x8aeeb27e,0xe86eabfc),LL(0xc902ad03,0x4e44e718),LL(0xf09e682a,0x064991f1),L_(0x000001e0), + LL(0x22921213,0xc501c914),LL(0xa64386af,0x86838cd0),LL(0x4dd63878,0xe353d214),LL(0x2b6e52eb,0x298c7007),LL(0xb94c5abb,0x4bbcef96),LL(0x3cdd0d98,0xfb73d97d),LL(0xe31b50a6,0xd4d6c5d5),LL(0x63019a2f,0xaac04770),L_(0x0000008c), LL(0xd0908913,0x1496527b),LL(0x959a4aac,0xe7cd0ef4),LL(0x5fb6b5e8,0xcf4b2051),LL(0x77e30f99,0x1b0c7952),LL(0x70b054fe,0x38ba1d97),LL(0x5de49575,0x947a5a05),LL(0x8fe1e2d6,0x4246cd4c),LL(0x3254f07e,0x238ade18),L_(0x00000133), + LL(0x4d8e1514,0x99aed77f),LL(0xf6fa1112,0x9c04ed64),LL(0xd4feb2e7,0x7a120999),LL(0x5d57b4f9,0x70550af6),LL(0xd07357d3,0x41340660),LL(0xe4afb7c6,0x05ac084c),LL(0x0826e572,0xae197ca4),LL(0x3ea7fc0b,0x8f07d680),L_(0x00000023), LL(0xcb353a2f,0xaf454a02),LL(0xb5cdf6d6,0xb32bd0de),LL(0xf3bb89c8,0x1bd8c3f6),LL(0x5deb355a,0x3db355ab),LL(0x2f043ae6,0xd5c6b398),LL(0x0e90987d,0xabe8910f),LL(0x380521ad,0x4bf6a241),LL(0x3dfa044a,0xfb752ed2),L_(0x000001d8), + LL(0xd3c55232,0xaad132cf),LL(0x696e2831,0x49f240e0),LL(0x0d4e57f0,0x3025b776),LL(0xf18f53bc,0x0b5878b5),LL(0x56b2575b,0x576025b0),LL(0x452417b5,0x51986dad),LL(0xa57a7837,0x5444a7c0),LL(0x9f4452b9,0x9f945ebb),L_(0x00000132), LL(0x83e66b0c,0xca0455ee),LL(0xd553d885,0x83b12fcc),LL(0xd68fe49a,0x3da8d9a1),LL(0xb71fad5d,0xa984d589),LL(0x1f435980,0x5db787bb),LL(0x659a3f24,0xa908e510),LL(0xdd95c91e,0xbe7d501b),LL(0x4a9245db,0xdaa920fc),L_(0x000000d3), + LL(0x70b49262,0x58fdd1be),LL(0x26f6dba6,0x1bc799a8),LL(0xcb4e9512,0xf00f6eae),LL(0x56df676a,0xe75a521d),LL(0x29d333ce,0x4eca7d77),LL(0x27fb68ac,0x206d2e50),LL(0xa49aec5f,0xaa272aa4),LL(0x1b6a988f,0x341efc69),L_(0x0000007f), LL(0x8415461c,0xe6df0f07),LL(0x3afd9193,0x782686ca),LL(0xe7785c7d,0x3c2a9148),LL(0x4c330f1e,0xa49f1fa5),LL(0x82ded4aa,0xde962297),LL(0xb845da08,0x79a993b6),LL(0x0729c991,0xf8fef022),LL(0xad904b0d,0xe6016c6a),L_(0x000001ce), +}, +/* digit=40 base_pwr=2^200 */ +{ + LL(0x0cbfbe4b,0x938c22f8),LL(0x943a3471,0x837e8130),LL(0xe2773aac,0x4a3c4f46),LL(0xf24010c6,0x2b750229),LL(0x138446be,0x007131ff),LL(0x731813b9,0xc2c90ce7),LL(0xe94672d6,0xdd149a00),LL(0x69dcb075,0x7531381b),L_(0x000000d0), LL(0xe8e6de08,0xb6b38c7b),LL(0x39ced7c6,0xb63d5a97),LL(0xa61fbc4f,0x8f6b6bae),LL(0x075fe4d1,0x6ae1dbab),LL(0xc1ebedbd,0x12c3dbf8),LL(0x6dce109a,0xc087b051),LL(0x4a2962c4,0xa1e1733e),LL(0xf40db685,0x9f800e79),L_(0x000001ad), + LL(0x8bb9ff0e,0x663feea7),LL(0x4fde5cbe,0xdd02746e),LL(0x3f440437,0x33232942),LL(0x8cb2a089,0x21f2f603),LL(0x50b4f0e4,0xa8d7b95a),LL(0x18c0b0f4,0x35a473ae),LL(0xc9451cc0,0x8955b22b),LL(0x9c5154ba,0x9d1fd085),L_(0x00000134), LL(0xc1a8bcfe,0xaff04652),LL(0xe19db868,0x961dcb73),LL(0xeea574f2,0xf8c3e1f9),LL(0xf4327664,0x9b512b73),LL(0xb683e483,0xb02a0ec5),LL(0x0fb615a0,0x7991b38a),LL(0xb1e55bb8,0x3f719551),LL(0x19309417,0x0ba8f164),L_(0x0000013c), + LL(0x63247bdc,0x20ed0fcb),LL(0xe26950f9,0xa5916c61),LL(0x8ac76960,0x2ae5b02a),LL(0x17149cfc,0xda5eb1a5),LL(0x5c8f4a8c,0x9118595b),LL(0x0004518e,0x9e0cc88e),LL(0x9dcbce69,0xb0b05838),LL(0x5edca7cd,0x8f7a0d45),L_(0x00000167), LL(0xd452c748,0x773e3080),LL(0xd9ebc5ab,0x32f8567c),LL(0x92748ad1,0x2f890896),LL(0xd6e0eb81,0x83d0c649),LL(0xdc173290,0xed13cd26),LL(0x6815ffda,0x775e539d),LL(0x727168b4,0x09166ff7),LL(0xbfad2565,0x7a36c1d3),L_(0x00000174), + LL(0xa559258c,0x46e6e936),LL(0xf2627126,0x96d6c787),LL(0x7ee8f552,0x6540e78b),LL(0x53eb4432,0x2fb88504),LL(0x073a9cef,0x0e4739b6),LL(0x9bbfb39a,0x5b6532c1),LL(0xbec805ba,0x4331c495),LL(0xedb74df4,0x002e8ec8),L_(0x000001d3), LL(0x48685b39,0xcbd7ba6c),LL(0x4bae18ce,0x3a66d73d),LL(0xa9e818b4,0x5a439da7),LL(0x422e109d,0xe2bd60c3),LL(0x71574884,0x482785ad),LL(0xf6bd330b,0x8c0c9a5b),LL(0x6c8383da,0x0007cc56),LL(0x2a9a00bf,0xa489783e),L_(0x00000056), + LL(0x7a2ccd93,0x9d4a8e40),LL(0xd221fba2,0xd46ad86a),LL(0xfddda1e9,0x14fcb5bf),LL(0xf9686431,0x60db0e24),LL(0xb0468c5a,0xa659be98),LL(0x5c91bca8,0xcabd0c78),LL(0x1e072204,0xd9453dfb),LL(0x50ebbe04,0x8aef77cf),L_(0x00000168), LL(0x9b426c53,0xb8b62e34),LL(0x7872d194,0x43334446),LL(0xddbd4e1c,0xaad0f260),LL(0x42324117,0x7d8cfb9c),LL(0xbd6c92ea,0x883e18f4),LL(0x68768225,0x72898dd5),LL(0x59ac483a,0x25923bd3),LL(0xffec7082,0x48de2e57),L_(0x00000021), + LL(0x8796d389,0xf64d07f7),LL(0x07a33d42,0x4d434a03),LL(0x8948a2a4,0x03ccc6f0),LL(0xbb8f90db,0x6ff7592e),LL(0x69af4969,0x87ff2ae9),LL(0xec7fca3c,0x687414fc),LL(0xd6cec6f5,0xb3255410),LL(0x9a9ae9c6,0x961c9823),L_(0x000001ea), LL(0x1f7e4e99,0x4284bbf9),LL(0x472d0237,0x86ea89ac),LL(0xd63ca5a6,0x6cd552ac),LL(0xe6161434,0x2fb24ab8),LL(0xdc07d107,0x880d3677),LL(0xd1833f7c,0xd225c8c0),LL(0x17c50635,0x2bf84ae7),LL(0xc1f8a219,0x2e83c678),L_(0x0000007f), + LL(0xc0d1be3d,0xbf7ea965),LL(0xe0762dd1,0x7e003dff),LL(0xd60aa791,0x62c54da8),LL(0xfa92fc72,0x21eaa7ed),LL(0xff6dc244,0x62c86ea7),LL(0x29f82d5e,0x68214737),LL(0x535c6df4,0xb69bc00d),LL(0x494bda6b,0xf34e2601),L_(0x00000133), LL(0x3563dbad,0x1096ecec),LL(0x12da1692,0xcc5db4fd),LL(0x2f945903,0xc4f95586),LL(0x15014cb4,0xf70f6fbb),LL(0x3d80e47a,0x0a6967e2),LL(0xadb489f2,0x65a13ebe),LL(0xa0094906,0xa28958e6),LL(0x9fafaa96,0xda82221f),L_(0x00000031), + LL(0xf4cc713b,0xbab5dfd8),LL(0x59f2c453,0xe3fa69de),LL(0x0c9b2cc1,0xb6318b0b),LL(0x56b33c17,0x2d5d399a),LL(0x6dc3c1e9,0xf08f8a6f),LL(0x9e28633f,0x51ffb7f3),LL(0xf1fbcd43,0x77388eef),LL(0x9d013e8c,0x953e5ebf),L_(0x0000006a), LL(0x19a3879a,0xbdbfd2f4),LL(0x95e5a481,0x017a31d1),LL(0x1ef3e1ae,0xb5b37267),LL(0x8988b706,0x748e8ba9),LL(0x3916983f,0x0e9de7d3),LL(0x6e3e3c93,0xe7e37cde),LL(0xee4ca324,0xae3cdd99),LL(0x2fb6a772,0x5fda48d8),L_(0x00000023), + LL(0xb1b36ee9,0xa88f1006),LL(0x32101e9d,0xec995155),LL(0xbc724136,0x50786c7c),LL(0x718458f0,0x942d96ed),LL(0xd4b44c20,0xa25702b9),LL(0xf245f9d1,0x060c2adf),LL(0xb57e7b0b,0xb9d35bf5),LL(0x7ec560d8,0x06f41b22),L_(0x00000056), LL(0x330450ba,0xe70f3385),LL(0xbb3cf7d0,0xaf72af3d),LL(0xf5c80879,0x24797994),LL(0xcff4c536,0x60ff916d),LL(0x9be0e09a,0xab9b1069),LL(0x069c4c8f,0x4df20300),LL(0x1f6d9a1c,0xe23cffcc),LL(0xe8dd8a18,0xf91c6b69),L_(0x000001c4), + LL(0xd0d2f55b,0x95fbe896),LL(0x77feee72,0x5cc61767),LL(0x8880fcfd,0x37faec22),LL(0x520b4347,0xb528d647),LL(0x08c7efa3,0xd89b3eae),LL(0x7f34be1f,0x0837f588),LL(0x08e5ae1a,0x1bd21d07),LL(0xdd6b478f,0x2fe84dcc),L_(0x0000011c), LL(0x39fd2b7b,0x834a2481),LL(0xe505f7b4,0x2410091c),LL(0x6e308dff,0xc904e585),LL(0x881cb270,0x8e50edd4),LL(0xb510da38,0x1a9f6193),LL(0xdd2ee182,0x09d449a4),LL(0x27fbd7e1,0x8ae922fd),LL(0x099fa1c5,0xd2acc7bd),L_(0x00000151), + LL(0x54d97245,0x0a20a859),LL(0x0116816e,0x589d2f96),LL(0x148078e7,0xaaa24c2b),LL(0x28f3d3c2,0x171935f6),LL(0x48826cdd,0x84d3a584),LL(0x4e4018a0,0x3aa25c41),LL(0x20c105fb,0xfbf31507),LL(0x27ff55a5,0x109df084),L_(0x00000126), LL(0xebf39f9e,0x7739d21b),LL(0xd2b7193f,0xacf34cf4),LL(0x3d27ea07,0xab2591de),LL(0x55176728,0x3ceb2fdd),LL(0x2cd960ff,0x716fc560),LL(0xb6983fee,0x90fd8f68),LL(0xb59a98f6,0xe1bb13d6),LL(0x476cf07b,0x119c8087),L_(0x00000019), + LL(0xbdb26400,0x09bcac55),LL(0xcc9f7ef1,0xf3382f38),LL(0x8ea6fbed,0x08f8a371),LL(0x93651490,0x97354cca),LL(0xa5d779cd,0xd6ff00ea),LL(0x17e28bc6,0xcb936676),LL(0xf2c7be3b,0x4d0cca52),LL(0xe6fcf731,0xfe1b3242),L_(0x000001b7), LL(0x195399b2,0x998790dc),LL(0x13a64152,0x616ab4fc),LL(0x4787beee,0x0f38f16c),LL(0x8c14e216,0x13dc0561),LL(0x5144326b,0xab46b249),LL(0x49417c95,0x0e55d9c5),LL(0x87bf06de,0x4c1e541e),LL(0xc0681d93,0x2c9b452b),L_(0x000000e9), + LL(0x5003f6a6,0x8a76574f),LL(0x406e1518,0xe6346b0d),LL(0xb53c0598,0xbdfc6afa),LL(0x9ca435a5,0x50f31dc3),LL(0x9cc07001,0x1695c15e),LL(0x1fd27db3,0x80905ca0),LL(0x1aadf518,0xad7428a8),LL(0x926949ce,0xff033643),L_(0x0000007c), LL(0x248272b0,0x44dec074),LL(0x2345ae4a,0xe0173b35),LL(0x3909da4f,0x56f4144f),LL(0xe4ed2bfd,0x95f4401f),LL(0x198f03a8,0x1227b3e8),LL(0x49d6d509,0x249ec281),LL(0xe4d920ef,0xc12324e5),LL(0x0d321781,0x00c158a5),L_(0x00000106), + LL(0x62d3fa5e,0xe0633553),LL(0x3677eb41,0xa7b03785),LL(0x9c729924,0x166ddf87),LL(0xac9990ff,0x9eba58ed),LL(0x2f6b0f44,0x29db9988),LL(0x2b93f534,0x7f4a4f14),LL(0x92b08207,0x695177a9),LL(0xc1d4f27c,0x1d65e607),L_(0x000001bf), LL(0x7f241b64,0x1902ce34),LL(0xc2625795,0x99c8b2c8),LL(0xb763d2c5,0x4d39eb77),LL(0xa75ff101,0xd8865e52),LL(0x2e31245d,0x51ed16bc),LL(0xfc608d17,0xd782bd3f),LL(0x441d7032,0x8f51fc25),LL(0x47fab287,0xe871d582),L_(0x0000006e), + LL(0xd66fc4f8,0xec4b364a),LL(0xfbb65219,0xd42017be),LL(0x359e7f30,0x3fc15863),LL(0x5c218315,0xb1a3700b),LL(0xf2cbaf1a,0x040dad16),LL(0xb6cd3ff6,0xbf23d44a),LL(0xd045f02a,0x83befb28),LL(0x4160599e,0x467f747b),L_(0x0000001d), LL(0xe7de34cd,0xc40b618b),LL(0xf743241b,0x64d1d40f),LL(0x576ba83f,0x5ece3029),LL(0x4dc64148,0x47769772),LL(0x6d3057fb,0xd175fe83),LL(0x0884e64d,0x33875e4e),LL(0x859df923,0x481b7714),LL(0x655fbae2,0xdef5f5e2),L_(0x00000044), + LL(0x1c7765f1,0x7dce56e1),LL(0xcfdef637,0x3df3dfe4),LL(0x35b39936,0xa715e9e9),LL(0xffaca630,0x1011f820),LL(0x33f64da2,0x222d3bc6),LL(0xc5987552,0x523adab0),LL(0xc95736a8,0x787c715d),LL(0x058fef5b,0x66393c63),L_(0x0000012a), LL(0x97f6f489,0x5434ecf8),LL(0x891f4ace,0x7708ad40),LL(0x51c5f6bf,0xfe89ee25),LL(0xc377ca62,0xe6011a07),LL(0xd24cd2ea,0xd028c949),LL(0xc094a1a4,0xcf84ab99),LL(0x1fed19d9,0x036f7f03),LL(0x0551c154,0x37b50c32),L_(0x000001d4), +}, +/* digit=41 base_pwr=2^205 */ +{ + LL(0xf5fef4c6,0x8936aa0b),LL(0xb069d26c,0xd3718b4b),LL(0x2e3dd1d0,0xeaaab400),LL(0x26ebf3da,0x315a34c4),LL(0x04c67676,0x1eb5f386),LL(0x97e2eb1b,0xbc318051),LL(0x7226db1a,0xf5e17eb3),LL(0x109ad73d,0x97d098f5),L_(0x00000137), LL(0x82acea04,0x5982cf08),LL(0x48806f5a,0x5f09406b),LL(0xabd27505,0x4db94328),LL(0xb3c49a50,0x38e43c40),LL(0x08d386ec,0x582b99e6),LL(0x3b07fe47,0x9089cf44),LL(0x7186cac2,0xac474a1b),LL(0x22d982cf,0x7b0368d4),L_(0x000001aa), + LL(0x51b31a96,0xba6cb60e),LL(0xf6d82cb3,0x989499c2),LL(0xf86e04fd,0xcb66fb0c),LL(0x35487bb6,0x7e6257cf),LL(0xdbe642cb,0x7caa5a38),LL(0x0132dd97,0xcf0c7ff7),LL(0x9fe7cec8,0x8b24a15a),LL(0x54f2a9f9,0x52eb7ce9),L_(0x00000075), LL(0x42f8ae5a,0x47aec9e8),LL(0x766fc554,0xced0e96d),LL(0x99065768,0x493166bd),LL(0x2b9adad9,0x28be045e),LL(0x222a08c3,0xae70d305),LL(0x4f554727,0x61d8ec1d),LL(0xfed1873d,0x41e23d82),LL(0x9f1c46d5,0xf348b3f1),L_(0x0000002e), + LL(0x482e6f9e,0x82d58220),LL(0x488e8bdb,0xaabd7c77),LL(0xba1084c7,0x67c7272c),LL(0xca6ae765,0xab82a151),LL(0x1ca84a79,0xa826c75c),LL(0x06316ad0,0xf3c64348),LL(0x0dd7f329,0xde3d6a04),LL(0x3f33bd2d,0x689c3e45),L_(0x00000043), LL(0xe98af372,0x8c61be6e),LL(0xb8361cc4,0x624c3291),LL(0xb8a7b622,0x4c3e4e24),LL(0x3c10547d,0x37a21d5f),LL(0xfa09bfc9,0x407a153f),LL(0x54fa325a,0x5c7fa63d),LL(0x8d13bea7,0xfb7c45a4),LL(0x2fe1e55b,0x1a8b8531),L_(0x0000015a), + LL(0xa0b12ed6,0x0246d25c),LL(0xaf11f361,0x0ca563e7),LL(0xd246f5c0,0x3dbda22c),LL(0xc1f5f271,0x1517fe92),LL(0x5b82f357,0xae558aff),LL(0xc7e4811a,0xfe93852e),LL(0x0a7d7a0c,0x80c69efa),LL(0x5a9a571e,0xcf0c8dc8),L_(0x0000015e), LL(0x62ea61b3,0xfa629e03),LL(0x70463933,0x97e91195),LL(0x4d8bdb29,0x1670ff63),LL(0x3758d16c,0xac0e352c),LL(0xc3148942,0xebf5c218),LL(0x789d4077,0x68df9269),LL(0xedd91114,0xc949bb1e),LL(0x1c9e59bd,0xa97ced00),L_(0x00000094), + LL(0xab334809,0xa992abd6),LL(0xe820b690,0x598bc6c2),LL(0x5618c97b,0xdba62f4c),LL(0x4cfa34df,0x13d15fa5),LL(0xe73cd8e4,0xf2867cb6),LL(0x0a135ff7,0xc48f860e),LL(0x8e8f76ce,0xfdd988f5),LL(0x3ad07476,0xcb3a07b0),L_(0x0000009d), LL(0x9756e016,0x59630aad),LL(0xf07162de,0x6a1c1e29),LL(0x47eefc5f,0xd695eb4b),LL(0x69323852,0xf81fbfef),LL(0xeb840ba2,0xe9a13161),LL(0x99e6fb6f,0x82ed26e9),LL(0x0282e82e,0xe498cc70),LL(0x4b2c80ab,0x6264860e),L_(0x00000002), + LL(0xc9751c23,0x9f6dc20b),LL(0x5c25edfa,0x51ff9b10),LL(0x2267d84b,0x77cd497c),LL(0xecebc8bb,0xd41da61c),LL(0x2e90633d,0x0c2e11a1),LL(0x61552b8c,0xe7151d1b),LL(0xfb4a699d,0xa5898fdf),LL(0x74297e23,0x1a45323e),L_(0x000000f7), LL(0xcf0213ad,0xfe2e5183),LL(0xf83ccca0,0x0905c1e0),LL(0xc44aa9ba,0x0b1cf7ee),LL(0xfedaabc5,0xc2ab4a81),LL(0x7f856296,0xb2c2c3b9),LL(0x7c377576,0x110f594f),LL(0x248077d8,0x0920b595),LL(0x7dcc7073,0xa5e1a393),L_(0x000001a3), + LL(0x5b8dd11b,0x003d8cbe),LL(0xf2309e12,0x1dd14f55),LL(0x6aafea42,0xd6b6d08d),LL(0x9f501238,0xd63623cd),LL(0xe37ddae1,0x079b78ad),LL(0xc658ecac,0x62a7d933),LL(0xffca3243,0xf37ff209),LL(0xefd095aa,0x8e2c83df),L_(0x000000dd), LL(0x08483b62,0x5e0a6e24),LL(0x2d2f9a76,0x1a69b899),LL(0xe6914b5b,0xf621c0e1),LL(0x8472fe93,0xdd02cec9),LL(0x92c73abd,0x8f7b6745),LL(0x3d6f438d,0xeceedfc7),LL(0x290f69f2,0x98f33394),LL(0x0ed2ebb0,0x2536905b),L_(0x00000123), + LL(0x63653aa4,0x5e0e658f),LL(0xa4e263b1,0xb787e362),LL(0xf1a72f5c,0xade21c8a),LL(0x3468dd85,0x51d6c477),LL(0xd69f8f93,0x4ea4254f),LL(0xae15e0af,0xdb86c982),LL(0xdd836935,0x98d3a2d5),LL(0xdc232783,0x5ffb0769),L_(0x0000002c), LL(0xd27779d1,0x4c2ae6ec),LL(0x043db3d9,0x09230456),LL(0x73642e7c,0x6f9dd795),LL(0x2a8692df,0x2cd98576),LL(0xa83e7242,0x16ac0a49),LL(0xa2e9e20f,0xd3fe59cf),LL(0xd0093708,0x10a46920),LL(0x10c84d0b,0xa5bda12a),L_(0x0000015f), + LL(0xedf1bf7e,0x8efb0b81),LL(0x586ad55f,0x8d830110),LL(0xef747d77,0xb3bf603e),LL(0x0f99e447,0xb48e1874),LL(0x9da3060c,0x389d594d),LL(0x10ea78c4,0xc7644272),LL(0xd0f0eafb,0xaf1ebb75),LL(0x7afab007,0xcc569782),L_(0x00000154), LL(0x0ef592de,0xebfccb68),LL(0xf0400a4a,0x474a550e),LL(0x9ca24b23,0xbf9aef56),LL(0x5613d5ac,0xab9d9c2b),LL(0xb8267455,0xbf868bc0),LL(0xdb52868c,0x909956ec),LL(0x50005f46,0x49928d00),LL(0xac611000,0x904632ee),L_(0x00000162), + LL(0x8607bdea,0xe148f242),LL(0x2dd2babc,0xa0bb05f4),LL(0xd775106b,0xbff23d31),LL(0xf2919560,0xe97c018c),LL(0x44a63043,0x4871d249),LL(0x87f10683,0x189ec6a3),LL(0x0d74d0f1,0x257dbb86),LL(0xd0bbd041,0xcc6bf0e5),L_(0x000001b9), LL(0x94b22c9b,0xad1a6c62),LL(0x9dacf60b,0xde935e97),LL(0x77ba8de8,0x73dfb2df),LL(0xeb7f0da2,0x64121541),LL(0x18d0ee67,0x024e0b69),LL(0x7b37359f,0x84be521c),LL(0xea621f3f,0xcd285848),LL(0xf996c437,0x6391d449),L_(0x00000030), + LL(0xf3eb9640,0x6d04608b),LL(0x807ec468,0x80a83900),LL(0xb77f8649,0x5eb64b76),LL(0x07caea9c,0xc62e7f72),LL(0x0ec672b0,0x465c546e),LL(0x378afe4c,0x4b627b99),LL(0xcc8adc18,0x929649b3),LL(0x8be7d42e,0x967ccf92),L_(0x00000057), LL(0x7aaa87b5,0xa6efca22),LL(0x4f172127,0xf3a643dc),LL(0x9bf5975f,0x4fe72fa7),LL(0x90cb1c95,0x4c4df518),LL(0xba142ada,0x799862f3),LL(0xca2d035c,0x68d4ff7c),LL(0x98b9e83b,0x7d49b932),LL(0x13c2887b,0x21991bff),L_(0x00000051), + LL(0xecf8f1af,0x881d7401),LL(0x5a044cc4,0xe24e7a25),LL(0x768d2e23,0xfaed9fe1),LL(0x8f7705f4,0x383ba961),LL(0xd4a1b2c2,0x435ea5ef),LL(0xa2b9797e,0x3b37f12c),LL(0xe7f7c215,0xb091bf0d),LL(0xf2391054,0xb7ba542b),L_(0x0000004c), LL(0x7896f156,0x701310b7),LL(0x9eb25738,0x04099f3f),LL(0x6dcb2223,0x7798cb36),LL(0x4d56786a,0x95c47f22),LL(0x919da3c8,0xdaeee06f),LL(0xb6abb8e6,0xa660ceaa),LL(0xa641a64e,0xa1891535),LL(0xc989455e,0x627a7ec8),L_(0x0000019f), + LL(0x8abf9f25,0x834e7f6b),LL(0xa4f8a8ed,0x8d0ab54c),LL(0x7e835385,0x86915b58),LL(0x726730be,0xba996ac1),LL(0xe84c9776,0x0ac27d99),LL(0x59603bec,0xbcd0e3fb),LL(0xc7989ede,0x1f1942c9),LL(0xf303b7a8,0x9f4547f6),L_(0x000000e4), LL(0x681044e0,0x53ff8c21),LL(0x01ac096d,0xdb4b7aa1),LL(0x69d169b0,0x9723cdd3),LL(0x802b82f6,0x2051bc9d),LL(0x256afff2,0x3d4a1ea2),LL(0x321bcf00,0x7da3a724),LL(0x26d669c5,0x4ccffc5e),LL(0x72d30cad,0x212847aa),L_(0x000000bc), + LL(0x8217dbfd,0x7dca0317),LL(0xad5ed722,0xe8f1e786),LL(0x8f7b7ae7,0x30b8f677),LL(0x9bd08de3,0x03bfd2ff),LL(0x1955b540,0x599706c8),LL(0xfa5ccf69,0x66c7232f),LL(0xa98d3152,0xa531f734),LL(0x35d69728,0xa518ffd1),L_(0x000001dd), LL(0x28dfd590,0xc9f5e869),LL(0x5ce90640,0x7f70dba5),LL(0x4d6b1828,0xa187b391),LL(0x636739ff,0xc3f757a7),LL(0x6788a6b6,0xca8804a7),LL(0xc2a0400e,0x6dfa8acb),LL(0x499f91eb,0x8bd0499a),LL(0x28af9210,0x45056091),L_(0x000001ea), + LL(0xdd2aeb14,0x35af5ce4),LL(0x33f86de1,0x24f47c0f),LL(0x237c0920,0x0133d426),LL(0x76b14d92,0xdebe095d),LL(0x989c257d,0x7569cd5b),LL(0x8d5f30b4,0xeebd5dcb),LL(0x7daee4b5,0x381f623b),LL(0x5a27d2f9,0xc7fab47d),L_(0x000000c0), LL(0xb30042d8,0x87c8f748),LL(0x04d7a15d,0x0ac1e9b0),LL(0x96216dea,0xb1634ac6),LL(0x3c5fec65,0xf61cf904),LL(0xab711a92,0x3d592940),LL(0x9bf5392f,0x2eefb59a),LL(0x96b616e2,0x6a36ed7e),LL(0x5c5c3417,0xb15b4b78),L_(0x0000008c), + LL(0xfb9aeab3,0x109924ed),LL(0x46d2968a,0x9147a28a),LL(0xfe84ed7a,0x49744c91),LL(0x88e478aa,0xfd889651),LL(0x65a34f30,0x8dc8d99e),LL(0x21fd955c,0x740206f2),LL(0x7ea7cd99,0xdedce892),LL(0xd4f83ab9,0xa7c26d23),L_(0x000000e8), LL(0x2c8cb8bc,0x91728e18),LL(0x0fa5f320,0x3ad9d78b),LL(0x760a4e2a,0x65aca369),LL(0x6812b50f,0x46ee027e),LL(0xdb993f3d,0xe5a7e2b8),LL(0x2acac076,0x60290375),LL(0xa179054a,0xddbfa0d3),LL(0xf87bff0f,0xee0dfeef),L_(0x000000fe), +}, +/* digit=42 base_pwr=2^210 */ +{ + LL(0xbd161967,0xbda60a63),LL(0x090aae19,0xcb3f577f),LL(0xe7638c32,0xf59abf93),LL(0x34b2a6dd,0x35486136),LL(0x3c50db1d,0x91b5e651),LL(0x49476ec8,0xf4bbb5bd),LL(0x83b636d2,0x3dd95f7a),LL(0xd5071e3a,0x77c02f69),L_(0x000000f9), LL(0x9531d83c,0xc6860379),LL(0x9c9ad3cf,0x35f1eec4),LL(0x4e50cb96,0x26b39588),LL(0xd703ca9d,0x3bd6a0e5),LL(0x3fe9036f,0x08ef03a9),LL(0x605b0ecc,0x070faad2),LL(0x6abd3a9b,0xf3494eab),LL(0x7fa81977,0x164f95f6),L_(0x00000031), + LL(0x676b493c,0x57205d81),LL(0xe8f546e2,0x442871cf),LL(0x87afe8b6,0xd5e346c5),LL(0x748676ba,0xa964afa3),LL(0xca39baf4,0xe1422f71),LL(0x0e9e0a58,0xd62c328b),LL(0xd31cca18,0x07714d71),LL(0x75787f65,0x810168e3),L_(0x000001ad), LL(0xa1440c8d,0xb730f78a),LL(0x509d6354,0xec14ff7e),LL(0xbeae80e0,0x9793053f),LL(0x019f7cc0,0xb6b1fd1b),LL(0xe4fca025,0x44558d48),LL(0x7ed4a037,0x86992aae),LL(0x0e2db1c4,0xf0333757),LL(0x557f4b02,0x30117649),L_(0x000000f4), + LL(0x194c0cc8,0x23e0df8d),LL(0x58c8cbc9,0x1732c3e0),LL(0x3466783b,0xf47836e0),LL(0x4713b9a8,0x79e1d15c),LL(0xa517b03d,0xefa174a4),LL(0x63c15938,0x49e8d766),LL(0xea4a3245,0xd01d6313),LL(0xbc5db16f,0x83758c05),L_(0x00000196), LL(0x7797400c,0xbf271b78),LL(0x3af2e11a,0x60042746),LL(0xa3ab648d,0x79d1c019),LL(0x5000aba1,0x253b9712),LL(0xd9239c9e,0x0e930854),LL(0x85a1b532,0xab5ac676),LL(0xe00c287d,0x57eaaede),LL(0xe2d767a0,0x43b264bf),L_(0x00000180), + LL(0x2d438c77,0xd715e37a),LL(0x436c808c,0x8615d6bb),LL(0x78232591,0x58c6e6b2),LL(0xca6d68ce,0xa40e8f75),LL(0xc4c37875,0xc01da381),LL(0xbe962879,0x58a155d9),LL(0x5dd3d4cf,0x847d5de7),LL(0xee99fd85,0x8f7f76b4),L_(0x00000015), LL(0x4cec18db,0xd4c9f66a),LL(0x5302a76b,0x647086e4),LL(0x1b679cdf,0x93b84a7e),LL(0xd412c242,0x92243bc4),LL(0x519ccba0,0xd5c3c375),LL(0x585371f2,0x8ba3d06b),LL(0x90f4c0f2,0x1daa7685),LL(0xf573b409,0x6342e78b),L_(0x0000013c), + LL(0x0b8749aa,0xf1f9c0d3),LL(0xf2f4b2d5,0xbf3b998b),LL(0x6f543cfb,0x0d744317),LL(0x25e2b138,0xda23008b),LL(0xc81ea703,0xa6df5808),LL(0x322e0c8c,0xdabad20e),LL(0x654aa6ef,0x3a6c3719),LL(0x64c8d439,0xf75f2e54),L_(0x00000167), LL(0x90408e7d,0x50778fd6),LL(0xbd5f5197,0xcbe15e1b),LL(0x16df4a37,0x36cef226),LL(0xb2ae2273,0xfaaea71f),LL(0xb8561402,0x40dd546c),LL(0xed28c500,0xa3b837f1),LL(0xe3cde0fb,0x7315fb7b),LL(0x893aced1,0x828da346),L_(0x0000010b), + LL(0x9ff41dd8,0x136ca413),LL(0x7447323e,0xc3f1d660),LL(0xfd177667,0x0d79142a),LL(0xeab4ffc2,0x1d798fb8),LL(0x8d6c7790,0x65d4f135),LL(0x6db0f7cc,0x3bd9feb2),LL(0xeb9db217,0xf714d78c),LL(0x48ba0ac8,0xa3ca23a0),L_(0x000000ce), LL(0xb4e50378,0xe69b95fe),LL(0x3047872d,0x2f7264f0),LL(0x968482d0,0xedcd1afb),LL(0x4afd067b,0x21685d4f),LL(0xd2b0a788,0x8c222e50),LL(0xee57ad29,0x86dde86a),LL(0xb70520ec,0xb933bc16),LL(0x0ddb5005,0x16594b1c),L_(0x0000019c), + LL(0x2b0b1b51,0xbbca315f),LL(0x5bb1b6c3,0x0036d456),LL(0x7469a0dc,0xd48baaad),LL(0x017a26b6,0x27d8ab41),LL(0x02fa6e32,0x15045224),LL(0x0c7090d4,0xdb62af96),LL(0x85ab46be,0x89adad56),LL(0x45b4363b,0x449f71e2),L_(0x00000079), LL(0x96000d89,0xf8377adc),LL(0x4bc2c5ac,0xa5878a73),LL(0x58a681e7,0x18006b8a),LL(0x8426f06f,0xacb84fbb),LL(0xf862f722,0x32b8466b),LL(0x041f4d43,0xe59c6ec4),LL(0xac4fc1fd,0xda852fdc),LL(0xa52e3ee8,0xf6e11234),L_(0x00000176), + LL(0x9fca3c39,0x9ddcb7fa),LL(0x44679a2a,0x8069c471),LL(0x3be369b3,0x0de84dbc),LL(0x82ca8262,0xd5e1f28d),LL(0x89e87798,0xa205de89),LL(0x84051f10,0x5c22abac),LL(0xc26a5b9c,0x99bba5fa),LL(0xdd74ecbb,0x359fa6c2),L_(0x00000053), LL(0x82c210ab,0x2e2ac09a),LL(0x2ac08c57,0x71535b42),LL(0xc5c720e0,0xa7bd1c3d),LL(0x18f95966,0x0a4b0c9e),LL(0x49a62e3a,0x2faa6c64),LL(0x4f85595c,0x529cbdd4),LL(0x7bb9f75f,0x93955cf4),LL(0x50f46a64,0xdefa5af6),L_(0x00000022), + LL(0x1a200a95,0xedc6f59f),LL(0xa294c7f6,0xa2e1643a),LL(0x5eabc120,0x41a385d8),LL(0x0ff38f95,0x6b429a90),LL(0xa608b840,0x5f0ae2e2),LL(0xf1d02f3b,0x9b8946a7),LL(0x2525fc8f,0xc76a7386),LL(0x49cc1359,0xca2a7f4d),L_(0x0000010a), LL(0x8186c176,0xbe8aed8e),LL(0x60d4bdb6,0x86d41413),LL(0x937209e4,0x3c716d10),LL(0xf538d0a6,0xa096c4bf),LL(0xd3c035a2,0x04283ffd),LL(0xb280d9ae,0x4964e73c),LL(0x3893b1c0,0x75d67682),LL(0xc2768753,0x005e5f85),L_(0x00000022), + LL(0x364ca3fa,0x8d283446),LL(0x498b2996,0x86abf4d3),LL(0xfde09c12,0x2dfa3c50),LL(0x0e695616,0x29f9b0d2),LL(0xb697398e,0x48792e33),LL(0x568f5e3a,0x7493cab0),LL(0x6ee081c2,0x657411b7),LL(0xb996a914,0x6bba20f2),L_(0x000001c4), LL(0x21ec8a20,0xcc21ceb0),LL(0xf3a30195,0x04798bbc),LL(0x8327746a,0xa982d5b1),LL(0x2b585e77,0xd3a733ef),LL(0x8fc21ff1,0x683b1710),LL(0xf43ba5ab,0xca115f83),LL(0xeb98616c,0xa31d56f2),LL(0x89236402,0x2fd3f97b),L_(0x000001e5), + LL(0xfdd8cece,0x71daa8fc),LL(0xcd75aec1,0x1ba03e2e),LL(0x3c07bc51,0x57185304),LL(0xca3e327c,0xb1122c0c),LL(0xfb82f00a,0x4ab98ef9),LL(0x143ac664,0xed517312),LL(0xb67dba09,0x3be9088b),LL(0xf6425b41,0x9abf3748),L_(0x000001ad), LL(0xa0f7c32b,0x58516a7c),LL(0x937668fa,0x1a5b0042),LL(0xee40f983,0x70389a31),LL(0x7bddb2f1,0xc5b229d2),LL(0x5e0553f6,0x5a0d088b),LL(0xeae9e1a5,0xf99b1b9a),LL(0xcda92dcb,0x5ef8199d),LL(0x7e285536,0x50942301),L_(0x000000fb), + LL(0xe8acd015,0x276df335),LL(0x996f91a7,0xbba5b9b6),LL(0x8be8a5f6,0xa13311be),LL(0x1f26ef24,0xfe2a95d5),LL(0xee11bab7,0x684a38b4),LL(0x3233a4f7,0x2ff2caf9),LL(0x3771e476,0x50176c17),LL(0x5e24adb0,0x7e6a96ea),L_(0x0000009e), LL(0xcee15413,0xd1540fbe),LL(0x9f444fde,0xc5cef3f3),LL(0x6ce01534,0x25f5b460),LL(0x1d8a8861,0x37e2199b),LL(0xa77157b4,0xea994fb5),LL(0x599e6b65,0xa91dfcae),LL(0x599cf24d,0x48964c92),LL(0x5d9f0d72,0x171d2191),L_(0x000001ac), + LL(0xb07ac833,0xc7cc5161),LL(0x5e82226c,0x71009ee1),LL(0x4bc92633,0xa4a6f458),LL(0x4b11e8ce,0x27cf64fc),LL(0xa35c3f83,0x247f343b),LL(0x08c548d2,0x5b9231c1),LL(0x8238f13a,0x98e33dc3),LL(0xb0046a52,0x4e6220c7),L_(0x0000010d), LL(0x2464e468,0x60df1456),LL(0xc43a8ffe,0xb03d69e6),LL(0xf8867110,0x760c6b46),LL(0x1cbd5f52,0xbfe67f56),LL(0xee1342df,0xf514ecfe),LL(0x7fa3d377,0xeacf358c),LL(0xb7abe871,0xf91db13e),LL(0xf63ff9a1,0xfd2c6720),L_(0x00000118), + LL(0xbcc7e27c,0xfcd4da3a),LL(0x01aa7fce,0x5590f28d),LL(0x891c86bc,0x3fde019f),LL(0xc74e219a,0x47bfd522),LL(0x17dfc33e,0xcd902b91),LL(0x1e1f0327,0x19b7adb8),LL(0x46fb1987,0x4aa71b67),LL(0x7c133f73,0xc87d00cc),L_(0x0000009a), LL(0x24c3c4f4,0x15897652),LL(0x484cb85c,0x6d5a49dd),LL(0x08cbe8b3,0x0398f1d3),LL(0xc2570a5f,0xcf0588fd),LL(0x75aff023,0x9a086ca6),LL(0x7d708565,0xf0ab637b),LL(0x478e9220,0x4da37998),LL(0x79f64eda,0x9f09ba72),L_(0x00000129), + LL(0xf12325c2,0x3cf6f674),LL(0x4d0bf9f0,0xe45ebcfb),LL(0xf49cc75a,0xf02c0b22),LL(0x198a7df8,0xce88b254),LL(0x798e3ccc,0x452bc12b),LL(0xcb1f3272,0xf7e1eeab),LL(0x204a39c3,0x03001038),LL(0xbf6a035b,0x8bb9d05a),L_(0x00000106), LL(0xbee3c686,0x519b1e12),LL(0xff47d24d,0xecef22c6),LL(0x1e6f218f,0xb9743d3d),LL(0x7fe5e0b0,0x0de37bec),LL(0xb84cd289,0x2f608290),LL(0x640acc09,0x0325466e),LL(0xf1f489de,0x523a4381),LL(0x5a2fd923,0x78483089),L_(0x0000012b), + LL(0x55dde0b9,0x51ca4b89),LL(0x0c9b5cc2,0xcb500f85),LL(0xb99572d6,0xb82356c8),LL(0x9eef8952,0x575ebe20),LL(0x607df288,0x389253a4),LL(0xa421a6b3,0xd513ff9b),LL(0x99f0eb4d,0xc84b56b7),LL(0x253ed789,0xe6a5c4d4),L_(0x00000093), LL(0x0f18530f,0x98ff217c),LL(0x6930ae01,0x8abc5898),LL(0x12fd1e77,0x94fad4d8),LL(0xf2ff5095,0x6733dcce),LL(0xf10fab65,0x36afad83),LL(0x17d75c59,0xd99578f7),LL(0x8a1a313c,0x16027411),LL(0x0bcd7387,0x46078ec4),L_(0x00000154), +}, +/* digit=43 base_pwr=2^215 */ +{ + LL(0xcb23bf8a,0x011cfb71),LL(0x25479ac0,0x785ff67b),LL(0x2f48bcdb,0xc454fd25),LL(0xf62da267,0x4e460f65),LL(0xac759a15,0xe6fa21e0),LL(0xdb56d239,0xfa07770b),LL(0xb91d7cce,0xfe275a8d),LL(0x68f07f46,0xa1529273),L_(0x00000127), LL(0x74d64a14,0xd7969a0d),LL(0x36f066b2,0xd81a759c),LL(0x3a664061,0x929c3e1c),LL(0x5ba8c41d,0x033ad63b),LL(0xfdb5a8a4,0xf387b665),LL(0x2b433c84,0x1e742e2c),LL(0x4f2d4d93,0xb030d2de),LL(0x8d631141,0xe3845c24),L_(0x0000006d), + LL(0x020c1dd2,0x650c039d),LL(0xab7b6907,0xb4f64d44),LL(0x26b42700,0x0576d051),LL(0x2c72c1e2,0x70d2ad71),LL(0x4322ae9e,0x315f4631),LL(0x89904b57,0xef02dfb1),LL(0x24905a45,0x8a7b4701),LL(0xde26cce6,0x5f0db2ca),L_(0x000000ac), LL(0x55247780,0x3a42cd20),LL(0x6fcfeb99,0xee9920d8),LL(0x1cc7f2d2,0x46bdb299),LL(0xb71c2095,0x1516a6ea),LL(0x99e62c53,0x95f1492f),LL(0x197ae770,0xe95c2cf5),LL(0x013e12e8,0x2aad7be2),LL(0x60b78cb7,0x0e70b967),L_(0x00000032), + LL(0x5d9cf3d8,0x7b152b81),LL(0x2adc31d1,0x1cf4d989),LL(0xf817919d,0xea745ea9),LL(0x86caaaf3,0x035cfaca),LL(0xbd62e874,0x533bc33d),LL(0xb1acfb8f,0x2cc2ce8d),LL(0xb212b5b7,0x5b9ba7f0),LL(0x350192b7,0xce04c178),L_(0x000001a3), LL(0xdb4255a9,0x88563e49),LL(0xaa946b95,0xe4c90142),LL(0x0e515aee,0x5062c2f0),LL(0x99e87538,0xcd39192d),LL(0x52eb943e,0x0c893238),LL(0x0201b73c,0xfbac7e1c),LL(0x1ab36a78,0xc6d833b4),LL(0x58d01a7c,0xe359c01f),L_(0x00000008), + LL(0x97851e87,0x7511fae2),LL(0x9afd1135,0x428434f6),LL(0xab322fa2,0xcbe5e3de),LL(0xd89f361e,0xc1b08880),LL(0xc1fbd2b7,0x6a50aa80),LL(0x9e40537e,0x7fdf104d),LL(0xd4f51df5,0xe707164e),LL(0xb78a6cfb,0xd887e3d0),L_(0x00000136), LL(0x9a5983b8,0x96365e7f),LL(0x129d87d9,0x64aad3c6),LL(0x2952186a,0xf8224d3c),LL(0x45209284,0xc689c1d4),LL(0x2c194d7b,0x03f44aec),LL(0x0e7c6b2d,0xf18a57e0),LL(0xe28c9eb3,0xfac4981d),LL(0x4b8b7de6,0x55215906),L_(0x00000009), + LL(0x7754239c,0x3a3a13a5),LL(0xbeace249,0xc22b9755),LL(0xd063181b,0x27e6ebf5),LL(0x80b61753,0x0eb1c7f3),LL(0x8b95d0ba,0x791e9667),LL(0x5d4d0f0f,0x5f5189e4),LL(0xdd28c3e4,0x9162d716),LL(0x2eca4da1,0x40913d2a),L_(0x000001de), LL(0x21d602fa,0x85fea8d0),LL(0x3c004f10,0xa6620dad),LL(0xb3680a4e,0x31990981),LL(0x8a6964de,0x3b4c2f57),LL(0xd1986197,0x3b4fdf64),LL(0x5bc5cf00,0xea0f7010),LL(0xbf1dee68,0x0d263581),LL(0x3edd2000,0x8ba6db98),L_(0x00000012), + LL(0xc5f1e841,0x79147285),LL(0xbe273f4c,0x71c0654b),LL(0xec66bd4d,0xdd0505e9),LL(0xed4771b4,0x4c891619),LL(0x316ff12d,0x821a0542),LL(0x0c65ede4,0xa23cffae),LL(0xb678c0c5,0xbf05e02d),LL(0x32bbf48a,0x91ff4f9e),L_(0x00000126), LL(0xf495f39d,0x944ec586),LL(0x5c351b2d,0x00e74766),LL(0x3939c0c8,0xfe310474),LL(0xb780a9b2,0x5e63ba55),LL(0x11cfcec0,0xc11119c9),LL(0x322972c9,0x0c8e0043),LL(0x35f5ba3b,0xa0946bc2),LL(0x222b78da,0x622257dc),L_(0x00000082), + LL(0xba9d4a6b,0x2b9dae76),LL(0xe9b24e64,0x1b491ac4),LL(0x9716bae3,0x162c28a6),LL(0x192c7196,0x00752a8a),LL(0x10883cfa,0xf0af2cfc),LL(0x77a5388d,0x5f1ffb0c),LL(0xebf78534,0x49abf2a7),LL(0xe9343bc9,0x54bcef89),L_(0x00000090), LL(0xd39aabbd,0xa864f2a7),LL(0x1bdde3a5,0x0362ffa7),LL(0x45782cba,0x113c94f8),LL(0xb94efa60,0xb5969326),LL(0xd2b826b0,0x92ab6bc9),LL(0x228e2d7d,0x1f6dc09e),LL(0xe5f07f40,0x3371efd7),LL(0x87e6028d,0x90fcb8fa),L_(0x000001be), + LL(0x3b22c3be,0xcf53147b),LL(0x97a83e73,0x0fba4048),LL(0xd11d0f51,0xfcf9128e),LL(0x6dfde4ab,0x095c92d5),LL(0xbcfa2a47,0xff3cd334),LL(0xa5b6f4d4,0xa2490038),LL(0x5df73169,0x663bcbc9),LL(0x41aba80e,0xa47769e8),L_(0x00000064), LL(0x62c4cf6f,0x2104365a),LL(0xa582938f,0xc439a531),LL(0x43321e6d,0xf7387146),LL(0xee861253,0x52424fe3),LL(0x13590283,0x0a676302),LL(0xe71ab2ae,0xa837702f),LL(0xf460396c,0xf7bce515),LL(0x01882e04,0xd9362399),L_(0x00000193), + LL(0x1e3dd431,0x9bd2b2b9),LL(0xc33456a5,0x6dcdccc4),LL(0x97a89ed3,0x865bca41),LL(0xbdb83821,0xf50a59bc),LL(0x46a8f43a,0x47c10299),LL(0xbaa69204,0x03139274),LL(0x1da8242a,0xa899da5a),LL(0x49b0bcc8,0x2caf68d5),L_(0x000000a8), LL(0xb2c24e74,0x4dc88c23),LL(0xc1c2ff36,0x896e10e9),LL(0x10c6c1db,0x7a488fa2),LL(0x58161012,0x6b4ceefa),LL(0x5188acf7,0xea1e2f11),LL(0x72073c50,0xefaa1151),LL(0xe696e16a,0xd65f38a5),LL(0xe4dea3d4,0x6710e2d4),L_(0x00000011), + LL(0x84a8ceca,0x6cdc17de),LL(0x2c374c6c,0xe3454080),LL(0xbd6a5b20,0x337b0f58),LL(0x40246c40,0x31d7aff9),LL(0x49292d34,0x01dba6a8),LL(0x37486a26,0x41a0f90b),LL(0x12d61cbe,0x782067dc),LL(0x3033f828,0xebc39fcd),L_(0x00000086), LL(0x93cb68aa,0x026818da),LL(0xf42673be,0xf2e2739e),LL(0x40e906d3,0xd8ecf6f0),LL(0x37b0e1f1,0x5c024d38),LL(0x6708c065,0x3417cf59),LL(0xc5788208,0x17020946),LL(0x8942a103,0x7086a405),LL(0x279752bc,0xbd8d65b0),L_(0x00000074), + LL(0xd8f6e509,0x9abc3d40),LL(0xf756f14e,0x748874bf),LL(0xf9192ae1,0x50f7dc14),LL(0xfb847314,0x424a6e96),LL(0xd7141cc9,0xe0539e22),LL(0xefedb9cd,0x7f5ec1a8),LL(0x7abbcc13,0xe6446e18),LL(0x0050521f,0x3706445a),L_(0x000001d0), LL(0x4ed46ff1,0x2f62e709),LL(0xa5e744f0,0x8279d454),LL(0x8aad355f,0x03801f2d),LL(0x88a334e7,0x30342602),LL(0x34cb8228,0xed180e75),LL(0x6d4243df,0x5bbbe349),LL(0xd0752a72,0x0977e643),LL(0xd5658e43,0xf968b621),L_(0x000000a7), + LL(0x2137affe,0x3757bccc),LL(0xce9d3ef4,0xb10a83cd),LL(0x021aa7d7,0x804bf03e),LL(0x79a14071,0x09822fa4),LL(0x1adecf50,0xec4d2fe9),LL(0x8fc3b061,0x479fbad1),LL(0xffe82ea4,0xb70c5762),LL(0x25b0bed7,0x8a667da4),L_(0x0000015c), LL(0x574750b9,0xd836c22b),LL(0x9beeade4,0xd28e01a7),LL(0xd7c41634,0x124715f6),LL(0x83d30d7e,0x8e33c4f9),LL(0x2ee2bdb2,0x5442a068),LL(0xa18cfc1f,0x68390a48),LL(0xa6cb1637,0x44abd789),LL(0xa8ecc588,0xbd6682cb),L_(0x00000183), + LL(0xe26454b3,0xd8199c9b),LL(0x86b3c132,0x77f229f5),LL(0x1a49a2e0,0x6f74d75e),LL(0x15ed7662,0x8dd2368b),LL(0x7d799783,0x313152ab),LL(0xa636aa73,0x925319e7),LL(0x2947bd12,0xacf4c559),LL(0xb2b023d8,0x0322c16a),L_(0x000001d9), LL(0x6d2236bf,0x8a09b0a3),LL(0xb1025eae,0x8ae5f654),LL(0xf817133f,0x081d6d59),LL(0xea1aa5d9,0xe9090ae2),LL(0xe61c2d54,0x0784905d),LL(0xf542221b,0x5789e25c),LL(0xa9b09c19,0x1b8dadc2),LL(0x7d4f5221,0xabe01efb),L_(0x000000be), + LL(0xa224339b,0x8fc36944),LL(0x1a86a356,0x88a55222),LL(0xa9332303,0xfc1f186c),LL(0xf8c2ca0c,0x1f24d4d5),LL(0xa82a6905,0x753ac024),LL(0xb6761f2a,0x8a0fe4e0),LL(0xb4a03fa9,0xd1d20586),LL(0xcb862d5f,0x2bcb9949),L_(0x00000092), LL(0x50da47cc,0xa285574f),LL(0xb1192295,0x23eb5f8c),LL(0x2436f1d4,0x3f4febd2),LL(0x842f6ae2,0x0f1f266f),LL(0x8091b264,0xee94d349),LL(0xf4561f25,0x6f4a16f1),LL(0x6e303b52,0x80ed7ffc),LL(0x08bbc14e,0x6f957c19),L_(0x000001ac), + LL(0x34993096,0x73d10fa8),LL(0x1b164c81,0xc855b452),LL(0xdd4617a8,0x9be0c270),LL(0x94a57ba1,0xb28b6ed5),LL(0xc1383246,0xc74bc4a3),LL(0x17910967,0x2a2a0e34),LL(0x8aab9202,0x93b8d150),LL(0x122babf8,0x1dffa251),L_(0x00000073), LL(0xc68b787b,0x5fd7acd3),LL(0x906979fc,0xf242bd9e),LL(0xc7fe62d6,0x59507727),LL(0xa94a1beb,0x966af710),LL(0xe7344f5a,0xd397803f),LL(0x5b835cef,0xcd196fb1),LL(0x1ca9e8ac,0xe701eb7e),LL(0x09bdf0a9,0x521354ea),L_(0x000001c2), + LL(0xd206da83,0xc389a398),LL(0x92326c61,0xc80b1e6a),LL(0x0b658149,0x23067f4a),LL(0xd5cf4f64,0xc96735ae),LL(0x1cf4dd22,0x43cb53c3),LL(0x4b478ba1,0xb353c721),LL(0x3b1bbb1e,0x46f2e84d),LL(0x7b5aa79b,0x4a4fa3d6),L_(0x000001d4), LL(0xcf711e2d,0x5ad31f07),LL(0x5402e45d,0x19f0b31e),LL(0x55650578,0x214cdf81),LL(0x3fd50ebe,0x3efd8e06),LL(0xd808dee6,0x0c82d63a),LL(0x39ccec30,0x39dfd0ee),LL(0x5249be7d,0xb6c788e8),LL(0xebe9271a,0x7ffa3cad),L_(0x00000072), +}, +/* digit=44 base_pwr=2^220 */ +{ + LL(0xe3ee97b9,0xfd61361b),LL(0xf3125658,0xd69b66e1),LL(0x96b636a1,0x0c7ac9e9),LL(0xe69b9e47,0xf9bb3617),LL(0x1b1e895b,0x12050a8c),LL(0xfa5a11a5,0xa2492213),LL(0xc2919aff,0x08d55c3b),LL(0xc4be1b10,0x6dcf2c08),L_(0x00000192), LL(0xa93efc6a,0xb4fb57fd),LL(0x6ce4aac2,0x6292f827),LL(0x9277cab1,0xc90518a9),LL(0x144e677d,0x0432d015),LL(0xea4408ab,0x35d9214e),LL(0x49b20eb2,0x2560b8a6),LL(0x48a45d8a,0x37dd269b),LL(0xcecf7d1d,0x71a47616),L_(0x0000009d), + LL(0x189072b9,0xa734d86d),LL(0x475ac257,0x324330b9),LL(0x3a9d12f1,0xcecaa5dc),LL(0x048adf08,0x33641cc3),LL(0xbfcc4fdc,0xe40352a6),LL(0x76f01bad,0x6e93dac8),LL(0x5bd7dfb0,0xc0e1ca53),LL(0xb21d4494,0xb51965b8),L_(0x00000019), LL(0xe7f6998f,0x46f90e9b),LL(0x76cb857a,0x1b517407),LL(0x31907caf,0x38843e17),LL(0x37770400,0xb3c14ab5),LL(0xb47cfe14,0x58c99d12),LL(0xd18daa18,0xd4551590),LL(0x84db2817,0xc4d8f7ef),LL(0x5a8544bb,0x752b595c),L_(0x000000e1), + LL(0x3382876f,0xa8718c9c),LL(0xd016412e,0x3d459798),LL(0xc7059eeb,0x07afd251),LL(0x7f6e9107,0x6ae603f5),LL(0x7c29b336,0x1f1d424b),LL(0x1f08b6d1,0x06f8f459),LL(0xfa0b1884,0x6dfa46f4),LL(0x22a09ce4,0x1ee6193a),L_(0x0000013e), LL(0xcfd96283,0x59ef37aa),LL(0xbc282a7b,0x0490844a),LL(0x16eca5fb,0xfa414af6),LL(0xdd42a4a0,0x748c915e),LL(0x6f1ab810,0xa3d4af5a),LL(0x31ef86bb,0xe768aff3),LL(0xd8ffc35c,0xb6c4e536),LL(0x6e278d36,0x8f61ddd5),L_(0x00000023), + LL(0x1fe994f7,0x108204ec),LL(0x1febacf8,0x0a0c3a40),LL(0xa1fbe66e,0x2570b727),LL(0x343654b7,0x5299d8ae),LL(0x83e0647b,0x158b323a),LL(0x3d86ee0d,0x758534d1),LL(0xe946224b,0xcb77d0eb),LL(0xe9a38321,0xb845ec39),L_(0x000000a9), LL(0xcd07b3e0,0x4421327c),LL(0x13edfc50,0x0c4b9b9c),LL(0xefee69b8,0xce07a452),LL(0x110b9736,0x2779de28),LL(0x810433de,0x19cb506b),LL(0x1468d237,0xd2930983),LL(0xb54615ee,0x895d360f),LL(0xa6a72f30,0x2a939f9f),L_(0x00000082), + LL(0xbad2c784,0x613613a0),LL(0x41479bab,0x64b3ba28),LL(0xae853dfe,0xd7d5f8f3),LL(0xeddc5d69,0x3c023c98),LL(0xc2af1c91,0x5e51c064),LL(0x3e811beb,0x3e28caf2),LL(0x297f73a1,0xb2c63f7a),LL(0xe92c2db1,0x272783c6),L_(0x00000069), LL(0xc2b0e8b8,0x4d9e33e7),LL(0x2930859a,0xf96d2a6e),LL(0x21c82319,0x234b3a37),LL(0x99962855,0xe1e952c7),LL(0x834c3fcf,0xa9fff526),LL(0x2d66290a,0xc1aa8293),LL(0xd0618b6f,0x65d795be),LL(0xd8f51b17,0x7ad3a784),L_(0x000000fa), + LL(0x345605ef,0x6fb99ec5),LL(0x5b03ab3b,0xdf673d70),LL(0xd514df02,0x97926d51),LL(0x68bd9794,0x7f3cad99),LL(0xa7bbd732,0x807b8edf),LL(0x1dee6527,0x9072fc5c),LL(0x6db8f170,0x8a088d03),LL(0xfad430f3,0xf3373c9b),L_(0x0000019d), LL(0x6523f7ac,0x562932b2),LL(0x98ce826d,0x15d43a46),LL(0xd64992b9,0x0e1471fe),LL(0x12cf137e,0x11a1c256),LL(0x19907c68,0x97e5e746),LL(0x5dcff6a5,0xb4d10f45),LL(0xfe503afc,0x2daf8e96),LL(0xbfaf4738,0x51a1e9e2),L_(0x0000005e), + LL(0x52c7ebf5,0x57c899ed),LL(0x309ddc9f,0x000b8805),LL(0xf9ec0561,0x61be65ad),LL(0xdb755990,0xc6ac2e8b),LL(0xf8f392c7,0xc546a9f7),LL(0x709f90fb,0xaa4eb38f),LL(0xb81ee256,0xe3bb73d5),LL(0x920cd9ff,0xe54f7913),L_(0x000000d1), LL(0xecfeb4fd,0x6fe432ea),LL(0x7d99d437,0x42314efd),LL(0xecbf2570,0x0d11bf19),LL(0x1a26524d,0xc070e881),LL(0x80db7170,0x69bb46ac),LL(0xed697625,0x6e7f5dec),LL(0xf5d4f199,0x35c855b1),LL(0x63c6d1bc,0xcfaf131b),L_(0x0000017f), + LL(0xdff5e6d9,0x4c7faf89),LL(0xe289504c,0x7c67c701),LL(0xc21c143d,0x51104808),LL(0x429b8b10,0x8547ea3f),LL(0x643f8b1a,0x442d1597),LL(0x8e30463a,0x1322c20d),LL(0x9700b9ca,0x12313e31),LL(0x53c7c741,0x429e582d),L_(0x0000001d), LL(0xc25e3208,0xa6df174d),LL(0xf30a9c65,0x734a8421),LL(0xcca7bd70,0x12f441c1),LL(0x42e970e9,0xda35c856),LL(0x990f29b0,0x7fbc6108),LL(0x201a5ca8,0x006704f9),LL(0xb4ba5b8a,0xd79c4200),LL(0x5332f15d,0xaa2c5720),L_(0x000001dc), + LL(0x0f472f30,0xa1d7fa9f),LL(0x366d01e5,0x0b24e344),LL(0x05318d76,0x9ed7c092),LL(0xd4cb6907,0xdf8af7fc),LL(0xe97d11bc,0xcad57852),LL(0x4e593cff,0x966648ef),LL(0xeb5229ac,0x0513e9bd),LL(0xc0b6887d,0xc4457c4d),L_(0x00000129), LL(0x1a11be6c,0xe56e3c4a),LL(0x33909c43,0x6b6ecd98),LL(0xab630f3e,0x58c96e3b),LL(0x604359ea,0xa6fb1a48),LL(0x4c23bc41,0x01509a8e),LL(0x735b6fd3,0x55538a0d),LL(0xc1e6f88e,0xca10627f),LL(0x43b7d098,0x7a0bef75),L_(0x000001ab), + LL(0x009970af,0x382d4ce3),LL(0xd57fa9f7,0x39f2057e),LL(0x5a8fe9d0,0x819adb6c),LL(0xf4dd28c4,0x26c97625),LL(0xa0db7a3e,0x6c864ae6),LL(0x8bee872f,0xfd35c90d),LL(0x42a5de0c,0xf6b8c643),LL(0xa0d68766,0x613a35a1),L_(0x00000002), LL(0xcdee18cd,0x7201d2d4),LL(0xeb515a90,0xb3006a97),LL(0x293640a4,0xdf1363d1),LL(0x4e898435,0xc4282ef1),LL(0xf5eec35c,0xf5395189),LL(0xf9d8e87e,0xecf465a2),LL(0x621a8997,0x2d4680db),LL(0xfe197810,0xf2c35d16),L_(0x00000113), + LL(0xbfba8722,0x35c78619),LL(0x976fd128,0x4fea3432),LL(0x9d455cba,0x94c9bc3b),LL(0xb7bb73c4,0x0a3d4425),LL(0x90c2ec3a,0xc1f93e1c),LL(0xa95d87c6,0xe60757b3),LL(0x60d5d399,0xd3d27995),LL(0xce2c84d1,0x81c8808b),L_(0x00000126), LL(0xecc27275,0x32b7091e),LL(0x76361e05,0xe202d497),LL(0x074baca9,0xd7df203d),LL(0x18d9c96d,0x60965442),LL(0x6777a2e9,0xcf542875),LL(0xcea9162e,0xd6cf9057),LL(0x0e08540f,0x118843d2),LL(0x12ce0e32,0x64680618),L_(0x000000bb), + LL(0x4dba9d58,0x3de4c30b),LL(0x1640f2bb,0xe1cd2dab),LL(0x67a49e8e,0x68415129),LL(0xce1a4189,0x5f6655b9),LL(0xf8e55d14,0x58251e9d),LL(0x2a896a11,0x2990bcd1),LL(0x5ee2f029,0xc1b51e11),LL(0xe59128b6,0x7f1b211c),L_(0x000001e4), LL(0xedda1e14,0x0e4c3270),LL(0x75ae7bca,0x0ff0470f),LL(0xe26fb687,0xdde851ff),LL(0x6353acb2,0x661a72f5),LL(0xa014b448,0x6da88895),LL(0x20ab0fca,0x41dc7a9c),LL(0x90420ccc,0x97a7f272),LL(0xf726e07e,0x23c2dfa2),L_(0x000000ae), + LL(0x9697fa66,0x19987e83),LL(0xc4bea825,0xb4d6f37a),LL(0x86bba8ac,0x1e145dc1),LL(0xa3d3860d,0x9d377493),LL(0x538d1baa,0x9ce67c55),LL(0x507bf776,0x0148462a),LL(0x563563c0,0xc2891330),LL(0xba0e7843,0xc76b64b0),L_(0x000000b3), LL(0xac531f86,0xca889e53),LL(0x632d2ce5,0xe7e3d3fe),LL(0xeabe8bf3,0xb7126e82),LL(0xcc6bda06,0xf58c6361),LL(0x69480574,0x6a99c0d0),LL(0x660e6906,0xd1fdf14a),LL(0x465778f0,0xddbb43b6),LL(0xb843d29c,0x575fd92f),L_(0x000001cd), + LL(0x311db7b4,0x2cd4fd82),LL(0x0e9a73c7,0x52c71a96),LL(0x4d3a4557,0x067ccd35),LL(0x3e412b8b,0x7bd77ec2),LL(0x951e31d9,0x4100bac7),LL(0x2ac6482b,0xccccb053),LL(0x6361906b,0x79655211),LL(0x269a7fe0,0x756f8ab0),L_(0x000000fb), LL(0xad9f10f9,0x8ce6630b),LL(0xcbecac0c,0x4a29a7b7),LL(0xf7ba2d3b,0x47e9ba07),LL(0x2e6c073a,0x5aa6a94b),LL(0x73cf6f20,0xa8a42977),LL(0x50805433,0xf9945386),LL(0x74ac62ed,0xc8f04c45),LL(0x14e4baea,0xe37de45f),L_(0x000001c5), + LL(0x860bbc4f,0x73f77d7e),LL(0x6ff96082,0x58430006),LL(0x328b95a9,0x82931188),LL(0x968102c5,0xbb40cb55),LL(0x6514614a,0x370bf205),LL(0xe5de48d5,0xb3d94790),LL(0x73c104b4,0xa5683b4f),LL(0xfb96fb1a,0x36a9677e),L_(0x00000050), LL(0x0c67ecca,0x32bfd837),LL(0x4594f7a0,0x3fb584bb),LL(0x9be3e3c1,0xc86bb1e7),LL(0xef4aecee,0xfa93fc70),LL(0x9de5dfe2,0xbfd3b8de),LL(0xe7670296,0xe1fa5638),LL(0x228cc6d9,0xd230d44e),LL(0xf7797644,0x82d4c20c),L_(0x0000002c), + LL(0xef42daff,0xe19f88e8),LL(0x828b99d9,0xc2beefa3),LL(0x51fa512e,0xd33e3c3c),LL(0xbe14d684,0x34a6c37a),LL(0x5b5936ae,0x89d4bea5),LL(0x2802583c,0xd938e649),LL(0x98da605b,0x1f045420),LL(0x55288cfc,0x659c47e4),L_(0x000000d0), LL(0x046a68ec,0xb9ddaea5),LL(0x22472a49,0x0aefe3e4),LL(0xc2da9569,0x6e21cee3),LL(0x0c7dcef3,0xb14f0abf),LL(0x98c3c9ea,0xb64941e1),LL(0x4819eee0,0x433cfcf6),LL(0xbfe77fa8,0x2f7686dd),LL(0x03c3b28a,0xdbfd2334),L_(0x000001c3), +}, +/* digit=45 base_pwr=2^225 */ +{ + LL(0x522fbbd1,0xc3b7107c),LL(0xe8887082,0xd218cc42),LL(0xcd304c29,0x7a96d44b),LL(0xf1c4d847,0xee7f483f),LL(0x530d4bec,0xc951d19c),LL(0x4d6bf1fd,0x71d2d68d),LL(0xe03d009b,0x4d3bd1df),LL(0xc4553769,0xdb4cb1a2),L_(0x000001c3), LL(0xfa15f331,0x5e86f0e3),LL(0xcaf5fb4c,0x715c3388),LL(0xb2f14ba7,0x81191db4),LL(0x38426103,0xf68a08e3),LL(0xb75d25e0,0xd342059c),LL(0x92f767fc,0x4dec2bd2),LL(0x7a696b41,0x16057d6a),LL(0x8adfb670,0x99c277b1),L_(0x00000159), + LL(0x733860ad,0xd6f16b10),LL(0x088e20bf,0xb30d007e),LL(0x859fdd39,0xd4c40b6e),LL(0xc9196072,0x0a59d2a4),LL(0x3c4f607d,0xaf5b531a),LL(0x5c546c30,0xfdc40588),LL(0xdc1d5df2,0x2971b1ad),LL(0xfb26f4df,0x7cb15104),L_(0x000001b6), LL(0xd17eec91,0x9ff74646),LL(0xe3bee8f3,0x96143e3d),LL(0x560fc63e,0x2e0395d9),LL(0xfd9d7aab,0x099cc808),LL(0x422f153f,0x4e3c3dca),LL(0xefabb0d7,0xed2c2c61),LL(0xd736943a,0x78f87c18),LL(0x96d74e41,0xb76afadf),L_(0x000001d1), + LL(0x6c4ef83b,0x204ae17c),LL(0xab5b4b2b,0x780e0409),LL(0xc4c863d0,0xf73d00d9),LL(0xd243a003,0xd17b97ed),LL(0xca6e6ef7,0xd335ec2e),LL(0x3f246d97,0xd6c07def),LL(0x0e2518ce,0xb8b0595f),LL(0xfdf728fd,0xc1ccb10b),L_(0x000000dc), LL(0xd02f5048,0x869f012d),LL(0x0a767d8e,0xbe6fa9d5),LL(0x1bbb0510,0xdeeebbfe),LL(0x8f4cdab7,0x8332cdf9),LL(0x75d651f0,0x54687821),LL(0xdd0fc83f,0xa428610a),LL(0x965277af,0x38635dc4),LL(0x9dff5c34,0x0961df5b),L_(0x000001fc), + LL(0xeb6cb2dd,0xe4290556),LL(0xea12a072,0x762385fe),LL(0xd082bac9,0x1be16424),LL(0x8697c433,0xf06c7a59),LL(0xa812dd21,0x7de72b68),LL(0x02f90069,0xa2e56525),LL(0x9acaec02,0xa89c7efd),LL(0x4f9120c4,0xdf713a32),L_(0x0000001b), LL(0x1027a34d,0x3367220e),LL(0xc9641453,0x9b048cab),LL(0x29a9fac9,0x0e9e757a),LL(0xcb21c285,0xde9cc170),LL(0xbef96957,0x7d017c03),LL(0x0f3534a3,0xa9c18cbf),LL(0x5a627fd6,0xed78ac58),LL(0xb9c29da8,0xef092aca),L_(0x000000e4), + LL(0x27ba92a3,0x1cb1ec3d),LL(0x669f05f8,0x03d201d9),LL(0x6bb4d70b,0x898f998e),LL(0x96c9a0f0,0xe22c0440),LL(0xfa56577c,0x7b9dee1b),LL(0x00502b66,0x47777bc8),LL(0x483cf935,0xffb71b74),LL(0x0b52d0b2,0x39112d39),L_(0x000000a7), LL(0x6e9174c3,0x75c45aee),LL(0x6b3c757b,0xf1bef81e),LL(0x7e3d1f7a,0x21a74b7e),LL(0x2bfe9dfd,0xb0da2bc4),LL(0x90c8361c,0x0c5783ca),LL(0xf50913fe,0x5dd47036),LL(0x34045f12,0xd0f87837),LL(0x89dc259f,0x560578ab),L_(0x000001bd), + LL(0xdd7b63bd,0x1a521d30),LL(0x8270aad1,0xd7dd0f9e),LL(0x5bd17ae9,0x2341942e),LL(0xc840cb6d,0xdc090118),LL(0x1c49ccd4,0x60e02fa4),LL(0x28d04bf0,0x3570b020),LL(0x1dc79e5a,0xbd1e244b),LL(0x5f5e1042,0xeebf73ef),L_(0x00000024), LL(0xa728463d,0x9d82fe22),LL(0xf2a4d116,0xfbb0437b),LL(0x538ffa89,0xac67b2fd),LL(0x70b0e36d,0xcd72f925),LL(0x3b843326,0x26042e6e),LL(0xd58ef907,0xa54711c2),LL(0x40c00366,0xa62c4885),LL(0x33e0a1f1,0x758c2c5e),L_(0x000001ec), + LL(0x49abc1ac,0xf11f835f),LL(0xd4f6e5fa,0x4a99daab),LL(0xbfa7d98f,0x3f46a163),LL(0xe712c72d,0x869f8036),LL(0x194ee078,0x1283d5ab),LL(0xe9c40094,0xf4b53cf8),LL(0x8eccbfb3,0x865de4fb),LL(0x27d82426,0xc4399d77),L_(0x0000011a), LL(0xc3188564,0xa59eaa03),LL(0xb1a23e95,0x99d72c23),LL(0x48055f02,0xf5f1e1c0),LL(0x04a35336,0x448cee4d),LL(0xcb7b9a8c,0x5862f10a),LL(0xb9974831,0x93b3f7d9),LL(0x93c6f79e,0xb09c629c),LL(0x2a3760fa,0x5d47957f),L_(0x00000001), + LL(0x1bb374f7,0xf060edf1),LL(0x83a0baf3,0x26de7078),LL(0xeb8cb2a3,0xf5a8d631),LL(0xcfa95554,0x6ba14fb5),LL(0x9d950c23,0xc53769e2),LL(0xc3b6e6d4,0x857d43ea),LL(0x00e396b6,0x28cc2c64),LL(0x79b3b40a,0x42ca52de),L_(0x00000101), LL(0x744d95ae,0x4e536d43),LL(0xbb696fec,0x60fe980d),LL(0x86879c73,0x6a564e15),LL(0x6796d473,0x62e7ce9d),LL(0xee75c812,0xd4cced89),LL(0xdd4f732c,0xa3a75fe2),LL(0x4a4d97d2,0x62def6c0),LL(0xfce046cc,0x0bfe781a),L_(0x00000059), + LL(0x46604a6b,0xecebff30),LL(0x5ddecacd,0x66805c77),LL(0xc732fa10,0x62e2a037),LL(0x9f8318aa,0xf535306d),LL(0xcb188ede,0xf3ae9b72),LL(0xd4215242,0x76515ea4),LL(0x19ee9251,0x04b30ff0),LL(0xfdb4add0,0xc2006bc5),L_(0x000001f3), LL(0x3b010d29,0x08f431a5),LL(0x9a41c273,0x4ef9856a),LL(0x29336f92,0x89a37aaf),LL(0xb4f719c9,0xb6ae5b4c),LL(0xcb8b83d7,0x0b93351c),LL(0x579d32e9,0x95ac6c1d),LL(0xed14de1a,0xc9a3144d),LL(0x59d39bac,0x4809d3c0),L_(0x00000192), + LL(0xb4a2a13e,0x46b4f926),LL(0x31967f76,0xedbec7a4),LL(0x9540a500,0x7d4cba0a),LL(0x3664934a,0x44eee05e),LL(0xacaf15ab,0x7e273dff),LL(0x0d40978b,0xb55d54b7),LL(0x7a7b2c2d,0xb2400231),LL(0xcc267a21,0x31dec63e),L_(0x00000134), LL(0x05754bc0,0x9ea998cb),LL(0x5e543e59,0x22a0befc),LL(0x0dee7b14,0x1aa7e66e),LL(0x052bb589,0x51c3c220),LL(0xe7133b54,0x64b84789),LL(0x86fee1bb,0xacd3a9a6),LL(0x6d321f88,0xf3dee610),LL(0x17435c7d,0x64e0790f),L_(0x00000193), + LL(0xfde9e64e,0x824c77d2),LL(0x1d5087de,0x3c424cb9),LL(0xce8e9c97,0xb3b1c7ef),LL(0x65ef8961,0x36bdf7df),LL(0x936db078,0xe1a9152e),LL(0x9ff36717,0xbde711fb),LL(0x1b59074d,0xc2a17a75),LL(0x9070200e,0xa0657ad1),L_(0x0000006b), LL(0xc32bca7d,0xf471b9b4),LL(0x63dca49d,0x23fe450a),LL(0x7aa88a47,0x569744e7),LL(0xbac5c025,0x557519ba),LL(0xc31b16cd,0x90672c5b),LL(0x7609de28,0xeb879e6d),LL(0x06a4f8d7,0xa50f3b9e),LL(0x45a7792d,0x5ef4893d),L_(0x00000138), + LL(0xa91734a3,0xa8c609cd),LL(0x3fc0a251,0xe916d838),LL(0x09bae516,0xdc8442b3),LL(0x70eda9b4,0xdbbd2829),LL(0xe66c09a8,0x44077102),LL(0x46f0d061,0x0c8b9a97),LL(0xe7c4e4e6,0x96dd9b50),LL(0xd93b4696,0xf2abcbd4),L_(0x00000050), LL(0x1b9aac0c,0xdcc67ed7),LL(0x34c98a81,0x1a864f2a),LL(0xd79eca11,0x46960243),LL(0xaf4ad720,0x02db8ea4),LL(0xe8d429d1,0xd9dae172),LL(0x9cac2c01,0xf704ba3a),LL(0x052267c9,0x0ee381b0),LL(0x768c8223,0xf95050b5),L_(0x0000019f), + LL(0x12097ddc,0xdbee340c),LL(0x7596d517,0x7a4d90d8),LL(0xe88332d5,0x27312835),LL(0xadc174b8,0xbf7deda3),LL(0x9fa8589b,0x30a04404),LL(0x50ccb83e,0x9ea9cbf7),LL(0xb73afec5,0x8a699ab5),LL(0x0382ff44,0x682b0e1c),L_(0x000001a1), LL(0xd2f8a7c3,0xa48bc771),LL(0x219fed54,0x20bed549),LL(0xd7a8f53a,0x9f897a30),LL(0xccad31ab,0xf4ab61be),LL(0xe4253812,0xd02eb63b),LL(0x02c0bd98,0xf369795f),LL(0x940fa395,0x6661d80d),LL(0x4fc30a92,0xdb54dfb5),L_(0x00000052), + LL(0xa8b475dc,0x7f4fad25),LL(0x917eadce,0x33c5c41f),LL(0xfac932b3,0x8175e0ba),LL(0x0c6ce437,0xd6df4caa),LL(0x628f6bd2,0xd8cef71f),LL(0xbbd0808b,0x1bf4e3d8),LL(0x82a3b927,0xf2573f56),LL(0x18b7f7d3,0x20a5d5d4),L_(0x0000013b), LL(0x23ee963f,0x6296df1a),LL(0x511300a6,0x48f698fe),LL(0x0a451118,0xe69d9b6b),LL(0xbda90f27,0x6b99560f),LL(0x00ad6b22,0x576639a4),LL(0x70498a28,0xe3fb0685),LL(0x766cc9eb,0x910ed9d6),LL(0xa13d4e5f,0x45079f4a),L_(0x0000016f), + LL(0xfcc87b80,0xb3a0df18),LL(0xcdee46b0,0x0f7b0b8f),LL(0x0dee6d65,0xdc8df7a6),LL(0xca19127a,0x6d034f50),LL(0xd6d74c77,0xcd8b7301),LL(0xd01a93fc,0x7b8e12a8),LL(0x77799926,0xc0b3bdfe),LL(0x157d532e,0x5444b9cf),L_(0x000000d1), LL(0xe1636c3d,0x2776ac60),LL(0xbab425f8,0x947e525b),LL(0x66085567,0x6d095956),LL(0xbcb7adb8,0x4d3075ac),LL(0x99a0d6ce,0xc684b9ba),LL(0x0e134c5c,0x4c65fec0),LL(0x30477674,0x5db48af9),LL(0xf3744581,0xfcc9963e),L_(0x0000004c), + LL(0x3d53729d,0xb51e39da),LL(0x258dcf68,0x1c50cc68),LL(0xb1289a02,0x54112229),LL(0x48928ef6,0xc73b83c7),LL(0xf0df33f4,0x6a0ebdbd),LL(0x5f166393,0x09883324),LL(0xbdfac3bf,0x21bceec6),LL(0x871bcc9c,0x64a15de9),L_(0x000001cb), LL(0xcba002c5,0x7efb2f27),LL(0xce8d66f9,0x6a48e2f0),LL(0xc4f49e10,0x0d05177f),LL(0x04e720d6,0x9e354273),LL(0x746f841b,0xe08c355b),LL(0x7b7b7cd5,0x81226157),LL(0x586eb9a8,0x38ce3838),LL(0x8c03b21c,0x02872c5a),L_(0x000000ec), +}, +/* digit=46 base_pwr=2^230 */ +{ + LL(0x7f032bde,0x8a4b6723),LL(0xa08c6852,0x79a5b3fd),LL(0xc7195714,0xd8054fed),LL(0x7c611c75,0x503c3580),LL(0xe88e5dbf,0xb37b9ea9),LL(0x2b4c4521,0x75f1c942),LL(0x950eb17e,0x79508472),LL(0x238eca42,0x845c91f9),L_(0x0000000f), LL(0xa8c10103,0xa0c1e80e),LL(0x978ae396,0x14b242e1),LL(0x2c0d00f9,0xb47bf7bf),LL(0xe944e43f,0xb416e50a),LL(0x906c3634,0xe7c8d114),LL(0x347f03a3,0x65b00ad0),LL(0xa6eba251,0x53a14e26),LL(0xf521e9dc,0x11eb83f4),L_(0x00000169), + LL(0x9d3bde43,0xcf0b0ab2),LL(0x1ea0d8e5,0x30d499c7),LL(0x4b6204df,0x8f748b9e),LL(0xc4dd3f54,0xba95c754),LL(0xc443876e,0xd7ad6cc9),LL(0x08e10896,0x544e9e2d),LL(0xa9428b4a,0x1a2d3e1e),LL(0xb6fe7189,0x05c7660e),L_(0x000000b9), LL(0x41251790,0xb366e641),LL(0x77106f8f,0x42b36e28),LL(0x2d9d82f5,0x63743c2e),LL(0xaf2b4eca,0xc887146a),LL(0xb28d08cf,0x4ed669e0),LL(0xc7391371,0xda28c885),LL(0x14ee1f56,0x84424da9),LL(0x42d4479d,0x33646227),L_(0x0000015e), + LL(0x23998889,0x12e89265),LL(0x1eeb47d8,0xcbb7e582),LL(0x5b702942,0x0f041cf4),LL(0x64d44f59,0x50d39295),LL(0x5d20f47c,0x0a8b51ba),LL(0x15a076aa,0x79ae768a),LL(0xa2141ba3,0xcf638bb5),LL(0xe3c47d36,0x582394d5),L_(0x0000019a), LL(0x1e394199,0xde6f722f),LL(0x7bcb9faa,0xc544456b),LL(0x7edbbe33,0xc58f127c),LL(0x178e1289,0xcd6856a6),LL(0x29c72942,0x7d0ce889),LL(0xdca59772,0x951589f5),LL(0x6908ef3f,0x4f00ce63),LL(0x110a84b5,0xc1a89443),L_(0x00000018), + LL(0xedea6906,0x1fbd25b5),LL(0xc3abc5bd,0xa3138347),LL(0x78a11d29,0xf2283223),LL(0xadac6d62,0x4af4ece3),LL(0x72b0dc7b,0xf1c75e43),LL(0xa7308e28,0x99139560),LL(0x0ea7127d,0x9cb3c31d),LL(0xee0172da,0xc69386a7),L_(0x00000036), LL(0xcae0b566,0x293be2a2),LL(0x82933139,0xaf8d3077),LL(0x41cdee07,0x4118b415),LL(0xd6d0895f,0xb3a9502a),LL(0x242767b9,0x404e1d44),LL(0x3924f383,0xe7a91a84),LL(0x3c5c40dc,0x0f30db5a),LL(0x2d443e9e,0x38df60b6),L_(0x00000053), + LL(0x06beb164,0x57eacd01),LL(0x8b237781,0x47bc0a58),LL(0x21bf6b08,0x72f947bb),LL(0x5c6b0c6d,0x0c58bea7),LL(0xc78326d2,0x8a6feb8c),LL(0xf3157ca1,0xe147ad97),LL(0x4be255e4,0xa6917b35),LL(0x7006cd50,0x1ceacc56),L_(0x000000eb), LL(0xce77913f,0xc4957a8d),LL(0x5e969282,0x3e3eb59d),LL(0x1216fdc0,0x2f2b0b06),LL(0x51a13162,0x5b88e211),LL(0xff4a6d02,0x6b68e6ae),LL(0xc7c80a3f,0xa7fca940),LL(0x2128145a,0x3a205f85),LL(0x459b75e6,0x48874b7e),L_(0x00000189), + LL(0xb951af1f,0xf1c2d135),LL(0x363e7de4,0xede249f0),LL(0x2374169d,0x92b91c52),LL(0x34ca05e7,0x42f9c460),LL(0xe96d13d2,0xb8dc141b),LL(0x9c04a0eb,0x11349888),LL(0x86f45f6f,0xa3c9d21f),LL(0x34d9dd7d,0x6359abc3),L_(0x000000ae), LL(0xd4c46ca9,0x906d8bdb),LL(0x82617ad1,0x5f4fb81e),LL(0xd70d26c6,0x68367c91),LL(0xe835f648,0x4d712331),LL(0x5dda13b7,0x06ca4385),LL(0x97f662ae,0xcbeb485a),LL(0x211b18b3,0xfe5f6ad4),LL(0x178f31f1,0xbfc76ef2),L_(0x000001e4), + LL(0x1da9f06e,0xab40e045),LL(0xcdbdf2d4,0xbc7f59a3),LL(0x25655817,0x7d6adfae),LL(0x5b05af23,0x3b9e8819),LL(0x1f7f265d,0x4d41011d),LL(0xa02a10b1,0xc4403b75),LL(0x4598d47a,0x21678b80),LL(0x72bcfd2d,0x0a91ddc2),L_(0x0000001a), LL(0x8f87df0f,0x5f9a8c36),LL(0x38d6c310,0x22226823),LL(0x4b065228,0xdf4b4ac7),LL(0x99e6867b,0x1562f4fb),LL(0xc9c2e12f,0xe5bf9e6b),LL(0xef6dd2fe,0xa02f573e),LL(0x99a366b2,0xf15b202c),LL(0x46de40b9,0x8fa6fe0d),L_(0x00000076), + LL(0x070b39a4,0x95d88264),LL(0x5a265bdb,0x771ed60f),LL(0x717063ef,0x0dd813de),LL(0xd974ca00,0x4d348196),LL(0x9d26915a,0x3def1612),LL(0xfcdfb352,0x1ecabcbb),LL(0x7290d698,0x44e08c75),LL(0x5c0c5d24,0x65a063c6),L_(0x0000011c), LL(0xc9b7cd37,0x751941d0),LL(0xa5845e0e,0x90c04cc0),LL(0xc51c09cc,0xf11f3a2b),LL(0x536ce8af,0x3944ca09),LL(0xd614a230,0xe5cb9d10),LL(0x4cf73a00,0x11f36267),LL(0x39b52629,0xe681d436),LL(0x27379f49,0x7634bb09),L_(0x000000a0), + LL(0x83402336,0x3b3162c4),LL(0xf5ba50b2,0x27a53ca3),LL(0x5b2f88a0,0x4d9f7313),LL(0xff015375,0x4100d075),LL(0xefc66c49,0xaa939a6b),LL(0x25334ce7,0x4d836d2e),LL(0x0ff09c49,0x9aa3f59b),LL(0xce13f150,0x6bd297a9),L_(0x000001e2), LL(0x138230ce,0x3c8984bd),LL(0x8be1ce28,0x7a30734a),LL(0x83fbedb8,0x56e66999),LL(0xc37e9e22,0xeb69a4db),LL(0x8b3de542,0x15192947),LL(0x4a7280d3,0x67515315),LL(0x5c05b359,0x0b9a8604),LL(0x5ec92a80,0x973deb80),L_(0x00000068), + LL(0xa6ca6db6,0x1256d99a),LL(0xa13ac401,0x9e017800),LL(0xed3810cb,0x84b7702c),LL(0xb6d9eff1,0xcdc98f94),LL(0xf4a42e06,0xa3cf6c58),LL(0x658f00c3,0x17b79fe0),LL(0x4db4bd0a,0xc0cd6ebd),LL(0x79f4a662,0xb6716eec),L_(0x00000069), LL(0x3c927a1c,0x6f9c5845),LL(0x5d9256ec,0x540f768a),LL(0xe910b5c3,0x4e7e7b8d),LL(0x3c907d51,0xf387c3d5),LL(0xeecfe723,0x213d5d27),LL(0xd78500a0,0xaa244815),LL(0xb117a5b8,0x7049f488),LL(0xfb72f9ed,0x3651c83c),L_(0x000000bb), + LL(0x33e7dea5,0xed918816),LL(0x14555dbb,0x178d8d22),LL(0x4a72d14b,0x1ebffe3d),LL(0xa3a172eb,0x476c82fd),LL(0x4c45f724,0x700c837a),LL(0xd80825d0,0x16888e37),LL(0x104ac32f,0xfaf93105),LL(0xed3ecf8b,0x503fb78e),L_(0x000001b3), LL(0x030d3211,0x3c014136),LL(0x4a1d6c14,0x3ae0a56f),LL(0xa38d42d7,0x765e846a),LL(0xdc241d4a,0x087fcd52),LL(0x0a7a4e2e,0xf088c4c3),LL(0x81043b53,0x0b74dc81),LL(0x030c4d6d,0xf465c63a),LL(0xb63f1e30,0xa7aa0a71),L_(0x0000018f), + LL(0x77408152,0xe2aea3b4),LL(0x22e76e20,0x6eca1ede),LL(0x7e03afde,0x08d1c44e),LL(0x4edf70d6,0x88d58544),LL(0xd8ec390b,0x474d298c),LL(0xc4c3f675,0x9ce21146),LL(0x3274110e,0xb12ae7e7),LL(0xce9cf1f4,0x67e9f4b4),L_(0x000000fa), LL(0x8bf7948c,0x102ef931),LL(0x3efdaff6,0x7a8b94cb),LL(0x59bd3104,0x4b8b1235),LL(0x25afad7c,0x24884827),LL(0xdd939da0,0x43b462ba),LL(0x45cb99ab,0x6a4b9f89),LL(0x0f6b65c6,0xbddb4b1c),LL(0x39e97dd0,0x5a1f7976),L_(0x000001d7), + LL(0x4ee368e9,0xcf01fbe1),LL(0xc5bd929e,0x47c26018),LL(0x2bbeb492,0x050e6a5c),LL(0x04741b6f,0x0f665d42),LL(0x4c0e1ab0,0x15137e0c),LL(0x3ee524ae,0x88980ffb),LL(0x86e225d0,0xa5de3190),LL(0xde9d18c0,0xe6bcf986),L_(0x000000db), LL(0xe5ef1407,0xc1e09545),LL(0xa8ab4958,0x7b416dfc),LL(0x05e9411d,0xb5a5de50),LL(0x916238cc,0x7da6c853),LL(0x0e933ce2,0xcff26d33),LL(0x7fab03f6,0xc2410d1b),LL(0x70a12092,0x130ded07),LL(0xa7ff89e1,0xf34872a0),L_(0x000000ea), + LL(0x7391f663,0x6107960e),LL(0x08dca3fc,0x9f978b8d),LL(0x2367f8bf,0x41ab4ac8),LL(0xbfb304bc,0xc14127da),LL(0xb2161643,0x89ee83de),LL(0x91433f74,0x76ad8bee),LL(0x3abcb595,0xa74d6d8b),LL(0xa8b1935f,0x314e698a),L_(0x0000001e), LL(0xee0dcf96,0xbd5f1508),LL(0x1fda31cb,0x4401991d),LL(0x67b33d1f,0x5dcaee66),LL(0x80ef50d3,0x58f1d026),LL(0xc6160acf,0x00a13e57),LL(0x3be539f3,0x88dd96e9),LL(0xa5a0a5ae,0x97419f0c),LL(0xcf6a8f10,0x44b2ca4c),L_(0x00000018), + LL(0x02cd85a8,0x5c77a891),LL(0x745da1cc,0xa4b913df),LL(0xa1006271,0xec1779e4),LL(0xb3fe3fca,0xcceebf8a),LL(0x7b0d3f86,0x82fd16d4),LL(0xeb20fdbf,0x4e29270b),LL(0x450edccc,0xa783c064),LL(0x2c637dd3,0x7337d5ce),L_(0x000000ee), LL(0x94d66859,0x819b276f),LL(0x71e05cf6,0x45bd1439),LL(0x748c488f,0x280a8add),LL(0xbb099ca8,0xe8e6e69d),LL(0x19429d88,0x4f4c80b6),LL(0x2d2698e8,0x0e4ab44b),LL(0x1eb3fc49,0xcd46fe76),LL(0x02d1a2ca,0x15543eb8),L_(0x00000116), + LL(0xa9d0f944,0x700ec0ac),LL(0x13ee9845,0xe55b42fb),LL(0xe5ad047b,0x45bc6993),LL(0xe8f73a08,0xee41f2ae),LL(0x1ac680ff,0xd3c83204),LL(0x740b12fc,0x5e36bb4a),LL(0x21ebc164,0x35a45c95),LL(0xb8dfcc77,0x92b0fbda),L_(0x000000ef), LL(0xe45e0eb2,0xb5805ed4),LL(0x829d754d,0x6c810584),LL(0x36cc488a,0xc9632468),LL(0x39f60f1e,0xf2ebc30d),LL(0x390502c0,0xde960758),LL(0x6d1feec9,0x63adf462),LL(0xf944bca3,0xdeea2824),LL(0x9c375dbf,0xa887d095),L_(0x0000010b), +}, +/* digit=47 base_pwr=2^235 */ +{ + LL(0xe3366deb,0x2fcf8b0a),LL(0x07415442,0xe5dadc06),LL(0x07a17d21,0xc237ee85),LL(0x83c01e78,0x08f5fd21),LL(0xada49ad1,0x998eec2d),LL(0x3e35f765,0x5a121c30),LL(0x1f207544,0xf5fdddb9),LL(0x537426d8,0x1dd7a92c),L_(0x000000af), LL(0xf6589369,0x9ac31da2),LL(0x22850494,0xd3189e72),LL(0x7646877e,0xe04fe426),LL(0xee0cbac9,0xf8802494),LL(0xd9fdf793,0xa975ea85),LL(0x0c9c6045,0x18cf38fb),LL(0x02b88cb1,0xa12c8778),LL(0x9757e39e,0x8e571e06),L_(0x00000054), + LL(0xd9933844,0xd91f89ee),LL(0xd77e7f7e,0x2cf0f860),LL(0xe9a24986,0x705ade19),LL(0xa4b26963,0x0f929eaf),LL(0xf6f18b5d,0x1a12f7ee),LL(0x0ff1861d,0x4ef59d59),LL(0x6b67d295,0x18bcbd0d),LL(0x70540dd4,0x83b51e51),L_(0x0000016e), LL(0x6f33ef54,0x0b0a67de),LL(0x090cb0d5,0x89c8fd0f),LL(0xb8b3eeba,0x289c0d96),LL(0xa8a26dc5,0xe6dd7431),LL(0xafde18e0,0xf0a660c8),LL(0x2cc76374,0x397bcfa0),LL(0x7654494d,0xd958a15b),LL(0x24476b8f,0x53a314e3),L_(0x0000017d), + LL(0x9d90faa8,0x74ca8553),LL(0x099db6d0,0x79fa68c5),LL(0x4c5dd75b,0x75880817),LL(0xccf37a0a,0x92dc167c),LL(0xf900a103,0xc92d1684),LL(0x8386aa09,0xfba8f79b),LL(0x53d25b65,0xb1822202),LL(0x183fbc1b,0xfccc5a8e),L_(0x000000ce), LL(0xa07c1dfc,0xf2f85858),LL(0x4925f513,0x1b5dd268),LL(0x3efe01ed,0x65fdd3e5),LL(0x47d317de,0x4621cca2),LL(0xdf49fdd8,0x60e7bc31),LL(0x66f9ab90,0xe320caa6),LL(0x2ca76c6f,0x41361bf3),LL(0x602d539d,0x267e9ebe),L_(0x000000f0), + LL(0x3938d7d9,0x925d2d91),LL(0xd471ad5a,0xe6ad36d9),LL(0x18a88bdc,0x599734aa),LL(0xb20b90be,0xaa6c0fb7),LL(0x33c88799,0xceda14b2),LL(0x7dad41f1,0x3bb924ee),LL(0xb7c643d1,0xa63db6fc),LL(0xcfe7d84e,0x46de4666),L_(0x000001a8), LL(0x81e8c45b,0xebe6128e),LL(0x4a9235f4,0x780d1146),LL(0x2db34ea2,0xb3ecdbc0),LL(0x31fad3e8,0xcdbe1207),LL(0x7ab5ebf8,0xdf431809),LL(0xbf1d4990,0x0f8e79eb),LL(0xe93c1583,0xfba03ee7),LL(0xefc40a1c,0xf76de664),L_(0x0000008d), + LL(0xb488c3a9,0xa3f4bcf5),LL(0xf02dfbba,0xf379ed8d),LL(0x7857a0d6,0x6c580cb5),LL(0x7b4a59a6,0x6d6738fc),LL(0x1654de01,0x7c102c44),LL(0x8d6ededc,0xb8a37f11),LL(0xe92baa08,0x6ecce15f),LL(0x1b1b1c96,0xf542a7b0),L_(0x000000af), LL(0x8b1ba942,0xcf9be3be),LL(0x02fd3092,0x22a60f7a),LL(0xd4c8209a,0xdeeb8950),LL(0x8636e6d7,0x29511c76),LL(0x09037c4f,0x419f1652),LL(0x4196d645,0x935dc02e),LL(0xeaef1b05,0xcec8a6ec),LL(0x2f5c9bf8,0xb432cd40),L_(0x000001bc), + LL(0x458a4ebb,0x7f267eeb),LL(0x2a1279f1,0xf11c0e49),LL(0xc76f729a,0x92b8f2a3),LL(0x5437339e,0xe00c8ca3),LL(0x41f96b14,0x1dbcc016),LL(0x449dde57,0x5fa3755e),LL(0x0a0df11e,0x42dc646a),LL(0x5d317707,0x3610d1c6),L_(0x000000f5), LL(0x553c4383,0x76e5b808),LL(0xc99fe831,0x61f75499),LL(0x19eef1a0,0xd4c21a60),LL(0xcc67deb8,0x192fdd7e),LL(0xec37ce33,0x13250ef2),LL(0xf6ed9344,0xac4baff8),LL(0x8d1e9777,0x0d67d5c5),LL(0x7183407f,0xd1b52871),L_(0x0000019f), + LL(0x078b4225,0x64430a84),LL(0x5637bc1f,0xc9bb1131),LL(0x102f522c,0x38d318b3),LL(0xb1dfff39,0x0967edf8),LL(0xc54708cf,0xff7bf052),LL(0xb7dea363,0x5d9deef1),LL(0x44846b8a,0x5e3fdc0e),LL(0x2ccf785a,0xdf1138dc),L_(0x0000010a), LL(0xe715aa67,0x3b1beaf4),LL(0x5076af3c,0xac3bbbf4),LL(0xdda27ca5,0xdc76f92a),LL(0x7c5f4d64,0x67fb8aff),LL(0x98258450,0xfa7eea13),LL(0x183f4c0d,0xc38dcddf),LL(0xc7ca9f82,0x0789054d),LL(0xa0ad28e2,0xf484ac51),L_(0x00000118), + LL(0xb9c90b3e,0x0d9d6152),LL(0x28f43810,0x4ecd5aff),LL(0x0a2146e6,0x7e0c0df1),LL(0x0d19ad5b,0x6775181b),LL(0x151d7c3f,0x43c7a1b8),LL(0x38a3ef9f,0x2dd235c3),LL(0x1fdd8171,0x1f2597ee),LL(0x4734726a,0x083971de),L_(0x000000b3), LL(0x0d9bef58,0xfac04120),LL(0x85ff590d,0x952b767c),LL(0x8b72aaea,0x843ae9c1),LL(0x004265e7,0x307d7542),LL(0x395a8932,0xc2dea503),LL(0xc7f73a8f,0x3399e1ee),LL(0xb86c7eb5,0x2926b2c4),LL(0x0d21cf86,0x47a4f082),L_(0x00000193), + LL(0x41c76045,0x685e8e4b),LL(0xd88c27c3,0x0240c0b1),LL(0xeaa149a2,0x79b4d2d7),LL(0x18bd3d71,0x368319a1),LL(0xdb5d6ca6,0x44a8c42f),LL(0x587ba79d,0x77c41337),LL(0xdb57f6f2,0xea1f7c4f),LL(0x8ae39899,0x77750728),L_(0x00000085), LL(0xc0c436b8,0x22355d19),LL(0xa2946cf3,0x598a6616),LL(0x4d6a2c7a,0x4bb8cec6),LL(0xfe918a85,0x94e93f01),LL(0x833d8970,0x64d5ba4a),LL(0xa972b798,0x05a95b5c),LL(0x636ab756,0xca11412a),LL(0x2b50cab7,0xeca1dc55),L_(0x00000097), + LL(0x4cd7297b,0xcb4f7b38),LL(0x1a4787e2,0xea069acc),LL(0xa5590739,0xa99d3f7a),LL(0x601be73f,0xcf6cca23),LL(0xaa83e6e7,0x3960cc53),LL(0x5920b117,0x20e0b86b),LL(0xa7ac9dbe,0x6b3ef99f),LL(0xf468bb6f,0x60ac6c56),L_(0x00000040), LL(0x9f97eeb6,0xdc626c18),LL(0xb7dd82a1,0x008f892e),LL(0x142f8425,0x705cbf37),LL(0x01a4b241,0x4c8483d1),LL(0x275951c0,0x82075cfd),LL(0xa7dae45a,0xa9d9f282),LL(0x63c98e81,0x30bf2902),LL(0xefc331b1,0xc5f55add),L_(0x00000095), + LL(0x0bea3751,0x4a6e860f),LL(0xaa1272c0,0x85afdbd7),LL(0x53123c17,0x796e466f),LL(0x327374bf,0x19701fb1),LL(0x8c2b076b,0x755659d8),LL(0x8fee24c8,0xc6001497),LL(0x45d95463,0x144b9a21),LL(0x98a62be8,0x9e1d51ac),L_(0x000000e1), LL(0xfa89441a,0xff126e8b),LL(0x87dd796d,0x5e933815),LL(0xad6f752f,0x0f756584),LL(0xa0d6329c,0xc8afd335),LL(0xef95a2f8,0xa429ff1c),LL(0xe9d51af6,0x06c04336),LL(0xbb9ac481,0x0e389129),LL(0x80d2d2dd,0xb75b239e),L_(0x000000d2), + LL(0x36e3c242,0x04ac9a1c),LL(0x9fb461cd,0x2abd08e0),LL(0x7bca251b,0xfa6e8384),LL(0xf5d98ad8,0x7e953f04),LL(0xca3dcc08,0xfd9f6c57),LL(0x679c5992,0xfac8f179),LL(0xc9cf93cd,0x0e29622c),LL(0x050d1a32,0x703c650a),L_(0x00000180), LL(0xd397fdc1,0xc1188e58),LL(0x60a160b5,0x6d729218),LL(0xbe9a3f42,0x311911d3),LL(0x864f8747,0x8a79eb1a),LL(0xe2ff5eb7,0x66b881de),LL(0xef83107b,0x8784fc87),LL(0xd139997a,0xd894e5ee),LL(0x9a80e84f,0x1a2f4197),L_(0x000001aa), + LL(0x82c0cc02,0x6619c168),LL(0xbefe84df,0x7fe74db9),LL(0x7efd2da4,0xc983adbf),LL(0x0bbc28a9,0x6535bd9b),LL(0x169b3680,0xcb39ad32),LL(0xd2112121,0x3f60a9f2),LL(0xa91386ce,0x3a1b138f),LL(0xb1ef230d,0x36ea6d68),L_(0x0000003e), LL(0x9f4b61ea,0x1ef3660b),LL(0x58bee126,0x3a1e13eb),LL(0x84fe2098,0x1044e049),LL(0xd3d31ea9,0x6e975e84),LL(0xbdc58274,0xcbeca3ca),LL(0x4c27aa9f,0xe9036bd4),LL(0xcc717651,0x982f94af),LL(0x20d99920,0x0268a0da),L_(0x000000be), + LL(0x60bd53c9,0x8e317075),LL(0x01712fc5,0x00607c95),LL(0x10e30ced,0x77b023a2),LL(0x53b465e6,0x620a31c6),LL(0xb10af467,0xa8ea62e5),LL(0x48d08ca5,0x31ddd990),LL(0x65af8778,0x5be8899d),LL(0x2b29f5ab,0x21d38a08),L_(0x00000083), LL(0x78c6e380,0xd56bb423),LL(0xba4bc4d5,0x28b7afb8),LL(0xa4ef2e4b,0xc314822c),LL(0xae9b41f7,0x882d9a51),LL(0xf2b327a2,0x1e6c2280),LL(0x7ce965ab,0xa49d1969),LL(0x5708dae4,0xea346d97),LL(0xcff1175e,0x572d2fbc),L_(0x000000e9), + LL(0x6ad30fb7,0x971c75d0),LL(0x3dd39efc,0x11aab543),LL(0xe47dc537,0xf6290b96),LL(0x38ce4cde,0xe7a164cd),LL(0xd9dcb339,0xebee41ba),LL(0xbc0e8d41,0x18ca0dd5),LL(0xd2a8a073,0x92054e4f),LL(0x366d13cf,0x188fdcbb),L_(0x000001e4), LL(0xa68c541a,0x587afc9e),LL(0xf03b4067,0x4ac1fdd7),LL(0x43baf1b7,0x900c0863),LL(0x35bd9902,0xe71367f8),LL(0x3f6d6815,0xfd613341),LL(0xc12cdb6c,0xa8569f79),LL(0x6e58f3c3,0xd9ca8493),LL(0xd420b011,0x6d1ebe67),L_(0x00000179), + LL(0x98392473,0xbd7d4bad),LL(0x4af0bab5,0xade61274),LL(0xcd1e04b0,0xe21c3a53),LL(0x4ec80a7f,0x4b987124),LL(0x28f48386,0x23f6fd14),LL(0x63b180bf,0xe2b4889d),LL(0xacf748b0,0x2996dea6),LL(0xf3a06107,0x7cdec9d5),L_(0x00000060), LL(0x242fc0a6,0xc2a9858e),LL(0x2d38ce4f,0xc709b1fa),LL(0x87521e69,0xf5996fd9),LL(0x4d05bae8,0x131ac99f),LL(0xc3bad75e,0x62578fe3),LL(0xc9d13920,0x3ada2279),LL(0xb6fbac90,0x696da364),LL(0x6c292885,0xd02ce135),L_(0x000001db), +}, +/* digit=48 base_pwr=2^240 */ +{ + LL(0xee1b4c29,0x3d1074e0),LL(0xff10eeb7,0xe087c1a0),LL(0xc77549f2,0x5e2e0837),LL(0x74d6808a,0x48c7156c),LL(0x11f82ce9,0xbc13bf7c),LL(0x72ee287e,0x06f6a514),LL(0x28c4e6f9,0x165038cb),LL(0x320fef0b,0xb6f1c9d9),L_(0x000000d8), LL(0x2cf5a19d,0x57d310ce),LL(0xadd6b6df,0xcd825c08),LL(0xdcd4cb28,0x48bebf85),LL(0x644e1cbe,0xf1d5aa6a),LL(0xbebbd351,0x908ba85c),LL(0x4d8a2aa1,0x518b1bc8),LL(0x343d2d77,0x29b988ed),LL(0x7ea90982,0x940fc8d0),L_(0x0000009f), + LL(0x73a5d8ba,0x8f96ebc1),LL(0x54a67c95,0x984cd0ed),LL(0xef67809a,0x8dd8453d),LL(0xde0abb72,0x4fe5f363),LL(0x4b73609f,0x8e4fc461),LL(0xaab1b83c,0xb989fee4),LL(0x06d2158c,0xfe56f7d6),LL(0x52096597,0x70734a0c),L_(0x00000172), LL(0xa18dccda,0x094ef503),LL(0x32b2f44d,0xebd6d9b7),LL(0x2c29898d,0xe0ef3ff7),LL(0xe5d5ffd4,0x30b99ae2),LL(0xe1c94a38,0x2dd5fca5),LL(0x15b084de,0x6d08e970),LL(0xe94504be,0x90fe0fe0),LL(0xdb79eaed,0xafa2897d),L_(0x0000011e), + LL(0xee4255c9,0x45dd470c),LL(0x907208e4,0x551b38ea),LL(0x1157ba3e,0x1b72b693),LL(0xcf9f94c5,0x83c616c9),LL(0xaf1c59b1,0x2fe84fca),LL(0x7ed67f1d,0xf1bd77c9),LL(0x1d1e1a09,0x51550daa),LL(0xbac2f477,0x58d345e7),L_(0x0000018d), LL(0x854d3f83,0xa5d95b5f),LL(0xa404c99b,0x29f414da),LL(0x5a1bac7d,0x81c9d673),LL(0x56fda469,0x2c1bc499),LL(0x66bdcd65,0xfe505f2a),LL(0x9783eab5,0x92378106),LL(0x6f9996ab,0xa7330e63),LL(0xa6238170,0xfa70e33d),L_(0x00000070), + LL(0x386cf1e1,0xfee86a58),LL(0xf15be04b,0x32b87572),LL(0xe35f663e,0x94b48632),LL(0x165f5c52,0x62fb4267),LL(0x7d3b9413,0x407dadeb),LL(0x189d86c3,0x5689012e),LL(0x63e5f780,0x61c7907d),LL(0xa2b7e335,0xc0dc085f),L_(0x000001c0), LL(0xb4f6916e,0xa9cbe4f2),LL(0x0cfb081d,0x5ac2d2f3),LL(0x11fe0a52,0x32662679),LL(0x8fcbbd46,0x3e344c2d),LL(0xb1ff4122,0xa0a08757),LL(0xa48229e9,0x6f7101c0),LL(0x56b8c92c,0x4af0e804),LL(0xbb9a086c,0xc21360d8),L_(0x00000174), + LL(0x64d30caf,0x5a00ce71),LL(0xb34ef3a4,0xac5c1fed),LL(0x800620f8,0xba6237c0),LL(0x97dc7c79,0xff56f449),LL(0x5563d588,0xe8ab9474),LL(0xb2b00a9a,0xb8d1df21),LL(0x6a286295,0x4cf9b378),LL(0x00426dbb,0x30b70043),L_(0x000000c8), LL(0xf792db10,0x1fa97f98),LL(0x5a4e4b25,0xd3a62f9d),LL(0x61b4d385,0xad987701),LL(0xb90b4cda,0x41727a73),LL(0x84f90823,0xec4abf7e),LL(0xd814c4a3,0xed3df0de),LL(0xc453671b,0x0c8945f2),LL(0xdda88869,0x94087855),L_(0x0000019a), + LL(0x7fb07527,0x0ce5f28e),LL(0x705e5e78,0x3af745ca),LL(0x93ca952d,0x7351cb28),LL(0xfedeccdc,0xc12e9837),LL(0x7e7bfbbf,0xd14b9356),LL(0x47999f34,0xc6295462),LL(0x3f729887,0x5692b0da),LL(0xc96edd28,0x812e383c),L_(0x000001c9), LL(0xd72f1105,0xef1bc941),LL(0x70199860,0x493b99ba),LL(0x2d090c33,0x279e0c37),LL(0xbe1503ff,0x3fbe286b),LL(0x80f6465c,0x06d81c3e),LL(0x0a9257bf,0x2a448d3a),LL(0x402ee72a,0x6a5669fe),LL(0xe592b91c,0x5315497c),L_(0x000000d9), + LL(0xc0b3f5e5,0x93b397c9),LL(0x3318572b,0xa3327857),LL(0x0e667f17,0x7af5bff7),LL(0x2e60b913,0xfb65a96b),LL(0x9e25ef17,0x9188dfee),LL(0xdd117ab2,0x830a2c9e),LL(0x5472d03d,0x063aa4e1),LL(0xd8512ca1,0x9593f42b),L_(0x000000df), LL(0x5ba796ee,0xa143be47),LL(0xbbccf7b7,0x40a8123d),LL(0x80d4a4b1,0x8562ea6a),LL(0xe8424774,0x53e144c7),LL(0xa39d882f,0x49ac8b6f),LL(0xb451fe15,0xffe4b1ea),LL(0xc4538f34,0x0527aede),LL(0x1076cc29,0xbcd8efdc),L_(0x00000183), + LL(0xcdaef57e,0x670c5c5b),LL(0x046d9801,0xf7b5e720),LL(0x0601ff33,0xa07084cc),LL(0x900e6b0a,0x791af83b),LL(0xd2391e07,0x2dd856fd),LL(0x0430654d,0x63408d88),LL(0x82606889,0xc176e8bf),LL(0x2fa4b443,0x18c663e6),L_(0x0000004e), LL(0x41a598d0,0x48d8ae04),LL(0x950e8cec,0x11b8065c),LL(0x1316d53d,0x3a5ccc8c),LL(0xfeecd686,0xed41a668),LL(0xbb41648c,0xf76ba771),LL(0x9a4bb4b6,0xa9b2b49a),LL(0x370974d5,0xf9f130ae),LL(0x200485de,0x4c25f49d),L_(0x000001b8), + LL(0x92cea4ef,0x24ffe291),LL(0x23a38bed,0x41132058),LL(0x4bf85483,0xba359818),LL(0xbdd23ab5,0x3571fdd9),LL(0xd8f1fbf5,0x740422c0),LL(0x46b3d29b,0xdeca158b),LL(0xf7c74726,0x69a6765b),LL(0xe058b8b2,0x3a247a5b),L_(0x000001e5), LL(0x4e26d5da,0x49bfcbe2),LL(0x37b93476,0x3090fa48),LL(0x219565ef,0x30eb0e12),LL(0x996b7d11,0xe2ef23ae),LL(0x935017a2,0xfedd570a),LL(0x59810960,0x510b5963),LL(0xf4feef53,0x4eeb57ef),LL(0xa6aed7bc,0x500fc7dc),L_(0x00000023), + LL(0xd3c23c96,0x502210f9),LL(0x2f6be4ac,0x36ffcfaf),LL(0x97a1a521,0x874cac2d),LL(0xd4b6d8f6,0x4e03da3a),LL(0xebd4b9c9,0x058f53fa),LL(0x05bdde0c,0x54da0035),LL(0xea492dfd,0xf1d437ba),LL(0x083ae453,0x837cc36f),L_(0x00000173), LL(0x653383a8,0x7ab16b91),LL(0x08283456,0xe627feae),LL(0x5b031ea9,0x5ab7febf),LL(0xbc9c1a1e,0xdf744ce8),LL(0x0a851efb,0x944a28d0),LL(0x92d1258a,0xa2c52c0a),LL(0x8db3d01a,0x3272efed),LL(0xc3e55528,0xdd38ae95),L_(0x00000092), + LL(0x20da6312,0x6c8b9288),LL(0x201a8b72,0x55d5044c),LL(0xcd7dd04a,0x5fefdd8a),LL(0xf135da4f,0x326e5c4a),LL(0x93ab679e,0x0ebd3dab),LL(0x9e1c63de,0x3da9430d),LL(0xb6139a96,0x1c3e1a0b),LL(0x0bbe99d7,0x31ad9e61),L_(0x000000a5), LL(0xd0083331,0xd69aa80c),LL(0x312fa8a7,0x10699493),LL(0xb830105a,0x432ef74c),LL(0x427ed742,0x21457fc6),LL(0x32a8f306,0xed7ee077),LL(0xde91b340,0x7b2b2143),LL(0x97655415,0x2c36d1f0),LL(0x3e70f7df,0x8cb68be3),L_(0x00000162), + LL(0xb5a77e18,0x1c2c5d0a),LL(0xbdac0199,0xf48304d4),LL(0x58ea0344,0x7badcb3c),LL(0x61cc3620,0x7fa76693),LL(0xee100174,0xcbbd3041),LL(0xb845bb4b,0x2ab9fe8e),LL(0xbc927037,0x7e87d3ef),LL(0x7c6a4dcf,0x87fd392a),L_(0x0000011a), LL(0xd9fd8527,0xf99d4987),LL(0x3518a503,0x093c711b),LL(0x5ed52438,0x8de87657),LL(0x1283fea5,0xa57d89d4),LL(0x1d760642,0x37377224),LL(0xbf397e80,0x0c073eb0),LL(0x2d948da0,0x19066ff6),LL(0x02fb3665,0x6f15cfd1),L_(0x00000090), + LL(0x33168ab8,0x0703434d),LL(0x36c93ab6,0x08a36b13),LL(0x54182f0b,0x6018b27b),LL(0x1eb09d80,0x52b2eff5),LL(0x5cab8c14,0x54baf54d),LL(0x09c5f439,0x9128c26e),LL(0xa0c91a3e,0x3c462ce0),LL(0xc8a5d523,0x0dcb5998),L_(0x000000bd), LL(0x2a3d44a3,0x168afb3c),LL(0x28b7e59a,0x51e02e1e),LL(0x7db3beb7,0x95d9b53f),LL(0xd954033d,0x4280b408),LL(0xfca4117d,0xd87fffcb),LL(0xa8a2c41d,0xedfe3235),LL(0xa4e146b0,0xc9ab6206),LL(0x23f56e8a,0x6cc8df44),L_(0x000000c5), + LL(0x4d499b60,0xe30728ab),LL(0xeda148e9,0x09a1b090),LL(0xb3c8e802,0x4fed9972),LL(0x6feab8c2,0xbd0bf024),LL(0x684e8ba5,0xb6e56fc0),LL(0xc679d0b7,0x3a2827e6),LL(0x05aad3cf,0x9605e502),LL(0x154eec73,0xc7d72f2b),L_(0x000001e2), LL(0x4a30f9e9,0x04181bc3),LL(0x17c5f246,0x0c346607),LL(0xf9d4abe6,0x9d5267c4),LL(0x53390747,0x76bf72c0),LL(0xe2e74911,0xd4ea29a3),LL(0x25cb2342,0x5c9021dd),LL(0x7e8d6c56,0xac452ce1),LL(0x1fd1d0fd,0x7f5955ad),L_(0x000001df), + LL(0xd68445e9,0x7a984abf),LL(0x46f086dc,0xd299e678),LL(0x3ae95a65,0xb7f240f5),LL(0xadf74e6d,0xdd46db9e),LL(0xc95ae291,0x3dae88ec),LL(0xbc688dc9,0x4474ebcc),LL(0xe0bd1aae,0x3a30df47),LL(0xd32d0317,0x222e18e3),L_(0x00000054), LL(0x13d89ccf,0xda1caa7c),LL(0x3b9e4f98,0x584fa9c3),LL(0xe3bb36fe,0xa33fbb40),LL(0xece5a0db,0x990ebace),LL(0x2d1efc59,0x1c0c2167),LL(0x0ea367aa,0x18eb3285),LL(0xaa6c72bd,0x4a9d7d68),LL(0x69e3bcf6,0xcd396faf),L_(0x0000018f), + LL(0xdfb404ce,0x20f43bc2),LL(0x14169ebb,0x776ec8b3),LL(0x4d9ce016,0x40cc814f),LL(0x64db6f3c,0xde6701fd),LL(0xbc27b375,0x1be16687),LL(0x41b2641f,0xaaf1c8ca),LL(0x5c7ebdd8,0x667e429e),LL(0x9221918a,0x84d2d4cd),L_(0x00000193), LL(0x8bc8b351,0x65966739),LL(0x502a6f1f,0xe772626c),LL(0x612fc65a,0xd1717c45),LL(0x06b47588,0xcd0bd273),LL(0xfd9dbcb0,0xf7b68702),LL(0x5beaed3a,0x60d2a43a),LL(0xd9e3bfb5,0x618c6158),LL(0xeec14b9b,0x1dad1537),L_(0x00000042), +}, +/* digit=49 base_pwr=2^245 */ +{ + LL(0xbf8b6eac,0x7b9e7889),LL(0xe957ebe2,0x3ae1f292),LL(0x2bd715ca,0x6ae08fea),LL(0x3b2ea475,0xcab67aaf),LL(0xf247c9f5,0xd47caa37),LL(0x53af0925,0x409f1b89),LL(0x57e7bd1f,0x4ee5b8e5),LL(0x0b979eb1,0x0e289030),L_(0x000000bb), LL(0x1ea9467a,0x1d78d6b7),LL(0x3dfcb1d0,0x595db0c6),LL(0x8e6aaf05,0x9217ec90),LL(0x45106ff4,0xab12df36),LL(0x8489adb8,0xc4207aff),LL(0x257b835b,0xabbbb85d),LL(0x706e08a1,0x71ad10a3),LL(0x6d2a5b7d,0xe224792f),L_(0x0000016a), + LL(0x50fd71f2,0x8295b8b6),LL(0x65b39aaa,0x0690f149),LL(0x1270c951,0x763e6fce),LL(0xbafb3a9f,0x3f839143),LL(0x0dc990be,0x3866c189),LL(0xa0d6a0e7,0x087b74c8),LL(0xb520d476,0xd8910a14),LL(0xbd81006e,0x16e6fb91),L_(0x0000012b), LL(0x63f73546,0x9757756a),LL(0xbe4b13d0,0xc54fba1e),LL(0x3f1884ce,0x4519ff97),LL(0x68950392,0xfb9e4f42),LL(0x2d309b59,0xf2ce5e20),LL(0x004b85f0,0x35d898e0),LL(0x05c20b17,0xd4f54e0b),LL(0x34add1fb,0x178e2a7f),L_(0x000001cb), + LL(0x2d50f2ad,0x9fa52c89),LL(0x8fc48ea8,0x6a680dfd),LL(0x4b09bae8,0x78d67917),LL(0x7cea1e12,0x0f37ae3b),LL(0x8383d337,0x9f51107a),LL(0x157913dc,0xbbd05c8e),LL(0xc347e479,0xe7f7f024),LL(0xc27dfb63,0xa32c2410),L_(0x000000c4), LL(0x275b47a6,0xa0c5983d),LL(0xbc8a42a9,0x31f03f3e),LL(0xdb0533ac,0x07b4440f),LL(0x1b5cb9b7,0x522041e9),LL(0x18816d64,0xa0763672),LL(0x78c44489,0xa7d823be),LL(0x0289668f,0xa033e066),LL(0x14b7bda9,0x1bf9880e),L_(0x00000004), + LL(0xb8d3d78f,0x992b024d),LL(0xcc47fd44,0x301e6aa5),LL(0x4ca3c2ae,0xa239d460),LL(0xb59f6635,0x72a93968),LL(0x93da741e,0x6f3e7cb4),LL(0xe451c847,0x958457a0),LL(0x0539a4ae,0x0ccc6f49),LL(0x70df123a,0x4b36ee4a),L_(0x0000013e), LL(0xaec0226e,0xa5bf5964),LL(0xd54e934e,0xa4f9d8d0),LL(0x838881f3,0x5759057f),LL(0xd231904c,0xf74d21e3),LL(0x65fa2854,0x09110e09),LL(0x3e3fbb9d,0x73f82547),LL(0x66595687,0xc3213d46),LL(0x4ee05953,0xc6c9fbf7),L_(0x000001e0), + LL(0x978a2d88,0xf19f1768),LL(0xfbd4f466,0xccc78e3b),LL(0x4ab17eab,0xe0f582bd),LL(0x42edf70d,0x32c21454),LL(0xe1c56694,0x7f57c601),LL(0x01c830d3,0xe9eae160),LL(0xe56900b5,0xca26d56c),LL(0x36688674,0xb2fb4c7c),L_(0x0000007e), LL(0x369579ff,0x53c6182e),LL(0x47ff90cc,0xaaf18b16),LL(0x8fc84257,0x96b0582e),LL(0x9e3a6661,0x4532767f),LL(0x0d14fb71,0x29d6ef11),LL(0xdc2f950b,0x54eb6cc6),LL(0x85acbd0a,0x525b30dd),LL(0x5c05fb17,0x67dd5268),L_(0x00000175), + LL(0x66c24804,0xaabdb0b2),LL(0x1475f80e,0x6b7bb07c),LL(0xd90a1e1c,0x92ecf09d),LL(0xc193105d,0x5feeb4d3),LL(0x322cd2b8,0xd3b68b08),LL(0xb3acd3e0,0xb0ed276b),LL(0x50511672,0x512d83e9),LL(0x5830b5d3,0xda968b0a),L_(0x000001db), LL(0x1320700b,0xa9aed6cf),LL(0xadb30375,0xb42997c1),LL(0xc6687e52,0x1d88f275),LL(0x5c1d5e8e,0x5d9e895e),LL(0xdbf775d5,0x1f149b28),LL(0xc29aed12,0xe2724e7a),LL(0x220a70ba,0x7e781bbf),LL(0xcf9cd146,0xfb0950fc),L_(0x00000166), + LL(0x8275d24f,0x26492a48),LL(0x8f120fe7,0xb833386c),LL(0xbca86762,0x7d77fbcb),LL(0x2f67d175,0x5165ed7e),LL(0xf29932da,0x40520604),LL(0x607db461,0x88627d90),LL(0x74dd9734,0x9d6e8589),LL(0xff8795e0,0x0898a1bd),L_(0x00000157), LL(0xa3d097c4,0xf0c19be8),LL(0x3e449e91,0xc086fd4a),LL(0xce081f35,0x60f6bfc7),LL(0x6b980172,0xf116eb17),LL(0x438fccb9,0xb036eed0),LL(0x3b9d80a6,0x355bcf69),LL(0x17f28db4,0x1d897ded),LL(0x5b488d87,0xb2564e1a),L_(0x000000be), + LL(0x823eac8a,0x6223dd4a),LL(0x84db5faf,0x0b0f5e29),LL(0xd39d495d,0x0a14e52d),LL(0x723841ce,0x365ed8de),LL(0xb4ef0fcb,0xdbcb1fe9),LL(0x3aa7d5d2,0xb19047ee),LL(0x2d33c7e0,0xe2978f53),LL(0x2ad3b9dd,0x9dbc97d1),L_(0x00000132), LL(0x6c00ac28,0x02d16555),LL(0xb3172c7a,0x8804b57f),LL(0xbeeb32c4,0xad774958),LL(0x59e99dad,0x34b2bc96),LL(0x90ab3c79,0x33fd281f),LL(0xe477effe,0xfaa713ab),LL(0x78b329a3,0xf3df2353),LL(0xac36cbb9,0x62e824d0),L_(0x00000145), + LL(0x54e642eb,0xd8f323fb),LL(0x81a85944,0x3dd3e0be),LL(0x51a21fab,0xd871d4d4),LL(0xb561f31e,0xb4ce4cde),LL(0x4449b15f,0xce67b526),LL(0x64493f22,0x82ddd4ad),LL(0x546ec9b8,0x0adc07a9),LL(0x4dba63e9,0x82628c7e),L_(0x00000128), LL(0xe1f0172a,0x5e900de4),LL(0x358c4d59,0x8391c4fa),LL(0xd7be91ac,0x82f89ceb),LL(0xac49480b,0x0dcd6532),LL(0x48237726,0xd2dee6e8),LL(0xaeda17a0,0x13850532),LL(0x2d6729ba,0x201426a9),LL(0xf52c6ebc,0x188c6ec6),L_(0x000000ae), + LL(0xc2fccc93,0x9b37123b),LL(0x274b93dc,0x0d11cfe3),LL(0x01caef2f,0xbe8ef001),LL(0xef0d218a,0x2810cd03),LL(0xace6e761,0x5c17a13d),LL(0x65a61b64,0xcfaaba81),LL(0x669bf078,0xd429ba49),LL(0xd9a6abec,0x0f71e96f),L_(0x0000016c), LL(0xee363303,0x592f7894),LL(0xe42d0a9c,0xfcc98aed),LL(0x3730d520,0xbb02c8f7),LL(0xe10a8edd,0x4886062f),LL(0x57fa6238,0xdab28f83),LL(0x308d0fc8,0x13c4d161),LL(0x8db6b346,0xf5b7f11e),LL(0x70d7617e,0xd7fc6e4f),L_(0x000000b4), + LL(0x0e9d00ce,0xe3c773fc),LL(0x30cb34f5,0x854f6660),LL(0xd3093680,0x5abdfb30),LL(0x7939c865,0x3d739567),LL(0xa46ffe9f,0x3a7253f9),LL(0x8fd8f096,0x151f1baa),LL(0xa1443d09,0x9a29f4f0),LL(0xb2ed7af8,0x0ad8104e),L_(0x000001fe), LL(0x58f41327,0x76fc8041),LL(0x0868fcae,0xf81d0998),LL(0xdba2642e,0x7f6f6367),LL(0x57d4f243,0x6a189847),LL(0x92fa4eaf,0xc022a76b),LL(0x4e736ea2,0xdd251f4b),LL(0x06ebdd88,0x39b7f55b),LL(0xb9f83aec,0xf34e682b),L_(0x00000021), + LL(0xfb89a61a,0xba33a960),LL(0x502d83da,0x377dd454),LL(0x04a7d732,0x60c9b2c8),LL(0xfa223630,0xe06fc03b),LL(0x7e497e85,0x145bb405),LL(0x456567db,0x39898314),LL(0x2d3a76ad,0xeb33a535),LL(0xd36b4686,0xebbad130),L_(0x00000079), LL(0x519e8255,0x8a5778a7),LL(0x10340c30,0xf7b160b7),LL(0x1f4c9e0a,0x729201ef),LL(0x09fe7ed4,0xe28d29ca),LL(0x57eb2d3f,0x3e4bfbfc),LL(0xfe99fffb,0xe7397e68),LL(0x62215a66,0x18c1dc25),LL(0x16278a5c,0x1045ab03),L_(0x000000ca), + LL(0xd14c0d2f,0xb45b8788),LL(0xc3b9c902,0xe8e7e9b5),LL(0xe1deb5a2,0x6f0ccb02),LL(0xcc118df4,0x931e8bf3),LL(0x44d4d935,0x8d49c80c),LL(0xae880f5f,0x294917c6),LL(0xdaf4ba46,0xf7ee5bdb),LL(0xe09285b3,0x11c3f0c5),L_(0x000000fe), LL(0xff95a4d2,0x6f1e6d94),LL(0x150c77e6,0xc23026fa),LL(0x8e7cd3f5,0x567d2494),LL(0xfba4ae31,0x380b42d3),LL(0x7135a34e,0xdf2c5139),LL(0xf390e611,0xfd3ff544),LL(0x1f3b21ae,0x4254bcbc),LL(0x67fca024,0x68f4c9e3),L_(0x0000003b), + LL(0x1f4a16c0,0x68ed5662),LL(0x0fa1e08c,0x31f2c30a),LL(0xb65f32e1,0x2d06bb12),LL(0xfec7dae7,0x95c78209),LL(0xb2e0fbb5,0x7d228e9d),LL(0x84a73eeb,0x0a7cd176),LL(0x4968f085,0xb3a9c57a),LL(0xf1034b1b,0x12dc73c6),L_(0x0000001d), LL(0xc3858dc2,0xd74b5636),LL(0x90895a11,0x8864d82d),LL(0x8f322a4c,0x1db6f8b1),LL(0xef6cb619,0xdc8f7532),LL(0x95fe8c47,0x6bb6ba07),LL(0xb376849e,0x6839da29),LL(0x55ee699f,0x9e4c3d09),LL(0x013177ca,0x06ac03b0),L_(0x00000198), + LL(0x1730ff3d,0x68b8e4b1),LL(0x556e1c75,0xb2cfde0a),LL(0xbf8d1b12,0x77dcfbef),LL(0xbfb5199d,0x8803a28c),LL(0xb3b33660,0x9ab9ee66),LL(0xffcfec92,0x75479f96),LL(0x66780a53,0x9e3f38c0),LL(0xe21a1107,0x8d2c8147),L_(0x000001a1), LL(0xec7cd093,0xf14b8da9),LL(0xf175c60b,0xc9c58bd9),LL(0x94928d32,0xf4158167),LL(0xa1977e7b,0x3720a8c9),LL(0x50e84c76,0xb29acf00),LL(0xa73b8ebd,0xdf12fc49),LL(0x8d8a4296,0xf75a8ea8),LL(0x1abde921,0xaa9b61ff),L_(0x000001a6), + LL(0xeb196620,0xd278de5a),LL(0x458b071b,0x5b584d1f),LL(0x0313ed9b,0x5f476cd6),LL(0xc54ce5fe,0x007678c1),LL(0x6d145a77,0xe258964a),LL(0x0c62f8fe,0xfa68420c),LL(0x595f7056,0x63621f28),LL(0x2d891192,0x5d8cf9f8),L_(0x0000019c), LL(0xe6cb7a7c,0x130243d2),LL(0x8d5a87bb,0xbcf908d7),LL(0xc4e517b3,0xd0ef67bc),LL(0xba70f65d,0x30e5dd35),LL(0x41af2fd9,0xaeb9fb07),LL(0x448314ee,0xf71f75eb),LL(0x3702fdd3,0xbac48350),LL(0x1d2c0a91,0x1ebd11ec),L_(0x000000e9), +}, +/* digit=50 base_pwr=2^250 */ +{ + LL(0x8057734b,0xf4bf04df),LL(0x31cb2cfc,0x0c3adb10),LL(0x13e25b6e,0x3dd2ab40),LL(0xff8fa4cf,0x758e2edf),LL(0xfeffd307,0xf31ad907),LL(0x4baf111b,0xeba1b456),LL(0x3c4f6a12,0x13a81607),LL(0x94fad755,0xe7fc43bd),L_(0x0000014d), LL(0x593810b9,0xb8d44eee),LL(0x369ffff5,0x5334df1e),LL(0x64f19da6,0x5c2b9ceb),LL(0x01321d0f,0xc5ca3390),LL(0x02b87e91,0x45689acf),LL(0x3a49c8b5,0x049dbf7c),LL(0x93f7ed7c,0x8d277840),LL(0x73a0a1d5,0x726f20ba),L_(0x000001d7), + LL(0x57fe6e74,0xe3d95d4b),LL(0xe45eed99,0x8fe19237),LL(0xddc0cb97,0x7eb46e14),LL(0x4df73f68,0x57bdaf6e),LL(0x8670ac6f,0x847741a1),LL(0xa46fbe2b,0x02454925),LL(0x82f9632d,0xc15a10d2),LL(0xaf2e144f,0xc55aed10),L_(0x00000015), LL(0x59c9bac7,0xc44dce06),LL(0xa506cebb,0x03aaab25),LL(0x48b6559b,0x933863a2),LL(0xc348048a,0xd37a9de4),LL(0x26cd5e20,0xc20f4402),LL(0xee95db69,0xff1c74e9),LL(0x2f425e1e,0xd820bb88),LL(0x1933a6f8,0x6f95cad2),L_(0x000000f0), + LL(0x909d4b32,0x6d40379a),LL(0x87db0c0b,0x3e1edc80),LL(0x4c5fed50,0x8c80df24),LL(0x0d788315,0x5caf06ac),LL(0x12556a93,0x95b47183),LL(0x76d86da1,0xc5714cff),LL(0xcec43480,0xc2f30fbd),LL(0x4e4b2ab3,0xc0cb91c6),L_(0x000001b8), LL(0x122dfa3e,0xcbc11bf0),LL(0x75b252f6,0x87c8dce3),LL(0x501537b7,0x84253d3b),LL(0x6a40795c,0xa38fd372),LL(0xb45a08cc,0x22234e1d),LL(0x09918d4e,0x76319208),LL(0xea70d97b,0x3ef6521d),LL(0x0bdcb67c,0xae2d874b),L_(0x0000018d), + LL(0x61d5097c,0x8fe4e5c5),LL(0x4aedde8b,0xc0d36b58),LL(0xaba27830,0xc0f869dc),LL(0x32bc7d59,0x14a35cbc),LL(0x22d71ab7,0x04bed4bc),LL(0x00680d9e,0xdf25061f),LL(0x3bf0836a,0xb3d768c3),LL(0x3b0d7fed,0x616b984e),L_(0x0000015c), LL(0x16b36592,0x3c8c5d5c),LL(0xbd923c28,0x9a32e9b2),LL(0xfbaf0321,0xf0d8e95a),LL(0xed15bdb0,0xd3039b5f),LL(0xd8942727,0xcc59ce26),LL(0xa1dec9a4,0xf0b3676f),LL(0x21992696,0xb8c7cfb1),LL(0x27260c98,0xc1c97929),L_(0x00000141), + LL(0x06497092,0x97538cbd),LL(0xee612332,0xd25447d7),LL(0xa1040800,0x9c9bdc12),LL(0x06fb815b,0x191fed4b),LL(0xae49fbdb,0xd9407747),LL(0x3d19e592,0x9715df76),LL(0x4613ac78,0x1e9e20a7),LL(0x6c932530,0xe2bfff7a),L_(0x000000fd), LL(0xe1fd9066,0x6bfd0423),LL(0x13390bb3,0xb87dda88),LL(0x40017ffb,0x979fe6b8),LL(0x635bb57d,0xb6fc9a61),LL(0x8ce87e55,0x535b6b63),LL(0xea1ec56c,0xf567cddc),LL(0x06b927fc,0x72c516ee),LL(0x6fb0868c,0x2ebdac5a),L_(0x000001ff), + LL(0x0de7eaeb,0x76e19265),LL(0x53bc630e,0x506faf0e),LL(0x88127211,0x64c166ff),LL(0xad3fc9e2,0x6308dc18),LL(0xb271bc9b,0xec631a3e),LL(0x23be699b,0x2e23525b),LL(0xbfded0b1,0x2391574a),LL(0x69f0d2b6,0xa8ede972),L_(0x0000007b), LL(0x5c84ab62,0x194cc299),LL(0xf244f4b2,0x911e4585),LL(0x7871cfc3,0x52af7b51),LL(0x331dbf96,0xd41147d5),LL(0x7a399291,0x48e46193),LL(0xb0e20d54,0xd985a24f),LL(0x98e92da0,0x7266525c),LL(0xe9b74352,0xe84bc9e9),L_(0x00000043), + LL(0x7a9ef311,0xe9d37b18),LL(0x456032b1,0x30dc5e77),LL(0xd6168724,0x47f55c35),LL(0x18a17037,0x154ea414),LL(0x86d54c7d,0xe14c43c8),LL(0x8d092542,0x78f9b9e8),LL(0x986d7498,0x98519065),LL(0xcc71fd0e,0x4d22c2b8),L_(0x00000060), LL(0x41eec301,0x91d1b267),LL(0x4de89064,0x601dee13),LL(0x91ac8ed6,0xd375837e),LL(0x8587c0dc,0xa03d56de),LL(0xd2c2524e,0xa4331dd9),LL(0xf36ec517,0x0f8bb8e6),LL(0xb100599c,0x0dc65f7a),LL(0x8ada0049,0xa298259e),L_(0x000000f3), + LL(0xc52854f8,0x1b2f821d),LL(0x01e839c8,0xcb7e709f),LL(0xf9520b0a,0xc4857ab9),LL(0x3a85ef6e,0x09f9eda6),LL(0x51f47572,0x96daca66),LL(0x6e717337,0xccecd697),LL(0x40b37bfa,0x29f4ce02),LL(0xcbb44372,0x0fe8a0ff),L_(0x00000191), LL(0x2adce4eb,0xa3781970),LL(0xcf2ed75e,0xf948f559),LL(0x524a7d80,0x3e1fceef),LL(0x058a1573,0x25fd5510),LL(0x5865318e,0x14c29ed3),LL(0xcb7d9fa1,0xcaa64e51),LL(0xf171b487,0x25580546),LL(0x006163b8,0xde740000),L_(0x00000086), + LL(0x09489108,0x87d0f1ad),LL(0x4cf7363c,0xd4fe9fd3),LL(0x9bd13abd,0x4b7d7e77),LL(0x66face9e,0x42746d44),LL(0x0edf9d57,0xd5f51826),LL(0x888b45bf,0x37b7e3fa),LL(0xde49e8c9,0x0262004d),LL(0x8fd87627,0xdc4da423),L_(0x0000008a), LL(0x5a095bda,0xce31cec6),LL(0x2990a670,0x1be9607f),LL(0xf2081d18,0x8855d0c8),LL(0x11fb1c34,0xc4c2574d),LL(0xf1b8ff1c,0x3e444ec2),LL(0x4404e3fc,0x2db84189),LL(0xb7726488,0x0dd78e74),LL(0x7de996b1,0x7da11b57),L_(0x0000001c), + LL(0xedc7667f,0x6a5bd2b7),LL(0x343d29b0,0xd33329b0),LL(0x82fbc88b,0xd3fc973d),LL(0xe1e7bcdd,0x111c0001),LL(0x1c56ee4a,0x0cb45e7f),LL(0x65818c84,0xaccf98e4),LL(0x69029f68,0x6bbf8831),LL(0x53ac7e98,0xe2fa2c45),L_(0x00000060), LL(0x05a0028e,0xb7950225),LL(0x0e5094fb,0xf11a656a),LL(0x3eed5459,0xd3afccdd),LL(0xe6e4111f,0xc0d31cdb),LL(0x822775ae,0xfb39d140),LL(0x04034f9a,0x5954dd7b),LL(0x8adace51,0xc58c7b83),LL(0xeef24d4c,0xe9d767e5),L_(0x0000004d), + LL(0x0d2c0dba,0x7f21ed73),LL(0xfb8a9c16,0x300cbdfb),LL(0x12e137b8,0x22e8279d),LL(0xefc00fd0,0x173a4228),LL(0xe30fee24,0xaf4fb8a2),LL(0xaa67fa02,0x6171abf8),LL(0xda82a49d,0x418d47f2),LL(0x3ea61949,0x572fdfa4),L_(0x00000170), LL(0x96484020,0xbfe14768),LL(0xceb46b56,0x36fbf6b3),LL(0x2855bf4d,0xd4e1ce80),LL(0xeeceaddf,0x5130ec7d),LL(0xeb1ca189,0x57123316),LL(0xabed8057,0xb7e8b4c8),LL(0xcb8de9f3,0xa878fb40),LL(0x81b143a5,0x2fa96496),L_(0x0000008b), + LL(0xff728615,0x22b150de),LL(0x9a87c082,0xad76f636),LL(0x222ff210,0xf2177234),LL(0x874b4d66,0xfb6d673f),LL(0x7a63aa6f,0x559b847a),LL(0x1fb601b8,0x7f528818),LL(0x1d5a56e1,0x2dceae56),LL(0x159cad3b,0x64799ea5),L_(0x00000170), LL(0x78fbf962,0xc6717776),LL(0xfb840953,0xe6943ee3),LL(0x6c82ee1f,0x45986586),LL(0xa8804763,0xb2c01a1d),LL(0xd2e62027,0x81dd9ed1),LL(0x7ac9ecf9,0xa86a93b5),LL(0xea3ed52c,0xab42d43a),LL(0x9783c732,0x4badd572),L_(0x00000127), + LL(0x251ac5fc,0x4e7db852),LL(0x1ee36133,0x5d2ce89b),LL(0x7925fde7,0x344442cb),LL(0x7be13983,0x933fd989),LL(0xf818aa84,0x868cf674),LL(0xcf763eff,0x970119fa),LL(0x1161eea1,0x91b1cf2b),LL(0xf803b198,0x47f45bbc),L_(0x000001d3), LL(0xb92b375d,0x2871ba24),LL(0x03c6e820,0x946bbdda),LL(0x1e7f5b10,0x6d786c0b),LL(0x901e63e0,0xf905444d),LL(0x61291f2a,0xa07d991d),LL(0x26f8514d,0x5dd4a768),LL(0x8caa8bed,0xba23453d),LL(0x625c627a,0x55ae73dc),L_(0x00000114), + LL(0xb896a822,0x7616ee6c),LL(0x76716c8f,0x9e16dd77),LL(0xd9dc6964,0x424e43ef),LL(0x4f1ab6f7,0x3307372b),LL(0x853acdd0,0xb131b10b),LL(0xd0481561,0x6c779030),LL(0x8833d896,0xb43c81fb),LL(0xf49c69e7,0x013b71e6),L_(0x000000d9), LL(0x89994c4d,0xf6938c6c),LL(0xcb8f8364,0x7d7772d3),LL(0xb55fa4df,0x5c5bb6fc),LL(0xe309036f,0x87518233),LL(0x00458dd9,0x5ae0cb46),LL(0xab6a628e,0x80a93940),LL(0xd00141d6,0xe42dc460),LL(0xe62c337f,0xf594561c),L_(0x000001d5), + LL(0x89aca927,0xe8ff16d6),LL(0xd0f00eb5,0x060c9ece),LL(0x76dc2763,0x8d24bcf1),LL(0xe04a4e63,0x8049d5a2),LL(0x1f378724,0xad86dce1),LL(0xee568d6b,0xbd4ecf75),LL(0x064ed8ea,0x23b4afb4),LL(0x3066bb9b,0xe8ba5019),L_(0x00000062), LL(0xb55d56a1,0x16a5e07c),LL(0x0317cfe4,0xb05c4eb0),LL(0xe263fd3a,0x87619f5b),LL(0xe43b9d32,0x04548fa9),LL(0x5fe60636,0x1e3bb4ee),LL(0x177080d6,0x80dd88dd),LL(0x6b920ffa,0x50a4adb9),LL(0x6cf839eb,0x579a402c),L_(0x00000026), + LL(0xc3463c36,0xd3860f86),LL(0x51b92975,0xd751ffa4),LL(0xe9c89ace,0x0fff3b8f),LL(0x22e82df0,0x44ceed1d),LL(0x9ef4bd4d,0x322e7d38),LL(0xec43e5b6,0x5dafe91d),LL(0x3ac6cd72,0x385f22e0),LL(0xc23c7139,0xecc87ca1),L_(0x000001ee), LL(0x21e0fc81,0xd6515802),LL(0xfbf97dbf,0x72372941),LL(0x689ac9e8,0x4611974e),LL(0xce7740f8,0xe04ba0c6),LL(0x7a8f9746,0x7419caa0),LL(0x05b0cdaf,0x30755659),LL(0xcd257003,0x5af7e403),LL(0x8e3b2c01,0x7d54b47d),L_(0x00000128), +}, +/* digit=51 base_pwr=2^255 */ +{ + LL(0xe0e5a47f,0x06aeb844),LL(0x171b7252,0x2f67f278),LL(0x3ef95a8f,0x411d7c3d),LL(0x1341fdfb,0xbc9db5d5),LL(0x9c831f2c,0x64cd3d49),LL(0x5fa0db40,0xb8bb90a7),LL(0x2c8d72cf,0x050fdef7),LL(0x9770a986,0x584d26e8),L_(0x0000012a), LL(0xd8cc5f72,0x8a357b6c),LL(0x75fe114c,0xe1fc26b3),LL(0xaa2296d0,0xe2fe623c),LL(0xe037cba1,0xca73315c),LL(0x36843eb8,0xb7e86db2),LL(0xb5b70ddf,0x4b155e04),LL(0x20198f9d,0x06921394),LL(0x51535cfa,0xaa06d437),L_(0x000001a2), + LL(0x3bc9f5b9,0x89cc4566),LL(0x68f57feb,0xa2543b28),LL(0x4bd3cbd6,0x0bf63c0e),LL(0x66da5e56,0x648f4a56),LL(0xb7d9cc0e,0x7591427c),LL(0xab848b1a,0xe85c5977),LL(0xf4656829,0x4025667a),LL(0xcdae8f7a,0xab876527),L_(0x000001b4), LL(0x40ffbcdc,0x204ed818),LL(0x30db96c4,0x1b3e5e48),LL(0x26c352dd,0x497308c9),LL(0x54703369,0x3370174e),LL(0xa9534502,0x7c6d8497),LL(0xae86058c,0xae7aecbf),LL(0xa32e4cdc,0x67daf0b8),LL(0x3a4e9eb5,0xaf8dd7df),L_(0x0000005e), + LL(0x715a5a95,0x5b9e36c3),LL(0xe50c2a6e,0x316c41f6),LL(0x6af25999,0xe48ac795),LL(0x813a1e7e,0x65d44dd3),LL(0x7fc2f7f1,0x4d3b130b),LL(0x08cc4038,0x7c00e333),LL(0x4484ccd4,0x8e7636fc),LL(0xf9a80322,0x1688e5f3),L_(0x0000008f), LL(0x05247531,0x0987f80d),LL(0x2cd48e4d,0x9fe4562b),LL(0xaa48e7e6,0xf168a311),LL(0x7fdc1a14,0xdf4018fc),LL(0xc463e403,0x6c8979b5),LL(0xd6d0bb4b,0x62cddf39),LL(0xdf09f24f,0x9b318fce),LL(0xca7e6578,0xcab54343),L_(0x0000018d), + LL(0xe7511a46,0xd7deae24),LL(0xcb23734e,0x23939762),LL(0x66bcd84d,0x989a46bd),LL(0x85ec037c,0x65439883),LL(0xcc808ec0,0xa3f08c8a),LL(0x680dc66c,0xa76800e7),LL(0x4c3c5332,0xcc98ee9e),LL(0x8663204a,0xa0ef46de),L_(0x000001b0), LL(0x7fff2898,0x05b4a4e2),LL(0xb14e22b3,0x930a37ee),LL(0xe9d3141e,0x35f5cd09),LL(0x3364f154,0xf55ccf3f),LL(0x55f31352,0xf6c93770),LL(0x0c74549e,0x4bf80f61),LL(0x8d0207da,0xb1c2b15c),LL(0xafb6ee97,0x0992fd2c),L_(0x00000092), + LL(0xa33e3956,0xea69c80c),LL(0xc95caa93,0xdeca4025),LL(0x95bc2026,0xc8c86ea9),LL(0xe3161b91,0x73fc72d8),LL(0x46b441b7,0x033e25a4),LL(0x6b7c1805,0x2d4e9335),LL(0x5a4b1a06,0xd30b7dc3),LL(0x992637db,0xdaac9a90),L_(0x000001d5), LL(0x67f8c589,0x4f4c9063),LL(0xc14619bd,0xfbc662e7),LL(0x3c65896e,0x8176a953),LL(0x1c5790f3,0x4f51c6bd),LL(0x0ef460cd,0xc6fa754c),LL(0xee3cd226,0x5e872735),LL(0x05291b65,0x79e3b5c0),LL(0x734e1b22,0xfa256432),L_(0x00000194), + LL(0x5d2ebb4f,0x0643f252),LL(0xedb2cca1,0x00e32811),LL(0xc996f279,0x6f6af92c),LL(0xbf992edb,0xbdef8275),LL(0x3384462d,0xa4dd3d26),LL(0x818a7ff9,0x8e214401),LL(0x60e7694d,0xa7aec62d),LL(0x9d54e87f,0x8bdd2244),L_(0x00000198), LL(0xe4e67752,0xfb63c9fb),LL(0x7e7ff11a,0x7eec026d),LL(0xc6b3e18f,0xe08b80f1),LL(0x84b5c983,0x5d6b5a4c),LL(0x4b0fd4b7,0x85f99e3a),LL(0xfc4904ce,0x7afd5a7c),LL(0xc336a99a,0xba1e62f6),LL(0x24e4a736,0xbe20ba29),L_(0x00000195), + LL(0x8229817c,0xbb592469),LL(0x29ecccb0,0x89ef0925),LL(0xce6e29e1,0xf98f60f1),LL(0x36216c3c,0x0848c8bd),LL(0x63a73874,0x085409b9),LL(0xd4abc07d,0x2319eb0d),LL(0x0e39c02a,0x6bda97a9),LL(0x393de5dc,0x0140ddd0),L_(0x00000115), LL(0x6a8c37e9,0xa2f22a24),LL(0x54381101,0x423788d2),LL(0xb694bdb7,0xc151a89e),LL(0xd0ef2b67,0xb01ee242),LL(0x01c2b082,0xc07af292),LL(0x10fd1158,0x3639401a),LL(0x8e3f86e2,0x1ed8f101),LL(0xcf21ea60,0x83b3b62f),L_(0x000001fb), + LL(0x10fc7810,0x718c92f0),LL(0x3423f6e8,0xdae8d246),LL(0x5f129e35,0xaeff7db0),LL(0xdbad59f4,0x963932f5),LL(0x3cf82c0c,0xf5e468db),LL(0x6b7d10e1,0x10e6e23c),LL(0x6e085959,0xc76fb1b0),LL(0x538880e8,0xe8c12594),L_(0x00000134), LL(0xd87b6710,0x89506649),LL(0x272ea4f0,0x9dd1a14c),LL(0xaa274066,0xa6cc0d62),LL(0x191622f8,0x92244f6f),LL(0xd28338e3,0xc3dcbd9d),LL(0xa8dd7166,0xa39c0c61),LL(0x4930a90c,0xb979b8ce),LL(0x6cd41296,0xaa5c88b7),L_(0x00000037), + LL(0xe9bd2031,0x8ef889ab),LL(0x6a8258a9,0x87f34cfa),LL(0x6e977272,0x538468d6),LL(0x198bf996,0xe9cb2903),LL(0xea7ac40d,0x389f9bff),LL(0x50fd922d,0x88f4717c),LL(0xcb0c2bca,0xb57f0298),LL(0x5d670088,0x812c3767),L_(0x000000fa), LL(0xadbacbad,0xd95da33d),LL(0x89860058,0x74f4e9a6),LL(0x9df658db,0x46a06ddb),LL(0x8faf5c15,0x36b96ffe),LL(0xe9bbc867,0x1a07dce2),LL(0x19a59e1c,0x9536a09f),LL(0x1683c160,0x7fabb0f1),LL(0x183d2bdd,0x06b7a416),L_(0x000001d0), + LL(0x31cd955a,0x5451d16f),LL(0x720fff5e,0xeacd93fd),LL(0x6c62e42c,0x6f74fc83),LL(0xff9b7285,0x8a51db93),LL(0x7b6bb42b,0x66ca983e),LL(0x8fd893a3,0x08eee06f),LL(0x491c6c89,0xe1230942),LL(0x638e9f64,0x4984e580),L_(0x00000176), LL(0x979f347c,0x0bad9aba),LL(0x7b9d835c,0x84846555),LL(0x89b78779,0xc6bb325d),LL(0x88fce8c3,0x0fb571c3),LL(0x237c5f2e,0x27185f17),LL(0x37bcf483,0x53b0ac57),LL(0xf037df6f,0x34a972e5),LL(0x73b6f7ae,0xf685c7b2),L_(0x00000021), + LL(0x0e793769,0xfab07625),LL(0x52bebe14,0xd1fbd06a),LL(0x7d25c686,0xe5149dc2),LL(0x20b2f012,0x6707c1b6),LL(0xe4fdb06a,0x5cf7e0a4),LL(0x124b0592,0xdadcb97c),LL(0x9ef54e16,0x97f26141),LL(0x6b91bf50,0x689c475b),L_(0x00000165), LL(0x22cd2270,0x31ac5e9e),LL(0x95772aee,0xf333125d),LL(0xfb3bbb8c,0x906a459b),LL(0xda033a3e,0xd9a3800f),LL(0x7aebdf94,0xea08c76a),LL(0x4600cde7,0xecd96496),LL(0x1b4f8404,0xb9fdf8c7),LL(0x58389c23,0xd186fc48),L_(0x00000137), + LL(0xc0dd4ad7,0xace5575b),LL(0xabf66053,0x6dc5328e),LL(0x54861cbd,0xea9fdaff),LL(0x8555b123,0x0ecf823c),LL(0x09e411c0,0xa5d8934d),LL(0x0ae97a01,0x170ceb09),LL(0x91dabc9c,0x73c40a75),LL(0xd8f751f2,0x52861011),L_(0x0000010f), LL(0x3075cd88,0x352bc9a3),LL(0x79de4fde,0xf0130bb7),LL(0x2eb1b199,0x3c4457b6),LL(0xa95e2900,0xf04878d3),LL(0xc1a9dc9f,0xe04ebfee),LL(0x097a6545,0xf5aa7d0d),LL(0x673c7b41,0x3c5c4ce8),LL(0xa67894e6,0x385d1700),L_(0x0000005b), + LL(0xf3612ddf,0x16680fb2),LL(0x370df675,0xbeb0847a),LL(0xbefb427d,0xbbe54c19),LL(0x9a4770e1,0x44a1916f),LL(0x7f5945d3,0xc14ef507),LL(0x731b2da3,0x17aa92af),LL(0x07208217,0xf69f649d),LL(0xa27c5c7b,0xabd89463),L_(0x000001f1), LL(0x6897edfe,0xe551752e),LL(0x9733c080,0x98e86236),LL(0xc5bfef7f,0x936a2ebe),LL(0xcc36a721,0x25c227b9),LL(0x11dd6248,0xf8d96ae8),LL(0x83440604,0x3b2dca5f),LL(0xc74d7e75,0x3d8a998d),LL(0x3c210303,0xdcf4cf75),L_(0x0000019c), + LL(0xcbdeae01,0xe646d7ef),LL(0x2f349cfb,0xfd187fbb),LL(0x22f14a9c,0x7fb5a2ff),LL(0x781ef46f,0x084df701),LL(0xada115d8,0xab2e7da6),LL(0x37b36285,0x21432735),LL(0x779e5cbe,0x42159b5d),LL(0x987b1bb3,0x182d17ef),L_(0x00000121), LL(0x95d5c1bd,0x0c974b93),LL(0x3e904667,0x4f31ca20),LL(0xc9fa51be,0xed87df23),LL(0x5530167f,0x7ab1aee3),LL(0x34d6716d,0x16c8a7b3),LL(0xb3f82160,0xf3eb37b8),LL(0x77ee013d,0x13ff1326),LL(0xa57a3a10,0xd7d1a2e9),L_(0x0000007e), + LL(0x57c07bef,0xfafe3733),LL(0xb917d893,0x17024a0a),LL(0xfd27b406,0x89eda4ec),LL(0xcd3182c3,0x4e2244fc),LL(0xcec915fc,0x083e32ec),LL(0xbc2fe85f,0x26668631),LL(0x3458ec27,0x23dec845),LL(0x2e647e96,0x35986103),L_(0x000001e3), LL(0x26887044,0x9c1dd0c7),LL(0xc0f6c814,0xdb6594dc),LL(0x59eee455,0x2db7ed2b),LL(0xc7b946f5,0xc94ac2ca),LL(0x45521872,0x1f918bfa),LL(0xe23366a4,0x3439b349),LL(0x50d8220c,0x347cd4a8),LL(0xc2e30ec6,0x9274e0c9),L_(0x0000009c), + LL(0x28064668,0x18b3fd00),LL(0x605cfac8,0x11efdfd4),LL(0x85d2f0b8,0x5bb41efb),LL(0xee216714,0x3c03cac7),LL(0xade36a6e,0x485c4b2d),LL(0xcd3725a1,0x50bc220d),LL(0x2cf525a5,0xb11c84f3),LL(0xe314db66,0x664e47ac),L_(0x00000013), LL(0xe7d464c1,0xa7a48858),LL(0x6f7bbfd1,0x7d04c227),LL(0xe24ada56,0xadced466),LL(0x03a6a941,0x70addbb1),LL(0xf14e02c2,0xc761ca82),LL(0x94b62798,0x03264d07),LL(0xa0bec3f9,0x966e8d47),LL(0xe6caf618,0x1f211c02),L_(0x0000001a), +}, +/* digit=52 base_pwr=2^260 */ +{ + LL(0xb5b4bc19,0x26c24408),LL(0x1e48c2aa,0x2fb6cd86),LL(0x8746f93b,0x515690c4),LL(0x71e5f018,0x76a3c1b7),LL(0x99fbb28d,0x993035c8),LL(0xc338e004,0xa3d8d18a),LL(0xb4e7f02f,0x804c0351),LL(0x09fabf9b,0x3e6175e3),L_(0x000000f8), LL(0x485a0549,0xf6830680),LL(0xc1a8a622,0x50d94962),LL(0xf94a3f34,0x0a44d62d),LL(0x8057a83e,0x05319e21),LL(0xd2bed201,0x3a4a1ebd),LL(0x3d6076c1,0x7368f486),LL(0x4672ca13,0xef4b1a43),LL(0xf96135e4,0x6692537f),L_(0x0000000b), + LL(0x08fe30e3,0xb81b7a5e),LL(0xb048815a,0x11e1229e),LL(0x2e0a161f,0xecb84207),LL(0xf8e1801b,0x5b394a58),LL(0x890edfad,0x37512807),LL(0xb3e4e477,0x5d81f675),LL(0xc9984105,0x1050ce18),LL(0xf43ed35c,0x17bd56ac),L_(0x000000c2), LL(0x5a1e0055,0xcf0d6c8c),LL(0xaf53db5d,0x6ee72ddb),LL(0xc6ab4e4f,0x32c8481a),LL(0x1b4e6860,0x5c545af6),LL(0x0e7c0e41,0xc3595ad6),LL(0x261ffe75,0xbf47f59b),LL(0xf66fa7cf,0xfa1aaf6c),LL(0x212e7097,0x86b7977f),L_(0x00000083), + LL(0x619e46fa,0x4b0029a7),LL(0xf5c33307,0x1eec5f29),LL(0x9e45f3bb,0xf8396133),LL(0x17635aad,0x25d3e2a3),LL(0xbdaba508,0xc34ef799),LL(0x574f4d09,0x78d47f38),LL(0x085e8086,0x3db03879),LL(0x1c4a5748,0x65ae9f6d),L_(0x00000144), LL(0xcaebc4bf,0xb52fb74f),LL(0xb901e46e,0x1868eef4),LL(0x68ec4a86,0x7bab1199),LL(0x9f2f51a0,0x8f19df10),LL(0x6a75a074,0x2d75da4f),LL(0x61385965,0x59f7f255),LL(0x60c80677,0x6b7b569e),LL(0x40b66382,0x0533f4d4),L_(0x00000145), + LL(0x4c4911e4,0x3b8e6670),LL(0xd20de07d,0x7aafab5a),LL(0xdab27e9b,0x3fb66eb5),LL(0x5ac52dbe,0x7ce85634),LL(0xdf84c8cf,0x9025496c),LL(0x95b8e1e2,0x776182f0),LL(0x8e6db4cd,0x21aaa54e),LL(0x3bb0faa3,0xe73fef00),L_(0x0000008a), LL(0x4fac454d,0x16d643fd),LL(0x70e138d6,0x5612fc48),LL(0x69ca59b8,0x0889a9e6),LL(0xfb3a26a0,0x93e3dad6),LL(0x43df1bc0,0xe6ce66bb),LL(0xae036271,0xfcd4244d),LL(0x05182a82,0x958ca2ac),LL(0x102559d8,0x26838c85),L_(0x00000075), + LL(0xcc2f3836,0x0184b954),LL(0x6cd88b38,0xdcf3ba77),LL(0x70c99422,0x86f66f43),LL(0xbc4bd450,0x7b81c0e8),LL(0x93575c5f,0x704cad24),LL(0x4091825d,0x4b9f70ce),LL(0xf1ff4bbf,0xac2a0a24),LL(0xb5d28bd9,0xe5ebf7a3),L_(0x00000023), LL(0xbdf9c155,0xeb270e7e),LL(0xeb783548,0xfd0b1050),LL(0x81562bc5,0x96b8a59a),LL(0xedb5f688,0xbc130375),LL(0x8ab1fc73,0xa1c5bd93),LL(0x89b28fea,0x7f18c19c),LL(0x8d6e4b1c,0xe98a494f),LL(0x409f7384,0x55131bf6),L_(0x0000003f), + LL(0xd9331dcc,0x25a27923),LL(0xffb6351b,0xc9bc2f04),LL(0x7f29f1e1,0x91e80528),LL(0x37069b7d,0x8a56cb26),LL(0xff75d6d4,0x7d9a9a20),LL(0x3f52dd39,0x52270b39),LL(0x703dee3c,0x67288a63),LL(0x13f9c1c2,0x49651d47),L_(0x00000038), LL(0x3c2dd2e1,0x1cd56c85),LL(0xbc1a8d52,0x46598a93),LL(0x87351736,0x4685de4b),LL(0x418967ee,0xf35701ef),LL(0x6dbbce4c,0x380b116b),LL(0xc5acf7cf,0x35416b03),LL(0xe839b424,0x8d1a9cff),LL(0x15841fbd,0xe1730d1f),L_(0x000001a6), + LL(0x9958b964,0xc0fdbea9),LL(0xf76bf65a,0xf573be01),LL(0x0c6778ad,0xffd85a6f),LL(0x927d0f51,0xfe98c72d),LL(0x1738874a,0x187e8ec8),LL(0x032ae57d,0x00c6d76d),LL(0xdf95e888,0xdee55d14),LL(0x0dec4042,0xcd5760c3),L_(0x000000e8), LL(0x4c10f002,0x14eac108),LL(0x7bdb463a,0xcbf771c3),LL(0x76281603,0xd48543b5),LL(0xfc634037,0xb965ac3e),LL(0x6e5426f3,0x49a7be5b),LL(0x87fba366,0x2e203d0f),LL(0xddb5ca9f,0xabbc3174),LL(0x55052649,0x2eb60836),L_(0x000000b7), + LL(0x1438294a,0x5c1bc4f6),LL(0x64a43b5d,0x1c634029),LL(0x5d7c2617,0x93c0fb82),LL(0x1b7967cc,0x96145dca),LL(0xd068364b,0x3b5c4ddf),LL(0xec5bd3c7,0xd5007f0e),LL(0x2d7bf8f0,0x771d6fd8),LL(0x215b93c7,0xf222990f),L_(0x00000075), LL(0x47223677,0x1d26e01b),LL(0x340c9a0a,0x04b5b926),LL(0x7edb2bec,0x0417ca25),LL(0xefd5d17d,0xb41c7280),LL(0x70df3372,0x93c942f6),LL(0xfbfcef99,0x7e3d7910),LL(0x37ef3a57,0x39005c54),LL(0x8c4d4c90,0xdb0ceb3a),L_(0x000000dd), + LL(0x7626a28b,0x65b80a9e),LL(0xb3de9aec,0x47955751),LL(0xebd70107,0xb9795325),LL(0x326b6e2a,0xb7ebfc01),LL(0xb10f9b62,0x6ec48711),LL(0x145049a1,0xb7dced78),LL(0xd8c85f83,0x6736770f),LL(0xf3878209,0x41fd70b3),L_(0x000001ea), LL(0xc5d35978,0x1245bc60),LL(0x228424d3,0x6d611151),LL(0xee80416f,0x92f6a019),LL(0x18ef86e2,0x2e88fbc7),LL(0x9f5d9f5c,0xb51a1205),LL(0x3ee14394,0xd989aea0),LL(0xe73a0ff8,0x81623fdf),LL(0x10ed321a,0x3d71a6e8),L_(0x000001dd), + LL(0xe8302688,0x98f6bd7a),LL(0xef684d8d,0xaac1e35c),LL(0x1c71e036,0x19611929),LL(0x9428ed8d,0x24f7251a),LL(0xf90f6e8a,0xcd34ddd1),LL(0x9742ae40,0xf7d22290),LL(0x9b5b15a7,0x5d805418),LL(0x91f1f6ec,0xe50e28f5),L_(0x000001c6), LL(0xd9e75a63,0x2c60d848),LL(0x5ad92240,0xf18911d8),LL(0xcfb4c90b,0x3c5b71d6),LL(0x1a2c26ff,0x5d53d732),LL(0x9fada03e,0x8bfbe9ec),LL(0xd69c81a8,0x443458b3),LL(0xce7f11ce,0xca59b490),LL(0x2489ddd2,0xdaf9ecde),L_(0x0000011d), + LL(0x75cf30c3,0xd052454d),LL(0x6844d9d2,0x667d1be2),LL(0xec3032ef,0xefd476cd),LL(0x67f7c660,0x47628345),LL(0x80c64c50,0x57751538),LL(0xbb8da5d7,0xb8ef3bee),LL(0xb395bca7,0x3bc2ad45),LL(0xc2e7e012,0x610d67aa),L_(0x000001ca), LL(0x2180bc90,0x3dc2b1ef),LL(0xf5d2b364,0x4ee3fb91),LL(0x38966853,0xe0446916),LL(0xc5fb0623,0x2a6bfc98),LL(0x6bce11c9,0x65c6b297),LL(0xeb6233b0,0xce8c355a),LL(0x6ac473c3,0xd97c1dd8),LL(0x56091541,0x0514bb6d),L_(0x00000023), + LL(0xb9480e26,0x92033f14),LL(0x17a6ef25,0x89a53d65),LL(0xaa5a50af,0xd872b73d),LL(0xa475ab82,0x53f65ce3),LL(0xe34acbbd,0x1d33affd),LL(0x33a80ee5,0xe7690066),LL(0x969e21f0,0xcc415a0a),LL(0xca2e0920,0xb0325f4a),L_(0x00000150), LL(0xa1f546f1,0x0f43e61e),LL(0x40fc3a90,0xa48abf41),LL(0x601d8bcd,0xe374c532),LL(0x786a5e70,0x7446fbbf),LL(0x484d4fec,0x0ec5b3b2),LL(0xdc5db3b9,0xeeb6c43c),LL(0xe60cf40d,0xca2ac048),LL(0x1ff63739,0x4475d66f),L_(0x000001b9), + LL(0x21d05128,0x9adfc451),LL(0xe4847519,0x294337f9),LL(0xbe446976,0x4e7dac1b),LL(0xf00a5441,0x94ab8aec),LL(0xc582caec,0x5ac9bb3b),LL(0xeacdc76b,0x3fe0e66a),LL(0x6e00689b,0x246c86c1),LL(0x6c266a0e,0xbf0ade72),L_(0x0000015c), LL(0xe7ec8261,0x70658a73),LL(0xff30554a,0xc9871f1a),LL(0x4b2448f2,0x8dd50a2b),LL(0x87a01756,0x3ea8f62c),LL(0xb6b9a2ea,0x7311e04c),LL(0x0d165122,0xfc6c9f2d),LL(0xb7efc2eb,0x07406007),LL(0x92c33ebb,0xbd8e5282),L_(0x0000001b), + LL(0xd9c24f49,0xe495d18f),LL(0x9b0f5222,0xac5ca929),LL(0x126086f0,0xf4d4507f),LL(0x41908fc8,0x3355d26d),LL(0x65791c82,0x31183a9c),LL(0xf00a9e80,0x018f0189),LL(0x644ffd95,0xe447af71),LL(0xbffa0975,0x7424f93b),L_(0x00000145), LL(0xfa695a18,0x0d6949a4),LL(0x78519510,0xb79c2b5f),LL(0xa59828a5,0x9ae92003),LL(0x6c54e38e,0xfb93be38),LL(0x67bd521a,0x4c71aeb4),LL(0x04b0340d,0xa3451e4d),LL(0xcd2e92f4,0xa9a77ad0),LL(0xfe218b65,0x656db073),L_(0x0000000f), + LL(0x30e20be8,0xa3b27cf0),LL(0x160f039b,0x82ec5f83),LL(0xcff71736,0xba9364b6),LL(0xebc485a6,0xddbcec8c),LL(0xdc80329f,0x3bda1715),LL(0xcc71e664,0x46fc4c3b),LL(0x592819ef,0xd1da3eb7),LL(0x2cb62fe8,0xb29cfca6),L_(0x00000055), LL(0x566fd9f2,0x8c802541),LL(0xfc158c58,0xe84b30eb),LL(0xf6625ae1,0xd137d022),LL(0x441de79b,0x42e42c6f),LL(0x7d99126c,0xf2ec0ec8),LL(0xfbbd41bb,0xb8f928d4),LL(0x2851ec63,0xf3ff5c1d),LL(0x5e5a9ca7,0xd3429e7d),L_(0x000000f5), + LL(0x4a3ce076,0x56a3a063),LL(0x8d143249,0x627718f3),LL(0x2232fc35,0x5a0479ef),LL(0x6a6d389e,0x82744b80),LL(0xf4d435b8,0xb0bd687a),LL(0x2792b960,0x4cecd317),LL(0xf792e60e,0x063be911),LL(0xb09dcb17,0x02f6ffb4),L_(0x00000059), LL(0x215ba3da,0xb04fbf6f),LL(0xe7c66f8f,0x07b90918),LL(0x95b38bbb,0x01c5b207),LL(0xc67022d2,0x4fdf3937),LL(0xee01b834,0xe5a11142),LL(0xc7b97506,0x11b8cb5f),LL(0x2ae40433,0x2450b7bc),LL(0xe3e1937f,0xa26a70cf),L_(0x0000005f), +}, +/* digit=53 base_pwr=2^265 */ +{ + LL(0x6bfa5396,0xf2fdc439),LL(0x7edbcb88,0xdb91292b),LL(0x19d35421,0xd5dee79a),LL(0xa420a538,0x035e9ea2),LL(0x9cf14f3b,0xe21709fe),LL(0x49703f94,0x690ca5b7),LL(0x495b47e8,0x4deb7af2),LL(0xcc2ef057,0xb09d6324),L_(0x000001d4), LL(0x9fe6e0b5,0x7ff7df3b),LL(0x25c764e6,0x1593ef9e),LL(0xb9153d85,0xef6d9489),LL(0x117822d7,0x238e5449),LL(0x1e34e4c9,0xbbd3333b),LL(0x58cc8198,0x416c6cfb),LL(0x7b487650,0xa8085b4b),LL(0xb3068c07,0x5e20cc8e),L_(0x0000017b), + LL(0x4bef6871,0xf98b837d),LL(0xe15922b2,0x62c29919),LL(0xc8afde9c,0x95a1a3c5),LL(0xffe9534c,0x604b1043),LL(0xfa2f638f,0x27a01a13),LL(0x04cd8a8d,0x2660393b),LL(0xe26fd0c2,0x72545d96),LL(0xcf0808a0,0x1dd10699),L_(0x00000187), LL(0x4ea56b71,0x037dfe3a),LL(0xc38223ef,0xd36e2094),LL(0xe8b66c87,0xe28405ae),LL(0xe3e2766e,0xa065b535),LL(0xed4b87f0,0x084a317d),LL(0x3f53ac0b,0x0ca5866d),LL(0xa0ee5586,0x82b21bd7),LL(0x1fa70803,0xff1d58cf),L_(0x000000f3), + LL(0xa39a68fa,0x905b2c93),LL(0xef13c9b6,0xd34ff12d),LL(0xa5eaf60e,0x46115d13),LL(0xad4eed45,0xc0704820),LL(0x0761b0ac,0xf0c499c6),LL(0x5dd51e45,0x4abd13af),LL(0xa978e552,0xb1ec09b7),LL(0xa79f811d,0x0dab7d3a),L_(0x00000190), LL(0x490481e8,0xa75f21e6),LL(0xea3d3b19,0x0364a9c0),LL(0x68df5edf,0x5e1d6b4a),LL(0xb44c93c9,0x33e2dcc0),LL(0x07832283,0xea8fc7be),LL(0x37cb9512,0xe9e13504),LL(0xc965c20f,0x887068c5),LL(0x62d3176a,0xe870a541),L_(0x00000004), + LL(0xc2984a5a,0xf1dd3a67),LL(0x7824703a,0xb39c772c),LL(0xbf0c69c5,0x46f942bc),LL(0x31d0901a,0x9e0174be),LL(0xd38bdff8,0xab6326f7),LL(0x91bfcc1e,0x8787eadb),LL(0x541868bb,0xa0385662),LL(0x6ba48a8b,0x6d878761),L_(0x00000060), LL(0xd5f8e883,0x69e290f5),LL(0x1d33d545,0x1ba52eb4),LL(0x662b634f,0x9dfd1d1b),LL(0x876fc504,0xbe51c909),LL(0x93e42059,0xcb7406ba),LL(0x49355b9d,0x2651475a),LL(0x8963ea18,0xbcf76704),LL(0x08985cee,0xaa85c805),L_(0x0000002e), + LL(0x2c70c50c,0x6c2616bb),LL(0xeb31ab0e,0x01e38aad),LL(0xbcd43f2e,0xda068909),LL(0x7f990c18,0x9fb2c072),LL(0xa82ff220,0x757bff88),LL(0x81327a89,0x28c2afd8),LL(0x1d3a1126,0x0c2079b4),LL(0x95685773,0xa957db38),L_(0x000000bb), LL(0x4a7cdb09,0x45f5c72a),LL(0x53fe6703,0x42ce353e),LL(0xbe22096d,0x4a3251c0),LL(0x601d33ed,0xaaaf17c5),LL(0xfe2c8cbc,0x3d4b4185),LL(0x242a9581,0xb32328dc),LL(0xbc79d78a,0x03bf4442),LL(0xa103c8f5,0x64e28853),L_(0x0000010c), + LL(0x1346edbb,0xb447a9f7),LL(0x2f9482b0,0x31ede472),LL(0xc7c55120,0x00d8bc4d),LL(0x627457bc,0x5c471ca7),LL(0x4a9f36d6,0x14a28cac),LL(0x436c70c1,0x38a173b4),LL(0x011c4897,0x96f4df0f),LL(0xdde3c9d7,0x587a661d),L_(0x00000193), LL(0x711723c4,0x143023ce),LL(0xbe0156de,0x68012aa1),LL(0xeabfa04c,0x3ed6803f),LL(0x204765fc,0x762dc13e),LL(0x2e5fcd9a,0x5b5cd65c),LL(0x04a542e1,0xd6b6a2d7),LL(0x3dcadeb8,0x57f74a74),LL(0x0da1060f,0xe953f87b),L_(0x00000148), + LL(0xfb1dd3f1,0x326c0546),LL(0x63e8f854,0x35eb9eac),LL(0x39f46433,0xf4944efa),LL(0xc8688704,0x91ff1606),LL(0xfeaa7186,0x99316708),LL(0xa92605cc,0x3fbb0f25),LL(0x2252affe,0xa90598c4),LL(0xcbb64aaa,0xb34934f1),L_(0x00000044), LL(0x58a7e6fc,0x763915ed),LL(0xc814b6b0,0xe697e570),LL(0x69866f7d,0x63fc73af),LL(0xb1f0f7a2,0xb634f283),LL(0x17533e2f,0x423d910b),LL(0xe17bdbad,0xfbcd888f),LL(0x778dac12,0x4c46f8f4),LL(0xfb0bef09,0x72d4d626),L_(0x0000017f), + LL(0x1eb22917,0x13b5648e),LL(0x34c2f6e4,0x202b7ba7),LL(0x8535398b,0xebd7f177),LL(0x7eea8b23,0xd3b0fc5e),LL(0xc7a0f19f,0xa3df55dd),LL(0x577641e2,0xcb9f261d),LL(0xf496646e,0x112454e8),LL(0xdaf2be9c,0xc23da6a9),L_(0x00000002), LL(0x2fed679f,0xe59d35c5),LL(0x1efd66d8,0x1b401767),LL(0x904f29b9,0x084f27ae),LL(0x129c352b,0x23e88566),LL(0xa3263601,0xd229faae),LL(0xc04620cf,0xc91c87f4),LL(0x535f695e,0x27c58545),LL(0x3cfc2a21,0xc94873fa),L_(0x000001a1), + LL(0xde0ea503,0xb13cb473),LL(0x88b9f2da,0x2dda613b),LL(0x3a43eba4,0xedbf11f5),LL(0x9cddb3f6,0xdf7a9b8a),LL(0x1e00c8ae,0x7e0c7ceb),LL(0x84c5eb6c,0x03d1dbf7),LL(0xc6747572,0x80122fe1),LL(0x5d6814d2,0x639c5254),L_(0x00000002), LL(0xde3b211d,0xec1fdac5),LL(0xa4651a82,0x690ed4f8),LL(0x4ef3c551,0xe2f0cf8b),LL(0x20e94507,0x61b6144a),LL(0xeb258124,0x11bde361),LL(0x51d9d605,0x541da730),LL(0x397e8ce6,0x06c00c29),LL(0xb4a5d672,0x43c098bc),L_(0x00000086), + LL(0x344f5276,0xf6656606),LL(0x82cb8136,0xd96edef6),LL(0x84c50ccd,0x9f0978ff),LL(0x37e0a146,0x17bb0d3a),LL(0xbf780900,0xb2dca4ae),LL(0x1d528632,0xb6bd3e16),LL(0x1bee4b87,0x8c609327),LL(0x16432d3a,0x4aa7829a),L_(0x000000d7), LL(0x09d85506,0x3f9c377c),LL(0x5046622f,0xa18dda52),LL(0xd98abc09,0x722fdd39),LL(0x23fb42b0,0xa78f3825),LL(0xf2a75675,0x13487db2),LL(0x33200560,0x244aa1c4),LL(0xc0bf37b5,0x86de25a6),LL(0x57b73e86,0x079d95dd),L_(0x000000bc), + LL(0x0ca7835c,0x17341b4f),LL(0x1e7f52de,0x52ebce6c),LL(0x882af4b0,0x673d8b9f),LL(0xbbd95fb1,0xd64ea8ef),LL(0x28e628db,0x7889079e),LL(0x54b7908d,0x26e0abe9),LL(0x3df2e6e8,0xc20813db),LL(0xfde7f3a9,0x978bffe2),L_(0x00000098), LL(0x280276f0,0xead10e9e),LL(0xad34ad6f,0x1076d303),LL(0x8df8f495,0x8819ee4a),LL(0xc0d57db8,0x70fb03b5),LL(0xb14472ea,0xbc0a100a),LL(0x18cc104f,0x7fbf87ac),LL(0x45839e8e,0x64d66536),LL(0x58fe7198,0x5bfbac43),L_(0x00000156), + LL(0x13d8a69c,0x1836614b),LL(0xcb97f199,0xc897ce78),LL(0x6d967571,0x940b810e),LL(0xd145156b,0x850c5939),LL(0x4b73e9e6,0x04a9944a),LL(0x6e833bad,0x2f7df8e9),LL(0x2cd53823,0x3b222e7b),LL(0xf7a26c91,0x1034f78b),L_(0x00000054), LL(0x40490586,0xfe320dfb),LL(0x5c8c95a5,0xcb9240ce),LL(0xfffec63d,0xc515192c),LL(0x000718b0,0x4259ce4f),LL(0xdbfc0155,0x6f7a6ff2),LL(0xb1ff6013,0x312bdeae),LL(0x4cc245a6,0x79a65a6f),LL(0x29aa5006,0xd3b4632f),L_(0x000001b1), + LL(0xba9ed328,0x356fabd3),LL(0x9eb2fa3e,0x32e2213b),LL(0x296648f1,0x5464f17a),LL(0xa0bf8f36,0xf19ca8ef),LL(0x4c8a5c7a,0x876e29a8),LL(0xa58d7e8a,0xd8f86aee),LL(0x0ec00506,0x04f4e1a3),LL(0x05b4072d,0x1462f8a1),L_(0x000000c1), LL(0x5e326e7e,0x564895eb),LL(0x5b19fee9,0x8c62d05b),LL(0x7809d8ab,0x0cb573dc),LL(0x4ad42bc1,0x1884e984),LL(0x9b3e8a9c,0x6b2d6773),LL(0x2d81f0f3,0x072385dc),LL(0x2f91b4d1,0xca372aa3),LL(0xe4038277,0xd16c3a45),L_(0x000000fa), + LL(0x5060d8be,0x9757a335),LL(0x1143084a,0x38952f06),LL(0xa4710659,0x025fc38c),LL(0x1698caaa,0xcf127f48),LL(0x7f55805b,0x39cb3c58),LL(0x621feb96,0x58068b85),LL(0x3a91b62b,0xa4e48dd8),LL(0xa7ba8220,0xbd22ff75),L_(0x0000005b), LL(0xfc09c649,0x05196c43),LL(0x142e4222,0xaa56e765),LL(0xeee6393d,0x8f13ec6c),LL(0xa88f8eb7,0x536554a7),LL(0x6720e144,0x66972f38),LL(0xadb6408b,0x9d95e37f),LL(0x67ab92ba,0xe96c2792),LL(0xa2d1345c,0x3fb8e9b5),L_(0x000001a7), + LL(0x945df86e,0x61c11852),LL(0xf484baad,0x1e71dab0),LL(0xad2e9168,0xe0ea71a3),LL(0x6e1a90b0,0x2b244009),LL(0xfb37ada7,0x0bd3281f),LL(0x38140203,0x1599d34d),LL(0xf278746c,0x3790a7db),LL(0x17f577dc,0x483a5cb9),L_(0x00000049), LL(0x22a84857,0x8f5c56dd),LL(0x6ec17c1a,0x767ebf21),LL(0xf0a141c4,0xf1091ff1),LL(0x051b5811,0x3ac1c024),LL(0x396942d9,0x692ece19),LL(0x5725cecf,0xf1e6de73),LL(0x75b56339,0x2f629ac2),LL(0x45030754,0x6207c855),L_(0x0000005d), + LL(0x8f44cc57,0xd14b028b),LL(0x8c73e470,0x684d5fa1),LL(0x46af781c,0xeb44feae),LL(0x3e3aadf0,0x4610320e),LL(0xfd9c5960,0xd8fffa44),LL(0x70d9d9d3,0xebbc9082),LL(0x8a6283f3,0xfcec5348),LL(0xdd60d649,0x44a603fa),L_(0x0000001d), LL(0x3023df31,0xce740ae3),LL(0x5f6a91eb,0x2000b013),LL(0x3780772b,0xe7ea71ec),LL(0x0e54747a,0x6f03b13d),LL(0xfc299d7f,0xd6603e33),LL(0xb6e9df68,0x86040d28),LL(0x2043747f,0x3aeee37a),LL(0xe4608968,0x9926fb8d),L_(0x0000004e), +}, +/* digit=54 base_pwr=2^270 */ +{ + LL(0x70b9e18f,0xabb9ad39),LL(0x6af8e430,0x523480bf),LL(0xf59d55e6,0x4bc56b8b),LL(0xc072bd61,0x3df0a6ec),LL(0x25c98f18,0xbee1786d),LL(0xbcc84059,0xf26f3fea),LL(0xb20a09a6,0x79a2dfb7),LL(0x93d600ce,0xcf2e6f03),L_(0x00000139), LL(0x3507cb80,0x9b72a39f),LL(0x2b1470af,0x4804a704),LL(0x7da313b0,0xe67c9622),LL(0xc290e590,0xbec90ccc),LL(0x796f29ca,0xf5e76e6a),LL(0xcadb620b,0x8ec01637),LL(0x15b03af3,0x4087520d),LL(0xd8dcf763,0x6c0ca6b7),L_(0x00000190), + LL(0xc34630d4,0x4f37e57a),LL(0xc030f2d5,0x649effc2),LL(0xb84aa880,0x3ad19d77),LL(0x1cab55a1,0x91bd296d),LL(0x8c081620,0xc8f7f0b2),LL(0x0c469726,0xb847d758),LL(0x1840b8cf,0xc59a8b12),LL(0xc8fd3c1c,0x0e2778fd),L_(0x000000b9), LL(0x2f98900f,0x446cc1f4),LL(0x3bf2f826,0x4fc8626c),LL(0x8d5f8bb7,0x7df08423),LL(0x3a877c74,0x41c77ea1),LL(0x471d935d,0x5556d8fe),LL(0xe98cde5b,0x279a8287),LL(0x068f4d40,0xe400538c),LL(0xdb305a88,0xc091d74b),L_(0x00000077), + LL(0xe7143fd6,0x766c809c),LL(0xdd78e4e1,0x81bcdd43),LL(0xa933555b,0xac8729aa),LL(0xb8964c85,0x4f18e8ec),LL(0x87096359,0x580f05ae),LL(0xffab1de5,0xe800a6a9),LL(0x797b2184,0xb6212cc3),LL(0xea98c5ce,0xc923afe4),L_(0x000000f1), LL(0x9f968c46,0x66353c22),LL(0xfe0b78e5,0x0345fac6),LL(0x27358467,0x180e49dd),LL(0x1ccff0c2,0x92bcdaf0),LL(0xea3ef331,0xf7e4fb3d),LL(0x99b89e87,0x092ef793),LL(0x9bdcca2a,0x1418dec5),LL(0xf9f9dccb,0x314595b4),L_(0x00000067), + LL(0x12cf8643,0x6e190a6f),LL(0xeee766f8,0x360709e0),LL(0x5b775cd5,0xd4566a98),LL(0xe4057c69,0x45df1e07),LL(0xc0672257,0x947733f9),LL(0x1b1c2a5a,0x4bcd6e2b),LL(0xc80987a2,0xe7293fbf),LL(0x89f4061a,0x11f7042b),L_(0x000001d7), LL(0x41e791cb,0xc53c1b03),LL(0xdaedd9c1,0xc48bf537),LL(0x495a12d7,0x2c8c9765),LL(0xe7c2d4a3,0x662fe9df),LL(0xfaed525a,0x27c6bad9),LL(0x5c4df70a,0x24dd660c),LL(0xba7fb076,0x21abac8b),LL(0x4a91b1d6,0xb618ce5d),L_(0x00000171), + LL(0x3e132643,0x7875f26a),LL(0x3212d16b,0x3953e4c1),LL(0x80a99a23,0x42f909d9),LL(0x457c9b9d,0x68f18c26),LL(0x62cfee59,0x0b1b0fbd),LL(0xd6e74f93,0x99d73ca6),LL(0x898ff611,0xecc60074),LL(0x0a0cf8cf,0x0e4b48e0),L_(0x00000082), LL(0xd0fa33dc,0xd086fac9),LL(0x30dd79af,0xe0e34e51),LL(0x0cb837fd,0x052d2441),LL(0xaefa0933,0xbdea4988),LL(0x44aec8de,0xdfac83ea),LL(0x46cb2469,0xfad769d2),LL(0x7cb77050,0x18dd28c7),LL(0x8001a60c,0x8fe3d888),L_(0x00000122), + LL(0xbc9cb5db,0x5b24df92),LL(0x2affa8b5,0x207215e0),LL(0x3c816de9,0x199ff528),LL(0xe11ab159,0xfcc61eda),LL(0xc8d67190,0x661fbf7d),LL(0xdda50129,0x76defd37),LL(0xd466e3a4,0xf14fb3e4),LL(0xc11ac280,0x7620efce),L_(0x000000d8), LL(0xd730b74c,0xb257b1f0),LL(0x4204720c,0xa9d04719),LL(0x620bab0b,0xcf599cb7),LL(0x4b89783a,0x4c38e784),LL(0x96aa7914,0xa4374ec1),LL(0xa42b74a4,0x1d57fa44),LL(0x5d9da37f,0x9e98081b),LL(0x907073d1,0xd1274d9a),L_(0x00000007), + LL(0xcbfb13a3,0x3e1d7c3a),LL(0xde4b8ce4,0x0940b9c2),LL(0x3515847d,0x594f371d),LL(0xc37d20b4,0x0d44e03d),LL(0x4b2281a5,0xa133895a),LL(0x03246afc,0x69dc40a2),LL(0x1243d0ed,0x6acc7d98),LL(0xc664eb78,0xa9ddc8a1),L_(0x00000041), LL(0xfe1862dd,0x1a66ad76),LL(0x3359c96c,0xebb34cc8),LL(0xe69f9794,0xd1662749),LL(0xf9f1455f,0xb162a274),LL(0x40fc34f6,0x9d860e20),LL(0x4fb62774,0xa70d36c2),LL(0x6f971a18,0x990d79fe),LL(0x19225101,0xdd30d9b3),L_(0x00000102), + LL(0x0a7a3999,0x51c91503),LL(0x673999f7,0xfe14668b),LL(0x08c22b2a,0xfc300d5b),LL(0xecabf6a5,0xe178c0bc),LL(0x020b90b3,0x79d38258),LL(0x81c171fe,0xa2f11763),LL(0x86f32623,0xf3a66cde),LL(0x6ff64b9b,0x5668f5ac),L_(0x000000c5), LL(0x6e735d95,0xac181251),LL(0x3ea58c5d,0xde279aea),LL(0x356a5f10,0x7e9f7153),LL(0xd08295b0,0x86ce9eb4),LL(0xf7c783f5,0x4daab1a3),LL(0x030b2d7c,0x603300a0),LL(0x2198f316,0xd0c0475c),LL(0xba184aa9,0xa6fe88ca),L_(0x00000111), + LL(0xdf1983b7,0xade6d9e8),LL(0xaf408fd2,0xfdbd3baf),LL(0xf2f9bf1e,0x437c785f),LL(0x502fb232,0xeb964445),LL(0xeaf5771f,0xb08bd2ce),LL(0x4c23d40b,0x71ed9783),LL(0xa9fbdb0a,0xf481a53f),LL(0x3a79f04f,0x8241d897),L_(0x0000006c), LL(0x2c38aa60,0xdbc73cb0),LL(0x6c1463d2,0x900c1c58),LL(0x38e9d58f,0x9115aabb),LL(0xc0a95554,0xd544f068),LL(0xb7066734,0x00d18a77),LL(0x10cc9da3,0x482d67a5),LL(0xf9d64b4f,0xfe8b6e80),LL(0xff8c0ceb,0xa32070d7),L_(0x000001c3), + LL(0x8777fa77,0x1fdd6bf9),LL(0xbe1106f7,0xc44a87ae),LL(0x43749975,0x3d0c3b77),LL(0xb45ea397,0xf0fbd03e),LL(0xd44cf903,0xb4c5c47c),LL(0xaa4a5ca8,0x38153aea),LL(0x2980014f,0x58f964fd),LL(0x7baccd46,0x2458a3d8),L_(0x00000059), LL(0x9360b528,0x9c8ef0d9),LL(0x8ec22b8f,0x99582fc5),LL(0x2b8aa8c6,0xd629663b),LL(0xcebbdb32,0x2ff405c2),LL(0xbd666f05,0x8989d659),LL(0x6c986174,0x2eb13e6b),LL(0x7fa4c2f5,0x5660e9a9),LL(0x30206c27,0xcd2e9b5f),L_(0x0000017c), + LL(0x970525d5,0x1b2c97bc),LL(0x3e8c6c5f,0x97ea6bef),LL(0xe6975580,0x1fa05de0),LL(0x45dcf226,0x28ce5e22),LL(0x6b3296e1,0xbc5ea09c),LL(0x355e867e,0x171e0d4c),LL(0x93a02b45,0xef953fca),LL(0x72562a6a,0x283e85d5),L_(0x00000050), LL(0x8028e2f9,0x00384cef),LL(0xc61925fd,0xb15e2b9b),LL(0x98c42ea4,0xe51f203e),LL(0xa9da7eaf,0x80b7c7d8),LL(0x00d05b8b,0xd0e8cb9d),LL(0x5b984aa6,0xe2223126),LL(0x97eb783a,0xcbd154b4),LL(0x60eeeb46,0x77d65106),L_(0x00000025), + LL(0x0193b1f2,0xecba5c8d),LL(0x4c52e9d2,0x1a2c0764),LL(0x084d971b,0x04071452),LL(0x5b00ba29,0x420810c9),LL(0xe37ace16,0x8726c12e),LL(0xfb3b3465,0x76e95cdb),LL(0xddb8f121,0x5a782ea1),LL(0xe1266546,0x9e91fb9e),L_(0x00000198), LL(0x5245f9b1,0xde0c16d5),LL(0xb01d1b1a,0xcdfa5a5a),LL(0x186cc016,0x907f643d),LL(0x951f20c1,0x19ce2692),LL(0x499758b8,0xa1e463db),LL(0xae173a15,0x1a60551b),LL(0x9960164a,0xa7db4dec),LL(0x5c5b509d,0xd9cec887),L_(0x00000054), + LL(0x21eaa3b3,0x16cce787),LL(0xd4a2fc01,0xa425fa18),LL(0xf155769e,0xaf00539b),LL(0x60eb1b90,0x688fdaf6),LL(0xfa6d7481,0xf34ab7ee),LL(0x4f289d5b,0x07dbb72e),LL(0x1e391abd,0xbc2da7ee),LL(0x95c48dba,0x566bd167),L_(0x0000003d), LL(0x43c9b589,0x9ce2304f),LL(0xd19a287e,0x13ab6992),LL(0x4405fdb4,0x96fa0864),LL(0x4139a060,0x41a760d2),LL(0xbccd999e,0x5ba64bc7),LL(0xb10009b9,0xd8deab9a),LL(0x984258d2,0x79776c54),LL(0x221ad688,0x10e8fea6),L_(0x0000004d), + LL(0xbd1cacd0,0x5b9e9b6c),LL(0x0d488b76,0x718de1b3),LL(0x479d6241,0xc5e08581),LL(0x835e01af,0x2980a85e),LL(0x5861c30b,0xb6dbc1d7),LL(0xa410ea56,0x2db982c5),LL(0xe2d1be8c,0x9bd416d2),LL(0x8b2c0849,0xff9c097a),L_(0x0000007c), LL(0x5bd1e957,0xbf3507bb),LL(0x84f97fa2,0x638f765c),LL(0xc3635cb6,0xddc089f6),LL(0xadab3335,0x03a11712),LL(0x45c1fc02,0x6d411e20),LL(0x92e35990,0x10bb8db9),LL(0x9c8fd9b8,0xa138660a),LL(0x9289131a,0x37f6b49c),L_(0x0000004c), + LL(0x5bc20fd8,0xa1146df7),LL(0xfdfcfffc,0x81511cf3),LL(0x23bc0f93,0x2b2a7c87),LL(0xdc82a234,0x03b40d7d),LL(0xa08a7dd1,0x710d66e6),LL(0x21695339,0xb2de413b),LL(0x70d88f9e,0xa639823f),LL(0x35b8b90e,0x023e9ff4),L_(0x00000110), LL(0x0c573ac4,0x67b34d07),LL(0x68b9df98,0xae385a70),LL(0x9e1b7b1b,0x69f1b285),LL(0xf3ca9831,0xacc09537),LL(0xd4b56b4f,0x9d566211),LL(0x5fe60450,0x8cabfe34),LL(0xfe548cc5,0xb714db58),LL(0x6edccbce,0x1b3de9cb),L_(0x000000f9), + LL(0xc323d062,0x3fb44e11),LL(0xd6d98611,0xf902dfd5),LL(0x894e506c,0xfd0b1d00),LL(0x85a52247,0x782247b1),LL(0xee7a96a2,0x73bd1827),LL(0x817a81ab,0xb5a675cc),LL(0x58e21da1,0x96f3b0ad),LL(0xba6b1f8c,0x0b4feab1),L_(0x000001eb), LL(0x2721b756,0x94e1e70f),LL(0xa2caaa6a,0xe4a5a160),LL(0xc595ff3d,0x4e2aab67),LL(0xc4ca75c8,0x55f145b7),LL(0x7731bee5,0xfc6003a4),LL(0xe7fe03b5,0x0bfb8f07),LL(0xc95ac06b,0x062bb217),LL(0x970ec8f9,0xa73aafef),L_(0x00000158), +}, +/* digit=55 base_pwr=2^275 */ +{ + LL(0x0e2b9a13,0x10edee70),LL(0x5fd3e47e,0x3597fca0),LL(0x77535436,0xd14d9e5f),LL(0x3e8b8ab9,0x09ae6cb6),LL(0x74096598,0xc8a4dd84),LL(0x9f1a5c96,0xcb6edd24),LL(0xd2f79af0,0x61d2b7a4),LL(0x0e166e53,0xfe3d22a6),L_(0x00000092), LL(0x995a329a,0xf72fa6f8),LL(0x96d7a363,0x488ad6e3),LL(0xd92f57cc,0x8510a286),LL(0xf0a9d195,0xb888aa8b),LL(0x317136c0,0xf42decec),LL(0xdf9fc71b,0xb6cc8b9b),LL(0xc0298d41,0x49e5d99a),LL(0x109ecbb2,0x314b57f8),L_(0x000000db), + LL(0x68b73573,0xb2d708c6),LL(0xce839038,0xce28ed96),LL(0x20e1ea62,0x8763eab5),LL(0xed2713c5,0xc4523fd6),LL(0x71027fe2,0x7eae1cb2),LL(0x9c4b8cf6,0x24a95e4f),LL(0x601ad020,0x07164949),LL(0xdd7d73ac,0x37442ffc),L_(0x00000043), LL(0x3ec84bf8,0xb77851b2),LL(0xdb8574d7,0xb645bbee),LL(0x286ebfe9,0x0c8710d8),LL(0x766e45ce,0xa79aecb4),LL(0xc2d31256,0xbf379f83),LL(0x340ea164,0x164bbbc5),LL(0xf851521a,0x1ac3081d),LL(0x7e9d5d5e,0xb205779b),L_(0x00000081), + LL(0xd2e1d746,0xde9114db),LL(0xe63af665,0x818c463b),LL(0x6295501a,0x35a127bf),LL(0xdce47ef1,0x007d2c0c),LL(0xcdab36d7,0xccb851cf),LL(0xfdd117a8,0xf238753e),LL(0x0f305c31,0x8e2817b4),LL(0x7fa2c0d7,0xf487e902),L_(0x00000153), LL(0x1fcbcf0a,0x170a9d8a),LL(0xfdab89fd,0xd0296988),LL(0xf7158579,0x9d9469d7),LL(0xe8a6f604,0x10415652),LL(0x2b54a37b,0xcc4eb51c),LL(0x0c719573,0xae48f5a3),LL(0xa83c1dff,0x30b12c01),LL(0x72dbb726,0x57308088),L_(0x00000172), + LL(0xc489ffe4,0x313e4b56),LL(0x08231734,0x6717f045),LL(0x479ae527,0xe3d436d8),LL(0xd02cb05c,0xf2257834),LL(0x00a63fdd,0xa7cf8043),LL(0x55acde6a,0x457f48d5),LL(0x3233d0de,0xde5db66b),LL(0x81aa55b4,0x0379d9ac),L_(0x000000a6), LL(0x067058f6,0x13e90717),LL(0xc47bead6,0xf2111132),LL(0x90e8a449,0xb92dfa6c),LL(0x2861c278,0x0e5052e4),LL(0xbb21a8a2,0xdd62ef7f),LL(0xda29cea2,0x06ce5d03),LL(0xb1054057,0x321921a2),LL(0x2bdda27b,0xa8070a21),L_(0x00000113), + LL(0x00c74bbc,0xb57fe1e1),LL(0x13d1fd3d,0xaf39e976),LL(0x9d300d5d,0x3c4bd73d),LL(0x394a792d,0x22ea164b),LL(0xdb8ad2a0,0x94ca8b71),LL(0x46b5c44e,0x29573de6),LL(0x4faada81,0xa68e6f0b),LL(0x9bb3e293,0x2829705e),L_(0x000001a5), LL(0xff57d0ed,0x562f24c2),LL(0x10d7ee7c,0xebc4c9ff),LL(0x1bfc2a5b,0x9e849995),LL(0x9ab67877,0x29bf2cd5),LL(0xebbab48f,0x1c14b040),LL(0xc34becb0,0x0f56d5be),LL(0xa06f84dd,0x74ea8bd3),LL(0x16998590,0x240441e5),L_(0x000000b5), + LL(0x5c45926a,0x99d23cf5),LL(0x8778f5f2,0xc8b025b9),LL(0x1705a5c8,0x3919b71b),LL(0x0d5b88f4,0xcb92372e),LL(0x60fa371f,0x943296e1),LL(0x0a89cc71,0x5fe1a497),LL(0x34a3ae69,0x5dec2f93),LL(0x1251e4b9,0x275a5942),L_(0x000000d6), LL(0xd859c11c,0xff47e08d),LL(0xaa12f1b2,0xad152f2f),LL(0xffb55ea0,0x2d49016e),LL(0x9565927a,0xe898a743),LL(0x6cdbde63,0x47e768ee),LL(0x9201bbe7,0x0a069ce7),LL(0x64e8832a,0x4d3af5cb),LL(0x22cff077,0x58cc25a5),L_(0x0000001d), + LL(0xdae36c68,0xb0b126b6),LL(0xaeabb8d7,0xc38359f0),LL(0x58505b26,0xb9091af1),LL(0xe930c10c,0x1baa2a57),LL(0x4ceb63b6,0xf34a1cb3),LL(0x2ce30eb5,0xe695563a),LL(0xb46502e9,0xbc4a4498),LL(0x3de11285,0x7d46bb82),L_(0x00000037), LL(0x31c841ea,0xd0a4132d),LL(0x4b0d3d99,0x19c65f2c),LL(0xbdec1fb8,0xe96bad16),LL(0xf98a7a22,0xfc740b98),LL(0x4ac9e432,0x327482c4),LL(0x19b02fa9,0xee365754),LL(0x2b71db69,0x8c4b6fcb),LL(0x3b059127,0x1ff3d7d8),L_(0x00000109), + LL(0xb46fd007,0x5b27f0e1),LL(0xc1b9a1af,0xc491a3f1),LL(0x3c2c754f,0x5cbaab1f),LL(0x2a77d316,0x0310665c),LL(0x760e6436,0xda6d64bd),LL(0xabfa1968,0xfb5f4ce1),LL(0x2b0e1701,0xb466c4ed),LL(0x7ed3c4d7,0x2ebf2125),L_(0x00000191), LL(0x2ef47a92,0x50f6e44d),LL(0xddd0d096,0x8ca37cde),LL(0xacd3234c,0xb7244def),LL(0xd39cba5f,0xacca56c2),LL(0x42e4fef3,0x04d3ff0e),LL(0xd03959e1,0xe6513498),LL(0x101ed923,0x40deadab),LL(0x3a0842e2,0x40cf65c5),L_(0x00000071), + LL(0x6ea80244,0x24abeced),LL(0x8027d5fa,0x54bd40b9),LL(0x6c207959,0xaeb9dac1),LL(0xd464b86a,0x419d1ea2),LL(0x6820d398,0x5e25c94d),LL(0x7cb4e131,0x65e1ca01),LL(0x407cd9e9,0xe5ede0b5),LL(0x9cc6a7e8,0xccfcd5ef),L_(0x0000012e), LL(0x8a46a1bf,0x38ae86f8),LL(0x198931f5,0xff746c8b),LL(0xd54d7f12,0x309a79bf),LL(0x1246b150,0x42f00081),LL(0x77449920,0xc47ea560),LL(0x3c1ca128,0x7f0d691e),LL(0x4a7cd82a,0x389f0267),LL(0x3325d3c5,0xd3d69318),L_(0x000000e6), + LL(0xa3cca92f,0xdc420de7),LL(0x40b5d961,0x0c56a78c),LL(0x0669c065,0x20ea2fcd),LL(0xd7d6512b,0x0cfdc1ce),LL(0x793f28c8,0x12dc4c42),LL(0x2a2c66b6,0x65ef14af),LL(0x8712d0f4,0x498de283),LL(0xaba3e10f,0xd43378b1),L_(0x000000ef), LL(0xaf2de227,0x29182339),LL(0x2743e625,0x75c8a0f5),LL(0x7cb967f9,0x3b942e5d),LL(0xa6fa495f,0x2c93c4c7),LL(0xaf911e44,0xe5ea4e81),LL(0x61393032,0x453b1c33),LL(0x6ad975cf,0xbd844374),LL(0x598fb85f,0x19bef583),L_(0x0000009f), + LL(0x9b9466a8,0xca0bf18d),LL(0xa3d7dbe9,0x4163c3c8),LL(0xfea7d95a,0xc8c760db),LL(0xbedeb961,0xbe4aaf54),LL(0x6366da72,0x184e2e0f),LL(0x4b391d6f,0xc176d3d7),LL(0xda402a6d,0x58e13d8b),LL(0x35c88b87,0x9e868f1c),L_(0x000001ed), LL(0x9fd8fa1b,0x060d87ba),LL(0x2fb088fa,0x7bb887ef),LL(0xd9fecef3,0x5f6918e8),LL(0xd8d0ab29,0x584e5e50),LL(0xa68549e0,0x1a0e8dad),LL(0xccee2619,0x6b94fb63),LL(0x2fe6d355,0x41620a75),LL(0x2f9f5687,0x3bbe2240),L_(0x00000024), + LL(0xa7583732,0x7b1c8a03),LL(0x5d3c5d98,0x9b0532ff),LL(0x8d28755f,0xa6811aec),LL(0x526696c9,0x1a05c762),LL(0x85c6fe67,0x9b509178),LL(0xb1cd9732,0x9ce1e435),LL(0xd6424b12,0xd25c0017),LL(0x7dfb69b5,0x8fd3449e),L_(0x000001bf), LL(0x45aa0fc3,0xdb3b3b47),LL(0x4f13caa8,0x8c65da30),LL(0xc42581d3,0xf1637449),LL(0x31ba26e3,0x086fb178),LL(0x1f20a375,0xe70bccf5),LL(0x794f66bb,0x8fb9ec67),LL(0x8759114e,0xba15c3e0),LL(0xbae55fef,0x6274e840),L_(0x000000b0), + LL(0x4b17f564,0x9940c688),LL(0xd17c3809,0x1ad4bb7a),LL(0x02bbb8e4,0x62901ee1),LL(0xdef212fe,0xf758e2a0),LL(0x902e165b,0x41df4c90),LL(0x813c93c1,0x2d980715),LL(0xdfe446b0,0x16925c07),LL(0x26180355,0x6a7e91aa),L_(0x000001e3), LL(0x97ef4ef8,0xa45e236d),LL(0xf8e5447a,0x116cff34),LL(0xe8d1be37,0x05f97032),LL(0xb0f21f66,0x2f2c027f),LL(0xa11df664,0xa89a55e5),LL(0x02fec70b,0x0cbe911b),LL(0x281dbb5c,0xf7515075),LL(0xff0a3fb5,0x5eb63dce),L_(0x0000017e), + LL(0x5eee65be,0xa91392a8),LL(0xbdba8a73,0x3162337e),LL(0x57c70feb,0xfe6064d0),LL(0x1cbf9841,0xb8ea5857),LL(0x0f9265ab,0x8f4d78e1),LL(0x4ea34ee6,0x86c61019),LL(0xe932bccc,0xa4d88afe),LL(0x9518b05b,0x1b666c9e),L_(0x0000007f), LL(0x59e8fd1b,0xf8bfc49e),LL(0x05208c75,0x9df54ae4),LL(0xd373c5a9,0x79933e71),LL(0x5b8a9772,0x64aa0b3f),LL(0xa96b6ada,0x636d2c0d),LL(0x5227ca04,0xc4142eed),LL(0x6e0ffb64,0x11d0f26b),LL(0x03baa051,0x6cce8a32),L_(0x00000049), + LL(0xf1fc721e,0x1b22c75f),LL(0xf889ab10,0x198462a9),LL(0xdc726c9f,0x4488dc01),LL(0x03497dbf,0x6173d9f9),LL(0x44668664,0xa2ec1a91),LL(0x97d57504,0xc515fce6),LL(0xe38e8b7b,0xc94145f8),LL(0x9a57e3c8,0x7f491462),L_(0x000001f6), LL(0xe3b58019,0xfab74bc2),LL(0x21aa76a0,0x5cde4de2),LL(0xcabcd328,0x58febacf),LL(0xfc5df376,0x164a8b43),LL(0x53cf2abb,0xd59cb6ca),LL(0x4bdbc3e7,0x5fa72448),LL(0x61888f39,0xec291663),LL(0xa63d2680,0x8efa4a04),L_(0x00000137), + LL(0x3aef952e,0xbfc44034),LL(0xda15115c,0x7be6519e),LL(0x4c0ca17c,0x1e404697),LL(0xd39b899e,0xd56cb968),LL(0xafaffc6b,0x977f25af),LL(0x0c48baa8,0x33c5e846),LL(0xb8ddcae7,0x8db3dd6c),LL(0xea4e7b4d,0x30c42ef0),L_(0x00000147), LL(0x6e0e9969,0x3bded433),LL(0x1c36485b,0x60a85776),LL(0x3a9ef9b4,0xc163b2e2),LL(0x9caea119,0x699c32d3),LL(0x6fbf2af8,0xc9afc21d),LL(0xb2f30acb,0x5cd46105),LL(0x2782e179,0xc5de1ebd),LL(0x94bd0296,0x40db331e),L_(0x000001f5), +}, +/* digit=56 base_pwr=2^280 */ +{ + LL(0xd75c1b45,0xb3566c4d),LL(0x70856265,0xffa63a05),LL(0xcbace31a,0x64645336),LL(0xd792b4ed,0xe49945b2),LL(0xcdc41c6d,0x4ffedb2c),LL(0xfc3fec1e,0xfb381239),LL(0x6c094341,0xb5868f95),LL(0xa828185b,0xf680572d),L_(0x000000da), LL(0xa2d876a6,0xbfe0585a),LL(0x480f8f0f,0x30bd3b95),LL(0x5be334d5,0xc2d3c86e),LL(0xd762f278,0x676d6c82),LL(0x1488b56b,0x539dec8e),LL(0x756194ec,0xc0fc3e4b),LL(0x4e5ad8a2,0xe01cce49),LL(0x1e1d4129,0x9cb7e94c),L_(0x00000045), + LL(0x1314c572,0x2ee172f7),LL(0x76d70712,0xcc86b737),LL(0x07937b43,0xc42e1bf4),LL(0x0a15775a,0xe0abab13),LL(0x8a6f4155,0x8a4930e5),LL(0x7af5f75c,0xe4d25a23),LL(0xf7ffdb8e,0x47745ba4),LL(0x1c8fe7af,0xda1f09c1),L_(0x00000067), LL(0xb90a6b8d,0x58ab833a),LL(0xbed40193,0x74f45669),LL(0x07b7fe4d,0x00a5516c),LL(0x8fed834f,0x35a36d31),LL(0x46f3d5f0,0xcf8a31bb),LL(0x46e1df3b,0x86c99729),LL(0xef24a7e8,0x383ab5e1),LL(0x3285864c,0x85a50c0d),L_(0x0000005b), + LL(0xd82688c4,0x82d65b66),LL(0x2c2925e3,0xc79d0387),LL(0x80fde81a,0xa2432027),LL(0xbc3a2b38,0xa34422b6),LL(0x24a6595f,0xb948d55e),LL(0x7ed8f149,0xfac14efa),LL(0x1011867c,0xe578bbe7),LL(0x01bd1e94,0xefa02765),L_(0x00000003), LL(0x88ed0039,0xc9f7389f),LL(0x4f58dfa2,0xd3bff99b),LL(0x27af2024,0xe0ca7fb1),LL(0xa09a0ca5,0x782dbf7b),LL(0x01098d83,0x19fa5d61),LL(0xabdbaa4b,0xddb85231),LL(0xc03b0d70,0xbb859499),LL(0x26cba60c,0x8d596ce3),L_(0x000001ba), + LL(0x11830fd3,0x8aec0422),LL(0xb67d56f7,0x85f0af78),LL(0xd0dd5f00,0xd1879493),LL(0xede77ef6,0xd412929c),LL(0x6254c309,0x2f8f47fc),LL(0x6cfbb6a1,0x4af63813),LL(0x0a561c30,0x70283e09),LL(0xb1640127,0xc77dd363),L_(0x000000e8), LL(0x1689c1a7,0x65973023),LL(0x29101040,0x7036678a),LL(0x6adb22ec,0x5919dc9a),LL(0xb9607eaa,0xff75ea6b),LL(0x2f103f0e,0xa1b15402),LL(0xc4300dcf,0xfdcf2e9d),LL(0x3ebbf1ab,0x1be47bf2),LL(0x3bc7610a,0xe48e43b2),L_(0x000000e8), + LL(0x079ff207,0xb1366222),LL(0xc255282f,0xcf45bdd6),LL(0xe5f65eaf,0x15c02959),LL(0x0d59b305,0xd5074c2f),LL(0x69d34def,0xf460bf31),LL(0x98c4daf0,0xcd4dd881),LL(0x2d35aae9,0xa3e2b924),LL(0xcd6f8fb3,0x7ee19179),L_(0x0000005b), LL(0xbdd26b48,0x3015c0c8),LL(0x24998853,0x9b18e9fc),LL(0xc27ee4ed,0x01ee8c44),LL(0x961e30d9,0x38c4d057),LL(0x4e4722a4,0x27a847d7),LL(0xbd34c3ce,0xfc175e9e),LL(0x9ec1f371,0x28ad6264),LL(0x9962cfa6,0x8cb8ba21),L_(0x00000025), + LL(0x61746f87,0x48414eef),LL(0x4b16d635,0x466a22f4),LL(0x91c53690,0xb9b4826e),LL(0xdfa700b4,0xba41d6fd),LL(0xa9d1c269,0x3f48b184),LL(0x9a1ae562,0x1d66af1a),LL(0x88445e2f,0x16e76216),LL(0x5528a0ef,0xa509e874),L_(0x000000a0), LL(0xf9d1f30e,0x4d16c4eb),LL(0x405c88d6,0xcb159002),LL(0x21995ea2,0x9206340d),LL(0xc1b476f5,0xbdb47138),LL(0x73c4a87f,0xf1fc51a6),LL(0xd81d7d81,0x68d2c132),LL(0x3035e2c5,0xc2e86c33),LL(0xdd1981e0,0x25fcaa15),L_(0x0000009f), + LL(0xa5dfb812,0x4ab2a49c),LL(0x70aadb7c,0x983438d3),LL(0x9f4ebf13,0xd25c9ac8),LL(0xd8d4d610,0x9c7f0f75),LL(0xca14e0b4,0xdcfed5c3),LL(0x4d6f7590,0x36f5cd7f),LL(0xd93cbfaa,0x65cb3d17),LL(0x1ddce79a,0xbd97f101),L_(0x000000b4), LL(0x87dd6cdb,0x8b012070),LL(0x77a85a51,0x279a4494),LL(0x7671964d,0xff88af2c),LL(0xf271d11a,0xdbb6c2c5),LL(0x82395ca1,0x85ba326b),LL(0x98f43101,0x0cb73c28),LL(0x63dc513c,0x6b203054),LL(0x4469f278,0xc5c18db9),L_(0x0000001f), + LL(0x36061c1a,0x3d80adc6),LL(0x4e403a26,0xab320624),LL(0xad04e1de,0xdcbb6130),LL(0x2a259720,0x6e850532),LL(0x231b1ad6,0xa60fb3f5),LL(0xcd79b6e2,0x663d49e1),LL(0x179c366e,0x01277eb6),LL(0xe6c6ea0d,0x883c4ffd),L_(0x00000073), LL(0xca5210dd,0x7e40167f),LL(0xaec71f68,0x9a231d95),LL(0x1c63bde5,0x4af79a44),LL(0xdec74dfa,0xfd79e68d),LL(0xa1952760,0x0b613ae2),LL(0x08e61ca7,0x9e73036b),LL(0xe30d2b54,0xd922e0f3),LL(0x6d8fb383,0x28c14621),L_(0x000000a0), + LL(0x6da7d675,0x1137f8e6),LL(0x66cf0839,0x9b11d642),LL(0xa909855d,0xc2008fb3),LL(0xcfac98d0,0x7141e8cb),LL(0xf021a4df,0xf143c405),LL(0xab358375,0x67bc2904),LL(0x17ae0177,0xcc509637),LL(0x3e96013d,0xa1e7d9dc),L_(0x00000049), LL(0xefccd8ff,0x957910b6),LL(0x497bb1a3,0x0139fb02),LL(0xbd519647,0xb1e83186),LL(0x3a05bf5b,0x19b27ed1),LL(0xcae014aa,0x82e975ee),LL(0x2c7c3285,0x88e9df86),LL(0x55efa48e,0xeb606052),LL(0x325f6177,0xa47eec1a),L_(0x00000161), + LL(0x6a4317c6,0x3a878798),LL(0xb073983a,0xb57577f3),LL(0x911ef229,0x88b3000a),LL(0xb6a2c941,0xfe60609c),LL(0x2014f532,0x505cb96c),LL(0x56c1e07d,0x4b65f80c),LL(0xacfa88b0,0x6d867481),LL(0xe4164f16,0x5599d374),L_(0x00000151), LL(0x92b10575,0x0c1e1e98),LL(0xfcb0b84f,0x19e6efb8),LL(0xb9207b90,0x51572182),LL(0xa8d8dbea,0x3bef29fc),LL(0x48664299,0xf1204f85),LL(0x601bc4d3,0x0e9a0fd0),LL(0x04ed7b5b,0x79ce5a54),LL(0x2efbde9a,0xa61da12c),L_(0x000001bd), + LL(0x452d878f,0x50fecf46),LL(0x92f8cb5b,0x920174e1),LL(0xf0d81ba1,0x1067e00e),LL(0xdf0090d3,0x0f944d92),LL(0x7cf84daa,0x29760c45),LL(0xe2fe5c35,0xdcd64aa5),LL(0x0fc3d3ab,0x926c41d9),LL(0xd093a0e6,0xf508ca71),L_(0x0000017a), LL(0x1dd9cd99,0x2ec2b366),LL(0x41b5fe84,0x68d89f52),LL(0x6a8252ee,0x7f37105c),LL(0x12bfbd7a,0x28e7afdd),LL(0xa8c8a6ce,0xc9ac312b),LL(0x64f59820,0xfc0802de),LL(0x91abcca1,0xdd3daa77),LL(0x3663e8e4,0xcba87568),L_(0x00000067), + LL(0x98711310,0x167f86e9),LL(0x77ecbc5f,0xb273c517),LL(0x1e1c4580,0x7b0cac28),LL(0x7d9e9af5,0x8231d2eb),LL(0x6aedfd99,0xaaffb728),LL(0xf1c98f12,0xe925ce44),LL(0x74f1520c,0xc049eb63),LL(0x494b788d,0xd9d95935),L_(0x0000009f), LL(0xc317b32d,0xccc2d2a6),LL(0x0b127e1a,0x3b751841),LL(0xcd70c11d,0x64418006),LL(0x1b4ae955,0xbadb0a24),LL(0x604cb635,0x9f330b20),LL(0xcfd3da79,0x73a90953),LL(0xef2d17df,0x1b20635f),LL(0x4743671d,0xd4c67374),L_(0x000001ab), + LL(0x12cdd2a6,0x9ec2635a),LL(0xbc72074c,0x1fe4598a),LL(0x2c820e92,0xe36ea0ca),LL(0x2497dd7b,0x4a8623f2),LL(0xe23eb8d9,0x60085b98),LL(0x40f9b504,0x1c20ee53),LL(0x201ec927,0x00761ac1),LL(0xd442c9fb,0x4f448cc8),L_(0x00000026), LL(0x820146fb,0x6e43f9a4),LL(0xccd45383,0xdd223c39),LL(0xe5a9e554,0xb7183f2b),LL(0xbabb5193,0xcaf50569),LL(0xd8970128,0x1fd8dbce),LL(0xa8d54145,0x334b381f),LL(0x13a9b729,0x728ba78e),LL(0x437dd328,0xd0616bed),L_(0x000000a9), + LL(0x5533acf3,0xaa17f0bc),LL(0xd2eb9fb6,0xcdb03b75),LL(0x6da41301,0xff96e100),LL(0xd003b0fd,0x0f341e2c),LL(0xeffd7580,0x00a92b40),LL(0xb4e94e73,0x2f420bab),LL(0x7e020897,0x3a5a980e),LL(0x0e9d7689,0x44d12101),L_(0x00000198), LL(0x4d880aed,0x2631776c),LL(0xf32bcc90,0x4363aa54),LL(0x81eb128d,0x290c3760),LL(0xc99f8366,0x24d51de3),LL(0xa9c8e087,0x2212897d),LL(0x63ef80d8,0xe1731f84),LL(0x4ba53d2d,0x71a09c6c),LL(0xf3c92c58,0x1de91d0d),L_(0x000001ba), + LL(0x1f13ee5a,0x007f0db0),LL(0xfc29c9c2,0xc5a04df7),LL(0x7ce23069,0x889ac9f2),LL(0xabf8339c,0x48b685ae),LL(0x57639632,0x3111646e),LL(0xf8b9f075,0x94f37131),LL(0xb2897670,0xf80a60f0),LL(0x834d23a7,0xeca2d9a7),L_(0x00000028), LL(0x3b936a84,0xc94b1130),LL(0x12c12cdf,0x7f1285c7),LL(0x53433711,0xa3fdb413),LL(0x6c9aab37,0xd50e87db),LL(0xc28229bf,0x6e31c080),LL(0x9878eb5e,0x647c7885),LL(0x6255df90,0x3c367034),LL(0x64a27e7b,0x359e7554),L_(0x0000010f), + LL(0x90855e35,0xc3090e22),LL(0x856faf70,0xcf9c3c63),LL(0xa537fff7,0xd0317a7a),LL(0x61c02007,0xdc853b32),LL(0x61687510,0x36ccdf2c),LL(0xd6f188d5,0x26fd385c),LL(0x2955fa1d,0xf2d7d6ea),LL(0x3087bdae,0x3173148e),L_(0x0000010f), LL(0x54216ede,0xd784c9a2),LL(0xc0770de6,0x4bf8c47c),LL(0x35e4c8fa,0xaece660d),LL(0x8910f637,0xedb7b99e),LL(0x5ced4fad,0xa82ce72b),LL(0x0fa07446,0x15701d4d),LL(0x94600c85,0x4152f301),LL(0xf34ffcea,0xf31c15ed),L_(0x00000096), +}, +/* digit=57 base_pwr=2^285 */ +{ + LL(0x31bdcc84,0x3f5b1c78),LL(0x7bafc7d2,0xbe5d1d02),LL(0x50c19efd,0x3cdce225),LL(0x5357a753,0x3af279d2),LL(0x14412057,0x76015a5e),LL(0x57141209,0xc91c803b),LL(0xb203384a,0x12ba72de),LL(0x2bedd680,0x825c3d8d),L_(0x0000011d), LL(0x39f8385e,0x6423553a),LL(0xeaf27fe1,0xef9335b8),LL(0xc4539fb7,0xfa5830e5),LL(0x66badc9f,0x0a5e5034),LL(0x1dcbb895,0xd3a2a96a),LL(0xa62dca0d,0x8a881a89),LL(0xd5f98db4,0x06e0a311),LL(0xe2554b95,0x69efeec8),L_(0x000001cd), + LL(0x8352945a,0xb00f4f23),LL(0xd445a023,0xdd54cf07),LL(0x551441ad,0xe62fb5bf),LL(0x33408f85,0xd275f3aa),LL(0x1f4e87ff,0x701eb4ed),LL(0xb08c2f8d,0xcbec0af1),LL(0x3b5987fa,0xf0bc3119),LL(0x37542336,0x219a8c12),L_(0x00000187), LL(0xae724bcb,0x5d52f04d),LL(0x1a68b0a5,0xd5fa5e22),LL(0x5bdff6f9,0xda24e831),LL(0x9487e3f2,0x8b43c649),LL(0x8cc54962,0xca393f54),LL(0x934d621c,0x52e8acee),LL(0x0ce12d1b,0xf0e6025e),LL(0xcb0b93c4,0x16663ffd),L_(0x00000171), + LL(0xb7086292,0x5de71627),LL(0xf54385d8,0x8b05712b),LL(0x7bb4ab47,0xcc6b5489),LL(0x5a9a3b2c,0x7fa6f6a0),LL(0x3bfef8f6,0x773cd523),LL(0xf505a80c,0x5c9cc4c4),LL(0xa3fe8c18,0xf37ae336),LL(0x6259e110,0xb440dc7a),L_(0x0000014c), LL(0xc7b0e1ec,0x1e50c98b),LL(0x4b379333,0x4a8aa5a0),LL(0x3b8d3103,0xc900df01),LL(0xc99c95da,0x52027ee1),LL(0xb891a1fd,0x4b5be3ae),LL(0xb6857422,0x5ba842f3),LL(0xe00bb37d,0x3f36375a),LL(0x13a7f31f,0x04743a28),L_(0x000000c3), + LL(0x37e819c9,0x69c14cb5),LL(0xb3bf6b75,0xa0bac5f2),LL(0xcc275187,0x6c2d559b),LL(0x0eb925ef,0xa5453338),LL(0xd0382a25,0x119f0d6c),LL(0xbbf74a02,0xaf681433),LL(0xbd994d4c,0x53999a9b),LL(0x8d27772c,0x249226a3),L_(0x000001af), LL(0xb493127b,0x796a46b5),LL(0x887c8f77,0xabbf7bee),LL(0x45dd063e,0xa0a8e117),LL(0xea429199,0x8d22e28a),LL(0x7e69a991,0xb0ecebe7),LL(0xb0ed2dea,0x0edf7cec),LL(0x37aa98d2,0x0e528886),LL(0x0ca19479,0x73078fbd),L_(0x0000000c), + LL(0xca9fd702,0x1809c965),LL(0x4cbc62e0,0x5c062be1),LL(0xeaea9560,0x1162dcba),LL(0x07340ec9,0xcf90fad2),LL(0x6f6f4573,0x8b6c2347),LL(0x41df3d0b,0x4bc4f7c5),LL(0x6aba94c9,0x9ce77c5e),LL(0x25055fe2,0xb9dd3d1f),L_(0x00000193), LL(0xedcc2ca4,0x6e430120),LL(0x31a5bf9b,0x31ef29c8),LL(0x4ea14b33,0x1451c355),LL(0x3d7a4759,0x515170ed),LL(0xc3011219,0x21413d55),LL(0xb375db75,0xacf6ce68),LL(0x846f6627,0x2facb2b3),LL(0xdee7b99f,0x3ead4f94),L_(0x0000004f), + LL(0xcc95dfa0,0x4f0117ae),LL(0xd22f1814,0xe3424149),LL(0xad5ce6fa,0x58b2d2e6),LL(0x70e2e877,0x5de9d268),LL(0x6eb2a9a7,0x6da54502),LL(0xddee04cc,0x3079a618),LL(0xaa37f095,0xef9c41ec),LL(0x0ab072b7,0x4f475d8e),L_(0x00000182), LL(0xb095050c,0x139a7b97),LL(0x482e5296,0x56474127),LL(0xc87e2a1d,0x0fe9253d),LL(0x4757efac,0xbdc55bb0),LL(0xaa65a406,0xfb5b47e5),LL(0xfa5b9027,0xd99ad5b0),LL(0x1f6adf92,0x3a4363de),LL(0x6339348e,0x6d9cf0af),L_(0x000001fa), + LL(0x3a106eb8,0x926c08a5),LL(0x58be047c,0x00018285),LL(0x4ede436f,0xb7c0f8da),LL(0x267d40d4,0x754e0583),LL(0xf821bcca,0x29b55f1c),LL(0x356838ff,0xef10fd05),LL(0xd3bb98d7,0xbf4cd160),LL(0xcf20597a,0xfe3d8718),L_(0x00000039), LL(0xd50f20a2,0xbe1a541a),LL(0x2ab231ad,0x833de73e),LL(0x3217ac39,0xde117a87),LL(0xe86047c6,0xa460f6e7),LL(0xbf61ad63,0x3e4086cc),LL(0x10646884,0xeedbe45c),LL(0x97bd568e,0x9c11e90d),LL(0x23655180,0xb96c7748),L_(0x000000ca), + LL(0xa8697eda,0x469af391),LL(0x5bb73205,0x3f5f97fe),LL(0x80d05ad0,0x73b1a3ca),LL(0x00af9b79,0xb52add98),LL(0xcc82c533,0x93cc487c),LL(0x0da2ae06,0xe46cf71a),LL(0x060c7047,0xaeb64abc),LL(0x3aa21503,0x0075b1d3),L_(0x000000ed), LL(0x12985515,0x29a2bed9),LL(0x9a79f6b1,0xda4630c4),LL(0x22374a19,0x62f001a1),LL(0x90a13059,0xa3cc4dcc),LL(0x026cefa3,0xb188b4cc),LL(0x0fbb1d3f,0xad092ff3),LL(0x36e3761c,0x6354b93c),LL(0xf3dbdbdc,0xb73317cf),L_(0x0000012a), + LL(0xda4d56d5,0x478cc5ff),LL(0x39f6b453,0x4e6379ca),LL(0x063068cd,0xe4f74a40),LL(0xdb751bed,0x94052b38),LL(0xb0c9cab3,0x8ee4c1e6),LL(0xf5c6aa29,0x3ca0dbb3),LL(0x4a2497c4,0x79c6ee9a),LL(0x9ea63ecb,0x00e2354a),L_(0x00000188), LL(0xe4a480ce,0x3a6196f9),LL(0x62b157a8,0xfa37ba58),LL(0x59648d99,0xe7f1758b),LL(0x1b51e49d,0x2e82eb6d),LL(0xbcb59206,0xc0686a28),LL(0x337d156a,0x6197f5d2),LL(0x69bbd81d,0x9b64ab0e),LL(0x45283587,0x8e4d1a8a),L_(0x000001e8), + LL(0x8fd25f3f,0xed1f56a5),LL(0xe00396a8,0xc29bf98d),LL(0x671ac7e0,0x61a8021c),LL(0xa76a8082,0x40244556),LL(0x85eaf05e,0xd4493c4b),LL(0xacc79ffa,0xf3dd2e24),LL(0xa065de83,0xc2899229),LL(0x616b4043,0x26ec1649),L_(0x0000015b), LL(0x8dee69e1,0x177b6d5f),LL(0x5bdfa715,0xbb1b8e86),LL(0x1c8a38c6,0x673dccd1),LL(0xb8eb3119,0x26507bdf),LL(0x5e9ab066,0x52444c41),LL(0x63e06aca,0xc41d72f8),LL(0x6233cfed,0xf0a4cf0f),LL(0xa4204c93,0x2e510168),L_(0x0000002c), + LL(0x02f56d78,0xb9ae2c20),LL(0xa8e73672,0x60eb4910),LL(0x76d9acc7,0xef341ec9),LL(0xf8c3ff90,0x71631b58),LL(0xc5d46ddd,0xf784f3a3),LL(0xaca2efa5,0x9fd6ccc9),LL(0xb432ab0f,0xe0c19b00),LL(0xe9336780,0x8e4851bc),L_(0x00000077), LL(0x763901d3,0xeb8a4214),LL(0x1ec45488,0xab894d10),LL(0xb3592330,0xfe84be74),LL(0xea5cac9d,0xd6ce52df),LL(0xd6fc5829,0x52b83766),LL(0xada3c1ed,0x6e5007f8),LL(0x07f9020f,0x9dc77e51),LL(0xf5261fb1,0x3d52bde6),L_(0x00000176), + LL(0x61e0b43b,0x9c19cb9b),LL(0xa33466a1,0x59900a19),LL(0x2eeef601,0xd1a35b61),LL(0x70079dee,0x043f6bdc),LL(0xcd5ea5fd,0xc0119db9),LL(0x3a3b272f,0x5b2eb1b8),LL(0xe45f974f,0xba8b6e51),LL(0x5f770445,0xd0419f04),L_(0x000001b4), LL(0x8f1c3e6a,0x4b8a6a2f),LL(0x21c82a7e,0x356eb5d6),LL(0x1f805802,0xc510787f),LL(0xb2d54598,0x678fa9fa),LL(0x14375d0b,0x27fba413),LL(0x6ed82aca,0xce44cfc3),LL(0xbe259313,0x826f662b),LL(0xdd1eec94,0xc3f7e810),L_(0x0000010e), + LL(0x451f3fda,0xafd7f180),LL(0x784a36b9,0xa71f98dd),LL(0x55359374,0xb80637d2),LL(0xeb356304,0x319eb954),LL(0xe36b826f,0x6caacbc8),LL(0x5436ed41,0xc8f9a6b4),LL(0x1ad27bfc,0x05822de6),LL(0x66b9e6c5,0x6448fc9c),L_(0x00000061), LL(0x1be571ae,0xd306ac81),LL(0x92fe9fac,0xdda81241),LL(0x90144259,0x08d31ec6),LL(0x70a69700,0x59532bbb),LL(0x548a4797,0x25db5e1c),LL(0xfe84a6c9,0xdb376141),LL(0xd82e648e,0xaf5e43aa),LL(0xd86080c6,0xa3c129c0),L_(0x00000047), + LL(0x16e20146,0x2343be89),LL(0xd0ffaccb,0x1cb1ffd2),LL(0x3a03a0c7,0x899f4ff5),LL(0x6266f542,0x5f5c983d),LL(0xbcc25c41,0xcccfd128),LL(0xdfd7dc3b,0x971841bb),LL(0xb315e6d3,0xab458be6),LL(0xf423c907,0x18de71ba),L_(0x000000e5), LL(0xe2e17f1c,0x8643db82),LL(0xdf24bfc8,0xae140a96),LL(0x7d249f93,0xcc1b0809),LL(0x4a944e10,0xbb9f2bb4),LL(0x2cf2ab30,0x2a9df9a6),LL(0x3e7a3348,0x8877de2f),LL(0xc1bae4c1,0x6e777963),LL(0x95df6e0c,0x12289ec3),L_(0x00000076), + LL(0x1a1f2092,0x84f63e6e),LL(0xb92016c3,0x9065995b),LL(0xcfc7edd3,0x7e853e34),LL(0xe921ec35,0xe5b9d192),LL(0x48df779c,0x22c1257c),LL(0x2377e36c,0xc67f15b2),LL(0x2dd7559c,0x56741ee4),LL(0x8133583f,0x266292d1),L_(0x00000077), LL(0x28b3ff2a,0xcd5b0dfd),LL(0xd6ec8a55,0x0e18cbd7),LL(0xa02b3661,0xd0b4c82b),LL(0x54051775,0x2328d0e9),LL(0xa2bff3fb,0xbab00086),LL(0x8724078f,0xf6183452),LL(0xe2d3f99f,0x1d9f7aa2),LL(0x3419a97e,0x6878b1f4),L_(0x00000013), + LL(0x5635e4e9,0x6c03f366),LL(0x7fd85da2,0xd5f694e1),LL(0x52fd006e,0x2f043a61),LL(0x51032d25,0x8bc9cc74),LL(0x9348d55c,0x6f5370ca),LL(0x56333c4c,0x3610540b),LL(0xc9a5ca53,0x716d25cb),LL(0x39d8071b,0x7337f70a),L_(0x00000036), LL(0x387c11b0,0x97db6fc5),LL(0x3251b143,0xdb755cfd),LL(0xd84aa2bf,0x0cc3e62a),LL(0x9e9e3810,0x6071f1f8),LL(0xe47fb104,0x3e7012d9),LL(0x97ec5c7c,0xf6c7e6ad),LL(0x98bc4de4,0xa4e7cef6),LL(0x240c6a07,0xa03a3a12),L_(0x00000198), +}, +/* digit=58 base_pwr=2^290 */ +{ + LL(0xdddd94b7,0x7663b161),LL(0xc93f0cc5,0x071af3d7),LL(0x22d6ac11,0xb9149bdc),LL(0xe6312d84,0xe44e4632),LL(0xc50d4c88,0xc448cc8e),LL(0x6c85277a,0xbfe4f89a),LL(0x128700ea,0xa38e5f2e),LL(0xb742928e,0x3e261880),L_(0x00000029), LL(0xc113b689,0xfa51028c),LL(0x9b6a14e2,0x09549191),LL(0x82dfd5da,0xe13022a3),LL(0x233ca662,0x96fafc24),LL(0x505fe429,0xa18dea4f),LL(0x96182166,0x15ea5a2d),LL(0x199ba558,0x22a4ac80),LL(0x33772326,0xb13c3b81),L_(0x00000111), + LL(0x46be575a,0x215bf15f),LL(0x61cb09c8,0xe5912a10),LL(0xae2de789,0xd84851c6),LL(0xd74ceccc,0xb95ccd21),LL(0x6a285101,0xd32dddf2),LL(0x0122d3f6,0xdb554921),LL(0x02c5d952,0x96a4aa1f),LL(0xb24be997,0x8cde88aa),L_(0x00000007), LL(0x0855f9f8,0x2cd753b8),LL(0x88aff9b9,0xcc49d782),LL(0xf7cdce61,0xdac4e445),LL(0xfad48cc3,0x0ac2a937),LL(0x956fdfcb,0x98c5bdda),LL(0x81841ce2,0x9f12bb3e),LL(0x170e6c81,0xcab58ad5),LL(0x30efd73e,0x76a3a481),L_(0x000000f4), + LL(0x17b9123c,0x361c2c61),LL(0xb9e4b6ab,0x810de58e),LL(0x3d0db7a6,0xe085a8d1),LL(0x45a31ec7,0xa7bb9df2),LL(0x35378c99,0xd8933f30),LL(0x186da525,0x1033d24d),LL(0xddb7a3b3,0x8af19819),LL(0xb5c9012c,0x57d17203),L_(0x000000c1), LL(0xe7a75fd6,0xce3ccda4),LL(0x41697bbe,0x5c6d7a27),LL(0xb8be57fb,0x1fba9fbf),LL(0xc562ecca,0x9a3fed12),LL(0x1bcd8090,0xf597a3fc),LL(0x74a6954d,0xce4e5ded),LL(0xb4910fbc,0xa5ed9cf8),LL(0x79902452,0x9c77346d),L_(0x00000177), + LL(0xc67a3c57,0x3a4f332d),LL(0x3d82a438,0x56af6321),LL(0x0fc06213,0xca05acfd),LL(0x8864ca32,0xe80103ea),LL(0xc2e9c7c1,0x99dd0ff4),LL(0x4c64b758,0xc9889d76),LL(0x80c128a8,0x881a1256),LL(0x77fdb7cd,0xf09f58ad),L_(0x000000c5), LL(0xcda86d61,0xc6ecd4f9),LL(0x41a633a8,0xecb1fc4c),LL(0x847c2f58,0x92dae51a),LL(0xa7d7b295,0x268f50e3),LL(0x3b5eef6e,0x3a27de2a),LL(0x0d7a599e,0x14916d54),LL(0xd01f9b57,0x204fbca0),LL(0x675e52e5,0xeb48615c),L_(0x000001d9), + LL(0x76250214,0x0a639042),LL(0x0fd5737f,0x31d2eb63),LL(0x801bd86d,0x85ffa7ea),LL(0x1011c35d,0x8d043e51),LL(0x1ef5b87b,0xcb405068),LL(0xec30dbd9,0xc20daf68),LL(0xe48310c1,0xcee24a41),LL(0xa65b8aca,0x119d1da9),L_(0x0000008e), LL(0x58c134d6,0x716e9def),LL(0x8b2825b1,0x5d82926b),LL(0xb4cd0082,0xe1a8a7c8),LL(0x6474e309,0x12620e3a),LL(0xb0da6f90,0x2d673d4a),LL(0x574adf3d,0x628b88b6),LL(0xb210b971,0x9d1b96a3),LL(0x6b2d573e,0xedcd56fc),L_(0x00000081), + LL(0x9d453d01,0xe07f6e9e),LL(0x0f0b6a27,0xa4a6f307),LL(0xddeaaa37,0x9c430a1d),LL(0xeacad6b5,0x9620fd47),LL(0x9a8128c0,0xf279790d),LL(0x3bf5952b,0xfb97ad6f),LL(0xe0561485,0x0fe7692a),LL(0x482c591f,0xe268f3cb),L_(0x0000017f), LL(0x0807b886,0xdb21bfbb),LL(0xde3dc674,0xdbf154f3),LL(0xf4401caa,0x32e63083),LL(0x462197d4,0xb9452cf6),LL(0x46240ddd,0x10344368),LL(0x1c6dbfe6,0xa986f17f),LL(0x94ccbb69,0x4632a20c),LL(0x3f6277d7,0x33029382),L_(0x00000197), + LL(0x0b3dd856,0x2b718a28),LL(0xd8752e23,0x65e87e31),LL(0xa158249b,0x88c3f123),LL(0xff7b1118,0xd9121432),LL(0xbe4461fe,0xa0850e4f),LL(0x9ef5bc2d,0x6350e71c),LL(0xf28780a7,0xc6dabd80),LL(0xfc8f574b,0xc3c266b1),L_(0x00000143), LL(0x007b740b,0x13bf6ff9),LL(0x7db218bc,0x9d000699),LL(0x0dec75e5,0x7cf7628c),LL(0xb95f2df4,0x2fa7aacc),LL(0xe8ff9a7d,0x96555722),LL(0x1076129b,0xa11a1984),LL(0x57afac1e,0xfd1e9ec4),LL(0x16d64a31,0x008b70a7),L_(0x00000032), + LL(0x67420c4b,0xb0d9eaa8),LL(0xf5caa2dd,0xddc322f7),LL(0xc31038c0,0x08fb4b57),LL(0xa651596a,0xd9ca6980),LL(0xab32e2a6,0xc95c78a8),LL(0xe5808eea,0x5a32ba78),LL(0xf5f9923d,0x3bbece34),LL(0x26ad1c8d,0x8f8b8459),L_(0x00000109), LL(0xbeef787c,0x16843645),LL(0x8875d753,0xa90e9fa2),LL(0xe13608c5,0xaf90c364),LL(0x57e5556e,0xcc40e058),LL(0x9e332dda,0x9c5012b5),LL(0x2b76768f,0x8a76230b),LL(0x2932d53c,0x573bdff3),LL(0x14999fbd,0xeee93001),L_(0x00000040), + LL(0x9092892f,0x1a3f60e5),LL(0x7e88fc70,0x29625c0d),LL(0x396b1851,0x610e5833),LL(0x947ef062,0xd8dd1f5d),LL(0x47f1a571,0xa0f65294),LL(0x7850d950,0x49f087e9),LL(0x22c8e733,0x18807434),LL(0xce5508b2,0xd0fc8fca),L_(0x000000a0), LL(0xc40adf60,0xc3d1360f),LL(0x69072d8a,0x8b9d1e81),LL(0x8cba6305,0x01ed34a6),LL(0x7a1a3844,0xbc37f296),LL(0x20c61572,0xd409e84e),LL(0xd54640e7,0xeb6c948c),LL(0xc9243fc3,0xc754fba2),LL(0xb39c9166,0xc28f4f28),L_(0x00000182), + LL(0xfb5d6f5a,0x32c7f33f),LL(0xa0e6751c,0x47474b7e),LL(0x7f265069,0xe1e4a2ce),LL(0x0460d889,0xeab5839d),LL(0xb51b9a7f,0xe7cad388),LL(0xa5032a25,0x46ee855a),LL(0x6621ee7b,0x16fbfccf),LL(0x5a6f1501,0x73af1329),L_(0x00000175), LL(0x070dcac9,0x694e09ae),LL(0x0646542a,0xaceb179f),LL(0x27a867a4,0xeb30df16),LL(0x14cf3975,0xf9d85fe3),LL(0xa18e96b2,0x37e6f97d),LL(0x7781a0f2,0xb09bd1ce),LL(0xa8de0b13,0x278a1089),LL(0xc3a91cf5,0x02296583),L_(0x000001f9), + LL(0xbdb5de67,0xeca2c791),LL(0x86fe1661,0xd1c18fea),LL(0x4aedcbc7,0x3f879f46),LL(0x0545d544,0x4cb96993),LL(0x95120a10,0x595026f4),LL(0x1d335198,0xc959c824),LL(0xa814ec2a,0x8fbede3e),LL(0x0e062b6d,0x3832b5b2),L_(0x00000086), LL(0x78dc0113,0xfad2bbc3),LL(0xcf89249c,0xf01f3803),LL(0x63266c42,0xb86898e0),LL(0x685db0a5,0x3becca8e),LL(0x7e4eaa63,0x3ec31fe1),LL(0x90fcf86c,0x394a64f7),LL(0x967f0628,0xc6f81bcd),LL(0x635c81b7,0xec462896),L_(0x00000158), + LL(0x3f6901a6,0x67236236),LL(0x67484461,0xdb36fbe6),LL(0x5f5c47c0,0x9fb54024),LL(0x71f2fbb3,0x44525a78),LL(0xbedf63e3,0xe71375bd),LL(0x9f085fb8,0x47d50bd8),LL(0x1c59b6e6,0x2f2ea430),LL(0x578031fa,0x58012b66),L_(0x0000019b), LL(0x48eca8dc,0x473015fd),LL(0xfde2151d,0x9616e82c),LL(0xe4d908c9,0xd4ec3b2f),LL(0x04a04977,0x13df9ad2),LL(0x3ee923f5,0x2b66641e),LL(0x175bb5d9,0x0fcd9df2),LL(0xcdb5c3c9,0xfac57254),LL(0x7fde8809,0xc6981a62),L_(0x00000185), + LL(0x89022a23,0xb19296e9),LL(0x9d659d99,0x6d5aa5b9),LL(0x489a28d9,0x5422e69c),LL(0x5cf35829,0x06993c4a),LL(0xed0dce41,0x4bccea69),LL(0x21d11ff6,0xa2e82c7c),LL(0x44f73388,0xda3168f8),LL(0xf6117d7c,0xdff018c7),L_(0x0000007f), LL(0xc2227980,0xeb022661),LL(0xe965ba34,0xfeff852b),LL(0x1a68518b,0xbe9a9ee4),LL(0x53aa84d0,0x31f46a2c),LL(0x112327ea,0x6855b874),LL(0x06311411,0x43d26e75),LL(0x7348f329,0x65628948),LL(0x0582ac08,0xe3244339),L_(0x0000001a), + LL(0xdb77778a,0x5a842868),LL(0x12b97327,0xd4a2fefb),LL(0x8f7a410f,0x84c0e584),LL(0x98e19862,0x3fbe93da),LL(0xe566e4f8,0xe44a9540),LL(0xec1d03a0,0xa377131e),LL(0x1b99313e,0x27336d2c),LL(0xc15f4f38,0x8c27d958),L_(0x0000009e), LL(0x7c38c847,0xe75811d3),LL(0xc54aa0e8,0xe1cbcf6b),LL(0xc195aaf4,0x5596682f),LL(0xe98a5845,0xe0cf229c),LL(0x70256db2,0x5a921b26),LL(0x10d830e7,0x37fc26fd),LL(0xe3def649,0x16a810c8),LL(0xdb834a77,0x613433c1),L_(0x00000034), + LL(0xd8bd0a2c,0x7624b24b),LL(0x7db58054,0xabebbd07),LL(0x20618f15,0x3a5e2752),LL(0x72097df2,0x4f72e3fd),LL(0xf79b4cba,0x6f03686a),LL(0x3cfd9643,0x2d89778e),LL(0x683c4a14,0xeade01a4),LL(0x7cca2771,0x533fd14a),L_(0x00000168), LL(0x182d4838,0x5f84ba35),LL(0xb97b68e1,0x4e0b9bd1),LL(0x6e47fe3d,0xcdba9cfa),LL(0x3026f026,0x6e415889),LL(0x057de03a,0x7c12c31f),LL(0xa54231cf,0xcdfae481),LL(0x68a6cb37,0x3908080c),LL(0x259ee9d4,0xa3c797b1),L_(0x0000009c), + LL(0x25864119,0x021a0d91),LL(0xd49fbe57,0xde5b21b0),LL(0xbb57b277,0x7291e7e7),LL(0x1e6a4b2d,0x16da29ce),LL(0x4426f88c,0x68f8b71f),LL(0x6a6ebaff,0x9995fbf7),LL(0xab510adb,0x6ec18d2c),LL(0x8d4b996a,0x3ce11f1f),L_(0x000001bc), LL(0x1321f3ca,0x8e04c405),LL(0x34703d79,0x6b0a33af),LL(0xdd55e68b,0xb14161e8),LL(0x4737f09c,0x57558d9c),LL(0x90c00b53,0x9d9a485a),LL(0x508e73fc,0xbb09dac2),LL(0xd252e5f5,0x4ba2132e),LL(0x33b1efcb,0xc58bf239),L_(0x00000193), +}, +/* digit=59 base_pwr=2^295 */ +{ + LL(0xaba36d21,0x5b781a84),LL(0x584291d5,0x6ea73ad7),LL(0x992c0a26,0x20e9954c),LL(0x169e02af,0x4d73d175),LL(0x2718e0ca,0xe1612ee1),LL(0xed50926d,0xc638cf1d),LL(0xc1060d91,0xb5998df8),LL(0x4b7dc332,0x4eb7dc88),L_(0x00000062), LL(0xaadf4bca,0xd78eae21),LL(0xa9f4bf2c,0x372725c2),LL(0x86c74c6b,0xb5b5158f),LL(0x736a4de4,0xba4800d6),LL(0x451f4693,0x5138590e),LL(0xd2239cb9,0x6f5d263e),LL(0x45bdc4c5,0xc0f8acf5),LL(0xd06676d4,0x8bbd0743),L_(0x00000003), + LL(0x04c169d8,0x714fe80d),LL(0x2da244cb,0x06f04145),LL(0xcda8b722,0x84ee9fa6),LL(0xc3d58870,0x0e111da7),LL(0x1c267392,0x53bb35ef),LL(0x906e57c4,0x6a858e61),LL(0x3eebaa20,0xf4582387),LL(0x20dd3b5b,0xcf71c4a7),L_(0x0000015d), LL(0x81e2955e,0x91605cdd),LL(0xe98756fb,0xcda7aac0),LL(0xf0286c4c,0xb4372718),LL(0xa4017819,0xdae0a5d8),LL(0x21935131,0x0720f8cb),LL(0x261dafa4,0x40e03217),LL(0x6fb18c8c,0x34851940),LL(0xcd3c7d48,0xe02770ca),L_(0x00000146), + LL(0x3aea03d8,0x826415dc),LL(0xaee30325,0xe70ecca1),LL(0x8395cad3,0x053fd2fe),LL(0x148ed662,0x3520779d),LL(0xad7a6345,0xc9cad78e),LL(0x02a99616,0xb2b3d15b),LL(0xa5bc3102,0x9cfe5a4d),LL(0x4cc19d74,0x59fc0a6f),L_(0x00000106), LL(0x3f02d2b6,0x3a1ba1c9),LL(0x487fa3ac,0xb4dfc9f7),LL(0xe0d152d8,0xf699a6f5),LL(0x8f345525,0x20633fdf),LL(0x76ba6839,0xca7d8a08),LL(0x2bd4f59f,0x88585003),LL(0x05078df0,0xcface355),LL(0x01da05b9,0xfd2eb0a9),L_(0x000000a7), + LL(0x5676f0c9,0x52b16ebe),LL(0xf47e5b46,0xe6ae36e7),LL(0x71c81701,0xe3a4cc33),LL(0x1ae7f8d6,0xb29431c3),LL(0xaeb29c67,0xb869125f),LL(0xe16be2af,0x052cfd62),LL(0x934ce6d0,0x10638824),LL(0xe1cd7490,0x2b021800),L_(0x000000e6), LL(0x23a9de59,0x53a39e35),LL(0x21f34b32,0xaa3b5761),LL(0xd9c36b4a,0x2e0442ed),LL(0x419b2399,0xd2725144),LL(0x4d374723,0x0ced8d6e),LL(0x6d58a708,0x1b1f1118),LL(0x0cd63ed1,0xd7a4d0b5),LL(0xf4c6faa6,0x9c897561),L_(0x00000055), + LL(0xca7de8bc,0x0cb3fdd3),LL(0x8e8db5d1,0xaee5321b),LL(0x87aea4fe,0x3857736e),LL(0x16711165,0x0c1ddf85),LL(0x0fefea55,0x5866facc),LL(0xf4b819a9,0x33eac999),LL(0xde7464eb,0x2a31e0a7),LL(0x4f70e413,0x152ce312),L_(0x0000015a), LL(0xab29e0e3,0xbf9b85c5),LL(0xba27db9c,0x153c54c7),LL(0x65beb177,0x0c1db955),LL(0x38a15bc3,0x12ad15c1),LL(0x1bbf7edd,0x99f39d44),LL(0x0cddc300,0x017014dd),LL(0x7ea43a2c,0x2d23d878),LL(0xbec5a12d,0x5eda0b7d),L_(0x00000155), + LL(0x64653256,0x06657d80),LL(0xd29c3627,0x8365a95f),LL(0xe70b9e02,0x084d6b18),LL(0xc68fa40d,0x80bbbcfe),LL(0xae56df9d,0x8a06728a),LL(0xb6253373,0xbd4a361e),LL(0xc77e1c92,0xd3c11b1d),LL(0xa94fbeef,0xa52dffaf),L_(0x000000fb), LL(0x00a47f4f,0xf19acb1f),LL(0xe668d3f2,0x23cbf024),LL(0x095d2d5d,0x7f105b84),LL(0x89f76b69,0x5b550d74),LL(0xe73345da,0xbc9d3a15),LL(0xd2b26a8f,0xd6a293e0),LL(0xe4494adf,0xe0387451),LL(0x818e6417,0xb0518331),L_(0x000001b0), + LL(0x9bcbace6,0x4d2a42df),LL(0x808fa6d8,0x68651170),LL(0x445f0d4b,0xec0d410c),LL(0xc6980698,0x1ad2d890),LL(0x005f7ee7,0xbcda7089),LL(0xa7d283e2,0xf5b48062),LL(0xcee64fee,0x0051a180),LL(0x73e72ad4,0x848f7b7c),L_(0x000001be), LL(0xfa1706be,0x690a81c3),LL(0x3ce8b5c2,0xac33d774),LL(0x15e254f0,0xa423baea),LL(0x948fbc87,0x2fe89ca2),LL(0x80cdde65,0x9a165eb6),LL(0xb1b05690,0x1c84102d),LL(0xc135f5d4,0x73f34a94),LL(0xc61329b0,0x8ced1268),L_(0x00000189), + LL(0xee3f1678,0x9713685f),LL(0x93a123f3,0x6ef5a591),LL(0xf28bae61,0x67b33050),LL(0xda7d2c65,0xae5b6596),LL(0x59fc9e4d,0x0481adbd),LL(0x18dde4a4,0x2fe92c16),LL(0xf2a19468,0x5adc0431),LL(0xeac05bc1,0xdb30fcce),L_(0x0000013e), LL(0x900c6eaf,0xee47d7a2),LL(0x4cf35b8d,0xc425ee95),LL(0x74908606,0xcdac359e),LL(0x22c94a88,0xef2c8586),LL(0x10d20bfb,0x8d0f7458),LL(0x1ca77f65,0x426741d7),LL(0x82f59f1e,0x640314c7),LL(0x294af36c,0xec0709c8),L_(0x00000035), + LL(0xcbc694b2,0x1e52ac8f),LL(0x0894401e,0x36abe923),LL(0x9f482e3b,0x81ce378a),LL(0x32d1efaf,0xae954687),LL(0x62ff86e1,0xd9afd8e0),LL(0x085da5ec,0x5871a105),LL(0xd026254f,0xe7a32717),LL(0x83b4a648,0x40288d2e),L_(0x0000004b), LL(0x3c782f28,0xb0b6dc10),LL(0xa8898440,0x699ececa),LL(0xe53262d1,0xdf9ba3e4),LL(0xdb180197,0xa82e89ff),LL(0x786042aa,0x97af8b17),LL(0x663faa6b,0x00b45e0a),LL(0xf346c12e,0x03c76f2d),LL(0xe8ec3f00,0xbda1be57),L_(0x000001a3), + LL(0xf094c184,0x55c5c739),LL(0xfcd89a8d,0xc0dcdb75),LL(0x71a4d047,0xd498ccfb),LL(0x8baef9a3,0x669e7edb),LL(0x20d8ae8f,0x98d6b13c),LL(0xd16a48c7,0x3f4ca564),LL(0x50d24170,0x509f9dc2),LL(0x8c680ef9,0xb2c17a38),L_(0x00000170), LL(0x942861e3,0x23778808),LL(0xe8d8d33c,0x9dd269ab),LL(0x9bd2fb18,0x1e8769b1),LL(0x62b11258,0x657bacd6),LL(0x8521c19d,0x584fbcaa),LL(0x46adc05d,0xe93891c5),LL(0x68fad3f4,0x8617aebc),LL(0x0857bce7,0xe39a4226),L_(0x00000101), + LL(0xfc938e83,0x17cc51bf),LL(0x6d70f113,0x546beb5c),LL(0xc94a2150,0x62ee8e73),LL(0x3d11d590,0x255999c7),LL(0x8c21f26b,0x42e22a6e),LL(0x3732f418,0xb9e01e7a),LL(0x910608f5,0xea10cdc0),LL(0xef7f9669,0xf54f17b3),L_(0x000000b5), LL(0x83ab9767,0xe994f9cf),LL(0x5a87a958,0xe54c87e2),LL(0x6e7d0b5e,0xa8cc0493),LL(0xb0873928,0x837b814a),LL(0x92c0806c,0x1e804d39),LL(0x8cb9df2c,0x1d8a5f76),LL(0x2377456b,0x33c3155b),LL(0xe6d63e09,0x55cb5f9c),L_(0x0000011e), + LL(0x4f8eb1a8,0xcfd79f62),LL(0xc5d103b9,0x295548e9),LL(0x71b65a58,0xb8462f3d),LL(0x40934991,0x1453c2b2),LL(0x41c087b5,0x1cf62fb3),LL(0x37eea50d,0x02ab6cdb),LL(0x7ada571b,0x1b49b692),LL(0xda9e677d,0xb52dc4d6),L_(0x00000004), LL(0xb839d5a9,0x2e42f171),LL(0xb6cceda3,0xdbcc6765),LL(0x09960889,0x2e336d9f),LL(0xe5440e8e,0x34cefd7d),LL(0xb410a81f,0xd8bc6b5a),LL(0x91782d60,0x46d80cbb),LL(0x95e22f30,0xc99291ea),LL(0x9e775cf7,0xca473be0),L_(0x00000082), + LL(0xcc9e1b6f,0x06ac0186),LL(0xbd98b833,0xdc7e7944),LL(0xae0a1564,0x0b94fb31),LL(0x8b85aba8,0xfd0db6b7),LL(0x3fa21f5d,0xbb92a7c4),LL(0x7133a3ce,0xfc2b2cf0),LL(0xd39f3731,0xb63fc2cb),LL(0x376e5f1f,0x4d89e9a6),L_(0x000000ce), LL(0x194cc828,0xe98c5f25),LL(0x2178e890,0x51c9207d),LL(0x1be32aa0,0x8d2cb6c8),LL(0x629881ee,0xdb210410),LL(0xe3099a6e,0xfd24a488),LL(0x62aff70d,0x6e705a1e),LL(0xb843d997,0x41319b69),LL(0x8bfa95c3,0xd9b9376a),L_(0x0000010b), + LL(0xa3e1ec65,0xc2b6a03b),LL(0xfefa851e,0x0a7bf6b7),LL(0x3a92f668,0xbf4905c0),LL(0xe8a75dea,0xff483a6a),LL(0x78467396,0xdc163b2b),LL(0x8999b6fb,0x8968be09),LL(0xc4a53538,0x419a12c9),LL(0x40b8e919,0xd87c8896),L_(0x0000010b), LL(0x81b9e47c,0x68f69e36),LL(0x5971b3c8,0x53ea08fc),LL(0xbd601db4,0x0ff01a96),LL(0xa72aee96,0x347158b6),LL(0xef1dc3a0,0xc8994151),LL(0xb70d9ea4,0x39937de4),LL(0xa2906842,0x73a17885),LL(0x1ae4276c,0x34f8bee7),L_(0x000000a8), + LL(0xfe5a5236,0x7fdb683d),LL(0x5075fbb5,0x35997d35),LL(0x4f7513bc,0xb65dda5b),LL(0xcca089f1,0x0e8d30ed),LL(0xf394427e,0x66ecf608),LL(0x7394ebe5,0x80d0cb61),LL(0x2babf408,0x9903b671),LL(0xb8208316,0xe416cdcf),L_(0x000000b6), LL(0xf1d8de96,0x26090ace),LL(0x026550ab,0xf1bd714b),LL(0xceedda36,0xd83c3071),LL(0x6a6fe427,0x5704c9b9),LL(0x9e328311,0xa3fbc241),LL(0xfceb37ff,0xf54b88ee),LL(0x2f82304a,0xb6315a8d),LL(0x77a230c7,0xeda8682e),L_(0x00000177), + LL(0x70a0b8b3,0x5759366b),LL(0xabadb724,0x75b84d60),LL(0x87caf5b9,0x983f793d),LL(0x1cecc3f1,0x94d8de54),LL(0xd8885c2e,0xf90b687c),LL(0xd952f2ac,0xd5046b6c),LL(0x16cc05b6,0x266e5bb0),LL(0x52f97cdb,0x5959c784),L_(0x000001c9), LL(0xefd1f634,0x931e70e0),LL(0xc8989bfc,0x36663528),LL(0xc244410e,0xf14f2667),LL(0xbca645d5,0xf8059cc8),LL(0x1c94e08c,0x1d2134f7),LL(0x1d1a84e9,0x3489ba7b),LL(0x21c35b98,0xdddbab1e),LL(0xa303bfc5,0x86156a8f),L_(0x00000198), +}, +/* digit=60 base_pwr=2^300 */ +{ + LL(0x6b1a72ba,0xec83fd79),LL(0x9640b910,0x5166dc54),LL(0x1f3c076c,0x553ff932),LL(0x6d2b7e4e,0x7e2f7e67),LL(0x097c11e9,0xaa2cdad5),LL(0xc5cedff5,0x397f4bc0),LL(0x57d09eef,0x8d95f667),LL(0xe7743495,0xe32eada9),L_(0x000000ee), LL(0x3f068368,0xe641f85b),LL(0xa0e3496c,0xa6b773ab),LL(0x7931548e,0x3aecbf5b),LL(0x2ef14927,0x58c42c5d),LL(0x1528b818,0xfddc70d9),LL(0x1c157c1e,0x0a328d34),LL(0x690e10df,0x0760fd8a),LL(0xa364f5d3,0x4ec3b44e),L_(0x000000d1), + LL(0x572bb6c8,0xb187f011),LL(0x26f1e48d,0xb62010d1),LL(0x0d05c4b7,0xe0fbe5e8),LL(0x3f0a2ba1,0x24d802f1),LL(0x189e9602,0xde0b8698),LL(0xc0b8af43,0x28591b4b),LL(0x706b742b,0x36bf7aec),LL(0x63d91963,0xec0d2fd3),L_(0x0000007f), LL(0xe7179b1f,0x440b0b6c),LL(0xe982e3e2,0xd99d67cd),LL(0xd814a6fa,0x7edfbb4d),LL(0x4ac7d349,0x46c6afc8),LL(0x63bbd77a,0x84cd907a),LL(0x18bcc3d6,0xf098909a),LL(0x756b5193,0xd6e0581d),LL(0x02f37ab5,0x06adf4d1),L_(0x000001fb), + LL(0xf4b1ce28,0xe90415e4),LL(0x6bd8544c,0xc664d2f1),LL(0x3e7600d6,0x01912f05),LL(0x1e8d9aa4,0x3e0c268e),LL(0x43dcdadd,0x2f140134),LL(0xbf936e21,0x252cf59c),LL(0xb8aaec39,0x00b8cef4),LL(0x7ed652c2,0xc64c11e4),L_(0x000000aa), LL(0x7a2dfe0a,0xa7c08e2e),LL(0x59176893,0xafe8a484),LL(0xc7c5a8f0,0x6f043d0d),LL(0xe33e999b,0xb3c3cfd6),LL(0x2a496c00,0xcb4fbc5e),LL(0xe2690de5,0x1dfaf5ee),LL(0x3d2db451,0x743e9277),LL(0x8bfecdd2,0xade6a194),L_(0x000000f4), + LL(0xcadf2116,0x8d039609),LL(0x488fdf25,0x1e037339),LL(0x0e39945a,0x4d16fa60),LL(0xf539a844,0x54408c23),LL(0xf7f8ccc4,0xbef729fb),LL(0x69b8abc6,0x76661fe3),LL(0x3dbd87a4,0xa8903415),LL(0x790f6266,0xc7b4bcd2),L_(0x000001e3), LL(0xec9aa47b,0xa406e205),LL(0xce1af477,0x72e7763c),LL(0xf7fcf645,0x43d00999),LL(0x1f7c9317,0x02adccdc),LL(0x8b87a139,0x541be26f),LL(0x9ffcb96f,0xbb590677),LL(0xc0636264,0xc0db1d61),LL(0x19484331,0x5585c8ae),L_(0x0000016e), + LL(0x77cc15c1,0xe85899b3),LL(0x5fff92e2,0xb4a44f31),LL(0xa8cf599e,0xca1a3e87),LL(0x17a2e4cf,0x205f34e2),LL(0xe4f28f3f,0xe9eb1362),LL(0x4aa7c205,0x6ace61c8),LL(0xfa76515b,0x7e550586),LL(0xec83aca3,0x35e870f8),L_(0x00000104), LL(0xd113de7a,0x2e02203e),LL(0x318327d4,0x004d9655),LL(0x5d903904,0x7cd1d2f1),LL(0x9d294adb,0xca1242c8),LL(0x3b5bb4eb,0x4af2a142),LL(0x93818e82,0x15e366f3),LL(0x9a304441,0xd6a53de7),LL(0x49183b2c,0xfd324d82),L_(0x0000007b), + LL(0xdb2cf29c,0x4d1ee196),LL(0xa1d04903,0xe53d6718),LL(0xacaf386a,0x6605e4e6),LL(0xcc306d74,0x458e136f),LL(0x77dc40c4,0xab7a1ac6),LL(0xbb331955,0xd47f6ee4),LL(0xb95c386e,0x43841037),LL(0x526640fb,0x00a37bb7),L_(0x00000010), LL(0x8f1bcdb4,0x8b8cc55b),LL(0x71d84cd7,0xe7e03251),LL(0x1b8eb12e,0x64c45f59),LL(0x2d7bd8c5,0xc2283df1),LL(0xb03bfc76,0x28a36461),LL(0xafd6fc81,0xa0580c8c),LL(0xe72b6275,0x511c376a),LL(0xce438282,0x0ca3213f),L_(0x00000078), + LL(0x353cadbb,0x1e2c0f6f),LL(0x17179cb8,0x0810156c),LL(0xaf140db0,0x63cd1fa8),LL(0x2171bb5e,0x729533d8),LL(0x544c77b0,0xf6676827),LL(0x0143af56,0x599efe1b),LL(0x5a759df2,0x3accffd4),LL(0x55962b59,0xc61321e5),L_(0x000001a3), LL(0xa5358dc7,0x66e58a6a),LL(0xbb4d42d5,0xe0cfd739),LL(0xe6ef3760,0x0620ef46),LL(0x6804fb37,0x253e0f9e),LL(0xf4e9cdc2,0xcb5c8c64),LL(0xec6f6658,0xa80d08da),LL(0x04153037,0xcc959be5),LL(0x3d215b47,0x7aaaa865),L_(0x0000004e), + LL(0x166381e4,0xf52bc233),LL(0x9700029a,0x2a837019),LL(0x3201dddf,0xd02e2c74),LL(0xd8885cda,0xaea6cd36),LL(0x7e35126d,0xbc3f784e),LL(0xfa40cea6,0x5130e882),LL(0xeec16a3a,0xace2f121),LL(0x13c43706,0xf3c3a16a),L_(0x000001cc), LL(0x9e7a6c25,0xc964823f),LL(0xe8e4729a,0xeed8d7ba),LL(0x3fe54edf,0xcfba42bd),LL(0xec6a4e7b,0xe917bf88),LL(0x06be2039,0x604163c6),LL(0x17d5a63a,0x6bdf09b0),LL(0x276869bd,0xf021410c),LL(0x4b94144f,0xf038cdd9),L_(0x00000013), + LL(0xf09a7d9b,0xeb8a6d24),LL(0x724db1ba,0x545ff43f),LL(0x850f42b2,0xfcaf8079),LL(0x5c1fdccc,0xde18c209),LL(0x57404da7,0x83097de7),LL(0x267842f8,0x8706015d),LL(0xab9a893d,0xe62c08dd),LL(0xe2b0c7a0,0x736bf358),L_(0x00000142), LL(0x254c1866,0x535f7766),LL(0x4779dd4d,0x10a98c32),LL(0xc095243e,0x0e7bc245),LL(0x3cd82df8,0x5fac69de),LL(0x59efca16,0xa2f0af19),LL(0x692e1ddd,0x40c91226),LL(0x9b21f9d2,0xa682e04c),LL(0xa51cafc2,0x831c0e79),L_(0x00000049), + LL(0x6101ea3e,0x94e4798e),LL(0x00af5508,0x9afdccb8),LL(0x987426d2,0x0f5f64d2),LL(0x4aaeb57e,0x76899b88),LL(0x9a8859b4,0xcf38ab59),LL(0x31a64817,0x8dc36916),LL(0x9b757c1f,0x28b27539),LL(0xfb6a189c,0xc63802b8),L_(0x000001ba), LL(0x997a98e3,0x225f33e4),LL(0x9d6bb39a,0x880025e5),LL(0xffb62ebd,0xb7d05691),LL(0x6aacd544,0x3e434b4f),LL(0xba8454f9,0x4bc06244),LL(0xbe5d3fe0,0x941bd419),LL(0x6732d1a1,0x6794ada7),LL(0x6efab77e,0x1058a767),L_(0x0000008b), + LL(0x7d41eaad,0xe58d6aac),LL(0x5f7430b9,0xb9ab109f),LL(0xedf696b8,0x252205ff),LL(0x65163bdb,0xb3a47496),LL(0xfd8eca02,0x915f0458),LL(0x6d6b0ec4,0xb0096e8b),LL(0xddddf89f,0x874c9e5e),LL(0xab9c669c,0x156cfc6b),L_(0x0000019a), LL(0x80d21354,0x8c6752e9),LL(0xc103803a,0x0196650f),LL(0x653fb161,0xe597cf0d),LL(0xa211c0cf,0x66902c1d),LL(0x126bc8cd,0xff4436dc),LL(0x502c8df4,0xcf0ef89e),LL(0x30d9c137,0xadabc266),LL(0x509eb349,0xcbdaa030),L_(0x000000ae), + LL(0x80ee5e16,0x9d067e75),LL(0x0846b23b,0xb348d35d),LL(0x6044d60f,0x4e0c74fc),LL(0x4437fb47,0x2124f846),LL(0xc898c89a,0x30abdb7d),LL(0xa1ecdf1d,0x496e747c),LL(0x09be44bd,0x9381d368),LL(0x6a34a28e,0x2cd1e7c2),L_(0x0000002c), LL(0x21c47e8f,0xece95ae5),LL(0x705df30c,0x08cdb28f),LL(0x8f6f90ca,0x15b2caca),LL(0xdb9f29f0,0xf8e2597f),LL(0x537c5e8b,0x91e195ad),LL(0xa54bf828,0x1ef3bc47),LL(0x5f5b1233,0x6c98e99d),LL(0x096c5cfe,0x0acf39b3),L_(0x00000155), + LL(0xe7e060d2,0x5e49ea9e),LL(0x8278d27c,0x1462a5cf),LL(0xb6b188b1,0xd1c3e723),LL(0x7adfe4be,0x9f4ab12b),LL(0x4f74656e,0x86f9e399),LL(0x15f9fd6f,0x647aabe4),LL(0x356f176c,0xdc05df56),LL(0x037f39e8,0x6f8c9681),L_(0x000000ab), LL(0x7fabb630,0xfd586565),LL(0x4f9b62dd,0x9a07decc),LL(0x07d1665c,0xb14d451c),LL(0xb6af032b,0x2d75e1e7),LL(0x7c7044cc,0xac2df8ec),LL(0xcac8a69f,0x0906e20d),LL(0x20c70582,0xa4167466),LL(0x1ca47052,0x6fe2b8c1),L_(0x0000002e), + LL(0xc222cb55,0xfb8bf3d9),LL(0xcaac45d1,0x39bf904a),LL(0x4d2bf532,0xa7f1203e),LL(0xa3246448,0x9ecdf560),LL(0x6d3940b2,0xa6d3b3a3),LL(0x89bdcf57,0x40dcc76f),LL(0xdcc95c73,0x9fa5791b),LL(0xa442ea24,0xc94b40b3),L_(0x000000fd), LL(0xbfbd8ae2,0x8473e7d8),LL(0xbc97c4e6,0xe17e4cb3),LL(0x8daa65ee,0x1d315fc6),LL(0x20c6ff94,0xeaec9cae),LL(0x74f3ffd6,0x1b61c251),LL(0x015f6f88,0x6a1cf873),LL(0xee694708,0xd187e0b9),LL(0x37da53ba,0x332ba61a),L_(0x000000b9), + LL(0x44bad1e8,0x409292b4),LL(0x27a8575f,0x23606aaf),LL(0xeb1afe84,0x6df6bd82),LL(0x546ebac4,0xd77cd802),LL(0xd19a6a0e,0x9ac38a98),LL(0x701bcf92,0xae1c0504),LL(0xd6247bc1,0x90bada7a),LL(0x7a406e08,0xcc3c49ab),L_(0x000001ac), LL(0x1a859f6a,0x5dcf7e44),LL(0x5f7352bf,0x2b674d19),LL(0x0ee31d4e,0x35a3e68d),LL(0x92916c56,0x5e153a5d),LL(0x1bbba324,0xa3d55e06),LL(0x27d3691c,0x74f6e553),LL(0xa9153a98,0x2c8a7473),LL(0x6e737b68,0x545acbac),L_(0x00000114), + LL(0x741a9412,0x892f8bd1),LL(0x31776371,0x6c0b1d4f),LL(0x60a2c8b1,0x9a688a19),LL(0xa0d12ea4,0x56eef3ec),LL(0x4746c345,0x90c83381),LL(0x842db71e,0x3fdb8d8b),LL(0x1bf4ae9e,0xbc576b9b),LL(0x9e0ee706,0x85a8de64),L_(0x0000014e), LL(0x9f19edfc,0x3c32799b),LL(0x25980592,0xc4760975),LL(0x76f95241,0xd6c8d637),LL(0xdd3d3b18,0x677dee0d),LL(0xe5bceafa,0x12ad9334),LL(0x7ca46478,0x3990ceb2),LL(0x94d56dac,0x39d6e555),LL(0x8e338deb,0x7a9d83d7),L_(0x0000016c), +}, +/* digit=61 base_pwr=2^305 */ +{ + LL(0x14b21476,0x52d7b490),LL(0x4215e0ae,0x3a781f13),LL(0x84df8cb3,0xaf858985),LL(0xc3ab10bf,0x449e13a9),LL(0xea1a4d65,0xb859368b),LL(0x2c8134df,0xb51fd78c),LL(0xa7d94439,0x4b1e6f5b),LL(0x003f1c75,0x4cf5d47b),L_(0x00000146), LL(0x3cdb3bab,0x6dc28640),LL(0xd6597a8e,0xe3d2ac15),LL(0xe5e853fb,0x8bd192da),LL(0xf804c989,0x76032d13),LL(0xdb66ee3c,0x738d5e8b),LL(0x349bcb16,0xe16c7ea1),LL(0xe4001679,0xd22ec201),LL(0x82f1f584,0xd9f317a9),L_(0x000001b7), + LL(0x92fe026b,0xec0a67f0),LL(0x2efbca10,0x3767ee14),LL(0xcc433a34,0x68131944),LL(0x370f6b9e,0x36fcc884),LL(0xb4d1b5e8,0x85328231),LL(0x85b956e6,0x3e4b895d),LL(0x17afd7ce,0x23cd96a1),LL(0xfc28a48e,0x6cbf1cc4),L_(0x00000175), LL(0x8d0ddeea,0x5cc45bb9),LL(0x4201b856,0xbec2c277),LL(0xb4f52020,0xcd76ab62),LL(0x3aabda65,0x2fb221ac),LL(0xd348e9ae,0xb7ba962f),LL(0x81d5e875,0xacdde7c3),LL(0x8ae119ed,0x7186eb96),LL(0xd5b495d5,0xdf795bd0),L_(0x0000016f), + LL(0xa9d725f4,0xabe42367),LL(0x83477d80,0xae655393),LL(0x9bf84781,0xf1389d3f),LL(0x50d527ea,0x02ffac63),LL(0x30005241,0x5a3b0583),LL(0x332af83e,0x30a51cf3),LL(0xd633aac0,0x7e87b5f6),LL(0x6133508c,0x54cf5544),L_(0x0000014e), LL(0xddfa61bb,0x79f352eb),LL(0x3d5e304a,0xc8a8525e),LL(0x673478be,0xcd082890),LL(0x65272acf,0x6528a7ef),LL(0x07746b44,0x6120a7a6),LL(0xaa126f2d,0xed8dc8aa),LL(0x0714c411,0x242ecc1e),LL(0x09219322,0x4dd29b99),L_(0x0000016f), + LL(0x2f54f5ef,0x9d1e3e79),LL(0x6e1c349e,0x7cb862d6),LL(0x411c782a,0x774f6f73),LL(0xf914b067,0xd88b7029),LL(0xbe145ff3,0x68ac9342),LL(0x0730a2fc,0x77dcfba1),LL(0x7ace014c,0xe34f0621),LL(0x876ebecf,0xb7a85b90),L_(0x00000104), LL(0xd99da4a6,0x2be45d39),LL(0x2af68cfe,0xeda14612),LL(0xbeab553a,0xc8cf47bb),LL(0x185338ec,0x9f26575d),LL(0xbcf5707a,0x2dafc93e),LL(0x9b4f2615,0x85006b56),LL(0x1c517096,0x58e4408a),LL(0x2759575a,0xa451b6b3),L_(0x00000143), + LL(0x03077a78,0x64081168),LL(0x9fca1732,0x9e2e68b9),LL(0xc2ec6027,0xbd01c53b),LL(0xcf8e3aa9,0x3c299cf0),LL(0xc31ff566,0x69a934da),LL(0x3a869b7d,0xee4c3bf3),LL(0x17fb711a,0xe353eab9),LL(0xb5b7fc05,0xd300c851),L_(0x000001da), LL(0xb6667f8d,0x7326c782),LL(0xf868e4b0,0x7616e981),LL(0x9cbec832,0x0d0b19fb),LL(0x0355a1b8,0x7504ef78),LL(0x9b3d9f50,0x75e429da),LL(0x0924def0,0x130ecd97),LL(0x07187605,0x844d6f96),LL(0x7c14ae9f,0x8921d3a7),L_(0x0000001b), + LL(0x6ef420ae,0x9415e0cc),LL(0xdd321662,0x7be013aa),LL(0xad261af9,0x46c47707),LL(0xedc263d9,0xabc20130),LL(0x2f265a39,0xe142f5b7),LL(0xcfeec142,0x90dba064),LL(0xa08536a7,0x488a0175),LL(0x6d419631,0xcf748207),L_(0x0000003f), LL(0x59c2a2ed,0x6def509f),LL(0x7ce6774c,0x4af30ccf),LL(0x09bc7469,0x3bf7cbb3),LL(0x12464f68,0x648dc8e6),LL(0x93c3b96f,0xb39085a1),LL(0x1000d207,0xe4a3e7cf),LL(0xcb93a762,0x39e62f3d),LL(0x08cde0be,0xd6284f5b),L_(0x00000092), + LL(0xcef51b82,0x4fd9fb1f),LL(0x0a484ffb,0x4a91b446),LL(0x5c5120d6,0xcfe786b3),LL(0x521a227a,0x1f347861),LL(0xb4d52b1b,0x005afae4),LL(0x28a0b22b,0xaed64316),LL(0x96565ad0,0xcf8e1f9b),LL(0x3bd3818c,0xd717a7fd),L_(0x000001d7), LL(0xf05313af,0x17132d83),LL(0x4d75e2a9,0xf9bc8f55),LL(0xbaf9947b,0x91f937e7),LL(0xcb9bb75f,0x232e92ab),LL(0x4c1c8f93,0x92cbf962),LL(0x90cd09cd,0xf2dcee1e),LL(0x07dbfe55,0xb89e680d),LL(0xc41cd340,0x51007568),L_(0x000001b3), + LL(0x652aa77d,0xb831eea8),LL(0x9b33eda2,0xdd1ac75a),LL(0xccb42fd2,0xe55769fc),LL(0xa865ab8f,0x2ea2c9e4),LL(0xc60208ee,0x28effb93),LL(0x321dff3f,0x2d6b1522),LL(0x5124fb78,0x6e29dc3e),LL(0x4cf961e9,0x2f39193c),L_(0x0000006d), LL(0xe3174790,0x035e63b7),LL(0x67da851f,0x7e9f39d6),LL(0x7183aa79,0xe886c75f),LL(0x4aa59f9f,0x6d9e6857),LL(0x706045d9,0x2ee25277),LL(0xb18ceb8f,0xe4bcaa94),LL(0x5bc3971a,0x57fc8f0d),LL(0x7b7b6081,0xdd642848),L_(0x00000150), + LL(0xff257250,0x44c8a327),LL(0x1f4b8713,0xa7ee221a),LL(0x5258be1d,0xe41af48e),LL(0xa737a8cd,0x83aeee1c),LL(0x3f320ac3,0xbb3a2bdf),LL(0x8abc18a8,0x2bfe7f09),LL(0x9da43962,0x5ab55046),LL(0x1318b08d,0xc7f6a7c8),L_(0x000000c2), LL(0xe5844c3c,0x072464c5),LL(0xe109557b,0x52cb5223),LL(0x2e18e586,0xbb44cf23),LL(0x58cf033e,0x8273746f),LL(0x9cb3f3f2,0x15027b4d),LL(0x0badc23f,0x03dd0534),LL(0xebde0563,0x94ef00b2),LL(0xf31a2a6f,0x88f86782),L_(0x000001e2), + LL(0x56b13d17,0x5644a483),LL(0x012e151c,0xec46d8f5),LL(0xcb60c92d,0x61f8e693),LL(0xf704143e,0x53579b44),LL(0x06b44ecd,0x98807645),LL(0xdda8c89f,0x17c64951),LL(0xfaab400d,0x2e39e25a),LL(0x16b86130,0xfef9c912),L_(0x0000004f), LL(0x25210623,0xd2367ca5),LL(0xf18ebddc,0xbcf685ba),LL(0x59f6d4cf,0xe159807e),LL(0x8c3c8195,0x2bb8d624),LL(0x02e20259,0x3ad24a15),LL(0x5eef3266,0xe9a952f5),LL(0xc8d0e08e,0x37d37845),LL(0x4cf4addb,0x778df76b),L_(0x0000002e), + LL(0x7a1441af,0x55047df4),LL(0xa605ea07,0x579060a2),LL(0x728d81cf,0x3b8900fa),LL(0x1ccc1e61,0xf49f8c7a),LL(0xd633ce10,0x4957105f),LL(0xe467c698,0xc3e2024e),LL(0xa14d0dd3,0xe7cc2be3),LL(0xc90176ba,0x00090c73),L_(0x000000f8), LL(0xf9360056,0x39d8bbe5),LL(0x229fde87,0x1982808c),LL(0x9d5d0ade,0xb83a93a2),LL(0x56715396,0x4130f493),LL(0xf5d0d1b5,0xc39ee248),LL(0xcbf57700,0x0662cf56),LL(0xf41ee620,0x121da851),LL(0x2397e72c,0x1ab413bf),L_(0x0000017e), + LL(0xdd8cd85b,0xbdd73dc1),LL(0x1f7a793b,0x7252dfce),LL(0xb3c777ad,0x1ad25f35),LL(0xd306f90f,0x314c1227),LL(0x4538596b,0x28e31145),LL(0x15f73822,0x1808f8a9),LL(0x5e4847ef,0x6eb8175d),LL(0x9d57409f,0x2ae642ae),L_(0x0000011d), LL(0x6debc205,0x3f28e667),LL(0xa45a1d7d,0x84954816),LL(0xe5f147ca,0xccfb8bd1),LL(0xcd78f915,0x9a693642),LL(0xb02b310f,0xb6cb5362),LL(0x1f01047b,0x7529c74d),LL(0x81d1fb13,0xdf4ae21d),LL(0x80b9dd94,0x6a1afeec),L_(0x000001bc), + LL(0x7bfa4703,0xc0abf15f),LL(0x81d957db,0x65ae7f67),LL(0xe0fe8725,0x40e4566b),LL(0x7c42febe,0x6340b7ff),LL(0xcf060fa6,0xea1d2782),LL(0x9a689bd9,0xb66eed98),LL(0xc45b992d,0x8f5646a0),LL(0x969dc412,0xd272048a),L_(0x000000d2), LL(0xc0243059,0x50900d7f),LL(0x701c6e38,0xaad1803d),LL(0x92065d64,0xf9668fa4),LL(0x361ef75c,0xfcc216b4),LL(0x962eb248,0x575be56a),LL(0x89b9828a,0xfde9ba30),LL(0x202a575f,0xc435f2ce),LL(0xba3890aa,0xf83734f6),L_(0x0000019a), + LL(0xdd8bb48a,0x3ede16d4),LL(0xa59cdc00,0xd0de9f29),LL(0x9f3b7991,0xda7b6269),LL(0x832ec0d2,0xf2e16e2b),LL(0xa8e7c828,0xd0c41727),LL(0x7f0878f9,0xc4546447),LL(0x7356692c,0xc4af90b2),LL(0x5fbe130e,0xaa2e9ec4),L_(0x00000190), LL(0xa8a02409,0x0074a183),LL(0x16d0ccbe,0x351544e0),LL(0xf7b675ff,0xf37d43c1),LL(0x87055e7e,0xc371f0a0),LL(0x3e668989,0xefcfca1d),LL(0x8323227b,0x36507d20),LL(0x38f76084,0x25498782),LL(0x75a23d95,0xacb8cb75),L_(0x00000154), + LL(0x1d79b659,0x20886bbb),LL(0x9a6dec74,0x296f5cd9),LL(0xfd24a18e,0x6092fe28),LL(0xbb4a7907,0xdeab539d),LL(0x869a8ccb,0x67f524d1),LL(0x61521c17,0xbbe3aaa1),LL(0x5f79a2c2,0x8be17e72),LL(0x7d8ce0cb,0x647da5af),L_(0x000000d8), LL(0xd52aec82,0x0f2ab363),LL(0x6d93da70,0xdfde9d3e),LL(0xa76d10f8,0xe72ce040),LL(0x17308d11,0x075467a8),LL(0xed2aabb3,0x9aa69a1d),LL(0xc10f78d3,0x4caac399),LL(0x13d4d378,0x7e54c473),LL(0xda4d8f8d,0x911cb804),L_(0x000001b0), + LL(0x9aa77765,0x253f45b8),LL(0x2af99e2d,0x112b491f),LL(0x76414d1e,0x4a8e2b12),LL(0x1c380001,0xa17691a7),LL(0xb0f6f9ff,0x4bd4233a),LL(0xcf4e764a,0xccb8bd49),LL(0x012735f0,0xc7fc0714),LL(0xf6037d3d,0x3da811dd),L_(0x000000e0), LL(0x60d3228c,0xf24a8fb9),LL(0xb39e1a42,0xa3c4048e),LL(0x07ea05b5,0xd581bb93),LL(0xfa0b7bd9,0xeeb6ce36),LL(0x8b7b8d8f,0xa0329bb2),LL(0xfcc8cab6,0x5c44e608),LL(0x04c03b08,0x3f2c4c95),LL(0x51593cce,0xb2ef5a3d),L_(0x0000013b), +}, +/* digit=62 base_pwr=2^310 */ +{ + LL(0x2fe5424a,0x052a5d7a),LL(0xbd77fdcc,0x91e67c5a),LL(0x7ae80845,0x30c17511),LL(0x4fb64810,0x92e55b53),LL(0x6c21b31f,0x96bd1eba),LL(0x4d056aef,0x3bd89651),LL(0xf597cfd9,0x39ce9f5d),LL(0x10c4de29,0x6737cbaf),L_(0x000000ef), LL(0xf5b4aa6e,0x726ccf17),LL(0xa070d7b2,0xef8a249b),LL(0x33084cb0,0xfece71d7),LL(0xdbf18fa7,0xf11b328d),LL(0x8e7f8fe7,0xdb8c5b89),LL(0xc5842d33,0x38ef699b),LL(0x44b71419,0x619477d9),LL(0xcd39a13d,0x28db36f5),L_(0x00000152), + LL(0x95d239ec,0xae5a71e3),LL(0x160db974,0xb267126a),LL(0x4df55ba5,0xf2bfd214),LL(0xcf291fe0,0xe4215d39),LL(0x3dc0a627,0x8849498b),LL(0xfec311ed,0x5b220c7d),LL(0x9fbb5099,0xa3d83cc2),LL(0xc55f9ca4,0x32f62dd6),L_(0x00000053), LL(0x69ec48f2,0xe73278db),LL(0xcaebf5d4,0x38b01c56),LL(0xe4ab979b,0x7e210f66),LL(0xfe305e1e,0x00e35bf7),LL(0xbbd247e8,0xf41625bd),LL(0x64eabbca,0xb3c01407),LL(0xe49d3fb6,0xc31a840a),LL(0x6ebed09d,0x6c67185e),L_(0x0000004a), + LL(0xc455f76d,0xeea3bb5d),LL(0xa7efe273,0x382ccbad),LL(0x1d1fd154,0x321aecf3),LL(0xba4c80f8,0x3a3eb329),LL(0x44874ee5,0xfc744e55),LL(0xc89ec973,0xd83775b1),LL(0x9ac52665,0x7c8cecd7),LL(0xe149472e,0xffa02e1a),L_(0x00000119), LL(0x10c59504,0x4863bc6f),LL(0x5e342dcd,0x30b568ee),LL(0xba377da7,0x61a3cd5a),LL(0xdb7394c9,0x7e13d011),LL(0x655ca62a,0x531b03ef),LL(0x687df8b5,0xa07d97a8),LL(0xc1cc63e0,0xc3579f84),LL(0x4f51c0a2,0x1f68d107),L_(0x00000159), + LL(0xcedb78e8,0x73976185),LL(0x5ac29ab9,0x1049200d),LL(0x5376ef50,0xb7cabe96),LL(0xb29fcfde,0x2ebeaa6e),LL(0x849702e8,0x9856863e),LL(0xd5820c1d,0xadb32b7d),LL(0x0b85b8b6,0xcb2a1da8),LL(0x4ecc2beb,0x911240a2),L_(0x000001cb), LL(0x6471f428,0x8e9339d6),LL(0x65738f28,0xc9389868),LL(0xec9ab31a,0xb78b477c),LL(0xb756dfc0,0x2531d4c9),LL(0x2bea7bd2,0xa957b1f7),LL(0x19668750,0xb7acf908),LL(0x23544082,0xfa97aa90),LL(0xd310dd35,0x7c9376d4),L_(0x00000065), + LL(0x03c1f949,0xe690991e),LL(0xb53d0f3e,0x7a8ed401),LL(0xe7688a48,0xc975d343),LL(0x0a163c7f,0xbbe320a1),LL(0x3c38f3b4,0x637ba641),LL(0x0cc94ae6,0x2fa7a438),LL(0xf036a2cd,0x85cf8f8c),LL(0xdd8d3d2d,0xf3dec45f),L_(0x000001f7), LL(0x0257d9f6,0x0fc0fe23),LL(0xf9f35894,0x22cf1f3c),LL(0x5367a382,0x0a85bdb7),LL(0xa486155c,0x43d0dc60),LL(0xa045fb49,0x28e031ef),LL(0x239e6d10,0xbc646dab),LL(0xf3c58cd8,0x37a252ad),LL(0xa190c29a,0x729ace13),L_(0x000001de), + LL(0xaa492173,0x2c2d00f5),LL(0x309124ad,0x92f17a73),LL(0x90896f6d,0xd107aa3f),LL(0x6655b0bf,0x28ed385a),LL(0x4393b8b0,0x64efc785),LL(0xa72dcb01,0xdc6d4959),LL(0xedcf6e0d,0xad09fb16),LL(0xa138cb63,0x5a264a29),L_(0x00000038), LL(0x11888849,0x23fa857e),LL(0xa4afca8f,0x362d992a),LL(0x4718e360,0xe0e7ef99),LL(0x51da204d,0x0a263a3e),LL(0x76d92100,0xc54159bd),LL(0xb90bd792,0x6992a7d6),LL(0x2d4d5792,0x34429060),LL(0xea9796c5,0x2d91640d),L_(0x00000104), + LL(0xd8036123,0x69a4e57c),LL(0xd8256cea,0x1bf79944),LL(0x4d134e77,0x4e8b215e),LL(0x63a4641d,0x83621b34),LL(0x8da5f102,0x530939c0),LL(0x9d6baa6f,0x78356025),LL(0x0a919eb7,0x9cebfe30),LL(0x523c04c9,0xba70fc3b),L_(0x00000060), LL(0x8a6eb39c,0xb404acda),LL(0xbeff381e,0xf36c4399),LL(0xc6bfdda5,0x193ff430),LL(0xddaf4961,0x43e642a9),LL(0x86bb6b08,0x4ebe4623),LL(0xd3326377,0x8dc4af24),LL(0x33ce6709,0xb168c749),LL(0x3757e6ab,0x451bf0a9),L_(0x000000f7), + LL(0xe12c9a10,0x95d393a7),LL(0x15af1e76,0x09f6c873),LL(0x5dad48c9,0x168b010a),LL(0x03c65a7e,0xd86fdc56),LL(0x73f51c26,0x88f52d53),LL(0x697c8b7d,0xbc64a497),LL(0x670982de,0xaf7a0676),LL(0x809f942a,0xb15cc57a),L_(0x000000be), LL(0xfd456a48,0x71728397),LL(0xf5563ef9,0x305f3c8f),LL(0x4e73a2dd,0xa80ae4a1),LL(0x828cc516,0x2258160b),LL(0xe74db735,0x108533e6),LL(0x14ad6801,0x3b320283),LL(0x541598a0,0x763ab107),LL(0x56c3d815,0xf632644f),L_(0x00000089), + LL(0x633a1213,0x3fb5de8b),LL(0x8bc4deb0,0x8d93c4e8),LL(0x1e8e7ab9,0x3dd24d9d),LL(0x201baf56,0xcada68d7),LL(0x0a384ece,0x503d4f19),LL(0x5dcc59f7,0x6763d7ad),LL(0x7849c18f,0xc66f3753),LL(0x6951161c,0xfc052118),L_(0x00000104), LL(0x0fd16654,0x90fd23ab),LL(0xfbb20d46,0xd8a0eeac),LL(0xd979406d,0x508b0789),LL(0xeb2d48ad,0x8cad1e65),LL(0x2f16458c,0x7615ee48),LL(0x8941144f,0x2d4a611a),LL(0x57baf847,0x706729a1),LL(0x04864e43,0x13b7d8ff),L_(0x000001c9), + LL(0x49e14cac,0x6b13d691),LL(0x15c5966e,0x5adf4806),LL(0xe79886a9,0xb44e7b28),LL(0xc0149ae3,0x14ea5297),LL(0x3f2176d8,0xd637170e),LL(0x3d5f7f20,0xfd66e46a),LL(0x5f76d12c,0x998ccf72),LL(0x8fbfc2d6,0xc2738301),L_(0x0000007b), LL(0x790af7d8,0x48202d24),LL(0x5d1ab080,0x22169c9a),LL(0xf44f3ef3,0x4f9cc0b4),LL(0x5a6ea1fc,0xd8a38b0c),LL(0x1e3f8f7c,0xfc2a4b0f),LL(0x2f6b7ea1,0x85236ace),LL(0x7c4797d9,0x507ad976),LL(0x30db4704,0x70b62118),L_(0x000000d0), + LL(0x27eeb11a,0xa8e006d6),LL(0xa8350ceb,0x0b5d40f6),LL(0xd0476f3e,0x7d6beb64),LL(0x8a7277db,0x9a1052c1),LL(0xb78ba330,0x6fb67a25),LL(0xa921f295,0x937d5f7f),LL(0x58e2fb78,0xb3c5ee8b),LL(0x224a8a6c,0x3ba51856),L_(0x00000158), LL(0x10433f3b,0x472c8eee),LL(0x46bd4fc5,0xd6bbe5d7),LL(0xbccb9c2d,0x8704f8a7),LL(0xd4145962,0xf0c09b77),LL(0xe9ce9fc8,0xe24e89e3),LL(0x091189c9,0x34dfd23c),LL(0xa0008822,0xddeaf170),LL(0x43b08954,0xe569f253),L_(0x000000b2), + LL(0x20ee092e,0x21969535),LL(0xd200f675,0x1aa95306),LL(0x8a20dfb4,0x450070d5),LL(0xe56ecbdc,0xa73c2aa2),LL(0x93697944,0x8cf15e09),LL(0x2bf1cc5f,0xb81e3982),LL(0xa98dee98,0x39d2614b),LL(0x4249763f,0x88bf80d0),L_(0x000001ce), LL(0x4194f3d6,0xea90be49),LL(0xeb5f7526,0x9d76e09e),LL(0x42892f62,0x665e7661),LL(0xdd2de6b9,0xdb45bef0),LL(0xe66edde4,0x0f0c29ed),LL(0xd947a3fe,0x39bccdcb),LL(0xdc0bb667,0x97600929),LL(0xeeaa185f,0xf355b62f),L_(0x00000198), + LL(0x05622c5d,0xc2d3d21b),LL(0xbe07feb4,0x9e1d3138),LL(0x90b99ecf,0x358fe997),LL(0x2ec0a3d5,0x95008edf),LL(0x7f72a6c8,0xc6e6cc84),LL(0x2b8ec523,0x351d40b6),LL(0x10aa3646,0x30961dc3),LL(0xdff38b1a,0x6d776cf7),L_(0x00000047), LL(0xafa6b1f7,0xfce248cf),LL(0xad217997,0xe663a7a1),LL(0x423b10cc,0x8d65dc51),LL(0x0215b195,0x0f10bc35),LL(0x0f4e07a2,0x23278029),LL(0x19d23499,0x304b98d9),LL(0x6127a2da,0x9fb0c81f),LL(0xed0c0943,0xcd486835),L_(0x000000c4), + LL(0xaf631c28,0xd0ac0ecd),LL(0xbaefab89,0x0a9db571),LL(0xe4775843,0x6c283a9c),LL(0xfebcf91f,0xd37751b1),LL(0xe02d1251,0x4c69aef4),LL(0x93ca62f3,0x756b2ab1),LL(0x017751a3,0x9921e7da),LL(0xf0df5f26,0x31fbf868),L_(0x00000112), LL(0x1547e61c,0xc24912f9),LL(0x6ce422f4,0xe5bc3bbe),LL(0x0c518f2e,0x00e5a237),LL(0x51ed5f7e,0xb6da428f),LL(0x1a77cbdb,0x248c6951),LL(0x086ad3a0,0xfd285428),LL(0x00d65807,0x460a5bc1),LL(0xc6265db2,0x728547e4),L_(0x000001fe), + LL(0x378f0a8d,0xcdbb56b7),LL(0xea484f2e,0xebecf09a),LL(0xbe1705e2,0xdc0d7050),LL(0xe83a83b6,0x5c8fdff7),LL(0x1cd41a57,0x58f038ee),LL(0x975aeb28,0x858f75ce),LL(0xddbb66ee,0x7455106f),LL(0x7e1bcafd,0x54e1961f),L_(0x00000128), LL(0xd2d34020,0xc329e633),LL(0x32cfb8ca,0x596dc91e),LL(0xe8fb4aa3,0x19c60dcd),LL(0x0c27fe63,0x9c2411d9),LL(0x49228e82,0xf4420f99),LL(0x5075f5a2,0x38a95326),LL(0xadb26b0e,0x7345059b),LL(0x67709e35,0x428212fb),L_(0x00000139), + LL(0xd8fc8db1,0x3a95d178),LL(0xb909e614,0x1860388a),LL(0x89b7600c,0x942112c1),LL(0xa080f4aa,0x5a1967f7),LL(0x5057c08b,0x13543a0e),LL(0xf9ac78fd,0x1598cafb),LL(0x9408a20a,0xfa7974b4),LL(0x8fb58bcd,0x17ad4e19),L_(0x00000162), LL(0xd603cb6a,0x57138c5b),LL(0xf8960264,0x185f172a),LL(0xea9d78b2,0x8652917b),LL(0x62148231,0x9b757159),LL(0xb7470a8b,0x4f2c7ae3),LL(0x532d7747,0xc96fd10f),LL(0x6b40b8bf,0x77081dbd),LL(0xa54da232,0x2cd44f13),L_(0x00000119), +}, +/* digit=63 base_pwr=2^315 */ +{ + LL(0x44140a9f,0xc1b5f874),LL(0x37761e89,0xc768e709),LL(0x052402d8,0xa7063fcc),LL(0x437e0d8f,0x5032ca28),LL(0xd7049706,0xe0560b81),LL(0xfcc5af72,0xdac1a63b),LL(0xabb68cfd,0xe89f3917),LL(0x257b3b85,0x80d7454a),L_(0x00000038), LL(0xbc9cca5e,0x001d4cbe),LL(0xe9651818,0x66b1014f),LL(0x64d65a97,0x511b3639),LL(0xd56646ec,0x26e7c4e0),LL(0xdfae8dcc,0xa94ae11a),LL(0x86e8d406,0x6e9a1a68),LL(0x47bbf4ad,0x3004a685),LL(0x13e8901b,0x5981c480),L_(0x0000008d), + LL(0xb7f0034c,0xc63223ff),LL(0xeed01f7e,0xb10c656e),LL(0xa95759d3,0xc8ceacdd),LL(0x5f68fe9f,0xb6ab8ec3),LL(0x50e97936,0x28c0b215),LL(0xe4ccc3b9,0x92be8e1d),LL(0xfc6be17e,0x20828c77),LL(0xb81bdb63,0x13352a78),L_(0x000001d2), LL(0xcfa9e131,0x3d9b3c1e),LL(0x0b5daa42,0x94567b3a),LL(0x6bf95aa5,0xa3d149d4),LL(0x8d0fbfb5,0x4e997958),LL(0x5e636b3d,0xc1e08ca4),LL(0x8fa3b11b,0x73645c35),LL(0x552e11b1,0x931ab993),LL(0x0db67bc8,0xce614c5f),L_(0x000000d3), + LL(0x78c98029,0xf005a100),LL(0x9be2e7f2,0x06f26644),LL(0x47f29a13,0x7b580ed9),LL(0x3f3b60f9,0x22198889),LL(0x7e6ec70b,0x9f87a7be),LL(0xfc2d715c,0xb2ebc47c),LL(0xfc003ea3,0xfa7b2218),LL(0x79438acf,0xbfd9d6c5),L_(0x000001c2), LL(0xd7ce55f5,0xdac555ca),LL(0x80f3c546,0xe5a4dad1),LL(0xa25a6ba7,0x2d4bd9fe),LL(0xa68cfbbf,0x35faf13a),LL(0x4e3df8bd,0xcfc847de),LL(0x8434c00b,0x4dfdf245),LL(0x40669463,0x6e619d42),LL(0x5f688c19,0x13d3a517),L_(0x0000004b), + LL(0x44f3544b,0x3aed7148),LL(0xbb901084,0x6321bcc4),LL(0x996ac002,0x53c74ad5),LL(0xcb634535,0x741982c7),LL(0xdc48a041,0x1196d8fe),LL(0x44c9f092,0xfabc20d2),LL(0x0a8fce97,0x32828d27),LL(0x62a6d447,0xcab0c775),L_(0x0000000b), LL(0x43969d2b,0x3a61da39),LL(0x4b749d7b,0xfb5b6d67),LL(0x9df6dae1,0xec275083),LL(0x4fd05c30,0x7da1a928),LL(0xb7bd6dae,0xec82a28e),LL(0x66cd19ba,0xa08ca71d),LL(0xd599b2c6,0x6c312c52),LL(0x5bfaa154,0x6795e306),L_(0x000001f0), + LL(0xd73110d9,0xe9c779ff),LL(0x99bf4200,0x2e4558d4),LL(0xb9ba6e9a,0x636dc521),LL(0x836fe297,0xa1c7e0bd),LL(0x461d465e,0xa229d229),LL(0x287fba32,0xe43c8f80),LL(0x5fa34491,0x76cbe0ad),LL(0x0e6b8f16,0x7a25d2a9),L_(0x000001d0), LL(0xdc2e36c7,0xd420ce9f),LL(0x59654147,0x2c11cbe4),LL(0x582dde44,0x73168c78),LL(0xcfbe66e7,0x5f455763),LL(0x55778942,0xd782c483),LL(0x9b69f069,0xff95fe3e),LL(0xaa1addcb,0x00a4bd0b),LL(0x47541c1d,0x8ad93857),L_(0x0000012a), + LL(0x8aa7d8c0,0x0afff918),LL(0x80ad064a,0x89af5deb),LL(0x7114ab96,0x4dbde778),LL(0x099fad0b,0xfd29cd3c),LL(0x525d6055,0xbd379d42),LL(0x4df50e85,0xdfc116d0),LL(0x3602e006,0x374d96b5),LL(0x2ee6c63f,0x6509a7f3),L_(0x000000f2), LL(0x6aa97902,0xee822c17),LL(0xfc039cb1,0x6c2fdf58),LL(0x5872cad5,0xea665324),LL(0x3b9e8ae0,0xaf2e64bf),LL(0xb8314c4d,0xa8f96bb4),LL(0x63c57f41,0x3df990e0),LL(0x5149d306,0x1d5f9b0d),LL(0x08ba6128,0x3d6cc9c6),L_(0x000000ba), + LL(0x5b4bef3c,0x84b34c8d),LL(0x0908a3fa,0x06e343a5),LL(0x8e41dac7,0xca844102),LL(0x83411f49,0x0712aa99),LL(0xd4bcaa5f,0xf85d2ba8),LL(0x0278367b,0xbdc302b7),LL(0x5016082b,0x54ed82be),LL(0xfea00712,0x1e47617b),L_(0x000001a6), LL(0xbea2cdee,0x5025ca72),LL(0xa8a5db48,0xd3c98c1a),LL(0xeb113cc6,0x259b9a28),LL(0x1b35c6d2,0x49923a55),LL(0x266d75d3,0x644a3ecc),LL(0x9590fb6b,0x221e1f1d),LL(0xa7f663c5,0x9c9bd811),LL(0x30cacfb5,0x8f25a4f3),L_(0x000001ad), + LL(0xda490054,0x5c5d4a76),LL(0x224e9112,0x74621c3b),LL(0x62ab184a,0x17406495),LL(0xedfb682a,0xc3f7c8cd),LL(0x16ae2053,0xd8e38d44),LL(0xdf044060,0x39ed9c28),LL(0x86143e57,0xf327b97f),LL(0x8b95f9f7,0x53853147),L_(0x00000072), LL(0x81550101,0x43b98e46),LL(0x05661b39,0xc1bcc1fc),LL(0x9ee23198,0x64ff1647),LL(0x115744fc,0x0f20d871),LL(0xcdf5ac56,0x92c9feea),LL(0x63cba9c3,0xa72f70b2),LL(0xadbac8fd,0x365c71db),LL(0x171aad35,0x9d51687d),L_(0x000000f9), + LL(0x7cba337f,0x7242ca8b),LL(0x45faaf9a,0xc08d85f8),LL(0x550ef4dc,0xb82ff28e),LL(0x814b8cba,0xbbe121da),LL(0x1eb4cd63,0x081656e6),LL(0x82eece40,0xf4405b11),LL(0xe9889d6a,0xf6c9d001),LL(0xbc4f3c1e,0xe85dc906),L_(0x0000001b), LL(0xd4907a17,0xbcfa56fc),LL(0xb8894301,0xa60a71ba),LL(0xc8290de3,0x5b4cf893),LL(0xfa8203e9,0xa8602943),LL(0xb0d9fec8,0x6b75b5c6),LL(0xacaeb1bd,0x40f20d5b),LL(0x228fdb83,0xe7477d37),LL(0x967812d8,0x3271b8d9),L_(0x000001d0), + LL(0x9302acf0,0x69acd4ec),LL(0x76812a69,0xd47ef468),LL(0x62f921ab,0xc8ee3434),LL(0xb7930834,0xc08c033b),LL(0x369c3e87,0xee51d0a2),LL(0xd98cac8f,0xc675c1fb),LL(0xa309b704,0x3fcbb3c6),LL(0x69a173a4,0x32c49495),L_(0x00000094), LL(0x2ef36de7,0x2b5e781f),LL(0x79bd3a70,0x68837e34),LL(0xd74e86eb,0x22881aa5),LL(0xecb38496,0x91b89a84),LL(0xdd2964ba,0x7caeee87),LL(0xb0230b75,0x83a10f40),LL(0x7853cadc,0x465657ae),LL(0xe45f5ad1,0x100e5033),L_(0x00000075), + LL(0x5443e17b,0x27034a2f),LL(0xae458db9,0xe02cc805),LL(0x361c4604,0xc6c6e812),LL(0xf53dab3f,0xe1de7819),LL(0xa93944c6,0x77575b10),LL(0x7d127be6,0x4580ec67),LL(0x18920ad0,0x6451a6a6),LL(0x595f7341,0xe3b018ad),L_(0x0000002f), LL(0x7a6f7a6b,0x73fafabe),LL(0xacea82d0,0xb8e018e3),LL(0xb66d3c1a,0xf0a068d2),LL(0xa0a76281,0x2960ab23),LL(0xd3310f1e,0x1ade815c),LL(0x5df5a459,0x4830c68e),LL(0x9bc40618,0x506f8ded),LL(0xa5b32181,0xb64aea9e),L_(0x00000055), + LL(0x11651e46,0xd2e44f39),LL(0x7f22b492,0xf166288f),LL(0x72f850db,0x45a14853),LL(0x6743ab2a,0x480b82ee),LL(0x235a84e1,0xbca609c8),LL(0x422668b9,0x2f4e85d8),LL(0x5d6f0bf0,0x792321da),LL(0x61afb880,0x2c095f02),L_(0x000000b8), LL(0x25cea9cf,0xe6bc2f57),LL(0x43f99381,0x4a832e1f),LL(0xe6089c84,0x51ad7011),LL(0x65600aa9,0x2a695207),LL(0x11447728,0xa07e689c),LL(0x7bb9a4c6,0xcd7b0e53),LL(0xdf06eaf0,0x78952329),LL(0x777c474d,0x10d2b00b),L_(0x00000107), + LL(0x42f9d45d,0x20322841),LL(0x736265c0,0x91a20b69),LL(0x7c956777,0x530024a3),LL(0xbcd4358f,0x2cfdf5c4),LL(0xe32fe9e3,0x69c3c240),LL(0x7dd472b9,0x16947a8a),LL(0xeeaaeb78,0x03c5cf25),LL(0x9aa3433d,0x521f3b6b),L_(0x00000018), LL(0x96f4132f,0x88ddc3b1),LL(0x00a93570,0xc5b29c7d),LL(0x5d8a1581,0xb3793bd2),LL(0x1877f26e,0x4435f13a),LL(0x4fc7c6c4,0x5b6c76af),LL(0xb032ee18,0x5465338c),LL(0xd7e32969,0x5e8d0f72),LL(0x82259fe6,0x38f0d401),L_(0x00000082), + LL(0xaebae92a,0x8093c8e0),LL(0x248ef981,0x84b971a4),LL(0x5353d713,0x8ab8dd10),LL(0xf3f56422,0x9e95615c),LL(0x163427ee,0x1dbed91f),LL(0x7cd8d83e,0xa05bff8c),LL(0x2a117b26,0x9094b7c0),LL(0x28d65130,0x8d73f3a7),L_(0x000001fa), LL(0x3fc6c29b,0xfb45cf4f),LL(0x5dd01b3b,0xa983b69a),LL(0xe3b24278,0xdda15e64),LL(0x0beba6e8,0xeabdafeb),LL(0xce3cbe7c,0xe28dd1f4),LL(0x03c3a01e,0x315483c0),LL(0x286b68f0,0x44cc13c4),LL(0x653661bd,0xa5a2b18a),L_(0x000000d7), + LL(0x837c224d,0xf83ea93b),LL(0xc7a428c9,0x308d0ccb),LL(0xdeef06fc,0xe456dad3),LL(0xd27b9dce,0x04dd575c),LL(0x8c1bbcfc,0x1c63319a),LL(0x479f6f73,0xed4daaeb),LL(0x7cb52d7f,0x9fe5930e),LL(0xd171cdbc,0xcd65b54d),L_(0x00000100), LL(0xf9b94ca6,0xbb8079a0),LL(0x2ea98b08,0xda724133),LL(0x24b7505e,0xedf1d97e),LL(0x5aed5e6f,0x283c1e51),LL(0xc39ad307,0xf64812a4),LL(0x76820a6c,0x13b5c88a),LL(0xb32f91ce,0xb8954a33),LL(0x211cbd9c,0x31a311e0),L_(0x000000ae), + LL(0xf859a830,0x3ef4f2d2),LL(0xcf466ff0,0x47044584),LL(0x78dc82b8,0xb52d320e),LL(0x8b5110dc,0xdfe140d7),LL(0xe07b117a,0x0b45fd46),LL(0x39af6581,0xbda19439),LL(0x26b6d5c5,0x8309f53f),LL(0x8091095a,0xaad23c7d),L_(0x000000d4), LL(0xa9e7ca16,0x90dd82bc),LL(0x1ee78b60,0x839c5155),LL(0x453fc776,0x2966b875),LL(0x6bf1d026,0x9e2a2996),LL(0x825d3c72,0x48c49cfc),LL(0x1345ab1d,0xad600996),LL(0x7e6049f3,0xf1b39850),LL(0x0b007da4,0x2c8f36cb),L_(0x00000038), +}, +/* digit=64 base_pwr=2^320 */ +{ + LL(0x90646dde,0xeba284c6),LL(0xdcd5cc91,0x292fa3ee),LL(0xea471fd6,0x5841cc32),LL(0x9fb23a12,0x35810a74),LL(0x4e18eb2e,0xd6133648),LL(0x5228a2bf,0x52cab6f6),LL(0x07542e74,0x40c74692),LL(0x62526cd9,0x36b9b329),L_(0x00000129), LL(0x063ef2a7,0x17573e4f),LL(0xca996c2a,0xc3d42418),LL(0x33e1f9c1,0x970fbd47),LL(0x246b3cbf,0x8c0b1561),LL(0xf0853508,0x16e93234),LL(0x8ff90188,0x74d99d7f),LL(0xaa556f85,0xd3b1d290),LL(0xdda5d989,0xab78218e),L_(0x000000d0), + LL(0x57077d65,0x87233d65),LL(0x32cea9ff,0xb1454f2b),LL(0x6963e65d,0xd5f2627e),LL(0xd15b05b7,0x68cad15b),LL(0xf2c9215a,0xf9679cfe),LL(0x982da4ec,0xdd21cc1f),LL(0x73910763,0x3925aff6),LL(0xce110fdc,0xad0858b1),L_(0x0000003c), LL(0xdb7b5667,0x160c51bf),LL(0x88f58f75,0x9e39ee8b),LL(0x713a7cf3,0x5af813ed),LL(0x8ac4ac36,0xa788e43e),LL(0xe789c040,0xc10b5e01),LL(0x3d0cb49e,0x26fdddf3),LL(0x3f2d9bd7,0x504e525a),LL(0x776e3c30,0xa456acdf),L_(0x00000051), + LL(0xa6499d4a,0x23707d7d),LL(0x4b6d85bc,0x2372ec00),LL(0x4b483dd7,0x838f63c9),LL(0x869b15c9,0x40b6584e),LL(0x291644dd,0x05bb5ad6),LL(0x693ec1c9,0xc10969be),LL(0xb5c6018d,0xb81150c7),LL(0x04c9c113,0xbd460de8),L_(0x0000000b), LL(0xb81757db,0x5ad558a1),LL(0xa356589b,0xf88e046d),LL(0xf093ea9c,0xede9de0f),LL(0x39acd54e,0x19ec3f88),LL(0xfcbf451f,0x44ec243f),LL(0xf8b02c0e,0x981fd0d1),LL(0x42d2cc07,0xf4701bca),LL(0x3f363b43,0x30f2e9e4),L_(0x000001f9), + LL(0xd9f5845f,0x006b0772),LL(0xa8c7c3d7,0x1ba3ff28),LL(0xc1d96b23,0xc17a4f5f),LL(0xda50f432,0xca88f653),LL(0xfce5ef14,0x31ac5da9),LL(0xd10257bb,0x18d3105d),LL(0x06b910de,0x4f950082),LL(0x8ed121d6,0x748b9a29),L_(0x00000083), LL(0x0ad3e4ad,0xfedc9456),LL(0xcda193af,0x30addb34),LL(0xf39dff50,0xa3a58a0d),LL(0x586d72c1,0xd7c02e84),LL(0x7190f71a,0xb6dddddd),LL(0xd7f7815a,0x93fd431d),LL(0xb059af28,0xdb90a301),LL(0x626d66eb,0xb55b2545),L_(0x000000c5), + LL(0x55a2cc5b,0x02a70327),LL(0x60173b4c,0x700e187b),LL(0x853a0c8b,0xebfa5d41),LL(0xa74d3fcb,0x6636a248),LL(0x7f152910,0xcd439df1),LL(0x433bf866,0x3d361a48),LL(0xd52b92a9,0x96508fce),LL(0xcdde5dbf,0x08fb48db),L_(0x0000004c), LL(0x57d607dc,0x41e6d707),LL(0xa287bad7,0xc1d0199a),LL(0xaca83d8b,0x3248272c),LL(0xdeea6deb,0x81490886),LL(0xd5830e62,0x803b3e7e),LL(0x0b551501,0x329bb8f5),LL(0xe61ae410,0x1b1ec67e),LL(0x2add209b,0x9d8f057d),L_(0x000001f7), + LL(0x4aeeb4f7,0x159240ac),LL(0x701cba0d,0xbe49e9de),LL(0x1e2030d5,0xa8d80ea6),LL(0x891f5b9f,0x389aa0a7),LL(0x281d5c9e,0xbf08f46a),LL(0x42c2a6a9,0x30133d89),LL(0xcae5c626,0x26d80fbd),LL(0x976ed6f2,0xd7445273),L_(0x0000007c), LL(0xebe5a160,0x4b64112e),LL(0x1ba10f05,0x3c715556),LL(0x076de398,0x051c721c),LL(0x1b6338a0,0xed93ec2b),LL(0x0b18e617,0xe40d08e3),LL(0x2546a805,0x39d986d0),LL(0x289546bf,0x87fe36cb),LL(0xcb29a40d,0x28ca6d96),L_(0x00000038), + LL(0xf08b61b9,0xb8888aaa),LL(0xeb89b8a3,0x504b24ba),LL(0x13c31ce0,0x1577d88f),LL(0x1d308489,0x01541da0),LL(0xc31edb15,0xfbe18906),LL(0xcb88a0c0,0xb123cf8a),LL(0xe0a54814,0xce17eb8d),LL(0x12d30b10,0x5435ad11),L_(0x000001c6), LL(0xd6e0b2ed,0x7a3c3081),LL(0x198cbd6e,0x18481bd1),LL(0x9feff602,0x8a4e33b7),LL(0x4dc9559a,0x242155d3),LL(0x49b265ae,0x0458dbdb),LL(0x66003375,0x19c33688),LL(0x53753ede,0xac09e0c8),LL(0x0eb6969a,0x25b27567),L_(0x00000052), + LL(0x13db9105,0xfd4c030e),LL(0x4bb182d8,0x45ba7b8e),LL(0x24d5733c,0x9bbae322),LL(0x857e0992,0xe18395c5),LL(0x7a4b7ec5,0xbbeb3431),LL(0x9d2ffacf,0x70996597),LL(0x0dac7ff4,0x634b33c0),LL(0xd22ac181,0x5a113dab),L_(0x00000132), LL(0x4a184515,0x1af6d0b4),LL(0x4b60b5e3,0x60067ebd),LL(0x7c6c236a,0xccf47b3d),LL(0x199b1be8,0x1dbd1cc7),LL(0xe888eba2,0xb4932466),LL(0x034c21f8,0x19ff1dee),LL(0xf9da1696,0xe040c95f),LL(0xee7e95c7,0x9dbe56ef),L_(0x0000015a), + LL(0xf23e08f9,0x33a41f31),LL(0xb89596d6,0xde8f6d08),LL(0x36e37e25,0x09152867),LL(0x911d84ea,0x4f3476b2),LL(0xba9def4c,0x44e0d519),LL(0x12065979,0xdfef8c30),LL(0x91c87d28,0xa45cf33c),LL(0x6b8dd103,0x5a48975d),L_(0x000001b7), LL(0x3141bb8f,0xe73885a7),LL(0x36da50e9,0xdc731cf5),LL(0xb97f8cf8,0x67bb07a8),LL(0x922b0be5,0xfb414a3b),LL(0xe9cbd504,0xd391785e),LL(0x2631b899,0x9eb65672),LL(0x50f31f7b,0x4ee45215),LL(0x0d4d0798,0x23e25b24),L_(0x00000039), + LL(0x24f12ded,0x6178bac5),LL(0x9eabc3c5,0xbfa39955),LL(0x503d57c5,0xda006222),LL(0x8e465ace,0xe390a3d7),LL(0x363ca671,0x7ca51f49),LL(0xe0376d27,0xab1c9afc),LL(0x325dbeb1,0xf303951f),LL(0x2ac46079,0x4fcc04e4),L_(0x000000b1), LL(0xa05b906b,0x1e1f126b),LL(0x7a1f14f0,0x0b9e64fc),LL(0x49fb5176,0x394e56b2),LL(0xc1fff51a,0x0b50d33b),LL(0xf135bc4a,0x41e4f563),LL(0xf07911e8,0x0008c3a8),LL(0xfd1855b2,0xd0455066),LL(0xb1f8cdf1,0x3e4e10b9),L_(0x0000006c), + LL(0x03ffd8c0,0x47688773),LL(0x75ef0188,0x81134439),LL(0x6a21abe0,0x3ff532d6),LL(0x9e0177ad,0x3c27f56d),LL(0xe284df24,0xd99892e8),LL(0xfcaf2cd5,0x668c2ac2),LL(0x72c31d05,0x450ea985),LL(0x617df772,0xd1386608),L_(0x000001fb), LL(0xa7faa0ca,0xa81bbd89),LL(0xb7cb40e7,0x6545e4d7),LL(0x4e799290,0x48c0ef0c),LL(0x129414b6,0xf9bc6b77),LL(0x75cac719,0xcf3cf61a),LL(0x7090a084,0x5de671da),LL(0x573167fe,0x53c2428e),LL(0x9be66bcd,0x581cfd76),L_(0x00000105), + LL(0x9912480b,0x868b1c0c),LL(0x6fc274a1,0x83263833),LL(0x7470faca,0x28bbd5e9),LL(0x10a9a5ed,0x92bc266f),LL(0x1a2df530,0xc1420bb6),LL(0x26088825,0x6de27806),LL(0xb843fbcd,0x96eddc77),LL(0xfaacb0c0,0xe58f23ff),L_(0x000000a2), LL(0x265f30c8,0x304fead2),LL(0x46f8b4da,0xcdc2767a),LL(0x030d0ccb,0x4ecb91a4),LL(0xa6cdee79,0x546f1657),LL(0x2f10c656,0xa2c85665),LL(0xdaca38a8,0xb2b32405),LL(0xa84dd381,0x29386bb0),LL(0x4d4926a6,0x3ed722f3),L_(0x000000e5), + LL(0x6732b4e2,0xb158c617),LL(0x70c2bdde,0x1e929730),LL(0x03b67c3d,0x83aa10cb),LL(0x207b6554,0xf8bd1f2f),LL(0x65897412,0x52c6a1bf),LL(0xd2b9e2bf,0x4072e449),LL(0x4573028a,0x51728cdb),LL(0x08f548f4,0xa5fb2b4e),L_(0x000000cb), LL(0x7e81850d,0xc30af1b8),LL(0xf64d0544,0x91fac057),LL(0xe6a44ca8,0x97b402f5),LL(0xf3758797,0x7a48f50b),LL(0x9ec9c59e,0xa20d052f),LL(0x7e0c3edb,0x50d02201),LL(0xba6cf070,0xc4603d10),LL(0x0fd79a40,0x04379719),L_(0x00000047), + LL(0xaa79abd0,0x33d05c0c),LL(0xf4e66422,0x28d54dca),LL(0x3f1a0e0a,0x1b90591f),LL(0x8319bf69,0x50c92b63),LL(0x45f8cdc5,0x2b172382),LL(0xc8908923,0xce47651d),LL(0x282da333,0xe6f22c70),LL(0x6dc02842,0x73a13e20),L_(0x00000052), LL(0x2709e7a5,0x9bb811ca),LL(0x2aa27cb4,0xff020d4c),LL(0x8f138cd3,0x181a1cec),LL(0x35013750,0x47863f93),LL(0x37481122,0xe6028031),LL(0x18f58c65,0xf01c48b5),LL(0x565f6657,0x9f20924b),LL(0xa7b0ed3f,0x643987ef),L_(0x000000eb), + LL(0x25a6701b,0x151f4865),LL(0x1b42c497,0xf30bdc50),LL(0x055325f0,0x144e0aa2),LL(0xf8e98fe1,0xa165a395),LL(0x2e0f9b5a,0x25afa523),LL(0x3ceadf0d,0x70ed634b),LL(0x55dbb9b8,0x1b25f855),LL(0xe2ddb61f,0x8a54708c),L_(0x00000000), LL(0xd7b55067,0x74847fca),LL(0xf91dd3a7,0x92445716),LL(0xe74dda4f,0xfe51e6c5),LL(0xd2ebe9fa,0xe3bfd67c),LL(0xec65184e,0x51f3767f),LL(0xc26dcf5e,0x6092d164),LL(0x7562e715,0x48053ca5),LL(0xc341746a,0xfe264b56),L_(0x000000c8), + LL(0x1486b225,0x688f0816),LL(0x55ab4efe,0x012b1be7),LL(0x48d9609c,0xdb068e78),LL(0x0fb98843,0x958488ad),LL(0xff5eda2d,0x83f6d23c),LL(0x3ec7372a,0xb176c41d),LL(0x5d185ec0,0x925e4903),LL(0x476314a5,0xe4ff9579),L_(0x0000003d), LL(0xc1b43aa4,0xd529cc94),LL(0xd2ad417d,0x2dfe7d43),LL(0x360ab4fa,0x52cc454d),LL(0xfb2e9eb5,0xa4732c24),LL(0xcf82a235,0x68d1e843),LL(0x67bb7a40,0xbca2ab8e),LL(0x91877eaf,0x99566cd1),LL(0x62574ab0,0x22f9872f),L_(0x000001f9), +}, +/* digit=65 base_pwr=2^325 */ +{ + LL(0x8bbe4fe2,0x2d85f820),LL(0x287db7bb,0x702fbecc),LL(0xe568667e,0xa157f36d),LL(0xf4ecbeb7,0x484f3352),LL(0x941bbfbf,0x558da014),LL(0x3d5fe38d,0x7b22586c),LL(0x8a8ef1b3,0x7a9e7fea),LL(0xba594962,0x0c422ebe),L_(0x00000074), LL(0xe63724c0,0x34c2ec0f),LL(0xeb882690,0x8c7ffbe0),LL(0x16f607ed,0x0a729f09),LL(0x9cab235b,0xfb783d21),LL(0xe85a3bb2,0x7a1f91a0),LL(0xaf1659ef,0x067ef36e),LL(0x3c3d4be9,0x2b43e992),LL(0x3b5e5bd9,0xe81391aa),L_(0x000001e3), + LL(0x6902a59d,0x58cf4fb6),LL(0x2d970cf0,0x6108b652),LL(0x8db98564,0x1c524ec7),LL(0xc375bd09,0x8ded01ba),LL(0xeaf41a1c,0xca7571d5),LL(0x1513bf75,0x83433ae4),LL(0x831a58ce,0xb1cbad60),LL(0xd4b5c1d0,0x7e3558b4),L_(0x00000012), LL(0x2423577d,0x5fc5bcaa),LL(0xcd90416c,0x1fd11e95),LL(0xf9cd3e85,0x77429d71),LL(0x4b143cec,0x818263e7),LL(0xb694e333,0x7b0bed2a),LL(0x078fef20,0x900d9d3b),LL(0x22c62d90,0xb2dcc393),LL(0xf713057f,0xee2cd8c7),L_(0x0000010a), + LL(0x62e274a4,0xc6a3697b),LL(0x36666b6c,0x771114f0),LL(0x4615de0a,0x4656bc00),LL(0x27ed1a54,0xfe1b0ffd),LL(0x7a367a4c,0xa7b011fe),LL(0x9395287b,0x1539028f),LL(0xe474d2cd,0x67ab6630),LL(0x50df81c9,0xd416f7d8),L_(0x00000009), LL(0x15224116,0xcd4ff017),LL(0x14e9eb99,0x68ce9cb6),LL(0xefe50131,0x878690dc),LL(0xf0500068,0xa58b25b4),LL(0xfe708a3e,0x1697bfbe),LL(0x4cbc1887,0x109e6148),LL(0xd61b572d,0xea6e538f),LL(0xcd507a67,0x8cf0642b),L_(0x00000010), + LL(0x44c4f316,0x254f2817),LL(0x74f04275,0xe534cfb9),LL(0x22ee390d,0xf368e25e),LL(0xbc4caed9,0x0d3f5a1e),LL(0xd7010447,0x26bb7427),LL(0x91f02404,0x7f0d8308),LL(0x993cd5f3,0x4ebe5786),LL(0x1ba9d89f,0x2549a02c),L_(0x0000007b), LL(0xef3c1601,0x575527d2),LL(0x33afd2d8,0x6240eaa7),LL(0x200435a3,0x0df72a8e),LL(0x104dbed5,0xe9f3dcc7),LL(0x1f5c3464,0x98404140),LL(0x791b398c,0x1581b281),LL(0xd77cd49e,0xa203aa2a),LL(0x2329530c,0x70040738),L_(0x0000004a), + LL(0x4c2c9776,0x8715b292),LL(0x5fca8e16,0x0659f3f5),LL(0x904a8960,0x7cdfccac),LL(0xd46df8f8,0xe8078ecb),LL(0xae2184c0,0xc1352930),LL(0x904b839e,0xf3fd8786),LL(0x36602186,0xc3ec21de),LL(0x2a20030f,0xe08de817),L_(0x00000046), LL(0x36bb6226,0xd7e4cb2f),LL(0x812cd124,0x5ac9609a),LL(0x83d9653b,0x690acbe2),LL(0xf981cac9,0xc894c3a8),LL(0xd274538e,0x286285d9),LL(0xc202f8f4,0x24269d02),LL(0x51bb2579,0xe768b7b8),LL(0x121f910a,0x8baea845),L_(0x00000158), + LL(0x41280631,0xf6a81b1e),LL(0xcf66e145,0x2a3bda3a),LL(0xa88833db,0x44164a42),LL(0x4e0df1ec,0x754bd187),LL(0x89a6c53a,0xff8dc770),LL(0x961d8b4b,0xa3761531),LL(0x87d46b93,0x31b05601),LL(0xf7105b06,0x4ef74177),L_(0x00000156), LL(0x5c72ab48,0xbc131ab6),LL(0x4688d4bb,0x6977d5eb),LL(0x82e94cb0,0x8706473c),LL(0xb785ac18,0x7362c724),LL(0xae704972,0x3b45de5c),LL(0x2e6bdb68,0x2c67f7d5),LL(0x99b0063e,0xa06ed86c),LL(0x4969a5c7,0xc4bf63b2),L_(0x000001fa), + LL(0x181e12e7,0x32f70f29),LL(0x4140b7bb,0xbcda177c),LL(0x0fdc8422,0xad59d7db),LL(0xd2a3a29c,0x9c1893f4),LL(0x8f80936a,0xe60fd330),LL(0xa903804b,0x6b3cc7d2),LL(0x0e38278b,0xfcb7a0c8),LL(0x31deb3a4,0xb47a9458),L_(0x000001ff), LL(0x2d8fb441,0xc70a541d),LL(0xcbbeaa75,0x6f004b75),LL(0xd7f127d6,0x1d4ef334),LL(0x15636fa0,0x758ac159),LL(0xa2548921,0xb047a7de),LL(0x60705693,0x128b4b7e),LL(0xa5696c87,0xf499a64e),LL(0xa206ac49,0xf272bcca),L_(0x000001bd), + LL(0xe83f7b24,0x7a4b896d),LL(0xb2e00072,0x47a68dd1),LL(0xd43d9655,0x1ce79a50),LL(0x6abc1f1e,0xec87252c),LL(0xe7160fe5,0xb60d6a5a),LL(0xdcf45caa,0xd235985f),LL(0x1b3180d9,0xf8982569),LL(0xdc646ab8,0x446d6798),L_(0x000001f0), LL(0x8387586a,0x6eec719b),LL(0x5f9db663,0xcc9431de),LL(0x38f4a187,0xef383b03),LL(0x3dbac366,0x2fa36674),LL(0xcc0b0d02,0x5760fac1),LL(0x67948b1b,0xe8d42650),LL(0x93934495,0x4f889216),LL(0xd3c64b8f,0x1cd8ec2e),L_(0x00000128), + LL(0x354d871a,0x107d6bfc),LL(0x5816dc43,0xb8b5b662),LL(0x1fe1463b,0x973f88f0),LL(0x4370119d,0xc84691e3),LL(0x153d37fa,0xd0059b51),LL(0x9a4e583e,0xe99b060f),LL(0x24c8671a,0x8d5b7c8c),LL(0xfdf410b1,0x0db2233f),L_(0x0000002f), LL(0x3e3f1b42,0x08c95cdd),LL(0x07dbde25,0xf5273466),LL(0xf0969049,0x76e98baa),LL(0x8cba001d,0xae173b76),LL(0xcde8bcc2,0xf10bd659),LL(0x09ae5065,0xc7bec674),LL(0x5cecdf22,0x4bdaed4b),LL(0x41bc9eb9,0xc459b9e5),L_(0x00000146), + LL(0x6121d2de,0xd08a3672),LL(0xbcb161c1,0x52ff0a6b),LL(0x0593dede,0x4b01e845),LL(0xb5c016b2,0x421052e7),LL(0x65c310a3,0x6c1dd249),LL(0xf97c5a2d,0x5a4e53fc),LL(0xe551417d,0x0e004126),LL(0xbf9b31fa,0xc101bc8b),L_(0x00000125), LL(0xf17fd0e4,0x2811e723),LL(0xeaad08c2,0xcc586f7d),LL(0xc771ce2f,0x8c0556ea),LL(0xef8166e5,0x32556e9b),LL(0x2d11bd0c,0x11e66977),LL(0xfe7d92c3,0x646a8dfa),LL(0x58b69181,0x8a624576),LL(0x5de6bd35,0xdeb3cceb),L_(0x00000027), + LL(0x81d3dab7,0x88f96f05),LL(0xc1d3ecbd,0x3593555a),LL(0x3073315c,0xb56c336e),LL(0xaec91693,0x5eea4cf3),LL(0x2eade86a,0x90e05846),LL(0xe134f505,0x9189d76c),LL(0x8d429f7e,0x0feade8a),LL(0xf0013b30,0xe083daf3),L_(0x00000097), LL(0xec2945ab,0x817e33d7),LL(0x9c2537c7,0xa44bf13f),LL(0x9a6a317a,0xda31eee4),LL(0x35ae34c0,0xa0379d97),LL(0xd66b27c5,0x76a48571),LL(0x1ae6d028,0x5d83028d),LL(0xbb8dadac,0x1e4ebd89),LL(0x8aaff54e,0x67e3f97d),L_(0x00000083), + LL(0x0bc690f6,0x9a7f8ba8),LL(0x2992a59b,0xa9efff68),LL(0x1a328627,0x3c1d097f),LL(0x555f21eb,0xf75afbb3),LL(0x48ff742c,0x4bf1016a),LL(0xa10b236e,0x5c770a94),LL(0xff3e57b4,0x5915a516),LL(0xc042020f,0x9df7440a),L_(0x00000186), LL(0x18a6102c,0xecaea7dc),LL(0xbf14c4c4,0xd0035f1c),LL(0x8343dde4,0x19dfc08d),LL(0x3a483722,0x5b130cf1),LL(0xc107a176,0x30fc7b7f),LL(0x6717617b,0xf8cab932),LL(0x626ffb5f,0x59269de8),LL(0x74af7c16,0xbf37b9d1),L_(0x0000000d), + LL(0x81146610,0xd31224fc),LL(0xe9393683,0x52cacad0),LL(0xd4fad3f5,0xd36819ae),LL(0x14ee7de5,0xb8c9f302),LL(0xdb882d76,0x103a3f52),LL(0xb3362378,0x1728ce43),LL(0x0f7553db,0x29c76302),LL(0x56ba2d84,0xc2f44114),L_(0x0000009f), LL(0x8ea45de7,0x3c639715),LL(0xd8b8276f,0xacdd7488),LL(0xac8ea8c0,0x912aac3a),LL(0x8de7940b,0x3dabab2d),LL(0xd5bb2c71,0xbc3f4a45),LL(0xbcc2e33c,0x2bf9f840),LL(0x9d0edeba,0x4b00c80e),LL(0xcbe852a6,0xbe4c368d),L_(0x00000191), + LL(0xc0428b2a,0xc2974837),LL(0x06284fef,0xe24d882e),LL(0x7041703c,0x6f37e52f),LL(0x5e1e37fd,0x7853375d),LL(0x145a0690,0xcc75898e),LL(0x270c5225,0x61f33577),LL(0x82c5658c,0x777ab969),LL(0x47024eca,0x315f136f),L_(0x00000012), LL(0x6ae06c18,0x8c1cda05),LL(0xb7db1fe6,0xedf31bed),LL(0x7f07ba36,0x8079b5f2),LL(0xcdbc2d84,0x22d262c8),LL(0x4bb1ece6,0xb457935a),LL(0x79793249,0x8614cc62),LL(0xe89f8430,0x258e4fa5),LL(0x836da5fd,0x759ca7b4),L_(0x00000009), + LL(0x8d1df13f,0xfa6cf668),LL(0xce181709,0x4b169dbb),LL(0x5bee0010,0x618d280d),LL(0x28a88cdb,0xa9c8042e),LL(0xd8239424,0x8ce15b95),LL(0xcfce331d,0xda740deb),LL(0x6f83c378,0x3c616a52),LL(0xfc05f1b1,0xda236e18),L_(0x0000013b), LL(0xc1e90721,0x8647ebee),LL(0x64ec0125,0x0db33259),LL(0x91422332,0xf49a7d94),LL(0xa2819732,0xcccef356),LL(0x9b90c693,0x87f18954),LL(0x805deff2,0x22aa64c0),LL(0x294b5e96,0x352be09c),LL(0xa610a1bc,0x8368526f),L_(0x0000017e), + LL(0x1fdc38a3,0x8a8479d8),LL(0x893e0d1c,0x045ea96a),LL(0x972cecee,0x37445b26),LL(0xb250ed0b,0x1c0a16a9),LL(0x08e477bf,0x7509c768),LL(0xc826b683,0xb74870c4),LL(0x008a3f9f,0x4d580408),LL(0x4b88d0f7,0x18d474fc),L_(0x0000003d), LL(0x2178ecd9,0x2fa143fb),LL(0x726dcabd,0x36d39ee2),LL(0xe017d3cb,0xd8d9e011),LL(0x43bd77e2,0x332c8650),LL(0xc8965069,0x3231a13f),LL(0xf7a775c4,0x1e3de078),LL(0xe93c91cf,0xe0f7c892),LL(0x50d48604,0x27097492),L_(0x0000011d), +}, +/* digit=66 base_pwr=2^330 */ +{ + LL(0x3a3e42bf,0x9e603471),LL(0xfb50e447,0x2536308c),LL(0xf617634a,0x9549272f),LL(0x302ba17f,0x3e264556),LL(0x0f6ed916,0xddb056ef),LL(0xc67d2e92,0xf04b9449),LL(0x7bf608be,0xe0fd2d62),LL(0x5ba41494,0xfaa0f9ad),L_(0x000000ca), LL(0x08a03740,0xac0394a9),LL(0x9ed3e6c1,0x9017e273),LL(0x2bf950e4,0x441c9b0d),LL(0x9856ca69,0x717b7978),LL(0x3315b53c,0x66f1bf12),LL(0xc5bce131,0xdc85d5ff),LL(0xf7b0dacb,0x32365700),LL(0xf85306a7,0x22ce0f19),L_(0x000000fc), + LL(0x9bda8667,0x4ae474b2),LL(0x3a2640ed,0x3684de2b),LL(0x21f91da9,0x424bab62),LL(0x9955df67,0x50d60209),LL(0x5193b4b5,0x196c99d5),LL(0x8e9f2748,0x7e7f3c74),LL(0x31e6b3fe,0x257248f6),LL(0x73f47f4e,0x56db9ba3),L_(0x0000018f), LL(0xbc4dd12f,0x48bc357e),LL(0x3556892c,0xfa4353a3),LL(0xb72124cf,0x6ea40bee),LL(0x1dbe3505,0xb37aa3c7),LL(0x2e951ca1,0xaddc96c7),LL(0x71de6fca,0x58ae291c),LL(0xf88244eb,0x96fd42af),LL(0x7e89a7bf,0x1c5d8ae9),L_(0x000000b4), + LL(0x263c0965,0x5894fe38),LL(0xa61f78f7,0x1b7d597b),LL(0x4cc9003f,0x94b8d7ad),LL(0x0c50139b,0x899c26b5),LL(0xd4d5af57,0x5801efbb),LL(0x7d0705ee,0xc45f009b),LL(0x345f5d52,0xc52fa5f2),LL(0xda142009,0x8d175fe7),L_(0x00000018), LL(0xbfaa39a3,0x3b59142d),LL(0xc3639f82,0x8ec202a8),LL(0x87394d85,0xb2496e6e),LL(0xa4035f4b,0x7b3e291d),LL(0xcab52bdd,0xda4a9abd),LL(0x41430674,0x23a5aab4),LL(0x7c18c413,0x57ee045c),LL(0xe39c61ef,0x6008e4d9),L_(0x00000190), + LL(0x1fc12350,0xc78ac751),LL(0x51e9a589,0x6a5f85af),LL(0xc09d63e5,0x8ce24a89),LL(0x9b655b51,0x5441652a),LL(0x9b445da7,0xf4ffab48),LL(0x9523b0e9,0x23e77128),LL(0x90aaf7cb,0x99234af2),LL(0xb5c9bc78,0xa65dc198),L_(0x000001dd), LL(0xbd5a6f7c,0xfaeeacca),LL(0x00e72c44,0xa2bbbd59),LL(0x47a63782,0xf531aecb),LL(0x67c393bb,0xc7dda450),LL(0x31630b09,0xe719fa6f),LL(0xc95e46b2,0xf849f3a0),LL(0xdeaf5d70,0x68299654),LL(0x827dd5d4,0x286bc1f0),L_(0x0000016c), + LL(0x70c9336e,0x9eae7cc9),LL(0x62e9226e,0x3410c389),LL(0x2f9c24f5,0x71f68cfe),LL(0x090966e9,0xa4f25f7a),LL(0xbb4733af,0x45a0c4d6),LL(0x6303208f,0x0dc0c0a0),LL(0xc45e9f18,0x9a589e6d),LL(0x5c94f082,0xb9c34b5b),L_(0x0000011d), LL(0x0284760d,0x9fc32695),LL(0xaccb375d,0x15ea0e6d),LL(0x5d3b353b,0xc2dc172e),LL(0xdcb147d5,0x96265816),LL(0x7b5ea6b9,0x7188496d),LL(0x6c199f62,0x067983d5),LL(0x8be2b6ee,0x804ab5f0),LL(0xb8433a5a,0xfb9701f7),L_(0x0000017f), + LL(0x9106f208,0xf346db2e),LL(0x75d8b8a7,0x6d441b3f),LL(0x33c9dd4c,0x49bf3101),LL(0x43c1a96f,0x586195d3),LL(0xc64bca08,0x797aa157),LL(0x35872dbe,0xf8494dd7),LL(0x155f257f,0x370900d2),LL(0x42b380b7,0x2ec6eba8),L_(0x0000006f), LL(0x1c0aaf14,0xd54c0210),LL(0x9ba3b710,0xdf76d347),LL(0x79738efe,0x168b7e7a),LL(0x59395338,0x5be21cb3),LL(0x786b578f,0x6c93997c),LL(0xb42b9419,0xda95deb9),LL(0x1b5aa55d,0x1941c038),LL(0x6282d548,0xdc8f9a51),L_(0x0000014b), + LL(0x8b6edce5,0xc54fa3d4),LL(0xc9331956,0x37673a44),LL(0x95ef7146,0x8699a77e),LL(0x35d322ef,0xe5aa4366),LL(0xb0a5fb37,0x1c2f8160),LL(0xdaf11474,0x6c679654),LL(0x4ae2c0a4,0x25f5bd9f),LL(0x0cd1a20c,0x2812f915),L_(0x000001b7), LL(0xead818f2,0x6ba35704),LL(0xddf43f70,0x66ebac5d),LL(0xbd74a353,0x5836be03),LL(0x8be404aa,0x606cb997),LL(0xa72b6949,0xe5570eb3),LL(0xe6f5f53a,0x1550fdd3),LL(0xd841cc12,0x83299eb2),LL(0xcf113a07,0x76117e23),L_(0x0000014d), + LL(0x8ca6af16,0x0412d583),LL(0xe9241a8a,0xac6aa964),LL(0x24077ab2,0xe1536c1d),LL(0xad189da3,0xdf56af4a),LL(0xfbfb6e01,0x46ef9e57),LL(0x8ca8e624,0x7c9eb17f),LL(0xcbcb351a,0xf3eda4f9),LL(0x0985fb54,0x69708739),L_(0x00000029), LL(0x2e5fdd15,0x4656d8d3),LL(0x4d7980be,0x8d7ed681),LL(0x65dbc6a6,0xe9b6528d),LL(0x433cebeb,0x9dfcc27d),LL(0x25c88d26,0x273aec82),LL(0x43f7caaf,0x8662d906),LL(0x1c78327e,0xe4a09eb4),LL(0x04763fda,0xad9bd2f6),L_(0x0000010e), + LL(0x4dc5df22,0x56bd282f),LL(0xc5002426,0x8905b0bd),LL(0xc776fda9,0x5fecb366),LL(0x691702ab,0x8c3c6d77),LL(0x3eafba03,0x7b9bb860),LL(0xa5a38b66,0x288652df),LL(0x9d4dccfc,0x8b876824),LL(0xf937bd4d,0xedcfeccb),L_(0x000001b7), LL(0x6481cd26,0x4223e6a4),LL(0xffdb1d9f,0x44384141),LL(0x4395593e,0x68a0f97c),LL(0x4b9f43be,0xa0157cb8),LL(0x99290f7c,0xcccef6ba),LL(0xef0777fc,0x4349cd23),LL(0xc43d71c0,0x17318622),LL(0xa3bb9fb0,0x5a9a1343),L_(0x0000009d), + LL(0xf567f47a,0xd92ddb9e),LL(0x22ba5c1f,0x65cc6bf6),LL(0xa333c9c6,0xb76d024f),LL(0x521f0218,0x51355f8c),LL(0xb277d241,0x061005e2),LL(0x36014e7f,0x322c2c56),LL(0x52d2dee0,0x8916c0e7),LL(0xf40b1b75,0x0e73d5bd),L_(0x00000126), LL(0xc2ed535a,0x2bc1b23d),LL(0x34905a27,0x31577092),LL(0xac41b5aa,0xf6758a71),LL(0x0e95917e,0xeccda7b1),LL(0x35f458d2,0x52d35c5f),LL(0x61af1ed0,0x42e21d1f),LL(0x99ea1f96,0x1b6c4f11),LL(0x1c9ff42a,0x5a729a64),L_(0x00000031), + LL(0x5f04894e,0xa860137a),LL(0x2bb38059,0x7d4fcbe1),LL(0xaebc7ba3,0x3de80141),LL(0xabc6d3af,0x0ce79f66),LL(0xecaf11f9,0x9743b455),LL(0x23367c7f,0xcf9fcf33),LL(0x458f9b06,0xaf18324a),LL(0x1dd894da,0xc4c95fe7),L_(0x0000010b), LL(0xd8ec1140,0xe5b4edaf),LL(0xff94f2f7,0xdb54a58e),LL(0xc8f912e0,0x655ce3bf),LL(0xdffa0710,0xb0757830),LL(0x0f2d4402,0xb963f905),LL(0x95d5e868,0x098d24ba),LL(0xcdbb826b,0xba591cbd),LL(0xb02b1feb,0x6a8df836),L_(0x000001ce), + LL(0xc29bd6ff,0x108f42a8),LL(0x9cf21db6,0xddcfd187),LL(0x555cfe2b,0xaf269c11),LL(0xe7b4d452,0xc4011856),LL(0x3cb7c3fc,0xfe6e4559),LL(0x415957c0,0x8996b215),LL(0x3b983b2c,0xbe5cf31d),LL(0x0312f953,0x78abc3a0),L_(0x00000170), LL(0x39b80aba,0xd52c0d6b),LL(0x847e724e,0x42bcb7b2),LL(0xcfdfc839,0x2ddac314),LL(0x2aac1c0a,0xa690e67e),LL(0x60736a1d,0xe310507c),LL(0x15f2f407,0xa30b8b85),LL(0x03447dd4,0xf3ddc7c2),LL(0x87208fe5,0x482e1135),L_(0x00000070), + LL(0x93eecb93,0x4b696b0d),LL(0x98400d78,0x671aa2b1),LL(0x05e6f78c,0x19c7b31c),LL(0x2f26896d,0x537e98fd),LL(0xc925cf6a,0x31498b2c),LL(0xe43ae0bb,0x5b628896),LL(0x2cc9c889,0xf81936b3),LL(0xd5a79df1,0xaa558d67),L_(0x000000a6), LL(0xc651825a,0x947e26f1),LL(0xd8102ba2,0xcba2e206),LL(0xf57819ca,0xe1b53333),LL(0xb14e41e4,0x89b722a1),LL(0xa87036c9,0x43d9c2e8),LL(0x8c5e594a,0x8a9f09ad),LL(0xfc198885,0x96afae31),LL(0xd164a447,0xf6ad8705),L_(0x00000015), + LL(0x4517c109,0x51de1f32),LL(0xfe892ec2,0xde0ad941),LL(0xa5e0c485,0x252b5759),LL(0x04504e2c,0xe069dceb),LL(0xceea659d,0x80061659),LL(0xb3fe1e63,0xee236d87),LL(0x846da87b,0xf97ae613),LL(0xa90f8433,0xe7abcaf3),L_(0x000001d9), LL(0x89e00052,0x583a7dc4),LL(0x6598f335,0x8097f299),LL(0x89f7734d,0xff15633b),LL(0x8aebbf6c,0xb01c7b6a),LL(0xb5108c62,0xc7f93ae2),LL(0xf807ee31,0xf990d4e3),LL(0x34992a71,0x9962859e),LL(0x282fca85,0x8047dde1),L_(0x00000172), + LL(0x5435ca99,0x5945bc53),LL(0xcf237d07,0xe31f2468),LL(0x1ef4bb2f,0x641e2901),LL(0x2c562b14,0x06773e1d),LL(0x2ff0373c,0xca66e36e),LL(0xc519e2a9,0x716d0497),LL(0xbfb75cdb,0x9a1fa9e2),LL(0x0dddfb32,0x1e517999),L_(0x00000085), LL(0x85c6aefd,0x9daa8f05),LL(0xe87b5c36,0xba374fa1),LL(0xcd0b7e7d,0xf9ec22c4),LL(0xd20b7cb2,0xdd4d581d),LL(0x516610e0,0x74ddb0da),LL(0x126aa3e2,0x4e09fb27),LL(0x35d95ce7,0x0c242711),LL(0x40d02e9e,0x926ede13),L_(0x0000004d), + LL(0xb5538d3b,0xb7d7682e),LL(0xd8734ac8,0xd322358b),LL(0x75fcdec6,0x56d9d86e),LL(0xe72ffc35,0x6c363b61),LL(0xd1066f3a,0x3d03c2ea),LL(0x7095dbd7,0xcd1674fd),LL(0xb42f9972,0xacc3e682),LL(0x9370acc2,0x80c71149),L_(0x000000fd), LL(0x89c235f7,0x5a49c095),LL(0xe1070948,0xd0d2a294),LL(0xe55bcaed,0xa073e38c),LL(0xd2884da3,0x25346561),LL(0x95d34747,0xbed8195e),LL(0x990b2c19,0xefe701ec),LL(0x17664aec,0x4c59ce88),LL(0xcb5f1246,0xa23cc1c6),L_(0x00000185), +}, +/* digit=67 base_pwr=2^335 */ +{ + LL(0xf7ab9a02,0x72a8d985),LL(0x39a70c2f,0xea7d5b7d),LL(0xf6f8acab,0x73f642dc),LL(0xdeb95d02,0x8a54bc56),LL(0x3f3cc37d,0x5a63f188),LL(0x1ef1bba0,0x8c074b83),LL(0xe112f14c,0x17f937a8),LL(0x29897379,0x4d335ca2),L_(0x00000087), LL(0x70af11f6,0x998374f7),LL(0x8ee96d7e,0x7d432cad),LL(0xbff9e11a,0xe6665366),LL(0xf6d56384,0x9b692423),LL(0xfc7e344a,0xf75f044e),LL(0xee1b3ddd,0xa827ee60),LL(0x9cd00df7,0xb2612c93),LL(0x3d529eb5,0xc4ffa6a1),L_(0x000000d7), + LL(0xa6774f15,0x39c16671),LL(0x3753ce58,0x7356faf0),LL(0x54c5f8c0,0x1165a356),LL(0xf5c1afc7,0xd6adf86c),LL(0x903b89f9,0xba6b4966),LL(0xbff86c3f,0xb1519f4e),LL(0xa87b0151,0xbe4f95b4),LL(0x85efd27b,0x0513d263),L_(0x00000104), LL(0xfa5d90d2,0xd4622a63),LL(0x2aca99c7,0xa6efd8d9),LL(0x1d6acf3a,0x7e55d6dd),LL(0x95a1b738,0xdb119c22),LL(0xd9703d10,0xd11a67da),LL(0x427c0f52,0xe412eedb),LL(0xe055192f,0x174c7a31),LL(0x404a5758,0xfd4b1dde),L_(0x0000015c), + LL(0x86c17046,0xc51693d1),LL(0x57ada379,0x7b463243),LL(0x9dea1156,0x65ad7ad1),LL(0x3431ffb8,0x22995c21),LL(0xbfb6e47d,0xa47b2e96),LL(0xecc87ed5,0xb5d8ce10),LL(0xab93da78,0xe414756b),LL(0x0b5319cc,0x327dee6e),L_(0x00000168), LL(0x0d0b7234,0x68a2cd80),LL(0xd1a1a9cc,0x62b72c52),LL(0x2c285a2a,0x23638d39),LL(0x1736a146,0x90e668b9),LL(0x99d14c12,0xe73e0b34),LL(0x0861672c,0x88955dcb),LL(0x7dc3cdab,0x06284ae9),LL(0x4fad41f5,0xfe7ca883),L_(0x000000d7), + LL(0x7fe98530,0x370d119f),LL(0x9990254b,0x764d3fe4),LL(0x8a86cb40,0x39be0e2c),LL(0x4b9820af,0x458321b0),LL(0x29475227,0x2c2ba583),LL(0xa07a5c7f,0x52e9ae89),LL(0xfa6d5206,0xbdc0eee8),LL(0x435604c9,0x6f2e4842),L_(0x000000c0), LL(0x2bfa81c0,0x1714a30a),LL(0x66400030,0xa3f37cbd),LL(0xab87a938,0xf3132874),LL(0xecbe1c91,0x7e9d7ac6),LL(0x1734fae5,0x7e33fb88),LL(0x600765b0,0xedfc073b),LL(0x428cbfb5,0x85e9a209),LL(0xbd290285,0x77ef7692),L_(0x000001e0), + LL(0xa928bd97,0xec2103fa),LL(0xa28d165e,0x31bc9c0a),LL(0x9e3c2272,0x1db480d5),LL(0xeefa29bf,0x5fe970c7),LL(0x0625c44f,0xa6473b7b),LL(0xd9e52858,0x66b89d6b),LL(0xea4cd7c9,0xc3e3b579),LL(0x3b6547a2,0xa8bdce16),L_(0x0000004e), LL(0x4065d81f,0x66f8ad71),LL(0x8a1901b7,0x08802270),LL(0x0ceae5cf,0x853e6e60),LL(0x63ae6ec1,0xd89e54bb),LL(0x1f365d84,0x9e03d94f),LL(0x49df44dd,0xddc9e1b3),LL(0xf70096c2,0xba5865a7),LL(0x6cc7a69e,0x01800fb8),L_(0x000001ad), + LL(0xd6f6ffe5,0x91cf34a0),LL(0xc22b2802,0xfd975370),LL(0xe87a26b1,0x662b3666),LL(0x46d8088a,0xa7466010),LL(0x0988f2ee,0xd8edbdfb),LL(0x1f7fc1eb,0xf4b2f213),LL(0x266b6d41,0x00896949),LL(0xc83c1c02,0x7c849de8),L_(0x000001e2), LL(0xf3a594e4,0x90bcda37),LL(0x480ec74a,0xdde9d726),LL(0x26216e2d,0xbef16495),LL(0xa5c64b02,0xfba3c749),LL(0xc3f630aa,0xea872930),LL(0x8695df3b,0xb21d654a),LL(0xb5372491,0xa2f3f6fc),LL(0xe917f3b3,0x13fe01cf),L_(0x00000146), + LL(0xd606cedc,0x12faa2d3),LL(0x93a86247,0x67da197c),LL(0xd4612a0b,0xfd72cd4e),LL(0x145bbdec,0x8483b822),LL(0xb4dba8a8,0xf56d58c6),LL(0x81ec1ed7,0x708f26ec),LL(0x631a5032,0xf4782ede),LL(0xb4b04fc8,0x34a251ec),L_(0x0000008d), LL(0xd85c10f7,0x1b8eedbc),LL(0xadbb93b8,0x1b68a64f),LL(0x2308b6f8,0xc37e6bd6),LL(0x392cec36,0x7b419db4),LL(0x0aee0e63,0x1777f3d5),LL(0xff167cd9,0x706d5278),LL(0xede81ea9,0x2ecab8c0),LL(0x63b7e96c,0xb7b3cb43),L_(0x0000005a), + LL(0x7b39090f,0xec8937b4),LL(0xbb7112fd,0x3ed5a415),LL(0x66e9e19d,0x01eab0fa),LL(0xbbe65978,0x740c409b),LL(0xba92675e,0xa050b19b),LL(0x3e8b56da,0xe6eedf2c),LL(0x2fbcf099,0xa55e0691),LL(0x80195262,0xf2c7d1e9),L_(0x000000e2), LL(0x013e53cc,0xeec1384c),LL(0x51ffea5b,0xeaca6749),LL(0xd0ad477d,0x45756473),LL(0x1fd4ee32,0x80864216),LL(0xa3069430,0x850c8b97),LL(0x405f653b,0x9de4340f),LL(0x5a543cae,0x347d550d),LL(0xa331ca24,0x75f4312e),L_(0x0000012a), + LL(0xf7fa7404,0x6f04ee1f),LL(0x5987ecf0,0xe39114e7),LL(0x8c92a999,0x734b40d0),LL(0x3eb0ff94,0x35b97b9a),LL(0xf3a7b34c,0xd5b35118),LL(0xd35276ae,0xfa36fe0d),LL(0x9e933110,0x3c37067d),LL(0xbe64ccaa,0x9629f86f),L_(0x00000157), LL(0x1cfc72eb,0x2f066fb6),LL(0x69fb1dea,0xd4e489f4),LL(0x65ba5821,0x3abd59aa),LL(0xf0068abc,0xf152d51c),LL(0xfa26b25b,0x4c7900c0),LL(0x929fd963,0x22beebe6),LL(0xd19508e6,0x6c8e147f),LL(0x84fd88ff,0x8a8eae8c),L_(0x00000146), + LL(0x746ef6f8,0x58c8162c),LL(0x15dbf9ea,0x7dd87f67),LL(0x5523d821,0x2bc5b0b4),LL(0x8780b2c5,0xb8903ecd),LL(0xf92e785d,0x54296f75),LL(0x6397e404,0xcce33c6e),LL(0x84bad1cc,0xd3c5f54e),LL(0x95b82162,0x33f935ae),L_(0x00000093), LL(0x3e26a2e6,0xf54ff1c3),LL(0xb4ec10e1,0xc2886785),LL(0xa1634274,0xe5822d49),LL(0xbfab5d5e,0xbe9122e0),LL(0x955a062f,0xf03c2cc2),LL(0x579ad9b7,0xf2e5e08e),LL(0xdd6ee255,0x1b65e701),LL(0x934f08f7,0xcd7d23cb),L_(0x0000009d), + LL(0xaddd73ec,0xaeacb5da),LL(0x9e604f26,0xf00003d7),LL(0xb32a37b8,0x5e05fada),LL(0x771ab3ac,0x03aa3a60),LL(0xe17eba9f,0x31442064),LL(0x7239319d,0x021c13e4),LL(0xa35b4712,0x3f7e400f),LL(0xc6e5283a,0x5888abe0),L_(0x00000110), LL(0x45cb211a,0x0081a506),LL(0x59fee06e,0x6e2f4f1a),LL(0x372aea8b,0x11014792),LL(0x2416f852,0x35841e3f),LL(0x71de69f4,0x710be3f1),LL(0xfa1b9018,0xd8151855),LL(0x92a94717,0x52addc4d),LL(0xff148def,0xea65eaa7),L_(0x0000003b), + LL(0xd85c3892,0x01927819),LL(0xd986cf50,0xab17488d),LL(0xeb6ebddd,0x8628281f),LL(0x92fa1e38,0x4511bc03),LL(0xe1691b01,0x0b79c2a5),LL(0xb842f844,0x8805d866),LL(0x343c71a4,0xd5d795d0),LL(0x042ac5c5,0xedd85588),L_(0x000000aa), LL(0x875f110a,0xfa896067),LL(0x0d43dab8,0xd6f1580b),LL(0x9a3104ec,0x840b3b59),LL(0x76717c31,0x41201091),LL(0x2243eb78,0x88de871b),LL(0xe2323a38,0x53ac3f7b),LL(0x764799c3,0xdaf476ff),LL(0x999d244e,0xc595b87c),L_(0x00000113), + LL(0x7b2cee87,0x8985e912),LL(0x3a4ec3d9,0x639aa554),LL(0x9515b9e8,0x2b90b395),LL(0xe330201b,0x5d9f9a07),LL(0x95f372a0,0x83696835),LL(0x0d679c0c,0x8c8132ef),LL(0xbc4509be,0x5efb5013),LL(0x1a4c14f9,0x7a8442ff),L_(0x0000016b), LL(0x27796676,0x1d220323),LL(0x607be429,0x7b931a60),LL(0x3b156b2a,0x38e10514),LL(0x36aabd76,0x8ff10073),LL(0x384c71ad,0x3603a7b3),LL(0x1c1f643f,0xe305de49),LL(0x08714206,0x63b53241),LL(0x57add901,0xfba33a9a),L_(0x00000151), + LL(0xe6fdb7c1,0x03800832),LL(0xceb77120,0xc3398df2),LL(0x625cbf7e,0x4c74b442),LL(0xdf67b9eb,0x424f2515),LL(0x6b977890,0x2abc1051),LL(0x2462b490,0x7c8f5df8),LL(0x6d60d980,0x1bb838ca),LL(0xff606aee,0x1e7a2ff1),L_(0x0000010e), LL(0x8ce853f5,0x238fce9b),LL(0x49a4c209,0x73f7bb70),LL(0xae2b39f7,0xcfbf4b1e),LL(0x53e2f55b,0x7309ae96),LL(0x026775b0,0xfcf869d6),LL(0x1b0e83da,0x72ed99fe),LL(0x02f8a21d,0xe81bf7a2),LL(0xd737619d,0x2bf238b7),L_(0x0000017b), + LL(0xd12397f2,0x38b832fc),LL(0xb158ca8a,0xb03ae8bb),LL(0x7420634b,0xac8efa9e),LL(0xaa8dadd3,0x259a7c31),LL(0x525d1488,0xf727fdfe),LL(0x8b687898,0x48ffe9fc),LL(0xfbbb696d,0xb00d2cb4),LL(0xf4a8353d,0x9be76892),L_(0x000000b6), LL(0x99e21f84,0xf73fea91),LL(0x0e2a8788,0xfce9c9d4),LL(0x18c2b050,0x3412a938),LL(0x1844f4f0,0xc14eff85),LL(0x4ad5ef54,0x0ad47ee3),LL(0x01446b7d,0x4c160f3e),LL(0xc22336c4,0xc43f42cf),LL(0x64f51a4f,0x34833c47),L_(0x00000155), + LL(0x54298a18,0x7f8ca9dd),LL(0x308270c4,0x433780e1),LL(0x2be3ff97,0xb186cdf8),LL(0xeb6471b0,0x747ce696),LL(0x05f60ab1,0x815fe310),LL(0x5a457da8,0x6bb9ac1b),LL(0x4901af0f,0x925bd14f),LL(0x652f972c,0xacd8b58a),L_(0x00000186), LL(0x72184c64,0x3e0f3553),LL(0xf7ba0c69,0x6dbda5e1),LL(0x5b11db3d,0xe46fae1c),LL(0xf1f51b89,0x7c0b46b0),LL(0xa48d5ec9,0x1cc037ca),LL(0xbdcc7599,0xe5f40355),LL(0x28784dc0,0xd1a3fa4f),LL(0x0b837ead,0xb5a1926d),L_(0x000001ee), +}, +/* digit=68 base_pwr=2^340 */ +{ + LL(0x97e26dd0,0xde847fc3),LL(0x2cc0ff17,0x8ee8bde0),LL(0x63e6fe38,0x774123d0),LL(0x97b1e73a,0xf8cb9f55),LL(0xee20c8da,0x8b938535),LL(0xa8b1bfac,0x3df10d7d),LL(0xe2a81936,0xe7d42738),LL(0x9979861a,0xaf0a6779),L_(0x0000003e), LL(0xde00c8a6,0xbb611141),LL(0xaefc5b58,0x9b3d91d2),LL(0x33633ce2,0x0d5e3306),LL(0x2544bfef,0x8956c10a),LL(0xbeaa2dd7,0xcfa84101),LL(0x8ba22402,0x96a5f958),LL(0x0df8f462,0x34ace12e),LL(0xc6c70187,0xe0e00d25),L_(0x000000a8), + LL(0x28cda662,0x8cc26d9a),LL(0x4788e280,0xddb52ac3),LL(0xa2e3c895,0x305bc55d),LL(0x6e792cc3,0xee807637),LL(0x5f9d9986,0x0da2d9cb),LL(0xaea185a3,0x56f8f0d8),LL(0x8ef462b9,0x096bebd6),LL(0x300f61c2,0x7be11b59),L_(0x0000004e), LL(0x15fdd133,0x9dea58bb),LL(0x2585fb77,0x8271cd5b),LL(0xd75c3d97,0x5ac1a4b5),LL(0x4eee827a,0x6fe4d480),LL(0x0147df6c,0x7f66c09f),LL(0x3f6a4c21,0x92c3b320),LL(0x1eeb9502,0x17768418),LL(0xebda3f44,0x12f688be),L_(0x00000117), + LL(0x8027c8dd,0xea4586de),LL(0xdc25b073,0xf24773b7),LL(0x49b36fcc,0x8466e794),LL(0x3cc03245,0x36f85404),LL(0x02d71d6f,0x251e24c9),LL(0x1a81ea4c,0x9e39ec68),LL(0x0e710d11,0x0e27e696),LL(0x44dfa8e5,0x6885ae0f),L_(0x000001c9), LL(0xe3e54e0a,0x7872cc7e),LL(0xb8224b0f,0xb5696e54),LL(0xe5d4bd3d,0x64ead37d),LL(0xcbad27cc,0x5b2f36d2),LL(0xa45e529b,0x521210e2),LL(0x788fbf74,0xe1bd2c8d),LL(0x40c5440b,0x2b990184),LL(0xbc157b39,0xeeecc510),L_(0x0000005d), + LL(0x1941c1e9,0x241f3444),LL(0xaf242ed2,0x73f71786),LL(0x82ffb7bd,0xee8f684b),LL(0x0b940040,0x0e0a7766),LL(0x3cb9180b,0x05509077),LL(0x41ff934d,0xd7e63b43),LL(0xfe154397,0x597b1f2e),LL(0x73566086,0x115dad8d),L_(0x0000018e), LL(0xe97eed76,0xa0320279),LL(0x44ad3c59,0x95d0b92b),LL(0x9546c02d,0x17644016),LL(0x0cf317d6,0xb1278de8),LL(0x0cc035b3,0xa150eec2),LL(0xa454911c,0x40f34047),LL(0xb15350f1,0x64a854ce),LL(0x24297dd6,0x45fd389a),L_(0x00000015), + LL(0x2f4ddeb6,0x1b54c6d4),LL(0xd46442b3,0xc94971a5),LL(0x8eb97dd3,0x9e3e1ff6),LL(0xe2df3525,0x058db0b2),LL(0xe0b69449,0x46968077),LL(0x4ea6ec9f,0xba76456e),LL(0x8457796a,0x77183369),LL(0x255412cc,0xb4e4306f),L_(0x0000005e), LL(0xf2060dc0,0xcef4a91b),LL(0x57dadc33,0xb934de9a),LL(0x51f56ade,0x2e8fe341),LL(0x49ab29d2,0x85723b5e),LL(0xfabf520f,0x1ee66b41),LL(0xbffe6761,0x0a605253),LL(0x50202f55,0x9e49468c),LL(0xef6d250b,0x956ea13f),L_(0x000001a2), + LL(0xea2b5246,0xe30dc097),LL(0xb5323240,0x3dd49c5e),LL(0x082d33c5,0x17c692b6),LL(0x12bc5d69,0x7e9d695a),LL(0x02c7fd33,0xb78372d6),LL(0x85e92117,0xefa0ef29),LL(0xceacebcb,0x9b4e8e18),LL(0x3d68cc3e,0xe3e50ee1),L_(0x000001b3), LL(0x0d2f5e36,0x5f980bec),LL(0x9b062f58,0x03edaeaa),LL(0x83ee3b51,0x4f1f8028),LL(0xe4a60553,0xd292d29e),LL(0xf95f8dad,0x7f9ba28d),LL(0xfb5785f5,0x54b8d134),LL(0x0fe162fe,0x2bd8287f),LL(0x2247f090,0x769ce1a1),L_(0x000001e3), + LL(0x8c32c911,0x416e3d53),LL(0x74341e71,0xa2b4eeb7),LL(0x9e6b225b,0xff742236),LL(0xd3c824dc,0x5e3b9c67),LL(0xd547224d,0xc6e4276d),LL(0xcc105d46,0x8a001d2d),LL(0x92da4b3a,0x3b252483),LL(0x67e2f395,0xcbb5174b),L_(0x000000fe), LL(0x508826b7,0x2308d720),LL(0x4e2e8071,0x9562db9b),LL(0x1bf6b116,0xb14e6841),LL(0x45f6d2ac,0xbfd32572),LL(0x8cdf458c,0xe189ac1c),LL(0x3f894fd3,0xb5d6ee49),LL(0xa59cbf0a,0x672a0c8f),LL(0xd8476d8e,0xfbb78753),L_(0x000000d9), + LL(0x1cd9788c,0x4e39334c),LL(0x0560e3e7,0xc62b58ab),LL(0xfa2ff6e2,0x25b0cfee),LL(0xe3dacd7d,0x56f469ae),LL(0x6476d0c4,0xaa862fad),LL(0x0d8d2340,0x468a688f),LL(0x648a9494,0x9d4d2feb),LL(0xe9f4ed20,0x3e7c5890),L_(0x000000a9), LL(0x3f607213,0x12cdd07e),LL(0x60784376,0x8d6d1246),LL(0xea183586,0x85400753),LL(0x5c35ba6a,0xf252808d),LL(0x57ba4df7,0x07b45d68),LL(0x048ddde7,0x8c60d683),LL(0x759393e3,0x919b183c),LL(0x760c630e,0x90171725),L_(0x00000120), + LL(0xe24eabd7,0xc6d9113b),LL(0xdfe5709e,0x1b269289),LL(0x74793368,0x0c1477a3),LL(0x3c2fbb12,0x544d389c),LL(0xbce04baa,0x4fcb6058),LL(0x52137546,0x62503bea),LL(0x306eaabe,0xb0495976),LL(0x49afd268,0xa62777c0),L_(0x00000171), LL(0xd8dbfcd4,0x5a2c2301),LL(0x122ed53b,0x23b67f05),LL(0x68235f24,0x0b4f5601),LL(0x850a3bcc,0xfc63cfca),LL(0xfb6987d1,0x7f3a86aa),LL(0xeb70f694,0x726395f3),LL(0xe2648fe0,0xfc883eec),LL(0x04f6906b,0x551243f7),L_(0x000001a2), + LL(0x1ea7b394,0x1329d8d9),LL(0x09b5385e,0xe206cc29),LL(0x8ad6ff5e,0xaa658f94),LL(0x8f946f98,0x428d98ec),LL(0x2b10de6d,0x3ec6baf6),LL(0x7efb3f61,0x21982753),LL(0x47b7f15b,0x578e65b3),LL(0x63e00597,0x5b3f1a2b),L_(0x0000010b), LL(0xc87fe251,0xec6244fb),LL(0xb103454a,0xbf7ff50a),LL(0xc09eeea3,0x5b8194a6),LL(0x117b25e8,0xb8d95b3b),LL(0x4719134d,0x98e3eda5),LL(0xfb408475,0x184c4131),LL(0xaae4a703,0x433cd4bd),LL(0xee1c89f5,0xec3f5308),L_(0x0000005f), + LL(0x15497e40,0x0a7c8b60),LL(0x2ac3e5be,0x35df434c),LL(0x73674292,0x218ab0b7),LL(0x377ea177,0x971e7bf8),LL(0x979969d0,0xa6fc69b3),LL(0xf051da86,0x0f199014),LL(0x50a5af5c,0x0bd76f2a),LL(0x68112265,0x6ef71ee6),L_(0x000001c9), LL(0xb6a11a9c,0x2c92d1d2),LL(0xa2718b70,0x8bc153fa),LL(0xefc700c8,0x7d63139e),LL(0x11bfab90,0x63a1a94a),LL(0x1c81d0a8,0x0af04b86),LL(0x5010811a,0x65f6b2d4),LL(0xd230f7b9,0x346b9acb),LL(0x92db7ff2,0x791ad571),L_(0x000001f4), + LL(0x731fb0e3,0x0bfa96fe),LL(0x4b219ff8,0xe186bb8d),LL(0x34f0b2a5,0x4bbcffce),LL(0x74e4771d,0x4fa8ab52),LL(0xa8af538f,0x0bd9aa17),LL(0x55b8ec20,0x24b82cd8),LL(0x55a1e2c4,0xf54b7fae),LL(0x34a02ce9,0x011a367d),L_(0x00000056), LL(0x49d91d2b,0xb4418223),LL(0xf5b325cc,0x48062883),LL(0xae0ea746,0x3f6511a6),LL(0xa6b89032,0x057c30cb),LL(0xe93a6d10,0x00156e39),LL(0x0c08d7cc,0x7ef1eeb2),LL(0x713dea1e,0xeb905073),LL(0x1c6abbcd,0x4e60ee01),L_(0x0000019c), + LL(0x0253f26d,0x1db48f4d),LL(0x239e10c2,0x3cbc9af9),LL(0xde4c09f2,0xabdb2bfd),LL(0xed72b749,0xf64b181a),LL(0x928d6d6b,0xc85d2a91),LL(0x9af06cb2,0x32a985b4),LL(0x67685c7b,0x4cf68328),LL(0x607e3b33,0x96bdc7c4),L_(0x00000164), LL(0x47c82fba,0xc31b32d2),LL(0xd33b72d3,0xf9f3e673),LL(0xd3e9eee6,0x42fb631c),LL(0x43164033,0x6eedae95),LL(0xaab1e76b,0x986360ea),LL(0x9e6c1afa,0x30e60546),LL(0xffd16939,0x06fbdf1b),LL(0x989aed4f,0x7870903a),L_(0x00000135), + LL(0x02ec16f2,0x1065b996),LL(0x62ecea90,0x92968f64),LL(0x48a2356f,0xe74f9d69),LL(0xc38162fc,0x799bc2e4),LL(0x109958a5,0xc2cf37fd),LL(0xc511c5bf,0xb810f3aa),LL(0xba774e2d,0x04423cab),LL(0x7df651dd,0xfa41efc5),L_(0x000000be), LL(0xc60869cc,0x843bf3e9),LL(0xca2ddefb,0x07001aa8),LL(0x2325dc6b,0xfb77a925),LL(0x19ebdc37,0x984cbf76),LL(0x991269aa,0x0ea96690),LL(0x5a99df72,0xf5a76c72),LL(0x261ea01a,0x11ed492c),LL(0xec2261aa,0x511c25de),L_(0x000000dd), + LL(0x2208733f,0x79d76ece),LL(0xdf3265ef,0xdd97cbec),LL(0x1201ac02,0x82ed80a6),LL(0x3e075507,0x2e6d2b22),LL(0x16c3d5bb,0x9b31411b),LL(0x89a53e5c,0x4570ab97),LL(0x5d2d34d3,0x76b65f73),LL(0xd36a94bd,0x3b4c1384),L_(0x00000038), LL(0x7939931b,0x91c17d4a),LL(0x850a6308,0x5b75be0c),LL(0xa8eb3e41,0xc4b1a960),LL(0x5176e7e2,0xef74a564),LL(0xf493e8d5,0xd77a5683),LL(0x2824a377,0xdc2b6e93),LL(0x3d90456b,0xf50c072e),LL(0xfe49afc1,0x3768ae59),L_(0x0000003a), + LL(0x0b81885e,0xc160ead5),LL(0xf73cb6f0,0xe2cd2bce),LL(0x53fb7eb3,0x9bb7bc05),LL(0xb6b62b31,0x8a471706),LL(0xdaf298a3,0x846c6b42),LL(0x9d404cf9,0x085e05e5),LL(0x8fac2e73,0xc53893b4),LL(0xa8ff0af6,0xe3d8eea7),L_(0x000001e9), LL(0xcd5b055a,0xe934470a),LL(0xc1af94ed,0x89b3f0c4),LL(0x4fba6b38,0x9af80496),LL(0x3e423ee4,0xd89fd53a),LL(0x793fadf0,0x353cc302),LL(0xcd463b61,0x51fbb36d),LL(0x782e102e,0xd6d1c6c3),LL(0xbbc63732,0xc97f604b),L_(0x0000019d), +}, +/* digit=69 base_pwr=2^345 */ +{ + LL(0x4a7e1773,0x5fdb3148),LL(0x0a1bc3a0,0xbda07174),LL(0xc265e95e,0x43b1d3c4),LL(0xedc546d6,0x611b9709),LL(0x807b04c2,0xe15784fc),LL(0x473ceec4,0x58afe5bd),LL(0xc97fb33e,0x7b94dc53),LL(0x39d6d532,0x914fc6dc),L_(0x0000002a), LL(0xd880ddb6,0x67cbcf73),LL(0xdf80627a,0x67d3e029),LL(0x91ccf95a,0xfd91b52d),LL(0xa53ec7ae,0xa855273c),LL(0x1131573a,0x07213a95),LL(0x49db550c,0xfa5fb98a),LL(0x470643af,0x0fa67f5b),LL(0x6bf0628a,0xf906186e),L_(0x0000012c), + LL(0xe3e2f37e,0x7f1be067),LL(0x7f152d2c,0x8659f773),LL(0x242f8dec,0x8df47d63),LL(0xcbac7d95,0x91c63b0a),LL(0xf620881b,0x8c2c6ad3),LL(0xda54c002,0x701999ad),LL(0x3012f693,0x99516f6a),LL(0x3c14f4c4,0x68d44cb7),L_(0x000001a0), LL(0x8d1b414e,0x1d209ec5),LL(0x76dcc740,0x51dc58e8),LL(0x93231067,0x4e14fe98),LL(0x5a4f75f2,0x88f5086e),LL(0x4ccd6aac,0xf294dbdb),LL(0xedf86543,0x30e3be99),LL(0x767f48ab,0x22dcd0b3),LL(0xd87667c6,0xd6615681),L_(0x0000017f), + LL(0xb6dcc9cf,0x0d5b110b),LL(0x1e6c13e6,0xa0842e9d),LL(0x58585159,0x443356f4),LL(0x265b46fe,0x3b25c086),LL(0x87729185,0x0ebbff20),LL(0xc71c4d1d,0x79c2136e),LL(0x3ebeca5e,0x3a96ed20),LL(0x32a0af3b,0x012e330a),L_(0x00000193), LL(0xdacd4b61,0x7d17ed67),LL(0xde583a56,0xe5703cea),LL(0x316840b4,0x03d396ce),LL(0x0cfc4143,0x6970ea48),LL(0xb1974ced,0xa63761b9),LL(0x3de4383d,0xe400788f),LL(0xd07d6726,0xa545993a),LL(0xa33056bd,0xd3fe822e),L_(0x00000185), + LL(0x04e40c0b,0x2f073480),LL(0xf78fb060,0xb2604448),LL(0xc2ac8aeb,0x277ca03f),LL(0x27864b78,0x2c6f473d),LL(0xeb1664eb,0x7cb793a9),LL(0x58eee9a3,0x9c2ce2b3),LL(0x94f18cbc,0xc87a3dc1),LL(0x2df6078b,0x0e93cd11),L_(0x00000022), LL(0x96d6d2f1,0x3fd1ed5d),LL(0xbe10752f,0x0c38fb72),LL(0xd1e47666,0x9b093c35),LL(0x73ab1d6d,0xd898dff7),LL(0x00e4cf26,0xc4b445df),LL(0x422c1136,0x9ee0d1ce),LL(0xb6e821b5,0xe82511ed),LL(0x1ade6252,0x81c804e4),L_(0x000000f4), + LL(0xd903ff9c,0x47ebbcfa),LL(0x75ed251a,0xc45b660c),LL(0xef50c145,0x733af648),LL(0x00ba4ec8,0x5119e848),LL(0xb32a226b,0x3e048abf),LL(0x1f648014,0x7a1eccf1),LL(0xfab712cd,0x2badbf53),LL(0x1ebfb8b6,0xca11e7be),L_(0x000000dd), LL(0xa034de60,0x789ae7e1),LL(0x42374e6e,0xa641227e),LL(0xb2f0016d,0xa82cadf5),LL(0x8ca0d43e,0x552e57fb),LL(0x5a71e67c,0xa8bcdb55),LL(0xc3a4e9f5,0x6e0e2bb2),LL(0x124b38d4,0xc1f40c89),LL(0x60b28fe4,0xabb2620f),L_(0x000001f8), + LL(0x54c77c89,0xfaecca00),LL(0x028ae659,0x3a3c5350),LL(0x656b887c,0x5b3bb83d),LL(0x0c6fbb7d,0xc2d4fb00),LL(0x8f5877ba,0xea3d0289),LL(0x01e01a3d,0x943983b2),LL(0xdcb878b4,0x382b3bfc),LL(0x7e566dbe,0xe238f00d),L_(0x0000010d), LL(0x312dd2eb,0xcf1a3019),LL(0x6043d5c3,0x3f970442),LL(0xd72b4978,0x47e77b41),LL(0x51765a88,0xd9f49bc6),LL(0xc2232c0f,0xf1592cf2),LL(0xba6cd5b1,0x7bdf89de),LL(0x33024471,0xa56dd8d4),LL(0x4e3c8e30,0x6718468d),L_(0x000001f6), + LL(0xb8ab0296,0x1c158b81),LL(0x3cf9ac17,0xe81b84be),LL(0xb9565ca7,0xcf197d97),LL(0x30adec74,0x0f74f924),LL(0xbbec4f93,0xc6810de9),LL(0xdd1aa6b4,0x68e13e67),LL(0x31b1e868,0x3b5ec800),LL(0xb287ff46,0x970d17f9),L_(0x00000148), LL(0x4e217778,0xfc348975),LL(0x3990d639,0x2c996afc),LL(0xbf8e72bb,0xc43038ef),LL(0xf3f9e817,0x673d9367),LL(0xb8d625be,0x33a4c44f),LL(0xb72553a3,0x6135473a),LL(0x7365b95f,0x91b434c7),LL(0x70995374,0x2e7887e0),L_(0x00000182), + LL(0xf2b44edf,0xf8d7989a),LL(0x1b1a9086,0xb30f16f9),LL(0x2b4d5672,0x919c3dae),LL(0x64f72009,0x3b6ec0a9),LL(0x64ce5600,0xc12b7f4f),LL(0xe0f0d4fb,0x144476bf),LL(0x3eb40f82,0x0332a8a4),LL(0x80cbb448,0xf3755660),L_(0x0000013f), LL(0x5e5d7124,0xe518caf3),LL(0xa53d6591,0xe170d9ab),LL(0x4f1b1b50,0x3e56ed3e),LL(0x7c4f9eca,0x8dfe4cc6),LL(0xfa0dd028,0xa59c7726),LL(0x0a01f234,0x6c8fa066),LL(0x704007db,0x8366767a),LL(0x4570b32e,0x94810fb8),L_(0x00000169), + LL(0xa5e76230,0xce3ac7a6),LL(0x5ab23199,0x54772e62),LL(0xd7eb0723,0x8caedc24),LL(0x76dd866b,0xa41bb763),LL(0xba5b9e92,0xe6d92de4),LL(0x28e72bc3,0xce269dcb),LL(0x2b7dc535,0x7e64fab4),LL(0xe7cccbfd,0x02a03896),L_(0x000001c3), LL(0x278c892b,0x3dc101fd),LL(0x079c3e36,0x2332d512),LL(0xf51726ad,0xdbc6dd2c),LL(0x81e5e3b6,0xbd26d73b),LL(0xb2e70917,0x24b0b54b),LL(0x23cdf2f9,0x0353dd40),LL(0x5e2acffb,0x2e871e61),LL(0x07f5e7c3,0x5b299ee3),L_(0x000001c5), + LL(0x66643187,0x3ec2ad9c),LL(0x115859c9,0x1f8e247e),LL(0x17b4d84b,0x2585ef39),LL(0x657d1198,0xa3f20465),LL(0x3619c497,0x6901431a),LL(0xe9a26e53,0xa5276fd0),LL(0x496e3f3c,0x1f276a6e),LL(0x348de17d,0xf8c3af85),L_(0x000001ca), LL(0x2d6d1037,0xb1e10393),LL(0x7b5ce8d7,0x6deb4f48),LL(0xc7dc292e,0xc43c502b),LL(0x6b03f2ee,0xb1a1182c),LL(0x39273259,0x7622b369),LL(0x4498e583,0xfe7d43c5),LL(0xa50df54f,0x61447fad),LL(0xc4339095,0x3a9a1f2a),L_(0x000000b7), + LL(0xcefa0f75,0x4af9a66e),LL(0x310c7a00,0x8db46828),LL(0x9223ef88,0x2cf042cc),LL(0x6fa5a04f,0x7c559200),LL(0x6daaab2b,0x91afc691),LL(0x98a36fb2,0x00b03676),LL(0x188b128b,0x51264914),LL(0xb9803ddb,0x75459c1a),L_(0x00000062), LL(0xbedae6b1,0xe3aaa000),LL(0x7a690ecd,0xceb2c1c6),LL(0x8880b402,0x45703d2c),LL(0xc0613e4c,0x8b8c9eb5),LL(0xc5db208f,0x4c846b8c),LL(0xa9987715,0x6bd91493),LL(0x42b48717,0x9a26dd34),LL(0x3e788715,0xd9b2c58c),L_(0x0000011e), + LL(0x2a0a9afe,0x361ab1b5),LL(0xccf7e9f1,0x24eb3b91),LL(0x5a00b663,0x3a047d69),LL(0x70c649d7,0xff025b44),LL(0xbfc42749,0xf2772669),LL(0xfa1fa0b0,0x1d856fe2),LL(0x59b50aeb,0xdd9c5baa),LL(0x07db1f1d,0x63853e29),L_(0x000001cc), LL(0xa8c851af,0x924ac747),LL(0xaa197f48,0x269fd103),LL(0x40db5d37,0x4cdd9698),LL(0x1838b760,0x491094a5),LL(0xfe6931b4,0x6e498775),LL(0xf5d608e3,0x0107968f),LL(0x1ebcbfad,0x4aa5111c),LL(0x9da743a4,0xcba06022),L_(0x000001c8), + LL(0x92933f27,0x47445d4b),LL(0x06b03d8a,0x4a0fee6b),LL(0x3277857c,0x1fa95d1d),LL(0x87c700bf,0x48c9ebf0),LL(0x2a50e2b3,0x43aa2c31),LL(0x9a26e1ce,0xfdbdd0e9),LL(0x52ca3b19,0xfcedcc05),LL(0x2999c847,0xbff002c4),L_(0x00000000), LL(0x3f6f21d0,0x64d4906f),LL(0x556e52bc,0x42f805ae),LL(0x90f2f1b6,0xda19f3db),LL(0xd869ad98,0x21709755),LL(0xf5bb8103,0x573f3fb7),LL(0x593f7e34,0x2bac9d40),LL(0x02d84c5f,0xa4e8ad8e),LL(0xea53406e,0x80797c51),L_(0x000001d4), + LL(0x1cc4de54,0x02db6ff9),LL(0x9a077100,0x442b39ab),LL(0xa4a99831,0x658c33f0),LL(0xd154641a,0x6b185008),LL(0xbb725f43,0x1c42ee9d),LL(0xc802ceb4,0xd4f04052),LL(0xde1c27e0,0xaa13dd25),LL(0x5e0fdafb,0x59845ec9),L_(0x0000003c), LL(0x0ff8a42e,0xd7b6958f),LL(0xc632359e,0x00693302),LL(0xd897df30,0x3a9976fe),LL(0x07f17ce0,0xb3320f5d),LL(0x0634d694,0x9281633f),LL(0xf481d736,0xa1f17a34),LL(0xc568493c,0x7973f20c),LL(0xc81657ab,0xe331f1c3),L_(0x0000010e), + LL(0x4294bb48,0x02479c06),LL(0xf0c74cf8,0x82afef4d),LL(0x3fe27e63,0xc6ed0fe5),LL(0x2473be19,0x88c3bb5a),LL(0xf0f01c24,0x8b895708),LL(0xff99c560,0xda940b97),LL(0x19fe223c,0x3a3e9972),LL(0xfce2e466,0x48aaf92b),L_(0x0000002b), LL(0x2fe2dabd,0x1f0040f3),LL(0xc569b506,0x6e592ad0),LL(0xa59e0b36,0xe1a1ad5f),LL(0x506ba908,0xdd28fbcb),LL(0x35a90e9a,0x5dfd21f8),LL(0xae82baef,0x5c23fd74),LL(0x03b13133,0xe27cfbd6),LL(0xa41bf476,0x7af7e895),L_(0x00000028), + LL(0x7b4c0b5b,0xdf92a189),LL(0x7fe35612,0x9f97d902),LL(0xa5105c7f,0xba021326),LL(0x9c521853,0xd2cadb21),LL(0x9b3ed45d,0xb3ab9d25),LL(0xddadc1eb,0x7b4a857f),LL(0xaddab060,0xbbc92a34),LL(0x7dff916f,0xee7e6c52),L_(0x00000121), LL(0xc6f5958e,0xa3ba1dab),LL(0x7b0e564a,0x27f6c008),LL(0xb9c963dd,0x3c030970),LL(0x76828eca,0x3cd7a457),LL(0x0834d3c2,0x417b833d),LL(0xf44c50d5,0xf0d8be25),LL(0x153d4a6b,0xa49590ea),LL(0x47e9c71d,0xf3a30dc2),L_(0x00000143), +}, +/* digit=70 base_pwr=2^350 */ +{ + LL(0x5891669d,0x995d0979),LL(0xe0c6b8f7,0xbaad255c),LL(0xcdfa7a67,0x2a84102f),LL(0x2ed9a546,0x5fff322b),LL(0x238b4cca,0x316895f0),LL(0x27a1fc8f,0x4369e1fc),LL(0x399300db,0x708ed717),LL(0x5f16f718,0x931503fe),L_(0x000000a4), LL(0x1ff0c6b2,0xa040da9e),LL(0xf9967269,0x8694422a),LL(0x5871908b,0x8350fa73),LL(0x61c801c8,0x80cd1b5d),LL(0x26cc63f6,0xaf0b4158),LL(0x3474f5f7,0x1e938b36),LL(0x7800e540,0x2f20f7f2),LL(0x56230526,0xd27bb44c),L_(0x000001e6), + LL(0x7e54e734,0x474f3cfa),LL(0x7075c330,0xb3ee576a),LL(0xb446bdd4,0x1b7efe90),LL(0xa143371a,0x826a3c98),LL(0x45fcf113,0xa412cdba),LL(0x4b5601ca,0x614348a4),LL(0x06ebe3f7,0x9f111b62),LL(0xd750e443,0x1f6bb4a9),L_(0x00000045), LL(0x5f2d48b9,0x63c0d59b),LL(0xcb29ae28,0xe216b29b),LL(0x3a9a3c78,0x2465c5b5),LL(0x9567856c,0x36d155fd),LL(0xdfbfe047,0xa1ce6b07),LL(0xc3a4fa43,0xf19b8361),LL(0x0e9f03c0,0xb21f548d),LL(0x9de803f9,0x85460ccb),L_(0x000000f8), + LL(0x1358b22f,0x28dc3d9e),LL(0xb1947d50,0x707f8201),LL(0xa08b9636,0x1277e4a9),LL(0x253ea9d3,0x38720146),LL(0x7e71d50f,0x62240fd9),LL(0x79e96c95,0x99a338fd),LL(0x14656a4b,0x3386ac0d),LL(0xaed2f11c,0x56e7d58c),L_(0x0000008f), LL(0xa0e5c79e,0xd77da8a6),LL(0xb38b4a7f,0xdb95d39e),LL(0xb6a3eb09,0xc15d78b6),LL(0x97f12510,0xc3aba47d),LL(0x56c5ceaa,0x1799be9b),LL(0x71c67e7c,0x8203dc96),LL(0xc27e5165,0xaf4cd822),LL(0x0bd2ed9a,0xb4f47f2a),L_(0x000000a9), + LL(0xbed671f0,0xd26b287c),LL(0x978130d6,0xd433a71c),LL(0x7aadd881,0xb4ad7bb1),LL(0x52e4f45f,0xb1940d6b),LL(0x722e2bd7,0x72d44569),LL(0xf91dc84e,0x6d3fde70),LL(0xd4254643,0xbd1bc41e),LL(0xb847e41a,0x544a7be2),L_(0x0000010f), LL(0x325818a6,0xe2e82545),LL(0x3d8e5d2b,0x1c9863cf),LL(0x5f30317d,0x98fb8ec2),LL(0x81f15ce0,0x8947db85),LL(0xf3e6c315,0x055d8793),LL(0x43a7feb5,0x8417f508),LL(0xac153d3d,0x248bbc38),LL(0x664329e7,0xfcfbcb03),L_(0x0000012f), + LL(0x8dd55839,0x0ffb3aeb),LL(0xf0f73b2b,0xb5b42e5a),LL(0xfb4aa83f,0x6fe3f768),LL(0x166957fb,0x1777755a),LL(0x9be2e29b,0xb21920be),LL(0xd39b15af,0x9d78ee52),LL(0x5cfe70fd,0x4ed3196b),LL(0x55c6cafd,0x34efaf79),L_(0x00000009), LL(0x60602ec9,0x9f0e1288),LL(0xc5b10817,0xef0c0487),LL(0x2d0a8114,0xd48fc96d),LL(0x7cfa2d81,0x641e3931),LL(0x6424b3ef,0xe6f897a1),LL(0x3828d18c,0xf36345b8),LL(0x162c7445,0xa9afd810),LL(0x86dd67b2,0x34f52c33),L_(0x0000011e), + LL(0x71f0b29b,0xbf4033d7),LL(0x282d7d2f,0x4816fc56),LL(0xbba4acf6,0x0d36fbc1),LL(0xed8c95f6,0xc3d935ee),LL(0xf5c04db6,0x0f8e468f),LL(0xf1e487eb,0xe95fc738),LL(0x07ce9d5f,0xd25bbce8),LL(0x3ea06aeb,0xd6e4d92f),L_(0x00000016), LL(0x8ee0b487,0xd1ebfa2e),LL(0x8c6285b5,0xff9b06cd),LL(0x7f8da651,0x19efacac),LL(0xfb702fe7,0xf38839db),LL(0xfd2c9b61,0xb8c0cb9c),LL(0x674adc03,0xd42ebdf8),LL(0x326b91f3,0x8993821a),LL(0x0fbb4e81,0xbc7b32f8),L_(0x0000012a), + LL(0x79b5c2f2,0x2fd676b6),LL(0x892e4204,0x41e60d2e),LL(0xdf88f03d,0x05344e65),LL(0x322deae7,0xabc0c748),LL(0xf3bee9da,0x7dbffa8f),LL(0xe2cbe049,0xf2922597),LL(0xb0e73ee1,0xa1ab5a4f),LL(0xd18b70e5,0xf7b0232d),L_(0x00000143), LL(0xbad81855,0x7a93eb9f),LL(0x998f9412,0x6520852d),LL(0x9fffa5de,0xa83ca014),LL(0x9492e738,0x29961bc9),LL(0x38356eab,0xbaa587e6),LL(0x9aad6aa8,0x5bde3fd3),LL(0x15f7c437,0xc663a8aa),LL(0x2b85ba68,0x922641a9),L_(0x00000017), + LL(0x872c802b,0x90b91e88),LL(0x9329a6f3,0x5e0fd985),LL(0x332091e8,0xc7233994),LL(0x069d0a1f,0x7172741e),LL(0x953488c0,0x1870fafc),LL(0x3b040fb9,0xbb2fd807),LL(0x9e841e1b,0x16872728),LL(0x48f58216,0xa72dc0f5),L_(0x000001bf), LL(0x4695d527,0x4ec2f404),LL(0xc898f3ae,0x893dfe9f),LL(0xd6d16346,0xcfc2a2d6),LL(0xdcfcc356,0x9780e14a),LL(0x52a0f58f,0xe40c34a9),LL(0x1f74017f,0x9637bf1f),LL(0xe85cc7e4,0x7db8273a),LL(0xf7240054,0xd4e119d7),L_(0x000000af), + LL(0xf3b66cc1,0x8bec2bfe),LL(0xe147d2d0,0x0f381def),LL(0x63d396f3,0xd719925a),LL(0xa70c4ee8,0x48335ffe),LL(0x70cbdf17,0xba86e989),LL(0x70acf1a0,0xa8e07900),LL(0x3fdcbfe3,0xf724a710),LL(0xd0dd93f1,0xcce8d0db),L_(0x000000dc), LL(0x2a8a4b44,0x312db409),LL(0xe842388e,0x51c17662),LL(0x5cfc4c86,0x2819cf9f),LL(0x3d2f2e78,0xcb5f9278),LL(0xc84b5c07,0x6807319b),LL(0x91966c94,0xd459389d),LL(0xf68df64d,0x22ed9565),LL(0x30d2c264,0x2d12cd4a),L_(0x0000015c), + LL(0x5d109ca1,0xa8198a4a),LL(0x7fd3cc79,0xcf8b16bd),LL(0x973e67ac,0x27c827e8),LL(0xc9207496,0x6d1709a1),LL(0x9157f587,0xc23a1cd6),LL(0xbedd9d1c,0x8b1088ef),LL(0xb005d24b,0xc08bed38),LL(0x6477a806,0x0681e2ab),L_(0x000001da), LL(0x34165bef,0x2de2bdb8),LL(0xe996e18b,0xf9e30d5c),LL(0x2c137e56,0x5c521393),LL(0x6041c771,0x8cdc666b),LL(0x4ee56b76,0x2695a1d6),LL(0x518a5638,0x41e2f039),LL(0xdb59944d,0xaf0a4010),LL(0x5b0e9f3f,0x829ed1fe),L_(0x0000001f), + LL(0xe83fbb80,0x3b382180),LL(0x93922bbc,0x1503eb8a),LL(0xd83a3aec,0x4f056b98),LL(0x0f661abc,0x1dc0c0de),LL(0x20cd5ab5,0x25a3a29e),LL(0x9409a1df,0x2ec3d724),LL(0x2311b333,0x9cff8f0d),LL(0xd299c4b1,0x30ec4ca0),L_(0x00000084), LL(0x05faf0db,0x674d075d),LL(0x79f5e3c1,0x3e4d547c),LL(0xaceff143,0xa985c66e),LL(0xceb1d3f0,0xc8735e90),LL(0x46311b8a,0xecdbba45),LL(0xd47b3dd0,0x8237affa),LL(0xc21e6384,0x6b4f82bd),LL(0x851d53b8,0xff59ca4e),L_(0x0000000e), + LL(0xfe08a2e5,0x29a5355a),LL(0xa2f29baf,0x3e11c687),LL(0x653058a2,0xab5abb63),LL(0x533110b2,0xead1d1b9),LL(0x254324e4,0x65d1b7b6),LL(0x9ad5a861,0xd1007405),LL(0x0712ab62,0x6f88f2a9),LL(0x78e9d501,0xefd62c6b),L_(0x000000fe), LL(0xe0d173ba,0x62d2d42c),LL(0x8d15289e,0x5d68b919),LL(0x4baf7b53,0x4a9af773),LL(0xbfd8566e,0x2c278158),LL(0x0f0f5b40,0xa603f631),LL(0x366d639e,0xed79331a),LL(0x457655be,0x5b5f4bc7),LL(0x744b4617,0x6ced0122),L_(0x0000008f), + LL(0x94abf4c2,0x0a6157b9),LL(0x62225ddd,0x63f4338a),LL(0x3ff075f1,0x19a505d3),LL(0xa170cf14,0xdfa6bdb1),LL(0x35bb45bd,0x3014f03b),LL(0x01eadcfb,0xdf884f38),LL(0xed9ce5a3,0xeb67d796),LL(0xbe4fe92b,0x01a5f419),L_(0x00000011), LL(0x1ff93f99,0x7ddc4629),LL(0x8bd2744c,0x40075673),LL(0xa1d1f6a9,0x6ac9b5bb),LL(0xbff10759,0x7709ddbb),LL(0xd617233f,0x04b71ff3),LL(0x91a5fcd2,0x45458de2),LL(0x699b54de,0x5147375c),LL(0x4e0307cc,0x2fe5917c),L_(0x000001bc), + LL(0xfc7b0e16,0x4252a836),LL(0xfbc6e97a,0xbffdbb20),LL(0xee422c57,0x5769cb47),LL(0x501f912b,0x3924d571),LL(0xae0c25a9,0x239c3442),LL(0x7ed84b21,0xd601103f),LL(0x74478136,0xebe1703d),LL(0xc5087e65,0x67b021e4),L_(0x00000156), LL(0xf2a22ea9,0x8ce094d8),LL(0xaa167fe1,0x70c73af6),LL(0x79b93fdc,0x0e41e095),LL(0x3eab3290,0x4d79fd87),LL(0xb7162ca3,0x66141590),LL(0x583d1391,0xe0bd38e8),LL(0xa393b806,0x169f55ab),LL(0x4bdc04a4,0xd1df6260),L_(0x00000012), + LL(0x7e5ec530,0x6ef19cc6),LL(0x8fb90054,0x349f0b5e),LL(0x7a588763,0xd381418c),LL(0xe35ce1af,0xec0fd49b),LL(0xecb4e203,0x7786513b),LL(0xa276ad19,0xfe701187),LL(0x99f4ee10,0x47d026fa),LL(0x58423dc0,0xa22bbaf1),L_(0x00000065), LL(0x5096d030,0x9aa1efcf),LL(0x5af392c9,0x8ba7989e),LL(0x7c5174d3,0xd1616f2e),LL(0xd20d0632,0xa5636d7c),LL(0xd761cf0d,0xce718261),LL(0x701e7d69,0x08d4d0bc),LL(0x66e92aa8,0x819aee8a),LL(0x0d6fcd90,0xc96d5138),L_(0x0000018d), + LL(0xb706d0d4,0x81b20efd),LL(0x117c40b0,0xec008c40),LL(0x0a6d9c2a,0x693270e3),LL(0x6114d3e0,0x4266a5ea),LL(0x44a6af67,0x81ebf621),LL(0xee3917e3,0x7fca3d45),LL(0xc35ff5d6,0xa3526048),LL(0x0f6e79db,0x7e7bfed4),L_(0x0000001a), LL(0xc6923808,0x0c06eb8d),LL(0x3343c5a2,0x3418cfe3),LL(0x3e67d0a5,0x15eb001a),LL(0x7e48959e,0x0ead5e7c),LL(0x0962e6ac,0x32e4162f),LL(0x3e28513c,0xfb8117bb),LL(0x317568fa,0x3a2e3034),LL(0x0c912ceb,0x55938174),L_(0x00000102), +}, +/* digit=71 base_pwr=2^355 */ +{ + LL(0x4b2fef73,0xfec70f6d),LL(0x92ef06ac,0xc38aac0c),LL(0x790f3344,0x53c30edf),LL(0x1b40fed7,0xfc800650),LL(0xf6da803d,0xfdf722f2),LL(0x284a42e2,0x5cecc340),LL(0xa0f15400,0xb36ac652),LL(0xef82f0df,0xd1506b21),L_(0x000001be), LL(0x59060616,0x84d76b78),LL(0xa1c3d7b8,0xc6050edc),LL(0x307e9a89,0x1519baa6),LL(0x8c7e0ccc,0x3495eff8),LL(0x22e91666,0xea17475b),LL(0x69639f1c,0x8c53c39e),LL(0x1f0e827f,0xede8121b),LL(0xeb066355,0x91249281),L_(0x0000015b), + LL(0x5a372292,0x3accccf3),LL(0x16751720,0xa2ac7465),LL(0x1bf938ea,0x83a983dd),LL(0xb73d73d6,0x598a6f1d),LL(0x630b4f7f,0x6235f9ed),LL(0xdb784cb5,0x52bdf332),LL(0xb330540f,0x221e5e83),LL(0xc25843b0,0x09499b4e),L_(0x0000004a), LL(0xb0a1b02a,0x010fb3ca),LL(0x8b6e52dc,0x60a24896),LL(0x22c046dc,0xae1e187a),LL(0x482695be,0x006acf49),LL(0x35934bd3,0xb960f105),LL(0x1e1d0143,0x4cfddf01),LL(0x5de371d8,0x56c439e8),LL(0x64828414,0x582ff3b5),L_(0x00000185), + LL(0x4315ba36,0x3578ec4a),LL(0x83ac7330,0x74417a7c),LL(0xb971e045,0xbee09246),LL(0xc391f3f4,0xb2cfe806),LL(0xf8fb9526,0xe574f401),LL(0x2d57d573,0x9ef64156),LL(0xf2047705,0x2e13ebeb),LL(0xe2e05adf,0x97b783be),L_(0x00000025), LL(0x81cc47cb,0xac801f25),LL(0xbb184270,0x1d0026d9),LL(0x772cb73c,0xc5ae7636),LL(0xf37dccd7,0x5106f975),LL(0x276aad31,0x2b41e6c0),LL(0x0c355836,0x7d420351),LL(0x169e0a27,0x25cdd7da),LL(0xe67ef6ec,0xdd1ddbf0),L_(0x000000fe), + LL(0xfbf17fb3,0xbce94ac6),LL(0x89803b61,0xe8afe442),LL(0x2e798f31,0x9a42f37b),LL(0x9475e43d,0x77aef7a7),LL(0xa8f685f3,0x203a6947),LL(0x969c3b8c,0xdf0dc1b4),LL(0x9c542cdb,0xc76bc8fb),LL(0xff501682,0x2a768660),L_(0x00000097), LL(0x5f3009bb,0xc8f9daec),LL(0xc4a46652,0x89b1c325),LL(0xb09499ac,0x721c0cae),LL(0x5e63ccd5,0xda46e344),LL(0xaca0b998,0x32db691c),LL(0x793a1fc7,0x049e845a),LL(0xd927f614,0x7aea310a),LL(0x80024bf0,0x5359be8b),L_(0x00000124), + LL(0x7a3137a8,0x57afd605),LL(0xb3d701e7,0x608eeeaf),LL(0xa1e2923b,0x3a52d1fe),LL(0xb5ba2517,0xf6c570be),LL(0x6f830092,0xa2b946db),LL(0x63e9fd66,0x2b96de58),LL(0xd1292d2e,0x89c80a56),LL(0xf418bcf0,0x02901646),L_(0x00000025), LL(0xbb16a820,0x9f28725f),LL(0xb36ad666,0x73de9bb2),LL(0x25e09cb1,0xf102152a),LL(0x3474fc24,0xb0389a9f),LL(0x9e0b3083,0x245ecf47),LL(0xefc86ff8,0xedc1e824),LL(0xd024fd72,0x022e7528),LL(0x0e37477f,0xa7fdb14f),L_(0x00000191), + LL(0x6cc9e802,0x130db159),LL(0x31d0f49f,0xbd9c79a2),LL(0xf1d499d6,0x7ea9b7cf),LL(0x367757ac,0x05a4d545),LL(0x0a42a453,0x1f2c8548),LL(0xd461a5b5,0xb8ed29ef),LL(0xe691c9e6,0xa549541f),LL(0x6490ea1c,0x09c0153e),L_(0x0000018f), LL(0x3f9a0edf,0x7f525f59),LL(0xc140a1f6,0xa98aaedb),LL(0xf5bef166,0x750be5c2),LL(0xd457a559,0x8cba58b2),LL(0xc5d96cfb,0x514d93d0),LL(0x70bfa2f9,0xb86d7234),LL(0xf6b79058,0xa8a78584),LL(0x18d58f11,0x2b2d0ad4),L_(0x000001e3), + LL(0x55bea4be,0x147202dd),LL(0x3c8a33ae,0xd39c4b9d),LL(0x1d455649,0x3f56141d),LL(0xc0ac51ab,0xa5a57669),LL(0xfc529732,0x1ee307ea),LL(0x1861bed9,0x5f1e4bec),LL(0xc7a796b8,0x5b0d925f),LL(0x06f456f4,0x2257c76d),L_(0x00000117), LL(0xfe075b8e,0x4360118e),LL(0x218cb0cb,0xaa1c1dca),LL(0xf6db0e7a,0x2be1c968),LL(0x5a3744ed,0x46bb2acc),LL(0xaf262fce,0x7e16d340),LL(0xaec37ad7,0xe6df41bd),LL(0x1060715f,0xee38cd22),LL(0x87b94898,0x34109b20),L_(0x000000a2), + LL(0xa0d42ca1,0xb416f6d1),LL(0xc2c062af,0x3dacb0a7),LL(0x1630676c,0xd74ee6b3),LL(0x95fc297a,0x8f736e49),LL(0x48a7a2d1,0xd64edc25),LL(0x6b5d5f53,0x83303159),LL(0x0e945b2c,0xdfaa52c4),LL(0xb0587c06,0x462a8f05),L_(0x0000017c), LL(0x4f0d870e,0x2fcd636b),LL(0x0835ddc0,0x86482b2b),LL(0xd2333470,0xc7f1c7b2),LL(0xb32bf92b,0xd5f30c92),LL(0x49153950,0x9ce136c0),LL(0x29288cec,0x4ac8254d),LL(0x34eb3849,0x0b3117ac),LL(0x14ba2a1b,0x3a85376a),L_(0x00000047), + LL(0x9b2fca5a,0xb3ec3510),LL(0xc014692a,0x988a8cb2),LL(0x70309a41,0xb83a1155),LL(0x92367194,0x22c65f09),LL(0x558d49bd,0x17ac8e14),LL(0xd539b194,0x281a7ecc),LL(0xa19213fa,0xc69fe80b),LL(0x1ef427d6,0x744a4f4d),L_(0x000001db), LL(0x64c7d0d7,0xf07169a2),LL(0x4ff0070e,0xe17c5e0d),LL(0x42362609,0xd97efa2b),LL(0xab4374f3,0x59d17f1f),LL(0xc3027acb,0x8cb9e348),LL(0xc305c872,0x320eb648),LL(0x861bfbe3,0xf68b129b),LL(0x2a98fbd9,0xc35aa741),L_(0x0000004d), + LL(0x9b675376,0xba2a6162),LL(0xfef26d3a,0xaf22bedc),LL(0x4bac42f2,0x32bd0514),LL(0xaf54da8b,0x474d59e6),LL(0x846ca3be,0xac190f17),LL(0x7e7c79bf,0xaea0f3e1),LL(0x13543ecb,0x0ff996ba),LL(0xabe74acd,0xe27a5f5a),L_(0x000000bd), LL(0xfeccff02,0xa8ccc73f),LL(0x1e746179,0x62af882b),LL(0xb19b717d,0x4e0895be),LL(0xb255045a,0x8f194a8b),LL(0x0b37366b,0x089f1cd5),LL(0x7b3da3e1,0x68b1f2a5),LL(0x91e4f674,0x9c4602f6),LL(0x698976ca,0x3ed98ad9),L_(0x000001e5), + LL(0x2100e990,0xfe476990),LL(0x532b6850,0x345630b7),LL(0x7ff00f29,0xecbc85e6),LL(0x9c3d2e4c,0x5f322ba8),LL(0x6869142c,0x9e246c23),LL(0xf5d1ef76,0x0affd2a0),LL(0x2e6d871e,0xb40893c1),LL(0x66c72704,0x1665fed8),L_(0x000001d9), LL(0x91fa7d18,0x06507414),LL(0x9d9489fd,0xa1379411),LL(0x7d5c53f0,0x7e6d3de2),LL(0x097595be,0xc486fb28),LL(0x85e5a09c,0xa9fd8f9e),LL(0x2996fa66,0xd71e16d0),LL(0x040664e3,0x7c75e965),LL(0x14b60428,0x9d686380),L_(0x00000032), + LL(0x23ecdd94,0x86f79bf5),LL(0xbf36d744,0xbf45f97e),LL(0x0fe48147,0x6235b3ae),LL(0xd40868d4,0xa9b13d93),LL(0x45fa9173,0x34e9264c),LL(0xb5705f4c,0xd0d58c79),LL(0xfd4b166f,0xaf4ff870),LL(0x7aaca2ed,0xb68a488f),L_(0x00000155), LL(0x9951fb26,0xf5f3e0b1),LL(0x747dd972,0xf6fc0c26),LL(0x92d84bc8,0x088102b5),LL(0x201255f7,0x84970893),LL(0x7f6288c9,0x6a679170),LL(0x9309b54e,0xd5327276),LL(0x389f4da5,0xc48b5de6),LL(0x8fc1eb23,0xac794b85),L_(0x0000011b), + LL(0xd3fa1c16,0xb408df01),LL(0x66056a5d,0x5f945157),LL(0xc30a058e,0xf0071848),LL(0xb615e360,0xe6a8d838),LL(0x132d49ae,0x1bb7f3ca),LL(0x092ee873,0x398ab7d7),LL(0xbf83bd98,0xba362639),LL(0x73208c1b,0x49dd5ba3),L_(0x000000cd), LL(0x081c78e2,0x0d07ce4b),LL(0x724cd057,0xf7baff54),LL(0x31245cf8,0xff518822),LL(0xff5f1211,0xea1813a7),LL(0x89f90332,0xfa74413f),LL(0x9e68455b,0x9e49a7a6),LL(0x182fad31,0x30e8a2ef),LL(0x233ce0d5,0xbd55ab52),L_(0x00000199), + LL(0xd2d5a87a,0x28e2d8df),LL(0x708c9183,0x1dbe8e5a),LL(0x9b9fb00f,0xa3695cb8),LL(0xaeafe9c7,0x9205b4ca),LL(0xd6ec0b74,0x756f204b),LL(0xa9e0254c,0xd51d1a73),LL(0x152441cf,0x0ca91564),LL(0x370d2b8b,0xe3cdd9e9),L_(0x000000de), LL(0x4dec1468,0x9dab1375),LL(0x5322d78e,0x78b8ab5d),LL(0x0adbfc55,0xa2b97f9c),LL(0xd5d0ce27,0x9cd573f2),LL(0xe94e39b4,0x06ee23d2),LL(0x213bd15a,0x708d61ea),LL(0x561b9d34,0x6271f59e),LL(0x41fb576c,0x9ae94507),L_(0x00000166), + LL(0x312474f6,0x6669c984),LL(0x46ae7251,0x8c23b4d3),LL(0x3738a807,0xad75f8b4),LL(0x3ef8e3cc,0xc8e8bbf5),LL(0x029e586a,0xa7111c4e),LL(0xa4d1beb9,0x238f36b4),LL(0xc4da1680,0xbe34bad6),LL(0x9409b124,0x6ab824c2),L_(0x00000002), LL(0x3b1b0723,0x0666df3f),LL(0xa0015f27,0xd7f90fcc),LL(0x3e7eb3a2,0xcd91c4ca),LL(0xa8bd0fd8,0x56907857),LL(0xc0b60059,0x3559db95),LL(0xc6ed4fe7,0x0c8beff5),LL(0x2ba51007,0x5bc2116c),LL(0x409f6b4e,0xa6198a28),L_(0x000000d8), + LL(0x6c54f37b,0x231a6637),LL(0xb888102e,0xaecdfa06),LL(0x430b0efa,0xd888793c),LL(0xb123b1e3,0x8beed2db),LL(0x8887df4f,0x3ea5e72a),LL(0x2425e985,0xccc7d4aa),LL(0xd98e93f3,0xe9181719),LL(0x07cba97f,0x8ea6eef3),L_(0x000000b0), LL(0xf51c3444,0x5719b171),LL(0x5d9f40be,0xe16ecd5e),LL(0xfea96313,0xfe1e359f),LL(0xd9f1461e,0xde9904f3),LL(0x38f6d943,0x881bb7a0),LL(0x2c5787d5,0xa74eed55),LL(0x67fc2cd9,0x7ccb483a),LL(0x2c643f37,0x7070b576),L_(0x000001db), +}, +/* digit=72 base_pwr=2^360 */ +{ + LL(0xb53942b1,0xca188556),LL(0xbd7c7672,0x20ced736),LL(0xa4667058,0xb83d6897),LL(0xe3f39ba4,0x174ecbf7),LL(0x34188faf,0x203dc58b),LL(0xdb5dba0b,0x5206b453),LL(0xf54df32d,0x52fcf51e),LL(0x08d08e3c,0x2f551f34),L_(0x00000173), LL(0x92603b2e,0x6b937ade),LL(0x7f7f5dfd,0x632c9b6a),LL(0x3151876b,0x3ee4a789),LL(0x7a59040d,0x41b009fd),LL(0xdfc2d274,0x68b427fe),LL(0x1c0ceded,0x07d57f92),LL(0x220fc8f2,0x83c79a42),LL(0x7b0f6753,0x410a2e83),L_(0x0000016f), + LL(0x2ff9c0f0,0x01fb8b79),LL(0x82addc43,0xfdb0062d),LL(0xb9cdf1d9,0xb1cf25ad),LL(0xb5a42255,0xaaea42eb),LL(0x1990669d,0x1dffd105),LL(0x88f20764,0x613001d6),LL(0xda7769bd,0xa275aa11),LL(0xe04ea507,0xea612e43),L_(0x00000073), LL(0x24386fbb,0x21f18b4b),LL(0x268a5e08,0xa7554f72),LL(0xad126436,0x714fe1c3),LL(0x5b5ba02f,0xb7c7cde4),LL(0xf2da3519,0xfc576f09),LL(0x4fb328e0,0x185faef3),LL(0xa0386e0f,0x2adc73d1),LL(0xc97a6bb3,0xda21be9a),L_(0x00000133), + LL(0xd542b802,0x6a23d540),LL(0x500040b2,0xf87554cc),LL(0xe6a09fa7,0x548aea96),LL(0x0cf27fbb,0xfa1d8c06),LL(0x1a618765,0x1943cfee),LL(0xe6a8c7ea,0x20bf61bc),LL(0x99730b0b,0x744528dd),LL(0x42eac170,0xd049742c),L_(0x00000023), LL(0x6da345a9,0x1e2bba63),LL(0xe601cd80,0xcbeefa62),LL(0xc9e240a6,0x8106469f),LL(0xda8103af,0xc7109e54),LL(0xdcc44907,0xdb9a3ec3),LL(0xe44b6df8,0xe34b7788),LL(0x0e67c93e,0x4a58495d),LL(0x63e8347b,0x23b5096e),L_(0x00000172), + LL(0x5b970b5a,0xbf417e03),LL(0xb60364c1,0xdda37ca1),LL(0xea847f52,0x28527f5c),LL(0x98d517fb,0xa1e399f7),LL(0xff102f07,0xc452c79f),LL(0x87dfab3c,0xc5aa688a),LL(0x490b0295,0x0dbc6056),LL(0x3dd17acd,0xb4f6972c),L_(0x000001ac), LL(0x90426354,0x23fa3555),LL(0x3a903ffa,0x262814e3),LL(0xc46f6e35,0x1cec4214),LL(0x7267bc6b,0xca2e1dc8),LL(0x20b7474b,0xeb500457),LL(0xf394811d,0x4304c697),LL(0xa5001f3d,0x0f7a5e2b),LL(0x4c9ea7fd,0xead3d012),L_(0x0000010d), + LL(0xd19de00c,0xb7e47c23),LL(0xd475bc3c,0xff4599af),LL(0x1acc6490,0x39b1950f),LL(0xee09f5dc,0xd14540f1),LL(0xe51c9564,0xf1b75050),LL(0xbebd088f,0x17895647),LL(0x240dba4c,0x097400cf),LL(0x559b95e8,0x5d4b8420),L_(0x0000005b), LL(0xd06fbfb7,0x85986a76),LL(0xc2ffb653,0xa478ed7f),LL(0x18e264c5,0x4841d184),LL(0x17a5a278,0x21d9e8a0),LL(0x297fe2fe,0x1bf52154),LL(0x072d6d91,0x88327dad),LL(0xae77c8ea,0x02d1fcbe),LL(0x13786b6a,0x25554500),L_(0x00000068), + LL(0x9f48a0af,0x17de731f),LL(0x7753cff6,0x972b7a35),LL(0x73655403,0x28d73a10),LL(0x0c70484d,0x46d46c14),LL(0x516a9dc8,0x455b7ef1),LL(0x0b552594,0xb8161489),LL(0xf418ade1,0x64a91645),LL(0x76a465f2,0x7693e9a1),L_(0x000000d3), LL(0xdcbca2f5,0xe5e5c3bf),LL(0xdc135bc4,0xca946121),LL(0x3d39b5c7,0x55877498),LL(0x318be468,0x9fb5d801),LL(0xe5cb6287,0x3afd92b1),LL(0xcd7f8034,0x34ed24ae),LL(0xa3835c84,0x6aa7d954),LL(0xd325764c,0x41780668),L_(0x00000002), + LL(0xf2280c1c,0x34c0928c),LL(0x37933b17,0x74a56f2c),LL(0x6bae2a29,0xb1d26ac8),LL(0x6bd1e8bd,0x84c336cb),LL(0xcdaa1b9c,0xaca41014),LL(0x7838c44f,0xe2ce24b8),LL(0x525239ca,0x515f204f),LL(0x8bcb0507,0xdbd0e0a5),L_(0x00000193), LL(0xc3926ced,0x631411bd),LL(0x3e15aa53,0x8672c87f),LL(0xade47bf6,0x93da50d5),LL(0x148028e4,0x0048f8cd),LL(0x03c75612,0xb5ecfaeb),LL(0x7b7867aa,0xafcde134),LL(0xa0208953,0xe2411e3b),LL(0x24be9b23,0x848d40b4),L_(0x0000002e), + LL(0x8d4ad28a,0x16583ec0),LL(0x7b7ba7d9,0x2bbb4768),LL(0x2b3f0b4e,0xe0e4b3fb),LL(0x9172caac,0xe6fb63a6),LL(0x22aab4b0,0xa00520c8),LL(0x7930e37a,0x4dcbf41f),LL(0x6bfa91da,0xf521a694),LL(0xb88bd604,0xa707c1f0),L_(0x0000000f), LL(0x0d23952f,0xd8520b88),LL(0x22333018,0xa6bc2bb8),LL(0xaa6a00bc,0x011553af),LL(0x5def3469,0x0ed5fc0a),LL(0xbcfec7c2,0xdee0e8c5),LL(0x2f464224,0x8adb476e),LL(0xd844542e,0xd3c1bdb2),LL(0xa709924f,0xac98d161),L_(0x0000012f), + LL(0x715ddc65,0x5054b047),LL(0xa4a3faff,0xd966b478),LL(0x3d33573c,0x1081c0ed),LL(0x928c644f,0x0d2ce409),LL(0xb6d01835,0x9e6a2193),LL(0x52176b02,0xa876fcb1),LL(0xa48ba61b,0x717040ec),LL(0xa24784a2,0x063597d5),L_(0x0000008d), LL(0x2c7389fc,0x24d496ff),LL(0xb9c0170d,0xf08c120b),LL(0xee06f00f,0x24a5f375),LL(0x9e3d247d,0x21f556fe),LL(0x23ca02e0,0x9baf2fa5),LL(0xc33aa42b,0x87dfcff1),LL(0x165eef36,0xf9dd5e4c),LL(0x54afa097,0xfe4014f0),L_(0x0000009f), + LL(0x52348ca8,0x690b2052),LL(0x836e06e2,0x3509fc01),LL(0x7b24d732,0xc3a11a6f),LL(0xf970953d,0xb1e661c4),LL(0x19774ec5,0x1a995696),LL(0xa05e5145,0x777347df),LL(0x1c3c2550,0x77882ae3),LL(0x5a7928a8,0x77fbd07d),L_(0x00000185), LL(0x09fd7d9d,0x41e2d40c),LL(0x16368545,0x29dc25b0),LL(0xfa97fb70,0xb7b7f0ff),LL(0xdec5a377,0x2c841e96),LL(0x205a5df4,0x01390c3a),LL(0xe68d053a,0xa1116c1b),LL(0x83274721,0x62015852),LL(0xe92e4364,0x6a3178e8),L_(0x00000016), + LL(0x84a707a5,0xf2f16fe9),LL(0x75049d40,0x2503f2a9),LL(0x67afd1db,0xe86bcd13),LL(0x1004d640,0x5322f07a),LL(0xf5a688a9,0xb4accb02),LL(0x5af14887,0xe07764b0),LL(0xd65fb0f3,0x03224e24),LL(0x5db913de,0xb8433f0c),L_(0x00000011), LL(0x1ac50b18,0xf3884513),LL(0xe8ba41a9,0xaded3528),LL(0x8ea44980,0x1a82f302),LL(0x31375544,0x0614f686),LL(0x4f3dc64f,0x8ad34274),LL(0x7f906c7a,0xc479a89a),LL(0xe50987f1,0x17709633),LL(0xaa307609,0x33922a61),L_(0x0000009d), + LL(0xbf75fd24,0x7b97be7b),LL(0xd004b0c4,0xd609efba),LL(0x341b0b8f,0x20475d65),LL(0x373000c9,0x00101859),LL(0x5bcb5ae6,0x518d7514),LL(0xfb3c86f2,0xf5d314f2),LL(0x2c8aceec,0x2307be1e),LL(0x778a0fa6,0x5d168daa),L_(0x0000011d), LL(0xd7b35cc7,0xa440b9a3),LL(0xa70ba700,0xa47a36dd),LL(0xef6fc566,0x17be0829),LL(0x8e295843,0x63809dc9),LL(0xa317bc2f,0x1a787c34),LL(0xbce26a9e,0x943ad796),LL(0xc651a487,0xe010f911),LL(0x636a6efc,0xcd31e255),L_(0x00000188), + LL(0xe2c5ac41,0xed5ce1f5),LL(0x8d6c9e3b,0x8f008e9a),LL(0x2a13d48e,0xa44f1754),LL(0x32cde8f7,0xaa90e24c),LL(0x8660b8f9,0x3052b86b),LL(0xd73a03c1,0x79244ef9),LL(0xe4f8a628,0xc2475432),LL(0x35d52164,0x9c11d0d4),L_(0x00000059), LL(0x3d8335f4,0xb6ab40a4),LL(0x3d6aa080,0x9ca82551),LL(0x92a4dc90,0x8044f304),LL(0x5989211e,0x4878d275),LL(0xc33afe23,0x50bb5ea4),LL(0x2b031b41,0x889e9545),LL(0x4a4f6a74,0xdcce463e),LL(0x6a9c23ca,0x260ab0c8),L_(0x0000007c), + LL(0xe02b88ed,0x2372213b),LL(0x84ab40ec,0xdaad8de9),LL(0xcb476943,0x2dbf8cf6),LL(0x9149cbb6,0x72626b77),LL(0x4935f2cb,0xae5d765c),LL(0x79eb7a36,0x65f4be84),LL(0x44c54fc0,0x2049ba34),LL(0xcbfa4bf0,0x9c904608),L_(0x00000083), LL(0x3dbc5a64,0xa5d29aec),LL(0x3010853b,0xdf573f6e),LL(0xcdc13fa1,0x9737e298),LL(0x24add1ef,0xa7f64bf7),LL(0x2431c698,0xb2b280e2),LL(0xbdff9a1e,0x93c22a36),LL(0xd70876a8,0x0c7227cd),LL(0xaf483376,0x04873b2d),L_(0x0000009e), + LL(0x86436bf8,0xecb1f89d),LL(0x21b6a936,0xf18c9695),LL(0x805badb2,0x45242b9a),LL(0x2c7430dc,0x7856a265),LL(0x5aacc16c,0x281a24a8),LL(0xbe56330d,0xd8f8608d),LL(0x50d0b225,0x62852160),LL(0x4403a1c3,0x7038362e),L_(0x00000075), LL(0x2d9d6d70,0x7dc02e97),LL(0x816727a7,0xca536177),LL(0xc5451dd1,0x304d66d8),LL(0xb89ef533,0x360da6a3),LL(0xe6b58c96,0x3f234bec),LL(0xc18619f4,0xb4bfa580),LL(0x891d516d,0x40c1bed3),LL(0x04f1453b,0x7060a227),L_(0x000001e8), + LL(0x367407cb,0x30c9a655),LL(0xcf48b04d,0xb68ea01a),LL(0x04344830,0x174d6fa7),LL(0x1ac58a53,0x9044eeb3),LL(0x0524d6f5,0xf87d51a6),LL(0xfb882d4d,0xaa0ba344),LL(0x1ed41d08,0xa85fb93d),LL(0x6086b6ae,0x7fa57f48),L_(0x000001f2), LL(0xb7febd79,0x596f6fa7),LL(0x2aae9562,0x04813ef9),LL(0xabc183c4,0xded30d2a),LL(0x6a011be4,0x20b7ae96),LL(0x88e77be2,0xbc3e6cfc),LL(0x77d5e0ca,0xac06a92b),LL(0xd7f99c6d,0xc76c3023),LL(0xa80a6be4,0x1d55150d),L_(0x0000012d), +}, +/* digit=73 base_pwr=2^365 */ +{ + LL(0x300cf42b,0xea0d37f0),LL(0xd1a1ebfa,0xb07ea564),LL(0xbce4cf04,0x4677d784),LL(0x74184f2b,0x14a4f867),LL(0x3b8741db,0x00b95ce9),LL(0x35b5960b,0xfae4a317),LL(0xd2c80a76,0x23107ec3),LL(0x0522c4d1,0x8678a9d7),L_(0x000000cd), LL(0xaec13d90,0x304b58dc),LL(0x88c3d5f2,0x45f5267d),LL(0xf847248f,0x28ef4e85),LL(0xc0f3da26,0x7945a7b9),LL(0xea2c17e3,0x8a2da387),LL(0xe84de988,0x211a8e98),LL(0x8290c88f,0x75574343),LL(0x6b4ce366,0xca4612f5),L_(0x00000040), + LL(0x7975b736,0x6c7a73bd),LL(0x1e3ef4b5,0x104fc4ba),LL(0x835871e0,0x4759b57a),LL(0x9b4ed462,0xd3c95d4d),LL(0x648a71ee,0x829d8353),LL(0xece81ad2,0xb2a56bed),LL(0x452c12f2,0xb67ec3e1),LL(0x35ab19b8,0x3f8f88bf),L_(0x000000cd), LL(0x5c7f0b66,0x76062e0d),LL(0x4abff696,0x6641cdd3),LL(0x9b89962a,0x0add12e1),LL(0x9f42be1c,0xa078191a),LL(0x72d9da14,0x7c488cf9),LL(0x607f65fc,0xa7e790e9),LL(0x5cdadd7d,0x83b3584d),LL(0x381ca37f,0x3c6df02d),L_(0x000001d4), + LL(0xded49058,0x3a1e6367),LL(0xfd8b4117,0xcdcf0fd6),LL(0x0c717ef3,0xb3300d01),LL(0x07e608fd,0x527d7c8e),LL(0xe69c0a0d,0xd39cd9ec),LL(0x11bdaf48,0xa5576772),LL(0x5d520c7f,0x92f3c61b),LL(0x1fbf8426,0x814bffe3),L_(0x00000055), LL(0xa0e0f49e,0x3dc94502),LL(0x8193bb95,0xb1a23052),LL(0xd7bdda5a,0x19650b25),LL(0x4c67c4a2,0x78abb7ba),LL(0xb9dbe10f,0x3eb157bd),LL(0xb3d0ff94,0x1a32ace6),LL(0x8180c4dc,0x9e9b36a4),LL(0xeb0124b6,0xfee72796),L_(0x000001a7), + LL(0x7bd3b0c9,0xedaed08c),LL(0x46195fa3,0xbcb9e4e5),LL(0xc31c13ef,0xb2cc8a6a),LL(0x483f2eae,0x912ca200),LL(0x5ee60fa1,0xff0ff27a),LL(0x9e9c56cf,0xdac70a7b),LL(0x4977503c,0xbda5a3e4),LL(0xa564deab,0xfe3a9fcb),L_(0x0000018e), LL(0x784eeb75,0x7e821113),LL(0x560a5e57,0x4ec38a12),LL(0xae4b9aaf,0x8358d926),LL(0x1cb5c9a3,0x7b69c24b),LL(0x0e546449,0xc0748541),LL(0x660a2d50,0xa4c426fb),LL(0x87263ee5,0xc286e0b9),LL(0xf7b3ba20,0x4bed6c50),L_(0x000000e5), + LL(0x1f5a397a,0x9263865c),LL(0x4434e163,0xf3a80e48),LL(0x9ca69373,0x9608a668),LL(0xc4b09404,0xb3964738),LL(0xbe4c6ca8,0xe169bce3),LL(0x7c62a7e9,0x4efa6e4a),LL(0xb46b0f85,0xe2e5aeb2),LL(0xe0111694,0x6babf49a),L_(0x000001f5), LL(0xbb845644,0x2589af29),LL(0x286fb826,0xc48651eb),LL(0x97cf3fde,0x6f9d0884),LL(0x78bdc9d0,0x16ca5665),LL(0x7e3d1e7d,0x5a2f1773),LL(0xc2f14e0d,0x5e7f3258),LL(0x6606eb12,0x77a28311),LL(0x67442ff0,0xc80cdb6d),L_(0x0000010b), + LL(0x009d2841,0x6f4c68a5),LL(0xfaab85ab,0x18a863e0),LL(0x8722f321,0x96627616),LL(0xe3cfe440,0x1b986ba1),LL(0xc819b534,0x03e0ab51),LL(0x7155ab76,0x9cf682fc),LL(0xc9e37547,0x4f4f98e5),LL(0x137f31be,0x3cda736a),L_(0x00000140), LL(0x7723495a,0x91d6868c),LL(0x2e86f052,0x70f48703),LL(0x14f3d533,0x6c353990),LL(0x099af7f9,0x0b2a6c71),LL(0x3d4612fb,0x9b98b62b),LL(0x406a6c59,0xe6249353),LL(0x3b1b8dd5,0xc92d7a1b),LL(0x1f751af1,0xf81ef140),L_(0x000000e0), + LL(0x3770cf24,0x2c9d1106),LL(0xdc34aa30,0xa7bfe1cd),LL(0x28ee1801,0xd18bd43a),LL(0x6d6e3e49,0x52b35eba),LL(0x25fc7059,0x7bfa8888),LL(0xe767a889,0x487fe05c),LL(0xbcac8ca5,0x09996d23),LL(0x52fe2328,0xe81bfb43),L_(0x0000010d), LL(0x0fdc93f1,0x121f3bab),LL(0xa0be654b,0xd4307448),LL(0x230e8622,0xa9492744),LL(0xcf01fc0b,0xe7b1abae),LL(0xcc98dab2,0x4d9cffdc),LL(0xf6504381,0xe9697cb5),LL(0x506e8f37,0xc3dfae33),LL(0xc253ed02,0x141d1dda),L_(0x0000011d), + LL(0xbe8f2ee3,0xd4e2418e),LL(0x60bac026,0xe3153f45),LL(0x08c6a85e,0x8e05a0fb),LL(0xabec7d7d,0x5867d053),LL(0xca6918d3,0x1ebaaa06),LL(0x7d8627f0,0x6ea92220),LL(0xdfe74b9c,0x27dc332f),LL(0x54478deb,0x33ddba7b),L_(0x000000b6), LL(0xda8ae443,0x2feb3b84),LL(0xd254321c,0xbd92cdce),LL(0xae0be12c,0x91edd7e2),LL(0x65ab5fae,0xacef4485),LL(0x607c22ad,0xe3f288c1),LL(0x01e22b70,0xa3baea8d),LL(0xe3598c73,0xc24e3c94),LL(0xf89cd9f6,0x595791d3),L_(0x000001a5), + LL(0x9ea2f400,0xa048c822),LL(0xbacfe4cd,0xc1680ce0),LL(0xd2bf80ae,0x4efcb3dd),LL(0x3024028c,0x029e5c0d),LL(0x63d006d1,0x5acb256c),LL(0x1d3229cd,0xee644462),LL(0x6e4f2a9d,0x4aa18f75),LL(0xd4fdba43,0x437e2a93),L_(0x000000b4), LL(0xffc70ce4,0x7de729a4),LL(0xcdd3e499,0xf4a84a14),LL(0x9fba5f0d,0x87d56bc9),LL(0xa92225d1,0x637de402),LL(0xa9f81afe,0x142558b2),LL(0x2061f42e,0xd09b2789),LL(0x1e15d846,0x8753411a),LL(0xf0c0c378,0x83c3fa31),L_(0x0000012c), + LL(0x2af88f08,0xda11421c),LL(0x8eaf7d82,0x6c3eef0e),LL(0x9224cdcb,0xd8359bd5),LL(0x34b2e501,0x734d08d8),LL(0xd9f7f27c,0x60136559),LL(0xa91fd047,0x7da1c7f8),LL(0xcb1bc103,0xf3f7e7c7),LL(0x65c241e1,0x7555ce39),L_(0x000000f9), LL(0x324c47c2,0x6b91fc57),LL(0x5484eacb,0x8a825cda),LL(0x888b470b,0xf0a2ebdb),LL(0x81202cfc,0x3ac37a5b),LL(0x05c01038,0xfe8f11c9),LL(0x5bf196e7,0x76123e92),LL(0x19cd94ed,0x353febf7),LL(0x9c972db2,0x65d70280),L_(0x0000019d), + LL(0xf016362a,0x217d03c5),LL(0x56db67a5,0xf3d76a7f),LL(0x992b8bdf,0x4fb50dfa),LL(0xf9702a82,0x5593b5d5),LL(0x9088a3ea,0x0ef00d4d),LL(0xbf26b47f,0xeb497149),LL(0x0793417a,0x58262023),LL(0x465f75db,0x4abc908a),L_(0x0000009e), LL(0xfa362b63,0x1667b32f),LL(0x4ef57c25,0x0a4bdcb0),LL(0x6e8c095e,0x696391d7),LL(0xabbc605b,0x1dd44220),LL(0xc3e47f6e,0x38adb47e),LL(0x8f35f645,0xd3c084d2),LL(0xf253b25e,0xfaa3b241),LL(0x0b53ca2e,0x2e3d4cbe),L_(0x00000189), + LL(0x3b140c85,0xf26ba24d),LL(0x0d68d639,0xbc6bcbf3),LL(0x76bdcf5c,0xd445a425),LL(0x4ce8f583,0x036223e7),LL(0x12c0333e,0x6b6c4cf4),LL(0x411cd547,0xfa6d4a89),LL(0x6d3fb3c8,0x7e41166b),LL(0x906f6895,0xd5a83001),L_(0x0000006a), LL(0x04968a38,0x33fa874d),LL(0xdb9b9bf4,0x6efa8bd8),LL(0xc1467c44,0x78067572),LL(0x41957d49,0x68a286e7),LL(0x4563827a,0x3562fe94),LL(0xd87962e4,0x5b2ba1f2),LL(0xbce9e3b5,0xeb40dfc9),LL(0xedcbc4f7,0x6ddd5a2c),L_(0x0000004c), + LL(0xc41935fa,0x70bab965),LL(0x738ba18f,0x90ebea6a),LL(0x3526ec84,0x544312d2),LL(0x606e765e,0x4f7ce18b),LL(0xe015cac8,0x0b6de72b),LL(0xea01d5b4,0x2ff4bd72),LL(0x0c7eba91,0x90d594c1),LL(0x8a32c97a,0x881a1a5b),L_(0x000001cb), LL(0x2511b170,0x8272c1c5),LL(0x72a5ff2c,0x0ff0a2ad),LL(0x4bb6c7a4,0x640ae3bc),LL(0x87804672,0x00da0040),LL(0x94aaf22e,0x2ebbcebb),LL(0xd8f3e9bf,0x8646dab7),LL(0x40c90d99,0xd08b3434),LL(0x8f9d970b,0xd1f0de73),L_(0x000001e3), + LL(0x7fee2d24,0x893123ae),LL(0xc8b47342,0xedaef283),LL(0xde3df2dd,0x303757c2),LL(0xc96f2592,0x089845fe),LL(0xa0d3f290,0x18b0b508),LL(0x4bf7b214,0x93c88975),LL(0x3cd67758,0xed218a4a),LL(0x81a61b63,0xfa78dcc6),L_(0x000001e5), LL(0xb7b5abd8,0x90ce8d10),LL(0x6c24429c,0xe40a36fc),LL(0xc3ad8e81,0x6178bcf5),LL(0x16d9b177,0x488d2cf8),LL(0xc063b1e0,0x57f41dcf),LL(0x1cbca7c3,0x200bb41d),LL(0xec7a80d6,0xd6366c22),LL(0x84ceffb4,0x66439f2f),L_(0x00000092), + LL(0x487aacbc,0x869f06cd),LL(0x97f9882a,0xaa57537b),LL(0xe3b1c07d,0x917cf4ff),LL(0xf6d1aa12,0x2683a59f),LL(0x73bca1f9,0x613d785e),LL(0x496708d8,0x66ede999),LL(0xf45fff24,0x4e9727c1),LL(0xf71c4572,0x39995099),L_(0x000000fb), LL(0xf3181f1f,0x60222373),LL(0xf249fc50,0xdb62572f),LL(0x95b4f7eb,0x4efd7ca7),LL(0xb4994b20,0x0762c1c5),LL(0x99292d14,0x4d4c1985),LL(0x140a608e,0x7f0ba7f9),LL(0x489023fc,0x77e472d8),LL(0xac039583,0xca8aeb86),L_(0x00000176), + LL(0x3a9026ef,0xa1cd049d),LL(0x859af0b3,0x32b70dbe),LL(0xd9aa6b96,0x83656cba),LL(0xa5229dc4,0x02bc7ba1),LL(0x574b487d,0xffc68a06),LL(0x9518ff35,0xad36470a),LL(0xaf20c720,0xcf8b908a),LL(0xee3bb49e,0xf8b9d88a),L_(0x00000166), LL(0xaca41ffd,0xc04ae92a),LL(0xff799aa5,0x352ca9e2),LL(0x48de6d0a,0xeb0f3051),LL(0xe2b8f5f2,0xa98f1062),LL(0xdfe726fe,0xc285eca4),LL(0x22419400,0x527244d3),LL(0x441ba1f9,0x3ec0c841),LL(0x9ac0f611,0xf7b09376),L_(0x00000167), +}, +/* digit=74 base_pwr=2^370 */ +{ + LL(0xde7c70ef,0xce2d58e6),LL(0x4fd2b399,0xe56a0a18),LL(0xd46ffafd,0x43a772e3),LL(0x61832664,0x5e99ec73),LL(0x5a652a9e,0x068acc97),LL(0xda22ced1,0x829eb99d),LL(0x17534159,0xc94c616f),LL(0xf6ab0176,0xa334609d),L_(0x000001bd), LL(0xac6018e9,0xf0e586eb),LL(0x03144a03,0xdf49ef2f),LL(0x70d82d13,0xf054795a),LL(0x3d4fad35,0xca4e83c9),LL(0x7178dcbf,0xdccd2e81),LL(0x06f96d5d,0x059906d9),LL(0x99860a4c,0xb0cc8989),LL(0x0b7c4473,0xc7a2422f),L_(0x000000a9), + LL(0x7dbd2185,0x990d40ea),LL(0xfd292d5f,0xfe2aa0bf),LL(0x0b3c033e,0x350ffa07),LL(0x7093caf5,0xcba18d05),LL(0x8e77aa62,0x5de1ef34),LL(0x8dcafce9,0x8d305062),LL(0x54c13b97,0xa2184206),LL(0x024b7581,0xc1eed7a3),L_(0x000000eb), LL(0xff7787c9,0xd2467c3c),LL(0x5919f6e7,0x6f3a2cc6),LL(0xe4ef4ee6,0xd95dc335),LL(0x8b15339d,0x53862418),LL(0xc47f7183,0xdc9f6ee9),LL(0x0164075a,0x8fc3c2d0),LL(0xfb8c9b9b,0x82f15ec0),LL(0x2cab4250,0x6da80b24),L_(0x00000170), + LL(0x470b4573,0xce799013),LL(0x9e5e77aa,0xdc0e8efd),LL(0x74901979,0x87335bd4),LL(0x8d25ae87,0x7663b155),LL(0x30b14eb3,0x42427def),LL(0x9f7acb63,0x504e9e47),LL(0x8f787f03,0xb68c9ee0),LL(0x9fb2d8ed,0x3fafed1d),L_(0x00000087), LL(0xded73ba3,0x84c837fd),LL(0x1b05f526,0x361ad6ff),LL(0xa178f8a8,0xba6a96b6),LL(0x0afa0765,0xf1a53f48),LL(0xee02b40e,0x455203e1),LL(0x280a052e,0xa80a8929),LL(0xcc11be29,0x6815682d),LL(0x4811eb83,0xd7ede303),L_(0x000000c4), + LL(0xaaf54dad,0x33981c54),LL(0xcebb5e69,0x32546345),LL(0x544b1b16,0x84cafbc6),LL(0x7981b01f,0x5cddc181),LL(0xaa139311,0x1378ad86),LL(0x68cbb494,0x7e2675fe),LL(0x588ce3ac,0x7f2694e9),LL(0xab708d62,0xeda381dd),L_(0x0000009d), LL(0xe3c020fa,0x31d5f56f),LL(0x1a13df6f,0xcdb4564c),LL(0x02f2a54c,0x586ae362),LL(0x19118f47,0xdb9ebb1f),LL(0x7fa3e3f6,0x0b71b651),LL(0x82c695b0,0x82ecf8c2),LL(0x58306aa8,0xc8a72bb7),LL(0x24bb71fa,0x1671f4f9),L_(0x00000135), + LL(0x1f561cbc,0xccfdb09e),LL(0x9138999d,0xfc40b806),LL(0x190da0c1,0x248d01f8),LL(0x660fe973,0x04db0124),LL(0xd2a3e26a,0xae1441c8),LL(0x3b5b69d9,0x542d784a),LL(0xe47e9fb1,0xc8706904),LL(0x07fd3e18,0x7b0252dc),L_(0x00000097), LL(0x8560fa2e,0x9bf565f8),LL(0x7a07a372,0xb2a08e69),LL(0x88b9b9fe,0x23737883),LL(0x4af5f0ac,0x3ee2589f),LL(0x4d74831e,0x0c99ecfe),LL(0xe461011a,0xccb75730),LL(0x5f6ac945,0x44dfe861),LL(0xde67a0c4,0x0a4190dc),L_(0x00000007), + LL(0x3171ae42,0x8eb6ed93),LL(0x8217bc59,0x480c8b3d),LL(0xf9f73e7b,0xed85e1cf),LL(0xa742114e,0xff0dd45c),LL(0x5d90782b,0x6499236f),LL(0xa8a56eb6,0x81a46542),LL(0xc0a1d718,0xb645bf88),LL(0x5ad3645d,0xda5b3451),L_(0x000000b5), LL(0xf266cd0a,0x8177efc2),LL(0x91a87849,0xd64e2a8c),LL(0xb25866c7,0x7fcea597),LL(0x7ba86329,0xf0a84157),LL(0x4ae784c7,0x6d45e6a0),LL(0xe8a4e8e8,0xbad02a45),LL(0x2b8a78de,0xcb445d9a),LL(0x1a096a8f,0x1c606af7),L_(0x0000006c), + LL(0xeb0a1bdc,0x9ad71dbf),LL(0x013860f9,0xefc2f3af),LL(0x0bf5cd2e,0xcc51df06),LL(0x366cecf5,0x8b6d4774),LL(0xff5f3234,0xb320cd40),LL(0xa48903e0,0x331e170d),LL(0xf463c308,0x7b602dac),LL(0x3d097dcb,0xca3b41f6),L_(0x00000081), LL(0xa54e089e,0x1f06f98d),LL(0x9812b78b,0x0835cbf9),LL(0xa1b46e69,0x96985a6e),LL(0xc756e3cb,0x8c83dd55),LL(0xe0033ed2,0xc71730ab),LL(0x7a46dc00,0x333b6de9),LL(0xe8045912,0x8f656577),LL(0x4a453d9c,0x385fe0c5),L_(0x000000a9), + LL(0x0691a0c5,0xcb831835),LL(0x9d0103c9,0x47a18b26),LL(0xbca486ca,0x2d151fe9),LL(0x8a31af06,0xc2bcd6c3),LL(0x4c38dae7,0x6a2dd494),LL(0xd0cab5f5,0x0e8dd5e2),LL(0xaaffb6b8,0xf1aa0451),LL(0xd1b4ab87,0xd7ec926b),L_(0x000001aa), LL(0x0b242143,0x61149962),LL(0xd2761793,0x4dbe67f0),LL(0x5f42f5e1,0xbdaa4d19),LL(0x9aea3745,0x2770c1ff),LL(0x336a10b0,0x730746fe),LL(0x965986ef,0x500d5a19),LL(0x98b61ae7,0x2c56a5b5),LL(0xfbc2b7c9,0xf20ece26),L_(0x000001c0), + LL(0xcdc9325a,0x47a76498),LL(0xc197a42e,0xa29d1821),LL(0x8a2704b7,0x54a27b18),LL(0x6d7a65e1,0x382392a3),LL(0x6e25e555,0x583ca3d8),LL(0xba1298fb,0x92305de9),LL(0x8762634a,0xc416a724),LL(0xe3560751,0x52b73064),L_(0x00000044), LL(0x9052c067,0xd4b7caca),LL(0x4fc9c7a4,0x0d61d52c),LL(0x88ca3d7d,0x39c96801),LL(0x9d85c914,0x072c2d52),LL(0xeae1af66,0xdc7e4834),LL(0x4567d964,0xcf69cc8b),LL(0x225a1435,0xec05edf7),LL(0xcf0fd41b,0x16674dc5),L_(0x000001ec), + LL(0xea4af642,0xc929fb7d),LL(0x666eee50,0xa82ad2d3),LL(0x943d9f3f,0xe959c5db),LL(0x01361c6c,0x413dcd10),LL(0x810dc990,0xba8e95a8),LL(0x111bfce1,0x144ccf37),LL(0x37942ccc,0xbba23cc8),LL(0x6250c86e,0x64797a98),L_(0x00000124), LL(0xe58dd600,0xa61fd6b9),LL(0x324caf26,0x208fb38d),LL(0x802296a3,0x923005fe),LL(0x1cab4d64,0x545d2ffc),LL(0x7edf08f3,0xfd85bdf3),LL(0xbbb0b3e1,0x9feb12a7),LL(0xab0ed8c1,0xeb4e517d),LL(0x45179c50,0x5c75791e),L_(0x00000194), + LL(0xe472b5a7,0xebddb001),LL(0x809051bf,0x932eff69),LL(0xb46ff016,0x5ce81f11),LL(0xb49261d6,0x39183971),LL(0x75ef3047,0x65753518),LL(0xefad1e5a,0x7887db59),LL(0x147b2e1c,0x6c93b47e),LL(0x239259f0,0xb5f34e30),L_(0x000001c3), LL(0xd6dbc9aa,0x905217df),LL(0x861e1dc6,0x9fada5a7),LL(0x3986b470,0xf9e88cd0),LL(0xcaab1d92,0x839c290b),LL(0x02e99a54,0x39b3ffa9),LL(0x910523a5,0x655e6f7c),LL(0x42d47f30,0xb367bd8a),LL(0x1e0a7f1b,0xe25d7561),L_(0x000001b2), + LL(0x72ded5be,0x4987e69d),LL(0xd0493c78,0xba0a5cbe),LL(0x59557a83,0x75bbdb17),LL(0xf2acabc4,0x65e4a623),LL(0x8bf3c53d,0xd71fb7df),LL(0xc8eb2466,0x7545f576),LL(0xc6d8140f,0x620a0123),LL(0x9f02bd4e,0x67837a46),L_(0x000000b9), LL(0x16cfc43b,0x8b871f92),LL(0xc2538248,0x4b3a3a4d),LL(0xef93af7d,0xdbf730c3),LL(0xbfd3ed77,0xf764526e),LL(0x07f935a6,0xcb6152b4),LL(0x1c016476,0x2bf32571),LL(0xdee3ad5a,0x88aaec73),LL(0xfb09ed56,0x5a614fc9),L_(0x000001cb), + LL(0xb19e9875,0x7c127a9f),LL(0x26712a11,0x642533c6),LL(0xf98c4d57,0xc60c2ae3),LL(0x65b1d46e,0x444527b6),LL(0x71dbb3f8,0xe33842c0),LL(0x4381ace7,0x9e839852),LL(0x6a3b078e,0x2c3ba212),LL(0x4de7e214,0xed5d5463),L_(0x00000071), LL(0xde560bf6,0x2312ab46),LL(0x8e3acd07,0x631b2001),LL(0xb498759a,0xcc66ba39),LL(0x22f04bfe,0xd634fae4),LL(0x0f57a006,0x6fb05b0c),LL(0xd36ff867,0x74e2535a),LL(0x85b24cf7,0xe1ec7865),LL(0x1a8674c2,0x8caeb36c),L_(0x000000ae), + LL(0xb79af8c7,0x41ce000d),LL(0xbbc4d762,0x3f8e4f4a),LL(0x850dfa23,0x315d2f3b),LL(0xc39228da,0x146ba937),LL(0xe938195d,0x05ba80b7),LL(0xa6946ca0,0x5996d5e9),LL(0x8582cc92,0x20830fe7),LL(0x9fbffd5e,0x49bd8864),L_(0x0000013a), LL(0x84fe2ca4,0x52a9ca5f),LL(0x342678f8,0x0fde0f1b),LL(0x03e8057f,0xb03f731a),LL(0x68041b2c,0xc1b65ef3),LL(0x5e348390,0x812a39aa),LL(0x6058d643,0x85301a5f),LL(0xf291dfe0,0x3f43fec2),LL(0x4f9f3872,0x0ea19231),L_(0x000001c4), + LL(0x5896d88c,0x2071dbfe),LL(0x4b89bb6a,0x243135cc),LL(0x0ff935bd,0x7a1a0770),LL(0xe0c7a9ac,0x227a5593),LL(0x6dd5bad8,0x3493e1c5),LL(0x8ba3715d,0x35c53b09),LL(0xc6b271ea,0x744d2bd3),LL(0x2e9feb1a,0x214dd692),L_(0x000001cb), LL(0x59ccbf72,0xeec6e175),LL(0x1f9d847f,0x63ead5ad),LL(0x5419e32c,0xd6156a57),LL(0xe233586a,0xe66a5622),LL(0x39029648,0x4092e8b6),LL(0xbf26b933,0x1e5f719a),LL(0xcd5ad746,0x4f5fc4b9),LL(0xf552f21c,0xd86c96b0),L_(0x00000191), + LL(0xb57fb012,0x9ad2983e),LL(0x090fc8d4,0x3313e6f8),LL(0x55cd8ed4,0x8651d168),LL(0x6a906312,0x55315e35),LL(0x591a919d,0x83731bdb),LL(0x5172884d,0x209c90f3),LL(0xe2ac6b9b,0xfbd125cc),LL(0x92e9decc,0x7d19839d),L_(0x000000c6), LL(0x081749ac,0xed7835fb),LL(0x29318405,0x7858c38c),LL(0xc88969fe,0x39c13839),LL(0x9e3d9e6b,0x193b8588),LL(0xa0e5421a,0xe0167b73),LL(0xc6ebad78,0x3cbbe3a6),LL(0xea506121,0xa8cbcf0f),LL(0x20f99af7,0xdbdf82d3),L_(0x00000134), +}, +/* digit=75 base_pwr=2^375 */ +{ + LL(0xbc40ed79,0xa97c0378),LL(0x851811ca,0x042ad325),LL(0x0425fd5a,0xae223e37),LL(0x93b83181,0xf721e5a1),LL(0x90e949dc,0x0e3457f0),LL(0x3df6a852,0xb654bab8),LL(0x5f22447c,0x720ad354),LL(0xec0dfbcc,0x64eddb51),L_(0x00000100), LL(0xa4ebf78a,0xa97e2d48),LL(0x5a22dda9,0xa660386d),LL(0x4ad7ed63,0xf4eac86c),LL(0x0e9bdfd6,0xa0b3cfe9),LL(0xf3d0576e,0xb9746e43),LL(0x38598ede,0x5a4f247c),LL(0x6c63f53c,0x9110d7d6),LL(0x937de7ce,0xedc5628f),L_(0x00000180), + LL(0x39240f69,0x07ceb75a),LL(0x22d17ed3,0x1d003cd4),LL(0x816d46db,0xacb6fef8),LL(0xb000a452,0x9bbe93ac),LL(0xa33425cb,0x8e7044e1),LL(0xd94105ed,0xbf04fc32),LL(0x7b448d72,0x8a8006d7),LL(0x77527b27,0xce1c27af),L_(0x000001f3), LL(0x04fea417,0xede21a04),LL(0xbea8a562,0xfe905ba2),LL(0x7dcaa390,0x8bd01814),LL(0x8c2e3be5,0xad37906a),LL(0x4bd6ba24,0xe4147c93),LL(0xab35993e,0x54b18700),LL(0xeb32c196,0xc4b62833),LL(0xfde9fb6d,0xefce4982),L_(0x000001ff), + LL(0xac68f4e5,0x326389a5),LL(0x8c87ee07,0xc8d06b64),LL(0xf1eb33ca,0x9f6c9bde),LL(0x905394b5,0xe7cff087),LL(0x9daef572,0x15defa0d),LL(0xdcb4d146,0x48372dac),LL(0x9d9bc2a2,0x558be40e),LL(0x918fbab0,0x093092b7),L_(0x00000105), LL(0x420c8419,0x80e77a4e),LL(0x1e399561,0x7faf6193),LL(0xe636d3ab,0xe0b54eab),LL(0x0991ea6a,0x12db09ef),LL(0xe300cb6a,0x2c4871c5),LL(0x5b2c3ec2,0x74b476ca),LL(0x01ab0f81,0x571997b2),LL(0xe7647206,0x7f0593e9),L_(0x00000120), + LL(0x9d919a09,0xcb8ddce8),LL(0x53953842,0xc94eac86),LL(0x510be22e,0x18af52b2),LL(0x5204fc68,0x6cd384c6),LL(0xb08bd4d3,0x40918e38),LL(0xbbca8f66,0xc2ac8cd3),LL(0x9b3d5866,0x2e4fdaef),LL(0xbd15b5a2,0xcebfa696),L_(0x0000008f), LL(0xf5dbeff0,0x8986becf),LL(0xa9f4f0a0,0xb5bde2b0),LL(0x2781857a,0xf623a384),LL(0xf48f7d34,0x2fc32d5d),LL(0x5aed2eab,0x3357b29a),LL(0x85d8000c,0xd7a02a4f),LL(0x47c091a8,0x83e2289a),LL(0x748c8758,0x78f3991d),L_(0x0000004c), + LL(0xa0a58e79,0xe09895cd),LL(0x8dc487b8,0x1ee06c73),LL(0x4cd52925,0x3615a586),LL(0xb40cf5e8,0x67c6302f),LL(0xe2444c40,0xad0f9fd1),LL(0xf79a9138,0x21560ea8),LL(0x53b1f139,0xdfcbf2e3),LL(0x42f5c15e,0x937e18f2),L_(0x000000d1), LL(0xb23bfb76,0x2b5822b9),LL(0x4289e6fd,0xcce11b47),LL(0x6b3fbfe6,0xfc6c35ad),LL(0x42db4435,0xf40269b9),LL(0xd9e6571d,0x052ecbf9),LL(0x43b34e97,0x85c17cbf),LL(0xc1ac2947,0x2cf45704),LL(0xb8e4df72,0xccda58a9),L_(0x00000190), + LL(0x70c63945,0x736929bd),LL(0x2018c224,0x183d085f),LL(0x4be72094,0xb8504d5a),LL(0xa1b86c43,0xb6f18e21),LL(0x4ff46986,0x6ad297dd),LL(0x8a9142ac,0xaf090f36),LL(0x09fe86be,0x3b6921ae),LL(0x3c8c552b,0x953006e9),L_(0x000001ce), LL(0x0006309b,0xaf72ac6e),LL(0x80956c6b,0xfa741157),LL(0xc4c2c5f7,0x5e9870c9),LL(0x7ec1eba5,0xf57cfca1),LL(0xc10b4b60,0xa6e490cc),LL(0xb0618cc6,0x39e98a9d),LL(0x31fe5f00,0xf0f53611),LL(0xb1970dbc,0xa442baa6),L_(0x00000100), + LL(0xa7015016,0x90a308db),LL(0x61cca596,0xcbaa218f),LL(0x6743511c,0x6574da13),LL(0x71c34c1b,0x50cf99a2),LL(0x570b3140,0x8ae9a0ed),LL(0x8fffc78b,0x816fb1cc),LL(0xe8d131b4,0x052abb5d),LL(0x64b0d1f3,0xe564075c),L_(0x0000006f), LL(0x20ebfdef,0x5fb1b653),LL(0x57fab65e,0x72bc2ab8),LL(0xcd37e51f,0x6c8bb1d5),LL(0x57d81547,0x75b37fd5),LL(0x572bd385,0x1441e8d8),LL(0x0eb239d2,0xd5a6c392),LL(0x7cc7ae14,0x16b857f6),LL(0x7141c32a,0x931901c6),L_(0x0000016f), + LL(0x981eb231,0xe53ec842),LL(0x16678799,0xeb3f78fb),LL(0xdb8c26f2,0x1091298b),LL(0xe09307e4,0x265d3b22),LL(0x79682bc2,0xf829161a),LL(0x8a62536f,0xdea99410),LL(0x002fb6de,0x3d369ec2),LL(0xca79fdbc,0xf58b2f20),L_(0x000000ba), LL(0xa6987577,0xf756d9fe),LL(0x61419646,0x9934641a),LL(0x308b017c,0x5de627fc),LL(0xbea2b76a,0x23ee7d29),LL(0xba8603cb,0x6ab47900),LL(0x85c79476,0x004b96bb),LL(0xf41684cc,0x94d547ed),LL(0x8b7656ed,0x2003142b),L_(0x00000030), + LL(0xacf59bef,0x8759d864),LL(0xfb67c7fb,0x0407a03f),LL(0xfb9982ce,0x020231ea),LL(0x55103874,0x9d3dc0fe),LL(0x9a32c3ea,0xc54c5166),LL(0x8e76b967,0x7422e59f),LL(0x538d7969,0x1567215f),LL(0xc1772e51,0x1bee3ac0),L_(0x00000159), LL(0xbc5e3fec,0x44e31ef8),LL(0xeef4a1e2,0xf4d1de52),LL(0x78709a3f,0x144880f0),LL(0x90e1bf50,0xc5a2e2e7),LL(0x6576ad05,0x963afdb1),LL(0x858a5053,0xfb62a6ae),LL(0x720e44be,0xf7d3d903),LL(0x85ea2a35,0x1ce3e300),L_(0x000000b2), + LL(0x22a69bc6,0xc85cdf02),LL(0xe346fabb,0x2b0945e1),LL(0xe07629de,0x76a1e2b5),LL(0x45e5724f,0x43bc885c),LL(0x6f8c506b,0xbd1f5350),LL(0xc4a247ae,0x9759458e),LL(0xe8c49a8e,0xad9f81fe),LL(0xef961f24,0x0789ce81),L_(0x00000078), LL(0x536c8acc,0xbdac3a5a),LL(0x0d120ebb,0x2f38cfe3),LL(0x29a29c91,0x470f8673),LL(0xa93d27e5,0x85f54b6a),LL(0x347ce7f7,0x869bc2c6),LL(0x681c6e83,0x240291c1),LL(0x5f895132,0xd778a681),LL(0x9354c132,0x35657182),L_(0x00000113), + LL(0x600c6b7d,0xdc0c7615),LL(0xd08ada52,0xf64fa06b),LL(0x6fe343d4,0x0f9f191b),LL(0x269d74ba,0x2b582fb8),LL(0x3e1302f6,0x4f3fa209),LL(0x3dd58666,0xbaec4e8c),LL(0x2346df80,0x2addc663),LL(0x961745b5,0x6358e5f3),L_(0x000001c0), LL(0xd43fe3d8,0xbca3dd73),LL(0x0f473bff,0x97d4d8fb),LL(0xcbcc7f23,0x592d62f3),LL(0x8c21a728,0x2d18d7d2),LL(0x08669251,0x5acddad3),LL(0x10138815,0x5eb1d5da),LL(0xaf710391,0xf88b7078),LL(0x200a8738,0x9614df01),L_(0x00000078), + LL(0x3d24acd4,0x39f8e71a),LL(0xf8ccaa40,0x89f9fde7),LL(0x4a565eb3,0x3a88c7c8),LL(0x2241445b,0xb88e20b6),LL(0x0479b1b1,0xe22d8db0),LL(0x96695cdc,0x02fe3690),LL(0x48a70132,0xaba6a66d),LL(0xafe3713b,0x5be868e0),L_(0x000001b6), LL(0x6375d71e,0xc518718a),LL(0x3e38b8c6,0x00a613fe),LL(0xee16d3bd,0x8bab2dac),LL(0x5f51a73a,0xecd0dde7),LL(0x5d598b1d,0xf9a19d5d),LL(0xcc2ed8e1,0x74ed2f5d),LL(0xb66c7686,0x1a036457),LL(0x45717b78,0xeb14d9fd),L_(0x000000d5), + LL(0x8eeb7cce,0x42bb5d7b),LL(0x69ebb0a9,0xf6f6e0b1),LL(0x24c217db,0x751a1bfd),LL(0xd4eab425,0x1570cf87),LL(0x46afeada,0x55c17749),LL(0x84f69779,0x72264346),LL(0x0e0b6e91,0x43f9c928),LL(0x2a080641,0x5face2cd),L_(0x000000e6), LL(0x24d003a4,0xb97b52aa),LL(0xb84b4c35,0x079d267b),LL(0xea1ade5e,0xfd3d3470),LL(0x64da3bef,0x603b5d99),LL(0x4e2ca35b,0xc90c1bef),LL(0x267ee929,0xa4dcd6fa),LL(0x2e371559,0xeadf09d2),LL(0xdc90620c,0x7ae7bd5e),L_(0x00000131), + LL(0xa33f00cd,0xe19a4c40),LL(0x3bef2c63,0x57c68d2d),LL(0x922215ae,0x03e85348),LL(0xb54763ee,0x7a4a0d2c),LL(0x4381fb33,0x747d2320),LL(0x3d971222,0xc828be44),LL(0xd96627f6,0x6d1199b7),LL(0xabfb6b5f,0x3d2170b3),L_(0x00000043), LL(0x971bb69f,0xbb1d3366),LL(0x8c946a2e,0xa111d7a3),LL(0xb29fb103,0x75997def),LL(0xa9647d36,0x82824e10),LL(0xa45fdefd,0xf29d6d05),LL(0xa9b94f37,0xe35c500f),LL(0x317e08c1,0x4c601022),LL(0x2a6ed921,0xa2afcd4a),L_(0x000000e0), + LL(0x6053b527,0x14a651b3),LL(0x6443bb77,0xc4e092bf),LL(0x3d523243,0xb725b204),LL(0x563f7657,0xf0d19ab6),LL(0x6dd80a2f,0x0c09a035),LL(0xa3a7805c,0x72bfb218),LL(0x767659a8,0x5001304f),LL(0x06ad0ad0,0xae6cf2cf),L_(0x00000048), LL(0x12dbf627,0x73b1275f),LL(0x58294610,0xf2619fd4),LL(0x12455781,0xc2991198),LL(0x822a98ac,0xc52b1be7),LL(0x6f92e55b,0x85c5dde4),LL(0x6f912a88,0x71070200),LL(0xc6ff80dc,0xed86ff4f),LL(0x5fb4c0fb,0xf6cd415c),L_(0x000001eb), + LL(0x2ce62ff7,0xe13291f0),LL(0xa731176a,0xc2f095b8),LL(0x53e5b4c8,0x22d8f01b),LL(0x9b8d5a23,0xf09c9053),LL(0x6cfad192,0xac4c2264),LL(0x016016f3,0xc2d48df5),LL(0x500c56f4,0xbed57312),LL(0x206618c9,0x249d3807),L_(0x00000152), LL(0x64b93c61,0xa752bb21),LL(0xa854f0db,0xad82109b),LL(0x2bd9fbff,0x39d0e928),LL(0xe612cee3,0x5cfc63fe),LL(0x3aca9e51,0x18541bf3),LL(0x0fd5f823,0x1df11f0f),LL(0xdccc44f5,0xe5d7f0f8),LL(0xc8e26d92,0xdc204c43),L_(0x00000134), +}, +/* digit=76 base_pwr=2^380 */ +{ + LL(0x4cea698e,0x90df775a),LL(0xa877dfb5,0x0e8c657f),LL(0xf628f95d,0xc58775b2),LL(0x1f94b622,0x55966c52),LL(0xd94ba3e7,0x2b826bca),LL(0x536e1836,0x1429585e),LL(0x6a8bf64e,0xab9cff45),LL(0xfdc0d065,0x7ad254f1),L_(0x0000006b), LL(0x3e6824f3,0x10be2241),LL(0xa869cd60,0xb5cc49f5),LL(0x399cde94,0x029dfb84),LL(0x53bc96f6,0xc7d08220),LL(0xf3d33d68,0xb6cb5f4b),LL(0xd70bd72f,0x81e790ba),LL(0x5f85b782,0xd6b87ddc),LL(0xd6fbd3aa,0x9bddab2f),L_(0x0000007e), + LL(0x658551e0,0xcff0963f),LL(0x1215b91a,0x7ce3e2ea),LL(0x276c4b8c,0xae4d76fd),LL(0x27c2c599,0xcf3a3b9f),LL(0x985a8106,0x706667b3),LL(0x3dd5545f,0xe5bf95ab),LL(0x9ae8ea63,0x5a494d9e),LL(0xac8eb301,0x36df8e2a),L_(0x0000014b), LL(0xf96eb433,0x241e0605),LL(0xec384ae0,0x19fc3d54),LL(0xbfb3e2ee,0xce0a2d7c),LL(0xa5ac041b,0x7e0aa0d1),LL(0x22b978b5,0xcf6adf10),LL(0x50508726,0x13804525),LL(0x77d6d81e,0x02fbac9b),LL(0x34536c98,0x6666d2c2),L_(0x000001d1), + LL(0xc31ca580,0x0fd75964),LL(0x2c167fba,0x79fb34e2),LL(0x68658968,0x3d2ac14b),LL(0x6bb85f11,0xf9265032),LL(0xe567c4fc,0x09815c6a),LL(0x30478f2d,0xb2da7033),LL(0x2d4e045b,0x7450186c),LL(0xeb491702,0x3d6ff5bb),L_(0x000001cb), LL(0xd6230d65,0xa96aee5e),LL(0x7fa7f974,0x54b866f5),LL(0xd445b199,0x7edd540d),LL(0xda3cc41b,0x6672b9ea),LL(0x3c302e2f,0xf5adb45c),LL(0x5ea3de1b,0x201f8535),LL(0x70efd3fa,0x9bc11d2a),LL(0x3d2e2804,0x4d97e055),L_(0x0000009e), + LL(0xe0b71938,0xdb5aaa83),LL(0x020dd38c,0xf16c4ef4),LL(0x0a2db89c,0xa5cd426b),LL(0x43e8b727,0xf5617c8e),LL(0x23ddc0ba,0xb43d6e58),LL(0x259e17f2,0xc826180e),LL(0x06737413,0x55f63ef5),LL(0x434e7412,0x23e6163c),L_(0x00000096), LL(0x0c64c884,0x9695e5ae),LL(0x47505a19,0x6e1e36e5),LL(0x74ec16e2,0x43d8b0e2),LL(0x4831814a,0x037ed439),LL(0x5b1a104c,0x375672e8),LL(0x5bc4b456,0x9fdc64a0),LL(0xf4e8604b,0xdb5b0994),LL(0xa1d8d54c,0x035e5850),L_(0x000000d7), + LL(0xc1e1dd97,0x6b6358ca),LL(0xae97ec9d,0xf89cd326),LL(0x96931bf3,0x0db33ff8),LL(0x1728a8a2,0x5df6988b),LL(0x8b413bf1,0xc9cd5efc),LL(0x7876052f,0x980dbb18),LL(0x662d8014,0x7d44d414),LL(0x56d9235f,0xf0c89214),L_(0x000000df), LL(0x6a6bdb67,0x7d2553d4),LL(0xd43349dd,0xc275fa25),LL(0x98c5095d,0x7e9d6a23),LL(0x5dae8169,0x48607095),LL(0x004d6221,0x0de66e5e),LL(0x88753853,0x407e61fc),LL(0x0cbeddeb,0xb1e576ab),LL(0x85968acb,0x6df65046),L_(0x000000e3), + LL(0xdf2834dc,0x1d1376b4),LL(0x2c927fc0,0xf4b1b912),LL(0xcb3e3200,0xd6a633a1),LL(0x54477db8,0x4c991410),LL(0xbf0c1c32,0xa9a4d4dd),LL(0xda008df0,0x30c04f89),LL(0xf68e5507,0x1a10f51d),LL(0x5ce5c51e,0x41031547),L_(0x000000da), LL(0x15811373,0xdec76b03),LL(0x4ca12b9b,0x53a8bf3f),LL(0x4e3a3297,0x6ef86a89),LL(0xc5a499c8,0x38a372fc),LL(0x97d666c8,0x6ec44e4a),LL(0x41b99123,0x95600ea2),LL(0x650c8dbf,0x4eb71cc1),LL(0x4c7627fd,0x54f79c84),L_(0x00000186), + LL(0xc38fca05,0x69ce7225),LL(0xf1a6e969,0x77785cf6),LL(0x9cc6268e,0xc7d8303c),LL(0x2b8308ef,0x6b0e5276),LL(0xcba9dc8a,0xa4bf9968),LL(0x416fd26f,0x8c4cdb7c),LL(0xe7d932fa,0xde7df0b0),LL(0x472063b5,0xd8e36d94),L_(0x0000001b), LL(0xd88f945e,0x852f11b9),LL(0x528d0c6d,0xe34ebb6a),LL(0x0491c222,0x572cf3b4),LL(0x3235246f,0x6a507a97),LL(0x5419c482,0x151b4954),LL(0xa45d1468,0x1e9ff246),LL(0x555cac59,0x74cf9098),LL(0x3f67c66c,0x4d10852a),L_(0x00000081), + LL(0x109aae5c,0x4d4d6495),LL(0x86a81e7f,0x54df2c4b),LL(0x4316eb10,0x19b90005),LL(0x41b6877c,0x63ac12d9),LL(0xdbe38379,0x7bdc46a9),LL(0xe68280f8,0x04afbefb),LL(0x1d97d1dc,0x64f8fe97),LL(0xfdaabbcc,0x3ef9d7ec),L_(0x00000054), LL(0x1998e321,0x4256ebb2),LL(0x5f744a3f,0x462bbab0),LL(0xc6587a4d,0x8de305cc),LL(0xf7cc14a1,0xd2c0e8c5),LL(0x1c2fa456,0xd7f552fd),LL(0x93096db0,0xdf5d165b),LL(0xeef9e935,0x0a7d4ef3),LL(0x8313440e,0x2ecbc3b6),L_(0x0000000c), + LL(0x86173dd6,0x4ec080d5),LL(0xc4429668,0x00e4c47a),LL(0x0c5790c3,0x2bb3e90a),LL(0x76060854,0xb06d2fa8),LL(0x51871594,0xb8a8220c),LL(0x35fa01c4,0x96cfa275),LL(0x351722c6,0xd2b5aea0),LL(0xcac00f2f,0x9a7e1203),L_(0x00000023), LL(0x30706067,0xa79d695c),LL(0xe8bbd2be,0xc13d4a47),LL(0xdd17ddc3,0x3a2ef1d7),LL(0x835e7fe3,0x3a0d7223),LL(0xdaab1fae,0xeadcb841),LL(0x2baa3375,0x25d48c28),LL(0x3675311d,0x1cfce1d1),LL(0x8cca0828,0x6d648baa),L_(0x0000001e), + LL(0xeb6ee1f4,0x39772678),LL(0x4730fdee,0x4814bf38),LL(0x7da6e5cf,0x717ace32),LL(0x2440a79c,0x1fa530fc),LL(0xee76a431,0xf0840ed5),LL(0x64a9d867,0x9b3e52c9),LL(0x01e024e8,0x388a3167),LL(0xbc5a3de8,0xb45ab215),L_(0x00000127), LL(0xff0e20a7,0xdb989f10),LL(0xb0c72279,0x88321c3c),LL(0x461d5212,0xe2e0c887),LL(0x22583d6f,0x0422ef3c),LL(0x5319c021,0xf26dbc88),LL(0x3aba5f48,0x62bbe876),LL(0x7e742165,0x411f00ae),LL(0xd32aa7f6,0x6608e197),L_(0x000000e2), + LL(0xe82a5867,0xb2aed406),LL(0x5c51d66d,0xe49e1c0a),LL(0x341d6090,0xeca16754),LL(0x50aaa76d,0x3d4ae66e),LL(0x23dd6ea7,0xc264093c),LL(0xb964aff3,0x124124d1),LL(0x6a903309,0x320f2ccc),LL(0x040a80c9,0xa2fc450d),L_(0x000000f1), LL(0x442fcd61,0x660ce624),LL(0x876d5eb7,0xb113de73),LL(0xd6a08a24,0x8fdedfa3),LL(0x7e981617,0xccca4ec9),LL(0xbf6d63e9,0x1cbf7303),LL(0xd5b865e9,0x06258e51),LL(0x8b4e0432,0xae5f01e7),LL(0xed7485d8,0x1fb3ec8e),L_(0x0000007f), + LL(0x9cc6138d,0xcd3a614c),LL(0xaac40dbd,0x933beab8),LL(0x23a3080d,0x4ca0b1cd),LL(0x3c101e4c,0x2d0376e4),LL(0xcb246c76,0x8ef2560e),LL(0x3a96d882,0x54be7604),LL(0x792be430,0x4ed7cfd6),LL(0xe67d1eea,0x924a5689),L_(0x0000002c), LL(0x64c2420d,0x63647d6b),LL(0x9642188f,0x514cab56),LL(0xbcdfd904,0x529ea4a2),LL(0x876c6668,0xcbd5305d),LL(0xfa8c20c0,0x58b69ea6),LL(0x1ac42596,0xf62b1c30),LL(0x80232775,0xee3d0824),LL(0xc5b975d6,0xc483c2ea),L_(0x000000b2), + LL(0xd2eb9667,0x8bc6d688),LL(0x6c7bd269,0x7652c729),LL(0xc96e37bd,0x405791df),LL(0x410e2904,0x5ab8090e),LL(0xf9bde0c1,0x1a7b424c),LL(0x37d8159f,0x26876e27),LL(0x6e7212ab,0x5e21bc5d),LL(0x2ff3af58,0xa29dba58),L_(0x000000a6), LL(0xb27af4fd,0x7dd665a0),LL(0xe048ab97,0x19984a71),LL(0x17b7a849,0x8f61b833),LL(0x9bdf5b57,0xeb63a0f7),LL(0x32adf9dd,0x8eaf0eb1),LL(0xe30814ac,0x799c8225),LL(0x35be0b92,0xa082ff80),LL(0x7e52495d,0x196f3154),L_(0x00000054), + LL(0xe45aefc6,0x3b3fccf2),LL(0xf8b435c7,0x7f599023),LL(0x4b07f56c,0xc6614964),LL(0x1f9e8dd5,0x7bfaa97f),LL(0x57a41fcb,0x056d5124),LL(0x69dc4c19,0x33956d10),LL(0x2e70770f,0xac607019),LL(0x17397aa9,0xbda3b4ee),L_(0x00000082), LL(0x8bf00dd1,0x11800cef),LL(0x9f451540,0x5de0b39d),LL(0x9cd9ec18,0xf09ca421),LL(0x7bff70d3,0x3fc8f958),LL(0x6af7560e,0x348716d4),LL(0x2601495a,0x4ed53bb1),LL(0x39eaa8c2,0x97052bec),LL(0x87acae02,0xb4363c7a),L_(0x00000069), + LL(0xfcf4623b,0x010e4074),LL(0x23ceb817,0x68de1fa6),LL(0xb6c3610b,0x79b5037c),LL(0x794616e3,0x38ca34e7),LL(0x6964c6c9,0x64ba9eb2),LL(0x9d828a84,0x713e3f60),LL(0xc6cafea4,0x69bdca04),LL(0x0035da7c,0xc53921ac),L_(0x00000170), LL(0x66f97d4d,0xbe97815a),LL(0x678d3502,0x09bb25d5),LL(0x417b9931,0xadbec401),LL(0xa021e930,0xef1be11c),LL(0xb53777ab,0xfb3f04c1),LL(0x2e6bc85d,0xab9fbf13),LL(0x22a4d27b,0xb988012f),LL(0xddee5ad9,0xfda8aea8),L_(0x0000007a), + LL(0x3ed86b54,0xc43ac524),LL(0x9805e79d,0x95a2175f),LL(0x2bee2dfe,0x6125c31c),LL(0x2b6284b0,0x10319508),LL(0x2264eba0,0x8cedfa4a),LL(0x25bc143e,0x3199afa3),LL(0xe3ae2485,0x63067c6a),LL(0xebebe969,0x54a7cecd),L_(0x0000016c), LL(0x9434e363,0x6de3a522),LL(0x3a1a5044,0xf721555f),LL(0x644f2db4,0x6dc38924),LL(0xb72ad43f,0x39beb126),LL(0xe7dd7722,0xd840de05),LL(0xd6caacd0,0xc67a2862),LL(0xce6fa639,0xba53021b),LL(0x71087602,0xec9b5982),L_(0x00000079), +}, +/* digit=77 base_pwr=2^385 */ +{ + LL(0xb9a7e9fc,0xb75ed4da),LL(0x7aaab2f5,0x1ee37679),LL(0x30159305,0x0b02f44a),LL(0x021962a3,0xd622cf13),LL(0x55a3eea1,0x9a7dfa05),LL(0x4fcd685c,0x7a2a6aca),LL(0xd2e75077,0xbd4c914a),LL(0x1e6aa905,0xeec52d7b),L_(0x000000ff), LL(0x3f6fa1e0,0xfa95204a),LL(0x539f85e4,0x36eeec34),LL(0xe8ddc16e,0x74599d1c),LL(0x50244a9e,0xb343c6c5),LL(0x714c017a,0xb07951ae),LL(0x4503f92d,0x44d15c8c),LL(0x830499e5,0x94680ff6),LL(0xe7188a7b,0xd6c4809f),L_(0x00000147), + LL(0x9a2546bd,0x1bf14718),LL(0xf89fcfd4,0xc079070b),LL(0xa403ed89,0xa107b324),LL(0x18c3f861,0x4dade6e3),LL(0x665e9f9b,0x332b6327),LL(0xb408e3b3,0xf62f16ec),LL(0x11ee2181,0x67bbd1bc),LL(0xd0ba5904,0x4b5440b9),L_(0x0000000f), LL(0xde86660f,0x9cb1aa7a),LL(0x8a32a33d,0xedb96d1a),LL(0x9ae722d5,0x0654bd1b),LL(0x1664c777,0x03d0e5a5),LL(0x6a4a631d,0xfb01ee81),LL(0x3d1d9344,0xc7691584),LL(0x1e1821b3,0xbe2d285c),LL(0xafc22520,0xe0834d6f),L_(0x000001e7), + LL(0x256a6798,0x08d12f4d),LL(0xf2407064,0xd7255fb6),LL(0x1c6799f2,0xad7d86d9),LL(0x8c32b1c7,0x259fb289),LL(0x172083c6,0xcdc9f2eb),LL(0xc85a5a26,0xdca9f61e),LL(0x303eee79,0x82cff2b2),LL(0x283cc245,0xaea38a1c),L_(0x00000018), LL(0xac3447b7,0xf7fee514),LL(0xb0b385f6,0x0a48204d),LL(0x785b0f88,0xaff858dd),LL(0xae66256a,0x24f69e65),LL(0x92f5e352,0xe99c8d90),LL(0xb2e1ccee,0x40cfa4d5),LL(0x5201f6ee,0xfefbb836),LL(0xbcabc908,0x61f21689),L_(0x00000144), + LL(0x5183d337,0xd756d8ef),LL(0xaef07505,0xdd4c26d4),LL(0xfd1d5c09,0xb43bb4e7),LL(0x53c26645,0x6a817eb2),LL(0xf92f5487,0x6209c32a),LL(0x3e205a08,0xb9b883a6),LL(0x802502f8,0xa6f9cb8d),LL(0x2169b5a7,0x87089ec1),L_(0x0000008d), LL(0x5c3f78b6,0x4cc2981d),LL(0xc0b6dcff,0x39135fd7),LL(0xe2051e1d,0x0f800ca1),LL(0x76456f99,0xae12c766),LL(0x987a86bb,0xdfc5fcbf),LL(0xcbf344cf,0xa853db02),LL(0x65a4f55e,0x24b115f9),LL(0xf4d8cf4b,0x28cffa2b),L_(0x000001db), + LL(0x8518ed22,0x9698f500),LL(0x46e1cf5e,0xa37c3c3b),LL(0xb10d9d35,0xb6d8d81a),LL(0x6814e15a,0x65739419),LL(0x9282b5ea,0xf890c6b6),LL(0x80d764c7,0x7d309653),LL(0xda043f0c,0xd070b1e7),LL(0xc9e15f63,0xb143ef10),L_(0x00000056), LL(0xc6e28862,0x47fd9b69),LL(0x525c5453,0xc9876e94),LL(0xe52b9bcb,0x3078ffdd),LL(0xab8f2cfa,0x7e1a8a45),LL(0x338e4367,0x3382f009),LL(0x5b0092de,0x06454df0),LL(0xdb5d1cbb,0xbbf3f2d3),LL(0x17b40f75,0xb1b7961b),L_(0x000000b1), + LL(0x3c3b17c4,0x7aa9d1e5),LL(0x71e12980,0x69777935),LL(0xdfdae6a9,0x2f45dffd),LL(0xf2900457,0xabe3441f),LL(0x6471580e,0x5aece4d0),LL(0xd983618d,0x85cd6571),LL(0xf5a1d861,0xc2bd978c),LL(0x955894c4,0x81cae98a),L_(0x0000017f), LL(0x4b6d344e,0x3176598c),LL(0x4b7790dd,0xc91def7d),LL(0xb21152ba,0x279d992a),LL(0xd92aafdd,0x7dab9fb5),LL(0x59dd70d0,0x7039956b),LL(0x14d13b0f,0x7cfe20de),LL(0x7bd5d4c8,0x45b10bc2),LL(0x59724543,0x906a5d0d),L_(0x000000cd), + LL(0x2093c6ef,0x80b9235f),LL(0x380affbc,0x0b4024a8),LL(0xcd02b098,0xc98a3c0b),LL(0x36545f0a,0xe62cf7ea),LL(0x3b089c99,0xdade8fc7),LL(0xf9b4c955,0xf404f355),LL(0x7650e822,0xae64ac11),LL(0xcc0fb628,0x593a1b6a),L_(0x000001df), LL(0x4231a24f,0xa51f1936),LL(0x091d5493,0xeabe8135),LL(0x5285ec41,0x6bc185fe),LL(0x9a7df8de,0x25f54dac),LL(0xc1b5836c,0x4e5fc638),LL(0xde102ff5,0x81a60442),LL(0x56a67f9d,0xaeaff6ca),LL(0x7cc5f40e,0xdaecfbdc),L_(0x000001d0), + LL(0x01bbcb15,0xcd4c9f1b),LL(0x64ba5d43,0x262898c5),LL(0xb6d345ac,0x0f11b91d),LL(0xf8015622,0xfa53c395),LL(0xeb32e3dc,0x4e8f0647),LL(0x125c49a2,0x537471de),LL(0x5c783701,0x7a9741e3),LL(0x00bc6a87,0x1c5d3aa6),L_(0x0000003e), LL(0x5cbf2fb6,0x18eae31d),LL(0x1336f732,0x7555dff2),LL(0x63097ec4,0x8f16a8d5),LL(0x928e41ac,0xc063790a),LL(0x72cf7210,0x2842e2a8),LL(0xbed4668e,0xe7f0d214),LL(0x7b5aab91,0xbd94783e),LL(0x472089cb,0x55df6f3c),L_(0x00000177), + LL(0x5f960853,0x6ba36bea),LL(0xd6462023,0x51b0110e),LL(0x0299f400,0x5ad94e5d),LL(0x1c56f2f6,0xd8d6e619),LL(0x0b4ea27d,0xe73e18fa),LL(0xdcfdac26,0x61a026ce),LL(0x27dab320,0x4ebfdadb),LL(0xb6af0729,0xe9561c2a),L_(0x000000e9), LL(0xc786fe34,0x1418a240),LL(0x7a5020b9,0x2b5125f4),LL(0x7dac2ce9,0x6985bdc7),LL(0x7a36a07a,0x6d385362),LL(0xc0a58550,0x940163b2),LL(0xd28cbf38,0xfb9a9d22),LL(0x8eddbcd2,0x1cfcdeb4),LL(0xad40ff84,0x41da1441),L_(0x000001a8), + LL(0xf50794a5,0xf1ab6a88),LL(0x32d8d898,0xb4c956c4),LL(0xbd9881d2,0xbc516c73),LL(0x5116a36c,0x91e840e1),LL(0xff4abf28,0x14bf8bab),LL(0x2bc617a5,0xb012c75f),LL(0xba5d811c,0xf333effb),LL(0x37bcddc4,0x771a4567),L_(0x000001ff), LL(0x4a68eb29,0xa48d6dfa),LL(0xf2542b71,0x495f434b),LL(0xe3f39bde,0x9f969883),LL(0x179f2c63,0xa68cdccf),LL(0x44e28315,0x7408c1bf),LL(0xeb7b9849,0xf6615345),LL(0x823ede15,0xdf405d5f),LL(0x17f01e94,0x0efd64e2),L_(0x00000156), + LL(0xb7d5223a,0x6794bc7e),LL(0xfa3914f9,0x044623b2),LL(0x3e94e3f2,0xc7e42b96),LL(0x85cc2a9d,0xe0fbde7f),LL(0x2e0e1f42,0xde5ec740),LL(0x0a1b4e4e,0x99d96c6e),LL(0xa3d7e876,0x9b31d8b9),LL(0xcce96a38,0x4fd9fc85),L_(0x000001dc), LL(0x05826168,0x5b7a322f),LL(0x4317247b,0x01f0266b),LL(0xfd3d2a1d,0xa9fbb760),LL(0x75fc993e,0x60905a87),LL(0x51ce6740,0x3c6c984d),LL(0x16580d6e,0xe79ccbef),LL(0x585522ad,0x57fa547e),LL(0x42f80ccf,0x8ad71acb),L_(0x00000188), + LL(0xb6d705e0,0xb16ee0ab),LL(0x28366fe7,0x0365fed1),LL(0xc78aeb84,0xf329889f),LL(0xee74063c,0x16267a5a),LL(0x9c5a9197,0x040a619f),LL(0xc54b40cc,0x16e7345f),LL(0x9d5f609d,0x957fc0b1),LL(0xaf8fbbc8,0xb1cb4d02),L_(0x00000117), LL(0x099b7338,0xd023f32f),LL(0x1deda80b,0xacb49a95),LL(0x4c11c95e,0x00e1f672),LL(0xde8db891,0x19ee52cc),LL(0x27a5b5d8,0x6176a0d3),LL(0xd6752e2d,0xdfccd883),LL(0xe819161e,0xe1282202),LL(0xe71376c0,0xb92fddf6),L_(0x00000047), + LL(0xf4c8ed53,0xfecc3203),LL(0x7168d714,0x1726e41f),LL(0xea5d7e70,0x69dd518d),LL(0xe7aec797,0x2cfd3a6e),LL(0x9ab3823a,0xb90a5bea),LL(0x43831c4a,0xdbb35cc6),LL(0xd5853b0b,0x95c10ae1),LL(0x55834ab5,0xd668a3cb),L_(0x000000d5), LL(0xaa33d813,0xc0f7662f),LL(0x98346aa6,0x173a0008),LL(0xabe91f50,0x0508c118),LL(0x97cdd826,0x7255d2e1),LL(0x01d1e340,0xeb07ccd4),LL(0xf2f7ac53,0xc6829327),LL(0x966981ba,0x0fb3f4fa),LL(0x1ee6ae0f,0xea212110),L_(0x00000091), + LL(0xb4ca9aa1,0x3c713d51),LL(0x946494a7,0x1e6130d8),LL(0xbd5ab69c,0x6cbf341e),LL(0xcf57622a,0x94d1578b),LL(0xc7327897,0xb1db7d17),LL(0x2874559e,0xf5607998),LL(0xd15eab48,0x18199bc9),LL(0xfe1d9b44,0xd0aedc11),L_(0x00000056), LL(0x931fafb3,0x50c646ed),LL(0xb75609c0,0x9721b326),LL(0x4a7a787a,0xed16025f),LL(0xbf8835a3,0x78dc9b8f),LL(0xee0c8b9a,0xf388850b),LL(0x5a1458a1,0xc5cee39e),LL(0xb7bfeb06,0xecfd0e49),LL(0x8795b039,0x70bdfc80),L_(0x00000111), + LL(0xaa736cd0,0xa3c85c78),LL(0xbd49ba23,0xe512fde9),LL(0xdb860d3f,0xbf99d4e9),LL(0x3cb574a7,0xbc4c4fcb),LL(0x9af33dfa,0x88710836),LL(0xfd7ca4de,0x4b83fe29),LL(0xa2306095,0x03d40abe),LL(0x5f9ae75f,0x5e83ab1a),L_(0x0000007e), LL(0x64e02741,0x97d0048f),LL(0xf861736c,0xde0ffdb3),LL(0x5e0c4806,0x335dce14),LL(0x76e125cd,0xcc1ff27f),LL(0x16822cb3,0x8414749b),LL(0x44ae46e0,0x68085d31),LL(0xe89d0a2c,0x9c734630),LL(0x569b26c1,0x2d89e8f0),L_(0x0000004b), + LL(0x0c5ceff9,0x1dc45be8),LL(0xf3a736f8,0xb7b948b5),LL(0xf684853d,0xa1d8a120),LL(0x7de7af37,0xe3760299),LL(0xadb401c1,0xa1ba866c),LL(0x24e3e6ca,0xcd94496a),LL(0xc3eae9d6,0x06f82a82),LL(0x4a74e14e,0x069d9983),L_(0x00000143), LL(0x25e3e5c6,0x2a60baf5),LL(0x3855bae4,0xfbb6aadc),LL(0x20017824,0x950ab7cd),LL(0x9dfd2439,0x96b97104),LL(0x65cd1e13,0x4925d16b),LL(0xf2ec4dd1,0xd82c0815),LL(0x9059e2e1,0x3ba03a79),LL(0x2f723163,0xf35a3c60),L_(0x00000017), +}, +/* digit=78 base_pwr=2^390 */ +{ + LL(0xaa6fc06d,0x05eac10d),LL(0x1d0d93fa,0x3fb80a45),LL(0x30dbe366,0x69a67246),LL(0x1373df55,0x3a7b7740),LL(0x3b688d58,0x9a1bf576),LL(0x6f4ce0d1,0xc2030797),LL(0x72348a80,0xd874e749),LL(0x24296b9d,0x26fc8724),L_(0x000000d7), LL(0xacca6490,0xa4626a33),LL(0x0b206a34,0x661fc19c),LL(0x597e1cfe,0x1f98c11b),LL(0x010915e6,0x00c41adb),LL(0xbdcb2d64,0xfed21859),LL(0x07de82c2,0xeffa2475),LL(0xba1295da,0x73a4f297),LL(0x570842d6,0x1fc083b4),L_(0x00000172), + LL(0x3f4e6262,0x05474c79),LL(0xf27eccc5,0x9bbd81b9),LL(0x4061bf3c,0x1385eed6),LL(0xe5477666,0x2d5cbcfe),LL(0xa0f415ca,0xab0a8618),LL(0x18675f88,0x47e7c454),LL(0x0d5df7ae,0x75324e3e),LL(0xe2f88082,0xe818ccf0),L_(0x000001bf), LL(0xacbfbda3,0xc2d8f452),LL(0xef224de6,0x9ce12031),LL(0x70dcb7f7,0xd958660b),LL(0xc4597b18,0x4dfd1c89),LL(0xda0fa522,0x2d69ce10),LL(0x989afa82,0x46e81b65),LL(0x4e1b3fa1,0xdcac5039),LL(0x832ae217,0x7d3eef41),L_(0x00000032), + LL(0x95a0d4c5,0x5daa1b89),LL(0x542982e7,0x98f2622c),LL(0x5b7e32c5,0xa09068bf),LL(0x6931e543,0xeb5500e2),LL(0x9089e794,0x2a396afe),LL(0xe5f72142,0x68403342),LL(0xf625b926,0x14e9fc8c),LL(0x6171d647,0xe3e5f19c),L_(0x0000006f), LL(0x3951af89,0x9dfea1fb),LL(0xaf413d88,0x0a1d61f5),LL(0xb4928484,0xc08e23bd),LL(0xe1c147cc,0x3ba7bae4),LL(0x0b6e0358,0x7c12896b),LL(0xa84a4aed,0x0195f08d),LL(0x7bcd8649,0xeba99c7c),LL(0x799d1ac2,0x0193b278),L_(0x0000008c), + LL(0xd9c64878,0x91f424e1),LL(0xb2d18470,0x482b31fa),LL(0xc18abe11,0x4548d244),LL(0xc9e02a20,0x901117bf),LL(0xb1dc1cd2,0x286c34a4),LL(0x8ee98a6d,0x04c325a4),LL(0xb76b3ae6,0xdb518aec),LL(0x981c8298,0xb7194b24),L_(0x0000008f), LL(0x6a5cca1c,0xfd055d97),LL(0xc7061a3b,0x8a107a2c),LL(0x5a667bf8,0xaf0a63ac),LL(0x21028dc3,0x3e8641fb),LL(0xa80d9487,0xd40a558d),LL(0x63f8d8c7,0x3accfc09),LL(0xccc46547,0xfbd53079),LL(0xe85ce362,0x15006f15),L_(0x0000001d), + LL(0xb205016d,0x913326ba),LL(0xe7e20db3,0xe0e58c40),LL(0x4dd3a381,0x4f08867b),LL(0x8c0db229,0x1f57cf8e),LL(0x862604e5,0x9951f866),LL(0x588c2473,0xdd04385b),LL(0x2a4f4278,0x13235969),LL(0x334e1277,0xe14a7afb),L_(0x0000007c), LL(0x3623f8c9,0xce866486),LL(0x4c0e101a,0xfa8ba6d4),LL(0x8dee1016,0x1cd14dc2),LL(0x5e8be2aa,0xcc56a3c9),LL(0x5bdaa677,0x26fe9020),LL(0x787cbbf4,0x6059a9eb),LL(0xf27c2ccd,0x52b29d1e),LL(0x431ad6f9,0xe9273bbd),L_(0x000001d1), + LL(0x9927e056,0x531296c8),LL(0xa4ea86fa,0xe8dd3548),LL(0x107a45cd,0xd8b7e446),LL(0x1bfd985a,0x280a4e8e),LL(0x4fc2dc66,0x4b39f03c),LL(0x86dfa832,0xc44021ef),LL(0x55d3ccb1,0x210fe263),LL(0x65b0f1db,0x68364a82),L_(0x000000b2), LL(0x6b668b89,0x2aec7e7e),LL(0x7906edd3,0x941505c5),LL(0x5f4fddad,0x657d2929),LL(0x320073ac,0xefaffd81),LL(0x7ab9edd6,0xeb40eb69),LL(0x23d38d94,0xc8df60f9),LL(0x1840540c,0xbfea59c1),LL(0x3958b571,0x2f7620df),L_(0x000000e7), + LL(0x47515b25,0xa8d54597),LL(0x3ace77d1,0x23823b9e),LL(0xb05ab9ad,0x7d6803d7),LL(0x36f8db67,0x8ed91e87),LL(0x8fbc69ec,0xe0042a07),LL(0x6a246110,0x5131b89e),LL(0xf857a2db,0x4c1861d6),LL(0x311746a3,0x84c00e5b),L_(0x000000b3), LL(0x28bacfad,0x95ff285c),LL(0xdd895ec5,0x9a709b4c),LL(0xadcb32cb,0x148a78f6),LL(0x7c40e4b0,0xf62708ee),LL(0xd37d48a3,0x68232a30),LL(0x382492cc,0x79b622f3),LL(0x92d657a0,0x09992500),LL(0x6a420a8f,0x501d8de9),L_(0x00000062), + LL(0xc3287fc0,0xc122141c),LL(0x66149a76,0xc602d382),LL(0xfdcc4f6e,0x16b23844),LL(0xea0673e3,0x7ff0591c),LL(0x53082d2f,0x82264497),LL(0xafeaf6b5,0xca528c9c),LL(0x01a84f6b,0xe2403638),LL(0x43738672,0x54c4174c),L_(0x000000fb), LL(0xab8f5585,0x4205f340),LL(0x0b6de62a,0xa84853c5),LL(0xc67ea2a5,0x92e0d583),LL(0x296584f2,0x6bb7a441),LL(0xa9f0cd97,0xce6eb31f),LL(0xd0d33dfa,0x850b5886),LL(0xca9b5dbb,0xe75a3fb5),LL(0x143bbd95,0xfc35ee42),L_(0x000000a9), + LL(0x34b49dba,0xfe747fdd),LL(0x0c47e2c5,0xf9ae16bd),LL(0xa07b48d2,0x01c347f0),LL(0x2cf4c727,0x747fa6ef),LL(0x850ead03,0xff312b98),LL(0x8726545d,0x5218270e),LL(0xa6f367cc,0x7680a110),LL(0x37efad3c,0xe34b12a3),L_(0x000001a8), LL(0x5db6b25b,0xe1fe8e14),LL(0x5767922c,0xe0242975),LL(0x20a012f1,0xba21fc56),LL(0x49ff848f,0xbd4ab80a),LL(0xde1b4b0f,0x24104f37),LL(0x314917b2,0x221548c9),LL(0xde9c2909,0x6f74cf12),LL(0x75ca1868,0x44d62839),L_(0x000001c2), + LL(0x719fc99a,0x3109d76a),LL(0x044307f0,0x7372da8e),LL(0x9ba083bb,0xd35f32f6),LL(0xd25b7e53,0x0a6c99ed),LL(0x30794ede,0x1523c414),LL(0xed97a2a7,0x7dbb6798),LL(0x6d897d7a,0xb996ba83),LL(0x3c0356d5,0xad5ef539),L_(0x00000049), LL(0xf8000ae0,0x37a40ab6),LL(0xfbb2d425,0x468766c5),LL(0xd03d4766,0xe6a77a37),LL(0x09eb18e1,0x9d7f1644),LL(0xbdb7ff41,0xeeb2f1b2),LL(0xc98d5a19,0x8377c08e),LL(0xda52ef67,0x1078c0d1),LL(0xbd2d3d66,0x9181c3b8),L_(0x000000fd), + LL(0x2445d3d3,0x4f7f8d77),LL(0x663aa882,0x9e806c61),LL(0xcd6d9ab0,0x434a485b),LL(0x575aafa5,0x0477ae83),LL(0x1fb377fe,0x7b98c782),LL(0x4ac83912,0xe2f16d17),LL(0xd098d31f,0xeaff3b56),LL(0xfba7077f,0x13382e53),L_(0x000000cb), LL(0x128eb20a,0x4aad91ac),LL(0xce1a9e84,0xc8fc10e4),LL(0xb01bef42,0x6afd2473),LL(0xb1a03e1c,0x507c30ff),LL(0x3760275a,0x162b2e12),LL(0xabb38d7f,0x558877e8),LL(0x88916de2,0x9f519917),LL(0x2fdccf2d,0xf70b4695),L_(0x00000020), + LL(0xf946f824,0x4848296d),LL(0xe0f71789,0xf3835d1a),LL(0x9fea01e8,0xaf761a04),LL(0xc7d32c83,0x1060dc76),LL(0x6c5ff4c8,0xc3751915),LL(0xec6a8a45,0x6f1dbd4a),LL(0xdf6166cd,0xa64bcecc),LL(0xa942edd4,0x53c4d352),L_(0x00000073), LL(0x0fac6740,0x957c5d10),LL(0xe757c12a,0x60819db9),LL(0x5aae5302,0xfbc64c70),LL(0x72a99d6e,0xb00bbd49),LL(0x3bf68d69,0xf0b755c1),LL(0x125fdc71,0x4502c9bf),LL(0xe7e83089,0x7e20c9f2),LL(0xaefe0993,0x5fa7bc0d),L_(0x0000002b), + LL(0x1c0e7e3e,0x596ae14c),LL(0xc255b673,0x1bb0ac11),LL(0x19c21f40,0x04f2091c),LL(0x1838e69c,0x3e9cb56d),LL(0x51439522,0xc1cecfc9),LL(0x52a9b2f6,0xc564467e),LL(0x3576c345,0xeb0fdcd3),LL(0xd04ad0d7,0x3c3aa2c6),L_(0x000001ef), LL(0xba0860cf,0x54b2e727),LL(0x044d2e1b,0x8701d001),LL(0x794b02f7,0xd8153787),LL(0x4f463b8e,0xa0dfa5ea),LL(0x253e324d,0x8fc87618),LL(0x19c78239,0x6165c650),LL(0x97b77e54,0x134c2cb2),LL(0x5e23fc18,0x5ade1fce),L_(0x0000012a), + LL(0x17c9180d,0xaad903e8),LL(0xb407a7f0,0xa64c2d6e),LL(0xc577e3d9,0xd68527c3),LL(0x398177a5,0xdf38bff9),LL(0xde6b9d9e,0x746c3309),LL(0x1d7385a5,0x98512661),LL(0x3b8d9701,0xe82c0d22),LL(0xe2b7edd9,0x16ce165c),L_(0x000000e2), LL(0x4980d6c2,0x491b562d),LL(0xd2049870,0x1de2def6),LL(0xcf01bb60,0xaff2152d),LL(0x20717620,0x5764198c),LL(0x503a4861,0x9702cec2),LL(0xce53ec1b,0x886169de),LL(0xe97c752c,0x8d58887b),LL(0xeb1ce735,0xe1b8ee6d),L_(0x000001ca), + LL(0x2c437027,0x6213a0d1),LL(0x1d410b7b,0xba1aa221),LL(0xa8aa0a76,0xbd669af8),LL(0x06a3140b,0x196f88e0),LL(0xdc333cc8,0x1c9aa099),LL(0x60557f79,0xe1ff46ae),LL(0xa7b7da68,0xd7626d62),LL(0x2a5a72d1,0xffb47531),L_(0x000000d1), LL(0x1a06575e,0x72d98927),LL(0x8e521d9d,0x6acd3ed1),LL(0x855c8e97,0x47c48377),LL(0x42413164,0x89182c42),LL(0xae6a473b,0x59d11d10),LL(0x730eb702,0xd4abd611),LL(0x71fd7c4f,0x4d329537),LL(0xe8493373,0x5e745909),L_(0x00000143), + LL(0x3b653b69,0x4c6f3e4a),LL(0x688f6e0a,0x2a9b6d1a),LL(0x9e0c6a62,0xfebdd4b3),LL(0x7fb92759,0xe14d66ca),LL(0x3d698e7d,0x0a2edb8e),LL(0x08ea4d11,0x10b21ab8),LL(0x0f855706,0xf8405b08),LL(0x104c29e8,0xadf7ff63),L_(0x0000007d), LL(0x2f741dbb,0x4757c2f5),LL(0xe671ed88,0xb38018e2),LL(0xd5288875,0x629331d9),LL(0x279d96a8,0x7e602196),LL(0x559eca5a,0x81f2dc09),LL(0xf274c146,0x96818fe5),LL(0x483d0424,0x1c8246f6),LL(0x76f5286b,0x44ba1052),L_(0x00000179), +}, +/* digit=79 base_pwr=2^395 */ +{ + LL(0x0f7e89bf,0x42d44166),LL(0x0a8f4b54,0x924764d2),LL(0xf7bf31e5,0x26e4af60),LL(0x7be28350,0x9fc53bdf),LL(0x08056835,0xa12726ea),LL(0x726e147e,0xd5e175b1),LL(0xca2a0207,0x833e5911),LL(0x4d322cae,0x6cba51a1),L_(0x00000093), LL(0x4e7b937f,0xdaa1d653),LL(0xe0948dd2,0xca2b565c),LL(0x2f88e2ac,0x94ccb3a4),LL(0x85d91e6c,0xd8fe4775),LL(0xb59cebc7,0x0807f46d),LL(0xf4237821,0xfc9eb940),LL(0x402ecff0,0xd173f94e),LL(0xbf7bc598,0xaf975145),L_(0x00000116), + LL(0x75e9fe79,0x15942a4c),LL(0x3dad29e1,0x350dec67),LL(0xe6be55a2,0xca3c399f),LL(0x71245659,0x87e22652),LL(0x8f51c63c,0x1bd4c445),LL(0x758ae1a1,0x319b57db),LL(0x547db810,0x7d5c89dc),LL(0x62c8ba84,0x959a5bbe),L_(0x00000039), LL(0x3876f024,0x8c3d490f),LL(0x482b690e,0x50d48521),LL(0x83aada08,0x82c13331),LL(0x45c4a535,0xae5a3425),LL(0x31c1467b,0x51c50d6f),LL(0x2d093b81,0x84a7d97c),LL(0x82d6fbdb,0xdb41ffbe),LL(0x4953468e,0xae0e9fad),L_(0x000001e6), + LL(0xd4f44715,0xc26f9e1d),LL(0xb8562be5,0x71fd7b5e),LL(0x039f5b0d,0xe3196121),LL(0x073e4db0,0x902cc367),LL(0x22f8b999,0x604d9b78),LL(0xc1cfc4a4,0x52f26ece),LL(0x88d45487,0xa175f394),LL(0x9f16c268,0x9fe9a65c),L_(0x000000ea), LL(0x3d6adc59,0x54ed1ed1),LL(0x4d516f86,0xb3a46011),LL(0xa9ca3304,0x8c5e216d),LL(0x2030c9a9,0x86a5904f),LL(0xc0c4c573,0x9467bf24),LL(0xb4a6fdae,0xa652162c),LL(0xd3472536,0xb6166589),LL(0x31361b4b,0xfa3bddac),L_(0x000001b7), + LL(0x6c223a73,0xaa60773f),LL(0xe8255739,0x58459ee1),LL(0x672547b1,0x3f4e65fb),LL(0x0030639d,0x5059b89e),LL(0xc29a4f63,0x3ffb7b9a),LL(0x267e1823,0x6854cad3),LL(0x7f7d6bbb,0x79c3b99a),LL(0x20d91b6e,0xbec22c47),L_(0x0000005e), LL(0x6be80718,0xd72fbb0f),LL(0x307d9b73,0x7f8c46dc),LL(0xc6fa2f52,0xfbf3d06f),LL(0xd62e537c,0xd7888122),LL(0x4ebd3818,0x11ea61a8),LL(0x479a6f83,0xeafa5532),LL(0xa4bf3325,0xc7a31554),LL(0x5a717809,0x9520a809),L_(0x00000039), + LL(0x320654ac,0x4f775892),LL(0xb974b129,0x5ce12c3e),LL(0xe8064395,0x2e69ed62),LL(0x31e3ae39,0x9c220c3b),LL(0xd59ea4b1,0xb79732ea),LL(0x6f45918a,0x6600e529),LL(0x08681af2,0x4ed3f5dd),LL(0x507438a2,0xac5ccefd),L_(0x0000006e), LL(0xf3fc209f,0x5b14db7c),LL(0x2484d059,0x411826aa),LL(0x6005d933,0xca8c9d7f),LL(0x15dd0c44,0x1900212d),LL(0x96825f72,0xa3ea7e14),LL(0x921c8c87,0x20d2b6f4),LL(0xfdd63f04,0xbe8c25ac),LL(0x9f6a6126,0xa2592316),L_(0x00000128), + LL(0x8f2ae670,0x27b80789),LL(0x4f60fc89,0xc97bbd7e),LL(0xbd2ecac1,0x5b008578),LL(0xaaf75b36,0x3b54d53e),LL(0x6540b6f5,0xce5a0ab8),LL(0xac54c1d9,0x52d909c6),LL(0x67e6b65d,0x6607ea02),LL(0x7ea06112,0x0a94e0f9),L_(0x0000011c), LL(0x077ac647,0x7fdd52c7),LL(0x49bb24e9,0xfc9b8e68),LL(0xe60101c7,0xdcbe3ce9),LL(0xc2ae52f0,0x3c779930),LL(0x85f01602,0xa50df581),LL(0x4a7c2cfe,0x8c89a686),LL(0x52f720dc,0xe2d3b3fd),LL(0x566aecf1,0x1ac6cabd),L_(0x000001e5), + LL(0x9e01d468,0x1a616c59),LL(0x8c145c49,0x1dbffc3d),LL(0x2990c86d,0x842bad94),LL(0x7914907c,0xb0b65826),LL(0x8753b549,0x09f19586),LL(0x29d809d0,0x3f813f8e),LL(0x3e155797,0x293bf471),LL(0x87d08f2b,0xc41c49e5),L_(0x000000a9), LL(0x8769b86f,0xd9473ed1),LL(0x7fc8f692,0x7012e2ef),LL(0x5014f2ae,0xe7047394),LL(0x086b300a,0xb63d8e90),LL(0xe77f5c2e,0xf739fb33),LL(0x700eca1b,0x22cfcea2),LL(0x8bf8652d,0x4bb3d357),LL(0xe61f7839,0xba0c3888),L_(0x00000189), + LL(0x1f417baa,0xe42f4734),LL(0xbb740324,0x9909bcd8),LL(0xe45bfed8,0xe9550616),LL(0x77889a7f,0x861f9828),LL(0x446a53b7,0xc8946a71),LL(0xfbe6cdbf,0x72916502),LL(0x70373dcf,0x59c8ba5f),LL(0x1ab59a0e,0x07606ee3),L_(0x000000ed), LL(0x7cf7e716,0xfa3f237a),LL(0xb5ddd50e,0x0f211f61),LL(0x56f3a63a,0x8319e664),LL(0x3124dae6,0xe5acc6a3),LL(0xf2c7d090,0x5d6c5fe3),LL(0x5cc8df62,0xa0165f43),LL(0x20f4229f,0x5adf8ff4),LL(0x2e9c92c9,0xd951affc),L_(0x00000003), + LL(0x28c3778e,0x85b95034),LL(0xdf5cb44e,0xffda53ce),LL(0x976139f3,0x126f8dfa),LL(0xe003499a,0x25a0d493),LL(0xb521d994,0x43bb5822),LL(0x4978624a,0x1b4bdd9b),LL(0xf19f8465,0xb8e6e89b),LL(0x51953414,0x3b559f26),L_(0x00000070), LL(0xb01bfe66,0x67904448),LL(0x23ee72a6,0x7f3ba24c),LL(0xefa5df96,0x4a910e6e),LL(0x2d36ae87,0xbee250f2),LL(0xa3310ea5,0xbebd708e),LL(0x5db14894,0x94f849b9),LL(0x7b2cb1b7,0x830487c0),LL(0xd8532e27,0x72d6bdee),L_(0x000001cc), + LL(0x1a632371,0x098e856f),LL(0xcfb4864e,0x2a48dc38),LL(0xa9b6c8ef,0x070c9954),LL(0xc3e565ee,0x47d25c31),LL(0xeec5d7b2,0xdd383653),LL(0x5ac0ce45,0x1f5f3381),LL(0xd40035f3,0x486c7281),LL(0xb516fd77,0x5bbe546e),L_(0x00000014), LL(0x9535f589,0x0df8a00f),LL(0x3f432f2f,0x740ff679),LL(0xa22b5ed0,0xff907935),LL(0x3d446e71,0xd013a668),LL(0xeeee1f6e,0x16c4dc5f),LL(0x37116783,0x8ed6e49d),LL(0x07fabe84,0xd710493c),LL(0x29dbccd8,0x9263e99e),L_(0x00000193), + LL(0x1f79b2df,0x906df6cd),LL(0x835e52c6,0x8a2f7445),LL(0x66d4156a,0xb891e801),LL(0xaa5c0324,0x852e9f5b),LL(0xd3f81a7a,0xce23b51a),LL(0xcdc49377,0xe9c8bbe9),LL(0x7da33db2,0xd5ae561f),LL(0x90aafd3d,0x2f82d67e),L_(0x00000046), LL(0x0d755e30,0xd53059fe),LL(0x43cd9246,0xca05f22d),LL(0x0c50a7ad,0x23745904),LL(0x612405ce,0x1e2b644e),LL(0x1783439c,0xbb5598f4),LL(0x8299ab36,0xfdba24f0),LL(0x36c6a428,0x085bc781),LL(0x42e84aa9,0xe954acbf),L_(0x00000123), + LL(0xb7caf2a5,0xeb9123d0),LL(0x9813e058,0x170c410c),LL(0xb14ecd8d,0x43a445ef),LL(0x12caafb5,0xb13251ba),LL(0x692c7666,0x6a58ee44),LL(0x93734f73,0x1ecf9f41),LL(0x0ff39b6d,0x582e2c3a),LL(0xdd49d16c,0xbc874e11),L_(0x00000054), LL(0x2f1debe5,0x9986c142),LL(0xbe161bed,0xadb85be6),LL(0x94c11992,0x974392b1),LL(0x4727d02a,0x1355dd0b),LL(0x9ef84fdc,0x001779ff),LL(0xdbbcd1c3,0x09218dc1),LL(0x615360f7,0xce2bff57),LL(0xa1cd90ce,0x5b2b4772),L_(0x00000008), + LL(0x3b91b808,0x797035ff),LL(0x63db3368,0x2ea4d5db),LL(0xd58aac93,0x5c1f4e24),LL(0xf46d30bc,0x87b8b188),LL(0xfe246192,0x177c783a),LL(0x2b7ec253,0x7157d89d),LL(0x93dd18f3,0x609635a4),LL(0xebb06e2d,0x9bb84085),L_(0x00000182), LL(0x7977b4f8,0x5291bba2),LL(0x68aae159,0xd5d8d4a8),LL(0xc3c56f74,0x8f01b0f8),LL(0xd20ce087,0x0018bf4f),LL(0xcf62fd4a,0x58c66e12),LL(0xe583beb9,0xcba992f3),LL(0x7c22cd07,0x82ea861b),LL(0xffb459bf,0x757b22f8),L_(0x0000010c), + LL(0xc9b1cbb9,0xf9bac8ff),LL(0xbeb1c7a5,0x70f6e41f),LL(0x32bb744d,0x1f50a7aa),LL(0x2a66377a,0x611c61b4),LL(0x324a6008,0x1ce936f3),LL(0xc3dc201c,0xc5bca084),LL(0xb70db700,0x47988c82),LL(0xfef0caf3,0x2dfe3675),L_(0x0000005e), LL(0xe9f94248,0x76fee427),LL(0x165d8d1c,0x937f269a),LL(0xdc1fbe1e,0xdfee35cc),LL(0x745db180,0x5475d4c9),LL(0xefc6cdb5,0xb36d0a2f),LL(0x26ccd4e8,0xf7ab4767),LL(0x3783e580,0x31ff3c1f),LL(0xce5d079b,0xed18ab19),L_(0x0000009c), + LL(0x0e0b8581,0x231ac4a1),LL(0x0790eab4,0xec50bbe6),LL(0xde5da610,0xc5c0bffc),LL(0xc2382715,0xd201e1fa),LL(0xaac50e22,0x27c0dbe5),LL(0xd06ae9b5,0x8715ddc4),LL(0x77f1683f,0x592ddcce),LL(0x410624c0,0xffb7a12c),L_(0x00000167), LL(0x73c64862,0xf76139b5),LL(0xf8b9348f,0x29844cbe),LL(0x30deae53,0x941fdd94),LL(0x5f88797a,0xa3612765),LL(0xbbb4a54a,0x8e2ccc8e),LL(0x4a469e09,0x47a174f2),LL(0xe17602e5,0xc6f2b50b),LL(0x5edc6700,0x887e7ea0),L_(0x000000bb), + LL(0xffa11839,0x350806a0),LL(0x8c8ad937,0xbc207b36),LL(0x45322006,0xf3feb2a7),LL(0x29b356ce,0x9772041b),LL(0x4db4360d,0x71532653),LL(0xffd40033,0x62b4c3a4),LL(0x525bb0cb,0xef8cba94),LL(0xb23dfc1a,0x5f95e7e7),L_(0x0000003c), LL(0xaafe7a77,0x3a9f0d5f),LL(0x05623688,0xe7ca479f),LL(0xe0f2e02f,0x821e669e),LL(0xd9320a75,0x3208dc12),LL(0x2a90f1fc,0xac95bd4d),LL(0xb836d5d0,0x0f15127a),LL(0xa56f1f5b,0x35a8c806),LL(0x4b53533b,0xb5d6ee48),L_(0x0000001d), +}, +/* digit=80 base_pwr=2^400 */ +{ + LL(0x321cc486,0xb1b291af),LL(0x63480c29,0x6afae0d2),LL(0xec906027,0xd90afac7),LL(0x067489d0,0x62d3da37),LL(0xe31b78ec,0xd88f38b3),LL(0xff5fafe7,0x3dfa7f35),LL(0x88536101,0x7a6237d7),LL(0x80270f89,0x42a2eac9),L_(0x0000002a), LL(0x69198d03,0x95b6527c),LL(0x38b21960,0xab3e28c0),LL(0x56c8573a,0x49dbf002),LL(0xb06c2993,0x016fc238),LL(0xc550c59c,0x7c26c63d),LL(0x22cb4395,0xd6c87128),LL(0x4a5765b7,0x42f34ea4),LL(0x360be87f,0x9436ed50),L_(0x0000001a), + LL(0x92004107,0xcf6c0f3c),LL(0x23b6d0c7,0x01323c15),LL(0xb2a524b7,0x445c4f05),LL(0xfb280e1d,0xb721bd24),LL(0x43a450cf,0x34d74f50),LL(0x459a3690,0x9ed3c3ca),LL(0xf8a99776,0x9bd35cd1),LL(0xaf456934,0xa1b94559),L_(0x000001a7), LL(0xda50d868,0xc7479e9f),LL(0x93e5dd5a,0xfdaf1391),LL(0xfcfc382f,0x727251e2),LL(0x4776e937,0x9f976e0e),LL(0xfaf93681,0x7e0dea37),LL(0x18ec38c9,0x45662b32),LL(0x0308bb26,0xd581e3f2),LL(0x1a441534,0xc275dc07),L_(0x00000046), + LL(0xe20ed2c8,0x9bcb5968),LL(0x702c5bb8,0xdfb47a52),LL(0x33f897ad,0xe16c51a7),LL(0x078f030c,0x5e8bc092),LL(0xb9a4c194,0xa0a224a9),LL(0x0d2a2dbe,0x244c74fb),LL(0x00b01506,0xef3b3eda),LL(0xf4403180,0x44f09c72),L_(0x000000d5), LL(0xc261b7e8,0x4a7f0289),LL(0x3c0211ff,0x88323d80),LL(0x1ffe93b1,0x81a127a4),LL(0x7deb5031,0x0bd65111),LL(0x65ffd296,0xff238b15),LL(0x80cef133,0x643d7062),LL(0xddb33d18,0x93ccc6e4),LL(0xc957a463,0x1fcc4678),L_(0x0000011d), + LL(0x7eb6c9cf,0x1ccb1806),LL(0xe0e23232,0x5eae4904),LL(0xc2c362eb,0xda675b34),LL(0x2c14f20a,0x13d2fa91),LL(0x60f4ae95,0x6c8c7ff9),LL(0x78df2064,0x6790ea32),LL(0xb702cc14,0x7608da34),LL(0xe2b87bb5,0xadae0fb9),L_(0x0000011f), LL(0x0ca7a84d,0xa26a843b),LL(0xc89f77d5,0x5a368ffa),LL(0x265d14c3,0x957c89a9),LL(0xbd1486e7,0x514b7e05),LL(0xa9030ef9,0x537cf3d5),LL(0xb9ea3998,0x4fb32008),LL(0x0c45cfba,0x61ff9565),LL(0x078d5a15,0x1cc6a564),L_(0x000001c0), + LL(0xa9ac7ecf,0x665bb52e),LL(0xf7ce0ec3,0x69d2fe28),LL(0x4c059fd5,0x76b354dc),LL(0x1290e892,0x674b639e),LL(0x6d828313,0x951c9220),LL(0xd6285250,0xee815fd8),LL(0x3a0ba16e,0x8ee38518),LL(0x5323ff40,0x6678fced),L_(0x00000073), LL(0xba67d240,0x73a8b28d),LL(0xba84ecb6,0xbd048216),LL(0x34998afb,0xfb264967),LL(0xfcd4e06c,0xc024c958),LL(0xd668c764,0x9c3e07fd),LL(0xee500455,0x0ea9e902),LL(0x7be48424,0xdf78504c),LL(0xb185d1cb,0xc315ffe9),L_(0x0000001f), + LL(0xd554604f,0xdb3f67e6),LL(0xdbdf25d6,0x23503a7e),LL(0x4a86faf8,0x58cbd82a),LL(0x727561d4,0x50ad1fb2),LL(0x0994b8fd,0x1d57e2f0),LL(0x1b2b4725,0x15736a57),LL(0x5dcba3cd,0x4df58192),LL(0xec335163,0xf716e579),L_(0x00000190), LL(0xfd15e62f,0x3615c741),LL(0xe4509eb4,0xef754782),LL(0xbb1dede8,0x7a793f6d),LL(0xa02e32d8,0x27d972fe),LL(0x00b65ecb,0xd0af4ace),LL(0x80ede0c9,0x96816659),LL(0x6c809dcb,0x979a653f),LL(0x943f6f1f,0x0638c8e6),L_(0x000001a7), + LL(0x69a82f95,0xc3695735),LL(0x79907894,0x6a94274c),LL(0x923a4f54,0xa698895f),LL(0x6213c148,0x57afe3d1),LL(0x14eca3c3,0x40597be1),LL(0x57638ac1,0x23258bde),LL(0xb1f30c4d,0xb9d09cea),LL(0xe2c1e648,0x544e3974),L_(0x0000015b), LL(0x2d296b84,0x28a45f39),LL(0x0111ad40,0xbe28f874),LL(0xc3e262fd,0x830a9ee4),LL(0xe3cc3453,0x0fdaa4f4),LL(0x044defae,0xcdb8b9c8),LL(0x06665f64,0x4a06827b),LL(0xb0bfa5e9,0x926f3364),LL(0xaf288ab3,0xd9d3c3ec),L_(0x0000015c), + LL(0xf210670e,0x5eb181f2),LL(0x047db30c,0xbb73f9ac),LL(0xf0b9977a,0xc5355db3),LL(0xa26685fe,0xa356655d),LL(0x48c1a2cb,0x950bb7fd),LL(0xc2c2dc45,0xe766094a),LL(0x437ff8a8,0x80146ca2),LL(0x0b26425d,0x5b7aafe5),L_(0x00000121), LL(0x7260e44b,0x1c8a54b7),LL(0x683c3c46,0xee244200),LL(0x806c758f,0xb90af5d8),LL(0x71dee02f,0x67ac6f65),LL(0x53aeab51,0x0f1dfed2),LL(0x762d7338,0x59bf51fc),LL(0x059d5565,0x1432973f),LL(0xa9143049,0xbf133e93),L_(0x0000017e), + LL(0x355d9c01,0xa86b08e9),LL(0x4f81ab77,0x4d06707c),LL(0x8f1bf925,0xaaec66fa),LL(0x4de91bfe,0x49683907),LL(0xb9d75b89,0xac105bac),LL(0x91f21593,0x6506b77d),LL(0xab4390d7,0x7287e5ee),LL(0x7487ed45,0x6c88b2c6),L_(0x000001c1), LL(0xd0ceccec,0x11c071b8),LL(0x97c81ddb,0x1bbbfe37),LL(0xd3ad9501,0x7a1b3885),LL(0x68eaad09,0x7027528c),LL(0xf0a64aef,0xcf860284),LL(0x3c25fb62,0x37b3f120),LL(0x5ae492f1,0xd454de89),LL(0x61c7d5ed,0x02ac32db),L_(0x000001a3), + LL(0x3afa7fde,0x245c4af0),LL(0x97406073,0x02c143ac),LL(0xda94e70d,0x1c3ce7f2),LL(0x639942c8,0x9cde176b),LL(0x7bd79b38,0x0883b19a),LL(0xac9d2c91,0xb4709f2a),LL(0x4423fc39,0x794a6aaa),LL(0x89d178db,0x2e0aecc8),L_(0x000000c4), LL(0xd62ec51a,0xb872cf73),LL(0xd957093e,0x85b4776d),LL(0x2acbd72e,0x0656f9a4),LL(0xd468fb6e,0xe2017205),LL(0xc79f3d11,0xe6a367a5),LL(0x012b1362,0x73088cac),LL(0x370e3947,0xb86f1933),LL(0x3bdf96c5,0xe8162ca6),L_(0x000000dd), + LL(0x432ab140,0x9b09e656),LL(0xeb6d1849,0x81aa411a),LL(0xaae86725,0xd8ee02c2),LL(0x3008becf,0x574081d1),LL(0x53cb17df,0x37bd5637),LL(0xe3afcfbe,0x116f90cd),LL(0xe91cbaad,0x9a6da94d),LL(0x023933b7,0xbabdb470),L_(0x0000008f), LL(0x7351bde3,0xf3d722e1),LL(0xef4074df,0x2345ac8e),LL(0x1492cda0,0xe92886d5),LL(0x0fa0e7ed,0x31537a63),LL(0x0778badc,0xa8b49a51),LL(0x2034669c,0x85153992),LL(0xace88cb9,0xfd679e52),LL(0x4c6fbbf5,0x48dc5511),L_(0x00000167), + LL(0xe07de72e,0xe7ef2e60),LL(0xcd7037d9,0x52aa0cf6),LL(0x7dc7381f,0x24da2a63),LL(0xc3562613,0x43cb3857),LL(0xfa06da1c,0x5a1b2f21),LL(0xc7806190,0xec8d6d1e),LL(0xf2d57ff1,0x5a0e8065),LL(0x3e9088a1,0xc30f4ccc),L_(0x0000005d), LL(0x5dde7f70,0x5912141f),LL(0x1bc58b8c,0x19ee91c4),LL(0xbf2996d5,0x41d465ca),LL(0xb39d820d,0x281052af),LL(0x890d83a9,0xa8cb9903),LL(0x32dbf7a5,0xbfad3855),LL(0x309c32fb,0x81d1982b),LL(0x44dec521,0xe04b5e8d),L_(0x000000cb), + LL(0xb2b331bb,0xf141f663),LL(0x6c39f9cb,0x458b556c),LL(0xea205dcc,0xb6c66d04),LL(0x96d440e6,0xa0f1a8e6),LL(0xd4e4d37e,0x3d5c97ee),LL(0xd69c9913,0x92914c77),LL(0x12d04cdd,0xb8bb2a33),LL(0xa42c1185,0x2dee2451),L_(0x00000084), LL(0x8f1a5bb3,0xe8feb727),LL(0xf2ee4afa,0xb371de96),LL(0x0f971611,0x605c486d),LL(0x50e27936,0x313e3113),LL(0xdf801ab6,0x7cfe0fbb),LL(0xfbec3f73,0x50864708),LL(0x55057cd2,0x3b426634),LL(0xa56700f5,0xe23875b8),L_(0x000000de), + LL(0xf2c197f3,0x923016ac),LL(0x17eaa1a0,0x28e3f935),LL(0x128b1c02,0xa23b14eb),LL(0x9183c2c0,0x504289c9),LL(0x5ea313d0,0xb5fd0ea2),LL(0x135c854c,0x03f5e8df),LL(0x491bfca7,0xd9abdd7a),LL(0x8b6af733,0x29d5f4e7),L_(0x0000014e), LL(0x535e0af4,0x50113295),LL(0xb89fd770,0x861c50a9),LL(0x6fd08a16,0x1b7e4c60),LL(0xb1a9800a,0xadc9902a),LL(0xbed31f30,0xa5b9d65d),LL(0xc9a0a6d4,0x75c10264),LL(0xe1743115,0xc317e935),LL(0x8c13233d,0xc0c350f5),L_(0x000000d2), + LL(0xbd31c0b0,0xfdaa94e2),LL(0x4ea46af8,0x2200fec9),LL(0x3139256c,0x4f2fd88a),LL(0xb9b83d67,0xe894a212),LL(0x5e6f7bed,0x449c5bc8),LL(0xbeebbe0e,0x1e599f77),LL(0x74fc58a0,0x7f4a9123),LL(0x6073c6cf,0x1a08d5bf),L_(0x00000113), LL(0x2d5f04f1,0xacb45b52),LL(0x06826375,0xbd9c13b3),LL(0xf41e6cac,0xc5b15016),LL(0x79237672,0x2f2bfd3b),LL(0xa99e108a,0x1681dcfd),LL(0x22fd3033,0x224f0276),LL(0xc24a2525,0x05e14660),LL(0xf9a0ff9c,0x09f9360e),L_(0x000001fb), + LL(0x442343fb,0x1e2ff226),LL(0x33f17650,0x597f6cd8),LL(0x95759918,0x5f1a7fb7),LL(0xb518de41,0x316d41dc),LL(0x966644e4,0x829d89c6),LL(0x7775eaca,0xed7a513d),LL(0x9d45da4e,0xdd14ef8a),LL(0x232852aa,0xc016fff6),L_(0x0000002e), LL(0x7b230dd6,0x0791f95c),LL(0x2cc46d0d,0xd4641a73),LL(0x04775f23,0xb9dcdfdd),LL(0xc9bd9d15,0x727ace99),LL(0xaec6f67a,0xa77fe3e5),LL(0xeac1ee2f,0x75b923be),LL(0x8f21d632,0x55852cf0),LL(0xb6658853,0xbe6d4550),L_(0x000000e1), +}, +/* digit=81 base_pwr=2^405 */ +{ + LL(0x51c61dc7,0x2c6e3212),LL(0x0a1fff24,0x4b5a6256),LL(0xa45d5589,0xbc1ece0d),LL(0x852bc8f1,0x655945af),LL(0xf4152e99,0xf81d51a6),LL(0x4573b7d9,0x15c74818),LL(0x69e42e80,0x69dba53f),LL(0x55b2c206,0x96245123),L_(0x0000009f), LL(0x553b866e,0x11c96019),LL(0x8a5146d0,0xc8d9fabe),LL(0x6c8e83c7,0x3fede45c),LL(0x3d5d33f9,0xb87d2fad),LL(0xe1fe306f,0x67a48456),LL(0xf030c243,0x2aa7e6e9),LL(0xb8f59e2c,0x8097392a),LL(0x7ae2ecee,0xdbed7e8f),L_(0x000000e7), + LL(0x1e3892c1,0x8efeaf2d),LL(0x8c7ed96e,0xf3e2fab6),LL(0x3cb959b9,0xfe65989c),LL(0x4cec2e34,0xb397dfd2),LL(0x2a821089,0x95a4f7a7),LL(0x194fcfc2,0xcd183d4d),LL(0x009eac36,0xc2005f34),LL(0x384df54a,0xc4355ce3),L_(0x0000017a), LL(0x52880022,0x6218f15a),LL(0xab158f0c,0xc9db684a),LL(0x919d3c1c,0x22157c5c),LL(0x733c654f,0xa5d7e7c5),LL(0x1bb67f61,0x6dc89cd4),LL(0x0cac1f78,0xf6e74669),LL(0x2b55f183,0xb445fa4f),LL(0x9df41e4c,0x69c4dd42),L_(0x000001a9), + LL(0xcf794718,0xd8d9bdcb),LL(0x3dd4ca53,0x1306c74d),LL(0x1af7d8d5,0x3e680d58),LL(0x9c6b82f0,0x884ca0be),LL(0x0aacdba7,0x5c62e372),LL(0xd633f595,0x1c4cad9a),LL(0xc84d067a,0x54e3c550),LL(0x4fe24eee,0xbe3f67b5),L_(0x0000019d), LL(0xc026b9ed,0xb999b839),LL(0xd75cb7b6,0xa5275bc7),LL(0x5e6b4aa8,0xfaa9f40a),LL(0xe6b156cd,0x1992d1c2),LL(0x16e51f4a,0x0b180928),LL(0x00c94afd,0x6b3427a9),LL(0x0f9d0fb1,0x09eefa51),LL(0x098f98b4,0xd3cae463),L_(0x000000ae), + LL(0xd17fe65d,0x881adc31),LL(0xbb3a93b6,0x8ce1cba5),LL(0xb603dd9e,0x4f5b70c1),LL(0xaed8b0cf,0x5f958dd3),LL(0x5eae2517,0xb70f44e1),LL(0xa5b942f5,0xc526177a),LL(0x02efb949,0xc8dd1153),LL(0x132ba3a2,0xf9288a95),L_(0x00000189), LL(0xede20db4,0xc45972eb),LL(0xbc841aed,0x7853d5b1),LL(0x933a99b8,0x6e1536aa),LL(0x85259727,0x238abf3c),LL(0x05488fa0,0x8485ab11),LL(0x1debe07d,0x6d6f6d52),LL(0xf1ad18f1,0x54637f92),LL(0xdfd3c55a,0xa2b58773),L_(0x00000004), + LL(0xed1c0bc7,0x66d98564),LL(0x72366f09,0x9a3f0f97),LL(0x00008259,0xb1a9b87a),LL(0x33f3b0e5,0xe8074b36),LL(0xd83471a9,0x68f935c3),LL(0x59dc097c,0x5ab59d2f),LL(0x049d3329,0xae3c2a44),LL(0x523ad362,0xd39de2e5),L_(0x000000b0), LL(0x55bdbbc5,0x10a229a9),LL(0xad11b358,0xdcf6cbc9),LL(0x8a7d993d,0x2d5c5b91),LL(0x31b67dc1,0xd2d684f6),LL(0x5dd81c8d,0x29c17938),LL(0xec292f8a,0x2fb94c2a),LL(0xe9c267eb,0x67c899b3),LL(0x31e831bd,0xd72dd6a7),L_(0x00000058), + LL(0x310d60d9,0x37a99dda),LL(0xabc73772,0xb8a9bdaf),LL(0x18907ad9,0xac790211),LL(0xd35c8ab3,0x56550490),LL(0x483d71b5,0x9c473d52),LL(0xaed32863,0x796ddfe4),LL(0xc175ce1c,0x39329661),LL(0xf0af8692,0x3411279a),L_(0x000001f3), LL(0x085548fc,0x2f981ba2),LL(0xe7ed779e,0x25706bd9),LL(0x385062b4,0x8826d6b1),LL(0x50749b03,0x8f92597e),LL(0x4d1f3b1e,0xcc7ec8dc),LL(0x5ffacc7e,0xc4c11580),LL(0x903de537,0x82ed5c34),LL(0x92e3ccb2,0x829a6dc1),L_(0x00000197), + LL(0xc22b2da3,0x8a8271c3),LL(0x46e669a1,0x9bedd70e),LL(0x6dbeb99e,0xe5038aaf),LL(0xc8d58c8e,0xe202e790),LL(0x312f9e8d,0x5eb0a99d),LL(0x2b3b3990,0x6e033ac6),LL(0x8ddb53b5,0xdd9938af),LL(0xcad94c88,0x8fee9f14),L_(0x00000103), LL(0xe8c634af,0x2d18c7f7),LL(0xf6c9ab51,0xddec3950),LL(0xd2e14fab,0x8eb24aaa),LL(0x85f6d87b,0xbff04dfa),LL(0x7d46acbb,0x458d7c7a),LL(0x949d94f0,0x5596e98b),LL(0x60ee6372,0x37137ad5),LL(0x20231d27,0xe0d4f3a2),L_(0x0000006d), + LL(0x95b0fc9d,0x1f851427),LL(0x75a8973a,0xf65e532b),LL(0x125d27c2,0xb7e6ca7e),LL(0x680245ef,0xd37a1c1d),LL(0xc0ac3fa3,0xc8ed8871),LL(0x73ed1f61,0x25a3f922),LL(0x1c0619b1,0xbaaf99bf),LL(0x2fc151e1,0xb9c92ca1),L_(0x0000015f), LL(0x02c28006,0x4cd45f13),LL(0x46eca65c,0x2f16b28a),LL(0x181d940c,0xdae561c3),LL(0xdef08156,0xdb51b5db),LL(0x5aff9fff,0xd7d0f3f0),LL(0x56731470,0x9f642167),LL(0x3e4323b0,0xc5c736fd),LL(0xc2c256f1,0xaf757eba),L_(0x00000046), + LL(0xe3fa203a,0xfc825ff9),LL(0xa28756a7,0x6fc9ac38),LL(0xf07539fe,0x19a8908a),LL(0x89d74956,0xc69dedbb),LL(0x934712d9,0x2aaee4e8),LL(0xbbd47741,0x1053c866),LL(0xda8058c4,0x00b68d70),LL(0xc019bbaf,0xb1236281),L_(0x000000ad), LL(0x7020f123,0xad679598),LL(0xffe5c58c,0x5fe8d191),LL(0xfb4d9415,0x46edaa9c),LL(0x44747329,0xdd0f1cc6),LL(0x34e406e5,0x79f7cddc),LL(0x40ad1213,0xab39e94c),LL(0x470ac094,0x885cb3a4),LL(0x12891647,0x3224c564),L_(0x00000150), + LL(0x5baed419,0x17473053),LL(0x116c3934,0x97765c7e),LL(0x74d1a056,0xf7e7734d),LL(0x2fb92919,0x22455583),LL(0x880ac302,0xc6198a57),LL(0xc983ea10,0x32d7f501),LL(0x3adab6b9,0xa4c1c306),LL(0x3997a013,0x14822e84),L_(0x000001b6), LL(0x1a3dfcbb,0xf8efc5c2),LL(0x2e766181,0xda380c24),LL(0x158c4baa,0x4d96447c),LL(0x6acaba32,0xe953e90e),LL(0x4ed2e3bf,0x86ffae71),LL(0x452c6d1b,0x3af83523),LL(0x49a52fe9,0x41a86c00),LL(0xec5b4f72,0x9c65d29c),L_(0x0000011d), + LL(0x3e3efd7e,0x15231af9),LL(0x83eb4905,0x29b6e8f6),LL(0x35420b50,0x76561721),LL(0xd8dddbf9,0x83f7c4f4),LL(0x776812d9,0x460a8666),LL(0xd3c1656b,0x6901dcbc),LL(0x22e1e397,0xd9c17a67),LL(0xd83adc99,0x7a32d3cd),L_(0x000000d0), LL(0xe72700dc,0x66102687),LL(0x8578e51e,0x957c6151),LL(0x9a86b387,0xb2bd85fe),LL(0x553c599b,0x21884750),LL(0xb8b8c27a,0x920c65b6),LL(0xf81924dd,0x6f14a6d0),LL(0x28619568,0x18db08c4),LL(0xab2d8a3f,0x11b85385),L_(0x0000015a), + LL(0x880a5659,0x5aa706e4),LL(0x0e7a9fe5,0x2110fcf2),LL(0xa8b2d6f6,0x67bdfcf9),LL(0xeaac5dca,0x0435935d),LL(0x39631926,0x399fbc31),LL(0x60795bd1,0x34625175),LL(0x0f561153,0xced09fb3),LL(0xe23ff49c,0xf1b45cd7),L_(0x00000126), LL(0xb5ed6363,0x4ec88551),LL(0xd20c517f,0x3c8be0dc),LL(0x221ae5ee,0xd895d43a),LL(0x6705afa1,0x00fa5270),LL(0xb373ab4d,0x75678bdf),LL(0x64e2886b,0x47650c25),LL(0x7e0e12f4,0xab5c87d2),LL(0x0c9aec40,0x15ef4537),L_(0x000000e3), + LL(0xfd1186f9,0x69bd1ae9),LL(0xe2ef5aee,0x0585cc2f),LL(0x1e6188c6,0xa3c01465),LL(0x301c46a3,0x1cc1ea41),LL(0xf7f76048,0x16944109),LL(0xedd90482,0xdc473809),LL(0x3da1ef77,0xf7267c80),LL(0xfefdbcd3,0xfd92f40f),L_(0x00000037), LL(0xbd7e42e8,0x365d3aae),LL(0x5f29db47,0x93437f82),LL(0xd2267583,0xf4a57394),LL(0xe0388ea5,0xb28bca60),LL(0x5cea0f68,0xbf640edf),LL(0xc68dbd2f,0x8db4f9b6),LL(0x24be537f,0x9d943d05),LL(0x7704cfe6,0x4a1f249a),L_(0x0000003e), + LL(0xca968ae2,0x15eb727b),LL(0x79b64a1c,0x82dd22e4),LL(0x51a73cb4,0xa1e0df42),LL(0x5140d8ce,0xf6d38530),LL(0xe8523991,0xbf2d199e),LL(0x578593ff,0xaabd945b),LL(0xcfef51c1,0x789ae01d),LL(0x9c35735e,0x685cad78),L_(0x0000015a), LL(0xa7f90d48,0x9ac2d994),LL(0x5bf21520,0x5119208b),LL(0x3671fecc,0x477379bf),LL(0xcfbe3b2b,0xdc4fe9f8),LL(0x98a8aee0,0x6e915903),LL(0xa7edc740,0xc4cb91a1),LL(0x71211193,0x1e307364),LL(0x96026ba1,0x814b8b56),L_(0x000000b1), + LL(0x6b636a3e,0xdfef19d0),LL(0x30a583d8,0x8521445c),LL(0x192a3c38,0x8651795c),LL(0xe24d5be6,0x6cfd9cef),LL(0x273daff4,0x78499d8a),LL(0xbe3d67fc,0xf4d9c05a),LL(0xfff37ca4,0x9d03588e),LL(0xbe977f9e,0x2b3a2963),L_(0x00000043), LL(0x5504ebb6,0x6c46a157),LL(0x146210b3,0x092ba668),LL(0x00fc64e7,0xcfe9730b),LL(0xc41f8e66,0xc11dab42),LL(0x79417f9d,0xff89645e),LL(0xddf57c66,0xd0e35f15),LL(0x98273f3c,0x49f211d9),LL(0xea35684c,0x1b8dcf07),L_(0x000000a4), + LL(0xa5cf0865,0x9d8b99d3),LL(0x7dad9f18,0x96f2ea6f),LL(0x96139562,0xf5d410b4),LL(0x86c29eba,0xc6b1f46d),LL(0x2dbba6d4,0xb1709ad9),LL(0x9de07504,0xeea80cc0),LL(0xc7c9ec95,0x47d01eb6),LL(0x99076486,0x19b1d6cd),L_(0x00000139), LL(0xe61ba7e9,0x0a5f9f34),LL(0x53cc24a0,0x5e367eff),LL(0x672781ea,0x275cfce0),LL(0xedc5266f,0x92d98139),LL(0x0d9e2099,0xc2c0efd5),LL(0xf3d9cb26,0x687bde18),LL(0x647d23fe,0xd97b9ccb),LL(0x0c54a71a,0x258eaff2),L_(0x0000007a), +}, +/* digit=82 base_pwr=2^410 */ +{ + LL(0x99ea3941,0x30cbad8f),LL(0xfa23022a,0x0f3c6cf3),LL(0x9f3a186b,0x33420e3c),LL(0xdc6e922b,0xbffbbdb1),LL(0xeac227c1,0x7aa59cde),LL(0x43d5b878,0xe3673dd9),LL(0x513a5be5,0xae77a5b5),LL(0xbc4c0fef,0x8e4c10fc),L_(0x00000151), LL(0x28229a86,0x2a245057),LL(0x020fe0ed,0x5e8e914b),LL(0x39e8625b,0xdbd2dbf4),LL(0x3dfac893,0x5bf5b95c),LL(0xc2cfde2a,0x29c6d879),LL(0xca30a315,0x05a9a75f),LL(0x3ac05ce9,0x894b84cf),LL(0xb5445553,0xeb87696c),L_(0x000001c2), + LL(0x6bc3c710,0xf9b134fd),LL(0x05a92256,0x23245303),LL(0x7ccfce0b,0x6d8cb621),LL(0xd61ca36a,0x6d0ef54f),LL(0x210c1e23,0x1a182b1b),LL(0x8ae4f253,0xb1f2e2c4),LL(0xa16671b7,0xd29f38da),LL(0xae1cf556,0x3fa6c8ea),L_(0x000001c8), LL(0x7396e499,0xb9a18df6),LL(0xa098406d,0xd588a978),LL(0xd15a5ed3,0x781ea818),LL(0x5e68786d,0xad06fce1),LL(0xf98680c4,0x66d7a550),LL(0x981589bd,0xd3ff4140),LL(0x7ff83976,0x6ffe6dff),LL(0x9c88eabc,0x47479f18),L_(0x00000116), + LL(0x71975c6a,0xdb783254),LL(0xe1b91784,0xcc2bd843),LL(0x7a80b2cc,0xda0b8166),LL(0xaa3b4ff9,0xaff9f442),LL(0x88dcdac5,0x38067551),LL(0x47d782df,0xba990049),LL(0x82a02e17,0x02eb92a1),LL(0x61467fcd,0x29ea45e3),L_(0x0000017b), LL(0x7050f019,0x15b7f2b2),LL(0x3170353b,0x4a58e306),LL(0x4a6890e8,0x0dcaea11),LL(0x2ee85176,0x198b5c45),LL(0x79793d5c,0x9872dd7c),LL(0x5ad3ba16,0x2940cc17),LL(0xacaf46a5,0x9d812262),LL(0xb1cff849,0xee571706),L_(0x0000000f), + LL(0x78fb5075,0xeb0d7e33),LL(0xb0731c42,0x657bac9b),LL(0x5dc372a3,0xd967282a),LL(0xa9374ab3,0xf9ac8856),LL(0xbdf21057,0x3b740967),LL(0xfec8274b,0x56933024),LL(0x5596459a,0x94a16871),LL(0xc8d21c17,0xef7bcfc7),L_(0x00000098), LL(0xb0a89f08,0xf9af7b9a),LL(0xbfd8b660,0x7b728a24),LL(0x9cb13ed9,0xee5e0227),LL(0xa450fd15,0xbd3b7d28),LL(0x972ff1fe,0xf367bf5b),LL(0x08f71ea2,0xaa4191b6),LL(0x496276ed,0x52d016bf),LL(0xc4a6a4c1,0x52e7dadd),L_(0x000000bf), + LL(0x78e99bd7,0x1afab699),LL(0x049e7f00,0x88380090),LL(0xb4090ebe,0xfc780e00),LL(0x9088eeb6,0x294d8c96),LL(0x7d582ac2,0x4027746c),LL(0x5e897916,0xc4fa7517),LL(0x24defc92,0xb30f7062),LL(0x7efacebb,0xe29a1ed9),L_(0x000000b6), LL(0xf3cced8f,0x856dc4c3),LL(0xee3e4e0d,0x6b56aa33),LL(0x971e660f,0xb6b834b0),LL(0xabff8d16,0x4f4e4f36),LL(0x791ab99f,0x1407b72f),LL(0x49828107,0x81293d19),LL(0xdc829510,0x1f2a3c51),LL(0x359122da,0x3bfa8d54),L_(0x000001db), + LL(0x6ad994ce,0xdf15ca96),LL(0x121949d5,0x705e6cb5),LL(0x15f3e1fa,0x844205ea),LL(0xda2168d9,0xb4128cbd),LL(0x793edfff,0x751feb1f),LL(0x332f4e92,0x4c804349),LL(0x4429da30,0x26bc232c),LL(0x8cea38b7,0x753baf61),L_(0x0000013c), LL(0xe7083ee5,0x88e43827),LL(0xb46e7eb4,0x41b7f39b),LL(0xc6fd29ba,0x98261154),LL(0x4974c56e,0x502ce35f),LL(0x0efcc622,0xad5a1de8),LL(0xfd41558a,0xa51d36ff),LL(0x1a681fdd,0xf2ea91c6),LL(0xaa082cc2,0xf7b13d69),L_(0x000000ed), + LL(0x0c38ee14,0xa66a52a8),LL(0x208e5e12,0x9cf1d09b),LL(0xa19a455d,0x4d39c2fb),LL(0xbd4d9e44,0x0adaf826),LL(0xd068570e,0xfd187cbc),LL(0x93225311,0x2398aca7),LL(0x490180a0,0x2dcbb906),LL(0xcee10c1a,0x40723e9c),L_(0x000001fc), LL(0x26d6a477,0x0caf9248),LL(0x7f7fda0a,0x722d1676),LL(0xbe8a621f,0x96407066),LL(0xe524661e,0x3a360a23),LL(0xaa8ac484,0x22dc1578),LL(0x9532f3a1,0x70f20b2b),LL(0x936a98d0,0x4e640ba5),LL(0x10c24716,0xc78e13ef),L_(0x000001ab), + LL(0xc4c781ab,0x8ced176d),LL(0x49979e6d,0x1d8f2f21),LL(0xb3c390a7,0xd1cc9018),LL(0xff49ec42,0x805d407d),LL(0x56592d13,0xb92c79f6),LL(0x69b4fae8,0x7816250a),LL(0xea40b75d,0x9c23c189),LL(0x98e49fbb,0x012080c6),L_(0x00000030), LL(0xf3d27ef2,0xde297ec2),LL(0x394adc76,0x39d2e9b4),LL(0x084a2dca,0xa4a3c98c),LL(0xff54162f,0x4df52d9f),LL(0x847a48de,0xa6af6c27),LL(0x9a4d9dcc,0x128a4972),LL(0x96ed3609,0x8323c41b),LL(0x0a200116,0x81fed229),L_(0x0000011e), + LL(0xa657dd9b,0x20d87189),LL(0x08f2635f,0x6ccede28),LL(0x6b5f8018,0xc2a0e842),LL(0x1a1eaa9e,0x09c6bbfb),LL(0x590c83ae,0xba912027),LL(0xb05367b2,0x98c59c39),LL(0x363d5716,0xc607367d),LL(0x2738b72f,0x76fa4bf8),L_(0x00000080), LL(0x7042e613,0x04011fd9),LL(0x6b33299c,0x42860e67),LL(0xfb00a1e0,0x95c30a5c),LL(0xc7ee4546,0xc597748e),LL(0xbb5a242e,0x3ed03861),LL(0xf0e0361f,0x87708c93),LL(0x2149d193,0x7590a638),LL(0x483134f1,0xc66e8a9d),L_(0x00000176), + LL(0xd5f27f39,0x3813f012),LL(0x5ffac9a4,0xc0d4789d),LL(0x3e79348e,0x955e2b14),LL(0xdb2d28b7,0xe25f9f8b),LL(0xc1656e1c,0x6715563b),LL(0xec42f2f4,0x79f7e28f),LL(0x2aead585,0x106b8506),LL(0x201ba118,0x7f8c385c),L_(0x00000033), LL(0x4d129b93,0x0507ebcf),LL(0xa8ba08d5,0x035af551),LL(0x5db82217,0xe87f61ae),LL(0x97aaf3ee,0xeaf13d4a),LL(0x5f02aeda,0x0476d73b),LL(0x05c9a1af,0x8d9103dd),LL(0xbbd0da23,0x4b324ed6),LL(0x4516539b,0x0edd4904),L_(0x000001b2), + LL(0x7ae64cdd,0xfad3e533),LL(0x9fbd42a4,0x2540903f),LL(0xd7649f2b,0xd8fbba0e),LL(0xc6189edd,0x6a06d4e6),LL(0x1ecce6bf,0xcbba2a3b),LL(0x5c61ec36,0xdb49be34),LL(0x447d3062,0xe4b0ad6c),LL(0x49fc7fee,0x1394cdb0),L_(0x0000018e), LL(0x1b4e3c31,0x1172029d),LL(0x30a8e021,0xbd509669),LL(0x6f8f7c76,0x34a06ccf),LL(0x28f39de2,0x1f805a36),LL(0x5b84e8ae,0x95bcde27),LL(0xa9d053ba,0xd196b2b5),LL(0x4777e8cb,0xbc21fa82),LL(0x1bd75421,0x58e2b8c6),L_(0x00000120), + LL(0xf6fda5e4,0x7a23ceea),LL(0x51aba8d2,0x241c7fb7),LL(0x58878762,0x60069d96),LL(0x51c9d281,0x30ade2dd),LL(0x9b631718,0x91c3eb50),LL(0xf909879a,0xca8dcb86),LL(0xee7eb48a,0x9244bc3d),LL(0x3828bf79,0x2a064705),L_(0x00000120), LL(0x2843df98,0xa015f7fc),LL(0x3ba48f85,0x2b6a12f5),LL(0x95ae129c,0x444e10a6),LL(0x8aeddb2a,0xecfba54d),LL(0x0e8bdf6a,0xc7c39b4f),LL(0x0a72c4d1,0x73b3e601),LL(0x5cdfd0f3,0x99b50a0d),LL(0x5168c9e0,0xbed1929d),L_(0x000001c8), + LL(0xac116c7f,0xa9be603a),LL(0xd22b9ef5,0xc53e7872),LL(0x9558bd84,0x154e0475),LL(0x65401d38,0xbb71dcda),LL(0xf42190a1,0x79891c59),LL(0xcce4f8f7,0x3876a596),LL(0x5ec40734,0x91d0b32b),LL(0xef02bcea,0xe2d3dc41),L_(0x00000083), LL(0x290b052f,0x48a15725),LL(0x7ac11538,0xde31cc2a),LL(0x59724de2,0x949e5fc7),LL(0x1c37f0ed,0xc39190ad),LL(0xc058927a,0xb63be947),LL(0x6bda54d7,0x1d0ceb2d),LL(0xcff0cf31,0xac38d621),LL(0x23f872f5,0x04b46672),L_(0x00000119), + LL(0xf8c3ff8b,0x13238feb),LL(0x8c998602,0xca47bfa7),LL(0xebe29b0a,0xe22527b3),LL(0x7f9eebf4,0x127b07f2),LL(0xa6e2939d,0xca0c1812),LL(0x6469e55a,0x65afd9e7),LL(0x46a7771a,0xf84da7e1),LL(0xbd0864a1,0xb5dbfbc9),L_(0x000000c0), LL(0x89796136,0xb3a29f77),LL(0xbf5bf543,0xb2d15c04),LL(0xd9bcacc1,0xb632b37f),LL(0x5041f46d,0x9bed186f),LL(0xb690ffbb,0x4873f91b),LL(0xeebd39f1,0xff2ad723),LL(0x79a50cae,0xd0c46d7f),LL(0x6b3bea02,0x4a5b4d01),L_(0x000000c1), + LL(0x59fc0874,0x0bb28261),LL(0xe9314bb7,0xa04bdd40),LL(0xaab60946,0xe0b7c3f9),LL(0x20cc2e25,0x1e792761),LL(0x60fd58e5,0x7823f278),LL(0x561086d3,0xfa3bf02e),LL(0x7b6170af,0x0390ab9e),LL(0x4a18459c,0x0c346fa4),L_(0x00000089), LL(0x1b1fad83,0xb623e6eb),LL(0xe73d3d7e,0x43490dbf),LL(0xc1f1a1fd,0x49e9e831),LL(0x0a18b7b1,0xe619f992),LL(0x0c6e526d,0xdb9252a1),LL(0x954cd738,0x6a826c49),LL(0x41105a8b,0xddcbb9cf),LL(0xe9217743,0x750efcbf),L_(0x00000193), + LL(0x83ba5b5f,0x90c2c466),LL(0x57128a20,0x1345257c),LL(0xdbf610a8,0xd16c4a33),LL(0xbff009fd,0x8f1d5b65),LL(0xb49af8c7,0xf560ad02),LL(0x0eb8499d,0xfb45ea45),LL(0xa52dc630,0x7e352023),LL(0x8ada8ac5,0x2fd6cb3d),L_(0x000001b7), LL(0x9d102023,0x8f6d7783),LL(0x4a52a42a,0x3f44af1f),LL(0x4175b2fd,0x05fe7f14),LL(0x079ac149,0x1757d0c0),LL(0x475fac70,0x88ae6d1c),LL(0x7bfd9387,0x33f3d56b),LL(0xb7dbf13b,0xcacad131),LL(0xebd1df20,0x8aef62c8),L_(0x00000009), +}, +/* digit=83 base_pwr=2^415 */ +{ + LL(0xa0c45001,0x96fd03e2),LL(0xf3f782f7,0x0bf4ad5c),LL(0x3ffeae62,0x8514f603),LL(0xe39ca015,0x5633e085),LL(0xa88f4e54,0x94884fbe),LL(0x85fc77f2,0xf605882a),LL(0x2678c646,0xa505f9b1),LL(0x799ba323,0x23217b43),L_(0x00000092), LL(0xf4170bf2,0x032e8744),LL(0x29194f6c,0x6cab181a),LL(0xa932a791,0xf60ec063),LL(0xb94fb0f9,0x217a0ff0),LL(0x8f066aff,0xd03ea56b),LL(0x56ee8b26,0xc1ffed4a),LL(0xefbf8ce2,0xed130515),LL(0x922eb114,0x74474339),L_(0x0000003d), + LL(0xd1837634,0x88affb50),LL(0x5fc7f37a,0x170a0c1c),LL(0xa1f73a2f,0x83474ff9),LL(0xea811929,0x4738ed4f),LL(0xdd78686b,0x24d293dc),LL(0x16188a23,0x36670cd9),LL(0xc585fd52,0xa2e54dbb),LL(0xd3b67188,0x10b37344),L_(0x000000ed), LL(0x6336003d,0xb4548b08),LL(0xfbe0b348,0xad120991),LL(0xef3cdca5,0x034c9a59),LL(0xd16cfcd2,0x56699960),LL(0x10f2524f,0xf6df1f5f),LL(0x4733c5f1,0x98a50032),LL(0x757f84ed,0x2ce4fa9a),LL(0x032f7eec,0xd296f3ba),L_(0x000000e3), + LL(0x5b81d69e,0x4c96fb7e),LL(0x71db44c9,0x7ac3b1c1),LL(0xe9e2107d,0x6305a422),LL(0xa60259b2,0xc0b70492),LL(0x17e1f71b,0x3dedfaf7),LL(0x57f8d178,0x15a8c62d),LL(0x7a704e50,0x81a4724b),LL(0x3b26accf,0xdf992c3c),L_(0x000000a0), LL(0xe21a6ddc,0xe35cce3f),LL(0xc9cc0ded,0xc51c6e93),LL(0x00949cad,0xba4d9081),LL(0x8de8b3c3,0x274926f6),LL(0x839aef68,0xf13d3b8a),LL(0x40a2e3c7,0x90113a91),LL(0xef4e7433,0x1f472807),LL(0x8320657c,0xd4accc1a),L_(0x000001d6), + LL(0xb32007cb,0xc34e9382),LL(0xcd77eae7,0xad7f0d81),LL(0x13604a2d,0xd0e3fde5),LL(0x70443d13,0x6cb59871),LL(0xc5f3e64c,0x7a8441d1),LL(0xadfd909c,0x00532361),LL(0xefba7861,0x0eb9abb4),LL(0x05155907,0xee4fe6fb),L_(0x00000108), LL(0xa4f6cc8a,0x7579200c),LL(0x128ad5ec,0x49006579),LL(0xc2659737,0x8cf2fa39),LL(0xc9df0a7f,0xdb548c37),LL(0x648b652d,0x3da31069),LL(0x075eeef1,0x34916a7e),LL(0x04d0e409,0xea6b7825),LL(0x08fd613b,0xba92eb2c),L_(0x0000015b), + LL(0x3dfeb0af,0x47521ca4),LL(0xc24e86b5,0x555d9a6b),LL(0x572924ea,0x878c09b9),LL(0x379539ca,0xb6b82a15),LL(0x8666f974,0x72ba5827),LL(0x2d9ff656,0xb17ece57),LL(0xc68cfdb5,0xfe917da6),LL(0x22f34e2a,0x08992968),L_(0x00000021), LL(0x174d7bcd,0xf77f07dd),LL(0xba763f11,0xf3886c72),LL(0x11e3d2aa,0xa4c6b62d),LL(0x550a0527,0xe4eac1e4),LL(0x6a7880c8,0x9b86f1e0),LL(0x00ea68f4,0x87cc2f01),LL(0x55e1d3f3,0xa6daef73),LL(0xa5a26f0f,0x2061095b),L_(0x000000d8), + LL(0x4a4107d1,0x8b5ab4da),LL(0xbf85411a,0x7b991f0d),LL(0xa933992a,0xce47a748),LL(0xc820accd,0x662f2eb8),LL(0x12508cc5,0x964b5fdd),LL(0xadddfe6b,0x1358db73),LL(0xf97a44a3,0xfefeacaa),LL(0xf544c5dd,0x3a084f6f),L_(0x00000140), LL(0xec21428a,0xa4ad406f),LL(0x54cddbeb,0xec844e89),LL(0x92a7fe19,0xa4c49f5f),LL(0x30484bff,0x8eb76b96),LL(0xf75a70ec,0x414948f0),LL(0xc139503c,0x7606dff2),LL(0x2fdf031b,0xead62083),LL(0xc5fa11a5,0xf7a1eba7),L_(0x0000007e), + LL(0xe0553aec,0x7ec431d8),LL(0x2ebaaf47,0x3c1a318b),LL(0xd9561acd,0x57cb3287),LL(0xf1f803a4,0x97882cee),LL(0x97ac71c6,0x08071010),LL(0xf26f5efd,0x60ed1a2f),LL(0xe4333f2a,0x76efc905),LL(0xc5d26fd2,0x4101ca9f),L_(0x0000013c), LL(0x3f266f96,0x75779876),LL(0xf709921a,0x294a8042),LL(0x5ab89053,0x0dc515ed),LL(0x5f21558b,0xd5146f68),LL(0x1cdf8e37,0x8dcdaaee),LL(0xe4930f54,0xacb8f4a6),LL(0x58634cb4,0x507294c8),LL(0x20ac12b8,0x38b15ebe),L_(0x000000ba), + LL(0xbdb35346,0x6973a3da),LL(0x5d8f611c,0x3f4e86dd),LL(0x799bf33f,0x749fb625),LL(0x4a326f63,0x667bd358),LL(0xa8161392,0x060fa9fe),LL(0xa3a8de55,0xc4af999e),LL(0xdd75d71a,0x18b1e644),LL(0xc8783194,0xe995c857),L_(0x00000067), LL(0x52eb541b,0x32c7afa5),LL(0x22bb4a07,0x08c59a72),LL(0xc7e0e1a6,0xe1132506),LL(0x1fa09057,0x5c6a1998),LL(0x6b7bf39c,0x41920509),LL(0x8ab7490c,0x462ba7d3),LL(0x9e016ba7,0xdc3595d9),LL(0x1207f474,0x6a3d8c9f),L_(0x00000063), + LL(0xb27c0a7b,0x2b8fd9cd),LL(0x606dd096,0xaea5acbf),LL(0x3ef0fe25,0x4859d96e),LL(0x078a8287,0xf923a972),LL(0x0d66d4df,0x660fec36),LL(0xb27b9ec1,0x102d1cc4),LL(0x1d991f63,0x730fac93),LL(0x0c8cdfad,0x601a8644),L_(0x0000005b), LL(0xb0aea91e,0x55d58869),LL(0x0d313b90,0xde263f83),LL(0x11dbdf4c,0xcde2808c),LL(0x824b53bf,0x6aad6afb),LL(0x94547c69,0x864c21db),LL(0x6771d459,0x65c1681d),LL(0x7f15bc35,0x95681ca9),LL(0xeac68bf9,0x78f00d83),L_(0x000000db), + LL(0xf35f241d,0x2f058d88),LL(0xb2e8d253,0xaca02a59),LL(0x15502597,0xbd7d1caf),LL(0xa0dfb1e8,0x680e361d),LL(0x9355f155,0x2ed31cfd),LL(0xb0064d2b,0x308047c0),LL(0xf348830f,0xbffaf7d4),LL(0x7bb7440f,0x553b98e1),L_(0x0000005a), LL(0xb6375708,0x9f0f6eac),LL(0x25881bc3,0xa7105d49),LL(0xd655e7e9,0x033db883),LL(0xdc82f09a,0x7d5a4975),LL(0xa17847e9,0x4036e619),LL(0xe9b20930,0x048479d0),LL(0x34fdadf8,0xe6c7daa4),LL(0x19412216,0x152f330b),L_(0x000000eb), + LL(0x6fe66f8e,0xc41a7939),LL(0xcb26a326,0x78d31411),LL(0xa365755c,0xd3a391dc),LL(0xe18d1f8e,0x25f34512),LL(0x72a34b02,0x345c60dd),LL(0xd3613f12,0xe2be6e2f),LL(0xee2aebd8,0x116aa632),LL(0x92435b38,0xa7cff2c3),L_(0x000000c9), LL(0x3f4fa083,0x342a1414),LL(0x9da3251e,0x650f3cbb),LL(0x1c4cfe7a,0x93ddee66),LL(0x90734ecc,0x1551811f),LL(0x6d901fe7,0xcc1cef07),LL(0x0c7d5cd4,0x3cf5fe87),LL(0xf0de3068,0x628a5bd8),LL(0x56e883b0,0x077d4d10),L_(0x00000195), + LL(0x8e2db279,0x2d362cca),LL(0xfb4260cc,0x99614b58),LL(0xe2d527b8,0x67cb8aa3),LL(0x08c1f0b4,0xef71b82f),LL(0xc4649ad1,0x4dc68072),LL(0x11a9313c,0x1ac298aa),LL(0x65002fbe,0x9f237961),LL(0xe90bf539,0x537dfdd6),L_(0x0000004b), LL(0xade2b535,0xfcf6c830),LL(0xf2e76469,0x4ed4174a),LL(0x51f1bc5f,0x3a450f7e),LL(0x83c0406c,0xb53708a6),LL(0xaa7dce02,0x2428a6e3),LL(0x44b377b6,0xf1abc0df),LL(0x9c1a58f5,0x0f02c35e),LL(0x27c5458b,0xea8718da),L_(0x00000116), + LL(0xedc91665,0x1709bab6),LL(0xd1568e14,0x5208725a),LL(0x11bb7351,0x3937bb45),LL(0xe6e5c9ed,0x51ec95b9),LL(0xcf7661c1,0x2e23be41),LL(0x6ad385c7,0x743b0e8c),LL(0xe91385d0,0xdfe84bbc),LL(0x6fd97535,0xdce16477),L_(0x000000c9), LL(0xdbe30fec,0xef8587b7),LL(0x0e47600f,0x8f375855),LL(0x6859ef6b,0x529ee446),LL(0xc03de2c7,0x84c625e6),LL(0x6f7cbb53,0x3af54a02),LL(0x29eb9d15,0x37cbf19d),LL(0x750b2d9f,0x2dc61071),LL(0x28f78635,0x6b20c9d0),L_(0x000001cc), + LL(0xc05c59ca,0x78134d37),LL(0x3d575868,0x09f53723),LL(0x6cf5af74,0xfc4fd018),LL(0x39a8ae6d,0xb54df4cc),LL(0xb1d402e8,0x25f3046d),LL(0xeece717b,0x98af312a),LL(0xa13a0c5d,0x5f96c47d),LL(0x7f73d630,0xc80a3e3a),L_(0x00000187), LL(0x516f5d07,0x7f27d5a2),LL(0x38bbf8fa,0xc4360f93),LL(0x2109c7d0,0xe57b26a1),LL(0xeea6004b,0x32aad5ae),LL(0xf9dededa,0x341aa5da),LL(0x6abc8307,0xfdd6b0a1),LL(0x88080bda,0x4cecd6e0),LL(0x1d4fa881,0x24b2b7fe),L_(0x0000015f), + LL(0x923ad134,0x9a724982),LL(0x5ec2d29e,0xa69853d7),LL(0xd1a7ff3b,0x4e7a173c),LL(0xffeab3d8,0x9f30735d),LL(0xdf72352a,0x92186213),LL(0x469f7a55,0x2d184184),LL(0x15c208a0,0x29514acf),LL(0xa37b763a,0x91393991),L_(0x0000015b), LL(0xfb958196,0xa16bd801),LL(0xf0588b07,0xc8dafbba),LL(0xda133516,0x3aebd875),LL(0xf622ae4f,0x34fb368f),LL(0x4f336c4d,0x0b5d9d6e),LL(0xc6eb3519,0xa586248a),LL(0x6d28f06f,0x6daf558c),LL(0x2f3e52a1,0xfb60040b),L_(0x000000b3), + LL(0xd74494af,0x05cc19d6),LL(0x6d31ebaa,0x2f30e929),LL(0x3edd43b0,0xc72cbbb4),LL(0x827c79aa,0x7829df3e),LL(0x4e4cf8d5,0x98bb6262),LL(0xffe745fb,0xad894f05),LL(0x50b350aa,0xb566ef19),LL(0xf2ea5e2d,0x37f6dcf4),L_(0x0000001e), LL(0xe7f3c59f,0xfa34202e),LL(0xd748da48,0x68fd9ed5),LL(0xe1cf505b,0xc7778cb3),LL(0x3af31b86,0xdadb4507),LL(0xfe717fdb,0xb4b6e80b),LL(0x13036b30,0x2c3f1ee4),LL(0x482b138b,0x4fc01593),LL(0x71e1ed1e,0xd788bd27),L_(0x00000084), +}, +/* digit=84 base_pwr=2^420 */ +{ + LL(0x836ce2cd,0x7d9afb73),LL(0x1c085462,0x2eb9d35d),LL(0xacf6649f,0x38a8a9ec),LL(0x095acf4c,0x78be52c0),LL(0xf7d7ea21,0x48f6e06d),LL(0x115ce7bb,0xbedc8285),LL(0x7f232680,0xe51e8f4b),LL(0xd24103a6,0x09aa0bc0),L_(0x000000aa), LL(0x39f42b13,0xe11c4bc5),LL(0xf757159c,0xbc8d09f1),LL(0x0e9e10c0,0xe3621884),LL(0x60d7345b,0x822e5e0a),LL(0xddc802d1,0x6ae792ac),LL(0xf49763d7,0x868a6be0),LL(0xff0f1717,0x7cae1bcd),LL(0x69443786,0x8bfe19f2),L_(0x0000010e), + LL(0xb02326b4,0xe01b8994),LL(0xe496416a,0xa213f31c),LL(0xdc0825ce,0x0281aa93),LL(0xe4450bdf,0x236853f9),LL(0xc8c09e59,0x841e294d),LL(0x595c72a5,0x1e14b03a),LL(0x2bc6e538,0x46b3008c),LL(0xef20b035,0xa57d1874),L_(0x000000ec), LL(0xe5948afb,0x5951a61c),LL(0xd36a1693,0x5b84b925),LL(0x1712f765,0xc1e05016),LL(0xa422f3fd,0xa758020b),LL(0xb022819a,0xb6927405),LL(0xfced2aa8,0x13a79822),LL(0x9ae63d93,0x87cbebb1),LL(0xcdd9c078,0x13e45feb),L_(0x0000005e), + LL(0xe4998422,0xc434f1f7),LL(0x878049fe,0xf0c9ca48),LL(0x692a3fe1,0x277fbbb0),LL(0x7ad48261,0x263dc0fe),LL(0xc6fec032,0x7e09052a),LL(0x04d38aeb,0x37fd6838),LL(0x6c55fb12,0x53925e9d),LL(0x63bce4b4,0xc33e2d82),L_(0x0000016a), LL(0xc6d3730d,0x70a764c5),LL(0x705b2adb,0xb9f1bed9),LL(0x3bab4631,0xb4850149),LL(0x37a14535,0x2385e829),LL(0xcd9ea79c,0x07aa5ebd),LL(0x17e5b5eb,0xd3216565),LL(0x8fb6885f,0xc6b2bd87),LL(0xce87f791,0xd44bfcfc),L_(0x000001ca), + LL(0xda995024,0xd4a7c1bb),LL(0xad86ee95,0xf741fd13),LL(0x1edd6ede,0x85b8fada),LL(0x08912214,0xb65b3c0a),LL(0x30092262,0x3583aac0),LL(0x6716727e,0x817eec2e),LL(0xd6729d8a,0x33bfe296),LL(0xa92ad342,0x779921dc),L_(0x00000006), LL(0x0bc37c31,0xc1373f0b),LL(0x5632a2bf,0x2c2b1683),LL(0xa8cd4f47,0xa4cedeb1),LL(0x32a4b6c9,0x180690c1),LL(0xfa510c76,0x1eca05f9),LL(0x51eb02c4,0x2e0f4e05),LL(0x63213fc5,0xb6165cde),LL(0xd91b429b,0x1fdd188c),L_(0x000000bc), + LL(0x58d599bc,0x52629f76),LL(0x87d39d0d,0x07dbdb1e),LL(0xcaaa9976,0xeb7d6dd2),LL(0x02ffcf23,0x7e0cd30a),LL(0x78d51085,0x83ecd227),LL(0x961e1f15,0x54655c5e),LL(0x8aa70a14,0xf96ec7c6),LL(0x62c8fb1f,0x64d2f55e),L_(0x000001b4), LL(0x0ac79416,0xb6e904d2),LL(0x0bec2602,0xef59ae4f),LL(0x80f6effa,0x330793e6),LL(0x54960688,0x2442ae08),LL(0xff5a5fdb,0xc5e3d773),LL(0xc6ac0199,0xcacfcecb),LL(0x2fa7a795,0xc57e52d1),LL(0xdfd6f9bf,0x2e4eaeaf),L_(0x000000e3), + LL(0xba2a7d7d,0xefeeeccb),LL(0xd77ed0ff,0x9db74ad1),LL(0x5e752d76,0x0b6200a7),LL(0xfc315b24,0x7b48ab8c),LL(0x38ef4859,0x6f975045),LL(0x980da41b,0x09695a2e),LL(0x0010c201,0x0d2b23ac),LL(0x7b7fe53f,0xfe8b4888),L_(0x0000001e), LL(0x8dd021c4,0xc97b952e),LL(0x6b8cb163,0x16bdd26e),LL(0xd62feeed,0x6129cfd5),LL(0x9be7e3db,0xcfa4489e),LL(0xd804ec9d,0x8f551707),LL(0xadb1fbcf,0x055312a2),LL(0x05be2283,0x7d87937c),LL(0x33c9f74b,0xe5edd3be),L_(0x000000d7), + LL(0x46a8f7e5,0x854b2f45),LL(0x223a8078,0x954aed2a),LL(0x155358a6,0x30349ae5),LL(0xae186e4b,0x982c7a2a),LL(0x15564aa5,0x26ca4f64),LL(0xbb73fd2e,0x3fca013a),LL(0x2d10cb06,0x3b01aea9),LL(0x33610496,0xd0f1f68f),L_(0x000001bc), LL(0xf43f1a25,0x7f69aedb),LL(0x1ef2c9b4,0x7e6d3ebe),LL(0x3246ee72,0x1a5a6120),LL(0xfc23f5bd,0x7e829b05),LL(0x02380698,0xfb70444c),LL(0xe903fa23,0xb14cf0d6),LL(0xaba52743,0x7e9872db),LL(0x4a9994d9,0xcbf74f83),L_(0x00000052), + LL(0x0feb8ccb,0x077ea324),LL(0xae770944,0x13db8792),LL(0x1201418e,0xbc07e7f8),LL(0x7f43920c,0xd56c9383),LL(0xa87da3ae,0xf13ae3d2),LL(0xddc44f1d,0x220944b8),LL(0x9328fcaa,0xe3819646),LL(0xeeb928d8,0x3e55f26b),L_(0x00000131), LL(0x1bd80088,0x42ec4f45),LL(0xfe195b7e,0x8b6807bd),LL(0xe12b70e6,0x2b99f5fa),LL(0x7ea15922,0x4e065912),LL(0x9b50760c,0x2efe8690),LL(0xb9b66711,0x16a38c58),LL(0x7b7026cf,0x0ea01a94),LL(0x80737374,0x39639895),L_(0x00000015), + LL(0x5664a574,0x514bdbc0),LL(0xb7081a5f,0xfa8d102a),LL(0x8b95f28e,0xbeeb8bec),LL(0x89435618,0x71f4af84),LL(0xdf609827,0xb479c91f),LL(0x14f1207b,0xcb1fbb1b),LL(0xde646157,0xf9e5fc99),LL(0x7b096333,0x34873e5f),L_(0x0000012f), LL(0x7966170e,0xd78f796f),LL(0x3fa5ab5e,0xa3fca0b1),LL(0xacf76276,0x8003771d),LL(0x1726ca8d,0xe6d96044),LL(0x3e43296d,0x93fa9826),LL(0x42531228,0x527acf14),LL(0x60a72222,0x7a97cba9),LL(0x3d7c6f6c,0x1948eafd),L_(0x0000012b), + LL(0x5463af9c,0x4e12b5af),LL(0x08d068df,0x886cf2ad),LL(0x79260e0d,0x52a61dfd),LL(0x3e9745ee,0x3f586c5d),LL(0xe1f15978,0x566b3b18),LL(0x87842ee1,0x9ad3de40),LL(0xa8f52a76,0xfa06fa9e),LL(0x391add0b,0x9e84e7b8),L_(0x00000042), LL(0x95c6c5aa,0xbb6677c3),LL(0xa05bc623,0x52d3e69c),LL(0xb274df3e,0x974dd07a),LL(0x630e22a1,0x5e6204a2),LL(0xb9a3958d,0x1b227ffa),LL(0xd0e0f634,0x8fc075d7),LL(0x37062afb,0xbe7fbf5c),LL(0x34adc02d,0x77906471),L_(0x0000012f), + LL(0xa73219ef,0x6c9a6028),LL(0x259579a0,0x6f5bb2d1),LL(0x0285a43e,0x154ac0bc),LL(0x167a3f99,0x36795c46),LL(0x728f737d,0xb73fd19e),LL(0x4d08d004,0xa6cc0016),LL(0x85ddb728,0xe72a83f5),LL(0x2e0d295e,0xbfbd9eeb),L_(0x000000f5), LL(0x30d1ecb0,0x90f9c914),LL(0x0eb6be44,0xaf866e12),LL(0xfe01cd22,0x5fd8a835),LL(0x7bf70c61,0x7f0a7679),LL(0x38813f80,0xc8998bdd),LL(0x3833317e,0xb796096b),LL(0xfec3ea9b,0x95f4e76d),LL(0xdad9de4b,0x341f07a8),L_(0x000000d0), + LL(0x9808d4ec,0xd3c33742),LL(0x200fc40a,0xb0a42399),LL(0x130ccf0d,0xcba30b44),LL(0x5e03c03f,0x8e5dcd29),LL(0x6cdd189a,0x1e3d9c12),LL(0x5a30516d,0x81b3e6ac),LL(0x6b10cabc,0xcc86cceb),LL(0x69bda2cd,0xc43e19c0),L_(0x0000003a), LL(0x616887a8,0xdc567bde),LL(0xe0559109,0x6575e24d),LL(0xe2ac30ae,0x67aa07b7),LL(0x2b6c5e32,0xdaf439f7),LL(0x407ff042,0x2ed76986),LL(0x0a686f32,0x1581e9c9),LL(0x5cacfb27,0x18e37622),LL(0xc3e3f9bf,0x387fd7f7),L_(0x000001ce), + LL(0x11961504,0xcd152b7e),LL(0xe1bfaadb,0x9f66edb2),LL(0x2faec2d9,0x65371362),LL(0xe758a385,0x03888c8c),LL(0x70736030,0x84bd514a),LL(0xf31e004a,0x391a903e),LL(0x246ee862,0x36e788ca),LL(0x4e1e02aa,0xf4e00df9),L_(0x00000137), LL(0x6c1152dc,0x13ba50a4),LL(0x4eff7c1a,0x941609eb),LL(0x6d04b057,0x4cf29ce1),LL(0x414be663,0xc8df1ba5),LL(0x12291ebf,0xaa401069),LL(0xeb298db0,0x8ded5bfb),LL(0x893e7d57,0x549bd728),LL(0x01b7b4f4,0xac5af1f1),L_(0x00000045), + LL(0x757b26d3,0x5f6b726e),LL(0xb153c049,0x1a260428),LL(0x30c06c83,0x9ce7c010),LL(0x5b4fc0ff,0x894ae091),LL(0x5657bc21,0x0aae49b6),LL(0x571a85ef,0x79cfa3cb),LL(0x65689c51,0x2187e975),LL(0xe76412d7,0x992bb278),L_(0x00000189), LL(0x11fe345d,0x0cf8c519),LL(0xaa2b60ae,0x9b1824f2),LL(0xc0f1fe55,0x9db0e06e),LL(0xd91bb72b,0xa610996c),LL(0x58e02f73,0xf2c3a8c2),LL(0x28d213dc,0xeae1bfc7),LL(0x13f362dc,0x943517da),LL(0xf7bdbaa1,0x496789e0),L_(0x00000049), + LL(0xb7668d30,0x6c383c56),LL(0x23ca0c67,0x0e7599c4),LL(0x99283769,0xfeb47aad),LL(0xe99af616,0xaf666d85),LL(0xf45b2fa8,0x9231d83a),LL(0x7c7b482a,0x98e9e83d),LL(0x8568ac48,0x1e56ad0b),LL(0xb6b0ac15,0x724bffe2),L_(0x00000169), LL(0x5217d4f7,0xb11260bb),LL(0x877aec8d,0xc03ce819),LL(0x4e72375a,0xccf9f47b),LL(0x54033f3a,0xac8daf52),LL(0x19b599aa,0xdea12842),LL(0x175a56a0,0x7ec2c31e),LL(0x8b550edc,0x1acab966),LL(0xf427902c,0xb52abab5),L_(0x00000147), + LL(0x70bcb2f8,0x52546c7f),LL(0x20270840,0x3c3eb721),LL(0x13f0d6d8,0x142e7b62),LL(0x019eaca7,0xf973a763),LL(0x025efc29,0x8be00c2a),LL(0x6f6199ab,0x03943eca),LL(0xb5618bcc,0xfbfb9ab2),LL(0x5fb02749,0x0ae9ab79),L_(0x0000013c), LL(0x3c3d712e,0x50f295b9),LL(0xab6d0e9f,0x083d8bf1),LL(0xbf53d7cb,0x07076abe),LL(0xf29d744e,0x51a53561),LL(0x5c2fc15a,0x7d647b91),LL(0x253f8428,0x51a29ead),LL(0x91bd9d62,0x006b7bce),LL(0xe106dd74,0xc770e4ef),L_(0x00000092), +}, +/* digit=85 base_pwr=2^425 */ +{ + LL(0x4d5c812f,0x412703ae),LL(0xe95afaa3,0xeb61e427),LL(0x271961d1,0x509a4412),LL(0xcf60fb71,0xef04644e),LL(0xd64abf7b,0xf44d4556),LL(0xfd03e651,0x9b052a7b),LL(0x4add4bdd,0xbb2156b9),LL(0x2a438d74,0x6c6c1657),L_(0x000001a3), LL(0x6be29111,0x0eae16f9),LL(0xafa2d73a,0x44951d52),LL(0x5bc81a5a,0x324d90b4),LL(0x8490fc89,0xcab36337),LL(0x7db83818,0xdcb411d8),LL(0xd6cb710a,0x80af21f7),LL(0xad265214,0xf370ca06),LL(0x3194a666,0xd8bc966e),L_(0x00000175), + LL(0xed0cc632,0xbbdc15d0),LL(0x35b540e1,0x979e91ce),LL(0x973de7aa,0x745fa684),LL(0x84d5e965,0x999e957c),LL(0x2675f78a,0x671ead70),LL(0xec63eb2b,0x9f4e2bee),LL(0x2262a934,0xa151a2d6),LL(0x885b027f,0x5a633743),L_(0x000001b4), LL(0xcbfe121a,0x63ade9fd),LL(0x64a13f40,0x23957199),LL(0xea6e576b,0x21e1e294),LL(0x1a39fa20,0x3e8e8d0c),LL(0xeb1db8f9,0x2627a8aa),LL(0xa239f73f,0x4ba11c83),LL(0xdc2704f3,0xe1591a19),LL(0x6d53062b,0x75cd2132),L_(0x000000c9), + LL(0x2f5961b0,0x615287cf),LL(0x9beb6f84,0x5201fcef),LL(0xa7eaedc7,0xabd8969f),LL(0x485d39df,0x52116284),LL(0x9a298f42,0xc2945b41),LL(0xb98d985b,0x02540f03),LL(0xbe292f99,0xfb5c8297),LL(0x927d1f59,0x379bfc25),L_(0x0000002d), LL(0x2527211f,0xbd1179af),LL(0x24128932,0x49c7ff27),LL(0x920719e9,0x1ce441c4),LL(0x7bdf184c,0xd4d77a7c),LL(0xd00ec091,0x286d6826),LL(0x3901be8d,0x8de5125b),LL(0x6d7da5fd,0x7b71c09c),LL(0x0a84f058,0xd13d8a20),L_(0x000000cb), + LL(0xfe1ac328,0x4047691d),LL(0xb25141cf,0x9109a95b),LL(0xcb8b02c5,0x46b0d286),LL(0x43ceb570,0xb7de8163),LL(0x45b33ca8,0xd109a4f7),LL(0xe4de2617,0xfe1ebf34),LL(0x50869270,0x1ca61709),LL(0xd0a3a1b0,0x38634a9a),L_(0x0000012e), LL(0x9fbe1e8e,0x38f07910),LL(0xce15260c,0xc1bab71b),LL(0x59aca1ef,0x5da68584),LL(0x8166c7ad,0x0bec54d9),LL(0x8f461203,0x49a9c32e),LL(0xd88a5170,0xefea1154),LL(0xbe8180a7,0xec5ede1e),LL(0xad08abc6,0xe0d26459),L_(0x0000017d), + LL(0x40dfaf92,0x75d35af0),LL(0xc6d5609c,0x78abf2cc),LL(0xe0503dac,0x06b14f6b),LL(0x2edd7321,0x1d8b929f),LL(0xf2198c61,0xae13548d),LL(0x510cab55,0x7dda7de6),LL(0xd681dc83,0x9c5b80c7),LL(0xf75528c0,0x3789ecc5),L_(0x00000012), LL(0xf941d11e,0x96096d94),LL(0x43aa0894,0xc108e7c3),LL(0x6b10f225,0x662c2a13),LL(0x6a846090,0xfd5f03e1),LL(0x2ef6dd38,0x6481ee80),LL(0x5be580e2,0x5fdbc53d),LL(0xa958cf09,0x11a46f11),LL(0xc02fca90,0x664e67d4),L_(0x00000194), + LL(0x9ae3c944,0x2e504292),LL(0xd30defda,0x0fa7d618),LL(0xea344a1b,0x8b5c684d),LL(0x88f031e8,0xc536e574),LL(0x4b824800,0x3cbde674),LL(0xad6b63cc,0x56514289),LL(0x9617ab5d,0x85b3cf5e),LL(0x7dc3ec36,0x7fc09058),L_(0x000001b6), LL(0x555deeda,0x846008dd),LL(0x6898fae8,0x9e7f0e84),LL(0xd8281d5a,0x10825f5c),LL(0x2d75ee2c,0x12dbdb85),LL(0x7c0aafd5,0x9070014b),LL(0xbf482380,0x9ee025e3),LL(0x0fc3aa99,0x63b81901),LL(0x508f2832,0x84535f01),L_(0x000000f2), + LL(0xc010cf33,0x9b68b1b0),LL(0xc08c3333,0xc47488c1),LL(0xab449170,0xb2a5ff61),LL(0xcf64ef35,0xb9e5f70f),LL(0x7b502c46,0x417cfca7),LL(0x88cbf950,0x1cf7bedc),LL(0xd4ad741c,0xf0d8aab2),LL(0xbcf1b6ad,0xf5a48560),L_(0x000000fe), LL(0xf9b68aec,0x502beb84),LL(0x2cc6cdcb,0x584dda42),LL(0x094da6af,0x129f5a40),LL(0xd42b7286,0x1002d93c),LL(0x5c173674,0x725b278c),LL(0xefa77633,0xd75f98ff),LL(0x791931d8,0x21527308),LL(0x512e096c,0x53d3565e),L_(0x000000de), + LL(0x140932ce,0x00019394),LL(0x62bec3a2,0xa2c579a3),LL(0x5ab884c7,0xa06cf4c6),LL(0x083cab2b,0xe7eda004),LL(0xf5f6cd3e,0xa107bb12),LL(0xe8649e92,0x492e8a0a),LL(0x5a344683,0x91fc3fba),LL(0x8dcfb242,0x94cfd171),L_(0x00000038), LL(0x1d1f30f0,0x03751b1b),LL(0xce223739,0xc2f1043f),LL(0x23da45da,0xf9307b4a),LL(0x3110105d,0x2b6d1b2c),LL(0xb39e6a89,0x2f645131),LL(0xd8e317be,0x90466331),LL(0xb2f395de,0xf1e436a0),LL(0x1cd56345,0x547fe748),L_(0x000001b0), + LL(0x6d41f81e,0x9c18c216),LL(0xfd251565,0x18071963),LL(0xf23633a9,0x005c3056),LL(0x1e0819de,0x46ebbb94),LL(0xb549b1c1,0xb17a6d7d),LL(0x92577078,0x991b825e),LL(0x8f6ca39e,0x98671ca8),LL(0x90ccdc4b,0x393fb1b5),L_(0x00000102), LL(0xcb6f46fe,0x3e2fd629),LL(0x150480ec,0x0aca508b),LL(0xcbfc5f51,0x0864f022),LL(0x14650672,0x3b3979b5),LL(0xbff63c37,0xb97ea4a4),LL(0x3b1cb3cc,0x3ef296ec),LL(0xcb4a6db9,0xff3bd186),LL(0xbd5b637b,0xedab5309),L_(0x00000052), + LL(0x7249f522,0xba62ee82),LL(0xd77204b3,0x77e6a3df),LL(0x710f93b4,0x02f4ab22),LL(0xcbb03368,0x5e0ecd43),LL(0xb189c2ee,0xc2847328),LL(0x9bdf60eb,0x0ebd36bf),LL(0xb67d93ed,0x0c17c388),LL(0x70c2279c,0xe8fdeaec),L_(0x000000d6), LL(0x8f80aff8,0x48b19e4c),LL(0xc3191f20,0x04206c4e),LL(0x8bdfd660,0x9a16a00f),LL(0xac2112af,0x61997c61),LL(0x8ab3667b,0x7b84c760),LL(0x06bdff10,0xf4e1645e),LL(0x607df1e8,0x352d17a0),LL(0xa63979fb,0x83c7eb22),L_(0x0000016b), + LL(0x223ba032,0xe2ef6187),LL(0xe76e649d,0x50e4618d),LL(0x6b987f60,0xc357d1ec),LL(0xad4f8231,0xd4a60be3),LL(0xb315fdb0,0x2eced057),LL(0xa9fb56ad,0x19319996),LL(0xa2da27cf,0x2f11dee2),LL(0x916ddbdc,0x7e40b2e7),L_(0x00000059), LL(0xd93389b7,0xb7a77c12),LL(0xb4cf9881,0x7da427fd),LL(0xcc7a5c06,0x80b0089c),LL(0xdef4d8fc,0x93e7089d),LL(0xe325b955,0x16ead4d1),LL(0xb039b2a1,0x5dfcb305),LL(0x1820d74b,0xe64404b5),LL(0xd5916176,0x6e3b8d75),L_(0x000001ef), + LL(0xf55f7a6b,0xe5919bbd),LL(0xff1cd958,0xef53a31b),LL(0xf4f94077,0x95740f28),LL(0xd731ab60,0xae2285d4),LL(0xa1ecbb47,0x8c0691df),LL(0x258e27d0,0x3a34371a),LL(0x6fcf67a4,0xe81db787),LL(0x31ad117e,0xcd7a8c18),L_(0x00000101), LL(0xc8eb7eab,0x1c27e10f),LL(0x7aa7d331,0x36d353fb),LL(0x484bc381,0x5feb0814),LL(0x14c00e62,0x5a897087),LL(0x4174c50b,0x73330526),LL(0xa9a0af61,0x7d611726),LL(0x60873261,0xca260561),LL(0xe43e2bb4,0x9e169695),L_(0x000001ef), + LL(0xb03b9785,0xb1e778d1),LL(0xe387f978,0x9b9aee5d),LL(0xd76337e3,0x92cf14d1),LL(0xe5ccf490,0x72921fc6),LL(0x5b43aefb,0x65d3e5c1),LL(0x795ec0f9,0x3904e5d3),LL(0xa4928380,0xa5751b73),LL(0xdfd26a4c,0x351de543),L_(0x00000098), LL(0x34b9f259,0x30b62509),LL(0x2b0ddc19,0xf6f4cca7),LL(0xe118ecd8,0xed5b6edf),LL(0x0c9d677b,0x4f5d7b07),LL(0x34b851c9,0x67daaa19),LL(0xade6f3a0,0xf4cef90c),LL(0x4e977f04,0xddf591d7),LL(0xa5a8e05f,0x51707198),L_(0x00000040), + LL(0x3afab893,0x8fe855a9),LL(0x6f37b397,0xfc53c756),LL(0x11e9e126,0x0be45fa0),LL(0x72b050d7,0x0064ab05),LL(0xfc69a454,0x2c4f8ec5),LL(0xe8ca3f9e,0xfd23251a),LL(0x3713bf5d,0xfbba4b98),LL(0xf9f17348,0x022b3ded),L_(0x00000105), LL(0xdf4c7717,0x496ec6da),LL(0x02b42501,0x3666ead7),LL(0xc5995675,0x03f0c9c9),LL(0xfafe4fc1,0x92c23f3c),LL(0x6e5dcc14,0x49d6013c),LL(0xa80274fd,0x6faecdf5),LL(0x3b89a119,0x6951f782),LL(0x04ebafd5,0xe5c75fdf),L_(0x00000059), + LL(0x2477dccc,0x4c63dd71),LL(0xecaaf994,0xdb563551),LL(0xfa0452c4,0x034243a2),LL(0x35dd1a49,0xc1e98b35),LL(0x67ebb1d1,0xd64a14c8),LL(0x65aa32b2,0xa40fe3b8),LL(0xf36b9b35,0x74b94620),LL(0xde048775,0x9c4f81d6),L_(0x000001ff), LL(0x2154a1a5,0x317a309b),LL(0x27e42884,0xea18f52e),LL(0xab7b0d80,0x6a303cb3),LL(0xd883eedd,0x6960a553),LL(0x5fa720c0,0x4a30771c),LL(0xaf1c642d,0x8c3afce3),LL(0x0aea4951,0x5b832460),LL(0x8daa7e14,0x3626a795),L_(0x00000086), + LL(0x084325f9,0x5078f4b7),LL(0xf8bc0fa4,0xf5948727),LL(0x1eb36b7b,0xea0106cf),LL(0xc704268c,0xc80e06d4),LL(0x300186e8,0x5c216323),LL(0x6e94d507,0x72ccb301),LL(0x882e86c3,0x053b8cfd),LL(0x3148a28a,0xd1710019),L_(0x00000143), LL(0x64ae003b,0x24c02876),LL(0x6d8c63b2,0xc0738276),LL(0xb8220989,0xd418521b),LL(0xa59b967c,0x52d761e7),LL(0x601efc41,0x0fa019e4),LL(0x41cb4d7c,0x9d52f11b),LL(0xcac0131d,0xe27a162d),LL(0xaac991e4,0x975ffa76),L_(0x00000189), +}, +/* digit=86 base_pwr=2^430 */ +{ + LL(0x0347ad37,0x53760212),LL(0xe9ad4077,0x52251dd3),LL(0x2f89c76c,0x5957d5e2),LL(0xb5844aaf,0x57c28051),LL(0x630bd361,0x369eb597),LL(0xacac6af3,0x5611a387),LL(0xaad0ef87,0xde2edc32),LL(0x0bccba64,0x731d170b),L_(0x000001f1), LL(0x5f219574,0xc2557f66),LL(0x48e1ee52,0x5f44f645),LL(0x0cf95561,0x64b6036a),LL(0x1e52bf2c,0x89213e75),LL(0x34bd858d,0x15aa570d),LL(0xbf1cb2e7,0xcc205ae3),LL(0xf29e703a,0xfb1911e3),LL(0x98a34a47,0x78616fc4),L_(0x00000095), + LL(0x7ca50557,0x301fc12e),LL(0x91d6adbf,0xdc42e25e),LL(0x587a0d31,0xcecd10d8),LL(0xf88cc8a9,0x8d1b41cc),LL(0x90bd959d,0x33b3f964),LL(0x999c5a51,0x47bee028),LL(0xc3a08825,0xb39f5f74),LL(0xd4fc3438,0x5af39ed4),L_(0x000001a7), LL(0x1f9ad9d9,0xbf02b54c),LL(0x0a29ee5f,0x4f0d6dbd),LL(0x57045bbc,0xe6fde293),LL(0xc7d0fce2,0x040027df),LL(0xcda45a33,0x23be51ff),LL(0x9841c14d,0x6d045486),LL(0x56ff1e33,0xfdc85221),LL(0x5ea634d9,0x619b696b),L_(0x000001ae), + LL(0x3ea82d4d,0xa104ae49),LL(0x5ed4f918,0x7f6fea1f),LL(0xfb0d6721,0xb83838c1),LL(0x99caa790,0xd116daa3),LL(0xc2f1d19e,0xe68d0873),LL(0x105c2468,0x247798a8),LL(0x672f66e0,0x740bca2a),LL(0xe789f0d7,0x86c229b4),L_(0x0000014c), LL(0xc9d1c796,0xd8e83bf0),LL(0x77be9153,0xaa767cd0),LL(0x71074af9,0xb3e46e21),LL(0x17f8ca53,0x7796d98d),LL(0x215b3c92,0xd098831f),LL(0x362429bd,0x0b75e1e5),LL(0x75d41b1b,0xc1e2cba3),LL(0x0101e963,0xbf3622fb),L_(0x000000fe), + LL(0xc6beb7ff,0xb9019f2f),LL(0x646b70de,0x2e533666),LL(0x90a5717d,0xd38f5274),LL(0x7916810f,0x3bb33bad),LL(0xfd952623,0x59b6b88e),LL(0x5dad71c0,0xfe6ed574),LL(0xca300788,0x21a98ac4),LL(0x6ded4a6a,0xeeff5891),L_(0x00000010), LL(0x03a67cf9,0x48da52e8),LL(0x98c1a5fc,0x1901e7d3),LL(0x42b185c0,0xcb2700b0),LL(0xaca4eda6,0xeec867cd),LL(0x0a19ae4e,0x7dcb7e93),LL(0x88471dcc,0x17e010a2),LL(0x198ed175,0xbb36f683),LL(0xbb4e8756,0xf915ed36),L_(0x0000007d), + LL(0x899986a2,0x56948883),LL(0xfd191432,0x519679d8),LL(0xcdcf1fa3,0x35711035),LL(0x87a0e867,0x663b1a45),LL(0x6c52192e,0xd46a0d9f),LL(0xd90e9a02,0x01cece65),LL(0x0dbf88f7,0x5032d5f7),LL(0xd5855448,0xc3ecbbe3),L_(0x00000083), LL(0x7299fb8b,0xda71595b),LL(0x4bb4a8ce,0x6609b74e),LL(0x23abfae6,0x76172b1d),LL(0xc43ff5b4,0xc2d69d21),LL(0x275e500d,0xf9af38b2),LL(0x8ab54bd9,0xe6a2d266),LL(0x983f2f3c,0xb11e43bc),LL(0x0d27f996,0x3ef88279),L_(0x00000141), + LL(0x235721d1,0x9058183f),LL(0xdd40e348,0x8259229c),LL(0x5e67db56,0x8582282f),LL(0xa5fd9ed5,0xea641a1b),LL(0x1a634c9e,0x6d89c3eb),LL(0x44359789,0x3d617332),LL(0xb7458f8e,0x974b6efb),LL(0xb6863988,0xd2857c41),L_(0x0000018e), LL(0x70c629ba,0xd0bd1dc8),LL(0x08757c7c,0x4edda34c),LL(0x5a31fc77,0xfa2bc7b5),LL(0xf6b159cc,0x36e4a532),LL(0x904f6b01,0x603edf4b),LL(0x96a6ebff,0xb699fdb4),LL(0xad76014c,0x888c04c9),LL(0x52da1b11,0x9675ab25),L_(0x00000151), + LL(0xee308f65,0x76cc2e7a),LL(0x23209d8a,0x39ac3634),LL(0x493f6e5e,0x2a49b5d9),LL(0xaac1e790,0x83449f3c),LL(0x85d5aef7,0x919c353b),LL(0x45144182,0x9673a9fe),LL(0xc1d4f2ca,0x9f1f328f),LL(0x8f5eeda5,0xf2216169),L_(0x00000042), LL(0x8673cd02,0x3f509f9a),LL(0x96feece0,0x85e87ba8),LL(0xe9be0b9b,0x186dcdb0),LL(0x7207011b,0x590eaaa1),LL(0x60f3a8d4,0x3aeb9b3f),LL(0xac89f276,0xd21f7163),LL(0xfd4e5813,0x05998e42),LL(0x80b7e4e3,0x38cd8e87),L_(0x00000006), + LL(0x2bd11682,0xc09d95ae),LL(0xd6f73873,0x7cafdfb9),LL(0x27b3bc9e,0x1f14d40f),LL(0x6fc05fa8,0x4eebf4e6),LL(0x4e6b76ed,0x7bb6036a),LL(0x736cb738,0x58e19e3f),LL(0x2277b08a,0xa4986beb),LL(0xbb55c0d7,0x8f830ada),L_(0x000000d1), LL(0x82356bcd,0xb25e59f9),LL(0x9a3ae563,0x18997059),LL(0xd06e16bf,0x7505891e),LL(0x3d688dac,0x76b3eb97),LL(0x10cb084c,0xc6498b2d),LL(0x2d6e8e95,0xafa574af),LL(0x503f71b8,0xc16133ca),LL(0x9966999b,0x6f3443fa),L_(0x000001d7), + LL(0xdbea5491,0xa62c57f7),LL(0x797a0980,0x03e966f7),LL(0x3a33197c,0x5565e857),LL(0x31df23bc,0x1feaa7a8),LL(0x240894a7,0xec48825c),LL(0x8f886413,0x9a2b6b14),LL(0x98c1f268,0x041a9538),LL(0x89254981,0x46c27078),L_(0x000001a7), LL(0x6917dfc0,0x3f850405),LL(0x16453f02,0x5e4fd155),LL(0xb6a3db9b,0xcd6306e4),LL(0xc259c564,0x89b34c35),LL(0x1cbd8b5f,0x7420eabc),LL(0x22f6885a,0xfe106029),LL(0x2bf9ec49,0xaef5fd1c),LL(0x73da5ef8,0x01c0496b),L_(0x000000d0), + LL(0x6be83fa9,0xccf43b6c),LL(0x2b2fd87d,0xb29b9f9b),LL(0x42c15930,0x75dead34),LL(0x8a992ae9,0x93d238f6),LL(0x835b46d8,0x537768fc),LL(0x59b7cdac,0x97a9b4f9),LL(0x8690f7d0,0xe523d489),LL(0xddd3b40f,0x2dcb85bf),L_(0x00000107), LL(0x29e746ab,0x2a6612ff),LL(0xa015a7b6,0xc599e46f),LL(0x72d01eaf,0x9b23b6a1),LL(0xc21d7f10,0xdff644dc),LL(0xac717daa,0x215cc0c4),LL(0x31113eff,0x29fa625d),LL(0x2da218c6,0x3ddc80ac),LL(0x8399eca4,0x5d17f283),L_(0x00000143), + LL(0x0f0161a0,0xfd958a4c),LL(0x656636ff,0x022fd87f),LL(0x77efdadd,0x3a9ac51c),LL(0x96597b30,0x2fbf14ce),LL(0x01364596,0x7d940bec),LL(0x1f7b85dc,0xbde90f3c),LL(0x3116d774,0x40e30d60),LL(0x9289d920,0x52c8b93a),L_(0x000001a8), LL(0x3eba46a9,0x2ebd850f),LL(0xa0eaa3d4,0x590d1f54),LL(0xbe22470c,0x53e4e7c3),LL(0xf88fc1e8,0xd8883aaa),LL(0x7782a946,0xe78d366f),LL(0x567fbeed,0xf47e81a5),LL(0xadd3d4f0,0xb2aaddfe),LL(0x29a661cf,0xa342a4e6),L_(0x00000027), + LL(0xfdf300d6,0x8c9cc5a1),LL(0xe5aa101a,0x329070ed),LL(0x53342a7d,0x852398fa),LL(0x007bb4fe,0x673ceb9c),LL(0xa9431236,0x3c9247b3),LL(0x1cb68268,0x115b1ee5),LL(0x5c07f2ef,0x3f6486b7),LL(0x7183b014,0x1585ec37),L_(0x00000110), LL(0xd84cedcc,0x0680da54),LL(0x9a2e8c00,0xe41a7e56),LL(0xe94c0472,0xb7c713ec),LL(0xf2aa41c1,0x742d18cc),LL(0x3e3162e5,0xedf3c376),LL(0x77417a84,0x57916b99),LL(0x165b44c7,0x246f2e2f),LL(0x1c45d988,0x8287828d),L_(0x0000015c), + LL(0x1ca07749,0xab8f038d),LL(0x27f0c816,0xc4edbd37),LL(0xc8522ec7,0x2f8f0b54),LL(0xe399477b,0x074481dc),LL(0x0fb69890,0xa0499848),LL(0xa5280b6b,0x88cb4213),LL(0x3dff5cd9,0x41c11365),LL(0xe549bd1e,0xea8a3c58),L_(0x000000fa), LL(0x19cc70e2,0x2b200b5c),LL(0x2ec791da,0xb1772087),LL(0xb33233b1,0x9df4451f),LL(0xaa1032a0,0xbaa72f9e),LL(0x645358e3,0xc7982461),LL(0x88b9794b,0xecd3c965),LL(0xcecd6313,0xa2d9359f),LL(0xf7b6ca2d,0x7f382df2),L_(0x000001ce), + LL(0xcb2fcc0b,0x02037c91),LL(0x41a52ada,0x82ddca3f),LL(0x1b403720,0x4b6a1108),LL(0x6acc9873,0x6d306779),LL(0x495190be,0x80fb3f34),LL(0x13ec341a,0x0307762f),LL(0x2ea03fd7,0x422a6d1a),LL(0xfacb4f11,0x014521e4),L_(0x000000f6), LL(0x869fd036,0x0ac6d565),LL(0xb343a25b,0xdead79aa),LL(0xf7c846e5,0x54b1471e),LL(0xccc5d545,0xf9ccfd6a),LL(0x31f5ccd5,0x43e993a3),LL(0x8fc6e767,0x07c79ed2),LL(0xd716a9ab,0x4894cc48),LL(0xae33e7f3,0xd6c5646c),L_(0x0000004f), + LL(0x7a287c20,0x37b15d9b),LL(0xc16b5265,0x43945dbd),LL(0x7a53a14b,0x994df966),LL(0xd272ba24,0xfbfe62a0),LL(0x80e0b451,0xb488717c),LL(0x7153f565,0x22303a33),LL(0x6397afa8,0xc85bf638),LL(0x0216bd4f,0x096b646c),L_(0x00000189), LL(0xf17f6fdf,0xf00721ec),LL(0x500e6e18,0xab5ca93b),LL(0xea2d8a0d,0x06a3b0f0),LL(0x44feaba9,0xf766ff9a),LL(0xea82aa95,0x05be709f),LL(0x0829c7c9,0x36a07ae0),LL(0xa1cfe409,0xc83c032c),LL(0x780ac746,0xde7f9ef0),L_(0x000001db), + LL(0xfdb1c069,0x18f9c015),LL(0x25767d44,0x49d6199f),LL(0x77c536b7,0xb54e847b),LL(0x1af54bfd,0x7979776c),LL(0x0b838623,0x51eefa22),LL(0xdf9bb4a7,0x028f18ac),LL(0xce45beb5,0x7dd86218),LL(0xb930f98a,0x3f055e3a),L_(0x00000102), LL(0x2c7f6a23,0x1df321b7),LL(0xeeb57c14,0x53902659),LL(0x0b2255cf,0xf2a776fd),LL(0x4cc9dbec,0x453cf8ab),LL(0x63e94ee6,0xf2d56478),LL(0x93a4007a,0x027149fe),LL(0x9cf116d0,0xa6376053),LL(0x17dc8184,0xe7465f73),L_(0x0000001d), +}, +/* digit=87 base_pwr=2^435 */ +{ + LL(0x4e8c16e6,0x6ea55f73),LL(0xf042fa2f,0xab1d226e),LL(0xb24c1848,0x6862a1dd),LL(0x413acbe8,0x1f4168e7),LL(0x91408365,0x9d596e07),LL(0x23961d18,0x01b379ca),LL(0x6d536797,0x05ec7b7e),LL(0x13cf35fa,0xd7f6b707),L_(0x00000120), LL(0x4c707b18,0xbc18785b),LL(0x76095f2d,0xa0054386),LL(0xe28a0370,0x50c89610),LL(0xfeeaf09e,0x144bba0b),LL(0x455cf10f,0x34cf6dd7),LL(0xf509d978,0xf94fe722),LL(0x05c279e5,0x8092debb),LL(0xe71244fe,0xb314f061),L_(0x00000153), + LL(0xbfafe94c,0x7f803868),LL(0xeb771971,0x05b4c2dd),LL(0x911e1ad0,0x0df34f87),LL(0x57076f1e,0x9958d5da),LL(0x6f49ecb2,0x55d1ebf6),LL(0x2ca7b49e,0xfcb4f571),LL(0xb2ff1b32,0x42a971c5),LL(0x49f97d3d,0x838bb327),L_(0x00000004), LL(0x789eb651,0xa52e7908),LL(0x86529c3b,0x7ddd9af7),LL(0xe7159473,0x6dd64d51),LL(0x8305400f,0x922bf016),LL(0x21ca4239,0x1db4bbaa),LL(0x8c94ee85,0xafda935d),LL(0x80623440,0x0a576c9c),LL(0xd9110efc,0xd79f58dc),L_(0x00000196), + LL(0x4946a27b,0xe1a7c929),LL(0xeff94575,0x7f265399),LL(0x076c7864,0xdf2046cc),LL(0xfe889ff0,0xe23267f8),LL(0x4b83615e,0x171f661f),LL(0x32637340,0xc3fd3e6c),LL(0x946ccba9,0xafb9463a),LL(0x9deb55e5,0xbdcb574f),L_(0x00000142), LL(0x21b6bfa5,0xd84d6148),LL(0x6362d37c,0xe1724e4e),LL(0x80e307d8,0x2dee8134),LL(0xd661095b,0x596062c6),LL(0xbc1b3be1,0x5779751a),LL(0x36f36543,0xd0be963f),LL(0x7fee02b0,0x75c65486),LL(0xb82030d1,0x72d27424),L_(0x00000046), + LL(0x9df95f7d,0xaeb38ccc),LL(0x49ee6062,0xc1411d18),LL(0x164333de,0xa4a4727a),LL(0x566e81b4,0x74b241dc),LL(0x290aa59c,0x85069fb7),LL(0x2865cb6d,0x28389d32),LL(0xcbd64839,0xce3c8f7e),LL(0x8c909864,0xfef248d2),L_(0x000000c9), LL(0x126259dc,0x4261d435),LL(0xb96bec85,0x62a6f5a6),LL(0x1f509bbc,0xb43f9c90),LL(0xc53ddbc8,0x94118466),LL(0x9ad3885e,0x22a38677),LL(0xd109dd2e,0x60b6db58),LL(0xeef4f2af,0xadf1adca),LL(0xd5bc0cd7,0x0fb47811),L_(0x00000022), + LL(0x04e04d29,0x456d2584),LL(0xca189af8,0x85bb0ebb),LL(0xf9e4ffa5,0x3e647534),LL(0x1136b7ab,0x0e1d213d),LL(0x91ac330c,0x6aa7c7de),LL(0x4345ad0a,0xf0255a49),LL(0xa156a357,0xe3967bfd),LL(0x2bdb3ace,0x8dff208b),L_(0x000001d8), LL(0xa955f611,0xad93b86d),LL(0xff9685e0,0x990e1837),LL(0xd599bc9a,0xa491c185),LL(0x320375e6,0x59cacf47),LL(0x427b05e7,0x03c76cd9),LL(0x9565d0db,0x073ece2e),LL(0x72f50d14,0x2045534c),LL(0x31281552,0xa43a812b),L_(0x00000114), + LL(0xb2b9d580,0x49f1b4d9),LL(0xd4601e45,0xd37e9635),LL(0x5712ad28,0x2c3143dd),LL(0xaf7e19b4,0xc6366f04),LL(0xaa565afd,0xc4b34637),LL(0xc12b452b,0xdd135b2a),LL(0x77fe7f5b,0xfeea8b42),LL(0x9ec6ff31,0x5cdaec8e),L_(0x000000c4), LL(0x8366af15,0x3f781317),LL(0x664c221b,0x652c3e83),LL(0xafac4ecd,0x6da93d03),LL(0xcfa7c466,0x2ceac0d6),LL(0x039d2b65,0xcb1a4cf4),LL(0xa6eb1946,0xa2285c58),LL(0x422c9b53,0x1b4d8367),LL(0xcc7349ed,0x4c55a379),L_(0x000000fa), + LL(0xa9e31a4b,0x85b7a89c),LL(0x1ea7ad0b,0x9f47c4ab),LL(0xe5150449,0x85cda5f6),LL(0xb891dfa1,0xe69386b4),LL(0xd89edbbe,0xf4ac48bb),LL(0x1b2a00ae,0x3c163ff2),LL(0x37bb423a,0x73d0c87f),LL(0x393a234b,0xe80b0fdc),L_(0x000001ac), LL(0x833e5248,0xc52fc82f),LL(0xa9154aa9,0xe56ec070),LL(0xb5b87f0b,0xb996ced1),LL(0x2c118a27,0xbb7f2dff),LL(0x3e0161d2,0x9ee991cd),LL(0x45e9acd1,0xb300f7d4),LL(0xfb934e98,0x20f357aa),LL(0x370589a8,0xfe8af1f8),L_(0x000001b4), + LL(0xac4010e5,0xb59ee173),LL(0x42f467a4,0x41b66fb9),LL(0x5770a301,0x02513df6),LL(0xf1d41988,0x7e0148f2),LL(0xf54abf2c,0xd9a1b6c6),LL(0xbb47b51b,0xfba956f2),LL(0xf5846505,0xb02618f4),LL(0x502a3ddc,0x69ec8c64),L_(0x0000007b), LL(0x3aa9231a,0x194b6953),LL(0x04316d8f,0x8f7bcb08),LL(0x006107c5,0x9f43afd0),LL(0x32f310f2,0xa15ea5dc),LL(0xe2b91ae7,0x3849a363),LL(0x2b4966c6,0x6a457445),LL(0x1d63455b,0xb8835c17),LL(0xcd39b535,0x1ae86f54),L_(0x00000109), + LL(0xdcd0412f,0x413915c5),LL(0xd3aa0f40,0x553e50ff),LL(0xc139c1fd,0x408079ac),LL(0xcaeedf51,0x5702513c),LL(0xf43dc271,0x1c08e5b0),LL(0xf5e1208e,0x48d91655),LL(0x813375b3,0x91b427b6),LL(0x0fa6be8b,0x833896b7),L_(0x000000d0), LL(0xbf42c4ce,0x7c3676f3),LL(0xac9ff585,0x853930b5),LL(0x94c9266b,0xc6b73b6c),LL(0xbc211c89,0x277b6c8b),LL(0x2fc248c5,0x93fd3dec),LL(0xcefb839e,0x4a5c85d3),LL(0x10bf217b,0x2a276f95),LL(0x3a708326,0xc15a4206),L_(0x00000147), + LL(0x614daa59,0x7bde1ec8),LL(0x34c4db4a,0xa70a6f08),LL(0x48a29f6b,0x587d1015),LL(0x49dbe231,0x998c9a20),LL(0x8aceafbb,0xe5eedcf8),LL(0xe6b738f7,0xcab08878),LL(0x9b693ecf,0xb374ede1),LL(0x008dd1dd,0x7a6cd94f),L_(0x000001be), LL(0x16a2f123,0x83bd130c),LL(0xc20757ed,0x17bff343),LL(0x228e06b2,0x1bef19ad),LL(0xc51046a9,0x0e88da5c),LL(0x011b5840,0x70a9f961),LL(0x49ae6f04,0xc6f83f90),LL(0x9d079a03,0x912f072e),LL(0x9a401435,0x0b78fe3f),L_(0x00000149), + LL(0x81fae141,0x20b6a171),LL(0xc0eec582,0x531fdbd5),LL(0x7a0400cc,0xe2cd895a),LL(0x9c308aa1,0xf0bb2d5a),LL(0x08b021d8,0xde68db65),LL(0xad0f2bcd,0xac747060),LL(0x3fd807ea,0xfe64802d),LL(0x8b4648ee,0x38d8773a),L_(0x00000176), LL(0xc5e737e0,0xcb637daf),LL(0x16605703,0xdffc80b5),LL(0x4845eee4,0xd28e60ca),LL(0x57f98d2e,0xdfda4fa3),LL(0xac95f77a,0x0d0b9220),LL(0x05da7201,0x60ec2cb7),LL(0x9a49b6df,0x201396c1),LL(0x611b2a93,0xb535c0ce),L_(0x0000000f), + LL(0xf4245fc8,0x1481fdff),LL(0x68c14a66,0x84edc501),LL(0x764d4d2b,0xbe356501),LL(0x736aaa60,0xe6771588),LL(0x0c40e330,0x5714d50c),LL(0x7b8fe887,0xfbdf2915),LL(0x9215aac4,0x549e25da),LL(0x58b4091b,0x442d2b00),L_(0x000001ad), LL(0xc5841383,0x88ee6a91),LL(0x934568ba,0x307efd84),LL(0x10dd1585,0xcb644b24),LL(0x3219b046,0x2bd376e1),LL(0xef0c68dc,0xdcecc49b),LL(0x56c2d2d1,0xc907f765),LL(0x810f8810,0x052b3ddd),LL(0x1ba20da5,0xc3448a3c),L_(0x0000019e), + LL(0x099d2210,0xb0648b7e),LL(0x193cb76d,0xf7fec768),LL(0xb90f6558,0x86126ace),LL(0x237a7fc7,0x749a6fe8),LL(0x83ab837e,0xb5c3035a),LL(0x3e9ae2d9,0x8de4bf68),LL(0x9c620970,0x0b3fa791),LL(0x8ef69888,0xc5e8388c),L_(0x0000005f), LL(0x8f4a5084,0x892086c5),LL(0xc04ac82e,0xfb491292),LL(0xc0d38a50,0x52d706d1),LL(0x42c8a5e7,0x582ce44e),LL(0xc9853494,0x96312a80),LL(0x04da6643,0x74ef5508),LL(0xbbc8dc30,0x9a8e3322),LL(0xfa669919,0xa1f29644),L_(0x000000d5), + LL(0xf4dadcf3,0x0e084366),LL(0x5cc0a55e,0x7ef0187f),LL(0xa139c3fe,0x49d53f7b),LL(0x5423f2e7,0xd809a727),LL(0x5a94a4ff,0xe2e74f9e),LL(0x541f08d0,0x22541929),LL(0x14dd0793,0x49159841),LL(0xdbf53ad1,0x408f5bb7),L_(0x0000018a), LL(0xdde4d64f,0x1db74ade),LL(0x46e28711,0x3b22deeb),LL(0x1ad3605f,0x8863541b),LL(0x1fe070fc,0xfdd530f5),LL(0x4af47e93,0x7f3d69c0),LL(0xd93cb647,0x6d16f551),LL(0xbc684cde,0x50cd6852),LL(0xb5154a9f,0x16ac0cc2),L_(0x0000009f), + LL(0x78202e6d,0xec5c2c31),LL(0xc90def9a,0xe4b46e4f),LL(0x67d0d316,0x8901b941),LL(0x2bb65bec,0xc96e5167),LL(0xf836eba2,0x096ab2fb),LL(0x996167b5,0x2719f2e6),LL(0xdde8e72c,0x12437287),LL(0x62d48d9a,0xf4ef64e5),L_(0x00000188), LL(0x8698b358,0x91da5b6b),LL(0xa56f46e1,0xc13b6841),LL(0x97107435,0xfbe3e2a6),LL(0xa446c520,0x759315a1),LL(0x0c5bba8d,0x861aec20),LL(0x852f2659,0x775fa0ec),LL(0xfbe06684,0xa91ab0fa),LL(0x03bd8b0d,0x3006d391),L_(0x00000023), + LL(0xcf090898,0x1b6190bc),LL(0xa4a386bf,0x17c47de2),LL(0x95703cbb,0x3bf84891),LL(0x3f013d22,0x12474267),LL(0x6fdb827a,0x0290f2b8),LL(0x50e9b7e1,0x79a8f44e),LL(0xcc658260,0x89a9228e),LL(0xab4d12b5,0x83a119d1),L_(0x000001b6), LL(0x93cc6375,0x2d25950f),LL(0x6b02229a,0x38c46b7a),LL(0xfb0617d5,0x6bc581dc),LL(0x0ce1dd7b,0x6b522d59),LL(0xd0dcdf5b,0x9133e3f5),LL(0x5cce47e7,0xd71f5bdf),LL(0x21b8ecd0,0x17d9aefe),LL(0x7aac21b7,0x7b609025),L_(0x00000188), +}, +/* digit=88 base_pwr=2^440 */ +{ + LL(0x35d8a1ec,0xf89fcba2),LL(0x59a63f98,0x86d07ca3),LL(0xf60025c0,0x590915cb),LL(0x68c18d4e,0x15cc7c3b),LL(0x85575ec9,0x09334801),LL(0xe8d10d82,0x4789511a),LL(0x82704b90,0xdb2e76c0),LL(0xf6a4e997,0xf5824d99),L_(0x000000c3), LL(0x8f32dc9f,0x6953628d),LL(0xa7575550,0x8504400e),LL(0x8537e141,0x609d8295),LL(0xc7b7f7a0,0x5da70118),LL(0xc50379c5,0x79ad1223),LL(0xc936f6ea,0xbde48629),LL(0x4f7f839c,0x1ba01725),LL(0xdff8def6,0x1bef09eb),L_(0x0000015c), + LL(0x5fe3f41c,0xe82eeedc),LL(0x330d665a,0x0753a4f9),LL(0x3f5e64a3,0x9e477096),LL(0xef9e92f3,0x07f9d297),LL(0x388062aa,0xc48c3ddf),LL(0x60ab0df5,0x55e6e61e),LL(0x5a47567e,0x9872a6f9),LL(0x3a66d012,0x425f368c),L_(0x00000153), LL(0xf66ffa47,0x03b7cc7b),LL(0xb2825eba,0xba3cef16),LL(0x90e67535,0x4aec5704),LL(0xcc34aef1,0x511ac67b),LL(0xd95c0e01,0x51002739),LL(0x0f4f3657,0x45e92922),LL(0x465557ab,0x1baabf91),LL(0x0e9abecf,0x8337c976),L_(0x000001e9), + LL(0xd2b325ae,0xa1025751),LL(0x6a01039d,0x28499cde),LL(0x5ba84622,0x47232500),LL(0x4da34907,0x523417ab),LL(0x54b07c1a,0xd3451baf),LL(0x3fa7e4ff,0x7ce5516f),LL(0x2fbff214,0xfc522cc4),LL(0xa33f1b0a,0x95c7010c),L_(0x000000b3), LL(0x5af51c66,0x665ed5f5),LL(0x980e5684,0xd596415b),LL(0xa5a1b30b,0x8834a37b),LL(0xfeebb04e,0xcf282494),LL(0xb29d17be,0x340dc6ce),LL(0x8d5399a5,0xa50f4a86),LL(0x76012bce,0x83faa312),LL(0x4bc769aa,0x6550a065),L_(0x0000018e), + LL(0xf4dbc144,0xec66fa0e),LL(0x134a53f7,0xa7b2871d),LL(0x1ee39cda,0x83070c04),LL(0x9749b3f1,0x6da77991),LL(0x867841c7,0xe916f1eb),LL(0x21e5438a,0xe409b274),LL(0x1b0e12d8,0x3842a6e5),LL(0xde5e08b8,0x74b9e008),L_(0x00000143), LL(0x63a63405,0xfea4cba7),LL(0x08e07acd,0x06789133),LL(0xdb2143a9,0x815c887a),LL(0x85ffe6dd,0xa9d2043c),LL(0xa68d05e2,0xd3ceab79),LL(0x93674d33,0x7a8a9863),LL(0x12ee73ca,0xd54b7afd),LL(0x6403b9bb,0x2eead112),L_(0x00000170), + LL(0x57f80d54,0xfa0b987f),LL(0x67c06145,0xfd55dd43),LL(0x34438e79,0xe8ca9c52),LL(0xfad0f9f8,0x810f12c2),LL(0xa97a7136,0xb3ec5af1),LL(0x3d0eabab,0xb7b58561),LL(0xecb3da01,0x8aadf26a),LL(0xbb015079,0x9cce9cad),L_(0x00000002), LL(0x43839606,0x265a72e5),LL(0xd025e951,0x90e3ddec),LL(0x5b2c9143,0x4955e972),LL(0x05386478,0xdae63ed0),LL(0x60c28f8c,0x4aa5ded8),LL(0x0fb99e77,0xb74c1dd8),LL(0x0f07854b,0x2caae0f2),LL(0x6691581c,0x069f6ba7),L_(0x00000148), + LL(0x6126647d,0xf5f13583),LL(0x8b738df6,0xe91f4420),LL(0x786c7341,0x1ae2188a),LL(0xda384ed9,0x08e3293b),LL(0x19b1a00b,0x9e09af31),LL(0x65267666,0x322f3662),LL(0xd07b9f37,0x764ea40f),LL(0x11ae129d,0xc16a911b),L_(0x00000185), LL(0x95ad18bc,0x59021aec),LL(0xeb3197c7,0x4daed80e),LL(0xdfd4a433,0x606234ad),LL(0xab3ff78d,0xf98a1d73),LL(0x9f90a43f,0x2c9cac66),LL(0x99bed176,0x5e8063cf),LL(0x8f03fcd4,0x50672a22),LL(0xfdb17bf7,0x027e080b),L_(0x00000079), + LL(0xfcf8e230,0x236a647c),LL(0x5dafe047,0x30081d74),LL(0xc3212b4d,0x0f548f13),LL(0x51f94578,0xd885e14f),LL(0x941059a0,0x06ed3092),LL(0x189c478f,0x5042651e),LL(0x7a26e8c7,0xf36b6ee0),LL(0x09a14b52,0x32dfdec0),L_(0x000001a0), LL(0x79eb582d,0xbe8ca673),LL(0x527f0a50,0x4c6beb6f),LL(0xadaba76e,0xfc7fd1fd),LL(0x9909b987,0x47c90091),LL(0x992155a0,0x06d6f45b),LL(0x2da697e0,0x740de37e),LL(0x1a38bcd1,0xce3867f1),LL(0x509b93e8,0x503be8b2),L_(0x00000160), + LL(0x1ab9de21,0xe8c16ca7),LL(0x4d3bbd16,0x519f4d4b),LL(0x53785c45,0x6454947e),LL(0x1aafab77,0xd9b9416f),LL(0x6883b419,0xb337e34e),LL(0x0208ba8a,0x7e584157),LL(0xab67774a,0x5a84d18c),LL(0x108ac516,0x77b69d31),L_(0x000001a9), LL(0x652943fd,0x91e5bcfd),LL(0xcd5e892a,0x5aa27743),LL(0x502744c8,0xa0414bf5),LL(0xe26bb91b,0xbc4ef773),LL(0x8bcd45f8,0x8f9e301b),LL(0x3589038c,0x30d42898),LL(0x9a5f5e5a,0xa609f771),LL(0xaf5c6671,0xade09eb4),L_(0x0000003a), + LL(0x284eb84a,0x775485ec),LL(0xf826fcc0,0xa66e99e3),LL(0xfac7759b,0x6006cfb6),LL(0x13b284ca,0x1fbb2a30),LL(0x53d194ad,0x2c2b6910),LL(0xf54ebb36,0xa49dd337),LL(0x46a6edea,0x8fc79498),LL(0x0d6aff86,0x842dc894),L_(0x000000f6), LL(0x954ada11,0x34121245),LL(0xb4cfd050,0xafb75e83),LL(0xaf8c43b1,0x77a38e5e),LL(0x4ff38619,0xe7485f16),LL(0xfa745e75,0x7e4f2466),LL(0xcdc30bb6,0x009d4a36),LL(0x9994c740,0x25e09cb4),LL(0x66ca76f4,0xf59131dd),L_(0x0000019e), + LL(0x7773c26b,0x6edaa49d),LL(0x0aa308ea,0x7669b865),LL(0x72c7a072,0xf06e514b),LL(0xa7ddba09,0xca616052),LL(0x126487b0,0xd64c8323),LL(0x713cc701,0xb7fd1abe),LL(0x84ce35d3,0x7bfbc16b),LL(0xba894fdd,0xba61b8c2),L_(0x0000009f), LL(0x27a3cc9b,0x18d74478),LL(0xa66248c8,0x62b773bd),LL(0x3c1ca3e3,0xde584f76),LL(0x5c3541fa,0x475ec797),LL(0xe7fdfe89,0xd692c26f),LL(0xe8463461,0xe888fcbd),LL(0x682f9099,0x1a8aba10),LL(0x0ae8eea4,0x2cc79e0c),L_(0x000000cc), + LL(0x2edafeba,0x901772ff),LL(0x6d000499,0x481b7323),LL(0xb7a27eb4,0x69fc5685),LL(0x4a7abcd1,0x47ec07ac),LL(0xcde4a9ac,0x56f5f84a),LL(0x45545bfb,0x6ef7da38),LL(0x33e7eca8,0x2edec324),LL(0xd8a46ddf,0xd29093de),L_(0x00000155), LL(0x94de9831,0x163bac52),LL(0xbeecc923,0x637f0966),LL(0x0af4893a,0x1759af91),LL(0x1d38f097,0xe0aea79f),LL(0xf9d81651,0x8ae541b7),LL(0x510d4c3c,0x32bd0e43),LL(0xd73faaea,0x6891a73c),LL(0x3864a690,0x6feafb02),L_(0x00000019), + LL(0xeacf95da,0xa0c16a35),LL(0xb6681c57,0x415f0571),LL(0xb2c83a60,0xcfe1f331),LL(0x4b9088d9,0x1279d3aa),LL(0x2ab5f2f1,0x29c29c20),LL(0xd47ee149,0x16735420),LL(0xfbb44304,0xb8379216),LL(0x23034403,0x20a6f133),L_(0x000000aa), LL(0xc23990b9,0xe0a94e50),LL(0x38217da2,0x2ba297d2),LL(0x18816b2c,0xe566aa72),LL(0xca63550f,0x1c7b21ca),LL(0xdfe51644,0x10c887fa),LL(0xef849ed8,0x4faeda58),LL(0xb92e8367,0x03636294),LL(0x2414c0ef,0x8476a050),L_(0x000001ab), + LL(0xfd6f68b0,0x93412483),LL(0x9f53d923,0x4403bdcc),LL(0xe30fa97e,0x6c9d0aa5),LL(0x1601e86b,0x9c1a2ec2),LL(0x19610105,0x431d5f14),LL(0x6cc0662b,0xb7bbdb4e),LL(0x84ed40f8,0x266aca0a),LL(0x1b8a27f1,0x198bae2a),L_(0x00000036), LL(0x95509e62,0x33afa5e4),LL(0x023ed8a6,0x8523afba),LL(0x036adaa0,0x83cbabb2),LL(0xf5cebadd,0xac3f99aa),LL(0x20899c44,0xca5f46cf),LL(0x0e94933a,0x7a04e2c1),LL(0x9a3fee46,0xb0015196),LL(0x367a01a4,0x1715a693),L_(0x0000001d), + LL(0xb429b2e7,0xc2d951af),LL(0xd89fbf0d,0x4488a068),LL(0x172ac7ad,0x7772ecaa),LL(0x0409a3f1,0xf7780ac8),LL(0x6d541e69,0x6ffa0a05),LL(0x4e8fccac,0x7509c471),LL(0xeff8ec93,0x018bbf89),LL(0x101b9048,0x2b2d5626),L_(0x00000102), LL(0x4bb1ca6a,0xbd338134),LL(0xda4a1896,0xaeb1aa9a),LL(0xdfd1cb54,0xc0b310a4),LL(0xeea1a455,0xbed91e2c),LL(0xaae7927d,0xd3502cea),LL(0xdfdf4808,0xd31ee1ce),LL(0xecc68f6a,0x893f08dc),LL(0x9350fda5,0x2a6f281d),L_(0x00000114), + LL(0xb4f8335f,0xd5d022dc),LL(0x6e654db2,0xe4aaf49d),LL(0xaa763047,0x24820282),LL(0xfe8aa2dd,0xef229292),LL(0xb7ff78ba,0x0170b38f),LL(0xe0a88558,0x0aca63f0),LL(0x66a526d3,0x97a4873e),LL(0xc069b5d3,0x28c88b56),L_(0x000001f1), LL(0xb3873204,0xa3de237d),LL(0xb57187d4,0x20e27844),LL(0x59762170,0xf8485db5),LL(0xf8fe71f6,0x47186213),LL(0xccceb1f1,0x3ddfa68a),LL(0xe9e1e35a,0x3805a749),LL(0x048090bc,0xeea89d03),LL(0xd04309c8,0x451591c1),L_(0x000001d8), + LL(0xe0dbf609,0x2e8fa162),LL(0x86c08a44,0xb15f83f4),LL(0xd94f9cd2,0x50bb6a89),LL(0x7bbf2a23,0x606cc572),LL(0x74b1325b,0xb03f198a),LL(0x73b79d3a,0xcf731a6f),LL(0xc95046a9,0x298efd11),LL(0x095ed71e,0xd622bb24),L_(0x00000074), LL(0xb59eae12,0x08c383b3),LL(0xb2f19275,0xe14dee81),LL(0x0d888be6,0xce4b12e8),LL(0x213fb612,0x78248f53),LL(0x43092c13,0x4330dbca),LL(0xe40c52b2,0x952b9ef5),LL(0x9d869889,0x31f1126e),LL(0xfbc05f41,0xfd03ae1d),L_(0x00000103), +}, +/* digit=89 base_pwr=2^445 */ +{ + LL(0xbdfd1e31,0x6e868b8b),LL(0x244e266c,0x05a4369e),LL(0x7c7bf40b,0xe296776b),LL(0xaed3b7e1,0x2cfd9c18),LL(0xddbc31e2,0x1ea90d63),LL(0x98abb7bc,0xe50b9291),LL(0x791f36a5,0xc2f87e55),LL(0xfe737c71,0x75c6d8e7),L_(0x0000004f), LL(0xd596ad7c,0xd54c9eb7),LL(0xa0fb486a,0x91d1e1e1),LL(0xd820f02c,0x9160a67f),LL(0xe5d16017,0xf1163f25),LL(0x8b61c557,0xfcbc9a92),LL(0x84ed79f2,0x6a33df9b),LL(0x54ba6955,0xc8febe18),LL(0x43c5cb8a,0xec5a3443),L_(0x000001a7), + LL(0xef36f15e,0xa725a8ec),LL(0x5828c615,0xf603a049),LL(0xac113424,0x87a77e81),LL(0x34642c16,0x761c2762),LL(0x9d0db298,0x29b1a474),LL(0x8ac3391f,0x143a9782),LL(0x050c5b69,0x5ae00925),LL(0xc578b0a2,0x144730ed),L_(0x0000016c), LL(0x4e6437c4,0x3bbfa384),LL(0x606aeb93,0x6e3daf55),LL(0x97e41356,0x4263527e),LL(0x4ac1c1ae,0x3a037893),LL(0x8c336382,0xb2143f58),LL(0x2bb7d997,0x69412726),LL(0x2419935b,0x9cb555c8),LL(0x724eeef9,0x2ef7f7cb),L_(0x000001b8), + LL(0x463c9476,0xf81335ca),LL(0xd6526151,0x999ff056),LL(0x3c494f0f,0x0a7433ca),LL(0x41b82dc1,0x7fa3bcdc),LL(0x9af11e06,0xec803bb3),LL(0x0ac7bb35,0x457b31fc),LL(0xb5e185aa,0xed555915),LL(0x586ab2cb,0x33044819),L_(0x00000097), LL(0x2112108d,0xbfc07b3b),LL(0xae813666,0x4f0a957b),LL(0x8eee1f42,0x82cf0958),LL(0xc3321225,0x4daeb7bd),LL(0x458ec031,0xe4de4e23),LL(0xd0f97884,0xfc50a768),LL(0x1655c201,0xb424f36a),LL(0x14f1a537,0x0cdff481),L_(0x0000006c), + LL(0xf3b637b5,0x22f8cb24),LL(0xf131c203,0x0c2b076a),LL(0x815ccfff,0xf056364e),LL(0xdbdfbdbf,0xc8028853),LL(0x41ab5760,0x8af0ee08),LL(0xca93ac08,0x3094da56),LL(0x30135092,0x5054010d),LL(0x74228a25,0x8e7dde67),L_(0x00000005), LL(0x5c512c3d,0x8a5176aa),LL(0x3779fd86,0xbe16420d),LL(0x7658fb3d,0x41f45c5c),LL(0x110cf130,0x49dea64d),LL(0x19e0e350,0x73f6746e),LL(0x87ca4575,0xfe7da390),LL(0x108ab4e2,0x874c5458),LL(0xe39cce4e,0x1d64965c),L_(0x00000179), + LL(0xb7099c8e,0xfa76cb01),LL(0x80465e82,0x38560d7e),LL(0xf4fd03ea,0xa649c8ff),LL(0x150b3815,0x72398c4a),LL(0xc0e6baed,0x1ba3da88),LL(0xfa79ad8b,0x6f43120b),LL(0x8353fc42,0xbd32e2fe),LL(0x7dbd7876,0x148c548b),L_(0x000001d9), LL(0xea549c25,0x18cf351b),LL(0x9ca7db2a,0x80485f13),LL(0x16240b9e,0xdfdb85c4),LL(0xc2dc15ee,0xbb4121d8),LL(0xcce3d597,0x0e963371),LL(0xafb37db7,0x7c69e287),LL(0xed3b5fd8,0x6c8d52b6),LL(0x608eaea5,0x053f2384),L_(0x00000165), + LL(0x625fe0c4,0xbbf62c47),LL(0x1eac543b,0x11eca801),LL(0x4e45d301,0x682f5663),LL(0x054cb071,0xe9473698),LL(0xf1ad1950,0x860a714e),LL(0xa8a339c8,0x96d39034),LL(0xe04ab8cd,0xde22b09f),LL(0x2a845e02,0xdfec2116),L_(0x000001e6), LL(0xaad333d8,0xeaca7b49),LL(0x3e7c928e,0xb0fcae9a),LL(0xca8b3e2f,0xc41fdaef),LL(0x9529863b,0xe1843977),LL(0xd56a624a,0xee7e83a7),LL(0x3438606a,0x81db821d),LL(0x06cdb198,0x3aa0eeb4),LL(0x9b12775b,0xe0d60750),L_(0x000001da), + LL(0xb1f4b70e,0xbe8e1de1),LL(0x9b0a79d8,0xc345fcdd),LL(0x77d93da0,0xb2f5a213),LL(0x7028f9ce,0x800fcc19),LL(0x1306f2ff,0x469efe59),LL(0x4cd68bf6,0xc5ffe046),LL(0x62b03f93,0x53010575),LL(0x5af4940d,0x46961f0f),L_(0x00000171), LL(0x354ba888,0xad6952b3),LL(0x9045b751,0x43f410dc),LL(0x217ebd7d,0x0d11a22c),LL(0x6ddeefda,0x6d1775a7),LL(0x43965993,0x055c0203),LL(0xe7060f57,0x3548b71e),LL(0xa89da1f0,0x805eb428),LL(0x6f8231a6,0xf7b78a97),L_(0x000000f7), + LL(0xb3368550,0xcf1f7c72),LL(0xe247b483,0x97b6bf76),LL(0x202781dc,0xc0f81747),LL(0x8b65bb58,0x92efba88),LL(0x9611a60c,0xd9612af5),LL(0xaf54a57c,0x20d7ccbe),LL(0xf8689ba5,0x6d3cbf9e),LL(0x0591cc36,0xdc1abfe9),L_(0x00000056), LL(0xcd538940,0xd4a04bec),LL(0x1e600b02,0x2a15021b),LL(0x6c3ebe8f,0x9586be60),LL(0xb8507cfe,0xf4028af5),LL(0x54dda762,0x4d392e89),LL(0x519d3758,0xbde8dadc),LL(0x58c3813e,0x81db641b),LL(0x91557ce6,0x23fa3b99),L_(0x00000063), + LL(0x3b03dea1,0x51bb00fd),LL(0x32b04d9e,0x8aefebe4),LL(0x22b78b18,0x8698b63c),LL(0x7da3c01d,0xa71b8bc0),LL(0x8d71ee46,0x27b7a39c),LL(0xb0583313,0xbd156109),LL(0x49d2846e,0x931258ab),LL(0x86e6af4e,0x3ca87258),L_(0x000000b6), LL(0x429e4df7,0x79f7c689),LL(0x39041060,0x6229b813),LL(0x9028538d,0x3a4aa59f),LL(0x517bfaf7,0x2d1cb542),LL(0x71d33bc2,0x882030de),LL(0x9ba76285,0x91ba5fcd),LL(0x25f86ca8,0x9ae0fc6d),LL(0x47f08f0a,0x3948678f),L_(0x00000089), + LL(0x22c29c44,0xcd9eb593),LL(0x18cd9b8b,0xac677eb2),LL(0x0d8705ef,0x6b203fcc),LL(0x934fa783,0x39fcfd85),LL(0x571b28eb,0x58bd6d8e),LL(0xd8f1d221,0x215fad4b),LL(0x3e44e705,0x827adc24),LL(0x5ff00393,0x1ec35c0f),L_(0x000001ac), LL(0xc588165d,0x14fc0a02),LL(0x5fce2e10,0x71f9384c),LL(0xf0f2ac5b,0x90d699f4),LL(0x7b00891b,0x43b6bcdf),LL(0xe8c4a652,0x7bc04d87),LL(0x0ac9f698,0x2ab126b5),LL(0x3eb3d860,0x849b38d0),LL(0x426d6e94,0xb6985535),L_(0x000000cf), + LL(0xe89608fa,0x0725d65d),LL(0x1183558e,0xb6a14f9d),LL(0x44070253,0x20d9075f),LL(0x6c243902,0x486b1799),LL(0x6c1a9d8a,0xf5efa075),LL(0x8ae5a14e,0x4ea72292),LL(0x2d7b9c93,0x0ca5c12a),LL(0x992cae02,0x91e3345c),L_(0x0000005b), LL(0x306b8949,0xc89bcdf7),LL(0xd10410ec,0x89966bf7),LL(0xcf680bd5,0x6ee731b3),LL(0xa0c3db72,0xe37f14f5),LL(0x2aa5a376,0xf554bdb7),LL(0x23be47dd,0xef1712c3),LL(0x96ab9b1d,0x1c7594e0),LL(0x9ed66d28,0x032ce687),L_(0x0000003d), + LL(0xc8516fe7,0x9e3351dd),LL(0x68d68f89,0x9fb7334d),LL(0x40ebf359,0xc5209aaa),LL(0x120177c0,0xe5d00b75),LL(0x2f0e6bbb,0xbf188e69),LL(0x110d2427,0x8e2e5213),LL(0xd6344a1b,0xdcf577cf),LL(0xa7331f94,0x3c553feb),L_(0x0000013c), LL(0x64f458fb,0x795a2fa2),LL(0x524f4a9f,0x6609f22b),LL(0x6b23609b,0x2c95b3f8),LL(0x0500bc47,0x8df999a3),LL(0x042c79e9,0x9db59925),LL(0x12a07a8b,0x55be1532),LL(0x07f62419,0x33c89540),LL(0x8df78722,0xfe671ad7),L_(0x00000141), + LL(0xe38c8109,0x18059a16),LL(0x52e9bed4,0x717c36f7),LL(0x49d5e825,0xb56dd6dd),LL(0x7783b6cd,0x667fac4c),LL(0xcf53b558,0x116a1985),LL(0x7c15cf14,0x9913c6ee),LL(0xe08410c5,0x6728a2a4),LL(0x9d771edb,0x331fb13d),L_(0x000000be), LL(0x34b06991,0x394ecd2b),LL(0x8da76d72,0x341e75ff),LL(0xf52f78d6,0x29ea6d71),LL(0x46d211ab,0xaf402bfc),LL(0x386ae83b,0x7e9586dd),LL(0x909f5bf1,0x11c7f555),LL(0x1b8a537f,0x427868fe),LL(0xcf05f9d7,0x32daf130),L_(0x00000055), + LL(0xc5d1aadd,0x4ef2bfbd),LL(0x360e62a2,0xc1081697),LL(0xa6a207aa,0x28d01fdb),LL(0x18abc7ac,0x204fc30b),LL(0xbcff0be1,0xe5cdb570),LL(0x48ef40e1,0x1f0b1c2e),LL(0xeb79790f,0x63136e14),LL(0x3d4fe961,0xb9d45c94),L_(0x00000140), LL(0x79d14142,0xa61088da),LL(0x8938b0fa,0xb39c86bd),LL(0xc33f1d7c,0xa2380177),LL(0x530d6911,0xaab3667d),LL(0x7b52bed9,0xd815d83b),LL(0x5c596749,0x44b95fe0),LL(0x5148c157,0x202c91ff),LL(0x406b7485,0x8bf24d49),L_(0x00000006), + LL(0xf808d1d3,0xd37bc919),LL(0xe29da36d,0x00b56fef),LL(0x7458f713,0x8621718f),LL(0x286883b4,0x448b7c11),LL(0x363d4ba5,0x6114fd6e),LL(0x04011c7c,0x0d4b7500),LL(0xe765f7ee,0x491c6545),LL(0xc2b827eb,0xd01f3320),L_(0x000001f5), LL(0x464d4102,0x6902bd96),LL(0xda599389,0xe2b47365),LL(0xfe7e3528,0xe9079def),LL(0x3aa4556e,0xc96d3bc8),LL(0x610e35fb,0xb585febd),LL(0xa0b2ea82,0x70988a63),LL(0x60d1db4d,0xd27f19aa),LL(0x6eee4c02,0x248d0f40),L_(0x00000073), + LL(0xa17e11d6,0xba327209),LL(0x4da0ba85,0xfac1ed29),LL(0x2e3b7145,0x48cf218d),LL(0x5cbfef12,0xde112f17),LL(0x76f3e234,0x194a8f16),LL(0x65787086,0xde1af9c2),LL(0x18958d56,0x495c76a5),LL(0xdd3dbcba,0xa5e9c9c9),L_(0x000000bf), LL(0xf9f1e953,0xb1fcebaf),LL(0x30a1b712,0x73d82709),LL(0x8296f1f2,0xfa6e1f41),LL(0x5ef71edd,0x7dd19081),LL(0xc4a2f8af,0x2f6fda9b),LL(0x85b1234b,0x541a4825),LL(0x23556036,0x79e6b22e),LL(0x911ac1cc,0x88ea71f9),L_(0x00000199), +}, +/* digit=90 base_pwr=2^450 */ +{ + LL(0xd86efa4b,0xa22cc5d8),LL(0x8ee779a0,0x5dd5d86c),LL(0xfd215954,0xfd5e2c81),LL(0xab1c7262,0x75f13cf7),LL(0x4f36ad82,0xe759a0b7),LL(0x8c3ddc91,0xd2223c0c),LL(0x10948a51,0x9b2c7f7d),LL(0x977160cf,0x285822b5),L_(0x0000000f), LL(0x92851c33,0x1a1e9623),LL(0xd7c127ef,0x7e5e2b50),LL(0xd984c528,0x3999dfdf),LL(0xaad5ce7d,0xd1373907),LL(0x5c84726f,0x97f8f082),LL(0x5ebbc32d,0x68dcb5c5),LL(0xbd51b3a0,0xa1b4f592),LL(0x36935287,0xf3eb9dca),L_(0x000000c8), + LL(0x56f967bd,0x95c0c51d),LL(0xdbb76844,0x7bb768dd),LL(0x35dbc45f,0xeda49098),LL(0x39df9e6d,0x3639006a),LL(0x47f77ee7,0xd878e5a2),LL(0xd141b2c8,0x2c8ccd83),LL(0x04a47e33,0x2d4027f8),LL(0x2c9dc7a0,0x9934bb00),L_(0x0000011b), LL(0x8efe0042,0x8d777a83),LL(0xd9919c1d,0x0f685368),LL(0x9dd72165,0x892863f1),LL(0x2a92b1de,0x8f2b25a3),LL(0x90ff3dd7,0x12a43206),LL(0xaf7bb8bc,0xe03505a4),LL(0xd763efcf,0xcf4f256c),LL(0x53701c70,0xef267753),L_(0x00000043), + LL(0xf628351d,0xecb197aa),LL(0x593ffafe,0xdd6e37e8),LL(0x40fd5b94,0x41331e2a),LL(0x298fef4f,0x60fb849c),LL(0xfd38fb42,0x7e149e93),LL(0xe83fe7b3,0x22e02e59),LL(0x5d08e682,0x58b84ec3),LL(0xcaa4bfd0,0x7f8e6b6a),L_(0x00000004), LL(0xc3c8a59d,0x89faa591),LL(0x3bdb5b23,0x6e000f52),LL(0xa824fd00,0x630a4795),LL(0xcbf7e717,0x4e000837),LL(0xc37102e6,0x5656508a),LL(0x40d36c3a,0xe0b06b84),LL(0x0a694f94,0xd89beeae),LL(0x647088c8,0x682c3563),L_(0x000001d9), + LL(0xd4220577,0x49e0800c),LL(0xd1b7504d,0x59ebe077),LL(0x04fd80e1,0x714afb4f),LL(0x90ea18a8,0x28810d8b),LL(0xf02c3cde,0x719cff83),LL(0x19367a86,0x8786eb9e),LL(0x952bac43,0xecceb4e9),LL(0x460e0748,0x55aefa66),L_(0x000001aa), LL(0x1f2623e4,0x7aaa315b),LL(0x44f96e09,0x7a5db2b5),LL(0x5dae237e,0xa9362519),LL(0x163873d0,0x69799223),LL(0x4d0fbf55,0xc1a58ea8),LL(0xd3bb728a,0x661ed43f),LL(0x100cfe43,0xf1cd21af),LL(0xa24f55c6,0x25dcbe9f),L_(0x00000118), + LL(0x33be448b,0x5ef36acd),LL(0xd5225f3c,0x5770b7a0),LL(0x90f00a62,0xebdaa1b7),LL(0xc0ab750b,0x1bcb88b8),LL(0x4d9be029,0x06bbf584),LL(0x9dfcba75,0x606f29fe),LL(0x74e426d7,0xd113e261),LL(0x2931cda9,0x0453e382),L_(0x00000056), LL(0x2b727cee,0xba1e3830),LL(0x95a907f6,0x1922ca15),LL(0x760c0c2f,0x24719cf1),LL(0x383ccd2c,0x11f794fe),LL(0xa0495e03,0xaf40e690),LL(0x3eba817e,0x1fab7cdd),LL(0xa83e8359,0x9846062a),LL(0x737b3c03,0x52241afa),L_(0x0000005b), + LL(0x747efd45,0x2d0ad5b6),LL(0x49587f7b,0x321154b0),LL(0x12ada5b1,0xdc3aa007),LL(0x0fe792e5,0xf996b5f9),LL(0x0e4944ed,0x8197e83f),LL(0x06340a72,0x6a72b742),LL(0xb3002f8a,0xbc8a8319),LL(0x173328b5,0x81f8ab11),L_(0x00000139), LL(0x964808f4,0x2774c6fa),LL(0xbe5f49f5,0x674e04ad),LL(0x8fbf7faa,0xe6de1313),LL(0x5724658c,0x38fee508),LL(0x6a0cb3e6,0xeb3e2c17),LL(0x24438695,0xe7eaef00),LL(0x43ac8a73,0x4dc94b9f),LL(0xd190f6ea,0x422b705b),L_(0x000001cd), + LL(0x1bd57124,0xd43e3b34),LL(0x02b39b5b,0xd46524f2),LL(0xabfa1c64,0xa4dd7015),LL(0x8ec6eade,0xfac38f67),LL(0x78cba481,0x1123582f),LL(0x61a4550d,0x1caa4894),LL(0x42f7ada2,0x83747c68),LL(0x17f7f74c,0xffb17df5),L_(0x00000130), LL(0x02e47bb1,0xeb2b93af),LL(0x7f0ef78c,0xcf301d2b),LL(0x8e9f267c,0x8e246b2f),LL(0xb4a2acd2,0x2035c962),LL(0x50846229,0x97e899e6),LL(0xe23609a5,0xfbcb2b53),LL(0x1483eb63,0xfc3f203e),LL(0x4d6ddbe6,0x2861a320),L_(0x00000039), + LL(0x5858d75c,0x41fc794a),LL(0xffcd84d6,0xf5985a4a),LL(0x5082ece4,0xcf3bb3f4),LL(0x850b4853,0xb1d8af65),LL(0x670d980b,0x6953dc3e),LL(0xf579458a,0x7963424e),LL(0xac2f2e4a,0x540b6858),LL(0x920d771e,0x1f5fed22),L_(0x000001be), LL(0xc4864af0,0x731be223),LL(0x662c4dc5,0x1419cfbb),LL(0xa5701752,0xd65099ca),LL(0xfbcc0240,0x3af88f3b),LL(0x1643acb1,0xfbc4861e),LL(0x67405bcd,0x35f067ed),LL(0x9351f1c8,0xcb8018ed),LL(0xeed0e188,0xd276f971),L_(0x000001f8), + LL(0x7974a311,0x8cc00e47),LL(0xd167d662,0x311413fa),LL(0xb1947f2a,0x68fd100f),LL(0xc373b68f,0xd96895d1),LL(0x259f8c2b,0xb6277660),LL(0x495d6470,0x6dd59691),LL(0x9eee1f91,0x8e4a7fc7),LL(0x1b01dab7,0xf1319245),L_(0x0000009c), LL(0x2efe3e85,0x3751b5a9),LL(0xb3dd751f,0x352c6ed0),LL(0x36c470b2,0xbb64e49d),LL(0x58925906,0x5b0b62a0),LL(0x9089d01b,0xe64e7de4),LL(0xf631915c,0xcd161d83),LL(0xfa1f87e7,0x44c46466),LL(0xcced2cc6,0xec7eb165),L_(0x00000125), + LL(0xda580a2f,0x0360b595),LL(0xc1265889,0x3fa41625),LL(0x9e6d3563,0xa19100cb),LL(0x10accaeb,0xaec86fbb),LL(0x7b3f3d8a,0x80771b15),LL(0xdb2ccbe9,0x803f9c49),LL(0x07a460fa,0xf34e5b14),LL(0x4b602490,0x6a99a6e6),L_(0x0000005d), LL(0x47562df1,0x308acd32),LL(0x65b0ad8e,0x3dceea03),LL(0x13ece697,0xe1bef19b),LL(0x0643badc,0x4cbdd893),LL(0x470bd8ab,0xafc33073),LL(0x39f6bceb,0x17b3cfed),LL(0xf3aad086,0x198868e1),LL(0x0e329726,0x9f6251f8),L_(0x00000016), + LL(0x2910e070,0x2c636d48),LL(0xd1bce1b0,0x51f92c94),LL(0x1ad3a1e4,0x88368755),LL(0x9be2c281,0xd8124a18),LL(0xe3a680f7,0x9e5bc7e6),LL(0x5e952f4f,0x2fefbd16),LL(0x5cef9135,0x19b6c616),LL(0x5576fffd,0xbf997c16),L_(0x000001f9), LL(0x7be439b2,0x01681747),LL(0xdbf38f7d,0x00a3bfc8),LL(0x549f1e54,0x39cded9a),LL(0x23fdd541,0x8b94ded9),LL(0x89eeca5b,0xfd084a5a),LL(0x5123eaa5,0x834be49d),LL(0xae42403e,0x02444c83),LL(0x25abfb57,0xbcb65841),L_(0x00000091), + LL(0x9621f3da,0x606a9e44),LL(0x91ee418d,0xd2dd052e),LL(0x7e5ea0e7,0x92e787f3),LL(0x69d6f73c,0x4508ea48),LL(0xfe248ecc,0xa2d461ac),LL(0x529ffcc1,0x22dcbd24),LL(0xf90dc5dc,0xa3364562),LL(0x542f8abb,0xd254e4f9),L_(0x0000016c), LL(0xc0262fa6,0x990aa036),LL(0xc4f4234a,0xb59ee2ed),LL(0x1031cef9,0xd5d4b081),LL(0x984145d5,0xdf2c037b),LL(0xc7b07787,0x2a2d6af2),LL(0x31d56853,0x6d5e6ff4),LL(0x309a7c9b,0xbb40c66e),LL(0xda6a3ee9,0xaf9db41c),L_(0x00000081), + LL(0x959a8be0,0x2ab124d1),LL(0xf806ef78,0x2f7a4e31),LL(0x0cea295c,0x32a4553d),LL(0x8a3bdbfd,0x19971283),LL(0x3b9e4766,0x8810a423),LL(0xcdcf9f57,0x8e85dc85),LL(0x020a6262,0x129bd8b1),LL(0xbc50d2d2,0x9a64395d),L_(0x00000068), LL(0x5b27b0a7,0xde8938c9),LL(0x2bd0d178,0xb0b45608),LL(0xde7e99ed,0x36896362),LL(0x3851afd1,0xe2cc94c2),LL(0xdfbefd8a,0x14aa57ae),LL(0x3c1abef1,0xd8652bb1),LL(0x0cc39736,0xaf001e99),LL(0x72b91536,0x9fdf9a10),L_(0x00000157), + LL(0x29021dc7,0x4403c833),LL(0x48e45088,0x26afc7d8),LL(0x41225474,0xa4629460),LL(0xcc7a0cd5,0xff951c59),LL(0xaba7cf1f,0x0d1f3526),LL(0xaf07c8ca,0x18426df5),LL(0x2746f85b,0x42d2e91b),LL(0xfabc76e4,0x58debcd4),L_(0x0000017d), LL(0x888a4dcd,0xa9da44e7),LL(0xeb092c08,0x1d496006),LL(0x0b68b024,0x67bb5005),LL(0xbf7c5c64,0x0562f97c),LL(0xca481cfe,0xb0ce28f4),LL(0xc88ad0f0,0x5bcd7411),LL(0x79f82640,0xcfb08fb0),LL(0x9dac9879,0x22beef72),L_(0x00000060), + LL(0x4092ef3c,0x055ab7d2),LL(0xb9344cd4,0xcbb171f1),LL(0xf24efa25,0x63c2684d),LL(0x4f8a3dbe,0xf0b702dd),LL(0xda3c37c4,0xa46de3f5),LL(0x17afe9a8,0xdeacde9a),LL(0x55f90e6b,0xb3ba7f88),LL(0x4d24b1d2,0xa174d6f6),L_(0x000000cc), LL(0x8d8e436b,0xbb7dee1a),LL(0xa172733c,0x562c1d69),LL(0x4325a01b,0x851c2792),LL(0x2307ef6a,0x99968ef0),LL(0x69918f4f,0xb12cbce1),LL(0xcd378fb1,0x9c21abf8),LL(0x48639036,0xe801ee02),LL(0x8268fb51,0x7205404d),L_(0x000000a5), + LL(0x7a194c8a,0x3a0f6f06),LL(0x7ad7abcf,0x531ca66d),LL(0x41cf832b,0x4ac4965a),LL(0x0f9f470a,0xe00766a0),LL(0xa92657cb,0xb432af80),LL(0xac40c892,0xa94b8968),LL(0xbd44eded,0x4be8b74c),LL(0x2a8d4620,0x98f760bd),L_(0x000001dd), LL(0x2479db10,0x2a7f464f),LL(0xdb3e7dcb,0x00b58c0f),LL(0x1a96b289,0x3c1d7ee5),LL(0x7a30a299,0xbf0ce935),LL(0xb49f5f57,0xf1f5d39e),LL(0x8f0c1970,0xac9cfb8b),LL(0x0718d4fa,0xe1c25a36),LL(0x66ec4ed9,0xb0d7504b),L_(0x0000004b), +}, +/* digit=91 base_pwr=2^455 */ +{ + LL(0x9db6d8d2,0x72de604b),LL(0xda62b655,0xfb7d9262),LL(0x9db8d0d3,0x8e9c2aa3),LL(0x9b867b7f,0xf2912d3c),LL(0x1a5ad674,0x279e6d83),LL(0xc6935b1c,0x82236f3c),LL(0x9a75e08b,0xfcf8f6f0),LL(0x1baaa28c,0x5ff40727),L_(0x000000f7), LL(0x120a90c1,0xab24706c),LL(0x991d9aa4,0x2ed85b4f),LL(0x767e0695,0x0793e3c1),LL(0xf7d06ffc,0x6115d975),LL(0x1316443d,0x9c57472c),LL(0x0b8651df,0x8b972443),LL(0xda1a64f2,0xf1bbd8db),LL(0x0c6db846,0x62aea165),L_(0x000000f5), + LL(0x6eab9379,0xd5d810c8),LL(0xe6eb51bd,0xe42198e6),LL(0x9bc2e3a0,0xc4b3dc48),LL(0xeda7e391,0x6ed77fe5),LL(0xcd0e3d73,0xc5e60972),LL(0x05f70f41,0x26a51aaa),LL(0xb07669f4,0x9830a47d),LL(0x34591483,0x45b98cf4),L_(0x00000090), LL(0x69325242,0xdc9d9c57),LL(0xf4c3b8bd,0x95086409),LL(0xd467dc92,0x3e6cf0fa),LL(0xfbebdef2,0x9684c1e0),LL(0x1daa3a72,0x8c3a2301),LL(0xf40ca0da,0x850f8c4e),LL(0x4dda12c0,0x990ccbe3),LL(0x8f2c5e51,0xc2f0adaf),L_(0x00000094), + LL(0x45c80cae,0x248df475),LL(0xb7ac228f,0x869c271f),LL(0xc18f18ee,0x46d75c07),LL(0xb3a5cead,0xa1a299f1),LL(0xf8c96489,0x7ba98e94),LL(0x805d6dbc,0x1a1d6b09),LL(0x485c463f,0x5bca1865),LL(0xfae82626,0x54594fd7),L_(0x000000b1), LL(0x88e41bdb,0x13e4d735),LL(0xb2ef61b8,0x5d0af04c),LL(0x3f79b3f0,0xe86965cf),LL(0x8df70be4,0x6a326017),LL(0x93f5bd3a,0x59b253c0),LL(0xcbf1399d,0xa14a5e9e),LL(0x5112a46b,0x98f7dd60),LL(0x84b48e76,0x9c0c1a6e),L_(0x0000005f), + LL(0x390065e7,0xf887b36a),LL(0xa9bb0064,0x651f2c93),LL(0x4572329d,0xd988aed3),LL(0x6f510e01,0x48541e9e),LL(0xabc023be,0x90ac10a8),LL(0xa8621efc,0xf943b700),LL(0xeb208400,0x768bb3b3),LL(0x64d85b1c,0x634af0db),L_(0x00000142), LL(0x250b4be1,0xa7e0a10a),LL(0x4e42e593,0xacaa8063),LL(0xadef0026,0x6f2f96cb),LL(0x955002da,0xca66aa2e),LL(0x57271d8d,0x15a69e81),LL(0x66dc7629,0xcf29f326),LL(0x378977dd,0x07d6619c),LL(0xe10e5eaa,0x48e47a94),L_(0x000000a5), + LL(0x9612b84f,0x60476dab),LL(0xd5ce8836,0x1ca95649),LL(0xd950d005,0xf0b56f1d),LL(0xe5ff1bc5,0x06d36f22),LL(0x6e683386,0xe2bbd6a0),LL(0x249d13ac,0x69fc343c),LL(0x15998eb3,0x47a41e75),LL(0xf1860545,0xc5dfbed2),L_(0x00000169), LL(0x972e1e1b,0xc1e80885),LL(0x5129b884,0xf74074e8),LL(0x9d124cde,0xb7fa9540),LL(0x9c58531f,0x291d5e4a),LL(0xaf4422a4,0xb30d5ded),LL(0x4cd8b631,0x30a12b16),LL(0x4d0ff100,0xb2d9901c),LL(0x450557f4,0x1b1ee29b),L_(0x00000026), + LL(0x85c6eadf,0x6dcd5109),LL(0xc399a187,0x5c966d1c),LL(0xfc77243f,0x4abf82c9),LL(0x3aec3b2c,0xfaf22c71),LL(0x4988df1e,0xaa22e170),LL(0x8f28a287,0x7d192a2d),LL(0xf724ea96,0x6179ade0),LL(0x8ced48e7,0x18acdc5b),L_(0x000001f3), LL(0xc8ad685c,0x0c63196a),LL(0x8e70052b,0xa08be270),LL(0xd8ff45f4,0xe9bd37fa),LL(0x46164862,0xcc39748e),LL(0x3cc067ef,0x7dcfa284),LL(0x68836731,0xc4586ae8),LL(0x8aabfd38,0x85ecef5b),LL(0x815642ea,0xaf78e84b),L_(0x00000073), + LL(0xbecd1954,0x55d6e970),LL(0xf86e2eca,0xa3c6d699),LL(0x35fd609b,0x277a6dcb),LL(0x8e0371bf,0x73c53bc0),LL(0x69861b02,0x747c9b1f),LL(0x121dd3fe,0xf6c83ab7),LL(0x1a4b5c05,0xa41b4b4b),LL(0x103beb00,0x6b773426),L_(0x0000002a), LL(0x2273e127,0x590624d3),LL(0x968b4935,0xdc61d6e8),LL(0x57ff9d1f,0xc882f647),LL(0x3774a13e,0xd8068210),LL(0xc8094f39,0x52df5a78),LL(0x9ce26b44,0xd80b9309),LL(0x06b76a9e,0x51126d68),LL(0x26a298cf,0x20129462),L_(0x0000002a), + LL(0x4a23b337,0x00b763fd),LL(0xe905f611,0x31c9604c),LL(0xad5b3ffa,0x059b27d0),LL(0xe85817bf,0x957d997f),LL(0xc9cea64f,0xa8adabfc),LL(0xbf24cb58,0x74dd2fa1),LL(0xfe218a31,0x08cb0dea),LL(0xcfee69ca,0x310fed00),L_(0x000001df), LL(0xb0001602,0xd66e131e),LL(0x18c779a4,0x47a1fa4d),LL(0x13180dd7,0x23f27ad3),LL(0x3169340c,0xdf4a2f35),LL(0xa8c2be04,0xaec77b35),LL(0x3a1f8aa1,0x2eed7fb2),LL(0xe69edc27,0x6110abc9),LL(0xa5d58ddb,0xe7590226),L_(0x0000002a), + LL(0xc035887a,0x2331223f),LL(0xe2c10ac8,0xb1509b5c),LL(0xf8262756,0x8c8a002b),LL(0x4f5e4c0e,0xccc65314),LL(0xaa63ef65,0x5d26b24c),LL(0x91432899,0xaef2d2ee),LL(0xace0562c,0x284cbe21),LL(0xdd5ba0e2,0x4e06f44f),L_(0x00000176), LL(0x604bd262,0x9becc83c),LL(0xb164c12c,0xc02c461a),LL(0x811e7743,0x621b38ad),LL(0x8fde0227,0x61151b61),LL(0x1eee0c18,0x90989162),LL(0xa3e85682,0x6d28169b),LL(0x478f9519,0xd980aa5d),LL(0x35d9dbcd,0xf940dd13),L_(0x00000120), + LL(0xe818a77b,0xf6f3cc8a),LL(0xede150db,0x71295f54),LL(0xc2f06bc3,0x173c2266),LL(0xbd26ab2d,0xda0b8b46),LL(0x958aad7f,0x470909e3),LL(0xbeb03518,0x0c135242),LL(0x6b5aad80,0xe6b782b0),LL(0xf43a70dc,0x1ebe42a4),L_(0x00000176), LL(0x0792877e,0xe9ee87f4),LL(0x5c7acfe8,0xcb05380b),LL(0x7c5775ef,0x2d540e71),LL(0x4507bf0a,0x839d644d),LL(0xc6b81a8c,0xbd1ff451),LL(0xa45f8834,0xc6531b7e),LL(0x06bfc9c3,0xf1a607c3),LL(0xfacabe92,0x152a3731),L_(0x00000013), + LL(0x42b39a61,0x972ed0b4),LL(0x6043f03e,0x2b923d0d),LL(0xef133e76,0x91d9dd18),LL(0xbb6feffc,0x25386141),LL(0x9f4c0085,0x7c52d849),LL(0x279b119e,0x1a74529c),LL(0xfbddc6be,0x3bb14fa6),LL(0x0fc37390,0x5b0469e7),L_(0x00000130), LL(0x2eb5ef21,0xc18b1c46),LL(0x93ed9948,0xc3e5b7a6),LL(0xef0ebe97,0x98b816ed),LL(0x5877dfeb,0x369d99d9),LL(0x3e4311e4,0x2bf65ec4),LL(0x311d0134,0x8c99e5b8),LL(0xc89dbf6c,0x0a9bf18b),LL(0x0c03cf95,0x67a8c9b6),L_(0x00000134), + LL(0x05361f9f,0x4dad1ff8),LL(0x536327ce,0x2d1bf3b3),LL(0x5b0b6267,0x47367af0),LL(0xf13ddf38,0x8798d158),LL(0xa948f127,0x84fbc252),LL(0x3d0fe92b,0x978e6fc0),LL(0x0138676b,0xef9334ec),LL(0x96ea4ba8,0xb13cf224),L_(0x00000198), LL(0x7d693fd2,0xa8ac5c62),LL(0x19d6d21f,0xb670515f),LL(0xb4a2fb70,0x28de441a),LL(0x4762c399,0x0fd9e912),LL(0x3371fcdb,0x896888c1),LL(0x85fb68ee,0xd0e213f1),LL(0x2d86c189,0xcea1f849),LL(0x151cf6fa,0x49b94eff),L_(0x000001b9), + LL(0x1baf476f,0xab2c72b8),LL(0x009b461a,0x349ca815),LL(0x64f4891c,0x07d9a898),LL(0x0c2c3617,0xe9f189a3),LL(0x6792792c,0x226e9a21),LL(0xf620343c,0xc9fabe1a),LL(0x72bb7a93,0xda748299),LL(0x321acb19,0x1b2afe12),L_(0x00000023), LL(0x72c1891c,0x938118e1),LL(0xbfadb006,0xb72a44a8),LL(0x9204c26a,0x32e10cf5),LL(0xbf6c9c27,0xd43d80b7),LL(0xbe5c3cec,0x0afdab99),LL(0x915d7960,0x1a5a24d1),LL(0x933f89c3,0xfe011c0b),LL(0x93e4d990,0xfd09b45f),L_(0x00000123), + LL(0x8c930d5e,0x5c3e8550),LL(0x67c79888,0xf4f27501),LL(0x18ef2850,0x0d7f6b01),LL(0xf40547f0,0x9cb15ed2),LL(0x89d6f189,0x1bc417a9),LL(0x5c937894,0x22180816),LL(0xb0e0c28f,0x72ddfe6b),LL(0x95839d95,0xb0b70e2e),L_(0x0000016a), LL(0x5a755fcb,0x0092c31b),LL(0x3261be8d,0x81547562),LL(0x2ed776ec,0x2bc72da3),LL(0x7afed7b9,0x943fbdb4),LL(0x7b5a5d6d,0x896c4516),LL(0x44f20815,0x23f06fef),LL(0x5bd5c28e,0x8f4f6c6d),LL(0xaeda432e,0x355da25e),L_(0x000001b3), + LL(0x69860706,0xfa6c2c0b),LL(0x097c5794,0x8878edbb),LL(0xc8776355,0xf986d296),LL(0xb4dc28da,0xcb68b5fd),LL(0x7d364b0a,0xf5c63307),LL(0xa8df5161,0xe81fb7b4),LL(0x5837723e,0x9cfefa9e),LL(0x681c02e5,0xf9182f1b),L_(0x000001f5), LL(0x9e5af2e3,0x43741dfd),LL(0xeeeaf6e7,0x0f7f7db0),LL(0x912e6cbd,0x1b17b840),LL(0xfbc2bc3c,0xff0906cb),LL(0xaed2e1f9,0x79085d0d),LL(0x413a3a6e,0x3e5f9190),LL(0xf10a18b2,0x5e4a7967),LL(0xbe3ecf44,0xb4e7b709),L_(0x000000ae), + LL(0x8c349a09,0x9f76c8ab),LL(0x693d1574,0x254fd850),LL(0xd18a6991,0x4944e4ef),LL(0xf78f60f5,0xbc73879c),LL(0x125696fe,0x04c63e00),LL(0x8e1e2dbe,0x88e142f6),LL(0x688fd93a,0xbbe7321b),LL(0xd6f1e83a,0xa7b2fa13),L_(0x000001aa), LL(0xa9d97c57,0xcbcaa293),LL(0x19ff3b97,0xb39ad595),LL(0xcedb5893,0x7e59369f),LL(0x47364ed0,0x15852af3),LL(0x7c32e933,0x4d5a40d4),LL(0x82768fe3,0x06533865),LL(0x53f8e4c6,0xf43bf2b4),LL(0x8b4a96dc,0x2542e182),L_(0x00000033), +}, +/* digit=92 base_pwr=2^460 */ +{ + LL(0xe3fec0f9,0x0611a7aa),LL(0x83626ec8,0x91b56818),LL(0xaebe5044,0xecc113fd),LL(0x3fc31dd2,0x68171e0f),LL(0x5fdadf10,0x4d2fbb6b),LL(0xe94a492b,0x06c20ee0),LL(0x0723f06e,0xe2fed2d9),LL(0x8316b906,0x2f32d5d0),L_(0x0000013b), LL(0xf27e685a,0x63731c43),LL(0x2924bed0,0xf8996c91),LL(0x58df5bd8,0x04d16a64),LL(0xb4780e3a,0x3ff6f14c),LL(0x5aed0330,0xcf56c817),LL(0xb62e0f3e,0xf8163011),LL(0xee8bd1d8,0x5c28fa8e),LL(0x9fa055be,0x5edb8d9c),L_(0x00000163), + LL(0x9d6a36d0,0x0deb4c2e),LL(0x0e66e6ba,0xb2451f1c),LL(0x058a747c,0x20962d66),LL(0x0214b10a,0xda104e82),LL(0xe594cae1,0xb4693d32),LL(0xf837609c,0x059d3bb7),LL(0x53eda7c5,0x1dd16cae),LL(0x3eb60275,0xc67ede2a),L_(0x0000007a), LL(0xc49b1452,0xc838202c),LL(0x35c208ae,0xb2fb2035),LL(0x56079145,0x55be9713),LL(0x95c814d4,0xfd8f0bb3),LL(0xc09f6782,0xcc755426),LL(0x8edafadb,0x4ecf0b74),LL(0xeaf4bc3a,0x553943ed),LL(0xa2bff049,0xe542c407),L_(0x0000017e), + LL(0x76e77cb5,0x0d581933),LL(0xc0bba438,0x9ddc3e72),LL(0xbc54c3a8,0x1bbc6d0f),LL(0xf2cdd63a,0x1518f660),LL(0xaf2f62bf,0x27e5bf5f),LL(0xbfe7727a,0x7b164682),LL(0xa33defeb,0x40ec257d),LL(0x6132b5ef,0x902b2e89),L_(0x0000000e), LL(0x87524e3b,0xe3ab4683),LL(0x69a88271,0x8299824e),LL(0x4545479e,0x373761e0),LL(0x397121a7,0xe3b1f753),LL(0x0aaebe93,0xd463acb4),LL(0x1af707da,0x1d6dcb72),LL(0x14e15233,0x48e5280c),LL(0x91655530,0xaaad009d),L_(0x00000012), + LL(0x964e28ff,0x9792b39f),LL(0xcfd79768,0xc556dfa7),LL(0xf279c07e,0xd7670e8c),LL(0xdad1cf40,0x5e04abde),LL(0x90b1377b,0x46fcc199),LL(0xf5067ad9,0x6a088572),LL(0x28101c96,0x2ad58aca),LL(0x43b5e33c,0xe333e24c),L_(0x000000b0), LL(0x475ac89b,0x54f0361a),LL(0xf79463ef,0xc22ce2dc),LL(0xdd053538,0x4e6817ca),LL(0x2bc1013b,0x4b01a6e1),LL(0x844a6eb4,0xad109d85),LL(0xbfdaef54,0x4481b985),LL(0x6830be54,0x297f121f),LL(0x8bfd8dd0,0x6d0b67a6),L_(0x000001cb), + LL(0xe23b3385,0x45ba65ed),LL(0x45dcbcdc,0xdd83e268),LL(0x0a0b1cdd,0x63968b4f),LL(0x35e092ea,0x71e6e72d),LL(0x3f1ddc4b,0xa46c5ed0),LL(0x5a166bbf,0xb7c76efc),LL(0x0de0b5f6,0xc1387b79),LL(0xb6445136,0x8923450a),L_(0x000001a7), LL(0x4005e747,0x99a85019),LL(0x0cae44ea,0x1e4af9c0),LL(0xe5e17b63,0x51c0dae8),LL(0xee91c80d,0x0c3cbe08),LL(0xa4093612,0xa23c8041),LL(0x3446b0ed,0xf215ada7),LL(0x43d14026,0x7813fb66),LL(0xb26fbac3,0x0031b68b),L_(0x000001c7), + LL(0x1660b409,0xe275ab90),LL(0x45ee7e0e,0x399f21e6),LL(0x37b06a37,0xe9bd12b1),LL(0x96080496,0xa5d50d58),LL(0x05ba3f26,0x7c1e3f37),LL(0x1d4a0081,0x4d39274a),LL(0x2d00866a,0x0317c40d),LL(0x64f146bf,0x2ec71ea0),L_(0x0000004e), LL(0x5c7f5630,0x933c199f),LL(0x4f78f168,0x3fb1362e),LL(0xa194ad2a,0x5259655c),LL(0x5f408022,0x5898f9da),LL(0xd8a6c1bc,0x7553edff),LL(0x2793c479,0xe26de20b),LL(0x1ea73083,0x533d9374),LL(0xb2a2971a,0x4fd22035),L_(0x000000e5), + LL(0x9a275851,0xf8f9d4de),LL(0xdebb5987,0xe3156400),LL(0xd526ec09,0xe0023f66),LL(0x5578bd03,0xd7d715cc),LL(0x3099f2ae,0x858cc9c0),LL(0x4417ca0c,0x2ea5506b),LL(0x23b4df57,0x7420ffbd),LL(0xe0c5dc14,0x99652bdf),L_(0x00000128), LL(0xf8e9148e,0x0d31987c),LL(0x9461ad7d,0xe6bbab25),LL(0xc859a4a7,0x3d2a289c),LL(0x08730e2b,0xbe629139),LL(0xcf6e14e9,0xc3904cf1),LL(0xdab045a7,0xacb2cca9),LL(0x2a43de3e,0xfa439f68),LL(0xd4d82c3a,0xd187ae70),L_(0x000001ec), + LL(0x78085816,0x5587b449),LL(0xe293d334,0x6f8ad12b),LL(0x4ce4906c,0x8d521bfa),LL(0xb26a6693,0xa914bdb3),LL(0x9dc3e746,0x3ae5f6e9),LL(0xb0881c2e,0xac2559db),LL(0x9191a1b5,0x72e53430),LL(0xa6c6a97a,0x07226ad4),L_(0x000001dd), LL(0x234483b3,0x3a39e249),LL(0x419af206,0xc72bc669),LL(0x42122752,0x9a44c7a3),LL(0xc28aa7e1,0x188ac573),LL(0x14ec6b11,0x09a3360e),LL(0xc8624588,0x3af7bc0b),LL(0x41e19299,0x42bd4817),LL(0xa8d8d757,0x8768555b),L_(0x000000cd), + LL(0x5b9a4085,0xe3a45fe5),LL(0x95591624,0xaebe1b9d),LL(0xa30f27ef,0xcc5daccf),LL(0xf894bab2,0x753b9ddd),LL(0x456446cc,0xa2185cca),LL(0xfed1e127,0x12d28159),LL(0x0339e65d,0x698c68d1),LL(0x1a9ca283,0xe9c06f97),L_(0x00000087), LL(0xb7266ccb,0xfa3c3bf1),LL(0x0574a504,0x1f37ca7f),LL(0xdbe81703,0xebc6693f),LL(0x6a068b27,0x9068b291),LL(0x03b786c6,0x3dcacbac),LL(0x74d197dc,0x5766087c),LL(0x8dd304a2,0x60b034d5),LL(0x45cead24,0x0eb18561),L_(0x0000010a), + LL(0x6e27781a,0x247df0f3),LL(0x5379241e,0xe00bbfb5),LL(0xad8e1bf2,0x4971d453),LL(0xffdae98c,0x4dac08bb),LL(0x43c392ba,0x1094f61d),LL(0x34435f45,0x25c82ce3),LL(0xc0379951,0x86ddd573),LL(0xbe3f91c8,0xa4a47405),L_(0x0000017c), LL(0x16746966,0xd140309f),LL(0x7d5ffd2b,0xb5c6fd08),LL(0xf1092ec1,0x3fef2aa9),LL(0xb1d3ec33,0x5486d81c),LL(0x414b5e87,0x09d0d988),LL(0x7faa17ff,0xd5d8f9a4),LL(0xed9cefef,0xa9baa755),LL(0xcec21b69,0xb4d04c7c),L_(0x000000b0), + LL(0x446d0af9,0x705db89c),LL(0x84f6bfda,0xac8dec0a),LL(0x7e47ba03,0x11601ccd),LL(0xa270c8be,0x5c7ebbe6),LL(0x6d1474f3,0xf62ef9fc),LL(0xe04a6269,0xfb77f59b),LL(0x9e393c86,0x150112d3),LL(0x5df9c04c,0x64d1ef7d),L_(0x0000006b), LL(0x430bfacf,0x4c8472a1),LL(0xfafe59da,0x41ca0a2b),LL(0x2ad99761,0x1e89c29e),LL(0x4b041df1,0xfe4fe5b6),LL(0x8b8ac33a,0xd36ab4d9),LL(0xf8473963,0x53e1a21e),LL(0x75363c3b,0x21c36ab1),LL(0xe0592363,0xe35ac3a5),L_(0x00000121), + LL(0x432d1107,0xee1e4fba),LL(0x2e463b38,0xafc972de),LL(0x1010af35,0xbe876d0d),LL(0x49188274,0x060ac231),LL(0xac345fe8,0xb568289e),LL(0xe6dec43c,0x9e9a1cec),LL(0xc8cf61bd,0xa7d9e863),LL(0x4480624e,0x84470564),L_(0x0000010f), LL(0x0aeb84ba,0x7730874b),LL(0xb07f3f33,0x5d9261b6),LL(0x122fcc85,0xe27f8557),LL(0x06820d8c,0x073c1847),LL(0x82e3f6be,0x3976550d),LL(0x0e6c3609,0x9a68ea2f),LL(0xf48dbeee,0x99ffba71),LL(0xcc24a469,0x3d0bdb6c),L_(0x00000168), + LL(0x910a6eae,0x01e0bacb),LL(0xfaf69acc,0xde8618ba),LL(0xc2f50b6a,0x14a7dc8c),LL(0x255c91c8,0x2f3c4d3d),LL(0x3e41e3ed,0xb39008da),LL(0x3885fe89,0xe57622e4),LL(0x0199693a,0x4d2436d5),LL(0x8a6ba080,0xdafeb6e6),L_(0x00000023), LL(0x5f1b83a0,0x2580e973),LL(0x8519d427,0xa920070b),LL(0x0b67d6f2,0x90fc96fb),LL(0x14566ecc,0x25c7716a),LL(0x30c1cfb5,0xb8dd507a),LL(0xd8b7f726,0xa175dc05),LL(0x24a60ede,0x99f15332),LL(0x78236bba,0x7ca4a569),L_(0x0000015f), + LL(0x4901b9ef,0x1e3479cf),LL(0xdd8491ad,0xd79c5592),LL(0xcd2995f5,0x8ece5732),LL(0x7f9162e1,0x7f928933),LL(0xff64a3a5,0xdd90d4ea),LL(0x82a7e6d8,0xd296e0f0),LL(0x8dc81d30,0xf317ef62),LL(0xa5bbd68c,0xc3c72a97),L_(0x000000bd), LL(0x43a9d0a2,0x8de59597),LL(0xbad8e310,0xe46b5cc5),LL(0xae543536,0x3be10fe7),LL(0xb038a518,0x22e5dfa8),LL(0x98fc1a73,0xda531be8),LL(0x4395fad8,0xa64d7d12),LL(0x81e9b112,0x5b7b8eee),LL(0x6b371c5e,0xf97cc8db),L_(0x00000072), + LL(0xac5fef79,0xeddf9eed),LL(0xac48ddad,0x3fafda2a),LL(0xb0386572,0xe2cfe37f),LL(0x4a95ae1d,0x2a2d6f2e),LL(0xf0b70c4d,0x5539faa3),LL(0x1e2738ed,0x855ae2b7),LL(0x680d7df5,0x5fa4d703),LL(0x047f7d72,0x981799eb),L_(0x000001a0), LL(0xc9f2a2dc,0xefb32d4e),LL(0x14e1364c,0x0008de76),LL(0x2af04490,0x56298a56),LL(0xa488b32b,0xe10ef61b),LL(0x7c93d9c0,0x74302f60),LL(0xe50aeca3,0x40b43584),LL(0x7cf8baf8,0xb9ab8a52),LL(0x29e97768,0xf0c44bc5),L_(0x000000b0), + LL(0x266fcb30,0xc7ebaeb9),LL(0x9166afc8,0x8df096c4),LL(0xb1a4fb9f,0x9ef63e0b),LL(0x0a63a275,0xd0e62d1d),LL(0xa13c16de,0xf215cb79),LL(0x82d5b46e,0x45439424),LL(0x5cf39033,0xc9b239aa),LL(0x4a39ce21,0xfcf03ed3),L_(0x000000a2), LL(0xdf517f0c,0xd8466a8a),LL(0x523be0b6,0x493a7775),LL(0x74759167,0x4894bb12),LL(0x5e2284c6,0x864e9ca2),LL(0xd07d26e2,0x08b7f98f),LL(0x6d662061,0x8e1e3fdb),LL(0xf64b5a66,0xa0ba6cae),LL(0xedd31c44,0xdac14a11),L_(0x00000091), +}, +/* digit=93 base_pwr=2^465 */ +{ + LL(0x5b2f805e,0xd37e005c),LL(0x6d99c24d,0x9fa0210b),LL(0x813da140,0xd53cbcd5),LL(0x9488bf13,0xb6d8655f),LL(0x5b2d055b,0xb21f224e),LL(0x3ba305b4,0x059a77dd),LL(0x5337f568,0x783aa9f0),LL(0xb88b4b1e,0xe8c56442),L_(0x0000016c), LL(0x71f23b13,0x9b7e0acb),LL(0xe0e90fde,0xda1867f2),LL(0x336f8ff1,0x14e3d072),LL(0x8e647516,0x87e51c7e),LL(0x1ca72a31,0x27ef1710),LL(0x61c42d89,0x641d8a97),LL(0xbb69cc0c,0x6138250e),LL(0xc12903e9,0xd2873a54),L_(0x000000b8), + LL(0x06415e13,0x0523f47f),LL(0x1fe7219c,0x11a49ec5),LL(0xbd8a88f4,0x6713e8b2),LL(0xd3f30897,0xe0f84892),LL(0x410c616e,0x4957e9fa),LL(0x60b01558,0xfce0903d),LL(0x41fc07f1,0x82117eff),LL(0x3ffa3ce1,0xb039b569),L_(0x00000054), LL(0x9c0d6884,0x04f700d5),LL(0x693fd9aa,0xa0743bcc),LL(0xb8b0e7fe,0x81c35812),LL(0xfcb182c1,0x64896cc8),LL(0x9f019f88,0x8c77cf49),LL(0xa6594c50,0x2c4110bb),LL(0x88406e14,0x0fcaee7e),LL(0xb8b45fd5,0x4dc1ba3e),L_(0x00000189), + LL(0x7eef0c8d,0x07c446c4),LL(0x0878421c,0xf275544a),LL(0x8722c55c,0x424a48fb),LL(0x028ec763,0xf6b5b3b9),LL(0xca8f7bf4,0xf78d4fe3),LL(0x77d82e20,0x04e23f42),LL(0xbc6300a7,0xf5f71bbf),LL(0x3aa908b8,0x0bc8e8a5),L_(0x00000109), LL(0x49fc8da7,0xd0dcad65),LL(0x35d31de3,0xe5fbc4e6),LL(0x9ac9c9da,0x525deba7),LL(0x0b85d812,0x465a1ffb),LL(0x08542228,0xc039c002),LL(0x1962a343,0x60c9d143),LL(0x729577d4,0x0fe4b631),LL(0x05befcdb,0x25528067),L_(0x00000198), + LL(0xe896c288,0xbc7bb607),LL(0x894887a4,0x14230e0a),LL(0x6eb1e976,0xe2c653f8),LL(0xe9303e71,0xdded494b),LL(0x9fc0dd96,0x98ac95d0),LL(0x63fba061,0x738abea5),LL(0xf3c1624d,0x4a0ea988),LL(0x389df64d,0xc6ae1823),L_(0x000001d5), LL(0x0454516f,0x7feeeb90),LL(0x7d7a8b0a,0xde36c637),LL(0xa9c345a7,0x611067e9),LL(0x0a9100d5,0x6bcdcedd),LL(0xf6c68c80,0x92b5dec6),LL(0x8d7d4a34,0xad3651f3),LL(0x2d5061b9,0xf739c0f2),LL(0xd15c9ea7,0x34e6cedb),L_(0x000000e7), + LL(0xcc5b33ab,0x5ef9ab41),LL(0xda8a106f,0x3b8cfab2),LL(0xb72948ff,0x3a4d0cd5),LL(0xf95a1457,0x5f6b94ff),LL(0xa636c12b,0x4c711bcc),LL(0x1e6c9e9f,0xffdba7aa),LL(0xe7eacce4,0xfce23073),LL(0x8fbc9275,0x5935eb69),L_(0x00000059), LL(0x00d4e588,0x05d931ae),LL(0x918b9aff,0x1f8a1b79),LL(0x844b544c,0xaa1709c8),LL(0x7e08066d,0x5258c624),LL(0xb640f1c6,0x176bbba4),LL(0xa22bddd0,0xc24ede16),LL(0xd090e0e9,0x4685aca4),LL(0xd8b8736b,0x64e8e6dc),L_(0x000000f2), + LL(0xd9d5f173,0x35476aba),LL(0x78928ff0,0xd948696e),LL(0x989109f6,0x5f254f30),LL(0x44ed9a63,0xd3543664),LL(0xa497e106,0xec63e4f7),LL(0x54a3d56c,0x4cb1418d),LL(0xbfbcd507,0x2a5c778f),LL(0x548f00b1,0x3ba6c12a),L_(0x00000150), LL(0xeeb4939d,0x4db14381),LL(0xc2817a38,0x86547af0),LL(0xb6947c7e,0x6d9e6104),LL(0x70ddd5de,0x2c369c27),LL(0x2f6e17ee,0x04550b40),LL(0x2c52689a,0xb0ead30b),LL(0x3892ae0d,0x99d74e20),LL(0x145321b6,0xd38ac454),L_(0x00000068), + LL(0x3ffb08c5,0x9a014b31),LL(0x2b898264,0x9e8130d3),LL(0x12fa12a6,0x014372da),LL(0x94999852,0x86eb5c63),LL(0x2a214084,0xdfb3f74b),LL(0x889d0eaf,0x9c182b54),LL(0x4f4c24a5,0x023efe1f),LL(0x0c3bbe75,0x3089629d),L_(0x0000012f), LL(0x76a8709a,0xdbfd5856),LL(0x138e9e46,0x49f8b60f),LL(0x8855a365,0x00624aa1),LL(0x358ac67f,0xff0d2d03),LL(0xd4f8c970,0xb9b15a4c),LL(0x244d4dda,0x60864d2f),LL(0x7db18004,0x1d1483da),LL(0xd00cd704,0xfbce4196),L_(0x000000b0), + LL(0x3cb5aab3,0x0feb0501),LL(0xca55bd42,0x8695f9af),LL(0x9c3c71fd,0xcc6e5ed1),LL(0x3d500caf,0x8edc89ca),LL(0x4e21b872,0x77647185),LL(0x0ff872ac,0xee45201f),LL(0xe23036d8,0xc8bee8b3),LL(0x5f2c13f7,0xa1d51a1e),L_(0x00000107), LL(0xbf685327,0x8022b011),LL(0x529ed8e2,0x2b6ff0cf),LL(0xb8a477a5,0x3b6e8238),LL(0xcf5cd2f6,0x291c55c9),LL(0x42ab247c,0x3f4796ab),LL(0x9f93937b,0x5dbfc098),LL(0xca7b47aa,0x7620e79b),LL(0x296f0a6b,0xdd4ea007),L_(0x00000158), + LL(0x26121c08,0xf01a2f06),LL(0x96bedf48,0x7e8f7f41),LL(0xd452fc32,0xcfab9384),LL(0xf1693df4,0x57e90144),LL(0xde828634,0xf5773fb8),LL(0xf8ca5704,0x123913d5),LL(0x2119d8cb,0x7eb6dfc1),LL(0xfdf9f63e,0x3c675fe5),L_(0x0000000b), LL(0x63fe6950,0x1f4969fc),LL(0x18608a42,0x92fc7ae8),LL(0x270c4cd5,0xf9035119),LL(0xd6e64853,0xc4832b26),LL(0x6b21d3fa,0xa4c2c4c7),LL(0x726b2dcb,0x725c739d),LL(0xb649408c,0xcaaec71e),LL(0xa0b38b9c,0x5b557fb0),L_(0x0000017b), + LL(0x2d41c6fd,0xffa160b7),LL(0x6ed5bb92,0xd76d4830),LL(0x174db5f3,0x56439bbf),LL(0x9cf210a6,0xcf76e11e),LL(0x0a183944,0xb1458e01),LL(0xa3ae6e4a,0x034db573),LL(0xc26a236a,0xe322c7d5),LL(0x3184159a,0xef56cb0f),L_(0x000000f3), LL(0x0a135217,0x83bf41c6),LL(0xc9df776e,0x9cd9b688),LL(0x5709e999,0xec730800),LL(0x9d5ce348,0x9c9f3378),LL(0xa53d30c8,0xdcaf4c9c),LL(0x09b66b9c,0xb8aeaba1),LL(0xc4d0530f,0xea0f22f3),LL(0x73581f25,0xc1d28f6a),L_(0x0000015a), + LL(0xcf778121,0x47e984e8),LL(0x20c4ae50,0xd1b90de4),LL(0xc94af252,0xdf5adf83),LL(0x41b573a2,0xb6b25c5d),LL(0x003e17b9,0x47e2aa64),LL(0x600d2bda,0xf75489f9),LL(0x595799ce,0x1b49400e),LL(0x7a9784ae,0xba0298f7),L_(0x0000009f), LL(0x3c7f600f,0xc18830c9),LL(0xc0e76415,0xb7a4b3e7),LL(0x46646194,0x210e39ff),LL(0x46e16ac1,0x94dd48b0),LL(0xe09df941,0x5657d728),LL(0x75b23925,0x987d7dae),LL(0xf5484304,0xb8bad70f),LL(0xee4753cb,0xc44a0313),L_(0x0000005e), + LL(0x8d604911,0x301bb718),LL(0x3ba3b59e,0x7ed618c3),LL(0x2225703f,0xe6e7b1ec),LL(0x3d9b8d85,0x2ddd2443),LL(0x526b020e,0xbbb89c6b),LL(0xf99d3527,0x9694dbcf),LL(0x1bef732e,0x34415736),LL(0x42d5d4d5,0x5cdafabf),L_(0x00000140), LL(0xd173ef6b,0x3da6214f),LL(0x2ffdc730,0x3a1a49d4),LL(0xc640e584,0x9755bbcb),LL(0xd90466dd,0x6a1bb6be),LL(0xcc97293e,0xd094e422),LL(0x23c9d622,0xf2ec9cc4),LL(0xcc616321,0xafe8382a),LL(0xc1a93af5,0x26522de8),L_(0x0000004e), + LL(0xdcb7addb,0x73e6acc5),LL(0x9117f654,0xea525fd4),LL(0xd6399efb,0x5316271b),LL(0xbf78249c,0xe30685a3),LL(0x7737d7b2,0xb95bf177),LL(0x4cfca353,0x138bd305),LL(0xa3671bc7,0x088b1877),LL(0x110ae487,0x1ff3771d),L_(0x000000fd), LL(0x0a4086e7,0xaf501744),LL(0x732576c6,0x4a538a56),LL(0xdfe16416,0xf3e1aa2e),LL(0xfe886ca1,0x95495af6),LL(0xfad421b0,0x2e5633e8),LL(0x14deea0f,0x87a33bf0),LL(0x59e08514,0x7333d917),LL(0x92bad09b,0x773222e4),L_(0x000001d4), + LL(0xd9f416e2,0x3565ca51),LL(0x0fd12235,0x5d3c8d16),LL(0xdc033287,0x948d4bd6),LL(0xd175dce3,0x9d5a6616),LL(0xd08718eb,0x4afce525),LL(0xd0bbb22a,0x9107b243),LL(0x93527f91,0x45382cdd),LL(0x6c46b7fb,0x8d893d42),L_(0x0000018d), LL(0xf7906107,0xbddfc4e9),LL(0x1d8f3a25,0x1c16029a),LL(0x51ce74f6,0x0f857730),LL(0x72d22f72,0x9d6f7b83),LL(0xa805ac0c,0xf970cb65),LL(0x6193a324,0xef9afdbc),LL(0x579b13d8,0x29a49024),LL(0x2ea3de42,0x4d4f92d1),L_(0x00000167), + LL(0x68b78453,0x3687601b),LL(0x61173b64,0x19ad59c7),LL(0x5cdaa0ac,0x37e94d1c),LL(0xb01a110c,0x46a8a192),LL(0xb73fb28d,0x89ea578e),LL(0x32a829b7,0xc1c111ef),LL(0x73a214d8,0x1c8ded15),LL(0x1cfef495,0xbf036574),L_(0x000001dd), LL(0x79e6c9f4,0xde40c899),LL(0x451757da,0x9bdf62c8),LL(0xde505c58,0xf590c16c),LL(0x0833d1ea,0x4f878ef4),LL(0xc9e82fbb,0x8ef0ccb2),LL(0x87ab08dc,0x1d1f4efd),LL(0x115ad9da,0x4e21d1ff),LL(0xd549cc87,0x88e6e9e7),L_(0x000001dd), + LL(0xc9cea1d4,0x424f87aa),LL(0xffc3ba23,0x162b1fab),LL(0xa3b2b167,0xb86c7978),LL(0x83e73da5,0x9b5f991d),LL(0x8d484c76,0x2cb3d908),LL(0xe085b439,0x28064542),LL(0xeba2ea8f,0x2b91d2b4),LL(0xcdc46cb8,0xe83321f8),L_(0x000000c0), LL(0x9d31426b,0xfd97601a),LL(0x4a0c50df,0x305e99ef),LL(0xfc4b8056,0xa29f6e86),LL(0xf5b0c1c8,0xbe1babed),LL(0x558d2cd4,0x75e98d4d),LL(0xd17d7bc8,0x45e57fd7),LL(0x9a0a33b7,0xc3cf9b60),LL(0x2d8c2a2b,0x5277b76d),L_(0x00000023), +}, +/* digit=94 base_pwr=2^470 */ +{ + LL(0x62b479f7,0x3e614e7a),LL(0x1806f150,0x0773591b),LL(0xc937295d,0xb432690c),LL(0x6d3468f3,0x7af2bc37),LL(0xc765b502,0xf1568b1f),LL(0x4508081c,0x4f2d04c8),LL(0x3b08d2fa,0x0d438419),LL(0xfdaa2353,0xd4118eb0),L_(0x000000dd), LL(0xa74bf7e0,0x7395d916),LL(0x879c30fb,0x732a652f),LL(0x33e906c3,0xd707078b),LL(0xeb09ecd6,0x4fe7914f),LL(0x76e24476,0xf1644295),LL(0x1ef70830,0x90ff7060),LL(0x8d1a94c2,0x8e38b393),LL(0x347e067e,0x7b7a7e79),L_(0x0000004d), + LL(0xb1fc1341,0x7e61fdc0),LL(0xe59da03f,0x98bd359f),LL(0x51831e76,0xf982fb68),LL(0x4079f81d,0x64253ce4),LL(0xffbd0a1c,0x684a0c0f),LL(0x24ab0837,0x0fa3fd27),LL(0xaefd7b90,0x8cd54b9a),LL(0x4f017be0,0x39893203),L_(0x00000159), LL(0x71b358dd,0x5f8bfed5),LL(0xbd73f12c,0xbd9b46e5),LL(0x7574722c,0x672fc532),LL(0x95b789de,0x9d4c5de7),LL(0x313e84cf,0x48e00647),LL(0x002f1934,0xdda401e2),LL(0x649a15d6,0x96114ef7),LL(0x37a4f04c,0x4a9dc085),L_(0x000000c3), + LL(0xf21720e5,0x8f0a82c0),LL(0x87ae4c3b,0x74f004b6),LL(0x384b1146,0xce02e119),LL(0xd665e4e4,0x1859c7a2),LL(0xe5dbd5ec,0xadfa269c),LL(0xa30b0013,0x74ac1d2b),LL(0xb4b5ebac,0xbc73c88d),LL(0xacdb48e2,0x872a2a2e),L_(0x00000061), LL(0x8570d85d,0x1044c064),LL(0x1021647f,0x3c4c4561),LL(0x05bc197e,0x8aef2b50),LL(0xdd7066b6,0x53c751b1),LL(0x10e7a8e7,0x3b7ee577),LL(0x2667f737,0xee8825eb),LL(0xd2baf066,0x2e6cd49a),LL(0xfaed0dee,0x4bbbae5e),L_(0x000000c0), + LL(0xea72f88d,0x755e5ed4),LL(0x7eafbd5d,0x22817dc2),LL(0x8274c8f2,0x6ed11c56),LL(0xa0be4b95,0xc506cd96),LL(0xfca3c62a,0x6c56121c),LL(0x160f6437,0x94e1e3c5),LL(0xcd969d97,0x2a1b9ac1),LL(0x6a2818ba,0x5d12cb94),L_(0x000001bd), LL(0x838f81f8,0x67065269),LL(0x6eaf2423,0x2f4afa25),LL(0x74390891,0x2342e954),LL(0xec048d33,0x5565f855),LL(0x3a8816f7,0x8e4ec59a),LL(0x55b015d4,0x6a715052),LL(0xbf898ef0,0x385313b6),LL(0x8baf90ae,0x415dc868),L_(0x000001d5), + LL(0xb57c6620,0x117822b3),LL(0x37c2f26e,0x4762f6de),LL(0x9377e35f,0xfb62c99f),LL(0x3c9faf6d,0xa5fec0c5),LL(0xe6f2602d,0x6a84d794),LL(0x1e2e5844,0x2e9c376a),LL(0x2b97dfd3,0xcdd28547),LL(0x24977fdb,0x3efe1f48),L_(0x00000189), LL(0x28c17d00,0xd2462621),LL(0x19582902,0x6e455352),LL(0x638d59c6,0xc3bea880),LL(0xd74f8133,0x1df686ac),LL(0xae8224be,0xdefcc095),LL(0x467de606,0xc63376c6),LL(0x1bbcfb09,0x644acbfc),LL(0xe6c4cc04,0xce83b441),L_(0x00000126), + LL(0x02da505b,0x27486dd1),LL(0x6bd544fa,0xc8ec4c55),LL(0xc9e28c7b,0xa7531516),LL(0x22d696c9,0xfbb565f5),LL(0x5bc69de8,0xf4a6f6f5),LL(0x3c4607fb,0x2183944a),LL(0xfbf34142,0xc088d4ca),LL(0x6a6a25a0,0xebf86497),L_(0x000000be), LL(0x17ac892f,0x08805ee9),LL(0xe10f4906,0xb9740059),LL(0x2a74e9d7,0x72ae3ee2),LL(0x2294188b,0x0359108b),LL(0xffa569a8,0x5438b3ae),LL(0xf5a918ef,0x5b1543c1),LL(0xbe32cd1e,0x857bce3b),LL(0xf67721ef,0xcb0f4756),L_(0x00000137), + LL(0x5bd5d895,0x7f863db9),LL(0xb81bcc90,0xc94e7e86),LL(0x24d3e88a,0x59ad89c4),LL(0xf5ed10e7,0xce7d1f0e),LL(0x1bd7de70,0x6932d3ed),LL(0xf1561272,0x12569b60),LL(0x393d97a6,0xf0741124),LL(0xa46a9516,0xc9b5b179),L_(0x00000130), LL(0xe867277a,0xda1e1906),LL(0x6ff9aa73,0x64a918f8),LL(0x1673d460,0xf233bf04),LL(0xe548f086,0x4ac69dac),LL(0xb984ce8a,0x12e45aea),LL(0x294fb6e3,0x5a19d674),LL(0xd8993346,0x00bc5dd3),LL(0x0c254d86,0x90107b13),L_(0x00000014), + LL(0xdf6f2ba1,0xec115486),LL(0xb08c738e,0x93e59803),LL(0x23024435,0x4f00e934),LL(0xbdbe60eb,0x7c91438e),LL(0x23e859e5,0x580e89c5),LL(0xba0053e0,0xb329d75c),LL(0xd11317c9,0x3d389550),LL(0xd235e570,0x5aac6426),L_(0x00000184), LL(0xfa06b949,0x42349105),LL(0x21c69e6c,0x9a81de9b),LL(0xf70eb151,0x2990539b),LL(0xafc827ae,0xfe9bf0bb),LL(0xee9dd548,0xb8dbb3c1),LL(0x8c4d4274,0xf3be2a90),LL(0xb7224476,0x6e6842bc),LL(0x8428346b,0x39da0c73),L_(0x000001ad), + LL(0xaf5db393,0xdaa88388),LL(0xe569ed69,0x7f0f1377),LL(0x60762027,0x2fe1fac0),LL(0xa5dd03fe,0x91b1f27a),LL(0xb60b2ae5,0xc4161046),LL(0x0c72417b,0xf9d8850d),LL(0x16e6bfc4,0xa63fb7e8),LL(0x1c03a1ed,0x8baa08f0),L_(0x0000017d), LL(0xaf898d56,0xba237ffd),LL(0x7b0680d7,0x0d439e05),LL(0x64dd0307,0x5d17a507),LL(0xded7a46c,0xaa6f686f),LL(0x46bc0763,0x302e95a9),LL(0x16dd6fb8,0x32a15017),LL(0xd01bdd13,0x4b4868e4),LL(0xe250803d,0x1558017b),L_(0x00000168), + LL(0xc67a04f1,0x275e8267),LL(0xb1b59985,0x6c0a68a7),LL(0x44944a18,0x537ca1e2),LL(0xd9ed65ad,0x30e1107c),LL(0x1eddede3,0x802fb267),LL(0xeaf5fb68,0x27195ee0),LL(0xd0137c18,0x11b69677),LL(0x331a8cb2,0xab2ade03),L_(0x00000147), LL(0x872e7d11,0x0449d382),LL(0x0033feb4,0x9c7c44c6),LL(0xb2576dae,0x83e4fe6e),LL(0xde49f678,0x8e0a0c88),LL(0x049a1944,0x873f101a),LL(0x2f0dcfaf,0x0c6ecf9c),LL(0xf4b7cbf4,0xb8b0d918),LL(0x5cf46641,0xd2760eea),L_(0x00000082), + LL(0xdb4a36c2,0x8ae1b4af),LL(0x5fa3cb57,0xd120dbcb),LL(0x79a8d192,0xec8bbea1),LL(0x8ab00e0a,0x0fa43f9b),LL(0x8da0324e,0x320ae51d),LL(0x53f9b52f,0xd7d8355e),LL(0x28f25abd,0x800a5d6c),LL(0xce8c317a,0x8116a102),L_(0x00000024), LL(0x539d001d,0x5e187817),LL(0xdc1f3bba,0x3d0941a2),LL(0x42b1a905,0xa2a2cc7f),LL(0x7392c3e9,0xc8a2218b),LL(0xf81e4937,0x50e22321),LL(0xec9f9e7e,0x650f7010),LL(0x905ed136,0xce7ae424),LL(0x143d78dd,0xf4b39b10),L_(0x000000de), + LL(0xfa007b15,0xeaa9a342),LL(0x15bb7a90,0x26771654),LL(0xdcc6aa0c,0xc720264a),LL(0x986a1f0b,0xe93f7bc1),LL(0xa182f9b5,0x1bf6b3fc),LL(0x5c22f84c,0x14eb9a7b),LL(0x7bdec7ad,0x42c3b078),LL(0x108902c9,0xd7973e78),L_(0x00000069), LL(0x4676602b,0x20230ff4),LL(0x64b88212,0x8928dd30),LL(0xd730a522,0xc0f54e1a),LL(0x528ea087,0xbe8035de),LL(0x2188b80a,0x1d9e98d6),LL(0x12fe3f39,0xc4b4d85f),LL(0x5d1c13b3,0x0436d0a9),LL(0x02c9a494,0xcc5f2436),L_(0x000001d2), + LL(0xbce8d401,0xfa9544c4),LL(0x3a3c6860,0xc43438df),LL(0x7ba2b50e,0x8cfb61b2),LL(0x160b337f,0x177729b0),LL(0xccab10b1,0x69458502),LL(0xb9a0ff5a,0x78449ba9),LL(0x67ca5074,0xa879a311),LL(0x73b77e61,0x91f5cf0f),L_(0x00000119), LL(0xa663023b,0xe9dd38a6),LL(0x7f1ab441,0xdb97e39f),LL(0x8836c427,0x0e31501d),LL(0x26be55f8,0x88c80de0),LL(0xf094f5db,0x161288e2),LL(0x239cdfc2,0xb27ca6c4),LL(0x6d31f6e4,0xbff28243),LL(0x6db05886,0xadc659a4),L_(0x000000f4), + LL(0x46bc5619,0xbc76d262),LL(0x3a81dc1b,0x1f94ed62),LL(0xb5ab7c11,0xcb89fed9),LL(0x7bd8c4df,0xf48a8846),LL(0xc61ecacd,0xe68265b3),LL(0x88e6ef63,0xfbdfdb92),LL(0x8bd95324,0x94692afd),LL(0xb7f81080,0x8b73dbb0),L_(0x000001a3), LL(0x42f27046,0xed59ec62),LL(0xe2c2f288,0x6fafd323),LL(0x11cda8bd,0x6af36bba),LL(0x324f4f07,0x06098acb),LL(0x091a65fb,0x74b50485),LL(0xf28dae6c,0x93e109e7),LL(0x1a6b91b6,0x648a962a),LL(0xba4a27c8,0x4dfe3efb),L_(0x000000ac), + LL(0x3b488e90,0xf43286a4),LL(0x56196c6d,0x6ba6cc59),LL(0xec8e64cd,0x7bd6708a),LL(0x98aaa1d7,0xb45c7cd9),LL(0xb5bcc0ce,0xce3eb2eb),LL(0x2653d9af,0x5b7387d0),LL(0xf3afdf31,0xe27833cf),LL(0x17806f1f,0x3ec743c7),L_(0x00000144), LL(0x5e969a67,0x96863b2d),LL(0xf200831e,0x1d6c065f),LL(0x1613e78e,0xa1366e05),LL(0xee600a0a,0xc0223e24),LL(0x06065867,0xe94c7976),LL(0x81ff94bd,0xf203aa4b),LL(0xf9511ac2,0xb7c19e3c),LL(0xd9eef849,0x75211256),L_(0x00000153), + LL(0x708d61a9,0x5cc484e2),LL(0x446b62d8,0x1d84ce14),LL(0x9c0fff45,0x08f1ae70),LL(0xe53a49ca,0x71899e1a),LL(0x9917f93d,0x3709a90d),LL(0x12fbb050,0x045ef39b),LL(0x38af72a2,0x0b8cc9a0),LL(0xf0817cd9,0x52b4ed83),L_(0x000000f3), LL(0xae023ef9,0xa7a71d48),LL(0x44e50d53,0x67e7ad87),LL(0x192ec226,0x37867d3b),LL(0xce32e194,0x24825f0c),LL(0xfce90271,0x5aa41f07),LL(0x4b826212,0xc9cefc67),LL(0x1f602e03,0xc071ae6d),LL(0xf9f93cc0,0xe4c52cae),L_(0x000001fa), +}, +/* digit=95 base_pwr=2^475 */ +{ + LL(0x58773b9a,0xebcc18c3),LL(0xf6385f12,0x8caf536b),LL(0x8a0c24ba,0xd83891ca),LL(0x08b3093c,0xb8c37621),LL(0xb26a0ef5,0xb41e3399),LL(0xca8c426d,0x0263fadf),LL(0x173bf676,0xd40bf584),LL(0xd8a6677a,0xa4760acd),L_(0x000000ec), LL(0x4207fa10,0xfbc42b8b),LL(0x5a60d34e,0x678686dc),LL(0xa367e08d,0x3e942c85),LL(0x2dd8cead,0x9d289bdc),LL(0xa6d1bb40,0xa4b034c3),LL(0x04955940,0x4e438893),LL(0x0034f368,0xddeee0c8),LL(0x63808a7c,0x8f3d9aa2),L_(0x00000114), + LL(0xd3e1babb,0x3ddf4a3f),LL(0x7d84daca,0x17e3e628),LL(0xd7eaf570,0x4870b354),LL(0x9fed1a4e,0x26a3e3ca),LL(0x5710e04c,0x0ce1ea5e),LL(0x17a2ff92,0xee67709e),LL(0xf8a3bc06,0xc019a660),LL(0xdb788ab8,0x3d909c0f),L_(0x000000f4), LL(0xebda5c3a,0x51c0c61e),LL(0xc130704b,0x5d086395),LL(0x762ffbcb,0xf6639983),LL(0x337f660b,0x46d9fb03),LL(0x8fa37c16,0x865cf06a),LL(0x3f14b6d2,0xe7365f2e),LL(0x8227d360,0xc5c3e588),LL(0xb6a48fcd,0x8c2eaf07),L_(0x0000019e), + LL(0x3e7b660c,0x226084ff),LL(0xaf5d90f5,0xe8626b6c),LL(0xa900e635,0x22c0e157),LL(0x22e31c96,0x1a4ad1af),LL(0x9e88afb5,0x3aadc5f1),LL(0xff5f6050,0xb11e90fa),LL(0xc0677ea3,0xf77875e2),LL(0xaed6a977,0x841145e6),L_(0x000001e8), LL(0x587f301e,0x6bb84d1a),LL(0xbfc80743,0xf386ce67),LL(0xb28c1dbb,0x43c48ae6),LL(0x88b71460,0xf88870e8),LL(0x4e3895ad,0x71c30d54),LL(0xcdbb1a28,0xa8e29d09),LL(0x71499052,0x6fbd1362),LL(0x3608395e,0x9cdda95f),L_(0x000000b2), + LL(0xf2dc50d1,0xb01ce2b5),LL(0x9f8c4d01,0xf417d7e3),LL(0x78d34284,0xcbf04214),LL(0xf59d157a,0xc4238071),LL(0xf8a594c0,0x7b0a1e05),LL(0xbaf85cdc,0xc9cfd81b),LL(0x1d1329e8,0xc9be4f2d),LL(0x3168fc55,0x5c20884e),L_(0x0000009b), LL(0x9cb47277,0x6e9fd410),LL(0x96d54227,0x16c1621d),LL(0xd61e57db,0x8656adf3),LL(0x2da52da5,0xd546ecce),LL(0x2098e089,0xb41508ee),LL(0x7499c874,0x9cf31199),LL(0xf525839d,0x96548966),LL(0xa0de08e5,0x1cdd85c0),L_(0x00000051), + LL(0x7be106c4,0xb8ede8af),LL(0xa3de8360,0xfdee27bf),LL(0x4341bdb3,0x376db3df),LL(0x851382eb,0x309206d9),LL(0x6325d433,0xff416946),LL(0x8994d6c3,0x0e775cfd),LL(0xfe50149c,0xee627cff),LL(0xee7b578d,0xcd01235e),L_(0x0000005b), LL(0xc03a13e9,0x5a46c19a),LL(0xeec8d37d,0xab92e082),LL(0xa6ae3bae,0x2deb57b4),LL(0xe3c4d075,0xce5d2ec0),LL(0x962e7d64,0xbd42e96f),LL(0xc56b57d5,0x513d5228),LL(0x68f2747e,0x7ec6010d),LL(0x1f92f153,0x8ad259fb),L_(0x000000ca), + LL(0x0c4d9937,0x1fdb1361),LL(0x018344e5,0x016f0192),LL(0xcb8a7e81,0x1ca2c27e),LL(0xc36425ff,0xa8df5318),LL(0x56d5d247,0x84872bcd),LL(0xa2e0d261,0x4866d142),LL(0x83feb22e,0x0999b14a),LL(0xab13dac7,0x07863be6),L_(0x000000d0), LL(0xd62b467d,0xce023bbb),LL(0xf8f48d21,0x35940e6e),LL(0xea9c5f9c,0x2bd76e0a),LL(0xa1f9af53,0x8ff97911),LL(0x750c500f,0xdefcff41),LL(0x3985ad13,0x9c027cfa),LL(0x36812ef9,0x34694b31),LL(0x5d319ee5,0x9722dca8),L_(0x0000019d), + LL(0xa6ef59c2,0xa78cdc7b),LL(0x67114f96,0x1a506e84),LL(0x909080ed,0xe3ccc90c),LL(0xe770488f,0xe93a6e81),LL(0x0b332add,0x6e681e90),LL(0x494adeb9,0x13abbb36),LL(0x580a5070,0xbf271178),LL(0xa19a151b,0xebb4d25d),L_(0x000000ae), LL(0x8202ce50,0x2353100e),LL(0x4b162883,0xf7cdd45e),LL(0x57659fda,0x4f79c844),LL(0x95b94da4,0x3ca165b0),LL(0xa6d4f4d9,0x3565f5c9),LL(0xc13d6186,0x288f561b),LL(0x81efd295,0x51b5a1dd),LL(0x0dee47df,0x0f774131),L_(0x0000005e), + LL(0xac4c9233,0x8240d25b),LL(0x6132b9fa,0x74ec9502),LL(0xddc2ef3e,0xa9db4e16),LL(0x29d151b0,0x5ad95c14),LL(0x9bb57bff,0x08144cde),LL(0xf2a19e48,0xef980c02),LL(0x655b0b6a,0x1f2df6c5),LL(0x2138725b,0x346457ed),L_(0x00000072), LL(0xe12bd180,0x8e3077ff),LL(0x2804b9bb,0x8db75e68),LL(0xb8a3a732,0x0cb1bbec),LL(0xb587b6f5,0x823e8549),LL(0xe705757a,0xdd7be7a7),LL(0xb60b8617,0x23677103),LL(0x131d7bc3,0x128ac224),LL(0x03713f91,0xadb3b9bf),L_(0x000000de), + LL(0x1a0be84b,0x625c8b6a),LL(0x8fc09173,0x14eb1426),LL(0xbb0b06c4,0xd925dd0a),LL(0x28f4f79f,0x5a160baf),LL(0x6a240ffc,0x4f7c033a),LL(0xcb7f6751,0x98adaaee),LL(0xc349dd94,0x192aa587),LL(0xee546461,0x189c51b1),L_(0x00000007), LL(0xeb23ea03,0x46d637ca),LL(0xaa3d1efa,0x01cfe315),LL(0xf7d6f7f9,0x4164c61b),LL(0x64b9530e,0x1a339a05),LL(0xce33c2f5,0xc30d67f4),LL(0xbcb863c9,0x79f8f963),LL(0x2bb9ff68,0x0799af64),LL(0xcfca4893,0xe7b1b3d8),L_(0x000000c3), + LL(0x58e4f6cf,0xa5b46eea),LL(0x00cef9c4,0x0381ae85),LL(0xe36179b5,0x317e7dbb),LL(0xac6498cb,0x2d824ab9),LL(0x328707df,0x6aa97d96),LL(0x80e79f5f,0xc19368fd),LL(0xe03799c5,0x109d20be),LL(0xa4688d4b,0x5dfd91a5),L_(0x000001ae), LL(0x49aaa1b4,0xfce4aa86),LL(0x8a4a894f,0x5f3c5caf),LL(0xf0a6af85,0x0a082826),LL(0x869fa6ef,0x4cf46392),LL(0x5a750056,0x1d906025),LL(0xb437590a,0x5afd7688),LL(0xfa2a2142,0x5b91f195),LL(0x46dd69d6,0x53028951),L_(0x00000004), + LL(0x0870d771,0x110cffe0),LL(0x4f03a88a,0xb44dbaac),LL(0x68ebc98c,0x849e6d09),LL(0x9e197499,0x126aa5d3),LL(0x374e4b92,0x9e50c62e),LL(0x9406118f,0xf4a6d99b),LL(0x4e25c845,0xc9df6238),LL(0xb15d2756,0xa10c0e52),L_(0x000001fe), LL(0x347cab66,0x816212f7),LL(0x43351049,0x52076e7a),LL(0x90d0771e,0xac804061),LL(0x50393b27,0x509ba99e),LL(0xb81254b5,0x6fa16ea2),LL(0xbe5e2613,0x1a907d04),LL(0xf4aab035,0x2ee00b2d),LL(0x00a0f275,0xab599862),L_(0x0000009e), + LL(0xecfc0941,0xfb9a872a),LL(0xde3af050,0xbec0fc8c),LL(0xebe6b500,0xe7c4ef2e),LL(0x28e4d4b7,0xb38a6c42),LL(0x82362d94,0xc4f9fb0e),LL(0x4e229d20,0xa3690dbf),LL(0xa6e45bdf,0x730c74e3),LL(0xa7b1c90f,0xf2fc481f),L_(0x00000106), LL(0xb887a36f,0xe5e496c4),LL(0xe46148f8,0x16f8ae6a),LL(0x4268188f,0x60936452),LL(0xdcecf1b3,0x828f2ec9),LL(0xeec097ea,0x8a581be5),LL(0x3e062b3a,0x85430a09),LL(0x4da12b49,0x562092de),LL(0xcbb50541,0x33c27b17),L_(0x000000ae), + LL(0xfb667016,0x4148520a),LL(0xb05dd749,0x6530988c),LL(0x4882c146,0x38e93ea7),LL(0xf98af47a,0x6360b046),LL(0x75158008,0x670a2092),LL(0xa8d210f6,0xcea39485),LL(0x590b4493,0xd54fb04e),LL(0xe30eec4b,0xea6ce05c),L_(0x000000fe), LL(0xc43f1354,0x095bed5a),LL(0xc9bc887c,0x40c45485),LL(0x2639073e,0x060df364),LL(0x9ad162fc,0x0ed461e0),LL(0xd17260de,0x48f9f001),LL(0xcef6cf88,0x5e44883d),LL(0xc42e028e,0x78ade819),LL(0x7ee983d2,0x24ef3daf),L_(0x00000059), + LL(0xad0684c9,0xfbbed4ff),LL(0x64e57bff,0x825f2bb2),LL(0x9eb6b035,0xfd8b6643),LL(0x3c213466,0x9c353790),LL(0x7313deab,0x9b0366be),LL(0x2121723c,0xac2996ae),LL(0x953e87c3,0xbd382785),LL(0xf9b6974b,0x3a30236c),L_(0x000001e4), LL(0xffdea7ff,0x5f3b2707),LL(0x68809f79,0xca4a12da),LL(0x374c5228,0x32cc5a86),LL(0x15cef9a1,0xae5f8c0d),LL(0x72616f2b,0xe61ce206),LL(0x75c41da6,0xde33abed),LL(0xa5fc5af7,0x50659126),LL(0x5776a4d1,0x4c16e788),L_(0x000000d4), + LL(0x59994686,0x017dab60),LL(0xe869faef,0x1a3d2819),LL(0xa91c965c,0x95cacbcd),LL(0x1c63a302,0x28898d33),LL(0x91791e04,0xe5b4e674),LL(0x2669fe66,0x4ee8bdb3),LL(0x55d62682,0x333ebff9),LL(0x2111714d,0x88832299),L_(0x000001e4), LL(0x1080f065,0x4df0c3cb),LL(0x7975bc08,0xa4a0f0d9),LL(0x6243d2cd,0xf978a250),LL(0x447d6ec4,0xca8ffce0),LL(0x3c8e28e1,0xa6bda9ff),LL(0x45d5e419,0x3acf30c2),LL(0x7bf52151,0x2b66a867),LL(0x21d9061e,0xbba7056e),L_(0x00000013), + LL(0x8e534a08,0x8f349801),LL(0x029f064c,0x07be931b),LL(0xb893aedc,0x14f71f6a),LL(0x242b0eea,0xe179067b),LL(0x8af895ee,0x99f6bf52),LL(0x5e852a27,0x1d5c2098),LL(0x94bc1969,0x296ab7db),LL(0x7605deba,0x31b9475f),L_(0x000000b2), LL(0xf8d3bc51,0xf8c45d63),LL(0x0d9145a0,0xb3a1daab),LL(0xbc0cd8bb,0x614875d3),LL(0x4f51299d,0xad650d62),LL(0x7baf748b,0xdb91d840),LL(0x83b9d385,0xf5cc54a3),LL(0x840ae765,0xbe2653a6),LL(0xab5a54bd,0x5728a0ed),L_(0x00000086), +}, +/* digit=96 base_pwr=2^480 */ +{ + LL(0x4732d33f,0x2be41906),LL(0x9f1fdd6e,0x9ab150fb),LL(0xb458dd16,0xf3f55fa5),LL(0xb1bb79de,0xd9b88ebf),LL(0xc1d98e1f,0x7b8b17a8),LL(0x7f6beb8b,0x6c86e6b3),LL(0xbc72340b,0x7bb70edd),LL(0xdc7c19d3,0x67a99418),L_(0x00000168), LL(0x22c0fb38,0x56a4a09f),LL(0x9cb6bc12,0x8ded9bb1),LL(0x77d8b51c,0x9f35ca45),LL(0xeb257480,0xf1168ba7),LL(0x770b52be,0x12cdae11),LL(0xed4f42bd,0xde9dff68),LL(0xd326b225,0x5631a8c3),LL(0x1d37f144,0xb14a3c37),L_(0x0000012c), + LL(0x0603f033,0x66b0b95f),LL(0xf969adad,0x57813fa7),LL(0x1acf7746,0x220707f6),LL(0x712a2615,0x71d4cd53),LL(0x2fd4ef2f,0x1f82a44a),LL(0xd9e26293,0x0681773f),LL(0xf763ad20,0xe31fd702),LL(0xa99b206f,0xc3a8767f),L_(0x00000165), LL(0x84569e51,0x41a7f8ce),LL(0x21c3dd47,0xcc9159a8),LL(0xe90e3290,0x06b623fa),LL(0x9e8cf993,0x531760ae),LL(0x2874afd7,0xc9e7cf28),LL(0xe6527ae8,0x293d6e1a),LL(0xf99eef73,0x03d3d878),LL(0x9237109e,0xe1efdba8),L_(0x0000016e), + LL(0xd074ce95,0xcc51928e),LL(0x2af7a58d,0xfb374b29),LL(0x5ec5d4bd,0xd01fb1db),LL(0x6d8cdd85,0x62636565),LL(0x641e476e,0x674fc478),LL(0xe28d244d,0xb39d16a5),LL(0xdbaa94dd,0x5fd5183a),LL(0x6b7fdde9,0xea66d862),L_(0x00000147), LL(0x62ab02a5,0x574c9d49),LL(0x88f7fd2b,0x31232213),LL(0x6c23d660,0xb2ca0c2c),LL(0xce3a1a6a,0x664a406b),LL(0x2ca19917,0x8f549744),LL(0x6f2fc149,0xab32866b),LL(0x41cbc3b0,0x7a277aea),LL(0x25557ca3,0x16026538),L_(0x000000f0), + LL(0x2a8dfc22,0x4fdb7562),LL(0x9be9e5c7,0x29bd5547),LL(0x548d39ec,0x29c79da4),LL(0xf3f7942d,0xc4bc1f5d),LL(0x948e1f79,0x34a7cecb),LL(0xb63229ed,0x76898793),LL(0x39c1a7d6,0xbe3b3419),LL(0x9157ad78,0x2801351b),L_(0x0000012f), LL(0xfece8891,0x59cbeae6),LL(0x85ddee3b,0x8140db30),LL(0xeeab1d34,0x41a033c2),LL(0xb676bba9,0x85703aaf),LL(0x23a9d8b6,0x35046b64),LL(0xb832a7c8,0x9e2475da),LL(0x5b8c259b,0xb51f8631),LL(0xdb18a6bb,0x53eb5dc8),L_(0x000001a2), + LL(0x85cafbb2,0x23cca37a),LL(0x57f26e36,0xc4d2ab36),LL(0x787ec793,0x520b9137),LL(0x436337f7,0xbcfb7906),LL(0x2caa7a0d,0x418cfaf2),LL(0x5a502d75,0x0ba14462),LL(0x066c6a13,0x1d083e40),LL(0xd21212f5,0xb9541e99),L_(0x000000eb), LL(0xe2ab22a5,0xa39384f4),LL(0x07cf7953,0xbdfbaff7),LL(0xaa5f9b05,0x1b083e95),LL(0x782626e8,0xfb350599),LL(0x06f421de,0xe92399d2),LL(0x415729d3,0x04ad8bd9),LL(0xcf103879,0x9370ad78),LL(0x766e0bc1,0xf2c002a0),L_(0x00000148), + LL(0xd8adb3ed,0xd6b8bb85),LL(0x9a142f9b,0x979dc67b),LL(0xfc51be0f,0xf84e32d8),LL(0xf9ccb118,0xf5b6ca36),LL(0x5e79aba7,0x3a900f56),LL(0xfcfd2df6,0x15163143),LL(0x22db9b75,0x5f85f9f1),LL(0xd886015e,0xe7c48af6),L_(0x000001f0), LL(0xd0dec7fa,0x5dcbc466),LL(0xc13f4daf,0x043aefcf),LL(0x613ac2b0,0x60909041),LL(0x9567d2ec,0xf4b79cb6),LL(0x57b5e5ef,0x8e04188e),LL(0x9dd05dcf,0x759c45aa),LL(0xcd8106c6,0xc6c633a7),LL(0x694b84b0,0xe7963345),L_(0x0000001e), + LL(0x68b4a3f3,0xfe8ed21f),LL(0xf39b982a,0xdf9459e0),LL(0xef033664,0x1245ad2f),LL(0x4c26109c,0x6578f9c3),LL(0x7b73834d,0x28e9fc09),LL(0x21a085c7,0x84bd7b31),LL(0x65666df5,0xd5585963),LL(0x9d7af58e,0xfd1e18ec),L_(0x000001e9), LL(0xaf6bc16e,0xe717df29),LL(0xf468848d,0x7c888dbb),LL(0xd747cd3b,0x51097e9d),LL(0xe70801a0,0x8bb9b824),LL(0x172bbff6,0xc27a8a5f),LL(0xf45d5351,0x402074f9),LL(0x0ba6fcc2,0xd7e5a578),LL(0xc1d4e050,0xcb9d2f1c),L_(0x000000eb), + LL(0x3b9d7737,0xf2b990fe),LL(0x1096bf3d,0x3b2d5eb8),LL(0xeb580e65,0xa2ad7396),LL(0xca4cfd31,0xcddd150b),LL(0x4cdae865,0x5cde916b),LL(0x6ffe74e3,0x1b6f19b5),LL(0x1e7dc0b2,0x333016e2),LL(0xc799d8bf,0x46cec318),L_(0x000000b1), LL(0xab36d519,0x9830acdb),LL(0xdd1e911c,0x1a0df89d),LL(0x891db580,0x646bbddd),LL(0xe25f1a5d,0xc4d27510),LL(0x10d55b0a,0x144af2f9),LL(0x5bcea08e,0x50da24a7),LL(0x7ae5f37d,0x9ad211e3),LL(0x73d37273,0xd9d5c417),L_(0x000000a2), + LL(0x2bd93615,0x785d4516),LL(0xd201173c,0x5cbe43f9),LL(0x6f813c93,0xfc65024c),LL(0x5174f5db,0xcbde45cf),LL(0x98aed5fb,0x29d4641e),LL(0xe15ff504,0xb6befd4a),LL(0x92a16838,0x3fb27455),LL(0x7017d508,0xa78ba07c),L_(0x000001cc), LL(0x3aef4cab,0xad9a35f0),LL(0x16e47d7b,0xbfe092d3),LL(0x75d728c5,0xd99290d8),LL(0x8ba65183,0xae8ed203),LL(0x9af2b287,0xe9db0d4e),LL(0x433a1079,0xe6c8ae7a),LL(0x21dd82ce,0x5486b431),LL(0xfbc30bb9,0x7775c8a8),L_(0x00000150), + LL(0x623589c4,0x92135986),LL(0xaae951c6,0x9a74fa72),LL(0x3dfd82d1,0x4bc31a1f),LL(0x060156b1,0x9ab6f26a),LL(0x8b245f24,0xa98e8084),LL(0x317596e1,0xc80c4dc3),LL(0x11d5e680,0xe262106e),LL(0xbee2a8d6,0x60234555),L_(0x000001ea), LL(0x90ed18c1,0x8b82b6cd),LL(0xa80d5059,0xb2182943),LL(0xa584e869,0xa8841e7d),LL(0x7e59ceee,0x74e1e538),LL(0x201d2b08,0x6d2519ec),LL(0x76d5cc62,0x41a115fc),LL(0xdedbfb6e,0xa6f152e5),LL(0x5c18feb7,0xd80d529e),L_(0x000000b3), + LL(0xecd211cd,0x3682bcf5),LL(0xe91e53c5,0x6ca16c30),LL(0x3355812c,0x6b8e8ce2),LL(0x18e076f5,0x77cbae05),LL(0x45a2864e,0xae50657d),LL(0x29b224b8,0x5b740476),LL(0x1853045f,0x9cd59d4a),LL(0x4fef40e2,0x6e774f0e),L_(0x00000092), LL(0x338e4f9d,0x0f66fd40),LL(0x87e39c23,0xd4b5406a),LL(0xb9d5824a,0x309845c7),LL(0x4567fe70,0x40e6539b),LL(0xc9f3a53e,0x4965ee0b),LL(0x0d799507,0x06d618a8),LL(0x28bea4e0,0x01fa0a00),LL(0x8b356252,0xb43cd562),L_(0x00000162), + LL(0xd82f0bd0,0x198a02d5),LL(0xcf78de3a,0xa89bcfff),LL(0x6931d65b,0x98eb3ac0),LL(0x204cbef2,0x796db40b),LL(0xdbd652c6,0x82883eda),LL(0x8c7c0479,0x6355b755),LL(0x3ccc26fb,0xb1589be6),LL(0xdcd445ae,0x8ce9a7eb),L_(0x00000063), LL(0x3ed1177d,0x34daeef1),LL(0x92e7ebd6,0x33e4d5b6),LL(0x252f990a,0x7af9fecc),LL(0xa16a7b3d,0x19533f3a),LL(0x07d26ab6,0xf0584373),LL(0xa41a7a2a,0xc7584589),LL(0x32ddecef,0xf36c6f17),LL(0xf2956cde,0xe47377e9),L_(0x000001ef), + LL(0xc14a919e,0x68fb10a1),LL(0xe2e1dbf7,0x1bce1a5b),LL(0x23f22cb2,0x865d95ed),LL(0x3d7b8ca9,0x9350d70c),LL(0x0559d55e,0xf39cff5a),LL(0x634be668,0x1f6fcd80),LL(0xbb740491,0x31d2120d),LL(0x7202a974,0x2efc5e17),L_(0x000001d7), LL(0x7fe1fd4a,0x6ff361af),LL(0xbd828851,0x26eff873),LL(0x96db8923,0x8d394d9b),LL(0x6a1cb060,0x3ebd8f2b),LL(0x2c56b043,0x71b88fe8),LL(0x91925e0f,0x39b0cfe1),LL(0xea28e59d,0xcb53dd25),LL(0x933a3cad,0x8fbf4361),L_(0x00000112), + LL(0x08433d22,0x13e495fa),LL(0x7698266f,0x51931514),LL(0xd385a184,0x7057cc40),LL(0x7fd1998f,0x8ffed935),LL(0x5d2e260a,0x55f9858d),LL(0x34fdc952,0x353e16aa),LL(0x3d6d1e16,0xd91adeda),LL(0x9e8895ec,0xa78987af),L_(0x00000106), LL(0x77ff974c,0x62e40103),LL(0x869a5ca3,0xc9ddcb20),LL(0x777bb6c1,0x0f3e3498),LL(0x4f97ec1c,0x18133992),LL(0xa7ddecae,0x1c9b2738),LL(0x280ea610,0xae01d593),LL(0xc9770c84,0x30145dcf),LL(0x7c4ed00d,0xa2a8b818),L_(0x00000107), + LL(0x9aa418d2,0xd4f005b4),LL(0x56eacf75,0xf05cca8e),LL(0x8a05a713,0x2382e841),LL(0x3f19077a,0x3c0079f4),LL(0xef823326,0x07e9f310),LL(0x71d13043,0x6311fb89),LL(0x0c6d6593,0x63ca3188),LL(0x0c592a1b,0xfce1253d),L_(0x00000042), LL(0x36fe1597,0x9089e935),LL(0x994e32d5,0xdc455b1d),LL(0x643872ac,0x914013f8),LL(0xac2eba70,0x35f0c433),LL(0x5a85e638,0x59b2430e),LL(0xa786ce7a,0x5225b772),LL(0x920543ca,0x51228731),LL(0x1e47ebe9,0xc56f0daf),L_(0x0000018f), + LL(0x3660052e,0x31ce7476),LL(0xe409da17,0x5b328da3),LL(0x098b5f71,0x607382a2),LL(0x51c3538d,0xc3ee7b06),LL(0xabf1dd7b,0x96d5eed9),LL(0xe8c0d16d,0x1a4ceb18),LL(0x3fe464dc,0x6b9f8f1e),LL(0x0c30d6fa,0x359d987d),L_(0x000000fa), LL(0x10803ed6,0x2947d098),LL(0xb97b5789,0x05d737b5),LL(0xcc27fc50,0x2087e2c1),LL(0x62d40feb,0xdd0d9606),LL(0xf37345b7,0x225ee555),LL(0x7f3858a7,0x9ae8d7c1),LL(0x0cf2ae73,0xdcf4e1aa),LL(0xee00ee77,0x649e41ec),L_(0x00000012), +}, +/* digit=97 base_pwr=2^485 */ +{ + LL(0xd619b611,0x808de672),LL(0x8326922a,0x156260ea),LL(0x1a0841b0,0x63e3e317),LL(0xacb0f8a9,0x806aeb44),LL(0x33483737,0xad9d8a14),LL(0x761a3419,0xbffd26bd),LL(0x2e7a343f,0x6d361b6d),LL(0x4d86e32c,0xf433219c),L_(0x0000003e), LL(0x22d4f25e,0x1f25620f),LL(0xd5c03d38,0x3a87f67d),LL(0x80f73464,0xe876505e),LL(0xe4906c5e,0x491baac4),LL(0x178a012b,0x93e07deb),LL(0x0f735b86,0xd75fad06),LL(0x76ce5dd8,0xc97cb185),LL(0xf5dd4cd9,0x634bbb55),L_(0x000000bc), + LL(0x4a6d5dde,0x37703361),LL(0xc5f2fac1,0x4dee5fdd),LL(0xe014aa4b,0x2218fde8),LL(0xa684a9b7,0x0e229612),LL(0x1d9b66c1,0x7cb5b99f),LL(0x1796c130,0x71c7eff0),LL(0xc0871522,0x27930b1e),LL(0xd19f171d,0x3091f21a),L_(0x000001d5), LL(0x4172f540,0xa74c873e),LL(0xbd512368,0xbc31a6ec),LL(0xd3ea21d4,0x62eff689),LL(0xbd43a95f,0x73a33474),LL(0x1413507c,0xf88fa97a),LL(0xb01846ef,0x8f06b4d3),LL(0xfbac8f6a,0xdc2a3015),LL(0x159ddd58,0x7b911f1a),L_(0x0000001f), + LL(0x5f77e97a,0x2fe873b0),LL(0x5ebf3c8d,0x32fe371d),LL(0x5b9ca7cc,0xc245b054),LL(0x2658798c,0xeaf83f8b),LL(0xf09afde6,0x761d87bd),LL(0x29e1b970,0xa4fd48a5),LL(0x1501c97b,0x5ab0a100),LL(0x1dca9665,0x0ec7beee),L_(0x0000002f), LL(0xc7a92892,0x28296b82),LL(0x171dfdb2,0x171bb70c),LL(0x1dac3a3a,0xad9a13af),LL(0xe21b7ea6,0x1fe361dd),LL(0x2f8b8125,0xccea9acd),LL(0xe8df3c1e,0xa4b48480),LL(0x8a5f495c,0xb8ecc783),LL(0x07fd225c,0xbc6bffc7),L_(0x00000054), + LL(0xb807b638,0x84cef36a),LL(0xcdf4c999,0x5f8d7040),LL(0xc211953a,0xfaefc5ed),LL(0x563ab4c0,0xa17066a1),LL(0x0c339a5c,0xafb2c094),LL(0x517a5667,0xb135b1e8),LL(0x3d2a94a0,0x4526e2ec),LL(0xd9185e4d,0x3c05d493),L_(0x000001b5), LL(0x676f8435,0x2fc5ced3),LL(0xff470fab,0x21ddb195),LL(0xed29f4a2,0x2d94f5fe),LL(0x69f0868b,0xaf8fcc50),LL(0x8631be3c,0x3dcfc141),LL(0x43a07062,0x1c9d9989),LL(0xbafa5f73,0x1cc4a069),LL(0xe1c5c56c,0xf502e626),L_(0x00000082), + LL(0xeb28400f,0xaaec0dfb),LL(0xb5f2559e,0x37f92069),LL(0xf82c9e25,0xde3d65ad),LL(0xca0987ef,0x52dba2b0),LL(0x110760de,0x6f1e9d7b),LL(0xec3c5a7a,0xb68a52e5),LL(0xe6b61974,0x47ef0970),LL(0xa12dbde7,0x952831ff),L_(0x000000e3), LL(0x193e5166,0x2a4c3695),LL(0x2be66d3f,0x90213a6f),LL(0xb1043636,0xecffb364),LL(0x0ea64838,0xaf651989),LL(0x059f3995,0xd04bda10),LL(0x8aa19045,0xfff61b8d),LL(0x76712e84,0xb77b5575),LL(0x6970c5d5,0xfb11370a),L_(0x0000011e), + LL(0x472b3293,0xe37454a0),LL(0x644b36eb,0x2bc89a6d),LL(0xe5b95fef,0x705a9c84),LL(0xc8e9527d,0x6ad037b8),LL(0xc306c56f,0xa3d9152e),LL(0x99bdd442,0x3acd8434),LL(0xd2e50d9f,0xfb35013e),LL(0x10c1418e,0xa1aaf42a),L_(0x000001ea), LL(0xd3620e3c,0x301c9fea),LL(0xa12968d1,0xf9c8c259),LL(0x796a5743,0x1c0237b8),LL(0x92290293,0x56baf809),LL(0xb04d2746,0x81ca3b50),LL(0x93109cb5,0xd70a42b1),LL(0x1ffad7c2,0x829c0f93),LL(0x90fb8081,0x00473bdc),L_(0x00000185), + LL(0xec7bc5fd,0x78a1fc22),LL(0x1e0d9fae,0xfe3efcad),LL(0x7975003b,0x1a1d9870),LL(0x5a8555e6,0x08399c40),LL(0x13808c98,0x1f10285e),LL(0xf7ae407f,0x6b16e9b6),LL(0x95f47114,0x5ef970a5),LL(0x42ba4017,0x58f89d1a),L_(0x000000be), LL(0x09085b73,0xb52c0fec),LL(0x68533122,0xc427c0ed),LL(0xd8c2fad9,0xbd46322d),LL(0x870ca81f,0xccd1cd67),LL(0xab6ba984,0x5510a68c),LL(0x6f619ce9,0x2516fdb1),LL(0xd13d0213,0x89ce2a78),LL(0xd4ddba71,0x33ef2f0f),L_(0x000000d6), + LL(0x2d019ecd,0xd29edf28),LL(0x8e335e18,0xe046e99e),LL(0x4ace8ce0,0x72c0503a),LL(0x42f01d0f,0x9c6d09e2),LL(0xfcb4567e,0x3998b6c2),LL(0x0686ceb1,0x91430be4),LL(0xb8fca6af,0x2236ef5d),LL(0x01c77e85,0x718e1a29),L_(0x000001a3), LL(0xab427d9a,0xab5ae430),LL(0xa843a1b6,0x025f63d8),LL(0xc9500fb6,0xd803e788),LL(0xfb7b9cb8,0xea023d9b),LL(0xcdad70fc,0x803f3ec5),LL(0xa7e50d4c,0x9c07188d),LL(0x9eb540fd,0x822ee2af),LL(0x0d14ab57,0xaff12ba0),L_(0x00000174), + LL(0x0f113d06,0x8230400e),LL(0xed3531cf,0x20fd0e05),LL(0x442851e2,0xd6869a7e),LL(0x1568acb2,0xae871699),LL(0xd7c29d8f,0xad380219),LL(0x512e57e5,0x17e73a2a),LL(0x0239d8b5,0xff1100de),LL(0xa4cc3700,0x3960bc57),L_(0x000000b5), LL(0xd0f458fc,0xec6e136b),LL(0x7a2013e5,0xb3934a8d),LL(0xdeac099e,0x7585325a),LL(0xc5fcf6e8,0xa4aae387),LL(0x73e275f5,0xe0a1bb17),LL(0xc599d358,0x78aeadce),LL(0x5e5ee001,0xf20a237c),LL(0xbc670ce3,0xc755c2ed),L_(0x00000056), + LL(0x980d56e7,0x9e1ae8f1),LL(0xb8a1be4d,0xec417dcf),LL(0xa0d53ddd,0x13c7c494),LL(0x565a5779,0xe8460798),LL(0x4157d87f,0x865e6ed9),LL(0x5fcc1adb,0x43eb5613),LL(0xff942117,0xf8951241),LL(0x65dffe8f,0xbc9c1cd1),L_(0x00000069), LL(0xb27b24a4,0x9c6c39b5),LL(0xdc72853e,0x60f36e47),LL(0x8941b5fe,0x036e5482),LL(0xd9f274e7,0x2bbb4450),LL(0xd2f8bf2a,0x900ba078),LL(0x48bef6a0,0x9a34b9c0),LL(0x548c40a6,0xa419ecbd),LL(0x3d7bc93f,0x5929867e),L_(0x000000b9), + LL(0xe3977001,0x2d5481cb),LL(0x900dd0cf,0x94bad4ae),LL(0x06d3c0a0,0xbee25614),LL(0x2d0029ba,0x4f1ce8bf),LL(0x7ae14d24,0x12c5aff4),LL(0xcb8bd567,0xd5130b01),LL(0xa1cb296e,0x13ab0e47),LL(0x287ae4a9,0x1c30c115),L_(0x000001e6), LL(0xdf0986d0,0x91cfcc0a),LL(0x9e6287d6,0xf8cffb98),LL(0x0a5d81d7,0x6e40495f),LL(0xfe24065c,0x4ac91688),LL(0x6ef91697,0x0bce1292),LL(0xfa7c3394,0x082d9558),LL(0x334da954,0x0d5bbff2),LL(0x41fa885a,0x6904d684),L_(0x0000009c), + LL(0x88636e5f,0x30ed1da7),LL(0x34a6a52a,0x610afcab),LL(0x9193baed,0x00ab78dc),LL(0x40598146,0x40d27bbd),LL(0xfc2510b3,0xdf263e04),LL(0x2c222200,0x4f8a34f4),LL(0xe2fa7ec8,0x7ecddf41),LL(0xf5c8a69f,0xb69fa963),L_(0x00000065), LL(0xdd29b7e1,0xde38eab5),LL(0x1dc06ecf,0xbce53abf),LL(0x287aff4f,0x123a0ff7),LL(0x865d5801,0x9bc53dd9),LL(0x7f2760b0,0xf4d19de7),LL(0x2617ed79,0x59b16830),LL(0xfb36b9bb,0x86d6b37c),LL(0xc68164d5,0x3ce542b7),L_(0x000001d5), + LL(0x83343459,0x785c9888),LL(0xd5898c8f,0x0f97f6b8),LL(0xa5e5e010,0x25a6849d),LL(0xdb272a5b,0x5b826b6b),LL(0xf1d7d775,0x8319ab20),LL(0x81fab2fc,0x051b545f),LL(0x13836d82,0xf3f0508b),LL(0x79a2e73a,0xc87d4ab2),L_(0x00000089), LL(0xe7797e18,0x9d6fea08),LL(0x0b7f377d,0x285c3784),LL(0x13a96505,0x5e5f0355),LL(0x80e5351a,0x92ff2d7f),LL(0xa4907b9b,0xf478e9fa),LL(0xec7c1179,0xd90b6dba),LL(0xd2c36f50,0xbe1d562a),LL(0x797351a1,0xf65a7374),L_(0x000001a1), + LL(0x6dcfe3ad,0x8caa24b9),LL(0xdad4ac58,0xe55e016b),LL(0x42a35993,0x04d4925f),LL(0xf4d85232,0x8c2cb262),LL(0x654bec90,0x44564228),LL(0xd9274933,0x58349da0),LL(0x55dc684a,0xb18184ce),LL(0xe08bebb4,0xe4015bbc),L_(0x0000006e), LL(0xa2f8db31,0xcea81cd2),LL(0xb89f906a,0x5a1b62b0),LL(0xc0a88adc,0x46897bd0),LL(0x3422a9ae,0x6bfb70df),LL(0x0d20f649,0x113b8338),LL(0x197424dc,0xf43ab4e9),LL(0x11c7f33e,0xc17b56d7),LL(0x3e3697c4,0xf0f21e9a),L_(0x00000141), + LL(0x0bbb8295,0xb3c8d4e4),LL(0x3221af32,0x786f9cb5),LL(0xef78da7b,0x6228aab0),LL(0x460bf9aa,0x4fd179a4),LL(0xf900af46,0x2bd49daa),LL(0x42fb7206,0xcadd2655),LL(0xfa16e111,0x992a0506),LL(0x4726c9f4,0xbd04e990),L_(0x000001c5), LL(0x8281f418,0xc3ac19be),LL(0xeed5408d,0xfa218d10),LL(0x2bf29af8,0x2a7befd5),LL(0x3b0d28b4,0xeabb7643),LL(0x28d2a823,0xfa48a66e),LL(0x34709b21,0x92c650bc),LL(0xdf1a83ea,0x261706b5),LL(0xa9a5f258,0xbeb0a33b),L_(0x00000019), + LL(0xe0952a3f,0xd53c20db),LL(0xb6013f7f,0x09d4a480),LL(0x447348d1,0xcb6a7da1),LL(0xd8bfe6fe,0x64e8c529),LL(0xa6067265,0x9034045f),LL(0xa8df68fa,0xff3f3ee2),LL(0x1796dbc7,0xdedc2792),LL(0xe9a130fe,0x4c3f368a),L_(0x000001e2), LL(0x9eed66d4,0x792961eb),LL(0xed55f272,0x9b014919),LL(0x0068193a,0x44cb0bf8),LL(0x32ef3174,0xe22227ee),LL(0x4cb4a896,0x147c8b85),LL(0xc6a73b28,0x2ed1bf6d),LL(0x6804296e,0x77be001d),LL(0x223e6f8a,0x89b143ab),L_(0x0000004c), +}, +/* digit=98 base_pwr=2^490 */ +{ + LL(0x8ea1f1fa,0xec0e9921),LL(0x21044500,0xcba88ccf),LL(0x0c873630,0x6fd4e4b8),LL(0x45764f80,0x056645dd),LL(0x4551a9a7,0x72ed8739),LL(0x025ba6b1,0xa9a78987),LL(0xdd01b45f,0x1f9f1355),LL(0xd2ccea3a,0x807cbab8),L_(0x00000192), LL(0xe24e1198,0x4c6c96e8),LL(0x1a51e813,0x57065d92),LL(0x2ab97599,0xa89e1baa),LL(0xabc4035c,0x057c2aaf),LL(0x1a6716df,0x9c0890aa),LL(0xf802387d,0xc7786bd3),LL(0xa39383e5,0x1f627056),LL(0x00601e4e,0xf2265779),L_(0x00000096), + LL(0x1b109b21,0xd4e8955d),LL(0xe1d0f381,0x45a79e1d),LL(0x6407a6cf,0xe689a76d),LL(0x407f2393,0xd92aed2a),LL(0xac261bd3,0x95547cc6),LL(0x9e62fcac,0x49835e0b),LL(0x1e291077,0xdde8f908),LL(0x7b3d6780,0xc4cab77f),L_(0x000001c5), LL(0xf3dc82cd,0xbde052d3),LL(0xaa1aeecd,0x958c939c),LL(0x24153092,0xca5c0f7b),LL(0x5c0c11b7,0xc9284796),LL(0x3698d827,0xd732af64),LL(0x351c0ba1,0xa3ee0367),LL(0x1b1bf491,0xec2302cf),LL(0xafdf3514,0x4436d640),L_(0x0000014c), + LL(0x1e921eea,0xe09f3da3),LL(0xb7ed8d41,0x97fc0836),LL(0x33451dcc,0x1b62ac0b),LL(0x4bb0f328,0xc7985f30),LL(0x76f68d69,0x7e5bf130),LL(0xa8fcc12a,0x87f28f61),LL(0x0c13fc90,0x097e8f18),LL(0x9299a913,0xec6104d5),L_(0x00000150), LL(0xa95b34c6,0xf8ef488b),LL(0x2c0a7e4f,0x94b33bee),LL(0x5db54ad3,0x4a72bd81),LL(0x0abb0c63,0x57fa905b),LL(0xa7b05810,0x98b0da0b),LL(0xc18c2e82,0xa6507965),LL(0xd53207a1,0xba323d2e),LL(0x1a96c29e,0xe70d8f52),L_(0x000001e6), + LL(0x7179d881,0xc54265bd),LL(0x14b97128,0xe0b08320),LL(0xfd3dafdf,0xb3fd6699),LL(0xb8bb1956,0x416a87bb),LL(0x038f8691,0x01dd4344),LL(0x88826c84,0x7456566c),LL(0x07a8a4b7,0xb2fca59f),LL(0x037671e1,0x797dc52a),L_(0x00000000), LL(0xe8d7f705,0x5d7843bb),LL(0xee9b4c46,0xfa39c4f9),LL(0x303b1652,0xc4a55ae2),LL(0xc15ae7c4,0x3ccdcb67),LL(0xda8ac526,0x7a17fd06),LL(0x8d1d1e92,0x685ac10d),LL(0x5bfc6232,0x048bbb8e),LL(0x233162cd,0xc2cffebb),L_(0x00000111), + LL(0x789c58d4,0x20c13569),LL(0x9b91ab1e,0x14810705),LL(0x032808d4,0x6428e5a7),LL(0xdd56117a,0xb86a6737),LL(0x9ed920a9,0x32ca9ded),LL(0x46d45de0,0x0898b533),LL(0xaef720c0,0xc4b5cbd6),LL(0xe8b625d5,0xd262cadb),L_(0x00000025), LL(0x69824bf0,0xbe07a63a),LL(0xae8c0455,0xc0c992ba),LL(0x56ade4e3,0xd8c4dd74),LL(0xaddf367e,0x1fb487a3),LL(0x10d03d26,0x978961e7),LL(0xced02543,0xb1fb8d4a),LL(0xd9cb94bb,0x4067c3be),LL(0xfd0c7063,0x1e63aa4d),L_(0x0000003e), + LL(0xc18c25f0,0x43a818af),LL(0x8e882098,0xa14d3397),LL(0x2df8f9ff,0xfba08f0f),LL(0xc3139e9a,0xd6f4162c),LL(0xd35b42ed,0xddc9743c),LL(0xa29eeda8,0xeaef65fa),LL(0x1d1cf761,0xc4cffc87),LL(0xf5204083,0x9c04512b),L_(0x000000af), LL(0x76c92be0,0xcce1fc0e),LL(0x4ca92fa2,0x0756de13),LL(0x7ef7ab66,0x6b218d95),LL(0xa4befba4,0xec5df862),LL(0x028018d1,0xb0fb4797),LL(0x0fba684f,0xbb1872b1),LL(0x035fcdb9,0x727d62c3),LL(0xa85f1754,0x52c190b4),L_(0x000001a0), + LL(0x62904b65,0x8c02d54a),LL(0xa33c5b35,0x9d3a0d5a),LL(0xda74fd32,0xcf0e2fac),LL(0xdf27160e,0xa9cf0042),LL(0xce44dc1f,0xf9b4e2f6),LL(0x8815ba75,0x71f7406a),LL(0x5d29fed7,0xba78d604),LL(0x1b44fac2,0xa544aa8d),L_(0x000001da), LL(0x44983ea1,0x4f2a1a98),LL(0xb052a60b,0x2ee09590),LL(0xfd68dd3b,0xf82abd62),LL(0x4cd7b68f,0x3747e4a5),LL(0xa7a82c3e,0x6580fff5),LL(0xfc1c77a5,0x878185a1),LL(0x29848ebd,0x3507cf8f),LL(0xe376e805,0x3d153708),L_(0x000000fa), + LL(0xec3c1780,0xd12cb202),LL(0xde81ad92,0x7dfd0285),LL(0xb71b7749,0x0c150a03),LL(0xf597a8a1,0xe99f4ad3),LL(0xaef51dbb,0x1f4533b0),LL(0x838ed493,0xbcf13b27),LL(0xffc95a8e,0x5623ddf8),LL(0x2b2cefcf,0x37c16683),L_(0x00000107), LL(0xda2ff7e4,0x8ce740d8),LL(0xf3d3ab04,0xd03ed624),LL(0x376415ce,0x76391c7d),LL(0x22ffbe56,0x671ffe7b),LL(0xcc5f4981,0x90390438),LL(0xae289dd4,0xef0984a5),LL(0xf9a1f5bb,0x41c66528),LL(0x3eb05c49,0xef77ff07),L_(0x0000003a), + LL(0x75a1acd6,0xdc003b87),LL(0x913da2c9,0x7357222f),LL(0xb56a4216,0x44f79a9a),LL(0x435f9dd6,0x6316da1e),LL(0x76bee0c1,0x44a0a348),LL(0x528570a1,0x1fc2528a),LL(0x9e402d88,0xadaf6615),LL(0x23fd690f,0x1b05eafc),L_(0x00000050), LL(0x66a31ca1,0x22ceb0f5),LL(0x9817f70b,0xb1910295),LL(0x586cc9da,0xfd424885),LL(0x92631348,0x902c218d),LL(0x2d6b4b6b,0x3b06ab9d),LL(0xf6ce2b8d,0xc2ef9db4),LL(0x5440a618,0x86f795ee),LL(0xe7115329,0x241af150),L_(0x0000019d), + LL(0x9e7167f7,0xb84d399a),LL(0x5d1b603b,0x6e75095d),LL(0x3ebd519c,0x0c38a4d8),LL(0x5a2e8ab6,0x703ee9c9),LL(0xbe621b2f,0x46425097),LL(0xeda0425f,0x3bda2722),LL(0x7eaff2bd,0xc82eaa59),LL(0xddb8e21a,0x9f181562),L_(0x0000011b), LL(0xa357af4a,0x319323ed),LL(0xf55ade52,0x1195febd),LL(0x72cc0544,0xa5494291),LL(0x34dc9234,0xaa005164),LL(0x2b24e83a,0x2e6ec50c),LL(0x61a67644,0x300b585a),LL(0x2a2cce42,0x251bf8fe),LL(0xc53eb03f,0xa53e93a0),L_(0x0000007c), + LL(0x7d64ddd7,0xbd450c1b),LL(0xb6233906,0xf8cf8ce0),LL(0x2f163b01,0x37f9bc73),LL(0x121c5a4d,0x74a3b3e9),LL(0x84c581f0,0xd2aa3a2e),LL(0xa16b9ae6,0x7a258259),LL(0x5182e300,0x6d279587),LL(0x3b163221,0x9054a8d4),L_(0x00000100), LL(0xa5941c9e,0x650238b5),LL(0xbdfac6cd,0xbc313548),LL(0x60bb5887,0x98e5a28f),LL(0x3b8aace3,0xb0c9ed3d),LL(0x1f5ded63,0x943fdf61),LL(0x3ad1b6fe,0x292fee9d),LL(0x3bea9f61,0x765fb8a8),LL(0xb3aff102,0x1c05be97),L_(0x0000005e), + LL(0xc6900b62,0xdf604a9b),LL(0xe5f51ce9,0xad97f878),LL(0xb763f98c,0x89d3ab54),LL(0x6fef5a13,0x3d0efdef),LL(0xdf2543ab,0x39be5cf0),LL(0x51869676,0xd8322a0d),LL(0x34850193,0x90477611),LL(0xe0860abf,0xf04b3d8d),L_(0x000000b4), LL(0xa5518941,0x65e57c44),LL(0xa66238e0,0x78a12a3f),LL(0xd140af78,0x55dcc858),LL(0x65fde14d,0xc7b391cc),LL(0x4d882561,0x2d7dbf32),LL(0xaa74e78f,0x03f85d09),LL(0xed166a45,0x7ad860c8),LL(0xe6da0c2a,0x8d8fe387),L_(0x00000004), + LL(0xb38db64f,0x06980a45),LL(0xdae5a808,0xcd56237c),LL(0xdb2a4bfb,0x1628aed0),LL(0x029fee0a,0x5baf2e6b),LL(0xcfe94b4b,0xbaa05917),LL(0x186a18d2,0x6fb7aa6f),LL(0x3e611766,0x97f81882),LL(0x759b437f,0x25dc9d58),L_(0x000000c3), LL(0x4bf0133d,0x16ed73fe),LL(0x1dbc5e5f,0xae04984f),LL(0xb2380921,0x00f6d531),LL(0x941b93a0,0x9956e547),LL(0xafda37c5,0xbcd796ef),LL(0xeb23c73c,0xd18e7739),LL(0xec321455,0x9f3b6f4a),LL(0xc9846e98,0x7c09f2f9),L_(0x0000010b), + LL(0xe0076809,0x447d7aeb),LL(0x4ec21998,0x691aa304),LL(0x062e1539,0xd6b055f4),LL(0x350b4c67,0x310e0e47),LL(0xeee31b24,0xe16697e6),LL(0x24a9c93a,0xc742c710),LL(0x50e8a296,0x5f791c6d),LL(0x511ff4a6,0x4536286d),L_(0x00000179), LL(0xc52ae1e0,0x36a695b3),LL(0x301dfa2f,0x07145edb),LL(0x89ff6d58,0xb1a2232a),LL(0xd04785f8,0x27854372),LL(0x37e21f65,0x82b68a6c),LL(0x56a575ee,0xb3063755),LL(0x45ea52c0,0x0e5cba73),LL(0x1f5a3458,0xb3b90431),L_(0x00000131), + LL(0xc80f270b,0x05a677e3),LL(0x7473a30c,0x5a28a98f),LL(0x8039064e,0x69a1890c),LL(0x559f0687,0xdf1716eb),LL(0x5a68dd8c,0x216c64b2),LL(0x665fa083,0x89b49b44),LL(0x27c0f780,0x952e61c5),LL(0x5e57e0f3,0xc9f22b25),L_(0x0000015f), LL(0x96d8f8cb,0x9de5f532),LL(0xa33b1f2d,0x6ef509f5),LL(0xd526630e,0x80ca2834),LL(0x2e72073f,0x551bac6e),LL(0x8bdc5409,0xa93f6103),LL(0x74c46ebb,0x78de2a49),LL(0xe616b99b,0xbd4c9f5c),LL(0x5a4f27fb,0x9a70865d),L_(0x000001c4), + LL(0x7162a8e4,0x66505ddc),LL(0x5ed0deab,0x89dc51fb),LL(0x5e972cc6,0xb69dc78b),LL(0x0c6e495f,0x3f182669),LL(0x96d605ca,0x85f61868),LL(0xf6678928,0xedfbfd32),LL(0x863f96f8,0xdece22e8),LL(0x64e644e5,0xf857a4d5),L_(0x000001b7), LL(0xeebfc5de,0x55691ddb),LL(0x1566a700,0x7fa43590),LL(0xe1f4e606,0x796a672c),LL(0x30886e62,0xe5ee14cf),LL(0x40aacab4,0x9b327c1a),LL(0x3294bd68,0x2c002fed),LL(0x103e5699,0xf8494f59),LL(0x9eb1323d,0x51fec2bb),L_(0x0000017b), +}, +/* digit=99 base_pwr=2^495 */ +{ + LL(0xaea3c081,0xcb769c73),LL(0xa9593240,0xb057cdf9),LL(0x4e8217f3,0x220054ab),LL(0x34dceca2,0x5ba1c2a7),LL(0x22b719c9,0x16500d13),LL(0x1b436038,0x0ba1ec57),LL(0xf76e87cb,0x59db2c76),LL(0x77c59385,0xbe033b58),L_(0x00000197), LL(0xeb075ca6,0xddb6a77f),LL(0xc6a6cde3,0x8f578d9c),LL(0xe4987253,0xeaf37819),LL(0xa10e469f,0xdc9c48cd),LL(0x0f98832d,0x51a6e545),LL(0xbf05ea5f,0x195d2d31),LL(0x75cd216a,0x89987c43),LL(0xd18007e6,0x358f3e07),L_(0x000000bc), + LL(0xf2770c43,0xd66a73f6),LL(0x68ca281c,0xa08670f9),LL(0x827efca6,0x180e8f32),LL(0xeac3a96b,0x9979b757),LL(0xbff7df80,0x2d9223bf),LL(0x166015fc,0x30d747dd),LL(0x5475a887,0x9ea9d126),LL(0xfbce1622,0x23756de3),L_(0x0000016d), LL(0xee27c6e9,0xa8ed537b),LL(0xe46c7c15,0x6d7df943),LL(0x4b3f8765,0x335be530),LL(0xdb8a9213,0xcb0ee208),LL(0xb61ee376,0xa4f5fc16),LL(0x4ee85495,0x2d47c111),LL(0x53ced62c,0x453ad352),LL(0xaf641c92,0xe1a21d73),L_(0x000001e4), + LL(0x45292063,0x515c16f0),LL(0xa0b8ef31,0x11c31db7),LL(0x6aca4236,0xa62abc90),LL(0xc862474f,0x94eec3da),LL(0x600cabaf,0x3cb82e64),LL(0xec07e4a3,0x3c98aa82),LL(0xef67e3ea,0x548e4dc2),LL(0x3817b7a5,0x6160dfbe),L_(0x000001b0), LL(0xd5114978,0x212ed3d8),LL(0xa341dfe1,0x71cd3579),LL(0x96070d42,0x9ade2ce0),LL(0x0d16c811,0x6ffd05f0),LL(0x1f2ea906,0x4add5623),LL(0x9034240f,0x871a6489),LL(0x92dc3317,0xd71bf3b7),LL(0xd6ec77d9,0x3faf4d88),L_(0x0000010a), + LL(0xc9de102a,0xab483ff2),LL(0x0cb9492b,0x1910717f),LL(0x1999673c,0x5ba40ad7),LL(0x61f5c7a7,0xec8c1ec8),LL(0x7a954022,0x87870445),LL(0xab6d023c,0x607c1194),LL(0xdaf5008c,0x53612330),LL(0x4ad39492,0x5bf20a93),L_(0x000001ab), LL(0x1b16277b,0xab8ed330),LL(0x045574d7,0xf38e3b31),LL(0xed11cb44,0xab10bb4e),LL(0xa511af67,0x33cee10c),LL(0x9fe7c1d0,0x1549874c),LL(0x6999489f,0xa85b392d),LL(0xfcfe4a15,0x3684decf),LL(0xb3b006a1,0xbaefda3e),L_(0x000001b8), + LL(0x8b50487e,0x3d2bc261),LL(0x1ee7f1c9,0xd8d2c223),LL(0x25894a88,0x1159870b),LL(0x106d0fe5,0xac7070a4),LL(0x37cd1eb7,0x45edd566),LL(0xfcc105e8,0x0d87aaf2),LL(0xbbc54886,0x650d534b),LL(0x4c68c1c6,0xf8b73f4b),L_(0x00000118), LL(0xdb0789c6,0x1c67e752),LL(0x9fdf5e33,0xda66e59f),LL(0x1506a29f,0x04eb7efc),LL(0x566aa91a,0xaf0c681f),LL(0x41ad74ab,0xcd6fd019),LL(0xa0e6609f,0x90d32f02),LL(0xf9f03394,0xc3f5d1da),LL(0xbd5dbcf1,0xa63c99d2),L_(0x0000015c), + LL(0xe7306a80,0x94e82cbf),LL(0x52832eb4,0x61b4102e),LL(0xb381c8b4,0x7f0afbca),LL(0xf1ba6e87,0x8482ae88),LL(0xc8cc076b,0xd709eb28),LL(0x5fc8e5ce,0x0c640cd4),LL(0x1363d1cf,0x6be8f78b),LL(0x4993a63d,0x7a8e7f6a),L_(0x00000140), LL(0x088bf641,0x1bfd703c),LL(0xb3415df0,0x8b57f708),LL(0xf82eeb2c,0x407aa69d),LL(0xa723ed35,0x9767c6b4),LL(0x4dbc3f44,0x52e1a818),LL(0xdffc3e96,0xad89d25e),LL(0xe8855e29,0x89f2e493),LL(0xb2c695a8,0xae2a995a),L_(0x0000005d), + LL(0x32b63b4e,0x7948d6db),LL(0x1bf35a68,0x6953ece3),LL(0x2e4f6945,0x5f0ffde7),LL(0x8e48e233,0x45b68e1d),LL(0x805943a8,0x7c03271d),LL(0x83acacfb,0x136c96e1),LL(0x20b340c8,0xb32c48cc),LL(0xbf7ec9c0,0x9a5cdcd3),L_(0x0000013c), LL(0x14fd95e6,0xeda9d905),LL(0x02288f5d,0x6d5bb5e0),LL(0xe250809d,0x26841f8e),LL(0x3ede31ca,0x5b8a74f6),LL(0x941707b2,0xcd744281),LL(0xf31b5a51,0xcb81c384),LL(0xa2b751ad,0x1c7d45f0),LL(0x98cd14ff,0x0b61414f),L_(0x000000eb), + LL(0x3dacf223,0x49c300d6),LL(0x149cc932,0x984e1f84),LL(0x4f71e87a,0xa635f884),LL(0x2ebebead,0xc51f4894),LL(0x8d815dca,0xb76c6b87),LL(0x60dede95,0xc3f25874),LL(0x83c91cf8,0x53753878),LL(0x6d13e9be,0x4ce987a5),L_(0x0000016d), LL(0x1675f42e,0x22fb2015),LL(0x4bf1c2d6,0x8bc4abf5),LL(0x22da7f9e,0xe7b83f3a),LL(0xe42051b0,0xeda536a6),LL(0x9d89d573,0x3ce8431a),LL(0x64d23c5a,0x3eec2b7a),LL(0x07a6be7b,0xb5fb43a0),LL(0x5b672919,0x4a7d1800),L_(0x00000045), + LL(0x98c6c900,0x54bf1abe),LL(0x835f5200,0x88be0ac1),LL(0x80a69454,0x37a520fe),LL(0x1ae181ec,0xfbf51fae),LL(0x1dbbcb25,0xe0a144d5),LL(0x7481d4f7,0xbb7cdca1),LL(0x89f680f7,0x0d5abe7d),LL(0xb4b624a0,0x391425d4),L_(0x000000f3), LL(0xe424aa1c,0xb4188e07),LL(0xbfd1f50f,0x6575b3b7),LL(0xa43201e2,0xbba2a525),LL(0xe0fef193,0xc9408771),LL(0x2d5a89d3,0x5fad41dc),LL(0x95a6705b,0x7d9dc257),LL(0x9020f8bb,0x290e4eb8),LL(0xfbd17a63,0xbb41e71c),L_(0x000000d2), + LL(0x29e97a00,0x929f484a),LL(0x0aa411ba,0x72a995e9),LL(0x16fc135a,0xc8dd8a3a),LL(0x2226cfa3,0xefeed6df),LL(0xebb1a266,0xbe66eb40),LL(0xd15ad7b0,0x9e390f8a),LL(0x0c3a1992,0x4d13a05e),LL(0xd151e340,0xcf393bac),L_(0x00000175), LL(0x4d898149,0x956cdbeb),LL(0x4f6ce102,0x1a20db88),LL(0x3138d132,0x4bd065b9),LL(0x3956528c,0x082878ee),LL(0x1ab3833d,0xc2946565),LL(0x49e6b0dc,0xe955cb4e),LL(0x10248d30,0x1ae9cc37),LL(0x9e6e01a5,0x5567eab8),L_(0x000000fc), + LL(0x17fc3dfc,0x263e83bd),LL(0x531fddd1,0x56ab0f10),LL(0x11105bea,0xe11b8ec7),LL(0x98797be3,0x1992abc2),LL(0xec87b621,0x2f8db083),LL(0x8d258c0b,0xb3d171f4),LL(0xac2ced2a,0xd1cb21ab),LL(0x7bcca55e,0x47bc4dad),L_(0x0000000d), LL(0xe7fc240a,0xf1f3098d),LL(0xb97a56f7,0x30359457),LL(0x13b63e78,0x5c0291e4),LL(0x0560b59b,0xfd66b1ed),LL(0xffcd1e35,0xab62195d),LL(0xa68ddbd9,0x5e1a88f2),LL(0xc8f7a10f,0x5805f677),LL(0xc770a044,0x145b476e),L_(0x00000166), + LL(0x072f54a0,0xfec59218),LL(0xbad5f014,0x29cb3195),LL(0xdeabd554,0xfb9c1406),LL(0x8cab2ab5,0xf39524ff),LL(0x1480bd6c,0x6fbb57c0),LL(0xc932f537,0x34f118cb),LL(0x9e4e5da0,0x6eb8d83c),LL(0xa6fb16c3,0xc80fc4ea),L_(0x00000048), LL(0x1e1cfe69,0xbe668aa1),LL(0x614afa98,0x9a412d4f),LL(0x4cadab47,0xb94d7822),LL(0x933864b0,0x51053a74),LL(0x424e5f26,0x3dd43fe6),LL(0x600bdaac,0xf8a04f2c),LL(0xc0b432cc,0x4257110e),LL(0x2f4d8257,0x58edc3e1),L_(0x0000004e), + LL(0x2d89ca71,0x42ad308f),LL(0x07b9420d,0xf2ff228d),LL(0xf800adda,0x959a36a9),LL(0xa755b758,0xe791f71f),LL(0x06570844,0xc9aeec3a),LL(0x2525c1b6,0xf99b3c09),LL(0xfae920c4,0x93e1e24e),LL(0x54cdd224,0x4a6949cb),L_(0x00000108), LL(0xbd54c1b3,0xc1192578),LL(0xf0af3d86,0x042c14ae),LL(0x035da967,0x54675869),LL(0x65aba6d1,0x00ddf870),LL(0xfb6525b8,0xcb3618ed),LL(0xa58a9ef1,0xa2776a71),LL(0xd7373181,0x9adaa84e),LL(0x5acac693,0x7c38e845),L_(0x00000017), + LL(0x2f298451,0x17d5163c),LL(0xb8856ff7,0xc5c08271),LL(0xa79d0557,0x32810d21),LL(0x16514840,0xa6e95174),LL(0xce8f06a5,0x393b8782),LL(0xf14b15d0,0xdf3da6f7),LL(0xa398eeac,0xc040c1ac),LL(0xd2eb31c7,0xe9ed34f4),L_(0x000001ac), LL(0xcc4ff509,0x6386bac2),LL(0x294f7bd0,0xf986d8d5),LL(0xec0b7a55,0x55592285),LL(0x96568681,0x15833824),LL(0x307162e2,0x03366d9a),LL(0x196efa15,0x78331de9),LL(0x6afbb75f,0xce11aa87),LL(0x4246ce65,0xa207e319),L_(0x000000f7), + LL(0xe290f3f8,0xdf95cccc),LL(0x2c3a928b,0x954c7e07),LL(0xb87fc4e2,0xc556dd0f),LL(0x5dde9996,0xa10a09f2),LL(0x017edf41,0x126b8ebf),LL(0x11739253,0xe86b6fe5),LL(0x1f9be2dd,0x7b89b849),LL(0x4acd9273,0x572a4b24),L_(0x00000018), LL(0x695c6282,0xe035ed7d),LL(0x8545db72,0x1c4fb913),LL(0x52bc38af,0xe8b8d046),LL(0x500cd8de,0xd8bd36cf),LL(0xc86ac9e5,0x7fd4ed73),LL(0x82941dac,0x968c57f8),LL(0xcd1842b9,0x806ab108),LL(0x4885bf1c,0x7821dec4),L_(0x0000014e), + LL(0x7d0fa54f,0xf8d6129f),LL(0xbddf5a7c,0xb2f43150),LL(0xb4988625,0x3c2f3809),LL(0x1299bbfb,0xb080f7b3),LL(0x84ed45f5,0x20ab0abb),LL(0x824f7bed,0x533e510d),LL(0xd6447243,0xb64fbbb6),LL(0x67c576b7,0xcaa9ee82),L_(0x00000016), LL(0xea0b07fd,0x4253a269),LL(0xf68fe622,0x4572de06),LL(0xa777b687,0xcf599bf5),LL(0xa16d5f86,0x2a811045),LL(0x94a33dfe,0x08732642),LL(0xac970a0c,0xd6867a04),LL(0xeb2b7d05,0x0e51a57c),LL(0xad29a28a,0xbf79a38e),L_(0x000001ac), +}, +/* digit=100 base_pwr=2^500 */ +{ + LL(0x6dc2f627,0x103efe86),LL(0xcb9e407c,0xaaa13853),LL(0x0e6c71ed,0x1b70a2af),LL(0x5ae18f75,0xcf7e3e82),LL(0x1ec11bb0,0x45c36a5a),LL(0x56ab4b56,0xa4e5487f),LL(0x86df052e,0x3868ef9a),LL(0xc7d75031,0xee422740),L_(0x00000060), LL(0xd47edd5d,0xb7ee652b),LL(0xfaa97f40,0xa3dd7397),LL(0x294d2d1b,0x453daecf),LL(0xe65344d3,0x24bd3f56),LL(0x1c9985d3,0xc78c6f61),LL(0x2675985e,0x8ad7e24f),LL(0x8b4060d3,0x6c928213),LL(0xffdfb749,0x27a6ad57),L_(0x000001e6), + LL(0xe5a166a7,0x589be6a7),LL(0x313031bd,0x84289d06),LL(0x704962d9,0x522512df),LL(0x4932ec5b,0x6a669eef),LL(0x4db07538,0xcfe74767),LL(0xabd7aebb,0xe7944dba),LL(0xd27fb22c,0x458ef814),LL(0x6ae70494,0xc9680563),L_(0x000001ad), LL(0x11b3ff8e,0x6c5b60c5),LL(0x915adb1e,0x108c6584),LL(0xf8937e8e,0x64ea3a9f),LL(0xab88406d,0x61d268f9),LL(0xd6126f44,0xae3ff279),LL(0xed1f3032,0x22a5d3b3),LL(0x3a1b63af,0x2fd7a532),LL(0x90caf928,0xf7a42a75),L_(0x00000199), + LL(0x014a6bc9,0x9fdfb005),LL(0x179f05f7,0x91c70d36),LL(0x1f0a00c5,0x1bdb8aa0),LL(0x13b09f86,0x1877e4cc),LL(0xab098b85,0x804921bd),LL(0x47ca3471,0xb874265f),LL(0x78a5d59c,0xeb734d84),LL(0xbb8aac74,0xa87e5bc7),L_(0x000000f6), LL(0x082ec4f4,0x635dd559),LL(0x340b409a,0x4cff9fd3),LL(0xe395e617,0x83237476),LL(0x0e435fdf,0x995df5d9),LL(0xacf9026e,0x0535beb0),LL(0xf60fe3f2,0xc3baddc2),LL(0x21d68a60,0x5d079f08),LL(0x8b800543,0xf7a20c38),L_(0x0000004e), + LL(0x4902c85a,0x061ce962),LL(0xee54d7fc,0xe676ddac),LL(0x8e982883,0xfc5997cf),LL(0xe8ccea68,0x4f3d06f1),LL(0x42831bb9,0x57b80d82),LL(0x625c3604,0x7389ec2e),LL(0x5466a1d8,0x13ff25b1),LL(0xf9c50093,0xfb5d45d1),L_(0x0000005e), LL(0xf2463011,0xab4e32c6),LL(0x08ec78b5,0x24014646),LL(0x53a9c0b3,0xd5ffb795),LL(0x5594ddea,0xf933bdcc),LL(0xdc110f8b,0xd5249289),LL(0x5d52f652,0xcb4147d2),LL(0x95ab06c0,0x968adb2d),LL(0xa1bbff17,0x4039be6f),L_(0x00000066), + LL(0xee64527d,0x186c159d),LL(0x6c1da851,0x87f87d48),LL(0x2ffecac8,0x326e8ac4),LL(0x70a401c5,0x68a082d2),LL(0x0bd703fe,0xbb17b4ec),LL(0x9fe82427,0xd5029b1a),LL(0xf75c6b25,0x8859df58),LL(0xfaac56e2,0x0f97f9bf),L_(0x000001c7), LL(0xe4e3e216,0xaf73b932),LL(0xe721dc13,0x98f115f8),LL(0x825bde14,0x102f60c7),LL(0xf0780fd3,0x92e5a9e9),LL(0x9fcac3f2,0x96a4edbc),LL(0x51ae4427,0x123f8f26),LL(0x622ca1bb,0x3d2d6a72),LL(0x4fa4ca10,0x77d0f199),L_(0x000000a5), + LL(0x10e1302b,0x33e577af),LL(0xbf557eaa,0x98005156),LL(0xca7cba0f,0xe3d41486),LL(0x73d1e9d6,0x3a30b9f9),LL(0xaa3443ad,0x99856b55),LL(0x81921940,0x0ca4724f),LL(0x250cf13f,0xba1696b8),LL(0x9b6f0f69,0xba1deb1e),L_(0x0000003b), LL(0x72f9435a,0xa037cb66),LL(0x7437eb08,0xfaf55d7e),LL(0x579149c6,0x43f7c61c),LL(0x921e4c69,0xeba03e36),LL(0xc342ab26,0x0a3ade34),LL(0x86264eb6,0xcf120523),LL(0xffc57653,0x914e6e20),LL(0x5770eec7,0x2d678456),L_(0x00000091), + LL(0x072e1bd0,0x3106fc3e),LL(0x9739a62b,0xd166966e),LL(0x6ea97e6a,0xbc843284),LL(0x0fb2aa2b,0x1768bc4f),LL(0xbd1f5f87,0x0a51f2d1),LL(0x8890f99b,0x5f53245a),LL(0x6a0000aa,0x38e0dc0b),LL(0x49547c15,0x3dbece21),L_(0x000001c3), LL(0x7b97c512,0xeab56de1),LL(0xcb15a8e3,0x8e0ff0fc),LL(0xc00352a7,0x0dae3bf3),LL(0x716e7d48,0x273cee30),LL(0x83dde892,0x00962a42),LL(0xe18ae53b,0xcb2ce674),LL(0xb8c78835,0x12176412),LL(0xc6faee27,0x94e0f5e7),L_(0x00000062), + LL(0x2d854d6e,0x78569761),LL(0x266d871a,0xe7df9590),LL(0x015aa94b,0x4e8bbf72),LL(0x150482ac,0x12880439),LL(0xaa4b2f7c,0x53495f23),LL(0x5ef777bb,0x04a67481),LL(0x38a798c0,0xc7aadc88),LL(0x308a425c,0x2ccb5f57),L_(0x00000043), LL(0x640f2881,0xb506af85),LL(0x718ebc6c,0xdd21e3a6),LL(0x2c50bba9,0x56098fde),LL(0x7b6e3c4d,0xa8a72185),LL(0x02f4d7a4,0x9218f9c4),LL(0x55530e5d,0xa541a6f2),LL(0xbf7b3c63,0x97421bb0),LL(0x04f0181b,0xe7a08f28),L_(0x0000003d), + LL(0x611c41b4,0xb7a89c2a),LL(0x59bf73de,0x701684bf),LL(0x59572fc8,0x8134fb14),LL(0x116042d5,0xc2db37ef),LL(0x49c61bec,0xf05c9753),LL(0x0b65e976,0xbbefa454),LL(0x3b1cd2a7,0x2cb97f65),LL(0x790f0086,0xc011e095),L_(0x000000d8), LL(0x7cfb4920,0x170eba17),LL(0xc6e8d2e1,0x609e9ebc),LL(0xe69224f6,0xa74251dc),LL(0x88ae4a2d,0xf5331e8f),LL(0xf73bb04a,0xfb6fb779),LL(0xf42091f4,0x7aa76758),LL(0x23ea8c88,0xf921d2fe),LL(0xb43fc164,0xb83f6c60),L_(0x0000014b), + LL(0xae89583e,0xb2f332da),LL(0x1235350c,0x3fc1272d),LL(0x28803380,0xcc94724d),LL(0x52679e63,0xa1b6d063),LL(0x5f59afa4,0x8fd15f1d),LL(0x1998f9ec,0x67514283),LL(0x856a5843,0x0b1f071f),LL(0x44e35d97,0xa4396ed8),L_(0x00000024), LL(0x1fa181f4,0x209d5128),LL(0x36d77579,0x3d71f02d),LL(0x6903b9cc,0x242255da),LL(0x255e80b9,0x0d577ece),LL(0x8c99ca99,0xcce7a8ce),LL(0x6e67b351,0x8274de19),LL(0xb1789c3b,0xd9d46d98),LL(0xb68f17a4,0xbe658d62),L_(0x00000190), + LL(0xb5bb0a17,0xb2d11384),LL(0xc0e43052,0x18ea1e36),LL(0x6499f986,0x67f0543f),LL(0x6c81b7cb,0xfe7f0035),LL(0x0049686c,0xc866a608),LL(0xd1d9672f,0xad63f7a9),LL(0x402ddc59,0x0430d4e2),LL(0x90a63a4e,0x212afc89),L_(0x0000011f), LL(0xd4b7e0dd,0xa5a4f004),LL(0xb4669198,0xe3c06d85),LL(0x9dbced32,0xd46b4406),LL(0x6dc0df8d,0x13bbdb5b),LL(0x26fe23c2,0x9e72fe86),LL(0xf3f82db4,0x9908a610),LL(0x21de6fb9,0xacd7a7dc),LL(0x84215e98,0x8d6e691f),L_(0x0000016f), + LL(0x5bb0cb53,0x6a2a68fa),LL(0x1a45088f,0x097c3677),LL(0x93e569b4,0xf6248b6e),LL(0x76442347,0xf5aa90b0),LL(0x7db67859,0x47468b1b),LL(0x0335b7c8,0xc14d722e),LL(0xbdb192bb,0xa89357c4),LL(0x6091e296,0xabbee708),L_(0x000001a6), LL(0x25d75afe,0xb79d5c35),LL(0xfa81b0bd,0xb8c1d912),LL(0x9c98ad08,0x6f43a564),LL(0x487e8e86,0xb8305a15),LL(0x68d70b11,0x4f253374),LL(0xda0a3387,0xc3ee2674),LL(0x12970085,0x7d1dcff2),LL(0xabf94fcc,0x3abb8f41),L_(0x000000ca), + LL(0x791890ca,0x43ae6f56),LL(0x2ecfea4f,0xbfbd972d),LL(0x1717ff60,0x50d6adf6),LL(0x54f2d354,0x6c6e24d6),LL(0x2e42a5a9,0x8ef967c8),LL(0x2c029c93,0xef490e17),LL(0x74b0a604,0x3a515366),LL(0x835d8fbf,0x878ca8ab),L_(0x000000f9), LL(0x25b70439,0xb19f5e63),LL(0x0a7f849d,0xe7343af4),LL(0xa13e0960,0x93d2a93e),LL(0xd7e39973,0x58e4acec),LL(0x89b42cb1,0xb14fea72),LL(0x128188b6,0xaf37faab),LL(0xfe8c3b50,0x51d9f7ee),LL(0x2b121d0a,0x5997d399),L_(0x000001a5), + LL(0x40c610da,0x70a88d95),LL(0x0ae00340,0x2c6b6f8f),LL(0x941fb569,0xd4a8a83d),LL(0xfd77e569,0xfe3e5239),LL(0x2906296c,0x5d2269e6),LL(0x779ada15,0x65afaeca),LL(0x46fce296,0x41d7fedd),LL(0x0ceb36d9,0x39bc7e8f),L_(0x00000013), LL(0x385b4015,0x5ebed878),LL(0x04b873d1,0xb3e0c338),LL(0x061d2bb8,0xd36ffa7e),LL(0x596e92bc,0xbde7e857),LL(0x58c9a5ab,0x78a8b297),LL(0x34780b9b,0x6bd40718),LL(0xac60511a,0x2d3c02e9),LL(0x83e6ac72,0x6d092687),L_(0x00000112), + LL(0xa33a65c3,0xfd72e9bb),LL(0x99783135,0x67ff52e3),LL(0x8dc913fd,0xab427847),LL(0x8986e4a7,0x5377b12a),LL(0x8a8d9fc8,0x57fef8f8),LL(0xb61bed13,0xf189dc79),LL(0xd4bb14a1,0x2e6d28f7),LL(0xcd3d6f13,0xf00e6579),L_(0x000001a6), LL(0xf42d044e,0x14efe417),LL(0x9fb6caaf,0xabbb19b6),LL(0x951205f5,0x787b1023),LL(0x440fd20f,0x4968e195),LL(0x6d5f6164,0x33cbed34),LL(0xa2722dcb,0xf576c320),LL(0xbddf2d94,0xb80ba0c8),LL(0x414feeda,0xeb25ced6),L_(0x00000008), + LL(0x9ee2c247,0xaa61ebad),LL(0x6aced3dd,0xe5fe2dd4),LL(0x0bd3e3fd,0xfe14f9f4),LL(0x09520569,0xd818d1a2),LL(0xb4968b88,0x82f0bdc9),LL(0x0b8b7732,0x6520e3de),LL(0xfe9e8edc,0x272ff767),LL(0xbc017cf0,0x0f65dc99),L_(0x000000da), LL(0x3dc034f9,0x0a9b50b0),LL(0x4ea634ab,0xe6308ff0),LL(0x7b191db6,0xee04399a),LL(0xddea9de7,0xda7bdea8),LL(0x492d45e6,0xb54c55ae),LL(0x39e666b7,0xf573f4e9),LL(0x0c925a51,0x0292c159),LL(0x71f91622,0x80fc7f50),L_(0x000000d3), +}, +/* digit=101 base_pwr=2^505 */ +{ + LL(0xb83d191c,0x53639a92),LL(0x1ce7b1b4,0x1474fb3a),LL(0x0d260e43,0xaefab808),LL(0xc4e32954,0xfaf9e670),LL(0xb5bae76d,0xde42d0d7),LL(0x9eb4687f,0x5f45bfa8),LL(0x7d89b1ca,0xba638bbc),LL(0xc0ecce4f,0x1de873fc),L_(0x000000a2), LL(0x9165fd5a,0x36c9c2b4),LL(0x318f9f96,0x2cb815fb),LL(0x6f676d6c,0x7560919e),LL(0x41cc633a,0xe2d47525),LL(0x9a79e211,0xe199c599),LL(0xfbee081e,0x265f515d),LL(0x3107dec5,0xd0ea4e25),LL(0x6f2bdc9e,0x5a539ab3),L_(0x0000001c), + LL(0x2d570179,0x6ffa11c2),LL(0x1bfc6586,0x1f882706),LL(0xe25c9a78,0xeb5d1a25),LL(0x12852d54,0xe5fcb1fe),LL(0x4f331734,0xd8c5dfb7),LL(0xe48b7e54,0xcfadcca2),LL(0xe9b41639,0x193402d5),LL(0xb8e1f8c2,0xc49e8f71),L_(0x00000148), LL(0x943f50d3,0x4e33ca43),LL(0xe98a1f64,0xa7cb416c),LL(0xbd595ac8,0xe328cd45),LL(0xf8fd4eb1,0xec3fd8cb),LL(0xf768cfe8,0x9eb626b0),LL(0x476b1bbc,0x069d1524),LL(0x8d0ffe31,0x220edd8d),LL(0x2925aa89,0x60b37558),L_(0x00000036), + LL(0xf4f778c1,0xe83c1031),LL(0xc5cc621c,0x434bc9bb),LL(0xac957c67,0x27bcbc47),LL(0x430a3686,0xace0a905),LL(0xed2cb5ad,0x38aa0831),LL(0x0f4f5d32,0x1fa3c11d),LL(0xc48e91c9,0xedbfb351),LL(0x98229765,0xdf2591e4),L_(0x0000012b), LL(0x72bcfd0f,0xe38e4555),LL(0xa53bea9a,0x97db1ecb),LL(0x196518c9,0x58970b56),LL(0x6895c332,0xc6b46d1e),LL(0x0fe772a3,0x18e44ad3),LL(0x48216056,0xaf1a5dd6),LL(0x86d1933f,0x18ae6deb),LL(0xdf5a53d7,0x4345a6ba),L_(0x0000004e), + LL(0x7fbc903f,0x0deafce5),LL(0xa11885f4,0xf942172b),LL(0xd640aa98,0x17ce6b52),LL(0xdc1bfcf8,0x9d8e40bc),LL(0x14a7d638,0x3c804e7d),LL(0x80e95516,0x63048fa8),LL(0x4af7c92b,0x15381b03),LL(0x88fd6851,0x73ec6a96),L_(0x000001af), LL(0xf3848b20,0xf4f85d1a),LL(0x6ba36666,0xf47de871),LL(0xfbfc6c17,0xf9474540),LL(0x70e03b35,0x72b1ddc6),LL(0xad63874b,0x7f48bdd3),LL(0xd249ea68,0x6a15d7cf),LL(0xc1614192,0xe9d101f9),LL(0xacd8d963,0x1b9b1c2f),L_(0x00000077), + LL(0xb30a7c89,0xc3b944a7),LL(0x8b0aff56,0x97b94164),LL(0xacb2b2a3,0xfade0d57),LL(0xe22c59c3,0x72ad3ddf),LL(0xd8b6f7d4,0x4a332f59),LL(0xe436d0e5,0xb28ca267),LL(0xa69516f2,0xc620d57f),LL(0xdd5b988f,0xb3a24be6),L_(0x00000126), LL(0x0e17b40b,0x7dc7da50),LL(0xf918114f,0xa2d07106),LL(0xb35f8ba3,0xfe3e2734),LL(0x583e00bb,0x27f4b785),LL(0x5b427e96,0xb8110ec6),LL(0x6198344d,0x2666790f),LL(0xc2f9267c,0x9a6bed52),LL(0x15a1c587,0x05e6612c),L_(0x00000067), + LL(0xa3837d8a,0xeddc635b),LL(0xb97227a6,0xf72fcd23),LL(0xcc5023cf,0x16ff8449),LL(0x4d184e1b,0xa6e3cc25),LL(0xb6176789,0x14e442c7),LL(0x200d2b68,0x147e4e2b),LL(0x9903da3b,0xa26bbf3b),LL(0x6b6aeb08,0x849b5dc2),L_(0x0000005d), LL(0x8b8b5947,0xbb6ef597),LL(0x250dac2d,0xac7eb4e4),LL(0x0cadff32,0xfb97f1fe),LL(0x1e4bc394,0x2549b2e2),LL(0xa4d9b459,0xc81df54d),LL(0xedb4d3d9,0x885b7f7b),LL(0xa8c245eb,0xc2642e0e),LL(0xfd485de4,0xbbbd9d24),L_(0x000000f9), + LL(0x41537261,0x82620992),LL(0x9bdd489e,0xf9ff35e3),LL(0xe0746b33,0xfea9ab53),LL(0xc4e354c0,0x5438eb93),LL(0x660ea2e7,0xe43d99e6),LL(0x15697bab,0xcb7634f2),LL(0xacd2ac86,0xcf1f1144),LL(0xd531df3b,0x2d6020c4),L_(0x0000005c), LL(0xba8f9454,0x5eadffbf),LL(0x79147d9d,0x6799957b),LL(0xf22818e2,0xfc746f29),LL(0x7b9b1ddc,0x87c40fbc),LL(0x5518ebb6,0x12ffe947),LL(0x9a81391e,0x997b0c31),LL(0x3a724bee,0x02662680),LL(0xe08a5f24,0x1ebe1250),L_(0x00000065), + LL(0x5f304612,0x3b6bccc6),LL(0x4b51d15f,0x4d9896e4),LL(0x61b0ed08,0xdf4f3be0),LL(0xcedf84c9,0x6ed8e29b),LL(0xf45bde62,0xaa49395c),LL(0x128499be,0x812a1bfb),LL(0x30e7b9a9,0x442e44bd),LL(0xe50016d9,0x251b4710),L_(0x00000177), LL(0xfaa5f8e4,0xb4c58ea8),LL(0x8972e1af,0x6a3b7639),LL(0x2d603c3a,0x64b41953),LL(0xad6090f4,0x1c1cc6d5),LL(0x644bda3e,0x79fc4551),LL(0xe003b3c6,0xc4fe3bf0),LL(0x879a2d4d,0x9f3993d4),LL(0xd0249205,0x90933a0b),L_(0x00000094), + LL(0xb1b095cf,0xbaa0eb60),LL(0x64977e8a,0xed1a5135),LL(0xdb1eee40,0x7fe9e6fc),LL(0xef595c17,0xbc2a7a81),LL(0x4d74eea7,0xafbb2385),LL(0x34f92af2,0xffa66ed1),LL(0x9f246323,0x91252082),LL(0xd49955a9,0xa2901a50),L_(0x00000001), LL(0xa661dce3,0x19a6a510),LL(0xae624c6c,0xf34dd865),LL(0xbf77202a,0x6cbac9c8),LL(0x0d692aaf,0x2471eb03),LL(0xae2ff6e2,0x4e8b52f6),LL(0xfc37aa01,0x96b6740a),LL(0x5ca85277,0x4fc2258e),LL(0x1a66c773,0xd7c07ad3),L_(0x00000122), + LL(0x8dbc9582,0x3efb63d7),LL(0xb52733b4,0xadb5f371),LL(0xa39008b4,0xbebb4df3),LL(0xb7dee0b6,0x6cbc3a0b),LL(0x889767ea,0x0970ea6b),LL(0xfb4bece2,0x7f67b6be),LL(0x890b0f75,0xe72afc5e),LL(0x8395198d,0x6c13b8e8),L_(0x000001e1), LL(0xd3420042,0xcd597e49),LL(0x85730a39,0xd16d451d),LL(0xbb9ddfb7,0xc5ad35f5),LL(0x46f1005a,0x04cccc76),LL(0xfc9aa038,0x199ada1e),LL(0x03f6f34d,0x48f0a0bd),LL(0x200aa943,0x2532adab),LL(0x83389203,0xa871ac66),L_(0x00000098), + LL(0xac1a4aa6,0xd09b5635),LL(0xc63c436d,0x1bf51ded),LL(0x36468adf,0x71acd515),LL(0x98fc5e09,0xf48ba93b),LL(0xed9c3a1c,0x0c6b0d79),LL(0x01b9c574,0x24610fb1),LL(0xb968199b,0xe209e9f6),LL(0xbbce4f03,0xeee7632a),L_(0x00000095), LL(0x2b338eea,0x7c32158c),LL(0xce330212,0xeb40d5de),LL(0x1694cc96,0x981c6977),LL(0xddf4fc29,0x9ea41d2c),LL(0x89f8c78d,0x86af7d31),LL(0xd67b4c4c,0xf2c9d3cf),LL(0xad9e3351,0x16fcf6af),LL(0x702ac15c,0x16ccd30f),L_(0x000000b0), + LL(0xef338e43,0x31986e71),LL(0xafcb621c,0xe99b97d2),LL(0x3f65ee43,0x0c39ca80),LL(0x14bf4d0a,0x4ebb930d),LL(0x840ff2ab,0x894804fb),LL(0x76798c37,0x89a1b227),LL(0x3aa6a099,0x34d5a9a4),LL(0x6f4a66e9,0xdd3ebcad),L_(0x0000005a), LL(0xda731fcf,0x63a60589),LL(0x9cc5953b,0x6c38743c),LL(0x85a6854a,0x08e7cd4c),LL(0xf39a75be,0x936c5fc4),LL(0xfc799df1,0x93f15bcf),LL(0x739e6699,0x4c317bf9),LL(0x2e5c38de,0x6db73251),LL(0x427a1224,0xa307eb83),L_(0x00000136), + LL(0xaa579162,0xdc077b67),LL(0xa1669c8a,0x49cbb3e1),LL(0xd5e45b94,0x26a91035),LL(0xe7362c4d,0x3ddf32d0),LL(0x643b77a9,0x27b4f14e),LL(0xaa5ac709,0x1246b2b6),LL(0xfed505b3,0xce87322e),LL(0x6473f9c6,0xffc4c045),L_(0x00000121), LL(0xf98bfb3d,0x4300e539),LL(0x1c3ea4fc,0x79dff91b),LL(0xe9151768,0xe8106a01),LL(0xced48484,0xd2bbaae2),LL(0xb0b62aaa,0xec766cbf),LL(0x4fd3762d,0x3740af93),LL(0x1969f618,0xeff16696),LL(0x481e8d46,0x08f70c0b),L_(0x00000191), + LL(0xf8786a71,0xe6e4ffd4),LL(0xd4cc0359,0xdeb8f8ef),LL(0x6a7bc267,0xb0f6a0db),LL(0xceec7c5d,0xbe8f401f),LL(0x328be59a,0x0120834c),LL(0xea6a0206,0x5b979c4e),LL(0xc2f2cb42,0x6693b49a),LL(0xc70270e4,0xcb7ea005),L_(0x0000003e), LL(0x4229943e,0xd93cd84b),LL(0x59acbb8f,0x771ac6f4),LL(0x37d3f220,0x5f43f61d),LL(0xe983e186,0xe1ef31c8),LL(0x66433715,0xe567c88b),LL(0x4ca008fa,0x4f949b3b),LL(0x164fa949,0x7f0981e7),LL(0x55a6f6fe,0x85c2f160),L_(0x00000030), + LL(0x7091f78d,0x0fe60315),LL(0x778f4301,0x3d35c1e7),LL(0x42ff27b9,0x4e622807),LL(0x9ba721f4,0x9122d492),LL(0xc966361a,0x0b7b9eb9),LL(0x824265f0,0xd71fbe97),LL(0x90d81101,0xf6012c22),LL(0x3aa81035,0x77c80e09),L_(0x000000c0), LL(0x23dea1b1,0xc562080c),LL(0x0edd3c7c,0xd4bfec34),LL(0x6ac1e8f3,0x8628425d),LL(0x3dfaff6a,0x6eeb0125),LL(0x2bd725ab,0xf2cb02f5),LL(0xeb0228d9,0x63e15d94),LL(0x41589407,0xaa99cd36),LL(0x94061e78,0xf8ab88d8),L_(0x00000109), + LL(0x21abe88e,0xb83d39ba),LL(0xfe497366,0x1a08bb8d),LL(0x3fb2e32d,0x68fadea4),LL(0x90040dcc,0xc78d9e5b),LL(0x6201359b,0x8999242f),LL(0x4ca94e09,0x83f1e38d),LL(0x3e9a9377,0xf5e42def),LL(0xc5c271ed,0xd3d42e09),L_(0x000000da), LL(0xb7e48974,0x7f14caf1),LL(0x52b71020,0x42fb2920),LL(0x840b578b,0x4e0acb78),LL(0x9f5c859d,0xbd1059c6),LL(0xf5ce1fef,0xdfc0d187),LL(0xd99b98e1,0xb702018d),LL(0xd9d695b6,0x7056ff1f),LL(0x1187f703,0x73121d9b),L_(0x0000000b), +}, +/* digit=102 base_pwr=2^510 */ +{ + LL(0x7a6e63bf,0x89622bfd),LL(0x12bebe9c,0xcafd2ca2),LL(0x487abee2,0xd290457b),LL(0xc04143f4,0x05d13bf4),LL(0x716aab7d,0x067f0ae3),LL(0x7740d413,0x5925a309),LL(0xebe6d02d,0x14370b8d),LL(0xe8ef2c27,0xfae20be9),L_(0x000001cf), LL(0x7eac0b8f,0x8d09dc72),LL(0xb463618a,0x49d83802),LL(0xe00f8249,0x50666aae),LL(0xd5a21e88,0x54be3730),LL(0x258522a3,0xa6ce164b),LL(0xbf3fd223,0xfefa386c),LL(0xb7ba5ba4,0x479bc6a0),LL(0x378ecff5,0xece410bb),L_(0x000000c6), + LL(0x97fc3142,0xb8ebdae4),LL(0xfcc42342,0x0addd068),LL(0x2e8a76fa,0x1ba58a99),LL(0x972d98aa,0x585d2056),LL(0x5a290a6f,0x51a66712),LL(0xa47990be,0xab19e664),LL(0xe44696be,0x2f64d1c3),LL(0x490ab4a2,0x0b8ce484),L_(0x0000014a), LL(0x88951457,0x0acf9a53),LL(0x3b3fd199,0xdaaafe7e),LL(0x1c1f1592,0x3015bdb3),LL(0xadb01684,0xb2dbb2d0),LL(0x670d1295,0x3f77ef5d),LL(0xb3f98aca,0x51408bf1),LL(0xb5280fd3,0x0b5ee9d3),LL(0x3a7a5866,0xe5879122),L_(0x00000186), + LL(0x43cd6b28,0x2aa4eb8b),LL(0x719fd8c6,0x2ae67788),LL(0xd8b75613,0xd4b10cdf),LL(0x691c837c,0x7871303d),LL(0x169b2b0b,0x0d01af02),LL(0x6b821f74,0x33573229),LL(0x82eb3840,0x782b872c),LL(0xef815609,0x64bda6ba),L_(0x000000a9), LL(0x4db2512d,0x654fa37e),LL(0x9665a8db,0x761f0aa2),LL(0xe37a4531,0x4eac5b19),LL(0x586ef6d9,0x886dc010),LL(0x014c7183,0x075d0e7c),LL(0x55263f06,0x8a38c3bb),LL(0x5b8b13c3,0xf18380c5),LL(0xcefec3fb,0xb50c9c44),L_(0x000000ec), + LL(0x5b59b03b,0x5131c51f),LL(0x65ab5849,0xd5115c76),LL(0x8739b754,0x840523eb),LL(0xb96b253e,0x8a1f77e3),LL(0x765d9707,0x8742a046),LL(0x7e942e5b,0x1539823d),LL(0x0b3194bd,0x560b9978),LL(0xb52679bf,0xbda6ff32),L_(0x0000001a), LL(0xe66dad83,0x92820e93),LL(0x881e08a8,0x208f9f2c),LL(0x7e5fd839,0x4e86968c),LL(0x305d2580,0x76aeb554),LL(0xb44037fc,0x24c686c9),LL(0xb80d02e0,0x20e62e51),LL(0x5774d5a6,0x653df90e),LL(0xf0000eae,0xc9b31961),L_(0x0000012a), + LL(0xe873ab5d,0x0eaaf4f9),LL(0xfbc7cc75,0x23c2ade5),LL(0xd4d5bade,0x734024b7),LL(0xaca16532,0xb04a1289),LL(0x748144eb,0x599436fa),LL(0x2dc69353,0x292c7b3d),LL(0xe403f7a9,0xb831d302),LL(0xb390c4b2,0xefcb4c53),L_(0x0000003e), LL(0xbd287a5b,0xe0c0eb7f),LL(0xf6a7b102,0x411f77a6),LL(0xc71476dc,0xae920f7c),LL(0x2edbab42,0x28d62eb0),LL(0x3c6b13bc,0xc5296531),LL(0x35b583ce,0xfb32a342),LL(0x66e0af0c,0x23a5daad),LL(0xa449b545,0xa7558c28),L_(0x00000033), + LL(0x52d4b721,0x6383559c),LL(0x52741d3a,0x6d33fc8c),LL(0x98c5775c,0x595adc9e),LL(0xdeefc5ad,0xc4827819),LL(0x94326f99,0x384312e5),LL(0xc9b59642,0xfb777603),LL(0x6642d1f6,0xfebd7a7d),LL(0x04e71c64,0xd51e2c8e),L_(0x00000072), LL(0xf9aa2f14,0xfe188e45),LL(0xc6c9a2ae,0xcfd37d07),LL(0x870985c6,0xb64a1b0a),LL(0xf54e2700,0xd57c3e8a),LL(0x97a88233,0x4ccc22c2),LL(0xe7db1ecd,0xfff2895e),LL(0xb9be3600,0x2a410545),LL(0x8934c5cb,0x71986e7a),L_(0x0000016c), + LL(0x9dfa6b98,0x8664ea8c),LL(0xb006fef1,0x18fac77e),LL(0x2d10f805,0x144d6d0c),LL(0xcefe66ce,0x7ca13881),LL(0x6bc51a22,0x93e1d2aa),LL(0xfe6fc406,0xdde6594a),LL(0xcfe90933,0x92333bca),LL(0x2f2f839c,0xf1434e7e),L_(0x000000b9), LL(0x2169be2f,0x84887df0),LL(0xbd49b873,0xf75f870f),LL(0x4f7c90e8,0xe89d9ed4),LL(0xf464a50f,0x9a76a69e),LL(0x3d9a6cbe,0x0a745d9f),LL(0x0f9b1034,0x87bec297),LL(0x5fe8ae9e,0x7f1ab569),LL(0xad783c5d,0xea58b4b0),L_(0x00000074), + LL(0x0917b4f6,0x9ff8d786),LL(0x35735942,0x05d76bb3),LL(0x995f4b0a,0x58d0fe01),LL(0xe40e0f1c,0x21dccd2e),LL(0x3af9c629,0x40ab0ca3),LL(0x074069c3,0xa30b637c),LL(0x098a102f,0x44888bc2),LL(0xde377018,0xb2e96e33),L_(0x0000016c), LL(0xa96d1903,0x0f70d506),LL(0xe57ed3ba,0xe59c4f2c),LL(0x2492cf26,0x5879a0eb),LL(0x3d130599,0x75760ae9),LL(0x4103b206,0x89f9d0d0),LL(0xa2b74089,0x4b0ad618),LL(0x723e7b44,0xab5c813e),LL(0xebb80451,0x305a1f27),L_(0x00000016), + LL(0xd00287bc,0xd06cea6e),LL(0x063477df,0x7ad6ed83),LL(0xdfc2e4d9,0x7d58a8ed),LL(0x1a10d461,0x9fae700f),LL(0x9ad7943b,0x37aee0fa),LL(0x575deb90,0xef0a0865),LL(0x926de4b2,0x3a26c380),LL(0xc5d7be4b,0x910a980d),L_(0x000001a4), LL(0x66fcdff6,0xdc85a306),LL(0x8a336a7f,0x078dd7d7),LL(0x3626cc20,0x5cdeb063),LL(0xc2b171da,0x273ae54e),LL(0xab82b41f,0x10b49e9f),LL(0x9d867301,0xca9e1b59),LL(0xe2e4e776,0x7eb0c998),LL(0x2437d70b,0x3320fabf),L_(0x0000006b), + LL(0xa0ce92cd,0x7b0fa120),LL(0xb86bacca,0xfbcd14e3),LL(0xa097b60e,0xd21921a2),LL(0x57795942,0x96c19ceb),LL(0x8537f555,0x2145d8ff),LL(0xe5e61d05,0xc2c7c89b),LL(0xbe0f1c2c,0xb88cf04d),LL(0x77a2f17b,0x47c65308),L_(0x000001d7), LL(0xc686be37,0x9b1b0b2e),LL(0x3ba530cb,0xac5182ed),LL(0xea3a3af8,0xfa4f9dd8),LL(0x03a0d517,0x7b2d9856),LL(0x2bd4dfe1,0x6d8ccb18),LL(0xa68f896d,0xc8c4d1ec),LL(0xa1acec0c,0x0fdaed1a),LL(0xdc43340b,0x1a6552ac),L_(0x000000d7), + LL(0xa74443d6,0x1cfe1d00),LL(0x35fc4f26,0x06e2cd4f),LL(0x7dce43d2,0xfe4a6fd7),LL(0x8884f4ad,0x8bc475be),LL(0x9fb2b07e,0x9fe1c66d),LL(0xde1173c5,0xa0cf5d6a),LL(0x6059a297,0x4938219f),LL(0x49237fdb,0x01e57227),L_(0x0000003d), LL(0x5f7cc32e,0x35f11932),LL(0x63db0e8e,0x431b9b60),LL(0x0b8d8078,0xdb56a2b7),LL(0xa040057a,0x856dd526),LL(0x87409cca,0x3d5f500d),LL(0xb482e56d,0xd9cd1b6f),LL(0xbf890467,0x815814ee),LL(0xafa8c19c,0x2dd2fd09),L_(0x0000015f), + LL(0x0680f460,0x4ab480b6),LL(0x71a65ccb,0x061e197a),LL(0x2360920f,0xb306dab3),LL(0x9d9428ae,0xee526750),LL(0xcbaf9d5a,0xf58e47b1),LL(0xd9a6f7e9,0x696a3350),LL(0x5af36c30,0x1f66ddb3),LL(0xeaff438c,0xd4937e17),L_(0x00000119), LL(0x7821be61,0xac9df61e),LL(0x22655044,0x106e2b83),LL(0x1ae7bb1e,0x343bc8e6),LL(0x99139508,0xbc1e06e0),LL(0x166453a2,0x966bd6b8),LL(0x3756d0eb,0xb4bb44e2),LL(0x3795c5a1,0x625fe170),LL(0xb7605deb,0x426f42f1),L_(0x00000048), + LL(0xa4866558,0x06cfe4f0),LL(0x868d9076,0x47442b11),LL(0xec69d70f,0x7bd07599),LL(0x5e554262,0x4c93a1e5),LL(0x9ba31acc,0x5fa3f8f0),LL(0x5118c586,0xed99e567),LL(0x9ed35f7d,0x9e3fd347),LL(0xce15a315,0x0a315f79),L_(0x000001ce), LL(0x3173a0a9,0x86dda811),LL(0xb40d1386,0xb2f0ff2d),LL(0x0d2ec043,0xc03a536d),LL(0x01fe94d1,0x753c381c),LL(0x6d3c523b,0x468beaaf),LL(0xeb47f9a1,0x5d8bebfe),LL(0xeaf18315,0xb071abcd),LL(0x1a924dbc,0x3c1a4715),L_(0x00000080), + LL(0x68ec9abe,0xcce52519),LL(0xd9a705a8,0xef1ab816),LL(0xb6139e2f,0x4fdd8131),LL(0xdab1fe19,0xf7fb9e55),LL(0x94460d6e,0xeb0d1405),LL(0x6a211783,0x6ba4226e),LL(0x8b3a8c56,0xf2eeb428),LL(0xf7e95eb9,0x0b4ffc60),L_(0x000001aa), LL(0xfb4dfe97,0xe66a7792),LL(0x7209db94,0xdb0eb453),LL(0x0352a746,0x3c883ac1),LL(0xdd4b846f,0xb4107c7d),LL(0xe960d5ec,0xf20e2f77),LL(0x61292f8f,0x8b9e3ba1),LL(0x85963097,0x1218ba8c),LL(0xbba1103f,0x61201057),L_(0x000001d3), + LL(0x86acebee,0x08fb83e5),LL(0x0419bb93,0xc48ce791),LL(0x7a851af1,0xd3ade5e1),LL(0xedcfe59c,0xbf3e625d),LL(0xd7763ab7,0xd2c5aaf2),LL(0x625d14ad,0xb7b3d23e),LL(0xbf8e7638,0x7079ecb0),LL(0xc7d9e9b0,0x9c8fcf47),L_(0x00000001), LL(0x8c2d591a,0x074d6a10),LL(0xceed2d69,0x1a1995f3),LL(0x61d18bb0,0xf02767e3),LL(0x33398884,0x68db2be1),LL(0xbdeb7872,0x3e3fa104),LL(0x82f62909,0x2e4ab79a),LL(0x55582545,0x67badda6),LL(0xa7bb473e,0x26c76ce9),L_(0x00000000), + LL(0x8b6d8d82,0xc0ebb49b),LL(0x76edd0b2,0x7ef78c95),LL(0x089746d8,0x86ff89a1),LL(0x30dee546,0x51992a8e),LL(0x8362adcd,0xafcb70ff),LL(0x883f2631,0xa55108d8),LL(0xa13e25b5,0x93138472),LL(0x1fd32baa,0x64387fbe),L_(0x00000097), LL(0xd0f2fcd5,0xe8652373),LL(0xe1299928,0xce8fd7e9),LL(0x16c54d21,0x938b0123),LL(0xad0e62d7,0x4d602bac),LL(0xf9df41ce,0xc55138cb),LL(0x25dfe098,0xbc01e0e6),LL(0xbf9a6851,0x2bdbc63d),LL(0xa70b0da1,0x8b07ceba),L_(0x000000ec), +}, +/* digit=103 base_pwr=2^515 */ +{ + LL(0x9de2eac9,0xaca511d0),LL(0x698e16fa,0xcb4d0031),LL(0x2e96a74c,0x7b609854),LL(0x679b8501,0x87d91373),LL(0x6f39c358,0xa39fd4a5),LL(0x3aea2bb2,0xc7eef60f),LL(0x4e8edd3f,0xd4812888),LL(0x89e1d001,0x2f4d1fa9),L_(0x00000173), LL(0x855b7b6b,0x0a629c27),LL(0xd6fdccbf,0x6bc14652),LL(0x5f32800f,0xd29c1358),LL(0x69e7f62a,0xf3a9fdce),LL(0x9418d0db,0xdaa9f4b6),LL(0xf492796f,0x525ae5fe),LL(0x32f4a27a,0xd91d1353),LL(0xcc1a7293,0xdc6b1bb1),L_(0x000000fa), + LL(0x4b410aaa,0xe776fe9e),LL(0xe46e8257,0xc90ea2e2),LL(0x285dece1,0x02e70a0d),LL(0xd2e4f07e,0x9e22652f),LL(0x7fb0667d,0x5325ca4b),LL(0xe36daaa9,0x04df1305),LL(0xeebe9d3d,0xfcd0755f),LL(0x570e3be0,0x4f74e603),L_(0x000001f7), LL(0xf1587145,0xb8a7ff33),LL(0x37b93b28,0x02791127),LL(0xa408dc4f,0x219fcf52),LL(0x7589c78d,0xbf0f03e3),LL(0x0bb10f8f,0x8d6cdb0c),LL(0xd517b4d7,0x99047428),LL(0x37e06b1f,0xa69f3aed),LL(0x98f8786b,0x8624d396),L_(0x00000150), + LL(0xf569dc20,0xa4ea5b5a),LL(0x734ae209,0x90fc2a73),LL(0x5823b56b,0x7673ea6e),LL(0x7dbb26e5,0xd6657bcd),LL(0xd1742aca,0xc34cd032),LL(0xe888df76,0x8065b09e),LL(0xa8dad269,0xc00f61b1),LL(0x3a07c5aa,0xd150d657),L_(0x00000038), LL(0x13c019ca,0xd0a14535),LL(0x608fa78a,0xfb7e5603),LL(0x1e082856,0x643ad480),LL(0x7bf543a7,0xf5b0db8f),LL(0xfadd24cd,0x7206f2c4),LL(0x1806c9ff,0x3a60a387),LL(0x0a68bae7,0x1164c0d4),LL(0x51de4b72,0xb512a4da),L_(0x00000076), + LL(0xfead3406,0x77314e66),LL(0xc35e0de9,0x4220d9f5),LL(0x86281b42,0x69b8f421),LL(0xe5f95c9d,0x5fd90a74),LL(0x9a89c707,0x8c09fc49),LL(0xe12f3480,0xa6764b64),LL(0x8c161166,0x886f3c36),LL(0x55f40cf1,0x68ad8aaa),L_(0x00000049), LL(0x36790bc9,0xf91f4bec),LL(0x489002d4,0xe8177d77),LL(0x1759ca38,0xe14e5a1f),LL(0xab2e759a,0x9005868d),LL(0xa02b4128,0xaa1dff8c),LL(0x2b9cd06e,0x12d6a4d8),LL(0x578741ea,0x641aef64),LL(0x1a343e8d,0xc6a85c8b),L_(0x000000d4), + LL(0x6d2e1752,0x4fe44c0c),LL(0x7a97ea09,0xec2c9500),LL(0x455f3253,0xa4bedbb4),LL(0x902e1815,0x27a1df89),LL(0xfb3e392c,0x120f8330),LL(0x583ac267,0x9a9698e2),LL(0xe8c87240,0x675c3030),LL(0x32adecb4,0x4f7fb620),L_(0x000000c6), LL(0x402fa549,0x56a1c202),LL(0xb86d1cd8,0xdab68ef9),LL(0xed63845f,0x1723eef9),LL(0x480f0cda,0x7a1853f8),LL(0xb146da6a,0x7337ff75),LL(0x4dd1db53,0xd3685d26),LL(0x41863100,0x9ea6ba31),LL(0xef5caeec,0xa06b6815),L_(0x000000e2), + LL(0x9a0b3f1b,0xfa7c3363),LL(0xf791b828,0x5836e010),LL(0x69b98b78,0xba2d3b6c),LL(0x504f9367,0xcea4290d),LL(0x5860835e,0xf3dd0621),LL(0x22ac6245,0x208bde66),LL(0xd8153e71,0xd2a1a552),LL(0xcd91cd77,0xc7df7c52),L_(0x000001eb), LL(0x68ac84ed,0x0bfe4e12),LL(0xfdf620f3,0xe9aa6d05),LL(0x78c9c26d,0x7d0e875e),LL(0x581fef3a,0x45acf57d),LL(0x4f2f3f1f,0x89769d1b),LL(0xb516d4fb,0x7161f8a2),LL(0xa50e2afa,0xa831731c),LL(0xa569ea98,0x69e2a679),L_(0x00000040), + LL(0x3662a23a,0xafc78e61),LL(0x4dc242cf,0xb32ad972),LL(0xbb40309f,0x790edca8),LL(0x89505a9a,0x3c060f5d),LL(0x112ba1c3,0x52485cd5),LL(0xc5bdc888,0x9feed1cd),LL(0x68110e28,0x49202782),LL(0x49d8d8e4,0x7cea44e5),L_(0x00000130), LL(0xf027ab8a,0x33e94828),LL(0x54f9b84f,0xdd82a038),LL(0xf69e1a64,0x9e8e50f3),LL(0xf1691b4d,0x13fe2932),LL(0x5ffe5329,0x032ff352),LL(0x51f4070a,0x9dcce305),LL(0xc3145c5b,0x62f1400d),LL(0xd89cb5eb,0xbef8bde9),L_(0x00000117), + LL(0xb69b37b8,0x37573b5a),LL(0x464e098a,0x2eac199e),LL(0x4b6ae9bd,0x41109e44),LL(0x96c7e839,0x638c7109),LL(0x99e6beb3,0xa5b03740),LL(0x0943a1c3,0x8490e0cd),LL(0xfab6ecb1,0x4e71bae8),LL(0xb69f0eb1,0x29f06246),L_(0x00000112), LL(0x5b8fa8ca,0x536e2d86),LL(0xa2a3d8ca,0xf4f50e4b),LL(0x4c428120,0xcb6eaa4c),LL(0xb4203e5b,0x69871129),LL(0x6da13d6c,0x218bdacf),LL(0x4f621f85,0x52046a31),LL(0x1ea900e8,0x3a13fa03),LL(0xc7d28019,0x167b70a8),L_(0x00000037), + LL(0x0575434b,0x2bdb447a),LL(0xae8792f8,0x63aef018),LL(0xae6cf0fd,0x3291cfc7),LL(0xe0ee5c02,0x3ae122af),LL(0x5bd690e7,0xff276537),LL(0xbc3516ac,0xf83b9879),LL(0xa4255fcc,0x05236d5e),LL(0x4ca14e35,0xaf60c6b5),L_(0x0000010d), LL(0x7d6c65fb,0xc17c08e7),LL(0x737de42a,0xac0df2a7),LL(0x520e48ce,0xaceb43b8),LL(0x2f791d6a,0x57fe87f0),LL(0x662b9dfe,0xc51cfa7c),LL(0x884ed1f4,0x75a9efdd),LL(0xb5ee76b0,0x3f9fe081),LL(0x61e43ed8,0xb9598115),L_(0x000001b1), + LL(0xaa029d13,0x82e47d41),LL(0x1c1e4e8c,0xf692383c),LL(0x819d110b,0x0caaa47b),LL(0xcb280e34,0xf6e315e8),LL(0x49f5a7e4,0x68659604),LL(0x6db3e3bf,0xc18d2a73),LL(0xb38233a8,0xab54c2d8),LL(0x216ab95c,0x670af6e7),L_(0x000001b4), LL(0x5df2f21c,0xf79cd8d1),LL(0x95f873cc,0x8946ec9e),LL(0xd4ae259b,0x352c8cec),LL(0x6383026a,0x4b6773b4),LL(0x574f14c8,0x7327edc3),LL(0x43f9e116,0xfc2d9802),LL(0x58a2e8d3,0x26360b9c),LL(0x2ae789b4,0xeac487c7),L_(0x0000004b), + LL(0x38176573,0xcfa66e36),LL(0xe576c7d6,0x40446421),LL(0x5a9fe083,0xa7e0a9d1),LL(0x43da69bc,0xcd5cfda4),LL(0xaca35d4c,0xdb98b2d8),LL(0xcc88e119,0x238da31d),LL(0xe775938e,0xd74d2fe0),LL(0x0e845777,0xee458b07),L_(0x00000086), LL(0xe869d146,0xfc21befe),LL(0x6f8ded71,0xf57aacc7),LL(0xa1f5602a,0x8a4a8706),LL(0xdf77dad6,0xe88d5556),LL(0xf0fb8eab,0x38891e24),LL(0x3a9313c2,0xd33f4e50),LL(0x4e334d02,0x267f4849),LL(0x45dbbeac,0x7b8b078d),L_(0x0000001d), + LL(0xa128f198,0x77a504d7),LL(0x706161d0,0x0d717bec),LL(0x8d3f449e,0xcd6aa437),LL(0x4c327553,0xbfa09758),LL(0xecfed023,0x131032e9),LL(0x4abfe666,0x2301de73),LL(0x972524c6,0xd67cd7b5),LL(0x1b68a20a,0xd8e4bd98),L_(0x000001d7), LL(0x75c85608,0xa0dd411d),LL(0x136bd0f9,0x8521a20a),LL(0xe9c06f6a,0x34117a07),LL(0xb1417701,0x625cc2c0),LL(0x534fecc6,0xe6f01c93),LL(0x698e9742,0xcea5bcd3),LL(0x43a9724a,0x54b554d5),LL(0x77820ced,0x7954cbcc),L_(0x0000005a), + LL(0x07759296,0xef4a4c48),LL(0x67e62639,0xef609727),LL(0x91ba0b01,0xc40bb739),LL(0x7f62ccbc,0xb7eda85e),LL(0xb14485bc,0x2a55f22b),LL(0xeab4bc94,0x091f3fde),LL(0xb13e2d7b,0x72b44ddf),LL(0xa6958062,0xd4d990ab),L_(0x000000af), LL(0x579003db,0x14ea0dda),LL(0xc0e83ba2,0x10cf6ee9),LL(0xc9f677ef,0x8e3eae8b),LL(0x1862146e,0xcfe0b037),LL(0xa6cdb8a8,0x6d8e5bd3),LL(0xf50d8419,0xdd3f0ea7),LL(0xf42ab2a9,0x8a6b5e3c),LL(0x12f65451,0xe62ff71b),L_(0x00000097), + LL(0xd1a8afb2,0x0460a7ae),LL(0x6526a7b4,0x80ab037a),LL(0xf752335e,0xf14c43bd),LL(0xd11a8f65,0x9b989eab),LL(0x23fa924f,0x0976a80f),LL(0xf16dad87,0x4e440171),LL(0x3baaac45,0xb9635c0d),LL(0xf0f34704,0x0e1ca863),L_(0x0000011b), LL(0x47c957ab,0x40fcc076),LL(0x420a4e5f,0x24cf57e8),LL(0xcec847e3,0x1f189869),LL(0xb20db2fe,0x27f88dee),LL(0x48712498,0x423c17a4),LL(0x284e6344,0xfe029568),LL(0x10b9bfa3,0xd426c180),LL(0x07626ee2,0x96cbf2d8),L_(0x000000c4), + LL(0xfdd27a3f,0x8a898f02),LL(0x37d5f07a,0x9e4691c0),LL(0xdc3f3126,0xb1ce0f65),LL(0x81c10b29,0x73e7fd11),LL(0xc595f2a8,0x5a3fd848),LL(0x47d0e340,0x439d759b),LL(0xbc668622,0x87538694),LL(0x461b9eba,0x3484697e),L_(0x0000013b), LL(0xbd5a6c1c,0x3d20296f),LL(0xf99ebce4,0x59fd2232),LL(0x51ac1eec,0x2fb986d6),LL(0xe71f9d4a,0xa5d1433c),LL(0xa289f5b9,0x4ece5225),LL(0xd51b9288,0x6ec5e037),LL(0xcce86717,0xb823e469),LL(0xac199283,0x45b78f23),L_(0x000000aa), + LL(0x16cc257b,0xbfa48e10),LL(0x08472093,0xc8ac9e7a),LL(0xb7492e4e,0x471d73ed),LL(0x53d1bd1c,0x243428ce),LL(0x40adeca7,0xb7d49d17),LL(0xd60077c0,0x7a95c66d),LL(0x737593cb,0xf237e1e5),LL(0x6a7c6f6e,0xa7929ff0),L_(0x00000060), LL(0x6c3da59f,0x894bcc2e),LL(0x7b3c416f,0xa493d3e8),LL(0x21231992,0x4c0a5993),LL(0xf376d082,0x0d5c6c61),LL(0x9e1550e6,0x2a3430f2),LL(0xf1d1beb9,0x11f95e81),LL(0x7b6bc5ab,0xa78bae02),LL(0x17858c60,0xbdd9ea90),L_(0x00000195), +}, +/* digit=104 base_pwr=2^520 */ +{ + LL(0xc0a103c0,0x0b8b69f6),LL(0xb96747cd,0x3f30c14c),LL(0x9e707ed2,0x029690c8),LL(0xd1292336,0x884265ce),LL(0x55cfec2b,0xc87e6275),LL(0xa097ab7d,0xa5558f62),LL(0xf635118e,0x23dda1ad),LL(0x5770b69e,0x1b70ffff),L_(0x0000011d), LL(0xe9851576,0x4f2606bc),LL(0x8c9c6bbd,0xccb92cf3),LL(0x58d1b308,0x2ce6913c),LL(0xbbdfb6fe,0x1967bfef),LL(0xe5cb515b,0x453132fc),LL(0x2527584e,0xc389b2f2),LL(0x2a1591df,0x0460d618),LL(0x602d5761,0x7498b0d1),L_(0x000001c5), + LL(0x59381757,0xb38cffee),LL(0xa135a61f,0x8ac17028),LL(0x2c9fe1a1,0x30418249),LL(0x3ecb968e,0x4c958b81),LL(0x6f834a0b,0x523285e8),LL(0x54df836f,0x29e4b05e),LL(0xf77b5fb2,0xe864d898),LL(0x48371505,0xcce3c32e),L_(0x000001b3), LL(0xce8bcd8c,0xc4a0e5e3),LL(0xfb74fd48,0x18996dc2),LL(0x875aaa20,0x5e9f86f5),LL(0x5eb82718,0x6642422b),LL(0x87431019,0xd6d6f0dd),LL(0x9d7e7982,0xcb46f571),LL(0x346044e6,0xa348c675),LL(0xdc02d250,0x517508af),L_(0x000001ec), + LL(0xa7a865fb,0x18145140),LL(0xded9f8c1,0xba498095),LL(0x40df2b19,0x3834dace),LL(0xa0c7dec0,0x3687e664),LL(0xfeee9a9e,0x09d971f2),LL(0xa032ee72,0x07148796),LL(0xa0b2cc31,0xb65bcec3),LL(0x46067d48,0xd8c2af65),L_(0x000001f5), LL(0xb094864d,0xd715c856),LL(0x79c821c5,0xbebe04f7),LL(0x62cf6310,0x3844c220),LL(0x89986c83,0x2644f899),LL(0x43935732,0xf80ac439),LL(0xfd741ec2,0x299a9f2d),LL(0x3022b589,0xbcf4790c),LL(0xf5663af1,0x767587f6),L_(0x00000046), + LL(0x67f89299,0xf1cdfa06),LL(0xda7b7826,0x97fea55e),LL(0xdd938459,0xc39699cc),LL(0x17d73f54,0x5971fbd4),LL(0x9f08e1d8,0x3631f804),LL(0x65a870ee,0x51a73b8e),LL(0xa3cdc8e3,0x54f69b2a),LL(0x85999014,0x59cbe0fe),L_(0x000000d6), LL(0x9c778792,0x085bfaeb),LL(0x17f6a7aa,0xe07f9788),LL(0x1e5f6c61,0xb271762a),LL(0xcc6a5dff,0x5d3e3cd3),LL(0x895eb0df,0x6eadd52e),LL(0x2cd665b4,0x92523b34),LL(0x93078c5b,0x2ebcff33),LL(0x48620212,0x777dd50c),L_(0x000001f4), + LL(0x57bfa90e,0xfe3fcdbd),LL(0x118dee98,0xcfc4ad1b),LL(0x0a524cec,0x6d1ffa5c),LL(0xe0d7420c,0x919d859d),LL(0x44af5553,0xf81fb745),LL(0x0981d6de,0xa17a7c3f),LL(0x6680c297,0xe0cc4fe7),LL(0xf6d22135,0xde36e57a),L_(0x00000115), LL(0xd78b0a1b,0x0b8ae03f),LL(0xac0c4195,0xc2638c06),LL(0xc994e2c7,0x4523ebb6),LL(0x49b75a94,0xdb72a765),LL(0x73310e2b,0x57a73d05),LL(0x8ce6d6b8,0x1e23ae4c),LL(0x4309eb9e,0x842f06ae),LL(0xf98aedc0,0xedf71264),L_(0x000000ed), + LL(0x7f81bbbd,0xbe47c62f),LL(0xd4c38f8c,0x49173568),LL(0x085a52c0,0x7d057b19),LL(0x612151d8,0x2de5c929),LL(0x8a4ea946,0xc4036de1),LL(0x0a8300dd,0x5a6e290b),LL(0x195518bc,0x894ed83e),LL(0x35e21097,0xd8dd898c),L_(0x00000074), LL(0x9a47676d,0xd0eee2e2),LL(0xc0b89ddf,0x8a7bf325),LL(0x0c5c995a,0xa5131a24),LL(0x9573e514,0xe5998b6e),LL(0x93979878,0x7ba59336),LL(0x7906f3c8,0xff513215),LL(0x093cead5,0xb76588a1),LL(0x243bc2e1,0x5abc03c8),L_(0x00000005), + LL(0x1074b7de,0x07c9d208),LL(0x234d2231,0x524b8b4b),LL(0xc6fe7d17,0x469a9182),LL(0x688b3e26,0x35461f18),LL(0xb0f49d1d,0x78f9ef1e),LL(0x4bb2130a,0xe72b7216),LL(0x9240661e,0xec1e4e46),LL(0x294674d4,0x95346b15),L_(0x000001f1), LL(0x2beae096,0xa594d4cd),LL(0xf533e3fe,0xdb75a21c),LL(0x99051c26,0xea1a808b),LL(0x9c10237a,0x230cfcd1),LL(0xe6396566,0x90aedfcf),LL(0x18cdd934,0x8c399655),LL(0x446502d8,0x0de6be10),LL(0x4a6de065,0x7b3640aa),L_(0x00000048), + LL(0x4f3b2020,0xf6315f2c),LL(0xf2e07c55,0x62ee6844),LL(0x9040fc8f,0xaf168881),LL(0xaec6bb02,0xa1922677),LL(0x968e4dee,0x53b90132),LL(0x92b21f9e,0x2b9cb75f),LL(0x4ae4c1d6,0x65408d1b),LL(0xd20f3732,0x70be8f94),L_(0x0000013d), LL(0xb2d1ac5c,0x05c00995),LL(0x4e16ae2b,0xf20b5acf),LL(0xd04ee882,0x1f8c5834),LL(0x35db5e06,0xc9dbfe41),LL(0x3a42f540,0x3f7b55b6),LL(0x500e266e,0x52ce3b47),LL(0xda6911e6,0x0c53d0a4),LL(0xee43c4db,0x6052a6d7),L_(0x00000194), + LL(0xfdcd47d9,0xf7f0245d),LL(0xc1b6e80d,0xd2bf51a5),LL(0x9077fd5b,0x4a61b710),LL(0x97dc422c,0x3089abb3),LL(0x2c00b155,0x893fa316),LL(0x40add702,0xb9d804ac),LL(0xc77985f1,0xdfaaf13d),LL(0x4150d1b3,0xaf9d85b4),L_(0x0000016c), LL(0x24cad038,0x92589d47),LL(0xd0dfdf3a,0x06f77875),LL(0x6b4012d5,0xfe067b9f),LL(0x4426c933,0x2ed7298d),LL(0x5353c502,0x67948217),LL(0x156d92c1,0xf0f675fa),LL(0xee2b368d,0xba020dd5),LL(0x3367f41b,0xd5aae0ea),L_(0x00000182), + LL(0xf394cccf,0x75917fbb),LL(0x1b52b513,0x87569974),LL(0xbeb1242f,0x4a568f34),LL(0xb03e5543,0x86a66b14),LL(0xc094f1b5,0x93edd5ae),LL(0x7da45bde,0x2fb2c47a),LL(0x960491e1,0x678ce19f),LL(0x890efc78,0xf4853187),L_(0x00000031), LL(0x7699808a,0x4363742f),LL(0xd3a570ac,0x1812091b),LL(0x4961aaea,0xd32e88d4),LL(0x97dd4a2f,0x1b33e755),LL(0xb3987552,0x79ed95a8),LL(0x669664b0,0x0837ce5b),LL(0x3584f341,0x3f9a0cc0),LL(0x116266b7,0x64a902cc),L_(0x000000e0), + LL(0x68c78f5b,0x0660e9a1),LL(0xb0698be3,0x5c045493),LL(0xc1ca94da,0x82b986b9),LL(0x4e8d0287,0xfafe7c0e),LL(0x02cfcf45,0x9235965c),LL(0xcf187fb8,0x316bebe3),LL(0x3fb90363,0xc42b951d),LL(0xc6248aec,0x26710295),L_(0x00000078), LL(0x5d4d89fa,0xc24f0956),LL(0xa11f38e2,0x398a2047),LL(0x9a0accc0,0x9e479268),LL(0x8ccafb17,0x468f61d6),LL(0x0c01f836,0x52f96c75),LL(0xeb043b98,0xacc6ee07),LL(0xa59405be,0xc63baaf6),LL(0xeddd33c9,0xba136442),L_(0x00000009), + LL(0x6e231385,0xc33b7b64),LL(0x1eb1f532,0x3bd3bca3),LL(0x3a7aee90,0x0882ad60),LL(0xad95f2eb,0xddaf31c3),LL(0x4c9d8e29,0x59c130df),LL(0xbdd1470a,0x7ac309bd),LL(0xe3bf394f,0xaafb8369),LL(0xedba4812,0x7f598209),L_(0x000000e8), LL(0x8bea28c8,0xb5d505d9),LL(0x81e772f9,0xfa065dfd),LL(0x15db5d5b,0x7e590809),LL(0x141e8679,0xc4ffd236),LL(0xf14602ff,0xbf521149),LL(0xcfd2b215,0xc500a7a4),LL(0xc04e3706,0xe4c06db1),LL(0x3e28ec80,0x93d40cbc),L_(0x00000009), + LL(0xb6cf9729,0x530c705b),LL(0x1a470405,0xe8292e38),LL(0x85b81d18,0xc5fdb2b2),LL(0x484b843b,0xa859e4fe),LL(0xeeae06f4,0x4e3895d5),LL(0x0a67c915,0xe6119b5b),LL(0xed968aa0,0x9264e00f),LL(0x66ed4c20,0xbf1d85ad),L_(0x00000091), LL(0x8c186038,0xd8a9d836),LL(0xee5d4b51,0xcf0b68ca),LL(0x89ad96c1,0xbcd75bca),LL(0xae1fa341,0x667fbe53),LL(0xa297bd27,0xe40caf5f),LL(0xd6165d4f,0x329b45f8),LL(0x62d6bced,0xc11413bc),LL(0xd1c11022,0x7e0d7384),L_(0x000000b1), + LL(0x422577fe,0xa39b851e),LL(0xa0188e61,0xf5e55bb8),LL(0xe96325dc,0x8cd5c092),LL(0x9087223b,0xe2c1a18b),LL(0xca56bfcd,0x548d8395),LL(0x4ae67f8d,0xaa6db861),LL(0x8f44b4e9,0x218ba5b9),LL(0x317abb0e,0x04386052),L_(0x000000d2), LL(0x27c1441a,0x91b2e14e),LL(0x6ac7c848,0x5377e2b3),LL(0xd40844b6,0x9d93badb),LL(0xe505b8cb,0x4d7f3493),LL(0x615a64c9,0x20a05d5d),LL(0x90a5eb78,0xa4cb086a),LL(0xed4783ac,0x36415b6c),LL(0xf10f3d20,0x56659094),L_(0x00000179), + LL(0x8da0847c,0x0eeb045d),LL(0xac240867,0x98145c00),LL(0xe7ce6952,0xb5d0c780),LL(0x315dd662,0x189fc413),LL(0x41646f48,0x4392d048),LL(0xc963ad1a,0x1e77199f),LL(0xebc649ee,0x83e1f918),LL(0xcd6ca624,0x13b6a99b),L_(0x00000169), LL(0xa873cec3,0x2108af54),LL(0x0b55c26f,0x3989bd71),LL(0xe0f27726,0x1e5e0053),LL(0x5c7e0958,0xa8452157),LL(0xf8e7b504,0xb64d38bf),LL(0xf180ac5c,0x8c8c65f5),LL(0x32a84a9b,0x8f00c232),LL(0x898ca7ed,0x1a1639de),L_(0x00000096), + LL(0x5f1724ec,0x6746f213),LL(0xe1073527,0xa966b0a8),LL(0x3ad14203,0x5bc4272f),LL(0x39620db2,0xbcd33a93),LL(0xe5eae695,0x26bac2fb),LL(0x0e4497dc,0xb7d647bd),LL(0x3a195407,0x7f7ed906),LL(0x899ce3f6,0xadd76129),L_(0x000000f3), LL(0xd7a2bdd5,0x333eb7cb),LL(0x51de1b18,0x8e185580),LL(0xa269b8e8,0x486cd055),LL(0x3555823a,0x6689b4be),LL(0xaa52baba,0xcd8d6ffd),LL(0xd072a45c,0x9cba9f57),LL(0xba53f86f,0x74a8d5fb),LL(0x16481f57,0x10747d58),L_(0x00000010), +} +}; +#else +const __ALIGN64 P521_POINT_AFFINE ec_p521r1_precomputed[105][16] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0xb331a163,0x18e172de),LL(0x4dfcbf3f,0xe0c2b521),LL(0x6f19a459,0x93d17fd4),LL(0x947f0ee0,0x3bf7f3ac),LL(0xdd50a5af,0xb035a69e),LL(0x90fc1457,0x9c829fda),LL(0x214e3240,0xb311cada),LL(0xe6cf1f65,0x5b820274),L_(0x00000103), LL(0x28460e4a,0x3b4fe8b3),LL(0x20445f4a,0x43513961),LL(0xb09a9e38,0x809fd683),LL(0x2062a85c,0x4caf7a13),LL(0x164bf739,0x8b939f33),LL(0x340bd7de,0x24abcda2),LL(0xeccc7aa2,0xda163e8d),LL(0x022e452f,0x3c4d1de0),L_(0x000000b5), + LL(0x1e90cf08,0x99dd36bc),LL(0xb3fa1f1c,0xb26b07ec),LL(0xa0e797d1,0x1d1ae2d7),LL(0x83d50825,0x6d377aaa),LL(0x4bd9d902,0x82ebb4df),LL(0x1a96372a,0xcd8e6603),LL(0x3a3a0193,0x40a46141),LL(0x3417e594,0x1213bf3f),L_(0x000000c8), LL(0x813d2ee3,0x6b30fa0d),LL(0x7b8df1ab,0x4af6e07a),LL(0x7a757e5f,0xd4cd1924),LL(0xb5c9c9bf,0xef4f928f),LL(0xddd9f1bb,0x4c836216),LL(0xa05590d1,0x3e26d4bb),LL(0x5ae35a88,0x777769f8),LL(0x8053f9f6,0xfc36d933),L_(0x00000063), + LL(0xbee9cf4d,0x976f1bd6),LL(0x02d2c8ce,0x43161975),LL(0x0dd75a48,0x8b5acff1),LL(0x028ed35e,0x251d2419),LL(0xe8d69f8b,0x0896bd46),LL(0x5cf2d6bd,0x2d891ecd),LL(0x3cda9537,0x325acaca),LL(0xaeec8eb5,0x21ef148c),L_(0x00000092), LL(0x72cfa6c0,0x50f74360),LL(0x212fac46,0xde49d2c8),LL(0x867882e4,0x68ef61e3),LL(0xd816ad67,0x67c6e2ba),LL(0x761716ea,0x8fd1aae7),LL(0x8be97c55,0xd4154e81),LL(0x7978aabf,0x63655c0a),LL(0xeccbcfc3,0xbefd316e),L_(0x000001dc), + LL(0x798d6d77,0x09438c81),LL(0xf17de43a,0x2d8472d2),LL(0x3350ea81,0x4f83c578),LL(0xa8745c47,0x257f1e83),LL(0x56432cf1,0xaaa0e9e7),LL(0x7e0362ea,0x8e2ff9cd),LL(0x66e30e44,0xa43e4838),LL(0x61aa5a41,0x57156102),L_(0x000001b2), LL(0x86a0825b,0xfe1a3726),LL(0xecf10fa3,0x78234ce8),LL(0xf75dbfd7,0xa854adc2),LL(0xa029127b,0xf2a5d1c2),LL(0xf93cf941,0xf178cc83),LL(0x0dad731f,0x7b737197),LL(0xdb2a90d7,0xc7585a55),LL(0x5b39f00b,0x13093ce9),L_(0x000001c2), + LL(0x3c194afc,0x4b764798),LL(0x9c6ad5a8,0xf36c498b),LL(0xd194ebf0,0x5789bf3c),LL(0x11b8897f,0x36af180a),LL(0x721c1e06,0x5c78bbd6),LL(0x926781ed,0x7eda9f86),LL(0x5fbd2cb7,0xc8e02758),LL(0x639ede19,0x9493d219),L_(0x000001e2), LL(0x65d6f9bb,0xf46f5848),LL(0xfc0b9e61,0x92b9aa7b),LL(0xbce8f803,0x108e7aff),LL(0xba188aa0,0xe4839679),LL(0x43ddb44b,0xe4d01a38),LL(0x28f6ec0b,0x47439700),LL(0x488e6c7f,0x88a54089),LL(0x764515b9,0xeeb300eb),L_(0x0000018d), + LL(0x5cfb915a,0xf6fbc903),LL(0x5711b98d,0xab2bf9c0),LL(0x4617b374,0x11ca98df),LL(0xca70393d,0x0b0a9fb9),LL(0xa92fde65,0x56f25580),LL(0x79cc0a83,0x4bbfeb8e),LL(0xcab11e98,0x7ca24068),LL(0xa9977f9a,0x66dac90c),L_(0x000000eb), LL(0x8bf78095,0xbc2c6a27),LL(0x6f0f5666,0x5aae506d),LL(0x101ee3dc,0x26f13a79),LL(0x4efcb64c,0x872b3246),LL(0x4b655b96,0x93100d45),LL(0x47392054,0xb9ed2d40),LL(0x889555dd,0x82a371d8),LL(0x35716e93,0x866327ac),L_(0x000000d6), + LL(0x6a15b574,0xc4140b76),LL(0xcd00e756,0xa87ee130),LL(0xe237ca9f,0x986e71dd),LL(0x6c64d36f,0x855fe34c),LL(0x2ec61846,0x617b88a6),LL(0x14780c69,0x747aa419),LL(0x062f9170,0xed05839d),LL(0xa3775b2f,0xceadbfb1),L_(0x000000ec), LL(0x8d8f4b46,0xe4829292),LL(0x3dae35c5,0x952eef7e),LL(0x2fcf3b38,0xa2c8e70d),LL(0x15ca91d1,0x49e6f64f),LL(0x2ab5e879,0xc51365ef),LL(0x6eb8edec,0x68141278),LL(0x3c5ae2c1,0xbd1ceb42),LL(0x8868ec18,0xcdd55150),L_(0x000001be), + LL(0x340208b1,0x2a553c67),LL(0x02c37cf5,0xdad37a02),LL(0x0d5ab144,0x0de46bcf),LL(0xf845acc6,0xdc2bcfa4),LL(0xc7adff52,0x82fc1314),LL(0x0545c51d,0xc54d801f),LL(0x2dea714e,0xcb580871),LL(0x31541a41,0xdb180fb9),L_(0x00000007), LL(0x0e58cc64,0x788f8bc0),LL(0xa9c56b21,0xa004a389),LL(0x34cf9dd4,0xf832e2bc),LL(0x5ff85d06,0x552c88da),LL(0x78c4f4e0,0x30833bd4),LL(0xada841ef,0xf4f16038),LL(0xcd227c76,0xb73c429d),LL(0x10247ed5,0xaaa17e24),L_(0x0000008e), + LL(0x03d614e2,0x3cb3e5f1),LL(0x330fa2b1,0x5ec2e694),LL(0xc7a7a85d,0x6fb92d18),LL(0x1af9e2ab,0x9cb09a6d),LL(0x32ba14f0,0xa2dc635b),LL(0x4c962558,0x0dcc43a3),LL(0x44769a2a,0x8ab8ab6a),LL(0x13517adf,0xacf0f10c),L_(0x000000f1), LL(0x270a8b98,0x435cd695),LL(0x9a1d5075,0x74944407),LL(0x3eb9b615,0x67a55fec),LL(0x4207fab7,0xbab02bd6),LL(0x3706b4f2,0x131eeda2),LL(0xdb6412dd,0x2a770e75),LL(0xc7184453,0xbd13d749),LL(0xcf85aaaa,0x4d4576f9),L_(0x000000c6), + LL(0x90643ae3,0xd0279799),LL(0xcd43ff84,0x8f8d4740),LL(0xf9be1720,0xd4c21049),LL(0x94ced526,0xbc7e6131),LL(0x885163e0,0x588d6d44),LL(0xe1a54923,0xcd604d63),LL(0x66c80ec3,0xdb390f62),LL(0x0efe7f3d,0x5ed30f94),L_(0x00000191), LL(0xacfad765,0x4c09af63),LL(0x0b94aa5e,0x1cb9cfd5),LL(0xf7f9b44b,0xb1ee2bf5),LL(0x5da9b7b0,0xea26cc32),LL(0x695fa9a4,0xc53177b1),LL(0x05d4bfeb,0x0a2128d9),LL(0xb0617759,0xd86515d3),LL(0x4edd7559,0x248b0a5d),L_(0x0000015c), + LL(0xcd229d61,0x16ed066d),LL(0x81766070,0x27d264d4),LL(0x4280ae01,0x75f18c88),LL(0x0de8cd8d,0x999331ed),LL(0x2979ede2,0x2a794c8b),LL(0x4aa1f796,0xf6be0bc2),LL(0xe7f6aee3,0xab9da18a),LL(0xaa378d1c,0x2cfef6ff),L_(0x00000009), LL(0x0425becc,0xc9672464),LL(0xaeac43a7,0x71fa40cd),LL(0x9b6e5640,0x8c8a54a9),LL(0x559c4919,0x8745a152),LL(0x158de454,0xea705cdc),LL(0x49f6974a,0x31085e82),LL(0x149d6eab,0x3b82a7d9),LL(0xc24e8654,0xe5dd1094),L_(0x0000001f), + LL(0xc6703677,0xb8dfc216),LL(0x58bdf34a,0xae298494),LL(0x009bba63,0x4d30749c),LL(0x98a3bff7,0xbe1fdc0d),LL(0xd3227485,0xd2cb3b89),LL(0xdb083e7b,0xabcac22b),LL(0x0f40c3a0,0xba4e3fef),LL(0x2ef27d74,0x49fc110e),L_(0x00000076), LL(0xf850122d,0xd1940d8b),LL(0x363cf3d8,0x91127ad7),LL(0x184425d3,0x7ca8dcdb),LL(0xdb660853,0x21ec37e6),LL(0x4beb68c4,0x5fb50be0),LL(0xd22f2025,0xd5b8a4a6),LL(0x23b1ff32,0x81d34165),LL(0x7f1e70e8,0x352493e0),L_(0x000000ca), + LL(0xd39f8fa6,0x46997de6),LL(0xfc0c43c2,0x80559c77),LL(0x74a5f61d,0xf3cd5c47),LL(0xb51aa852,0x84701e4c),LL(0x3099622c,0x5f57adc3),LL(0x1c2776e9,0x66f0da61),LL(0x0d49fb9b,0x95a49243),LL(0xce6bc32e,0xc261cb56),L_(0x0000007c), LL(0xe4c23b96,0xfd811538),LL(0xfb948d00,0x57c88bf4),LL(0xe1b0ccf5,0x9a8e5fdd),LL(0x1f936fee,0xac1c5e3b),LL(0x9560deae,0xd72e0f10),LL(0xe34e3d33,0x1c36aa10),LL(0x04676a85,0x6d51f6ad),LL(0xd48d0c93,0xb6bc0ff6),L_(0x00000075), + LL(0xba61d6f1,0x16e9a196),LL(0xae964f34,0x5c0977df),LL(0x5533b3fb,0x25bde3a2),LL(0x16bcef9f,0x645c4b91),LL(0xccba7e03,0xd5f0598c),LL(0x17ea7d85,0x0a4a08b5),LL(0x68cac5a0,0x7d57c26f),LL(0xd4f0dc66,0x2a8d8db2),L_(0x000001ee), LL(0xa5172924,0xc293806a),LL(0x5f20b34f,0xa9d43e42),LL(0x06adb487,0xf8e899ee),LL(0x2608f44d,0xd8da79ac),LL(0xb1683bc0,0x4dc36bf6),LL(0x350423e7,0x15c728c1),LL(0xfdc23809,0x5dd5da5e),LL(0xe96b3148,0xbaed65ad),L_(0x0000011a), + LL(0xaa9adab6,0x9bde5c6d),LL(0x5ef4d7f1,0x4c0f1fc9),LL(0x8ecdc6cb,0x8e47e019),LL(0xff3c3ade,0x13ede807),LL(0x08dc8e67,0x996f8947),LL(0x296b4bda,0x185a0504),LL(0x07dc7de6,0xe2a36a18),LL(0xf820aac7,0x5e5c9232),L_(0x0000004d), LL(0x32ed1a36,0x4050a3aa),LL(0xecab1a1a,0x6622355e),LL(0xc9237ec8,0x11964b64),LL(0x4010a471,0x644ca385),LL(0x6abf4831,0x34cba42f),LL(0x5d25b108,0x54dd6906),LL(0xb1ef824b,0x9199f6df),LL(0xb53e7326,0x8ab89c8e),L_(0x00000113), + LL(0x17f45f44,0x47c0d420),LL(0x299d3628,0x4003ee6e),LL(0x6f86dfae,0xd3cc2b18),LL(0x5072cb2e,0xc430e500),LL(0x294a1ff8,0x69058c45),LL(0x9eeb197c,0x30c97e9f),LL(0x859543fb,0x13563a1d),LL(0x2eed4bed,0x544e4568),L_(0x0000006c), LL(0x5f1e8dcd,0x7c4de39d),LL(0x99a97139,0x69468c31),LL(0x294f1802,0xd64eccc4),LL(0xd505983a,0x9cc6daa3),LL(0x60e0c170,0x64a5b5c1),LL(0x8763e518,0x61dc006a),LL(0xb9099af2,0xc69e9f34),LL(0x0fe38a58,0x2c16bb80),L_(0x0000001e), +}, +/* digit=1 base_pwr=2^5 */ +{ + LL(0x4f59ae8d,0x5c3b72b5),LL(0xc123c8ad,0xae6b62e3),LL(0xca4e7ba3,0xeb5d2e8f),LL(0x7633eb4d,0xaee39acb),LL(0xeb750251,0x77dcf2f5),LL(0x1c6dd3f6,0x32a70340),LL(0x9a1f1f0b,0x7ca5d0ad),LL(0x4a21b83d,0x69051d23),L_(0x000000cb), LL(0x5511dec3,0x4c8a50ab),LL(0x1b4ae54d,0xb2d5cb0b),LL(0x6fe6cc64,0xe3f5079b),LL(0x5cdba6f0,0xdc0c66eb),LL(0xbef10266,0xe32e16eb),LL(0xb3e0ef80,0x5faff80c),LL(0x347fbdec,0xaff9f041),LL(0x088b1af3,0x68ca055c),L_(0x000001fa), + LL(0xa16ae6a8,0xc671907b),LL(0xa0da9ee1,0x014d027e),LL(0x0efad55c,0x0b01f380),LL(0xb9d3e016,0xe2f7ed1b),LL(0x938df5e9,0xe67c4396),LL(0xd65b0a5c,0xd40c305d),LL(0x533f5edd,0x01c97f61),LL(0x68a79ebe,0xe7088976),L_(0x000000be), LL(0xad9d235c,0x2c52fc6f),LL(0xea2d78b8,0xedd0329e),LL(0x21e0e0d2,0xf1d7cac0),LL(0x887a53dc,0xd0a846a5),LL(0xc5d60b2d,0x1b4f43d5),LL(0x0e8631dd,0x4597d8ee),LL(0x36cdd8e6,0xbe2bdcac),LL(0xb9d50810,0xc2474902),L_(0x00000075), + LL(0x571ccaa7,0xcc45066e),LL(0x3f9b1980,0x05f6f02b),LL(0x6757639e,0xe84f381f),LL(0x4e03775c,0x5ef348d1),LL(0x4770c353,0x3845ff7f),LL(0x5fb50c57,0xedbd5036),LL(0x5b16a317,0xe0ae9613),LL(0xbda8a1ca,0xab626b1c),L_(0x000000f2), LL(0x2efb5af8,0xce499e42),LL(0xdea5dcca,0xf85f9a34),LL(0x8fc76f8d,0x07899ffe),LL(0x0f62f621,0xbdb94b70),LL(0x648a20af,0xfe99ecf5),LL(0x436c353f,0xd5421253),LL(0x3fcac929,0xe3d53ffd),LL(0xa9413337,0xdbd78092),L_(0x00000158), + LL(0xf05f3504,0x72b9b7d4),LL(0xdabb5813,0x90711a09),LL(0xa79713f3,0x40b52fc0),LL(0xbea8efb8,0xb43b138e),LL(0xcba724a4,0x7bae703e),LL(0x96698925,0x5de16b6e),LL(0xd41e4b4c,0x80a9811f),LL(0xc1b18e03,0xf93f1c0f),L_(0x0000012c), LL(0x989bdb97,0x0964efd8),LL(0x725e184a,0x049a3954),LL(0x09871a1a,0x92325673),LL(0x462734e1,0x586e4cd6),LL(0x54d24ffa,0xe1d8d7ce),LL(0xb30da7d5,0x69f3efbc),LL(0x416e700f,0xef7de3d3),LL(0xe729987f,0x8354141e),L_(0x000000fa), + LL(0x08a54bd7,0x32ffe09a),LL(0x456c0723,0xd6fc852f),LL(0x40d62750,0x2ffa7f72),LL(0x4aeb61e4,0xe7b77ac3),LL(0x502b124f,0xfe47dfb6),LL(0x4dd6a90a,0x06cd1ac4),LL(0xa6600862,0x47e8bdf2),LL(0x9f7f4801,0x3d29e3f1),L_(0x0000009f), LL(0x0fde861b,0xc7487c32),LL(0x94ff60ca,0x23970cbd),LL(0x72b3e644,0x6984aedb),LL(0xcc2f8476,0x43e3b1aa),LL(0x4e288fca,0xd6b84507),LL(0x5c070a30,0xcde70c2f),LL(0x806889c8,0x9397e29b),LL(0x4c71559f,0x35a4b1e0),L_(0x0000000b), + LL(0x85707b44,0xfaa21460),LL(0xdf0df8fc,0x6496b635),LL(0xa66cdf1c,0x72a3871c),LL(0x9e220e51,0x55171f57),LL(0x76519fbf,0x2bc7ff1e),LL(0x1fe67c09,0x4f8bd386),LL(0x55ed0240,0xc5765e29),LL(0x1c77281d,0x27bc3df5),L_(0x00000160), LL(0x9e78f5c3,0x38d57586),LL(0x6a14b857,0xa24ce77d),LL(0x956a40cd,0x6eeb21f0),LL(0x384b0097,0x30d4fd92),LL(0x3f99bf29,0xce9aade0),LL(0x0b162be5,0xc168443c),LL(0x056730f0,0x8b3af3cd),LL(0x86e7a481,0x043e9d2a),L_(0x0000010a), + LL(0xd9b7e5ae,0xd2292194),LL(0xc11a98a6,0x0b648125),LL(0x59e37b44,0xaf635b08),LL(0x25aea6af,0x19039f0b),LL(0xd7528475,0xd304853b),LL(0x17b80f08,0x08f86bd4),LL(0x16cad388,0x4ba43b52),LL(0xd0f1e285,0x084ad45e),L_(0x000000b9), LL(0x7719f6ae,0x0e419d0c),LL(0x808c65ad,0x5ed42353),LL(0x2e40948b,0xc831c79b),LL(0x95dfdfbe,0x1f8615c2),LL(0x19810fc6,0xd5083188),LL(0xc73c4dd3,0x9df9fc10),LL(0xb9ee4c0f,0xb094cd65),LL(0x75870f78,0x4c55caa4),L_(0x0000009c), + LL(0x56757d02,0xc834df00),LL(0xc0d9c745,0xe5caf285),LL(0x91f23599,0x620faea3),LL(0x2d4e48a9,0xb7461523),LL(0x99bdc7a7,0xf47934e5),LL(0xd4dc2fd4,0x4f65ada3),LL(0x4c81e39c,0x3c079897),LL(0x64a2c57e,0x815ad610),L_(0x00000107), LL(0x3fa38d40,0x22a435ef),LL(0xc247d609,0xa826a53b),LL(0x3d8a1866,0xcede94d3),LL(0x75ac695c,0x2b9c71de),LL(0x8bcb2e7b,0xd52b9aa7),LL(0x1a8316e1,0x40f2da2b),LL(0xe2a07695,0x49881db4),LL(0x7e4c0ddd,0x39a09e21),L_(0x000001d5), + LL(0x7118ea7a,0xe663ce23),LL(0xd6a550c8,0x67612dfd),LL(0x45b8de7d,0xd0a752b6),LL(0x1b9bd789,0x60ad3301),LL(0x023b6c29,0xcc26ecce),LL(0xa078b41a,0x61239a1a),LL(0xee942cd7,0x6922505f),LL(0x5e08263e,0xe76fdb87),L_(0x00000029), LL(0x1108fef0,0xe9adb593),LL(0xe4610492,0x509096b8),LL(0x26279733,0x4c917c92),LL(0xc7a80802,0x7516cc5c),LL(0x8edbea9c,0x131d3769),LL(0x1db92a9d,0xe32f86b9),LL(0xc3bfb615,0x16237fcf),LL(0xdaad00e7,0xe0767305),L_(0x000001c0), + LL(0x726d1da3,0xd0f5eba7),LL(0x5afe82c9,0x00a2bafd),LL(0xa7f8f99a,0x8c282afe),LL(0x5344cf5a,0xa7ab3e18),LL(0xb4f699ab,0x2626fca8),LL(0x345363ae,0xc44f5f11),LL(0x9cac1c3a,0xa135f6b3),LL(0x2cc9c6d3,0x3b77c483),L_(0x000001e8), LL(0x90784ad0,0x4491c85e),LL(0xc87a8f35,0x23793bcb),LL(0x9606baed,0xcd6ee91d),LL(0xaa42a14a,0x54d429b3),LL(0x40a29e37,0x89ff244a),LL(0xd4a2c066,0x0bb505cb),LL(0xdc545060,0xfc93a903),LL(0xad7e26a4,0xc3b67c6e),L_(0x000001fe), + LL(0x8ceb07a2,0x96bcc3d3),LL(0x99d9281c,0x3db83972),LL(0x3ff2e9a3,0x16268498),LL(0x00d03fc3,0xf0d72767),LL(0x974db3bc,0x52e2c15d),LL(0xcfc51b17,0xe4156324),LL(0x10aa8cfe,0x989f0141),LL(0x8e68c302,0x9e3bb348),L_(0x00000058), LL(0xb1ff4858,0x798b01e9),LL(0xb7bcaeeb,0xb107b933),LL(0x0bdcd04d,0x5499a0b1),LL(0x26fd1d2e,0xacddcbd8),LL(0x56837ddc,0xa9081a22),LL(0x3bdf1491,0x05c3276e),LL(0xc07890c9,0x91891ac9),LL(0xa184d413,0x925157ab),L_(0x00000171), + LL(0x8bff7233,0x91b8350b),LL(0xf62b4383,0xb265f67b),LL(0xc46f7226,0x21d7036a),LL(0xef90907e,0x8034aa28),LL(0xdabc0434,0xd005b709),LL(0xb12cb388,0x06bb608b),LL(0xe65c7159,0xeb7b8a18),LL(0x11e0f987,0x7aab899b),L_(0x000001f6), LL(0x8d53586a,0x0ab2f2c0),LL(0xe3db9e6a,0x80aa8220),LL(0xb7b44599,0x2bea87eb),LL(0xa54e5ad3,0x6c5ac479),LL(0x93b927af,0x83fb3fac),LL(0x62a4775c,0x9c4bd501),LL(0x657b8d9a,0x88136dc2),LL(0x31811cf2,0x2b887e73),L_(0x00000185), + LL(0x4d4e2e15,0xa3ad1cf1),LL(0xf792f378,0x7aef7449),LL(0x4d833ce0,0x5394ba78),LL(0x06fcfedb,0xf33fd365),LL(0x76965949,0x9c4ccb42),LL(0x4e9fbd73,0x61aaa0a9),LL(0x9fa1995c,0x3ba114e8),LL(0x462ee846,0x7540468d),L_(0x000000cf), LL(0x0442839b,0x46e8546b),LL(0x4cfa345f,0x0d411f16),LL(0xc1e9119e,0xf8d99149),LL(0x0deb6f34,0xb98975e2),LL(0x6508c235,0x6e32684a),LL(0x741c5884,0x99583d46),LL(0xacaecb2f,0xd61998e0),LL(0xdc28ccee,0x1ef321fc),L_(0x000001db), + LL(0x22a3dc2c,0xbc8dbffe),LL(0xf713e616,0xbe6a57a2),LL(0xbe89cc5f,0x5dfb0ead),LL(0xb5bd5287,0x5dba909b),LL(0xff87fb08,0x124b1f29),LL(0xd39afe41,0x8ad8951f),LL(0x0e13a626,0x2f09f744),LL(0x4826695e,0x44419020),L_(0x00000036), LL(0x89f11d49,0xd8b689b1),LL(0x42cf8f40,0x8f4bb929),LL(0x1093f58a,0x41b6334a),LL(0x5f1b0229,0xcbfc9d3f),LL(0xfa09f9c8,0x4f838812),LL(0x4ae0b40b,0x114194e2),LL(0x6d9844d6,0x69722fe6),LL(0x15e4c6d7,0xb8f4264f),L_(0x000001cf), + LL(0x2f86d0f6,0xf27fea27),LL(0xb102e317,0xf76070d1),LL(0xb05afc5b,0x1c9d3a3b),LL(0x5dd0f5d9,0x00e4d9fc),LL(0xee4d6689,0x65f0f1c6),LL(0x2a86ba85,0xde562216),LL(0x3e6bfc0d,0xdbfc35a2),LL(0x9af0f242,0x5ad61eda),L_(0x00000142), LL(0x941bae5d,0x2b9df6f5),LL(0x5be1e379,0x818b63c5),LL(0x35a1da29,0x7c374ecf),LL(0x81936096,0x91cdc4c0),LL(0x32597a76,0x72e4e5df),LL(0x3e8a2fa3,0x5b7351e8),LL(0x916e7f8d,0x19372aca),LL(0xabd62e9d,0xe3d4016a),L_(0x0000015c), + LL(0xc98396a0,0x1d4dea3f),LL(0x2852471e,0xf1b1b604),LL(0x9e270a42,0xbff87527),LL(0xe46c1327,0xfe022231),LL(0xfc05c823,0xe4c1b07e),LL(0xa4581988,0x46e86dbf),LL(0xc3803e03,0xf3ea14d7),LL(0x8c2f4163,0x3536b269),L_(0x00000094), LL(0x474df73f,0x3f77cba0),LL(0x82f0ebae,0x9fac52f4),LL(0xeabe2a5c,0x4d046303),LL(0x5a86c777,0xd8716f60),LL(0x16157561,0x76cfe4cf),LL(0x564b6dae,0xf10528e0),LL(0x9113bb26,0x878d8ad6),LL(0x933ccc8b,0xc9676c2f),L_(0x00000038), +}, +/* digit=2 base_pwr=2^10 */ +{ + LL(0x7c6312ff,0xb394c36d),LL(0xd8c526b5,0xae9f8123),LL(0x6b7fb3e1,0x7287a461),LL(0x2d9f22f9,0xd21b31a9),LL(0x895d4a0f,0xd7cbfded),LL(0x81ff2d23,0x5c105748),LL(0xe830bd0b,0x4fe2bd04),LL(0x9dfeb777,0xdf56afd6),L_(0x000001fe), LL(0x83b243fc,0x7e7441cd),LL(0xa23e166b,0x5c91b009),LL(0x85f70865,0x122f85c7),LL(0x22e7768c,0x6db40321),LL(0x2fb75185,0xd6df94b8),LL(0x80b31836,0x98df3edc),LL(0xeea7ce80,0x05298e9a),LL(0x048ecb96,0x1e0476e6),L_(0x000001ed), + LL(0x8ec6fc14,0x292021e4),LL(0xa9680402,0x9500ecd0),LL(0xed719b16,0x41202339),LL(0xb81e8a19,0xb85440eb),LL(0xd40e8e4d,0x3f6a53c2),LL(0x84a12a31,0x2796c5c6),LL(0x497c0088,0x91636765),LL(0x751837b7,0x8b09820c),L_(0x0000014e), LL(0xd4740897,0xfeb6c7cf),LL(0x05fd0f39,0x66755043),LL(0x24da0165,0x915708d7),LL(0xcde5846c,0xc7bb1c3f),LL(0x0cbcc847,0x5d5c58a4),LL(0xd0093587,0x531dd999),LL(0x178ab52f,0x88ff3f98),LL(0x4485d318,0x35266a7c),L_(0x00000171), + LL(0x7f523b68,0x91acdac6),LL(0xe5501216,0x656f99d2),LL(0x9d6ec374,0xe158465f),LL(0xf67a8845,0x15ed0b99),LL(0x0ea75aec,0x01226fd6),LL(0xc000f5ba,0x0a951866),LL(0x2eb378e5,0x185feb1f),LL(0x746f4b9e,0xd7b2048c),L_(0x00000097), LL(0xae887bf0,0xc9deb828),LL(0x2d928546,0x4d8afcb8),LL(0x7759681c,0x47a77426),LL(0x1f2422bc,0x9941fb7f),LL(0xc9c44935,0x3b4f41a6),LL(0x50ea43ef,0x708dbefd),LL(0x5c9f2544,0xcef3425f),LL(0x8d085b3a,0x17fe443d),L_(0x00000114), + LL(0x4dbc092f,0xa2f27fd6),LL(0xfff03850,0x2ad51407),LL(0x2ffc14aa,0xc4b80840),LL(0xbe516b67,0x4499107f),LL(0x0f027098,0x715688b4),LL(0x5e2c9af3,0xbddce779),LL(0x26ec8f7d,0xcc8a5dc6),LL(0xcc9e1305,0x6a9d132a),L_(0x000001c4), LL(0xcd14a595,0xce664e13),LL(0x678ff921,0xb7485d5a),LL(0xed6fe685,0xdd61d65f),LL(0x2b7d0453,0xa066d915),LL(0x81e48dc7,0x0c3395f0),LL(0xc1cb1256,0x6053e587),LL(0x630f2cdd,0xc776afca),LL(0xf0d70553,0x61da1814),L_(0x000000dc), + LL(0x71ac09f5,0xd012b2e5),LL(0x9190907b,0xc03bb972),LL(0xab45bb80,0x8ed0d272),LL(0x3b41e8eb,0xaa3449d8),LL(0xd2d64ef1,0x4e6b21d4),LL(0x9f7e0342,0x9eb72363),LL(0xb6336622,0x69f35a65),LL(0x9114adb9,0x24fc697e),L_(0x000001f5), LL(0x18b88dd7,0x489c82e7),LL(0x1d050011,0x5e1bdb72),LL(0x80ac7d35,0x3a785f6c),LL(0x6bb1ceb8,0x4d0595c0),LL(0x47ba8e65,0xf29ab5dc),LL(0xfba4c7c5,0x768427d3),LL(0xf250f0c9,0x38fed5ff),LL(0x60390918,0x655b698f),L_(0x000000eb), + LL(0xd8129c74,0x33a20918),LL(0x56ec57a8,0x44da27b8),LL(0xfe03052c,0x5c69a6e2),LL(0xb8645b34,0x61e0489c),LL(0xedf7eb89,0x0d9cee51),LL(0xb459ccf4,0x4bbdc11a),LL(0x2e3c7f1a,0x22591a2d),LL(0xab74c4c7,0xa982d5f8),L_(0x00000083), LL(0xffdc8f5b,0x9755e96d),LL(0x00d903b0,0x73fc3336),LL(0xa3ed2567,0xa44f5c0a),LL(0x78da9c2e,0x130585a8),LL(0x5d2a5778,0xf488bddc),LL(0x203a9db6,0x0d642fb8),LL(0x49bb8671,0x86aadd4d),LL(0xc216425a,0x20f6b6a8),L_(0x0000012f), + LL(0x106b0907,0x6c59b6a4),LL(0x77bee1fa,0x082792c1),LL(0x39609b3e,0x4e300675),LL(0x9586b280,0x41820c34),LL(0xf4b318a9,0x568da4bf),LL(0x504b9f0d,0x18b54e1d),LL(0x7cd449b1,0xea63bc73),LL(0x35d4426b,0x9a0a15d7),L_(0x0000001e), LL(0x0b6fffaa,0x5b9ffa5e),LL(0xc584b1b6,0xb1ee386e),LL(0x00bfc921,0x2e48b6f0),LL(0xc1a25580,0x90b9e7af),LL(0x232ccaec,0x60d7386e),LL(0xbcde0a94,0x27832dfe),LL(0x20ca19ad,0xa34dad1d),LL(0x2a628682,0xad3601ca),L_(0x00000146), + LL(0x61a19c36,0x5540d3da),LL(0xde90b954,0xfed5fc9d),LL(0x08cbe546,0x6579be89),LL(0x931292ec,0x31c8bf2b),LL(0xde0b2215,0x64709233),LL(0xf0e33dcf,0xa91e2913),LL(0x99299206,0x933880d8),LL(0xab37b024,0x63ef0d07),L_(0x0000010d), LL(0x6eb1d587,0x5f29f3ee),LL(0x6f46862b,0x13755e24),LL(0xe2652ae3,0x952c2e51),LL(0xba6a65e2,0x013b9446),LL(0x3fd1b792,0x5e7bffb4),LL(0x96a14917,0x66af7dd8),LL(0x68a41011,0x553d0d5f),LL(0x4ff29cf9,0x381be3a3),L_(0x00000010), + LL(0x1d7e25bf,0x707d2643),LL(0xb62058b6,0x3eddf1f7),LL(0xcf147bf5,0x09f87dab),LL(0x11a1e31b,0x9b643ba2),LL(0x4287faad,0x31ecf4ec),LL(0xfdf5220a,0xa4f09336),LL(0x8916b869,0xd2c73095),LL(0xe07b7112,0xe676b1a5),L_(0x00000038), LL(0xea00c98e,0x31798ea9),LL(0xee9f1bb9,0xa0db3168),LL(0x33aa5ab3,0x5107a1fa),LL(0xbb110cf5,0xccdd22ec),LL(0xedd17aae,0x8bb0cd07),LL(0x610d689f,0xcf178778),LL(0xcca4e56f,0x95d696e3),LL(0xaef30431,0x5f284888),L_(0x0000008d), + LL(0x7352fa9e,0x4590e4bc),LL(0x951e01ab,0x42b51fb7),LL(0x3643ff6f,0x1a3be50c),LL(0xdad9a3a4,0x5c6479b6),LL(0xb0a91741,0x5f9d3ca9),LL(0x841c9d52,0xbed2f70d),LL(0xdc8331dc,0x3fce8436),LL(0x0a312707,0xf8c4ccb2),L_(0x000001e6), LL(0x4d9d7ef9,0xaec9953a),LL(0x62242fd1,0x04665dd7),LL(0x49b9eb5e,0x7d7f1a35),LL(0x6a03ee74,0xcabc639f),LL(0x22cc5c02,0xf26d2603),LL(0xbb312bf5,0x05ee7955),LL(0x10cf1634,0x00c226f0),LL(0x3baa95d6,0x49ecb4bc),L_(0x00000144), + LL(0x968950c6,0xa826a58f),LL(0xe858945d,0x3a7fc7e7),LL(0xd63d6714,0x63d3c677),LL(0xc319d1ba,0x349e7bde),LL(0xb4155a1d,0x03a4c66e),LL(0x3ddc0044,0x77aa278e),LL(0xccce8941,0xd867d113),LL(0x4e46021e,0x06424305),L_(0x000000ad), LL(0x6dd54385,0xd8308ab7),LL(0x2e1458d6,0x0d0a4aaf),LL(0x924e3bd4,0x309fb2fb),LL(0x2f7cd47f,0x5161e4da),LL(0xbc75672b,0x27fa09f8),LL(0x0e420bf8,0x6bf78336),LL(0x83d1b09e,0x3c3d3117),LL(0x89323d7e,0x585a4d97),L_(0x00000059), + LL(0xe8b9e5f2,0x9e4c557e),LL(0xa63316be,0xc510883d),LL(0xfba63955,0x58616eed),LL(0x5eba66cb,0x1f901bb5),LL(0x7d93dd07,0xe4c33f46),LL(0xd7520d11,0x9c2288bd),LL(0x3c9b7282,0xa3f22d4f),LL(0xf979cce9,0xbc4f2416),L_(0x000001cb), LL(0x69f91fa6,0x1780ab39),LL(0x9f2b3904,0x1e17f9e9),LL(0x0408a22e,0xf102825a),LL(0xe814b39a,0x4077db13),LL(0x717c70c1,0x116e8d04),LL(0x1642fd91,0x5157bba1),LL(0x072760c2,0x223d53fd),LL(0xf596860d,0x68119130),L_(0x000000d6), + LL(0xd03914a2,0x1f8fa1cb),LL(0xbc0f726e,0xc55472bc),LL(0x9dcf7393,0xcc596835),LL(0x86ab65ea,0x0c9b7622),LL(0x90362f16,0x8c0ca08c),LL(0xe8de2a3c,0xec48a671),LL(0xbde41568,0x0286ac32),LL(0xd27da64f,0xdc224c38),L_(0x00000016), LL(0xf6c82cd6,0x53a87083),LL(0x3e753ee6,0xab548bed),LL(0x07afab6b,0xc34ddb60),LL(0xc0dc2ddc,0x378f8e85),LL(0x399c4261,0x5087e698),LL(0x6f7e49f2,0x07f39938),LL(0x6345ae4d,0xc730c9c6),LL(0xb6c2765f,0xfb522df3),L_(0x0000014d), + LL(0xe4292c6d,0xf4cf1a41),LL(0xfb9a8b65,0xf774c321),LL(0x5046d341,0x7b28d6b2),LL(0xfe598075,0xb06becbe),LL(0xc3187f95,0xd220a206),LL(0xc278703d,0x54ba06d2),LL(0xb514e8c6,0xda1d824d),LL(0xc959300e,0xc32680df),L_(0x000000c4), LL(0x7fbd13f4,0xec877f9e),LL(0xd0e494f0,0x209c6b0a),LL(0x529b0f0c,0xc6b1073b),LL(0x50fb2f00,0xd17f2e67),LL(0x80cd82a4,0x62378ddb),LL(0x9f57c57d,0x0162b312),LL(0xc234e4cb,0x8483d5e6),LL(0x501d8ec9,0x5438453f),L_(0x00000176), + LL(0x0d037502,0xd53d7a18),LL(0x424ed14d,0xd13f986d),LL(0x29de6753,0x3e4dbff0),LL(0x6d33dc1f,0xf6b77dc2),LL(0x87ad5722,0xbf6050c2),LL(0xaea8f254,0x83742064),LL(0xb17406b4,0x7d90e061),LL(0x13b29245,0x6d00e002),L_(0x00000097), LL(0x7f20e8bb,0x5bf160f5),LL(0x8562b323,0x1d2d2e90),LL(0x4b31d400,0xea7b242c),LL(0x4a1acb5c,0x229d7510),LL(0xc93f9b92,0x3eba408b),LL(0xb068a0e7,0xb0525ab0),LL(0xb376d6b0,0xd96dff43),LL(0xf1b03f82,0x78a56db4),L_(0x00000168), + LL(0x77ddddf5,0x631d2365),LL(0xc4b6db39,0x5fc5e812),LL(0xd1cccab0,0xc38ec807),LL(0x8729f1a1,0x1629e92c),LL(0xc999e406,0x6b4c00d1),LL(0x781d88f5,0x3cac8f29),LL(0xcce3380c,0x16b02141),LL(0xc7e0e0cc,0xcb8c9920),L_(0x000001a3), LL(0x76234580,0xd02da7d0),LL(0xe2d27b0a,0xcc82cf5a),LL(0x3adad7f2,0x2c08a15c),LL(0x7009305d,0x55fa7b4d),LL(0xde9e632a,0x0b55b693),LL(0x2a821156,0xb565732e),LL(0x3788cf98,0x89f0adb6),LL(0x2d1f6054,0x0705738e),L_(0x000001b1), +}, +/* digit=3 base_pwr=2^15 */ +{ + LL(0xb0c6a7b6,0x23a29c73),LL(0x9c3eafc7,0x392643c3),LL(0xf81be3c4,0x88c0b213),LL(0xec734fa3,0x33b98ae3),LL(0x9b26d37a,0x23074268),LL(0x687a332e,0x28354ec1),LL(0x6935b64e,0xf60d4b7e),LL(0x9d55aecf,0x437bcba7),L_(0x000000b6), LL(0xd6073362,0x8bcd336b),LL(0x5b5f67fb,0xb6c7a784),LL(0x5633e845,0xdf601730),LL(0xa907be72,0x2814a576),LL(0xfe65734d,0xc7084b86),LL(0x0758f113,0xd7bad9f2),LL(0x5030c22c,0x3ef6af2a),LL(0x7ff1cabc,0x15f43164),L_(0x00000122), + LL(0x6184cce9,0xac65525f),LL(0x5051a406,0xc9acc4f2),LL(0x651c4a44,0xb637bdd2),LL(0x571fa6bd,0x2ae9ce59),LL(0x4cf1489d,0xf56bdf32),LL(0x61b0a821,0xe5fa827f),LL(0x9dcea620,0x4b46a244),LL(0x7027c9ed,0x6e4d3c94),L_(0x000001d6), LL(0x0495f1c5,0x27a410cd),LL(0xee6432c2,0xbc9ba135),LL(0x73536858,0x53142570),LL(0x7e39c350,0xd0616e0b),LL(0x316eeb65,0xa694a069),LL(0x55bbe949,0x9aba0dc4),LL(0x1f9d7b76,0x32d36d72),LL(0x1dcb7a1d,0x9a8a0a04),L_(0x0000001a), + LL(0x0fce6d79,0x49c3fb55),LL(0x3a2f9da5,0x3a8e9a7e),LL(0x44e158ff,0xd771a67e),LL(0x7de21bd3,0xa6180b0e),LL(0x5cf6b900,0x349f9cad),LL(0x53ff2b3f,0x783786f1),LL(0xe350b1ce,0xec23cb86),LL(0x58690faa,0xbca103ef),L_(0x0000009a), LL(0xe8902691,0x4d7ea0cd),LL(0xdfaca68b,0x13648702),LL(0x595a974f,0x5bd316f2),LL(0xbf226a22,0xbb11b239),LL(0xeaee978b,0x2ab1e433),LL(0xc7607b51,0x870c9a0f),LL(0x43795a95,0xe00a29c5),LL(0x53d7cad7,0xd68ee860),L_(0x00000013), + LL(0x9b30d330,0x8312448f),LL(0x499ca6a8,0x27c12fd1),LL(0xaf5a132e,0xc3fb765e),LL(0x01b2d2a5,0x07951a8d),LL(0xce3517c8,0x97c68ed6),LL(0xe67d936a,0x8cdd161c),LL(0xad5eb28f,0x795d9876),LL(0x6496ac4a,0x2bca3997),L_(0x000001f8), LL(0x7fd91252,0x6e4dff62),LL(0xe44601e6,0xa96a9194),LL(0x84a673b1,0xf81ccae8),LL(0x06054966,0x2eba8c5d),LL(0x53226945,0x77e70b53),LL(0x17deba76,0x98891e5c),LL(0x2fe55a92,0xccf9a70e),LL(0x8b39032d,0xcf81d4d4),L_(0x0000009b), + LL(0x2c87d9f4,0xce45ab56),LL(0x0de1dc21,0xa16d3789),LL(0x72ace7c2,0xe08192c8),LL(0xe7012d3c,0x4840d465),LL(0x2d9fcc09,0xd2d9e7c8),LL(0xb83abe6f,0x4dc89aa4),LL(0x57f505dd,0x58ef6f90),LL(0xc12ca416,0x3b0f2ce4),L_(0x00000096), LL(0x9e8dd733,0x4f047388),LL(0x1231cdd3,0x536cd1c8),LL(0x45523810,0xd1e5a85f),LL(0x4bcff7cb,0x3fceb99e),LL(0x86ad3d2f,0x00ae1467),LL(0xddf93ca7,0xab6574df),LL(0x4160edd9,0x611238b6),LL(0x0bbbbc9e,0xc6a872eb),L_(0x00000014), + LL(0x4b9dc9a7,0x4e86b3f7),LL(0xd56a4df5,0xb7fc672c),LL(0xc91daa4c,0x047ac313),LL(0xd8b04fac,0x71df8b53),LL(0xd047ffb7,0x48cf7c44),LL(0xe196a8ad,0xbf663542),LL(0xea4fed68,0x45aa68b0),LL(0xdbd49e0b,0x9fea1483),L_(0x0000005e), LL(0xd77d603e,0x33664de2),LL(0x5ef7dee2,0x994f9685),LL(0xc8ab10b1,0x5e3c5bf8),LL(0xf5ab3d23,0xff2ae5c2),LL(0xdbff37af,0x9d0fd0f4),LL(0x50db50de,0xa6d91d52),LL(0xe2c950fc,0xa742da0b),LL(0x0ec3836f,0x3cb961c7),L_(0x00000071), + LL(0xea3797f2,0x00f8c37d),LL(0x0b3e1166,0xce0936fa),LL(0xb532c55c,0x204a444f),LL(0xeef2ac73,0xa6b09c79),LL(0x31515d9e,0xac9e3e09),LL(0xdd05ab36,0xe9cef435),LL(0x319eb710,0xfa2d9fd3),LL(0x1d7ac545,0x6af2d4bc),L_(0x00000199), LL(0x595b4001,0x2f76c04a),LL(0x0f70018c,0x74e5849f),LL(0xa9c62272,0xb2abd908),LL(0xaecd915f,0x5ffbaabb),LL(0x9fa73bfe,0x111c8c5f),LL(0x35b0554e,0x77c9c2a7),LL(0xcc8177e6,0xe83b44a5),LL(0x3bc6ae04,0x18cd6dec),L_(0x000000b1), + LL(0x229b222a,0xb1bb114a),LL(0xff59f733,0x887f6c13),LL(0x2679cded,0xbbad5dfb),LL(0xd35dec8b,0xea94d41f),LL(0x90930770,0xd4f0a601),LL(0x2ad07da8,0x2142901c),LL(0x48f142ed,0x692aaa86),LL(0x252e4559,0x82af1f42),L_(0x000000a7), LL(0x9b4f335e,0x78c42f0d),LL(0xc2716105,0xfda89975),LL(0x2c49b195,0x35776137),LL(0x3ac76051,0x4de0d058),LL(0xfcd0c4d5,0x47ffa549),LL(0xe11bc35f,0x31f21817),LL(0x3f57a567,0x46ac2b10),LL(0xcde0cd71,0xa72a1284),L_(0x0000008e), + LL(0xaecaf4a5,0xcd468ef8),LL(0x60b977fb,0xbcb8a438),LL(0x3938f4bc,0xcfcf5c2b),LL(0x2c7337c9,0x7bb844f3),LL(0x23c47750,0xdea5e248),LL(0xf126971b,0x47ee8dea),LL(0x6f1d664c,0xd5392932),LL(0x3efa21b6,0x9886378b),L_(0x00000075), LL(0x5940abfb,0x28ef7f36),LL(0x3e9bee76,0x8f415722),LL(0x360759cd,0x11a30e1c),LL(0x3c8733e8,0x78196a73),LL(0xc43394c7,0xf3a60c7e),LL(0xac3864e9,0x776e1d00),LL(0x0c19158c,0x2e4681b7),LL(0x517321cc,0x2a4a5040),L_(0x0000007c), + LL(0x69bb2a3b,0x59d22ba1),LL(0x18bc1523,0xee4d727c),LL(0xbabfd9ca,0x4c8338aa),LL(0xe3550512,0xa9cc3cca),LL(0xe599b6e8,0x15386807),LL(0xc5ab3c64,0x3919da2f),LL(0xd2ee43d4,0x801a4c6f),LL(0x38ead934,0x40a087be),L_(0x00000197), LL(0x8b8c66b5,0x7834d44e),LL(0x74807217,0x690ef307),LL(0x926feb1c,0x54c7151d),LL(0xbe2f1f34,0x456bd03f),LL(0xc48ce8e6,0x04a6964d),LL(0xafec270c,0xe8febbc7),LL(0x483b3a5f,0xd30f159a),LL(0x96cb139a,0x52fa9aca),L_(0x000000c9), + LL(0x0e87f867,0xf99ad667),LL(0x75faf57c,0x011dcb9c),LL(0x6c05cb53,0x4f1f75a2),LL(0x3556cade,0x2dea9ad0),LL(0x3f87760d,0xb590f7b4),LL(0xe73b9512,0xc497a74f),LL(0x5a5a684b,0x8d18f07d),LL(0x8e2fa89c,0xbe126a50),L_(0x000000ef), LL(0xc3adce30,0x12408706),LL(0x4d73c59c,0xcce1c5bc),LL(0x2ddcd22c,0x381eb1ab),LL(0x0b77c42b,0x43827dd9),LL(0xaee2e20f,0x0ecadad8),LL(0x4d7ed6ba,0x141b0bef),LL(0x69fa3aa0,0x9ae275eb),LL(0x3d138706,0x2d98b314),L_(0x0000016a), + LL(0x7fc0e976,0x65d7b1d3),LL(0xc8c06baa,0x608a4b87),LL(0x2e527b8c,0xa2d8c259),LL(0xcc19bb3a,0xb09308aa),LL(0x4ce5b0ad,0x2458761d),LL(0x7a6ee0f4,0xd73d4f70),LL(0xd791c442,0x0d3867f8),LL(0x3ba7a1a6,0x14027c94),L_(0x0000007b), LL(0x0e7ffca3,0x467af3d9),LL(0x60c44d23,0x9427b9fa),LL(0xe4a16358,0xaff54ce0),LL(0x55e4129a,0x275c2816),LL(0xcbefd5ea,0x7c03c7fc),LL(0xb7160ce2,0xc97ca421),LL(0x84bb35f0,0xea69ee6f),LL(0x35e0436e,0x360ec7ec),L_(0x000001ca), + LL(0xf585af17,0xbac45c7f),LL(0xf7251745,0xd6aa93a1),LL(0x8a56414c,0x8fa35248),LL(0xf6e64410,0x1720b12e),LL(0x81f59ca8,0x6cb0f80a),LL(0x232a9916,0x205cfe62),LL(0x872efe0b,0xdcba9616),LL(0xa3d26e5c,0x2c5a0421),L_(0x000001fc), LL(0x06a36051,0x478ec567),LL(0x7d42157a,0xa110b6a7),LL(0x0c863ff6,0xb1e77441),LL(0xa6979407,0x7c13c78a),LL(0x6a0ad3b6,0x08c47fd0),LL(0x34e0edd0,0xcd2ed5cb),LL(0x8df0c73d,0x41a8e1a2),LL(0x73883967,0x85e0312e),L_(0x00000135), + LL(0x7d33b8c9,0xa6572311),LL(0x3fceee3a,0x1482e2ca),LL(0x52560262,0x6d96dfdb),LL(0xa105a9eb,0xbdc41e36),LL(0x8c0fd8b7,0xa2f2edd5),LL(0xb271c58b,0x050043d8),LL(0x4a51907c,0xa79966a3),LL(0x0fa52e13,0x60842aee),L_(0x00000128), LL(0xdac2d706,0x62accbe2),LL(0x0b78e0d4,0x8397028d),LL(0x2c9d107f,0x711b525e),LL(0xfedd5666,0x0c96203d),LL(0x88395725,0x2be09463),LL(0xf9856d0f,0x6dd96c8f),LL(0x9c7a6702,0x4398fe82),LL(0xfc430b6d,0xbf922dac),L_(0x000000da), + LL(0xaa02764f,0x7d06225f),LL(0x36596aaf,0x23dab345),LL(0x0047b230,0x1f940005),LL(0x1c2f1ccf,0xb4fb0f0c),LL(0x82a82a8c,0x589309ef),LL(0xc66190cb,0x19fbd0a3),LL(0x839f41c1,0x0fe2846b),LL(0xcc1c9536,0xeb188d9c),L_(0x00000082), LL(0x729f81c7,0x27782d0b),LL(0x55359881,0x76e1016b),LL(0xcaad48a7,0x26d82543),LL(0xc89767f1,0xcf1f4470),LL(0xd4acb529,0xe5b4bfed),LL(0x7b75fd29,0xae8ee068),LL(0xc3d34db9,0x3b3ffbcb),LL(0x9c535467,0xf84d77d7),L_(0x00000122), + LL(0x9faba8ba,0x5f421abd),LL(0xe82276fc,0x94ac402c),LL(0x91f2efc8,0x7d55bead),LL(0x8241f32e,0xcc1090d2),LL(0xe8bce170,0x19f59df3),LL(0xe27350cb,0x4ac35c2d),LL(0x3e6cfc43,0xd13cf90c),LL(0x84bc2847,0xe00912a7),L_(0x000001c7), LL(0xfd3f87f7,0x2713cbe9),LL(0x4fd8d338,0x34163c33),LL(0x46cada61,0x7214cbe3),LL(0x6aa94a54,0x30a042dd),LL(0xf7b92358,0xe120acf2),LL(0x09be500b,0x30c3e8d0),LL(0x51dc7f0d,0x6f225e27),LL(0xb7edd06e,0xe3546714),L_(0x000000a9), +}, +/* digit=4 base_pwr=2^20 */ +{ + LL(0x20c1256f,0x2fd11810),LL(0x5aa78701,0xc4a46931),LL(0xea26a86c,0x056b1163),LL(0xbe00b905,0xa0ac68e4),LL(0x52f1dad4,0xc19c5769),LL(0xc6fde2d8,0xbbc11dae),LL(0x6293f810,0x3a3baf9c),LL(0x5056fba0,0xfa278d37),L_(0x000001c8), LL(0x5973f08b,0x4cc716b5),LL(0x8efce6c1,0xb5b613b1),LL(0x64d3ad94,0x248f005d),LL(0xba83b800,0xa375eb34),LL(0xc9ee4cf2,0x413af2a4),LL(0x68a27d29,0x25ea8722),LL(0x8d12fde5,0xc9c082bd),LL(0x2d233189,0x935ee6fa),L_(0x0000017f), + LL(0x85f1bef2,0xa73fb5cd),LL(0x111a8c9c,0x1a80d76a),LL(0x8d3b7461,0x2e325f88),LL(0x7765b87f,0xc8ad9e3f),LL(0x92e36012,0x2c7cf6c4),LL(0xbf5a9dc4,0x7d5db366),LL(0x6228a81d,0x915359f9),LL(0x725123cd,0x62477772),L_(0x00000183), LL(0x8b6c7a0e,0xa38cc5da),LL(0xee14f97f,0xb43bb38e),LL(0x770c4afd,0xaa0f15c0),LL(0x138850f3,0x3953b993),LL(0x2658cf7e,0xb70f0779),LL(0x1d447c8b,0xd78fd38c),LL(0x681177a0,0x8e23ebe4),LL(0x704ca751,0xf974bc9d),L_(0x00000059), + LL(0xba8fa7e4,0x4e9fda74),LL(0x334944db,0x404855f4),LL(0x65201753,0x31df130f),LL(0x19a9846d,0x661cb9d7),LL(0xbc651ab9,0xc04c2995),LL(0x91c2b653,0x1b2c3fb5),LL(0x1b65fb33,0xc90b91d2),LL(0x9233b624,0xf53a7c1f),L_(0x000000a4), LL(0xfceac108,0x86d9cc5a),LL(0x4cdd0a2e,0x0e2ec8f9),LL(0x309b7d38,0xf2c40675),LL(0x0d2223f6,0xc1e34e32),LL(0xa3be480d,0xb364f62b),LL(0xec527b72,0x3595753d),LL(0xf6639f06,0x4e283d90),LL(0x67ed0c35,0x3f3d71d5),L_(0x0000000c), + LL(0x5667e2e3,0x2b33e937),LL(0x711cfb9d,0x5cc9c7d0),LL(0xedf0adb9,0xc5aaa7c2),LL(0x610b704f,0x770150b6),LL(0x1107368e,0xf9af2a47),LL(0x06e6cc4e,0xfe1e566d),LL(0x814dd0ca,0x7ca67146),LL(0x6c67f663,0xf0648fd3),L_(0x000001a8), LL(0xecb744b3,0xd960d19d),LL(0xc0bcfa2a,0x99ff41db),LL(0x933b28a6,0xb97977ca),LL(0x951faf63,0xca3752a7),LL(0x15168f23,0x01e0f16b),LL(0x4ea397d9,0x05f55f96),LL(0x3b374a51,0x813c0d40),LL(0xe408ed3a,0x4d48dd43),L_(0x00000079), + LL(0x937586c5,0x83c230d0),LL(0x61062265,0x9c8f1eaf),LL(0x10419f67,0x2c698769),LL(0x8d67dbad,0x4407836e),LL(0x4c3c184d,0x99fd2f81),LL(0x52a37538,0x7825fefa),LL(0x45a721e3,0xfff07585),LL(0xa4b823d5,0xabf0c498),L_(0x00000014), LL(0x96e376eb,0x6a23fbe4),LL(0x5f76504d,0xb69ec350),LL(0x545afc26,0xfb28fe6b),LL(0x87ed2073,0xaf95f20e),LL(0xa6145047,0x4d27cd1b),LL(0xc4cc53f8,0xa35d865d),LL(0x9ee96b7f,0xb07b711a),LL(0x430aefde,0xda4b08ec),L_(0x000001a9), + LL(0xc7354ba1,0x9fdb88ca),LL(0xdc64a8c7,0x9f85e2ef),LL(0x7f3a69d0,0x5631012d),LL(0xd2bed232,0xfd4d1f17),LL(0x04dfd89c,0xe64d46be),LL(0xd5598288,0x9f8bf20f),LL(0x1f269d18,0xc11d0864),LL(0x333e29ff,0x28d5f9fc),L_(0x000000d2), LL(0x9cc7dab1,0xbbef8e94),LL(0x5c714223,0x7f10fed7),LL(0xbb61d266,0x09c647b0),LL(0xe823dbf3,0xf58db2b8),LL(0x4601c5a1,0x3a71fa3e),LL(0x344f9c02,0x0b5cbdd6),LL(0x77b11f1a,0xf8df6a65),LL(0x6eb12db5,0x640b327e),L_(0x00000170), + LL(0x0db94e9f,0x9c4cc346),LL(0x646b9dff,0x339e03c0),LL(0x7ae26f18,0x64dca76c),LL(0x2ba1712f,0x2c804061),LL(0x16950e5f,0xb5bf0fae),LL(0x13d1569e,0x185858b6),LL(0x5b35ba86,0x6880b124),LL(0x3c937406,0xc9854d9a),L_(0x00000058), LL(0xee5f1c44,0x96f83044),LL(0x10924610,0xe69176fe),LL(0x5cfb2614,0x324a7887),LL(0x825516a8,0xfbad9007),LL(0xc065d69c,0x3d71727b),LL(0x06621f87,0x85c81c53),LL(0xe21856f1,0x3ac1471a),LL(0x68582e4e,0x92c8d47e),L_(0x000001c3), + LL(0x9ace1c67,0x5469124c),LL(0x24f3ddfa,0xccd6db20),LL(0xaadd52b4,0x74a2fc6f),LL(0x24af0765,0x17b27151),LL(0xb5105915,0x118a106b),LL(0x7e240081,0xcffda2d6),LL(0xc6925ec7,0x88b3b39f),LL(0x37b374e2,0x1e0f8120),L_(0x0000016d), LL(0xefd91b81,0x3a683e17),LL(0xa72b7c41,0x952a60ed),LL(0x0495c130,0x9c4b61d8),LL(0xbf06a574,0x872c4bf6),LL(0x0c7cbd39,0xe01cb7ce),LL(0x989f1a82,0x726d7547),LL(0x44906b41,0x52742de9),LL(0x2e02ff37,0x3d8a309f),L_(0x000000a8), + LL(0x8dd4b66d,0x73240fb0),LL(0xb6e39bb1,0x1303b771),LL(0x195468c6,0x7bd7b8e4),LL(0x9c3d4d09,0xa8684e6d),LL(0x724f9017,0x31c9bec6),LL(0x2fd691e3,0x727ff44a),LL(0x5f3d4db7,0x89060924),LL(0x984ffa88,0xbadb47b0),L_(0x000001dd), LL(0x0c1bfdeb,0x6d85f7e8),LL(0x4b0cbc59,0xccccc632),LL(0xe1faf1ce,0xc7a0620b),LL(0xf6e95c18,0x0aa71a3a),LL(0x8fa50a9c,0x49a07249),LL(0x8cf3e64b,0xaed36f6a),LL(0x94bd6377,0xa4cf33ed),LL(0xeb0073d7,0x331d113f),L_(0x0000019f), + LL(0x87c3614b,0x53d1d5ef),LL(0xaa78183f,0x8ea4ef11),LL(0x5c12de26,0x84a5c0b0),LL(0x3315c75e,0x4f1d31e4),LL(0x0d7a1bdb,0x97ef83ed),LL(0x8d2ce325,0x91dd29d3),LL(0x3340be93,0x184b8ada),LL(0x0f8f6087,0x8ea5afc1),L_(0x0000015b), LL(0x8ce9dccb,0x96d5b0b9),LL(0x641d29f6,0xb48f1d66),LL(0x50813cfd,0x8881842c),LL(0x7ff13a32,0x3fa7e856),LL(0x78eaa08d,0x7984e336),LL(0xfbc798ef,0x67c2e064),LL(0xb3fc5a0a,0x23e92b2d),LL(0xe38a9115,0x5b238a08),L_(0x0000013f), + LL(0x3691b2b4,0x9b215aee),LL(0x5cf3f209,0xa1d61cff),LL(0x4a0f639e,0x2783ba69),LL(0x62cddd5b,0x1490682d),LL(0x5648b7c2,0x074ffd3c),LL(0xeb8c7a90,0x0e9bddbd),LL(0xf3751b7e,0xbce879c7),LL(0xa3bfa1d5,0xb7fba2d9),L_(0x0000016c), LL(0x20a30aeb,0xe42922b6),LL(0x3498a06c,0xa129b145),LL(0x26cc79e5,0x9d307ed3),LL(0x1c156f64,0x2baf6215),LL(0x14f481b2,0x9b79cac0),LL(0x2eb38c02,0xc564e629),LL(0xde0cf55a,0x24a1582a),LL(0xad5a0f7d,0x0a21a7d5),L_(0x0000011a), + LL(0xa68ccc39,0x6997bdf9),LL(0x05de1b77,0x553e670c),LL(0xee7e6f6d,0xadae5917),LL(0x199db8cd,0xecf2088a),LL(0xc33572de,0xa41c0fa0),LL(0x7b432d00,0x1dc922e3),LL(0xc58b8529,0xb5615888),LL(0xb9f1df40,0x310ba77e),L_(0x000001d5), LL(0xe11804a4,0x9626517b),LL(0xb50d5ff0,0x34399d8f),LL(0xeb302429,0x18d0e9c5),LL(0x47c13487,0x18ec316e),LL(0x851d2afc,0x1b701f2c),LL(0x167d9f22,0x883a9116),LL(0xa8f932f6,0xc3a9d8fd),LL(0x0da0e796,0xa92d4102),L_(0x00000116), + LL(0x029cd0ab,0x5d899070),LL(0xb5278a7b,0xe7ecc032),LL(0xabde08a8,0x9fa79438),LL(0xd3d2c019,0x80363047),LL(0x66ae4725,0x141bc210),LL(0xeab542c4,0xdf1d8696),LL(0xd1c060a0,0x3908c1f0),LL(0xfa788627,0x34d35bd3),L_(0x000001a3), LL(0x677d387d,0x76fb5476),LL(0x05f7c0d8,0x3a298203),LL(0x2097dc46,0xe5119f75),LL(0x1f8bd7b9,0x5996aa0e),LL(0x61982b25,0x92c77df7),LL(0x119a9371,0xac8b008e),LL(0x7f9b0675,0x346bbe9d),LL(0x8f2407d2,0xffdfc237),L_(0x00000063), + LL(0xab5b8457,0x52f7bee1),LL(0xbc2db536,0x07aae0d0),LL(0x58623dce,0xa3e03da9),LL(0xf444f5c3,0xe7b9b75d),LL(0xdb04bbba,0x8fa837de),LL(0xb065c230,0xed346416),LL(0x51909adb,0x16d6222a),LL(0x3c084209,0x7ace49f1),L_(0x000000d1), LL(0xdf2f5e19,0xbbb390fd),LL(0x38ba1ac8,0xc03099bd),LL(0xa1e828bc,0x6f1d5124),LL(0xb83c59a2,0xfd863005),LL(0xc17a0d0d,0x97857c15),LL(0x2d92fc6c,0xd53a6942),LL(0xb70e5498,0x36d4d6e3),LL(0x368524fa,0x19450987),L_(0x000001c5), + LL(0xc5143f3d,0xcda50c31),LL(0x34bd47c0,0x5f0ed71c),LL(0x1dee87b7,0x24882cc9),LL(0x7e3bbffb,0xd1c7d1fb),LL(0x1e403329,0x92474fcc),LL(0x53d4ee41,0xbcade2fb),LL(0xbd25257b,0x48035309),LL(0x1ff4afd1,0xa15dc4f3),L_(0x00000163), LL(0xf76b6465,0x54f67634),LL(0x6c3176f4,0x76970368),LL(0x7bbaa2a0,0xe3ebf308),LL(0xc5082d82,0x65ccfb3f),LL(0xec84bb5f,0xf3b5795a),LL(0x4999273e,0xa51dd238),LL(0x7a764cec,0xe6317658),LL(0xd0cd1c12,0xc77140d5),L_(0x0000006b), + LL(0x440872f1,0x28a369cd),LL(0xf5dafa9c,0x07ce63b6),LL(0xc12c54cd,0x4f79c12d),LL(0x0a67eec8,0xee7a34a0),LL(0xdbc7a4ed,0xff4e7f63),LL(0x40f7ea82,0x50ab4929),LL(0xdc3353f9,0xcd953027),LL(0x1b37a3c6,0x4f307be2),L_(0x00000197), LL(0x4c5f758a,0x416ce18f),LL(0xa1adfbab,0xb9e45e70),LL(0xa53a6ae6,0xf8e38074),LL(0x19bbc5ea,0x639d3359),LL(0x66580a40,0x3c3446f8),LL(0xabe333f8,0xf20b5de7),LL(0x703c0639,0xd4a42c48),LL(0x59dbbfad,0xfadceed6),L_(0x0000016e), +}, +/* digit=5 base_pwr=2^25 */ +{ + LL(0xd025b49c,0xa66a4107),LL(0x4a0b9d5c,0x09a27870),LL(0x383562d7,0xb8b27e26),LL(0x8bfb3e1f,0xcd156bc2),LL(0x06132452,0x49ca82ac),LL(0x92d3d9a2,0xa22d3a0e),LL(0xd34655b5,0xa2b19aaf),LL(0x36ff20de,0xa0e8848d),L_(0x0000018f), LL(0x86f6b302,0x1143727c),LL(0x8192a853,0xc5c00385),LL(0x52b2fd4b,0xdaf1da93),LL(0x5e79d62b,0xde7c27d2),LL(0x23c74903,0x18fc4730),LL(0xd6b3ad47,0x3e48286e),LL(0xe1fb2466,0xde5e2dbe),LL(0x558feb16,0x6b4b7857),L_(0x000000b0), + LL(0xf33aa997,0x399f83a0),LL(0xac6eebd0,0xf152344e),LL(0x1e36ba58,0xb233cc5d),LL(0xbcb7b01b,0xb95ccb58),LL(0x0e6e01c3,0xbd70b347),LL(0x28b73f3c,0x471f1429),LL(0x192a8fa5,0x72f33fe8),LL(0x51b82a42,0xe6f5e677),L_(0x000001ef), LL(0x91ea1f80,0x29d67e20),LL(0x9219d0e0,0x355df0fe),LL(0x86128187,0xb88069ec),LL(0x196ceb57,0xc5d6f3e9),LL(0xcb831fc0,0x61a90e72),LL(0x76ccb185,0x875cf514),LL(0x775daca6,0x5e9d0fdc),LL(0xf11fb0d6,0x37c46556),L_(0x00000034), + LL(0x4f6f0528,0x8365a540),LL(0xd607f5f7,0xa6130da7),LL(0x85d457a1,0x282ce8f3),LL(0x7a71db8c,0xf22e8e12),LL(0x675b1780,0x1ed981d1),LL(0x54455f27,0x879b7161),LL(0xd4c8d2d0,0xe53f2395),LL(0xfbb885ea,0x533bd02f),L_(0x0000018d), LL(0xdd4e8a69,0xc1a29f03),LL(0xd15d6f60,0x620f1843),LL(0x51aa6497,0xb9253703),LL(0x3bdc3d85,0xb15aa83f),LL(0xd5713630,0x38bafd76),LL(0x46f5b250,0xa324c450),LL(0xc7ef0e3a,0x428ff854),LL(0x3074cd9a,0x61029f87),L_(0x00000130), + LL(0xdb38150e,0x98edde21),LL(0x02c3ed54,0x10e8c4a8),LL(0x92441512,0x5d3d5708),LL(0xf9b009f9,0x785d69a6),LL(0xac80e954,0xa197859e),LL(0x166d8dbf,0x9a954ad6),LL(0x5cac81cf,0xd5536054),LL(0x01aaa83b,0xd431342d),L_(0x000001b4), LL(0x578a0342,0x2cf62469),LL(0xb8dd8820,0x8c4987d0),LL(0xc2b48e0f,0x3b1becfe),LL(0xd5c621a6,0xa90343a0),LL(0xf668f2b6,0xfe098700),LL(0x9c088bd4,0xbd8fa882),LL(0x3f0936a8,0x67794851),LL(0xae92e720,0xc5748733),L_(0x00000186), + LL(0x45dfbf2f,0x3cd0f06a),LL(0x39d3c154,0xf941b6e2),LL(0x350febe9,0x2d076edd),LL(0x4d560b52,0x55928e0b),LL(0x2b184b05,0x9f1196dc),LL(0x85b25794,0x6b4f0570),LL(0x942eaf69,0xe7c1e0be),LL(0xd7c08589,0x63f1f217),L_(0x0000012d), LL(0x7bc564b2,0x3dbde8c2),LL(0x8d95012a,0xeff3d407),LL(0xa7b28d48,0x08aae60c),LL(0x1b0df773,0xe7d844e8),LL(0xf5cd9389,0xe907a4ac),LL(0x0fa28183,0x6e40930b),LL(0x381dd63b,0x20fcef80),LL(0xa89662a0,0x5312183a),L_(0x000001c7), + LL(0x33be7ac9,0xf700265a),LL(0xf01390c9,0x82de52e5),LL(0x6ffa798e,0xd0dd94ce),LL(0xd994953e,0x2a40701e),LL(0xdc206da1,0xf9937624),LL(0x9641d8d6,0x68b09fde),LL(0xfb08d3aa,0x515609bd),LL(0xc7a5c685,0x916b2107),L_(0x0000017a), LL(0x34c11eaf,0x007f99c6),LL(0x3e931cb9,0xfb91b432),LL(0x97268272,0xb16a5f9f),LL(0x14f51fca,0x22fdf379),LL(0x448325ce,0xa5ef4116),LL(0x36a8c292,0xb6fe6cbe),LL(0xee4ed4ed,0xd30012d0),LL(0x5ebc5cb5,0x50b1fe61),L_(0x00000103), + LL(0x6edf3f2a,0xc68eb226),LL(0x00200346,0x880aea4d),LL(0x8d31f029,0x006895c8),LL(0xf085775e,0x89fcfc5e),LL(0xd25cf0d0,0xb2a191ee),LL(0x4508a2eb,0xc9428552),LL(0x90ca4e90,0x22abade9),LL(0x985e1eac,0x8ec6b7a8),L_(0x00000092), LL(0x31e5ce6f,0x96705235),LL(0xdb11d250,0xee984de1),LL(0xfa51e382,0x06a31aa7),LL(0x47482dcf,0xb9587e74),LL(0x988048ce,0x51593c99),LL(0xca987f12,0x6fe30df1),LL(0xffd978f6,0xfa604f59),LL(0x8e6925df,0xbebed832),L_(0x00000121), + LL(0x24f8517a,0x039e54c1),LL(0x2549eb0e,0x1ec83d52),LL(0xeb02627a,0x18a8ead8),LL(0x95771e96,0x497c2cef),LL(0xd4f3a6b4,0x1c4917c7),LL(0x080b55a4,0xe8babd80),LL(0x90585b7b,0x6c548c79),LL(0xdabe54a0,0x2dcbdc64),L_(0x00000099), LL(0x2b269bac,0xdf9b98b0),LL(0xc4ed8c6b,0x0247e075),LL(0xd8e1a299,0xbc830716),LL(0x019c94ed,0x3458f33a),LL(0x9c1665fb,0xcd4d82fa),LL(0xff63e700,0x2326e507),LL(0x41c9bbfa,0x5b452b83),LL(0xc9214a3f,0x1a7050df),L_(0x0000012f), + LL(0x3a39f3de,0x6207af25),LL(0x48efebf2,0xe105123f),LL(0xc14c4d56,0xe2f0d038),LL(0xe91d26ba,0x4b6de581),LL(0x4ec88307,0x8f223417),LL(0x0cd6e3f2,0x6ecd94a5),LL(0x986d1a76,0x75765814),LL(0x6e247362,0x2e292aa2),L_(0x00000047), LL(0x8b83a718,0x6e918a1b),LL(0xc07b54ba,0x67b07959),LL(0x22adb8dc,0x96a7a38b),LL(0x2810db83,0xd80ec3cd),LL(0x512687fb,0x3b7485fc),LL(0x6a994329,0x746aec5a),LL(0xd193ecb8,0x6e8d782e),LL(0x72720264,0xf4c3b7e3),L_(0x00000160), + LL(0x18efe68e,0x7f9ec076),LL(0xd1c7c3de,0x2cb36021),LL(0x39cd1c50,0x4584b14d),LL(0x997b5332,0x4275cf71),LL(0x8ac5db4a,0x47f829e4),LL(0x0bc80acc,0x41dd84b4),LL(0x93021863,0x498e9e29),LL(0x6c2be4f1,0x514dc4f7),L_(0x000001aa), LL(0xa59f6acf,0x50030fe6),LL(0xbe6f68fb,0x21480f26),LL(0x217fd94a,0x7a75421a),LL(0xfc5b6dc5,0x7f8cd384),LL(0x19e9f3af,0x674a2419),LL(0xd009b54a,0x454fa1ef),LL(0x6bd82b7f,0xf5bea7db),LL(0x31688d56,0x02858efb),L_(0x00000076), + LL(0x24d7621f,0x92168834),LL(0x1fc413da,0x47855bbd),LL(0x13a9e461,0x17199daf),LL(0x4e3536bc,0x42c2a13c),LL(0x2b4a64a6,0xa8670cf2),LL(0x38d86ada,0x6c221d69),LL(0x68ee0d8d,0x91def21c),LL(0xa5126dec,0x99a859f3),L_(0x000000bd), LL(0x03f14fd3,0x378bafe9),LL(0xef0ab60c,0x11be6eda),LL(0xe18440ad,0x59ce941a),LL(0xead8d861,0x59cf0928),LL(0xd51985bf,0x608dbb83),LL(0x54f87d88,0xb568f14f),LL(0x15b84493,0xb574903f),LL(0xbc432c12,0x90bc4e6d),L_(0x0000010e), + LL(0x79d38b74,0x7eaa6aae),LL(0xf84e0117,0xdb942db5),LL(0x77a0b212,0xd22fb9bf),LL(0xc56ffa35,0x3c3e0310),LL(0xdf48ef3e,0x9f901558),LL(0x372e6e7b,0xa69d9dbe),LL(0x0da5fd74,0xeaa231af),LL(0x1a06775c,0xc9f04db6),L_(0x000001cf), LL(0xd09d3577,0x7802613d),LL(0x61b4d69e,0x19ba2ee8),LL(0xa78fefe1,0x46a7d09b),LL(0x7be0e7b7,0xedbd7a6a),LL(0xed289bee,0x894b4148),LL(0x613e6a64,0x4ced52a0),LL(0xf2a487de,0x58c856b6),LL(0x802d7250,0xe3475832),L_(0x0000000e), + LL(0xd1a6df86,0x365ca885),LL(0xca64af53,0xfb62f8cc),LL(0xbd654db8,0x7be4b7f7),LL(0x029300b0,0x8e5d1bd5),LL(0xc892e13f,0x2c67f87f),LL(0xcc4777a4,0x8b3a46c0),LL(0xba6516c2,0x7400b2a4),LL(0x6cbe8178,0xce032c3d),L_(0x000001ff), LL(0x24153eca,0x540f05b7),LL(0x19221aa5,0x97f95061),LL(0x09e289a2,0xbba5984c),LL(0xf2867a5f,0xa0f6739b),LL(0x0f075e42,0xa0718647),LL(0xab768457,0xa0b31eb8),LL(0xae89b1c6,0xf7e66ea8),LL(0x127d85c9,0xabebbadf),L_(0x00000087), + LL(0x6d5a6301,0x8cd94792),LL(0x3dd861e6,0x97b8baf4),LL(0xfe513cef,0x04f520d2),LL(0x71773dad,0x05832bb5),LL(0xe9f256e1,0x644c2754),LL(0x40df1966,0x700981f0),LL(0x9215b453,0x5dacb6f1),LL(0xc1eb3c97,0xc9b5d3dd),L_(0x00000093), LL(0xbd504fe7,0x365fddbf),LL(0x8fd2242a,0xc2c35f7a),LL(0x4bda285f,0xc1adbae0),LL(0xe964cfd7,0x9f4dbf4e),LL(0x29f5bb5b,0xebe1db2e),LL(0xaab3521e,0xeb26c679),LL(0x17b1e0d2,0x460499ac),LL(0x5a9383dc,0x366f4a0a),L_(0x000001a5), + LL(0x13ec332c,0xb2a67fff),LL(0xb50e03f5,0x50971210),LL(0xfca3bc03,0xa67e12aa),LL(0x4ad52b09,0xbb90dbda),LL(0xff71aa12,0x0edb116e),LL(0x6d43afd2,0x0827d59a),LL(0x97de7056,0x29d216bb),LL(0x7a131b7f,0xe3451b60),L_(0x0000017c), LL(0xb922ac22,0xfa7cdb03),LL(0xf832d6ed,0x58c5a459),LL(0xd373c013,0x7af850a7),LL(0xec4706eb,0x2c0a7082),LL(0x67642828,0x10a909d7),LL(0xae5e13c9,0xab317113),LL(0x5697d646,0x62e5e289),LL(0x83fffcd8,0xb1590922),L_(0x000000d9), + LL(0x331109fa,0x16fb0987),LL(0x7dc5b06e,0xf23db224),LL(0x62c76a0d,0x3f2f53ef),LL(0xf6843163,0x41397218),LL(0x63cbe6a9,0x6d05ffc2),LL(0xb14a253b,0x7ed103a8),LL(0x8ee0b454,0xf389d693),LL(0x3310d7c6,0x9221bf4f),L_(0x000001e6), LL(0xe3ae5ea5,0xeba63d9e),LL(0x281cc803,0xff5d7d44),LL(0x5a289454,0xfa26da52),LL(0x8b5bf3e7,0x8b9a0868),LL(0xf6c91ab8,0x565a2877),LL(0x10a39907,0x737c0212),LL(0x1223d6a1,0xe131db55),LL(0x19f277aa,0x3e1fc414),L_(0x000001cc), +}, +/* digit=6 base_pwr=2^30 */ +{ + LL(0x205e28d0,0x97a1a0b2),LL(0x662c120e,0x6679b5d8),LL(0xd256806d,0x56f0da8b),LL(0x5177882d,0xb3a0c292),LL(0x1fd447d9,0x15eb4fc8),LL(0xd44b077e,0xf15d98b7),LL(0x44ac5bb0,0x2721ac99),LL(0x38b1a539,0x90bc5964),L_(0x000000ee), LL(0x2615ec8d,0x7c193099),LL(0x6014ef39,0xde0771a4),LL(0x7929bb3e,0x2d975e02),LL(0xcd3fad00,0xd387bd9d),LL(0x38c634c3,0x4ebf2479),LL(0x08079c3f,0x2c2da2b5),LL(0xe2b2209a,0xd2e85151),LL(0xbb80ad2e,0x2c3845f4),L_(0x00000166), + LL(0x8f90c95c,0xb8f686b4),LL(0x17d91844,0xa7467794),LL(0xb498e1e2,0x354bd2f6),LL(0xdf2e61e9,0xaea1ed2a),LL(0xb0db08d1,0xf347f08d),LL(0x02cba497,0x78713784),LL(0x5de0850c,0x51753c73),LL(0xed5b7079,0x1738e1f9),L_(0x0000007a), LL(0xd4d045e4,0x91e83186),LL(0xd4180245,0x2f07b1ad),LL(0x059bab68,0x1d467074),LL(0x2b0f371c,0xb0e391ea),LL(0x80e5f219,0xf22e68c2),LL(0xb058f844,0x79b7f960),LL(0x6ca98996,0xd1250203),LL(0x1f63acdb,0x0336e28a),L_(0x000000bf), + LL(0x6f5a9e54,0xbda97f65),LL(0xaf7af291,0x3726d93c),LL(0x49f05287,0x2f95260a),LL(0x41ba40c2,0x77d547dd),LL(0x957f51b5,0x05f74755),LL(0x8ef3d171,0xabb35056),LL(0x131fa675,0x73e0ad7e),LL(0xf2cdf14a,0xc6b88e0e),L_(0x00000119), LL(0xe74e4c04,0x5dd32692),LL(0x56454c03,0xbec75c70),LL(0xcf373902,0xf969fbf4),LL(0xcc237598,0xc6be1f8c),LL(0x25a52045,0x1317acb0),LL(0xbd2ef98d,0x4c09bec9),LL(0x87e896e1,0xa4033c40),LL(0x16b064d0,0x35a420c5),L_(0x00000082), + LL(0x2223b656,0xf580463d),LL(0x7a55f8bf,0xbd3d896f),LL(0x19d6f3c8,0xdc1bc358),LL(0xf8dfdd32,0xa2786cfc),LL(0x57477a57,0xae5589b6),LL(0x9f47a3b0,0x06de5eae),LL(0x93f21788,0x2c782fcd),LL(0xd9479ee3,0x96eb796d),L_(0x00000135), LL(0x0929435c,0x52a35de2),LL(0x5b11dd83,0x4ce809af),LL(0x080ab8c3,0xe25a76cf),LL(0x50478b1c,0x216bfb22),LL(0x103b3ff7,0xd87f4762),LL(0x99b34133,0x41327480),LL(0x95f627aa,0xa729b689),LL(0x62b3cf30,0xd78ba6fb),L_(0x0000017d), + LL(0x721c2b47,0x251bc403),LL(0xb04b42b0,0x43b1fedb),LL(0x73ae072d,0xe91e26a3),LL(0x0d23d9bf,0xbe237693),LL(0x40c88f4f,0x3424beb1),LL(0x6a55a156,0xa0854744),LL(0x26b2b7ac,0xd61d14b6),LL(0x4ee7f1ff,0x2b8c920f),L_(0x0000005f), LL(0xa08faeb0,0x9b46600b),LL(0xfac400c9,0x541f8756),LL(0xfa469aa7,0x961867a9),LL(0x9f699a76,0xaf3ea90e),LL(0x6fa24828,0x87c1ec18),LL(0xb4eae9ea,0x13538c6c),LL(0xd16f2fd6,0x3f2706c2),LL(0x1ba2b83f,0x49f12b47),L_(0x0000001b), + LL(0xbdd4d4a0,0x305ae6fd),LL(0x1d7bb497,0xfd52a449),LL(0x143fec43,0xf6e16ac4),LL(0xebf21b11,0x8a70f179),LL(0xdc6c0238,0xb6be355d),LL(0xd156ead0,0x45178899),LL(0x91cfd7f1,0xdeb4b443),LL(0x63af6554,0x56edae1a),L_(0x000000f2), LL(0xc755678e,0x78e21693),LL(0x747e0d46,0x04110693),LL(0x8c5bb7f8,0x878fdb74),LL(0xb933a4bb,0x90576198),LL(0x4a53f37a,0xb6123d17),LL(0x9e11e3a2,0x6fc61c48),LL(0xf4f2778d,0x0bd5422a),LL(0x78936064,0x0834022a),L_(0x00000075), + LL(0x1cdfc255,0x0e89d4d5),LL(0x620f831a,0x353a0af0),LL(0xb276e069,0x687747f6),LL(0x848dd0c6,0xf27dfd62),LL(0x0bb6c7d1,0x05846ed2),LL(0x561ca5d7,0x17ec1af8),LL(0x39a2756b,0x4280d8ec),LL(0xf4bc9db5,0x3c387c2c),L_(0x00000111), LL(0x827b9727,0x96e34ce9),LL(0x3fe216b6,0x79c77aa0),LL(0x6720f347,0xfad412f9),LL(0x695ff127,0x74dee9fa),LL(0x5f1b0845,0xe65f23d5),LL(0xbfbfe9e6,0x3e545ad7),LL(0xe1c9f0ed,0x92d8678d),LL(0x9914fd4c,0x34192088),L_(0x000001ca), + LL(0x479267d4,0x0396f4d9),LL(0x88692b5b,0xb1e5f7f0),LL(0xfd9437e3,0x9509c3c1),LL(0xb9b9b7fa,0x15a75e6c),LL(0xba37b6c1,0x5b42f650),LL(0xdbbc62d0,0x5b3cf510),LL(0x6d5fe62d,0xc6a49bf0),LL(0x824e6593,0x21168049),L_(0x0000007a), LL(0xcc7f70f3,0xeb94fc53),LL(0x6a2b34a3,0x82c0e60f),LL(0xea4bc9d4,0x8f42888a),LL(0x7ab9ed31,0xc0fe3ed3),LL(0x1a505ae0,0xe94fad3b),LL(0x545382c9,0xfa0f3128),LL(0x9ae4fb8e,0x44bd4be6),LL(0xa516fe88,0x3f6a7003),L_(0x000000d6), + LL(0x5455aac0,0x2a8889b3),LL(0xc9b0d66d,0x1c5bf83e),LL(0x736f64af,0xeb5d7b9e),LL(0xb0411171,0xfd19cd82),LL(0x22d46926,0xdc65529f),LL(0x1a902efa,0x2603fa26),LL(0xa829e75c,0x4e40cf1f),LL(0x25ea27fc,0xe0d4e87d),L_(0x00000161), LL(0x4b68fce9,0xe6bccc3f),LL(0x83ed8b75,0x047d0099),LL(0x864c3567,0x85060d1b),LL(0x1ddc1dd9,0x3ee4ae76),LL(0x974e9669,0x389206d2),LL(0x6126092a,0x91ac46ae),LL(0xe4c7cd87,0x450710f2),LL(0x9e581f06,0xc5c30640),L_(0x000000ae), + LL(0x291b3bd9,0x42264245),LL(0x08f40ce6,0x9254ae8e),LL(0x244beb5d,0x6f14d800),LL(0x0b345a89,0xe0141c82),LL(0xb5b0de4a,0xf52d10c3),LL(0x2ca8fb1f,0xebf183aa),LL(0xdb884d75,0x8611998a),LL(0xd2bb9afb,0xce37079a),L_(0x00000152), LL(0xa6d267bb,0xe6bc257b),LL(0xf0568557,0x2160d875),LL(0x6b9e2dd7,0xb1fad31a),LL(0x9c709714,0xed3d24a8),LL(0xf7d05de5,0x61431dc5),LL(0xdc526178,0x0501b15f),LL(0xe40e89ee,0xb2aa5088),LL(0xf3025f1d,0x365bc9f8),L_(0x000001e3), + LL(0x859759f0,0xb249eb45),LL(0xff4d25bf,0xb8020268),LL(0xd9737355,0x9d4a831f),LL(0x84343cef,0xba7e139e),LL(0x5bb5557e,0xb24bfdbf),LL(0x3ab8fb19,0x31a1b161),LL(0x3fa57146,0x4ec60d24),LL(0x01fac245,0xf4776d25),L_(0x000000f7), LL(0x3e8c0bac,0x5b116d34),LL(0x0f307133,0x62db28ba),LL(0x9a0533b5,0x0939b6eb),LL(0xacf1cf00,0x89d1c401),LL(0x693e7c92,0x4b14c89d),LL(0x0945b630,0x4ed7b53a),LL(0x4b162dc1,0x79a7fa4b),LL(0x3e6b7dc4,0xbe6da5c0),L_(0x0000009b), + LL(0xb35e8088,0x24bb4a7a),LL(0x9e47ec6e,0x968fd370),LL(0xe7d95582,0x474d55e3),LL(0x783f2538,0x9d35c0f8),LL(0x83b454e1,0x4578fbe5),LL(0x114b724c,0x98f51326),LL(0x97ee546b,0xf190d99b),LL(0x801229b8,0x3b184691),L_(0x000000b2), LL(0x7ee4a0a2,0x8b19b4b6),LL(0xd4f5faa0,0xc220cb11),LL(0x6ad0862b,0xce1c7d42),LL(0xd7a63508,0x3236a72d),LL(0xeaae4777,0x36cda4ac),LL(0xbe3fcce9,0x808ba7a0),LL(0x972c3840,0x79c14a5b),LL(0xcda4655c,0x0cecb887),L_(0x00000155), + LL(0xf72e10a1,0x23f718f8),LL(0x07515abf,0x820e2eb6),LL(0xc81af50b,0xea92c2b4),LL(0x06af11fd,0x71048468),LL(0x755ab069,0x6ada8b6e),LL(0x5f2e0402,0xe7b549c5),LL(0xa45c27e8,0x13b56922),LL(0x1760f8ae,0x07a6f401),L_(0x00000085), LL(0xacb0965f,0xc6437d60),LL(0x30e79f87,0x93a0e68a),LL(0xcb0f4dcf,0x3613f9b0),LL(0x02e2383c,0x32355c62),LL(0x3ec75821,0x4a835dde),LL(0x4891bfda,0xa38a3a87),LL(0xd0206185,0x9de0b9b9),LL(0xa9cedb8c,0x54d8a9f4),L_(0x0000018f), + LL(0x8b5ddb45,0xdc46fb16),LL(0x8166a790,0x41a5e4a7),LL(0xc854c900,0x342b51ba),LL(0xeb4a908e,0x116e0741),LL(0xb76499d7,0xc1551311),LL(0x6cc7399a,0xccaf37b4),LL(0xf2094cc8,0x9c29f265),LL(0xc4a1fb65,0xcca404c7),L_(0x0000005f), LL(0xa4cf272a,0xcfc8b9dd),LL(0x9fd1f1c4,0xb8e8cb4f),LL(0x8ddfade3,0xfd72dadc),LL(0xf084903f,0x764ba410),LL(0x9094e8a7,0xf43466f6),LL(0xb9869fee,0x1564c4ac),LL(0x82a6cc83,0x7742c943),LL(0x89c1b557,0x2b44656c),L_(0x0000001a), + LL(0x7e25b95d,0x08c1d55c),LL(0x50011066,0x2de90a9b),LL(0x63db375d,0x46d6ba3b),LL(0x2d3fa9bd,0x9ae8aa53),LL(0x9fb12874,0xabf67a35),LL(0xd1f1f45f,0x05d8099d),LL(0xdc479fc0,0xdf2cdfde),LL(0x779d8b52,0xe51f87a9),L_(0x000000da), LL(0x8f62ac2a,0x4ab94029),LL(0x56a0908f,0xbb03c1b4),LL(0x9ce0943b,0x6319d2ed),LL(0xe2d743f7,0x910c2363),LL(0x871683b7,0x78ddf2fb),LL(0x43f08ff4,0xb7c5e230),LL(0x2ebe58e7,0x1c175b19),LL(0xc02e1520,0x9f7bb585),L_(0x0000013c), + LL(0xec7786aa,0x70017bcc),LL(0x26576a40,0x926b1ae0),LL(0x5e810d17,0x6c002685),LL(0xdef24d30,0xd826c439),LL(0x78ac55c7,0xe40f66cc),LL(0xfbf9b521,0xe26697c9),LL(0x01aaaf8a,0x46a75caf),LL(0xd094aec3,0x12da82a9),L_(0x00000072), LL(0x99a161f4,0xcc3c7e5f),LL(0x88977e72,0xfefa749b),LL(0xd6e24cf4,0x56863737),LL(0x4607a910,0x4dcfe4ed),LL(0x01768685,0xac7bc09c),LL(0x9ec211ac,0xc731394d),LL(0xac76909c,0xd59e4dd8),LL(0x246fb612,0x6cf6ebc7),L_(0x00000183), +}, +/* digit=7 base_pwr=2^35 */ +{ + LL(0x5592f380,0x0dd54d04),LL(0x44d05f6f,0x298fe241),LL(0xe2d191b2,0xad46274a),LL(0x9113fc1e,0xcc54c590),LL(0x0dea702c,0x763ea8c1),LL(0x74f208c5,0x35441e72),LL(0x578c5736,0x3706b2f2),LL(0x81343695,0x93b46c3b),L_(0x00000063), LL(0x88ada464,0x4c2605a5),LL(0xd5464606,0x004bbf31),LL(0xca04e18d,0x03210805),LL(0x998cccf9,0x89627867),LL(0x48398a6f,0x8d2faed1),LL(0xca85dacf,0xde01ea7e),LL(0x92784742,0x0feb7d82),LL(0x9fe5859b,0xb9f9aeb8),L_(0x00000150), + LL(0x05a73aaf,0xe5e08d95),LL(0x18e919ab,0x9fd8bcd3),LL(0x5b386f06,0xd6891589),LL(0x0b5abd07,0x07bc244a),LL(0x339901b0,0xc3693691),LL(0x684cff05,0x179dcef7),LL(0xe69b7993,0xb0125196),LL(0x23db7308,0x03553a28),L_(0x000000be), LL(0xf88e8361,0x0c66e267),LL(0x2f9f93bf,0x6d375b82),LL(0x09656c0d,0x6d5dc021),LL(0x0c1fc16b,0xba81db53),LL(0x86bf6541,0xb4caf94b),LL(0x1a6d443c,0x87f59d3c),LL(0x0e10fe1a,0xb72afcd6),LL(0x8d7e1995,0x1a0c6a08),L_(0x000000da), + LL(0x3c2640b0,0xef7a7df4),LL(0xf6850378,0x2a55c175),LL(0xed04fb24,0x8b6f667a),LL(0xa7e743ff,0x93061f72),LL(0xdf46d114,0xdaa59d80),LL(0x9d4ed766,0x49c1e1f8),LL(0x4b991a82,0x2fe74922),LL(0x2e41804d,0xe9a27b22),L_(0x00000196), LL(0xf37b7a2c,0x140444d6),LL(0x8f14ff32,0xf54bdbb6),LL(0x34a9f316,0xde42c24e),LL(0x9515de8e,0x96a88eec),LL(0xf1959aa3,0xdcd09006),LL(0x30671815,0x058c4643),LL(0xb6c6d2af,0x65dac0ec),LL(0xd1a5f578,0xc7fbdbf4),L_(0x00000150), + LL(0x0a5b8daa,0xd4667616),LL(0x8dcdbdbe,0x16e7a7e7),LL(0x1b0f5e9c,0x9178e1fc),LL(0x3cb9503e,0xf2294c93),LL(0xe6f78b36,0x420442aa),LL(0xfb2d6ec3,0x01e17c7f),LL(0x7d30fddc,0x9c7293b8),LL(0x36bed473,0xa2fcf928),L_(0x000000a0), LL(0x4975943e,0x84cf37b8),LL(0xab2857b7,0x645eaa02),LL(0xe12a0d65,0x3d30b0ac),LL(0x267c93aa,0x30be3eff),LL(0x6fa69542,0x903aa7ed),LL(0x2cdb01e1,0x311ae0c8),LL(0xc5056d4c,0x275f0bd3),LL(0x94d54a98,0x7fa09220),L_(0x0000005d), + LL(0x8c942dd7,0x62d7fcf1),LL(0xc893077d,0x643ea78e),LL(0xda471b28,0x4e9d9fdb),LL(0xfb673df7,0xe64cf76a),LL(0x51536a0a,0xfccba343),LL(0x5fc020fd,0x279bce99),LL(0xdee7d155,0xb7f5fd72),LL(0x68c90549,0xdc14172d),L_(0x00000119), LL(0x4ecec5bb,0xe6b0baf4),LL(0x6a4bc82c,0x18f9ed0f),LL(0x93eb1856,0xdc69912e),LL(0x6f327c7d,0x2be0e2b3),LL(0x52fbc6f3,0xe7e8bfdb),LL(0x24b3acf0,0xd81de1d4),LL(0x62a84326,0xe49b2810),LL(0xc3912b42,0x55d57336),L_(0x000001ab), + LL(0x551c0660,0x2fe061f4),LL(0x91d40c3d,0xa2b6dd70),LL(0x7cc4883d,0xbd2bf743),LL(0x58011dda,0xaee852f2),LL(0x71bdaba7,0x39f463ce),LL(0xbd7c195b,0xfb33b881),LL(0xede085fe,0xbf7d695a),LL(0xf8fa2471,0xe577b380),L_(0x00000149), LL(0xc96eeab9,0x8a6f5a6d),LL(0x07f71f13,0xb29f154f),LL(0x242d7a9e,0xb707d1c7),LL(0xf3c7f1af,0x44aee842),LL(0x0af2896b,0x01f56999),LL(0xc5c5b556,0x1e36ed07),LL(0xcca26786,0x245430fa),LL(0xa78eb214,0xaa96816e),L_(0x00000106), + LL(0x0f4d9fba,0xa4eddc14),LL(0x9ebcb886,0x420f1510),LL(0x3c114b65,0x4e6c23f6),LL(0xba3fc70d,0x5f6bd766),LL(0x718ac792,0x532bdc38),LL(0x5c2b8f46,0x03efcc7f),LL(0x72c3a472,0x5c2b9a45),LL(0x9dc110c9,0xba2fb9f4),L_(0x00000147), LL(0x1a6af2f7,0xb5c3ea1c),LL(0x8052b6c2,0xab27ec8a),LL(0xa3cff07f,0x4c92575d),LL(0x00fa9778,0x4b43265d),LL(0xff1e188a,0x6c53a129),LL(0xedc9e95e,0xfcb7ddb8),LL(0xfb7de911,0xc1dd8dd6),LL(0x6e53bbb5,0xd488fa72),L_(0x000000b1), + LL(0x7daeaaab,0x6eaee317),LL(0x6e35398b,0xf5c1267a),LL(0xd01bbbbb,0xa2b92ae2),LL(0x3af1a4f4,0x5cdfa4bf),LL(0x5532088e,0x638a58f5),LL(0x2a0ec8ee,0xbce5e7aa),LL(0x79c3f50b,0x46a16448),LL(0x378387c2,0x1c40f25e),L_(0x000001cd), LL(0x6769ee88,0x8ec2984b),LL(0x62fea90f,0x1f9e47bd),LL(0xe7522665,0x3d9f9867),LL(0x916cb049,0x5be2cccb),LL(0x1106987f,0x71156e1c),LL(0x7bad869c,0x011576bd),LL(0x945007a5,0x38b76a6e),LL(0xc18de41f,0xd11c30ae),L_(0x00000109), + LL(0x6ee5a7d6,0x2831843a),LL(0x58bef9ba,0xe4f07223),LL(0xd00147a3,0xe1c40e6b),LL(0xd10e53e0,0xe7025e87),LL(0x5d5f797a,0xf0dd838b),LL(0xe3b65b5f,0x16931c80),LL(0xd1ff0eb8,0x42704c55),LL(0xffc29bf2,0x999442d4),L_(0x00000150), LL(0x279cdc4f,0xed03963d),LL(0x51c15682,0x4a0c613e),LL(0xc3d504ac,0x6ef1db42),LL(0xba61ce4e,0xf8742eaf),LL(0x2e74a6d4,0x3efa3cf5),LL(0xd53943f5,0x201c12e1),LL(0x253da54a,0xa468664c),LL(0xa35c5fd4,0x6014ba12),L_(0x000001c6), + LL(0x687c5994,0x7a229d23),LL(0x8aa53c89,0x118e3e78),LL(0x080e973b,0x15c794e3),LL(0x5a91046f,0x30c0f281),LL(0x5ac04ed5,0xfe35eb92),LL(0x0c5478a4,0xfe18e707),LL(0x7d9c57a1,0x4bf409ce),LL(0xfcd17edd,0xdecf58aa),L_(0x00000138), LL(0x3d2850fe,0x23469475),LL(0x2c45c37e,0xc528ec7d),LL(0xf346792a,0xa36bdd41),LL(0xca964be2,0x11d67932),LL(0x3fef3e79,0xc72673a0),LL(0xf0bc0101,0x53d6358e),LL(0xb9caaba6,0x2bf874e2),LL(0xbbcc3188,0xe8aaf45e),L_(0x00000102), + LL(0xf22d90c1,0x24df4deb),LL(0x449aa491,0x37a9290e),LL(0xd1657f10,0xc6bbdf04),LL(0x4ba3ee4b,0x4075fc0e),LL(0xe3e07500,0xf134a6c8),LL(0x7661f086,0x2b3b9213),LL(0xfd4c08de,0x6f51f169),LL(0xcae8fa7f,0x275a9f04),L_(0x000000b3), LL(0x9303da25,0x1e8df3c5),LL(0x6a92d1ac,0xb326f2a6),LL(0xafc6ed8c,0x46ef258d),LL(0xe7d3b364,0x53fe6ba5),LL(0x7b2d91d1,0x669d23c2),LL(0x150f6968,0xc05b6015),LL(0x230a0105,0x376b2356),LL(0x3df6108a,0xea51c972),L_(0x00000165), + LL(0x5490baa5,0x148d7d84),LL(0xae379993,0xd948464c),LL(0xac4f8ace,0xddaf46fe),LL(0x68d1b7c8,0x6c39b672),LL(0x10d4770e,0x5967ac57),LL(0x30a2c195,0x2098b748),LL(0x19047735,0x858d17fe),LL(0xe5071ced,0x709c0191),L_(0x0000000a), LL(0x44b4f003,0x2a7e4193),LL(0x767f8087,0x1262c90a),LL(0x91770fa4,0x25315a97),LL(0x4bc5606e,0x696dd31a),LL(0x6a665041,0x7ec13746),LL(0xbd01da6d,0xac07c562),LL(0x59de1e2c,0x4bc4a92e),LL(0x8f7d2999,0xcaa3e706),L_(0x0000016a), + LL(0x37e7ccad,0x0f93acce),LL(0x909c5616,0x3802c7e4),LL(0x50e428ab,0x3b424aa7),LL(0xdee4af73,0xc7e0291d),LL(0x5bbec3a0,0x3889c563),LL(0x7854dc66,0xe5ea7c0c),LL(0x7701185f,0x9cdf7704),LL(0x0b88a64a,0x5a2a21ad),L_(0x000000be), LL(0xe5481dba,0xc168583c),LL(0xbb4cbf39,0xec84a971),LL(0x16e6876e,0xdde2891b),LL(0x4940610a,0x9e03560a),LL(0x5406bed1,0x992e1390),LL(0x475b7757,0xc2108310),LL(0x7cc85b3f,0xffbf072b),LL(0x82170451,0x18e357eb),L_(0x000000d8), + LL(0x9d172698,0x0dde3c4b),LL(0xb8a86057,0x4dad7e2a),LL(0x376d08bb,0x709cc4fe),LL(0x2d396e50,0xb38f91df),LL(0x78138716,0x6a45d957),LL(0x7a064e9a,0xeda47781),LL(0xf79bf83f,0x037062a4),LL(0x2aff8e01,0xb537eca1),L_(0x00000160), LL(0x49748577,0xa23c2d1e),LL(0xdb9b468c,0x79fc968b),LL(0x9d5d5807,0xb4f35908),LL(0xae7478af,0x7ffb5a37),LL(0x6f6ac1a1,0x0ad6d095),LL(0x35d076fb,0xcc73da49),LL(0x4e896c83,0xf0b38ddd),LL(0xcd942654,0x1d47691f),L_(0x0000017a), + LL(0xf362300f,0x940a7fee),LL(0x0c8996fe,0xff7970e2),LL(0x434f05d2,0x3ed8edff),LL(0xc3ed10ba,0x5ebc5312),LL(0xdee87d6d,0xa445169b),LL(0x12a8674e,0xc4cceb87),LL(0xd8da7725,0x51c6dc7d),LL(0xea8956f4,0x656977af),L_(0x0000019f), LL(0x7d3585a5,0xa5517351),LL(0x13fe8bb4,0x74f18cb5),LL(0xe68912ee,0x7950c8df),LL(0x1512d84f,0x2fbcbaca),LL(0x7df13019,0x0de4c1a1),LL(0xe29f312a,0xabb943b7),LL(0x656e2b95,0x7ae2e506),LL(0xfc56ddff,0xb10146ab),L_(0x00000105), + LL(0xccd06bf8,0xa717a0ac),LL(0x6ceb8a0c,0xb428946c),LL(0x2bd2594e,0x5c199265),LL(0x80688236,0x3a824141),LL(0x74f2f352,0xb634a60c),LL(0x83ce2e27,0xf4680f2b),LL(0x33426806,0x485e159f),LL(0x18c76ca1,0x28f63537),L_(0x0000011d), LL(0x1f63dec4,0xd74bb74e),LL(0x6f95ccb7,0x4a5f0944),LL(0xc75d0662,0xd36f4555),LL(0xd6e7583f,0x23cc2b28),LL(0x783fa303,0x2c0c49bb),LL(0x4f771001,0x907cd3d6),LL(0xac90f899,0xe2c79e69),LL(0x2cb352bd,0x93baf6c1),L_(0x000001c1), +}, +/* digit=8 base_pwr=2^40 */ +{ + LL(0x93bc2a7f,0x46f49f7a),LL(0xcc0b41a2,0x91072db7),LL(0xd30ac7ec,0x53711f97),LL(0x9de685e7,0xef0acc16),LL(0xb8a2ae9a,0x6bded4c6),LL(0x4497e3c4,0x04789cdc),LL(0xb2b2ea26,0xfea082fe),LL(0xe890cba4,0xb570178f),L_(0x000001c0), LL(0x66edbc5c,0xa472aca4),LL(0x5ad15298,0xa8066050),LL(0x1b16ca97,0x38b0c1cc),LL(0xa2937bbf,0x4d56c3dd),LL(0x72545fac,0x7e35494b),LL(0x4b5790f0,0x903e9ca7),LL(0xb0c8bc40,0xc4b43111),LL(0x5923f9e9,0xed048546),L_(0x000000a0), + LL(0xc18b52bf,0x6410d489),LL(0x28530a4d,0xae318bb5),LL(0x3f7d7028,0xb534b71f),LL(0x0b21b686,0x1f599597),LL(0xf01ea275,0x663379dd),LL(0x800a1322,0x77c11915),LL(0x6db4beae,0xe3261c47),LL(0xe89c22a1,0x7fe9cae8),L_(0x0000016e), LL(0xfce16965,0xd6426762),LL(0x2e53d9af,0x532ec13f),LL(0x1e801ed5,0xe9efe413),LL(0x6963e2f9,0x8aecc3c8),LL(0x5f46e509,0xb47801a3),LL(0xc3d8faa2,0x3b6f3406),LL(0x349f37b4,0xadb57971),LL(0x49ef39f4,0x63bf47d7),L_(0x0000014f), + LL(0xf9dcaceb,0x5a73dec3),LL(0xd887946c,0x0e0ffb30),LL(0xe7e62831,0x84126935),LL(0xe074c83b,0x158a7df5),LL(0x18b04291,0x08eaada2),LL(0xfa20f72a,0x40d05438),LL(0x9aa8c4aa,0x8405e6ac),LL(0xb7559284,0xd94b0b92),L_(0x00000024), LL(0x7981326c,0xf1a037a8),LL(0x13ab2cdb,0x9887e290),LL(0x98bd3d86,0xfecffd65),LL(0x3c803a95,0x2fd8393b),LL(0x3e4c5072,0x129b699c),LL(0x5e3c4e70,0xfa72cdd6),LL(0x65f24da0,0x6c0ccbba),LL(0x5325682f,0xd21b5897),L_(0x000000e9), + LL(0x728d8231,0xeede07ff),LL(0x52ba3f46,0xc57dc8bc),LL(0xbbd28782,0x49d96a93),LL(0x9e0a7a0e,0x49576560),LL(0xe9fbe4aa,0x79dbfb8a),LL(0xcccb4c5f,0xe1789960),LL(0xd25ebfd5,0x09b74da3),LL(0x56df642b,0x37317c2e),L_(0x000001a4), LL(0xd17057a2,0xa759ce4d),LL(0xab9d226b,0x57744ef0),LL(0xb7115a63,0xdddc9ee2),LL(0xd77f24c2,0xdfee8900),LL(0x2142ea1a,0xa9d5346a),LL(0x6d500f3f,0xa84ecd7e),LL(0x7a1527e7,0xae35caeb),LL(0x10e6262d,0x07461c81),L_(0x0000017d), + LL(0xcd457989,0xbd6196a6),LL(0xdd85ca16,0x6f76c2cb),LL(0xcfd847e9,0xaa25840d),LL(0x8ea001b3,0x444e27ec),LL(0xa898be24,0x8a0c53dd),LL(0xb3e4397d,0xfa5f98a5),LL(0x64ea9863,0xbe8e1973),LL(0x922c6bbf,0x4f87cbbd),L_(0x0000015d), LL(0x0664b7db,0x54735a19),LL(0x990568c9,0x7371d65a),LL(0x52b4c902,0x600bdaf0),LL(0xc2cc9668,0x4697299e),LL(0xbadac668,0xeb4949cf),LL(0x33272f7c,0xeda14ca0),LL(0x3989fbe1,0xd9927092),LL(0x0f1714c9,0x09c6f2a8),L_(0x000000a1), + LL(0x00da9fad,0x39d9c06e),LL(0x69b9bebe,0x7878b1c2),LL(0x50e16aa4,0xa0545c03),LL(0x04f7fb31,0x5d57a4d6),LL(0xd233dc43,0x629977c5),LL(0x87e54a59,0xaa747e53),LL(0x0cca577c,0x80698068),LL(0x3aa24734,0xa5c6ac7f),L_(0x000001a5), LL(0xf46ecf72,0x87d84398),LL(0x5b5e3ea0,0xf8e3dbad),LL(0xc29bdf29,0xc86793b7),LL(0x8b4ad4a2,0x337e0dd4),LL(0x34cf9d25,0xc858ea72),LL(0xb282be01,0xe90a676b),LL(0x7590c7bf,0x7d306f50),LL(0x155053c4,0x2ef83915),L_(0x000001fe), + LL(0xfa311b42,0xa08e6727),LL(0x609fc56f,0x6285b2f7),LL(0x07ce1a3e,0xe94807c3),LL(0xc9c1df6d,0x19a317d8),LL(0xd70b9796,0x052a3379),LL(0x870efdde,0xaa7d20b3),LL(0x8f7406db,0xbb6e443d),LL(0x511beafe,0x2e19a355),L_(0x00000177), LL(0xd62e82c9,0x9d51e499),LL(0x9995a224,0x615ca9d8),LL(0xd99162d9,0xab897ac7),LL(0x51034000,0x24f35e95),LL(0xb70ca9d9,0x853be7df),LL(0xff11b526,0x38dc8c8a),LL(0x463b8a66,0x3331fb01),LL(0xb55e7404,0x69bac4e7),L_(0x0000000c), + LL(0x508d4f13,0xdd3ccf18),LL(0xf25524c5,0xd8ab1776),LL(0xe0bf0c9e,0x017a54a5),LL(0x1226e24a,0xb9626be8),LL(0xb0e5b1ec,0x8b7b3bc5),LL(0xf24c6acb,0x14da0130),LL(0x46736054,0x7db2f1d9),LL(0x73af8b9c,0x690b53ae),L_(0x00000140), LL(0xb11a4baf,0xf7b99ef6),LL(0x1e9bb68c,0xb7054990),LL(0xa5ca0071,0xe57cc5d4),LL(0x55009f7b,0x501abab5),LL(0x08dbaab6,0x2d17b21b),LL(0xcde35c58,0x9921c7ba),LL(0x9991c48d,0x3f13fb4b),LL(0xc6f664c9,0xc04b4d72),L_(0x00000100), + LL(0xaf8f0fbd,0x3fffd972),LL(0x513637b7,0xa381ede6),LL(0x3a907a7b,0xef4d7386),LL(0xdec53a87,0xfaf3ac39),LL(0x6072c595,0x7077416d),LL(0x25742340,0x8d4d4598),LL(0x0272fbab,0xc3dce550),LL(0x44d3c246,0xe453c93a),L_(0x000000c7), LL(0x8a45d7f7,0xf5989e00),LL(0xa25dc323,0x31cb7128),LL(0xd19e79bc,0x87f0b5cb),LL(0xf782a69b,0x62e18e62),LL(0x4a3bc664,0xacc62f0f),LL(0x8a21efa3,0x855aaaab),LL(0x5dc442d8,0x895a7f3a),LL(0x7fccf9f6,0xd3bb417f),L_(0x0000012b), + LL(0xf6a194a7,0x21638407),LL(0x8d081ace,0xe465a985),LL(0x1e6d4f3f,0x596aa1dd),LL(0x800bb059,0xf63247cf),LL(0x88ecdd17,0xd80d0066),LL(0xd6196a9e,0x359a8606),LL(0x6d1c0b4e,0xf12ac0e0),LL(0x1f003c05,0x0a4696e8),L_(0x000000d9), LL(0xe591e392,0x88389649),LL(0x09f83a93,0x2b4134e0),LL(0x9d2fd6ac,0x3ada50c0),LL(0xd488e638,0xa2f5e7c7),LL(0x6ae6d5dd,0xece41bdd),LL(0x626ed9b1,0x83fc37eb),LL(0x0ec94ba6,0x390a5c6f),LL(0xd316539d,0x016da834),L_(0x000001fa), + LL(0xf8cf81f2,0xdd03c701),LL(0xce67a0a5,0x957637c9),LL(0x4af6b68e,0x49c7193a),LL(0x2b716eb7,0xa9f1106e),LL(0x04a50d86,0x5cdc8e58),LL(0x29fe3e8a,0x404173b6),LL(0x2217e337,0x8d0fe7b4),LL(0x41f85927,0x04f5e2ee),L_(0x00000085), LL(0xf0033298,0x7982223c),LL(0xeed36f1b,0xc078a101),LL(0xc8a52b8f,0x54b52769),LL(0xfd843c12,0x0c71b06d),LL(0xdaa31445,0xd139607d),LL(0x996c457f,0x3373eded),LL(0x0d6abc25,0x616b57db),LL(0x27a4f9a0,0x2f577a05),L_(0x000000d9), + LL(0x24d46da3,0xc28ba5d6),LL(0x84ca0be2,0x69aff480),LL(0xb7d623cf,0xeee1ba2a),LL(0xc4a065a8,0xe236787f),LL(0xd893b3f3,0xaa351426),LL(0x2106fcf4,0xc4d98be5),LL(0xf2dfc4d7,0x534e82e2),LL(0x4f43180c,0xc094b8bf),L_(0x00000037), LL(0xea92fe7d,0x3cd0971d),LL(0xb9b4d4bf,0x5fa502b8),LL(0x56e42bc0,0x2f95fd57),LL(0x9a55a6ac,0xefd75261),LL(0x9c01cac4,0xc54d4200),LL(0x8b9c411f,0x9a2d86c0),LL(0x84f22245,0x0123f4e9),LL(0x924fe183,0xc4d22790),L_(0x00000014), + LL(0x5adfc431,0xed2fd11e),LL(0x1a785308,0xb3ad4ad2),LL(0x534b1813,0x19e08445),LL(0x77328159,0x557af465),LL(0xcd28509e,0x114e6813),LL(0x908aacef,0xdd6f9e0a),LL(0xea30d82c,0x5aec37e4),LL(0x56efd94a,0xaae09d84),L_(0x000000b3), LL(0x9a808c1f,0x8215d192),LL(0x00e65251,0x2e216a64),LL(0x8be89e79,0xa21b58aa),LL(0x1bae586d,0xde6dc431),LL(0x6074af45,0xd9ffe269),LL(0x144f7409,0x7968f9ca),LL(0x4c70bef4,0x057ee0b0),LL(0x464dfc55,0x96645958),L_(0x00000139), + LL(0xda8f0d55,0xbc3cfc53),LL(0xf7a0b6a9,0xc3851a8d),LL(0xd221e3bc,0x3b6631e9),LL(0x73e218ec,0xd802d5a9),LL(0xbb393674,0x357ad609),LL(0x17e839e5,0x26a2911a),LL(0xfd4ff33d,0xa9163042),LL(0x40c85178,0xaab7ae88),L_(0x00000084), LL(0xebbb0dce,0x628d1685),LL(0xc4b138ed,0xad6058b9),LL(0x1ab4e65c,0xd77f3507),LL(0xa315e387,0x01e25773),LL(0xc1c7fc22,0x5f337f59),LL(0x9dd402d9,0xc4922f4d),LL(0x8947a84e,0x52e76d6f),LL(0x83ef2457,0xdca5e48b),L_(0x000001a4), + LL(0x67dd4533,0xed953e34),LL(0x0ffa9336,0x4fc44042),LL(0xb44d3a69,0x0c1288b1),LL(0x7f745c6a,0x0c5f14a6),LL(0x345f8ac2,0x765ee067),LL(0xcfed50e8,0x659b1874),LL(0x5ef0443b,0x26abda6a),LL(0x894afeee,0x4aa8ff63),L_(0x000001af), LL(0xabe2ed4e,0x46dcead8),LL(0x196272e0,0x64053114),LL(0x13a8b18e,0xbcb0e703),LL(0xf9b6c7a1,0xaecaa246),LL(0xb17e245a,0xd0c5c4d7),LL(0xce6786b6,0x01f4866b),LL(0x12c94128,0xea713e45),LL(0x75975359,0x68aeda04),L_(0x000000de), + LL(0xb900e09c,0xf45b409f),LL(0x7837bf97,0xff4a0108),LL(0x2bcafcbc,0x6b8d204b),LL(0x0da165ec,0x8423a60a),LL(0xb1171697,0xf8295351),LL(0x3eb1f2f7,0x1f58e2d1),LL(0x2b669228,0xbbed8459),LL(0x5f9819ae,0xe7cb925f),L_(0x0000002b), LL(0x7b7ea077,0x53ee2ff7),LL(0x5b359b96,0x98e8334b),LL(0x87baabe1,0x85a52104),LL(0x95a5886c,0xc237881a),LL(0x809649f4,0x7f95c6f6),LL(0xd3395612,0xed6c6419),LL(0x657d29fa,0xa5be49aa),LL(0x7ae0b376,0xd04f1da6),L_(0x000001ac), +}, +/* digit=9 base_pwr=2^45 */ +{ + LL(0x45fb32ba,0x8a721e35),LL(0x5c4674f0,0x584020b4),LL(0x84a774fc,0xadafd3a2),LL(0x477afffe,0x266e1004),LL(0xd6a2c4ec,0x326c6652),LL(0x428066dc,0x0b3a65b9),LL(0x4c7d5c77,0xe355b810),LL(0x4b6af237,0x7bce6d8c),L_(0x00000197), LL(0x1c0b97b7,0xde135822),LL(0xcc7ac435,0x876cab38),LL(0x8f30b09e,0xec654cdc),LL(0xcb3a4f5a,0x26a9da0c),LL(0xb2ac30ca,0x8e2a6fa3),LL(0x77ee1103,0x545c20a5),LL(0xf50fb144,0x97bff8e2),LL(0x58359a6d,0x39ffa931),L_(0x00000194), + LL(0xb2c8ba9c,0xddf8d1b9),LL(0x7f24e874,0x27291ffd),LL(0x563287c7,0xd028bd9d),LL(0xd01bdb48,0x3b0c1265),LL(0x71b99b97,0x618319b9),LL(0xf686050d,0x8420d531),LL(0xc411c3a3,0xaed7c201),LL(0x468eb84c,0x13a48d97),L_(0x0000019f), LL(0xf6eb2fc0,0x1dab9da1),LL(0xc275b73e,0x49847c3a),LL(0x54d322f9,0xf0578805),LL(0xdd0cd2b7,0x4958eafe),LL(0x185bb3e7,0xd9061a48),LL(0x5c6dfcd8,0xf9ac370d),LL(0xa0217866,0xf54cb188),LL(0xa132c3b5,0xec13457a),L_(0x000000b7), + LL(0xf197825d,0x1340276a),LL(0x4bbcc96d,0xd82fe632),LL(0xcad6233b,0xc290475e),LL(0x0cd8d04a,0x738cce9a),LL(0x8e8e067d,0xaa038ad0),LL(0xd83e4317,0xa7ce55aa),LL(0xd5e91f49,0x856a1887),LL(0x5efeae92,0x16577a13),L_(0x0000013c), LL(0x9bfa0b6a,0x3d153ead),LL(0xef7bc585,0xca7f6fb4),LL(0x0b798e2a,0xf8abfbb3),LL(0x53595cf1,0x79182066),LL(0x1774e7d1,0x862d3928),LL(0x8b4548df,0xdb1e4086),LL(0x6e38fc52,0x72153b33),LL(0xe2e4b80e,0xb610b52c),L_(0x00000006), + LL(0xf5595043,0xe1b752f3),LL(0x1b9318d9,0xf6e2b364),LL(0x5c02bb70,0x38d64e0f),LL(0x9d8f2870,0x07542416),LL(0xa62f3a1b,0x3b8c6755),LL(0xd59701bf,0x2b642127),LL(0x20fbe8ba,0xfac17f0c),LL(0x3410177d,0x46466526),L_(0x000001b8), LL(0x2b08cc56,0x70680750),LL(0xe532cef6,0x7a1e8980),LL(0x29a4a8b8,0x3b679637),LL(0xcb3a4f19,0x0043db7c),LL(0x92e07ae8,0x346fea83),LL(0x0da35be0,0xef33f7a0),LL(0xcb41f4e9,0x271ea778),LL(0xbb760e77,0xcbdf796e),L_(0x00000018), + LL(0x120e5ac8,0xcad14e90),LL(0xd45b7941,0x130b3936),LL(0x78bbd634,0x3839fe90),LL(0x8f94ae22,0xfb2c2b29),LL(0xbd4d9761,0xb2caaa91),LL(0xf6e513d3,0x37bd3dff),LL(0xa0f24baa,0x9dd2846a),LL(0x1d27a8db,0x025f7ece),L_(0x000001d1), LL(0xd4e2cdab,0x8296eec9),LL(0xee13214a,0xce1e6780),LL(0x6fed4902,0x8ec28ea6),LL(0x28576525,0xa9bf0652),LL(0x0afbfe7d,0x0c66edcd),LL(0x9e743eb7,0xc8ec4a8a),LL(0x64589360,0x09bf2d23),LL(0x7a6453a2,0x48ef097a),L_(0x000000c5), + LL(0x4d44bd26,0x5e7c9a8b),LL(0xfa441738,0x3f4fd525),LL(0x8cdf278d,0x5b1fa4df),LL(0x60600772,0xb7e79779),LL(0x15388443,0x6b7719f4),LL(0xd7a3aeca,0x17dd158d),LL(0x02441c0d,0x3d070ec1),LL(0xd5eb5d02,0x8264d6c9),L_(0x00000123), LL(0x0ab898cb,0x01117e64),LL(0xee325365,0x6f680374),LL(0xbc1ae420,0xdaebee10),LL(0x98a23bbf,0xfec8e51b),LL(0xb59efdf3,0xbbf08b12),LL(0xa18137ff,0x1532459f),LL(0x04b7fdbe,0x60238519),LL(0x37b3447b,0x4a54c60e),L_(0x00000108), + LL(0x6b53a82a,0xad2c8749),LL(0x5a5a47d3,0x75f76d03),LL(0x60558c44,0x6ecf38ff),LL(0x957fd8a0,0x7695311e),LL(0xcd47da64,0x215ee9fe),LL(0x35b22e22,0x4796f4b7),LL(0x949a56db,0xf62c912e),LL(0x74debc0c,0x62bb4591),L_(0x00000058), LL(0x9bd8df8c,0x203b317a),LL(0x637e055c,0x03c45bfe),LL(0x90fbadef,0x1132b50f),LL(0xaf36e7bf,0x20a98c58),LL(0x4f36088b,0xdebbd429),LL(0xcbb98ba8,0x391e4230),LL(0x3091f3e1,0xb3356938),LL(0xd86355bd,0xb1556872),L_(0x000000ab), + LL(0xf79ba658,0xb48e1df3),LL(0x3eb15b18,0x5fc03a10),LL(0x3bed592a,0x3591ad26),LL(0x127b78a3,0x07e9d80a),LL(0xc0337c7b,0x349dd74f),LL(0x364ed2a0,0xb1a807c5),LL(0x588d4203,0xecd92cca),LL(0x772a1716,0xf28c1d9e),L_(0x00000183), LL(0xf6fc1df3,0x42d25980),LL(0x8922f157,0x36f0fdb0),LL(0xa583206a,0x8cc1fe47),LL(0xc73f8816,0x1d279801),LL(0xe1b77767,0x7ac8979c),LL(0x3dba6831,0xa98b4836),LL(0x60d40152,0xc7f36b74),LL(0xc3d46c62,0xde52bda1),L_(0x000001ec), + LL(0xed4a0395,0x99b5cc1c),LL(0x4cddc23e,0x1d30267a),LL(0x16bee440,0xcd4130db),LL(0x553abd41,0x6652be0e),LL(0x6e659595,0x22061ff2),LL(0xf0c20235,0x72c720f6),LL(0x077f6daf,0x8079b1de),LL(0x1ad9ac77,0x52a9e551),L_(0x00000074), LL(0x6701fea0,0xdd8e0cb1),LL(0x5849b249,0xf395a61b),LL(0xb92466c3,0xc2b702c7),LL(0x77432a31,0xbd7899d3),LL(0x28b4ebc6,0x307f0a10),LL(0x0b06f919,0x5c8246fb),LL(0x7154af20,0x8f032be2),LL(0xc88de5c5,0xd4f96409),L_(0x00000076), + LL(0x344eafa5,0x0a16f77b),LL(0x724f29ca,0xdbafe962),LL(0x94bbb419,0x30985479),LL(0x2b2c87d2,0x3775b2ba),LL(0xe0e3814b,0xbd366c77),LL(0x1130e80c,0x7b644025),LL(0xf10ea539,0xe1da2161),LL(0xf66677b2,0xcab81415),L_(0x00000060), LL(0x11454e50,0xd8ab26fa),LL(0x45948446,0x2a4b8bd4),LL(0x35518731,0x34c59cba),LL(0xcc005baf,0xbd4d3f49),LL(0x06c483a0,0xa3e5d238),LL(0xd77da187,0xc4657e79),LL(0xa31fff1d,0x33918629),LL(0x0e898785,0xce7defc6),L_(0x00000010), + LL(0xd39844b5,0xc0ae95fc),LL(0x0cd04d32,0x608fd1bf),LL(0x2b33bcf9,0x8e195302),LL(0x3567e13c,0xb9784d4d),LL(0x6f12914d,0xf39a6a6c),LL(0xf4d361ba,0xcf170781),LL(0x366e62a5,0x70b10e90),LL(0xa3bce706,0x4f54bbdc),L_(0x00000091), LL(0x65a7fa0b,0xdf710618),LL(0x93abe742,0x7805a257),LL(0x738295fd,0x76e1d4b4),LL(0xcb5b0f15,0xc121708d),LL(0x716ee171,0x14725b57),LL(0xd2227241,0x2e484d37),LL(0x34400369,0xef0bb7f5),LL(0xebdf59e5,0xe564b505),L_(0x00000082), + LL(0xf35d7da4,0x0ee635c0),LL(0x6c91936e,0xdd72a103),LL(0xa9f8eae7,0x2a073b1f),LL(0xff539491,0x6c35942b),LL(0x0a881a03,0x35498b7c),LL(0x67e4af9a,0x59bde411),LL(0xf903d1e5,0x517835ca),LL(0xf0b93b5b,0xf4238664),L_(0x000001ed), LL(0x079d614c,0x550a47c5),LL(0x1c8515d3,0x1f9595ac),LL(0x1557c55d,0xf301c894),LL(0xb5548c2e,0xecc6608b),LL(0x6ed92475,0xf17244f1),LL(0x9b9d35aa,0x9b6083ca),LL(0x82abcca4,0x902eead4),LL(0x45a99fbc,0x489ec5a2),L_(0x00000074), + LL(0xc92a2f72,0xb4d59736),LL(0x46a97747,0xec9ee773),LL(0x92e9e427,0x54eed174),LL(0xe62769e0,0xb25c6252),LL(0x26eca3d7,0xb5598a2e),LL(0x72728c2b,0x73ee8036),LL(0x6cefdf35,0x4ee8ce4c),LL(0x700d3d8f,0x80153dd7),L_(0x000000e7), LL(0x2ffb5bc1,0xb8175b8e),LL(0xd9c451df,0xbdb5cc88),LL(0x9445c144,0x846b2eaf),LL(0x92957da0,0x5ff2e582),LL(0x2da50816,0xe7cc1a15),LL(0x4dc70abf,0xe4999b07),LL(0x24220cc0,0x1b3556b4),LL(0xb4413c1d,0x112c52e6),L_(0x0000006a), + LL(0xb5ee8957,0x45878f54),LL(0x112fbfa1,0x1879f721),LL(0xe9f0dfae,0xb007f421),LL(0xf113817d,0xeb000fbc),LL(0x35d8e979,0x206151d8),LL(0x0bf9caf2,0x258ab3b7),LL(0x6e8e8e3a,0x92a042db),LL(0x7a4dc496,0x53dcf8da),L_(0x00000112), LL(0x3d64ea94,0x7360c36c),LL(0xbf2b13c7,0xfb77c37c),LL(0x73884c74,0x65a78a55),LL(0x5d8600a0,0x888762bf),LL(0x77475414,0xc8ba0daf),LL(0x975e6be1,0x59f8b668),LL(0x14cf6707,0x185c7c67),LL(0xfef650be,0x043f0a23),L_(0x00000051), + LL(0x14dc97d9,0xa3e0a482),LL(0xe962fe1d,0x44364f6d),LL(0x19480b73,0x9ffa10f7),LL(0x28fc88ac,0x7993eaa2),LL(0x8a5db808,0xd4bb9db5),LL(0x4464dfad,0x9088a081),LL(0x903605db,0x86f98ca4),LL(0x87bd4fc7,0x5fb11fcc),L_(0x0000014a), LL(0xba5ec771,0xec2c3e51),LL(0x3078a6cd,0x1ad83e79),LL(0x66717c17,0xad871d3e),LL(0x8530527c,0x0e3f9442),LL(0x92315ca1,0x49c67cb7),LL(0x2fc5cd79,0x4eb1ba39),LL(0x256788a6,0x10b0e6f6),LL(0xb9cd18a5,0xef51548b),L_(0x000000c8), + LL(0xd61fb046,0x90213473),LL(0x4f9db0e1,0xcbb6e9b8),LL(0x36fcff78,0x6aa8fb8a),LL(0x7cd5e9d1,0x337a00c4),LL(0x2c2601e9,0xfe8445d7),LL(0xbbab713e,0x0681fd15),LL(0x0b2dd233,0x2151cff9),LL(0x00ab444b,0xf5654249),L_(0x000001cf), LL(0x06de9a88,0xcb8ede52),LL(0x209abe3b,0xe1369e32),LL(0xb711e224,0x53136516),LL(0x533569db,0x59d96525),LL(0x5419656e,0xf2d68025),LL(0x326eee21,0xd59bb004),LL(0x073cca71,0x1cbb722c),LL(0xaa784f93,0x50513866),L_(0x00000019), +}, +/* digit=10 base_pwr=2^50 */ +{ + LL(0x51931359,0x672b4b0a),LL(0x14acc3b3,0x78ea42e6),LL(0x22fe0a9a,0xe72784cd),LL(0xc20faf43,0x8f9c3ea6),LL(0x5e49f303,0x4c50987c),LL(0x12d1fb91,0x0c76e9b9),LL(0x96a89b90,0x74dc2b7b),LL(0x238b29a0,0x3a4808de),L_(0x00000076), LL(0xca68ea37,0x06adb168),LL(0x5ecbae96,0xe58dde88),LL(0x4d422e92,0xeba17742),LL(0xa609937c,0x1451998a),LL(0x8f30fc81,0x9eba807b),LL(0xa724c9f9,0x200db6e7),LL(0x651c126e,0xc9db2dc7),LL(0xb58e38f0,0x63ee509c),L_(0x000000e0), + LL(0x71e8870b,0x8ea654a6),LL(0xa23dd690,0xc3eb3660),LL(0x673dbdf6,0xa5ddaf70),LL(0x9bbf5d38,0x1e7af5c1),LL(0x0fe1371d,0xcc1eff61),LL(0x1572e30b,0x1308bdd3),LL(0x20ce33cf,0xc60db70b),LL(0x6ab6b3ed,0xbf718e03),L_(0x00000103), LL(0xae357b86,0x3ce6e16b),LL(0x94e06b89,0xa3849b8d),LL(0xb6058ad8,0xacee1675),LL(0x6add0f99,0x39df12ed),LL(0x43cd380c,0x5c645ff1),LL(0x0481e233,0x94a0f618),LL(0xc84b4bf9,0x805a52a4),LL(0x49a710f4,0xe454ce98),L_(0x000001a9), + LL(0x99d73698,0x68ebe9cf),LL(0x7fcd4216,0xc625e525),LL(0x4922e8d6,0xe579cc68),LL(0xe272485c,0x58eef2df),LL(0x1aedb9d5,0x6bba0e47),LL(0xf69dbcc2,0x6afac0cf),LL(0xd8f85c14,0x4dfdd56a),LL(0xc7e717e4,0xfa08e4f2),L_(0x000000ae), LL(0x7d4e9483,0x056cb0ab),LL(0x8a2580c9,0xee676f9d),LL(0x031109c0,0x0e2ecd89),LL(0x784c6d24,0xedf27261),LL(0xeac131cc,0xdb6b9edd),LL(0x9428ee22,0xf59f93aa),LL(0x90347b1c,0xd59691aa),LL(0xcb3849d1,0x0b74214c),L_(0x000001ca), + LL(0xc42ea299,0x33ae1a32),LL(0xd0ddacf9,0xb43b79b9),LL(0x30561bd9,0x0ad2636c),LL(0x12241370,0xd830def9),LL(0x85a779a0,0xda5f6561),LL(0x28b8580f,0x7e785d86),LL(0x8bafa8c6,0x48ce8b18),LL(0xc75df63d,0x746f16d2),L_(0x000000df), LL(0x5a90afd2,0xc72b304c),LL(0x1b4b2e57,0x40d7dec2),LL(0xe0f45d07,0x3eb94cfd),LL(0xaabbfa71,0xae1b3f10),LL(0x37fa8b4f,0xb080d24d),LL(0x6f6447d2,0x142abdb3),LL(0x20453501,0xfd470df7),LL(0x76e433f8,0xc036f47e),L_(0x000001af), + LL(0x1f809e00,0x9eb8b4e3),LL(0x91e1d4a1,0xa399e369),LL(0x9b1aa8fe,0xf15f9651),LL(0x80a83b4c,0xea343c7b),LL(0x1c2fb2b2,0xc40680cb),LL(0x4d003567,0xe7a338fc),LL(0x65bc46fe,0x4519127e),LL(0x3a269638,0x40c08630),L_(0x00000163), LL(0x8811cc38,0xcd6861c0),LL(0xd2e2abb7,0xccb0e7ea),LL(0xce5461a0,0x8c05450d),LL(0x28a458ea,0xeff9ba00),LL(0x51ce8e58,0x3e543072),LL(0x41ebfad1,0xa43fc5d6),LL(0x2acf8a4f,0xc0d63fae),LL(0xd16efc25,0x156cea94),L_(0x00000000), + LL(0x0c31be44,0x25c21bb4),LL(0x171af22e,0x91e02b25),LL(0xa0756859,0x87db4292),LL(0xd07cf03c,0xd52aff6a),LL(0xf2199b54,0x476b6c0b),LL(0x4c50edf5,0x1bd465b7),LL(0xdeb36507,0x9e6301c1),LL(0x957f58a4,0x0a904754),L_(0x00000067), LL(0xf73b742f,0x5e9d3550),LL(0x6b92e894,0x419be8da),LL(0xd785e55e,0x95d412eb),LL(0x6018e5bc,0xadbd35ab),LL(0x079447ae,0x5f3359bd),LL(0x21b9bd0a,0xc4db3315),LL(0x5774802e,0x4978d805),LL(0x18a2368a,0x662a2d67),L_(0x0000011c), + LL(0xd53479d6,0x5c26f234),LL(0x2d429971,0x107f7e92),LL(0x8c689924,0x334d8841),LL(0x2a5fa3eb,0xe5ebe430),LL(0xc519e325,0xe8291ba7),LL(0xf2242ce5,0x8a0c19be),LL(0x20419cdc,0x804a91ee),LL(0x70dcad32,0xacb0db7f),L_(0x000000c4), LL(0x78a46e2e,0x18b297a6),LL(0x21fc2dc8,0x3ba036e4),LL(0x30517e2f,0x7a021835),LL(0x49f89605,0x19710681),LL(0x84156ac1,0xd61e5109),LL(0x05c42243,0x31ade9f9),LL(0x7b661ab8,0x83c25735),LL(0x22eb398b,0x6193abdf),L_(0x0000012d), + LL(0xad081cbd,0x1433b543),LL(0x88d8cd2c,0x94641d24),LL(0x2da0394f,0xd8e36e70),LL(0x48288ca4,0x461fe782),LL(0xa112c8a6,0x6f063613),LL(0xb8624a48,0x77efb66b),LL(0x511d90ff,0x016e8d41),LL(0xce809694,0x5bb229a1),L_(0x000000d0), LL(0x36feced9,0x3ecdac71),LL(0x921f42e8,0xee8e2857),LL(0xe82b293d,0x2c3ef9bb),LL(0x182b25ab,0xac32f4bd),LL(0x297ad819,0x74b598de),LL(0xdd15916b,0xd5e666a5),LL(0x51456a24,0x447be0b1),LL(0x4dc25c5c,0x8726ab79),L_(0x0000003f), + LL(0xb1762839,0xba507049),LL(0xed038901,0xdcef710b),LL(0x4b349ec8,0x2489f866),LL(0x37b4ec4e,0x991460d8),LL(0x94e1cecc,0xbf2a63d2),LL(0x33d105a8,0xc7e7415f),LL(0xbf883b5c,0x268241cd),LL(0x2f565fda,0x65d5bd35),L_(0x000001f3), LL(0x8bf3904a,0x8e823f54),LL(0x0c2d77f6,0x06de5eb9),LL(0x2c00d580,0x89b51b4d),LL(0x41ce4b94,0x794caf3e),LL(0x177cd9b2,0x7c62716f),LL(0xfe0ae88a,0xb7e50074),LL(0x4d023907,0x49a489fb),LL(0x545f8faa,0xe82852b9),L_(0x00000070), + LL(0x05813dea,0x62545e9a),LL(0xc84039c9,0x70606ec0),LL(0xcdf6907b,0xec7e8e9b),LL(0x2e4e87c0,0x9d6e053f),LL(0xffa08764,0x22a2e351),LL(0xe5b305f1,0x95345fe3),LL(0x65c90711,0x4f24c950),LL(0x139d472c,0xbf685d44),L_(0x00000179), LL(0x9eeab46c,0xac8b67e8),LL(0x267bcc83,0x702c21e5),LL(0x0dac9b29,0xce390fe4),LL(0x60429071,0x6ef71376),LL(0x4a80e0d7,0x47100322),LL(0x0ef6a473,0xdc625a85),LL(0x759024e7,0xea01db5d),LL(0x1e4722a2,0x155020a2),L_(0x0000014b), + LL(0x5678bfca,0xb048b1b3),LL(0x5bacba68,0xf518ba8c),LL(0x1626088b,0x7054f024),LL(0xa686c886,0x933a9118),LL(0xbb623954,0x1c3c471e),LL(0xc4da98f0,0xf1b8c9b1),LL(0xa0619dd5,0xaeebf226),LL(0x24b28dc5,0xcbe9fb08),L_(0x00000092), LL(0x47814012,0x49c3a34f),LL(0x1cf06d59,0xfcdcc300),LL(0x6d4a798d,0xe86df54b),LL(0xa1a4dd57,0x1534b80c),LL(0xaf606d64,0xbdfde769),LL(0xde1cbaa0,0x649c3a2a),LL(0xbf6c9950,0x763574e1),LL(0xaaf6f737,0x7fdbd339),L_(0x0000015a), + LL(0xf687c377,0xca314119),LL(0x3eacfd33,0x2512d094),LL(0x9c0e1850,0xe55f9fd6),LL(0xc3c6ea7e,0xc20685b7),LL(0x66291556,0x4868b07c),LL(0xb5895337,0xf9f339d7),LL(0x9238a109,0x75d6855b),LL(0xac6af37f,0x78b54491),L_(0x00000184), LL(0x6eb5d5b2,0xe7603bff),LL(0xf7552855,0x8f73b087),LL(0xc19b7320,0xe8f5c0ad),LL(0x55df5442,0xb6aeabd3),LL(0x3a4b8876,0x8dc2b22b),LL(0xf8bca737,0x26f89265),LL(0x3dbb040c,0xfb6645f2),LL(0xb09ab1bb,0x30259f38),L_(0x000001e9), + LL(0x9e2dc755,0xea8b03a8),LL(0x5618c490,0xd5d01455),LL(0x01a7a348,0x9622ab8a),LL(0xa6b5c4df,0x9adea853),LL(0x303519de,0xa9b99058),LL(0xb3d0934b,0x0fbd9ea2),LL(0x2cdee030,0xe856d6fd),LL(0xa351d2a2,0x89fdbc8b),L_(0x000001d3), LL(0xea40ff5a,0x4859e663),LL(0x906f2d7a,0x71904b77),LL(0x411180a4,0xbd7ebd35),LL(0xe50b9460,0x0ec190c2),LL(0x2e7f4d73,0x4c9e4aac),LL(0x76a98ae4,0x4323017a),LL(0x7f0e29c1,0x22ea8f39),LL(0x31c71758,0x89d8efe3),L_(0x000000d5), + LL(0xcf98bee6,0x54f3df55),LL(0x672d0a69,0xe9759866),LL(0x1addc9d4,0x9c17b622),LL(0x6c819f7f,0xc42650ec),LL(0x6b1209c4,0x6a1aa1b9),LL(0x2b341fef,0xdbcf91bf),LL(0xc99d2b99,0xed76cdf2),LL(0x27467cd2,0x05f190ee),L_(0x00000008), LL(0x64754f19,0xc40615cf),LL(0xb8f1e46f,0x9a8d5587),LL(0x540f1fa5,0x804f7dd7),LL(0x21752096,0x2c95388c),LL(0x9444e15c,0x133319bb),LL(0xb1d5a817,0x29552f4e),LL(0x79fc1cba,0x93730e70),LL(0xcae8a131,0x4445951a),L_(0x000000dd), + LL(0x88863b50,0xbfdb676e),LL(0xb9545954,0xfcfc0194),LL(0xe74bedd7,0x888694d2),LL(0xe59a14c4,0x236680d1),LL(0x4cd674c0,0xacdf13c1),LL(0x52151e94,0xcdbecfcb),LL(0x6a28bc34,0x641d77e2),LL(0x6293af48,0x38e4eee3),L_(0x00000057), LL(0x2e8f361b,0x67004141),LL(0x39634681,0x5db1f02f),LL(0xf975c602,0xe645bd3a),LL(0x8b39a53a,0xfafccb60),LL(0xa58e37f9,0x33ab2637),LL(0xcf611fd4,0x8b8cc6bb),LL(0xe7f89e7f,0x28eb10f6),LL(0x5f527820,0xfdcde1d1),L_(0x00000151), + LL(0x9411ca0d,0x92267e14),LL(0xb385c8ea,0xbbfcc2ab),LL(0xbfd56d29,0x34b29656),LL(0x5f2180a7,0x06f72807),LL(0x6dc34000,0x02310437),LL(0x854af754,0x1bae73e6),LL(0xbc753242,0x06a8d2dd),LL(0x11770a34,0x9848b3d7),L_(0x0000011f), LL(0x14476594,0xeb8cb497),LL(0x6ba99aed,0xc86324ad),LL(0xc49863ca,0x8a316428),LL(0x2e5cfc3d,0xcb62d82a),LL(0x79adc3e0,0x9e5f3fda),LL(0xcaddeff7,0xb4f990b6),LL(0xae15a98e,0xb9b0e410),LL(0xedf394c7,0xac6cb00a),L_(0x00000171), +}, +/* digit=11 base_pwr=2^55 */ +{ + LL(0x20c391c2,0x96d1c5f4),LL(0xeaef76b3,0x6bb17f5e),LL(0x7feb16a1,0x3f16a57b),LL(0xcc801552,0x4aadf126),LL(0xcded6e6d,0xe23393c9),LL(0x6848f602,0x2c8dbcb3),LL(0x49f3a9ae,0xf811e23c),LL(0xc0c1ebfa,0x27162730),L_(0x000001e5), LL(0xaf1b88cd,0xb4c22029),LL(0xaa7f22fc,0x9624d6d5),LL(0xbb120735,0x416db935),LL(0xa8308449,0x85fd3219),LL(0xc467f9f1,0xb4d3e00f),LL(0xa69d57d8,0x187052a8),LL(0x0528c91e,0xb79e6638),LL(0x2a603bc9,0xb4ac37a4),L_(0x000001ab), + LL(0xca26efe1,0xa3ad38a0),LL(0xf5cd529d,0xec34abea),LL(0x94808b1e,0x27c847ac),LL(0x87ade961,0xfa6df215),LL(0x6a43fa8c,0xbcfdb5ad),LL(0x947fbb39,0xdd4d0c9f),LL(0xbca687c5,0xe8772a4e),LL(0x7d79e215,0x9fc12922),L_(0x0000008e), LL(0xbf926e1c,0xb04fbc5a),LL(0xb9c12ffd,0x34707ba5),LL(0x4ee8c89b,0x81aa347c),LL(0x367a152d,0x4cd56572),LL(0x74511a3a,0xa6642939),LL(0xd0e3b8f1,0x60ea13e9),LL(0xee14ab42,0x81a19a28),LL(0xea76ba4c,0x96065d5d),L_(0x00000103), + LL(0x6b0c75c4,0x23a4b0aa),LL(0xdb181c23,0xdc940ab7),LL(0x7b70983d,0x328a76b8),LL(0xd5b473a0,0xadcb9bcd),LL(0x3863dc05,0x646b4949),LL(0xe5090fd0,0x0b996e3d),LL(0xd0261360,0x7c332b20),LL(0xcc6b2f86,0x415e4fc7),L_(0x00000009), LL(0x28cd5819,0xf08cb2c4),LL(0xfbdf661a,0x9b1c2455),LL(0x2be7d7be,0x38fbe0c1),LL(0xbd91e037,0x84e69e29),LL(0x1cdba496,0xc6f94abf),LL(0xa8445728,0x8e9508e3),LL(0x4a144f07,0x8ee0e340),LL(0xc5b72f6a,0x80119066),L_(0x00000075), + LL(0xaff1e1b3,0x87421ab9),LL(0xbbfcc6da,0xa3305ebd),LL(0x4b75a8e1,0x8f4cb778),LL(0x4410056f,0xb5abdc6a),LL(0x4ff65612,0xd83f32f5),LL(0x21c44b1c,0xb989d251),LL(0x80a7bb1f,0x5214abed),LL(0x8f200e11,0x5e3475ba),L_(0x000001fc), LL(0xf4fb8525,0xf5f23c02),LL(0xaa8e02a4,0x405911d9),LL(0x45abb8b1,0x7a6dae03),LL(0x4834d14e,0x4621957b),LL(0xeb31fdc5,0x7cbf9b75),LL(0x26ee5dca,0xee84304e),LL(0x37349cc1,0xcc6a2c7d),LL(0x5a34c3af,0x740fffc8),L_(0x000001ac), + LL(0x9f122c9e,0x71cfc92d),LL(0x9c6ec42c,0xb86c84b7),LL(0xc8d12bf6,0x1c821b85),LL(0xe8432cc5,0x197e0f04),LL(0x4258bc34,0xc4f03c70),LL(0x60ae518c,0x811512ff),LL(0xf050c9b8,0xe8038335),LL(0x0b215595,0x84b70af0),L_(0x00000078), LL(0x423ac4f7,0xb15c3155),LL(0x2fd13662,0x7684c454),LL(0x5cf8078d,0x1a7bfb14),LL(0x2b928e98,0x1d05b843),LL(0x3bbf2a85,0xeeb1e658),LL(0x356da90c,0x179bc7a9),LL(0x11d26c87,0xf524843e),LL(0xf4159e0d,0x47c538ec),L_(0x00000128), + LL(0x08cefac8,0xb1885068),LL(0xe8422939,0x5985dd6e),LL(0xab14cf0e,0xcda94a64),LL(0xc27af983,0xd127851a),LL(0xf24f6eaf,0xbab20f8f),LL(0xda3b25d8,0xa549d9c6),LL(0xed810bd4,0x5bf18f37),LL(0xf630e4c9,0x14bb2655),L_(0x0000018b), LL(0xae18594e,0x52697460),LL(0xf8de9d89,0xaec56660),LL(0x294777cd,0xe3a93a39),LL(0xf7dc98fd,0x63fcc0bd),LL(0xc0c53dc3,0x5d2c2708),LL(0x55da9198,0x3692d050),LL(0xebcde249,0xcdc4d312),LL(0x8d0017f5,0x5aeda0c1),L_(0x000000a3), + LL(0x1d9471ec,0x737ba42a),LL(0xd3401c6a,0x33fd5fca),LL(0x3c2758a5,0xb016b83f),LL(0x79b1c693,0x3409d0d4),LL(0x5f80d853,0x4f2a7005),LL(0x4d1634ee,0x799e106c),LL(0x1e92ef70,0x632dcd5e),LL(0x86232632,0xb8cf2e87),L_(0x00000008), LL(0x1acab1e2,0x92c31a31),LL(0x91455009,0x740223dd),LL(0x15a695ed,0xa95f341b),LL(0xe601b98b,0x17db74b3),LL(0x19ccbb77,0xd916a466),LL(0x44573d27,0xc31a7a19),LL(0x093c0363,0x1bb20e06),LL(0x6715c5f0,0xc4532de7),L_(0x0000000c), + LL(0xa1a3f86e,0x2df7ec8e),LL(0xf1f8f7f3,0xd8551991),LL(0xb16ec397,0xbc80f4ee),LL(0xebe5be1a,0xa1e6cbf5),LL(0xaf8233b8,0x5c403702),LL(0x41483767,0xbf97ecb0),LL(0x2899a5cc,0x58655568),LL(0x0720d399,0x092de028),L_(0x000000bf), LL(0x88312054,0xd550df72),LL(0xf87e274d,0x193eb1e2),LL(0xa715c43f,0x97773656),LL(0xcb67dce2,0x8a585c6e),LL(0x0aacb5db,0x6332fcd1),LL(0x4f16d92a,0xdeebccba),LL(0x2b8001ac,0x8936c8da),LL(0x7b627657,0x4f5f2781),L_(0x000001b8), + LL(0x8d63a794,0x35fd304e),LL(0xdd225fc9,0xa6aae952),LL(0xc40c9b7f,0xd5054f16),LL(0x42316d8c,0xf663b3dc),LL(0xb3d7abe3,0x13c94097),LL(0x7aa82bbf,0x78263190),LL(0x2a622ce8,0x819c0b14),LL(0x2b1dba5c,0xcf88a41a),L_(0x00000049), LL(0xe69bb850,0xdf7bd8ef),LL(0x985f2ed6,0xc76c2599),LL(0x44f156c5,0x46e2c0c0),LL(0x7cfc49ae,0xf5fb07c3),LL(0x6f59a7a0,0x2f48e451),LL(0x1b89eefd,0x88119cbb),LL(0x1c41ec61,0xa18666db),LL(0x53014a3d,0x4b3591f0),L_(0x00000078), + LL(0x792d6d08,0x4d84ecf1),LL(0xe0110c24,0xc93fa7f1),LL(0xc72b1bb4,0x908f695c),LL(0x1730f1b2,0x8d0bc692),LL(0xdb0b36b3,0xe4bf469c),LL(0xa1db29c0,0x1d41428d),LL(0x7a577f2c,0x2cd1253d),LL(0x23b65522,0x07ab206a),L_(0x0000009c), LL(0xa4ba5fbd,0x9808ec8a),LL(0xa5383520,0x49718327),LL(0x2c210a5f,0xdc5bb249),LL(0xef53e1db,0x7e38e02e),LL(0xc9d3c171,0x7b41e983),LL(0x3a07d487,0x2d8aedea),LL(0x6c0e3ba1,0xa17e058b),LL(0x22c8be6d,0x7c63dfd0),L_(0x000000fd), + LL(0x6a5713b6,0xac6235d1),LL(0x19855a0f,0x32d1869e),LL(0x093a8212,0x8afdb213),LL(0x89861196,0x3402ba32),LL(0xb3676c48,0x5e54b89e),LL(0x53597329,0xbdde3064),LL(0x94cdc873,0xc3d273b6),LL(0xfd911ed5,0xa0110df1),L_(0x000000a2), LL(0x0d98f860,0xf6cf3683),LL(0xa681e586,0x6f5c1e3f),LL(0xc6905825,0x7d626d06),LL(0x571b75e4,0x00a44322),LL(0xf9fe1aa4,0x34ece73d),LL(0x3975b815,0x38add31a),LL(0xfa3db092,0x499ecb33),LL(0x2ce86fab,0x9eb9f7bf),L_(0x000000cb), + LL(0xf5870ab9,0xa353002c),LL(0xa12da044,0x6150f34f),LL(0x0086b83e,0x69e6eea2),LL(0xa2cdf131,0x5e80e0a0),LL(0x528616b2,0x2d13e0cc),LL(0x4a67c598,0x9702e01a),LL(0x83d6e661,0x15b60ef1),LL(0x6f9172f8,0xd6247a1f),L_(0x00000115), LL(0x7b2b5776,0xe6acc547),LL(0x055811a0,0xba422b24),LL(0xa9873020,0x8c990991),LL(0x310acf2c,0x96459d45),LL(0x78701ea7,0x917c30ec),LL(0xd1688c83,0xdb51be44),LL(0xb42ce9e9,0x0b514c3b),LL(0x0b03fd87,0x0c8ed48d),L_(0x000000c7), + LL(0xbcc82868,0x69816459),LL(0x580f7a11,0x9b94ac07),LL(0x11b4de1d,0x120451de),LL(0x8f21a7aa,0xc048b454),LL(0x0f6b490e,0xca8d647e),LL(0x5d0f4e1d,0xf1f7c090),LL(0x3e12d889,0x1ad27c80),LL(0x5b341256,0x381024e5),L_(0x00000161), LL(0x35f1970a,0x4366eed0),LL(0x1134e984,0x55c0352d),LL(0x7ea259fe,0xfad7d83b),LL(0xda4dcbce,0xdd5f6008),LL(0xb2924c78,0x01b25214),LL(0xac404086,0xf325f997),LL(0x2b613948,0xf37e21a0),LL(0x26e31be0,0xf87b2cb4),L_(0x000000bc), + LL(0x017edbd6,0xf483d72a),LL(0xb08491c6,0x58a225c5),LL(0x568a7e71,0x7fde8697),LL(0x821bf73d,0xef4bc022),LL(0xec765e3a,0x8d1daf2f),LL(0xb59a1d2e,0x72d486e7),LL(0x1edfc037,0x2a595f95),LL(0xf1683f88,0x9376cfff),L_(0x00000081), LL(0x55fc5381,0x96f30cc5),LL(0xc6ce2141,0x76a3af64),LL(0x339f5668,0x5449bfff),LL(0xe438adb5,0xf3c48dff),LL(0x1aa59ae8,0xce59b544),LL(0xc0fd6c57,0xb7bdc7b7),LL(0x8e51d10e,0x973b8e1d),LL(0x6427d578,0x99827d6a),L_(0x00000098), + LL(0xe76cf424,0x4eac44ab),LL(0x559e7a5a,0x0ddf44f2),LL(0xc58d75d8,0xfb0d499a),LL(0xab62039f,0x6cf6c677),LL(0xd4e76825,0x2e427953),LL(0xa955fdca,0xe1d73f88),LL(0x049f7f5d,0x89dc4a2e),LL(0xd5493485,0x3b5c3f5a),L_(0x000001ec), LL(0xa5dc86bb,0x2a75769b),LL(0x606d9e57,0x550fb22b),LL(0x260bcabb,0x7bccdd84),LL(0x2e3ee7a3,0xc4b6b979),LL(0x03bd7f7d,0xfc3349bd),LL(0x122b5333,0x95f84290),LL(0x4bdf7095,0x3057b4f5),LL(0x6af3cf31,0x5d341e22),L_(0x0000015b), + LL(0x1d055192,0xf272a08c),LL(0x343f766f,0x142d545c),LL(0xb8bd86e9,0x860ef117),LL(0x60c69c66,0xb6de931c),LL(0x1b54e53c,0x9924f2f5),LL(0x878c0c9b,0x0b949095),LL(0xfba7e2a3,0x6916f5f1),LL(0x7da79c3a,0x9166a581),L_(0x000000c9), LL(0xe06ad6ba,0xd551de11),LL(0x3b3cbbe6,0x6c45d4c3),LL(0xcc4aa553,0xe3c9e3df),LL(0x1bb5c238,0x05a1e382),LL(0x8dfc012d,0x84d8d463),LL(0x3b856506,0x05b7e241),LL(0xcdcfd8e8,0x27718949),LL(0xc1a85e66,0xab32f2ef),L_(0x0000017a), +}, +/* digit=12 base_pwr=2^60 */ +{ + LL(0x0af6a9bd,0xdca0a6cc),LL(0xfe5f904b,0xd9e6d336),LL(0xd87d0339,0x3b8c9d8b),LL(0x4d463bab,0xfb629c3f),LL(0xc203e46d,0x4ea62ed4),LL(0x998a0ef3,0x64035458),LL(0x62783285,0x7769592c),LL(0x3c56ebb3,0xb1cb181b),L_(0x00000013), LL(0x259a17aa,0xd51ce441),LL(0x8666df8e,0xc62b1c65),LL(0x437c7966,0x74db6999),LL(0x0fecb364,0x7c60998f),LL(0x1f725b1f,0x71fdafc2),LL(0x5b56396c,0xa547fb5a),LL(0x9d888686,0x0f566ae7),LL(0x130033ff,0xd990e0f4),L_(0x00000172), + LL(0x12a6c73f,0x66164319),LL(0xfe4c8bf4,0x9c6ffbd2),LL(0x42f313ec,0x2869e4fd),LL(0xf8b100ba,0xbae712b9),LL(0x0e18229b,0x61a1f1da),LL(0xffe55501,0x032c80f2),LL(0x3bfaa0e0,0x48f0b1d5),LL(0xb83c7607,0x49fa235f),L_(0x00000083), LL(0xa0ed3335,0x8b3c031f),LL(0xc141575b,0x53c30e33),LL(0xfa62217c,0xf9f945a8),LL(0x8b667de4,0x889399aa),LL(0x7c4952fb,0xb711abc7),LL(0xabedb6e3,0x59e7e12f),LL(0x5a1b2cb9,0x1857ebfe),LL(0x4206e243,0xef43f534),L_(0x00000079), + LL(0xa95f9c5a,0x0d937115),LL(0x2ee0eb80,0x4b1412c8),LL(0xdf5a5904,0xe6f39cf3),LL(0xcd50327e,0x9a796b16),LL(0x0841dfd1,0xc493ac5c),LL(0x19d15d79,0x7275eb23),LL(0x4b9d4479,0x1a3b6feb),LL(0xe1eb10df,0x3bcfa542),L_(0x00000060), LL(0x7551bac5,0x7a907c78),LL(0x232dc783,0x82e7d67e),LL(0x5acaf222,0x5ebc3c22),LL(0xe17100c9,0x62250256),LL(0x3198b234,0x4beb3ba2),LL(0x16986b8a,0x492d3035),LL(0x973e4135,0xfcc0dd28),LL(0x2e1155d6,0x2fe7131b),L_(0x000000da), + LL(0x1f14d7bc,0xe951da15),LL(0x3d397c45,0x3964143f),LL(0x24be6549,0x2e556c9c),LL(0xe1293e25,0x3aed330a),LL(0x4bfda40e,0xdf82159a),LL(0x3b13e72c,0x514f7b17),LL(0xa5b859ff,0xe20684bf),LL(0x90812f67,0xed303fce),L_(0x0000009b), LL(0xbca9abf7,0x3b0b3a0f),LL(0x72194a82,0x11d27090),LL(0x17f5564f,0x9bbb7a7f),LL(0x87f0af99,0x96c01479),LL(0x69d62017,0x45cce25a),LL(0x0c43d35c,0x26584337),LL(0xcbff6e89,0x19a55401),LL(0xb503e2ea,0x4184b0ea),L_(0x000001d3), + LL(0xaecaabc4,0xdeccde50),LL(0x9ffdf34c,0x395d2404),LL(0x25068e1b,0x40559189),LL(0x93fb9ea4,0xd141ad3f),LL(0x2a60ba95,0xc42f76f0),LL(0x414a5981,0x946bf800),LL(0x138c47b5,0x38435023),LL(0xf314147e,0x9aa25f3c),L_(0x0000016b), LL(0xe38bdcc6,0x3cebd917),LL(0x0966bac7,0xc3533788),LL(0x2718c3e8,0x33ee6ede),LL(0x10236ae8,0x4f5b88fd),LL(0x44797bb1,0x485e76bd),LL(0xb2b31296,0x68194c12),LL(0xe45112ba,0x0cb75dc1),LL(0x8574000b,0xc33c7dd8),L_(0x00000135), + LL(0x8f37d315,0xf77a65b3),LL(0x37731160,0xde279622),LL(0x6f06ae65,0x87ebd334),LL(0x25b38b15,0x2a1d2c7a),LL(0xa55c6b9f,0xb1687394),LL(0x0ccf2f34,0x4f27c66a),LL(0xecf3de75,0xa9866c84),LL(0xa4a0f4aa,0x44979b4d),L_(0x000001dd), LL(0x0366dd8b,0xbfeaeff0),LL(0xfe941121,0xa80b5c3b),LL(0xc3fed2fa,0x18a5b6a4),LL(0x23dfdf47,0x2ef007c6),LL(0xdb0791d2,0xcec61c6b),LL(0x6d79949c,0xe328d9cc),LL(0x0d03e696,0xaa14a153),LL(0xfdb36710,0xffd70d45),L_(0x0000011b), + LL(0x736dcfa6,0x77e26493),LL(0x6af49ff9,0x089ee4ac),LL(0x1720bd71,0x2f3b86d6),LL(0x48d2c5df,0xbcc66a78),LL(0xd78e07af,0x1f230a9e),LL(0x077a7ceb,0xd2f61bf5),LL(0xfbf99e70,0x92770c3f),LL(0x7ae5f084,0x1a79a148),L_(0x00000035), LL(0xa6ee44c4,0x990f4f03),LL(0x4aacbd8f,0x45377427),LL(0x0ef447b6,0x55b5c873),LL(0xe02e661f,0x11e65ae5),LL(0x99f13f10,0xfe17d3ed),LL(0x393cf4c8,0xdbeb35dd),LL(0x23277110,0x65a7d1cd),LL(0x444802cd,0x8532c3fb),L_(0x000000c9), + LL(0xea71a842,0x4c057a1d),LL(0xfc8fb859,0xe1689c80),LL(0xadc9a8e1,0x09c22f52),LL(0xc47b8163,0x0a960c99),LL(0x90c495f0,0x0a0f356d),LL(0x88242e20,0x87494b79),LL(0xb7f9ca6a,0x6fdcd587),LL(0xd76d2c39,0x43fae9c4),L_(0x000001ec), LL(0x1e35970d,0xaee47a26),LL(0x8df13449,0xadfd394c),LL(0x67553f2c,0x71cdfbec),LL(0xa43c6154,0xf09db2ac),LL(0x4606556e,0xf2e04011),LL(0x12eca225,0x9dfb28da),LL(0x87a4c839,0x28812bc5),LL(0x8cba8984,0xd9e2b1ab),L_(0x000001ad), + LL(0xcb554ab1,0x3446834e),LL(0x21810284,0x2ab359a6),LL(0xf95fa59b,0xf33f9ef0),LL(0x16db657d,0x0f8d940a),LL(0x38fe2897,0x39b668bf),LL(0xdeba7f4c,0xc6452278),LL(0x7471cf19,0xb96dd1e3),LL(0x732f77c2,0x0834711b),L_(0x00000092), LL(0x745c3f1b,0xbca782f9),LL(0x8bd5ef13,0xc4e21488),LL(0x8211733f,0x8f6c1b78),LL(0x50b780cb,0x4b628b50),LL(0x1a1a0206,0x78e4de6a),LL(0x44975c37,0xf9f51865),LL(0x6ef7e616,0xbadf032d),LL(0x3882a9ad,0x821f6884),L_(0x000001f4), + LL(0xe84ad756,0xf2f7ceab),LL(0x6545847a,0xfb04aded),LL(0xdd4cb1ba,0x87083ecc),LL(0xf4c8bbb0,0x452249b7),LL(0x6531b732,0x868536ed),LL(0x6968e15d,0x1d0209ca),LL(0xf0285aff,0xfaefc194),LL(0xbed23705,0xa154b4bd),L_(0x000001c9), LL(0x3ea47ce4,0x69374c35),LL(0x2a6d8757,0xdc6375ee),LL(0xc6f768ea,0xaeba5bab),LL(0x327c743e,0xda6790e0),LL(0x9a01ae4a,0x1a9de4f9),LL(0x3ae6cb85,0x9ac5b7b3),LL(0x6d32a174,0xf134b615),LL(0xdf38a0f3,0x136a4fec),L_(0x000000c9), + LL(0x688d2325,0x79db6c85),LL(0x5359ff24,0x764f954a),LL(0xc7801c4a,0xfa78e8b8),LL(0x098ede82,0xb52cd1ab),LL(0xd34f03a8,0x66adb2da),LL(0xcfcfe244,0xfc69d130),LL(0xb5e52304,0xf88483bc),LL(0xab73db68,0x38339bc7),L_(0x000000fb), LL(0x077d01af,0x7eb9fb07),LL(0x8abf2d7a,0xcb62a0d5),LL(0x37a4ecbb,0x1a28e347),LL(0x06b68356,0x35c05ae1),LL(0xadaac01c,0x2f3d8c6e),LL(0x712aa1f3,0x9ee5907c),LL(0x69606236,0xc9bdbb2c),LL(0x7b2e6894,0x1e267011),L_(0x00000045), + LL(0x09d420b2,0xccc993bc),LL(0xa3ad7d2a,0xd8b3ee97),LL(0x7986ac14,0x59fa9e76),LL(0x95dc5774,0x9477b42b),LL(0xfbe8e9d7,0x89d7ab26),LL(0x79b03712,0x017b7f94),LL(0x77f9bdea,0xbd8dcef1),LL(0x7a238609,0xb9973bfe),L_(0x00000018), LL(0xaee002b6,0xcdfc127c),LL(0x23640ec5,0xad2abcbc),LL(0xc6dc5bd5,0x05982646),LL(0x20400061,0x3c1c6b9f),LL(0x6ee16a76,0xc943d1fd),LL(0xd619a75d,0xd16a85f5),LL(0xa278715e,0xd8747be6),LL(0x34ec8668,0x3ff993c0),L_(0x00000037), + LL(0xcec9be5b,0x6f5e16ec),LL(0xfd62380c,0x192223b1),LL(0x27bda6fd,0xe1e75d7c),LL(0x0df8a788,0xd01bccf4),LL(0xbeed1a6b,0x6611a8ed),LL(0x01402436,0x17838dc7),LL(0x7f189fd3,0x615a507f),LL(0x760bd862,0xe4e17352),L_(0x000001b5), LL(0x791dac6d,0x2bb5aa65),LL(0x0457b859,0xece0f798),LL(0x1a8af3a8,0xde75b69f),LL(0x6625db63,0xcf064060),LL(0xeeda55fc,0x0d8f8c69),LL(0x05536430,0x27c6a431),LL(0xb1dc58b1,0x56c1ac3a),LL(0x0c1a1dab,0x1e026aae),L_(0x00000012), + LL(0xfb73e1e4,0x0f973c1b),LL(0x6977f355,0xca40d04d),LL(0x2797e4c7,0x01c089b0),LL(0x1b05804b,0x0064b701),LL(0x7b76fc1d,0x9677da0f),LL(0xb0b47105,0xd02ba9e2),LL(0x4fb9b758,0x6b2435ea),LL(0x2fd704c2,0xd08297a6),L_(0x00000031), LL(0xdc19942f,0x4734e848),LL(0x366f685b,0x6b9e935f),LL(0xb3827f30,0x81e91d77),LL(0x4cce7910,0x36ada690),LL(0xcb031a95,0x227eb763),LL(0x6ac3a0f0,0x527fc0d3),LL(0x7b60ac80,0x404eb0f3),LL(0x2c62b4f1,0xf1c63ec9),L_(0x0000004a), + LL(0x95cf6b06,0x69fd4f1d),LL(0xbdef736a,0x9044b8ce),LL(0xd7e44ee1,0x546a5d1c),LL(0xe3ac270c,0xbe0ace78),LL(0xe59e1538,0x27b93218),LL(0xe51fc4ac,0xf26796fb),LL(0x71f9328b,0x9137cac1),LL(0x07a55147,0xbda08657),L_(0x000001f4), LL(0x9ce1532c,0x37d59c98),LL(0x2c0e5b9e,0x62f632e6),LL(0x55146f87,0x29fd2249),LL(0x402150dd,0x12ea0f69),LL(0xf442153e,0xfa397b38),LL(0x9b5cefd9,0xc5ad174d),LL(0x8cae5294,0xb46b9f16),LL(0xcd8b0a60,0x773343a7),L_(0x000001db), + LL(0x1e614695,0x71344edf),LL(0x2b4a50c1,0xb3013081),LL(0x4896c770,0x2cf314a1),LL(0x96a68659,0x90053fe7),LL(0xd79226d8,0x5847ac79),LL(0x3ada869a,0xf60993a8),LL(0x7d156a5c,0x67e4b5fe),LL(0x7850cdf6,0xed437add),L_(0x00000084), LL(0xf35bcbb3,0x4e2d6021),LL(0x9877f0a3,0x90be9398),LL(0x4d6435bb,0x86130340),LL(0xe5919257,0x2710c007),LL(0xcc99d199,0x87d3586c),LL(0xc1451c79,0xe8681c58),LL(0xfa896da8,0x6659a487),LL(0xb1a9e543,0x67bd49a8),L_(0x000000bf), +}, +/* digit=13 base_pwr=2^65 */ +{ + LL(0xfa295332,0x0b259ba7),LL(0x94f8c958,0xa4092fea),LL(0xbe9d56f6,0x622efd38),LL(0x0f2ba425,0xa4d25a72),LL(0x57c0adb2,0x2498a9ea),LL(0x11f11875,0x893bbb4d),LL(0x195ec41d,0x2f56b02f),LL(0x2ad72c4b,0xe7bb8bca),L_(0x000000e7), LL(0x0fa4013f,0x521f983a),LL(0xebae7f17,0x5292b2f1),LL(0xdebce289,0xd6d75002),LL(0xb6cd203a,0x93bfe503),LL(0x3c3592c9,0xa40b351b),LL(0x180f5400,0x9b6bafed),LL(0x291283ae,0xd4d6a9f0),LL(0x036cf95d,0x6e0c1563),L_(0x00000035), + LL(0xa8cfa5a9,0x33878665),LL(0xa5401cc3,0x809b2a4b),LL(0x6cdc3f0e,0x90d9594f),LL(0x9bbfac67,0xd551d6e9),LL(0xfd836074,0xe874e847),LL(0x13f89d9a,0x264b3b0b),LL(0x7a6ec5fa,0x0a3ac51f),LL(0x6dd250c6,0x6ed0021d),L_(0x000000bb), LL(0xd1e14aba,0x7c3196ca),LL(0x1495ef12,0x78a62924),LL(0x0cbcf8af,0x1f4ded5d),LL(0x83d56ec3,0xfa54b15b),LL(0xcc6ef029,0x6f0a12c6),LL(0xae62cc51,0xce830e11),LL(0x964fd2d0,0x88747fe9),LL(0x56076a32,0xe8f7bc67),L_(0x0000014e), + LL(0xb73d3d92,0xc668cfa4),LL(0xda69c4d9,0x97ee2907),LL(0xbf4c3402,0xbf5fb743),LL(0x4034c59c,0xd60ae9cd),LL(0x99bc4b73,0xda82be72),LL(0xda1f7664,0xe3800a84),LL(0xfb007b67,0xb7700f12),LL(0xb546161e,0x1386e882),L_(0x0000011f), LL(0x4be150bb,0xfc5d0def),LL(0x660c9122,0x1ba0f43d),LL(0x3a5b4550,0x7224e926),LL(0x33c24e5b,0xba92b4ef),LL(0xd249e1b7,0x2b1856c8),LL(0xb2c9aa15,0x5fe68108),LL(0x6e540179,0x2fe766ae),LL(0xa379f58c,0xecd72903),L_(0x000001a1), + LL(0x4d5341f2,0xdff5ad0b),LL(0xbb141c66,0x6270a82e),LL(0x7912e413,0xfc62897d),LL(0x6b16ad87,0x348f2e6b),LL(0x0fe7c18f,0xae57af6d),LL(0x2f22a03b,0x6d2d6ab0),LL(0xefa7a28a,0xd717c3e7),LL(0x73423958,0xe64f19c6),L_(0x00000065), LL(0x0b4f0f2c,0x8c6c9219),LL(0xa884b55b,0xaff1be7f),LL(0xde74b331,0x8882c375),LL(0x7a676c7d,0x57c355f3),LL(0x71190b6b,0x180dbbfa),LL(0x599b9c95,0xd7dc77b1),LL(0x8f766481,0x227eba11),LL(0x840229ee,0x3dabc4aa),L_(0x000001c9), + LL(0x5d79f380,0xaa1f8835),LL(0xe2b5d59c,0xf1a96e2b),LL(0x281ece14,0x146a87f9),LL(0xb65f19cf,0x24f845c5),LL(0x2f123e45,0x9418bddf),LL(0x90bcee98,0xb6ea99d9),LL(0x64b9ae2d,0xd147e8b2),LL(0xda89ba61,0xf40e6b8f),L_(0x0000014d), LL(0x53c9380f,0x31e35563),LL(0x7d832bdb,0x7117919e),LL(0x5906fec2,0xbdd97ce8),LL(0x069087de,0x015486f6),LL(0x866bf3e5,0x909fd1d8),LL(0x1d61be88,0x770d7f9e),LL(0xa28b013b,0xe7653682),LL(0xddec12fa,0x6232ac60),L_(0x0000006d), + LL(0x38819383,0x0ad9906f),LL(0x9f83225e,0x089577d6),LL(0x8e97694b,0x264428ce),LL(0x0c33baa6,0x1bf2f80c),LL(0x0823ef0c,0xbf31819a),LL(0x2e4750ee,0x66c7b596),LL(0xd160d5df,0x886455a6),LL(0x575835ea,0x662cb270),L_(0x0000006f), LL(0x3c424c86,0x240ffedb),LL(0xd1be1d89,0x3c874c88),LL(0xed147fb3,0xccd38c51),LL(0xbbd7bef5,0x10af1392),LL(0x101c8dcb,0xd85a000f),LL(0x018793c4,0x0b435263),LL(0x24305a2a,0x989d12cc),LL(0x9c061ca0,0xa4553f3e),L_(0x0000005f), + LL(0x9a069590,0x8dfc3414),LL(0x1912aeb6,0x0b37df44),LL(0x1e30b3df,0xcbe1989a),LL(0xaf9f97dc,0x415de022),LL(0x4e406185,0x01cb0277),LL(0x2eb58373,0xbb545160),LL(0x0ab0a19c,0x1e53639f),LL(0xeecdb49f,0x1d63db69),L_(0x000001de), LL(0x2a5d2526,0x8e8397e0),LL(0xa679b16d,0x44c0a296),LL(0x7dcafbf3,0xee3f4022),LL(0x668a1c15,0x2ca74425),LL(0xea786663,0x4906d981),LL(0xda4fa2cc,0x0bbbb1fb),LL(0x21224a70,0x8859a117),LL(0x8ec6a6f4,0x1d1581ec),L_(0x0000019b), + LL(0xf1507b4b,0x4574b533),LL(0xb56c3906,0x76eaa707),LL(0xa9532376,0x16e5e98a),LL(0x611c9b67,0x12d9a934),LL(0x9eb6a261,0x8430b478),LL(0x3fab6e06,0x50fd9610),LL(0xd215cdde,0x1d509b62),LL(0xc4da786d,0xcdfc10b7),L_(0x0000007b), LL(0x752a0af8,0x3ebf635e),LL(0x680f5838,0x9175f3f7),LL(0x9f1a0d87,0x861b999d),LL(0x04cce1e2,0x75ef231f),LL(0xe86e6afd,0xaf7240e6),LL(0x04734476,0xe887f56c),LL(0x2837e095,0xc194ba35),LL(0x9e3dc524,0x97c14f46),L_(0x000000dc), + LL(0x9a9802d3,0x4d7d0f39),LL(0x0345d8d7,0x5e5fc037),LL(0x6923910c,0x0187070a),LL(0x5e15ce92,0x3e13ac42),LL(0x456e81c2,0xcc3c7cbf),LL(0xfc527716,0xcd65b4f8),LL(0x5fd7c9e9,0x305c5c1a),LL(0x4af9f3b6,0x023984a4),L_(0x00000196), LL(0x1b64c99c,0xc01b599b),LL(0x38f68420,0x53fbc68b),LL(0x1b40d8c5,0x91c4f402),LL(0xe87107e9,0x0e78fd77),LL(0x96fc64fc,0xf13016cf),LL(0x438fbd69,0x59324677),LL(0xa8e5ff95,0x50792eee),LL(0xb6a73a20,0xf0ee755c),L_(0x00000074), + LL(0xb1979059,0xaa4d1038),LL(0xf13725c9,0x5751fd0c),LL(0x22f3e709,0xe1b98f3c),LL(0x131dbcec,0x8e66976f),LL(0x64116cc1,0x2dc36526),LL(0xf955db38,0x6f94eedc),LL(0x6bee8490,0x2dc08c31),LL(0x65ce87a2,0x73c1c8c0),L_(0x0000016b), LL(0xf8a59cff,0x9035a740),LL(0x328c1388,0x61a4c1b8),LL(0x1625b5b4,0x8b1931b4),LL(0xf35b9bbd,0x075bce63),LL(0xfb1707dd,0x7a601744),LL(0x232aecf6,0x50241612),LL(0xa974c9fd,0xf1cae8d5),LL(0x7f4ba9ea,0x7ae0d836),L_(0x0000012d), + LL(0xe7c06e65,0xa5756aa5),LL(0xd57f322c,0xc48c9811),LL(0xd934c78f,0xf0128bf0),LL(0x15f53184,0xd880ad31),LL(0xadaedd19,0x967dfa08),LL(0x374ad4e4,0x94c0e608),LL(0x389863cb,0xcecf2255),LL(0xe582d71f,0x02511eed),L_(0x0000017c), LL(0x5b089de0,0xef23aed0),LL(0x89f1eb4b,0xb93d3851),LL(0x8967136f,0x4daacc4f),LL(0x2482bd87,0xd7b99516),LL(0x8a382f79,0x404615c9),LL(0x9daadb4f,0x114144be),LL(0xd38bfc82,0x173ad4ab),LL(0x7f91ad71,0xcab03e42),L_(0x0000008b), + LL(0xa28a3c93,0x299c2c3f),LL(0xf2024c1b,0x63be4df6),LL(0xcbefbff9,0x39510e86),LL(0xe4d80ac6,0xf1d2f2e9),LL(0x8653ba64,0x0165880a),LL(0xd4fac73e,0x73ce1252),LL(0x67da578f,0xeb225590),LL(0xc1817050,0x2d6d0dbb),L_(0x00000096), LL(0xdc671b44,0xa93c7bda),LL(0x82c05dfc,0xcb77f18a),LL(0xaea605e9,0x1df6368b),LL(0x295e78ce,0x67c3474a),LL(0x93547410,0x18ce6948),LL(0x7dc8108a,0x7c67eccb),LL(0x8d3a8c61,0x67a75d98),LL(0xbd7b3b73,0xbf3fd62e),L_(0x00000046), + LL(0xaca4c347,0x9fc92c8d),LL(0x994543ca,0xc6ad228f),LL(0xb218a1c0,0xc58614eb),LL(0x527974b7,0x6ca62054),LL(0x85ffca1f,0xc2129ab9),LL(0xc6c14b3f,0x019b6e5f),LL(0x2ae678d2,0x1e22f90d),LL(0x5b3ee46c,0x71e5f846),L_(0x00000084), LL(0xd3c4dd26,0x4e855850),LL(0x74af7741,0xf226ab4a),LL(0xe0d7e588,0x332581f0),LL(0xe826c3d6,0x4284a728),LL(0xcdf777fd,0x6bfcaba8),LL(0x5a83f0b7,0x6ddf35c7),LL(0x2fbd194d,0x212fa0d3),LL(0x072b793f,0xa6758649),L_(0x0000011c), + LL(0x9d02c3bc,0xb7ec87d2),LL(0xe0887e3d,0xb3caff01),LL(0x4d1f3674,0x567cdbdc),LL(0x39e61184,0x3d19e2c3),LL(0xbe0de4f9,0x0c3139a2),LL(0x500e0978,0x7ba6031f),LL(0x6f3470b9,0xf8e9a69a),LL(0x65297bad,0xe732fb59),L_(0x0000001d), LL(0xc7bd9625,0x69eb8288),LL(0xe4ec65aa,0x281d3a84),LL(0x2c8f25ab,0x27426301),LL(0x97e61a91,0x3672bc0b),LL(0x95476b11,0xbfd7d2dd),LL(0xbff37ddc,0x918c4eae),LL(0x82eea309,0xbd19084d),LL(0x26d27fb7,0x769378af),L_(0x0000016a), + LL(0xe6cbd721,0x4a4ba674),LL(0xc27ec19d,0xf1234a47),LL(0x16a6532d,0x3cf8bf88),LL(0xe2dbe535,0xbc4dc6be),LL(0x948616ba,0x46216f90),LL(0x76d1a242,0x02af6244),LL(0xd5de4770,0xd85e1029),LL(0x7fda32cb,0x5681f9f1),L_(0x0000012f), LL(0x34f944fd,0x944544cd),LL(0x0193b124,0x72b4685a),LL(0xe7601697,0x6ec14591),LL(0x9572360e,0x2184e096),LL(0xffc7295c,0x9127a0f3),LL(0x844306ef,0x818c91ad),LL(0xf603be79,0x81b486bc),LL(0xc1bd26da,0x0974514f),L_(0x0000014d), + LL(0x3c726e7d,0x7d1e874b),LL(0xa513da39,0x8c78c755),LL(0x92677915,0xe62fef13),LL(0xe9e24f3a,0x3d1cf9e1),LL(0xd96cf621,0xf503d4fc),LL(0x0e1204b1,0xf07e39bb),LL(0x71958180,0x7a406c60),LL(0x3b7b9a61,0x304ca46d),L_(0x00000095), LL(0xcdb43a8c,0xf37f3857),LL(0xed377a92,0x8ae49b6b),LL(0x0827d789,0xbd50e338),LL(0xdeff6865,0xfdb287e2),LL(0xe758e466,0xa0c560a0),LL(0x54321f3b,0xb418a264),LL(0xd44767fd,0xfaaa26f5),LL(0xcc7b7f8b,0x59390d36),L_(0x0000006b), +}, +/* digit=14 base_pwr=2^70 */ +{ + LL(0x580dde02,0x814d149b),LL(0xeaa3b1ca,0x3cc8c599),LL(0x43a45440,0xc98d833d),LL(0xdba29de3,0x6e31f2af),LL(0xab2ff205,0xf81e95cb),LL(0xb530ab3b,0x49419f19),LL(0x8a6e1bb6,0xd0585b64),LL(0x1dfbba1e,0xd49f7ff1),L_(0x000001e2), LL(0x2b473469,0xc0250d4a),LL(0xb9f4e199,0xd4759758),LL(0x326d4e2a,0xc32f68bc),LL(0xa78113ab,0x840b01ce),LL(0xcd248f92,0xbd87644a),LL(0xa8d8d61e,0xe9a32d38),LL(0x58a69c2a,0x6a0c706b),LL(0xf4b942e1,0x8c19f561),L_(0x000000d7), + LL(0x538c7fcc,0xff198eec),LL(0x4ec043bd,0x29ee8af8),LL(0x125b846f,0xd01572ea),LL(0x280cfc9e,0x4ba80325),LL(0x3f73f265,0x57e3b7be),LL(0x6bcaffbf,0xf83701a2),LL(0x1a2d3724,0x19d20a25),LL(0x410f80b3,0x50b7f3ec),L_(0x00000161), LL(0x3b961197,0xc136f93b),LL(0xc26463d8,0x000ba8d6),LL(0x8d99824e,0x0e084f84),LL(0xcfbb42b2,0x81fef33f),LL(0x138715f7,0x48ed1078),LL(0xca7dbdd0,0x42869724),LL(0x3c66b900,0xcfde2c20),LL(0x89fab2c4,0x1ca32904),L_(0x000001b8), + LL(0xaf4c0100,0xca7c1c9b),LL(0xd05a1cfa,0x096b7d5f),LL(0x5e939f07,0xc34c35b1),LL(0x11a408f8,0xef94d03f),LL(0x9c1a3053,0xa610576b),LL(0x89fbfdb7,0xce4bec40),LL(0xabf93595,0x66023f5e),LL(0xc5d43f87,0x958d40aa),L_(0x000001ef), LL(0xa58413e1,0xcbfb3671),LL(0x1874038a,0xd3ca207c),LL(0xb2e8a04a,0xccca2442),LL(0x3073c925,0x3c9baa99),LL(0x554b9664,0x6d9e1787),LL(0x70e99ee9,0x874df9a7),LL(0x312bf341,0x1b8e89dd),LL(0xfdf17994,0x5caa8ba7),L_(0x0000005e), + LL(0x5838bb0c,0xad2e37a1),LL(0x5a28cd2c,0x54d33ad6),LL(0xd4f1caa9,0x44b04b20),LL(0x80e4c9d2,0x8c65ceb1),LL(0x370a13f5,0xecff016c),LL(0xee758816,0x6ad260ae),LL(0x95c36fe1,0xbbdbb7b5),LL(0x4d06dfe8,0x48d94294),L_(0x000000f5), LL(0xf5c325d6,0x955c2a22),LL(0x79a376a5,0x16640925),LL(0xf8e9390b,0x36b3aac4),LL(0x2a8dbf22,0x034f2b72),LL(0x77b02d94,0xd5de86b9),LL(0x729cfcd8,0xa8bc9f80),LL(0xbe296bcf,0x1dbcbc03),LL(0xec1469f1,0x73243364),L_(0x000000f0), + LL(0x4141a618,0xa7081b57),LL(0x51abc1ef,0x738c30ac),LL(0xb0cb69e4,0x731cd9ef),LL(0x9b0b0c3b,0xf0dc5cc9),LL(0x40e54a92,0xfba2bbb5),LL(0x0dee7871,0x5ee7b5d3),LL(0x540e5eaf,0xad1a2eba),LL(0x7c44af5d,0xafd14dda),L_(0x000000d4), LL(0x451af808,0x1bf41212),LL(0xacac98b3,0xd6076452),LL(0xed40fc8f,0x868d93c4),LL(0xb7246c52,0xab7c14c6),LL(0x36bab138,0x789fa296),LL(0x330e1a06,0x88e8110a),LL(0x5dbf4ce1,0xff782421),LL(0x9cabebe8,0xa4afa38f),L_(0x00000046), + LL(0xbf3ef154,0x0cb92f46),LL(0x47026a02,0xe21fd797),LL(0x1dec53c2,0x0b5a2b41),LL(0xcfbf686e,0xdb7c6dc9),LL(0xd6d5c0b4,0xb4a8866b),LL(0xf8283374,0x14d9e7f9),LL(0x4dd48282,0xffba2822),LL(0xf9de17db,0x48083494),L_(0x00000075), LL(0x1814c604,0xbe3bf885),LL(0x12bae7dc,0xdf04c3eb),LL(0xe8ee1061,0xc658c3bb),LL(0x8d34f043,0x47642843),LL(0x2916bbb3,0xedee7c23),LL(0x70f93acd,0xc93b4f5c),LL(0x187bf7ea,0x75348b4d),LL(0xffda6e9d,0x9cb29eeb),L_(0x00000033), + LL(0xc855134e,0xdd4ae89b),LL(0x30b7a1ad,0xd9dc0b8c),LL(0xbee0416e,0x67e1dcbc),LL(0x66147ae2,0x7907e5e7),LL(0xb9dea373,0x537d932f),LL(0xf4450461,0x8d5aa671),LL(0x7b0644e6,0x33269776),LL(0x835848af,0x93b63489),L_(0x00000138), LL(0xfdca2fb9,0x400c0893),LL(0xe36e56e3,0x095f6119),LL(0xaaeab6ef,0x07fda371),LL(0xfdbbf61e,0x51034096),LL(0x65d823d3,0xc5284f49),LL(0xcec7f701,0x00cca32d),LL(0x443cce6e,0x13b673ca),LL(0x7c7c1332,0x75e93750),L_(0x000001f7), + LL(0x5f48e2fc,0xfafcc610),LL(0x2c5d9495,0xd34073fc),LL(0x321d1a08,0x30442510),LL(0x3427742e,0x8068ffd8),LL(0x2ec5f97b,0xa7faa8a5),LL(0xac14530d,0x5d010e52),LL(0xf277a140,0x3edf5701),LL(0xcdd53228,0x07eb00ea),L_(0x00000155), LL(0xf8f566cb,0x51771845),LL(0xa7b0e50c,0x66aafeee),LL(0x81cf4ee6,0x8fd52580),LL(0x1bc2c6ec,0x232a19c7),LL(0x6790d250,0xd4c06ab2),LL(0xdc4411be,0xacd06e0b),LL(0xe0fd2a20,0x19734273),LL(0xc9fb738a,0xe5b5e5c1),L_(0x00000162), + LL(0x2c36a49c,0x346bc599),LL(0xb17c0c24,0x4349ec6d),LL(0x1994a52e,0xc574a60f),LL(0x479b18ee,0x2cf1156f),LL(0x00b04364,0x587d6a8b),LL(0xe20999e4,0xb840bbc5),LL(0xdfbaad24,0x1056fcbe),LL(0xb84e8539,0x211c4015),L_(0x0000009b), LL(0x34b3807b,0xc83300dc),LL(0xcbae472d,0xff64a1e1),LL(0x60ef1e86,0x1368c7ee),LL(0xfa9cecf9,0x1a548595),LL(0x12c62bf5,0xbab6253e),LL(0xc9541d0a,0x2d9ef7be),LL(0x1e1f27f7,0x956cff19),LL(0xba2813eb,0x5c29eeaf),L_(0x00000030), + LL(0xdb558004,0xce8d95f8),LL(0x9dc5e59e,0xf1893cb5),LL(0xa7cb9fd4,0x77041349),LL(0x53461897,0xb8f3b00e),LL(0x4b8c1719,0x3acc8d5e),LL(0xe436769f,0x2b51a3ea),LL(0x15adc570,0x5fa4c1f5),LL(0x93a4046f,0x70b3a881),L_(0x000000f5), LL(0xc6ca2c5f,0x8e92a20f),LL(0xe70ae728,0x9e74b9b9),LL(0x6d7cbd1a,0x8837144f),LL(0x797825f3,0xa10a4e2b),LL(0xd3f2260a,0xbce98f37),LL(0x3d85debd,0x39cb6f79),LL(0xa763a30e,0xb1f85a09),LL(0x15a4a3f3,0xb462b7b8),L_(0x000000c0), + LL(0x4df25f56,0xf82561fb),LL(0x9e75f649,0x8c808470),LL(0xd7751a0f,0x0c1dcee3),LL(0x4322644e,0xf53e90ce),LL(0xd68db21e,0x8f8d9278),LL(0x72d07c10,0x94db3061),LL(0x821b176c,0x2c56677c),LL(0x51fa088e,0xabb0b5b6),L_(0x00000172), LL(0xbd496ef4,0x2f3203c7),LL(0x702f0af9,0xf4ee87af),LL(0xdeead7f4,0x1e240ba2),LL(0x6ba4a666,0x45c6b9bc),LL(0x5b558a22,0x69826d07),LL(0x82f16b78,0x1d474e7f),LL(0x1b099f67,0x6f9ab8f0),LL(0x79936b07,0xb7da7cd3),L_(0x00000140), + LL(0xdcb6ef22,0x8cd18dc5),LL(0x4111e26b,0x563a07bc),LL(0x3482455e,0x0e2f7391),LL(0xcb5ec4ad,0x21483bed),LL(0xc0caacaf,0xa5a48441),LL(0xc9e80f16,0xbffbf280),LL(0x90242b85,0x91f37a76),LL(0xd9544186,0x2dcd22ee),L_(0x00000157), LL(0xa766d6e3,0xfc4b8794),LL(0x38293f47,0xa81360ec),LL(0x31e9f867,0xbe34d77d),LL(0xdb92af31,0x882df842),LL(0xcd799976,0xd34a906c),LL(0xabb505dd,0x961ddfb3),LL(0xa3a37b0b,0x4fbbb326),LL(0xf7af85a7,0x508f35d4),L_(0x00000028), + LL(0xbb0940d9,0x3d70435a),LL(0xff491b63,0x1eb2a685),LL(0x22d3c808,0xa380de6e),LL(0x17e44c8f,0xd9df636d),LL(0x2a35379f,0xa903bf9f),LL(0x0f809249,0x387b8a0a),LL(0xabe12175,0x44dbe0cd),LL(0xfd759d00,0xcccc9723),L_(0x0000003c), LL(0x98196ddd,0x019c1122),LL(0x84c5a37e,0x254adbe9),LL(0x3981a4ac,0xbfc928a2),LL(0x62436eb9,0x7ad29c64),LL(0xc99f2914,0x2cc9ceca),LL(0x2f0c2529,0x2d8109c3),LL(0xbda5dcc9,0xe65ae3c9),LL(0x27c8461f,0x2300f14c),L_(0x00000101), + LL(0x7f2f4a50,0xdb205fa6),LL(0x977d6dff,0xb6a346a4),LL(0x39b1aa2b,0xc02f5c26),LL(0x6d520bed,0x7e9b3df6),LL(0x9fe2d1ad,0x8060eb41),LL(0xffe8b3d8,0x8de43158),LL(0x6b78c0bc,0xe900b6ef),LL(0xba5607f9,0xe9657827),L_(0x000001ae), LL(0x656a0930,0xe37eeb37),LL(0xf82e5547,0x817b9a2b),LL(0xebe57826,0x966c6b06),LL(0xd17239c5,0x0d566764),LL(0xb6e7e211,0xb736c18d),LL(0x67f60fe4,0x7f6de467),LL(0x91c330d3,0xdf003076),LL(0x6fe1ff1d,0xf3ffae38),L_(0x00000032), + LL(0xa38e4c83,0xee75b3b5),LL(0x42633219,0x96b76b44),LL(0xa702e22d,0xce624bec),LL(0x45df636e,0x087dc34c),LL(0x00b8ab39,0x7c3b41a0),LL(0xa4c92149,0xbe1f412c),LL(0xc186c0a7,0xa0e6b72f),LL(0x6f9b9c73,0x909b955c),L_(0x000001a3), LL(0x6d958194,0xfceeca76),LL(0xc25f90a1,0xd246f978),LL(0xf7a79529,0x5bdce3f4),LL(0x202fdba0,0x4516ada4),LL(0x9ccb5769,0x22fea769),LL(0x35cd1aca,0x9d5e791d),LL(0x72d93ad7,0x89481217),LL(0xd00224e0,0xdc53ffd6),L_(0x000000b6), + LL(0x0b6d183b,0xcdd1f50d),LL(0x88770143,0x721cf9d0),LL(0xd247118a,0x5a8338fa),LL(0xfa498ee5,0x33ff454e),LL(0xa8d98087,0x2107a954),LL(0x4eaefaa7,0x39298606),LL(0xc385af5a,0x3e0c503b),LL(0xfc7e0cec,0x37f8795c),L_(0x00000096), LL(0xa2f6c113,0xbf161ebf),LL(0x48b5f685,0xbb087e9c),LL(0x58eb481e,0x3b7987c9),LL(0xa465a54c,0x6e92e01e),LL(0xa8194344,0x1e66d88b),LL(0xb0c7a894,0x40dc6c71),LL(0x690cafad,0x057f59a3),LL(0xf02679ac,0x4a12e130),L_(0x0000007d), +}, +/* digit=15 base_pwr=2^75 */ +{ + LL(0x3a007995,0x19e3233b),LL(0xcd545767,0xc78c2194),LL(0xc744ff86,0x789e51d3),LL(0xafacd6dd,0x7a5cd253),LL(0x398cb1ba,0x18b56085),LL(0x273c4fb9,0xff1bce38),LL(0x0ba240c9,0xbca7efa9),LL(0x3bb2e372,0x05ab8ba7),L_(0x0000012d), LL(0x563a114b,0xf4adbd1d),LL(0x90284d2d,0xe9ad940e),LL(0xe3af63ef,0x61ffca7f),LL(0x96feaa4e,0xba0669de),LL(0xdbf94ff4,0xd7b8471a),LL(0x696c5279,0x1dda976e),LL(0x0a229117,0x1566b880),LL(0xba44b588,0x7a731f5f),L_(0x0000006a), + LL(0x29b896b5,0x025efc3b),LL(0x60e34ccb,0xbcd9f85c),LL(0xae29c1d9,0x1e85f821),LL(0x3dcc6356,0x27219e29),LL(0x3f95824c,0x9e01039f),LL(0xd3a9843c,0x8ef0f79f),LL(0xbba44b84,0x9cddb5a3),LL(0xf0a7f537,0xe6239011),L_(0x00000062), LL(0xd40be315,0x0d73669d),LL(0x0706daaa,0x90c605d6),LL(0x262a826a,0x2e67d62f),LL(0x90997b0e,0x5ac29c5e),LL(0xa4dc7322,0x9728fe4c),LL(0x46c28be3,0x8656b7a7),LL(0xcf46a3d3,0x318bd5a3),LL(0x0c58ac70,0xbdba780a),L_(0x0000012f), + LL(0xd012d32d,0xb1701460),LL(0x36257f7f,0x712c0989),LL(0xbc1511ff,0x948635e7),LL(0x929c254b,0x950b6b9e),LL(0x88fae008,0xc1ebc649),LL(0xb35e21c2,0x69de590b),LL(0x0c8fd948,0xc534704d),LL(0x03df94d1,0xc72f229f),L_(0x00000191), LL(0x417e1367,0xbe538962),LL(0xbaa7a81a,0x6d9ba3b4),LL(0x085df8a2,0x72446606),LL(0xc1a4f077,0x313aa0fe),LL(0x443486a7,0x310facd1),LL(0x4bb29bc8,0xe7424659),LL(0x70dbb24c,0x7a208944),LL(0x2ddd11bb,0x4190996b),L_(0x000000fa), + LL(0x5370e2b4,0xa39d68ac),LL(0x0b26e23e,0xf98a9904),LL(0xbe557ba1,0xcef362a9),LL(0x202765cc,0xa7731e3c),LL(0xa726d7b5,0xcd815e2b),LL(0x1c25faf8,0xa6579cd9),LL(0xdafb2e8b,0xc5ec8fb3),LL(0x648049fa,0xd9a36af4),L_(0x000001d2), LL(0xa04b6251,0x96110b89),LL(0xd1ddccb2,0x551f88c9),LL(0x0f26d015,0x9b8bbb0b),LL(0xb5bd39d3,0x9d52ffc2),LL(0x2dc18ef7,0xab6d006e),LL(0x142fb527,0x804f61d0),LL(0x391511fa,0x9dbe5992),LL(0xa3e717ea,0x408dd815),L_(0x0000008a), + LL(0x9289c640,0x6b7a800c),LL(0xc76b2795,0x581d42f0),LL(0x8ca1e81a,0x4472a2fa),LL(0xbf4b6019,0x6715dfdd),LL(0xb304a936,0xf9366e36),LL(0x391be48c,0x81f74b90),LL(0x6151e36b,0xd32b6b20),LL(0xc48b79a5,0x9a91aea9),L_(0x00000183), LL(0x831e89ed,0xfa6f04fa),LL(0x5ebcfa5b,0xec4ecc3d),LL(0x6b2117a0,0x7b376a81),LL(0x90bf1080,0xba3f0166),LL(0x0993a607,0xaf14e2f1),LL(0x8cf72c90,0xef21c633),LL(0xd173a6d3,0x187451c2),LL(0x13ec5f08,0xdd8ab011),L_(0x0000006c), + LL(0x0f29eadd,0x246b16c2),LL(0x9b833212,0x9da31a63),LL(0x297cf150,0x4995a63d),LL(0x90a2a3a8,0x26054531),LL(0x22ca8af6,0x0cdf918d),LL(0x62531849,0xa5ed4b64),LL(0x7ca9de65,0xfa4fec38),LL(0x72b35acf,0xa666610b),L_(0x0000018a), LL(0xf96d539b,0x221e3646),LL(0x256f3a4b,0xb6bf83af),LL(0xc408a90f,0x7abd62f0),LL(0xaefff14a,0x4069cdfd),LL(0xae41ce0c,0x29824953),LL(0xb47d1cba,0xa382ab7e),LL(0x9eb440b7,0x957f6459),LL(0x4c148b60,0xaf1d974a),L_(0x00000047), + LL(0x1086c5f8,0x26130fe0),LL(0x7b4b2e70,0x68d46ff5),LL(0x0c407c0a,0x3b8c39a0),LL(0x88577dcf,0x6dc35106),LL(0x5dafbff6,0x66c847b2),LL(0x2d675f1f,0x17ebe229),LL(0x834c9c2b,0x7dd924e2),LL(0xd5b6edf6,0x0a03148b),L_(0x000000d6), LL(0xf96321d7,0x6f67acfa),LL(0x9437a2b2,0xf66029f2),LL(0xe7b46c71,0x329167d4),LL(0xb24e796b,0xcf0f34c3),LL(0x9d6e95b5,0x4f9e7abb),LL(0xcb817cb5,0xb5258968),LL(0xe5382677,0xb89d3951),LL(0xb2e2fb7f,0xd0f6ea08),L_(0x000000c4), + LL(0xe65a160c,0x79edff6b),LL(0x1ae3af0e,0x7704970c),LL(0x8b957c42,0xb8aa395f),LL(0x5f0f181e,0xbdf3d6c8),LL(0xe7d8f529,0x4e626c58),LL(0xd83fd353,0x770dabfa),LL(0xe5ada98c,0xac3e65d7),LL(0x6430730b,0x954e2567),L_(0x0000010b), LL(0x09d0476d,0x4dcf97c3),LL(0xab9b5d71,0xa56a3252),LL(0x9648c08c,0xff297fc7),LL(0x897ba609,0xff84306b),LL(0x4c446a06,0xddb64374),LL(0xbc202d01,0x97ee1218),LL(0xf9b0f80f,0xf048db33),LL(0xb5f54bb8,0xf9d935e8),L_(0x000000e7), + LL(0xa010dba8,0xa2fb38a6),LL(0x31feab78,0x36899fbf),LL(0xacceb7c2,0x5bdd898c),LL(0x14de8e04,0xe42d5076),LL(0x459ea861,0xe51c21c6),LL(0xfbda1b0c,0xdc95445c),LL(0xa7d4e38e,0x7947f71f),LL(0xadcd66a5,0x2c40ef60),L_(0x00000199), LL(0xdcdf5f99,0xf1467b2f),LL(0x2de2bfcc,0x9c1ae772),LL(0xd43f04fe,0x41471183),LL(0x043333f6,0xc9a3cf00),LL(0xf1a6e8cb,0x7cc8a0c7),LL(0xa8c3f924,0x74a1cf04),LL(0x828052df,0x8be5596b),LL(0x50a45820,0xd5384c0f),L_(0x00000198), + LL(0xe9851bfc,0x51c40077),LL(0xbfe0982b,0x87cd565d),LL(0xd372a1cb,0xccd954bd),LL(0xbbff7b4d,0x294b36f6),LL(0x8237c51d,0x4ce0f879),LL(0x261403d6,0x569d6e3c),LL(0xb79e0e60,0xeba6224f),LL(0xc33dd3b5,0x701a34d7),L_(0x000001f7), LL(0xaaf054ad,0x5f93dace),LL(0x160bbbee,0x8aa260aa),LL(0xa9f4b722,0xb1b5025d),LL(0x817d1e67,0x81308a04),LL(0xfe002797,0x4afd2f00),LL(0x680cc208,0x154f68e6),LL(0xd4b7eccc,0x4cc6b0f1),LL(0xb8976118,0x39f42fe2),L_(0x000000b5), + LL(0x7283e8a9,0x8ab94a45),LL(0x0bb733f0,0x642a6645),LL(0x41a534e8,0x57ae42c1),LL(0xd4abc981,0x8be6ea3e),LL(0x7e62f50a,0xb3f01b7e),LL(0x98a38cc8,0x8865f98b),LL(0x7862605c,0xf1a738cf),LL(0xde02b3ce,0x7cbcb60e),L_(0x00000191), LL(0xbb74e488,0xc6aa6ad4),LL(0xf6d314f3,0x1691860c),LL(0x97214287,0x625fd28f),LL(0xab878ce4,0xd6ea61fb),LL(0x8ebed709,0x5a22486f),LL(0x6db8fc6f,0x0b71449e),LL(0x46c06119,0x0e8cd622),LL(0xe44026c8,0x2b868bc7),L_(0x0000017c), + LL(0xab7fbeff,0x954c6cef),LL(0x7291b35c,0x062277d6),LL(0x7553137c,0xaf482063),LL(0xb75730d8,0x710c68e8),LL(0xb68d2250,0xbae3e7c1),LL(0xff637a2f,0x6b643e1a),LL(0x1ef002bf,0xdcdc4699),LL(0x38ab4582,0x3d4d096e),L_(0x00000057), LL(0x92bea0d8,0x899ee626),LL(0x4d7631d6,0xcdd2a79a),LL(0x2ee3aea9,0x8162f50f),LL(0x1476eea0,0xc4d433fb),LL(0x27c81475,0xe8214237),LL(0xdc969d9f,0x56c76934),LL(0x6d918c87,0x7533eb08),LL(0x56d2a891,0x6eb1be30),L_(0x0000001e), + LL(0x1b47da4b,0x8a8331e9),LL(0x49ed1362,0x59fa2b27),LL(0x418a7189,0xe8454c56),LL(0xf46859d8,0xb777077d),LL(0xdf895326,0xa1ecfc76),LL(0x7c0bff3a,0xa0d40120),LL(0x4dc72f6f,0x863ee5b0),LL(0x6d7d35d2,0xf072a9db),L_(0x0000015b), LL(0x51536aa9,0x797cc189),LL(0x992a786b,0x424d6c36),LL(0x0bb1db2f,0x7b4a72f0),LL(0x99596f48,0xd38d470a),LL(0x7d9d8119,0xed3220cb),LL(0x7fe52443,0xd0f7efd8),LL(0xf334c76a,0x5b52a8c0),LL(0x289cf254,0x9c518382),L_(0x00000178), + LL(0x50ef0de9,0x06fa762c),LL(0xf226f768,0x770bcaf6),LL(0x47cff6b0,0xec1a0d3e),LL(0xb780ef8c,0x49872a4e),LL(0x434df874,0x82a505c8),LL(0xfc298963,0x6b56a94d),LL(0xc037f2d4,0x1721c7a5),LL(0xef98ff94,0xdf6aa659),L_(0x00000092), LL(0xce001c93,0x229e4010),LL(0xb7710f4a,0xb1be023a),LL(0x4f780b68,0x37373fb4),LL(0x44ddc611,0xb6129029),LL(0xeba09ab8,0x3d4bb157),LL(0x52d1be00,0x7557730f),LL(0x5d184bff,0x79506c27),LL(0xabea8b49,0x120e5c57),L_(0x000000a5), + LL(0x475e54a3,0xe76ea216),LL(0x641b111e,0xe7b2f367),LL(0x11e8b8cf,0xaa1845af),LL(0x3e44ec0e,0x634d35d6),LL(0xd9e05b86,0x9fef6a5e),LL(0xa66acc79,0x6151a902),LL(0xc7fadad6,0x95ee0cab),LL(0x4f71151e,0x5844d0c7),L_(0x000000b3), LL(0xc47ffd5b,0xd5a7577a),LL(0xa66a5bd1,0x1bbdd68c),LL(0x1a4070bb,0xafa4a6f8),LL(0xb0f9b28c,0x67075086),LL(0x966afc2e,0x63512dbd),LL(0xed5912ae,0x8f26597d),LL(0xd092a281,0xa415f451),LL(0xc2ef31e4,0x0ffffc3e),L_(0x00000147), + LL(0x4e004498,0xbea3c389),LL(0xaa39f9d0,0xa8f46458),LL(0x0b3654a0,0xf830008b),LL(0x4cd7392b,0xa46a22ca),LL(0xb12eb97a,0x80e1d7af),LL(0xd888b9cb,0xf74c8adc),LL(0xbb6e179c,0x73b51d04),LL(0x968eb224,0xb5490b50),L_(0x000001f5), LL(0x51f96d03,0x9de9e100),LL(0xfade3749,0xecddcd4f),LL(0xfc72771e,0x7aa9dbdf),LL(0x5e1bb964,0xdc24156b),LL(0xbaddb508,0x0de78eea),LL(0x6facddf4,0xb1c48894),LL(0x4a964d6a,0x49c82382),LL(0x6f258c87,0x62eac3b1),L_(0x000001b0), +}, +/* digit=16 base_pwr=2^80 */ +{ + LL(0x32cc508d,0xcd408945),LL(0x60b1057f,0xf3eb54e9),LL(0x77d231ff,0xbd6ea408),LL(0xe5110313,0xb9ee8343),LL(0x85209f6e,0x64924e77),LL(0xe7fa5897,0x32e258b2),LL(0x618a6eb3,0x11e2e038),LL(0x96067c35,0xf4c23aaf),L_(0x000000a7), LL(0x0f221560,0xef974e44),LL(0xa1b7a3a0,0x8ea1f931),LL(0x72932b48,0x720e4174),LL(0xbb75d745,0x1bf9c803),LL(0x996758e5,0x7f0b3909),LL(0x8d83f97c,0x39d56a48),LL(0x1fac932b,0x55fe1ded),LL(0xaaf43ccf,0x91fe8399),L_(0x0000002b), + LL(0x6ffb7834,0xad3e7387),LL(0xd3158a49,0x8771e37a),LL(0xb98ec469,0x6f103f2c),LL(0x1bd53110,0xf8325af3),LL(0xa434959f,0xe47f875b),LL(0xa10264ee,0xcf224bc0),LL(0x9ccf2f61,0x337d33a1),LL(0x86ce6031,0xe6ee9f21),L_(0x0000009e), LL(0x6706e91f,0x9179c5ea),LL(0x79ba3023,0x9aa4ed38),LL(0x7e239f26,0xaa83eb97),LL(0xef091443,0x82853a90),LL(0x336fc4d2,0x2b260d34),LL(0x56b3a0bb,0x119fbd07),LL(0xe0f16198,0x3453a3a6),LL(0xa2af0802,0xd2ee6016),L_(0x00000050), + LL(0x8000185b,0x02ebe1f2),LL(0x3ebcda00,0x30d3e5f2),LL(0x75cccaba,0x8ea9d40f),LL(0x108edd48,0x152a6563),LL(0x6028024e,0x732e422c),LL(0x17618296,0x142e6cc1),LL(0x9dea7266,0x5d4e4488),LL(0xb05325e9,0xf99254d1),L_(0x000001a3), LL(0xf3270a2e,0xc29b5dca),LL(0xbad984d9,0xd2f759d7),LL(0xad7bc046,0x347ff7c2),LL(0xa4e4f59d,0xc16d4c0f),LL(0x0a06be29,0x872d14ff),LL(0x2390bb31,0xb7a5b6ec),LL(0x66be2ce2,0x408ae4cc),LL(0x6b9b1fe0,0xc70e0700),L_(0x00000080), + LL(0x9cc4cee5,0xa99628d5),LL(0x4764e916,0x4417813a),LL(0x9a05da16,0xe423f0c4),LL(0x2babb644,0x24dca899),LL(0xd179a66e,0x894f6883),LL(0xc157cbef,0xed7756c7),LL(0x44c30131,0xcdff08e1),LL(0x78b0a3e9,0xf5fa08ac),L_(0x00000059), LL(0x43dabd75,0xbe7ba3ec),LL(0x93626426,0xd17b8f8b),LL(0xbfcd2a78,0x486d7ac0),LL(0xaeda53c9,0xfc3c49c2),LL(0xbc99eeae,0x49fb4a9c),LL(0x12ab3d09,0xdb075628),LL(0xc0f863b5,0x3d5da4c6),LL(0x8ec31fe4,0xc774d9e0),L_(0x00000072), + LL(0x098d00b0,0x4acb7a91),LL(0xf4f8175f,0xfe317cf8),LL(0xf8155d16,0x2bc9a77c),LL(0xac3ddeef,0x17520bd7),LL(0x0aeae3c4,0x44ee6fbc),LL(0x1aaae6ff,0xd8c23852),LL(0xf47bc828,0x553f42c9),LL(0xc09b26d0,0xb04bad2f),L_(0x000001e8), LL(0x9a32ac7c,0xc1e669bb),LL(0xc8aca498,0x697322f4),LL(0x43042d46,0x334625a5),LL(0xdf16aa69,0x67bda03c),LL(0xab4b67c2,0x205d341f),LL(0x83a55d6f,0x05daa2bd),LL(0xcdfd94e0,0x9ac9573f),LL(0x1cb76afe,0x2fdad4e8),L_(0x000000d1), + LL(0xf074fced,0x97863b91),LL(0xc43281c9,0x92d449a3),LL(0x7a68c2d7,0x063c9119),LL(0x3b2de0b3,0x55e1666a),LL(0xf3e7d825,0xf70b4227),LL(0x6aacf427,0x6c04e18d),LL(0xc2b9b616,0xaa4c82c2),LL(0x376fa210,0x3261f95a),L_(0x000001ca), LL(0x27de0f4a,0x63844f17),LL(0x70941232,0xfd0bec77),LL(0x3b5f4e85,0x68fe79f4),LL(0x5cbc9a57,0x826a7303),LL(0x65bb2328,0xda7d2209),LL(0x40788a77,0x6978fe42),LL(0x14c7cf99,0xc2ae1a05),LL(0x77943ce3,0x53eab85e),L_(0x00000074), + LL(0xdb0d1b45,0x25e9937f),LL(0x14c566a9,0xd1cf3988),LL(0xcd250848,0xcc300694),LL(0xbfd82b6c,0x135bc75f),LL(0xa47db4ae,0x8639e63f),LL(0x2295c1f1,0x30a5e5b3),LL(0x61f91b27,0x2841bb1c),LL(0x1335383b,0x5f90a945),L_(0x00000129), LL(0xe1df27e3,0x0fb695c7),LL(0x721a9ee4,0xc8c313d1),LL(0x267e9801,0xb288bc93),LL(0x9aafbe12,0x80d7a36a),LL(0x5e34c2b1,0x5e8b79ae),LL(0x22efe6b6,0x7da7f03b),LL(0x552e9134,0xee94e563),LL(0xab16538c,0xb9465f4a),L_(0x000001e5), + LL(0x336db42e,0x49f7546b),LL(0xf6900421,0x57093c06),LL(0x8e00d7d3,0x8d2dbce8),LL(0xd9ede742,0xd004dc4a),LL(0x01940521,0x0d3be2ce),LL(0xdc4ae497,0x1bb5cf60),LL(0x0a6ccb03,0x803df567),LL(0xdf04605d,0xa1f5bb64),L_(0x0000013c), LL(0xa05f0fb0,0x1f8ad28a),LL(0x39d0a695,0xe5b908dd),LL(0xd67e92ff,0x4165f76f),LL(0xf281077f,0xc8d52980),LL(0xc9ee2db2,0x9ff0b841),LL(0xe792e9a0,0x9a5850f2),LL(0xd74d1fff,0xdbe9887c),LL(0x468c4978,0xb14ef9aa),L_(0x0000018f), + LL(0x17cfe85b,0x645a5369),LL(0x96452c88,0xfe80ed90),LL(0xd777343c,0x53d07352),LL(0x57827fb3,0xa6c3e43b),LL(0x80b39b9b,0x2a8365b0),LL(0xaf5a3de0,0xac5e9239),LL(0x181d4337,0xea4d87d6),LL(0x51fe7247,0x91c5ece4),L_(0x00000037), LL(0x0dfb5a0c,0x7a7e75fb),LL(0x15428231,0x5c94ba5c),LL(0xdf444166,0xc521d0ff),LL(0x0f639c5d,0x74de2e37),LL(0xdc1e397f,0xc9356e9e),LL(0x93e3e959,0x0c9e3464),LL(0x39201886,0x6a78ad71),LL(0x2c0f3246,0x857cb413),L_(0x000001f9), + LL(0x9207f1ee,0xc358b92f),LL(0xcc5ec219,0x085c3194),LL(0x8df4ef1a,0x71e157f1),LL(0xb527e0ab,0xdd0a2a0d),LL(0xae481b48,0x0e0efe51),LL(0x27b717b7,0x5828b573),LL(0xc2a98225,0x3d2c0ff1),LL(0x099e23ff,0x7269417e),L_(0x00000083), LL(0xf9a97523,0x11db2059),LL(0x5fbc6f68,0x162229b6),LL(0x08c87928,0xc7000da2),LL(0xa03b55dc,0x3f37b2b0),LL(0x03e27759,0x2abf57b8),LL(0x6d3e3a66,0x3d925762),LL(0xa5335174,0xec43569d),LL(0xb9e4cda0,0xe4522ca8),L_(0x000000f8), + LL(0x991bdfe4,0x46da618a),LL(0x0642fbf7,0x2827ab9a),LL(0xcb3c80d7,0xa4c02a4a),LL(0x24ffe39b,0xdd1a385c),LL(0x81fb1f95,0x4fe48911),LL(0x7ed78cb0,0x42514e36),LL(0x12838990,0x2822adf0),LL(0xcd6245c9,0x17e195af),L_(0x00000018), LL(0x682326f4,0xeadeab18),LL(0xa6714b92,0x8194d4d8),LL(0xec34ca02,0xaf1a5a6c),LL(0x18aa0b61,0x21f3603a),LL(0xd56cb67c,0x9e65c6ef),LL(0x64df4053,0x9af9ff17),LL(0x6e1b769a,0x333abb94),LL(0xd74c3bd6,0xb764bf57),L_(0x00000185), + LL(0x6b395c0b,0xb5b87b52),LL(0x48432467,0x7efdcd9b),LL(0x9d4e858e,0x7c0c8922),LL(0x30d29dcc,0xd7b3a015),LL(0xe0639cac,0x02eb2112),LL(0xa2a88900,0x99cb32dd),LL(0x5ee2bf55,0xe98b88fa),LL(0xa3323b39,0x9b1c4ab7),L_(0x000001c6), LL(0xe5c08a49,0x2cf028a4),LL(0xf8ca8809,0x62209ac3),LL(0xfaac3cb2,0x91bff5ca),LL(0x2cd5c8b2,0x2f2a80df),LL(0x2244abea,0xd2c4cfb9),LL(0x1181848d,0x345b1ca4),LL(0xc35b7b60,0x3093dc03),LL(0x815a0c2b,0xccdd0f34),L_(0x000000a3), + LL(0x3f060a04,0xc9440b7b),LL(0xf892eb31,0x8c0aafa8),LL(0xc25c561f,0xebcb8c35),LL(0x12770520,0xe63e94d2),LL(0x6d5c16b3,0x1c828d52),LL(0x9bde42a4,0xcafff93a),LL(0x2b7abe51,0xc4851b92),LL(0xa9fcd2b9,0x41227e00),L_(0x0000009b), LL(0x24e44af4,0xebda81a0),LL(0xa695bf6c,0xdee85d40),LL(0x76c43176,0xf9ff0671),LL(0x8106e3cf,0x7e8060f0),LL(0x4ce1b2a1,0xa7e23360),LL(0x81d1ed8c,0xbfa62d39),LL(0x47f7b51a,0x4292ca9e),LL(0x9139a437,0x60e7fdba),L_(0x000000ae), + LL(0xa65d9111,0xb4e47850),LL(0x4221510a,0x7528def6),LL(0xeca10d8d,0x12fd7625),LL(0x4560fa05,0x7883ec3b),LL(0x5c64949f,0x2a961e63),LL(0x4df0271f,0x4eacd5e7),LL(0x9af4d45b,0x62f25ceb),LL(0x9ab3bb2a,0x7ef167e5),L_(0x000001f5), LL(0x92cdd0ea,0x6860d474),LL(0xae51b5ad,0xc69002e2),LL(0xccd9fe59,0xe138bd08),LL(0x00304cd8,0x9ec62f95),LL(0x329feb5b,0x0928d5e4),LL(0x8a27990e,0x6d9656bc),LL(0x0f0e6792,0xb7989c9a),LL(0x3f1c862c,0x1bbbc30e),L_(0x00000033), + LL(0xa5a66086,0xf622c1ac),LL(0x7ccf9bc1,0x3beaf465),LL(0xa68726c3,0x900cd78d),LL(0x2a903911,0x2be1c512),LL(0x8832203c,0xa8466703),LL(0xbf042dcb,0x1301ba91),LL(0xa8235209,0xfc06ed9e),LL(0xe1aef50a,0x04f3d4d5),L_(0x00000138), LL(0x47a0b87c,0x55a0038d),LL(0x9826631d,0x6ef49646),LL(0xe8d54ad8,0x53644562),LL(0xa200feff,0x773835a0),LL(0x5c4408b1,0xb6c0a0e2),LL(0x3199aac7,0x2d23ae2f),LL(0x4f2c5a36,0xdfbd8171),LL(0xccacb296,0xa7505cc8),L_(0x000001e2), + LL(0xcf45bc39,0xbca99c74),LL(0x16aa0dee,0xae132b38),LL(0xb713a9d8,0xf8d3fb57),LL(0x139b0131,0xc38156e4),LL(0xc42164bb,0x3293d5ff),LL(0x74da5a53,0x28a54d0e),LL(0x970fceff,0x56246758),LL(0x3ef8fd2b,0x1b3685cb),L_(0x000000ad), LL(0xa0e59886,0xe1a4b217),LL(0xaa3f69ad,0x23117719),LL(0xb7b4e45e,0x118c88c1),LL(0xf1294233,0xd7dfa5c3),LL(0xf1ed8c9d,0xfa2104f8),LL(0x22213ffa,0x89ed7138),LL(0x3ea0a97e,0x2cd0f857),LL(0xf09db9f8,0x28378a81),L_(0x00000167), +}, +/* digit=17 base_pwr=2^85 */ +{ + LL(0x7d77d542,0x6c76648a),LL(0xa16759eb,0xae9936fc),LL(0xd9556eeb,0x239c8db3),LL(0x1fc23af7,0x3df02c8f),LL(0xd956a664,0xfec894e1),LL(0x2a0d5264,0xaaa92f80),LL(0x14a90b90,0x93d756f0),LL(0x53d197ff,0xb190be07),L_(0x00000163), LL(0x06dc80b7,0x026f8974),LL(0xdd1ea5de,0xbf46ad6a),LL(0x1c416858,0x8f0f1c5d),LL(0x6b3d82ce,0xf587ce4d),LL(0xa459159d,0x3b92c19a),LL(0xb6baca47,0xda5bec10),LL(0x600af3c6,0x40e0b4be),LL(0xc81e2b9b,0x5a9bfcf6),L_(0x000001ec), + LL(0x7d27dadf,0x34d4f088),LL(0x4ff582d9,0x24ab4a3b),LL(0x151ee4b7,0x58c8094d),LL(0xdf116aee,0x1ceee559),LL(0x6c8ad814,0xf6cc0cd1),LL(0x3d13c277,0x9d41dd2c),LL(0x75e0cd1b,0xf318d63c),LL(0xbb0767f3,0x285b2c06),L_(0x000000cd), LL(0x1f3f3f36,0x8f1170f9),LL(0x44906780,0x6338ef63),LL(0x7495e6b8,0x66dcb459),LL(0x3f524ab7,0x7ec63428),LL(0xfd773112,0x86373e0a),LL(0x549575be,0xd2af0e3a),LL(0x9dfc2be8,0x6314c681),LL(0xffa7af5c,0xed6d3f7a),L_(0x0000013d), + LL(0xb01c752e,0x2db47294),LL(0x8755f110,0xefd03152),LL(0x233b9d7e,0x00f8e7a5),LL(0x69c62c75,0x1ee3b5dc),LL(0x551f4471,0xa5e280f0),LL(0xc7dd9d94,0x11042cd8),LL(0x0c2167eb,0xaf8b1437),LL(0x7f4636e4,0x9f076780),L_(0x00000112), LL(0x77598691,0x12f599a0),LL(0xcf61cb84,0x0459d6b4),LL(0x6f27cc0b,0x126405e2),LL(0xbc7fdaf5,0x4a3026dd),LL(0x0cdbba7c,0x658e4a3b),LL(0x25d0b262,0xf2e795bb),LL(0xeec95e90,0xc8766509),LL(0x52259c52,0x0502e5a4),L_(0x000001a9), + LL(0x35410967,0x88f9eb94),LL(0x20da6297,0xae5dfb3d),LL(0x527623e5,0x17557d88),LL(0xc844e99c,0xb4031115),LL(0xb6a57ec3,0x4aff5aa0),LL(0xbe7d0b59,0xea2e84ad),LL(0x1e84a37c,0x947fcbaf),LL(0x048c2935,0x17d978e3),L_(0x00000076), LL(0x93f58bed,0x503171b0),LL(0x7aaa2b21,0x7b8e1c73),LL(0x6261f263,0x620dfceb),LL(0x1e8e8701,0xdb241dd2),LL(0xce453d37,0x74e79c85),LL(0x7db88257,0x6f92bc71),LL(0x5a2566e6,0x6fb9d9ff),LL(0x4ae0bd7b,0xebbcbbfd),L_(0x000001c4), + LL(0xed12288f,0xe57e6348),LL(0x585fa9eb,0xa7abfcec),LL(0xb1b5c7dc,0x12939a1c),LL(0x76c09203,0x48eb6b41),LL(0xc4cc679c,0x2a08cff6),LL(0x4778574b,0x8519401e),LL(0xa530fac0,0x93672b0d),LL(0xe3ed0e37,0x42bda3c5),L_(0x0000011e), LL(0xb789e1a5,0x479a986c),LL(0x85a2af38,0x47001e80),LL(0x5a9c69c9,0x623b25fe),LL(0x05944f83,0xecb76557),LL(0x1f6667a7,0x0cb584d5),LL(0xc3bb24b7,0xdaf97923),LL(0x7f09e6d8,0x00ac1be5),LL(0x6d082075,0xfc0ef0db),L_(0x000001a8), + LL(0xcbbf6efa,0xd82adf79),LL(0x6f9a1c1d,0x1d21df42),LL(0x47e0a609,0x1902bf5b),LL(0x6c507d72,0xd92481e1),LL(0x732e3603,0x4e995e7f),LL(0x0a9f3c6f,0x57c9de5d),LL(0x171e968b,0xace10341),LL(0x27d7d96d,0x8b519973),L_(0x00000108), LL(0x093b8c99,0x68806375),LL(0x999003af,0x0227279e),LL(0x62158e85,0xd41629b8),LL(0x3479df9d,0xa2d25c33),LL(0x3570b3aa,0x61de636e),LL(0x4eb04a19,0x71b3bbeb),LL(0x0ce04d19,0x4c30f9b9),LL(0x15492470,0xb4fa9cb3),L_(0x00000082), + LL(0xcc212f6f,0xf1e3cf43),LL(0x2c575c09,0xdd247286),LL(0x0980e757,0x812b4ec0),LL(0x19cba5ed,0x883e3e28),LL(0x4641e487,0x0bb816e7),LL(0x6c96b70b,0x461f03f5),LL(0x26aaf764,0x918835cd),LL(0xe1cfcddb,0x0c7159a8),L_(0x00000104), LL(0xb11711e0,0x3f7282c1),LL(0xed552895,0x44826000),LL(0x25594479,0x065389a8),LL(0x70867768,0x96f127c7),LL(0x52ffb2b6,0xaa1f5abe),LL(0x0831bd74,0x9739a178),LL(0xf0a510a0,0x6154e726),LL(0x36902e78,0x51eacd77),L_(0x0000005b), + LL(0x42cd0f9e,0x7bbdb010),LL(0xa3fbb175,0x1996a380),LL(0xf39db731,0xbb69e651),LL(0xf3f08146,0xec6679cd),LL(0x8679b0b6,0x60847478),LL(0x90d1ae26,0x883e5a59),LL(0xa5e209ed,0xba61924f),LL(0x3c755c0b,0x53df41de),L_(0x000001ef), LL(0x847c1f82,0x8ace9c6a),LL(0xa1434ccf,0x857d9026),LL(0xad864d4c,0x0ee5b0b7),LL(0xf613e221,0x86a35718),LL(0x91165b2c,0x55984d67),LL(0x080d19fb,0x15401901),LL(0x3389eccf,0xd99a0e8b),LL(0x8b509b98,0x5d25fe60),L_(0x000001d7), + LL(0x7c660e1a,0xfd68d650),LL(0x85aa25df,0xe307472b),LL(0x3713d00e,0x3afed55d),LL(0xc091f93d,0xecc3137e),LL(0xa9f9d1a2,0xa3d44f8a),LL(0x32a1cdec,0x4344089c),LL(0xc8d64b46,0xe3575142),LL(0x11bd5244,0x0baf1702),L_(0x000001f4), LL(0xe4cb9635,0x8fa8648f),LL(0x3dc52f80,0xdf8e13dd),LL(0x058fc1b8,0xc1ab282d),LL(0x3abf2a6c,0xf290d505),LL(0xfb0841a1,0xea29f4f4),LL(0x3d94894a,0xb691fb1a),LL(0xf7a1cc29,0x0da25d00),LL(0xfc4326f1,0x3439b98c),L_(0x000001fa), + LL(0x1b3c8c62,0x1ffd1435),LL(0x58c3116e,0x54a96e6c),LL(0x90a8d92e,0x623a9ece),LL(0x891efe6b,0x66715556),LL(0xe72489c2,0xd3bfc0b3),LL(0x5b00b58c,0x8cf3d04d),LL(0x06c601e4,0x71f460fb),LL(0x26e3ef6c,0xab622fd1),L_(0x00000122), LL(0x626e2af2,0xa51ff90c),LL(0xec49ef66,0xd3f82493),LL(0x704277da,0x9f0e6e8a),LL(0xca17ce54,0x80cb9b26),LL(0x62bbba3d,0x39fb568b),LL(0x7ff82aae,0x978a0c13),LL(0x9cbfd867,0x6bd90fa9),LL(0x07be1717,0x35fbb751),L_(0x000001d2), + LL(0xd809dd1b,0x12107a4a),LL(0xc16d6592,0xdc70467d),LL(0xf8d5c83c,0x273b2243),LL(0x596e052c,0xeab68bd9),LL(0x8aaa0dde,0x11cdb329),LL(0x39baf3e4,0x65459e78),LL(0x004f292b,0xc654b1e0),LL(0x4da9e734,0x3bae514a),L_(0x00000186), LL(0x1ee009d1,0x45bc8ab1),LL(0x24563a0d,0xde252f6e),LL(0x04322137,0xd1d577ae),LL(0x29c5297d,0x554880c2),LL(0xf29e1a9e,0xfc0d4b7e),LL(0xa08f14c2,0xe648399e),LL(0xfd1007c8,0x23bed899),LL(0x2a7303ca,0xf8a75610),L_(0x000000b1), + LL(0x2e60230d,0x883ed27b),LL(0xf8aee1ce,0x57a9715e),LL(0x9d84b9da,0xa58cae2e),LL(0x59971acb,0x62ef042b),LL(0x5b1190ec,0xa8c70cf9),LL(0x1ecd90c6,0x1e5cf5d1),LL(0x0a20a7a4,0x3aec3e16),LL(0x7baf5a6c,0x8a25f66e),L_(0x00000149), LL(0xf18a3f41,0x0debc30a),LL(0xc54674cb,0x2dbc3b83),LL(0xc265a6e5,0xa8033fd7),LL(0xf450415c,0x2a50f527),LL(0x6adf277c,0x81475ec6),LL(0xff0d3a36,0x5f2c676b),LL(0xdffe6c53,0x0c1f159c),LL(0xf5ad7f78,0xa68f5906),L_(0x00000191), + LL(0x00058fc2,0x8bb729ca),LL(0x48246fa7,0xff563f60),LL(0xb23219d5,0x8c64a3a5),LL(0xf34e49ac,0xe82036c1),LL(0x9d2397f6,0xe392c964),LL(0x58216601,0xbeda885c),LL(0x3d7f9573,0xe289f5e8),LL(0xb1917dc6,0x15f32b69),L_(0x0000009e), LL(0x6d9791a6,0x37eb92d1),LL(0x066237a9,0x7995f34e),LL(0x764ae778,0x8d994f01),LL(0xde5ca0e3,0xaff07e24),LL(0x199bd467,0x544454f0),LL(0x4bf2e809,0x603eb80f),LL(0xe5054850,0xc95e16ef),LL(0xa4a6c672,0x0af00fa9),L_(0x00000060), + LL(0xc8db0700,0x32a1b788),LL(0x45d0d169,0xc842373b),LL(0x87531f66,0x674b4407),LL(0xdbe71b0e,0x8189664d),LL(0x42dd8323,0x7cdb6aec),LL(0x8df2c5a6,0x86c397bc),LL(0x86388fa4,0x110db0bc),LL(0xf6d18eb8,0xa1af0086),L_(0x00000118), LL(0x23e50391,0xa2dcf957),LL(0x6ae2419f,0x1c7362d5),LL(0xac9caab7,0xd238a731),LL(0xbef3c44d,0x28f6d7ae),LL(0x5c3ea7d4,0xdacef1fe),LL(0xd654307e,0xb31d909e),LL(0x01625227,0x6d2db310),LL(0xb2421d90,0x923e60f9),L_(0x000000b4), + LL(0x4083d41b,0xf3bbcb07),LL(0xe8c0bfc8,0x91274928),LL(0x9c0b763c,0xc81b7765),LL(0xbe1076e4,0xbf368625),LL(0x9568943e,0x8c2112ae),LL(0xb0cd4c71,0xf70e5fb5),LL(0x8fe2ec7e,0x76a5c64b),LL(0x867a5527,0xdac3d4b5),L_(0x0000016c), LL(0x3faf5b44,0x41c29ed5),LL(0x50ffd8e6,0xcb155068),LL(0xa9b2855c,0x28ae527b),LL(0x9d8e8d01,0x2a092960),LL(0x5cbf1edf,0x66ffe099),LL(0xb212b2a8,0xd340e610),LL(0xfc0600f9,0xa2f5aba0),LL(0xb08ba7b8,0x10dafa5b),L_(0x000001a7), + LL(0x0ca526cf,0xa9ed0f7a),LL(0x125b33af,0x1dd685ac),LL(0x516f5290,0x17e7ff8f),LL(0x927c416e,0x720475ad),LL(0x0fc77cc9,0x67e1e919),LL(0x3aec0717,0x6652fcb3),LL(0xcb2653df,0xd80f0d48),LL(0x8bf16720,0x98cc486c),L_(0x000000c0), LL(0x08404c44,0x7f43e4e4),LL(0x9c42e337,0xdefb2272),LL(0xc3b37e10,0xdaf241ae),LL(0xc795c866,0x0a07c892),LL(0xbf4d3079,0xb2425f5f),LL(0xa5db075b,0xb7cb5830),LL(0x0875f161,0x93c95089),LL(0x91cad664,0x21f9ae65),L_(0x0000000b), +}, +/* digit=18 base_pwr=2^90 */ +{ + LL(0xc3797559,0x266f6975),LL(0x22dfb9d9,0x599f544c),LL(0xdb081480,0x839c2be6),LL(0xeb8ec462,0xb5cdf12a),LL(0xd9d49cd3,0xa917fb29),LL(0x96146a8b,0x233b216f),LL(0xd936c0b8,0xf0abf1a9),LL(0x8c8a45a2,0xbb59a787),L_(0x000000fb), LL(0x0f5dd64a,0xd1625aef),LL(0x056528c2,0x5ff56fc7),LL(0x9b293d67,0xa5c323cb),LL(0x02b295cc,0x4d697cbd),LL(0xbc712910,0xe4eb4b02),LL(0xc1e4d83f,0xa4e9327c),LL(0x9c23cdd4,0x5af46cdc),LL(0x94640699,0xac05353f),L_(0x00000006), + LL(0x6147414f,0xaed9435d),LL(0xbd16db82,0x62ff16a9),LL(0x3b07e71a,0x52dcaf4a),LL(0xf9456ee7,0xea0d3e3f),LL(0x1d78dd65,0x64901fef),LL(0x31145bf8,0xbc9f4225),LL(0x366fd367,0x81cb13ee),LL(0x290083f4,0xbc209fe6),L_(0x00000193), LL(0x5232088e,0xc5e887c8),LL(0xcc7b3f38,0xf005e149),LL(0xe1bede78,0xe8c89874),LL(0x2dfeaf32,0xcb4e28c7),LL(0x3cb0a4d9,0xda48c711),LL(0xaf7daba5,0x1fe289a0),LL(0x0d3633ab,0xbd5d0dc0),LL(0xc0b05c86,0xefd7c801),L_(0x000000dc), + LL(0x85849a1c,0x74861653),LL(0xe1eb1a35,0xaf98abe0),LL(0x53b40a6e,0xf083ec36),LL(0x74acbc0b,0x0b5a921d),LL(0x28a65b06,0x5764e30a),LL(0x5588eb5e,0x62277d5e),LL(0xc8da671e,0x39cae462),LL(0x53bbf492,0xc9d38ca9),L_(0x000001ab), LL(0xa6baa014,0xd98a134c),LL(0x31e23fcb,0xdbe32368),LL(0xa8c7a352,0xef82abaa),LL(0xa98ba793,0xcbb55844),LL(0x1a07e161,0xaf3169a7),LL(0x4991ee4a,0x5cfbe290),LL(0x0c980dd6,0x56a21524),LL(0x1c07cd7d,0x6b70cccd),L_(0x0000000c), + LL(0x07567a7a,0x045155d8),LL(0x351697cf,0xce8bb246),LL(0xcba64633,0xdd5c2900),LL(0x24297174,0xe7f044c7),LL(0x0c3a3851,0x48c830bf),LL(0xd35ff595,0x817a26f0),LL(0x7d923f53,0xd93d8b02),LL(0x2b3dd7ca,0xbc01062c),L_(0x0000000d), LL(0xcc94cbf6,0x986d299b),LL(0xdf6f5c09,0xf89ccb5a),LL(0x5aee26f4,0x18699f82),LL(0xc1b545bb,0x6595e656),LL(0xb0d22aa5,0xa3953fae),LL(0x6abcba5e,0xa9580b4b),LL(0xd4e240d3,0xef465246),LL(0x13b6fdf7,0x97f3ed86),L_(0x00000124), + LL(0xbd979035,0xf355f70f),LL(0xc5a87f52,0x1b7365b1),LL(0x18c500a7,0x2dd3210c),LL(0xf547e418,0xc57a734c),LL(0x391d8bfc,0x928abb19),LL(0x5ec8dcf1,0x3e6991b5),LL(0x7de9b3d1,0x9e25eac7),LL(0x6ebd2b96,0x6a202a22),L_(0x000000d2), LL(0x7d70fd72,0xae0eb8d2),LL(0xf2114ba3,0xb57b0ed4),LL(0xe573b783,0xc65906cc),LL(0x0b2b3d21,0xfac74740),LL(0x9dbb25b7,0x6157bc5c),LL(0x6859f85a,0x21a21340),LL(0x0df614a7,0xbfacee18),LL(0xe4709b5a,0xa37c69b2),L_(0x000000ef), + LL(0x15b4091f,0x31ad054c),LL(0xdccd6f0a,0x57e2c372),LL(0x27698a20,0x9a3a4ffe),LL(0xcc03de8d,0xc754fb8f),LL(0xcd17cdf6,0xa956ebe7),LL(0x7cb9ef2e,0x9d18d38c),LL(0x190daaea,0xdc66f2ca),LL(0x7d783383,0x46f57c30),L_(0x0000012d), LL(0x727ea062,0xfefa898f),LL(0x773b6e5f,0xfbea71e8),LL(0x7460be92,0xc9254b56),LL(0x318caed7,0xc982d8e5),LL(0x7f1a16b2,0x9a4da06d),LL(0x38233ae7,0xe149d876),LL(0x3b8c2af7,0x70fc3c7a),LL(0xec4a5565,0x8d292554),L_(0x00000197), + LL(0x5f08f3c6,0xd02192ba),LL(0x05cbe08a,0xbb7b43e6),LL(0x4a339a92,0x2b4034e6),LL(0x1c6eea28,0x0145dd56),LL(0xb3481662,0x819f74ea),LL(0x5fdab086,0x2d08d669),LL(0x401f4d8b,0x87d855a8),LL(0x71a3977d,0x0a7c167c),L_(0x000000e6), LL(0x787e1654,0x7f231760),LL(0x1dcce655,0x2908ba05),LL(0x10acadce,0xe5a3ffa8),LL(0x60f31016,0xe1211553),LL(0x34c2a1c2,0xfe1b8dad),LL(0xa81d35d3,0xe7230bfc),LL(0x37a78d41,0xcfeaf774),LL(0x6e60ae9c,0x929625f5),L_(0x000001ed), + LL(0x898a64cd,0xda668233),LL(0xc8516d6d,0x1f40d7d1),LL(0x5fb1f564,0xd5a115e0),LL(0x7906c2d8,0x496ac4ad),LL(0x6f4efe00,0x3643f707),LL(0x6c892d97,0x414f5838),LL(0xe34b14c4,0x7c2d83c2),LL(0xc00d08bc,0xb5ea2437),L_(0x000000e4), LL(0xca445165,0x219e2e5b),LL(0xcbf3a3f2,0x118227ea),LL(0xf1a84019,0x6017e2ce),LL(0x58a5f9de,0x1922122d),LL(0xf1ecfa6e,0x98696eb0),LL(0xd3df6fb1,0x54826be2),LL(0x8fefc088,0x02dea006),LL(0x77c29791,0xd7ce374e),L_(0x000000d7), + LL(0xe65ce508,0xa5fec659),LL(0x0b177612,0xdd1bcbef),LL(0xfc84b3bf,0xe4569388),LL(0x984ce0ec,0x163caf98),LL(0x9cc1f201,0x3fa88dda),LL(0x39bac4dd,0x6c254803),LL(0x70562e22,0x75a93dd1),LL(0x2cbfcecc,0x16ebf295),L_(0x0000006d), LL(0x0ce600b2,0xe3dc17db),LL(0x5b060f2c,0x5399ddf1),LL(0xd74988f6,0x83e38dff),LL(0x2b96b9f4,0x87e221d8),LL(0x2c298bc9,0x0753b765),LL(0xd6bd45f4,0x27e5b1a1),LL(0x18ca1da9,0x41853811),LL(0x7849f1e1,0xf9e739bd),L_(0x000001fa), + LL(0x226b8a15,0xdb333954),LL(0x4e3975a7,0xaa52c0ba),LL(0x74176c01,0x1fd9d014),LL(0xa1a2b6b0,0xf61b81e1),LL(0x28415db7,0xd3614b3a),LL(0xa0f6000e,0x9e00e5a5),LL(0x5cf34986,0x9efe446d),LL(0x0b69d383,0x845d741b),L_(0x00000121), LL(0x2d0c1e46,0x1f77c4cb),LL(0x553d358a,0xe9f129ca),LL(0x071ebad1,0x088b2769),LL(0x8eb8c2d8,0xf3219a51),LL(0x877b3a25,0x17c5431a),LL(0x9c4b8adf,0xeac2ff93),LL(0xffc69d68,0x23d158f5),LL(0x2e0840d4,0xbd9e89fa),L_(0x00000048), + LL(0x6d2a4e6a,0xb45f9376),LL(0x6e78c290,0xbff42b2f),LL(0x5fb9af74,0x2af23d44),LL(0xaebdf547,0x7deaa238),LL(0x93a6597a,0x25df5576),LL(0x5dcbd040,0x6f6b456f),LL(0xa9249467,0xb63da0b0),LL(0x7f719d63,0xb3143ac8),L_(0x00000173), LL(0xda677478,0xcb218f05),LL(0xb119afe4,0x3e0b4052),LL(0x816ad70e,0x342ea279),LL(0x14498c92,0x7acbb776),LL(0xc4e09c12,0xbf8e66de),LL(0x0f290835,0x3edfdd90),LL(0x8ca19f41,0x794255ee),LL(0xa1bde671,0xd1cabfcb),L_(0x0000002b), + LL(0x4848eb20,0x80f21ad1),LL(0xde0fb7d6,0x8e50bcbd),LL(0x4c1119fd,0x83d6f607),LL(0xf9f2e435,0xd9961c79),LL(0x765361f1,0x625f26bb),LL(0x008a463e,0x2b47c8db),LL(0x87cd134f,0x328c3977),LL(0x36eea7ef,0xb645529b),L_(0x000000b4), LL(0x3d664722,0xdfe036fb),LL(0x206e887a,0x67daf1eb),LL(0x72f017c4,0xf7db19b3),LL(0xad33a99e,0x06ea7ba8),LL(0xf55c0da8,0x14bd637e),LL(0x9b12c024,0x59864973),LL(0xd282f3bb,0x55feed3d),LL(0xce69b372,0x299c53ec),L_(0x00000071), + LL(0xdf10c34e,0xb43675e3),LL(0xb8ad4110,0x19590538),LL(0x801f28aa,0x239ed388),LL(0xc602d7b2,0x3a5a6ad4),LL(0xbdc9fad5,0x62b5ae49),LL(0x135d222c,0x5042d74a),LL(0xc3f94c1d,0x28ba3dd9),LL(0xe0a1ec48,0x5abc7310),L_(0x000000f3), LL(0xceb5a088,0x77f171c2),LL(0x8f737348,0x31242fc1),LL(0xdbca643a,0xe44bcbd8),LL(0xcd573afd,0xbad62d6a),LL(0xc4c9f268,0x5d49ae75),LL(0x98fad2cf,0x9b8f817e),LL(0xd8431494,0x96bb2753),LL(0xc49e4432,0xa3c623a8),L_(0x000000d9), + LL(0xa4f9f22d,0x2ccfc8e8),LL(0x4cd46e2b,0xa48136e4),LL(0xa95491dd,0x8818327f),LL(0x6393487e,0x7a069a28),LL(0x98ab19e5,0x5c879344),LL(0x02491e0c,0x82e60002),LL(0x2abf1999,0xc0e10b00),LL(0x82724899,0x06d9bded),L_(0x0000010e), LL(0x4897df79,0x688c2193),LL(0x43479e7f,0xc705deaf),LL(0x5b79a04e,0x068f9205),LL(0xb2c04a79,0x3a42239d),LL(0x0245715d,0xa99eca86),LL(0x55284faa,0x9f983742),LL(0x07d9bbaa,0x5fe3bb74),LL(0x5a19431d,0xaebc434c),L_(0x0000013f), + LL(0x99e63ac2,0xac6175c0),LL(0xcb3bdf62,0x0d4bf222),LL(0xd9e5f622,0x83e1cd77),LL(0x4ca3e4a6,0xde0dce61),LL(0xf80cd49b,0xeac1e293),LL(0xf190c10e,0x901aa7ce),LL(0x30eda1d3,0x25f2f0a6),LL(0xa509dab1,0x7ead9599),L_(0x0000001e), LL(0x0ab974ef,0x9b6b41ad),LL(0xcc8fc9d8,0x20269236),LL(0x5472afda,0x81034020),LL(0xb7eb7c83,0x26dba78a),LL(0x7c59479d,0x81e829eb),LL(0xb0ba6216,0x1549f5f2),LL(0x843a5c45,0x18302134),LL(0xa2709e3b,0xf629ef4c),L_(0x000001d3), + LL(0xbde5f81a,0x8f81e9a3),LL(0x7f4da051,0x9720014a),LL(0xa02bf073,0x9ff1f457),LL(0xe074553e,0x3a46ea6b),LL(0x64351eaa,0x7e32f0dd),LL(0xd22b22b2,0xb488462f),LL(0xcafc2c23,0x566dddda),LL(0xfb75908f,0x6e12535b),L_(0x00000182), LL(0xe8987332,0xfe94dfd9),LL(0x4f63b44f,0xf9b91bc6),LL(0x0dbd772b,0xecb77f43),LL(0xd580392a,0x2fb67ddf),LL(0x1ddc69fb,0x2fdb69c9),LL(0x9ea2314d,0x754b9b9f),LL(0xe624f23e,0xf3f2e9c2),LL(0xc6e677e1,0x734230a3),L_(0x0000016b), +}, +/* digit=19 base_pwr=2^95 */ +{ + LL(0x14f438f4,0xd13ff0c3),LL(0xb8e45f22,0xd55796ec),LL(0x3dd2e2bb,0xf830ab87),LL(0x9eb71d33,0x14a36478),LL(0x83167e0b,0x46513aa4),LL(0x793502c2,0x03e86d3a),LL(0xb0fe98cb,0x4eb2db2b),LL(0x0404a0ec,0x002c10d7),L_(0x00000162), LL(0x8f4384c5,0x0cd19a5c),LL(0xc19b3257,0x1c33b468),LL(0x9210942f,0x29ccbac3),LL(0x36048a2a,0xd4ffa97d),LL(0x4f69ef5f,0xcd6b0a67),LL(0x82d0ece5,0x13229739),LL(0x4bce1b8b,0x491493bd),LL(0x4d6596bf,0x6c17983d),L_(0x0000018d), + LL(0x560db5e8,0x1117f6d4),LL(0x8e19b583,0x1106059c),LL(0xe8232c57,0xc78f908c),LL(0xd0f09782,0x4a24aa92),LL(0x8bd0fcb6,0xd766becf),LL(0xf59977e3,0x155f53d2),LL(0xfa9a727f,0x49389ae2),LL(0xff877e92,0x595c1920),L_(0x00000027), LL(0x9985d510,0x3b4e5204),LL(0xe4788dc7,0xaa68342b),LL(0x8a0ca8e6,0x7b14f89c),LL(0x66874892,0xf19eb3e8),LL(0xe17375dd,0x5e5f8b7c),LL(0x652a41d1,0x2912af54),LL(0xa86a7275,0x5ab9a777),LL(0xbaf706d8,0xa88b103b),L_(0x000001a5), + LL(0x8ca944bc,0x4852fbcb),LL(0xbefff557,0x0369a497),LL(0x3e3736fb,0xe2bb7551),LL(0xd21615dc,0xe6d3b727),LL(0xe319eb4c,0xe8de5f7d),LL(0x48fe4856,0x592a3396),LL(0x7516380a,0x80dc9aef),LL(0x51f52af0,0xddc54f51),L_(0x0000001a), LL(0x98c6421f,0x38523c52),LL(0xec51f4f2,0xf58cc95f),LL(0xbc6c8082,0x36ef370c),LL(0x7bc605a3,0x8ac270e3),LL(0x83d78da4,0x0412498a),LL(0x6de54abd,0x66b38131),LL(0xdb62d8c6,0xe06d3c3f),LL(0xf5e45a86,0x4e3ea929),L_(0x000000f5), + LL(0x4517d395,0x53d2cbb1),LL(0x5b733d69,0x44a3ef5b),LL(0x472126ff,0xee076565),LL(0xa4a1334d,0xb26c37b2),LL(0x12573d17,0xb5b29517),LL(0x129c2c7a,0xd328148c),LL(0xa2c72b08,0x08907f5a),LL(0x1d10e103,0x4f66b18b),L_(0x00000085), LL(0x5e159666,0x9359d888),LL(0x4827d5dd,0x0281b6f1),LL(0xa475f3a4,0x6b19bc4b),LL(0x2eef4469,0xdc6dfbc3),LL(0x782b50db,0x9ef4383e),LL(0x0583236a,0xd7320845),LL(0x7767db3f,0x0dd190b0),LL(0x3c0278a0,0x96afa315),L_(0x0000002a), + LL(0xb03b1675,0x97e68374),LL(0x1c499646,0xae2f3284),LL(0x74508785,0x0255084b),LL(0xf1921ad5,0x6ea40714),LL(0x2aabd8cb,0x516433de),LL(0xd1c8abdf,0x5d2d8ded),LL(0x8f5d7b6f,0x421e5a19),LL(0x2d6ae9c5,0x9eaf7e7b),L_(0x0000018a), LL(0xd9a89463,0x4310dcf0),LL(0x0122d1b0,0xd2489f91),LL(0x4e7b58d3,0x655fdd5d),LL(0x40c4379c,0xc7862d42),LL(0x6da55b4a,0x975cc64c),LL(0x1e1d3862,0x84484f68),LL(0x301cfa3f,0x2a16eb0a),LL(0x20ebbbdb,0x293922e4),L_(0x00000132), + LL(0xc0ba905f,0x5b3d8d39),LL(0x62a268ee,0xea2a0a44),LL(0x094457cb,0x80f032f3),LL(0xab36ceff,0x8790739b),LL(0x21b0fdf3,0x40209bce),LL(0x38249dc8,0xf0c1c8e0),LL(0x213ecb4d,0x70c51d81),LL(0x2b025e0d,0xac4a363c),L_(0x000000a8), LL(0x493bb32c,0x798bfbf2),LL(0xf622fccb,0x28838277),LL(0xc2594827,0x5cbe5b67),LL(0x2c07c4dd,0x2c4c703c),LL(0x1c19526a,0xdcd0df4c),LL(0xed390177,0x57a743a1),LL(0x3a4c5274,0xac32bea6),LL(0x1c302e78,0x133f075d),L_(0x00000097), + LL(0x18bc0976,0xa3094433),LL(0x7cfa690a,0xca509300),LL(0x660a165b,0x9645aafc),LL(0xdcef6d7c,0xd90c6f35),LL(0x07a41bbc,0xad0dd448),LL(0x702e476c,0x5c881f7f),LL(0x2185a821,0x9c91260c),LL(0x0622b914,0x6ca1be63),L_(0x0000001d), LL(0xfe64e60a,0x59c3b83d),LL(0x192bd9cf,0x5bdb24df),LL(0x69659379,0xa9cbc111),LL(0x437b31e8,0x2954601b),LL(0xb7b5589c,0x13c392f3),LL(0x97064b9e,0xf1845fb5),LL(0x8d803336,0x7ea9c980),LL(0xea2d2221,0x36a667ca),L_(0x00000196), + LL(0x23fc5003,0xa9841f43),LL(0x62407436,0xc6f35f8a),LL(0xfc260a1f,0xf5e9286e),LL(0xe74c4b2d,0x504bfafb),LL(0x7cb3568b,0x3548e504),LL(0x1af9dbcf,0xd92aaad7),LL(0x85e423c5,0x2d182410),LL(0x94d1d884,0x1fe174f8),L_(0x00000105), LL(0x9975b2a3,0x55f78348),LL(0x0939eec5,0x92b31a41),LL(0x23255263,0x4a1b7bc2),LL(0x65a25c26,0x283464db),LL(0x08fc1aed,0xecd1a9b7),LL(0xea335c70,0x90a7a2a0),LL(0x9f14ffdd,0x7fd21f2e),LL(0x9566dadd,0x36ebafb4),L_(0x000001e5), + LL(0x578b8f88,0x2bbf7009),LL(0x8c4ed5a7,0x30e7b9aa),LL(0x30aeacb4,0xe07a93f1),LL(0x58d02f17,0xbcf5fa42),LL(0x7c6f83ed,0x228f3e47),LL(0x91d5ba0c,0x815eef51),LL(0xe37c3b79,0x0528cf82),LL(0x507b5dce,0x7d4e9bf2),L_(0x000000aa), LL(0x5a682d56,0x14eac39b),LL(0x72ce45fa,0x90b36bc5),LL(0x5f62d8bb,0xadbc91ec),LL(0x9d5e2385,0xfae2e6dd),LL(0xef20a2d0,0x380bdc5e),LL(0x9c9037ea,0x2d48d188),LL(0xdd58b76d,0x6a4ce00a),LL(0xb6e3d5d7,0x2f506090),L_(0x00000135), + LL(0xfffa5757,0x64cbfd55),LL(0x1f1c3ae1,0x8a854545),LL(0xd0be9705,0x7272e007),LL(0x2a8f4c49,0x254138ed),LL(0xc97ed736,0x15e864c7),LL(0x83df5162,0xb624fc1b),LL(0xf4114fdb,0xcc0313aa),LL(0x8c7f0423,0xa6edea7a),L_(0x000000a8), LL(0xa4ed76ab,0x3e74f599),LL(0x8b381bfe,0x25d1f92d),LL(0x9e406956,0x06a5a359),LL(0x869bdf5e,0x5afaf671),LL(0xaec86f62,0xbbcc12cd),LL(0x0dd1d724,0xda751689),LL(0x21630603,0x409b6925),LL(0x1f15a18b,0xa4edb254),L_(0x00000191), + LL(0xc7b9233c,0xff6a30c8),LL(0x6ecefcff,0xf3d40688),LL(0xfad25722,0xc51d4aa6),LL(0xf9c6f8fa,0x3fae03f2),LL(0xc7864470,0x5ca7328e),LL(0x4201ca64,0x4b3ff739),LL(0x08cad454,0xb2721cee),LL(0x43bf4523,0x4594a3d1),L_(0x00000197), LL(0xaf0e573e,0x2a8f8fba),LL(0x3f5e67f8,0xae4ce46a),LL(0x616a72e1,0x906994c7),LL(0x3a7f4aec,0x055b94c2),LL(0x8bb69b90,0x67e39f74),LL(0x4eead34a,0x7a7cada3),LL(0xf92b70d7,0x9b22abe2),LL(0xca616691,0xa5cfde92),L_(0x00000052), + LL(0xd5e1c4e6,0x7ad659b7),LL(0xe2f2a298,0x3f7f338d),LL(0xaaeb06f1,0x6d9b55a5),LL(0xa60e84f2,0x30c6f8b9),LL(0x9d105631,0xd017d58e),LL(0xfa41e760,0x9e20b973),LL(0xb2f4acf3,0x840eaafd),LL(0xec9c6ab5,0xcbac2501),L_(0x00000065), LL(0x22f4549b,0xb140b897),LL(0xc2510a98,0x3e099225),LL(0x9117bbe6,0x18af31b1),LL(0xba7147bd,0x68bb5c46),LL(0xf0f540e3,0x29d33114),LL(0x1c9aeacf,0xe59588a0),LL(0xeb2d0e67,0x29ef0e25),LL(0x4bb1b8d0,0x4c60558e),L_(0x0000014b), + LL(0xfaf6783d,0xd0223b63),LL(0x4dcebc43,0x6472ecb7),LL(0x6ff8245b,0x1d3fdb09),LL(0x3439a621,0xa67bac9a),LL(0xd009a2d7,0x94c65387),LL(0xf330caae,0x19a02e17),LL(0xa6f7e5f9,0xb2396a55),LL(0x5fef60ca,0x08eb7e67),L_(0x0000007f), LL(0xefd6a160,0xefa0d1c9),LL(0xbd7c0837,0x2ede1f4e),LL(0xfcadb9c0,0xf4756366),LL(0x47882726,0xcd42f3e5),LL(0x5c040ce2,0xa61b16f9),LL(0xdb84713f,0xc4ef07e5),LL(0xe43320a0,0xecb2b8ce),LL(0xac70be15,0x4eb58c90),L_(0x00000124), + LL(0x0457915c,0x89a3e1eb),LL(0xe08cc88e,0xed12c670),LL(0x89133ab9,0x1faeab1d),LL(0x15d9bc0c,0x3c4250f6),LL(0x881504d6,0x084c8e8f),LL(0x3ead62cd,0xaf76dbe5),LL(0x49cfac6a,0x85bf1dcc),LL(0x007ea0b8,0x8816bfc7),L_(0x0000016a), LL(0x47472352,0x123835c7),LL(0x80692fa2,0x67bab29e),LL(0x8379c2a8,0xc2ecca00),LL(0x9065aafb,0x32da9779),LL(0xda605d2e,0x421bbbfb),LL(0x12432283,0xbdc2e115),LL(0x9c126b9d,0x437a9d89),LL(0x7ce3f8d6,0xa0a2a746),L_(0x000001f8), + LL(0x5b6dacf5,0x7ae17558),LL(0x1b0157e6,0x314ffaf0),LL(0x03819c6a,0x9d2d7013),LL(0x0e14b9b1,0xc8c2b439),LL(0x91c83635,0x9f636f0b),LL(0x98fed93b,0xe579e47a),LL(0x23b6808c,0xaeb0f547),LL(0x8d044288,0xcd184b66),L_(0x00000151), LL(0x891f32da,0xf965270d),LL(0x655e3634,0xe11f64ad),LL(0xacfd673c,0x1b496453),LL(0x68fb4507,0xdf15820b),LL(0x64f7f419,0xd816e8bb),LL(0xfdaf2edc,0x0858d605),LL(0xd9f619c9,0xbbe07451),LL(0xb9e75198,0x3e93a602),L_(0x00000116), + LL(0xe000c97f,0x5fa6cdb3),LL(0x595ed0a5,0xfd5fcd60),LL(0xa02a23c6,0x76e522bd),LL(0x61844a1d,0xbaf8c003),LL(0x0c6c179e,0xd0a47af4),LL(0x6aa1a6cc,0x71e2a115),LL(0x4eb00620,0x2ca1b0fc),LL(0xc1c5314a,0x3dce0bb4),L_(0x00000094), LL(0xcdc04837,0x5b4e8123),LL(0x242a32ef,0xa7d67834),LL(0xccb0fead,0xc2a3bc3a),LL(0xe65ed32f,0xe7119407),LL(0xab8b44e6,0xaeb1712a),LL(0x5a5977e9,0x39ce4f89),LL(0x708cfeb0,0xa19d43ed),LL(0x4957cd1c,0x0562d425),L_(0x000000ce), +}, +/* digit=20 base_pwr=2^100 */ +{ + LL(0xc29a3fb6,0xcfe3b9a1),LL(0xca033fc3,0x8c5a528b),LL(0xb4bc3e3f,0x23396cd7),LL(0x4bd134e2,0x39c3eb8c),LL(0x565224c7,0x25548c0a),LL(0xf01471ec,0xb0fb17f6),LL(0x5fc65797,0x18aee101),LL(0xc4d69b6d,0x07d23448),L_(0x0000005e), LL(0x0074be70,0xa14b550a),LL(0x52425042,0xf8e6b95a),LL(0x3f438c42,0x0174e981),LL(0x81004aa1,0x34ae4351),LL(0x510cd9a8,0xb1b67e29),LL(0x8cdf2105,0x41438bad),LL(0x8ec5ba91,0xc64d1130),LL(0x00e8c08d,0xc01f2343),L_(0x0000011e), + LL(0xb2625d11,0xdcf3505f),LL(0x9962934c,0xc306874b),LL(0x981e8fcd,0x02704410),LL(0x2bd0a650,0x249eb349),LL(0x6a534a84,0x6b6bb40b),LL(0x0c32e132,0xbe5d2914),LL(0xcb2ca52e,0x029956b2),LL(0x77c72251,0x01849b8c),L_(0x00000029), LL(0xfe2b4e07,0x6314442e),LL(0x4431d884,0x66618e79),LL(0xcd3eeea2,0x6a5a933f),LL(0x64415965,0xbda24f06),LL(0x522dc52f,0x82f45dda),LL(0xd412542f,0x0e5075c9),LL(0xff34a66e,0x9a2aba0f),LL(0x512c4a1d,0xb89bbd69),L_(0x000000f8), + LL(0xa3dc5b94,0x9872016b),LL(0x2889ccb7,0x1df5e18d),LL(0xe0129254,0xdbcaebf5),LL(0x4cd20b4c,0x63d6c33a),LL(0x1f301089,0xc46a1dad),LL(0x755fc0db,0x2c0e39b6),LL(0x6ef9e694,0xac07fa12),LL(0xd500d36f,0xd54aa805),L_(0x0000013e), LL(0xf90b5e7b,0x65e8dbbf),LL(0xeb8ecb37,0xe491cc2d),LL(0xd314c068,0xd31ab995),LL(0xe810513a,0xcca181b4),LL(0x9b50dc0f,0x0c1e0526),LL(0x89302958,0xb6453c85),LL(0xde5a7d26,0x3c9a98b2),LL(0x6f7a7718,0x3cbf6b38),L_(0x000001a3), + LL(0xd7d861fc,0x7b3c184c),LL(0x5c425a73,0x14a6e3b9),LL(0x85d4a651,0x532f514e),LL(0xb665bb45,0x8b87e598),LL(0xa66a39b0,0xdbcbbabb),LL(0xa46208db,0xa64b561f),LL(0x9520864b,0x05569250),LL(0xde8b31e2,0x46d15281),L_(0x000000a8), LL(0xdd1bb6a7,0xe76a8c5d),LL(0xc0f66932,0xc6ee633c),LL(0xc546bb80,0x911f68d0),LL(0x828f4e0c,0xc213a206),LL(0xeb2a4276,0x04a16b2c),LL(0xcbe98cb2,0x38c09aa1),LL(0xbcc1671d,0xa6f3ebee),LL(0x7a684ba9,0xe784232c),L_(0x00000088), + LL(0x2ca34639,0x14b160b2),LL(0xe3cc4351,0x57f2d520),LL(0x8707011b,0x1d30ff78),LL(0xb1a346a6,0xd69eda68),LL(0xa84618b8,0x4008115f),LL(0x06f520c0,0xfeeecaa8),LL(0x6a14e30d,0xcc7e0843),LL(0x68bc839c,0x9aec405f),L_(0x00000113), LL(0xb3ae58e3,0xd35d5af6),LL(0xf29bb951,0x38625415),LL(0x552cd755,0xb49fd087),LL(0x87ef7e8a,0xde9ebd20),LL(0x76b067b5,0x110309c1),LL(0x1ece1e74,0xb224505a),LL(0x91a5a2d7,0x03ba9629),LL(0x79263dad,0x31e7eb88),L_(0x00000193), + LL(0xa71b7e01,0x5ba885f2),LL(0x915b6877,0xb98305b9),LL(0x53769a90,0x10c19b27),LL(0x8d87ac0d,0x8f7acf63),LL(0x583c77c1,0x64d02af2),LL(0x6e04d239,0xe5be9202),LL(0x8f85294d,0x3a5a3099),LL(0xbb22f880,0xf9b4d2d2),L_(0x00000113), LL(0x150daae0,0xf1b9b104),LL(0x500967b9,0xe48eb13c),LL(0xec3e5c4d,0x895cf9cc),LL(0xb6158629,0x7d90f3f7),LL(0x8aa201ea,0xc0cda29f),LL(0x0c9a6e88,0x4c0d7015),LL(0x97d1c62f,0x56ee70bc),LL(0x4fd0f68d,0xedd26b8e),L_(0x00000130), + LL(0x413edbb8,0x792ccd3b),LL(0x1564f76a,0x72527a7c),LL(0x2778d6f2,0x45b55b68),LL(0x67ba3cee,0x6e138f21),LL(0x5d96d43a,0x38c932f1),LL(0x63638065,0x4892afee),LL(0x6ed7c45d,0xb82b82f0),LL(0x287b4614,0xad914fee),L_(0x00000089), LL(0xb0953f4f,0x5150d18c),LL(0x107a5e99,0x67e23c2e),LL(0x71a733f6,0x2e8bfba0),LL(0xca46066c,0x1d6c6108),LL(0x8cfb4987,0x39bb5a64),LL(0x48164ece,0x0cf34f51),LL(0x336996f4,0xe99b9250),LL(0xd6e08146,0x773a9c69),L_(0x00000183), + LL(0x4008e517,0x7a6c13d1),LL(0xc5d69ab8,0xc4597b07),LL(0xc66db12e,0xdbd74a68),LL(0xca40dec9,0x4579d719),LL(0x5a617fff,0x13172539),LL(0xe3835876,0x09e3b946),LL(0x2478942d,0x42d20c85),LL(0x82ecbef7,0x34ea5879),L_(0x00000124), LL(0x5f589886,0xc9ae2bbd),LL(0x8ba22c3f,0x2126ee97),LL(0xe212b5ab,0xff875595),LL(0x389b739e,0x9d6707a2),LL(0x263595af,0x87d12dd7),LL(0x92670f97,0xb014c330),LL(0x00678803,0x692f506a),LL(0x060764da,0x2c056f67),L_(0x000001b4), + LL(0xa7daee3e,0x99e57328),LL(0x3e8ff84f,0x8d930fda),LL(0x140c8ff0,0x29def859),LL(0x514bf396,0x6dc6556a),LL(0x917c0e6f,0x1b3aa174),LL(0x2fd52f94,0xbc6b4711),LL(0xec0486f8,0x10164218),LL(0xfc4d6fdb,0x53878087),L_(0x000000df), LL(0x143ce621,0xb9fa1174),LL(0xb63c7e44,0x5ae8a4f3),LL(0xa5424b58,0x8d2b2e47),LL(0x1058f848,0xc653cf99),LL(0x5d72c078,0x9ab7f092),LL(0x5a469db8,0x0eb39c94),LL(0xb34488b0,0xd4f2904e),LL(0xff8c9e4f,0xf8df541b),L_(0x00000041), + LL(0x5b0f1fb8,0x0aa30019),LL(0xcd7cdff0,0xb19b5360),LL(0x2a32083a,0x1a886b29),LL(0x6fd83895,0x3e954ca3),LL(0xfc9e4bd7,0xf6dfbbe3),LL(0xd49474b0,0xbe5e429b),LL(0x6cfc9bf8,0xb282ba89),LL(0xd4f6b8c7,0xffc5e2b0),L_(0x00000099), LL(0xf0239d41,0x54cf1a20),LL(0xf833aa3b,0xbe4f75ce),LL(0x667c55f3,0x210d085a),LL(0xf20673c4,0x90bc983c),LL(0xe6d37945,0x2b933ece),LL(0x7400e31b,0xa73815a0),LL(0x0016f173,0x2d12b0bb),LL(0x04943106,0x2f2ea6cc),L_(0x000000b4), + LL(0xf8f8e68e,0x93b485b5),LL(0xbbae7e17,0x21f99dd4),LL(0xd3ee3730,0x8f41688d),LL(0x869cee4c,0xa7149163),LL(0x7ffdc064,0x1dd2e6f5),LL(0x3e9c9ee6,0x3e5343f8),LL(0x1bea26ce,0xd599de2a),LL(0xc95e92f5,0x12eb8e21),L_(0x0000004b), LL(0xc38ccf06,0x17914783),LL(0x5b85620d,0x3066f430),LL(0x8a55dcb5,0x73026026),LL(0x8691669e,0xe37b2f3d),LL(0x6c8abb34,0xb0b3d5e7),LL(0xe607781f,0x1d40a38b),LL(0xbd4e966b,0xa4bb9c3f),LL(0xfa1cc8e1,0x52c54053),L_(0x0000019c), + LL(0x61cb5b4c,0xa0ed42bb),LL(0xb44afbfd,0x8be8a8dd),LL(0x0621480b,0xe9c3bbe4),LL(0x3bbd013b,0x3dad214a),LL(0xf63413c0,0xf44a0f7a),LL(0xfedcc70e,0xababaa32),LL(0x0bd6ea84,0xd282fada),LL(0x556a1b66,0x85e11955),L_(0x0000005f), LL(0x2eb9a417,0xd244439d),LL(0xe9ea5bcc,0x6a6b06e0),LL(0xc7910063,0x95bae48e),LL(0x065bc250,0x8f84ff6a),LL(0x70b64554,0x1fab9066),LL(0xe0a46dab,0xe07a85ee),LL(0x8bdd86f2,0x832625e0),LL(0x012550fd,0x518e586d),L_(0x0000008c), + LL(0xafed2f9f,0x24dc0f96),LL(0xe142d2cd,0xa6689657),LL(0xea2d5cc5,0xae481b79),LL(0xd0bdf4f2,0x8a560bee),LL(0x85db3226,0xa5d11f99),LL(0xfd86b657,0x77ab3c4c),LL(0x9ecb073c,0x1fa5f6fb),LL(0x59db760e,0x55d4b8e3),L_(0x0000012e), LL(0x09f0d045,0x3533500a),LL(0x2990659d,0x4eb8eebc),LL(0xe68fe462,0x60e87a33),LL(0x48e37752,0xcd62216e),LL(0x703956e1,0x0dcfead1),LL(0x3a09a4d6,0x491340a6),LL(0x49d2c6bb,0x0b013428),LL(0x50df11ed,0xd9a7913c),L_(0x00000048), + LL(0xd8099e2f,0x2aad5a31),LL(0x5920a298,0xb4992465),LL(0x07aa2d85,0x6aeecdc9),LL(0xe712f629,0x2a16e6d8),LL(0x8639dfb4,0x36815fc1),LL(0x2a477d95,0x0b2f5359),LL(0x7c3ca55a,0x896f9530),LL(0x05522116,0xa9274ead),L_(0x0000008d), LL(0x208b956c,0x65da1fcf),LL(0x1c1f9a0d,0x1534c8eb),LL(0x772539f2,0xb39694db),LL(0xbc2cb67e,0xf14a06ea),LL(0xf6e48c27,0x4aa51441),LL(0xe7141d18,0xbd52c5e3),LL(0x7983136e,0x77a0099a),LL(0xd7f96b63,0xa49e12a5),L_(0x00000083), + LL(0x0a99ca48,0xd8a3e48d),LL(0xb1ee6ff6,0xa6f4001b),LL(0x2ec4e0b2,0x04f03a29),LL(0xe977781e,0x0605bcbc),LL(0x0f8d3aa3,0xa1ff6ad7),LL(0x052c4409,0x13eedc9a),LL(0x211fe699,0x4cc42df8),LL(0xd70f26db,0x9c11a057),L_(0x000001fc), LL(0x00258026,0x08667174),LL(0x7f49a77b,0xa5dfdb47),LL(0x0446d9f9,0x6b646fc8),LL(0x24ebc0c9,0xb269fd06),LL(0x244a494a,0xd5fd906c),LL(0x9c16866d,0x27e6983d),LL(0x545f39fb,0x798c184b),LL(0x5fdefa1a,0x5cbdd99b),L_(0x0000013d), + LL(0x1e365108,0x765f67fb),LL(0x1aae9f80,0xb1b38d14),LL(0x7a9407e4,0xc8424d69),LL(0x9693e7cc,0x91d93e3f),LL(0xba50e7d2,0x385c13c5),LL(0xd94ecd34,0x6fcf73c9),LL(0x80eb0bb6,0x0d598f4a),LL(0x1c4d4c29,0x1f3a1b72),L_(0x00000172), LL(0x3b0fb9a3,0x326d546e),LL(0x4c6d27ba,0xa848cf09),LL(0x09d2dc18,0x46c0e416),LL(0x6f0069ca,0x9231b926),LL(0x1c4aef79,0xbdbead08),LL(0x9d4dabac,0x272ba195),LL(0x8e216ceb,0xcc49b720),LL(0x83cc03ec,0xd678f2ba),L_(0x00000177), +}, +/* digit=21 base_pwr=2^105 */ +{ + LL(0xd64c0998,0x7c43b599),LL(0x85a2ec86,0x4c9f6ac7),LL(0x59f29f0d,0xfaa4ec8b),LL(0xf16ae8c0,0x2017604d),LL(0xab8d8f78,0xbb59089d),LL(0x2772bc38,0x38403982),LL(0x6e88e817,0xf3d1571c),LL(0x7d4e8e0c,0x4a1b1a7b),L_(0x0000016a), LL(0x477bc572,0x39b5eb10),LL(0x8d22a645,0x77d71bc8),LL(0xd769223e,0x9734dc62),LL(0xfe2b562c,0x41cdb0ad),LL(0x3173fab2,0x70ddf3ff),LL(0x997d6033,0x70dbbbbd),LL(0x6d59561f,0x998a88a5),LL(0x64aafc32,0x1f2324be),L_(0x000001d4), + LL(0x449a64c8,0x674c0fe9),LL(0x81603532,0x01e88fe6),LL(0x595c6e13,0x913b8697),LL(0xf6f513d4,0x3b6d478c),LL(0x88c1e320,0xb2857351),LL(0x90cfb68d,0xdfb9fd43),LL(0x6c4bb93b,0xcc660149),LL(0x3f388af7,0x73e97063),L_(0x000001bd), LL(0x9a5258fb,0xacae0a8b),LL(0xb741a40d,0xba0560ab),LL(0x795d005e,0x3978bc6a),LL(0xcaa47999,0x1c0b2496),LL(0x1ff04fef,0x6ddcefe7),LL(0x47c3b092,0xf281ff39),LL(0xcc93f3d8,0x23027cc7),LL(0x773c9a3f,0x2ea46e78),L_(0x00000046), + LL(0x21f6a156,0xc4591dc9),LL(0xf7c15406,0xb36c8aaa),LL(0x3b0d0813,0x287834fd),LL(0x44ef9e76,0x94a18ce5),LL(0x52fb6092,0xbd019877),LL(0xb24d08d9,0xd4816092),LL(0x39d2d32c,0x188b097d),LL(0x5b9f00f2,0xa3f1ab3a),L_(0x00000003), LL(0xccda9d6f,0x41dad104),LL(0x637d2807,0x4ee619b7),LL(0x0f5a9cc8,0x4f3d7156),LL(0x97bb554b,0x367054b8),LL(0xe890a210,0x3f1f61c3),LL(0x0784aff6,0xb92963c2),LL(0xc9acc43c,0x309317af),LL(0xdadb0d3e,0xf3d3b5c1),L_(0x00000012), + LL(0x6d5e67b8,0x049665d8),LL(0x19993eb2,0xb56e1ced),LL(0x7a62ba87,0xdfb9c1fc),LL(0x6fc5cf75,0x4712b627),LL(0x554f5dad,0xe0548bd1),LL(0xecba89fb,0x1ee24125),LL(0xfa18f5ad,0x7e176a53),LL(0x8796b526,0x557064e1),L_(0x000001aa), LL(0xada0f1a1,0xe4e5f968),LL(0x89107584,0x8e12a3e0),LL(0xd6a2ba69,0x1ee9c73c),LL(0xe23b2a1f,0x43a76e02),LL(0x428e9adc,0xe3d7526f),LL(0xf09d62c6,0x0557ab8a),LL(0x37cd537d,0x2758b1d3),LL(0xe54434b8,0x3d68a000),L_(0x000000f5), + LL(0x2d008a6b,0xd28295a8),LL(0x6d2db388,0x2d6dd882),LL(0x7d1d9977,0x1f0a2196),LL(0xa51d2cc4,0x5e445be3),LL(0x52abdb6b,0x3146aac1),LL(0x1f1b1ee1,0xfac49408),LL(0x92df369d,0x84b1d832),LL(0xf67ffdf5,0xac7d64da),L_(0x0000005f), LL(0xba8a7d18,0xfa0e70ac),LL(0xf53c34b6,0x3063c19b),LL(0x4954b990,0xcac557d4),LL(0x2d1447f0,0xc89953df),LL(0xc7aef4e6,0x66df6476),LL(0xcb978dd6,0xc6d8f86c),LL(0xf9c4098f,0x024e891d),LL(0x25468ae2,0x0b1850aa),L_(0x0000006a), + LL(0x9893947c,0xe7519a11),LL(0xc44aa926,0x9787209d),LL(0xf096efcd,0x743501fd),LL(0xce9a1706,0x1f7551cc),LL(0x684716f6,0x8dae5405),LL(0x149e678c,0x4cc025ce),LL(0xa47c9f5e,0xb9f91415),LL(0x9acbec1a,0x39acf658),L_(0x0000019f), LL(0x1acf3849,0x7e3ea9f8),LL(0x0e3c4dae,0x4d104dc4),LL(0xadaff9d7,0x5ec06e69),LL(0x2c84d798,0x553ccd90),LL(0x93c28668,0x32f13211),LL(0x585b3068,0x2907a89a),LL(0xcdceca12,0xb9c0d594),LL(0x128fec44,0xf4db515d),L_(0x0000016d), + LL(0x1698ff12,0x50452a3f),LL(0x34e63149,0x70c02b2e),LL(0xa04d3b54,0x3afdb0b0),LL(0x61ed2692,0x91c5ad02),LL(0xd6e4e6a2,0x602aa43c),LL(0x134189db,0x4a9101c1),LL(0xf2cd081d,0x4ee8352b),LL(0xf7a72eda,0x24e8f999),L_(0x000000eb), LL(0x04ba1ce3,0xf4179875),LL(0xa4294fcb,0xe4a0b700),LL(0x05833496,0xb77b6e65),LL(0x8229a64f,0x204eabae),LL(0xe9137cfc,0x4ba1e0a9),LL(0x66c9fb36,0x5ece8d91),LL(0xabbbb589,0x725a0003),LL(0x62522294,0xdcc40fa3),L_(0x00000167), + LL(0xfe36c3a6,0x11953f80),LL(0xd15f704a,0x0b4cc57c),LL(0x3d3a8bb5,0x347df44d),LL(0xb5099398,0x3789e215),LL(0xd81f3a55,0x5f2bce30),LL(0x853ed011,0x0b7f91f0),LL(0x20d53ac9,0x8d7ec293),LL(0x63e7bfbe,0x8e08485b),L_(0x00000157), LL(0x56cdcd80,0xc636cf5e),LL(0x21241d8f,0x6e4c3d96),LL(0x6812f9d5,0x81fb84a8),LL(0x7741d3de,0xb50a7928),LL(0xbab3d77e,0x7cc80386),LL(0x8f374862,0x1901afee),LL(0xbf5ceb2a,0xdd95591f),LL(0xed0c8140,0x58db480a),L_(0x00000046), + LL(0xf412c36c,0x0ee07a01),LL(0x426518b8,0x54499ba5),LL(0x89e701b7,0x380c3953),LL(0xf3f8a9a9,0xd8749088),LL(0x809a3666,0xc559f6c7),LL(0xe768213d,0x64aff50b),LL(0xaad0b2e7,0x0535ff88),LL(0x68771b34,0xcb2d46cd),L_(0x0000017f), LL(0x7ec42d0f,0x4a3e7bea),LL(0xf9c7931c,0xe0127a41),LL(0xe2d8d114,0x88a09cfa),LL(0xc08a0d23,0xa27150fc),LL(0x052224fb,0x1880e3c3),LL(0xc80a285d,0xc9c2bfb6),LL(0xd52dcb46,0xfd0b235d),LL(0xfb31d609,0xc8ebb8df),L_(0x0000014b), + LL(0x058ee09e,0xf551f7ab),LL(0xd68828a3,0x85ee0c11),LL(0x6925306d,0x45a463ec),LL(0x9d6c7188,0xf851554d),LL(0x962b1441,0x66783d33),LL(0x32aca09e,0x856ca966),LL(0x9146adcd,0x5f7a7608),LL(0xfe631a24,0x269af51f),L_(0x00000087), LL(0x28d6e11e,0x0d442988),LL(0xc65a878d,0x0f8c7ce6),LL(0x332a94e8,0xf933213e),LL(0x0a2bf942,0x055f0bf3),LL(0x0e64c7cf,0x371deac5),LL(0x34d3b9fd,0x384367de),LL(0x6f42cc1a,0x15ed6027),LL(0x8f2a65d1,0x58437198),L_(0x000001ca), + LL(0x1243edd3,0x7356cd93),LL(0xc68eb0e6,0xfc213d5b),LL(0xa963c442,0xd8a42be8),LL(0x426acfcc,0x4e52c125),LL(0x3019a35c,0xcccbb098),LL(0xcbc21858,0xd433019c),LL(0x687acf0a,0x47525d0f),LL(0xce5e2216,0xe523322f),L_(0x000001cf), LL(0x88d6b26d,0x6dad247f),LL(0xa7f32d3f,0x70a43312),LL(0x340a2808,0xe2da73d8),LL(0xed020b20,0x477f5bf7),LL(0x752a7c57,0x84e84209),LL(0xaf283680,0xdce8d8d1),LL(0xf2a576b8,0x4e1b6410),LL(0x6cfe6e79,0x69ed0095),L_(0x0000008c), + LL(0xf28c9f4c,0xd2aab695),LL(0x7916e1ca,0x8e97f41e),LL(0xe9e93d40,0x40703872),LL(0xd7c8afdf,0x78640530),LL(0x8fe1f1c7,0xfb5cc433),LL(0x2060da94,0x7302096f),LL(0x953a5bfe,0x62d3763e),LL(0x4947fc61,0xeba19a33),L_(0x00000049), LL(0x92108fd5,0x8477b34f),LL(0xe9b6b7e8,0x31f306a1),LL(0x306db354,0xd16d3be6),LL(0xdf966d91,0x0deb9d15),LL(0x62b5d760,0x613eaff2),LL(0x22a569a2,0xae4f8efb),LL(0x0eeb67c4,0x9bca80a4),LL(0xac4e55dc,0x0d30055e),L_(0x00000183), + LL(0xe7b9391b,0xb559bea1),LL(0xd94e135b,0xbbc93e2a),LL(0xca27f88b,0xda4f9fae),LL(0x9fac28c9,0xe1b8ef16),LL(0x5f1ec2d6,0xfd385151),LL(0x49bb68ca,0xfb07a8a5),LL(0x55e48d66,0x146bc523),LL(0xe1490dad,0x0b9411ce),L_(0x00000010), LL(0xd3c160fa,0xec69a98d),LL(0xf736bcb4,0xb1767df2),LL(0x0bfa04f5,0x48e96045),LL(0x87d98ff0,0x977f6553),LL(0x6992858f,0x17332805),LL(0x22fe39cc,0xe8ffd592),LL(0xc326d64f,0x6551c98c),LL(0x12a83f56,0xa04ddf29),L_(0x00000192), + LL(0xdef70c89,0x5d8bd28a),LL(0xb3dcf1dc,0xe969cb6b),LL(0x157c6b46,0x846f656e),LL(0x30bef44a,0x3e3ab4ad),LL(0x14cc18c8,0x63d1dbea),LL(0x10262f96,0xfe27704f),LL(0xa567503f,0x1ff786bf),LL(0xff184f96,0x3fcb21d0),L_(0x000001f6), LL(0x92281a63,0x41b9f732),LL(0x4f7c669f,0x4f4c7a3a),LL(0xd9aab809,0x6fecf938),LL(0xece45010,0xbed97dd7),LL(0x20855b33,0x41c58421),LL(0xda8500b4,0x6bc3ec2e),LL(0xf0a33322,0xa1fd8aed),LL(0xe01eb188,0x1be357d3),L_(0x00000141), + LL(0x1799b47a,0x205f8a25),LL(0x5c7dce04,0x6bc7753c),LL(0x918feeda,0xb0bd3460),LL(0xba66aed0,0xfae70886),LL(0x5d2bdd64,0x37b93501),LL(0xa85e194e,0x12025c5a),LL(0x44f97270,0xb54faac3),LL(0x98c400c5,0x8d500c94),L_(0x00000190), LL(0xabe22aa5,0x3c01512e),LL(0x99aa80de,0xca5be145),LL(0x312f55d9,0x8dbfded4),LL(0x1ca51916,0x3f318a7b),LL(0xa0b3f9fb,0x42abfb1f),LL(0x2303713b,0x195a32bb),LL(0xb6968fd2,0x069ca809),LL(0x52819c4b,0x27ea438b),L_(0x00000079), + LL(0x662fcdd0,0xd8b1dbd1),LL(0x66c06c9a,0xaf6b6e15),LL(0x28998a9b,0xca45c4ad),LL(0x2d2005db,0xfcd947b1),LL(0x609acb17,0x6bf7b35f),LL(0x25ebaf2e,0xb8a8aba3),LL(0x599df520,0xe4302e3f),LL(0x2bf9b973,0xf871980d),L_(0x000000fd), LL(0x25aebd11,0x8868630c),LL(0xa5529c40,0xaf7c4f6b),LL(0xf5657b1a,0xc0fd49e0),LL(0x3fa70b84,0x4d86ecda),LL(0x39f53004,0xc59dce6d),LL(0x39513f7e,0xbdaf7343),LL(0x822c2924,0xce22dd61),LL(0xacb0786e,0x78182466),L_(0x00000054), +}, +/* digit=22 base_pwr=2^110 */ +{ + LL(0x55dedb27,0x5a0fc338),LL(0x03e8af53,0x788ccd88),LL(0xe10cabd0,0xa1f1f7d6),LL(0x5f889d7f,0x0487ee35),LL(0xa583e303,0x1885d800),LL(0x2fc9f3dd,0x09ae9a4a),LL(0x2887b5bf,0xa554fc30),LL(0xd91181d3,0x1d189678),L_(0x000001e4), LL(0x53b146d6,0x52f280d5),LL(0xdfaac466,0xe0b73d63),LL(0x0d77869d,0xa8a399cd),LL(0xba5ffe6a,0x5c61b757),LL(0xaffc1da6,0x71cf6c9e),LL(0x34d27387,0x20ae1248),LL(0xf184b956,0x7f6504de),LL(0x1c974cb4,0x94c62d76),L_(0x0000019b), + LL(0x659b9b53,0xd37156ff),LL(0xf8338bab,0xa115d2c7),LL(0x9d1175b5,0xa927371c),LL(0x53c22d6a,0xe5b07da3),LL(0xb79ee37b,0x3585421c),LL(0x8ac92029,0xbe2b0a93),LL(0xd489e47a,0x363622f3),LL(0xccd5811b,0xdf568ac9),L_(0x00000183), LL(0x41cb54f0,0xbf83fb74),LL(0x527b4fee,0x7d9fa2d5),LL(0x6d4a3597,0xf8ab4037),LL(0xe4619c87,0xd590e945),LL(0xab913b27,0xe8861075),LL(0x389b1da0,0xd8fb707f),LL(0xe0beb49d,0x35140b6f),LL(0x392dd172,0x0d587bf7),L_(0x000001ea), + LL(0xbf4176d0,0xfe15067e),LL(0x0120bf23,0xc1d45172),LL(0x0cb82143,0xfbe2cf59),LL(0xb0e80076,0xd69fd57c),LL(0xbd9b2caa,0x78503bca),LL(0x99823d72,0x2730e435),LL(0x31cc7be0,0x4b145b24),LL(0x10f8d6e3,0x7db8fea2),L_(0x000001cf), LL(0x4fc47dab,0x7a72c91b),LL(0x564e5846,0x5530b4bc),LL(0x1837936f,0x9913d2c3),LL(0xdf60105f,0x5f1a5851),LL(0x839ef0be,0x3d6d7b8d),LL(0x05890a65,0x48845fee),LL(0x57eb20fa,0xcc1288ca),LL(0xf7b7e05b,0xbf1a3cac),L_(0x0000015a), + LL(0x7082a01c,0x50e34426),LL(0x91616bf5,0x27cfd7b1),LL(0x426bd9ae,0xc299bf54),LL(0x5f468d0e,0x0487ca37),LL(0x695e6354,0xb93aa7dc),LL(0x9322f558,0x8f48edec),LL(0x818f0592,0x957ee742),LL(0xaca5b088,0x248afd23),L_(0x000001be), LL(0x11189720,0x45a01307),LL(0x348cb9e4,0x5bf246e5),LL(0xf5c183c6,0x3fd8ccf1),LL(0xe9a40aeb,0x0fbda6f2),LL(0x087abdef,0xdaf09cee),LL(0x90c450f5,0xe33344ee),LL(0x3abe1073,0xa3404424),LL(0x02a065d1,0x011c8b8f),L_(0x0000010a), + LL(0x5faa9290,0xbd275c4d),LL(0x69ab8c9c,0xebf0d548),LL(0x7a6bc4a9,0xe5ed16cd),LL(0x31faf28e,0x3e681735),LL(0xcf90331c,0xc624be8b),LL(0xfb66de1c,0x42603696),LL(0x2a65b006,0xc07466ec),LL(0x9d7f9688,0x84d634f3),L_(0x0000013b), LL(0x44e0d6d8,0x3db25f9e),LL(0xe7ca860d,0xa581c150),LL(0x1c6481b3,0x49e5b0b8),LL(0x62060736,0x82bc7eb1),LL(0x54daac9c,0x376c43d1),LL(0x68353454,0xfb293af5),LL(0x2dde1795,0x7e2ec37f),LL(0xed4ef8f0,0xbefc779b),L_(0x000001a4), + LL(0x4adfcff9,0x2b928ce2),LL(0xb2e63ba3,0xd02f461c),LL(0x73336d0f,0x04fd6cc5),LL(0x48e88a3a,0xc377597d),LL(0x56c730e8,0x5ac92cdd),LL(0xaf7486b7,0x0317d853),LL(0xe151b910,0x0978da40),LL(0x86c35051,0x6108c40e),L_(0x00000134), LL(0xb333edf0,0x1ff77a8a),LL(0xd24f0df5,0xed7f23b9),LL(0xdfae6385,0xaa4f024f),LL(0x2a1af93e,0x2ffef5f6),LL(0x6f45d8a5,0x9aa11e63),LL(0x853bb088,0x2271f40e),LL(0x8ed5445f,0x3ccb38c1),LL(0x24afc179,0x6883bc27),L_(0x000001d3), + LL(0x57906522,0x85f7ceb0),LL(0xce569864,0x059b3177),LL(0x45f8df95,0x60efada7),LL(0x2ee7a947,0x87aafc1c),LL(0xdce2c588,0x17fd804d),LL(0xdcf2f1ac,0x10e82f62),LL(0x4b1309c3,0xe852efd4),LL(0x0ef30c42,0x8810a12f),L_(0x000000d4), LL(0x95ed2fc9,0x55cd2f37),LL(0x5d0e9c83,0x107085fd),LL(0x479d2ac2,0x85ff5e6a),LL(0x7bd3eb35,0xd6ed74ec),LL(0xc8a77d96,0x366d8e34),LL(0x3be40939,0xf0ec3c90),LL(0x11212f04,0xc317d540),LL(0x5743bb20,0x4f1fdd52),L_(0x000000c4), + LL(0xffb66d41,0x6ea70c3f),LL(0xc5491789,0xcb17d54f),LL(0x1eaf6e4d,0x7c642a64),LL(0xb15be10c,0x99328296),LL(0x611efe5f,0x30829e9c),LL(0x3cdec049,0x5f18e861),LL(0x1a7c38da,0xab7985a5),LL(0x3536d908,0x8a46db8f),L_(0x00000102), LL(0x8ece50b4,0x5435f6e4),LL(0x13d04672,0x60505d74),LL(0x07efc4e5,0x8a551fa9),LL(0xcc601ad2,0x8fed3391),LL(0x9eeaf4b1,0x4338a854),LL(0x72c52e1a,0x61868d33),LL(0xce70bb6b,0x9c3a511b),LL(0x5c8d75eb,0xf313ce1f),L_(0x0000008f), + LL(0x69ee64f3,0x508ada39),LL(0xdd8c7134,0xda598cbd),LL(0x36c545ec,0x05133eca),LL(0x0c3f5caf,0x2df79eab),LL(0x71cd5c2a,0x920bc258),LL(0xfa67ae73,0x1fd1e4a4),LL(0x2ed2d89b,0x48726f90),LL(0xd5a8956c,0x2a4c3dab),L_(0x0000011a), LL(0x6f23ba5d,0xb20e4dfc),LL(0x4bab12af,0x5fcc6747),LL(0x0006c88a,0xaa6ea9a8),LL(0xe8e4646f,0x9db86f5a),LL(0x8f1f8a76,0xec7745fa),LL(0x455291dc,0xe15a4259),LL(0x155de9ad,0x6c3a6e93),LL(0xf9fdf6e0,0x54f6c4df),L_(0x00000005), + LL(0x3dc752ef,0x14921ae6),LL(0xdad5624e,0xf829dec8),LL(0x1d1460ab,0x5833de5b),LL(0x9c1ff203,0xd5ded33e),LL(0xfac09cf2,0xbb7c2ad4),LL(0x82d6f980,0xf32dbe91),LL(0xad650ca0,0x82ca75ed),LL(0x6c58e180,0x360a9033),L_(0x00000156), LL(0xea9d2225,0xd3ca85cc),LL(0x434cfef1,0x3bb6dff7),LL(0xce357f60,0x56328ba9),LL(0x0e4a179e,0x4a4804e3),LL(0xe56b9eac,0x254a5b01),LL(0x72a81cd7,0x8b35d349),LL(0xe054875e,0xc8c87ac4),LL(0xe8c11607,0xfef9a015),L_(0x00000001), + LL(0x1c6cc43f,0x6f96d167),LL(0x794436fa,0x586761cb),LL(0xd20a52b3,0x3ae24479),LL(0xc24cf7e8,0x5d299550),LL(0x7aabd2b7,0x9cea4b13),LL(0x09feb305,0xd75ffb4e),LL(0x5b6a28d7,0x5d3cd9c7),LL(0x4d85737b,0x3f800863),L_(0x00000186), LL(0x743b9f5d,0xe042f5f5),LL(0xe03225a4,0xc7dc3d4b),LL(0xdfce41ae,0x51cdf46c),LL(0xd3c05da2,0x69bf3a35),LL(0xc18cbac7,0xc0889d43),LL(0x51fc0084,0xf694d481),LL(0xbfa4cfd4,0x05438a3a),LL(0xcb44f4a9,0x037fbdcc),L_(0x0000003c), + LL(0x22d68d2a,0x6f65a633),LL(0xd77949bf,0x368db479),LL(0x738f46ed,0xe52e22f5),LL(0x7212d465,0x4758d194),LL(0x8bb783e2,0xd677a59c),LL(0x1b239d33,0x60904604),LL(0x9c2f2775,0x8df6497a),LL(0x9be5339a,0xfc0bbe7a),L_(0x0000007c), LL(0xb5804d78,0xbd5cd190),LL(0xbfbebfb6,0xd58769b6),LL(0x66d25685,0xf9ea5b23),LL(0x206ac283,0x09d14a84),LL(0x845e93a9,0xe03b612f),LL(0xc6807818,0x061fa312),LL(0xeb980705,0x6b501efd),LL(0xfa3670b6,0x8ea0643c),L_(0x00000010), + LL(0x509702e1,0xaf686102),LL(0xc4201f85,0x800e44cf),LL(0x7e6e7641,0x35e4ed58),LL(0xa3fd838b,0x5af78edd),LL(0x728e86da,0x0effaedc),LL(0x6fd05e38,0xfd668fa4),LL(0x4ebcbbb8,0xe45dbf60),LL(0x21bf82d8,0xafb31f6c),L_(0x000000c4), LL(0xf066dcdf,0x1ca3b2b7),LL(0x73890298,0x96fc550c),LL(0xcc4f19d8,0xfc004a6a),LL(0xc9fae54f,0xcdd730f4),LL(0xa5e22c5e,0x2754c10a),LL(0xb60dac89,0x49c473e4),LL(0xd5465b8b,0x30fa2831),LL(0x14688f19,0xa1a65375),L_(0x00000100), + LL(0x8f88f135,0x7034290c),LL(0x2f4cd77e,0x61556d3d),LL(0xe5aea948,0xee182466),LL(0xf7fd60b4,0xfaab2132),LL(0x2107919a,0xb164b7c6),LL(0x4909986e,0xb4de2fa4),LL(0xe1076a94,0x331fc36a),LL(0x8fd3234a,0xadcb78d4),L_(0x0000009f), LL(0x07524382,0x3f9109b1),LL(0xec9a0d40,0x11cb9eb3),LL(0x7e1084f2,0x1e06d740),LL(0x00717031,0x2928ea89),LL(0x4bde88cb,0xd69d113b),LL(0x20f91a03,0x2ff2dbf3),LL(0x7a3884fc,0xdf24441f),LL(0x198806cf,0x69d88d2a),L_(0x000001dc), + LL(0x076f7438,0x1544e142),LL(0x15274247,0x022e14c5),LL(0x96077c3c,0x30862489),LL(0x789e3935,0x50c53e4e),LL(0x1141fcf3,0x3047c405),LL(0x2cd7f2a5,0x57a60daf),LL(0x9bc52e3e,0xcd0ce692),LL(0x21830d42,0x6d7217a9),L_(0x000001f3), LL(0x77ac72bb,0x403e48dc),LL(0xad70038c,0xc084214e),LL(0x170491ff,0xf7b0b5fe),LL(0xd8cf2d1c,0x4af0ed5d),LL(0xd8301c30,0x00208a5b),LL(0x33f56a54,0x18e018d4),LL(0xfa224eea,0xef56c21e),LL(0xaa9262c2,0x692f082d),L_(0x0000006e), + LL(0x328296f3,0x4bb11c1f),LL(0x6050199a,0x15b40849),LL(0x53a7ca7c,0x81bc50ce),LL(0x0a2c1da2,0x682873f5),LL(0x52c0e34f,0x44102170),LL(0x9c5ef21f,0x9f354fbc),LL(0x0bba954e,0x6cd7990a),LL(0x02432a32,0x37dabca4),L_(0x00000019), LL(0x2be6dddd,0xe55cac7b),LL(0x8a3b8a57,0xda37392c),LL(0xec1dc93e,0x2e3fecd4),LL(0xcf4f78c9,0xfedf3f09),LL(0x1ff689fe,0x03374052),LL(0x092dabd5,0xdf4087ca),LL(0xb9e4e110,0x9d02763e),LL(0xf3f329b7,0xdaeda689),L_(0x0000012e), +}, +/* digit=23 base_pwr=2^115 */ +{ + LL(0xbd54382d,0x826f7b17),LL(0x32c36ec7,0xdce64f28),LL(0x22a16680,0xab2193ae),LL(0xaf6a85c2,0x52cc0a0a),LL(0x2f202702,0xcc1335b3),LL(0x2afbf317,0x3743776e),LL(0x0deb4740,0xf9a19900),LL(0x61591f25,0xd91b36bc),L_(0x00000002), LL(0x1d84eebf,0xb06a4eb6),LL(0x8bb72608,0xb23e7396),LL(0x2e886104,0x992a3ae8),LL(0x7c8605d2,0x418a91d2),LL(0xe33bec6e,0x5f2b49e6),LL(0xa9d829d4,0xd1f4a3f4),LL(0xeb2f044b,0x28bc4cea),LL(0xb1ef09fa,0x00e53c63),L_(0x00000050), + LL(0x04826845,0x6b1ee54a),LL(0x9240015b,0x608b1dc0),LL(0x25698b8a,0xa1390509),LL(0xb5e532ad,0xdf4acb31),LL(0x30c41c46,0x16e05bee),LL(0x07d190c1,0x642c1273),LL(0xb566eca9,0x1b365a48),LL(0x5c3cffa2,0x3f2fc46d),L_(0x000000c2), LL(0x21b8836b,0xa0057686),LL(0x520f579e,0x7bf51510),LL(0xa43d38cb,0x0a4bbc0c),LL(0xfe21891a,0x687446c9),LL(0x1242b093,0x8feab881),LL(0xcacb6d61,0x7a921f31),LL(0xcf611aa4,0xc5cb09d3),LL(0xfef9a8ef,0xa83137d8),L_(0x0000012e), + LL(0x4375da6c,0x13287748),LL(0x4fda63b3,0xfa3518ec),LL(0xbc16ce7a,0x996ffb04),LL(0xf3ffb5fd,0xf0a2d30e),LL(0x6da8bb6d,0xa23e83a8),LL(0x08e806aa,0x0642e4da),LL(0x0286c1dc,0x84837dcb),LL(0x8196eb23,0x999ea9ac),L_(0x00000060), LL(0x1c8d1ec4,0x9c108506),LL(0x77ca438c,0xdc8649fb),LL(0xdbfc198f,0xaf929bb8),LL(0xa5fbf701,0x60078f43),LL(0xe25fdf9d,0x3f03bcb4),LL(0xca36812b,0x53c1eaae),LL(0xb394d3a9,0x1f8445ff),LL(0x78a7b4ab,0x8305bbeb),L_(0x000000b0), + LL(0x6d42c81a,0x40e01936),LL(0x7487e815,0xd6072e7b),LL(0x32da913c,0xe7b4156c),LL(0xf1e87478,0xb217423d),LL(0x4880f5cc,0xca344dd5),LL(0x90182347,0x15da2c26),LL(0x87d2337d,0x8d993e28),LL(0x604cc23f,0x0e937379),L_(0x000001ea), LL(0xf9778d40,0xc9dd1808),LL(0x4345027e,0xdcd7b63f),LL(0x198a63ab,0x03bcf65f),LL(0xa7a4c388,0x1130c2d3),LL(0xb476f99f,0xc1ea5019),LL(0x991ad6b9,0x4f67377e),LL(0xa9f5ad13,0xd99047df),LL(0x80641e2f,0xd93815dc),L_(0x00000185), + LL(0x2a4af296,0xf45a67c1),LL(0x963ea378,0x3fc32889),LL(0xe19e2266,0x2477017e),LL(0x3e1c3af5,0x1bbfecd7),LL(0x9c6aea32,0x03afdf5f),LL(0xdd92f5ef,0xd2ffd177),LL(0xcff66e71,0x22d56579),LL(0xca369a53,0x098e3322),L_(0x000001b9), LL(0x3ecebaa8,0x87cbd3db),LL(0xfef4d6ca,0x92b7d8a0),LL(0xf81b8c47,0x4e50ecbb),LL(0xdd6768bf,0x916361ed),LL(0xf3c09bf3,0x6b31d1bf),LL(0x54e2879b,0x17c7f544),LL(0x44b470e7,0xb6fa811a),LL(0x32df7372,0x135177e9),L_(0x000000ad), + LL(0x83de0d9d,0x7ea57102),LL(0x4652ceba,0xdd543523),LL(0xb8a36856,0xb586f821),LL(0x19e00261,0x6ce309c3),LL(0x1ed079e5,0xe0f75ac3),LL(0x51ff1099,0x2442020d),LL(0x0c077aee,0x248b83fa),LL(0xc85e1f87,0xf5eebe6f),L_(0x000001f4), LL(0xaf872b79,0x311d3108),LL(0x2ca2a32b,0x5040c97d),LL(0x4fa4c2f0,0x7615703d),LL(0x80d5eb27,0x36c8c169),LL(0xb5f074a5,0x95daa1e3),LL(0xbda91813,0x672dad89),LL(0x395bd4fb,0xf61f3d94),LL(0xc4a2c81e,0x8ba214b4),L_(0x00000108), + LL(0x04e91ed9,0x861a2094),LL(0x2bca8d77,0xca4ca01a),LL(0x03590793,0xf16fc210),LL(0xc8ad1877,0x48a85346),LL(0x89666be4,0xf0fc0cfc),LL(0x6adba857,0xcd27d0e4),LL(0xdc6000be,0x66de6f3c),LL(0x410cd2f9,0x701dbfa3),L_(0x00000143), LL(0x27a30017,0x3566e721),LL(0x523a0305,0x793773f0),LL(0x1ee9afff,0x7fd66850),LL(0xdbc711c7,0x047ae5ad),LL(0x3acae945,0x203bb8df),LL(0xb932a42c,0xfe2439ff),LL(0xd51dba9f,0xe4630688),LL(0x268de595,0x2e9ee036),L_(0x0000012e), + LL(0xcb924e78,0xf61f664c),LL(0x2e404ee4,0x5ac67cb0),LL(0x6b002de5,0x87550da7),LL(0x537e3c3c,0xb6b43fc4),LL(0xcc36c052,0xb2d5ce01),LL(0x0c5bb204,0x8e7f6d0e),LL(0xf930fde8,0x09c188bb),LL(0x056f87d9,0xff08d168),L_(0x000000ad), LL(0xbd1106b6,0xe76203aa),LL(0x0182e8dc,0x02fff311),LL(0x1307d3fa,0x96bf7d1e),LL(0x71013392,0x6ed2ca34),LL(0x24a22e45,0x1b668eed),LL(0xe4102d01,0x79cf95e5),LL(0x681d10cb,0x6c6693b0),LL(0xf94e08ac,0x7a740355),L_(0x000000d1), + LL(0x4ea63be4,0x7d917da9),LL(0x5de2c336,0xadecf30f),LL(0x0955c66b,0x81dabb28),LL(0x6e473865,0x19491209),LL(0x1d9702d7,0xa1f53ee2),LL(0xa4bef482,0x26877597),LL(0x0315b12f,0x18b70eae),LL(0xbca15f03,0x5864f695),L_(0x000001d8), LL(0xe0496daa,0x1afe44da),LL(0x518d4571,0x824106af),LL(0xf72d3376,0xa6b1f64c),LL(0x1149d145,0xbe64f34b),LL(0x8c71ca30,0xd7b0b0f7),LL(0x3acfa7a5,0x58a3ea6e),LL(0xcc0bc394,0x5e42d97e),LL(0xe6ba0355,0xb8a8749f),L_(0x00000051), + LL(0xcc323242,0x25b57cdb),LL(0x0afacd89,0x4d31e696),LL(0x075e88b1,0x80ecc1c8),LL(0x4d853d58,0xe213393a),LL(0x5c2d17b4,0x1d02b340),LL(0x29f6c35a,0x7f4eb22a),LL(0x763f945f,0x991b6570),LL(0x38d9e916,0x8274a08a),L_(0x00000172), LL(0x919e262a,0xcdb707d0),LL(0x7b3ccd89,0xc28362e2),LL(0xe31adec3,0xd970a8d2),LL(0x2e5340b0,0x11f1ff4f),LL(0xb76d44ac,0x42bd388a),LL(0x528cddee,0x2165e718),LL(0x7cb055f5,0xa8c2384a),LL(0xd81cae87,0x5ee96e3b),L_(0x0000011f), + LL(0x95c8885f,0x504d777f),LL(0x6a9d125d,0x327807d9),LL(0xd624f272,0x0e53c679),LL(0x95ea222f,0xe1387ac7),LL(0xb1597752,0x656acd9a),LL(0x352cac8c,0x6190d15d),LL(0x61bf8856,0x01af7e20),LL(0xc719ce43,0x14d8c07b),L_(0x00000194), LL(0x83f36452,0xfdd73cd6),LL(0x314de5cf,0x46e7aa4c),LL(0x50ce899f,0x7424d707),LL(0x38e875fc,0x3221445c),LL(0x9f3a7a99,0x974ba6c9),LL(0xe06eb667,0xcc871495),LL(0xffe48ed2,0xda22c28b),LL(0x34965180,0x95e30bbd),L_(0x0000007e), + LL(0x8ee0ef29,0xfb175926),LL(0x1c82db3e,0x93d33d24),LL(0xb912da50,0xbb15ebc6),LL(0xcea7d557,0x53132904),LL(0x2a95c0c2,0x1728bce5),LL(0xd703338d,0x3e934774),LL(0x9ff62322,0xa4bdaa17),LL(0x5a25267e,0xfd8b69c0),L_(0x0000000c), LL(0x4db3f1bf,0x49cf21d2),LL(0xa18c0ec0,0x1567c730),LL(0xf359d391,0x8f78c3e0),LL(0xa1bf7eca,0x9f9aa64e),LL(0x4252d4d8,0x5b2ffd6d),LL(0x3cf77a2e,0x70d5197d),LL(0x420f1fde,0xc4ac046e),LL(0xfbaabfd6,0x197eef82),L_(0x00000092), + LL(0x6f164190,0xacca9818),LL(0xdc3afb13,0x75acc7ba),LL(0xf8e7944e,0xaec6267e),LL(0x266c89d3,0xc0d5983e),LL(0x7a35b6ea,0xc7025ed3),LL(0xcc6f8ba4,0xb3a78dfe),LL(0xe18e7845,0x43ed79a0),LL(0xd3e423c7,0x9847da1e),L_(0x00000022), LL(0x7ad878cd,0xf2ddd3e7),LL(0x7ad2ccc8,0xdd3af93f),LL(0xe988a2b1,0xc20e3266),LL(0xf31777a1,0xc508e478),LL(0x5f61decf,0x6ca64937),LL(0x38c983d0,0x63f7f656),LL(0xffbb003b,0xff837029),LL(0x32104839,0xc4d50105),L_(0x000001ee), + LL(0x0f23d833,0x787960d2),LL(0x1a82d064,0x1e23da2c),LL(0xf31fd1ab,0x632fca0d),LL(0x67beaa32,0x48f5480d),LL(0xb9e45d26,0xbb162f9b),LL(0xd434d563,0x10e02089),LL(0xa10eef01,0x647082d3),LL(0xb7735d1d,0x03650cb7),L_(0x0000017f), LL(0x40d95b89,0xe61d29d9),LL(0x68b4d3bb,0x1c7d5b4e),LL(0xd78df4bc,0xbd612a5a),LL(0xd83302ca,0x80982747),LL(0x511140b2,0x754f6279),LL(0x16e7211a,0x1d43610e),LL(0xf0dec954,0x3999e665),LL(0xbaca9f0f,0x3cdd9ee6),L_(0x000000e0), + LL(0x38877144,0x1ee1b012),LL(0xed46bb99,0xf5e943b8),LL(0x376d8b60,0x1bc6b4d7),LL(0x4b6cb863,0x7dc297da),LL(0x216481d0,0x123486d4),LL(0xc754e76d,0xb1c0a1e8),LL(0xdbcf937b,0xadf930fc),LL(0xdaf06ef4,0xa5ef1b3b),L_(0x000000c3), LL(0x03210a22,0x979dbfb5),LL(0xd444dbbf,0xd232212a),LL(0xef6c2520,0x35e7b199),LL(0xee0108b0,0x21bd8267),LL(0xe6dba29f,0xc9483241),LL(0x8b0b6ada,0x304a26d8),LL(0xebc36edd,0x88b58b4d),LL(0x0b4cd577,0x6441b89d),L_(0x00000108), + LL(0xee657257,0x208861aa),LL(0x5d4bf915,0x8adfc02b),LL(0x8b2a8792,0x51bf7839),LL(0xd1929e39,0x6ac2d82c),LL(0x51878fc6,0x2453f26a),LL(0x67c6a197,0x0ebd963c),LL(0x29e6f9cc,0xab6feb88),LL(0x6a8aecc7,0xb24a4c98),L_(0x00000165), LL(0x9f30636d,0xe6a5beb0),LL(0x5f6af11d,0x247b3767),LL(0xa04301fc,0x7893d122),LL(0x577167d7,0x4d974f3f),LL(0xea69addd,0x983fc60d),LL(0xd35bf8be,0x627055a8),LL(0x95c80a83,0x51c83aaf),LL(0xa21f06b1,0xee9e2a9a),L_(0x0000011b), +}, +/* digit=24 base_pwr=2^120 */ +{ + LL(0x1dc1e136,0x3cf04eac),LL(0x1c4f5e85,0x599f9890),LL(0xcbc44867,0x34ff0e3e),LL(0x5a12a7f8,0x851c12ee),LL(0xf066c152,0x7ca61be6),LL(0x73832df9,0x7153da2c),LL(0x14acdbe2,0xb73e882e),LL(0x87567338,0x9a4f930b),L_(0x000000cc), LL(0xd1fe8148,0x05fd56d3),LL(0x49ee53a4,0xe986a7db),LL(0x11101981,0x695cf7bc),LL(0x750760e2,0xb6aca2a9),LL(0x4815cb90,0x9f5ace2a),LL(0xc3dc9f29,0x6b06b61b),LL(0x3b28698d,0x6b2e5c22),LL(0x5687880a,0xb6015c0b),L_(0x000001bc), + LL(0x1af552c0,0xaaadcddf),LL(0x160c329a,0xf071e91a),LL(0x77f33e93,0xf9cbbaf7),LL(0x6e836178,0x74f3bc69),LL(0x430ecc6d,0x349ec647),LL(0x9e682571,0xbbec63ff),LL(0x3f624e0d,0x64eff8b4),LL(0x0d19e23a,0xab39a800),L_(0x000001cb), LL(0xce60d534,0x3eff3832),LL(0xe89d00d8,0x12f600da),LL(0xf8745dbd,0x3eb89d2d),LL(0x48217cd8,0xe79b868a),LL(0xc5ce0f8a,0xc2c4ae44),LL(0x0fe94021,0xa980ca2b),LL(0x5ab9482e,0xf0414674),LL(0xcffa33fc,0x96a9f1c2),L_(0x00000109), + LL(0xb176fd51,0xa2b01fa7),LL(0xbebf27e3,0x1a17875c),LL(0xca98073a,0x1a08df20),LL(0x73873253,0xcea9581c),LL(0xdc360b05,0xbad316bf),LL(0xb8a68986,0x9591db5f),LL(0x6941db20,0x838ce851),LL(0x0df495ad,0x337f3cd5),L_(0x000001fb), LL(0xb5d46b24,0xf0d09b27),LL(0xf2b04a4a,0xe34ef392),LL(0xc4e0cb50,0x9c028d0c),LL(0xbe127061,0x60b8995b),LL(0x202d9276,0xa9beaf92),LL(0x3a61c444,0x686effea),LL(0x7cc238c3,0xce321e42),LL(0x09075147,0x65266fe6),L_(0x0000014b), + LL(0x16e9dd16,0x8a3599a2),LL(0x05317187,0x0821091d),LL(0x24ef2697,0x6ed2cda3),LL(0x4950f2f1,0xeaefd2e9),LL(0xc815b553,0x9f00612d),LL(0x47c1f801,0x930eacc5),LL(0xfd1730a1,0x136fc4a1),LL(0x8252d52d,0xc56a7db8),L_(0x00000098), LL(0x6b77522a,0x2deb3842),LL(0xaea9f6b1,0xca869197),LL(0x3823d16a,0x187c4319),LL(0xf12c9d38,0xd5cc9828),LL(0xe31f43da,0x436529c3),LL(0x0781728a,0x63d40c6f),LL(0xbfbb0978,0x94da1798),LL(0x7a196933,0x97dcd1e1),L_(0x000000d8), + LL(0x95a20633,0x4ce60573),LL(0x98b05888,0xb9e9ac42),LL(0x9f28e7bc,0x770f80c7),LL(0xabb15751,0xd0147212),LL(0xcce75763,0x67296f82),LL(0x8034afbe,0xa2950d9f),LL(0x11791412,0x9731ca6f),LL(0x87c616f9,0x1f16d8bb),L_(0x00000104), LL(0xc7f27dc8,0x5fa5d017),LL(0x95bcc4fc,0x9fdb4deb),LL(0x39917e40,0x30051c1e),LL(0xbefa777d,0x3f36dfcf),LL(0x26ebd51f,0xd9696a85),LL(0x16cc089e,0x58a6c0bc),LL(0x6723f03c,0x3193efb5),LL(0xe4f7a675,0x97abbf77),L_(0x00000000), + LL(0x0082edbf,0x7ff0d41a),LL(0x1522ffb6,0x76aa53cf),LL(0x453dcda7,0x3ac99dda),LL(0x634bcd8a,0xca31a6bf),LL(0xdf09af12,0xda6aee65),LL(0xb96045d3,0xb2e1c131),LL(0x6f3c7e70,0x72188816),LL(0xcb58f8b9,0x9a1f5d21),L_(0x000000c7), LL(0x51f3e032,0xd4da7b11),LL(0xcafbe9a8,0xe3a95788),LL(0x39c010af,0x8c87071e),LL(0x05cb3faf,0xafcfc04b),LL(0x08a702fb,0x42c775b7),LL(0x5b3b6187,0x8aab53d6),LL(0xb84f9386,0x8bb27ffb),LL(0x08491b70,0x9bf23a75),L_(0x0000003b), + LL(0x2f20328d,0xb581eaa6),LL(0xd269e274,0x8fb2a285),LL(0x604b1779,0x5b26ea89),LL(0x3aa53ad7,0xd5119e93),LL(0x9fa62691,0x3e002a94),LL(0x8ba167e0,0x62921501),LL(0x195dffb0,0xe4ae2796),LL(0xdc1f93ea,0x2bba3282),L_(0x00000096), LL(0x980977c6,0x654950f7),LL(0x422ba8f7,0x9f0fcf77),LL(0xb7dc1d4c,0x6b970562),LL(0x0b2f7617,0x2de6068f),LL(0x894ad6c1,0xd3457950),LL(0xe569d53d,0xfc63f78f),LL(0x14981ae1,0xf2a90b52),LL(0x902dadf9,0xee87e5ab),L_(0x0000003e), + LL(0x5406fc86,0xc759885f),LL(0x5bd2a491,0x2d4cddc5),LL(0xc35aa122,0xb5461045),LL(0x2154985e,0x188b457a),LL(0xff0dcbe4,0x235148df),LL(0xd70c6a7e,0xa2535a30),LL(0x7d8e9016,0x6be2be33),LL(0x99a19ee9,0x8e953cf8),L_(0x000001ae), LL(0xa1dc1860,0x519771ba),LL(0xea4c9a1d,0xe6bf7f8d),LL(0xc44825c6,0xfd4b88d5),LL(0x48270d80,0x619d7b16),LL(0xcd7c088d,0x50ac4887),LL(0xcc2ce67f,0xd1ac72f9),LL(0xaafa6b89,0xafdce091),LL(0xb9365de8,0xe061fac9),L_(0x000000e8), + LL(0x7862482b,0x264a6de7),LL(0xcc327c76,0xf0e8036a),LL(0xdd64bd2f,0x58aff74c),LL(0xd63e620b,0x0d34c089),LL(0x792f3b2b,0x3cffd08d),LL(0xb8e40e30,0x2466d774),LL(0x5be025a8,0x83e235d8),LL(0xe9d3cf63,0x87a2f8e7),L_(0x0000016e), LL(0x93020cb2,0xfef8d504),LL(0x75b3c700,0xa8404df1),LL(0x1f7b3ca4,0x25cfc4f3),LL(0x3dca1055,0x21fc5f18),LL(0x73402205,0x096d5dd9),LL(0xf8afba2b,0xe13c530e),LL(0x23634751,0x7b6b3f2e),LL(0xca1be461,0x93159c76),L_(0x00000162), + LL(0x662154b2,0xf439d6d1),LL(0xc1e155ac,0x0ae5f642),LL(0xa2dd72ce,0x55e79db1),LL(0x71c8da23,0x7905f65a),LL(0x29ffbd0d,0x21383ef6),LL(0x39515d47,0x28c8f708),LL(0x739d692e,0x67130a0a),LL(0xe8283125,0x9d6fd698),L_(0x000000a8), LL(0xe6e2797b,0x7f499c43),LL(0x57f047a7,0x8571cbc2),LL(0xe0447784,0x8f068f3b),LL(0x85efc6b1,0x9497bb27),LL(0x4b52e9d2,0x5f954c9e),LL(0x896bc179,0x299e982a),LL(0xfe335eac,0x2fe557d1),LL(0x15ed5037,0x714710c8),L_(0x0000011d), + LL(0x45022f8e,0xe4a9bc90),LL(0xcb58c8df,0xd48d6951),LL(0xf9950f95,0x3a67fa88),LL(0xcfc52411,0x8aad81c0),LL(0xea907dba,0x193feef4),LL(0xbcf6e329,0x847c4744),LL(0x51539dcb,0xbfaf49f8),LL(0xe1705ff1,0x79078f89),L_(0x00000187), LL(0x7e920920,0x93070144),LL(0xf4a966bf,0xebc39792),LL(0x26b6e21a,0x5380b22b),LL(0xe6fd22df,0xf5ce884f),LL(0x866ea333,0xbbd94169),LL(0x3e0f11de,0x3a3c3087),LL(0x2fd9dd8d,0xefe676ed),LL(0x227a4771,0x250b4a16),L_(0x000001d2), + LL(0xe1817fcc,0x7ff2aece),LL(0xe4758b83,0x15a3e785),LL(0x768947ca,0x54660e77),LL(0x2c352eca,0x1486538c),LL(0xaac39b78,0x86e8fec5),LL(0xaa608004,0x414e550f),LL(0x32acb85c,0xa6493364),LL(0x2fd7f2f3,0x3d144499),L_(0x00000085), LL(0x92784c4d,0xcdd72f6c),LL(0x18258546,0x7a0d4685),LL(0xabc0f043,0xa00c87a4),LL(0xfab6104e,0xd492feca),LL(0x0edfb4e6,0xd10ae319),LL(0xa0ad3d18,0x74331002),LL(0xb3e27cea,0x1c928b0f),LL(0x43d33a89,0xb7eaffcb),L_(0x00000056), + LL(0x7f32173f,0x5c89c248),LL(0x82306719,0xa569342d),LL(0x5318cae6,0xaf11c888),LL(0xb3871b59,0x43ea3a04),LL(0xccb1894e,0x7d6e369f),LL(0x584ca2b8,0x4a0018e5),LL(0x01476d73,0xc7bd79b4),LL(0x6328258d,0xed62337f),L_(0x00000095), LL(0x607af994,0x27381ef0),LL(0x686aee98,0x28efc122),LL(0xe773f07b,0x1e1202b4),LL(0xb162dfca,0xd4141270),LL(0xfcd08076,0xdb1eed20),LL(0xd4dbdbd9,0xec8f2a2a),LL(0x31a47c86,0x153d8ef2),LL(0x74c6410f,0x33a76f22),L_(0x000001f8), + LL(0x0b272d33,0xb7894299),LL(0x2ade0047,0x7215a462),LL(0x8525f896,0xe97dd7d4),LL(0x8faa7fcd,0xf320c207),LL(0x2aaff4f3,0xce32f0aa),LL(0xf98216e5,0xe5a62be1),LL(0x4be7ec71,0x057e6071),LL(0xe8262bc9,0xd6f6ecc9),L_(0x000000e4), LL(0xe0348118,0x1e1c1702),LL(0x67b5b771,0x61dc410d),LL(0x540bfa59,0x52daedcf),LL(0x722428bd,0xa96118aa),LL(0xced4360f,0xaa07a68e),LL(0xd1ae09f8,0x4870992b),LL(0x98c1f34f,0xf97358de),LL(0xea267e80,0x8837a9e0),L_(0x00000086), + LL(0xb75d5e00,0xba7367a8),LL(0xcb6a4c5d,0x698ec043),LL(0xc4a8a172,0x58a0e780),LL(0x1c52f090,0x45a0c118),LL(0x7ba85810,0x41f652a4),LL(0x261486ed,0x14a0dead),LL(0xe61b0bd4,0x4a38be55),LL(0x881f7207,0x554bf84d),L_(0x000000fb), LL(0xb678cf5d,0x8cf0f2b1),LL(0x1c805e0f,0x50bc855f),LL(0x4c9f70d9,0xab5b49a8),LL(0x82a11ee6,0xbf5c0c4e),LL(0xecca8fd8,0x30c1e91a),LL(0x40104321,0x3bccd5ea),LL(0xf20e8305,0x7cc38a3b),LL(0xa89c9d80,0xf84d4b44),L_(0x0000008d), + LL(0x6dc98840,0x33535047),LL(0xa105e17e,0xf240ea34),LL(0x0ca7c1ed,0xe0a7225c),LL(0x60ee9bcd,0x8d5abc2e),LL(0xd1b7a04f,0xed201196),LL(0x421fd636,0xee08dcde),LL(0x3a41da5f,0x4d648f1c),LL(0x37a2b18a,0x637ab14b),L_(0x00000031), LL(0xe2574ca3,0x8f4aa46c),LL(0x42b5000c,0x5e6cb8b1),LL(0x2cc007b3,0xd18aeecc),LL(0x139d4602,0xfad62b8b),LL(0x4857b6e6,0x0b803515),LL(0xaaf5703a,0x7dfe5be4),LL(0x5b88d9b4,0xc7e255f1),LL(0xb42f23b0,0x642d5cee),L_(0x000001a2), +}, +/* digit=25 base_pwr=2^125 */ +{ + LL(0x9827bf41,0xd6c228d6),LL(0x53bd6003,0xac8482db),LL(0xedd6d84e,0x199f6c6c),LL(0x554b59c1,0xc80a2555),LL(0xbb3dd0d5,0x9a255d70),LL(0xb61698fd,0x8ce8ece5),LL(0x01602388,0x0910e4ff),LL(0x21f2b5b4,0xb877de8b),L_(0x00000006), LL(0xba9be6e9,0xe014bad7),LL(0xd6c8e28b,0x7941a6f1),LL(0x983d3be4,0x93e374aa),LL(0xb03efe8a,0x7787501a),LL(0x2ecc1517,0x3863f010),LL(0x8ce1a07f,0x2339ade0),LL(0xb1181652,0x142e138f),LL(0xed660839,0xade2437d),L_(0x00000072), + LL(0xb7c246de,0xbed2f33b),LL(0xc7b5006a,0xd46decde),LL(0x50c509c6,0x83eafeed),LL(0x09502cf6,0x6c8d2171),LL(0x6fa7b091,0xe284eb82),LL(0x6ef3971c,0x5478a9a0),LL(0x7e812b4b,0xbedbb05d),LL(0xbdf3afd0,0x5880bfa9),L_(0x000000a8), LL(0x17c0e4a6,0xde9fb976),LL(0x510f0d79,0x2d46f889),LL(0x5085caf9,0x57625cb7),LL(0x63379f4c,0x7679eef9),LL(0x202dc487,0x61e8da06),LL(0xd95a7481,0x933c7094),LL(0x6f198e77,0x7e527ab9),LL(0x3cef9bb6,0x3556a0a2),L_(0x000000a3), + LL(0x587ef556,0xadb4b17e),LL(0xe6db7725,0x223554b9),LL(0x298840a9,0x8ea40d6a),LL(0xb9987d3e,0x088f1989),LL(0x8c544359,0x98c4e679),LL(0x26877124,0xd4955574),LL(0xaeb47579,0x42531911),LL(0xedd6bd8c,0x876a0c25),L_(0x00000030), LL(0x17da2be3,0x578452ef),LL(0xf3506ed1,0x26ec7e64),LL(0x400c530b,0x0a9d93fd),LL(0x42c14bcb,0xeec28064),LL(0xdbc44330,0x21d894ab),LL(0x1784b7a3,0x83284ca2),LL(0xbd2fe673,0xbdaabf2c),LL(0x333a314b,0xdd217a0b),L_(0x00000109), + LL(0x6110cba8,0x3dead375),LL(0x261b1296,0x24e572ee),LL(0x4f710c53,0xa4d924c1),LL(0x3234879d,0x2bb72d3a),LL(0xf0242c6b,0x5319d73b),LL(0x56b72596,0x5d438ac3),LL(0x9c1467ec,0xe4eb1ea6),LL(0x40556d55,0x74c566ea),L_(0x00000000), LL(0x113bb0cf,0xf755482f),LL(0x1fdd8292,0xb750229b),LL(0x36eb56b3,0x8756dd9d),LL(0xd65055f0,0xad24bc9f),LL(0x305fbea1,0x29626eb1),LL(0xfcecb5ba,0xc9855409),LL(0xf6273264,0x81000d0a),LL(0x9d561b22,0x7b8d7b24),L_(0x0000017f), + LL(0xd531bd0b,0x1f33fdc4),LL(0x1e83cdaa,0x527f8e3e),LL(0x867d160e,0xf198e03e),LL(0x1f8e836d,0x319f12f2),LL(0xe5494da5,0x312ddaeb),LL(0x8aa887f2,0x0cacf5c7),LL(0xab111707,0x0ac8def9),LL(0xbe88c645,0x9ea7eeaa),L_(0x000000e2), LL(0xaae9a35d,0xecaceba5),LL(0x4a0a292e,0xbb26ecc4),LL(0x686acc28,0x1e45b0f2),LL(0x2a87d12e,0x3a62004b),LL(0x0c521e1f,0x1147391e),LL(0x2c697526,0x4d3ecffc),LL(0x940dd92a,0x45f78060),LL(0x3a2ded9e,0xeb3a17cc),L_(0x000000cb), + LL(0xf734ebf4,0x6012408c),LL(0x62256296,0xf1399678),LL(0x6234e097,0x152b073d),LL(0xd0a76b3e,0xbf3c9a35),LL(0x1dc1794f,0xca7a4461),LL(0x0ba3b03d,0xc31edda4),LL(0x3859cdff,0x8b3288b3),LL(0xf848ef1a,0x47d3b9b9),L_(0x00000067), LL(0x8f1d82f1,0x25e150c8),LL(0x41cecb20,0x4d109c13),LL(0xc9d21d04,0x7441f09e),LL(0x7778b13b,0xe84ff4c4),LL(0xa32c0c4b,0xc5ccc687),LL(0x309d686e,0x4ddb0a19),LL(0x9203c78d,0xba0868c4),LL(0x53181ea2,0x064154d0),L_(0x0000002f), + LL(0xe3ff2a58,0x31973b19),LL(0x2a26ad18,0x67b2d91a),LL(0x5fcc6c2f,0xe2db81e3),LL(0x0637d795,0x74742bd8),LL(0x1ed4fcac,0x26659e88),LL(0x30b9bfbf,0x232b6d3c),LL(0xae535c11,0x97bb1796),LL(0x32eef414,0xf6fe8c4f),L_(0x000000cb), LL(0x4a8e4230,0xc9a735e1),LL(0x8c58bcc2,0xa2ae4a3b),LL(0x1cf20755,0xcba626bb),LL(0x30e29d2d,0xc537d49e),LL(0xa170a87e,0x2ce7cb6e),LL(0x6a6c16d0,0x5f03a6b1),LL(0xa45e1673,0xe7f13685),LL(0x5d8c9454,0xdc67d748),L_(0x0000006a), + LL(0xaf97f8c2,0x16b51e78),LL(0xbb4d7657,0x4d4e4ac9),LL(0x12ece85a,0x2a2be63f),LL(0x2c2556ca,0x191c3b7f),LL(0x12341b0c,0x6c15ecee),LL(0xdf666379,0x2e302dd7),LL(0xce9cb829,0x76d162a4),LL(0xa7f8ba92,0xead863df),L_(0x000001b4), LL(0xd8403973,0x56dae839),LL(0xd9d38a99,0xd9da7dcb),LL(0xb69b8acf,0xd93d0fff),LL(0x4e0adb2a,0xf74f0454),LL(0xbb2ad644,0xb5de013b),LL(0xd489e7d5,0x944ef674),LL(0xa2d2bd3f,0x0ae01d0e),LL(0xdd32d1ec,0xf54aa8ae),L_(0x000000b0), + LL(0xe4705f69,0xcf1b879b),LL(0xacfbcaf7,0x1be6ac8d),LL(0x7318370c,0xdc61b734),LL(0x68c96561,0x0073d96f),LL(0xb94c34d8,0xc1901cf0),LL(0xf081cf45,0xe5c4c386),LL(0xf0fb0845,0xcbb72560),LL(0x26daccc8,0xc0c2c739),L_(0x0000003c), LL(0x649de0ae,0x12fe8c98),LL(0x69621218,0xdfb8607d),LL(0x8791c2b5,0xe9d74f1a),LL(0x3844e43f,0x58b63a6e),LL(0xa8d06c72,0x30e1aac8),LL(0xb6d9b103,0xc4264540),LL(0x3d6167d2,0x08191333),LL(0x68c04430,0x84141b67),L_(0x000000ed), + LL(0x1aa56828,0x0367e359),LL(0x3cdae245,0xb804f8f2),LL(0x72553e1f,0x67c4cfca),LL(0xb65b5da8,0xd9a5c285),LL(0x9a1f0411,0x613cad66),LL(0xba23bbe1,0xf8b4e4e2),LL(0x1cef34cc,0x8c65734b),LL(0x932e9f3f,0x02f73b5b),L_(0x00000186), LL(0x0351d0a0,0x59bb05ec),LL(0x31868efa,0x8bafab58),LL(0x0873b1c0,0xec7f2fe3),LL(0x3643b183,0xc1a9b522),LL(0x8e06d826,0x5a21bdcb),LL(0x8e78107b,0xd0770856),LL(0xf66af571,0xb9c9076a),LL(0xc46c020c,0x4aa90b62),L_(0x0000012f), + LL(0x5dc8f4b8,0xa33c20bc),LL(0x7ec83bd7,0xd911b15d),LL(0xd15a6121,0x4a74a6f1),LL(0x7ded1664,0x38816e97),LL(0x011743f8,0x3193fcc0),LL(0x2ce300dc,0xda43c181),LL(0x4a353b8c,0x15a04d1c),LL(0xc667d3b1,0x388d9585),L_(0x0000019c), LL(0x0bdf93dd,0xe0cceb86),LL(0x0ead0ff6,0x54678a08),LL(0x869bbb72,0xb18f6184),LL(0x7bd575cd,0x64b65577),LL(0xa032d6e4,0x7c7dc54a),LL(0x322afc12,0x30a518c1),LL(0xb73e6fec,0x94b0be46),LL(0xfb67de43,0x33b5236d),L_(0x000000fe), + LL(0x0f962f35,0x9c6f091e),LL(0x29586d09,0xc7324d43),LL(0xf0870634,0xfc9e4d8f),LL(0xa54095ca,0xb869d9b8),LL(0x750af3db,0x6d2001cc),LL(0x1a6baecc,0x24533332),LL(0x4d43331a,0x73cd1354),LL(0xe8c54106,0xc8a6bf97),L_(0x000001c2), LL(0x24bca00e,0xe99a79ea),LL(0xbfa3857b,0x6523d1b7),LL(0xf152a797,0x74d5c2b9),LL(0x7c8d0d7e,0xca070e93),LL(0x0c8c05da,0x90e17c3e),LL(0x6e856e17,0xc09e9cee),LL(0x45014958,0x157a95c9),LL(0x8be88b6b,0xb046e21d),L_(0x0000015b), + LL(0xcdd92148,0x641d359f),LL(0x2502c5ea,0x6f35d51a),LL(0x3893c7d7,0x20bf4812),LL(0x2ac899fa,0xea66bfcf),LL(0x3dd9d780,0x6686f753),LL(0x5853eeec,0x471826dd),LL(0x3f6607f4,0x63551e77),LL(0xab0845ea,0x9591457e),L_(0x0000004b), LL(0xc75e008e,0x1eb5093e),LL(0xf1fc3d61,0x48e575c1),LL(0x02888aae,0x04ab23f0),LL(0xe87f1ead,0xae16fee2),LL(0xb7f7d076,0x3eebdb5c),LL(0x94d4a8d3,0x1d42f789),LL(0x32f711dd,0xb65c5dfe),LL(0xffe8ae2e,0x5368ab2c),L_(0x0000014c), + LL(0xc71e34a7,0x960dca9f),LL(0xb04fd5f9,0xf94be13b),LL(0xcb350c8c,0xad91afd4),LL(0x507fe2c4,0x64d4307d),LL(0x965e3503,0x5c7ae781),LL(0x150451f8,0x6bf2a6c3),LL(0x730da87b,0x2d1774ae),LL(0x075f7ca9,0x5f606798),L_(0x000000a6), LL(0x7d9d82a2,0xdf7b7ba4),LL(0x9f994c7a,0x02b12659),LL(0xbc50a3bf,0x9dfdd3b8),LL(0x383c8539,0xfd8d4292),LL(0x17ae38e3,0xf28f2f03),LL(0x882096f8,0x5cc24a79),LL(0x4e0ef573,0xf15428a2),LL(0x57f145e4,0xb89880e7),L_(0x0000000c), + LL(0x457824fc,0x185ab84d),LL(0x1253397d,0x8d154628),LL(0x387df8c9,0x6bebdcd0),LL(0x9150bff8,0x556713ef),LL(0xe0119e69,0x47194289),LL(0xea336304,0xaea5316a),LL(0xfcab6f8a,0x32095630),LL(0x9256e44a,0xf5be137f),L_(0x000000e7), LL(0x91535ac7,0x1d1ebf3f),LL(0x100cda53,0x2af14479),LL(0xebfd994d,0x0287bad1),LL(0x075babf0,0x868eb0f1),LL(0x4f27433f,0x59c4864e),LL(0xb3ca6bbe,0x042e0b78),LL(0x36fc642d,0xc718e121),LL(0x457b51e4,0x6451668a),L_(0x000000f1), + LL(0x8e3c3743,0x2cea274d),LL(0x79b2083b,0xf6accb4a),LL(0xf7eff159,0x1a2ac9cf),LL(0xbd1a458b,0xc30597c5),LL(0xdaf5afd8,0x67ad0a34),LL(0xad0ce95f,0xfcb5f547),LL(0xf492633f,0xd42c927e),LL(0xd70d201b,0x677f0118),L_(0x0000014d), LL(0x7325271d,0x511be774),LL(0x532d9f83,0xe33f2540),LL(0x0e1e6624,0x6202d9c5),LL(0xf8f4394e,0x9c8fa1b9),LL(0xf8528991,0x2359d3b9),LL(0xd88ed641,0x4c00c9ea),LL(0x054c125a,0xbd626daa),LL(0xe0db1f33,0xbfaf8853),L_(0x00000029), +}, +/* digit=26 base_pwr=2^130 */ +{ + LL(0xd73be466,0x565e43ad),LL(0x8ce3b9fd,0x4a046e43),LL(0xef2d69e6,0xb337e9ed),LL(0x7f11d4e7,0xb4d2646c),LL(0x09fce23d,0x9cfe36cf),LL(0xf8577ee6,0xd497797f),LL(0x1e1b23f9,0xba0fa9f7),LL(0x813fdfce,0x1ec2f2d2),L_(0x000000cb), LL(0xbc5801d3,0xba1d6ad8),LL(0xfa8c88b9,0x38f8437e),LL(0x58d2c493,0xdf5755dc),LL(0xa5d4147a,0x9f31388e),LL(0x2454e0d1,0xd880f0ef),LL(0xed7c5174,0xf4ab4400),LL(0x2972f596,0x422f97c0),LL(0xfd1f05bd,0x1b6edbb7),L_(0x0000009e), + LL(0xe5308733,0xcdb37e83),LL(0x48081b75,0x60b5bfda),LL(0x38365296,0x9f69f061),LL(0x88a8974b,0x5fb9ec96),LL(0x75444cc0,0xf252002f),LL(0x899c5a67,0x664675a1),LL(0x11db7cc9,0xc6b6d7be),LL(0xe5e85617,0x8bf19549),L_(0x000001df), LL(0x650536e0,0x7897a846),LL(0x57bdeceb,0xb8acad39),LL(0x39f416b8,0xbb4ba894),LL(0xde12e814,0x45c679cf),LL(0xfa77e0ef,0xbfcd091b),LL(0xae92f35b,0xf3ea6cc5),LL(0xff4f9db9,0x15f66583),LL(0x67f0fed3,0x81b129a8),L_(0x0000009d), + LL(0x647774c8,0xd728f100),LL(0x8216c030,0x7565d29a),LL(0x38976a5d,0x0e8d40b2),LL(0xdebd4cac,0xe6c701d8),LL(0x3dc8c008,0x71a01dd8),LL(0x54f5f816,0x85aadb00),LL(0xe571a7d2,0x66dfeb71),LL(0x0d64dc32,0x2213f7ff),L_(0x000000b1), LL(0x8476568e,0x70c9c24c),LL(0x81e7d6f2,0xdfa45074),LL(0x8ce07818,0xc75e724b),LL(0x17be95c5,0xf85a8c49),LL(0x56216aaf,0x71eb7f6d),LL(0xf60fc3e9,0x4afdaffe),LL(0xb5697356,0x598d1d44),LL(0x2dfe785a,0x78a83874),L_(0x000001b6), + LL(0x70487d30,0xa5efc98a),LL(0x56482796,0x86f3d005),LL(0x81ed5742,0x41ac177d),LL(0x693c9188,0x41f63ff3),LL(0x544078e1,0xcb0cceba),LL(0xf396ad9c,0xcd9ca803),LL(0x1f2f8905,0xb9a3b9f8),LL(0x4318691b,0x399dbc5b),L_(0x000000c9), LL(0xf876e309,0xb6fd45a8),LL(0xf87881ff,0xa8a0715e),LL(0xb8d73d7d,0x074192a0),LL(0xca88981c,0xdc66d086),LL(0x00f41a80,0x8f279d46),LL(0x34882bbb,0xb5564038),LL(0x10c7a90c,0x5552b11c),LL(0xf89b04d8,0x834a5053),L_(0x000000bc), + LL(0x3f7dbd38,0xce9c88b4),LL(0xf194c13b,0xdc04befb),LL(0xdd6c7f32,0xd71b8746),LL(0xc7a2d3eb,0xb71fb09e),LL(0x497484b9,0x73e11c5b),LL(0x1fc70d7c,0x9831a6ee),LL(0x15940a74,0xc9a49067),LL(0xe36e9b20,0x365b0985),L_(0x00000144), LL(0x54606829,0x7dd8cbe9),LL(0x0d9bdc27,0xc774aae0),LL(0x36955f4f,0xcfe0f91f),LL(0x72271ae4,0x1d88d914),LL(0xc0f2a388,0xe1f3ebda),LL(0x63cec6da,0xf2b86354),LL(0xe4a5ad95,0xed0252cb),LL(0xedde22e8,0x7a31d7c3),L_(0x00000152), + LL(0x840ba74d,0xab9733bd),LL(0x35000794,0xc171b7dd),LL(0x7a0a699e,0x370bb4fe),LL(0xed68a491,0xfb486be6),LL(0xf15b9567,0x86467e73),LL(0x5a72e34b,0x007fbbba),LL(0x4fc2fd9c,0x07f9990e),LL(0xf83d0453,0x47ba1009),L_(0x0000014d), LL(0x3ed4cc4e,0xd0aa85e5),LL(0xfa4eda85,0xcc6de111),LL(0xab8aa3e2,0xd8d585dc),LL(0x43bc8ccf,0x69adf3a0),LL(0x9f03e827,0x2ce58643),LL(0x4e3d11d6,0xf05e13fa),LL(0x2820b6d0,0x7af921ff),LL(0x94e1a5fd,0x91b383f3),L_(0x00000193), + LL(0x8c47f3dc,0xfd8a756c),LL(0xca9eb3fd,0x31799e67),LL(0x5933facf,0x70399eb0),LL(0xe0504d9d,0xdc761184),LL(0x469e7106,0x8ef17d6d),LL(0xcd5f283f,0xb55ec3df),LL(0xdaa7f2c8,0x7711b93f),LL(0xa9a6a6b5,0x3add4e0a),L_(0x0000007c), LL(0xc75a128f,0x9a94b1bb),LL(0xa3a9b3b6,0x99889957),LL(0xd56e141d,0xc45c74e4),LL(0x969c754a,0x455c4484),LL(0xf069f686,0x7584cae6),LL(0xbd579d45,0x441fc298),LL(0x29bfd918,0xea727ee8),LL(0xb0624772,0xd66de027),L_(0x000000c7), + LL(0x7b2e1e8d,0x3ae58142),LL(0x2e71222e,0x90f869db),LL(0x9d393376,0xb1ce0668),LL(0x2d537bfd,0x1a9bff70),LL(0x47346bbf,0x4aeeb846),LL(0x8a0e90f5,0x73c9dd46),LL(0x54e3afa2,0xb6c871a6),LL(0x5945d8c3,0xf25b8746),L_(0x00000110), LL(0x100e770a,0xac70e87a),LL(0x1c87dbe4,0x797d6d91),LL(0x961a5c5e,0xc5b533fb),LL(0x548c0001,0xb560cfb8),LL(0xa9d47191,0xa65c8463),LL(0x37d39eec,0xcad37d21),LL(0x716bab4e,0x7b0514ad),LL(0x89ad5bc2,0x4b2c1f87),L_(0x000001e9), + LL(0x7c1ff897,0x4bd5aa83),LL(0x73534a22,0xb8d76f5e),LL(0x26abe76b,0x8f3282b7),LL(0x76978114,0x14a5cb17),LL(0x1bff40a3,0xb7375a3c),LL(0xb7209f08,0x91b36a89),LL(0xb4553b1e,0xcebaa86d),LL(0x73824616,0x8a3a95bd),L_(0x000000b5), LL(0xbcb95506,0x36ce8449),LL(0x45813245,0x0d1e1b38),LL(0xd6d0eea3,0x7fd0d6a4),LL(0x14a3ad4b,0x14bcb34d),LL(0x4fc99703,0xf4772d1d),LL(0xe5d8c8d7,0x1d59825b),LL(0x6cc8f63c,0x8d26276f),LL(0xba00b77b,0x4ea936fb),L_(0x00000180), + LL(0x06031f54,0x960c67a1),LL(0x32f38594,0x09357fe4),LL(0x3b745f59,0x2a14d637),LL(0x8fa90857,0x653eeaba),LL(0x65744c6c,0xfa37b71c),LL(0xf85872c8,0x3238cb4d),LL(0x9700049f,0xbb9a7dcb),LL(0x4c8ed8c4,0x47abe41a),L_(0x00000191), LL(0x49db6e5a,0x58e268fc),LL(0x4b45feb2,0x84cf99d5),LL(0x2045f9c6,0x80f4779c),LL(0xf44869f9,0xa220c8fc),LL(0x058ad702,0x7e09b470),LL(0x948098cc,0x5bc02559),LL(0x495b8c3f,0x33da20c4),LL(0x197459a3,0x4eda80f6),L_(0x000001da), + LL(0xd2a33c4e,0xb8c0a18c),LL(0x4edc42cb,0x42d862b6),LL(0xd775f940,0x1e91d30a),LL(0x6703500a,0xba0ea3ff),LL(0xa7531dda,0x2773ec8b),LL(0x39b7bed4,0x2d04e32b),LL(0xb4d1689d,0x9117e556),LL(0xd20ddefd,0x0946439e),L_(0x000000d4), LL(0xa10a2f30,0x55b7005a),LL(0x2bae1e82,0x53323c22),LL(0x2ff6304e,0x397190c6),LL(0xd9f087fd,0xa7a8b69d),LL(0xb68e3037,0x12602cd7),LL(0x25d350ef,0x22bf670f),LL(0x86cdc0d1,0x8a47dde9),LL(0x8ee7e2f2,0x974ab69b),L_(0x00000074), + LL(0xc6dbc583,0xd24b6766),LL(0xd31b0ef8,0x95890706),LL(0xe3a35296,0xc90c51cc),LL(0xb8ed7618,0x7cff3a80),LL(0x4973ebf1,0xd473b1c4),LL(0x3a129c68,0x098525e4),LL(0x5036c9f1,0xc374031f),LL(0x3955ea92,0x77e611d3),L_(0x000000d2), LL(0xf46f1c31,0x64ddf24c),LL(0x9e1fda40,0x70db5256),LL(0x5ea2c55e,0xf8940530),LL(0xf14297ac,0x034f59d5),LL(0xa46ea96e,0x42888331),LL(0x7dc4622a,0x102ad134),LL(0xe007741a,0xfe88a514),LL(0x1db8ec7c,0xc746e046),L_(0x00000099), + LL(0x514ddbd3,0x40394ddf),LL(0xc9c65dd0,0x539c2910),LL(0x679067ad,0x449575b2),LL(0x3e4b50f3,0x3cba3f07),LL(0x3ae8deca,0xdb855b46),LL(0xde55385b,0x16ac2f4b),LL(0xcf4ed383,0x1d879d47),LL(0x1e8113f4,0x90927036),L_(0x000000d6), LL(0xce4c202b,0x3d4593d6),LL(0x973ac87d,0xf0b4acfe),LL(0x01434726,0x6764442d),LL(0xfe9274d4,0x6b582005),LL(0xe308fe9e,0xf520a500),LL(0xaae35487,0x99c31e18),LL(0xcdca5ee1,0x1d99ed71),LL(0x0f6491b7,0x05d24b98),L_(0x000001b8), + LL(0x46f862a6,0x65cb077c),LL(0x631e9559,0x9b939d55),LL(0x25138071,0xf40d4552),LL(0x952fcfe6,0xb308097f),LL(0x0a6a5375,0x2e65e8e6),LL(0x3e9edb80,0x1310ce7e),LL(0x9008e712,0x36b60d2d),LL(0xef767e69,0x0706fc9a),L_(0x00000167), LL(0xfa1dc587,0x32ad8729),LL(0x4064ce9d,0xe1763571),LL(0x56c0be29,0x7963b458),LL(0xde3b2135,0x95d575d7),LL(0x66e40952,0xa842ef1e),LL(0x444bd560,0x5e446834),LL(0x9e4dbf26,0xf024c8aa),LL(0xf4d25cc1,0x3119e4bb),L_(0x00000080), + LL(0x31f1b543,0x5b8d2482),LL(0x0ec252b0,0x19b88e25),LL(0x0818329c,0xcd8bbb1b),LL(0xdb10a837,0x02e4893e),LL(0x81192510,0x84cd1c11),LL(0xbe980656,0x6c489430),LL(0x0f675008,0x346cc643),LL(0x57e72ed9,0xa6664b52),L_(0x00000049), LL(0x8c9e3525,0xc2a2b6e2),LL(0x50c3fc67,0xaf377b60),LL(0x018ff455,0xd7f347bb),LL(0xcd5a7fd3,0x820f28df),LL(0x7a766a20,0xbaa35047),LL(0x2e3e3c08,0xea0d932e),LL(0x620422f9,0x561b15cb),LL(0x78d9ad76,0xe4b810ff),L_(0x00000012), + LL(0x0f23847d,0xcb2c301d),LL(0x46a3121c,0x24b1883c),LL(0x64fb5faa,0x43263cce),LL(0xc10bc090,0x731fce3c),LL(0xe510506a,0x134986c0),LL(0xd2899a05,0xaa30a907),LL(0xd8592433,0x6671f165),LL(0xa5074a40,0xe0e30eea),L_(0x00000119), LL(0x39b1d8c9,0x4f03f7bd),LL(0xed9a2887,0x4a870054),LL(0xbd121753,0x510756ad),LL(0x9a0d0a37,0x85faa51a),LL(0x35296053,0xdf5c089f),LL(0x15a5c2ed,0x130a237e),LL(0xbd316fba,0x3774ff2c),LL(0x2c9d3ce1,0x66d3d7ee),L_(0x000001e7), +}, +/* digit=27 base_pwr=2^135 */ +{ + LL(0x45c384b6,0x2d4100e2),LL(0x7187b9e4,0xc5264e57),LL(0x2477a817,0xcb20ec20),LL(0xc146fbb4,0xa5dd079d),LL(0x6c49fc51,0xb66b540f),LL(0xa207dd34,0x18cb3114),LL(0xfc85f364,0x79042a4a),LL(0xa886f4d4,0xf32c0592),L_(0x00000021), LL(0x3c62b595,0x7df28ef3),LL(0x09a83c10,0xc98bc18d),LL(0x61720266,0xe8b908cb),LL(0xbfa40c64,0x3266ed34),LL(0xc5f7d00d,0x785d5c5a),LL(0xed6e6699,0x0fda50cd),LL(0x0528d637,0x9fa7129a),LL(0x226a0134,0xc857ddf6),L_(0x0000013a), + LL(0x854a83b5,0xa6b72500),LL(0x82b8a64e,0xf5cc5dee),LL(0xa44f4310,0x82f7e307),LL(0xa979f999,0x26038361),LL(0x36271c95,0x9d4a6e7e),LL(0x2c2e87bd,0x83121a68),LL(0x801461a1,0xdda0c42c),LL(0xc46dd1bb,0x16d6b9ef),L_(0x00000004), LL(0xf5ff9d53,0xac7e6d6f),LL(0xba6044cb,0x8a2a18c9),LL(0x4e0b1c61,0x47645723),LL(0x538c1881,0xff1d071b),LL(0x0d20849f,0x3d943038),LL(0x033ae333,0xd1326f05),LL(0xe89c6421,0x504a49c4),LL(0x0c637164,0x5b9d0e64),L_(0x00000191), + LL(0xc4db51e8,0x0ee6ce1d),LL(0x76a9fbe6,0x471be04f),LL(0xaee80fe4,0x63fea5d4),LL(0x13ed56ca,0xbb7b1989),LL(0xff53dd5a,0xbdd30335),LL(0x5aa48cba,0x8830cbd1),LL(0xced46a92,0x6ec07f47),LL(0x4d0d3e16,0x3e149703),L_(0x0000002c), LL(0x85d83aa8,0x030c528b),LL(0x3981ba7e,0xf6347818),LL(0x51c072a5,0x8851b9e3),LL(0x6bc6f46b,0x908af12a),LL(0xab612e82,0x11ae86d1),LL(0x194bfdad,0x855184ce),LL(0x3ed70ec9,0xbc5ba81b),LL(0x36a51b16,0xbe363f21),L_(0x0000017e), + LL(0x89a7c665,0x4ba50604),LL(0xf92c410e,0x03183bca),LL(0x325bb838,0xde751063),LL(0x4a227afa,0x61ce2f62),LL(0x8d611fad,0xe1c057fe),LL(0x63741f27,0x26a80815),LL(0xcc3f4944,0xdc51e188),LL(0x1fb19202,0x18a29e60),L_(0x000000fc), LL(0x23f5c4ba,0x8b90f284),LL(0xeac00c83,0xecc8f9f7),LL(0xc63ca5b1,0xabd4ae3b),LL(0x61f4eb49,0x5868250a),LL(0xde5e94c7,0x8aa62e59),LL(0x2e205082,0xa27ce17d),LL(0x4d94b7ec,0x3cf7dcd2),LL(0x84ff72ff,0xd9add4ed),L_(0x0000006b), + LL(0xd6250a4d,0xc4c48937),LL(0xb7e17582,0x30cd4a1c),LL(0x663cb672,0x4ecce3f6),LL(0x51a07652,0xe3e24952),LL(0x971076ab,0xb2837d4a),LL(0xcfa04494,0xae48378d),LL(0x2f234848,0x35aa4670),LL(0x5204cd94,0xdbb7f2c1),L_(0x0000010b), LL(0xce99c049,0x189c18e6),LL(0x1251a582,0xe65b23d2),LL(0x1ea8f76e,0x50f4154e),LL(0xde65bbaa,0x55d8a624),LL(0xd1acdeb6,0x9745647b),LL(0xdbc7b696,0xa1a36741),LL(0xc3af97df,0x0e06b475),LL(0xcec9f674,0x09826835),L_(0x0000018d), + LL(0x9edae224,0xc93ceb2c),LL(0xc40b8881,0x376b68f1),LL(0x493ec443,0x2fe4d107),LL(0x2613f055,0x2adbc0de),LL(0xc264177a,0x6850f4d4),LL(0x999b4445,0x024b1759),LL(0xb5528e8c,0xa532c490),LL(0xfe9cb25f,0xfd3a94e4),L_(0x00000027), LL(0xea2401de,0x29f2c840),LL(0xae4f0565,0x6004e218),LL(0x9745c833,0x45a26d7d),LL(0x1aa8e8c7,0x2e1e3abc),LL(0xf254366c,0xd176c592),LL(0x5dba9a65,0x75f2ce2f),LL(0xcb70eda5,0xef390121),LL(0xdf3bd7c9,0x57bbfad4),L_(0x000000fb), + LL(0xf2fb4c5a,0x612c5e22),LL(0x90ec0ad8,0x19eef2ca),LL(0xf648d0a0,0xb08c2818),LL(0x56957806,0xc6fa4d71),LL(0xe858889f,0xd381edae),LL(0x0d311c34,0x51c58427),LL(0xc7d13fa9,0x223f6153),LL(0xe7ffd714,0x41bebc46),L_(0x00000125), LL(0xa9aa9baf,0xd185738b),LL(0xa46d0a8f,0xb3308a45),LL(0x74e9630a,0x50e76c6b),LL(0xa8af0eb5,0xe6d664ef),LL(0xb4263c27,0xd6ff5afe),LL(0x0d5ab8af,0xa29e25ea),LL(0x35f45527,0x9641d328),LL(0x8c614ae7,0xf344ace6),L_(0x0000007d), + LL(0xe352f406,0x44f05c5b),LL(0x36069000,0x3a7061d3),LL(0xe7fd3e15,0xd82371f2),LL(0xb123a32e,0xc0c29bdd),LL(0x1a15e8ee,0x0938b2d1),LL(0x9bba46b8,0xa2ae38c1),LL(0x66a69b9b,0x470c4e74),LL(0xe7a0607a,0x04517ba8),L_(0x00000067), LL(0x04e250e3,0x0d3d6116),LL(0x99aa8990,0x2850e69a),LL(0xe87aacf0,0x0f5ea018),LL(0xa9b70f5d,0xe629958e),LL(0xc9dfec50,0x67ad0ad8),LL(0xa19fef72,0xfbbc4dd8),LL(0x4e913349,0x44ef73af),LL(0x36506a6e,0xa2784d06),L_(0x0000009a), + LL(0x4fc61403,0xbe686c91),LL(0x3b319ce9,0xcaf2c252),LL(0x48b002e1,0xd7142b37),LL(0xfd368034,0x4805818a),LL(0x24a14bab,0xfef62905),LL(0x0f3cee8f,0x8e05459e),LL(0xdd641c3a,0xf8a79ba8),LL(0xda069476,0xb3c5de43),L_(0x00000084), LL(0x39168c60,0x3f0a7260),LL(0x3e3e3f10,0xefe9a0b6),LL(0x98f31f24,0x029755ad),LL(0x68a3bd55,0x56d48cfc),LL(0x08db9e00,0x180b09d6),LL(0xf41fc496,0x43518b4d),LL(0x0a026b4c,0x53fa9a78),LL(0x49c51679,0xd4505c06),L_(0x000000f2), + LL(0x04533f2b,0xc6b20735),LL(0xf37cab9f,0x59889c71),LL(0x2957243a,0xee6d3e3b),LL(0xcd4ef031,0xc82e2f33),LL(0xbe1fa792,0x9431aaa2),LL(0xd5df936a,0x5897dee2),LL(0x69038db7,0x3c5c1a27),LL(0x49337ba9,0xd62944c1),L_(0x00000141), LL(0xdaff077c,0x92632965),LL(0xd489db4e,0x73090129),LL(0x940397cb,0x3ab24c2f),LL(0x08747c46,0xa7844d0f),LL(0x4063f57e,0xde4ab15b),LL(0xdfb6a687,0x7bdc8db9),LL(0xc4b7272d,0x670393c5),LL(0xcc129fac,0x2bf452b3),L_(0x0000012b), + LL(0xd3620658,0xd490ca01),LL(0x480b6735,0xf6b97c19),LL(0x5a38261b,0xeb8077db),LL(0x3a0d7cfc,0x6cb95b1f),LL(0xd822b66c,0x027f3439),LL(0x204c12b4,0x5b1121d8),LL(0xd1662f63,0x50df8b79),LL(0x5a06b5c4,0xa26c4803),L_(0x00000195), LL(0xdd45df26,0x7d35a477),LL(0xdf45caba,0x37ca8bf1),LL(0xb9d5153b,0xa163bc4d),LL(0x2a09a7c7,0x79721ae6),LL(0xf16f3745,0x4901566b),LL(0x8b7edc54,0xda6d915a),LL(0x2073fe4c,0x59c5233d),LL(0x0e719f5b,0x8881557c),L_(0x00000041), + LL(0x34d85352,0xb5e1a9d1),LL(0x04b6fb3b,0x96ed674c),LL(0xc5869197,0x2201eaeb),LL(0xc13b24f0,0x43fe141e),LL(0xd5acb880,0x77717702),LL(0xb4c36b2f,0xf913c28e),LL(0xbd9e8fe1,0xbb8bc0cb),LL(0x871dc376,0xdf0d6014),L_(0x00000130), LL(0xb3b18239,0x9062a004),LL(0x0d96f561,0x84b9c0aa),LL(0xd38134a4,0x384e6a14),LL(0x62e9b9dd,0x434945b9),LL(0x0d2a3f87,0x26111d5b),LL(0x0558e17c,0xca088afb),LL(0x7e83601c,0x5f4109b6),LL(0xf3372d86,0x33a44ebe),L_(0x00000052), + LL(0x2e8b93c7,0x08562f0b),LL(0xbd858543,0x4642e58a),LL(0xf3108a95,0xe72a8e55),LL(0xc3b6dcd3,0x48efed30),LL(0xbf3f1b76,0xeef47f99),LL(0xbe7c393d,0x7808a959),LL(0xb13004f3,0xab865ef6),LL(0x937fdeea,0xd800a95c),L_(0x0000001e), LL(0xde622870,0x5b036454),LL(0x1435996c,0x253cdb02),LL(0xc939a75b,0x00181ca2),LL(0x497b4076,0xc885fd30),LL(0x89ffccfd,0x5be5d64a),LL(0xd221db4b,0xf3ff67a9),LL(0x7c1814ff,0xe534c2d3),LL(0xdff1b3c3,0x4c8996de),L_(0x00000045), + LL(0xc9c5a035,0x6fb80668),LL(0xd3037f61,0xf7001431),LL(0x61783bd7,0x7eb67860),LL(0xa8db044a,0x687c5be2),LL(0xbd63e80e,0x72619e19),LL(0x79bd6dba,0x3f54433d),LL(0xd3da5abb,0x53179eab),LL(0xbeded885,0x2f58ffce),L_(0x000000d6), LL(0x8c1156c4,0x0e48c339),LL(0x6a8706fa,0xd70c895f),LL(0xdef1e5d8,0x74e0aa32),LL(0x628036e7,0xb31a93a3),LL(0xa6fa3b42,0xe7bb3f2a),LL(0x91ab3f15,0xd667e0a4),LL(0x1d5276ef,0x172f04b6),LL(0xac2e330e,0x46c091fd),L_(0x000001a4), + LL(0xcaeed330,0x3479c8d8),LL(0x774a0f8d,0x2da43aae),LL(0x89fab1e0,0x5a52588d),LL(0x22017d07,0xf2088700),LL(0x3344f84f,0xf666f8bc),LL(0xcded1b00,0x98c10e11),LL(0x385b1f15,0x4a35267e),LL(0x4cb957d9,0x0bc3b5db),L_(0x000000b2), LL(0xb7f4f85a,0x70aae220),LL(0x50f81138,0xd0547dcc),LL(0x320d34eb,0xaa86f5d7),LL(0x4627a90c,0x313d3af2),LL(0x0d86c9fe,0x9d1708c0),LL(0x93baaabc,0x4bb0c611),LL(0x5e3713af,0x8c78d7cf),LL(0x23abcabf,0x24042f80),L_(0x00000150), + LL(0x8d760d23,0x2a50426c),LL(0x2fd748bd,0xd4451d72),LL(0x84a5084a,0x7d518774),LL(0x395bd1ac,0x41ad7719),LL(0x5dc03d65,0x54b40eaa),LL(0xf42c68a2,0xc699a962),LL(0x481b2b4d,0x78f2ecdd),LL(0xd9badbf1,0x6d040345),L_(0x00000038), LL(0x6890c940,0x7a9849bb),LL(0xe8615e51,0x5822be91),LL(0xe3c3e516,0x9ed67ca7),LL(0x5ebee67a,0x5438f44c),LL(0xbf03236f,0xf9e45ec0),LL(0x29c5029e,0x412d0011),LL(0x4fd4f4e3,0x09bad0b6),LL(0x5f591e3c,0xd09fc0e1),L_(0x0000006a), +}, +/* digit=28 base_pwr=2^140 */ +{ + LL(0x6867ca62,0xb2e8cc83),LL(0x2abfd678,0xd7d6c96a),LL(0xbb6c702c,0xb7b75f62),LL(0x8eb9ab34,0x2a8eb698),LL(0x67b38227,0xee1d1728),LL(0xbff15e40,0x6f600751),LL(0x4ec3001b,0x30ff996b),LL(0x7fb8efdf,0x35fa815d),L_(0x000001bb), LL(0xfc62d76a,0x1c80dd81),LL(0x4a2f2f09,0xc1a9825d),LL(0x4ae9b61a,0xb05a4fb5),LL(0x71a812fc,0xa7baf2db),LL(0x8bb96eaa,0xcc434e4e),LL(0x53c2dfd9,0x8fce5672),LL(0xceeb8e7b,0xd6b948ee),LL(0xc787b7e9,0x44e8daba),L_(0x00000053), + LL(0x44566d20,0x816dab3c),LL(0xa555ef8d,0x68ad0a5e),LL(0x93fa3eae,0xb45ab760),LL(0xad51a41f,0x14a732bc),LL(0x3c784a11,0xcd96f357),LL(0x7e912d99,0x7808bc95),LL(0x547dff3f,0xd022a461),LL(0xd3f93d98,0x51efde9d),L_(0x0000010f), LL(0xdcf5792b,0x9e50e443),LL(0x1c5d0319,0xab35921f),LL(0xce7e3777,0x61acb763),LL(0xc69a2c80,0xd5a1f19e),LL(0xd4921d8b,0x86d49b86),LL(0x3effd3f1,0xd287849a),LL(0x969ee2c3,0x2319a1d3),LL(0x7987e8d9,0xda41b97e),L_(0x00000077), + LL(0x66e6b355,0x48d7c646),LL(0x494cec8b,0x4319bb26),LL(0x3c15f132,0xa4923bd5),LL(0xb25b7340,0xe36296a4),LL(0xd2c82187,0x62a70b23),LL(0x3a2676cb,0x3ce0a44b),LL(0x15ada951,0x93e13762),LL(0xcdd5bfa0,0x7e7884bd),L_(0x00000094), LL(0xe16f0577,0xeb1d23f2),LL(0x563bc2d6,0x74b1ae5a),LL(0x22ce417d,0xf0676c19),LL(0x8b56e586,0x64665c8d),LL(0xd3d21118,0x4a9d1f08),LL(0xb5b57a1f,0x9ad18a2e),LL(0x121b1440,0x31f16f69),LL(0xd3dba51f,0x94a4555a),L_(0x00000186), + LL(0x14a0990f,0x1571f4bd),LL(0x8a12a2ae,0xa7e98142),LL(0x64ea4bd5,0xf548a570),LL(0xc2f56d89,0x3a99f05e),LL(0x24fcfb51,0xb029c28b),LL(0x468881de,0x16eb364a),LL(0x54a22d8c,0x9df6df67),LL(0x8e7ba7c2,0x2986939a),L_(0x000000d8), LL(0x6d585b84,0x8b87eab6),LL(0xf8f2e668,0x61b8a4ae),LL(0x1b210ab1,0xcd5968d0),LL(0x38c32d9f,0x9469f27a),LL(0x2170203f,0x7e65bf26),LL(0xdf5327ba,0x268e8f3d),LL(0x0d743f23,0xbbd5d6a5),LL(0x6866dcf3,0xebf3b6f7),L_(0x00000010), + LL(0xfe75ceb3,0xc2dbf93c),LL(0x7d044fdd,0x05aa3d0f),LL(0x3459ab15,0x1e4c0404),LL(0xbea051fd,0xeeca2cbf),LL(0xa5c86723,0x428637a5),LL(0x81d9dd90,0xd3aca9d5),LL(0xf6461276,0x78277709),LL(0x5fdc5888,0xc80ded9e),L_(0x0000013d), LL(0x105fdead,0xb799ae3c),LL(0xc919db59,0x5e3595ac),LL(0x2aa1f7f7,0x4e9b6f6b),LL(0x519dab32,0x1054eecc),LL(0xd70aa0c8,0xdab1fa02),LL(0x45046840,0xe8162c46),LL(0x382d8fac,0x3f7fc117),LL(0xc63a2e34,0xf8b4f79c),L_(0x000001dc), + LL(0x40f45643,0x5e42072e),LL(0xb22b4730,0x6980bc47),LL(0x0c0959ae,0xd0091f48),LL(0x17382117,0xe76ce6df),LL(0x6fb6755f,0x083b1371),LL(0x8e338195,0x3ce92877),LL(0x57844465,0x22eadd23),LL(0x88650fd1,0xcb97b5f2),L_(0x00000194), LL(0xb832d4f9,0x40795011),LL(0x2f5eb6ec,0x56106a16),LL(0x439d72fa,0x7a360472),LL(0x9a695980,0x77c4b5ed),LL(0xbd3315f1,0xcd83808f),LL(0xc773b196,0x21f3f41d),LL(0xdcca40dc,0x42518607),LL(0xd975bf10,0x6fd38920),L_(0x000000cd), + LL(0x7643d0a4,0xca61488d),LL(0xc9a4ec9b,0x78d40864),LL(0x08ac32aa,0xd1f91912),LL(0xe2c33dbb,0x4ce17265),LL(0xa6b041d8,0xc73e5e84),LL(0x130222f6,0xcaf07f55),LL(0xbc20bdd0,0x2fe0bc76),LL(0x482195b2,0x6fe4ca43),L_(0x00000141), LL(0x37f04c87,0xbdd6ee14),LL(0x601822b2,0xb9431fd2),LL(0xf10879b1,0xebee54b7),LL(0xb8d5c027,0x530c61a6),LL(0x52358509,0x3b953e07),LL(0xc05d71ee,0xd055e247),LL(0xfc120f31,0x51f78c21),LL(0xb71a77f5,0x8d424c40),L_(0x0000008b), + LL(0xdcca1655,0xfcdcd83f),LL(0x6f13723c,0x6fe01dad),LL(0x48fc724e,0x10ea92f4),LL(0xe9506b35,0xbacd3171),LL(0x32c50316,0x5b9c3826),LL(0xb525812e,0xb06a2041),LL(0x6095bd35,0x29d1e51d),LL(0x8c9f2aff,0x03f8818f),L_(0x000001ba), LL(0xf5e8440d,0x5815a76f),LL(0x4652dd8f,0x0ba6e7eb),LL(0xa2d772d1,0x67d0cfa7),LL(0x2c2c10a3,0x9134fbe1),LL(0xe122408a,0x4d3fc999),LL(0x98396be7,0xf158ed72),LL(0xf1736447,0x2e445a86),LL(0x3589b3e7,0xd638a810),L_(0x0000013e), + LL(0xaa39db8a,0xcd1bfa5a),LL(0x3f690830,0xf20580fd),LL(0x47516625,0xc02a443b),LL(0x72df9c02,0x37c50805),LL(0x1f658c86,0x70ba4df8),LL(0xb9b7c15e,0x7863af7e),LL(0x4f048a5e,0xac437359),LL(0x985ed711,0x9b762ef5),L_(0x00000035), LL(0x31deb67a,0xf7ff8403),LL(0x277a75a7,0x9efc9dd1),LL(0x9e038122,0x72ab76fd),LL(0x380f72e2,0xa5bd7ec4),LL(0x55ee2df7,0xe6e012fa),LL(0x8dba5f73,0x3daacbbb),LL(0x7d57b1b9,0x706e065a),LL(0x2a1528ff,0x9e984f15),L_(0x000001c4), + LL(0x15c609d6,0xe5366bdb),LL(0xba4c8f5f,0xab004e8e),LL(0xa55c2b8f,0xbe220e5c),LL(0x9b0a693e,0x328cf3bb),LL(0xf0a01098,0x93659056),LL(0xba4d555d,0xa9299fb7),LL(0x705141f5,0xac2b6ea4),LL(0x44c2570f,0xd6c8f88d),L_(0x00000158), LL(0x4159e7f0,0xda0acb04),LL(0xd0b0f9e2,0x72227853),LL(0x9c81b6a3,0xfca5d947),LL(0xe37b62d0,0x89f8e6a5),LL(0xa2b087c1,0x397e6f2d),LL(0x79ab8dd4,0x0c2f8337),LL(0xe811e1ad,0xaed2062f),LL(0x41fc3c1b,0x6608ac6e),L_(0x00000196), + LL(0x62da0bcd,0x66e8ec0f),LL(0xa2436a22,0xb2614d9b),LL(0xc4f2fabe,0xd37ba7ca),LL(0x91730356,0xd6947b5c),LL(0x74afd26f,0xf62dae98),LL(0x24fc84c9,0xa5d82a0e),LL(0x01183e91,0x6d7bad82),LL(0x9ae00850,0x45968698),L_(0x00000176), LL(0xf94e5ea9,0x6a5a8c8b),LL(0x370f5efd,0x4a208fd5),LL(0x0abfbfb6,0xd3eba761),LL(0xb4577a64,0xaea020f7),LL(0x9d9fbff8,0xee185b5a),LL(0x7590eb6e,0xde37c8c6),LL(0x110f6564,0x087e5b3d),LL(0xf182e709,0x2a62e074),L_(0x00000022), + LL(0x35933656,0x11881664),LL(0x57d6289e,0xb5dfe85d),LL(0xb19a5774,0x03f55586),LL(0x84a3823a,0x83e66aba),LL(0x819d0f7f,0xe6540e46),LL(0x8229f91b,0xf8e60b64),LL(0x0ebba171,0x3cb7174c),LL(0x13a992ea,0xfc144f32),L_(0x000000dc), LL(0x66b10914,0xaf137af3),LL(0x22188a39,0xa99be2ef),LL(0xc9e8bf06,0x9f80153c),LL(0xb82d6f97,0xb70bb797),LL(0x713e0f8f,0x08001bac),LL(0x2900ebf9,0xc349df5c),LL(0x2dc5150c,0xcda05b0f),LL(0x705ef690,0xf953a13e),L_(0x0000006c), + LL(0x2275d0c6,0x43c2cbe5),LL(0xb77f7c23,0x426913e3),LL(0xa4d09bcb,0x193a8beb),LL(0x1c330bb2,0x9694aec2),LL(0xf90a1043,0x466c8910),LL(0x47794b4c,0x013120f4),LL(0x92db08ad,0x27504b4e),LL(0xfd2c4ee7,0x2771ac8c),L_(0x00000039), LL(0x3983eaf2,0x1520fd40),LL(0x43f9f523,0x10ab4804),LL(0xbbc7abbe,0x4c94f219),LL(0xb3da18c6,0x0653b434),LL(0x34410d29,0xa49aa62c),LL(0x475b1588,0x3fb54eff),LL(0x1efe3b74,0xe35ee322),LL(0xb5457582,0x0e28d1fe),L_(0x000001da), + LL(0xdfafafb9,0xd5ac6ec8),LL(0x3e035e11,0xf1bfe6e7),LL(0x0cdfda44,0x99f86b4b),LL(0xd82854c9,0x51eb2ba8),LL(0xe9378d3c,0xfc70edec),LL(0x0488564d,0x78099daa),LL(0x4df1eac2,0x106d93e9),LL(0xfcd2965d,0x9106f692),L_(0x0000018f), LL(0xeb73c32f,0x65c6a4f0),LL(0x12e6dfd1,0x613a95bd),LL(0xc4753f02,0x64c8ae6d),LL(0x6ee36689,0x82594975),LL(0x85faeab2,0xff936e47),LL(0xfd968563,0x16aa8dfb),LL(0xfae37039,0x6a6051eb),LL(0x090bfcd6,0xa79a4c77),L_(0x000000f5), + LL(0x1283d38d,0xab80a4e1),LL(0xab4695b9,0xb05894a6),LL(0x37378243,0x7f2984bd),LL(0x1227f75f,0xdf654236),LL(0xe2ef58d5,0x290dd3fb),LL(0xdf64907f,0x38ba14af),LL(0xf1d428ec,0x0c38bf2f),LL(0xc2c54bbc,0x86299078),L_(0x000000eb), LL(0x07837c73,0x31dfd968),LL(0xda6621ef,0x28b820a5),LL(0xe6fe2937,0xb934b778),LL(0x2622aba5,0xe627cb53),LL(0xdff94dc8,0xa81ea0cd),LL(0x560bd971,0x9c8b6e45),LL(0x2209f943,0xdbaad845),LL(0x6e9d457d,0xf9a711fc),L_(0x00000166), + LL(0x8402ef56,0xe6626b55),LL(0x5c34e569,0xbb9dc4c8),LL(0x009d6dab,0x6746cac4),LL(0xcf68656c,0x3336b947),LL(0xfe65ab97,0xe266a898),LL(0x0371ecf3,0x5830a2ee),LL(0x1d57e75b,0xc9710982),LL(0x3e097669,0x4a1d3264),L_(0x000000c9), LL(0x78e2ad77,0xddfb754e),LL(0x284311de,0x4aaa3d53),LL(0xac9d56ca,0xfe5f5938),LL(0x19e9ec29,0x24185a04),LL(0xe89e92d3,0x746f628d),LL(0xfd0968c4,0x6959a461),LL(0x2cc1b198,0x7f39e175),LL(0x5c4efa86,0x9030ef68),L_(0x000001fd), +}, +/* digit=29 base_pwr=2^145 */ +{ + LL(0x15578941,0x1a86314a),LL(0x6a7421e8,0xe2ec4906),LL(0xe975bc97,0xa7485f37),LL(0xd59fd20a,0xe5e712ab),LL(0x5b001318,0x951133a1),LL(0x1259bdca,0x057f57ee),LL(0xcbd3b2c6,0x33dad04a),LL(0xef3153ef,0xb54dd9e7),L_(0x000001a7), LL(0x2ed37d50,0xa4e81e7b),LL(0xf8f36d87,0x5a01a3ef),LL(0x0288c3e4,0x8b372673),LL(0x846f5208,0xa991189b),LL(0x6f560651,0x71db52e5),LL(0x431caeef,0x58e36c06),LL(0xa3f98d5e,0xd8d03f83),LL(0x020099b8,0xc4c7aadc),L_(0x00000118), + LL(0x52ab1b79,0x7e2040bd),LL(0x95a122c6,0x89ab0660),LL(0xf1cb78af,0x01a20058),LL(0xc77cb751,0x31375e35),LL(0x5e133615,0xea159ba6),LL(0x524c75ea,0x7ecbfca3),LL(0xab8ae0fa,0x5719d039),LL(0x623ac91c,0x7f17199c),L_(0x000001ae), LL(0x6b1430a2,0x8450eb5d),LL(0xc47b9efe,0xafb92b30),LL(0xa9991147,0xf6824bee),LL(0xe1752c3f,0x2b160b39),LL(0x7fd6a625,0x6256f4b4),LL(0x574646e7,0x076f7bff),LL(0xe5bbdfa9,0xcc3f350c),LL(0x4642b5db,0xa6dbfda8),L_(0x00000093), + LL(0xfa21d74b,0x37719209),LL(0x8cfe5b17,0x00c8bba2),LL(0x1c2878b2,0xa620523f),LL(0x170331c9,0xa5843ac0),LL(0x8cd83b50,0x0381135b),LL(0xb047131d,0xa643b75e),LL(0xd2ab54c3,0xc5ef1464),LL(0x62ed0e42,0x2a2e87f3),L_(0x000000fe), LL(0x91bb20fb,0x78f86132),LL(0x7805c40a,0x895f7e0d),LL(0xa2a8624a,0x3ce4b54c),LL(0x6579a871,0x1b0cde0e),LL(0xd626e2cc,0x6377df41),LL(0x045193c6,0xcd6454de),LL(0x1c3ca349,0x4909db1f),LL(0xb047b0a1,0x2ac29d91),L_(0x0000015a), + LL(0xf432b93e,0x4a6f35d7),LL(0x611248d4,0x62f74f5a),LL(0xff45509d,0xef98d968),LL(0xf78b11dc,0x540d2d90),LL(0x8e0fdb4e,0xf1948691),LL(0xf839178d,0x775c9c48),LL(0x1546952b,0x2da4516e),LL(0xb05a9a42,0x7e1f1548),L_(0x0000016d), LL(0x5a0e6542,0x5c40801a),LL(0xc9bfcea8,0x8cf4381f),LL(0xecff5ed1,0x04226551),LL(0xe3765708,0x3addaf06),LL(0xbf10bb39,0xe6d6327d),LL(0xa7a94c0b,0xde98dcbd),LL(0xc9cc265a,0x9445d1d2),LL(0x39198006,0x0a4801d2),L_(0x000001ce), + LL(0x6fd53bcb,0x11b88070),LL(0x89212039,0x0fd4310b),LL(0x7c570d88,0xfb34d160),LL(0xe29cc2db,0x8d8b6c1d),LL(0x98ac6419,0x633a2387),LL(0x48918f6b,0x3767a8fb),LL(0xc7f5fff0,0x1de5bf8a),LL(0x517008cf,0x0be25167),L_(0x0000010f), LL(0xc8a802dc,0x31a9aa05),LL(0x3f45d1a4,0x955dbbaa),LL(0x019bc5a3,0xf987ec6f),LL(0x7819e65f,0xa521ab1b),LL(0x6a8b4966,0x9db12d33),LL(0x1c418ebe,0x5c25c25e),LL(0xd371d986,0x05758d98),LL(0xcdb745fe,0x95301bd1),L_(0x00000034), + LL(0x82dda7a2,0x8cb7272f),LL(0x285a44b5,0xd0fa019c),LL(0x772202b8,0x256b2dc1),LL(0xf7a1827e,0x70cc578d),LL(0xf561fd03,0xf01369b8),LL(0x4b48b6ea,0xb34eeab3),LL(0xf869dc36,0xf55466de),LL(0x10fbfa49,0xd2c42ed5),L_(0x00000049), LL(0xa79b35c8,0x72243fd6),LL(0x48942459,0x6f4d4b6f),LL(0xbe3c7cfe,0x4b050256),LL(0x273326f3,0xccad925d),LL(0xcfe66f8b,0x63feb094),LL(0xd430d816,0xe74dd574),LL(0xf5ea27b5,0x45e6d69a),LL(0xe57442d8,0x62ad1e6a),L_(0x0000013c), + LL(0x91a18dca,0x52fb15ad),LL(0x64cc9794,0x889fc872),LL(0x76b7b4b5,0x516a4447),LL(0x7f78f44e,0xe0dc9367),LL(0x03435817,0x6c0ef141),LL(0x3e179290,0xdcc3815b),LL(0xa243fcb3,0x57d2c5d1),LL(0x33e3e4cd,0xcfefc1bf),L_(0x00000110), LL(0x373d3db8,0x567532fe),LL(0xa4edcdd2,0xe2cdd2ad),LL(0x313da102,0x7dc4c171),LL(0x9b6477b7,0x10610301),LL(0xd6614ed9,0xe5dbb13f),LL(0x093e9d03,0xc78d8181),LL(0x34692c91,0xd1998555),LL(0xfad9c4a4,0xbc55ef3f),L_(0x00000114), + LL(0x22136d3a,0x5150ed1e),LL(0xf12f4a61,0x48b602d1),LL(0x58c86ca8,0x8f3a438f),LL(0x2ad94dbc,0xfd28616c),LL(0xa1741520,0xfc8f344f),LL(0x97e96926,0xa2867b76),LL(0x3f74f49a,0xc963769f),LL(0x9eafe4ec,0xf81b0338),L_(0x000001be), LL(0x8d3271ab,0xeb904c8b),LL(0x361247ec,0xcf0e8b6b),LL(0x9dc846a9,0xf58b8dfe),LL(0x1bd5a3dc,0x46766ec7),LL(0xabb872ef,0x7028f76a),LL(0x5976ea25,0x7d56cad7),LL(0xa7a4c1e3,0x50e6e410),LL(0xd9ef6dff,0x18098aa4),L_(0x00000110), + LL(0x54ca4d62,0xa4adf367),LL(0x2f1d9120,0x9de3bdf9),LL(0xa199c49a,0x911112e9),LL(0x918e1ab3,0x51c4e324),LL(0x1ab9377d,0xdecbb2fc),LL(0x089f9423,0xfbdc7272),LL(0x61643ec7,0x297b6a31),LL(0x8eafbdcf,0x2cfa0899),L_(0x000001dd), LL(0xb9b29381,0x9618730d),LL(0x5c79e6e7,0x984e3379),LL(0x9a017cdf,0x6a46a60e),LL(0xb44ef6fe,0x6fd9e713),LL(0x8cf5836b,0x2e3b6ebb),LL(0x29b6614b,0x741582d0),LL(0xa7c94b36,0xb93abf5a),LL(0xc0822faa,0x19fa7da6),L_(0x00000070), + LL(0x6d40ef9f,0x75d98fac),LL(0x52ee8497,0x4f994b00),LL(0xb0754aa8,0xae60032c),LL(0x19b6eb82,0xb89fa32d),LL(0x3aea1e12,0xd3d62cba),LL(0xa47b84ef,0x7b3e3f24),LL(0x3738323f,0xa1811a10),LL(0xa83238ea,0x5ad6df01),L_(0x000000fb), LL(0xe600e837,0x2ba5692b),LL(0x25fadbb6,0x8c4ff4f6),LL(0xad437e54,0xfa9d42cd),LL(0x14c8f3b0,0x79e73eb8),LL(0xa0355c3e,0xee8fbd21),LL(0xefee74e8,0xb4ebba9f),LL(0x0e987b86,0x0e79123c),LL(0xa0018bb1,0x9f828609),L_(0x000000b4), + LL(0x68def816,0x3f12ff36),LL(0x4b57900c,0x7fffe102),LL(0xd2939213,0x70f61f2a),LL(0x4ecb6d5f,0x351a0540),LL(0xca3d4a8e,0x51a7737d),LL(0x887af4be,0xbc6bf04e),LL(0xfca084af,0xafb6ef2e),LL(0x80de41d0,0x1f45db0a),L_(0x000001a1), LL(0xa72b2fa9,0x9b7182ad),LL(0xa970074e,0x18bf55a2),LL(0x056574a9,0xb8d1ebac),LL(0xeba9a5ac,0x4bbdf7b3),LL(0xd324a4b9,0x20cc2ce0),LL(0x56572fe4,0x1a2b2538),LL(0xf24f0245,0xef07dd5e),LL(0x5ab8b3cb,0x4d463bcb),L_(0x0000013a), + LL(0x41cdedbf,0xcbb3dcf6),LL(0x8c3fb216,0x19500d09),LL(0xe213167c,0xe814428b),LL(0xac93cb34,0x1a28a2b6),LL(0x861cf475,0xbc74e6e7),LL(0xcc2d45ad,0x0f8c1d18),LL(0xbd9bdb71,0x6d7baa7c),LL(0x43067701,0x1f4e3b7d),L_(0x00000024), LL(0x8a8c2d8f,0xc8929c33),LL(0xc43c1d40,0x819f1cba),LL(0xdda7d3c4,0x598c12f3),LL(0xe612ee48,0xaa092a4b),LL(0x97324657,0xd55e9103),LL(0x1b8a4a06,0xd7a8f2d0),LL(0x010537d8,0xf7a0ab83),LL(0x9ae31bf0,0xc6e0b42d),L_(0x00000083), + LL(0xf56f7c26,0xac1feb24),LL(0x4df5d838,0x15563b3a),LL(0x1ca4e8a0,0xbf968a88),LL(0x62060557,0x3ca8c519),LL(0x46507367,0x743fec64),LL(0x374e7834,0xd6eda8e3),LL(0xe0db390d,0x64260f14),LL(0x96c53e95,0x0f1c8b0a),L_(0x00000171), LL(0xb4ebbd85,0x2786a497),LL(0x2343b68c,0xbc5660f7),LL(0x3871cff1,0xa03e99a5),LL(0x32a3116c,0x91a2e2b2),LL(0x39a66a33,0xf1e21170),LL(0xb4a691a2,0x0b59581c),LL(0x760bf647,0xbf35d6e4),LL(0xccdb4699,0x35e4ec1b),L_(0x00000125), + LL(0x8ea4e81f,0x6f0c46da),LL(0x6349f724,0xa1f6221f),LL(0x3d1cb710,0x801a6d7d),LL(0x9a8daaa8,0xdff7216c),LL(0xaabb78f1,0x0d054787),LL(0x6a1b8dee,0x9342cf54),LL(0x7426ffaf,0x8839548a),LL(0x7e189575,0xc54c3c21),L_(0x0000007a), LL(0x645473ec,0xf45138ac),LL(0xcb977455,0x51f3e82d),LL(0x23de028c,0xcb2096e6),LL(0x1236013a,0xd60fa53f),LL(0x790031f5,0x590da1dc),LL(0x41383462,0xd75ce15d),LL(0xaac7003b,0x5c3cf3c2),LL(0xe97d1507,0x738f1700),L_(0x00000179), + LL(0x552d3a3e,0xf4eca93b),LL(0xae1c95c5,0xdc45bd28),LL(0x0c12e32d,0x5dd7eb7c),LL(0x50ac538b,0x692eb87e),LL(0xc65147a8,0xa055973b),LL(0x8ff87281,0x23507ab9),LL(0x63636873,0x1c85fb4c),LL(0x794d2027,0x597db57e),L_(0x0000006f), LL(0xfe67d871,0x0c89c0f4),LL(0x7e7fa083,0x3b0ba9a3),LL(0x25bac099,0x1416b2e6),LL(0xcbc2cc9b,0xbbcf2943),LL(0xc5a1f7b3,0x354fa11e),LL(0xb195e363,0x61adb945),LL(0xcce31308,0xfde526a9),LL(0x5e8055b0,0x2d4a42f0),L_(0x00000100), + LL(0x7e3f21a0,0x83926d83),LL(0x58ff928b,0x46424f50),LL(0x50a21088,0x656540b1),LL(0xd69839e2,0x2172157b),LL(0xc836bb43,0x34535e3b),LL(0x1f818f5d,0x61ec6b27),LL(0xf4cd40aa,0x8714bd57),LL(0xfdb8302a,0x633209c8),L_(0x000000d1), LL(0x0a6b22f2,0x8b7033af),LL(0xdbf4f3b5,0x213a07cd),LL(0xd71e271e,0xfa9434d1),LL(0xc069f3af,0xd5d23e3a),LL(0xc4ccd448,0xe785990c),LL(0xdd215a3d,0x500536e9),LL(0x43168909,0xe45a1f48),LL(0x9f92d8e2,0x747468d3),L_(0x000000aa), +}, +/* digit=30 base_pwr=2^150 */ +{ + LL(0xf661dbbf,0x43121ba6),LL(0x2325e379,0x176edfca),LL(0xf0cef68c,0xa3861e28),LL(0x617ac6ed,0xa77e7f84),LL(0x57535e8c,0xd31f498d),LL(0xf36e23d1,0x546d78b2),LL(0x2c3f8810,0xcfc7d55e),LL(0x156a1cb9,0xd5aca891),L_(0x0000001a), LL(0x974ce76b,0x894a4c0a),LL(0xc178af73,0xe4d65f8f),LL(0x5d4f42d7,0xf71cb940),LL(0xf73dac29,0x1d35c689),LL(0x32814192,0xe3cb66f4),LL(0x753255de,0xaf9effca),LL(0xa9814253,0xd34e3d9e),LL(0x22e23b71,0x8168c420),L_(0x000001f1), + LL(0xaa0bda51,0x62c59939),LL(0x9d4f255c,0x1e39fae8),LL(0x74c49bbe,0x09372aef),LL(0x180fc9e6,0xde724860),LL(0x163da12a,0xfa823f50),LL(0xa72a28de,0x965a30e8),LL(0x3c600eca,0x905cf108),LL(0x9f8b9687,0xd2d094af),L_(0x000000c3), LL(0x26afd7d7,0x13810cfd),LL(0x986aa03b,0x37d1ddbf),LL(0xeede05c2,0x2715d035),LL(0xb7ae0b88,0x95ef9e71),LL(0x08124878,0xe5042346),LL(0x9f87f170,0x3054f163),LL(0xebc09360,0xce2e674e),LL(0x593b42f2,0x6d4f4654),L_(0x000001b2), + LL(0x673811ec,0x60b858de),LL(0xeb464fae,0x677b9369),LL(0xd5f16b47,0x26383f92),LL(0xc119870e,0x3f8c6fe9),LL(0x5da1cbb2,0xf7124d37),LL(0xf6c7c1d8,0xdb2b9c75),LL(0x96be948d,0x93746dbd),LL(0x9988eb57,0x760b9ec6),L_(0x00000024), LL(0x03e8f45c,0x3d8c21e4),LL(0x9b0b40cd,0xc1186513),LL(0xb44deee2,0xf970a928),LL(0x2d95e66b,0xa6ac8009),LL(0x8387cee5,0xbddad6f7),LL(0xfec87180,0x0d3ded17),LL(0x2404e11c,0x41ea3e64),LL(0x725101e4,0x4f7761e0),L_(0x000001b3), + LL(0xc6a2f3a1,0xa09feeb1),LL(0x180b5e19,0xc54628c6),LL(0xe8c61be2,0x773cefba),LL(0x054eeedc,0x90648d31),LL(0x0005e411,0x36489351),LL(0x44b74925,0x54e90646),LL(0x573a22ca,0xd626639e),LL(0xa6074dac,0x850593b5),L_(0x00000197), LL(0x9e2e1f28,0x11161ac9),LL(0x4f328fba,0xaaf012b0),LL(0xb74a91c1,0xadb60a6c),LL(0x0cf3c48d,0x1b818269),LL(0xf7c4e07d,0x9eb0dacb),LL(0x2e6fbed1,0xaba09048),LL(0x9ea1ef81,0xaab8c6fb),LL(0x4b567809,0x87318d6d),L_(0x00000196), + LL(0xdee1b8d1,0xeadd7be3),LL(0x42ed487b,0xcb4bb355),LL(0x508d338c,0x1d927c01),LL(0x671a9478,0xd1e3ea8e),LL(0x6482584e,0x83bdc72c),LL(0xb63d17da,0xe52363b8),LL(0x49266941,0x4b78813a),LL(0xcb9e3414,0x5ec6b5cf),L_(0x00000092), LL(0x1f691526,0xb7f97367),LL(0x8a234b55,0xb87b73bd),LL(0x107f953d,0x2944bffc),LL(0x7c0ce6fb,0x6166fb64),LL(0xe784fca9,0x0a71a69e),LL(0x864d9dbf,0xa770d1de),LL(0x1d767a82,0x641a01bc),LL(0xcb0ce972,0xe39d1b9b),L_(0x000001fd), + LL(0xc878d60b,0xeb346a1c),LL(0x6b8a06cb,0x38f8292a),LL(0x28e10a9b,0xa02441ad),LL(0x110ae3e5,0x374d8f2e),LL(0x9df680d7,0x622d31b8),LL(0x0be1994b,0x98b8d29a),LL(0x35da2573,0xcf273b8e),LL(0x5a38591a,0x797f3e99),L_(0x00000156), LL(0x49364b7a,0xd85cd33a),LL(0x18db5402,0x71a1b4e6),LL(0x7ccbb0bd,0xda26853d),LL(0xc76e0476,0x1360631f),LL(0x888e44f3,0xf6b0ad63),LL(0x2c3af0f8,0xbec71f59),LL(0xdbf01e8d,0x723b0fd6),LL(0x92661703,0x31867e0b),L_(0x00000137), + LL(0x28ddccde,0x38aeac57),LL(0x4e993e85,0x0db5dd87),LL(0x38abc090,0xb465add4),LL(0x0c1739c3,0x43d0e74a),LL(0x70bd3e21,0x0b277d58),LL(0xac3af0a3,0x7b2c5422),LL(0x770a41ce,0x08580ab5),LL(0x9864e070,0xa3af8219),L_(0x0000002c), LL(0xe88e2a8f,0x6783af82),LL(0x37cfc10e,0x6261464c),LL(0x8e8c7510,0xcc9c836e),LL(0x503598b9,0x560d6425),LL(0xcf7c6100,0x4d90b834),LL(0xa8db43b7,0x2444a629),LL(0xd2cb3f5e,0xcabe2a81),LL(0x64aa2ef3,0xfca35c68),L_(0x0000013b), + LL(0x8b6de757,0xa9eb572b),LL(0xe5a924f4,0x650813f9),LL(0x4cddfbbc,0x0f808102),LL(0x750529ae,0x8dbdc23e),LL(0xfc407a67,0x3db36c6d),LL(0x549e5c64,0xadee9ab1),LL(0x55d46bd9,0xacadd1f8),LL(0xf68182d8,0xdd3bbaed),L_(0x00000171), LL(0x66e2fb66,0x24a72828),LL(0xe75f104b,0x50b3c877),LL(0xe38bb301,0x2f8590fa),LL(0xb7b5535d,0xf87c6208),LL(0xe1b50eae,0x41ba355d),LL(0x3f0d0c45,0x8bfe9602),LL(0xdc159699,0x3cdcf2ea),LL(0xab8c033f,0xe7e25f41),L_(0x000001dd), + LL(0x29dba96e,0xc3f8209e),LL(0xb1d945a2,0x08e3fd6a),LL(0x6511a3da,0x9263ef8c),LL(0x2562d483,0xd579038d),LL(0xc4c88945,0x5094d203),LL(0x75e4003b,0x54ec1258),LL(0xbe6102b0,0xe7874a8c),LL(0x8d34a4cc,0x27868839),L_(0x000000ea), LL(0x018d87b3,0x19a05999),LL(0xaacd7c73,0xd3cb884f),LL(0xe794b313,0x5a8d6b1c),LL(0x598893b1,0x47ab4f51),LL(0x7e862cb6,0xcd145d37),LL(0x58ebff95,0xa0ddf0aa),LL(0xcb716afe,0xa0791796),LL(0xc7f724f2,0xf2c9729e),L_(0x000000ee), + LL(0x5cadd4b7,0x080a8ec1),LL(0xb97d34b1,0x7709d928),LL(0x24150cc5,0xfda92711),LL(0x9f76ea4a,0xa5dd93a6),LL(0x4e4f7b83,0x826a2138),LL(0xb1f097c8,0xdb8dc9be),LL(0x877e5a70,0xf1a434cb),LL(0xdd51585b,0x86a8a774),L_(0x000000d3), LL(0x7f07e424,0x166eed95),LL(0x061bf4f5,0x469e3126),LL(0x06b67307,0xacfcc07d),LL(0x87971f8e,0x96d964d3),LL(0xe5aebd3f,0xa4d18cb2),LL(0x5d286291,0x3fbd829f),LL(0x7560bbae,0x277863a6),LL(0x6e83e561,0x690089b3),L_(0x000001ba), + LL(0x6a2ec0c8,0x6902a948),LL(0x82ea938a,0x1db5acbd),LL(0x9ed742a7,0x26e981b2),LL(0x64d1ad56,0x075f4b10),LL(0x30adf93f,0xfd5008eb),LL(0xdc51091f,0x7f4f1467),LL(0x907912b5,0x0fb17ba1),LL(0x567270fd,0xa348b34f),L_(0x00000094), LL(0xbf940606,0x18337830),LL(0xabbf9925,0x7019fd78),LL(0xbb5e1175,0xc937b351),LL(0x1359c463,0xd19eff42),LL(0xfe68dfe8,0xa8892734),LL(0xed1005b7,0x7cc639ba),LL(0x780e1feb,0xb6ff755e),LL(0x1f0082fa,0x16899eda),L_(0x000001ec), + LL(0x191bfbe8,0x87367459),LL(0x58859da0,0xd000c521),LL(0x4373d9cc,0x560dbafd),LL(0xfeee235e,0x8d303a3e),LL(0x1fe980f9,0x2a6082ad),LL(0xb5244f01,0x567ed43e),LL(0x8306748e,0xa7eddca6),LL(0x4e531e38,0xec76ef95),L_(0x0000006a), LL(0x100101b4,0x4e959563),LL(0x7ab1df8f,0xbcb6c605),LL(0x0218cd6f,0x3a152b14),LL(0x217b7b09,0x9b32670a),LL(0x7924c99c,0x8550cfd6),LL(0xf9af0b38,0xda396f8c),LL(0x27557bfe,0x01351543),LL(0xf74a0d9f,0xdcef098c),L_(0x000000cb), + LL(0xafc3d641,0x7e899074),LL(0xeac59b4a,0xab6f7e5f),LL(0x9036a3e5,0xd5685de7),LL(0x32b71856,0x6c3ebc40),LL(0xbe82a80b,0x46fa8ac4),LL(0x8d567d33,0x8f1ba3f5),LL(0xe3d61024,0x9622947c),LL(0x175ff060,0xe735b06d),L_(0x0000015b), LL(0x79460a8f,0x28338621),LL(0xa409e48e,0x6cee22e8),LL(0x04f98fee,0x448a258d),LL(0xb3e86ccf,0xedd8a07d),LL(0x94212741,0xe7c10493),LL(0x0eae65b6,0x72b816f3),LL(0x3c05e156,0xaf3b8cf2),LL(0xbeed59dd,0xd6c91b11),L_(0x0000017d), + LL(0x09ba81aa,0x3d989afa),LL(0xf91b3d7c,0x24d1650d),LL(0xff5c31f0,0xdd5b9bae),LL(0x20976038,0xf21ca860),LL(0x119240c2,0xcea2f4f0),LL(0x317b48b0,0x894a28c8),LL(0x18cdb521,0x70a13f92),LL(0x613d3aff,0xe3c74422),L_(0x00000003), LL(0xe8dd6883,0x18e6d135),LL(0xeb2f0e32,0x2b49078e),LL(0xf0a3dbd6,0x80094f8b),LL(0xad97e7ba,0x7ec56e28),LL(0x9e31d818,0x1a28c019),LL(0x2e151983,0x924258ad),LL(0x40e237bd,0x4e48eb49),LL(0x7b03fcb6,0x865da13c),L_(0x00000181), + LL(0x023dd329,0x3dc56c97),LL(0x2622fb40,0x2ec06f52),LL(0xca023e51,0x70809db6),LL(0x4a297188,0x1e390795),LL(0x4a3bacea,0xc30dbed7),LL(0x0824bcd6,0x3a9a9a8c),LL(0x3e051eda,0x98211435),LL(0xbf2fd10b,0xec587a65),L_(0x0000000f), LL(0x6a685349,0x272a03cd),LL(0xecc543f9,0x54d18fe3),LL(0xdf8cb8ba,0x9b7c5d19),LL(0x5f3f336d,0x9e4ff288),LL(0x5e647a61,0x2dc0aea7),LL(0xbdca4466,0x24b8d191),LL(0x33cd397e,0x4bd62cf4),LL(0xf66b542f,0x572d2230),L_(0x000000a6), + LL(0x6acd9335,0xcbf85583),LL(0x52fb515f,0x7808f963),LL(0x374fc6d2,0x5865c5cb),LL(0xebbbb50f,0xa4d0c81e),LL(0x47f3a5b9,0x29ed702e),LL(0x97b4bc63,0x64f0fada),LL(0xf73be9b2,0xe65e3bbc),LL(0x42f9f14d,0x40320dd4),L_(0x000001bd), LL(0x4729cdbc,0x47ce590b),LL(0xf363cdb2,0x5be836dd),LL(0x6a8da968,0x5fd32e4b),LL(0x49bdb981,0x076e41c0),LL(0x8d8f7528,0x097db4cb),LL(0x7fc1d50b,0xf829470b),LL(0x75b1cc67,0xd2b6caef),LL(0xd55324b1,0x829ebed3),L_(0x000001ac), +}, +/* digit=31 base_pwr=2^155 */ +{ + LL(0xf69ff50f,0xfc1e2456),LL(0x02b84001,0x1c124be7),LL(0xa6c9b545,0x2857f671),LL(0x07337c72,0xb0a89f0e),LL(0x7d3661d0,0xaf022308),LL(0x61f17db2,0xd9b173b2),LL(0xd0457b51,0xf8c65404),LL(0xefc1cd30,0x8f61986e),L_(0x00000196), LL(0xfffafb34,0xc5bd6770),LL(0xfc7a7db4,0x0de59815),LL(0x342e8ca8,0x843b5602),LL(0x0e1c9e4f,0x3bfe9122),LL(0x8b0b7c5b,0xa1e2826c),LL(0xe442b313,0x88ce465c),LL(0xf2ef9e99,0x77217ce5),LL(0xa10ff590,0x672e5682),L_(0x000001f7), + LL(0x9441390c,0x054f8022),LL(0x7143ab58,0x9b74e159),LL(0x8a901ba0,0x116652a4),LL(0x9b4f3635,0x0afb314b),LL(0x45e2ee30,0xd4622886),LL(0x4d2f79f7,0xb66e6167),LL(0x298ff3c1,0x2505aad2),LL(0x27d64009,0xc36ddbd3),L_(0x00000066), LL(0x0eb20dd5,0x4b51c2ba),LL(0x74c9cdac,0xbf1d3648),LL(0x10d4063e,0x6b726013),LL(0xc8c6fbaa,0xf8b94ac6),LL(0x6ce6639f,0x91f488ec),LL(0xf454066c,0x24c600b8),LL(0xf37706e5,0x1cff656e),LL(0x434286c2,0xe127b8a0),L_(0x00000087), + LL(0x35d5b009,0x7857cb4d),LL(0x2bf04d1e,0xc85eb560),LL(0xaf5c9697,0x3e426a2c),LL(0x140d9785,0xe234a765),LL(0xfae3a667,0x6a198191),LL(0x6a2fce6c,0x3a779c8f),LL(0x217e7e57,0xb35dd0c7),LL(0xb20040f7,0xad54aae8),L_(0x000000c4), LL(0x36df1d99,0x46ee68e7),LL(0x884f54d7,0x2f9e3760),LL(0x70670755,0x1a8bd746),LL(0xd3fc19b5,0xc34c78ba),LL(0xaf9a102e,0x9b57be0c),LL(0xfe21514a,0x9e7c2e6d),LL(0xde90d865,0xd44207f4),LL(0x19f36d3f,0x344544a7),L_(0x00000123), + LL(0xd877e284,0x37f60445),LL(0xca4191dc,0x69f0b4df),LL(0x358c7759,0x12aaa285),LL(0x72cf55e1,0x7f71ae31),LL(0x0ffea4f4,0xfc352eb3),LL(0x5b8d412a,0xc7ffc3d9),LL(0xabdbf74b,0x239ccbac),LL(0xd4b6acd1,0xfa89f30d),L_(0x00000163), LL(0xa6870d63,0xd1598751),LL(0xc6b0d1f9,0xc925f0b6),LL(0xa890fd44,0x106c309b),LL(0xcedd20fe,0xc46673f1),LL(0x2408588d,0xebfbcf6f),LL(0xb54153cb,0xa52fed53),LL(0x7b4aaced,0x672bbf3f),LL(0x84a22a21,0xf033a8d4),L_(0x0000004d), + LL(0x2197649c,0xa6098bec),LL(0x132b7114,0xe879a5ea),LL(0xbf33520a,0x5ec11946),LL(0xf7eb2f05,0x76724ae5),LL(0x8b00135e,0xa281ab75),LL(0xe322da16,0x75ecccf9),LL(0xf00478b6,0x5f741662),LL(0x77d420d9,0x27da38cf),L_(0x000001c3), LL(0x8deebf19,0x38cf892d),LL(0xdd1ae54e,0x4a486822),LL(0x8e9572bf,0x15d5deb4),LL(0x83965350,0xa31f170a),LL(0x098efd39,0x225bfe44),LL(0x3effcffa,0xd17f63bf),LL(0xf8e3659d,0x72dce9ce),LL(0x561fceba,0x7a4df1b0),L_(0x0000009f), + LL(0xaed633fc,0x573eaf11),LL(0xc05113c8,0x5f254d2b),LL(0x283764aa,0xee71c7fd),LL(0x70135776,0x88759ff7),LL(0x33df5ba9,0x84205188),LL(0xd52265da,0x809c0705),LL(0x912507fb,0x641067f4),LL(0x28d91a94,0x4a47efb6),L_(0x000000d6), LL(0xc5e6e2ac,0x0000ebfa),LL(0xa6c0565c,0xced796bd),LL(0x6c90c0d4,0x100a3283),LL(0xee187fc8,0x82bcb3d2),LL(0x8d7848e9,0x290e6b62),LL(0x4a59be08,0x5ab586db),LL(0xb9a00808,0xf4b07e2f),LL(0x210d8de2,0xc7559d56),L_(0x00000067), + LL(0x224b3264,0x7213c7fe),LL(0x43204c94,0x13a1a9d8),LL(0xf7f1cdee,0x68201c17),LL(0xd60991d9,0xbe9464cd),LL(0x4334ef4d,0x715fe2ea),LL(0x590e3478,0x7284a69e),LL(0xe07f24de,0x7c088851),LL(0x5ce9bed5,0xf517b62c),L_(0x000001c5), LL(0x3aeb8798,0x222d178c),LL(0xa01cdb6d,0xe0c1815b),LL(0x29424615,0xec65cc42),LL(0xfd885c8b,0xfd5df228),LL(0xd9564da3,0x9775d121),LL(0xb060eb3c,0xdc43087b),LL(0xbf975586,0x0c723af3),LL(0x941c0856,0x081262ab),L_(0x0000006c), + LL(0xbf0ac7a2,0x744e57f4),LL(0x8834334c,0x2edb448a),LL(0x4c1f9523,0xc8e4d56a),LL(0x85d4cde6,0x0bd23e3b),LL(0x83063d71,0x45b52f37),LL(0x14ca833d,0x2012d08a),LL(0xff85aaed,0x02ccbe55),LL(0x9fa9b95c,0x0a4b1e91),L_(0x000001fa), LL(0x04999b76,0xf355b09a),LL(0x9309a1f5,0x00d64b66),LL(0xb2bd55ad,0x57889605),LL(0x6b121bac,0x20d91b65),LL(0xed693b72,0x1faab888),LL(0x344453ea,0x45d07a30),LL(0x75e36d67,0xf7e7a52e),LL(0x86433618,0xdc4aaa79),L_(0x000000c8), + LL(0x9079f10e,0x7efb5f88),LL(0x2c050909,0x1cc662d3),LL(0x7e0de0a5,0x5ee0da97),LL(0xb01a8aa9,0x4922eaaa),LL(0xbf868cba,0x64bbc9e2),LL(0xba2129b9,0x0afac1c6),LL(0x38f86242,0xc8be3270),LL(0x7520a9f0,0x711b9939),L_(0x00000014), LL(0x0cf7a18c,0x5d48ee16),LL(0xc85d4499,0x04528b19),LL(0x2452bab5,0x65b2b9c3),LL(0xbcfb2531,0xd43a545f),LL(0xc03362e0,0x07cc670e),LL(0x5d9aafa1,0x58f98004),LL(0xd816f41a,0x324a8340),LL(0x352c0783,0x948019c3),L_(0x00000060), + LL(0x4b2484fc,0xfc2dc91c),LL(0x3b5be485,0xd7e9f840),LL(0x42217cb5,0x8585ec85),LL(0x3deede9d,0xa1f0053f),LL(0x48c56ddd,0x845902ce),LL(0xb2e99028,0xdbb111fe),LL(0x8f6659bc,0xf1537c2b),LL(0x89960f5b,0x2b6c075d),L_(0x000001de), LL(0x88a9e85b,0x39c6986f),LL(0x69af11de,0x0fa555ee),LL(0x0c555b9d,0x411f3b27),LL(0x62266b30,0x0b0e864c),LL(0x784a1194,0x112da824),LL(0xb7ec5b26,0xc56950bf),LL(0x8a57ba0f,0x3866d81f),LL(0x72e0aa00,0x33d123b7),L_(0x0000012f), + LL(0xf2f274e7,0x9f7aad66),LL(0xd84871e2,0x040c2554),LL(0x2a4885e0,0x8ddb8ec0),LL(0xbfd317bb,0x2a407fab),LL(0xaa27b70d,0x17f03cf3),LL(0x1bed7718,0x8c3de6bc),LL(0x34f5d378,0x0e550353),LL(0xfef609bb,0xf9faf54a),L_(0x000000e9), LL(0xc5275edd,0xd325a149),LL(0x33824d71,0x14d92534),LL(0xba4131f2,0xf74f4dc1),LL(0x81fdb0c7,0xd354ab8c),LL(0xc33be6cd,0x96e68610),LL(0x7d362d2c,0x967ca304),LL(0xad3a9c9c,0x90a06f8b),LL(0xaf6da5b3,0x05921c7a),L_(0x00000012), + LL(0xc1710f55,0x67ff0e8d),LL(0x7ef6718f,0x601481b6),LL(0xb39b462d,0x57d09ffa),LL(0xad90ba10,0xf83bbbb5),LL(0x918d94f2,0xed4c7a16),LL(0x2bee8d2e,0x9ddb61a1),LL(0xdadd0291,0xde96ab74),LL(0x2e5753e9,0xf3c27390),L_(0x000001bb), LL(0xa3926dcd,0x5af3e375),LL(0x827a6eab,0xeb250dce),LL(0x08623cdc,0x52408bd1),LL(0x9a7d0e9c,0x236fdad4),LL(0xf66e3019,0x55ed033a),LL(0x55cf40ab,0x67077bc7),LL(0x33b49be6,0x3d6972e6),LL(0x34396ea4,0xc069b953),L_(0x000000fb), + LL(0xa4c22061,0x30374f9c),LL(0x83feabc1,0x5043f74b),LL(0xf24a71b6,0x0f58d08b),LL(0x5ac8cda0,0xe7084b9c),LL(0x20120c5a,0xc241d2a2),LL(0xa700c2dd,0x246b4a2f),LL(0xe50e9154,0xe1b127ec),LL(0x240be13a,0x7313d8aa),L_(0x00000117), LL(0x0178da07,0x4ac8c26e),LL(0xa3abe616,0xeaa2008e),LL(0x58d98d73,0x16a0bdbf),LL(0xf5f03b56,0x0dd5224a),LL(0xafd2d956,0x656cc265),LL(0xe30a653c,0x896d53dd),LL(0xc8ac8028,0x8038e832),LL(0xe07a2ee0,0x1df13c5a),L_(0x00000179), + LL(0xf7671c0c,0xdb94fffe),LL(0x0361d956,0xbca8fdc3),LL(0x860aa7a6,0xff4ebfa5),LL(0xca2b724b,0xd506fbfe),LL(0xe572f34f,0x2e88a7d1),LL(0x430c48ff,0x74822e19),LL(0xeb20b178,0x623c0129),LL(0x07cc6f01,0x013ca3db),L_(0x00000040), LL(0xe9244f5d,0x8954a885),LL(0x2bf3bfbd,0xf3969954),LL(0xa7e331fd,0x80dc93a6),LL(0x16b29c51,0xe85d8098),LL(0xfad960c8,0x7931b35d),LL(0x74ab3a3a,0x2e570f29),LL(0xf4422349,0x54904daa),LL(0x5e1f7007,0x16920cf2),L_(0x0000014c), + LL(0x11b4e5eb,0x5620232e),LL(0x8a138aa8,0x46f706eb),LL(0xa03d24cf,0x6e11ca59),LL(0x7337f5d0,0xad37149e),LL(0xfa3336f2,0xb68bf40b),LL(0xcb9ee77e,0xa7c9f76e),LL(0x8719bf3b,0xf9bd4330),LL(0x45e4e081,0xe7e07596),L_(0x00000148), LL(0x4d1bc133,0x8d32cc0d),LL(0x1bd3eff3,0xa11a2038),LL(0xde1eb1a9,0xa2e7f299),LL(0xb382b9cb,0xac50dfdc),LL(0x62fa8c40,0xe2272381),LL(0xa696bb54,0xf025e3e7),LL(0x68bf08ed,0x608f07d7),LL(0x91eb5365,0xd0e1062b),L_(0x00000157), + LL(0xea56e1b7,0x5f8128c4),LL(0x028409b6,0xe5e0d92d),LL(0x8ed0e1c4,0xf3b74f68),LL(0xc55f66d6,0x35d3f9f9),LL(0xdeb2ab80,0x3bde4296),LL(0xa7cb6b64,0x25e29f7e),LL(0x9b9d057f,0x087f5f23),LL(0x17e3fac2,0x1dc271af),L_(0x0000015d), LL(0xd463cbb3,0xd926fd3e),LL(0x014b12b6,0xab9ee679),LL(0x3a1bcb9a,0x1f47e609),LL(0x17170593,0xf44f73dc),LL(0x3b0a4387,0xd2a12e51),LL(0x3ce5c7cd,0x473ec3b7),LL(0x7f341e3a,0x6aef1796),LL(0x09a474c8,0x8fa42a38),L_(0x00000047), +}, +/* digit=32 base_pwr=2^160 */ +{ + LL(0xc2dc9808,0x7f1bc655),LL(0xb688a237,0x67de245f),LL(0xd7a61e34,0x30b260cd),LL(0x9aaf28a3,0x9aeae5d8),LL(0xd4e07803,0x53d349d8),LL(0xd7aea422,0x38cabcfe),LL(0x3728bd24,0x25a9960f),LL(0x58af5683,0x16a09af6),L_(0x0000003e), LL(0x816e52ab,0x1bc21ee4),LL(0x31a5819d,0x26613d4c),LL(0x2a5969b3,0x1a8c1407),LL(0xabfa75ee,0xd357015b),LL(0x7c563bc4,0xd2086ecb),LL(0xa4a80425,0x9b8fafb1),LL(0xc2661a2c,0x547ef737),LL(0xe7afb2d6,0xac816c20),L_(0x0000002f), + LL(0x65726f32,0xb7a9942b),LL(0xa33e2204,0x4a26b80f),LL(0xbbf82a56,0x73c6f40a),LL(0x970dfcc9,0xf9548526),LL(0xf1c38e96,0xd2bbae55),LL(0x2ecb19ab,0x1edd71d6),LL(0x6d97496c,0x2e20adf2),LL(0x17e1cf32,0x714bc0d9),L_(0x00000130), LL(0x76aaf44a,0xb67e29ba),LL(0x1031c67b,0x3d1213c2),LL(0xe37fdfde,0xb4f3b345),LL(0xb46f2bbe,0xef5d5bda),LL(0x53442227,0xbdace910),LL(0x75a65c11,0x0e12dac1),LL(0x99010c36,0x58cdb1cf),LL(0x06f25026,0x3222c871),L_(0x00000187), + LL(0xee441882,0xdeb1c61c),LL(0xf8ff5eb8,0x6080b71c),LL(0x7b2ccc29,0x214b75b5),LL(0xffb3c6aa,0xe80f53b9),LL(0x90a50e70,0xfeb156be),LL(0x0211fd2f,0xa94620e8),LL(0x15422e55,0x085db41e),LL(0x20305265,0x492c355d),L_(0x00000093), LL(0x139e1933,0x50841313),LL(0x976e986b,0xb6d55898),LL(0x36a0866b,0xa443f795),LL(0xe06bc0b2,0x63ba00b8),LL(0x734e5428,0xdd7a73a3),LL(0x213440e4,0xb2efa382),LL(0xb0905af8,0xe95312ec),LL(0xb084f884,0x3260e8ef),L_(0x000001cc), + LL(0x3f172c5e,0xd8ddaafa),LL(0xeb6e8784,0x785f2ae4),LL(0xf77d65ef,0x4e5db162),LL(0xdec5c58d,0x2375c785),LL(0x4a30bffa,0xc92e0f7f),LL(0x0c920bb7,0x294b17a0),LL(0x26f93d72,0x0a9107e0),LL(0xce9dc095,0xcde64911),L_(0x0000018d), LL(0x2b841c67,0x72452329),LL(0xb0490079,0x0e7ddb4c),LL(0x55646515,0xc3ad47f9),LL(0x4b2a0877,0xd8708db4),LL(0xa4c3de4b,0xb4a9131f),LL(0x938e9d24,0x85e650ae),LL(0x80176c45,0x60bb2e49),LL(0x0248559a,0xe3e93182),L_(0x000000cd), + LL(0x28cef71c,0x2e3e2609),LL(0x5311578b,0xb15a4e84),LL(0x66031c77,0xc30c76cc),LL(0xf2c06ffc,0xc352a0e2),LL(0xea471db8,0x9a687b94),LL(0x2e1e184b,0xb1979864),LL(0x08e1a1c9,0x7d1d84cf),LL(0xa36c823a,0x25036462),L_(0x00000135), LL(0x47b77555,0x1b0d298e),LL(0xe7833c92,0x071e1319),LL(0xe5e5ae43,0xbf6e6f4c),LL(0x48ff7cbd,0x44726013),LL(0xec042f31,0x861a992a),LL(0x820461f1,0x0e5f80d4),LL(0x5b728532,0x588846b7),LL(0x4edf14c0,0xdbf695ef),L_(0x0000003f), + LL(0x0f51608c,0x41c6cf4e),LL(0x15b1b366,0x263e7b75),LL(0x6eb6d459,0x041a5063),LL(0x53679a56,0x6ef1d0df),LL(0x9b4abcaa,0xb47a0301),LL(0xae975077,0xd2d427ef),LL(0x62f30c49,0x5a3dfa91),LL(0xc801e565,0xee86df8b),L_(0x00000124), LL(0x68202783,0x26d59f48),LL(0x4e17501a,0x3895e666),LL(0x202e3866,0xaa8031f4),LL(0xd2af7613,0x8ddf2869),LL(0xa21cc1e5,0xe13d84ff),LL(0x5da3159e,0x8f6eb59a),LL(0xb87bbc9c,0xdc5df9b7),LL(0xb8b6006c,0x68fc1771),L_(0x00000158), + LL(0x3e6aa5bb,0x9e7a21c0),LL(0xee3c40e2,0x9e430844),LL(0x91ca8307,0x420584b0),LL(0xfb05a033,0x5dc3546a),LL(0x515d7ef6,0xdfae44d0),LL(0x8e97acb0,0xad35608c),LL(0x1c181a0b,0x85a78e5d),LL(0xd8ba90d8,0xd453e7ca),L_(0x0000010d), LL(0x4b1cba50,0x3d89eff9),LL(0x1828d959,0xb8883419),LL(0x9cd1acbe,0xe7788137),LL(0xd9c16250,0xf51b1fc4),LL(0x2f4d66db,0xbf985d68),LL(0xe78a703c,0x98e4fae0),LL(0x8125e5c9,0x9fe12466),LL(0x7096d179,0xcfe7195c),L_(0x0000004d), + LL(0x96c267db,0x2de8af3a),LL(0xd7a0da68,0xfc2373c7),LL(0x5ae71058,0x00846c04),LL(0xb05a94e6,0x87910867),LL(0x49ec9a78,0x0df20f65),LL(0xaecf973f,0xd4a6c168),LL(0x30604ed3,0x0b50f6bc),LL(0x2722d421,0x1ef35f34),L_(0x000001d2), LL(0x3c89badc,0x32767a9d),LL(0x76ac95ea,0xdc1a4baa),LL(0x3eced60d,0x114219cd),LL(0x2d3cddf3,0x557cfa7d),LL(0x4c14e1ea,0xd40b6e23),LL(0x77a3c466,0x24ae1830),LL(0x9bfca752,0x8ee59e15),LL(0x0d62fa0c,0x91ffb4c3),L_(0x00000106), + LL(0x98c15e86,0xdbdbd0e0),LL(0x13fe0c31,0x3f1495d3),LL(0x611ba4e9,0xcaa1f174),LL(0xd93815b9,0xec434016),LL(0x3bdec28e,0xb9edffc7),LL(0x7d039312,0x995ffc03),LL(0x340b94bb,0xf4d0bdad),LL(0xd62628f0,0xd171e355),L_(0x000001b2), LL(0x874bb93e,0xd381244e),LL(0xb9a019ce,0x2710057d),LL(0xa746e7f7,0x5f04bc77),LL(0xc973f2cc,0x16b90cee),LL(0x45b7cdcc,0x3bf24131),LL(0xf860483e,0xa97598d3),LL(0xd873a041,0x5da07fc7),LL(0x13ee03df,0x1370307d),L_(0x000001cb), + LL(0x04785e61,0x6896551c),LL(0xc769142d,0x1f7de113),LL(0xdc5c38a3,0x6f6444e4),LL(0x619b0fe5,0x442a0f4e),LL(0xc1f930e3,0x0e3d13dc),LL(0xc2166fc3,0x16566439),LL(0x1264bd78,0x043b1c6c),LL(0x55bd407b,0x85bcb31d),L_(0x00000096), LL(0x51809e05,0x37cc449e),LL(0xcbcd15b1,0xc268f122),LL(0xde98d3eb,0xd1094f76),LL(0x2f691855,0x38e9385f),LL(0x940e99ca,0xebc0ca85),LL(0x7a41361e,0x633585a2),LL(0xe77d0dba,0xf4c9fedd),LL(0xffae9098,0x6c29f55e),L_(0x000001b5), + LL(0xa2f1a549,0xf13eb703),LL(0xc846b81d,0xcf6235f8),LL(0xba752969,0x28bf7176),LL(0xa83689cf,0x4f491b5c),LL(0xac203f35,0xa5c72127),LL(0x17a19c66,0xc5180b7d),LL(0xe3fefda7,0x2a895472),LL(0xbc0194d4,0x7cd212ca),L_(0x00000155), LL(0x854caa47,0x822cdfe0),LL(0x7cac3eb5,0x3c7db833),LL(0x13d80239,0x03909920),LL(0xd8e93f09,0xde83b6de),LL(0xb075d1a2,0x53e966c9),LL(0x372a1d5e,0x5b917dec),LL(0x60dd5294,0x8284dac3),LL(0xff014a15,0xac0f873e),L_(0x00000047), + LL(0x73b6bc0c,0xf1bfa63a),LL(0x10296f8e,0xabe3e152),LL(0x9dd0aaa4,0xd3d4285b),LL(0x0c15dad8,0x5f828ba3),LL(0x3be85ac5,0x343ddcee),LL(0x2204e02a,0x532735c7),LL(0x7ba86652,0x2a530b1b),LL(0x262994c6,0x13b8c7c1),L_(0x00000129), LL(0x391a6b29,0x05dfaa4f),LL(0x6b8878ef,0x3e5666ae),LL(0xb1b8a9fa,0xa4a12d5f),LL(0x9ace0b8d,0xc27561ea),LL(0x7b4c8164,0xef8504c5),LL(0xd8cc29d3,0x16570313),LL(0x483fc408,0x3b7b5ec3),LL(0x2f18c762,0x6d721583),L_(0x000001c3), + LL(0xb6ecbf65,0x8116e2fc),LL(0x5e8f5e16,0x59e26819),LL(0x5609fad9,0x8fafa607),LL(0x02dca647,0x7fb0c319),LL(0x1e28746a,0x62d45955),LL(0x6e8dafba,0x53e7625a),LL(0x83169dc2,0xe60b1042),LL(0xebf6fde7,0x8e9c9927),L_(0x00000153), LL(0x7b2d8bde,0x5592a1b4),LL(0x1e6bd0f2,0xcdd5271e),LL(0x566eb6fd,0x7f5033b8),LL(0x4ca0b581,0xd99ab0fb),LL(0xb6096f1e,0x3953fc59),LL(0xcf65a6f4,0x1d2ec4b4),LL(0x1920c542,0xd24e43ac),LL(0xbc37795d,0x3e1940bf),L_(0x00000100), + LL(0x154c2ad3,0x9ab5e4b3),LL(0xa83af5c6,0xaf86c5e5),LL(0x17feec16,0xa5cec56c),LL(0x98ec6557,0x84e83213),LL(0x0f7fdcf1,0x4c26d215),LL(0xffda8a76,0x453ea210),LL(0x9ecd3b2e,0x5f3f4d74),LL(0x45856be9,0x8864bfe9),L_(0x000000bc), LL(0xa68371b9,0x1b7d95b0),LL(0xe827845c,0xee539828),LL(0x8d12cb9b,0xe4618579),LL(0x7d751e1d,0x49a508f4),LL(0xf62e7726,0x71d8ff6b),LL(0x1aa5f1f4,0x1b002961),LL(0xb185989f,0xc7af8411),LL(0x436bb002,0x902fe574),L_(0x000000c6), + LL(0x83b10389,0x5487e28e),LL(0x6c59c4b1,0xdbe03ec9),LL(0x5812b87f,0x800f9a8d),LL(0xa69e4288,0x0042610f),LL(0xa98baf31,0xa41914ae),LL(0x04c78aca,0xad52d4dd),LL(0x200e6b24,0xe64f0db1),LL(0xef061a8b,0xb301c9f3),L_(0x00000118), LL(0x9064a4d4,0xf05bb7bd),LL(0xdb0e1035,0x95a8d7b1),LL(0xbed0afed,0x5aa18c8f),LL(0x1db27276,0xbed5ae9a),LL(0x21d6647d,0x87ff9181),LL(0xd1b9171c,0x25ddbbf6),LL(0x6afd3974,0x58651838),LL(0xd5394b3e,0x6640e3ca),L_(0x00000126), + LL(0x97acef3f,0xdda16fb0),LL(0x1fbdca04,0xe90de335),LL(0xff197a3e,0x7011f9ba),LL(0x10909fc0,0xbf835536),LL(0xa3d538e2,0xd3c214c4),LL(0xd1adfbd9,0x4b2db047),LL(0xa7800e16,0xe30b9e3f),LL(0x3ba0bb0c,0x566a5103),L_(0x000001b3), LL(0x3ccb2552,0xb20301de),LL(0xc8c0dcda,0xaf7c3af2),LL(0x06c79c8a,0x7eefe996),LL(0x38fb5284,0x7cb586d6),LL(0x59bf5673,0xec4f260f),LL(0x36f200b1,0x62ff887d),LL(0x39132913,0xe5ed3b69),LL(0xc40f0d7a,0x2b5086e3),L_(0x000001e0), +}, +/* digit=33 base_pwr=2^165 */ +{ + LL(0x9d8a516e,0x02a3fb8a),LL(0x5fedd472,0xecb3edff),LL(0x7fb9838f,0x762220d1),LL(0x8b9ac40f,0x23ad98dc),LL(0x59a8311e,0xfb615d6c),LL(0x86c784ed,0xe6c85dc4),LL(0xee5f8f84,0x6bbf81a7),LL(0x58d5bb86,0x91b5becc),L_(0x000000ac), LL(0xa1d41ef1,0x007acce1),LL(0x20e9778f,0xd8b8126b),LL(0x438944de,0x437a71b3),LL(0x4e76c73c,0x9a1b4b13),LL(0x14a56abd,0xb7385f9b),LL(0x29b4de8d,0x3115d582),LL(0x91b40784,0x15347258),LL(0xba8c32f8,0xf9f46c55),L_(0x000000ed), + LL(0x99943818,0x2684f683),LL(0x9d27b5d4,0x68a5f913),LL(0xa3ed9c84,0x9f9d03a1),LL(0xe699de7f,0xe3117424),LL(0x6ddd7e41,0x967769d8),LL(0xf6fd89cc,0x0e9e00b5),LL(0x4a6926ea,0x3d7b6393),LL(0x5b068a8b,0x5f0b111c),L_(0x000001a3), LL(0x297d21cf,0x9a2aecb4),LL(0xcf147f52,0x251f8677),LL(0xd2a35774,0xf0bbad3b),LL(0xbedc57bb,0xfe5b3790),LL(0xaa31f1db,0xb3cb7422),LL(0x01bb1e75,0x476bcd99),LL(0xb31cdbf6,0x8c278bd8),LL(0x6fb17125,0xd548282a),L_(0x00000150), + LL(0x19f12734,0x3d48fbed),LL(0xf69ad2bb,0x49bdd26f),LL(0x985b989b,0x61bfbf26),LL(0x451c21eb,0x35f12cad),LL(0xf237a30e,0x680a082d),LL(0x2751a3b3,0x88ebe4c9),LL(0xc7316941,0x0887a8fb),LL(0xa8bdfe94,0xd925bb03),L_(0x00000187), LL(0x356f89f4,0xde19c8b9),LL(0xeab9cd80,0x77afef27),LL(0xf941390d,0x16f538f8),LL(0x8c79f62a,0x9a2c1a2b),LL(0x84a907ee,0xb7aa5d96),LL(0x9877951e,0xfe7d75aa),LL(0x59fbafe1,0xc17b983b),LL(0xb437db42,0xab1072ba),L_(0x000001c1), + LL(0x3a57f7ec,0x4ce56b58),LL(0x1306d958,0xce15377e),LL(0x1e23a49b,0xbad5b26b),LL(0x2d98c317,0xae8b11f4),LL(0xdc523283,0xf50073f0),LL(0xe7af81dd,0xab516099),LL(0x519277c4,0x6a29299e),LL(0x8cb7cfdd,0xf9d5fc0d),L_(0x000000ae), LL(0xad29a85f,0x9213cb42),LL(0x37030b7e,0x364e5e4a),LL(0xf8a54d03,0x771a3941),LL(0xb7d507ec,0xd6f8ad50),LL(0xddb1def4,0xbd493bf4),LL(0xc65eeab3,0x716822a9),LL(0x7e2f6019,0x1d5d463b),LL(0x062fa75d,0x39044728),L_(0x00000094), + LL(0x6ebc6aeb,0x755f610d),LL(0x7e269fb2,0xbc7a68af),LL(0x9a7e6748,0x576c91d2),LL(0xaa653529,0x8b42e1e9),LL(0xe03c250b,0x9e921ac8),LL(0xf313cd04,0x500a0736),LL(0x48b57315,0xfbe580a3),LL(0xd15496dd,0xbe103270),L_(0x000000c6), LL(0xe43286f3,0x42537712),LL(0xfad38cc2,0x5ba8dd4a),LL(0xe8e53c49,0x940cf7d8),LL(0x88cb201e,0xe105c906),LL(0x0310db91,0x14eb5137),LL(0xbdf5c752,0x04b87caa),LL(0x73be9996,0x32ce177d),LL(0x545383f4,0xa2679329),L_(0x00000146), + LL(0x181fa26f,0xe91dfab4),LL(0x8f94d28e,0x500e4763),LL(0x031df707,0x2cdd284c),LL(0xfc76fd9e,0xb532df91),LL(0xdbbb6032,0x95140af2),LL(0x0796b18c,0x1a08045a),LL(0xf970af5c,0xb920694c),LL(0x325b81c7,0xb373cbe7),L_(0x00000087), LL(0x6128ccb5,0x68880de0),LL(0x2e3ad7bc,0xb9bdf74f),LL(0x769e9e60,0x43ac2084),LL(0x0eb7035f,0x71aa1b0a),LL(0x443fc7a8,0x9b9cb064),LL(0x8d6eb3bc,0xcda0b792),LL(0x35030dfe,0xcc362ccd),LL(0x29fff962,0xda9f8e29),L_(0x0000017c), + LL(0x01f40601,0x78cfd6f2),LL(0x993f944b,0x042c6de6),LL(0xe197b472,0x7bbfb051),LL(0xe877f763,0xa554df58),LL(0x82d5094c,0x5d801ed2),LL(0xd75061e2,0x89c183e2),LL(0x060481cf,0xe8a754c6),LL(0x43706037,0x94d020ef),L_(0x00000096), LL(0xc842ce7d,0x1ecea7b9),LL(0x0c3c295e,0xd56a995a),LL(0x2352f8cc,0x2d519fed),LL(0x7a9172aa,0x95d8bcc3),LL(0x546f4f90,0x6b8cea31),LL(0xaeee4bb3,0x3f188de2),LL(0xb3d9fe63,0x63e62bb8),LL(0x9f32b579,0x1d4076c1),L_(0x000000be), + LL(0xa42ee214,0xde6a66c4),LL(0x6c6c7d51,0xc1ce9444),LL(0xd2eee21b,0xeaac0d5d),LL(0x8f8f4a8d,0x5914a3e8),LL(0x755296fd,0x6c394520),LL(0xe647dd87,0x3798ebb4),LL(0x696a7a68,0xc9fd6484),LL(0x66ec9d8e,0x1c7ad1d8),L_(0x0000015a), LL(0xf4ca34e1,0x01e46446),LL(0x0fc27507,0x4431e6d9),LL(0x0b310d40,0x9766b761),LL(0xe5199614,0x04e26686),LL(0xae7e80f7,0x4f7efe74),LL(0x9829aa76,0xd9535c6d),LL(0x5702e183,0x755a23c2),LL(0x457bd92a,0x92bf30a0),L_(0x00000040), + LL(0xf84e8b92,0xa379a575),LL(0xfe2e00bb,0xf17caafe),LL(0xf713e2fe,0xfca28897),LL(0x56bf2a80,0x484598f6),LL(0x6ed19617,0xda495469),LL(0x3fe63788,0x9a48ed8c),LL(0x32c6923d,0xea4ef749),LL(0xdd905e15,0xc8a6856d),L_(0x00000125), LL(0xa7aa5cfa,0xcd183286),LL(0xb2b44bda,0xf345a8f6),LL(0xb4add52f,0xfc8c57af),LL(0x001d629f,0x9943972a),LL(0x1f5f64d0,0xee2dc970),LL(0xc7523ceb,0x078e50ed),LL(0xa1b8fb92,0x98c1c85f),LL(0x69d2866f,0x12275bf9),L_(0x00000129), + LL(0x225d5458,0xae1049c6),LL(0x1f4012ec,0xe45c8c16),LL(0x89c61650,0xe63f6f74),LL(0x97d5ef6b,0x13c990c2),LL(0x7718d93d,0x3b2af534),LL(0x388b9ecf,0xb4a19bd4),LL(0x53cfc179,0xc67cc8de),LL(0xea4e62f5,0xccf5963e),L_(0x00000185), LL(0xd67d72c3,0xa67e3213),LL(0xb4e77b7d,0x2c9d3a3a),LL(0x77d06f89,0x5e517015),LL(0x66b06c1c,0x79e0be47),LL(0x25f78836,0xacaba839),LL(0xf6cdc997,0x60da7988),LL(0x18ee069c,0x75dac3e5),LL(0x028ed009,0x3f7a195d),L_(0x0000014e), + LL(0x77706fdb,0xce2d42d6),LL(0x121b5db1,0xbfb3bb0d),LL(0xc38da042,0xcc50a951),LL(0x690091d1,0xe0527354),LL(0xad28eb90,0x6d30c1cf),LL(0x4621b3fa,0x72f783b8),LL(0xecc35c39,0x05168f18),LL(0x7e7054f1,0x744bd75d),L_(0x00000158), LL(0x437313ab,0xe9455bf8),LL(0xe4a7314e,0x131fad1a),LL(0xb8e1f53e,0xd17720a7),LL(0xbbc2ae3a,0x41e60518),LL(0xde92e4d6,0x53833db7),LL(0xd91c6976,0xa3c1ec67),LL(0x002fce6d,0x353e4fb8),LL(0xf35678d9,0x008548f1),L_(0x0000003d), + LL(0xe8b6d7a1,0xfb16d9c1),LL(0x2d6fbafd,0x4603abda),LL(0xc1c342fe,0xc3174b01),LL(0xf763e29a,0x6ef24fdc),LL(0x081c9b95,0x6ff0c881),LL(0xadc9659b,0xc6c4ce5a),LL(0xb4df1c4c,0x1e8123e9),LL(0x9a4d9154,0xaa2cc087),L_(0x00000047), LL(0x08513662,0x1126c683),LL(0x7efb0353,0xe6d3af24),LL(0x506609c7,0x31b758c2),LL(0x8f74142c,0x5c5f34e5),LL(0x0a3e4fdd,0x3f4b19a6),LL(0xe42c81b5,0xf8223898),LL(0x57c04ea3,0x21041b37),LL(0x44625a29,0x52ac9b84),L_(0x000000ea), + LL(0xafb45817,0x273a1b81),LL(0xe782c707,0x122cfd64),LL(0xf60341eb,0x55516c45),LL(0x19dc551b,0x646dbbd6),LL(0x33015a2f,0xc8d289cb),LL(0x1e2ea096,0x01dbc5f5),LL(0x04e60127,0xb40b7fdc),LL(0xaa434764,0xd6732b6e),L_(0x0000008d), LL(0x3cf9666a,0x4a435c55),LL(0xd7f50159,0xa122c995),LL(0xfe948450,0x52defdfc),LL(0xb5bd3afb,0x272ef1f4),LL(0x702b6fc2,0x86c9c7cf),LL(0x578c41a5,0xce279630),LL(0xafedf374,0x57fd35a9),LL(0xdd29b0d6,0x359e1bc5),L_(0x0000016b), + LL(0x8c313c96,0x81430d8f),LL(0xb3ef9728,0x10f97c7d),LL(0x57ddefb8,0x07066ad1),LL(0xca00506e,0x586f421c),LL(0xdaf65ab2,0x2bf4f170),LL(0x2f754fdd,0xf2415152),LL(0x88f0654f,0x18776438),LL(0x5393b3f2,0xad67f2ff),L_(0x00000150), LL(0x560341d5,0xd6250f20),LL(0xce99e680,0x4c66a708),LL(0xd56bd29f,0x440c3774),LL(0x8b248864,0x9f32acf5),LL(0xad54b8ec,0x99d6dad5),LL(0x45a78e51,0xedbfc6a1),LL(0xa505dcaa,0x28bf41f3),LL(0x8a48ad87,0xae2d610a),L_(0x000000c3), + LL(0x548d3329,0x8505c5bc),LL(0x76050884,0x4dfc2894),LL(0x6b686f2c,0x1e02d4a1),LL(0x9d97a4c0,0x2a447f5a),LL(0x5475b435,0xc828b6cc),LL(0xd2791aa0,0xe6e9d956),LL(0x3b328dfd,0x69ef6cbe),LL(0x988497f9,0xd58525b0),L_(0x000000b4), LL(0x628f0906,0x503dd445),LL(0xc52d4b69,0xdd2f1758),LL(0x438796f6,0x16280d32),LL(0xce2abc46,0x2fb22aa7),LL(0xbdfd0070,0xa5833469),LL(0xd5120c6e,0x80d303f0),LL(0x047308c9,0xd719acb8),LL(0x2a731dfc,0x1df4d436),L_(0x000001be), + LL(0xfb9cf085,0xff178cc9),LL(0x717cdc0a,0xcd1f6670),LL(0x8870fa8c,0xc4d58854),LL(0x99c44c6b,0xd627431a),LL(0xd7a4c31e,0x552f232d),LL(0x85daf88c,0x940140f0),LL(0x1d886818,0x9aa8211a),LL(0x16e4c1b0,0x985e3412),L_(0x00000004), LL(0x4b6cac59,0x3374279c),LL(0xc878a0ba,0x8991eda2),LL(0x84ea0b3f,0x32e3b4cf),LL(0x5e729a39,0xcc5f3102),LL(0xd47222c0,0xb4346c5b),LL(0xc5c9ba94,0x2995032e),LL(0x41a4babe,0x7ddb493f),LL(0x7b6e042b,0x862b224e),L_(0x000001cd), +}, +/* digit=34 base_pwr=2^170 */ +{ + LL(0xfe921c0f,0x079475b7),LL(0x410ea1a2,0xea0fd52e),LL(0x77d4bbcb,0x212e44af),LL(0x260a54b0,0xc66a7d1f),LL(0x4269af2e,0x4993bda8),LL(0xd04f3479,0x0b15e358),LL(0x0bdfadc5,0x1c67a4d3),LL(0x2250ea3d,0x4f317e91),L_(0x00000130), LL(0x2783de4f,0xfb63579e),LL(0xd5ac84fd,0x1abe0cba),LL(0x4b8a145c,0x84082001),LL(0x5d987c51,0xcfadaba8),LL(0xd9eba9aa,0xf5fccfd5),LL(0x82de291a,0x85e551a9),LL(0x372c4557,0x5e2bcee4),LL(0x9d89842d,0x7d7f549c),L_(0x000001cf), + LL(0xd17b0f39,0x5ae74e03),LL(0xb17b1a43,0xfbdcdaf3),LL(0xe5084910,0x63c90868),LL(0x9102285b,0xd8e63c01),LL(0xd5454d88,0x80d185fe),LL(0x50f99e23,0xf9e19dfe),LL(0xce8d3eba,0x728e09d7),LL(0x51277498,0x1de72015),L_(0x00000011), LL(0x777fda1b,0x7188feeb),LL(0xf597fdfd,0x6801e0f6),LL(0x29652f82,0x252e9d17),LL(0x58dec034,0xc6aa0c9d),LL(0x43cc68d0,0x6779b37e),LL(0x9c62a4e7,0x8d509f56),LL(0x0558ca70,0xd90c4133),LL(0x56b5657b,0x3de96569),L_(0x00000006), + LL(0x9ea07210,0xa60d5a9b),LL(0xe0116982,0xb1b1d6d6),LL(0x275ea7bc,0x7f932848),LL(0x607da14c,0x3af5ede1),LL(0x931400f1,0x03040c84),LL(0x3c889175,0x6c5973c9),LL(0xe7a0f614,0x293b333f),LL(0x5267024f,0xfd3993bc),L_(0x00000111), LL(0x81f51a89,0x99b337fa),LL(0xc1ab5f24,0x9bde774a),LL(0x5f059cb6,0x070a9fc0),LL(0xdd8da34f,0x8499182e),LL(0x7e9ea166,0x829389a7),LL(0xaf460691,0x5d843a97),LL(0x6edc8515,0xf45adbcb),LL(0x1fe7439d,0x998d92a0),L_(0x00000006), + LL(0x8e9008a5,0x241f1037),LL(0x92193f76,0x4e7ecf00),LL(0xf8905d70,0x28097f48),LL(0x6b4870ad,0x389acac8),LL(0x2f86eb6f,0xc3b9a313),LL(0xfe5a3ffb,0x9c6b9598),LL(0x14fb463a,0x2f429f10),LL(0x40890855,0x26f84e06),L_(0x000000ad), LL(0x530c94ae,0xd0399afa),LL(0xac70ca6d,0x7da5ef17),LL(0x854eb299,0xe2c80b49),LL(0x4afd62b1,0x77d7cf10),LL(0xf0b13757,0xb8dbecfe),LL(0xdfbd794d,0xf21b1b05),LL(0x47404dbf,0x96f1e68e),LL(0x28abdaf2,0x049bd809),L_(0x00000082), + LL(0xe27f7207,0xf97a3f2a),LL(0x787c8ad9,0xd2383086),LL(0x5dd8b1e6,0xfa851816),LL(0x13c110cb,0x0056cac9),LL(0xffc6bc3c,0xca2b8de4),LL(0x9e086187,0xd596553e),LL(0x4495145a,0xa323bbac),LL(0x799ae6f9,0x259cbe64),L_(0x000001f6), LL(0x53c95598,0x813fad43),LL(0x8941d128,0xee24f158),LL(0x81fe1387,0x7ca3f8b2),LL(0xec9a8f90,0xf4bc106e),LL(0x14a7e155,0x9b049dce),LL(0xacb41c88,0xf8e36863),LL(0x1985dcc1,0xc3075358),LL(0xa78ad338,0x5bf6eb17),L_(0x00000015), + LL(0x764f13da,0x1663cb94),LL(0xef025b32,0xdbea0296),LL(0xc7c10036,0x846d4ce1),LL(0xa4ebe01c,0xdcd331ba),LL(0x36bdd387,0x165ca514),LL(0xbf0ef724,0x1500e9b6),LL(0xf3d31456,0x2e001ed2),LL(0x0726f097,0x03718369),L_(0x00000050), LL(0x8451ea7f,0x6ab1aeac),LL(0x04486599,0x2c2e44e3),LL(0x2f540159,0x22a4d1df),LL(0x2edd9124,0x1b2aa406),LL(0x2d29f8fe,0x3d860387),LL(0xaed1f58f,0x2d78d5df),LL(0xbde871a5,0x65a5c46d),LL(0x6c0a2f54,0xde41cdf5),L_(0x00000189), + LL(0xbc829d92,0xb48b90b7),LL(0x41e85ef8,0x52345df2),LL(0xdc154eba,0x0472e3d9),LL(0xf8b4b2db,0x59486c6e),LL(0xd8c1f468,0x2a84dd3b),LL(0x1d593d50,0xdf33e197),LL(0x775fa504,0x0cadf964),LL(0xa92cc156,0x9927b85b),L_(0x00000083), LL(0x6a0487ca,0xfc3c5102),LL(0x03084458,0x9fa6a745),LL(0xcfa05014,0x51d7c6b7),LL(0x8f18942a,0x8c314152),LL(0x2258ef9c,0x789bb4fe),LL(0x5dcef195,0x1bcd3685),LL(0x2b822a02,0x4e898c2f),LL(0xbded6e36,0x9c74bcf9),L_(0x000001c6), + LL(0xaa163689,0x5ab01bff),LL(0x58bf7fb7,0xba4b1f3e),LL(0x50bc67e3,0xe8b59cab),LL(0xcea4689c,0x0d30cf8a),LL(0xaf1932a3,0xb3d1d8ed),LL(0x92c06e5c,0xfa7949e4),LL(0xb16d8b25,0x6f41db2d),LL(0x10d851b9,0xe9a23b06),L_(0x00000117), LL(0xb154a2b3,0x96d36fe2),LL(0x09d47ca1,0x766e2a61),LL(0xf1863dba,0xa8ef9263),LL(0xe92b5a5b,0xa5da163b),LL(0xcaad9918,0x520c8298),LL(0xf5e79189,0x0a27963a),LL(0x4ab05f91,0x20b8c3b8),LL(0xfd0103c4,0xced227ba),L_(0x000000cc), + LL(0xdd063123,0xa94faf37),LL(0x027545cc,0x751ad636),LL(0x5633398c,0xe2af69a4),LL(0xdb3a42f8,0x9980ca80),LL(0x3ef70c7f,0x2f9f4827),LL(0x03c8083d,0x4bd7694f),LL(0x2297619a,0xcba6106f),LL(0xb857e944,0x5d665130),L_(0x00000068), LL(0xed99704a,0x9b54a475),LL(0xd04dd3a0,0x45640d66),LL(0xe5bc76a8,0xb7f7aff6),LL(0xffcfd663,0x7c51db6e),LL(0x1b1b7d77,0x4ab9daa0),LL(0x312b124a,0xd1e4a043),LL(0xa2044f37,0x1147cf83),LL(0xc70b0257,0x3b2bed84),L_(0x000000bd), + LL(0x240110f2,0x7cc2f02a),LL(0xebf0be7a,0x2ac9b5c2),LL(0x24af14f6,0x9a211862),LL(0x782fa4b4,0x50410353),LL(0xf137e0ec,0x1b26ae96),LL(0x241ccb89,0x2cdf1d3c),LL(0x2b213449,0xac6249df),LL(0x063b93cd,0xae3ea116),L_(0x000001e7), LL(0x243cd7a1,0xf821c5c8),LL(0xd3358ef9,0x1dea9bcc),LL(0x06149e77,0x744a2dd7),LL(0x76a25a6f,0x510fe3ad),LL(0x126f991b,0x2bff6928),LL(0x9ff56b6f,0x26743e80),LL(0xb7342a0d,0x75a539a6),LL(0x1e395f1d,0xade39b8f),L_(0x00000039), + LL(0xc5b17046,0x6c3972f8),LL(0x30453d81,0xa45c6e8c),LL(0xf914e1ed,0x3fd2d983),LL(0x8df9d87a,0x465d7bda),LL(0x0b35e4f5,0x6fe2ce33),LL(0xd6b328dc,0x54ed3799),LL(0xfe08ef94,0x7a45c9eb),LL(0x18e443cd,0xf274d81a),L_(0x000000d6), LL(0x785e8d35,0x203318e2),LL(0x5c35d7f0,0x7b61a2b1),LL(0x652767b2,0x861e2602),LL(0x830e75ba,0x44dc9f10),LL(0x31d6ffa6,0x2ba2cf1f),LL(0x61cf1408,0x6ea5aa79),LL(0x8a5f9d9e,0xc5f5c401),LL(0x983aa3d8,0xa970331d),L_(0x000001d7), + LL(0xaae3e45f,0xebb6d11c),LL(0x08fdeeb8,0x0f274ee5),LL(0x562c576b,0xee620c83),LL(0x10e47bae,0x88c57185),LL(0x279b8105,0x919ff42e),LL(0x927c894a,0x7edf259b),LL(0x23100a00,0x169d16a2),LL(0x2acb9ccb,0xe6d07a5b),L_(0x0000011a), LL(0xfee8415a,0x94d74f07),LL(0xcacca4b5,0x4fb6e0e5),LL(0x08cc549b,0x08e788b7),LL(0xc62edae5,0xc2847dc0),LL(0x9b9ef886,0x64c8eee6),LL(0x9deee406,0xed24b57a),LL(0xa5474323,0xca2b9d44),LL(0x16f12261,0xf3a0da6f),L_(0x00000122), + LL(0x7ec4af3a,0x1798ff0a),LL(0x06583190,0xce45de42),LL(0xa85d801e,0x661ec8ee),LL(0xe6f87169,0x12391657),LL(0xa304ed8e,0x70c4e172),LL(0x8bed9dc1,0xd437a386),LL(0xa1738ce7,0xd75a62c8),LL(0xfe484c38,0x91a53279),L_(0x000000bc), LL(0x9f0ace8e,0xb886c429),LL(0x274adb1a,0x61800342),LL(0x733bc7ba,0x05688d04),LL(0xe49410a8,0x9d06b25e),LL(0x1965c8e7,0x2b710949),LL(0xad70d74f,0x3d588ffa),LL(0x3d3fbe49,0x7220b560),LL(0xe246db1c,0x9e8e9616),L_(0x0000006e), + LL(0x8d34890c,0x59239eaf),LL(0x15030568,0x6578691d),LL(0xd8dd39f6,0xcb5a2489),LL(0x121c7f85,0xf808f7b5),LL(0x952a8bc8,0x99daec7f),LL(0x84b94629,0xd8fb611d),LL(0xbad11517,0xcd32215c),LL(0x967dfc54,0x781070b7),L_(0x000001fe), LL(0x4a7b1ca7,0x3e19d6b8),LL(0x4aecc72b,0xc71b44ff),LL(0xa89c3596,0xc6ae9705),LL(0x99c2157d,0x4697a093),LL(0x95d8264e,0xd6e1d1c0),LL(0x6704d656,0x1e3c6190),LL(0xc7b65104,0x91499ef5),LL(0x466ffc24,0x879387d1),L_(0x00000177), + LL(0x9b81bb10,0x3ae92664),LL(0x35d0ee3c,0xc1f7e1a2),LL(0x20c5e62f,0x8f740935),LL(0xb7936d32,0x451ab7a1),LL(0xc573c20c,0x126bba09),LL(0x3152bb2a,0xa66454b3),LL(0xb17e342e,0x784051fe),LL(0x3681b560,0x1536e827),L_(0x000000a8), LL(0x8f5b18c5,0xcc09f617),LL(0x6e34c103,0x22747cab),LL(0xf8a96755,0xde36110e),LL(0x4dcfc108,0x67ee6834),LL(0x342676fc,0x8502fdf2),LL(0x5b48ae34,0x3b4a1019),LL(0x85dba2fb,0x75c0d58b),LL(0xda298efd,0xb34a8e88),L_(0x0000011f), + LL(0x335496bc,0xd3205850),LL(0x88067d33,0xcf402bd3),LL(0x0074be0b,0x2913e673),LL(0xe8db4e94,0x62a0cb43),LL(0xcf7beef4,0x8c2ead81),LL(0xf06de58a,0x97eccd5d),LL(0x501f23bb,0x1d5954e3),LL(0xa8b8e4e1,0xcdca24b4),L_(0x00000085), LL(0x1d598c1e,0xbf9648fc),LL(0x9987cb09,0xd224f8ad),LL(0xd88fba1f,0x60665a60),LL(0xd86a1d9f,0xf1e7f754),LL(0x26c4ad1d,0x4acf77f7),LL(0x7713e1da,0x938971a2),LL(0x0f78da10,0x3b7fc94e),LL(0x92811d7d,0xbb436839),L_(0x00000004), +}, +/* digit=35 base_pwr=2^175 */ +{ + LL(0x5c665e2b,0x4232c5cb),LL(0x9a24517e,0x26232f5f),LL(0x5981cd79,0x0a27a027),LL(0xe253d4d8,0x783b1d5a),LL(0xd6c00bb7,0x89b5ab0b),LL(0x40ea4c25,0x6c48caf7),LL(0xfc5351cf,0xa482e177),LL(0x2b0e714b,0xb60940fd),L_(0x0000017f), LL(0x8552b5ad,0x11881ba7),LL(0xfb2067a3,0x4ccac10c),LL(0x5d449097,0x9013dcbe),LL(0x8873accd,0xb2cf2a8b),LL(0x380d70e5,0x2c281733),LL(0x4631440b,0x7c3b711d),LL(0x3747bc66,0xd6b99662),LL(0x423c70b2,0x8e7bb383),L_(0x000000d5), + LL(0xa8b11d17,0x2eed227f),LL(0x7fd9a16c,0x916842cb),LL(0xe12a5d02,0x6758564c),LL(0xe59ed474,0x4b48f9be),LL(0x8e675f35,0xece126be),LL(0xf7c75d69,0x8ce3aca2),LL(0x00f88d21,0x9a768d60),LL(0x26ea6ff2,0xb90d290f),L_(0x00000113), LL(0x5d96ef4c,0xa0efb2f0),LL(0xac3a2f2d,0xa99dc276),LL(0x757c443d,0x23ce0342),LL(0x390d2a5e,0x9b674e3b),LL(0x7e7ea78e,0x32e72b98),LL(0xdca485e1,0xb6c21856),LL(0xda17d0d6,0xee5bed8c),LL(0x220788bd,0x3c4e1237),L_(0x000001cd), + LL(0x2333e9ce,0x1a6d9a86),LL(0xaadfe3f4,0x56277e4f),LL(0x389e2b48,0xc71ed641),LL(0x5717d1e3,0x5f0642b9),LL(0x56053a56,0x042b6345),LL(0xafc491b1,0x5ee182db),LL(0x9a47e510,0x6ccadf49),LL(0xf6da1632,0x3b09fd0e),L_(0x00000044), LL(0x05064c02,0x708a5ae7),LL(0xd681e121,0x3b41c0e8),LL(0xcbc4f74a,0xe5968e75),LL(0x47ee9e3e,0x6b8f739b),LL(0xe232789d,0xcd2e53fe),LL(0xd5500a30,0xde9e78f3),LL(0x2cad3174,0x4522aa08),LL(0x295cf494,0x7b02adf4),L_(0x0000007a), + LL(0x0e236499,0x8d70cd44),LL(0x61afc7ec,0xd8467c51),LL(0x4c9aa882,0xbc140872),LL(0x62a215cb,0xad6d3cb9),LL(0x6c4986c1,0x912aaf7a),LL(0x83691332,0x6db2702d),LL(0x7d4a1ecd,0x3fa17e01),LL(0xbf2405e9,0x44b4cf2d),L_(0x000000d9), LL(0x8a064116,0xe42ae3e6),LL(0x395b06fc,0x39938713),LL(0x5bb1098f,0xca3394a1),LL(0x97734c1b,0xe8c0bedb),LL(0x1edfc62a,0x9b0452cb),LL(0xc661bc2f,0x04c79c90),LL(0xe6253323,0x2a0dada4),LL(0x2e4ae434,0x218bc6fc),L_(0x00000101), + LL(0xd1cc1e71,0x144c819c),LL(0x6629502b,0xbd39770d),LL(0x8c2f7831,0xe5075a30),LL(0x4ec45cef,0x641b65dd),LL(0xa56294ef,0xe6aa4eb3),LL(0x75854d3b,0xbdb743c7),LL(0x3fdd169d,0x5176a409),LL(0x181ac2e1,0x0bd27e3a),L_(0x000000a2), LL(0x0ec035b9,0x3f057fe2),LL(0xa4b87bdc,0x3feadb94),LL(0xf7f87024,0x5db56992),LL(0x6a6cdc10,0x57cd02da),LL(0xdd69ecb6,0xc54a8f0e),LL(0xe1da3c2e,0x10cf592f),LL(0x8fe5cc2e,0x3b4989f2),LL(0x37d88e4b,0xe43fe00f),L_(0x00000135), + LL(0xb01bd7fc,0xb25b337f),LL(0xe1e660dd,0xac5d025a),LL(0x6a73c379,0xb69c2605),LL(0xdede6af2,0xb7e81b95),LL(0xa1ae9121,0x6cd030d2),LL(0x5f7f754f,0xb47d1e9a),LL(0xc9b7c0f8,0xe925d238),LL(0xd6fa902c,0xc4a56d32),L_(0x0000002a), LL(0xf95ace42,0x6ab6a655),LL(0x709a356f,0x8fa78d47),LL(0x9d32f258,0xc583f5d3),LL(0xab0a90b8,0x5d68b6be),LL(0x8bc51799,0xcae9d65d),LL(0x4a80ea4a,0xd569fb10),LL(0x2cb3b12f,0x67b09db0),LL(0x4b3e1e5f,0x28308c62),L_(0x0000007b), + LL(0xf5df84a6,0xcdd9e65f),LL(0xf9cc5322,0x1ae57f11),LL(0x997b8e3d,0x4ec38b17),LL(0x52bddbee,0x99728cf4),LL(0x3daa3db0,0xc592cfa0),LL(0xe99b31ff,0x0d3ad893),LL(0x71adf8f6,0x21a14a01),LL(0x748065a6,0x7604c00e),L_(0x0000008a), LL(0x313c6b68,0x45073a51),LL(0x4026740f,0xe3c1a79a),LL(0x03ea00aa,0x7f5aaba8),LL(0xae0bdab5,0x1d349675),LL(0x81ecbbfd,0x611cda3e),LL(0x62377d6e,0xc226bbb5),LL(0x4eee5f15,0xf8b5d257),LL(0x8afee162,0x44124202),L_(0x0000010a), + LL(0x1e93cbca,0x14655922),LL(0x200324a2,0x6c357ebc),LL(0xfbe29569,0x537e73da),LL(0xf1c77b70,0x59d41573),LL(0x12b0a8e9,0xc50a71dc),LL(0xd18455d9,0x7c9b3656),LL(0x7fcbc173,0xd9283b61),LL(0x6acf8093,0x9416c097),L_(0x000000db), LL(0xfa8b5737,0xf0027024),LL(0x3b38a173,0x386bfccf),LL(0xbbc99c54,0xbdb95480),LL(0x8bfbf241,0xcc88d566),LL(0x8353dffb,0x7968e885),LL(0xaa2a216b,0xe22f661f),LL(0xf0cc373d,0x0c189437),LL(0x5601679c,0x68e69c1f),L_(0x0000002b), + LL(0xb1e74cee,0x969661a7),LL(0x9719c192,0x390ae167),LL(0x76ffd55a,0xe6fc4921),LL(0x17827dab,0xb57cd8f2),LL(0x4435c383,0x16123417),LL(0x1dcf73d3,0x8d4cffd7),LL(0x0c91ecfd,0xe6e70928),LL(0x8412502a,0x82f5ef71),L_(0x0000012b), LL(0x019a0e1b,0xecf807dc),LL(0xfb488f96,0x6c466766),LL(0xedde1e48,0x756a682c),LL(0x37d6152f,0x2661ee25),LL(0x5b6f467e,0x96e2b2d4),LL(0xb97a8d49,0x1c1589d1),LL(0xbcf05602,0xdf83ce24),LL(0x04b7cee0,0xda686197),L_(0x0000000c), + LL(0xfca86967,0x34e40148),LL(0xfa3981f6,0x1c864ffb),LL(0x42879632,0x5079d6d1),LL(0x3e4b6047,0x9eef5744),LL(0x6e1e5a87,0xfd7f7f13),LL(0x38d5d2b8,0x19b63788),LL(0x1c2726dd,0xc17815ed),LL(0xf17abcb4,0x58a0242e),L_(0x00000030), LL(0x7bb9a599,0x40e55822),LL(0x3d146be1,0x7f28ae92),LL(0x8852f582,0x8cdd00a5),LL(0x60ada16c,0x7def110e),LL(0x8158a85a,0x1d1152d2),LL(0xa55ae5c6,0x4be61bf1),LL(0x0a31606d,0x8fcf413c),LL(0xd625cdfd,0x2b64bb3c),L_(0x00000131), + LL(0x6c3d008c,0xd11d6fc4),LL(0x0786f8b9,0x26066afc),LL(0x6f28cd76,0x6a57afc2),LL(0x9d41e208,0x2ed8fbfb),LL(0x32ce6027,0xda94edc4),LL(0xf08d764b,0x94110774),LL(0xd4093a46,0x8526b334),LL(0x084fdb6f,0x41d9b8a0),L_(0x0000002d), LL(0x652dbbe1,0x75164543),LL(0x605ecb71,0x6687cd0a),LL(0x3962a1b6,0xfe7869a3),LL(0x347a147b,0x1cab34bd),LL(0x634a95b8,0xbb85dfab),LL(0xbfeffee8,0x4995b282),LL(0xf245a753,0x69b18723),LL(0x5d6e7794,0x653a65a4),L_(0x000001cd), + LL(0x643f2f8c,0xcd45c4a5),LL(0x24a0afd5,0xa6b24112),LL(0x2258c4c8,0xfa87a5ca),LL(0x8f855fed,0x3975cb67),LL(0xc55199f4,0x9edc6298),LL(0x5a48e9a3,0x7312684e),LL(0xf55daba0,0xbfadaeb9),LL(0xc9f5f377,0xc404fb39),L_(0x00000199), LL(0x5a3e0968,0xc70ffd11),LL(0xfcccb869,0xba001f2a),LL(0xfe8068fd,0x124107bd),LL(0x06868f7c,0x28b9fe02),LL(0x3821a909,0x33728dac),LL(0xac94afc5,0x3e9edff0),LL(0x7f67565b,0x0bd10c69),LL(0x250773ba,0x54f9dbea),L_(0x00000070), + LL(0x70ff7fb7,0xad0ad081),LL(0x7b1f1709,0x88afd9fd),LL(0x2c52599e,0xa4b49d9d),LL(0x58896d4a,0x6df73899),LL(0x001961cd,0x1c7f535c),LL(0xd4c3ed4d,0x75c903a7),LL(0x4c699591,0xab8339d4),LL(0x939fc682,0xa4d28226),L_(0x0000016d), LL(0x921bc00d,0xe64a70d3),LL(0x0644b2c5,0xb7245016),LL(0x4fad690f,0x8e863833),LL(0x52268bfe,0xcab84fe2),LL(0xc76f784d,0x75b08768),LL(0xbd5df903,0x97114157),LL(0x49a7a2a6,0x5dbab306),LL(0xb4ae419a,0x15ea0320),L_(0x000001eb), + LL(0x24275a2c,0xc241f782),LL(0xba60fbb4,0xc4fd93b4),LL(0x616268c1,0x0872941b),LL(0x107f7964,0x25e04f20),LL(0x831b4388,0x7786625f),LL(0xc5f61924,0x8de20083),LL(0x791c6d52,0xb0abde39),LL(0x75c25ecf,0x22801b3b),L_(0x0000011f), LL(0xb58e09f4,0x4c6bc5ce),LL(0xb3112937,0x38e27941),LL(0xcee2666e,0xca0e3235),LL(0x8dbee896,0x9b498dea),LL(0x53066000,0x0f289764),LL(0x58ff5f8f,0xfb5ee444),LL(0xa7b5e140,0xf9fb559a),LL(0xac85e138,0x3b186272),L_(0x000000f7), + LL(0x0d7ebeca,0x20feaf54),LL(0x19cc13ae,0x3c5c75ec),LL(0x38ba79ba,0x78f3f1f0),LL(0xf2dc8803,0x911501c4),LL(0x8fb64807,0x6448cf01),LL(0xa8bff66a,0x206b2cb4),LL(0xce9b312c,0x195342ba),LL(0x219fa1d7,0x26a20ccd),L_(0x00000180), LL(0xe91053ed,0x41af0398),LL(0xadc91c1f,0x6166dc26),LL(0x5d9c3eef,0x055887cd),LL(0x90ea6dfd,0x3d270166),LL(0xa4280b95,0x206854af),LL(0x7b358dc6,0xa6ae166a),LL(0x03623eb4,0x34af3892),LL(0xe4258201,0x02a9b53b),L_(0x00000143), + LL(0xbb9f0c61,0x99256667),LL(0x3489213e,0x27fdbbfc),LL(0x1218ca33,0x5630d2c7),LL(0x5a83f00e,0xbdc8df91),LL(0x0d628331,0x28ee96b8),LL(0xbfe73e81,0x6a5f7e06),LL(0x2a7cd331,0xdd16364a),LL(0x8cd2a08b,0x20b4bc74),L_(0x00000127), LL(0x221d90fa,0x814ecb88),LL(0x8b5df20c,0x00fc7920),LL(0x76343a10,0xc99f2520),LL(0x14b68032,0x71413b8a),LL(0x654fe0dc,0x9a173cb4),LL(0xa9acd97c,0x85a386e9),LL(0x14a40bfc,0x87bf160a),LL(0x849e9970,0xa7001032),L_(0x000000a3), +}, +/* digit=36 base_pwr=2^180 */ +{ + LL(0x77384b0d,0x16c289b4),LL(0xf9601e0c,0x9eabe48c),LL(0x71ddca51,0xb3f199d6),LL(0x3fce7863,0xa3ecba6f),LL(0x2e01be3e,0x67c58c7d),LL(0xfbf4b701,0x4893679a),LL(0x2cb78d1f,0xe019a436),LL(0x15a3d7fe,0xff764615),L_(0x00000185), LL(0x25f2840f,0x160c51fc),LL(0x516e72ef,0x97156a16),LL(0xd9625db3,0xbf6e8398),LL(0x3f5b2c0e,0x651404d6),LL(0xfc5b6523,0xd10c4d87),LL(0x8eef476d,0xf40ffa31),LL(0xe5d39771,0xe3788025),LL(0x98fa2547,0xdce443c2),L_(0x000000e8), + LL(0xb2523e81,0x8e050759),LL(0x42659aef,0xb0377d50),LL(0x2b36823c,0x419b9ae7),LL(0xff957169,0xf46fc17e),LL(0x59705ceb,0xb61ce7ad),LL(0x2fffbd18,0xa7135b60),LL(0xfe9192a7,0x96f2e092),LL(0x30a3a8e5,0x14c4a74d),L_(0x000000cb), LL(0x667c895e,0x3da48897),LL(0xeb732652,0x467afe86),LL(0x5b7a7cf8,0x393a5ee2),LL(0xf2568e46,0xb15dd000),LL(0xb79a3304,0x203f1569),LL(0xd91a36bd,0xa5e938c0),LL(0x1a346459,0x521da127),LL(0x88c575bf,0x2cea24c6),L_(0x0000015b), + LL(0xc8c62a6b,0xeaef0121),LL(0x98cc53c0,0x58d73540),LL(0x925273a9,0xc04448cc),LL(0x73c56bf4,0xc52be46f),LL(0x542b800b,0x39147d47),LL(0x30298d6b,0x44cb5cfe),LL(0xb2312e04,0x9ed4247f),LL(0x4c4d89dd,0x77e09705),L_(0x000000c6), LL(0x460edd6a,0xed4f4d5b),LL(0x9206a582,0xb9ca6130),LL(0x3e18c6dd,0xa3efafa9),LL(0xa68f9bb8,0xb2d783bd),LL(0xb70a52c8,0xc0dda564),LL(0xdbe47728,0x0dc789e7),LL(0xe8a6481c,0xe4119aa3),LL(0x27f421a4,0x522c7bed),L_(0x0000012f), + LL(0xf301ee13,0x055dadf3),LL(0xd3d6ab94,0x8803374b),LL(0xa078817f,0xc730e431),LL(0xe1298465,0xaae8170a),LL(0xba08da98,0x8b779119),LL(0xf12876bc,0x1b8f7410),LL(0xbe46247c,0x67bc98dc),LL(0x18059808,0x0a103176),L_(0x00000068), LL(0xf59de67d,0xd0125b70),LL(0x1682d3d2,0x8c5ad3a0),LL(0x9c7c1b26,0x62fcf59a),LL(0xa095cf63,0x6482c8ad),LL(0x5b79b1ed,0xc253c84e),LL(0xd6952b3b,0x56917d1d),LL(0xdfad9c37,0x5c8f439f),LL(0xa63232aa,0xb95c4651),L_(0x00000156), + LL(0x1f3a0552,0x620ca4b5),LL(0x48133bce,0x765c9fcc),LL(0x710e23a7,0x7a6387e5),LL(0xd9c29479,0xa6621b41),LL(0x9fe4eedd,0x3bf9d9ac),LL(0x5df19f73,0x4cb8a304),LL(0x4f51d70e,0x45d5c96c),LL(0x25c50ad2,0xc3e2641a),L_(0x000000eb), LL(0xb3acd866,0x4b6a5c45),LL(0x9f7d19bc,0x3f85a2b0),LL(0x0758494b,0xd50f6942),LL(0x554c9337,0x40c2407e),LL(0x0ccb9c2f,0xc5dfc1a6),LL(0x11e7e482,0x6ad44e8b),LL(0x0fea5311,0xedd080e6),LL(0x9fd549f4,0x409ed188),L_(0x0000010f), + LL(0x7e7e29c5,0x2b2e558b),LL(0x3e6bc46b,0x4702314f),LL(0x56eeaa30,0x06726fae),LL(0x5ca44a1b,0x2ee6f214),LL(0x0ea8da79,0x829cf968),LL(0x141e7e4c,0x723cb279),LL(0x45b326cd,0xdac514c6),LL(0x5e8e8931,0xb9bb3b3d),L_(0x000001de), LL(0x61e5ed08,0x4a34e74e),LL(0x83644940,0xe1d4a984),LL(0x1f65c56b,0x3e5f4500),LL(0x062ee718,0xaa764b8e),LL(0x6a39ef75,0x9012ed64),LL(0xbddef450,0x42837f0e),LL(0xfaa786a7,0xf89ab588),LL(0x474accf0,0x7a91f8d7),L_(0x000000c5), + LL(0x1ef31aa7,0x70683b34),LL(0x5ed33b5f,0x2190eb5f),LL(0xf3278604,0x8f6e3b2b),LL(0xdb29e400,0xc911a62c),LL(0xd42f0700,0x688f5189),LL(0x7efff5e3,0xc2de5c25),LL(0xe2d46677,0x6189c193),LL(0x5de47c98,0xa4dc1cca),L_(0x0000015b), LL(0xa7dddac1,0xcaddccac),LL(0xcf555803,0x0778df17),LL(0x5faf93e7,0xb029278c),LL(0x7cfbb523,0xa7546c0e),LL(0x33ef004b,0xd52d052d),LL(0xc8957290,0x54a34c36),LL(0xcc555faf,0xa3e1b89d),LL(0x77136cbc,0x07995587),L_(0x00000007), + LL(0x4760b5ef,0x30fe1ead),LL(0xd1479bf4,0x3a480e70),LL(0xba684ec7,0x54c97c0a),LL(0x99909719,0xd306cb54),LL(0xea1c5645,0xcc5c264c),LL(0x3d9ecc85,0x39efac32),LL(0x465cbfa7,0xe63b20c4),LL(0xe9cad749,0x41d04b4e),L_(0x000000d8), LL(0x13242934,0x860bc182),LL(0x41b298a9,0x7a452bdb),LL(0x51ceda44,0x0786c3f6),LL(0x53ca2965,0x7845a5f1),LL(0x7e0cd8cc,0x5913baf8),LL(0x060bc9cd,0x0312de2e),LL(0x79bfb315,0xf7a14442),LL(0xa16f8265,0x104fcff8),L_(0x00000101), + LL(0x350ffc55,0xd2d93315),LL(0xecd8b90d,0x88f5e22f),LL(0x9eccd42a,0xdc1f662e),LL(0xc4f29c7e,0x42b4d8d9),LL(0x4f6798fc,0xe485f1a4),LL(0x46c699bd,0x6c52567f),LL(0xf81e6fde,0xccefcbe0),LL(0xcd5234c4,0xb5f3a75d),L_(0x00000147), LL(0xc73f9043,0x8ce6bb52),LL(0xbdeaccaa,0x746080b0),LL(0x3424a5b8,0x0eee571d),LL(0x785554a3,0x4bc343de),LL(0x6aadb674,0x44652a58),LL(0x2ff3c998,0x5fd0a875),LL(0x84f6f7fc,0xba89cfbf),LL(0xd08e7a6f,0x3566a002),L_(0x00000104), + LL(0x533b8a60,0x3e2d62d2),LL(0xda0545e5,0x476d9e76),LL(0xb53693d1,0x8749ddb7),LL(0x78864741,0x6623b715),LL(0x737a1960,0xb1899ac7),LL(0xf216ba69,0x057f8862),LL(0xb25babc9,0xcb288274),LL(0x927aa4d0,0xa7dcbe28),L_(0x00000159), LL(0xd9a6f518,0xfa70c9cf),LL(0xfefa0627,0xcdcaaa25),LL(0xceb9750a,0x15a2f18a),LL(0x9cc57e80,0xba45323a),LL(0x0cadb63b,0xe3f19ccd),LL(0xa55c80d9,0x1e511bb0),LL(0x3bb4df11,0x164359dc),LL(0x3e271d06,0x1f1ae900),L_(0x00000000), + LL(0xaa6cb262,0xb186d04e),LL(0xe56a357b,0x750898af),LL(0xb3fa3a15,0x4d60c192),LL(0xc07d177e,0x9679fa78),LL(0xf75650e4,0x3ad024b4),LL(0xfc2fc8b2,0x0bddcaf6),LL(0x559b0ced,0x604f3f34),LL(0x995261e0,0x1b5f8e9d),L_(0x000001a0), LL(0xfb2e6335,0xc5822803),LL(0x102a3be3,0xc4f23418),LL(0x2683d799,0x446dc4f9),LL(0x87d5a82b,0x82fb7bba),LL(0xba06b349,0x859d405f),LL(0xdacb2e84,0xf7fdeed1),LL(0xa51f1588,0x8b67135b),LL(0xc2217c58,0xbd5966c7),L_(0x000000b7), + LL(0x8ed9d71b,0xf4c69057),LL(0x0ee9b6ca,0xb90a3ad0),LL(0x690215b5,0xe1a72991),LL(0x9dc86f3e,0x4e4042ba),LL(0x076b900e,0x7d9520d4),LL(0xf559233d,0xa6fe5f79),LL(0xd16f05cc,0x6290cb9a),LL(0x2c55a35f,0x2d4f8345),L_(0x0000017e), LL(0x02fbcf5d,0xc7fdf1f3),LL(0x78d6c024,0x3c5ac58d),LL(0x180724dc,0xeafba33f),LL(0x0f2d4859,0xa9ec392b),LL(0x9adb7f75,0x10b122b3),LL(0xa1699e54,0x8be6fae5),LL(0xcfb1317b,0x3a96cd81),LL(0x9a5bff09,0x44a057c8),L_(0x00000143), + LL(0xf6d8c638,0xd287d869),LL(0x6aabc1f2,0x26b0f715),LL(0xbdea2e8a,0x8e33c1dc),LL(0x689a9c3d,0x8c56f036),LL(0xa841ff6c,0x527eaefd),LL(0x10032f78,0x0c199e97),LL(0x6215f00a,0xd8293042),LL(0x0262f60a,0xfb4b2139),L_(0x00000098), LL(0x0105c4ab,0xa09207d0),LL(0x2a3ccda5,0x7549d228),LL(0x67ad8625,0x0483ecfd),LL(0x12b83a0c,0x0eee9667),LL(0xe653fd39,0x14bf0bf5),LL(0xdd617912,0x5b9e1025),LL(0x58e59489,0xb42fb14a),LL(0x6b6fe3f4,0xd59f64f0),L_(0x00000022), + LL(0x82f2b927,0xfe39c03a),LL(0x595b30e1,0xa1ad263a),LL(0xcc294836,0xe59896e0),LL(0x55678ebc,0xdab6cc2a),LL(0x3b48be12,0xf27aff9b),LL(0x1525c60c,0x72f22657),LL(0xbfa65ac2,0xe179fdb5),LL(0x957d9762,0x5bc621c4),L_(0x00000066), LL(0xaabb8ddd,0x2e567a04),LL(0xfc24eb81,0xcd0abafe),LL(0x3ab9ba57,0x7ece5b5f),LL(0x94233802,0xfa49f2c9),LL(0x192ad8a9,0x7c6c9e7b),LL(0xd9733712,0x97c62d5b),LL(0x608ec02f,0x3b573c6e),LL(0x90c6dba5,0x100eafa7),L_(0x0000017c), + LL(0x41a926ac,0xea7b4b5d),LL(0x6a5e3301,0x595fce21),LL(0xee8aa9a4,0x4300c92a),LL(0xeb1b3325,0xfb3d0ddc),LL(0xe7231d36,0xdd2028ea),LL(0x0407b0dc,0xb99d20da),LL(0xf0f51dbb,0xe418d5a9),LL(0x31d74a02,0xb34fb225),L_(0x000001ea), LL(0xf7fd4389,0xbfaf4600),LL(0xe8d861a3,0xf167dda3),LL(0x92cf759f,0xc46df950),LL(0x32d3e4f2,0xb7815d1f),LL(0x91ed2fcf,0x6d421190),LL(0x12864b88,0xf9dfcf39),LL(0x04988ed3,0x74a6a7f4),LL(0x44aba25d,0x1a08a720),L_(0x000000d7), + LL(0x4033bcc8,0xd518ffb7),LL(0x2da2c2e9,0x1ae0cd73),LL(0x9a4290d6,0x357cfbc1),LL(0x784c1f06,0x3ca1aed8),LL(0x3fe20989,0x85a8dedb),LL(0x2f87969a,0xc8eb2e93),LL(0x550ff529,0xfbbcc740),LL(0x54bf85aa,0x9d6aa4f5),L_(0x00000124), LL(0xd5bc6372,0x557f4f2e),LL(0xc2efbdc0,0x9d0c30f3),LL(0x262ac2fc,0xd5dddabb),LL(0xa05b87d4,0x769d1cf7),LL(0xfc91e745,0x4d0a4907),LL(0xdcd38c99,0x89250072),LL(0xc453a288,0x0dffae1a),LL(0xe7245800,0xf08702a8),L_(0x000001af), +}, +/* digit=37 base_pwr=2^185 */ +{ + LL(0x06d9177f,0x5e3cbf74),LL(0x39ed5397,0x2f09def0),LL(0x0caf736f,0xbc534da8),LL(0xfcc790fe,0x46448c8e),LL(0xb0ad47e7,0x36b92fa7),LL(0xc7671ca3,0x90e92c64),LL(0x637080ab,0x52dfd8d6),LL(0x5711517b,0xed4b932f),L_(0x00000178), LL(0x56a0257f,0x24412386),LL(0x77234bc0,0x364971ed),LL(0x9b2d316f,0x0cc8b1d0),LL(0xdf4ae5e0,0x307856bf),LL(0x1468fa8d,0xe3791c04),LL(0xfc69805b,0xfa589236),LL(0x0c1fe733,0x89a33762),LL(0x37b57609,0x42b031e7),L_(0x000001e9), + LL(0x8a01e6a2,0x71b4886b),LL(0x83120c39,0xdae7cb78),LL(0xf3efe6ce,0xfd659d28),LL(0xe1699713,0x75625028),LL(0x0252af65,0xcd7c4a21),LL(0x81fe2a3a,0x7efc9c5a),LL(0x2fab4ecf,0x8ae2a5f8),LL(0x92444155,0xf68655c0),L_(0x00000034), LL(0x95495dd4,0xdf9b0e72),LL(0xbb0facca,0xab5a8f70),LL(0x01ed29d2,0x6b65b325),LL(0xf439adfe,0x2e9c2436),LL(0x40a6c720,0xbcd403e2),LL(0x97776531,0x4526a2b6),LL(0x90cd1256,0xa61dc2d5),LL(0x170acdcf,0xac792b64),L_(0x00000126), + LL(0x8be8d883,0x770de7cc),LL(0x95107be3,0x07c65e3e),LL(0x780e3eca,0xcf6ac96f),LL(0x3d615089,0x2549b641),LL(0xf585b5b2,0xacd5da79),LL(0x4c0d8b5f,0x3c8b5c5a),LL(0x970b49ff,0xadd6dfaa),LL(0xc025c0e7,0xdf3f065c),L_(0x00000179), LL(0x0b3c64dd,0xc797b7cd),LL(0xbc308343,0x1f367813),LL(0x138ae118,0xe7bfbf3f),LL(0x1f8c6302,0xe3cc546f),LL(0xef35ea2e,0x904ac34e),LL(0x852c3a0b,0x2596f106),LL(0xb1310ec5,0x1e6e533a),LL(0x763b1938,0x2a9b4abf),L_(0x00000068), + LL(0x29b5e462,0xab5e9c2f),LL(0xc87a1f3a,0x40c3ae00),LL(0x8fdfc7cb,0xf72aade9),LL(0xf671ec86,0xaa376ff2),LL(0x369dd7b2,0x0c4b0748),LL(0x1a9eb6f9,0xe5c39e83),LL(0xb8bdb31a,0xc9ef6929),LL(0x5a4c5224,0xaad6c712),L_(0x000001ba), LL(0x3d80ab90,0x8a32a994),LL(0x0edbbb7c,0x51b7d4fd),LL(0x9eb83ad0,0xbe08eaa8),LL(0x343de0eb,0xc33cc9fb),LL(0xad3c4d0c,0x24b0953f),LL(0x9c30b151,0x582773fc),LL(0x3a021a47,0x75ab2c19),LL(0xddfb8816,0x2171ab73),L_(0x0000011a), + LL(0x8da3d9ef,0x644b8138),LL(0x80531565,0xf0f2d302),LL(0x3bfd457e,0x64c28e98),LL(0x93b685b7,0x24eeda6c),LL(0x2b149454,0x97f74e2b),LL(0x1420398e,0xce3c2017),LL(0x93fa9e0c,0xa9df8bc6),LL(0x0fc6b820,0x951fb9ae),L_(0x00000066), LL(0x52bf8c38,0x06c9ae45),LL(0x500fd912,0x2fbca6d5),LL(0x5e0fd35b,0xe9e18d3d),LL(0x39985525,0x3bfa858d),LL(0x3a3dab8f,0x0bc682dc),LL(0x51f2882f,0x5632ba53),LL(0xd2912672,0xa5d16cfd),LL(0xefb27960,0xa8e18261),L_(0x00000078), + LL(0xf235a5ba,0x39db43f4),LL(0xdd5bbd91,0x4d8ac038),LL(0xc1e864b1,0xbb5ec32b),LL(0x9c3d8682,0x0da419a0),LL(0x7fa3e54d,0xbbcc85f7),LL(0x4911605b,0x16bf46df),LL(0x459ed701,0x42b3919e),LL(0x4a6f67ab,0xc54ccf4e),L_(0x0000016e), LL(0x761f44af,0x78dc3aaf),LL(0x7ec577f5,0x443c49b1),LL(0xcedfe95e,0x4ca71a23),LL(0x80d161de,0x88a46fa9),LL(0xa3a812c1,0x8060703c),LL(0x5d69c965,0x52f25061),LL(0xebe46263,0xf14ae427),LL(0x2518ad4d,0x8ea0658a),L_(0x00000112), + LL(0xb29db4b3,0x3eb4e951),LL(0x73934c0c,0xd205a31b),LL(0xcde75602,0xf7d9ceca),LL(0x652846c3,0xa5604560),LL(0xf53ed6dc,0xfcef8ee2),LL(0xa3dda8b0,0x73763d47),LL(0x5dcfc88c,0x3f72bc6b),LL(0x61afbead,0xb25f5862),L_(0x0000019c), LL(0x706c2fef,0xb896e8ba),LL(0x91189666,0xa5f8d9e7),LL(0x6dc25f9d,0x98f8493f),LL(0x29210ade,0x77e1557d),LL(0xc803167f,0x80aaf764),LL(0x746e916c,0x9a02bf22),LL(0x6f8c70cb,0x692f9669),LL(0xe6efe144,0x7721e1e7),L_(0x00000116), + LL(0xd6f014ad,0x10e7e9c3),LL(0x91edf75a,0x042dda6a),LL(0xfbe9047f,0x6df69276),LL(0x497f9141,0xfce4035a),LL(0xab982ab7,0x1e6adadf),LL(0xd973b8b6,0x218a9fd9),LL(0xe2c23f1d,0x9e1c8c04),LL(0x2274d47d,0x94c92cb1),L_(0x00000053), LL(0x090ec3de,0x272cecd7),LL(0x6d724d9a,0x50e492db),LL(0xe32d2f19,0x68f82a50),LL(0x6bf40e9c,0x0678afdb),LL(0x4b25727f,0xe6ae7819),LL(0x06b77a36,0xbb096d18),LL(0xeedfa35c,0xf41afd3f),LL(0xc17d9b9f,0xf7315e57),L_(0x00000072), + LL(0xaac42698,0x9e517311),LL(0x90d691a0,0xbbe7b23f),LL(0x3efcc598,0xc5b3ba4a),LL(0xf044505e,0x8a70a012),LL(0x818530c1,0xb73eeaec),LL(0xd4496b66,0x25f453bb),LL(0xabda0862,0x6dcb9832),LL(0x76d60bb1,0x6fccf460),L_(0x00000068), LL(0xa348f0b1,0xdb8646ed),LL(0x1af6f002,0x451f5839),LL(0x3087f4a7,0xa66aaeeb),LL(0x47adc893,0xbec9934e),LL(0x6e6950e9,0xb35294f1),LL(0x31d5e186,0x7bf79296),LL(0x590c3c8b,0xc1942a2c),LL(0x1b804ef3,0xf152ba51),L_(0x00000074), + LL(0xd23e1c8a,0x01715db9),LL(0x41d8f90c,0xbbc2c6b8),LL(0x4e56a842,0x83c0fc75),LL(0x986646d8,0x4fe3bcf5),LL(0x5fdbc4e4,0x2ada0ebd),LL(0x0e534106,0x8c28b66c),LL(0xb1f981f9,0x56f04488),LL(0x79a1b1cb,0x291ee458),L_(0x000000d5), LL(0x98d4263b,0xb7ee4dad),LL(0xb8425937,0x9ce9983c),LL(0xaff51ac5,0x798d12f4),LL(0x772fa5da,0xb536f2fe),LL(0x9c00b0c8,0xb35431b3),LL(0xf4789358,0x2ee8e687),LL(0x664cbdfe,0x29120ae4),LL(0xfa9435a4,0x94cd44dc),L_(0x000000a8), + LL(0xde30af0b,0x64ca10f1),LL(0x7af2cf68,0xf23265e4),LL(0xcdd4b45d,0x4fc85e40),LL(0x3c687440,0x3ef2a535),LL(0x6a698fc3,0x9efabe8e),LL(0x63e4d298,0x18de82a4),LL(0xb24c2816,0x775b0ff1),LL(0xf09e7eee,0xae091929),L_(0x00000039), LL(0x1cbca914,0x7dbc5bb9),LL(0xcc9dfa8d,0x432844d1),LL(0xb35c10a9,0xdb4db17a),LL(0xf5e1db87,0xf9910dba),LL(0x86ff1ebc,0xb2c9c01b),LL(0x189bbc27,0xa7d616b4),LL(0x5df3f754,0xe6cc2fbf),LL(0x274e1d3a,0xb0f2916e),L_(0x000000f8), + LL(0xcbf1d173,0xd9410d43),LL(0xb76d4376,0x656599eb),LL(0x900d071f,0x2fb9b595),LL(0x5fbadcc3,0xe781b5f4),LL(0xc0a2440b,0x50f63654),LL(0xbfcd2d0c,0x1e522100),LL(0x2f21286a,0x4f742889),LL(0x482b198e,0x3ab8b88a),L_(0x00000159), LL(0xd5622874,0x47efa194),LL(0x1f58794f,0xbd93f7de),LL(0xc2129e69,0x5496a993),LL(0x1b271db6,0x8f7ac06b),LL(0x5b18ae06,0x78e56286),LL(0x6111cab0,0xbf1dc2cb),LL(0x641b9597,0x9c602e3b),LL(0x6826b02e,0xeec26ee4),L_(0x000000a9), + LL(0xcc35919a,0x2497cb5e),LL(0x94f52d11,0x4ef3c830),LL(0xdf80522a,0x94fd85cb),LL(0xf72be2d7,0x29671043),LL(0x75499b11,0x540e521b),LL(0x0bd6a835,0x5b01c741),LL(0xc2f40e1e,0x4828498e),LL(0xb6d6e72b,0x3a3120eb),L_(0x00000072), LL(0x87e9147b,0x4ff41c4c),LL(0x7947091e,0x283731b8),LL(0x31294652,0xf259b874),LL(0x0f36636f,0x8ee00f38),LL(0xfc2118ab,0x8017118b),LL(0x5f13103b,0xc3d2d9af),LL(0xc3feb59d,0xca5c4199),LL(0x39888318,0x669fc868),L_(0x000000d1), + LL(0x5d7424e4,0x59ff2a43),LL(0x6be7810b,0x30694fb4),LL(0x78ec13fc,0x92716d06),LL(0x1d9c5aae,0x8fbb9bb8),LL(0x416a4a81,0x1881c6a4),LL(0x15a0a324,0x489236d7),LL(0x23235b6b,0x685caeab),LL(0xa5c2734b,0x61eb3c66),L_(0x000000d4), LL(0x383cc04c,0x2d3601e9),LL(0xd66a0119,0xa6e151c6),LL(0x9e61fd22,0x8339ddd5),LL(0x91be32a7,0x235b6f9c),LL(0x7155449c,0x322c55d0),LL(0xa7e5e410,0xbe0a861c),LL(0xce4ac258,0x0323587c),LL(0xd78b88ca,0x00416746),L_(0x00000149), + LL(0xb1cdbf59,0x59991ed2),LL(0x646f1d97,0xae034cb5),LL(0xcf9f8f62,0xa6cfbf1e),LL(0x9a35acdb,0xb02eab43),LL(0x0993f86d,0x172ffcec),LL(0xc65c756e,0x1b44bc51),LL(0x5ec6620c,0x19230f70),LL(0xc9e7a1a7,0xec7cab96),L_(0x0000015b), LL(0xf7bed1a1,0x28d9a36c),LL(0x391142c7,0x3d4288e4),LL(0x0485a093,0xf59f8fae),LL(0x0209a097,0x94df4e25),LL(0x5fdf8f3e,0xbc0be074),LL(0xb3140419,0xba7e0344),LL(0x5cbb3260,0x95c0673b),LL(0x536a91bd,0x49e9efa6),L_(0x0000007b), + LL(0x9f78e57a,0x123d2b21),LL(0xa3cf981a,0xecb0183c),LL(0x1eddfd07,0x6998ed9f),LL(0x8f90e3c6,0x0e05152f),LL(0xfad41bb2,0x7dab5c5e),LL(0x939419c7,0xca783006),LL(0xde605b32,0x98ae5cd1),LL(0x3d6039cc,0xb8a93393),L_(0x00000160), LL(0x590ae5b0,0x68c4bf82),LL(0xfdf4f711,0x01a66f3e),LL(0xa65b0015,0x241e1da4),LL(0x0665dbdf,0x4c3387ba),LL(0xf15f360d,0xc88fe301),LL(0x8acf4e85,0x061a8e04),LL(0x9ca9957c,0x51bcc011),LL(0x8585dfcf,0x656e99ea),L_(0x000000b7), +}, +/* digit=38 base_pwr=2^190 */ +{ + LL(0x37a0e4fa,0xd96e52e4),LL(0x3aebdd33,0x29f2632f),LL(0x4fd15682,0x2c70c85e),LL(0x4f3be789,0x0a1634de),LL(0xc7d9fb18,0x638b44c2),LL(0x3e6cb175,0xe33499b5),LL(0x0b60dc32,0x2ecdad29),LL(0xcf1fcbab,0x3e0d39d1),L_(0x0000014b), LL(0x5d1854ce,0xb5b7539f),LL(0xb9d47257,0x96df1240),LL(0x561ffc72,0x5e9f9e9a),LL(0x6d945271,0x9f0df30d),LL(0x25aea910,0x1e814b45),LL(0x4c475d52,0x7037d6e7),LL(0x2239acac,0x6b60afbb),LL(0x3a178a1e,0x3b53fdfe),L_(0x000001f6), + LL(0x3a760e88,0x1c8cff61),LL(0x662259f9,0x3af1d337),LL(0x798ee44c,0x04c2f55a),LL(0x7171b763,0x6b42022c),LL(0x451b89de,0xe995dc45),LL(0x0166754c,0x5d7e90f4),LL(0x45f5e9ea,0x1437fe2c),LL(0x5f81a1be,0xdd209d83),L_(0x000000f7), LL(0x34c04a7d,0x2e0b1aaf),LL(0x62ecd7d2,0xad928156),LL(0x3ef4d947,0xdc8b88ed),LL(0x90778ccc,0xd0a75501),LL(0x1ea32bf7,0x615d6df4),LL(0x370394ed,0x6cdce7de),LL(0xa5a2d856,0x5b5d94b6),LL(0xb1500a75,0x79b1d869),L_(0x0000015f), + LL(0x49071d49,0x08ad1120),LL(0x6075e725,0x64ba748d),LL(0xec7f443e,0xf8b1338b),LL(0xe9769df7,0xe04bfcf3),LL(0x276b48ae,0x8c536f3f),LL(0x51362d75,0x91347181),LL(0x7270c649,0x8771d27e),LL(0xd7277846,0x78d1b0b0),L_(0x0000007b), LL(0xf80d5fba,0xb1ff417a),LL(0x8984b71a,0x7e8990b5),LL(0x052a6765,0xa10e9e6f),LL(0xa3a8ec04,0x68613043),LL(0xf8edeb0d,0x94eee364),LL(0x38d79bc5,0xb9b0283c),LL(0x1f04d202,0x240928e2),LL(0xef3aafdb,0xc9d0a1bb),L_(0x0000017c), + LL(0x7b556d5f,0x0eb6f5de),LL(0xe1fefbb4,0x92b00751),LL(0xadf10d77,0x245d985b),LL(0xa78c0fd8,0x1ec6c5bd),LL(0x197cec62,0x6f653476),LL(0xf59e9de3,0x29578b20),LL(0x48b6a349,0xdd081291),LL(0x858df1e4,0x1947d260),L_(0x00000196), LL(0x4a2df7b8,0x72cf54b6),LL(0x702ccf08,0x5ba02c9e),LL(0x4fa2136f,0x4316a469),LL(0x62ca46c9,0x2a601fae),LL(0x6a69d6c7,0xf210ce68),LL(0x3ca9ff0a,0x108647e2),LL(0x7301dc8a,0xbc72d54b),LL(0xc0d011e4,0x8176db4f),L_(0x00000002), + LL(0xaff92b49,0x3a47424a),LL(0x1313f0d7,0xd74e27bd),LL(0xc984d57a,0xa310f0f4),LL(0x7f2762aa,0xf81b869f),LL(0xc1c0028a,0x73626037),LL(0x16619502,0xb6eafd5a),LL(0x02aa41a3,0x7a26f16a),LL(0xee8393c6,0x76a73209),L_(0x00000172), LL(0xc3e1533a,0x770bf892),LL(0xe55dcb14,0x37abc785),LL(0x49d52ff8,0x88ea32f9),LL(0xca2e3d46,0xf41fb729),LL(0x28df94aa,0xd1d7fe42),LL(0x6b931662,0x453917fd),LL(0xf0e1ad47,0x15504e62),LL(0xac5c9f2e,0x74231808),L_(0x00000140), + LL(0x1643c1a4,0x253c03de),LL(0x2114e9cd,0xd7e1536e),LL(0x1b41ae52,0xc0d640bc),LL(0xe9135dab,0xb1a92fcb),LL(0x5a9ef7aa,0xf491bd34),LL(0xd3e367c8,0x6cfcfac3),LL(0x6970f4aa,0x28093242),LL(0x12bc2a52,0x16e9d71c),L_(0x00000064), LL(0x68fd0341,0x14138a14),LL(0x1a1ea358,0xd7ebb375),LL(0x0313c60f,0xb31aaf76),LL(0x7f4e2cd8,0x63d1b78f),LL(0x376b2b87,0xea4746f2),LL(0x9adb2628,0x7159cd2f),LL(0x3fee262c,0x45cb3634),LL(0x258e2340,0x9f14787d),L_(0x0000002e), + LL(0x1f614296,0x5dcc4da5),LL(0xa12ada20,0x6dbe5329),LL(0xd7a52ac6,0x2fb42468),LL(0x898121b3,0xe9f5b08e),LL(0x86a37006,0xf5a42f83),LL(0xbe3e6de0,0x271bec98),LL(0xc405b595,0x486c9095),LL(0x9adc363e,0xec7821b2),L_(0x0000011c), LL(0x3c99889c,0x5b663d6b),LL(0x0c06893d,0xa00328d8),LL(0x8fc3f4f3,0x2578283f),LL(0x3d264389,0x57571710),LL(0x28e44b9a,0xd62bb6bf),LL(0x87dd3c9c,0xd7a2f5d0),LL(0xf55cade8,0xcb792986),LL(0xfa60b3a6,0x5a4730dc),L_(0x00000189), + LL(0x04c2c927,0x8890056b),LL(0xc5944824,0x319a82e4),LL(0x5d37d95b,0x5a8bd6a5),LL(0xd80dfb73,0xa7edec74),LL(0xdb368732,0x60fac47d),LL(0x4f46dbb9,0xb7d14924),LL(0xe4ae15b9,0x255c8153),LL(0xd6f56370,0x73d96dd7),L_(0x00000042), LL(0x8323077c,0xc814ef11),LL(0x2b965e01,0xd2dfe1b5),LL(0xcad600e8,0x2cdd66c5),LL(0xcd44f8d0,0xad1f4964),LL(0xbb170f04,0x6b03da74),LL(0x09f8b95d,0x721ac428),LL(0xc3ee7059,0xab3fd08d),LL(0x69cd062a,0xeb3f55bd),L_(0x0000006f), + LL(0x02685d92,0xb24b23c8),LL(0xbb2912fa,0x700eb07a),LL(0x547f3fb5,0x51442fab),LL(0xf8090af2,0x91ae8f36),LL(0xd9f38784,0x7db330a6),LL(0x213e5f98,0xc4904ecd),LL(0xd61a36f0,0x18124e05),LL(0xdf7f8676,0x7f34e23c),L_(0x00000047), LL(0x2a682aca,0xa540909b),LL(0x1f256aed,0x28d1d810),LL(0x643a464f,0xc1d65b95),LL(0xc56ce322,0xe242b555),LL(0xf79c9363,0x165401c2),LL(0x90b17574,0xb89e030b),LL(0xd9ba6bec,0xad9d3eed),LL(0x3cf323eb,0xb926c391),L_(0x00000199), + LL(0x68365daf,0x6bf21ffc),LL(0x9e0da99b,0x2a11bae7),LL(0x4b632c36,0xd82e9b91),LL(0x8aba8d4a,0xd3edcc69),LL(0x7bcaa8bf,0x0780abc1),LL(0x4b5bb38e,0xf449e1ff),LL(0xb3a33e0f,0x8bf9427c),LL(0x5f153607,0xd3095501),L_(0x000001f9), LL(0xc25e9667,0xa71cb23b),LL(0xf1192121,0xb5c951ff),LL(0xe5267dca,0xde9bed29),LL(0x45f5f5dc,0x62c0dc77),LL(0x5c58640e,0xb410973e),LL(0xab71fb6e,0x2ca60e2a),LL(0xbd3de2bc,0x91e919a4),LL(0xb16029e8,0xcc5ea62b),L_(0x00000057), + LL(0x920ffb1b,0x2f766525),LL(0x5063e19e,0x0c6dbf49),LL(0x2d7c8225,0xc1e5d3a2),LL(0x5919b3b0,0xc8eabb36),LL(0x9bd4d72c,0x7daca33a),LL(0xe43be366,0x6a2d3407),LL(0xd8bf85b2,0xcb065c13),LL(0x74ca1514,0x12ff272a),L_(0x000001ed), LL(0x240e3231,0xdfa8142f),LL(0xbfc4ea2d,0xe35ddb6b),LL(0xac61b3dd,0xf38f22ff),LL(0x0b6750d6,0x6e04a783),LL(0x0ae7817b,0x43182e3c),LL(0x5fc3f142,0x70dd88d4),LL(0x8958a84f,0xe8d996f8),LL(0x988beb73,0xfbc25676),L_(0x000000d3), + LL(0x2fb883d8,0xae353f2a),LL(0xb61aaafb,0x473d0ade),LL(0x890f51bd,0xd1b37ae3),LL(0x0f0c4103,0xeca49348),LL(0x0087e22d,0xc669a58f),LL(0x3462ae96,0xd7ec27b9),LL(0x71fe3af0,0x345f63a7),LL(0x5d6f6927,0x415c1403),L_(0x0000008b), LL(0x2047ce82,0x2d78ca1a),LL(0xbf2a2a03,0xffe80d92),LL(0x8144148d,0x41e35712),LL(0xf4375651,0x70453a65),LL(0x4044794e,0x74d6e72f),LL(0xc3b6ed9d,0xc9dec888),LL(0x03c9efa2,0x01d35b17),LL(0x4a8b5ee1,0x0c747556),L_(0x0000016c), + LL(0xfedb9ea3,0x89f7c11a),LL(0xcc1f90fd,0x930eb52d),LL(0x56a442b3,0xb33c2951),LL(0x6f35d3db,0x189b9ef0),LL(0x5065c93b,0x03375bf3),LL(0xb5e57110,0x9efd6440),LL(0xacf2c750,0xada5967b),LL(0x09a6e279,0x2239bfb7),L_(0x00000034), LL(0xdb8bd33e,0x5a1a6302),LL(0x0c057175,0xd07e6a63),LL(0x12ebc219,0xd7415a35),LL(0x5c53acb6,0xffce8b04),LL(0xc61aee58,0xb8a197ba),LL(0x3531c053,0x76809753),LL(0xd0b9df9b,0x5e6fa51d),LL(0xdfc91e09,0x0d89124e),L_(0x0000018d), + LL(0x8909747e,0x7284d674),LL(0x9a35c4f1,0xaebd8339),LL(0x80afa728,0xcd763811),LL(0xe7b55292,0xbfb44242),LL(0x2f4e7b9f,0xa0832cc1),LL(0x4b2452f9,0xeb50e9df),LL(0xfb6f4f77,0x557d53b4),LL(0x081a5219,0x421a55ef),L_(0x00000078), LL(0xda08f2ab,0x71ddd646),LL(0xdc6cd83b,0x827b9770),LL(0x2342c2c2,0x40af5e14),LL(0x1b228d0c,0xc507fb1d),LL(0x01646580,0x8f89f75f),LL(0x38a92b52,0xe00b0563),LL(0x154282c5,0x27686a53),LL(0x4f688875,0xa595819d),L_(0x000000ac), + LL(0x5b121bb1,0xfd31a6ee),LL(0x6472e541,0x1922fc41),LL(0xcfaa3052,0xffa68d9b),LL(0x6480d380,0xb9a18b55),LL(0xe83a1c00,0xb0e4740a),LL(0x0caf0d03,0x6f130693),LL(0x4ea7894d,0x36b54495),LL(0x3a9ed5ca,0x2a06c77e),L_(0x0000019d), LL(0x6328956b,0x8cad3c5b),LL(0x903ec0c4,0x38be6a97),LL(0x4788849b,0x6a8af4cc),LL(0xb82169df,0x753b96f7),LL(0xf48e2aee,0xbe19a762),LL(0x3765ed66,0xc53900a8),LL(0x5283437e,0x77012317),LL(0x86b0a458,0x28a77627),L_(0x00000076), + LL(0xb5408c0e,0x1466bddd),LL(0x7d090375,0x68631831),LL(0x1d77faab,0xfd6f5c35),LL(0xe1c56990,0xed7bc7e6),LL(0x544f54fd,0x65874640),LL(0x9b1f7a03,0xcb87ac9e),LL(0xd060b45a,0x33e1a951),LL(0xd46b22b1,0x419962d4),L_(0x000001e8), LL(0x7cb30863,0xb9f34068),LL(0xa3dfc88f,0x545e0d0d),LL(0x7b5897e6,0xbbf7c012),LL(0x8cdc1322,0x5bfb3570),LL(0x13ce8bdc,0xe13ad999),LL(0xe1589aef,0xb6cb7333),LL(0x92265f86,0x5f5d1b9d),LL(0x9dfffba1,0x3f3bb65e),L_(0x0000013c), +}, +/* digit=39 base_pwr=2^195 */ +{ + LL(0x60d3d920,0xe5091b5f),LL(0xae3143dd,0xec304735),LL(0xe360b755,0xf78afe69),LL(0x119298c9,0xe3ed2ff3),LL(0x5c6a7738,0x24d64036),LL(0x06b1298a,0x8b486bf0),LL(0x3448a967,0x81e9050b),LL(0x6d50f02b,0x435dfac4),L_(0x0000006a), LL(0xf1b1ce68,0x59ff13a9),LL(0xfc1bfb85,0x23011f5e),LL(0x1d2b17a5,0xbec4e57b),LL(0xfdcb9ac6,0x53d5a58e),LL(0x109c3a11,0x4b16461a),LL(0xe6c06b2a,0xa5edc709),LL(0xc93e99c5,0x4ed62c80),LL(0x18529aa9,0xb0d33b02),L_(0x00000143), + LL(0xbce7cc65,0x49c78f7a),LL(0xe90f1135,0x6489c7f6),LL(0x7145775f,0xbe8e5262),LL(0xc353f1ce,0x36a4b927),LL(0xda2f29fc,0x3ef5bace),LL(0x3d4c0acc,0xb8074e6a),LL(0x43a9c64f,0x638d3fd6),LL(0x70fffe4c,0xb73e74c0),L_(0x000000bb), LL(0x5efbd2cd,0x9bf19e6e),LL(0xe86655bd,0x7942ab0c),LL(0xe82b0e8c,0xb1c0c790),LL(0x2f2b552c,0x9dab8e1e),LL(0x390a098c,0xa67eba46),LL(0x9b4d9810,0x6a4756fc),LL(0xc97785ec,0x8fe8cb25),LL(0xf5f5b6c1,0xf04de215),L_(0x000001ea), + LL(0x3e59c5ce,0x3ea8b15a),LL(0xda44d978,0xd1bea64a),LL(0xe489d3d2,0x8d887f59),LL(0xcaf7d8fe,0xf6f90986),LL(0x76e4ba07,0xeeb4dfe6),LL(0x19aece18,0xaf8390c7),LL(0x4b163792,0x8ecf88f9),LL(0xfe44fa1c,0xa188e3dd),L_(0x0000006a), LL(0x631704b8,0xceaf9552),LL(0xd06dc6ba,0x319c43cf),LL(0x86d813d4,0xc141f1cb),LL(0x1dcaf56d,0x59594026),LL(0xe9fcecb7,0x7334a724),LL(0xda2f8a7f,0xd2a3a54d),LL(0x40d320ca,0x376b3d8c),LL(0xee9740bc,0xf59a7790),L_(0x000000f0), + LL(0xf72bf06c,0x3dcbcaa8),LL(0xcedc2a2b,0x559f9fa4),LL(0x707cbdc6,0x65301ff4),LL(0xb59f1a1d,0xfc409d5e),LL(0xbb9620b3,0x6c53a5fe),LL(0x48b591f7,0x766a3eea),LL(0xc3fc458e,0x1913597e),LL(0xb4cf309e,0x0cff2a5e),L_(0x000000d6), LL(0x8bb24162,0xdda1da6f),LL(0xcd895e57,0x92393366),LL(0x02de8414,0x59ad0cbc),LL(0x65ce8f07,0x893b6573),LL(0xbcfa2564,0x73186b40),LL(0x4fbea748,0xd0156cb0),LL(0x512a03d4,0x0e490f66),LL(0x328165e7,0xb9d1236b),L_(0x0000015c), + LL(0xff9d55c9,0xf62fa8e3),LL(0x4867369d,0xa6218d53),LL(0x3d4df374,0x462df770),LL(0x0e4446f3,0x5002dbe2),LL(0xc6146393,0xee0caf51),LL(0x1bc9af4e,0x615e075e),LL(0x2e28e88d,0x750b8016),LL(0xc58c8ffa,0xc7d3f7ff),L_(0x0000019e), LL(0x91860ab2,0x88c92592),LL(0x4340d28a,0xa23735bf),LL(0x72c0db10,0x9e762765),LL(0xb8f03780,0xf1edfe96),LL(0x7d6eee09,0x395f70ab),LL(0x2e30082e,0xa5b4a747),LL(0xa42e66ca,0x42b9fa7f),LL(0x3482cf5e,0x48386fbb),L_(0x00000130), + LL(0xd1d63dbd,0xe4cd39f5),LL(0x09f98c29,0xaa873723),LL(0x561fec44,0xdc9951ea),LL(0xfd07b42d,0x6c46651a),LL(0x34575586,0x7bf78c6a),LL(0xa447b2e0,0x9284f87c),LL(0x9cdea2ee,0x7235d419),LL(0x677e1753,0x3057349a),L_(0x000001cf), LL(0x14229ff9,0xc8f306c8),LL(0xa79e93cb,0x1a7861e7),LL(0x05616521,0x7842d63c),LL(0x95f90f64,0xcf737ed9),LL(0xc0e16cd8,0xff0413e3),LL(0xedcf1408,0xc3a4f30d),LL(0x43a170a9,0x11a0a6b4),LL(0xcc49b5c7,0x21ebf6e0),L_(0x000000a0), + LL(0xd2ecdcea,0xd4a0eaa9),LL(0x7d01a093,0xc04512bd),LL(0x177d0211,0xa88e2872),LL(0xe8ab8a12,0xf6040bce),LL(0xec0d3b20,0xbaded143),LL(0xef133b8e,0xc0271e57),LL(0x57beaa78,0xa57bec42),LL(0x6cf36a58,0xb50afa18),L_(0x000001f2), LL(0x2b962ada,0x54a163f7),LL(0xdc75f9c2,0x9214028b),LL(0xf894f882,0x29ad8172),LL(0x454f24fe,0x0197a015),LL(0xb080990f,0x1b117443),LL(0x1d17b86f,0x15991c9a),LL(0x66059551,0x66f5d53f),LL(0x4e2d70c8,0x1de3adc7),L_(0x000000d4), + LL(0x6bac308c,0xd825f740),LL(0x34b0da8d,0x0fbb496f),LL(0xde870fb5,0x365075e1),LL(0x7841bcf2,0xd3c98322),LL(0x3b8e05ff,0xc39c86d8),LL(0x74cbe33d,0xf0fd6d0e),LL(0x8904ae19,0x6ed62a5a),LL(0x2b1e2805,0xb06988c3),L_(0x000000e9), LL(0x97d2a267,0x4c1cde55),LL(0x05031449,0xc0326e91),LL(0x50606033,0x423b1ee1),LL(0xf18317b0,0x398c9c61),LL(0x5cc474ed,0x96a97237),LL(0x7eb4df47,0x96b52ef0),LL(0x1372ae46,0xb1ed9607),LL(0xabf9d1fe,0xcf8f25ff),L_(0x00000036), + LL(0x31528630,0xd54e33b3),LL(0x4ada5d83,0x74c3835a),LL(0x9759009e,0xdb44c86f),LL(0x44543433,0xb0ab6930),LL(0x244966ca,0x9d760ccb),LL(0xc7b02622,0x48a60f21),LL(0xe78f542a,0xb0eae43b),LL(0x57db1786,0x7809642e),L_(0x000001f7), LL(0xabc5cfbf,0x88276635),LL(0x5fba9138,0xcf1d1a57),LL(0x568aba80,0x955f0fe2),LL(0x9cc142b7,0x00c55c57),LL(0x897ffd8e,0x15579a99),LL(0xb910a1ec,0x58a539a3),LL(0x68c6e345,0xa76c02ea),LL(0x37272cb2,0x81b23d5b),L_(0x00000083), + LL(0x9045b8e2,0x054435bd),LL(0xe377c286,0x12ddcca1),LL(0xd747b1a8,0x3eb9f510),LL(0x775c0ea6,0x4fcce9d3),LL(0x5865c783,0xd37d19f7),LL(0x2eb67bba,0xbbc7cb40),LL(0x53271117,0xd5530a0f),LL(0x600a1a8b,0x320b3908),L_(0x0000011e), LL(0xddabbe5e,0xb10fe3c6),LL(0x3587db17,0x11b65599),LL(0x1c163208,0xad78aa4f),LL(0xe7539751,0x51c18792),LL(0xc229bfb7,0x5719f77d),LL(0xf84f03ce,0xdd5c3eed),LL(0xbb9c60b9,0xc4b8c257),LL(0xe60da1b9,0x2658c345),L_(0x00000004), + LL(0xe70fa9ae,0x80aea17a),LL(0x3cc6237a,0xa1a05142),LL(0xbfbb8572,0x82ef4062),LL(0x1a092a36,0x584063eb),LL(0x083d9b48,0x0ca19b36),LL(0xd64fde39,0x92047044),LL(0x84e4f4c7,0x3a0049a4),LL(0x025a777c,0x234042e3),L_(0x000001eb), LL(0xa8f92448,0x1e5063b2),LL(0xfb85d333,0x72d2c93b),LL(0x0f374579,0x6c2c1440),LL(0x599d4bd1,0xf99fc78f),LL(0xf8d879ab,0x7157a6f4),LL(0x24350117,0x6511ce35),LL(0xf5039be6,0x3e9cc395),LL(0xa82c44a2,0x9a34c956),L_(0x0000003c), + LL(0xe6e7d409,0x83ea2a70),LL(0x4c9ba2b5,0x137328e5),LL(0xd4654390,0xb93501ec),LL(0xd733683a,0x118e98e5),LL(0x89f374dd,0x00d407bd),LL(0x5295b907,0x13b0afb6),LL(0x57db6bfc,0x6b480958),LL(0x95fc47c6,0xef3d4708),L_(0x0000006a), LL(0xaa37df30,0x84543a49),LL(0x5c127536,0xaf148309),LL(0xbf08a1c2,0xcb7176db),LL(0xbab267dc,0xa7bbd2fb),LL(0xabd6efdf,0x8aeeb27e),LL(0xe86eabfc,0xc902ad03),LL(0x4e44e718,0xf09e682a),LL(0x064991f1,0xe6ec4fe0),L_(0x00000084), + LL(0xc501c914,0xa64386af),LL(0x86838cd0,0x4dd63878),LL(0xe353d214,0x2b6e52eb),LL(0x298c7007,0xb94c5abb),LL(0x4bbcef96,0x3cdd0d98),LL(0xfb73d97d,0xe31b50a6),LL(0xd4d6c5d5,0x63019a2f),LL(0xaac04770,0x2424268c),L_(0x00000045), LL(0x1496527b,0x959a4aac),LL(0xe7cd0ef4,0x5fb6b5e8),LL(0xcf4b2051,0x77e30f99),LL(0x1b0c7952,0x70b054fe),LL(0x38ba1d97,0x5de49575),LL(0x947a5a05,0x8fe1e2d6),LL(0x4246cd4c,0x3254f07e),LL(0x238ade18,0x21122733),L_(0x000001a1), + LL(0x99aed77f,0xf6fa1112),LL(0x9c04ed64,0xd4feb2e7),LL(0x7a120999,0x5d57b4f9),LL(0x70550af6,0xd07357d3),LL(0x41340660,0xe4afb7c6),LL(0x05ac084c,0x0826e572),LL(0xae197ca4,0x3ea7fc0b),LL(0x8f07d680,0x1c2a2823),L_(0x0000009b), LL(0xaf454a02,0xb5cdf6d6),LL(0xb32bd0de,0xf3bb89c8),LL(0x1bd8c3f6,0x5deb355a),LL(0x3db355ab,0x2f043ae6),LL(0xd5c6b398,0x0e90987d),LL(0xabe8910f,0x380521ad),LL(0x4bf6a241,0x3dfa044a),LL(0xfb752ed2,0x6a745fd8),L_(0x00000196), + LL(0xaad132cf,0x696e2831),LL(0x49f240e0,0x0d4e57f0),LL(0x3025b776,0xf18f53bc),LL(0x0b5878b5,0x56b2575b),LL(0x576025b0,0x452417b5),LL(0x51986dad,0xa57a7837),LL(0x5444a7c0,0x9f4452b9),LL(0x9f945ebb,0x8aa46532),L_(0x000001a7), LL(0xca0455ee,0xd553d885),LL(0x83b12fcc,0xd68fe49a),LL(0x3da8d9a1,0xb71fad5d),LL(0xa984d589,0x1f435980),LL(0x5db787bb,0x659a3f24),LL(0xa908e510,0xdd95c91e),LL(0xbe7d501b,0x4a9245db),LL(0xdaa920fc,0xccd618d3),L_(0x00000107), + LL(0x58fdd1be,0x26f6dba6),LL(0x1bc799a8,0xcb4e9512),LL(0xf00f6eae,0x56df676a),LL(0xe75a521d,0x29d333ce),LL(0x4eca7d77,0x27fb68ac),LL(0x206d2e50,0xa49aec5f),LL(0xaa272aa4,0x1b6a988f),LL(0x341efc69,0x6924c47f),L_(0x000000e1), LL(0xe6df0f07,0x3afd9193),LL(0x782686ca,0xe7785c7d),LL(0x3c2a9148,0x4c330f1e),LL(0xa49f1fa5,0x82ded4aa),LL(0xde962297,0xb845da08),LL(0x79a993b6,0x0729c991),LL(0xf8fef022,0xad904b0d),LL(0xe6016c6a,0x2a8c39ce),L_(0x00000108), +}, +/* digit=40 base_pwr=2^200 */ +{ + LL(0x938c22f8,0x943a3471),LL(0x837e8130,0xe2773aac),LL(0x4a3c4f46,0xf24010c6),LL(0x2b750229,0x138446be),LL(0x007131ff,0x731813b9),LL(0xc2c90ce7,0xe94672d6),LL(0xdd149a00,0x69dcb075),LL(0x7531381b,0x7f7c96d0),L_(0x00000019), LL(0xb6b38c7b,0x39ced7c6),LL(0xb63d5a97,0xa61fbc4f),LL(0x8f6b6bae,0x075fe4d1),LL(0x6ae1dbab,0xc1ebedbd),LL(0x12c3dbf8,0x6dce109a),LL(0xc087b051,0x4a2962c4),LL(0xa1e1733e,0xf40db685),LL(0x9f800e79,0xcdbc11ad),L_(0x000001d1), + LL(0x663feea7,0x4fde5cbe),LL(0xdd02746e,0x3f440437),LL(0x33232942,0x8cb2a089),LL(0x21f2f603,0x50b4f0e4),LL(0xa8d7b95a,0x18c0b0f4),LL(0x35a473ae,0xc9451cc0),LL(0x8955b22b,0x9c5154ba),LL(0x9d1fd085,0x73fe1d34),L_(0x00000117), LL(0xaff04652,0xe19db868),LL(0x961dcb73,0xeea574f2),LL(0xf8c3e1f9,0xf4327664),LL(0x9b512b73,0xb683e483),LL(0xb02a0ec5,0x0fb615a0),LL(0x7991b38a,0xb1e55bb8),LL(0x3f719551,0x19309417),LL(0x0ba8f164,0x5179fd3c),L_(0x00000183), + LL(0x20ed0fcb,0xe26950f9),LL(0xa5916c61,0x8ac76960),LL(0x2ae5b02a,0x17149cfc),LL(0xda5eb1a5,0x5c8f4a8c),LL(0x9118595b,0x0004518e),LL(0x9e0cc88e,0x9dcbce69),LL(0xb0b05838,0x5edca7cd),LL(0x8f7a0d45,0x48f7b967),L_(0x000000c6), LL(0x773e3080,0xd9ebc5ab),LL(0x32f8567c,0x92748ad1),LL(0x2f890896,0xd6e0eb81),LL(0x83d0c649,0xdc173290),LL(0xed13cd26,0x6815ffda),LL(0x775e539d,0x727168b4),LL(0x09166ff7,0xbfad2565),LL(0x7a36c1d3,0xa58e9174),L_(0x000001a8), + LL(0x46e6e936,0xf2627126),LL(0x96d6c787,0x7ee8f552),LL(0x6540e78b,0x53eb4432),LL(0x2fb88504,0x073a9cef),LL(0x0e4739b6,0x9bbfb39a),LL(0x5b6532c1,0xbec805ba),LL(0x4331c495,0xedb74df4),LL(0x002e8ec8,0xb24b19d3),L_(0x0000014a), LL(0xcbd7ba6c,0x4bae18ce),LL(0x3a66d73d,0xa9e818b4),LL(0x5a439da7,0x422e109d),LL(0xe2bd60c3,0x71574884),LL(0x482785ad,0xf6bd330b),LL(0x8c0c9a5b,0x6c8383da),LL(0x0007cc56,0x2a9a00bf),LL(0xa489783e,0xd0b67256),L_(0x00000090), + LL(0x9d4a8e40,0xd221fba2),LL(0xd46ad86a,0xfddda1e9),LL(0x14fcb5bf,0xf9686431),LL(0x60db0e24,0xb0468c5a),LL(0xa659be98,0x5c91bca8),LL(0xcabd0c78,0x1e072204),LL(0xd9453dfb,0x50ebbe04),LL(0x8aef77cf,0x599b2768),L_(0x000000f4), LL(0xb8b62e34,0x7872d194),LL(0x43334446,0xddbd4e1c),LL(0xaad0f260,0x42324117),LL(0x7d8cfb9c,0xbd6c92ea),LL(0x883e18f4,0x68768225),LL(0x72898dd5,0x59ac483a),LL(0x25923bd3,0xffec7082),LL(0x48de2e57,0x84d8a621),L_(0x00000136), + LL(0xf64d07f7,0x07a33d42),LL(0x4d434a03,0x8948a2a4),LL(0x03ccc6f0,0xbb8f90db),LL(0x6ff7592e,0x69af4969),LL(0x87ff2ae9,0xec7fca3c),LL(0x687414fc,0xd6cec6f5),LL(0xb3255410,0x9a9ae9c6),LL(0x961c9823,0x2da713ea),L_(0x0000010f), LL(0x4284bbf9,0x472d0237),LL(0x86ea89ac,0xd63ca5a6),LL(0x6cd552ac,0xe6161434),LL(0x2fb24ab8,0xdc07d107),LL(0x880d3677,0xd1833f7c),LL(0xd225c8c0,0x17c50635),LL(0x2bf84ae7,0xc1f8a219),LL(0x2e83c678,0xfc9d327f),L_(0x0000003e), + LL(0xbf7ea965,0xe0762dd1),LL(0x7e003dff,0xd60aa791),LL(0x62c54da8,0xfa92fc72),LL(0x21eaa7ed,0xff6dc244),LL(0x62c86ea7,0x29f82d5e),LL(0x68214737,0x535c6df4),LL(0xb69bc00d,0x494bda6b),LL(0xf34e2601,0xa37c7b33),L_(0x00000181), LL(0x1096ecec,0x12da1692),LL(0xcc5db4fd,0x2f945903),LL(0xc4f95586,0x15014cb4),LL(0xf70f6fbb,0x3d80e47a),LL(0x0a6967e2,0xadb489f2),LL(0x65a13ebe,0xa0094906),LL(0xa28958e6,0x9fafaa96),LL(0xda82221f,0xc7b75a31),L_(0x0000006a), + LL(0xbab5dfd8,0x59f2c453),LL(0xe3fa69de,0x0c9b2cc1),LL(0xb6318b0b,0x56b33c17),LL(0x2d5d399a,0x6dc3c1e9),LL(0xf08f8a6f,0x9e28633f),LL(0x51ffb7f3,0xf1fbcd43),LL(0x77388eef,0x9d013e8c),LL(0x953e5ebf,0x98e2766a),L_(0x000001e9), LL(0xbdbfd2f4,0x95e5a481),LL(0x017a31d1,0x1ef3e1ae),LL(0xb5b37267,0x8988b706),LL(0x748e8ba9,0x3916983f),LL(0x0e9de7d3,0x6e3e3c93),LL(0xe7e37cde,0xee4ca324),LL(0xae3cdd99,0x2fb6a772),LL(0x5fda48d8,0x470f3423),L_(0x00000033), + LL(0xa88f1006,0x32101e9d),LL(0xec995155,0xbc724136),LL(0x50786c7c,0x718458f0),LL(0x942d96ed,0xd4b44c20),LL(0xa25702b9,0xf245f9d1),LL(0x060c2adf,0xb57e7b0b),LL(0xb9d35bf5,0x7ec560d8),LL(0x06f41b22,0x66ddd256),L_(0x00000163), LL(0xe70f3385,0xbb3cf7d0),LL(0xaf72af3d,0xf5c80879),LL(0x24797994,0xcff4c536),LL(0x60ff916d,0x9be0e09a),LL(0xab9b1069,0x069c4c8f),LL(0x4df20300,0x1f6d9a1c),LL(0xe23cffcc,0xe8dd8a18),LL(0xf91c6b69,0x08a175c4),L_(0x00000066), + LL(0x95fbe896,0x77feee72),LL(0x5cc61767,0x8880fcfd),LL(0x37faec22,0x520b4347),LL(0xb528d647,0x08c7efa3),LL(0xd89b3eae,0x7f34be1f),LL(0x0837f588,0x08e5ae1a),LL(0x1bd21d07,0xdd6b478f),LL(0x2fe84dcc,0xa5eab71c),L_(0x000001a1), LL(0x834a2481,0xe505f7b4),LL(0x2410091c,0x6e308dff),LL(0xc904e585,0x881cb270),LL(0x8e50edd4,0xb510da38),LL(0x1a9f6193,0xdd2ee182),LL(0x09d449a4,0x27fbd7e1),LL(0x8ae922fd,0x099fa1c5),LL(0xd2acc7bd,0xfa56f751),L_(0x00000073), + LL(0x0a20a859,0x0116816e),LL(0x589d2f96,0x148078e7),LL(0xaaa24c2b,0x28f3d3c2),LL(0x171935f6,0x48826cdd),LL(0x84d3a584,0x4e4018a0),LL(0x3aa25c41,0x20c105fb),LL(0xfbf31507,0x27ff55a5),LL(0x109df084,0xb2e48b26),L_(0x000000a9), LL(0x7739d21b,0xd2b7193f),LL(0xacf34cf4,0x3d27ea07),LL(0xab2591de,0x55176728),LL(0x3ceb2fdd,0x2cd960ff),LL(0x716fc560,0xb6983fee),LL(0x90fd8f68,0xb59a98f6),LL(0xe1bb13d6,0x476cf07b),LL(0x119c8087,0xe73f3c19),L_(0x000001d7), + LL(0x09bcac55,0xcc9f7ef1),LL(0xf3382f38,0x8ea6fbed),LL(0x08f8a371,0x93651490),LL(0x97354cca,0xa5d779cd),LL(0xd6ff00ea,0x17e28bc6),LL(0xcb936676,0xf2c7be3b),LL(0x4d0cca52,0xe6fcf731),LL(0xfe1b3242,0x64c801b7),L_(0x0000017b), LL(0x998790dc,0x13a64152),LL(0x616ab4fc,0x4787beee),LL(0x0f38f16c,0x8c14e216),LL(0x13dc0561,0x5144326b),LL(0xab46b249,0x49417c95),LL(0x0e55d9c5,0x87bf06de),LL(0x4c1e541e,0xc0681d93),LL(0x2c9b452b,0xa73364e9),L_(0x00000032), + LL(0x8a76574f,0x406e1518),LL(0xe6346b0d,0xb53c0598),LL(0xbdfc6afa,0x9ca435a5),LL(0x50f31dc3,0x9cc07001),LL(0x1695c15e,0x1fd27db3),LL(0x80905ca0,0x1aadf518),LL(0xad7428a8,0x926949ce),LL(0xff033643,0x07ed4c7c),L_(0x000000a0), LL(0x44dec074,0x2345ae4a),LL(0xe0173b35,0x3909da4f),LL(0x56f4144f,0xe4ed2bfd),LL(0x95f4401f,0x198f03a8),LL(0x1227b3e8,0x49d6d509),LL(0x249ec281,0xe4d920ef),LL(0xc12324e5,0x0d321781),LL(0x00c158a5,0x04e56106),L_(0x00000049), + LL(0xe0633553,0x3677eb41),LL(0xa7b03785,0x9c729924),LL(0x166ddf87,0xac9990ff),LL(0x9eba58ed,0x2f6b0f44),LL(0x29db9988,0x2b93f534),LL(0x7f4a4f14,0x92b08207),LL(0x695177a9,0xc1d4f27c),LL(0x1d65e607,0xa7f4bdbf),L_(0x000000c5), LL(0x1902ce34,0xc2625795),LL(0x99c8b2c8,0xb763d2c5),LL(0x4d39eb77,0xa75ff101),LL(0xd8865e52,0x2e31245d),LL(0x51ed16bc,0xfc608d17),LL(0xd782bd3f,0x441d7032),LL(0x8f51fc25,0x47fab287),LL(0xe871d582,0x4836c86e),L_(0x000000fe), + LL(0xec4b364a,0xfbb65219),LL(0xd42017be,0x359e7f30),LL(0x3fc15863,0x5c218315),LL(0xb1a3700b,0xf2cbaf1a),LL(0x040dad16,0xb6cd3ff6),LL(0xbf23d44a,0xd045f02a),LL(0x83befb28,0x4160599e),LL(0x467f747b,0xdf89f01d),L_(0x000001ac), LL(0xc40b618b,0xf743241b),LL(0x64d1d40f,0x576ba83f),LL(0x5ece3029,0x4dc64148),LL(0x47769772,0x6d3057fb),LL(0xd175fe83,0x0884e64d),LL(0x33875e4e,0x859df923),LL(0x481b7714,0x655fbae2),LL(0xdef5f5e2,0xbc699a44),L_(0x000001cf), + LL(0x7dce56e1,0xcfdef637),LL(0x3df3dfe4,0x35b39936),LL(0xa715e9e9,0xffaca630),LL(0x1011f820,0x33f64da2),LL(0x222d3bc6,0xc5987552),LL(0x523adab0,0xc95736a8),LL(0x787c715d,0x058fef5b),LL(0x66393c63,0xeecbe32a),L_(0x00000038), LL(0x5434ecf8,0x891f4ace),LL(0x7708ad40,0x51c5f6bf),LL(0xfe89ee25,0xc377ca62),LL(0xe6011a07,0xd24cd2ea),LL(0xd028c949,0xc094a1a4),LL(0xcf84ab99,0x1fed19d9),LL(0x036f7f03,0x0551c154),LL(0x37b50c32,0xede913d4),L_(0x0000012f), +}, +/* digit=41 base_pwr=2^205 */ +{ + LL(0x8936aa0b,0xb069d26c),LL(0xd3718b4b,0x2e3dd1d0),LL(0xeaaab400,0x26ebf3da),LL(0x315a34c4,0x04c67676),LL(0x1eb5f386,0x97e2eb1b),LL(0xbc318051,0x7226db1a),LL(0xf5e17eb3,0x109ad73d),LL(0x97d098f5,0xfde98d37),L_(0x000001eb), LL(0x5982cf08,0x48806f5a),LL(0x5f09406b,0xabd27505),LL(0x4db94328,0xb3c49a50),LL(0x38e43c40,0x08d386ec),LL(0x582b99e6,0x3b07fe47),LL(0x9089cf44,0x7186cac2),LL(0xac474a1b,0x22d982cf),LL(0x7b0368d4,0x59d409aa),L_(0x00000105), + LL(0xba6cb60e,0xf6d82cb3),LL(0x989499c2,0xf86e04fd),LL(0xcb66fb0c,0x35487bb6),LL(0x7e6257cf,0xdbe642cb),LL(0x7caa5a38,0x0132dd97),LL(0xcf0c7ff7,0x9fe7cec8),LL(0x8b24a15a,0x54f2a9f9),LL(0x52eb7ce9,0x66352c75),L_(0x000000a3), LL(0x47aec9e8,0x766fc554),LL(0xced0e96d,0x99065768),LL(0x493166bd,0x2b9adad9),LL(0x28be045e,0x222a08c3),LL(0xae70d305,0x4f554727),LL(0x61d8ec1d,0xfed1873d),LL(0x41e23d82,0x9f1c46d5),LL(0xf348b3f1,0xf15cb42e),L_(0x00000085), + LL(0x82d58220,0x488e8bdb),LL(0xaabd7c77,0xba1084c7),LL(0x67c7272c,0xca6ae765),LL(0xab82a151,0x1ca84a79),LL(0xa826c75c,0x06316ad0),LL(0xf3c64348,0x0dd7f329),LL(0xde3d6a04,0x3f33bd2d),LL(0x689c3e45,0x5cdf3c43),L_(0x00000090), LL(0x8c61be6e,0xb8361cc4),LL(0x624c3291,0xb8a7b622),LL(0x4c3e4e24,0x3c10547d),LL(0x37a21d5f,0xfa09bfc9),LL(0x407a153f,0x54fa325a),LL(0x5c7fa63d,0x8d13bea7),LL(0xfb7c45a4,0x2fe1e55b),LL(0x1a8b8531,0x15e6e55a),L_(0x000001d3), + LL(0x0246d25c,0xaf11f361),LL(0x0ca563e7,0xd246f5c0),LL(0x3dbda22c,0xc1f5f271),LL(0x1517fe92,0x5b82f357),LL(0xae558aff,0xc7e4811a),LL(0xfe93852e,0x0a7d7a0c),LL(0x80c69efa,0x5a9a571e),LL(0xcf0c8dc8,0x625dad5e),L_(0x00000141), LL(0xfa629e03,0x70463933),LL(0x97e91195,0x4d8bdb29),LL(0x1670ff63,0x3758d16c),LL(0xac0e352c,0xc3148942),LL(0xebf5c218,0x789d4077),LL(0x68df9269,0xedd91114),LL(0xc949bb1e,0x1c9e59bd),LL(0xa97ced00,0xd4c36694),L_(0x000000c5), + LL(0xa992abd6,0xe820b690),LL(0x598bc6c2,0x5618c97b),LL(0xdba62f4c,0x4cfa34df),LL(0x13d15fa5,0xe73cd8e4),LL(0xf2867cb6,0x0a135ff7),LL(0xc48f860e,0x8e8f76ce),LL(0xfdd988f5,0x3ad07476),LL(0xcb3a07b0,0x6690129d),L_(0x00000156), LL(0x59630aad,0xf07162de),LL(0x6a1c1e29,0x47eefc5f),LL(0xd695eb4b,0x69323852),LL(0xf81fbfef,0xeb840ba2),LL(0xe9a13161,0x99e6fb6f),LL(0x82ed26e9,0x0282e82e),LL(0xe498cc70,0x4b2c80ab),LL(0x6264860e,0xadc02c02),L_(0x0000012e), + LL(0x9f6dc20b,0x5c25edfa),LL(0x51ff9b10,0x2267d84b),LL(0x77cd497c,0xecebc8bb),LL(0xd41da61c,0x2e90633d),LL(0x0c2e11a1,0x61552b8c),LL(0xe7151d1b,0xfb4a699d),LL(0xa5898fdf,0x74297e23),LL(0x1a45323e,0xea3846f7),L_(0x00000192), LL(0xfe2e5183,0xf83ccca0),LL(0x0905c1e0,0xc44aa9ba),LL(0x0b1cf7ee,0xfedaabc5),LL(0xc2ab4a81,0x7f856296),LL(0xb2c2c3b9,0x7c377576),LL(0x110f594f,0x248077d8),LL(0x0920b595,0x7dcc7073),LL(0xa5e1a393,0x04275ba3),L_(0x0000019e), + LL(0x003d8cbe,0xf2309e12),LL(0x1dd14f55,0x6aafea42),LL(0xd6b6d08d,0x9f501238),LL(0xd63623cd,0xe37ddae1),LL(0x079b78ad,0xc658ecac),LL(0x62a7d933,0xffca3243),LL(0xf37ff209,0xefd095aa),LL(0x8e2c83df,0x1ba236dd),L_(0x000000b7), LL(0x5e0a6e24,0x2d2f9a76),LL(0x1a69b899,0xe6914b5b),LL(0xf621c0e1,0x8472fe93),LL(0xdd02cec9,0x92c73abd),LL(0x8f7b6745,0x3d6f438d),LL(0xeceedfc7,0x290f69f2),LL(0x98f33394,0x0ed2ebb0),LL(0x2536905b,0x9076c523),L_(0x00000010), + LL(0x5e0e658f,0xa4e263b1),LL(0xb787e362,0xf1a72f5c),LL(0xade21c8a,0x3468dd85),LL(0x51d6c477,0xd69f8f93),LL(0x4ea4254f,0xae15e0af),LL(0xdb86c982,0xdd836935),LL(0x98d3a2d5,0xdc232783),LL(0x5ffb0769,0xca75482c),L_(0x000000c6), LL(0x4c2ae6ec,0x043db3d9),LL(0x09230456,0x73642e7c),LL(0x6f9dd795,0x2a8692df),LL(0x2cd98576,0xa83e7242),LL(0x16ac0a49,0xa2e9e20f),LL(0xd3fe59cf,0xd0093708),LL(0x10a46920,0x10c84d0b),LL(0xa5bda12a,0xeef3a35f),L_(0x000001a4), + LL(0x8efb0b81,0x586ad55f),LL(0x8d830110,0xef747d77),LL(0xb3bf603e,0x0f99e447),LL(0xb48e1874,0x9da3060c),LL(0x389d594d,0x10ea78c4),LL(0xc7644272,0xd0f0eafb),LL(0xaf1ebb75,0x7afab007),LL(0xcc569782,0xe37efd54),L_(0x000001db), LL(0xebfccb68,0xf0400a4a),LL(0x474a550e,0x9ca24b23),LL(0xbf9aef56,0x5613d5ac),LL(0xab9d9c2b,0xb8267455),LL(0xbf868bc0,0xdb52868c),LL(0x909956ec,0x50005f46),LL(0x49928d00,0xac611000),LL(0x904632ee,0xeb25bd62),L_(0x0000001d), + LL(0xe148f242,0x2dd2babc),LL(0xa0bb05f4,0xd775106b),LL(0xbff23d31,0xf2919560),LL(0xe97c018c,0x44a63043),LL(0x4871d249,0x87f10683),LL(0x189ec6a3,0x0d74d0f1),LL(0x257dbb86,0xd0bbd041),LL(0xcc6bf0e5,0x0f7bd5b9),L_(0x0000010c), LL(0xad1a6c62,0x9dacf60b),LL(0xde935e97,0x77ba8de8),LL(0x73dfb2df,0xeb7f0da2),LL(0x64121541,0x18d0ee67),LL(0x024e0b69,0x7b37359f),LL(0x84be521c,0xea621f3f),LL(0xcd285848,0xf996c437),LL(0x6391d449,0x64593630),L_(0x00000129), + LL(0x6d04608b,0x807ec468),LL(0x80a83900,0xb77f8649),LL(0x5eb64b76,0x07caea9c),LL(0xc62e7f72,0x0ec672b0),LL(0x465c546e,0x378afe4c),LL(0x4b627b99,0xcc8adc18),LL(0x929649b3,0x8be7d42e),LL(0x967ccf92,0xd72c8057),L_(0x000001e7), LL(0xa6efca22,0x4f172127),LL(0xf3a643dc,0x9bf5975f),LL(0x4fe72fa7,0x90cb1c95),LL(0x4c4df518,0xba142ada),LL(0x799862f3,0xca2d035c),LL(0x68d4ff7c,0x98b9e83b),LL(0x7d49b932,0x13c2887b),LL(0x21991bff,0x550f6a51),L_(0x000000f5), + LL(0x881d7401,0x5a044cc4),LL(0xe24e7a25,0x768d2e23),LL(0xfaed9fe1,0x8f7705f4),LL(0x383ba961,0xd4a1b2c2),LL(0x435ea5ef,0xa2b9797e),LL(0x3b37f12c,0xe7f7c215),LL(0xb091bf0d,0xf2391054),LL(0xb7ba542b,0xf1e35e4c),L_(0x000001d9), LL(0x701310b7,0x9eb25738),LL(0x04099f3f,0x6dcb2223),LL(0x7798cb36,0x4d56786a),LL(0x95c47f22,0x919da3c8),LL(0xdaeee06f,0xb6abb8e6),LL(0xa660ceaa,0xa641a64e),LL(0xa1891535,0xc989455e),LL(0x627a7ec8,0x2de2ad9f),L_(0x000000f1), + LL(0x834e7f6b,0xa4f8a8ed),LL(0x8d0ab54c,0x7e835385),LL(0x86915b58,0x726730be),LL(0xba996ac1,0xe84c9776),LL(0x0ac27d99,0x59603bec),LL(0xbcd0e3fb,0xc7989ede),LL(0x1f1942c9,0xf303b7a8),LL(0x9f4547f6,0x7f3e4ae4),L_(0x00000115), LL(0x53ff8c21,0x01ac096d),LL(0xdb4b7aa1,0x69d169b0),LL(0x9723cdd3,0x802b82f6),LL(0x2051bc9d,0x256afff2),LL(0x3d4a1ea2,0x321bcf00),LL(0x7da3a724,0x26d669c5),LL(0x4ccffc5e,0x72d30cad),LL(0x212847aa,0x2089c0bc),L_(0x000000d0), + LL(0x7dca0317,0xad5ed722),LL(0xe8f1e786,0x8f7b7ae7),LL(0x30b8f677,0x9bd08de3),LL(0x03bfd2ff,0x1955b540),LL(0x599706c8,0xfa5ccf69),LL(0x66c7232f,0xa98d3152),LL(0xa531f734,0x35d69728),LL(0xa518ffd1,0x2fb7fbdd),L_(0x00000104), LL(0xc9f5e869,0x5ce90640),LL(0x7f70dba5,0x4d6b1828),LL(0xa187b391,0x636739ff),LL(0xc3f757a7,0x6788a6b6),LL(0xca8804a7,0xc2a0400e),LL(0x6dfa8acb,0x499f91eb),LL(0x8bd0499a,0x28af9210),LL(0x45056091,0xbfab21ea),L_(0x00000051), + LL(0x35af5ce4,0x33f86de1),LL(0x24f47c0f,0x237c0920),LL(0x0133d426,0x76b14d92),LL(0xdebe095d,0x989c257d),LL(0x7569cd5b,0x8d5f30b4),LL(0xeebd5dcb,0x7daee4b5),LL(0x381f623b,0x5a27d2f9),LL(0xc7fab47d,0x55d628c0),L_(0x000001ba), LL(0x87c8f748,0x04d7a15d),LL(0x0ac1e9b0,0x96216dea),LL(0xb1634ac6,0x3c5fec65),LL(0xf61cf904,0xab711a92),LL(0x3d592940,0x9bf5392f),LL(0x2eefb59a,0x96b616e2),LL(0x6a36ed7e,0x5c5c3417),LL(0xb15b4b78,0x0085b08c),L_(0x00000166), + LL(0x109924ed,0x46d2968a),LL(0x9147a28a,0xfe84ed7a),LL(0x49744c91,0x88e478aa),LL(0xfd889651,0x65a34f30),LL(0x8dc8d99e,0x21fd955c),LL(0x740206f2,0x7ea7cd99),LL(0xdedce892,0xd4f83ab9),LL(0xa7c26d23,0x35d566e8),L_(0x000001f7), LL(0x91728e18,0x0fa5f320),LL(0x3ad9d78b,0x760a4e2a),LL(0x65aca369,0x6812b50f),LL(0x46ee027e,0xdb993f3d),LL(0xe5a7e2b8,0x2acac076),LL(0x60290375,0xa179054a),LL(0xddbfa0d3,0xf87bff0f),LL(0xee0dfeef,0x197178fe),L_(0x00000059), +}, +/* digit=42 base_pwr=2^210 */ +{ + LL(0xbda60a63,0x090aae19),LL(0xcb3f577f,0xe7638c32),LL(0xf59abf93,0x34b2a6dd),LL(0x35486136,0x3c50db1d),LL(0x91b5e651,0x49476ec8),LL(0xf4bbb5bd,0x83b636d2),LL(0x3dd95f7a,0xd5071e3a),LL(0x77c02f69,0x2c32cef9),L_(0x0000017a), LL(0xc6860379,0x9c9ad3cf),LL(0x35f1eec4,0x4e50cb96),LL(0x26b39588,0xd703ca9d),LL(0x3bd6a0e5,0x3fe9036f),LL(0x08ef03a9,0x605b0ecc),LL(0x070faad2,0x6abd3a9b),LL(0xf3494eab,0x7fa81977),LL(0x164f95f6,0x63b07831),L_(0x0000012a), + LL(0x57205d81,0xe8f546e2),LL(0x442871cf,0x87afe8b6),LL(0xd5e346c5,0x748676ba),LL(0xa964afa3,0xca39baf4),LL(0xe1422f71,0x0e9e0a58),LL(0xd62c328b,0xd31cca18),LL(0x07714d71,0x75787f65),LL(0x810168e3,0xd69279ad),L_(0x000000ce), LL(0xb730f78a,0x509d6354),LL(0xec14ff7e,0xbeae80e0),LL(0x9793053f,0x019f7cc0),LL(0xb6b1fd1b,0xe4fca025),LL(0x44558d48,0x7ed4a037),LL(0x86992aae,0x0e2db1c4),LL(0xf0333757,0x557f4b02),LL(0x30117649,0x88191af4),L_(0x00000142), + LL(0x23e0df8d,0x58c8cbc9),LL(0x1732c3e0,0x3466783b),LL(0xf47836e0,0x4713b9a8),LL(0x79e1d15c,0xa517b03d),LL(0xefa174a4,0x63c15938),LL(0x49e8d766,0xea4a3245),LL(0xd01d6313,0xbc5db16f),LL(0x83758c05,0x98199196),L_(0x00000032), LL(0xbf271b78,0x3af2e11a),LL(0x60042746,0xa3ab648d),LL(0x79d1c019,0x5000aba1),LL(0x253b9712,0xd9239c9e),LL(0x0e930854,0x85a1b532),LL(0xab5ac676,0xe00c287d),LL(0x57eaaede,0xe2d767a0),LL(0x43b264bf,0x2e801980),L_(0x000000ef), + LL(0xd715e37a,0x436c808c),LL(0x8615d6bb,0x78232591),LL(0x58c6e6b2,0xca6d68ce),LL(0xa40e8f75,0xc4c37875),LL(0xc01da381,0xbe962879),LL(0x58a155d9,0x5dd3d4cf),LL(0x847d5de7,0xee99fd85),LL(0x8f7f76b4,0x8718ee15),L_(0x0000005a), LL(0xd4c9f66a,0x5302a76b),LL(0x647086e4,0x1b679cdf),LL(0x93b84a7e,0xd412c242),LL(0x92243bc4,0x519ccba0),LL(0xd5c3c375,0x585371f2),LL(0x8ba3d06b,0x90f4c0f2),LL(0x1daa7685,0xf573b409),LL(0x6342e78b,0xd831b73c),L_(0x00000099), + LL(0xf1f9c0d3,0xf2f4b2d5),LL(0xbf3b998b,0x6f543cfb),LL(0x0d744317,0x25e2b138),LL(0xda23008b,0xc81ea703),LL(0xa6df5808,0x322e0c8c),LL(0xdabad20e,0x654aa6ef),LL(0x3a6c3719,0x64c8d439),LL(0xf75f2e54,0x0e935567),L_(0x00000017), LL(0x50778fd6,0xbd5f5197),LL(0xcbe15e1b,0x16df4a37),LL(0x36cef226,0xb2ae2273),LL(0xfaaea71f,0xb8561402),LL(0x40dd546c,0xed28c500),LL(0xa3b837f1,0xe3cde0fb),LL(0x7315fb7b,0x893aced1),LL(0x828da346,0x811cfb0b),L_(0x00000120), + LL(0x136ca413,0x7447323e),LL(0xc3f1d660,0xfd177667),LL(0x0d79142a,0xeab4ffc2),LL(0x1d798fb8,0x8d6c7790),LL(0x65d4f135,0x6db0f7cc),LL(0x3bd9feb2,0xeb9db217),LL(0xf714d78c,0x48ba0ac8),LL(0xa3ca23a0,0xe83bb0ce),L_(0x0000013f), LL(0xe69b95fe,0x3047872d),LL(0x2f7264f0,0x968482d0),LL(0xedcd1afb,0x4afd067b),LL(0x21685d4f,0xd2b0a788),LL(0x8c222e50,0xee57ad29),LL(0x86dde86a,0xb70520ec),LL(0xb933bc16,0x0ddb5005),LL(0x16594b1c,0xca06f19c),L_(0x00000169), + LL(0xbbca315f,0x5bb1b6c3),LL(0x0036d456,0x7469a0dc),LL(0xd48baaad,0x017a26b6),LL(0x27d8ab41,0x02fa6e32),LL(0x15045224,0x0c7090d4),LL(0xdb62af96,0x85ab46be),LL(0x89adad56,0x45b4363b),LL(0x449f71e2,0x1636a279),L_(0x00000056), LL(0xf8377adc,0x4bc2c5ac),LL(0xa5878a73,0x58a681e7),LL(0x18006b8a,0x8426f06f),LL(0xacb84fbb,0xf862f722),LL(0x32b8466b,0x041f4d43),LL(0xe59c6ec4,0xac4fc1fd),LL(0xda852fdc,0xa52e3ee8),LL(0xf6e11234,0x001b1376),L_(0x0000012c), + LL(0x9ddcb7fa,0x44679a2a),LL(0x8069c471,0x3be369b3),LL(0x0de84dbc,0x82ca8262),LL(0xd5e1f28d,0x89e87798),LL(0xa205de89,0x84051f10),LL(0x5c22abac,0xc26a5b9c),LL(0x99bba5fa,0xdd74ecbb),LL(0x359fa6c2,0x94787253),L_(0x0000013f), LL(0x2e2ac09a,0x2ac08c57),LL(0x71535b42,0xc5c720e0),LL(0xa7bd1c3d,0x18f95966),LL(0x0a4b0c9e,0x49a62e3a),LL(0x2faa6c64,0x4f85595c),LL(0x529cbdd4,0x7bb9f75f),LL(0x93955cf4,0x50f46a64),LL(0xdefa5af6,0x84215622),L_(0x00000105), + LL(0xedc6f59f,0xa294c7f6),LL(0xa2e1643a,0x5eabc120),LL(0x41a385d8,0x0ff38f95),LL(0x6b429a90,0xa608b840),LL(0x5f0ae2e2,0xf1d02f3b),LL(0x9b8946a7,0x2525fc8f),LL(0xc76a7386,0x49cc1359),LL(0xca2a7f4d,0x40152b0a),L_(0x00000034), LL(0xbe8aed8e,0x60d4bdb6),LL(0x86d41413,0x937209e4),LL(0x3c716d10,0xf538d0a6),LL(0xa096c4bf,0xd3c035a2),LL(0x04283ffd,0xb280d9ae),LL(0x4964e73c,0x3893b1c0),LL(0x75d67682,0xc2768753),LL(0x005e5f85,0x0d82ec22),L_(0x00000103), + LL(0x8d283446,0x498b2996),LL(0x86abf4d3,0xfde09c12),LL(0x2dfa3c50,0x0e695616),LL(0x29f9b0d2,0xb697398e),LL(0x48792e33,0x568f5e3a),LL(0x7493cab0,0x6ee081c2),LL(0x657411b7,0xb996a914),LL(0x6bba20f2,0x9947f5c4),L_(0x0000006c), LL(0xcc21ceb0,0xf3a30195),LL(0x04798bbc,0x8327746a),LL(0xa982d5b1,0x2b585e77),LL(0xd3a733ef,0x8fc21ff1),LL(0x683b1710,0xf43ba5ab),LL(0xca115f83,0xeb98616c),LL(0xa31d56f2,0x89236402),LL(0x2fd3f97b,0xd91441e5),L_(0x00000043), + LL(0x71daa8fc,0xcd75aec1),LL(0x1ba03e2e,0x3c07bc51),LL(0x57185304,0xca3e327c),LL(0xb1122c0c,0xfb82f00a),LL(0x4ab98ef9,0x143ac664),LL(0xed517312,0xb67dba09),LL(0x3be9088b,0xf6425b41),LL(0x9abf3748,0xb19d9dad),L_(0x000001fb), LL(0x58516a7c,0x937668fa),LL(0x1a5b0042,0xee40f983),LL(0x70389a31,0x7bddb2f1),LL(0xc5b229d2,0x5e0553f6),LL(0x5a0d088b,0xeae9e1a5),LL(0xf99b1b9a,0xcda92dcb),LL(0x5ef8199d,0x7e285536),LL(0x50942301,0xef8656fb),L_(0x00000141), + LL(0x276df335,0x996f91a7),LL(0xbba5b9b6,0x8be8a5f6),LL(0xa13311be,0x1f26ef24),LL(0xfe2a95d5,0xee11bab7),LL(0x684a38b4,0x3233a4f7),LL(0x2ff2caf9,0x3771e476),LL(0x50176c17,0x5e24adb0),LL(0x7e6a96ea,0x59a02a9e),L_(0x000001d1), LL(0xd1540fbe,0x9f444fde),LL(0xc5cef3f3,0x6ce01534),LL(0x25f5b460,0x1d8a8861),LL(0x37e2199b,0xa77157b4),LL(0xea994fb5,0x599e6b65),LL(0xa91dfcae,0x599cf24d),LL(0x48964c92,0x5d9f0d72),LL(0x171d2191,0xc2a827ac),L_(0x0000019d), + LL(0xc7cc5161,0x5e82226c),LL(0x71009ee1,0x4bc92633),LL(0xa4a6f458,0x4b11e8ce),LL(0x27cf64fc,0xa35c3f83),LL(0x247f343b,0x08c548d2),LL(0x5b9231c1,0x8238f13a),LL(0x98e33dc3,0xb0046a52),LL(0x4e6220c7,0xf590670d),L_(0x00000160), LL(0x60df1456,0xc43a8ffe),LL(0xb03d69e6,0xf8867110),LL(0x760c6b46,0x1cbd5f52),LL(0xbfe67f56,0xee1342df),LL(0xf514ecfe,0x7fa3d377),LL(0xeacf358c,0xb7abe871),LL(0xf91db13e,0xf63ff9a1),LL(0xfd2c6720,0xc9c8d118),L_(0x00000048), + LL(0xfcd4da3a,0x01aa7fce),LL(0x5590f28d,0x891c86bc),LL(0x3fde019f,0xc74e219a),LL(0x47bfd522,0x17dfc33e),LL(0xcd902b91,0x1e1f0327),LL(0x19b7adb8,0x46fb1987),LL(0x4aa71b67,0x7c133f73),LL(0xc87d00cc,0x8fc4f89a),L_(0x00000179), LL(0x15897652,0x484cb85c),LL(0x6d5a49dd,0x08cbe8b3),LL(0x0398f1d3,0xc2570a5f),LL(0xcf0588fd,0x75aff023),LL(0x9a086ca6,0x7d708565),LL(0xf0ab637b,0x478e9220),LL(0x4da37998,0x79f64eda),LL(0x9f09ba72,0x8789e929),L_(0x00000049), + LL(0x3cf6f674,0x4d0bf9f0),LL(0xe45ebcfb,0xf49cc75a),LL(0xf02c0b22,0x198a7df8),LL(0xce88b254,0x798e3ccc),LL(0x452bc12b,0xcb1f3272),LL(0xf7e1eeab,0x204a39c3),LL(0x03001038,0xbf6a035b),LL(0x8bb9d05a,0x464b8506),L_(0x000001e2), LL(0x519b1e12,0xff47d24d),LL(0xecef22c6,0x1e6f218f),LL(0xb9743d3d,0x7fe5e0b0),LL(0x0de37bec,0xb84cd289),LL(0x2f608290,0x640acc09),LL(0x0325466e,0xf1f489de),LL(0x523a4381,0x5a2fd923),LL(0x78483089,0xc78d0d2b),L_(0x0000017d), + LL(0x51ca4b89,0x0c9b5cc2),LL(0xcb500f85,0xb99572d6),LL(0xb82356c8,0x9eef8952),LL(0x575ebe20,0x607df288),LL(0x389253a4,0xa421a6b3),LL(0xd513ff9b,0x99f0eb4d),LL(0xc84b56b7,0x253ed789),LL(0xe6a5c4d4,0xbbc17293),L_(0x000000ab), LL(0x98ff217c,0x6930ae01),LL(0x8abc5898,0x12fd1e77),LL(0x94fad4d8,0xf2ff5095),LL(0x6733dcce,0xf10fab65),LL(0x36afad83,0x17d75c59),LL(0xd99578f7,0x8a1a313c),LL(0x16027411,0x0bcd7387),LL(0x46078ec4,0x30a61f54),L_(0x0000001e), +}, +/* digit=43 base_pwr=2^215 */ +{ + LL(0x011cfb71,0x25479ac0),LL(0x785ff67b,0x2f48bcdb),LL(0xc454fd25,0xf62da267),LL(0x4e460f65,0xac759a15),LL(0xe6fa21e0,0xdb56d239),LL(0xfa07770b,0xb91d7cce),LL(0xfe275a8d,0x68f07f46),LL(0xa1529273,0x477f1527),L_(0x00000196), LL(0xd7969a0d,0x36f066b2),LL(0xd81a759c,0x3a664061),LL(0x929c3e1c,0x5ba8c41d),LL(0x033ad63b,0xfdb5a8a4),LL(0xf387b665,0x2b433c84),LL(0x1e742e2c,0x4f2d4d93),LL(0xb030d2de,0x8d631141),LL(0xe3845c24,0xac94286d),L_(0x000000e9), + LL(0x650c039d,0xab7b6907),LL(0xb4f64d44,0x26b42700),LL(0x0576d051,0x2c72c1e2),LL(0x70d2ad71,0x4322ae9e),LL(0x315f4631,0x89904b57),LL(0xef02dfb1,0x24905a45),LL(0x8a7b4701,0xde26cce6),LL(0x5f0db2ca,0x183ba4ac),L_(0x00000004), LL(0x3a42cd20,0x6fcfeb99),LL(0xee9920d8,0x1cc7f2d2),LL(0x46bdb299,0xb71c2095),LL(0x1516a6ea,0x99e62c53),LL(0x95f1492f,0x197ae770),LL(0xe95c2cf5,0x013e12e8),LL(0x2aad7be2,0x60b78cb7),LL(0x0e70b967,0x48ef0032),L_(0x000000aa), + LL(0x7b152b81,0x2adc31d1),LL(0x1cf4d989,0xf817919d),LL(0xea745ea9,0x86caaaf3),LL(0x035cfaca,0xbd62e874),LL(0x533bc33d,0xb1acfb8f),LL(0x2cc2ce8d,0xb212b5b7),LL(0x5b9ba7f0,0x350192b7),LL(0xce04c178,0x39e7b1a3),L_(0x000000bb), LL(0x88563e49,0xaa946b95),LL(0xe4c90142,0x0e515aee),LL(0x5062c2f0,0x99e87538),LL(0xcd39192d,0x52eb943e),LL(0x0c893238,0x0201b73c),LL(0xfbac7e1c,0x1ab36a78),LL(0xc6d833b4,0x58d01a7c),LL(0xe359c01f,0x84ab5208),L_(0x000001b6), + LL(0x7511fae2,0x9afd1135),LL(0x428434f6,0xab322fa2),LL(0xcbe5e3de,0xd89f361e),LL(0xc1b08880,0xc1fbd2b7),LL(0x6a50aa80,0x9e40537e),LL(0x7fdf104d,0xd4f51df5),LL(0xe707164e,0xb78a6cfb),LL(0xd887e3d0,0x0a3d0f36),L_(0x0000012f), LL(0x96365e7f,0x129d87d9),LL(0x64aad3c6,0x2952186a),LL(0xf8224d3c,0x45209284),LL(0xc689c1d4,0x2c194d7b),LL(0x03f44aec,0x0e7c6b2d),LL(0xf18a57e0,0xe28c9eb3),LL(0xfac4981d,0x4b8b7de6),LL(0x55215906,0xb3077009),L_(0x00000134), + LL(0x3a3a13a5,0xbeace249),LL(0xc22b9755,0xd063181b),LL(0x27e6ebf5,0x80b61753),LL(0x0eb1c7f3,0x8b95d0ba),LL(0x791e9667,0x5d4d0f0f),LL(0x5f5189e4,0xdd28c3e4),LL(0x9162d716,0x2eca4da1),LL(0x40913d2a,0xa84739de),L_(0x000000ee), LL(0x85fea8d0,0x3c004f10),LL(0xa6620dad,0xb3680a4e),LL(0x31990981,0x8a6964de),LL(0x3b4c2f57,0xd1986197),LL(0x3b4fdf64,0x5bc5cf00),LL(0xea0f7010,0xbf1dee68),LL(0x0d263581,0x3edd2000),LL(0x8ba6db98,0xac05f412),L_(0x00000043), + LL(0x79147285,0xbe273f4c),LL(0x71c0654b,0xec66bd4d),LL(0xdd0505e9,0xed4771b4),LL(0x4c891619,0x316ff12d),LL(0x821a0542,0x0c65ede4),LL(0xa23cffae,0xb678c0c5),LL(0xbf05e02d,0x32bbf48a),LL(0x91ff4f9e,0xe3d08326),L_(0x0000018b), LL(0x944ec586,0x5c351b2d),LL(0x00e74766,0x3939c0c8),LL(0xfe310474,0xb780a9b2),LL(0x5e63ba55,0x11cfcec0),LL(0xc11119c9,0x322972c9),LL(0x0c8e0043,0x35f5ba3b),LL(0xa0946bc2,0x222b78da),LL(0x622257dc,0x2be73a82),L_(0x000001e9), + LL(0x2b9dae76,0xe9b24e64),LL(0x1b491ac4,0x9716bae3),LL(0x162c28a6,0x192c7196),LL(0x00752a8a,0x10883cfa),LL(0xf0af2cfc,0x77a5388d),LL(0x5f1ffb0c,0xebf78534),LL(0x49abf2a7,0xe9343bc9),LL(0x54bcef89,0x3a94d690),L_(0x00000175), LL(0xa864f2a7,0x1bdde3a5),LL(0x0362ffa7,0x45782cba),LL(0x113c94f8,0xb94efa60),LL(0xb5969326,0xd2b826b0),LL(0x92ab6bc9,0x228e2d7d),LL(0x1f6dc09e,0xe5f07f40),LL(0x3371efd7,0x87e6028d),LL(0x90fcb8fa,0x35577bbe),L_(0x000001a7), + LL(0xcf53147b,0x97a83e73),LL(0x0fba4048,0xd11d0f51),LL(0xfcf9128e,0x6dfde4ab),LL(0x095c92d5,0xbcfa2a47),LL(0xff3cd334,0xa5b6f4d4),LL(0xa2490038,0x5df73169),LL(0x663bcbc9,0x41aba80e),LL(0xa47769e8,0x45877c64),L_(0x00000076), LL(0x2104365a,0xa582938f),LL(0xc439a531,0x43321e6d),LL(0xf7387146,0xee861253),LL(0x52424fe3,0x13590283),LL(0x0a676302,0xe71ab2ae),LL(0xa837702f,0xf460396c),LL(0xf7bce515,0x01882e04),LL(0xd9362399,0x899edf93),L_(0x000000c5), + LL(0x9bd2b2b9,0xc33456a5),LL(0x6dcdccc4,0x97a89ed3),LL(0x865bca41,0xbdb83821),LL(0xf50a59bc,0x46a8f43a),LL(0x47c10299,0xbaa69204),LL(0x03139274,0x1da8242a),LL(0xa899da5a,0x49b0bcc8),LL(0x2caf68d5,0x7ba862a8),L_(0x0000003c), LL(0x4dc88c23,0xc1c2ff36),LL(0x896e10e9,0x10c6c1db),LL(0x7a488fa2,0x58161012),LL(0x6b4ceefa,0x5188acf7),LL(0xea1e2f11,0x72073c50),LL(0xefaa1151,0xe696e16a),LL(0xd65f38a5,0xe4dea3d4),LL(0x6710e2d4,0x849ce811),L_(0x00000165), + LL(0x6cdc17de,0x2c374c6c),LL(0xe3454080,0xbd6a5b20),LL(0x337b0f58,0x40246c40),LL(0x31d7aff9,0x49292d34),LL(0x01dba6a8,0x37486a26),LL(0x41a0f90b,0x12d61cbe),LL(0x782067dc,0x3033f828),LL(0xebc39fcd,0x519d9486),L_(0x00000109), LL(0x026818da,0xf42673be),LL(0xf2e2739e,0x40e906d3),LL(0xd8ecf6f0,0x37b0e1f1),LL(0x5c024d38,0x6708c065),LL(0x3417cf59,0xc5788208),LL(0x17020946,0x8942a103),LL(0x7086a405,0x279752bc),LL(0xbd8d65b0,0x96d15474),L_(0x00000127), + LL(0x9abc3d40,0xf756f14e),LL(0x748874bf,0xf9192ae1),LL(0x50f7dc14,0xfb847314),LL(0x424a6e96,0xd7141cc9),LL(0xe0539e22,0xefedb9cd),LL(0x7f5ec1a8,0x7abbcc13),LL(0xe6446e18,0x0050521f),LL(0x3706445a,0xedca13d0),L_(0x000001b1), LL(0x2f62e709,0xa5e744f0),LL(0x8279d454,0x8aad355f),LL(0x03801f2d,0x88a334e7),LL(0x30342602,0x34cb8228),LL(0xed180e75,0x6d4243df),LL(0x5bbbe349,0xd0752a72),LL(0x0977e643,0xd5658e43),LL(0xf968b621,0xa8dfe2a7),L_(0x0000009d), + LL(0x3757bccc,0xce9d3ef4),LL(0xb10a83cd,0x021aa7d7),LL(0x804bf03e,0x79a14071),LL(0x09822fa4,0x1adecf50),LL(0xec4d2fe9,0x8fc3b061),LL(0x479fbad1,0xffe82ea4),LL(0xb70c5762,0x25b0bed7),LL(0x8a667da4,0x6f5ffd5c),L_(0x00000042), LL(0xd836c22b,0x9beeade4),LL(0xd28e01a7,0xd7c41634),LL(0x124715f6,0x83d30d7e),LL(0x8e33c4f9,0x2ee2bdb2),LL(0x5442a068,0xa18cfc1f),LL(0x68390a48,0xa6cb1637),LL(0x44abd789,0xa8ecc588),LL(0xbd6682cb,0x8ea17383),L_(0x000000ae), + LL(0xd8199c9b,0x86b3c132),LL(0x77f229f5,0x1a49a2e0),LL(0x6f74d75e,0x15ed7662),LL(0x8dd2368b,0x7d799783),LL(0x313152ab,0xa636aa73),LL(0x925319e7,0x2947bd12),LL(0xacf4c559,0xb2b023d8),LL(0x0322c16a,0xc8a967d9),L_(0x000001c4), LL(0x8a09b0a3,0xb1025eae),LL(0x8ae5f654,0xf817133f),LL(0x081d6d59,0xea1aa5d9),LL(0xe9090ae2,0xe61c2d54),LL(0x0784905d,0xf542221b),LL(0x5789e25c,0xa9b09c19),LL(0x1b8dadc2,0x7d4f5221),LL(0xabe01efb,0x446d7ebe),L_(0x000000da), + LL(0x8fc36944,0x1a86a356),LL(0x88a55222,0xa9332303),LL(0xfc1f186c,0xf8c2ca0c),LL(0x1f24d4d5,0xa82a6905),LL(0x753ac024,0xb6761f2a),LL(0x8a0fe4e0,0xb4a03fa9),LL(0xd1d20586,0xcb862d5f),LL(0x2bcb9949,0x48673692),L_(0x00000144), LL(0xa285574f,0xb1192295),LL(0x23eb5f8c,0x2436f1d4),LL(0x3f4febd2,0x842f6ae2),LL(0x0f1f266f,0x8091b264),LL(0xee94d349,0xf4561f25),LL(0x6f4a16f1,0x6e303b52),LL(0x80ed7ffc,0x08bbc14e),LL(0x6f957c19,0xb48f99ac),L_(0x000000a1), + LL(0x73d10fa8,0x1b164c81),LL(0xc855b452,0xdd4617a8),LL(0x9be0c270,0x94a57ba1),LL(0xb28b6ed5,0xc1383246),LL(0xc74bc4a3,0x17910967),LL(0x2a2a0e34,0x8aab9202),LL(0x93b8d150,0x122babf8),LL(0x1dffa251,0x32612c73),L_(0x00000069), LL(0x5fd7acd3,0x906979fc),LL(0xf242bd9e,0xc7fe62d6),LL(0x59507727,0xa94a1beb),LL(0x966af710,0xe7344f5a),LL(0xd397803f,0x5b835cef),LL(0xcd196fb1,0x1ca9e8ac),LL(0xe701eb7e,0x09bdf0a9),LL(0x521354ea,0x16f0f7c2),L_(0x0000018d), + LL(0xc389a398,0x92326c61),LL(0xc80b1e6a,0x0b658149),LL(0x23067f4a,0xd5cf4f64),LL(0xc96735ae,0x1cf4dd22),LL(0x43cb53c3,0x4b478ba1),LL(0xb353c721,0x3b1bbb1e),LL(0x46f2e84d,0x7b5aa79b),LL(0x4a4fa3d6,0x0db507d4),L_(0x000001a4), LL(0x5ad31f07,0x5402e45d),LL(0x19f0b31e,0x55650578),LL(0x214cdf81,0x3fd50ebe),LL(0x3efd8e06,0xd808dee6),LL(0x0c82d63a,0x39ccec30),LL(0x39dfd0ee,0x5249be7d),LL(0xb6c788e8,0xebe9271a),LL(0x7ffa3cad,0xe23c5a72),L_(0x0000019e), +}, +/* digit=44 base_pwr=2^220 */ +{ + LL(0xfd61361b,0xf3125658),LL(0xd69b66e1,0x96b636a1),LL(0x0c7ac9e9,0xe69b9e47),LL(0xf9bb3617,0x1b1e895b),LL(0x12050a8c,0xfa5a11a5),LL(0xa2492213,0xc2919aff),LL(0x08d55c3b,0xc4be1b10),LL(0x6dcf2c08,0xdd2f7392),L_(0x000001c7), LL(0xb4fb57fd,0x6ce4aac2),LL(0x6292f827,0x9277cab1),LL(0xc90518a9,0x144e677d),LL(0x0432d015,0xea4408ab),LL(0x35d9214e,0x49b20eb2),LL(0x2560b8a6,0x48a45d8a),LL(0x37dd269b,0xcecf7d1d),LL(0x71a47616,0x7df8d49d),L_(0x00000152), + LL(0xa734d86d,0x475ac257),LL(0x324330b9,0x3a9d12f1),LL(0xcecaa5dc,0x048adf08),LL(0x33641cc3,0xbfcc4fdc),LL(0xe40352a6,0x76f01bad),LL(0x6e93dac8,0x5bd7dfb0),LL(0xc0e1ca53,0xb21d4494),LL(0xb51965b8,0x20e57219),L_(0x00000031), LL(0x46f90e9b,0x76cb857a),LL(0x1b517407,0x31907caf),LL(0x38843e17,0x37770400),LL(0xb3c14ab5,0xb47cfe14),LL(0x58c99d12,0xd18daa18),LL(0xd4551590,0x84db2817),LL(0xc4d8f7ef,0x5a8544bb),LL(0x752b595c,0xed331ee1),L_(0x000001cf), + LL(0xa8718c9c,0xd016412e),LL(0x3d459798,0xc7059eeb),LL(0x07afd251,0x7f6e9107),LL(0x6ae603f5,0x7c29b336),LL(0x1f1d424b,0x1f08b6d1),LL(0x06f8f459,0xfa0b1884),LL(0x6dfa46f4,0x22a09ce4),LL(0x1ee6193a,0x050edf3e),L_(0x00000067), LL(0x59ef37aa,0xbc282a7b),LL(0x0490844a,0x16eca5fb),LL(0xfa414af6,0xdd42a4a0),LL(0x748c915e,0x6f1ab810),LL(0xa3d4af5a,0x31ef86bb),LL(0xe768aff3,0xd8ffc35c),LL(0xb6c4e536,0x6e278d36),LL(0x8f61ddd5,0xb2c50623),L_(0x0000019f), + LL(0x108204ec,0x1febacf8),LL(0x0a0c3a40,0xa1fbe66e),LL(0x2570b727,0x343654b7),LL(0x5299d8ae,0x83e0647b),LL(0x158b323a,0x3d86ee0d),LL(0x758534d1,0xe946224b),LL(0xcb77d0eb,0xe9a38321),LL(0xb845ec39,0xd329eea9),L_(0x0000003f), LL(0x4421327c,0x13edfc50),LL(0x0c4b9b9c,0xefee69b8),LL(0xce07a452,0x110b9736),LL(0x2779de28,0x810433de),LL(0x19cb506b,0x1468d237),LL(0xd2930983,0xb54615ee),LL(0x895d360f,0xa6a72f30),LL(0x2a939f9f,0x0f67c082),L_(0x0000019a), + LL(0x613613a0,0x41479bab),LL(0x64b3ba28,0xae853dfe),LL(0xd7d5f8f3,0xeddc5d69),LL(0x3c023c98,0xc2af1c91),LL(0x5e51c064,0x3e811beb),LL(0x3e28caf2,0x297f73a1),LL(0xb2c63f7a,0xe92c2db1),LL(0x272783c6,0xa58f0869),L_(0x00000175), LL(0x4d9e33e7,0x2930859a),LL(0xf96d2a6e,0x21c82319),LL(0x234b3a37,0x99962855),LL(0xe1e952c7,0x834c3fcf),LL(0xa9fff526,0x2d66290a),LL(0xc1aa8293,0xd0618b6f),LL(0x65d795be,0xd8f51b17),LL(0x7ad3a784,0x61d170fa),L_(0x00000185), + LL(0x6fb99ec5,0x5b03ab3b),LL(0xdf673d70,0xd514df02),LL(0x97926d51,0x68bd9794),LL(0x7f3cad99,0xa7bbd732),LL(0x807b8edf,0x1dee6527),LL(0x9072fc5c,0x6db8f170),LL(0x8a088d03,0xfad430f3),LL(0xf3373c9b,0xac0bdf9d),L_(0x00000068), LL(0x562932b2,0x98ce826d),LL(0x15d43a46,0xd64992b9),LL(0x0e1471fe,0x12cf137e),LL(0x11a1c256,0x19907c68),LL(0x97e5e746,0x5dcff6a5),LL(0xb4d10f45,0xfe503afc),LL(0x2daf8e96,0xbfaf4738),LL(0x51a1e9e2,0x47ef585e),L_(0x000000ca), + LL(0x57c899ed,0x309ddc9f),LL(0x000b8805,0xf9ec0561),LL(0x61be65ad,0xdb755990),LL(0xc6ac2e8b,0xf8f392c7),LL(0xc546a9f7,0x709f90fb),LL(0xaa4eb38f,0xb81ee256),LL(0xe3bb73d5,0x920cd9ff),LL(0xe54f7913,0x8fd7ead1),L_(0x000000a5), LL(0x6fe432ea,0x7d99d437),LL(0x42314efd,0xecbf2570),LL(0x0d11bf19,0x1a26524d),LL(0xc070e881,0x80db7170),LL(0x69bb46ac,0xed697625),LL(0x6e7f5dec,0xf5d4f199),LL(0x35c855b1,0x63c6d1bc),LL(0xcfaf131b,0xfd69fb7f),L_(0x000001d9), + LL(0x4c7faf89,0xe289504c),LL(0x7c67c701,0xc21c143d),LL(0x51104808,0x429b8b10),LL(0x8547ea3f,0x643f8b1a),LL(0x442d1597,0x8e30463a),LL(0x1322c20d,0x9700b9ca),LL(0x12313e31,0x53c7c741),LL(0x429e582d,0xebcdb21d),L_(0x000001bf), LL(0xa6df174d,0xf30a9c65),LL(0x734a8421,0xcca7bd70),LL(0x12f441c1,0x42e970e9),LL(0xda35c856,0x990f29b0),LL(0x7fbc6108,0x201a5ca8),LL(0x006704f9,0xb4ba5b8a),LL(0xd79c4200,0x5332f15d),LL(0xaa2c5720,0xbc6411dc),L_(0x00000184), + LL(0xa1d7fa9f,0x366d01e5),LL(0x0b24e344,0x05318d76),LL(0x9ed7c092,0xd4cb6907),LL(0xdf8af7fc,0xe97d11bc),LL(0xcad57852,0x4e593cff),LL(0x966648ef,0xeb5229ac),LL(0x0513e9bd,0xc0b6887d),LL(0xc4457c4d,0x8e5e6129),L_(0x0000001e), LL(0xe56e3c4a,0x33909c43),LL(0x6b6ecd98,0xab630f3e),LL(0x58c96e3b,0x604359ea),LL(0xa6fb1a48,0x4c23bc41),LL(0x01509a8e,0x735b6fd3),LL(0x55538a0d,0xc1e6f88e),LL(0xca10627f,0x43b7d098),LL(0x7a0bef75,0x237cd9ab),L_(0x00000034), + LL(0x382d4ce3,0xd57fa9f7),LL(0x39f2057e,0x5a8fe9d0),LL(0x819adb6c,0xf4dd28c4),LL(0x26c97625,0xa0db7a3e),LL(0x6c864ae6,0x8bee872f),LL(0xfd35c90d,0x42a5de0c),LL(0xf6b8c643,0xa0d68766),LL(0x613a35a1,0x32e15e02),L_(0x00000001), LL(0x7201d2d4,0xeb515a90),LL(0xb3006a97,0x293640a4),LL(0xdf1363d1,0x4e898435),LL(0xc4282ef1,0xf5eec35c),LL(0xf5395189,0xf9d8e87e),LL(0xecf465a2,0x621a8997),LL(0x2d4680db,0xfe197810),LL(0xf2c35d16,0xdc319b13),L_(0x0000019b), + LL(0x35c78619,0x976fd128),LL(0x4fea3432,0x9d455cba),LL(0x94c9bc3b,0xb7bb73c4),LL(0x0a3d4425,0x90c2ec3a),LL(0xc1f93e1c,0xa95d87c6),LL(0xe60757b3,0x60d5d399),LL(0xd3d27995,0xce2c84d1),LL(0x81c8808b,0x750e4526),L_(0x0000017f), LL(0x32b7091e,0x76361e05),LL(0xe202d497,0x074baca9),LL(0xd7df203d,0x18d9c96d),LL(0x60965442,0x6777a2e9),LL(0xcf542875,0xcea9162e),LL(0xd6cf9057,0x0e08540f),LL(0x118843d2,0x12ce0e32),LL(0x64680618,0x84e4eabb),L_(0x000001d9), + LL(0x3de4c30b,0x1640f2bb),LL(0xe1cd2dab,0x67a49e8e),LL(0x68415129,0xce1a4189),LL(0x5f6655b9,0xf8e55d14),LL(0x58251e9d,0x2a896a11),LL(0x2990bcd1,0x5ee2f029),LL(0xc1b51e11,0xe59128b6),LL(0x7f1b211c,0x753ab1e4),L_(0x0000009b), LL(0x0e4c3270,0x75ae7bca),LL(0x0ff0470f,0xe26fb687),LL(0xdde851ff,0x6353acb2),LL(0x661a72f5,0xa014b448),LL(0x6da88895,0x20ab0fca),LL(0x41dc7a9c,0x90420ccc),LL(0x97a7f272,0xf726e07e),LL(0x23c2dfa2,0xb43c28ae),L_(0x000001db), + LL(0x19987e83,0xc4bea825),LL(0xb4d6f37a,0x86bba8ac),LL(0x1e145dc1,0xa3d3860d),LL(0x9d377493,0x538d1baa),LL(0x9ce67c55,0x507bf776),LL(0x0148462a,0x563563c0),LL(0xc2891330,0xba0e7843),LL(0xc76b64b0,0x2ff4ccb3),L_(0x0000012d), LL(0xca889e53,0x632d2ce5),LL(0xe7e3d3fe,0xeabe8bf3),LL(0xb7126e82,0xcc6bda06),LL(0xf58c6361,0x69480574),LL(0x6a99c0d0,0x660e6906),LL(0xd1fdf14a,0x465778f0),LL(0xddbb43b6,0xb843d29c),LL(0x575fd92f,0xa63f0dcd),L_(0x00000158), + LL(0x2cd4fd82,0x0e9a73c7),LL(0x52c71a96,0x4d3a4557),LL(0x067ccd35,0x3e412b8b),LL(0x7bd77ec2,0x951e31d9),LL(0x4100bac7,0x2ac6482b),LL(0xccccb053,0x6361906b),LL(0x79655211,0x269a7fe0),LL(0x756f8ab0,0x3b6f68fb),L_(0x00000062), LL(0x8ce6630b,0xcbecac0c),LL(0x4a29a7b7,0xf7ba2d3b),LL(0x47e9ba07,0x2e6c073a),LL(0x5aa6a94b,0x73cf6f20),LL(0xa8a42977,0x50805433),LL(0xf9945386,0x74ac62ed),LL(0xc8f04c45,0x14e4baea),LL(0xe37de45f,0x3e21f3c5),L_(0x0000015b), + LL(0x73f77d7e,0x6ff96082),LL(0x58430006,0x328b95a9),LL(0x82931188,0x968102c5),LL(0xbb40cb55,0x6514614a),LL(0x370bf205,0xe5de48d5),LL(0xb3d94790,0x73c104b4),LL(0xa5683b4f,0xfb96fb1a),LL(0x36a9677e,0x17789e50),L_(0x0000010c), LL(0x32bfd837,0x4594f7a0),LL(0x3fb584bb,0x9be3e3c1),LL(0xc86bb1e7,0xef4aecee),LL(0xfa93fc70,0x9de5dfe2),LL(0xbfd3b8de,0xe7670296),LL(0xe1fa5638,0x228cc6d9),LL(0xd230d44e,0xf7797644),LL(0x82d4c20c,0xcfd9942c),L_(0x00000018), + LL(0xe19f88e8,0x828b99d9),LL(0xc2beefa3,0x51fa512e),LL(0xd33e3c3c,0xbe14d684),LL(0x34a6c37a,0x5b5936ae),LL(0x89d4bea5,0x2802583c),LL(0xd938e649,0x98da605b),LL(0x1f045420,0x55288cfc),LL(0x659c47e4,0x85b5fed0),L_(0x000001de), LL(0xb9ddaea5,0x22472a49),LL(0x0aefe3e4,0xc2da9569),LL(0x6e21cee3,0x0c7dcef3),LL(0xb14f0abf,0x98c3c9ea),LL(0xb64941e1,0x4819eee0),LL(0x433cfcf6,0xbfe77fa8),LL(0x2f7686dd,0x03c3b28a),LL(0xdbfd2334,0xd4d1d9c3),L_(0x00000008), +}, +/* digit=45 base_pwr=2^225 */ +{ + LL(0xc3b7107c,0xe8887082),LL(0xd218cc42,0xcd304c29),LL(0x7a96d44b,0xf1c4d847),LL(0xee7f483f,0x530d4bec),LL(0xc951d19c,0x4d6bf1fd),LL(0x71d2d68d,0xe03d009b),LL(0x4d3bd1df,0xc4553769),LL(0xdb4cb1a2,0x5f77a3c3),L_(0x000000a4), LL(0x5e86f0e3,0xcaf5fb4c),LL(0x715c3388,0xb2f14ba7),LL(0x81191db4,0x38426103),LL(0xf68a08e3,0xb75d25e0),LL(0xd342059c,0x92f767fc),LL(0x4dec2bd2,0x7a696b41),LL(0x16057d6a,0x8adfb670),LL(0x99c277b1,0x2be66359),L_(0x000001f4), + LL(0xd6f16b10,0x088e20bf),LL(0xb30d007e,0x859fdd39),LL(0xd4c40b6e,0xc9196072),LL(0x0a59d2a4,0x3c4f607d),LL(0xaf5b531a,0x5c546c30),LL(0xfdc40588,0xdc1d5df2),LL(0x2971b1ad,0xfb26f4df),LL(0x7cb15104,0x70c15bb6),L_(0x000000e6), LL(0x9ff74646,0xe3bee8f3),LL(0x96143e3d,0x560fc63e),LL(0x2e0395d9,0xfd9d7aab),LL(0x099cc808,0x422f153f),LL(0x4e3c3dca,0xefabb0d7),LL(0xed2c2c61,0xd736943a),LL(0x78f87c18,0x96d74e41),LL(0xb76afadf,0xfdd923d1),L_(0x000001a2), + LL(0x204ae17c,0xab5b4b2b),LL(0x780e0409,0xc4c863d0),LL(0xf73d00d9,0xd243a003),LL(0xd17b97ed,0xca6e6ef7),LL(0xd335ec2e,0x3f246d97),LL(0xd6c07def,0x0e2518ce),LL(0xb8b0595f,0xfdf728fd),LL(0xc1ccb10b,0x9df076dc),L_(0x000000d8), LL(0x869f012d,0x0a767d8e),LL(0xbe6fa9d5,0x1bbb0510),LL(0xdeeebbfe,0x8f4cdab7),LL(0x8332cdf9,0x75d651f0),LL(0x54687821,0xdd0fc83f),LL(0xa428610a,0x965277af),LL(0x38635dc4,0x9dff5c34),LL(0x0961df5b,0x5ea091fc),L_(0x000001a0), + LL(0xe4290556,0xea12a072),LL(0x762385fe,0xd082bac9),LL(0x1be16424,0x8697c433),LL(0xf06c7a59,0xa812dd21),LL(0x7de72b68,0x02f90069),LL(0xa2e56525,0x9acaec02),LL(0xa89c7efd,0x4f9120c4),LL(0xdf713a32,0xd965ba1b),L_(0x000001d6), LL(0x3367220e,0xc9641453),LL(0x9b048cab,0x29a9fac9),LL(0x0e9e757a,0xcb21c285),LL(0xde9cc170,0xbef96957),LL(0x7d017c03,0x0f3534a3),LL(0xa9c18cbf,0x5a627fd6),LL(0xed78ac58,0xb9c29da8),LL(0xef092aca,0x4f469ae4),L_(0x00000020), + LL(0x1cb1ec3d,0x669f05f8),LL(0x03d201d9,0x6bb4d70b),LL(0x898f998e,0x96c9a0f0),LL(0xe22c0440,0xfa56577c),LL(0x7b9dee1b,0x00502b66),LL(0x47777bc8,0x483cf935),LL(0xffb71b74,0x0b52d0b2),LL(0x39112d39,0x752546a7),L_(0x0000004f), LL(0x75c45aee,0x6b3c757b),LL(0xf1bef81e,0x7e3d1f7a),LL(0x21a74b7e,0x2bfe9dfd),LL(0xb0da2bc4,0x90c8361c),LL(0x0c5783ca,0xf50913fe),LL(0x5dd47036,0x34045f12),LL(0xd0f87837,0x89dc259f),LL(0x560578ab,0x22e987bd),L_(0x000000dd), + LL(0x1a521d30,0x8270aad1),LL(0xd7dd0f9e,0x5bd17ae9),LL(0x2341942e,0xc840cb6d),LL(0xdc090118,0x1c49ccd4),LL(0x60e02fa4,0x28d04bf0),LL(0x3570b020,0x1dc79e5a),LL(0xbd1e244b,0x5f5e1042),LL(0xeebf73ef,0xf6c77a24),L_(0x000001ba), LL(0x9d82fe22,0xf2a4d116),LL(0xfbb0437b,0x538ffa89),LL(0xac67b2fd,0x70b0e36d),LL(0xcd72f925,0x3b843326),LL(0x26042e6e,0xd58ef907),LL(0xa54711c2,0x40c00366),LL(0xa62c4885,0x33e0a1f1),LL(0x758c2c5e,0x508c7bec),L_(0x0000014e), + LL(0xf11f835f,0xd4f6e5fa),LL(0x4a99daab,0xbfa7d98f),LL(0x3f46a163,0xe712c72d),LL(0x869f8036,0x194ee078),LL(0x1283d5ab,0xe9c40094),LL(0xf4b53cf8,0x8eccbfb3),LL(0x865de4fb,0x27d82426),LL(0xc4399d77,0x5783591a),L_(0x00000093), LL(0xa59eaa03,0xb1a23e95),LL(0x99d72c23,0x48055f02),LL(0xf5f1e1c0,0x04a35336),LL(0x448cee4d,0xcb7b9a8c),LL(0x5862f10a,0xb9974831),LL(0x93b3f7d9,0x93c6f79e),LL(0xb09c629c,0x2a3760fa),LL(0x5d47957f,0x310ac801),L_(0x00000186), + LL(0xf060edf1,0x83a0baf3),LL(0x26de7078,0xeb8cb2a3),LL(0xf5a8d631,0xcfa95554),LL(0x6ba14fb5,0x9d950c23),LL(0xc53769e2,0xc3b6e6d4),LL(0x857d43ea,0x00e396b6),LL(0x28cc2c64,0x79b3b40a),LL(0x42ca52de,0x66e9ef01),L_(0x00000037), LL(0x4e536d43,0xbb696fec),LL(0x60fe980d,0x86879c73),LL(0x6a564e15,0x6796d473),LL(0x62e7ce9d,0xee75c812),LL(0xd4cced89,0xdd4f732c),LL(0xa3a75fe2,0x4a4d97d2),LL(0x62def6c0,0xfce046cc),LL(0x0bfe781a,0x9b2b5c59),L_(0x000000e8), + LL(0xecebff30,0x5ddecacd),LL(0x66805c77,0xc732fa10),LL(0x62e2a037,0x9f8318aa),LL(0xf535306d,0xcb188ede),LL(0xf3ae9b72,0xd4215242),LL(0x76515ea4,0x19ee9251),LL(0x04b30ff0,0xfdb4add0),LL(0xc2006bc5,0xc094d7f3),L_(0x0000008c), LL(0x08f431a5,0x9a41c273),LL(0x4ef9856a,0x29336f92),LL(0x89a37aaf,0xb4f719c9),LL(0xb6ae5b4c,0xcb8b83d7),LL(0x0b93351c,0x579d32e9),LL(0x95ac6c1d,0xed14de1a),LL(0xc9a3144d,0x59d39bac),LL(0x4809d3c0,0x021a5392),L_(0x00000076), + LL(0x46b4f926,0x31967f76),LL(0xedbec7a4,0x9540a500),LL(0x7d4cba0a,0x3664934a),LL(0x44eee05e,0xacaf15ab),LL(0x7e273dff,0x0d40978b),LL(0xb55d54b7,0x7a7b2c2d),LL(0xb2400231,0xcc267a21),LL(0x31dec63e,0x45427d34),L_(0x00000169), LL(0x9ea998cb,0x5e543e59),LL(0x22a0befc,0x0dee7b14),LL(0x1aa7e66e,0x052bb589),LL(0x51c3c220,0xe7133b54),LL(0x64b84789,0x86fee1bb),LL(0xacd3a9a6,0x6d321f88),LL(0xf3dee610,0x17435c7d),LL(0x64e0790f,0xea978193),L_(0x0000000a), + LL(0x824c77d2,0x1d5087de),LL(0x3c424cb9,0xce8e9c97),LL(0xb3b1c7ef,0x65ef8961),LL(0x36bdf7df,0x936db078),LL(0xe1a9152e,0x9ff36717),LL(0xbde711fb,0x1b59074d),LL(0xc2a17a75,0x9070200e),LL(0xa0657ad1,0xd3cc9c6b),L_(0x000001fb), LL(0xf471b9b4,0x63dca49d),LL(0x23fe450a,0x7aa88a47),LL(0x569744e7,0xbac5c025),LL(0x557519ba,0xc31b16cd),LL(0x90672c5b,0x7609de28),LL(0xeb879e6d,0x06a4f8d7),LL(0xa50f3b9e,0x45a7792d),LL(0x5ef4893d,0x5794fb38),L_(0x00000186), + LL(0xa8c609cd,0x3fc0a251),LL(0xe916d838,0x09bae516),LL(0xdc8442b3,0x70eda9b4),LL(0xdbbd2829,0xe66c09a8),LL(0x44077102,0x46f0d061),LL(0x0c8b9a97,0xe7c4e4e6),LL(0x96dd9b50,0xd93b4696),LL(0xf2abcbd4,0x2e694650),L_(0x00000152), LL(0xdcc67ed7,0x34c98a81),LL(0x1a864f2a,0xd79eca11),LL(0x46960243,0xaf4ad720),LL(0x02db8ea4,0xe8d429d1),LL(0xd9dae172,0x9cac2c01),LL(0xf704ba3a,0x052267c9),LL(0x0ee381b0,0x768c8223),LL(0xf95050b5,0x3558199f),L_(0x00000037), + LL(0xdbee340c,0x7596d517),LL(0x7a4d90d8,0xe88332d5),LL(0x27312835,0xadc174b8),LL(0xbf7deda3,0x9fa8589b),LL(0x30a04404,0x50ccb83e),LL(0x9ea9cbf7,0xb73afec5),LL(0x8a699ab5,0x0382ff44),LL(0x682b0e1c,0x12fbb9a1),L_(0x00000024), LL(0xa48bc771,0x219fed54),LL(0x20bed549,0xd7a8f53a),LL(0x9f897a30,0xccad31ab),LL(0xf4ab61be,0xe4253812),LL(0xd02eb63b,0x02c0bd98),LL(0xf369795f,0x940fa395),LL(0x6661d80d,0x4fc30a92),LL(0xdb54dfb5,0xf14f8652),L_(0x000001a5), + LL(0x7f4fad25,0x917eadce),LL(0x33c5c41f,0xfac932b3),LL(0x8175e0ba,0x0c6ce437),LL(0xd6df4caa,0x628f6bd2),LL(0xd8cef71f,0xbbd0808b),LL(0x1bf4e3d8,0x82a3b927),LL(0xf2573f56,0x18b7f7d3),LL(0x20a5d5d4,0x68ebb93b),L_(0x00000151), LL(0x6296df1a,0x511300a6),LL(0x48f698fe,0x0a451118),LL(0xe69d9b6b,0xbda90f27),LL(0x6b99560f,0x00ad6b22),LL(0x576639a4,0x70498a28),LL(0xe3fb0685,0x766cc9eb),LL(0x910ed9d6,0xa13d4e5f),LL(0x45079f4a,0xdd2c7f6f),L_(0x00000047), + LL(0xb3a0df18,0xcdee46b0),LL(0x0f7b0b8f,0x0dee6d65),LL(0xdc8df7a6,0xca19127a),LL(0x6d034f50,0xd6d74c77),LL(0xcd8b7301,0xd01a93fc),LL(0x7b8e12a8,0x77799926),LL(0xc0b3bdfe,0x157d532e),LL(0x5444b9cf,0x90f700d1),L_(0x000001f9), LL(0x2776ac60,0xbab425f8),LL(0x947e525b,0x66085567),LL(0x6d095956,0xbcb7adb8),LL(0x4d3075ac,0x99a0d6ce),LL(0xc684b9ba,0x0e134c5c),LL(0x4c65fec0,0x30477674),LL(0x5db48af9,0xf3744581),LL(0xfcc9963e,0xc6d87a4c),L_(0x000001c2), + LL(0xb51e39da,0x258dcf68),LL(0x1c50cc68,0xb1289a02),LL(0x54112229,0x48928ef6),LL(0xc73b83c7,0xf0df33f4),LL(0x6a0ebdbd,0x5f166393),LL(0x09883324,0xbdfac3bf),LL(0x21bceec6,0x871bcc9c),LL(0x64a15de9,0xa6e53bcb),L_(0x0000007a), LL(0x7efb2f27,0xce8d66f9),LL(0x6a48e2f0,0xc4f49e10),LL(0x0d05177f,0x04e720d6),LL(0x9e354273,0x746f841b),LL(0xe08c355b,0x7b7b7cd5),LL(0x81226157,0x586eb9a8),LL(0x38ce3838,0x8c03b21c),LL(0x02872c5a,0x40058aec),L_(0x00000197), +}, +/* digit=46 base_pwr=2^230 */ +{ + LL(0x8a4b6723,0xa08c6852),LL(0x79a5b3fd,0xc7195714),LL(0xd8054fed,0x7c611c75),LL(0x503c3580,0xe88e5dbf),LL(0xb37b9ea9,0x2b4c4521),LL(0x75f1c942,0x950eb17e),LL(0x79508472,0x238eca42),LL(0x845c91f9,0x0657bc0f),L_(0x000000fe), LL(0xa0c1e80e,0x978ae396),LL(0x14b242e1,0x2c0d00f9),LL(0xb47bf7bf,0xe944e43f),LL(0xb416e50a,0x906c3634),LL(0xe7c8d114,0x347f03a3),LL(0x65b00ad0,0xa6eba251),LL(0x53a14e26,0xf521e9dc),LL(0x11eb83f4,0x82020769),L_(0x00000151), + LL(0xcf0b0ab2,0x1ea0d8e5),LL(0x30d499c7,0x4b6204df),LL(0x8f748b9e,0xc4dd3f54),LL(0xba95c754,0xc443876e),LL(0xd7ad6cc9,0x08e10896),LL(0x544e9e2d,0xa9428b4a),LL(0x1a2d3e1e,0xb6fe7189),LL(0x05c7660e,0x77bc86b9),L_(0x0000013a), LL(0xb366e641,0x77106f8f),LL(0x42b36e28,0x2d9d82f5),LL(0x63743c2e,0xaf2b4eca),LL(0xc887146a,0xb28d08cf),LL(0x4ed669e0,0xc7391371),LL(0xda28c885,0x14ee1f56),LL(0x84424da9,0x42d4479d),LL(0x33646227,0x4a2f215e),L_(0x00000082), + LL(0x12e89265,0x1eeb47d8),LL(0xcbb7e582,0x5b702942),LL(0x0f041cf4,0x64d44f59),LL(0x50d39295,0x5d20f47c),LL(0x0a8b51ba,0x15a076aa),LL(0x79ae768a,0xa2141ba3),LL(0xcf638bb5,0xe3c47d36),LL(0x582394d5,0x3311139a),L_(0x00000047), LL(0xde6f722f,0x7bcb9faa),LL(0xc544456b,0x7edbbe33),LL(0xc58f127c,0x178e1289),LL(0xcd6856a6,0x29c72942),LL(0x7d0ce889,0xdca59772),LL(0x951589f5,0x6908ef3f),LL(0x4f00ce63,0x110a84b5),LL(0xc1a89443,0x72833218),L_(0x0000003c), + LL(0x1fbd25b5,0xc3abc5bd),LL(0xa3138347,0x78a11d29),LL(0xf2283223,0xadac6d62),LL(0x4af4ece3,0x72b0dc7b),LL(0xf1c75e43,0xa7308e28),LL(0x99139560,0x0ea7127d),LL(0x9cb3c31d,0xee0172da),LL(0xc69386a7,0xd4d20c36),L_(0x000001db), LL(0x293be2a2,0x82933139),LL(0xaf8d3077,0x41cdee07),LL(0x4118b415,0xd6d0895f),LL(0xb3a9502a,0x242767b9),LL(0x404e1d44,0x3924f383),LL(0xe7a91a84,0x3c5c40dc),LL(0x0f30db5a,0x2d443e9e),LL(0x38df60b6,0xc16acc53),L_(0x00000195), + LL(0x57eacd01,0x8b237781),LL(0x47bc0a58,0x21bf6b08),LL(0x72f947bb,0x5c6b0c6d),LL(0x0c58bea7,0xc78326d2),LL(0x8a6feb8c,0xf3157ca1),LL(0xe147ad97,0x4be255e4),LL(0xa6917b35,0x7006cd50),LL(0x1ceacc56,0x7d62c8eb),L_(0x0000000d), LL(0xc4957a8d,0x5e969282),LL(0x3e3eb59d,0x1216fdc0),LL(0x2f2b0b06,0x51a13162),LL(0x5b88e211,0xff4a6d02),LL(0x6b68e6ae,0xc7c80a3f),LL(0xa7fca940,0x2128145a),LL(0x3a205f85,0x459b75e6),LL(0x48874b7e,0xef227f89),L_(0x0000019c), + LL(0xf1c2d135,0x363e7de4),LL(0xede249f0,0x2374169d),LL(0x92b91c52,0x34ca05e7),LL(0x42f9c460,0xe96d13d2),LL(0xb8dc141b,0x9c04a0eb),LL(0x11349888,0x86f45f6f),LL(0xa3c9d21f,0x34d9dd7d),LL(0x6359abc3,0xa35e3eae),L_(0x00000172), LL(0x906d8bdb,0x82617ad1),LL(0x5f4fb81e,0xd70d26c6),LL(0x68367c91,0xe835f648),LL(0x4d712331,0x5dda13b7),LL(0x06ca4385,0x97f662ae),LL(0xcbeb485a,0x211b18b3),LL(0xfe5f6ad4,0x178f31f1),LL(0xbfc76ef2,0x88d953e4),L_(0x000001a9), + LL(0xab40e045,0xcdbdf2d4),LL(0xbc7f59a3,0x25655817),LL(0x7d6adfae,0x5b05af23),LL(0x3b9e8819,0x1f7f265d),LL(0x4d41011d,0xa02a10b1),LL(0xc4403b75,0x4598d47a),LL(0x21678b80,0x72bcfd2d),LL(0x0a91ddc2,0x53e0dc1a),L_(0x0000003b), LL(0x5f9a8c36,0x38d6c310),LL(0x22226823,0x4b065228),LL(0xdf4b4ac7,0x99e6867b),LL(0x1562f4fb,0xc9c2e12f),LL(0xe5bf9e6b,0xef6dd2fe),LL(0xa02f573e,0x99a366b2),LL(0xf15b202c,0x46de40b9),LL(0x8fa6fe0d,0x0fbe1e76),L_(0x0000011f), + LL(0x95d88264,0x5a265bdb),LL(0x771ed60f,0x717063ef),LL(0x0dd813de,0xd974ca00),LL(0x4d348196,0x9d26915a),LL(0x3def1612,0xfcdfb352),LL(0x1ecabcbb,0x7290d698),LL(0x44e08c75,0x5c0c5d24),LL(0x65a063c6,0x1673491c),L_(0x0000000e), LL(0x751941d0,0xa5845e0e),LL(0x90c04cc0,0xc51c09cc),LL(0xf11f3a2b,0x536ce8af),LL(0x3944ca09,0xd614a230),LL(0xe5cb9d10,0x4cf73a00),LL(0x11f36267,0x39b52629),LL(0xe681d436,0x27379f49),LL(0x7634bb09,0x6f9a6ea0),L_(0x00000193), + LL(0x3b3162c4,0xf5ba50b2),LL(0x27a53ca3,0x5b2f88a0),LL(0x4d9f7313,0xff015375),LL(0x4100d075,0xefc66c49),LL(0xaa939a6b,0x25334ce7),LL(0x4d836d2e,0x0ff09c49),LL(0x9aa3f59b,0xce13f150),LL(0x6bd297a9,0x80466de2),L_(0x00000106), LL(0x3c8984bd,0x8be1ce28),LL(0x7a30734a,0x83fbedb8),LL(0x56e66999,0xc37e9e22),LL(0xeb69a4db,0x8b3de542),LL(0x15192947,0x4a7280d3),LL(0x67515315,0x5c05b359),LL(0x0b9a8604,0x5ec92a80),LL(0x973deb80,0x04619c68),L_(0x00000027), + LL(0x1256d99a,0xa13ac401),LL(0x9e017800,0xed3810cb),LL(0x84b7702c,0xb6d9eff1),LL(0xcdc98f94,0xf4a42e06),LL(0xa3cf6c58,0x658f00c3),LL(0x17b79fe0,0x4db4bd0a),LL(0xc0cd6ebd,0x79f4a662),LL(0xb6716eec,0x94db6c69),L_(0x0000014d), LL(0x6f9c5845,0x5d9256ec),LL(0x540f768a,0xe910b5c3),LL(0x4e7e7b8d,0x3c907d51),LL(0xf387c3d5,0xeecfe723),LL(0x213d5d27,0xd78500a0),LL(0xaa244815,0xb117a5b8),LL(0x7049f488,0xfb72f9ed),LL(0x3651c83c,0x24f438bb),L_(0x00000079), + LL(0xed918816,0x14555dbb),LL(0x178d8d22,0x4a72d14b),LL(0x1ebffe3d,0xa3a172eb),LL(0x476c82fd,0x4c45f724),LL(0x700c837a,0xd80825d0),LL(0x16888e37,0x104ac32f),LL(0xfaf93105,0xed3ecf8b),LL(0x503fb78e,0xcfbd4bb3),L_(0x00000067), LL(0x3c014136,0x4a1d6c14),LL(0x3ae0a56f,0xa38d42d7),LL(0x765e846a,0xdc241d4a),LL(0x087fcd52,0x0a7a4e2e),LL(0xf088c4c3,0x81043b53),LL(0x0b74dc81,0x030c4d6d),LL(0xf465c63a,0xb63f1e30),LL(0xa7aa0a71,0x1a64238f),L_(0x00000006), + LL(0xe2aea3b4,0x22e76e20),LL(0x6eca1ede,0x7e03afde),LL(0x08d1c44e,0x4edf70d6),LL(0x88d58544,0xd8ec390b),LL(0x474d298c,0xc4c3f675),LL(0x9ce21146,0x3274110e),LL(0xb12ae7e7,0xce9cf1f4),LL(0x67e9f4b4,0x8102a4fa),L_(0x000000ee), LL(0x102ef931,0x3efdaff6),LL(0x7a8b94cb,0x59bd3104),LL(0x4b8b1235,0x25afad7c),LL(0x24884827,0xdd939da0),LL(0x43b462ba,0x45cb99ab),LL(0x6a4b9f89,0x0f6b65c6),LL(0xbddb4b1c,0x39e97dd0),LL(0x5a1f7976,0xef2919d7),L_(0x00000117), + LL(0xcf01fbe1,0xc5bd929e),LL(0x47c26018,0x2bbeb492),LL(0x050e6a5c,0x04741b6f),LL(0x0f665d42,0x4c0e1ab0),LL(0x15137e0c,0x3ee524ae),LL(0x88980ffb,0x86e225d0),LL(0xa5de3190,0xde9d18c0),LL(0xe6bcf986,0xc6d1d2db),L_(0x0000009d), LL(0xc1e09545,0xa8ab4958),LL(0x7b416dfc,0x05e9411d),LL(0xb5a5de50,0x916238cc),LL(0x7da6c853,0x0e933ce2),LL(0xcff26d33,0x7fab03f6),LL(0xc2410d1b,0x70a12092),LL(0x130ded07,0xa7ff89e1),LL(0xf34872a0,0xde280eea),L_(0x000001cb), + LL(0x6107960e,0x08dca3fc),LL(0x9f978b8d,0x2367f8bf),LL(0x41ab4ac8,0xbfb304bc),LL(0xc14127da,0xb2161643),LL(0x89ee83de,0x91433f74),LL(0x76ad8bee,0x3abcb595),LL(0xa74d6d8b,0xa8b1935f),LL(0x314e698a,0x23ecc61e),L_(0x000000e7), LL(0xbd5f1508,0x1fda31cb),LL(0x4401991d,0x67b33d1f),LL(0x5dcaee66,0x80ef50d3),LL(0x58f1d026,0xc6160acf),LL(0x00a13e57,0x3be539f3),LL(0x88dd96e9,0xa5a0a5ae),LL(0x97419f0c,0xcf6a8f10),LL(0x44b2ca4c,0x1b9f2c18),L_(0x000001dc), + LL(0x5c77a891,0x745da1cc),LL(0xa4b913df,0xa1006271),LL(0xec1779e4,0xb3fe3fca),LL(0xcceebf8a,0x7b0d3f86),LL(0x82fd16d4,0xeb20fdbf),LL(0x4e29270b,0x450edccc),LL(0xa783c064,0x2c637dd3),LL(0x7337d5ce,0x9b0b50ee),L_(0x00000005), LL(0x819b276f,0x71e05cf6),LL(0x45bd1439,0x748c488f),LL(0x280a8add,0xbb099ca8),LL(0xe8e6e69d,0x19429d88),LL(0x4f4c80b6,0x2d2698e8),LL(0x0e4ab44b,0x1eb3fc49),LL(0xcd46fe76,0x02d1a2ca),LL(0x15543eb8,0xacd0b316),L_(0x00000129), + LL(0x700ec0ac,0x13ee9845),LL(0xe55b42fb,0xe5ad047b),LL(0x45bc6993,0xe8f73a08),LL(0xee41f2ae,0x1ac680ff),LL(0xd3c83204,0x740b12fc),LL(0x5e36bb4a,0x21ebc164),LL(0x35a45c95,0xb8dfcc77),LL(0x92b0fbda,0xa1f288ef),L_(0x00000153), LL(0xb5805ed4,0x829d754d),LL(0x6c810584,0x36cc488a),LL(0xc9632468,0x39f60f1e),LL(0xf2ebc30d,0x390502c0),LL(0xde960758,0x6d1feec9),LL(0x63adf462,0xf944bca3),LL(0xdeea2824,0x9c375dbf),LL(0xa887d095,0xbc1d650b),L_(0x000001c8), +}, +/* digit=47 base_pwr=2^235 */ +{ + LL(0x2fcf8b0a,0x07415442),LL(0xe5dadc06,0x07a17d21),LL(0xc237ee85,0x83c01e78),LL(0x08f5fd21,0xada49ad1),LL(0x998eec2d,0x3e35f765),LL(0x5a121c30,0x1f207544),LL(0xf5fdddb9,0x537426d8),LL(0x1dd7a92c,0x6cdbd6af),L_(0x000001c6), LL(0x9ac31da2,0x22850494),LL(0xd3189e72,0x7646877e),LL(0xe04fe426,0xee0cbac9),LL(0xf8802494,0xd9fdf793),LL(0xa975ea85,0x0c9c6045),LL(0x18cf38fb,0x02b88cb1),LL(0xa12c8778,0x9757e39e),LL(0x8e571e06,0xb126d254),L_(0x000001ec), + LL(0xd91f89ee,0xd77e7f7e),LL(0x2cf0f860,0xe9a24986),LL(0x705ade19,0xa4b26963),LL(0x0f929eaf,0xf6f18b5d),LL(0x1a12f7ee,0x0ff1861d),LL(0x4ef59d59,0x6b67d295),LL(0x18bcbd0d,0x70540dd4),LL(0x83b51e51,0x2670896e),L_(0x000001b3), LL(0x0b0a67de,0x090cb0d5),LL(0x89c8fd0f,0xb8b3eeba),LL(0x289c0d96,0xa8a26dc5),LL(0xe6dd7431,0xafde18e0),LL(0xf0a660c8,0x2cc76374),LL(0x397bcfa0,0x7654494d),LL(0xd958a15b,0x24476b8f),LL(0x53a314e3,0x67dea97d),L_(0x000000de), + LL(0x74ca8553,0x099db6d0),LL(0x79fa68c5,0x4c5dd75b),LL(0x75880817,0xccf37a0a),LL(0x92dc167c,0xf900a103),LL(0xc92d1684,0x8386aa09),LL(0xfba8f79b,0x53d25b65),LL(0xb1822202,0x183fbc1b),LL(0xfccc5a8e,0x21f550ce),L_(0x0000013b), LL(0xf2f85858,0x4925f513),LL(0x1b5dd268,0x3efe01ed),LL(0x65fdd3e5,0x47d317de),LL(0x4621cca2,0xdf49fdd8),LL(0x60e7bc31,0x66f9ab90),LL(0xe320caa6,0x2ca76c6f),LL(0x41361bf3,0x602d539d),LL(0x267e9ebe,0xf83bf8f0),L_(0x00000140), + LL(0x925d2d91,0xd471ad5a),LL(0xe6ad36d9,0x18a88bdc),LL(0x599734aa,0xb20b90be),LL(0xaa6c0fb7,0x33c88799),LL(0xceda14b2,0x7dad41f1),LL(0x3bb924ee,0xb7c643d1),LL(0xa63db6fc,0xcfe7d84e),LL(0x46de4666,0x71afb3a8),L_(0x00000072), LL(0xebe6128e,0x4a9235f4),LL(0x780d1146,0x2db34ea2),LL(0xb3ecdbc0,0x31fad3e8),LL(0xcdbe1207,0x7ab5ebf8),LL(0xdf431809,0xbf1d4990),LL(0x0f8e79eb,0xe93c1583),LL(0xfba03ee7,0xefc40a1c),LL(0xf76de664,0xd188b68d),L_(0x00000103), + LL(0xa3f4bcf5,0xf02dfbba),LL(0xf379ed8d,0x7857a0d6),LL(0x6c580cb5,0x7b4a59a6),LL(0x6d6738fc,0x1654de01),LL(0x7c102c44,0x8d6ededc),LL(0xb8a37f11,0xe92baa08),LL(0x6ecce15f,0x1b1b1c96),LL(0xf542a7b0,0x118752af),L_(0x00000169), LL(0xcf9be3be,0x02fd3092),LL(0x22a60f7a,0xd4c8209a),LL(0xdeeb8950,0x8636e6d7),LL(0x29511c76,0x09037c4f),LL(0x419f1652,0x4196d645),LL(0x935dc02e,0xeaef1b05),LL(0xcec8a6ec,0x2f5c9bf8),LL(0xb432cd40,0x375285bc),L_(0x00000116), + LL(0x7f267eeb,0x2a1279f1),LL(0xf11c0e49,0xc76f729a),LL(0x92b8f2a3,0x5437339e),LL(0xe00c8ca3,0x41f96b14),LL(0x1dbcc016,0x449dde57),LL(0x5fa3755e,0x0a0df11e),LL(0x42dc646a,0x5d317707),LL(0x3610d1c6,0x149d76f5),L_(0x0000008b), LL(0x76e5b808,0xc99fe831),LL(0x61f75499,0x19eef1a0),LL(0xd4c21a60,0xcc67deb8),LL(0x192fdd7e,0xec37ce33),LL(0x13250ef2,0xf6ed9344),LL(0xac4baff8,0x8d1e9777),LL(0x0d67d5c5,0x7183407f),LL(0xd1b52871,0x7887079f),L_(0x000000aa), + LL(0x64430a84,0x5637bc1f),LL(0xc9bb1131,0x102f522c),LL(0x38d318b3,0xb1dfff39),LL(0x0967edf8,0xc54708cf),LL(0xff7bf052,0xb7dea363),LL(0x5d9deef1,0x44846b8a),LL(0x5e3fdc0e,0x2ccf785a),LL(0xdf1138dc,0x16844b0a),L_(0x0000000f), LL(0x3b1beaf4,0x5076af3c),LL(0xac3bbbf4,0xdda27ca5),LL(0xdc76f92a,0x7c5f4d64),LL(0x67fb8aff,0x98258450),LL(0xfa7eea13,0x183f4c0d),LL(0xc38dcddf,0xc7ca9f82),LL(0x0789054d,0xa0ad28e2),LL(0xf484ac51,0x2b54cf18),L_(0x000001ce), + LL(0x0d9d6152,0x28f43810),LL(0x4ecd5aff,0x0a2146e6),LL(0x7e0c0df1,0x0d19ad5b),LL(0x6775181b,0x151d7c3f),LL(0x43c7a1b8,0x38a3ef9f),LL(0x2dd235c3,0x1fdd8171),LL(0x1f2597ee,0x4734726a),LL(0x083971de,0x92167cb3),L_(0x00000173), LL(0xfac04120,0x85ff590d),LL(0x952b767c,0x8b72aaea),LL(0x843ae9c1,0x004265e7),LL(0x307d7542,0x395a8932),LL(0xc2dea503,0xc7f73a8f),LL(0x3399e1ee,0xb86c7eb5),LL(0x2926b2c4,0x0d21cf86),LL(0x47a4f082,0x37deb193),L_(0x0000001b), + LL(0x685e8e4b,0xd88c27c3),LL(0x0240c0b1,0xeaa149a2),LL(0x79b4d2d7,0x18bd3d71),LL(0x368319a1,0xdb5d6ca6),LL(0x44a8c42f,0x587ba79d),LL(0x77c41337,0xdb57f6f2),LL(0xea1f7c4f,0x8ae39899),LL(0x77750728,0x8ec08a85),L_(0x00000083), LL(0x22355d19,0xa2946cf3),LL(0x598a6616,0x4d6a2c7a),LL(0x4bb8cec6,0xfe918a85),LL(0x94e93f01,0x833d8970),LL(0x64d5ba4a,0xa972b798),LL(0x05a95b5c,0x636ab756),LL(0xca11412a,0x2b50cab7),LL(0xeca1dc55,0x886d7097),L_(0x00000181), + LL(0xcb4f7b38,0x1a4787e2),LL(0xea069acc,0xa5590739),LL(0xa99d3f7a,0x601be73f),LL(0xcf6cca23,0xaa83e6e7),LL(0x3960cc53,0x5920b117),LL(0x20e0b86b,0xa7ac9dbe),LL(0x6b3ef99f,0xf468bb6f),LL(0x60ac6c56,0xae52f640),L_(0x00000099), LL(0xdc626c18,0xb7dd82a1),LL(0x008f892e,0x142f8425),LL(0x705cbf37,0x01a4b241),LL(0x4c8483d1,0x275951c0),LL(0x82075cfd,0xa7dae45a),LL(0xa9d9f282,0x63c98e81),LL(0x30bf2902,0xefc331b1),LL(0xc5f55add,0x2fdd6c95),L_(0x0000013f), + LL(0x4a6e860f,0xaa1272c0),LL(0x85afdbd7,0x53123c17),LL(0x796e466f,0x327374bf),LL(0x19701fb1,0x8c2b076b),LL(0x755659d8,0x8fee24c8),LL(0xc6001497,0x45d95463),LL(0x144b9a21,0x98a62be8),LL(0x9e1d51ac,0xd46ea2e1),L_(0x00000017), LL(0xff126e8b,0x87dd796d),LL(0x5e933815,0xad6f752f),LL(0x0f756584,0xa0d6329c),LL(0xc8afd335,0xef95a2f8),LL(0xa429ff1c,0xe9d51af6),LL(0x06c04336,0xbb9ac481),LL(0x0e389129,0x80d2d2dd),LL(0xb75b239e,0x128834d2),L_(0x000001f5), + LL(0x04ac9a1c,0x9fb461cd),LL(0x2abd08e0,0x7bca251b),LL(0xfa6e8384,0xf5d98ad8),LL(0x7e953f04,0xca3dcc08),LL(0xfd9f6c57,0x679c5992),LL(0xfac8f179,0xc9cf93cd),LL(0x0e29622c,0x050d1a32),LL(0x703c650a,0xc7848580),L_(0x0000006d), LL(0xc1188e58,0x60a160b5),LL(0x6d729218,0xbe9a3f42),LL(0x311911d3,0x864f8747),LL(0x8a79eb1a,0xe2ff5eb7),LL(0x66b881de,0xef83107b),LL(0x8784fc87,0xd139997a),LL(0xd894e5ee,0x9a80e84f),LL(0x1a2f4197,0x2ffb83aa),L_(0x000001a7), + LL(0x6619c168,0xbefe84df),LL(0x7fe74db9,0x7efd2da4),LL(0xc983adbf,0x0bbc28a9),LL(0x6535bd9b,0x169b3680),LL(0xcb39ad32,0xd2112121),LL(0x3f60a9f2,0xa91386ce),LL(0x3a1b138f,0xb1ef230d),LL(0x36ea6d68,0x8198043e),L_(0x00000105), LL(0x1ef3660b,0x58bee126),LL(0x3a1e13eb,0x84fe2098),LL(0x1044e049,0xd3d31ea9),LL(0x6e975e84,0xbdc58274),LL(0xcbeca3ca,0x4c27aa9f),LL(0xe9036bd4,0xcc717651),LL(0x982f94af,0x20d99920),LL(0x0268a0da,0x96c3d4be),L_(0x0000013e), + LL(0x8e317075,0x01712fc5),LL(0x00607c95,0x10e30ced),LL(0x77b023a2,0x53b465e6),LL(0x620a31c6,0xb10af467),LL(0xa8ea62e5,0x48d08ca5),LL(0x31ddd990,0x65af8778),LL(0x5be8899d,0x2b29f5ab),LL(0x21d38a08,0x7aa79283),L_(0x000000c1), LL(0xd56bb423,0xba4bc4d5),LL(0x28b7afb8,0xa4ef2e4b),LL(0xc314822c,0xae9b41f7),LL(0x882d9a51,0xf2b327a2),LL(0x1e6c2280,0x7ce965ab),LL(0xa49d1969,0x5708dae4),LL(0xea346d97,0xcff1175e),LL(0x572d2fbc,0x8dc700e9),L_(0x000000f1), + LL(0x971c75d0,0x3dd39efc),LL(0x11aab543,0xe47dc537),LL(0xf6290b96,0x38ce4cde),LL(0xe7a164cd,0xd9dcb339),LL(0xebee41ba,0xbc0e8d41),LL(0x18ca0dd5,0xd2a8a073),LL(0x92054e4f,0x366d13cf),LL(0x188fdcbb,0xa61f6fe4),L_(0x000000d5), LL(0x587afc9e,0xf03b4067),LL(0x4ac1fdd7,0x43baf1b7),LL(0x900c0863,0x35bd9902),LL(0xe71367f8,0x3f6d6815),LL(0xfd613341,0xc12cdb6c),LL(0xa8569f79,0x6e58f3c3),LL(0xd9ca8493,0xd420b011),LL(0x6d1ebe67,0x18a83579),L_(0x0000014d), + LL(0xbd7d4bad,0x4af0bab5),LL(0xade61274,0xcd1e04b0),LL(0xe21c3a53,0x4ec80a7f),LL(0x4b987124,0x28f48386),LL(0x23f6fd14,0x63b180bf),LL(0xe2b4889d,0xacf748b0),LL(0x2996dea6,0xf3a06107),LL(0x7cdec9d5,0x7248e660),L_(0x00000130), LL(0xc2a9858e,0x2d38ce4f),LL(0xc709b1fa,0x87521e69),LL(0xf5996fd9,0x4d05bae8),LL(0x131ac99f,0xc3bad75e),LL(0x62578fe3,0xc9d13920),LL(0x3ada2279,0xb6fbac90),LL(0x696da364,0x6c292885),LL(0xd02ce135,0x5f814ddb),L_(0x00000048), +}, +/* digit=48 base_pwr=2^240 */ +{ + LL(0x3d1074e0,0xff10eeb7),LL(0xe087c1a0,0xc77549f2),LL(0x5e2e0837,0x74d6808a),LL(0x48c7156c,0x11f82ce9),LL(0xbc13bf7c,0x72ee287e),LL(0x06f6a514,0x28c4e6f9),LL(0x165038cb,0x320fef0b),LL(0xb6f1c9d9,0x369852d8),L_(0x000001dc), LL(0x57d310ce,0xadd6b6df),LL(0xcd825c08,0xdcd4cb28),LL(0x48bebf85,0x644e1cbe),LL(0xf1d5aa6a,0xbebbd351),LL(0x908ba85c,0x4d8a2aa1),LL(0x518b1bc8,0x343d2d77),LL(0x29b988ed,0x7ea90982),LL(0x940fc8d0,0xeb433a9f),L_(0x00000059), + LL(0x8f96ebc1,0x54a67c95),LL(0x984cd0ed,0xef67809a),LL(0x8dd8453d,0xde0abb72),LL(0x4fe5f363,0x4b73609f),LL(0x8e4fc461,0xaab1b83c),LL(0xb989fee4,0x06d2158c),LL(0xfe56f7d6,0x52096597),LL(0x70734a0c,0x4bb17572),L_(0x000000e7), LL(0x094ef503,0x32b2f44d),LL(0xebd6d9b7,0x2c29898d),LL(0xe0ef3ff7,0xe5d5ffd4),LL(0x30b99ae2,0xe1c94a38),LL(0x2dd5fca5,0x15b084de),LL(0x6d08e970,0xe94504be),LL(0x90fe0fe0,0xdb79eaed),LL(0xafa2897d,0x1b99b51e),L_(0x00000143), + LL(0x45dd470c,0x907208e4),LL(0x551b38ea,0x1157ba3e),LL(0x1b72b693,0xcf9f94c5),LL(0x83c616c9,0xaf1c59b1),LL(0x2fe84fca,0x7ed67f1d),LL(0xf1bd77c9,0x1d1e1a09),LL(0x51550daa,0xbac2f477),LL(0x58d345e7,0x84ab938d),L_(0x000001dc), LL(0xa5d95b5f,0xa404c99b),LL(0x29f414da,0x5a1bac7d),LL(0x81c9d673,0x56fda469),LL(0x2c1bc499,0x66bdcd65),LL(0xfe505f2a,0x9783eab5),LL(0x92378106,0x6f9996ab),LL(0xa7330e63,0xa6238170),LL(0xfa70e33d,0x9a7f0670),L_(0x0000010a), + LL(0xfee86a58,0xf15be04b),LL(0x32b87572,0xe35f663e),LL(0x94b48632,0x165f5c52),LL(0x62fb4267,0x7d3b9413),LL(0x407dadeb,0x189d86c3),LL(0x5689012e,0x63e5f780),LL(0x61c7907d,0xa2b7e335),LL(0xc0dc085f,0xd9e3c3c0),L_(0x00000070), LL(0xa9cbe4f2,0x0cfb081d),LL(0x5ac2d2f3,0x11fe0a52),LL(0x32662679,0x8fcbbd46),LL(0x3e344c2d,0xb1ff4122),LL(0xa0a08757,0xa48229e9),LL(0x6f7101c0,0x56b8c92c),LL(0x4af0e804,0xbb9a086c),LL(0xc21360d8,0xed22dd74),L_(0x00000169), + LL(0x5a00ce71,0xb34ef3a4),LL(0xac5c1fed,0x800620f8),LL(0xba6237c0,0x97dc7c79),LL(0xff56f449,0x5563d588),LL(0xe8ab9474,0xb2b00a9a),LL(0xb8d1df21,0x6a286295),LL(0x4cf9b378,0x00426dbb),LL(0x30b70043,0xa6195ec8),L_(0x000000c9), LL(0x1fa97f98,0x5a4e4b25),LL(0xd3a62f9d,0x61b4d385),LL(0xad987701,0xb90b4cda),LL(0x41727a73,0x84f90823),LL(0xec4abf7e,0xd814c4a3),LL(0xed3df0de,0xc453671b),LL(0x0c8945f2,0xdda88869),LL(0x94087855,0x25b6219a),L_(0x000001ef), + LL(0x0ce5f28e,0x705e5e78),LL(0x3af745ca,0x93ca952d),LL(0x7351cb28,0xfedeccdc),LL(0xc12e9837,0x7e7bfbbf),LL(0xd14b9356,0x47999f34),LL(0xc6295462,0x3f729887),LL(0x5692b0da,0xc96edd28),LL(0x812e383c,0x60ea4fc9),L_(0x000000ff), LL(0xef1bc941,0x70199860),LL(0x493b99ba,0x2d090c33),LL(0x279e0c37,0xbe1503ff),LL(0x3fbe286b,0x80f6465c),LL(0x06d81c3e,0x0a9257bf),LL(0x2a448d3a,0x402ee72a),LL(0x6a5669fe,0xe592b91c),LL(0x5315497c,0x5e220ad9),L_(0x000001ae), + LL(0x93b397c9,0x3318572b),LL(0xa3327857,0x0e667f17),LL(0x7af5bff7,0x2e60b913),LL(0xfb65a96b,0x9e25ef17),LL(0x9188dfee,0xdd117ab2),LL(0x830a2c9e,0x5472d03d),LL(0x063aa4e1,0xd8512ca1),LL(0x9593f42b,0x67ebcadf),L_(0x00000181), LL(0xa143be47,0xbbccf7b7),LL(0x40a8123d,0x80d4a4b1),LL(0x8562ea6a,0xe8424774),LL(0x53e144c7,0xa39d882f),LL(0x49ac8b6f,0xb451fe15),LL(0xffe4b1ea,0xc4538f34),LL(0x0527aede,0x1076cc29),LL(0xbcd8efdc,0x4f2ddd83),L_(0x000000b7), + LL(0x670c5c5b,0x046d9801),LL(0xf7b5e720,0x0601ff33),LL(0xa07084cc,0x900e6b0a),LL(0x791af83b,0xd2391e07),LL(0x2dd856fd,0x0430654d),LL(0x63408d88,0x82606889),LL(0xc176e8bf,0x2fa4b443),LL(0x18c663e6,0x5deafc4e),L_(0x0000019b), LL(0x48d8ae04,0x950e8cec),LL(0x11b8065c,0x1316d53d),LL(0x3a5ccc8c,0xfeecd686),LL(0xed41a668,0xbb41648c),LL(0xf76ba771,0x9a4bb4b6),LL(0xa9b2b49a,0x370974d5),LL(0xf9f130ae,0x200485de),LL(0x4c25f49d,0x4b31a1b8),L_(0x00000083), + LL(0x24ffe291,0x23a38bed),LL(0x41132058,0x4bf85483),LL(0xba359818,0xbdd23ab5),LL(0x3571fdd9,0xd8f1fbf5),LL(0x740422c0,0x46b3d29b),LL(0xdeca158b,0xf7c74726),LL(0x69a6765b,0xe058b8b2),LL(0x3a247a5b,0x9d49dfe5),L_(0x00000125), LL(0x49bfcbe2,0x37b93476),LL(0x3090fa48,0x219565ef),LL(0x30eb0e12,0x996b7d11),LL(0xe2ef23ae,0x935017a2),LL(0xfedd570a,0x59810960),LL(0x510b5963,0xf4feef53),LL(0x4eeb57ef,0xa6aed7bc),LL(0x500fc7dc,0x4dabb423),L_(0x0000009c), + LL(0x502210f9,0x2f6be4ac),LL(0x36ffcfaf,0x97a1a521),LL(0x874cac2d,0xd4b6d8f6),LL(0x4e03da3a,0xebd4b9c9),LL(0x058f53fa,0x05bdde0c),LL(0x54da0035,0xea492dfd),LL(0xf1d437ba,0x083ae453),LL(0x837cc36f,0x84792d73),L_(0x000001a7), LL(0x7ab16b91,0x08283456),LL(0xe627feae,0x5b031ea9),LL(0x5ab7febf,0xbc9c1a1e),LL(0xdf744ce8,0x0a851efb),LL(0x944a28d0,0x92d1258a),LL(0xa2c52c0a,0x8db3d01a),LL(0x3272efed,0xc3e55528),LL(0xdd38ae95,0x67075092),L_(0x000000ca), + LL(0x6c8b9288,0x201a8b72),LL(0x55d5044c,0xcd7dd04a),LL(0x5fefdd8a,0xf135da4f),LL(0x326e5c4a,0x93ab679e),LL(0x0ebd3dab,0x9e1c63de),LL(0x3da9430d,0xb6139a96),LL(0x1c3e1a0b,0x0bbe99d7),LL(0x31ad9e61,0xb4c624a5),L_(0x00000041), LL(0xd69aa80c,0x312fa8a7),LL(0x10699493,0xb830105a),LL(0x432ef74c,0x427ed742),LL(0x21457fc6,0x32a8f306),LL(0xed7ee077,0xde91b340),LL(0x7b2b2143,0x97655415),LL(0x2c36d1f0,0x3e70f7df),LL(0x8cb68be3,0x10666362),L_(0x000001a0), + LL(0x1c2c5d0a,0xbdac0199),LL(0xf48304d4,0x58ea0344),LL(0x7badcb3c,0x61cc3620),LL(0x7fa76693,0xee100174),LL(0xcbbd3041,0xb845bb4b),LL(0x2ab9fe8e,0xbc927037),LL(0x7e87d3ef,0x7c6a4dcf),LL(0x87fd392a,0x4efc311a),L_(0x0000016b), LL(0xf99d4987,0x3518a503),LL(0x093c711b,0x5ed52438),LL(0x8de87657,0x1283fea5),LL(0xa57d89d4,0x1d760642),LL(0x37377224,0xbf397e80),LL(0x0c073eb0,0x2d948da0),LL(0x19066ff6,0x02fb3665),LL(0x6f15cfd1,0xfb0a4e90),L_(0x000001b3), + LL(0x0703434d,0x36c93ab6),LL(0x08a36b13,0x54182f0b),LL(0x6018b27b,0x1eb09d80),LL(0x52b2eff5,0x5cab8c14),LL(0x54baf54d,0x09c5f439),LL(0x9128c26e,0xa0c91a3e),LL(0x3c462ce0,0xc8a5d523),LL(0x0dcb5998,0x2d1570bd),L_(0x00000066), LL(0x168afb3c,0x28b7e59a),LL(0x51e02e1e,0x7db3beb7),LL(0x95d9b53f,0xd954033d),LL(0x4280b408,0xfca4117d),LL(0xd87fffcb,0xa8a2c41d),LL(0xedfe3235,0xa4e146b0),LL(0xc9ab6206,0x23f56e8a),LL(0x6cc8df44,0x7a8946c5),L_(0x00000054), + LL(0xe30728ab,0xeda148e9),LL(0x09a1b090,0xb3c8e802),LL(0x4fed9972,0x6feab8c2),LL(0xbd0bf024,0x684e8ba5),LL(0xb6e56fc0,0xc679d0b7),LL(0x3a2827e6,0x05aad3cf),LL(0x9605e502,0x154eec73),LL(0xc7d72f2b,0x9336c1e2),L_(0x0000009a), LL(0x04181bc3,0x17c5f246),LL(0x0c346607,0xf9d4abe6),LL(0x9d5267c4,0x53390747),LL(0x76bf72c0,0xe2e74911),LL(0xd4ea29a3,0x25cb2342),LL(0x5c9021dd,0x7e8d6c56),LL(0xac452ce1,0x1fd1d0fd),LL(0x7f5955ad,0x61f3d3df),L_(0x00000094), + LL(0x7a984abf,0x46f086dc),LL(0xd299e678,0x3ae95a65),LL(0xb7f240f5,0xadf74e6d),LL(0xdd46db9e,0xc95ae291),LL(0x3dae88ec,0xbc688dc9),LL(0x4474ebcc,0xe0bd1aae),LL(0x3a30df47,0xd32d0317),LL(0x222e18e3,0x088bd254),L_(0x000001ad), LL(0xda1caa7c,0x3b9e4f98),LL(0x584fa9c3,0xe3bb36fe),LL(0xa33fbb40,0xece5a0db),LL(0x990ebace,0x2d1efc59),LL(0x1c0c2167,0x0ea367aa),LL(0x18eb3285,0xaa6c72bd),LL(0x4a9d7d68,0x69e3bcf6),LL(0xcd396faf,0xb1399f8f),L_(0x00000027), + LL(0x20f43bc2,0x14169ebb),LL(0x776ec8b3,0x4d9ce016),LL(0x40cc814f,0x64db6f3c),LL(0xde6701fd,0xbc27b375),LL(0x1be16687,0x41b2641f),LL(0xaaf1c8ca,0x5c7ebdd8),LL(0x667e429e,0x9221918a),LL(0x84d2d4cd,0x68099d93),L_(0x000001bf), LL(0x65966739,0x502a6f1f),LL(0xe772626c,0x612fc65a),LL(0xd1717c45,0x06b47588),LL(0xcd0bd273,0xfd9dbcb0),LL(0xf7b68702,0x5beaed3a),LL(0x60d2a43a,0xd9e3bfb5),LL(0x618c6158,0xeec14b9b),LL(0x1dad1537,0x9166a242),L_(0x00000117), +}, +/* digit=49 base_pwr=2^245 */ +{ + LL(0x7b9e7889,0xe957ebe2),LL(0x3ae1f292,0x2bd715ca),LL(0x6ae08fea,0x3b2ea475),LL(0xcab67aaf,0xf247c9f5),LL(0xd47caa37,0x53af0925),LL(0x409f1b89,0x57e7bd1f),LL(0x4ee5b8e5,0x0b979eb1),LL(0x0e289030,0x16dd58bb),L_(0x0000017f), LL(0x1d78d6b7,0x3dfcb1d0),LL(0x595db0c6,0x8e6aaf05),LL(0x9217ec90,0x45106ff4),LL(0xab12df36,0x8489adb8),LL(0xc4207aff,0x257b835b),LL(0xabbbb85d,0x706e08a1),LL(0x71ad10a3,0x6d2a5b7d),LL(0xe224792f,0x528cf56a),L_(0x0000003d), + LL(0x8295b8b6,0x65b39aaa),LL(0x0690f149,0x1270c951),LL(0x763e6fce,0xbafb3a9f),LL(0x3f839143,0x0dc990be),LL(0x3866c189,0xa0d6a0e7),LL(0x087b74c8,0xb520d476),LL(0xd8910a14,0xbd81006e),LL(0x16e6fb91,0xfae3e52b),L_(0x000000a1), LL(0x9757756a,0xbe4b13d0),LL(0xc54fba1e,0x3f1884ce),LL(0x4519ff97,0x68950392),LL(0xfb9e4f42,0x2d309b59),LL(0xf2ce5e20,0x004b85f0),LL(0x35d898e0,0x05c20b17),LL(0xd4f54e0b,0x34add1fb),LL(0x178e2a7f,0xee6a8dcb),L_(0x000000c7), + LL(0x9fa52c89,0x8fc48ea8),LL(0x6a680dfd,0x4b09bae8),LL(0x78d67917,0x7cea1e12),LL(0x0f37ae3b,0x8383d337),LL(0x9f51107a,0x157913dc),LL(0xbbd05c8e,0xc347e479),LL(0xe7f7f024,0xc27dfb63),LL(0xa32c2410,0xa1e55ac4),L_(0x0000005a), LL(0xa0c5983d,0xbc8a42a9),LL(0x31f03f3e,0xdb0533ac),LL(0x07b4440f,0x1b5cb9b7),LL(0x522041e9,0x18816d64),LL(0xa0763672,0x78c44489),LL(0xa7d823be,0x0289668f),LL(0xa033e066,0x14b7bda9),LL(0x1bf9880e,0xb68f4c04),L_(0x0000004e), + LL(0x992b024d,0xcc47fd44),LL(0x301e6aa5,0x4ca3c2ae),LL(0xa239d460,0xb59f6635),LL(0x72a93968,0x93da741e),LL(0x6f3e7cb4,0xe451c847),LL(0x958457a0,0x0539a4ae),LL(0x0ccc6f49,0x70df123a),LL(0x4b36ee4a,0xa7af1f3e),L_(0x00000171), LL(0xa5bf5964,0xd54e934e),LL(0xa4f9d8d0,0x838881f3),LL(0x5759057f,0xd231904c),LL(0xf74d21e3,0x65fa2854),LL(0x09110e09,0x3e3fbb9d),LL(0x73f82547,0x66595687),LL(0xc3213d46,0x4ee05953),LL(0xc6c9fbf7,0x8044dde0),L_(0x0000015d), + LL(0xf19f1768,0xfbd4f466),LL(0xccc78e3b,0x4ab17eab),LL(0xe0f582bd,0x42edf70d),LL(0x32c21454,0xe1c56694),LL(0x7f57c601,0x01c830d3),LL(0xe9eae160,0xe56900b5),LL(0xca26d56c,0x36688674),LL(0xb2fb4c7c,0x145b107e),L_(0x0000012f), LL(0x53c6182e,0x47ff90cc),LL(0xaaf18b16,0x8fc84257),LL(0x96b0582e,0x9e3a6661),LL(0x4532767f,0x0d14fb71),LL(0x29d6ef11,0xdc2f950b),LL(0x54eb6cc6,0x85acbd0a),LL(0x525b30dd,0x5c05fb17),LL(0x67dd5268,0x2af3ff75),L_(0x0000006d), + LL(0xaabdb0b2,0x1475f80e),LL(0x6b7bb07c,0xd90a1e1c),LL(0x92ecf09d,0xc193105d),LL(0x5feeb4d3,0x322cd2b8),LL(0xd3b68b08,0xb3acd3e0),LL(0xb0ed276b,0x50511672),LL(0x512d83e9,0x5830b5d3),LL(0xda968b0a,0x849009db),L_(0x000000cd), LL(0xa9aed6cf,0xadb30375),LL(0xb42997c1,0xc6687e52),LL(0x1d88f275,0x5c1d5e8e),LL(0x5d9e895e,0xdbf775d5),LL(0x1f149b28,0xc29aed12),LL(0xe2724e7a,0x220a70ba),LL(0x7e781bbf,0xcf9cd146),LL(0xfb0950fc,0x40e01766),L_(0x00000026), + LL(0x26492a48,0x8f120fe7),LL(0xb833386c,0xbca86762),LL(0x7d77fbcb,0x2f67d175),LL(0x5165ed7e,0xf29932da),LL(0x40520604,0x607db461),LL(0x88627d90,0x74dd9734),LL(0x9d6e8589,0xff8795e0),LL(0x0898a1bd,0xeba49f57),L_(0x00000104), LL(0xf0c19be8,0x3e449e91),LL(0xc086fd4a,0xce081f35),LL(0x60f6bfc7,0x6b980172),LL(0xf116eb17,0x438fccb9),LL(0xb036eed0,0x3b9d80a6),LL(0x355bcf69,0x17f28db4),LL(0x1d897ded,0x5b488d87),LL(0xb2564e1a,0xa12f88be),L_(0x00000147), + LL(0x6223dd4a,0x84db5faf),LL(0x0b0f5e29,0xd39d495d),LL(0x0a14e52d,0x723841ce),LL(0x365ed8de,0xb4ef0fcb),LL(0xdbcb1fe9,0x3aa7d5d2),LL(0xb19047ee,0x2d33c7e0),LL(0xe2978f53,0x2ad3b9dd),LL(0x9dbc97d1,0x7d591532),L_(0x00000104), LL(0x02d16555,0xb3172c7a),LL(0x8804b57f,0xbeeb32c4),LL(0xad774958,0x59e99dad),LL(0x34b2bc96,0x90ab3c79),LL(0x33fd281f,0xe477effe),LL(0xfaa713ab,0x78b329a3),LL(0xf3df2353,0xac36cbb9),LL(0x62e824d0,0x01585145),L_(0x000000d8), + LL(0xd8f323fb,0x81a85944),LL(0x3dd3e0be,0x51a21fab),LL(0xd871d4d4,0xb561f31e),LL(0xb4ce4cde,0x4449b15f),LL(0xce67b526,0x64493f22),LL(0x82ddd4ad,0x546ec9b8),LL(0x0adc07a9,0x4dba63e9),LL(0x82628c7e,0xcc85d728),L_(0x000000a9), LL(0x5e900de4,0x358c4d59),LL(0x8391c4fa,0xd7be91ac),LL(0x82f89ceb,0xac49480b),LL(0x0dcd6532,0x48237726),LL(0xd2dee6e8,0xaeda17a0),LL(0x13850532,0x2d6729ba),LL(0x201426a9,0xf52c6ebc),LL(0x188c6ec6,0xe02e54ae),L_(0x000001c3), + LL(0x9b37123b,0x274b93dc),LL(0x0d11cfe3,0x01caef2f),LL(0xbe8ef001,0xef0d218a),LL(0x2810cd03,0xace6e761),LL(0x5c17a13d,0x65a61b64),LL(0xcfaaba81,0x669bf078),LL(0xd429ba49,0xd9a6abec),LL(0x0f71e96f,0xf999276c),L_(0x00000185), LL(0x592f7894,0xe42d0a9c),LL(0xfcc98aed,0x3730d520),LL(0xbb02c8f7,0xe10a8edd),LL(0x4886062f,0x57fa6238),LL(0xdab28f83,0x308d0fc8),LL(0x13c4d161,0x8db6b346),LL(0xf5b7f11e,0x70d7617e),LL(0xd7fc6e4f,0x6c6606b4),L_(0x000001dc), + LL(0xe3c773fc,0x30cb34f5),LL(0x854f6660,0xd3093680),LL(0x5abdfb30,0x7939c865),LL(0x3d739567,0xa46ffe9f),LL(0x3a7253f9,0x8fd8f096),LL(0x151f1baa,0xa1443d09),LL(0x9a29f4f0,0xb2ed7af8),LL(0x0ad8104e,0x3a019dfe),L_(0x0000001d), LL(0x76fc8041,0x0868fcae),LL(0xf81d0998,0xdba2642e),LL(0x7f6f6367,0x57d4f243),LL(0x6a189847,0x92fa4eaf),LL(0xc022a76b,0x4e736ea2),LL(0xdd251f4b,0x06ebdd88),LL(0x39b7f55b,0xb9f83aec),LL(0xf34e682b,0xe8264e21),L_(0x000000b1), + LL(0xba33a960,0x502d83da),LL(0x377dd454,0x04a7d732),LL(0x60c9b2c8,0xfa223630),LL(0xe06fc03b,0x7e497e85),LL(0x145bb405,0x456567db),LL(0x39898314,0x2d3a76ad),LL(0xeb33a535,0xd36b4686),LL(0xebbad130,0x134c3479),L_(0x000001f7), LL(0x8a5778a7,0x10340c30),LL(0xf7b160b7,0x1f4c9e0a),LL(0x729201ef,0x09fe7ed4),LL(0xe28d29ca,0x57eb2d3f),LL(0x3e4bfbfc,0xfe99fffb),LL(0xe7397e68,0x62215a66),LL(0x18c1dc25,0x16278a5c),LL(0x1045ab03,0x3d04aaca),L_(0x000000a3), + LL(0xb45b8788,0xc3b9c902),LL(0xe8e7e9b5,0xe1deb5a2),LL(0x6f0ccb02,0xcc118df4),LL(0x931e8bf3,0x44d4d935),LL(0x8d49c80c,0xae880f5f),LL(0x294917c6,0xdaf4ba46),LL(0xf7ee5bdb,0xe09285b3),LL(0x11c3f0c5,0x981a5efe),L_(0x000001a2), LL(0x6f1e6d94,0x150c77e6),LL(0xc23026fa,0x8e7cd3f5),LL(0x567d2494,0xfba4ae31),LL(0x380b42d3,0x7135a34e),LL(0xdf2c5139,0xf390e611),LL(0xfd3ff544,0x1f3b21ae),LL(0x4254bcbc,0x67fca024),LL(0x68f4c9e3,0x2b49a43b),L_(0x000001ff), + LL(0x68ed5662,0x0fa1e08c),LL(0x31f2c30a,0xb65f32e1),LL(0x2d06bb12,0xfec7dae7),LL(0x95c78209,0xb2e0fbb5),LL(0x7d228e9d,0x84a73eeb),LL(0x0a7cd176,0x4968f085),LL(0xb3a9c57a,0xf1034b1b),LL(0x12dc73c6,0x942d801d),L_(0x0000003e), LL(0xd74b5636,0x90895a11),LL(0x8864d82d,0x8f322a4c),LL(0x1db6f8b1,0xef6cb619),LL(0xdc8f7532,0x95fe8c47),LL(0x6bb6ba07,0xb376849e),LL(0x6839da29,0x55ee699f),LL(0x9e4c3d09,0x013177ca),LL(0x06ac03b0,0x0b1b8598),L_(0x00000187), + LL(0x68b8e4b1,0x556e1c75),LL(0xb2cfde0a,0xbf8d1b12),LL(0x77dcfbef,0xbfb5199d),LL(0x8803a28c,0xb3b33660),LL(0x9ab9ee66,0xffcfec92),LL(0x75479f96,0x66780a53),LL(0x9e3f38c0,0xe21a1107),LL(0x8d2c8147,0x61fe7ba1),L_(0x0000002e), LL(0xf14b8da9,0xf175c60b),LL(0xc9c58bd9,0x94928d32),LL(0xf4158167,0xa1977e7b),LL(0x3720a8c9,0x50e84c76),LL(0xb29acf00,0xa73b8ebd),LL(0xdf12fc49,0x8d8a4296),LL(0xf75a8ea8,0x1abde921),LL(0xaa9b61ff,0xf9a127a6),L_(0x000001d8), + LL(0xd278de5a,0x458b071b),LL(0x5b584d1f,0x0313ed9b),LL(0x5f476cd6,0xc54ce5fe),LL(0x007678c1,0x6d145a77),LL(0xe258964a,0x0c62f8fe),LL(0xfa68420c,0x595f7056),LL(0x63621f28,0x2d891192),LL(0x5d8cf9f8,0x32cc419c),L_(0x000001d6), LL(0x130243d2,0x8d5a87bb),LL(0xbcf908d7,0xc4e517b3),LL(0xd0ef67bc,0xba70f65d),LL(0x30e5dd35,0x41af2fd9),LL(0xaeb9fb07,0x448314ee),LL(0xf71f75eb,0x3702fdd3),LL(0xbac48350,0x1d2c0a91),LL(0x1ebd11ec,0x96f4f8e9),L_(0x000001cd), +}, +/* digit=50 base_pwr=2^250 */ +{ + LL(0xf4bf04df,0x31cb2cfc),LL(0x0c3adb10,0x13e25b6e),LL(0x3dd2ab40,0xff8fa4cf),LL(0x758e2edf,0xfeffd307),LL(0xf31ad907,0x4baf111b),LL(0xeba1b456,0x3c4f6a12),LL(0x13a81607,0x94fad755),LL(0xe7fc43bd,0xaee6974d),L_(0x00000100), LL(0xb8d44eee,0x369ffff5),LL(0x5334df1e,0x64f19da6),LL(0x5c2b9ceb,0x01321d0f),LL(0xc5ca3390,0x02b87e91),LL(0x45689acf,0x3a49c8b5),LL(0x049dbf7c,0x93f7ed7c),LL(0x8d277840,0x73a0a1d5),LL(0x726f20ba,0x702173d7),L_(0x000000b2), + LL(0xe3d95d4b,0xe45eed99),LL(0x8fe19237,0xddc0cb97),LL(0x7eb46e14,0x4df73f68),LL(0x57bdaf6e,0x8670ac6f),LL(0x847741a1,0xa46fbe2b),LL(0x02454925,0x82f9632d),LL(0xc15a10d2,0xaf2e144f),LL(0xc55aed10,0xfcdce815),L_(0x000000af), LL(0xc44dce06,0xa506cebb),LL(0x03aaab25,0x48b6559b),LL(0x933863a2,0xc348048a),LL(0xd37a9de4,0x26cd5e20),LL(0xc20f4402,0xee95db69),LL(0xff1c74e9,0x2f425e1e),LL(0xd820bb88,0x1933a6f8),LL(0x6f95cad2,0x93758ef0),L_(0x000000b3), + LL(0x6d40379a,0x87db0c0b),LL(0x3e1edc80,0x4c5fed50),LL(0x8c80df24,0x0d788315),LL(0x5caf06ac,0x12556a93),LL(0x95b47183,0x76d86da1),LL(0xc5714cff,0xcec43480),LL(0xc2f30fbd,0x4e4b2ab3),LL(0xc0cb91c6,0x3a9665b8),L_(0x00000121), LL(0xcbc11bf0,0x75b252f6),LL(0x87c8dce3,0x501537b7),LL(0x84253d3b,0x6a40795c),LL(0xa38fd372,0xb45a08cc),LL(0x22234e1d,0x09918d4e),LL(0x76319208,0xea70d97b),LL(0x3ef6521d,0x0bdcb67c),LL(0xae2d874b,0x5bf47d8d),L_(0x00000024), + LL(0x8fe4e5c5,0x4aedde8b),LL(0xc0d36b58,0xaba27830),LL(0xc0f869dc,0x32bc7d59),LL(0x14a35cbc,0x22d71ab7),LL(0x04bed4bc,0x00680d9e),LL(0xdf25061f,0x3bf0836a),LL(0xb3d768c3,0x3b0d7fed),LL(0x616b984e,0xaa12f95c),L_(0x000000c3), LL(0x3c8c5d5c,0xbd923c28),LL(0x9a32e9b2,0xfbaf0321),LL(0xf0d8e95a,0xed15bdb0),LL(0xd3039b5f,0xd8942727),LL(0xcc59ce26,0xa1dec9a4),LL(0xf0b3676f,0x21992696),LL(0xb8c7cfb1,0x27260c98),LL(0xc1c97929,0x66cb2541),L_(0x0000002d), + LL(0x97538cbd,0xee612332),LL(0xd25447d7,0xa1040800),LL(0x9c9bdc12,0x06fb815b),LL(0x191fed4b,0xae49fbdb),LL(0xd9407747,0x3d19e592),LL(0x9715df76,0x4613ac78),LL(0x1e9e20a7,0x6c932530),LL(0xe2bfff7a,0x92e124fd),L_(0x0000000c), LL(0x6bfd0423,0x13390bb3),LL(0xb87dda88,0x40017ffb),LL(0x979fe6b8,0x635bb57d),LL(0xb6fc9a61,0x8ce87e55),LL(0x535b6b63,0xea1ec56c),LL(0xf567cddc,0x06b927fc),LL(0x72c516ee,0x6fb0868c),LL(0x2ebdac5a,0xfb20cdff),L_(0x000001c3), + LL(0x76e19265,0x53bc630e),LL(0x506faf0e,0x88127211),LL(0x64c166ff,0xad3fc9e2),LL(0x6308dc18,0xb271bc9b),LL(0xec631a3e,0x23be699b),LL(0x2e23525b,0xbfded0b1),LL(0x2391574a,0x69f0d2b6),LL(0xa8ede972,0xcfd5d67b),L_(0x0000001b), LL(0x194cc299,0xf244f4b2),LL(0x911e4585,0x7871cfc3),LL(0x52af7b51,0x331dbf96),LL(0xd41147d5,0x7a399291),LL(0x48e46193,0xb0e20d54),LL(0xd985a24f,0x98e92da0),LL(0x7266525c,0xe9b74352),LL(0xe84bc9e9,0x0956c443),L_(0x000000b9), + LL(0xe9d37b18,0x456032b1),LL(0x30dc5e77,0xd6168724),LL(0x47f55c35,0x18a17037),LL(0x154ea414,0x86d54c7d),LL(0xe14c43c8,0x8d092542),LL(0x78f9b9e8,0x986d7498),LL(0x98519065,0xcc71fd0e),LL(0x4d22c2b8,0x3de62260),L_(0x000000f5), LL(0x91d1b267,0x4de89064),LL(0x601dee13,0x91ac8ed6),LL(0xd375837e,0x8587c0dc),LL(0xa03d56de,0xd2c2524e),LL(0xa4331dd9,0xf36ec517),LL(0x0f8bb8e6,0xb100599c),LL(0x0dc65f7a,0x8ada0049),LL(0xa298259e,0xdd8602f3),L_(0x00000083), + LL(0x1b2f821d,0x01e839c8),LL(0xcb7e709f,0xf9520b0a),LL(0xc4857ab9,0x3a85ef6e),LL(0x09f9eda6,0x51f47572),LL(0x96daca66,0x6e717337),LL(0xccecd697,0x40b37bfa),LL(0x29f4ce02,0xcbb44372),LL(0x0fe8a0ff,0x50a9f191),L_(0x0000018a), LL(0xa3781970,0xcf2ed75e),LL(0xf948f559,0x524a7d80),LL(0x3e1fceef,0x058a1573),LL(0x25fd5510,0x5865318e),LL(0x14c29ed3,0xcb7d9fa1),LL(0xcaa64e51,0xf171b487),LL(0x25580546,0x006163b8),LL(0xde740000,0xb9c9d686),L_(0x00000055), + LL(0x87d0f1ad,0x4cf7363c),LL(0xd4fe9fd3,0x9bd13abd),LL(0x4b7d7e77,0x66face9e),LL(0x42746d44,0x0edf9d57),LL(0xd5f51826,0x888b45bf),LL(0x37b7e3fa,0xde49e8c9),LL(0x0262004d,0x8fd87627),LL(0xdc4da423,0x9122108a),L_(0x00000012), LL(0xce31cec6,0x2990a670),LL(0x1be9607f,0xf2081d18),LL(0x8855d0c8,0x11fb1c34),LL(0xc4c2574d,0xf1b8ff1c),LL(0x3e444ec2,0x4404e3fc),LL(0x2db84189,0xb7726488),LL(0x0dd78e74,0x7de996b1),LL(0x7da11b57,0x12b7b41c),L_(0x000000b4), + LL(0x6a5bd2b7,0x343d29b0),LL(0xd33329b0,0x82fbc88b),LL(0xd3fc973d,0xe1e7bcdd),LL(0x111c0001,0x1c56ee4a),LL(0x0cb45e7f,0x65818c84),LL(0xaccf98e4,0x69029f68),LL(0x6bbf8831,0x53ac7e98),LL(0xe2fa2c45,0x8eccfe60),L_(0x000001db), LL(0xb7950225,0x0e5094fb),LL(0xf11a656a,0x3eed5459),LL(0xd3afccdd,0xe6e4111f),LL(0xc0d31cdb,0x822775ae),LL(0xfb39d140,0x04034f9a),LL(0x5954dd7b,0x8adace51),LL(0xc58c7b83,0xeef24d4c),LL(0xe9d767e5,0x40051c4d),L_(0x0000000b), + LL(0x7f21ed73,0xfb8a9c16),LL(0x300cbdfb,0x12e137b8),LL(0x22e8279d,0xefc00fd0),LL(0x173a4228,0xe30fee24),LL(0xaf4fb8a2,0xaa67fa02),LL(0x6171abf8,0xda82a49d),LL(0x418d47f2,0x3ea61949),LL(0x572fdfa4,0x581b7570),L_(0x0000001a), LL(0xbfe14768,0xceb46b56),LL(0x36fbf6b3,0x2855bf4d),LL(0xd4e1ce80,0xeeceaddf),LL(0x5130ec7d,0xeb1ca189),LL(0x57123316,0xabed8057),LL(0xb7e8b4c8,0xcb8de9f3),LL(0xa878fb40,0x81b143a5),LL(0x2fa96496,0x9080408b),L_(0x0000012c), + LL(0x22b150de,0x9a87c082),LL(0xad76f636,0x222ff210),LL(0xf2177234,0x874b4d66),LL(0xfb6d673f,0x7a63aa6f),LL(0x559b847a,0x1fb601b8),LL(0x7f528818,0x1d5a56e1),LL(0x2dceae56,0x159cad3b),LL(0x64799ea5,0xe50c2b70),L_(0x000001fe), LL(0xc6717776,0xfb840953),LL(0xe6943ee3,0x6c82ee1f),LL(0x45986586,0xa8804763),LL(0xb2c01a1d,0xd2e62027),LL(0x81dd9ed1,0x7ac9ecf9),LL(0xa86a93b5,0xea3ed52c),LL(0xab42d43a,0x9783c732),LL(0x4badd572,0xf7f2c527),L_(0x000000f1), + LL(0x4e7db852,0x1ee36133),LL(0x5d2ce89b,0x7925fde7),LL(0x344442cb,0x7be13983),LL(0x933fd989,0xf818aa84),LL(0x868cf674,0xcf763eff),LL(0x970119fa,0x1161eea1),LL(0x91b1cf2b,0xf803b198),LL(0x47f45bbc,0x358bf9d3),L_(0x0000004a), LL(0x2871ba24,0x03c6e820),LL(0x946bbdda,0x1e7f5b10),LL(0x6d786c0b,0x901e63e0),LL(0xf905444d,0x61291f2a),LL(0xa07d991d,0x26f8514d),LL(0x5dd4a768,0x8caa8bed),LL(0xba23453d,0x625c627a),LL(0x55ae73dc,0x566ebb14),L_(0x00000172), + LL(0x7616ee6c,0x76716c8f),LL(0x9e16dd77,0xd9dc6964),LL(0x424e43ef,0x4f1ab6f7),LL(0x3307372b,0x853acdd0),LL(0xb131b10b,0xd0481561),LL(0x6c779030,0x8833d896),LL(0xb43c81fb,0xf49c69e7),LL(0x013b71e6,0x2d5044d9),L_(0x00000171), LL(0xf6938c6c,0xcb8f8364),LL(0x7d7772d3,0xb55fa4df),LL(0x5c5bb6fc,0xe309036f),LL(0x87518233,0x00458dd9),LL(0x5ae0cb46,0xab6a628e),LL(0x80a93940,0xd00141d6),LL(0xe42dc460,0xe62c337f),LL(0xf594561c,0x32989bd5),L_(0x00000113), + LL(0xe8ff16d6,0xd0f00eb5),LL(0x060c9ece,0x76dc2763),LL(0x8d24bcf1,0xe04a4e63),LL(0x8049d5a2,0x1f378724),LL(0xad86dce1,0xee568d6b),LL(0xbd4ecf75,0x064ed8ea),LL(0x23b4afb4,0x3066bb9b),LL(0xe8ba5019,0x59524e62),L_(0x00000113), LL(0x16a5e07c,0x0317cfe4),LL(0xb05c4eb0,0xe263fd3a),LL(0x87619f5b,0xe43b9d32),LL(0x04548fa9,0x5fe60636),LL(0x1e3bb4ee,0x177080d6),LL(0x80dd88dd,0x6b920ffa),LL(0x50a4adb9,0x6cf839eb),LL(0x579a402c,0xbaad4226),L_(0x0000016a), + LL(0xd3860f86,0x51b92975),LL(0xd751ffa4,0xe9c89ace),LL(0x0fff3b8f,0x22e82df0),LL(0x44ceed1d,0x9ef4bd4d),LL(0x322e7d38,0xec43e5b6),LL(0x5dafe91d,0x3ac6cd72),LL(0x385f22e0,0xc23c7139),LL(0xecc87ca1,0x8c786dee),L_(0x00000186), LL(0xd6515802,0xfbf97dbf),LL(0x72372941,0x689ac9e8),LL(0x4611974e,0xce7740f8),LL(0xe04ba0c6,0x7a8f9746),LL(0x7419caa0,0x05b0cdaf),LL(0x30755659,0xcd257003),LL(0x5af7e403,0x8e3b2c01),LL(0x7d54b47d,0xc1f90328),L_(0x00000043), +}, +/* digit=51 base_pwr=2^255 */ +{ + LL(0x06aeb844,0x171b7252),LL(0x2f67f278,0x3ef95a8f),LL(0x411d7c3d,0x1341fdfb),LL(0xbc9db5d5,0x9c831f2c),LL(0x64cd3d49,0x5fa0db40),LL(0xb8bb90a7,0x2c8d72cf),LL(0x050fdef7,0x9770a986),LL(0x584d26e8,0xcb48ff2a),L_(0x000001c1), LL(0x8a357b6c,0x75fe114c),LL(0xe1fc26b3,0xaa2296d0),LL(0xe2fe623c,0xe037cba1),LL(0xca73315c,0x36843eb8),LL(0xb7e86db2,0xb5b70ddf),LL(0x4b155e04,0x20198f9d),LL(0x06921394,0x51535cfa),LL(0xaa06d437,0x98bee5a2),L_(0x000001b1), + LL(0x89cc4566,0x68f57feb),LL(0xa2543b28,0x4bd3cbd6),LL(0x0bf63c0e,0x66da5e56),LL(0x648f4a56,0xb7d9cc0e),LL(0x7591427c,0xab848b1a),LL(0xe85c5977,0xf4656829),LL(0x4025667a,0xcdae8f7a),LL(0xab876527,0x93eb73b4),L_(0x00000077), LL(0x204ed818,0x30db96c4),LL(0x1b3e5e48,0x26c352dd),LL(0x497308c9,0x54703369),LL(0x3370174e,0xa9534502),LL(0x7c6d8497,0xae86058c),LL(0xae7aecbf,0xa32e4cdc),LL(0x67daf0b8,0x3a4e9eb5),LL(0xaf8dd7df,0xff79b85e),L_(0x00000081), + LL(0x5b9e36c3,0xe50c2a6e),LL(0x316c41f6,0x6af25999),LL(0xe48ac795,0x813a1e7e),LL(0x65d44dd3,0x7fc2f7f1),LL(0x4d3b130b,0x08cc4038),LL(0x7c00e333,0x4484ccd4),LL(0x8e7636fc,0xf9a80322),LL(0x1688e5f3,0xb4b52a8f),L_(0x000000e2), LL(0x0987f80d,0x2cd48e4d),LL(0x9fe4562b,0xaa48e7e6),LL(0xf168a311,0x7fdc1a14),LL(0xdf4018fc,0xc463e403),LL(0x6c8979b5,0xd6d0bb4b),LL(0x62cddf39,0xdf09f24f),LL(0x9b318fce,0xca7e6578),LL(0xcab54343,0x48ea638d),L_(0x0000000a), + LL(0xd7deae24,0xcb23734e),LL(0x23939762,0x66bcd84d),LL(0x989a46bd,0x85ec037c),LL(0x65439883,0xcc808ec0),LL(0xa3f08c8a,0x680dc66c),LL(0xa76800e7,0x4c3c5332),LL(0xcc98ee9e,0x8663204a),LL(0xa0ef46de,0xa2348db0),L_(0x000001ce), LL(0x05b4a4e2,0xb14e22b3),LL(0x930a37ee,0xe9d3141e),LL(0x35f5cd09,0x3364f154),LL(0xf55ccf3f,0x55f31352),LL(0xf6c93770,0x0c74549e),LL(0x4bf80f61,0x8d0207da),LL(0xb1c2b15c,0xafb6ee97),LL(0x0992fd2c,0xfe513092),L_(0x000000ff), + LL(0xea69c80c,0xc95caa93),LL(0xdeca4025,0x95bc2026),LL(0xc8c86ea9,0xe3161b91),LL(0x73fc72d8,0x46b441b7),LL(0x033e25a4,0x6b7c1805),LL(0x2d4e9335,0x5a4b1a06),LL(0xd30b7dc3,0x992637db),LL(0xdaac9a90,0x7c72add5),L_(0x00000146), LL(0x4f4c9063,0xc14619bd),LL(0xfbc662e7,0x3c65896e),LL(0x8176a953,0x1c5790f3),LL(0x4f51c6bd,0x0ef460cd),LL(0xc6fa754c,0xee3cd226),LL(0x5e872735,0x05291b65),LL(0x79e3b5c0,0x734e1b22),LL(0xfa256432,0xf18b1394),L_(0x000000cf), + LL(0x0643f252,0xedb2cca1),LL(0x00e32811,0xc996f279),LL(0x6f6af92c,0xbf992edb),LL(0xbdef8275,0x3384462d),LL(0xa4dd3d26,0x818a7ff9),LL(0x8e214401,0x60e7694d),LL(0xa7aec62d,0x9d54e87f),LL(0x8bdd2244,0x5d769f98),L_(0x000000ba), LL(0xfb63c9fb,0x7e7ff11a),LL(0x7eec026d,0xc6b3e18f),LL(0xe08b80f1,0x84b5c983),LL(0x5d6b5a4c,0x4b0fd4b7),LL(0x85f99e3a,0xfc4904ce),LL(0x7afd5a7c,0xc336a99a),LL(0xba1e62f6,0x24e4a736),LL(0xbe20ba29,0xcceea595),L_(0x000001c9), + LL(0xbb592469,0x29ecccb0),LL(0x89ef0925,0xce6e29e1),LL(0xf98f60f1,0x36216c3c),LL(0x0848c8bd,0x63a73874),LL(0x085409b9,0xd4abc07d),LL(0x2319eb0d,0x0e39c02a),LL(0x6bda97a9,0x393de5dc),LL(0x0140ddd0,0x5302f915),L_(0x00000104), LL(0xa2f22a24,0x54381101),LL(0x423788d2,0xb694bdb7),LL(0xc151a89e,0xd0ef2b67),LL(0xb01ee242,0x01c2b082),LL(0xc07af292,0x10fd1158),LL(0x3639401a,0x8e3f86e2),LL(0x1ed8f101,0xcf21ea60),LL(0x83b3b62f,0x186fd3fb),L_(0x000000d5), + LL(0x718c92f0,0x3423f6e8),LL(0xdae8d246,0x5f129e35),LL(0xaeff7db0,0xdbad59f4),LL(0x963932f5,0x3cf82c0c),LL(0xf5e468db,0x6b7d10e1),LL(0x10e6e23c,0x6e085959),LL(0xc76fb1b0,0x538880e8),LL(0xe8c12594,0xf8f02134),L_(0x00000021), LL(0x89506649,0x272ea4f0),LL(0x9dd1a14c,0xaa274066),LL(0xa6cc0d62,0x191622f8),LL(0x92244f6f,0xd28338e3),LL(0xc3dcbd9d,0xa8dd7166),LL(0xa39c0c61,0x4930a90c),LL(0xb979b8ce,0x6cd41296),LL(0xaa5c88b7,0xf6ce2037),L_(0x000001b0), + LL(0x8ef889ab,0x6a8258a9),LL(0x87f34cfa,0x6e977272),LL(0x538468d6,0x198bf996),LL(0xe9cb2903,0xea7ac40d),LL(0x389f9bff,0x50fd922d),LL(0x88f4717c,0xcb0c2bca),LL(0xb57f0298,0x5d670088),LL(0x812c3767,0x7a4062fa),L_(0x000001d3), LL(0xd95da33d,0x89860058),LL(0x74f4e9a6,0x9df658db),LL(0x46a06ddb,0x8faf5c15),LL(0x36b96ffe,0xe9bbc867),LL(0x1a07dce2,0x19a59e1c),LL(0x9536a09f,0x1683c160),LL(0x7fabb0f1,0x183d2bdd),LL(0x06b7a416,0x75975bd0),L_(0x0000015b), + LL(0x5451d16f,0x720fff5e),LL(0xeacd93fd,0x6c62e42c),LL(0x6f74fc83,0xff9b7285),LL(0x8a51db93,0x7b6bb42b),LL(0x66ca983e,0x8fd893a3),LL(0x08eee06f,0x491c6c89),LL(0xe1230942,0x638e9f64),LL(0x4984e580,0x9b2ab576),L_(0x00000063), LL(0x0bad9aba,0x7b9d835c),LL(0x84846555,0x89b78779),LL(0xc6bb325d,0x88fce8c3),LL(0x0fb571c3,0x237c5f2e),LL(0x27185f17,0x37bcf483),LL(0x53b0ac57,0xf037df6f),LL(0x34a972e5,0x73b6f7ae),LL(0xf685c7b2,0x3e68f821),L_(0x0000012f), + LL(0xfab07625,0x52bebe14),LL(0xd1fbd06a,0x7d25c686),LL(0xe5149dc2,0x20b2f012),LL(0x6707c1b6,0xe4fdb06a),LL(0x5cf7e0a4,0x124b0592),LL(0xdadcb97c,0x9ef54e16),LL(0x97f26141,0x6b91bf50),LL(0x689c475b,0xf26ed365),L_(0x0000001c), LL(0x31ac5e9e,0x95772aee),LL(0xf333125d,0xfb3bbb8c),LL(0x906a459b,0xda033a3e),LL(0xd9a3800f,0x7aebdf94),LL(0xea08c76a,0x4600cde7),LL(0xecd96496,0x1b4f8404),LL(0xb9fdf8c7,0x58389c23),LL(0xd186fc48,0x9a44e137),L_(0x00000045), + LL(0xace5575b,0xabf66053),LL(0x6dc5328e,0x54861cbd),LL(0xea9fdaff,0x8555b123),LL(0x0ecf823c,0x09e411c0),LL(0xa5d8934d,0x0ae97a01),LL(0x170ceb09,0x91dabc9c),LL(0x73c40a75,0xd8f751f2),LL(0x52861011,0xba95af0f),L_(0x00000181), LL(0x352bc9a3,0x79de4fde),LL(0xf0130bb7,0x2eb1b199),LL(0x3c4457b6,0xa95e2900),LL(0xf04878d3,0xc1a9dc9f),LL(0xe04ebfee,0x097a6545),LL(0xf5aa7d0d,0x673c7b41),LL(0x3c5c4ce8,0xa67894e6),LL(0x385d1700,0xeb9b105b),L_(0x00000060), + LL(0x16680fb2,0x370df675),LL(0xbeb0847a,0xbefb427d),LL(0xbbe54c19,0x9a4770e1),LL(0x44a1916f,0x7f5945d3),LL(0xc14ef507,0x731b2da3),LL(0x17aa92af,0x07208217),LL(0xf69f649d,0xa27c5c7b),LL(0xabd89463,0xc25bbff1),L_(0x000001e6), LL(0xe551752e,0x9733c080),LL(0x98e86236,0xc5bfef7f),LL(0x936a2ebe,0xcc36a721),LL(0x25c227b9,0x11dd6248),LL(0xf8d96ae8,0x83440604),LL(0x3b2dca5f,0xc74d7e75),LL(0x3d8a998d,0x3c210303),LL(0xdcf4cf75,0x2fdbfd9c),L_(0x000000d1), + LL(0xe646d7ef,0x2f349cfb),LL(0xfd187fbb,0x22f14a9c),LL(0x7fb5a2ff,0x781ef46f),LL(0x084df701,0xada115d8),LL(0xab2e7da6,0x37b36285),LL(0x21432735,0x779e5cbe),LL(0x42159b5d,0x987b1bb3),LL(0x182d17ef,0xbd5c0321),L_(0x00000197), LL(0x0c974b93,0x3e904667),LL(0x4f31ca20,0xc9fa51be),LL(0xed87df23,0x5530167f),LL(0x7ab1aee3,0x34d6716d),LL(0x16c8a7b3,0xb3f82160),LL(0xf3eb37b8,0x77ee013d),LL(0x13ff1326,0xa57a3a10),LL(0xd7d1a2e9,0xab837a7e),L_(0x0000012b), + LL(0xfafe3733,0xb917d893),LL(0x17024a0a,0xfd27b406),LL(0x89eda4ec,0xcd3182c3),LL(0x4e2244fc,0xcec915fc),LL(0x083e32ec,0xbc2fe85f),LL(0x26668631,0x3458ec27),LL(0x23dec845,0x2e647e96),LL(0x35986103,0x80f7dfe3),L_(0x000000af), LL(0x9c1dd0c7,0xc0f6c814),LL(0xdb6594dc,0x59eee455),LL(0x2db7ed2b,0xc7b946f5),LL(0xc94ac2ca,0x45521872),LL(0x1f918bfa,0xe23366a4),LL(0x3439b349,0x50d8220c),LL(0x347cd4a8,0xc2e30ec6),LL(0x9274e0c9,0x10e0889c),L_(0x0000004d), + LL(0x18b3fd00,0x605cfac8),LL(0x11efdfd4,0x85d2f0b8),LL(0x5bb41efb,0xee216714),LL(0x3c03cac7,0xade36a6e),LL(0x485c4b2d,0xcd3725a1),LL(0x50bc220d,0x2cf525a5),LL(0xb11c84f3,0xe314db66),LL(0x664e47ac,0x0c8cd013),L_(0x00000050), LL(0xa7a48858,0x6f7bbfd1),LL(0x7d04c227,0xe24ada56),LL(0xadced466,0x03a6a941),LL(0x70addbb1,0xf14e02c2),LL(0xc761ca82,0x94b62798),LL(0x03264d07,0xa0bec3f9),LL(0x966e8d47,0xe6caf618),LL(0x1f211c02,0xa8c9821a),L_(0x000001cf), +}, +/* digit=52 base_pwr=2^260 */ +{ + LL(0x26c24408,0x1e48c2aa),LL(0x2fb6cd86,0x8746f93b),LL(0x515690c4,0x71e5f018),LL(0x76a3c1b7,0x99fbb28d),LL(0x993035c8,0xc338e004),LL(0xa3d8d18a,0xb4e7f02f),LL(0x804c0351,0x09fabf9b),LL(0x3e6175e3,0x697832f8),L_(0x0000016b), LL(0xf6830680,0xc1a8a622),LL(0x50d94962,0xf94a3f34),LL(0x0a44d62d,0x8057a83e),LL(0x05319e21,0xd2bed201),LL(0x3a4a1ebd,0x3d6076c1),LL(0x7368f486,0x4672ca13),LL(0xef4b1a43,0xf96135e4),LL(0x6692537f,0xb40a920b),L_(0x00000090), + LL(0xb81b7a5e,0xb048815a),LL(0x11e1229e,0x2e0a161f),LL(0xecb84207,0xf8e1801b),LL(0x5b394a58,0x890edfad),LL(0x37512807,0xb3e4e477),LL(0x5d81f675,0xc9984105),LL(0x1050ce18,0xf43ed35c),LL(0x17bd56ac,0xfc61c6c2),L_(0x00000011), LL(0xcf0d6c8c,0xaf53db5d),LL(0x6ee72ddb,0xc6ab4e4f),LL(0x32c8481a,0x1b4e6860),LL(0x5c545af6,0x0e7c0e41),LL(0xc3595ad6,0x261ffe75),LL(0xbf47f59b,0xf66fa7cf),LL(0xfa1aaf6c,0x212e7097),LL(0x86b7977f,0x3c00aa83),L_(0x000000b4), + LL(0x4b0029a7,0xf5c33307),LL(0x1eec5f29,0x9e45f3bb),LL(0xf8396133,0x17635aad),LL(0x25d3e2a3,0xbdaba508),LL(0xc34ef799,0x574f4d09),LL(0x78d47f38,0x085e8086),LL(0x3db03879,0x1c4a5748),LL(0x65ae9f6d,0x3c8df544),L_(0x000000c3), LL(0xb52fb74f,0xb901e46e),LL(0x1868eef4,0x68ec4a86),LL(0x7bab1199,0x9f2f51a0),LL(0x8f19df10,0x6a75a074),LL(0x2d75da4f,0x61385965),LL(0x59f7f255,0x60c80677),LL(0x6b7b569e,0x40b66382),LL(0x0533f4d4,0xd7897f45),L_(0x00000195), + LL(0x3b8e6670,0xd20de07d),LL(0x7aafab5a,0xdab27e9b),LL(0x3fb66eb5,0x5ac52dbe),LL(0x7ce85634,0xdf84c8cf),LL(0x9025496c,0x95b8e1e2),LL(0x776182f0,0x8e6db4cd),LL(0x21aaa54e,0x3bb0faa3),LL(0xe73fef00,0x9223c88a),L_(0x00000098), LL(0x16d643fd,0x70e138d6),LL(0x5612fc48,0x69ca59b8),LL(0x0889a9e6,0xfb3a26a0),LL(0x93e3dad6,0x43df1bc0),LL(0xe6ce66bb,0xae036271),LL(0xfcd4244d,0x05182a82),LL(0x958ca2ac,0x102559d8),LL(0x26838c85,0x588a9a75),L_(0x0000009f), + LL(0x0184b954,0x6cd88b38),LL(0xdcf3ba77,0x70c99422),LL(0x86f66f43,0xbc4bd450),LL(0x7b81c0e8,0x93575c5f),LL(0x704cad24,0x4091825d),LL(0x4b9f70ce,0xf1ff4bbf),LL(0xac2a0a24,0xb5d28bd9),LL(0xe5ebf7a3,0x5e706c23),L_(0x00000198), LL(0xeb270e7e,0xeb783548),LL(0xfd0b1050,0x81562bc5),LL(0x96b8a59a,0xedb5f688),LL(0xbc130375,0x8ab1fc73),LL(0xa1c5bd93,0x89b28fea),LL(0x7f18c19c,0x8d6e4b1c),LL(0xe98a494f,0x409f7384),LL(0x55131bf6,0xf382aa3f),L_(0x0000017b), + LL(0x25a27923,0xffb6351b),LL(0xc9bc2f04,0x7f29f1e1),LL(0x91e80528,0x37069b7d),LL(0x8a56cb26,0xff75d6d4),LL(0x7d9a9a20,0x3f52dd39),LL(0x52270b39,0x703dee3c),LL(0x67288a63,0x13f9c1c2),LL(0x49651d47,0x663b9838),L_(0x000001b2), LL(0x1cd56c85,0xbc1a8d52),LL(0x46598a93,0x87351736),LL(0x4685de4b,0x418967ee),LL(0xf35701ef,0x6dbbce4c),LL(0x380b116b,0xc5acf7cf),LL(0x35416b03,0xe839b424),LL(0x8d1a9cff,0x15841fbd),LL(0xe1730d1f,0x5ba5c3a6),L_(0x00000078), + LL(0xc0fdbea9,0xf76bf65a),LL(0xf573be01,0x0c6778ad),LL(0xffd85a6f,0x927d0f51),LL(0xfe98c72d,0x1738874a),LL(0x187e8ec8,0x032ae57d),LL(0x00c6d76d,0xdf95e888),LL(0xdee55d14,0x0dec4042),LL(0xcd5760c3,0xb172c8e8),L_(0x00000132), LL(0x14eac108,0x7bdb463a),LL(0xcbf771c3,0x76281603),LL(0xd48543b5,0xfc634037),LL(0xb965ac3e,0x6e5426f3),LL(0x49a7be5b,0x87fba366),LL(0x2e203d0f,0xddb5ca9f),LL(0xabbc3174,0x55052649),LL(0x2eb60836,0x21e004b7),L_(0x00000098), + LL(0x5c1bc4f6,0x64a43b5d),LL(0x1c634029,0x5d7c2617),LL(0x93c0fb82,0x1b7967cc),LL(0x96145dca,0xd068364b),LL(0x3b5c4ddf,0xec5bd3c7),LL(0xd5007f0e,0x2d7bf8f0),LL(0x771d6fd8,0x215b93c7),LL(0xf222990f,0x70529475),L_(0x00000028), LL(0x1d26e01b,0x340c9a0a),LL(0x04b5b926,0x7edb2bec),LL(0x0417ca25,0xefd5d17d),LL(0xb41c7280,0x70df3372),LL(0x93c942f6,0xfbfcef99),LL(0x7e3d7910,0x37ef3a57),LL(0x39005c54,0x8c4d4c90),LL(0xdb0ceb3a,0x446ceedd),L_(0x0000008e), + LL(0x65b80a9e,0xb3de9aec),LL(0x47955751,0xebd70107),LL(0xb9795325,0x326b6e2a),LL(0xb7ebfc01,0xb10f9b62),LL(0x6ec48711,0x145049a1),LL(0xb7dced78,0xd8c85f83),LL(0x6736770f,0xf3878209),LL(0x41fd70b3,0x4d4517ea),L_(0x000000ec), LL(0x1245bc60,0x228424d3),LL(0x6d611151,0xee80416f),LL(0x92f6a019,0x18ef86e2),LL(0x2e88fbc7,0x9f5d9f5c),LL(0xb51a1205,0x3ee14394),LL(0xd989aea0,0xe73a0ff8),LL(0x81623fdf,0x10ed321a),LL(0x3d71a6e8,0xa6b2f1dd),L_(0x0000018b), + LL(0x98f6bd7a,0xef684d8d),LL(0xaac1e35c,0x1c71e036),LL(0x19611929,0x9428ed8d),LL(0x24f7251a,0xf90f6e8a),LL(0xcd34ddd1,0x9742ae40),LL(0xf7d22290,0x9b5b15a7),LL(0x5d805418,0x91f1f6ec),LL(0xe50e28f5,0x604d11c6),L_(0x000001d0), LL(0x2c60d848,0x5ad92240),LL(0xf18911d8,0xcfb4c90b),LL(0x3c5b71d6,0x1a2c26ff),LL(0x5d53d732,0x9fada03e),LL(0x8bfbe9ec,0xd69c81a8),LL(0x443458b3,0xce7f11ce),LL(0xca59b490,0x2489ddd2),LL(0xdaf9ecde,0xceb4c71d),L_(0x000001b3), + LL(0xd052454d,0x6844d9d2),LL(0x667d1be2,0xec3032ef),LL(0xefd476cd,0x67f7c660),LL(0x47628345,0x80c64c50),LL(0x57751538,0xbb8da5d7),LL(0xb8ef3bee,0xb395bca7),LL(0x3bc2ad45,0xc2e7e012),LL(0x610d67aa,0x9e6187ca),L_(0x000000eb), LL(0x3dc2b1ef,0xf5d2b364),LL(0x4ee3fb91,0x38966853),LL(0xe0446916,0xc5fb0623),LL(0x2a6bfc98,0x6bce11c9),LL(0x65c6b297,0xeb6233b0),LL(0xce8c355a,0x6ac473c3),LL(0xd97c1dd8,0x56091541),LL(0x0514bb6d,0x01792023),L_(0x00000043), + LL(0x92033f14,0x17a6ef25),LL(0x89a53d65,0xaa5a50af),LL(0xd872b73d,0xa475ab82),LL(0x53f65ce3,0xe34acbbd),LL(0x1d33affd,0x33a80ee5),LL(0xe7690066,0x969e21f0),LL(0xcc415a0a,0xca2e0920),LL(0xb0325f4a,0x901c4d50),L_(0x00000172), LL(0x0f43e61e,0x40fc3a90),LL(0xa48abf41,0x601d8bcd),LL(0xe374c532,0x786a5e70),LL(0x7446fbbf,0x484d4fec),LL(0x0ec5b3b2,0xdc5db3b9),LL(0xeeb6c43c,0xe60cf40d),LL(0xca2ac048,0x1ff63739),LL(0x4475d66f,0xea8de3b9),L_(0x00000143), + LL(0x9adfc451,0xe4847519),LL(0x294337f9,0xbe446976),LL(0x4e7dac1b,0xf00a5441),LL(0x94ab8aec,0xc582caec),LL(0x5ac9bb3b,0xeacdc76b),LL(0x3fe0e66a,0x6e00689b),LL(0x246c86c1,0x6c266a0e),LL(0xbf0ade72,0xa0a2515c),L_(0x00000043), LL(0x70658a73,0xff30554a),LL(0xc9871f1a,0x4b2448f2),LL(0x8dd50a2b,0x87a01756),LL(0x3ea8f62c,0xb6b9a2ea),LL(0x7311e04c,0x0d165122),LL(0xfc6c9f2d,0xb7efc2eb),LL(0x07406007,0x92c33ebb),LL(0xbd8e5282,0xd904c21b),L_(0x000001cf), + LL(0xe495d18f,0x9b0f5222),LL(0xac5ca929,0x126086f0),LL(0xf4d4507f,0x41908fc8),LL(0x3355d26d,0x65791c82),LL(0x31183a9c,0xf00a9e80),LL(0x018f0189,0x644ffd95),LL(0xe447af71,0xbffa0975),LL(0x7424f93b,0x849e9345),L_(0x000001b3), LL(0x0d6949a4,0x78519510),LL(0xb79c2b5f,0xa59828a5),LL(0x9ae92003,0x6c54e38e),LL(0xfb93be38,0x67bd521a),LL(0x4c71aeb4,0x04b0340d),LL(0xa3451e4d,0xcd2e92f4),LL(0xa9a77ad0,0xfe218b65),LL(0x656db073,0xd2b4300f),L_(0x000001f4), + LL(0xa3b27cf0,0x160f039b),LL(0x82ec5f83,0xcff71736),LL(0xba9364b6,0xebc485a6),LL(0xddbcec8c,0xdc80329f),LL(0x3bda1715,0xcc71e664),LL(0x46fc4c3b,0x592819ef),LL(0xd1da3eb7,0x2cb62fe8),LL(0xb29cfca6,0xc417d055),L_(0x00000061), LL(0x8c802541,0xfc158c58),LL(0xe84b30eb,0xf6625ae1),LL(0xd137d022,0x441de79b),LL(0x42e42c6f,0x7d99126c),LL(0xf2ec0ec8,0xfbbd41bb),LL(0xb8f928d4,0x2851ec63),LL(0xf3ff5c1d,0x5e5a9ca7),LL(0xd3429e7d,0xdfb3e4f5),L_(0x000000ac), + LL(0x56a3a063,0x8d143249),LL(0x627718f3,0x2232fc35),LL(0x5a0479ef,0x6a6d389e),LL(0x82744b80,0xf4d435b8),LL(0xb0bd687a,0x2792b960),LL(0x4cecd317,0xf792e60e),LL(0x063be911,0xb09dcb17),LL(0x02f6ffb4,0x79c0ec59),L_(0x00000094), LL(0xb04fbf6f,0xe7c66f8f),LL(0x07b90918,0x95b38bbb),LL(0x01c5b207,0xc67022d2),LL(0x4fdf3937,0xee01b834),LL(0xe5a11142,0xc7b97506),LL(0x11b8cb5f,0x2ae40433),LL(0x2450b7bc,0xe3e1937f),LL(0xa26a70cf,0xb747b45f),L_(0x00000042), +}, +/* digit=53 base_pwr=2^265 */ +{ + LL(0xf2fdc439,0x7edbcb88),LL(0xdb91292b,0x19d35421),LL(0xd5dee79a,0xa420a538),LL(0x035e9ea2,0x9cf14f3b),LL(0xe21709fe,0x49703f94),LL(0x690ca5b7,0x495b47e8),LL(0x4deb7af2,0xcc2ef057),LL(0xb09d6324,0xf4a72dd4),L_(0x000000d7), LL(0x7ff7df3b,0x25c764e6),LL(0x1593ef9e,0xb9153d85),LL(0xef6d9489,0x117822d7),LL(0x238e5449,0x1e34e4c9),LL(0xbbd3333b,0x58cc8198),LL(0x416c6cfb,0x7b487650),LL(0xa8085b4b,0xb3068c07),LL(0x5e20cc8e,0xcdc16b7b),L_(0x0000013f), + LL(0xf98b837d,0xe15922b2),LL(0x62c29919,0xc8afde9c),LL(0x95a1a3c5,0xffe9534c),LL(0x604b1043,0xfa2f638f),LL(0x27a01a13,0x04cd8a8d),LL(0x2660393b,0xe26fd0c2),LL(0x72545d96,0xcf0808a0),LL(0x1dd10699,0xded0e387),L_(0x00000097), LL(0x037dfe3a,0xc38223ef),LL(0xd36e2094,0xe8b66c87),LL(0xe28405ae,0xe3e2766e),LL(0xa065b535,0xed4b87f0),LL(0x084a317d,0x3f53ac0b),LL(0x0ca5866d,0xa0ee5586),LL(0x82b21bd7,0x1fa70803),LL(0xff1d58cf,0x4ad6e2f3),L_(0x0000009d), + LL(0x905b2c93,0xef13c9b6),LL(0xd34ff12d,0xa5eaf60e),LL(0x46115d13,0xad4eed45),LL(0xc0704820,0x0761b0ac),LL(0xf0c499c6,0x5dd51e45),LL(0x4abd13af,0xa978e552),LL(0xb1ec09b7,0xa79f811d),LL(0x0dab7d3a,0x34d1f590),L_(0x00000147), LL(0xa75f21e6,0xea3d3b19),LL(0x0364a9c0,0x68df5edf),LL(0x5e1d6b4a,0xb44c93c9),LL(0x33e2dcc0,0x07832283),LL(0xea8fc7be,0x37cb9512),LL(0xe9e13504,0xc965c20f),LL(0x887068c5,0x62d3176a),LL(0xe870a541,0x0903d004),L_(0x00000092), + LL(0xf1dd3a67,0x7824703a),LL(0xb39c772c,0xbf0c69c5),LL(0x46f942bc,0x31d0901a),LL(0x9e0174be,0xd38bdff8),LL(0xab6326f7,0x91bfcc1e),LL(0x8787eadb,0x541868bb),LL(0xa0385662,0x6ba48a8b),LL(0x6d878761,0x3094b460),L_(0x00000185), LL(0x69e290f5,0x1d33d545),LL(0x1ba52eb4,0x662b634f),LL(0x9dfd1d1b,0x876fc504),LL(0xbe51c909,0x93e42059),LL(0xcb7406ba,0x49355b9d),LL(0x2651475a,0x8963ea18),LL(0xbcf76704,0x08985cee),LL(0xaa85c805,0xf1d1062e),L_(0x000001ab), + LL(0x6c2616bb,0xeb31ab0e),LL(0x01e38aad,0xbcd43f2e),LL(0xda068909,0x7f990c18),LL(0x9fb2c072,0xa82ff220),LL(0x757bff88,0x81327a89),LL(0x28c2afd8,0x1d3a1126),LL(0x0c2079b4,0x95685773),LL(0xa957db38,0xe18a18bb),L_(0x00000058), LL(0x45f5c72a,0x53fe6703),LL(0x42ce353e,0xbe22096d),LL(0x4a3251c0,0x601d33ed),LL(0xaaaf17c5,0xfe2c8cbc),LL(0x3d4b4185,0x242a9581),LL(0xb32328dc,0xbc79d78a),LL(0x03bf4442,0xa103c8f5),LL(0x64e28853,0xf9b6130c),L_(0x00000094), + LL(0xb447a9f7,0x2f9482b0),LL(0x31ede472,0xc7c55120),LL(0x00d8bc4d,0x627457bc),LL(0x5c471ca7,0x4a9f36d6),LL(0x14a28cac,0x436c70c1),LL(0x38a173b4,0x011c4897),LL(0x96f4df0f,0xdde3c9d7),LL(0x587a661d,0x8ddb7793),L_(0x00000026), LL(0x143023ce,0xbe0156de),LL(0x68012aa1,0xeabfa04c),LL(0x3ed6803f,0x204765fc),LL(0x762dc13e,0x2e5fcd9a),LL(0x5b5cd65c,0x04a542e1),LL(0xd6b6a2d7,0x3dcadeb8),LL(0x57f74a74,0x0da1060f),LL(0xe953f87b,0x2e478948),L_(0x000000e2), + LL(0x326c0546,0x63e8f854),LL(0x35eb9eac,0x39f46433),LL(0xf4944efa,0xc8688704),LL(0x91ff1606,0xfeaa7186),LL(0x99316708,0xa92605cc),LL(0x3fbb0f25,0x2252affe),LL(0xa90598c4,0xcbb64aaa),LL(0xb34934f1,0x3ba7e244),L_(0x000001f6), LL(0x763915ed,0xc814b6b0),LL(0xe697e570,0x69866f7d),LL(0x63fc73af,0xb1f0f7a2),LL(0xb634f283,0x17533e2f),LL(0x423d910b,0xe17bdbad),LL(0xfbcd888f,0x778dac12),LL(0x4c46f8f4,0xfb0bef09),LL(0x72d4d626,0x4fcdf97f),L_(0x000000b1), + LL(0x13b5648e,0x34c2f6e4),LL(0x202b7ba7,0x8535398b),LL(0xebd7f177,0x7eea8b23),LL(0xd3b0fc5e,0xc7a0f19f),LL(0xa3df55dd,0x577641e2),LL(0xcb9f261d,0xf496646e),LL(0x112454e8,0xdaf2be9c),LL(0xc23da6a9,0x64522e02),L_(0x0000003d), LL(0xe59d35c5,0x1efd66d8),LL(0x1b401767,0x904f29b9),LL(0x084f27ae,0x129c352b),LL(0x23e88566,0xa3263601),LL(0xd229faae,0xc04620cf),LL(0xc91c87f4,0x535f695e),LL(0x27c58545,0x3cfc2a21),LL(0xc94873fa,0xdacf3fa1),L_(0x0000005f), + LL(0xb13cb473,0x88b9f2da),LL(0x2dda613b,0x3a43eba4),LL(0xedbf11f5,0x9cddb3f6),LL(0xdf7a9b8a,0x1e00c8ae),LL(0x7e0c7ceb,0x84c5eb6c),LL(0x03d1dbf7,0xc6747572),LL(0x80122fe1,0x5d6814d2),LL(0x639c5254,0x1d4a0602),L_(0x000001bc), LL(0xec1fdac5,0xa4651a82),LL(0x690ed4f8,0x4ef3c551),LL(0xe2f0cf8b,0x20e94507),LL(0x61b6144a,0xeb258124),LL(0x11bde361,0x51d9d605),LL(0x541da730,0x397e8ce6),LL(0x06c00c29,0xb4a5d672),LL(0x43c098bc,0x76423a86),L_(0x000001bc), + LL(0xf6656606,0x82cb8136),LL(0xd96edef6,0x84c50ccd),LL(0x9f0978ff,0x37e0a146),LL(0x17bb0d3a,0xbf780900),LL(0xb2dca4ae,0x1d528632),LL(0xb6bd3e16,0x1bee4b87),LL(0x8c609327,0x16432d3a),LL(0x4aa7829a,0x9ea4ecd7),L_(0x00000068), LL(0x3f9c377c,0x5046622f),LL(0xa18dda52,0xd98abc09),LL(0x722fdd39,0x23fb42b0),LL(0xa78f3825,0xf2a75675),LL(0x13487db2,0x33200560),LL(0x244aa1c4,0xc0bf37b5),LL(0x86de25a6,0x57b73e86),LL(0x079d95dd,0xb0aa0cbc),L_(0x00000013), + LL(0x17341b4f,0x1e7f52de),LL(0x52ebce6c,0x882af4b0),LL(0x673d8b9f,0xbbd95fb1),LL(0xd64ea8ef,0x28e628db),LL(0x7889079e,0x54b7908d),LL(0x26e0abe9,0x3df2e6e8),LL(0xc20813db,0xfde7f3a9),LL(0x978bffe2,0x4f06b898),L_(0x00000019), LL(0xead10e9e,0xad34ad6f),LL(0x1076d303,0x8df8f495),LL(0x8819ee4a,0xc0d57db8),LL(0x70fb03b5,0xb14472ea),LL(0xbc0a100a,0x18cc104f),LL(0x7fbf87ac,0x45839e8e),LL(0x64d66536,0x58fe7198),LL(0x5bfbac43,0x04ede156),L_(0x00000050), + LL(0x1836614b,0xcb97f199),LL(0xc897ce78,0x6d967571),LL(0x940b810e,0xd145156b),LL(0x850c5939,0x4b73e9e6),LL(0x04a9944a,0x6e833bad),LL(0x2f7df8e9,0x2cd53823),LL(0x3b222e7b,0xf7a26c91),LL(0x1034f78b,0xb14d3854),L_(0x00000027), LL(0xfe320dfb,0x5c8c95a5),LL(0xcb9240ce,0xfffec63d),LL(0xc515192c,0x000718b0),LL(0x4259ce4f,0xdbfc0155),LL(0x6f7a6ff2,0xb1ff6013),LL(0x312bdeae,0x4cc245a6),LL(0x79a65a6f,0x29aa5006),LL(0xd3b4632f,0x920b0db1),L_(0x00000080), + LL(0x356fabd3,0x9eb2fa3e),LL(0x32e2213b,0x296648f1),LL(0x5464f17a,0xa0bf8f36),LL(0xf19ca8ef,0x4c8a5c7a),LL(0x876e29a8,0xa58d7e8a),LL(0xd8f86aee,0x0ec00506),LL(0x04f4e1a3,0x05b4072d),LL(0x1462f8a1,0x3da650c1),L_(0x00000175), LL(0x564895eb,0x5b19fee9),LL(0x8c62d05b,0x7809d8ab),LL(0x0cb573dc,0x4ad42bc1),LL(0x1884e984,0x9b3e8a9c),LL(0x6b2d6773,0x2d81f0f3),LL(0x072385dc,0x2f91b4d1),LL(0xca372aa3,0xe4038277),LL(0xd16c3a45,0x64dcfcfa),L_(0x000000bc), + LL(0x9757a335,0x1143084a),LL(0x38952f06,0xa4710659),LL(0x025fc38c,0x1698caaa),LL(0xcf127f48,0x7f55805b),LL(0x39cb3c58,0x621feb96),LL(0x58068b85,0x3a91b62b),LL(0xa4e48dd8,0xa7ba8220),LL(0xbd22ff75,0xc1b17c5b),L_(0x000000a0), LL(0x05196c43,0x142e4222),LL(0xaa56e765,0xeee6393d),LL(0x8f13ec6c,0xa88f8eb7),LL(0x536554a7,0x6720e144),LL(0x66972f38,0xadb6408b),LL(0x9d95e37f,0x67ab92ba),LL(0xe96c2792,0xa2d1345c),LL(0x3fb8e9b5,0x138c93a7),L_(0x000001f8), + LL(0x61c11852,0xf484baad),LL(0x1e71dab0,0xad2e9168),LL(0xe0ea71a3,0x6e1a90b0),LL(0x2b244009,0xfb37ada7),LL(0x0bd3281f,0x38140203),LL(0x1599d34d,0xf278746c),LL(0x3790a7db,0x17f577dc),LL(0x483a5cb9,0xbbf0dc49),L_(0x00000128), LL(0x8f5c56dd,0x6ec17c1a),LL(0x767ebf21,0xf0a141c4),LL(0xf1091ff1,0x051b5811),LL(0x3ac1c024,0x396942d9),LL(0x692ece19,0x5725cecf),LL(0xf1e6de73,0x75b56339),LL(0x2f629ac2,0x45030754),LL(0x6207c855,0x5090ae5d),L_(0x00000045), + LL(0xd14b028b,0x8c73e470),LL(0x684d5fa1,0x46af781c),LL(0xeb44feae,0x3e3aadf0),LL(0x4610320e,0xfd9c5960),LL(0xd8fffa44,0x70d9d9d3),LL(0xebbc9082,0x8a6283f3),LL(0xfcec5348,0xdd60d649),LL(0x44a603fa,0x8998ae1d),L_(0x0000011e), LL(0xce740ae3,0x5f6a91eb),LL(0x2000b013,0x3780772b),LL(0xe7ea71ec,0x0e54747a),LL(0x6f03b13d,0xfc299d7f),LL(0xd6603e33,0xb6e9df68),LL(0x86040d28,0x2043747f),LL(0x3aeee37a,0xe4608968),LL(0x9926fb8d,0x47be624e),L_(0x00000060), +}, +/* digit=54 base_pwr=2^270 */ +{ + LL(0xabb9ad39,0x6af8e430),LL(0x523480bf,0xf59d55e6),LL(0x4bc56b8b,0xc072bd61),LL(0x3df0a6ec,0x25c98f18),LL(0xbee1786d,0xbcc84059),LL(0xf26f3fea,0xb20a09a6),LL(0x79a2dfb7,0x93d600ce),LL(0xcf2e6f03,0x73c31f39),L_(0x000000e1), LL(0x9b72a39f,0x2b1470af),LL(0x4804a704,0x7da313b0),LL(0xe67c9622,0xc290e590),LL(0xbec90ccc,0x796f29ca),LL(0xf5e76e6a,0xcadb620b),LL(0x8ec01637,0x15b03af3),LL(0x4087520d,0xd8dcf763),LL(0x6c0ca6b7,0x0f970190),L_(0x0000006a), + LL(0x4f37e57a,0xc030f2d5),LL(0x649effc2,0xb84aa880),LL(0x3ad19d77,0x1cab55a1),LL(0x91bd296d,0x8c081620),LL(0xc8f7f0b2,0x0c469726),LL(0xb847d758,0x1840b8cf),LL(0xc59a8b12,0xc8fd3c1c),LL(0x0e2778fd,0x8c61a8b9),L_(0x00000186), LL(0x446cc1f4,0x3bf2f826),LL(0x4fc8626c,0x8d5f8bb7),LL(0x7df08423,0x3a877c74),LL(0x41c77ea1,0x471d935d),LL(0x5556d8fe,0xe98cde5b),LL(0x279a8287,0x068f4d40),LL(0xe400538c,0xdb305a88),LL(0xc091d74b,0x31201e77),L_(0x0000005f), + LL(0x766c809c,0xdd78e4e1),LL(0x81bcdd43,0xa933555b),LL(0xac8729aa,0xb8964c85),LL(0x4f18e8ec,0x87096359),LL(0x580f05ae,0xffab1de5),LL(0xe800a6a9,0x797b2184),LL(0xb6212cc3,0xea98c5ce),LL(0xc923afe4,0x287facf1),L_(0x000001ce), LL(0x66353c22,0xfe0b78e5),LL(0x0345fac6,0x27358467),LL(0x180e49dd,0x1ccff0c2),LL(0x92bcdaf0,0xea3ef331),LL(0xf7e4fb3d,0x99b89e87),LL(0x092ef793,0x9bdcca2a),LL(0x1418dec5,0xf9f9dccb),LL(0x314595b4,0x2d188c67),L_(0x0000013f), + LL(0x6e190a6f,0xeee766f8),LL(0x360709e0,0x5b775cd5),LL(0xd4566a98,0xe4057c69),LL(0x45df1e07,0xc0672257),LL(0x947733f9,0x1b1c2a5a),LL(0x4bcd6e2b,0xc80987a2),LL(0xe7293fbf,0x89f4061a),LL(0x11f7042b,0x9f0c87d7),L_(0x00000025), LL(0xc53c1b03,0xdaedd9c1),LL(0xc48bf537,0x495a12d7),LL(0x2c8c9765,0xe7c2d4a3),LL(0x662fe9df,0xfaed525a),LL(0x27c6bad9,0x5c4df70a),LL(0x24dd660c,0xba7fb076),LL(0x21abac8b,0x4a91b1d6),LL(0xb618ce5d,0xcf239771),L_(0x00000083), + LL(0x7875f26a,0x3212d16b),LL(0x3953e4c1,0x80a99a23),LL(0x42f909d9,0x457c9b9d),LL(0x68f18c26,0x62cfee59),LL(0x0b1b0fbd,0xd6e74f93),LL(0x99d73ca6,0x898ff611),LL(0xecc60074,0x0a0cf8cf),LL(0x0e4b48e0,0x264c8682),L_(0x0000007c), LL(0xd086fac9,0x30dd79af),LL(0xe0e34e51,0x0cb837fd),LL(0x052d2441,0xaefa0933),LL(0xbdea4988,0x44aec8de),LL(0xdfac83ea,0x46cb2469),LL(0xfad769d2,0x7cb77050),LL(0x18dd28c7,0x8001a60c),LL(0x8fe3d888,0xf467b922),L_(0x000001a1), + LL(0x5b24df92,0x2affa8b5),LL(0x207215e0,0x3c816de9),LL(0x199ff528,0xe11ab159),LL(0xfcc61eda,0xc8d67190),LL(0x661fbf7d,0xdda50129),LL(0x76defd37,0xd466e3a4),LL(0xf14fb3e4,0xc11ac280),LL(0x7620efce,0x396bb6d8),L_(0x00000179), LL(0xb257b1f0,0x4204720c),LL(0xa9d04719,0x620bab0b),LL(0xcf599cb7,0x4b89783a),LL(0x4c38e784,0x96aa7914),LL(0xa4374ec1,0xa42b74a4),LL(0x1d57fa44,0x5d9da37f),LL(0x9e98081b,0x907073d1),LL(0xd1274d9a,0x616e9807),L_(0x000001ae), + LL(0x3e1d7c3a,0xde4b8ce4),LL(0x0940b9c2,0x3515847d),LL(0x594f371d,0xc37d20b4),LL(0x0d44e03d,0x4b2281a5),LL(0xa133895a,0x03246afc),LL(0x69dc40a2,0x1243d0ed),LL(0x6acc7d98,0xc664eb78),LL(0xa9ddc8a1,0xf6274641),L_(0x00000197), LL(0x1a66ad76,0x3359c96c),LL(0xebb34cc8,0xe69f9794),LL(0xd1662749,0xf9f1455f),LL(0xb162a274,0x40fc34f6),LL(0x9d860e20,0x4fb62774),LL(0xa70d36c2,0x6f971a18),LL(0x990d79fe,0x19225101),LL(0xdd30d9b3,0x30c5bb02),L_(0x000001fc), + LL(0x51c91503,0x673999f7),LL(0xfe14668b,0x08c22b2a),LL(0xfc300d5b,0xecabf6a5),LL(0xe178c0bc,0x020b90b3),LL(0x79d38258,0x81c171fe),LL(0xa2f11763,0x86f32623),LL(0xf3a66cde,0x6ff64b9b),LL(0x5668f5ac,0xf47332c5),L_(0x00000014), LL(0xac181251,0x3ea58c5d),LL(0xde279aea,0x356a5f10),LL(0x7e9f7153,0xd08295b0),LL(0x86ce9eb4,0xf7c783f5),LL(0x4daab1a3,0x030b2d7c),LL(0x603300a0,0x2198f316),LL(0xd0c0475c,0xba184aa9),LL(0xa6fe88ca,0xe6bb2b11),L_(0x000000dc), + LL(0xade6d9e8,0xaf408fd2),LL(0xfdbd3baf,0xf2f9bf1e),LL(0x437c785f,0x502fb232),LL(0xeb964445,0xeaf5771f),LL(0xb08bd2ce,0x4c23d40b),LL(0x71ed9783,0xa9fbdb0a),LL(0xf481a53f,0x3a79f04f),LL(0x8241d897,0x33076e6c),L_(0x000001be), LL(0xdbc73cb0,0x6c1463d2),LL(0x900c1c58,0x38e9d58f),LL(0x9115aabb,0xc0a95554),LL(0xd544f068,0xb7066734),LL(0x00d18a77,0x10cc9da3),LL(0x482d67a5,0xf9d64b4f),LL(0xfe8b6e80,0xff8c0ceb),LL(0xa32070d7,0x7154c1c3),L_(0x00000058), + LL(0x1fdd6bf9,0xbe1106f7),LL(0xc44a87ae,0x43749975),LL(0x3d0c3b77,0xb45ea397),LL(0xf0fbd03e,0xd44cf903),LL(0xb4c5c47c,0xaa4a5ca8),LL(0x38153aea,0x2980014f),LL(0x58f964fd,0x7baccd46),LL(0x2458a3d8,0xeff4ee59),L_(0x0000010e), LL(0x9c8ef0d9,0x8ec22b8f),LL(0x99582fc5,0x2b8aa8c6),LL(0xd629663b,0xcebbdb32),LL(0x2ff405c2,0xbd666f05),LL(0x8989d659,0x6c986174),LL(0x2eb13e6b,0x7fa4c2f5),LL(0x5660e9a9,0x30206c27),LL(0xcd2e9b5f,0xc16a517c),L_(0x00000126), + LL(0x1b2c97bc,0x3e8c6c5f),LL(0x97ea6bef,0xe6975580),LL(0x1fa05de0,0x45dcf226),LL(0x28ce5e22,0x6b3296e1),LL(0xbc5ea09c,0x355e867e),LL(0x171e0d4c,0x93a02b45),LL(0xef953fca,0x72562a6a),LL(0x283e85d5,0x0a4baa50),L_(0x0000012e), LL(0x00384cef,0xc61925fd),LL(0xb15e2b9b,0x98c42ea4),LL(0xe51f203e,0xa9da7eaf),LL(0x80b7c7d8,0x00d05b8b),LL(0xd0e8cb9d,0x5b984aa6),LL(0xe2223126,0x97eb783a),LL(0xcbd154b4,0x60eeeb46),LL(0x77d65106,0x51c5f225),L_(0x00000100), + LL(0xecba5c8d,0x4c52e9d2),LL(0x1a2c0764,0x084d971b),LL(0x04071452,0x5b00ba29),LL(0x420810c9,0xe37ace16),LL(0x8726c12e,0xfb3b3465),LL(0x76e95cdb,0xddb8f121),LL(0x5a782ea1,0xe1266546),LL(0x9e91fb9e,0x2763e598),L_(0x00000003), LL(0xde0c16d5,0xb01d1b1a),LL(0xcdfa5a5a,0x186cc016),LL(0x907f643d,0x951f20c1),LL(0x19ce2692,0x499758b8),LL(0xa1e463db,0xae173a15),LL(0x1a60551b,0x9960164a),LL(0xa7db4dec,0x5c5b509d),LL(0xd9cec887,0x8bf36254),L_(0x000000a4), + LL(0x16cce787,0xd4a2fc01),LL(0xa425fa18,0xf155769e),LL(0xaf00539b,0x60eb1b90),LL(0x688fdaf6,0xfa6d7481),LL(0xf34ab7ee,0x4f289d5b),LL(0x07dbb72e,0x1e391abd),LL(0xbc2da7ee,0x95c48dba),LL(0x566bd167,0xd547663d),L_(0x00000043), LL(0x9ce2304f,0xd19a287e),LL(0x13ab6992,0x4405fdb4),LL(0x96fa0864,0x4139a060),LL(0x41a760d2,0xbccd999e),LL(0x5ba64bc7,0xb10009b9),LL(0xd8deab9a,0x984258d2),LL(0x79776c54,0x221ad688),LL(0x10e8fea6,0x936b124d),L_(0x00000087), + LL(0x5b9e9b6c,0x0d488b76),LL(0x718de1b3,0x479d6241),LL(0xc5e08581,0x835e01af),LL(0x2980a85e,0x5861c30b),LL(0xb6dbc1d7,0xa410ea56),LL(0x2db982c5,0xe2d1be8c),LL(0x9bd416d2,0x8b2c0849),LL(0xff9c097a,0x3959a07c),L_(0x0000017a), LL(0xbf3507bb,0x84f97fa2),LL(0x638f765c,0xc3635cb6),LL(0xddc089f6,0xadab3335),LL(0x03a11712,0x45c1fc02),LL(0x6d411e20,0x92e35990),LL(0x10bb8db9,0x9c8fd9b8),LL(0xa138660a,0x9289131a),LL(0x37f6b49c,0xa3d2ae4c),L_(0x000000b7), + LL(0xa1146df7,0xfdfcfffc),LL(0x81511cf3,0x23bc0f93),LL(0x2b2a7c87,0xdc82a234),LL(0x03b40d7d,0xa08a7dd1),LL(0x710d66e6,0x21695339),LL(0xb2de413b,0x70d88f9e),LL(0xa639823f,0x35b8b90e),LL(0x023e9ff4,0x841fb110),L_(0x000000b7), LL(0x67b34d07,0x68b9df98),LL(0xae385a70,0x9e1b7b1b),LL(0x69f1b285,0xf3ca9831),LL(0xacc09537,0xd4b56b4f),LL(0x9d566211,0x5fe60450),LL(0x8cabfe34,0xfe548cc5),LL(0xb714db58,0x6edccbce),LL(0x1b3de9cb,0xae7588f9),L_(0x00000018), + LL(0x3fb44e11,0xd6d98611),LL(0xf902dfd5,0x894e506c),LL(0xfd0b1d00,0x85a52247),LL(0x782247b1,0xee7a96a2),LL(0x73bd1827,0x817a81ab),LL(0xb5a675cc,0x58e21da1),LL(0x96f3b0ad,0xba6b1f8c),LL(0x0b4feab1,0x47a0c5eb),L_(0x00000186), LL(0x94e1e70f,0xa2caaa6a),LL(0xe4a5a160,0xc595ff3d),LL(0x4e2aab67,0xc4ca75c8),LL(0x55f145b7,0x7731bee5),LL(0xfc6003a4,0xe7fe03b5),LL(0x0bfb8f07,0xc95ac06b),LL(0x062bb217,0x970ec8f9),LL(0xa73aafef,0x436ead58),L_(0x0000004e), +}, +/* digit=55 base_pwr=2^275 */ +{ + LL(0x10edee70,0x5fd3e47e),LL(0x3597fca0,0x77535436),LL(0xd14d9e5f,0x3e8b8ab9),LL(0x09ae6cb6,0x74096598),LL(0xc8a4dd84,0x9f1a5c96),LL(0xcb6edd24,0xd2f79af0),LL(0x61d2b7a4,0x0e166e53),LL(0xfe3d22a6,0x57342692),L_(0x0000001c), LL(0xf72fa6f8,0x96d7a363),LL(0x488ad6e3,0xd92f57cc),LL(0x8510a286,0xf0a9d195),LL(0xb888aa8b,0x317136c0),LL(0xf42decec,0xdf9fc71b),LL(0xb6cc8b9b,0xc0298d41),LL(0x49e5d99a,0x109ecbb2),LL(0x314b57f8,0xb46534db),L_(0x00000132), + LL(0xb2d708c6,0xce839038),LL(0xce28ed96,0x20e1ea62),LL(0x8763eab5,0xed2713c5),LL(0xc4523fd6,0x71027fe2),LL(0x7eae1cb2,0x9c4b8cf6),LL(0x24a95e4f,0x601ad020),LL(0x07164949,0xdd7d73ac),LL(0x37442ffc,0x6e6ae643),L_(0x000000d1), LL(0xb77851b2,0xdb8574d7),LL(0xb645bbee,0x286ebfe9),LL(0x0c8710d8,0x766e45ce),LL(0xa79aecb4,0xc2d31256),LL(0xbf379f83,0x340ea164),LL(0x164bbbc5,0xf851521a),LL(0x1ac3081d,0x7e9d5d5e),LL(0xb205779b,0x9097f081),L_(0x0000007d), + LL(0xde9114db,0xe63af665),LL(0x818c463b,0x6295501a),LL(0x35a127bf,0xdce47ef1),LL(0x007d2c0c,0xcdab36d7),LL(0xccb851cf,0xfdd117a8),LL(0xf238753e,0x0f305c31),LL(0x8e2817b4,0x7fa2c0d7),LL(0xf487e902,0xc3ae8d53),L_(0x000001a5), LL(0x170a9d8a,0xfdab89fd),LL(0xd0296988,0xf7158579),LL(0x9d9469d7,0xe8a6f604),LL(0x10415652,0x2b54a37b),LL(0xcc4eb51c,0x0c719573),LL(0xae48f5a3,0xa83c1dff),LL(0x30b12c01,0x72dbb726),LL(0x57308088,0x979e1572),L_(0x0000003f), + LL(0x313e4b56,0x08231734),LL(0x6717f045,0x479ae527),LL(0xe3d436d8,0xd02cb05c),LL(0xf2257834,0x00a63fdd),LL(0xa7cf8043,0x55acde6a),LL(0x457f48d5,0x3233d0de),LL(0xde5db66b,0x81aa55b4),LL(0x0379d9ac,0x13ffc8a6),L_(0x00000189), LL(0x13e90717,0xc47bead6),LL(0xf2111132,0x90e8a449),LL(0xb92dfa6c,0x2861c278),LL(0x0e5052e4,0xbb21a8a2),LL(0xdd62ef7f,0xda29cea2),LL(0x06ce5d03,0xb1054057),LL(0x321921a2,0x2bdda27b),LL(0xa8070a21,0xe0b1ed13),L_(0x0000000c), + LL(0xb57fe1e1,0x13d1fd3d),LL(0xaf39e976,0x9d300d5d),LL(0x3c4bd73d,0x394a792d),LL(0x22ea164b,0xdb8ad2a0),LL(0x94ca8b71,0x46b5c44e),LL(0x29573de6,0x4faada81),LL(0xa68e6f0b,0x9bb3e293),LL(0x2829705e,0x8e9779a5),L_(0x00000001), LL(0x562f24c2,0x10d7ee7c),LL(0xebc4c9ff,0x1bfc2a5b),LL(0x9e849995,0x9ab67877),LL(0x29bf2cd5,0xebbab48f),LL(0x1c14b040,0xc34becb0),LL(0x0f56d5be,0xa06f84dd),LL(0x74ea8bd3,0x16998590),LL(0x240441e5,0xafa1dab5),L_(0x000001fe), + LL(0x99d23cf5,0x8778f5f2),LL(0xc8b025b9,0x1705a5c8),LL(0x3919b71b,0x0d5b88f4),LL(0xcb92372e,0x60fa371f),LL(0x943296e1,0x0a89cc71),LL(0x5fe1a497,0x34a3ae69),LL(0x5dec2f93,0x1251e4b9),LL(0x275a5942,0x8b24d4d6),L_(0x000000b8), LL(0xff47e08d,0xaa12f1b2),LL(0xad152f2f,0xffb55ea0),LL(0x2d49016e,0x9565927a),LL(0xe898a743,0x6cdbde63),LL(0x47e768ee,0x9201bbe7),LL(0x0a069ce7,0x64e8832a),LL(0x4d3af5cb,0x22cff077),LL(0x58cc25a5,0xb382381d),L_(0x000001b0), + LL(0xb0b126b6,0xaeabb8d7),LL(0xc38359f0,0x58505b26),LL(0xb9091af1,0xe930c10c),LL(0x1baa2a57,0x4ceb63b6),LL(0xf34a1cb3,0x2ce30eb5),LL(0xe695563a,0xb46502e9),LL(0xbc4a4498,0x3de11285),LL(0x7d46bb82,0xc6d8d037),L_(0x000001b5), LL(0xd0a4132d,0x4b0d3d99),LL(0x19c65f2c,0xbdec1fb8),LL(0xe96bad16,0xf98a7a22),LL(0xfc740b98,0x4ac9e432),LL(0x327482c4,0x19b02fa9),LL(0xee365754,0x2b71db69),LL(0x8c4b6fcb,0x3b059127),LL(0x1ff3d7d8,0x9083d509),L_(0x00000063), + LL(0x5b27f0e1,0xc1b9a1af),LL(0xc491a3f1,0x3c2c754f),LL(0x5cbaab1f,0x2a77d316),LL(0x0310665c,0x760e6436),LL(0xda6d64bd,0xabfa1968),LL(0xfb5f4ce1,0x2b0e1701),LL(0xb466c4ed,0x7ed3c4d7),LL(0x2ebf2125,0xdfa00f91),L_(0x00000168), LL(0x50f6e44d,0xddd0d096),LL(0x8ca37cde,0xacd3234c),LL(0xb7244def,0xd39cba5f),LL(0xacca56c2,0x42e4fef3),LL(0x04d3ff0e,0xd03959e1),LL(0xe6513498,0x101ed923),LL(0x40deadab,0x3a0842e2),LL(0x40cf65c5,0xe8f52471),L_(0x0000005d), + LL(0x24abeced,0x8027d5fa),LL(0x54bd40b9,0x6c207959),LL(0xaeb9dac1,0xd464b86a),LL(0x419d1ea2,0x6820d398),LL(0x5e25c94d,0x7cb4e131),LL(0x65e1ca01,0x407cd9e9),LL(0xe5ede0b5,0x9cc6a7e8),LL(0xccfcd5ef,0x5004892e),L_(0x000000dd), LL(0x38ae86f8,0x198931f5),LL(0xff746c8b,0xd54d7f12),LL(0x309a79bf,0x1246b150),LL(0x42f00081,0x77449920),LL(0xc47ea560,0x3c1ca128),LL(0x7f0d691e,0x4a7cd82a),LL(0x389f0267,0x3325d3c5),LL(0xd3d69318,0x8d437ee6),L_(0x00000114), + LL(0xdc420de7,0x40b5d961),LL(0x0c56a78c,0x0669c065),LL(0x20ea2fcd,0xd7d6512b),LL(0x0cfdc1ce,0x793f28c8),LL(0x12dc4c42,0x2a2c66b6),LL(0x65ef14af,0x8712d0f4),LL(0x498de283,0xaba3e10f),LL(0xd43378b1,0x99525eef),L_(0x00000147), LL(0x29182339,0x2743e625),LL(0x75c8a0f5,0x7cb967f9),LL(0x3b942e5d,0xa6fa495f),LL(0x2c93c4c7,0xaf911e44),LL(0xe5ea4e81,0x61393032),LL(0x453b1c33,0x6ad975cf),LL(0xbd844374,0x598fb85f),LL(0x19bef583,0x5bc44e9f),L_(0x0000015e), + LL(0xca0bf18d,0xa3d7dbe9),LL(0x4163c3c8,0xfea7d95a),LL(0xc8c760db,0xbedeb961),LL(0xbe4aaf54,0x6366da72),LL(0x184e2e0f,0x4b391d6f),LL(0xc176d3d7,0xda402a6d),LL(0x58e13d8b,0x35c88b87),LL(0x9e868f1c,0x28cd51ed),L_(0x00000137), LL(0x060d87ba,0x2fb088fa),LL(0x7bb887ef,0xd9fecef3),LL(0x5f6918e8,0xd8d0ab29),LL(0x584e5e50,0xa68549e0),LL(0x1a0e8dad,0xccee2619),LL(0x6b94fb63,0x2fe6d355),LL(0x41620a75,0x2f9f5687),LL(0x3bbe2240,0xb1f43624),L_(0x0000013f), + LL(0x7b1c8a03,0x5d3c5d98),LL(0x9b0532ff,0x8d28755f),LL(0xa6811aec,0x526696c9),LL(0x1a05c762,0x85c6fe67),LL(0x9b509178,0xb1cd9732),LL(0x9ce1e435,0xd6424b12),LL(0xd25c0017,0x7dfb69b5),LL(0x8fd3449e,0xb06e65bf),L_(0x0000014e), LL(0xdb3b3b47,0x4f13caa8),LL(0x8c65da30,0xc42581d3),LL(0xf1637449,0x31ba26e3),LL(0x086fb178,0x1f20a375),LL(0xe70bccf5,0x794f66bb),LL(0x8fb9ec67,0x8759114e),LL(0xba15c3e0,0xbae55fef),LL(0x6274e840,0x541f86b0),L_(0x0000008b), + LL(0x9940c688,0xd17c3809),LL(0x1ad4bb7a,0x02bbb8e4),LL(0x62901ee1,0xdef212fe),LL(0xf758e2a0,0x902e165b),LL(0x41df4c90,0x813c93c1),LL(0x2d980715,0xdfe446b0),LL(0x16925c07,0x26180355),LL(0x6a7e91aa,0x2feac9e3),L_(0x00000096), LL(0xa45e236d,0xf8e5447a),LL(0x116cff34,0xe8d1be37),LL(0x05f97032,0xb0f21f66),LL(0x2f2c027f,0xa11df664),LL(0xa89a55e5,0x02fec70b),LL(0x0cbe911b,0x281dbb5c),LL(0xf7515075,0xff0a3fb5),LL(0x5eb63dce,0xde9df17e),L_(0x0000012f), + LL(0xa91392a8,0xbdba8a73),LL(0x3162337e,0x57c70feb),LL(0xfe6064d0,0x1cbf9841),LL(0xb8ea5857,0x0f9265ab),LL(0x8f4d78e1,0x4ea34ee6),LL(0x86c61019,0xe932bccc),LL(0xa4d88afe,0x9518b05b),LL(0x1b666c9e,0xdccb7c7f),L_(0x000000bd), LL(0xf8bfc49e,0x05208c75),LL(0x9df54ae4,0xd373c5a9),LL(0x79933e71,0x5b8a9772),LL(0x64aa0b3f,0xa96b6ada),LL(0x636d2c0d,0x5227ca04),LL(0xc4142eed,0x6e0ffb64),LL(0x11d0f26b,0x03baa051),LL(0x6cce8a32,0xd1fa3649),L_(0x000000b3), + LL(0x1b22c75f,0xf889ab10),LL(0x198462a9,0xdc726c9f),LL(0x4488dc01,0x03497dbf),LL(0x6173d9f9,0x44668664),LL(0xa2ec1a91,0x97d57504),LL(0xc515fce6,0xe38e8b7b),LL(0xc94145f8,0x9a57e3c8),LL(0x7f491462,0xf8e43df6),L_(0x000001e3), LL(0xfab74bc2,0x21aa76a0),LL(0x5cde4de2,0xcabcd328),LL(0x58febacf,0xfc5df376),LL(0x164a8b43,0x53cf2abb),LL(0xd59cb6ca,0x4bdbc3e7),LL(0x5fa72448,0x61888f39),LL(0xec291663,0xa63d2680),LL(0x8efa4a04,0x6b003337),L_(0x000001c7), + LL(0xbfc44034,0xda15115c),LL(0x7be6519e,0x4c0ca17c),LL(0x1e404697,0xd39b899e),LL(0xd56cb968,0xafaffc6b),LL(0x977f25af,0x0c48baa8),LL(0x33c5e846,0xb8ddcae7),LL(0x8db3dd6c,0xea4e7b4d),LL(0x30c42ef0,0xdf2a5d47),L_(0x00000075), LL(0x3bded433,0x1c36485b),LL(0x60a85776,0x3a9ef9b4),LL(0xc163b2e2,0x9caea119),LL(0x699c32d3,0x6fbf2af8),LL(0xc9afc21d,0xb2f30acb),LL(0x5cd46105,0x2782e179),LL(0xc5de1ebd,0x94bd0296),LL(0x40db331e,0x1d32d3f5),L_(0x000000dc), +}, +/* digit=56 base_pwr=2^280 */ +{ + LL(0xb3566c4d,0x70856265),LL(0xffa63a05,0xcbace31a),LL(0x64645336,0xd792b4ed),LL(0xe49945b2,0xcdc41c6d),LL(0x4ffedb2c,0xfc3fec1e),LL(0xfb381239,0x6c094341),LL(0xb5868f95,0xa828185b),LL(0xf680572d,0xb8368ada),L_(0x000001ae), LL(0xbfe0585a,0x480f8f0f),LL(0x30bd3b95,0x5be334d5),LL(0xc2d3c86e,0xd762f278),LL(0x676d6c82,0x1488b56b),LL(0x539dec8e,0x756194ec),LL(0xc0fc3e4b,0x4e5ad8a2),LL(0xe01cce49,0x1e1d4129),LL(0x9cb7e94c,0xb0ed4c45),L_(0x00000145), + LL(0x2ee172f7,0x76d70712),LL(0xcc86b737,0x07937b43),LL(0xc42e1bf4,0x0a15775a),LL(0xe0abab13,0x8a6f4155),LL(0x8a4930e5,0x7af5f75c),LL(0xe4d25a23,0xf7ffdb8e),LL(0x47745ba4,0x1c8fe7af),LL(0xda1f09c1,0x298ae467),L_(0x00000026), LL(0x58ab833a,0xbed40193),LL(0x74f45669,0x07b7fe4d),LL(0x00a5516c,0x8fed834f),LL(0x35a36d31,0x46f3d5f0),LL(0xcf8a31bb,0x46e1df3b),LL(0x86c99729,0xef24a7e8),LL(0x383ab5e1,0x3285864c),LL(0x85a50c0d,0x14d71a5b),L_(0x00000172), + LL(0x82d65b66,0x2c2925e3),LL(0xc79d0387,0x80fde81a),LL(0xa2432027,0xbc3a2b38),LL(0xa34422b6,0x24a6595f),LL(0xb948d55e,0x7ed8f149),LL(0xfac14efa,0x1011867c),LL(0xe578bbe7,0x01bd1e94),LL(0xefa02765,0x4d118803),L_(0x000001b0), LL(0xc9f7389f,0x4f58dfa2),LL(0xd3bff99b,0x27af2024),LL(0xe0ca7fb1,0xa09a0ca5),LL(0x782dbf7b,0x01098d83),LL(0x19fa5d61,0xabdbaa4b),LL(0xddb85231,0xc03b0d70),LL(0xbb859499,0x26cba60c),LL(0x8d596ce3,0xda0073ba),L_(0x00000111), + LL(0x8aec0422,0xb67d56f7),LL(0x85f0af78,0xd0dd5f00),LL(0xd1879493,0xede77ef6),LL(0xd412929c,0x6254c309),LL(0x2f8f47fc,0x6cfbb6a1),LL(0x4af63813,0x0a561c30),LL(0x70283e09,0xb1640127),LL(0xc77dd363,0x061fa6e8),L_(0x00000023), LL(0x65973023,0x29101040),LL(0x7036678a,0x6adb22ec),LL(0x5919dc9a,0xb9607eaa),LL(0xff75ea6b,0x2f103f0e),LL(0xa1b15402,0xc4300dcf),LL(0xfdcf2e9d,0x3ebbf1ab),LL(0x1be47bf2,0x3bc7610a),LL(0xe48e43b2,0x13834ee8),L_(0x0000002d), + LL(0xb1366222,0xc255282f),LL(0xcf45bdd6,0xe5f65eaf),LL(0x15c02959,0x0d59b305),LL(0xd5074c2f,0x69d34def),LL(0xf460bf31,0x98c4daf0),LL(0xcd4dd881,0x2d35aae9),LL(0xa3e2b924,0xcd6f8fb3),LL(0x7ee19179,0x3fe40e5b),L_(0x0000000f), LL(0x3015c0c8,0x24998853),LL(0x9b18e9fc,0xc27ee4ed),LL(0x01ee8c44,0x961e30d9),LL(0x38c4d057,0x4e4722a4),LL(0x27a847d7,0xbd34c3ce),LL(0xfc175e9e,0x9ec1f371),LL(0x28ad6264,0x9962cfa6),LL(0x8cb8ba21,0xa4d69025),L_(0x0000017b), + LL(0x48414eef,0x4b16d635),LL(0x466a22f4,0x91c53690),LL(0xb9b4826e,0xdfa700b4),LL(0xba41d6fd,0xa9d1c269),LL(0x3f48b184,0x9a1ae562),LL(0x1d66af1a,0x88445e2f),LL(0x16e76216,0x5528a0ef),LL(0xa509e874,0xe8df0ea0),L_(0x000000c2), LL(0x4d16c4eb,0x405c88d6),LL(0xcb159002,0x21995ea2),LL(0x9206340d,0xc1b476f5),LL(0xbdb47138,0x73c4a87f),LL(0xf1fc51a6,0xd81d7d81),LL(0x68d2c132,0x3035e2c5),LL(0xc2e86c33,0xdd1981e0),LL(0x25fcaa15,0xa3e61c9f),L_(0x000001f3), + LL(0x4ab2a49c,0x70aadb7c),LL(0x983438d3,0x9f4ebf13),LL(0xd25c9ac8,0xd8d4d610),LL(0x9c7f0f75,0xca14e0b4),LL(0xdcfed5c3,0x4d6f7590),LL(0x36f5cd7f,0xd93cbfaa),LL(0x65cb3d17,0x1ddce79a),LL(0xbd97f101,0xbf7024b4),L_(0x0000014b), LL(0x8b012070,0x77a85a51),LL(0x279a4494,0x7671964d),LL(0xff88af2c,0xf271d11a),LL(0xdbb6c2c5,0x82395ca1),LL(0x85ba326b,0x98f43101),LL(0x0cb73c28,0x63dc513c),LL(0x6b203054,0x4469f278),LL(0xc5c18db9,0xbad9b61f),L_(0x0000010f), + LL(0x3d80adc6,0x4e403a26),LL(0xab320624,0xad04e1de),LL(0xdcbb6130,0x2a259720),LL(0x6e850532,0x231b1ad6),LL(0xa60fb3f5,0xcd79b6e2),LL(0x663d49e1,0x179c366e),LL(0x01277eb6,0xe6c6ea0d),LL(0x883c4ffd,0x0c383473),L_(0x0000006c), LL(0x7e40167f,0xaec71f68),LL(0x9a231d95,0x1c63bde5),LL(0x4af79a44,0xdec74dfa),LL(0xfd79e68d,0xa1952760),LL(0x0b613ae2,0x08e61ca7),LL(0x9e73036b,0xe30d2b54),LL(0xd922e0f3,0x6d8fb383),LL(0x28c14621,0xa421baa0),L_(0x00000194), + LL(0x1137f8e6,0x66cf0839),LL(0x9b11d642,0xa909855d),LL(0xc2008fb3,0xcfac98d0),LL(0x7141e8cb,0xf021a4df),LL(0xf143c405,0xab358375),LL(0x67bc2904,0x17ae0177),LL(0xcc509637,0x3e96013d),LL(0xa1e7d9dc,0x4facea49),L_(0x000000db), LL(0x957910b6,0x497bb1a3),LL(0x0139fb02,0xbd519647),LL(0xb1e83186,0x3a05bf5b),LL(0x19b27ed1,0xcae014aa),LL(0x82e975ee,0x2c7c3285),LL(0x88e9df86,0x55efa48e),LL(0xeb606052,0x325f6177),LL(0xa47eec1a,0x99b1ff61),L_(0x000001df), + LL(0x3a878798,0xb073983a),LL(0xb57577f3,0x911ef229),LL(0x88b3000a,0xb6a2c941),LL(0xfe60609c,0x2014f532),LL(0x505cb96c,0x56c1e07d),LL(0x4b65f80c,0xacfa88b0),LL(0x6d867481,0xe4164f16),LL(0x5599d374,0x862f8d51),L_(0x000000d4), LL(0x0c1e1e98,0xfcb0b84f),LL(0x19e6efb8,0xb9207b90),LL(0x51572182,0xa8d8dbea),LL(0x3bef29fc,0x48664299),LL(0xf1204f85,0x601bc4d3),LL(0x0e9a0fd0,0x04ed7b5b),LL(0x79ce5a54,0x2efbde9a),LL(0xa61da12c,0x620aebbd),L_(0x00000125), + LL(0x50fecf46,0x92f8cb5b),LL(0x920174e1,0xf0d81ba1),LL(0x1067e00e,0xdf0090d3),LL(0x0f944d92,0x7cf84daa),LL(0x29760c45,0xe2fe5c35),LL(0xdcd64aa5,0x0fc3d3ab),LL(0x926c41d9,0xd093a0e6),LL(0xf508ca71,0x5b0f1f7a),L_(0x0000008a), LL(0x2ec2b366,0x41b5fe84),LL(0x68d89f52,0x6a8252ee),LL(0x7f37105c,0x12bfbd7a),LL(0x28e7afdd,0xa8c8a6ce),LL(0xc9ac312b,0x64f59820),LL(0xfc0802de,0x91abcca1),LL(0xdd3daa77,0x3663e8e4),LL(0xcba87568,0xb39b3267),L_(0x0000003b), + LL(0x167f86e9,0x77ecbc5f),LL(0xb273c517,0x1e1c4580),LL(0x7b0cac28,0x7d9e9af5),LL(0x8231d2eb,0x6aedfd99),LL(0xaaffb728,0xf1c98f12),LL(0xe925ce44,0x74f1520c),LL(0xc049eb63,0x494b788d),LL(0xd9d95935,0xe226209f),L_(0x00000130), LL(0xccc2d2a6,0x0b127e1a),LL(0x3b751841,0xcd70c11d),LL(0x64418006,0x1b4ae955),LL(0xbadb0a24,0x604cb635),LL(0x9f330b20,0xcfd3da79),LL(0x73a90953,0xef2d17df),LL(0x1b20635f,0x4743671d),LL(0xd4c67374,0x2f665bab),L_(0x00000186), + LL(0x9ec2635a,0xbc72074c),LL(0x1fe4598a,0x2c820e92),LL(0xe36ea0ca,0x2497dd7b),LL(0x4a8623f2,0xe23eb8d9),LL(0x60085b98,0x40f9b504),LL(0x1c20ee53,0x201ec927),LL(0x00761ac1,0xd442c9fb),LL(0x4f448cc8,0x9ba54c26),L_(0x00000025), LL(0x6e43f9a4,0xccd45383),LL(0xdd223c39,0xe5a9e554),LL(0xb7183f2b,0xbabb5193),LL(0xcaf50569,0xd8970128),LL(0x1fd8dbce,0xa8d54145),LL(0x334b381f,0x13a9b729),LL(0x728ba78e,0x437dd328),LL(0xd0616bed,0x028df6a9),L_(0x00000104), + LL(0xaa17f0bc,0xd2eb9fb6),LL(0xcdb03b75,0x6da41301),LL(0xff96e100,0xd003b0fd),LL(0x0f341e2c,0xeffd7580),LL(0x00a92b40,0xb4e94e73),LL(0x2f420bab,0x7e020897),LL(0x3a5a980e,0x0e9d7689),LL(0x44d12101,0x6759e798),L_(0x000000aa), LL(0x2631776c,0xf32bcc90),LL(0x4363aa54,0x81eb128d),LL(0x290c3760,0xc99f8366),LL(0x24d51de3,0xa9c8e087),LL(0x2212897d,0x63ef80d8),LL(0xe1731f84,0x4ba53d2d),LL(0x71a09c6c,0xf3c92c58),LL(0x1de91d0d,0x1015dbba),L_(0x0000009b), + LL(0x007f0db0,0xfc29c9c2),LL(0xc5a04df7,0x7ce23069),LL(0x889ac9f2,0xabf8339c),LL(0x48b685ae,0x57639632),LL(0x3111646e,0xf8b9f075),LL(0x94f37131,0xb2897670),LL(0xf80a60f0,0x834d23a7),LL(0xeca2d9a7,0x27dcb428),L_(0x0000003e), LL(0xc94b1130,0x12c12cdf),LL(0x7f1285c7,0x53433711),LL(0xa3fdb413,0x6c9aab37),LL(0xd50e87db,0xc28229bf),LL(0x6e31c080,0x9878eb5e),LL(0x647c7885,0x6255df90),LL(0x3c367034,0x64a27e7b),LL(0x359e7554,0x26d5090f),L_(0x00000077), + LL(0xc3090e22,0x856faf70),LL(0xcf9c3c63,0xa537fff7),LL(0xd0317a7a,0x61c02007),LL(0xdc853b32,0x61687510),LL(0x36ccdf2c,0xd6f188d5),LL(0x26fd385c,0x2955fa1d),LL(0xf2d7d6ea,0x3087bdae),LL(0x3173148e,0x0abc6b0f),L_(0x00000121), LL(0xd784c9a2,0xc0770de6),LL(0x4bf8c47c,0x35e4c8fa),LL(0xaece660d,0x8910f637),LL(0xedb7b99e,0x5ced4fad),LL(0xa82ce72b,0x0fa07446),LL(0x15701d4d,0x94600c85),LL(0x4152f301,0xf34ffcea),LL(0xf31c15ed,0x42ddbc96),L_(0x000000a8), +}, +/* digit=57 base_pwr=2^285 */ +{ + LL(0x3f5b1c78,0x7bafc7d2),LL(0xbe5d1d02,0x50c19efd),LL(0x3cdce225,0x5357a753),LL(0x3af279d2,0x14412057),LL(0x76015a5e,0x57141209),LL(0xc91c803b,0xb203384a),LL(0x12ba72de,0x2bedd680),LL(0x825c3d8d,0x7b99091d),L_(0x00000063), LL(0x6423553a,0xeaf27fe1),LL(0xef9335b8,0xc4539fb7),LL(0xfa5830e5,0x66badc9f),LL(0x0a5e5034,0x1dcbb895),LL(0xd3a2a96a,0xa62dca0d),LL(0x8a881a89,0xd5f98db4),LL(0x06e0a311,0xe2554b95),LL(0x69efeec8,0xf070bdcd),L_(0x00000073), + LL(0xb00f4f23,0xd445a023),LL(0xdd54cf07,0x551441ad),LL(0xe62fb5bf,0x33408f85),LL(0xd275f3aa,0x1f4e87ff),LL(0x701eb4ed,0xb08c2f8d),LL(0xcbec0af1,0x3b5987fa),LL(0xf0bc3119,0x37542336),LL(0x219a8c12,0xa528b587),L_(0x00000106), LL(0x5d52f04d,0x1a68b0a5),LL(0xd5fa5e22,0x5bdff6f9),LL(0xda24e831,0x9487e3f2),LL(0x8b43c649,0x8cc54962),LL(0xca393f54,0x934d621c),LL(0x52e8acee,0x0ce12d1b),LL(0xf0e6025e,0xcb0b93c4),LL(0x16663ffd,0xe4979771),L_(0x0000015c), + LL(0x5de71627,0xf54385d8),LL(0x8b05712b,0x7bb4ab47),LL(0xcc6b5489,0x5a9a3b2c),LL(0x7fa6f6a0,0x3bfef8f6),LL(0x773cd523,0xf505a80c),LL(0x5c9cc4c4,0xa3fe8c18),LL(0xf37ae336,0x6259e110),LL(0xb440dc7a,0x10c5254c),L_(0x0000016e), LL(0x1e50c98b,0x4b379333),LL(0x4a8aa5a0,0x3b8d3103),LL(0xc900df01,0xc99c95da),LL(0x52027ee1,0xb891a1fd),LL(0x4b5be3ae,0xb6857422),LL(0x5ba842f3,0xe00bb37d),LL(0x3f36375a,0x13a7f31f),LL(0x04743a28,0x61c3d8c3),L_(0x0000018f), + LL(0x69c14cb5,0xb3bf6b75),LL(0xa0bac5f2,0xcc275187),LL(0x6c2d559b,0x0eb925ef),LL(0xa5453338,0xd0382a25),LL(0x119f0d6c,0xbbf74a02),LL(0xaf681433,0xbd994d4c),LL(0x53999a9b,0x8d27772c),LL(0x249226a3,0xd03393af),L_(0x0000006f), LL(0x796a46b5,0x887c8f77),LL(0xabbf7bee,0x45dd063e),LL(0xa0a8e117,0xea429199),LL(0x8d22e28a,0x7e69a991),LL(0xb0ecebe7,0xb0ed2dea),LL(0x0edf7cec,0x37aa98d2),LL(0x0e528886,0x0ca19479),LL(0x73078fbd,0x2624f60c),L_(0x00000169), + LL(0x1809c965,0x4cbc62e0),LL(0x5c062be1,0xeaea9560),LL(0x1162dcba,0x07340ec9),LL(0xcf90fad2,0x6f6f4573),LL(0x8b6c2347,0x41df3d0b),LL(0x4bc4f7c5,0x6aba94c9),LL(0x9ce77c5e,0x25055fe2),LL(0xb9dd3d1f,0x3fae0593),L_(0x00000195), LL(0x6e430120,0x31a5bf9b),LL(0x31ef29c8,0x4ea14b33),LL(0x1451c355,0x3d7a4759),LL(0x515170ed,0xc3011219),LL(0x21413d55,0xb375db75),LL(0xacf6ce68,0x846f6627),LL(0x2facb2b3,0xdee7b99f),LL(0x3ead4f94,0x9859484f),L_(0x000001db), + LL(0x4f0117ae,0xd22f1814),LL(0xe3424149,0xad5ce6fa),LL(0x58b2d2e6,0x70e2e877),LL(0x5de9d268,0x6eb2a9a7),LL(0x6da54502,0xddee04cc),LL(0x3079a618,0xaa37f095),LL(0xef9c41ec,0x0ab072b7),LL(0x4f475d8e,0x2bbf4182),L_(0x00000199), LL(0x139a7b97,0x482e5296),LL(0x56474127,0xc87e2a1d),LL(0x0fe9253d,0x4757efac),LL(0xbdc55bb0,0xaa65a406),LL(0xfb5b47e5,0xfa5b9027),LL(0xd99ad5b0,0x1f6adf92),LL(0x3a4363de,0x6339348e),LL(0x6d9cf0af,0x2a0a19fa),L_(0x00000161), + LL(0x926c08a5,0x58be047c),LL(0x00018285,0x4ede436f),LL(0xb7c0f8da,0x267d40d4),LL(0x754e0583,0xf821bcca),LL(0x29b55f1c,0x356838ff),LL(0xef10fd05,0xd3bb98d7),LL(0xbf4cd160,0xcf20597a),LL(0xfe3d8718,0x20dd7039),L_(0x00000074), LL(0xbe1a541a,0x2ab231ad),LL(0x833de73e,0x3217ac39),LL(0xde117a87,0xe86047c6),LL(0xa460f6e7,0xbf61ad63),LL(0x3e4086cc,0x10646884),LL(0xeedbe45c,0x97bd568e),LL(0x9c11e90d,0x23655180),LL(0xb96c7748,0x1e4144ca),L_(0x000001aa), + LL(0x469af391,0x5bb73205),LL(0x3f5f97fe,0x80d05ad0),LL(0x73b1a3ca,0x00af9b79),LL(0xb52add98,0xcc82c533),LL(0x93cc487c,0x0da2ae06),LL(0xe46cf71a,0x060c7047),LL(0xaeb64abc,0x3aa21503),LL(0x0075b1d3,0xd2fdb4ed),L_(0x00000150), LL(0x29a2bed9,0x9a79f6b1),LL(0xda4630c4,0x22374a19),LL(0x62f001a1,0x90a13059),LL(0xa3cc4dcc,0x026cefa3),LL(0xb188b4cc,0x0fbb1d3f),LL(0xad092ff3,0x36e3761c),LL(0x6354b93c,0xf3dbdbdc),LL(0xb73317cf,0x30aa2b2a),L_(0x00000025), + LL(0x478cc5ff,0x39f6b453),LL(0x4e6379ca,0x063068cd),LL(0xe4f74a40,0xdb751bed),LL(0x94052b38,0xb0c9cab3),LL(0x8ee4c1e6,0xf5c6aa29),LL(0x3ca0dbb3,0x4a2497c4),LL(0x79c6ee9a,0x9ea63ecb),LL(0x00e2354a,0x9aadab88),L_(0x000001b4), LL(0x3a6196f9,0x62b157a8),LL(0xfa37ba58,0x59648d99),LL(0xe7f1758b,0x1b51e49d),LL(0x2e82eb6d,0xbcb59206),LL(0xc0686a28,0x337d156a),LL(0x6197f5d2,0x69bbd81d),LL(0x9b64ab0e,0x45283587),LL(0x8e4d1a8a,0x49019de8),L_(0x000001c9), + LL(0xed1f56a5,0xe00396a8),LL(0xc29bf98d,0x671ac7e0),LL(0x61a8021c,0xa76a8082),LL(0x40244556,0x85eaf05e),LL(0xd4493c4b,0xacc79ffa),LL(0xf3dd2e24,0xa065de83),LL(0xc2899229,0x616b4043),LL(0x26ec1649,0xa4be7f5b),L_(0x0000011f), LL(0x177b6d5f,0x5bdfa715),LL(0xbb1b8e86,0x1c8a38c6),LL(0x673dccd1,0xb8eb3119),LL(0x26507bdf,0x5e9ab066),LL(0x52444c41,0x63e06aca),LL(0xc41d72f8,0x6233cfed),LL(0xf0a4cf0f,0xa4204c93),LL(0x2e510168,0xdcd3c22c),L_(0x0000011b), + LL(0xb9ae2c20,0xa8e73672),LL(0x60eb4910,0x76d9acc7),LL(0xef341ec9,0xf8c3ff90),LL(0x71631b58,0xc5d46ddd),LL(0xf784f3a3,0xaca2efa5),LL(0x9fd6ccc9,0xb432ab0f),LL(0xe0c19b00,0xe9336780),LL(0x8e4851bc,0xeadaf077),L_(0x00000005), LL(0xeb8a4214,0x1ec45488),LL(0xab894d10,0xb3592330),LL(0xfe84be74,0xea5cac9d),LL(0xd6ce52df,0xd6fc5829),LL(0x52b83766,0xada3c1ed),LL(0x6e5007f8,0x07f9020f),LL(0x9dc77e51,0xf5261fb1),LL(0x3d52bde6,0x7203a776),L_(0x000000ec), + LL(0x9c19cb9b,0xa33466a1),LL(0x59900a19,0x2eeef601),LL(0xd1a35b61,0x70079dee),LL(0x043f6bdc,0xcd5ea5fd),LL(0xc0119db9,0x3a3b272f),LL(0x5b2eb1b8,0xe45f974f),LL(0xba8b6e51,0x5f770445),LL(0xd0419f04,0xc16877b4),L_(0x000000c3), LL(0x4b8a6a2f,0x21c82a7e),LL(0x356eb5d6,0x1f805802),LL(0xc510787f,0xb2d54598),LL(0x678fa9fa,0x14375d0b),LL(0x27fba413,0x6ed82aca),LL(0xce44cfc3,0xbe259313),LL(0x826f662b,0xdd1eec94),LL(0xc3f7e810,0x387cd50e),L_(0x0000011e), + LL(0xafd7f180,0x784a36b9),LL(0xa71f98dd,0x55359374),LL(0xb80637d2,0xeb356304),LL(0x319eb954,0xe36b826f),LL(0x6caacbc8,0x5436ed41),LL(0xc8f9a6b4,0x1ad27bfc),LL(0x05822de6,0x66b9e6c5),LL(0x6448fc9c,0x3e7fb461),L_(0x0000008a), LL(0xd306ac81,0x92fe9fac),LL(0xdda81241,0x90144259),LL(0x08d31ec6,0x70a69700),LL(0x59532bbb,0x548a4797),LL(0x25db5e1c,0xfe84a6c9),LL(0xdb376141,0xd82e648e),LL(0xaf5e43aa,0xd86080c6),LL(0xa3c129c0,0xcae35c47),L_(0x00000037), + LL(0x2343be89,0xd0ffaccb),LL(0x1cb1ffd2,0x3a03a0c7),LL(0x899f4ff5,0x6266f542),LL(0x5f5c983d,0xbcc25c41),LL(0xcccfd128,0xdfd7dc3b),LL(0x971841bb,0xb315e6d3),LL(0xab458be6,0xf423c907),LL(0x18de71ba,0xc4028ce5),L_(0x0000002d), LL(0x8643db82,0xdf24bfc8),LL(0xae140a96,0x7d249f93),LL(0xcc1b0809,0x4a944e10),LL(0xbb9f2bb4,0x2cf2ab30),LL(0x2a9df9a6,0x3e7a3348),LL(0x8877de2f,0xc1bae4c1),LL(0x6e777963,0x95df6e0c),LL(0x12289ec3,0xc2fe3876),L_(0x000001c5), + LL(0x84f63e6e,0xb92016c3),LL(0x9065995b,0xcfc7edd3),LL(0x7e853e34,0xe921ec35),LL(0xe5b9d192,0x48df779c),LL(0x22c1257c,0x2377e36c),LL(0xc67f15b2,0x2dd7559c),LL(0x56741ee4,0x8133583f),LL(0x266292d1,0x3e412477),L_(0x00000034), LL(0xcd5b0dfd,0xd6ec8a55),LL(0x0e18cbd7,0xa02b3661),LL(0xd0b4c82b,0x54051775),LL(0x2328d0e9,0xa2bff3fb),LL(0xbab00086,0x8724078f),LL(0xf6183452,0xe2d3f99f),LL(0x1d9f7aa2,0x3419a97e),LL(0x6878b1f4,0x67fe5413),L_(0x00000051), + LL(0x6c03f366,0x7fd85da2),LL(0xd5f694e1,0x52fd006e),LL(0x2f043a61,0x51032d25),LL(0x8bc9cc74,0x9348d55c),LL(0x6f5370ca,0x56333c4c),LL(0x3610540b,0xc9a5ca53),LL(0x716d25cb,0x39d8071b),LL(0x7337f70a,0x6bc9d236),L_(0x000000ac), LL(0x97db6fc5,0x3251b143),LL(0xdb755cfd,0xd84aa2bf),LL(0x0cc3e62a,0x9e9e3810),LL(0x6071f1f8,0xe47fb104),LL(0x3e7012d9,0x97ec5c7c),LL(0xf6c7e6ad,0x98bc4de4),LL(0xa4e7cef6,0x240c6a07),LL(0xa03a3a12,0xf8236198),L_(0x00000070), +}, +/* digit=58 base_pwr=2^290 */ +{ + LL(0x7663b161,0xc93f0cc5),LL(0x071af3d7,0x22d6ac11),LL(0xb9149bdc,0xe6312d84),LL(0xe44e4632,0xc50d4c88),LL(0xc448cc8e,0x6c85277a),LL(0xbfe4f89a,0x128700ea),LL(0xa38e5f2e,0xb742928e),LL(0x3e261880,0xbb296e29),L_(0x000001bb), LL(0xfa51028c,0x9b6a14e2),LL(0x09549191,0x82dfd5da),LL(0xe13022a3,0x233ca662),LL(0x96fafc24,0x505fe429),LL(0xa18dea4f,0x96182166),LL(0x15ea5a2d,0x199ba558),LL(0x22a4ac80,0x33772326),LL(0xb13c3b81,0x276d1311),L_(0x00000182), + LL(0x215bf15f,0x61cb09c8),LL(0xe5912a10,0xae2de789),LL(0xd84851c6,0xd74ceccc),LL(0xb95ccd21,0x6a285101),LL(0xd32dddf2,0x0122d3f6),LL(0xdb554921,0x02c5d952),LL(0x96a4aa1f,0xb24be997),LL(0x8cde88aa,0x7caeb407),L_(0x0000008d), LL(0x2cd753b8,0x88aff9b9),LL(0xcc49d782,0xf7cdce61),LL(0xdac4e445,0xfad48cc3),LL(0x0ac2a937,0x956fdfcb),LL(0x98c5bdda,0x81841ce2),LL(0x9f12bb3e,0x170e6c81),LL(0xcab58ad5,0x30efd73e),LL(0x76a3a481,0xabf3f0f4),L_(0x00000010), + LL(0x361c2c61,0xb9e4b6ab),LL(0x810de58e,0x3d0db7a6),LL(0xe085a8d1,0x45a31ec7),LL(0xa7bb9df2,0x35378c99),LL(0xd8933f30,0x186da525),LL(0x1033d24d,0xddb7a3b3),LL(0x8af19819,0xb5c9012c),LL(0x57d17203,0x722478c1),L_(0x0000002f), LL(0xce3ccda4,0x41697bbe),LL(0x5c6d7a27,0xb8be57fb),LL(0x1fba9fbf,0xc562ecca),LL(0x9a3fed12,0x1bcd8090),LL(0xf597a3fc,0x74a6954d),LL(0xce4e5ded,0xb4910fbc),LL(0xa5ed9cf8,0x79902452),LL(0x9c77346d,0x4ebfad77),L_(0x000001cf), + LL(0x3a4f332d,0x3d82a438),LL(0x56af6321,0x0fc06213),LL(0xca05acfd,0x8864ca32),LL(0xe80103ea,0xc2e9c7c1),LL(0x99dd0ff4,0x4c64b758),LL(0xc9889d76,0x80c128a8),LL(0x881a1256,0x77fdb7cd),LL(0xf09f58ad,0xf478aec5),L_(0x0000018c), LL(0xc6ecd4f9,0x41a633a8),LL(0xecb1fc4c,0x847c2f58),LL(0x92dae51a,0xa7d7b295),LL(0x268f50e3,0x3b5eef6e),LL(0x3a27de2a,0x0d7a599e),LL(0x14916d54,0xd01f9b57),LL(0x204fbca0,0x675e52e5),LL(0xeb48615c,0x50dac3d9),L_(0x0000019b), + LL(0x0a639042,0x0fd5737f),LL(0x31d2eb63,0x801bd86d),LL(0x85ffa7ea,0x1011c35d),LL(0x8d043e51,0x1ef5b87b),LL(0xcb405068,0xec30dbd9),LL(0xc20daf68,0xe48310c1),LL(0xcee24a41,0xa65b8aca),LL(0x119d1da9,0x4a04288e),L_(0x000000ec), LL(0x716e9def,0x8b2825b1),LL(0x5d82926b,0xb4cd0082),LL(0xe1a8a7c8,0x6474e309),LL(0x12620e3a,0xb0da6f90),LL(0x2d673d4a,0x574adf3d),LL(0x628b88b6,0xb210b971),LL(0x9d1b96a3,0x6b2d573e),LL(0xedcd56fc,0x8269ac81),L_(0x000000b1), + LL(0xe07f6e9e,0x0f0b6a27),LL(0xa4a6f307,0xddeaaa37),LL(0x9c430a1d,0xeacad6b5),LL(0x9620fd47,0x9a8128c0),LL(0xf279790d,0x3bf5952b),LL(0xfb97ad6f,0xe0561485),LL(0x0fe7692a,0x482c591f),LL(0xe268f3cb,0x8a7a037f),L_(0x0000013a), LL(0xdb21bfbb,0xde3dc674),LL(0xdbf154f3,0xf4401caa),LL(0x32e63083,0x462197d4),LL(0xb9452cf6,0x46240ddd),LL(0x10344368,0x1c6dbfe6),LL(0xa986f17f,0x94ccbb69),LL(0x4632a20c,0x3f6277d7),LL(0x33029382,0x0f710d97),L_(0x00000010), + LL(0x2b718a28,0xd8752e23),LL(0x65e87e31,0xa158249b),LL(0x88c3f123,0xff7b1118),LL(0xd9121432,0xbe4461fe),LL(0xa0850e4f,0x9ef5bc2d),LL(0x6350e71c,0xf28780a7),LL(0xc6dabd80,0xfc8f574b),LL(0xc3c266b1,0x7bb0ad43),L_(0x00000016), LL(0x13bf6ff9,0x7db218bc),LL(0x9d000699,0x0dec75e5),LL(0x7cf7628c,0xb95f2df4),LL(0x2fa7aacc,0xe8ff9a7d),LL(0x96555722,0x1076129b),LL(0xa11a1984,0x57afac1e),LL(0xfd1e9ec4,0x16d64a31),LL(0x008b70a7,0xf6e81632),L_(0x00000000), + LL(0xb0d9eaa8,0xf5caa2dd),LL(0xddc322f7,0xc31038c0),LL(0x08fb4b57,0xa651596a),LL(0xd9ca6980,0xab32e2a6),LL(0xc95c78a8,0xe5808eea),LL(0x5a32ba78,0xf5f9923d),LL(0x3bbece34,0x26ad1c8d),LL(0x8f8b8459,0x84189709),L_(0x000000ce), LL(0x16843645,0x8875d753),LL(0xa90e9fa2,0xe13608c5),LL(0xaf90c364,0x57e5556e),LL(0xcc40e058,0x9e332dda),LL(0x9c5012b5,0x2b76768f),LL(0x8a76230b,0x2932d53c),LL(0x573bdff3,0x14999fbd),LL(0xeee93001,0xdef0f840),L_(0x0000017d), + LL(0x1a3f60e5,0x7e88fc70),LL(0x29625c0d,0x396b1851),LL(0x610e5833,0x947ef062),LL(0xd8dd1f5d,0x47f1a571),LL(0xa0f65294,0x7850d950),LL(0x49f087e9,0x22c8e733),LL(0x18807434,0xce5508b2),LL(0xd0fc8fca,0x25125ea0),L_(0x00000121), LL(0xc3d1360f,0x69072d8a),LL(0x8b9d1e81,0x8cba6305),LL(0x01ed34a6,0x7a1a3844),LL(0xbc37f296,0x20c61572),LL(0xd409e84e,0xd54640e7),LL(0xeb6c948c,0xc9243fc3),LL(0xc754fba2,0xb39c9166),LL(0xc28f4f28,0x15bec182),L_(0x00000188), + LL(0x32c7f33f,0xa0e6751c),LL(0x47474b7e,0x7f265069),LL(0xe1e4a2ce,0x0460d889),LL(0xeab5839d,0xb51b9a7f),LL(0xe7cad388,0xa5032a25),LL(0x46ee855a,0x6621ee7b),LL(0x16fbfccf,0x5a6f1501),LL(0x73af1329,0xbadeb575),L_(0x000001f6), LL(0x694e09ae,0x0646542a),LL(0xaceb179f,0x27a867a4),LL(0xeb30df16,0x14cf3975),LL(0xf9d85fe3,0xa18e96b2),LL(0x37e6f97d,0x7781a0f2),LL(0xb09bd1ce,0xa8de0b13),LL(0x278a1089,0xc3a91cf5),LL(0x02296583,0x1b9593f9),L_(0x0000000e), + LL(0xeca2c791,0x86fe1661),LL(0xd1c18fea,0x4aedcbc7),LL(0x3f879f46,0x0545d544),LL(0x4cb96993,0x95120a10),LL(0x595026f4,0x1d335198),LL(0xc959c824,0xa814ec2a),LL(0x8fbede3e,0x0e062b6d),LL(0x3832b5b2,0x6bbcce86),L_(0x0000017b), LL(0xfad2bbc3,0xcf89249c),LL(0xf01f3803,0x63266c42),LL(0xb86898e0,0x685db0a5),LL(0x3becca8e,0x7e4eaa63),LL(0x3ec31fe1,0x90fcf86c),LL(0x394a64f7,0x967f0628),LL(0xc6f81bcd,0x635c81b7),LL(0xec462896,0xb8022758),L_(0x000000f1), + LL(0x67236236,0x67484461),LL(0xdb36fbe6,0x5f5c47c0),LL(0x9fb54024,0x71f2fbb3),LL(0x44525a78,0xbedf63e3),LL(0xe71375bd,0x9f085fb8),LL(0x47d50bd8,0x1c59b6e6),LL(0x2f2ea430,0x578031fa),LL(0x58012b66,0xd2034d9b),L_(0x0000007e), LL(0x473015fd,0xfde2151d),LL(0x9616e82c,0xe4d908c9),LL(0xd4ec3b2f,0x04a04977),LL(0x13df9ad2,0x3ee923f5),LL(0x2b66641e,0x175bb5d9),LL(0x0fcd9df2,0xcdb5c3c9),LL(0xfac57254,0x7fde8809),LL(0xc6981a62,0xd951b985),L_(0x00000091), + LL(0xb19296e9,0x9d659d99),LL(0x6d5aa5b9,0x489a28d9),LL(0x5422e69c,0x5cf35829),LL(0x06993c4a,0xed0dce41),LL(0x4bccea69,0x21d11ff6),LL(0xa2e82c7c,0x44f73388),LL(0xda3168f8,0xf6117d7c),LL(0xdff018c7,0x0454467f),L_(0x00000112), LL(0xeb022661,0xe965ba34),LL(0xfeff852b,0x1a68518b),LL(0xbe9a9ee4,0x53aa84d0),LL(0x31f46a2c,0x112327ea),LL(0x6855b874,0x06311411),LL(0x43d26e75,0x7348f329),LL(0x65628948,0x0582ac08),LL(0xe3244339,0x44f3001a),L_(0x00000184), + LL(0x5a842868,0x12b97327),LL(0xd4a2fefb,0x8f7a410f),LL(0x84c0e584,0x98e19862),LL(0x3fbe93da,0xe566e4f8),LL(0xe44a9540,0xec1d03a0),LL(0xa377131e,0x1b99313e),LL(0x27336d2c,0xc15f4f38),LL(0x8c27d958,0xeeef149e),L_(0x000001b6), LL(0xe75811d3,0xc54aa0e8),LL(0xe1cbcf6b,0xc195aaf4),LL(0x5596682f,0xe98a5845),LL(0xe0cf229c,0x70256db2),LL(0x5a921b26,0x10d830e7),LL(0x37fc26fd,0xe3def649),LL(0x16a810c8,0xdb834a77),LL(0x613433c1,0x71908e34),L_(0x000000f8), + LL(0x7624b24b,0x7db58054),LL(0xabebbd07,0x20618f15),LL(0x3a5e2752,0x72097df2),LL(0x4f72e3fd,0xf79b4cba),LL(0x6f03686a,0x3cfd9643),LL(0x2d89778e,0x683c4a14),LL(0xeade01a4,0x7cca2771),LL(0x533fd14a,0x7a145968),L_(0x000001b1), LL(0x5f84ba35,0xb97b68e1),LL(0x4e0b9bd1,0x6e47fe3d),LL(0xcdba9cfa,0x3026f026),LL(0x6e415889,0x057de03a),LL(0x7c12c31f,0xa54231cf),LL(0xcdfae481,0x68a6cb37),LL(0x3908080c,0x259ee9d4),LL(0xa3c797b1,0x5a90709c),L_(0x00000030), + LL(0x021a0d91,0xd49fbe57),LL(0xde5b21b0,0xbb57b277),LL(0x7291e7e7,0x1e6a4b2d),LL(0x16da29ce,0x4426f88c),LL(0x68f8b71f,0x6a6ebaff),LL(0x9995fbf7,0xab510adb),LL(0x6ec18d2c,0x8d4b996a),LL(0x3ce11f1f,0x0c8233bc),L_(0x0000004b), LL(0x8e04c405,0x34703d79),LL(0x6b0a33af,0xdd55e68b),LL(0xb14161e8,0x4737f09c),LL(0x57558d9c,0x90c00b53),LL(0x9d9a485a,0x508e73fc),LL(0xbb09dac2,0xd252e5f5),LL(0x4ba2132e,0x33b1efcb),LL(0xc58bf239,0x43e79593),L_(0x00000026), +}, +/* digit=59 base_pwr=2^295 */ +{ + LL(0x5b781a84,0x584291d5),LL(0x6ea73ad7,0x992c0a26),LL(0x20e9954c,0x169e02af),LL(0x4d73d175,0x2718e0ca),LL(0xe1612ee1,0xed50926d),LL(0xc638cf1d,0xc1060d91),LL(0xb5998df8,0x4b7dc332),LL(0x4eb7dc88,0x46da4262),L_(0x00000157), LL(0xd78eae21,0xa9f4bf2c),LL(0x372725c2,0x86c74c6b),LL(0xb5b5158f,0x736a4de4),LL(0xba4800d6,0x451f4693),LL(0x5138590e,0xd2239cb9),LL(0x6f5d263e,0x45bdc4c5),LL(0xc0f8acf5,0xd06676d4),LL(0x8bbd0743,0xbe979403),L_(0x00000155), + LL(0x714fe80d,0x2da244cb),LL(0x06f04145,0xcda8b722),LL(0x84ee9fa6,0xc3d58870),LL(0x0e111da7,0x1c267392),LL(0x53bb35ef,0x906e57c4),LL(0x6a858e61,0x3eebaa20),LL(0xf4582387,0x20dd3b5b),LL(0xcf71c4a7,0x82d3b15d),L_(0x00000009), LL(0x91605cdd,0xe98756fb),LL(0xcda7aac0,0xf0286c4c),LL(0xb4372718,0xa4017819),LL(0xdae0a5d8,0x21935131),LL(0x0720f8cb,0x261dafa4),LL(0x40e03217,0x6fb18c8c),LL(0x34851940,0xcd3c7d48),LL(0xe02770ca,0xc52abd46),L_(0x00000103), + LL(0x826415dc,0xaee30325),LL(0xe70ecca1,0x8395cad3),LL(0x053fd2fe,0x148ed662),LL(0x3520779d,0xad7a6345),LL(0xc9cad78e,0x02a99616),LL(0xb2b3d15b,0xa5bc3102),LL(0x9cfe5a4d,0x4cc19d74),LL(0x59fc0a6f,0xd407b106),L_(0x00000075), LL(0x3a1ba1c9,0x487fa3ac),LL(0xb4dfc9f7,0xe0d152d8),LL(0xf699a6f5,0x8f345525),LL(0x20633fdf,0x76ba6839),LL(0xca7d8a08,0x2bd4f59f),LL(0x88585003,0x05078df0),LL(0xcface355,0x01da05b9),LL(0xfd2eb0a9,0x05a56ca7),L_(0x0000007e), + LL(0x52b16ebe,0xf47e5b46),LL(0xe6ae36e7,0x71c81701),LL(0xe3a4cc33,0x1ae7f8d6),LL(0xb29431c3,0xaeb29c67),LL(0xb869125f,0xe16be2af),LL(0x052cfd62,0x934ce6d0),LL(0x10638824,0xe1cd7490),LL(0x2b021800,0xede192e6),L_(0x000000ac), LL(0x53a39e35,0x21f34b32),LL(0xaa3b5761,0xd9c36b4a),LL(0x2e0442ed,0x419b2399),LL(0xd2725144,0x4d374723),LL(0x0ced8d6e,0x6d58a708),LL(0x1b1f1118,0x0cd63ed1),LL(0xd7a4d0b5,0xf4c6faa6),LL(0x9c897561,0x53bcb255),L_(0x00000047), + LL(0x0cb3fdd3,0x8e8db5d1),LL(0xaee5321b,0x87aea4fe),LL(0x3857736e,0x16711165),LL(0x0c1ddf85,0x0fefea55),LL(0x5866facc,0xf4b819a9),LL(0x33eac999,0xde7464eb),LL(0x2a31e0a7,0x4f70e413),LL(0x152ce312,0xfbd1795a),L_(0x00000194), LL(0xbf9b85c5,0xba27db9c),LL(0x153c54c7,0x65beb177),LL(0x0c1db955,0x38a15bc3),LL(0x12ad15c1,0x1bbf7edd),LL(0x99f39d44,0x0cddc300),LL(0x017014dd,0x7ea43a2c),LL(0x2d23d878,0xbec5a12d),LL(0x5eda0b7d,0x53c1c755),L_(0x00000156), + LL(0x06657d80,0xd29c3627),LL(0x8365a95f,0xe70b9e02),LL(0x084d6b18,0xc68fa40d),LL(0x80bbbcfe,0xae56df9d),LL(0x8a06728a,0xb6253373),LL(0xbd4a361e,0xc77e1c92),LL(0xd3c11b1d,0xa94fbeef),LL(0xa52dffaf,0xca64acfb),L_(0x000000c8), LL(0xf19acb1f,0xe668d3f2),LL(0x23cbf024,0x095d2d5d),LL(0x7f105b84,0x89f76b69),LL(0x5b550d74,0xe73345da),LL(0xbc9d3a15,0xd2b26a8f),LL(0xd6a293e0,0xe4494adf),LL(0xe0387451,0x818e6417),LL(0xb0518331,0x48fe9fb0),L_(0x00000001), + LL(0x4d2a42df,0x808fa6d8),LL(0x68651170,0x445f0d4b),LL(0xec0d410c,0xc6980698),LL(0x1ad2d890,0x005f7ee7),LL(0xbcda7089,0xa7d283e2),LL(0xf5b48062,0xcee64fee),LL(0x0051a180,0x73e72ad4),LL(0x848f7b7c,0x9759cdbe),L_(0x00000137), LL(0x690a81c3,0x3ce8b5c2),LL(0xac33d774,0x15e254f0),LL(0xa423baea,0x948fbc87),LL(0x2fe89ca2,0x80cdde65),LL(0x9a165eb6,0xb1b05690),LL(0x1c84102d,0xc135f5d4),LL(0x73f34a94,0xc61329b0),LL(0x8ced1268,0x2e0d7d89),L_(0x000001f4), + LL(0x9713685f,0x93a123f3),LL(0x6ef5a591,0xf28bae61),LL(0x67b33050,0xda7d2c65),LL(0xae5b6596,0x59fc9e4d),LL(0x0481adbd,0x18dde4a4),LL(0x2fe92c16,0xf2a19468),LL(0x5adc0431,0xeac05bc1),LL(0xdb30fcce,0x7e2cf13e),L_(0x000001dc), LL(0xee47d7a2,0x4cf35b8d),LL(0xc425ee95,0x74908606),LL(0xcdac359e,0x22c94a88),LL(0xef2c8586,0x10d20bfb),LL(0x8d0f7458,0x1ca77f65),LL(0x426741d7,0x82f59f1e),LL(0x640314c7,0x294af36c),LL(0xec0709c8,0x18dd5e35),L_(0x00000120), + LL(0x1e52ac8f,0x0894401e),LL(0x36abe923,0x9f482e3b),LL(0x81ce378a,0x32d1efaf),LL(0xae954687,0x62ff86e1),LL(0xd9afd8e0,0x085da5ec),LL(0x5871a105,0xd026254f),LL(0xe7a32717,0x83b4a648),LL(0x40288d2e,0x8d29644b),L_(0x00000197), LL(0xb0b6dc10,0xa8898440),LL(0x699ececa,0xe53262d1),LL(0xdf9ba3e4,0xdb180197),LL(0xa82e89ff,0x786042aa),LL(0x97af8b17,0x663faa6b),LL(0x00b45e0a,0xf346c12e),LL(0x03c76f2d,0xe8ec3f00),LL(0xbda1be57,0xf05e51a3),L_(0x00000078), + LL(0x55c5c739,0xfcd89a8d),LL(0xc0dcdb75,0x71a4d047),LL(0xd498ccfb,0x8baef9a3),LL(0x669e7edb,0x20d8ae8f),LL(0x98d6b13c,0xd16a48c7),LL(0x3f4ca564,0x50d24170),LL(0x509f9dc2,0x8c680ef9),LL(0xb2c17a38,0x29830970),L_(0x000001e1), LL(0x23778808,0xe8d8d33c),LL(0x9dd269ab,0x9bd2fb18),LL(0x1e8769b1,0x62b11258),LL(0x657bacd6,0x8521c19d),LL(0x584fbcaa,0x46adc05d),LL(0xe93891c5,0x68fad3f4),LL(0x8617aebc,0x0857bce7),LL(0xe39a4226,0x50c3c701),L_(0x00000128), + LL(0x17cc51bf,0x6d70f113),LL(0x546beb5c,0xc94a2150),LL(0x62ee8e73,0x3d11d590),LL(0x255999c7,0x8c21f26b),LL(0x42e22a6e,0x3732f418),LL(0xb9e01e7a,0x910608f5),LL(0xea10cdc0,0xef7f9669),LL(0xf54f17b3,0x271d06b5),L_(0x000001f9), LL(0xe994f9cf,0x5a87a958),LL(0xe54c87e2,0x6e7d0b5e),LL(0xa8cc0493,0xb0873928),LL(0x837b814a,0x92c0806c),LL(0x1e804d39,0x8cb9df2c),LL(0x1d8a5f76,0x2377456b),LL(0x33c3155b,0xe6d63e09),LL(0x55cb5f9c,0x572ecf1e),L_(0x00000107), + LL(0xcfd79f62,0xc5d103b9),LL(0x295548e9,0x71b65a58),LL(0xb8462f3d,0x40934991),LL(0x1453c2b2,0x41c087b5),LL(0x1cf62fb3,0x37eea50d),LL(0x02ab6cdb,0x7ada571b),LL(0x1b49b692,0xda9e677d),LL(0xb52dc4d6,0x1d635004),L_(0x0000009f), LL(0x2e42f171,0xb6cceda3),LL(0xdbcc6765,0x09960889),LL(0x2e336d9f,0xe5440e8e),LL(0x34cefd7d,0xb410a81f),LL(0xd8bc6b5a,0x91782d60),LL(0x46d80cbb,0x95e22f30),LL(0xc99291ea,0x9e775cf7),LL(0xca473be0,0x73ab5282),L_(0x00000170), + LL(0x06ac0186,0xbd98b833),LL(0xdc7e7944,0xae0a1564),LL(0x0b94fb31,0x8b85aba8),LL(0xfd0db6b7,0x3fa21f5d),LL(0xbb92a7c4,0x7133a3ce),LL(0xfc2b2cf0,0xd39f3731),LL(0xb63fc2cb,0x376e5f1f),LL(0x4d89e9a6,0x3c36dece),L_(0x00000199), LL(0xe98c5f25,0x2178e890),LL(0x51c9207d,0x1be32aa0),LL(0x8d2cb6c8,0x629881ee),LL(0xdb210410,0xe3099a6e),LL(0xfd24a488,0x62aff70d),LL(0x6e705a1e,0xb843d997),LL(0x41319b69,0x8bfa95c3),LL(0xd9b9376a,0x9990510b),L_(0x00000032), + LL(0xc2b6a03b,0xfefa851e),LL(0x0a7bf6b7,0x3a92f668),LL(0xbf4905c0,0xe8a75dea),LL(0xff483a6a,0x78467396),LL(0xdc163b2b,0x8999b6fb),LL(0x8968be09,0xc4a53538),LL(0x419a12c9,0x40b8e919),LL(0xd87c8896,0xc3d8cb0b),L_(0x00000147), LL(0x68f69e36,0x5971b3c8),LL(0x53ea08fc,0xbd601db4),LL(0x0ff01a96,0xa72aee96),LL(0x347158b6,0xef1dc3a0),LL(0xc8994151,0xb70d9ea4),LL(0x39937de4,0xa2906842),LL(0x73a17885,0x1ae4276c),LL(0x34f8bee7,0x73c8f8a8),L_(0x00000103), + LL(0x7fdb683d,0x5075fbb5),LL(0x35997d35,0x4f7513bc),LL(0xb65dda5b,0xcca089f1),LL(0x0e8d30ed,0xf394427e),LL(0x66ecf608,0x7394ebe5),LL(0x80d0cb61,0x2babf408),LL(0x9903b671,0xb8208316),LL(0xe416cdcf,0xb4a46cb6),L_(0x000001fc), LL(0x26090ace,0x026550ab),LL(0xf1bd714b,0xceedda36),LL(0xd83c3071,0x6a6fe427),LL(0x5704c9b9,0x9e328311),LL(0xa3fbc241,0xfceb37ff),LL(0xf54b88ee,0x2f82304a),LL(0xb6315a8d,0x77a230c7),LL(0xeda8682e,0xb1bd2d77),L_(0x000001e3), + LL(0x5759366b,0xabadb724),LL(0x75b84d60,0x87caf5b9),LL(0x983f793d,0x1cecc3f1),LL(0x94d8de54,0xd8885c2e),LL(0xf90b687c,0xd952f2ac),LL(0xd5046b6c,0x16cc05b6),LL(0x266e5bb0,0x52f97cdb),LL(0x5959c784,0x417167c9),L_(0x000000e1), LL(0x931e70e0,0xc8989bfc),LL(0x36663528,0xc244410e),LL(0xf14f2667,0xbca645d5),LL(0xf8059cc8,0x1c94e08c),LL(0x1d2134f7,0x1d1a84e9),LL(0x3489ba7b,0x21c35b98),LL(0xdddbab1e,0xa303bfc5),LL(0x86156a8f,0xa3ec6998),L_(0x000001df), +}, +/* digit=60 base_pwr=2^300 */ +{ + LL(0xec83fd79,0x9640b910),LL(0x5166dc54,0x1f3c076c),LL(0x553ff932,0x6d2b7e4e),LL(0x7e2f7e67,0x097c11e9),LL(0xaa2cdad5,0xc5cedff5),LL(0x397f4bc0,0x57d09eef),LL(0x8d95f667,0xe7743495),LL(0xe32eada9,0x34e574ee),L_(0x000000d6), LL(0xe641f85b,0xa0e3496c),LL(0xa6b773ab,0x7931548e),LL(0x3aecbf5b,0x2ef14927),LL(0x58c42c5d,0x1528b818),LL(0xfddc70d9,0x1c157c1e),LL(0x0a328d34,0x690e10df),LL(0x0760fd8a,0xa364f5d3),LL(0x4ec3b44e,0x0d06d0d1),L_(0x0000007e), + LL(0xb187f011,0x26f1e48d),LL(0xb62010d1,0x0d05c4b7),LL(0xe0fbe5e8,0x3f0a2ba1),LL(0x24d802f1,0x189e9602),LL(0xde0b8698,0xc0b8af43),LL(0x28591b4b,0x706b742b),LL(0x36bf7aec,0x63d91963),LL(0xec0d2fd3,0x576d907f),L_(0x000000ae), LL(0x440b0b6c,0xe982e3e2),LL(0xd99d67cd,0xd814a6fa),LL(0x7edfbb4d,0x4ac7d349),LL(0x46c6afc8,0x63bbd77a),LL(0x84cd907a,0x18bcc3d6),LL(0xf098909a,0x756b5193),LL(0xd6e0581d,0x02f37ab5),LL(0x06adf4d1,0x2f363ffb),L_(0x000001ce), + LL(0xe90415e4,0x6bd8544c),LL(0xc664d2f1,0x3e7600d6),LL(0x01912f05,0x1e8d9aa4),LL(0x3e0c268e,0x43dcdadd),LL(0x2f140134,0xbf936e21),LL(0x252cf59c,0xb8aaec39),LL(0x00b8cef4,0x7ed652c2),LL(0xc64c11e4,0x639c50aa),L_(0x000001e9), LL(0xa7c08e2e,0x59176893),LL(0xafe8a484,0xc7c5a8f0),LL(0x6f043d0d,0xe33e999b),LL(0xb3c3cfd6,0x2a496c00),LL(0xcb4fbc5e,0xe2690de5),LL(0x1dfaf5ee,0x3d2db451),LL(0x743e9277,0x8bfecdd2),LL(0xade6a194,0x5bfc14f4),L_(0x000000f4), + LL(0x8d039609,0x488fdf25),LL(0x1e037339,0x0e39945a),LL(0x4d16fa60,0xf539a844),LL(0x54408c23,0xf7f8ccc4),LL(0xbef729fb,0x69b8abc6),LL(0x76661fe3,0x3dbd87a4),LL(0xa8903415,0x790f6266),LL(0xc7b4bcd2,0xbe422de3),L_(0x00000195), LL(0xa406e205,0xce1af477),LL(0x72e7763c,0xf7fcf645),LL(0x43d00999,0x1f7c9317),LL(0x02adccdc,0x8b87a139),LL(0x541be26f,0x9ffcb96f),LL(0xbb590677,0xc0636264),LL(0xc0db1d61,0x19484331),LL(0x5585c8ae,0x3548f76e),L_(0x000001d9), + LL(0xe85899b3,0x5fff92e2),LL(0xb4a44f31,0xa8cf599e),LL(0xca1a3e87,0x17a2e4cf),LL(0x205f34e2,0xe4f28f3f),LL(0xe9eb1362,0x4aa7c205),LL(0x6ace61c8,0xfa76515b),LL(0x7e550586,0xec83aca3),LL(0x35e870f8,0x982b8304),L_(0x000000ef), LL(0x2e02203e,0x318327d4),LL(0x004d9655,0x5d903904),LL(0x7cd1d2f1,0x9d294adb),LL(0xca1242c8,0x3b5bb4eb),LL(0x4af2a142,0x93818e82),LL(0x15e366f3,0x9a304441),LL(0xd6a53de7,0x49183b2c),LL(0xfd324d82,0x27bcf47b),L_(0x000001a2), + LL(0x4d1ee196,0xa1d04903),LL(0xe53d6718,0xacaf386a),LL(0x6605e4e6,0xcc306d74),LL(0x458e136f,0x77dc40c4),LL(0xab7a1ac6,0xbb331955),LL(0xd47f6ee4,0xb95c386e),LL(0x43841037,0x526640fb),LL(0x00a37bb7,0x59e53810),L_(0x000001b6), LL(0x8b8cc55b,0x71d84cd7),LL(0xe7e03251,0x1b8eb12e),LL(0x64c45f59,0x2d7bd8c5),LL(0xc2283df1,0xb03bfc76),LL(0x28a36461,0xafd6fc81),LL(0xa0580c8c,0xe72b6275),LL(0x511c376a,0xce438282),LL(0x0ca3213f,0x379b6878),L_(0x0000011e), + LL(0x1e2c0f6f,0x17179cb8),LL(0x0810156c,0xaf140db0),LL(0x63cd1fa8,0x2171bb5e),LL(0x729533d8,0x544c77b0),LL(0xf6676827,0x0143af56),LL(0x599efe1b,0x5a759df2),LL(0x3accffd4,0x55962b59),LL(0xc61321e5,0x795b77a3),L_(0x0000006a), LL(0x66e58a6a,0xbb4d42d5),LL(0xe0cfd739,0xe6ef3760),LL(0x0620ef46,0x6804fb37),LL(0x253e0f9e,0xf4e9cdc2),LL(0xcb5c8c64,0xec6f6658),LL(0xa80d08da,0x04153037),LL(0xcc959be5,0x3d215b47),LL(0x7aaaa865,0x6b1b8e4e),L_(0x0000014a), + LL(0xf52bc233,0x9700029a),LL(0x2a837019,0x3201dddf),LL(0xd02e2c74,0xd8885cda),LL(0xaea6cd36,0x7e35126d),LL(0xbc3f784e,0xfa40cea6),LL(0x5130e882,0xeec16a3a),LL(0xace2f121,0x13c43706),LL(0xf3c3a16a,0xc703c9cc),L_(0x0000002c), LL(0xc964823f,0xe8e4729a),LL(0xeed8d7ba,0x3fe54edf),LL(0xcfba42bd,0xec6a4e7b),LL(0xe917bf88,0x06be2039),LL(0x604163c6,0x17d5a63a),LL(0x6bdf09b0,0x276869bd),LL(0xf021410c,0x4b94144f),LL(0xf038cdd9,0xf4d84a13),L_(0x0000013c), + LL(0xeb8a6d24,0x724db1ba),LL(0x545ff43f,0x850f42b2),LL(0xfcaf8079,0x5c1fdccc),LL(0xde18c209,0x57404da7),LL(0x83097de7,0x267842f8),LL(0x8706015d,0xab9a893d),LL(0xe62c08dd,0xe2b0c7a0),LL(0x736bf358,0x34fb3742),L_(0x000001e1), LL(0x535f7766,0x4779dd4d),LL(0x10a98c32,0xc095243e),LL(0x0e7bc245,0x3cd82df8),LL(0x5fac69de,0x59efca16),LL(0xa2f0af19,0x692e1ddd),LL(0x40c91226,0x9b21f9d2),LL(0xa682e04c,0xa51cafc2),LL(0x831c0e79,0x9830cc49),L_(0x0000004a), + LL(0x94e4798e,0x00af5508),LL(0x9afdccb8,0x987426d2),LL(0x0f5f64d2,0x4aaeb57e),LL(0x76899b88,0x9a8859b4),LL(0xcf38ab59,0x31a64817),LL(0x8dc36916,0x9b757c1f),LL(0x28b27539,0xfb6a189c),LL(0xc63802b8,0x03d47dba),L_(0x000000c2), LL(0x225f33e4,0x9d6bb39a),LL(0x880025e5,0xffb62ebd),LL(0xb7d05691,0x6aacd544),LL(0x3e434b4f,0xba8454f9),LL(0x4bc06244,0xbe5d3fe0),LL(0x941bd419,0x6732d1a1),LL(0x6794ada7,0x6efab77e),LL(0x1058a767,0xf531c68b),L_(0x00000132), + LL(0xe58d6aac,0x5f7430b9),LL(0xb9ab109f,0xedf696b8),LL(0x252205ff,0x65163bdb),LL(0xb3a47496,0xfd8eca02),LL(0x915f0458,0x6d6b0ec4),LL(0xb0096e8b,0xddddf89f),LL(0x874c9e5e,0xab9c669c),LL(0x156cfc6b,0x83d55b9a),L_(0x000000fa), LL(0x8c6752e9,0xc103803a),LL(0x0196650f,0x653fb161),LL(0xe597cf0d,0xa211c0cf),LL(0x66902c1d,0x126bc8cd),LL(0xff4436dc,0x502c8df4),LL(0xcf0ef89e,0x30d9c137),LL(0xadabc266,0x509eb349),LL(0xcbdaa030,0xa426a8ae),L_(0x00000101), + LL(0x9d067e75,0x0846b23b),LL(0xb348d35d,0x6044d60f),LL(0x4e0c74fc,0x4437fb47),LL(0x2124f846,0xc898c89a),LL(0x30abdb7d,0xa1ecdf1d),LL(0x496e747c,0x09be44bd),LL(0x9381d368,0x6a34a28e),LL(0x2cd1e7c2,0xdcbc2c2c),L_(0x00000101), LL(0xece95ae5,0x705df30c),LL(0x08cdb28f,0x8f6f90ca),LL(0x15b2caca,0xdb9f29f0),LL(0xf8e2597f,0x537c5e8b),LL(0x91e195ad,0xa54bf828),LL(0x1ef3bc47,0x5f5b1233),LL(0x6c98e99d,0x096c5cfe),LL(0x0acf39b3,0x88fd1f55),L_(0x00000043), + LL(0x5e49ea9e,0x8278d27c),LL(0x1462a5cf,0xb6b188b1),LL(0xd1c3e723,0x7adfe4be),LL(0x9f4ab12b,0x4f74656e),LL(0x86f9e399,0x15f9fd6f),LL(0x647aabe4,0x356f176c),LL(0xdc05df56,0x037f39e8),LL(0x6f8c9681,0xc0c1a4ab),L_(0x000001cf), LL(0xfd586565,0x4f9b62dd),LL(0x9a07decc,0x07d1665c),LL(0xb14d451c,0xb6af032b),LL(0x2d75e1e7,0x7c7044cc),LL(0xac2df8ec,0xcac8a69f),LL(0x0906e20d,0x20c70582),LL(0xa4167466,0x1ca47052),LL(0x6fe2b8c1,0x576c602e),L_(0x000000ff), + LL(0xfb8bf3d9,0xcaac45d1),LL(0x39bf904a,0x4d2bf532),LL(0xa7f1203e,0xa3246448),LL(0x9ecdf560,0x6d3940b2),LL(0xa6d3b3a3,0x89bdcf57),LL(0x40dcc76f,0xdcc95c73),LL(0x9fa5791b,0xa442ea24),LL(0xc94b40b3,0x4596aafd),L_(0x00000184), LL(0x8473e7d8,0xbc97c4e6),LL(0xe17e4cb3,0x8daa65ee),LL(0x1d315fc6,0x20c6ff94),LL(0xeaec9cae,0x74f3ffd6),LL(0x1b61c251,0x015f6f88),LL(0x6a1cf873,0xee694708),LL(0xd187e0b9,0x37da53ba),LL(0x332ba61a,0x7b15c4b9),L_(0x0000017f), + LL(0x409292b4,0x27a8575f),LL(0x23606aaf,0xeb1afe84),LL(0x6df6bd82,0x546ebac4),LL(0xd77cd802,0xd19a6a0e),LL(0x9ac38a98,0x701bcf92),LL(0xae1c0504,0xd6247bc1),LL(0x90bada7a,0x7a406e08),LL(0xcc3c49ab,0x75a3d1ac),L_(0x00000089), LL(0x5dcf7e44,0x5f7352bf),LL(0x2b674d19,0x0ee31d4e),LL(0x35a3e68d,0x92916c56),LL(0x5e153a5d,0x1bbba324),LL(0xa3d55e06,0x27d3691c),LL(0x74f6e553,0xa9153a98),LL(0x2c8a7473,0x6e737b68),LL(0x545acbac,0x0b3ed514),L_(0x00000035), + LL(0x892f8bd1,0x31776371),LL(0x6c0b1d4f,0x60a2c8b1),LL(0x9a688a19,0xa0d12ea4),LL(0x56eef3ec,0x4746c345),LL(0x90c83381,0x842db71e),LL(0x3fdb8d8b,0x1bf4ae9e),LL(0xbc576b9b,0x9e0ee706),LL(0x85a8de64,0x3528254e),L_(0x000000e8), LL(0x3c32799b,0x25980592),LL(0xc4760975,0x76f95241),LL(0xd6c8d637,0xdd3d3b18),LL(0x677dee0d,0xe5bceafa),LL(0x12ad9334,0x7ca46478),LL(0x3990ceb2,0x94d56dac),LL(0x39d6e555,0x8e338deb),LL(0x7a9d83d7,0x33dbf96c),L_(0x0000013e), +}, +/* digit=61 base_pwr=2^305 */ +{ + LL(0x52d7b490,0x4215e0ae),LL(0x3a781f13,0x84df8cb3),LL(0xaf858985,0xc3ab10bf),LL(0x449e13a9,0xea1a4d65),LL(0xb859368b,0x2c8134df),LL(0xb51fd78c,0xa7d94439),LL(0x4b1e6f5b,0x003f1c75),LL(0x4cf5d47b,0x6428ed46),L_(0x00000029), LL(0x6dc28640,0xd6597a8e),LL(0xe3d2ac15,0xe5e853fb),LL(0x8bd192da,0xf804c989),LL(0x76032d13,0xdb66ee3c),LL(0x738d5e8b,0x349bcb16),LL(0xe16c7ea1,0xe4001679),LL(0xd22ec201,0x82f1f584),LL(0xd9f317a9,0xb67757b7),L_(0x00000079), + LL(0xec0a67f0,0x2efbca10),LL(0x3767ee14,0xcc433a34),LL(0x68131944,0x370f6b9e),LL(0x36fcc884,0xb4d1b5e8),LL(0x85328231,0x85b956e6),LL(0x3e4b895d,0x17afd7ce),LL(0x23cd96a1,0xfc28a48e),LL(0x6cbf1cc4,0xfc04d775),L_(0x00000125), LL(0x5cc45bb9,0x4201b856),LL(0xbec2c277,0xb4f52020),LL(0xcd76ab62,0x3aabda65),LL(0x2fb221ac,0xd348e9ae),LL(0xb7ba962f,0x81d5e875),LL(0xacdde7c3,0x8ae119ed),LL(0x7186eb96,0xd5b495d5),LL(0xdf795bd0,0x1bbdd56f),L_(0x0000011a), + LL(0xabe42367,0x83477d80),LL(0xae655393,0x9bf84781),LL(0xf1389d3f,0x50d527ea),LL(0x02ffac63,0x30005241),LL(0x5a3b0583,0x332af83e),LL(0x30a51cf3,0xd633aac0),LL(0x7e87b5f6,0x6133508c),LL(0x54cf5544,0xae4be94e),L_(0x00000153), LL(0x79f352eb,0x3d5e304a),LL(0xc8a8525e,0x673478be),LL(0xcd082890,0x65272acf),LL(0x6528a7ef,0x07746b44),LL(0x6120a7a6,0xaa126f2d),LL(0xed8dc8aa,0x0714c411),LL(0x242ecc1e,0x09219322),LL(0x4dd29b99,0xf4c3776f),L_(0x000001bb), + LL(0x9d1e3e79,0x6e1c349e),LL(0x7cb862d6,0x411c782a),LL(0x774f6f73,0xf914b067),LL(0xd88b7029,0xbe145ff3),LL(0x68ac9342,0x0730a2fc),LL(0x77dcfba1,0x7ace014c),LL(0xe34f0621,0x876ebecf),LL(0xb7a85b90,0xa9ebdf04),L_(0x0000005e), LL(0x2be45d39,0x2af68cfe),LL(0xeda14612,0xbeab553a),LL(0xc8cf47bb,0x185338ec),LL(0x9f26575d,0xbcf5707a),LL(0x2dafc93e,0x9b4f2615),LL(0x85006b56,0x1c517096),LL(0x58e4408a,0x2759575a),LL(0xa451b6b3,0x3b494d43),L_(0x000001b3), + LL(0x64081168,0x9fca1732),LL(0x9e2e68b9,0xc2ec6027),LL(0xbd01c53b,0xcf8e3aa9),LL(0x3c299cf0,0xc31ff566),LL(0x69a934da,0x3a869b7d),LL(0xee4c3bf3,0x17fb711a),LL(0xe353eab9,0xb5b7fc05),LL(0xd300c851,0x0ef4f1da),L_(0x00000006), LL(0x7326c782,0xf868e4b0),LL(0x7616e981,0x9cbec832),LL(0x0d0b19fb,0x0355a1b8),LL(0x7504ef78,0x9b3d9f50),LL(0x75e429da,0x0924def0),LL(0x130ecd97,0x07187605),LL(0x844d6f96,0x7c14ae9f),LL(0x8921d3a7,0xccff1a1b),L_(0x0000016c), + LL(0x9415e0cc,0xdd321662),LL(0x7be013aa,0xad261af9),LL(0x46c47707,0xedc263d9),LL(0xabc20130,0x2f265a39),LL(0xe142f5b7,0xcfeec142),LL(0x90dba064,0xa08536a7),LL(0x488a0175,0x6d419631),LL(0xcf748207,0xe8415c3f),L_(0x000000dd), LL(0x6def509f,0x7ce6774c),LL(0x4af30ccf,0x09bc7469),LL(0x3bf7cbb3,0x12464f68),LL(0x648dc8e6,0x93c3b96f),LL(0xb39085a1,0x1000d207),LL(0xe4a3e7cf,0xcb93a762),LL(0x39e62f3d,0x08cde0be),LL(0xd6284f5b,0x8545da92),L_(0x000000b3), + LL(0x4fd9fb1f,0x0a484ffb),LL(0x4a91b446,0x5c5120d6),LL(0xcfe786b3,0x521a227a),LL(0x1f347861,0xb4d52b1b),LL(0x005afae4,0x28a0b22b),LL(0xaed64316,0x96565ad0),LL(0xcf8e1f9b,0x3bd3818c),LL(0xd717a7fd,0xea3705d7),L_(0x0000019d), LL(0x17132d83,0x4d75e2a9),LL(0xf9bc8f55,0xbaf9947b),LL(0x91f937e7,0xcb9bb75f),LL(0x232e92ab,0x4c1c8f93),LL(0x92cbf962,0x90cd09cd),LL(0xf2dcee1e,0x07dbfe55),LL(0xb89e680d,0xc41cd340),LL(0x51007568,0xa6275fb3),L_(0x000001e0), + LL(0xb831eea8,0x9b33eda2),LL(0xdd1ac75a,0xccb42fd2),LL(0xe55769fc,0xa865ab8f),LL(0x2ea2c9e4,0xc60208ee),LL(0x28effb93,0x321dff3f),LL(0x2d6b1522,0x5124fb78),LL(0x6e29dc3e,0x4cf961e9),LL(0x2f39193c,0x554efa6d),L_(0x000000ca), LL(0x035e63b7,0x67da851f),LL(0x7e9f39d6,0x7183aa79),LL(0xe886c75f,0x4aa59f9f),LL(0x6d9e6857,0x706045d9),LL(0x2ee25277,0xb18ceb8f),LL(0xe4bcaa94,0x5bc3971a),LL(0x57fc8f0d,0x7b7b6081),LL(0xdd642848,0x2e8f2150),L_(0x000001c6), + LL(0x44c8a327,0x1f4b8713),LL(0xa7ee221a,0x5258be1d),LL(0xe41af48e,0xa737a8cd),LL(0x83aeee1c,0x3f320ac3),LL(0xbb3a2bdf,0x8abc18a8),LL(0x2bfe7f09,0x9da43962),LL(0x5ab55046,0x1318b08d),LL(0xc7f6a7c8,0x4ae4a0c2),L_(0x000001fe), LL(0x072464c5,0xe109557b),LL(0x52cb5223,0x2e18e586),LL(0xbb44cf23,0x58cf033e),LL(0x8273746f,0x9cb3f3f2),LL(0x15027b4d,0x0badc23f),LL(0x03dd0534,0xebde0563),LL(0x94ef00b2,0xf31a2a6f),LL(0x88f86782,0x089879e2),L_(0x000001cb), + LL(0x5644a483,0x012e151c),LL(0xec46d8f5,0xcb60c92d),LL(0x61f8e693,0xf704143e),LL(0x53579b44,0x06b44ecd),LL(0x98807645,0xdda8c89f),LL(0x17c64951,0xfaab400d),LL(0x2e39e25a,0x16b86130),LL(0xfef9c912,0x627a2e4f),L_(0x000000ad), LL(0xd2367ca5,0xf18ebddc),LL(0xbcf685ba,0x59f6d4cf),LL(0xe159807e,0x8c3c8195),LL(0x2bb8d624,0x02e20259),LL(0x3ad24a15,0x5eef3266),LL(0xe9a952f5,0xc8d0e08e),LL(0x37d37845,0x4cf4addb),LL(0x778df76b,0x420c462e),L_(0x0000004a), + LL(0x55047df4,0xa605ea07),LL(0x579060a2,0x728d81cf),LL(0x3b8900fa,0x1ccc1e61),LL(0xf49f8c7a,0xd633ce10),LL(0x4957105f,0xe467c698),LL(0xc3e2024e,0xa14d0dd3),LL(0xe7cc2be3,0xc90176ba),LL(0x00090c73,0x28835ef8),L_(0x000000f4), LL(0x39d8bbe5,0x229fde87),LL(0x1982808c,0x9d5d0ade),LL(0xb83a93a2,0x56715396),LL(0x4130f493,0xf5d0d1b5),LL(0xc39ee248,0xcbf57700),LL(0x0662cf56,0xf41ee620),LL(0x121da851,0x2397e72c),LL(0x1ab413bf,0x6c00ad7e),L_(0x000001f2), + LL(0xbdd73dc1,0x1f7a793b),LL(0x7252dfce,0xb3c777ad),LL(0x1ad25f35,0xd306f90f),LL(0x314c1227,0x4538596b),LL(0x28e31145,0x15f73822),LL(0x1808f8a9,0x5e4847ef),LL(0x6eb8175d,0x9d57409f),LL(0x2ae642ae,0x19b0b71d),L_(0x000001bb), LL(0x3f28e667,0xa45a1d7d),LL(0x84954816,0xe5f147ca),LL(0xccfb8bd1,0xcd78f915),LL(0x9a693642,0xb02b310f),LL(0xb6cb5362,0x1f01047b),LL(0x7529c74d,0x81d1fb13),LL(0xdf4ae21d,0x80b9dd94),LL(0x6a1afeec,0xd7840bbc),L_(0x000000db), + LL(0xc0abf15f,0x81d957db),LL(0x65ae7f67,0xe0fe8725),LL(0x40e4566b,0x7c42febe),LL(0x6340b7ff,0xcf060fa6),LL(0xea1d2782,0x9a689bd9),LL(0xb66eed98,0xc45b992d),LL(0x8f5646a0,0x969dc412),LL(0xd272048a,0xf48e06d2),L_(0x000000f7), LL(0x50900d7f,0x701c6e38),LL(0xaad1803d,0x92065d64),LL(0xf9668fa4,0x361ef75c),LL(0xfcc216b4,0x962eb248),LL(0x575be56a,0x89b9828a),LL(0xfde9ba30,0x202a575f),LL(0xc435f2ce,0xba3890aa),LL(0xf83734f6,0x4860b39a),L_(0x00000180), + LL(0x3ede16d4,0xa59cdc00),LL(0xd0de9f29,0x9f3b7991),LL(0xda7b6269,0x832ec0d2),LL(0xf2e16e2b,0xa8e7c828),LL(0xd0c41727,0x7f0878f9),LL(0xc4546447,0x7356692c),LL(0xc4af90b2,0x5fbe130e),LL(0xaa2e9ec4,0x17691590),L_(0x000001bb), LL(0x0074a183,0x16d0ccbe),LL(0x351544e0,0xf7b675ff),LL(0xf37d43c1,0x87055e7e),LL(0xc371f0a0,0x3e668989),LL(0xefcfca1d,0x8323227b),LL(0x36507d20,0x38f76084),LL(0x25498782,0x75a23d95),LL(0xacb8cb75,0x40481354),L_(0x00000151), + LL(0x20886bbb,0x9a6dec74),LL(0x296f5cd9,0xfd24a18e),LL(0x6092fe28,0xbb4a7907),LL(0xdeab539d,0x869a8ccb),LL(0x67f524d1,0x61521c17),LL(0xbbe3aaa1,0x5f79a2c2),LL(0x8be17e72,0x7d8ce0cb),LL(0x647da5af,0xf36cb2d8),L_(0x0000003a), LL(0x0f2ab363,0x6d93da70),LL(0xdfde9d3e,0xa76d10f8),LL(0xe72ce040,0x17308d11),LL(0x075467a8,0xed2aabb3),LL(0x9aa69a1d,0xc10f78d3),LL(0x4caac399,0x13d4d378),LL(0x7e54c473,0xda4d8f8d),LL(0x911cb804,0x55d905b0),L_(0x000001aa), + LL(0x253f45b8,0x2af99e2d),LL(0x112b491f,0x76414d1e),LL(0x4a8e2b12,0x1c380001),LL(0xa17691a7,0xb0f6f9ff),LL(0x4bd4233a,0xcf4e764a),LL(0xccb8bd49,0x012735f0),LL(0xc7fc0714,0xf6037d3d),LL(0x3da811dd,0x4eeecae0),L_(0x00000135), LL(0xf24a8fb9,0xb39e1a42),LL(0xa3c4048e,0x07ea05b5),LL(0xd581bb93,0xfa0b7bd9),LL(0xeeb6ce36,0x8b7b8d8f),LL(0xa0329bb2,0xfcc8cab6),LL(0x5c44e608,0x04c03b08),LL(0x3f2c4c95,0x51593cce),LL(0xb2ef5a3d,0xa645193b),L_(0x000000c1), +}, +/* digit=62 base_pwr=2^310 */ +{ + LL(0x052a5d7a,0xbd77fdcc),LL(0x91e67c5a,0x7ae80845),LL(0x30c17511,0x4fb64810),LL(0x92e55b53,0x6c21b31f),LL(0x96bd1eba,0x4d056aef),LL(0x3bd89651,0xf597cfd9),LL(0x39ce9f5d,0x10c4de29),LL(0x6737cbaf,0xca8494ef),L_(0x0000005f), LL(0x726ccf17,0xa070d7b2),LL(0xef8a249b,0x33084cb0),LL(0xfece71d7,0xdbf18fa7),LL(0xf11b328d,0x8e7f8fe7),LL(0xdb8c5b89,0xc5842d33),LL(0x38ef699b,0x44b71419),LL(0x619477d9,0xcd39a13d),LL(0x28db36f5,0x6954dd52),L_(0x000001eb), + LL(0xae5a71e3,0x160db974),LL(0xb267126a,0x4df55ba5),LL(0xf2bfd214,0xcf291fe0),LL(0xe4215d39,0x3dc0a627),LL(0x8849498b,0xfec311ed),LL(0x5b220c7d,0x9fbb5099),LL(0xa3d83cc2,0xc55f9ca4),LL(0x32f62dd6,0xa473d853),L_(0x0000012b), LL(0xe73278db,0xcaebf5d4),LL(0x38b01c56,0xe4ab979b),LL(0x7e210f66,0xfe305e1e),LL(0x00e35bf7,0xbbd247e8),LL(0xf41625bd,0x64eabbca),LL(0xb3c01407,0xe49d3fb6),LL(0xc31a840a,0x6ebed09d),LL(0x6c67185e,0xd891e44a),L_(0x000000d3), + LL(0xeea3bb5d,0xa7efe273),LL(0x382ccbad,0x1d1fd154),LL(0x321aecf3,0xba4c80f8),LL(0x3a3eb329,0x44874ee5),LL(0xfc744e55,0xc89ec973),LL(0xd83775b1,0x9ac52665),LL(0x7c8cecd7,0xe149472e),LL(0xffa02e1a,0xabeedb19),L_(0x00000188), LL(0x4863bc6f,0x5e342dcd),LL(0x30b568ee,0xba377da7),LL(0x61a3cd5a,0xdb7394c9),LL(0x7e13d011,0x655ca62a),LL(0x531b03ef,0x687df8b5),LL(0xa07d97a8,0xc1cc63e0),LL(0xc3579f84,0x4f51c0a2),LL(0x1f68d107,0x8b2a0959),L_(0x00000021), + LL(0x73976185,0x5ac29ab9),LL(0x1049200d,0x5376ef50),LL(0xb7cabe96,0xb29fcfde),LL(0x2ebeaa6e,0x849702e8),LL(0x9856863e,0xd5820c1d),LL(0xadb32b7d,0x0b85b8b6),LL(0xcb2a1da8,0x4ecc2beb),LL(0x911240a2,0xb6f1d1cb),L_(0x0000019d), LL(0x8e9339d6,0x65738f28),LL(0xc9389868,0xec9ab31a),LL(0xb78b477c,0xb756dfc0),LL(0x2531d4c9,0x2bea7bd2),LL(0xa957b1f7,0x19668750),LL(0xb7acf908,0x23544082),LL(0xfa97aa90,0xd310dd35),LL(0x7c9376d4,0xe3e85065),L_(0x000000c8), + LL(0xe690991e,0xb53d0f3e),LL(0x7a8ed401,0xe7688a48),LL(0xc975d343,0x0a163c7f),LL(0xbbe320a1,0x3c38f3b4),LL(0x637ba641,0x0cc94ae6),LL(0x2fa7a438,0xf036a2cd),LL(0x85cf8f8c,0xdd8d3d2d),LL(0xf3dec45f,0x83f293f7),L_(0x00000007), LL(0x0fc0fe23,0xf9f35894),LL(0x22cf1f3c,0x5367a382),LL(0x0a85bdb7,0xa486155c),LL(0x43d0dc60,0xa045fb49),LL(0x28e031ef,0x239e6d10),LL(0xbc646dab,0xf3c58cd8),LL(0x37a252ad,0xa190c29a),LL(0x729ace13,0xafb3edde),L_(0x00000004), + LL(0x2c2d00f5,0x309124ad),LL(0x92f17a73,0x90896f6d),LL(0xd107aa3f,0x6655b0bf),LL(0x28ed385a,0x4393b8b0),LL(0x64efc785,0xa72dcb01),LL(0xdc6d4959,0xedcf6e0d),LL(0xad09fb16,0xa138cb63),LL(0x5a264a29,0x9242e638),L_(0x00000154), LL(0x23fa857e,0xa4afca8f),LL(0x362d992a,0x4718e360),LL(0xe0e7ef99,0x51da204d),LL(0x0a263a3e,0x76d92100),LL(0xc54159bd,0xb90bd792),LL(0x6992a7d6,0x2d4d5792),LL(0x34429060,0xea9796c5),LL(0x2d91640d,0x11109304),L_(0x00000023), + LL(0x69a4e57c,0xd8256cea),LL(0x1bf79944,0x4d134e77),LL(0x4e8b215e,0x63a4641d),LL(0x83621b34,0x8da5f102),LL(0x530939c0,0x9d6baa6f),LL(0x78356025,0x0a919eb7),LL(0x9cebfe30,0x523c04c9),LL(0xba70fc3b,0x06c24660),L_(0x000001b0), LL(0xb404acda,0xbeff381e),LL(0xf36c4399,0xc6bfdda5),LL(0x193ff430,0xddaf4961),LL(0x43e642a9,0x86bb6b08),LL(0x4ebe4623,0xd3326377),LL(0x8dc4af24,0x33ce6709),LL(0xb168c749,0x3757e6ab),LL(0x451bf0a9,0xdd6738f7),L_(0x00000114), + LL(0x95d393a7,0x15af1e76),LL(0x09f6c873,0x5dad48c9),LL(0x168b010a,0x03c65a7e),LL(0xd86fdc56,0x73f51c26),LL(0x88f52d53,0x697c8b7d),LL(0xbc64a497,0x670982de),LL(0xaf7a0676,0x809f942a),LL(0xb15cc57a,0x593420be),L_(0x000001c2), LL(0x71728397,0xf5563ef9),LL(0x305f3c8f,0x4e73a2dd),LL(0xa80ae4a1,0x828cc516),LL(0x2258160b,0xe74db735),LL(0x108533e6,0x14ad6801),LL(0x3b320283,0x541598a0),LL(0x763ab107,0x56c3d815),LL(0xf632644f,0x8ad49089),L_(0x000001fa), + LL(0x3fb5de8b,0x8bc4deb0),LL(0x8d93c4e8,0x1e8e7ab9),LL(0x3dd24d9d,0x201baf56),LL(0xcada68d7,0x0a384ece),LL(0x503d4f19,0x5dcc59f7),LL(0x6763d7ad,0x7849c18f),LL(0xc66f3753,0x6951161c),LL(0xfc052118,0x74242704),L_(0x000000c6), LL(0x90fd23ab,0xfbb20d46),LL(0xd8a0eeac,0xd979406d),LL(0x508b0789,0xeb2d48ad),LL(0x8cad1e65,0x2f16458c),LL(0x7615ee48,0x8941144f),LL(0x2d4a611a,0x57baf847),LL(0x706729a1,0x04864e43),LL(0x13b7d8ff,0xa2cca9c9),L_(0x0000001f), + LL(0x6b13d691,0x15c5966e),LL(0x5adf4806,0xe79886a9),LL(0xb44e7b28,0xc0149ae3),LL(0x14ea5297,0x3f2176d8),LL(0xd637170e,0x3d5f7f20),LL(0xfd66e46a,0x5f76d12c),LL(0x998ccf72,0x8fbfc2d6),LL(0xc2738301,0xc299587b),L_(0x00000093), LL(0x48202d24,0x5d1ab080),LL(0x22169c9a,0xf44f3ef3),LL(0x4f9cc0b4,0x5a6ea1fc),LL(0xd8a38b0c,0x1e3f8f7c),LL(0xfc2a4b0f,0x2f6b7ea1),LL(0x85236ace,0x7c4797d9),LL(0x507ad976,0x30db4704),LL(0x70b62118,0x15efb0d0),L_(0x000000f2), + LL(0xa8e006d6,0xa8350ceb),LL(0x0b5d40f6,0xd0476f3e),LL(0x7d6beb64,0x8a7277db),LL(0x9a1052c1,0xb78ba330),LL(0x6fb67a25,0xa921f295),LL(0x937d5f7f,0x58e2fb78),LL(0xb3c5ee8b,0x224a8a6c),LL(0x3ba51856,0xdd623558),L_(0x0000004f), LL(0x472c8eee,0x46bd4fc5),LL(0xd6bbe5d7,0xbccb9c2d),LL(0x8704f8a7,0xd4145962),LL(0xf0c09b77,0xe9ce9fc8),LL(0xe24e89e3,0x091189c9),LL(0x34dfd23c,0xa0008822),LL(0xddeaf170,0x43b08954),LL(0xe569f253,0x867e76b2),L_(0x00000020), + LL(0x21969535,0xd200f675),LL(0x1aa95306,0x8a20dfb4),LL(0x450070d5,0xe56ecbdc),LL(0xa73c2aa2,0x93697944),LL(0x8cf15e09,0x2bf1cc5f),LL(0xb81e3982,0xa98dee98),LL(0x39d2614b,0x4249763f),LL(0x88bf80d0,0xdc125dce),L_(0x00000041), LL(0xea90be49,0xeb5f7526),LL(0x9d76e09e,0x42892f62),LL(0x665e7661,0xdd2de6b9),LL(0xdb45bef0,0xe66edde4),LL(0x0f0c29ed,0xd947a3fe),LL(0x39bccdcb,0xdc0bb667),LL(0x97600929,0xeeaa185f),LL(0xf355b62f,0x29e7ad98),L_(0x00000083), + LL(0xc2d3d21b,0xbe07feb4),LL(0x9e1d3138,0x90b99ecf),LL(0x358fe997,0x2ec0a3d5),LL(0x95008edf,0x7f72a6c8),LL(0xc6e6cc84,0x2b8ec523),LL(0x351d40b6,0x10aa3646),LL(0x30961dc3,0xdff38b1a),LL(0x6d776cf7,0xc458ba47),L_(0x0000000a), LL(0xfce248cf,0xad217997),LL(0xe663a7a1,0x423b10cc),LL(0x8d65dc51,0x0215b195),LL(0x0f10bc35,0x0f4e07a2),LL(0x23278029,0x19d23499),LL(0x304b98d9,0x6127a2da),LL(0x9fb0c81f,0xed0c0943),LL(0xcd486835,0x4d63eec4),L_(0x0000015f), + LL(0xd0ac0ecd,0xbaefab89),LL(0x0a9db571,0xe4775843),LL(0x6c283a9c,0xfebcf91f),LL(0xd37751b1,0xe02d1251),LL(0x4c69aef4,0x93ca62f3),LL(0x756b2ab1,0x017751a3),LL(0x9921e7da,0xf0df5f26),LL(0x31fbf868,0xc6385112),L_(0x0000015e), LL(0xc24912f9,0x6ce422f4),LL(0xe5bc3bbe,0x0c518f2e),LL(0x00e5a237,0x51ed5f7e),LL(0xb6da428f,0x1a77cbdb),LL(0x248c6951,0x086ad3a0),LL(0xfd285428,0x00d65807),LL(0x460a5bc1,0xc6265db2),LL(0x728547e4,0x8fcc39fe),L_(0x0000002a), + LL(0xcdbb56b7,0xea484f2e),LL(0xebecf09a,0xbe1705e2),LL(0xdc0d7050,0xe83a83b6),LL(0x5c8fdff7,0x1cd41a57),LL(0x58f038ee,0x975aeb28),LL(0x858f75ce,0xddbb66ee),LL(0x7455106f,0x7e1bcafd),LL(0x54e1961f,0x1e151b28),L_(0x0000006f), LL(0xc329e633,0x32cfb8ca),LL(0x596dc91e,0xe8fb4aa3),LL(0x19c60dcd,0x0c27fe63),LL(0x9c2411d9,0x49228e82),LL(0xf4420f99,0x5075f5a2),LL(0x38a95326,0xadb26b0e),LL(0x7345059b,0x67709e35),LL(0x428212fb,0xa6804139),L_(0x000001a5), + LL(0x3a95d178,0xb909e614),LL(0x1860388a,0x89b7600c),LL(0x942112c1,0xa080f4aa),LL(0x5a1967f7,0x5057c08b),LL(0x13543a0e,0xf9ac78fd),LL(0x1598cafb,0x9408a20a),LL(0xfa7974b4,0x8fb58bcd),LL(0x17ad4e19,0xf91b6362),L_(0x000001b1), LL(0x57138c5b,0xf8960264),LL(0x185f172a,0xea9d78b2),LL(0x8652917b,0x62148231),LL(0x9b757159,0xb7470a8b),LL(0x4f2c7ae3,0x532d7747),LL(0xc96fd10f,0x6b40b8bf),LL(0x77081dbd,0xa54da232),LL(0x2cd44f13,0x0796d519),L_(0x000001ac), +}, +/* digit=63 base_pwr=2^315 */ +{ + LL(0xc1b5f874,0x37761e89),LL(0xc768e709,0x052402d8),LL(0xa7063fcc,0x437e0d8f),LL(0x5032ca28,0xd7049706),LL(0xe0560b81,0xfcc5af72),LL(0xdac1a63b,0xabb68cfd),LL(0xe89f3917,0x257b3b85),LL(0x80d7454a,0x28153e38),L_(0x00000088), LL(0x001d4cbe,0xe9651818),LL(0x66b1014f,0x64d65a97),LL(0x511b3639,0xd56646ec),LL(0x26e7c4e0,0xdfae8dcc),LL(0xa94ae11a,0x86e8d406),LL(0x6e9a1a68,0x47bbf4ad),LL(0x3004a685,0x13e8901b),LL(0x5981c480,0x3994bc8d),L_(0x00000179), + LL(0xc63223ff,0xeed01f7e),LL(0xb10c656e,0xa95759d3),LL(0xc8ceacdd,0x5f68fe9f),LL(0xb6ab8ec3,0x50e97936),LL(0x28c0b215,0xe4ccc3b9),LL(0x92be8e1d,0xfc6be17e),LL(0x20828c77,0xb81bdb63),LL(0x13352a78,0xe00699d2),L_(0x0000016f), LL(0x3d9b3c1e,0x0b5daa42),LL(0x94567b3a,0x6bf95aa5),LL(0xa3d149d4,0x8d0fbfb5),LL(0x4e997958,0x5e636b3d),LL(0xc1e08ca4,0x8fa3b11b),LL(0x73645c35,0x552e11b1),LL(0x931ab993,0x0db67bc8),LL(0xce614c5f,0x53c262d3),L_(0x0000019f), + LL(0xf005a100,0x9be2e7f2),LL(0x06f26644,0x47f29a13),LL(0x7b580ed9,0x3f3b60f9),LL(0x22198889,0x7e6ec70b),LL(0x9f87a7be,0xfc2d715c),LL(0xb2ebc47c,0xfc003ea3),LL(0xfa7b2218,0x79438acf),LL(0xbfd9d6c5,0x930053c2),L_(0x000000f1), LL(0xdac555ca,0x80f3c546),LL(0xe5a4dad1,0xa25a6ba7),LL(0x2d4bd9fe,0xa68cfbbf),LL(0x35faf13a,0x4e3df8bd),LL(0xcfc847de,0x8434c00b),LL(0x4dfdf245,0x40669463),LL(0x6e619d42,0x5f688c19),LL(0x13d3a517,0x9cabea4b),L_(0x000001af), + LL(0x3aed7148,0xbb901084),LL(0x6321bcc4,0x996ac002),LL(0x53c74ad5,0xcb634535),LL(0x741982c7,0xdc48a041),LL(0x1196d8fe,0x44c9f092),LL(0xfabc20d2,0x0a8fce97),LL(0x32828d27,0x62a6d447),LL(0xcab0c775,0xe6a8960b),L_(0x00000089), LL(0x3a61da39,0x4b749d7b),LL(0xfb5b6d67,0x9df6dae1),LL(0xec275083,0x4fd05c30),LL(0x7da1a928,0xb7bd6dae),LL(0xec82a28e,0x66cd19ba),LL(0xa08ca71d,0xd599b2c6),LL(0x6c312c52,0x5bfaa154),LL(0x6795e306,0x2d3a57f0),L_(0x00000087), + LL(0xe9c779ff,0x99bf4200),LL(0x2e4558d4,0xb9ba6e9a),LL(0x636dc521,0x836fe297),LL(0xa1c7e0bd,0x461d465e),LL(0xa229d229,0x287fba32),LL(0xe43c8f80,0x5fa34491),LL(0x76cbe0ad,0x0e6b8f16),LL(0x7a25d2a9,0x6221b3d0),L_(0x000001ae), LL(0xd420ce9f,0x59654147),LL(0x2c11cbe4,0x582dde44),LL(0x73168c78,0xcfbe66e7),LL(0x5f455763,0x55778942),LL(0xd782c483,0x9b69f069),LL(0xff95fe3e,0xaa1addcb),LL(0x00a4bd0b,0x47541c1d),LL(0x8ad93857,0x5c6d8f2a),L_(0x000001b8), + LL(0x0afff918,0x80ad064a),LL(0x89af5deb,0x7114ab96),LL(0x4dbde778,0x099fad0b),LL(0xfd29cd3c,0x525d6055),LL(0xbd379d42,0x4df50e85),LL(0xdfc116d0,0x3602e006),LL(0x374d96b5,0x2ee6c63f),LL(0x6509a7f3,0x4fb180f2),L_(0x00000115), LL(0xee822c17,0xfc039cb1),LL(0x6c2fdf58,0x5872cad5),LL(0xea665324,0x3b9e8ae0),LL(0xaf2e64bf,0xb8314c4d),LL(0xa8f96bb4,0x63c57f41),LL(0x3df990e0,0x5149d306),LL(0x1d5f9b0d,0x08ba6128),LL(0x3d6cc9c6,0x52f204ba),L_(0x000000d5), + LL(0x84b34c8d,0x0908a3fa),LL(0x06e343a5,0x8e41dac7),LL(0xca844102,0x83411f49),LL(0x0712aa99,0xd4bcaa5f),LL(0xf85d2ba8,0x0278367b),LL(0xbdc302b7,0x5016082b),LL(0x54ed82be,0xfea00712),LL(0x1e47617b,0x97de79a6),L_(0x000000b6), LL(0x5025ca72,0xa8a5db48),LL(0xd3c98c1a,0xeb113cc6),LL(0x259b9a28,0x1b35c6d2),LL(0x49923a55,0x266d75d3),LL(0x644a3ecc,0x9590fb6b),LL(0x221e1f1d,0xa7f663c5),LL(0x9c9bd811,0x30cacfb5),LL(0x8f25a4f3,0x459bddad),L_(0x0000017d), + LL(0x5c5d4a76,0x224e9112),LL(0x74621c3b,0x62ab184a),LL(0x17406495,0xedfb682a),LL(0xc3f7c8cd,0x16ae2053),LL(0xd8e38d44,0xdf044060),LL(0x39ed9c28,0x86143e57),LL(0xf327b97f,0x8b95f9f7),LL(0x53853147,0x9200a872),L_(0x000001b4), LL(0x43b98e46,0x05661b39),LL(0xc1bcc1fc,0x9ee23198),LL(0x64ff1647,0x115744fc),LL(0x0f20d871,0xcdf5ac56),LL(0x92c9feea,0x63cba9c3),LL(0xa72f70b2,0xadbac8fd),LL(0x365c71db,0x171aad35),LL(0x9d51687d,0xaa0202f9),L_(0x00000102), + LL(0x7242ca8b,0x45faaf9a),LL(0xc08d85f8,0x550ef4dc),LL(0xb82ff28e,0x814b8cba),LL(0xbbe121da,0x1eb4cd63),LL(0x081656e6,0x82eece40),LL(0xf4405b11,0xe9889d6a),LL(0xf6c9d001,0xbc4f3c1e),LL(0xe85dc906,0x7466fe1b),L_(0x000000f9), LL(0xbcfa56fc,0xb8894301),LL(0xa60a71ba,0xc8290de3),LL(0x5b4cf893,0xfa8203e9),LL(0xa8602943,0xb0d9fec8),LL(0x6b75b5c6,0xacaeb1bd),LL(0x40f20d5b,0x228fdb83),LL(0xe7477d37,0x967812d8),LL(0x3271b8d9,0x20f42fd0),L_(0x000001a9), + LL(0x69acd4ec,0x76812a69),LL(0xd47ef468,0x62f921ab),LL(0xc8ee3434,0xb7930834),LL(0xc08c033b,0x369c3e87),LL(0xee51d0a2,0xd98cac8f),LL(0xc675c1fb,0xa309b704),LL(0x3fcbb3c6,0x69a173a4),LL(0x32c49495,0x0559e094),L_(0x00000126), LL(0x2b5e781f,0x79bd3a70),LL(0x68837e34,0xd74e86eb),LL(0x22881aa5,0xecb38496),LL(0x91b89a84,0xdd2964ba),LL(0x7caeee87,0xb0230b75),LL(0x83a10f40,0x7853cadc),LL(0x465657ae,0xe45f5ad1),LL(0x100e5033,0xe6dbce75),L_(0x0000005d), + LL(0x27034a2f,0xae458db9),LL(0xe02cc805,0x361c4604),LL(0xc6c6e812,0xf53dab3f),LL(0xe1de7819,0xa93944c6),LL(0x77575b10,0x7d127be6),LL(0x4580ec67,0x18920ad0),LL(0x6451a6a6,0x595f7341),LL(0xe3b018ad,0x87c2f62f),L_(0x000000a8), LL(0x73fafabe,0xacea82d0),LL(0xb8e018e3,0xb66d3c1a),LL(0xf0a068d2,0xa0a76281),LL(0x2960ab23,0xd3310f1e),LL(0x1ade815c,0x5df5a459),LL(0x4830c68e,0x9bc40618),LL(0x506f8ded,0xa5b32181),LL(0xb64aea9e,0xdef4d655),L_(0x000000f4), + LL(0xd2e44f39,0x7f22b492),LL(0xf166288f,0x72f850db),LL(0x45a14853,0x6743ab2a),LL(0x480b82ee,0x235a84e1),LL(0xbca609c8,0x422668b9),LL(0x2f4e85d8,0x5d6f0bf0),LL(0x792321da,0x61afb880),LL(0x2c095f02,0xca3c8cb8),L_(0x00000022), LL(0xe6bc2f57,0x43f99381),LL(0x4a832e1f,0xe6089c84),LL(0x51ad7011,0x65600aa9),LL(0x2a695207,0x11447728),LL(0xa07e689c,0x7bb9a4c6),LL(0xcd7b0e53,0xdf06eaf0),LL(0x78952329,0x777c474d),LL(0x10d2b00b,0x9d539f07),L_(0x0000004b), + LL(0x20322841,0x736265c0),LL(0x91a20b69,0x7c956777),LL(0x530024a3,0xbcd4358f),LL(0x2cfdf5c4,0xe32fe9e3),LL(0x69c3c240,0x7dd472b9),LL(0x16947a8a,0xeeaaeb78),LL(0x03c5cf25,0x9aa3433d),LL(0x521f3b6b,0xf3a8ba18),L_(0x00000085), LL(0x88ddc3b1,0x00a93570),LL(0xc5b29c7d,0x5d8a1581),LL(0xb3793bd2,0x1877f26e),LL(0x4435f13a,0x4fc7c6c4),LL(0x5b6c76af,0xb032ee18),LL(0x5465338c,0xd7e32969),LL(0x5e8d0f72,0x82259fe6),LL(0x38f0d401,0xe8265e82),L_(0x0000012d), + LL(0x8093c8e0,0x248ef981),LL(0x84b971a4,0x5353d713),LL(0x8ab8dd10,0xf3f56422),LL(0x9e95615c,0x163427ee),LL(0x1dbed91f,0x7cd8d83e),LL(0xa05bff8c,0x2a117b26),LL(0x9094b7c0,0x28d65130),LL(0x8d73f3a7,0x75d255fa),L_(0x0000015d), LL(0xfb45cf4f,0x5dd01b3b),LL(0xa983b69a,0xe3b24278),LL(0xdda15e64,0x0beba6e8),LL(0xeabdafeb,0xce3cbe7c),LL(0xe28dd1f4,0x03c3a01e),LL(0x315483c0,0x286b68f0),LL(0x44cc13c4,0x653661bd),LL(0xa5a2b18a,0x8d8536d7),L_(0x0000007f), + LL(0xf83ea93b,0xc7a428c9),LL(0x308d0ccb,0xdeef06fc),LL(0xe456dad3,0xd27b9dce),LL(0x04dd575c,0x8c1bbcfc),LL(0x1c63319a,0x479f6f73),LL(0xed4daaeb,0x7cb52d7f),LL(0x9fe5930e,0xd171cdbc),LL(0xcd65b54d,0xf8449b00),L_(0x00000106), LL(0xbb8079a0,0x2ea98b08),LL(0xda724133,0x24b7505e),LL(0xedf1d97e,0x5aed5e6f),LL(0x283c1e51,0xc39ad307),LL(0xf64812a4,0x76820a6c),LL(0x13b5c88a,0xb32f91ce),LL(0xb8954a33,0x211cbd9c),LL(0x31a311e0,0x72994cae),L_(0x000001f3), + LL(0x3ef4f2d2,0xcf466ff0),LL(0x47044584,0x78dc82b8),LL(0xb52d320e,0x8b5110dc),LL(0xdfe140d7,0xe07b117a),LL(0x0b45fd46,0x39af6581),LL(0xbda19439,0x26b6d5c5),LL(0x8309f53f,0x8091095a),LL(0xaad23c7d,0xb35060d4),L_(0x000001f0), LL(0x90dd82bc,0x1ee78b60),LL(0x839c5155,0x453fc776),LL(0x2966b875,0x6bf1d026),LL(0x9e2a2996,0x825d3c72),LL(0x48c49cfc,0x1345ab1d),LL(0xad600996,0x7e6049f3),LL(0xf1b39850,0x0b007da4),LL(0x2c8f36cb,0xcf942c38),L_(0x00000153), +}, +/* digit=64 base_pwr=2^320 */ +{ + LL(0xeba284c6,0xdcd5cc91),LL(0x292fa3ee,0xea471fd6),LL(0x5841cc32,0x9fb23a12),LL(0x35810a74,0x4e18eb2e),LL(0xd6133648,0x5228a2bf),LL(0x52cab6f6,0x07542e74),LL(0x40c74692,0x62526cd9),LL(0x36b9b329,0xc8dbbd29),L_(0x00000120), LL(0x17573e4f,0xca996c2a),LL(0xc3d42418,0x33e1f9c1),LL(0x970fbd47,0x246b3cbf),LL(0x8c0b1561,0xf0853508),LL(0x16e93234,0x8ff90188),LL(0x74d99d7f,0xaa556f85),LL(0xd3b1d290,0xdda5d989),LL(0xab78218e,0x7de54ed0),L_(0x0000000c), + LL(0x87233d65,0x32cea9ff),LL(0xb1454f2b,0x6963e65d),LL(0xd5f2627e,0xd15b05b7),LL(0x68cad15b,0xf2c9215a),LL(0xf9679cfe,0x982da4ec),LL(0xdd21cc1f,0x73910763),LL(0x3925aff6,0xce110fdc),LL(0xad0858b1,0x0efaca3c),L_(0x000000ae), LL(0x160c51bf,0x88f58f75),LL(0x9e39ee8b,0x713a7cf3),LL(0x5af813ed,0x8ac4ac36),LL(0xa788e43e,0xe789c040),LL(0xc10b5e01,0x3d0cb49e),LL(0x26fdddf3,0x3f2d9bd7),LL(0x504e525a,0x776e3c30),LL(0xa456acdf,0xf6acce51),L_(0x000001b6), + LL(0x23707d7d,0x4b6d85bc),LL(0x2372ec00,0x4b483dd7),LL(0x838f63c9,0x869b15c9),LL(0x40b6584e,0x291644dd),LL(0x05bb5ad6,0x693ec1c9),LL(0xc10969be,0xb5c6018d),LL(0xb81150c7,0x04c9c113),LL(0xbd460de8,0x933a940b),L_(0x0000014c), LL(0x5ad558a1,0xa356589b),LL(0xf88e046d,0xf093ea9c),LL(0xede9de0f,0x39acd54e),LL(0x19ec3f88,0xfcbf451f),LL(0x44ec243f,0xf8b02c0e),LL(0x981fd0d1,0x42d2cc07),LL(0xf4701bca,0x3f363b43),LL(0x30f2e9e4,0x2eafb7f9),L_(0x00000170), + LL(0x006b0772,0xa8c7c3d7),LL(0x1ba3ff28,0xc1d96b23),LL(0xc17a4f5f,0xda50f432),LL(0xca88f653,0xfce5ef14),LL(0x31ac5da9,0xd10257bb),LL(0x18d3105d,0x06b910de),LL(0x4f950082,0x8ed121d6),LL(0x748b9a29,0xeb08be83),L_(0x000001b3), LL(0xfedc9456,0xcda193af),LL(0x30addb34,0xf39dff50),LL(0xa3a58a0d,0x586d72c1),LL(0xd7c02e84,0x7190f71a),LL(0xb6dddddd,0xd7f7815a),LL(0x93fd431d,0xb059af28),LL(0xdb90a301,0x626d66eb),LL(0xb55b2545,0xa7c95ac5),L_(0x00000015), + LL(0x02a70327,0x60173b4c),LL(0x700e187b,0x853a0c8b),LL(0xebfa5d41,0xa74d3fcb),LL(0x6636a248,0x7f152910),LL(0xcd439df1,0x433bf866),LL(0x3d361a48,0xd52b92a9),LL(0x96508fce,0xcdde5dbf),LL(0x08fb48db,0x4598b64c),L_(0x000000ab), LL(0x41e6d707,0xa287bad7),LL(0xc1d0199a,0xaca83d8b),LL(0x3248272c,0xdeea6deb),LL(0x81490886,0xd5830e62),LL(0x803b3e7e,0x0b551501),LL(0x329bb8f5,0xe61ae410),LL(0x1b1ec67e,0x2add209b),LL(0x9d8f057d,0xac0fb9f7),L_(0x000000af), + LL(0x159240ac,0x701cba0d),LL(0xbe49e9de,0x1e2030d5),LL(0xa8d80ea6,0x891f5b9f),LL(0x389aa0a7,0x281d5c9e),LL(0xbf08f46a,0x42c2a6a9),LL(0x30133d89,0xcae5c626),LL(0x26d80fbd,0x976ed6f2),LL(0xd7445273,0xdd69ee7c),L_(0x00000095), LL(0x4b64112e,0x1ba10f05),LL(0x3c715556,0x076de398),LL(0x051c721c,0x1b6338a0),LL(0xed93ec2b,0x0b18e617),LL(0xe40d08e3,0x2546a805),LL(0x39d986d0,0x289546bf),LL(0x87fe36cb,0xcb29a40d),LL(0x28ca6d96,0xcb42c038),L_(0x000001d7), + LL(0xb8888aaa,0xeb89b8a3),LL(0x504b24ba,0x13c31ce0),LL(0x1577d88f,0x1d308489),LL(0x01541da0,0xc31edb15),LL(0xfbe18906,0xcb88a0c0),LL(0xb123cf8a,0xe0a54814),LL(0xce17eb8d,0x12d30b10),LL(0x5435ad11,0x16c373c6),L_(0x000001e1), LL(0x7a3c3081,0x198cbd6e),LL(0x18481bd1,0x9feff602),LL(0x8a4e33b7,0x4dc9559a),LL(0x242155d3,0x49b265ae),LL(0x0458dbdb,0x66003375),LL(0x19c33688,0x53753ede),LL(0xac09e0c8,0x0eb6969a),LL(0x25b27567,0xc165da52),L_(0x000001ad), + LL(0xfd4c030e,0x4bb182d8),LL(0x45ba7b8e,0x24d5733c),LL(0x9bbae322,0x857e0992),LL(0xe18395c5,0x7a4b7ec5),LL(0xbbeb3431,0x9d2ffacf),LL(0x70996597,0x0dac7ff4),LL(0x634b33c0,0xd22ac181),LL(0x5a113dab,0xb7220b32),L_(0x00000027), LL(0x1af6d0b4,0x4b60b5e3),LL(0x60067ebd,0x7c6c236a),LL(0xccf47b3d,0x199b1be8),LL(0x1dbd1cc7,0xe888eba2),LL(0xb4932466,0x034c21f8),LL(0x19ff1dee,0xf9da1696),LL(0xe040c95f,0xee7e95c7),LL(0x9dbe56ef,0x308a2b5a),L_(0x00000094), + LL(0x33a41f31,0xb89596d6),LL(0xde8f6d08,0x36e37e25),LL(0x09152867,0x911d84ea),LL(0x4f3476b2,0xba9def4c),LL(0x44e0d519,0x12065979),LL(0xdfef8c30,0x91c87d28),LL(0xa45cf33c,0x6b8dd103),LL(0x5a48975d,0x7c11f3b7),L_(0x000001e4), LL(0xe73885a7,0x36da50e9),LL(0xdc731cf5,0xb97f8cf8),LL(0x67bb07a8,0x922b0be5),LL(0xfb414a3b,0xe9cbd504),LL(0xd391785e,0x2631b899),LL(0x9eb65672,0x50f31f7b),LL(0x4ee45215,0x0d4d0798),LL(0x23e25b24,0x83771e39),L_(0x00000062), + LL(0x6178bac5,0x9eabc3c5),LL(0xbfa39955,0x503d57c5),LL(0xda006222,0x8e465ace),LL(0xe390a3d7,0x363ca671),LL(0x7ca51f49,0xe0376d27),LL(0xab1c9afc,0x325dbeb1),LL(0xf303951f,0x2ac46079),LL(0x4fcc04e4,0xe25bdab1),L_(0x00000049), LL(0x1e1f126b,0x7a1f14f0),LL(0x0b9e64fc,0x49fb5176),LL(0x394e56b2,0xc1fff51a),LL(0x0b50d33b,0xf135bc4a),LL(0x41e4f563,0xf07911e8),LL(0x0008c3a8,0xfd1855b2),LL(0xd0455066,0xb1f8cdf1),LL(0x3e4e10b9,0xb720d66c),L_(0x00000140), + LL(0x47688773,0x75ef0188),LL(0x81134439,0x6a21abe0),LL(0x3ff532d6,0x9e0177ad),LL(0x3c27f56d,0xe284df24),LL(0xd99892e8,0xfcaf2cd5),LL(0x668c2ac2,0x72c31d05),LL(0x450ea985,0x617df772),LL(0xd1386608,0xffb181fb),L_(0x00000007), LL(0xa81bbd89,0xb7cb40e7),LL(0x6545e4d7,0x4e799290),LL(0x48c0ef0c,0x129414b6),LL(0xf9bc6b77,0x75cac719),LL(0xcf3cf61a,0x7090a084),LL(0x5de671da,0x573167fe),LL(0x53c2428e,0x9be66bcd),LL(0x581cfd76,0xf5419505),L_(0x0000014f), + LL(0x868b1c0c,0x6fc274a1),LL(0x83263833,0x7470faca),LL(0x28bbd5e9,0x10a9a5ed),LL(0x92bc266f,0x1a2df530),LL(0xc1420bb6,0x26088825),LL(0x6de27806,0xb843fbcd),LL(0x96eddc77,0xfaacb0c0),LL(0xe58f23ff,0x249016a2),L_(0x00000132), LL(0x304fead2,0x46f8b4da),LL(0xcdc2767a,0x030d0ccb),LL(0x4ecb91a4,0xa6cdee79),LL(0x546f1657,0x2f10c656),LL(0xa2c85665,0xdaca38a8),LL(0xb2b32405,0xa84dd381),LL(0x29386bb0,0x4d4926a6),LL(0x3ed722f3,0xbe6190e5),L_(0x0000004c), + LL(0xb158c617,0x70c2bdde),LL(0x1e929730,0x03b67c3d),LL(0x83aa10cb,0x207b6554),LL(0xf8bd1f2f,0x65897412),LL(0x52c6a1bf,0xd2b9e2bf),LL(0x4072e449,0x4573028a),LL(0x51728cdb,0x08f548f4),LL(0xa5fb2b4e,0x6569c4cb),L_(0x000000ce), LL(0xc30af1b8,0xf64d0544),LL(0x91fac057,0xe6a44ca8),LL(0x97b402f5,0xf3758797),LL(0x7a48f50b,0x9ec9c59e),LL(0xa20d052f,0x7e0c3edb),LL(0x50d02201,0xba6cf070),LL(0xc4603d10,0x0fd79a40),LL(0x04379719,0x030a1a47),L_(0x000000fd), + LL(0x33d05c0c,0xf4e66422),LL(0x28d54dca,0x3f1a0e0a),LL(0x1b90591f,0x8319bf69),LL(0x50c92b63,0x45f8cdc5),LL(0x2b172382,0xc8908923),LL(0xce47651d,0x282da333),LL(0xe6f22c70,0x6dc02842),LL(0x73a13e20,0xf357a052),L_(0x00000154), LL(0x9bb811ca,0x2aa27cb4),LL(0xff020d4c,0x8f138cd3),LL(0x181a1cec,0x35013750),LL(0x47863f93,0x37481122),LL(0xe6028031,0x18f58c65),LL(0xf01c48b5,0x565f6657),LL(0x9f20924b,0xa7b0ed3f),LL(0x643987ef,0x13cf4aeb),L_(0x0000004e), + LL(0x151f4865,0x1b42c497),LL(0xf30bdc50,0x055325f0),LL(0x144e0aa2,0xf8e98fe1),LL(0xa165a395,0x2e0f9b5a),LL(0x25afa523,0x3ceadf0d),LL(0x70ed634b,0x55dbb9b8),LL(0x1b25f855,0xe2ddb61f),LL(0x8a54708c,0x4ce03600),L_(0x0000004b), LL(0x74847fca,0xf91dd3a7),LL(0x92445716,0xe74dda4f),LL(0xfe51e6c5,0xd2ebe9fa),LL(0xe3bfd67c,0xec65184e),LL(0x51f3767f,0xc26dcf5e),LL(0x6092d164,0x7562e715),LL(0x48053ca5,0xc341746a),LL(0xfe264b56,0x6aa0cec8),L_(0x000001af), + LL(0x688f0816,0x55ab4efe),LL(0x012b1be7,0x48d9609c),LL(0xdb068e78,0x0fb98843),LL(0x958488ad,0xff5eda2d),LL(0x83f6d23c,0x3ec7372a),LL(0xb176c41d,0x5d185ec0),LL(0x925e4903,0x476314a5),LL(0xe4ff9579,0x0d644a3d),L_(0x00000029), LL(0xd529cc94,0xd2ad417d),LL(0x2dfe7d43,0x360ab4fa),LL(0x52cc454d,0xfb2e9eb5),LL(0xa4732c24,0xcf82a235),LL(0x68d1e843,0x67bb7a40),LL(0xbca2ab8e,0x91877eaf),LL(0x99566cd1,0x62574ab0),LL(0x22f9872f,0x687549f9),L_(0x00000183), +}, +/* digit=65 base_pwr=2^325 */ +{ + LL(0x2d85f820,0x287db7bb),LL(0x702fbecc,0xe568667e),LL(0xa157f36d,0xf4ecbeb7),LL(0x484f3352,0x941bbfbf),LL(0x558da014,0x3d5fe38d),LL(0x7b22586c,0x8a8ef1b3),LL(0x7a9e7fea,0xba594962),LL(0x0c422ebe,0x7c9fc474),L_(0x00000117), LL(0x34c2ec0f,0xeb882690),LL(0x8c7ffbe0,0x16f607ed),LL(0x0a729f09,0x9cab235b),LL(0xfb783d21,0xe85a3bb2),LL(0x7a1f91a0,0xaf1659ef),LL(0x067ef36e,0x3c3d4be9),LL(0x2b43e992,0x3b5e5bd9),LL(0xe81391aa,0x6e4981e3),L_(0x000001cc), + LL(0x58cf4fb6,0x2d970cf0),LL(0x6108b652,0x8db98564),LL(0x1c524ec7,0xc375bd09),LL(0x8ded01ba,0xeaf41a1c),LL(0xca7571d5,0x1513bf75),LL(0x83433ae4,0x831a58ce),LL(0xb1cbad60,0xd4b5c1d0),LL(0x7e3558b4,0x054b3a12),L_(0x000000d2), LL(0x5fc5bcaa,0xcd90416c),LL(0x1fd11e95,0xf9cd3e85),LL(0x77429d71,0x4b143cec),LL(0x818263e7,0xb694e333),LL(0x7b0bed2a,0x078fef20),LL(0x900d9d3b,0x22c62d90),LL(0xb2dcc393,0xf713057f),LL(0xee2cd8c7,0x46aefb0a),L_(0x00000048), + LL(0xc6a3697b,0x36666b6c),LL(0x771114f0,0x4615de0a),LL(0x4656bc00,0x27ed1a54),LL(0xfe1b0ffd,0x7a367a4c),LL(0xa7b011fe,0x9395287b),LL(0x1539028f,0xe474d2cd),LL(0x67ab6630,0x50df81c9),LL(0xd416f7d8,0xc4e94809),L_(0x000000c5), LL(0xcd4ff017,0x14e9eb99),LL(0x68ce9cb6,0xefe50131),LL(0x878690dc,0xf0500068),LL(0xa58b25b4,0xfe708a3e),LL(0x1697bfbe,0x4cbc1887),LL(0x109e6148,0xd61b572d),LL(0xea6e538f,0xcd507a67),LL(0x8cf0642b,0x44822c10),L_(0x0000002a), + LL(0x254f2817,0x74f04275),LL(0xe534cfb9,0x22ee390d),LL(0xf368e25e,0xbc4caed9),LL(0x0d3f5a1e,0xd7010447),LL(0x26bb7427,0x91f02404),LL(0x7f0d8308,0x993cd5f3),LL(0x4ebe5786,0x1ba9d89f),LL(0x2549a02c,0x89e62c7b),L_(0x00000089), LL(0x575527d2,0x33afd2d8),LL(0x6240eaa7,0x200435a3),LL(0x0df72a8e,0x104dbed5),LL(0xe9f3dcc7,0x1f5c3464),LL(0x98404140,0x791b398c),LL(0x1581b281,0xd77cd49e),LL(0xa203aa2a,0x2329530c),LL(0x70040738,0x782c024a),L_(0x000001de), + LL(0x8715b292,0x5fca8e16),LL(0x0659f3f5,0x904a8960),LL(0x7cdfccac,0xd46df8f8),LL(0xe8078ecb,0xae2184c0),LL(0xc1352930,0x904b839e),LL(0xf3fd8786,0x36602186),LL(0xc3ec21de,0x2a20030f),LL(0xe08de817,0x592eec46),L_(0x00000098), LL(0xd7e4cb2f,0x812cd124),LL(0x5ac9609a,0x83d9653b),LL(0x690acbe2,0xf981cac9),LL(0xc894c3a8,0xd274538e),LL(0x286285d9,0xc202f8f4),LL(0x24269d02,0x51bb2579),LL(0xe768b7b8,0x121f910a),LL(0x8baea845,0x76c44d58),L_(0x0000006d), + LL(0xf6a81b1e,0xcf66e145),LL(0x2a3bda3a,0xa88833db),LL(0x44164a42,0x4e0df1ec),LL(0x754bd187,0x89a6c53a),LL(0xff8dc770,0x961d8b4b),LL(0xa3761531,0x87d46b93),LL(0x31b05601,0xf7105b06),LL(0x4ef74177,0x500c6356),L_(0x00000082), LL(0xbc131ab6,0x4688d4bb),LL(0x6977d5eb,0x82e94cb0),LL(0x8706473c,0xb785ac18),LL(0x7362c724,0xae704972),LL(0x3b45de5c,0x2e6bdb68),LL(0x2c67f7d5,0x99b0063e),LL(0xa06ed86c,0x4969a5c7),LL(0xc4bf63b2,0xe55691fa),L_(0x000000b8), + LL(0x32f70f29,0x4140b7bb),LL(0xbcda177c,0x0fdc8422),LL(0xad59d7db,0xd2a3a29c),LL(0x9c1893f4,0x8f80936a),LL(0xe60fd330,0xa903804b),LL(0x6b3cc7d2,0x0e38278b),LL(0xfcb7a0c8,0x31deb3a4),LL(0xb47a9458,0x3c25cfff),L_(0x00000030), LL(0xc70a541d,0xcbbeaa75),LL(0x6f004b75,0xd7f127d6),LL(0x1d4ef334,0x15636fa0),LL(0x758ac159,0xa2548921),LL(0xb047a7de,0x60705693),LL(0x128b4b7e,0xa5696c87),LL(0xf499a64e,0xa206ac49),LL(0xf272bcca,0x1f6883bd),L_(0x0000005b), + LL(0x7a4b896d,0xb2e00072),LL(0x47a68dd1,0xd43d9655),LL(0x1ce79a50,0x6abc1f1e),LL(0xec87252c,0xe7160fe5),LL(0xb60d6a5a,0xdcf45caa),LL(0xd235985f,0x1b3180d9),LL(0xf8982569,0xdc646ab8),LL(0x446d6798,0x7ef649f0),L_(0x000001d0), LL(0x6eec719b,0x5f9db663),LL(0xcc9431de,0x38f4a187),LL(0xef383b03,0x3dbac366),LL(0x2fa36674,0xcc0b0d02),LL(0x5760fac1,0x67948b1b),LL(0xe8d42650,0x93934495),LL(0x4f889216,0xd3c64b8f),LL(0x1cd8ec2e,0x0eb0d528),L_(0x00000107), + LL(0x107d6bfc,0x5816dc43),LL(0xb8b5b662,0x1fe1463b),LL(0x973f88f0,0x4370119d),LL(0xc84691e3,0x153d37fa),LL(0xd0059b51,0x9a4e583e),LL(0xe99b060f,0x24c8671a),LL(0x8d5b7c8c,0xfdf410b1),LL(0x0db2233f,0x9b0e342f),L_(0x0000006a), LL(0x08c95cdd,0x07dbde25),LL(0xf5273466,0xf0969049),LL(0x76e98baa,0x8cba001d),LL(0xae173b76,0xcde8bcc2),LL(0xf10bd659,0x09ae5065),LL(0xc7bec674,0x5cecdf22),LL(0x4bdaed4b,0x41bc9eb9),LL(0xc459b9e5,0x7e368546),L_(0x0000007c), + LL(0xd08a3672,0xbcb161c1),LL(0x52ff0a6b,0x0593dede),LL(0x4b01e845,0xb5c016b2),LL(0x421052e7,0x65c310a3),LL(0x6c1dd249,0xf97c5a2d),LL(0x5a4e53fc,0xe551417d),LL(0x0e004126,0xbf9b31fa),LL(0xc101bc8b,0x43a5bd25),L_(0x000000c2), LL(0x2811e723,0xeaad08c2),LL(0xcc586f7d,0xc771ce2f),LL(0x8c0556ea,0xef8166e5),LL(0x32556e9b,0x2d11bd0c),LL(0x11e66977,0xfe7d92c3),LL(0x646a8dfa,0x58b69181),LL(0x8a624576,0x5de6bd35),LL(0xdeb3cceb,0xffa1c827),L_(0x000001e2), + LL(0x88f96f05,0xc1d3ecbd),LL(0x3593555a,0x3073315c),LL(0xb56c336e,0xaec91693),LL(0x5eea4cf3,0x2eade86a),LL(0x90e05846,0xe134f505),LL(0x9189d76c,0x8d429f7e),LL(0x0feade8a,0xf0013b30),LL(0xe083daf3,0xa7b56e97),L_(0x00000103), LL(0x817e33d7,0x9c2537c7),LL(0xa44bf13f,0x9a6a317a),LL(0xda31eee4,0x35ae34c0),LL(0xa0379d97,0xd66b27c5),LL(0x76a48571,0x1ae6d028),LL(0x5d83028d,0xbb8dadac),LL(0x1e4ebd89,0x8aaff54e),LL(0x67e3f97d,0x528b5683),L_(0x000001d8), + LL(0x9a7f8ba8,0x2992a59b),LL(0xa9efff68,0x1a328627),LL(0x3c1d097f,0x555f21eb),LL(0xf75afbb3,0x48ff742c),LL(0x4bf1016a,0xa10b236e),LL(0x5c770a94,0xff3e57b4),LL(0x5915a516,0xc042020f),LL(0x9df7440a,0x8d21ed86),L_(0x00000017), LL(0xecaea7dc,0xbf14c4c4),LL(0xd0035f1c,0x8343dde4),LL(0x19dfc08d,0x3a483722),LL(0x5b130cf1,0xc107a176),LL(0x30fc7b7f,0x6717617b),LL(0xf8cab932,0x626ffb5f),LL(0x59269de8,0x74af7c16),LL(0xbf37b9d1,0x4c20580d),L_(0x00000031), + LL(0xd31224fc,0xe9393683),LL(0x52cacad0,0xd4fad3f5),LL(0xd36819ae,0x14ee7de5),LL(0xb8c9f302,0xdb882d76),LL(0x103a3f52,0xb3362378),LL(0x1728ce43,0x0f7553db),LL(0x29c76302,0x56ba2d84),LL(0xc2f44114,0x28cc209f),L_(0x00000102), LL(0x3c639715,0xd8b8276f),LL(0xacdd7488,0xac8ea8c0),LL(0x912aac3a,0x8de7940b),LL(0x3dabab2d,0xd5bb2c71),LL(0xbc3f4a45,0xbcc2e33c),LL(0x2bf9f840,0x9d0edeba),LL(0x4b00c80e,0xcbe852a6),LL(0xbe4c368d,0x48bbcf91),L_(0x0000011d), + LL(0xc2974837,0x06284fef),LL(0xe24d882e,0x7041703c),LL(0x6f37e52f,0x5e1e37fd),LL(0x7853375d,0x145a0690),LL(0xcc75898e,0x270c5225),LL(0x61f33577,0x82c5658c),LL(0x777ab969,0x47024eca),LL(0x315f136f,0x85165412),L_(0x00000180), LL(0x8c1cda05,0xb7db1fe6),LL(0xedf31bed,0x7f07ba36),LL(0x8079b5f2,0xcdbc2d84),LL(0x22d262c8,0x4bb1ece6),LL(0xb457935a,0x79793249),LL(0x8614cc62,0xe89f8430),LL(0x258e4fa5,0x836da5fd),LL(0x759ca7b4,0xc0d83009),L_(0x000000d5), + LL(0xfa6cf668,0xce181709),LL(0x4b169dbb,0x5bee0010),LL(0x618d280d,0x28a88cdb),LL(0xa9c8042e,0xd8239424),LL(0x8ce15b95,0xcfce331d),LL(0xda740deb,0x6f83c378),LL(0x3c616a52,0xfc05f1b1),LL(0xda236e18,0x3be27f3b),L_(0x0000011a), LL(0x8647ebee,0x64ec0125),LL(0x0db33259,0x91422332),LL(0xf49a7d94,0xa2819732),LL(0xcccef356,0x9b90c693),LL(0x87f18954,0x805deff2),LL(0x22aa64c0,0x294b5e96),LL(0x352be09c,0xa610a1bc),LL(0x8368526f,0xd20e437e),L_(0x00000183), + LL(0x8a8479d8,0x893e0d1c),LL(0x045ea96a,0x972cecee),LL(0x37445b26,0xb250ed0b),LL(0x1c0a16a9,0x08e477bf),LL(0x7509c768,0xc826b683),LL(0xb74870c4,0x008a3f9f),LL(0x4d580408,0x4b88d0f7),LL(0x18d474fc,0xb871463d),L_(0x0000003f), LL(0x2fa143fb,0x726dcabd),LL(0x36d39ee2,0xe017d3cb),LL(0xd8d9e011,0x43bd77e2),LL(0x332c8650,0xc8965069),LL(0x3231a13f,0xf7a775c4),LL(0x1e3de078,0xe93c91cf),LL(0xe0f7c892,0x50d48604),LL(0x27097492,0xf1d9b31d),L_(0x00000042), +}, +/* digit=66 base_pwr=2^330 */ +{ + LL(0x9e603471,0xfb50e447),LL(0x2536308c,0xf617634a),LL(0x9549272f,0x302ba17f),LL(0x3e264556,0x0f6ed916),LL(0xddb056ef,0xc67d2e92),LL(0xf04b9449,0x7bf608be),LL(0xe0fd2d62,0x5ba41494),LL(0xfaa0f9ad,0x7c857eca),L_(0x00000074), LL(0xac0394a9,0x9ed3e6c1),LL(0x9017e273,0x2bf950e4),LL(0x441c9b0d,0x9856ca69),LL(0x717b7978,0x3315b53c),LL(0x66f1bf12,0xc5bce131),LL(0xdc85d5ff,0xf7b0dacb),LL(0x32365700,0xf85306a7),LL(0x22ce0f19,0x406e80fc),L_(0x00000011), + LL(0x4ae474b2,0x3a2640ed),LL(0x3684de2b,0x21f91da9),LL(0x424bab62,0x9955df67),LL(0x50d60209,0x5193b4b5),LL(0x196c99d5,0x8e9f2748),LL(0x7e7f3c74,0x31e6b3fe),LL(0x257248f6,0x73f47f4e),LL(0x56db9ba3,0xb50ccf8f),L_(0x00000137), LL(0x48bc357e,0x3556892c),LL(0xfa4353a3,0xb72124cf),LL(0x6ea40bee,0x1dbe3505),LL(0xb37aa3c7,0x2e951ca1),LL(0xaddc96c7,0x71de6fca),LL(0x58ae291c,0xf88244eb),LL(0x96fd42af,0x7e89a7bf),LL(0x1c5d8ae9,0x9ba25eb4),L_(0x00000178), + LL(0x5894fe38,0xa61f78f7),LL(0x1b7d597b,0x4cc9003f),LL(0x94b8d7ad,0x0c50139b),LL(0x899c26b5,0xd4d5af57),LL(0x5801efbb,0x7d0705ee),LL(0xc45f009b,0x345f5d52),LL(0xc52fa5f2,0xda142009),LL(0x8d175fe7,0x7812ca18),L_(0x0000004c), LL(0x3b59142d,0xc3639f82),LL(0x8ec202a8,0x87394d85),LL(0xb2496e6e,0xa4035f4b),LL(0x7b3e291d,0xcab52bdd),LL(0xda4a9abd,0x41430674),LL(0x23a5aab4,0x7c18c413),LL(0x57ee045c,0xe39c61ef),LL(0x6008e4d9,0x54734790),L_(0x0000017f), + LL(0xc78ac751,0x51e9a589),LL(0x6a5f85af,0xc09d63e5),LL(0x8ce24a89,0x9b655b51),LL(0x5441652a,0x9b445da7),LL(0xf4ffab48,0x9523b0e9),LL(0x23e77128,0x90aaf7cb),LL(0x99234af2,0xb5c9bc78),LL(0xa65dc198,0x8246a1dd),L_(0x0000003f), LL(0xfaeeacca,0x00e72c44),LL(0xa2bbbd59,0x47a63782),LL(0xf531aecb,0x67c393bb),LL(0xc7dda450,0x31630b09),LL(0xe719fa6f,0xc95e46b2),LL(0xf849f3a0,0xdeaf5d70),LL(0x68299654,0x827dd5d4),LL(0x286bc1f0,0xb4def96c),L_(0x0000017a), + LL(0x9eae7cc9,0x62e9226e),LL(0x3410c389,0x2f9c24f5),LL(0x71f68cfe,0x090966e9),LL(0xa4f25f7a,0xbb4733af),LL(0x45a0c4d6,0x6303208f),LL(0x0dc0c0a0,0xc45e9f18),LL(0x9a589e6d,0x5c94f082),LL(0xb9c34b5b,0x9266dd1d),L_(0x000000e1), LL(0x9fc32695,0xaccb375d),LL(0x15ea0e6d,0x5d3b353b),LL(0xc2dc172e,0xdcb147d5),LL(0x96265816,0x7b5ea6b9),LL(0x7188496d,0x6c199f62),LL(0x067983d5,0x8be2b6ee),LL(0x804ab5f0,0xb8433a5a),LL(0xfb9701f7,0x08ec1b7f),L_(0x00000005), + LL(0xf346db2e,0x75d8b8a7),LL(0x6d441b3f,0x33c9dd4c),LL(0x49bf3101,0x43c1a96f),LL(0x586195d3,0xc64bca08),LL(0x797aa157,0x35872dbe),LL(0xf8494dd7,0x155f257f),LL(0x370900d2,0x42b380b7),LL(0x2ec6eba8,0x0de4106f),L_(0x00000122), LL(0xd54c0210,0x9ba3b710),LL(0xdf76d347,0x79738efe),LL(0x168b7e7a,0x59395338),LL(0x5be21cb3,0x786b578f),LL(0x6c93997c,0xb42b9419),LL(0xda95deb9,0x1b5aa55d),LL(0x1941c038,0x6282d548),LL(0xdc8f9a51,0x155e294b),L_(0x00000038), + LL(0xc54fa3d4,0xc9331956),LL(0x37673a44,0x95ef7146),LL(0x8699a77e,0x35d322ef),LL(0xe5aa4366,0xb0a5fb37),LL(0x1c2f8160,0xdaf11474),LL(0x6c679654,0x4ae2c0a4),LL(0x25f5bd9f,0x0cd1a20c),LL(0x2812f915,0xddb9cbb7),L_(0x00000116), LL(0x6ba35704,0xddf43f70),LL(0x66ebac5d,0xbd74a353),LL(0x5836be03,0x8be404aa),LL(0x606cb997,0xa72b6949),LL(0xe5570eb3,0xe6f5f53a),LL(0x1550fdd3,0xd841cc12),LL(0x83299eb2,0xcf113a07),LL(0x76117e23,0xb031e54d),L_(0x000001d5), + LL(0x0412d583,0xe9241a8a),LL(0xac6aa964,0x24077ab2),LL(0xe1536c1d,0xad189da3),LL(0xdf56af4a,0xfbfb6e01),LL(0x46ef9e57,0x8ca8e624),LL(0x7c9eb17f,0xcbcb351a),LL(0xf3eda4f9,0x0985fb54),LL(0x69708739,0x4d5e2c29),L_(0x00000119), LL(0x4656d8d3,0x4d7980be),LL(0x8d7ed681,0x65dbc6a6),LL(0xe9b6528d,0x433cebeb),LL(0x9dfcc27d,0x25c88d26),LL(0x273aec82,0x43f7caaf),LL(0x8662d906,0x1c78327e),LL(0xe4a09eb4,0x04763fda),LL(0xad9bd2f6,0xbfba2b0e),L_(0x0000005c), + LL(0x56bd282f,0xc5002426),LL(0x8905b0bd,0xc776fda9),LL(0x5fecb366,0x691702ab),LL(0x8c3c6d77,0x3eafba03),LL(0x7b9bb860,0xa5a38b66),LL(0x288652df,0x9d4dccfc),LL(0x8b876824,0xf937bd4d),LL(0xedcfeccb,0x8bbe45b7),L_(0x0000009b), LL(0x4223e6a4,0xffdb1d9f),LL(0x44384141,0x4395593e),LL(0x68a0f97c,0x4b9f43be),LL(0xa0157cb8,0x99290f7c),LL(0xcccef6ba,0xef0777fc),LL(0x4349cd23,0xc43d71c0),LL(0x17318622,0xa3bb9fb0),LL(0x5a9a1343,0x039a4c9d),L_(0x000000c9), + LL(0xd92ddb9e,0x22ba5c1f),LL(0x65cc6bf6,0xa333c9c6),LL(0xb76d024f,0x521f0218),LL(0x51355f8c,0xb277d241),LL(0x061005e2,0x36014e7f),LL(0x322c2c56,0x52d2dee0),LL(0x8916c0e7,0xf40b1b75),LL(0x0e73d5bd,0xcfe8f526),L_(0x000001ea), LL(0x2bc1b23d,0x34905a27),LL(0x31577092,0xac41b5aa),LL(0xf6758a71,0x0e95917e),LL(0xeccda7b1,0x35f458d2),LL(0x52d35c5f,0x61af1ed0),LL(0x42e21d1f,0x99ea1f96),LL(0x1b6c4f11,0x1c9ff42a),LL(0x5a729a64,0xdaa6b431),L_(0x00000185), + LL(0xa860137a,0x2bb38059),LL(0x7d4fcbe1,0xaebc7ba3),LL(0x3de80141,0xabc6d3af),LL(0x0ce79f66,0xecaf11f9),LL(0x9743b455,0x23367c7f),LL(0xcf9fcf33,0x458f9b06),LL(0xaf18324a,0x1dd894da),LL(0xc4c95fe7,0x09129d0b),L_(0x000000be), LL(0xe5b4edaf,0xff94f2f7),LL(0xdb54a58e,0xc8f912e0),LL(0x655ce3bf,0xdffa0710),LL(0xb0757830,0x0f2d4402),LL(0xb963f905,0x95d5e868),LL(0x098d24ba,0xcdbb826b),LL(0xba591cbd,0xb02b1feb),LL(0x6a8df836,0xd82281ce),L_(0x000001b1), + LL(0x108f42a8,0x9cf21db6),LL(0xddcfd187,0x555cfe2b),LL(0xaf269c11,0xe7b4d452),LL(0xc4011856,0x3cb7c3fc),LL(0xfe6e4559,0x415957c0),LL(0x8996b215,0x3b983b2c),LL(0xbe5cf31d,0x0312f953),LL(0x78abc3a0,0x37adff70),L_(0x00000185), LL(0xd52c0d6b,0x847e724e),LL(0x42bcb7b2,0xcfdfc839),LL(0x2ddac314,0x2aac1c0a),LL(0xa690e67e,0x60736a1d),LL(0xe310507c,0x15f2f407),LL(0xa30b8b85,0x03447dd4),LL(0xf3ddc7c2,0x87208fe5),LL(0x482e1135,0x70157470),L_(0x00000073), + LL(0x4b696b0d,0x98400d78),LL(0x671aa2b1,0x05e6f78c),LL(0x19c7b31c,0x2f26896d),LL(0x537e98fd,0xc925cf6a),LL(0x31498b2c,0xe43ae0bb),LL(0x5b628896,0x2cc9c889),LL(0xf81936b3,0xd5a79df1),LL(0xaa558d67,0xdd9726a6),L_(0x00000127), LL(0x947e26f1,0xd8102ba2),LL(0xcba2e206,0xf57819ca),LL(0xe1b53333,0xb14e41e4),LL(0x89b722a1,0xa87036c9),LL(0x43d9c2e8,0x8c5e594a),LL(0x8a9f09ad,0xfc198885),LL(0x96afae31,0xd164a447),LL(0xf6ad8705,0xa304b415),L_(0x0000018c), + LL(0x51de1f32,0xfe892ec2),LL(0xde0ad941,0xa5e0c485),LL(0x252b5759,0x04504e2c),LL(0xe069dceb,0xceea659d),LL(0x80061659,0xb3fe1e63),LL(0xee236d87,0x846da87b),LL(0xf97ae613,0xa90f8433),LL(0xe7abcaf3,0x2f8213d9),L_(0x0000008a), LL(0x583a7dc4,0x6598f335),LL(0x8097f299,0x89f7734d),LL(0xff15633b,0x8aebbf6c),LL(0xb01c7b6a,0xb5108c62),LL(0xc7f93ae2,0xf807ee31),LL(0xf990d4e3,0x34992a71),LL(0x9962859e,0x282fca85),LL(0x8047dde1,0xc000a572),L_(0x00000113), + LL(0x5945bc53,0xcf237d07),LL(0xe31f2468,0x1ef4bb2f),LL(0x641e2901,0x2c562b14),LL(0x06773e1d,0x2ff0373c),LL(0xca66e36e,0xc519e2a9),LL(0x716d0497,0xbfb75cdb),LL(0x9a1fa9e2,0x0dddfb32),LL(0x1e517999,0x6b953285),L_(0x000000a8), LL(0x9daa8f05,0xe87b5c36),LL(0xba374fa1,0xcd0b7e7d),LL(0xf9ec22c4,0xd20b7cb2),LL(0xdd4d581d,0x516610e0),LL(0x74ddb0da,0x126aa3e2),LL(0x4e09fb27,0x35d95ce7),LL(0x0c242711,0x40d02e9e),LL(0x926ede13,0x8d5dfa4d),L_(0x0000010b), + LL(0xb7d7682e,0xd8734ac8),LL(0xd322358b,0x75fcdec6),LL(0x56d9d86e,0xe72ffc35),LL(0x6c363b61,0xd1066f3a),LL(0x3d03c2ea,0x7095dbd7),LL(0xcd1674fd,0xb42f9972),LL(0xacc3e682,0x9370acc2),LL(0x80c71149,0xa71a76fd),L_(0x0000016a), LL(0x5a49c095,0xe1070948),LL(0xd0d2a294,0xe55bcaed),LL(0xa073e38c,0xd2884da3),LL(0x25346561,0x95d34747),LL(0xbed8195e,0x990b2c19),LL(0xefe701ec,0x17664aec),LL(0x4c59ce88,0xcb5f1246),LL(0xa23cc1c6,0x846bef85),L_(0x00000113), +}, +/* digit=67 base_pwr=2^335 */ +{ + LL(0x72a8d985,0x39a70c2f),LL(0xea7d5b7d,0xf6f8acab),LL(0x73f642dc,0xdeb95d02),LL(0x8a54bc56,0x3f3cc37d),LL(0x5a63f188,0x1ef1bba0),LL(0x8c074b83,0xe112f14c),LL(0x17f937a8,0x29897379),LL(0x4d335ca2,0x57340487),L_(0x000001ef), LL(0x998374f7,0x8ee96d7e),LL(0x7d432cad,0xbff9e11a),LL(0xe6665366,0xf6d56384),LL(0x9b692423,0xfc7e344a),LL(0xf75f044e,0xee1b3ddd),LL(0xa827ee60,0x9cd00df7),LL(0xb2612c93,0x3d529eb5),LL(0xc4ffa6a1,0x5e23ecd7),L_(0x000000e1), + LL(0x39c16671,0x3753ce58),LL(0x7356faf0,0x54c5f8c0),LL(0x1165a356,0xf5c1afc7),LL(0xd6adf86c,0x903b89f9),LL(0xba6b4966,0xbff86c3f),LL(0xb1519f4e,0xa87b0151),LL(0xbe4f95b4,0x85efd27b),LL(0x0513d263,0xee9e2b04),L_(0x0000014c), LL(0xd4622a63,0x2aca99c7),LL(0xa6efd8d9,0x1d6acf3a),LL(0x7e55d6dd,0x95a1b738),LL(0xdb119c22,0xd9703d10),LL(0xd11a67da,0x427c0f52),LL(0xe412eedb,0xe055192f),LL(0x174c7a31,0x404a5758),LL(0xfd4b1dde,0xbb21a55c),L_(0x000001f4), + LL(0xc51693d1,0x57ada379),LL(0x7b463243,0x9dea1156),LL(0x65ad7ad1,0x3431ffb8),LL(0x22995c21,0xbfb6e47d),LL(0xa47b2e96,0xecc87ed5),LL(0xb5d8ce10,0xab93da78),LL(0xe414756b,0x0b5319cc),LL(0x327dee6e,0x82e08d68),L_(0x0000010d), LL(0x68a2cd80,0xd1a1a9cc),LL(0x62b72c52,0x2c285a2a),LL(0x23638d39,0x1736a146),LL(0x90e668b9,0x99d14c12),LL(0xe73e0b34,0x0861672c),LL(0x88955dcb,0x7dc3cdab),LL(0x06284ae9,0x4fad41f5),LL(0xfe7ca883,0x16e468d7),L_(0x0000001a), + LL(0x370d119f,0x9990254b),LL(0x764d3fe4,0x8a86cb40),LL(0x39be0e2c,0x4b9820af),LL(0x458321b0,0x29475227),LL(0x2c2ba583,0xa07a5c7f),LL(0x52e9ae89,0xfa6d5206),LL(0xbdc0eee8,0x435604c9),LL(0x6f2e4842,0xd30a60c0),L_(0x000000ff), LL(0x1714a30a,0x66400030),LL(0xa3f37cbd,0xab87a938),LL(0xf3132874,0xecbe1c91),LL(0x7e9d7ac6,0x1734fae5),LL(0x7e33fb88,0x600765b0),LL(0xedfc073b,0x428cbfb5),LL(0x85e9a209,0xbd290285),LL(0x77ef7692,0xf50381e0),L_(0x00000057), + LL(0xec2103fa,0xa28d165e),LL(0x31bc9c0a,0x9e3c2272),LL(0x1db480d5,0xeefa29bf),LL(0x5fe970c7,0x0625c44f),LL(0xa6473b7b,0xd9e52858),LL(0x66b89d6b,0xea4cd7c9),LL(0xc3e3b579,0x3b6547a2),LL(0xa8bdce16,0x517b2e4e),L_(0x00000152), LL(0x66f8ad71,0x8a1901b7),LL(0x08802270,0x0ceae5cf),LL(0x853e6e60,0x63ae6ec1),LL(0xd89e54bb,0x1f365d84),LL(0x9e03d94f,0x49df44dd),LL(0xddc9e1b3,0xf70096c2),LL(0xba5865a7,0x6cc7a69e),LL(0x01800fb8,0xcbb03fad),L_(0x00000080), + LL(0x91cf34a0,0xc22b2802),LL(0xfd975370,0xe87a26b1),LL(0x662b3666,0x46d8088a),LL(0xa7466010,0x0988f2ee),LL(0xd8edbdfb,0x1f7fc1eb),LL(0xf4b2f213,0x266b6d41),LL(0x00896949,0xc83c1c02),LL(0x7c849de8,0xedffcbe2),L_(0x000001ad), LL(0x90bcda37,0x480ec74a),LL(0xdde9d726,0x26216e2d),LL(0xbef16495,0xa5c64b02),LL(0xfba3c749,0xc3f630aa),LL(0xea872930,0x8695df3b),LL(0xb21d654a,0xb5372491),LL(0xa2f3f6fc,0xe917f3b3),LL(0x13fe01cf,0x4b29c946),L_(0x000001e7), + LL(0x12faa2d3,0x93a86247),LL(0x67da197c,0xd4612a0b),LL(0xfd72cd4e,0x145bbdec),LL(0x8483b822,0xb4dba8a8),LL(0xf56d58c6,0x81ec1ed7),LL(0x708f26ec,0x631a5032),LL(0xf4782ede,0xb4b04fc8),LL(0x34a251ec,0x0d9db88d),L_(0x000001ac), LL(0x1b8eedbc,0xadbb93b8),LL(0x1b68a64f,0x2308b6f8),LL(0xc37e6bd6,0x392cec36),LL(0x7b419db4,0x0aee0e63),LL(0x1777f3d5,0xff167cd9),LL(0x706d5278,0xede81ea9),LL(0x2ecab8c0,0x63b7e96c),LL(0xb7b3cb43,0xb821ee5a),L_(0x000001b0), + LL(0xec8937b4,0xbb7112fd),LL(0x3ed5a415,0x66e9e19d),LL(0x01eab0fa,0xbbe65978),LL(0x740c409b,0xba92675e),LL(0xa050b19b,0x3e8b56da),LL(0xe6eedf2c,0x2fbcf099),LL(0xa55e0691,0x80195262),LL(0xf2c7d1e9,0x72121ee2),L_(0x000000f6), LL(0xeec1384c,0x51ffea5b),LL(0xeaca6749,0xd0ad477d),LL(0x45756473,0x1fd4ee32),LL(0x80864216,0xa3069430),LL(0x850c8b97,0x405f653b),LL(0x9de4340f,0x5a543cae),LL(0x347d550d,0xa331ca24),LL(0x75f4312e,0x7ca7992a),L_(0x00000002), + LL(0x6f04ee1f,0x5987ecf0),LL(0xe39114e7,0x8c92a999),LL(0x734b40d0,0x3eb0ff94),LL(0x35b97b9a,0xf3a7b34c),LL(0xd5b35118,0xd35276ae),LL(0xfa36fe0d,0x9e933110),LL(0x3c37067d,0xbe64ccaa),LL(0x9629f86f,0xf4e80957),L_(0x000001ef), LL(0x2f066fb6,0x69fb1dea),LL(0xd4e489f4,0x65ba5821),LL(0x3abd59aa,0xf0068abc),LL(0xf152d51c,0xfa26b25b),LL(0x4c7900c0,0x929fd963),LL(0x22beebe6,0xd19508e6),LL(0x6c8e147f,0x84fd88ff),LL(0x8a8eae8c,0xf8e5d746),L_(0x00000039), + LL(0x58c8162c,0x15dbf9ea),LL(0x7dd87f67,0x5523d821),LL(0x2bc5b0b4,0x8780b2c5),LL(0xb8903ecd,0xf92e785d),LL(0x54296f75,0x6397e404),LL(0xcce33c6e,0x84bad1cc),LL(0xd3c5f54e,0x95b82162),LL(0x33f935ae,0xddedf093),L_(0x000000e8), LL(0xf54ff1c3,0xb4ec10e1),LL(0xc2886785,0xa1634274),LL(0xe5822d49,0xbfab5d5e),LL(0xbe9122e0,0x955a062f),LL(0xf03c2cc2,0x579ad9b7),LL(0xf2e5e08e,0xdd6ee255),LL(0x1b65e701,0x934f08f7),LL(0xcd7d23cb,0x4d45cc9d),L_(0x0000007c), + LL(0xaeacb5da,0x9e604f26),LL(0xf00003d7,0xb32a37b8),LL(0x5e05fada,0x771ab3ac),LL(0x03aa3a60,0xe17eba9f),LL(0x31442064,0x7239319d),LL(0x021c13e4,0xa35b4712),LL(0x3f7e400f,0xc6e5283a),LL(0x5888abe0,0xbae7d910),L_(0x0000015b), LL(0x0081a506,0x59fee06e),LL(0x6e2f4f1a,0x372aea8b),LL(0x11014792,0x2416f852),LL(0x35841e3f,0x71de69f4),LL(0x710be3f1,0xfa1b9018),LL(0xd8151855,0x92a94717),LL(0x52addc4d,0xff148def),LL(0xea65eaa7,0x9642343b),L_(0x0000008b), + LL(0x01927819,0xd986cf50),LL(0xab17488d,0xeb6ebddd),LL(0x8628281f,0x92fa1e38),LL(0x4511bc03,0xe1691b01),LL(0x0b79c2a5,0xb842f844),LL(0x8805d866,0x343c71a4),LL(0xd5d795d0,0x042ac5c5),LL(0xedd85588,0xb87124aa),L_(0x000001b0), LL(0xfa896067,0x0d43dab8),LL(0xd6f1580b,0x9a3104ec),LL(0x840b3b59,0x76717c31),LL(0x41201091,0x2243eb78),LL(0x88de871b,0xe2323a38),LL(0x53ac3f7b,0x764799c3),LL(0xdaf476ff,0x999d244e),LL(0xc595b87c,0xbe221513),L_(0x0000010e), + LL(0x8985e912,0x3a4ec3d9),LL(0x639aa554,0x9515b9e8),LL(0x2b90b395,0xe330201b),LL(0x5d9f9a07,0x95f372a0),LL(0x83696835,0x0d679c0c),LL(0x8c8132ef,0xbc4509be),LL(0x5efb5013,0x1a4c14f9),LL(0x7a8442ff,0x59dd0f6b),L_(0x000000f6), LL(0x1d220323,0x607be429),LL(0x7b931a60,0x3b156b2a),LL(0x38e10514,0x36aabd76),LL(0x8ff10073,0x384c71ad),LL(0x3603a7b3,0x1c1f643f),LL(0xe305de49,0x08714206),LL(0x63b53241,0x57add901),LL(0xfba33a9a,0xf2cced51),L_(0x0000004e), + LL(0x03800832,0xceb77120),LL(0xc3398df2,0x625cbf7e),LL(0x4c74b442,0xdf67b9eb),LL(0x424f2515,0x6b977890),LL(0x2abc1051,0x2462b490),LL(0x7c8f5df8,0x6d60d980),LL(0x1bb838ca,0xff606aee),LL(0x1e7a2ff1,0xfb6f830e),L_(0x000001cd), LL(0x238fce9b,0x49a4c209),LL(0x73f7bb70,0xae2b39f7),LL(0xcfbf4b1e,0x53e2f55b),LL(0x7309ae96,0x026775b0),LL(0xfcf869d6,0x1b0e83da),LL(0x72ed99fe,0x02f8a21d),LL(0xe81bf7a2,0xd737619d),LL(0x2bf238b7,0xd0a7eb7b),L_(0x00000119), + LL(0x38b832fc,0xb158ca8a),LL(0xb03ae8bb,0x7420634b),LL(0xac8efa9e,0xaa8dadd3),LL(0x259a7c31,0x525d1488),LL(0xf727fdfe,0x8b687898),LL(0x48ffe9fc,0xfbbb696d),LL(0xb00d2cb4,0xf4a8353d),LL(0x9be76892,0x472fe4b6),L_(0x000001a2), LL(0xf73fea91,0x0e2a8788),LL(0xfce9c9d4,0x18c2b050),LL(0x3412a938,0x1844f4f0),LL(0xc14eff85,0x4ad5ef54),LL(0x0ad47ee3,0x01446b7d),LL(0x4c160f3e,0xc22336c4),LL(0xc43f42cf,0x64f51a4f),LL(0x34833c47,0xc43f0955),L_(0x00000133), + LL(0x7f8ca9dd,0x308270c4),LL(0x433780e1,0x2be3ff97),LL(0xb186cdf8,0xeb6471b0),LL(0x747ce696,0x05f60ab1),LL(0x815fe310,0x5a457da8),LL(0x6bb9ac1b,0x4901af0f),LL(0x925bd14f,0x652f972c),LL(0xacd8b58a,0x53143186),L_(0x000000a8), LL(0x3e0f3553,0xf7ba0c69),LL(0x6dbda5e1,0x5b11db3d),LL(0xe46fae1c,0xf1f51b89),LL(0x7c0b46b0,0xa48d5ec9),LL(0x1cc037ca,0xbdcc7599),LL(0xe5f40355,0x28784dc0),LL(0xd1a3fa4f,0x0b837ead),LL(0xb5a1926d,0x3098c9ee),L_(0x000000e4), +}, +/* digit=68 base_pwr=2^340 */ +{ + LL(0xde847fc3,0x2cc0ff17),LL(0x8ee8bde0,0x63e6fe38),LL(0x774123d0,0x97b1e73a),LL(0xf8cb9f55,0xee20c8da),LL(0x8b938535,0xa8b1bfac),LL(0x3df10d7d,0xe2a81936),LL(0xe7d42738,0x9979861a),LL(0xaf0a6779,0xc4dba03e),L_(0x0000012f), LL(0xbb611141,0xaefc5b58),LL(0x9b3d91d2,0x33633ce2),LL(0x0d5e3306,0x2544bfef),LL(0x8956c10a,0xbeaa2dd7),LL(0xcfa84101,0x8ba22402),LL(0x96a5f958,0x0df8f462),LL(0x34ace12e,0xc6c70187),LL(0xe0e00d25,0x01914ca8),L_(0x000001bc), + LL(0x8cc26d9a,0x4788e280),LL(0xddb52ac3,0xa2e3c895),LL(0x305bc55d,0x6e792cc3),LL(0xee807637,0x5f9d9986),LL(0x0da2d9cb,0xaea185a3),LL(0x56f8f0d8,0x8ef462b9),LL(0x096bebd6,0x300f61c2),LL(0x7be11b59,0x9b4cc44e),L_(0x00000051), LL(0x9dea58bb,0x2585fb77),LL(0x8271cd5b,0xd75c3d97),LL(0x5ac1a4b5,0x4eee827a),LL(0x6fe4d480,0x0147df6c),LL(0x7f66c09f,0x3f6a4c21),LL(0x92c3b320,0x1eeb9502),LL(0x17768418,0xebda3f44),LL(0x12f688be,0xfba26717),L_(0x0000002b), + LL(0xea4586de,0xdc25b073),LL(0xf24773b7,0x49b36fcc),LL(0x8466e794,0x3cc03245),LL(0x36f85404,0x02d71d6f),LL(0x251e24c9,0x1a81ea4c),LL(0x9e39ec68,0x0e710d11),LL(0x0e27e696,0x44dfa8e5),LL(0x6885ae0f,0x4f91bbc9),L_(0x00000100), LL(0x7872cc7e,0xb8224b0f),LL(0xb5696e54,0xe5d4bd3d),LL(0x64ead37d,0xcbad27cc),LL(0x5b2f36d2,0xa45e529b),LL(0x521210e2,0x788fbf74),LL(0xe1bd2c8d,0x40c5440b),LL(0x2b990184,0xbc157b39),LL(0xeeecc510,0xca9c145d),L_(0x000001c7), + LL(0x241f3444,0xaf242ed2),LL(0x73f71786,0x82ffb7bd),LL(0xee8f684b,0x0b940040),LL(0x0e0a7766,0x3cb9180b),LL(0x05509077,0x41ff934d),LL(0xd7e63b43,0xfe154397),LL(0x597b1f2e,0x73566086),LL(0x115dad8d,0x8383d38e),L_(0x00000032), LL(0xa0320279,0x44ad3c59),LL(0x95d0b92b,0x9546c02d),LL(0x17644016,0x0cf317d6),LL(0xb1278de8,0x0cc035b3),LL(0xa150eec2,0xa454911c),LL(0x40f34047,0xb15350f1),LL(0x64a854ce,0x24297dd6),LL(0x45fd389a,0xfddaec15),L_(0x000001d2), + LL(0x1b54c6d4,0xd46442b3),LL(0xc94971a5,0x8eb97dd3),LL(0x9e3e1ff6,0xe2df3525),LL(0x058db0b2,0xe0b69449),LL(0x46968077,0x4ea6ec9f),LL(0xba76456e,0x8457796a),LL(0x77183369,0x255412cc),LL(0xb4e4306f,0x9bbd6c5e),L_(0x0000005e), LL(0xcef4a91b,0x57dadc33),LL(0xb934de9a,0x51f56ade),LL(0x2e8fe341,0x49ab29d2),LL(0x85723b5e,0xfabf520f),LL(0x1ee66b41,0xbffe6761),LL(0x0a605253,0x50202f55),LL(0x9e49468c,0xef6d250b),LL(0x956ea13f,0x0c1b81a2),L_(0x000001e4), + LL(0xe30dc097,0xb5323240),LL(0x3dd49c5e,0x082d33c5),LL(0x17c692b6,0x12bc5d69),LL(0x7e9d695a,0x02c7fd33),LL(0xb78372d6,0x85e92117),LL(0xefa0ef29,0xceacebcb),LL(0x9b4e8e18,0x3d68cc3e),LL(0xe3e50ee1,0x56a48db3),L_(0x000001d4), LL(0x5f980bec,0x9b062f58),LL(0x03edaeaa,0x83ee3b51),LL(0x4f1f8028,0xe4a60553),LL(0xd292d29e,0xf95f8dad),LL(0x7f9ba28d,0xfb5785f5),LL(0x54b8d134,0x0fe162fe),LL(0x2bd8287f,0x2247f090),LL(0x769ce1a1,0x5ebc6de3),L_(0x0000001a), + LL(0x416e3d53,0x74341e71),LL(0xa2b4eeb7,0x9e6b225b),LL(0xff742236,0xd3c824dc),LL(0x5e3b9c67,0xd547224d),LL(0xc6e4276d,0xcc105d46),LL(0x8a001d2d,0x92da4b3a),LL(0x3b252483,0x67e2f395),LL(0xcbb5174b,0x659222fe),L_(0x00000118), LL(0x2308d720,0x4e2e8071),LL(0x9562db9b,0x1bf6b116),LL(0xb14e6841,0x45f6d2ac),LL(0xbfd32572,0x8cdf458c),LL(0xe189ac1c,0x3f894fd3),LL(0xb5d6ee49,0xa59cbf0a),LL(0x672a0c8f,0xd8476d8e),LL(0xfbb78753,0x104d6ed9),L_(0x000000a1), + LL(0x4e39334c,0x0560e3e7),LL(0xc62b58ab,0xfa2ff6e2),LL(0x25b0cfee,0xe3dacd7d),LL(0x56f469ae,0x6476d0c4),LL(0xaa862fad,0x0d8d2340),LL(0x468a688f,0x648a9494),LL(0x9d4d2feb,0xe9f4ed20),LL(0x3e7c5890,0xb2f118a9),L_(0x00000039), LL(0x12cdd07e,0x60784376),LL(0x8d6d1246,0xea183586),LL(0x85400753,0x5c35ba6a),LL(0xf252808d,0x57ba4df7),LL(0x07b45d68,0x048ddde7),LL(0x8c60d683,0x759393e3),LL(0x919b183c,0x760c630e),LL(0x90171725,0xc0e42720),L_(0x0000007e), + LL(0xc6d9113b,0xdfe5709e),LL(0x1b269289,0x74793368),LL(0x0c1477a3,0x3c2fbb12),LL(0x544d389c,0xbce04baa),LL(0x4fcb6058,0x52137546),LL(0x62503bea,0x306eaabe),LL(0xb0495976,0x49afd268),LL(0xa62777c0,0x9d57af71),L_(0x000001c4), LL(0x5a2c2301,0x122ed53b),LL(0x23b67f05,0x68235f24),LL(0x0b4f5601,0x850a3bcc),LL(0xfc63cfca,0xfb6987d1),LL(0x7f3a86aa,0xeb70f694),LL(0x726395f3,0xe2648fe0),LL(0xfc883eec,0x04f6906b),LL(0x551243f7,0xb7f9a9a2),L_(0x000001b1), + LL(0x1329d8d9,0x09b5385e),LL(0xe206cc29,0x8ad6ff5e),LL(0xaa658f94,0x8f946f98),LL(0x428d98ec,0x2b10de6d),LL(0x3ec6baf6,0x7efb3f61),LL(0x21982753,0x47b7f15b),LL(0x578e65b3,0x63e00597),LL(0x5b3f1a2b,0x4f67290b),L_(0x0000003d), LL(0xec6244fb,0xb103454a),LL(0xbf7ff50a,0xc09eeea3),LL(0x5b8194a6,0x117b25e8),LL(0xb8d95b3b,0x4719134d),LL(0x98e3eda5,0xfb408475),LL(0x184c4131,0xaae4a703),LL(0x433cd4bd,0xee1c89f5),LL(0xec3f5308,0xffc4a25f),L_(0x00000190), + LL(0x0a7c8b60,0x2ac3e5be),LL(0x35df434c,0x73674292),LL(0x218ab0b7,0x377ea177),LL(0x971e7bf8,0x979969d0),LL(0xa6fc69b3,0xf051da86),LL(0x0f199014,0x50a5af5c),LL(0x0bd76f2a,0x68112265),LL(0x6ef71ee6,0x92fc81c9),L_(0x0000002a), LL(0x2c92d1d2,0xa2718b70),LL(0x8bc153fa,0xefc700c8),LL(0x7d63139e,0x11bfab90),LL(0x63a1a94a,0x1c81d0a8),LL(0x0af04b86,0x5010811a),LL(0x65f6b2d4,0xd230f7b9),LL(0x346b9acb,0x92db7ff2),LL(0x791ad571,0x423539f4),L_(0x0000016d), + LL(0x0bfa96fe,0x4b219ff8),LL(0xe186bb8d,0x34f0b2a5),LL(0x4bbcffce,0x74e4771d),LL(0x4fa8ab52,0xa8af538f),LL(0x0bd9aa17,0x55b8ec20),LL(0x24b82cd8,0x55a1e2c4),LL(0xf54b7fae,0x34a02ce9),LL(0x011a367d,0x3f61c656),L_(0x000000e6), LL(0xb4418223,0xf5b325cc),LL(0x48062883,0xae0ea746),LL(0x3f6511a6,0xa6b89032),LL(0x057c30cb,0xe93a6d10),LL(0x00156e39,0x0c08d7cc),LL(0x7ef1eeb2,0x713dea1e),LL(0xeb905073,0x1c6abbcd),LL(0x4e60ee01,0xb23a579c),L_(0x00000093), + LL(0x1db48f4d,0x239e10c2),LL(0x3cbc9af9,0xde4c09f2),LL(0xabdb2bfd,0xed72b749),LL(0xf64b181a,0x928d6d6b),LL(0xc85d2a91,0x9af06cb2),LL(0x32a985b4,0x67685c7b),LL(0x4cf68328,0x607e3b33),LL(0x96bdc7c4,0xa7e4db64),L_(0x00000004), LL(0xc31b32d2,0xd33b72d3),LL(0xf9f3e673,0xd3e9eee6),LL(0x42fb631c,0x43164033),LL(0x6eedae95,0xaab1e76b),LL(0x986360ea,0x9e6c1afa),LL(0x30e60546,0xffd16939),LL(0x06fbdf1b,0x989aed4f),LL(0x7870903a,0x905f7535),L_(0x0000008f), + LL(0x1065b996,0x62ecea90),LL(0x92968f64,0x48a2356f),LL(0xe74f9d69,0xc38162fc),LL(0x799bc2e4,0x109958a5),LL(0xc2cf37fd,0xc511c5bf),LL(0xb810f3aa,0xba774e2d),LL(0x04423cab,0x7df651dd),LL(0xfa41efc5,0xd82de4be),L_(0x00000005), LL(0x843bf3e9,0xca2ddefb),LL(0x07001aa8,0x2325dc6b),LL(0xfb77a925,0x19ebdc37),LL(0x984cbf76,0x991269aa),LL(0x0ea96690,0x5a99df72),LL(0xf5a76c72,0x261ea01a),LL(0x11ed492c,0xec2261aa),LL(0x511c25de,0x10d398dd),L_(0x0000018c), + LL(0x79d76ece,0xdf3265ef),LL(0xdd97cbec,0x1201ac02),LL(0x82ed80a6,0x3e075507),LL(0x2e6d2b22,0x16c3d5bb),LL(0x9b31411b,0x89a53e5c),LL(0x4570ab97,0x5d2d34d3),LL(0x76b65f73,0xd36a94bd),LL(0x3b4c1384,0x10e67e38),L_(0x00000044), LL(0x91c17d4a,0x850a6308),LL(0x5b75be0c,0xa8eb3e41),LL(0xc4b1a960,0x5176e7e2),LL(0xef74a564,0xf493e8d5),LL(0xd77a5683,0x2824a377),LL(0xdc2b6e93,0x3d90456b),LL(0xf50c072e,0xfe49afc1),LL(0x3768ae59,0x7326363a),L_(0x000000f2), + LL(0xc160ead5,0xf73cb6f0),LL(0xe2cd2bce,0x53fb7eb3),LL(0x9bb7bc05,0xb6b62b31),LL(0x8a471706,0xdaf298a3),LL(0x846c6b42,0x9d404cf9),LL(0x085e05e5,0x8fac2e73),LL(0xc53893b4,0xa8ff0af6),LL(0xe3d8eea7,0x0310bde9),L_(0x00000017), LL(0xe934470a,0xc1af94ed),LL(0x89b3f0c4,0x4fba6b38),LL(0x9af80496,0x3e423ee4),LL(0xd89fd53a,0x793fadf0),LL(0x353cc302,0xcd463b61),LL(0x51fbb36d,0x782e102e),LL(0xd6d1c6c3,0xbbc63732),LL(0xc97f604b,0xb60ab59d),L_(0x0000019a), +}, +/* digit=69 base_pwr=2^345 */ +{ + LL(0x5fdb3148,0x0a1bc3a0),LL(0xbda07174,0xc265e95e),LL(0x43b1d3c4,0xedc546d6),LL(0x611b9709,0x807b04c2),LL(0xe15784fc,0x473ceec4),LL(0x58afe5bd,0xc97fb33e),LL(0x7b94dc53,0x39d6d532),LL(0x914fc6dc,0xfc2ee62a),L_(0x00000094), LL(0x67cbcf73,0xdf80627a),LL(0x67d3e029,0x91ccf95a),LL(0xfd91b52d,0xa53ec7ae),LL(0xa855273c,0x1131573a),LL(0x07213a95,0x49db550c),LL(0xfa5fb98a,0x470643af),LL(0x0fa67f5b,0x6bf0628a),LL(0xf906186e,0x01bb6d2c),L_(0x000001b1), + LL(0x7f1be067,0x7f152d2c),LL(0x8659f773,0x242f8dec),LL(0x8df47d63,0xcbac7d95),LL(0x91c63b0a,0xf620881b),LL(0x8c2c6ad3,0xda54c002),LL(0x701999ad,0x3012f693),LL(0x99516f6a,0x3c14f4c4),LL(0x68d44cb7,0xc5e6fda0),L_(0x000001c7), LL(0x1d209ec5,0x76dcc740),LL(0x51dc58e8,0x93231067),LL(0x4e14fe98,0x5a4f75f2),LL(0x88f5086e,0x4ccd6aac),LL(0xf294dbdb,0xedf86543),LL(0x30e3be99,0x767f48ab),LL(0x22dcd0b3,0xd87667c6),LL(0xd6615681,0x36829d7f),L_(0x0000011a), + LL(0x0d5b110b,0x1e6c13e6),LL(0xa0842e9d,0x58585159),LL(0x443356f4,0x265b46fe),LL(0x3b25c086,0x87729185),LL(0x0ebbff20,0xc71c4d1d),LL(0x79c2136e,0x3ebeca5e),LL(0x3a96ed20,0x32a0af3b),LL(0x012e330a,0xb9939f93),L_(0x0000016d), LL(0x7d17ed67,0xde583a56),LL(0xe5703cea,0x316840b4),LL(0x03d396ce,0x0cfc4143),LL(0x6970ea48,0xb1974ced),LL(0xa63761b9,0x3de4383d),LL(0xe400788f,0xd07d6726),LL(0xa545993a,0xa33056bd),LL(0xd3fe822e,0x9a96c385),L_(0x000001b5), + LL(0x2f073480,0xf78fb060),LL(0xb2604448,0xc2ac8aeb),LL(0x277ca03f,0x27864b78),LL(0x2c6f473d,0xeb1664eb),LL(0x7cb793a9,0x58eee9a3),LL(0x9c2ce2b3,0x94f18cbc),LL(0xc87a3dc1,0x2df6078b),LL(0x0e93cd11,0xc8181622),L_(0x00000009), LL(0x3fd1ed5d,0xbe10752f),LL(0x0c38fb72,0xd1e47666),LL(0x9b093c35,0x73ab1d6d),LL(0xd898dff7,0x00e4cf26),LL(0xc4b445df,0x422c1136),LL(0x9ee0d1ce,0xb6e821b5),LL(0xe82511ed,0x1ade6252),LL(0x81c804e4,0xada5e2f4),L_(0x0000012d), + LL(0x47ebbcfa,0x75ed251a),LL(0xc45b660c,0xef50c145),LL(0x733af648,0x00ba4ec8),LL(0x5119e848,0xb32a226b),LL(0x3e048abf,0x1f648014),LL(0x7a1eccf1,0xfab712cd),LL(0x2badbf53,0x1ebfb8b6),LL(0xca11e7be,0x07ff38dd),L_(0x000001b2), LL(0x789ae7e1,0x42374e6e),LL(0xa641227e,0xb2f0016d),LL(0xa82cadf5,0x8ca0d43e),LL(0x552e57fb,0x5a71e67c),LL(0xa8bcdb55,0xc3a4e9f5),LL(0x6e0e2bb2,0x124b38d4),LL(0xc1f40c89,0x60b28fe4),LL(0xabb2620f,0x69bcc1f8),L_(0x00000140), + LL(0xfaecca00,0x028ae659),LL(0x3a3c5350,0x656b887c),LL(0x5b3bb83d,0x0c6fbb7d),LL(0xc2d4fb00,0x8f5877ba),LL(0xea3d0289,0x01e01a3d),LL(0x943983b2,0xdcb878b4),LL(0x382b3bfc,0x7e566dbe),LL(0xe238f00d,0x8ef9130d),L_(0x000000a9), LL(0xcf1a3019,0x6043d5c3),LL(0x3f970442,0xd72b4978),LL(0x47e77b41,0x51765a88),LL(0xd9f49bc6,0xc2232c0f),LL(0xf1592cf2,0xba6cd5b1),LL(0x7bdf89de,0x33024471),LL(0xa56dd8d4,0x4e3c8e30),LL(0x6718468d,0x5ba5d7f6),L_(0x00000062), + LL(0x1c158b81,0x3cf9ac17),LL(0xe81b84be,0xb9565ca7),LL(0xcf197d97,0x30adec74),LL(0x0f74f924,0xbbec4f93),LL(0xc6810de9,0xdd1aa6b4),LL(0x68e13e67,0x31b1e868),LL(0x3b5ec800,0xb287ff46),LL(0x970d17f9,0x56052d48),L_(0x00000171), LL(0xfc348975,0x3990d639),LL(0x2c996afc,0xbf8e72bb),LL(0xc43038ef,0xf3f9e817),LL(0x673d9367,0xb8d625be),LL(0x33a4c44f,0xb72553a3),LL(0x6135473a,0x7365b95f),LL(0x91b434c7,0x70995374),LL(0x2e7887e0,0x42eef182),L_(0x0000009c), + LL(0xf8d7989a,0x1b1a9086),LL(0xb30f16f9,0x2b4d5672),LL(0x919c3dae,0x64f72009),LL(0x3b6ec0a9,0x64ce5600),LL(0xc12b7f4f,0xe0f0d4fb),LL(0x144476bf,0x3eb40f82),LL(0x0332a8a4,0x80cbb448),LL(0xf3755660,0x689dbf3f),L_(0x000001e5), LL(0xe518caf3,0xa53d6591),LL(0xe170d9ab,0x4f1b1b50),LL(0x3e56ed3e,0x7c4f9eca),LL(0x8dfe4cc6,0xfa0dd028),LL(0xa59c7726,0x0a01f234),LL(0x6c8fa066,0x704007db),LL(0x8366767a,0x4570b32e),LL(0x94810fb8,0xbae24969),L_(0x000000bc), + LL(0xce3ac7a6,0x5ab23199),LL(0x54772e62,0xd7eb0723),LL(0x8caedc24,0x76dd866b),LL(0xa41bb763,0xba5b9e92),LL(0xe6d92de4,0x28e72bc3),LL(0xce269dcb,0x2b7dc535),LL(0x7e64fab4,0xe7cccbfd),LL(0x02a03896,0xcec461c3),L_(0x0000014b), LL(0x3dc101fd,0x079c3e36),LL(0x2332d512,0xf51726ad),LL(0xdbc6dd2c,0x81e5e3b6),LL(0xbd26d73b,0xb2e70917),LL(0x24b0b54b,0x23cdf2f9),LL(0x0353dd40,0x5e2acffb),LL(0x2e871e61,0x07f5e7c3),LL(0x5b299ee3,0x191257c5),L_(0x0000004f), + LL(0x3ec2ad9c,0x115859c9),LL(0x1f8e247e,0x17b4d84b),LL(0x2585ef39,0x657d1198),LL(0xa3f20465,0x3619c497),LL(0x6901431a,0xe9a26e53),LL(0xa5276fd0,0x496e3f3c),LL(0x1f276a6e,0x348de17d),LL(0xf8c3af85,0xc8630fca),L_(0x000000cc), LL(0xb1e10393,0x7b5ce8d7),LL(0x6deb4f48,0xc7dc292e),LL(0xc43c502b,0x6b03f2ee),LL(0xb1a1182c,0x39273259),LL(0x7622b369,0x4498e583),LL(0xfe7d43c5,0xa50df54f),LL(0x61447fad,0xc4339095),LL(0x3a9a1f2a,0xda206eb7),L_(0x0000005a), + LL(0x4af9a66e,0x310c7a00),LL(0x8db46828,0x9223ef88),LL(0x2cf042cc,0x6fa5a04f),LL(0x7c559200,0x6daaab2b),LL(0x91afc691,0x98a36fb2),LL(0x00b03676,0x188b128b),LL(0x51264914,0xb9803ddb),LL(0x75459c1a,0xf41eea62),L_(0x0000019d), LL(0xe3aaa000,0x7a690ecd),LL(0xceb2c1c6,0x8880b402),LL(0x45703d2c,0xc0613e4c),LL(0x8b8c9eb5,0xc5db208f),LL(0x4c846b8c,0xa9987715),LL(0x6bd91493,0x42b48717),LL(0x9a26dd34,0x3e788715),LL(0xd9b2c58c,0xb5cd631e),L_(0x0000017d), + LL(0x361ab1b5,0xccf7e9f1),LL(0x24eb3b91,0x5a00b663),LL(0x3a047d69,0x70c649d7),LL(0xff025b44,0xbfc42749),LL(0xf2772669,0xfa1fa0b0),LL(0x1d856fe2,0x59b50aeb),LL(0xdd9c5baa,0x07db1f1d),LL(0x63853e29,0x1535fdcc),L_(0x00000054), LL(0x924ac747,0xaa197f48),LL(0x269fd103,0x40db5d37),LL(0x4cdd9698,0x1838b760),LL(0x491094a5,0xfe6931b4),LL(0x6e498775,0xf5d608e3),LL(0x0107968f,0x1ebcbfad),LL(0x4aa5111c,0x9da743a4),LL(0xcba06022,0x90a35fc8),L_(0x00000151), + LL(0x47445d4b,0x06b03d8a),LL(0x4a0fee6b,0x3277857c),LL(0x1fa95d1d,0x87c700bf),LL(0x48c9ebf0,0x2a50e2b3),LL(0x43aa2c31,0x9a26e1ce),LL(0xfdbdd0e9,0x52ca3b19),LL(0xfcedcc05,0x2999c847),LL(0xbff002c4,0x267e4e00),L_(0x00000125), LL(0x64d4906f,0x556e52bc),LL(0x42f805ae,0x90f2f1b6),LL(0xda19f3db,0xd869ad98),LL(0x21709755,0xf5bb8103),LL(0x573f3fb7,0x593f7e34),LL(0x2bac9d40,0x02d84c5f),LL(0xa4e8ad8e,0xea53406e),LL(0x80797c51,0xde43a1d4),L_(0x0000007e), + LL(0x02db6ff9,0x9a077100),LL(0x442b39ab,0xa4a99831),LL(0x658c33f0,0xd154641a),LL(0x6b185008,0xbb725f43),LL(0x1c42ee9d,0xc802ceb4),LL(0xd4f04052,0xde1c27e0),LL(0xaa13dd25,0x5e0fdafb),LL(0x59845ec9,0x89bca83c),L_(0x00000039), LL(0xd7b6958f,0xc632359e),LL(0x00693302,0xd897df30),LL(0x3a9976fe,0x07f17ce0),LL(0xb3320f5d,0x0634d694),LL(0x9281633f,0xf481d736),LL(0xa1f17a34,0xc568493c),LL(0x7973f20c,0xc81657ab),LL(0xe331f1c3,0xf1485d0e),L_(0x0000001f), + LL(0x02479c06,0xf0c74cf8),LL(0x82afef4d,0x3fe27e63),LL(0xc6ed0fe5,0x2473be19),LL(0x88c3bb5a,0xf0f01c24),LL(0x8b895708,0xff99c560),LL(0xda940b97,0x19fe223c),LL(0x3a3e9972,0xfce2e466),LL(0x48aaf92b,0x2976902b),L_(0x00000085), LL(0x1f0040f3,0xc569b506),LL(0x6e592ad0,0xa59e0b36),LL(0xe1a1ad5f,0x506ba908),LL(0xdd28fbcb,0x35a90e9a),LL(0x5dfd21f8,0xae82baef),LL(0x5c23fd74,0x03b13133),LL(0xe27cfbd6,0xa41bf476),LL(0x7af7e895,0xc5b57a28),L_(0x0000005f), + LL(0xdf92a189,0x7fe35612),LL(0x9f97d902,0xa5105c7f),LL(0xba021326,0x9c521853),LL(0xd2cadb21,0x9b3ed45d),LL(0xb3ab9d25,0xddadc1eb),LL(0x7b4a857f,0xaddab060),LL(0xbbc92a34,0x7dff916f),LL(0xee7e6c52,0x9816b721),L_(0x000000f6), LL(0xa3ba1dab,0x7b0e564a),LL(0x27f6c008,0xb9c963dd),LL(0x3c030970,0x76828eca),LL(0x3cd7a457,0x0834d3c2),LL(0x417b833d,0xf44c50d5),LL(0xf0d8be25,0x153d4a6b),LL(0xa49590ea,0x47e9c71d),LL(0xf3a30dc2,0xeb2b1d43),L_(0x0000018d), +}, +/* digit=70 base_pwr=2^350 */ +{ + LL(0x995d0979,0xe0c6b8f7),LL(0xbaad255c,0xcdfa7a67),LL(0x2a84102f,0x2ed9a546),LL(0x5fff322b,0x238b4cca),LL(0x316895f0,0x27a1fc8f),LL(0x4369e1fc,0x399300db),LL(0x708ed717,0x5f16f718),LL(0x931503fe,0x22cd3aa4),L_(0x000000b1), LL(0xa040da9e,0xf9967269),LL(0x8694422a,0x5871908b),LL(0x8350fa73,0x61c801c8),LL(0x80cd1b5d,0x26cc63f6),LL(0xaf0b4158,0x3474f5f7),LL(0x1e938b36,0x7800e540),LL(0x2f20f7f2,0x56230526),LL(0xd27bb44c,0xe18d65e6),L_(0x0000003f), + LL(0x474f3cfa,0x7075c330),LL(0xb3ee576a,0xb446bdd4),LL(0x1b7efe90,0xa143371a),LL(0x826a3c98,0x45fcf113),LL(0xa412cdba,0x4b5601ca),LL(0x614348a4,0x06ebe3f7),LL(0x9f111b62,0xd750e443),LL(0x1f6bb4a9,0xa9ce6845),L_(0x000000fc), LL(0x63c0d59b,0xcb29ae28),LL(0xe216b29b,0x3a9a3c78),LL(0x2465c5b5,0x9567856c),LL(0x36d155fd,0xdfbfe047),LL(0xa1ce6b07,0xc3a4fa43),LL(0xf19b8361,0x0e9f03c0),LL(0xb21f548d,0x9de803f9),LL(0x85460ccb,0x5a9172f8),L_(0x000000be), + LL(0x28dc3d9e,0xb1947d50),LL(0x707f8201,0xa08b9636),LL(0x1277e4a9,0x253ea9d3),LL(0x38720146,0x7e71d50f),LL(0x62240fd9,0x79e96c95),LL(0x99a338fd,0x14656a4b),LL(0x3386ac0d,0xaed2f11c),LL(0x56e7d58c,0xb1645e8f),L_(0x00000026), LL(0xd77da8a6,0xb38b4a7f),LL(0xdb95d39e,0xb6a3eb09),LL(0xc15d78b6,0x97f12510),LL(0xc3aba47d,0x56c5ceaa),LL(0x1799be9b,0x71c67e7c),LL(0x8203dc96,0xc27e5165),LL(0xaf4cd822,0x0bd2ed9a),LL(0xb4f47f2a,0xcb8f3ca9),L_(0x00000141), + LL(0xd26b287c,0x978130d6),LL(0xd433a71c,0x7aadd881),LL(0xb4ad7bb1,0x52e4f45f),LL(0xb1940d6b,0x722e2bd7),LL(0x72d44569,0xf91dc84e),LL(0x6d3fde70,0xd4254643),LL(0xbd1bc41e,0xb847e41a),LL(0x544a7be2,0xace3e10f),L_(0x0000017d), LL(0xe2e82545,0x3d8e5d2b),LL(0x1c9863cf,0x5f30317d),LL(0x98fb8ec2,0x81f15ce0),LL(0x8947db85,0xf3e6c315),LL(0x055d8793,0x43a7feb5),LL(0x8417f508,0xac153d3d),LL(0x248bbc38,0x664329e7),LL(0xfcfbcb03,0xb0314d2f),L_(0x00000064), + LL(0x0ffb3aeb,0xf0f73b2b),LL(0xb5b42e5a,0xfb4aa83f),LL(0x6fe3f768,0x166957fb),LL(0x1777755a,0x9be2e29b),LL(0xb21920be,0xd39b15af),LL(0x9d78ee52,0x5cfe70fd),LL(0x4ed3196b,0x55c6cafd),LL(0x34efaf79,0xaab07209),L_(0x0000011b), LL(0x9f0e1288,0xc5b10817),LL(0xef0c0487,0x2d0a8114),LL(0xd48fc96d,0x7cfa2d81),LL(0x641e3931,0x6424b3ef),LL(0xe6f897a1,0x3828d18c),LL(0xf36345b8,0x162c7445),LL(0xa9afd810,0x86dd67b2),LL(0x34f52c33,0xc05d931e),L_(0x000000c0), + LL(0xbf4033d7,0x282d7d2f),LL(0x4816fc56,0xbba4acf6),LL(0x0d36fbc1,0xed8c95f6),LL(0xc3d935ee,0xf5c04db6),LL(0x0f8e468f,0xf1e487eb),LL(0xe95fc738,0x07ce9d5f),LL(0xd25bbce8,0x3ea06aeb),LL(0xd6e4d92f,0xe1653616),L_(0x000000e3), LL(0xd1ebfa2e,0x8c6285b5),LL(0xff9b06cd,0x7f8da651),LL(0x19efacac,0xfb702fe7),LL(0xf38839db,0xfd2c9b61),LL(0xb8c0cb9c,0x674adc03),LL(0xd42ebdf8,0x326b91f3),LL(0x8993821a,0x0fbb4e81),LL(0xbc7b32f8,0xc1690f2a),L_(0x0000011d), + LL(0x2fd676b6,0x892e4204),LL(0x41e60d2e,0xdf88f03d),LL(0x05344e65,0x322deae7),LL(0xabc0c748,0xf3bee9da),LL(0x7dbffa8f,0xe2cbe049),LL(0xf2922597,0xb0e73ee1),LL(0xa1ab5a4f,0xd18b70e5),LL(0xf7b0232d,0x6b85e543),L_(0x000000f3), LL(0x7a93eb9f,0x998f9412),LL(0x6520852d,0x9fffa5de),LL(0xa83ca014,0x9492e738),LL(0x29961bc9,0x38356eab),LL(0xbaa587e6,0x9aad6aa8),LL(0x5bde3fd3,0x15f7c437),LL(0xc663a8aa,0x2b85ba68),LL(0x922641a9,0xb030aa17),L_(0x00000175), + LL(0x90b91e88,0x9329a6f3),LL(0x5e0fd985,0x332091e8),LL(0xc7233994,0x069d0a1f),LL(0x7172741e,0x953488c0),LL(0x1870fafc,0x3b040fb9),LL(0xbb2fd807,0x9e841e1b),LL(0x16872728,0x48f58216),LL(0xa72dc0f5,0x590057bf),L_(0x0000010e), LL(0x4ec2f404,0xc898f3ae),LL(0x893dfe9f,0xd6d16346),LL(0xcfc2a2d6,0xdcfcc356),LL(0x9780e14a,0x52a0f58f),LL(0xe40c34a9,0x1f74017f),LL(0x9637bf1f,0xe85cc7e4),LL(0x7db8273a,0xf7240054),LL(0xd4e119d7,0x2baa4eaf),L_(0x0000008d), + LL(0x8bec2bfe,0xe147d2d0),LL(0x0f381def,0x63d396f3),LL(0xd719925a,0xa70c4ee8),LL(0x48335ffe,0x70cbdf17),LL(0xba86e989,0x70acf1a0),LL(0xa8e07900,0x3fdcbfe3),LL(0xf724a710,0xd0dd93f1),LL(0xcce8d0db,0x6cd982dc),L_(0x000001e7), LL(0x312db409,0xe842388e),LL(0x51c17662,0x5cfc4c86),LL(0x2819cf9f,0x3d2f2e78),LL(0xcb5f9278,0xc84b5c07),LL(0x6807319b,0x91966c94),LL(0xd459389d,0xf68df64d),LL(0x22ed9565,0x30d2c264),LL(0x2d12cd4a,0x1496895c),L_(0x00000055), + LL(0xa8198a4a,0x7fd3cc79),LL(0xcf8b16bd,0x973e67ac),LL(0x27c827e8,0xc9207496),LL(0x6d1709a1,0x9157f587),LL(0xc23a1cd6,0xbedd9d1c),LL(0x8b1088ef,0xb005d24b),LL(0xc08bed38,0x6477a806),LL(0x0681e2ab,0x213943da),L_(0x000000ba), LL(0x2de2bdb8,0xe996e18b),LL(0xf9e30d5c,0x2c137e56),LL(0x5c521393,0x6041c771),LL(0x8cdc666b,0x4ee56b76),LL(0x2695a1d6,0x518a5638),LL(0x41e2f039,0xdb59944d),LL(0xaf0a4010,0x5b0e9f3f),LL(0x829ed1fe,0x2cb7de1f),L_(0x00000068), + LL(0x3b382180,0x93922bbc),LL(0x1503eb8a,0xd83a3aec),LL(0x4f056b98,0x0f661abc),LL(0x1dc0c0de,0x20cd5ab5),LL(0x25a3a29e,0x9409a1df),LL(0x2ec3d724,0x2311b333),LL(0x9cff8f0d,0xd299c4b1),LL(0x30ec4ca0,0x7f770084),L_(0x000001d0), LL(0x674d075d,0x79f5e3c1),LL(0x3e4d547c,0xaceff143),LL(0xa985c66e,0xceb1d3f0),LL(0xc8735e90,0x46311b8a),LL(0xecdbba45,0xd47b3dd0),LL(0x8237affa,0xc21e6384),LL(0x6b4f82bd,0x851d53b8),LL(0xff59ca4e,0xf5e1b60e),L_(0x0000000b), + LL(0x29a5355a,0xa2f29baf),LL(0x3e11c687,0x653058a2),LL(0xab5abb63,0x533110b2),LL(0xead1d1b9,0x254324e4),LL(0x65d1b7b6,0x9ad5a861),LL(0xd1007405,0x0712ab62),LL(0x6f88f2a9,0x78e9d501),LL(0xefd62c6b,0x1145cafe),L_(0x000001fc), LL(0x62d2d42c,0x8d15289e),LL(0x5d68b919,0x4baf7b53),LL(0x4a9af773,0xbfd8566e),LL(0x2c278158,0x0f0f5b40),LL(0xa603f631,0x366d639e),LL(0xed79331a,0x457655be),LL(0x5b5f4bc7,0x744b4617),LL(0x6ced0122,0xa2e7748f),L_(0x000001c1), + LL(0x0a6157b9,0x62225ddd),LL(0x63f4338a,0x3ff075f1),LL(0x19a505d3,0xa170cf14),LL(0xdfa6bdb1,0x35bb45bd),LL(0x3014f03b,0x01eadcfb),LL(0xdf884f38,0xed9ce5a3),LL(0xeb67d796,0xbe4fe92b),LL(0x01a5f419,0x57e98411),L_(0x00000129), LL(0x7ddc4629,0x8bd2744c),LL(0x40075673,0xa1d1f6a9),LL(0x6ac9b5bb,0xbff10759),LL(0x7709ddbb,0xd617233f),LL(0x04b71ff3,0x91a5fcd2),LL(0x45458de2,0x699b54de),LL(0x5147375c,0x4e0307cc),LL(0x2fe5917c,0xf27f33bc),L_(0x0000003f), + LL(0x4252a836,0xfbc6e97a),LL(0xbffdbb20,0xee422c57),LL(0x5769cb47,0x501f912b),LL(0x3924d571,0xae0c25a9),LL(0x239c3442,0x7ed84b21),LL(0xd601103f,0x74478136),LL(0xebe1703d,0xc5087e65),LL(0x67b021e4,0xf61c2d56),L_(0x000001f8), LL(0x8ce094d8,0xaa167fe1),LL(0x70c73af6,0x79b93fdc),LL(0x0e41e095,0x3eab3290),LL(0x4d79fd87,0xb7162ca3),LL(0x66141590,0x583d1391),LL(0xe0bd38e8,0xa393b806),LL(0x169f55ab,0x4bdc04a4),LL(0xd1df6260,0x445d5212),L_(0x000001e5), + LL(0x6ef19cc6,0x8fb90054),LL(0x349f0b5e,0x7a588763),LL(0xd381418c,0xe35ce1af),LL(0xec0fd49b,0xecb4e203),LL(0x7786513b,0xa276ad19),LL(0xfe701187,0x99f4ee10),LL(0x47d026fa,0x58423dc0),LL(0xa22bbaf1,0xbd8a6065),L_(0x000000fc), LL(0x9aa1efcf,0x5af392c9),LL(0x8ba7989e,0x7c5174d3),LL(0xd1616f2e,0xd20d0632),LL(0xa5636d7c,0xd761cf0d),LL(0xce718261,0x701e7d69),LL(0x08d4d0bc,0x66e92aa8),LL(0x819aee8a,0x0d6fcd90),LL(0xc96d5138,0x2da0618d),L_(0x000000a1), + LL(0x81b20efd,0x117c40b0),LL(0xec008c40,0x0a6d9c2a),LL(0x693270e3,0x6114d3e0),LL(0x4266a5ea,0x44a6af67),LL(0x81ebf621,0xee3917e3),LL(0x7fca3d45,0xc35ff5d6),LL(0xa3526048,0x0f6e79db),LL(0x7e7bfed4,0x0da1a81a),L_(0x0000016e), LL(0x0c06eb8d,0x3343c5a2),LL(0x3418cfe3,0x3e67d0a5),LL(0x15eb001a,0x7e48959e),LL(0x0ead5e7c,0x0962e6ac),LL(0x32e4162f,0x3e28513c),LL(0xfb8117bb,0x317568fa),LL(0x3a2e3034,0x0c912ceb),LL(0x55938174,0x24701102),L_(0x0000018d), +}, +/* digit=71 base_pwr=2^355 */ +{ + LL(0xfec70f6d,0x92ef06ac),LL(0xc38aac0c,0x790f3344),LL(0x53c30edf,0x1b40fed7),LL(0xfc800650,0xf6da803d),LL(0xfdf722f2,0x284a42e2),LL(0x5cecc340,0xa0f15400),LL(0xb36ac652,0xef82f0df),LL(0xd1506b21,0x5fdee7be),L_(0x00000096), LL(0x84d76b78,0xa1c3d7b8),LL(0xc6050edc,0x307e9a89),LL(0x1519baa6,0x8c7e0ccc),LL(0x3495eff8,0x22e91666),LL(0xea17475b,0x69639f1c),LL(0x8c53c39e,0x1f0e827f),LL(0xede8121b,0xeb066355),LL(0x91249281,0x0c0c2d5b),L_(0x000000b2), + LL(0x3accccf3,0x16751720),LL(0xa2ac7465,0x1bf938ea),LL(0x83a983dd,0xb73d73d6),LL(0x598a6f1d,0x630b4f7f),LL(0x6235f9ed,0xdb784cb5),LL(0x52bdf332,0xb330540f),LL(0x221e5e83,0xc25843b0),LL(0x09499b4e,0x6e45244a),L_(0x000000b4), LL(0x010fb3ca,0x8b6e52dc),LL(0x60a24896,0x22c046dc),LL(0xae1e187a,0x482695be),LL(0x006acf49,0x35934bd3),LL(0xb960f105,0x1e1d0143),LL(0x4cfddf01,0x5de371d8),LL(0x56c439e8,0x64828414),LL(0x582ff3b5,0x43605585),L_(0x00000161), + LL(0x3578ec4a,0x83ac7330),LL(0x74417a7c,0xb971e045),LL(0xbee09246,0xc391f3f4),LL(0xb2cfe806,0xf8fb9526),LL(0xe574f401,0x2d57d573),LL(0x9ef64156,0xf2047705),LL(0x2e13ebeb,0xe2e05adf),LL(0x97b783be,0x2b746c25),L_(0x00000086), LL(0xac801f25,0xbb184270),LL(0x1d0026d9,0x772cb73c),LL(0xc5ae7636,0xf37dccd7),LL(0x5106f975,0x276aad31),LL(0x2b41e6c0,0x0c355836),LL(0x7d420351,0x169e0a27),LL(0x25cdd7da,0xe67ef6ec),LL(0xdd1ddbf0,0x988f96fe),L_(0x00000103), + LL(0xbce94ac6,0x89803b61),LL(0xe8afe442,0x2e798f31),LL(0x9a42f37b,0x9475e43d),LL(0x77aef7a7,0xa8f685f3),LL(0x203a6947,0x969c3b8c),LL(0xdf0dc1b4,0x9c542cdb),LL(0xc76bc8fb,0xff501682),LL(0x2a768660,0xe2ff6697),L_(0x000001f7), LL(0xc8f9daec,0xc4a46652),LL(0x89b1c325,0xb09499ac),LL(0x721c0cae,0x5e63ccd5),LL(0xda46e344,0xaca0b998),LL(0x32db691c,0x793a1fc7),LL(0x049e845a,0xd927f614),LL(0x7aea310a,0x80024bf0),LL(0x5359be8b,0x60137724),L_(0x000000be), + LL(0x57afd605,0xb3d701e7),LL(0x608eeeaf,0xa1e2923b),LL(0x3a52d1fe,0xb5ba2517),LL(0xf6c570be,0x6f830092),LL(0xa2b946db,0x63e9fd66),LL(0x2b96de58,0xd1292d2e),LL(0x89c80a56,0xf418bcf0),LL(0x02901646,0x626f5025),L_(0x000000f4), LL(0x9f28725f,0xb36ad666),LL(0x73de9bb2,0x25e09cb1),LL(0xf102152a,0x3474fc24),LL(0xb0389a9f,0x9e0b3083),LL(0x245ecf47,0xefc86ff8),LL(0xedc1e824,0xd024fd72),LL(0x022e7528,0x0e37477f),LL(0xa7fdb14f,0x2d504191),L_(0x00000176), + LL(0x130db159,0x31d0f49f),LL(0xbd9c79a2,0xf1d499d6),LL(0x7ea9b7cf,0x367757ac),LL(0x05a4d545,0x0a42a453),LL(0x1f2c8548,0xd461a5b5),LL(0xb8ed29ef,0xe691c9e6),LL(0xa549541f,0x6490ea1c),LL(0x09c0153e,0x93d0058f),L_(0x000000d9), LL(0x7f525f59,0xc140a1f6),LL(0xa98aaedb,0xf5bef166),LL(0x750be5c2,0xd457a559),LL(0x8cba58b2,0xc5d96cfb),LL(0x514d93d0,0x70bfa2f9),LL(0xb86d7234,0xf6b79058),LL(0xa8a78584,0x18d58f11),LL(0x2b2d0ad4,0x341dbfe3),L_(0x0000007f), + LL(0x147202dd,0x3c8a33ae),LL(0xd39c4b9d,0x1d455649),LL(0x3f56141d,0xc0ac51ab),LL(0xa5a57669,0xfc529732),LL(0x1ee307ea,0x1861bed9),LL(0x5f1e4bec,0xc7a796b8),LL(0x5b0d925f,0x06f456f4),LL(0x2257c76d,0x7d497d17),L_(0x000000ab), LL(0x4360118e,0x218cb0cb),LL(0xaa1c1dca,0xf6db0e7a),LL(0x2be1c968,0x5a3744ed),LL(0x46bb2acc,0xaf262fce),LL(0x7e16d340,0xaec37ad7),LL(0xe6df41bd,0x1060715f),LL(0xee38cd22,0x87b94898),LL(0x34109b20,0x0eb71ca2),L_(0x000001fc), + LL(0xb416f6d1,0xc2c062af),LL(0x3dacb0a7,0x1630676c),LL(0xd74ee6b3,0x95fc297a),LL(0x8f736e49,0x48a7a2d1),LL(0xd64edc25,0x6b5d5f53),LL(0x83303159,0x0e945b2c),LL(0xdfaa52c4,0xb0587c06),LL(0x462a8f05,0xa859437c),L_(0x00000141), LL(0x2fcd636b,0x0835ddc0),LL(0x86482b2b,0xd2333470),LL(0xc7f1c7b2,0xb32bf92b),LL(0xd5f30c92,0x49153950),LL(0x9ce136c0,0x29288cec),LL(0x4ac8254d,0x34eb3849),LL(0x0b3117ac,0x14ba2a1b),LL(0x3a85376a,0x1b0e1c47),L_(0x0000009e), + LL(0xb3ec3510,0xc014692a),LL(0x988a8cb2,0x70309a41),LL(0xb83a1155,0x92367194),LL(0x22c65f09,0x558d49bd),LL(0x17ac8e14,0xd539b194),LL(0x281a7ecc,0xa19213fa),LL(0xc69fe80b,0x1ef427d6),LL(0x744a4f4d,0x5f94b5db),L_(0x00000136), LL(0xf07169a2,0x4ff0070e),LL(0xe17c5e0d,0x42362609),LL(0xd97efa2b,0xab4374f3),LL(0x59d17f1f,0xc3027acb),LL(0x8cb9e348,0xc305c872),LL(0x320eb648,0x861bfbe3),LL(0xf68b129b,0x2a98fbd9),LL(0xc35aa741,0x8fa1ae4d),L_(0x000000c9), + LL(0xba2a6162,0xfef26d3a),LL(0xaf22bedc,0x4bac42f2),LL(0x32bd0514,0xaf54da8b),LL(0x474d59e6,0x846ca3be),LL(0xac190f17,0x7e7c79bf),LL(0xaea0f3e1,0x13543ecb),LL(0x0ff996ba,0xabe74acd),LL(0xe27a5f5a,0xcea6ecbd),L_(0x00000136), LL(0xa8ccc73f,0x1e746179),LL(0x62af882b,0xb19b717d),LL(0x4e0895be,0xb255045a),LL(0x8f194a8b,0x0b37366b),LL(0x089f1cd5,0x7b3da3e1),LL(0x68b1f2a5,0x91e4f674),LL(0x9c4602f6,0x698976ca),LL(0x3ed98ad9,0x99fe05e5),L_(0x000001fd), + LL(0xfe476990,0x532b6850),LL(0x345630b7,0x7ff00f29),LL(0xecbc85e6,0x9c3d2e4c),LL(0x5f322ba8,0x6869142c),LL(0x9e246c23,0xf5d1ef76),LL(0x0affd2a0,0x2e6d871e),LL(0xb40893c1,0x66c72704),LL(0x1665fed8,0x01d321d9),L_(0x00000042), LL(0x06507414,0x9d9489fd),LL(0xa1379411,0x7d5c53f0),LL(0x7e6d3de2,0x097595be),LL(0xc486fb28,0x85e5a09c),LL(0xa9fd8f9e,0x2996fa66),LL(0xd71e16d0,0x040664e3),LL(0x7c75e965,0x14b60428),LL(0x9d686380,0xf4fa3032),L_(0x00000123), + LL(0x86f79bf5,0xbf36d744),LL(0xbf45f97e,0x0fe48147),LL(0x6235b3ae,0xd40868d4),LL(0xa9b13d93,0x45fa9173),LL(0x34e9264c,0xb5705f4c),LL(0xd0d58c79,0xfd4b166f),LL(0xaf4ff870,0x7aaca2ed),LL(0xb68a488f,0xd9bb2955),L_(0x00000047), LL(0xf5f3e0b1,0x747dd972),LL(0xf6fc0c26,0x92d84bc8),LL(0x088102b5,0x201255f7),LL(0x84970893,0x7f6288c9),LL(0x6a679170,0x9309b54e),LL(0xd5327276,0x389f4da5),LL(0xc48b5de6,0x8fc1eb23),LL(0xac794b85,0xa3f64d1b),L_(0x00000132), + LL(0xb408df01,0x66056a5d),LL(0x5f945157,0xc30a058e),LL(0xf0071848,0xb615e360),LL(0xe6a8d838,0x132d49ae),LL(0x1bb7f3ca,0x092ee873),LL(0x398ab7d7,0xbf83bd98),LL(0xba362639,0x73208c1b),LL(0x49dd5ba3,0xf4382ccd),L_(0x000001a7), LL(0x0d07ce4b,0x724cd057),LL(0xf7baff54,0x31245cf8),LL(0xff518822,0xff5f1211),LL(0xea1813a7,0x89f90332),LL(0xfa74413f,0x9e68455b),LL(0x9e49a7a6,0x182fad31),LL(0x30e8a2ef,0x233ce0d5),LL(0xbd55ab52,0x38f1c599),L_(0x00000010), + LL(0x28e2d8df,0x708c9183),LL(0x1dbe8e5a,0x9b9fb00f),LL(0xa3695cb8,0xaeafe9c7),LL(0x9205b4ca,0xd6ec0b74),LL(0x756f204b,0xa9e0254c),LL(0xd51d1a73,0x152441cf),LL(0x0ca91564,0x370d2b8b),LL(0xe3cdd9e9,0xab50f4de),L_(0x000001a5), LL(0x9dab1375,0x5322d78e),LL(0x78b8ab5d,0x0adbfc55),LL(0xa2b97f9c,0xd5d0ce27),LL(0x9cd573f2,0xe94e39b4),LL(0x06ee23d2,0x213bd15a),LL(0x708d61ea,0x561b9d34),LL(0x6271f59e,0x41fb576c),LL(0x9ae94507,0xd828d166),L_(0x0000009b), + LL(0x6669c984,0x46ae7251),LL(0x8c23b4d3,0x3738a807),LL(0xad75f8b4,0x3ef8e3cc),LL(0xc8e8bbf5,0x029e586a),LL(0xa7111c4e,0xa4d1beb9),LL(0x238f36b4,0xc4da1680),LL(0xbe34bad6,0x9409b124),LL(0x6ab824c2,0x48e9ec02),L_(0x00000062), LL(0x0666df3f,0xa0015f27),LL(0xd7f90fcc,0x3e7eb3a2),LL(0xcd91c4ca,0xa8bd0fd8),LL(0x56907857,0xc0b60059),LL(0x3559db95,0xc6ed4fe7),LL(0x0c8beff5,0x2ba51007),LL(0x5bc2116c,0x409f6b4e),LL(0xa6198a28,0x360e46d8),L_(0x00000076), + LL(0x231a6637,0xb888102e),LL(0xaecdfa06,0x430b0efa),LL(0xd888793c,0xb123b1e3),LL(0x8beed2db,0x8887df4f),LL(0x3ea5e72a,0x2425e985),LL(0xccc7d4aa,0xd98e93f3),LL(0xe9181719,0x07cba97f),LL(0x8ea6eef3,0xa9e6f6b0),L_(0x000000d8), LL(0x5719b171,0x5d9f40be),LL(0xe16ecd5e,0xfea96313),LL(0xfe1e359f,0xd9f1461e),LL(0xde9904f3,0x38f6d943),LL(0x881bb7a0,0x2c5787d5),LL(0xa74eed55,0x67fc2cd9),LL(0x7ccb483a,0x2c643f37),LL(0x7070b576,0x386889db),L_(0x000001ea), +}, +/* digit=72 base_pwr=2^360 */ +{ + LL(0xca188556,0xbd7c7672),LL(0x20ced736,0xa4667058),LL(0xb83d6897,0xe3f39ba4),LL(0x174ecbf7,0x34188faf),LL(0x203dc58b,0xdb5dba0b),LL(0x5206b453,0xf54df32d),LL(0x52fcf51e,0x08d08e3c),LL(0x2f551f34,0x72856373),L_(0x0000016a), LL(0x6b937ade,0x7f7f5dfd),LL(0x632c9b6a,0x3151876b),LL(0x3ee4a789,0x7a59040d),LL(0x41b009fd,0xdfc2d274),LL(0x68b427fe,0x1c0ceded),LL(0x07d57f92,0x220fc8f2),LL(0x83c79a42,0x7b0f6753),LL(0x410a2e83,0xc0765d6f),L_(0x00000124), + LL(0x01fb8b79,0x82addc43),LL(0xfdb0062d,0xb9cdf1d9),LL(0xb1cf25ad,0xb5a42255),LL(0xaaea42eb,0x1990669d),LL(0x1dffd105,0x88f20764),LL(0x613001d6,0xda7769bd),LL(0xa275aa11,0xe04ea507),LL(0xea612e43,0xf381e073),L_(0x0000005f), LL(0x21f18b4b,0x268a5e08),LL(0xa7554f72,0xad126436),LL(0x714fe1c3,0x5b5ba02f),LL(0xb7c7cde4,0xf2da3519),LL(0xfc576f09,0x4fb328e0),LL(0x185faef3,0xa0386e0f),LL(0x2adc73d1,0xc97a6bb3),LL(0xda21be9a,0x70df7733),L_(0x00000048), + LL(0x6a23d540,0x500040b2),LL(0xf87554cc,0xe6a09fa7),LL(0x548aea96,0x0cf27fbb),LL(0xfa1d8c06,0x1a618765),LL(0x1943cfee,0xe6a8c7ea),LL(0x20bf61bc,0x99730b0b),LL(0x744528dd,0x42eac170),LL(0xd049742c,0x85700423),L_(0x000001aa), LL(0x1e2bba63,0xe601cd80),LL(0xcbeefa62,0xc9e240a6),LL(0x8106469f,0xda8103af),LL(0xc7109e54,0xdcc44907),LL(0xdb9a3ec3,0xe44b6df8),LL(0xe34b7788,0x0e67c93e),LL(0x4a58495d,0x63e8347b),LL(0x23b5096e,0x468b5372),L_(0x000000db), + LL(0xbf417e03,0xb60364c1),LL(0xdda37ca1,0xea847f52),LL(0x28527f5c,0x98d517fb),LL(0xa1e399f7,0xff102f07),LL(0xc452c79f,0x87dfab3c),LL(0xc5aa688a,0x490b0295),LL(0x0dbc6056,0x3dd17acd),LL(0xb4f6972c,0x2e16b5ac),L_(0x000000b7), LL(0x23fa3555,0x3a903ffa),LL(0x262814e3,0xc46f6e35),LL(0x1cec4214,0x7267bc6b),LL(0xca2e1dc8,0x20b7474b),LL(0xeb500457,0xf394811d),LL(0x4304c697,0xa5001f3d),LL(0x0f7a5e2b,0x4c9ea7fd),LL(0xead3d012,0x84c6a90d),L_(0x00000120), + LL(0xb7e47c23,0xd475bc3c),LL(0xff4599af,0x1acc6490),LL(0x39b1950f,0xee09f5dc),LL(0xd14540f1,0xe51c9564),LL(0xf1b75050,0xbebd088f),LL(0x17895647,0x240dba4c),LL(0x097400cf,0x559b95e8),LL(0x5d4b8420,0x3bc0185b),L_(0x000001a3), LL(0x85986a76,0xc2ffb653),LL(0xa478ed7f,0x18e264c5),LL(0x4841d184,0x17a5a278),LL(0x21d9e8a0,0x297fe2fe),LL(0x1bf52154,0x072d6d91),LL(0x88327dad,0xae77c8ea),LL(0x02d1fcbe,0x13786b6a),LL(0x25554500,0xdf7f6e68),L_(0x000001a0), + LL(0x17de731f,0x7753cff6),LL(0x972b7a35,0x73655403),LL(0x28d73a10,0x0c70484d),LL(0x46d46c14,0x516a9dc8),LL(0x455b7ef1,0x0b552594),LL(0xb8161489,0xf418ade1),LL(0x64a91645,0x76a465f2),LL(0x7693e9a1,0x91415ed3),L_(0x0000013e), LL(0xe5e5c3bf,0xdc135bc4),LL(0xca946121,0x3d39b5c7),LL(0x55877498,0x318be468),LL(0x9fb5d801,0xe5cb6287),LL(0x3afd92b1,0xcd7f8034),LL(0x34ed24ae,0xa3835c84),LL(0x6aa7d954,0xd325764c),LL(0x41780668,0x7945ea02),L_(0x000001b9), + LL(0x34c0928c,0x37933b17),LL(0x74a56f2c,0x6bae2a29),LL(0xb1d26ac8,0x6bd1e8bd),LL(0x84c336cb,0xcdaa1b9c),LL(0xaca41014,0x7838c44f),LL(0xe2ce24b8,0x525239ca),LL(0x515f204f,0x8bcb0507),LL(0xdbd0e0a5,0x50183993),L_(0x000001e4), LL(0x631411bd,0x3e15aa53),LL(0x8672c87f,0xade47bf6),LL(0x93da50d5,0x148028e4),LL(0x0048f8cd,0x03c75612),LL(0xb5ecfaeb,0x7b7867aa),LL(0xafcde134,0xa0208953),LL(0xe2411e3b,0x24be9b23),LL(0x848d40b4,0x24d9da2e),L_(0x00000187), + LL(0x16583ec0,0x7b7ba7d9),LL(0x2bbb4768,0x2b3f0b4e),LL(0xe0e4b3fb,0x9172caac),LL(0xe6fb63a6,0x22aab4b0),LL(0xa00520c8,0x7930e37a),LL(0x4dcbf41f,0x6bfa91da),LL(0xf521a694,0xb88bd604),LL(0xa707c1f0,0x95a5140f),L_(0x0000011a), LL(0xd8520b88,0x22333018),LL(0xa6bc2bb8,0xaa6a00bc),LL(0x011553af,0x5def3469),LL(0x0ed5fc0a,0xbcfec7c2),LL(0xdee0e8c5,0x2f464224),LL(0x8adb476e,0xd844542e),LL(0xd3c1bdb2,0xa709924f),LL(0xac98d161,0x472a5f2f),L_(0x0000001a), + LL(0x5054b047,0xa4a3faff),LL(0xd966b478,0x3d33573c),LL(0x1081c0ed,0x928c644f),LL(0x0d2ce409,0xb6d01835),LL(0x9e6a2193,0x52176b02),LL(0xa876fcb1,0xa48ba61b),LL(0x717040ec,0xa24784a2),LL(0x063597d5,0xbbb8ca8d),L_(0x000000e2), LL(0x24d496ff,0xb9c0170d),LL(0xf08c120b,0xee06f00f),LL(0x24a5f375,0x9e3d247d),LL(0x21f556fe,0x23ca02e0),LL(0x9baf2fa5,0xc33aa42b),LL(0x87dfcff1,0x165eef36),LL(0xf9dd5e4c,0x54afa097),LL(0xfe4014f0,0xe713f89f),L_(0x00000058), + LL(0x690b2052,0x836e06e2),LL(0x3509fc01,0x7b24d732),LL(0xc3a11a6f,0xf970953d),LL(0xb1e661c4,0x19774ec5),LL(0x1a995696,0xa05e5145),LL(0x777347df,0x1c3c2550),LL(0x77882ae3,0x5a7928a8),LL(0x77fbd07d,0x69195185),L_(0x000000a4), LL(0x41e2d40c,0x16368545),LL(0x29dc25b0,0xfa97fb70),LL(0xb7b7f0ff,0xdec5a377),LL(0x2c841e96,0x205a5df4),LL(0x01390c3a,0xe68d053a),LL(0xa1116c1b,0x83274721),LL(0x62015852,0xe92e4364),LL(0x6a3178e8,0xfafb3a16),L_(0x00000013), + LL(0xf2f16fe9,0x75049d40),LL(0x2503f2a9,0x67afd1db),LL(0xe86bcd13,0x1004d640),LL(0x5322f07a,0xf5a688a9),LL(0xb4accb02,0x5af14887),LL(0xe07764b0,0xd65fb0f3),LL(0x03224e24,0x5db913de),LL(0xb8433f0c,0x4e0f4a11),L_(0x00000109), LL(0xf3884513,0xe8ba41a9),LL(0xaded3528,0x8ea44980),LL(0x1a82f302,0x31375544),LL(0x0614f686,0x4f3dc64f),LL(0x8ad34274,0x7f906c7a),LL(0xc479a89a,0xe50987f1),LL(0x17709633,0xaa307609),LL(0x33922a61,0x8a16309d),L_(0x00000035), + LL(0x7b97be7b,0xd004b0c4),LL(0xd609efba,0x341b0b8f),LL(0x20475d65,0x373000c9),LL(0x00101859,0x5bcb5ae6),LL(0x518d7514,0xfb3c86f2),LL(0xf5d314f2,0x2c8aceec),LL(0x2307be1e,0x778a0fa6),LL(0x5d168daa,0xebfa491d),L_(0x0000017e), LL(0xa440b9a3,0xa70ba700),LL(0xa47a36dd,0xef6fc566),LL(0x17be0829,0x8e295843),LL(0x63809dc9,0xa317bc2f),LL(0x1a787c34,0xbce26a9e),LL(0x943ad796,0xc651a487),LL(0xe010f911,0x636a6efc),LL(0xcd31e255,0x66b98f88),L_(0x000001af), + LL(0xed5ce1f5,0x8d6c9e3b),LL(0x8f008e9a,0x2a13d48e),LL(0xa44f1754,0x32cde8f7),LL(0xaa90e24c,0x8660b8f9),LL(0x3052b86b,0xd73a03c1),LL(0x79244ef9,0xe4f8a628),LL(0xc2475432,0x35d52164),LL(0x9c11d0d4,0x8b588259),L_(0x000001c5), LL(0xb6ab40a4,0x3d6aa080),LL(0x9ca82551,0x92a4dc90),LL(0x8044f304,0x5989211e),LL(0x4878d275,0xc33afe23),LL(0x50bb5ea4,0x2b031b41),LL(0x889e9545,0x4a4f6a74),LL(0xdcce463e,0x6a9c23ca),LL(0x260ab0c8,0x066be87c),L_(0x0000007b), + LL(0x2372213b,0x84ab40ec),LL(0xdaad8de9,0xcb476943),LL(0x2dbf8cf6,0x9149cbb6),LL(0x72626b77,0x4935f2cb),LL(0xae5d765c,0x79eb7a36),LL(0x65f4be84,0x44c54fc0),LL(0x2049ba34,0xcbfa4bf0),LL(0x9c904608,0x5711da83),L_(0x000001c0), LL(0xa5d29aec,0x3010853b),LL(0xdf573f6e,0xcdc13fa1),LL(0x9737e298,0x24add1ef),LL(0xa7f64bf7,0x2431c698),LL(0xb2b280e2,0xbdff9a1e),LL(0x93c22a36,0xd70876a8),LL(0x0c7227cd,0xaf483376),LL(0x04873b2d,0x78b4c89e),L_(0x0000007b), + LL(0xecb1f89d,0x21b6a936),LL(0xf18c9695,0x805badb2),LL(0x45242b9a,0x2c7430dc),LL(0x7856a265,0x5aacc16c),LL(0x281a24a8,0xbe56330d),LL(0xd8f8608d,0x50d0b225),LL(0x62852160,0x4403a1c3),LL(0x7038362e,0x86d7f075),L_(0x0000010c), LL(0x7dc02e97,0x816727a7),LL(0xca536177,0xc5451dd1),LL(0x304d66d8,0xb89ef533),LL(0x360da6a3,0xe6b58c96),LL(0x3f234bec,0xc18619f4),LL(0xb4bfa580,0x891d516d),LL(0x40c1bed3,0x04f1453b),LL(0x7060a227,0x3adae1e8),L_(0x0000005b), + LL(0x30c9a655,0xcf48b04d),LL(0xb68ea01a,0x04344830),LL(0x174d6fa7,0x1ac58a53),LL(0x9044eeb3,0x0524d6f5),LL(0xf87d51a6,0xfb882d4d),LL(0xaa0ba344,0x1ed41d08),LL(0xa85fb93d,0x6086b6ae),LL(0x7fa57f48,0xe80f97f2),L_(0x0000006c), LL(0x596f6fa7,0x2aae9562),LL(0x04813ef9,0xabc183c4),LL(0xded30d2a,0x6a011be4),LL(0x20b7ae96,0x88e77be2),LL(0xbc3e6cfc,0x77d5e0ca),LL(0xac06a92b,0xd7f99c6d),LL(0xc76c3023,0xa80a6be4),LL(0x1d55150d,0xfd7af32d),L_(0x0000016f), +}, +/* digit=73 base_pwr=2^365 */ +{ + LL(0xea0d37f0,0xd1a1ebfa),LL(0xb07ea564,0xbce4cf04),LL(0x4677d784,0x74184f2b),LL(0x14a4f867,0x3b8741db),LL(0x00b95ce9,0x35b5960b),LL(0xfae4a317,0xd2c80a76),LL(0x23107ec3,0x0522c4d1),LL(0x8678a9d7,0x19e856cd),L_(0x00000060), LL(0x304b58dc,0x88c3d5f2),LL(0x45f5267d,0xf847248f),LL(0x28ef4e85,0xc0f3da26),LL(0x7945a7b9,0xea2c17e3),LL(0x8a2da387,0xe84de988),LL(0x211a8e98,0x8290c88f),LL(0x75574343,0x6b4ce366),LL(0xca4612f5,0x827b2040),L_(0x0000015d), + LL(0x6c7a73bd,0x1e3ef4b5),LL(0x104fc4ba,0x835871e0),LL(0x4759b57a,0x9b4ed462),LL(0xd3c95d4d,0x648a71ee),LL(0x829d8353,0xece81ad2),LL(0xb2a56bed,0x452c12f2),LL(0xb67ec3e1,0x35ab19b8),LL(0x3f8f88bf,0xeb6e6ccd),L_(0x000000f2), LL(0x76062e0d,0x4abff696),LL(0x6641cdd3,0x9b89962a),LL(0x0add12e1,0x9f42be1c),LL(0xa078191a,0x72d9da14),LL(0x7c488cf9,0x607f65fc),LL(0xa7e790e9,0x5cdadd7d),LL(0x83b3584d,0x381ca37f),LL(0x3c6df02d,0xfe16cdd4),L_(0x000000b8), + LL(0x3a1e6367,0xfd8b4117),LL(0xcdcf0fd6,0x0c717ef3),LL(0xb3300d01,0x07e608fd),LL(0x527d7c8e,0xe69c0a0d),LL(0xd39cd9ec,0x11bdaf48),LL(0xa5576772,0x5d520c7f),LL(0x92f3c61b,0x1fbf8426),LL(0x814bffe3,0xa920b055),L_(0x000001bd), LL(0x3dc94502,0x8193bb95),LL(0xb1a23052,0xd7bdda5a),LL(0x19650b25,0x4c67c4a2),LL(0x78abb7ba,0xb9dbe10f),LL(0x3eb157bd,0xb3d0ff94),LL(0x1a32ace6,0x8180c4dc),LL(0x9e9b36a4,0xeb0124b6),LL(0xfee72796,0xc1e93da7),L_(0x00000141), + LL(0xedaed08c,0x46195fa3),LL(0xbcb9e4e5,0xc31c13ef),LL(0xb2cc8a6a,0x483f2eae),LL(0x912ca200,0x5ee60fa1),LL(0xff0ff27a,0x9e9c56cf),LL(0xdac70a7b,0x4977503c),LL(0xbda5a3e4,0xa564deab),LL(0xfe3a9fcb,0xa761938e),L_(0x000000f7), LL(0x7e821113,0x560a5e57),LL(0x4ec38a12,0xae4b9aaf),LL(0x8358d926,0x1cb5c9a3),LL(0x7b69c24b,0x0e546449),LL(0xc0748541,0x660a2d50),LL(0xa4c426fb,0x87263ee5),LL(0xc286e0b9,0xf7b3ba20),LL(0x4bed6c50,0x9dd6eae5),L_(0x000000f0), + LL(0x9263865c,0x4434e163),LL(0xf3a80e48,0x9ca69373),LL(0x9608a668,0xc4b09404),LL(0xb3964738,0xbe4c6ca8),LL(0xe169bce3,0x7c62a7e9),LL(0x4efa6e4a,0xb46b0f85),LL(0xe2e5aeb2,0xe0111694),LL(0x6babf49a,0xb472f5f5),L_(0x0000003e), LL(0x2589af29,0x286fb826),LL(0xc48651eb,0x97cf3fde),LL(0x6f9d0884,0x78bdc9d0),LL(0x16ca5665,0x7e3d1e7d),LL(0x5a2f1773,0xc2f14e0d),LL(0x5e7f3258,0x6606eb12),LL(0x77a28311,0x67442ff0),LL(0xc80cdb6d,0x08ac890b),L_(0x00000177), + LL(0x6f4c68a5,0xfaab85ab),LL(0x18a863e0,0x8722f321),LL(0x96627616,0xe3cfe440),LL(0x1b986ba1,0xc819b534),LL(0x03e0ab51,0x7155ab76),LL(0x9cf682fc,0xc9e37547),LL(0x4f4f98e5,0x137f31be),LL(0x3cda736a,0x3a508340),L_(0x00000001), LL(0x91d6868c,0x2e86f052),LL(0x70f48703,0x14f3d533),LL(0x6c353990,0x099af7f9),LL(0x0b2a6c71,0x3d4612fb),LL(0x9b98b62b,0x406a6c59),LL(0xe6249353,0x3b1b8dd5),LL(0xc92d7a1b,0x1f751af1),LL(0xf81ef140,0x4692b4e0),L_(0x000000ee), + LL(0x2c9d1106,0xdc34aa30),LL(0xa7bfe1cd,0x28ee1801),LL(0xd18bd43a,0x6d6e3e49),LL(0x52b35eba,0x25fc7059),LL(0x7bfa8888,0xe767a889),LL(0x487fe05c,0xbcac8ca5),LL(0x09996d23,0x52fe2328),LL(0xe81bfb43,0xe19e490d),L_(0x0000006e), LL(0x121f3bab,0xa0be654b),LL(0xd4307448,0x230e8622),LL(0xa9492744,0xcf01fc0b),LL(0xe7b1abae,0xcc98dab2),LL(0x4d9cffdc,0xf6504381),LL(0xe9697cb5,0x506e8f37),LL(0xc3dfae33,0xc253ed02),LL(0x141d1dda,0xb927e31d),L_(0x0000001f), + LL(0xd4e2418e,0x60bac026),LL(0xe3153f45,0x08c6a85e),LL(0x8e05a0fb,0xabec7d7d),LL(0x5867d053,0xca6918d3),LL(0x1ebaaa06,0x7d8627f0),LL(0x6ea92220,0xdfe74b9c),LL(0x27dc332f,0x54478deb),LL(0x33ddba7b,0x1e5dc6b6),L_(0x0000017d), LL(0x2feb3b84,0xd254321c),LL(0xbd92cdce,0xae0be12c),LL(0x91edd7e2,0x65ab5fae),LL(0xacef4485,0x607c22ad),LL(0xe3f288c1,0x01e22b70),LL(0xa3baea8d,0xe3598c73),LL(0xc24e3c94,0xf89cd9f6),LL(0x595791d3,0x15c887a5),L_(0x000001b5), + LL(0xa048c822,0xbacfe4cd),LL(0xc1680ce0,0xd2bf80ae),LL(0x4efcb3dd,0x3024028c),LL(0x029e5c0d,0x63d006d1),LL(0x5acb256c,0x1d3229cd),LL(0xee644462,0x6e4f2a9d),LL(0x4aa18f75,0xd4fdba43),LL(0x437e2a93,0x45e800b4),L_(0x0000013d), LL(0x7de729a4,0xcdd3e499),LL(0xf4a84a14,0x9fba5f0d),LL(0x87d56bc9,0xa92225d1),LL(0x637de402,0xa9f81afe),LL(0x142558b2,0x2061f42e),LL(0xd09b2789,0x1e15d846),LL(0x8753411a,0xf0c0c378),LL(0x83c3fa31,0x8e19c92c),L_(0x000001ff), + LL(0xda11421c,0x8eaf7d82),LL(0x6c3eef0e,0x9224cdcb),LL(0xd8359bd5,0x34b2e501),LL(0x734d08d8,0xd9f7f27c),LL(0x60136559,0xa91fd047),LL(0x7da1c7f8,0xcb1bc103),LL(0xf3f7e7c7,0x65c241e1),LL(0x7555ce39,0xf11e10f9),L_(0x00000055), LL(0x6b91fc57,0x5484eacb),LL(0x8a825cda,0x888b470b),LL(0xf0a2ebdb,0x81202cfc),LL(0x3ac37a5b,0x05c01038),LL(0xfe8f11c9,0x5bf196e7),LL(0x76123e92,0x19cd94ed),LL(0x353febf7,0x9c972db2),LL(0x65d70280,0x988f859d),L_(0x00000064), + LL(0x217d03c5,0x56db67a5),LL(0xf3d76a7f,0x992b8bdf),LL(0x4fb50dfa,0xf9702a82),LL(0x5593b5d5,0x9088a3ea),LL(0x0ef00d4d,0xbf26b47f),LL(0xeb497149,0x0793417a),LL(0x58262023,0x465f75db),LL(0x4abc908a,0x2c6c549e),L_(0x000001e0), LL(0x1667b32f,0x4ef57c25),LL(0x0a4bdcb0,0x6e8c095e),LL(0x696391d7,0xabbc605b),LL(0x1dd44220,0xc3e47f6e),LL(0x38adb47e,0x8f35f645),LL(0xd3c084d2,0xf253b25e),LL(0xfaa3b241,0x0b53ca2e),LL(0x2e3d4cbe,0x6c56c789),L_(0x000001f4), + LL(0xf26ba24d,0x0d68d639),LL(0xbc6bcbf3,0x76bdcf5c),LL(0xd445a425,0x4ce8f583),LL(0x036223e7,0x12c0333e),LL(0x6b6c4cf4,0x411cd547),LL(0xfa6d4a89,0x6d3fb3c8),LL(0x7e41166b,0x906f6895),LL(0xd5a83001,0x28190a6a),L_(0x00000076), LL(0x33fa874d,0xdb9b9bf4),LL(0x6efa8bd8,0xc1467c44),LL(0x78067572,0x41957d49),LL(0x68a286e7,0x4563827a),LL(0x3562fe94,0xd87962e4),LL(0x5b2ba1f2,0xbce9e3b5),LL(0xeb40dfc9,0xedcbc4f7),LL(0x6ddd5a2c,0x2d14704c),L_(0x00000009), + LL(0x70bab965,0x738ba18f),LL(0x90ebea6a,0x3526ec84),LL(0x544312d2,0x606e765e),LL(0x4f7ce18b,0xe015cac8),LL(0x0b6de72b,0xea01d5b4),LL(0x2ff4bd72,0x0c7eba91),LL(0x90d594c1,0x8a32c97a),LL(0x881a1a5b,0x326bf5cb),L_(0x00000188), LL(0x8272c1c5,0x72a5ff2c),LL(0x0ff0a2ad,0x4bb6c7a4),LL(0x640ae3bc,0x87804672),LL(0x00da0040,0x94aaf22e),LL(0x2ebbcebb,0xd8f3e9bf),LL(0x8646dab7,0x40c90d99),LL(0xd08b3434,0x8f9d970b),LL(0xd1f0de73,0x2362e1e3),L_(0x0000004a), + LL(0x893123ae,0xc8b47342),LL(0xedaef283,0xde3df2dd),LL(0x303757c2,0xc96f2592),LL(0x089845fe,0xa0d3f290),LL(0x18b0b508,0x4bf7b214),LL(0x93c88975,0x3cd67758),LL(0xed218a4a,0x81a61b63),LL(0xfa78dcc6,0xdc5a49e5),L_(0x000000ff), LL(0x90ce8d10,0x6c24429c),LL(0xe40a36fc,0xc3ad8e81),LL(0x6178bcf5,0x16d9b177),LL(0x488d2cf8,0xc063b1e0),LL(0x57f41dcf,0x1cbca7c3),LL(0x200bb41d,0xec7a80d6),LL(0xd6366c22,0x84ceffb4),LL(0x66439f2f,0x6b57b092),L_(0x0000016f), + LL(0x869f06cd,0x97f9882a),LL(0xaa57537b,0xe3b1c07d),LL(0x917cf4ff,0xf6d1aa12),LL(0x2683a59f,0x73bca1f9),LL(0x613d785e,0x496708d8),LL(0x66ede999,0xf45fff24),LL(0x4e9727c1,0xf71c4572),LL(0x39995099,0xf55978fb),L_(0x00000090), LL(0x60222373,0xf249fc50),LL(0xdb62572f,0x95b4f7eb),LL(0x4efd7ca7,0xb4994b20),LL(0x0762c1c5,0x99292d14),LL(0x4d4c1985,0x140a608e),LL(0x7f0ba7f9,0x489023fc),LL(0x77e472d8,0xac039583),LL(0xca8aeb86,0x303e3f76),L_(0x000001e6), + LL(0xa1cd049d,0x859af0b3),LL(0x32b70dbe,0xd9aa6b96),LL(0x83656cba,0xa5229dc4),LL(0x02bc7ba1,0x574b487d),LL(0xffc68a06,0x9518ff35),LL(0xad36470a,0xaf20c720),LL(0xcf8b908a,0xee3bb49e),LL(0xf8b9d88a,0x204ddf66),L_(0x00000075), LL(0xc04ae92a,0xff799aa5),LL(0x352ca9e2,0x48de6d0a),LL(0xeb0f3051,0xe2b8f5f2),LL(0xa98f1062,0xdfe726fe),LL(0xc285eca4,0x22419400),LL(0x527244d3,0x441ba1f9),LL(0x3ec0c841,0x9ac0f611),LL(0xf7b09376,0x483ffb67),L_(0x00000159), +}, +/* digit=74 base_pwr=2^370 */ +{ + LL(0xce2d58e6,0x4fd2b399),LL(0xe56a0a18,0xd46ffafd),LL(0x43a772e3,0x61832664),LL(0x5e99ec73,0x5a652a9e),LL(0x068acc97,0xda22ced1),LL(0x829eb99d,0x17534159),LL(0xc94c616f,0xf6ab0176),LL(0xa334609d,0xf8e1dfbd),L_(0x000001bc), LL(0xf0e586eb,0x03144a03),LL(0xdf49ef2f,0x70d82d13),LL(0xf054795a,0x3d4fad35),LL(0xca4e83c9,0x7178dcbf),LL(0xdccd2e81,0x06f96d5d),LL(0x059906d9,0x99860a4c),LL(0xb0cc8989,0x0b7c4473),LL(0xc7a2422f,0xc031d2a9),L_(0x00000158), + LL(0x990d40ea,0xfd292d5f),LL(0xfe2aa0bf,0x0b3c033e),LL(0x350ffa07,0x7093caf5),LL(0xcba18d05,0x8e77aa62),LL(0x5de1ef34,0x8dcafce9),LL(0x8d305062,0x54c13b97),LL(0xa2184206,0x024b7581),LL(0xc1eed7a3,0x7a430aeb),L_(0x000000fb), LL(0xd2467c3c,0x5919f6e7),LL(0x6f3a2cc6,0xe4ef4ee6),LL(0xd95dc335,0x8b15339d),LL(0x53862418,0xc47f7183),LL(0xdc9f6ee9,0x0164075a),LL(0x8fc3c2d0,0xfb8c9b9b),LL(0x82f15ec0,0x2cab4250),LL(0x6da80b24,0xef0f9370),L_(0x000001fe), + LL(0xce799013,0x9e5e77aa),LL(0xdc0e8efd,0x74901979),LL(0x87335bd4,0x8d25ae87),LL(0x7663b155,0x30b14eb3),LL(0x42427def,0x9f7acb63),LL(0x504e9e47,0x8f787f03),LL(0xb68c9ee0,0x9fb2d8ed),LL(0x3fafed1d,0x168ae687),L_(0x0000008e), LL(0x84c837fd,0x1b05f526),LL(0x361ad6ff,0xa178f8a8),LL(0xba6a96b6,0x0afa0765),LL(0xf1a53f48,0xee02b40e),LL(0x455203e1,0x280a052e),LL(0xa80a8929,0xcc11be29),LL(0x6815682d,0x4811eb83),LL(0xd7ede303,0xae7746c4),L_(0x000001bd), + LL(0x33981c54,0xcebb5e69),LL(0x32546345,0x544b1b16),LL(0x84cafbc6,0x7981b01f),LL(0x5cddc181,0xaa139311),LL(0x1378ad86,0x68cbb494),LL(0x7e2675fe,0x588ce3ac),LL(0x7f2694e9,0xab708d62),LL(0xeda381dd,0xea9b5a9d),L_(0x00000155), LL(0x31d5f56f,0x1a13df6f),LL(0xcdb4564c,0x02f2a54c),LL(0x586ae362,0x19118f47),LL(0xdb9ebb1f,0x7fa3e3f6),LL(0x0b71b651,0x82c695b0),LL(0x82ecf8c2,0x58306aa8),LL(0xc8a72bb7,0x24bb71fa),LL(0x1671f4f9,0x8041f535),L_(0x000001c7), + LL(0xccfdb09e,0x9138999d),LL(0xfc40b806,0x190da0c1),LL(0x248d01f8,0x660fe973),LL(0x04db0124,0xd2a3e26a),LL(0xae1441c8,0x3b5b69d9),LL(0x542d784a,0xe47e9fb1),LL(0xc8706904,0x07fd3e18),LL(0x7b0252dc,0xac397897),L_(0x0000003e), LL(0x9bf565f8,0x7a07a372),LL(0xb2a08e69,0x88b9b9fe),LL(0x23737883,0x4af5f0ac),LL(0x3ee2589f,0x4d74831e),LL(0x0c99ecfe,0xe461011a),LL(0xccb75730,0x5f6ac945),LL(0x44dfe861,0xde67a0c4),LL(0x0a4190dc,0xc1f45c07),L_(0x0000010a), + LL(0x8eb6ed93,0x8217bc59),LL(0x480c8b3d,0xf9f73e7b),LL(0xed85e1cf,0xa742114e),LL(0xff0dd45c,0x5d90782b),LL(0x6499236f,0xa8a56eb6),LL(0x81a46542,0xc0a1d718),LL(0xb645bf88,0x5ad3645d),LL(0xda5b3451,0xe35c84b5),L_(0x00000062), LL(0x8177efc2,0x91a87849),LL(0xd64e2a8c,0xb25866c7),LL(0x7fcea597,0x7ba86329),LL(0xf0a84157,0x4ae784c7),LL(0x6d45e6a0,0xe8a4e8e8),LL(0xbad02a45,0x2b8a78de),LL(0xcb445d9a,0x1a096a8f),LL(0x1c606af7,0xcd9a146c),L_(0x000001e4), + LL(0x9ad71dbf,0x013860f9),LL(0xefc2f3af,0x0bf5cd2e),LL(0xcc51df06,0x366cecf5),LL(0x8b6d4774,0xff5f3234),LL(0xb320cd40,0xa48903e0),LL(0x331e170d,0xf463c308),LL(0x7b602dac,0x3d097dcb),LL(0xca3b41f6,0x1437b881),L_(0x000001d6), LL(0x1f06f98d,0x9812b78b),LL(0x0835cbf9,0xa1b46e69),LL(0x96985a6e,0xc756e3cb),LL(0x8c83dd55,0xe0033ed2),LL(0xc71730ab,0x7a46dc00),LL(0x333b6de9,0xe8045912),LL(0x8f656577,0x4a453d9c),LL(0x385fe0c5,0x9c113ca9),L_(0x0000014a), + LL(0xcb831835,0x9d0103c9),LL(0x47a18b26,0xbca486ca),LL(0x2d151fe9,0x8a31af06),LL(0xc2bcd6c3,0x4c38dae7),LL(0x6a2dd494,0xd0cab5f5),LL(0x0e8dd5e2,0xaaffb6b8),LL(0xf1aa0451,0xd1b4ab87),LL(0xd7ec926b,0x23418baa),L_(0x0000000d), LL(0x61149962,0xd2761793),LL(0x4dbe67f0,0x5f42f5e1),LL(0xbdaa4d19,0x9aea3745),LL(0x2770c1ff,0x336a10b0),LL(0x730746fe,0x965986ef),LL(0x500d5a19,0x98b61ae7),LL(0x2c56a5b5,0xfbc2b7c9),LL(0xf20ece26,0x484287c0),L_(0x00000016), + LL(0x47a76498,0xc197a42e),LL(0xa29d1821,0x8a2704b7),LL(0x54a27b18,0x6d7a65e1),LL(0x382392a3,0x6e25e555),LL(0x583ca3d8,0xba1298fb),LL(0x92305de9,0x8762634a),LL(0xc416a724,0xe3560751),LL(0x52b73064,0x9264b444),L_(0x0000019b), LL(0xd4b7caca,0x4fc9c7a4),LL(0x0d61d52c,0x88ca3d7d),LL(0x39c96801,0x9d85c914),LL(0x072c2d52,0xeae1af66),LL(0xdc7e4834,0x4567d964),LL(0xcf69cc8b,0x225a1435),LL(0xec05edf7,0xcf0fd41b),LL(0x16674dc5,0xa580cfec),L_(0x00000120), + LL(0xc929fb7d,0x666eee50),LL(0xa82ad2d3,0x943d9f3f),LL(0xe959c5db,0x01361c6c),LL(0x413dcd10,0x810dc990),LL(0xba8e95a8,0x111bfce1),LL(0x144ccf37,0x37942ccc),LL(0xbba23cc8,0x6250c86e),LL(0x64797a98,0x95ec8524),L_(0x000001d4), LL(0xa61fd6b9,0x324caf26),LL(0x208fb38d,0x802296a3),LL(0x923005fe,0x1cab4d64),LL(0x545d2ffc,0x7edf08f3),LL(0xfd85bdf3,0xbbb0b3e1),LL(0x9feb12a7,0xab0ed8c1),LL(0xeb4e517d,0x45179c50),LL(0x5c75791e,0x1bac0194),L_(0x000001cb), + LL(0xebddb001,0x809051bf),LL(0x932eff69,0xb46ff016),LL(0x5ce81f11,0xb49261d6),LL(0x39183971,0x75ef3047),LL(0x65753518,0xefad1e5a),LL(0x7887db59,0x147b2e1c),LL(0x6c93b47e,0x239259f0),LL(0xb5f34e30,0xe56b4fc3),L_(0x000001c8), LL(0x905217df,0x861e1dc6),LL(0x9fada5a7,0x3986b470),LL(0xf9e88cd0,0xcaab1d92),LL(0x839c290b,0x02e99a54),LL(0x39b3ffa9,0x910523a5),LL(0x655e6f7c,0x42d47f30),LL(0xb367bd8a,0x1e0a7f1b),LL(0xe25d7561,0xb79355b2),L_(0x000001ad), + LL(0x4987e69d,0xd0493c78),LL(0xba0a5cbe,0x59557a83),LL(0x75bbdb17,0xf2acabc4),LL(0x65e4a623,0x8bf3c53d),LL(0xd71fb7df,0xc8eb2466),LL(0x7545f576,0xc6d8140f),LL(0x620a0123,0x9f02bd4e),LL(0x67837a46,0xbdab7cb9),L_(0x000000e5), LL(0x8b871f92,0xc2538248),LL(0x4b3a3a4d,0xef93af7d),LL(0xdbf730c3,0xbfd3ed77),LL(0xf764526e,0x07f935a6),LL(0xcb6152b4,0x1c016476),LL(0x2bf32571,0xdee3ad5a),LL(0x88aaec73,0xfb09ed56),LL(0x5a614fc9,0x9f8877cb),L_(0x0000002d), + LL(0x7c127a9f,0x26712a11),LL(0x642533c6,0xf98c4d57),LL(0xc60c2ae3,0x65b1d46e),LL(0x444527b6,0x71dbb3f8),LL(0xe33842c0,0x4381ace7),LL(0x9e839852,0x6a3b078e),LL(0x2c3ba212,0x4de7e214),LL(0xed5d5463,0x3d30ea71),L_(0x00000163), LL(0x2312ab46,0x8e3acd07),LL(0x631b2001,0xb498759a),LL(0xcc66ba39,0x22f04bfe),LL(0xd634fae4,0x0f57a006),LL(0x6fb05b0c,0xd36ff867),LL(0x74e2535a,0x85b24cf7),LL(0xe1ec7865,0x1a8674c2),LL(0x8caeb36c,0xac17ecae),L_(0x000001bc), + LL(0x41ce000d,0xbbc4d762),LL(0x3f8e4f4a,0x850dfa23),LL(0x315d2f3b,0xc39228da),LL(0x146ba937,0xe938195d),LL(0x05ba80b7,0xa6946ca0),LL(0x5996d5e9,0x8582cc92),LL(0x20830fe7,0x9fbffd5e),LL(0x49bd8864,0x35f18f3a),L_(0x0000016f), LL(0x52a9ca5f,0x342678f8),LL(0x0fde0f1b,0x03e8057f),LL(0xb03f731a,0x68041b2c),LL(0xc1b65ef3,0x5e348390),LL(0x812a39aa,0x6058d643),LL(0x85301a5f,0xf291dfe0),LL(0x3f43fec2,0x4f9f3872),LL(0x0ea19231,0xfc5949c4),L_(0x00000109), + LL(0x2071dbfe,0x4b89bb6a),LL(0x243135cc,0x0ff935bd),LL(0x7a1a0770,0xe0c7a9ac),LL(0x227a5593,0x6dd5bad8),LL(0x3493e1c5,0x8ba3715d),LL(0x35c53b09,0xc6b271ea),LL(0x744d2bd3,0x2e9feb1a),LL(0x214dd692,0x2db119cb),L_(0x000000b1), LL(0xeec6e175,0x1f9d847f),LL(0x63ead5ad,0x5419e32c),LL(0xd6156a57,0xe233586a),LL(0xe66a5622,0x39029648),LL(0x4092e8b6,0xbf26b933),LL(0x1e5f719a,0xcd5ad746),LL(0x4f5fc4b9,0xf552f21c),LL(0xd86c96b0,0x997ee591),L_(0x000000b3), + LL(0x9ad2983e,0x090fc8d4),LL(0x3313e6f8,0x55cd8ed4),LL(0x8651d168,0x6a906312),LL(0x55315e35,0x591a919d),LL(0x83731bdb,0x5172884d),LL(0x209c90f3,0xe2ac6b9b),LL(0xfbd125cc,0x92e9decc),LL(0x7d19839d,0xff6024c6),L_(0x0000016a), LL(0xed7835fb,0x29318405),LL(0x7858c38c,0xc88969fe),LL(0x39c13839,0x9e3d9e6b),LL(0x193b8588,0xa0e5421a),LL(0xe0167b73,0xc6ebad78),LL(0x3cbbe3a6,0xea506121),LL(0xa8cbcf0f,0x20f99af7),LL(0xdbdf82d3,0x2e935934),L_(0x00000010), +}, +/* digit=75 base_pwr=2^375 */ +{ + LL(0xa97c0378,0x851811ca),LL(0x042ad325,0x0425fd5a),LL(0xae223e37,0x93b83181),LL(0xf721e5a1,0x90e949dc),LL(0x0e3457f0,0x3df6a852),LL(0xb654bab8,0x5f22447c),LL(0x720ad354,0xec0dfbcc),LL(0x64eddb51,0x81daf300),L_(0x00000178), LL(0xa97e2d48,0x5a22dda9),LL(0xa660386d,0x4ad7ed63),LL(0xf4eac86c,0x0e9bdfd6),LL(0xa0b3cfe9,0xf3d0576e),LL(0xb9746e43,0x38598ede),LL(0x5a4f247c,0x6c63f53c),LL(0x9110d7d6,0x937de7ce),LL(0xedc5628f,0xd7ef1580),L_(0x00000149), + LL(0x07ceb75a,0x22d17ed3),LL(0x1d003cd4,0x816d46db),LL(0xacb6fef8,0xb000a452),LL(0x9bbe93ac,0xa33425cb),LL(0x8e7044e1,0xd94105ed),LL(0xbf04fc32,0x7b448d72),LL(0x8a8006d7,0x77527b27),LL(0xce1c27af,0x481ed3f3),L_(0x00000072), LL(0xede21a04,0xbea8a562),LL(0xfe905ba2,0x7dcaa390),LL(0x8bd01814,0x8c2e3be5),LL(0xad37906a,0x4bd6ba24),LL(0xe4147c93,0xab35993e),LL(0x54b18700,0xeb32c196),LL(0xc4b62833,0xfde9fb6d),LL(0xefce4982,0xfd482fff),L_(0x00000009), + LL(0x326389a5,0x8c87ee07),LL(0xc8d06b64,0xf1eb33ca),LL(0x9f6c9bde,0x905394b5),LL(0xe7cff087,0x9daef572),LL(0x15defa0d,0xdcb4d146),LL(0x48372dac,0x9d9bc2a2),LL(0x558be40e,0x918fbab0),LL(0x093092b7,0xd1e9cb05),L_(0x00000158), LL(0x80e77a4e,0x1e399561),LL(0x7faf6193,0xe636d3ab),LL(0xe0b54eab,0x0991ea6a),LL(0x12db09ef,0xe300cb6a),LL(0x2c4871c5,0x5b2c3ec2),LL(0x74b476ca,0x01ab0f81),LL(0x571997b2,0xe7647206),LL(0x7f0593e9,0x19083320),L_(0x00000084), + LL(0xcb8ddce8,0x53953842),LL(0xc94eac86,0x510be22e),LL(0x18af52b2,0x5204fc68),LL(0x6cd384c6,0xb08bd4d3),LL(0x40918e38,0xbbca8f66),LL(0xc2ac8cd3,0x9b3d5866),LL(0x2e4fdaef,0xbd15b5a2),LL(0xcebfa696,0x2334128f),L_(0x0000013b), LL(0x8986becf,0xa9f4f0a0),LL(0xb5bde2b0,0x2781857a),LL(0xf623a384,0xf48f7d34),LL(0x2fc32d5d,0x5aed2eab),LL(0x3357b29a,0x85d8000c),LL(0xd7a02a4f,0x47c091a8),LL(0x83e2289a,0x748c8758),LL(0x78f3991d,0xb7dfe04c),L_(0x000001eb), + LL(0xe09895cd,0x8dc487b8),LL(0x1ee06c73,0x4cd52925),LL(0x3615a586,0xb40cf5e8),LL(0x67c6302f,0xe2444c40),LL(0xad0f9fd1,0xf79a9138),LL(0x21560ea8,0x53b1f139),LL(0xdfcbf2e3,0x42f5c15e),LL(0x937e18f2,0x4b1cf2d1),L_(0x00000141), LL(0x2b5822b9,0x4289e6fd),LL(0xcce11b47,0x6b3fbfe6),LL(0xfc6c35ad,0x42db4435),LL(0xf40269b9,0xd9e6571d),LL(0x052ecbf9,0x43b34e97),LL(0x85c17cbf,0xc1ac2947),LL(0x2cf45704,0xb8e4df72),LL(0xccda58a9,0x77f6ed90),L_(0x00000164), + LL(0x736929bd,0x2018c224),LL(0x183d085f,0x4be72094),LL(0xb8504d5a,0xa1b86c43),LL(0xb6f18e21,0x4ff46986),LL(0x6ad297dd,0x8a9142ac),LL(0xaf090f36,0x09fe86be),LL(0x3b6921ae,0x3c8c552b),LL(0x953006e9,0x8c728bce),L_(0x000000e1), LL(0xaf72ac6e,0x80956c6b),LL(0xfa741157,0xc4c2c5f7),LL(0x5e9870c9,0x7ec1eba5),LL(0xf57cfca1,0xc10b4b60),LL(0xa6e490cc,0xb0618cc6),LL(0x39e98a9d,0x31fe5f00),LL(0xf0f53611,0xb1970dbc),LL(0xa442baa6,0x0c613700),L_(0x00000000), + LL(0x90a308db,0x61cca596),LL(0xcbaa218f,0x6743511c),LL(0x6574da13,0x71c34c1b),LL(0x50cf99a2,0x570b3140),LL(0x8ae9a0ed,0x8fffc78b),LL(0x816fb1cc,0xe8d131b4),LL(0x052abb5d,0x64b0d1f3),LL(0xe564075c,0x02a02c6f),L_(0x0000014e), LL(0x5fb1b653,0x57fab65e),LL(0x72bc2ab8,0xcd37e51f),LL(0x6c8bb1d5,0x57d81547),LL(0x75b37fd5,0x572bd385),LL(0x1441e8d8,0x0eb239d2),LL(0xd5a6c392,0x7cc7ae14),LL(0x16b857f6,0x7141c32a),LL(0x931901c6,0xd7fbdf6f),L_(0x00000041), + LL(0xe53ec842,0x16678799),LL(0xeb3f78fb,0xdb8c26f2),LL(0x1091298b,0xe09307e4),LL(0x265d3b22,0x79682bc2),LL(0xf829161a,0x8a62536f),LL(0xdea99410,0x002fb6de),LL(0x3d369ec2,0xca79fdbc),LL(0xf58b2f20,0x3d6462ba),L_(0x00000130), LL(0xf756d9fe,0x61419646),LL(0x9934641a,0x308b017c),LL(0x5de627fc,0xbea2b76a),LL(0x23ee7d29,0xba8603cb),LL(0x6ab47900,0x85c79476),LL(0x004b96bb,0xf41684cc),LL(0x94d547ed,0x8b7656ed),LL(0x2003142b,0x30eaee30),L_(0x0000014d), + LL(0x8759d864,0xfb67c7fb),LL(0x0407a03f,0xfb9982ce),LL(0x020231ea,0x55103874),LL(0x9d3dc0fe,0x9a32c3ea),LL(0xc54c5166,0x8e76b967),LL(0x7422e59f,0x538d7969),LL(0x1567215f,0xc1772e51),LL(0x1bee3ac0,0xeb37df59),L_(0x00000159), LL(0x44e31ef8,0xeef4a1e2),LL(0xf4d1de52,0x78709a3f),LL(0x144880f0,0x90e1bf50),LL(0xc5a2e2e7,0x6576ad05),LL(0x963afdb1,0x858a5053),LL(0xfb62a6ae,0x720e44be),LL(0xf7d3d903,0x85ea2a35),LL(0x1ce3e300,0xbc7fd8b2),L_(0x00000178), + LL(0xc85cdf02,0xe346fabb),LL(0x2b0945e1,0xe07629de),LL(0x76a1e2b5,0x45e5724f),LL(0x43bc885c,0x6f8c506b),LL(0xbd1f5350,0xc4a247ae),LL(0x9759458e,0xe8c49a8e),LL(0xad9f81fe,0xef961f24),LL(0x0789ce81,0x4d378c78),L_(0x00000045), LL(0xbdac3a5a,0x0d120ebb),LL(0x2f38cfe3,0x29a29c91),LL(0x470f8673,0xa93d27e5),LL(0x85f54b6a,0x347ce7f7),LL(0x869bc2c6,0x681c6e83),LL(0x240291c1,0x5f895132),LL(0xd778a681,0x9354c132),LL(0x35657182,0xd9159913),L_(0x000000a6), + LL(0xdc0c7615,0xd08ada52),LL(0xf64fa06b,0x6fe343d4),LL(0x0f9f191b,0x269d74ba),LL(0x2b582fb8,0x3e1302f6),LL(0x4f3fa209,0x3dd58666),LL(0xbaec4e8c,0x2346df80),LL(0x2addc663,0x961745b5),LL(0x6358e5f3,0x18d6fbc0),L_(0x000000c0), LL(0xbca3dd73,0x0f473bff),LL(0x97d4d8fb,0xcbcc7f23),LL(0x592d62f3,0x8c21a728),LL(0x2d18d7d2,0x08669251),LL(0x5acddad3,0x10138815),LL(0x5eb1d5da,0xaf710391),LL(0xf88b7078,0x200a8738),LL(0x9614df01,0x7fc7b078),L_(0x000001a8), + LL(0x39f8e71a,0xf8ccaa40),LL(0x89f9fde7,0x4a565eb3),LL(0x3a88c7c8,0x2241445b),LL(0xb88e20b6,0x0479b1b1),LL(0xe22d8db0,0x96695cdc),LL(0x02fe3690,0x48a70132),LL(0xaba6a66d,0xafe3713b),LL(0x5be868e0,0x4959a9b6),L_(0x0000007a), LL(0xc518718a,0x3e38b8c6),LL(0x00a613fe,0xee16d3bd),LL(0x8bab2dac,0x5f51a73a),LL(0xecd0dde7,0x5d598b1d),LL(0xf9a19d5d,0xcc2ed8e1),LL(0x74ed2f5d,0xb66c7686),LL(0x1a036457,0x45717b78),LL(0xeb14d9fd,0xebae3cd5),L_(0x000000c6), + LL(0x42bb5d7b,0x69ebb0a9),LL(0xf6f6e0b1,0x24c217db),LL(0x751a1bfd,0xd4eab425),LL(0x1570cf87,0x46afeada),LL(0x55c17749,0x84f69779),LL(0x72264346,0x0e0b6e91),LL(0x43f9c928,0x2a080641),LL(0x5face2cd,0xd6f99ce6),L_(0x0000011d), LL(0xb97b52aa,0xb84b4c35),LL(0x079d267b,0xea1ade5e),LL(0xfd3d3470,0x64da3bef),LL(0x603b5d99,0x4e2ca35b),LL(0xc90c1bef,0x267ee929),LL(0xa4dcd6fa,0x2e371559),LL(0xeadf09d2,0xdc90620c),LL(0x7ae7bd5e,0xa0074931),L_(0x00000049), + LL(0xe19a4c40,0x3bef2c63),LL(0x57c68d2d,0x922215ae),LL(0x03e85348,0xb54763ee),LL(0x7a4a0d2c,0x4381fb33),LL(0x747d2320,0x3d971222),LL(0xc828be44,0xd96627f6),LL(0x6d1199b7,0xabfb6b5f),LL(0x3d2170b3,0x7e019a43),L_(0x00000146), LL(0xbb1d3366,0x8c946a2e),LL(0xa111d7a3,0xb29fb103),LL(0x75997def,0xa9647d36),LL(0x82824e10,0xa45fdefd),LL(0xf29d6d05,0xa9b94f37),LL(0xe35c500f,0x317e08c1),LL(0x4c601022,0x2a6ed921),LL(0xa2afcd4a,0x376d3ee0),L_(0x0000012e), + LL(0x14a651b3,0x6443bb77),LL(0xc4e092bf,0x3d523243),LL(0xb725b204,0x563f7657),LL(0xf0d19ab6,0x6dd80a2f),LL(0x0c09a035,0xa3a7805c),LL(0x72bfb218,0x767659a8),LL(0x5001304f,0x06ad0ad0),LL(0xae6cf2cf,0xa76a4e48),L_(0x000000c0), LL(0x73b1275f,0x58294610),LL(0xf2619fd4,0x12455781),LL(0xc2991198,0x822a98ac),LL(0xc52b1be7,0x6f92e55b),LL(0x85c5dde4,0x6f912a88),LL(0x71070200,0xc6ff80dc),LL(0xed86ff4f,0x5fb4c0fb),LL(0xf6cd415c,0xb7ec4feb),L_(0x00000025), + LL(0xe13291f0,0xa731176a),LL(0xc2f095b8,0x53e5b4c8),LL(0x22d8f01b,0x9b8d5a23),LL(0xf09c9053,0x6cfad192),LL(0xac4c2264,0x016016f3),LL(0xc2d48df5,0x500c56f4),LL(0xbed57312,0x206618c9),LL(0x249d3807,0xcc5fef52),L_(0x00000059), LL(0xa752bb21,0xa854f0db),LL(0xad82109b,0x2bd9fbff),LL(0x39d0e928,0xe612cee3),LL(0x5cfc63fe,0x3aca9e51),LL(0x18541bf3,0x0fd5f823),LL(0x1df11f0f,0xdccc44f5),LL(0xe5d7f0f8,0xc8e26d92),LL(0xdc204c43,0x7278c334),L_(0x000000c9), +}, +/* digit=76 base_pwr=2^380 */ +{ + LL(0x90df775a,0xa877dfb5),LL(0x0e8c657f,0xf628f95d),LL(0xc58775b2,0x1f94b622),LL(0x55966c52,0xd94ba3e7),LL(0x2b826bca,0x536e1836),LL(0x1429585e,0x6a8bf64e),LL(0xab9cff45,0xfdc0d065),LL(0x7ad254f1,0xd4d31c6b),L_(0x00000099), LL(0x10be2241,0xa869cd60),LL(0xb5cc49f5,0x399cde94),LL(0x029dfb84,0x53bc96f6),LL(0xc7d08220,0xf3d33d68),LL(0xb6cb5f4b,0xd70bd72f),LL(0x81e790ba,0x5f85b782),LL(0xd6b87ddc,0xd6fbd3aa),LL(0x9bddab2f,0xd049e67e),L_(0x0000007c), + LL(0xcff0963f,0x1215b91a),LL(0x7ce3e2ea,0x276c4b8c),LL(0xae4d76fd,0x27c2c599),LL(0xcf3a3b9f,0x985a8106),LL(0x706667b3,0x3dd5545f),LL(0xe5bf95ab,0x9ae8ea63),LL(0x5a494d9e,0xac8eb301),LL(0x36df8e2a,0x0aa3c14b),L_(0x000000cb), LL(0x241e0605,0xec384ae0),LL(0x19fc3d54,0xbfb3e2ee),LL(0xce0a2d7c,0xa5ac041b),LL(0x7e0aa0d1,0x22b978b5),LL(0xcf6adf10,0x50508726),LL(0x13804525,0x77d6d81e),LL(0x02fbac9b,0x34536c98),LL(0x6666d2c2,0xdd6867d1),L_(0x000001f2), + LL(0x0fd75964,0x2c167fba),LL(0x79fb34e2,0x68658968),LL(0x3d2ac14b,0x6bb85f11),LL(0xf9265032,0xe567c4fc),LL(0x09815c6a,0x30478f2d),LL(0xb2da7033,0x2d4e045b),LL(0x7450186c,0xeb491702),LL(0x3d6ff5bb,0x394b01cb),L_(0x00000186), LL(0xa96aee5e,0x7fa7f974),LL(0x54b866f5,0xd445b199),LL(0x7edd540d,0xda3cc41b),LL(0x6672b9ea,0x3c302e2f),LL(0xf5adb45c,0x5ea3de1b),LL(0x201f8535,0x70efd3fa),LL(0x9bc11d2a,0x3d2e2804),LL(0x4d97e055,0x461aca9e),L_(0x000001ac), + LL(0xdb5aaa83,0x020dd38c),LL(0xf16c4ef4,0x0a2db89c),LL(0xa5cd426b,0x43e8b727),LL(0xf5617c8e,0x23ddc0ba),LL(0xb43d6e58,0x259e17f2),LL(0xc826180e,0x06737413),LL(0x55f63ef5,0x434e7412),LL(0x23e6163c,0x6e327096),L_(0x000001c1), LL(0x9695e5ae,0x47505a19),LL(0x6e1e36e5,0x74ec16e2),LL(0x43d8b0e2,0x4831814a),LL(0x037ed439,0x5b1a104c),LL(0x375672e8,0x5bc4b456),LL(0x9fdc64a0,0xf4e8604b),LL(0xdb5b0994,0xa1d8d54c),LL(0x035e5850,0xc99108d7),L_(0x00000018), + LL(0x6b6358ca,0xae97ec9d),LL(0xf89cd326,0x96931bf3),LL(0x0db33ff8,0x1728a8a2),LL(0x5df6988b,0x8b413bf1),LL(0xc9cd5efc,0x7876052f),LL(0x980dbb18,0x662d8014),LL(0x7d44d414,0x56d9235f),LL(0xf0c89214,0xc3bb2edf),L_(0x00000183), LL(0x7d2553d4,0xd43349dd),LL(0xc275fa25,0x98c5095d),LL(0x7e9d6a23,0x5dae8169),LL(0x48607095,0x004d6221),LL(0x0de66e5e,0x88753853),LL(0x407e61fc,0x0cbeddeb),LL(0xb1e576ab,0x85968acb),LL(0x6df65046,0xd7b6cee3),L_(0x000000d4), + LL(0x1d1376b4,0x2c927fc0),LL(0xf4b1b912,0xcb3e3200),LL(0xd6a633a1,0x54477db8),LL(0x4c991410,0xbf0c1c32),LL(0xa9a4d4dd,0xda008df0),LL(0x30c04f89,0xf68e5507),LL(0x1a10f51d,0x5ce5c51e),LL(0x41031547,0x5069b8da),L_(0x000001be), LL(0xdec76b03,0x4ca12b9b),LL(0x53a8bf3f,0x4e3a3297),LL(0x6ef86a89,0xc5a499c8),LL(0x38a372fc,0x97d666c8),LL(0x6ec44e4a,0x41b99123),LL(0x95600ea2,0x650c8dbf),LL(0x4eb71cc1,0x4c7627fd),LL(0x54f79c84,0x0226e786),L_(0x0000002b), + LL(0x69ce7225,0xf1a6e969),LL(0x77785cf6,0x9cc6268e),LL(0xc7d8303c,0x2b8308ef),LL(0x6b0e5276,0xcba9dc8a),LL(0xa4bf9968,0x416fd26f),LL(0x8c4cdb7c,0xe7d932fa),LL(0xde7df0b0,0x472063b5),LL(0xd8e36d94,0x1f940a1b),L_(0x00000187), LL(0x852f11b9,0x528d0c6d),LL(0xe34ebb6a,0x0491c222),LL(0x572cf3b4,0x3235246f),LL(0x6a507a97,0x5419c482),LL(0x151b4954,0xa45d1468),LL(0x1e9ff246,0x555cac59),LL(0x74cf9098,0x3f67c66c),LL(0x4d10852a,0x1f28bc81),L_(0x000001b1), + LL(0x4d4d6495,0x86a81e7f),LL(0x54df2c4b,0x4316eb10),LL(0x19b90005,0x41b6877c),LL(0x63ac12d9,0xdbe38379),LL(0x7bdc46a9,0xe68280f8),LL(0x04afbefb,0x1d97d1dc),LL(0x64f8fe97,0xfdaabbcc),LL(0x3ef9d7ec,0x355cb854),L_(0x00000021), LL(0x4256ebb2,0x5f744a3f),LL(0x462bbab0,0xc6587a4d),LL(0x8de305cc,0xf7cc14a1),LL(0xd2c0e8c5,0x1c2fa456),LL(0xd7f552fd,0x93096db0),LL(0xdf5d165b,0xeef9e935),LL(0x0a7d4ef3,0x8313440e),LL(0x2ecbc3b6,0x31c6420c),L_(0x00000033), + LL(0x4ec080d5,0xc4429668),LL(0x00e4c47a,0x0c5790c3),LL(0x2bb3e90a,0x76060854),LL(0xb06d2fa8,0x51871594),LL(0xb8a8220c,0x35fa01c4),LL(0x96cfa275,0x351722c6),LL(0xd2b5aea0,0xcac00f2f),LL(0x9a7e1203,0x2e7bac23),L_(0x0000010c), LL(0xa79d695c,0xe8bbd2be),LL(0xc13d4a47,0xdd17ddc3),LL(0x3a2ef1d7,0x835e7fe3),LL(0x3a0d7223,0xdaab1fae),LL(0xeadcb841,0x2baa3375),LL(0x25d48c28,0x3675311d),LL(0x1cfce1d1,0x8cca0828),LL(0x6d648baa,0xe0c0ce1e),L_(0x00000060), + LL(0x39772678,0x4730fdee),LL(0x4814bf38,0x7da6e5cf),LL(0x717ace32,0x2440a79c),LL(0x1fa530fc,0xee76a431),LL(0xf0840ed5,0x64a9d867),LL(0x9b3e52c9,0x01e024e8),LL(0x388a3167,0xbc5a3de8),LL(0xb45ab215,0xddc3e927),L_(0x000001d6), LL(0xdb989f10,0xb0c72279),LL(0x88321c3c,0x461d5212),LL(0xe2e0c887,0x22583d6f),LL(0x0422ef3c,0x5319c021),LL(0xf26dbc88,0x3aba5f48),LL(0x62bbe876,0x7e742165),LL(0x411f00ae,0xd32aa7f6),LL(0x6608e197,0x1c414ee2),L_(0x000001fe), + LL(0xb2aed406,0x5c51d66d),LL(0xe49e1c0a,0x341d6090),LL(0xeca16754,0x50aaa76d),LL(0x3d4ae66e,0x23dd6ea7),LL(0xc264093c,0xb964aff3),LL(0x124124d1,0x6a903309),LL(0x320f2ccc,0x040a80c9),LL(0xa2fc450d,0x54b0cef1),L_(0x000001d0), LL(0x660ce624,0x876d5eb7),LL(0xb113de73,0xd6a08a24),LL(0x8fdedfa3,0x7e981617),LL(0xccca4ec9,0xbf6d63e9),LL(0x1cbf7303,0xd5b865e9),LL(0x06258e51,0x8b4e0432),LL(0xae5f01e7,0xed7485d8),LL(0x1fb3ec8e,0x5f9ac27f),L_(0x00000088), + LL(0xcd3a614c,0xaac40dbd),LL(0x933beab8,0x23a3080d),LL(0x4ca0b1cd,0x3c101e4c),LL(0x2d0376e4,0xcb246c76),LL(0x8ef2560e,0x3a96d882),LL(0x54be7604,0x792be430),LL(0x4ed7cfd6,0xe67d1eea),LL(0x924a5689,0x8c271a2c),L_(0x00000139), LL(0x63647d6b,0x9642188f),LL(0x514cab56,0xbcdfd904),LL(0x529ea4a2,0x876c6668),LL(0xcbd5305d,0xfa8c20c0),LL(0x58b69ea6,0x1ac42596),LL(0xf62b1c30,0x80232775),LL(0xee3d0824,0xc5b975d6),LL(0xc483c2ea,0x84841ab2),L_(0x000000c9), + LL(0x8bc6d688,0x6c7bd269),LL(0x7652c729,0xc96e37bd),LL(0x405791df,0x410e2904),LL(0x5ab8090e,0xf9bde0c1),LL(0x1a7b424c,0x37d8159f),LL(0x26876e27,0x6e7212ab),LL(0x5e21bc5d,0x2ff3af58),LL(0xa29dba58,0xd72ccea6),L_(0x000001a5), LL(0x7dd665a0,0xe048ab97),LL(0x19984a71,0x17b7a849),LL(0x8f61b833,0x9bdf5b57),LL(0xeb63a0f7,0x32adf9dd),LL(0x8eaf0eb1,0xe30814ac),LL(0x799c8225,0x35be0b92),LL(0xa082ff80,0x7e52495d),LL(0x196f3154,0xf5e9fa54),L_(0x00000164), + LL(0x3b3fccf2,0xf8b435c7),LL(0x7f599023,0x4b07f56c),LL(0xc6614964,0x1f9e8dd5),LL(0x7bfaa97f,0x57a41fcb),LL(0x056d5124,0x69dc4c19),LL(0x33956d10,0x2e70770f),LL(0xac607019,0x17397aa9),LL(0xbda3b4ee,0xb5df8c82),L_(0x000001c8), LL(0x11800cef,0x9f451540),LL(0x5de0b39d,0x9cd9ec18),LL(0xf09ca421,0x7bff70d3),LL(0x3fc8f958,0x6af7560e),LL(0x348716d4,0x2601495a),LL(0x4ed53bb1,0x39eaa8c2),LL(0x97052bec,0x87acae02),LL(0xb4363c7a,0xe01ba269),L_(0x00000117), + LL(0x010e4074,0x23ceb817),LL(0x68de1fa6,0xb6c3610b),LL(0x79b5037c,0x794616e3),LL(0x38ca34e7,0x6964c6c9),LL(0x64ba9eb2,0x9d828a84),LL(0x713e3f60,0xc6cafea4),LL(0x69bdca04,0x0035da7c),LL(0xc53921ac,0xe8c47770),L_(0x000001f9), LL(0xbe97815a,0x678d3502),LL(0x09bb25d5,0x417b9931),LL(0xadbec401,0xa021e930),LL(0xef1be11c,0xb53777ab),LL(0xfb3f04c1,0x2e6bc85d),LL(0xab9fbf13,0x22a4d27b),LL(0xb988012f,0xddee5ad9),LL(0xfda8aea8,0xf2fa9a7a),L_(0x000000cd), + LL(0xc43ac524,0x9805e79d),LL(0x95a2175f,0x2bee2dfe),LL(0x6125c31c,0x2b6284b0),LL(0x10319508,0x2264eba0),LL(0x8cedfa4a,0x25bc143e),LL(0x3199afa3,0xe3ae2485),LL(0x63067c6a,0xebebe969),LL(0x54a7cecd,0xb0d6a96c),L_(0x0000007d), LL(0x6de3a522,0x3a1a5044),LL(0xf721555f,0x644f2db4),LL(0x6dc38924,0xb72ad43f),LL(0x39beb126,0xe7dd7722),LL(0xd840de05,0xd6caacd0),LL(0xc67a2862,0xce6fa639),LL(0xba53021b,0x71087602),LL(0xec9b5982,0x69c6c679),L_(0x00000128), +}, +/* digit=77 base_pwr=2^385 */ +{ + LL(0xb75ed4da,0x7aaab2f5),LL(0x1ee37679,0x30159305),LL(0x0b02f44a,0x021962a3),LL(0xd622cf13,0x55a3eea1),LL(0x9a7dfa05,0x4fcd685c),LL(0x7a2a6aca,0xd2e75077),LL(0xbd4c914a,0x1e6aa905),LL(0xeec52d7b,0x4fd3f8ff),L_(0x00000173), LL(0xfa95204a,0x539f85e4),LL(0x36eeec34,0xe8ddc16e),LL(0x74599d1c,0x50244a9e),LL(0xb343c6c5,0x714c017a),LL(0xb07951ae,0x4503f92d),LL(0x44d15c8c,0x830499e5),LL(0x94680ff6,0xe7188a7b),LL(0xd6c4809f,0xdf43c147),L_(0x0000007e), + LL(0x1bf14718,0xf89fcfd4),LL(0xc079070b,0xa403ed89),LL(0xa107b324,0x18c3f861),LL(0x4dade6e3,0x665e9f9b),LL(0x332b6327,0xb408e3b3),LL(0xf62f16ec,0x11ee2181),LL(0x67bbd1bc,0xd0ba5904),LL(0x4b5440b9,0x4a8d7a0f),L_(0x00000134), LL(0x9cb1aa7a,0x8a32a33d),LL(0xedb96d1a,0x9ae722d5),LL(0x0654bd1b,0x1664c777),LL(0x03d0e5a5,0x6a4a631d),LL(0xfb01ee81,0x3d1d9344),LL(0xc7691584,0x1e1821b3),LL(0xbe2d285c,0xafc22520),LL(0xe0834d6f,0x0ccc1fe7),L_(0x000001bd), + LL(0x08d12f4d,0xf2407064),LL(0xd7255fb6,0x1c6799f2),LL(0xad7d86d9,0x8c32b1c7),LL(0x259fb289,0x172083c6),LL(0xcdc9f2eb,0xc85a5a26),LL(0xdca9f61e,0x303eee79),LL(0x82cff2b2,0x283cc245),LL(0xaea38a1c,0xd4cf3018),L_(0x0000004a), LL(0xf7fee514,0xb0b385f6),LL(0x0a48204d,0x785b0f88),LL(0xaff858dd,0xae66256a),LL(0x24f69e65,0x92f5e352),LL(0xe99c8d90,0xb2e1ccee),LL(0x40cfa4d5,0x5201f6ee),LL(0xfefbb836,0xbcabc908),LL(0x61f21689,0x688f6f44),L_(0x00000158), + LL(0xd756d8ef,0xaef07505),LL(0xdd4c26d4,0xfd1d5c09),LL(0xb43bb4e7,0x53c26645),LL(0x6a817eb2,0xf92f5487),LL(0x6209c32a,0x3e205a08),LL(0xb9b883a6,0x802502f8),LL(0xa6f9cb8d,0x2169b5a7),LL(0x87089ec1,0x07a66e8d),L_(0x000000a3), LL(0x4cc2981d,0xc0b6dcff),LL(0x39135fd7,0xe2051e1d),LL(0x0f800ca1,0x76456f99),LL(0xae12c766,0x987a86bb),LL(0xdfc5fcbf,0xcbf344cf),LL(0xa853db02,0x65a4f55e),LL(0x24b115f9,0xf4d8cf4b),LL(0x28cffa2b,0x7ef16ddb),L_(0x000000b8), + LL(0x9698f500,0x46e1cf5e),LL(0xa37c3c3b,0xb10d9d35),LL(0xb6d8d81a,0x6814e15a),LL(0x65739419,0x9282b5ea),LL(0xf890c6b6,0x80d764c7),LL(0x7d309653,0xda043f0c),LL(0xd070b1e7,0xc9e15f63),LL(0xb143ef10,0x31da4456),L_(0x0000010a), LL(0x47fd9b69,0x525c5453),LL(0xc9876e94,0xe52b9bcb),LL(0x3078ffdd,0xab8f2cfa),LL(0x7e1a8a45,0x338e4367),LL(0x3382f009,0x5b0092de),LL(0x06454df0,0xdb5d1cbb),LL(0xbbf3f2d3,0x17b40f75),LL(0xb1b7961b,0xc510c4b1),L_(0x0000018d), + LL(0x7aa9d1e5,0x71e12980),LL(0x69777935,0xdfdae6a9),LL(0x2f45dffd,0xf2900457),LL(0xabe3441f,0x6471580e),LL(0x5aece4d0,0xd983618d),LL(0x85cd6571,0xf5a1d861),LL(0xc2bd978c,0x955894c4),LL(0x81cae98a,0x762f897f),L_(0x00000078), LL(0x3176598c,0x4b7790dd),LL(0xc91def7d,0xb21152ba),LL(0x279d992a,0xd92aafdd),LL(0x7dab9fb5,0x59dd70d0),LL(0x7039956b,0x14d13b0f),LL(0x7cfe20de,0x7bd5d4c8),LL(0x45b10bc2,0x59724543),LL(0x906a5d0d,0xda689ccd),L_(0x00000096), + LL(0x80b9235f,0x380affbc),LL(0x0b4024a8,0xcd02b098),LL(0xc98a3c0b,0x36545f0a),LL(0xe62cf7ea,0x3b089c99),LL(0xdade8fc7,0xf9b4c955),LL(0xf404f355,0x7650e822),LL(0xae64ac11,0xcc0fb628),LL(0x593a1b6a,0x278ddfdf),L_(0x00000041), LL(0xa51f1936,0x091d5493),LL(0xeabe8135,0x5285ec41),LL(0x6bc185fe,0x9a7df8de),LL(0x25f54dac,0xc1b5836c),LL(0x4e5fc638,0xde102ff5),LL(0x81a60442,0x56a67f9d),LL(0xaeaff6ca,0x7cc5f40e),LL(0xdaecfbdc,0x63449fd0),L_(0x00000084), + LL(0xcd4c9f1b,0x64ba5d43),LL(0x262898c5,0xb6d345ac),LL(0x0f11b91d,0xf8015622),LL(0xfa53c395,0xeb32e3dc),LL(0x4e8f0647,0x125c49a2),LL(0x537471de,0x5c783701),LL(0x7a9741e3,0x00bc6a87),LL(0x1c5d3aa6,0x77962a3e),L_(0x00000003), LL(0x18eae31d,0x1336f732),LL(0x7555dff2,0x63097ec4),LL(0x8f16a8d5,0x928e41ac),LL(0xc063790a,0x72cf7210),LL(0x2842e2a8,0xbed4668e),LL(0xe7f0d214,0x7b5aab91),LL(0xbd94783e,0x472089cb),LL(0x55df6f3c,0x7e5f6d77),L_(0x000000b9), + LL(0x6ba36bea,0xd6462023),LL(0x51b0110e,0x0299f400),LL(0x5ad94e5d,0x1c56f2f6),LL(0xd8d6e619,0x0b4ea27d),LL(0xe73e18fa,0xdcfdac26),LL(0x61a026ce,0x27dab320),LL(0x4ebfdadb,0xb6af0729),LL(0xe9561c2a,0x2c10a6e9),L_(0x000000bf), LL(0x1418a240,0x7a5020b9),LL(0x2b5125f4,0x7dac2ce9),LL(0x6985bdc7,0x7a36a07a),LL(0x6d385362,0xc0a58550),LL(0x940163b2,0xd28cbf38),LL(0xfb9a9d22,0x8eddbcd2),LL(0x1cfcdeb4,0xad40ff84),LL(0x41da1441,0x0dfc69a8),L_(0x0000018f), + LL(0xf1ab6a88,0x32d8d898),LL(0xb4c956c4,0xbd9881d2),LL(0xbc516c73,0x5116a36c),LL(0x91e840e1,0xff4abf28),LL(0x14bf8bab,0x2bc617a5),LL(0xb012c75f,0xba5d811c),LL(0xf333effb,0x37bcddc4),LL(0x771a4567,0x0f294bff),L_(0x000001ea), LL(0xa48d6dfa,0xf2542b71),LL(0x495f434b,0xe3f39bde),LL(0x9f969883,0x179f2c63),LL(0xa68cdccf,0x44e28315),LL(0x7408c1bf,0xeb7b9849),LL(0xf6615345,0x823ede15),LL(0xdf405d5f,0x17f01e94),LL(0x0efd64e2,0xd1d65356),L_(0x00000094), + LL(0x6794bc7e,0xfa3914f9),LL(0x044623b2,0x3e94e3f2),LL(0xc7e42b96,0x85cc2a9d),LL(0xe0fbde7f,0x2e0e1f42),LL(0xde5ec740,0x0a1b4e4e),LL(0x99d96c6e,0xa3d7e876),LL(0x9b31d8b9,0xcce96a38),LL(0x4fd9fc85,0xaa4475dc),L_(0x0000016f), LL(0x5b7a322f,0x4317247b),LL(0x01f0266b,0xfd3d2a1d),LL(0xa9fbb760,0x75fc993e),LL(0x60905a87,0x51ce6740),LL(0x3c6c984d,0x16580d6e),LL(0xe79ccbef,0x585522ad),LL(0x57fa547e,0x42f80ccf),LL(0x8ad71acb,0x04c2d188),L_(0x0000000b), + LL(0xb16ee0ab,0x28366fe7),LL(0x0365fed1,0xc78aeb84),LL(0xf329889f,0xee74063c),LL(0x16267a5a,0x9c5a9197),LL(0x040a619f,0xc54b40cc),LL(0x16e7345f,0x9d5f609d),LL(0x957fc0b1,0xaf8fbbc8),LL(0xb1cb4d02,0xae0bc117),L_(0x0000016d), LL(0xd023f32f,0x1deda80b),LL(0xacb49a95,0x4c11c95e),LL(0x00e1f672,0xde8db891),LL(0x19ee52cc,0x27a5b5d8),LL(0x6176a0d3,0xd6752e2d),LL(0xdfccd883,0xe819161e),LL(0xe1282202,0xe71376c0),LL(0xb92fddf6,0x36e67047),L_(0x00000013), + LL(0xfecc3203,0x7168d714),LL(0x1726e41f,0xea5d7e70),LL(0x69dd518d,0xe7aec797),LL(0x2cfd3a6e,0x9ab3823a),LL(0xb90a5bea,0x43831c4a),LL(0xdbb35cc6,0xd5853b0b),LL(0x95c10ae1,0x55834ab5),LL(0xd668a3cb,0x91daa6d5),L_(0x000001e9), LL(0xc0f7662f,0x98346aa6),LL(0x173a0008,0xabe91f50),LL(0x0508c118,0x97cdd826),LL(0x7255d2e1,0x01d1e340),LL(0xeb07ccd4,0xf2f7ac53),LL(0xc6829327,0x966981ba),LL(0x0fb3f4fa,0x1ee6ae0f),LL(0xea212110,0x67b02691),L_(0x00000154), + LL(0x3c713d51,0x946494a7),LL(0x1e6130d8,0xbd5ab69c),LL(0x6cbf341e,0xcf57622a),LL(0x94d1578b,0xc7327897),LL(0xb1db7d17,0x2874559e),LL(0xf5607998,0xd15eab48),LL(0x18199bc9,0xfe1d9b44),LL(0xd0aedc11,0x95354256),L_(0x00000169), LL(0x50c646ed,0xb75609c0),LL(0x9721b326,0x4a7a787a),LL(0xed16025f,0xbf8835a3),LL(0x78dc9b8f,0xee0c8b9a),LL(0xf388850b,0x5a1458a1),LL(0xc5cee39e,0xb7bfeb06),LL(0xecfd0e49,0x8795b039),LL(0x70bdfc80,0x3f5f6711),L_(0x00000126), + LL(0xa3c85c78,0xbd49ba23),LL(0xe512fde9,0xdb860d3f),LL(0xbf99d4e9,0x3cb574a7),LL(0xbc4c4fcb,0x9af33dfa),LL(0x88710836,0xfd7ca4de),LL(0x4b83fe29,0xa2306095),LL(0x03d40abe,0x5f9ae75f),LL(0x5e83ab1a,0xe6d9a07e),L_(0x00000154), LL(0x97d0048f,0xf861736c),LL(0xde0ffdb3,0x5e0c4806),LL(0x335dce14,0x76e125cd),LL(0xcc1ff27f,0x16822cb3),LL(0x8414749b,0x44ae46e0),LL(0x68085d31,0xe89d0a2c),LL(0x9c734630,0x569b26c1),LL(0x2d89e8f0,0xc04e824b),L_(0x000000c9), + LL(0x1dc45be8,0xf3a736f8),LL(0xb7b948b5,0xf684853d),LL(0xa1d8a120,0x7de7af37),LL(0xe3760299,0xadb401c1),LL(0xa1ba866c,0x24e3e6ca),LL(0xcd94496a,0xc3eae9d6),LL(0x06f82a82,0x4a74e14e),LL(0x069d9983,0xb9dff343),L_(0x00000018), LL(0x2a60baf5,0x3855bae4),LL(0xfbb6aadc,0x20017824),LL(0x950ab7cd,0x9dfd2439),LL(0x96b97104,0x65cd1e13),LL(0x4925d16b,0xf2ec4dd1),LL(0xd82c0815,0x9059e2e1),LL(0x3ba03a79,0x2f723163),LL(0xf35a3c60,0xc7cb8c17),L_(0x0000004b), +}, +/* digit=78 base_pwr=2^390 */ +{ + LL(0x05eac10d,0x1d0d93fa),LL(0x3fb80a45,0x30dbe366),LL(0x69a67246,0x1373df55),LL(0x3a7b7740,0x3b688d58),LL(0x9a1bf576,0x6f4ce0d1),LL(0xc2030797,0x72348a80),LL(0xd874e749,0x24296b9d),LL(0x26fc8724,0xdf80dad7),L_(0x00000154), LL(0xa4626a33,0x0b206a34),LL(0x661fc19c,0x597e1cfe),LL(0x1f98c11b,0x010915e6),LL(0x00c41adb,0xbdcb2d64),LL(0xfed21859,0x07de82c2),LL(0xeffa2475,0xba1295da),LL(0x73a4f297,0x570842d6),LL(0x1fc083b4,0x94c92172),L_(0x00000159), + LL(0x05474c79,0xf27eccc5),LL(0x9bbd81b9,0x4061bf3c),LL(0x1385eed6,0xe5477666),LL(0x2d5cbcfe,0xa0f415ca),LL(0xab0a8618,0x18675f88),LL(0x47e7c454,0x0d5df7ae),LL(0x75324e3e,0xe2f88082),LL(0xe818ccf0,0x9cc4c5bf),L_(0x0000007e), LL(0xc2d8f452,0xef224de6),LL(0x9ce12031,0x70dcb7f7),LL(0xd958660b,0xc4597b18),LL(0x4dfd1c89,0xda0fa522),LL(0x2d69ce10,0x989afa82),LL(0x46e81b65,0x4e1b3fa1),LL(0xdcac5039,0x832ae217),LL(0x7d3eef41,0x7f7b4632),L_(0x00000159), + LL(0x5daa1b89,0x542982e7),LL(0x98f2622c,0x5b7e32c5),LL(0xa09068bf,0x6931e543),LL(0xeb5500e2,0x9089e794),LL(0x2a396afe,0xe5f72142),LL(0x68403342,0xf625b926),LL(0x14e9fc8c,0x6171d647),LL(0xe3e5f19c,0x41a98a6f),L_(0x0000012b), LL(0x9dfea1fb,0xaf413d88),LL(0x0a1d61f5,0xb4928484),LL(0xc08e23bd,0xe1c147cc),LL(0x3ba7bae4,0x0b6e0358),LL(0x7c12896b,0xa84a4aed),LL(0x0195f08d,0x7bcd8649),LL(0xeba99c7c,0x799d1ac2),LL(0x0193b278,0xa35f128c),L_(0x00000072), + LL(0x91f424e1,0xb2d18470),LL(0x482b31fa,0xc18abe11),LL(0x4548d244,0xc9e02a20),LL(0x901117bf,0xb1dc1cd2),LL(0x286c34a4,0x8ee98a6d),LL(0x04c325a4,0xb76b3ae6),LL(0xdb518aec,0x981c8298),LL(0xb7194b24,0x8c90f08f),L_(0x000001b3), LL(0xfd055d97,0xc7061a3b),LL(0x8a107a2c,0x5a667bf8),LL(0xaf0a63ac,0x21028dc3),LL(0x3e8641fb,0xa80d9487),LL(0xd40a558d,0x63f8d8c7),LL(0x3accfc09,0xccc46547),LL(0xfbd53079,0xe85ce362),LL(0x15006f15,0xb994381d),L_(0x000000d4), + LL(0x913326ba,0xe7e20db3),LL(0xe0e58c40,0x4dd3a381),LL(0x4f08867b,0x8c0db229),LL(0x1f57cf8e,0x862604e5),LL(0x9951f866,0x588c2473),LL(0xdd04385b,0x2a4f4278),LL(0x13235969,0x334e1277),LL(0xe14a7afb,0x0a02da7c),L_(0x00000164), LL(0xce866486,0x4c0e101a),LL(0xfa8ba6d4,0x8dee1016),LL(0x1cd14dc2,0x5e8be2aa),LL(0xcc56a3c9,0x5bdaa677),LL(0x26fe9020,0x787cbbf4),LL(0x6059a9eb,0xf27c2ccd),LL(0x52b29d1e,0x431ad6f9),LL(0xe9273bbd,0x47f193d1),L_(0x0000006c), + LL(0x531296c8,0xa4ea86fa),LL(0xe8dd3548,0x107a45cd),LL(0xd8b7e446,0x1bfd985a),LL(0x280a4e8e,0x4fc2dc66),LL(0x4b39f03c,0x86dfa832),LL(0xc44021ef,0x55d3ccb1),LL(0x210fe263,0x65b0f1db),LL(0x68364a82,0x4fc0acb2),L_(0x00000132), LL(0x2aec7e7e,0x7906edd3),LL(0x941505c5,0x5f4fddad),LL(0x657d2929,0x320073ac),LL(0xefaffd81,0x7ab9edd6),LL(0xeb40eb69,0x23d38d94),LL(0xc8df60f9,0x1840540c),LL(0xbfea59c1,0x3958b571),LL(0x2f7620df,0xcd1712e7),L_(0x000000d6), + LL(0xa8d54597,0x3ace77d1),LL(0x23823b9e,0xb05ab9ad),LL(0x7d6803d7,0x36f8db67),LL(0x8ed91e87,0x8fbc69ec),LL(0xe0042a07,0x6a246110),LL(0x5131b89e,0xf857a2db),LL(0x4c1861d6,0x311746a3),LL(0x84c00e5b,0xa2b64ab3),L_(0x0000008e), LL(0x95ff285c,0xdd895ec5),LL(0x9a709b4c,0xadcb32cb),LL(0x148a78f6,0x7c40e4b0),LL(0xf62708ee,0xd37d48a3),LL(0x68232a30,0x382492cc),LL(0x79b622f3,0x92d657a0),LL(0x09992500,0x6a420a8f),LL(0x501d8de9,0x759f5a62),L_(0x00000051), + LL(0xc122141c,0x66149a76),LL(0xc602d382,0xfdcc4f6e),LL(0x16b23844,0xea0673e3),LL(0x7ff0591c,0x53082d2f),LL(0x82264497,0xafeaf6b5),LL(0xca528c9c,0x01a84f6b),LL(0xe2403638,0x43738672),LL(0x54c4174c,0x50ff80fb),L_(0x00000186), LL(0x4205f340,0x0b6de62a),LL(0xa84853c5,0xc67ea2a5),LL(0x92e0d583,0x296584f2),LL(0x6bb7a441,0xa9f0cd97),LL(0xce6eb31f,0xd0d33dfa),LL(0x850b5886,0xca9b5dbb),LL(0xe75a3fb5,0x143bbd95),LL(0xfc35ee42,0x1eab0aa9),L_(0x00000157), + LL(0xfe747fdd,0x0c47e2c5),LL(0xf9ae16bd,0xa07b48d2),LL(0x01c347f0,0x2cf4c727),LL(0x747fa6ef,0x850ead03),LL(0xff312b98,0x8726545d),LL(0x5218270e,0xa6f367cc),LL(0x7680a110,0x37efad3c),LL(0xe34b12a3,0x693b75a8),L_(0x00000069), LL(0xe1fe8e14,0x5767922c),LL(0xe0242975,0x20a012f1),LL(0xba21fc56,0x49ff848f),LL(0xbd4ab80a,0xde1b4b0f),LL(0x24104f37,0x314917b2),LL(0x221548c9,0xde9c2909),LL(0x6f74cf12,0x75ca1868),LL(0x44d62839,0x6d64b7c2),L_(0x000000bb), + LL(0x3109d76a,0x044307f0),LL(0x7372da8e,0x9ba083bb),LL(0xd35f32f6,0xd25b7e53),LL(0x0a6c99ed,0x30794ede),LL(0x1523c414,0xed97a2a7),LL(0x7dbb6798,0x6d897d7a),LL(0xb996ba83,0x3c0356d5),LL(0xad5ef539,0x3f933449),L_(0x000000e3), LL(0x37a40ab6,0xfbb2d425),LL(0x468766c5,0xd03d4766),LL(0xe6a77a37,0x09eb18e1),LL(0x9d7f1644,0xbdb7ff41),LL(0xeeb2f1b2,0xc98d5a19),LL(0x8377c08e,0xda52ef67),LL(0x1078c0d1,0xbd2d3d66),LL(0x9181c3b8,0x0015c0fd),L_(0x000001f0), + LL(0x4f7f8d77,0x663aa882),LL(0x9e806c61,0xcd6d9ab0),LL(0x434a485b,0x575aafa5),LL(0x0477ae83,0x1fb377fe),LL(0x7b98c782,0x4ac83912),LL(0xe2f16d17,0xd098d31f),LL(0xeaff3b56,0xfba7077f),LL(0x13382e53,0x8ba7a6cb),L_(0x00000048), LL(0x4aad91ac,0xce1a9e84),LL(0xc8fc10e4,0xb01bef42),LL(0x6afd2473,0xb1a03e1c),LL(0x507c30ff,0x3760275a),LL(0x162b2e12,0xabb38d7f),LL(0x558877e8,0x88916de2),LL(0x9f519917,0x2fdccf2d),LL(0xf70b4695,0x1d641420),L_(0x00000025), + LL(0x4848296d,0xe0f71789),LL(0xf3835d1a,0x9fea01e8),LL(0xaf761a04,0xc7d32c83),LL(0x1060dc76,0x6c5ff4c8),LL(0xc3751915,0xec6a8a45),LL(0x6f1dbd4a,0xdf6166cd),LL(0xa64bcecc,0xa942edd4),LL(0x53c4d352,0x8df04873),L_(0x000001f2), LL(0x957c5d10,0xe757c12a),LL(0x60819db9,0x5aae5302),LL(0xfbc64c70,0x72a99d6e),LL(0xb00bbd49,0x3bf68d69),LL(0xf0b755c1,0x125fdc71),LL(0x4502c9bf,0xe7e83089),LL(0x7e20c9f2,0xaefe0993),LL(0x5fa7bc0d,0x58ce802b),L_(0x0000001f), + LL(0x596ae14c,0xc255b673),LL(0x1bb0ac11,0x19c21f40),LL(0x04f2091c,0x1838e69c),LL(0x3e9cb56d,0x51439522),LL(0xc1cecfc9,0x52a9b2f6),LL(0xc564467e,0x3576c345),LL(0xeb0fdcd3,0xd04ad0d7),LL(0x3c3aa2c6,0x1cfc7def),L_(0x00000038), LL(0x54b2e727,0x044d2e1b),LL(0x8701d001,0x794b02f7),LL(0xd8153787,0x4f463b8e),LL(0xa0dfa5ea,0x253e324d),LL(0x8fc87618,0x19c78239),LL(0x6165c650,0x97b77e54),LL(0x134c2cb2,0x5e23fc18),LL(0x5ade1fce,0x10c19f2a),L_(0x00000174), + LL(0xaad903e8,0xb407a7f0),LL(0xa64c2d6e,0xc577e3d9),LL(0xd68527c3,0x398177a5),LL(0xdf38bff9,0xde6b9d9e),LL(0x746c3309,0x1d7385a5),LL(0x98512661,0x3b8d9701),LL(0xe82c0d22,0xe2b7edd9),LL(0x16ce165c,0x92301ae2),L_(0x0000002f), LL(0x491b562d,0xd2049870),LL(0x1de2def6,0xcf01bb60),LL(0xaff2152d,0x20717620),LL(0x5764198c,0x503a4861),LL(0x9702cec2,0xce53ec1b),LL(0x886169de,0xe97c752c),LL(0x8d58887b,0xeb1ce735),LL(0xe1b8ee6d,0x01ad85ca),L_(0x00000093), + LL(0x6213a0d1,0x1d410b7b),LL(0xba1aa221,0xa8aa0a76),LL(0xbd669af8,0x06a3140b),LL(0x196f88e0,0xdc333cc8),LL(0x1c9aa099,0x60557f79),LL(0xe1ff46ae,0xa7b7da68),LL(0xd7626d62,0x2a5a72d1),LL(0xffb47531,0x86e04ed1),L_(0x00000058), LL(0x72d98927,0x8e521d9d),LL(0x6acd3ed1,0x855c8e97),LL(0x47c48377,0x42413164),LL(0x89182c42,0xae6a473b),LL(0x59d11d10,0x730eb702),LL(0xd4abd611,0x71fd7c4f),LL(0x4d329537,0xe8493373),LL(0x5e745909,0x0caebd43),L_(0x00000034), + LL(0x4c6f3e4a,0x688f6e0a),LL(0x2a9b6d1a,0x9e0c6a62),LL(0xfebdd4b3,0x7fb92759),LL(0xe14d66ca,0x3d698e7d),LL(0x0a2edb8e,0x08ea4d11),LL(0x10b21ab8,0x0f855706),LL(0xf8405b08,0x104c29e8),LL(0xadf7ff63,0xca76d27d),L_(0x00000076), LL(0x4757c2f5,0xe671ed88),LL(0xb38018e2,0xd5288875),LL(0x629331d9,0x279d96a8),LL(0x7e602196,0x559eca5a),LL(0x81f2dc09,0xf274c146),LL(0x96818fe5,0x483d0424),LL(0x1c8246f6,0x76f5286b),LL(0x44ba1052,0xe83b7779),L_(0x0000005e), +}, +/* digit=79 base_pwr=2^395 */ +{ + LL(0x42d44166,0x0a8f4b54),LL(0x924764d2,0xf7bf31e5),LL(0x26e4af60,0x7be28350),LL(0x9fc53bdf,0x08056835),LL(0xa12726ea,0x726e147e),LL(0xd5e175b1,0xca2a0207),LL(0x833e5911,0x4d322cae),LL(0x6cba51a1,0xfd137e93),L_(0x0000001e), LL(0xdaa1d653,0xe0948dd2),LL(0xca2b565c,0x2f88e2ac),LL(0x94ccb3a4,0x85d91e6c),LL(0xd8fe4775,0xb59cebc7),LL(0x0807f46d,0xf4237821),LL(0xfc9eb940,0x402ecff0),LL(0xd173f94e,0xbf7bc598),LL(0xaf975145,0xf726ff16),L_(0x0000009c), + LL(0x15942a4c,0x3dad29e1),LL(0x350dec67,0xe6be55a2),LL(0xca3c399f,0x71245659),LL(0x87e22652,0x8f51c63c),LL(0x1bd4c445,0x758ae1a1),LL(0x319b57db,0x547db810),LL(0x7d5c89dc,0x62c8ba84),LL(0x959a5bbe,0xd3fcf239),L_(0x000000eb), LL(0x8c3d490f,0x482b690e),LL(0x50d48521,0x83aada08),LL(0x82c13331,0x45c4a535),LL(0xae5a3425,0x31c1467b),LL(0x51c50d6f,0x2d093b81),LL(0x84a7d97c,0x82d6fbdb),LL(0xdb41ffbe,0x4953468e),LL(0xae0e9fad,0xede049e6),L_(0x00000070), + LL(0xc26f9e1d,0xb8562be5),LL(0x71fd7b5e,0x039f5b0d),LL(0xe3196121,0x073e4db0),LL(0x902cc367,0x22f8b999),LL(0x604d9b78,0xc1cfc4a4),LL(0x52f26ece,0x88d45487),LL(0xa175f394,0x9f16c268),LL(0x9fe9a65c,0xe88e2aea),L_(0x000001a9), LL(0x54ed1ed1,0x4d516f86),LL(0xb3a46011,0xa9ca3304),LL(0x8c5e216d,0x2030c9a9),LL(0x86a5904f,0xc0c4c573),LL(0x9467bf24,0xb4a6fdae),LL(0xa652162c,0xd3472536),LL(0xb6166589,0x31361b4b),LL(0xfa3bddac,0xd5b8b3b7),L_(0x0000007a), + LL(0xaa60773f,0xe8255739),LL(0x58459ee1,0x672547b1),LL(0x3f4e65fb,0x0030639d),LL(0x5059b89e,0xc29a4f63),LL(0x3ffb7b9a,0x267e1823),LL(0x6854cad3,0x7f7d6bbb),LL(0x79c3b99a,0x20d91b6e),LL(0xbec22c47,0x4474e65e),L_(0x000000d8), LL(0xd72fbb0f,0x307d9b73),LL(0x7f8c46dc,0xc6fa2f52),LL(0xfbf3d06f,0xd62e537c),LL(0xd7888122,0x4ebd3818),LL(0x11ea61a8,0x479a6f83),LL(0xeafa5532,0xa4bf3325),LL(0xc7a31554,0x5a717809),LL(0x9520a809,0xd00e3039),L_(0x000000d7), + LL(0x4f775892,0xb974b129),LL(0x5ce12c3e,0xe8064395),LL(0x2e69ed62,0x31e3ae39),LL(0x9c220c3b,0xd59ea4b1),LL(0xb79732ea,0x6f45918a),LL(0x6600e529,0x08681af2),LL(0x4ed3f5dd,0x507438a2),LL(0xac5ccefd,0x0ca9586e),L_(0x00000064), LL(0x5b14db7c,0x2484d059),LL(0x411826aa,0x6005d933),LL(0xca8c9d7f,0x15dd0c44),LL(0x1900212d,0x96825f72),LL(0xa3ea7e14,0x921c8c87),LL(0x20d2b6f4,0xfdd63f04),LL(0xbe8c25ac,0x9f6a6126),LL(0xa2592316,0xf8413f28),L_(0x000001e7), + LL(0x27b80789,0x4f60fc89),LL(0xc97bbd7e,0xbd2ecac1),LL(0x5b008578,0xaaf75b36),LL(0x3b54d53e,0x6540b6f5),LL(0xce5a0ab8,0xac54c1d9),LL(0x52d909c6,0x67e6b65d),LL(0x6607ea02,0x7ea06112),LL(0x0a94e0f9,0x55cce11c),L_(0x0000011e), LL(0x7fdd52c7,0x49bb24e9),LL(0xfc9b8e68,0xe60101c7),LL(0xdcbe3ce9,0xc2ae52f0),LL(0x3c779930,0x85f01602),LL(0xa50df581,0x4a7c2cfe),LL(0x8c89a686,0x52f720dc),LL(0xe2d3b3fd,0x566aecf1),LL(0x1ac6cabd,0xf58c8fe5),L_(0x0000000e), + LL(0x1a616c59,0x8c145c49),LL(0x1dbffc3d,0x2990c86d),LL(0x842bad94,0x7914907c),LL(0xb0b65826,0x8753b549),LL(0x09f19586,0x29d809d0),LL(0x3f813f8e,0x3e155797),LL(0x293bf471,0x87d08f2b),LL(0xc41c49e5,0x03a8d0a9),L_(0x0000013c), LL(0xd9473ed1,0x7fc8f692),LL(0x7012e2ef,0x5014f2ae),LL(0xe7047394,0x086b300a),LL(0xb63d8e90,0xe77f5c2e),LL(0xf739fb33,0x700eca1b),LL(0x22cfcea2,0x8bf8652d),LL(0x4bb3d357,0xe61f7839),LL(0xba0c3888,0xd370df89),L_(0x0000010e), + LL(0xe42f4734,0xbb740324),LL(0x9909bcd8,0xe45bfed8),LL(0xe9550616,0x77889a7f),LL(0x861f9828,0x446a53b7),LL(0xc8946a71,0xfbe6cdbf),LL(0x72916502,0x70373dcf),LL(0x59c8ba5f,0x1ab59a0e),LL(0x07606ee3,0x82f754ed),L_(0x0000003e), LL(0xfa3f237a,0xb5ddd50e),LL(0x0f211f61,0x56f3a63a),LL(0x8319e664,0x3124dae6),LL(0xe5acc6a3,0xf2c7d090),LL(0x5d6c5fe3,0x5cc8df62),LL(0xa0165f43,0x20f4229f),LL(0x5adf8ff4,0x2e9c92c9),LL(0xd951affc,0xefce2c03),L_(0x000000f9), + LL(0x85b95034,0xdf5cb44e),LL(0xffda53ce,0x976139f3),LL(0x126f8dfa,0xe003499a),LL(0x25a0d493,0xb521d994),LL(0x43bb5822,0x4978624a),LL(0x1b4bdd9b,0xf19f8465),LL(0xb8e6e89b,0x51953414),LL(0x3b559f26,0x86ef1c70),L_(0x00000051), LL(0x67904448,0x23ee72a6),LL(0x7f3ba24c,0xefa5df96),LL(0x4a910e6e,0x2d36ae87),LL(0xbee250f2,0xa3310ea5),LL(0xbebd708e,0x5db14894),LL(0x94f849b9,0x7b2cb1b7),LL(0x830487c0,0xd8532e27),LL(0x72d6bdee,0x37fccdcc),L_(0x00000160), + LL(0x098e856f,0xcfb4864e),LL(0x2a48dc38,0xa9b6c8ef),LL(0x070c9954,0xc3e565ee),LL(0x47d25c31,0xeec5d7b2),LL(0xdd383653,0x5ac0ce45),LL(0x1f5f3381,0xd40035f3),LL(0x486c7281,0xb516fd77),LL(0x5bbe546e,0xc646e214),L_(0x00000034), LL(0x0df8a00f,0x3f432f2f),LL(0x740ff679,0xa22b5ed0),LL(0xff907935,0x3d446e71),LL(0xd013a668,0xeeee1f6e),LL(0x16c4dc5f,0x37116783),LL(0x8ed6e49d,0x07fabe84),LL(0xd710493c,0x29dbccd8),LL(0x9263e99e,0x6beb1393),L_(0x0000012a), + LL(0x906df6cd,0x835e52c6),LL(0x8a2f7445,0x66d4156a),LL(0xb891e801,0xaa5c0324),LL(0x852e9f5b,0xd3f81a7a),LL(0xce23b51a,0xcdc49377),LL(0xe9c8bbe9,0x7da33db2),LL(0xd5ae561f,0x90aafd3d),LL(0x2f82d67e,0xf365be46),L_(0x0000003e), LL(0xd53059fe,0x43cd9246),LL(0xca05f22d,0x0c50a7ad),LL(0x23745904,0x612405ce),LL(0x1e2b644e,0x1783439c),LL(0xbb5598f4,0x8299ab36),LL(0xfdba24f0,0x36c6a428),LL(0x085bc781,0x42e84aa9),LL(0xe954acbf,0xeabc6123),L_(0x0000001a), + LL(0xeb9123d0,0x9813e058),LL(0x170c410c,0xb14ecd8d),LL(0x43a445ef,0x12caafb5),LL(0xb13251ba,0x692c7666),LL(0x6a58ee44,0x93734f73),LL(0x1ecf9f41,0x0ff39b6d),LL(0x582e2c3a,0xdd49d16c),LL(0xbc874e11,0x95e54a54),L_(0x0000016f), LL(0x9986c142,0xbe161bed),LL(0xadb85be6,0x94c11992),LL(0x974392b1,0x4727d02a),LL(0x1355dd0b,0x9ef84fdc),LL(0x001779ff,0xdbbcd1c3),LL(0x09218dc1,0x615360f7),LL(0xce2bff57,0xa1cd90ce),LL(0x5b2b4772,0x3bd7ca08),L_(0x0000005e), + LL(0x797035ff,0x63db3368),LL(0x2ea4d5db,0xd58aac93),LL(0x5c1f4e24,0xf46d30bc),LL(0x87b8b188,0xfe246192),LL(0x177c783a,0x2b7ec253),LL(0x7157d89d,0x93dd18f3),LL(0x609635a4,0xebb06e2d),LL(0x9bb84085,0x23701182),L_(0x00000077), LL(0x5291bba2,0x68aae159),LL(0xd5d8d4a8,0xc3c56f74),LL(0x8f01b0f8,0xd20ce087),LL(0x0018bf4f,0xcf62fd4a),LL(0x58c66e12,0xe583beb9),LL(0xcba992f3,0x7c22cd07),LL(0x82ea861b,0xffb459bf),LL(0x757b22f8,0xef69f10c),L_(0x000000f2), + LL(0xf9bac8ff,0xbeb1c7a5),LL(0x70f6e41f,0x32bb744d),LL(0x1f50a7aa,0x2a66377a),LL(0x611c61b4,0x324a6008),LL(0x1ce936f3,0xc3dc201c),LL(0xc5bca084,0xb70db700),LL(0x47988c82,0xfef0caf3),LL(0x2dfe3675,0x6397725e),L_(0x00000193), LL(0x76fee427,0x165d8d1c),LL(0x937f269a,0xdc1fbe1e),LL(0xdfee35cc,0x745db180),LL(0x5475d4c9,0xefc6cdb5),LL(0xb36d0a2f,0x26ccd4e8),LL(0xf7ab4767,0x3783e580),LL(0x31ff3c1f,0xce5d079b),LL(0xed18ab19,0xf284909c),L_(0x000001d3), + LL(0x231ac4a1,0x0790eab4),LL(0xec50bbe6,0xde5da610),LL(0xc5c0bffc,0xc2382715),LL(0xd201e1fa,0xaac50e22),LL(0x27c0dbe5,0xd06ae9b5),LL(0x8715ddc4,0x77f1683f),LL(0x592ddcce,0x410624c0),LL(0xffb7a12c,0x170b0367),L_(0x0000001c), LL(0xf76139b5,0xf8b9348f),LL(0x29844cbe,0x30deae53),LL(0x941fdd94,0x5f88797a),LL(0xa3612765,0xbbb4a54a),LL(0x8e2ccc8e,0x4a469e09),LL(0x47a174f2,0xe17602e5),LL(0xc6f2b50b,0x5edc6700),LL(0x887e7ea0,0x8c90c4bb),L_(0x000000e7), + LL(0x350806a0,0x8c8ad937),LL(0xbc207b36,0x45322006),LL(0xf3feb2a7,0x29b356ce),LL(0x9772041b,0x4db4360d),LL(0x71532653,0xffd40033),LL(0x62b4c3a4,0x525bb0cb),LL(0xef8cba94,0xb23dfc1a),LL(0x5f95e7e7,0x4230723c),L_(0x000001ff), LL(0x3a9f0d5f,0x05623688),LL(0xe7ca479f,0xe0f2e02f),LL(0x821e669e,0xd9320a75),LL(0x3208dc12,0x2a90f1fc),LL(0xac95bd4d,0xb836d5d0),LL(0x0f15127a,0xa56f1f5b),LL(0x35a8c806,0x4b53533b),LL(0xb5d6ee48,0xfcf4ee1d),L_(0x00000155), +}, +/* digit=80 base_pwr=2^400 */ +{ + LL(0xb1b291af,0x63480c29),LL(0x6afae0d2,0xec906027),LL(0xd90afac7,0x067489d0),LL(0x62d3da37,0xe31b78ec),LL(0xd88f38b3,0xff5fafe7),LL(0x3dfa7f35,0x88536101),LL(0x7a6237d7,0x80270f89),LL(0x42a2eac9,0x39890c2a),L_(0x00000064), LL(0x95b6527c,0x38b21960),LL(0xab3e28c0,0x56c8573a),LL(0x49dbf002,0xb06c2993),LL(0x016fc238,0xc550c59c),LL(0x7c26c63d,0x22cb4395),LL(0xd6c87128,0x4a5765b7),LL(0x42f34ea4,0x360be87f),LL(0x9436ed50,0x331a061a),L_(0x000000d2), + LL(0xcf6c0f3c,0x23b6d0c7),LL(0x01323c15,0xb2a524b7),LL(0x445c4f05,0xfb280e1d),LL(0xb721bd24,0x43a450cf),LL(0x34d74f50,0x459a3690),LL(0x9ed3c3ca,0xf8a99776),LL(0x9bd35cd1,0xaf456934),LL(0xa1b94559,0x00820fa7),L_(0x00000124), LL(0xc7479e9f,0x93e5dd5a),LL(0xfdaf1391,0xfcfc382f),LL(0x727251e2,0x4776e937),LL(0x9f976e0e,0xfaf93681),LL(0x7e0dea37,0x18ec38c9),LL(0x45662b32,0x0308bb26),LL(0xd581e3f2,0x1a441534),LL(0xc275dc07,0xa1b0d046),L_(0x000001b4), + LL(0x9bcb5968,0x702c5bb8),LL(0xdfb47a52,0x33f897ad),LL(0xe16c51a7,0x078f030c),LL(0x5e8bc092,0xb9a4c194),LL(0xa0a224a9,0x0d2a2dbe),LL(0x244c74fb,0x00b01506),LL(0xef3b3eda,0xf4403180),LL(0x44f09c72,0x1da590d5),L_(0x000001c4), LL(0x4a7f0289,0x3c0211ff),LL(0x88323d80,0x1ffe93b1),LL(0x81a127a4,0x7deb5031),LL(0x0bd65111,0x65ffd296),LL(0xff238b15,0x80cef133),LL(0x643d7062,0xddb33d18),LL(0x93ccc6e4,0xc957a463),LL(0x1fcc4678,0xc36fd11d),L_(0x00000184), + LL(0x1ccb1806,0xe0e23232),LL(0x5eae4904,0xc2c362eb),LL(0xda675b34,0x2c14f20a),LL(0x13d2fa91,0x60f4ae95),LL(0x6c8c7ff9,0x78df2064),LL(0x6790ea32,0xb702cc14),LL(0x7608da34,0xe2b87bb5),LL(0xadae0fb9,0x6d939f1f),L_(0x000000fd), LL(0xa26a843b,0xc89f77d5),LL(0x5a368ffa,0x265d14c3),LL(0x957c89a9,0xbd1486e7),LL(0x514b7e05,0xa9030ef9),LL(0x537cf3d5,0xb9ea3998),LL(0x4fb32008,0x0c45cfba),LL(0x61ff9565,0x078d5a15),LL(0x1cc6a564,0x4f509bc0),L_(0x00000019), + LL(0x665bb52e,0xf7ce0ec3),LL(0x69d2fe28,0x4c059fd5),LL(0x76b354dc,0x1290e892),LL(0x674b639e,0x6d828313),LL(0x951c9220,0xd6285250),LL(0xee815fd8,0x3a0ba16e),LL(0x8ee38518,0x5323ff40),LL(0x6678fced,0x58fd9e73),L_(0x00000153), LL(0x73a8b28d,0xba84ecb6),LL(0xbd048216,0x34998afb),LL(0xfb264967,0xfcd4e06c),LL(0xc024c958,0xd668c764),LL(0x9c3e07fd,0xee500455),LL(0x0ea9e902,0x7be48424),LL(0xdf78504c,0xb185d1cb),LL(0xc315ffe9,0xcfa4801f),L_(0x00000174), + LL(0xdb3f67e6,0xdbdf25d6),LL(0x23503a7e,0x4a86faf8),LL(0x58cbd82a,0x727561d4),LL(0x50ad1fb2,0x0994b8fd),LL(0x1d57e2f0,0x1b2b4725),LL(0x15736a57,0x5dcba3cd),LL(0x4df58192,0xec335163),LL(0xf716e579,0xa8c09f90),L_(0x000001aa), LL(0x3615c741,0xe4509eb4),LL(0xef754782,0xbb1dede8),LL(0x7a793f6d,0xa02e32d8),LL(0x27d972fe,0x00b65ecb),LL(0xd0af4ace,0x80ede0c9),LL(0x96816659,0x6c809dcb),LL(0x979a653f,0x943f6f1f),LL(0x0638c8e6,0x2bcc5fa7),L_(0x000001fa), + LL(0xc3695735,0x79907894),LL(0x6a94274c,0x923a4f54),LL(0xa698895f,0x6213c148),LL(0x57afe3d1,0x14eca3c3),LL(0x40597be1,0x57638ac1),LL(0x23258bde,0xb1f30c4d),LL(0xb9d09cea,0xe2c1e648),LL(0x544e3974,0x505f2b5b),L_(0x000000d3), LL(0x28a45f39,0x0111ad40),LL(0xbe28f874,0xc3e262fd),LL(0x830a9ee4,0xe3cc3453),LL(0x0fdaa4f4,0x044defae),LL(0xcdb8b9c8,0x06665f64),LL(0x4a06827b,0xb0bfa5e9),LL(0x926f3364,0xaf288ab3),LL(0xd9d3c3ec,0x52d7095c),L_(0x0000005a), + LL(0x5eb181f2,0x047db30c),LL(0xbb73f9ac,0xf0b9977a),LL(0xc5355db3,0xa26685fe),LL(0xa356655d,0x48c1a2cb),LL(0x950bb7fd,0xc2c2dc45),LL(0xe766094a,0x437ff8a8),LL(0x80146ca2,0x0b26425d),LL(0x5b7aafe5,0x20ce1d21),L_(0x000001e4), LL(0x1c8a54b7,0x683c3c46),LL(0xee244200,0x806c758f),LL(0xb90af5d8,0x71dee02f),LL(0x67ac6f65,0x53aeab51),LL(0x0f1dfed2,0x762d7338),LL(0x59bf51fc,0x059d5565),LL(0x1432973f,0xa9143049),LL(0xbf133e93,0xc1c8977e),L_(0x000000e4), + LL(0xa86b08e9,0x4f81ab77),LL(0x4d06707c,0x8f1bf925),LL(0xaaec66fa,0x4de91bfe),LL(0x49683907,0xb9d75b89),LL(0xac105bac,0x91f21593),LL(0x6506b77d,0xab4390d7),LL(0x7287e5ee,0x7487ed45),LL(0x6c88b2c6,0xbb3803c1),L_(0x0000006a), LL(0x11c071b8,0x97c81ddb),LL(0x1bbbfe37,0xd3ad9501),LL(0x7a1b3885,0x68eaad09),LL(0x7027528c,0xf0a64aef),LL(0xcf860284,0x3c25fb62),LL(0x37b3f120,0x5ae492f1),LL(0xd454de89,0x61c7d5ed),LL(0x02ac32db,0x9d99d9a3),L_(0x000001a1), + LL(0x245c4af0,0x97406073),LL(0x02c143ac,0xda94e70d),LL(0x1c3ce7f2,0x639942c8),LL(0x9cde176b,0x7bd79b38),LL(0x0883b19a,0xac9d2c91),LL(0xb4709f2a,0x4423fc39),LL(0x794a6aaa,0x89d178db),LL(0x2e0aecc8,0xf4ffbcc4),L_(0x00000075), LL(0xb872cf73,0xd957093e),LL(0x85b4776d,0x2acbd72e),LL(0x0656f9a4,0xd468fb6e),LL(0xe2017205,0xc79f3d11),LL(0xe6a367a5,0x012b1362),LL(0x73088cac,0x370e3947),LL(0xb86f1933,0x3bdf96c5),LL(0xe8162ca6,0x5d8a34dd),L_(0x000001ac), + LL(0x9b09e656,0xeb6d1849),LL(0x81aa411a,0xaae86725),LL(0xd8ee02c2,0x3008becf),LL(0x574081d1,0x53cb17df),LL(0x37bd5637,0xe3afcfbe),LL(0x116f90cd,0xe91cbaad),LL(0x9a6da94d,0x023933b7),LL(0xbabdb470,0x5562808f),L_(0x00000086), LL(0xf3d722e1,0xef4074df),LL(0x2345ac8e,0x1492cda0),LL(0xe92886d5,0x0fa0e7ed),LL(0x31537a63,0x0778badc),LL(0xa8b49a51,0x2034669c),LL(0x85153992,0xace88cb9),LL(0xfd679e52,0x4c6fbbf5),LL(0x48dc5511,0xa37bc767),L_(0x000000e6), + LL(0xe7ef2e60,0xcd7037d9),LL(0x52aa0cf6,0x7dc7381f),LL(0x24da2a63,0xc3562613),LL(0x43cb3857,0xfa06da1c),LL(0x5a1b2f21,0xc7806190),LL(0xec8d6d1e,0xf2d57ff1),LL(0x5a0e8065,0x3e9088a1),LL(0xc30f4ccc,0xfbce5c5d),L_(0x000001c0), LL(0x5912141f,0x1bc58b8c),LL(0x19ee91c4,0xbf2996d5),LL(0x41d465ca,0xb39d820d),LL(0x281052af,0x890d83a9),LL(0xa8cb9903,0x32dbf7a5),LL(0xbfad3855,0x309c32fb),LL(0x81d1982b,0x44dec521),LL(0xe04b5e8d,0xbcfee0cb),L_(0x000000bb), + LL(0xf141f663,0x6c39f9cb),LL(0x458b556c,0xea205dcc),LL(0xb6c66d04,0x96d440e6),LL(0xa0f1a8e6,0xd4e4d37e),LL(0x3d5c97ee,0xd69c9913),LL(0x92914c77,0x12d04cdd),LL(0xb8bb2a33,0xa42c1185),LL(0x2dee2451,0x66637684),L_(0x00000165), LL(0xe8feb727,0xf2ee4afa),LL(0xb371de96,0x0f971611),LL(0x605c486d,0x50e27936),LL(0x313e3113,0xdf801ab6),LL(0x7cfe0fbb,0xfbec3f73),LL(0x50864708,0x55057cd2),LL(0x3b426634,0xa56700f5),LL(0xe23875b8,0x34b766de),L_(0x0000011e), + LL(0x923016ac,0x17eaa1a0),LL(0x28e3f935,0x128b1c02),LL(0xa23b14eb,0x9183c2c0),LL(0x504289c9,0x5ea313d0),LL(0xb5fd0ea2,0x135c854c),LL(0x03f5e8df,0x491bfca7),LL(0xd9abdd7a,0x8b6af733),LL(0x29d5f4e7,0x832fe74e),L_(0x000001e5), LL(0x50113295,0xb89fd770),LL(0x861c50a9,0x6fd08a16),LL(0x1b7e4c60,0xb1a9800a),LL(0xadc9902a,0xbed31f30),LL(0xa5b9d65d,0xc9a0a6d4),LL(0x75c10264,0xe1743115),LL(0xc317e935,0x8c13233d),LL(0xc0c350f5,0xbc15e8d2),L_(0x000000a6), + LL(0xfdaa94e2,0x4ea46af8),LL(0x2200fec9,0x3139256c),LL(0x4f2fd88a,0xb9b83d67),LL(0xe894a212,0x5e6f7bed),LL(0x449c5bc8,0xbeebbe0e),LL(0x1e599f77,0x74fc58a0),LL(0x7f4a9123,0x6073c6cf),LL(0x1a08d5bf,0x63816113),L_(0x0000017a), LL(0xacb45b52,0x06826375),LL(0xbd9c13b3,0xf41e6cac),LL(0xc5b15016,0x79237672),LL(0x2f2bfd3b,0xa99e108a),LL(0x1681dcfd,0x22fd3033),LL(0x224f0276,0xc24a2525),LL(0x05e14660,0xf9a0ff9c),LL(0x09f9360e,0xbe09e3fb),L_(0x0000005a), + LL(0x1e2ff226,0x33f17650),LL(0x597f6cd8,0x95759918),LL(0x5f1a7fb7,0xb518de41),LL(0x316d41dc,0x966644e4),LL(0x829d89c6,0x7775eaca),LL(0xed7a513d,0x9d45da4e),LL(0xdd14ef8a,0x232852aa),LL(0xc016fff6,0x4687f62e),L_(0x00000088), LL(0x0791f95c,0x2cc46d0d),LL(0xd4641a73,0x04775f23),LL(0xb9dcdfdd,0xc9bd9d15),LL(0x727ace99,0xaec6f67a),LL(0xa77fe3e5,0xeac1ee2f),LL(0x75b923be,0x8f21d632),LL(0x55852cf0,0xb6658853),LL(0xbe6d4550,0x461bace1),L_(0x000000f6), +}, +/* digit=81 base_pwr=2^405 */ +{ + LL(0x2c6e3212,0x0a1fff24),LL(0x4b5a6256,0xa45d5589),LL(0xbc1ece0d,0x852bc8f1),LL(0x655945af,0xf4152e99),LL(0xf81d51a6,0x4573b7d9),LL(0x15c74818,0x69e42e80),LL(0x69dba53f,0x55b2c206),LL(0x96245123,0x8c3b8e9f),L_(0x000000a3), LL(0x11c96019,0x8a5146d0),LL(0xc8d9fabe,0x6c8e83c7),LL(0x3fede45c,0x3d5d33f9),LL(0xb87d2fad,0xe1fe306f),LL(0x67a48456,0xf030c243),LL(0x2aa7e6e9,0xb8f59e2c),LL(0x8097392a,0x7ae2ecee),LL(0xdbed7e8f,0x770cdce7),L_(0x000000aa), + LL(0x8efeaf2d,0x8c7ed96e),LL(0xf3e2fab6,0x3cb959b9),LL(0xfe65989c,0x4cec2e34),LL(0xb397dfd2,0x2a821089),LL(0x95a4f7a7,0x194fcfc2),LL(0xcd183d4d,0x009eac36),LL(0xc2005f34,0x384df54a),LL(0xc4355ce3,0x7125837a),L_(0x0000003c), LL(0x6218f15a,0xab158f0c),LL(0xc9db684a,0x919d3c1c),LL(0x22157c5c,0x733c654f),LL(0xa5d7e7c5,0x1bb67f61),LL(0x6dc89cd4,0x0cac1f78),LL(0xf6e74669,0x2b55f183),LL(0xb445fa4f,0x9df41e4c),LL(0x69c4dd42,0x100045a9),L_(0x000000a5), + LL(0xd8d9bdcb,0x3dd4ca53),LL(0x1306c74d,0x1af7d8d5),LL(0x3e680d58,0x9c6b82f0),LL(0x884ca0be,0x0aacdba7),LL(0x5c62e372,0xd633f595),LL(0x1c4cad9a,0xc84d067a),LL(0x54e3c550,0x4fe24eee),LL(0xbe3f67b5,0xf28e319d),L_(0x0000019e), LL(0xb999b839,0xd75cb7b6),LL(0xa5275bc7,0x5e6b4aa8),LL(0xfaa9f40a,0xe6b156cd),LL(0x1992d1c2,0x16e51f4a),LL(0x0b180928,0x00c94afd),LL(0x6b3427a9,0x0f9d0fb1),LL(0x09eefa51,0x098f98b4),LL(0xd3cae463,0x4d73daae),L_(0x00000180), + LL(0x881adc31,0xbb3a93b6),LL(0x8ce1cba5,0xb603dd9e),LL(0x4f5b70c1,0xaed8b0cf),LL(0x5f958dd3,0x5eae2517),LL(0xb70f44e1,0xa5b942f5),LL(0xc526177a,0x02efb949),LL(0xc8dd1153,0x132ba3a2),LL(0xf9288a95,0xffccbb89),L_(0x000001a2), LL(0xc45972eb,0xbc841aed),LL(0x7853d5b1,0x933a99b8),LL(0x6e1536aa,0x85259727),LL(0x238abf3c,0x05488fa0),LL(0x8485ab11,0x1debe07d),LL(0x6d6f6d52,0xf1ad18f1),LL(0x54637f92,0xdfd3c55a),LL(0xa2b58773,0xc41b6804),L_(0x000001db), + LL(0x66d98564,0x72366f09),LL(0x9a3f0f97,0x00008259),LL(0xb1a9b87a,0x33f3b0e5),LL(0xe8074b36,0xd83471a9),LL(0x68f935c3,0x59dc097c),LL(0x5ab59d2f,0x049d3329),LL(0xae3c2a44,0x523ad362),LL(0xd39de2e5,0x38178eb0),L_(0x000001da), LL(0x10a229a9,0xad11b358),LL(0xdcf6cbc9,0x8a7d993d),LL(0x2d5c5b91,0x31b67dc1),LL(0xd2d684f6,0x5dd81c8d),LL(0x29c17938,0xec292f8a),LL(0x2fb94c2a,0xe9c267eb),LL(0x67c899b3,0x31e831bd),LL(0xd72dd6a7,0x7b778a58),L_(0x000000ab), + LL(0x37a99dda,0xabc73772),LL(0xb8a9bdaf,0x18907ad9),LL(0xac790211,0xd35c8ab3),LL(0x56550490,0x483d71b5),LL(0x9c473d52,0xaed32863),LL(0x796ddfe4,0xc175ce1c),LL(0x39329661,0xf0af8692),LL(0x3411279a,0x1ac1b3f3),L_(0x00000062), LL(0x2f981ba2,0xe7ed779e),LL(0x25706bd9,0x385062b4),LL(0x8826d6b1,0x50749b03),LL(0x8f92597e,0x4d1f3b1e),LL(0xcc7ec8dc,0x5ffacc7e),LL(0xc4c11580,0x903de537),LL(0x82ed5c34,0x92e3ccb2),LL(0x829a6dc1,0xaa91f997),L_(0x00000010), + LL(0x8a8271c3,0x46e669a1),LL(0x9bedd70e,0x6dbeb99e),LL(0xe5038aaf,0xc8d58c8e),LL(0xe202e790,0x312f9e8d),LL(0x5eb0a99d,0x2b3b3990),LL(0x6e033ac6,0x8ddb53b5),LL(0xdd9938af,0xcad94c88),LL(0x8fee9f14,0x565b4703),L_(0x00000184), LL(0x2d18c7f7,0xf6c9ab51),LL(0xddec3950,0xd2e14fab),LL(0x8eb24aaa,0x85f6d87b),LL(0xbff04dfa,0x7d46acbb),LL(0x458d7c7a,0x949d94f0),LL(0x5596e98b,0x60ee6372),LL(0x37137ad5,0x20231d27),LL(0xe0d4f3a2,0x8c695e6d),L_(0x000001d1), + LL(0x1f851427,0x75a8973a),LL(0xf65e532b,0x125d27c2),LL(0xb7e6ca7e,0x680245ef),LL(0xd37a1c1d,0xc0ac3fa3),LL(0xc8ed8871,0x73ed1f61),LL(0x25a3f922,0x1c0619b1),LL(0xbaaf99bf,0x2fc151e1),LL(0xb9c92ca1,0x61f93b5f),L_(0x0000012b), LL(0x4cd45f13,0x46eca65c),LL(0x2f16b28a,0x181d940c),LL(0xdae561c3,0xdef08156),LL(0xdb51b5db,0x5aff9fff),LL(0xd7d0f3f0,0x56731470),LL(0x9f642167,0x3e4323b0),LL(0xc5c736fd,0xc2c256f1),LL(0xaf757eba,0x85000c46),L_(0x00000005), + LL(0xfc825ff9,0xa28756a7),LL(0x6fc9ac38,0xf07539fe),LL(0x19a8908a,0x89d74956),LL(0xc69dedbb,0x934712d9),LL(0x2aaee4e8,0xbbd47741),LL(0x1053c866,0xda8058c4),LL(0x00b68d70,0xc019bbaf),LL(0xb1236281,0xf44074ad),L_(0x000001c7), LL(0xad679598,0xffe5c58c),LL(0x5fe8d191,0xfb4d9415),LL(0x46edaa9c,0x44747329),LL(0xdd0f1cc6,0x34e406e5),LL(0x79f7cddc,0x40ad1213),LL(0xab39e94c,0x470ac094),LL(0x885cb3a4,0x12891647),LL(0x3224c564,0x41e24750),L_(0x000000e0), + LL(0x17473053,0x116c3934),LL(0x97765c7e,0x74d1a056),LL(0xf7e7734d,0x2fb92919),LL(0x22455583,0x880ac302),LL(0xc6198a57,0xc983ea10),LL(0x32d7f501,0x3adab6b9),LL(0xa4c1c306,0x3997a013),LL(0x14822e84,0x5da833b6),L_(0x000000b7), LL(0xf8efc5c2,0x2e766181),LL(0xda380c24,0x158c4baa),LL(0x4d96447c,0x6acaba32),LL(0xe953e90e,0x4ed2e3bf),LL(0x86ffae71,0x452c6d1b),LL(0x3af83523,0x49a52fe9),LL(0x41a86c00,0xec5b4f72),LL(0x9c65d29c,0x7bf9771d),L_(0x00000034), + LL(0x15231af9,0x83eb4905),LL(0x29b6e8f6,0x35420b50),LL(0x76561721,0xd8dddbf9),LL(0x83f7c4f4,0x776812d9),LL(0x460a8666,0xd3c1656b),LL(0x6901dcbc,0x22e1e397),LL(0xd9c17a67,0xd83adc99),LL(0x7a32d3cd,0x7dfafcd0),L_(0x0000007c), LL(0x66102687,0x8578e51e),LL(0x957c6151,0x9a86b387),LL(0xb2bd85fe,0x553c599b),LL(0x21884750,0xb8b8c27a),LL(0x920c65b6,0xf81924dd),LL(0x6f14a6d0,0x28619568),LL(0x18db08c4,0xab2d8a3f),LL(0x11b85385,0x4e01b95a),L_(0x000001ce), + LL(0x5aa706e4,0x0e7a9fe5),LL(0x2110fcf2,0xa8b2d6f6),LL(0x67bdfcf9,0xeaac5dca),LL(0x0435935d,0x39631926),LL(0x399fbc31,0x60795bd1),LL(0x34625175,0x0f561153),LL(0xced09fb3,0xe23ff49c),LL(0xf1b45cd7,0x14acb326),L_(0x00000110), LL(0x4ec88551,0xd20c517f),LL(0x3c8be0dc,0x221ae5ee),LL(0xd895d43a,0x6705afa1),LL(0x00fa5270,0xb373ab4d),LL(0x75678bdf,0x64e2886b),LL(0x47650c25,0x7e0e12f4),LL(0xab5c87d2,0x0c9aec40),LL(0x15ef4537,0xdac6c6e3),L_(0x0000016b), + LL(0x69bd1ae9,0xe2ef5aee),LL(0x0585cc2f,0x1e6188c6),LL(0xa3c01465,0x301c46a3),LL(0x1cc1ea41,0xf7f76048),LL(0x16944109,0xedd90482),LL(0xdc473809,0x3da1ef77),LL(0xf7267c80,0xfefdbcd3),LL(0xfd92f40f,0x230df237),L_(0x000001fa), LL(0x365d3aae,0x5f29db47),LL(0x93437f82,0xd2267583),LL(0xf4a57394,0xe0388ea5),LL(0xb28bca60,0x5cea0f68),LL(0xbf640edf,0xc68dbd2f),LL(0x8db4f9b6,0x24be537f),LL(0x9d943d05,0x7704cfe6),LL(0x4a1f249a,0xfc85d03e),L_(0x0000017a), + LL(0x15eb727b,0x79b64a1c),LL(0x82dd22e4,0x51a73cb4),LL(0xa1e0df42,0x5140d8ce),LL(0xf6d38530,0xe8523991),LL(0xbf2d199e,0x578593ff),LL(0xaabd945b,0xcfef51c1),LL(0x789ae01d,0x9c35735e),LL(0x685cad78,0x2d15c55a),L_(0x00000195), LL(0x9ac2d994,0x5bf21520),LL(0x5119208b,0x3671fecc),LL(0x477379bf,0xcfbe3b2b),LL(0xdc4fe9f8,0x98a8aee0),LL(0x6e915903,0xa7edc740),LL(0xc4cb91a1,0x71211193),LL(0x1e307364,0x96026ba1),LL(0x814b8b56,0xf21a90b1),L_(0x0000014f), + LL(0xdfef19d0,0x30a583d8),LL(0x8521445c,0x192a3c38),LL(0x8651795c,0xe24d5be6),LL(0x6cfd9cef,0x273daff4),LL(0x78499d8a,0xbe3d67fc),LL(0xf4d9c05a,0xfff37ca4),LL(0x9d03588e,0xbe977f9e),LL(0x2b3a2963,0xc6d47c43),L_(0x000000d6), LL(0x6c46a157,0x146210b3),LL(0x092ba668,0x00fc64e7),LL(0xcfe9730b,0xc41f8e66),LL(0xc11dab42,0x79417f9d),LL(0xff89645e,0xddf57c66),LL(0xd0e35f15,0x98273f3c),LL(0x49f211d9,0xea35684c),LL(0x1b8dcf07,0x09d76ca4),L_(0x000000aa), + LL(0x9d8b99d3,0x7dad9f18),LL(0x96f2ea6f,0x96139562),LL(0xf5d410b4,0x86c29eba),LL(0xc6b1f46d,0x2dbba6d4),LL(0xb1709ad9,0x9de07504),LL(0xeea80cc0,0xc7c9ec95),LL(0x47d01eb6,0x99076486),LL(0x19b1d6cd,0x9e10cb39),L_(0x0000014b), LL(0x0a5f9f34,0x53cc24a0),LL(0x5e367eff,0x672781ea),LL(0x275cfce0,0xedc5266f),LL(0x92d98139,0x0d9e2099),LL(0xc2c0efd5,0xf3d9cb26),LL(0x687bde18,0x647d23fe),LL(0xd97b9ccb,0x0c54a71a),LL(0x258eaff2,0x374fd27a),L_(0x000001cc), +}, +/* digit=82 base_pwr=2^410 */ +{ + LL(0x30cbad8f,0xfa23022a),LL(0x0f3c6cf3,0x9f3a186b),LL(0x33420e3c,0xdc6e922b),LL(0xbffbbdb1,0xeac227c1),LL(0x7aa59cde,0x43d5b878),LL(0xe3673dd9,0x513a5be5),LL(0xae77a5b5,0xbc4c0fef),LL(0x8e4c10fc,0xd4728351),L_(0x00000133), LL(0x2a245057,0x020fe0ed),LL(0x5e8e914b,0x39e8625b),LL(0xdbd2dbf4,0x3dfac893),LL(0x5bf5b95c,0xc2cfde2a),LL(0x29c6d879,0xca30a315),LL(0x05a9a75f,0x3ac05ce9),LL(0x894b84cf,0xb5445553),LL(0xeb87696c,0x45350dc2),L_(0x00000050), + LL(0xf9b134fd,0x05a92256),LL(0x23245303,0x7ccfce0b),LL(0x6d8cb621,0xd61ca36a),LL(0x6d0ef54f,0x210c1e23),LL(0x1a182b1b,0x8ae4f253),LL(0xb1f2e2c4,0xa16671b7),LL(0xd29f38da,0xae1cf556),LL(0x3fa6c8ea,0x878e21c8),L_(0x000000d7), LL(0xb9a18df6,0xa098406d),LL(0xd588a978,0xd15a5ed3),LL(0x781ea818,0x5e68786d),LL(0xad06fce1,0xf98680c4),LL(0x66d7a550,0x981589bd),LL(0xd3ff4140,0x7ff83976),LL(0x6ffe6dff,0x9c88eabc),LL(0x47479f18,0x2dc93316),L_(0x000000e7), + LL(0xdb783254,0xe1b91784),LL(0xcc2bd843,0x7a80b2cc),LL(0xda0b8166,0xaa3b4ff9),LL(0xaff9f442,0x88dcdac5),LL(0x38067551,0x47d782df),LL(0xba990049,0x82a02e17),LL(0x02eb92a1,0x61467fcd),LL(0x29ea45e3,0x2eb8d57b),L_(0x000000e3), LL(0x15b7f2b2,0x3170353b),LL(0x4a58e306,0x4a6890e8),LL(0x0dcaea11,0x2ee85176),LL(0x198b5c45,0x79793d5c),LL(0x9872dd7c,0x5ad3ba16),LL(0x2940cc17,0xacaf46a5),LL(0x9d812262,0xb1cff849),LL(0xee571706,0xa1e0320f),L_(0x000000e0), + LL(0xeb0d7e33,0xb0731c42),LL(0x657bac9b,0x5dc372a3),LL(0xd967282a,0xa9374ab3),LL(0xf9ac8856,0xbdf21057),LL(0x3b740967,0xfec8274b),LL(0x56933024,0x5596459a),LL(0x94a16871,0xc8d21c17),LL(0xef7bcfc7,0xf6a0ea98),L_(0x000000f1), LL(0xf9af7b9a,0xbfd8b660),LL(0x7b728a24,0x9cb13ed9),LL(0xee5e0227,0xa450fd15),LL(0xbd3b7d28,0x972ff1fe),LL(0xf367bf5b,0x08f71ea2),LL(0xaa4191b6,0x496276ed),LL(0x52d016bf,0xc4a6a4c1),LL(0x52e7dadd,0x513e10bf),L_(0x00000161), + LL(0x1afab699,0x049e7f00),LL(0x88380090,0xb4090ebe),LL(0xfc780e00,0x9088eeb6),LL(0x294d8c96,0x7d582ac2),LL(0x4027746c,0x5e897916),LL(0xc4fa7517,0x24defc92),LL(0xb30f7062,0x7efacebb),LL(0xe29a1ed9,0xd337aeb6),L_(0x000000f1), LL(0x856dc4c3,0xee3e4e0d),LL(0x6b56aa33,0x971e660f),LL(0xb6b834b0,0xabff8d16),LL(0x4f4e4f36,0x791ab99f),LL(0x1407b72f,0x49828107),LL(0x81293d19,0xdc829510),LL(0x1f2a3c51,0x359122da),LL(0x3bfa8d54,0x99db1fdb),L_(0x000001e7), + LL(0xdf15ca96,0x121949d5),LL(0x705e6cb5,0x15f3e1fa),LL(0x844205ea,0xda2168d9),LL(0xb4128cbd,0x793edfff),LL(0x751feb1f,0x332f4e92),LL(0x4c804349,0x4429da30),LL(0x26bc232c,0x8cea38b7),LL(0x753baf61,0xb3299d3c),L_(0x000000d5), LL(0x88e43827,0xb46e7eb4),LL(0x41b7f39b,0xc6fd29ba),LL(0x98261154,0x4974c56e),LL(0x502ce35f,0x0efcc622),LL(0xad5a1de8,0xfd41558a),LL(0xa51d36ff,0x1a681fdd),LL(0xf2ea91c6,0xaa082cc2),LL(0xf7b13d69,0x107dcaed),L_(0x000001ce), + LL(0xa66a52a8,0x208e5e12),LL(0x9cf1d09b,0xa19a455d),LL(0x4d39c2fb,0xbd4d9e44),LL(0x0adaf826,0xd068570e),LL(0xfd187cbc,0x93225311),LL(0x2398aca7,0x490180a0),LL(0x2dcbb906,0xcee10c1a),LL(0x40723e9c,0x71dc29fc),L_(0x00000018), LL(0x0caf9248,0x7f7fda0a),LL(0x722d1676,0xbe8a621f),LL(0x96407066,0xe524661e),LL(0x3a360a23,0xaa8ac484),LL(0x22dc1578,0x9532f3a1),LL(0x70f20b2b,0x936a98d0),LL(0x4e640ba5,0x10c24716),LL(0xc78e13ef,0xad48efab),L_(0x0000004d), + LL(0x8ced176d,0x49979e6d),LL(0x1d8f2f21,0xb3c390a7),LL(0xd1cc9018,0xff49ec42),LL(0x805d407d,0x56592d13),LL(0xb92c79f6,0x69b4fae8),LL(0x7816250a,0xea40b75d),LL(0x9c23c189,0x98e49fbb),LL(0x012080c6,0x8f035630),L_(0x00000189), LL(0xde297ec2,0x394adc76),LL(0x39d2e9b4,0x084a2dca),LL(0xa4a3c98c,0xff54162f),LL(0x4df52d9f,0x847a48de),LL(0xa6af6c27,0x9a4d9dcc),LL(0x128a4972,0x96ed3609),LL(0x8323c41b,0x0a200116),LL(0x81fed229,0xa4fde51e),L_(0x000001e7), + LL(0x20d87189,0x08f2635f),LL(0x6ccede28,0x6b5f8018),LL(0xc2a0e842,0x1a1eaa9e),LL(0x09c6bbfb,0x590c83ae),LL(0xba912027,0xb05367b2),LL(0x98c59c39,0x363d5716),LL(0xc607367d,0x2738b72f),LL(0x76fa4bf8,0xafbb3680),L_(0x0000014c), LL(0x04011fd9,0x6b33299c),LL(0x42860e67,0xfb00a1e0),LL(0x95c30a5c,0xc7ee4546),LL(0xc597748e,0xbb5a242e),LL(0x3ed03861,0xf0e0361f),LL(0x87708c93,0x2149d193),LL(0x7590a638,0x483134f1),LL(0xc66e8a9d,0x85cc2776),L_(0x000000e0), + LL(0x3813f012,0x5ffac9a4),LL(0xc0d4789d,0x3e79348e),LL(0x955e2b14,0xdb2d28b7),LL(0xe25f9f8b,0xc1656e1c),LL(0x6715563b,0xec42f2f4),LL(0x79f7e28f,0x2aead585),LL(0x106b8506,0x201ba118),LL(0x7f8c385c,0xe4fe7233),L_(0x000001ab), LL(0x0507ebcf,0xa8ba08d5),LL(0x035af551,0x5db82217),LL(0xe87f61ae,0x97aaf3ee),LL(0xeaf13d4a,0x5f02aeda),LL(0x0476d73b,0x05c9a1af),LL(0x8d9103dd,0xbbd0da23),LL(0x4b324ed6,0x4516539b),LL(0x0edd4904,0x253727b2),L_(0x0000009a), + LL(0xfad3e533,0x9fbd42a4),LL(0x2540903f,0xd7649f2b),LL(0xd8fbba0e,0xc6189edd),LL(0x6a06d4e6,0x1ecce6bf),LL(0xcbba2a3b,0x5c61ec36),LL(0xdb49be34,0x447d3062),LL(0xe4b0ad6c,0x49fc7fee),LL(0x1394cdb0,0xcc99bb8e),L_(0x000000f5), LL(0x1172029d,0x30a8e021),LL(0xbd509669,0x6f8f7c76),LL(0x34a06ccf,0x28f39de2),LL(0x1f805a36,0x5b84e8ae),LL(0x95bcde27,0xa9d053ba),LL(0xd196b2b5,0x4777e8cb),LL(0xbc21fa82,0x1bd75421),LL(0x58e2b8c6,0x9c786320),L_(0x00000036), + LL(0x7a23ceea,0x51aba8d2),LL(0x241c7fb7,0x58878762),LL(0x60069d96,0x51c9d281),LL(0x30ade2dd,0x9b631718),LL(0x91c3eb50,0xf909879a),LL(0xca8dcb86,0xee7eb48a),LL(0x9244bc3d,0x3828bf79),LL(0x2a064705,0xfb4bc920),L_(0x000001ed), LL(0xa015f7fc,0x3ba48f85),LL(0x2b6a12f5,0x95ae129c),LL(0x444e10a6,0x8aeddb2a),LL(0xecfba54d,0x0e8bdf6a),LL(0xc7c39b4f,0x0a72c4d1),LL(0x73b3e601,0x5cdfd0f3),LL(0x99b50a0d,0x5168c9e0),LL(0xbed1929d,0x87bf31c8),L_(0x00000050), + LL(0xa9be603a,0xd22b9ef5),LL(0xc53e7872,0x9558bd84),LL(0x154e0475,0x65401d38),LL(0xbb71dcda,0xf42190a1),LL(0x79891c59,0xcce4f8f7),LL(0x3876a596,0x5ec40734),LL(0x91d0b32b,0xef02bcea),LL(0xe2d3dc41,0x22d8fe83),L_(0x00000158), LL(0x48a15725,0x7ac11538),LL(0xde31cc2a,0x59724de2),LL(0x949e5fc7,0x1c37f0ed),LL(0xc39190ad,0xc058927a),LL(0xb63be947,0x6bda54d7),LL(0x1d0ceb2d,0xcff0cf31),LL(0xac38d621,0x23f872f5),LL(0x04b46672,0x160a5f19),L_(0x00000052), + LL(0x13238feb,0x8c998602),LL(0xca47bfa7,0xebe29b0a),LL(0xe22527b3,0x7f9eebf4),LL(0x127b07f2,0xa6e2939d),LL(0xca0c1812,0x6469e55a),LL(0x65afd9e7,0x46a7771a),LL(0xf84da7e1,0xbd0864a1),LL(0xb5dbfbc9,0x87ff16c0),L_(0x000001f1), LL(0xb3a29f77,0xbf5bf543),LL(0xb2d15c04,0xd9bcacc1),LL(0xb632b37f,0x5041f46d),LL(0x9bed186f,0xb690ffbb),LL(0x4873f91b,0xeebd39f1),LL(0xff2ad723,0x79a50cae),LL(0xd0c46d7f,0x6b3bea02),LL(0x4a5b4d01,0xf2c26cc1),L_(0x00000112), + LL(0x0bb28261,0xe9314bb7),LL(0xa04bdd40,0xaab60946),LL(0xe0b7c3f9,0x20cc2e25),LL(0x1e792761,0x60fd58e5),LL(0x7823f278,0x561086d3),LL(0xfa3bf02e,0x7b6170af),LL(0x0390ab9e,0x4a18459c),LL(0x0c346fa4,0xf810e889),L_(0x000000b3), LL(0xb623e6eb,0xe73d3d7e),LL(0x43490dbf,0xc1f1a1fd),LL(0x49e9e831,0x0a18b7b1),LL(0xe619f992,0x0c6e526d),LL(0xdb9252a1,0x954cd738),LL(0x6a826c49,0x41105a8b),LL(0xddcbb9cf,0xe9217743),LL(0x750efcbf,0x3f5b0793),L_(0x00000036), + LL(0x90c2c466,0x57128a20),LL(0x1345257c,0xdbf610a8),LL(0xd16c4a33,0xbff009fd),LL(0x8f1d5b65,0xb49af8c7),LL(0xf560ad02,0x0eb8499d),LL(0xfb45ea45,0xa52dc630),LL(0x7e352023,0x8ada8ac5),LL(0x2fd6cb3d,0x74b6bfb7),L_(0x00000107), LL(0x8f6d7783,0x4a52a42a),LL(0x3f44af1f,0x4175b2fd),LL(0x05fe7f14,0x079ac149),LL(0x1757d0c0,0x475fac70),LL(0x88ae6d1c,0x7bfd9387),LL(0x33f3d56b,0xb7dbf13b),LL(0xcacad131,0xebd1df20),LL(0x8aef62c8,0x20404609),L_(0x0000013a), +}, +/* digit=83 base_pwr=2^415 */ +{ + LL(0x96fd03e2,0xf3f782f7),LL(0x0bf4ad5c,0x3ffeae62),LL(0x8514f603,0xe39ca015),LL(0x5633e085,0xa88f4e54),LL(0x94884fbe,0x85fc77f2),LL(0xf605882a,0x2678c646),LL(0xa505f9b1,0x799ba323),LL(0x23217b43,0x88a00292),L_(0x00000141), LL(0x032e8744,0x29194f6c),LL(0x6cab181a,0xa932a791),LL(0xf60ec063,0xb94fb0f9),LL(0x217a0ff0,0x8f066aff),LL(0xd03ea56b,0x56ee8b26),LL(0xc1ffed4a,0xefbf8ce2),LL(0xed130515,0x922eb114),LL(0x74474339,0x2e17e43d),L_(0x000001e8), + LL(0x88affb50,0x5fc7f37a),LL(0x170a0c1c,0xa1f73a2f),LL(0x83474ff9,0xea811929),LL(0x4738ed4f,0xdd78686b),LL(0x24d293dc,0x16188a23),LL(0x36670cd9,0xc585fd52),LL(0xa2e54dbb,0xd3b67188),LL(0x10b37344,0x06ec68ed),L_(0x000001a3), LL(0xb4548b08,0xfbe0b348),LL(0xad120991,0xef3cdca5),LL(0x034c9a59,0xd16cfcd2),LL(0x56699960,0x10f2524f),LL(0xf6df1f5f,0x4733c5f1),LL(0x98a50032,0x757f84ed),LL(0x2ce4fa9a,0x032f7eec),LL(0xd296f3ba,0x6c007ae3),L_(0x000000c6), + LL(0x4c96fb7e,0x71db44c9),LL(0x7ac3b1c1,0xe9e2107d),LL(0x6305a422,0xa60259b2),LL(0xc0b70492,0x17e1f71b),LL(0x3dedfaf7,0x57f8d178),LL(0x15a8c62d,0x7a704e50),LL(0x81a4724b,0x3b26accf),LL(0xdf992c3c,0x03ad3ca0),L_(0x000000b7), LL(0xe35cce3f,0xc9cc0ded),LL(0xc51c6e93,0x00949cad),LL(0xba4d9081,0x8de8b3c3),LL(0x274926f6,0x839aef68),LL(0xf13d3b8a,0x40a2e3c7),LL(0x90113a91,0xef4e7433),LL(0x1f472807,0x8320657c),LL(0xd4accc1a,0x34dbb9d6),L_(0x000001c4), + LL(0xc34e9382,0xcd77eae7),LL(0xad7f0d81,0x13604a2d),LL(0xd0e3fde5,0x70443d13),LL(0x6cb59871,0xc5f3e64c),LL(0x7a8441d1,0xadfd909c),LL(0x00532361,0xefba7861),LL(0x0eb9abb4,0x05155907),LL(0xee4fe6fb,0x400f9708),L_(0x00000166), LL(0x7579200c,0x128ad5ec),LL(0x49006579,0xc2659737),LL(0x8cf2fa39,0xc9df0a7f),LL(0xdb548c37,0x648b652d),LL(0x3da31069,0x075eeef1),LL(0x34916a7e,0x04d0e409),LL(0xea6b7825,0x08fd613b),LL(0xba92eb2c,0xed99155b),L_(0x00000149), + LL(0x47521ca4,0xc24e86b5),LL(0x555d9a6b,0x572924ea),LL(0x878c09b9,0x379539ca),LL(0xb6b82a15,0x8666f974),LL(0x72ba5827,0x2d9ff656),LL(0xb17ece57,0xc68cfdb5),LL(0xfe917da6,0x22f34e2a),LL(0x08992968,0xfd615e21),L_(0x0000007b), LL(0xf77f07dd,0xba763f11),LL(0xf3886c72,0x11e3d2aa),LL(0xa4c6b62d,0x550a0527),LL(0xe4eac1e4,0x6a7880c8),LL(0x9b86f1e0,0x00ea68f4),LL(0x87cc2f01,0x55e1d3f3),LL(0xa6daef73,0xa5a26f0f),LL(0x2061095b,0x9af79ad8),L_(0x0000002e), + LL(0x8b5ab4da,0xbf85411a),LL(0x7b991f0d,0xa933992a),LL(0xce47a748,0xc820accd),LL(0x662f2eb8,0x12508cc5),LL(0x964b5fdd,0xadddfe6b),LL(0x1358db73,0xf97a44a3),LL(0xfefeacaa,0xf544c5dd),LL(0x3a084f6f,0x820fa340),L_(0x00000094), LL(0xa4ad406f,0x54cddbeb),LL(0xec844e89,0x92a7fe19),LL(0xa4c49f5f,0x30484bff),LL(0x8eb76b96,0xf75a70ec),LL(0x414948f0,0xc139503c),LL(0x7606dff2,0x2fdf031b),LL(0xead62083,0xc5fa11a5),LL(0xf7a1eba7,0x4285147e),L_(0x000001d8), + LL(0x7ec431d8,0x2ebaaf47),LL(0x3c1a318b,0xd9561acd),LL(0x57cb3287,0xf1f803a4),LL(0x97882cee,0x97ac71c6),LL(0x08071010,0xf26f5efd),LL(0x60ed1a2f,0xe4333f2a),LL(0x76efc905,0xc5d26fd2),LL(0x4101ca9f,0xaa75d93c),L_(0x000001c0), LL(0x75779876,0xf709921a),LL(0x294a8042,0x5ab89053),LL(0x0dc515ed,0x5f21558b),LL(0xd5146f68,0x1cdf8e37),LL(0x8dcdaaee,0xe4930f54),LL(0xacb8f4a6,0x58634cb4),LL(0x507294c8,0x20ac12b8),LL(0x38b15ebe,0x4cdf2cba),L_(0x0000007e), + LL(0x6973a3da,0x5d8f611c),LL(0x3f4e86dd,0x799bf33f),LL(0x749fb625,0x4a326f63),LL(0x667bd358,0xa8161392),LL(0x060fa9fe,0xa3a8de55),LL(0xc4af999e,0xdd75d71a),LL(0x18b1e644,0xc8783194),LL(0xe995c857,0x66a68c67),L_(0x0000017b), LL(0x32c7afa5,0x22bb4a07),LL(0x08c59a72,0xc7e0e1a6),LL(0xe1132506,0x1fa09057),LL(0x5c6a1998,0x6b7bf39c),LL(0x41920509,0x8ab7490c),LL(0x462ba7d3,0x9e016ba7),LL(0xdc3595d9,0x1207f474),LL(0x6a3d8c9f,0xd6a83663),L_(0x000000a5), + LL(0x2b8fd9cd,0x606dd096),LL(0xaea5acbf,0x3ef0fe25),LL(0x4859d96e,0x078a8287),LL(0xf923a972,0x0d66d4df),LL(0x660fec36,0xb27b9ec1),LL(0x102d1cc4,0x1d991f63),LL(0x730fac93,0x0c8cdfad),LL(0x601a8644,0xf814f65b),L_(0x00000164), LL(0x55d58869,0x0d313b90),LL(0xde263f83,0x11dbdf4c),LL(0xcde2808c,0x824b53bf),LL(0x6aad6afb,0x94547c69),LL(0x864c21db,0x6771d459),LL(0x65c1681d,0x7f15bc35),LL(0x95681ca9,0xeac68bf9),LL(0x78f00d83,0x5d523cdb),L_(0x00000161), + LL(0x2f058d88,0xb2e8d253),LL(0xaca02a59,0x15502597),LL(0xbd7d1caf,0xa0dfb1e8),LL(0x680e361d,0x9355f155),LL(0x2ed31cfd,0xb0064d2b),LL(0x308047c0,0xf348830f),LL(0xbffaf7d4,0x7bb7440f),LL(0x553b98e1,0xbe483a5a),L_(0x000001e6), LL(0x9f0f6eac,0x25881bc3),LL(0xa7105d49,0xd655e7e9),LL(0x033db883,0xdc82f09a),LL(0x7d5a4975,0xa17847e9),LL(0x4036e619,0xe9b20930),LL(0x048479d0,0x34fdadf8),LL(0xe6c7daa4,0x19412216),LL(0x152f330b,0x6eae10eb),L_(0x0000016c), + LL(0xc41a7939,0xcb26a326),LL(0x78d31411,0xa365755c),LL(0xd3a391dc,0xe18d1f8e),LL(0x25f34512,0x72a34b02),LL(0x345c60dd,0xd3613f12),LL(0xe2be6e2f,0xee2aebd8),LL(0x116aa632,0x92435b38),LL(0xa7cff2c3,0xccdf1cc9),L_(0x000000df), LL(0x342a1414,0x9da3251e),LL(0x650f3cbb,0x1c4cfe7a),LL(0x93ddee66,0x90734ecc),LL(0x1551811f,0x6d901fe7),LL(0xcc1cef07,0x0c7d5cd4),LL(0x3cf5fe87,0xf0de3068),LL(0x628a5bd8,0x56e883b0),LL(0x077d4d10,0x9f410795),L_(0x0000007e), + LL(0x2d362cca,0xfb4260cc),LL(0x99614b58,0xe2d527b8),LL(0x67cb8aa3,0x08c1f0b4),LL(0xef71b82f,0xc4649ad1),LL(0x4dc68072,0x11a9313c),LL(0x1ac298aa,0x65002fbe),LL(0x9f237961,0xe90bf539),LL(0x537dfdd6,0x5b64f24b),L_(0x0000011c), LL(0xfcf6c830,0xf2e76469),LL(0x4ed4174a,0x51f1bc5f),LL(0x3a450f7e,0x83c0406c),LL(0xb53708a6,0xaa7dce02),LL(0x2428a6e3,0x44b377b6),LL(0xf1abc0df,0x9c1a58f5),LL(0x0f02c35e,0x27c5458b),LL(0xea8718da,0xc56a6b16),L_(0x0000015b), + LL(0x1709bab6,0xd1568e14),LL(0x5208725a,0x11bb7351),LL(0x3937bb45,0xe6e5c9ed),LL(0x51ec95b9,0xcf7661c1),LL(0x2e23be41,0x6ad385c7),LL(0x743b0e8c,0xe91385d0),LL(0xdfe84bbc,0x6fd97535),LL(0xdce16477,0x922ccac9),L_(0x000001db), LL(0xef8587b7,0x0e47600f),LL(0x8f375855,0x6859ef6b),LL(0x529ee446,0xc03de2c7),LL(0x84c625e6,0x6f7cbb53),LL(0x3af54a02,0x29eb9d15),LL(0x37cbf19d,0x750b2d9f),LL(0x2dc61071,0x28f78635),LL(0x6b20c9d0,0xc61fd9cc),L_(0x000001b7), + LL(0x78134d37,0x3d575868),LL(0x09f53723,0x6cf5af74),LL(0xfc4fd018,0x39a8ae6d),LL(0xb54df4cc,0xb1d402e8),LL(0x25f3046d,0xeece717b),LL(0x98af312a,0xa13a0c5d),LL(0x5f96c47d,0x7f73d630),LL(0xc80a3e3a,0xb8b39587),L_(0x00000180), LL(0x7f27d5a2,0x38bbf8fa),LL(0xc4360f93,0x2109c7d0),LL(0xe57b26a1,0xeea6004b),LL(0x32aad5ae,0xf9dededa),LL(0x341aa5da,0x6abc8307),LL(0xfdd6b0a1,0x88080bda),LL(0x4cecd6e0,0x1d4fa881),LL(0x24b2b7fe,0xdeba0f5f),L_(0x000000a2), + LL(0x9a724982,0x5ec2d29e),LL(0xa69853d7,0xd1a7ff3b),LL(0x4e7a173c,0xffeab3d8),LL(0x9f30735d,0xdf72352a),LL(0x92186213,0x469f7a55),LL(0x2d184184,0x15c208a0),LL(0x29514acf,0xa37b763a),LL(0x91393991,0x75a2695b),L_(0x00000124), LL(0xa16bd801,0xf0588b07),LL(0xc8dafbba,0xda133516),LL(0x3aebd875,0xf622ae4f),LL(0x34fb368f,0x4f336c4d),LL(0x0b5d9d6e,0xc6eb3519),LL(0xa586248a,0x6d28f06f),LL(0x6daf558c,0x2f3e52a1),LL(0xfb60040b,0x2b032cb3),L_(0x000001f7), + LL(0x05cc19d6,0x6d31ebaa),LL(0x2f30e929,0x3edd43b0),LL(0xc72cbbb4,0x827c79aa),LL(0x7829df3e,0x4e4cf8d5),LL(0x98bb6262,0xffe745fb),LL(0xad894f05,0x50b350aa),LL(0xb566ef19,0xf2ea5e2d),LL(0x37f6dcf4,0x89295e1e),L_(0x000001ae), LL(0xfa34202e,0xd748da48),LL(0x68fd9ed5,0xe1cf505b),LL(0xc7778cb3,0x3af31b86),LL(0xdadb4507,0xfe717fdb),LL(0xb4b6e80b,0x13036b30),LL(0x2c3f1ee4,0x482b138b),LL(0x4fc01593,0x71e1ed1e),LL(0xd788bd27,0xe78b3e84),L_(0x000001cf), +}, +/* digit=84 base_pwr=2^420 */ +{ + LL(0x7d9afb73,0x1c085462),LL(0x2eb9d35d,0xacf6649f),LL(0x38a8a9ec,0x095acf4c),LL(0x78be52c0,0xf7d7ea21),LL(0x48f6e06d,0x115ce7bb),LL(0xbedc8285,0x7f232680),LL(0xe51e8f4b,0xd24103a6),LL(0x09aa0bc0,0xd9c59aaa),L_(0x00000106), LL(0xe11c4bc5,0xf757159c),LL(0xbc8d09f1,0x0e9e10c0),LL(0xe3621884,0x60d7345b),LL(0x822e5e0a,0xddc802d1),LL(0x6ae792ac,0xf49763d7),LL(0x868a6be0,0xff0f1717),LL(0x7cae1bcd,0x69443786),LL(0x8bfe19f2,0xe856270e),L_(0x00000073), + LL(0xe01b8994,0xe496416a),LL(0xa213f31c,0xdc0825ce),LL(0x0281aa93,0xe4450bdf),LL(0x236853f9,0xc8c09e59),LL(0x841e294d,0x595c72a5),LL(0x1e14b03a,0x2bc6e538),LL(0x46b3008c,0xef20b035),LL(0xa57d1874,0x464d68ec),L_(0x00000160), LL(0x5951a61c,0xd36a1693),LL(0x5b84b925,0x1712f765),LL(0xc1e05016,0xa422f3fd),LL(0xa758020b,0xb022819a),LL(0xb6927405,0xfced2aa8),LL(0x13a79822,0x9ae63d93),LL(0x87cbebb1,0xcdd9c078),LL(0x13e45feb,0x2915f65e),L_(0x000001cb), + LL(0xc434f1f7,0x878049fe),LL(0xf0c9ca48,0x692a3fe1),LL(0x277fbbb0,0x7ad48261),LL(0x263dc0fe,0xc6fec032),LL(0x7e09052a,0x04d38aeb),LL(0x37fd6838,0x6c55fb12),LL(0x53925e9d,0x63bce4b4),LL(0xc33e2d82,0x3308456a),L_(0x000001c9), LL(0x70a764c5,0x705b2adb),LL(0xb9f1bed9,0x3bab4631),LL(0xb4850149,0x37a14535),LL(0x2385e829,0xcd9ea79c),LL(0x07aa5ebd,0x17e5b5eb),LL(0xd3216565,0x8fb6885f),LL(0xc6b2bd87,0xce87f791),LL(0xd44bfcfc,0xa6e61bca),L_(0x0000018d), + LL(0xd4a7c1bb,0xad86ee95),LL(0xf741fd13,0x1edd6ede),LL(0x85b8fada,0x08912214),LL(0xb65b3c0a,0x30092262),LL(0x3583aac0,0x6716727e),LL(0x817eec2e,0xd6729d8a),LL(0x33bfe296,0xa92ad342),LL(0x779921dc,0x32a04806),L_(0x000001b5), LL(0xc1373f0b,0x5632a2bf),LL(0x2c2b1683,0xa8cd4f47),LL(0xa4cedeb1,0x32a4b6c9),LL(0x180690c1,0xfa510c76),LL(0x1eca05f9,0x51eb02c4),LL(0x2e0f4e05,0x63213fc5),LL(0xb6165cde,0xd91b429b),LL(0x1fdd188c,0x86f862bc),L_(0x00000017), + LL(0x52629f76,0x87d39d0d),LL(0x07dbdb1e,0xcaaa9976),LL(0xeb7d6dd2,0x02ffcf23),LL(0x7e0cd30a,0x78d51085),LL(0x83ecd227,0x961e1f15),LL(0x54655c5e,0x8aa70a14),LL(0xf96ec7c6,0x62c8fb1f),LL(0x64d2f55e,0xab3379b4),L_(0x000000b1), LL(0xb6e904d2,0x0bec2602),LL(0xef59ae4f,0x80f6effa),LL(0x330793e6,0x54960688),LL(0x2442ae08,0xff5a5fdb),LL(0xc5e3d773,0xc6ac0199),LL(0xcacfcecb,0x2fa7a795),LL(0xc57e52d1,0xdfd6f9bf),LL(0x2e4eaeaf,0x8f282ce3),L_(0x00000015), + LL(0xefeeeccb,0xd77ed0ff),LL(0x9db74ad1,0x5e752d76),LL(0x0b6200a7,0xfc315b24),LL(0x7b48ab8c,0x38ef4859),LL(0x6f975045,0x980da41b),LL(0x09695a2e,0x0010c201),LL(0x0d2b23ac,0x7b7fe53f),LL(0xfe8b4888,0x54fafa1e),L_(0x00000174), LL(0xc97b952e,0x6b8cb163),LL(0x16bdd26e,0xd62feeed),LL(0x6129cfd5,0x9be7e3db),LL(0xcfa4489e,0xd804ec9d),LL(0x8f551707,0xadb1fbcf),LL(0x055312a2,0x05be2283),LL(0x7d87937c,0x33c9f74b),LL(0xe5edd3be,0xa04388d7),L_(0x0000011b), + LL(0x854b2f45,0x223a8078),LL(0x954aed2a,0x155358a6),LL(0x30349ae5,0xae186e4b),LL(0x982c7a2a,0x15564aa5),LL(0x26ca4f64,0xbb73fd2e),LL(0x3fca013a,0x2d10cb06),LL(0x3b01aea9,0x33610496),LL(0xd0f1f68f,0x51efcbbc),L_(0x0000008d), LL(0x7f69aedb,0x1ef2c9b4),LL(0x7e6d3ebe,0x3246ee72),LL(0x1a5a6120,0xfc23f5bd),LL(0x7e829b05,0x02380698),LL(0xfb70444c,0xe903fa23),LL(0xb14cf0d6,0xaba52743),LL(0x7e9872db,0x4a9994d9),LL(0xcbf74f83,0x7e344a52),L_(0x000001e8), + LL(0x077ea324,0xae770944),LL(0x13db8792,0x1201418e),LL(0xbc07e7f8,0x7f43920c),LL(0xd56c9383,0xa87da3ae),LL(0xf13ae3d2,0xddc44f1d),LL(0x220944b8,0x9328fcaa),LL(0xe3819646,0xeeb928d8),LL(0x3e55f26b,0xd7199731),L_(0x0000001f), LL(0x42ec4f45,0xfe195b7e),LL(0x8b6807bd,0xe12b70e6),LL(0x2b99f5fa,0x7ea15922),LL(0x4e065912,0x9b50760c),LL(0x2efe8690,0xb9b66711),LL(0x16a38c58,0x7b7026cf),LL(0x0ea01a94,0x80737374),LL(0x39639895,0xb0011015),L_(0x00000037), + LL(0x514bdbc0,0xb7081a5f),LL(0xfa8d102a,0x8b95f28e),LL(0xbeeb8bec,0x89435618),LL(0x71f4af84,0xdf609827),LL(0xb479c91f,0x14f1207b),LL(0xcb1fbb1b,0xde646157),LL(0xf9e5fc99,0x7b096333),LL(0x34873e5f,0xc94ae92f),L_(0x000000ac), LL(0xd78f796f,0x3fa5ab5e),LL(0xa3fca0b1,0xacf76276),LL(0x8003771d,0x1726ca8d),LL(0xe6d96044,0x3e43296d),LL(0x93fa9826,0x42531228),LL(0x527acf14,0x60a72222),LL(0x7a97cba9,0x3d7c6f6c),LL(0x1948eafd,0xcc2e1d2b),L_(0x000000f2), + LL(0x4e12b5af,0x08d068df),LL(0x886cf2ad,0x79260e0d),LL(0x52a61dfd,0x3e9745ee),LL(0x3f586c5d,0xe1f15978),LL(0x566b3b18,0x87842ee1),LL(0x9ad3de40,0xa8f52a76),LL(0xfa06fa9e,0x391add0b),LL(0x9e84e7b8,0xc75f3842),L_(0x000000a8), LL(0xbb6677c3,0xa05bc623),LL(0x52d3e69c,0xb274df3e),LL(0x974dd07a,0x630e22a1),LL(0x5e6204a2,0xb9a3958d),LL(0x1b227ffa,0xd0e0f634),LL(0x8fc075d7,0x37062afb),LL(0xbe7fbf5c,0x34adc02d),LL(0x77906471,0x8d8b552f),L_(0x0000012b), + LL(0x6c9a6028,0x259579a0),LL(0x6f5bb2d1,0x0285a43e),LL(0x154ac0bc,0x167a3f99),LL(0x36795c46,0x728f737d),LL(0xb73fd19e,0x4d08d004),LL(0xa6cc0016,0x85ddb728),LL(0xe72a83f5,0x2e0d295e),LL(0xbfbd9eeb,0x6433def5),L_(0x0000014e), LL(0x90f9c914,0x0eb6be44),LL(0xaf866e12,0xfe01cd22),LL(0x5fd8a835,0x7bf70c61),LL(0x7f0a7679,0x38813f80),LL(0xc8998bdd,0x3833317e),LL(0xb796096b,0xfec3ea9b),LL(0x95f4e76d,0xdad9de4b),LL(0x341f07a8,0xa3d960d0),L_(0x00000061), + LL(0xd3c33742,0x200fc40a),LL(0xb0a42399,0x130ccf0d),LL(0xcba30b44,0x5e03c03f),LL(0x8e5dcd29,0x6cdd189a),LL(0x1e3d9c12,0x5a30516d),LL(0x81b3e6ac,0x6b10cabc),LL(0xcc86cceb,0x69bda2cd),LL(0xc43e19c0,0x11a9d83a),L_(0x00000130), LL(0xdc567bde,0xe0559109),LL(0x6575e24d,0xe2ac30ae),LL(0x67aa07b7,0x2b6c5e32),LL(0xdaf439f7,0x407ff042),LL(0x2ed76986,0x0a686f32),LL(0x1581e9c9,0x5cacfb27),LL(0x18e37622,0xc3e3f9bf),LL(0x387fd7f7,0xd10f51ce),L_(0x000000c2), + LL(0xcd152b7e,0xe1bfaadb),LL(0x9f66edb2,0x2faec2d9),LL(0x65371362,0xe758a385),LL(0x03888c8c,0x70736030),LL(0x84bd514a,0xf31e004a),LL(0x391a903e,0x246ee862),LL(0x36e788ca,0x4e1e02aa),LL(0xf4e00df9,0x2c2a0937),L_(0x00000023), LL(0x13ba50a4,0x4eff7c1a),LL(0x941609eb,0x6d04b057),LL(0x4cf29ce1,0x414be663),LL(0xc8df1ba5,0x12291ebf),LL(0xaa401069,0xeb298db0),LL(0x8ded5bfb,0x893e7d57),LL(0x549bd728,0x01b7b4f4),LL(0xac5af1f1,0x22a5b845),L_(0x000000d8), + LL(0x5f6b726e,0xb153c049),LL(0x1a260428,0x30c06c83),LL(0x9ce7c010,0x5b4fc0ff),LL(0x894ae091,0x5657bc21),LL(0x0aae49b6,0x571a85ef),LL(0x79cfa3cb,0x65689c51),LL(0x2187e975,0xe76412d7),LL(0x992bb278,0xf64da789),L_(0x000000ea), LL(0x0cf8c519,0xaa2b60ae),LL(0x9b1824f2,0xc0f1fe55),LL(0x9db0e06e,0xd91bb72b),LL(0xa610996c,0x58e02f73),LL(0xf2c3a8c2,0x28d213dc),LL(0xeae1bfc7,0x13f362dc),LL(0x943517da,0xf7bdbaa1),LL(0x496789e0,0xfc68ba49),L_(0x00000023), + LL(0x6c383c56,0x23ca0c67),LL(0x0e7599c4,0x99283769),LL(0xfeb47aad,0xe99af616),LL(0xaf666d85,0xf45b2fa8),LL(0x9231d83a,0x7c7b482a),LL(0x98e9e83d,0x8568ac48),LL(0x1e56ad0b,0xb6b0ac15),LL(0x724bffe2,0xcd1a6169),L_(0x0000016e), LL(0xb11260bb,0x877aec8d),LL(0xc03ce819,0x4e72375a),LL(0xccf9f47b,0x54033f3a),LL(0xac8daf52,0x19b599aa),LL(0xdea12842,0x175a56a0),LL(0x7ec2c31e,0x8b550edc),LL(0x1acab966,0xf427902c),LL(0xb52abab5,0x2fa9ef47),L_(0x000000a4), + LL(0x52546c7f,0x20270840),LL(0x3c3eb721,0x13f0d6d8),LL(0x142e7b62,0x019eaca7),LL(0xf973a763,0x025efc29),LL(0x8be00c2a,0x6f6199ab),LL(0x03943eca,0xb5618bcc),LL(0xfbfb9ab2,0x5fb02749),LL(0x0ae9ab79,0x7965f13c),L_(0x000000e1), LL(0x50f295b9,0xab6d0e9f),LL(0x083d8bf1,0xbf53d7cb),LL(0x07076abe,0xf29d744e),LL(0x51a53561,0x5c2fc15a),LL(0x7d647b91,0x253f8428),LL(0x51a29ead,0x91bd9d62),LL(0x006b7bce,0xe106dd74),LL(0xc770e4ef,0x7ae25c92),L_(0x00000078), +}, +/* digit=85 base_pwr=2^425 */ +{ + LL(0x412703ae,0xe95afaa3),LL(0xeb61e427,0x271961d1),LL(0x509a4412,0xcf60fb71),LL(0xef04644e,0xd64abf7b),LL(0xf44d4556,0xfd03e651),LL(0x9b052a7b,0x4add4bdd),LL(0xbb2156b9,0x2a438d74),LL(0x6c6c1657,0xb9025fa3),L_(0x0000009a), LL(0x0eae16f9,0xafa2d73a),LL(0x44951d52,0x5bc81a5a),LL(0x324d90b4,0x8490fc89),LL(0xcab36337,0x7db83818),LL(0xdcb411d8,0xd6cb710a),LL(0x80af21f7,0xad265214),LL(0xf370ca06,0x3194a666),LL(0xd8bc966e,0xc5222375),L_(0x000000d7), + LL(0xbbdc15d0,0x35b540e1),LL(0x979e91ce,0x973de7aa),LL(0x745fa684,0x84d5e965),LL(0x999e957c,0x2675f78a),LL(0x671ead70,0xec63eb2b),LL(0x9f4e2bee,0x2262a934),LL(0xa151a2d6,0x885b027f),LL(0x5a633743,0x198c65b4),L_(0x000001da), LL(0x63ade9fd,0x64a13f40),LL(0x23957199,0xea6e576b),LL(0x21e1e294,0x1a39fa20),LL(0x3e8e8d0c,0xeb1db8f9),LL(0x2627a8aa,0xa239f73f),LL(0x4ba11c83,0xdc2704f3),LL(0xe1591a19,0x6d53062b),LL(0x75cd2132,0xfc2434c9),L_(0x00000197), + LL(0x615287cf,0x9beb6f84),LL(0x5201fcef,0xa7eaedc7),LL(0xabd8969f,0x485d39df),LL(0x52116284,0x9a298f42),LL(0xc2945b41,0xb98d985b),LL(0x02540f03,0xbe292f99),LL(0xfb5c8297,0x927d1f59),LL(0x379bfc25,0xb2c3602d),L_(0x0000005e), LL(0xbd1179af,0x24128932),LL(0x49c7ff27,0x920719e9),LL(0x1ce441c4,0x7bdf184c),LL(0xd4d77a7c,0xd00ec091),LL(0x286d6826,0x3901be8d),LL(0x8de5125b,0x6d7da5fd),LL(0x7b71c09c,0x0a84f058),LL(0xd13d8a20,0x4e423ecb),L_(0x0000004a), + LL(0x4047691d,0xb25141cf),LL(0x9109a95b,0xcb8b02c5),LL(0x46b0d286,0x43ceb570),LL(0xb7de8163,0x45b33ca8),LL(0xd109a4f7,0xe4de2617),LL(0xfe1ebf34,0x50869270),LL(0x1ca61709,0xd0a3a1b0),LL(0x38634a9a,0x3586512e),L_(0x000001fc), LL(0x38f07910,0xce15260c),LL(0xc1bab71b,0x59aca1ef),LL(0x5da68584,0x8166c7ad),LL(0x0bec54d9,0x8f461203),LL(0x49a9c32e,0xd88a5170),LL(0xefea1154,0xbe8180a7),LL(0xec5ede1e,0xad08abc6),LL(0xe0d26459,0x7c3d1d7d),L_(0x0000013f), + LL(0x75d35af0,0xc6d5609c),LL(0x78abf2cc,0xe0503dac),LL(0x06b14f6b,0x2edd7321),LL(0x1d8b929f,0xf2198c61),LL(0xae13548d,0x510cab55),LL(0x7dda7de6,0xd681dc83),LL(0x9c5b80c7,0xf75528c0),LL(0x3789ecc5,0xbf5f2412),L_(0x00000081), LL(0x96096d94,0x43aa0894),LL(0xc108e7c3,0x6b10f225),LL(0x662c2a13,0x6a846090),LL(0xfd5f03e1,0x2ef6dd38),LL(0x6481ee80,0x5be580e2),LL(0x5fdbc53d,0xa958cf09),LL(0x11a46f11,0xc02fca90),LL(0x664e67d4,0x83a23d94),L_(0x000001f2), + LL(0x2e504292,0xd30defda),LL(0x0fa7d618,0xea344a1b),LL(0x8b5c684d,0x88f031e8),LL(0xc536e574,0x4b824800),LL(0x3cbde674,0xad6b63cc),LL(0x56514289,0x9617ab5d),LL(0x85b3cf5e,0x7dc3ec36),LL(0x7fc09058,0xc79289b6),L_(0x00000135), LL(0x846008dd,0x6898fae8),LL(0x9e7f0e84,0xd8281d5a),LL(0x10825f5c,0x2d75ee2c),LL(0x12dbdb85,0x7c0aafd5),LL(0x9070014b,0xbf482380),LL(0x9ee025e3,0x0fc3aa99),LL(0x63b81901,0x508f2832),LL(0x84535f01,0xbbddb4f2),L_(0x000000aa), + LL(0x9b68b1b0,0xc08c3333),LL(0xc47488c1,0xab449170),LL(0xb2a5ff61,0xcf64ef35),LL(0xb9e5f70f,0x7b502c46),LL(0x417cfca7,0x88cbf950),LL(0x1cf7bedc,0xd4ad741c),LL(0xf0d8aab2,0xbcf1b6ad),LL(0xf5a48560,0x219e66fe),L_(0x00000180), LL(0x502beb84,0x2cc6cdcb),LL(0x584dda42,0x094da6af),LL(0x129f5a40,0xd42b7286),LL(0x1002d93c,0x5c173674),LL(0x725b278c,0xefa77633),LL(0xd75f98ff,0x791931d8),LL(0x21527308,0x512e096c),LL(0x53d3565e,0x6d15d8de),L_(0x000001f3), + LL(0x00019394,0x62bec3a2),LL(0xa2c579a3,0x5ab884c7),LL(0xa06cf4c6,0x083cab2b),LL(0xe7eda004,0xf5f6cd3e),LL(0xa107bb12,0xe8649e92),LL(0x492e8a0a,0x5a344683),LL(0x91fc3fba,0x8dcfb242),LL(0x94cfd171,0x12659c38),L_(0x00000028), LL(0x03751b1b,0xce223739),LL(0xc2f1043f,0x23da45da),LL(0xf9307b4a,0x3110105d),LL(0x2b6d1b2c,0xb39e6a89),LL(0x2f645131,0xd8e317be),LL(0x90466331,0xb2f395de),LL(0xf1e436a0,0x1cd56345),LL(0x547fe748,0x3e61e1b0),L_(0x0000003a), + LL(0x9c18c216,0xfd251565),LL(0x18071963,0xf23633a9),LL(0x005c3056,0x1e0819de),LL(0x46ebbb94,0xb549b1c1),LL(0xb17a6d7d,0x92577078),LL(0x991b825e,0x8f6ca39e),LL(0x98671ca8,0x90ccdc4b),LL(0x393fb1b5,0x83f03d02),L_(0x000000da), LL(0x3e2fd629,0x150480ec),LL(0x0aca508b,0xcbfc5f51),LL(0x0864f022,0x14650672),LL(0x3b3979b5,0xbff63c37),LL(0xb97ea4a4,0x3b1cb3cc),LL(0x3ef296ec,0xcb4a6db9),LL(0xff3bd186,0xbd5b637b),LL(0xedab5309,0xde8dfc52),L_(0x00000196), + LL(0xba62ee82,0xd77204b3),LL(0x77e6a3df,0x710f93b4),LL(0x02f4ab22,0xcbb03368),LL(0x5e0ecd43,0xb189c2ee),LL(0xc2847328,0x9bdf60eb),LL(0x0ebd36bf,0xb67d93ed),LL(0x0c17c388,0x70c2279c),LL(0xe8fdeaec,0x93ea44d6),L_(0x000000e4), LL(0x48b19e4c,0xc3191f20),LL(0x04206c4e,0x8bdfd660),LL(0x9a16a00f,0xac2112af),LL(0x61997c61,0x8ab3667b),LL(0x7b84c760,0x06bdff10),LL(0xf4e1645e,0x607df1e8),LL(0x352d17a0,0xa63979fb),LL(0x83c7eb22,0x015ff16b),L_(0x0000011f), + LL(0xe2ef6187,0xe76e649d),LL(0x50e4618d,0x6b987f60),LL(0xc357d1ec,0xad4f8231),LL(0xd4a60be3,0xb315fdb0),LL(0x2eced057,0xa9fb56ad),LL(0x19319996,0xa2da27cf),LL(0x2f11dee2,0x916ddbdc),LL(0x7e40b2e7,0x77406459),L_(0x00000044), LL(0xb7a77c12,0xb4cf9881),LL(0x7da427fd,0xcc7a5c06),LL(0x80b0089c,0xdef4d8fc),LL(0x93e7089d,0xe325b955),LL(0x16ead4d1,0xb039b2a1),LL(0x5dfcb305,0x1820d74b),LL(0xe64404b5,0xd5916176),LL(0x6e3b8d75,0x67136fef),L_(0x000001b2), + LL(0xe5919bbd,0xff1cd958),LL(0xef53a31b,0xf4f94077),LL(0x95740f28,0xd731ab60),LL(0xae2285d4,0xa1ecbb47),LL(0x8c0691df,0x258e27d0),LL(0x3a34371a,0x6fcf67a4),LL(0xe81db787,0x31ad117e),LL(0xcd7a8c18,0xbef4d701),L_(0x000001ea), LL(0x1c27e10f,0x7aa7d331),LL(0x36d353fb,0x484bc381),LL(0x5feb0814,0x14c00e62),LL(0x5a897087,0x4174c50b),LL(0x73330526,0xa9a0af61),LL(0x7d611726,0x60873261),LL(0xca260561,0xe43e2bb4),LL(0x9e169695,0xd6fd57ef),L_(0x00000191), + LL(0xb1e778d1,0xe387f978),LL(0x9b9aee5d,0xd76337e3),LL(0x92cf14d1,0xe5ccf490),LL(0x72921fc6,0x5b43aefb),LL(0x65d3e5c1,0x795ec0f9),LL(0x3904e5d3,0xa4928380),LL(0xa5751b73,0xdfd26a4c),LL(0x351de543,0x772f0a98),L_(0x00000160), LL(0x30b62509,0x2b0ddc19),LL(0xf6f4cca7,0xe118ecd8),LL(0xed5b6edf,0x0c9d677b),LL(0x4f5d7b07,0x34b851c9),LL(0x67daaa19,0xade6f3a0),LL(0xf4cef90c,0x4e977f04),LL(0xddf591d7,0xa5a8e05f),LL(0x51707198,0x73e4b240),L_(0x00000069), + LL(0x8fe855a9,0x6f37b397),LL(0xfc53c756,0x11e9e126),LL(0x0be45fa0,0x72b050d7),LL(0x0064ab05,0xfc69a454),LL(0x2c4f8ec5,0xe8ca3f9e),LL(0xfd23251a,0x3713bf5d),LL(0xfbba4b98,0xf9f17348),LL(0x022b3ded,0xf5712705),L_(0x00000075), LL(0x496ec6da,0x02b42501),LL(0x3666ead7,0xc5995675),LL(0x03f0c9c9,0xfafe4fc1),LL(0x92c23f3c,0x6e5dcc14),LL(0x49d6013c,0xa80274fd),LL(0x6faecdf5,0x3b89a119),LL(0x6951f782,0x04ebafd5),LL(0xe5c75fdf,0x98ee2e59),L_(0x000001be), + LL(0x4c63dd71,0xecaaf994),LL(0xdb563551,0xfa0452c4),LL(0x034243a2,0x35dd1a49),LL(0xc1e98b35,0x67ebb1d1),LL(0xd64a14c8,0x65aa32b2),LL(0xa40fe3b8,0xf36b9b35),LL(0x74b94620,0xde048775),LL(0x9c4f81d6,0xefb999ff),L_(0x00000048), LL(0x317a309b,0x27e42884),LL(0xea18f52e,0xab7b0d80),LL(0x6a303cb3,0xd883eedd),LL(0x6960a553,0x5fa720c0),LL(0x4a30771c,0xaf1c642d),LL(0x8c3afce3,0x0aea4951),LL(0x5b832460,0x8daa7e14),LL(0x3626a795,0xa9434a86),L_(0x00000042), + LL(0x5078f4b7,0xf8bc0fa4),LL(0xf5948727,0x1eb36b7b),LL(0xea0106cf,0xc704268c),LL(0xc80e06d4,0x300186e8),LL(0x5c216323,0x6e94d507),LL(0x72ccb301,0x882e86c3),LL(0x053b8cfd,0x3148a28a),LL(0xd1710019,0x864bf343),L_(0x00000010), LL(0x24c02876,0x6d8c63b2),LL(0xc0738276,0xb8220989),LL(0xd418521b,0xa59b967c),LL(0x52d761e7,0x601efc41),LL(0x0fa019e4,0x41cb4d7c),LL(0x9d52f11b,0xcac0131d),LL(0xe27a162d,0xaac991e4),LL(0x975ffa76,0x5c007789),L_(0x000000c9), +}, +/* digit=86 base_pwr=2^430 */ +{ + LL(0x53760212,0xe9ad4077),LL(0x52251dd3,0x2f89c76c),LL(0x5957d5e2,0xb5844aaf),LL(0x57c28051,0x630bd361),LL(0x369eb597,0xacac6af3),LL(0x5611a387,0xaad0ef87),LL(0xde2edc32,0x0bccba64),LL(0x731d170b,0x8f5a6ff1),L_(0x00000006), LL(0xc2557f66,0x48e1ee52),LL(0x5f44f645,0x0cf95561),LL(0x64b6036a,0x1e52bf2c),LL(0x89213e75,0x34bd858d),LL(0x15aa570d,0xbf1cb2e7),LL(0xcc205ae3,0xf29e703a),LL(0xfb1911e3,0x98a34a47),LL(0x78616fc4,0x432ae895),L_(0x000000be), + LL(0x301fc12e,0x91d6adbf),LL(0xdc42e25e,0x587a0d31),LL(0xcecd10d8,0xf88cc8a9),LL(0x8d1b41cc,0x90bd959d),LL(0x33b3f964,0x999c5a51),LL(0x47bee028,0xc3a08825),LL(0xb39f5f74,0xd4fc3438),LL(0x5af39ed4,0x4a0aafa7),L_(0x000000f9), LL(0xbf02b54c,0x0a29ee5f),LL(0x4f0d6dbd,0x57045bbc),LL(0xe6fde293,0xc7d0fce2),LL(0x040027df,0xcda45a33),LL(0x23be51ff,0x9841c14d),LL(0x6d045486,0x56ff1e33),LL(0xfdc85221,0x5ea634d9),LL(0x619b696b,0x35b3b3ae),L_(0x0000003f), + LL(0xa104ae49,0x5ed4f918),LL(0x7f6fea1f,0xfb0d6721),LL(0xb83838c1,0x99caa790),LL(0xd116daa3,0xc2f1d19e),LL(0xe68d0873,0x105c2468),LL(0x247798a8,0x672f66e0),LL(0x740bca2a,0xe789f0d7),LL(0x86c229b4,0x505a9b4c),L_(0x0000007d), LL(0xd8e83bf0,0x77be9153),LL(0xaa767cd0,0x71074af9),LL(0xb3e46e21,0x17f8ca53),LL(0x7796d98d,0x215b3c92),LL(0xd098831f,0x362429bd),LL(0x0b75e1e5,0x75d41b1b),LL(0xc1e2cba3,0x0101e963),LL(0xbf3622fb,0xa38f2cfe),L_(0x00000193), + LL(0xb9019f2f,0x646b70de),LL(0x2e533666,0x90a5717d),LL(0xd38f5274,0x7916810f),LL(0x3bb33bad,0xfd952623),LL(0x59b6b88e,0x5dad71c0),LL(0xfe6ed574,0xca300788),LL(0x21a98ac4,0x6ded4a6a),LL(0xeeff5891,0x7d6ffe10),L_(0x0000018d), LL(0x48da52e8,0x98c1a5fc),LL(0x1901e7d3,0x42b185c0),LL(0xcb2700b0,0xaca4eda6),LL(0xeec867cd,0x0a19ae4e),LL(0x7dcb7e93,0x88471dcc),LL(0x17e010a2,0x198ed175),LL(0xbb36f683,0xbb4e8756),LL(0xf915ed36,0x4cf9f27d),L_(0x00000007), + LL(0x56948883,0xfd191432),LL(0x519679d8,0xcdcf1fa3),LL(0x35711035,0x87a0e867),LL(0x663b1a45,0x6c52192e),LL(0xd46a0d9f,0xd90e9a02),LL(0x01cece65,0x0dbf88f7),LL(0x5032d5f7,0xd5855448),LL(0xc3ecbbe3,0x330d4483),L_(0x00000113), LL(0xda71595b,0x4bb4a8ce),LL(0x6609b74e,0x23abfae6),LL(0x76172b1d,0xc43ff5b4),LL(0xc2d69d21,0x275e500d),LL(0xf9af38b2,0x8ab54bd9),LL(0xe6a2d266,0x983f2f3c),LL(0xb11e43bc,0x0d27f996),LL(0x3ef88279,0x33f71741),L_(0x000000e5), + LL(0x9058183f,0xdd40e348),LL(0x8259229c,0x5e67db56),LL(0x8582282f,0xa5fd9ed5),LL(0xea641a1b,0x1a634c9e),LL(0x6d89c3eb,0x44359789),LL(0x3d617332,0xb7458f8e),LL(0x974b6efb,0xb6863988),LL(0xd2857c41,0xae43a38e),L_(0x00000046), LL(0xd0bd1dc8,0x08757c7c),LL(0x4edda34c,0x5a31fc77),LL(0xfa2bc7b5,0xf6b159cc),LL(0x36e4a532,0x904f6b01),LL(0x603edf4b,0x96a6ebff),LL(0xb699fdb4,0xad76014c),LL(0x888c04c9,0x52da1b11),LL(0x9675ab25,0x8c537551),L_(0x000000e1), + LL(0x76cc2e7a,0x23209d8a),LL(0x39ac3634,0x493f6e5e),LL(0x2a49b5d9,0xaac1e790),LL(0x83449f3c,0x85d5aef7),LL(0x919c353b,0x45144182),LL(0x9673a9fe,0xc1d4f2ca),LL(0x9f1f328f,0x8f5eeda5),LL(0xf2216169,0x611eca42),L_(0x000001dc), LL(0x3f509f9a,0x96feece0),LL(0x85e87ba8,0xe9be0b9b),LL(0x186dcdb0,0x7207011b),LL(0x590eaaa1,0x60f3a8d4),LL(0x3aeb9b3f,0xac89f276),LL(0xd21f7163,0xfd4e5813),LL(0x05998e42,0x80b7e4e3),LL(0x38cd8e87,0xe79a0406),L_(0x0000010c), + LL(0xc09d95ae,0xd6f73873),LL(0x7cafdfb9,0x27b3bc9e),LL(0x1f14d40f,0x6fc05fa8),LL(0x4eebf4e6,0x4e6b76ed),LL(0x7bb6036a,0x736cb738),LL(0x58e19e3f,0x2277b08a),LL(0xa4986beb,0xbb55c0d7),LL(0x8f830ada,0xa22d04d1),L_(0x00000057), LL(0xb25e59f9,0x9a3ae563),LL(0x18997059,0xd06e16bf),LL(0x7505891e,0x3d688dac),LL(0x76b3eb97,0x10cb084c),LL(0xc6498b2d,0x2d6e8e95),LL(0xafa574af,0x503f71b8),LL(0xc16133ca,0x9966999b),LL(0x6f3443fa,0x6ad79bd7),L_(0x00000104), + LL(0xa62c57f7,0x797a0980),LL(0x03e966f7,0x3a33197c),LL(0x5565e857,0x31df23bc),LL(0x1feaa7a8,0x240894a7),LL(0xec48825c,0x8f886413),LL(0x9a2b6b14,0x98c1f268),LL(0x041a9538,0x89254981),LL(0x46c27078,0xd4a923a7),L_(0x000001b7), LL(0x3f850405,0x16453f02),LL(0x5e4fd155,0xb6a3db9b),LL(0xcd6306e4,0xc259c564),LL(0x89b34c35,0x1cbd8b5f),LL(0x7420eabc,0x22f6885a),LL(0xfe106029,0x2bf9ec49),LL(0xaef5fd1c,0x73da5ef8),LL(0x01c0496b,0x2fbf80d0),L_(0x000000d2), + LL(0xccf43b6c,0x2b2fd87d),LL(0xb29b9f9b,0x42c15930),LL(0x75dead34,0x8a992ae9),LL(0x93d238f6,0x835b46d8),LL(0x537768fc,0x59b7cdac),LL(0x97a9b4f9,0x8690f7d0),LL(0xe523d489,0xddd3b40f),LL(0x2dcb85bf,0xd07f5307),L_(0x000000d7), LL(0x2a6612ff,0xa015a7b6),LL(0xc599e46f,0x72d01eaf),LL(0x9b23b6a1,0xc21d7f10),LL(0xdff644dc,0xac717daa),LL(0x215cc0c4,0x31113eff),LL(0x29fa625d,0x2da218c6),LL(0x3ddc80ac,0x8399eca4),LL(0x5d17f283,0xce8d5743),L_(0x00000053), + LL(0xfd958a4c,0x656636ff),LL(0x022fd87f,0x77efdadd),LL(0x3a9ac51c,0x96597b30),LL(0x2fbf14ce,0x01364596),LL(0x7d940bec,0x1f7b85dc),LL(0xbde90f3c,0x3116d774),LL(0x40e30d60,0x9289d920),LL(0x52c8b93a,0x02c341a8),L_(0x0000001e), LL(0x2ebd850f,0xa0eaa3d4),LL(0x590d1f54,0xbe22470c),LL(0x53e4e7c3,0xf88fc1e8),LL(0xd8883aaa,0x7782a946),LL(0xe78d366f,0x567fbeed),LL(0xf47e81a5,0xadd3d4f0),LL(0xb2aaddfe,0x29a661cf),LL(0xa342a4e6,0x748d5227),L_(0x0000007d), + LL(0x8c9cc5a1,0xe5aa101a),LL(0x329070ed,0x53342a7d),LL(0x852398fa,0x007bb4fe),LL(0x673ceb9c,0xa9431236),LL(0x3c9247b3,0x1cb68268),LL(0x115b1ee5,0x5c07f2ef),LL(0x3f6486b7,0x7183b014),LL(0x1585ec37,0xe601ad10),L_(0x000001fb), LL(0x0680da54,0x9a2e8c00),LL(0xe41a7e56,0xe94c0472),LL(0xb7c713ec,0xf2aa41c1),LL(0x742d18cc,0x3e3162e5),LL(0xedf3c376,0x77417a84),LL(0x57916b99,0x165b44c7),LL(0x246f2e2f,0x1c45d988),LL(0x8287828d,0x99db995c),L_(0x000001b0), + LL(0xab8f038d,0x27f0c816),LL(0xc4edbd37,0xc8522ec7),LL(0x2f8f0b54,0xe399477b),LL(0x074481dc,0x0fb69890),LL(0xa0499848,0xa5280b6b),LL(0x88cb4213,0x3dff5cd9),LL(0x41c11365,0xe549bd1e),LL(0xea8a3c58,0x40ee92fa),L_(0x00000039), LL(0x2b200b5c,0x2ec791da),LL(0xb1772087,0xb33233b1),LL(0x9df4451f,0xaa1032a0),LL(0xbaa72f9e,0x645358e3),LL(0xc7982461,0x88b9794b),LL(0xecd3c965,0xcecd6313),LL(0xa2d9359f,0xf7b6ca2d),LL(0x7f382df2,0x98e1c5ce),L_(0x00000033), + LL(0x02037c91,0x41a52ada),LL(0x82ddca3f,0x1b403720),LL(0x4b6a1108,0x6acc9873),LL(0x6d306779,0x495190be),LL(0x80fb3f34,0x13ec341a),LL(0x0307762f,0x2ea03fd7),LL(0x422a6d1a,0xfacb4f11),LL(0x014521e4,0x5f9816f6),L_(0x00000196), LL(0x0ac6d565,0xb343a25b),LL(0xdead79aa,0xf7c846e5),LL(0x54b1471e,0xccc5d545),LL(0xf9ccfd6a,0x31f5ccd5),LL(0x43e993a3,0x8fc6e767),LL(0x07c79ed2,0xd716a9ab),LL(0x4894cc48,0xae33e7f3),LL(0xd6c5646c,0x3fa06c4f),L_(0x0000010d), + LL(0x37b15d9b,0xc16b5265),LL(0x43945dbd,0x7a53a14b),LL(0x994df966,0xd272ba24),LL(0xfbfe62a0,0x80e0b451),LL(0xb488717c,0x7153f565),LL(0x22303a33,0x6397afa8),LL(0xc85bf638,0x0216bd4f),LL(0x096b646c,0x50f84189),L_(0x000000f4), LL(0xf00721ec,0x500e6e18),LL(0xab5ca93b,0xea2d8a0d),LL(0x06a3b0f0,0x44feaba9),LL(0xf766ff9a,0xea82aa95),LL(0x05be709f,0x0829c7c9),LL(0x36a07ae0,0xa1cfe409),LL(0xc83c032c,0x780ac746),LL(0xde7f9ef0,0xfedfbfdb),L_(0x000001e2), + LL(0x18f9c015,0x25767d44),LL(0x49d6199f,0x77c536b7),LL(0xb54e847b,0x1af54bfd),LL(0x7979776c,0x0b838623),LL(0x51eefa22,0xdf9bb4a7),LL(0x028f18ac,0xce45beb5),LL(0x7dd86218,0xb930f98a),LL(0x3f055e3a,0x6380d302),L_(0x000001fb), LL(0x1df321b7,0xeeb57c14),LL(0x53902659,0x0b2255cf),LL(0xf2a776fd,0x4cc9dbec),LL(0x453cf8ab,0x63e94ee6),LL(0xf2d56478,0x93a4007a),LL(0x027149fe,0x9cf116d0),LL(0xa6376053,0x17dc8184),LL(0xe7465f73,0xfed4461d),L_(0x00000058), +}, +/* digit=87 base_pwr=2^435 */ +{ + LL(0x6ea55f73,0xf042fa2f),LL(0xab1d226e,0xb24c1848),LL(0x6862a1dd,0x413acbe8),LL(0x1f4168e7,0x91408365),LL(0x9d596e07,0x23961d18),LL(0x01b379ca,0x6d536797),LL(0x05ec7b7e,0x13cf35fa),LL(0xd7f6b707,0x182dcd20),L_(0x0000009d), LL(0xbc18785b,0x76095f2d),LL(0xa0054386,0xe28a0370),LL(0x50c89610,0xfeeaf09e),LL(0x144bba0b,0x455cf10f),LL(0x34cf6dd7,0xf509d978),LL(0xf94fe722,0x05c279e5),LL(0x8092debb,0xe71244fe),LL(0xb314f061,0xe0f63153),L_(0x00000098), + LL(0x7f803868,0xeb771971),LL(0x05b4c2dd,0x911e1ad0),LL(0x0df34f87,0x57076f1e),LL(0x9958d5da,0x6f49ecb2),LL(0x55d1ebf6,0x2ca7b49e),LL(0xfcb4f571,0xb2ff1b32),LL(0x42a971c5,0x49f97d3d),LL(0x838bb327,0x5fd29804),L_(0x0000017f), LL(0xa52e7908,0x86529c3b),LL(0x7ddd9af7,0xe7159473),LL(0x6dd64d51,0x8305400f),LL(0x922bf016,0x21ca4239),LL(0x1db4bbaa,0x8c94ee85),LL(0xafda935d,0x80623440),LL(0x0a576c9c,0xd9110efc),LL(0xd79f58dc,0x3d6ca396),L_(0x000000f1), + LL(0xe1a7c929,0xeff94575),LL(0x7f265399,0x076c7864),LL(0xdf2046cc,0xfe889ff0),LL(0xe23267f8,0x4b83615e),LL(0x171f661f,0x32637340),LL(0xc3fd3e6c,0x946ccba9),LL(0xafb9463a,0x9deb55e5),LL(0xbdcb574f,0x8d44f742),L_(0x00000092), LL(0xd84d6148,0x6362d37c),LL(0xe1724e4e,0x80e307d8),LL(0x2dee8134,0xd661095b),LL(0x596062c6,0xbc1b3be1),LL(0x5779751a,0x36f36543),LL(0xd0be963f,0x7fee02b0),LL(0x75c65486,0xb82030d1),LL(0x72d27424,0x6d7f4a46),L_(0x00000043), + LL(0xaeb38ccc,0x49ee6062),LL(0xc1411d18,0x164333de),LL(0xa4a4727a,0x566e81b4),LL(0x74b241dc,0x290aa59c),LL(0x85069fb7,0x2865cb6d),LL(0x28389d32,0xcbd64839),LL(0xce3c8f7e,0x8c909864),LL(0xfef248d2,0xf2befac9),L_(0x0000013b), LL(0x4261d435,0xb96bec85),LL(0x62a6f5a6,0x1f509bbc),LL(0xb43f9c90,0xc53ddbc8),LL(0x94118466,0x9ad3885e),LL(0x22a38677,0xd109dd2e),LL(0x60b6db58,0xeef4f2af),LL(0xadf1adca,0xd5bc0cd7),LL(0x0fb47811,0xc4b3b822),L_(0x00000024), + LL(0x456d2584,0xca189af8),LL(0x85bb0ebb,0xf9e4ffa5),LL(0x3e647534,0x1136b7ab),LL(0x0e1d213d,0x91ac330c),LL(0x6aa7c7de,0x4345ad0a),LL(0xf0255a49,0xa156a357),LL(0xe3967bfd,0x2bdb3ace),LL(0x8dff208b,0xc09a53d8),L_(0x00000009), LL(0xad93b86d,0xff9685e0),LL(0x990e1837,0xd599bc9a),LL(0xa491c185,0x320375e6),LL(0x59cacf47,0x427b05e7),LL(0x03c76cd9,0x9565d0db),LL(0x073ece2e,0x72f50d14),LL(0x2045534c,0x31281552),LL(0xa43a812b,0xabec2314),L_(0x00000152), + LL(0x49f1b4d9,0xd4601e45),LL(0xd37e9635,0x5712ad28),LL(0x2c3143dd,0xaf7e19b4),LL(0xc6366f04,0xaa565afd),LL(0xc4b34637,0xc12b452b),LL(0xdd135b2a,0x77fe7f5b),LL(0xfeea8b42,0x9ec6ff31),LL(0x5cdaec8e,0x73ab00c4),L_(0x00000165), LL(0x3f781317,0x664c221b),LL(0x652c3e83,0xafac4ecd),LL(0x6da93d03,0xcfa7c466),LL(0x2ceac0d6,0x039d2b65),LL(0xcb1a4cf4,0xa6eb1946),LL(0xa2285c58,0x422c9b53),LL(0x1b4d8367,0xcc7349ed),LL(0x4c55a379,0xcd5e2afa),L_(0x00000106), + LL(0x85b7a89c,0x1ea7ad0b),LL(0x9f47c4ab,0xe5150449),LL(0x85cda5f6,0xb891dfa1),LL(0xe69386b4,0xd89edbbe),LL(0xf4ac48bb,0x1b2a00ae),LL(0x3c163ff2,0x37bb423a),LL(0x73d0c87f,0x393a234b),LL(0xe80b0fdc,0xc63497ac),L_(0x00000153), LL(0xc52fc82f,0xa9154aa9),LL(0xe56ec070,0xb5b87f0b),LL(0xb996ced1,0x2c118a27),LL(0xbb7f2dff,0x3e0161d2),LL(0x9ee991cd,0x45e9acd1),LL(0xb300f7d4,0xfb934e98),LL(0x20f357aa,0x370589a8),LL(0xfe8af1f8,0x7ca491b4),L_(0x00000106), + LL(0xb59ee173,0x42f467a4),LL(0x41b66fb9,0x5770a301),LL(0x02513df6,0xf1d41988),LL(0x7e0148f2,0xf54abf2c),LL(0xd9a1b6c6,0xbb47b51b),LL(0xfba956f2,0xf5846505),LL(0xb02618f4,0x502a3ddc),LL(0x69ec8c64,0x8021ca7b),L_(0x00000158), LL(0x194b6953,0x04316d8f),LL(0x8f7bcb08,0x006107c5),LL(0x9f43afd0,0x32f310f2),LL(0xa15ea5dc,0xe2b91ae7),LL(0x3849a363,0x2b4966c6),LL(0x6a457445,0x1d63455b),LL(0xb8835c17,0xcd39b535),LL(0x1ae86f54,0x52463509),L_(0x00000075), + LL(0x413915c5,0xd3aa0f40),LL(0x553e50ff,0xc139c1fd),LL(0x408079ac,0xcaeedf51),LL(0x5702513c,0xf43dc271),LL(0x1c08e5b0,0xf5e1208e),LL(0x48d91655,0x813375b3),LL(0x91b427b6,0x0fa6be8b),LL(0x833896b7,0xa0825ed0),L_(0x000001b9), LL(0x7c3676f3,0xac9ff585),LL(0x853930b5,0x94c9266b),LL(0xc6b73b6c,0xbc211c89),LL(0x277b6c8b,0x2fc248c5),LL(0x93fd3dec,0xcefb839e),LL(0x4a5c85d3,0x10bf217b),LL(0x2a276f95,0x3a708326),LL(0xc15a4206,0x85899d47),L_(0x0000017e), + LL(0x7bde1ec8,0x34c4db4a),LL(0xa70a6f08,0x48a29f6b),LL(0x587d1015,0x49dbe231),LL(0x998c9a20,0x8aceafbb),LL(0xe5eedcf8,0xe6b738f7),LL(0xcab08878,0x9b693ecf),LL(0xb374ede1,0x008dd1dd),LL(0x7a6cd94f,0x9b54b3be),L_(0x000000c2), LL(0x83bd130c,0xc20757ed),LL(0x17bff343,0x228e06b2),LL(0x1bef19ad,0xc51046a9),LL(0x0e88da5c,0x011b5840),LL(0x70a9f961,0x49ae6f04),LL(0xc6f83f90,0x9d079a03),LL(0x912f072e,0x9a401435),LL(0x0b78fe3f,0x45e24749),L_(0x0000002d), + LL(0x20b6a171,0xc0eec582),LL(0x531fdbd5,0x7a0400cc),LL(0xe2cd895a,0x9c308aa1),LL(0xf0bb2d5a,0x08b021d8),LL(0xde68db65,0xad0f2bcd),LL(0xac747060,0x3fd807ea),LL(0xfe64802d,0x8b4648ee),LL(0x38d8773a,0xf5c28376),L_(0x00000103), LL(0xcb637daf,0x16605703),LL(0xdffc80b5,0x4845eee4),LL(0xd28e60ca,0x57f98d2e),LL(0xdfda4fa3,0xac95f77a),LL(0x0d0b9220,0x05da7201),LL(0x60ec2cb7,0x9a49b6df),LL(0x201396c1,0x611b2a93),LL(0xb535c0ce,0xce6fc00f),L_(0x0000018b), + LL(0x1481fdff,0x68c14a66),LL(0x84edc501,0x764d4d2b),LL(0xbe356501,0x736aaa60),LL(0xe6771588,0x0c40e330),LL(0x5714d50c,0x7b8fe887),LL(0xfbdf2915,0x9215aac4),LL(0x549e25da,0x58b4091b),LL(0x442d2b00,0x48bf91ad),L_(0x000001e8), LL(0x88ee6a91,0x934568ba),LL(0x307efd84,0x10dd1585),LL(0xcb644b24,0x3219b046),LL(0x2bd376e1,0xef0c68dc),LL(0xdcecc49b,0x56c2d2d1),LL(0xc907f765,0x810f8810),LL(0x052b3ddd,0x1ba20da5),LL(0xc3448a3c,0x0827079e),L_(0x0000018b), + LL(0xb0648b7e,0x193cb76d),LL(0xf7fec768,0xb90f6558),LL(0x86126ace,0x237a7fc7),LL(0x749a6fe8,0x83ab837e),LL(0xb5c3035a,0x3e9ae2d9),LL(0x8de4bf68,0x9c620970),LL(0x0b3fa791,0x8ef69888),LL(0xc5e8388c,0x3a44205f),L_(0x00000013), LL(0x892086c5,0xc04ac82e),LL(0xfb491292,0xc0d38a50),LL(0x52d706d1,0x42c8a5e7),LL(0x582ce44e,0xc9853494),LL(0x96312a80,0x04da6643),LL(0x74ef5508,0xbbc8dc30),LL(0x9a8e3322,0xfa669919),LL(0xa1f29644,0x94a108d5),L_(0x0000011e), + LL(0x0e084366,0x5cc0a55e),LL(0x7ef0187f,0xa139c3fe),LL(0x49d53f7b,0x5423f2e7),LL(0xd809a727,0x5a94a4ff),LL(0xe2e74f9e,0x541f08d0),LL(0x22541929,0x14dd0793),LL(0x49159841,0xdbf53ad1),LL(0x408f5bb7,0xb5b9e78a),L_(0x000001e9), LL(0x1db74ade,0x46e28711),LL(0x3b22deeb,0x1ad3605f),LL(0x8863541b,0x1fe070fc),LL(0xfdd530f5,0x4af47e93),LL(0x7f3d69c0,0xd93cb647),LL(0x6d16f551,0xbc684cde),LL(0x50cd6852,0xb5154a9f),LL(0x16ac0cc2,0xc9ac9e9f),L_(0x000001bb), + LL(0xec5c2c31,0xc90def9a),LL(0xe4b46e4f,0x67d0d316),LL(0x8901b941,0x2bb65bec),LL(0xc96e5167,0xf836eba2),LL(0x096ab2fb,0x996167b5),LL(0x2719f2e6,0xdde8e72c),LL(0x12437287,0x62d48d9a),LL(0xf4ef64e5,0x405cdb88),L_(0x000000f0), LL(0x91da5b6b,0xa56f46e1),LL(0xc13b6841,0x97107435),LL(0xfbe3e2a6,0xa446c520),LL(0x759315a1,0x0c5bba8d),LL(0x861aec20,0x852f2659),LL(0x775fa0ec,0xfbe06684),LL(0xa91ab0fa,0x03bd8b0d),LL(0x3006d391,0x3166b023),L_(0x0000010d), + LL(0x1b6190bc,0xa4a386bf),LL(0x17c47de2,0x95703cbb),LL(0x3bf84891,0x3f013d22),LL(0x12474267,0x6fdb827a),LL(0x0290f2b8,0x50e9b7e1),LL(0x79a8f44e,0xcc658260),LL(0x89a9228e,0xab4d12b5),LL(0x83a119d1,0x121131b6),L_(0x0000019e), LL(0x2d25950f,0x6b02229a),LL(0x38c46b7a,0xfb0617d5),LL(0x6bc581dc,0x0ce1dd7b),LL(0x6b522d59,0xd0dcdf5b),LL(0x9133e3f5,0x5cce47e7),LL(0xd71f5bdf,0x21b8ecd0),LL(0x17d9aefe,0x7aac21b7),LL(0x7b609025,0x98c6eb88),L_(0x00000127), +}, +/* digit=88 base_pwr=2^440 */ +{ + LL(0xf89fcba2,0x59a63f98),LL(0x86d07ca3,0xf60025c0),LL(0x590915cb,0x68c18d4e),LL(0x15cc7c3b,0x85575ec9),LL(0x09334801,0xe8d10d82),LL(0x4789511a,0x82704b90),LL(0xdb2e76c0,0xf6a4e997),LL(0xf5824d99,0xb143d8c3),L_(0x0000006b), LL(0x6953628d,0xa7575550),LL(0x8504400e,0x8537e141),LL(0x609d8295,0xc7b7f7a0),LL(0x5da70118,0xc50379c5),LL(0x79ad1223,0xc936f6ea),LL(0xbde48629,0x4f7f839c),LL(0x1ba01725,0xdff8def6),LL(0x1bef09eb,0x65b93f5c),L_(0x0000011e), + LL(0xe82eeedc,0x330d665a),LL(0x0753a4f9,0x3f5e64a3),LL(0x9e477096,0xef9e92f3),LL(0x07f9d297,0x388062aa),LL(0xc48c3ddf,0x60ab0df5),LL(0x55e6e61e,0x5a47567e),LL(0x9872a6f9,0x3a66d012),LL(0x425f368c,0xc7e83953),L_(0x000000bf), LL(0x03b7cc7b,0xb2825eba),LL(0xba3cef16,0x90e67535),LL(0x4aec5704,0xcc34aef1),LL(0x511ac67b,0xd95c0e01),LL(0x51002739,0x0f4f3657),LL(0x45e92922,0x465557ab),LL(0x1baabf91,0x0e9abecf),LL(0x8337c976,0xdff48fe9),L_(0x000001ec), + LL(0xa1025751,0x6a01039d),LL(0x28499cde,0x5ba84622),LL(0x47232500,0x4da34907),LL(0x523417ab,0x54b07c1a),LL(0xd3451baf,0x3fa7e4ff),LL(0x7ce5516f,0x2fbff214),LL(0xfc522cc4,0xa33f1b0a),LL(0x95c7010c,0x664b5cb3),L_(0x000001a5), LL(0x665ed5f5,0x980e5684),LL(0xd596415b,0xa5a1b30b),LL(0x8834a37b,0xfeebb04e),LL(0xcf282494,0xb29d17be),LL(0x340dc6ce,0x8d5399a5),LL(0xa50f4a86,0x76012bce),LL(0x83faa312,0x4bc769aa),LL(0x6550a065,0xea38cd8e),L_(0x000000b5), + LL(0xec66fa0e,0x134a53f7),LL(0xa7b2871d,0x1ee39cda),LL(0x83070c04,0x9749b3f1),LL(0x6da77991,0x867841c7),LL(0xe916f1eb,0x21e5438a),LL(0xe409b274,0x1b0e12d8),LL(0x3842a6e5,0xde5e08b8),LL(0x74b9e008,0xb7828943),L_(0x000001e9), LL(0xfea4cba7,0x08e07acd),LL(0x06789133,0xdb2143a9),LL(0x815c887a,0x85ffe6dd),LL(0xa9d2043c,0xa68d05e2),LL(0xd3ceab79,0x93674d33),LL(0x7a8a9863,0x12ee73ca),LL(0xd54b7afd,0x6403b9bb),LL(0x2eead112,0x4c680b70),L_(0x000000c7), + LL(0xfa0b987f,0x67c06145),LL(0xfd55dd43,0x34438e79),LL(0xe8ca9c52,0xfad0f9f8),LL(0x810f12c2,0xa97a7136),LL(0xb3ec5af1,0x3d0eabab),LL(0xb7b58561,0xecb3da01),LL(0x8aadf26a,0xbb015079),LL(0x9cce9cad,0xf01aa802),L_(0x000000af), LL(0x265a72e5,0xd025e951),LL(0x90e3ddec,0x5b2c9143),LL(0x4955e972,0x05386478),LL(0xdae63ed0,0x60c28f8c),LL(0x4aa5ded8,0x0fb99e77),LL(0xb74c1dd8,0x0f07854b),LL(0x2caae0f2,0x6691581c),LL(0x069f6ba7,0x072c0d48),L_(0x00000087), + LL(0xf5f13583,0x8b738df6),LL(0xe91f4420,0x786c7341),LL(0x1ae2188a,0xda384ed9),LL(0x08e3293b,0x19b1a00b),LL(0x9e09af31,0x65267666),LL(0x322f3662,0xd07b9f37),LL(0x764ea40f,0x11ae129d),LL(0xc16a911b,0x4cc8fb85),L_(0x000000c2), LL(0x59021aec,0xeb3197c7),LL(0x4daed80e,0xdfd4a433),LL(0x606234ad,0xab3ff78d),LL(0xf98a1d73,0x9f90a43f),LL(0x2c9cac66,0x99bed176),LL(0x5e8063cf,0x8f03fcd4),LL(0x50672a22,0xfdb17bf7),LL(0x027e080b,0x5a317879),L_(0x0000012b), + LL(0x236a647c,0x5dafe047),LL(0x30081d74,0xc3212b4d),LL(0x0f548f13,0x51f94578),LL(0xd885e14f,0x941059a0),LL(0x06ed3092,0x189c478f),LL(0x5042651e,0x7a26e8c7),LL(0xf36b6ee0,0x09a14b52),LL(0x32dfdec0,0xf1c461a0),L_(0x000001f9), LL(0xbe8ca673,0x527f0a50),LL(0x4c6beb6f,0xadaba76e),LL(0xfc7fd1fd,0x9909b987),LL(0x47c90091,0x992155a0),LL(0x06d6f45b,0x2da697e0),LL(0x740de37e,0x1a38bcd1),LL(0xce3867f1,0x509b93e8),LL(0x503be8b2,0xd6b05b60),L_(0x000000f3), + LL(0xe8c16ca7,0x4d3bbd16),LL(0x519f4d4b,0x53785c45),LL(0x6454947e,0x1aafab77),LL(0xd9b9416f,0x6883b419),LL(0xb337e34e,0x0208ba8a),LL(0x7e584157,0xab67774a),LL(0x5a84d18c,0x108ac516),LL(0x77b69d31,0x73bc43a9),L_(0x00000035), LL(0x91e5bcfd,0xcd5e892a),LL(0x5aa27743,0x502744c8),LL(0xa0414bf5,0xe26bb91b),LL(0xbc4ef773,0x8bcd45f8),LL(0x8f9e301b,0x3589038c),LL(0x30d42898,0x9a5f5e5a),LL(0xa609f771,0xaf5c6671),LL(0xade09eb4,0x5287fa3a),L_(0x000000ca), + LL(0x775485ec,0xf826fcc0),LL(0xa66e99e3,0xfac7759b),LL(0x6006cfb6,0x13b284ca),LL(0x1fbb2a30,0x53d194ad),LL(0x2c2b6910,0xf54ebb36),LL(0xa49dd337,0x46a6edea),LL(0x8fc79498,0x0d6aff86),LL(0x842dc894,0x9d7094f6),L_(0x00000050), LL(0x34121245,0xb4cfd050),LL(0xafb75e83,0xaf8c43b1),LL(0x77a38e5e,0x4ff38619),LL(0xe7485f16,0xfa745e75),LL(0x7e4f2466,0xcdc30bb6),LL(0x009d4a36,0x9994c740),LL(0x25e09cb4,0x66ca76f4),LL(0xf59131dd,0x95b4239e),L_(0x0000012a), + LL(0x6edaa49d,0x0aa308ea),LL(0x7669b865,0x72c7a072),LL(0xf06e514b,0xa7ddba09),LL(0xca616052,0x126487b0),LL(0xd64c8323,0x713cc701),LL(0xb7fd1abe,0x84ce35d3),LL(0x7bfbc16b,0xba894fdd),LL(0xba61b8c2,0xe784d69f),L_(0x000000ee), LL(0x18d74478,0xa66248c8),LL(0x62b773bd,0x3c1ca3e3),LL(0xde584f76,0x5c3541fa),LL(0x475ec797,0xe7fdfe89),LL(0xd692c26f,0xe8463461),LL(0xe888fcbd,0x682f9099),LL(0x1a8aba10,0x0ae8eea4),LL(0x2cc79e0c,0x479936cc),L_(0x0000004f), + LL(0x901772ff,0x6d000499),LL(0x481b7323,0xb7a27eb4),LL(0x69fc5685,0x4a7abcd1),LL(0x47ec07ac,0xcde4a9ac),LL(0x56f5f84a,0x45545bfb),LL(0x6ef7da38,0x33e7eca8),LL(0x2edec324,0xd8a46ddf),LL(0xd29093de,0xb5fd7555),L_(0x0000005d), LL(0x163bac52,0xbeecc923),LL(0x637f0966,0x0af4893a),LL(0x1759af91,0x1d38f097),LL(0xe0aea79f,0xf9d81651),LL(0x8ae541b7,0x510d4c3c),LL(0x32bd0e43,0xd73faaea),LL(0x6891a73c,0x3864a690),LL(0x6feafb02,0xbd306219),L_(0x00000129), + LL(0xa0c16a35,0xb6681c57),LL(0x415f0571,0xb2c83a60),LL(0xcfe1f331,0x4b9088d9),LL(0x1279d3aa,0x2ab5f2f1),LL(0x29c29c20,0xd47ee149),LL(0x16735420,0xfbb44304),LL(0xb8379216,0x23034403),LL(0x20a6f133,0x9f2bb4aa),L_(0x000001d5), LL(0xe0a94e50,0x38217da2),LL(0x2ba297d2,0x18816b2c),LL(0xe566aa72,0xca63550f),LL(0x1c7b21ca,0xdfe51644),LL(0x10c887fa,0xef849ed8),LL(0x4faeda58,0xb92e8367),LL(0x03636294,0x2414c0ef),LL(0x8476a050,0x732173ab),L_(0x00000184), + LL(0x93412483,0x9f53d923),LL(0x4403bdcc,0xe30fa97e),LL(0x6c9d0aa5,0x1601e86b),LL(0x9c1a2ec2,0x19610105),LL(0x431d5f14,0x6cc0662b),LL(0xb7bbdb4e,0x84ed40f8),LL(0x266aca0a,0x1b8a27f1),LL(0x198bae2a,0xded16036),L_(0x000001fa), LL(0x33afa5e4,0x023ed8a6),LL(0x8523afba,0x036adaa0),LL(0x83cbabb2,0xf5cebadd),LL(0xac3f99aa,0x20899c44),LL(0xca5f46cf,0x0e94933a),LL(0x7a04e2c1,0x9a3fee46),LL(0xb0015196,0x367a01a4),LL(0x1715a693,0xa13cc41d),L_(0x0000012a), + LL(0xc2d951af,0xd89fbf0d),LL(0x4488a068,0x172ac7ad),LL(0x7772ecaa,0x0409a3f1),LL(0xf7780ac8,0x6d541e69),LL(0x6ffa0a05,0x4e8fccac),LL(0x7509c471,0xeff8ec93),LL(0x018bbf89,0x101b9048),LL(0x2b2d5626,0x5365cf02),L_(0x00000168), LL(0xbd338134,0xda4a1896),LL(0xaeb1aa9a,0xdfd1cb54),LL(0xc0b310a4,0xeea1a455),LL(0xbed91e2c,0xaae7927d),LL(0xd3502cea,0xdfdf4808),LL(0xd31ee1ce,0xecc68f6a),LL(0x893f08dc,0x9350fda5),LL(0x2a6f281d,0x6394d514),L_(0x00000097), + LL(0xd5d022dc,0x6e654db2),LL(0xe4aaf49d,0xaa763047),LL(0x24820282,0xfe8aa2dd),LL(0xef229292,0xb7ff78ba),LL(0x0170b38f,0xe0a88558),LL(0x0aca63f0,0x66a526d3),LL(0x97a4873e,0xc069b5d3),LL(0x28c88b56,0xf066bff1),L_(0x00000169), LL(0xa3de237d,0xb57187d4),LL(0x20e27844,0x59762170),LL(0xf8485db5,0xf8fe71f6),LL(0x47186213,0xccceb1f1),LL(0x3ddfa68a,0xe9e1e35a),LL(0x3805a749,0x048090bc),LL(0xeea89d03,0xd04309c8),LL(0x451591c1,0x0e6409d8),L_(0x00000167), + LL(0x2e8fa162,0x86c08a44),LL(0xb15f83f4,0xd94f9cd2),LL(0x50bb6a89,0x7bbf2a23),LL(0x606cc572,0x74b1325b),LL(0xb03f198a,0x73b79d3a),LL(0xcf731a6f,0xc95046a9),LL(0x298efd11,0x095ed71e),LL(0xd622bb24,0xb7ec1274),L_(0x000001c1), LL(0x08c383b3,0xb2f19275),LL(0xe14dee81,0x0d888be6),LL(0xce4b12e8,0x213fb612),LL(0x78248f53,0x43092c13),LL(0x4330dbca,0xe40c52b2),LL(0x952b9ef5,0x9d869889),LL(0x31f1126e,0xfbc05f41),LL(0xfd03ae1d,0x3d5c2503),L_(0x0000016b), +}, +/* digit=89 base_pwr=2^445 */ +{ + LL(0x6e868b8b,0x244e266c),LL(0x05a4369e,0x7c7bf40b),LL(0xe296776b,0xaed3b7e1),LL(0x2cfd9c18,0xddbc31e2),LL(0x1ea90d63,0x98abb7bc),LL(0xe50b9291,0x791f36a5),LL(0xc2f87e55,0xfe737c71),LL(0x75c6d8e7,0xfa3c624f),L_(0x0000017b), LL(0xd54c9eb7,0xa0fb486a),LL(0x91d1e1e1,0xd820f02c),LL(0x9160a67f,0xe5d16017),LL(0xf1163f25,0x8b61c557),LL(0xfcbc9a92,0x84ed79f2),LL(0x6a33df9b,0x54ba6955),LL(0xc8febe18,0x43c5cb8a),LL(0xec5a3443,0x2d5af9a7),L_(0x000001ab), + LL(0xa725a8ec,0x5828c615),LL(0xf603a049,0xac113424),LL(0x87a77e81,0x34642c16),LL(0x761c2762,0x9d0db298),LL(0x29b1a474,0x8ac3391f),LL(0x143a9782,0x050c5b69),LL(0x5ae00925,0xc578b0a2),LL(0x144730ed,0x6de2bd6c),L_(0x000001de), LL(0x3bbfa384,0x606aeb93),LL(0x6e3daf55,0x97e41356),LL(0x4263527e,0x4ac1c1ae),LL(0x3a037893,0x8c336382),LL(0xb2143f58,0x2bb7d997),LL(0x69412726,0x2419935b),LL(0x9cb555c8,0x724eeef9),LL(0x2ef7f7cb,0xc86f89b8),L_(0x0000009c), + LL(0xf81335ca,0xd6526151),LL(0x999ff056,0x3c494f0f),LL(0x0a7433ca,0x41b82dc1),LL(0x7fa3bcdc,0x9af11e06),LL(0xec803bb3,0x0ac7bb35),LL(0x457b31fc,0xb5e185aa),LL(0xed555915,0x586ab2cb),LL(0x33044819,0x7928ec97),L_(0x0000008c), LL(0xbfc07b3b,0xae813666),LL(0x4f0a957b,0x8eee1f42),LL(0x82cf0958,0xc3321225),LL(0x4daeb7bd,0x458ec031),LL(0xe4de4e23,0xd0f97884),LL(0xfc50a768,0x1655c201),LL(0xb424f36a,0x14f1a537),LL(0x0cdff481,0x24211a6c),L_(0x00000042), + LL(0x22f8cb24,0xf131c203),LL(0x0c2b076a,0x815ccfff),LL(0xf056364e,0xdbdfbdbf),LL(0xc8028853,0x41ab5760),LL(0x8af0ee08,0xca93ac08),LL(0x3094da56,0x30135092),LL(0x5054010d,0x74228a25),LL(0x8e7dde67,0x6c6f6a05),L_(0x000001e7), LL(0x8a5176aa,0x3779fd86),LL(0xbe16420d,0x7658fb3d),LL(0x41f45c5c,0x110cf130),LL(0x49dea64d,0x19e0e350),LL(0x73f6746e,0x87ca4575),LL(0xfe7da390,0x108ab4e2),LL(0x874c5458,0xe39cce4e),LL(0x1d64965c,0xa2587b79),L_(0x000000b8), + LL(0xfa76cb01,0x80465e82),LL(0x38560d7e,0xf4fd03ea),LL(0xa649c8ff,0x150b3815),LL(0x72398c4a,0xc0e6baed),LL(0x1ba3da88,0xfa79ad8b),LL(0x6f43120b,0x8353fc42),LL(0xbd32e2fe,0x7dbd7876),LL(0x148c548b,0x13391dd9),L_(0x0000016e), LL(0x18cf351b,0x9ca7db2a),LL(0x80485f13,0x16240b9e),LL(0xdfdb85c4,0xc2dc15ee),LL(0xbb4121d8,0xcce3d597),LL(0x0e963371,0xafb37db7),LL(0x7c69e287,0xed3b5fd8),LL(0x6c8d52b6,0x608eaea5),LL(0x053f2384,0xa9384b65),L_(0x000001d4), + LL(0xbbf62c47,0x1eac543b),LL(0x11eca801,0x4e45d301),LL(0x682f5663,0x054cb071),LL(0xe9473698,0xf1ad1950),LL(0x860a714e,0xa8a339c8),LL(0x96d39034,0xe04ab8cd),LL(0xde22b09f,0x2a845e02),LL(0xdfec2116,0xbfc189e6),L_(0x000000c4), LL(0xeaca7b49,0x3e7c928e),LL(0xb0fcae9a,0xca8b3e2f),LL(0xc41fdaef,0x9529863b),LL(0xe1843977,0xd56a624a),LL(0xee7e83a7,0x3438606a),LL(0x81db821d,0x06cdb198),LL(0x3aa0eeb4,0x9b12775b),LL(0xe0d60750,0xa667b1da),L_(0x00000155), + LL(0xbe8e1de1,0x9b0a79d8),LL(0xc345fcdd,0x77d93da0),LL(0xb2f5a213,0x7028f9ce),LL(0x800fcc19,0x1306f2ff),LL(0x469efe59,0x4cd68bf6),LL(0xc5ffe046,0x62b03f93),LL(0x53010575,0x5af4940d),LL(0x46961f0f,0xe96e1d71),L_(0x00000163), LL(0xad6952b3,0x9045b751),LL(0x43f410dc,0x217ebd7d),LL(0x0d11a22c,0x6ddeefda),LL(0x6d1775a7,0x43965993),LL(0x055c0203,0xe7060f57),LL(0x3548b71e,0xa89da1f0),LL(0x805eb428,0x6f8231a6),LL(0xf7b78a97,0x975110f7),L_(0x0000006a), + LL(0xcf1f7c72,0xe247b483),LL(0x97b6bf76,0x202781dc),LL(0xc0f81747,0x8b65bb58),LL(0x92efba88,0x9611a60c),LL(0xd9612af5,0xaf54a57c),LL(0x20d7ccbe,0xf8689ba5),LL(0x6d3cbf9e,0x0591cc36),LL(0xdc1abfe9,0x6d0aa056),L_(0x00000166), LL(0xd4a04bec,0x1e600b02),LL(0x2a15021b,0x6c3ebe8f),LL(0x9586be60,0xb8507cfe),LL(0xf4028af5,0x54dda762),LL(0x4d392e89,0x519d3758),LL(0xbde8dadc,0x58c3813e),LL(0x81db641b,0x91557ce6),LL(0x23fa3b99,0xa7128063),L_(0x0000019a), + LL(0x51bb00fd,0x32b04d9e),LL(0x8aefebe4,0x22b78b18),LL(0x8698b63c,0x7da3c01d),LL(0xa71b8bc0,0x8d71ee46),LL(0x27b7a39c,0xb0583313),LL(0xbd156109,0x49d2846e),LL(0x931258ab,0x86e6af4e),LL(0x3ca87258,0x07bd42b6),L_(0x00000076), LL(0x79f7c689,0x39041060),LL(0x6229b813,0x9028538d),LL(0x3a4aa59f,0x517bfaf7),LL(0x2d1cb542,0x71d33bc2),LL(0x882030de,0x9ba76285),LL(0x91ba5fcd,0x25f86ca8),LL(0x9ae0fc6d,0x47f08f0a),LL(0x3948678f,0x3c9bee89),L_(0x00000085), + LL(0xcd9eb593,0x18cd9b8b),LL(0xac677eb2,0x0d8705ef),LL(0x6b203fcc,0x934fa783),LL(0x39fcfd85,0x571b28eb),LL(0x58bd6d8e,0xd8f1d221),LL(0x215fad4b,0x3e44e705),LL(0x827adc24,0x5ff00393),LL(0x1ec35c0f,0x853889ac),L_(0x00000045), LL(0x14fc0a02,0x5fce2e10),LL(0x71f9384c,0xf0f2ac5b),LL(0x90d699f4,0x7b00891b),LL(0x43b6bcdf,0xe8c4a652),LL(0x7bc04d87,0x0ac9f698),LL(0x2ab126b5,0x3eb3d860),LL(0x849b38d0,0x426d6e94),LL(0xb6985535,0x102cbacf),L_(0x0000018b), + LL(0x0725d65d,0x1183558e),LL(0xb6a14f9d,0x44070253),LL(0x20d9075f,0x6c243902),LL(0x486b1799,0x6c1a9d8a),LL(0xf5efa075,0x8ae5a14e),LL(0x4ea72292,0x2d7b9c93),LL(0x0ca5c12a,0x992cae02),LL(0x91e3345c,0x2c11f45b),L_(0x000001d1), LL(0xc89bcdf7,0xd10410ec),LL(0x89966bf7,0xcf680bd5),LL(0x6ee731b3,0xa0c3db72),LL(0xe37f14f5,0x2aa5a376),LL(0xf554bdb7,0x23be47dd),LL(0xef1712c3,0x96ab9b1d),LL(0x1c7594e0,0x9ed66d28),LL(0x032ce687,0xd712923d),L_(0x00000060), + LL(0x9e3351dd,0x68d68f89),LL(0x9fb7334d,0x40ebf359),LL(0xc5209aaa,0x120177c0),LL(0xe5d00b75,0x2f0e6bbb),LL(0xbf188e69,0x110d2427),LL(0x8e2e5213,0xd6344a1b),LL(0xdcf577cf,0xa7331f94),LL(0x3c553feb,0xa2dfcf3c),L_(0x00000190), LL(0x795a2fa2,0x524f4a9f),LL(0x6609f22b,0x6b23609b),LL(0x2c95b3f8,0x0500bc47),LL(0x8df999a3,0x042c79e9),LL(0x9db59925,0x12a07a8b),LL(0x55be1532,0x07f62419),LL(0x33c89540,0x8df78722),LL(0xfe671ad7,0xe8b1f741),L_(0x000000c9), + LL(0x18059a16,0x52e9bed4),LL(0x717c36f7,0x49d5e825),LL(0xb56dd6dd,0x7783b6cd),LL(0x667fac4c,0xcf53b558),LL(0x116a1985,0x7c15cf14),LL(0x9913c6ee,0xe08410c5),LL(0x6728a2a4,0x9d771edb),LL(0x331fb13d,0x190212be),L_(0x000001c7), LL(0x394ecd2b,0x8da76d72),LL(0x341e75ff,0xf52f78d6),LL(0x29ea6d71,0x46d211ab),LL(0xaf402bfc,0x386ae83b),LL(0x7e9586dd,0x909f5bf1),LL(0x11c7f555,0x1b8a537f),LL(0x427868fe,0xcf05f9d7),LL(0x32daf130,0x60d32255),L_(0x00000069), + LL(0x4ef2bfbd,0x360e62a2),LL(0xc1081697,0xa6a207aa),LL(0x28d01fdb,0x18abc7ac),LL(0x204fc30b,0xbcff0be1),LL(0xe5cdb570,0x48ef40e1),LL(0x1f0b1c2e,0xeb79790f),LL(0x63136e14,0x3d4fe961),LL(0xb9d45c94,0xa355bb40),L_(0x0000018b), LL(0xa61088da,0x8938b0fa),LL(0xb39c86bd,0xc33f1d7c),LL(0xa2380177,0x530d6911),LL(0xaab3667d,0x7b52bed9),LL(0xd815d83b,0x5c596749),LL(0x44b95fe0,0x5148c157),LL(0x202c91ff,0x406b7485),LL(0x8bf24d49,0xa2828406),L_(0x000000f3), + LL(0xd37bc919,0xe29da36d),LL(0x00b56fef,0x7458f713),LL(0x8621718f,0x286883b4),LL(0x448b7c11,0x363d4ba5),LL(0x6114fd6e,0x04011c7c),LL(0x0d4b7500,0xe765f7ee),LL(0x491c6545,0xc2b827eb),LL(0xd01f3320,0x11a3a7f5),L_(0x000001f0), LL(0x6902bd96,0xda599389),LL(0xe2b47365,0xfe7e3528),LL(0xe9079def,0x3aa4556e),LL(0xc96d3bc8,0x610e35fb),LL(0xb585febd,0xa0b2ea82),LL(0x70988a63,0x60d1db4d),LL(0xd27f19aa,0x6eee4c02),LL(0x248d0f40,0x9a820473),L_(0x0000008c), + LL(0xba327209,0x4da0ba85),LL(0xfac1ed29,0x2e3b7145),LL(0x48cf218d,0x5cbfef12),LL(0xde112f17,0x76f3e234),LL(0x194a8f16,0x65787086),LL(0xde1af9c2,0x18958d56),LL(0x495c76a5,0xdd3dbcba),LL(0xa5e9c9c9,0xfc23acbf),L_(0x00000142), LL(0xb1fcebaf,0x30a1b712),LL(0x73d82709,0x8296f1f2),LL(0xfa6e1f41,0x5ef71edd),LL(0x7dd19081,0xc4a2f8af),LL(0x2f6fda9b,0x85b1234b),LL(0x541a4825,0x23556036),LL(0x79e6b22e,0x911ac1cc),LL(0x88ea71f9,0xe3d2a799),L_(0x000001f3), +}, +/* digit=90 base_pwr=2^450 */ +{ + LL(0xa22cc5d8,0x8ee779a0),LL(0x5dd5d86c,0xfd215954),LL(0xfd5e2c81,0xab1c7262),LL(0x75f13cf7,0x4f36ad82),LL(0xe759a0b7,0x8c3ddc91),LL(0xd2223c0c,0x10948a51),LL(0x9b2c7f7d,0x977160cf),LL(0x285822b5,0xddf4960f),L_(0x000001b0), LL(0x1a1e9623,0xd7c127ef),LL(0x7e5e2b50,0xd984c528),LL(0x3999dfdf,0xaad5ce7d),LL(0xd1373907,0x5c84726f),LL(0x97f8f082,0x5ebbc32d),LL(0x68dcb5c5,0xbd51b3a0),LL(0xa1b4f592,0x36935287),LL(0xf3eb9dca,0x0a3866c8),L_(0x00000125), + LL(0x95c0c51d,0xdbb76844),LL(0x7bb768dd,0x35dbc45f),LL(0xeda49098,0x39df9e6d),LL(0x3639006a,0x47f77ee7),LL(0xd878e5a2,0xd141b2c8),LL(0x2c8ccd83,0x04a47e33),LL(0x2d4027f8,0x2c9dc7a0),LL(0x9934bb00,0xf2cf7b1b),L_(0x000000ad), LL(0x8d777a83,0xd9919c1d),LL(0x0f685368,0x9dd72165),LL(0x892863f1,0x2a92b1de),LL(0x8f2b25a3,0x90ff3dd7),LL(0x12a43206,0xaf7bb8bc),LL(0xe03505a4,0xd763efcf),LL(0xcf4f256c,0x53701c70),LL(0xef267753,0xfc008443),L_(0x0000011d), + LL(0xecb197aa,0x593ffafe),LL(0xdd6e37e8,0x40fd5b94),LL(0x41331e2a,0x298fef4f),LL(0x60fb849c,0xfd38fb42),LL(0x7e149e93,0xe83fe7b3),LL(0x22e02e59,0x5d08e682),LL(0x58b84ec3,0xcaa4bfd0),LL(0x7f8e6b6a,0x506a3a04),L_(0x000001ec), LL(0x89faa591,0x3bdb5b23),LL(0x6e000f52,0xa824fd00),LL(0x630a4795,0xcbf7e717),LL(0x4e000837,0xc37102e6),LL(0x5656508a,0x40d36c3a),LL(0xe0b06b84,0x0a694f94),LL(0xd89beeae,0x647088c8),LL(0x682c3563,0x914b3bd9),L_(0x00000187), + LL(0x49e0800c,0xd1b7504d),LL(0x59ebe077,0x04fd80e1),LL(0x714afb4f,0x90ea18a8),LL(0x28810d8b,0xf02c3cde),LL(0x719cff83,0x19367a86),LL(0x8786eb9e,0x952bac43),LL(0xecceb4e9,0x460e0748),LL(0x55aefa66,0x440aefaa),L_(0x000001a8), LL(0x7aaa315b,0x44f96e09),LL(0x7a5db2b5,0x5dae237e),LL(0xa9362519,0x163873d0),LL(0x69799223,0x4d0fbf55),LL(0xc1a58ea8,0xd3bb728a),LL(0x661ed43f,0x100cfe43),LL(0xf1cd21af,0xa24f55c6),LL(0x25dcbe9f,0x4c47c918),L_(0x0000003e), + LL(0x5ef36acd,0xd5225f3c),LL(0x5770b7a0,0x90f00a62),LL(0xebdaa1b7,0xc0ab750b),LL(0x1bcb88b8,0x4d9be029),LL(0x06bbf584,0x9dfcba75),LL(0x606f29fe,0x74e426d7),LL(0xd113e261,0x2931cda9),LL(0x0453e382,0x7c891656),L_(0x00000067), LL(0xba1e3830,0x95a907f6),LL(0x1922ca15,0x760c0c2f),LL(0x24719cf1,0x383ccd2c),LL(0x11f794fe,0xa0495e03),LL(0xaf40e690,0x3eba817e),LL(0x1fab7cdd,0xa83e8359),LL(0x9846062a,0x737b3c03),LL(0x52241afa,0xe4f9dc5b),L_(0x00000056), + LL(0x2d0ad5b6,0x49587f7b),LL(0x321154b0,0x12ada5b1),LL(0xdc3aa007,0x0fe792e5),LL(0xf996b5f9,0x0e4944ed),LL(0x8197e83f,0x06340a72),LL(0x6a72b742,0xb3002f8a),LL(0xbc8a8319,0x173328b5),LL(0x81f8ab11,0xfdfa8b39),L_(0x000000e8), LL(0x2774c6fa,0xbe5f49f5),LL(0x674e04ad,0x8fbf7faa),LL(0xe6de1313,0x5724658c),LL(0x38fee508,0x6a0cb3e6),LL(0xeb3e2c17,0x24438695),LL(0xe7eaef00,0x43ac8a73),LL(0x4dc94b9f,0xd190f6ea),LL(0x422b705b,0x9011e9cd),L_(0x0000012c), + LL(0xd43e3b34,0x02b39b5b),LL(0xd46524f2,0xabfa1c64),LL(0xa4dd7015,0x8ec6eade),LL(0xfac38f67,0x78cba481),LL(0x1123582f,0x61a4550d),LL(0x1caa4894,0x42f7ada2),LL(0x83747c68,0x17f7f74c),LL(0xffb17df5,0xaae24930),L_(0x00000037), LL(0xeb2b93af,0x7f0ef78c),LL(0xcf301d2b,0x8e9f267c),LL(0x8e246b2f,0xb4a2acd2),LL(0x2035c962,0x50846229),LL(0x97e899e6,0xe23609a5),LL(0xfbcb2b53,0x1483eb63),LL(0xfc3f203e,0x4d6ddbe6),LL(0x2861a320,0xc8f76239),L_(0x00000005), + LL(0x41fc794a,0xffcd84d6),LL(0xf5985a4a,0x5082ece4),LL(0xcf3bb3f4,0x850b4853),LL(0xb1d8af65,0x670d980b),LL(0x6953dc3e,0xf579458a),LL(0x7963424e,0xac2f2e4a),LL(0x540b6858,0x920d771e),LL(0x1f5fed22,0xb1aeb9be),L_(0x000000b0), LL(0x731be223,0x662c4dc5),LL(0x1419cfbb,0xa5701752),LL(0xd65099ca,0xfbcc0240),LL(0x3af88f3b,0x1643acb1),LL(0xfbc4861e,0x67405bcd),LL(0x35f067ed,0x9351f1c8),LL(0xcb8018ed,0xeed0e188),LL(0xd276f971,0x0c95e1f8),L_(0x00000189), + LL(0x8cc00e47,0xd167d662),LL(0x311413fa,0xb1947f2a),LL(0x68fd100f,0xc373b68f),LL(0xd96895d1,0x259f8c2b),LL(0xb6277660,0x495d6470),LL(0x6dd59691,0x9eee1f91),LL(0x8e4a7fc7,0x1b01dab7),LL(0xf1319245,0xe946229c),L_(0x000000f2), LL(0x3751b5a9,0xb3dd751f),LL(0x352c6ed0,0x36c470b2),LL(0xbb64e49d,0x58925906),LL(0x5b0b62a0,0x9089d01b),LL(0xe64e7de4,0xf631915c),LL(0xcd161d83,0xfa1f87e7),LL(0x44c46466,0xcced2cc6),LL(0xec7eb165,0xfc7d0b25),L_(0x0000005d), + LL(0x0360b595,0xc1265889),LL(0x3fa41625,0x9e6d3563),LL(0xa19100cb,0x10accaeb),LL(0xaec86fbb,0x7b3f3d8a),LL(0x80771b15,0xdb2ccbe9),LL(0x803f9c49,0x07a460fa),LL(0xf34e5b14,0x4b602490),LL(0x6a99a6e6,0xb0145e5d),L_(0x000001b4), LL(0x308acd32,0x65b0ad8e),LL(0x3dceea03,0x13ece697),LL(0xe1bef19b,0x0643badc),LL(0x4cbdd893,0x470bd8ab),LL(0xafc33073,0x39f6bceb),LL(0x17b3cfed,0xf3aad086),LL(0x198868e1,0x0e329726),LL(0x9f6251f8,0xac5be216),L_(0x0000008e), + LL(0x2c636d48,0xd1bce1b0),LL(0x51f92c94,0x1ad3a1e4),LL(0x88368755,0x9be2c281),LL(0xd8124a18,0xe3a680f7),LL(0x9e5bc7e6,0x5e952f4f),LL(0x2fefbd16,0x5cef9135),LL(0x19b6c616,0x5576fffd),LL(0xbf997c16,0x21c0e1f9),L_(0x00000052), LL(0x01681747,0xdbf38f7d),LL(0x00a3bfc8,0x549f1e54),LL(0x39cded9a,0x23fdd541),LL(0x8b94ded9,0x89eeca5b),LL(0xfd084a5a,0x5123eaa5),LL(0x834be49d,0xae42403e),LL(0x02444c83,0x25abfb57),LL(0xbcb65841,0xc8736491),L_(0x000000f7), + LL(0x606a9e44,0x91ee418d),LL(0xd2dd052e,0x7e5ea0e7),LL(0x92e787f3,0x69d6f73c),LL(0x4508ea48,0xfe248ecc),LL(0xa2d461ac,0x529ffcc1),LL(0x22dcbd24,0xf90dc5dc),LL(0xa3364562,0x542f8abb),LL(0xd254e4f9,0x43e7b56c),L_(0x0000012c), LL(0x990aa036,0xc4f4234a),LL(0xb59ee2ed,0x1031cef9),LL(0xd5d4b081,0x984145d5),LL(0xdf2c037b,0xc7b07787),LL(0x2a2d6af2,0x31d56853),LL(0x6d5e6ff4,0x309a7c9b),LL(0xbb40c66e,0xda6a3ee9),LL(0xaf9db41c,0x4c5f4c81),L_(0x00000180), + LL(0x2ab124d1,0xf806ef78),LL(0x2f7a4e31,0x0cea295c),LL(0x32a4553d,0x8a3bdbfd),LL(0x19971283,0x3b9e4766),LL(0x8810a423,0xcdcf9f57),LL(0x8e85dc85,0x020a6262),LL(0x129bd8b1,0xbc50d2d2),LL(0x9a64395d,0x3517c068),L_(0x0000012b), LL(0xde8938c9,0x2bd0d178),LL(0xb0b45608,0xde7e99ed),LL(0x36896362,0x3851afd1),LL(0xe2cc94c2,0xdfbefd8a),LL(0x14aa57ae,0x3c1abef1),LL(0xd8652bb1,0x0cc39736),LL(0xaf001e99,0x72b91536),LL(0x9fdf9a10,0x4f614f57),L_(0x000000b6), + LL(0x4403c833,0x48e45088),LL(0x26afc7d8,0x41225474),LL(0xa4629460,0xcc7a0cd5),LL(0xff951c59,0xaba7cf1f),LL(0x0d1f3526,0xaf07c8ca),LL(0x18426df5,0x2746f85b),LL(0x42d2e91b,0xfabc76e4),LL(0x58debcd4,0x043b8f7d),L_(0x00000052), LL(0xa9da44e7,0xeb092c08),LL(0x1d496006,0x0b68b024),LL(0x67bb5005,0xbf7c5c64),LL(0x0562f97c,0xca481cfe),LL(0xb0ce28f4,0xc88ad0f0),LL(0x5bcd7411,0x79f82640),LL(0xcfb08fb0,0x9dac9879),LL(0x22beef72,0x149b9a60),L_(0x00000111), + LL(0x055ab7d2,0xb9344cd4),LL(0xcbb171f1,0xf24efa25),LL(0x63c2684d,0x4f8a3dbe),LL(0xf0b702dd,0xda3c37c4),LL(0xa46de3f5,0x17afe9a8),LL(0xdeacde9a,0x55f90e6b),LL(0xb3ba7f88,0x4d24b1d2),LL(0xa174d6f6,0x25de78cc),L_(0x00000081), LL(0xbb7dee1a,0xa172733c),LL(0x562c1d69,0x4325a01b),LL(0x851c2792,0x2307ef6a),LL(0x99968ef0,0x69918f4f),LL(0xb12cbce1,0xcd378fb1),LL(0x9c21abf8,0x48639036),LL(0xe801ee02,0x8268fb51),LL(0x7205404d,0x1c86d6a5),L_(0x0000011b), + LL(0x3a0f6f06,0x7ad7abcf),LL(0x531ca66d,0x41cf832b),LL(0x4ac4965a,0x0f9f470a),LL(0xe00766a0,0xa92657cb),LL(0xb432af80,0xac40c892),LL(0xa94b8968,0xbd44eded),LL(0x4be8b74c,0x2a8d4620),LL(0x98f760bd,0x329915dd),L_(0x000000f4), LL(0x2a7f464f,0xdb3e7dcb),LL(0x00b58c0f,0x1a96b289),LL(0x3c1d7ee5,0x7a30a299),LL(0xbf0ce935,0xb49f5f57),LL(0xf1f5d39e,0x8f0c1970),LL(0xac9cfb8b,0x0718d4fa),LL(0xe1c25a36,0x66ec4ed9),LL(0xb0d7504b,0xf3b6204b),L_(0x00000048), +}, +/* digit=91 base_pwr=2^455 */ +{ + LL(0x72de604b,0xda62b655),LL(0xfb7d9262,0x9db8d0d3),LL(0x8e9c2aa3,0x9b867b7f),LL(0xf2912d3c,0x1a5ad674),LL(0x279e6d83,0xc6935b1c),LL(0x82236f3c,0x9a75e08b),LL(0xfcf8f6f0,0x1baaa28c),LL(0x5ff40727,0x6db1a4f7),L_(0x0000013b), LL(0xab24706c,0x991d9aa4),LL(0x2ed85b4f,0x767e0695),LL(0x0793e3c1,0xf7d06ffc),LL(0x6115d975,0x1316443d),LL(0x9c57472c,0x0b8651df),LL(0x8b972443,0xda1a64f2),LL(0xf1bbd8db,0x0c6db846),LL(0x62aea165,0x152182f5),L_(0x00000024), + LL(0xd5d810c8,0xe6eb51bd),LL(0xe42198e6,0x9bc2e3a0),LL(0xc4b3dc48,0xeda7e391),LL(0x6ed77fe5,0xcd0e3d73),LL(0xc5e60972,0x05f70f41),LL(0x26a51aaa,0xb07669f4),LL(0x9830a47d,0x34591483),LL(0x45b98cf4,0x5726f290),L_(0x000000dd), LL(0xdc9d9c57,0xf4c3b8bd),LL(0x95086409,0xd467dc92),LL(0x3e6cf0fa,0xfbebdef2),LL(0x9684c1e0,0x1daa3a72),LL(0x8c3a2301,0xf40ca0da),LL(0x850f8c4e,0x4dda12c0),LL(0x990ccbe3,0x8f2c5e51),LL(0xc2f0adaf,0x64a48494),L_(0x000000d2), + LL(0x248df475,0xb7ac228f),LL(0x869c271f,0xc18f18ee),LL(0x46d75c07,0xb3a5cead),LL(0xa1a299f1,0xf8c96489),LL(0x7ba98e94,0x805d6dbc),LL(0x1a1d6b09,0x485c463f),LL(0x5bca1865,0xfae82626),LL(0x54594fd7,0x90195cb1),L_(0x0000008b), LL(0x13e4d735,0xb2ef61b8),LL(0x5d0af04c,0x3f79b3f0),LL(0xe86965cf,0x8df70be4),LL(0x6a326017,0x93f5bd3a),LL(0x59b253c0,0xcbf1399d),LL(0xa14a5e9e,0x5112a46b),LL(0x98f7dd60,0x84b48e76),LL(0x9c0c1a6e,0xc837b65f),L_(0x00000111), + LL(0xf887b36a,0xa9bb0064),LL(0x651f2c93,0x4572329d),LL(0xd988aed3,0x6f510e01),LL(0x48541e9e,0xabc023be),LL(0x90ac10a8,0xa8621efc),LL(0xf943b700,0xeb208400),LL(0x768bb3b3,0x64d85b1c),LL(0x634af0db,0x00cbcf42),L_(0x00000072), LL(0xa7e0a10a,0x4e42e593),LL(0xacaa8063,0xadef0026),LL(0x6f2f96cb,0x955002da),LL(0xca66aa2e,0x57271d8d),LL(0x15a69e81,0x66dc7629),LL(0xcf29f326,0x378977dd),LL(0x07d6619c,0xe10e5eaa),LL(0x48e47a94,0x1697c2a5),L_(0x0000004a), + LL(0x60476dab,0xd5ce8836),LL(0x1ca95649,0xd950d005),LL(0xf0b56f1d,0xe5ff1bc5),LL(0x06d36f22,0x6e683386),LL(0xe2bbd6a0,0x249d13ac),LL(0x69fc343c,0x15998eb3),LL(0x47a41e75,0xf1860545),LL(0xc5dfbed2,0x25709f69),L_(0x0000012c), LL(0xc1e80885,0x5129b884),LL(0xf74074e8,0x9d124cde),LL(0xb7fa9540,0x9c58531f),LL(0x291d5e4a,0xaf4422a4),LL(0xb30d5ded,0x4cd8b631),LL(0x30a12b16,0x4d0ff100),LL(0xb2d9901c,0x450557f4),LL(0x1b1ee29b,0x5c3c3626),L_(0x0000012e), + LL(0x6dcd5109,0xc399a187),LL(0x5c966d1c,0xfc77243f),LL(0x4abf82c9,0x3aec3b2c),LL(0xfaf22c71,0x4988df1e),LL(0xaa22e170,0x8f28a287),LL(0x7d192a2d,0xf724ea96),LL(0x6179ade0,0x8ced48e7),LL(0x18acdc5b,0x8dd5bff3),L_(0x0000010b), LL(0x0c63196a,0x8e70052b),LL(0xa08be270,0xd8ff45f4),LL(0xe9bd37fa,0x46164862),LL(0xcc39748e,0x3cc067ef),LL(0x7dcfa284,0x68836731),LL(0xc4586ae8,0x8aabfd38),LL(0x85ecef5b,0x815642ea),LL(0xaf78e84b,0x5ad0b873),L_(0x00000191), + LL(0x55d6e970,0xf86e2eca),LL(0xa3c6d699,0x35fd609b),LL(0x277a6dcb,0x8e0371bf),LL(0x73c53bc0,0x69861b02),LL(0x747c9b1f,0x121dd3fe),LL(0xf6c83ab7,0x1a4b5c05),LL(0xa41b4b4b,0x103beb00),LL(0x6b773426,0x9a32a82a),L_(0x0000017d), LL(0x590624d3,0x968b4935),LL(0xdc61d6e8,0x57ff9d1f),LL(0xc882f647,0x3774a13e),LL(0xd8068210,0xc8094f39),LL(0x52df5a78,0x9ce26b44),LL(0xd80b9309,0x06b76a9e),LL(0x51126d68,0x26a298cf),LL(0x20129462,0xe7c24e2a),L_(0x00000044), + LL(0x00b763fd,0xe905f611),LL(0x31c9604c,0xad5b3ffa),LL(0x059b27d0,0xe85817bf),LL(0x957d997f,0xc9cea64f),LL(0xa8adabfc,0xbf24cb58),LL(0x74dd2fa1,0xfe218a31),LL(0x08cb0dea,0xcfee69ca),LL(0x310fed00,0x47666fdf),L_(0x00000094), LL(0xd66e131e,0x18c779a4),LL(0x47a1fa4d,0x13180dd7),LL(0x23f27ad3,0x3169340c),LL(0xdf4a2f35,0xa8c2be04),LL(0xaec77b35,0x3a1f8aa1),LL(0x2eed7fb2,0xe69edc27),LL(0x6110abc9,0xa5d58ddb),LL(0xe7590226,0x002c042a),L_(0x00000160), + LL(0x2331223f,0xe2c10ac8),LL(0xb1509b5c,0xf8262756),LL(0x8c8a002b,0x4f5e4c0e),LL(0xccc65314,0xaa63ef65),LL(0x5d26b24c,0x91432899),LL(0xaef2d2ee,0xace0562c),LL(0x284cbe21,0xdd5ba0e2),LL(0x4e06f44f,0x6b10f576),L_(0x00000180), LL(0x9becc83c,0xb164c12c),LL(0xc02c461a,0x811e7743),LL(0x621b38ad,0x8fde0227),LL(0x61151b61,0x1eee0c18),LL(0x90989162,0xa3e85682),LL(0x6d28169b,0x478f9519),LL(0xd980aa5d,0x35d9dbcd),LL(0xf940dd13,0x97a4c520),L_(0x000000c0), + LL(0xf6f3cc8a,0xede150db),LL(0x71295f54,0xc2f06bc3),LL(0x173c2266,0xbd26ab2d),LL(0xda0b8b46,0x958aad7f),LL(0x470909e3,0xbeb03518),LL(0x0c135242,0x6b5aad80),LL(0xe6b782b0,0xf43a70dc),LL(0x1ebe42a4,0x314ef776),L_(0x000001d0), LL(0xe9ee87f4,0x5c7acfe8),LL(0xcb05380b,0x7c5775ef),LL(0x2d540e71,0x4507bf0a),LL(0x839d644d,0xc6b81a8c),LL(0xbd1ff451,0xa45f8834),LL(0xc6531b7e,0x06bfc9c3),LL(0xf1a607c3,0xfacabe92),LL(0x152a3731,0x250efc13),L_(0x0000000f), + LL(0x972ed0b4,0x6043f03e),LL(0x2b923d0d,0xef133e76),LL(0x91d9dd18,0xbb6feffc),LL(0x25386141,0x9f4c0085),LL(0x7c52d849,0x279b119e),LL(0x1a74529c,0xfbddc6be),LL(0x3bb14fa6,0x0fc37390),LL(0x5b0469e7,0x6734c330),L_(0x00000085), LL(0xc18b1c46,0x93ed9948),LL(0xc3e5b7a6,0xef0ebe97),LL(0x98b816ed,0x5877dfeb),LL(0x369d99d9,0x3e4311e4),LL(0x2bf65ec4,0x311d0134),LL(0x8c99e5b8,0xc89dbf6c),LL(0x0a9bf18b,0x0c03cf95),LL(0x67a8c9b6,0x6bde4334),L_(0x0000005d), + LL(0x4dad1ff8,0x536327ce),LL(0x2d1bf3b3,0x5b0b6267),LL(0x47367af0,0xf13ddf38),LL(0x8798d158,0xa948f127),LL(0x84fbc252,0x3d0fe92b),LL(0x978e6fc0,0x0138676b),LL(0xef9334ec,0x96ea4ba8),LL(0xb13cf224,0x6c3f3f98),L_(0x0000000a), LL(0xa8ac5c62,0x19d6d21f),LL(0xb670515f,0xb4a2fb70),LL(0x28de441a,0x4762c399),LL(0x0fd9e912,0x3371fcdb),LL(0x896888c1,0x85fb68ee),LL(0xd0e213f1,0x2d86c189),LL(0xcea1f849,0x151cf6fa),LL(0x49b94eff,0xd27fa5b9),L_(0x000000fa), + LL(0xab2c72b8,0x009b461a),LL(0x349ca815,0x64f4891c),LL(0x07d9a898,0x0c2c3617),LL(0xe9f189a3,0x6792792c),LL(0x226e9a21,0xf620343c),LL(0xc9fabe1a,0x72bb7a93),LL(0xda748299,0x321acb19),LL(0x1b2afe12,0x5e8ede23),L_(0x00000037), LL(0x938118e1,0xbfadb006),LL(0xb72a44a8,0x9204c26a),LL(0x32e10cf5,0xbf6c9c27),LL(0xd43d80b7,0xbe5c3cec),LL(0x0afdab99,0x915d7960),LL(0x1a5a24d1,0x933f89c3),LL(0xfe011c0b,0x93e4d990),LL(0xfd09b45f,0x83123923),L_(0x000000e5), + LL(0x5c3e8550,0x67c79888),LL(0xf4f27501,0x18ef2850),LL(0x0d7f6b01,0xf40547f0),LL(0x9cb15ed2,0x89d6f189),LL(0x1bc417a9,0x5c937894),LL(0x22180816,0xb0e0c28f),LL(0x72ddfe6b,0x95839d95),LL(0xb0b70e2e,0x261abd6a),L_(0x00000119), LL(0x0092c31b,0x3261be8d),LL(0x81547562,0x2ed776ec),LL(0x2bc72da3,0x7afed7b9),LL(0x943fbdb4,0x7b5a5d6d),LL(0x896c4516,0x44f20815),LL(0x23f06fef,0x5bd5c28e),LL(0x8f4f6c6d,0xaeda432e),LL(0x355da25e,0xeabf97b3),L_(0x000000b4), + LL(0xfa6c2c0b,0x097c5794),LL(0x8878edbb,0xc8776355),LL(0xf986d296,0xb4dc28da),LL(0xcb68b5fd,0x7d364b0a),LL(0xf5c63307,0xa8df5161),LL(0xe81fb7b4,0x5837723e),LL(0x9cfefa9e,0x681c02e5),LL(0xf9182f1b,0x0c0e0df5),L_(0x000000d3), LL(0x43741dfd,0xeeeaf6e7),LL(0x0f7f7db0,0x912e6cbd),LL(0x1b17b840,0xfbc2bc3c),LL(0xff0906cb,0xaed2e1f9),LL(0x79085d0d,0x413a3a6e),LL(0x3e5f9190,0xf10a18b2),LL(0x5e4a7967,0xbe3ecf44),LL(0xb4e7b709,0xb5e5c6ae),L_(0x0000013c), + LL(0x9f76c8ab,0x693d1574),LL(0x254fd850,0xd18a6991),LL(0x4944e4ef,0xf78f60f5),LL(0xbc73879c,0x125696fe),LL(0x04c63e00,0x8e1e2dbe),LL(0x88e142f6,0x688fd93a),LL(0xbbe7321b,0xd6f1e83a),LL(0xa7b2fa13,0x693413aa),L_(0x00000118), LL(0xcbcaa293,0x19ff3b97),LL(0xb39ad595,0xcedb5893),LL(0x7e59369f,0x47364ed0),LL(0x15852af3,0x7c32e933),LL(0x4d5a40d4,0x82768fe3),LL(0x06533865,0x53f8e4c6),LL(0xf43bf2b4,0x8b4a96dc),LL(0x2542e182,0xb2f8ae33),L_(0x00000153), +}, +/* digit=92 base_pwr=2^460 */ +{ + LL(0x0611a7aa,0x83626ec8),LL(0x91b56818,0xaebe5044),LL(0xecc113fd,0x3fc31dd2),LL(0x68171e0f,0x5fdadf10),LL(0x4d2fbb6b,0xe94a492b),LL(0x06c20ee0,0x0723f06e),LL(0xe2fed2d9,0x8316b906),LL(0x2f32d5d0,0xfd81f33b),L_(0x000001c7), LL(0x63731c43,0x2924bed0),LL(0xf8996c91,0x58df5bd8),LL(0x04d16a64,0xb4780e3a),LL(0x3ff6f14c,0x5aed0330),LL(0xcf56c817,0xb62e0f3e),LL(0xf8163011,0xee8bd1d8),LL(0x5c28fa8e,0x9fa055be),LL(0x5edb8d9c,0xfcd0b563),L_(0x000001e4), + LL(0x0deb4c2e,0x0e66e6ba),LL(0xb2451f1c,0x058a747c),LL(0x20962d66,0x0214b10a),LL(0xda104e82,0xe594cae1),LL(0xb4693d32,0xf837609c),LL(0x059d3bb7,0x53eda7c5),LL(0x1dd16cae,0x3eb60275),LL(0xc67ede2a,0xd46da07a),L_(0x0000013a), LL(0xc838202c,0x35c208ae),LL(0xb2fb2035,0x56079145),LL(0x55be9713,0x95c814d4),LL(0xfd8f0bb3,0xc09f6782),LL(0xcc755426,0x8edafadb),LL(0x4ecf0b74,0xeaf4bc3a),LL(0x553943ed,0xa2bff049),LL(0xe542c407,0x3628a57e),L_(0x00000189), + LL(0x0d581933,0xc0bba438),LL(0x9ddc3e72,0xbc54c3a8),LL(0x1bbc6d0f,0xf2cdd63a),LL(0x1518f660,0xaf2f62bf),LL(0x27e5bf5f,0xbfe7727a),LL(0x7b164682,0xa33defeb),LL(0x40ec257d,0x6132b5ef),LL(0x902b2e89,0xcef96a0e),L_(0x000000ed), LL(0xe3ab4683,0x69a88271),LL(0x8299824e,0x4545479e),LL(0x373761e0,0x397121a7),LL(0xe3b1f753,0x0aaebe93),LL(0xd463acb4,0x1af707da),LL(0x1d6dcb72,0x14e15233),LL(0x48e5280c,0x91655530),LL(0xaaad009d,0xa49c7612),L_(0x0000010e), + LL(0x9792b39f,0xcfd79768),LL(0xc556dfa7,0xf279c07e),LL(0xd7670e8c,0xdad1cf40),LL(0x5e04abde,0x90b1377b),LL(0x46fcc199,0xf5067ad9),LL(0x6a088572,0x28101c96),LL(0x2ad58aca,0x43b5e33c),LL(0xe333e24c,0x9c51feb0),L_(0x0000012c), LL(0x54f0361a,0xf79463ef),LL(0xc22ce2dc,0xdd053538),LL(0x4e6817ca,0x2bc1013b),LL(0x4b01a6e1,0x844a6eb4),LL(0xad109d85,0xbfdaef54),LL(0x4481b985,0x6830be54),LL(0x297f121f,0x8bfd8dd0),LL(0x6d0b67a6,0xb59137cb),L_(0x0000008e), + LL(0x45ba65ed,0x45dcbcdc),LL(0xdd83e268,0x0a0b1cdd),LL(0x63968b4f,0x35e092ea),LL(0x71e6e72d,0x3f1ddc4b),LL(0xa46c5ed0,0x5a166bbf),LL(0xb7c76efc,0x0de0b5f6),LL(0xc1387b79,0xb6445136),LL(0x8923450a,0x76670ba7),L_(0x000001c4), LL(0x99a85019,0x0cae44ea),LL(0x1e4af9c0,0xe5e17b63),LL(0x51c0dae8,0xee91c80d),LL(0x0c3cbe08,0xa4093612),LL(0xa23c8041,0x3446b0ed),LL(0xf215ada7,0x43d14026),LL(0x7813fb66,0xb26fbac3),LL(0x0031b68b,0x0bce8fc7),L_(0x00000080), + LL(0xe275ab90,0x45ee7e0e),LL(0x399f21e6,0x37b06a37),LL(0xe9bd12b1,0x96080496),LL(0xa5d50d58,0x05ba3f26),LL(0x7c1e3f37,0x1d4a0081),LL(0x4d39274a,0x2d00866a),LL(0x0317c40d,0x64f146bf),LL(0x2ec71ea0,0xc168124e),L_(0x0000002c), LL(0x933c199f,0x4f78f168),LL(0x3fb1362e,0xa194ad2a),LL(0x5259655c,0x5f408022),LL(0x5898f9da,0xd8a6c1bc),LL(0x7553edff,0x2793c479),LL(0xe26de20b,0x1ea73083),LL(0x533d9374,0xb2a2971a),LL(0x4fd22035,0xfeac60e5),L_(0x000000b8), + LL(0xf8f9d4de,0xdebb5987),LL(0xe3156400,0xd526ec09),LL(0xe0023f66,0x5578bd03),LL(0xd7d715cc,0x3099f2ae),LL(0x858cc9c0,0x4417ca0c),LL(0x2ea5506b,0x23b4df57),LL(0x7420ffbd,0xe0c5dc14),LL(0x99652bdf,0x4eb0a328),L_(0x00000134), LL(0x0d31987c,0x9461ad7d),LL(0xe6bbab25,0xc859a4a7),LL(0x3d2a289c,0x08730e2b),LL(0xbe629139,0xcf6e14e9),LL(0xc3904cf1,0xdab045a7),LL(0xacb2cca9,0x2a43de3e),LL(0xfa439f68,0xd4d82c3a),LL(0xd187ae70,0xd2291dec),L_(0x000001f1), + LL(0x5587b449,0xe293d334),LL(0x6f8ad12b,0x4ce4906c),LL(0x8d521bfa,0xb26a6693),LL(0xa914bdb3,0x9dc3e746),LL(0x3ae5f6e9,0xb0881c2e),LL(0xac2559db,0x9191a1b5),LL(0x72e53430,0xa6c6a97a),LL(0x07226ad4,0x10b02ddd),L_(0x000000f0), LL(0x3a39e249,0x419af206),LL(0xc72bc669,0x42122752),LL(0x9a44c7a3,0xc28aa7e1),LL(0x188ac573,0x14ec6b11),LL(0x09a3360e,0xc8624588),LL(0x3af7bc0b,0x41e19299),LL(0x42bd4817,0xa8d8d757),LL(0x8768555b,0x890766cd),L_(0x00000046), + LL(0xe3a45fe5,0x95591624),LL(0xaebe1b9d,0xa30f27ef),LL(0xcc5daccf,0xf894bab2),LL(0x753b9ddd,0x456446cc),LL(0xa2185cca,0xfed1e127),LL(0x12d28159,0x0339e65d),LL(0x698c68d1,0x1a9ca283),LL(0xe9c06f97,0x34810a87),L_(0x000000b7), LL(0xfa3c3bf1,0x0574a504),LL(0x1f37ca7f,0xdbe81703),LL(0xebc6693f,0x6a068b27),LL(0x9068b291,0x03b786c6),LL(0x3dcacbac,0x74d197dc),LL(0x5766087c,0x8dd304a2),LL(0x60b034d5,0x45cead24),LL(0x0eb18561,0x4cd9970a),L_(0x0000016e), + LL(0x247df0f3,0x5379241e),LL(0xe00bbfb5,0xad8e1bf2),LL(0x4971d453,0xffdae98c),LL(0x4dac08bb,0x43c392ba),LL(0x1094f61d,0x34435f45),LL(0x25c82ce3,0xc0379951),LL(0x86ddd573,0xbe3f91c8),LL(0xa4a47405,0x4ef0357c),L_(0x000000dc), LL(0xd140309f,0x7d5ffd2b),LL(0xb5c6fd08,0xf1092ec1),LL(0x3fef2aa9,0xb1d3ec33),LL(0x5486d81c,0x414b5e87),LL(0x09d0d988,0x7faa17ff),LL(0xd5d8f9a4,0xed9cefef),LL(0xa9baa755,0xcec21b69),LL(0xb4d04c7c,0xe8d2ccb0),L_(0x0000002c), + LL(0x705db89c,0x84f6bfda),LL(0xac8dec0a,0x7e47ba03),LL(0x11601ccd,0xa270c8be),LL(0x5c7ebbe6,0x6d1474f3),LL(0xf62ef9fc,0xe04a6269),LL(0xfb77f59b,0x9e393c86),LL(0x150112d3,0x5df9c04c),LL(0x64d1ef7d,0xda15f26b),L_(0x00000088), LL(0x4c8472a1,0xfafe59da),LL(0x41ca0a2b,0x2ad99761),LL(0x1e89c29e,0x4b041df1),LL(0xfe4fe5b6,0x8b8ac33a),LL(0xd36ab4d9,0xf8473963),LL(0x53e1a21e,0x75363c3b),LL(0x21c36ab1,0xe0592363),LL(0xe35ac3a5,0x17f59f21),L_(0x00000086), + LL(0xee1e4fba,0x2e463b38),LL(0xafc972de,0x1010af35),LL(0xbe876d0d,0x49188274),LL(0x060ac231,0xac345fe8),LL(0xb568289e,0xe6dec43c),LL(0x9e9a1cec,0xc8cf61bd),LL(0xa7d9e863,0x4480624e),LL(0x84470564,0x5a220f0f),L_(0x00000086), LL(0x7730874b,0xb07f3f33),LL(0x5d9261b6,0x122fcc85),LL(0xe27f8557,0x06820d8c),LL(0x073c1847,0x82e3f6be),LL(0x3976550d,0x0e6c3609),LL(0x9a68ea2f,0xf48dbeee),LL(0x99ffba71,0xcc24a469),LL(0x3d0bdb6c,0xd7097568),L_(0x00000015), + LL(0x01e0bacb,0xfaf69acc),LL(0xde8618ba,0xc2f50b6a),LL(0x14a7dc8c,0x255c91c8),LL(0x2f3c4d3d,0x3e41e3ed),LL(0xb39008da,0x3885fe89),LL(0xe57622e4,0x0199693a),LL(0x4d2436d5,0x8a6ba080),LL(0xdafeb6e6,0x14dd5c23),L_(0x00000122), LL(0x2580e973,0x8519d427),LL(0xa920070b,0x0b67d6f2),LL(0x90fc96fb,0x14566ecc),LL(0x25c7716a,0x30c1cfb5),LL(0xb8dd507a,0xd8b7f726),LL(0xa175dc05,0x24a60ede),LL(0x99f15332,0x78236bba),LL(0x7ca4a569,0x3707415f),L_(0x000000be), + LL(0x1e3479cf,0xdd8491ad),LL(0xd79c5592,0xcd2995f5),LL(0x8ece5732,0x7f9162e1),LL(0x7f928933,0xff64a3a5),LL(0xdd90d4ea,0x82a7e6d8),LL(0xd296e0f0,0x8dc81d30),LL(0xf317ef62,0xa5bbd68c),LL(0xc3c72a97,0x0373debd),L_(0x00000092), LL(0x8de59597,0xbad8e310),LL(0xe46b5cc5,0xae543536),LL(0x3be10fe7,0xb038a518),LL(0x22e5dfa8,0x98fc1a73),LL(0xda531be8,0x4395fad8),LL(0xa64d7d12,0x81e9b112),LL(0x5b7b8eee,0x6b371c5e),LL(0xf97cc8db,0x53a14472),L_(0x00000087), + LL(0xeddf9eed,0xac48ddad),LL(0x3fafda2a,0xb0386572),LL(0xe2cfe37f,0x4a95ae1d),LL(0x2a2d6f2e,0xf0b70c4d),LL(0x5539faa3,0x1e2738ed),LL(0x855ae2b7,0x680d7df5),LL(0x5fa4d703,0x047f7d72),LL(0x981799eb,0xbfdef3a0),L_(0x00000158), LL(0xefb32d4e,0x14e1364c),LL(0x0008de76,0x2af04490),LL(0x56298a56,0xa488b32b),LL(0xe10ef61b,0x7c93d9c0),LL(0x74302f60,0xe50aeca3),LL(0x40b43584,0x7cf8baf8),LL(0xb9ab8a52,0x29e97768),LL(0xf0c44bc5,0xe545b8b0),L_(0x00000193), + LL(0xc7ebaeb9,0x9166afc8),LL(0x8df096c4,0xb1a4fb9f),LL(0x9ef63e0b,0x0a63a275),LL(0xd0e62d1d,0xa13c16de),LL(0xf215cb79,0x82d5b46e),LL(0x45439424,0x5cf39033),LL(0xc9b239aa,0x4a39ce21),LL(0xfcf03ed3,0xdf9660a2),L_(0x0000004c), LL(0xd8466a8a,0x523be0b6),LL(0x493a7775,0x74759167),LL(0x4894bb12,0x5e2284c6),LL(0x864e9ca2,0xd07d26e2),LL(0x08b7f98f,0x6d662061),LL(0x8e1e3fdb,0xf64b5a66),LL(0xa0ba6cae,0xedd31c44),LL(0xdac14a11,0xa2fe1891),L_(0x000001be), +}, +/* digit=93 base_pwr=2^465 */ +{ + LL(0xd37e005c,0x6d99c24d),LL(0x9fa0210b,0x813da140),LL(0xd53cbcd5,0x9488bf13),LL(0xb6d8655f,0x5b2d055b),LL(0xb21f224e,0x3ba305b4),LL(0x059a77dd,0x5337f568),LL(0x783aa9f0,0xb88b4b1e),LL(0xe8c56442,0x5f00bd6c),L_(0x000000b6), LL(0x9b7e0acb,0xe0e90fde),LL(0xda1867f2,0x336f8ff1),LL(0x14e3d072,0x8e647516),LL(0x87e51c7e,0x1ca72a31),LL(0x27ef1710,0x61c42d89),LL(0x641d8a97,0xbb69cc0c),LL(0x6138250e,0xc12903e9),LL(0xd2873a54,0xe47626b8),L_(0x000000e3), + LL(0x0523f47f,0x1fe7219c),LL(0x11a49ec5,0xbd8a88f4),LL(0x6713e8b2,0xd3f30897),LL(0xe0f84892,0x410c616e),LL(0x4957e9fa,0x60b01558),LL(0xfce0903d,0x41fc07f1),LL(0x82117eff,0x3ffa3ce1),LL(0xb039b569,0x82bc2654),L_(0x0000000c), LL(0x04f700d5,0x693fd9aa),LL(0xa0743bcc,0xb8b0e7fe),LL(0x81c35812,0xfcb182c1),LL(0x64896cc8,0x9f019f88),LL(0x8c77cf49,0xa6594c50),LL(0x2c4110bb,0x88406e14),LL(0x0fcaee7e,0xb8b45fd5),LL(0x4dc1ba3e,0x1ad10989),L_(0x00000138), + LL(0x07c446c4,0x0878421c),LL(0xf275544a,0x8722c55c),LL(0x424a48fb,0x028ec763),LL(0xf6b5b3b9,0xca8f7bf4),LL(0xf78d4fe3,0x77d82e20),LL(0x04e23f42,0xbc6300a7),LL(0xf5f71bbf,0x3aa908b8),LL(0x0bc8e8a5,0xde191b09),L_(0x000000fd), LL(0xd0dcad65,0x35d31de3),LL(0xe5fbc4e6,0x9ac9c9da),LL(0x525deba7,0x0b85d812),LL(0x465a1ffb,0x08542228),LL(0xc039c002,0x1962a343),LL(0x60c9d143,0x729577d4),LL(0x0fe4b631,0x05befcdb),LL(0x25528067,0xf91b4f98),L_(0x00000093), + LL(0xbc7bb607,0x894887a4),LL(0x14230e0a,0x6eb1e976),LL(0xe2c653f8,0xe9303e71),LL(0xdded494b,0x9fc0dd96),LL(0x98ac95d0,0x63fba061),LL(0x738abea5,0xf3c1624d),LL(0x4a0ea988,0x389df64d),LL(0xc6ae1823,0x2d8511d5),L_(0x000001d1), LL(0x7feeeb90,0x7d7a8b0a),LL(0xde36c637,0xa9c345a7),LL(0x611067e9,0x0a9100d5),LL(0x6bcdcedd,0xf6c68c80),LL(0x92b5dec6,0x8d7d4a34),LL(0xad3651f3,0x2d5061b9),LL(0xf739c0f2,0xd15c9ea7),LL(0x34e6cedb,0xa8a2dee7),L_(0x00000008), + LL(0x5ef9ab41,0xda8a106f),LL(0x3b8cfab2,0xb72948ff),LL(0x3a4d0cd5,0xf95a1457),LL(0x5f6b94ff,0xa636c12b),LL(0x4c711bcc,0x1e6c9e9f),LL(0xffdba7aa,0xe7eacce4),LL(0xfce23073,0x8fbc9275),LL(0x5935eb69,0xb6675659),L_(0x00000198), LL(0x05d931ae,0x918b9aff),LL(0x1f8a1b79,0x844b544c),LL(0xaa1709c8,0x7e08066d),LL(0x5258c624,0xb640f1c6),LL(0x176bbba4,0xa22bddd0),LL(0xc24ede16,0xd090e0e9),LL(0x4685aca4,0xd8b8736b),LL(0x64e8e6dc,0xa9cb10f2),L_(0x00000001), + LL(0x35476aba,0x78928ff0),LL(0xd948696e,0x989109f6),LL(0x5f254f30,0x44ed9a63),LL(0xd3543664,0xa497e106),LL(0xec63e4f7,0x54a3d56c),LL(0x4cb1418d,0xbfbcd507),LL(0x2a5c778f,0x548f00b1),LL(0x3ba6c12a,0xabe2e750),L_(0x000001b3), LL(0x4db14381,0xc2817a38),LL(0x86547af0,0xb6947c7e),LL(0x6d9e6104,0x70ddd5de),LL(0x2c369c27,0x2f6e17ee),LL(0x04550b40,0x2c52689a),LL(0xb0ead30b,0x3892ae0d),LL(0x99d74e20,0x145321b6),LL(0xd38ac454,0x69273a68),L_(0x000001dd), + LL(0x9a014b31,0x2b898264),LL(0x9e8130d3,0x12fa12a6),LL(0x014372da,0x94999852),LL(0x86eb5c63,0x2a214084),LL(0xdfb3f74b,0x889d0eaf),LL(0x9c182b54,0x4f4c24a5),LL(0x023efe1f,0x0c3bbe75),LL(0x3089629d,0xf6118b2f),L_(0x0000007f), LL(0xdbfd5856,0x138e9e46),LL(0x49f8b60f,0x8855a365),LL(0x00624aa1,0x358ac67f),LL(0xff0d2d03,0xd4f8c970),LL(0xb9b15a4c,0x244d4dda),LL(0x60864d2f,0x7db18004),LL(0x1d1483da,0xd00cd704),LL(0xfbce4196,0x50e134b0),L_(0x000000ed), + LL(0x0feb0501,0xca55bd42),LL(0x8695f9af,0x9c3c71fd),LL(0xcc6e5ed1,0x3d500caf),LL(0x8edc89ca,0x4e21b872),LL(0x77647185,0x0ff872ac),LL(0xee45201f,0xe23036d8),LL(0xc8bee8b3,0x5f2c13f7),LL(0xa1d51a1e,0x6b556707),L_(0x00000079), LL(0x8022b011,0x529ed8e2),LL(0x2b6ff0cf,0xb8a477a5),LL(0x3b6e8238,0xcf5cd2f6),LL(0x291c55c9,0x42ab247c),LL(0x3f4796ab,0x9f93937b),LL(0x5dbfc098,0xca7b47aa),LL(0x7620e79b,0x296f0a6b),LL(0xdd4ea007,0xd0a64f58),L_(0x0000017e), + LL(0xf01a2f06,0x96bedf48),LL(0x7e8f7f41,0xd452fc32),LL(0xcfab9384,0xf1693df4),LL(0x57e90144,0xde828634),LL(0xf5773fb8,0xf8ca5704),LL(0x123913d5,0x2119d8cb),LL(0x7eb6dfc1,0xfdf9f63e),LL(0x3c675fe5,0x2438100b),L_(0x0000004c), LL(0x1f4969fc,0x18608a42),LL(0x92fc7ae8,0x270c4cd5),LL(0xf9035119,0xd6e64853),LL(0xc4832b26,0x6b21d3fa),LL(0xa4c2c4c7,0x726b2dcb),LL(0x725c739d,0xb649408c),LL(0xcaaec71e,0xa0b38b9c),LL(0x5b557fb0,0xfcd2a17b),L_(0x000000c7), + LL(0xffa160b7,0x6ed5bb92),LL(0xd76d4830,0x174db5f3),LL(0x56439bbf,0x9cf210a6),LL(0xcf76e11e,0x0a183944),LL(0xb1458e01,0xa3ae6e4a),LL(0x034db573,0xc26a236a),LL(0xe322c7d5,0x3184159a),LL(0xef56cb0f,0x838dfaf3),L_(0x0000005a), LL(0x83bf41c6,0xc9df776e),LL(0x9cd9b688,0x5709e999),LL(0xec730800,0x9d5ce348),LL(0x9c9f3378,0xa53d30c8),LL(0xdcaf4c9c,0x09b66b9c),LL(0xb8aeaba1,0xc4d0530f),LL(0xea0f22f3,0x73581f25),LL(0xc1d28f6a,0x26a42f5a),L_(0x00000014), + LL(0x47e984e8,0x20c4ae50),LL(0xd1b90de4,0xc94af252),LL(0xdf5adf83,0x41b573a2),LL(0xb6b25c5d,0x003e17b9),LL(0x47e2aa64,0x600d2bda),LL(0xf75489f9,0x595799ce),LL(0x1b49400e,0x7a9784ae),LL(0xba0298f7,0xef02429f),L_(0x0000019e), LL(0xc18830c9,0xc0e76415),LL(0xb7a4b3e7,0x46646194),LL(0x210e39ff,0x46e16ac1),LL(0x94dd48b0,0xe09df941),LL(0x5657d728,0x75b23925),LL(0x987d7dae,0xf5484304),LL(0xb8bad70f,0xee4753cb),LL(0xc44a0313,0xfec01e5e),L_(0x00000078), + LL(0x301bb718,0x3ba3b59e),LL(0x7ed618c3,0x2225703f),LL(0xe6e7b1ec,0x3d9b8d85),LL(0x2ddd2443,0x526b020e),LL(0xbbb89c6b,0xf99d3527),LL(0x9694dbcf,0x1bef732e),LL(0x34415736,0x42d5d4d5),LL(0x5cdafabf,0xc0922340),L_(0x0000011a), LL(0x3da6214f,0x2ffdc730),LL(0x3a1a49d4,0xc640e584),LL(0x9755bbcb,0xd90466dd),LL(0x6a1bb6be,0xcc97293e),LL(0xd094e422,0x23c9d622),LL(0xf2ec9cc4,0xcc616321),LL(0xafe8382a,0xc1a93af5),LL(0x26522de8,0xe7ded64e),L_(0x000001a2), + LL(0x73e6acc5,0x9117f654),LL(0xea525fd4,0xd6399efb),LL(0x5316271b,0xbf78249c),LL(0xe30685a3,0x7737d7b2),LL(0xb95bf177,0x4cfca353),LL(0x138bd305,0xa3671bc7),LL(0x088b1877,0x110ae487),LL(0x1ff3771d,0x6f5bb6fd),L_(0x000001b9), LL(0xaf501744,0x732576c6),LL(0x4a538a56,0xdfe16416),LL(0xf3e1aa2e,0xfe886ca1),LL(0x95495af6,0xfad421b0),LL(0x2e5633e8,0x14deea0f),LL(0x87a33bf0,0x59e08514),LL(0x7333d917,0x92bad09b),LL(0x773222e4,0x810dcfd4),L_(0x00000014), + LL(0x3565ca51,0x0fd12235),LL(0x5d3c8d16,0xdc033287),LL(0x948d4bd6,0xd175dce3),LL(0x9d5a6616,0xd08718eb),LL(0x4afce525,0xd0bbb22a),LL(0x9107b243,0x93527f91),LL(0x45382cdd,0x6c46b7fb),LL(0x8d893d42,0xe82dc58d),L_(0x000001b3), LL(0xbddfc4e9,0x1d8f3a25),LL(0x1c16029a,0x51ce74f6),LL(0x0f857730,0x72d22f72),LL(0x9d6f7b83,0xa805ac0c),LL(0xf970cb65,0x6193a324),LL(0xef9afdbc,0x579b13d8),LL(0x29a49024,0x2ea3de42),LL(0x4d4f92d1,0x20c20f67),L_(0x000001ef), + LL(0x3687601b,0x61173b64),LL(0x19ad59c7,0x5cdaa0ac),LL(0x37e94d1c,0xb01a110c),LL(0x46a8a192,0xb73fb28d),LL(0x89ea578e,0x32a829b7),LL(0xc1c111ef,0x73a214d8),LL(0x1c8ded15,0x1cfef495),LL(0xbf036574,0x6f08a7dd),L_(0x000000d1), LL(0xde40c899,0x451757da),LL(0x9bdf62c8,0xde505c58),LL(0xf590c16c,0x0833d1ea),LL(0x4f878ef4,0xc9e82fbb),LL(0x8ef0ccb2,0x87ab08dc),LL(0x1d1f4efd,0x115ad9da),LL(0x4e21d1ff,0xd549cc87),LL(0x88e6e9e7,0xcd93e9dd),L_(0x000000f3), + LL(0x424f87aa,0xffc3ba23),LL(0x162b1fab,0xa3b2b167),LL(0xb86c7978,0x83e73da5),LL(0x9b5f991d,0x8d484c76),LL(0x2cb3d908,0xe085b439),LL(0x28064542,0xeba2ea8f),LL(0x2b91d2b4,0xcdc46cb8),LL(0xe83321f8,0x9d43a8c0),L_(0x00000193), LL(0xfd97601a,0x4a0c50df),LL(0x305e99ef,0xfc4b8056),LL(0xa29f6e86,0xf5b0c1c8),LL(0xbe1babed,0x558d2cd4),LL(0x75e98d4d,0xd17d7bc8),LL(0x45e57fd7,0x9a0a33b7),LL(0xc3cf9b60,0x2d8c2a2b),LL(0x5277b76d,0x6284d623),L_(0x0000013a), +}, +/* digit=94 base_pwr=2^470 */ +{ + LL(0x3e614e7a,0x1806f150),LL(0x0773591b,0xc937295d),LL(0xb432690c,0x6d3468f3),LL(0x7af2bc37,0xc765b502),LL(0xf1568b1f,0x4508081c),LL(0x4f2d04c8,0x3b08d2fa),LL(0x0d438419,0xfdaa2353),LL(0xd4118eb0,0x68f3eedd),L_(0x000000c5), LL(0x7395d916,0x879c30fb),LL(0x732a652f,0x33e906c3),LL(0xd707078b,0xeb09ecd6),LL(0x4fe7914f,0x76e24476),LL(0xf1644295,0x1ef70830),LL(0x90ff7060,0x8d1a94c2),LL(0x8e38b393,0x347e067e),LL(0x7b7a7e79,0x97efc04d),L_(0x0000014e), + LL(0x7e61fdc0,0xe59da03f),LL(0x98bd359f,0x51831e76),LL(0xf982fb68,0x4079f81d),LL(0x64253ce4,0xffbd0a1c),LL(0x684a0c0f,0x24ab0837),LL(0x0fa3fd27,0xaefd7b90),LL(0x8cd54b9a,0x4f017be0),LL(0x39893203,0xf8268359),L_(0x00000163), LL(0x5f8bfed5,0xbd73f12c),LL(0xbd9b46e5,0x7574722c),LL(0x672fc532,0x95b789de),LL(0x9d4c5de7,0x313e84cf),LL(0x48e00647,0x002f1934),LL(0xdda401e2,0x649a15d6),LL(0x96114ef7,0x37a4f04c),LL(0x4a9dc085,0x66b1bac3),L_(0x000000e3), + LL(0x8f0a82c0,0x87ae4c3b),LL(0x74f004b6,0x384b1146),LL(0xce02e119,0xd665e4e4),LL(0x1859c7a2,0xe5dbd5ec),LL(0xadfa269c,0xa30b0013),LL(0x74ac1d2b,0xb4b5ebac),LL(0xbc73c88d,0xacdb48e2),LL(0x872a2a2e,0x2e41ca61),L_(0x000001e4), LL(0x1044c064,0x1021647f),LL(0x3c4c4561,0x05bc197e),LL(0x8aef2b50,0xdd7066b6),LL(0x53c751b1,0x10e7a8e7),LL(0x3b7ee577,0x2667f737),LL(0xee8825eb,0xd2baf066),LL(0x2e6cd49a,0xfaed0dee),LL(0x4bbbae5e,0xe1b0bac0),L_(0x0000010a), + LL(0x755e5ed4,0x7eafbd5d),LL(0x22817dc2,0x8274c8f2),LL(0x6ed11c56,0xa0be4b95),LL(0xc506cd96,0xfca3c62a),LL(0x6c56121c,0x160f6437),LL(0x94e1e3c5,0xcd969d97),LL(0x2a1b9ac1,0x6a2818ba),LL(0x5d12cb94,0xe5f11bbd),L_(0x000001d4), LL(0x67065269,0x6eaf2423),LL(0x2f4afa25,0x74390891),LL(0x2342e954,0xec048d33),LL(0x5565f855,0x3a8816f7),LL(0x8e4ec59a,0x55b015d4),LL(0x6a715052,0xbf898ef0),LL(0x385313b6,0x8baf90ae),LL(0x415dc868,0x1f03f1d5),L_(0x00000107), + LL(0x117822b3,0x37c2f26e),LL(0x4762f6de,0x9377e35f),LL(0xfb62c99f,0x3c9faf6d),LL(0xa5fec0c5,0xe6f2602d),LL(0x6a84d794,0x1e2e5844),LL(0x2e9c376a,0x2b97dfd3),LL(0xcdd28547,0x24977fdb),LL(0x3efe1f48,0xf8cc4189),L_(0x0000016a), LL(0xd2462621,0x19582902),LL(0x6e455352,0x638d59c6),LL(0xc3bea880,0xd74f8133),LL(0x1df686ac,0xae8224be),LL(0xdefcc095,0x467de606),LL(0xc63376c6,0x1bbcfb09),LL(0x644acbfc,0xe6c4cc04),LL(0xce83b441,0x82fa0126),L_(0x00000051), + LL(0x27486dd1,0x6bd544fa),LL(0xc8ec4c55,0xc9e28c7b),LL(0xa7531516,0x22d696c9),LL(0xfbb565f5,0x5bc69de8),LL(0xf4a6f6f5,0x3c4607fb),LL(0x2183944a,0xfbf34142),LL(0xc088d4ca,0x6a6a25a0),LL(0xebf86497,0xb4a0b6be),L_(0x00000005), LL(0x08805ee9,0xe10f4906),LL(0xb9740059,0x2a74e9d7),LL(0x72ae3ee2,0x2294188b),LL(0x0359108b,0xffa569a8),LL(0x5438b3ae,0xf5a918ef),LL(0x5b1543c1,0xbe32cd1e),LL(0x857bce3b,0xf67721ef),LL(0xcb0f4756,0x59125f37),L_(0x0000002f), + LL(0x7f863db9,0xb81bcc90),LL(0xc94e7e86,0x24d3e88a),LL(0x59ad89c4,0xf5ed10e7),LL(0xce7d1f0e,0x1bd7de70),LL(0x6932d3ed,0xf1561272),LL(0x12569b60,0x393d97a6),LL(0xf0741124,0xa46a9516),LL(0xc9b5b179,0xabb12b30),L_(0x000000b7), LL(0xda1e1906,0x6ff9aa73),LL(0x64a918f8,0x1673d460),LL(0xf233bf04,0xe548f086),LL(0x4ac69dac,0xb984ce8a),LL(0x12e45aea,0x294fb6e3),LL(0x5a19d674,0xd8993346),LL(0x00bc5dd3,0x0c254d86),LL(0x90107b13,0xce4ef414),L_(0x000001d0), + LL(0xec115486,0xb08c738e),LL(0x93e59803,0x23024435),LL(0x4f00e934,0xbdbe60eb),LL(0x7c91438e,0x23e859e5),LL(0x580e89c5,0xba0053e0),LL(0xb329d75c,0xd11317c9),LL(0x3d389550,0xd235e570),LL(0x5aac6426,0xde574384),L_(0x000001be), LL(0x42349105,0x21c69e6c),LL(0x9a81de9b,0xf70eb151),LL(0x2990539b,0xafc827ae),LL(0xfe9bf0bb,0xee9dd548),LL(0xb8dbb3c1,0x8c4d4274),LL(0xf3be2a90,0xb7224476),LL(0x6e6842bc,0x8428346b),LL(0x39da0c73,0x0d7293ad),L_(0x000001f4), + LL(0xdaa88388,0xe569ed69),LL(0x7f0f1377,0x60762027),LL(0x2fe1fac0,0xa5dd03fe),LL(0x91b1f27a,0xb60b2ae5),LL(0xc4161046,0x0c72417b),LL(0xf9d8850d,0x16e6bfc4),LL(0xa63fb7e8,0x1c03a1ed),LL(0x8baa08f0,0xbb67277d),L_(0x0000015e), LL(0xba237ffd,0x7b0680d7),LL(0x0d439e05,0x64dd0307),LL(0x5d17a507,0xded7a46c),LL(0xaa6f686f,0x46bc0763),LL(0x302e95a9,0x16dd6fb8),LL(0x32a15017,0xd01bdd13),LL(0x4b4868e4,0xe250803d),LL(0x1558017b,0x131aad68),L_(0x0000015f), + LL(0x275e8267,0xb1b59985),LL(0x6c0a68a7,0x44944a18),LL(0x537ca1e2,0xd9ed65ad),LL(0x30e1107c,0x1eddede3),LL(0x802fb267,0xeaf5fb68),LL(0x27195ee0,0xd0137c18),LL(0x11b69677,0x331a8cb2),LL(0xab2ade03,0xf409e347),L_(0x0000018c), LL(0x0449d382,0x0033feb4),LL(0x9c7c44c6,0xb2576dae),LL(0x83e4fe6e,0xde49f678),LL(0x8e0a0c88,0x049a1944),LL(0x873f101a,0x2f0dcfaf),LL(0x0c6ecf9c,0xf4b7cbf4),LL(0xb8b0d918,0x5cf46641),LL(0xd2760eea,0x5cfa2282),L_(0x0000010e), + LL(0x8ae1b4af,0x5fa3cb57),LL(0xd120dbcb,0x79a8d192),LL(0xec8bbea1,0x8ab00e0a),LL(0x0fa43f9b,0x8da0324e),LL(0x320ae51d,0x53f9b52f),LL(0xd7d8355e,0x28f25abd),LL(0x800a5d6c,0xce8c317a),LL(0x8116a102,0x946d8424),L_(0x000001b6), LL(0x5e187817,0xdc1f3bba),LL(0x3d0941a2,0x42b1a905),LL(0xa2a2cc7f,0x7392c3e9),LL(0xc8a2218b,0xf81e4937),LL(0x50e22321,0xec9f9e7e),LL(0x650f7010,0x905ed136),LL(0xce7ae424,0x143d78dd),LL(0xf4b39b10,0x3a003ade),L_(0x000000a7), + LL(0xeaa9a342,0x15bb7a90),LL(0x26771654,0xdcc6aa0c),LL(0xc720264a,0x986a1f0b),LL(0xe93f7bc1,0xa182f9b5),LL(0x1bf6b3fc,0x5c22f84c),LL(0x14eb9a7b,0x7bdec7ad),LL(0x42c3b078,0x108902c9),LL(0xd7973e78,0x00f62a69),L_(0x000001f4), LL(0x20230ff4,0x64b88212),LL(0x8928dd30,0xd730a522),LL(0xc0f54e1a,0x528ea087),LL(0xbe8035de,0x2188b80a),LL(0x1d9e98d6,0x12fe3f39),LL(0xc4b4d85f,0x5d1c13b3),LL(0x0436d0a9,0x02c9a494),LL(0xcc5f2436,0xecc057d2),L_(0x0000008c), + LL(0xfa9544c4,0x3a3c6860),LL(0xc43438df,0x7ba2b50e),LL(0x8cfb61b2,0x160b337f),LL(0x177729b0,0xccab10b1),LL(0x69458502,0xb9a0ff5a),LL(0x78449ba9,0x67ca5074),LL(0xa879a311,0x73b77e61),LL(0x91f5cf0f,0xd1a80319),L_(0x00000179), LL(0xe9dd38a6,0x7f1ab441),LL(0xdb97e39f,0x8836c427),LL(0x0e31501d,0x26be55f8),LL(0x88c80de0,0xf094f5db),LL(0x161288e2,0x239cdfc2),LL(0xb27ca6c4,0x6d31f6e4),LL(0xbff28243,0x6db05886),LL(0xadc659a4,0xc60476f4),L_(0x0000014c), + LL(0xbc76d262,0x3a81dc1b),LL(0x1f94ed62,0xb5ab7c11),LL(0xcb89fed9,0x7bd8c4df),LL(0xf48a8846,0xc61ecacd),LL(0xe68265b3,0x88e6ef63),LL(0xfbdfdb92,0x8bd95324),LL(0x94692afd,0xb7f81080),LL(0x8b73dbb0,0x78ac33a3),L_(0x0000008d), LL(0xed59ec62,0xe2c2f288),LL(0x6fafd323,0x11cda8bd),LL(0x6af36bba,0x324f4f07),LL(0x06098acb,0x091a65fb),LL(0x74b50485,0xf28dae6c),LL(0x93e109e7,0x1a6b91b6),LL(0x648a962a,0xba4a27c8),LL(0x4dfe3efb,0xe4e08cac),L_(0x00000085), + LL(0xf43286a4,0x56196c6d),LL(0x6ba6cc59,0xec8e64cd),LL(0x7bd6708a,0x98aaa1d7),LL(0xb45c7cd9,0xb5bcc0ce),LL(0xce3eb2eb,0x2653d9af),LL(0x5b7387d0,0xf3afdf31),LL(0xe27833cf,0x17806f1f),LL(0x3ec743c7,0x911d2144),L_(0x00000076), LL(0x96863b2d,0xf200831e),LL(0x1d6c065f,0x1613e78e),LL(0xa1366e05,0xee600a0a),LL(0xc0223e24,0x06065867),LL(0xe94c7976,0x81ff94bd),LL(0xf203aa4b,0xf9511ac2),LL(0xb7c19e3c,0xd9eef849),LL(0x75211256,0x2d34cf53),L_(0x000000bd), + LL(0x5cc484e2,0x446b62d8),LL(0x1d84ce14,0x9c0fff45),LL(0x08f1ae70,0xe53a49ca),LL(0x71899e1a,0x9917f93d),LL(0x3709a90d,0x12fbb050),LL(0x045ef39b,0x38af72a2),LL(0x0b8cc9a0,0xf0817cd9),LL(0x52b4ed83,0x1ac352f3),L_(0x000000e1), LL(0xa7a71d48,0x44e50d53),LL(0x67e7ad87,0x192ec226),LL(0x37867d3b,0xce32e194),LL(0x24825f0c,0xfce90271),LL(0x5aa41f07,0x4b826212),LL(0xc9cefc67,0x1f602e03),LL(0xc071ae6d,0xf9f93cc0),LL(0xe4c52cae,0x047df3fa),L_(0x0000015c), +}, +/* digit=95 base_pwr=2^475 */ +{ + LL(0xebcc18c3,0xf6385f12),LL(0x8caf536b,0x8a0c24ba),LL(0xd83891ca,0x08b3093c),LL(0xb8c37621,0xb26a0ef5),LL(0xb41e3399,0xca8c426d),LL(0x0263fadf,0x173bf676),LL(0xd40bf584,0xd8a6677a),LL(0xa4760acd,0xee7734ec),L_(0x000000b0), LL(0xfbc42b8b,0x5a60d34e),LL(0x678686dc,0xa367e08d),LL(0x3e942c85,0x2dd8cead),LL(0x9d289bdc,0xa6d1bb40),LL(0xa4b034c3,0x04955940),LL(0x4e438893,0x0034f368),LL(0xddeee0c8,0x63808a7c),LL(0x8f3d9aa2,0x0ff42114),L_(0x00000084), + LL(0x3ddf4a3f,0x7d84daca),LL(0x17e3e628,0xd7eaf570),LL(0x4870b354,0x9fed1a4e),LL(0x26a3e3ca,0x5710e04c),LL(0x0ce1ea5e,0x17a2ff92),LL(0xee67709e,0xf8a3bc06),LL(0xc019a660,0xdb788ab8),LL(0x3d909c0f,0xc37576f4),L_(0x000001a7), LL(0x51c0c61e,0xc130704b),LL(0x5d086395,0x762ffbcb),LL(0xf6639983,0x337f660b),LL(0x46d9fb03,0x8fa37c16),LL(0x865cf06a,0x3f14b6d2),LL(0xe7365f2e,0x8227d360),LL(0xc5c3e588,0xb6a48fcd),LL(0x8c2eaf07,0xb4b8759e),L_(0x000001d7), + LL(0x226084ff,0xaf5d90f5),LL(0xe8626b6c,0xa900e635),LL(0x22c0e157,0x22e31c96),LL(0x1a4ad1af,0x9e88afb5),LL(0x3aadc5f1,0xff5f6050),LL(0xb11e90fa,0xc0677ea3),LL(0xf77875e2,0xaed6a977),LL(0x841145e6,0xf6cc19e8),L_(0x0000007c), LL(0x6bb84d1a,0xbfc80743),LL(0xf386ce67,0xb28c1dbb),LL(0x43c48ae6,0x88b71460),LL(0xf88870e8,0x4e3895ad),LL(0x71c30d54,0xcdbb1a28),LL(0xa8e29d09,0x71499052),LL(0x6fbd1362,0x3608395e),LL(0x9cdda95f,0xfe603cb2),L_(0x000000b0), + LL(0xb01ce2b5,0x9f8c4d01),LL(0xf417d7e3,0x78d34284),LL(0xcbf04214,0xf59d157a),LL(0xc4238071,0xf8a594c0),LL(0x7b0a1e05,0xbaf85cdc),LL(0xc9cfd81b,0x1d1329e8),LL(0xc9be4f2d,0x3168fc55),LL(0x5c20884e,0xb8a1a29b),L_(0x000001e5), LL(0x6e9fd410,0x96d54227),LL(0x16c1621d,0xd61e57db),LL(0x8656adf3,0x2da52da5),LL(0xd546ecce,0x2098e089),LL(0xb41508ee,0x7499c874),LL(0x9cf31199,0xf525839d),LL(0x96548966,0xa0de08e5),LL(0x1cdd85c0,0x68e4ee51),L_(0x00000139), + LL(0xb8ede8af,0xa3de8360),LL(0xfdee27bf,0x4341bdb3),LL(0x376db3df,0x851382eb),LL(0x309206d9,0x6325d433),LL(0xff416946,0x8994d6c3),LL(0x0e775cfd,0xfe50149c),LL(0xee627cff,0xee7b578d),LL(0xcd01235e,0xc20d885b),L_(0x000000f7), LL(0x5a46c19a,0xeec8d37d),LL(0xab92e082,0xa6ae3bae),LL(0x2deb57b4,0xe3c4d075),LL(0xce5d2ec0,0x962e7d64),LL(0xbd42e96f,0xc56b57d5),LL(0x513d5228,0x68f2747e),LL(0x7ec6010d,0x1f92f153),LL(0x8ad259fb,0x7427d2ca),L_(0x00000180), + LL(0x1fdb1361,0x018344e5),LL(0x016f0192,0xcb8a7e81),LL(0x1ca2c27e,0xc36425ff),LL(0xa8df5318,0x56d5d247),LL(0x84872bcd,0xa2e0d261),LL(0x4866d142,0x83feb22e),LL(0x0999b14a,0xab13dac7),LL(0x07863be6,0x9b326ed0),L_(0x00000018), LL(0xce023bbb,0xf8f48d21),LL(0x35940e6e,0xea9c5f9c),LL(0x2bd76e0a,0xa1f9af53),LL(0x8ff97911,0x750c500f),LL(0xdefcff41,0x3985ad13),LL(0x9c027cfa,0x36812ef9),LL(0x34694b31,0x5d319ee5),LL(0x9722dca8,0x568cfb9d),L_(0x000001ac), + LL(0xa78cdc7b,0x67114f96),LL(0x1a506e84,0x909080ed),LL(0xe3ccc90c,0xe770488f),LL(0xe93a6e81,0x0b332add),LL(0x6e681e90,0x494adeb9),LL(0x13abbb36,0x580a5070),LL(0xbf271178,0xa19a151b),LL(0xebb4d25d,0xdeb384ae),L_(0x0000014d), LL(0x2353100e,0x4b162883),LL(0xf7cdd45e,0x57659fda),LL(0x4f79c844,0x95b94da4),LL(0x3ca165b0,0xa6d4f4d9),LL(0x3565f5c9,0xc13d6186),LL(0x288f561b,0x81efd295),LL(0x51b5a1dd,0x0dee47df),LL(0x0f774131,0x059ca05e),L_(0x00000104), + LL(0x8240d25b,0x6132b9fa),LL(0x74ec9502,0xddc2ef3e),LL(0xa9db4e16,0x29d151b0),LL(0x5ad95c14,0x9bb57bff),LL(0x08144cde,0xf2a19e48),LL(0xef980c02,0x655b0b6a),LL(0x1f2df6c5,0x2138725b),LL(0x346457ed,0x99246672),L_(0x00000158), LL(0x8e3077ff,0x2804b9bb),LL(0x8db75e68,0xb8a3a732),LL(0x0cb1bbec,0xb587b6f5),LL(0x823e8549,0xe705757a),LL(0xdd7be7a7,0xb60b8617),LL(0x23677103,0x131d7bc3),LL(0x128ac224,0x03713f91),LL(0xadb3b9bf,0x57a300de),L_(0x000001c2), + LL(0x625c8b6a,0x8fc09173),LL(0x14eb1426,0xbb0b06c4),LL(0xd925dd0a,0x28f4f79f),LL(0x5a160baf,0x6a240ffc),LL(0x4f7c033a,0xcb7f6751),LL(0x98adaaee,0xc349dd94),LL(0x192aa587,0xee546461),LL(0x189c51b1,0x17d09607),L_(0x00000034), LL(0x46d637ca,0xaa3d1efa),LL(0x01cfe315,0xf7d6f7f9),LL(0x4164c61b,0x64b9530e),LL(0x1a339a05,0xce33c2f5),LL(0xc30d67f4,0xbcb863c9),LL(0x79f8f963,0x2bb9ff68),LL(0x0799af64,0xcfca4893),LL(0xe7b1b3d8,0x47d406c3),L_(0x000001d6), + LL(0xa5b46eea,0x00cef9c4),LL(0x0381ae85,0xe36179b5),LL(0x317e7dbb,0xac6498cb),LL(0x2d824ab9,0x328707df),LL(0x6aa97d96,0x80e79f5f),LL(0xc19368fd,0xe03799c5),LL(0x109d20be,0xa4688d4b),LL(0x5dfd91a5,0xc9ed9fae),L_(0x000000b1), LL(0xfce4aa86,0x8a4a894f),LL(0x5f3c5caf,0xf0a6af85),LL(0x0a082826,0x869fa6ef),LL(0x4cf46392,0x5a750056),LL(0x1d906025,0xb437590a),LL(0x5afd7688,0xfa2a2142),LL(0x5b91f195,0x46dd69d6),LL(0x53028951,0x55436804),L_(0x00000093), + LL(0x110cffe0,0x4f03a88a),LL(0xb44dbaac,0x68ebc98c),LL(0x849e6d09,0x9e197499),LL(0x126aa5d3,0x374e4b92),LL(0x9e50c62e,0x9406118f),LL(0xf4a6d99b,0x4e25c845),LL(0xc9df6238,0xb15d2756),LL(0xa10c0e52,0xe1aee3fe),L_(0x00000010), LL(0x816212f7,0x43351049),LL(0x52076e7a,0x90d0771e),LL(0xac804061,0x50393b27),LL(0x509ba99e,0xb81254b5),LL(0x6fa16ea2,0xbe5e2613),LL(0x1a907d04,0xf4aab035),LL(0x2ee00b2d,0x00a0f275),LL(0xab599862,0xf956cc9e),L_(0x00000068), + LL(0xfb9a872a,0xde3af050),LL(0xbec0fc8c,0xebe6b500),LL(0xe7c4ef2e,0x28e4d4b7),LL(0xb38a6c42,0x82362d94),LL(0xc4f9fb0e,0x4e229d20),LL(0xa3690dbf,0xa6e45bdf),LL(0x730c74e3,0xa7b1c90f),LL(0xf2fc481f,0xf8128306),L_(0x000001d9), LL(0xe5e496c4,0xe46148f8),LL(0x16f8ae6a,0x4268188f),LL(0x60936452,0xdcecf1b3),LL(0x828f2ec9,0xeec097ea),LL(0x8a581be5,0x3e062b3a),LL(0x85430a09,0x4da12b49),LL(0x562092de,0xcbb50541),LL(0x33c27b17,0x0f46deae),L_(0x00000171), + LL(0x4148520a,0xb05dd749),LL(0x6530988c,0x4882c146),LL(0x38e93ea7,0xf98af47a),LL(0x6360b046,0x75158008),LL(0x670a2092,0xa8d210f6),LL(0xcea39485,0x590b4493),LL(0xd54fb04e,0xe30eec4b),LL(0xea6ce05c,0xcce02cfe),L_(0x000001f6), LL(0x095bed5a,0xc9bc887c),LL(0x40c45485,0x2639073e),LL(0x060df364,0x9ad162fc),LL(0x0ed461e0,0xd17260de),LL(0x48f9f001,0xcef6cf88),LL(0x5e44883d,0xc42e028e),LL(0x78ade819,0x7ee983d2),LL(0x24ef3daf,0x7e26a859),L_(0x00000188), + LL(0xfbbed4ff,0x64e57bff),LL(0x825f2bb2,0x9eb6b035),LL(0xfd8b6643,0x3c213466),LL(0x9c353790,0x7313deab),LL(0x9b0366be,0x2121723c),LL(0xac2996ae,0x953e87c3),LL(0xbd382785,0xf9b6974b),LL(0x3a30236c,0x0d0993e4),L_(0x0000015a), LL(0x5f3b2707,0x68809f79),LL(0xca4a12da,0x374c5228),LL(0x32cc5a86,0x15cef9a1),LL(0xae5f8c0d,0x72616f2b),LL(0xe61ce206,0x75c41da6),LL(0xde33abed,0xa5fc5af7),LL(0x50659126,0x5776a4d1),LL(0x4c16e788,0xbd4ffed4),L_(0x000001ff), + LL(0x017dab60,0xe869faef),LL(0x1a3d2819,0xa91c965c),LL(0x95cacbcd,0x1c63a302),LL(0x28898d33,0x91791e04),LL(0xe5b4e674,0x2669fe66),LL(0x4ee8bdb3,0x55d62682),LL(0x333ebff9,0x2111714d),LL(0x88832299,0x328d0de4),L_(0x000000b3), LL(0x4df0c3cb,0x7975bc08),LL(0xa4a0f0d9,0x6243d2cd),LL(0xf978a250,0x447d6ec4),LL(0xca8ffce0,0x3c8e28e1),LL(0xa6bda9ff,0x45d5e419),LL(0x3acf30c2,0x7bf52151),LL(0x2b66a867,0x21d9061e),LL(0xbba7056e,0x01e0ca13),L_(0x00000021), + LL(0x8f349801,0x029f064c),LL(0x07be931b,0xb893aedc),LL(0x14f71f6a,0x242b0eea),LL(0xe179067b,0x8af895ee),LL(0x99f6bf52,0x5e852a27),LL(0x1d5c2098,0x94bc1969),LL(0x296ab7db,0x7605deba),LL(0x31b9475f,0xa69410b2),L_(0x0000011c), LL(0xf8c45d63,0x0d9145a0),LL(0xb3a1daab,0xbc0cd8bb),LL(0x614875d3,0x4f51299d),LL(0xad650d62,0x7baf748b),LL(0xdb91d840,0x83b9d385),LL(0xf5cc54a3,0x840ae765),LL(0xbe2653a6,0xab5a54bd),LL(0x5728a0ed,0xa778a286),L_(0x000001f1), +}, +/* digit=96 base_pwr=2^480 */ +{ + LL(0x2be41906,0x9f1fdd6e),LL(0x9ab150fb,0xb458dd16),LL(0xf3f55fa5,0xb1bb79de),LL(0xd9b88ebf,0xc1d98e1f),LL(0x7b8b17a8,0x7f6beb8b),LL(0x6c86e6b3,0xbc72340b),LL(0x7bb70edd,0xdc7c19d3),LL(0x67a99418,0x65a67f68),L_(0x0000008e), LL(0x56a4a09f,0x9cb6bc12),LL(0x8ded9bb1,0x77d8b51c),LL(0x9f35ca45,0xeb257480),LL(0xf1168ba7,0x770b52be),LL(0x12cdae11,0xed4f42bd),LL(0xde9dff68,0xd326b225),LL(0x5631a8c3,0x1d37f144),LL(0xb14a3c37,0x81f6712c),L_(0x00000045), + LL(0x66b0b95f,0xf969adad),LL(0x57813fa7,0x1acf7746),LL(0x220707f6,0x712a2615),LL(0x71d4cd53,0x2fd4ef2f),LL(0x1f82a44a,0xd9e26293),LL(0x0681773f,0xf763ad20),LL(0xe31fd702,0xa99b206f),LL(0xc3a8767f,0x07e06765),L_(0x0000000c), LL(0x41a7f8ce,0x21c3dd47),LL(0xcc9159a8,0xe90e3290),LL(0x06b623fa,0x9e8cf993),LL(0x531760ae,0x2874afd7),LL(0xc9e7cf28,0xe6527ae8),LL(0x293d6e1a,0xf99eef73),LL(0x03d3d878,0x9237109e),LL(0xe1efdba8,0xad3ca36e),L_(0x00000108), + LL(0xcc51928e,0x2af7a58d),LL(0xfb374b29,0x5ec5d4bd),LL(0xd01fb1db,0x6d8cdd85),LL(0x62636565,0x641e476e),LL(0x674fc478,0xe28d244d),LL(0xb39d16a5,0xdbaa94dd),LL(0x5fd5183a,0x6b7fdde9),LL(0xea66d862,0xe99d2b47),L_(0x000001a0), LL(0x574c9d49,0x88f7fd2b),LL(0x31232213,0x6c23d660),LL(0xb2ca0c2c,0xce3a1a6a),LL(0x664a406b,0x2ca19917),LL(0x8f549744,0x6f2fc149),LL(0xab32866b,0x41cbc3b0),LL(0x7a277aea,0x25557ca3),LL(0x16026538,0x56054af0),L_(0x000000c5), + LL(0x4fdb7562,0x9be9e5c7),LL(0x29bd5547,0x548d39ec),LL(0x29c79da4,0xf3f7942d),LL(0xc4bc1f5d,0x948e1f79),LL(0x34a7cecb,0xb63229ed),LL(0x76898793,0x39c1a7d6),LL(0xbe3b3419,0x9157ad78),LL(0x2801351b,0x1bf8452f),L_(0x00000055), LL(0x59cbeae6,0x85ddee3b),LL(0x8140db30,0xeeab1d34),LL(0x41a033c2,0xb676bba9),LL(0x85703aaf,0x23a9d8b6),LL(0x35046b64,0xb832a7c8),LL(0x9e2475da,0x5b8c259b),LL(0xb51f8631,0xdb18a6bb),LL(0x53eb5dc8,0x9d1123a2),L_(0x000001fd), + LL(0x23cca37a,0x57f26e36),LL(0xc4d2ab36,0x787ec793),LL(0x520b9137,0x436337f7),LL(0xbcfb7906,0x2caa7a0d),LL(0x418cfaf2,0x5a502d75),LL(0x0ba14462,0x066c6a13),LL(0x1d083e40,0xd21212f5),LL(0xb9541e99,0x95f764eb),L_(0x0000010b), LL(0xa39384f4,0x07cf7953),LL(0xbdfbaff7,0xaa5f9b05),LL(0x1b083e95,0x782626e8),LL(0xfb350599,0x06f421de),LL(0xe92399d2,0x415729d3),LL(0x04ad8bd9,0xcf103879),LL(0x9370ad78,0x766e0bc1),LL(0xf2c002a0,0x56454b48),L_(0x000001c5), + LL(0xd6b8bb85,0x9a142f9b),LL(0x979dc67b,0xfc51be0f),LL(0xf84e32d8,0xf9ccb118),LL(0xf5b6ca36,0x5e79aba7),LL(0x3a900f56,0xfcfd2df6),LL(0x15163143,0x22db9b75),LL(0x5f85f9f1,0xd886015e),LL(0xe7c48af6,0x5b67dbf0),L_(0x000001b1), LL(0x5dcbc466,0xc13f4daf),LL(0x043aefcf,0x613ac2b0),LL(0x60909041,0x9567d2ec),LL(0xf4b79cb6,0x57b5e5ef),LL(0x8e04188e,0x9dd05dcf),LL(0x759c45aa,0xcd8106c6),LL(0xc6c633a7,0x694b84b0),LL(0xe7963345,0xbd8ff41e),L_(0x000001a1), + LL(0xfe8ed21f,0xf39b982a),LL(0xdf9459e0,0xef033664),LL(0x1245ad2f,0x4c26109c),LL(0x6578f9c3,0x7b73834d),LL(0x28e9fc09,0x21a085c7),LL(0x84bd7b31,0x65666df5),LL(0xd5585963,0x9d7af58e),LL(0xfd1e18ec,0x6947e7e9),L_(0x000000d1), LL(0xe717df29,0xf468848d),LL(0x7c888dbb,0xd747cd3b),LL(0x51097e9d,0xe70801a0),LL(0x8bb9b824,0x172bbff6),LL(0xc27a8a5f,0xf45d5351),LL(0x402074f9,0x0ba6fcc2),LL(0xd7e5a578,0xc1d4e050),LL(0xcb9d2f1c,0xd782dceb),L_(0x0000015e), + LL(0xf2b990fe,0x1096bf3d),LL(0x3b2d5eb8,0xeb580e65),LL(0xa2ad7396,0xca4cfd31),LL(0xcddd150b,0x4cdae865),LL(0x5cde916b,0x6ffe74e3),LL(0x1b6f19b5,0x1e7dc0b2),LL(0x333016e2,0xc799d8bf),LL(0x46cec318,0x3aee6eb1),L_(0x00000077), LL(0x9830acdb,0xdd1e911c),LL(0x1a0df89d,0x891db580),LL(0x646bbddd,0xe25f1a5d),LL(0xc4d27510,0x10d55b0a),LL(0x144af2f9,0x5bcea08e),LL(0x50da24a7,0x7ae5f37d),LL(0x9ad211e3,0x73d37273),LL(0xd9d5c417,0x6daa32a2),L_(0x00000156), + LL(0x785d4516,0xd201173c),LL(0x5cbe43f9,0x6f813c93),LL(0xfc65024c,0x5174f5db),LL(0xcbde45cf,0x98aed5fb),LL(0x29d4641e,0xe15ff504),LL(0xb6befd4a,0x92a16838),LL(0x3fb27455,0x7017d508),LL(0xa78ba07c,0xb26c2bcc),L_(0x00000057), LL(0xad9a35f0,0x16e47d7b),LL(0xbfe092d3,0x75d728c5),LL(0xd99290d8,0x8ba65183),LL(0xae8ed203,0x9af2b287),LL(0xe9db0d4e,0x433a1079),LL(0xe6c8ae7a,0x21dd82ce),LL(0x5486b431,0xfbc30bb9),LL(0x7775c8a8,0xde995750),L_(0x00000075), + LL(0x92135986,0xaae951c6),LL(0x9a74fa72,0x3dfd82d1),LL(0x4bc31a1f,0x060156b1),LL(0x9ab6f26a,0x8b245f24),LL(0xa98e8084,0x317596e1),LL(0xc80c4dc3,0x11d5e680),LL(0xe262106e,0xbee2a8d6),LL(0x60234555,0x6b1389ea),L_(0x000000c4), LL(0x8b82b6cd,0xa80d5059),LL(0xb2182943,0xa584e869),LL(0xa8841e7d,0x7e59ceee),LL(0x74e1e538,0x201d2b08),LL(0x6d2519ec,0x76d5cc62),LL(0x41a115fc,0xdedbfb6e),LL(0xa6f152e5,0x5c18feb7),LL(0xd80d529e,0xda3182b3),L_(0x00000121), + LL(0x3682bcf5,0xe91e53c5),LL(0x6ca16c30,0x3355812c),LL(0x6b8e8ce2,0x18e076f5),LL(0x77cbae05,0x45a2864e),LL(0xae50657d,0x29b224b8),LL(0x5b740476,0x1853045f),LL(0x9cd59d4a,0x4fef40e2),LL(0x6e774f0e,0xa4239a92),L_(0x000001d9), LL(0x0f66fd40,0x87e39c23),LL(0xd4b5406a,0xb9d5824a),LL(0x309845c7,0x4567fe70),LL(0x40e6539b,0xc9f3a53e),LL(0x4965ee0b,0x0d799507),LL(0x06d618a8,0x28bea4e0),LL(0x01fa0a00,0x8b356252),LL(0xb43cd562,0x1c9f3b62),L_(0x00000067), + LL(0x198a02d5,0xcf78de3a),LL(0xa89bcfff,0x6931d65b),LL(0x98eb3ac0,0x204cbef2),LL(0x796db40b,0xdbd652c6),LL(0x82883eda,0x8c7c0479),LL(0x6355b755,0x3ccc26fb),LL(0xb1589be6,0xdcd445ae),LL(0x8ce9a7eb,0x5e17a063),L_(0x000001b0), LL(0x34daeef1,0x92e7ebd6),LL(0x33e4d5b6,0x252f990a),LL(0x7af9fecc,0xa16a7b3d),LL(0x19533f3a,0x07d26ab6),LL(0xf0584373,0xa41a7a2a),LL(0xc7584589,0x32ddecef),LL(0xf36c6f17,0xf2956cde),LL(0xe47377e9,0xa22efbef),L_(0x0000007d), + LL(0x68fb10a1,0xe2e1dbf7),LL(0x1bce1a5b,0x23f22cb2),LL(0x865d95ed,0x3d7b8ca9),LL(0x9350d70c,0x0559d55e),LL(0xf39cff5a,0x634be668),LL(0x1f6fcd80,0xbb740491),LL(0x31d2120d,0x7202a974),LL(0x2efc5e17,0x95233dd7),L_(0x00000182), LL(0x6ff361af,0xbd828851),LL(0x26eff873,0x96db8923),LL(0x8d394d9b,0x6a1cb060),LL(0x3ebd8f2b,0x2c56b043),LL(0x71b88fe8,0x91925e0f),LL(0x39b0cfe1,0xea28e59d),LL(0xcb53dd25,0x933a3cad),LL(0x8fbf4361,0xc3fa9512),L_(0x000000ff), + LL(0x13e495fa,0x7698266f),LL(0x51931514,0xd385a184),LL(0x7057cc40,0x7fd1998f),LL(0x8ffed935,0x5d2e260a),LL(0x55f9858d,0x34fdc952),LL(0x353e16aa,0x3d6d1e16),LL(0xd91adeda,0x9e8895ec),LL(0xa78987af,0x867a4506),L_(0x00000010), LL(0x62e40103,0x869a5ca3),LL(0xc9ddcb20,0x777bb6c1),LL(0x0f3e3498,0x4f97ec1c),LL(0x18133992,0xa7ddecae),LL(0x1c9b2738,0x280ea610),LL(0xae01d593,0xc9770c84),LL(0x30145dcf,0x7c4ed00d),LL(0xa2a8b818,0xff2e9907),L_(0x000000ef), + LL(0xd4f005b4,0x56eacf75),LL(0xf05cca8e,0x8a05a713),LL(0x2382e841,0x3f19077a),LL(0x3c0079f4,0xef823326),LL(0x07e9f310,0x71d13043),LL(0x6311fb89,0x0c6d6593),LL(0x63ca3188,0x0c592a1b),LL(0xfce1253d,0x4831a442),L_(0x00000135), LL(0x9089e935,0x994e32d5),LL(0xdc455b1d,0x643872ac),LL(0x914013f8,0xac2eba70),LL(0x35f0c433,0x5a85e638),LL(0x59b2430e,0xa786ce7a),LL(0x5225b772,0x920543ca),LL(0x51228731,0x1e47ebe9),LL(0xc56f0daf,0xfc2b2f8f),L_(0x0000006d), + LL(0x31ce7476,0xe409da17),LL(0x5b328da3,0x098b5f71),LL(0x607382a2,0x51c3538d),LL(0xc3ee7b06,0xabf1dd7b),LL(0x96d5eed9,0xe8c0d16d),LL(0x1a4ceb18,0x3fe464dc),LL(0x6b9f8f1e,0x0c30d6fa),LL(0x359d987d,0xc00a5cfa),L_(0x0000006c), LL(0x2947d098,0xb97b5789),LL(0x05d737b5,0xcc27fc50),LL(0x2087e2c1,0x62d40feb),LL(0xdd0d9606,0xf37345b7),LL(0x225ee555,0x7f3858a7),LL(0x9ae8d7c1,0x0cf2ae73),LL(0xdcf4e1aa,0xee00ee77),LL(0x649e41ec,0x007dac12),L_(0x00000021), +}, +/* digit=97 base_pwr=2^485 */ +{ + LL(0x808de672,0x8326922a),LL(0x156260ea,0x1a0841b0),LL(0x63e3e317,0xacb0f8a9),LL(0x806aeb44,0x33483737),LL(0xad9d8a14,0x761a3419),LL(0xbffd26bd,0x2e7a343f),LL(0x6d361b6d,0x4d86e32c),LL(0xf433219c,0x336c223e),L_(0x000001ac), LL(0x1f25620f,0xd5c03d38),LL(0x3a87f67d,0x80f73464),LL(0xe876505e,0xe4906c5e),LL(0x491baac4,0x178a012b),LL(0x93e07deb,0x0f735b86),LL(0xd75fad06,0x76ce5dd8),LL(0xc97cb185,0xf5dd4cd9),LL(0x634bbb55,0xa9e4bcbc),L_(0x00000045), + LL(0x37703361,0xc5f2fac1),LL(0x4dee5fdd,0xe014aa4b),LL(0x2218fde8,0xa684a9b7),LL(0x0e229612,0x1d9b66c1),LL(0x7cb5b99f,0x1796c130),LL(0x71c7eff0,0xc0871522),LL(0x27930b1e,0xd19f171d),LL(0x3091f21a,0xdabbbdd5),L_(0x00000094), LL(0xa74c873e,0xbd512368),LL(0xbc31a6ec,0xd3ea21d4),LL(0x62eff689,0xbd43a95f),LL(0x73a33474,0x1413507c),LL(0xf88fa97a,0xb01846ef),LL(0x8f06b4d3,0xfbac8f6a),LL(0xdc2a3015,0x159ddd58),LL(0x7b911f1a,0xe5ea801f),L_(0x00000082), + LL(0x2fe873b0,0x5ebf3c8d),LL(0x32fe371d,0x5b9ca7cc),LL(0xc245b054,0x2658798c),LL(0xeaf83f8b,0xf09afde6),LL(0x761d87bd,0x29e1b970),LL(0xa4fd48a5,0x1501c97b),LL(0x5ab0a100,0x1dca9665),LL(0x0ec7beee,0xefd2f42f),L_(0x000000be), LL(0x28296b82,0x171dfdb2),LL(0x171bb70c,0x1dac3a3a),LL(0xad9a13af,0xe21b7ea6),LL(0x1fe361dd,0x2f8b8125),LL(0xccea9acd,0xe8df3c1e),LL(0xa4b48480,0x8a5f495c),LL(0xb8ecc783,0x07fd225c),LL(0xbc6bffc7,0x52512454),L_(0x0000018f), + LL(0x84cef36a,0xcdf4c999),LL(0x5f8d7040,0xc211953a),LL(0xfaefc5ed,0x563ab4c0),LL(0xa17066a1,0x0c339a5c),LL(0xafb2c094,0x517a5667),LL(0xb135b1e8,0x3d2a94a0),LL(0x4526e2ec,0xd9185e4d),LL(0x3c05d493,0x0f6c71b5),L_(0x00000170), LL(0x2fc5ced3,0xff470fab),LL(0x21ddb195,0xed29f4a2),LL(0x2d94f5fe,0x69f0868b),LL(0xaf8fcc50,0x8631be3c),LL(0x3dcfc141,0x43a07062),LL(0x1c9d9989,0xbafa5f73),LL(0x1cc4a069,0xe1c5c56c),LL(0xf502e626,0xdf086a82),L_(0x000000ce), + LL(0xaaec0dfb,0xb5f2559e),LL(0x37f92069,0xf82c9e25),LL(0xde3d65ad,0xca0987ef),LL(0x52dba2b0,0x110760de),LL(0x6f1e9d7b,0xec3c5a7a),LL(0xb68a52e5,0xe6b61974),LL(0x47ef0970,0xa12dbde7),LL(0x952831ff,0x50801ee3),L_(0x000001d6), LL(0x2a4c3695,0x2be66d3f),LL(0x90213a6f,0xb1043636),LL(0xecffb364,0x0ea64838),LL(0xaf651989,0x059f3995),LL(0xd04bda10,0x8aa19045),LL(0xfff61b8d,0x76712e84),LL(0xb77b5575,0x6970c5d5),LL(0xfb11370a,0x7ca2cd1e),L_(0x00000032), + LL(0xe37454a0,0x644b36eb),LL(0x2bc89a6d,0xe5b95fef),LL(0x705a9c84,0xc8e9527d),LL(0x6ad037b8,0xc306c56f),LL(0xa3d9152e,0x99bdd442),LL(0x3acd8434,0xd2e50d9f),LL(0xfb35013e,0x10c1418e),LL(0xa1aaf42a,0x566527ea),L_(0x0000008e), LL(0x301c9fea,0xa12968d1),LL(0xf9c8c259,0x796a5743),LL(0x1c0237b8,0x92290293),LL(0x56baf809,0xb04d2746),LL(0x81ca3b50,0x93109cb5),LL(0xd70a42b1,0x1ffad7c2),LL(0x829c0f93,0x90fb8081),LL(0x00473bdc,0xc41c7985),L_(0x000001a6), + LL(0x78a1fc22,0x1e0d9fae),LL(0xfe3efcad,0x7975003b),LL(0x1a1d9870,0x5a8555e6),LL(0x08399c40,0x13808c98),LL(0x1f10285e,0xf7ae407f),LL(0x6b16e9b6,0x95f47114),LL(0x5ef970a5,0x42ba4017),LL(0x58f89d1a,0xf78bfabe),L_(0x000001d8), LL(0xb52c0fec,0x68533122),LL(0xc427c0ed,0xd8c2fad9),LL(0xbd46322d,0x870ca81f),LL(0xccd1cd67,0xab6ba984),LL(0x5510a68c,0x6f619ce9),LL(0x2516fdb1,0xd13d0213),LL(0x89ce2a78,0xd4ddba71),LL(0x33ef2f0f,0x10b6e6d6),L_(0x00000012), + LL(0xd29edf28,0x8e335e18),LL(0xe046e99e,0x4ace8ce0),LL(0x72c0503a,0x42f01d0f),LL(0x9c6d09e2,0xfcb4567e),LL(0x3998b6c2,0x0686ceb1),LL(0x91430be4,0xb8fca6af),LL(0x2236ef5d,0x01c77e85),LL(0x718e1a29,0x033d9ba3),L_(0x0000005a), LL(0xab5ae430,0xa843a1b6),LL(0x025f63d8,0xc9500fb6),LL(0xd803e788,0xfb7b9cb8),LL(0xea023d9b,0xcdad70fc),LL(0x803f3ec5,0xa7e50d4c),LL(0x9c07188d,0x9eb540fd),LL(0x822ee2af,0x0d14ab57),LL(0xaff12ba0,0x84fb3574),L_(0x00000156), + LL(0x8230400e,0xed3531cf),LL(0x20fd0e05,0x442851e2),LL(0xd6869a7e,0x1568acb2),LL(0xae871699,0xd7c29d8f),LL(0xad380219,0x512e57e5),LL(0x17e73a2a,0x0239d8b5),LL(0xff1100de,0xa4cc3700),LL(0x3960bc57,0x227a0cb5),L_(0x0000001e), LL(0xec6e136b,0x7a2013e5),LL(0xb3934a8d,0xdeac099e),LL(0x7585325a,0xc5fcf6e8),LL(0xa4aae387,0x73e275f5),LL(0xe0a1bb17,0xc599d358),LL(0x78aeadce,0x5e5ee001),LL(0xf20a237c,0xbc670ce3),LL(0xc755c2ed,0xe8b1f856),L_(0x000001a1), + LL(0x9e1ae8f1,0xb8a1be4d),LL(0xec417dcf,0xa0d53ddd),LL(0x13c7c494,0x565a5779),LL(0xe8460798,0x4157d87f),LL(0x865e6ed9,0x5fcc1adb),LL(0x43eb5613,0xff942117),LL(0xf8951241,0x65dffe8f),LL(0xbc9c1cd1,0x1aadce69),L_(0x00000130), LL(0x9c6c39b5,0xdc72853e),LL(0x60f36e47,0x8941b5fe),LL(0x036e5482,0xd9f274e7),LL(0x2bbb4450,0xd2f8bf2a),LL(0x900ba078,0x48bef6a0),LL(0x9a34b9c0,0x548c40a6),LL(0xa419ecbd,0x3d7bc93f),LL(0x5929867e,0xf64948b9),L_(0x00000164), + LL(0x2d5481cb,0x900dd0cf),LL(0x94bad4ae,0x06d3c0a0),LL(0xbee25614,0x2d0029ba),LL(0x4f1ce8bf,0x7ae14d24),LL(0x12c5aff4,0xcb8bd567),LL(0xd5130b01,0xa1cb296e),LL(0x13ab0e47,0x287ae4a9),LL(0x1c30c115,0x2ee003e6),L_(0x000001c7), LL(0x91cfcc0a,0x9e6287d6),LL(0xf8cffb98,0x0a5d81d7),LL(0x6e40495f,0xfe24065c),LL(0x4ac91688,0x6ef91697),LL(0x0bce1292,0xfa7c3394),LL(0x082d9558,0x334da954),LL(0x0d5bbff2,0x41fa885a),LL(0x6904d684,0x130da09c),L_(0x000001be), + LL(0x30ed1da7,0x34a6a52a),LL(0x610afcab,0x9193baed),LL(0x00ab78dc,0x40598146),LL(0x40d27bbd,0xfc2510b3),LL(0xdf263e04,0x2c222200),LL(0x4f8a34f4,0xe2fa7ec8),LL(0x7ecddf41,0xf5c8a69f),LL(0xb69fa963,0xc6dcbe65),L_(0x00000110), LL(0xde38eab5,0x1dc06ecf),LL(0xbce53abf,0x287aff4f),LL(0x123a0ff7,0x865d5801),LL(0x9bc53dd9,0x7f2760b0),LL(0xf4d19de7,0x2617ed79),LL(0x59b16830,0xfb36b9bb),LL(0x86d6b37c,0xc68164d5),LL(0x3ce542b7,0x536fc3d5),L_(0x000001ba), + LL(0x785c9888,0xd5898c8f),LL(0x0f97f6b8,0xa5e5e010),LL(0x25a6849d,0xdb272a5b),LL(0x5b826b6b,0xf1d7d775),LL(0x8319ab20,0x81fab2fc),LL(0x051b545f,0x13836d82),LL(0xf3f0508b,0x79a2e73a),LL(0xc87d4ab2,0x6868b289),L_(0x00000106), LL(0x9d6fea08,0x0b7f377d),LL(0x285c3784,0x13a96505),LL(0x5e5f0355,0x80e5351a),LL(0x92ff2d7f,0xa4907b9b),LL(0xf478e9fa,0xec7c1179),LL(0xd90b6dba,0xd2c36f50),LL(0xbe1d562a,0x797351a1),LL(0xf65a7374,0xf2fc31a1),L_(0x000001ce), + LL(0x8caa24b9,0xdad4ac58),LL(0xe55e016b,0x42a35993),LL(0x04d4925f,0xf4d85232),LL(0x8c2cb262,0x654bec90),LL(0x44564228,0xd9274933),LL(0x58349da0,0x55dc684a),LL(0xb18184ce,0xe08bebb4),LL(0xe4015bbc,0x9fc75a6e),L_(0x000000db), LL(0xcea81cd2,0xb89f906a),LL(0x5a1b62b0,0xc0a88adc),LL(0x46897bd0,0x3422a9ae),LL(0x6bfb70df,0x0d20f649),LL(0x113b8338,0x197424dc),LL(0xf43ab4e9,0x11c7f33e),LL(0xc17b56d7,0x3e3697c4),LL(0xf0f21e9a,0xf1b66341),L_(0x00000145), + LL(0xb3c8d4e4,0x3221af32),LL(0x786f9cb5,0xef78da7b),LL(0x6228aab0,0x460bf9aa),LL(0x4fd179a4,0xf900af46),LL(0x2bd49daa,0x42fb7206),LL(0xcadd2655,0xfa16e111),LL(0x992a0506,0x4726c9f4),LL(0xbd04e990,0x77052bc5),L_(0x00000017), LL(0xc3ac19be,0xeed5408d),LL(0xfa218d10,0x2bf29af8),LL(0x2a7befd5,0x3b0d28b4),LL(0xeabb7643,0x28d2a823),LL(0xfa48a66e,0x34709b21),LL(0x92c650bc,0xdf1a83ea),LL(0x261706b5,0xa9a5f258),LL(0xbeb0a33b,0x03e83019),L_(0x00000105), + LL(0xd53c20db,0xb6013f7f),LL(0x09d4a480,0x447348d1),LL(0xcb6a7da1,0xd8bfe6fe),LL(0x64e8c529,0xa6067265),LL(0x9034045f,0xa8df68fa),LL(0xff3f3ee2,0x1796dbc7),LL(0xdedc2792,0xe9a130fe),LL(0x4c3f368a,0x2a547fe2),L_(0x000001c1), LL(0x792961eb,0xed55f272),LL(0x9b014919,0x0068193a),LL(0x44cb0bf8,0x32ef3174),LL(0xe22227ee,0x4cb4a896),LL(0x147c8b85,0xc6a73b28),LL(0x2ed1bf6d,0x6804296e),LL(0x77be001d,0x223e6f8a),LL(0x89b143ab,0xdacda84c),L_(0x0000013d), +}, +/* digit=98 base_pwr=2^490 */ +{ + LL(0xec0e9921,0x21044500),LL(0xcba88ccf,0x0c873630),LL(0x6fd4e4b8,0x45764f80),LL(0x056645dd,0x4551a9a7),LL(0x72ed8739,0x025ba6b1),LL(0xa9a78987,0xdd01b45f),LL(0x1f9f1355,0xd2ccea3a),LL(0x807cbab8,0x43e3f592),L_(0x0000011d), LL(0x4c6c96e8,0x1a51e813),LL(0x57065d92,0x2ab97599),LL(0xa89e1baa,0xabc4035c),LL(0x057c2aaf,0x1a6716df),LL(0x9c0890aa,0xf802387d),LL(0xc7786bd3,0xa39383e5),LL(0x1f627056,0x00601e4e),LL(0xf2265779,0x9c233096),L_(0x000001c4), + LL(0xd4e8955d,0xe1d0f381),LL(0x45a79e1d,0x6407a6cf),LL(0xe689a76d,0x407f2393),LL(0xd92aed2a,0xac261bd3),LL(0x95547cc6,0x9e62fcac),LL(0x49835e0b,0x1e291077),LL(0xdde8f908,0x7b3d6780),LL(0xc4cab77f,0x213643c5),L_(0x00000036), LL(0xbde052d3,0xaa1aeecd),LL(0x958c939c,0x24153092),LL(0xca5c0f7b,0x5c0c11b7),LL(0xc9284796,0x3698d827),LL(0xd732af64,0x351c0ba1),LL(0xa3ee0367,0x1b1bf491),LL(0xec2302cf,0xafdf3514),LL(0x4436d640,0xb9059b4c),L_(0x000001e7), + LL(0xe09f3da3,0xb7ed8d41),LL(0x97fc0836,0x33451dcc),LL(0x1b62ac0b,0x4bb0f328),LL(0xc7985f30,0x76f68d69),LL(0x7e5bf130,0xa8fcc12a),LL(0x87f28f61,0x0c13fc90),LL(0x097e8f18,0x9299a913),LL(0xec6104d5,0x243dd550),L_(0x0000003d), LL(0xf8ef488b,0x2c0a7e4f),LL(0x94b33bee,0x5db54ad3),LL(0x4a72bd81,0x0abb0c63),LL(0x57fa905b,0xa7b05810),LL(0x98b0da0b,0xc18c2e82),LL(0xa6507965,0xd53207a1),LL(0xba323d2e,0x1a96c29e),LL(0xe70d8f52,0xb6698de6),L_(0x00000152), + LL(0xc54265bd,0x14b97128),LL(0xe0b08320,0xfd3dafdf),LL(0xb3fd6699,0xb8bb1956),LL(0x416a87bb,0x038f8691),LL(0x01dd4344,0x88826c84),LL(0x7456566c,0x07a8a4b7),LL(0xb2fca59f,0x037671e1),LL(0x797dc52a,0xf3b10200),L_(0x000000e2), LL(0x5d7843bb,0xee9b4c46),LL(0xfa39c4f9,0x303b1652),LL(0xc4a55ae2,0xc15ae7c4),LL(0x3ccdcb67,0xda8ac526),LL(0x7a17fd06,0x8d1d1e92),LL(0x685ac10d,0x5bfc6232),LL(0x048bbb8e,0x233162cd),LL(0xc2cffebb,0xafee0b11),L_(0x000001d1), + LL(0x20c13569,0x9b91ab1e),LL(0x14810705,0x032808d4),LL(0x6428e5a7,0xdd56117a),LL(0xb86a6737,0x9ed920a9),LL(0x32ca9ded,0x46d45de0),LL(0x0898b533,0xaef720c0),LL(0xc4b5cbd6,0xe8b625d5),LL(0xd262cadb,0x38b1a825),L_(0x000000f1), LL(0xbe07a63a,0xae8c0455),LL(0xc0c992ba,0x56ade4e3),LL(0xd8c4dd74,0xaddf367e),LL(0x1fb487a3,0x10d03d26),LL(0x978961e7,0xced02543),LL(0xb1fb8d4a,0xd9cb94bb),LL(0x4067c3be,0xfd0c7063),LL(0x1e63aa4d,0x0497e03e),L_(0x000000d3), + LL(0x43a818af,0x8e882098),LL(0xa14d3397,0x2df8f9ff),LL(0xfba08f0f,0xc3139e9a),LL(0xd6f4162c,0xd35b42ed),LL(0xddc9743c,0xa29eeda8),LL(0xeaef65fa,0x1d1cf761),LL(0xc4cffc87,0xf5204083),LL(0x9c04512b,0x184be0af),L_(0x00000183), LL(0xcce1fc0e,0x4ca92fa2),LL(0x0756de13,0x7ef7ab66),LL(0x6b218d95,0xa4befba4),LL(0xec5df862,0x028018d1),LL(0xb0fb4797,0x0fba684f),LL(0xbb1872b1,0x035fcdb9),LL(0x727d62c3,0xa85f1754),LL(0x52c190b4,0x9257c1a0),L_(0x000000ed), + LL(0x8c02d54a,0xa33c5b35),LL(0x9d3a0d5a,0xda74fd32),LL(0xcf0e2fac,0xdf27160e),LL(0xa9cf0042,0xce44dc1f),LL(0xf9b4e2f6,0x8815ba75),LL(0x71f7406a,0x5d29fed7),LL(0xba78d604,0x1b44fac2),LL(0xa544aa8d,0x2096cbda),L_(0x000000c5), LL(0x4f2a1a98,0xb052a60b),LL(0x2ee09590,0xfd68dd3b),LL(0xf82abd62,0x4cd7b68f),LL(0x3747e4a5,0xa7a82c3e),LL(0x6580fff5,0xfc1c77a5),LL(0x878185a1,0x29848ebd),LL(0x3507cf8f,0xe376e805),LL(0x3d153708,0x307d42fa),L_(0x00000089), + LL(0xd12cb202,0xde81ad92),LL(0x7dfd0285,0xb71b7749),LL(0x0c150a03,0xf597a8a1),LL(0xe99f4ad3,0xaef51dbb),LL(0x1f4533b0,0x838ed493),LL(0xbcf13b27,0xffc95a8e),LL(0x5623ddf8,0x2b2cefcf),LL(0x37c16683,0x782f0107),L_(0x000001d8), LL(0x8ce740d8,0xf3d3ab04),LL(0xd03ed624,0x376415ce),LL(0x76391c7d,0x22ffbe56),LL(0x671ffe7b,0xcc5f4981),LL(0x90390438,0xae289dd4),LL(0xef0984a5,0xf9a1f5bb),LL(0x41c66528,0x3eb05c49),LL(0xef77ff07,0x5fefc83a),L_(0x000001b4), + LL(0xdc003b87,0x913da2c9),LL(0x7357222f,0xb56a4216),LL(0x44f79a9a,0x435f9dd6),LL(0x6316da1e,0x76bee0c1),LL(0x44a0a348,0x528570a1),LL(0x1fc2528a,0x9e402d88),LL(0xadaf6615,0x23fd690f),LL(0x1b05eafc,0x4359ac50),L_(0x000000eb), LL(0x22ceb0f5,0x9817f70b),LL(0xb1910295,0x586cc9da),LL(0xfd424885,0x92631348),LL(0x902c218d,0x2d6b4b6b),LL(0x3b06ab9d,0xf6ce2b8d),LL(0xc2ef9db4,0x5440a618),LL(0x86f795ee,0xe7115329),LL(0x241af150,0x4639439d),L_(0x000000cd), + LL(0xb84d399a,0x5d1b603b),LL(0x6e75095d,0x3ebd519c),LL(0x0c38a4d8,0x5a2e8ab6),LL(0x703ee9c9,0xbe621b2f),LL(0x46425097,0xeda0425f),LL(0x3bda2722,0x7eaff2bd),LL(0xc82eaa59,0xddb8e21a),LL(0x9f181562,0xe2cfef1b),L_(0x0000013c), LL(0x319323ed,0xf55ade52),LL(0x1195febd,0x72cc0544),LL(0xa5494291,0x34dc9234),LL(0xaa005164,0x2b24e83a),LL(0x2e6ec50c,0x61a67644),LL(0x300b585a,0x2a2cce42),LL(0x251bf8fe,0xc53eb03f),LL(0xa53e93a0,0xaf5e947c),L_(0x00000146), + LL(0xbd450c1b,0xb6233906),LL(0xf8cf8ce0,0x2f163b01),LL(0x37f9bc73,0x121c5a4d),LL(0x74a3b3e9,0x84c581f0),LL(0xd2aa3a2e,0xa16b9ae6),LL(0x7a258259,0x5182e300),LL(0x6d279587,0x3b163221),LL(0x9054a8d4,0xc9bbaf00),L_(0x000000fa), LL(0x650238b5,0xbdfac6cd),LL(0xbc313548,0x60bb5887),LL(0x98e5a28f,0x3b8aace3),LL(0xb0c9ed3d,0x1f5ded63),LL(0x943fdf61,0x3ad1b6fe),LL(0x292fee9d,0x3bea9f61),LL(0x765fb8a8,0xb3aff102),LL(0x1c05be97,0x28393c5e),L_(0x0000014b), + LL(0xdf604a9b,0xe5f51ce9),LL(0xad97f878,0xb763f98c),LL(0x89d3ab54,0x6fef5a13),LL(0x3d0efdef,0xdf2543ab),LL(0x39be5cf0,0x51869676),LL(0xd8322a0d,0x34850193),LL(0x90477611,0xe0860abf),LL(0xf04b3d8d,0x2016c4b4),L_(0x0000018d), LL(0x65e57c44,0xa66238e0),LL(0x78a12a3f,0xd140af78),LL(0x55dcc858,0x65fde14d),LL(0xc7b391cc,0x4d882561),LL(0x2d7dbf32,0xaa74e78f),LL(0x03f85d09,0xed166a45),LL(0x7ad860c8,0xe6da0c2a),LL(0x8d8fe387,0xa3128204),L_(0x0000014a), + LL(0x06980a45,0xdae5a808),LL(0xcd56237c,0xdb2a4bfb),LL(0x1628aed0,0x029fee0a),LL(0x5baf2e6b,0xcfe94b4b),LL(0xbaa05917,0x186a18d2),LL(0x6fb7aa6f,0x3e611766),LL(0x97f81882,0x759b437f),LL(0x25dc9d58,0x1b6c9ec3),L_(0x00000167), LL(0x16ed73fe,0x1dbc5e5f),LL(0xae04984f,0xb2380921),LL(0x00f6d531,0x941b93a0),LL(0x9956e547,0xafda37c5),LL(0xbcd796ef,0xeb23c73c),LL(0xd18e7739,0xec321455),LL(0x9f3b6f4a,0xc9846e98),LL(0x7c09f2f9,0xe0267b0b),L_(0x00000097), + LL(0x447d7aeb,0x4ec21998),LL(0x691aa304,0x062e1539),LL(0xd6b055f4,0x350b4c67),LL(0x310e0e47,0xeee31b24),LL(0xe16697e6,0x24a9c93a),LL(0xc742c710,0x50e8a296),LL(0x5f791c6d,0x511ff4a6),LL(0x4536286d,0x0ed01379),L_(0x000001c0), LL(0x36a695b3,0x301dfa2f),LL(0x07145edb,0x89ff6d58),LL(0xb1a2232a,0xd04785f8),LL(0x27854372,0x37e21f65),LL(0x82b68a6c,0x56a575ee),LL(0xb3063755,0x45ea52c0),LL(0x0e5cba73,0x1f5a3458),LL(0xb3b90431,0x55c3c131),L_(0x0000018a), + LL(0x05a677e3,0x7473a30c),LL(0x5a28a98f,0x8039064e),LL(0x69a1890c,0x559f0687),LL(0xdf1716eb,0x5a68dd8c),LL(0x216c64b2,0x665fa083),LL(0x89b49b44,0x27c0f780),LL(0x952e61c5,0x5e57e0f3),LL(0xc9f22b25,0x1e4e175f),L_(0x00000190), LL(0x9de5f532,0xa33b1f2d),LL(0x6ef509f5,0xd526630e),LL(0x80ca2834,0x2e72073f),LL(0x551bac6e,0x8bdc5409),LL(0xa93f6103,0x74c46ebb),LL(0x78de2a49,0xe616b99b),LL(0xbd4c9f5c,0x5a4f27fb),LL(0x9a70865d,0xb1f197c4),L_(0x0000012d), + LL(0x66505ddc,0x5ed0deab),LL(0x89dc51fb,0x5e972cc6),LL(0xb69dc78b,0x0c6e495f),LL(0x3f182669,0x96d605ca),LL(0x85f61868,0xf6678928),LL(0xedfbfd32,0x863f96f8),LL(0xdece22e8,0x64e644e5),LL(0xf857a4d5,0xc551c9b7),L_(0x000000e2), LL(0x55691ddb,0x1566a700),LL(0x7fa43590,0xe1f4e606),LL(0x796a672c,0x30886e62),LL(0xe5ee14cf,0x40aacab4),LL(0x9b327c1a,0x3294bd68),LL(0x2c002fed,0x103e5699),LL(0xf8494f59,0x9eb1323d),LL(0x51fec2bb,0x7f8bbd7b),L_(0x000001dd), +}, +/* digit=99 base_pwr=2^495 */ +{ + LL(0xcb769c73,0xa9593240),LL(0xb057cdf9,0x4e8217f3),LL(0x220054ab,0x34dceca2),LL(0x5ba1c2a7,0x22b719c9),LL(0x16500d13,0x1b436038),LL(0x0ba1ec57,0xf76e87cb),LL(0x59db2c76,0x77c59385),LL(0xbe033b58,0x47810397),L_(0x0000015d), LL(0xddb6a77f,0xc6a6cde3),LL(0x8f578d9c,0xe4987253),LL(0xeaf37819,0xa10e469f),LL(0xdc9c48cd,0x0f98832d),LL(0x51a6e545,0xbf05ea5f),LL(0x195d2d31,0x75cd216a),LL(0x89987c43,0xd18007e6),LL(0x358f3e07,0x0eb94cbc),L_(0x000001d6), + LL(0xd66a73f6,0x68ca281c),LL(0xa08670f9,0x827efca6),LL(0x180e8f32,0xeac3a96b),LL(0x9979b757,0xbff7df80),LL(0x2d9223bf,0x166015fc),LL(0x30d747dd,0x5475a887),LL(0x9ea9d126,0xfbce1622),LL(0x23756de3,0xee18876d),L_(0x000001e4), LL(0xa8ed537b,0xe46c7c15),LL(0x6d7df943,0x4b3f8765),LL(0x335be530,0xdb8a9213),LL(0xcb0ee208,0xb61ee376),LL(0xa4f5fc16,0x4ee85495),LL(0x2d47c111,0x53ced62c),LL(0x453ad352,0xaf641c92),LL(0xe1a21d73,0x4f8dd3e4),L_(0x000001dc), + LL(0x515c16f0,0xa0b8ef31),LL(0x11c31db7,0x6aca4236),LL(0xa62abc90,0xc862474f),LL(0x94eec3da,0x600cabaf),LL(0x3cb82e64,0xec07e4a3),LL(0x3c98aa82,0xef67e3ea),LL(0x548e4dc2,0x3817b7a5),LL(0x6160dfbe,0x5240c7b0),L_(0x0000008a), LL(0x212ed3d8,0xa341dfe1),LL(0x71cd3579,0x96070d42),LL(0x9ade2ce0,0x0d16c811),LL(0x6ffd05f0,0x1f2ea906),LL(0x4add5623,0x9034240f),LL(0x871a6489,0x92dc3317),LL(0xd71bf3b7,0xd6ec77d9),LL(0x3faf4d88,0x2292f10a),L_(0x000001aa), + LL(0xab483ff2,0x0cb9492b),LL(0x1910717f,0x1999673c),LL(0x5ba40ad7,0x61f5c7a7),LL(0xec8c1ec8,0x7a954022),LL(0x87870445,0xab6d023c),LL(0x607c1194,0xdaf5008c),LL(0x53612330,0x4ad39492),LL(0x5bf20a93,0xbc2055ab),L_(0x00000193), LL(0xab8ed330,0x045574d7),LL(0xf38e3b31,0xed11cb44),LL(0xab10bb4e,0xa511af67),LL(0x33cee10c,0x9fe7c1d0),LL(0x1549874c,0x6999489f),LL(0xa85b392d,0xfcfe4a15),LL(0x3684decf,0xb3b006a1),LL(0xbaefda3e,0x2c4ef7b8),L_(0x00000036), + LL(0x3d2bc261,0x1ee7f1c9),LL(0xd8d2c223,0x25894a88),LL(0x1159870b,0x106d0fe5),LL(0xac7070a4,0x37cd1eb7),LL(0x45edd566,0xfcc105e8),LL(0x0d87aaf2,0xbbc54886),LL(0x650d534b,0x4c68c1c6),LL(0xf8b73f4b,0xa090fd18),L_(0x00000116), LL(0x1c67e752,0x9fdf5e33),LL(0xda66e59f,0x1506a29f),LL(0x04eb7efc,0x566aa91a),LL(0xaf0c681f,0x41ad74ab),LL(0xcd6fd019,0xa0e6609f),LL(0x90d32f02,0xf9f03394),LL(0xc3f5d1da,0xbd5dbcf1),LL(0xa63c99d2,0x0f138d5c),L_(0x000001b6), + LL(0x94e82cbf,0x52832eb4),LL(0x61b4102e,0xb381c8b4),LL(0x7f0afbca,0xf1ba6e87),LL(0x8482ae88,0xc8cc076b),LL(0xd709eb28,0x5fc8e5ce),LL(0x0c640cd4,0x1363d1cf),LL(0x6be8f78b,0x4993a63d),LL(0x7a8e7f6a,0x60d50140),L_(0x000001ce), LL(0x1bfd703c,0xb3415df0),LL(0x8b57f708,0xf82eeb2c),LL(0x407aa69d,0xa723ed35),LL(0x9767c6b4,0x4dbc3f44),LL(0x52e1a818,0xdffc3e96),LL(0xad89d25e,0xe8855e29),LL(0x89f2e493,0xb2c695a8),LL(0xae2a995a,0x17ec825d),L_(0x00000011), + LL(0x7948d6db,0x1bf35a68),LL(0x6953ece3,0x2e4f6945),LL(0x5f0ffde7,0x8e48e233),LL(0x45b68e1d,0x805943a8),LL(0x7c03271d,0x83acacfb),LL(0x136c96e1,0x20b340c8),LL(0xb32c48cc,0xbf7ec9c0),LL(0x9a5cdcd3,0x6c769d3c),L_(0x00000065), LL(0xeda9d905,0x02288f5d),LL(0x6d5bb5e0,0xe250809d),LL(0x26841f8e,0x3ede31ca),LL(0x5b8a74f6,0x941707b2),LL(0xcd744281,0xf31b5a51),LL(0xcb81c384,0xa2b751ad),LL(0x1c7d45f0,0x98cd14ff),LL(0x0b61414f,0xfb2bcceb),L_(0x00000029), + LL(0x49c300d6,0x149cc932),LL(0x984e1f84,0x4f71e87a),LL(0xa635f884,0x2ebebead),LL(0xc51f4894,0x8d815dca),LL(0xb76c6b87,0x60dede95),LL(0xc3f25874,0x83c91cf8),LL(0x53753878,0x6d13e9be),LL(0x4ce987a5,0x59e4476d),L_(0x0000007b), LL(0x22fb2015,0x4bf1c2d6),LL(0x8bc4abf5,0x22da7f9e),LL(0xe7b83f3a,0xe42051b0),LL(0xeda536a6,0x9d89d573),LL(0x3ce8431a,0x64d23c5a),LL(0x3eec2b7a,0x07a6be7b),LL(0xb5fb43a0,0x5b672919),LL(0x4a7d1800,0xebe85c45),L_(0x0000002c), + LL(0x54bf1abe,0x835f5200),LL(0x88be0ac1,0x80a69454),LL(0x37a520fe,0x1ae181ec),LL(0xfbf51fae,0x1dbbcb25),LL(0xe0a144d5,0x7481d4f7),LL(0xbb7cdca1,0x89f680f7),LL(0x0d5abe7d,0xb4b624a0),LL(0x391425d4,0x8d9200f3),L_(0x00000131), LL(0xb4188e07,0xbfd1f50f),LL(0x6575b3b7,0xa43201e2),LL(0xbba2a525,0xe0fef193),LL(0xc9408771,0x2d5a89d3),LL(0x5fad41dc,0x95a6705b),LL(0x7d9dc257,0x9020f8bb),LL(0x290e4eb8,0xfbd17a63),LL(0xbb41e71c,0x495438d2),L_(0x000001c8), + LL(0x929f484a,0x0aa411ba),LL(0x72a995e9,0x16fc135a),LL(0xc8dd8a3a,0x2226cfa3),LL(0xefeed6df,0xebb1a266),LL(0xbe66eb40,0xd15ad7b0),LL(0x9e390f8a,0x0c3a1992),LL(0x4d13a05e,0xd151e340),LL(0xcf393bac,0xd2f40175),L_(0x00000053), LL(0x956cdbeb,0x4f6ce102),LL(0x1a20db88,0x3138d132),LL(0x4bd065b9,0x3956528c),LL(0x082878ee,0x1ab3833d),LL(0xc2946565,0x49e6b0dc),LL(0xe955cb4e,0x10248d30),LL(0x1ae9cc37,0x9e6e01a5),LL(0x5567eab8,0x130292fc),L_(0x0000009b), + LL(0x263e83bd,0x531fddd1),LL(0x56ab0f10,0x11105bea),LL(0xe11b8ec7,0x98797be3),LL(0x1992abc2,0xec87b621),LL(0x2f8db083,0x8d258c0b),LL(0xb3d171f4,0xac2ced2a),LL(0xd1cb21ab,0x7bcca55e),LL(0x47bc4dad,0xf87bf80d),L_(0x0000002f), LL(0xf1f3098d,0xb97a56f7),LL(0x30359457,0x13b63e78),LL(0x5c0291e4,0x0560b59b),LL(0xfd66b1ed,0xffcd1e35),LL(0xab62195d,0xa68ddbd9),LL(0x5e1a88f2,0xc8f7a10f),LL(0x5805f677,0xc770a044),LL(0x145b476e,0xf8481566),L_(0x000001cf), + LL(0xfec59218,0xbad5f014),LL(0x29cb3195,0xdeabd554),LL(0xfb9c1406,0x8cab2ab5),LL(0xf39524ff,0x1480bd6c),LL(0x6fbb57c0,0xc932f537),LL(0x34f118cb,0x9e4e5da0),LL(0x6eb8d83c,0xa6fb16c3),LL(0xc80fc4ea,0x5ea94048),L_(0x0000000e), LL(0xbe668aa1,0x614afa98),LL(0x9a412d4f,0x4cadab47),LL(0xb94d7822,0x933864b0),LL(0x51053a74,0x424e5f26),LL(0x3dd43fe6,0x600bdaac),LL(0xf8a04f2c,0xc0b432cc),LL(0x4257110e,0x2f4d8257),LL(0x58edc3e1,0x39fcd24e),L_(0x0000003c), + LL(0x42ad308f,0x07b9420d),LL(0xf2ff228d,0xf800adda),LL(0x959a36a9,0xa755b758),LL(0xe791f71f,0x06570844),LL(0xc9aeec3a,0x2525c1b6),LL(0xf99b3c09,0xfae920c4),LL(0x93e1e24e,0x54cdd224),LL(0x4a6949cb,0x1394e308),L_(0x0000005b), LL(0xc1192578,0xf0af3d86),LL(0x042c14ae,0x035da967),LL(0x54675869,0x65aba6d1),LL(0x00ddf870,0xfb6525b8),LL(0xcb3618ed,0xa58a9ef1),LL(0xa2776a71,0xd7373181),LL(0x9adaa84e,0x5acac693),LL(0x7c38e845,0xa9836617),L_(0x0000017a), + LL(0x17d5163c,0xb8856ff7),LL(0xc5c08271,0xa79d0557),LL(0x32810d21,0x16514840),LL(0xa6e95174,0xce8f06a5),LL(0x393b8782,0xf14b15d0),LL(0xdf3da6f7,0xa398eeac),LL(0xc040c1ac,0xd2eb31c7),LL(0xe9ed34f4,0x5308a3ac),L_(0x0000005e), LL(0x6386bac2,0x294f7bd0),LL(0xf986d8d5,0xec0b7a55),LL(0x55592285,0x96568681),LL(0x15833824,0x307162e2),LL(0x03366d9a,0x196efa15),LL(0x78331de9,0x6afbb75f),LL(0xce11aa87,0x4246ce65),LL(0xa207e319,0x9fea12f7),L_(0x00000198), + LL(0xdf95cccc,0x2c3a928b),LL(0x954c7e07,0xb87fc4e2),LL(0xc556dd0f,0x5dde9996),LL(0xa10a09f2,0x017edf41),LL(0x126b8ebf,0x11739253),LL(0xe86b6fe5,0x1f9be2dd),LL(0x7b89b849,0x4acd9273),LL(0x572a4b24,0x21e7f018),L_(0x000001c5), LL(0xe035ed7d,0x8545db72),LL(0x1c4fb913,0x52bc38af),LL(0xe8b8d046,0x500cd8de),LL(0xd8bd36cf,0xc86ac9e5),LL(0x7fd4ed73,0x82941dac),LL(0x968c57f8,0xcd1842b9),LL(0x806ab108,0x4885bf1c),LL(0x7821dec4,0xb8c5054e),L_(0x000000d2), + LL(0xf8d6129f,0xbddf5a7c),LL(0xb2f43150,0xb4988625),LL(0x3c2f3809,0x1299bbfb),LL(0xb080f7b3,0x84ed45f5),LL(0x20ab0abb,0x824f7bed),LL(0x533e510d,0xd6447243),LL(0xb64fbbb6,0x67c576b7),LL(0xcaa9ee82,0x1f4a9e16),L_(0x000000fa), LL(0x4253a269,0xf68fe622),LL(0x4572de06,0xa777b687),LL(0xcf599bf5,0xa16d5f86),LL(0x2a811045,0x94a33dfe),LL(0x08732642,0xac970a0c),LL(0xd6867a04,0xeb2b7d05),LL(0x0e51a57c,0xad29a28a),LL(0xbf79a38e,0x160ffbac),L_(0x000001d4), +}, +/* digit=100 base_pwr=2^500 */ +{ + LL(0x103efe86,0xcb9e407c),LL(0xaaa13853,0x0e6c71ed),LL(0x1b70a2af,0x5ae18f75),LL(0xcf7e3e82,0x1ec11bb0),LL(0x45c36a5a,0x56ab4b56),LL(0xa4e5487f,0x86df052e),LL(0x3868ef9a,0xc7d75031),LL(0xee422740,0x85ec4e60),L_(0x000000db), LL(0xb7ee652b,0xfaa97f40),LL(0xa3dd7397,0x294d2d1b),LL(0x453daecf,0xe65344d3),LL(0x24bd3f56,0x1c9985d3),LL(0xc78c6f61,0x2675985e),LL(0x8ad7e24f,0x8b4060d3),LL(0x6c928213,0xffdfb749),LL(0x27a6ad57,0xfdbabbe6),L_(0x000001a8), + LL(0x589be6a7,0x313031bd),LL(0x84289d06,0x704962d9),LL(0x522512df,0x4932ec5b),LL(0x6a669eef,0x4db07538),LL(0xcfe74767,0xabd7aebb),LL(0xe7944dba,0xd27fb22c),LL(0x458ef814,0x6ae70494),LL(0xc9680563,0x42cd4fad),L_(0x000001cb), LL(0x6c5b60c5,0x915adb1e),LL(0x108c6584,0xf8937e8e),LL(0x64ea3a9f,0xab88406d),LL(0x61d268f9,0xd6126f44),LL(0xae3ff279,0xed1f3032),LL(0x22a5d3b3,0x3a1b63af),LL(0x2fd7a532,0x90caf928),LL(0xf7a42a75,0x67ff1d99),L_(0x00000023), + LL(0x9fdfb005,0x179f05f7),LL(0x91c70d36,0x1f0a00c5),LL(0x1bdb8aa0,0x13b09f86),LL(0x1877e4cc,0xab098b85),LL(0x804921bd,0x47ca3471),LL(0xb874265f,0x78a5d59c),LL(0xeb734d84,0xbb8aac74),LL(0xa87e5bc7,0x94d792f6),L_(0x00000002), LL(0x635dd559,0x340b409a),LL(0x4cff9fd3,0xe395e617),LL(0x83237476,0x0e435fdf),LL(0x995df5d9,0xacf9026e),LL(0x0535beb0,0xf60fe3f2),LL(0xc3baddc2,0x21d68a60),LL(0x5d079f08,0x8b800543),LL(0xf7a20c38,0x5d89e84e),L_(0x00000010), + LL(0x061ce962,0xee54d7fc),LL(0xe676ddac,0x8e982883),LL(0xfc5997cf,0xe8ccea68),LL(0x4f3d06f1,0x42831bb9),LL(0x57b80d82,0x625c3604),LL(0x7389ec2e,0x5466a1d8),LL(0x13ff25b1,0xf9c50093),LL(0xfb5d45d1,0x0590b45e),L_(0x00000092), LL(0xab4e32c6,0x08ec78b5),LL(0x24014646,0x53a9c0b3),LL(0xd5ffb795,0x5594ddea),LL(0xf933bdcc,0xdc110f8b),LL(0xd5249289,0x5d52f652),LL(0xcb4147d2,0x95ab06c0),LL(0x968adb2d,0xa1bbff17),LL(0x4039be6f,0x8c602266),L_(0x000001e4), + LL(0x186c159d,0x6c1da851),LL(0x87f87d48,0x2ffecac8),LL(0x326e8ac4,0x70a401c5),LL(0x68a082d2,0x0bd703fe),LL(0xbb17b4ec,0x9fe82427),LL(0xd5029b1a,0xf75c6b25),LL(0x8859df58,0xfaac56e2),LL(0x0f97f9bf,0xc8a4fbc7),L_(0x000001dc), LL(0xaf73b932,0xe721dc13),LL(0x98f115f8,0x825bde14),LL(0x102f60c7,0xf0780fd3),LL(0x92e5a9e9,0x9fcac3f2),LL(0x96a4edbc,0x51ae4427),LL(0x123f8f26,0x622ca1bb),LL(0x3d2d6a72,0x4fa4ca10),LL(0x77d0f199,0xc7c42ca5),L_(0x000001c9), + LL(0x33e577af,0xbf557eaa),LL(0x98005156,0xca7cba0f),LL(0xe3d41486,0x73d1e9d6),LL(0x3a30b9f9,0xaa3443ad),LL(0x99856b55,0x81921940),LL(0x0ca4724f,0x250cf13f),LL(0xba1696b8,0x9b6f0f69),LL(0xba1deb1e,0xc260563b),L_(0x00000021), LL(0xa037cb66,0x7437eb08),LL(0xfaf55d7e,0x579149c6),LL(0x43f7c61c,0x921e4c69),LL(0xeba03e36,0xc342ab26),LL(0x0a3ade34,0x86264eb6),LL(0xcf120523,0xffc57653),LL(0x914e6e20,0x5770eec7),LL(0x2d678456,0xf286b491),L_(0x000000e5), + LL(0x3106fc3e,0x9739a62b),LL(0xd166966e,0x6ea97e6a),LL(0xbc843284,0x0fb2aa2b),LL(0x1768bc4f,0xbd1f5f87),LL(0x0a51f2d1,0x8890f99b),LL(0x5f53245a,0x6a0000aa),LL(0x38e0dc0b,0x49547c15),LL(0x3dbece21,0x5c37a1c3),L_(0x0000000e), LL(0xeab56de1,0xcb15a8e3),LL(0x8e0ff0fc,0xc00352a7),LL(0x0dae3bf3,0x716e7d48),LL(0x273cee30,0x83dde892),LL(0x00962a42,0xe18ae53b),LL(0xcb2ce674,0xb8c78835),LL(0x12176412,0xc6faee27),LL(0x94e0f5e7,0x2f8a2462),L_(0x000000f7), + LL(0x78569761,0x266d871a),LL(0xe7df9590,0x015aa94b),LL(0x4e8bbf72,0x150482ac),LL(0x12880439,0xaa4b2f7c),LL(0x53495f23,0x5ef777bb),LL(0x04a67481,0x38a798c0),LL(0xc7aadc88,0x308a425c),LL(0x2ccb5f57,0x0a9adc43),L_(0x0000005b), LL(0xb506af85,0x718ebc6c),LL(0xdd21e3a6,0x2c50bba9),LL(0x56098fde,0x7b6e3c4d),LL(0xa8a72185,0x02f4d7a4),LL(0x9218f9c4,0x55530e5d),LL(0xa541a6f2,0xbf7b3c63),LL(0x97421bb0,0x04f0181b),LL(0xe7a08f28,0x1e51023d),L_(0x000000c8), + LL(0xb7a89c2a,0x59bf73de),LL(0x701684bf,0x59572fc8),LL(0x8134fb14,0x116042d5),LL(0xc2db37ef,0x49c61bec),LL(0xf05c9753,0x0b65e976),LL(0xbbefa454,0x3b1cd2a7),LL(0x2cb97f65,0x790f0086),LL(0xc011e095,0x388368d8),L_(0x000000c2), LL(0x170eba17,0xc6e8d2e1),LL(0x609e9ebc,0xe69224f6),LL(0xa74251dc,0x88ae4a2d),LL(0xf5331e8f,0xf73bb04a),LL(0xfb6fb779,0xf42091f4),LL(0x7aa76758,0x23ea8c88),LL(0xf921d2fe,0xb43fc164),LL(0xb83f6c60,0xf692414b),L_(0x000000f9), + LL(0xb2f332da,0x1235350c),LL(0x3fc1272d,0x28803380),LL(0xcc94724d,0x52679e63),LL(0xa1b6d063,0x5f59afa4),LL(0x8fd15f1d,0x1998f9ec),LL(0x67514283,0x856a5843),LL(0x0b1f071f,0x44e35d97),LL(0xa4396ed8,0x12b07c24),L_(0x0000015d), LL(0x209d5128,0x36d77579),LL(0x3d71f02d,0x6903b9cc),LL(0x242255da,0x255e80b9),LL(0x0d577ece,0x8c99ca99),LL(0xcce7a8ce,0x6e67b351),LL(0x8274de19,0xb1789c3b),LL(0xd9d46d98,0xb68f17a4),LL(0xbe658d62,0x4303e990),L_(0x0000003f), + LL(0xb2d11384,0xc0e43052),LL(0x18ea1e36,0x6499f986),LL(0x67f0543f,0x6c81b7cb),LL(0xfe7f0035,0x0049686c),LL(0xc866a608,0xd1d9672f),LL(0xad63f7a9,0x402ddc59),LL(0x0430d4e2,0x90a63a4e),LL(0x212afc89,0x76142f1f),L_(0x0000016b), LL(0xa5a4f004,0xb4669198),LL(0xe3c06d85,0x9dbced32),LL(0xd46b4406,0x6dc0df8d),LL(0x13bbdb5b,0x26fe23c2),LL(0x9e72fe86,0xf3f82db4),LL(0x9908a610,0x21de6fb9),LL(0xacd7a7dc,0x84215e98),LL(0x8d6e691f,0x6fc1bb6f),L_(0x000001a9), + LL(0x6a2a68fa,0x1a45088f),LL(0x097c3677,0x93e569b4),LL(0xf6248b6e,0x76442347),LL(0xf5aa90b0,0x7db67859),LL(0x47468b1b,0x0335b7c8),LL(0xc14d722e,0xbdb192bb),LL(0xa89357c4,0x6091e296),LL(0xabbee708,0x6196a7a6),L_(0x000000b7), LL(0xb79d5c35,0xfa81b0bd),LL(0xb8c1d912,0x9c98ad08),LL(0x6f43a564,0x487e8e86),LL(0xb8305a15,0x68d70b11),LL(0x4f253374,0xda0a3387),LL(0xc3ee2674,0x12970085),LL(0x7d1dcff2,0xabf94fcc),LL(0x3abb8f41,0xaeb5fcca),L_(0x0000004b), + LL(0x43ae6f56,0x2ecfea4f),LL(0xbfbd972d,0x1717ff60),LL(0x50d6adf6,0x54f2d354),LL(0x6c6e24d6,0x2e42a5a9),LL(0x8ef967c8,0x2c029c93),LL(0xef490e17,0x74b0a604),LL(0x3a515366,0x835d8fbf),LL(0x878ca8ab,0x312194f9),L_(0x000000f2), LL(0xb19f5e63,0x0a7f849d),LL(0xe7343af4,0xa13e0960),LL(0x93d2a93e,0xd7e39973),LL(0x58e4acec,0x89b42cb1),LL(0xb14fea72,0x128188b6),LL(0xaf37faab,0xfe8c3b50),LL(0x51d9f7ee,0x2b121d0a),LL(0x5997d399,0x6e0873a5),L_(0x0000004b), + LL(0x70a88d95,0x0ae00340),LL(0x2c6b6f8f,0x941fb569),LL(0xd4a8a83d,0xfd77e569),LL(0xfe3e5239,0x2906296c),LL(0x5d2269e6,0x779ada15),LL(0x65afaeca,0x46fce296),LL(0x41d7fedd,0x0ceb36d9),LL(0x39bc7e8f,0x8c21b413),L_(0x00000081), LL(0x5ebed878,0x04b873d1),LL(0xb3e0c338,0x061d2bb8),LL(0xd36ffa7e,0x596e92bc),LL(0xbde7e857,0x58c9a5ab),LL(0x78a8b297,0x34780b9b),LL(0x6bd40718,0xac60511a),LL(0x2d3c02e9,0x83e6ac72),LL(0x6d092687,0xb6802b12),L_(0x00000070), + LL(0xfd72e9bb,0x99783135),LL(0x67ff52e3,0x8dc913fd),LL(0xab427847,0x8986e4a7),LL(0x5377b12a,0x8a8d9fc8),LL(0x57fef8f8,0xb61bed13),LL(0xf189dc79,0xd4bb14a1),LL(0x2e6d28f7,0xcd3d6f13),LL(0xf00e6579,0x74cb87a6),L_(0x00000146), LL(0x14efe417,0x9fb6caaf),LL(0xabbb19b6,0x951205f5),LL(0x787b1023,0x440fd20f),LL(0x4968e195,0x6d5f6164),LL(0x33cbed34,0xa2722dcb),LL(0xf576c320,0xbddf2d94),LL(0xb80ba0c8,0x414feeda),LL(0xeb25ced6,0x5a089c08),L_(0x000001e8), + LL(0xaa61ebad,0x6aced3dd),LL(0xe5fe2dd4,0x0bd3e3fd),LL(0xfe14f9f4,0x09520569),LL(0xd818d1a2,0xb4968b88),LL(0x82f0bdc9,0x0b8b7732),LL(0x6520e3de,0xfe9e8edc),LL(0x272ff767,0xbc017cf0),LL(0x0f65dc99,0xc5848eda),L_(0x0000013d), LL(0x0a9b50b0,0x4ea634ab),LL(0xe6308ff0,0x7b191db6),LL(0xee04399a,0xddea9de7),LL(0xda7bdea8,0x492d45e6),LL(0xb54c55ae,0x39e666b7),LL(0xf573f4e9,0x0c925a51),LL(0x0292c159,0x71f91622),LL(0x80fc7f50,0x8069f2d3),L_(0x0000007b), +}, +/* digit=101 base_pwr=2^505 */ +{ + LL(0x53639a92,0x1ce7b1b4),LL(0x1474fb3a,0x0d260e43),LL(0xaefab808,0xc4e32954),LL(0xfaf9e670,0xb5bae76d),LL(0xde42d0d7,0x9eb4687f),LL(0x5f45bfa8,0x7d89b1ca),LL(0xba638bbc,0xc0ecce4f),LL(0x1de873fc,0x7a3238a2),L_(0x00000170), LL(0x36c9c2b4,0x318f9f96),LL(0x2cb815fb,0x6f676d6c),LL(0x7560919e,0x41cc633a),LL(0xe2d47525,0x9a79e211),LL(0xe199c599,0xfbee081e),LL(0x265f515d,0x3107dec5),LL(0xd0ea4e25,0x6f2bdc9e),LL(0x5a539ab3,0xcbfab41c),L_(0x00000122), + LL(0x6ffa11c2,0x1bfc6586),LL(0x1f882706,0xe25c9a78),LL(0xeb5d1a25,0x12852d54),LL(0xe5fcb1fe,0x4f331734),LL(0xd8c5dfb7,0xe48b7e54),LL(0xcfadcca2,0xe9b41639),LL(0x193402d5,0xb8e1f8c2),LL(0xc49e8f71,0xae02f348),L_(0x0000005a), LL(0x4e33ca43,0xe98a1f64),LL(0xa7cb416c,0xbd595ac8),LL(0xe328cd45,0xf8fd4eb1),LL(0xec3fd8cb,0xf768cfe8),LL(0x9eb626b0,0x476b1bbc),LL(0x069d1524,0x8d0ffe31),LL(0x220edd8d,0x2925aa89),LL(0x60b37558,0x7ea1a636),L_(0x00000128), + LL(0xe83c1031,0xc5cc621c),LL(0x434bc9bb,0xac957c67),LL(0x27bcbc47,0x430a3686),LL(0xace0a905,0xed2cb5ad),LL(0x38aa0831,0x0f4f5d32),LL(0x1fa3c11d,0xc48e91c9),LL(0xedbfb351,0x98229765),LL(0xdf2591e4,0xeef1832b),L_(0x000001e9), LL(0xe38e4555,0xa53bea9a),LL(0x97db1ecb,0x196518c9),LL(0x58970b56,0x6895c332),LL(0xc6b46d1e,0x0fe772a3),LL(0x18e44ad3,0x48216056),LL(0xaf1a5dd6,0x86d1933f),LL(0x18ae6deb,0xdf5a53d7),LL(0x4345a6ba,0x79fa1e4e),L_(0x000000e5), + LL(0x0deafce5,0xa11885f4),LL(0xf942172b,0xd640aa98),LL(0x17ce6b52,0xdc1bfcf8),LL(0x9d8e40bc,0x14a7d638),LL(0x3c804e7d,0x80e95516),LL(0x63048fa8,0x4af7c92b),LL(0x15381b03,0x88fd6851),LL(0x73ec6a96,0x79207faf),L_(0x000000ff), LL(0xf4f85d1a,0x6ba36666),LL(0xf47de871,0xfbfc6c17),LL(0xf9474540,0x70e03b35),LL(0x72b1ddc6,0xad63874b),LL(0x7f48bdd3,0xd249ea68),LL(0x6a15d7cf,0xc1614192),LL(0xe9d101f9,0xacd8d963),LL(0x1b9b1c2f,0x09164077),L_(0x000001e7), + LL(0xc3b944a7,0x8b0aff56),LL(0x97b94164,0xacb2b2a3),LL(0xfade0d57,0xe22c59c3),LL(0x72ad3ddf,0xd8b6f7d4),LL(0x4a332f59,0xe436d0e5),LL(0xb28ca267,0xa69516f2),LL(0xc620d57f,0xdd5b988f),LL(0xb3a24be6,0x14f91326),L_(0x00000166), LL(0x7dc7da50,0xf918114f),LL(0xa2d07106,0xb35f8ba3),LL(0xfe3e2734,0x583e00bb),LL(0x27f4b785,0x5b427e96),LL(0xb8110ec6,0x6198344d),LL(0x2666790f,0xc2f9267c),LL(0x9a6bed52,0x15a1c587),LL(0x05e6612c,0x2f681667),L_(0x0000001c), + LL(0xeddc635b,0xb97227a6),LL(0xf72fcd23,0xcc5023cf),LL(0x16ff8449,0x4d184e1b),LL(0xa6e3cc25,0xb6176789),LL(0x14e442c7,0x200d2b68),LL(0x147e4e2b,0x9903da3b),LL(0xa26bbf3b,0x6b6aeb08),LL(0x849b5dc2,0x06fb145d),L_(0x00000147), LL(0xbb6ef597,0x250dac2d),LL(0xac7eb4e4,0x0cadff32),LL(0xfb97f1fe,0x1e4bc394),LL(0x2549b2e2,0xa4d9b459),LL(0xc81df54d,0xedb4d3d9),LL(0x885b7f7b,0xa8c245eb),LL(0xc2642e0e,0xfd485de4),LL(0xbbbd9d24,0x16b28ef9),L_(0x00000117), + LL(0x82620992,0x9bdd489e),LL(0xf9ff35e3,0xe0746b33),LL(0xfea9ab53,0xc4e354c0),LL(0x5438eb93,0x660ea2e7),LL(0xe43d99e6,0x15697bab),LL(0xcb7634f2,0xacd2ac86),LL(0xcf1f1144,0xd531df3b),LL(0x2d6020c4,0xa6e4c25c),L_(0x00000082), LL(0x5eadffbf,0x79147d9d),LL(0x6799957b,0xf22818e2),LL(0xfc746f29,0x7b9b1ddc),LL(0x87c40fbc,0x5518ebb6),LL(0x12ffe947,0x9a81391e),LL(0x997b0c31,0x3a724bee),LL(0x02662680,0xe08a5f24),LL(0x1ebe1250,0x1f28a865),L_(0x00000175), + LL(0x3b6bccc6,0x4b51d15f),LL(0x4d9896e4,0x61b0ed08),LL(0xdf4f3be0,0xcedf84c9),LL(0x6ed8e29b,0xf45bde62),LL(0xaa49395c,0x128499be),LL(0x812a1bfb,0x30e7b9a9),LL(0x442e44bd,0xe50016d9),LL(0x251b4710,0x608c2577),L_(0x000000be), LL(0xb4c58ea8,0x8972e1af),LL(0x6a3b7639,0x2d603c3a),LL(0x64b41953,0xad6090f4),LL(0x1c1cc6d5,0x644bda3e),LL(0x79fc4551,0xe003b3c6),LL(0xc4fe3bf0,0x879a2d4d),LL(0x9f3993d4,0xd0249205),LL(0x90933a0b,0x4bf1c894),L_(0x000001f5), + LL(0xbaa0eb60,0x64977e8a),LL(0xed1a5135,0xdb1eee40),LL(0x7fe9e6fc,0xef595c17),LL(0xbc2a7a81,0x4d74eea7),LL(0xafbb2385,0x34f92af2),LL(0xffa66ed1,0x9f246323),LL(0x91252082,0xd49955a9),LL(0xa2901a50,0x612b9e01),L_(0x00000163), LL(0x19a6a510,0xae624c6c),LL(0xf34dd865,0xbf77202a),LL(0x6cbac9c8,0x0d692aaf),LL(0x2471eb03,0xae2ff6e2),LL(0x4e8b52f6,0xfc37aa01),LL(0x96b6740a,0x5ca85277),LL(0x4fc2258e,0x1a66c773),LL(0xd7c07ad3,0xc3b9c722),L_(0x0000014c), + LL(0x3efb63d7,0xb52733b4),LL(0xadb5f371,0xa39008b4),LL(0xbebb4df3,0xb7dee0b6),LL(0x6cbc3a0b,0x889767ea),LL(0x0970ea6b,0xfb4bece2),LL(0x7f67b6be,0x890b0f75),LL(0xe72afc5e,0x8395198d),LL(0x6c13b8e8,0x792b05e1),L_(0x0000011b), LL(0xcd597e49,0x85730a39),LL(0xd16d451d,0xbb9ddfb7),LL(0xc5ad35f5,0x46f1005a),LL(0x04cccc76,0xfc9aa038),LL(0x199ada1e,0x03f6f34d),LL(0x48f0a0bd,0x200aa943),LL(0x2532adab,0x83389203),LL(0xa871ac66,0x84008498),L_(0x000001a6), + LL(0xd09b5635,0xc63c436d),LL(0x1bf51ded,0x36468adf),LL(0x71acd515,0x98fc5e09),LL(0xf48ba93b,0xed9c3a1c),LL(0x0c6b0d79,0x01b9c574),LL(0x24610fb1,0xb968199b),LL(0xe209e9f6,0xbbce4f03),LL(0xeee7632a,0x34954c95),L_(0x00000158), LL(0x7c32158c,0xce330212),LL(0xeb40d5de,0x1694cc96),LL(0x981c6977,0xddf4fc29),LL(0x9ea41d2c,0x89f8c78d),LL(0x86af7d31,0xd67b4c4c),LL(0xf2c9d3cf,0xad9e3351),LL(0x16fcf6af,0x702ac15c),LL(0x16ccd30f,0x671dd4b0),L_(0x00000056), + LL(0x31986e71,0xafcb621c),LL(0xe99b97d2,0x3f65ee43),LL(0x0c39ca80,0x14bf4d0a),LL(0x4ebb930d,0x840ff2ab),LL(0x894804fb,0x76798c37),LL(0x89a1b227,0x3aa6a099),LL(0x34d5a9a4,0x6f4a66e9),LL(0xdd3ebcad,0x671c865a),L_(0x000001de), LL(0x63a60589,0x9cc5953b),LL(0x6c38743c,0x85a6854a),LL(0x08e7cd4c,0xf39a75be),LL(0x936c5fc4,0xfc799df1),LL(0x93f15bcf,0x739e6699),LL(0x4c317bf9,0x2e5c38de),LL(0x6db73251,0x427a1224),LL(0xa307eb83,0xe63f9f36),L_(0x000001b4), + LL(0xdc077b67,0xa1669c8a),LL(0x49cbb3e1,0xd5e45b94),LL(0x26a91035,0xe7362c4d),LL(0x3ddf32d0,0x643b77a9),LL(0x27b4f14e,0xaa5ac709),LL(0x1246b2b6,0xfed505b3),LL(0xce87322e,0x6473f9c6),LL(0xffc4c045,0xaf22c521),L_(0x00000154), LL(0x4300e539,0x1c3ea4fc),LL(0x79dff91b,0xe9151768),LL(0xe8106a01,0xced48484),LL(0xd2bbaae2,0xb0b62aaa),LL(0xec766cbf,0x4fd3762d),LL(0x3740af93,0x1969f618),LL(0xeff16696,0x481e8d46),LL(0x08f70c0b,0x17f67b91),L_(0x000001f3), + LL(0xe6e4ffd4,0xd4cc0359),LL(0xdeb8f8ef,0x6a7bc267),LL(0xb0f6a0db,0xceec7c5d),LL(0xbe8f401f,0x328be59a),LL(0x0120834c,0xea6a0206),LL(0x5b979c4e,0xc2f2cb42),LL(0x6693b49a,0xc70270e4),LL(0xcb7ea005,0xf0d4e23e),L_(0x000001f0), LL(0xd93cd84b,0x59acbb8f),LL(0x771ac6f4,0x37d3f220),LL(0x5f43f61d,0xe983e186),LL(0xe1ef31c8,0x66433715),LL(0xe567c88b,0x4ca008fa),LL(0x4f949b3b,0x164fa949),LL(0x7f0981e7,0x55a6f6fe),LL(0x85c2f160,0x53287c30),L_(0x00000084), + LL(0x0fe60315,0x778f4301),LL(0x3d35c1e7,0x42ff27b9),LL(0x4e622807,0x9ba721f4),LL(0x9122d492,0xc966361a),LL(0x0b7b9eb9,0x824265f0),LL(0xd71fbe97,0x90d81101),LL(0xf6012c22,0x3aa81035),LL(0x77c80e09,0x23ef1ac0),L_(0x000000e1), LL(0xc562080c,0x0edd3c7c),LL(0xd4bfec34,0x6ac1e8f3),LL(0x8628425d,0x3dfaff6a),LL(0x6eeb0125,0x2bd725ab),LL(0xf2cb02f5,0xeb0228d9),LL(0x63e15d94,0x41589407),LL(0xaa99cd36,0x94061e78),LL(0xf8ab88d8,0xbd436309),L_(0x00000047), + LL(0xb83d39ba,0xfe497366),LL(0x1a08bb8d,0x3fb2e32d),LL(0x68fadea4,0x90040dcc),LL(0xc78d9e5b,0x6201359b),LL(0x8999242f,0x4ca94e09),LL(0x83f1e38d,0x3e9a9377),LL(0xf5e42def,0xc5c271ed),LL(0xd3d42e09,0x57d11cda),L_(0x00000043), LL(0x7f14caf1,0x52b71020),LL(0x42fb2920,0x840b578b),LL(0x4e0acb78,0x9f5c859d),LL(0xbd1059c6,0xf5ce1fef),LL(0xdfc0d187,0xd99b98e1),LL(0xb702018d,0xd9d695b6),LL(0x7056ff1f,0x1187f703),LL(0x73121d9b,0xc912e80b),L_(0x0000016f), +}, +/* digit=102 base_pwr=2^510 */ +{ + LL(0x89622bfd,0x12bebe9c),LL(0xcafd2ca2,0x487abee2),LL(0xd290457b,0xc04143f4),LL(0x05d13bf4,0x716aab7d),LL(0x067f0ae3,0x7740d413),LL(0x5925a309,0xebe6d02d),LL(0x14370b8d,0xe8ef2c27),LL(0xfae20be9,0xdcc77fcf),L_(0x000000f4), LL(0x8d09dc72,0xb463618a),LL(0x49d83802,0xe00f8249),LL(0x50666aae,0xd5a21e88),LL(0x54be3730,0x258522a3),LL(0xa6ce164b,0xbf3fd223),LL(0xfefa386c,0xb7ba5ba4),LL(0x479bc6a0,0x378ecff5),LL(0xece410bb,0x58171ec6),L_(0x000000fd), + LL(0xb8ebdae4,0xfcc42342),LL(0x0addd068,0x2e8a76fa),LL(0x1ba58a99,0x972d98aa),LL(0x585d2056,0x5a290a6f),LL(0x51a66712,0xa47990be),LL(0xab19e664,0xe44696be),LL(0x2f64d1c3,0x490ab4a2),LL(0x0b8ce484,0xf862854a),L_(0x0000012f), LL(0x0acf9a53,0x3b3fd199),LL(0xdaaafe7e,0x1c1f1592),LL(0x3015bdb3,0xadb01684),LL(0xb2dbb2d0,0x670d1295),LL(0x3f77ef5d,0xb3f98aca),LL(0x51408bf1,0xb5280fd3),LL(0x0b5ee9d3,0x3a7a5866),LL(0xe5879122,0x2a28af86),L_(0x00000111), + LL(0x2aa4eb8b,0x719fd8c6),LL(0x2ae67788,0xd8b75613),LL(0xd4b10cdf,0x691c837c),LL(0x7871303d,0x169b2b0b),LL(0x0d01af02,0x6b821f74),LL(0x33573229,0x82eb3840),LL(0x782b872c,0xef815609),LL(0x64bda6ba,0x9ad650a9),L_(0x00000087), LL(0x654fa37e,0x9665a8db),LL(0x761f0aa2,0xe37a4531),LL(0x4eac5b19,0x586ef6d9),LL(0x886dc010,0x014c7183),LL(0x075d0e7c,0x55263f06),LL(0x8a38c3bb,0x5b8b13c3),LL(0xf18380c5,0xcefec3fb),LL(0xb50c9c44,0x64a25aec),L_(0x0000009b), + LL(0x5131c51f,0x65ab5849),LL(0xd5115c76,0x8739b754),LL(0x840523eb,0xb96b253e),LL(0x8a1f77e3,0x765d9707),LL(0x8742a046,0x7e942e5b),LL(0x1539823d,0x0b3194bd),LL(0x560b9978,0xb52679bf),LL(0xbda6ff32,0xb360761a),L_(0x000000b6), LL(0x92820e93,0x881e08a8),LL(0x208f9f2c,0x7e5fd839),LL(0x4e86968c,0x305d2580),LL(0x76aeb554,0xb44037fc),LL(0x24c686c9,0xb80d02e0),LL(0x20e62e51,0x5774d5a6),LL(0x653df90e,0xf0000eae),LL(0xc9b31961,0xdb5b072a),L_(0x000001cc), + LL(0x0eaaf4f9,0xfbc7cc75),LL(0x23c2ade5,0xd4d5bade),LL(0x734024b7,0xaca16532),LL(0xb04a1289,0x748144eb),LL(0x599436fa,0x2dc69353),LL(0x292c7b3d,0xe403f7a9),LL(0xb831d302,0xb390c4b2),LL(0xefcb4c53,0xe756ba3e),L_(0x000001d0), LL(0xe0c0eb7f,0xf6a7b102),LL(0x411f77a6,0xc71476dc),LL(0xae920f7c,0x2edbab42),LL(0x28d62eb0,0x3c6b13bc),LL(0xc5296531,0x35b583ce),LL(0xfb32a342,0x66e0af0c),LL(0x23a5daad,0xa449b545),LL(0xa7558c28,0x50f4b633),L_(0x0000017a), + LL(0x6383559c,0x52741d3a),LL(0x6d33fc8c,0x98c5775c),LL(0x595adc9e,0xdeefc5ad),LL(0xc4827819,0x94326f99),LL(0x384312e5,0xc9b59642),LL(0xfb777603,0x6642d1f6),LL(0xfebd7a7d,0x04e71c64),LL(0xd51e2c8e,0xa96e4272),L_(0x000000a5), LL(0xfe188e45,0xc6c9a2ae),LL(0xcfd37d07,0x870985c6),LL(0xb64a1b0a,0xf54e2700),LL(0xd57c3e8a,0x97a88233),LL(0x4ccc22c2,0xe7db1ecd),LL(0xfff2895e,0xb9be3600),LL(0x2a410545,0x8934c5cb),LL(0x71986e7a,0x545e296c),L_(0x000001f3), + LL(0x8664ea8c,0xb006fef1),LL(0x18fac77e,0x2d10f805),LL(0x144d6d0c,0xcefe66ce),LL(0x7ca13881,0x6bc51a22),LL(0x93e1d2aa,0xfe6fc406),LL(0xdde6594a,0xcfe90933),LL(0x92333bca,0x2f2f839c),LL(0xf1434e7e,0xf4d730b9),L_(0x0000013b), LL(0x84887df0,0xbd49b873),LL(0xf75f870f,0x4f7c90e8),LL(0xe89d9ed4,0xf464a50f),LL(0x9a76a69e,0x3d9a6cbe),LL(0x0a745d9f,0x0f9b1034),LL(0x87bec297,0x5fe8ae9e),LL(0x7f1ab569,0xad783c5d),LL(0xea58b4b0,0xd37c5e74),L_(0x00000042), + LL(0x9ff8d786,0x35735942),LL(0x05d76bb3,0x995f4b0a),LL(0x58d0fe01,0xe40e0f1c),LL(0x21dccd2e,0x3af9c629),LL(0x40ab0ca3,0x074069c3),LL(0xa30b637c,0x098a102f),LL(0x44888bc2,0xde377018),LL(0xb2e96e33,0x2f69ed6c),L_(0x00000012), LL(0x0f70d506,0xe57ed3ba),LL(0xe59c4f2c,0x2492cf26),LL(0x5879a0eb,0x3d130599),LL(0x75760ae9,0x4103b206),LL(0x89f9d0d0,0xa2b74089),LL(0x4b0ad618,0x723e7b44),LL(0xab5c813e,0xebb80451),LL(0x305a1f27,0xda320616),L_(0x00000152), + LL(0xd06cea6e,0x063477df),LL(0x7ad6ed83,0xdfc2e4d9),LL(0x7d58a8ed,0x1a10d461),LL(0x9fae700f,0x9ad7943b),LL(0x37aee0fa,0x575deb90),LL(0xef0a0865,0x926de4b2),LL(0x3a26c380,0xc5d7be4b),LL(0x910a980d,0x050f79a4),L_(0x000001a0), LL(0xdc85a306,0x8a336a7f),LL(0x078dd7d7,0x3626cc20),LL(0x5cdeb063,0xc2b171da),LL(0x273ae54e,0xab82b41f),LL(0x10b49e9f,0x9d867301),LL(0xca9e1b59,0xe2e4e776),LL(0x7eb0c998,0x2437d70b),LL(0x3320fabf,0xf9bfec6b),L_(0x000000cd), + LL(0x7b0fa120,0xb86bacca),LL(0xfbcd14e3,0xa097b60e),LL(0xd21921a2,0x57795942),LL(0x96c19ceb,0x8537f555),LL(0x2145d8ff,0xe5e61d05),LL(0xc2c7c89b,0xbe0f1c2c),LL(0xb88cf04d,0x77a2f17b),LL(0x47c65308,0x9d259bd7),L_(0x00000141), LL(0x9b1b0b2e,0x3ba530cb),LL(0xac5182ed,0xea3a3af8),LL(0xfa4f9dd8,0x03a0d517),LL(0x7b2d9856,0x2bd4dfe1),LL(0x6d8ccb18,0xa68f896d),LL(0xc8c4d1ec,0xa1acec0c),LL(0x0fdaed1a,0xdc43340b),LL(0x1a6552ac,0x0d7c6ed7),L_(0x0000018d), + LL(0x1cfe1d00,0x35fc4f26),LL(0x06e2cd4f,0x7dce43d2),LL(0xfe4a6fd7,0x8884f4ad),LL(0x8bc475be,0x9fb2b07e),LL(0x9fe1c66d,0xde1173c5),LL(0xa0cf5d6a,0x6059a297),LL(0x4938219f,0x49237fdb),LL(0x01e57227,0x8887ac3d),L_(0x0000014e), LL(0x35f11932,0x63db0e8e),LL(0x431b9b60,0x0b8d8078),LL(0xdb56a2b7,0xa040057a),LL(0x856dd526,0x87409cca),LL(0x3d5f500d,0xb482e56d),LL(0xd9cd1b6f,0xbf890467),LL(0x815814ee,0xafa8c19c),LL(0x2dd2fd09,0xf9865d5f),L_(0x000000be), + LL(0x4ab480b6,0x71a65ccb),LL(0x061e197a,0x2360920f),LL(0xb306dab3,0x9d9428ae),LL(0xee526750,0xcbaf9d5a),LL(0xf58e47b1,0xd9a6f7e9),LL(0x696a3350,0x5af36c30),LL(0x1f66ddb3,0xeaff438c),LL(0xd4937e17,0x01e8c119),L_(0x0000000d), LL(0xac9df61e,0x22655044),LL(0x106e2b83,0x1ae7bb1e),LL(0x343bc8e6,0x99139508),LL(0xbc1e06e0,0x166453a2),LL(0x966bd6b8,0x3756d0eb),LL(0xb4bb44e2,0x3795c5a1),LL(0x625fe170,0xb7605deb),LL(0x426f42f1,0x437cc248),L_(0x000000f0), + LL(0x06cfe4f0,0x868d9076),LL(0x47442b11,0xec69d70f),LL(0x7bd07599,0x5e554262),LL(0x4c93a1e5,0x9ba31acc),LL(0x5fa3f8f0,0x5118c586),LL(0xed99e567,0x9ed35f7d),LL(0x9e3fd347,0xce15a315),LL(0x0a315f79,0x0ccab1ce),L_(0x00000149), LL(0x86dda811,0xb40d1386),LL(0xb2f0ff2d,0x0d2ec043),LL(0xc03a536d,0x01fe94d1),LL(0x753c381c,0x6d3c523b),LL(0x468beaaf,0xeb47f9a1),LL(0x5d8bebfe,0xeaf18315),LL(0xb071abcd,0x1a924dbc),LL(0x3c1a4715,0xe7415280),L_(0x00000062), + LL(0xcce52519,0xd9a705a8),LL(0xef1ab816,0xb6139e2f),LL(0x4fdd8131,0xdab1fe19),LL(0xf7fb9e55,0x94460d6e),LL(0xeb0d1405,0x6a211783),LL(0x6ba4226e,0x8b3a8c56),LL(0xf2eeb428,0xf7e95eb9),LL(0x0b4ffc60,0xd9357daa),L_(0x000000d1), LL(0xe66a7792,0x7209db94),LL(0xdb0eb453,0x0352a746),LL(0x3c883ac1,0xdd4b846f),LL(0xb4107c7d,0xe960d5ec),LL(0xf20e2f77,0x61292f8f),LL(0x8b9e3ba1,0x85963097),LL(0x1218ba8c,0xbba1103f),LL(0x61201057,0x9bfd2fd3),L_(0x000001f6), + LL(0x08fb83e5,0x0419bb93),LL(0xc48ce791,0x7a851af1),LL(0xd3ade5e1,0xedcfe59c),LL(0xbf3e625d,0xd7763ab7),LL(0xd2c5aaf2,0x625d14ad),LL(0xb7b3d23e,0xbf8e7638),LL(0x7079ecb0,0xc7d9e9b0),LL(0x9c8fcf47,0x59d7dc01),L_(0x0000010d), LL(0x074d6a10,0xceed2d69),LL(0x1a1995f3,0x61d18bb0),LL(0xf02767e3,0x33398884),LL(0x68db2be1,0xbdeb7872),LL(0x3e3fa104,0x82f62909),LL(0x2e4ab79a,0x55582545),LL(0x67badda6,0xa7bb473e),LL(0x26c76ce9,0x5ab23400),L_(0x00000118), + LL(0xc0ebb49b,0x76edd0b2),LL(0x7ef78c95,0x089746d8),LL(0x86ff89a1,0x30dee546),LL(0x51992a8e,0x8362adcd),LL(0xafcb70ff,0x883f2631),LL(0xa55108d8,0xa13e25b5),LL(0x93138472,0x1fd32baa),LL(0x64387fbe,0xdb1b0497),L_(0x00000116), LL(0xe8652373,0xe1299928),LL(0xce8fd7e9,0x16c54d21),LL(0x938b0123,0xad0e62d7),LL(0x4d602bac,0xf9df41ce),LL(0xc55138cb,0x25dfe098),LL(0xbc01e0e6,0xbf9a6851),LL(0x2bdbc63d,0xa70b0da1),LL(0x8b07ceba,0xe5f9aaec),L_(0x000001a1), +}, +/* digit=103 base_pwr=2^515 */ +{ + LL(0xaca511d0,0x698e16fa),LL(0xcb4d0031,0x2e96a74c),LL(0x7b609854,0x679b8501),LL(0x87d91373,0x6f39c358),LL(0xa39fd4a5,0x3aea2bb2),LL(0xc7eef60f,0x4e8edd3f),LL(0xd4812888,0x89e1d001),LL(0x2f4d1fa9,0xc5d59373),L_(0x0000013b), LL(0x0a629c27,0xd6fdccbf),LL(0x6bc14652,0x5f32800f),LL(0xd29c1358,0x69e7f62a),LL(0xf3a9fdce,0x9418d0db),LL(0xdaa9f4b6,0xf492796f),LL(0x525ae5fe,0x32f4a27a),LL(0xd91d1353,0xcc1a7293),LL(0xdc6b1bb1,0xb6f6d6fa),L_(0x0000010a), + LL(0xe776fe9e,0xe46e8257),LL(0xc90ea2e2,0x285dece1),LL(0x02e70a0d,0xd2e4f07e),LL(0x9e22652f,0x7fb0667d),LL(0x5325ca4b,0xe36daaa9),LL(0x04df1305,0xeebe9d3d),LL(0xfcd0755f,0x570e3be0),LL(0x4f74e603,0x821555f7),L_(0x00000096), LL(0xb8a7ff33,0x37b93b28),LL(0x02791127,0xa408dc4f),LL(0x219fcf52,0x7589c78d),LL(0xbf0f03e3,0x0bb10f8f),LL(0x8d6cdb0c,0xd517b4d7),LL(0x99047428,0x37e06b1f),LL(0xa69f3aed,0x98f8786b),LL(0x8624d396,0xb0e28b50),L_(0x000001e2), + LL(0xa4ea5b5a,0x734ae209),LL(0x90fc2a73,0x5823b56b),LL(0x7673ea6e,0x7dbb26e5),LL(0xd6657bcd,0xd1742aca),LL(0xc34cd032,0xe888df76),LL(0x8065b09e,0xa8dad269),LL(0xc00f61b1,0x3a07c5aa),LL(0xd150d657,0xd3b84038),L_(0x000001ea), LL(0xd0a14535,0x608fa78a),LL(0xfb7e5603,0x1e082856),LL(0x643ad480,0x7bf543a7),LL(0xf5b0db8f,0xfadd24cd),LL(0x7206f2c4,0x1806c9ff),LL(0x3a60a387,0x0a68bae7),LL(0x1164c0d4,0x51de4b72),LL(0xb512a4da,0x80339476),L_(0x00000027), + LL(0x77314e66,0xc35e0de9),LL(0x4220d9f5,0x86281b42),LL(0x69b8f421,0xe5f95c9d),LL(0x5fd90a74,0x9a89c707),LL(0x8c09fc49,0xe12f3480),LL(0xa6764b64,0x8c161166),LL(0x886f3c36,0x55f40cf1),LL(0x68ad8aaa,0x5a680c49),L_(0x000001fd), LL(0xf91f4bec,0x489002d4),LL(0xe8177d77,0x1759ca38),LL(0xe14e5a1f,0xab2e759a),LL(0x9005868d,0xa02b4128),LL(0xaa1dff8c,0x2b9cd06e),LL(0x12d6a4d8,0x578741ea),LL(0x641aef64,0x1a343e8d),LL(0xc6a85c8b,0xf21792d4),L_(0x0000006c), + LL(0x4fe44c0c,0x7a97ea09),LL(0xec2c9500,0x455f3253),LL(0xa4bedbb4,0x902e1815),LL(0x27a1df89,0xfb3e392c),LL(0x120f8330,0x583ac267),LL(0x9a9698e2,0xe8c87240),LL(0x675c3030,0x32adecb4),LL(0x4f7fb620,0x5c2ea4c6),L_(0x000000da), LL(0x56a1c202,0xb86d1cd8),LL(0xdab68ef9,0xed63845f),LL(0x1723eef9,0x480f0cda),LL(0x7a1853f8,0xb146da6a),LL(0x7337ff75,0x4dd1db53),LL(0xd3685d26,0x41863100),LL(0x9ea6ba31,0xef5caeec),LL(0xa06b6815,0x5f4a92e2),L_(0x00000080), + LL(0xfa7c3363,0xf791b828),LL(0x5836e010,0x69b98b78),LL(0xba2d3b6c,0x504f9367),LL(0xcea4290d,0x5860835e),LL(0xf3dd0621,0x22ac6245),LL(0x208bde66,0xd8153e71),LL(0xd2a1a552,0xcd91cd77),LL(0xc7df7c52,0x167e37eb),L_(0x00000134), LL(0x0bfe4e12,0xfdf620f3),LL(0xe9aa6d05,0x78c9c26d),LL(0x7d0e875e,0x581fef3a),LL(0x45acf57d,0x4f2f3f1f),LL(0x89769d1b,0xb516d4fb),LL(0x7161f8a2,0xa50e2afa),LL(0xa831731c,0xa569ea98),LL(0x69e2a679,0x5909da40),L_(0x000000d1), + LL(0xafc78e61,0x4dc242cf),LL(0xb32ad972,0xbb40309f),LL(0x790edca8,0x89505a9a),LL(0x3c060f5d,0x112ba1c3),LL(0x52485cd5,0xc5bdc888),LL(0x9feed1cd,0x68110e28),LL(0x49202782,0x49d8d8e4),LL(0x7cea44e5,0xc5447530),L_(0x0000006c), LL(0x33e94828,0x54f9b84f),LL(0xdd82a038,0xf69e1a64),LL(0x9e8e50f3,0xf1691b4d),LL(0x13fe2932,0x5ffe5329),LL(0x032ff352,0x51f4070a),LL(0x9dcce305,0xc3145c5b),LL(0x62f1400d,0xd89cb5eb),LL(0xbef8bde9,0x4f571517),L_(0x000001e0), + LL(0x37573b5a,0x464e098a),LL(0x2eac199e,0x4b6ae9bd),LL(0x41109e44,0x96c7e839),LL(0x638c7109,0x99e6beb3),LL(0xa5b03740,0x0943a1c3),LL(0x8490e0cd,0xfab6ecb1),LL(0x4e71bae8,0xb69f0eb1),LL(0x29f06246,0x366f7112),L_(0x0000016d), LL(0x536e2d86,0xa2a3d8ca),LL(0xf4f50e4b,0x4c428120),LL(0xcb6eaa4c,0xb4203e5b),LL(0x69871129,0x6da13d6c),LL(0x218bdacf,0x4f621f85),LL(0x52046a31,0x1ea900e8),LL(0x3a13fa03,0xc7d28019),LL(0x167b70a8,0x1f519437),L_(0x000000b7), + LL(0x2bdb447a,0xae8792f8),LL(0x63aef018,0xae6cf0fd),LL(0x3291cfc7,0xe0ee5c02),LL(0x3ae122af,0x5bd690e7),LL(0xff276537,0xbc3516ac),LL(0xf83b9879,0xa4255fcc),LL(0x05236d5e,0x4ca14e35),LL(0xaf60c6b5,0xea86970d),L_(0x0000000a), LL(0xc17c08e7,0x737de42a),LL(0xac0df2a7,0x520e48ce),LL(0xaceb43b8,0x2f791d6a),LL(0x57fe87f0,0x662b9dfe),LL(0xc51cfa7c,0x884ed1f4),LL(0x75a9efdd,0xb5ee76b0),LL(0x3f9fe081,0x61e43ed8),LL(0xb9598115,0xd8cbf7b1),L_(0x000000fa), + LL(0x82e47d41,0x1c1e4e8c),LL(0xf692383c,0x819d110b),LL(0x0caaa47b,0xcb280e34),LL(0xf6e315e8,0x49f5a7e4),LL(0x68659604,0x6db3e3bf),LL(0xc18d2a73,0xb38233a8),LL(0xab54c2d8,0x216ab95c),LL(0x670af6e7,0x053a27b4),L_(0x00000154), LL(0xf79cd8d1,0x95f873cc),LL(0x8946ec9e,0xd4ae259b),LL(0x352c8cec,0x6383026a),LL(0x4b6773b4,0x574f14c8),LL(0x7327edc3,0x43f9e116),LL(0xfc2d9802,0x58a2e8d3),LL(0x26360b9c,0x2ae789b4),LL(0xeac487c7,0xe5e4384b),L_(0x000000bb), + LL(0xcfa66e36,0xe576c7d6),LL(0x40446421,0x5a9fe083),LL(0xa7e0a9d1,0x43da69bc),LL(0xcd5cfda4,0xaca35d4c),LL(0xdb98b2d8,0xcc88e119),LL(0x238da31d,0xe775938e),LL(0xd74d2fe0,0x0e845777),LL(0xee458b07,0x2ecae686),L_(0x00000070), LL(0xfc21befe,0x6f8ded71),LL(0xf57aacc7,0xa1f5602a),LL(0x8a4a8706,0xdf77dad6),LL(0xe88d5556,0xf0fb8eab),LL(0x38891e24,0x3a9313c2),LL(0xd33f4e50,0x4e334d02),LL(0x267f4849,0x45dbbeac),LL(0x7b8b078d,0xd3a28c1d),L_(0x000001d0), + LL(0x77a504d7,0x706161d0),LL(0x0d717bec,0x8d3f449e),LL(0xcd6aa437,0x4c327553),LL(0xbfa09758,0xecfed023),LL(0x131032e9,0x4abfe666),LL(0x2301de73,0x972524c6),LL(0xd67cd7b5,0x1b68a20a),LL(0xd8e4bd98,0x51e331d7),L_(0x00000142), LL(0xa0dd411d,0x136bd0f9),LL(0x8521a20a,0xe9c06f6a),LL(0x34117a07,0xb1417701),LL(0x625cc2c0,0x534fecc6),LL(0xe6f01c93,0x698e9742),LL(0xcea5bcd3,0x43a9724a),LL(0x54b554d5,0x77820ced),LL(0x7954cbcc,0x90ac105a),L_(0x000000eb), + LL(0xef4a4c48,0x67e62639),LL(0xef609727,0x91ba0b01),LL(0xc40bb739,0x7f62ccbc),LL(0xb7eda85e,0xb14485bc),LL(0x2a55f22b,0xeab4bc94),LL(0x091f3fde,0xb13e2d7b),LL(0x72b44ddf,0xa6958062),LL(0xd4d990ab,0xeb252caf),L_(0x0000000e), LL(0x14ea0dda,0xc0e83ba2),LL(0x10cf6ee9,0xc9f677ef),LL(0x8e3eae8b,0x1862146e),LL(0xcfe0b037,0xa6cdb8a8),LL(0x6d8e5bd3,0xf50d8419),LL(0xdd3f0ea7,0xf42ab2a9),LL(0x8a6b5e3c,0x12f65451),LL(0xe62ff71b,0x2007b697),L_(0x000000af), + LL(0x0460a7ae,0x6526a7b4),LL(0x80ab037a,0xf752335e),LL(0xf14c43bd,0xd11a8f65),LL(0x9b989eab,0x23fa924f),LL(0x0976a80f,0xf16dad87),LL(0x4e440171,0x3baaac45),LL(0xb9635c0d,0xf0f34704),LL(0x0e1ca863,0x515f651b),L_(0x000001a3), LL(0x40fcc076,0x420a4e5f),LL(0x24cf57e8,0xcec847e3),LL(0x1f189869,0xb20db2fe),LL(0x27f88dee,0x48712498),LL(0x423c17a4,0x284e6344),LL(0xfe029568,0x10b9bfa3),LL(0xd426c180,0x07626ee2),LL(0x96cbf2d8,0x92af56c4),L_(0x0000008f), + LL(0x8a898f02,0x37d5f07a),LL(0x9e4691c0,0xdc3f3126),LL(0xb1ce0f65,0x81c10b29),LL(0x73e7fd11,0xc595f2a8),LL(0x5a3fd848,0x47d0e340),LL(0x439d759b,0xbc668622),LL(0x87538694,0x461b9eba),LL(0x3484697e,0xa4f47f3b),L_(0x000001fb), LL(0x3d20296f,0xf99ebce4),LL(0x59fd2232,0x51ac1eec),LL(0x2fb986d6,0xe71f9d4a),LL(0xa5d1433c,0xa289f5b9),LL(0x4ece5225,0xd51b9288),LL(0x6ec5e037,0xcce86717),LL(0xb823e469,0xac199283),LL(0x45b78f23,0xb4d838aa),L_(0x0000017a), + LL(0xbfa48e10,0x08472093),LL(0xc8ac9e7a,0xb7492e4e),LL(0x471d73ed,0x53d1bd1c),LL(0x243428ce,0x40adeca7),LL(0xb7d49d17,0xd60077c0),LL(0x7a95c66d,0x737593cb),LL(0xf237e1e5,0x6a7c6f6e),LL(0xa7929ff0,0x984af660),L_(0x0000002d), LL(0x894bcc2e,0x7b3c416f),LL(0xa493d3e8,0x21231992),LL(0x4c0a5993,0xf376d082),LL(0x0d5c6c61,0x9e1550e6),LL(0x2a3430f2,0xf1d1beb9),LL(0x11f95e81,0x7b6bc5ab),LL(0xa78bae02,0x17858c60),LL(0xbdd9ea90,0x7b4b3f95),L_(0x000000d8), +}, +/* digit=104 base_pwr=2^520 */ +{ + LL(0x0b8b69f6,0xb96747cd),LL(0x3f30c14c,0x9e707ed2),LL(0x029690c8,0xd1292336),LL(0x884265ce,0x55cfec2b),LL(0xc87e6275,0xa097ab7d),LL(0xa5558f62,0xf635118e),LL(0x23dda1ad,0x5770b69e),LL(0x1b70ffff,0x4207811d),L_(0x00000181), LL(0x4f2606bc,0x8c9c6bbd),LL(0xccb92cf3,0x58d1b308),LL(0x2ce6913c,0xbbdfb6fe),LL(0x1967bfef,0xe5cb515b),LL(0x453132fc,0x2527584e),LL(0xc389b2f2,0x2a1591df),LL(0x0460d618,0x602d5761),LL(0x7498b0d1,0x0a2aedc5),L_(0x000001d3), + LL(0xb38cffee,0xa135a61f),LL(0x8ac17028,0x2c9fe1a1),LL(0x30418249,0x3ecb968e),LL(0x4c958b81,0x6f834a0b),LL(0x523285e8,0x54df836f),LL(0x29e4b05e,0xf77b5fb2),LL(0xe864d898,0x48371505),LL(0xcce3c32e,0x702eafb3),L_(0x000000b2), LL(0xc4a0e5e3,0xfb74fd48),LL(0x18996dc2,0x875aaa20),LL(0x5e9f86f5,0x5eb82718),LL(0x6642422b,0x87431019),LL(0xd6d6f0dd,0x9d7e7982),LL(0xcb46f571,0x346044e6),LL(0xa348c675,0xdc02d250),LL(0x517508af,0x179b19ec),L_(0x0000019d), + LL(0x18145140,0xded9f8c1),LL(0xba498095,0x40df2b19),LL(0x3834dace,0xa0c7dec0),LL(0x3687e664,0xfeee9a9e),LL(0x09d971f2,0xa032ee72),LL(0x07148796,0xa0b2cc31),LL(0xb65bcec3,0x46067d48),LL(0xd8c2af65,0x50cbf7f5),L_(0x0000014f), LL(0xd715c856,0x79c821c5),LL(0xbebe04f7,0x62cf6310),LL(0x3844c220,0x89986c83),LL(0x2644f899,0x43935732),LL(0xf80ac439,0xfd741ec2),LL(0x299a9f2d,0x3022b589),LL(0xbcf4790c,0xf5663af1),LL(0x767587f6,0x290c9a46),L_(0x00000161), + LL(0xf1cdfa06,0xda7b7826),LL(0x97fea55e,0xdd938459),LL(0xc39699cc,0x17d73f54),LL(0x5971fbd4,0x9f08e1d8),LL(0x3631f804,0x65a870ee),LL(0x51a73b8e,0xa3cdc8e3),LL(0x54f69b2a,0x85999014),LL(0x59cbe0fe,0xf12532d6),L_(0x000000cf), LL(0x085bfaeb,0x17f6a7aa),LL(0xe07f9788,0x1e5f6c61),LL(0xb271762a,0xcc6a5dff),LL(0x5d3e3cd3,0x895eb0df),LL(0x6eadd52e,0x2cd665b4),LL(0x92523b34,0x93078c5b),LL(0x2ebcff33,0x48620212),LL(0x777dd50c,0xef0f25f4),L_(0x00000138), + LL(0xfe3fcdbd,0x118dee98),LL(0xcfc4ad1b,0x0a524cec),LL(0x6d1ffa5c,0xe0d7420c),LL(0x919d859d,0x44af5553),LL(0xf81fb745,0x0981d6de),LL(0xa17a7c3f,0x6680c297),LL(0xe0cc4fe7,0xf6d22135),LL(0xde36e57a,0x7f521d15),L_(0x000000af), LL(0x0b8ae03f,0xac0c4195),LL(0xc2638c06,0xc994e2c7),LL(0x4523ebb6,0x49b75a94),LL(0xdb72a765,0x73310e2b),LL(0x57a73d05,0x8ce6d6b8),LL(0x1e23ae4c,0x4309eb9e),LL(0x842f06ae,0xf98aedc0),LL(0xedf71264,0x161436ed),L_(0x000001af), + LL(0xbe47c62f,0xd4c38f8c),LL(0x49173568,0x085a52c0),LL(0x7d057b19,0x612151d8),LL(0x2de5c929,0x8a4ea946),LL(0xc4036de1,0x0a8300dd),LL(0x5a6e290b,0x195518bc),LL(0x894ed83e,0x35e21097),LL(0xd8dd898c,0x03777a74),L_(0x000000ff), LL(0xd0eee2e2,0xc0b89ddf),LL(0x8a7bf325,0x0c5c995a),LL(0xa5131a24,0x9573e514),LL(0xe5998b6e,0x93979878),LL(0x7ba59336,0x7906f3c8),LL(0xff513215,0x093cead5),LL(0xb76588a1,0x243bc2e1),LL(0x5abc03c8,0x8eceda05),L_(0x00000134), + LL(0x07c9d208,0x234d2231),LL(0x524b8b4b,0xc6fe7d17),LL(0x469a9182,0x688b3e26),LL(0x35461f18,0xb0f49d1d),LL(0x78f9ef1e,0x4bb2130a),LL(0xe72b7216,0x9240661e),LL(0xec1e4e46,0x294674d4),LL(0x95346b15,0xe96fbdf1),L_(0x00000020), LL(0xa594d4cd,0xf533e3fe),LL(0xdb75a21c,0x99051c26),LL(0xea1a808b,0x9c10237a),LL(0x230cfcd1,0xe6396566),LL(0x90aedfcf,0x18cdd934),LL(0x8c399655,0x446502d8),LL(0x0de6be10,0x4a6de065),LL(0x7b3640aa,0xd5c12c48),L_(0x00000057), + LL(0xf6315f2c,0xf2e07c55),LL(0x62ee6844,0x9040fc8f),LL(0xaf168881,0xaec6bb02),LL(0xa1922677,0x968e4dee),LL(0x53b90132,0x92b21f9e),LL(0x2b9cb75f,0x4ae4c1d6),LL(0x65408d1b,0xd20f3732),LL(0x70be8f94,0x7640413d),L_(0x0000009e), LL(0x05c00995,0x4e16ae2b),LL(0xf20b5acf,0xd04ee882),LL(0x1f8c5834,0x35db5e06),LL(0xc9dbfe41,0x3a42f540),LL(0x3f7b55b6,0x500e266e),LL(0x52ce3b47,0xda6911e6),LL(0x0c53d0a4,0xee43c4db),LL(0x6052a6d7,0xa358b994),L_(0x00000165), + LL(0xf7f0245d,0xc1b6e80d),LL(0xd2bf51a5,0x9077fd5b),LL(0x4a61b710,0x97dc422c),LL(0x3089abb3,0x2c00b155),LL(0x893fa316,0x40add702),LL(0xb9d804ac,0xc77985f1),LL(0xdfaaf13d,0x4150d1b3),LL(0xaf9d85b4,0x9a8fb36c),L_(0x000001fb), LL(0x92589d47,0xd0dfdf3a),LL(0x06f77875,0x6b4012d5),LL(0xfe067b9f,0x4426c933),LL(0x2ed7298d,0x5353c502),LL(0x67948217,0x156d92c1),LL(0xf0f675fa,0xee2b368d),LL(0xba020dd5,0x3367f41b),LL(0xd5aae0ea,0x95a07182),L_(0x00000049), + LL(0x75917fbb,0x1b52b513),LL(0x87569974,0xbeb1242f),LL(0x4a568f34,0xb03e5543),LL(0x86a66b14,0xc094f1b5),LL(0x93edd5ae,0x7da45bde),LL(0x2fb2c47a,0x960491e1),LL(0x678ce19f,0x890efc78),LL(0xf4853187,0x29999e31),L_(0x000001e7), LL(0x4363742f,0xd3a570ac),LL(0x1812091b,0x4961aaea),LL(0xd32e88d4,0x97dd4a2f),LL(0x1b33e755,0xb3987552),LL(0x79ed95a8,0x669664b0),LL(0x0837ce5b,0x3584f341),LL(0x3f9a0cc0,0x116266b7),LL(0x64a902cc,0x330114e0),L_(0x000000ed), + LL(0x0660e9a1,0xb0698be3),LL(0x5c045493,0xc1ca94da),LL(0x82b986b9,0x4e8d0287),LL(0xfafe7c0e,0x02cfcf45),LL(0x9235965c,0xcf187fb8),LL(0x316bebe3,0x3fb90363),LL(0xc42b951d,0xc6248aec),LL(0x26710295,0x8f1eb678),L_(0x000000d1), LL(0xc24f0956,0xa11f38e2),LL(0x398a2047,0x9a0accc0),LL(0x9e479268,0x8ccafb17),LL(0x468f61d6,0x0c01f836),LL(0x52f96c75,0xeb043b98),LL(0xacc6ee07,0xa59405be),LL(0xc63baaf6,0xeddd33c9),LL(0xba136442,0x9b13f409),L_(0x000000ba), + LL(0xc33b7b64,0x1eb1f532),LL(0x3bd3bca3,0x3a7aee90),LL(0x0882ad60,0xad95f2eb),LL(0xddaf31c3,0x4c9d8e29),LL(0x59c130df,0xbdd1470a),LL(0x7ac309bd,0xe3bf394f),LL(0xaafb8369,0xedba4812),LL(0x7f598209,0x46270ae8),L_(0x000000dc), LL(0xb5d505d9,0x81e772f9),LL(0xfa065dfd,0x15db5d5b),LL(0x7e590809,0x141e8679),LL(0xc4ffd236,0xf14602ff),LL(0xbf521149,0xcfd2b215),LL(0xc500a7a4,0xc04e3706),LL(0xe4c06db1,0x3e28ec80),LL(0x93d40cbc,0xd4519009),L_(0x00000117), + LL(0x530c705b,0x1a470405),LL(0xe8292e38,0x85b81d18),LL(0xc5fdb2b2,0x484b843b),LL(0xa859e4fe,0xeeae06f4),LL(0x4e3895d5,0x0a67c915),LL(0xe6119b5b,0xed968aa0),LL(0x9264e00f,0x66ed4c20),LL(0xbf1d85ad,0x9f2e5291),L_(0x0000016d), LL(0xd8a9d836,0xee5d4b51),LL(0xcf0b68ca,0x89ad96c1),LL(0xbcd75bca,0xae1fa341),LL(0x667fbe53,0xa297bd27),LL(0xe40caf5f,0xd6165d4f),LL(0x329b45f8,0x62d6bced),LL(0xc11413bc,0xd1c11022),LL(0x7e0d7384,0x30c070b1),L_(0x00000118), + LL(0xa39b851e,0xa0188e61),LL(0xf5e55bb8,0xe96325dc),LL(0x8cd5c092,0x9087223b),LL(0xe2c1a18b,0xca56bfcd),LL(0x548d8395,0x4ae67f8d),LL(0xaa6db861,0x8f44b4e9),LL(0x218ba5b9,0x317abb0e),LL(0x04386052,0x4aeffcd2),L_(0x00000084), LL(0x91b2e14e,0x6ac7c848),LL(0x5377e2b3,0xd40844b6),LL(0x9d93badb,0xe505b8cb),LL(0x4d7f3493,0x615a64c9),LL(0x20a05d5d,0x90a5eb78),LL(0xa4cb086a,0xed4783ac),LL(0x36415b6c,0xf10f3d20),LL(0x56659094,0x82883579),L_(0x0000004f), + LL(0x0eeb045d,0xac240867),LL(0x98145c00,0xe7ce6952),LL(0xb5d0c780,0x315dd662),LL(0x189fc413,0x41646f48),LL(0x4392d048,0xc963ad1a),LL(0x1e77199f,0xebc649ee),LL(0x83e1f918,0xcd6ca624),LL(0x13b6a99b,0x4108f969),L_(0x0000011b), LL(0x2108af54,0x0b55c26f),LL(0x3989bd71,0xe0f27726),LL(0x1e5e0053,0x5c7e0958),LL(0xa8452157,0xf8e7b504),LL(0xb64d38bf,0xf180ac5c),LL(0x8c8c65f5,0x32a84a9b),LL(0x8f00c232,0x898ca7ed),LL(0x1a1639de,0xe79d8696),L_(0x00000150), + LL(0x6746f213,0xe1073527),LL(0xa966b0a8,0x3ad14203),LL(0x5bc4272f,0x39620db2),LL(0xbcd33a93,0xe5eae695),LL(0x26bac2fb,0x0e4497dc),LL(0xb7d647bd,0x3a195407),LL(0x7f7ed906,0x899ce3f6),LL(0xadd76129,0x2e49d8f3),L_(0x000000be), LL(0x333eb7cb,0x51de1b18),LL(0x8e185580,0xa269b8e8),LL(0x486cd055,0x3555823a),LL(0x6689b4be,0xaa52baba),LL(0xcd8d6ffd,0xd072a45c),LL(0x9cba9f57,0xba53f86f),LL(0x74a8d5fb,0x16481f57),LL(0x10747d58,0x457baa10),L_(0x000001af), +} +}; +#endif + +#endif /* _DISABLE_ECP_521R1_HARDCODED_BP_TBL_ */ +#endif /* _IPP_DATA */ + + +IPP_OWN_DEFN (const cpPrecompAP*, gfpec_precom_nistP521r1_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 5, + /* select function */ p521r1_select_ap_w5, + /* precomputed data */ (BNU_CHUNK_T*)ec_p521r1_precomputed + }; + return &t; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprime_isco.h b/plugin/ippcp/library/src/sources/ippcp/pcpprime_isco.h new file mode 100644 index 000000000..1f2c53cb7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprime_isco.h @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcpngrsa.h" + +/* test if E and A are coprime */ +static int cpIsCoPrime(BNU_CHUNK_T* pA, int nsA, + BNU_CHUNK_T* pB, int nsB, + BNU_CHUNK_T* pBuffer) +{ + if (nsA>nsB) { + SWAP_PTR(BNU_CHUNK_T, pA, pB); + SWAP(nsA, nsB); + } + { + __ALIGN8 IppsBigNumState bnA, bnB, bnGcd; + BNU_CHUNK_T* pDataA = pBuffer; + BNU_CHUNK_T* pBuffA = pDataA + nsA + 1; + BNU_CHUNK_T* pDataB = pBuffA + nsA + 1; + BNU_CHUNK_T* pBuffB = pDataB + nsB + 1; + BNU_CHUNK_T* pDataGcd = pBuffB + nsB + 1; + BNU_CHUNK_T* pBuffGcd = pDataGcd + nsB + 1; + + BN_Make(pDataA, pBuffA, nsA, &bnA); + BN_Make(pDataB, pBuffB, nsB, &bnB); + BN_Make(pDataGcd, pBuffGcd, nsB, &bnGcd); + + COPY_BNU(pDataA, pA, nsA) + BN_Set(pDataA, nsA, &bnA); + COPY_BNU(pDataB, pB, nsB) + BN_Set(pDataB, nsB, &bnB); + ippsGcd_BN(&bnA, &bnB, &bnGcd); + return 0 == cpBN_cmp(&bnGcd, cpBN_OneRef()); + } +} \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprime_isprob.h b/plugin/ippcp/library/src/sources/ippcp/pcpprime_isprob.h new file mode 100644 index 000000000..eab2c319c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprime_isprob.h @@ -0,0 +1,137 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcpngrsa.h" + + +static int cpMillerRabinTest(BNU_CHUNK_T* pW, cpSize nsW, + const BNU_CHUNK_T* pE, cpSize bitsizeE, + int k, + const BNU_CHUNK_T* pPrime1, + gsModEngine* pMont, + BNU_CHUNK_T* pBuffer) +{ + cpSize nsP = MOD_LEN(pMont); + + /* to Montgomery Domain */ + ZEXPAND_BNU(pW, nsW, nsP); + MOD_METHOD(pMont)->encode(pW, pW, pMont); + + /* w = exp(w,e) */ + #if !defined(_USE_WINDOW_EXP_) + gsMontExpBin_BNU_sscm(pW, pW, nsP, pE, bitsizeE, pMont, pBuffer); + #else + gsMontExpWin_BNU_sscm(pW, pW, nsP, pE, bitsizeE, pMont, pBuffer); + #endif + + /* if (w==1) ||(w==prime-1) => probably prime */ + if ((0 == cpCmp_BNU(pW, nsP, MOD_MNT_R(pMont), nsP)) + || (0 == cpCmp_BNU(pW, nsP, pPrime1, nsP))) + return 1; /* witness of the primality */ + + while (--k) { + MOD_METHOD(pMont)->sqr(pW, pW, pMont); + + if (0 == cpCmp_BNU(pW, nsP, MOD_MNT_R(pMont), nsP)) + return 0; /* witness of the compositeness */ + if (0 == cpCmp_BNU(pW, nsP, pPrime1, nsP)) + return 1; /* witness of the primality */ + } + return 0; +} + +/* test if P is prime + +returns: +IPP_IS_PRIME (==1) - prime value has been detected +IPP_IS_COMPOSITE (==0) - composite value has been detected +-1 - if internal error (ippStsNoErr != rndFunc()) +*/ +static int cpIsProbablyPrime(BNU_CHUNK_T* pPrime, int bitSize, + int nTrials, + IppBitSupplier rndFunc, void* pRndParam, + gsModEngine* pME, + BNU_CHUNK_T* pBuffer) +{ + /* if test for trivial divisors passed*/ + int ret = cpMimimalPrimeTest((Ipp32u*)pPrime, BITS2WORD32_SIZE(bitSize)); + + /* appy Miller-Rabin test */ + if (ret) { + int ns = BITS_BNU_CHUNK(bitSize); + BNU_CHUNK_T* pPrime1 = pBuffer; + BNU_CHUNK_T* pOdd = pPrime1 + ns; + BNU_CHUNK_T* pWitness = pOdd + ns; + BNU_CHUNK_T* pMontPrime1 = pWitness + ns; + BNU_CHUNK_T* pScratchBuffer = pMontPrime1 + ns; + int k, a, lenOdd; + + /* prime1 = prime-1 = odd*2^a */ + cpDec_BNU(pPrime1, pPrime, ns, 1); + for (k = 0, a = 0; k0; n--) { + Ipp64u tmp = IPP_MAKEDWORD(pX[n-1],r); + r = (Ipp32u)(tmp%divider); + } + return r; +} + +/* minimal prime test */ +static Ipp32u PrimeList[] = { + 2, 3, 5, 7, 11, 13, 17, 19, + 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, + 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, 257, 263, + 269, 271, 277, 281, 283, 293, 307, 311, + 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, + 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, + 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, + 727, 733, 739, 743, 751, 757, 761, 769, + 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, + 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + 1009,1013,1019,1021,1031,1033,1039,1049, + 1051,1061,1063,1069,1087,1091,1093,1097, + 1103,1109,1117,1123,1129,1151,1153,1163, + 1171,1181,1187,1193,1201,1213,1217,1223, + 1229,1231,1237,1249,1259,1277,1279,1283, + 1289,1291,1297,1301,1303,1307,1319,1321, + 1327,1361,1367,1373,1381,1399,1409,1423, + 1427,1429,1433,1439,1447,1451,1453,1459, + 1471,1481,1483,1487,1489,1493,1499,1511, + 1523,1531,1543,1549,1553,1559,1567,1571, + 1579,1583,1597,1601,1607,1609,1613,1619, + 1621,1627,1637,1657,1663,1667,1669,1693, + 1697,1699,1709,1721,1723,1733,1741,1747, + 1753,1759,1777,1783,1787,1789,1801,1811, + 1823,1831,1847,1861,1867,1871,1873,1877, + 1879,1889,1901,1907,1913,1931,1933,1949, + 1951,1973,1979,1987,1993,1997,1999,2003, + 2011,2017,2027,2029,2039,2053,2063,2069, + 2081,2083,2087,2089,2099,2111,2113,2129, + 2131,2137,2141,2143,2153,2161,2179,2203, + 2207,2213,2221,2237,2239,2243,2251,2267, + 2269,2273,2281,2287,2293,2297,2309,2311, + 2333,2339,2341,2347,2351,2357,2371,2377, + 2381,2383,2389,2393,2399,2411,2417,2423, + 2437,2441,2447,2459,2467,2473,2477,2503, + 2521,2531,2539,2543,2549,2551,2557,2579, + 2591,2593,2609,2617,2621,2633,2647,2657, + 2659,2663,2671,2677,2683,2687,2689,2693, + 2699,2707,2711,2713,2719,2729,2731,2741, + 2749,2753,2767,2777,2789,2791,2797,2801, + 2803,2819,2833,2837,2843,2851,2857,2861, + 2879,2887,2897,2903,2909,2917,2927,2939, + 2953,2957,2963,2969,2971,2999,3001,3011, + 3019,3023,3037,3041,3049,3061,3067,3079, + 3083,3089,3109,3119,3121,3137,3163,3167, + 3169,3181,3187,3191,3203,3209,3217,3221, + 3229,3251,3253,3257,3259,3271,3299,3301, + 3307,3313,3319,3323,3329,3331,3343,3347, + 3359,3361,3371,3373,3389,3391,3407,3413, + 3433,3449,3457,3461,3463,3467,3469,3491, + 3499,3511,3517,3527,3529,3533,3539,3541, + 3547,3557,3559,3571,3581,3583,3593,3607, + 3613,3617,3623,3631,3637,3643,3659,3671, + 3673,3677,3691,3697,3701,3709,3719,3727, + 3733,3739,3761,3767,3769,3779,3793,3797, + 3803,3821,3823,3833,3847,3851,3853,3863, + 3877,3881,3889,3907,3911,3917,3919,3923, + 3929,3931,3943,3947,3967,3989,4001,4003, + 4007,4013,4019,4021,4027,4049,4051,4057, + 4073,4079,4091,4093,4099,4111,4127,4129, + 4133,4139,4153,4157,4159,4177,4201,4211, + 4217,4219,4229,4231,4241,4243,4253,4259, + 4261,4271,4273,4283,4289,4297,4327,4337, + 4339,4349,4357,4363,4373,4391,4397,4409, + 4421,4423,4441,4447,4451,4457,4463,4481, + 4483,4493,4507,4513,4517,4519,4523,4547, + 4549,4561,4567,4583,4591,4597,4603,4621, + 4637,4639,4643,4649,4651,4657,4663,4673, + 4679,4691,4703,4721,4723,4729,4733,4751, + 4759,4783,4787,4789,4793,4799,4801,4813, + 4817,4831,4861,4871,4877,4889,4903,4909, + 4919,4931,4933,4937,4943,4951,4957,4967, + 4969,4973,4987,4993,4999,5003,5009,5011, + 5021,5023,5039,5051,5059,5077,5081,5087, + 5099,5101,5107,5113,5119,5147,5153,5167, + 5171,5179,5189,5197,5209,5227,5231,5233, + 5237,5261,5273,5279,5281,5297,5303,5309, + 5323,5333,5347,5351,5381,5387,5393,5399, + 5407,5413,5417,5419,5431,5437,5441,5443, + 5449,5471,5477,5479,5483,5501,5503,5507, + 5519,5521,5527,5531,5557,5563,5569,5573, + 5581,5591,5623,5639,5641,5647,5651,5653, + 5657,5659,5669,5683,5689,5693,5701,5711, + 5717,5737,5741,5743,5749,5779,5783,5791, + 5801,5807,5813,5821,5827,5839,5843,5849, + 5851,5857,5861,5867,5869,5879,5881,5897, + 5903,5923,5927,5939,5953,5981,5987,6007, + 6011,6029,6037,6043,6047,6053,6067,6073, + 6079,6089,6091,6101,6113,6121,6131,6133, + 6143,6151,6163,6173,6197,6199,6203,6211, + 6217,6221,6229,6247,6257,6263,6269,6271, + 6277,6287,6299,6301,6311,6317,6323,6329, + 6337,6343,6353,6359,6361,6367,6373,6379, + 6389,6397,6421,6427,6449,6451,6469,6473, + 6481,6491,6521,6529,6547,6551,6553,6563, + 6569,6571,6577,6581,6599,6607,6619,6637, + 6653,6659,6661,6673,6679,6689,6691,6701, + 6703,6709,6719,6733,6737,6761,6763,6779, + 6781,6791,6793,6803,6823,6827,6829,6833, + 6841,6857,6863,6869,6871,6883,6899,6907, + 6911,6917,6947,6949,6959,6961,6967,6971, + 6977,6983,6991,6997,7001,7013,7019,7027, + 7039,7043,7057,7069,7079,7103,7109,7121, + 7127,7129,7151,7159,7177,7187,7193,7207, + 7211,7213,7219,7229,7237,7243,7247,7253, + 7283,7297,7307,7309,7321,7331,7333,7349, + 7351,7369,7393,7411,7417,7433,7451,7457, + 7459,7477,7481,7487,7489,7499,7507,7517, + 7523,7529,7537,7541,7547,7549,7559,7561, + 7573,7577,7583,7589,7591,7603,7607,7621, + 7639,7643,7649,7669,7673,7681,7687,7691, + 7699,7703,7717,7723,7727,7741,7753,7757, + 7759,7789,7793,7817,7823,7829,7841,7853, + 7867,7873,7877,7879,7883,7901,7907,7919, + 7927,7933,7937,7949,7951,7963,7993,8009, + 8011,8017,8039,8053,8059,8069,8081,8087, + 8089,8093,8101,8111,8117,8123,8147,8161, + 8167,8171,8179,8191,8209,8219,8221,8231, + 8233,8237,8243,8263,8269,8273,8287,8291, + 8293,8297,8311,8317,8329,8353,8363,8369, + 8377,8387,8389,8419,8423,8429,8431,8443, + 8447,8461,8467,8501,8513,8521,8527,8537, + 8539,8543,8563,8573,8581,8597,8599,8609, + 8623,8627,8629,8641,8647,8663,8669,8677, + 8681,8689,8693,8699,8707,8713,8719,8731, + 8737,8741,8747,8753,8761,8779,8783,8803, + 8807,8819,8821,8831,8837,8839,8849,8861, + 8863,8867,8887,8893,8923,8929,8933,8941, + 8951,8963,8969,8971,8999,9001,9007,9011, + 9013,9029,9041,9043,9049,9059,9067,9091, + 9103,9109,9127,9133,9137,9151,9157,9161, + 9173,9181,9187,9199,9203,9209,9221,9227, + 9239,9241,9257,9277,9281,9283,9293,9311, + 9319,9323,9337,9341,9343,9349,9371,9377, + 9391,9397,9403,9413,9419,9421,9431,9433, + 9437,9439,9461,9463,9467,9473,9479,9491, + 9497,9511,9521,9533,9539,9547,9551,9587, + 9601,9613,9619,9623,9629,9631,9643,9649, + 9661,9677,9679,9689,9697,9719,9721,9733, + 9739,9743,9749,9767,9769,9781,9787,9791, + 9803,9811,9817,9829,9833,9839,9851,9857, + 9859,9871,9883,9887,9901,9907,9923,9929, + 9931,9941,9949,9967,9973,10007,10009,10037, + 10039,10061,10067,10069,10079,10091,10093,10099, + 10103,10111,10133,10139,10141,10151,10159,10163, + 10169,10177,10181,10193,10211,10223,10243,10247, + 10253,10259,10267,10271,10273,10289,10301,10303, + 10313,10321,10331,10333,10337,10343,10357,10369, + 10391,10399,10427,10429,10433,10453,10457,10459, + 10463,10477,10487,10499,10501,10513,10529,10531, + 10559,10567,10589,10597,10601,10607,10613,10627, + 10631,10639,10651,10657,10663,10667,10687,10691, + 10709,10711,10723,10729,10733,10739,10753,10771, + 10781,10789,10799,10831,10837,10847,10853,10859, + 10861,10867,10883,10889,10891,10903,10909,10937, + 10939,10949,10957,10973,10979,10987,10993,11003, + 11027,11047,11057,11059,11069,11071,11083,11087, + 11093,11113,11117,11119,11131,11149,11159,11161, + 11171,11173,11177,11197,11213,11239,11243,11251, + 11257,11261,11273,11279,11287,11299,11311,11317, + 11321,11329,11351,11353,11369,11383,11393,11399, + 11411,11423,11437,11443,11447,11467,11471,11483, + 11489,11491,11497,11503,11519,11527,11549,11551, + 11579,11587,11593,11597,11617,11621,11633,11657, + 11677,11681,11689,11699,11701,11717,11719,11731, + 11743,11777,11779,11783,11789,11801,11807,11813, + 11821,11827,11831,11833,11839,11863,11867,11887, + 11897,11903,11909,11923,11927,11933,11939,11941, + 11953,11959,11969,11971,11981,11987,12007,12011, + 12037,12041,12043,12049,12071,12073,12097,12101, + 12107,12109,12113,12119,12143,12149,12157,12161, + 12163,12197,12203,12211,12227,12239,12241,12251, + 12253,12263,12269,12277,12281,12289,12301,12323, + 12329,12343,12347,12373,12377,12379,12391,12401, + 12409,12413,12421,12433,12437,12451,12457,12473, + 12479,12487,12491,12497,12503,12511,12517,12527, + 12539,12541,12547,12553,12569,12577,12583,12589, + 12601,12611,12613,12619,12637,12641,12647,12653, + 12659,12671,12689,12697,12703,12713,12721,12739, + 12743,12757,12763,12781,12791,12799,12809,12821, + 12823,12829,12841,12853,12889,12893,12899,12907, + 12911,12917,12919,12923,12941,12953,12959,12967, + 12973,12979,12983,13001,13003,13007,13009,13033, + 13037,13043,13049,13063,13093,13099,13103,13109, + 13121,13127,13147,13151,13159,13163,13171,13177, + 13183,13187,13217,13219,13229,13241,13249,13259, + 13267,13291,13297,13309,13313,13327,13331,13337, + 13339,13367,13381,13397,13399,13411,13417,13421, + 13441,13451,13457,13463,13469,13477,13487,13499, + 13513,13523,13537,13553,13567,13577,13591,13597, + 13613,13619,13627,13633,13649,13669,13679,13681, + 13687,13691,13693,13697,13709,13711,13721,13723, + 13729,13751,13757,13759,13763,13781,13789,13799, + 13807,13829,13831,13841,13859,13873,13877,13879, + 13883,13901,13903,13907,13913,13921,13931,13933, + 13963,13967,13997,13999,14009,14011,14029,14033, + 14051,14057,14071,14081,14083,14087,14107,14143, + 14149,14153,14159,14173,14177,14197,14207,14221, + 14243,14249,14251,14281,14293,14303,14321,14323, + 14327,14341,14347,14369,14387,14389,14401,14407, + 14411,14419,14423,14431,14437,14447,14449,14461, + 14479,14489,14503,14519,14533,14537,14543,14549, + 14551,14557,14561,14563,14591,14593,14621,14627, + 14629,14633,14639,14653,14657,14669,14683,14699, + 14713,14717,14723,14731,14737,14741,14747,14753, + 14759,14767,14771,14779,14783,14797,14813,14821, + 14827,14831,14843,14851,14867,14869,14879,14887, + 14891,14897,14923,14929,14939,14947,14951,14957, + 14969,14983,15013,15017,15031,15053,15061,15073, + 15077,15083,15091,15101,15107,15121,15131,15137, + 15139,15149,15161,15173,15187,15193,15199,15217, + 15227,15233,15241,15259,15263,15269,15271,15277, + 15287,15289,15299,15307,15313,15319,15329,15331, + 15349,15359,15361,15373,15377,15383,15391,15401, + 15413,15427,15439,15443,15451,15461,15467,15473, + 15493,15497,15511,15527,15541,15551,15559,15569, + 15581,15583,15601,15607,15619,15629,15641,15643, + 15647,15649,15661,15667,15671,15679,15683,15727, + 15731,15733,15737,15739,15749,15761,15767,15773, + 15787,15791,15797,15803,15809,15817,15823,15859, + 15877,15881,15887,15889,15901,15907,15913,15919, + 15923,15937,15959,15971,15973,15991,16001,16007, + 16033,16057,16061,16063,16067,16069,16073,16087, + 16091,16097,16103,16111,16127,16139,16141,16183, + 16187,16189,16193,16217,16223,16229,16231,16249, + 16253,16267,16273,16301,16319,16333,16339,16349, + 16361,16363,16369,16381,16411,16417,16421,16427, + 16433,16447,16451,16453,16477,16481,16487,16493, + 16519,16529,16547,16553,16561,16567,16573,16603, + 16607,16619,16631,16633,16649,16651,16657,16661, + 16673,16691,16693,16699,16703,16729,16741,16747, + 16759,16763,16787,16811,16823,16829,16831,16843, + 16871,16879,16883,16889,16901,16903,16921,16927, + 16931,16937,16943,16963,16979,16981,16987,16993, + 17011,17021,17027,17029,17033,17041,17047,17053, + 17077,17093,17099,17107,17117,17123,17137,17159, + 17167,17183,17189,17191,17203,17207,17209,17231, + 17239,17257,17291,17293,17299,17317,17321,17327, + 17333,17341,17351,17359,17377,17383,17387,17389, + 17393,17401,17417,17419,17431,17443,17449,17467, + 17471,17477,17483,17489,17491,17497,17509,17519, + 17539,17551,17569,17573,17579,17581,17597,17599, + 17609,17623,17627,17657,17659,17669,17681,17683, + 17707,17713,17729,17737,17747,17749,17761,17783, + 17789,17791,17807,17827,17837,17839,17851,17863 +}; + +/*F* +// Name: cpMimimalPrimeTest +// +// Purpose: Test a number for being a mimnimal probable prime from list. +// +// Returns: Reason: +// 0 not prime number +// 1 prime number +// +// Parameters: +// pPrime prime number +// len32 length of prime number +*F*/ + +IPP_OWN_DEFN (int, cpMimimalPrimeTest, (const Ipp32u* pPrime, cpSize len32)) +{ + cpSize i; + + FIX_BNU32(pPrime, len32); + + /* take a look in the list */ + if(1==len32) { + for(i=0; i<(cpSize)(sizeof(PrimeList)/sizeof(Ipp32u)); i++) { + if(pPrime[0]==PrimeList[i]) + return 1; + } + } + + /* test if value under the test is divisible by first prime numbers 2,3,5, ... */ + for(i=0; i<(cpSize)(sizeof(PrimeList)/sizeof(Ipp32u)); i++) { + if(0 == cpMod32(pPrime, len32, PrimeList[i])) + return 0; + } + + return 1; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprime_packctx.c b/plugin/ippcp/library/src/sources/ippcp/pcpprime_packctx.c new file mode 100644 index 000000000..e4951a34b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprime_packctx.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// cpPackPrimeCtx() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcptool.h" + +/*F* +// Name: cpPackPrimeCtx +// +// Purpose: Serialize prime context +// +// Parameters: +// pCtx context +// pBuffer buffer +*F*/ + +IPP_OWN_DEFN (void, cpPackPrimeCtx, (const IppsPrimeState* pCtx, Ipp8u* pBuffer)) +{ + IppsPrimeState* pB = (IppsPrimeState*)(pBuffer); + + /* max length of prime */ + cpSize nsPrime = BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pCtx)); + + CopyBlock(pCtx, pB, sizeof(IppsPrimeState)); + + cpSize dataAlignment = (cpSize)(IPP_INT_PTR(PRIME_NUMBER(pCtx)) - IPP_INT_PTR(pCtx) - (IPP_INT64)sizeof(IppsPrimeState)); + cpSize gsMontOffset = (cpSize)(IPP_INT_PTR(PRIME_MONT(pCtx)) - IPP_INT_PTR(pCtx) - dataAlignment); + + CopyBlock(PRIME_NUMBER(pCtx), (Ipp8u*)pB + sizeof(IppsPrimeState), nsPrime*(Ipp32s)sizeof(BNU_CHUNK_T)); + gsPackModEngineCtx(PRIME_MONT(pCtx), (Ipp8u*)pB + gsMontOffset); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprime_test.c b/plugin/ippcp/library/src/sources/ippcp/pcpprime_test.c new file mode 100644 index 000000000..311df8e60 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprime_test.c @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// cpPrimeTest() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcptool.h" + +/* Rabin-Miller test */ +/* -1 is returned when pBuffer cannot be allocated */ +static int RabinMiller(int a, BNU_CHUNK_T* pZ, BNU_CHUNK_T* pR, cpSize nsR, BNU_CHUNK_T* pM, cpSize nsM, gsModEngine* pModEngine) +{ + /* modulus and it length and other parameters */ + const BNU_CHUNK_T* pModulus = MOD_MODULUS(pModEngine); + cpSize modLen = MOD_LEN(pModEngine); + + const int usedPoolLen = 1; + BNU_CHUNK_T* pBuffer = 0; + + /* compute z = r^m mod prime */ + nsR = cpMontEnc_BNU_EX(pR, pR, nsR, pModEngine); + cpMontExpBin_BNU(pZ, pR, nsR, pM, nsM, pModEngine); + + /* if z==1 => probably prime */ + if(0==cpCmp_BNU(pZ, modLen, MOD_MNT_R(pModEngine), modLen)) + return 1; + + pBuffer = gsModPoolAlloc(pModEngine, usedPoolLen); + if(NULL == pBuffer) + return -1; + + /* if z==prime-1 => probably prime */ + cpSub_BNU(pBuffer, pModulus, MOD_MNT_R(pModEngine), modLen); + if(0==cpCmp_BNU(pZ, modLen, pBuffer, modLen)) + { + gsModPoolFree(pModEngine, usedPoolLen); + return 1; + } + + while(--a) { + + /* z = z^2 mod w */ + cpMontSqr_BNU(pZ, pZ, pModEngine); + + /* if z==1 => definitely composite */ + if(0==cpCmp_BNU(pZ, modLen, MOD_MNT_R(pModEngine), modLen)) + { + gsModPoolFree(pModEngine, usedPoolLen); + return 0; + } + + /* if z==w-1 => probably prime */ + cpSub_BNU(pBuffer, pModulus, MOD_MNT_R(pModEngine), modLen); + if(0==cpCmp_BNU(pZ, modLen, pBuffer, modLen)) + { + gsModPoolFree(pModEngine, usedPoolLen); + return 1; + } + } + + gsModPoolFree(pModEngine, usedPoolLen); + + /* if we are here, then we deal with composize */ + return 0; +} + +/* + returns: + IPP_IS_PRIME (==1) - prime value has been detected + IPP_IS_COMPOSITE (==0) - composite value has been detected + -1 - if internal error (ippStsNoErr != rndFunc()) +*/ + +/*F* +// Name: cpPrimeTest +// +// Purpose: Test a number for being a probable prime. +// +// Returns: Reason: +// 0 not prime number +// 1 prime number +// +// Parameters: +// pPrime prime number +// primeLen length of prime number +// nTrials parameter for the Miller-Rabin probable primality test +// pCtx pointer to the context +// rndFunc external PRNG +// pRndParam pointer to the external PRNG parameters +*F*/ + +IPP_OWN_DEFN (int, cpPrimeTest, (const BNU_CHUNK_T* pPrime, cpSize primeLen, cpSize nTrials, IppsPrimeState* pCtx, IppBitSupplier rndFunc, void* pRndParam)) +{ + FIX_BNU(pPrime, primeLen); + + if( primeLen==1 && pPrime[0]==0) + return 0; + + /* 2 is prime number */ + else if( primeLen==1 && pPrime[0]==2) + return 1; + + /* + // test number + */ + else { + cpSize primeBitsize = BITSIZE_BNU(pPrime, primeLen); + cpSize primeLen32 = BITS2WORD32_SIZE(primeBitsize); + + /* apply easy prime test */ + if( 0==cpMimimalPrimeTest((Ipp32u*)pPrime, primeLen32) ) + return 0; + + /* continue test */ + else { + cpSize n, a; + + gsModEngine* pModEngine = PRIME_MONT(pCtx); + BNU_CHUNK_T* pMdata = PRIME_TEMP1(pCtx); + BNU_CHUNK_T* pRdata = PRIME_TEMP2(pCtx); + BNU_CHUNK_T* pZdata = PRIME_TEMP3(pCtx); + cpSize lenM, lenR; + + /* set up Montgomery engine (and save value being under the test) */ + gsModEngineInit(pModEngine, (Ipp32u*)pPrime, BITSIZE_BNU(pPrime, primeLen), MONT_DEFAULT_POOL_LENGTH, gsModArithMont()); + + /* express w = m*2^a + 1 */ + cpDec_BNU(pMdata, pPrime, primeLen, 1); + for(n=0,a=0; n=1 */ + if(!cpTst_BNU(pRdata, lenR)) + pRdata[0] |= 1; + FIX_BNU(pRdata, lenR); + + /* Rabin-Miller test */ + int result = RabinMiller(a, pZdata, pRdata,primeLen, pMdata,lenM, pModEngine); + if(-1 == result) //internal error + return -1; + if(0 == result) + return 0; + } + + return 1; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprime_unpackctx.c b/plugin/ippcp/library/src/sources/ippcp/pcpprime_unpackctx.c new file mode 100644 index 000000000..b2d83d6fb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprime_unpackctx.c @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// cpUnpackPrimeCtx() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcptool.h" + +/*F* +// Name: cpUnpackPrimeCtx +// +// Purpose: Deserialize prime context +// +// Parameters: +// pCtx context +// pBuffer buffer +*F*/ + +IPP_OWN_DEFN (void, cpUnpackPrimeCtx, (const Ipp8u* pBuffer, IppsPrimeState* pCtx)) +{ + IppsPrimeState* pB = (IppsPrimeState*)(pBuffer); + + /* max length of prime */ + cpSize nsPrime = BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pB)); + + CopyBlock(pB, pCtx, sizeof(IppsPrimeState)); + + Ipp8u* ptr = (Ipp8u*)pCtx; + ptr += sizeof(IppsPrimeState); + ptr = IPP_ALIGNED_PTR(ptr, PRIME_ALIGNMENT); + PRIME_NUMBER(pCtx)= (BNU_CHUNK_T*)(ptr); + ptr += nsPrime*(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_TEMP1(pCtx) = (BNU_CHUNK_T*)(ptr); + ptr += nsPrime*(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_TEMP2(pCtx) = (BNU_CHUNK_T*)(ptr); + ptr += nsPrime*(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_TEMP3(pCtx) = (BNU_CHUNK_T*)(ptr); + ptr += nsPrime*(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_MONT(pCtx) = (gsModEngine*)(ptr); + + cpSize gsMontOffset = (cpSize)(IPP_INT_PTR(PRIME_MONT(pCtx)) - IPP_INT_PTR(pCtx)); + + CopyBlock((Ipp8u*)pB + sizeof(IppsPrimeState), PRIME_NUMBER(pCtx), nsPrime*(Ipp32s)sizeof(BNU_CHUNK_T)); + gsUnpackModEngineCtx((Ipp8u*)pB + gsMontOffset, PRIME_MONT(pCtx)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimeg.h b/plugin/ippcp/library/src/sources/ippcp/pcpprimeg.h new file mode 100644 index 000000000..ac0cb8e43 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimeg.h @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// +*/ + + +#if !defined(_CP_PRIME_H) +#define _CP_PRIME_H + +#include "pcpbn.h" +#include "pcpmontgomery.h" + + +/* +// Prime context +*/ +struct _cpPrime { + Ipp32u idCtx; /* Prime context identifier */ + cpSize maxBitSize; /* max bit length */ + BNU_CHUNK_T* pPrime; /* prime value */ + BNU_CHUNK_T* pT1; /* temporary BNU */ + BNU_CHUNK_T* pT2; /* temporary BNU */ + BNU_CHUNK_T* pT3; /* temporary BNU */ + gsModEngine* pMont; /* montgomery engine */ +}; + +/* alignment */ +#define PRIME_ALIGNMENT ((int)sizeof(void*)) + +/* Prime accessory macros */ +#define PRIME_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxPrimeNumber ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define PRIME_MAXBITSIZE(ctx) ((ctx)->maxBitSize) +#define PRIME_NUMBER(ctx) ((ctx)->pPrime) +#define PRIME_TEMP1(ctx) ((ctx)->pT1) +#define PRIME_TEMP2(ctx) ((ctx)->pT2) +#define PRIME_TEMP3(ctx) ((ctx)->pT3) +#define PRIME_MONT(ctx) ((ctx)->pMont) + +#define PRIME_VALID_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxPrimeNumber) + +/* +// Number of Miller-Rabin rounds for an error rate of less than 1/2^80 for random 'b'-bit input, b >= 100. +// (see Table 4.4, Handbook of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996] +*/ +#define MR_rounds_p80(b) ((b) >= 1300 ? 2 : \ + (b) >= 850 ? 3 : \ + (b) >= 650 ? 4 : \ + (b) >= 550 ? 5 : \ + (b) >= 450 ? 6 : \ + (b) >= 400 ? 7 : \ + (b) >= 350 ? 8 : \ + (b) >= 300 ? 9 : \ + (b) >= 250 ? 12 : \ + (b) >= 200 ? 15 : \ + (b) >= 150 ? 18 : \ + /*(b) >= 100*/ 27) + +/* easy prime test */ +#define cpMimimalPrimeTest OWNAPI(cpMimimalPrimeTest) + IPP_OWN_DECL (int, cpMimimalPrimeTest, (const Ipp32u* pPrime, cpSize ns)) + +/* prime test */ +#define cpPrimeTest OWNAPI(cpPrimeTest) + IPP_OWN_DECL (int, cpPrimeTest, (const BNU_CHUNK_T* pPrime, cpSize primeLen, cpSize nTrials, IppsPrimeState* pCtx, IppBitSupplier rndFunc, void* pRndParam)) + +#define cpPackPrimeCtx OWNAPI(cpPackPrimeCtx) + IPP_OWN_DECL (void, cpPackPrimeCtx, (const IppsPrimeState* pCtx, Ipp8u* pBuffer)) +#define cpUnpackPrimeCtx OWNAPI(cpUnpackPrimeCtx) + IPP_OWN_DECL (void, cpUnpackPrimeCtx, (const Ipp8u* pBuffer, IppsPrimeState* pCtx)) + +#endif /* _CP_PRIME_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimegen_bn.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimegen_bn.c new file mode 100644 index 000000000..97d8315b6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimegen_bn.c @@ -0,0 +1,124 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeGen_BN() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcptool.h" + +/*F* +// Name: ippsPrimeGen_BN +// +// Purpose: Generates a random probable prime Big number of the specified bitlength. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == rndFunc +// ippStsContextMatchErr !PRIME_VALID_ID() +// ippStsLengthErr 1 > nBits +// ippStsOutOfRangeErr nBits > PRIME_MAXBITSIZE() +// ippStsBadArgErr 1 > nTrials +// ippStsInsufficientEntropy when prime generation fails due +// to a poor choice of seed/context bitstream. +// ippStsNoErr no error +// +// Parameters: +// pPrime BigNum context +// nBits bitlength for the desired probable prime number +// nTrials parameter for the Miller-Rabin probable primality test +// pCtx pointer to the context +// rndFunc external PRNG +// pRndParam pointer to the external PRNG parameters +// +// +// Notes: +// ippsPrimeGen_BN() returns ippStsInsufficientEntropy, if it +// detects that it needs more entropy seed during its probable prime +// generation. In this case, the user should update PRNG parameters +// and call the primitive again. +*F*/ + +IPPFUN(IppStatus, ippsPrimeGen_BN, (IppsBigNumState* pPrime, int nBits, + int nTrials, + IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +{ + /* test generator context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test BN context */ + IPP_BAD_PTR1_RET(pPrime); + IPP_BADARG_RET(!BN_VALID_ID(pPrime), ippStsContextMatchErr); + + IPP_BADARG_RET(nBits<1, ippStsLengthErr); + IPP_BADARG_RET(nBits>PRIME_MAXBITSIZE(pCtx), ippStsOutOfRangeErr); + IPP_BADARG_RET(BN_ROOM(pPrime) < BITS_BNU_CHUNK(nBits), ippStsOutOfRangeErr); + + IPP_BADARG_RET(nTrials < 0, ippStsBadArgErr); + IPP_BAD_PTR1_RET(rndFunc); + + { + cpSize count; + Ipp32u result = IPP_IS_COMPOSITE; + + BNU_CHUNK_T botPattern = 0x1; + BNU_CHUNK_T topPattern = (BNU_CHUNK_T)1 << ((nBits-1)&(BNU_CHUNK_BITS-1)); + BNU_CHUNK_T topMask = MASK_BNU_CHUNK(nBits); + + BNU_CHUNK_T* pRand = BN_NUMBER(pPrime); + cpSize randLen = BITS_BNU_CHUNK(nBits); + + ZEXPAND_BNU(pRand, 0, BN_ROOM(pPrime)); + BN_SIZE(pPrime) = randLen; + BN_SIGN(pPrime) = ippBigNumPOS; + + if (nTrials < 1) + nTrials = MR_rounds_p80(nBits); + + #define MAX_COUNT (1000) + for(count=0; count +/*F* +// Name: ippsPrimeGen +// +// Purpose: Generates a random probable prime number of the specified bitlength. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == rndFunc +// ippStsContextMatchErr !PRIME_VALID_ID() +// ippStsLengthErr 1 > nBits +// ippStsOutOfRangeErr nBits > PRIME_MAXBITSIZE() +// ippStsBadArgErr 1 > nTrials +// ippStsInsufficientEntropy when prime generation fails due +// to a poor choice of seed/context bitstream. +// ippStsNoErr no error +// +// Parameters: +// nBits bitlength for the desired probable prime number +// nTrials parameter for the Miller-Rabin probable primality test +// pCtx pointer to the context +// rndFunc external PRNG +// pRndParam pointer to the external PRNG parameters +// +// +// Notes: +// ippsPrimeGen()returns ippStsInsufficientEntropy, if it +// detects that it needs more entropy seed during its probable prime +// generation. In this case, the user should update PRNG parameters +// and call the primitive again. +*F*/ +IPPFUN(IppStatus, ippsPrimeGen, (int nBits, int nTrials, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR2_RET(pCtx, rndFunc); + + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + IPP_BADARG_RET(nBits<1, ippStsLengthErr); + IPP_BADARG_RET(nBits>PRIME_MAXBITSIZE(pCtx), ippStsOutOfRangeErr); + + IPP_BADARG_RET(nTrials < 0, ippStsBadArgErr); + + { + cpSize count; + + BNU_CHUNK_T botPattern = 0x1; + BNU_CHUNK_T topPattern = (BNU_CHUNK_T)1 << ((nBits-1)&(BNU_CHUNK_BITS-1)); + BNU_CHUNK_T topMask = MASK_BNU_CHUNK(nBits); + + BNU_CHUNK_T* pRand = PRIME_NUMBER(pCtx); + cpSize randLen = BITS_BNU_CHUNK(nBits); + + ZEXPAND_BNU(pRand, 0, BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pCtx))); + + if(nTrials < 1) + nTrials = MR_rounds_p80(nBits); + + #define MAX_COUNT (1000) + for(count=0; countidCtx +// ippStsNoErr no error +// +// Parameters: +// pPrime pointer to the BNU value +// pSize pointer to the BNU wordsize +// pCtx pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsPrimeGet, (Ipp32u* pPrime, int* pSize, const IppsPrimeState* pCtx)) +{ + IPP_BAD_PTR3_RET(pCtx, pPrime, pSize); + + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + { + Ipp32u* pValue = (Ipp32u*)PRIME_NUMBER(pCtx); + cpSize len32 = BITS2WORD32_SIZE(PRIME_MAXBITSIZE(pCtx)); + FIX_BNU32(pValue, len32); + + COPY_BNU(pPrime, pValue, len32); + *pSize = len32; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimeget_bn.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimeget_bn.c new file mode 100644 index 000000000..11973bd17 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimeget_bn.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeGet_BN() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" + +/*F* +// Name: ippsPrimeGet_BN +// +// Purpose: Extracts probable prime and store into BN. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pPrime +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pPrime->idCtx +// ippStsOutOfRangeErr BN_ROOM(pPrime) < BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pCtx)) +// ippStsNoErr no error +// +// Parameters: +// pPrime pointer to the BN +// pCtx pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsPrimeGet_BN, (IppsBigNumState* pPrime, const IppsPrimeState* pCtx)) +{ + IPP_BAD_PTR2_RET(pCtx, pPrime); + + IPP_BADARG_RET(!BN_VALID_ID(pPrime), ippStsContextMatchErr); + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + { + BNU_CHUNK_T* pValue = PRIME_NUMBER(pCtx); + cpSize ns = BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pCtx)); + FIX_BNU(pValue, ns); + + IPP_BADARG_RET(BN_ROOM(pPrime) < ns, ippStsOutOfRangeErr); + + COPY_BNU(BN_NUMBER(pPrime), pValue, ns); + BN_SIZE(pPrime) = ns; + BN_SIGN(pPrime) = ippBigNumPOS; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimegetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimegetsize.c new file mode 100644 index 000000000..559398336 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimegetsize.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeGetSize() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcptool.h" + +/*F* +// Name: ippsPrimeGetSize +// +// Purpose: Returns size of Prime Number Generator context (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// ippStsLengthErr 1 > nMaxBits +// ippStsNoErr no error +// +// Parameters: +// nMaxBits max length of a prime number +// pSize pointer to the size of internal context +*F*/ +IPPFUN(IppStatus, ippsPrimeGetSize, (int nMaxBits, int* pSize)) +{ + IPP_BAD_PTR1_RET(pSize); + IPP_BADARG_RET(nMaxBits<1, ippStsLengthErr); + + { + cpSize len = BITS_BNU_CHUNK(nMaxBits); + cpSize montSize; + + gsModEngineGetSize(nMaxBits, MONT_DEFAULT_POOL_LENGTH, &montSize); + + *pSize = (Ipp32s)sizeof(IppsPrimeState) + +len*(Ipp32s)sizeof(BNU_CHUNK_T) + +len*(Ipp32s)sizeof(BNU_CHUNK_T) + +len*(Ipp32s)sizeof(BNU_CHUNK_T) + +len*(Ipp32s)sizeof(BNU_CHUNK_T) + +montSize + +PRIME_ALIGNMENT-1; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimeginitca.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimeginitca.c new file mode 100644 index 000000000..dbc86a490 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimeginitca.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeInit() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcptool.h" + +/*F* +// Name: ippsPrimeInit +// +// Purpose: Initializes Prime Number Generator context +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// ippStsLengthErr 1 > nMaxBits +// ippStsNoErr no error +// +// Parameters: +// nMaxBits max length of a prime number +// pCtx pointer to the context to be initialized +*F*/ +IPPFUN(IppStatus, ippsPrimeInit, (int nMaxBits, IppsPrimeState* pCtx)) +{ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(nMaxBits<1, ippStsLengthErr); + + { + Ipp8u* ptr = (Ipp8u*)pCtx; + + cpSize len = BITS_BNU_CHUNK(nMaxBits); + + PRIME_SET_ID(pCtx); + PRIME_MAXBITSIZE(pCtx) = nMaxBits; + + ptr += sizeof(IppsPrimeState); + ptr = (Ipp8u*)(IPP_ALIGNED_PTR(ptr, PRIME_ALIGNMENT)); + PRIME_NUMBER(pCtx) = (BNU_CHUNK_T*)ptr; + + ptr += len*(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_TEMP1(pCtx) = (BNU_CHUNK_T*)ptr; + + ptr += len*(Ipp32s)(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_TEMP2(pCtx) = (BNU_CHUNK_T*)ptr; + + ptr += len*(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_TEMP3(pCtx) = (BNU_CHUNK_T*)ptr; + + ptr += len*(Ipp32s)sizeof(BNU_CHUNK_T); + PRIME_MONT(pCtx) = (gsModEngine*)(ptr); + gsModEngineInit(PRIME_MONT(pCtx), NULL, nMaxBits, MONT_DEFAULT_POOL_LENGTH, gsModArithMont()); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimegsetca.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimegsetca.c new file mode 100644 index 000000000..2a4c029fe --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimegsetca.c @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeSet() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" + +/*F* +// Name: ippsPrimeSet +// +// Purpose: Sets a trial BNU for further testing +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pPrime +// ippStsContextMatchErr illegal pCtx->idCtx +// ippStsLengthErr 1 > nBits +// ippStsOutOfRangeErr nBits > PRIME_MAXBITSIZE(pCtx) +// ippStsNoErr no error +// +// Parameters: +// pPrime pointer to the number to be set +// nBits bitlength of input number bitlength +// pCtx pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsPrimeSet, (const Ipp32u* pPrime, int nBits, IppsPrimeState* pCtx)) +{ + IPP_BAD_PTR2_RET(pCtx, pPrime); + IPP_BADARG_RET(nBits<1, ippStsLengthErr); + + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + IPP_BADARG_RET(nBits > PRIME_MAXBITSIZE(pCtx), ippStsOutOfRangeErr); + + /* clear prime container */ + ZEXPAND_BNU(PRIME_NUMBER(pCtx), 0, BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pCtx))); + + { + Ipp32u* pValue = (Ipp32u*)PRIME_NUMBER(pCtx); + + cpSize len32 = BITS2WORD32_SIZE(nBits); + Ipp32u mask = MAKEMASK32(nBits); + FIX_BNU32(pPrime, len32); + + ZEXPAND_COPY_BNU(pValue, BITS2WORD32_SIZE(PRIME_MAXBITSIZE(pCtx)), pPrime, len32); + pValue[len32-1] &= mask; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimeset_bn.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimeset_bn.c new file mode 100644 index 000000000..6a567ab6b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimeset_bn.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeSet_BN() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" + +/*F* +// Name: ippsPrimeSet_BN +// +// Purpose: Sets a trial BN for further testing +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pPrime +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pPrime->idCtx +// ippStsOutOfRangeErr BITSIZE_BNU(BN_NUMBER(pPrime), BN_SIZE(pPrime)) +// > PRIME_MAXBITSIZE(pCtx) +// ippStsNoErr no error +// +// Parameters: +// pPrime pointer to the BN to be set +// pCtx pointer to the context +// +*F*/ +IPPFUN(IppStatus, ippsPrimeSet_BN, (const IppsBigNumState* pPrime, IppsPrimeState* pCtx)) +{ + IPP_BAD_PTR2_RET(pCtx, pPrime); + + IPP_BADARG_RET(!BN_VALID_ID(pPrime), ippStsContextMatchErr); + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pPrime), BN_SIZE(pPrime)) > PRIME_MAXBITSIZE(pCtx), ippStsOutOfRangeErr); + + { + BNU_CHUNK_T* pPrimeU = BN_NUMBER(pPrime); + cpSize ns = BN_SIZE(pPrime); + cpSize nBits = BITSIZE_BNU(pPrimeU, ns); + + BNU_CHUNK_T* pPrimeCtx = PRIME_NUMBER(pCtx); + BNU_CHUNK_T topMask = MASK_BNU_CHUNK(nBits); + + ZEXPAND_COPY_BNU(pPrimeCtx, BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pCtx)), pPrimeU, ns); + pPrimeCtx[ns-1] &= topMask; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimetest.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimetest.c new file mode 100644 index 000000000..5fdcc11c6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimetest.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeTest() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcptool.h" + +/*F* +// Name: ippsPrimeTest +// +// Purpose: Test a number for being a probable prime. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == rndFunc +// NULL == pResult +// ippStsContextMatchErr !PRIME_VALID_ID() +// ippStsBadArgErr 1 > nTrials +// ippStsNoErr no error +// +// Parameters: +// pResult result of test +// nTrials parameter for the Miller-Rabin probable primality test +// pCtx pointer to the context +// rndFunc external PRNG +// pRndParam pointer to the external PRNG parameters +*F*/ + +IPPFUN(IppStatus, ippsPrimeTest, (int nTrials, + Ipp32u* pResult, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR3_RET(pResult, pCtx, rndFunc); + IPP_BADARG_RET(nTrials<1, ippStsBadArgErr); + + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + { + BNU_CHUNK_T* pPrime = PRIME_NUMBER(pCtx); + cpSize ns = BITS_BNU_CHUNK(PRIME_MAXBITSIZE(pCtx)); + FIX_BNU(pPrime, ns); + + { + int ret = cpPrimeTest(pPrime, ns, nTrials, pCtx, rndFunc, pRndParam); + if(-1 == ret) + return ippStsErr; + else { + *pResult = ret? IPP_IS_PRIME : IPP_IS_COMPOSITE; + return ippStsNoErr; + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprimetest_bn.c b/plugin/ippcp/library/src/sources/ippcp/pcpprimetest_bn.c new file mode 100644 index 000000000..2144c8f1a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprimetest_bn.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Intel(R) Integrated Performance Primitives. Cryptographic Primitives (ippcp) +// Prime Number Primitives. +// +// Contents: +// ippsPrimeTest_BN() +// +*/ + +#include "owncp.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcptool.h" + +/*F* +// Name: ippsPrimeTest_BN +// +// Purpose: Test a Big number for being a probable prime. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == rndFunc +// NULL == pResult +// ippStsContextMatchErr !PRIME_VALID_ID() +// ippStsBadArgErr 1 > nTrials +// ippStsNoErr no error +// +// Parameters: +// pPrime BigNum context +// pResult result of test +// nTrials parameter for the Miller-Rabin probable primality test +// pCtx pointer to the context +// rndFunc external PRNG +// pRndParam pointer to the external PRNG parameters +*F*/ + +IPPFUN(IppStatus, ippsPrimeTest_BN, (const IppsBigNumState* pPrime, + int nTrials, + Ipp32u* pResult, IppsPrimeState* pCtx, + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR4_RET(pPrime, pResult, pCtx, rndFunc); + IPP_BADARG_RET(nTrials<1, ippStsBadArgErr); + + IPP_BADARG_RET(!PRIME_VALID_ID(pCtx), ippStsContextMatchErr); + + IPP_BADARG_RET(!BN_VALID_ID(pPrime), ippStsContextMatchErr); + + { + BNU_CHUNK_T* pPrimeBN = BN_NUMBER(pPrime); + cpSize ns = BN_SIZE(pPrime); + + { + int ret = cpPrimeTest(pPrimeBN, ns, nTrials, pCtx, rndFunc, pRndParam); + if(-1 == ret) + return ippStsErr; + else { + *pResult = ret? IPP_IS_PRIME : IPP_IS_COMPOSITE; + return ippStsNoErr; + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprng.h b/plugin/ippcp/library/src/sources/ippcp/pcpprng.h new file mode 100644 index 000000000..a62e1b5ff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprng.h @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions and +// Internal Pseudo Random Generator Function Prototypes +// +*/ + +#if !defined(_CP_PRNG_H) +#define _CP_PRNG_H + +/* +// Pseudo-random generation context +*/ + +#define MAX_XKEY_SIZE 512 +#define DEFAULT_XKEY_SIZE 512 /* must be >=160 || <=512 */ + +struct _cpPRNG { + Ipp32u idCtx; /* PRNG identifier */ + cpSize seedBits; /* secret seed-key bitsize */ + BNU_CHUNK_T Q[BITS_BNU_CHUNK(160)]; /* modulus */ + BNU_CHUNK_T T[BITS_BNU_CHUNK(160)]; /* parameter of SHA_G() funct */ + BNU_CHUNK_T xAug[BITS_BNU_CHUNK(MAX_XKEY_SIZE)]; /* optional entropy augment */ + BNU_CHUNK_T xKey[BITS_BNU_CHUNK(MAX_XKEY_SIZE)]; /* secret seed-key */ +}; + +/* alignment */ +#define PRNG_ALIGNMENT ((int)(sizeof(void*))) + +#define RAND_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxPRNG ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define RAND_SEEDBITS(ctx) ((ctx)->seedBits) +#define RAND_Q(ctx) ((ctx)->Q) +#define RAND_T(ctx) ((ctx)->T) +#define RAND_XAUGMENT(ctx) ((ctx)->xAug) +#define RAND_XKEY(ctx) ((ctx)->xKey) + +#define RAND_VALID_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxPRNG) + +#define cpPRNGen OWNAPI(cpPRNGen) + IPP_OWN_DECL (int, cpPRNGen, (Ipp32u* pBuffer, cpSize bitLen, IppsPRNGState* pCtx)) +#define cpPRNGenPattern OWNAPI(cpPRNGenPattern) + IPP_OWN_DECL (int, cpPRNGenPattern, (BNU_CHUNK_T* pRand, int bitSize, BNU_CHUNK_T botPattern, BNU_CHUNK_T topPattern, IppBitSupplier rndFunc, void* pRndParam)) +#define cpPRNGenRange OWNAPI(cpPRNGenRange) + IPP_OWN_DECL (int, cpPRNGenRange, (BNU_CHUNK_T* pRand, const BNU_CHUNK_T* pLo, cpSize loLen, const BNU_CHUNK_T* pHi, cpSize hiLen, IppBitSupplier rndFunc, void* pRndParam)) + +#endif /* _CP_PRNG_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprng_gen.c b/plugin/ippcp/library/src/sources/ippcp/pcpprng_gen.c new file mode 100644 index 000000000..22e462243 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprng_gen.c @@ -0,0 +1,149 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// cpPRNGen() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcphash.h" +#include "pcpprng.h" +#include "pcptool.h" + + +/* +// G() function based on SHA1 +// +// Parameters: +// T 160 bit parameter +// pHexStr input hex string +// hexStrLen size of hex string (Ipp8u segnments) +// xBNU 160 bit BNU result +// +// Note 1: +// must to be hexStrLen <= 64 (512 bits) +*/ +static void SHA1_G(Ipp32u* xBNU, const Ipp32u* T, Ipp8u* pHexStr, int hexStrLen) +{ + /* select processing function */ + cpHashProc updateFunc; + #if (_SHA_NI_ENABLING_==_FEATURE_ON_) + updateFunc = UpdateSHA1ni; + #elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_) + updateFunc = IsFeatureEnabled(ippCPUID_SHA)? UpdateSHA1ni : UpdateSHA1; + #else + updateFunc = UpdateSHA1; + #endif + + /* pad HexString zeros */ + PadBlock(0, pHexStr+hexStrLen, BITS2WORD8_SIZE(MAX_XKEY_SIZE)-hexStrLen); + + /* reset initial HASH value */ + xBNU[0] = T[0]; + xBNU[1] = T[1]; + xBNU[2] = T[2]; + xBNU[3] = T[3]; + xBNU[4] = T[4]; + + /* SHA1 */ + //UpdateSHA1(xBNU, pHexStr, BITS2WORD8_SIZE(MAX_XKEY_SIZE), SHA1_cnt); + updateFunc(xBNU, pHexStr, BITS2WORD8_SIZE(MAX_XKEY_SIZE), SHA1_cnt); + + /* swap back */ + SWAP(xBNU[0],xBNU[4]); + SWAP(xBNU[1],xBNU[3]); +} + +/*F* +// Name: cpPRNGen +// +// Purpose: Returns bitsize of the bitstring has beed added +// +// Returns: +// bitsize of the bitstring has beed added +// +// Parameters: +// pRand pointer to the buffer +// nBits number of bits be requested +// pRnd pointer to the context +*F*/ + +IPP_OWN_DEFN (int, cpPRNGen, (Ipp32u* pRand, cpSize nBits, IppsPRNGState* pRnd)) +{ + BNU_CHUNK_T Xj [BITS_BNU_CHUNK(MAX_XKEY_SIZE)]; + BNU_CHUNK_T XVAL[BITS_BNU_CHUNK(MAX_XKEY_SIZE)]; + + Ipp8u TXVAL[BITS2WORD8_SIZE(MAX_XKEY_SIZE)]; + + /* XKEY length in BNU_CHUNK_T */ + cpSize xKeyLen = BITS_BNU_CHUNK(RAND_SEEDBITS(pRnd)); + /* XKEY length in bytes */ + cpSize xKeySize= BITS2WORD8_SIZE(RAND_SEEDBITS(pRnd)); + /* XKEY word's mask */ + BNU_CHUNK_T xKeyMsk = MASK_BNU_CHUNK(RAND_SEEDBITS(pRnd)); + + /* number of Ipp32u chunks to be generated */ + cpSize genlen = BITS2WORD32_SIZE(nBits); + + ZEXPAND_BNU(Xj, 0, BITS_BNU_CHUNK(MAX_XKEY_SIZE)); + ZEXPAND_BNU(XVAL, 0, BITS_BNU_CHUNK(MAX_XKEY_SIZE)); + + while(genlen) { + cpSize len; + + /* Step 1: XVAL=(Xkey+Xseed) mod 2^b */ + BNU_CHUNK_T carry = cpAdd_BNU(XVAL, RAND_XKEY(pRnd), RAND_XAUGMENT(pRnd), xKeyLen); + XVAL[xKeyLen-1] &= xKeyMsk; + + /* Step 2: xj=G(t, XVAL) mod Q */ + cpToOctStr_BNU(TXVAL, xKeySize, XVAL, xKeyLen); + SHA1_G((Ipp32u*)Xj, (Ipp32u*)RAND_T(pRnd), TXVAL, xKeySize); + + { + cpSize sizeXj = BITS_BNU_CHUNK(160); + if(0 <= cpCmp_BNU(Xj, BITS_BNU_CHUNK(IPP_SHA1_DIGEST_BITSIZE), RAND_Q(pRnd),BITS_BNU_CHUNK(IPP_SHA1_DIGEST_BITSIZE)) ) + sizeXj = cpMod_BNU(Xj, BITS_BNU_CHUNK(IPP_SHA1_DIGEST_BITSIZE), RAND_Q(pRnd), BITS_BNU_CHUNK(IPP_SHA1_DIGEST_BITSIZE)); + FIX_BNU(Xj, sizeXj); + ZEXPAND_BNU(Xj, sizeXj, BITS_BNU_CHUNK(MAX_XKEY_SIZE)); + } + + /* Step 3: Xkey=(1+Xkey+Xj) mod 2^b */ + cpInc_BNU(RAND_XKEY(pRnd), RAND_XKEY(pRnd), xKeyLen, 1); + carry = cpAdd_BNU(RAND_XKEY(pRnd), RAND_XKEY(pRnd), Xj, xKeyLen); + RAND_XKEY(pRnd)[xKeyLen-1] &= xKeyMsk; + + /* fill out result */ + len = genlen=_IPP_G9) || (_IPP32E>=_IPP32E_E9)) +__INLINE int cpRand_hw_sample(BNU_CHUNK_T* pSample) +{ +#define LOCAL_COUNTER (8) + int n; + int success = 0; + for(n=0; n=_IPP32E_E9) +__INLINE int cpRand_hw_sample32(Ipp32u* pSample) +{ +#define LOCAL_COUNTER (8) + int n; + int success = 0; + for(n=0; n=_IPP32E_E9) + if( bufLen%((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))) ) { + if( !cpRand_hw_sample32(pBuffer)) { + return 0; + } + } + #endif + return 1; +} +#endif + +#endif /* #if !defined (_PCP_PRN_GEN_HW_H) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngen_bn.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngen_bn.c new file mode 100644 index 000000000..67c47f332 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngen_bn.c @@ -0,0 +1,90 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGen_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcphash.h" +#include "pcpprng.h" +#include "pcptool.h" + +/*F* +// Name: ippsPRNGen_BN +// +// Purpose: Generates a pseudorandom big number of the specified nBits length. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pRand +// +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pRand->idCtx +// +// ippStsLengthErr 1 > nBits +// nBits > BN_ROOM(pRand) +// +// ippStsNoErr no error +// +// Parameters: +// pRand pointer to the BN random +// nBits number of bits be requested +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsPRNGen_BN,(IppsBigNumState* pRand, int nBits, void* pCtx)) +{ + IppsPRNGState* pRndCtx; + + /* test PRNG context */ + IPP_BAD_PTR1_RET(pCtx); + pRndCtx = (IppsPRNGState*)(pCtx); + IPP_BADARG_RET(!RAND_VALID_ID(pRndCtx), ippStsContextMatchErr); + + /* test random BN */ + IPP_BAD_PTR1_RET(pRand); + IPP_BADARG_RET(!BN_VALID_ID(pRand), ippStsContextMatchErr); + + /* test sizes */ + IPP_BADARG_RET(nBits< 1, ippStsLengthErr); + IPP_BADARG_RET(nBits> BN_ROOM(pRand)*BNU_CHUNK_BITS, ippStsLengthErr); + + + { + BNU_CHUNK_T* pRandBN = BN_NUMBER(pRand); + cpSize rndSize = BITS_BNU_CHUNK(nBits); + BNU_CHUNK_T rndMask = MASK_BNU_CHUNK(nBits); + + cpPRNGen((Ipp32u*)pRandBN, nBits, pRndCtx); + pRandBN[rndSize-1] &= rndMask; + + FIX_BNU(pRandBN, rndSize); + BN_SIZE(pRand) = rndSize; + BN_SIGN(pRand) = ippBigNumPOS; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngen_pattern.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngen_pattern.c new file mode 100644 index 000000000..07f424e85 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngen_pattern.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// cpPRNGenPattern() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcphash.h" +#include "pcpprng.h" +#include "pcptool.h" + +/* generates random string of specified bitSize length + returns: + 1 random bit string generated + -1 detected internal error (ippStsNoErr != rndFunc()) +*/ +IPP_OWN_DEFN (int, cpPRNGenPattern, (BNU_CHUNK_T* pRand, int bitSize, BNU_CHUNK_T botPattern, BNU_CHUNK_T topPattern, IppBitSupplier rndFunc, void* pRndParam)) +{ + BNU_CHUNK_T topMask = MASK_BNU_CHUNK(bitSize); + cpSize randLen = BITS_BNU_CHUNK(bitSize); + + IppStatus sts = rndFunc((Ipp32u*)pRand, bitSize, pRndParam); + if(ippStsNoErr!=sts) return -1; + + pRand[randLen-1] &= topMask; + pRand[0] |= botPattern; + pRand[randLen-1] |= topPattern; + return 1; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngen_range.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngen_range.c new file mode 100644 index 000000000..93a9328ed --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngen_range.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// cpPRNGenRange() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcphash.h" +#include "pcpprng.h" +#include "pcptool.h" + +/* generates random string of specified bitSize length + within specified ragnge lo < r < Hi + returns: + 0 random bit string not generated + 1 random bit string generated + -1 detected internal error (ippStsNoErr != rndFunc()) +*/ +IPP_OWN_DEFN (int, cpPRNGenRange, (BNU_CHUNK_T* pRand, const BNU_CHUNK_T* pLo, cpSize loLen, const BNU_CHUNK_T* pHi, cpSize hiLen, IppBitSupplier rndFunc, void* pRndParam)) +{ + int bitSize = BITSIZE_BNU(pHi,hiLen); + BNU_CHUNK_T topMask = MASK_BNU_CHUNK(bitSize); + + #define MAX_COUNT (1000) + int n; + for(n=0; nidCtx +// +// ippStsLengthErr 1 > nBits +// +// ippStsNoErr no error +// +// Parameters: +// pRand pointer to the buffer +// nBits number of bits be requested +// pCtx pointer to the context +*F*/ + +IPPFUN(IppStatus, ippsPRNGen,(Ipp32u* pRand, int nBits, void* pCtx)) +{ + IppsPRNGState* pCtxCtx = (IppsPRNGState*)pCtx; + + /* test PRNG context */ + IPP_BAD_PTR2_RET(pRand, pCtx); + IPP_BADARG_RET(!RAND_VALID_ID(pCtxCtx), ippStsContextMatchErr); + + /* test sizes */ + IPP_BADARG_RET(nBits< 1, ippStsLengthErr); + + { + cpSize rndSize = BITS2WORD32_SIZE(nBits); + Ipp32u rndMask = MAKEMASK32(nBits); + + cpPRNGen(pRand, nBits, pCtxCtx); + pRand[rndSize-1] &= rndMask; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngenhw_bn.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngenhw_bn.c new file mode 100644 index 000000000..c0798ba87 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngenhw_bn.c @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGenRDRAND_BN() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" +#include "pcpprng_genhw.h" + +/*F* +// Name: ippsPRNGenRDRAND_BN +// +// Purpose: Generates a pseudorandom big number +// based on RDRAND instruction of the specified nBits length. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pBuffer +// +// ippStsLengthErr 1 > nBits +// nBits > BN_ROOM(pRand) +// +// ippStsNotSupportedModeErr unsupported rdrand instruction +// +// ippStsErr random big number can't be generated +// +// ippStsNoErr no error +// +// Parameters: +// pRand pointer to the big number +// nBits number of bits be requested +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsPRNGenRDRAND_BN,(IppsBigNumState* pRand, int nBits, void* pCtx)) +{ + /* test random BN */ + IPP_BAD_PTR1_RET(pRand); + IPP_BADARG_RET(!BN_VALID_ID(pRand), ippStsContextMatchErr); + + /* test sizes */ + IPP_BADARG_RET(nBits< 1, ippStsLengthErr); + IPP_BADARG_RET(nBits> BN_ROOM(pRand)*BNU_CHUNK_BITS, ippStsLengthErr); + + IPP_UNREFERENCED_PARAMETER(pCtx); + + #if ((_IPP>=_IPP_G9) || (_IPP32E>=_IPP32E_E9)) + if( IsFeatureEnabled(ippCPUID_RDRAND) ) { + BNU_CHUNK_T* pRandBN = BN_NUMBER(pRand); + cpSize rndSize = BITS_BNU_CHUNK(nBits); + BNU_CHUNK_T rndMask = MASK_BNU_CHUNK(nBits); + + if(cpRandHW_buffer((Ipp32u*)pRandBN, rndSize*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)))) { + pRandBN[rndSize-1] &= rndMask; + + FIX_BNU(pRandBN, rndSize); + BN_SIZE(pRand) = rndSize; + BN_SIGN(pRand) = ippBigNumPOS; + + return ippStsNoErr; + } + else + return ippStsErr; + } + + /* unsupported rdrand instruction */ + else + #endif + IPP_ERROR_RET(ippStsNotSupportedModeErr); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngenhwca.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngenhwca.c new file mode 100644 index 000000000..eeeb3a036 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngenhwca.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGenRDRAND() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" +#include "pcpprng_genhw.h" + +/*F* +// Name: ippsPRNGenRDRAND +// +// Purpose: Generates a pseudorandom bit sequence +// based on RDRAND instruction of the specified nBits length. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pRand +// +// ippStsLengthErr 1 > nBits +// +// ippStsNotSupportedModeErr unsupported rdrand instruction +// +// ippStsErr random bit sequence can't be generated +// +// ippStsNoErr no error +// +// Parameters: +// pRand pointer to the buffer +// nBits number of bits be requested +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsPRNGenRDRAND,(Ipp32u* pRand, int nBits, void* pCtx)) +{ + /* test PRNG buffer */ + IPP_BAD_PTR1_RET(pRand); + + /* test sizes */ + IPP_BADARG_RET(nBits< 1, ippStsLengthErr); + + IPP_UNREFERENCED_PARAMETER(pCtx); + + #if ((_IPP>=_IPP_G9) || (_IPP32E>=_IPP32E_E9)) + if( IsFeatureEnabled(ippCPUID_RDRAND) ) { + cpSize rndSize = BITS2WORD32_SIZE(nBits); + Ipp32u rndMask = MAKEMASK32(nBits); + + if(cpRandHW_buffer(pRand, rndSize)) { + pRand[rndSize-1] &= rndMask; + return ippStsNoErr; + } + else + return ippStsErr; + } + /* unsupported rdrand instruction */ + else + #endif + IPP_ERROR_RET(ippStsNotSupportedModeErr); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprnggetseed.c b/plugin/ippcp/library/src/sources/ippcp/pcpprnggetseed.c new file mode 100644 index 000000000..8da2254c2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprnggetseed.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGGetSeed() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprng.h" + +/*F* +// Name: ippsPRNGGetSeed +// +// Purpose: Get current SEED value from the state +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pSeed +// +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pSeed->idCtx +// ippStsOutOfRangeErr length of the actual SEED > length SEED destination +// +// ippStsNoErr no error +// +// Parameters: +// pCtx pointer to the context +// pSeed pointer to the SEED +*F*/ +IPPFUN(IppStatus, ippsPRNGGetSeed, (const IppsPRNGState* pCtx, IppsBigNumState* pSeed)) +{ + /* test PRNG context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RAND_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test seed */ + IPP_BAD_PTR1_RET(pSeed); + IPP_BADARG_RET(!BN_VALID_ID(pSeed), ippStsContextMatchErr); + + return ippsSet_BN(ippBigNumPOS, + BITS2WORD32_SIZE(RAND_SEEDBITS(pCtx)), + (Ipp32u*)RAND_XKEY(pCtx), + pSeed); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprnggetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpprnggetsize.c new file mode 100644 index 000000000..3ab23a47e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprnggetsize.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprng.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsPRNGGetSize +// +// Purpose: Returns size of PRNG context (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNoErr no error +// +// Parameters: +// pSize pointer to the size of internal context +*F*/ +IPPFUN(IppStatus, ippsPRNGGetSize, (int* pSize)) +{ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsPRNGState); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprnginitca.c b/plugin/ippcp/library/src/sources/ippcp/pcpprnginitca.c new file mode 100644 index 000000000..8ef02303d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprnginitca.c @@ -0,0 +1,87 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprng.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsPRNGInit +// +// Purpose: Initializes PRNG context +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// +// ippStsLengthErr seedBits < 1 +// seedBits < MAX_XKEY_SIZE +// seedBits % 8 !=0 +// +// ippStsNoErr no error +// +// Parameters: +// seedBits seed bitsize +// pCtx pointer to the context to be initialized +*F*/ +IPPFUN(IppStatus, ippsPRNGInit, (int seedBits, IppsPRNGState* pCtx)) +{ + /* test PRNG context */ + IPP_BAD_PTR1_RET(pCtx); + + /* test sizes */ + IPP_BADARG_RET((1>seedBits) || (seedBits>MAX_XKEY_SIZE) ||(seedBits&7), ippStsLengthErr); + + { + int hashIvSize = cpHashIvSize(ippHashAlg_SHA1); + const Ipp8u* iv = cpHashIV[ippHashAlg_SHA1]; + + /* cleanup context */ + ZEXPAND_BNU((Ipp8u*)pCtx, 0, (cpSize)(sizeof(IppsPRNGState))); + + RAND_SET_ID(pCtx); + RAND_SEEDBITS(pCtx) = seedBits; + + /* default Q parameter */ + ((Ipp32u*)RAND_Q(pCtx))[0] = 0xFFFFFFFF; + ((Ipp32u*)RAND_Q(pCtx))[1] = 0xFFFFFFFF; + ((Ipp32u*)RAND_Q(pCtx))[2] = 0xFFFFFFFF; + ((Ipp32u*)RAND_Q(pCtx))[3] = 0xFFFFFFFF; + ((Ipp32u*)RAND_Q(pCtx))[4] = 0xFFFFFFFF; + + /* workaround to avoid false positive stringop-overflow error on gcc10.1 and gcc11.1 */ + hashIvSize = ( IPP_MIN(hashIvSize, BITS2WORD8_SIZE(160)) ); + + /* default T parameter */ + CopyBlock(iv, RAND_T(pCtx), hashIvSize); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngsetaugment.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetaugment.c new file mode 100644 index 000000000..1c175a695 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetaugment.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGSetAugment() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprng.h" + +/*F* +// Name: ippsPRNGSetAugment +// +// Purpose: Sets the Entropy Augmentation +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pAug +// +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pAug->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pAug pointer to the entropy eugmentation +// pCtx pointer to the context +*F*/ + +IPPFUN(IppStatus, ippsPRNGSetAugment, (const IppsBigNumState* pAug, IppsPRNGState* pCtx)) +{ + /* test PRNG context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RAND_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test augmentation */ + IPP_BAD_PTR1_RET(pAug); + IPP_BADARG_RET(!BN_VALID_ID(pAug), ippStsContextMatchErr); + + { + cpSize argSize = BITS_BNU_CHUNK( RAND_SEEDBITS(pCtx) ); + BNU_CHUNK_T mask = MASK_BNU_CHUNK(RAND_SEEDBITS(pCtx)); + cpSize size = IPP_MIN(BN_SIZE(pAug), argSize); + + ZEXPAND_COPY_BNU(RAND_XAUGMENT(pCtx), (cpSize)(sizeof(RAND_XAUGMENT(pCtx))/sizeof(BNU_CHUNK_T)), BN_NUMBER(pAug), size); + RAND_XAUGMENT(pCtx)[argSize-1] &= mask; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngsetca.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetca.c new file mode 100644 index 000000000..d167b6e59 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetca.c @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGSetH0() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprng.h" + +/*F* +// Name: ippsPRNGSetH0 +// +// Purpose: Sets 160-bit parameter of G() function. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pH0 +// +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pH0->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pH0 pointer to the parameter used into G() function +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsPRNGSetH0,(const IppsBigNumState* pH0, IppsPRNGState* pCtx)) +{ + /* test PRNG context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RAND_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test H0 */ + IPP_BAD_PTR1_RET(pH0); + IPP_BADARG_RET(!BN_VALID_ID(pH0), ippStsContextMatchErr); + + { + cpSize len = IPP_MIN(5, BN_SIZE(pH0)*((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)))); + ZEXPAND_BNU(RAND_T(pCtx), 0, (int)(sizeof(RAND_T(pCtx))/sizeof(BNU_CHUNK_T))); + ZEXPAND_COPY_BNU((Ipp32u*)RAND_T(pCtx), (int)(sizeof(RAND_T(pCtx))/(sizeof(Ipp32u))), + (Ipp32u*)BN_NUMBER(pH0), len); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngsetmodulus.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetmodulus.c new file mode 100644 index 000000000..8d4879b4c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetmodulus.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGSetModulus() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprng.h" + +/*F* +// Name: ippsPRNGSetModulus +// +// Purpose: Sets 160-bit modulus Q. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pMod +// +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pMod->idCtx +// +// ippStsBadArgErr 160 != bitsize(pMod) +// +// ippStsNoErr no error +// +// Parameters: +// pMod pointer to the 160-bit modulus +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsPRNGSetModulus, (const IppsBigNumState* pMod, IppsPRNGState* pCtx)) +{ + /* test PRNG context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RAND_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test modulus */ + IPP_BAD_PTR1_RET(pMod); + IPP_BADARG_RET(!BN_VALID_ID(pMod), ippStsContextMatchErr); + IPP_BADARG_RET(160 != BITSIZE_BNU(BN_NUMBER(pMod),BN_SIZE(pMod)), ippStsBadArgErr); + + ZEXPAND_COPY_BNU(RAND_Q(pCtx), (int)(sizeof(RAND_Q(pCtx))/sizeof(BNU_CHUNK_T)), BN_NUMBER(pMod), BN_SIZE(pMod)); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpprngsetseed.c b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetseed.c new file mode 100644 index 000000000..9801353d0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpprngsetseed.c @@ -0,0 +1,72 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// PRNG Functions +// +// Contents: +// ippsPRNGSetSeed() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprng.h" + +/*F* +// Name: ippsPRNGSetSeed +// +// Purpose: Sets the initial state with the SEED value +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pCtx +// NULL == pSeed +// +// ippStsContextMatchErr illegal pCtx->idCtx +// illegal pSeed->idCtx +// +// ippStsNoErr no error +// +// Parameters: +// pSeed pointer to the SEED +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsPRNGSetSeed, (const IppsBigNumState* pSeed, IppsPRNGState* pCtx)) +{ + /* test PRNG context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!RAND_VALID_ID(pCtx), ippStsContextMatchErr); + + /* test seed */ + IPP_BAD_PTR1_RET(pSeed); + IPP_BADARG_RET(!BN_VALID_ID(pSeed), ippStsContextMatchErr); + + { + cpSize argSize = BITS_BNU_CHUNK( RAND_SEEDBITS(pCtx) ); + BNU_CHUNK_T mask = MASK_BNU_CHUNK(RAND_SEEDBITS(pCtx)); + cpSize size = IPP_MIN(BN_SIZE(pSeed), argSize); + + ZEXPAND_COPY_BNU(RAND_XKEY(pCtx), (cpSize)(sizeof(RAND_XKEY(pCtx))/sizeof(BNU_CHUNK_T)), BN_NUMBER(pSeed), size); + RAND_XKEY(pCtx)[argSize-1] &= mask; + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprij.h b/plugin/ippcp/library/src/sources/ippcp/pcprij.h new file mode 100644 index 000000000..d7034f185 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprij.h @@ -0,0 +1,286 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions and +// Internal Rijndael based Encrypt/Decrypt Function Prototypes +// +// +*/ + +#if !defined(_PCP_RIJ_H) +#define _PCP_RIJ_H + +#include "pcpaesnoise.h" + +/* +// The GF(256) modular polynomial and elements +*/ +#define WPOLY 0x011B +#define BPOLY 0x1B + +/* +// Make WORD using 4 arbitrary bytes +*/ +#define BYTES_TO_WORD(b0,b1,b2,b3) ( ( ((Ipp32u)((Ipp8u)(b3))) <<24 ) \ + |( ((Ipp32u)((Ipp8u)(b2))) <<16 ) \ + |( ((Ipp32u)((Ipp8u)(b1))) << 8 ) \ + |( ((Ipp32u)((Ipp8u)(b0))) ) ) +/* +// Make WORD setting byte in specified position +*/ +#define BYTE0_TO_WORD(b) BYTES_TO_WORD((b), 0, 0, 0) +#define BYTE1_TO_WORD(b) BYTES_TO_WORD( 0, (b), 0, 0) +#define BYTE2_TO_WORD(b) BYTES_TO_WORD( 0, 0, (b), 0) +#define BYTE3_TO_WORD(b) BYTES_TO_WORD( 0, 0, 0, (b)) + +/* +// Extract byte from specified position n. +// Sure, n=0,1,2 or 3 only +*/ +#define EBYTE(w,n) ((Ipp8u)((w) >> (8 * (n)))) + +/* alignment */ +#define RIJ_ALIGNMENT (16) +/* alignment in words */ +#define RIJ_ALIGNMENT_WORD (16/4) +/* Assuming word is 4 bytes in rij calculations */ +#define RIJ_BYTES_IN_WORD (4) + +#define MBS_RIJ128 (128/8) /* message block size (bytes) */ +#define MBS_RIJ192 (192/8) +#define MBS_RIJ256 (256/8) + +#define SR (4) /* number of rows in STATE data */ + +#define NB(msgBlks) ((msgBlks)/32) /* message block size (words) */ + /* 4-word for 128-bits data block */ + /* 6-word for 192-bits data block */ + /* 8-word for 256-bits data block */ + +#define NK(keybits) ((keybits)/32) /* key length (words): */ +#define NK128 NK(ippRijndaelKey128) /* 4-word for 128-bits security key */ +#define NK192 NK(ippRijndaelKey192) /* 6-word for 192-bits security key */ +#define NK256 NK(ippRijndaelKey256) /* 8-word for 256-bits security key */ + +#define NR128_128 (10) /* number of rounds data: 128 bits key: 128 bits are used */ +#define NR128_192 (12) /* number of rounds data: 128 bits key: 192 bits are used */ +#define NR128_256 (14) /* number of rounds data: 128 bits key: 256 bits are used */ +#define NR192_128 (12) /* number of rounds data: 192 bits key: 128 bits are used */ +#define NR192_192 (12) /* number of rounds data: 192 bits key: 192 bits are used */ +#define NR192_256 (14) /* number of rounds data: 192 bits key: 256 bits are used */ +#define NR256_128 (14) /* number of rounds data: 256 bits key: 128 bits are used */ +#define NR256_192 (14) /* number of rounds data: 256 bits key: 192 bits are used */ +#define NR256_256 (14) /* number of rounds data: 256 bits key: 256 bits are used */ + +#define NSK128_256 ((NR128_256+1)*NK128) /* max number of scheduled keys for 128-bit data (256-bit key) (in words) */ +#define NSK192_256 ((NR192_256+1)*NK192) /* max number of scheduled keys for 192-bit data (256-bit key) (in words) */ +#define NSK256_256 ((NR256_256+1)*NK256) /* max number of scheduled keys for 256-bit data (256-bit key) (in words) */ + +/* +// Rijndael's spec +// +// Rijndael128, Rijndael192 and Rijndael256 +// reserve space for maximum number of expanded keys +*/ +IPP_OWN_FUNPTR (void, RijnCipher, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTbl)) + +struct _cpRijndael128 { + Ipp32u idCtx; /* Rijndael spec identifier */ + int nk; /* security key length (words) */ + int nb; /* data block size (words) */ + int nr; /* number of rounds */ + RijnCipher encoder; /* encoder/decoder */ + RijnCipher decoder; /* entry point */ + Ipp32u* pEncTbl; /* expanded S-boxes for */ + Ipp32u* pDecTbl; /* encryption and decryption */ + Ipp8u* pEncKeys; /* pointer to array of keys for encryption */ + Ipp8u* pDecKeys; /* pointer to array of keys for decryption */ + Ipp32u aesNI; /* AES instruction available */ + Ipp32u safeInit; /* SafeInit performed */ + Ipp32u keys[2*NSK128_256 + RIJ_ALIGNMENT_WORD]; /* array of keys for encryption/decryption */ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + cpAESNoiseParams noiseParams; +#endif +}; + +struct _cpRijndael192 { + Ipp32u idCtx; /* Rijndael spec identifier */ + int nk; /* security key length (words) */ + int nb; /* data block size (words) */ + int nr; /* number of rounds */ + RijnCipher encoder; /* encoder/decoder */ + RijnCipher decoder; /* entry point */ + Ipp32u* pEncTbl; /* expanded S-boxes for */ + Ipp32u* pDecTbl; /* encryption and decryption */ + Ipp8u* pEncKeys; /* pointer to array of keys for encryption */ + Ipp8u* pDecKeys; /* pointer to array of keys for decryption */ + Ipp32u aesNI; /* AES instruction available */ + Ipp32u safeInit; /* SafeInit performed */ + Ipp32u keys[2*NSK192_256 + RIJ_ALIGNMENT_WORD]; /* array of keys for encryption/decryption */ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + cpAESNoiseParams noiseParams; +#endif +}; + + struct _cpRijndael256 { + Ipp32u idCtx; /* Rijndael spec identifier */ + int nk; /* security key length (words) */ + int nb; /* data block size (words) */ + int nr; /* number of rounds */ + RijnCipher encoder; /* encoder/decoder */ + RijnCipher decoder; /* entry point */ + Ipp32u* pEncTbl; /* expanded S-boxes for */ + Ipp32u* pDecTbl; /* encryption and decryption */ + Ipp8u* pEncKeys; /* pointer array of keys for encryption */ + Ipp8u* pDecKeys; /* pointer array of keys for decryprion */ + Ipp32u aesNI; /* AES instruction available */ + Ipp32u safeInit; /* SafeInit performed */ + Ipp32u keys[2*NSK256_256 + RIJ_ALIGNMENT_WORD]; /* array of keys for encryption/decryption */ +#if (_AES_PROB_NOISE == _FEATURE_ON_) + cpAESNoiseParams noiseParams; +#endif +}; + +#define AES_MB_MAX_KERNEL_SIZE (16) /* max number of buffers in multi buffer */ +#define CFB16_BLOCK_SIZE (16) /* CFB mode block size for multi buffer */ + +/* +// Useful macros +*/ +#define RIJ_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxRijndael ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define RIJ_RESET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxRijndael) +#define RIJ_NB(ctx) ((ctx)->nb) +#define RIJ_NK(ctx) ((ctx)->nk) +#define RIJ_NR(ctx) ((ctx)->nr) +#define RIJ_ENCODER(ctx) ((ctx)->encoder) +#define RIJ_DECODER(ctx) ((ctx)->decoder) +#define RIJ_ENC_SBOX(ctx) ((ctx)->pEncTbl) +#define RIJ_DEC_SBOX(ctx) ((ctx)->pDecTbl) +#define RIJ_EKEYS(ctx) ((ctx)->pEncKeys) +#define RIJ_DKEYS(ctx) ((ctx)->pDecKeys) +#define RIJ_AESNI(ctx) ((ctx)->aesNI) +#define RIJ_SAFE_INIT(ctx) ((ctx)->safeInit) +#define RIJ_KEYS_BUFFER(ctx) ((ctx)->keys) + +#if (_AES_PROB_NOISE == _FEATURE_ON_) +#define RIJ_NOISE_PARAMS(ctx) ((ctx)->noiseParams) +#endif + +#define VALID_RIJ_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxRijndael) + +/* +// Internal functions +*/ +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPOSITE_GF_) +#define SafeEncrypt_RIJ128 OWNAPI(SafeEncrypt_RIJ128) + IPP_OWN_DECL (void, SafeEncrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTbl)) +#define SafeDecrypt_RIJ128 OWNAPI(SafeDecrypt_RIJ128) + IPP_OWN_DECL (void, SafeDecrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTbl)) +#endif + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) +#define Safe2Encrypt_RIJ128 OWNAPI(Safe2Encrypt_RIJ128) + IPP_OWN_DECL (void, Safe2Encrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTbl)) +#define Safe2Decrypt_RIJ128 OWNAPI(Safe2Decrypt_RIJ128) + IPP_OWN_DECL (void, Safe2Decrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTbl)) +#endif + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) +#define Encrypt_RIJ128_AES_NI OWNAPI(Encrypt_RIJ128_AES_NI) + IPP_OWN_DECL (void, Encrypt_RIJ128_AES_NI, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTbl)) +#define EncryptECB_RIJ128pipe_AES_NI OWNAPI(EncryptECB_RIJ128pipe_AES_NI) + IPP_OWN_DECL (void, EncryptECB_RIJ128pipe_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len)) +#define EncryptCBC_RIJ128_AES_NI OWNAPI(EncryptCBC_RIJ128_AES_NI) + IPP_OWN_DECL (void, EncryptCBC_RIJ128_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, const Ipp8u* pIV)) +#define EncryptCTR_RIJ128pipe_AES_NI OWNAPI(EncryptCTR_RIJ128pipe_AES_NI) + IPP_OWN_DECL (void, EncryptCTR_RIJ128pipe_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, Ipp8u* pCtrValue, const Ipp8u* pCtrBitMask)) +#define EncryptStreamCTR32_AES_NI OWNAPI(EncryptStreamCTR32_AES_NI) + IPP_OWN_DECL (void, EncryptStreamCTR32_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, Ipp8u* pCtrValue)) + +#define EncryptCFB_RIJ128_AES_NI OWNAPI(EncryptCFB_RIJ128_AES_NI) + IPP_OWN_DECL (void, EncryptCFB_RIJ128_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, int cfbBlkSize, const Ipp8u* pIV)) +#define EncryptCFB32_RIJ128_AES_NI OWNAPI(EncryptCFB32_RIJ128_AES_NI) + IPP_OWN_DECL (void, EncryptCFB32_RIJ128_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, int cfbBlkSize, const Ipp8u* pIV)) +#define EncryptCFB128_RIJ128_AES_NI OWNAPI(EncryptCFB128_RIJ128_AES_NI) + IPP_OWN_DECL (void, EncryptCFB128_RIJ128_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, const Ipp8u* pIV)) +#define EncryptOFB_RIJ128_AES_NI OWNAPI(EncryptOFB_RIJ128_AES_NI) + IPP_OWN_DECL (void, EncryptOFB_RIJ128_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, int ofbBlkSize, Ipp8u* pIV)) +#define EncryptOFB128_RIJ128_AES_NI OWNAPI(EncryptOFB128_RIJ128_AES_NI) + IPP_OWN_DECL (void, EncryptOFB128_RIJ128_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, Ipp8u* pIV)) + +#define Decrypt_RIJ128_AES_NI OWNAPI(Decrypt_RIJ128_AES_NI) + IPP_OWN_DECL (void, Decrypt_RIJ128_AES_NI, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTbl)) +#define DecryptECB_RIJ128pipe_AES_NI OWNAPI(DecryptECB_RIJ128pipe_AES_NI) + IPP_OWN_DECL (void, DecryptECB_RIJ128pipe_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len)) +#define DecryptCBC_RIJ128pipe_AES_NI OWNAPI(DecryptCBC_RIJ128pipe_AES_NI) + IPP_OWN_DECL (void, DecryptCBC_RIJ128pipe_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, const Ipp8u* pIV)) +#define DecryptCFB_RIJ128pipe_AES_NI OWNAPI(DecryptCFB_RIJ128pipe_AES_NI) + IPP_OWN_DECL (void, DecryptCFB_RIJ128pipe_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int cfbBlocks, int cfbBlkSize, const Ipp8u* pIV)) +#define DecryptCFB32_RIJ128pipe_AES_NI OWNAPI(DecryptCFB32_RIJ128pipe_AES_NI) + IPP_OWN_DECL (void, DecryptCFB32_RIJ128pipe_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int cfbBlocks, int cfbBlkSize, const Ipp8u* pIV)) +#define DecryptCFB128_RIJ128pipe_AES_NI OWNAPI(DecryptCFB128_RIJ128pipe_AES_NI) + IPP_OWN_DECL (void, DecryptCFB128_RIJ128pipe_AES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, const Ipp8u* pIV)) + +#define cpExpandAesKey_NI OWNAPI(cpExpandAesKey_NI) + IPP_OWN_DECL (void, cpExpandAesKey_NI, (const Ipp8u* pSecret, IppsAESSpec* pCtx)) + +#define cpAESEncryptXTS_AES_NI OWNAPI(cpAESEncryptXTS_AES_NI) + IPP_OWN_DECL (void, cpAESEncryptXTS_AES_NI, (Ipp8u* outBlk, const Ipp8u* inpBlk, int nBlks, const Ipp8u* pRKey, int nr, Ipp8u* pTweak)) +#define cpAESDecryptXTS_AES_NI OWNAPI(cpAESDecryptXTS_AES_NI) + IPP_OWN_DECL (void, cpAESDecryptXTS_AES_NI, (Ipp8u* outBlk, const Ipp8u* inpBlk, int nBlks, const Ipp8u* pRKey, int nr, Ipp8u* pTweak)) + +#if (_IPP32E>=_IPP32E_K1) +#define cpAESEncryptXTS_VAES OWNAPI(cpAESEncryptXTS_VAES) + IPP_OWN_DECL (void, cpAESEncryptXTS_VAES, (Ipp8u* outBlk, const Ipp8u* inpBlk, int nBlks, const Ipp8u* pRKey, int nr, Ipp8u* pTweak)) +#define cpAESDecryptXTS_VAES OWNAPI(cpAESDecryptXTS_VAES) + IPP_OWN_DECL (void, cpAESDecryptXTS_VAES, (Ipp8u* outBlk, const Ipp8u* inpBlk, int nBlks, const Ipp8u* pRKey, int nr, Ipp8u* pTweak)) + +#define EncryptECB_RIJ128pipe_VAES_NI OWNAPI(EncryptECB_RIJ128pipe_VAES_NI) + IPP_OWN_DECL (void, EncryptECB_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsAESSpec* pCtx)) +#define EncryptCTR_RIJ128pipe_VAES_NI OWNAPI(EncryptCTR_RIJ128pipe_VAES_NI) + IPP_OWN_DECL (void, EncryptCTR_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, Ipp8u* pCtrValue, const Ipp8u* pCtrBitMask)) +#define EncryptStreamCTR32_VAES_NI OWNAPI(EncryptStreamCTR32_VAES_NI) + IPP_OWN_DECL (void, EncryptStreamCTR32_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int nr, const Ipp8u* pKeys, int len, Ipp8u* pCtrValue)) + +#define DecryptECB_RIJ128pipe_VAES_NI OWNAPI(DecryptECB_RIJ128pipe_VAES_NI) + IPP_OWN_DECL (void, DecryptECB_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsAESSpec* pCtx)) +#define DecryptCBC_RIJ128pipe_VAES_NI OWNAPI(DecryptCBC_RIJ128pipe_VAES_NI) + IPP_OWN_DECL (void, DecryptCBC_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsAESSpec* pCtx, const Ipp8u* pIV)) + +#define DecryptCFB_RIJ128pipe_VAES_NI OWNAPI(DecryptCFB_RIJ128pipe_VAES_NI) + IPP_OWN_DECL (void, DecryptCFB_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, const IppsAESSpec* pCtx, const Ipp8u* pIV)) +#define DecryptCFB64_RIJ128pipe_VAES_NI OWNAPI(DecryptCFB64_RIJ128pipe_VAES_NI) + IPP_OWN_DECL (void, DecryptCFB64_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsAESSpec* pCtx, const Ipp8u* pIV)) +#define DecryptCFB128_RIJ128pipe_VAES_NI OWNAPI(DecryptCFB128_RIJ128pipe_VAES_NI) + IPP_OWN_DECL (void, DecryptCFB128_RIJ128pipe_VAES_NI, (const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsAESSpec* pCtx, const Ipp8u* pIV)) +#endif /* _IPP32E>=_IPP32E_K1 */ + +#endif /* _IPP>=_IPP_P8 || _IPP32E>=_IPP32E_Y8 */ + +#define ExpandRijndaelKey OWNAPI(ExpandRijndaelKey) + IPP_OWN_DECL (void, ExpandRijndaelKey, (const Ipp8u* pKey, int NK, int NB, int NR, int nKeys, Ipp8u* pEncKeys, Ipp8u* pDecKeys)) + +#if(_IPP>_IPP_PX || _IPP32E>_IPP32E_PX) +#define Touch_SubsDword_8uT OWNAPI(Touch_SubsDword_8uT) + IPP_OWN_DECL (Ipp32u, Touch_SubsDword_8uT, (Ipp32u inp, const Ipp8u* pTbl, int tblLen)) +#endif + +#endif /* _PCP_RIJ_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprij128safe.c b/plugin/ippcp/library/src/sources/ippcp/pcprij128safe.c new file mode 100644 index 000000000..88015d0e3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprij128safe.c @@ -0,0 +1,243 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Safe Rijndael Encrypt, Decrypt +// (It's the special free from Sbox/tables implementation) +// +*/ + +#include "owndefs.h" +#include "owncp.h" + +#if ((_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8)) /* no pshufb instruction */ + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPOSITE_GF_) +#include "pcprij128safe.h" + +#if defined _PCP_RIJ_SAFE_OLD +/* +// old version +*/ + +IPP_OWN_DEFN (Ipp8u, TransformByte, (Ipp8u x, const Ipp8u Transformation[])) +{ + Ipp32u y = 0; + + Ipp32u testBit = 0x01; + int bit; + for(bit=0; bit<8; bit++) { + Ipp32u mask = (x & testBit)? 0xFF : 0; + y ^= Transformation[bit] & mask; + testBit <<= 1; + } + + return (Ipp8u)y; +} + +static Ipp8u Native2CompositeTransformation[] = {0x01,0x2E,0x49,0x43,0x35,0xD0,0x3D,0xE9}; + +IPP_OWN_DEFN (void, TransformNative2Composite, (Ipp8u out[], const Ipp8u inp[])) +{ + int n; + for(n=0; n<16; n++) + out[n] = TransformByte(inp[n], Native2CompositeTransformation); +} + +static Ipp8u Composite2NativeTransformation[] = {0x01,0x5C,0xE0,0x50,0x1F,0xEE,0x55,0x6A}; + +IPP_OWN_DEFN (void, TransformComposite2Native, (Ipp8u out[], const Ipp8u inp[])) +{ + int n; + for(n=0; n<16; n++) + out[n] = TransformByte(inp[n], Composite2NativeTransformation); +} + +IPP_OWN_DEFN (void, AddRoundKey, (Ipp8u out[], const Ipp8u inp[], const Ipp8u pKey[])) +{ + int n; + for(n=0; n<16; n++) + out[n] = (Ipp8u)( inp[n] ^ pKey[n] ); +} + +#define MASK_BIT(x,n) ((Ipp32s)((x)<<(31-n)) >>31) +#define GF16mulX(x) ( ((x)<<1) ^ ( MASK_BIT(x,3) & 0x13) ) + +static Ipp8u GF16mul(Ipp8u a, Ipp8u b) +{ + Ipp32u a0 = a; + Ipp32u a1 = GF16mulX(a0); + Ipp32u a2 = GF16mulX(a1); + Ipp32u a4 = GF16mulX(a2); + + Ipp32u r = (a0 & MASK_BIT(b,0)) + ^(a1 & MASK_BIT(b,1)) + ^(a2 & MASK_BIT(b,2)) + ^(a4 & MASK_BIT(b,3)); + + return (Ipp8u)r; +} + +static Ipp8u GF16_sqr[] = {0x00,0x01,0x04,0x05,0x03,0x02,0x07,0x06, + 0x0C,0x0D,0x08,0x09,0x0F,0x0E,0x0B,0x0A}; +static Ipp8u GF16_sqr1[]= {0x00,0x09,0x02,0x0B,0x08,0x01,0x0A,0x03, + 0x06,0x0F,0x04,0x0D,0x0E,0x07,0x0C,0x05}; +static Ipp8u GF16_inv[] = {0x00,0x01,0x09,0x0E,0x0D,0x0B,0x07,0x06, + 0x0F,0x02,0x0C,0x05,0x0A,0x04,0x03,0x08}; +IPP_OWN_DEFN (Ipp8u, InverseComposite, (Ipp8u x)) +{ + /* split x = {bc} => b*t + c */ + int b = (x>>4) & 0x0F; + int c = x & 0x0F; + + int D = GF16mul((Ipp8u)b, (Ipp8u)c) + ^GF16_sqr[c] + ^GF16_sqr1[b]; + + D = GF16_inv[D]; + + c = GF16mul((Ipp8u)(b^c), (Ipp8u)D); + b = GF16mul((Ipp8u)b, (Ipp8u)D); + + /* merge p*t + q => {pq} = x */ + x = (Ipp8u)((b<<4) + c); + return x; +} +#endif /* _PCP_RIJ_SAFE_OLD */ + +#if !defined _PCP_RIJ_SAFE_OLD +/* +// new version +*/ + +/* GF(2^128) -> GF((2^4)^2) isomorphous transformation matrix Ipp8u Native2CompositeTransformation[] = {0x01,0x2E,0x49,0x43,0x35,0xD0,0x3D,0xE9}; + is defined in reference code, see doc for details */ +static Ipp8u Native2CompositeTransformationLO[] = { /* defived from Native2CompositeTransformation[i], i=0,1,2,3 */ + /* 0 */ 0x00, + /* 1 */ 0x01, + /* 2 */ 0x2E, + /* 3 */ 0x2E^0x01, + /* 4 */ 0x49, + /* 5 */ 0x49^0x01, + /* 6 */ 0x49^0x2E, + /* 7 */ 0x49^0x2E^0x01, + /* 8 */ 0x43, + /* 9 */ 0x43^0x01, + /* a */ 0x43^0x2E, + /* b */ 0x43^0x2E^0x01, + /* c */ 0x43^0x49, + /* d */ 0x43^0x49^0x01, + /* e */ 0x43^0x49^0x2E, + /* f */ 0x43^0x49^0x2E^0x01 +}; +static Ipp8u Native2CompositeTransformationHI[] = { /* defived from Native2CompositeTransformation[i], i=4,5,6,7 */ + /* 0 */ 0x00, + /* 1 */ 0x35, + /* 2 */ 0xD0, + /* 3 */ 0xD0^0x35, + /* 4 */ 0x3D, + /* 5 */ 0x3D^0x35, + /* 6 */ 0x3D^0xD0, + /* 7 */ 0x3D^0xD0^0x35, + /* 8 */ 0xE9, + /* 9 */ 0xE9^0x35, + /* a */ 0xE9^0xD0, + /* b */ 0xE9^0xD0^0x35, + /* c */ 0xE9^0x3D, + /* d */ 0xE9^0x3D^0x35, + /* e */ 0xE9^0x3D^0xD0, + /* f */ 0xE9^0x3D^0xD0^0x35 +}; +IPP_OWN_DEFN (void, TransformNative2Composite, (Ipp8u out[16], const Ipp8u inp[16])) +{ + Ipp8u blk_lo[16], blk_hi[16]; + ((Ipp64u*)blk_lo)[0] = ((Ipp64u*)inp)[0] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_lo)[1] = ((Ipp64u*)inp)[1] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_hi)[0] = (((Ipp64u*)inp)[0]>>4) & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_hi)[1] = (((Ipp64u*)inp)[1]>>4) & 0x0F0F0F0F0F0F0F0F; + { + int n; + for(n=0; n<16; n++) { + Ipp8u lo = Native2CompositeTransformationLO[blk_lo[n]]; + Ipp8u hi = Native2CompositeTransformationHI[blk_hi[n]]; + out[n] = lo^hi; + } + } +} + +/* GF((2^4)^2) -> GF(2^128) isomorphous transformation matrix Ipp8u Composite2NativeTransformation[] = {0x01,0x5C,0xE0,0x50,0x1F,0xEE,0x55,0x6A}; + is defined in reference code, see doc for details */ +static Ipp8u Composite2NativeTransformationLO[] = { /* defived from Composite2NativeTransformation[i], i=0,1,2,3 */ + /* 0 */ 0x00, + /* 1 */ 0x01, + /* 2 */ 0x5C, + /* 3 */ 0x5C^0x01, + /* 4 */ 0xE0, + /* 5 */ 0xE0^0x01, + /* 6 */ 0xE0^0x5C, + /* 7 */ 0xE0^0x5C^0x01, + /* 8 */ 0x50, + /* 9 */ 0x50^0x01, + /* a */ 0x50^0x5C, + /* b */ 0x50^0x5C^0x01, + /* c */ 0x50^0xE0, + /* d */ 0x50^0xE0^0x01, + /* e */ 0x50^0xE0^0x5C, + /* f */ 0x50^0xE0^0x5C^0x01 +}; +static Ipp8u Composite2NativeTransformationHI[] = {/* defived from Composite2NativeTransformation[i], i=4,5,6,7 */ + /* 0 */ 0x00, + /* 1 */ 0x1F, + /* 2 */ 0xEE, + /* 3 */ 0xEE^0x1F, + /* 4 */ 0x55, + /* 5 */ 0x55^0x1F, + /* 6 */ 0x55^0xEE, + /* 7 */ 0x55^0xEE^0x1F, + /* 8 */ 0x6A, + /* 9 */ 0x6A^0x1F, + /* a */ 0x6A^0xEE, + /* b */ 0x6A^0xEE^0x1F, + /* c */ 0x6A^0x55, + /* d */ 0x6A^0x55^0x1F, + /* e */ 0x6A^0x55^0xEE, + /* f */ 0x6A^0x55^0xEE^0x1F +}; +IPP_OWN_DEFN (void, TransformComposite2Native, (Ipp8u out[16], const Ipp8u inp[16])) +{ + Ipp8u blk_lo[16], blk_hi[16]; + ((Ipp64u*)blk_lo)[0] = ((Ipp64u*)inp)[0] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_lo)[1] = ((Ipp64u*)inp)[1] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_hi)[0] = (((Ipp64u*)inp)[0]>>4) & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_hi)[1] = (((Ipp64u*)inp)[1]>>4) & 0x0F0F0F0F0F0F0F0F; + { + int n; + for(n=0; n<16; n++) { + Ipp8u lo = Composite2NativeTransformationLO[blk_lo[n]]; + Ipp8u hi = Composite2NativeTransformationHI[blk_hi[n]]; + out[n] = lo^hi; + } + } +} +#endif /* !_PCP_RIJ_SAFE_OLD */ + +#endif /* _ALG_AES_SAFE_COMPOSITE_GF_ */ + +#endif /* (_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprij128safe.h b/plugin/ippcp/library/src/sources/ippcp/pcprij128safe.h new file mode 100644 index 000000000..d5e2d6f48 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprij128safe.h @@ -0,0 +1,94 @@ +/******************************************************************************* +* Copyright (C) 2007 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Safe Rijndael Encrypt, Decrypt +// +// +*/ + +#if !defined(_PCP_RIJ_SAFE_H) +#define _PCP_RIJ_SAFE_H + +#include "owncp.h" +#include "pcprijtables.h" +#include "pcpbnuimpl.h" +#include "pcpmask_ct.h" + +#if defined _PCP_RIJ_SAFE_OLD +/* old version */ +#define TransformByte OWNAPI(TransformByte) + IPP_OWN_DECL (Ipp8u, TransformByte, (Ipp8u x, const Ipp8u Transformation[])) +#define TransformNative2Composite OWNAPI(TransformNative2Composite) + IPP_OWN_DECL (void, TransformNative2Composite, (Ipp8u out[16], const Ipp8u inp[16])) +#define TransformComposite2Native OWNAPI(TransformComposite2Native) + IPP_OWN_DECL (void, TransformComposite2Native, (Ipp8u out[16], const Ipp8u inp[16])) +#define InverseComposite OWNAPI(InverseComposite) + IPP_OWN_DECL (Ipp8u, InverseComposite, (Ipp8u x)) +#define AddRoundKey OWNAPI(AddRoundKey) + IPP_OWN_DECL (void, AddRoundKey, (Ipp8u out[], const Ipp8u inp[], const Ipp8u pKey[])) +#endif + + +#if !defined _PCP_RIJ_SAFE_OLD +/* new version */ +#define TransformNative2Composite OWNAPI(TransformNative2Composite) + IPP_OWN_DECL (void, TransformNative2Composite, (Ipp8u out[16], const Ipp8u inp[16])) +#define TransformComposite2Native OWNAPI(TransformComposite2Native) + IPP_OWN_DECL (void, TransformComposite2Native, (Ipp8u out[16], const Ipp8u inp[16])) + +/* add round key operation */ +__INLINE void AddRoundKey(Ipp8u out[16], const Ipp8u inp[16], const Ipp8u rkey[16]) +{ + ((Ipp64u*)out)[0] = ((Ipp64u*)inp)[0] ^ ((Ipp64u*)rkey)[0]; + ((Ipp64u*)out)[1] = ((Ipp64u*)inp)[1] ^ ((Ipp64u*)rkey)[1]; +} + +/* add logs of GF(2^4) elements +// the exp table has been build matched for that implementation +*/ +__INLINE Ipp8u AddLogGF16(Ipp8u loga, Ipp8u logb) +{ + //Ipp8u s = loga+logb; + //return (s>2*14)? 15 : (s>14)? s-15 : s; + Ipp8u s = loga+logb; + Ipp8u delta = ((0xF-1)-s)>>7; + s -= delta; + s |= 0-(s>>7); + return s & (0xF); +} +#endif + +#define SELECTION_BITS ((sizeof(BNU_CHUNK_T)/sizeof(Ipp8u)) -1) + +__INLINE Ipp8u getSboxValue(Ipp8u x) +{ + BNU_CHUNK_T selection = 0; + const Ipp8u* SboxEntry = RijEncSbox; + + Ipp32u i; + for (i = 0; i>7)); +} + +__INLINE Ipp32u xtime4(Ipp32u x) +{ + Ipp32u t = (x+x) &0xFEFEFEFE; + t ^= mask4(x) & 0x1B1B1B1B; + return t; +} + +#endif /* _PCP_RIJ_SAFE2_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprij128safedec2pxca.c b/plugin/ippcp/library/src/sources/ippcp/pcprij128safedec2pxca.c new file mode 100644 index 000000000..0d56a28ff --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprij128safedec2pxca.c @@ -0,0 +1,157 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Decrypt 128-bit data block according to Rijndael +// (compact S-box based implementation) +// +// Contents: +// Safe2Decrypt_RIJ128() +// +// +*/ + +#include "owncp.h" + +#if ((_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8)) /* no pshufb instruction */ + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + +#include "pcprij128safe2.h" +#include "pcprijtables.h" + + +#include "pcpbnuimpl.h" +#define SELECTION_BITS ((sizeof(BNU_CHUNK_T)/sizeof(Ipp8u)) -1) + +#if defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) +__INLINE Ipp8u getInvSboxValue(Ipp8u x) +{ + BNU_CHUNK_T selection = 0; + const BNU_CHUNK_T* SboxEntry = (BNU_CHUNK_T*)RijDecSbox; + + BNU_CHUNK_T i_sel = x/sizeof(BNU_CHUNK_T); /* selection index */ + BNU_CHUNK_T i; + for(i=0; i>= (x & SELECTION_BITS)*8; + return (Ipp8u)(selection & 0xFF); +} + +#else +#include "pcpmask_ct.h" +__INLINE Ipp8u getInvSboxValue(Ipp8u x) +{ + BNU_CHUNK_T selection = 0; + const BNU_CHUNK_T* SboxEntry = (BNU_CHUNK_T*)RijDecSbox; + + Ipp32u _x = x/sizeof(BNU_CHUNK_T); + Ipp32u i; + for(i=0; i>= (x & SELECTION_BITS)*8; + return (Ipp8u)(selection & 0xFF); +} +#endif + +__INLINE void invSubBytes(Ipp8u state[]) +{ + int i; + for(i=0;i<16;i++) + state[i] = getInvSboxValue(state[i]); +} + +__INLINE void invShiftRows(Ipp32u* state) +{ + state[1] = ROR32(state[1], 24); + state[2] = ROR32(state[2], 16); + state[3] = ROR32(state[3], 8); +} + +__INLINE void invMixColumns(Ipp32u* state) +{ + Ipp32u y0 = state[1] ^ state[2] ^ state[3]; + Ipp32u y1 = state[0] ^ state[2] ^ state[3]; + Ipp32u y2 = state[0] ^ state[1] ^ state[3]; + Ipp32u y3 = state[0] ^ state[1] ^ state[2]; + Ipp32u t02, t13, t0123; + + state[0] = xtime4(state[0]); + state[1] = xtime4(state[1]); + state[2] = xtime4(state[2]); + state[3] = xtime4(state[3]); + + y0 ^= state[0] ^ state[1]; + y1 ^= state[1] ^ state[2]; + y2 ^= state[2] ^ state[3]; + y3 ^= state[3] ^ state[0]; + + t02 = state[0] ^ state[2]; + t13 = state[1] ^ state[3]; + t02 = xtime4(t02); + t13 = xtime4(t13); + + t0123 = t02^t13; + t0123 = xtime4(t0123); + + state[0] = y0 ^t02 ^t0123; + state[1] = y1 ^t13 ^t0123; + state[2] = y2 ^t02 ^t0123; + state[3] = y3 ^t13 ^t0123; +} + + +IPP_OWN_DEFN (void, Safe2Decrypt_RIJ128, (const Ipp8u* in, Ipp8u* out, int Nr, const Ipp8u* RoundKey, const void* sbox)) +{ + Ipp32u state[4]; + + int round=0; + + IPP_UNREFERENCED_PARAMETER(sbox); + + // copy input to the state array + TRANSPOSE((Ipp8u*)state, in); + + // add the round key to the state before starting the rounds. + XorRoundKey((Ipp32u*)state, (Ipp32u*)(RoundKey+Nr*16)); + + // there will be Nr rounds + for(round=Nr-1;round>0;round--) { + invShiftRows(state); + invSubBytes((Ipp8u*)state); + XorRoundKey(state,(Ipp32u*)(RoundKey+round*16)); + invMixColumns(state); + } + + // last round + invShiftRows(state); + invSubBytes((Ipp8u*)state); + XorRoundKey(state,(Ipp32u*)(RoundKey+0*16)); + + // copy from the state to output + TRANSPOSE(out, (Ipp8u*)state); +} +#endif /* _ALG_AES_SAFE_COMPACT_SBOX_ */ + +#endif /* (_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprij128safedecpxca.c b/plugin/ippcp/library/src/sources/ippcp/pcprij128safedecpxca.c new file mode 100644 index 000000000..e4e034df6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprij128safedecpxca.c @@ -0,0 +1,411 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Decrypt 128-bit data block according to Rijndael +// (It's the special free from Sbox/tables implementation) +// +// Contents: +// SafeDecrypt_RIJ128() +// +// +*/ + +#include "owncp.h" + +#if ((_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8)) /* no pshufb instruction */ + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPOSITE_GF_) + +#include "pcprij.h" +#include "pcprij128safe.h" + +#if defined _PCP_RIJ_SAFE_OLD +/* +// old version +*/ + +static Ipp8u AffineMatrix[] = {0x50,0x36,0x15,0x82,0x01,0x34,0x40,0x3E}; +static void InvSubByte(Ipp8u inp_out[]) +{ + Ipp8u AffineCnt = 0x48; + int n; + for(n=0; n<16; n++) { + Ipp8u x = inp_out[n]; + x = TransformByte(x, AffineMatrix); + x^= AffineCnt; + x = InverseComposite(x); + inp_out[n] = x; + } +} + +static int ShiftRowsInx[] = {0,13,10,7,4,1,14,11,8,5,2,15,12,9,6,3}; +static void InvShiftRows(Ipp8u inp_out[]) +{ + Ipp8u tmp[16]; + + int n; + for(n=0; n<16; n++) + tmp[n] = inp_out[n]; + + for(n=0; n<16; n++) { + int idx = ShiftRowsInx[n]; + inp_out[n] = tmp[idx]; + } +} + +static Ipp8u GF16mul_4_2x[] = {0x00,0x24,0x48,0x6C,0x83,0xA7,0xCB,0xEF, + 0x36,0x12,0x7E,0x5A,0xB5,0x91,0xFD,0xD9}; +static Ipp8u GF16mul_1_6x[] = {0x00,0x61,0xC2,0xA3,0xB4,0xD5,0x76,0x17, + 0x58,0x39,0x9A,0xFB,0xEC,0x8D,0x2E,0x4F}; + +static Ipp8u GF16mul_C_6x[] = {0x00,0x6C,0xCB,0xA7,0xB5,0xD9,0x7E,0x12, + 0x5A,0x36,0x91,0xFD,0xEF,0x83,0x24,0x48}; +static Ipp8u GF16mul_3_Ax[] = {0x00,0xA3,0x76,0xD5,0xEC,0x4F,0x9A,0x39, + 0xFB,0x58,0x8D,0x2E,0x17,0xB4,0x61,0xC2}; + +static Ipp8u GF16mul_B_0x[] = {0x00,0x0B,0x05,0x0E,0x0A,0x01,0x0F,0x04, + 0x07,0x0C,0x02,0x09,0x0D,0x06,0x08,0x03}; +static Ipp8u GF16mul_0_Bx[] = {0x00,0xB0,0x50,0xE0,0xA0,0x10,0xF0,0x40, + 0x70,0xC0,0x20,0x90,0xD0,0x60,0x80,0x30}; + +static Ipp8u GF16mul_2_4x[] = {0x00,0x42,0x84,0xC6,0x38,0x7A,0xBC,0xFE, + 0x63,0x21,0xE7,0xA5,0x5B,0x19,0xDF,0x9D}; +static Ipp8u GF16mul_2_6x[] = {0x00,0x62,0xC4,0xA6,0xB8,0xDA,0x7C,0x1E, + 0x53,0x31,0x97,0xF5,0xEB,0x89,0x2F,0x4D}; +static void InvMixColumn(Ipp8u inp_out[]) +{ + + Ipp8u out[16]; + Ipp32u* pInp32 = (Ipp32u*)inp_out; + + int n; + + for(n=0; n<16; n++) { + int xL = inp_out[n] & 0xF; + int xH = (inp_out[n]>>4) & 0xF; + out[n] = (Ipp8u)( GF16mul_4_2x[xL] ^ GF16mul_1_6x[xH] ); + } + + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + for(n=0; n<16; n++) { + int xL = inp_out[n] & 0xF; + int xH = (inp_out[n]>>4) & 0xF; + out[n]^= (Ipp8u)( GF16mul_C_6x[xL] ^ GF16mul_3_Ax[xH] ); + } + + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + for(n=0; n<16; n++) { + int xL = inp_out[n] & 0xF; + int xH = (inp_out[n]>>4) & 0xF; + out[n]^= (Ipp8u)( GF16mul_B_0x[xL] ^ GF16mul_0_Bx[xH] ); + } + + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + for(n=0; n<16; n++) { + int xL = inp_out[n] & 0xF; + int xH = (inp_out[n]>>4) & 0xF; + out[n]^= (Ipp8u)( GF16mul_2_4x[xL] ^ GF16mul_2_6x[xH] ); + } + + for(n=0; n<16; n++) + inp_out[n] = out[n]; +} + +/* define number of column in the state */ +#define SC NB(128) +#define STATE_SIZE (sizeof(Ipp32u)*SC) + +IPP_OWN_DEFN (void, SafeDecrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTables)) +{ + int r; + + Ipp8u state[STATE_SIZE]; /* state */ + + IPP_UNREFERENCED_PARAMETER(pTables); + + /* native => composite */ + TransformNative2Composite(state, pInpBlk); + + pKeys += nr*STATE_SIZE; + + /* input whitening */ + AddRoundKey(state, state, pKeys); + pKeys -= STATE_SIZE; + + /* regular (nr-1) rounds */ + for(r=1; r native */ + TransformComposite2Native(pOutBlk, state); +} +#endif /* _PCP_RIJ_SAFE_OLD */ + +#if !defined _PCP_RIJ_SAFE_OLD +/* +// new version +*/ + +/* +// SubByte operation in composite GF((2^4)^2) +// sdetails are in the doc. +// +// multiplication in basic GF(2^4) performs by log-and-exp sequence +*/ +static Ipp8u GF16_sqr1[] = {0x00,0x09,0x02,0x0B,0x08,0x01,0x0A,0x03, /* (x^2)*{9} */ + 0x06,0x0F,0x04,0x0D,0x0E,0x07,0x0C,0x05}; + +static Ipp8u GF16_log[] = {0xC0,0x00,0x01,0x04,0x02,0x08,0x05,0x0A, /* log element x */ + 0x03,0x0E,0x09,0x07,0x06,0x0D,0x0B,0x0C}; +static Ipp8u GF16_invlog[] = {0xC0,0x00,0x0E,0x0B,0x0D,0x07,0x0A,0x05, /* log of multiple inversion element x^-1 */ + 0x0C,0x01,0x06,0x08,0x09,0x02,0x04,0x03}; +static Ipp8u GF16_exp[] = {0x01,0x02,0x04,0x08,0x03,0x06,0x0C,0x0B, + 0x05,0x0A,0x07,0x0E,0x0F,0x0D,0x09,0x00}; /* exp[15]= 0!!! */ + +/* affine transformation matrix Ipp8u AffineMatrix[] = {0x50,0x36,0x15,0x82,0x01,0x34,0x40,0x3E}; + is defined in reference code, see doc for details */ +static Ipp8u InvAffineMatrixLO[] = { /* defived from AffineMatrix[i], i=0,1,2,3 */ + /* 0 */ 0x00, + /* 1 */ 0x50, + /* 2 */ 0x36, + /* 3 */ 0x36^0x50, + /* 4 */ 0x15, + /* 5 */ 0x15^0x50, + /* 6 */ 0x15^0x36, + /* 7 */ 0x15^0x36^0x50, + /* 8 */ 0x82, + /* 9 */ 0x82^0x50, + /* a */ 0x82^0x36, + /* b */ 0x82^0x36^0x50, + /* c */ 0x82^0x15, + /* d */ 0x82^0x15^0x50, + /* e */ 0x82^0x15^0x36, + /* f */ 0x82^0x15^0x36^0x50 +}; +static Ipp8u InvAffineMatrixHI[] = { /* defived from AffineMatrix[i], i=4,5,6,7 */ + /* 0 */ 0x00, + /* 1 */ 0x01, + /* 2 */ 0x34, + /* 3 */ 0x34^0x01, + /* 4 */ 0x40, + /* 5 */ 0x40^0x01, + /* 6 */ 0x40^0x34, + /* 7 */ 0x40^0x34^0x01, + /* 8 */ 0x3E, + /* 9 */ 0x3E^0x01, + /* a */ 0x3E^0x34, + /* b */ 0x3E^0x34^0x01, + /* c */ 0x3E^0x40, + /* d */ 0x3E^0x40^0x01, + /* e */ 0x3E^0x40^0x34, + /* f */ 0x3E^0x40^0x34^0x01 +}; + +static void InvSubByte(Ipp8u blk[16]) +{ + Ipp8u blk_c[16], blk_b[16]; + ((Ipp64u*)blk_c)[0] = ((Ipp64u*)blk)[0] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_c)[1] = ((Ipp64u*)blk)[1] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_b)[0] = (((Ipp64u*)blk)[0]>>4) & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_b)[1] = (((Ipp64u*)blk)[1]>>4) & 0x0F0F0F0F0F0F0F0F; + + { + const Ipp8u affineCnt = 0x48; /* /* value of H(0x05) */ + int n; + for(n=0; n<16; n++) { + Ipp8u c = blk_c[n]; + Ipp8u b = blk_b[n]; + + /* affine transformation y = (AT)*(x) + affineCnt */ + Ipp8u t = InvAffineMatrixLO[c] ^ InvAffineMatrixHI[b] ^ affineCnt; + c = t & 0xF; + b = t >> 4; + + /* {c+b*t} element inversion => {c+b*t} */ + { + Ipp8u log_c = GF16_log[c]; + Ipp8u log_b = GF16_log[b]; + Ipp8u log_cb = GF16_log[c^b]; + + Ipp8u d = GF16_sqr1[b]; + Ipp8u t = AddLogGF16(log_c, log_cb); + d ^= GF16_exp[t]; + + d = GF16_invlog[d]; + c = AddLogGF16(log_cb, d); + b = AddLogGF16(log_b, d); + c = GF16_exp[c]; + b = GF16_exp[b]; + } + + blk[n] = b<<4 | c; + } + } +} + +/* inplace ShiftRows operation */ +/* int ShiftRowsInx[] = {0,13,10,7, 4,1,14,11, 8,5,2,15, 12,9,6,3}; */ +static void InvShiftRows(Ipp8u blk[16]) +{ + Ipp8u x = blk[13]; + blk[13]= blk[9]; + blk[9] = blk[5]; + blk[5] = blk[1]; + blk[1] = x; + + x = blk[10]; + blk[10]= blk[2]; + blk[2] = x; + x = blk[14]; + blk[14]= blk[6]; + blk[6] = x; + + x = blk[3]; + blk[3] = blk[7]; + blk[7] = blk[11]; + blk[11]= blk[15]; + blk[15]= x; +} + +static Ipp8u GF16mul_4_2x[] = {0x00,0x24,0x48,0x6C,0x83,0xA7,0xCB,0xEF, + 0x36,0x12,0x7E,0x5A,0xB5,0x91,0xFD,0xD9}; +static Ipp8u GF16mul_1_6x[] = {0x00,0x61,0xC2,0xA3,0xB4,0xD5,0x76,0x17, + 0x58,0x39,0x9A,0xFB,0xEC,0x8D,0x2E,0x4F}; + +static Ipp8u GF16mul_C_6x[] = {0x00,0x6C,0xCB,0xA7,0xB5,0xD9,0x7E,0x12, + 0x5A,0x36,0x91,0xFD,0xEF,0x83,0x24,0x48}; +static Ipp8u GF16mul_3_Ax[] = {0x00,0xA3,0x76,0xD5,0xEC,0x4F,0x9A,0x39, + 0xFB,0x58,0x8D,0x2E,0x17,0xB4,0x61,0xC2}; + +static Ipp8u GF16mul_B_0x[] = {0x00,0x0B,0x05,0x0E,0x0A,0x01,0x0F,0x04, + 0x07,0x0C,0x02,0x09,0x0D,0x06,0x08,0x03}; +static Ipp8u GF16mul_0_Bx[] = {0x00,0xB0,0x50,0xE0,0xA0,0x10,0xF0,0x40, + 0x70,0xC0,0x20,0x90,0xD0,0x60,0x80,0x30}; + +static Ipp8u GF16mul_2_4x[] = {0x00,0x42,0x84,0xC6,0x38,0x7A,0xBC,0xFE, + 0x63,0x21,0xE7,0xA5,0x5B,0x19,0xDF,0x9D}; +static Ipp8u GF16mul_2_6x[] = {0x00,0x62,0xC4,0xA6,0xB8,0xDA,0x7C,0x1E, + 0x53,0x31,0x97,0xF5,0xEB,0x89,0x2F,0x4D}; +static void InvMixColumn(Ipp8u blk[16]) +{ + Ipp8u out[16]; + Ipp32u* pInp32 = (Ipp32u*)blk; + + int n; + for(n=0; n<16; n++) { + int xL = blk[n] & 0xF; + int xH = (blk[n]>>4) & 0xF; + out[n] = GF16mul_4_2x[xL] ^ GF16mul_1_6x[xH]; + } + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + + for(n=0; n<16; n++) { + int xL = blk[n] & 0xF; + int xH = (blk[n]>>4) & 0xF; + out[n]^= GF16mul_C_6x[xL] ^ GF16mul_3_Ax[xH]; + } + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + + for(n=0; n<16; n++) { + int xL = blk[n] & 0xF; + int xH = (blk[n]>>4) & 0xF; + out[n]^= GF16mul_B_0x[xL] ^ GF16mul_0_Bx[xH]; + } + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + + for(n=0; n<16; n++) { + int xL = blk[n] & 0xF; + int xH = (blk[n]>>4) & 0xF; + blk[n] = out[n] ^ GF16mul_2_4x[xL] ^ GF16mul_2_6x[xH]; + } +} + +/* define number of column in the state */ +#define SC NB(128) +#define STATE_SIZE (sizeof(Ipp32u)*SC) + +IPP_OWN_DEFN (void, SafeDecrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTables)) +{ + int r; + + Ipp8u state[STATE_SIZE]; /* state */ + + IPP_UNREFERENCED_PARAMETER(pTables); + + /* native => composite */ + TransformNative2Composite(state, pInpBlk); + + pKeys += nr*STATE_SIZE; + + /* input whitening */ + AddRoundKey(state, state, pKeys); + pKeys -= STATE_SIZE; + + /* regular (nr-1) rounds */ + for(r=1; r native */ + TransformComposite2Native(pOutBlk, state); +} +#endif /* !_PCP_RIJ_SAFE_OLD */ + +#endif /* _ALG_AES_SAFE_COMPOSITE_GF_ */ + +#endif /* (_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprij128safeenc2pxca.c b/plugin/ippcp/library/src/sources/ippcp/pcprij128safeenc2pxca.c new file mode 100644 index 000000000..8e8c9e427 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprij128safeenc2pxca.c @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt 128-bit data block according to Rijndael +// (compact S-box based implementation) +// +// Contents: +// Safe2Encrypt_RIJ128() +// +// +*/ + +#include "owncp.h" + +#if ((_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8)) /* no pshufb instruction */ + +#if (_ALG_AES_SAFE_==_ALG_AES_SAFE_COMPACT_SBOX_) + +#include "pcprij128safe.h" +#include "pcprij128safe2.h" +#include "pcprijtables.h" + +__INLINE void SubBytes(Ipp8u state[]) +{ + int i; + for(i=0;i<16;i++) { + state[i] = getSboxValue(state[i]); + } +} + + +__INLINE void ShiftRows(Ipp32u* state) +{ + state[1] = ROR32(state[1], 8); + state[2] = ROR32(state[2], 16); + state[3] = ROR32(state[3], 24); +} + +// MixColumns4 function mixes the columns of the state matrix +__INLINE void MixColumns(Ipp32u* state) +{ + Ipp32u y0 = state[1] ^ state[2] ^ state[3]; + Ipp32u y1 = state[0] ^ state[2] ^ state[3]; + Ipp32u y2 = state[0] ^ state[1] ^ state[3]; + Ipp32u y3 = state[0] ^ state[1] ^ state[2]; + + state[0] = xtime4(state[0]); + state[1] = xtime4(state[1]); + state[2] = xtime4(state[2]); + state[3] = xtime4(state[3]); + + y0 ^= state[0] ^ state[1]; + y1 ^= state[1] ^ state[2]; + y2 ^= state[2] ^ state[3]; + y3 ^= state[3] ^ state[0]; + + state[0] = y0; + state[1] = y1; + state[2] = y2; + state[3] = y3; +} + +IPP_OWN_DEFN (void, Safe2Encrypt_RIJ128, (const Ipp8u* in, Ipp8u* out, int Nr, const Ipp8u* RoundKey, const void* sbox)) +{ + Ipp32u state[4]; + + int round=0; + + IPP_UNREFERENCED_PARAMETER(sbox); + + // copy input to the state array + TRANSPOSE((Ipp8u*)state, in); + + // add round key to the state before starting the rounds. + XorRoundKey(state, (Ipp32u*)(RoundKey+0*16)); + + // there will be Nr rounds + for(round=1;round>4) & 0xF ); + tmp[n] = (Ipp8u)( GF16mul_E_2x[xL] ^ GF16mul_1_Cx[xH] ); + } + + pTmp32[0] ^= ROR32(pTmp32[0], 8); + pTmp32[1] ^= ROR32(pTmp32[1], 8); + pTmp32[2] ^= ROR32(pTmp32[2], 8); + pTmp32[3] ^= ROR32(pTmp32[3], 8); + + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + pTmp32[0] ^= pInp32[0]; + pTmp32[1] ^= pInp32[1]; + pTmp32[2] ^= pInp32[2]; + pTmp32[3] ^= pInp32[3]; + + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + pTmp32[0] ^= pInp32[0]; + pTmp32[1] ^= pInp32[1]; + pTmp32[2] ^= pInp32[2]; + pTmp32[3] ^= pInp32[3]; + + pInp32[0] = ROR32(pInp32[0], 8); + pInp32[1] = ROR32(pInp32[1], 8); + pInp32[2] = ROR32(pInp32[2], 8); + pInp32[3] = ROR32(pInp32[3], 8); + pInp32[0]^= pTmp32[0]; + pInp32[1]^= pTmp32[1]; + pInp32[2]^= pTmp32[2]; + pInp32[3]^= pTmp32[3]; +} + +/* define number of column in the state */ +#define SC NB(128) +#define STATE_SIZE (sizeof(Ipp32u)*SC) + +IPP_OWN_DEFN (void, SafeEncrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTables)) +{ + int r; + + Ipp8u state[STATE_SIZE]; /* state */ + + IPP_UNREFERENCED_PARAMETER(pTables); + + /* native => composite */ + TransformNative2Composite(state, pInpBlk); + + /* input whitening */ + AddRoundKey(state, state, pKeys); + pKeys += STATE_SIZE; + + /* regular (nr-1) rounds */ + for(r=1; r native */ + TransformComposite2Native(pOutBlk, state); +} +#endif /* _PCP_RIJ_SAFE_OLD */ + +#if !defined _PCP_RIJ_SAFE_OLD +/* +// new version +*/ + +/* +// SubByte operation in composite GF((2^4)^2) +// sdetails are in the doc. +// +// multiplication in basic GF(2^4) performs by log-and-exp sequence +*/ +static Ipp8u GF16_sqr1[] = {0x00,0x09,0x02,0x0B,0x08,0x01,0x0A,0x03, /* (x^2)*{9} */ + 0x06,0x0F,0x04,0x0D,0x0E,0x07,0x0C,0x05}; + +static Ipp8u GF16_log[] = {0xC0,0x00,0x01,0x04,0x02,0x08,0x05,0x0A, /* log element x */ + 0x03,0x0E,0x09,0x07,0x06,0x0D,0x0B,0x0C}; +static Ipp8u GF16_invlog[] = {0xC0,0x00,0x0E,0x0B,0x0D,0x07,0x0A,0x05, /* log of multiple inversion element x^-1 */ + 0x0C,0x01,0x06,0x08,0x09,0x02,0x04,0x03}; +static Ipp8u GF16_exp[] = {0x01,0x02,0x04,0x08,0x03,0x06,0x0C,0x0B, + 0x05,0x0A,0x07,0x0E,0x0F,0x0D,0x09,0x00}; /* exp[15]= 0!!! */ + +/* affine transformation matrix Ipp8u AffineMatrix[] = {0x10,0x22,0x55,0x82,0x41,0x34,0x40,0x2A}; + is defined in reference code, see doc for details */ +static Ipp8u FwdAffineMatrixLO[] = { /* defived from AffineMatrix[i], i=0,1,2,3 */ + /* 0 */ 0x00, + /* 1 */ 0x10, + /* 2 */ 0x22, + /* 3 */ 0x22^0x10, + /* 4 */ 0x55, + /* 5 */ 0x55^0x10, + /* 6 */ 0x55^0x22, + /* 7 */ 0x55^0x22^0x10, + /* 8 */ 0x82, + /* 9 */ 0x82^0x10, + /* a */ 0x82^0x22, + /* b */ 0x82^0x22^0x10, + /* c */ 0x82^0x55, + /* d */ 0x82^0x55^0x10, + /* e */ 0x82^0x55^0x22, + /* f */ 0x82^0x55^0x22^0x10 +}; +static Ipp8u FwdAffineMatrixHI[] = { /* defived from AffineMatrix[i], i=4,5,6,7 */ + /* 0 */ 0x00, + /* 1 */ 0x41, + /* 2 */ 0x34, + /* 3 */ 0x34^0x41, + /* 4 */ 0x40, + /* 5 */ 0x40^0x41, + /* 6 */ 0x40^0x34, + /* 7 */ 0x40^0x34^0x41, + /* 8 */ 0x2A, + /* 9 */ 0x2A^0x41, + /* a */ 0x2A^0x34, + /* b */ 0x2A^0x34^0x41, + /* c */ 0x2A^0x40, + /* d */ 0x2A^0x40^0x41, + /* e */ 0x2A^0x40^0x34, + /* f */ 0x2A^0x40^0x34^0x41 +}; + +/* inplace SubByte */ +static void FwdSubByte(Ipp8u blk[16]) +{ + Ipp8u blk_c[16], blk_b[16]; + ((Ipp64u*)blk_c)[0] = ((Ipp64u*)blk)[0] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_c)[1] = ((Ipp64u*)blk)[1] & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_b)[0] = (((Ipp64u*)blk)[0]>>4) & 0x0F0F0F0F0F0F0F0F; + ((Ipp64u*)blk_b)[1] = (((Ipp64u*)blk)[1]>>4) & 0x0F0F0F0F0F0F0F0F; + + { + const Ipp8u affineCnt = 0xc2; /* value of H(0x63) */ + int n; + for(n=0; n<16; n++) { + Ipp8u c = blk_c[n]; + Ipp8u b = blk_b[n]; + + /* {c+b*t} element inversion => {c+b*t} */ + Ipp8u log_c = GF16_log[c]; + Ipp8u log_b = GF16_log[b]; + Ipp8u log_cb = GF16_log[c^b]; + + Ipp8u d = GF16_sqr1[b]; + Ipp8u t = AddLogGF16(log_c, log_cb); + d ^= GF16_exp[t]; + + d = GF16_invlog[d]; + c = AddLogGF16(log_cb, d); + b = AddLogGF16(log_b, d); + c = GF16_exp[c]; + b = GF16_exp[b]; + + /* affine transformation y = (AT)*(x^-1) + affineCnt */ + c = FwdAffineMatrixLO[c]; + b = FwdAffineMatrixHI[b]; + blk[n] = (c^b) ^affineCnt; + } + } +} + +/* inplace ShifttRows operation */ +/* int ShiftRowsInx[] = {0,5,10,15, 4,9,14,3, 8,13,2,7, 12,1,6,11}; */ +__INLINE void FwdShiftRows(Ipp8u blk[16]) +{ + Ipp8u x = blk[1]; + blk[1] = blk[5]; + blk[5] = blk[9]; + blk[9] = blk[13]; + blk[13]= x; + + x = blk[2]; + blk[2] = blk[10]; + blk[10]= x; + x = blk[6]; + blk[6] = blk[14]; + blk[14]= x; + + x = blk[15]; + blk[15] = blk[11]; + blk[11] = blk[7]; + blk[7] = blk[3]; + blk[3] = x; +} + +/* inplace Mixcolumns operation */ +static Ipp8u GF16mul_E_2x[] = {0x00,0x2E,0x4F,0x61,0x8D,0xA3,0xC2,0xEC, + 0x39,0x17,0x76,0x58,0xB4,0x9A,0xFB,0xD5}; +static Ipp8u GF16mul_1_Cx[] = {0x00,0xC1,0xB2,0x73,0x54,0x95,0xE6,0x27, + 0xA8,0x69,0x1A,0xDB,0xFC,0x3D,0x4E,0x8F}; +static void FwdMixColumn(Ipp8u blk[16]) +{ + Ipp8u tmp[16]; + Ipp32u* pTmp32 = (Ipp32u*)tmp; + Ipp32u* pBlk32 = (Ipp32u*)blk; + + int n; + for(n=0; n<16; n++) { + Ipp8u xL = blk[n] & 0xF; + Ipp8u xH =(blk[n]>>4) & 0xF; + tmp[n] = GF16mul_E_2x[xL] ^ GF16mul_1_Cx[xH]; + } + + pTmp32[0] ^= ROR32(pTmp32[0], 8); + pTmp32[1] ^= ROR32(pTmp32[1], 8); + pTmp32[2] ^= ROR32(pTmp32[2], 8); + pTmp32[3] ^= ROR32(pTmp32[3], 8); + + pBlk32[0] = ROR32(pBlk32[0], 8); + pBlk32[1] = ROR32(pBlk32[1], 8); + pBlk32[2] = ROR32(pBlk32[2], 8); + pBlk32[3] = ROR32(pBlk32[3], 8); + pTmp32[0] ^= pBlk32[0]; + pTmp32[1] ^= pBlk32[1]; + pTmp32[2] ^= pBlk32[2]; + pTmp32[3] ^= pBlk32[3]; + + pBlk32[0] = ROR32(pBlk32[0], 8); + pBlk32[1] = ROR32(pBlk32[1], 8); + pBlk32[2] = ROR32(pBlk32[2], 8); + pBlk32[3] = ROR32(pBlk32[3], 8); + pTmp32[0] ^= pBlk32[0]; + pTmp32[1] ^= pBlk32[1]; + pTmp32[2] ^= pBlk32[2]; + pTmp32[3] ^= pBlk32[3]; + + pBlk32[0] = ROR32(pBlk32[0], 8); + pBlk32[1] = ROR32(pBlk32[1], 8); + pBlk32[2] = ROR32(pBlk32[2], 8); + pBlk32[3] = ROR32(pBlk32[3], 8); + pBlk32[0]^= pTmp32[0]; + pBlk32[1]^= pTmp32[1]; + pBlk32[2]^= pTmp32[2]; + pBlk32[3]^= pTmp32[3]; +} + + +/* define number of column in the state */ +#define SC NB(128) +#define STATE_SIZE (sizeof(Ipp32u)*SC) + + +IPP_OWN_DEFN (void, SafeEncrypt_RIJ128, (const Ipp8u* pInpBlk, Ipp8u* pOutBlk, int nr, const Ipp8u* pKeys, const void* pTables)) +{ + int r; + + Ipp8u state[STATE_SIZE]; /* local state */ + + IPP_UNREFERENCED_PARAMETER(pTables); + + /* native => composite */ + TransformNative2Composite(state, pInpBlk); + + /* input whitening */ + AddRoundKey(state, state, pKeys); + pKeys += STATE_SIZE; + + /* regular (nr-1) rounds */ + for(r=1; r native */ + TransformComposite2Native(pOutBlk, state); +} +#endif /* !_PCP_RIJ_SAFE_OLD */ + +#endif /* _ALG_AES_SAFE_COMPOSITE_GF_ */ + +#endif /* (_IPP <_IPP_V8) && (_IPP32E <_IPP32E_U8) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprijdecsboxca.c b/plugin/ippcp/library/src/sources/ippcp/pcprijdecsboxca.c new file mode 100644 index 000000000..4293331e3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprijdecsboxca.c @@ -0,0 +1,47 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt tables for Rijndael +// +// Contents: +// RijDecSbox[256] +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcprijtables.h" + + +/* +// Reference to pcrijencryptpxca.c +// for details +*/ + +/* +// Pure Decription S-boxes +*/ +#if defined( _IPP_DATA ) + +const __ALIGN64 Ipp8u RijDecSbox[256] = { DEC_SBOX(none_t) }; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprijencsboxca.c b/plugin/ippcp/library/src/sources/ippcp/pcprijencsboxca.c new file mode 100644 index 000000000..5984408bb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprijencsboxca.c @@ -0,0 +1,47 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt tables for Rijndael +// +// Contents: +// RijEncSbox[256] +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcprijtables.h" + + +/* +// Reference to pcrijencryptpxca.c +// for details +*/ + +/* +// Pure Encryprion S-boxes +*/ +#if defined( _IPP_DATA ) + +const __ALIGN64 Ipp8u RijEncSbox[256] = { ENC_SBOX(none_t) }; + +#endif /* _IPP_DATA */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprijkeysca.c b/plugin/ippcp/library/src/sources/ippcp/pcprijkeysca.c new file mode 100644 index 000000000..0dbdd3950 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprijkeysca.c @@ -0,0 +1,301 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Initialization of Rijndael +// +// Contents: +// EncRijndaelKeys() +// DecRijndaelKeys() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcprij.h" +#include "pcprijtables.h" +#include "pcptool.h" +#include "pcprij128safe.h" +#include "pcprij128safe2.h" +/* +// Pseudo Code for Key Expansion +// was shown in Sec 5.2 of FIPS-197 +// +// KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk) +// begin +// word temp +// +// i = 0 +// +// while (i < Nk) +// w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]) +// i = i+1 +// end while +// +// i = Nk +// +// while (i < Nb * (Nr+1)] +// temp = w[i-1] +// if (i mod Nk = 0) +// temp = SubWord(RotWord(temp)) xor Rcon[i/Nk] +// else if (Nk > 6 and i mod Nk = 4) +// temp = SubWord(temp) +// end if +// w[i] = w[i-Nk] xor temp +// i = i + 1 +// end while +// end +// +// Note: +// I see nothing any reason for optimizing reference code above +// because it run once for each encryption/decryption procedure. +// +// +// We are going to use so called Equivalent Inverse Cipher. +// Look the reason are in pcaesdecryptpxca.c. +// +// For the Equivalent Inverse Cipher, the following pseudo code is added at +// the end of the Key Expansion routine (Sec. 5.2): +// +// for i = 0 step 1 to (Nr+1)*Nb-1 +// dw[i] = w[i] +// end for +// +// for round = 1 step 1 to Nr-1 +// InvMixColumns(dw[round*Nb, (round+1)*Nb-1]) // note change of type +// end for +// +// Note that, since InvMixColumns operates on a two-dimensional array of bytes +// while the Round Keys are held in an array of words, the call to +// InvMixColumns in this code sequence involves a change of type (i.e. the +// input to InvMixColumns() is normally the State array, which is considered +// to be a two-dimensional array of bytes, whereas the input here is a Round +// Key computed as a one-dimensional array of words). +// +// +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Brief Consideration of InvMixColumn() +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Let words U and V are input and output of InvMixColumn() operation. +// Let U(0), U(1), U(2) and U(3) are bytes of word U. +// And V(0), V(1), V(2) and V(3) are bytes of word V. +// +// According to sec 5.3.3. of FIPS-197 +// V(0) = {E}U(0) xor {B}U(1) xor {D}U(2) xor {9}U(3) +// V(1) = {9}U(0) xor {E}U(1) xor {B}U(2) xor {D}U(3) +// V(2) = {D}U(0) xor {9}U(1) xor {E}U(2) xor {B}U(3) +// V(3) = {B}U(0) xor {D}U(1) xor {9}U(2) xor {E}U(3) +// where {hex}U(n) means GF(256) multiplication +// +// Or +// V = word( {E}U(0), {9}U(0), {D}U(0), {B}U(0) ) xor +// word( {B}U(1), {E}U(1), {9}U(1), {D}U(1) ) xor +// word( {D}U(2), {B}U(2), {E}U(2), {9}U(2) ) xor +// word( {9}U(3), {D}U(3), {B}U(3), {E}U(3) ) +// +// Word values +// word( {E}x, {9}x, {D}x, {B}x ) +// word( {B}y, {E}y, {9}y, {D}y ) +// word( {D}z, {B}z, {E}z, {9}z ) +// word( {9}t, {D}t, {B}t, {E}t ) +// are precomputed tables (for x,y,z,t = 0x00, ... 0xff) +// +// Tables InvMixCol_Tbl[4] are contents exactly as we want +// and macro InvMixColumn() provide necassary operation. +*/ + +/* +// RconTbl[] contains [x**(i),{00},{00},{00}], i=0,..,10 GF(256) +// +// Note: +// Reference sec 4.2 of FIPS-197 for calculation +*/ +static const Ipp32u RconTbl[] = { + BYTE0_TO_WORD(0x01), BYTE0_TO_WORD(0x02), BYTE0_TO_WORD(0x04), BYTE0_TO_WORD(0x08), + BYTE0_TO_WORD(0x10), BYTE0_TO_WORD(0x20), BYTE0_TO_WORD(0x40), BYTE0_TO_WORD(0x80), + BYTE0_TO_WORD(0x1B), BYTE0_TO_WORD(0x36), BYTE0_TO_WORD(0x6C), BYTE0_TO_WORD(0xD8), + BYTE0_TO_WORD(0xAB), BYTE0_TO_WORD(0x4D), BYTE0_TO_WORD(0x9A), BYTE0_TO_WORD(0x2F), + BYTE0_TO_WORD(0x5E), BYTE0_TO_WORD(0xBC), BYTE0_TO_WORD(0x63), BYTE0_TO_WORD(0xC6), + BYTE0_TO_WORD(0x97), BYTE0_TO_WORD(0x35), BYTE0_TO_WORD(0x6A), BYTE0_TO_WORD(0xD4), + BYTE0_TO_WORD(0xB3), BYTE0_TO_WORD(0x7D), BYTE0_TO_WORD(0xFA), BYTE0_TO_WORD(0xEF), + BYTE0_TO_WORD(0xC5) +}; + +/// commented due to mitigation +// +///* precomputed table for InvMixColumn() operation */ +//static const Ipp32u InvMixCol_Tbl[4][256] = { +// { LINE(inv_t0) }, +// { LINE(inv_t1) }, +// { LINE(inv_t2) }, +// { LINE(inv_t3) } +//}; +// +//#define InvMixColumn(x, tbl) \ +// ( (tbl)[0][ EBYTE((x),0) ] \ +// ^(tbl)[1][ EBYTE((x),1) ] \ +// ^(tbl)[2][ EBYTE((x),2) ] \ +// ^(tbl)[3][ EBYTE((x),3) ] ) + +__INLINE Ipp32u InvMixColumn(Ipp32u x) +{ + Ipp32u x_mul_2 = xtime4(x); + Ipp32u x_mul_4 = xtime4(x_mul_2); + Ipp32u x_mul_8 = xtime4(x_mul_4); + + Ipp32u x_mul_9 = x_mul_8 ^ x; + Ipp32u x_mul_B = x_mul_8 ^ x_mul_2 ^ x; + Ipp32u x_mul_D = x_mul_8 ^ x_mul_4 ^ x; + Ipp32u x_mul_E = x_mul_8 ^ x_mul_4 ^ x_mul_2; + + x = x_mul_E ^ ROR32(x_mul_B, 8) ^ ROR32(x_mul_D, 16) ^ ROR32(x_mul_9, 24); + return x; +} + +/* +// Expansion of key for Rijndael's Encryption +*/ +IPP_OWN_DEFN (void, ExpandRijndaelKey, (const Ipp8u* pKey, int NK, int NB, int NR, int nKeys, Ipp8u* pEncKeys, Ipp8u* pDecKeys)) +{ + Ipp32u* enc_keys = (Ipp32u*)pEncKeys; + Ipp32u* dec_keys = (Ipp32u*)pDecKeys; + /* convert security key to WORD and save into the enc_key array */ + int n; + for(n=0; n=_IPP_W7) || (_IPP32E==_IPP32E_M7)) + _mm_lfence(); /* lfence added because of potential exploit of speculative execution (KW); lfence accessible on SSE2 and above */ + #endif + dec_keys[n] = InvMixColumn(dec_keys[n]); + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprijtables.h b/plugin/ippcp/library/src/sources/ippcp/pcprijtables.h new file mode 100644 index 000000000..ee0414c43 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprijtables.h @@ -0,0 +1,197 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Rijndael Tables Declarations +// +// +*/ + +#if !defined(_PCP_RIJTBLES_H) +#define _PCP_RIJTBLES_H + +#include "owndefs.h" +#include "owncp.h" +#include "pcprij.h" + +/* +// GF(256) multiplication operations +*/ +#define gf_m2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) +#define gf_m4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) +#define gf_m8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ + ^ (((x>>5) & 4) * WPOLY)) +#define gf_m1(x) ((x)) +#define gf_m3(x) (gf_m2(x) ^ x) +#define gf_m9(x) (gf_m8(x) ^ x) +#define gf_mB(x) (gf_m8(x) ^ gf_m2(x) ^ x) +#define gf_mD(x) (gf_m8(x) ^ gf_m4(x) ^ x) +#define gf_mE(x) (gf_m8(x) ^ gf_m4(x) ^ gf_m2(x)) + +/* +// The following particular transformations +// are used for create Encryption Tables +*/ +#define fwd_t0(x) BYTES_TO_WORD(gf_m2(x), gf_m1(x), gf_m1(x), gf_m3(x)) +#define fwd_t1(x) BYTES_TO_WORD(gf_m3(x), gf_m2(x), gf_m1(x), gf_m1(x)) +#define fwd_t2(x) BYTES_TO_WORD(gf_m1(x), gf_m3(x), gf_m2(x), gf_m1(x)) +#define fwd_t3(x) BYTES_TO_WORD(gf_m1(x), gf_m1(x), gf_m3(x), gf_m2(x)) + +/* +// The following particular transformations +// are used for create Decryption Tables +*/ +#define inv_t0(x) BYTES_TO_WORD(gf_mE(x), gf_m9(x), gf_mD(x), gf_mB(x)) +#define inv_t1(x) BYTES_TO_WORD(gf_mB(x), gf_mE(x), gf_m9(x), gf_mD(x)) +#define inv_t2(x) BYTES_TO_WORD(gf_mD(x), gf_mB(x), gf_mE(x), gf_m9(x)) +#define inv_t3(x) BYTES_TO_WORD(gf_m9(x), gf_mD(x), gf_mB(x), gf_mE(x)) + +#define exp_b3(x) BYTES_TO_WORD(0, 0, 0, (x)) +#define exp_b2(x) BYTES_TO_WORD(0, 0, (x),0) +#define exp_b1(x) BYTES_TO_WORD(0, (x),0, 0) +#define exp_b0(x) BYTES_TO_WORD((x),0, 0, 0) + +/* +// The following particular transformations +// are used for create pure Encryption/Decryption Sboxes +*/ +#define none_t(x) (x) + + +/* +// Just sequence of byte, beginning 0x00 upto 0xff +// (be parametrized by any transformation 't') +*/ +#define LINE(t) \ + t(0x00), t(0x01), t(0x02), t(0x03), t(0x04), t(0x05), t(0x06), t(0x07),\ + t(0x08), t(0x09), t(0x0a), t(0x0b), t(0x0c), t(0x0d), t(0x0e), t(0x0f),\ + t(0x10), t(0x11), t(0x12), t(0x13), t(0x14), t(0x15), t(0x16), t(0x17),\ + t(0x18), t(0x19), t(0x1a), t(0x1b), t(0x1c), t(0x1d), t(0x1e), t(0x1f),\ + t(0x20), t(0x21), t(0x22), t(0x23), t(0x24), t(0x25), t(0x26), t(0x27),\ + t(0x28), t(0x29), t(0x2a), t(0x2b), t(0x2c), t(0x2d), t(0x2e), t(0x2f),\ + t(0x30), t(0x31), t(0x32), t(0x33), t(0x34), t(0x35), t(0x36), t(0x37),\ + t(0x38), t(0x39), t(0x3a), t(0x3b), t(0x3c), t(0x3d), t(0x3e), t(0x3f),\ + t(0x40), t(0x41), t(0x42), t(0x43), t(0x44), t(0x45), t(0x46), t(0x47),\ + t(0x48), t(0x49), t(0x4a), t(0x4b), t(0x4c), t(0x4d), t(0x4e), t(0x4f),\ + t(0x50), t(0x51), t(0x52), t(0x53), t(0x54), t(0x55), t(0x56), t(0x57),\ + t(0x58), t(0x59), t(0x5a), t(0x5b), t(0x5c), t(0x5d), t(0x5e), t(0x5f),\ + t(0x60), t(0x61), t(0x62), t(0x63), t(0x64), t(0x65), t(0x66), t(0x67),\ + t(0x68), t(0x69), t(0x6a), t(0x6b), t(0x6c), t(0x6d), t(0x6e), t(0x6f),\ + t(0x70), t(0x71), t(0x72), t(0x73), t(0x74), t(0x75), t(0x76), t(0x77),\ + t(0x78), t(0x79), t(0x7a), t(0x7b), t(0x7c), t(0x7d), t(0x7e), t(0x7f),\ + t(0x80), t(0x81), t(0x82), t(0x83), t(0x84), t(0x85), t(0x86), t(0x87),\ + t(0x88), t(0x89), t(0x8a), t(0x8b), t(0x8c), t(0x8d), t(0x8e), t(0x8f),\ + t(0x90), t(0x91), t(0x92), t(0x93), t(0x94), t(0x95), t(0x96), t(0x97),\ + t(0x98), t(0x99), t(0x9a), t(0x9b), t(0x9c), t(0x9d), t(0x9e), t(0x9f),\ + t(0xa0), t(0xa1), t(0xa2), t(0xa3), t(0xa4), t(0xa5), t(0xa6), t(0xa7),\ + t(0xa8), t(0xa9), t(0xaa), t(0xab), t(0xac), t(0xad), t(0xae), t(0xaf),\ + t(0xb0), t(0xb1), t(0xb2), t(0xb3), t(0xb4), t(0xb5), t(0xb6), t(0xb7),\ + t(0xb8), t(0xb9), t(0xba), t(0xbb), t(0xbc), t(0xbd), t(0xbe), t(0xbf),\ + t(0xc0), t(0xc1), t(0xc2), t(0xc3), t(0xc4), t(0xc5), t(0xc6), t(0xc7),\ + t(0xc8), t(0xc9), t(0xca), t(0xcb), t(0xcc), t(0xcd), t(0xce), t(0xcf),\ + t(0xd0), t(0xd1), t(0xd2), t(0xd3), t(0xd4), t(0xd5), t(0xd6), t(0xd7),\ + t(0xd8), t(0xd9), t(0xda), t(0xdb), t(0xdc), t(0xdd), t(0xde), t(0xdf),\ + t(0xe0), t(0xe1), t(0xe2), t(0xe3), t(0xe4), t(0xe5), t(0xe6), t(0xe7),\ + t(0xe8), t(0xe9), t(0xea), t(0xeb), t(0xec), t(0xed), t(0xee), t(0xef),\ + t(0xf0), t(0xf1), t(0xf2), t(0xf3), t(0xf4), t(0xf5), t(0xf6), t(0xf7),\ + t(0xf8), t(0xf9), t(0xfa), t(0xfb), t(0xfc), t(0xfd), t(0xfe), t(0xff) + +/* +// Encrypt/Decrypt S-box data +// (be parametrized by any transformation 't') +*/ +#define ENC_SBOX(t) \ + t(0x63), t(0x7c), t(0x77), t(0x7b), t(0xf2), t(0x6b), t(0x6f), t(0xc5),\ + t(0x30), t(0x01), t(0x67), t(0x2b), t(0xfe), t(0xd7), t(0xab), t(0x76),\ + t(0xca), t(0x82), t(0xc9), t(0x7d), t(0xfa), t(0x59), t(0x47), t(0xf0),\ + t(0xad), t(0xd4), t(0xa2), t(0xaf), t(0x9c), t(0xa4), t(0x72), t(0xc0),\ + t(0xb7), t(0xfd), t(0x93), t(0x26), t(0x36), t(0x3f), t(0xf7), t(0xcc),\ + t(0x34), t(0xa5), t(0xe5), t(0xf1), t(0x71), t(0xd8), t(0x31), t(0x15),\ + t(0x04), t(0xc7), t(0x23), t(0xc3), t(0x18), t(0x96), t(0x05), t(0x9a),\ + t(0x07), t(0x12), t(0x80), t(0xe2), t(0xeb), t(0x27), t(0xb2), t(0x75),\ + t(0x09), t(0x83), t(0x2c), t(0x1a), t(0x1b), t(0x6e), t(0x5a), t(0xa0),\ + t(0x52), t(0x3b), t(0xd6), t(0xb3), t(0x29), t(0xe3), t(0x2f), t(0x84),\ + t(0x53), t(0xd1), t(0x00), t(0xed), t(0x20), t(0xfc), t(0xb1), t(0x5b),\ + t(0x6a), t(0xcb), t(0xbe), t(0x39), t(0x4a), t(0x4c), t(0x58), t(0xcf),\ + t(0xd0), t(0xef), t(0xaa), t(0xfb), t(0x43), t(0x4d), t(0x33), t(0x85),\ + t(0x45), t(0xf9), t(0x02), t(0x7f), t(0x50), t(0x3c), t(0x9f), t(0xa8),\ + t(0x51), t(0xa3), t(0x40), t(0x8f), t(0x92), t(0x9d), t(0x38), t(0xf5),\ + t(0xbc), t(0xb6), t(0xda), t(0x21), t(0x10), t(0xff), t(0xf3), t(0xd2),\ + t(0xcd), t(0x0c), t(0x13), t(0xec), t(0x5f), t(0x97), t(0x44), t(0x17),\ + t(0xc4), t(0xa7), t(0x7e), t(0x3d), t(0x64), t(0x5d), t(0x19), t(0x73),\ + t(0x60), t(0x81), t(0x4f), t(0xdc), t(0x22), t(0x2a), t(0x90), t(0x88),\ + t(0x46), t(0xee), t(0xb8), t(0x14), t(0xde), t(0x5e), t(0x0b), t(0xdb),\ + t(0xe0), t(0x32), t(0x3a), t(0x0a), t(0x49), t(0x06), t(0x24), t(0x5c),\ + t(0xc2), t(0xd3), t(0xac), t(0x62), t(0x91), t(0x95), t(0xe4), t(0x79),\ + t(0xe7), t(0xc8), t(0x37), t(0x6d), t(0x8d), t(0xd5), t(0x4e), t(0xa9),\ + t(0x6c), t(0x56), t(0xf4), t(0xea), t(0x65), t(0x7a), t(0xae), t(0x08),\ + t(0xba), t(0x78), t(0x25), t(0x2e), t(0x1c), t(0xa6), t(0xb4), t(0xc6),\ + t(0xe8), t(0xdd), t(0x74), t(0x1f), t(0x4b), t(0xbd), t(0x8b), t(0x8a),\ + t(0x70), t(0x3e), t(0xb5), t(0x66), t(0x48), t(0x03), t(0xf6), t(0x0e),\ + t(0x61), t(0x35), t(0x57), t(0xb9), t(0x86), t(0xc1), t(0x1d), t(0x9e),\ + t(0xe1), t(0xf8), t(0x98), t(0x11), t(0x69), t(0xd9), t(0x8e), t(0x94),\ + t(0x9b), t(0x1e), t(0x87), t(0xe9), t(0xce), t(0x55), t(0x28), t(0xdf),\ + t(0x8c), t(0xa1), t(0x89), t(0x0d), t(0xbf), t(0xe6), t(0x42), t(0x68),\ + t(0x41), t(0x99), t(0x2d), t(0x0f), t(0xb0), t(0x54), t(0xbb), t(0x16) + +#define DEC_SBOX(t) \ + t(0x52), t(0x09), t(0x6a), t(0xd5), t(0x30), t(0x36), t(0xa5), t(0x38),\ + t(0xbf), t(0x40), t(0xa3), t(0x9e), t(0x81), t(0xf3), t(0xd7), t(0xfb),\ + t(0x7c), t(0xe3), t(0x39), t(0x82), t(0x9b), t(0x2f), t(0xff), t(0x87),\ + t(0x34), t(0x8e), t(0x43), t(0x44), t(0xc4), t(0xde), t(0xe9), t(0xcb),\ + t(0x54), t(0x7b), t(0x94), t(0x32), t(0xa6), t(0xc2), t(0x23), t(0x3d),\ + t(0xee), t(0x4c), t(0x95), t(0x0b), t(0x42), t(0xfa), t(0xc3), t(0x4e),\ + t(0x08), t(0x2e), t(0xa1), t(0x66), t(0x28), t(0xd9), t(0x24), t(0xb2),\ + t(0x76), t(0x5b), t(0xa2), t(0x49), t(0x6d), t(0x8b), t(0xd1), t(0x25),\ + t(0x72), t(0xf8), t(0xf6), t(0x64), t(0x86), t(0x68), t(0x98), t(0x16),\ + t(0xd4), t(0xa4), t(0x5c), t(0xcc), t(0x5d), t(0x65), t(0xb6), t(0x92),\ + t(0x6c), t(0x70), t(0x48), t(0x50), t(0xfd), t(0xed), t(0xb9), t(0xda),\ + t(0x5e), t(0x15), t(0x46), t(0x57), t(0xa7), t(0x8d), t(0x9d), t(0x84),\ + t(0x90), t(0xd8), t(0xab), t(0x00), t(0x8c), t(0xbc), t(0xd3), t(0x0a),\ + t(0xf7), t(0xe4), t(0x58), t(0x05), t(0xb8), t(0xb3), t(0x45), t(0x06),\ + t(0xd0), t(0x2c), t(0x1e), t(0x8f), t(0xca), t(0x3f), t(0x0f), t(0x02),\ + t(0xc1), t(0xaf), t(0xbd), t(0x03), t(0x01), t(0x13), t(0x8a), t(0x6b),\ + t(0x3a), t(0x91), t(0x11), t(0x41), t(0x4f), t(0x67), t(0xdc), t(0xea),\ + t(0x97), t(0xf2), t(0xcf), t(0xce), t(0xf0), t(0xb4), t(0xe6), t(0x73),\ + t(0x96), t(0xac), t(0x74), t(0x22), t(0xe7), t(0xad), t(0x35), t(0x85),\ + t(0xe2), t(0xf9), t(0x37), t(0xe8), t(0x1c), t(0x75), t(0xdf), t(0x6e),\ + t(0x47), t(0xf1), t(0x1a), t(0x71), t(0x1d), t(0x29), t(0xc5), t(0x89),\ + t(0x6f), t(0xb7), t(0x62), t(0x0e), t(0xaa), t(0x18), t(0xbe), t(0x1b),\ + t(0xfc), t(0x56), t(0x3e), t(0x4b), t(0xc6), t(0xd2), t(0x79), t(0x20),\ + t(0x9a), t(0xdb), t(0xc0), t(0xfe), t(0x78), t(0xcd), t(0x5a), t(0xf4),\ + t(0x1f), t(0xdd), t(0xa8), t(0x33), t(0x88), t(0x07), t(0xc7), t(0x31),\ + t(0xb1), t(0x12), t(0x10), t(0x59), t(0x27), t(0x80), t(0xec), t(0x5f),\ + t(0x60), t(0x51), t(0x7f), t(0xa9), t(0x19), t(0xb5), t(0x4a), t(0x0d),\ + t(0x2d), t(0xe5), t(0x7a), t(0x9f), t(0x93), t(0xc9), t(0x9c), t(0xef),\ + t(0xa0), t(0xe0), t(0x3b), t(0x4d), t(0xae), t(0x2a), t(0xf5), t(0xb0),\ + t(0xc8), t(0xeb), t(0xbb), t(0x3c), t(0x83), t(0x53), t(0x99), t(0x61),\ + t(0x17), t(0x2b), t(0x04), t(0x7e), t(0xba), t(0x77), t(0xd6), t(0x26),\ + t(0xe1), t(0x69), t(0x14), t(0x63), t(0x55), t(0x21), t(0x0c), t(0x7d), + +/* +// Internal cipher tables +*/ +extern const __ALIGN64 Ipp8u RijEncSbox[256]; /* pure encryption S-box */ +extern const __ALIGN64 Ipp8u RijDecSbox[256]; /* pure decryption S-box */ + +extern const __ALIGN16 Ipp32u RijEncTbl[5][256]; /* precomputed encryption tables */ +extern const __ALIGN16 Ipp32u RijDecTbl[5][256]; /* precomputed decryption tables */ + +#endif /* _PCP_RIJTBLES_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_decrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_decrypt.c new file mode 100644 index 000000000..8eb949c1e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_decrypt.c @@ -0,0 +1,93 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_Decrypt() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +/*F* +// Name: ippsRSA_Decrypt +// +// Purpose: Performs RSA Decryprion +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// NULL == pCtxt +// NULL == pPtxt +// NULL == pBuffer +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID() +// !BN_VALID_ID(pCtxt) +// !BN_VALID_ID(pPtxt) +// +// ippStsIncompleteContextErr private key is not set up +// +// ippStsOutOfRangeErr pCtxt >= modulus +// pCtxt <0 +// +// ippStsSizeErr BN_ROOM(pPtxt) is not enough +// +// ippStsNoErr no error +// +// Parameters: +// pCtxt pointer to the ciphertext +// pPtxt pointer to the plaintext +// pKey pointer to the key context +// pScratchBuffer pointer to the temporary buffer +*F*/ +IPPFUN(IppStatus, ippsRSA_Decrypt,(const IppsBigNumState* pCtxt, + IppsBigNumState* pPtxt, + const IppsRSAPrivateKeyState* pKey, + Ipp8u* pBuffer)) +{ + IPP_BAD_PTR2_RET(pKey, pBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + IPP_BAD_PTR1_RET(pCtxt); + IPP_BADARG_RET(!BN_VALID_ID(pCtxt), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pCtxt), ippStsOutOfRangeErr); + IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(pCtxt), BN_SIZE(pCtxt), + MOD_MODULUS(RSA_PRV_KEY_NMONT(pKey)), MOD_LEN(RSA_PRV_KEY_NMONT(pKey))), ippStsOutOfRangeErr); + + IPP_BAD_PTR1_RET(pPtxt); + IPP_BADARG_RET(!BN_VALID_ID(pPtxt), ippStsContextMatchErr); + IPP_BADARG_RET(BN_ROOM(pPtxt) < BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey)), ippStsSizeErr); + + { + BNU_CHUNK_T* pScratchBuffer = (BNU_CHUNK_T*)( IPP_ALIGNED_PTR(pBuffer, (int)sizeof(BNU_CHUNK_T)) ); + + if(RSA_PRV_KEY1_VALID_ID(pKey)) + gsRSAprv_cipher(pPtxt, pCtxt, pKey, pScratchBuffer); + else + gsRSAprv_cipher_crt(pPtxt, pCtxt, pKey, pScratchBuffer); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_emsa_pkcs1v15.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_emsa_pkcs1v15.h new file mode 100644 index 000000000..ba92d2c21 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_emsa_pkcs1v15.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +static int EMSA_PKCSv15(const Ipp8u* msgDg, int lenMsgDg, + const Ipp8u* fixPS, int lenFixPS, + Ipp8u* pEM, int lenEM) +{ + /* + // encoded message format: + // EM = 00 || 01 || PS=(FF..FF) || 00 || T + // T = fixPS || msgDg + // len(PS) >= 8 + */ + int tLen = lenFixPS + lenMsgDg; + + if (lenEM >= tLen + 11) { + int psLen = lenEM - 3 - tLen; + + PadBlock(0xFF, pEM, lenEM); + pEM[0] = 0x00; + pEM[1] = 0x01; + pEM[2 + psLen] = 0x00; + CopyBlock(fixPS, pEM + 3 + psLen, lenFixPS); + if (msgDg) { + CopyBlock(msgDg, pEM + 3 + psLen + lenFixPS, lenMsgDg); + } + return 1; + } + else + return 0; /* encoded message length too long */ +} \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_encrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_encrypt.c new file mode 100644 index 000000000..95cfdf904 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_encrypt.c @@ -0,0 +1,88 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_Encrypt() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +/*F* +// Name: ippsRSA_Encrypt +// +// Purpose: Performs RSA Encryprion +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// NULL == pPtxt +// NULL == pCtxt +// NULL == pBuffer +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID() +// !BN_VALID_ID(pPtxt) +// !BN_VALID_ID(pCtxt) +// +// ippStsIncompleteContextErr public key is not setup +// +// ippStsOutOfRangeErr pPtxt >= modulus +// pPtxt <0 +// +// ippStsSizeErr BN_ROOM(pCtxt) is not enough +// +// ippStsNoErr no error +// +// Parameters: +// pPtxt pointer to the plaintext +// pCtxt pointer to the ciphertext +// pKey pointer to the key context +// pScratchBuffer pointer to the temporary buffer +*F*/ +IPPFUN(IppStatus, ippsRSA_Encrypt,(const IppsBigNumState* pPtxt, + IppsBigNumState* pCtxt, + const IppsRSAPublicKeyState* pKey, + Ipp8u* pBuffer)) +{ + IPP_BAD_PTR2_RET(pKey, pBuffer); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + IPP_BAD_PTR1_RET(pPtxt); + IPP_BADARG_RET(!BN_VALID_ID(pPtxt), ippStsContextMatchErr); + IPP_BADARG_RET(BN_NEGATIVE(pPtxt), ippStsOutOfRangeErr); + IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(pPtxt), BN_SIZE(pPtxt), + MOD_MODULUS(RSA_PUB_KEY_NMONT(pKey)), MOD_LEN(RSA_PUB_KEY_NMONT(pKey))), ippStsOutOfRangeErr); + + IPP_BAD_PTR1_RET(pCtxt); + IPP_BADARG_RET(!BN_VALID_ID(pCtxt), ippStsContextMatchErr); + IPP_BADARG_RET(BN_ROOM(pCtxt) < BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey)), ippStsSizeErr); + + { + BNU_CHUNK_T* pScratchBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pBuffer, (int)sizeof(BNU_CHUNK_T)) ); + gsRSApub_cipher(pCtxt, pPtxt, pKey, pScratchBuffer); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_generatekeys.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_generatekeys.c new file mode 100644 index 000000000..a45c78690 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_generatekeys.c @@ -0,0 +1,300 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_GenerateKeys() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcpngrsa.h" + +#include "pcpprime_isco.h" +#include "pcpprime_isprob.h" + +/*F* +// Name: ippsRSA_GenerateKeys +// +// Purpose: Generate RSA keys +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSrcPublicExp +// NULL == pPublicExp +// NULL == pModulus +// NULL == pPrivateKeyType2 +// NULL == pPrimeGen +// NULL == pBuffer +// NULL == rndFunc +// +// ippStsContextMatchErr !RSA_PRV_KEY2_VALID_ID(pPrivateKeyType2) +// !RSA_PRV_KEY1_VALID_ID(pPrivateKeyType1) +// !BN_VALID_ID(pSrcPublicExp) +// !BN_VALID_ID(pPublicExp) +// !BN_VALID_ID(pModulus) +// !PRIME_VALID_ID(pPrimeGen) +// +// ippStsSizeErr BN_ROOM(pPublicExp) < BN_SIZE(pSrcPublicExp) +// BN_ROOM(pModulus) < SIZE(factorPbitSize+factorQbitSize) +// PRIME_MAXBITSIZE(pPrimeGen) < factorPbitSize +// +// ippStsOutOfRangeErr 0 >= pSrcPublicExp +// +// ippStsBadArgErr nTrials < 1 +// +// ippStsNoErr no error +// +// Parameters: +// pSrcPublicExp pointer to the beginning public exponent +// pPublicExp pointer to the resulting public exponent (E) +// pModulus pointer to the resulting modulus (N) +// pPrivateKeyType2 pointer to the private key type2 context +// pPrivateKeyType1 (optional) pointer to the private key type1 context +// pBuffer pointer to the temporary buffer +// nTrials parameter of Miller-Rabin Test +// pPrimeGen pointer to the Prime generator context +// rndFunc external PRNG +// pRndParam pointer to the external PRNG parameters +*F*/ +IPPFUN(IppStatus, ippsRSA_GenerateKeys,(const IppsBigNumState* pSrcPublicExp, + IppsBigNumState* pModulus, + IppsBigNumState* pPublicExp, + IppsBigNumState* pPrivateExp, /* optional */ + IppsRSAPrivateKeyState* pPrivateKeyType2, + Ipp8u* pBuffer, + int nTrials, + IppsPrimeState* pPrimeGen, /* NULL */ + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR1_RET(pSrcPublicExp); + IPP_BADARG_RET(!BN_VALID_ID(pSrcPublicExp), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pSrcPublicExp)), ippStsOutOfRangeErr); + /* test if e is odd and e>=3 */ + IPP_BADARG_RET(!(BN_NUMBER(pSrcPublicExp)[0] &1), ippStsBadArgErr); + IPP_BADARG_RET((0 > cpBN_cmp(pSrcPublicExp, cpBN_ThreeRef())), ippStsBadArgErr); + + IPP_BAD_PTR1_RET(pModulus); + IPP_BADARG_RET(!BN_VALID_ID(pModulus), ippStsContextMatchErr); + + IPP_BAD_PTR1_RET(pPublicExp); + IPP_BADARG_RET(!BN_VALID_ID(pPublicExp), ippStsContextMatchErr); + IPP_BADARG_RET(BN_ROOM(pPublicExp) ret) break; /* internal error */ + if(0 ==ret) continue; /* composite factor */ + found = 1; + } + if(!found) + goto err; /* internal error or ippStsInsufficientEntropy */ + + /* + // generate prime Q + */ + topPattern = (BNU_CHUNK_T)1 << ((factorQbitSize-1)&(BNU_CHUNK_BITS-1)); + nRounds = 5*factorQbitSize; + + for(r=0,found=0; r=512) { + int bitsize = BITSIZE_BNU(pFreeBuffer, nsP); + if(bitsize < (factorPbitSize-100)) continue; /* abs(P-Q) <=2^(factorPbitSize-100)*/ + } + } + } + + /* test if bitsize(N) = bitsize(P)+bitsize(Q) */ + cpMul_BNU_school(pProdN, pFactorP, nsP, pFactorQ, nsQ); + if(rsaModulusBitSize != BITSIZE_BNU(pProdN, nsN)) continue; + + /* chek if E and (Q-1) co-prime */ + cpDec_BNU(pFactorQ, pFactorQ, nsQ, 1); + if(0 == cpIsCoPrime(BN_NUMBER(pPublicExp), BN_SIZE(pPublicExp), pFactorQ, nsQ, pFreeBuffer)) continue; + + /* test Q for primality */ + cpInc_BNU(pFactorQ, pFactorQ, nsQ, 1); + gsModEngineInit(pMontQ, (Ipp32u*)pFactorQ, factorQbitSize, MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + //if(0==cpIsProbablyPrime(pFactorQ, factorQbitSize, mrTrials, + // rndFunc, pRndParam, + // pMontQ, pFreeBuffer)) continue; + //found = 1; + ret = cpIsProbablyPrime(pFactorQ, factorQbitSize, mrTrials, + rndFunc, pRndParam, + pMontQ, pFreeBuffer); + if(0 > ret) break; /* internal error */ + if(0 ==ret) continue; /* composite factor */ + found = 1; + } + if(!found) + goto err; /* internal error or ippStsInsufficientEntropy */ + + { + BNU_CHUNK_T* pExpD = pFreeBuffer; + BNU_CHUNK_T* pExpDBuf = pExpD +nsN+1; + BNU_CHUNK_T* pPhi = pExpDBuf+nsN+1; + BNU_CHUNK_T* pPhiBuf = pPhi +nsN+1; + int nsD, ns; + + /* phi = (P-1) * (Q-1) */ + cpDec_BNU(pFactorP, pFactorP, nsP, 1); + cpDec_BNU(pFactorQ, pFactorQ, nsQ, 1); + cpMul_BNU_school(pPhi, pFactorP, nsP, pFactorQ, nsQ); + + /* D = 1/E mod (phi) */ + nsD = cpModInv_BNU(pExpD, BN_NUMBER(pPublicExp),BN_SIZE(pPublicExp), pPhi,nsN, pExpDBuf, BN_BUFFER(pPublicExp), pPhiBuf); + /* if D exp requested */ + if(pPrivateExp) + BN_Set(pExpD, nsD, pPrivateExp); + + /* compute dP = D mod(P-1) */ + COPY_BNU(pExpDBuf, pExpD, nsD); + ns = cpMod_BNU(pExpDBuf, nsD, pFactorP, nsP); + ZEXPAND_COPY_BNU(pExpDp, nsP, pExpDBuf, ns); + /* compute dQ = D mod(Q-1) */ + COPY_BNU(pPhi, pExpD, nsD); + ns = cpMod_BNU(pPhi, nsD, pFactorQ, nsQ); + ZEXPAND_COPY_BNU(pExpDq, nsQ, pPhi, ns); + + /* restore P and Q */ + pFactorP[0]++; + pFactorQ[0]++; + /* re-init Montgomery Engine */ + gsModEngineInit(pMontP, (Ipp32u*)pFactorP, factorPbitSize, MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + gsModEngineInit(pMontQ, (Ipp32u*)pFactorQ, factorQbitSize, MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + + /* compute Qinv = 1/Q mod P */ + COPY_BNU(pPhiBuf, pFactorP,nsP); + ns = cpModInv_BNU(pInvQ, pFactorQ,nsQ, pPhiBuf,nsP, pExpD, pExpDBuf, pPhi); + /* expand invQ */ + ZEXPAND_BNU(pInvQ, ns, nsP); + + cpMul_BNU_school(pProdN, pFactorP, nsP, pFactorQ, nsQ); + gsModEngineInit(pMontN, (Ipp32u*)pProdN, factorPbitSize+factorQbitSize, MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + /* setup modulus */ + BN_Set(pProdN, nsN, pModulus); + + /* actual size of modulus in bits */ + RSA_PRV_KEY_BITSIZE_N(pPrivateKeyType2) = BITSIZE_BNU(pProdN, nsN); + + ret = 1; + return ippStsNoErr; + } + + err: + ZEXPAND_BNU(pFactorP, 0, nsP); + ZEXPAND_BNU(pFactorQ, 0, nsQ); + ZEXPAND_BNU(pExpDp, 0, nsP); + ZEXPAND_BNU(pExpDq, 0, nsQ); + ZEXPAND_BNU(pInvQ, 0, nsP); + return ret<0? ippStsErr : ippStsInsufficientEntropy; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_generatesign_pkcs1v15.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_generatesign_pkcs1v15.h new file mode 100644 index 000000000..c0fc4d77d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_generatesign_pkcs1v15.h @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +#include "pcprsa_emsa_pkcs1v15.h" + +static int GenerateSign(const Ipp8u* pMsg, int msgLen, /* message representation */ + const Ipp8u* pSalt, int saltLen, /* fied string */ + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + BNU_CHUNK_T* pBuffer) +{ + /* size of RSA modulus in bytes and chunks */ + cpSize rsaBits = RSA_PRV_KEY_BITSIZE_N(pPrvKey); + cpSize k = BITS2WORD8_SIZE(rsaBits); + cpSize nsN = BITS_BNU_CHUNK(rsaBits); + + /* EMSA-PKCS-v1_5 encoding */ + int result = EMSA_PKCSv15(pMsg, msgLen, pSalt, saltLen, pSign, k); + + if (result) { + /* temporary BNs */ + __ALIGN8 IppsBigNumState bnC; + __ALIGN8 IppsBigNumState bnP; + + /* make BNs */ + BN_Make(pBuffer, pBuffer + nsN + 1, nsN, &bnC); + pBuffer += (nsN + 1) * 2; + BN_Make(pBuffer, pBuffer + nsN + 1, nsN, &bnP); + pBuffer += (nsN + 1) * 2; + + /* + // private-key operation + */ + ippsSetOctString_BN(pSign, k, &bnC); + + if (RSA_PRV_KEY1_VALID_ID(pPrvKey)) + gsRSAprv_cipher(&bnP, &bnC, pPrvKey, pBuffer); + else + gsRSAprv_cipher_crt(&bnP, &bnC, pPrvKey, pBuffer); + + ippsGetOctString_BN(pSign, k, &bnP); + + /* check the result before send it out (fault attack mitigatioin) */ + if (pPubKey) { + gsRSApub_cipher(&bnP, &bnP, pPubKey, pBuffer); + + /* check signature before send it out (fault attack mitigatioin) */ + if (0 != cpBN_cmp(&bnP, &bnC)) { + PadBlock(0, pSign, k); + result = 0; + } + } + } + + return result; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_getbuffersizeprivatekey.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getbuffersizeprivatekey.c new file mode 100644 index 000000000..26001e950 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getbuffersizeprivatekey.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_GetBufferSizePrivateKey() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +#include "pcprsa_getdefmeth_priv.h" + +/*F* +// Name: ippsRSA_GetBufferSizePrivateKey +// +// Purpose: Returns size of temporary buffer (in bytes) for private key operation +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// NULL == pBufferSize +// +// ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID() +// +// ippStsIncompleteContextErr (type1) private key is not set up +// +// ippStsNoErr no error +// +// Parameters: +// pBufferSize pointer to size of temporary buffer +// pKey pointer to the key context +*F*/ +IPPFUN(IppStatus, ippsRSA_GetBufferSizePrivateKey,(int* pBufferSize, const IppsRSAPrivateKeyState* pKey)) +{ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(RSA_PRV_KEY1_VALID_ID(pKey) && !RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + IPP_BAD_PTR1_RET(pBufferSize); + + { + cpSize modulusBits = (RSA_PRV_KEY1_VALID_ID(pKey))? RSA_PRV_KEY_BITSIZE_N(pKey) : + IPP_MAX(RSA_PRV_KEY_BITSIZE_P(pKey), RSA_PRV_KEY_BITSIZE_Q(pKey)); + gsMethod_RSA* m = getDualExpMethod_RSA_private(RSA_PRV_KEY_BITSIZE_P(pKey), RSA_PRV_KEY_BITSIZE_Q(pKey)); + if (NULL == m) + m = getDefaultMethod_RSA_private(modulusBits); + + cpSize bitSizeN = (RSA_PRV_KEY1_VALID_ID(pKey))? modulusBits : modulusBits*2; + cpSize nsN = BITS_BNU_CHUNK(bitSizeN); + + cpSize bn_scheme = (nsN+1)*2; /* BN for RSA schemes */ + cpSize bn3_gen = (RSA_PRV_KEY2_VALID_ID(pKey))? (nsN+1)*2*3 : 0; /* 3 BN for generation/validation */ + + cpSize bufferNum = bn_scheme*2 /* (1)2 BN for RSA (enc)/sign schemes */ + + 1; /* BNU_CHUNK_T alignment */ + bufferNum += m->bufferNumFunc(modulusBits); /* RSA private key operation */ + + bufferNum = IPP_MAX(bufferNum, bn3_gen); /* generation/validation resource overlaps RSA resource */ + + *pBufferSize = bufferNum*(Ipp32s)sizeof(BNU_CHUNK_T); + + #if defined(_USE_WINDOW_EXP_) + /* pre-computed table should be CACHE_LINE aligned*/ + *pBufferSize += CACHE_LINE_SIZE; + #endif + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_getbuffersizepublickey.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getbuffersizepublickey.c new file mode 100644 index 000000000..f52a237e0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getbuffersizepublickey.c @@ -0,0 +1,77 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_GetBufferSizePublicKey() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +#include "pcprsa_getdefmeth_pub.h" + +/*F* +// Name: ippsRSA_GetBufferSizePublicKey +// +// Purpose: Returns size of temporary buffer (in bytes) for public key operation +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// NULL == pBufferSize +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID() +// +// ippStsIncompleteContextErr no ippsRSA_SetPublicKey() call +// +// ippStsNoErr no error +// +// Parameters: +// pBufferSize pointer to size of temporary buffer +// pKey pointer to the key context +*F*/ +IPPFUN(IppStatus, ippsRSA_GetBufferSizePublicKey,(int* pBufferSize, const IppsRSAPublicKeyState* pKey)) +{ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + IPP_BAD_PTR1_RET(pBufferSize); + + { + cpSize bitSizeN = RSA_PUB_KEY_BITSIZE_N(pKey); + cpSize nsN = BITS_BNU_CHUNK(bitSizeN); + + gsMethod_RSA* m = getDefaultMethod_RSA_public(bitSizeN); + + cpSize bufferNum = ((nsN+1)*2)*2 /* (1)2 BN for RSA (enc)/sign schemes */ + + 1; /* BNU_CHUNK_T alignment */ + bufferNum += m->bufferNumFunc(bitSizeN); /* RSA public key operation */ + + *pBufferSize = bufferNum*(Ipp32s)sizeof(BNU_CHUNK_T); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_getdefmeth_priv.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getdefmeth_priv.h new file mode 100644 index 000000000..3f927f5d6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getdefmeth_priv.h @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +static gsMethod_RSA* getDefaultMethod_RSA_private(int modulusBitSize) +{ + gsMethod_RSA* m; + +#if(_IPP32E>=_IPP32E_K1) + m = IsFeatureEnabled(ippCPUID_AVX512IFMA) ? gsMethod_RSA_avx512_private() : gsMethod_RSA_avx2_private(); + +#elif(_IPP32E>=_IPP32E_L9) + m = IsFeatureEnabled(ippCPUID_ADCOX) ? gsMethod_RSA_gpr_private() : gsMethod_RSA_avx2_private(); + +#elif(_IPP>=_IPP_W7) + m = gsMethod_RSA_sse2_private(); + +#else + m = gsMethod_RSA_gpr_private(); +#endif + + if (!(m->loModulusBisize <= modulusBitSize && modulusBitSize <= m->hiModulusBisize)) + m = gsMethod_RSA_gpr_private(); + return m; +} + +static gsMethod_RSA* getDualExpMethod_RSA_private(int bitSizeDP, int bitSizeDQ) +{ + /* Dual exp kernels assume same bitsizes of private exponents */ + if ((bitSizeDP != bitSizeDQ) || (bitSizeDP == 0)) + return NULL; + +#if(_IPP32E>=_IPP32E_K1) + gsMethod_RSA* m = NULL; + m = gsMethod_RSA_avx512_crt_private(bitSizeDP); + if (m && m->dualExpFun) + return m; +#endif + + return NULL; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_getdefmeth_pub.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getdefmeth_pub.h new file mode 100644 index 000000000..85cf09eab --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getdefmeth_pub.h @@ -0,0 +1,50 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + + +/* get default method based on CPU's features */ +static gsMethod_RSA* getDefaultMethod_RSA_public(int modulusBitSize) +{ + gsMethod_RSA* m; + +#if(_IPP32E>=_IPP32E_K1) + m = IsFeatureEnabled(ippCPUID_AVX512IFMA) ? gsMethod_RSA_avx512_public() : gsMethod_RSA_avx2_public(); +#elif(_IPP32E>=_IPP32E_L9) + m = gsMethod_RSA_avx2_public(); +#elif(_IPP>=_IPP_W7) + m = gsMethod_RSA_sse2_public(); +#else + m = gsMethod_RSA_gpr_public(); +#endif + + if (!(m->loModulusBisize <= modulusBitSize && modulusBitSize <= m->hiModulusBisize)) + m = gsMethod_RSA_gpr_public(); + return m; +} \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_getprivatekeytype1.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getprivatekeytype1.c new file mode 100644 index 000000000..47d7022d3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getprivatekeytype1.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_GetPrivateKeyType1() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" + +/*F* +// Name: ippsRSA_GetPrivateKeyType1 +// +// Purpose: Extract key component from the key context +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// +// ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID() +// !BN_VALID_ID(pModulus) +// !BN_VALID_ID(pExp) +// +// ippStsIncompleteContextErr private key is not set up +// +// ippStsSizeErr BN_ROOM(pModulus), BN_ROOM(pExp) is not enough +// +// ippStsNoErr no error +// +// Parameters: +// pModulus (optional) pointer to the modulus (N) +// pExp (optional) pointer to the public exponent (E) +// pKey pointer to the key context +*F*/ +IPPFUN(IppStatus, ippsRSA_GetPrivateKeyType1,(IppsBigNumState* pModulus, + IppsBigNumState* pExp, + const IppsRSAPrivateKeyState* pKey)) +{ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(!RSA_PRV_KEY1_VALID_ID(pKey), ippStsContextMatchErr); + + if(pModulus) { + IPP_BADARG_RET(!BN_VALID_ID(pModulus), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + IPP_BADARG_RET(BN_ROOM(pModulus) rsaModulusBitSize +// MAX_RSA_SIZE < rsaModulusBitSize +// +// ippStsBadArgErr 0 >= privateExpBitSize +// privateExpBitSize > rsaModulusBitSize +// +// ippStsNoErr no error +// +// Parameters: +// rsaModulusBitSize bitsize of RSA modulus (bitsize of N) +// privateExpBitSize bitsize of private exponent (bitsize of D) +// pSize pointer to the size of RSA key context (bytes) +*F*/ + + +IPPFUN(IppStatus, ippsRSA_GetSizePrivateKeyType1,(int rsaModulusBitSize, int privateExpBitSize, int* pKeySize)) +{ + IPP_BAD_PTR1_RET(pKeySize); + IPP_BADARG_RET((MIN_RSA_SIZE>rsaModulusBitSize) || (rsaModulusBitSize>MAX_RSA_SIZE), ippStsNotSupportedModeErr); + IPP_BADARG_RET(!((0 (factorPbitSize+factorQbitSize) +// MAX_RSA_SIZE < (factorPbitSize+factorQbitSize) +// +// ippStsBadArgErr 0 >= factorPbitSize +// 0 >= factorQbitSize +// factorQbitSize > factorPbitSize +// +// ippStsNoErr no error +// +// Parameters: +// factorPbitSize bitsize of RSA modulus (bitsize of P) +// factorPbitSize bitsize of private exponent (bitsize of Q) +// pSize pointer to the size of RSA key context (bytes) +*F*/ + + +IPPFUN(IppStatus, ippsRSA_GetSizePrivateKeyType2,(int factorPbitSize, int factorQbitSize, int* pKeySize)) +{ + IPP_BAD_PTR1_RET(pKeySize); + IPP_BADARG_RET((factorPbitSize<=0) || (factorQbitSize<=0), ippStsBadArgErr); + //25.09.2019 gres: IPP_BADARG_RET((factorPbitSize < factorQbitSize), ippStsBadArgErr); + IPP_BADARG_RET((MIN_RSA_SIZE>(factorPbitSize+factorQbitSize) || (factorPbitSize+factorQbitSize)>MAX_RSA_SIZE), ippStsNotSupportedModeErr); + + *pKeySize = cpSizeof_RSA_privateKey2(factorPbitSize, factorQbitSize); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_getsizepublickey.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getsizepublickey.c new file mode 100644 index 000000000..ad0c1589e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_getsizepublickey.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_GetSizePublicKey() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" + +#include "pcprsa_sizeof_pubkey.h" + + +/*F* +// Name: ippsRSA_GetSizePublicKey +// +// Purpose: Returns context size (bytes) of RSA public key context +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSize +// +// ippStsNotSupportedModeErr MIN_RSA_SIZE > rsaModulusBitSize +// MAX_RSA_SIZE < rsaModulusBitSize +// +// ippStsBadArgErr 0 >= publicExpBitSize +// publicExpBitSize > rsaModulusBitSize +// +// ippStsNoErr no error +// +// Parameters: +// rsaModulusBitSize bitsize of RSA modulus (bitsize of N) +// publicExpBitSize bitsize of public exponent (bitsize of E) +// pSize pointer to the size of RSA key context (bytes) +*F*/ +IPPFUN(IppStatus, ippsRSA_GetSizePublicKey,(int rsaModulusBitSize, int publicExpBitSize, int* pKeySize)) +{ + IPP_BAD_PTR1_RET(pKeySize); + IPP_BADARG_RET((MIN_RSA_SIZE>rsaModulusBitSize) || (rsaModulusBitSize>MAX_RSA_SIZE), ippStsNotSupportedModeErr); + IPP_BADARG_RET(!((0=_IPP32E_L9) +#include "pcpngmontexpstuff_avx2.h" + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_avx2_private, (void)) +{ + static gsMethod_RSA m = { + RSA_AVX2_MIN_BITSIZE, RSA_AVX2_MAX_BITSIZE, /* RSA range */ + + /* private key exponentiation: private, window, avx2 */ + #if !defined(_USE_WINDOW_EXP_) + gsMontExpBinBuffer_avx2, + gsMontExpBin_BNU_sscm_avx2 + #else + gsMontExpWinBuffer_avx2, + gsMontExpWin_BNU_sscm_avx2 + #endif + , NULL + }; + return &m; +} +#endif /* _IPP32E_L9 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx2_public.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx2_public.c new file mode 100644 index 000000000..9a30735dd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx2_public.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// gsMethod_RSA_gpr_public() +// +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpngrsamethod.h" +#include "pcpngrsa.h" + +#if (_IPP32E>=_IPP32E_L9) +#include "pcpngmontexpstuff_avx2.h" + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_avx2_public, (void)) +{ + static gsMethod_RSA m = { + RSA_AVX2_MIN_BITSIZE, RSA_AVX2_MAX_BITSIZE, /* RSA range */ + + /* public key exponentiation: public, binary gpr */ + gsMontExpBinBuffer, + gsModExpBin_BNU, + NULL + }; + return &m; +} +#endif /* _IPP32E_L9 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx512_private.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx512_private.c new file mode 100644 index 000000000..b257c0985 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx512_private.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// gsMethod_RSA_gpr_private() +// +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpngrsamethod.h" +#include "pcpngrsa.h" + +#if (_IPP32E>=_IPP32E_K1) +#include "pcpngmontexpstuff_avx512.h" + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_avx512_private, (void)) +{ + static gsMethod_RSA m = { + RSA_AVX512_MIN_BITSIZE, RSA_AVX512_MAX_BITSIZE, /* RSA range */ + + /* private key exponentiation: private, window, avx512 */ + #if !defined(_USE_WINDOW_EXP_) + gsMontExpBinBuffer_avx512, + gsMontExpBin_BNU_sscm_avx512 + #else + gsMontExpWinBuffer_avx512, + gsMontExpWin_BNU_sscm_avx512 + #endif + , NULL + }; + return &m; +} + +#define RSA_DUAL_EXP_AVX512_MIN_BITSIZE 2048 +#define RSA_DUAL_EXP_AVX512_MAX_BITSIZE 4096 + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_avx512_crt_private, (int privExpBitSize)) { + static gsMethod_RSA m = { + RSA_DUAL_EXP_AVX512_MIN_BITSIZE, RSA_DUAL_EXP_AVX512_MAX_BITSIZE, /* RSA range */ + gsMontDualExpWinBuffer_avx512, + NULL, + NULL + }; + + if (IsFeatureEnabled(ippCPUID_AVX512IFMA)) { + ngMontDualExp dexpFunc = NULL; + switch (privExpBitSize) { + /* RSA 2k,3k,4k only supported */ + case 1024: + case 1536: + case 2048: + dexpFunc = gsMontDualExpWin_BNU_sscm_avx512; + break; + default: + dexpFunc = NULL; + } + m.dualExpFun = dexpFunc; + } + + return &m; +} +#endif /* _IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx512_public.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx512_public.c new file mode 100644 index 000000000..6106d3f2f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__avx512_public.c @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// gsMethod_RSA_gpr_public() +// +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpngrsamethod.h" +#include "pcpngrsa.h" + +#if (_IPP32E>=_IPP32E_K1) +#include "pcpngmontexpstuff_avx512.h" + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_avx512_public, (void)) +{ + static gsMethod_RSA m = { + RSA_AVX512_MIN_BITSIZE, RSA_AVX512_MAX_BITSIZE, /* RSA range */ + + /* public key exponentiation: public, binary, avx512 */ + gsMontExpBinBuffer_avx512, + gsMontExpBin_BNU_avx512, + NULL + }; + return &m; +} +#endif /* _IPP32E_L9 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__gpr_private.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__gpr_private.c new file mode 100644 index 000000000..dd93e7e90 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__gpr_private.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// gsMethod_RSA_gpr_private() +// +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpngrsamethod.h" +#include "pcpngrsa.h" + +/* +// definition of RSA exponentiation (PX/GPR based) +*/ + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_gpr_private, (void)) +{ + static gsMethod_RSA m = { + MIN_RSA_SIZE, MAX_RSA_SIZE, /* RSA range */ + + /* private key exponentiation: private, window, gpr */ + gsMontExpWinBuffer, + #if !defined(_USE_WINDOW_EXP_) + gsModExpBin_BNU_sscm + #else + gsModExpWin_BNU_sscm + #endif + , NULL + }; + return &m; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__gpr_public.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__gpr_public.c new file mode 100644 index 000000000..bed08e629 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__gpr_public.c @@ -0,0 +1,47 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// gsMethod_RSA_gpr_public() +// +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpngrsamethod.h" +#include "pcpngrsa.h" + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_gpr_public, (void)) +{ + static gsMethod_RSA m = { + MIN_RSA_SIZE, MAX_RSA_SIZE, /* RSA range */ + + /* public key exponentiation: public, binary, gpr */ + gsMontExpBinBuffer, + gsModExpBin_BNU, + NULL + }; + return &m; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__sse2_private.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__sse2_private.c new file mode 100644 index 000000000..f07b9cbc2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__sse2_private.c @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// gsMethod_RSA_sse2_private() +// +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpngrsamethod.h" +#include "pcpngrsa.h" + + +#if (_IPP>=_IPP_W7) +#include "pcpngmontexpstuff_sse2.h" + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_sse2_private, (void)) +{ + static gsMethod_RSA m = { + RSA_SSE2_MIN_BITSIZE, RSA_SSE2_MAX_BITSIZE, /* RSA range */ + + /* private key exponentiation: private, window, sse2 */ + #if !defined(_USE_WINDOW_EXP_) + gsMontExpBinBuffer_sse2, + gsMontExpBin_BNU_sscm_sse2 + #else + gsMontExpWinBuffer_sse2, + gsMontExpWin_BNU_sscm_sse2 + #endif + , NULL + }; + return &m; +} +#endif /* _IPP_W7 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__sse2_public.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__sse2_public.c new file mode 100644 index 000000000..e8deda826 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsmethod__sse2_public.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Montgomery engine preparation (GetSize/init/Set) +*/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// gsMethod_RSA_sse2_public() +// +*/ + +#include "owncp.h" +#include "pcpngmontexpstuff.h" +#include "gsscramble.h" +#include "pcpngrsamethod.h" +#include "pcpngrsa.h" + +#if (_IPP>=_IPP_W7) + +#include "pcpngmontexpstuff_sse2.h" + +IPP_OWN_DEFN (gsMethod_RSA*, gsMethod_RSA_sse2_public, (void)) +{ + static gsMethod_RSA m = { + RSA_SSE2_MIN_BITSIZE, RSA_SSE2_MAX_BITSIZE, /* RSA range */ + + /* public key exponentiation: public, binary, sse2 */ + gsMontExpBinBuffer_sse2, + gsMontExpBin_BNU_sse2, + NULL + }; + return &m; +} +#endif /* _IPP_W7 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsprv_cipher.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsprv_cipher.c new file mode 100644 index 000000000..5aef08ec3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsprv_cipher.c @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// gsRSAprv_cipher() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +#include "pcprsa_getdefmeth_priv.h" + +IPP_OWN_DEFN (void, gsRSAprv_cipher, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsRSAPrivateKeyState* pKey, BNU_CHUNK_T* pBuffer)) +{ + gsMethod_RSA* m = getDefaultMethod_RSA_private(RSA_PRV_KEY_BITSIZE_N(pKey)); + + BNU_CHUNK_T* dataY = BN_NUMBER(pY); + cpSize nsY = m->expFun(dataY, + BN_NUMBER(pX), BN_SIZE(pX), + RSA_PRV_KEY_D(pKey), RSA_PRV_KEY_BITSIZE_N(pKey), + RSA_PRV_KEY_NMONT(pKey), + pBuffer); + FIX_BNU(dataY, nsY); + BN_SIZE(pY) = nsY; + BN_SIGN(pY) = ippBigNumPOS; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsprv_cipher_crt.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsprv_cipher_crt.c new file mode 100644 index 000000000..1f75cc76c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gsprv_cipher_crt.c @@ -0,0 +1,159 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// gsRSAprv_cipher_crt() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +#include "pcprsa_getdefmeth_priv.h" + +/* CTE version of CRT based RSA decrypt */ +IPP_OWN_DEFN (void, gsRSAprv_cipher_crt, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsRSAPrivateKeyState* pKey, BNU_CHUNK_T* pBuffer)) +{ + const BNU_CHUNK_T* dataX = BN_NUMBER(pX); + cpSize nsX = BN_SIZE(pX); + + BNU_CHUNK_T* dataY = BN_NUMBER(pY); + + BNU_CHUNK_T* dataXp = BN_NUMBER(pY); + BNU_CHUNK_T* dataXq = BN_BUFFER(pY); + + /* P- and Q- montgometry engines */ + gsModEngine* pMontP = RSA_PRV_KEY_PMONT(pKey); + gsModEngine* pMontQ = RSA_PRV_KEY_QMONT(pKey); + cpSize nsP = MOD_LEN(pMontP); + cpSize nsQ = MOD_LEN(pMontQ); + cpSize bitSizeP = RSA_PRV_KEY_BITSIZE_P(pKey); + cpSize bitSizeQ = RSA_PRV_KEY_BITSIZE_Q(pKey); + cpSize bitSizeDP = bitSizeP; //BITSIZE_BNU(RSA_PRV_KEY_DP(pKey), nsP); /* bitsize of dP exp */ + cpSize bitSizeDQ = bitSizeQ; //BITSIZE_BNU(RSA_PRV_KEY_DQ(pKey), nsQ); /* bitsize of dQ exp */ + + /* Prefer dual exponentiation method if available */ + gsMethod_RSA* m = getDualExpMethod_RSA_private(bitSizeDP, bitSizeDQ); + if (m) { + ZEXPAND_COPY_BNU(pBuffer, nsQ+nsQ, dataX, nsX); + MOD_METHOD(pMontQ)->red(dataXq, pBuffer, pMontQ); + MOD_METHOD(pMontQ)->mul(dataXq, dataXq, MOD_MNT_R2(pMontQ), pMontQ); + + ZEXPAND_COPY_BNU(pBuffer, nsP+nsP, dataX, nsX); + MOD_METHOD(pMontP)->red(dataXp, pBuffer, pMontP); + MOD_METHOD(pMontP)->mul(dataXp, dataXp, MOD_MNT_R2(pMontP), pMontP); + + BNU_CHUNK_T* pDataX[2] = {0}; + pDataX[0] = dataXq; + pDataX[1] = dataXp; + + cpSize pSize[2] = {0}; + pSize[0] = nsQ; + pSize[1] = nsP; + + BNU_CHUNK_T* pPrvExp[2] = {0}; + pPrvExp[0] = RSA_PRV_KEY_DQ(pKey); + pPrvExp[1] = RSA_PRV_KEY_DP(pKey); + + gsModEngine* pMont[2] = {0}; + pMont[0] = pMontQ; + pMont[1] = pMontP; + + m->dualExpFun(pDataX, (const BNU_CHUNK_T**)pDataX, pSize, (const BNU_CHUNK_T**)pPrvExp, pMont, pBuffer); + } else { + /* compute xq = x^dQ mod Q */ + if (bitSizeP== bitSizeQ) { /* believe it's enough conditions for correct Mont application */ + ZEXPAND_COPY_BNU(pBuffer, nsQ+nsQ, dataX, nsX); + MOD_METHOD(pMontQ)->red(dataXq, pBuffer, pMontQ); + MOD_METHOD(pMontQ)->mul(dataXq, dataXq, MOD_MNT_R2(pMontQ), pMontQ); + } + else { + COPY_BNU(dataXq, dataX, nsX); + cpMod_BNU(dataXq, nsX, MOD_MODULUS(pMontQ), nsQ); + } + + m = getDefaultMethod_RSA_private(bitSizeDQ); + m->expFun(dataXq, dataXq, nsQ, RSA_PRV_KEY_DQ(pKey), bitSizeDQ, pMontQ, pBuffer); + + /* compute xp = x^dP mod P */ + if (bitSizeP== bitSizeQ) { /* believe it's enough conditions for correct Mont application */ + ZEXPAND_COPY_BNU(pBuffer, nsP+nsP, dataX, nsX); + MOD_METHOD(pMontP)->red(dataXp, pBuffer, pMontP); + MOD_METHOD(pMontP)->mul(dataXp, dataXp, MOD_MNT_R2(pMontP), pMontP); + } + else { + COPY_BNU(dataXp, dataX, nsX); + cpMod_BNU(dataXp, nsX, MOD_MODULUS(pMontP), nsP); + } + + m = getDefaultMethod_RSA_private(bitSizeDP); + m->expFun(dataXp, dataXp, nsP, RSA_PRV_KEY_DP(pKey), bitSizeDP, pMontP, pBuffer); + } + + /* + // recombination + */ + /* xq = xq mod P + must be sure that xq in the same residue domain as xp + because of following (xp-xq) mod P operation + */ + if (bitSizeP == bitSizeQ) { /* believe it's enough conditions for correct Mont application */ + ZEXPAND_COPY_BNU(pBuffer, nsP+nsP, dataXq, nsQ); + //MOD_METHOD(pMontP)->red(pBuffer, pBuffer, pMontP); + //MOD_METHOD(pMontP)->mul(pBuffer, pBuffer, MOD_MNT_R2(pMontP), pMontP); + MOD_METHOD(pMontP)->sub(pBuffer, pBuffer, MOD_MODULUS(pMontP), pMontP); + /* xp = (xp - xq) mod P */ + MOD_METHOD(pMontP)->sub(dataXp, dataXp, pBuffer, pMontP); + } + else { + COPY_BNU(pBuffer, dataXq, nsQ); + { + cpSize nsQP = cpMod_BNU(pBuffer, nsQ, MOD_MODULUS(pMontP), nsP); + BNU_CHUNK_T cf = cpSub_BNU(dataXp, dataXp, pBuffer, nsQP); + if(nsP-nsQP) + cf = cpDec_BNU(dataXp+nsQP, dataXp + nsQP, (nsP-nsQP), cf); + if (cf) + cpAdd_BNU(dataXp, dataXp, MOD_MODULUS(pMontP), nsP); + } + } + + /* xp = xp*qInv mod P */ + /* convert invQ into Montgomery domain */ + MOD_METHOD(pMontP)->encode(pBuffer, RSA_PRV_KEY_INVQ(pKey), (gsModEngine*)pMontP); + /* and multiply xp *= mont(invQ) mod P */ + MOD_METHOD(pMontP)->mul(dataXp, dataXp, pBuffer, pMontP); + + /* Y = xq + xp*Q */ + cpMul_BNU_school(pBuffer, dataXp, nsP, MOD_MODULUS(pMontQ), nsQ); + { + BNU_CHUNK_T cf = cpAdd_BNU(dataY, pBuffer, dataXq, nsQ); + cpInc_BNU(dataY + nsQ, pBuffer + nsQ, nsP, cf); + } + + nsX = nsP + nsQ; + FIX_BNU(dataY, nsX); + BN_SIZE(pY) = nsX; + BN_SIGN(pY) = ippBigNumPOS; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_gspub_cipher.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gspub_cipher.c new file mode 100644 index 000000000..59948ffb2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_gspub_cipher.c @@ -0,0 +1,49 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// gsRSApub_cipher() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" +#include "pcpngrsamethod.h" + +#include "pcprsa_getdefmeth_pub.h" + +IPP_OWN_DEFN (void, gsRSApub_cipher, (IppsBigNumState* pY, const IppsBigNumState* pX, const IppsRSAPublicKeyState* pKey, BNU_CHUNK_T* pBuffer)) +{ + gsMethod_RSA* m = getDefaultMethod_RSA_public(RSA_PRV_KEY_BITSIZE_N(pKey)); + + BNU_CHUNK_T* dataY = BN_NUMBER(pY); + cpSize nsY = m->expFun(dataY, + BN_NUMBER(pX), BN_SIZE(pX), + RSA_PUB_KEY_E(pKey), RSA_PUB_KEY_BITSIZE_E(pKey), + RSA_PUB_KEY_NMONT(pKey), + pBuffer); + FIX_BNU(dataY, nsY); + BN_SIZE(pY) = nsY; + BN_SIGN(pY) = ippBigNumPOS; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_initprivatekeytype1.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_initprivatekeytype1.c new file mode 100644 index 000000000..c21eb0755 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_initprivatekeytype1.c @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_InitPrivateKeyType1() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" + +#include "pcprsa_sizeof_privkey1.h" + +/*F* +// Name: ippsRSA_InitPrivateKeyType1 +// +// Purpose: Init RSA private key context +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// +// ippStsNotSupportedModeErr MIN_RSA_SIZE > rsaModulusBitSize +// MAX_RSA_SIZE < rsaModulusBitSize +// +// ippStsBadArgErr 0 >= privateExpBitSize +// privateExpBitSize > rsaModulusBitSize +// +// ippStsMemAllocErr keyCtxSize is not enough for operation +// +// ippStsNoErr no error +// +// Parameters: +// rsaModulusBitSize bitsize of RSA modulus (bitsize of N) +// privateExpBitSize bitsize of private exponent (bitsize of D) +// pKey pointer to the key context +// keyCtxSize size of memmory accosizted with key comtext +*F*/ + +IPPFUN(IppStatus, ippsRSA_InitPrivateKeyType1,(int rsaModulusBitSize, int privateExpBitSize, + IppsRSAPrivateKeyState* pKey, int keyCtxSize)) +{ + IPP_BAD_PTR1_RET(pKey); + + IPP_BADARG_RET((MIN_RSA_SIZE>rsaModulusBitSize) || (rsaModulusBitSize>MAX_RSA_SIZE), ippStsNotSupportedModeErr); + IPP_BADARG_RET(!((0 (factorPbitSize+factorQbitSize) +// MAX_RSA_SIZE < (factorPbitSize+factorQbitSize) +// +// ippStsBadArgErr 0 >= factorPbitSize +// 0 >= factorQbitSize +// factorQbitSize > factorPbitSize +// +// ippStsMemAllocErr keyCtxSize is not enough for operation +// +// ippStsNoErr no error +// +// Parameters: +// factorPbitSize bitsize of RSA modulus (bitsize of P) +// factorQbitSize bitsize of private exponent (bitsize of Q) +// pKey pointer to the key context +// keyCtxSize size of memmory accosizted with key comtext +*F*/ + +IPPFUN(IppStatus, ippsRSA_InitPrivateKeyType2,(int factorPbitSize, int factorQbitSize, + IppsRSAPrivateKeyState* pKey, int keyCtxSize)) +{ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET((factorPbitSize<=0) || (factorQbitSize<=0), ippStsBadArgErr); + //25.09.2019 gres: IPP_BADARG_RET((factorPbitSize < factorQbitSize), ippStsBadArgErr); + IPP_BADARG_RET((MIN_RSA_SIZE>(factorPbitSize+factorQbitSize) || (factorPbitSize+factorQbitSize)>MAX_RSA_SIZE), ippStsNotSupportedModeErr); + + /* test available size of context buffer */ + IPP_BADARG_RET(keyCtxSize rsaModulusBitSize +// MAX_RSA_SIZE < rsaModulusBitSize +// +// ippStsBadArgErr 0 >= publicExpBitSize +// publicExpBitSize > rsaModulusBitSize +// +// ippStsMemAllocErr keyCtxSize is not enough for operation +// +// ippStsNoErr no error +// +// Parameters: +// rsaModulusBitSize bitsize of RSA modulus (bitsize of N) +// publicExpBitSize bitsize of public exponent (bitsize of E) +// pKey pointer to the key context +// keyCtxSize size of memmory accosizted with key comtext +*F*/ +IPPFUN(IppStatus, ippsRSA_InitPublicKey,(int rsaModulusBitSize, int publicExpBitSize, + IppsRSAPublicKeyState* pKey, int keyCtxSize)) +{ + IPP_BAD_PTR1_RET(pKey); + + IPP_BADARG_RET((MIN_RSA_SIZE>rsaModulusBitSize) || (rsaModulusBitSize>MAX_RSA_SIZE), ippStsNotSupportedModeErr); + IPP_BADARG_RET(!((0hashAlgId, ippStsNotSupportedModeErr); + IPP_BADARG_RET(ippHashAlg_SM3 == pMethod->hashAlgId, ippStsNotSupportedModeErr); + + /* use aligned public key context if defined */ + if (*pPubKey) { + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(*pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(*pPubKey), ippStsIncompleteContextErr); + } + + /* test data pointer */ + IPP_BAD_PTR2_RET(pMsg, pSign); + /* test length */ + IPP_BADARG_RET(msgLen < 0, ippStsLengthErr); + + return ippStsNoErr; +} + +// Check all the ippsRSAVerify_PKCS1v15_rmf parameters, set valid=0, align pKey pointer +__INLINE IppStatus SingleVerifyPkcs1v15RmfPreproc(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, int* pIsValid, + const IppsRSAPublicKeyState** pKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer) +{ + /* test public key context */ + IPP_BAD_PTR3_RET(*pKey, pScratchBuffer, pMethod); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(*pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(*pKey), ippStsIncompleteContextErr); + + /* test hash algorithm ID */ + IPP_BADARG_RET(ippHashAlg_Unknown == pMethod->hashAlgId, ippStsNotSupportedModeErr); + IPP_BADARG_RET(ippHashAlg_SM3 == pMethod->hashAlgId, ippStsNotSupportedModeErr); + + /* test data pointer */ + IPP_BAD_PTR3_RET(pMsg, pSign, pIsValid); + /* test length */ + IPP_BADARG_RET(msgLen < 0, ippStsLengthErr); + + *pIsValid = 0; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_pss_preproc.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_pss_preproc.h new file mode 100644 index 000000000..cb5d4c03c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_pss_preproc.h @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +#include "owncp.h" +#include "pcphash_rmf.h" + +// Check all the ippsRSASign_PSS_rmf parameters and align pPrvKey, pPubKey pointers +__INLINE IppStatus SingleSignPssRmfPreproc(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSalt, int saltLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState** pPrvKey, + const IppsRSAPublicKeyState** pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer) +{ + /* test message length */ + IPP_BADARG_RET((msgLen < 0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + /* test data pointer */ + IPP_BAD_PTR2_RET(pSign, pMethod); + + /* test salt length and salt pointer */ + IPP_BADARG_RET(saltLen < 0, ippStsLengthErr); + IPP_BADARG_RET((saltLen && !pSalt), ippStsNullPtrErr); + + /* test private key context */ + IPP_BAD_PTR2_RET(*pPrvKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(*pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(*pPrvKey), ippStsIncompleteContextErr); + + /* use aligned public key context if defined */ + if (*pPubKey) { + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(*pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(*pPubKey), ippStsIncompleteContextErr); + } + + return ippStsNoErr; +} + +// Check all the ippsRSAVerify_PSS_rmf parameters, set valid=0, align pKey pointer +__INLINE IppStatus SingleVerifyPssRmfPreproc(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, + int* pIsValid, + const IppsRSAPublicKeyState** pKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer) +{ + /* test message length */ + IPP_BADARG_RET((msgLen < 0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + /* test data pointer */ + IPP_BAD_PTR3_RET(pSign, pIsValid, pMethod); + + /* test public key context */ + IPP_BAD_PTR2_RET(*pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(*pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(*pKey), ippStsIncompleteContextErr); + + *pIsValid = 0; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_setprivatekeytype1.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_setprivatekeytype1.c new file mode 100644 index 000000000..fa374e4be --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_setprivatekeytype1.c @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_SetPrivateKeyType1() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" + +/*F* +// Name: ippsRSA_SetPrivateKeyType1 +// +// Purpose: Set up the RSA private key +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pModulus +// NULL == pPrivateExp +// NULL == pKey +// +// ippStsContextMatchErr !BN_VALID_ID(pModulus) +// !BN_VALID_ID(pPrivateExp) +// !RSA_PRV_KEY_VALID_ID() +// +// ippStsOutOfRangeErr 0 >= pModulus +// 0 >= pPrivateExp +// +// ippStsSizeErr bitsize(pModulus) exceeds requested value +// bitsize(pPrivateExp) exceeds requested value +// +// ippStsNoErr no error +// +// Parameters: +// pModulus pointer to modulus (N) +// pPrivateExp pointer to public exponent (D) +// pKey pointer to the key context +*F*/ +IPPFUN(IppStatus, ippsRSA_SetPrivateKeyType1,(const IppsBigNumState* pModulus, + const IppsBigNumState* pPrivateExp, + IppsRSAPrivateKeyState* pKey)) +{ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(!RSA_PRV_KEY1_VALID_ID(pKey), ippStsContextMatchErr); + + IPP_BAD_PTR1_RET(pModulus); + IPP_BADARG_RET(!BN_VALID_ID(pModulus), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pModulus)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pModulus), BN_SIZE(pModulus)) > RSA_PRV_KEY_MAXSIZE_N(pKey), ippStsSizeErr); + + IPP_BAD_PTR1_RET(pPrivateExp); + IPP_BADARG_RET(!BN_VALID_ID(pPrivateExp), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pPrivateExp)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pPrivateExp), BN_SIZE(pPrivateExp)) > RSA_PRV_KEY_MAXSIZE_D(pKey), ippStsSizeErr); + + { + /* store D */ + ZEXPAND_COPY_BNU(RSA_PRV_KEY_D(pKey), BITS_BNU_CHUNK(RSA_PRV_KEY_MAXSIZE_D(pKey)), BN_NUMBER(pPrivateExp), BN_SIZE(pPrivateExp)); + + /* setup montgomery engine */ + gsModEngineInit(RSA_PRV_KEY_NMONT(pKey), (Ipp32u*)BN_NUMBER(pModulus), cpBN_bitsize(pModulus), MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + + RSA_PRV_KEY_BITSIZE_N(pKey) = cpBN_bitsize(pModulus); + RSA_PRV_KEY_BITSIZE_D(pKey) = cpBN_bitsize(pPrivateExp); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_setprivatekeytype2.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_setprivatekeytype2.c new file mode 100644 index 000000000..04bcc83c2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_setprivatekeytype2.c @@ -0,0 +1,142 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_SetPrivateKeyType2() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" + +/*F* +// Name: ippsRSA_SetPrivateKeyType2 +// +// Purpose: Set up the RSA private key +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pFactorP, NULL == pFactorQ +// NULL == pCrtExpP, NULL == pCrtExpQ +// NULL == pInverseQ +// NULL == pKey +// +// ippStsContextMatchErr !BN_VALID_ID(pFactorP), !BN_VALID_ID(pFactorQ) +// !BN_VALID_ID(pCrtExpP), !BN_VALID_ID(pCrtExpQ) +// !BN_VALID_ID(pInverseQ) +// !RSA_PRV_KEY_VALID_ID() +// +// ippStsOutOfRangeErr 0 >= pFactorP, 0 >= pFactorQ +// 0 >= pCrtExpP, 0 >= pCrtExpQ +// 0 >= pInverseQ +// +// ippStsSizeErr bitsize(pFactorP) exceeds requested value +// bitsize(pFactorQ) exceeds requested value +// bitsize(pCrtExpP) > bitsize(pFactorP) +// bitsize(pCrtExpQ) > bitsize(pFactorQ) +// bitsize(pInverseQ) > bitsize(pFactorP) +// +// ippStsNoErr no error +// +// Parameters: +// pFactorP, pFactorQ pointer to the RSA modulus (N) prime factors +// pCrtExpP, pCrtExpQ pointer to CTR's exponent +// pInverseQ 1/Q mod P +// pKey pointer to the key context +*F*/ +IPPFUN(IppStatus, ippsRSA_SetPrivateKeyType2,(const IppsBigNumState* pFactorP, + const IppsBigNumState* pFactorQ, + const IppsBigNumState* pCrtExpP, + const IppsBigNumState* pCrtExpQ, + const IppsBigNumState* pInverseQ, + IppsRSAPrivateKeyState* pKey)) +{ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(!RSA_PRV_KEY2_VALID_ID(pKey), ippStsContextMatchErr); + + IPP_BAD_PTR1_RET(pFactorP); + IPP_BADARG_RET(!BN_VALID_ID(pFactorP), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pFactorP)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pFactorP), BN_SIZE(pFactorP)) > RSA_PRV_KEY_BITSIZE_P(pKey), ippStsSizeErr); + + IPP_BAD_PTR1_RET(pFactorQ); + IPP_BADARG_RET(!BN_VALID_ID(pFactorQ), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pFactorQ)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pFactorQ), BN_SIZE(pFactorQ)) > RSA_PRV_KEY_BITSIZE_Q(pKey), ippStsSizeErr); + + /* let P>Q */ + //IPP_BADARG_RET(0>=cpBN_cmp(pFactorP,pFactorQ), ippStsBadArgErr); + + IPP_BAD_PTR1_RET(pCrtExpP); + IPP_BADARG_RET(!BN_VALID_ID(pCrtExpP), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pCrtExpP)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pCrtExpP), BN_SIZE(pCrtExpP)) > RSA_PRV_KEY_BITSIZE_P(pKey), ippStsSizeErr); + + IPP_BAD_PTR1_RET(pCrtExpQ); + IPP_BADARG_RET(!BN_VALID_ID(pCrtExpQ), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pCrtExpQ)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pCrtExpQ), BN_SIZE(pCrtExpQ)) > RSA_PRV_KEY_BITSIZE_Q(pKey), ippStsSizeErr); + + IPP_BAD_PTR1_RET(pInverseQ); + IPP_BADARG_RET(!BN_VALID_ID(pInverseQ), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pInverseQ)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pInverseQ), BN_SIZE(pInverseQ)) > RSA_PRV_KEY_BITSIZE_P(pKey), ippStsSizeErr); + + /* set bitsize(N) = 0, so the key contex is not ready */ + RSA_PRV_KEY_BITSIZE_N(pKey) = 0; + RSA_PRV_KEY_BITSIZE_D(pKey) = 0; + + /* setup montgomery engine P */ + gsModEngineInit(RSA_PRV_KEY_PMONT(pKey), (Ipp32u*)BN_NUMBER(pFactorP), cpBN_bitsize(pFactorP), MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + /* setup montgomery engine Q */ + gsModEngineInit(RSA_PRV_KEY_QMONT(pKey), (Ipp32u*)BN_NUMBER(pFactorQ), cpBN_bitsize(pFactorQ), MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + + /* actual size of key components */ + RSA_PRV_KEY_BITSIZE_P(pKey) = cpBN_bitsize(pFactorP); + RSA_PRV_KEY_BITSIZE_Q(pKey) = cpBN_bitsize(pFactorQ); + + /* store CTR's exp dp */ + ZEXPAND_COPY_BNU(RSA_PRV_KEY_DP(pKey), BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_P(pKey)), BN_NUMBER(pCrtExpP), BN_SIZE(pCrtExpP)); + /* store CTR's exp dq */ + ZEXPAND_COPY_BNU(RSA_PRV_KEY_DQ(pKey), BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_Q(pKey)), BN_NUMBER(pCrtExpQ), BN_SIZE(pCrtExpQ)); + /* store CTR's invQ */ + ZEXPAND_COPY_BNU(RSA_PRV_KEY_INVQ(pKey), BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_P(pKey)), BN_NUMBER(pInverseQ), BN_SIZE(pInverseQ)); + + /* setup montgomery engine N = P*Q */ + { + BNU_CHUNK_T* pN = MOD_MODULUS(RSA_PRV_KEY_NMONT(pKey)); + cpSize nsN = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_P(pKey) + RSA_PRV_KEY_BITSIZE_Q(pKey)); + + cpMul_BNU_school(pN, + BN_NUMBER(pFactorP), BN_SIZE(pFactorP), + BN_NUMBER(pFactorQ), BN_SIZE(pFactorQ)); + + gsModEngineInit(RSA_PRV_KEY_NMONT(pKey), (Ipp32u*)MOD_MODULUS(RSA_PRV_KEY_NMONT(pKey)), + RSA_PRV_KEY_BITSIZE_P(pKey) + RSA_PRV_KEY_BITSIZE_Q(pKey), MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + + FIX_BNU(pN, nsN); + RSA_PRV_KEY_BITSIZE_N(pKey) = BITSIZE_BNU(pN, nsN); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_setpublickey.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_setpublickey.c new file mode 100644 index 000000000..f3030deed --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_setpublickey.c @@ -0,0 +1,92 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_SetPublicKey() +// +*/ + +#include "owncp.h" +#include "pcpbn.h" +#include "pcpngrsa.h" + +/*F* +// Name: ippsRSA_SetPublicKey +// +// Purpose: Set up the RSA public key +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// NULL == pPublicExp +// NULL == pKey +// +// ippStsContextMatchErr !BN_VALID_ID(pModulus) +// !BN_VALID_ID(pPublicExp) +// !RSA_PUB_KEY_VALID_ID() +// +// ippStsOutOfRangeErr 0 >= pModulus +// 0 >= pPublicExp +// +// ippStsSizeErr bitsize(pModulus) exceeds requested value +// bitsize(pPublicExp) exceeds requested value +// +// ippStsNoErr no error +// +// Parameters: +// pModulus pointer to modulus (N) +// pPublicExp pointer to public exponent (E) +// pKey pointer to the key context +*F*/ +IPPFUN(IppStatus, ippsRSA_SetPublicKey,(const IppsBigNumState* pModulus, + const IppsBigNumState* pPublicExp, + IppsRSAPublicKeyState* pKey)) +{ + IPP_BAD_PTR1_RET(pKey); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + + IPP_BAD_PTR1_RET(pModulus); + IPP_BADARG_RET(!BN_VALID_ID(pModulus), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pModulus)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pModulus), BN_SIZE(pModulus)) > RSA_PUB_KEY_MAXSIZE_N(pKey), ippStsSizeErr); + + IPP_BAD_PTR1_RET(pPublicExp); + IPP_BADARG_RET(!BN_VALID_ID(pPublicExp), ippStsContextMatchErr); + IPP_BADARG_RET(!(0 < cpBN_tst(pPublicExp)), ippStsOutOfRangeErr); + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pPublicExp), BN_SIZE(pPublicExp)) > RSA_PUB_KEY_MAXSIZE_E(pKey), ippStsSizeErr); + + { + RSA_PUB_KEY_BITSIZE_N(pKey) = 0; + RSA_PUB_KEY_BITSIZE_E(pKey) = 0; + + /* store E */ + ZEXPAND_COPY_BNU(RSA_PUB_KEY_E(pKey), BITS_BNU_CHUNK(RSA_PUB_KEY_MAXSIZE_E(pKey)), BN_NUMBER(pPublicExp), BN_SIZE(pPublicExp)); + + /* setup montgomery engine */ + gsModEngineInit(RSA_PUB_KEY_NMONT(pKey), (Ipp32u*)BN_NUMBER(pModulus), cpBN_bitsize(pModulus), MOD_ENGINE_RSA_POOL_SIZE, gsModArithRSA()); + + RSA_PUB_KEY_BITSIZE_N(pKey) = cpBN_bitsize(pModulus); + RSA_PUB_KEY_BITSIZE_E(pKey) = cpBN_bitsize(pPublicExp); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_privkey1.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_privkey1.h new file mode 100644 index 000000000..1adea98e6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_privkey1.h @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +*/ + +static int cpSizeof_RSA_privateKey1(int rsaModulusBitSize, int privateExpBitSize) +{ + int prvExpLen = BITS_BNU_CHUNK(privateExpBitSize); + int modulusLen32 = BITS2WORD32_SIZE(rsaModulusBitSize); + int montNsize; + rsaMontExpGetSize(modulusLen32, &montNsize); + + return (Ipp32s)sizeof(IppsRSAPrivateKeyState) + + prvExpLen * (Ipp32s)sizeof(BNU_CHUNK_T) + + (Ipp32s)sizeof(BNU_CHUNK_T) - 1 + + montNsize; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_privkey2.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_privkey2.h new file mode 100644 index 000000000..7e8de54e6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_privkey2.h @@ -0,0 +1,48 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +*/ + +static int cpSizeof_RSA_privateKey2(int factorPbitSize, int factorQbitSize) +{ + int factorPlen = BITS_BNU_CHUNK(factorPbitSize); + int factorQlen = BITS_BNU_CHUNK(factorQbitSize); + int factorPlen32 = BITS2WORD32_SIZE(factorPbitSize); + int factorQlen32 = BITS2WORD32_SIZE(factorQbitSize); + int rsaModulusLen32 = BITS2WORD32_SIZE(factorPbitSize + factorQbitSize); + int montPsize; + int montQsize; + int montNsize; + rsaMontExpGetSize(factorPlen32, &montPsize); + rsaMontExpGetSize(factorQlen32, &montQsize); + rsaMontExpGetSize(rsaModulusLen32, &montNsize); + + return (Ipp32s)sizeof(IppsRSAPrivateKeyState) + + factorPlen * (Ipp32s)sizeof(BNU_CHUNK_T) /* dp slot */ + + factorQlen * (Ipp32s)sizeof(BNU_CHUNK_T) /* dq slot */ + + factorPlen * (Ipp32s)sizeof(BNU_CHUNK_T) /* qinv slot */ + + (Ipp32s)sizeof(BNU_CHUNK_T) - 1 /* alignment */ + + montPsize + + montQsize + + montNsize; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_pubkey.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_pubkey.h new file mode 100644 index 000000000..7fcbe1c28 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_sizeof_pubkey.h @@ -0,0 +1,38 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +*/ + +/* compute size of RSA public key context */ +static int cpSizeof_RSA_publicKey(int rsaModulusBitSize, int publicExpBitSize) +{ + int pubExpLen = BITS_BNU_CHUNK(publicExpBitSize); + int modulusLen32 = BITS2WORD32_SIZE(rsaModulusBitSize); + int montNsize; + rsaMontExpGetSize(modulusLen32, &montNsize); + + return (Ipp32s)sizeof(IppsRSAPublicKeyState) + + pubExpLen*(Ipp32s)sizeof(BNU_CHUNK_T) + + (Ipp32s)sizeof(BNU_CHUNK_T)-1 /* alignment */ + + montNsize; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_validatekeys.c b/plugin/ippcp/library/src/sources/ippcp/pcprsa_validatekeys.c new file mode 100644 index 000000000..34f062cb0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_validatekeys.c @@ -0,0 +1,355 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA Functions +// +// Contents: +// ippsRSA_ValidateKeys() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpbn.h" +#include "pcpprimeg.h" +#include "pcpprng.h" +#include "pcpngrsa.h" + +#include "pcpprime_isco.h" +#include "pcpprime_isprob.h" + +/*F* +// Name: ippsRSA_ValidateKeys +// +// Purpose: Validate RSA keys +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pPublicKey +// NULL == pPrivateKeyType2 +// NULL == pPrivateKeyType1 +// NULL == pBuffer +// NULL == pPrimeGen +// NULL == rndFunc +// NULL == pResult +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID(pPublicKey) +// !RSA_PRV_KEY2_VALID_ID(pPrivateKeyType2) +// !RSA_PRV_KEY1_VALID_ID(pPrivateKeyType1) +// !PRIME_VALID_ID(pPrimeGen) +// +// ippStsIncompleteContextErr public and.or private key is not set up +// +// ippStsSizeErr PRIME_MAXBITSIZE(pPrimeGen) < factorPbitSize +// +// ippStsBadArgErr nTrials < 1 +// +// ippStsNoErr no error +// +// Parameters: +// pResult pointer to the validation result +// pPublicKey pointer to the public key context +// pPrivateKeyType2 pointer to the private key type2 context +// pPrivateKeyType1 (optional) pointer to the private key type1 context +// pBuffer pointer to the temporary buffer +// nTrials parameter of Miller-Rabin Test +// pPrimeGen pointer to the Prime generator context +// rndFunc external PRNG +// pRndParam pointer to the external PRNG parameters +*F*/ +/* +// make sure D*E = 1 mod(phi(P,Q)) +// where phi(P,Q) = (P-1)*(Q-1) +*/ +static +int isValidPriv1_classic(const BNU_CHUNK_T* pN, int nsN, + const BNU_CHUNK_T* pE, int nsE, + const BNU_CHUNK_T* pD, int nsD, + const BNU_CHUNK_T* pFactorP, int nsP, + const BNU_CHUNK_T* pFactorQ, int nsQ, + BNU_CHUNK_T* pBuffer) +{ + BNU_CHUNK_T* pPhi = pBuffer; + BNU_CHUNK_T* pProduct = pPhi + nsN; + BNU_CHUNK_T c = cpSub_BNU(pPhi, pN, pFactorP, nsP); + int prodLen; + if (nsN>1) cpDec_BNU(pPhi + nsP, pN + nsP, nsQ, c); + c = cpSub_BNU(pPhi, pPhi, pFactorQ, nsQ); + if (nsN>1) cpDec_BNU(pPhi + nsQ, pPhi + nsQ, nsP, c); + cpInc_BNU(pPhi, pPhi, nsP + nsQ, 1); + + cpMul_BNU_school(pProduct, pE, nsE, pD, nsD); + prodLen = cpMod_BNU(pProduct, nsE + nsD, pPhi, nsN); + + return 1 == cpEqu_BNU_CHUNK(pProduct, prodLen, 1) ? IPP_IS_VALID : IPP_IS_INVALID; +} + +/* +// make sure D*E = 1 mod(lcm(P-1,Q-1)) +// where lcm(P-1,Q-1) = (P-1)*(Q-1)/gcd(P-1,Q-1) +*/ +static +int isValidPriv1_rsa(const BNU_CHUNK_T* pN, int nsN, + const BNU_CHUNK_T* pE, int nsE, + const BNU_CHUNK_T* pD, int nsD, + BNU_CHUNK_T* pFactorP, int nsP, + BNU_CHUNK_T* pFactorQ, int nsQ, + BNU_CHUNK_T* pBuffer) +{ + __ALIGN8 IppsBigNumState tmpBN1; + __ALIGN8 IppsBigNumState tmpBN2; + __ALIGN8 IppsBigNumState tmpBN3; + + BNU_CHUNK_T* pProduct = pBuffer; + BNU_CHUNK_T* pGcd = pProduct + (nsN + 1); + BNU_CHUNK_T* pLcm; + int nsLcm; + int prodLen; + pBuffer = pGcd + (nsP + 1) * 2; + + /* P = P-1 and Q = Q-1 */ + pFactorP[0]--; + pFactorQ[0]--; + + /* compute product (P-1)*(Q-1) = P*Q -P -Q +1 = N -(P-1) -(Q-1) -1 */ + { + BNU_CHUNK_T c = cpSub_BNU(pProduct, pN, pFactorP, nsP); + if (nsN>1) cpDec_BNU(pProduct + nsP, pN + nsP, nsQ, c); + c = cpSub_BNU(pProduct, pProduct, pFactorQ, nsQ); + if (nsN>1) cpDec_BNU(pProduct + nsQ, pProduct + nsQ, nsP, c); + cpDec_BNU(pProduct, pProduct, nsN, 1); + } + + /* compute gcd(p-1, q-1) */ + BN_Make(pGcd, pGcd + nsP + 1, nsP, &tmpBN1); /* BN(gcd) */ + BN_SIZE(&tmpBN1) = nsP; + BN_Make(pFactorP, pBuffer, nsP, &tmpBN2); /* BN(P-1) */ + BN_SIZE(&tmpBN2) = nsP; + BN_Make(pFactorQ, pBuffer + nsP + 1, nsQ, &tmpBN3); /* BN(Q-1) */ + BN_SIZE(&tmpBN3) = nsQ; + ippsGcd_BN(&tmpBN2, &tmpBN3, &tmpBN1); + + /* compute lcm(p-1, q-1) = (p-1)(q-1)/gcd(p-1, q-1) */ + pLcm = pBuffer; + cpDiv_BNU(pLcm, &nsLcm, pProduct, nsN, pGcd, BN_SIZE(&tmpBN1)); + + /* test E*D = 1 mod lcm */ + cpMul_BNU_school(pProduct, pE, nsE, pD, nsD); + prodLen = cpMod_BNU(pProduct, nsE + nsD, pLcm, nsLcm); + + /* restore P and Q */ + pFactorP[0]++; + pFactorQ[0]++; + + return 1 == cpEqu_BNU_CHUNK(pProduct, prodLen, 1) ? IPP_IS_VALID : IPP_IS_INVALID; +} + +IPPFUN(IppStatus, ippsRSA_ValidateKeys,(int* pResult, + const IppsRSAPublicKeyState* pPublicKey, + const IppsRSAPrivateKeyState* pPrivateKeyType2, + const IppsRSAPrivateKeyState* pPrivateKeyType1, /*optional */ + Ipp8u* pBuffer, + int nTrials, + IppsPrimeState* pPrimeGen, /*NULL */ + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR1_RET(pPublicKey); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pPublicKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pPublicKey), ippStsIncompleteContextErr); + + IPP_BAD_PTR1_RET(pPrivateKeyType2); + IPP_BADARG_RET(!RSA_PRV_KEY2_VALID_ID(pPrivateKeyType2), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrivateKeyType2), ippStsIncompleteContextErr); + + if(pPrivateKeyType1) { /* pPrivateKeyType1 is optional */ + IPP_BADARG_RET(!RSA_PRV_KEY1_VALID_ID(pPrivateKeyType1), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrivateKeyType1), ippStsIncompleteContextErr); + } + + IPP_BAD_PTR3_RET(pResult, pBuffer, rndFunc); + + IPP_UNREFERENCED_PARAMETER(pPrimeGen); + + { + /* E key component */ + BNU_CHUNK_T* pExpE = RSA_PUB_KEY_E(pPublicKey); + cpSize nsE = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_E(pPublicKey)); + + /* N key component */ + BNU_CHUNK_T* pN = MOD_MODULUS(RSA_PUB_KEY_NMONT(pPublicKey)); + cpSize nsN = MOD_LEN(RSA_PUB_KEY_NMONT(pPublicKey)); + + /* P, Q, dP, dQ, invQ key components */ + gsModEngine* pMontP = RSA_PRV_KEY_PMONT(pPrivateKeyType2); + gsModEngine* pMontQ = RSA_PRV_KEY_QMONT(pPrivateKeyType2); + BNU_CHUNK_T* pFactorP= MOD_MODULUS(pMontP); + BNU_CHUNK_T* pFactorQ= MOD_MODULUS(pMontQ); + BNU_CHUNK_T* pExpDp = RSA_PRV_KEY_DP(pPrivateKeyType2); + BNU_CHUNK_T* pExpDq = RSA_PRV_KEY_DQ(pPrivateKeyType2); + BNU_CHUNK_T* pInvQ = RSA_PRV_KEY_INVQ(pPrivateKeyType2); + + int factorPbitSize = RSA_PRV_KEY_BITSIZE_P(pPrivateKeyType2); + int factorQbitSize = RSA_PRV_KEY_BITSIZE_Q(pPrivateKeyType2); + cpSize nsP = MOD_LEN(RSA_PRV_KEY_PMONT(pPrivateKeyType2)); + cpSize nsQ = MOD_LEN(RSA_PRV_KEY_QMONT(pPrivateKeyType2)); + + int ret = IPP_IS_VALID; + + BNU_CHUNK_T* pTmp = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pBuffer, (int)sizeof(BNU_CHUNK_T))); + BNU_CHUNK_T* pFreeBuffer = pTmp+nsN; + + /* choose security parameter */ + int mrTrials = (nTrials<1)? MR_rounds_p80(factorPbitSize) : nTrials; + + IppStatus sts = ippStsNoErr; + do { + /* test if E is odd and 3 <= E < N */ + if(0==(pExpE[0]&1)) { + ret = IPP_IS_INVALID; + break; + } + if(1==nsE && pExpE[0]<3) { + ret = IPP_IS_INVALID; + break; + } + if(0 <= cpCmp_BNU(pExpE, nsE, pN, nsN)) { + ret = IPP_IS_INVALID; + break; + } + + /* test if N==P*Q */ + cpMul_BNU_school(pFreeBuffer, pFactorP, nsP, pFactorQ, nsQ); + { + cpSize ns = cpFix_BNU(pFreeBuffer, nsP+nsQ); + if(cpCmp_BNU(pFreeBuffer, ns, pN, nsN)) { + ret = IPP_IS_INVALID; + break; + } + } + /* test if PubKey(N)==PrivKeytype2(N) */ + if(cpCmp_BNU(pN, nsN, MOD_MODULUS(RSA_PRV_KEY_NMONT(pPrivateKeyType2)), MOD_LEN(RSA_PRV_KEY_NMONT(pPrivateKeyType2)))) { + ret = IPP_IS_INVALID; + break; + } + /* test if PubKey(N)==PrivKeytype1(N) */ + if(pPrivateKeyType1) { + if(cpCmp_BNU(pN, nsN, MOD_MODULUS(RSA_PRV_KEY_NMONT(pPrivateKeyType1)), MOD_LEN(RSA_PRV_KEY_NMONT(pPrivateKeyType1)))) { + ret = IPP_IS_INVALID; + break; + } + } + + /* test if P is prime */ + //if(0==cpIsProbablyPrime(pFactorP, factorPbitSize, mrTrials, + // rndFunc, pRndParam, + // pMontP, pFreeBuffer)) { + // ret = IPP_IS_COMPOSITE; + // break; + //} + { + int r = cpIsProbablyPrime(pFactorP, factorPbitSize, mrTrials, + rndFunc, pRndParam, + pMontP, pFreeBuffer); + if(0>r) { + sts = ippStsErr; + break; + } + if(0==r) { + ret = IPP_IS_COMPOSITE; + break; + } + } + /* test if E and (P-1) co-prime */ + cpDec_BNU(pTmp, pFactorP, nsP, 1); + if(0 == cpIsCoPrime(pExpE, nsE, pTmp, nsP, pFreeBuffer)) { + ret = IPP_IS_INVALID; + break; + } + /* test if E*dP = 1 mod (P-1) */ + cpMul_BNU_school(pFreeBuffer, pExpDp, nsP, pExpE, nsE); + cpMod_BNU(pFreeBuffer, nsP+nsE, pTmp, nsP); + if(!cpEqu_BNU_CHUNK(pFreeBuffer, nsP, 1)) { + ret = IPP_IS_INVALID; + break; + } + + /* test if Q is prime */ + //if(0==cpIsProbablyPrime(pFactorQ, factorQbitSize, mrTrials, + // rndFunc, pRndParam, + // pMontQ, pFreeBuffer)) { + // ret = IPP_IS_COMPOSITE; + // break; + //} + { + int r = cpIsProbablyPrime(pFactorQ, factorQbitSize, mrTrials, + rndFunc, pRndParam, + pMontQ, pFreeBuffer); + if(0>r) { + sts = ippStsErr; + break; + } + if(0==r) { + ret = IPP_IS_COMPOSITE; + break; + } + } + /* test if E and (Q-1) co-prime */ + cpDec_BNU(pTmp, pFactorQ, nsQ, 1); + if(0 == cpIsCoPrime(pExpE, nsE, pTmp, nsQ, pFreeBuffer)) { + ret = IPP_IS_INVALID; + break; + } + /* test if E*dQ = 1 mod (Q-1) */ + cpMul_BNU_school(pFreeBuffer, pExpDq, nsQ, pExpE, nsE); + cpMod_BNU(pFreeBuffer, nsQ+nsE, pTmp, nsQ); + if(!cpEqu_BNU_CHUNK(pFreeBuffer, nsQ, 1)) { + ret = IPP_IS_INVALID; + break; + } + + /* test if 1==(Q*Qinv) mod P */ + cpMul_BNU_school(pFreeBuffer, pInvQ, nsP, pFactorQ,nsQ); + cpMod_BNU(pFreeBuffer, nsP+nsQ, pFactorP, nsP); + if(!cpEqu_BNU_CHUNK(pFreeBuffer, nsP, 1)) { + ret = IPP_IS_INVALID; + break; + } + + /* test private exponent (optional) */ + if(pPrivateKeyType1) { + const BNU_CHUNK_T* pExpD = RSA_PRV_KEY_D(pPrivateKeyType1); + cpSize nsD = nsN; + int resilt1 = isValidPriv1_classic(pN,nsN, pExpE,nsE, pExpD,nsD, + pFactorP,nsP, pFactorQ,nsQ, + pTmp); + int resilt2 = isValidPriv1_rsa(pN,nsN, pExpE,nsE, pExpD,nsD, + pFactorP,nsP, pFactorQ,nsQ, + pTmp); + if(IPP_IS_VALID!=resilt1 && IPP_IS_VALID!=resilt2) { + ret = IPP_IS_INVALID; + break; + } + } + } while(0); + + *pResult = ret; + return sts; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsa_verifysign_pkcs1v15.h b/plugin/ippcp/library/src/sources/ippcp/pcprsa_verifysign_pkcs1v15.h new file mode 100644 index 000000000..42c22f0e7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsa_verifysign_pkcs1v15.h @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +#include "pcprsa_emsa_pkcs1v15.h" + +static int VerifySign(const Ipp8u* pMsg, int msgLen, /* message representation */ + const Ipp8u* pSalt, int saltLen, /* fied string */ + const Ipp8u* pSign, + int* pIsValid, + const IppsRSAPublicKeyState* pKey, + BNU_CHUNK_T* pBuffer) +{ + /* size of RSA modulus in bytes and chunks */ + cpSize rsaBits = RSA_PUB_KEY_BITSIZE_N(pKey); + cpSize k = BITS2WORD8_SIZE(rsaBits); + cpSize nsN = BITS_BNU_CHUNK(rsaBits); + + /* temporary BNs */ + __ALIGN8 IppsBigNumState bnC; + __ALIGN8 IppsBigNumState bnP; + + /* make BNs */ + BN_Make(pBuffer, pBuffer + nsN + 1, nsN, &bnC); + pBuffer += (nsN + 1) * 2; + BN_Make(pBuffer, pBuffer + nsN + 1, nsN, &bnP); + pBuffer += (nsN + 1) * 2; + + /* + // public-key operation + */ + ippsSetOctString_BN(pSign, k, &bnP); + gsRSApub_cipher(&bnC, &bnP, pKey, pBuffer); + + /* convert EM into the string */ + ippsGetOctString_BN((Ipp8u*)(BN_BUFFER(&bnC)), k, &bnC); + + /* EMSA-PKCS-v1_5 encoding */ + if (EMSA_PKCSv15(pMsg, msgLen, pSalt, saltLen, (Ipp8u*)(BN_NUMBER(&bnC)), k)) { + *pIsValid = 1 == EquBlock((Ipp8u*)(BN_BUFFER(&bnC)), (Ipp8u*)(BN_NUMBER(&bnC)), k); + return 1; + } + else + return 0; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_oaep.c b/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_oaep.c new file mode 100644 index 000000000..5d19ab88e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_oaep.c @@ -0,0 +1,215 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSAES-OAEP Encryption/Decription Functions +// +// Contents: +// ippsRSADecrypt_OAEP() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcptool.h" +#include "pcpngrsa.h" +#include "pcphash.h" + +/*F* +// Name: ippsRSADecrypt_OAEP +// +// Purpose: Performs RSAES-OAEP decryprion scheme +// +// Returns: Reason: +// ippStsNotSupportedModeErr unknown hashAlg +// +// ippStsNullPtrErr NULL == pKey +// NULL == pSrc +// NULL == pLab +// NULL == pDst +// NULL == pDstLen +// NULL == pBuffer +// +// ippStsLengthErr labLen <0 +// RSAsize < 2*hashLen +2 +// +// ippStsIncompleteContextErr private key is not set up +// +// ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID() +// +// ippStsOutOfRangeErr ciphertext > RSA(N) +// +// ippStsUnderRunErr decoding error +// +// ippStsNoErr no error +// +// Parameters: +// pSrc pointer to the ciphertext +// assumed that length of the ciphertext is equal to k - sizeof RSA modulus in bytes +// pLab (optional) pointer to the label associated with plaintext +// labLen label length (bytes) +// pDst pointer to the plaintext +// pDstLen pointer to the plaintext length +// assumed that length of the recovered message is at least k-hashLen*2-2 bytes; +// maximum message length is (k-hashLen*2-2) bytes and is for choosen RSA and Hash-function +// pKey pointer to the RSA private key context +// hashAlg hash alg ID +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSADecrypt_OAEP, (const Ipp8u* pSrc, + const Ipp8u* pLab, int labLen, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pScratchBuffer)) +{ + int hashLen; + + /* test hash algorith ID */ + hashAlg = cpValidHashAlg(hashAlg); + IPP_BADARG_RET(ippHashAlg_Unknown == hashAlg, ippStsNotSupportedModeErr); + + /* test data pointer */ + IPP_BAD_PTR3_RET(pSrc, pDst, pDstLen); + + IPP_BADARG_RET(!pLab && labLen, ippStsNullPtrErr); + + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + /* test hash length */ + IPP_BADARG_RET(labLen < 0, ippStsLengthErr); + + hashLen = cpHashSize(hashAlg); + /* test compatibility of RSA and hash length */ + IPP_BADARG_RET(BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey)) < (2 * hashLen + 2), ippStsLengthErr); + + { + /* size of RSA modulus in bytes and chunks */ + int k = BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey)); + cpSize nsN = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey)); + + /* align resource */ + BNU_CHUNK_T* pResource = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T))); + + /* temporary BN */ + __ALIGN8 IppsBigNumState tmpBN; + BN_Make(pResource, pResource+ nsN + 1, nsN, &tmpBN); + pResource += (nsN + 1) * 2; /* update buffer pointer */ + ippsSetOctString_BN(pSrc, k, &tmpBN); /* convert ciphertext to BigNum */ + /* make sure ciphertext < RSA modulus N */ + IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(&tmpBN), BN_SIZE(&tmpBN), + MOD_MODULUS(RSA_PRV_KEY_NMONT(pKey)), MOD_LEN(RSA_PRV_KEY_NMONT(pKey))), ippStsOutOfRangeErr); + + /* RSA decryption */ + + if (RSA_PRV_KEY1_VALID_ID(pKey)) + gsRSAprv_cipher(&tmpBN, &tmpBN, pKey, pResource); + else + gsRSAprv_cipher_crt(&tmpBN, &tmpBN, pKey, pResource); + + /* + // EME-OAEP decoding + */ + { + Ipp8u* pEM = (Ipp8u*)(BN_BUFFER(&tmpBN)); + Ipp8u* pBuffer = (Ipp8u*)BN_NUMBER(&tmpBN); + + int i; + /* convert RSA encoded into EM */ + for (i = 0; i < k; i++) { + pEM[i] = pBuffer[k - 1 - i]; + } + + /* + // OAEP EM decoding, EM = Y || maskedSeed || maskedDB + */ + { + /* check that Y == 0 */ + BNU_CHUNK_T res = cpIsZero_ct(pEM[0]); + + Ipp8u* pSeed = pEM + 1; + Ipp8u* pDB = pEM + 1 + hashLen; /* DB = lHash || PS || Msg */ + int dbLen = k - 1 - hashLen; + int maxMsgLen = dbLen - hashLen - 1; + + /* seed = maskedSeed ^ seedMask, seedMask = MGF(maskedDB, hashLen) */ + ippsMGF(pDB, dbLen, pBuffer, hashLen, hashAlg); + XorBlock(pSeed, pBuffer, pSeed, hashLen); + + /* DB = maskedDB ^ dbMask, dbMask = MGF (seed, dbLen) */ + ippsMGF(pSeed, hashLen, pBuffer, dbLen, hashAlg); + XorBlock(pDB, pBuffer, pDB, dbLen); + + /* re-compute Hash(Label) and compare with lHash */ + ippsHashMessage(pLab, labLen, pBuffer, hashAlg); + res &= cpIsEquBlock_ct(pDB, pBuffer, hashLen); + + /* detect the padding consists of a number of 0x00-bytes, followed by a 0x01 */ + BNU_CHUNK_T byte_01_found = 0; + BNU_CHUNK_T byte_01_idx = 0; + for (i = hashLen; i < dbLen; i++) { + BNU_CHUNK_T byte_00 = cpIsZero_ct(pDB[i]); /* mask if byte is 0x00 */ + BNU_CHUNK_T byte_01 = cpIsZero_ct(pDB[i] ^ 0x01); /* mask if byte is 0x01 */ + /* set index of byte 01_idx if byte 01 found */ + byte_01_idx = cpSelect_ct(~byte_01_found & byte_01, (BNU_CHUNK_T)i, byte_01_idx); + /* set flag byte_01_found */ + byte_01_found |= byte_01; + /* update EM encoding result */ + res &= (byte_01_found | byte_00); + } + /* update EM encoding result if byte_01_found */ + res &= byte_01_found; + + /* copy decoded message to pDst */ + { + /* move decoded message by (maxMsgLen-msgLen) left + */ + int msgIdx = (int)byte_01_idx + 1; /* decoded message index inside DB */ + int msgLen = dbLen - msgIdx; /* length of decoded message */ + + BNU_CHUNK_T mask; + for(msgIdx = 1; msgIdx < maxMsgLen; msgIdx <<= 1) { + mask = cpIsEqu_ct((BNU_CHUNK_T)(msgIdx & (maxMsgLen - msgLen)), (BNU_CHUNK_T)msgIdx); + for(i = hashLen+1; i < (dbLen-msgIdx); i++) + pDB[i] = cpSelect_ct_8u(mask, pDB[i + msgIdx], pDB[i]); + } + + /* copy decoded message */ + for(i = 0; i < maxMsgLen; i++) { + mask = res & cpIsLt_ct((BNU_CHUNK_T)i, (BNU_CHUNK_T)msgLen); + pDst[i] = cpSelect_ct_8u(mask, pDB[i + hashLen + 1], pDst[i]); + } + + /* decoded message length */ + *pDstLen = cpSelect_ct_int(res, msgLen, -1); + } + + /* clean */ + PurgeBlock(pEM, k); + PurgeBlock(pBuffer, k); + + /* return error status if is */ + return (IppStatus)cpSelect_ct_int(res, ippStsNoErr, ippStsUnderRunErr); + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_oaep_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_oaep_rmf.c new file mode 100644 index 000000000..565d75b91 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_oaep_rmf.c @@ -0,0 +1,210 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// RSAES-OAEP Encryption/Decription Functions +// +// Contents: +// ippsRSADecrypt_OAEP_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcptool.h" +#include "pcpngrsa.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsRSADecrypt_OAEP_rmf +// +// Purpose: Performs RSAES-OAEP decryprion scheme +// +// Returns: Reason: +// ippStsNotSupportedModeErr unknown hashAlg +// +// ippStsNullPtrErr NULL == pKey +// NULL == pSrc +// NULL == pLab +// NULL == pDst +// NULL == pDstLen +// NULL == pMethod +// NULL == pBuffer +// +// ippStsLengthErr labLen <0 +// RSAsize < 2*hashLen +2 +// +// ippStsIncompleteContextErr private key is not set up +// +// ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID() +// +// ippStsOutOfRangeErr ciphertext > RSA(N) +// +// ippStsUnderRunErr decoding error +// +// ippStsNoErr no error +// +// Parameters: +// pSrc pointer to the ciphertext +// assumed that length of the ciphertext is equal to k - sizeof RSA modulus in bytes +// pLab (optional) pointer to the label associated with plaintext +// labLen label length (bytes) +// pDst pointer to the encoded plaintext +// assumed that length of the recovered message is at least k-hashLen*2-2 bytes; +// maximum message length is (k-hashLen*2-2) bytes and is for choosen RSA and Hash-function +// pDstLen pointer to the plaintext length +// pKey pointer to the RSA private key context +// pMethod hash methods +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSADecrypt_OAEP_rmf, (const Ipp8u* pSrc, + const Ipp8u* pLab, int labLen, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + int hashLen; + + /* test data pointer */ + IPP_BAD_PTR4_RET(pSrc, pDst, pDstLen, pMethod); + + IPP_BADARG_RET(!pLab && labLen, ippStsNullPtrErr); + + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + /* test hash length */ + IPP_BADARG_RET(labLen < 0, ippStsLengthErr); + + hashLen = pMethod->hashLen; + /* test compatibility of RSA and hash length */ + IPP_BADARG_RET(BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey)) < (2 * hashLen + 2), ippStsLengthErr); + + { + /* size of RSA modulus in bytes and chunks */ + int k = BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey)); + cpSize nsN = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey)); + + /* align resource */ + BNU_CHUNK_T* pResource = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T))); + + /* temporary BN */ + __ALIGN8 IppsBigNumState tmpBN; + BN_Make(pResource, pResource+nsN+1, nsN, &tmpBN); + pResource += (nsN + 1) * 2; /* update buffer pointer */ + ippsSetOctString_BN(pSrc, k, &tmpBN); /* convert ciphertext to BigNum */ + /* make sure ciphertext < RSA modulus N */ + IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(&tmpBN), BN_SIZE(&tmpBN), + MOD_MODULUS(RSA_PRV_KEY_NMONT(pKey)), MOD_LEN(RSA_PRV_KEY_NMONT(pKey))), ippStsOutOfRangeErr); + + /* RSA decryption */ + if (RSA_PRV_KEY1_VALID_ID(pKey)) + gsRSAprv_cipher(&tmpBN, &tmpBN, pKey, pResource); + else + gsRSAprv_cipher_crt(&tmpBN, &tmpBN, pKey, pResource); + + /* + // EME-OAEP decoding + */ + { + Ipp8u* pEM = (Ipp8u*)(BN_BUFFER(&tmpBN)); + Ipp8u* pBuffer = (Ipp8u*)BN_NUMBER(&tmpBN); + + int i; + /* convert RSA encoded into EM */ + for (i = 0; i < k; i++) { + pEM[i] = pBuffer[k-1-i]; + } + + /* + // OAEP EM decoding, EM = Y || maskedSeed || maskedDB + */ + { + /* check that Y == 0 */ + BNU_CHUNK_T res = cpIsZero_ct(pEM[0]); + + Ipp8u* pSeed = pEM + 1; + Ipp8u* pDB = pEM + 1 + hashLen; /* DB = lHash || PS || Msg */ + int dbLen = k - 1 - hashLen; + int maxMsgLen = dbLen - hashLen - 1; + + /* seed = maskedSeed ^ seedMask, seedMask = MGF(maskedDB, hashLen) */ + ippsMGF1_rmf(pDB, dbLen, pBuffer, hashLen, pMethod); + XorBlock(pSeed, pBuffer, pSeed, hashLen); + + /* DB = maskedDB ^ dbMask, dbMask = MGF (seed, dbLen) */ + ippsMGF1_rmf(pSeed, hashLen, pBuffer, dbLen, pMethod); + XorBlock(pDB, pBuffer, pDB, dbLen); + + /* re-compute Hash(Label) and compare with lHash */ + ippsHashMessage_rmf(pLab, labLen, pBuffer, pMethod); + res &= cpIsEquBlock_ct(pDB, pBuffer, hashLen); + + /* detect the padding consists of a number of 0x00-bytes, followed by a 0x01 */ + BNU_CHUNK_T byte_01_found = 0; + BNU_CHUNK_T byte_01_idx = 0; + for (i = hashLen; i < dbLen; i++) { + BNU_CHUNK_T byte_00 = cpIsZero_ct(pDB[i]); /* mask if byte is 0x00 */ + BNU_CHUNK_T byte_01 = cpIsZero_ct(pDB[i] ^ 0x01); /* mask if byte is 0x01 */ + /* set index of byte 01_idx if byte 01 found */ + byte_01_idx = cpSelect_ct(~byte_01_found & byte_01, (BNU_CHUNK_T)i, byte_01_idx); + /* set flag byte_01_found */ + byte_01_found |= byte_01; + /* update EM encoding result */ + res &= (byte_01_found | byte_00); + } + /* update EM encoding result if byte_01_found */ + res &= byte_01_found; + + /* copy decoded message to pDst */ + { + /* move decoded message by (maxMsgLen-msgLen) left + */ + int msgIdx = (int)byte_01_idx + 1; /* decoded message index inside DB */ + int msgLen = dbLen - msgIdx; /* length of decoded message */ + + BNU_CHUNK_T mask; + for(msgIdx = 1; msgIdx < maxMsgLen; msgIdx <<= 1) { + mask = cpIsEqu_ct((BNU_CHUNK_T)(msgIdx & (maxMsgLen - msgLen)), (BNU_CHUNK_T)msgIdx); + for(i = hashLen+1; i < (dbLen-msgIdx); i++) + pDB[i] = cpSelect_ct_8u(mask, pDB[i + msgIdx], pDB[i]); + } + + /* copy decoded message */ + for(i = 0; i < maxMsgLen; i++) { + mask = res & cpIsLt_ct((BNU_CHUNK_T)i, (BNU_CHUNK_T)msgLen); + pDst[i] = cpSelect_ct_8u(mask, pDB[i + hashLen + 1], pDst[i]); + } + + /* decoded message length */ + *pDstLen = cpSelect_ct_int(res, msgLen, -1); + } + + /* clean */ + PurgeBlock(pEM, k); + PurgeBlock(pBuffer, k); + + /* return error status if is */ + return (IppStatus)cpSelect_ct_int(res, ippStsNoErr, ippStsUnderRunErr); + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_pkcsv15.c b/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_pkcsv15.c new file mode 100644 index 000000000..0806b0bbd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsadecrypt_pkcsv15.c @@ -0,0 +1,153 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA-PKCS1-v1_5 Encryption Scheme +// +// Contents: +// ippsRSADecrypt_PKCSv15() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcptool.h" + + +static Ipp32u NonZeroBlockLen(const Ipp8u* pData, int dataLen) +{ + int i; + for(i=0; i emLen); + + /* + // decoded message format: + // EM = 00 || 02 || PS || 00 || Msg + // len(PS) >= 8 + */ + errDecodeFlag |= (0x00 != pEM[0]); + errDecodeFlag |= (0x02 != pEM[1]); + errDecodeFlag |= (0x00 != pEM[3+psLen-1]); + CopyBlock(pEM+3+psLen, pMsg, msgLen); + *pMsgLen = msgLen; + return !errDecodeFlag; +} + + +/* +// returns 0 decription error +/ 1 OK +*/ +static int Decryption(const Ipp8u* pCipherTxt, + Ipp8u* pMsg, int* pMsgLen, + const IppsRSAPrivateKeyState* pKey, + BNU_CHUNK_T* pBuffer) +{ + /* size of RSA modulus in bytes and chunks */ + int k = BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey)); + cpSize nsN = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey)); + + /* temporary BN */ + __ALIGN8 IppsBigNumState tmpBN; + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &tmpBN); + + /* update buffer pointer */ + pBuffer += (nsN+1)*2; + + /* + // private-key operation + */ + ippsSetOctString_BN(pCipherTxt, k, &tmpBN); + if( 0 <= cpCmp_BNU(BN_NUMBER(&tmpBN), BN_SIZE(&tmpBN), + MOD_MODULUS(RSA_PRV_KEY_NMONT(pKey)), nsN) ) + return 0; + + if(RSA_PRV_KEY1_VALID_ID(pKey)) + gsRSAprv_cipher(&tmpBN, &tmpBN, pKey, pBuffer); + else + gsRSAprv_cipher_crt(&tmpBN, &tmpBN, pKey, pBuffer); + + ippsGetOctString_BN((Ipp8u*)(BN_BUFFER(&tmpBN)), k, &tmpBN); + + /* EME-PKCS-v1_5 decoding */ + return DecodeEME_PKCSv15((Ipp8u*)(BN_BUFFER(&tmpBN)), k, pMsg, pMsgLen); +} + +/*F* +// Name: ippsRSADecrypt_PKCSv15 +// +// Purpose: Performs Decrption according to RSA-ES-PKCS1_v1.5 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSrc +// NULL == pDst +// NULL == pDstLen +// NULL == pKey +// NULL == pBuffer +// +// ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID() +// +// ippStsIncompleteContextErr private key is not set up +// +// ippStsSizeErr RSA modulus size too short (k < 11, see PKCS#1) !! runtime error +// ippStsPaddingErr pSrc > size of RSA modulus !! runtime error +// DecodeEME_PKCS_v1_5 error +// ippStsNoErr no error +// +// Parameters: +// pSrc pointer to the ciphertext +// pDst pointer to the plaintext +// pDstLen pointer to the length (bytes) of decrypted plaintext +// pKey pointer to the RSA private key context +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSADecrypt_PKCSv15,(const Ipp8u* pSrc, + Ipp8u* pDst, int* pDstLen, + const IppsRSAPrivateKeyState* pKey, + Ipp8u* pScratchBuffer)) +{ + /* use aligned key context */ + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + /* test data pointer */ + IPP_BAD_PTR3_RET(pSrc, pDst, pDstLen); + + if(RSA_PRV_KEY_BITSIZE_N(pKey) < 11*BYTESIZE) + return ippStsSizeErr; + + { + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))); + return Decryption(pSrc, pDst, pDstLen, + pKey, + pBuffer)? ippStsNoErr : ippStsPaddingErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_oaep.c b/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_oaep.c new file mode 100644 index 000000000..01229a52b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_oaep.c @@ -0,0 +1,159 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSAES-OAEP Encryption/Decription Functions +// +// Contents: +// ippsRSAEncrypt_OAEP() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcptool.h" +#include "pcpngrsa.h" +#include "pcphash.h" + +/*F* +// Name: ippsRSAEncrypt_OAEP +// +// Purpose: Performs RSAES-OAEP encryprion scheme +// +// Returns: Reason: +// ippStsNotSupportedModeErr unknown hashAlg +// +// ippStsNullPtrErr NULL == pKey +// NULL == pSrc +// NULL == pDst +// NULL == pLabel +// NULL == pSeed +// NULL == pBuffer +// +// ippStsLengthErr srcLen <0 +// labLen <0 +// srcLen > RSAsize -2*hashLen -2 +// RSAsize < 2*hashLen +2 +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID() +// +// ippStsIncompleteContextErr public key is not set up +// +// ippStsNoErr no error +// +// Parameters: +// pSrc pointer to the plaintext +// srcLen plaintext length (bytes) +// pLabel (optional) pointer to the label associated with plaintext +// labLen label length (bytes) +// pSeed seed string of hashLen size +// pDst pointer to the ciphertext (length of pdst is not less then size of RSA modulus) +// pKey pointer to the RSA public key context +// hashAlg hash alg ID +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSAEncrypt_OAEP,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pLabel, int labLen, + const Ipp8u* pSeed, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pScratchBuffer)) +{ + int hashLen; + + /* test hash algorith ID */ + hashAlg = cpValidHashAlg(hashAlg); + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + + /* test data pointer */ + IPP_BAD_PTR3_RET(pSrc,pDst, pSeed); + + IPP_BADARG_RET(!pLabel && labLen, ippStsNullPtrErr); + + /* test public key context */ + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + /* test length */ + IPP_BADARG_RET(srcLen<0||labLen<0, ippStsLengthErr); + + hashLen = cpHashSize(hashAlg); + /* test compatibility of RSA and hash length */ + IPP_BADARG_RET(BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey)) < (2*hashLen +2), ippStsLengthErr); + /* test compatibility of msg length and other (RSA and hash) lengths */ + IPP_BADARG_RET(BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey))-(2*hashLen +2) < srcLen, ippStsLengthErr); + + { + /* size of RSA modulus in bytes and chunks */ + int k = BITS2WORD8_SIZE(RSA_PUB_KEY_BITSIZE_N(pKey)); + cpSize nsN = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey)); + + /* + // EME-OAEP encoding + */ + { + Ipp8u seedMask[BITS2WORD8_SIZE(IPP_SHA512_DIGEST_BITSIZE)]; + + Ipp8u* pMaskedSeed = pDst+1; + Ipp8u* pMaskedDB = pDst +hashLen +1; + + pDst[0] = 0; + + /* maskedDB = MGF(seed, k-1-hashLen)*/ + ippsMGF(pSeed, hashLen, pMaskedDB, k-1-hashLen, hashAlg); + + /* seedMask = HASH(pLab) */ + ippsHashMessage(pLabel, labLen, seedMask, hashAlg); + + /* maskedDB ^= concat(HASH(pLab),PS,0x01,pSc) */ + XorBlock(pMaskedDB, seedMask, pMaskedDB, hashLen); + pMaskedDB[k-srcLen-hashLen-2] ^= 0x01; + XorBlock(pMaskedDB+k-srcLen-hashLen-2+1, pSrc, pMaskedDB+k-srcLen-hashLen-2+1, srcLen); + + /* seedMask = MGF(maskedDB, hashLen) */ + ippsMGF(pMaskedDB, k-1-hashLen, seedMask, hashLen, hashAlg); + /* maskedSeed = seed ^ seedMask */ + XorBlock(pSeed, seedMask, pMaskedSeed, hashLen); + } + + /* RSA encryption */ + { + /* align buffer */ + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T)) ); + + /* temporary BN */ + __ALIGN8 IppsBigNumState tmpBN; + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &tmpBN); + + /* updtae buffer pointer */ + pBuffer += (nsN+1)*2; + + ippsSetOctString_BN(pDst, k, &tmpBN); + + gsRSApub_cipher(&tmpBN, &tmpBN, pKey, pBuffer); + + ippsGetOctString_BN(pDst, k, &tmpBN); + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_oaep_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_oaep_rmf.c new file mode 100644 index 000000000..08dd1b799 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_oaep_rmf.c @@ -0,0 +1,153 @@ +/******************************************************************************* +* Copyright (C) 2016 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// RSAES-OAEP Encryption/Decription Functions +// +// Contents: +// ippsRSAEncrypt_OAEP_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcptool.h" +#include "pcpngrsa.h" +#include "pcphash_rmf.h" + +/*F* +// Name: ippsRSAEncrypt_OAEP_rmf +// +// Purpose: Performs RSAES-OAEP encryprion scheme +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pKey +// NULL == pSrc +// NULL == pDst +// NULL == pLabel +// NULL == pSeed +// NULL == pMethod +// NULL == pBuffer +// +// ippStsLengthErr srcLen <0 +// labLen <0 +// srcLen > RSAsize -2*hashLen -2 +// RSAsize < 2*hashLen +2 +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID() +// +// ippStsIncompleteContextErr public key is not set up +// +// ippStsNoErr no error +// +// Parameters: +// pSrc pointer to the plaintext +// srcLen plaintext length (bytes) +// pLabel (optional) pointer to the label associated with plaintext +// labLen label length (bytes) +// pSeed seed string of hashLen size +// pDst pointer to the ciphertext (length of pdst is not less then size of RSA modulus) +// pKey pointer to the RSA public key context +// pMethod hash methods +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSAEncrypt_OAEP_rmf,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pLabel, int labLen, + const Ipp8u* pSeed, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + int hashLen; + + /* test data pointer */ + IPP_BAD_PTR4_RET(pSrc, pDst, pSeed, pMethod); + + IPP_BADARG_RET(!pLabel && labLen, ippStsNullPtrErr); + + /* test public key context */ + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + /* test length */ + IPP_BADARG_RET(srcLen<0||labLen<0, ippStsLengthErr); + + hashLen = pMethod->hashLen; + /* test compatibility of RSA and hash length */ + IPP_BADARG_RET(BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey)) < (2*hashLen +2), ippStsLengthErr); + /* test compatibility of msg length and other (RSA and hash) lengths */ + IPP_BADARG_RET(BITS2WORD8_SIZE(RSA_PRV_KEY_BITSIZE_N(pKey))-(2*hashLen +2) < srcLen, ippStsLengthErr); + + { + /* size of RSA modulus in bytes and chunks */ + int k = BITS2WORD8_SIZE(RSA_PUB_KEY_BITSIZE_N(pKey)); + cpSize nsN = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey)); + + /* + // EME-OAEP encoding + */ + { + Ipp8u seedMask[BITS2WORD8_SIZE(IPP_SHA512_DIGEST_BITSIZE)]; + + Ipp8u* pMaskedSeed = pDst+1; + Ipp8u* pMaskedDB = pDst +hashLen +1; + + pDst[0] = 0; + + /* maskedDB = MGF(seed, k-1-hashLen)*/ + ippsMGF1_rmf(pSeed, hashLen, pMaskedDB, k-1-hashLen, pMethod); + + /* seedMask = HASH(pLab) */ + ippsHashMessage_rmf(pLabel, labLen, seedMask, pMethod); + + /* maskedDB ^= concat(HASH(pLab),PS,0x01,pSc) */ + XorBlock(pMaskedDB, seedMask, pMaskedDB, hashLen); + pMaskedDB[k-srcLen-hashLen-2] ^= 0x01; + XorBlock(pMaskedDB+k-srcLen-hashLen-2+1, pSrc, pMaskedDB+k-srcLen-hashLen-2+1, srcLen); + + /* seedMask = MGF(maskedDB, hashLen) */ + ippsMGF1_rmf(pMaskedDB, k-1-hashLen, seedMask, hashLen, pMethod); + /* maskedSeed = seed ^ seedMask */ + XorBlock(pSeed, seedMask, pMaskedSeed, hashLen); + } + + /* RSA encryption */ + { + /* align buffer */ + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T)) ); + + /* temporary BN */ + __ALIGN8 IppsBigNumState tmpBN; + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &tmpBN); + + /* updtae buffer pointer */ + pBuffer += (nsN+1)*2; + + ippsSetOctString_BN(pDst, k, &tmpBN); + + gsRSApub_cipher(&tmpBN, &tmpBN, pKey, pBuffer); + + ippsGetOctString_BN(pDst, k, &tmpBN); + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_pkcsv15.c b/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_pkcsv15.c new file mode 100644 index 000000000..c456a52e2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsaencrypt_pkcsv15.c @@ -0,0 +1,136 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSA-PKCS1-v1_5 Encryption Scheme +// +// Contents: +// ippsRSAEncrypt_PKCSv15() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcptool.h" + + +static int EncodeEME_PKCSv15(const Ipp8u* msg, Ipp32u msgLen, + const Ipp8u* rndPS, + Ipp8u* pEM, Ipp32u lenEM) +{ + /* + // encoded message format: + // EM = 00 || 02 || PS || 00 || Msg + // len(PS) >= 8 + */ + Ipp32u psLen = lenEM - msgLen - 3; + + pEM[0] = 0x00; + pEM[1] = 0x02; + if(rndPS) + CopyBlock(rndPS, pEM+2, (cpSize)psLen); + else + PadBlock(0xFF, pEM+2, (cpSize)psLen); + pEM[2+psLen] = 0x00; + CopyBlock(msg, pEM+3+psLen, (cpSize)msgLen); + return 1; +} + + +static int Encryption(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pRndPS, + Ipp8u* pCipherTxt, + const IppsRSAPublicKeyState* pKey, + BNU_CHUNK_T* pBuffer) +{ + /* size of RSA modulus in bytes and chunks */ + int k= BITS2WORD8_SIZE(RSA_PUB_KEY_BITSIZE_N(pKey)); + cpSize nsN = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey)); + + if( (msgLen+11)<=k ) { + /* temporary BN */ + __ALIGN8 IppsBigNumState tmpBN; + BN_Make(pBuffer, pBuffer+nsN, nsN, &tmpBN); + + /* EME-PKCS-v1_5 encoding */ + EncodeEME_PKCSv15(pMsg, (Ipp32u)msgLen, pRndPS, (Ipp8u*)(BN_BUFFER(&tmpBN)), (Ipp32u)k); + /* + // public-key operation + */ + ippsSetOctString_BN((Ipp8u*)(BN_BUFFER(&tmpBN)), k, &tmpBN); + gsRSApub_cipher(&tmpBN, &tmpBN, pKey, pBuffer+nsN*2); + + /* convert into the cipher text */ + ippsGetOctString_BN(pCipherTxt, k, &tmpBN); + return 1; + } + else + return 0; +} + +/*F* +// Name: ippsRSAEncrypt_PKCSv15 +// +// Purpose: Performs Encrption according to RSA-ES-PKCS1_v1.5 +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pSrc +// NULL == pDst +// NULL == pKey +// NULL == pBuffer +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID() +// +// ippStsIncompleteContextErr public key is not set up +// +// //ippStsLengthErr 0 == srcLen +// ippStsSizeErr RSA modulus too short (srcLen > k-11, see PKCS#1) !!runtime error +// ippStsNoErr no error +// +// Parameters: +// pSrc pointer to the plaintext to be encrypted +// srcLen plaintext length (bytes) +// pRandPS pointer to the random nonzero string of suitable length (psLen >= k -3 -srcLen) +// pDst pointer to the ciphertext (k bytes length, == length of RSA modulus +// pKey pointer to the public key context context +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSAEncrypt_PKCSv15,(const Ipp8u* pSrc, int srcLen, + const Ipp8u* pRndPS, + Ipp8u* pDst, + const IppsRSAPublicKeyState* pKey, + Ipp8u* pScratchBuffer)) +{ + /* test public key context */ + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + /* test data pointer */ + IPP_BAD_PTR2_RET(pSrc, pDst); + + { + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))); + return Encryption(pSrc, srcLen, pRndPS, pDst, + pKey, + pBuffer)? ippStsNoErr : ippStsSizeErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pkcs1v15.c b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pkcs1v15.c new file mode 100644 index 000000000..ce747720a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pkcs1v15.c @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +// Signatire Scheme with Appendix Signatute Generation +// +// Contents: +// ippsRSASign_PKCS1v15() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +#include "pcprsa_pkcs1c15_data.h" +#include "pcprsa_generatesign_pkcs1v15.h" + +IPPFUN(IppStatus, ippsRSASign_PKCS1v15,(const Ipp8u* pMsg, int msgLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + IppHashAlgId hashAlg, + Ipp8u* pScratchBuffer)) +{ + /* test private key context */ + IPP_BAD_PTR2_RET(pPrvKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrvKey), ippStsIncompleteContextErr); + + /* test hash algorith ID */ + hashAlg = cpValidHashAlg(hashAlg); + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + IPP_BADARG_RET(ippHashAlg_SM3==hashAlg, ippStsNotSupportedModeErr); + + /* use aligned public key context if defined */ + if(pPubKey) { + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pPubKey), ippStsIncompleteContextErr); + } + + /* test data pointer */ + IPP_BAD_PTR2_RET(pMsg, pSign); + /* test length */ + IPP_BADARG_RET(msgLen<0, ippStsLengthErr); + + { + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + int mdLen = cpHashSize(hashAlg); + ippsHashMessage(pMsg, msgLen, md, hashAlg); + + { + const Ipp8u* pSalt = pksc15_salt[hashAlg].pSalt; + int saltLen = pksc15_salt[hashAlg].saltLen; + + int sts = GenerateSign(md, mdLen, + pSalt, saltLen, + pSign, + pPrvKey, pPubKey, + (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T)))); + + return (1==sts)? ippStsNoErr : ippStsSizeErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pkcs1v15_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pkcs1v15_rmf.c new file mode 100644 index 000000000..01e5b768b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pkcs1v15_rmf.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +// Signatire Scheme with Appendix Signatute Generation +// +// Contents: +// ippsRSASign_PKCS1v15_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +#include "pcprsa_pkcs1c15_data.h" +#include "pcprsa_generatesign_pkcs1v15.h" +#include "pcprsa_pkcs1v15_preproc.h" + +IPPFUN(IppStatus, ippsRSASign_PKCS1v15_rmf,(const Ipp8u* pMsg, int msgLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + const IppStatus preprocResult = SingleSignPkcs1v15RmfPreproc(pMsg, msgLen, pSign, + &pPrvKey, &pPubKey, pMethod, pScratchBuffer); // badargs and pointer alignments + + if (ippStsNoErr != preprocResult) { + return preprocResult; + } + + { + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + int mdLen = pMethod->hashLen; + ippsHashMessage_rmf(pMsg, msgLen, md, pMethod); + + { + const Ipp8u* pSalt = pksc15_salt[pMethod->hashAlgId].pSalt; + int saltLen = pksc15_salt[pMethod->hashAlgId].saltLen; + + int sts = GenerateSign(md, mdLen, + pSalt, saltLen, + pSign, + pPrvKey, pPubKey, + (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T)))); + + return (1==sts)? ippStsNoErr : ippStsSizeErr; + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pss.c b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pss.c new file mode 100644 index 000000000..e66c90888 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pss.c @@ -0,0 +1,218 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PSS +// +// Signatire Scheme with Appendix Signatute Generation +// (Ppobabilistic Signature Scheme) +// +// Contents: +// ippsRSASign_PSS() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +/*F* +// Name: ippsRSASign_PSS +// +// Purpose: Performs Signature Generation according to RSASSA-PSS +// +// Returns: Reason: +// ippStsNotSupportedModeErr invalid hashAlg value +// +// ippStsNullPtrErr NULL == pMsg +// NULL == pSalt +// NULL == pSign +// NULL == pPrvKey +// NULL == pPubKey +// NULL == pBuffer +// +// ippStsLengthErr msgLen<0 +// saltLen<0 +// emLen < (hashLen +saltLen +2), +// where emLen = (BITSIZE(RSA)-1)/8 +// +// ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID() +// !RSA_PUB_KEY_VALID_ID() +// +// ippStsIncompleteContextErr private or/and public key is not set up +// +// ippStsNoErr no error +// +// Parameters: +// pMsg pointer to the message to be signed +// msgLen lenfth of the message +// pSalt "salt" pointer to random string +// saltLen length of the "salt" string (bytes) +// pSign pointer to the signature string of the RSA length +// pPrvKey pointer to the RSA private key context +// pPubKey (optional) pointer to the RSA public key context +// hashAlg hash ID +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSASign_PSS,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSalt, int saltLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + IppHashAlgId hashAlg, + Ipp8u* pScratchBuffer)) +{ + /* test hash algorith ID */ + hashAlg = cpValidHashAlg(hashAlg); + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + /* test data pointer */ + IPP_BAD_PTR1_RET(pSign); + + /* test salt length and salt pointer */ + IPP_BADARG_RET(saltLen<0, ippStsLengthErr); + IPP_BADARG_RET((saltLen && !pSalt), ippStsNullPtrErr); + + /* test private key context */ + IPP_BAD_PTR2_RET(pPrvKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrvKey), ippStsIncompleteContextErr); + + /* use public key context if defined */ + if(pPubKey) { + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pPubKey), ippStsIncompleteContextErr); + } + + { + Ipp8u hashMsg[MAX_HASH_SIZE]; + + /* hash length */ + int hashLen = cpHashSize(hashAlg); + + /* size of RSA modulus in bytes and chunks */ + cpSize rsaBits = RSA_PRV_KEY_BITSIZE_N(pPrvKey); + cpSize k = BITS2WORD8_SIZE(rsaBits); + cpSize nsN = BITS_BNU_CHUNK(rsaBits); + + /* align buffer */ + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T)) ); + + /* temporary BNs */ + __ALIGN8 IppsBigNumState bnC; + __ALIGN8 IppsBigNumState bnP; + + /* message presentative size */ + int emBits = rsaBits-1; + int emLen = BITS2WORD8_SIZE(emBits); + + /* size of padding string (PS) */ + int psLen = emLen -hashLen -saltLen -2; + + /* test size consistence */ + if(0 > psLen) + IPP_ERROR_RET(ippStsLengthErr); + + /* compute hash of the message */ + ippsHashMessage(pMsg, msgLen, hashMsg, hashAlg); + + /* make BNs */ + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnC); + pBuffer += (nsN+1)*2; + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnP); + pBuffer += (nsN+1)*2; + + /* + // EMSA-PSS encoding + */ + { + Ipp8u* pM = (Ipp8u*)BN_NUMBER(&bnP); + Ipp8u* pEM = pSign; + Ipp8u* pDB = pSign; + int dbLen = emLen-hashLen-1; + Ipp8u* pH = pSign+dbLen; + + /* construct message M' + // M' = (00 00 00 00 00 00 00 00) || mHash || salt + // where: + // mHash = HASH(pMsg) + */ + PadBlock(0, pM, 8); + CopyBlock(hashMsg, pM+8, hashLen); + CopyBlock(pSalt, pM+8+hashLen, saltLen); + + /* construct EM + // EM = maskedDB || H || 0xBC + // where: + // H = HASH(M') + // maskedDB = DB ^ MGF(H) + // where: + // DB = PS || 0x01 || salt + // + // by other words + // EM = (dbMask ^ (PS || 0x01 || salt)) || HASH(M) || 0xBC + */ + pEM[emLen-1] = 0xBC; /* tail octet */ + ippsHashMessage(pM, 8+hashLen+saltLen, pH, hashAlg); /* H = HASH(M) */ + ippsMGF(pH, hashLen, pDB, dbLen, hashAlg); /* dbMask = MGF(H) */ + + XorBlock(pDB+psLen+1, pSalt, pDB+psLen+1, saltLen); + pDB[psLen] ^= 0x01; + + /* make sure that top 8*emLen-emBits bits are clear */ + pDB[0] &= MAKEMASK32(8-8*emLen+emBits); + } + + /* + // private-key operation + */ + ippsSetOctString_BN(pSign, emLen, &bnC); + + if(RSA_PRV_KEY1_VALID_ID(pPrvKey)) + gsRSAprv_cipher(&bnP, &bnC, pPrvKey, pBuffer); + else + gsRSAprv_cipher_crt(&bnP, &bnC, pPrvKey, pBuffer); + + ippsGetOctString_BN(pSign, k, &bnP); + + /* no check requested */ + if(!pPubKey) + return ippStsNoErr; + + /* check the result before send it out (fault attack mitigatioin) */ + else { + gsRSApub_cipher(&bnP, &bnP, pPubKey, pBuffer); + if(0==cpBN_cmp(&bnP, &bnC)) + return ippStsNoErr; + /* discard signature if check failed */ + else { + PadBlock(0, pSign, k); + return ippStsErr; + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pss_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pss_rmf.c new file mode 100644 index 000000000..61d595117 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsasign_pss_rmf.c @@ -0,0 +1,201 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PSS +// +// Signatire Scheme with Appendix Signatute Generation +// (Ppobabilistic Signature Scheme) +// +// Contents: +// ippsRSASign_PSS_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +#include "pcprsa_pss_preproc.h" + +/*F* +// Name: ippsRSASign_PSS_rmf +// +// Purpose: Performs Signature Generation according to RSASSA-PSS +// +// Returns: Reason: +// ippStsNotSupportedModeErr invalid hashAlg value +// +// ippStsNullPtrErr NULL == pMsg +// NULL == pSalt +// NULL == pSign +// NULL == pPrvKey +// NULL == pPubKey +// NULL == pMethod +// NULL == pBuffer +// +// ippStsLengthErr msgLen<0 +// saltLen<0 +// emLen < (hashLen +saltLen +2), +// where emLen = (BITSIZE(RSA)-1)/8 +// +// ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID() +// !RSA_PUB_KEY_VALID_ID() +// +// ippStsIncompleteContextErr private or/and public key is not set up +// +// ippStsNoErr no error +// +// Parameters: +// pMsg pointer to the message to be signed +// msgLen lenfth of the message +// pSalt "salt" pointer to random string +// saltLen length of the "salt" string (bytes) +// pSign pointer to the signature string of the RSA length +// pPrvKey pointer to the RSA private key context +// pPubKey (optional) pointer to the RSA public key context +// pMethod hash method +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSASign_PSS_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSalt, int saltLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + const IppStatus preprocResult = SingleSignPssRmfPreproc(pMsg, msgLen, pSalt, saltLen, + pSign, &pPrvKey, &pPubKey, pMethod, pScratchBuffer); // badargs and pointer alignments + + if (ippStsNoErr != preprocResult) { + return preprocResult; + } + + { + Ipp8u hashMsg[MAX_HASH_SIZE]; + + /* hash length */ + int hashLen = pMethod->hashLen; + + /* size of RSA modulus in bytes and chunks */ + cpSize rsaBits = RSA_PRV_KEY_BITSIZE_N(pPrvKey); + cpSize k = BITS2WORD8_SIZE(rsaBits); + cpSize nsN = BITS_BNU_CHUNK(rsaBits); + + /* align buffer */ + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T)) ); + + /* temporary BNs */ + __ALIGN8 IppsBigNumState bnC; + __ALIGN8 IppsBigNumState bnP; + + /* message presentative size */ + int emBits = rsaBits-1; + int emLen = BITS2WORD8_SIZE(emBits); + + /* size of padding string (PS) */ + int psLen = emLen -hashLen -saltLen -2; + + /* test size consistence */ + if(0 > psLen) + IPP_ERROR_RET(ippStsLengthErr); + + /* compute hash of the message */ + ippsHashMessage_rmf(pMsg, msgLen, hashMsg, pMethod); + + /* make BNs */ + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnC); + pBuffer += (nsN+1)*2; + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnP); + pBuffer += (nsN+1)*2; + + /* + // EMSA-PSS encoding + */ + { + Ipp8u* pM = (Ipp8u*)BN_NUMBER(&bnP); + Ipp8u* pEM = pSign; + Ipp8u* pDB = pSign; + int dbLen = emLen-hashLen-1; + Ipp8u* pH = pSign+dbLen; + + /* construct message M' + // M' = (00 00 00 00 00 00 00 00) || mHash || salt + // where: + // mHash = HASH(pMsg) + */ + PadBlock(0, pM, 8); + CopyBlock(hashMsg, pM+8, hashLen); + CopyBlock(pSalt, pM+8+hashLen, saltLen); + + /* construct EM + // EM = maskedDB || H || 0xBC + // where: + // H = HASH(M') + // maskedDB = DB ^ MGF(H) + // where: + // DB = PS || 0x01 || salt + // + // by other words + // EM = (dbMask ^ (PS || 0x01 || salt)) || HASH(M) || 0xBC + */ + pEM[emLen-1] = 0xBC; /* tail octet */ + ippsHashMessage_rmf(pM, 8+hashLen+saltLen, pH, pMethod); /* H = HASH(M) */ + ippsMGF1_rmf(pH, hashLen, pDB, dbLen, pMethod); /* dbMask = MGF(H) */ + + XorBlock(pDB+psLen+1, pSalt, pDB+psLen+1, saltLen); + pDB[psLen] ^= 0x01; + + /* make sure that top 8*emLen-emBits bits are clear */ + pDB[0] &= MAKEMASK32(8-8*emLen+emBits); + } + + /* + // private-key operation + */ + ippsSetOctString_BN(pSign, emLen, &bnC); + + if(RSA_PRV_KEY1_VALID_ID(pPrvKey)) + gsRSAprv_cipher(&bnP, &bnC, pPrvKey, pBuffer); + else + gsRSAprv_cipher_crt(&bnP, &bnC, pPrvKey, pBuffer); + + ippsGetOctString_BN(pSign, k, &bnP); + + /* no check requested */ + if(!pPubKey) + return ippStsNoErr; + + /* check the result before send it out (fault attack mitigatioin) */ + else { + gsRSApub_cipher(&bnP, &bnP, pPubKey, pBuffer); + if(0==cpBN_cmp(&bnP, &bnC)) + return ippStsNoErr; + /* discard signature if check failed */ + else { + PadBlock(0, pSign, k); + return ippStsErr; + } + } + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsasignhash_pkcs1v15.c b/plugin/ippcp/library/src/sources/ippcp/pcprsasignhash_pkcs1v15.c new file mode 100644 index 000000000..c6651b496 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsasignhash_pkcs1v15.c @@ -0,0 +1,85 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +// Signatire Scheme with Appendix Signatute Generation +// +// Contents: +// ippsRSASignHash_PKCS1v15() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +#include "pcprsa_pkcs1c15_data.h" +#include "pcprsa_generatesign_pkcs1v15.h" + +#if defined( _ABL_ ) + +IPPFUN(IppStatus, ippsRSASignHash_PKCS1v15,(const Ipp8u* md, int mdLen, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + IppHashAlgId hashAlg, + Ipp8u* pScratchBuffer)) +{ + /* test private key context */ + IPP_BAD_PTR2_RET(pPrvKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrvKey), ippStsIncompleteContextErr); + + /* test hash algorith ID */ + hashAlg = cpValidHashAlg(hashAlg); + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + IPP_BADARG_RET(ippHashAlg_SM3==hashAlg, ippStsNotSupportedModeErr); + + /* use public key context if defined */ + if(pPubKey) { + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pPubKey), ippStsIncompleteContextErr); + } + + /* test data pointer */ + IPP_BAD_PTR2_RET(md, pSign); + /* test length */ + IPP_BADARG_RET(mdLen!=cpHashSize(hashAlg), ippStsLengthErr); + + { + const Ipp8u* pSalt = pksc15_salt[hashAlg].pSalt; + int saltLen = pksc15_salt[hashAlg].saltLen; + + int sts = GenerateSign(md, mdLen, + pSalt, saltLen, + pSign, + pPrvKey, pPubKey, + (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T)))); + + return (1==sts)? ippStsNoErr : ippStsSizeErr; + } +} + +#endif /* #if defined( _ABL_ ) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsasignhash_pkcs1v15_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcprsasignhash_pkcs1v15_rmf.c new file mode 100644 index 000000000..a468d46b9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsasignhash_pkcs1v15_rmf.c @@ -0,0 +1,84 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +// Signatire Scheme with Appendix Signatute Generation +// +// Contents: +// ippsRSASignHash_PKCS1v15_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +#include "pcprsa_pkcs1c15_data.h" +#include "pcprsa_generatesign_pkcs1v15.h" + +#if defined( _ABL_ ) + +IPPFUN(IppStatus, ippsRSASignHash_PKCS1v15_rmf,(const Ipp8u* md, + Ipp8u* pSign, + const IppsRSAPrivateKeyState* pPrvKey, + const IppsRSAPublicKeyState* pPubKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + IppHashAlgId hashAlg; + + /* test private key context */ + IPP_BAD_PTR3_RET(pPrvKey, pScratchBuffer, pMethod); + IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pPrvKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrvKey), ippStsIncompleteContextErr); + + /* test hash algorith ID */ + hashAlg = pMethod->hashAlgId; + IPP_BADARG_RET(ippHashAlg_SM3==hashAlg, ippStsNotSupportedModeErr); + + /* use aligned public key context if defined */ + if(pPubKey) { + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pPubKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pPubKey), ippStsIncompleteContextErr); + } + + /* test data pointer */ + IPP_BAD_PTR2_RET(md, pSign); + + { + const Ipp8u* pSalt = pksc15_salt[hashAlg].pSalt; + int saltLen = pksc15_salt[hashAlg].saltLen; + + int sts = GenerateSign(md, pMethod->hashLen, + pSalt, saltLen, + pSign, + pPrvKey, pPubKey, + (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T)))); + + return (1==sts)? ippStsNoErr : ippStsSizeErr; + } +} + +#endif /* #if defined( _ABL_ ) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pkcs1v15.c b/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pkcs1v15.c new file mode 100644 index 000000000..246c075c6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pkcs1v15.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +// Signatire Scheme with Appendix Signatute Generation +// +// Contents: +// ippsRSAVerify_PKCS1v15() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +#include "pcprsa_pkcs1c15_data.h" +#include "pcprsa_verifysign_pkcs1v15.h" + +IPPFUN(IppStatus, ippsRSAVerify_PKCS1v15,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, int* pIsValid, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pScratchBuffer)) +{ + /* test public key context */ + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + /* test hash algorith ID */ + hashAlg = cpValidHashAlg(hashAlg); + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + IPP_BADARG_RET(ippHashAlg_SM3==hashAlg, ippStsNotSupportedModeErr); + + /* test data pointer */ + IPP_BAD_PTR3_RET(pMsg, pSign, pIsValid); + /* test length */ + IPP_BADARG_RET(msgLen<0, ippStsLengthErr); + + *pIsValid = 0; + { + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + int mdLen = cpHashSize(hashAlg); + ippsHashMessage(pMsg, msgLen, md, hashAlg); + + return VerifySign(md, mdLen, + pksc15_salt[hashAlg].pSalt, pksc15_salt[hashAlg].saltLen, + pSign, pIsValid, + pKey, + (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))))? ippStsNoErr : ippStsSizeErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pkcs1v15_rmf.c b/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pkcs1v15_rmf.c new file mode 100644 index 000000000..3d17a77af --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pkcs1v15_rmf.c @@ -0,0 +1,64 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PKCS-v1_5 +// +// Signatire Scheme with Appendix Signatute Generation +// +// Contents: +// ippsRSAVerify_PKCS1v15_rmf() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +#include "pcprsa_pkcs1c15_data.h" +#include "pcprsa_verifysign_pkcs1v15.h" +#include "pcprsa_pkcs1v15_preproc.h" + +IPPFUN(IppStatus, ippsRSAVerify_PKCS1v15_rmf,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, int* pIsValid, + const IppsRSAPublicKeyState* pKey, + const IppsHashMethod* pMethod, + Ipp8u* pScratchBuffer)) +{ + const IppStatus preprocResult = SingleVerifyPkcs1v15RmfPreproc(pMsg, msgLen, pSign, + pIsValid, &pKey, pMethod, pScratchBuffer); // badargs, pointer alignments, set valid = 0 + + if (ippStsNoErr != preprocResult) { + return preprocResult; + } + + { + Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE]; + ippsHashMessage_rmf(pMsg, msgLen, md, pMethod); + + return VerifySign(md, pMethod->hashLen, + pksc15_salt[pMethod->hashAlgId].pSalt, pksc15_salt[pMethod->hashAlgId].saltLen, + pSign, pIsValid, + pKey, + (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))))? ippStsNoErr : ippStsSizeErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pss.c b/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pss.c new file mode 100644 index 000000000..81bb0c4e8 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcprsaverify_pss.c @@ -0,0 +1,194 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// RSASSA-PSS +// +// Signatire Scheme with Appendix Signatute Generation +// (Ppobabilistic Signature Scheme) +// +// Contents: +// ippsRSAVerify_PSS() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpngrsa.h" +#include "pcphash.h" +#include "pcptool.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*F* +// Name: ippsRSAVerify_PSS +// +// Purpose: Performs Signature Verification according to RSASSA-PSS +// +// Returns: Reason: +// ippStsNotSupportedModeErr invalid hashAlg value +// +// ippStsNullPtrErr NULL == pMsg +// NULL == pSign +// NULL == pIsValid +// NULL == pKey +// NULL == pBuffer +// +// ippStsLengthErr msgLen<0 +// RSAsize <=hashLen +2 +// +// ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID() +// +// ippStsIncompleteContextErr public key is not set up +// +// ippStsNoErr no error +// +// Parameters: +// pMsg pointer to the message to be verified +// msgLen length of the message +// pSign pointer to the signature string of the RSA length +// pIsValid pointer to the verification result +// pKey pointer to the RSA public key context +// hashAlg hash ID +// pBuffer pointer to scratch buffer +*F*/ +IPPFUN(IppStatus, ippsRSAVerify_PSS,(const Ipp8u* pMsg, int msgLen, + const Ipp8u* pSign, + int* pIsValid, + const IppsRSAPublicKeyState* pKey, + IppHashAlgId hashAlg, + Ipp8u* pScratchBuffer)) +{ + /* test hash algorith ID */ + hashAlg = cpValidHashAlg(hashAlg); + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + /* test data pointer */ + IPP_BAD_PTR2_RET(pSign, pIsValid); + + /* test public key context */ + IPP_BAD_PTR2_RET(pKey, pScratchBuffer); + IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr); + IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr); + + { + Ipp8u hashMsg[MAX_HASH_SIZE]; + + /* hash length */ + int hashLen = cpHashSize(hashAlg); + + /* size of RSA modulus in bytes and chunks */ + cpSize rsaBits = RSA_PUB_KEY_BITSIZE_N(pKey); + cpSize k = BITS2WORD8_SIZE(rsaBits); + cpSize nsN = BITS_BNU_CHUNK(rsaBits); + + /* align buffer */ + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T)) ); + + /* temporary BNs */ + __ALIGN8 IppsBigNumState bnC; + __ALIGN8 IppsBigNumState bnP; + + /* message presentative size */ + int emBits = rsaBits-1; + int emLen = BITS2WORD8_SIZE(emBits); + + /* test size consistence */ + if(k <= (hashLen+2)) + IPP_ERROR_RET(ippStsLengthErr); + + /* compute hash of the message */ + ippsHashMessage(pMsg, msgLen, hashMsg, hashAlg); + + /* make BNs */ + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnC); + pBuffer += (nsN+1)*2; + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnP); + pBuffer += (nsN+1)*2; + + /* + // public-key operation + */ + ippsSetOctString_BN(pSign, k, &bnP); + gsRSApub_cipher(&bnC, &bnP, pKey, pBuffer); + + *pIsValid = 0; + /* + // EMSA-PSS verification + */ + { + /* convert BN into octet string EM + // EM = maskedDB || H || 0xBC + */ + Ipp8u* pEM = (Ipp8u*)BN_BUFFER(&bnC); + ippsGetOctString_BN(pEM, emLen, &bnC); + + /* test last byte and top of (8*emLen-emBits) bits */ + if(0xBC==pEM[emLen-1] && 0x00==(pEM[0] >>(8-(8*emLen-emBits)))) { + int psLen; + Ipp8u* pM = (Ipp8u*)BN_NUMBER(&bnP); + + /* pointers to the EM fields */ + int dbLen = emLen-hashLen-1; + Ipp8u* pDB = pEM; + Ipp8u* pH = pEM+dbLen; + + /* recover DB = maskedDB ^ MGF(H) */ + ippsMGF(pH, hashLen, pM, dbLen, hashAlg); + XorBlock(pDB, pM, pDB, dbLen); + + /* make sure that top 8*emLen-emBits bits are clear */ + pDB[0] &= MAKEMASK32(8-8*emLen+emBits); + + /* skip over padding sring (PS) */ + for(psLen=0; psLenhashLen; + + /* size of RSA modulus in bytes and chunks */ + cpSize rsaBits = RSA_PUB_KEY_BITSIZE_N(pKey); + cpSize k = BITS2WORD8_SIZE(rsaBits); + cpSize nsN = BITS_BNU_CHUNK(rsaBits); + + /* align buffer */ + BNU_CHUNK_T* pBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pScratchBuffer, (int)sizeof(BNU_CHUNK_T)) ); + + /* temporary BNs */ + __ALIGN8 IppsBigNumState bnC; + __ALIGN8 IppsBigNumState bnP; + + /* message presentative size */ + int emBits = rsaBits-1; + int emLen = BITS2WORD8_SIZE(emBits); + + /* test size consistence */ + if(k <= (hashLen+2)) + IPP_ERROR_RET(ippStsLengthErr); + + /* compute hash of the message */ + ippsHashMessage_rmf(pMsg, msgLen, hashMsg, pMethod); + + /* make BNs */ + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnC); + pBuffer += (nsN+1)*2; + BN_Make(pBuffer, pBuffer+nsN+1, nsN, &bnP); + pBuffer += (nsN+1)*2; + + /* + // public-key operation + */ + ippsSetOctString_BN(pSign, k, &bnP); + gsRSApub_cipher(&bnC, &bnP, pKey, pBuffer); + + /* + // EMSA-PSS verification + */ + { + /* convert BN into octet string EM + // EM = maskedDB || H || 0xBC + */ + Ipp8u* pEM = (Ipp8u*)BN_BUFFER(&bnC); + ippsGetOctString_BN(pEM, emLen, &bnC); + + /* test last byte and top of (8*emLen-emBits) bits */ + if(0xBC==pEM[emLen-1] && 0x00==(pEM[0] >>(8-(8*emLen-emBits)))) { + int psLen; + Ipp8u* pM = (Ipp8u*)BN_NUMBER(&bnP); + + /* pointers to the EM fields */ + int dbLen = emLen-hashLen-1; + Ipp8u* pDB = pEM; + Ipp8u* pH = pEM+dbLen; + + /* recover DB = maskedDB ^ MGF(H) */ + ippsMGF1_rmf(pH, hashLen, pM, dbLen, pMethod); + XorBlock(pDB, pM, pDB, dbLen); + + /* make sure that top 8*emLen-emBits bits are clear */ + pDB[0] &= MAKEMASK32(8-8*emLen+emBits); + + /* skip over padding sring (PS) */ + for(psLen=0; psLenhashAlgId; + IPP_BADARG_RET(ippHashAlg_SM3==hashAlg, ippStsNotSupportedModeErr); + + /* test data pointer */ + IPP_BAD_PTR3_RET(md, pSign, pIsValid); + + *pIsValid = 0; + return VerifySign(md, pMethod->hashLen, + pksc15_salt[hashAlg].pSalt, pksc15_salt[hashAlg].saltLen, + pSign, pIsValid, + pKey, + (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pBuffer), (int)sizeof(BNU_CHUNK_T))))? ippStsNoErr : ippStsSizeErr; +} + +#endif /* #if defined( _ABL_ ) */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpscramble.h b/plugin/ippcp/library/src/sources/ippcp/pcpscramble.h new file mode 100644 index 000000000..42c20a4d6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpscramble.h @@ -0,0 +1,169 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Fixed window exponentiation scramble/unscramble +// +// Contents: +// cpScramblePut() +// cpScrambleGet() +// +// +*/ + +#if !defined(_PC_SCRAMBLE_H) +#define _PC_SCRAMBLE_H + +/* +// cpsScramblePut/cpsScrambleGet +// stores to/retrieves from pScrambleEntry position +// pre-computed data if fixed window method is used +*/ +__INLINE void cpScramblePut(Ipp8u* pArray, cpSize colummSize, + const Ipp32u* pData, cpSize dataSize) +{ + int i; + switch(colummSize) { + case 1: // column - byte + dataSize *= sizeof(Ipp32u); + for(i=0; i 2 dword) + for(; dataSize>=2; dataSize-=2, pArray+=CACHE_LINE_SIZE, pData+=2) { + ((Ipp32u*)pArray)[0] = pData[0]; + ((Ipp32u*)pArray)[1] = pData[1]; + } + if(dataSize) + ((Ipp32u*)pArray)[0] = pData[0]; + break; + case 16: // column - oword (16 bytes => 4 dword) + for(; dataSize>=4; dataSize-=4, pArray+=CACHE_LINE_SIZE, pData+=4) { + ((Ipp32u*)pArray)[0] = pData[0]; + ((Ipp32u*)pArray)[1] = pData[1]; + ((Ipp32u*)pArray)[2] = pData[2]; + ((Ipp32u*)pArray)[3] = pData[3]; + } + for(; dataSize>0; dataSize--, pArray+=sizeof(Ipp32u), pData++) + ((Ipp32u*)pArray)[0] = pData[0]; + break; + case 32: // column - 2 oword (32 bytes => 8 dword) + for(; dataSize>=8; dataSize-=8, pArray+=CACHE_LINE_SIZE, pData+=8) { + ((Ipp32u*)pArray)[0] = pData[0]; + ((Ipp32u*)pArray)[1] = pData[1]; + ((Ipp32u*)pArray)[2] = pData[2]; + ((Ipp32u*)pArray)[3] = pData[3]; + ((Ipp32u*)pArray)[4] = pData[4]; + ((Ipp32u*)pArray)[5] = pData[5]; + ((Ipp32u*)pArray)[6] = pData[6]; + ((Ipp32u*)pArray)[7] = pData[7]; + } + for(; dataSize>0; dataSize--, pArray+=sizeof(Ipp32u), pData++) + ((Ipp32u*)pArray)[0] = pData[0]; + break; + default: + break; + } +} + + +/* +// Retrieve data from pArray +*/ +#define u8_to_u32(b0,b1,b2,b3, x) \ + ((x) = (b0), \ + (x)|=((b1)<<8), \ + (x)|=((b2)<<16), \ + (x)|=((b3)<<24)) +#define u16_to_u32(w0,w1, x) \ + ((x) = (w0), \ + (x)|=((w1)<<16)) +#define u32_to_u64(dw0,dw1, x) \ + ((x) = (Ipp64u)(dw0), \ + (x)|= (((Ipp64u)(dw1))<<32)) + +__INLINE void cpScrambleGet(Ipp32u* pData, cpSize dataSize, + const Ipp8u* pArray, cpSize colummSize) +{ + int i; + switch(colummSize) { + case 1: // column - byte + for(i=0; i 2 dword) + for(; dataSize>=2; dataSize-=2, pArray+=CACHE_LINE_SIZE, pData+=2) { + pData[0] = ((Ipp32u*)pArray)[0]; + pData[1] = ((Ipp32u*)pArray)[1]; + } + if(dataSize) + pData[0] = ((Ipp32u*)pArray)[0]; + break; + case 16: // column - oword (16 bytes => 4 dword) + for(; dataSize>=4; dataSize-=4, pArray+=CACHE_LINE_SIZE, pData+=4) { + pData[0] = ((Ipp32u*)pArray)[0]; + pData[1] = ((Ipp32u*)pArray)[1]; + pData[2] = ((Ipp32u*)pArray)[2]; + pData[3] = ((Ipp32u*)pArray)[3]; + + } + for(; dataSize>0; dataSize--, pArray+=sizeof(Ipp32u), pData++) + pData[0] = ((Ipp32u*)pArray)[0]; + break; + case 32: // column - 2 oword (32 bytes => 8 dword) + for(; dataSize>=8; dataSize-=8, pArray+=CACHE_LINE_SIZE, pData+=8) { + pData[0] = ((Ipp32u*)pArray)[0]; + pData[1] = ((Ipp32u*)pArray)[1]; + pData[2] = ((Ipp32u*)pArray)[2]; + pData[3] = ((Ipp32u*)pArray)[3]; + pData[4] = ((Ipp32u*)pArray)[4]; + pData[5] = ((Ipp32u*)pArray)[5]; + pData[6] = ((Ipp32u*)pArray)[6]; + pData[7] = ((Ipp32u*)pArray)[7]; + } + for(; dataSize>0; dataSize--, pArray+=sizeof(Ipp32u), pData++) + pData[0] = ((Ipp32u*)pArray)[0]; + break; + default: + break; + } +} + +#endif /* _PC_SCRAMBLE_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1ca.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha1ca.c new file mode 100644 index 000000000..1bf44e126 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1ca.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// cpFinalizeSHA1() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + + +IPP_OWN_DEFN (void, cpFinalizeSHA1, (DigestSHA1 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u processedMsgLen)) +{ + /* select processing function */ + #if (_SHA_NI_ENABLING_==_FEATURE_ON_) + cpHashProc updateFunc = UpdateSHA1ni; + #elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_) + cpHashProc updateFunc = IsFeatureEnabled(ippCPUID_SHA)? UpdateSHA1ni : UpdateSHA1; + #else + cpHashProc updateFunc = UpdateSHA1; + #endif + + /* local buffer and it length */ + Ipp8u buffer[MBS_SHA1*2]; + int bufferLen = inpLen < (MBS_SHA1-(int)MLR_SHA1)? MBS_SHA1 : MBS_SHA1*2; + + /* copy rest of message into internal buffer */ + CopyBlock(inpBuffer, buffer, inpLen); + + /* padd message */ + buffer[inpLen++] = 0x80; + PadBlock(0, buffer+inpLen, (cpSize)(bufferLen-inpLen-(int)MLR_SHA1)); + + /* put processed message length in bits */ + processedMsgLen = ENDIANNESS64(processedMsgLen<<3); + ((Ipp64u*)(buffer+bufferLen))[-1] = processedMsgLen; + + /* copmplete hash computation */ + updateFunc(pHash, buffer, bufferLen, sha1_cnt); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1duplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha1duplicate.c new file mode 100644 index 000000000..f57b0447b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1duplicate.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsSHA1Duplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA1Duplicate +// +// Purpose: Clone SHA1 state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxSHA1 +// pDstState->idCtx != idCtxSHA1 +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source SHA1 state +// pDstState pointer to the target SHA1 state +// +// Note: +// pDstState may to be uninitialized by ippsSHA1Init() +// +*F*/ +IPPFUN(IppStatus, ippsSHA1Duplicate,(const IppsSHA1State* pSrcState, IppsSHA1State* pDstState)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcState, pDstState); + IPP_BADARG_RET(!HASH_VALID_ID(pSrcState, idCtxSHA1), ippStsContextMatchErr); + + /* copy state */ + CopyBlock(pSrcState, pDstState, sizeof(IppsSHA1State)); + HASH_SET_ID(pDstState, idCtxSHA1); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1final.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha1final.c new file mode 100644 index 000000000..a43405854 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1final.c @@ -0,0 +1,75 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsSHA1Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsSHA1Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA1 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SHS state +// +*F*/ +IPPFUN(IppStatus, ippsSHA1Final,(Ipp8u* pMD, IppsSHA1State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA1), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + + cpFinalizeSHA1(HASH_VALUE(pState), HASH_BUFF(pState), HASH_BUFFIDX(pState), HASH_LENLO(pState)); + /* convert hash into big endian */ + ((Ipp32u*)pMD)[0] = ENDIANNESS32(HASH_VALUE(pState)[0]); + ((Ipp32u*)pMD)[1] = ENDIANNESS32(HASH_VALUE(pState)[1]); + ((Ipp32u*)pMD)[2] = ENDIANNESS32(HASH_VALUE(pState)[2]); + ((Ipp32u*)pMD)[3] = ENDIANNESS32(HASH_VALUE(pState)[3]); + ((Ipp32u*)pMD)[4] = ENDIANNESS32(HASH_VALUE(pState)[4]); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + sha1_hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha1getsize.c new file mode 100644 index 000000000..7984cbdfb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1getsize.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsSHA1GetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA1GetSize +// +// Purpose: Returns size (bytes) of IppsSHA1State state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ +IPPFUN(IppStatus, ippsSHA1GetSize,(int* pSize)) +{ + /* test pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsSHA1State); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha1gettag.c new file mode 100644 index 000000000..20b7273d9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1gettag.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsSHA1GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsSHA1GetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA1 +// ippStsLengthErr max_SHA_digestLen < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHS state +// +*F*/ +IPPFUN(IppStatus, ippsSHA1GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA1State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA1), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSHA1)idCtx != idCtxSHA1 +// ippStsNoErr no errors +// +// Parameters: +// pState pointer to the hash state +// pBuffer pointer to the destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsSHA1Pack,(const IppsSHA1State* pState, Ipp8u* pBuffer)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA1), ippStsContextMatchErr); + + CopyBlock(pState, pBuffer, sizeof(IppsSHA1State)); + IppsSHA1State* pCopy = (IppsSHA1State*)pBuffer; + HASH_RESET_ID(pCopy, idCtxSHA1); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1stuff.h b/plugin/ippcp/library/src/sources/ippcp/pcpsha1stuff.h new file mode 100644 index 000000000..a1a93a691 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1stuff.h @@ -0,0 +1,87 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// SHA1 stuff +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" + +#if !defined(_CP_HASH_SHA1) +#define _CP_HASH_SHA1 + +/* SHA-1 constants */ +static const Ipp32u sha1_iv[] = { + 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}; + +static __ALIGN16 const Ipp32u sha1_cnt[] = { + 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 +}; + +IPP_OWN_DEFN (static void, sha1_hashInit, (void* pHash)) +{ + /* setup initial digest */ + ((Ipp32u*)pHash)[0] = sha1_iv[0]; + ((Ipp32u*)pHash)[1] = sha1_iv[1]; + ((Ipp32u*)pHash)[2] = sha1_iv[2]; + ((Ipp32u*)pHash)[3] = sha1_iv[3]; + ((Ipp32u*)pHash)[4] = sha1_iv[4]; +} + +IPP_OWN_DEFN (static void, sha1_hashUpdate, (void* pHash, const Ipp8u* pMsg, int msgLen)) +{ + UpdateSHA1(pHash, pMsg, msgLen, sha1_cnt); +} + +#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_) +IPP_OWN_DEFN (static void, sha1_ni_hashUpdate, (void* pHash, const Ipp8u* pMsg, int msgLen)) +{ + UpdateSHA1ni(pHash, pMsg, msgLen, sha1_cnt); +} +#endif + +IPP_OWN_DEFN (static void, sha1_hashOctString, (Ipp8u* pMD, void* pHashVal)) +{ + /* convert hash into big endian */ + ((Ipp32u*)pMD)[0] = ENDIANNESS32(((Ipp32u*)pHashVal)[0]); + ((Ipp32u*)pMD)[1] = ENDIANNESS32(((Ipp32u*)pHashVal)[1]); + ((Ipp32u*)pMD)[2] = ENDIANNESS32(((Ipp32u*)pHashVal)[2]); + ((Ipp32u*)pMD)[3] = ENDIANNESS32(((Ipp32u*)pHashVal)[3]); + ((Ipp32u*)pMD)[4] = ENDIANNESS32(((Ipp32u*)pHashVal)[4]); +} + +IPP_OWN_DEFN (static void, sha1_msgRep, (Ipp8u* pDst, Ipp64u lenLo, Ipp64u lenHi)) +{ + IPP_UNREFERENCED_PARAMETER(lenHi); + lenLo = ENDIANNESS64(lenLo<<3); + ((Ipp64u*)(pDst))[0] = lenLo; +} + +#define cpFinalizeSHA1 OWNAPI(cpFinalizeSHA1) + IPP_OWN_DECL (void, cpFinalizeSHA1, (DigestSHA1 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u processedMsgLen)) + +#endif /* #if !defined(_CP_HASH_SHA1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1unpack.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha1unpack.c new file mode 100644 index 000000000..16e028789 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1unpack.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsSHA1Unpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA1Unpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// pBuffer == NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the input buffer +// pCtx pointer hash state +// +*F*/ +IPPFUN(IppStatus, ippsSHA1Unpack,(const Ipp8u* pBuffer, IppsSHA1State* pCtx)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pCtx, pBuffer); + + CopyBlock(pBuffer, pCtx, sizeof(IppsSHA1State)); + HASH_SET_ID(pCtx, idCtxSHA1); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha1update.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha1update.c new file mode 100644 index 000000000..2ce129969 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha1update.c @@ -0,0 +1,122 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA1 +// +// Contents: +// ippsSHA1Update() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha1stuff.h" + +/*F* +// Name: ippsSHA1Update +// +// Purpose: Updates intermediate digest based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA1 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the SHA1 state +// +*F*/ +IPPFUN(IppStatus, ippsSHA1Update,(const Ipp8u* pSrc, int len, IppsSHA1State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA1), ippStsContextMatchErr); + + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + /* + // handle non empty message + */ + if(len) { + /* select processing function */ + #if (_SHA_NI_ENABLING_==_FEATURE_ON_) + cpHashProc updateFunc = UpdateSHA1ni; + #elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_) + cpHashProc updateFunc = IsFeatureEnabled(ippCPUID_SHA)? UpdateSHA1ni : UpdateSHA1; + #else + cpHashProc updateFunc = UpdateSHA1; + #endif + + int procLen; + + int idx = HASH_BUFFIDX(pState); + Ipp8u* pBuffer = HASH_BUFF(pState); + Ipp64u lenLo = HASH_LENLO(pState) + (Ipp64u)len; + + /* if non empty internal buffer filling */ + if(idx) { + /* copy from input stream to the internal buffer as match as possible */ + procLen = IPP_MIN(len, (MBS_SHA1-idx)); + CopyBlock(pSrc, pBuffer+idx, procLen); + + /* update message pointer and length */ + idx += procLen; + pSrc += procLen; + len -= procLen; + + /* update digest if buffer full */ + if( MBS_SHA1 == idx) { + updateFunc(HASH_VALUE(pState), pBuffer, MBS_SHA1, sha1_cnt); + idx = 0; + } + } + + /* main message part processing */ + procLen = len & ~(MBS_SHA1-1); + if(procLen) { + updateFunc(HASH_VALUE(pState), pSrc, procLen, sha1_cnt); + pSrc += procLen; + len -= procLen; + } + + /* store rest of message into the internal buffer */ + if(len) { + CopyBlock(pSrc, pBuffer, len); + idx += len; + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_BUFFIDX(pState) = idx; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha224duplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha224duplicate.c new file mode 100644 index 000000000..e12c77d94 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha224duplicate.c @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA224Duplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA224Duplicate +// +// Purpose: Clone SHA224 state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxSHA256 +// pDstState->idCtx != idCtxSHA256 +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source SHA224 state +// pDstState pointer to the target SHA224 state +// +// Note: +// pDstState may to be uninitialized by ippsSHA224Init() +// +*F*/ + +IPPFUN(IppStatus, ippsSHA224Duplicate,(const IppsSHA224State* pSrcState, IppsSHA224State* pDstState)) +{ + return ippsSHA256Duplicate(pSrcState, pDstState); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha224final.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha224final.c new file mode 100644 index 000000000..6869bdb2b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha224final.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA224Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsSHA224Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA256 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SHA224 state +// +*F*/ + +IPPFUN(IppStatus, ippsSHA224Final,(Ipp8u* pMD, IppsSHA224State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA256), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + + cpFinalizeSHA256(HASH_VALUE(pState), HASH_BUFF(pState), HASH_BUFFIDX(pState), HASH_LENLO(pState)); + /* convert hash into big endian */ + ((Ipp32u*)pMD)[0] = ENDIANNESS32(HASH_VALUE(pState)[0]); + ((Ipp32u*)pMD)[1] = ENDIANNESS32(HASH_VALUE(pState)[1]); + ((Ipp32u*)pMD)[2] = ENDIANNESS32(HASH_VALUE(pState)[2]); + ((Ipp32u*)pMD)[3] = ENDIANNESS32(HASH_VALUE(pState)[3]); + ((Ipp32u*)pMD)[4] = ENDIANNESS32(HASH_VALUE(pState)[4]); + ((Ipp32u*)pMD)[5] = ENDIANNESS32(HASH_VALUE(pState)[5]); + ((Ipp32u*)pMD)[6] = ENDIANNESS32(HASH_VALUE(pState)[6]); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + sha224_hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha224getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha224getsize.c new file mode 100644 index 000000000..cb0b472c7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha224getsize.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA224GetSize() +// +*/ + +/*F* +// Name: ippsSHA224GetSize +// +// Purpose: Returns size (bytes) of IppsSHA224State state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +IPPFUN(IppStatus, ippsSHA224GetSize,(int* pSize)) +{ + return GetSizeSHA256(pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha224gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha224gettag.c new file mode 100644 index 000000000..4d3f57040 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha224gettag.c @@ -0,0 +1,82 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA224GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsSHA224GetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA256 +// ippStsLengthErr max_SHA_digestLen < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHA224 state +// +*F*/ + +IPPFUN(IppStatus, ippsSHA224GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA224State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA256), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSHA224)idCtx != idCtxSHA256 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the SHA224 state +// +*F*/ + +IPPFUN(IppStatus, ippsSHA224Update,(const Ipp8u* pSrc, int len, IppsSHA224State* pState)) +{ + return ippsSHA256Update(pSrc, len, pState); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha256_messagedigest.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha256_messagedigest.c new file mode 100644 index 000000000..e33565bab --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha256_messagedigest.c @@ -0,0 +1,87 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// cpSHA256MessageDigest() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +IPP_OWN_DEFN (IppStatus, cpSHA256MessageDigest, (DigestSHA256 hash, const Ipp8u* pMsg, int msgLen, const DigestSHA256 IV)) +{ + /* test digest pointer */ + IPP_BAD_PTR1_RET(hash); + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + { + /* select processing function */ + #if (_SHA_NI_ENABLING_==_FEATURE_ON_) + cpHashProc updateFunc = UpdateSHA256ni; + #elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_) + cpHashProc updateFunc = IsFeatureEnabled(ippCPUID_SHA)? UpdateSHA256ni : UpdateSHA256; + #else + cpHashProc updateFunc = UpdateSHA256; + #endif + + /* message length in the multiple MBS and the rest */ + int msgLenBlks = msgLen & (-MBS_SHA256); + int msgLenRest = msgLen - msgLenBlks; + + /* init hash */ + hash[0] = IV[0]; + hash[1] = IV[1]; + hash[2] = IV[2]; + hash[3] = IV[3]; + hash[4] = IV[4]; + hash[5] = IV[5]; + hash[6] = IV[6]; + hash[7] = IV[7]; + + /* process main part of the message */ + if(msgLenBlks) { + updateFunc(hash, pMsg, msgLenBlks, sha256_cnt); + pMsg += msgLenBlks; + } + + cpFinalizeSHA256(hash, pMsg, msgLenRest, (Ipp64u)msgLen); + hash[0] = ENDIANNESS32(hash[0]); + hash[1] = ENDIANNESS32(hash[1]); + hash[2] = ENDIANNESS32(hash[2]); + hash[3] = ENDIANNESS32(hash[3]); + hash[4] = ENDIANNESS32(hash[4]); + hash[5] = ENDIANNESS32(hash[5]); + hash[6] = ENDIANNESS32(hash[6]); + hash[7] = ENDIANNESS32(hash[7]); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha256ca.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha256ca.c new file mode 100644 index 000000000..f2f78ddd6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha256ca.c @@ -0,0 +1,65 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// cpFinalizeSHA256() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +IPP_OWN_DEFN (void, cpFinalizeSHA256, (DigestSHA256 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u processedMsgLen)) +{ + /* select processing function */ + #if (_SHA_NI_ENABLING_==_FEATURE_ON_) + cpHashProc updateFunc = UpdateSHA256ni; + #elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_) + cpHashProc updateFunc = IsFeatureEnabled(ippCPUID_SHA)? UpdateSHA256ni : UpdateSHA256; + #else + cpHashProc updateFunc = UpdateSHA256; + #endif + + /* local buffer and it length */ + Ipp8u buffer[MBS_SHA256*2]; + int bufferLen = inpLen < (MBS_SHA256-(int)MLR_SHA256)? MBS_SHA256 : MBS_SHA256*2; + + /* copy rest of message into internal buffer */ + CopyBlock(inpBuffer, buffer, inpLen); + + /* padd message */ + buffer[inpLen++] = 0x80; + PadBlock(0, buffer+inpLen, (cpSize)(bufferLen-inpLen-(int)MLR_SHA256)); + + /* put processed message length in bits */ + processedMsgLen = ENDIANNESS64(processedMsgLen<<3); + ((Ipp64u*)(buffer+bufferLen))[-1] = processedMsgLen; + + /* copmplete hash computation */ + updateFunc(pHash, buffer, bufferLen, sha256_cnt); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha256duplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha256duplicate.c new file mode 100644 index 000000000..ad7bb24f4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha256duplicate.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA256Duplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA256Duplicate +// +// Purpose: Clone SHA256 state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxSHA256 +// pDstState->idCtx != idCtxSHA256 +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source SHA256 state +// pDstState pointer to the target SHA256 state +// +// Note: +// pDstState may to be uninitialized by ippsSHA256Init() +// +*F*/ +IPPFUN(IppStatus, ippsSHA256Duplicate,(const IppsSHA256State* pSrcState, IppsSHA256State* pDstState)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcState, pDstState); + /* test states ID */ + IPP_BADARG_RET(!HASH_VALID_ID(pSrcState, idCtxSHA256), ippStsContextMatchErr); + + /* copy state */ + CopyBlock(pSrcState, pDstState, sizeof(IppsSHA256State)); + HASH_SET_ID(pDstState, idCtxSHA256); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha256final.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha256final.c new file mode 100644 index 000000000..5f488fddb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha256final.c @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA256Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + + +/*F* +// Name: ippsSHA256Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA256 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SHA256 state +// +*F*/ +IPPFUN(IppStatus, ippsSHA256Final,(Ipp8u* pMD, IppsSHA256State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA256), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + + cpFinalizeSHA256(HASH_VALUE(pState), HASH_BUFF(pState), HASH_BUFFIDX(pState), HASH_LENLO(pState)); + /* convert hash into big endian */ + ((Ipp32u*)pMD)[0] = ENDIANNESS32(HASH_VALUE(pState)[0]); + ((Ipp32u*)pMD)[1] = ENDIANNESS32(HASH_VALUE(pState)[1]); + ((Ipp32u*)pMD)[2] = ENDIANNESS32(HASH_VALUE(pState)[2]); + ((Ipp32u*)pMD)[3] = ENDIANNESS32(HASH_VALUE(pState)[3]); + ((Ipp32u*)pMD)[4] = ENDIANNESS32(HASH_VALUE(pState)[4]); + ((Ipp32u*)pMD)[5] = ENDIANNESS32(HASH_VALUE(pState)[5]); + ((Ipp32u*)pMD)[6] = ENDIANNESS32(HASH_VALUE(pState)[6]); + ((Ipp32u*)pMD)[7] = ENDIANNESS32(HASH_VALUE(pState)[7]); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + sha256_hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha256getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha256getsize.c new file mode 100644 index 000000000..6ca1db62e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha256getsize.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA256GetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsSHA256GetSize +// +// Purpose: Returns size (bytes) of IppsSHA256State state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ +IPPFUN(IppStatus, ippsSHA256GetSize,(int* pSize)) +{ + return GetSizeSHA256(pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha256gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha256gettag.c new file mode 100644 index 000000000..d398460c0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha256gettag.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SHA256 +// +// Contents: +// ippsSHA256GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha256stuff.h" + +/*F* +// Name: ippsSHA256GetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA256 +// ippStsLengthErr max_SHA_digestLen < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHA256 state +// +*F*/ +IPPFUN(IppStatus, ippsSHA256GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA256State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA256), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSHA256)idCtx != idCtxSHA256 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the SHA256 state +// +*F*/ +IPPFUN(IppStatus, ippsSHA256Update,(const Ipp8u* pSrc, int len, IppsSHA256State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA256), ippStsContextMatchErr); + + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + /* + // handle non empty message + */ + if(len) { + /* select processing function */ + #if (_SHA_NI_ENABLING_==_FEATURE_ON_) + cpHashProc updateFunc = UpdateSHA256ni; + #elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_) + cpHashProc updateFunc = IsFeatureEnabled(ippCPUID_SHA)? UpdateSHA256ni : UpdateSHA256; + #else + cpHashProc updateFunc = UpdateSHA256; + #endif + + int procLen; + + int idx = HASH_BUFFIDX(pState); + Ipp8u* pBuffer = HASH_BUFF(pState); + Ipp64u lenLo = HASH_LENLO(pState) + (Ipp64u)len; + + /* if non empty internal buffer filling */ + if(idx) { + /* copy from input stream to the internal buffer as match as possible */ + procLen = IPP_MIN(len, (MBS_SHA256-idx)); + CopyBlock(pSrc, pBuffer+idx, procLen); + + /* update message pointer and length */ + pSrc += procLen; + len -= procLen; + idx += procLen; + + /* update digest if buffer full */ + if( MBS_SHA256 == idx) { + updateFunc(HASH_VALUE(pState), pBuffer, MBS_SHA256, sha256_cnt); + idx = 0; + } + } + + /* main message part processing */ + procLen = len & ~(MBS_SHA256-1); + if(procLen) { + updateFunc(HASH_VALUE(pState), pSrc, procLen, sha256_cnt); + pSrc += procLen; + len -= procLen; + } + + /* store rest of message into the internal buffer */ + if(len) { + CopyBlock(pSrc, pBuffer, len); + idx += len; + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_BUFFIDX(pState) = idx; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha384duplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha384duplicate.c new file mode 100644 index 000000000..9faabfda7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha384duplicate.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA384Duplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA384Duplicate +// +// Purpose: Clone SHA512 state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxSHA512 +// pDstState->idCtx != idCtxSHA512 +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source SHA384 state +// pDstState pointer to the target SHA384 state +// Note: +// pDstState may to be uninitialized by ippsSHA384Init() +// +*F*/ + +IPPFUN(IppStatus, ippsSHA384Duplicate,(const IppsSHA384State* pSrcState, IppsSHA384State* pDstState)) +{ + return ippsSHA512Duplicate(pSrcState, pDstState); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha384final.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha384final.c new file mode 100644 index 000000000..74333422d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha384final.c @@ -0,0 +1,80 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA384Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsSHA384Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA512 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SHA384 state +// +*F*/ + +IPPFUN(IppStatus, ippsSHA384Final,(Ipp8u* pMD, IppsSHA384State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA512), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + + cpFinalizeSHA512(HASH_VALUE(pState), + HASH_BUFF(pState), HASH_BUFFIDX(pState), + HASH_LENLO(pState), HASH_LENHI(pState)); + /* convert hash into big endian */ + ((Ipp64u*)pMD)[0] = ENDIANNESS64(HASH_VALUE(pState)[0]); + ((Ipp64u*)pMD)[1] = ENDIANNESS64(HASH_VALUE(pState)[1]); + ((Ipp64u*)pMD)[2] = ENDIANNESS64(HASH_VALUE(pState)[2]); + ((Ipp64u*)pMD)[3] = ENDIANNESS64(HASH_VALUE(pState)[3]); + ((Ipp64u*)pMD)[4] = ENDIANNESS64(HASH_VALUE(pState)[4]); + ((Ipp64u*)pMD)[5] = ENDIANNESS64(HASH_VALUE(pState)[5]); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + HASH_LENHI(pState) = 0; + sha512_384_hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha384getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha384getsize.c new file mode 100644 index 000000000..84bdbc2e0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha384getsize.c @@ -0,0 +1,53 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA384GetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsSHA384GetSize +// +// Purpose: Returns size (bytes) of IppsSHA384State state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ + +IPPFUN(IppStatus, ippsSHA384GetSize,(int* pSize)) +{ + return GetSizeSHA512(pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha384gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha384gettag.c new file mode 100644 index 000000000..40af46b61 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha384gettag.c @@ -0,0 +1,82 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA384GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsSHA384GetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA512 +// ippStsLengthErr max_SHA_digestLen < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHA384 state +// +*F*/ + +IPPFUN(IppStatus, ippsSHA384GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA384State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA512), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSHA384)idCtx != idCtxSHA512 +// ippStsNoErr no errors +// +// Parameters: +// pState pointer hash state +// pBuffer pointer to the destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsSHA384Pack,(const IppsSHA384State* pState, Ipp8u* pBuffer)) +{ + return ippsSHA512Pack(pState, pBuffer); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha384unpack.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha384unpack.c new file mode 100644 index 000000000..00d27ecf0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha384unpack.c @@ -0,0 +1,54 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA384Unpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA384Unpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pBuffer== NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the input buffer +// pState pointer hash state +// +*F*/ + +IPPFUN(IppStatus, ippsSHA384Unpack,(const Ipp8u* pBuffer, IppsSHA384State* pState)) +{ + return ippsSHA512Unpack(pBuffer, pState); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha384update.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha384update.c new file mode 100644 index 000000000..dec3ec84c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha384update.c @@ -0,0 +1,57 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA384Update() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA384Update +// +// Purpose: Updates intermadiate digest based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA512 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the SHA384 state +// +*F*/ + +IPPFUN(IppStatus, ippsSHA384Update,(const Ipp8u* pSrc, int len, IppsSHA384State* pState)) +{ + return ippsSHA512Update(pSrc, len, pState); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512_init.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512_init.c new file mode 100644 index 000000000..adc9dc5d5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512_init.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// InitSHA512() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +IPP_OWN_DEFN (IppStatus, InitSHA512, (IppsSHA512State* pState, const DigestSHA512 IV)) +{ + /* test state pointer */ + IPP_BAD_PTR1_RET(pState); + + /* set state ID */ + HASH_SET_ID(pState, idCtxSHA512); + /* zeros message length */ + HASH_LENLO(pState) = 0; + HASH_LENHI(pState) = 0; + /* message buffer is free */ + HASH_BUFFIDX(pState) = 0; + /* setup initial digest */ + hashInit(HASH_VALUE(pState), IV); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512_messagedigest.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512_messagedigest.c new file mode 100644 index 000000000..d551fdb4f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512_messagedigest.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// cpSHA512MessageDigest() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +IPP_OWN_DEFN (IppStatus, cpSHA512MessageDigest, (DigestSHA512 hash, const Ipp8u* pMsg, int msgLen, const DigestSHA512 IV)) +{ + /* test digest pointer */ + IPP_BAD_PTR1_RET(hash); + /* test message length */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + /* test message pointer */ + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + { + /* message length in the multiple MBS and the rest */ + int msgLenBlks = msgLen & (-MBS_SHA512); + int msgLenRest = msgLen - msgLenBlks; + + /* init hash */ + hashInit(hash, IV); + + /* process main part of the message */ + if(msgLenBlks) { + UpdateSHA512(hash, pMsg, msgLenBlks, sha512_cnt); + pMsg += msgLenBlks; + } + + cpFinalizeSHA512(hash, pMsg, msgLenRest, (Ipp64u)msgLen, 0); + hash[0] = ENDIANNESS64(hash[0]); + hash[1] = ENDIANNESS64(hash[1]); + hash[2] = ENDIANNESS64(hash[2]); + hash[3] = ENDIANNESS64(hash[3]); + hash[4] = ENDIANNESS64(hash[4]); + hash[5] = ENDIANNESS64(hash[5]); + hash[6] = ENDIANNESS64(hash[6]); + hash[7] = ENDIANNESS64(hash[7]); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512duplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512duplicate.c new file mode 100644 index 000000000..0a93ecd7a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512duplicate.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA512Duplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA512Duplicate +// +// Purpose: Clone SHA512 state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxSHA512 +// pDstState->idCtx != idCtxSHA512 +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source SHA512 state +// pDstState pointer to the target SHA512 state +// Note: +// pDstState may to be uninitialized by ippsSHA512Init() +// +*F*/ +IPPFUN(IppStatus, ippsSHA512Duplicate,(const IppsSHA512State* pSrcState, IppsSHA512State* pDstState)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcState, pDstState); + /* test states ID */ + IPP_BADARG_RET(!HASH_VALID_ID(pSrcState, idCtxSHA512), ippStsContextMatchErr); + + /* copy state */ + CopyBlock(pSrcState, pDstState, sizeof(IppsSHA512State)); + HASH_SET_ID(pDstState, idCtxSHA512); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512final.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512final.c new file mode 100644 index 000000000..f1721b876 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512final.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA512Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsSHA512Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pMD == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA512 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SHA512 state +// +*F*/ +IPPFUN(IppStatus, ippsSHA512Final,(Ipp8u* pMD, IppsSHA512State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA512), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + + cpFinalizeSHA512(HASH_VALUE(pState), + HASH_BUFF(pState), HASH_BUFFIDX(pState), + HASH_LENLO(pState), HASH_LENHI(pState)); + /* convert hash into big endian */ + ((Ipp64u*)pMD)[0] = ENDIANNESS64(HASH_VALUE(pState)[0]); + ((Ipp64u*)pMD)[1] = ENDIANNESS64(HASH_VALUE(pState)[1]); + ((Ipp64u*)pMD)[2] = ENDIANNESS64(HASH_VALUE(pState)[2]); + ((Ipp64u*)pMD)[3] = ENDIANNESS64(HASH_VALUE(pState)[3]); + ((Ipp64u*)pMD)[4] = ENDIANNESS64(HASH_VALUE(pState)[4]); + ((Ipp64u*)pMD)[5] = ENDIANNESS64(HASH_VALUE(pState)[5]); + ((Ipp64u*)pMD)[6] = ENDIANNESS64(HASH_VALUE(pState)[6]); + ((Ipp64u*)pMD)[7] = ENDIANNESS64(HASH_VALUE(pState)[7]); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + HASH_LENHI(pState) = 0; + sha512_hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512getsize.c new file mode 100644 index 000000000..c9277fbae --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512getsize.c @@ -0,0 +1,52 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA512GetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsSHA512GetSize +// +// Purpose: Returns size (bytes) of IppsSHA512State state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ +IPPFUN(IppStatus, ippsSHA512GetSize,(int* pSize)) +{ + return GetSizeSHA512(pSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512gettag.c new file mode 100644 index 000000000..c657cc745 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512gettag.c @@ -0,0 +1,83 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA512GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsSHA512GetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA512 +// ippStsLengthErr max_SHA_digestLen < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHA512 state +// +*F*/ +IPPFUN(IppStatus, ippsSHA512GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA512State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA512), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSHA512)idCtx != idCtxSHA512 +// ippStsNoErr no errors +// +// Parameters: +// pState pointer hash state +// pBuffer pointer to the destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsSHA512Pack,(const IppsSHA512State* pState, Ipp8u* pBuffer)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA512), ippStsContextMatchErr); + + CopyBlock(pState, pBuffer, sizeof(IppsSHA512State)); + IppsSHA512State* pCopy = (IppsSHA512State*)pBuffer; + HASH_RESET_ID(pCopy, idCtxSHA512); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512stuff.h b/plugin/ippcp/library/src/sources/ippcp/pcpsha512stuff.h new file mode 100644 index 000000000..2c0fc981a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512stuff.h @@ -0,0 +1,200 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// SHA512 stuff +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +#if !defined(_PCP_SHA512_STUFF_H) +#define _PCP_SHA512_STUFF_H + +/* SHA-512, SHA-384, SHA512-224, SHA512 constants */ +static const Ipp64u sha512_iv[] = { + CONST_64(0x6A09E667F3BCC908), CONST_64(0xBB67AE8584CAA73B), + CONST_64(0x3C6EF372FE94F82B), CONST_64(0xA54FF53A5F1D36F1), + CONST_64(0x510E527FADE682D1), CONST_64(0x9B05688C2B3E6C1F), + CONST_64(0x1F83D9ABFB41BD6B), CONST_64(0x5BE0CD19137E2179)}; +static const Ipp64u sha512_384_iv[] = { + CONST_64(0xCBBB9D5DC1059ED8), CONST_64(0x629A292A367CD507), + CONST_64(0x9159015A3070DD17), CONST_64(0x152FECD8F70E5939), + CONST_64(0x67332667FFC00B31), CONST_64(0x8EB44A8768581511), + CONST_64(0xDB0C2E0D64F98FA7), CONST_64(0x47B5481DBEFA4FA4)}; +static const Ipp64u sha512_256_iv[] = { + CONST_64(0x22312194FC2BF72C), CONST_64(0x9F555FA3C84C64C2), + CONST_64(0x2393B86B6F53B151), CONST_64(0x963877195940EABD), + CONST_64(0x96283EE2A88EFFE3), CONST_64(0xBE5E1E2553863992), + CONST_64(0x2B0199FC2C85B8AA), CONST_64(0x0EB72DDC81C52CA2)}; +static const Ipp64u sha512_224_iv[] = { + CONST_64(0x8C3D37C819544DA2), CONST_64(0x73E1996689DCD4D6), + CONST_64(0x1DFAB7AE32FF9C82), CONST_64(0x679DD514582F9FCF), + CONST_64(0x0F6D2B697BD44DA8), CONST_64(0x77E36F7304C48942), + CONST_64(0x3F9D85A86A1D36C8), CONST_64(0x1112E6AD91D692A1)}; + +static __ALIGN16 const Ipp64u sha512_cnt[] = { + CONST_64(0x428A2F98D728AE22), CONST_64(0x7137449123EF65CD), CONST_64(0xB5C0FBCFEC4D3B2F), CONST_64(0xE9B5DBA58189DBBC), + CONST_64(0x3956C25BF348B538), CONST_64(0x59F111F1B605D019), CONST_64(0x923F82A4AF194F9B), CONST_64(0xAB1C5ED5DA6D8118), + CONST_64(0xD807AA98A3030242), CONST_64(0x12835B0145706FBE), CONST_64(0x243185BE4EE4B28C), CONST_64(0x550C7DC3D5FFB4E2), + CONST_64(0x72BE5D74F27B896F), CONST_64(0x80DEB1FE3B1696B1), CONST_64(0x9BDC06A725C71235), CONST_64(0xC19BF174CF692694), + CONST_64(0xE49B69C19EF14AD2), CONST_64(0xEFBE4786384F25E3), CONST_64(0x0FC19DC68B8CD5B5), CONST_64(0x240CA1CC77AC9C65), + CONST_64(0x2DE92C6F592B0275), CONST_64(0x4A7484AA6EA6E483), CONST_64(0x5CB0A9DCBD41FBD4), CONST_64(0x76F988DA831153B5), + CONST_64(0x983E5152EE66DFAB), CONST_64(0xA831C66D2DB43210), CONST_64(0xB00327C898FB213F), CONST_64(0xBF597FC7BEEF0EE4), + CONST_64(0xC6E00BF33DA88FC2), CONST_64(0xD5A79147930AA725), CONST_64(0x06CA6351E003826F), CONST_64(0x142929670A0E6E70), + CONST_64(0x27B70A8546D22FFC), CONST_64(0x2E1B21385C26C926), CONST_64(0x4D2C6DFC5AC42AED), CONST_64(0x53380D139D95B3DF), + CONST_64(0x650A73548BAF63DE), CONST_64(0x766A0ABB3C77B2A8), CONST_64(0x81C2C92E47EDAEE6), CONST_64(0x92722C851482353B), + CONST_64(0xA2BFE8A14CF10364), CONST_64(0xA81A664BBC423001), CONST_64(0xC24B8B70D0F89791), CONST_64(0xC76C51A30654BE30), + CONST_64(0xD192E819D6EF5218), CONST_64(0xD69906245565A910), CONST_64(0xF40E35855771202A), CONST_64(0x106AA07032BBD1B8), + CONST_64(0x19A4C116B8D2D0C8), CONST_64(0x1E376C085141AB53), CONST_64(0x2748774CDF8EEB99), CONST_64(0x34B0BCB5E19B48A8), + CONST_64(0x391C0CB3C5C95A63), CONST_64(0x4ED8AA4AE3418ACB), CONST_64(0x5B9CCA4F7763E373), CONST_64(0x682E6FF3D6B2B8A3), + CONST_64(0x748F82EE5DEFB2FC), CONST_64(0x78A5636F43172F60), CONST_64(0x84C87814A1F0AB72), CONST_64(0x8CC702081A6439EC), + CONST_64(0x90BEFFFA23631E28), CONST_64(0xA4506CEBDE82BDE9), CONST_64(0xBEF9A3F7B2C67915), CONST_64(0xC67178F2E372532B), + CONST_64(0xCA273ECEEA26619C), CONST_64(0xD186B8C721C0C207), CONST_64(0xEADA7DD6CDE0EB1E), CONST_64(0xF57D4F7FEE6ED178), + CONST_64(0x06F067AA72176FBA), CONST_64(0x0A637DC5A2C898A6), CONST_64(0x113F9804BEF90DAE), CONST_64(0x1B710B35131C471B), + CONST_64(0x28DB77F523047D84), CONST_64(0x32CAAB7B40C72493), CONST_64(0x3C9EBE0A15C9BEBC), CONST_64(0x431D67C49C100D4C), + CONST_64(0x4CC5D4BECB3E42B6), CONST_64(0x597F299CFC657E2A), CONST_64(0x5FCB6FAB3AD6FAEC), CONST_64(0x6C44198C4A475817) +}; + +/* setup init hash value */ +__INLINE void hashInit(Ipp64u* pHash, const Ipp64u* iv) +{ + pHash[0] = iv[0]; + pHash[1] = iv[1]; + pHash[2] = iv[2]; + pHash[3] = iv[3]; + pHash[4] = iv[4]; + pHash[5] = iv[5]; + pHash[6] = iv[6]; + pHash[7] = iv[7]; +} +IPP_OWN_DEFN (static void, sha512_hashInit, (void* pHash)) +{ + hashInit((Ipp64u*)pHash, sha512_iv); +} +IPP_OWN_DEFN (static void, sha512_384_hashInit, (void* pHash)) +{ + hashInit((Ipp64u*)pHash, sha512_384_iv); +} +IPP_OWN_DEFN (static void, sha512_256_hashInit, (void* pHash)) +{ + hashInit((Ipp64u*)pHash, sha512_256_iv); +} +IPP_OWN_DEFN (static void, sha512_224_hashInit, (void* pHash)) +{ + hashInit((Ipp64u*)pHash, sha512_224_iv); +} + +IPP_OWN_DEFN (static void, sha512_hashUpdate, (void* pHash, const Ipp8u* pMsg, int msgLen)) +{ + UpdateSHA512(pHash, pMsg, msgLen, sha512_cnt); +} + +/* convert hash into big endian */ +IPP_OWN_DEFN (static void, sha512_hashOctString, (Ipp8u* pMD, void* pHashVal)) +{ + ((Ipp64u*)pMD)[0] = ENDIANNESS64(((Ipp64u*)pHashVal)[0]); + ((Ipp64u*)pMD)[1] = ENDIANNESS64(((Ipp64u*)pHashVal)[1]); + ((Ipp64u*)pMD)[2] = ENDIANNESS64(((Ipp64u*)pHashVal)[2]); + ((Ipp64u*)pMD)[3] = ENDIANNESS64(((Ipp64u*)pHashVal)[3]); + ((Ipp64u*)pMD)[4] = ENDIANNESS64(((Ipp64u*)pHashVal)[4]); + ((Ipp64u*)pMD)[5] = ENDIANNESS64(((Ipp64u*)pHashVal)[5]); + ((Ipp64u*)pMD)[6] = ENDIANNESS64(((Ipp64u*)pHashVal)[6]); + ((Ipp64u*)pMD)[7] = ENDIANNESS64(((Ipp64u*)pHashVal)[7]); +} +IPP_OWN_DEFN (static void, sha512_384_hashOctString, (Ipp8u* pMD, void* pHashVal)) +{ + ((Ipp64u*)pMD)[0] = ENDIANNESS64(((Ipp64u*)pHashVal)[0]); + ((Ipp64u*)pMD)[1] = ENDIANNESS64(((Ipp64u*)pHashVal)[1]); + ((Ipp64u*)pMD)[2] = ENDIANNESS64(((Ipp64u*)pHashVal)[2]); + ((Ipp64u*)pMD)[3] = ENDIANNESS64(((Ipp64u*)pHashVal)[3]); + ((Ipp64u*)pMD)[4] = ENDIANNESS64(((Ipp64u*)pHashVal)[4]); + ((Ipp64u*)pMD)[5] = ENDIANNESS64(((Ipp64u*)pHashVal)[5]); +} +IPP_OWN_DEFN (static void, sha512_256_hashOctString, (Ipp8u* pMD, void* pHashVal)) +{ + ((Ipp64u*)pMD)[0] = ENDIANNESS64(((Ipp64u*)pHashVal)[0]); + ((Ipp64u*)pMD)[1] = ENDIANNESS64(((Ipp64u*)pHashVal)[1]); + ((Ipp64u*)pMD)[2] = ENDIANNESS64(((Ipp64u*)pHashVal)[2]); + ((Ipp64u*)pMD)[3] = ENDIANNESS64(((Ipp64u*)pHashVal)[3]); +} +IPP_OWN_DEFN (static void, sha512_224_hashOctString, (Ipp8u* pMD, void* pHashVal)) +{ + ((Ipp64u*)pMD)[0] = ENDIANNESS64(((Ipp64u*)pHashVal)[0]); + ((Ipp64u*)pMD)[1] = ENDIANNESS64(((Ipp64u*)pHashVal)[1]); + ((Ipp64u*)pMD)[2] = ENDIANNESS64(((Ipp64u*)pHashVal)[2]); + ((Ipp32u*)pMD)[6] = ENDIANNESS32(((Ipp32u*)pHashVal)[7]); +} + +IPP_OWN_DEFN (static void, sha512_msgRep, (Ipp8u* pDst, Ipp64u lenLo, Ipp64u lenHi)) +{ + lenHi = LSL64(lenHi,3) | LSR64(lenLo,63-3); + lenLo = LSL64(lenLo,3); + ((Ipp64u*)(pDst))[0] = ENDIANNESS64(lenHi); + ((Ipp64u*)(pDst))[1] = ENDIANNESS64(lenLo); +} + +IPP_OWN_DEFN (static IppStatus, GetSizeSHA512, (int* pSize)) +{ + /* test pointer */ + IPP_BAD_PTR1_RET(pSize); + *pSize = sizeof(IppsSHA512State); + return ippStsNoErr; +} + +/* #define cpFinalizeSHA512 OWNAPI(cpFinalizeSHA512) */ + /* IPP_OWN_DECL (void, cpFinalizeSHA512, (DigestSHA512 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u lenLo, Ipp64u lenHi)) */ +#define cpSHA512MessageDigest OWNAPI(cpSHA512MessageDigest) + IPP_OWN_DECL (IppStatus, cpSHA512MessageDigest, (DigestSHA512 hash, const Ipp8u* pMsg, int msgLen, const DigestSHA512 IV)) +#define InitSHA512 OWNAPI(InitSHA512) + IPP_OWN_DECL (IppStatus, InitSHA512, (IppsSHA512State* pState, const DigestSHA512 IV)) + +IPP_OWN_DEFN (static void, cpFinalizeSHA512, (DigestSHA512 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u lenLo, Ipp64u lenHi)) +{ + /* local buffer and it length */ + Ipp8u buffer[MBS_SHA512*2]; + int bufferLen = inpLen < (MBS_SHA512-(int)MLR_SHA512)? MBS_SHA512 : MBS_SHA512*2; + + /* copy rest of message into internal buffer */ + CopyBlock(inpBuffer, buffer, inpLen); + + /* padd message */ + buffer[inpLen++] = 0x80; + PadBlock(0, buffer+inpLen, (cpSize)(bufferLen-inpLen-(int)MLR_SHA512)); + + /* message length representation */ + lenHi = LSL64(lenHi,3) | LSR64(lenLo,63-3); + lenLo = LSL64(lenLo,3); + ((Ipp64u*)(buffer+bufferLen))[-2] = ENDIANNESS64(lenHi); + ((Ipp64u*)(buffer+bufferLen))[-1] = ENDIANNESS64(lenLo); + + /* copmplete hash computation */ + UpdateSHA512(pHash, buffer, bufferLen, sha512_cnt); +} + +#endif /* #if !defined(_PCP_SHA512_STUFF_H) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512unpack.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512unpack.c new file mode 100644 index 000000000..0278675a5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512unpack.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA512Unpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSHA512Unpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pBuffer== NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the input buffer +// pState pointer hash state +// +*F*/ +IPPFUN(IppStatus, ippsSHA512Unpack,(const Ipp8u* pBuffer, IppsSHA512State* pState)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + + CopyBlock(pBuffer, pState, sizeof(IppsSHA512State)); + HASH_SET_ID(pState, idCtxSHA512); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsha512update.c b/plugin/ippcp/library/src/sources/ippcp/pcpsha512update.c new file mode 100644 index 000000000..80c512f18 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsha512update.c @@ -0,0 +1,116 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SHA512 message digest +// +// Contents: +// ippsSHA512Update() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsha512stuff.h" + +/*F* +// Name: ippsSHA512Update +// +// Purpose: Updates intermadiate digest based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSHA512 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the SHA512 state +// +*F*/ +IPPFUN(IppStatus, ippsSHA512Update,(const Ipp8u* pSrc, int len, IppsSHA512State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSHA512), ippStsContextMatchErr); + + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + /* + // handle non empty message + */ + if(len) { + int procLen; + + int idx = HASH_BUFFIDX(pState); + Ipp8u* pBuffer = HASH_BUFF(pState); + Ipp64u lenLo = HASH_LENLO(pState) + (Ipp64u)len; + Ipp64u lenHi = HASH_LENHI(pState); + if(lenLo < HASH_LENLO(pState)) lenHi++; + + /* if non empty internal buffer filling */ + if(idx) { + /* copy from input stream to the internal buffer as match as possible */ + procLen = IPP_MIN(len, (MBS_SHA512-idx)); + CopyBlock(pSrc, pBuffer+idx, procLen); + + /* update message pointer and length */ + pSrc += procLen; + len -= procLen; + idx += procLen; + + /* update digest if buffer full */ + if(MBS_SHA512 == idx) { + UpdateSHA512(HASH_VALUE(pState), pBuffer, MBS_SHA512, sha512_cnt); + idx = 0; + } + } + + /* main message part processing */ + procLen = len & ~(MBS_SHA512-1); + if(procLen) { + UpdateSHA512(HASH_VALUE(pState), pSrc, procLen, sha512_cnt); + pSrc += procLen; + len -= procLen; + } + + /* store rest of message into the internal buffer */ + if(len) { + CopyBlock(pSrc, pBuffer, len); + idx += len; + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_LENHI(pState) = lenHi; + HASH_BUFFIDX(pState) = idx; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpshsmgfca.c b/plugin/ippcp/library/src/sources/ippcp/pcpshsmgfca.c new file mode 100644 index 000000000..121814e9d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpshsmgfca.c @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// HASH based Mask Generation Functions +// +// Contents: +// ippsMGF_SHA1() +// ippsMGF_SHA224() +// ippsMGF_SHA256() +// ippsMGF_SHA384() +// ippsMGF_SHA512() +// ippsMGF_MD5() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcptool.h" + + +/*F* +// Name: ippsMGF_SHA1 +// ippsMGF_SHA224 +// ippsMGF_SHA256 +// ippsMGF_SHA384 +// ippsMGF_SHA512 +// ippsMGF_MD5 +// +// Purpose: Mask Generation Functions. +// +// Returns: Reason: +// ippStsNullPtrErr pMask == NULL +// ippStsLengthErr seedLen <0 +// maskLen <0 +// ippStsNotSupportedModeErr if algID is not match to supported hash alg +// ippStsNoErr no errors +// +// Parameters: +// pSeed pointer to the input stream +// seedLen input stream length (bytes) +// pMask pointer to the ouput mask +// maskLen desired length of mask (bytes) +// hashAlg identifier of the hash algorithm +// +*F*/ +IPPFUN(IppStatus, ippsMGF, (const Ipp8u* pSeed, int seedLen, Ipp8u* pMask, int maskLen, IppHashAlgId hashAlg)) +{ + /* get algorithm id */ + hashAlg = cpValidHashAlg(hashAlg); + /* test hash alg */ + IPP_BADARG_RET(ippHashAlg_Unknown==hashAlg, ippStsNotSupportedModeErr); + + IPP_BAD_PTR1_RET(pMask); + IPP_BADARG_RET((seedLen<0)||(maskLen<0), ippStsLengthErr); + + { + /* hash specific */ + int hashSize = cpHashSize(hashAlg); + + int i, outLen; + + IppsHashState hashCtx; + ippsHashInit(&hashCtx, hashAlg); + + if(!pSeed) + seedLen = 0; + + for(i=0,outLen=0; outLen>24) & 0xFF); + cnt[1] = (Ipp8u)((i>>16) & 0xFF); + cnt[2] = (Ipp8u)((i>>8) & 0xFF); + cnt[3] = (Ipp8u)(i & 0xFF); + + cpReInitHash(&hashCtx, hashAlg); + ippsHashUpdate(pSeed, seedLen, &hashCtx); + ippsHashUpdate(cnt, 4, &hashCtx); + + if((outLen + hashSize) <= maskLen) { + ippsHashFinal(pMask+outLen, &hashCtx); + outLen += hashSize; + } + else { + Ipp8u md[MAX_HASH_SIZE]; + ippsHashFinal(md, &hashCtx); + CopyBlock(md, pMask+outLen, maskLen-outLen); + outLen = maskLen; + } + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm2pprecomca.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm2pprecomca.c new file mode 100644 index 000000000..15ed1bcfa --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm2pprecomca.c @@ -0,0 +1,2540 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// EC over Prime Finite Field (SM2 precomputed) +// +// +*/ +#include "owncp.h" +#include "pcpgfpecstuff.h" + + +#define OPERAND_BITSIZE (256) +#define LEN_P256 (BITS_BNU_CHUNK(OPERAND_BITSIZE)) + +/* SM2 affine point */ +typedef struct{ + BNU_CHUNK_T X[LEN_P256]; + BNU_CHUNK_T Y[LEN_P256]; +} SM2_POINT_AFFINE; + +extern const __ALIGN64 SM2_POINT_AFFINE precomputed_ec_sm2[37][64]; + + +#if defined( _IPP_DATA ) + +#if !defined(_DISABLE_ECP_SM2_HARDCODED_BP_TBL_) +/* see ippcp_baseptbl.cpp test for generation details */ + +const __ALIGN64 SM2_POINT_AFFINE precomputed_ec_sm2[37][64] = { +/* digit=0 base_pwr=2^0 */ +{ + LL(0xf418029e,0x61328990),LL(0xdca6c050,0x3e7981ed),LL(0xac24c3c3,0xd6a1ed99),LL(0xe1c13b05,0x91167a5e), LL(0x3c2d0ddd,0xc1354e59),LL(0x8d3295fa,0xc1f5e578),LL(0x6e2a48f8,0x8d4cfb06),LL(0x81d735bd,0x63cd65d4), + LL(0xbc3be46a,0x0af037bf),LL(0x2d8fa938,0x83bdc9ba),LL(0x5788cd24,0x5349d94b),LL(0xcaa5736a,0x0d7e9c18), LL(0x69db9ac1,0x6a7e1a1d),LL(0xc4a8e82b,0xccbd8d37),LL(0x9b7157ac,0xc7b14516),LL(0x6c21bdf5,0x947e7465), + LL(0xab589e4a,0x1cda54fd),LL(0xdb4f0a0d,0x26765289),LL(0x8ceb4a0a,0x0a265a30),LL(0xfe887c64,0x3019fd6b), LL(0x4b2fc190,0x0a10fbe9),LL(0x87cbce60,0xf40aa52b),LL(0x6dc13c97,0xcc496bfa),LL(0x5bb3fbb4,0x28ad3478), + LL(0x98615060,0x393f7c5a),LL(0xe9016209,0x487ea27f),LL(0xa09f9020,0x8a86bcb4),LL(0xc899dbe1,0x50dc8e3a), LL(0xfd619998,0xfc099043),LL(0x7c7383bd,0x1de135ea),LL(0x32cf70ed,0x4d0bd556),LL(0x25bce9e3,0x6ffc31c5), + LL(0x6a9c8162,0x9a575633),LL(0x21dfcc53,0x15aa58f2),LL(0x1ef5f4c5,0x7ad354bf),LL(0x63f875b9,0x0f443ef3), LL(0xd3450133,0x2e81d68f),LL(0xe3607d18,0xb30f4bbd),LL(0x362258ef,0xb1826a4c),LL(0x142a6768,0x7b415276), + LL(0x0acd72ba,0x136a9c4c),LL(0x5e7ec73c,0xb1274a25),LL(0x5de34db6,0xf15a876e),LL(0x8cba8047,0x85e74ca0), LL(0xb469eb37,0x08454cdd),LL(0xc99754f8,0x8fbf6d1f),LL(0xec30e984,0x1060e7f8),LL(0x4b8c598a,0xb568bc97), + LL(0x81f06784,0xaa3531c7),LL(0x07132520,0x0b894193),LL(0xacfe18c5,0x84ee5b69),LL(0xd9fbec28,0xbbf492e0), LL(0xe5f6186d,0x313a35c1),LL(0x757a01b8,0x0e449a2e),LL(0x2bd99baf,0x96c9b992),LL(0x3b84d777,0x2ba05a8f), + LL(0x09122670,0xde523a1c),LL(0x22cc810c,0x90be6f2a),LL(0x4387df9e,0x086e6341),LL(0xd9c44134,0x115c2fc0), LL(0x8799302a,0x9334430d),LL(0xe27b7ea4,0x693b3500),LL(0x9a8f3382,0xcbe1136f),LL(0xb5778247,0xe77fd5f2), + LL(0x30fbde86,0x98e795c3),LL(0xab21af8f,0x8e5e0495),LL(0xb48669b4,0x3925bf83),LL(0x469522c8,0x77d88740), LL(0x987b04ce,0x8fbf8b5b),LL(0x3aff4428,0x63c563a8),LL(0x53a6e969,0x5dc11165),LL(0x32697f4c,0x822a6c24), + LL(0x642cb143,0x6774298a),LL(0x2d110e71,0xecdb60d8),LL(0x1388728e,0xe810b11b),LL(0xd8603a8a,0x2e8237d8), LL(0x50aeeae1,0x673968fc),LL(0x6746a3f4,0x08c65d19),LL(0xd7dd7165,0x7a61a6b5),LL(0xa9b6df3a,0xe31bbfd9), + LL(0x3421e115,0x2b252ad0),LL(0xc6affc01,0x7557c8c7),LL(0x8a509267,0xd90c19fd),LL(0xe0d871c8,0x483da168), LL(0xc10729bf,0x72d6f9b3),LL(0x15b7061e,0x5dd84021),LL(0x9f2c587d,0x9bfea2db),LL(0x98641ec2,0x528398a7), + LL(0xf3afdd62,0x18a65d8d),LL(0xd6d7e4e4,0x89f38500),LL(0x9d8d4f07,0x65708c6a),LL(0xd0bdc7f4,0xb90ea13c), LL(0x8c3e2b32,0x58985855),LL(0xbcfad3a1,0xfa48d5c5),LL(0x62385ffa,0x5c3544e7),LL(0x7e72aeb7,0xb6bd39ed), + LL(0x8000fe4e,0x34e51c6a),LL(0x89c46941,0x7da2bdfd),LL(0xe1bc2b2e,0x667ba91d),LL(0x10a73e5c,0x3c80c9d0), LL(0xc7f5c64d,0x4fadebbe),LL(0x3ea35052,0xaef09eb4),LL(0x26ec55f9,0x167ee11b),LL(0x85189260,0x45fa508a), + LL(0x22542fc3,0xa0e9a439),LL(0xddac78dc,0x3f194a6c),LL(0x6f74d053,0xa75ae72d),LL(0x097c6617,0x0f8babeb), LL(0x4303c247,0x1d12bc5c),LL(0xbd1e246c,0xfe0c027a),LL(0xb69b55ad,0xe9ca1a99),LL(0x117cd63a,0xff6cd2b0), + LL(0xdde97d4d,0xf3489343),LL(0xbbb2ce1f,0x9c14e38a),LL(0xcfddf221,0x25866911),LL(0x460efef1,0x0df89411), LL(0x73ae8326,0xf713f30e),LL(0xcdd274a1,0xd9be66a8),LL(0x36885947,0xdf915ae2),LL(0x7878b781,0x2c5c1e9e), + LL(0x39e8a120,0xf71560c9),LL(0x7273b59a,0x7121d6b8),LL(0x8ef4639d,0x649535ce),LL(0x14cc6d58,0xcd01076e), LL(0x96e74f8a,0x2705729a),LL(0x5533037e,0xb07e3230),LL(0x663c5c62,0x0846dcc1),LL(0x10fc3ac1,0x6a4759c1), + LL(0xcfbdfeff,0x3c126193),LL(0x4996d845,0x4a31dd20),LL(0x19f2b658,0x48a76ba0),LL(0x8890a8bc,0xbe330142), LL(0x308aa041,0x287b34e1),LL(0x813adf29,0xcbf5da24),LL(0xcdcdc439,0xcdfc5a58),LL(0x198a6075,0xbda3bda2), + LL(0x1497fe38,0x639f92bc),LL(0xd58bd278,0x8ed8eeac),LL(0xb417bfe4,0xcf5d7ce6),LL(0x44400c59,0xf617c54e), LL(0x7d8dc939,0xde635635),LL(0x241baaff,0x2e6a3a75),LL(0xe07e8e97,0x02f324e5),LL(0x70f9fc9d,0xeb715487), + LL(0x86712116,0xbefd3380),LL(0x884efe46,0x9b9e9707),LL(0x8c9e513f,0x611a1eec),LL(0x3b6dbcec,0xe2d8e3f5), LL(0x4f8964e4,0x7cedab1c),LL(0xf4e139f8,0xee12d062),LL(0x9a9af4f3,0x8e63c9c0),LL(0x8b907b23,0xe3246dbb), + LL(0x71099001,0x70d5bda2),LL(0x15fae7dd,0x3d876d4a),LL(0x7b69c20e,0xaba0500f),LL(0x9834adf2,0xa8e3e094), LL(0x980b21b9,0x69db851b),LL(0x788c2a30,0x274c1de2),LL(0xd47d153d,0x5caa5336),LL(0x57cef318,0xada69877), + LL(0xa0551c80,0x83879486),LL(0x658e61be,0x1611dea0),LL(0x1b935068,0x1fe95c82),LL(0x5b229223,0x8f01e019), LL(0x7e93c389,0x23017e05),LL(0x9840dd64,0xce4ac99d),LL(0x1de86399,0xddc9b900),LL(0x88015785,0x6abe5cc3), + LL(0xb3c50898,0xc09545a9),LL(0x6c05d902,0xbd443361),LL(0x2c6bcc8c,0xed71f70c),LL(0xbdf8e908,0x8dbc0b88), LL(0x4fcbcd9a,0x56eb5b98),LL(0x08114397,0xafb6fedc),LL(0xb35f7927,0x0500ce5b),LL(0x95efe710,0x7005bcf9), + LL(0x2eba7f39,0x125cbed2),LL(0x6c488d44,0xc7c42e76),LL(0x676915c4,0xdb8991f9),LL(0x9183839f,0xdf6ae594), LL(0xc79f8bd1,0x4f69c304),LL(0xaa1662fa,0x638cb070),LL(0xba6f2599,0xc7f68c72),LL(0x1f6edfa9,0x11bb84d9), + LL(0xa215fda2,0x9ed156ec),LL(0x20c5ddb6,0x19de7a91),LL(0x0668c65d,0xc1ed949d),LL(0xd0826f6a,0x96683044), LL(0x1adaa8ff,0x1e6325e0),LL(0x07ac392a,0xbc53bc24),LL(0xd9f06e44,0x2c342db5),LL(0x30db8c1a,0x3f529385), + LL(0xe7492326,0xc5957d29),LL(0x0663f829,0x3addc3df),LL(0x728cfdc1,0x8faa3169),LL(0x6b975134,0xde53aa7c), LL(0xefddc764,0xf481759b),LL(0x09edaff3,0xd605474b),LL(0x653d48c9,0xc7df1eb9),LL(0xc5040212,0xa71e6854), + LL(0xafe945b5,0x136d8342),LL(0xe9d239c7,0x91707e7d),LL(0xfb2e80de,0xeda23dc5),LL(0xff614966,0x892bed73), LL(0x838dc12d,0x2ded2367),LL(0xb002bd9c,0x73fd298c),LL(0x2c4629df,0xc548b426),LL(0x8f7e03b7,0x93605d17), + LL(0xd37c24cc,0x32861816),LL(0xe427975a,0x5bb54ee2),LL(0x32f943a9,0x6da013d2),LL(0x9bc202e5,0x0746a77a), LL(0xcd1def5b,0x6db07a84),LL(0x861d9f9b,0x9421fe7f),LL(0x692181fb,0x71767292),LL(0xc9d2441d,0x0560e7e5), + LL(0x4d7e922a,0xf1496afd),LL(0xe11fa533,0x67f42a3f),LL(0x977956cd,0x9f903e5b),LL(0x1eb49608,0x37671e24), LL(0x21fb2047,0x967950a0),LL(0x35da3c6b,0x141f96fb),LL(0xd27bba59,0xe07c3c40),LL(0x0e1af754,0xbde5ed1d), + LL(0x54f1f257,0xdc64c4b0),LL(0xb01196dc,0xecb033c8),LL(0x8202d5bd,0x54e65f4d),LL(0x2b2fd451,0x63afcc93), LL(0x30640fb7,0x1e929a39),LL(0x5b361718,0xdc91387e),LL(0xf8f0bbe8,0x10aadecb),LL(0x0977e2bb,0x81d8f466), + LL(0xbd64cd96,0xdcaa3790),LL(0xcee698d3,0xbc8ac152),LL(0xa1143c45,0xde7192f7),LL(0xf5fb9ea0,0xf7c9d826), LL(0xc9468f50,0x54aea92e),LL(0xcc427ed4,0x340f4459),LL(0x02ad5467,0x3fec5be9),LL(0x2cc6c8b5,0xec780d9c), + LL(0xb889c78a,0x7b179a8b),LL(0x0aca32c5,0x069a7ab9),LL(0x591b9a36,0xe4e5215e),LL(0x3bd54630,0x7802fb3e), LL(0x233c6eeb,0x9a479313),LL(0x4e1cbabc,0x18c612ad),LL(0xc0e36f3b,0x28a29273),LL(0x7d3deb26,0xf4e2dfb1), + LL(0xadbb3c8b,0xa6c11369),LL(0x4c8ec378,0xd78af40b),LL(0x03f0a982,0xffb3a80d),LL(0xa83be50a,0x550e3e71), LL(0x418ee45b,0x845c0fb2),LL(0x0791b964,0x5297cf43),LL(0xcc47e33b,0x676b638c),LL(0xfecf85b2,0xb1c52fac), + LL(0x3dba2c0e,0xf011b5e5),LL(0x026d4f11,0xa6c68448),LL(0xc3f206fb,0x11596db3),LL(0x29414a3c,0xc91c76dc), LL(0xb94ddc7c,0x1839b9d1),LL(0x56ae8610,0xdfb20ce7),LL(0xd8734400,0x3e2b1cd9),LL(0xf01ea540,0x59f9329a), + LL(0x2351a2a9,0x7d4c140c),LL(0xbf4c9823,0x575c1e1b),LL(0x31068df9,0x8f11c2ca),LL(0x05e6def0,0xe3c17aa0), LL(0x501c8630,0xe6281c70),LL(0xc88a412e,0xad240917),LL(0x390492d7,0x6f21bfb7),LL(0xc3a3ccb7,0x61ea1385), + LL(0x33733cbc,0x60494a83),LL(0x27ed8157,0x8da622a0),LL(0x0471ad90,0x0022b154),LL(0xd3568003,0x3bd0a4c5), LL(0xd932df23,0xdc8e2d03),LL(0x7a1f5159,0x859ed940),LL(0x2a375b0f,0xad670e63),LL(0x9520db97,0x15922fae), + LL(0x59eb1a9b,0xfb73d16f),LL(0x8511e541,0x3ee8cc1f),LL(0x1590c321,0x20d72d59),LL(0x3bd075d4,0x62eab566), LL(0xfae123ab,0xac07a7c7),LL(0x1f10af6e,0x83b89abf),LL(0x1da8ac5d,0x469962ec),LL(0x8c58c3b3,0x09761c35), + LL(0x7da90fc9,0x2c086d5e),LL(0x5cc27782,0x458e5ffd),LL(0xb9268939,0xc3f48611),LL(0xde4b9110,0x39fed873), LL(0xfda698cc,0x16ef8f78),LL(0xa973bb50,0xb028dc21),LL(0xe29b725b,0x45eb849e),LL(0x14c6eae9,0xd41b5b6d), + LL(0xc55d5720,0x5e931b21),LL(0xa0e40b19,0xb628ccb2),LL(0x000651a5,0x42044ffe),LL(0x076544e7,0x2130b4de), LL(0x3677c70f,0x38428594),LL(0xf8945d86,0xfdcdb038),LL(0x4169ae44,0xfb2e3d4c),LL(0x0d13bce2,0xd4695e9b), + LL(0x039d646d,0x45191390),LL(0xb12ba339,0x983b7a2e),LL(0x5923e7d6,0xdfd30d3e),LL(0xba9d206a,0xae3590f0), LL(0xb6d5e62a,0x7d58d334),LL(0x7e402b12,0xb15b0544),LL(0x62ae8e01,0xac57e113),LL(0xf473edee,0x4d83804c), + LL(0xc81bc828,0x2faa7c4d),LL(0xfb62561f,0xb16ed9d7),LL(0x49c2fa93,0x4c9da270),LL(0xb311d90d,0x3b014c73), LL(0xf5443332,0xd29c5d65),LL(0xeebdb7c2,0xb6457d54),LL(0x4cce9480,0xc6a0bf3a),LL(0x85355854,0xd434a3b0), + LL(0x8b2c703c,0x178ca01b),LL(0x0ab71a51,0x605bba53),LL(0x3db948d5,0x2140948e),LL(0x5fb6b8c1,0xc45b2689), LL(0xf17b47bd,0x421f66de),LL(0x2e9b3ee5,0x57627a5a),LL(0x66614339,0xedf3920a),LL(0x4b638a46,0x7ea61903), + LL(0x3c030643,0x7203d542),LL(0x5e631461,0x7112bb3d),LL(0x2bc3da9c,0x2604eac7),LL(0x32d2541b,0x2e4964e7), LL(0xe8b6482a,0x940faf46),LL(0x24d27c9e,0x8f772fcb),LL(0xca7c5f88,0x125c34d7),LL(0xd1f47795,0x9903eadb), + LL(0xe2147129,0x11aaa417),LL(0xf88a0a30,0x3ccef5c2),LL(0x90283f97,0x78d5207a),LL(0xd25226b6,0xba1261e9), LL(0xd1e7a01c,0xbfc79248),LL(0x941ab2bd,0x373f1cd5),LL(0x19a0668b,0xf0881e21),LL(0x1f77bf0a,0x7b793789), + LL(0x63d4523d,0x49c2769b),LL(0xf0399eaf,0xf8df2cba),LL(0x22a2a74d,0x5ae94c69),LL(0xefd1e193,0xd08f8d45), LL(0xc681f376,0x64341fc4),LL(0xec918711,0x3a8e25c8),LL(0x0608f50f,0xdf35304d),LL(0x9a973742,0x9b4c6967), + LL(0xbfba043b,0xb5c1f5d3),LL(0xe975f03b,0xaff4f896),LL(0xae2cbb01,0xea1f39bd),LL(0xa62915ff,0x4cc1c4cb), LL(0x89e943b8,0x5eb4afa3),LL(0x154e565a,0x8c4d27e5),LL(0x7f2bced6,0x4e2e5a7e),LL(0x4487f6a3,0x7af408e2), + LL(0x97a60de7,0xe5dacbae),LL(0x4401b0ad,0x9774834c),LL(0x8a9113f9,0x7683bb00),LL(0x42b2ba67,0xc6fe7e8b), LL(0x54e760c8,0xc0c0564d),LL(0x118606c2,0xf7b05401),LL(0xec3cd7b9,0x554a9b0f),LL(0x27916a21,0xce75ecfb), + LL(0x12118abd,0xf6638997),LL(0x097da3a7,0x2ba6e754),LL(0x0fdf9985,0x1df82085),LL(0x546c864a,0xbf73502a), LL(0xc02d9ce0,0xdfde9323),LL(0xe4dd0e7d,0x580491e2),LL(0xae43b9b4,0xe71522d2),LL(0x6a231a41,0x876e3627), + LL(0xb36362ec,0xfa8ff511),LL(0x34085959,0x11c5a9f6),LL(0x9770c62b,0x272b86f2),LL(0x7c7e8827,0xf0626225), LL(0xea1e13eb,0x929168bf),LL(0xce59b0f5,0xdb892971),LL(0x4f826f34,0x6769e31d),LL(0x0a955cec,0xfa1dd934), + LL(0xa294d7ea,0x123d9ca2),LL(0x4492569b,0x8699063b),LL(0xa8dd86c3,0x6a50eae9),LL(0x12c06c38,0x3d757d10), LL(0x3e41e556,0x5a92c2c0),LL(0x6330c21a,0xa64595eb),LL(0xe184d925,0x70d8141a),LL(0xa2f10304,0x8543f2ce), + LL(0x9eaca504,0x4559b0a2),LL(0x2617bc9b,0xb9843a4b),LL(0x1b641003,0x5b28d4ee),LL(0x4ced538a,0x3e9af8e1), LL(0x7bdf7dc2,0x3790fe89),LL(0xc32549ee,0xc7c74941),LL(0xabcd2f42,0xdcc8295b),LL(0xead078b6,0x48b29a4f), + LL(0x2040178e,0x8e8b28e3),LL(0x971725fc,0xceff8f3e),LL(0xfcee2cc1,0x4a97b6fa),LL(0xbac85b56,0x775df6a9), LL(0xd28a21cc,0x32e5cbe6),LL(0xae2b82db,0xe8b86ada),LL(0x86e38e96,0x44dfbb50),LL(0x1afc2d4b,0x45d3fe7d), + LL(0xd23f620d,0x838b356e),LL(0x4592fe4b,0x2e8fa8ac),LL(0x3af5b1d8,0x1396e1b3),LL(0xcbf50fb0,0x9c0c2ef3), LL(0x836e93e9,0xd9efb6c9),LL(0x0899163f,0xe6eb5870),LL(0xdca00d1b,0x3a2f6d77),LL(0xb40ba0d6,0x36f55f89), + LL(0x32866e57,0xf3b1701f),LL(0x59de0f2e,0xf0768473),LL(0xab57962d,0xe55d7aed),LL(0x2b60cabb,0x45004985), LL(0xd5498888,0x8d539d6e),LL(0xa5e0ff6a,0x176ce1a0),LL(0xdc088c50,0xcb7c15ef),LL(0xc9a9ae2f,0x90393d7a), + LL(0xd396bdce,0xd9c1a140),LL(0x6fb2800f,0x4215b78b),LL(0x2f76b0df,0x8939109f),LL(0x2adb40a8,0x0f250897), LL(0x3a86e009,0x4db0007c),LL(0xf968a635,0x6ef0ad95),LL(0x8eaefa78,0x58a82d4b),LL(0x493604a4,0xe8a181cb), + LL(0x520d216d,0x36c84e34),LL(0xc666171c,0x2b2ef6b5),LL(0x2ce29d37,0x9469b91f),LL(0xc15f20aa,0x3ecd84e7), LL(0x292edd2c,0xf1090635),LL(0x7c3447f6,0x6d439362),LL(0x3eea3fdf,0x51b9a0a9),LL(0x9e57e450,0x68e0d1f8), + LL(0x7380931e,0x25d249d5),LL(0x2011a45b,0x87f03fad),LL(0xefde1ca3,0x89df0324),LL(0x9a9b4330,0x52ae43cd), LL(0xa1867c1b,0xfe48bc64),LL(0x9866920e,0xdd874f66),LL(0xfcf50251,0x6942a7e4),LL(0x9c5f6298,0xf5c10048), + LL(0x00973d66,0x305183eb),LL(0x95baf07c,0x1ce66760),LL(0x74822e13,0x74c9d971),LL(0x76b5e6ef,0x2ccd7fbb), LL(0xa3e1ca18,0x51688b49),LL(0xa603f2f1,0x1beb5bbb),LL(0x962534b6,0x09a231d1),LL(0xafa92f75,0x70417ce1), + LL(0xe154bc00,0xb86b6d82),LL(0x895483e5,0x5a0b19e8),LL(0xa0ff1e44,0xb15f6c05),LL(0xfdd8615d,0x2938b88a), LL(0x971615c3,0x81800a05),LL(0xc03d2039,0x6be6d56b),LL(0xc476ce64,0xff3e57d2),LL(0x6f583ee8,0x5b509b7b), + LL(0x7c1f5d3b,0x1d92c36c),LL(0xe11df757,0x1e60b19b),LL(0xe37e36f6,0x20261501),LL(0x29bc86e3,0xb68a9aaa), LL(0xf61d23ca,0xfba81eaa),LL(0xd5adaa18,0x63440834),LL(0xa5f93bb8,0xa80d76ed),LL(0x5a728480,0x3264283d), + LL(0xe4b8c48e,0xd6171111),LL(0xde557cca,0x3ee227a1),LL(0x3cb59841,0x2bebc09a),LL(0x99bf6205,0x2f8047fe), LL(0x4c43845f,0xb78b243e),LL(0x46d3b5e0,0x484ac183),LL(0x0314524d,0xa07be476),LL(0x1ab4c447,0xc0a3aa35), + LL(0x9c341f84,0x2f302d58),LL(0x84f130ba,0x264911a7),LL(0x3ee64343,0x30bed408),LL(0x5dc5868a,0xd7d6e92d), LL(0x80adb3fb,0x92074568),LL(0xa133123e,0x005ab33c),LL(0x42e1da50,0x105119fd),LL(0xb7f6b1e8,0x6987117d), + LL(0xc2bccb7a,0xa2315af3),LL(0x8672c98a,0x95ddd3ee),LL(0x5f48f607,0xa9032645),LL(0xc5273603,0x76861e62), LL(0x88817217,0x71aaa35f),LL(0x2892afac,0x57e95b6c),LL(0x9e84c791,0xf65e909b),LL(0xaa52f3b1,0x257bcc2d), + LL(0x865c665a,0xd5f6110a),LL(0x30c08b4c,0xddc3afe1),LL(0xefec26fc,0x4df3d04a),LL(0xb035af5d,0xf229bddf), LL(0xd191b439,0x364913cf),LL(0x5a7fa8a4,0xf41b8f6d),LL(0x6f6c1219,0x677cc51b),LL(0x148b7f64,0x593afe4a), + LL(0x0d038ad4,0x80ffa5ae),LL(0x36256c8f,0xf44d3df3),LL(0xbc978dce,0x0a3077c8),LL(0x745b8317,0xf3d9b4b0), LL(0xb6b1852c,0x8bbf4484),LL(0x0e78ff07,0x0cd02ed4),LL(0x49c24238,0x91cb827e),LL(0xdaa3cb55,0x58adaee5), +}, +/* digit=1 base_pwr=2^7 */ +{ + LL(0x033fc12a,0x07e6ce4d),LL(0x4886f316,0xba4f98a1),LL(0xe66f3f11,0xb24b38f3),LL(0x5ea4bde3,0xe3f6205a), LL(0xa77b998f,0x00705387),LL(0x9549f3b1,0x2c9b4457),LL(0x533a61d6,0xdef6625b),LL(0x7e4f781a,0x4eda7e2a), + LL(0xfd120134,0xe9730aaa),LL(0xc057309c,0xb22b9089),LL(0x84726ce7,0x98e79565),LL(0xd635a584,0x0e1431a0), LL(0xe834ffa6,0xbd387023),LL(0x036ab1ae,0x64198ddf),LL(0x9124b684,0x46e5ebb1),LL(0x233b3c6d,0xa316fa44), + LL(0x84782513,0xec2a9325),LL(0x2903d20b,0xd67c8ab7),LL(0x157f9aee,0x6b65b262),LL(0x69f964a2,0x547be60c), LL(0xee0419db,0x001bf327),LL(0xf20c7005,0x92fa0800),LL(0xcdc1ccda,0x1e11e745),LL(0xe471f822,0xa785ec10), + LL(0xa1371aa4,0xbc970210),LL(0x54b5424e,0xaff481a0),LL(0x0e64269b,0xbcdf91fd),LL(0xb02fc7cf,0x18bb37bb), LL(0x6f69d439,0xd99edd79),LL(0x169514b2,0x4e27a58f),LL(0x66e19ae4,0x80eca1ca),LL(0x0788696d,0x0470e965), + LL(0x8c9d34f6,0xa6b1992f),LL(0xa5ed969e,0xaf062ffe),LL(0x3a6d7ae2,0xbca2580d),LL(0xc8999158,0xf30cd9e6), LL(0x49d1ab0d,0x93e57897),LL(0x30214280,0xcfa3aa4d),LL(0x0a814831,0x0ca8b4fd),LL(0x0b10097c,0xdad179db), + LL(0x3dfdc228,0x63778bfc),LL(0xb9648a36,0xc0bae0ad),LL(0x015a99b5,0xda8cb8ab),LL(0x8366b58a,0xb045cccb), LL(0x4164cebd,0x74ef8ef4),LL(0xc5e00e5f,0x41e71fc8),LL(0x4479468e,0x753cf906),LL(0x332ea72d,0x78b5223f), + LL(0xddebafa2,0x8fc3e370),LL(0x351f9f04,0x15ffcce0),LL(0x45b0efdc,0x3fbd5f5c),LL(0x0fe3b460,0xb8216623), LL(0x533c7db6,0xe8322fbd),LL(0x00a243ff,0xf3866d15),LL(0xa0e5aaea,0xf1194ae2),LL(0xb9287b3d,0x3e93eb01), + LL(0x5876d6e8,0x528a9e2f),LL(0xd2b622d7,0x93c48f85),LL(0x3e5411d7,0x88d9eac8),LL(0x00a70e91,0xb7e4a6ba), LL(0xf1c43b2e,0xaf18e5ba),LL(0xa2f347de,0x46578c7e),LL(0xf009638f,0x19ca736d),LL(0xbd1acd29,0xa6563f1e), + LL(0x2f4126e7,0xdf9bcd3a),LL(0xd62efebd,0xecc22d13),LL(0x10943242,0xd9b29b4b),LL(0x670136f9,0x499ffa74), LL(0x2b889952,0xa2a9ad2c),LL(0xfd132dad,0x945f306e),LL(0x15cebfd7,0xfd05b884),LL(0xc7a5627f,0x653e70af), + LL(0x577dae35,0xfefc54b5),LL(0xaac3a655,0x9d2f0546),LL(0xfac31d00,0xb96bd298),LL(0xee69563d,0x3328a51c), LL(0x43195f4e,0x5e19098e),LL(0xa998010b,0x657f4ba5),LL(0x4047ccb6,0x45f29a84),LL(0x6e423da6,0x833a5443), + LL(0xca33f42b,0x97e480c6),LL(0x06e52a05,0x20a51033),LL(0x0a9be572,0x85e87255),LL(0xb988b582,0xe8bc857a), LL(0xc183c500,0x782495e8),LL(0xfee0ae2f,0xf33a87fd),LL(0xc64d1dec,0xf069fe20),LL(0xf4b08816,0x0b6dd98a), + LL(0x99229a90,0x6e6cf298),LL(0x1d71d532,0xa6840bc8),LL(0x71e3a8b7,0x803e5407),LL(0x6afd9a0e,0xd5611ee4), LL(0xbbbefa73,0xd739ca0e),LL(0xc5ec48b7,0x6082dbab),LL(0xbbdea0ec,0xa0ab10df),LL(0xf1633e03,0xb1b7ebe4), + LL(0x7be26441,0xfa752496),LL(0x0ef683e6,0xf52cb1b6),LL(0x39dd611d,0x1c96401f),LL(0x7bb19083,0x09c5a35b), LL(0x00a5d5a1,0xa2f002b8),LL(0xacf4e8ed,0x4e300ddd),LL(0xb4cc58c6,0x0d26b600),LL(0x50062651,0x5a53863a), + LL(0xad1cac22,0x62e64475),LL(0xc7e11395,0x2008653e),LL(0xd9479c4a,0xa875ad01),LL(0x804b30d1,0x3e6cf633), LL(0xb6b06e46,0x58b3ef6e),LL(0xf7b8410b,0x74c45dbe),LL(0xc278458d,0x02675759),LL(0xacd30bd1,0xb2ef4956), + LL(0x339aae8d,0x1a4a5773),LL(0x0c0fe175,0xa775b952),LL(0x5d5d5ac1,0x7b39ac1b),LL(0x11a511b6,0x3f183d49), LL(0x045ac045,0x9524e286),LL(0x4934c52f,0x0498d296),LL(0x9b636528,0x1fec5474),LL(0xc3e9b84b,0xec6f7a37), + LL(0x12ee579d,0x870b12dd),LL(0x06dd62d6,0x2a9a12ab),LL(0x071d7582,0xbcd52599),LL(0xa869c457,0x7a36193a), LL(0xe976ae5b,0xd29e6592),LL(0xadfecd58,0xe82c8712),LL(0xf714686d,0xbc83a440),LL(0x0c21e3ba,0xfe19344a), + LL(0xd7a191ae,0x2a32c989),LL(0x4e58caca,0x00a25163),LL(0xe4a11597,0x2c6501b8),LL(0x7f1891e6,0xb3e45d09), LL(0x659fd516,0xb7f532b1),LL(0xa7002930,0x99cf64de),LL(0xf2cd2d4d,0x56357ed4),LL(0x3447951f,0xa94cf5c5), + LL(0x76a164be,0x26c7f244),LL(0xa72e974c,0xbd83e20b),LL(0xda31de06,0x64e9c241),LL(0x1cdb203d,0x022bc0f0), LL(0x55c0601f,0x5eec4fcb),LL(0xb168a484,0xa1504f91),LL(0x1243026d,0xb9cf98b1),LL(0xfb3e5a1c,0x6a009deb), + LL(0x60657650,0xf1df3752),LL(0xcb1b8d9e,0xa5bbd8f5),LL(0x81b6af13,0x9e0d9447),LL(0x624cb828,0x8572cecf), LL(0xd003617a,0x28319d57),LL(0x996fde09,0x175c4766),LL(0x04878e13,0x168514b2),LL(0xec83a771,0x58a541d7), + LL(0x29fb000f,0xafdaad3b),LL(0xc20f56f5,0x1977a8de),LL(0xc5b7ba77,0x450faf6f),LL(0xe5954518,0x93253964), LL(0x644c3385,0x11ee0f31),LL(0xa8a57bad,0x6c24de9d),LL(0x5533a7ba,0xe8ff408c),LL(0xeace56fa,0x660a74d9), + LL(0x8cc2a866,0xb4b2543b),LL(0xeffc0cbf,0x69f23f18),LL(0x5308b9b1,0x0db4682a),LL(0x17037e08,0xce7fac53), LL(0x0a885b01,0xf02098c4),LL(0xb2e4eb6e,0xd375c03d),LL(0x70d4b81b,0xb6d4f6c1),LL(0x7ce5f297,0xa2b5e9cd), + LL(0xb8a233c3,0x787229cc),LL(0x3419867f,0x44ef5dd8),LL(0x79d3d8dc,0x00316d22),LL(0x90bb1410,0xdcf32003), LL(0x835d2264,0x62ad0125),LL(0x0ed6605c,0x768c8658),LL(0xfc44e760,0xa31abf17),LL(0xbb22e570,0xc91848ac), + LL(0xb16c805f,0xad1882f5),LL(0x7ccf9e9a,0xb74cc0ed),LL(0x7b122dd7,0x9635af23),LL(0x5c3cd11b,0x48a20903), LL(0x34c1eb54,0xa24820b6),LL(0x5284dcb3,0x31a3c330),LL(0x069c2ee4,0xd966cf59),LL(0xb3ff9335,0xa74eec6f), + LL(0x4620e739,0xf44eeb99),LL(0xf4159a9a,0x7663a596),LL(0xb4b745b1,0x79c54f42),LL(0x59db9482,0xa8d34937), LL(0x579501df,0x35fad92a),LL(0x289d7c2b,0x1d81bbe3),LL(0xddf3d371,0x1d60a274),LL(0x46df1233,0xf08e23e5), + LL(0xf3a95f04,0x4bc4c079),LL(0xa8626015,0x0b43e660),LL(0x246ae3ac,0xedb31526),LL(0x41247209,0xa8536eb6), LL(0xfdfacc62,0x6893a7df),LL(0xc557777b,0xf3de226f),LL(0x0d7f4265,0xa68c8d8c),LL(0x15c685e3,0x55a628eb), + LL(0x5ecec6ee,0x8cad8f87),LL(0x2a06c242,0x4aefda2d),LL(0x57f00a7d,0x46a21033),LL(0x7ed125cf,0x91910c3a), LL(0x541165d2,0x0b7f0e4a),LL(0x553eeec1,0x15ed1b93),LL(0xd24e020b,0xadf5b4db),LL(0xa7493b8b,0xf05307a3), + LL(0x62070042,0x725548dc),LL(0xc274916a,0x74d71526),LL(0x6f098d01,0x3269851e),LL(0xf9ec928c,0xb2e01cb7), LL(0x2b4368cd,0x96c2d922),LL(0xa0ec45d1,0x8eb84b03),LL(0x26e5b3ac,0x733ad068),LL(0x93c5a962,0xced3679e), + LL(0xdd6eb876,0x23c6a22d),LL(0xa343dc3b,0xbd98ad9a),LL(0x56054515,0x61933d03),LL(0xe45cd744,0x4a64b769), LL(0x12586de6,0x617a63f3),LL(0x7976e7d1,0x04984a9f),LL(0xcd2a0a6b,0xb00ba446),LL(0x7d059d46,0x5b64e7f5), + LL(0x6a4b08e6,0x8801ce04),LL(0xb13bbe9c,0x66f31460),LL(0x4d87114e,0xb174e887),LL(0xf348e94f,0xb2fee192), LL(0x7c822d05,0xfede2283),LL(0x8f82b14a,0x8d50c49c),LL(0x0f5f1b5d,0x21ea4f6e),LL(0xc1818095,0x68627cf0), + LL(0x8a7b2458,0xc1c0650c),LL(0x8bbc6aff,0x82ab62bb),LL(0x6ce6989d,0x7b3665d7),LL(0x7579e973,0x2ad7991f), LL(0x7e9e8510,0x701287aa),LL(0x0a18da53,0xb296a038),LL(0x2bf00fdc,0xf8c3af86),LL(0xb220dc06,0x55776951), + LL(0x7d7dd541,0x4e6e4b4f),LL(0xfe5c7431,0x812feac7),LL(0x340297b1,0x6bdfa63e),LL(0x98009910,0xecc11e55), LL(0xb25b98c0,0xee4c6165),LL(0x02c5939c,0x8a07b0d2),LL(0x23147c40,0x9b36c176),LL(0xde2eab3a,0x396054a2), + LL(0x2c439171,0x1f41010b),LL(0xe8139388,0x3ff85ee6),LL(0x8f077633,0x4ada4c7d),LL(0x824e6023,0x9976011a), LL(0xeaf49f63,0xa2501197),LL(0xd60b0c4c,0xdff2122f),LL(0xbab3df90,0x1a6a3abb),LL(0xb66ffd5f,0x854bbcc6), + LL(0x728572c1,0x525964a9),LL(0xfadbd14b,0x8a4923a2),LL(0xcd90b61b,0x03830df9),LL(0x79c2afe9,0xcdb00f4a), LL(0xa6c3f13d,0xff2f84bb),LL(0x5c0de4dd,0xdee45c30),LL(0xfba2e933,0x3e1dd748),LL(0x7c51124c,0xe9dcc690), + LL(0x28e11f62,0x725177af),LL(0x8a64fdf5,0xc8e120a1),LL(0xf24fb357,0x82ab73df),LL(0x44724879,0x2d5d1618), LL(0x96c66b86,0x09627e26),LL(0xc81d38c1,0x1d547cae),LL(0xd0f76658,0xbe8991a4),LL(0xcf11a976,0xf1508662), + LL(0x3be3e582,0xa5dafebd),LL(0x07399295,0xd9f545ba),LL(0x676f9598,0xd9f564a4),LL(0x9294431e,0xec00bddf), LL(0xc1fdc758,0xc1971113),LL(0x69a001de,0xe32f572f),LL(0xb907f044,0x048d7776),LL(0x5ca10e67,0x4a474e6e), + LL(0x3039a4b7,0x6476dd40),LL(0x018ee2b8,0x85de9baa),LL(0xfd7365f2,0x0c945aeb),LL(0x96c7267e,0x2b47dc0d), LL(0x0410de25,0xb12b48a7),LL(0x177242c1,0x3ba7a11a),LL(0x6504ff87,0x44e6cee7),LL(0x9d19f26c,0xb2605ff6), + LL(0x50fb1b6b,0xa56bb589),LL(0x71d2fb53,0x98dc1180),LL(0xa1b78e04,0xa4fdc6f8),LL(0x39d9349d,0xbea745b0), LL(0x62d7eb73,0xac474229),LL(0x8b808ac3,0x7b765138),LL(0xd0ca219f,0x882370af),LL(0x9d1c23e8,0x28dcff7b), + LL(0x3872f0a9,0xc6dc70eb),LL(0xdfb642b1,0xb2f21248),LL(0x65bbdfc9,0x86838f0f),LL(0x40b28364,0x1d04a8b5), LL(0x1e4d8d58,0xd4fa229d),LL(0xfad0a9cd,0x74ee5e20),LL(0x5a40ec4a,0x25a59aae),LL(0x3727d6cd,0x73be91f3), + LL(0xd63f64eb,0x9c31405e),LL(0x91d2f1c1,0x9943c34c),LL(0x4fcdbf34,0x70ad75d7),LL(0xb239e00d,0xa6ce7145), LL(0xcd04b9e9,0x136bceed),LL(0x44ed7f96,0xb9ebeb8d),LL(0x5d136280,0x068b43a5),LL(0x4c559b6b,0x2e1b6624), + LL(0x5472d67b,0xe3808e72),LL(0xce74546e,0x73450378),LL(0xea1d58f7,0xc1b1b66e),LL(0xe34c2a7d,0x2b576e4f), LL(0x2f732803,0xc2b1bdf7),LL(0x9f8e48c3,0x37aea390),LL(0x944f1cf3,0x8bbbb61e),LL(0x86c59643,0x5cc7ccaa), + LL(0x8d5b000a,0xaf4c18e3),LL(0x2b6d561c,0x23b0edd0),LL(0x0d6cbe27,0x11b67ef0),LL(0xb1b50e9d,0x679d789b), LL(0x372c4015,0xda198336),LL(0x65781ea7,0x5da50baf),LL(0x550201ba,0x00b3a6d4),LL(0xecfffc72,0x988b89f7), + LL(0x25948852,0xf2f08a09),LL(0x406d1a34,0x4036bbb7),LL(0x23d2dd87,0x1cd57f08),LL(0x4704dac3,0x11a4387e), LL(0xc5413b59,0xb8091a7a),LL(0x09b5fa71,0xe58940c6),LL(0x6a75397c,0x70fd5154),LL(0x5c59ff75,0xea544375), + LL(0xac25bd3a,0x15e5bed3),LL(0x6b17971e,0x1bed3c33),LL(0xbaa96968,0x046fc1cd),LL(0x7090256f,0xda1b010d), LL(0xe6677d20,0xeec55752),LL(0x24c9bb42,0x8eac5d06),LL(0x8f4120e0,0xc2f6270e),LL(0x07748faa,0xd9ae9fff), + LL(0xe8f7b7af,0x5a1b2634),LL(0x81b1612d,0x1fcd743d),LL(0x3d420398,0x6b065aa2),LL(0x41e06643,0xe758b9c7), LL(0x7f111b3b,0xe1e52b53),LL(0x83498731,0xb9ee0a5d),LL(0xea8154f4,0x49c19631),LL(0xe1c08746,0x8f5a3479), + LL(0x65dd5561,0xe032d7c1),LL(0x442bef09,0x6c3420fe),LL(0xa64eff47,0x1d390561),LL(0x902763bf,0x0d8fbf07), LL(0xa4bc6856,0x0262f26d),LL(0x9f4f2101,0x7c1b59a7),LL(0x51240642,0x663d9b38),LL(0x77ce53cc,0x39a0b4c2), + LL(0x61f5e655,0x1c896beb),LL(0x9f4bfd2d,0x75c4c049),LL(0x10111b02,0xb8799a15),LL(0xa4c2fa0e,0xc76f8641), LL(0x185fc036,0xd77ff7fd),LL(0xf5acbd16,0x53212bd6),LL(0x0408cff8,0x4ef7431f),LL(0xfb082c4b,0x45aa9d99), + LL(0xf0438565,0x22c1fa8e),LL(0x4cb43ab5,0x8e3a2ee3),LL(0x232081d1,0x457df338),LL(0x482ff47b,0xd1293d9b), LL(0x68106365,0x802a300e),LL(0xe51978c9,0xa8f27aa1),LL(0xa6a6a4d3,0x6ca0edda),LL(0x24c9526a,0x4cab1223), + LL(0x56730245,0x26234b2e),LL(0xe1b54be4,0x9a04c15d),LL(0xee89282b,0x153fb6cf),LL(0xd79d81ad,0x5901ca12), LL(0x7c3c5ffd,0xbe6853d8),LL(0x35e1942a,0x16d3efb5),LL(0x3b56bece,0x3491f207),LL(0x5b818cfd,0x0d75e0c1), + LL(0x40969df4,0x79a0e319),LL(0x9ae34b31,0x75e4632c),LL(0x68e8df30,0x4a47585c),LL(0x2a495467,0x4a4a40e4), LL(0x2762eae9,0x92b8a6f5),LL(0xc9a3d133,0xa204cd80),LL(0xd1ff23cf,0xa441ecfd),LL(0x4550ee57,0xd06feb58), + LL(0xdc032002,0xe14ca6a1),LL(0x05505a36,0x9a780e57),LL(0x08cb2b29,0xad93852e),LL(0x008b00c4,0xa54deaab), LL(0xe1042350,0x8cd2c71a),LL(0xa8915596,0x2014b85d),LL(0x97ddd1dc,0x1228b3e4),LL(0x4a3b3ab7,0xa97282ce), + LL(0x0f1559ad,0xd978cd73),LL(0x86b14d3c,0x2e877fa2),LL(0x3660f189,0x01d3dc94),LL(0x0d2b4ddd,0x90ad950d), LL(0x92245e3e,0xa8d26760),LL(0x4964245d,0xfc1bf8d5),LL(0xac3d97eb,0x31206c72),LL(0xa58c64cb,0x39dfd972), + LL(0x7efbbd16,0xd631907f),LL(0x174f1fd5,0x4fdc84e2),LL(0x5c277996,0xe81e89b3),LL(0x5f79f1de,0xcb277b4e), LL(0x2ed1962c,0x2eff44b3),LL(0x72883505,0xbe36a640),LL(0x545e69a0,0x14a1fac0),LL(0xd6f658b9,0x76dbbcbd), + LL(0x78e2e86d,0x0720c584),LL(0xcaeead35,0x52fccffb),LL(0x587fd1b2,0x06f28c72),LL(0x9e48bf69,0xec36a912), LL(0xdaa3cdbd,0x74874436),LL(0xcdc2f2a3,0xb3f7409f),LL(0x1951c078,0x0e50d7fa),LL(0xee8949f0,0xd97ff34e), + LL(0x742d7b1d,0x00db635e),LL(0x29f0d0f9,0x5c0b280e),LL(0xeabf9b35,0xafa7e616),LL(0x2c8a76e8,0x7341e2c7), LL(0x2e96f198,0x9679e34d),LL(0x90ee26ca,0x8c2661c0),LL(0x67a6516e,0x9c6dab35),LL(0x46b4b34f,0x7c8edc4b), + LL(0x2afba4fe,0xc502cf2f),LL(0x6776dbf1,0x76847ae0),LL(0xa2c3c83e,0xace02706),LL(0x4601c550,0x0012645f), LL(0xef6189bd,0x1940e14a),LL(0x2cdf5e89,0xba7f615f),LL(0x438a3781,0x698101aa),LL(0xa9e22357,0xf568a45d), + LL(0x1f913210,0x83af640e),LL(0x8d505edc,0x529a29fd),LL(0xd6b0c85a,0xdf3d3090),LL(0x6897ea43,0x46e23886), LL(0x416577ae,0x97cca980),LL(0x9aa08fc3,0x1f5a96a8),LL(0x56c05c30,0xcb014b33),LL(0x05ec9be4,0x1944765a), + LL(0xddc4371d,0x2d6789cc),LL(0xf3618fc2,0xd768f5a6),LL(0x3da93c1c,0x77065e11),LL(0x0e27b3eb,0x4ea3fbc3), LL(0x11ba30e9,0x7c1bfba0),LL(0x1036ebe6,0xfc6fba67),LL(0xd3231aed,0x0053a30c),LL(0xee3ac524,0x7f0613d9), + LL(0x63093df6,0x95ec2fd9),LL(0x7c0eea52,0xfbc63768),LL(0x8b64ea48,0xf767b286),LL(0xf75bc633,0x6959b0ec), LL(0xc9f63154,0x47e34c3b),LL(0xa524bc76,0xd616b19f),LL(0x632ac100,0xefc9bb54),LL(0xb4d96a7d,0xd9abba10), + LL(0xfe2ad7e8,0x3b7dd91a),LL(0xb4ebf343,0x29134cd7),LL(0x152864fd,0x49d1c305),LL(0x80efc220,0x3afd83d0), LL(0x3f2f0d27,0x3552517e),LL(0xfda48969,0x0a2b5006),LL(0x3c3e8ec9,0x568863ed),LL(0x891edec9,0xd99d5c62), + LL(0xd1c9d6ee,0xb0ddc129),LL(0x57db23b4,0x373dad74),LL(0xb416c7df,0x7c178b0b),LL(0x4f8a7153,0x77431dac), LL(0x41c1367e,0xf5288888),LL(0xb838c91c,0xf1518939),LL(0x541f3281,0x81e17838),LL(0x65b2bde5,0x70030244), + LL(0x7350251c,0xdc309424),LL(0x7c811130,0xfac0c6ad),LL(0x6a141269,0x3817aa1a),LL(0xe10b4a6d,0x1aa5a92f), LL(0x34648a96,0x996cca7f),LL(0x4e2a4f52,0x517a25b9),LL(0x38b1547c,0xff95ac42),LL(0xd9b9cd4f,0x01d981b6), + LL(0x88d60eba,0xcc34d15e),LL(0xa0ea1a51,0x45851bf4),LL(0x82854ee0,0x5d5f9b30),LL(0x176ea156,0x914be21f), LL(0x2a05c368,0xecac86d1),LL(0x73a666a8,0x255cb9c0),LL(0x78c0eec5,0x5e4799d9),LL(0x8fc05a71,0x40ed8989), + LL(0x8ae03edd,0x54888ac2),LL(0xa83b554b,0xef3e9865),LL(0xb7612fe4,0x47b41822),LL(0x8f76cd2e,0xf6e16fd5), LL(0xa977b5dd,0x091c7b12),LL(0x8f99d4aa,0x7051bf6b),LL(0xfed218fe,0x9f737902),LL(0xb752c612,0xd8112477), + LL(0x18d13bd3,0xbb45c287),LL(0x23c6dd1a,0xbbf3a894),LL(0x13b9cf87,0xc8171c5e),LL(0x34f5348d,0x2dfc7792), LL(0x985cabd4,0x9b9a662d),LL(0x4d971de0,0x588a6ebc),LL(0x574cba64,0xda9fd894),LL(0x651e6e67,0x7e0f0cca), +}, +/* digit=2 base_pwr=2^14 */ +{ + LL(0x4b8bceb8,0x88ca276c),LL(0x752d1106,0x6d4ec101),LL(0xf834dcbf,0x2ad98063),LL(0xdfff19d0,0x4da81d19), LL(0x3a9828ff,0x4ccc7cd2),LL(0x2e64b332,0xf1e389b0),LL(0x7308b81c,0xe2fb6a6c),LL(0x5bcc0ac6,0xc6df66b2), + LL(0xe1c58c80,0x5ccb8c75),LL(0x83fcc95a,0x2ba9de04),LL(0xdfccbcf9,0xccdeb0ee),LL(0x70f3d3ad,0x1d667d4f), LL(0x36269820,0xc6aa14a5),LL(0x0fe87940,0x329a308b),LL(0xede5cfb2,0x39869970),LL(0xf601bb2c,0xc33c3068), + LL(0xa1a8781b,0x3087444a),LL(0x5cff3cbf,0x6cb5b706),LL(0x83082714,0x7673a8e4),LL(0x0842a792,0xc4bce015), LL(0x53e2a531,0xae71a033),LL(0x8b5315f9,0x147b28f8),LL(0x6c5ab37a,0xcc460133),LL(0x540dde16,0xb1dd088b), + LL(0x11c09289,0xec250455),LL(0x164079c9,0x83042ba7),LL(0x6e3879a2,0x4881640c),LL(0x802452ee,0x77c5babc), LL(0x7088f360,0x7a7759a6),LL(0xb74be7e9,0x02da352c),LL(0xe0338289,0x15800cdb),LL(0x501688c6,0xad69f7c9), + LL(0x57ae1213,0xb7d35063),LL(0x97024ecd,0xd536753a),LL(0x24938196,0x9d680716),LL(0x44ed6d4e,0xac1bee4c), LL(0x33e95503,0x6dd9c9bf),LL(0x88fc1c3d,0x5ee9f1fd),LL(0x21654473,0x4a701ff4),LL(0xbd2ffe36,0x9a316450), + LL(0x103b5fa2,0xe9130a63),LL(0x8eee983b,0xe97f7120),LL(0xe8749cba,0x54b7f85b),LL(0xbb1bca55,0x69976910), LL(0xf4e621d3,0x9ec4034f),LL(0x695e17da,0xaad567ed),LL(0xcedb2ea8,0x7647f054),LL(0x09fc7433,0xf85f944c), + LL(0xb95eeddd,0x30af23b3),LL(0x89985f3d,0xfd1d565a),LL(0x4c254738,0xfbb53173),LL(0x171170a4,0xb07ba56a), LL(0x294d55d1,0x5069882c),LL(0x792694c1,0xae0385c4),LL(0x11225dc6,0x0a0c7927),LL(0xe22867c9,0xadcc5f08), + LL(0xaee03999,0x164ac67f),LL(0x79ff7f91,0x4de174d3),LL(0x548da6ea,0x063e4943),LL(0xdb7ccdf7,0x5264880b), LL(0x49b992cc,0x4a18f34b),LL(0x14065870,0xe16b6f4d),LL(0x4cdb0e21,0xd32479ac),LL(0x162bc9f8,0xce8151f6), + LL(0xe8f78545,0x0f8d9a2f),LL(0x3145b086,0x091643db),LL(0x23a1bcc9,0x5915a582),LL(0x8a280fc7,0x97348efd), LL(0x65eccf5d,0x3f9d6236),LL(0x01ac8146,0xd1a34937),LL(0x8ad0d5c1,0x1b8e5128),LL(0xd581dd11,0x5cbcc9ef), + LL(0xed059f1d,0x947ceaff),LL(0x7460a186,0xf5754d03),LL(0x0164ff7b,0x37698fa6),LL(0x35805339,0x630900d2), LL(0xeddd6bbc,0xe467a6be),LL(0x5e36b12e,0xc53bffec),LL(0xf831fc7d,0x06dfd3f9),LL(0xdaef86ac,0xd995fcc4), + LL(0x32d5b2e3,0x7d148468),LL(0x6335f566,0x7796b94c),LL(0x6769b8bd,0x693983d6),LL(0xed5244fa,0xff0306aa), LL(0x89b8e801,0x2e90d41a),LL(0x39e732f3,0x1af09d86),LL(0x320ccb1d,0x96d14e1f),LL(0xc05dcece,0xbaf21c6f), + LL(0xc216cf37,0x8ae82a1c),LL(0x773828bf,0xac437f45),LL(0x9d51a85b,0x8c12ff18),LL(0x34c16578,0xfeb563be), LL(0xc6706966,0x9d9353b6),LL(0x0cda8733,0xcdc6eb5a),LL(0x3e4953db,0x033c186e),LL(0xb2e37f7c,0x2ba46a66), + LL(0xb9f3ee06,0xb32115e2),LL(0xdd6346a9,0x1bc12cec),LL(0x321242fe,0x6b9c2142),LL(0x5c68ea06,0xcf9b9bb3), LL(0x920d49bc,0x7fe554ac),LL(0x37aedebb,0x90b3a9b4),LL(0x7695af86,0xacb181e0),LL(0xfd567fea,0xd1c99c55), + LL(0xfccf76eb,0xb7c18083),LL(0xf93113a3,0xc693bdbb),LL(0x66e03205,0x215ff05d),LL(0xf76d2a12,0x4424aaea), LL(0xe7f30891,0xb23f2782),LL(0x062db479,0xad814d5e),LL(0x4aea78c3,0x347ec1d0),LL(0x6a2332f2,0x3d0f0a7e), + LL(0x8ad9e323,0x02ecefa6),LL(0x0d45e0c9,0x16c81248),LL(0x2757306c,0xd4b6253d),LL(0x81e42d04,0xe90203a3), LL(0xc13782f0,0xbcef10fb),LL(0x156267d4,0x823efe5d),LL(0xfddb0092,0x18add11a),LL(0xb104561a,0x27068a29), + LL(0xda0abf3e,0x7eb7f516),LL(0x61b3381f,0x3c92ac94),LL(0xd3418870,0xbad7320e),LL(0x07dbe066,0xbab7a126), LL(0x2def303f,0xe7ce59be),LL(0x2d1e0c9f,0x0bf1f237),LL(0x38f418dc,0x12c18d1e),LL(0xb85bb676,0x7fcc5e3e), + LL(0x1b038ac6,0x0bcf25ad),LL(0xddf1becb,0x35388760),LL(0x8a1ad137,0x5734bf37),LL(0xb7645056,0x92f3a250), LL(0x718a5ace,0x6ed926a4),LL(0xb967f1cf,0x8e63f0a2),LL(0xd835fe33,0x6d9cccc9),LL(0x31f82e18,0xb1b5efee), + LL(0x24f2c6b1,0x997aa2a4),LL(0x9e536a91,0xde87114f),LL(0x0f819ec8,0x01938bd2),LL(0xef772a43,0x012e9031), LL(0x77aa9256,0x1578eb4c),LL(0x61a0c8ed,0x052b4088),LL(0x6ab5a380,0x1153a330),LL(0x132f5675,0xa3e7f085), + LL(0x909b8a41,0x5e946e00),LL(0x16a3c156,0x55f7d231),LL(0x8ac8f8e3,0xcd952464),LL(0xcd8d67f7,0x7c5184d4), LL(0x39ef93a7,0xb3468964),LL(0x4e9058c8,0xf4aa0b7e),LL(0x4b7c713f,0xa409403e),LL(0x41a83e50,0x9d55e33c), + LL(0x7e1754b8,0x9efee704),LL(0xb1c0027b,0x54085471),LL(0x45af4e6d,0xc5e7a6fa),LL(0x30048569,0xb4d3cd58), LL(0xf3ae8e79,0xd2c20014),LL(0x849f3f23,0xd0b6af13),LL(0x17982a8c,0x3a1db915),LL(0xf9ffcf90,0xea3c8099), + LL(0x7bada472,0x25d9eb82),LL(0x09afd498,0xff84d98c),LL(0x56ff21f4,0x5e2c1ffe),LL(0x2f2f3a94,0xafd07201), LL(0xcdb673bc,0xb0227fe6),LL(0xfe8d7326,0x58fc0e7e),LL(0x191bfd4d,0xb988d3eb),LL(0x2474d8b6,0x82499093), + LL(0x68caff21,0xd1ef53cb),LL(0x5074160a,0x3cff018c),LL(0x98f982fc,0x609a4688),LL(0x562a099e,0xee5caaac), LL(0xf8c6cfd7,0xf650365b),LL(0x9cbc10ee,0x2652aa23),LL(0x6ab86f4e,0x904fd66e),LL(0x2d82f3d8,0x6a25bbc3), + LL(0x19c7a275,0xd3e6ecad),LL(0x3604b2dd,0x05ed0451),LL(0x00c71863,0xdd1d87e2),LL(0x8cd23356,0xd9fc8793), LL(0x0036b81f,0x3337f8ba),LL(0xb5300622,0x63b5a762),LL(0xce8800e3,0x4cf696f1),LL(0x07e3cbc3,0x12cb3261), + LL(0x0fa12b5b,0x18eac953),LL(0x77d159b5,0x45ccf073),LL(0x6e844a0d,0xa7480444),LL(0xd77d1c18,0x4404e6c6), LL(0xce1af18f,0x003e43a6),LL(0x17fdffcc,0x8a828081),LL(0xcabf3d17,0x91b63c11),LL(0xad26f286,0xa4dedc21), + LL(0x1a2b1579,0x6bf62b69),LL(0xceeb29ff,0x3b67b87b),LL(0x40d4b996,0x451ffadb),LL(0x080978f8,0x10c6ae50), LL(0x2c242dc5,0x959d47e2),LL(0x5423e158,0xced9e922),LL(0x8d8a68f1,0x9a212d4c),LL(0x3708393f,0xeff3d644), + LL(0xfbaffded,0x43f51810),LL(0x0f6fd7c3,0x3886ccb4),LL(0x13c31946,0xb939247b),LL(0xaa1fd72a,0xbc1ee613), LL(0x631fd790,0x6d40140a),LL(0xd26b3fd9,0x9382e3ba),LL(0xb3af96c3,0xff414370),LL(0xe0ea9ad6,0x38c813cf), + LL(0x157594da,0xf8844c3c),LL(0xcac628bd,0x2a7b514f),LL(0xc08c5107,0xc023e4e2),LL(0x3f2722fe,0x6c164496), LL(0xc03a22ad,0x842e1d06),LL(0x37ddae0d,0x5dbc2865),LL(0x0342bc72,0x46dfc88d),LL(0xa4a3c65c,0x873c805c), + LL(0x60aa5c14,0xd202853b),LL(0x3850cc05,0x1dc35d34),LL(0x0cabccfd,0x8014357e),LL(0xc5a5225a,0x1aa44ce9), LL(0x3a8444b4,0xa3cef920),LL(0xc95384b1,0xcf3f91b3),LL(0xc9e5da54,0x1d625ba1),LL(0xb1d0f46a,0xbf1fba37), + LL(0xfb3f4885,0xdcef4fad),LL(0x3267f912,0xa49debb2),LL(0x1e121cb8,0x6417d37a),LL(0x533e94c9,0xa6d871fc), LL(0x2e4834fb,0x89f80208),LL(0xb353452f,0x27e83f0f),LL(0xe1f8f322,0xaf009f3c),LL(0x89319fd8,0xa5b77a77), + LL(0xedf71900,0x0a89e741),LL(0xd514d93f,0xd679b841),LL(0xb0a03702,0x8878577f),LL(0x85a209ae,0xc9607b78), LL(0x59432a28,0xb7bd0616),LL(0xed567145,0x0da060a2),LL(0x1a449f52,0x44e35a7a),LL(0xbbaccc0f,0x9c9a2c82), + LL(0xd83701f4,0x83abd436),LL(0x4bb9cbe8,0x56e8bfe8),LL(0xc631cd1e,0x5b545cc8),LL(0x955aca7d,0x6d03426f), LL(0x2f8db817,0x049fc9fa),LL(0xdc59675f,0xfcec1799),LL(0x0455f095,0xa00ed392),LL(0xe5096b18,0x6d7cfa5f), + LL(0xe30ae90b,0x2cda5cae),LL(0xcaabea0d,0x2cc34290),LL(0x41e67856,0x564afcd9),LL(0xcf6ef8b7,0x210c7a09), LL(0xf82a591d,0xc316d352),LL(0xab43d2a1,0x5fe8cc4d),LL(0x8b4e9470,0xd8ebce97),LL(0xba321a07,0x26c78f44), + LL(0xd75e509c,0xa63f4b34),LL(0xb9a6c63b,0x9122bbc5),LL(0x17942443,0x8bf792a3),LL(0x7f4f70f9,0x95b05d68), LL(0x13b70dc8,0x57d7dee5),LL(0xfc376fdd,0xe84259ed),LL(0xe3e313b4,0xf8c4c4ff),LL(0x13fa8ff1,0xf8e2d3da), + LL(0xf8e4eede,0x9692c390),LL(0x0e95a902,0x3b514551),LL(0x7360623e,0x45c1670c),LL(0x6abd2a82,0xf7a74f55), LL(0x24e8e721,0x99b16e7e),LL(0x512f1401,0xae52fa2a),LL(0x3f3a09d5,0x46c60e80),LL(0x0750e968,0xf803d1b3), + LL(0x1791644e,0x17840d2f),LL(0x3b7981e6,0x3e32b3db),LL(0xd3dfae10,0x2d0830a5),LL(0x6cc6dd0d,0x1b28d118), LL(0x78368274,0x944a9889),LL(0x55b1bf81,0x310da94a),LL(0x0d739056,0x503061ec),LL(0xb4d73288,0x1947e940), + LL(0x0228346f,0x760ee846),LL(0xc5cff077,0x108765b3),LL(0xbeb12160,0x22092b39),LL(0xb63001af,0xa631d553), LL(0x0af3d43a,0x9340cac4),LL(0x60d338a3,0xe6cbfb54),LL(0x7ca3f604,0x2280ff0c),LL(0x3ba738cb,0xaf48f86b), + LL(0x47d372ff,0x7435dd78),LL(0xf005c006,0xbf9c7149),LL(0x7a8d0e81,0x624084b9),LL(0x4840496c,0x50b578f3), LL(0xb52a4266,0x414ca2c1),LL(0x5535ef0b,0xa3c30275),LL(0xb50f7f47,0xd4b808c1),LL(0x9a199920,0xe6781ae2), + LL(0x27a91ef8,0x50141234),LL(0x5b77d060,0x2f4f5937),LL(0xc2dcb03d,0x1be8269e),LL(0x9f65043f,0xa293017c), LL(0x8caac401,0x1678dfe0),LL(0x968b1716,0x4942d8ce),LL(0xae36e201,0xa9b55fae),LL(0xd5279632,0xcfe4bde3), + LL(0x79d637e6,0x6126d744),LL(0xd63b4aad,0x8491f1a8),LL(0x9816b82c,0xdf97b736),LL(0x796408c1,0xafca2c36), LL(0x7a8e8058,0xc17f3f01),LL(0xe74705e2,0xb3335a24),LL(0x46e3e3b0,0xee200023),LL(0x40630e08,0x07bce061), + LL(0xee8f9dfc,0x46b42c00),LL(0x9e9b7f58,0x3b8e8509),LL(0xd36e8e89,0x83df4b18),LL(0x15d50555,0x09631af5), LL(0xef1ee3f1,0xb7906b77),LL(0x4bd1e17b,0x8272dc83),LL(0x4903faac,0xf160bfd9),LL(0x0dc71e59,0x7fe9e999), + LL(0xe714187d,0x6ee9b790),LL(0x9d5a656f,0x7391ec2a),LL(0xe10b20f0,0xcbb55ec6),LL(0xec3645d6,0xbba3b57b), LL(0xe18322e8,0x9c3265bc),LL(0x93328c91,0xdb49b0f3),LL(0x49c2bbec,0xa911db72),LL(0x6e5bd229,0xf71b4df3), + LL(0x7ba27baa,0xdccede33),LL(0x4b712a97,0x1af4476a),LL(0x8a8683ad,0xf0aaabec),LL(0x6fa8e84c,0x138cdac5), LL(0xdc78b1ad,0xd2d50b00),LL(0x696442b9,0x26fc0b72),LL(0x125bf11b,0x12cd5d8b),LL(0xc4f82ca6,0x2a2ce980), + LL(0x52e00dd3,0x9921c0a6),LL(0xf1d7e1af,0x98e8707a),LL(0xdf03b040,0xaa7aa8b8),LL(0xdff6bd74,0xb3ba8b23), LL(0x31db8c0b,0x2fd0faab),LL(0x2819b732,0x4697e9bf),LL(0x0425b866,0x2dc3a5d0),LL(0xd97816f1,0x4b9e7899), + LL(0x4c756c70,0x1355c412),LL(0x0fa089af,0x2d4c4eee),LL(0x3b8a01b5,0x4d8425a8),LL(0xa3531d3a,0xcc26b8a9), LL(0x7ebd9eea,0x6eebe11b),LL(0x92c0f858,0xd511a797),LL(0xec49a0c8,0xaa863f01),LL(0xa8242995,0x7fb65625), + LL(0x3dbc00c3,0x9de9d3f4),LL(0x3f7d61ab,0xb846152f),LL(0xd0d74549,0xc060fdbd),LL(0x7b273702,0xe722aab2), LL(0xd81b6f6e,0x9e54f098),LL(0x9e2fde1f,0x32dbaa5f),LL(0x9ebbc796,0x14cc9995),LL(0x0eb83921,0x4ca6686c), + LL(0x10a0c0bd,0x6e65d7c6),LL(0xb3c0f6cd,0x1f6930d7),LL(0x4d783d6f,0xe4e0a933),LL(0x70b20ad4,0xc945ee7f), LL(0x034b0265,0x521bd135),LL(0x0fa9be95,0xeb5d96e0),LL(0x357ef592,0x834c28c2),LL(0xb81df99f,0x08ab5b4c), + LL(0xf464825d,0x6be99d80),LL(0x9a0c1293,0x1cc83719),LL(0xe7e43c6a,0x76616803),LL(0x91cc47ac,0x6fa33715), LL(0xdbfc08b9,0xc3fdb99b),LL(0x68e2b249,0x66e1ef2d),LL(0x64a4a438,0xd3d8ef7f),LL(0xa6f25b00,0x775a70fc), + LL(0xa0cb5443,0x2444c682),LL(0x4b743ee7,0x264c2662),LL(0xa303eb20,0xd7a1adc4),LL(0xf60a5b98,0x3f14821b), LL(0x1a1d7661,0xa439102d),LL(0x8d8a5a1a,0x47c25a37),LL(0xa34c66a9,0xdf4a48db),LL(0x4c828c73,0xab467364), + LL(0x3459cc8b,0xd3caad73),LL(0x181b16c2,0x08eeb442),LL(0x70600d33,0x3444abbb),LL(0xcd0f8e70,0xaa2a39c4), LL(0x24836d70,0x5fc6ae8f),LL(0x47d32fd4,0xc119be84),LL(0x0d6000ce,0x2b3f3771),LL(0xe602337a,0x439893a8), + LL(0xc1e8e564,0x4b75ff6e),LL(0xe451cf42,0x6185413c),LL(0x162c3150,0x0276d3b6),LL(0x3aea9c55,0x844539e0), LL(0x42e9d70b,0xfc629ee6),LL(0x0be610c9,0x4eb9b7e6),LL(0x39ca3d92,0x8c53fda1),LL(0x14c2e9e2,0xd2e4cfa6), + LL(0xf14b31b2,0x3c1f6895),LL(0xeb951fad,0xad42d951),LL(0xb8f10fc1,0x5b20a169),LL(0x586c61cd,0x284810bd), LL(0xe863d781,0x0c4a89aa),LL(0x9c235d5c,0x2eda4847),LL(0xe6005150,0x8e141950),LL(0x52785efa,0x75716e1b), + LL(0x8305624e,0x290ced58),LL(0x06650920,0x398956a8),LL(0xdb5bd5b6,0xd057a47b),LL(0xbe9e119c,0xf2d85299), LL(0x7c5fc039,0x4783095c),LL(0x05363915,0x72f7e7cd),LL(0xdf3e2968,0xe46b90d1),LL(0xaaea2e53,0xaadb3dae), + LL(0x0cc4f426,0xf5d37496),LL(0x59d78369,0xa59bffa8),LL(0xf0a46b04,0x7ad4cc11),LL(0xb8e21b9e,0xcbd63351), LL(0x5653ebbf,0x60d255e6),LL(0x4d6b5843,0x3eaa59af),LL(0x9e1df2e2,0x90049d25),LL(0xe56aa105,0x9a185a6d), + LL(0x80e3d909,0xbd31c5cf),LL(0xa1f034d1,0x30caad3b),LL(0xd9c7c342,0xaca74fa1),LL(0x9565cf8a,0xac722cfc), LL(0x5b42e582,0x8b172ce6),LL(0x9b0607b2,0x9e99e4e5),LL(0x9446ca45,0x284eb579),LL(0xc57c9feb,0x6c5464ba), + LL(0xe511bc3b,0x1437fc95),LL(0x834d0889,0x22d7bc16),LL(0xc5071c43,0x62e545b2),LL(0x8cb4acd6,0x4c644d48), LL(0x68246492,0xd9efbe50),LL(0xcbd8ad0e,0xc9d169e7),LL(0x798ae01f,0xcb7365dc),LL(0x6d0dea3a,0x5783f98f), + LL(0xec454423,0x9b4a7e38),LL(0x96ff4c8c,0x27405d08),LL(0x0c462f7c,0x9769f097),LL(0x7dc946aa,0xcbda5412), LL(0xe7dd5146,0xdacb510f),LL(0x30507b37,0x9c9a0d39),LL(0x05ded0ac,0xa605730b),LL(0x6c6c7b5b,0x7e683472), + LL(0x7c952984,0xb378d92c),LL(0x72ae34d6,0xec76370d),LL(0xacda665b,0x1fde0bde),LL(0xb931afc1,0xc8f648f4), LL(0xb960f6ce,0x2b55adb2),LL(0x7336a643,0x71b3bdd4),LL(0x73cc39e7,0xf66e77bf),LL(0x2fa3999a,0xf582c5e8), + LL(0xaf986d1d,0x30ecd0c7),LL(0x4557dd65,0xa2ae53ed),LL(0x7d618a1d,0x97ebccfb),LL(0x11eed889,0xcbf54149), LL(0xd8f2bdd4,0xdd0ff0e7),LL(0xfa769e74,0x6ac4a9fb),LL(0x93e5abab,0xdfdfc7e9),LL(0xdffc6fcc,0x0c7151c5), + LL(0x5cbae56c,0x6d75e962),LL(0x96dccb89,0x77fae152),LL(0x6cc0e535,0x275c4946),LL(0x81781318,0xc4a400a9), LL(0x77ba50e6,0x8b9f872c),LL(0xa138eeb4,0x971b6cb3),LL(0x53f552a7,0xa7e7d1f9),LL(0x8447c730,0x360512ce), + LL(0xc5454439,0xf0c73bbb),LL(0xa3a24b5c,0x7f1b9b18),LL(0x51fa7d6b,0xc5bb48dc),LL(0x8b05a553,0xd264d6ec), LL(0xe9371f83,0x123caaf2),LL(0xb149f564,0xdf5da393),LL(0x853b9bab,0x38e02eb6),LL(0x95bf6647,0xc6aab96e), + LL(0x3141219b,0x4890be89),LL(0x7883fe8e,0x7afe4c2f),LL(0x59b86241,0xc27bd13c),LL(0xaacebdc9,0x1b9720f5), LL(0xf6b2174c,0xa054e203),LL(0x60f6de8e,0xd4e7b952),LL(0xf4558633,0xcf7b1aea),LL(0xbefa40a6,0x43fc1881), + LL(0xe23cef63,0x592164dd),LL(0xf7b4aaf2,0xfe57d6e8),LL(0xe8aef9bc,0x38a5e2c9),LL(0x1ac2b10b,0x576bd78c), LL(0x14309d10,0x2357944c),LL(0xed0ed94a,0x9933d7ed),LL(0x0339f299,0xb8792ea3),LL(0x87fd9bd1,0xcfb44322), + LL(0x92966739,0x864f2fd5),LL(0xd3cfd83e,0x7435ecc5),LL(0xec4249f2,0x8516d277),LL(0xfc158b34,0xaa7e1a8a), LL(0xfbe640a1,0xfc0fc22b),LL(0x91121fec,0xf287767f),LL(0x3f590dcb,0x0ce48273),LL(0xf087c249,0x5e994e2f), + LL(0x65604726,0x681a38c7),LL(0x247a421e,0x4f8c6ae3),LL(0x1294956e,0x1a51eaa0),LL(0x47c9b324,0x0984b1ef), LL(0x597b7696,0x3749bd0d),LL(0x08e57ee7,0x9d432b78),LL(0x2ba112d2,0x3092afe1),LL(0x16c5a7f5,0x89ccee49), +}, +/* digit=3 base_pwr=2^21 */ +{ + LL(0x54089685,0x355e9d7b),LL(0x40818349,0x9f0ec68f),LL(0x3861b80f,0x4cf4d8cd),LL(0xc1f5fa14,0xcce669fd), LL(0x1788f9da,0xea212509),LL(0xf3ccf239,0x32953613),LL(0x50027f3b,0x1048d092),LL(0x4270fbcb,0xe807b39d), + LL(0x95e388c3,0x5099dc55),LL(0xea44e3ea,0xd0670ff5),LL(0x61b41f7b,0xd212c993),LL(0xfaf13305,0x4f594af9), LL(0x05c01232,0xbc508bf2),LL(0x39ff08a5,0x76833536),LL(0xb837741a,0xa1cf70bd),LL(0xaaf7bd2a,0xba8e6616), + LL(0xdef27938,0xde04c343),LL(0x48cee32a,0x3f15ca91),LL(0x9dd142da,0xcb61573b),LL(0x126dd9bc,0xc094eefd), LL(0x136bb4da,0x5d42f1a5),LL(0xdb2f3449,0x75693952),LL(0x5c16795e,0x98017cd6),LL(0x2afb67db,0x9e401530), + LL(0x9b7c6c75,0x6376749f),LL(0xacbca35d,0x680eacdc),LL(0x5e145b32,0xe87fd5b5),LL(0x36b886af,0xeb20d1ba), LL(0x779b12bb,0xca499055),LL(0x0be39fb7,0x6f290ff2),LL(0xf4a128ce,0x33ad6fe0),LL(0x9b31da81,0xf09e2a40), + LL(0x12039372,0xb2ed3d70),LL(0x2ff46c13,0xb87e02c4),LL(0xfb27dce2,0x164246c6),LL(0xe6d95811,0xe34ee8f6), LL(0x3ec1fde9,0x66cc601c),LL(0x80ffdd56,0x056b3194),LL(0x9626aa21,0xff009868),LL(0x2d931092,0xc3e4982c), + LL(0xc3d42729,0xbc0da9c1),LL(0x720df0a0,0x4905da24),LL(0x45f6eadf,0x0e5e1fa0),LL(0x2aab7523,0xc02033f3), LL(0xedde75e1,0x45ba916f),LL(0x75c68e52,0xf43919bd),LL(0x84892e6a,0x00e7c076),LL(0x70dfeb08,0x259f8488), + LL(0xd8a869a0,0x3bfd5f2c),LL(0x574e7d67,0x1df48669),LL(0xe14cfd3b,0x16d6ed5a),LL(0xfcf78465,0x583aac2c), LL(0x67da2ae9,0x67210e6b),LL(0xcfee511d,0x0b024e70),LL(0x13839a4f,0xf27e122c),LL(0xb79dfa97,0xfa5356c9), + LL(0xf357999b,0xf0c24783),LL(0x26bfacb3,0x2c21474c),LL(0xd3ddb945,0xe3abed6a),LL(0x6031a5ea,0xbb21b764), LL(0x8afc2a09,0x6db3b68b),LL(0x81306b71,0x1aac2f08),LL(0x852eb6f5,0x882c3371),LL(0xd98e9b6f,0xadfe0c1a), + LL(0x7edcb9e5,0x0247ee7b),LL(0x1f29918b,0xe29ec013),LL(0x6099b6ce,0x5d1629e6),LL(0xcb534584,0x68587803), LL(0x8ce551d3,0x6ccfeddb),LL(0xf85123a8,0x7ef98b72),LL(0xf9711dcd,0x19af4771),LL(0xfd80e4dd,0x8f67858b), + LL(0x7d607ee3,0xa4c8c016),LL(0x4015a479,0x15db36d7),LL(0x9d28ea30,0x0cb58eee),LL(0xbecb7b4e,0xb3d469b0), LL(0x6f476e2c,0x811081b9),LL(0x59c78fab,0x264da3aa),LL(0x3cd73147,0xd6e5813d),LL(0xe905362c,0xce9e34a4), + LL(0xcb3afa55,0xe551ec2e),LL(0x4b05589c,0x2c9bef25),LL(0xbcd083bc,0xd36ddeb7),LL(0xddb54a24,0x1c180b52), LL(0xc0961f32,0xb84220f3),LL(0xfe3ae670,0xa71103fb),LL(0x46902477,0x6a14d319),LL(0x778b8eee,0x516701d2), + LL(0x4c3166d5,0x1cdb1025),LL(0x3d6fcb6e,0x3a0ba2c2),LL(0xb3820def,0xa218b4af),LL(0xbfe8a8f8,0xda6de958), LL(0x4ceabdfa,0xc2b3c755),LL(0x8d73edcb,0xd3534691),LL(0x0ce17182,0x453b8e63),LL(0x01654263,0x6507a5b0), + LL(0xd5da0e59,0xb2b8e424),LL(0x61ac4c2e,0x7e599c75),LL(0x41aff49a,0xc64cb4c3),LL(0xea3e378e,0x0e231e63), LL(0xe08edace,0x707cc0e3),LL(0x5410779f,0x18918dd2),LL(0x2eef6bb3,0xcdd57690),LL(0xff758569,0x4c54d7d8), + LL(0x2c89683c,0x49459204),LL(0x7827e518,0x93596a16),LL(0x2b20c939,0x6198954b),LL(0x8044d3ba,0x6672c94d), LL(0x199b16dd,0x55e95fd3),LL(0x4185999a,0xa8484135),LL(0xfe36e449,0x5e8709c8),LL(0x91401957,0x47470e2e), + LL(0x0874afce,0x0058bb09),LL(0x606c3e52,0x19fb1d56),LL(0x710903a0,0xe1208b2a),LL(0xd47dfd1c,0xecabc372), LL(0x5e94818f,0xd9daa7f4),LL(0x5dc99882,0x1302ac8f),LL(0xc44d37be,0x7b4c6b15),LL(0x72d19e0d,0x0bcf6d4c), + LL(0x3fd5a1de,0x1e0bf063),LL(0xa75b5b8c,0x5d05e901),LL(0xcb3c617a,0xbbbdb1ab),LL(0x1aef4706,0x44954a8c), LL(0xff6a6e47,0xbc3ceea3),LL(0x0ded1275,0x6140f421),LL(0x4dabe95f,0xbb4b4c04),LL(0x7135e813,0xc55e87da), + LL(0xd963dd6b,0x15ad105c),LL(0x666941a3,0x33d18f73),LL(0x5d9253d6,0x860ccabe),LL(0xd16e8b69,0x2af702fd), LL(0x74e525c0,0x7e46aadd),LL(0xaf59f48f,0xd9958a44),LL(0x8e7de482,0xd8ca872f),LL(0xcf7d007d,0xc2270c14), + LL(0xa200e574,0x87c6204e),LL(0x7b69e79e,0x0ee014cb),LL(0x82b23226,0x176ff378),LL(0x8dbbb2f3,0x802d829d), LL(0xe0a4dc31,0xb902924f),LL(0x5fe522f2,0x1f1a9ec7),LL(0x4da7c04a,0xbcd95d85),LL(0xb1543c0c,0x3a3a2e63), + LL(0xf3271bf8,0x9e70a3ff),LL(0xd2cd68ad,0xd2522d88),LL(0xa6b727b9,0xb777851b),LL(0x63ff5264,0x58953d6f), LL(0xb65c70d2,0x5e111c22),LL(0xd3a5143f,0xaae73c5b),LL(0x85ef5dc0,0x2daa2bfc),LL(0xea13ded3,0x5e7258d2), + LL(0x2e3ce423,0x4161127c),LL(0x6b1af415,0x7e35a0a2),LL(0xeed24b7b,0x004483a8),LL(0x9f9d44f1,0x2816180a), LL(0x062829a1,0x214add93),LL(0x225e847c,0x262a0bef),LL(0x5d6c53c4,0x4bb1b1ce),LL(0x91d06e53,0xd02f829a), + LL(0x784da27c,0xcdc8ba5c),LL(0x161b5836,0x78a6c0d2),LL(0x8373c6a4,0x6bea92c4),LL(0xa881f59a,0x815f1a30), LL(0x227cb8e2,0x699c8642),LL(0x25a2b9d0,0x515d1e2b),LL(0x1787b3e5,0xcb5f1c6c),LL(0x104dddc6,0xc9a10260), + LL(0x0f3811e5,0x18be4f2a),LL(0x71e727d3,0x8c05d3fc),LL(0xfa707140,0xecae3e5f),LL(0xd275b463,0x4bb05b16), LL(0xb02a5ac8,0x74bad373),LL(0x520344ee,0x7232875a),LL(0x65059d8f,0x32cef98c),LL(0x54e1b11d,0x68e0fdb6), + LL(0x3f3db43f,0x683424f3),LL(0xabf4a83f,0xf5f0878f),LL(0x4ac2c5c9,0x681350d9),LL(0x47dd3652,0x825e9ecb), LL(0x20713db6,0x420743f0),LL(0xd1b082e5,0x95db7427),LL(0x1affa57d,0xa0e1117f),LL(0xf940f325,0x62c87b5e), + LL(0x4e1d5d9a,0x6a65fda8),LL(0x345ccdef,0x0c0fe385),LL(0xd6d72c0a,0x19ff360f),LL(0xfb016131,0x1be1e8d7), LL(0x025b45e1,0xe2f27e91),LL(0x05259bf1,0x25bec266),LL(0xe51cc67e,0xd7b8b4e7),LL(0xab80a20e,0x3a839aa5), + LL(0x9f85320d,0x04a9b695),LL(0x98d669f3,0xb939cd83),LL(0xe6948957,0x24464ced),LL(0xa43928e8,0x463de507), LL(0xf8755845,0x4e1844e7),LL(0x5447e61c,0xc9c71091),LL(0x599d4bd7,0x1798f394),LL(0x1e072c64,0x758f7630), + LL(0x739b1925,0x83c93728),LL(0xfa8eb048,0x692017d7),LL(0x478d1ee3,0x4a3a2a59),LL(0x022640cd,0xb8e62912), LL(0x8572b8d7,0x4689a4dd),LL(0x8f79da63,0x6281ddfe),LL(0x212a153c,0x788bf9aa),LL(0xb3438da6,0xb67e18f5), + LL(0x31cebdb8,0x3fbafc51),LL(0xb042bd47,0x7f8ad590),LL(0xe3055004,0xf5d26c88),LL(0x3d7d6f5c,0x7f23a149), LL(0x8758ccc0,0x2fee5428),LL(0xe1b80dfa,0xb08c91b7),LL(0xea0c0a53,0xf2bcc903),LL(0x04e684ff,0xcdf2eae0), + LL(0xe1d9a693,0x354b2c07),LL(0x97a833a8,0x93b1fa2d),LL(0xe9e5f2b1,0x2dcd22c7),LL(0x18aa3163,0xf040a69c), LL(0x76939874,0x4f9a4b29),LL(0x15e24d44,0x58e5947f),LL(0xb0c2ef6f,0x9b47a945),LL(0xf630e92c,0xc4a15b7d), + LL(0x7b1d4141,0x8d7a33e7),LL(0x966486bc,0x44dabde9),LL(0xef31dc9d,0x387a6016),LL(0x1462ff61,0x76744b23), LL(0x20cdd726,0x2ad63954),LL(0x0e7803da,0x9cff7e86),LL(0xfd124ed3,0xaf5b8b4a),LL(0x050c1149,0x466dbbbd), + LL(0x06b296a3,0x68352636),LL(0x7f3fe1ef,0x0ab40080),LL(0x05bf08f8,0x1fc38951),LL(0x633c457f,0x69b54ae4), LL(0x1a206c53,0x2ad428c6),LL(0x8b09b3f9,0xd6725687),LL(0x0bc619c9,0x552d4d0e),LL(0x3113c689,0x0e88b313), + LL(0xe87a91b4,0xb2483b80),LL(0x0c75377b,0xb9f842d7),LL(0x5a78145e,0x50463f38),LL(0x830817a9,0xf2d3810d), LL(0x39cc886a,0x1819261e),LL(0x8415699b,0x697de51d),LL(0x5cab106e,0x688a874e),LL(0xcb8692ec,0xde48f3bb), + LL(0x38f4194d,0xffa1de97),LL(0x3b996b63,0x33d2726a),LL(0x0d2053a7,0x787c0ec3),LL(0xeecd5c0c,0x9447e9cb), LL(0x284773c0,0x077f121c),LL(0x815829a1,0x496427e4),LL(0x94def08b,0x4b119786),LL(0x9c15a778,0x9e7b29e6), + LL(0xfd4a8a47,0xa4d6d2be),LL(0x4333baef,0x4f000a12),LL(0x642c570b,0xc9049d86),LL(0x25e6aa6a,0x9424e8f9), LL(0xe011cfec,0x84de7fe9),LL(0x1e8c83b0,0xf273f956),LL(0xa47a40a6,0x98960835),LL(0x0a13c27b,0xd91a20f1), + LL(0xed703e13,0xaf08b4ef),LL(0xc9994946,0xefcbcf34),LL(0x2d53b069,0x019e6f38),LL(0x9b160894,0x3d62c3c0), LL(0xadfc8f3b,0xac7ad700),LL(0x0042fce6,0x41cc0cc3),LL(0x21cf742c,0x0228ae75),LL(0xf4c9a1a9,0x56a1152a), + LL(0xfebd27dc,0x5d8a3321),LL(0x7c525f7f,0x89bce700),LL(0x1c1039ee,0xe8f815a9),LL(0x62e86536,0x9f6db698), LL(0x66fe804d,0x1ea6e7a6),LL(0x261aea16,0x652acc41),LL(0xf9df596b,0xde28e5d8),LL(0x1553a545,0x18f453c1), + LL(0x84eeb5c8,0xa224f763),LL(0x835ba87e,0x8ac452f5),LL(0xc5f4c054,0x9b2b5939),LL(0x3ac1cdcc,0xb2577943), LL(0x772c60dc,0x1ba2cd0d),LL(0xd7a9bd1c,0x1fa52c43),LL(0x60444f34,0x2efd4f4a),LL(0x2bdcfc9d,0x7d188c05), + LL(0xe1913711,0x49ef6825),LL(0x600d6c46,0xbca95ded),LL(0xaf8d66d3,0x63916baa),LL(0x2dc837a8,0x04981202), LL(0x0d3ae79d,0xb501e517),LL(0xb4edb859,0x99ff7864),LL(0xaf4ec081,0x5099edee),LL(0x964f4052,0x89574889), + LL(0x52066d70,0x1690fdb8),LL(0x671f4e7f,0xb403207d),LL(0xd7413111,0x8ebc1d1b),LL(0xb4cfdf14,0x1432d7fe), LL(0x65ad5d0e,0x9277666a),LL(0xa928e194,0xbd5ae578),LL(0xb64962fb,0x2f6c10d5),LL(0x2e794187,0xe3d756c0), + LL(0xd3e6349c,0xf04fd82a),LL(0xcc7d39b6,0xde602dba),LL(0x044e7deb,0x0886e20a),LL(0xe9ba917e,0x6e30c75f), LL(0x4a322ede,0x763961fc),LL(0x2324bb92,0x6df4a3cb),LL(0x8f2ac967,0x9fe82323),LL(0x2345372a,0x3c372afe), + LL(0x50b66fec,0xbf7e9c55),LL(0x0c065cfa,0x5db7dd71),LL(0x50d459ea,0x3525e310),LL(0x8122941a,0xad7abe5a), LL(0x122d92fa,0xc7aeba80),LL(0xefcc1c24,0x066c3765),LL(0x8ffd71b1,0xa6d767ca),LL(0x9cc16dbc,0x4a75fab5), + LL(0xbb58b63d,0x9acf8b89),LL(0x6fc8c090,0x226cdcd3),LL(0xae7fbd0b,0x852965b7),LL(0xb8bfe65f,0x4cadd176), LL(0xcfa2ac11,0x4ccc11d1),LL(0x800319ab,0x8abf7420),LL(0x88bb3ef1,0x24ab82cb),LL(0x524c0ce1,0x4d3db003), + LL(0x3a431e8c,0x38483641),LL(0x792848ad,0xfc0c04a0),LL(0xa07701b0,0x2fc52bb8),LL(0xf29c72cb,0xdfdced3d), LL(0x5280c2e0,0x677e3d84),LL(0xe98cbec5,0x2dda1451),LL(0xaec26be2,0xba28b181),LL(0x5ddea39b,0x16694717), + LL(0x4b9aa9b0,0x911ec5f0),LL(0x3594ae7d,0x24b9aaa0),LL(0xc3c136a0,0x0ccfa661),LL(0xb7474319,0x5518964d), LL(0x2175c3dc,0xf0b0427b),LL(0x966b7bad,0x08db4cfc),LL(0x5e888ad1,0x6f61428a),LL(0x57b52d37,0xfaa96176), + LL(0x10aac879,0xe834013b),LL(0x95a62172,0x73397bb0),LL(0x33a244b2,0x97806839),LL(0xc3bec0d0,0x0ab3806c), LL(0x2a72512d,0x4fc7a859),LL(0x0a4228b9,0x96474939),LL(0x4de4b4a5,0x8e5d79a8),LL(0x05d62667,0x5a60d1b0), + LL(0x08d90c20,0xd31be21d),LL(0xcc14dbb1,0x3f7ed5f2),LL(0xd7d431c4,0xdc8f58f9),LL(0x82b5c63f,0x714f6dee), LL(0x76d2de93,0x6b285466),LL(0xc39dd98c,0x3c2f5d8f),LL(0xea3760a2,0x9bba0075),LL(0x2411742e,0x75e0389a), + LL(0x7ffdb955,0x87d6715a),LL(0x9efb199d,0x702108fc),LL(0x6c010f8a,0xf11db1f9),LL(0x7eb6871b,0xf52b1e0f), LL(0x97c3ed9e,0xc49c0dc7),LL(0x77220a50,0x18846f95),LL(0x97afddcb,0xdb2273bc),LL(0xcc469f75,0x5b9a16d6), + LL(0x3beedaf4,0xee364394),LL(0x528a9239,0x825e01d6),LL(0xffd0f17c,0xb60ba965),LL(0xb888384b,0xc00106b0), LL(0x31751f74,0x6e24322f),LL(0x1821d05a,0xfe4d074c),LL(0xbf072932,0xf2493c73),LL(0x21089f21,0xa797e208), + LL(0x2988abcd,0xf1b318af),LL(0x8e7da518,0xf887558f),LL(0x97836b57,0xb8b9939c),LL(0xc0a74cf3,0xf793e3b5), LL(0x37684170,0xe191008a),LL(0x05cb453c,0x7708823b),LL(0x361beb2c,0xec221d40),LL(0xeb1b68f4,0x0e5a6cce), + LL(0x9644e937,0x3dc535f0),LL(0xfda6c1b7,0xf506d720),LL(0xf99437bd,0xc78c0e0b),LL(0xcc9e2b09,0xa920b4d3), LL(0xf089b0e0,0x550965fe),LL(0x0109d910,0xf9813492),LL(0x8c9d5d83,0xd2496f20),LL(0x3e3e661f,0x751b6900), + LL(0x9e6ac190,0x921edbde),LL(0xf02d0e7a,0x75891359),LL(0x1c4da092,0xdeb0f83b),LL(0x4feb2375,0x7b427915), LL(0x7c3a85c3,0x24637c72),LL(0x3f214ac3,0xbbfabf86),LL(0xae22fbfa,0xe8765740),LL(0x5f14045a,0x3a09fab0), + LL(0x8190dd41,0x546d574f),LL(0x48b5a39f,0xdfcf0b73),LL(0x74097b2d,0xf26c69de),LL(0x3a7e3e90,0x37aa27ff), LL(0x83bbe3df,0x0942447b),LL(0x9ab378aa,0xe779fe20),LL(0x91e2264f,0xad18ad23),LL(0xaaabd6d1,0xe1dad926), + LL(0x5db5e5c8,0x9de0aa4f),LL(0xdb67e44e,0x45c3d73e),LL(0x5cd83936,0x440862a1),LL(0xffce9a79,0x9f2b9a88), LL(0x76cc6265,0x63299069),LL(0x7a8830f5,0xf596a67f),LL(0x8d1d8284,0x7051c842),LL(0x3e5561fc,0xa00d05a8), + LL(0x7a34d5bc,0x15ce42d5),LL(0xb0e37254,0x4d9b3f5f),LL(0x38841ab4,0x26e84094),LL(0x9a8ede27,0xa7afd35d), LL(0x14835fa9,0x4e8bcdb8),LL(0x79493e39,0x85d04ddc),LL(0xdf8f65ae,0xbfa8fa79),LL(0xda6c7c62,0xe31d759a), + LL(0x7600aea7,0x76f27e70),LL(0xd4d9acf5,0xbec79f15),LL(0x5eae2ff6,0x0f10bd0f),LL(0x7116a0c4,0x96c9eef1), LL(0x0cb6f595,0x30add2cc),LL(0x943efe90,0x0c70b548),LL(0x0a05f4a8,0x2ce8026f),LL(0xb7c53c00,0xaa3da153), + LL(0x8e385a26,0xcc46bf67),LL(0x99bae0f6,0x64bcf06e),LL(0x035dcb4c,0x49480a36),LL(0xe3cbae58,0x2cc1a299), LL(0xb5480cb2,0x849f8633),LL(0x5607d83e,0x1d8fa56d),LL(0xcea9f22b,0xcc3f0eee),LL(0x1a23f3da,0x7d5ece29), + LL(0x8ae66f00,0xc6f0a006),LL(0x78d648f0,0x2620157e),LL(0x40d2880f,0xfc717762),LL(0xbe105017,0x2e0e293c), LL(0x854116f4,0xb320f214),LL(0x2d5cd4ec,0x5e4fa700),LL(0xdffc1c55,0x83fa0a23),LL(0xc9a9ca15,0x18fcb8d2), + LL(0xd0ac70fe,0x9e9baccd),LL(0x27fe06ce,0x8ba02fb7),LL(0x3868fdd4,0x2708804c),LL(0x9ba83df4,0x355eaf0c), LL(0xbe43993a,0x014089ba),LL(0x469cccd6,0xc8b59eda),LL(0xb893a5a7,0x77c94507),LL(0x8e517fd5,0x0dffd39b), + LL(0x13dbeadf,0x71b6edb7),LL(0xfea2d0cb,0x1617b77f),LL(0x48ff989f,0xf7454736),LL(0xb618bfa3,0x27357890), LL(0xa7181331,0xf08c70ac),LL(0xb8bc036d,0x33b6cfe5),LL(0x7163f883,0x75ed10f9),LL(0x47d1cbbd,0x979875fc), + LL(0x7ad23938,0x6644b234),LL(0xd82e2bc8,0x0f09e7f1),LL(0x5588a39d,0x1e6c512b),LL(0xce8eae85,0xb44e6694), LL(0xf392a4c7,0x107336e2),LL(0xdbcd7b43,0x2619b284),LL(0xb7f476a5,0x7b7ec516),LL(0x43081af2,0x0de74ef3), + LL(0xd8d54faf,0x93d08bc6),LL(0xf2ae6c9f,0x88d343a7),LL(0xbc147c27,0x7cdb9003),LL(0x69248562,0xd740b19d), LL(0x464b3b60,0x7f3c48bb),LL(0xc91d92c1,0xfc4cd7e9),LL(0xd7420ac9,0x8172af80),LL(0xb9a50be9,0x66907b77), + LL(0x9ec8e974,0xed99fea1),LL(0x54f39b1c,0x624a8c94),LL(0xce9798d1,0x9c4d608a),LL(0xa4812277,0x81e1652e), LL(0xf58b7db8,0xa2cf7509),LL(0x745e450e,0xef2cd193),LL(0x9d9da493,0x48ee8431),LL(0xb8ce96fd,0x7b471698), + LL(0xe7553998,0x14dbaff8),LL(0x822de823,0xb0b14e4a),LL(0x429d7c51,0x11032354),LL(0xd572d20e,0xc1bb3327), LL(0x6a9c189e,0xff473811),LL(0x9c7b3b83,0x7cf2354e),LL(0x7662df92,0x29681ff6),LL(0x51c297d1,0x09296227), + LL(0x5e3da635,0x1b800b34),LL(0x745116e4,0xb5fd32d2),LL(0x2565abb0,0xdae17a1f),LL(0x1fec80c2,0x4f39d3d7), LL(0x290c2f4b,0xb4a19cc2),LL(0x0b6e5ae0,0x1a1b049e),LL(0x6a823b6b,0x41be6e92),LL(0x969649ce,0x35648873), + LL(0x2a8ed3d7,0xe85f995e),LL(0x2f319e47,0x9dc712e8),LL(0x536d98a2,0xc4402eff),LL(0x37521e35,0xca61e310), LL(0xc3196672,0xfed39621),LL(0xff17e8a7,0x29e7743f),LL(0x412a7c49,0x47eca488),LL(0x33a2a6da,0xf0114513), +}, +/* digit=4 base_pwr=2^28 */ +{ + LL(0xe6880b5f,0x5675a12a),LL(0xe2606d25,0x9ba1e92c),LL(0xeb3b2125,0xb012facb),LL(0xc37b0099,0x3c50fdfb), LL(0x9ce223e9,0xc9ce461c),LL(0xeefbd8ac,0xcb90bdd6),LL(0xc631ea8e,0xf657e5a4),LL(0x38a83ff6,0x6584520b), + LL(0x635abcf0,0xd959f317),LL(0x99e17618,0xa516a43f),LL(0xce3bd99b,0xed90ccf2),LL(0xa9fb3290,0x2fc6d460), LL(0x0cde4302,0xb61ebe09),LL(0xf908003b,0x5a3b061f),LL(0xf60f5787,0xf51bb736),LL(0x057efc2f,0x1717f6e9), + LL(0x1ca260ef,0x565acf93),LL(0xf1811d23,0x7d6e797d),LL(0x783e42c8,0xe63c6920),LL(0x8dcb5158,0xdc9dbce8), LL(0xc8e39022,0x1426dc7a),LL(0x30ebfe47,0xf3037f34),LL(0xf87d6395,0x75aa6845),LL(0x61f53539,0xbf792fd5), + LL(0x6ddc3d83,0xa8bf2172),LL(0xd88207bb,0xf68deb6e),LL(0xcd03bd7e,0xa8eae2eb),LL(0x951f59a4,0x64c7f57e), LL(0xa1786d57,0x8badb223),LL(0x71182790,0x2e7fda60),LL(0x9a5a9457,0x9dc90e36),LL(0xf4b07e07,0x6eca838b), + LL(0x03264871,0xad2e235b),LL(0xb8b933de,0xb4c56243),LL(0x91354c8e,0xd9c2bdda),LL(0x6a73fc76,0x97d743ff), LL(0xce88013e,0xbed4109d),LL(0xf3b3bf4f,0xa2428275),LL(0x011e761c,0x900d3560),LL(0xe24fd6c2,0x34925d7d), + LL(0xa8198235,0x08b966ca),LL(0xed2d764a,0x355d098c),LL(0xa3d63f3a,0xfac27f7c),LL(0xd3edc140,0x3e553f6c), LL(0x11ff4334,0x64d72c7f),LL(0xbc62cb57,0x48735aab),LL(0xeba21082,0xcf064294),LL(0xbb8d96fd,0xc1f9e456), + LL(0x293cd945,0x1d24bdbc),LL(0xea254e36,0x76985bcb),LL(0x876fb485,0x3df2cb6a),LL(0xcd1f673d,0x0176969f), LL(0x642133a7,0x8b41cacb),LL(0x373880e2,0x31ea88f8),LL(0xb3b1463f,0xccf1ff85),LL(0xaca74a27,0x88fffa15), + LL(0x167cdd1f,0x9a4b9b92),LL(0xf879b894,0xa9118fc0),LL(0xc55479f5,0xf6e73387),LL(0xc626d292,0xfadf82ed), LL(0x56e80e6a,0xa03bb761),LL(0xf27555d1,0x59a783f9),LL(0x3d087e43,0x027d63b6),LL(0x02fdeded,0x29f9ff32), + LL(0x371d0ec5,0x88a9173d),LL(0x08c0227a,0x04ac4d0d),LL(0x9c7ec715,0x00213011),LL(0xd9d6b472,0x0d2b7c76), LL(0x5050bdff,0xe678d53a),LL(0x65a5fcd5,0x8f929d57),LL(0x1dc3e712,0x0793920b),LL(0x4b073699,0x9a6a690f), + LL(0x758bdc9d,0x329d9a81),LL(0x7d867b66,0xebbaadd9),LL(0xe6025f68,0x0d7e6b19),LL(0xc53dce26,0x50184374), LL(0x3ed13916,0x298cb00f),LL(0xf5d45b26,0x835fe31e),LL(0xf5a7fb7a,0x373a9c49),LL(0x34d3d8a8,0x59ed7e23), + LL(0x3baf6fa3,0x1a8dfe33),LL(0xda53714f,0x926ccce7),LL(0x18ef6fe2,0xda4feaed),LL(0xc3ca5cdd,0xeddaf090), LL(0xbfe06d45,0xc39c2046),LL(0x0d7f549f,0x1d9e889e),LL(0x8d537d0a,0x209ace73),LL(0x0e31e1ce,0x6f182c88), + LL(0x1b8c82e2,0x865e0761),LL(0xa659f2ab,0xcf11bcb9),LL(0x7c868143,0x1804bbeb),LL(0x453e36eb,0x2fa89a0e), LL(0x2e17bad1,0x42d69d8f),LL(0xdc2ec741,0xe7fcea6f),LL(0x379ceb37,0xe7f19b45),LL(0x49bb35a0,0x84f0bd89), + LL(0x5264b33d,0xa8a50678),LL(0xab1c9e26,0x8cfae763),LL(0xff9b931a,0x1e837dc3),LL(0x796ac029,0x76164be8), LL(0x1266db27,0x26a8bb2b),LL(0x54822255,0xfba4ab83),LL(0x38524458,0x7a5adcfd),LL(0x44ee212c,0xa056c882), + LL(0x55018577,0xe8db6fee),LL(0x91955960,0xf71256b6),LL(0x10abe8d8,0xeb1c118e),LL(0xd45a8426,0x984efc9f), LL(0x00f2c6ed,0x4e1b323a),LL(0x331baae2,0x1759a7af),LL(0x2e00ba6c,0xf1587189),LL(0xbb385d39,0xbd8a877e), + LL(0x57d6c1ae,0x440d1eae),LL(0xa957dc67,0x092abdef),LL(0x74554b3f,0x1065cbc6),LL(0x710566c7,0x67062382), LL(0x6d04ae2b,0xd327679d),LL(0xb0340551,0x11507b00),LL(0xa2f52d80,0x2e571583),LL(0xe8578507,0x673628f4), + LL(0x0cf4efe5,0xecb8f92d),LL(0x960e2d22,0x88c47214),LL(0x6059f079,0xca9549ef),LL(0x7016da7c,0xd0a3774a), LL(0x1d001cab,0xd51c95f6),LL(0xa3feeec1,0x2d744def),LL(0x0afedf2b,0xb7c20cc2),LL(0x71d144a5,0xbf16c5f1), + LL(0x3dc0d12e,0x00384727),LL(0xb01cc80f,0xaa95f450),LL(0xa6f8e927,0x19be3106),LL(0x0417ba8b,0x6d6e10aa), LL(0x870e3491,0x149f120c),LL(0x026dde94,0x27380b41),LL(0xf29b04e6,0x97d00840),LL(0x4bf9eb19,0x21d5d7e3), + LL(0xd5327f05,0xea1daad9),LL(0x9c88c17c,0xf1f45d94),LL(0x3f8ee0ab,0xc5f3dee2),LL(0x75238a56,0x706b777c), LL(0xf834c60b,0xf7aee379),LL(0x13cfe17b,0x5c24dae6),LL(0x8091804b,0x354c82e5),LL(0x102a577b,0x0dec2fdf), + LL(0x5253f8fc,0xbf3b7030),LL(0xd913c01c,0xe516fa69),LL(0xa105ba64,0x053afef4),LL(0xc89c1e76,0x91a1f36c), LL(0x7e724e18,0x3375865c),LL(0x29327b2b,0x43132144),LL(0x6f7bb24e,0x9cb2fc3b),LL(0x6319e789,0x20a6a16d), + LL(0x642c467a,0x20bfbd77),LL(0x259d50c8,0x3452bb12),LL(0xec7ffab2,0x0d3ba9c7),LL(0x3560e541,0xbbdb5454), LL(0xd63ba04b,0xab1d6e22),LL(0x7d24f015,0xdf6f11d3),LL(0xf3df15fa,0x7c4d61d2),LL(0x40b3288c,0xd5269f79), + LL(0x0e7c7b6c,0xf8516b9e),LL(0xc203dac8,0x48750d82),LL(0xa13d3083,0x89845d36),LL(0x280a131a,0xb3db3cfa), LL(0xfbf752e6,0x40045401),LL(0x1432e856,0x0289f97b),LL(0x5fc1aa11,0x41a9f371),LL(0x8d464042,0xe5c1e5a5), + LL(0x589b71a7,0xfbee2ea2),LL(0x5de7056c,0xdd6ee5bd),LL(0x8fd6b6de,0xcf8a4541),LL(0xb15e33b1,0xb47831dc), LL(0x2064321e,0x126a2169),LL(0x6e517edd,0xa21d2d22),LL(0x5ba5a30b,0x1f8072be),LL(0xc6a24b7d,0x24cca576), + LL(0x5c282027,0x57eab82f),LL(0x557344b3,0x1620f5e6),LL(0x460b3385,0x59e852e0),LL(0xf050816c,0xc906e3db), LL(0x3eb398e8,0xc031f8cf),LL(0x507ac07f,0x9c25b69b),LL(0x9cf7bdbe,0x652baf2b),LL(0x5ad91107,0x06fedc53), + LL(0x4c4b12c5,0xa8ca0be2),LL(0x28762d5d,0x633292b6),LL(0x827c0d5e,0xc04983f2),LL(0xc707ef03,0xcb6b867d), LL(0xb9ac1124,0xa7fc0d5b),LL(0xaab7dcaf,0xa5ce085b),LL(0x1cfda998,0xb85e8f1c),LL(0x27822503,0x8208df42), + LL(0xa8dd6d76,0xeaa82320),LL(0xad36eb73,0x7b2fb4ae),LL(0x97a7b040,0x24d73191),LL(0x4001e02f,0xc3ff64ae), LL(0x88799d94,0xd5d87157),LL(0x93ceb95a,0x559142d0),LL(0x59c3009a,0x798a453c),LL(0x7d6c83a2,0x546b6fab), + LL(0x5c76029a,0xe263b23a),LL(0x4ac62973,0x85630532),LL(0xecb007ac,0x14ee0643),LL(0x7ca60905,0xf9e06297), LL(0x92f1f170,0x21b2fb23),LL(0x46528ab2,0x31c40918),LL(0x3395cfd2,0x43b53242),LL(0x6d14fb40,0x4042138f), + LL(0x4464f342,0x80899c8c),LL(0x084be305,0x0f54c993),LL(0xfbf84810,0xfacecac3),LL(0x8ae5244f,0xa6585936), LL(0x9a9f8d4a,0xb467c3c0),LL(0xfd394895,0x3e5f219c),LL(0x9bf85fa8,0x39f0767a),LL(0xd8ee6022,0xd97cc55d), + LL(0xc83f86c4,0xc480938f),LL(0xe43bfcc6,0x6479b8ef),LL(0x38cabad7,0x8e6f2e22),LL(0x31f8c6aa,0x48e57fdd), LL(0xcfbbdcac,0x66dd6a77),LL(0x50ece329,0xc7d9950b),LL(0x0747a937,0x2e31f205),LL(0xa07acb8a,0xc0f8a7e2), + LL(0x15eaa686,0x578477bd),LL(0xf2f58b50,0xd72fb935),LL(0xd3a64d22,0xe9fdbc6f),LL(0x492dc89f,0xa3e42674), LL(0xa8fb7d24,0x42410ffd),LL(0x52676ed7,0x08a37dfd),LL(0xcb5d6125,0x4607c41b),LL(0x4001fa42,0x7db48af8), + LL(0x50cd30f0,0xe2264eb1),LL(0xe215f8d7,0xbb6fe952),LL(0x97e3fe73,0xf3ce2411),LL(0x37f19247,0xe52e2179), LL(0x20c233c1,0x9c7fc8c0),LL(0xb383b101,0x91c7e721),LL(0xa7ac883f,0x1163c472),LL(0x9d3b0f1e,0xbe1c3b3a), + LL(0xa3536baf,0x07be716f),LL(0x62e9c19a,0x764d9f4e),LL(0x8eaf19f4,0x15af3499),LL(0x38ea0ace,0x987a7c47), LL(0x4a1f0117,0xb03740b8),LL(0xfe098a9f,0x5cd1164f),LL(0xc9d6fee5,0xaf952cef),LL(0x3c0ad28b,0x4e86dcbb), + LL(0x677b7a8f,0x81125450),LL(0xe69273d2,0xba889fce),LL(0x582c5990,0x4a40a859),LL(0xf48934c3,0x836638b3), LL(0xf3596ba6,0xe964e189),LL(0xde8b0754,0x2f417c0e),LL(0xd5f93f1b,0xd883169f),LL(0xd45bb389,0x0318fe4e), + LL(0xdb03273e,0xe2c998a1),LL(0x33ec151b,0xc34f544d),LL(0xeb92d963,0xae0456b1),LL(0x9738857f,0xaab61ec4), LL(0xf71d9c39,0x4fb6a34e),LL(0xd816ec44,0xaa9dbd8c),LL(0x5efdf950,0xf6532e37),LL(0x67109c55,0x7151dc44), + LL(0x3f4e322c,0xb18b586a),LL(0x3553a18b,0x27b30066),LL(0x1ae4cd85,0xbd31ea24),LL(0xa64de69a,0xe8f88f4a), LL(0x609c13bb,0x8c946a97),LL(0x0eebd9f0,0xbf8cc55a),LL(0x7a8892b9,0x446aa2e4),LL(0x65b98c31,0x660c0a55), + LL(0xd3463522,0x568c56fc),LL(0xeb130aa5,0xfa6bf3a6),LL(0x008dc0da,0x16c1568b),LL(0xfed70a87,0x9c4132cc), LL(0xd497fdff,0x3e983d09),LL(0xf0ebe6b0,0xd7a0e542),LL(0x68b542ca,0x193a07e0),LL(0x07c6ab4f,0x4909776b), + LL(0x418acd7b,0x55b77ef4),LL(0x47a77d32,0x64ba62d3),LL(0x2d1f562e,0xaec1aa93),LL(0x10dc5999,0x3468725b), LL(0x6ff0d478,0x422851b1),LL(0x8e7dddcc,0x15da8429),LL(0xb8ac5238,0x38567920),LL(0x2e3344d8,0xfd29eb4a), + LL(0x4fc636b5,0x7b2af70c),LL(0x879e7640,0x242acfc8),LL(0xb5e25c7b,0x88e89786),LL(0x16ec1bfd,0x85576b1b), LL(0x1891e595,0xb31c8253),LL(0xca5608a5,0x14315dfe),LL(0xb0c14fd9,0xb9d61b76),LL(0x734b6cab,0x5d5ad8a3), + LL(0x44aee005,0xc2ea321d),LL(0x147ed658,0xd68abd2c),LL(0x893db877,0x31152d60),LL(0x281487b6,0x4807ac46), LL(0x65da04b5,0x58ebd15e),LL(0xb2f9d1fd,0xf0f74fd4),LL(0x393c7d91,0x3d04aa65),LL(0x8e7e6a2c,0xb46fb59a), + LL(0xae1eed5d,0x9236fdf1),LL(0x7810e2be,0x71936f56),LL(0x6d9ff147,0xa1ead7d5),LL(0x149a9b6d,0x32670ed8), LL(0xcb58ea59,0x12772fdd),LL(0x9df52ddb,0xfce260b3),LL(0xccab1e97,0x3221f2fb),LL(0x57762484,0xf8ff7e37), + LL(0x855512cf,0xb0a31a1c),LL(0xd71d4c4e,0x293a819e),LL(0xcd6a900f,0xc1ebc896),LL(0x9b9e0a4b,0xc727a646), LL(0x0018f29f,0x06124fc0),LL(0x41b7730c,0x67bd8fed),LL(0xc77be72e,0xeeebf0f0),LL(0x474d747a,0x427fe6fe), + LL(0x932ccbf0,0xa7fb9a4f),LL(0x5f3d489f,0xabb9c85e),LL(0xbdf26442,0xe7e4f956),LL(0x38d17422,0xd014848e), LL(0xd3e9bff6,0xae37d855),LL(0xca5aeb09,0x88fbae1d),LL(0xf025feaa,0x1a8a740b),LL(0xb9475ebb,0xc1a67821), + LL(0xde2bf8a2,0xb6cb6acc),LL(0x66a0f14e,0x9b2ab1ca),LL(0x83b2ba59,0xcbfbc068),LL(0x68447934,0x336ab62c), LL(0xf19719b8,0xd3a016a9),LL(0x0b5b9d6e,0x819a31bb),LL(0x3e1c6c0b,0x7b24be2b),LL(0x013f6821,0x10834b4a), + LL(0x86f21d2c,0xe5e5de27),LL(0xe9e35ad5,0x56b46a2d),LL(0xe2111e59,0xfc4e861d),LL(0x6e37ca63,0x7472ce5e), LL(0x27d2210e,0xafab9a71),LL(0x9ff6245a,0x1644a0a6),LL(0x8dbef51f,0xee498acb),LL(0x2e9604d3,0xd4c70da1), + LL(0x6fecb64c,0xde487364),LL(0xd15fb62f,0xa8fda1fd),LL(0x088de028,0x97e2febe),LL(0xecdce095,0x4a769019), LL(0x50a58ddb,0x4cb6a338),LL(0x17028d36,0x08df59d8),LL(0xb51722b7,0xfe3a80ff),LL(0x963c2383,0xa3cc2fe2), + LL(0x53cc5341,0x40b2df49),LL(0xa3c4bf2f,0xf3e90d4c),LL(0x20f02731,0x3f25c5ec),LL(0x69065d9a,0xd84f5b5a), LL(0x129921be,0x156d350e),LL(0x1b116922,0xe98787cc),LL(0x39e77b13,0xba5f9b82),LL(0x044449a5,0xee4d79f5), + LL(0xdd6d852d,0xb54b7388),LL(0xf9ca5fdf,0xf7554c5c),LL(0x51228a81,0x864d1fbf),LL(0x9a80f90b,0x721e1add), LL(0xad0efa62,0x89d4e297),LL(0x6dba9404,0x4e471a87),LL(0x1c1008b0,0x9a38158b),LL(0x95c47ec2,0x3dfe81a7), + LL(0x28603026,0xcb02ce9b),LL(0x3bd357fc,0xfd3207aa),LL(0xf296f5f2,0xb3807bdd),LL(0x23c2ea7e,0x7895918d), LL(0x88feb3ba,0xdc0eb62f),LL(0xbdd75674,0x024dfd84),LL(0x0a1e0496,0xe5bd3828),LL(0x24c8f30c,0xb8b1cd86), + LL(0x674d10cf,0xb559e34d),LL(0x9f962ec5,0x6955bb69),LL(0x542af42d,0x8bf1ab6c),LL(0xdfa61256,0x3f2f33fa), LL(0x73d1049e,0x32140195),LL(0xdfd7f39b,0xf5089278),LL(0xb4237be0,0xb42eb51c),LL(0x874d0e57,0xdf747f44), + LL(0x77b5d475,0xbe64bb22),LL(0x28308634,0x2c3d5ecb),LL(0xcb999c46,0x936a2987),LL(0xe26489ea,0x5a30ddfa), LL(0xc8eabf9c,0x8bfc782e),LL(0x74c8c6e3,0xb9995bb0),LL(0x391f5c5a,0x4f99c7ac),LL(0x5270c4ad,0x67f4092b), + LL(0xe6e8135e,0x6771a29d),LL(0x6c698cec,0x988dfb2b),LL(0x77812aa1,0x7818600f),LL(0xfd98e1c1,0x04393c83), LL(0x864ef146,0xe448232e),LL(0xa465ab71,0x9b70ecf4),LL(0xb13cc704,0x31df0531),LL(0x16e48426,0x401ae0b3), + LL(0x7fc514ed,0xa8106630),LL(0xde4b1614,0xda798170),LL(0xc2c684fe,0xde892efc),LL(0x05d64eff,0xd5205bc1), LL(0xe1d59ba5,0x84df4ead),LL(0x89bb2ea7,0x65245ca1),LL(0x64edbf51,0x3de6ca34),LL(0x56bcebf9,0x115296e4), + LL(0x7fd52a3d,0x0851631f),LL(0x949ad4be,0x9881db71),LL(0x88caf772,0x4b2337dd),LL(0x33ec7979,0x02da59de), LL(0xafe840df,0x2473c620),LL(0xa92ef1d0,0x2965ebff),LL(0x6fcd9651,0x2452854f),LL(0xbac2ed99,0x97092935), + LL(0x08242246,0xf0743ce7),LL(0x6d1a8439,0x76fdd82c),LL(0x61079258,0x3627c890),LL(0x82b21983,0x312f98f1), LL(0xe9173891,0xd87dceec),LL(0xd7a30e32,0xad16cfe0),LL(0xc9c7efaf,0xc404a1a6),LL(0xd6df357e,0x46e34671), + LL(0x7a02aa32,0x92fec7c4),LL(0x5a6a7bb9,0x567fef7e),LL(0xa3f97b5d,0x35fd570c),LL(0x4a4b0dfa,0x456bad8c), LL(0xa677f090,0x85a3f42c),LL(0x22a68d53,0x35060bb8),LL(0x53567530,0x1cea9d11),LL(0x8169fbce,0xf2cbc8dd), + LL(0x86cde794,0xa3e1d52d),LL(0xb3bdf344,0x72a258cb),LL(0x31b8614d,0x2997cd59),LL(0x8164b632,0x31ce2ea4), LL(0x0eba7545,0xe495e9b7),LL(0xbc4403b5,0xaad69130),LL(0x45760d9b,0x37f6389b),LL(0xb871b17d,0x00f4d58d), + LL(0x4aa359d7,0x91973d4d),LL(0xc8dd0582,0x249f510c),LL(0x7608be27,0xef11ac87),LL(0xd940b1c7,0xce116714), LL(0xfef20037,0xf34881f3),LL(0x98203f4e,0x26222472),LL(0xe9363154,0x4c9e98ed),LL(0x03a8158d,0xa806b3a6), + LL(0x09d16ce3,0xdd974d66),LL(0x59ae977a,0xe1bcc513),LL(0x218464d6,0x0e6201c7),LL(0x9e35c7af,0x05789811), LL(0x8b33a863,0xb1596f7a),LL(0x42bd8284,0x8fa93aeb),LL(0x46e11559,0xf197c202),LL(0xadd27d86,0x356b9c81), + LL(0x1695cb70,0x3c4080fd),LL(0x20f20318,0xc10c28cc),LL(0xce1ffab9,0xe9d7ed93),LL(0x4f9de9bd,0xb23976b3), LL(0x6d61a6f2,0x9b1b81dd),LL(0xf6318874,0x7537d729),LL(0x20cee7ab,0xb75022f4),LL(0xaa430952,0x425fddba), + LL(0x1ccfb3fd,0x54c4306d),LL(0x46a30a37,0xf10a54f1),LL(0x74fd4925,0x2d332a29),LL(0x1438feb2,0x8d2fa921), LL(0xfbb41bd2,0x46a9c6b5),LL(0xd30c65fd,0x87e98550),LL(0x66cd9a20,0xfbcb2ca6),LL(0x91719670,0xc176530e), + LL(0xcec38056,0xdd4a1a18),LL(0x75544998,0xe6ef1793),LL(0x30583fb6,0xf58f69cf),LL(0xaa76bf2b,0x12197860), LL(0x3bb686fc,0x717813e5),LL(0x0f06c403,0x9beeb1ae),LL(0x2782dc86,0xd83416ee),LL(0xb5500ccc,0x5fc89c01), + LL(0x8e110ed3,0x063aee25),LL(0x45963073,0x1a87377c),LL(0x5110634f,0x86944f59),LL(0x0ba76459,0x50659ae1), LL(0xde9eb40d,0xa00e48ff),LL(0xfe5b118c,0x49235afa),LL(0xc425ee38,0x81705008),LL(0x2d5f2f92,0x3c01abc8), + LL(0x6fdf148b,0x4a21bc95),LL(0x0b7e6871,0xea5cc30e),LL(0x11713844,0x90b4abb6),LL(0xf2001af9,0x3b7d734f), LL(0x782b2020,0xfc616b89),LL(0xd8b0e02d,0x68b3935c),LL(0x1cbb2de4,0x54cf5b8c),LL(0xa7c0f7ac,0x42b0432a), + LL(0xbdffae5e,0xa04e06ef),LL(0xd4b636ee,0x36cac28e),LL(0xc3a98127,0x08a06b2f),LL(0x290c5385,0x1ef0b57b), LL(0x27154c46,0x14e184b8),LL(0x60910b3e,0xa5dd3444),LL(0x3c67a74b,0xd0008ac4),LL(0xefed9fd1,0x2649cba4), + LL(0xf0c1bb4f,0x26bc537a),LL(0xd06b90f5,0x37f376ff),LL(0xbe7c89cf,0x4d48d994),LL(0x8d572003,0x511c2158), LL(0x088dda1e,0xc26fbac1),LL(0x7ad4934c,0xc3d55189),LL(0x85dcaf7c,0x5233c176),LL(0xa88b473d,0xec3a8a29), +}, +/* digit=5 base_pwr=2^35 */ +{ + LL(0xb1f0c175,0xfd96667a),LL(0x2ab99e7d,0xa256a611),LL(0x05e43f9d,0xff07c1ea),LL(0x7e1c9cd6,0x305700bc), LL(0x2b2887a3,0x3f1e2546),LL(0xc772fd14,0xdd782f49),LL(0x38584057,0x9125f996),LL(0x16a02cf9,0x19fd0396), + LL(0x4c58174d,0xa8d62bd3),LL(0xa900551f,0x872251d3),LL(0xf12802c3,0x06f5862d),LL(0xdd925555,0x5d93c48a), LL(0xbd6006f8,0xc39b67d5),LL(0xf96ccc67,0xea6f756b),LL(0x543014db,0x140e853e),LL(0xe9de42c0,0x2bdc5674), + LL(0xe01c073d,0x01dfda7b),LL(0xff9e1234,0x07a6bb65),LL(0x622cee4e,0x2a4f7f18),LL(0x50f0a3a7,0xdf4cead8), LL(0x1b8c2903,0x152b3c8e),LL(0x5f2a89b3,0x9e82e999),LL(0x68ce7a3c,0x0e6cfa7e),LL(0x0ca0464c,0xebb34d90), + LL(0xeda49f74,0xfa1a58fa),LL(0x0e4545a3,0xddb89957),LL(0xc74c07e4,0xd3576489),LL(0xb59b1008,0x64e4b39e), LL(0xf66b546c,0x3b090340),LL(0xcdeb912f,0x0e0f4013),LL(0x01e55cca,0xbb00b46c),LL(0x99ad0768,0x55b61b34), + LL(0xe8bbda5b,0xb06b71fc),LL(0xa24b0a63,0x8de64d84),LL(0xb5d4603f,0xb73dc262),LL(0x1965a916,0x5d5fa964), LL(0x3bc98966,0xb48a4053),LL(0x6f564743,0xaa871863),LL(0xe76a6a3e,0x88b00822),LL(0xb38d9e0d,0x58c9e92e), + LL(0xe989963e,0xc0d22337),LL(0xd3778d5a,0x2c4831ce),LL(0xee8c4178,0xd775c6a5),LL(0x9d0c2894,0xe2391654), LL(0x5d0eb314,0xf7d4fe86),LL(0x8b2290d3,0x42801b8f),LL(0xcdcefa78,0x73e9b332),LL(0x3e877fea,0xc0d169d9), + LL(0xffee23fa,0x29c8138b),LL(0xfb92e3b8,0xbff98230),LL(0x8fa75007,0x14077ad5),LL(0x88e61b81,0x4d3a6e10), LL(0x3bcf733d,0x218a867d),LL(0x665e37fc,0x20ff6566),LL(0xda5cbf67,0xe39c0581),LL(0x8add8c4c,0x4a6e1d7c), + LL(0x734a1327,0xcab02370),LL(0x1951afa8,0xa1df7afc),LL(0x42638b8a,0x581cfbaf),LL(0x2130eaa6,0x39db6d2b), LL(0xda2f91a5,0x4bbc805b),LL(0xe569add8,0x3dcb0a7e),LL(0xd721fa7d,0x724ab65a),LL(0xf88f8008,0xa5152b95), + LL(0x281615ba,0x7fe7f1b9),LL(0x41d5aa0c,0x419d1a53),LL(0x9fb0917e,0xafc556dc),LL(0x616ce893,0xab2a69f3), LL(0xc0861e05,0xfb9a6eb1),LL(0x5eb02b8f,0x0b74ae11),LL(0x3b1e44fe,0xccff0ad5),LL(0x88824f53,0x86dfe0e6), + LL(0x41177a46,0xedf38dc4),LL(0x7f039a7b,0xd9a955bb),LL(0x4d8ae7c2,0x4f152581),LL(0x4f848819,0x063c9f83), LL(0x841e8783,0x54ea4526),LL(0xaa5f2b32,0xe86a4119),LL(0x19846dcf,0xb7529a3b),LL(0x35689d70,0x91356a07), + LL(0x8f049ef8,0xbe66f5db),LL(0xc38dd5ed,0x0f5fd99e),LL(0x1b4ae7a7,0x1896d52b),LL(0x480b1ebb,0xf27c45c6), LL(0x3fede5c1,0xd88cff4c),LL(0xda27560b,0x57d902c9),LL(0x52d57deb,0x84aa7f07),LL(0x08bb6028,0x8da4c7c8), + LL(0x8910763e,0x658f4dea),LL(0x076a0f80,0x6e5fcb48),LL(0xab65f9b9,0x6a5447a4),LL(0xa75bb0c5,0xd7d863d4), LL(0xe87e7916,0x806c34a7),LL(0xcd961e88,0x05391559),LL(0x74fe6aeb,0x5def2d88),LL(0xf9226ca1,0x8ac350b2), + LL(0x12401813,0xffa8a649),LL(0x5337c55d,0xd6182762),LL(0x3be902e3,0xfce9d7ff),LL(0xea0dd7a5,0xb3b275d1), LL(0x2cb48ac9,0x342620f4),LL(0xa8b38a74,0xc0369384),LL(0xc0695d3a,0x04b0ee6a),LL(0x94c5394d,0x4d025585), + LL(0x81443d16,0xff9635d0),LL(0xa6cc364b,0x2342cbfa),LL(0x25bf8438,0x63b0a032),LL(0xa078d298,0x6ccd3ce5), LL(0x91292fd3,0xf93bd108),LL(0x14073286,0xc887a31b),LL(0x9f62cd16,0xeb1275bf),LL(0x61578b46,0x0335bae3), + LL(0x53348e4e,0x810d5efd),LL(0x63c74225,0xf9cd822a),LL(0xa426bf44,0x93d2e810),LL(0x019d36b3,0x95a47a97), LL(0xd5d1f840,0x1da421b9),LL(0xd6c46e3c,0xe5b8a55f),LL(0xc9244881,0x2dd3a5e7),LL(0x70c1fd2f,0xd50f9cde), + LL(0x614d9ff3,0xbee2aca7),LL(0x358f245a,0xd1f13b2c),LL(0xc46f62ab,0x9e92d83f),LL(0x827d7374,0xc1dd32dd), LL(0xc3e566e7,0x1636d593),LL(0x04ccb02b,0x81c2f4e7),LL(0xcd35b652,0xb57782c6),LL(0x88210d42,0xad88787e), + LL(0xfbd7d35a,0x3ad52d72),LL(0x37a2a095,0x4117f502),LL(0xd356b3b6,0xed03d415),LL(0x15ca6087,0x135d5a8c), LL(0xef5dca2a,0xfbaba41f),LL(0xafb4787d,0x660e5cd0),LL(0xa55e9ef0,0xe0e66378),LL(0x69939f56,0xf24513cf), + LL(0xab4f6bd9,0x0f38f09c),LL(0x922dcac1,0xec3037b4),LL(0x08a1a51e,0x706b201a),LL(0x8ffff040,0x15911351), LL(0xccf63d87,0x239d7b6a),LL(0x5187f595,0xeca37dc8),LL(0xad5a0ab3,0x04ea79e4),LL(0xe9520e8f,0xcdd81522), + LL(0xc35e1020,0x7fe6b6aa),LL(0x140ac884,0x57b63c9e),LL(0x33f19077,0xc45c23fc),LL(0xb71273c5,0x468d2c36), LL(0xfc305ac2,0xeb6839d6),LL(0x0183793a,0xf6e310ff),LL(0x32da639d,0xbca206e4),LL(0x8518e27e,0x8eb5cac1), + LL(0x66ed96f9,0xfeed0feb),LL(0xecc3a8dc,0x1632632e),LL(0x1455c8ae,0x90449363),LL(0x0aeada65,0x8d7619d4), LL(0x9f630ee9,0x2f2fa898),LL(0x370db87c,0xd78caf0c),LL(0xc45898cf,0x46fa0fc9),LL(0x2d84244f,0xa509cc3e), + LL(0xa5b099aa,0xbdbea4b4),LL(0x7592587b,0x8e8fe284),LL(0x42000897,0x0226d387),LL(0x36db5cd9,0xb6780551), LL(0xca64f047,0xd8fe5eb1),LL(0xb77cf8cb,0x6f21474b),LL(0xee45ae34,0xab8fcae7),LL(0x1f19cd67,0x73eaf9eb), + LL(0xee4df6ce,0x5bb96415),LL(0xa3ae4cf3,0xd1e27bcf),LL(0xc7f1868e,0x9bf7ace3),LL(0x82091dca,0xe821aa8b), LL(0xd381b6c4,0xf732e6bc),LL(0xdd01864f,0x5feda346),LL(0xb6387846,0x0933b92c),LL(0xa0028029,0xbf1f1e83), + LL(0xa3e38124,0x0848bf8c),LL(0x208fda8f,0xfe295fdf),LL(0x8913a1c4,0x73379239),LL(0x7e78564e,0x59354b24), LL(0x32dcafbc,0x042b7529),LL(0xfa93c5c7,0x752173d3),LL(0x9737135a,0x6ffd4590),LL(0x0f983005,0x249712b0), + LL(0x1f25da8b,0xdbba2874),LL(0x097ba4a9,0x14027f11),LL(0x34b8e4a2,0xe429b3c7),LL(0x056b4afc,0xd66a43e3), LL(0x2ac351e6,0x158644ad),LL(0x164bc6cc,0xff4aecd9),LL(0xf6c615ee,0xbb5b0c87),LL(0xd7679b1b,0xc497d8ee), + LL(0xf1c6e97a,0xf666c625),LL(0xc73a277f,0xe89f84b2),LL(0x746af4c0,0x2403d513),LL(0xb7101feb,0xe6858fdf), LL(0x84f1dcb7,0x1a42c51b),LL(0x8202bc04,0xc57f12e0),LL(0x754df5ae,0xf8326a93),LL(0x81a46aef,0x3d3daf04), + LL(0x01232d03,0x8bb8c276),LL(0xfb371cf1,0xd446c82e),LL(0xefa495f4,0xe5e8b639),LL(0x477e6493,0x51a7b34a), LL(0x824f2b6e,0xffba5466),LL(0xf0eaa6a9,0xcc67ddad),LL(0xfee19b24,0xcf0f8ce1),LL(0x83b3df41,0x34309127), + LL(0x9719a6cd,0xc8b13e8c),LL(0x619d5c33,0xb408e505),LL(0xa3158864,0x8c1b831b),LL(0x0b3d02bb,0x506b3c16), LL(0xbf11ff8d,0xf23846bc),LL(0x16e0328a,0xf0f043e8),LL(0x65986a7a,0x30b7b9cd),LL(0x21b660cd,0x0951b102), + LL(0x52bf29a5,0x72a26c5f),LL(0xb6534592,0xb513d669),LL(0x578195ea,0xb8ac15ad),LL(0xc0785f88,0xd6ed33ea), LL(0xb9e33946,0x39e23dbf),LL(0xf43e88eb,0xeadb2453),LL(0x2746c34b,0x6d82fefa),LL(0xcc542b54,0xe9172aa0), + LL(0xecb50699,0x8af6b819),LL(0x1c1d0af9,0x4af76939),LL(0x99dddb1a,0x5a7dbbbe),LL(0x891ea41d,0x97b0a3aa), LL(0x6e35ea4f,0x32b457e6),LL(0x9d77b900,0xe2a21c2a),LL(0x2ac991cf,0xb18718d6),LL(0x740743cd,0xc4416237), + LL(0x6a05ab55,0xcc3f76b6),LL(0x98091425,0x2ab4b29e),LL(0xb6478fc8,0xbf373ad1),LL(0x178b5844,0x8a1a9489), LL(0x09daf4be,0xb5295edf),LL(0x4ed54766,0x07fbb119),LL(0x7d0b9d8f,0x6e44367b),LL(0xedb96a10,0x6dc4d8f6), + LL(0x37fc19a3,0x2ba69106),LL(0x0b138296,0x522eba39),LL(0xfda58cf3,0x751544c7),LL(0x0ba33938,0xaba6fe16), LL(0x94dac7d6,0x48e085be),LL(0x19f99faa,0x06c87014),LL(0x1a587f89,0x33b9a8d6),LL(0x3fd8d8fe,0xdae382ca), + LL(0x150b0fcd,0xb5b383c6),LL(0xed9b0f4c,0xf948da80),LL(0xccd05413,0xcf075225),LL(0x4f62be64,0x3f31b12c), LL(0x368c17f6,0x23b21fc8),LL(0x400bc690,0x423d5369),LL(0xdeac140e,0x5335dd1e),LL(0x9493ad61,0xe631c249), + LL(0x32fe490a,0xc274c695),LL(0x6d8ebd70,0x42bcb4e1),LL(0x65d7a1d0,0x69059e1e),LL(0x29fdd109,0xf36dfe2f), LL(0x0c4e6370,0xacfea1ec),LL(0x7a935ff4,0x97e7f722),LL(0xf8006bbd,0x83e7c7c3),LL(0x78e6792c,0x87a8b84d), + LL(0x94d3d60f,0x5cbe4883),LL(0x91cbc054,0x6eba464d),LL(0x021c38fa,0xf9c880d0),LL(0x21af4942,0x6200faf1), LL(0x5f03e261,0xd5b2b12d),LL(0xf3ea3e07,0x1659a0ac),LL(0x836757a8,0x8008f18d),LL(0x75a8f8e0,0xfb2f467b), + LL(0x9c9b00cc,0x9a6183c7),LL(0x3bf842b0,0x82ca07e3),LL(0xee1f83d9,0xe7089191),LL(0x2d0cd2da,0xc41ecde4), LL(0x4d1feacd,0x0ce421b0),LL(0x431c53f1,0xe80a1395),LL(0xe6bfccf5,0xae9b2018),LL(0x8b359c3b,0xdf9f86ad), + LL(0xb6170a5f,0x9887e28f),LL(0xf3c0c30c,0xf5b85d21),LL(0x632af7a4,0x30861cf8),LL(0xbb4ec123,0x2fb670ad), LL(0x3c425976,0x0668b84c),LL(0x02883af7,0x55c21b4e),LL(0xf8698d29,0x0fad58b5),LL(0x68b671c5,0xef210770), + LL(0x23f232b8,0x534d510a),LL(0x49c99708,0xdb66fec1),LL(0x6d54721b,0xf1a6f3e7),LL(0x4480f858,0x8d37ab64), LL(0xb0f7f354,0x7fcfca6c),LL(0x95bfd318,0x58c7ff5f),LL(0x903f9d91,0x3048e9af),LL(0x75357af0,0xe480bc0e), + LL(0xa5a1162e,0x4f915e1c),LL(0x37efa40c,0xdd539c21),LL(0x789201c2,0x61a45c53),LL(0xe7890746,0x1bc2333d), LL(0xbbed8f77,0xeed38f50),LL(0x178501a0,0xc1e93732),LL(0xa8fb8623,0xfed5b1d1),LL(0xdc3e1148,0xa3be3e2c), + LL(0xa71a390a,0x62fc1633),LL(0x2891c4c3,0x4be2868e),LL(0x2a0c3c23,0x6573fe49),LL(0xde1589d0,0x182d0bd4), LL(0x5a7aa63d,0x17c6a780),LL(0x12543191,0x9d84cfa8),LL(0x950c85c9,0xcdb22db7),LL(0x119010c4,0xd03589e0), + LL(0x8220dee8,0xbcd02e8a),LL(0x705632fd,0xbd4d1f2a),LL(0x22f8e30b,0x00119bfd),LL(0x6eb97c32,0x06c6e73e), LL(0x35abff53,0xa26f0a6a),LL(0x8564c37d,0x7d79a89f),LL(0x1b207495,0x0347bb17),LL(0xb5c8253a,0x1baf90e9), + LL(0x37affc96,0x01059b5f),LL(0xffee0a60,0xbe76c578),LL(0x75d6b83c,0x45d7291b),LL(0xe0b58129,0x212ff131), LL(0xaa5d46ed,0x4acc5748),LL(0x9193931b,0x9fc557d9),LL(0xda4eba9b,0x17568fcf),LL(0xa0edc975,0x2cf3690c), + LL(0x953df6fd,0x0e8b0e7e),LL(0x62036a87,0x38ea7cea),LL(0x655c3685,0x57e01428),LL(0xc39d8a43,0xaedfee73), LL(0x5fb27e0a,0xed7f6598),LL(0x946888e0,0x524c3653),LL(0xe949b72f,0xd84a299b),LL(0xb0c61ea4,0x76c1397a), + LL(0x1afe465a,0xfd9f7ed0),LL(0xdbbaf852,0x832c69ad),LL(0x03713338,0xcd888c22),LL(0xe3306617,0x4e1fe026), LL(0x23521b97,0xa87adf86),LL(0xf9fbb2a0,0x673d3625),LL(0x5d8f5b80,0xf29a1413),LL(0xd3526501,0x6e9be0c4), + LL(0xe8bfd84d,0x6129f861),LL(0x77e35a47,0x1df491d6),LL(0xa84a82cb,0xefe0e9a9),LL(0x6d949612,0x972bc3bc), LL(0x3a766eca,0x8d7795f5),LL(0x12fcc6d4,0x6119383f),LL(0xc95f0e21,0xa66d9836),LL(0x684e434b,0x77a0aa0a), + LL(0x7dd7b05a,0x3d55d256),LL(0x0fed8362,0xda616243),LL(0x383e94fe,0x24bd0fe8),LL(0x6bfd0cd2,0xbc2b7334), LL(0x321f7a70,0xf9497232),LL(0x6a3df54f,0x37a4c2f6),LL(0x4ddc49d6,0x7ba783bf),LL(0x04408c76,0x4d142317), + LL(0x38b99f23,0x7502146b),LL(0x21992e8f,0x479ab73c),LL(0xd52c41d3,0xf605370a),LL(0x3a60435f,0x358b746d), LL(0x5bc537b8,0xb2cbab94),LL(0xb99057d3,0x1fd24431),LL(0xb8510f3c,0xff2242a0),LL(0x0733bc53,0x74b4965d), + LL(0x86edc9b2,0x30a3a634),LL(0x49c07c7f,0x99c9cf19),LL(0x5b0cd506,0x9d8a50c2),LL(0xbbcb3d65,0x0ed9da5a), LL(0x013f88ec,0x6de1fb5e),LL(0x09086f8c,0xc9356bff),LL(0x2b8825d7,0xa272e1ac),LL(0xf2c5ba33,0x3ad83acb), + LL(0x275bce43,0x721ca22c),LL(0xd24f78e8,0xf058b8a7),LL(0xeed46b97,0xd178eb57),LL(0x259fdb5b,0x4ad7d425), LL(0x1b515fe5,0x669ed853),LL(0x76fa1b5e,0x9f14b8e5),LL(0x3da46b02,0xfaba8d0c),LL(0x338f7652,0x759c2c95), + LL(0xb5c0ceb3,0x9a369cb0),LL(0x28a2a633,0xc1d2d1ab),LL(0xfcb48cd3,0x676190e3),LL(0xee09c3b1,0x9af97ab3), LL(0xf7e918f5,0x39323719),LL(0xfd3cd554,0xc657cb57),LL(0xa2a02d5c,0x78a33d05),LL(0x64ada03f,0xda3b79df), + LL(0x61b3a72a,0x7115ab5c),LL(0x337194fc,0xdd19f34b),LL(0x8f0a14c3,0x0f23bfec),LL(0xa60485d3,0x1fe19eec), LL(0xa463dc9b,0x1ca308c3),LL(0x5e1ae8be,0x83e18dd0),LL(0xd928c0e7,0x849eabdf),LL(0x6bd3e7b3,0x2d131ff5), + LL(0x45be4c14,0xc84cd284),LL(0xf8f4c719,0xdee94092),LL(0x3cb73831,0xe8f223ef),LL(0x18c2361e,0x24382f88), LL(0xbe91c8dd,0x205366d0),LL(0x56024b95,0x1e17b50c),LL(0x742cabd3,0x3c3487da),LL(0x8bad494c,0xbe451387), + LL(0x18ffaef0,0xfae6c0bf),LL(0x85ed1ede,0x2e7b0ee3),LL(0x125d1488,0x3cebaa05),LL(0x7c8b7fb8,0xcd0de0fe), LL(0x464bc74a,0x59434d54),LL(0xa03fd77b,0x17472da2),LL(0x2c1a9edc,0xab23d042),LL(0xd9cf4b37,0x5390625e), + LL(0x0531264e,0x43b85844),LL(0xee7aedca,0x8d71805e),LL(0xfbe643ad,0x4ace3068),LL(0x5f7d46c1,0xc98d1cd2), LL(0xf59b3acd,0xd4888744),LL(0x27288b99,0xcf662d61),LL(0x5bce2649,0xf2704561),LL(0x206ae654,0x33a8f3f9), + LL(0x9bce2b39,0xe834843f),LL(0xa90cfc7d,0x8de8e41d),LL(0xd81115b4,0x398800ed),LL(0xff2532da,0x4d33f7c5), LL(0xdcc59e2c,0x5ae37fb2),LL(0x24015306,0xca27b622),LL(0x11e8d6e6,0x51beca89),LL(0xa9693774,0x08c0b7e2), + LL(0x72fa713e,0x795e1a21),LL(0x4be58266,0x5ec1c123),LL(0x1be14fc3,0x5d8e87da),LL(0x80283ad5,0x82cefc1e), LL(0xdab7865e,0x820a385b),LL(0xf3daf96c,0x11e32d62),LL(0x5835a989,0xf022ade7),LL(0x00242233,0x2cbc2554), + LL(0xe7ce649c,0x653335a0),LL(0x6857eff7,0x8b30baef),LL(0xf3288377,0x7ea7c856),LL(0xe8572f5d,0x1387b347), LL(0xbe10c0cf,0x8a6b0352),LL(0x037c97b9,0x2a74e834),LL(0x197b122e,0xfe10bf59),LL(0x1918aced,0xd1ee174c), + LL(0x3958c20d,0x568e5fb9),LL(0x0484a92f,0x1188cbe6),LL(0x4b0d29e3,0x00ec14f4),LL(0x16a2796d,0x2b2e078e), LL(0x20440444,0x48b8cffa),LL(0x661ab68d,0xd4b877a0),LL(0xc4b459fa,0x1f352ab1),LL(0xc53aa54c,0x33accbe6), + LL(0x02bb383b,0xce4ff566),LL(0xfd62813d,0xcad561c6),LL(0x01dfc9a8,0x0927c348),LL(0x00fb9a61,0x0dde73fb), LL(0xfce59f34,0xd859809f),LL(0x81872a46,0x225bd9b6),LL(0x0314bb90,0x2642add2),LL(0x0ae61eb8,0x82dc7958), + LL(0x22d5b667,0x84c97478),LL(0x6214f46d,0xb2fe94d1),LL(0x12cb20de,0x834740f2),LL(0x8aa69c94,0x336dc7a7), LL(0x939a33e6,0x8ca085a4),LL(0x75a94543,0xd59c9ae9),LL(0x3c47dd07,0x83c97f98),LL(0xe3177231,0x0985f73e), + LL(0xebbc623d,0xe556c3fc),LL(0xb1b968fa,0x30a3242f),LL(0xbcd05a51,0x842ce9b0),LL(0x0ad576ce,0x241a35ed), LL(0xbb4a793e,0x49ccaf3c),LL(0x4492a828,0x6e6c7a7b),LL(0xba53eb42,0x72f4f5fc),LL(0x3ea74dab,0x0ca4ba53), + LL(0xbbaf9d5f,0xe7b5fb06),LL(0xb02d3b20,0xd49c2e17),LL(0x2d933cc8,0x4d31052a),LL(0x07299aec,0x5346e0b4), LL(0x79aa99ec,0x952a6205),LL(0xecb34e97,0xaab9bc32),LL(0x58ffe9ae,0xd539d7e4),LL(0x9d994472,0x91599393), + LL(0xe8822711,0x6b1d4868),LL(0x73d452b8,0x8857e282),LL(0xf08ed046,0xad59adfd),LL(0xc1c47abe,0xdb755d65), LL(0x63275d49,0x2df8520b),LL(0x7f8a3249,0xc3c712ec),LL(0x5215ef57,0x55f2a108),LL(0x3ee2f149,0x955e07a3), + LL(0x33f344f4,0x2194ff53),LL(0xbad16820,0xb455b9fe),LL(0x610b4e4c,0xfe69ea78),LL(0x8ab11fe8,0x2957be96), LL(0x2ce14366,0x3efdee3c),LL(0x01eddf9f,0x42043f9f),LL(0x93524f6c,0xfb7998b1),LL(0xdfecf763,0x95ea64c0), + LL(0x21afa86f,0xb23d2620),LL(0x86b11457,0xea757f03),LL(0xb0148d30,0x0bc4d2d1),LL(0x88ce4170,0x119b5535), LL(0x0aa9c8f6,0xaab5bb67),LL(0x88e05de2,0xdfc9693c),LL(0xe3f1e9c3,0x6cae7e57),LL(0x6f6c3b9c,0x2b1ceb54), +}, +/* digit=6 base_pwr=2^42 */ +{ + LL(0x87636183,0x12e335ca),LL(0x719d1ca3,0x1461a65a),LL(0xb14161d8,0x8150080a),LL(0xc612e112,0x08da4ebf), LL(0xa8498a9a,0xc95dfb6b),LL(0xba0f8dba,0x099cf91d),LL(0x4fb4f497,0x12d2ae14),LL(0x33cb7306,0xfa3a28b0), + LL(0x0f01c7ce,0xc89fc5d0),LL(0x7283bdf0,0x6fc45ffd),LL(0x81151923,0x71dece81),LL(0xc433fcc9,0xed1cb14c), LL(0xd3959bcf,0x4279612b),LL(0x35b5732f,0xe163880b),LL(0x71d0a1ca,0x35414ca7),LL(0x2c1e47f3,0xe8b9e651), + LL(0xc8df0a74,0x4ff11b0c),LL(0xe095ea9a,0x346ba520),LL(0xcc2bc6c0,0x81dd2268),LL(0xc2701468,0x2fb2e99f), LL(0x98053f0e,0x0d213361),LL(0xf7ae879a,0xe0b8280d),LL(0x952560f7,0xd92b7a75),LL(0x9723b62e,0x8d17dfad), + LL(0x08b21362,0x5ce8a78a),LL(0xd9fe0b36,0xf37f5e7f),LL(0x2c87837c,0xdca66c7f),LL(0x0bf2e993,0x92524b94), LL(0x71745788,0xfc0f020c),LL(0x3cbfbf4c,0x6018de46),LL(0xac3de1c8,0xa8446691),LL(0x5de5ae41,0xb194d419), + LL(0x2ff27af2,0x1586cdff),LL(0xde26b5ef,0xee628535),LL(0xc682923e,0x58480040),LL(0x5e37da30,0x4dd4596b), LL(0x2f64225f,0x247b9fd7),LL(0x51ca2121,0xdcc6de5f),LL(0x86e7ab9a,0x99fb41ac),LL(0x952b413a,0x54c782a0), + LL(0x7298c7d9,0x7641190e),LL(0x716eda14,0x499c35ed),LL(0xbb764e90,0x316134bf),LL(0x884fc34e,0x4d23467e), LL(0xf1d13484,0xfd1208a9),LL(0xcd298a74,0x089d9605),LL(0x73c4346a,0xb398c85a),LL(0xf37f13de,0x50064076), + LL(0xa6ebb83d,0xfe10d25a),LL(0xa834b30d,0xc5e3edf8),LL(0x683e09ff,0x546b5d5c),LL(0xc6dc44c6,0x02f96218), LL(0xc0edfc04,0x64528c55),LL(0xb0fc3058,0xb5a44a2c),LL(0xceeff21c,0x9f09b116),LL(0x6b0fbbcd,0x077bcd67), + LL(0x9ce76a94,0x29aaa4a8),LL(0xc0725c97,0x847cd081),LL(0x97e16665,0x0c099e90),LL(0x8f7b1fc4,0xe409ffc9), LL(0x690941ed,0xc0575b80),LL(0x92c0ee9d,0x8e25100a),LL(0x9b75837d,0x71662d27),LL(0xe56bb22b,0x6eeb9e97), + LL(0x85c6a60b,0xf1d6333f),LL(0x1d7ccfaa,0x982fee9d),LL(0xd4634535,0x1c5e28e7),LL(0x94fec469,0xa76e1d27), LL(0xafe377ec,0x1fe944d6),LL(0x2f68ae6b,0xbd579a25),LL(0xab6b515e,0x10eabb93),LL(0x31b4e4b8,0xa17b5f6c), + LL(0xaf72c239,0x05e785fb),LL(0x8af42e92,0x597e2016),LL(0xb32ae6c9,0x663f5a72),LL(0x45541cc6,0x3040ff13), LL(0xdeca6b32,0x6140081f),LL(0xc735001b,0xcdaccaf7),LL(0xdaef0e68,0x62de5066),LL(0xd837df99,0x056e9021), + LL(0x16cd1be7,0xba399283),LL(0xcfacf7ad,0x2a486323),LL(0x277777ce,0x00c15730),LL(0xd49a254c,0x5d2f200f), LL(0xdb68078d,0xf38a1f3b),LL(0x33604a36,0x595dea3f),LL(0x904b60b2,0x14749d8c),LL(0x246348ff,0xe70c96d8), + LL(0x390e35da,0x04340d52),LL(0x27a9947c,0xc098e3d3),LL(0x9ecc7a3f,0xe6d78198),LL(0x23aa6df6,0x2c39102e), LL(0x300f3cb1,0xb83fed0d),LL(0xdcfbe054,0xc0b1e356),LL(0x20cf45a8,0x3da2224c),LL(0x2f30deda,0x5be55df7), + LL(0x2faa9530,0x4d31c29d),LL(0x49d42f79,0x1d5783ae),LL(0xf618b3f3,0xe588c224),LL(0xf8f5b65d,0x7d8a6f90), LL(0x62d09174,0xa802a3d2),LL(0xbddd1cb7,0x4f1a93d9),LL(0x35a5c1dc,0xe08e1d3c),LL(0xf9d2958e,0x856b2323), + LL(0x96f00090,0xefd1e3ba),LL(0x3e0d25de,0xd489943f),LL(0x30c8626f,0x082c40ae),LL(0xa4f428e0,0xf6e5b5ef), LL(0x38a7f623,0x660414a3),LL(0x23eefed8,0xcd4e68de),LL(0xfc14e750,0x6dcadc62),LL(0xbeae89b6,0xcb78b3bc), + LL(0x1d5e580e,0x445acc56),LL(0xc43abe19,0xbf6547ef),LL(0xc922d50f,0xd160a81b),LL(0xf68eed4e,0x3877c7f8), LL(0xf8a9f64a,0x395745ea),LL(0x603350f6,0x9085b253),LL(0x8b1df366,0x2a4c71f1),LL(0xabe332dc,0x49b9e818), + LL(0x528960b1,0xb3e76e66),LL(0xd84aecb3,0x445dc393),LL(0x1612ad64,0x13618436),LL(0x8c831e37,0x3ccbeccc), LL(0x6121383c,0x0fb0bd41),LL(0x80d895a3,0x316164a3),LL(0x233f2f1e,0xc3d34153),LL(0xe0d92225,0x2905906f), + LL(0x95456622,0xe12d66e2),LL(0xff554b13,0x10469942),LL(0xf7126c09,0xa894af86),LL(0xf581d3f5,0x448f3267), LL(0xa2b5e758,0xb5512926),LL(0x43fddd90,0x08f02988),LL(0x8ba319e6,0x5f437035),LL(0x865b37e7,0xd254188e), + LL(0x8a5cb63a,0x5b281b23),LL(0x6dd136c2,0xa15a2712),LL(0x169beae4,0x00fab229),LL(0xde31b4a1,0x400d3f37), LL(0xf8545cb0,0x275877a4),LL(0x36df0277,0xb396a513),LL(0x838ced07,0xf9896978),LL(0x715cea8d,0x86e68167), + LL(0x06a5a96d,0x0eb0f0de),LL(0x1fcf91ae,0x2c7a3672),LL(0x630eca3a,0x287bf614),LL(0xf60c9d2d,0x65347473), LL(0x906efa7f,0xed15a229),LL(0xd549b5b3,0xe7be6381),LL(0x2ce9141b,0x23f32972),LL(0xfcf823f8,0x9618d9a1), + LL(0xa3d89e15,0x3d0ef0d3),LL(0x0d07f5eb,0x4d5a30c9),LL(0x73e4887a,0xc359e310),LL(0xdbdec349,0x2f4c6b7e), LL(0xba142643,0xc5a1d3e9),LL(0x11c794b6,0x8f4fd58e),LL(0x1810c63d,0xcad091d1),LL(0xf0bfa76c,0x5b616239), + LL(0xa838792a,0xe3433562),LL(0x54148e98,0x4aead02b),LL(0xdb66f216,0x809f2baf),LL(0xeabfe5da,0x09cc90ff), LL(0x63e8edad,0x69eb235a),LL(0xa7f95997,0x64f7acb5),LL(0xfae20f25,0xe999ea18),LL(0x3c4966b3,0xcd7ff208), + LL(0x345c8929,0x595e0cc0),LL(0xde5e2498,0xfe43c73c),LL(0x503f216d,0x0cdefc98),LL(0xf98826fb,0x8e4e170d), LL(0xb6c79b1c,0x1492247d),LL(0xef0532aa,0xf8e24b38),LL(0x044bc458,0x9f349d51),LL(0x1002d315,0x2ef04ead), + LL(0xda60d581,0xaf322f23),LL(0x0681173f,0x07deaa88),LL(0xa78feca0,0x86b97444),LL(0xc633a54d,0x64d336ea), LL(0x2a426cbf,0x10dd4b1f),LL(0x7af59869,0x08d97c15),LL(0x2d7fe97e,0xb8cc814b),LL(0x3bfb60fe,0x7eacd2e1), + LL(0xb790881c,0x967dafb7),LL(0x3663e76c,0x2002b8e4),LL(0xf8e82490,0x3bd28ede),LL(0x4bb2a47a,0x44dd2e81), LL(0xdbc3f2f8,0xde750dfe),LL(0x6e2eec70,0xd9b6e912),LL(0x1e4c4d2f,0xe8400e2f),LL(0x23217be2,0xd3325697), + LL(0xd4231a1d,0x030b7e39),LL(0x613d17d8,0x1f72e8b1),LL(0x01857d37,0xcd423512),LL(0x0b4b7926,0x9ecd682c), LL(0x8ec44636,0xfe4ac1c3),LL(0x9aacc091,0x4a030cbf),LL(0x0b133f54,0x12bb252e),LL(0xf970d266,0xbf90ea5d), + LL(0xf5484410,0xe00d25f7),LL(0x2a922894,0xb4984eeb),LL(0x8e1e09ce,0x498102fd),LL(0xe1d731bf,0x8f8c9fcb), LL(0x0b4983b7,0xdb897669),LL(0x7b2468f5,0x7a7767f9),LL(0x72f4d5f4,0x1a2f9fe8),LL(0xa6169daa,0x10e95aa9), + LL(0x520166e9,0x9487e50f),LL(0xc4ee6a95,0x6f6b115b),LL(0xcf7560f8,0xaf29926f),LL(0x1f989e46,0x20a32458), LL(0xd3bd2473,0x165a2232),LL(0xe9fecdf8,0x93d841ff),LL(0xbf9978c0,0x71d63fa7),LL(0xe7de184b,0x381bcf34), + LL(0x347dfaef,0x317c8e40),LL(0x64464bf3,0x795b0f7d),LL(0x1364ec20,0x15dc99d6),LL(0x91600d3f,0xc07fce28), LL(0xc8bebbda,0x9825338b),LL(0xa8547c03,0x5e5e89f6),LL(0x1a040b84,0x3c50032f),LL(0x2b3a533d,0xcea7544f), + LL(0x43247e19,0xea26d87d),LL(0xfba8368e,0x7e753390),LL(0x3c7bcfc6,0xb35e75cb),LL(0x7e44aab3,0xf78cb5ce), LL(0xa98d7104,0x4a3534e9),LL(0x6f5852ea,0x2b83ea6c),LL(0x68dced7c,0x11337fff),LL(0xd1a2a294,0xcca0f2c6), + LL(0x426bf202,0xb547c662),LL(0x66194a34,0xec50423e),LL(0x78161e84,0x11d34865),LL(0x64f04dec,0x83508c06), LL(0xf7732345,0xd1c72976),LL(0x18e77e0a,0xd624bacd),LL(0xba79bdd9,0x71344b75),LL(0x8d6c1474,0xe4bfe085), + LL(0xcc5eb43a,0x505e8fd9),LL(0xdaaf0621,0x612ab1d0),LL(0xe6672368,0xde170783),LL(0x83788673,0xfee7df44), LL(0xd119271d,0x364d6885),LL(0xe1b0cea2,0xdd70bae8),LL(0x5832adba,0xb4b873ad),LL(0x8c683749,0xad3ecc18), + LL(0x4d217a2e,0x963d8793),LL(0x1fa4702d,0x099e8c56),LL(0xe6431f1b,0x6d91bc47),LL(0xa5f61399,0x3fd21287), LL(0x682fa08b,0x2fc90bae),LL(0xc1ca371c,0x51699c85),LL(0x831c428f,0x16f29d74),LL(0x9fa2b504,0x0ecefb66), + LL(0xa75c5a91,0xd04ac53f),LL(0x3bf0524b,0xcbe62421),LL(0xb8792826,0x91dcb3ce),LL(0x7885092a,0x28a6bf88), LL(0x64c1e218,0x24798e59),LL(0x3fec97dc,0x18e848dc),LL(0x9da457b7,0x935e0f50),LL(0xb8f497a6,0x46b67ab7), + LL(0x7651e4ff,0x15a38140),LL(0x4890cd7f,0x6ba6c617),LL(0x5fe253ca,0xa527b8d2),LL(0xff3d603b,0x945277b8), LL(0x75392f01,0x10796155),LL(0x2bd9619d,0xcac8f713),LL(0xdebb8e28,0x71a87eca),LL(0x52ab1792,0xe8e6179e), + LL(0xe33705e7,0x4ce3998b),LL(0x48ba56e4,0xf9a0661a),LL(0xd9e4e184,0x47f06b30),LL(0xf9f8f6df,0xda465f75), LL(0xc0ad3e20,0xb05acbbe),LL(0x92bc2c13,0xec8776a4),LL(0x240a908b,0xbb3971b7),LL(0xbbd0cecc,0x80a14367), + LL(0x086949bc,0x40911e50),LL(0x4064a19d,0x39b3ab69),LL(0x6b07eaa7,0x538c6d96),LL(0xd3723bde,0x38c05b47), LL(0x080d2a64,0x1e669308),LL(0x2a77601f,0x6b44dbe5),LL(0xe7c6ce9a,0x35579681),LL(0xa16afa75,0xd2950b0e), + LL(0xeaf7fafc,0xd228a3ba),LL(0xee878f00,0x9324e71d),LL(0xe413c1ce,0xa853bfc1),LL(0xdcf17d1c,0xfe916368), LL(0x2546154b,0x8611383a),LL(0xe715b375,0xdbdf225d),LL(0x8dbb0651,0x874d70a6),LL(0x9ed56391,0x84e58895), + LL(0x3776503c,0xca83d8ad),LL(0x46e82d65,0x2cf38b4e),LL(0xadf3a8d1,0x65af46e6),LL(0x1d31056d,0x4f09a4ab), LL(0xcacc81d5,0xdba27b42),LL(0x5d6e1bdd,0xb6caa0ca),LL(0xf7198b26,0x1086e441),LL(0xac572f9b,0x15dfe6cb), + LL(0xd2051dd5,0xd9444337),LL(0x834cd72d,0x6c34b236),LL(0x58df3f28,0x84783216),LL(0x2e921372,0x59b8808e), LL(0x55835302,0x3b268249),LL(0x9f4863f1,0x3299cbe0),LL(0x4c4e213a,0x616e3cdd),LL(0x8c824317,0xa3c84868), + LL(0x460ed764,0x884be61c),LL(0xb6041177,0x388df47b),LL(0x60b29b0b,0x27089763),LL(0xe502ba08,0xd66d7d53), LL(0x5acbfaf4,0xadec85ca),LL(0x470c9519,0xfbacf9b7),LL(0xdbcda5b2,0x5d18b7f6),LL(0x0f228ed5,0x7615c036), + LL(0xd6000825,0xdfcd8273),LL(0x9d440eb3,0xdacfcf11),LL(0x7738fa46,0xa8257834),LL(0x76281df3,0x7db548af), LL(0x3e0b052c,0x71dd19f6),LL(0xd876613f,0x811feef2),LL(0xf9c3155c,0x7536e854),LL(0x4c8c1220,0x3e594973), + LL(0x069b4228,0xf8c5c72d),LL(0x1f2f6b02,0xc077d394),LL(0x76393a52,0x0032dfb9),LL(0x706c3572,0x5e52c880), LL(0xe003750f,0x4a9d6e9d),LL(0x6147cee7,0x3d54814d),LL(0x23b655fa,0x09ed7f77),LL(0xf1988361,0x14fff651), + LL(0xfb263d48,0x742f3abd),LL(0x53699a0c,0xedb557dc),LL(0x7ecd0f61,0xc692a474),LL(0x058f0d17,0xdc64f583), LL(0x3227d3ed,0x68a9ce75),LL(0x4601d083,0xfd0b0320),LL(0x9c2cee38,0x7167b330),LL(0x710e350d,0xef658993), + LL(0x16910648,0x75a83be1),LL(0x2e7d446c,0x5b32e77d),LL(0xa86ba2de,0x8e0534e5),LL(0xb692aeee,0xc8a92eac), LL(0xf663150f,0x3cf686eb),LL(0x01962baf,0x840eaade),LL(0xa264d877,0x3e06154f),LL(0x24630300,0xbbd04137), + LL(0x58631468,0x0b0151bd),LL(0x9f99bbe5,0x570ef82c),LL(0xb30f7b96,0x03565f47),LL(0x98c04b24,0x000628e0), LL(0xd6ccdb2b,0xd34a90ae),LL(0xa99a761c,0x1a584858),LL(0x65e29f1b,0xa640ddca),LL(0x728d3208,0xffb672f9), + LL(0x5433abd8,0x550f6392),LL(0x13ff0107,0x4f35e116),LL(0xe731a37b,0xbb2b0fab),LL(0xc83d6e74,0x1e8a5a08), LL(0xc6565e23,0xf617e177),LL(0x76da0795,0x8e370e5a),LL(0x03936a55,0xa5631e02),LL(0xd41293ad,0xe576bee9), + LL(0x5381bc98,0xfcfd9bc7),LL(0x000a98ab,0x8a42ddfd),LL(0xb49463c4,0xd6091ca6),LL(0x9754ce07,0xf37f6b9f), LL(0xfa399fda,0xe1543897),LL(0x8810063c,0x7b029ead),LL(0xec5a5b52,0xa98a46bd),LL(0xd50cc504,0xdd162811), + LL(0x67a95e56,0x4d725c1d),LL(0x8e17af44,0xc36d6e8b),LL(0x313454c1,0x38ffb699),LL(0x991e4eaa,0x22c3da8c), LL(0x0bb72dc0,0xfa36ee15),LL(0x4fd01d32,0x356bbf74),LL(0x3c7939a3,0x9ff71a30),LL(0x691786e9,0xa0ad2fb5), + LL(0x283c34c1,0x7d7f4770),LL(0x2454a31c,0x0148a4f0),LL(0xeab3b646,0xdcbb138a),LL(0xf101223e,0x7834bdb9), LL(0x965baa81,0x49de6cc3),LL(0x15471215,0x5462f15e),LL(0x81d17760,0xd77e7a56),LL(0x53f00de3,0xa08c5ad9), + LL(0x397ed010,0x2e6e6686),LL(0x2bef28cb,0xe444a5a9),LL(0x4073cbe4,0x1ab9d616),LL(0x18f0b7dd,0x24c6b9e0), LL(0xc2a93055,0x456482b6),LL(0xefbe8715,0x0f89129f),LL(0x62e5f6f2,0xb50818c3),LL(0x3d63c663,0x1d74a1ca), + LL(0xd84bfa55,0x9a9124ee),LL(0x254b3f04,0x6cf81f41),LL(0xa1051109,0x7c9b7c3e),LL(0x640e8df2,0x71c3d6d6), LL(0x62f6af2f,0x56571157),LL(0xe1bc9ae8,0x2ec61a3f),LL(0x2fcc848b,0x20caa2ff),LL(0xdc5c297e,0x71e30dac), + LL(0xfbc0740a,0x11901efc),LL(0xb6e35fca,0x4994fc5f),LL(0x177de7dd,0x4dc09eba),LL(0x0494bebf,0xedfdd25c), LL(0x0cbaeb8b,0xc4821ed9),LL(0x66788fbd,0xa9ef7a48),LL(0xd65efbc2,0x5b7a7ca5),LL(0xa9cb1fc6,0xe18feb42), + LL(0x56b00ab5,0x2cc74b9c),LL(0xdb4bf3f4,0xf559a140),LL(0xb8a4b54e,0x283136d4),LL(0x37032aa2,0xe969e4f8), LL(0xd85beed3,0x5635fb66),LL(0xa72a54bb,0x32bc4fdd),LL(0x4c386a49,0xc1e5ee2b),LL(0x795a0b08,0x979fd877), + LL(0x431f0b8e,0x5acef24d),LL(0xd13cafef,0x9f1c4a80),LL(0x4659f447,0xf19ac70b),LL(0x10f561ae,0x82bab6b6), LL(0xbbc879a7,0x1268e7f3),LL(0x79c37165,0x7e7d7141),LL(0x597e313f,0x491f049d),LL(0xecc98736,0x6ca7e73e), + LL(0x80a31eb9,0xd7712aa4),LL(0x2d8b99d7,0xbf7376ca),LL(0x2b8e5f7b,0xc1166cdc),LL(0xf1a48c9b,0x562bf290), LL(0x31c38c75,0xa6e72238),LL(0xb5f42def,0x51a9a100),LL(0xa100b75f,0xa0931d81),LL(0x967830be,0x7022479d), + LL(0xc192bc29,0x53eaaa1f),LL(0x4123a9f2,0x09504e7a),LL(0x90671997,0xe897397f),LL(0x4294fda2,0xc56185d2), LL(0x9819b185,0xb531f278),LL(0xe9dda4cc,0x390155ff),LL(0x14d26bf9,0x1258a5d9),LL(0x7e5f13a1,0x47d8f5ae), + LL(0xe9591945,0xef9e05e3),LL(0x846441be,0x92d20e07),LL(0x1d897ad1,0x28cc70ef),LL(0x0bac861f,0xee962e74), LL(0xbed368e4,0x9b7a4236),LL(0xe49b9720,0xe65ac22a),LL(0x22c1bd82,0x851f0032),LL(0x1e75ab15,0x771573ec), + LL(0x702eb71a,0x2e0a4635),LL(0xee924cd9,0x65167c74),LL(0x10ccabb5,0xe16b3515),LL(0x10ea5907,0x63cf15c4), LL(0x616f5290,0x59dacdc6),LL(0x8e372a43,0x19eb409b),LL(0xe3c36beb,0x5c879337),LL(0x0555fa1e,0x5841e7e2), + LL(0xf346ec2d,0xce197347),LL(0x221db43d,0xe14818a8),LL(0xc935c025,0x1bf37115),LL(0xfee14ce0,0xb22bdb03), LL(0xf0e3dfd6,0x893c5efa),LL(0xb1f95e1e,0x8fe9d56c),LL(0x407e4db0,0x6ee580e5),LL(0x9fb33911,0x0292bfc4), + LL(0xb2869cac,0x598ce787),LL(0x4798690a,0xd2f77720),LL(0x9cb6015a,0x2689e0f3),LL(0x7127b0e8,0x8831ddeb), LL(0x5c4fd58c,0x44db087b),LL(0xcda33285,0x04a0c68e),LL(0xe1a4c364,0xe55f00d7),LL(0xb6393b21,0xb3a2ea9a), + LL(0x5e9d8db9,0x99ef4da3),LL(0x17b484bc,0xa01f11d9),LL(0x1767f6ca,0xc2283fbf),LL(0x9e77f389,0xbb524479), LL(0x10149726,0xc4ea3c66),LL(0x82ec5f64,0x4b71d644),LL(0x642944c7,0x0fe49d52),LL(0x5a17a7bd,0x69fef689), + LL(0x8c3dce23,0x2f3588fc),LL(0x68e0c237,0x9d429231),LL(0x86fa61d2,0x63756076),LL(0x729bc192,0x1d89c6b8), LL(0x00d3ffd1,0x85e098d2),LL(0xde6f9109,0x5bf292c2),LL(0x3e7b8f23,0xb20dc994),LL(0x87c6eb54,0xcbe51bad), + LL(0x0517b914,0x263fd862),LL(0x225499a7,0x447624ad),LL(0x71f807d9,0xfbb831bb),LL(0x2fe2e021,0x9514fe38), LL(0x52418e9a,0x881e8763),LL(0xf1d9b43b,0x268e4655),LL(0x1f780af9,0xf917044a),LL(0x3d758ba5,0x3727b2d9), + LL(0x68755cf3,0x8487eb90),LL(0x7fe12541,0x1887394e),LL(0x46af8ca8,0x2e4c65d4),LL(0xb9e119dc,0x72aae645), LL(0x1ec6ad73,0x958e0094),LL(0x8ce4573e,0x84a7eec4),LL(0xf9254b96,0x3d6d00d4),LL(0x8e421732,0x4ef44f58), +}, +/* digit=7 base_pwr=2^49 */ +{ + LL(0x7d3ad2ac,0xf59de0f8),LL(0xc0f92c5c,0xd2670cb1),LL(0xc900b6a5,0x8f05944a),LL(0x8d9668eb,0x11aeed23), LL(0x7c488ea6,0x21b038e4),LL(0x78083d75,0x406ea3f7),LL(0x3bd31fe2,0xd22197b4),LL(0x28a6ef9a,0xdc8f8ccb), + LL(0x02887281,0x679a6483),LL(0x7f9de66f,0x13f3d39b),LL(0xf1a7dee2,0x289c3c50),LL(0x40b698b8,0xa510a53c), LL(0x06f799ad,0xc566c3fb),LL(0xb5374650,0xcc95a879),LL(0x61c947b2,0xbd7343c0),LL(0x9543e51b,0xbbbff69d), + LL(0xba75aba9,0xb80d38dc),LL(0xd150f881,0xe9b61ac6),LL(0xca7b47c5,0x9f56af52),LL(0x77fb3128,0x040300d9), LL(0xc01fd0c1,0x36877184),LL(0x8b6e134b,0x40112a04),LL(0xccd71653,0x56daed90),LL(0xb74bd62e,0xec553aa6), + LL(0x11476dde,0x0398381d),LL(0x1ea0923f,0x4959204d),LL(0x017745bd,0xd67427ad),LL(0x6935e467,0xef022a74), LL(0x24e0380a,0x57e799f5),LL(0xb5f1a730,0x6ee2b64f),LL(0x521771d8,0x9aeaac48),LL(0x0992a13c,0x02c8521c), + LL(0x48f6934a,0x25dd9f41),LL(0x3e38e31f,0x8d191988),LL(0x32899837,0x35548844),LL(0xf56b07d6,0xf87c696b), LL(0x73e927b9,0xbc66e7d7),LL(0xbb0bedc5,0x04cdac77),LL(0x0bcd022a,0x1e6f2903),LL(0x22c574b5,0xafa637be), + LL(0x55c1759b,0xcdca4b1e),LL(0xa6819d39,0x3d46ee3b),LL(0xb4b0fce9,0xf7497ade),LL(0xdcb613c3,0x54aef506), LL(0x522ff464,0xbc11d721),LL(0x37bd3c51,0xf53f16f2),LL(0x485695b9,0x88f29955),LL(0xdac00fe3,0x428ce742), + LL(0xa3520c27,0xd971fbd2),LL(0xe05e1b9d,0x2204fe54),LL(0xf0c15c89,0xb08be507),LL(0x901a15c3,0xfeeda919), LL(0x84b60eb5,0x6576ad3b),LL(0x59e951da,0x40d4b9a1),LL(0x76244608,0xbe96e1b8),LL(0x58ef9f37,0x3af35ec9), + LL(0x153adbf7,0xbfe5c43b),LL(0x80351fec,0x07a66edf),LL(0x3b109e60,0x3d804235),LL(0xa832c162,0x4dc97176), LL(0xb1db1e5c,0x03fec75f),LL(0xa15b9900,0x6aa02da6),LL(0x4faa1cff,0x5f9e808f),LL(0xa6412a26,0x90aa28bd), + LL(0xe041d453,0x2fb2c15b),LL(0x86c18ef0,0x2b847efa),LL(0x115b7318,0x84f5ee9d),LL(0x71699936,0xd568b080), LL(0x6ea5c852,0x34658ae7),LL(0x126d10ce,0x99f918b3),LL(0x09b9407f,0x75e3d9cc),LL(0x7883f978,0x11c6a0bb), + LL(0x876db0fd,0x522a6925),LL(0x7a9a4211,0xc5401ca1),LL(0x6789e755,0x89163b57),LL(0x0fd6f1b8,0xd2b2c99a), LL(0xa7b452dc,0x427eea22),LL(0xef9db65c,0xce8e6682),LL(0xda9c80f7,0xfd835810),LL(0xea916411,0xdb91bfbb), + LL(0x798b5051,0x7a5aefad),LL(0x42a0d4cd,0xbd7ebc88),LL(0xbac28520,0x958e327a),LL(0x7d010c77,0xfa8bf6d4), LL(0x579752f4,0x8a7040aa),LL(0xe573d895,0x47974d84),LL(0xfe16f77b,0xfd2a0cdc),LL(0xdbf71fdc,0x0f08f86a), + LL(0x2983bd4d,0xb19de6f1),LL(0x1e3a28b3,0xb990931e),LL(0x00cbc4f9,0x43b71b8b),LL(0xf4d75a0e,0x35d1ddd0), LL(0xc653f111,0xc211951d),LL(0x88750928,0xbbc46824),LL(0x174803e3,0x0cf6e752),LL(0x8960d80c,0x81f5e0ac), + LL(0x0c52fcf9,0xe03ca085),LL(0x0865ced4,0xa795382e),LL(0xe7117376,0x03bd561c),LL(0x3fd7184a,0x8608dde1), LL(0xa2a98acc,0xfd48fd50),LL(0x11df74b0,0x902fa587),LL(0xfa73b8f1,0x683f101d),LL(0xe7c0efa6,0xc805d31b), + LL(0x5b11d6c0,0xe5effb4e),LL(0x01c8374c,0xba30f747),LL(0x0c275aec,0x8733511b),LL(0x97354e36,0xf140b740), LL(0x0341268e,0xb01ded69),LL(0x27eac17b,0x17bc3176),LL(0x8984992c,0x88097703),LL(0x3e05061c,0x37bfafab), + LL(0x111d0eb8,0x7eca9f09),LL(0x8f243481,0xda7eb023),LL(0x59b5e491,0xac3cb2d6),LL(0x4f794842,0x56e725b1), LL(0x45b2dff6,0x43245254),LL(0xef10ec78,0xeafe73b9),LL(0x78819dbf,0x0d3cb2bc),LL(0xe784eb22,0xff1cd617), + LL(0x9ce0fcd6,0x0dbaf1c9),LL(0x3232a847,0x732ea65e),LL(0x6a75d822,0xdb2ce218),LL(0x3d2273ca,0x88ffd479), LL(0xf2f26b61,0x89092ad2),LL(0x686706ab,0xfb7041bd),LL(0x5e23597c,0xe3d5fa75),LL(0x5995fc84,0xa2035bf8), + LL(0x4514b8bd,0x1feecd2c),LL(0x434b9233,0x57cb78b4),LL(0x24215322,0x59bd2ad7),LL(0x1ce8daa0,0x41437de2), LL(0x7147ce80,0x401bbece),LL(0x5abb61e8,0x5e462137),LL(0x5a3790eb,0xbbf21033),LL(0x5134dee3,0x9a791c09), + LL(0xcedd2cc1,0xc8ded766),LL(0x6447b925,0xa3e48e9d),LL(0x69efa728,0xc73282a3),LL(0x8d408bec,0x8cb72c30), LL(0x41cf92eb,0xfb4f2797),LL(0x26f2412e,0xef3f42a0),LL(0xa941ab5a,0xdbc0f972),LL(0x98337613,0xc7bd62dd), + LL(0x4e45dcbd,0x31892744),LL(0xb51b7f91,0x3b2979cb),LL(0x29b27fec,0x41e002f5),LL(0x4dd51b0f,0x9007ee68), LL(0x6e23d565,0x82f417a3),LL(0x77127820,0x3321f343),LL(0x199b32be,0x8d09d965),LL(0x5bc2017b,0x948429eb), + LL(0x124eb248,0x22b639f9),LL(0x125f8c22,0xed097f74),LL(0x5f8bed34,0xdbc02517),LL(0x51aa29c3,0xb93f5b42), LL(0xc7368c44,0x6fedd599),LL(0x2c772a9a,0x99a5a795),LL(0x7a5f156e,0x30b35ba7),LL(0x191c45af,0x9dc50978), + LL(0xb5b4c4fe,0xe8d241f5),LL(0xb75f54f8,0xda89eac1),LL(0x9ef86ae5,0xb399dba0),LL(0x51c1b8c6,0x2337bb46), LL(0x4d02f348,0xfe60b0c5),LL(0x0afc6cd0,0x709f1235),LL(0xb40fce18,0x8a0b458b),LL(0xe3929cfa,0xefe143aa), + LL(0x0ca6cec0,0xab3a4b0d),LL(0x67246ec3,0xcb235374),LL(0x1ec2538f,0xdf9b0e89),LL(0x80c7b53d,0x3ec2ea13), LL(0xd0ae3146,0x920c55f2),LL(0x43946090,0xd3ac4e1e),LL(0x97ebe7a4,0xeba72583),LL(0x393d401f,0x5031644a), + LL(0x9714de1a,0x802c3409),LL(0xde5bacba,0xc62d66d0),LL(0x903b8148,0xb6c2abeb),LL(0x5bffe1c4,0x203531ef), LL(0xe862ead7,0x186266de),LL(0x1a23bebb,0x21e643d5),LL(0x6edda603,0x15c13d11),LL(0xb1bebc77,0x39b4a3a3), + LL(0xb9ac4754,0xdb456c1a),LL(0x4d3f305a,0xf497e6e9),LL(0x3fa62dc0,0x84d27e3a),LL(0x2524b94f,0xc18c3569), LL(0xe380f5cb,0x92198954),LL(0x272ea458,0x81d8221c),LL(0x5f328491,0x6fa082f6),LL(0x8e304ccf,0x810ca5af), + LL(0x0d76e6d5,0xda9f1c15),LL(0xb7abad72,0x4bd38afc),LL(0x08aa20f5,0x14b5cc26),LL(0x81061318,0x010a1af8), LL(0x03c287c0,0xaf9d7a73),LL(0xbc4d40ab,0x9ba5105a),LL(0xb07937a6,0x99e4b824),LL(0xc869f63c,0x026d294c), + LL(0xc910b521,0xaaebde75),LL(0xa7d5dd9c,0xc803ded4),LL(0x62764be2,0xc8b713b0),LL(0x92540cf3,0x5ea9ea2b), LL(0x6930bd0e,0xbaa999c6),LL(0x1f4b254c,0x57052e53),LL(0x2b0b27ee,0xfb9fd699),LL(0x4cc83793,0x86b70932), + LL(0xfba59bbe,0x09ab4dd7),LL(0x04f4609e,0x83204fee),LL(0x93934977,0x251cb390),LL(0x647c13e8,0x8add9e8b), LL(0xe7ea7006,0x444815d3),LL(0xbd032c32,0x22333c0a),LL(0x4058b7cb,0xe7728dc8),LL(0xd1bc061f,0xde8eb503), + LL(0x493d76c2,0x5d3ece2e),LL(0xd804954a,0xa425f3ae),LL(0xeac95eb8,0x49100271),LL(0x38b4be56,0x94e4dfa0), LL(0x650f9930,0xa855893f),LL(0x50264765,0x1fa0a07d),LL(0x0d1d40be,0x37a3c169),LL(0x2eed2a0d,0xfedb51e4), + LL(0x1b3348b4,0xa6e0c2b2),LL(0xc414464e,0x9e361f42),LL(0x176e109a,0x3e14e2ee),LL(0xf4af92fd,0x5f1a6bbe), LL(0x84beb8e5,0xf15d4647),LL(0x97d36132,0xac3f01c1),LL(0x84ca42ae,0x36e669bf),LL(0xd9433ca1,0xf789bdbd), + LL(0xf71e84d4,0x384f37f4),LL(0x59d6481a,0x57de9473),LL(0xf5e6fa70,0xa9a81f99),LL(0x6cb57bf3,0x26f0a64f), LL(0x061d38fe,0xc07e1c13),LL(0x4a475732,0x6fae70e9),LL(0x840e595c,0x6cfb6b1d),LL(0x62848351,0xb23cf1f2), + LL(0x4fcf8743,0xef6094c7),LL(0x05fab119,0x7dc42218),LL(0x5c220d15,0x3207463f),LL(0x22c4bfb2,0xdf51b3f0), LL(0x1572735b,0x13db445b),LL(0x2f6db574,0xd7662537),LL(0x7796f888,0x692f1e05),LL(0x33f45593,0x9f3d7a5b), + LL(0x313de667,0xb5deb892),LL(0x66a478a8,0x75c872d7),LL(0xc4992428,0xb67b5513),LL(0xf70fde09,0xf97e010e), LL(0x60ee268c,0x49b0f053),LL(0xf67cd321,0x981b5141),LL(0x4fbc187c,0xb5a1ac8d),LL(0xc12e6da8,0x162417e2), + LL(0x62914938,0x07bb6fff),LL(0x19f44438,0xd385285b),LL(0xa28904dc,0x05a610a1),LL(0x5a29b9f8,0xd80a7099), LL(0xc177af4a,0x72ccb553),LL(0x5e3752f4,0xac0bd91b),LL(0x7ae838a0,0x8e8ae668),LL(0x1fdfe7c3,0xcaa5a46c), + LL(0x93d34156,0x2cc2c1a5),LL(0x61fe4572,0x22beffb1),LL(0xfcdc7418,0x66f9f3ce),LL(0x6af66892,0xbaccda41), LL(0x1af43f56,0x775c783d),LL(0x0ae04034,0x1b23b187),LL(0xe99b486b,0x5a9325f4),LL(0x8367ab05,0x36d5bfe9), + LL(0xa519d028,0x17d8d2fb),LL(0xbe00e7e0,0x27b6beb2),LL(0x15a3f03a,0x8d51c36c),LL(0x5faac8dd,0xbf90e78b), LL(0xb27ab69f,0x4e8c28e7),LL(0x4a553da4,0x37ecf0c7),LL(0x210fe720,0x3a39682f),LL(0x0b0cdd0c,0x60c62e80), + LL(0xa16647cd,0x893aa225),LL(0x64ce0455,0xcffb728e),LL(0xc4f0fe79,0x81891d39),LL(0xf9c39f00,0x1abe3073), LL(0xf961d05c,0x88336c27),LL(0xa5fc96df,0xc9033a88),LL(0x864b39f8,0x0d084405),LL(0x851e95c9,0x866aa904), + LL(0x98bae4a8,0x0c36da08),LL(0xb5feb202,0x9f88d799),LL(0x8054e4da,0xcd9aeb4a),LL(0x1e9134cb,0x005206bf), LL(0x17ee6649,0xd5f32bf8),LL(0x60847ad2,0x9431dcd8),LL(0x8a3e4050,0xbe6d62c7),LL(0xedf10d40,0x3ae68f7a), + LL(0x4604d71f,0xa95c9ea0),LL(0x415f8028,0x01aa3fea),LL(0x5a41970a,0x3dd55ca5),LL(0x0b5776b4,0x05978ad4), LL(0x787fe20c,0x7c9f5bdd),LL(0x75fdba0b,0x23b9fb7d),LL(0x5fcf3a0f,0xfb1a724d),LL(0x87817071,0xd63b3515), + LL(0x44e40138,0xecae282d),LL(0x87605748,0x8732df23),LL(0xd11188cb,0x0ef49da0),LL(0x51146cc0,0xc0478138), LL(0x46621921,0x4ba42323),LL(0x47dfa4eb,0x8836dd44),LL(0x8ec16442,0xdb6a0100),LL(0x9cdd2e87,0xabdd9b81), + LL(0x502e26d1,0x205ee262),LL(0x3294e240,0xb961ef9c),LL(0x6da7733d,0x7178f1fb),LL(0x232ecf73,0x989b69fb), LL(0x9a9bccae,0xb7278a35),LL(0x400a01f3,0xb1c81a0b),LL(0xa6b213ba,0x0781855a),LL(0x3429817e,0x8acc1b78), + LL(0xfb4e1aae,0x527e3a9f),LL(0x4c0b0f4c,0xc18c1cfd),LL(0x1fa7d9f0,0x0676c365),LL(0x4454cc7c,0x3314509f), LL(0xc7c48245,0xb0f45371),LL(0x695ef470,0x913fe759),LL(0xc8d3e0ad,0xbb676070),LL(0x902e1638,0x0db98fcc), + LL(0xfc4dfaa8,0x42874e9c),LL(0x7084b2cb,0xcbf89462),LL(0x8a846ab8,0xd6d46f77),LL(0x14c183b1,0x9e4506ca), LL(0xc53b7631,0xc2d0f9b7),LL(0x294d6c34,0xe47c3d8f),LL(0xc05d3f1c,0x04e3c868),LL(0xa5957fef,0xbacec4f3), + LL(0x3b77893e,0x4f4530ba),LL(0x69a18bd9,0x4c234f54),LL(0x5071f5e3,0xb45aadd8),LL(0xd1bd0b86,0x73e4160a), LL(0x1c474f64,0x43fcb30d),LL(0x617d1612,0xedef0769),LL(0x0eec330e,0x92076734),LL(0x5b0a21b5,0xd7767770), + LL(0x183e26f4,0x4b7dea31),LL(0xc9fd2e70,0x59d6ff20),LL(0xd5d914f5,0x7bdea00f),LL(0x56376640,0xc736dd0d), LL(0x38ae8300,0x593ae6ef),LL(0xdf0355bf,0xdafe49f1),LL(0x0db4491f,0x094ccd86),LL(0xfe4271ab,0x32295701), + LL(0x5db7014e,0x2b7690e4),LL(0xd7766bfb,0x1bbc9c36),LL(0x7d986d0c,0xc52249f0),LL(0x324f20ae,0xc7eec37b), LL(0x0e912329,0xd376afa3),LL(0x04268fa3,0xbc35e949),LL(0x9e91a4ac,0x617bf765),LL(0x1d483ecc,0xb1e932ed), + LL(0xac493266,0xd4e31672),LL(0xecdafb85,0x1c779fe2),LL(0x06280499,0xed09eb4a),LL(0xcd4e1f33,0x3dd8d965), LL(0xf34576dc,0x0fb4308d),LL(0x85781a43,0xa8ccbf5e),LL(0xce623a24,0x8dbf488a),LL(0x6118cfd4,0xb0e71d30), + LL(0x8cc9d957,0xfc68da68),LL(0x83815670,0x7e5e6b65),LL(0x3f185dfe,0x2c16f5ef),LL(0x98952b33,0x23a4098b), LL(0xd515f551,0x15a80298),LL(0xa7f8f341,0x71a2e7fc),LL(0x8cf4f7b6,0xed42b1b6),LL(0x1504d390,0x02743db2), + LL(0x3016e513,0x2bded3a8),LL(0xfb0f7bfb,0xa3c508af),LL(0xaa2be716,0xa6a490de),LL(0xf4485b9f,0x5a04d9e5), LL(0x6ad25b5d,0xd07b99d1),LL(0x65a72cb4,0xa1840109),LL(0x14c45a95,0xc8e2b32d),LL(0xe4f2ecff,0x0fae6e86), + LL(0xd94b6fe7,0xd09f454b),LL(0x23006b62,0xa776a633),LL(0xd332b4b9,0x6c700a1c),LL(0xce016225,0x50c3fb34), LL(0x8af71463,0x4b805bc3),LL(0x5f1fb3b7,0x049143e2),LL(0x5a6d1dd3,0xbcaf4b61),LL(0x4733abac,0x02093dd7), + LL(0xdf59f061,0x1a23c3f6),LL(0x80c4efb7,0x87a6c141),LL(0xd88e4363,0x47635ae4),LL(0xbf8d2072,0x75e2089f), LL(0xac83803b,0xa2bc1b27),LL(0xe2aafecf,0x8ae61522),LL(0xd0010193,0x4b459205),LL(0x9205f876,0x900f6a31), + LL(0xf808f044,0x49cddbc9),LL(0x95094ead,0x94637692),LL(0xb87c9bbf,0x3c9c7c0c),LL(0x4e1844d1,0x1699670a), LL(0xcbcf85c3,0xd8a978f2),LL(0x6a36e1c9,0x83e7b806),LL(0xfaff9c52,0x6f28a73f),LL(0xb71eaa80,0x51341222), + LL(0x9328a676,0x195461da),LL(0x21766180,0xefcc93e5),LL(0x771a5485,0xed82c930),LL(0x205a8bff,0x34f15ce0), LL(0xb8b3bfd8,0x88ab72cb),LL(0x8110fe55,0xbb59a5be),LL(0xc7d61a31,0x9ce8a082),LL(0x5b1c63d2,0xfe81d072), + LL(0xe9ff8421,0x9fae0be1),LL(0x967e13a6,0x4254f89d),LL(0x35da926f,0x1c094620),LL(0x4a76583d,0x84eda272), LL(0xe0e0ffb8,0xa4033064),LL(0xabc72d0c,0x47951945),LL(0xb72c32e7,0x0af6bb4c),LL(0xda797f9e,0x6c73357b), + LL(0x2ac2e99d,0xd7a726c9),LL(0xcd62e7cc,0xf44b4731),LL(0xe6225822,0xf89f8e29),LL(0x8d713d92,0xa44bb9b0), LL(0x9404f6c6,0x3291e8d3),LL(0x37bdb22d,0x50b7a4ff),LL(0x216a0f13,0xe008662e),LL(0xcf382547,0x150fa2d6), + LL(0x3138acbc,0xe5e47c55),LL(0x40d7f3db,0x595cf1e2),LL(0x2ee1949d,0x2872392d),LL(0x8a4fb721,0xdbd15bf8), LL(0x183351dc,0x30e78cdc),LL(0x6b294729,0xa39b8efb),LL(0xc7b553e8,0x0df4d23e),LL(0x659d3ffc,0x434f38fa), + LL(0x55a0c931,0x1764115e),LL(0xa5c920a4,0x34ea18b9),LL(0xaf903710,0x6a099ddc),LL(0xe49f2c7a,0x4b937dc1), LL(0x430f0a7e,0xacfc4a1a),LL(0x421dbe96,0x8f106a58),LL(0x1811d3fe,0x48ac7026),LL(0xb80f13c5,0x5484226a), + LL(0x8da7ca79,0xf692e17b),LL(0x718691b9,0x4827aaa2),LL(0x5c5ea68c,0x881f1c38),LL(0x88bdf643,0x1620f5d6), LL(0x0b9a5add,0xe5703cb2),LL(0xbe925061,0x392e6ea5),LL(0xb0bab0d5,0x2a66ce20),LL(0xf98e8dad,0x83a8e0e5), + LL(0xdeec2329,0x53532223),LL(0x346eea96,0x6a740238),LL(0x1dde2a6a,0xa54afbdf),LL(0xf2b5b190,0x0e6ca8c1), LL(0xf3cd4e46,0xcccaa3c6),LL(0x0eb7bb3c,0x168d66bd),LL(0x08d4f4e9,0xf1275144),LL(0x139811fc,0x2ae8c946), + LL(0xc870713a,0x4973c726),LL(0xba54b13f,0x298465ee),LL(0x940f224f,0x9f901403),LL(0xb9950a40,0x5cd6a07b), LL(0x069a8484,0x9d4095e6),LL(0xd4f8831f,0xe6bf3181),LL(0x39243da8,0x37ceb29a),LL(0x2693653c,0xb3887f31), + LL(0x42c98a56,0x685d2172),LL(0x3969dd9a,0x350fbab8),LL(0xe8ac84ec,0x728edca9),LL(0x59bbb0c4,0xf42beab3), LL(0x27d3c3fd,0x9793e746),LL(0xc732b37e,0xbf6016de),LL(0xdf0f248f,0x3688173a),LL(0x7ed59dfa,0x84fbd040), + LL(0xa6731b1b,0x2bad638f),LL(0xb7355979,0x1c7b4b13),LL(0xb8e77093,0xf21550e0),LL(0x53efc63c,0x14d0bc9d), LL(0xd56e1f29,0x119ae9fb),LL(0x4d60bc5a,0x3511309c),LL(0xe3574e43,0xec654f06),LL(0xbef6aea2,0x2d6695df), + LL(0x5d6abff7,0x27ece611),LL(0x640c9ab8,0xa706d42d),LL(0x5a6f8fa6,0x7a7252d9),LL(0x349aaf8c,0x32be7195), LL(0xff734e23,0xffb48a3d),LL(0x7d27b99c,0xa9b36c82),LL(0x0ccaedbc,0x85b7a57e),LL(0xc04f2394,0xb93b14fd), + LL(0x160700e0,0x3a3a78c5),LL(0x961e4af8,0xbd7ae60a),LL(0xd9472cd7,0xe1deb736),LL(0x3880bbbe,0x276b51b7), LL(0x1aa99bfb,0xcf0c4b9a),LL(0x689d7f58,0xaf949d5f),LL(0x65f33328,0x00878488),LL(0xe7d7b484,0x0f1a178c), + LL(0x849e6d32,0xd44550f8),LL(0xfe16485e,0xe7bc29d4),LL(0x2f343924,0x29bbfec6),LL(0x40f2b5ce,0xeeb802f2), LL(0xbbb64f33,0x2b337542),LL(0x9f9bdb3c,0x4c1d3a36),LL(0xc7a1cb88,0x1067cf3b),LL(0x4601fb6e,0x3f12a31d), +}, +/* digit=8 base_pwr=2^56 */ +{ + LL(0x1f8a4a91,0xb720a78f),LL(0x753dbe73,0x59e22211),LL(0xadd0991a,0x9f5ad99c),LL(0x7380726f,0x3a0db802), LL(0x7dfb4f1c,0x37f0761c),LL(0x5ac819cd,0x68e7098a),LL(0x37ffe348,0x9683d610),LL(0x2b7b5140,0x5bf205e5), + LL(0x61a97262,0x9846b5f6),LL(0x974a82f7,0xedf2cacb),LL(0xaf439654,0x3dfab85f),LL(0xc724ee09,0x43fb0ef9), LL(0x53b0119a,0xd0d5016f),LL(0x5bc8fc81,0x68445363),LL(0x1f65d298,0x6d10b649),LL(0x21a4e64f,0x0f3c88c6), + LL(0x7f34c517,0x320372a1),LL(0x2378bc27,0x5602bd16),LL(0x91aae024,0x666a592d),LL(0x317bbdaa,0x716886ab), LL(0xe3045103,0xce55fe68),LL(0x7de1d701,0xf2c4b0b2),LL(0x7d724cb6,0x8da35885),LL(0x9ec47314,0x9aac623c), + LL(0xb8529a01,0x824cff46),LL(0x4856b95c,0x6e4d82a2),LL(0xc65af7f7,0x58c6b833),LL(0xae110e53,0x8a6c4125), LL(0x4f083340,0x38207c30),LL(0x176cdb31,0x71aa384b),LL(0x42882de1,0x1ada2941),LL(0xc16a2e4a,0x38b1ad2e), + LL(0x142bcb30,0xbdda2720),LL(0xfaf604d1,0x56175263),LL(0xe6796314,0x086189c1),LL(0x5b04dd19,0xdab01c68), LL(0xba8ed3c1,0xce54e4b0),LL(0xe281acfb,0xf616513b),LL(0x5e0a6319,0xaf179629),LL(0x328b587b,0x85e79ac9), + LL(0xc9fd7da0,0x11d84588),LL(0x1238d0c4,0xa78682d0),LL(0x829d6475,0x333ddde0),LL(0x69de9e18,0x80c88440), LL(0xc6d8176f,0x5d15f21a),LL(0xa509d470,0xdaff9434),LL(0x8bbbfcd5,0x0191bb0a),LL(0x08fc2688,0xff7732b8), + LL(0x5ab3d89e,0x02fe772d),LL(0x9a786c91,0xf1580ec9),LL(0x5a323866,0x8fd83417),LL(0xbadec96f,0x93711d49), LL(0x6b9b4a30,0x2020c34a),LL(0xb8b0de24,0xbf10e000),LL(0x28de3ce5,0x2a5f298d),LL(0xfe1a1c63,0x807a398e), + LL(0x73f7c45c,0x9fb640cd),LL(0x0afe059c,0xeb1f87ad),LL(0x52b168d4,0xa3c3979a),LL(0x7b1e403f,0x6eef460c), LL(0x2724bb3f,0x6d943e50),LL(0xf9d922d1,0x53f3f1bb),LL(0xcd538b4a,0x547e7a03),LL(0xd2c4145f,0x37631e20), + LL(0xb1f810bf,0xe7e49922),LL(0xf2645825,0xacafdb0f),LL(0x15f35bda,0x0f22216a),LL(0xd85bd0b7,0x6f2b4d95), LL(0xbedc9ecd,0x2f203db8),LL(0xb91e090d,0x26639ff6),LL(0x3486eb84,0x94cd6596),LL(0x42c05747,0x32747db3), + LL(0xcebfa9f1,0xcd3e7a52),LL(0xfb2b3007,0x5e792d76),LL(0xb9ecce81,0x9669523d),LL(0x04f191e1,0x9263cc85), LL(0x69655fe1,0x192019c0),LL(0x4d984e59,0x1c5cc5eb),LL(0xdf33f336,0x9ad10ed6),LL(0x41d94897,0x0ca48387), + LL(0xf222476c,0xbd1ddf67),LL(0x12d6dc4d,0xb4ad7126),LL(0x93ed702a,0x5c327b18),LL(0xfa70cd9f,0x7e3a27b1), LL(0xc0c4f415,0xdca750bd),LL(0x213a5d61,0x98197c90),LL(0x6f10fcc7,0x9bbd014a),LL(0x2ceed4fb,0xb06061e1), + LL(0xa8ad25f9,0xaf6dbbe2),LL(0x7ade697d,0xe70e9f40),LL(0x6eb872d7,0xb829e016),LL(0x1b04173f,0xc330e15c), LL(0x0d4763d8,0xd4868e29),LL(0x4c18c9fb,0x37867f72),LL(0x28019486,0x5fd2f47f),LL(0xb16e9bdd,0xe6bfdf81), + LL(0x783e43c5,0xace2a977),LL(0x76eed46a,0xe1791288),LL(0xd1767739,0x3884a5b2),LL(0x427c50a3,0x14eddddb), LL(0x1c9b1fcc,0xbeeed5ac),LL(0x4ecdb47a,0x50b1cb44),LL(0x0dcb78d5,0xcbf69555),LL(0xf2b17a99,0xe60bf9c7), + LL(0x9e9ade95,0x0edae6b0),LL(0xcb78b1e1,0xb5c6e13d),LL(0x1c257848,0x32860fba),LL(0xef7f5080,0xfc9aa9f4), LL(0x32aac870,0xccef8508),LL(0xfb5310a0,0x4b237704),LL(0xfeebb972,0x4c3cf970),LL(0x763d5f67,0x5dd3c7a0), + LL(0xccbf29c6,0xa656797e),LL(0x5a76a56b,0x6d77f211),LL(0x0e3daff3,0xc627156b),LL(0x7646fb1c,0xa4bd37f5), LL(0xa8cd3e5a,0x5fd7e286),LL(0x2f5fed51,0x3889951a),LL(0xe48c49be,0xf8186fc5),LL(0xc662ee38,0x0d3d308a), + LL(0x970e164d,0xb7c9bf06),LL(0xbd3d3087,0xc27a88d8),LL(0xf4e7c899,0x8a37c9cd),LL(0xab411371,0x18494d5a), LL(0xd9d8b29c,0x06532375),LL(0x915a2f74,0xb92dd45c),LL(0x515acb02,0x8a23f6bf),LL(0x435bfa89,0x0e69248c), + LL(0x6866c5e4,0x8bf41ec3),LL(0x0999159d,0xf059e652),LL(0xd29d7cd8,0xf906838f),LL(0x3a269735,0xc30100f6), LL(0x6280e70b,0xb7742bc8),LL(0x867b54e1,0x0067d971),LL(0xf544622a,0xafe9032b),LL(0x118a2042,0x6b441e39), + LL(0xcdd66b70,0x905c8655),LL(0xc1e2110d,0xe88cce1b),LL(0xee674093,0x8cc23c0c),LL(0xb2ea3fc3,0x55ded4d9), LL(0xb58dfbed,0xdd14502b),LL(0x49f698f8,0x523a4dd9),LL(0x01c83e5a,0xf843a501),LL(0xfe71ee1e,0xf11fd4c1), + LL(0x162d7c0b,0xeedd7229),LL(0x4ccad713,0xd42d6a9e),LL(0x2b0c7b93,0xa082fffd),LL(0x2a5016b9,0xee3abd48), LL(0xc117e22b,0x5079c95f),LL(0x814b8666,0x5d4b9169),LL(0x9bf90a6d,0x9e0f5e87),LL(0x744bf7ab,0x4346bd29), + LL(0xbfb551b6,0x4d85af0e),LL(0x31f7a958,0xb48e3da8),LL(0x6f5bc50d,0x3b474ce6),LL(0xe7c8dced,0x9fdb47bc), LL(0x53003272,0x2064450e),LL(0x839e69da,0x6bb230f3),LL(0x4d822be5,0xb6941512),LL(0xf11a9dc1,0xb51bc6aa), + LL(0xb23047dc,0x866447f8),LL(0xe5f52c2d,0xe02dbd63),LL(0x02770a76,0xe6ea43cb),LL(0x56fa6c25,0x853f5fe3), LL(0x960de6d5,0xfe9615f0),LL(0xf4b1b945,0x37c8b0c8),LL(0x4618629d,0xa6e83805),LL(0x23a2ac61,0x38fb5264), + LL(0x01751c20,0x5dfd7005),LL(0xce72773a,0x7e100245),LL(0x0776794a,0xdf09f92a),LL(0x1b730fdc,0xc4a8de81), LL(0xf0c7b031,0x72c302ab),LL(0x1283913b,0xdddff68e),LL(0xe32517b5,0x24889098),LL(0x856a2934,0x2483a0f5), + LL(0xa1c3d56d,0xdf6d7dcc),LL(0x09afb797,0x07f9c00b),LL(0x083d9557,0xe90da23d),LL(0xcbc03826,0x80ae6e53), LL(0x7c0e1b23,0x1fd6ff6d),LL(0xb1100226,0x1e90f3c8),LL(0x05a24e23,0xf179e00e),LL(0x946f16bd,0xe5361efe), + LL(0x4c662091,0x50f12e4a),LL(0x28608585,0xdad2c7a3),LL(0xf7429473,0x55c66749),LL(0x045ea1b4,0x440b77de), LL(0x91229927,0x9f707b49),LL(0xc6725715,0x3501e29e),LL(0x1225a8e6,0x5626fabb),LL(0x9507e709,0x270a9c2b), + LL(0xbdcb9039,0xe0d629da),LL(0x20255b7c,0xb4d7cd22),LL(0x5ed874a6,0x10c8614b),LL(0x4e67d406,0x36891e70), LL(0x1dce66fe,0x020da834),LL(0xabd64dea,0xae69e1e7),LL(0xcc71b37b,0x9cf153a1),LL(0x44771c7e,0xa6e9d024), + LL(0x8840fc17,0xb15e31c7),LL(0x349124a4,0x57853112),LL(0xbac542ee,0x78a9d807),LL(0x38fe1188,0xe7b4d812), LL(0xb3a3b801,0x874adc70),LL(0x4694cec2,0x80c0e02a),LL(0xe97805e1,0xd05c8c0e),LL(0x89d8cd40,0x8eaebceb), + LL(0x378d055f,0x888c777b),LL(0xb104a132,0x6956795e),LL(0xbe8472d7,0xe4bce719),LL(0x5f51729e,0x23c9f0bf), LL(0x36a3bf3e,0xfe7f7e19),LL(0x20a32d37,0xf8f5d2ca),LL(0x93b8a344,0xf383b467),LL(0x27a6e2c5,0x7eab76f5), + LL(0x93b54bc1,0x86c31b0e),LL(0xfc4ecab2,0xb9405ea9),LL(0xa0f6d341,0x09485578),LL(0x4b77e8e7,0x88053bb8), LL(0x29a07ddd,0xcde9b777),LL(0x97649102,0xec8ea63f),LL(0xc516777a,0xf74d082a),LL(0xbacf0dd3,0xf4e26d89), + LL(0xd0b3b578,0x6a919da8),LL(0xa0b5f7d8,0x0bcc3b29),LL(0x9e55924b,0xbf4565e5),LL(0x7889dbb6,0x13b36187), LL(0x533981bd,0xad0e59c6),LL(0x0bd0cb7a,0xea941b62),LL(0xa9e7aa7c,0xe5e35e9a),LL(0x088bfd7d,0x27f61727), + LL(0x8b3c7fbc,0xda2a5a20),LL(0xba55cb48,0x33cdd403),LL(0x90e7ff36,0xb72b51cf),LL(0x6f215840,0x8cc4b553), LL(0xd2671224,0xf7b80ad9),LL(0x6a45436b,0x560b4387),LL(0xff9e8fae,0xdca90694),LL(0xf97aa84e,0x2e7e9546), + LL(0xf37cd717,0x71e9ff45),LL(0x0d73e98f,0x6edf335e),LL(0x9f715170,0xf355690c),LL(0x3f5a82bd,0xf74df40b), LL(0x95e5b105,0x28b6d931),LL(0x2841a54c,0x8827f47c),LL(0x62b4312d,0x159cb943),LL(0x8db37edb,0x277943d7), + LL(0x6113a9f8,0x561454fd),LL(0xe70e67e6,0x78ebe733),LL(0x903f2feb,0x8764360b),LL(0x97902f36,0x2ba3b3d8), LL(0x87490b8a,0x28808cef),LL(0xf05f31b3,0xb1175954),LL(0x6c9b4f4d,0xbd5d6005),LL(0xdd254e60,0x12b13fca), + LL(0x14959566,0x38d4e812),LL(0x36fe9a6c,0xe253b750),LL(0x809450c1,0x24b2c81a),LL(0x8fec36b1,0x0aa89966), LL(0x053e97e7,0x9a99deb5),LL(0xe31d3a6e,0x5e57321c),LL(0x8dbe78a2,0xcd7a4f33),LL(0x3299e070,0x9f809d4f), + LL(0xa26a9eca,0xd6de8cfa),LL(0xa158a735,0x33d5705b),LL(0xc2293743,0x08dd3fcc),LL(0x68bbbaea,0x1f8d0a46), LL(0x61bc4105,0x53ff76f9),LL(0x7c4a8fc9,0x6445e88d),LL(0xc285d0e6,0xfd9a8d04),LL(0xfe62b449,0xf08d0d6b), + LL(0xc062810c,0x08c27292),LL(0x6663fa28,0x955629f6),LL(0x9d86fee8,0xbaf96c0e),LL(0x46bb9894,0x1dbc5406), LL(0x93dd45c7,0x8d6b6207),LL(0x3ee989fc,0xaf3baef6),LL(0x59b7b2f7,0xf66cfdb1),LL(0xda16c637,0x287fc2bf), + LL(0x2d71f863,0xa44ca8fa),LL(0x84d5dee5,0xa1161962),LL(0x3957b610,0x5a5c8ce3),LL(0x17f50b57,0xdbb32253), LL(0x76056358,0xc6a4eb7d),LL(0xc359d90f,0xff9eb424),LL(0xa88cb38c,0xdf4afe23),LL(0xa696b75d,0x2ae727cb), + LL(0xd20a58c8,0x47cc63ef),LL(0xc492ab36,0xd319dc3a),LL(0x36c7f76e,0x887a7d83),LL(0xfcd4cf49,0x65ed5e3e), LL(0xda301d39,0x0e6f2f34),LL(0x38ad4533,0xf2f7c102),LL(0xae834622,0x8a3a003b),LL(0xa060a0d4,0x94084169), + LL(0x13c8a1eb,0xb673168b),LL(0x459f8da1,0x80109609),LL(0x5c82007b,0x68003fa1),LL(0x248e0430,0x9f634159), LL(0xfb9b6510,0x188156ab),LL(0xe62844de,0xc35be1cc),LL(0xb0c84d39,0x21e8f908),LL(0xdad3ae53,0xa886d3eb), + LL(0x82b0f5fd,0x9e20cd56),LL(0xc465c721,0xc0c12f0b),LL(0x6f913a6e,0xfeeb1051),LL(0xaa32d6fe,0x9e7c76b9), LL(0xb8637b5f,0x820b49a0),LL(0xf4abccf0,0xe9ae172a),LL(0xfb270e67,0xccc050b1),LL(0x2269d1de,0x0b51d7e3), + LL(0x678c8d8b,0xca772ec1),LL(0x77ae7c7b,0x74eea3f8),LL(0x1e1bcbd3,0x51550df1),LL(0x3458b249,0xa931c17c), LL(0xf204aed5,0x192c3a45),LL(0xc993c881,0x93abf63d),LL(0x83421891,0xc60aa2cb),LL(0xf6b70284,0x11ce6735), + LL(0x69e152e4,0x53e8a3ee),LL(0x0033da23,0x6889ece0),LL(0x7d585418,0xada56904),LL(0xf5e5abb9,0xaf81a877), LL(0xdf515727,0x36e0267d),LL(0x3daad2a9,0xe04b532d),LL(0x1a11ced6,0x290e3ee7),LL(0x65e7a651,0x5be7c429), + LL(0x8ef9b498,0xc0662cd3),LL(0x6c4dcbf9,0x0ec5fbf0),LL(0xce4d7e3a,0x26694c70),LL(0xfa52de99,0xc1699a93), LL(0x6dae3e97,0x2e0d394b),LL(0x4c66e572,0xe3af28cf),LL(0xba1e27e4,0x9caf7bf8),LL(0xd5a4bdaa,0xd5c39337), + LL(0x9ec8ad6d,0xbb5d9551),LL(0x609fc2e1,0xfb3bc1f1),LL(0x95fe12b5,0x0d95ad2a),LL(0x5341dc74,0xf6fd6e89), LL(0x7537b803,0x1532991e),LL(0xeaf96f9c,0x77772fd3),LL(0xf832749a,0x4ed09840),LL(0x95f19d25,0x69a194ce), + LL(0x041cc340,0x5464471a),LL(0x1c442289,0x26f7e550),LL(0xb5ce9706,0x38f2c20e),LL(0x8a44efd3,0xcf73f8f2), LL(0x586e8f77,0x5176eda5),LL(0x63ece447,0x47e33844),LL(0x86b00be2,0x83826e8f),LL(0x539807b7,0x49cffcdb), + LL(0x414d3fb1,0x543d1fad),LL(0x38b1ef44,0xd56aac6a),LL(0x96c89050,0x9980bb64),LL(0xb169b8a9,0xc300cb46), LL(0x83413df4,0x5ab01a6b),LL(0xf3c91eda,0x179b8922),LL(0x43cccc06,0x4060b943),LL(0x9458ec1e,0x4f6adeb5), + LL(0xe339e40e,0x0a4c6437),LL(0x02aefe83,0x9cb6c532),LL(0x23dce7ea,0xb072d02b),LL(0x59a9032f,0x2cd7b117), LL(0x81dbfaef,0x01220cea),LL(0x0905332d,0xffe0026c),LL(0x0197adff,0x95ec2cb2),LL(0x4c3d0e49,0x853bf6f5), + LL(0x25d78f7c,0x04ed54fb),LL(0xbb68cb9f,0x45aae3e1),LL(0xe32d7421,0xf4f1a2c6),LL(0x45a05771,0x646ade65), LL(0x91eab45e,0xab241cfa),LL(0x7b214af0,0xb1cf204c),LL(0x851d311c,0x92dfb3e3),LL(0x144ae0da,0x56479ffb), + LL(0x9a7a4ede,0xbf847444),LL(0xf5cfd20f,0xb26b1f15),LL(0x83b33b64,0xf380ed7d),LL(0x3d1998c9,0xa21f9564), LL(0xa720e347,0xd985c7d3),LL(0x8bdf09d5,0x98078974),LL(0xce947692,0xa1f34ce2),LL(0xf419c385,0xf69e6144), + LL(0x8c3adcc6,0xe1926526),LL(0x42746263,0x848974fb),LL(0x97791569,0xa731261f),LL(0x065b721b,0xfed39da2), LL(0x836a7e20,0x8369b04c),LL(0x53c19f62,0x5758a761),LL(0x0ebea868,0x45746383),LL(0x3b7d71a8,0x20179927), + LL(0x57632243,0xb466ed4f),LL(0x120577c9,0xc8d918cb),LL(0xeda40e9c,0xbab307e5),LL(0xd5f65d1b,0xe6dbc7d4), LL(0x60619e10,0xcae0c649),LL(0x6b0df67c,0xffddf6d1),LL(0xb32ee5d1,0x60488755),LL(0x47164a55,0xcb278aaf), + LL(0x0bfb732d,0x354c3392),LL(0x649bc125,0xcd4fc821),LL(0x770ffdb8,0xa8e1253f),LL(0x0ff0c37e,0xf7eec595), LL(0x7149b102,0xe5a65279),LL(0xd0528224,0x1cbbb56b),LL(0xb51c5df4,0x40b1a8d9),LL(0x39e1ca25,0xccb43d26), + LL(0xfdcfe8c5,0x48f74dc2),LL(0xfa5b8daf,0x3ccb31b6),LL(0x7de6300f,0x6f8dc5bc),LL(0xf247bc0b,0x2a373fd3), LL(0x17825306,0xefe13539),LL(0xc50c47b4,0xeb253484),LL(0x3c739f02,0x4a7f2af3),LL(0x9a3c6746,0x3a3eb385), + LL(0x588978e2,0xa90afa2a),LL(0x8d80894f,0x501fcebf),LL(0x6bf1a4cb,0x1de1d06d),LL(0x6cc42a07,0xb0f4a61d), LL(0x78d406f0,0x975cb8de),LL(0xe3d293e3,0x560b0d7b),LL(0x32e686ca,0x5746227c),LL(0x3fcb0205,0xd12854f5), + LL(0x499512e3,0x8c0eaba8),LL(0xade99108,0x8d97c229),LL(0xff2b5782,0xd80da38e),LL(0xaef08107,0xf8c30ba1), LL(0x076b97c3,0x9068d7d0),LL(0xb1b7eba5,0x851d1cb9),LL(0x318e4675,0x02bb728c),LL(0x76ddc683,0x0efe9707), + LL(0x6a248b04,0x6985d358),LL(0xf8969ed1,0x75eb6019),LL(0x606a0c64,0xecb66a20),LL(0xfe39b5e5,0xd1252f64), LL(0x2aa222a9,0x93d5d61c),LL(0x1ffff8ec,0x16c0d6f9),LL(0x5dfab0fe,0x0f1f962d),LL(0xcedcccb0,0x88776fe1), + LL(0xa32cbff1,0x410333c6),LL(0x093bcbda,0xca13ce28),LL(0x0e479259,0xd97b0684),LL(0xbf505c93,0x8b2b3ad8), LL(0x71761412,0x42092d64),LL(0x918acf33,0x9d0c842d),LL(0xac9ade57,0x904d3add),LL(0xe0d5ef6a,0x025e4177), + LL(0x0b33d4ed,0xce406ec0),LL(0x57b5c958,0xf73ac4da),LL(0x6ef70849,0x5f96cb8c),LL(0x77b32d5d,0x702ccc6f), LL(0xcea6885c,0x75bda8d8),LL(0xc0c0432e,0xbfc3e62e),LL(0x54631c9a,0x46db9cc6),LL(0xba1d1550,0x1669075b), + LL(0x2d227656,0x5ccc4e34),LL(0x02cb0644,0x0724e41b),LL(0x435601fb,0xc5e2077d),LL(0x68d6aee2,0x356155c5), LL(0xfde58906,0x0ea00013),LL(0x37a9eda4,0x79fa13c3),LL(0x8f51a6a6,0x7d09479d),LL(0x1f979fed,0x86e955b7), + LL(0xe39ab804,0x9cb22960),LL(0x03535a39,0x6aeae783),LL(0xb9909be6,0xeb4741de),LL(0x1a5f4139,0xb957c5da), LL(0xedc1819f,0xafdb3e8b),LL(0xe7caa690,0x33545722),LL(0x8bb66ed0,0x0ef33e28),LL(0x70e667b5,0x59073742), + LL(0x5c7773b8,0x0390fb3c),LL(0x286a809d,0xb80b4a2f),LL(0xfac46467,0xd17d6103),LL(0x91a48972,0x9a09a0d6), LL(0x39e44585,0xa2124b62),LL(0x174d241a,0x14c8a671),LL(0xada8ba26,0x99abfa37),LL(0xfbb457ae,0x847f3040), + LL(0x7529a18c,0x0587aaa4),LL(0x9bb45ee6,0x23b3f724),LL(0x2aa81155,0x4d7f5712),LL(0xa4f16d09,0xa9185804), LL(0x3fc992d1,0xab638141),LL(0x0cad0bb0,0xb6c326fa),LL(0x60f2cb10,0xe21c3625),LL(0x2fac20a9,0x6c7af09e), + LL(0xdc6f72ab,0x31e892fa),LL(0x21b81f7b,0x71d5c6a3),LL(0x298a0dd2,0xc3e2d70d),LL(0x13ecdc80,0xbc0c37e2), LL(0xe6496ba4,0xd3191146),LL(0x35115466,0x15f81541),LL(0x07d1937f,0x162be77d),LL(0x7b176367,0x38b4d194), + LL(0xb8cafbc9,0x4485966d),LL(0xf44c2a81,0x7cfc0d67),LL(0xe624cefe,0xe9e7ec4d),LL(0x581d4e48,0x4db8bec3), LL(0x7fc8615a,0xe76edf00),LL(0x9a02cdb8,0x1b62c4a5),LL(0x83938a6d,0x8b565749),LL(0x50c86c19,0xd813864e), + LL(0x16f55d40,0x7fc071ef),LL(0x9bb45ea5,0x70195438),LL(0xa35543ca,0x83cf09f2),LL(0x20554c19,0x07e91a84), LL(0x62a9d06e,0x51ecd701),LL(0x2044a663,0x00e14c62),LL(0x00423dd9,0xb1317c13),LL(0xa46eab4c,0xf49431bc), +}, +/* digit=9 base_pwr=2^63 */ +{ + LL(0xd0614aa1,0x35118434),LL(0xd1418434,0x8bae9779),LL(0xb8c15b89,0xf5641d82),LL(0x416432eb,0x2383af56), LL(0x2c73f990,0xa552d3f0),LL(0xa6bbdc7d,0x8df82e9e),LL(0xd75ec634,0x0f336aa8),LL(0x1603e53f,0xc42e3b2d), + LL(0xbad830d2,0x4b33e020),LL(0x590dffb3,0x5c101f9e),LL(0xbc80ecb0,0xcd0e0498),LL(0x52aa293e,0x302787f8), LL(0x220f8fc8,0xbfd64ced),LL(0xbe0ee377,0xcf5cebe0),LL(0x8913b128,0xdc03a038),LL(0xfde23279,0x4b096971), + LL(0xd2d638ad,0xb0f8c0de),LL(0x4f299d5f,0x47fc8c77),LL(0x9b68d48e,0xd1720a92),LL(0xa1c6f103,0xf944e708), LL(0xa146889b,0x36e34e04),LL(0xe74a2a28,0xb0aad2d6),LL(0xca52f53c,0xedbb034b),LL(0x87fb2713,0xe987a8e1), + LL(0xf727ef3a,0x6c5389af),LL(0x33db88fb,0x95ffeb95),LL(0x9dae0777,0x27cb7042),LL(0x616dbf02,0xd20afe81), LL(0x914bf706,0x0fab8e18),LL(0x0517cd09,0x3b1e66f3),LL(0x12e40644,0x24b46dce),LL(0x08f2d8fa,0x0ff10168), + LL(0xea2d8d84,0xe08a10df),LL(0xe97dda79,0xe31f05e7),LL(0x4e9ab132,0xfe95f84a),LL(0x927e216f,0xacd6f7fc), LL(0x83c5a3ea,0x025e27bd),LL(0x50f120fc,0xed010c0d),LL(0xb828101f,0x443b3b8a),LL(0x8cfc0dea,0xd8384819), + LL(0x83dc5447,0xe55f34c8),LL(0x04e4e9a0,0xbe76243b),LL(0x819166a2,0x78fb4cbc),LL(0xae37f80a,0x0bdfb703), LL(0xc217cda8,0xf869288e),LL(0x62af4156,0x2662bb71),LL(0x50ae9d30,0xce64f291),LL(0xdc0353c9,0xee0d4440), + LL(0xbd25609c,0x3e61a9ea),LL(0xb3839c8b,0x4ccaea93),LL(0xe43736e2,0x721cefa3),LL(0xd0035908,0x229cb244), LL(0x7f10aebb,0x936bc1dc),LL(0xb67332e7,0xc93a1002),LL(0xf98d1132,0xf4b53dd4),LL(0xd5a75030,0x7b99a196), + LL(0xca9a9526,0xb13caadd),LL(0x69a303e9,0x701c63fa),LL(0xb0a50f3c,0xb97d667a),LL(0x68e6557f,0x27c03d7c), LL(0xeb105607,0xab24e712),LL(0x8dd86ccb,0x4936aedd),LL(0x0a986d68,0x32196f8a),LL(0x248f5a65,0x0307b826), + LL(0xfcadb2ad,0x20e14b4c),LL(0x8c3b8c23,0x4cb4a092),LL(0x1caa9db1,0x50fe3c1a),LL(0x81c0a4e9,0x23cc56e8), LL(0x0867753f,0x5ab09199),LL(0xf9d47c55,0x5a253d19),LL(0x1a9bcc88,0x422b4e03),LL(0x671e4f36,0x4e1ce22b), + LL(0xebbe949f,0x588f58b5),LL(0x6982215b,0xb7762296),LL(0xcff863c0,0x3cc83dd6),LL(0x01098f51,0x81ec094d), LL(0xbe0432d0,0x214d69aa),LL(0x6455957d,0xe4e52a9c),LL(0xfadc1eab,0x94743ba8),LL(0x8176316f,0x2c395d97), + LL(0xe6bb4d34,0xeab6400c),LL(0xc0d49bf2,0x7364dc55),LL(0xe6959c7e,0xd6fa6e40),LL(0x7eaae61c,0x7960a997), LL(0x94ea77c2,0x918b3c63),LL(0x76866dd1,0x2cf4997f),LL(0xbcbba8ca,0xc4214abf),LL(0x7aa4aab2,0x349a6133), + LL(0x99458b24,0xd64bab77),LL(0x2eba3064,0x6fe19e25),LL(0x74068f03,0x9aabd83d),LL(0x6fdf8655,0xaef81218), LL(0x65593fef,0xf506d27b),LL(0xfaa457b2,0x0a1ad85d),LL(0xa303dff4,0x266d0f06),LL(0xabb416e3,0xe8114f4e), + LL(0x6aa5a1b8,0xe743f617),LL(0x1b5b2bd6,0xaf84652d),LL(0x092e2c46,0x8b1beab1),LL(0xe2518383,0x7e857549), LL(0xa9383124,0x6be2ece1),LL(0x7fc20081,0x8309442a),LL(0xc3046cab,0x1f00eb8b),LL(0x26f39f8c,0x959f3155), + LL(0x8fc2ed93,0xaacfe2d3),LL(0x78f0f858,0x83446645),LL(0xdda35ec4,0x58de6f09),LL(0xf78c69b1,0x891e5ecd), LL(0x91c13d67,0xff4a4ba9),LL(0x487d5575,0x6e78063d),LL(0x8d303a7e,0x226b621e),LL(0xc95987ed,0x5c9bc103), + LL(0x5e3be13e,0x28980108),LL(0x414af955,0x5e8c0ac5),LL(0xeaaa71a5,0x0f08e93b),LL(0xce4524f0,0x1bc50407), LL(0x921be66b,0x6a6a2e6a),LL(0xc27da9f2,0x37113baa),LL(0x52e90e29,0xc7b3c636),LL(0xc8558307,0xc075d178), + LL(0x88a45b65,0x605f581a),LL(0x68e58c1c,0xcb789200),LL(0xbc5bfe1c,0x14cbed65),LL(0xf02b11d7,0xd1af7dc7), LL(0xcd3a7cc8,0xb8341bc0),LL(0xa01a77b7,0x8e9aefe8),LL(0x5ae2a402,0x8eeafe87),LL(0xc11f3859,0x27a0698f), + LL(0xf7af9756,0xc5e49f07),LL(0x9e5b871f,0xffd65bcc),LL(0x423eed7b,0x62a95357),LL(0xb2ec687c,0x93cf64d5), LL(0xbe5da479,0x04b87dd7),LL(0x1a134c0b,0xdcceabd7),LL(0xc5c6925c,0xa4875091),LL(0x8e9c098d,0x3bf947df), + LL(0x11d1323b,0xb2617271),LL(0xe4c6046d,0x7769247c),LL(0xcfa6aac3,0xf9c1aaab),LL(0x354492e2,0xf7f13317), LL(0xe91befb6,0x4bd65afd),LL(0xf25b8f8d,0x3e78cd8c),LL(0xe60ff4d9,0x2adf53ed),LL(0x3d288d4c,0x81ec3853), + LL(0xee3bf44a,0xda852a71),LL(0xd7b5c6da,0x39b4ef6c),LL(0x44f4e720,0x472e6996),LL(0x9191614b,0xbbd19d38), LL(0x30c0e99d,0xa2bcc2ec),LL(0x57ba0582,0x29318d7b),LL(0xd315963a,0x322faf40),LL(0x0c0619d1,0x49ba5570), + LL(0xe5dcd066,0xc28c1f81),LL(0xff9e3493,0x64d1268d),LL(0xbdf8992c,0xab0db38e),LL(0x320cce30,0xe3790c26), LL(0x26e3e4b0,0x59b408a0),LL(0x6ab8504e,0xe9e5fe29),LL(0x83c9eaf3,0x45c827bd),LL(0x89518edb,0xc298e236), + LL(0x8d3ab381,0xb79a8b15),LL(0xdb0bb7c0,0x6bb951e8),LL(0xbe4b3353,0x5ebd3854),LL(0x2eb3b0fe,0x107ba27d), LL(0x46786cb4,0x9d01654d),LL(0xcf3a1aa2,0xf46d8352),LL(0xa1662f72,0xa8f669a0),LL(0x68a1d3e1,0xc979209f), + LL(0x65471473,0xc64975fa),LL(0xff1f2aad,0x1f8eec02),LL(0x8d0dd401,0x1b520fcc),LL(0x15e14346,0xcd732092), LL(0x8f878a76,0x616478d8),LL(0x7423e0f5,0x3579d49c),LL(0x1b2af15f,0x119f6d6e),LL(0xb08c2c8c,0xbbe33d81), + LL(0x8534a355,0x051d99c9),LL(0x458b764b,0xe3f3ddd3),LL(0xbc8c03bd,0xbd7e51aa),LL(0xe8d42e38,0xcd7abf4a), LL(0x3160e63f,0xf0d97428),LL(0x34d13871,0x258bba07),LL(0x3dcb885e,0x4fedb647),LL(0x50f0a645,0x009fca27), + LL(0x99775c4e,0x3f06c146),LL(0xf66e7d05,0xb10a4ed3),LL(0x3a3ab903,0x9300e3ca),LL(0xde3c3e1f,0x0a5610e0), LL(0x1af56fb7,0xe2827312),LL(0xd75d9a9c,0x7e2a2365),LL(0xf11f8963,0x9c3bb05a),LL(0x30c80488,0xdf94cac7), + LL(0x2d1143f5,0xaff1682f),LL(0xb4d6ed7f,0x5837e83a),LL(0xb4bce662,0xf3e179be),LL(0x8caa5fbb,0xfa8d7862), LL(0x59ea54c1,0xbdde016f),LL(0x3c1ac962,0xc488c829),LL(0x14b46863,0xabe8b367),LL(0x82897d1a,0xbcfde363), + LL(0x8c152354,0x87ddf0ec),LL(0x7a953398,0xdec85db7),LL(0x0b57108f,0x927a8b10),LL(0x525f78f2,0xb38b732f), LL(0xeb306d56,0x7e696084),LL(0x50269227,0x9befefef),LL(0xcaddfa11,0xfa86e376),LL(0x404be227,0xd50a08da), + LL(0x03bb523c,0xb7408e33),LL(0xc093aaf1,0x6d21aa4a),LL(0xa85d6fcf,0x52aae4c9),LL(0xb726afa9,0xf5d057c9), LL(0xf92ca5b2,0x7979bb5c),LL(0xc4e3e4f3,0x4b1f7936),LL(0x071ec517,0x2c534200),LL(0x67d3f86a,0x47b52ffe), + LL(0x84d1c5b2,0x4a0b581d),LL(0x0dfa90cb,0xfc825a4a),LL(0x11c72996,0x2df2ec98),LL(0x7dde922e,0x82077a6e), LL(0x9f28b584,0x89acda10),LL(0xe49fe66f,0x54578eb8),LL(0x4a1c29d7,0x90a5f700),LL(0xb3b44748,0x2de4719c), + LL(0x18d85e6b,0x6944fe14),LL(0xde7b904f,0x90bd8208),LL(0xa4597137,0x5811f3b6),LL(0xd4ab5433,0x7ea43767), LL(0xa204a36f,0x7ec39109),LL(0xa30fb76e,0xa43a4a57),LL(0xe090f2be,0x4fd514f8),LL(0xda1c97f8,0x3918138e), + LL(0x15145a20,0x2b466ae2),LL(0xfbac86b7,0x28ccb2ce),LL(0x04106b98,0xb891b707),LL(0x29696a08,0xe40a2310), LL(0x636d9e11,0x1210fed0),LL(0x2043caa1,0xdaea218d),LL(0x0aef7dcd,0x10c2ed0f),LL(0xffa5db7b,0x926be98a), + LL(0x36abac30,0xe762191c),LL(0x8b75b5cb,0xe21acfaa),LL(0xd180cc32,0x4f5e6b9f),LL(0x55deffdd,0x01358309), LL(0x992a66f3,0x1b1ab943),LL(0xceef1a9c,0x1ebe0246),LL(0x7a01dcb9,0xa24c9e25),LL(0x326505f5,0x3d45c4e3), + LL(0xc8544885,0x9b805759),LL(0x7bfcad78,0xbe9b99ca),LL(0x2b8fe78e,0xd1db36e1),LL(0xd5387bcf,0x37255a2d), LL(0xa150ad32,0x044b3a3e),LL(0x6671ae59,0xc65bc2a3),LL(0x1d52384b,0x41ce078e),LL(0x9e72c300,0x3115f1b1), + LL(0xd0a358a0,0x487ff9da),LL(0x9c242aec,0x4b20c369),LL(0x1c7b145f,0x7813a44c),LL(0xd6f2d3ee,0x87c6bede), LL(0x47d393b1,0x34d2a89b),LL(0x73f78679,0x1e9f97c6),LL(0x2edce91c,0xcb614fe0),LL(0x7e9a5fa9,0x62b96009), + LL(0x58c34b85,0x7eb2aeb5),LL(0xcf5074fc,0xa256a478),LL(0x98c1de9b,0x73f23a56),LL(0x61ce6535,0xeffd490e), LL(0x4a6c15c8,0x2569df2a),LL(0xfffc97a5,0x91e202a0),LL(0x28dc7a57,0xd83c428e),LL(0x9fc8dca8,0x03bc53c7), + LL(0x9b60487b,0xed394cfa),LL(0xb483a686,0xa4259f91),LL(0x179a5cca,0x11f51779),LL(0x86c1d1c7,0x00b00ef0), LL(0xf1231aed,0x6e596d2a),LL(0xd80eaa89,0x6c1a702b),LL(0xd23f1d64,0xd28f8c15),LL(0x6d01728f,0x93e85bea), + LL(0x1c704922,0xd4288fb5),LL(0x8c1363c5,0xaadd1968),LL(0x52f2cc4e,0x9b5c42d7),LL(0xc298e794,0xf9e4bc96), LL(0xaf0804ac,0xd604f076),LL(0xb3bb2628,0xa441140a),LL(0xd37bf6bd,0x761eabca),LL(0xbe1cf79c,0x7d192922), + LL(0x3da7073d,0x2365739e),LL(0x8e2c078f,0xfb7423ea),LL(0x3adfb6f3,0x08f5132e),LL(0x710a26fe,0x470a4205), LL(0x2b6c9b33,0xbe0afeb4),LL(0x3cd813bf,0x94d9edc8),LL(0x440a1699,0xa2c7a7a0),LL(0x4eaf0c10,0xbdc4ea3b), + LL(0x52fdc8d3,0x5a5455db),LL(0xb2945868,0x60485f39),LL(0x00af0abe,0x54ce9567),LL(0xe8d15f54,0x17bff77b), LL(0x0e14a7ec,0x0021c531),LL(0xdc9c800a,0x3efdb22d),LL(0x4d947ada,0x9a9e2747),LL(0xb37fc947,0x19417bc4), + LL(0x8f02c551,0x71ca8da8),LL(0x074cebc0,0x782d5da4),LL(0xc1a43a2d,0x99094980),LL(0x24890d9b,0xe1b02ff0), LL(0x45d82f7c,0x4eedaddb),LL(0x5061c943,0x7ae170a5),LL(0x4d47c578,0xaf8c7ea0),LL(0xad3a6eae,0xcad17044), + LL(0x4f4c9c8b,0x51383e61),LL(0x9182fc81,0x78d17182),LL(0x90d72cb4,0xbed6f0d4),LL(0x7bea62f0,0x98761291), LL(0xef3cd3fc,0x27594570),LL(0x91a8c364,0xf4759534),LL(0x2744eb2d,0xf5c607c5),LL(0xd8d8f337,0x0d6264eb), + LL(0xa8701750,0xb54867a6),LL(0x87691191,0x1387e940),LL(0xbd2f75dc,0xc451f178),LL(0xd1da6080,0x31a099d3), LL(0x49f87f03,0x0d0fcf97),LL(0x0af6273d,0x0b7585f8),LL(0x1142265d,0x3619cf2c),LL(0x05c559a4,0xf84d3f96), + LL(0xb83f2cb9,0xc3d3c80e),LL(0x8f602141,0xf4ef0b54),LL(0xb9612928,0x3afb343d),LL(0x8db5c907,0x7abe5620), LL(0xcf019b08,0xcd692215),LL(0x9ae12255,0x98d70b38),LL(0x8dfda5f2,0xb459e256),LL(0x8f3f403e,0x066a445e), + LL(0x423fbbb6,0x5663e123),LL(0x5424d48f,0xcc55ce36),LL(0x3b6d5467,0x8bca99b9),LL(0x316fc956,0x299ff0ea), LL(0xa0ceb256,0xd973a8d8),LL(0x6d9956b9,0x443ecdb9),LL(0x2f64f912,0x8c16a75d),LL(0xbbf7ab50,0x89e490c2), + LL(0xb8dbf031,0x4bd00db0),LL(0x7d2cb92d,0x866e0bbe),LL(0x1dd3db2c,0xad36406e),LL(0xe4e3f194,0x969dc881), LL(0x2a115bc8,0xcb3ac9e4),LL(0xe0a5ab75,0xb45efd5d),LL(0x55377d5c,0x1709c293),LL(0xde6bc25d,0x06d11ba4), + LL(0xccf2d10b,0x84a09347),LL(0x08ee5aef,0x571cd4d9),LL(0xa450dd82,0x1379ac02),LL(0xae404542,0x5b7f02f5), LL(0x2a7df4ce,0x17366e7f),LL(0x9830ebec,0x5bb3560c),LL(0x7c254726,0x5c582580),LL(0x70ab7b3d,0xea13f8fd), + LL(0x314e2a25,0x868c0f8d),LL(0x0be90b12,0x4b3dad3a),LL(0x32aaffcf,0x09970da4),LL(0x8a6d894d,0xe711e9cf), LL(0x0a80d07a,0x511521af),LL(0x8a2a2851,0xe3814716),LL(0x1de9183e,0xde76d41b),LL(0xaac779e5,0x8a9fc79a), + LL(0x26879f8b,0xd7d1f235),LL(0xe37d5f9f,0xcc849c85),LL(0x6b9cd82f,0x26b5488a),LL(0x91099141,0x1b068e8d), LL(0x35ee636f,0x040dc00f),LL(0xd84a9cbb,0xab40f94b),LL(0xdb303776,0x2e4cf65c),LL(0x78e8affb,0x42eaa12e), + LL(0x876f8f38,0x7835e4e9),LL(0x090ca6b6,0xcd421d77),LL(0xad0604f7,0x71a1d12d),LL(0x1a22e872,0x51c2d158), LL(0x429e45e9,0xfe7dfcc8),LL(0x48224b6f,0x20028f5c),LL(0x50abf907,0xf7afed37),LL(0xc4ce1a69,0x92183692), + LL(0x2d128add,0x0b93365c),LL(0x13200221,0x883f43c3),LL(0x4d309b2d,0x9d3b5a53),LL(0xcf91a023,0x60f0db16), LL(0x5b0e47be,0x20f0ebbd),LL(0x317d8b4b,0xcc20dde8),LL(0x5303dd7c,0xab033b48),LL(0x7a9c1974,0x6703eac7), + LL(0x351c8f26,0x92f0b738),LL(0x08569159,0xadd39ac8),LL(0x61098dd5,0x80866e5e),LL(0xcae578f6,0x7d0c1c6f), LL(0x975f59e4,0x13d89cee),LL(0x0092de2c,0x86006ed4),LL(0x819adda4,0xda825b0a),LL(0xde710934,0x74fefb46), + LL(0xd3dc8683,0x7c2ec289),LL(0x690e5d08,0x25898cd8),LL(0xbcc67531,0x9bed0f32),LL(0xac762453,0x356ba80c), LL(0x7680da5e,0xd3224c57),LL(0x3399d679,0xaae2597b),LL(0x68df6e74,0xb2a2a1e5),LL(0x2301b373,0x49d23e8c), + LL(0x170dd677,0xcb89b484),LL(0x6b3ee110,0x36b1d3d1),LL(0x0d7b51b4,0xe50ada4f),LL(0xfd9afdbc,0xa2f4fb57), LL(0xaa6dd8e8,0xb1b9b81d),LL(0x0be328aa,0x616056a0),LL(0xe12b07c8,0x8f6dd943),LL(0x325abaf6,0x4bb551c6), + LL(0x68fbed5f,0xa5460380),LL(0x87ed0d37,0xa65d059f),LL(0x208aa8cc,0xff60beda),LL(0x33d2d65e,0xc91ff11b), LL(0xf65f65d2,0x078c4e5e),LL(0xf347dccf,0xa92ed905),LL(0xf59e3be9,0x261ad25d),LL(0x3b69facc,0x95903d91), + LL(0xe789d854,0xcf0a2f94),LL(0x10fbf531,0x9d39cd51),LL(0x6de44e3c,0x980ed5d4),LL(0x78425caa,0xaedbae37), LL(0x7bd278b8,0x35804bc1),LL(0x6a2d7bee,0xf4bee96a),LL(0xa605671c,0xc6c553a6),LL(0x86f010d2,0x182c9238), + LL(0x9cd6f37a,0x94343b7a),LL(0x237190a9,0xa71e3853),LL(0xa8a28451,0xfcbebde7),LL(0xd711d2be,0xfa928367), LL(0xc3668951,0xba8fd2ea),LL(0x2d241329,0x00fad1ed),LL(0x5dbdffd1,0x61b82e19),LL(0x5a181dfe,0x0e5e5782), + LL(0xc60f1799,0x1c1bf593),LL(0x64ef800f,0x388d6950),LL(0xce927a87,0xf78ef00f),LL(0x6abfff9f,0x2a010419), LL(0xb0b7ffe2,0x13a7b08e),LL(0x6da4cc8f,0x4619da3e),LL(0x7937e0bd,0x8ac19190),LL(0x1af4f84c,0xf97d3fcb), + LL(0x8ac425a1,0xaea2abd0),LL(0x4a02e136,0xc619c17d),LL(0x1b2c4acb,0xf09a57d3),LL(0x87b4eb40,0xc6fce6fc), LL(0xb21b02f7,0xa161bb70),LL(0x95bcb925,0x075301fb),LL(0xe1b440ce,0x1d408003),LL(0x606b3142,0xb42a47af), + LL(0x1c832c35,0xd4ad09c7),LL(0x0e17fb8f,0x5bebe913),LL(0x8b45b250,0xbf8efbcd),LL(0xe5ca21e4,0xbef3cafe), LL(0x688076f1,0x08a18be7),LL(0x0c3a2648,0xabbb3fc5),LL(0xfb54720e,0xa77086e8),LL(0x19c29e8e,0x84277757), + LL(0x5b95b36d,0x551768ca),LL(0xc7df6d3f,0x8850a9b0),LL(0x5008c00a,0xe5a2737f),LL(0xad076e3c,0x9a577c0d), LL(0x2afa6a8a,0xbe7c611c),LL(0x04259dac,0x5dd9142a),LL(0x422bf3d1,0xd14253bb),LL(0x6805c78b,0x8c9dc4c6), + LL(0xd430488c,0xb9837258),LL(0x7abc184b,0xf9fc178b),LL(0x0c5e6a11,0x035d3079),LL(0xfbc2182b,0x20cbe540), LL(0x9d76812f,0x849994e2),LL(0xf7a85553,0x166a9279),LL(0x19d70aff,0x15ff0643),LL(0x4bc6a829,0x3c58e0b0), + LL(0x84df75ff,0x3809904b),LL(0x67a7c214,0x454c63fd),LL(0x2d873c09,0x79e0ffde),LL(0xcef301bf,0x620a3293), LL(0x237c2bdf,0x8f38c8e8),LL(0x13203c2c,0x61cf96de),LL(0xd0bef848,0xdff401d6),LL(0xee4bcbb6,0x3c8ed7ce), + LL(0x07ff8f9a,0x3e128e2d),LL(0xad7e8d5e,0x0653c0b2),LL(0xb1930408,0x7bb30bb5),LL(0x4c158386,0x91d18705), LL(0x80c21fb4,0xc4cf843c),LL(0x8a04133a,0x97a72d75),LL(0x4218755a,0x6b7c49f3),LL(0x68a40f68,0xc1a5a447), + LL(0x15ca3037,0x0ab9650e),LL(0xac06feb0,0x16b1fa71),LL(0x0faa3dca,0x50179660),LL(0x1c1aaeae,0x368b2d89), LL(0xb46f0310,0xf6fa652a),LL(0x79fcbc59,0x86a4d627),LL(0x6106a132,0x78169b8e),LL(0x9e387d16,0x40a741eb), + LL(0x80eed542,0x14a45174),LL(0x3362ef7f,0xadd64561),LL(0xc5dd0396,0x39228bfc),LL(0xea0c538b,0xe9fdf903), LL(0x74d235de,0x6bfd91ec),LL(0x24aa0a47,0x96ec2378),LL(0xaf8d6168,0xf5699241),LL(0xc548a60b,0x0a7b9be3), +}, +/* digit=10 base_pwr=2^70 */ +{ + LL(0x2ade9556,0xe5255c30),LL(0x75ba2e9b,0xe328af1b),LL(0x41ce9e47,0x9d3391ef),LL(0xfb0ffcc9,0xb74cd668), LL(0xe3226acf,0xc67103e4),LL(0xd2959e42,0xa65ad22c),LL(0x99d490fc,0x3aaa8406),LL(0x9ecc6356,0x3e26a1c2), + LL(0x4e92defc,0x71c975de),LL(0xd0089883,0x81aeb173),LL(0x2ec09190,0x8a30ce4a),LL(0x69a36d64,0x426e7838), LL(0x309bd2d7,0x5899a0b6),LL(0x3cc1a4af,0x3b1c24af),LL(0x345163b3,0xb2aa8142),LL(0x2c78c86d,0xd2ad9a69), + LL(0x8e7a4174,0xde59fe5d),LL(0xab3b0f3d,0xaedff2d2),LL(0x1f053470,0x4688e9e0),LL(0x97c95c7c,0x29ff3fb1), LL(0x85e6a8df,0xffb930cc),LL(0x623b6068,0xaa4d3175),LL(0xf9716623,0x682101dd),LL(0x402db696,0xa3bc9f5f), + LL(0xba4e4651,0xf67233c6),LL(0x0714d4ac,0x8cf95660),LL(0x71f1f8da,0xd70decc3),LL(0x7078370e,0xb674732a), LL(0x4ccc773b,0x4270416d),LL(0xde87951e,0xc848ff35),LL(0x493dfb56,0xa61506a8),LL(0x767eb110,0xd8371ea9), + LL(0x9e6b1d70,0xb468c382),LL(0x4cd025fb,0x1a901978),LL(0x5e6879e8,0x4bf50c7e),LL(0x71cf7119,0x6b862c0f), LL(0x06240e95,0x6a53ce89),LL(0x04107ff4,0x3ddfaa0a),LL(0x65532b51,0x317093cc),LL(0x0e27b5fc,0xf1e0f859), + LL(0xfe4674b4,0x96a97a12),LL(0xf7c97b12,0x2a132ae6),LL(0xa5f5ae91,0x5afcd087),LL(0xd4805ddb,0xfd1d3a32), LL(0xd7b5c8bd,0x0a989dc0),LL(0x4429af19,0x35d186e4),LL(0x42935fba,0x65623ad2),LL(0xe79b867d,0x4e274314), + LL(0x08aaba2a,0x47d92016),LL(0xf3f4c812,0x12b62343),LL(0x464f4b4c,0xb35bf043),LL(0xd8e8ba16,0xdc9391c0), LL(0x5d460c0d,0xcc0f8c4a),LL(0xe20fc6ad,0x04ce64bf),LL(0xaa4b7db5,0xd0289df5),LL(0xe5299815,0xe0ea15c5), + LL(0xda3adfe0,0xc066ee2f),LL(0x0c964e7d,0xce6a9bdc),LL(0x0c859476,0x04a0115b),LL(0x9c95699c,0xb5e02dc9), LL(0x11377eb9,0xf8301f62),LL(0x172bca2e,0x57b245a2),LL(0x7b47cf1f,0xa7d9b470),LL(0x1774b1c1,0x1b469bab), + LL(0xda2dce70,0xbb9ec3e9),LL(0xd29bcdda,0x02d5353e),LL(0xb215233c,0xc193244a),LL(0xd27a4e2a,0xb8d5727f), LL(0xb6c5b114,0x79e56194),LL(0x5ce727f0,0xe2c20e71),LL(0x236cbfea,0xc92f34a5),LL(0x56a02b8f,0xcc47dfd1), + LL(0xe983ba13,0x5cdbda39),LL(0x6e96c8b2,0x20f3de57),LL(0x66b76faa,0x2ff05aa7),LL(0xd7f84b47,0xa876bc62), LL(0x0d677d1f,0x962ef8a9),LL(0x801d3001,0xabc7bb1e),LL(0x7d13a23f,0xdb5f0b1a),LL(0x20b819e4,0x2664f3ab), + LL(0xdc45375a,0x96be66c5),LL(0x4a6c24e8,0x780ee062),LL(0x013a13ee,0xc6fbfd1a),LL(0x21fc4f9c,0x6ce1496c), LL(0x81f272c5,0x03130c09),LL(0xa26609cd,0x06e59457),LL(0xee5363b4,0xf4c5e564),LL(0x7df0775d,0x1cd19a11), + LL(0xdfd6586e,0xcdfcfa67),LL(0x1ba23faa,0x358953e5),LL(0xaeec5d6f,0x0f467275),LL(0x5b0e6b2a,0xb815967a), LL(0x012b89b4,0xb01bf133),LL(0x6839cc04,0xdd924bbc),LL(0x120dfd73,0xa5cd2180),LL(0x19bf8098,0x1abb11ef), + LL(0x6a281d1d,0xd56c11ce),LL(0x70daeb19,0xfb01f455),LL(0x8f29fcc1,0xbb442a0d),LL(0xe9b2f829,0x9aa60157), LL(0x90ae8113,0x1f3f6e61),LL(0x6c946c0d,0xc701a185),LL(0x52ba7caa,0xb4b89268),LL(0xb0a5c77f,0xd657c679), + LL(0x0dd26330,0x0f14eb11),LL(0x9b036325,0xff622296),LL(0x186e735a,0xaf833fb8),LL(0xc7e710f5,0x7801b02f), LL(0x5c948f43,0xa0bf821f),LL(0x86225c71,0x3be31aea),LL(0xe60b1c88,0xe98f4f7b),LL(0x73c5281b,0x6306588d), + LL(0x83c9f829,0xd6178277),LL(0xc06675f1,0x67b20e6c),LL(0xcb2d5b9d,0x8a63fb89),LL(0x038c00fe,0xcb28128c), LL(0x8c7c6c6e,0x070a5141),LL(0x8789c3b7,0xc05e18c3),LL(0xd5c67731,0x09fd03c2),LL(0xf54010ec,0xc59e2abb), + LL(0xf1ef2232,0x03977889),LL(0x9c7409a5,0xbe2c82f1),LL(0x32004e03,0x35ac44f9),LL(0x856823a3,0x048bb359), LL(0xec1cf253,0x2e108d6c),LL(0x703eb1d2,0xe98e74d7),LL(0x570ac34d,0xcaf64f60),LL(0x4d7797fa,0xff814e7d), + LL(0x70818472,0x93b6abc3),LL(0x888357af,0x0e984be6),LL(0x3fe0c135,0x2a7ca1b0),LL(0x94a82d67,0x0c6c4a11), LL(0xbb83ae74,0x0c90c359),LL(0x328b8af1,0x49b25e5e),LL(0x798ff0a6,0x26a36032),LL(0x1fc28ca3,0xbbf89c99), + LL(0xe679eb71,0x4ce174e2),LL(0xd1c183bd,0x17c76176),LL(0x03a69f58,0x4bf67be8),LL(0xc0ee530c,0x937a391c), LL(0x1f7daaff,0x2daa9d90),LL(0xc54f14d0,0xa47e99b2),LL(0xc57feeca,0x6be357e7),LL(0xcfdfd5dd,0x3753fad2), + LL(0x48f90174,0x74e1457a),LL(0x9b4734da,0xb8092642),LL(0x5800ea72,0x291e75ba),LL(0xc72c28f7,0x25a21b38), LL(0x505aa4d2,0x2193e0c9),LL(0xada9d3f8,0x2f6829e3),LL(0x92900e29,0x66cd5a1d),LL(0x7414dc1d,0x1360d287), + LL(0x0d1b96aa,0x5deeb2eb),LL(0x3e52ccf1,0x25783ce3),LL(0x29d534ef,0xe4e251f4),LL(0x55797dad,0x9fe9693d), LL(0xc6ab9935,0x6a173d69),LL(0x7721ca8e,0x23991318),LL(0xc393eb26,0x38cbcd30),LL(0x71d95a9e,0xe3627ab9), + LL(0x7f6fe2d4,0xdf1218be),LL(0xfabd8326,0x850c8598),LL(0xb0f7cf49,0x1214d3d7),LL(0x1805345b,0xeaf60d31), LL(0xbfee2c5f,0xc5caf65b),LL(0x45e23043,0x70127979),LL(0x500fbad2,0xda36e794),LL(0x4156e3a6,0x38fa60b0), + LL(0x3cbab88a,0x45934bdd),LL(0x1b19dce4,0x72821e74),LL(0x8661e32d,0x532f706d),LL(0x73a9930e,0x3dbfc225), LL(0x3cbeb0f1,0x72d1cb2a),LL(0xe20f5613,0x795b0696),LL(0x9fc88717,0x6e3469e8),LL(0x483864d2,0xf4bf0531), + LL(0xfa19ddd9,0xc92e6a8c),LL(0x3528e628,0x7db7e2ee),LL(0xf321fc88,0x997a00eb),LL(0xacdf205f,0x7605a2c9), LL(0xea9c3ed0,0x9fca58cf),LL(0x56ff0e98,0x833078cb),LL(0x662a1695,0x75159b8f),LL(0x1919f51f,0x186560b7), + LL(0x5ef764b4,0xe9b60e57),LL(0xbe73c698,0x61ad29fc),LL(0xdd2be1ee,0x18489017),LL(0x7febda71,0xac95e3b6), LL(0x5ac96092,0xa6985346),LL(0xbfc83566,0x906265c3),LL(0x5972fa4a,0x1692c812),LL(0x00773540,0x4e76f879), + LL(0x542b137e,0xba9a6268),LL(0x4c7926e2,0x43a52b90),LL(0xfeae554e,0x28785bf5),LL(0x0ab61576,0xc023b688), LL(0x10933a55,0xb3ec8181),LL(0x6331678e,0x75634459),LL(0x17c50b5d,0xe0dfa141),LL(0xe2151f25,0x4cbe7fda), + LL(0xce81fbaf,0x3f3072ac),LL(0x0ff56a32,0xa387bb20),LL(0x99865968,0x2b08a811),LL(0x084cb1f2,0x7279f913), LL(0xdad70f5a,0x78cca6c9),LL(0xff47647d,0x72469f6a),LL(0xe358b597,0x2505c7ff),LL(0x998ff0dc,0x7c5268a8), + LL(0x99d5b1c1,0x32d70129),LL(0x24a90c34,0x72727c15),LL(0x715662b1,0x57dad21c),LL(0x132f3294,0x76b4b6ec), LL(0x267d246e,0xd03b46b1),LL(0x29b47516,0xc7c848ec),LL(0x1660af51,0x5eab3dbc),LL(0x04c66383,0x818894c4), + LL(0xa7b82f5c,0x26a45c3e),LL(0xea98adfb,0x494694de),LL(0x134b182c,0x44a06ec3),LL(0x75b82b41,0x5570befa), LL(0x129f952e,0x819f6808),LL(0x914f87c4,0xa6fad25f),LL(0x7c7be905,0x831e5668),LL(0xe623a5c2,0x93107f38), + LL(0x5e40c5f4,0xa9d88469),LL(0xaa5993c5,0x4314d233),LL(0x9c19bbc5,0x5eab88d0),LL(0xb385d3cd,0x795e1c21), LL(0xce163fbe,0x532a1871),LL(0xb867aea4,0x727cb126),LL(0xf7f30476,0xfc7047eb),LL(0xfcc4fe35,0x18031271), + LL(0x884a4c6d,0x4b84fa4a),LL(0x55c830ab,0x82cb9aee),LL(0x0cc927cc,0xd4cfdf04),LL(0xa16bef30,0x787efdde), LL(0x32e3c763,0xd1fb2dd6),LL(0x16737272,0x8739566f),LL(0x03a1055a,0xf9ae4f46),LL(0xf9a7472b,0x199970cd), + LL(0x1d33ac50,0xf9893cfb),LL(0x1e5ff4e5,0x74cf7dd4),LL(0xf7165331,0x72ec32e5),LL(0xbb4679cf,0xa082c59a), LL(0x5c75461a,0x3cd0a467),LL(0x40f06206,0xd2872d68),LL(0xb5122795,0x08271eef),LL(0x1475e22b,0x7006d350), + LL(0x89e35108,0xf7cd1bcc),LL(0x93f1cbaf,0x924efa43),LL(0xf35b13ac,0xe3716559),LL(0x60370a1d,0xa0a88e87), LL(0x8c286ea3,0x1203be0a),LL(0x6ebd50c7,0x97fc5ab6),LL(0x74284d08,0x2b5b3602),LL(0x694a20e0,0x3055716f), + LL(0x193520c0,0x793c8a89),LL(0x655f5ff2,0x356402d0),LL(0x1af5ddd6,0x0cf889ee),LL(0xb3f149b2,0x3eb7eb35), LL(0x68e07e0e,0x5254b57c),LL(0x9c5bbfa7,0xb1971de2),LL(0x0ad81e7e,0xcc85a53a),LL(0xed3cbb10,0xbaaa4d2b), + LL(0x8f3a7eec,0xbdf9941c),LL(0xa1f26666,0x6e1b7dab),LL(0x2d79a58f,0xe7a0dfa4),LL(0x1f2b9667,0x25e0ddb5), LL(0x5fd96351,0x4b3b5105),LL(0x8874abd1,0x12325832),LL(0x795d91a5,0x56e90310),LL(0x2c32eec8,0x376a79d2), + LL(0xa8a16445,0xd9dd8817),LL(0x0e00fa92,0xd61f6aec),LL(0x17d95f07,0x594a620d),LL(0xf4b15001,0xa1534fda), LL(0x0974f4a3,0xe9402601),LL(0x8f671f13,0x4c3fc130),LL(0xc5f35bfb,0x8eaab35a),LL(0x4626baca,0x13b98472), + LL(0xcdee6f8d,0xf48703ad),LL(0x12d39694,0xf1ba0309),LL(0x9fcda52c,0xeb2d4d92),LL(0x5507b401,0x984f5111), LL(0xf6bab9ec,0xe3aa26ae),LL(0x6b2e077d,0x557b5e3f),LL(0x2f9c5f35,0x7185ab4f),LL(0x1680bcbc,0x96f21a33), + LL(0x2ddb1173,0x2e7f6e07),LL(0x816ffc8d,0xa704416e),LL(0x52e26265,0x55acfaa3),LL(0x8b758c94,0x9c244253), LL(0x0479936d,0x4012e0a6),LL(0x6d8541d8,0x12749e93),LL(0xce56a2a1,0x374f420d),LL(0xc79da17f,0x6a8e3614), + LL(0x157cc9e1,0x3602ad09),LL(0x13603196,0xf3c4a54c),LL(0x8473ae27,0x354fc6ed),LL(0x651b8003,0xb4cf4251), LL(0x3415b5f0,0x456b1b9b),LL(0xc4c71507,0xe078a858),LL(0x9a0a11fb,0xf4210409),LL(0xf930ec45,0x76de42a0), + LL(0xcfa869a1,0x82ecd0af),LL(0xdccf2e47,0xa637938a),LL(0xc041648a,0x1d2858f2),LL(0xc0dfacd2,0xcf9abfe8), LL(0xbdddebe1,0x3af77e19),LL(0x180b535f,0x15f6b0bb),LL(0x549d34c1,0x497de678),LL(0x3dba7d6f,0x31495c9e), + LL(0x393ab61c,0x47b9368b),LL(0x27441f92,0xdb8ee3a8),LL(0xfb0b0117,0x214a6a5f),LL(0x43759430,0x429e61ad), LL(0x77316c0e,0x78116e88),LL(0xa6a29e98,0x59c82616),LL(0xaaef4619,0xbfed454f),LL(0x35926335,0x673327c4), + LL(0x18c616a7,0xaa66d8c5),LL(0x6d28fb98,0xa93946a6),LL(0x133336dd,0x4fc30de5),LL(0x7f0c805e,0x7e000a34), LL(0xcf7eab23,0xa82dcf54),LL(0x8dc24371,0x679e67a8),LL(0x1af582d8,0x26b2dffc),LL(0xd3fe2155,0x4c1d692a), + LL(0x2d024923,0x2475b110),LL(0xc303c1e7,0x0cc9245d),LL(0x03667a7a,0x290b7a77),LL(0xd87dbd9c,0x2ab8eb6d), LL(0xc098719e,0x7089e481),LL(0x12c022c8,0x17dd6d74),LL(0x8b7aca14,0x90efa01f),LL(0xf55fbe83,0x8b601fba), + LL(0x415aa7a5,0xf800bd76),LL(0x3aa74349,0x015573d3),LL(0xaf5ec789,0xd5143779),LL(0xd76dd2dd,0x32330b4b), LL(0x82331ef1,0xec6caa4d),LL(0x25ad1965,0x92cc8865),LL(0x134370b0,0xf8209a40),LL(0xb883cf95,0x320a37b9), + LL(0x5d39731d,0x94237ba2),LL(0x8532a968,0x6359d195),LL(0xf86b8b75,0x8bca94c9),LL(0xde316226,0xdb5c6a9c), LL(0xa2fa0c26,0xdf300c59),LL(0x48af4357,0x6dbf6082),LL(0x06535fc9,0x25066c6c),LL(0xa29b2477,0xba2e774e), + LL(0x1931299b,0x5157e93d),LL(0x3a8035a4,0xd6249c10),LL(0x81245740,0xcb18fcf1),LL(0xad5ebe1f,0xb4d84c9d), LL(0x8df0d59d,0x95050bec),LL(0xac2a2e0c,0x190a4860),LL(0xfd1bbb11,0x29029e0f),LL(0xb075b432,0x341f73de), + LL(0x74836028,0xa825c3c5),LL(0x8f55343a,0xec4fd74b),LL(0x60a683b3,0x009bcab5),LL(0xcd3adea6,0x29877303), LL(0x684a33ac,0x9f264bf2),LL(0x84b3c379,0xc8bf19e6),LL(0xa1215470,0x8ac35fb8),LL(0x405386d6,0x2919d9da), + LL(0x19780b2a,0xb4e4aa30),LL(0x356ddd4e,0x639b8fcb),LL(0x9322c245,0x6ed7b10c),LL(0x57f39c76,0x84ec0bc6), LL(0x879176fb,0x6a1be66c),LL(0xe10e0f77,0x4cab3151),LL(0xe2ae0777,0x01c6321f),LL(0x65e57ff1,0x04d6a04c), + LL(0x142596dc,0x8c1725ed),LL(0xb2d413a6,0xd321d49a),LL(0x2b5e8ae7,0x19c25fc3),LL(0xbd3c7dc6,0xfc32cbeb), LL(0x57b98ff5,0xf3ec98b8),LL(0xf75b1a00,0x52e5f1ad),LL(0x8f8ad463,0x16812bb4),LL(0xa274f0c3,0x9d67cb11), + LL(0x80064047,0xdec72055),LL(0x4319f87b,0x3f828c01),LL(0xff4d6c4a,0xffcad5c3),LL(0x67a6e030,0xee6659b2), LL(0x0478715f,0x9cb5c729),LL(0x5a1c926e,0xc63fc281),LL(0xdeb11155,0x1b8788ca),LL(0x4f0c00b2,0xbe2eebf1), + LL(0xa6af09d1,0x9b72ffd0),LL(0xa9a459f3,0xcbac42bd),LL(0xf560dc93,0x150806c0),LL(0xc57787ee,0x71c636e4), LL(0x2a951b0d,0xe4f3acb8),LL(0x3b18d294,0x510dc771),LL(0xb060e782,0xfbb3fb53),LL(0x0358210e,0x0659cadd), + LL(0xecde1629,0x23638245),LL(0xcc09daa5,0xee6e9a65),LL(0xee18f9cf,0xf440bb81),LL(0x955200e0,0x99e4d6e8), LL(0x93e69354,0x34555b58),LL(0xfb29b19b,0xa6080e13),LL(0x5100ab06,0x3bfa4796),LL(0x22eec8fc,0xf5db4b13), + LL(0xe5aaa980,0x2c1a229e),LL(0xd29eb83e,0x446cd46b),LL(0x7f5aa015,0xe0c044da),LL(0xa18f23f7,0xa55d5f23), LL(0xb6b70f51,0xd71e58c1),LL(0xb5862c51,0x77c72d10),LL(0xfce94ceb,0x01db731a),LL(0x13a47553,0x877703a8), + LL(0x3b75e6d9,0x4878b0b1),LL(0xfe60f98a,0xbe8421f0),LL(0xc69d6820,0x6312821b),LL(0x00d2db20,0x4c019374), LL(0x2a1d8b74,0xb1bd5175),LL(0xef7fdad6,0xa0a24ad2),LL(0x929fc488,0xf29fd27d),LL(0x162a02de,0x8e28b4ed), + LL(0xc166afcf,0x434cbdb3),LL(0xbf663e65,0x7b79e808),LL(0xa3c3b159,0xd445f1b0),LL(0xb35b2be9,0xdf9f92b7), LL(0x788a9bbc,0x815b57f3),LL(0xabbba2e0,0x9e03e357),LL(0x91a658d8,0x3fc574d5),LL(0xadf4e250,0x83b35d8a), + LL(0xacd1e4f0,0xa0e15175),LL(0x868b4e04,0xeca899a4),LL(0x782b7ee7,0x713b4e9e),LL(0xb7d58c1a,0xed177e1e), LL(0xac8364b2,0x4778df76),LL(0x2e8f7ef7,0x6898fb31),LL(0xa03975b0,0xfccf4c53),LL(0x8597436f,0x0f908d14), + LL(0x96671c53,0xbeaf1a16),LL(0x6bc4cbbf,0x9be64329),LL(0x80017bf3,0xc8f66f63),LL(0x8836ff35,0x92d700f2), LL(0x13a4daf1,0x9ddd7a81),LL(0x9b72664b,0xb3c42723),LL(0x81babf43,0x3d96f79a),LL(0x7ce5830d,0xa46c9c0c), + LL(0xf5999a71,0x54dfec97),LL(0xe586a578,0xdb5be461),LL(0xcfb4e7ad,0xf9bc3f04),LL(0xb11f07aa,0x6e5448a9), LL(0x70132d5a,0x29ef7791),LL(0x28ba851a,0x4fe486c3),LL(0xb62f7f8a,0x6743fecd),LL(0x44d24d01,0xeb264387), + LL(0x72ebb976,0xf93c05bc),LL(0xaaae099e,0xe65b30c0),LL(0xc8427104,0x4194721a),LL(0x3025853e,0x3af3487f), LL(0xdbf48435,0xb33a2893),LL(0x2d79334e,0x2c5ac639),LL(0xb16b05a6,0x8fc199f8),LL(0x7661a77b,0xc145358e), + LL(0x1841f719,0x15b580b6),LL(0xd7045528,0x24f5fadb),LL(0x98df2c22,0xe443c257),LL(0xd7eed58b,0x48acf5a7), LL(0xedeb9e4b,0xe24e6571),LL(0x562533fd,0xcd047b81),LL(0xd1566e36,0x618ddd86),LL(0xdba1eced,0x09a77b70), + LL(0x6968ddb9,0x0e9de410),LL(0x12985b32,0x10f0f429),LL(0x8ca7d2fa,0xbe21b10f),LL(0xc610ae2b,0x0844d8e8), LL(0xd57107d5,0x58a08694),LL(0xc34441f3,0x45f44bd5),LL(0x79a54186,0xe8b3b3df),LL(0xb8b5f26b,0x6496d668), + LL(0x192503be,0xd69cefb8),LL(0x40f928fc,0xb692128d),LL(0xa7ed8c47,0x13b11dfd),LL(0x5a196756,0x90bd279f), LL(0x17ff33eb,0x78f2e8c6),LL(0xaaf6c182,0xa7b233d4),LL(0x76a31f46,0x63d62503),LL(0x1449dc97,0x53143dc3), + LL(0x94922922,0x5bb86802),LL(0x89181334,0x2f45a7dc),LL(0x1ec5cce4,0xf7c466d5),LL(0xbb3bd5f3,0x52d15eed), LL(0xe6eacf86,0x150bd5f6),LL(0x0ba66988,0x7fecaf3a),LL(0x11f6f528,0xcdd7fadb),LL(0x55042faf,0x60f64c68), + LL(0x961ddf76,0x1615919d),LL(0x53f2f514,0xdba095cb),LL(0x1e6c076c,0xf04960ba),LL(0x4c9f17d5,0xe5276722), LL(0x61c186a9,0x93ff80f9),LL(0x3c58ab92,0xd17378b0),LL(0x769492e8,0xc67f9ae1),LL(0x0c3d023b,0xaccfc868), + LL(0x5b99708d,0x7d67a63d),LL(0x4b80189a,0xfb29bef7),LL(0x241c402e,0x3cb7eeaa),LL(0x2c5c2767,0x328cb6de), LL(0x9cec231d,0x0d24a7b4),LL(0x0e2e6a7f,0x725955fc),LL(0xb7f17b13,0xa2040cfa),LL(0xa25c71cf,0x215eff8d), +}, +/* digit=11 base_pwr=2^77 */ +{ + LL(0xc0d41a94,0xe4d9cab1),LL(0x9e60f7d4,0xc38b202a),LL(0x9336116c,0x2bbf6b17),LL(0x2e068f13,0x2f9aa877), LL(0xa4bac9fd,0xf8820627),LL(0x8a593cb4,0x2209cb9e),LL(0xc7417931,0xaa78ec63),LL(0x7cfccfbf,0x42d21251), + LL(0x3e611940,0x40cee5ae),LL(0x0aa090ec,0x4e2d9ea9),LL(0x1b926e42,0x73d167ef),LL(0x5d5112a3,0x7fff36df), LL(0xcaffa3fb,0x25587745),LL(0xc5a83504,0x224f7f4e),LL(0x3b47bf2a,0x5ceff018),LL(0xecfab5c6,0xed9bfa73), + LL(0xd9b429c9,0xf3d570b8),LL(0xc5ad81cb,0x69460116),LL(0x2f6825bd,0x30833a08),LL(0x7c99f36a,0xa297122a), LL(0x05c3abdf,0x6fc9b848),LL(0x5f2e24b2,0xefe95298),LL(0x8915d922,0xf045275a),LL(0x298a9726,0x79146aab), + LL(0x4f831d0b,0x0c7d5905),LL(0x2d47d4fe,0xfaaaa26c),LL(0x85042e12,0x5ac28599),LL(0x7796977d,0x7eda370b), LL(0x95c0be63,0x9f0bd71d),LL(0x8e821005,0x7c4601bc),LL(0x4c2ffae9,0xf1ecbc60),LL(0x9b688173,0x7e3efc57), + LL(0xf4ea7641,0x868c672b),LL(0xd94243dc,0x4fa90a82),LL(0xf5eab489,0xbd82913e),LL(0xe966b39d,0xceebc159), LL(0x35c51e2b,0x31fe4f5f),LL(0xc79c1725,0x2fea6ab1),LL(0x83afad40,0x5856cd85),LL(0x4ca89b88,0x7f960988), + LL(0x1ed8fed0,0x9d237c2d),LL(0x4e0c6f10,0x69b4ec80),LL(0xe4648395,0x11f83283),LL(0x306e152a,0x6f4636a7), LL(0x804539b3,0xf70fd23a),LL(0xb3cdb981,0x4db0903a),LL(0x6691eb18,0xe506ae6f),LL(0x1d8e9d9d,0xaa69c7aa), + LL(0x3e4e2088,0x540af950),LL(0x95f04e57,0x8fab01d5),LL(0xa8c51a67,0x51bf909a),LL(0xfd19beb7,0x01299f5e), LL(0xb8f15aeb,0xdf703400),LL(0x2d890394,0x19c70987),LL(0x203d2d99,0xf5fcc675),LL(0xc3d4ddea,0xabbf3f21), + LL(0x587feffa,0x8348ca15),LL(0x7d69e4ad,0x585d0740),LL(0x885a0745,0x6fbe5619),LL(0xb10b24dd,0x04ee9eba), LL(0x0f4c12d7,0x5c27075c),LL(0x3c51c605,0xacf4acdc),LL(0xfce336d0,0x782fa52b),LL(0x483621d2,0x6e1d078f), + LL(0xd4dc3277,0xa2253bfb),LL(0x4691bc12,0x3a014307),LL(0xebdef616,0x415aa5b2),LL(0x16fe065b,0x1008a44a), LL(0x16dfa94d,0x4004a90a),LL(0x8464785b,0x0e24f541),LL(0x88d30ea8,0xd2715c89),LL(0x1f05a312,0xaf81a9ff), + LL(0x3e8d5eef,0x958da470),LL(0xd3c80414,0x09561898),LL(0x8bb74691,0xba6b731c),LL(0x577f2ef9,0x6b7355cd), LL(0xb8a98efa,0xd1f416ed),LL(0x11590271,0xd4a1293a),LL(0x4658e9eb,0x2c4d5934),LL(0xd1f15d39,0x51803651), + LL(0x3c95fffe,0x9b9f0c05),LL(0x31acd6ca,0x8f021451),LL(0xf9dba549,0x5fee2961),LL(0x17ea0456,0x05217975), LL(0xd13a6a4a,0xc0591906),LL(0x90daf370,0xa7f5ed02),LL(0xfc4c304d,0x1f8b7158),LL(0x1b7f0246,0x77016c29), + LL(0x2ea265d2,0xc27d1847),LL(0x2862781e,0xec0789c6),LL(0x5d86a60e,0x0a79ac1f),LL(0x130670a5,0xe325b563), LL(0x6d33bfee,0xf4794460),LL(0xec25bb10,0x126e703e),LL(0xa7bf902f,0xeae22fd3),LL(0x28eef62e,0x8b2fb282), + LL(0x059138b4,0xb68de35b),LL(0xd46e68e3,0xfc44bf56),LL(0xff11f76a,0x71567daa),LL(0x6b17cd2a,0x9110e849), LL(0x69573b93,0x7c4027e3),LL(0x1eb9bf01,0x84ee945a),LL(0x28c26cdb,0xa3fadc6d),LL(0x575dfc1b,0x7037a74d), + LL(0x9b2223dd,0x58c96a91),LL(0x51461b94,0x912fc795),LL(0x2df3329a,0xc18ced63),LL(0x88a002d0,0x79d6f75f), LL(0xf44d3d84,0x73d7a089),LL(0x8c058073,0x98c78aa7),LL(0x333ae8ff,0x0ab8b3c7),LL(0xebd4e536,0xf5a8f5ec), + LL(0x83a5f52b,0x2c7df9fd),LL(0xcc062097,0x314fc7c3),LL(0xc5a3113c,0x6c3195f8),LL(0x2c25a629,0xf130cef9), LL(0x70c8dd70,0x10c8cc5b),LL(0x01cd40d3,0xecb7a35f),LL(0x6fe21c93,0xfbee538f),LL(0x2ba12ee8,0x57ec1959), + LL(0xb2b806a8,0x74387a1b),LL(0xbad5d0f4,0x14efa300),LL(0x23a0e9e4,0xee7e4421),LL(0x3b6abdec,0x504ae428), LL(0x927b1aac,0xb8c06fcb),LL(0x323b71d3,0x55e1c85c),LL(0x48d6dae1,0xf47e180f),LL(0xa84cb0b8,0x6d80dd63), + LL(0xd75d7785,0xf8e07d53),LL(0x37614325,0x3edf19b7),LL(0x357946ed,0xf03709b0),LL(0xd12105e7,0x567d8c0d), LL(0xa9383b49,0xecf6abc0),LL(0xcab329a7,0xfe9c760b),LL(0x43928852,0x425e62fa),LL(0x6194b51f,0x27945ae0), + LL(0x3ee4f7cd,0x756f0f54),LL(0x26e4c865,0x4337ac7b),LL(0x35b9c3ae,0xf94596c3),LL(0x4d6aa5d2,0x066fd3da), LL(0x43c8d94c,0xce1a5b7e),LL(0x614c0fc2,0xaed496a8),LL(0x2a6d5481,0x355e16f5),LL(0xa09d3afe,0x8f934639), + LL(0x2bf2a099,0xd170daef),LL(0xae6ee507,0x3920d87a),LL(0x248158e3,0xbdac1c8e),LL(0x05c54e69,0x99033a9a), LL(0x41872197,0x4513bdf0),LL(0xd3f0f889,0x15634020),LL(0x05d42aa8,0x76c1855a),LL(0xe8ba47cc,0x23079179), + LL(0x728429e6,0xf80b787b),LL(0x3dd8c4f8,0x896b6ea5),LL(0xc7d9fe06,0x711eef39),LL(0xebced829,0xfff28d03), LL(0x4ad40c88,0x5d7823b8),LL(0x3b112bd4,0x40a5a166),LL(0x63bce926,0x84230bfa),LL(0xbe17e7cd,0x39d2e6bd), + LL(0xef03ee6c,0xa772e242),LL(0xfa009e67,0x888bc969),LL(0x4893e1f0,0x0f06ee83),LL(0x6b89e124,0xf28f0d3c), LL(0x71f5cbc5,0xb3e70ef8),LL(0x6cad191e,0xff0f7e62),LL(0xf028d276,0x990697be),LL(0x4ad8f830,0x144c101c), + LL(0x3556d74f,0xbcaafb45),LL(0xeb4c7ea0,0xbc216224),LL(0x234a62c8,0x73ad1043),LL(0x2d95ff46,0xa644eb6a), LL(0x0a3373f8,0xd545b60a),LL(0xd4edaa10,0xf7a0572c),LL(0xa97a85b4,0xa7177049),LL(0x7d3ec769,0x529dbadd), + LL(0x7822dd37,0xc45610f6),LL(0x98258666,0xfad07fab),LL(0x87259c1b,0xac27001f),LL(0x1b849745,0xa9bdc6a9), LL(0x04c862b1,0xc7ee7216),LL(0x0012f591,0x32c1541e),LL(0x5a366d79,0x8198aadd),LL(0x68866e1b,0x03cd312e), + LL(0x9ec64698,0xa0dbc381),LL(0x1ef36dd2,0x770e4d11),LL(0x8d56bdfd,0x01d17915),LL(0x75eb9947,0xb48153cd), LL(0xfde98390,0xc1d17a54),LL(0x0fe2d6fc,0x0817eaf7),LL(0xa6a704f1,0x44a63591),LL(0x7f554182,0x9423465f), + LL(0x13e0574e,0xc7c23cbd),LL(0x439941b6,0x6e06e2cb),LL(0xafa39c79,0xa8aebd2c),LL(0xedede735,0x1b859e2b), LL(0x6b4f5465,0x2f485781),LL(0x624c81e8,0xec3093f0),LL(0xc282644c,0xc1f027c1),LL(0x2b74ab51,0x2f6e990b), + LL(0xed2ea3df,0x9a988d1c),LL(0xff39d3df,0xa3f50efd),LL(0xec1d7614,0x418a3627),LL(0x3d4fa3e8,0xafc1520c), LL(0x891a9c69,0x741305af),LL(0x5d6f8296,0xe87064d4),LL(0x12307b05,0x47c9394c),LL(0xc35f0f40,0x6b038acb), + LL(0x1ccca008,0xa6e77647),LL(0x9dd71746,0x58e4cfb6),LL(0xc1fe84ae,0xdf649c98),LL(0x90db4388,0x2e308ddc), LL(0xe9362400,0xc2641332),LL(0x42d265e5,0x92dd9842),LL(0x31eb91bd,0xe0e4ed9b),LL(0x145535c5,0x62ec7dd1), + LL(0xf810812f,0x1ff29a09),LL(0x15e9b102,0x56b64acb),LL(0x5b353184,0xb5f6d4d4),LL(0x1c593774,0xc3c9292c), LL(0x2c700292,0x16781036),LL(0x3ae2f0c6,0xf0948fc9),LL(0x4da778ea,0x40e353cc),LL(0xa34df03a,0x07febf09), + LL(0x9ec397ff,0x349812ae),LL(0x330f02d0,0x7c78812f),LL(0x7d241ea2,0xf956700b),LL(0xebed08be,0x864b1809), LL(0xb9eb1635,0xe4cec3df),LL(0xab49fb60,0x7dd65ad6),LL(0x86788a28,0x06551163),LL(0x11fb4214,0xda8792d5), + LL(0xcec09c3e,0x82140df3),LL(0x539db03f,0xcd34ca30),LL(0xe7dd0e09,0xf07cf030),LL(0x56ae3487,0x7b08a242), LL(0xbf5a6549,0x9c0fd607),LL(0xd189d68e,0x0b1fc745),LL(0x9cf52022,0x0d91be74),LL(0x43ff7fc3,0x6013f31f), + LL(0xb5654233,0x3bf90bd5),LL(0x202bf534,0xd0a17969),LL(0xc97e02ba,0xff373b8b),LL(0xd31dba07,0x4606de54), LL(0x8114562a,0xb045c50a),LL(0x7b8d8915,0xc123acac),LL(0xb60aa324,0xa8f7cd87),LL(0xabc48200,0x077cab67), + LL(0x0d7fff59,0x88a68643),LL(0x67bfe743,0x82b92193),LL(0xc2ce06f9,0x1a8b86cf),LL(0xf9ad6134,0xa38414a0), LL(0x28e2c39f,0x7f102610),LL(0x480856a0,0x34805c20),LL(0x18c3034d,0x1b3f9302),LL(0x574c0c9d,0x1713f457), + LL(0x690ce2a5,0xd84fa26f),LL(0xe01a4637,0xd4cfa19f),LL(0xcc6fad47,0x4807fb82),LL(0xf933226a,0xc9d84b48), LL(0x7cd2c9dd,0x9b7c530e),LL(0xf44818e3,0x6436a001),LL(0xdfb00461,0xbae0ceed),LL(0x51c8c8a3,0xed6a7c5f), + LL(0x0463ac73,0xa6e7fa54),LL(0xc77b19e5,0xa0deed89),LL(0xff218725,0x4e0a3396),LL(0x2edf2704,0x7cfbbd57), LL(0x4e8608c5,0x8114d0ca),LL(0x38c935b7,0xceae65b9),LL(0x330af8fd,0x052b1407),LL(0x723c422b,0x02e189a1), + LL(0x657560c8,0xf1cd6216),LL(0xe5068361,0x099eec2f),LL(0x3de78037,0x68ef58fb),LL(0xf3e399e9,0x83e0d34e), LL(0xf9a17095,0x3a2a14c8),LL(0xaaf9f08a,0xc7a360be),LL(0x30e99527,0x6420155f),LL(0x9f180405,0x8f610960), + LL(0x02bc97fe,0x871a832f),LL(0x8dc7f1f2,0xa14b3326),LL(0x87f78ad1,0xc9bd8b41),LL(0x0b59b9c5,0xd378d02a), LL(0x35c0dc14,0x418a32a5),LL(0xf53d85af,0x4c96979d),LL(0x08eb4b26,0xb6f40e97),LL(0xcaa6252f,0xa21349ca), + LL(0x5de38e2d,0xb13d8062),LL(0x9b43c5d6,0x54ea3684),LL(0xb1d6521d,0xc0ad58d7),LL(0x22085236,0x182f8823), LL(0x2a08449e,0x9d50cecc),LL(0x17ab0b68,0xeb85e785),LL(0x8d74e26b,0xb8a22ab7),LL(0x77d03987,0x77515524), + LL(0x77ad71de,0x117a63f2),LL(0xc94c8c82,0x1cca30d0),LL(0x2f05382d,0xe5fefba9),LL(0x9b4b42f1,0xcc9e8916), LL(0x9fe716c1,0xbe939e13),LL(0x95e38cc2,0xbf2b9c80),LL(0x37adde62,0xf60c4491),LL(0xf4df75a3,0x3eb3338a), + LL(0xfe4d84df,0x16398af3),LL(0xfaf3e5f2,0xed752cf8),LL(0xb4cf0e1c,0x746a4339),LL(0x39fb6018,0xb8bd479a), LL(0x57dffed3,0x3a9a045b),LL(0xa5ae3c78,0x2b46ea98),LL(0xde6b0399,0x74b5163f),LL(0x80e511c5,0x069628a0), + LL(0x1b96672b,0x19cfc882),LL(0x379d1f57,0x2759c76b),LL(0x2269a514,0xa6cc7a98),LL(0x683b1413,0x1bc2015b), LL(0x1bf4be62,0xc43b1178),LL(0x7bf2b0be,0xd2941975),LL(0xc4591cfd,0x1eac3587),LL(0x0e66d495,0x283169e6), + LL(0x052352e1,0xd39bedb7),LL(0xd719cd43,0xb04af7f2),LL(0xe92956d7,0x702143d4),LL(0xa0e5b847,0x53498722), LL(0x574885fb,0xf0e8edc5),LL(0x8b5187c6,0x4d9418ac),LL(0xd2a00019,0x70e99cb3),LL(0xe7f8a61b,0xf0da5be4), + LL(0x7dd34fde,0x52704cbe),LL(0x2926bb6a,0x0fb7224a),LL(0xf2b0af92,0x0d58bddd),LL(0x0e9cad36,0x2f986a07), LL(0x80e3a6f9,0xc85549d4),LL(0x322cb14c,0xa013e913),LL(0xf25ac201,0x8a19cf30),LL(0xffb8f2e4,0x130e4ce0), + LL(0x0ce56c13,0x21ad2c8c),LL(0xb15f6a2f,0x13ed2106),LL(0x9453ce96,0xa217b5f6),LL(0x64e0bf9c,0x93b1cdc7), LL(0xc4fe8e72,0x753d894d),LL(0xf3a3916a,0x46c6cea3),LL(0x383dd581,0xc1fb78e1),LL(0x17376a3e,0x1b7ba1a9), + LL(0x5df66852,0xa1411287),LL(0xa30445d3,0x4e9d333c),LL(0x917568a9,0xb5a26c14),LL(0xe857a6ac,0x885f1857), LL(0x84b1f8cf,0x05fbd3ee),LL(0x1e81e4e1,0x5c1f4097),LL(0x011f30e6,0x43999be4),LL(0xa890719d,0xa8aab3bd), + LL(0xc7088eb2,0x49d598ce),LL(0xe341047c,0x7a892468),LL(0x07cb6075,0x8e69b5c4),LL(0x8c37dc04,0x83d066fd), LL(0x6ffff7ac,0x4fcc6d02),LL(0x7edfb968,0x1afaaf74),LL(0x70d529de,0x2972b753),LL(0x08218b2e,0xf65bff0d), + LL(0x4182b9fc,0x119b3c4b),LL(0x27b5e101,0xcab66591),LL(0x2ab87a02,0xfff2e939),LL(0xeec5949b,0x1c10c40d), LL(0x30aa1242,0x98366224),LL(0xf225a4e7,0x833e9dee),LL(0x992e8475,0x07f1cfec),LL(0x1ef83a8a,0x377a9d79), + LL(0xc6715544,0xaf1d0863),LL(0x1fd71505,0x34dd65c1),LL(0x04fed293,0x74d55c22),LL(0x86d2f3be,0x31b1e50e), LL(0xc09594ac,0x876148b9),LL(0x8900b56e,0x73aace3b),LL(0xa2cf4c37,0x4617258a),LL(0xc6f38a92,0x554e8f16), + LL(0xda0723bc,0xd8594800),LL(0xf3c8381d,0x524452df),LL(0x138ca980,0x846dfa02),LL(0xe2d32e56,0xaa77a80c), LL(0x419c86b5,0x27573fbc),LL(0xb70216c3,0xe7486807),LL(0xc72036e6,0x8b7a685a),LL(0x15fae3d8,0xa1764627), + LL(0x815f379c,0x0a1f2361),LL(0x01ab64d2,0x9811607e),LL(0xff2c75cd,0x31841038),LL(0x474982aa,0x8751674e), LL(0x52a2523f,0x2f32b55b),LL(0xe85f2025,0x6ff8d2a7),LL(0x707b2dcb,0xd2ec31ee),LL(0x6e277971,0xdac81e59), + LL(0x0e78191b,0x5445e3a2),LL(0x8c80db2f,0x134dba0b),LL(0x94002b55,0xe9925a87),LL(0x4293c71d,0xe56fa2be), LL(0xa9d009c2,0x72aca4d2),LL(0x02fb0741,0x0c1219dd),LL(0x208fd227,0x689fbc66),LL(0xe4bb09d8,0x8266f2f7), + LL(0x2a61b8bb,0x1a791f9b),LL(0x3eff4f21,0xb29b31b7),LL(0xab7812db,0x2f97803a),LL(0x880ceb4c,0xdbf27bae), LL(0x45e9db5b,0xecb84887),LL(0x5cb7d0ec,0x3dfd84e1),LL(0x77c0b1e0,0xc89f61c2),LL(0xb7656544,0x7ada1d37), + LL(0x910a966c,0x0bca9585),LL(0x6f12c20c,0x80385b47),LL(0xa4b30374,0xf63a1605),LL(0x104b4783,0x2f91b24c), LL(0xb3ab423f,0x9210f5b9),LL(0x2fd424a6,0xb9aa656d),LL(0xf7e8d640,0x63c615d5),LL(0xbb59cfec,0xd567ff98), + LL(0xf7692947,0x78121697),LL(0xbd9f5ed5,0xb9166739),LL(0xb64b20e2,0x58d9a4f4),LL(0xc9fcc93c,0x291898d9), LL(0xd6c6065a,0xbce6509e),LL(0xb84834a4,0x39af658f),LL(0x94b49185,0x0f919d44),LL(0x5dbe7308,0x3b80fc51), + LL(0xe321c228,0xb9fd8ae4),LL(0x360692ba,0x4a46bd2d),LL(0xd05b84b0,0x91d5396e),LL(0xd6b058d0,0x266e89fd), LL(0xb2c42e38,0x6fb142d7),LL(0x994ebc2f,0x93c9fe18),LL(0x104b04a3,0x90e17885),LL(0x654eb6ac,0x6a5fa420), + LL(0x3f349b26,0x26c8a9b4),LL(0xb4e528ae,0x39387f7e),LL(0x5eb46726,0xa74bea43),LL(0x9150b043,0x0b3e82dc), LL(0xe2fc799f,0xc69ffac9),LL(0x48921338,0xd0479697),LL(0x0a4e061b,0x91a68264),LL(0x3f410bcc,0x93a6c41e), + LL(0x6b1fb104,0xaea8d055),LL(0x31fe146f,0x2ff339a4),LL(0xcf63c413,0x3d7ef85b),LL(0x289a097b,0x1f0f57c5), LL(0x5bda1160,0x82f2f83b),LL(0x6fea66e8,0x433eea4d),LL(0xcae11651,0x1f3fff4f),LL(0x6b1c243b,0xfa71c3fd), + LL(0x674832a4,0x59f36add),LL(0x2891e4e6,0x7b6d3802),LL(0x084fa3c6,0x47b313bc),LL(0x6584c9c0,0x90003ac6), LL(0xbc802849,0x9718c2dd),LL(0x2870ca08,0x9a5a2698),LL(0xcf68f352,0xb5cfe625),LL(0x6e6b0caa,0x90d0e2ed), + LL(0xba64d50b,0xb30780c3),LL(0x7acb4fca,0x16328345),LL(0x84b258de,0xf64e01fd),LL(0x35dcd2f1,0x2a25873e), LL(0xce4b39da,0x36606813),LL(0xa69a93e3,0x5285c91e),LL(0xdcb501d6,0x4da13aaa),LL(0x52e3dc24,0xb90d0a52), + LL(0x60a57d0f,0x6882d15e),LL(0x167612fe,0x52142caf),LL(0x463d39cc,0x532ccfb1),LL(0xe5a969f3,0xcdecde85), LL(0xd1bc4480,0xa89c1d1d),LL(0x83f32199,0x9373f362),LL(0x6d653c44,0x42f3493d),LL(0x6c80e27e,0xa867e4db), + LL(0x5cb7623d,0x954fbd83),LL(0x0b83d55c,0xba8b3007),LL(0xe2b23256,0x71946b92),LL(0xfaf95492,0xe0a2a7bf), LL(0x4e0c81ef,0x32ed3d91),LL(0x46f058d6,0xb8c8b14c),LL(0x67221924,0xc76c917f),LL(0x2ddf3cd4,0xd26c1d51), + LL(0x4fc9b14a,0x184e1395),LL(0xc1969b8b,0x651a0c29),LL(0xc9d5bf9c,0x05687179),LL(0xebcd85b6,0xb2f18ed1), LL(0xe446f1ef,0x8b662764),LL(0x71699f5a,0x6c0e051e),LL(0x27d93da8,0xf94a1151),LL(0xa05fe7a4,0x751235c6), + LL(0x624e9ae2,0x40aaf88f),LL(0xf5f6e5c5,0x6499b3f5),LL(0x98157f61,0x01fb0b8e),LL(0x33827220,0x070438f3), LL(0x50ab0b43,0x7409012f),LL(0x63c50e65,0xdbbba563),LL(0xc0d084ad,0x6b572ca3),LL(0x7b76cd6c,0xf10f6684), + LL(0x0c34363b,0x32bcca97),LL(0xb40e8157,0x7a9cef10),LL(0x6eaec234,0x3d5ffc51),LL(0x5f23d481,0x7d7b41a5), LL(0xeecdfe73,0xe5276c22),LL(0x8ac8c30d,0xa9b2725b),LL(0xed0c743b,0xee449588),LL(0x48df73b7,0x6d3b82a3), + LL(0x023cb0df,0xcb52edc2),LL(0xd5a24591,0x08773a4d),LL(0xe12a9072,0x0d9a6aaa),LL(0x5bf5586e,0x4261f56f), LL(0x60a08106,0x184b0402),LL(0xb09cfa61,0x1b398053),LL(0xd5dae483,0xdf7f55b1),LL(0x86ef2cde,0x9554210e), +}, +/* digit=12 base_pwr=2^84 */ +{ + LL(0x9204db30,0x564d6e85),LL(0x2aa84cdf,0x139bb928),LL(0x88476456,0x9413d7ea),LL(0x5a1ffa66,0x5c554483), LL(0x2ed18080,0x7b863089),LL(0xd14e5daf,0x589aaf20),LL(0x7b5f81ca,0xeee4f96f),LL(0x1bb0b415,0x88d47007), + LL(0x55c9bd11,0x1bb400d3),LL(0x06fc2851,0x8402465c),LL(0x65063b3e,0xa81ba22d),LL(0x6e1aa0c6,0xbab2dcbc), LL(0xbe645e25,0xe5f43f1a),LL(0x4df84be1,0x62320533),LL(0x21a2eaf4,0x14ac7080),LL(0x58beb26f,0x3f946464), + LL(0x7a82d20f,0x5f2a3e9a),LL(0x191011f2,0x399e015c),LL(0x886ac8e6,0xfbec312a),LL(0xeda47f96,0x0dd5140a), LL(0x26b47318,0x0d4df313),LL(0xe6685ec8,0xe2c9ec78),LL(0xcd8442cd,0x4df119ae),LL(0x7b32a1cf,0xdb1ca955), + LL(0x126506cc,0x7e2c5852),LL(0x08b3567d,0xba94aac7),LL(0xc05a3f24,0x6905cdf4),LL(0x3547f8b3,0xbf5f559b), LL(0xaade7a1d,0x9e4b4e62),LL(0x1fda3088,0x56b8b9d6),LL(0x4c43d89f,0xea3eb4c6),LL(0x9c69e047,0xfb7e537c), + LL(0xdfe5f6ab,0xc23d9491),LL(0xc1a9c0af,0x42fc362d),LL(0x127d2b35,0x04170b01),LL(0x04116aeb,0x4f0f17bc), LL(0xc9184cf6,0x716c01df),LL(0x895ceae7,0x914dc877),LL(0x390bff2e,0x696b2ae8),LL(0xf88af5db,0xf6ccd628), + LL(0x0f88095a,0xdada9bb9),LL(0x919ce305,0x7155c28f),LL(0x6d78b266,0x32a01e47),LL(0xb652c4f8,0x6da94459), LL(0x827ea8ef,0xa31783a6),LL(0xbdb1af2b,0x4d69b7c6),LL(0xaf31dab9,0x2874eb38),LL(0xafd9bace,0xa0ed9910), + LL(0x4037f17e,0x7d892e3a),LL(0x5f91a4fa,0x81fa9841),LL(0x961cf02f,0x17c7292d),LL(0x388bcc75,0x35af0c0e), LL(0x127a29b0,0x340bec90),LL(0x3d087445,0x955714a4),LL(0xa587c273,0xfd430880),LL(0xd24dfda2,0x715ecd50), + LL(0xaafd6cef,0x4ade066d),LL(0xf8c1decc,0xce59c8de),LL(0x77b96ece,0x3e12a24a),LL(0x44cc710c,0xee7c32fc), LL(0x240e9bb7,0x70700e4f),LL(0x6a63b06e,0x837ada54),LL(0xd19644ee,0xa58ce980),LL(0x27e7451c,0xcaa5d14d), + LL(0x387272fc,0x8e78d2ed),LL(0xfd8a0f13,0x9163a377),LL(0x635c55f0,0x858436bd),LL(0x5ba5b0eb,0x0a414f9b), LL(0x7d7383b1,0x2b58373a),LL(0x6030a376,0x5e7b9d36),LL(0x543514ef,0x9c69af86),LL(0x26080ff3,0x044698cc), + LL(0xa2e23074,0x76f54954),LL(0x17526081,0x90393264),LL(0xf3b78a50,0x0d095055),LL(0x69d8b26d,0x1f3a3776), LL(0xf5e7c8fb,0x0575e3bb),LL(0xee40b0c5,0xee7dd406),LL(0x55dab556,0xe6522e5d),LL(0xb61cd918,0x2d1b5709), + LL(0x01400b8d,0x0ea9278e),LL(0x6464f584,0x9552e745),LL(0x12fc094f,0x67f5645b),LL(0xde303128,0x77c40f3c), LL(0x0e3f3381,0x16d7e9a5),LL(0x59947693,0x017795ab),LL(0x9222eaf5,0xb69b5708),LL(0x1b77f122,0x61b213e0), + LL(0xdc8db00e,0xa7cc8bbf),LL(0x3aa7fc1f,0x1c51f5e4),LL(0xb4ac2d0c,0xb85b782e),LL(0x0468e5ea,0x32fde94b), LL(0x7f7ff0a9,0x8ad5b9a2),LL(0x8fdbb3f9,0xcd26f418),LL(0x6ebf89db,0x853bc95d),LL(0xa066b849,0x1da0a323), + LL(0x4bce0fa7,0xc4cc7aab),LL(0x6bc940f1,0xd4a05b69),LL(0x392dbd11,0xc77300e6),LL(0x21f70aae,0x0dc2eac6), LL(0x4b2ad7e0,0x9d4b513b),LL(0xa6daee1d,0x19822167),LL(0x69b98eee,0x7d71d202),LL(0x35f3f150,0xdfd435dc), + LL(0xddfd45ed,0x66d46ad3),LL(0xe50a2f01,0xf0325189),LL(0x3ec5683d,0xe19b9500),LL(0x91dd97e9,0xc46ab0a2), LL(0xed682c4a,0x74c971d7),LL(0xa14da289,0xafedac2d),LL(0xe39ba740,0xd17838fe),LL(0x053536bc,0xeb497bca), + LL(0xde6d4c38,0x551ba4ca),LL(0x4f52298b,0xa67be247),LL(0x9a5b40a8,0x98413188),LL(0xbb0acfb5,0x083a26aa), LL(0x11d16ebb,0x4929ff5e),LL(0xa942ae7e,0x91f08b63),LL(0x876663ec,0xaa428ef3),LL(0x1e97cbb2,0xfaabd309), + LL(0xf1edd62f,0xca0ed50c),LL(0xd29f48d9,0xc3c7ae6f),LL(0x8a72ae88,0xff47bf28),LL(0x348c6666,0x584ddfe5), LL(0x36731fdf,0x271137e9),LL(0x88d98bc8,0x714bc7db),LL(0x0da6be30,0xcea912c1),LL(0xbe62d6a5,0x91cb844d), + LL(0xec027bfa,0xe16ca42a),LL(0x17603e76,0x0c88f701),LL(0x63d5a31a,0x799418e3),LL(0xebb063f6,0x033bb53b), LL(0x625d3909,0xbcd05461),LL(0x85f23129,0x2d7b7868),LL(0x95090997,0x23b07887),LL(0x18d2c218,0x216c08ae), + LL(0xeebdbcf9,0xe1ccb6c1),LL(0xe873842e,0x89ca4552),LL(0x3c2fcdd5,0x4837f137),LL(0x108a8c0a,0x805874e8), LL(0x3d442fa7,0xe7e524f4),LL(0xf8131f8a,0x580d82be),LL(0x93d3d50f,0x6dcb7d27),LL(0xb5b39168,0x51207d3e), + LL(0x09110fe9,0x9a3ce117),LL(0x48721d93,0x8f3c6e4f),LL(0x87bdfa61,0x60a62b48),LL(0x7c01d84a,0x086dac65), LL(0x53841493,0x4af7878c),LL(0xb3bd5aa1,0x3b1a8935),LL(0x902e5686,0x65c8445b),LL(0x2e3b1822,0xde16cfa5), + LL(0x0a3e3684,0x19879e78),LL(0xee249180,0xec553912),LL(0xf8f4c1ee,0x8eb73fae),LL(0xb81fd20d,0xdee59877), LL(0x20b5ece3,0x2452e63f),LL(0xb632dddb,0x17be9422),LL(0x94311e6d,0x01f89220),LL(0xa332f84f,0x8f0fe052), + LL(0x1b9784d5,0x59657aab),LL(0xd8a7f347,0x6f2ce032),LL(0x6b95e6e9,0x84247793),LL(0x4395b044,0x34301cf4), LL(0xf7fb5401,0x98ebfd98),LL(0xfcdb31a4,0x14fd494b),LL(0xf90e0481,0x042f89d8),LL(0x4134ab52,0x6b90a008), + LL(0x7fe2ffec,0x8fa22555),LL(0xa778448f,0xc6dc3d32),LL(0x85f45aad,0x4886fedb),LL(0x51704d0c,0x5bdef90e), LL(0xe2d1fdaf,0x46ad596d),LL(0x04126f0d,0x914e0090),LL(0xaef960a6,0x71aaeb18),LL(0xac77472c,0x8f4601e5), + LL(0xd8d9768c,0x42e5a186),LL(0x00f6004f,0x8cbf3a6c),LL(0xc1ddebdc,0x9d4bf5ac),LL(0xa9c066fb,0x13354792), LL(0x923fe808,0x72e0b81c),LL(0xc526d6e4,0x1e73b868),LL(0xa81f1e24,0x3f7bedc6),LL(0xe920ba24,0xed1ff363), + LL(0x659604c5,0x58234c89),LL(0xce4b0872,0xa6a421ad),LL(0xcc19578f,0x5dc8848a),LL(0x4f28bdfc,0xfcb418d0), LL(0x8d6442f5,0xf2e74820),LL(0x4dcf6378,0x0c481d85),LL(0x4556438b,0x4987d1a6),LL(0x3157c6be,0x76359363), + LL(0x1c1dceef,0x29bbf3b7),LL(0x576f1dbd,0x0995c340),LL(0x8fa61304,0x0405db3d),LL(0xcc7d345e,0x63438f3d), LL(0x942120e5,0x688174dd),LL(0xcd70c93c,0xc7dd05bd),LL(0x5e871ae0,0xdc8a32dc),LL(0x6178647a,0x1a7896b9), + LL(0x59c437e3,0x1fc3f7a2),LL(0x24235e5e,0x737de2e3),LL(0x7a5eaabd,0x589a56e3),LL(0xcca140f3,0x5a79da8e), LL(0xa12463fa,0x3d8b0d82),LL(0x0875daf5,0x63fc83d8),LL(0xbd9211f7,0x42a30803),LL(0x32d3935f,0x62f6167f), + LL(0x6f269922,0x70cd6467),LL(0x96163b47,0xf694ca21),LL(0x5f5ba669,0xf3bafb2d),LL(0xb8ed8333,0xcf7cf341), LL(0x9997edc2,0x34b2022d),LL(0x309c6508,0x57e6f4b5),LL(0x64841008,0xf6fbf864),LL(0xed075d44,0xbc9821f5), + LL(0xf37cc6b7,0x78c80f73),LL(0x6ab88fc2,0x41d28626),LL(0x58ca26fc,0x2126981c),LL(0xbe3dbf87,0x7a956c64), LL(0xce0ce9f3,0x2f41e27d),LL(0xf4c98e5b,0x0cb49ae0),LL(0xcace473e,0xba6224a6),LL(0x393e092f,0x25dddbc0), + LL(0xa4fb974d,0x747daf46),LL(0xc76dbe2e,0xfb775fe7),LL(0x9670c22e,0xb7b3ad6d),LL(0x10a380bc,0xc6580b23), LL(0x92087c3d,0x4ea226f5),LL(0xb53aa3c7,0xe67c379f),LL(0x991c3c9b,0x4133f831),LL(0x4fa0dd18,0x80f9e5bd), + LL(0xc6f80fb4,0x0094e7c6),LL(0x351bebd3,0x16e99ebc),LL(0xaae16a6f,0xc555ed44),LL(0x2f6367eb,0xe9d2846f), LL(0x83d46d0f,0xb34c93d0),LL(0x894fadc6,0xc0cb137a),LL(0xab31f937,0x21e289f8),LL(0x1bc72a35,0xac5e0516), + LL(0xf3d4db0d,0x6221871b),LL(0xa039826c,0x72d1fdce),LL(0x668c8022,0x69d9cc8b),LL(0xfee064ff,0x0bf359ce), LL(0xe8d16f19,0xb8e636b7),LL(0x443160ac,0xde88f403),LL(0x032836ee,0x4228177a),LL(0xe9801d86,0xee8fac37), + LL(0x4626e343,0x496c9363),LL(0xf4e4c8fa,0xf6999578),LL(0xb8648a06,0xce7306f6),LL(0xae7996e5,0xe2775c8c), LL(0xbf09d221,0x7b47e678),LL(0x515c2ace,0xf5251e1e),LL(0x77b48b41,0x087f9121),LL(0xeb38d74b,0xc40e7725), + LL(0xce95134a,0x1d559f4a),LL(0x320c8bc6,0x1048a1bc),LL(0xe3085f1b,0xad2ddaf8),LL(0x0ad35636,0xf1cfc4cb), LL(0x57db1e96,0x2bd8d4fb),LL(0xe1976ab7,0xd1813026),LL(0x15867022,0xa80e501c),LL(0x01f68017,0xecaf1497), + LL(0x48ab68b7,0xd82c5e79),LL(0x204d2962,0xa0f117e4),LL(0x7dedbf05,0x99b3bda1),LL(0x52786ecd,0xb872dbff), LL(0x57592d3c,0x56253c32),LL(0x4d570c07,0x495fbb05),LL(0xfaecad3e,0x073c49cb),LL(0xb46bad46,0xec8c1f57), + LL(0xce3b07c7,0x13800a76),LL(0x0ffaec55,0x9bbf87d7),LL(0xaf2426c3,0xf69a9ee3),LL(0x2fd70c22,0x2d0c201f), LL(0xc42bb661,0x957e5be1),LL(0x1dc771df,0x3e6ae19d),LL(0xe3cfafa7,0x60af970d),LL(0x5ebd1883,0x721ce869), + LL(0xb87d0ede,0xab0a80a5),LL(0x2954a3e3,0x33576f02),LL(0xc413fc00,0xcc2fe8c0),LL(0xeb86a18b,0x5ae762bd), LL(0x3fe6c6dc,0xbc309dde),LL(0xbf0d1eb5,0xb4f9d001),LL(0xd4fa748c,0xf3f3c5b9),LL(0x2ca78fdd,0x78e8867f), + LL(0xcdf1624b,0x8f85f872),LL(0xa7db0248,0xfdce003b),LL(0x1ad9866b,0x0ad33ef7),LL(0x296248a4,0x27d12937), LL(0xc99c656a,0x23bf35eb),LL(0x17753ace,0xcfb64da2),LL(0x6fbf7969,0x8bc0e741),LL(0xe719cff9,0x131018ef), + LL(0xd1c02b67,0x98f4ef66),LL(0x1f81f578,0xe8aa6cdb),LL(0x159469de,0xa6f97fb3),LL(0xe3906d9e,0xf8e834cd), LL(0x71bbd3d1,0x33ccda6d),LL(0xf952c038,0xeac76a4a),LL(0xe5b53383,0x2891eaa0),LL(0xedcf6de7,0xd629dbdd), + LL(0xa3fb0fa1,0x4af093cd),LL(0x0d1ea294,0x130fd057),LL(0xb57747bf,0xb553cb13),LL(0x024e856b,0x107c0f0e), LL(0xbd631fef,0xfd63a2ff),LL(0x12c01222,0x8df62ec2),LL(0xc0af11a9,0xacbce197),LL(0x5c4922b5,0x35fa3e80), + LL(0xc3de57ba,0xbc257ccf),LL(0x293ad2df,0xb481ca1c),LL(0x2058e222,0xb123f3bb),LL(0xefe46989,0x219cde82), LL(0xe9a316da,0x58ac87b8),LL(0xd4d25c91,0xa8294237),LL(0x62d14158,0xb54dad88),LL(0xb3da2a84,0x9250885f), + LL(0xd54776bd,0xb4e3bedf),LL(0x78043ee5,0x81a4c582),LL(0x4eb87133,0x279a0963),LL(0xf2bfdb52,0x827d333c), LL(0xed71e119,0x3601c6d1),LL(0x0d64df1d,0x3d9b1772),LL(0x3fa3c40e,0x2f5bcc09),LL(0x8e26aef5,0x74b7b30d), + LL(0x3d3ac848,0x98fd949b),LL(0x92e259f1,0xd99e99d0),LL(0x8d353c77,0x34404265),LL(0x4d8dfb1f,0xffc05a7d), LL(0x4e9d92c9,0xbaf2f471),LL(0x5ea9cef3,0xf354f8b2),LL(0xb8b2c8a0,0xf2be0fea),LL(0xfbce308f,0xa392d3e3), + LL(0x02619258,0x58cd793d),LL(0xfea6eacc,0x16a8c9e7),LL(0xb90f9cb5,0x3fcae1ed),LL(0xd59bc4ce,0x1df76d07), LL(0x8574a3ce,0x39248217),LL(0x03b6e82e,0x9d0df2b7),LL(0x33206733,0x64227c0f),LL(0xb342da7d,0xb909614f), + LL(0xb8e15a20,0xe46e977f),LL(0x744eaa18,0xdf2aa89d),LL(0x7ff12f89,0xa40b36b7),LL(0x86b0e7d4,0xbf7ed788), LL(0x9e044a5b,0x35930c5c),LL(0x4ac6b8a0,0x599cfa2b),LL(0xa8f06839,0x68f5f40d),LL(0xe8a1b9d5,0xe838649b), + LL(0xdd45feda,0x2e3c91a9),LL(0x58de0625,0x5f73aa38),LL(0x7535cddc,0xcc2b2397),LL(0xca7825fa,0x60e69d0b), LL(0x62424bd7,0x8f1a95c4),LL(0xf6f21e23,0x5e175a13),LL(0x4fa48b20,0x594e5b82),LL(0x9b14fed3,0x2bfed204), + LL(0x74484bc3,0x87c925fc),LL(0x5639abc5,0x052b634f),LL(0x290426dc,0x169549b6),LL(0xdaaefd38,0xfe515a22), LL(0xb4d87ccb,0x8a63a39c),LL(0x4034acdc,0x3dec5f62),LL(0x61090db0,0x59969d81),LL(0xf157248d,0xb089b8f7), + LL(0x9d59a29f,0x42b0ca54),LL(0x9be7ee82,0x522b3e3e),LL(0xac166a7e,0x894aade2),LL(0x9184ec33,0x57aaf19a), LL(0x5e50711a,0x84406a11),LL(0x1614f8d3,0x0cafd148),LL(0x3f7d19f8,0xc6174fdc),LL(0xff4958be,0xca5bed9a), + LL(0xe4fdd396,0x8dc18aaa),LL(0xd371c3f4,0xf6e8a9ee),LL(0xa5dfefde,0xc6b58042),LL(0xfc4f3577,0xccc3bbb6), LL(0xdedfdd55,0x9f583e4a),LL(0xb48c5fb2,0x9ea45133),LL(0x232d61e0,0xca2b3229),LL(0xb0b5cb38,0x642101a8), + LL(0xa9ebda1a,0x0cfac5fc),LL(0xd2dc9c7c,0x02398bd6),LL(0x80591234,0xd95511d9),LL(0xe8230901,0x0e5cc99c), LL(0x140eaba1,0x943350f6),LL(0xe0623c93,0x9fe19108),LL(0xd74e189b,0x052bf5d9),LL(0x40cd7173,0x3e341bff), + LL(0xcb7d384d,0x89b5b355),LL(0x50b76f18,0xedee32da),LL(0x5804d9df,0x6a9cfb19),LL(0x376fc2d8,0xccf638f8), LL(0xe14de014,0xebdce7a5),LL(0x7f606fa5,0x0135085f),LL(0x69b58c3b,0xf8a3de5f),LL(0x59ca19d1,0xbaa80445), + LL(0x0ce7238d,0x3252147d),LL(0xd57bc36f,0xd446960b),LL(0xb275f5ca,0x9b1743ce),LL(0x27629de8,0xda048c48), LL(0xd3bbac67,0x005354db),LL(0x1ba1facc,0x62c392fb),LL(0xa18da892,0xb066bfae),LL(0x367a8320,0xdb090711), + LL(0x6f90249a,0xbb7092e2),LL(0xe22da86b,0x6de14155),LL(0xb38d4ad8,0xe16136d3),LL(0xd0fbb940,0x9deaa5c9), LL(0xaacf50e3,0x54a54ba3),LL(0xb9ba4570,0x66e5645a),LL(0x48cb742a,0x77e28d94),LL(0xed98a2c9,0xc795b138), + LL(0x1daa17ee,0x899331f6),LL(0x4a77734f,0xac950653),LL(0x71f3e3b6,0xd7f6304f),LL(0x65fc119c,0xe7256955), LL(0xbe527794,0x3e60a04c),LL(0x7c578fb0,0xdaf53be4),LL(0xebc0754b,0xf785a4f8),LL(0xde1b78b4,0x8b21b116), + LL(0x62fb1c56,0xfe47e04f),LL(0x229f1017,0x8a92f9e6),LL(0x68b7842c,0x2d73dd23),LL(0xa56dbc4f,0x3b43f7dc), LL(0xd0f3f4ca,0x9435defe),LL(0x500594e3,0xdabfb1ba),LL(0x428f5ead,0x70e929e8),LL(0xbdc7716e,0x44adf585), + LL(0x02204867,0x7b7ff077),LL(0x0c78476c,0xf2f306be),LL(0x7e783793,0x48849fd5),LL(0xaf77e3c7,0xc2dc3c7d), LL(0xa980cdf6,0x5eb2b691),LL(0x204e25df,0x7ca7b7a4),LL(0xc5070eab,0x1e7c2f82),LL(0x4eb7cd3b,0x32ca4b36), + LL(0xf94ad1ab,0x38ffde8f),LL(0x59921b25,0xb4757ae1),LL(0xb4d2f624,0x856cd3f3),LL(0x1eb40708,0x90593929), LL(0x1193b3e4,0xffc4b89a),LL(0xbd2f804f,0x6afba7a8),LL(0x69dc21ed,0x72aabbaa),LL(0xe7fb6de1,0x5d1da32e), + LL(0x98d1e26b,0x56c0f440),LL(0xf7cc7d6c,0x9456a6c3),LL(0x14f2f24d,0x9eb0aebb),LL(0x7dd788a5,0x51d7c699), LL(0x46a22e97,0x053b8098),LL(0x8c025be8,0x27d8ea2a),LL(0x10d5afaa,0xe0bd464a),LL(0xe7cf120c,0x137c452d), + LL(0xd091397b,0xd06bd227),LL(0x21bc796f,0x4b307bf3),LL(0x7f5a37b0,0x701eaf3a),LL(0xac7d4718,0x8d5a0f61), LL(0xed8b1a37,0x0cf9eea3),LL(0x2aa9061c,0x10854f10),LL(0xa30eb4e6,0x0aaf430c),LL(0x2a050dfb,0xb74342f5), + LL(0x20e1899f,0x2feee9d7),LL(0xf2a1dbfc,0x49464a8e),LL(0x5762d68e,0x4d7cf25e),LL(0x7bf43462,0xe7b6e759), LL(0x79daf6e0,0x71fce284),LL(0x03858705,0x2d3ff71f),LL(0xbc4af4e6,0x07d8d288),LL(0x18f1c7d4,0x6777d197), + LL(0x0e85f036,0xb5770041),LL(0x4c8d9768,0xe1bb263e),LL(0xe3917798,0x4fcc1d44),LL(0x07abcde4,0x274d1d90), LL(0xb7a10472,0xc9b8ae9f),LL(0x8d10e8ec,0x6632e3be),LL(0x50f3a172,0xb6876fb0),LL(0xb4cf4867,0x753692d4), + LL(0x58e598f7,0xfe3624e6),LL(0x6d81fb40,0x15f90418),LL(0x9bea3649,0xae762f7b),LL(0x161e85cb,0xc48d2262), LL(0xcf5a21f0,0x8e8726a1),LL(0xa1f6653b,0x536c441f),LL(0x67ec5b86,0x0716bad0),LL(0xb2147d1f,0xa423a957), + LL(0xdca2e393,0x8eec96c8),LL(0x2843ef12,0x3619e36d),LL(0x2ef695e1,0xdc16fe2d),LL(0xffea8124,0x04ed2cad), LL(0x180ce636,0x5018a0ce),LL(0xdce7b2f8,0xc34b0bbf),LL(0x0c54fc30,0x645a02a9),LL(0xf3f819d9,0x6ee6772b), + LL(0x7cecded6,0xe2bbbdcd),LL(0x3f038851,0x9ae4fd55),LL(0xa2f316c7,0xc30664ab),LL(0x63ffb50a,0x3cccf4a1), LL(0xd00fb8f2,0xc37ee6ca),LL(0xad906eb1,0x593db6d5),LL(0x4aa84505,0x8f75b594),LL(0x9e5939f0,0xeff39d82), + LL(0xc064f530,0x4b7fab3c),LL(0xde175892,0x731153ae),LL(0x3d4c4e60,0x335e6503),LL(0x776ce13a,0xb0876a8a), LL(0x22241ecd,0xa8a566ee),LL(0x011e861c,0xb7456b3e),LL(0x177dd490,0xa9aff4eb),LL(0xc8f77c40,0x189b1ed9), +}, +/* digit=13 base_pwr=2^91 */ +{ + LL(0x2857a1fc,0x624de687),LL(0x2ff8f505,0xbd0a0d9c),LL(0xc381bc9a,0xeecb4fad),LL(0xfa94e41b,0x72386292), LL(0xe75fc753,0x354d3f83),LL(0xa7a5a6bf,0x06afc753),LL(0xb2f568dc,0x1ce792ee),LL(0xbd2f9647,0xc5faaee3), + LL(0xf912b74f,0x175fbeb0),LL(0x6e0ceedd,0x45fbe8e1),LL(0xd9233ee7,0xf0e1aa68),LL(0x406a626e,0xe55fc1ce), LL(0xe08712e7,0x20efa1b9),LL(0xbcfd6360,0x5fd108b5),LL(0xeec1edac,0xea431df6),LL(0x940803f1,0xae1c0521), + LL(0x15407ffe,0x584a16d0),LL(0x08a82a69,0xa977f702),LL(0x67f8a198,0x52eefecf),LL(0x19f7a7e0,0xec213738), LL(0x35987b9a,0x6795cfef),LL(0x97028480,0xb243403b),LL(0x9c1b9124,0xac24b12b),LL(0xa90f8aeb,0x1f379501), + LL(0x64bc0f09,0xa8e97fb6),LL(0xc953cd08,0x0b913991),LL(0x7fc3bf00,0x8385a1b3),LL(0xb09ccd8f,0xb6e74dec), LL(0xec473ea7,0x6e1df026),LL(0x530766bd,0xf2f7fbbe),LL(0x3292052b,0xf18cb47a),LL(0x9114866a,0x7f8d4592), + LL(0x8bfa2c22,0xf0a1c565),LL(0x2b326c0e,0xc28518c3),LL(0xec107d66,0xabafc6f0),LL(0x8478907a,0xbc7a6abf), LL(0xa2920288,0x8c1c8f6a),LL(0x930c043e,0x6c87579d),LL(0xb309696d,0x25ee808d),LL(0xb7a71041,0x433bbbda), + LL(0xb3086691,0x48d6d957),LL(0x26640916,0x9946a29b),LL(0x43db59a9,0x932ca93c),LL(0xe4fe91ba,0xaa61a0c5), LL(0x815bf003,0x9e22e112),LL(0xc86ba8d3,0xa9ed1b18),LL(0x1069f434,0x1b5d3c14),LL(0x1cc01754,0x3cd2ebd0), + LL(0x3350f670,0x5c06b244),LL(0xf6f9c751,0x7557dc9d),LL(0xde66fd97,0xa7ebd3b8),LL(0x2befe6fe,0xc126dbaa), LL(0x396f434a,0x312f4897),LL(0x61a4124d,0xe05cfcd6),LL(0x1525c05e,0xc83b8688),LL(0x11899f64,0x4646dbf2), + LL(0x8e419e08,0x2b7507cb),LL(0xaf855eec,0x785328d7),LL(0x7b8683a5,0x875db0c7),LL(0x90a597e9,0x3d1bc968), LL(0x47eeeab4,0x7d4afa10),LL(0xd680ca71,0x2668dd43),LL(0x17365023,0xc3210d1f),LL(0x17fb31cc,0xd5bb2ee4), + LL(0x08e9ba09,0xbefb6a4f),LL(0xb0c1b6e1,0xc6beedb8),LL(0x3510ef35,0x59daf057),LL(0xdbbabc65,0x604047cf), LL(0xa06b7340,0xfabc80a8),LL(0xdf765977,0x7433dee7),LL(0xfd807cfb,0x149a2c4a),LL(0x3480a086,0x14e8ad3b), + LL(0xb22c5f89,0xb0c3156f),LL(0xbf78675a,0xd10ece4a),LL(0x80b8ad9f,0xe270e317),LL(0xb0c2b420,0xfe7a6210), LL(0x125ef635,0xf091d738),LL(0xc1a6f202,0xf1f277d6),LL(0x3587d9bb,0xe2727e7b),LL(0xb3e2b84b,0x83b209a9), + LL(0x7a13effa,0xc9eb445d),LL(0x0d697480,0x89b856f1),LL(0x25c03cb7,0x834bbae2),LL(0xe0b4a7b2,0x0d8adb85), LL(0xc7fbc240,0x7b6884af),LL(0xaa4f9097,0x6b485409),LL(0x290c106f,0x4d0a367f),LL(0x3f0efdfd,0xab87d218), + LL(0x50f2b65b,0x15b9bab7),LL(0x5e5d53e4,0xa7403d4b),LL(0x28529212,0x2e23e376),LL(0x6e050767,0x6fe903a2), LL(0x6cf570fb,0x4c5291a1),LL(0x7a30b326,0x4bfb8607),LL(0x27c572a9,0xec4905f8),LL(0x0f381c31,0x72eeb8c9), + LL(0x460adca0,0x33346cec),LL(0x7b34756a,0xd4d5bba8),LL(0xeac84add,0x02b2e2d4),LL(0xdc1053b5,0xa129845b), LL(0xdca6f9ce,0x53f067e0),LL(0x3526aba6,0x6e9998ed),LL(0x1c0982da,0xa4aef9e2),LL(0x93f5d96f,0xfe5b606e), + LL(0x9c14b699,0x26b8502e),LL(0x0948a291,0xf1bcdca6),LL(0x2aefd415,0x73e43a32),LL(0xd1e2cfb5,0x7f523357), LL(0x97d3fa94,0xa60151c0),LL(0x72129630,0x820c0d58),LL(0x5854acf5,0xb8f2e1ed),LL(0x3c656ac3,0x86d6646c), + LL(0xbef1d0da,0x2284a612),LL(0xa8c8faba,0x2e7c5f4e),LL(0x70303ea3,0xfd441ae7),LL(0x5161cf82,0x9613f329), LL(0x2e19531f,0x65a3cc65),LL(0x34281f69,0x177a2775),LL(0x7c82e094,0x0cc692a4),LL(0xb6f377f0,0x9d62a55b), + LL(0xf96ec2b8,0xa24cf6ac),LL(0xa961cc16,0xd06747c3),LL(0xbd17f0a2,0x57c7001c),LL(0x34afe2d6,0x5f298db0), LL(0xdf12f671,0x51b01ef2),LL(0x5ce712fe,0xc01c5066),LL(0x92a74776,0xac0f4034),LL(0x08d696bd,0xa3e9934f), + LL(0xe7daaff8,0xafb6981a),LL(0x73bdcafc,0x5f8998d9),LL(0xbaf9906c,0x23ec39e1),LL(0xc999c9c0,0x5e248410), LL(0x17dad895,0xd14c7a89),LL(0xcbb3f6b9,0xfde9d01a),LL(0x5f698f1b,0x1d6b26ef),LL(0xf0baff97,0xc6495cd1), + LL(0x587674ec,0x5a72dc07),LL(0xdb09cd65,0x100f9ff0),LL(0xb30cf6e6,0xec0fb71f),LL(0x81066143,0xf54cb597), LL(0x633857c4,0x0090e997),LL(0xda92c5d2,0x7326ed15),LL(0x47c56e86,0x794cd8af),LL(0xf89214c9,0xb272112f), + LL(0x3445879d,0x37960861),LL(0xf2fcfc55,0xc5e496b0),LL(0x6559e153,0xfe74e95f),LL(0x54a772af,0x1e18b2b5), LL(0x157c157c,0xd146980c),LL(0xa11d77b5,0x31ee3f25),LL(0x5707db6d,0x7762a07d),LL(0xbd2022b8,0x00804bcb), + LL(0xd571c59e,0xdf3f4658),LL(0xcf45c1ee,0xc49e7a34),LL(0x43972cff,0xf401ba3d),LL(0xe509c2b6,0x146d989c), LL(0xeb72392f,0x7c68d6c8),LL(0x0658b8e6,0xdd048de5),LL(0x9a0aeb72,0xc9dc61b7),LL(0xb741d644,0x98b080e0), + LL(0xb1c5982a,0xa6ec0eed),LL(0x5ebbc26f,0x58d28317),LL(0x33e5b7dc,0xac8f1e1e),LL(0x9d8f9fed,0x31e4f65e), LL(0x904ad76d,0x6c9af383),LL(0x9bdb0517,0xfc38c53c),LL(0x0e69f85e,0x9ae278ee),LL(0xefd9d887,0x18b362b7), + LL(0x5bbbd3ac,0x65a5f74b),LL(0x077bfb4f,0x41eb4593),LL(0x83b38100,0xb642934b),LL(0xac1a99bb,0x643ceed7), LL(0xee7cd5f7,0x9c27e66d),LL(0x6ddbaa6b,0x2ccf87d5),LL(0x447b1192,0xd51ca739),LL(0x95f5f142,0x78471053), + LL(0x3a650829,0x915f50cd),LL(0x898a6a1c,0xe032bdc5),LL(0x2d15959f,0xde8fb4f1),LL(0xbad56140,0x1fc5fc73), LL(0x8e60c3c3,0xdafbf206),LL(0xe428adb5,0x4963dc95),LL(0xd49584fb,0x1538e081),LL(0xbc0e5fa9,0xb34add66), + LL(0xa7f28b2f,0x404ecf12),LL(0x7fa9c435,0x6ddc3ce1),LL(0x61ee755e,0xda887e3f),LL(0x8f71280a,0x4b5da661), LL(0xdc79a4cd,0xee5a86df),LL(0x99be4d36,0xd8514b8a),LL(0xcc82c751,0x674793ea),LL(0x437aedcd,0xf3a2123a), + LL(0xfcd6f027,0xf825ff37),LL(0xa681a001,0x60a056d8),LL(0xaa92c135,0x92a39248),LL(0xdcd190a7,0x61884e23), LL(0x24cc911c,0xec0d1420),LL(0x5aa16ad7,0xbdb0baae),LL(0x8a1694d7,0xf12726b5),LL(0xc93673f9,0x8c7cf113), + LL(0x7f2edc38,0x02fb6c69),LL(0x2fbe8690,0xcc4d4304),LL(0xe89c80d5,0x405b2491),LL(0x3d938bc1,0xdef46c76), LL(0x2520e3b0,0xd92ec0fa),LL(0x1fe2dfda,0x2501cfa3),LL(0x1d5c8474,0xe7c5753d),LL(0xe6226dcf,0xc059abc0), + LL(0x55a9011d,0x2dceefe6),LL(0xbbbbef00,0x8799064a),LL(0x0b49b5ef,0x7fe944c2),LL(0x225b21dc,0x722bbef0), LL(0xd2bb14af,0x84687cbb),LL(0x9b6f6caf,0xfc4ab4f0),LL(0x2c146a52,0xb7b7bb59),LL(0x1dfea10b,0xb90d67f2), + LL(0x713e1d30,0xca4ca8c8),LL(0xf8a13db8,0x50cbb994),LL(0xa5b0e3e5,0x2bee12b2),LL(0xe71e19fb,0xa7c5d6d1), LL(0x9e0314cd,0x28442423),LL(0x66cda5c0,0xc95c2746),LL(0x1c5ffd19,0xfe52a79a),LL(0x38a0339f,0xb93875cc), + LL(0xb49fb049,0x6a94196c),LL(0xcc12a38d,0xbeb1eb4b),LL(0xf5e8d167,0xbc136771),LL(0xd5f8ae87,0xa91e1232), LL(0x95172460,0xb2e812c7),LL(0xb8f81870,0xc699d376),LL(0xa8900827,0x9e4a3b70),LL(0x506c0b29,0xe0d4b2f4), + LL(0x7246fd96,0x13b4d1c7),LL(0x33965581,0x84ea2158),LL(0x2e53c024,0x9b9f071b),LL(0x864a1b78,0xcb005908), LL(0x3f742c2f,0x03daddf5),LL(0xdf595911,0xd29230e5),LL(0xca0406a1,0x3f7d4e6b),LL(0xb1db7e47,0xeb646f66), + LL(0x590e3107,0xb896003e),LL(0xf754ac01,0x7a0dc361),LL(0xe63ab0ac,0xe877a6f3),LL(0xdf60d307,0xd43b54f3), LL(0x59cf0add,0x65ef91ba),LL(0x18990eb4,0x35e99393),LL(0x8e46fbf6,0xc186ab16),LL(0x8c1eaa91,0x4c0eb22f), + LL(0x1abd31f0,0x4599b894),LL(0x9a1da7d3,0xdb34198d),LL(0xa0f0217d,0xa8b89523),LL(0xe56b884e,0x2014cc43), LL(0x49efd4ee,0x6fb94f88),LL(0x287f4ae0,0xf1b81710),LL(0x99fd2deb,0x89d38a9a),LL(0x72b67a53,0x8179277a), + LL(0x1a03755b,0x0ef6ce56),LL(0xfcdb3469,0x8dc768f2),LL(0xa21d959d,0x0be58a91),LL(0x9b103cd0,0xea44861a), LL(0x808b8a46,0x332e86e7),LL(0x8772c3f8,0x9882015c),LL(0x9f4b5d29,0xe6b272fe),LL(0xa29b023b,0x0e183a28), + LL(0x2286ebf3,0xf2fab88f),LL(0xfce83e6f,0xb7532ced),LL(0xe0cde4fc,0x17999d7c),LL(0xc1b7668a,0x7230fd85), LL(0xef588309,0x97a57d39),LL(0xf906f6e7,0x7e175f28),LL(0x72b70bfe,0x51f67413),LL(0x2f82218c,0x2132f595), + LL(0x9d8727cb,0x9cc0746e),LL(0xbba1ec8e,0xa2af77fb),LL(0x31a67cc9,0xc75aee60),LL(0x57408325,0xaeab9e0f), LL(0xec34bb89,0xf24de697),LL(0x5d958bdf,0x06b90039),LL(0x0603d6cc,0x6f55222e),LL(0x2eb0b239,0x496537b5), + LL(0x8be08323,0x083e5889),LL(0xf8dc0a78,0xc573596e),LL(0xe8901eca,0xc3e988fa),LL(0x6e350257,0x7f7b48f6), LL(0xa216e329,0xed820567),LL(0x8ce989c1,0x55f46737),LL(0xeeab9441,0x7f48c5f1),LL(0x86fe0831,0x1d3cac11), + LL(0x408a0306,0xe0364bae),LL(0x7a4eb2cb,0xe8d8aba0),LL(0x1fd7d5da,0xe548725e),LL(0xed5ed958,0x8de04491), LL(0x61d73977,0x3e75eba2),LL(0x55420386,0x4f580400),LL(0xd859a690,0x54642fa4),LL(0x296e336e,0x2c905f7e), + LL(0x22e260bc,0x4e287e66),LL(0x4a28d5bd,0x71a2ec99),LL(0xa7c5c3e3,0x5528da21),LL(0xa49471e0,0xae9f6856), LL(0x587cd94f,0xdcd8e66b),LL(0x6c7b7db8,0x91afbd79),LL(0x067e3cdd,0xdf2e6625),LL(0xa6375f59,0x15b5a329), + LL(0xb6586c5f,0x3b8b3b1d),LL(0xd34f10fb,0xe4d50a77),LL(0x7c3c01f7,0x26cb86f5),LL(0x8c57e6f7,0x36e9d3cc), LL(0x62c6dbae,0xaa8e7ce1),LL(0x60d7fae5,0x7f6b7689),LL(0xc797ee16,0x519a7659),LL(0xb36a6b1b,0xa1c7b30e), + LL(0x74dff201,0x8da05ba6),LL(0x40d0a835,0xd2eac07f),LL(0x610a7d6f,0x2701eb31),LL(0xbf893c4f,0x5c17a91e), LL(0x6bc8b161,0x68b92e88),LL(0xf52e6ec0,0xa312fd5b),LL(0x6b7952cf,0xf7daf460),LL(0x18aeb57a,0x847f0cf3), + LL(0xb0146708,0x27b178ed),LL(0x54ca2aa5,0x85a23554),LL(0x395a7b16,0x80dd123c),LL(0x0058bfce,0x64a9337b), LL(0xf4addc4a,0xf6ae9380),LL(0x464536f1,0x0f84385a),LL(0x16534f6c,0x41fc2270),LL(0xb8795ec3,0x13d8976f), + LL(0x8e12c560,0x2e90b3e4),LL(0x239b2c58,0x242a86ec),LL(0x0768275c,0x6fb42ecc),LL(0xbd96de9e,0xee341cd0), LL(0x84355d11,0xfd1833ac),LL(0x5f55ec6c,0xf062392c),LL(0xfee33fba,0x6ee7b59b),LL(0xabf86e0f,0x8113f0ca), + LL(0xcc68033c,0x2285aaaf),LL(0x78430646,0x850b732b),LL(0x2b3fa03d,0x50fa4b61),LL(0x3caf050d,0x4d893ecc), LL(0x988df419,0x454764e6),LL(0xfb61f1a4,0x055d8a4b),LL(0x8475e07a,0x3b7c5f4b),LL(0xa6a228e4,0xf93a198b), + LL(0xec8d566a,0xe0a8ce61),LL(0xc55f4bd6,0xe41397d6),LL(0x654bdf55,0x4cc18d48),LL(0x9325ac25,0xe1b49f9e), LL(0x72c68871,0x79840752),LL(0x6d806fe8,0x8930d8b5),LL(0x0bd5f65e,0x11c8b5a8),LL(0xbf37d7a8,0xe931c025), + LL(0xae8af083,0x25b17fd9),LL(0xde4215ed,0xd589fd8b),LL(0x4b3f61fd,0x56378f04),LL(0x6bfb4f9a,0xf0f39213), LL(0xe906cc6a,0x6b0f9596),LL(0x096f8296,0x441f13da),LL(0x1e4940e0,0x08f933d4),LL(0x5a53e7ee,0x6c35391c), + LL(0x19c3d18e,0x5f41c4d3),LL(0x1d389d95,0xc0804e09),LL(0x18a5a3f2,0x7323a9ab),LL(0x410a6381,0x7b7c2475), LL(0xb02cfe18,0xd362eb9a),LL(0x553b2970,0x79ef3d0a),LL(0x3d2acdab,0x371f7760),LL(0x7f241dfd,0x6cd37890), + LL(0xdf4a28e4,0x592a242e),LL(0x1bb45217,0x1e623cdc),LL(0x494074d3,0x5a9633a6),LL(0xd52fbfd8,0x81b74307), LL(0xdec4c5ff,0x98292651),LL(0x3e0f6edf,0xe1b7bc86),LL(0x6bb8fb31,0x3d5fd86a),LL(0x1cf29f19,0xa830e9a2), + LL(0xcf69c747,0xfffc5482),LL(0xa83549fd,0x7748a0f4),LL(0xe7ccf4a6,0xba1c8a0d),LL(0xa2ede6b7,0x6cd1399a), LL(0x87bb90d9,0x8fb634e6),LL(0xc59a5304,0xfa8e659b),LL(0xa9122d95,0xcd6bfc75),LL(0xdfa6d75a,0xdb107def), + LL(0xcc27760a,0xb0ec4cfc),LL(0xbed3a1a1,0xf24c1e22),LL(0x819bffc7,0x4f8522a1),LL(0xa93d97e1,0x263c7b5b), LL(0xa4b4de49,0xab1d31e0),LL(0xebbfe8f5,0x374e968b),LL(0x51ca0d08,0xe82e9756),LL(0x7df3f2df,0xc05715a2), + LL(0x038004ad,0x941f02c5),LL(0xa0fd46d4,0xc136a2a5),LL(0x3d31d26c,0x85db7d24),LL(0xbfefeecc,0x05bba6af), LL(0x5a60aebf,0xf803b539),LL(0x813d0e6d,0x9bb8a479),LL(0x066abdfb,0xb689c813),LL(0x0072e530,0xd93b3f4b), + LL(0x987446ad,0x242140a4),LL(0x06a02f0c,0x40b3f709),LL(0xa0fd6018,0x33f9bf20),LL(0xf21abfdc,0x58517c18), LL(0xc1f80f3f,0xa33dc5db),LL(0x7ec91c80,0xbb7dfe27),LL(0x8ca97dd8,0xd2cf9338),LL(0x32e43d44,0x5761f871), + LL(0xe513ea90,0x3c8ffb0e),LL(0x79bcdecc,0x91ecda36),LL(0x9b1a5514,0xdad3fdd5),LL(0x640d3af0,0x8fb630f9), LL(0xf9d2e0be,0x82949b09),LL(0xeba23663,0x079ca0ff),LL(0x135238d4,0x51e62c53),LL(0xc446bd67,0xf5fa0c61), + LL(0xe8da43d6,0x19dcdd2f),LL(0x95f29b5b,0x46fbf7ea),LL(0x635e8388,0x7f3eaa05),LL(0x5369750b,0x5ef817c3), LL(0xc860c4aa,0x06025893),LL(0x5551c9ef,0xa2f6684d),LL(0xfbc0c667,0xd6af67dc),LL(0xcd2fe44b,0xfd8d7394), + LL(0x302a17cc,0x011968ae),LL(0xc3e5a5cb,0x2206ff24),LL(0xa20dbfb7,0x4c7f0df3),LL(0xa395dd6f,0x59566376), LL(0x373ea76b,0x68ff3d9f),LL(0xf6cf8ada,0x2394f93a),LL(0xe7514a94,0x3acc5dba),LL(0x5ddfa11b,0x0340da7a), + LL(0x1a05155d,0xc3f03022),LL(0x4f7656c0,0x6cbbdc6b),LL(0x0b0875f5,0x6e30dbdd),LL(0x3471b0d5,0x5e7c2883), LL(0x408b4bc8,0x49cfd71c),LL(0xf01c002b,0xd29a184e),LL(0xff415b0f,0x308be85c),LL(0x01a8fe7d,0x1b4176f0), + LL(0x0c33bed3,0xb850acc7),LL(0x23af7af0,0x76aac640),LL(0x21d5853f,0x049187ee),LL(0x6620195c,0x44fbf6e5), LL(0x36158178,0xf0abf14b),LL(0x90e419c2,0x9866ffca),LL(0x9e8523a8,0x7522e277),LL(0x08e90f1d,0x2f2590f3), + LL(0x66d3f75b,0xde1c0c52),LL(0x6c299b57,0x47dc9ceb),LL(0x51f7f2b5,0x4ad12847),LL(0x452b07a5,0xeedf9d8d), LL(0x3dad76c6,0x207b0627),LL(0x5d4c0280,0xccbb5201),LL(0xb019ae8d,0x0bdca05b),LL(0xf2da7eb4,0xb5f8d088), + LL(0x4626c00c,0x4e79a0be),LL(0x5af82c0f,0xf6fdd64f),LL(0x5f7cba0f,0x7a828224),LL(0xb0765493,0xc2214834), LL(0xabd53ccf,0x5b0d0d1a),LL(0xf4a1b517,0x3b03a22d),LL(0x6ece453e,0xb235c862),LL(0xf66471c7,0xf43ac344), + LL(0xa1552fa5,0xeaff93dd),LL(0xcf3ae702,0xef1b40dc),LL(0x9ca613a4,0x35ced3fd),LL(0xa2f33a0d,0x90e350ab), LL(0x002b5738,0x47bb89aa),LL(0x032b8b08,0xafc01bba),LL(0x61588b4b,0x688ae119),LL(0xcf66ef14,0xdb7d820a), + LL(0x084910bf,0x83b654db),LL(0x60ea75a1,0xbb581f8b),LL(0x1cdae7c4,0x6917f282),LL(0xa40a07c3,0xb719f931), LL(0x31297b3b,0xf8efb8b9),LL(0x4d6fc5c6,0x74246ded),LL(0xd2c61503,0x5a111754),LL(0x71654764,0xf64d2b88), + LL(0x6ad8f168,0x4b452692),LL(0x0cc6fc91,0x907beb21),LL(0xbf13c18b,0xe876d523),LL(0x4cf37ca1,0x4d28e457), LL(0x6d3d1172,0x4c0dc22d),LL(0x5a753137,0x7935a8d2),LL(0xda44d652,0x03484e3d),LL(0xc50025a9,0x05a3d80f), + LL(0xff477c6d,0x6d43c503),LL(0x1ccd416a,0x35f4c4cf),LL(0xd5088349,0x7070f471),LL(0x281d30c8,0x678460ca), LL(0xc6defb33,0x8923cd9a),LL(0xe2557cab,0x44930f56),LL(0xad156c4a,0x33b020bb),LL(0xbcaf4805,0xfdab31e3), + LL(0x864b5564,0xffe79bec),LL(0x10c60d52,0x0510e352),LL(0x328a652e,0x66203aaf),LL(0x54fea042,0x9d5403bf), LL(0x6e5e5c7c,0xb3fe6743),LL(0xecc66e02,0x6deef667),LL(0x44eacacb,0x199ee152),LL(0xd8803fd9,0x9f49fcd4), + LL(0x2d3a6e28,0xdd5fee9e),LL(0x686d8ca3,0x8eed56d4),LL(0x78083491,0x36889a27),LL(0xbef20457,0xea1a6555), LL(0xa501e2a3,0xe7e6b609),LL(0xfb23de2f,0x1ea0ae29),LL(0x632c9a6b,0x5f537d07),LL(0x9a3db961,0x61770d1f), +}, +/* digit=14 base_pwr=2^98 */ +{ + LL(0x7497e8a5,0x325c60db),LL(0x8c6949a9,0x05d8eab8),LL(0xc7bd5898,0x3169e466),LL(0x192d8e3f,0xadc06264), LL(0xd55959fe,0x1ff468f4),LL(0x202dba19,0x97b33ee0),LL(0x21cf84bb,0xaa0c3fe2),LL(0x04a8d176,0x48cdc0af), + LL(0x9c0d4009,0x53d8c448),LL(0x2e24dbaa,0xd3714617),LL(0x9b62e5f1,0xdd92e730),LL(0x9922cc8a,0x97b344d7), LL(0x0bfe3e8f,0x416b009b),LL(0xf3c82269,0x56873834),LL(0xe6623555,0xf82a980f),LL(0x5ce68e54,0xb027ecaa), + LL(0xfe87680d,0x005a4b24),LL(0x4cf6ee32,0xd92532dc),LL(0x4bd3e01f,0xfcd27c8c),LL(0xe1b59ffa,0xda7d9949), LL(0x2735d373,0xe3d5f31f),LL(0x288e71fb,0x7e139ca5),LL(0x93979cb4,0xe474bc80),LL(0xf6fcc665,0x7f4f6017), + LL(0xfbd613c3,0xe6982c86),LL(0xc366f17a,0xf4af69d5),LL(0xb85c2343,0x8683eed6),LL(0x24bc2116,0xf5bb244a), LL(0xc9fc77d4,0x997a74bc),LL(0x6f44b54b,0xe202eb91),LL(0xa6997e76,0x77886412),LL(0x02c8837e,0x6996c8fb), + LL(0x2c61382c,0x0986df8a),LL(0x667c8ee9,0x90607b92),LL(0x084eacde,0x051fcbf7),LL(0x6e685877,0x84e3dba4), LL(0xe458da50,0x35861a82),LL(0xcf392b51,0xd036823f),LL(0x3dd86e74,0x43181481),LL(0x3741a385,0x8dcfe17d), + LL(0x40f56786,0x8e1a77cf),LL(0x6d4b7774,0xc5bca7f6),LL(0xc81ec077,0x86b588a0),LL(0x9206354f,0x88952a01), LL(0x43a8519a,0x5444a989),LL(0x2857b210,0xe29dd68c),LL(0x9a144624,0x36658903),LL(0xe423e899,0x8c4dedb0), + LL(0xea886e5c,0x482040c5),LL(0x1cdd50f7,0x42fe5a56),LL(0x453b6e7f,0xf034f132),LL(0xb3c69762,0xba3fa97d), LL(0xcadb598e,0x34262560),LL(0x07afe0a8,0x7ed74b51),LL(0xebe0e8bb,0x2261d849),LL(0x608cea1c,0x23747e55), + LL(0x902c343d,0xb2e9371c),LL(0xda4fdba1,0xf57b2de8),LL(0xb67703a1,0x43f9afa4),LL(0xf79fe203,0xeafafb41), LL(0xf649a494,0xfec99dc9),LL(0xfe378232,0x14799ef9),LL(0x7184e31e,0xba3f8114),LL(0xdc0e987f,0x0abbb815), + LL(0x6fb5d02c,0x1dc7221f),LL(0x40f1607c,0xa0dfb113),LL(0xdbe8db86,0xd217f238),LL(0xe91f2859,0xc02547eb), LL(0xa98d0875,0x41df6bcb),LL(0x78f6be54,0xf51a8077),LL(0xba66bef5,0x3ebdf28d),LL(0x9175ec20,0xc65c7b38), + LL(0x475589d5,0x2302981d),LL(0x199d8ad4,0xbd479708),LL(0x8db46795,0xcb508be9),LL(0x6b224eb4,0xba1e066e), LL(0x1326ab8a,0xae909633),LL(0xf5bbe5e6,0xac989728),LL(0xb1729b41,0x1de663f5),LL(0x00c3d293,0x2018f58c), + LL(0x71efe25b,0xe647c0e6),LL(0x6104ebd6,0xaa30f871),LL(0x3c166de6,0x1003eebe),LL(0x1cbc42d3,0x0c308538), LL(0x56cba120,0x98b6c312),LL(0x860d2916,0x9065ae66),LL(0xa7dabb6b,0x2162062b),LL(0x8e011036,0x1422386b), + LL(0xe069de1c,0xd2589ad6),LL(0x7ee09300,0x3fe8e67a),LL(0x2f8ae49b,0x5b881860),LL(0x263a6a90,0x186a1482), LL(0x9b35b33a,0xc6079b39),LL(0x53d3411d,0x6c38d789),LL(0x720b2f99,0x743c4462),LL(0x29e14d08,0x4d903dd7), + LL(0x7b963913,0x625dfce0),LL(0xcc65e41f,0x60a83daf),LL(0x93e185a2,0x9e88c26c),LL(0x13707ac3,0x6d950e92), LL(0xa0a23dd0,0xbd7df2dc),LL(0xc2116cc8,0x5fad27f2),LL(0xda4430be,0x0703b868),LL(0x83cc41df,0x5ebf0e2f), + LL(0xf9e83fc8,0xebb91900),LL(0x6d60bb8a,0xf9539591),LL(0xb604935a,0x3bdd7a8b),LL(0x64e5eec0,0x2cae8c67), LL(0x60aaf21d,0x30cf58bb),LL(0x359f63cc,0x5e0f6f5d),LL(0x0547e03a,0xda245055),LL(0xb9e143ce,0xa83fd8bb), + LL(0x1b0215aa,0xa564435a),LL(0x354ba769,0xecffccec),LL(0xbdbbd594,0xd846149a),LL(0x65dd1597,0x9137df36), LL(0xa9f3ac33,0xc4f39f37),LL(0x961d7e8d,0xf594bb74),LL(0x835befbc,0x41fa4b58),LL(0xed79139e,0xa983eae9), + LL(0xb4e31aa4,0xd4085efc),LL(0x18b26adf,0xc760aec0),LL(0x76a7400d,0x14c1f78e),LL(0x317fe128,0x87b8aced), LL(0xcbd85bb4,0x4433582e),LL(0x86adc041,0x58f01426),LL(0x8f0d5781,0x3596dd50),LL(0x1a31a82f,0x2e7f3b80), + LL(0x2d1ede3e,0xcac7ccc8),LL(0xe89573db,0xc9b9a8f3),LL(0x54b40df9,0xbf744f69),LL(0xa85ecb47,0x88eb2281), LL(0x426ec49d,0x6b115026),LL(0xc8c41110,0xebda4660),LL(0xdf392aae,0x0a4a32ac),LL(0x37cb7080,0x2a28f9b3), + LL(0x6bd9414d,0xfed99d1a),LL(0x5715620e,0x15f59c41),LL(0xac431919,0x93edd9fc),LL(0xe1ccc47f,0xed1d43ae), LL(0x556d1ab5,0xafed2acd),LL(0x02e039c0,0x817b967d),LL(0xe02a68bb,0x335d15da),LL(0x67df767c,0x4fa75ea0), + LL(0x44833943,0x384704b3),LL(0x4084ef35,0x7809ed3c),LL(0x79c7ff41,0x2abab3c4),LL(0xa833fb73,0x2b7ef5b2), LL(0x4901a4ff,0x12b0335b),LL(0x44d58617,0x3eea607b),LL(0xd7f57746,0x7161b669),LL(0xb1e93442,0xee17e43f), + LL(0xd6d7878c,0x95c9bd80),LL(0x34ff7c75,0xe1ef20ee),LL(0xd2ccd599,0x3fab197a),LL(0x952ef4f9,0x9e480593), LL(0x06ea3410,0x69777fd2),LL(0x74fa7dd5,0xb0280454),LL(0xc43bb5fc,0x641b6860),LL(0xecd7b8a8,0x9f359d5b), + LL(0x70be68cd,0x4431d4ed),LL(0x08b55f8f,0x712117f4),LL(0x23d0b6ca,0x449e1319),LL(0xfdee5357,0x658323cc), LL(0x62879a95,0xa1ef8114),LL(0x69963eeb,0xc21257e5),LL(0xc5bbee13,0x1016ab74),LL(0x43d81a86,0x99bb310a), + LL(0x1d33a15a,0xdef03c44),LL(0x49127148,0x3e78cf18),LL(0x30b0cc00,0xe8d93368),LL(0xbd7ccd85,0xb05458fb), LL(0xdbaa76b0,0x8c2896dd),LL(0x79e4cacb,0x0d826600),LL(0xff730ed0,0x50a45b23),LL(0xeba9030e,0x4a0e079c), + LL(0xe3129aa0,0x3ead3fdc),LL(0x48aac890,0xa93b39f3),LL(0xf362465e,0x0fd73860),LL(0xf8df2764,0x69177f2c), LL(0x824ebddf,0x4cd58c50),LL(0x2fcef01d,0x1478981f),LL(0x980524b3,0x511bd380),LL(0x4d23e8e9,0xc95252b1), + LL(0x9ce08452,0x7ff12c37),LL(0xa3a87024,0x3dd8dd09),LL(0xb849dcb6,0x61ff0d39),LL(0xfefad6de,0x3f5eab86), LL(0x251523f9,0xb6146886),LL(0x5be2135b,0x45ac1d52),LL(0x41d2c5d4,0x63507995),LL(0xb3064e72,0x7f19f799), + LL(0xa2efb9be,0x7280ad9b),LL(0xba9659de,0xbc8fbb60),LL(0x875a8062,0xa4861c12),LL(0x2f2387ca,0x78c920c8), LL(0x03b7da99,0xfe0a6ea7),LL(0x48e3afa3,0x936a44b8),LL(0x89fd127b,0x618a0ecf),LL(0x06f24bc5,0xa35614cd), + LL(0x8d49c05f,0x21a1002e),LL(0x2fd7989d,0xceeacfd1),LL(0x8f5f4ea5,0x8c058f4b),LL(0x563e214b,0xf31bd38e), LL(0x245c7585,0xbe47bd98),LL(0x6bc2a404,0x70d1a05c),LL(0xc68257f7,0x830d7f30),LL(0x8136c932,0x1abbbfbb), + LL(0x6e03597b,0x6fbc43b7),LL(0x5fca14a2,0xc18fddb6),LL(0xe8f506e2,0xd3c4ca78),LL(0xa47e27de,0x6b8711dd), LL(0x16382b5b,0xc308c189),LL(0xcf96bd7a,0xe9d3145b),LL(0xafb26629,0x5c290ec1),LL(0x209438ff,0xb4eb8130), + LL(0xe1118539,0x7335044a),LL(0x5192a007,0xed6d43fc),LL(0xa43a2bd4,0x1a8bf622),LL(0xefa9f3a5,0xefec3fb6), LL(0x6d834bde,0x6d224bbc),LL(0xb0fbc744,0xaaebfcb8),LL(0xc4ea1652,0x383b2bfc),LL(0x751ae816,0x9cd26d90), + LL(0xf47f0f9a,0xae614386),LL(0x73c6ecd0,0x99873787),LL(0xe5414fc7,0x0b56c1ad),LL(0xfd40286c,0x9b85e6b5), LL(0xd64687dc,0x7117aacd),LL(0xad8a8c4d,0x85d148e7),LL(0x7962655c,0xf62f8eb5),LL(0x7f0c6a2c,0x8386b37e), + LL(0x90c47d7f,0x6b4715a3),LL(0x458a54e4,0x1fc4ced1),LL(0x0ed97b0a,0x01853943),LL(0x5b370e0e,0x58a280be), LL(0x344f3960,0x8d488cb6),LL(0x0741604b,0x9050c599),LL(0x07954771,0x0878fb1b),LL(0xdbb3c82b,0xd927ea8c), + LL(0x384f01fa,0x2fe71d59),LL(0x238bb66b,0x66d2b790),LL(0xb8fd803b,0xceaec11f),LL(0x6dd09c0c,0xbb919914), LL(0x2ccb2f67,0xab5992e6),LL(0xcca50326,0x2421878f),LL(0x9ee6dc73,0x363d933d),LL(0x084b1fa3,0xa374ab0b), + LL(0x161f6475,0x2d832a29),LL(0xfc8797eb,0x435b8d78),LL(0xd71b609c,0x66bc156d),LL(0xfe0c2004,0xb3dca798), LL(0x02fd92d7,0x445d47bf),LL(0xc8b03083,0x1d1c9798),LL(0x079a7c51,0xca46d98d),LL(0x1afeb89a,0xb93f286c), + LL(0xeeb6665d,0x1c174510),LL(0x7479a932,0x65874b6a),LL(0x2335e3b8,0x28d16a85),LL(0xc747eae6,0x5e22bd3b), LL(0x04be16b4,0xa770e0a7),LL(0x40b3ff57,0x9f5f9ca9),LL(0x845ec39f,0x3f39e529),LL(0xebe697ce,0x5d5f4d60), + LL(0xbd90d4f4,0xea2a262f),LL(0xfe1b6494,0xa1ce74ac),LL(0xfa0fc472,0x4e419004),LL(0x4e691060,0xdef0e440), LL(0xa9f4baf3,0x57195a3a),LL(0x5e758c53,0xf14e108b),LL(0x920895e0,0x10a34f9d),LL(0xfeb57a63,0xc3f18af9), + LL(0xda1bef0d,0x4b1c988c),LL(0x3df6915b,0x8b328cd9),LL(0xf45586d5,0x5ddc5ecc),LL(0x040322fc,0x426468b9), LL(0xbe981558,0xf7f44765),LL(0x1855504a,0x25093991),LL(0xf7d6df43,0x72c51f2e),LL(0x849c99e5,0x858637fb), + LL(0x0ee9f78b,0x68b84dfd),LL(0xf2ee390e,0xff42fc9b),LL(0x531e1dcf,0xaca71e10),LL(0x7feaedfa,0x391620e2), LL(0xacf3e5da,0x7b2d6a02),LL(0xd20a16d3,0x261823d2),LL(0xbb00cd30,0xf9afa5d6),LL(0x1084580d,0xba151f4a), + LL(0x26a3fcc3,0xb5f4b3a9),LL(0x6729f4da,0x5d84a823),LL(0xfc35f732,0x51540c41),LL(0xa6ae5bf7,0x81b0cb58), LL(0xbd81bd27,0x91c7ae07),LL(0x1d56ff5d,0x0868980e),LL(0x65224df6,0xaef85a31),LL(0x17a69e35,0x112eba3b), + LL(0xc3a9d932,0x07c34677),LL(0x8ac45e37,0x3b6b7cce),LL(0x31b6248a,0x5e0e2b6e),LL(0x453d9685,0x14ee5b66), LL(0xbd4d807a,0x4c5e2be7),LL(0xc121fea8,0xc03f37f8),LL(0x8df7b5e7,0xcf34911e),LL(0x5f754191,0x00e7f18e), + LL(0x2dcea4aa,0x89a8c9e1),LL(0x50f6db55,0xcc1cc31a),LL(0x9046955f,0x4a6f542c),LL(0xda2485d4,0x85fed580), LL(0x9ac53748,0xa70f62d1),LL(0x655870a7,0xc2fbb850),LL(0x8c859aef,0xaeb2d438),LL(0xcc9ff51e,0xe3cc5ae5), + LL(0x0a3ebbfc,0xf8d8c55d),LL(0xed48f61a,0xdcd838d5),LL(0xd4cba7ab,0x032f91ea),LL(0x2f70235e,0xeb0ed88d), LL(0x000ef325,0xd4498170),LL(0x4b923c4a,0xfd34e07f),LL(0xb19b84cb,0xf71c07a9),LL(0xed9690a3,0x000a669c), + LL(0xb5705e16,0xf45eb0ef),LL(0x7d9ce007,0x8cfd6a62),LL(0xd9e52885,0x76ba9a5f),LL(0x8aa9ffd6,0x13f72881), LL(0x85528e4a,0x0a11e8dd),LL(0xcee8d663,0x58f1993d),LL(0xa1c81fd3,0xb49d750b),LL(0xe7de2e6b,0xaae29861), + LL(0x5dd7de70,0x9a40644e),LL(0x937a5546,0x67fbae1c),LL(0x956c2fa8,0xb3e02907),LL(0x21b4aede,0xaf785374), LL(0x9c0a8bfe,0xf42a1e96),LL(0x78957181,0x3f6690e6),LL(0xa6c5e0a7,0x1b1c9575),LL(0xf9cfb9bd,0x6def8124), + LL(0x72faa1b0,0xde552cf9),LL(0x9b5ebbbc,0xfac2f4ad),LL(0x8ef89ba1,0x4b60a5a5),LL(0x8012f3b1,0xb6d9be57), LL(0x9b2b083d,0x3992a6f7),LL(0xac640f77,0xe79ec527),LL(0x3f1e632e,0xf6cca775),LL(0x8fb80790,0x5dae8413), + LL(0xb572407c,0xf0d4146c),LL(0x3f84cc39,0x829cfb38),LL(0xe31f007e,0xd7c9fed4),LL(0x09e68ce9,0x93b2a5bc), LL(0xd01482b9,0x073fb24a),LL(0xb8d44e62,0xfe494244),LL(0x3dc49858,0xe59a1649),LL(0xf005b31f,0x071776f7), + LL(0x285439af,0xaa368f59),LL(0xe27e783d,0xb0821574),LL(0x098746ba,0xe16903f6),LL(0x69dc00d0,0x436a95ae), LL(0x877bfcec,0x9ae5a91a),LL(0x1416ad3a,0x5d8758d9),LL(0x25fd9a9a,0xa420ce40),LL(0x39b0fbfa,0x99610fdf), + LL(0x41cc1e9b,0x782af222),LL(0x86ff4cf6,0x346a4a92),LL(0xabc900c1,0x9dc4c6cd),LL(0xe7fade51,0x7ed2476c), LL(0x4f1dd24b,0x68a72185),LL(0xb08260cb,0xcefcf0fd),LL(0x8a6f61b6,0x0199a147),LL(0xcb5769c5,0x176b6079), + LL(0x347d5a63,0x6dbcceb0),LL(0x9c4dc505,0x26433ebc),LL(0x05d5e74d,0x52570318),LL(0x057ca464,0x692f1d81), LL(0x477f424e,0xa09554a0),LL(0x176a695d,0xbd3f9bbd),LL(0x5972db27,0x8c7f52f3),LL(0xf28b2aa4,0xacee8234), + LL(0x3a4a0217,0xb853465a),LL(0x66f3a4d5,0x74a2534f),LL(0xeff0423b,0xae1a7ff3),LL(0xbb126028,0xd2a01a09), LL(0x4963e855,0xff84c6f0),LL(0x6bc18d50,0x63db264c),LL(0xcc6a5e25,0x39792dca),LL(0xedb37a25,0xf20cdf3e), + LL(0x8730f2c4,0x6a460f3d),LL(0x6a0ab6bb,0xe9b786c4),LL(0x084015c2,0xa9720a6b),LL(0x0dbe6f0f,0x28add2e2), LL(0x26be7de7,0x90fb0ba7),LL(0xe40f15fd,0xfae8b5d4),LL(0xceb9c856,0x007363a1),LL(0x586b770e,0x6d8bfe14), + LL(0xb7bcc0e0,0x63e7d78e),LL(0x3ed4ab62,0x56c569f8),LL(0x9e103abb,0x76c6a5bb),LL(0x638fc44d,0xeb24afeb), LL(0xf0be16f1,0x15e00239),LL(0x8778f084,0x7db92f67),LL(0x63de2bef,0x5198680e),LL(0xe0510421,0x69031d0e), + LL(0xb94753c1,0x8058f8aa),LL(0x454bf609,0x412d4c97),LL(0x95f9fd19,0xb8dbfe8a),LL(0x68b43233,0x6cd3221a), LL(0xa5adaaff,0x384a9f15),LL(0x42b2ef95,0x60c70f90),LL(0x2c7da919,0x085b2f3b),LL(0xbc8407e1,0x1e5d23d1), + LL(0xadb45b3e,0x9ea95bc9),LL(0xed06ec67,0xb5a28fec),LL(0x62a3c143,0xd678df46),LL(0x6793284a,0x80f0bc9d), LL(0x07d4afc7,0xeb7865a9),LL(0xc1301d87,0x0fc5eafe),LL(0x4823349b,0x50a8e7f5),LL(0x2d019e96,0x97800fa2), + LL(0x1bdd1d9c,0xfeff2579),LL(0x23886156,0x4d938c5d),LL(0x6979b9f6,0x25e3a806),LL(0x37bb6199,0xeeef8fa0), LL(0xd7d308b8,0x4d917977),LL(0x4ae672cc,0x60ca7ff9),LL(0x2a68db6e,0xb24ec154),LL(0x9e9942f5,0x7b0604ec), + LL(0xca4fad9e,0xfdf4794f),LL(0x3df5de22,0x086020f8),LL(0xd601533c,0x653da6ca),LL(0x735709f3,0xf97c1865), LL(0x7cbd6ab6,0x2457ffd0),LL(0xd003a502,0xce05a482),LL(0x33ee2740,0x5c0c0cba),LL(0xf37174aa,0x8146ca00), + LL(0x587262bb,0xec118827),LL(0x7e2a402c,0x8468c029),LL(0xbd6eb2aa,0xe1c3a9e3),LL(0xb496bde8,0x77d09b4d), LL(0x854693bf,0x454e767a),LL(0xa4de85bc,0x6bbcc22e),LL(0xb180f206,0x66452f10),LL(0x0f5b1744,0x110c5a05), + LL(0xa6b3f6e4,0xb7be75d8),LL(0x2c0d2e1d,0xf64bb3fd),LL(0x935ae640,0xad17a039),LL(0x8f243748,0x7304ad63), LL(0xd278caa9,0x04316bb4),LL(0x1e84f91d,0x19b89c62),LL(0x6e7a2511,0xdf4a47e9),LL(0x998b6bc0,0xdef32df9), + LL(0xcee95a1f,0xf1253ce0),LL(0x0ae96e31,0xbacf5206),LL(0x0b343e63,0x4ba2e24a),LL(0x79929dc6,0xca64d07f), LL(0x9424ce75,0xf2823ac8),LL(0x0207ee9f,0x2d4add37),LL(0x387cde5f,0x44d9ecd0),LL(0xe180a21f,0xa5095ccb), + LL(0x7c0cedf8,0x901cec8a),LL(0x3b8c759c,0xf291dc78),LL(0x49401234,0x98b8efdc),LL(0x058e9d9e,0x8f2b16e3), LL(0x27dba00f,0x16ce8007),LL(0x6d66d2f1,0x5bb8fca9),LL(0x7b85a96b,0x092eda98),LL(0x973eae20,0xec53f4bc), + LL(0x1b93a60f,0xe6e0df59),LL(0x2f6b0abf,0x65e06ecf),LL(0x569a9e1d,0xb8c2ec3e),LL(0xaa8c1cc3,0x27f9fe72), LL(0xccd4d5e2,0x9cf3908f),LL(0x725c8528,0x5a40e0a9),LL(0xd470b0b0,0x27b15a1e),LL(0x33d81bff,0x50a09ec1), + LL(0xda99fcf5,0xba976a58),LL(0xc3536b7c,0x3881ef1e),LL(0xfbc931b1,0xec65a069),LL(0xfc929a0e,0xab7f57b4), LL(0xbc61f452,0xc7c63491),LL(0xc1750dbc,0x5c1aa935),LL(0x9ff0465c,0x35b8789b),LL(0x727647b7,0x8ff8589b), + LL(0xa95022b6,0x2b56fe50),LL(0x2adbdbbd,0x24220569),LL(0xd2b80ea8,0x2370d94f),LL(0x71d9e6f7,0xe5d47b73), LL(0x8d858032,0x2fe84b72),LL(0x4ffd7cfe,0x0411034b),LL(0x7c2c84e0,0x0819a9f3),LL(0x30228f9e,0xf8248dfd), + LL(0x4fdf6c79,0x75c77f0a),LL(0x15579cc7,0x195b4b59),LL(0xf8d3705c,0x274c7c81),LL(0x70ee9be1,0x45a2209f), LL(0x0b1e818b,0x4a4fce69),LL(0xbb9926b1,0x74d05e5f),LL(0x3f2a796b,0xb64639ce),LL(0xae957d59,0x2d168d5b), + LL(0x16171846,0x067c2270),LL(0x1a03f8d1,0x7bb71d15),LL(0x495a09a1,0x2badd196),LL(0x51b990c4,0x024db163), LL(0xe79dcaac,0xc19edc61),LL(0x60df81e9,0xf17f54bd),LL(0x9ae347e4,0x4560262e),LL(0x59eb711d,0x1d2c2542), + LL(0x4919affe,0x40372d2d),LL(0xa009bd16,0x2d4a2ea3),LL(0xc1a62eb1,0x48f1e7f8),LL(0x587a1124,0xce083725), LL(0xe7ebadd3,0xe874261b),LL(0x057b93e9,0x7ca5c156),LL(0xfe39e6ff,0xe8b381e5),LL(0xd30815c3,0x2d16b32f), +}, +/* digit=15 base_pwr=2^105 */ +{ + LL(0xad2e996a,0xdfd30b28),LL(0x9df0fc37,0x64d4eeec),LL(0xddc39763,0x8e049e3d),LL(0x37ea2e8e,0x9f55e0ce), LL(0x4bf01984,0xf3fcba4e),LL(0x9d55bc4b,0x764d5c3d),LL(0xcfda895f,0x98cb92a1),LL(0x5c7bca69,0x27dfe795), + LL(0x23a86e2c,0x86dfdecf),LL(0x3387f712,0x02ac466b),LL(0xd63509d1,0xc30a1ac2),LL(0x63aebbd1,0xd3913422), LL(0x068ae34f,0xdc7b789f),LL(0x487dcd10,0x499f2d01),LL(0xa3e8a4b4,0x68e2a3bc),LL(0x14d2a26c,0xdf87ba71), + LL(0x34479e7b,0x9e3ab999),LL(0xb026e780,0x9d5f2dc3),LL(0x4f1bd429,0x131374fd),LL(0x9be1379a,0x92e2e738), LL(0xd13bc111,0x6cc32f80),LL(0x86f81c92,0x6fbfc350),LL(0x9263913a,0x12ca1b30),LL(0xe06ab75c,0x6f7da1ff), + LL(0x19301b16,0x4780f12a),LL(0xbc368a20,0x233bc231),LL(0xcbadb344,0xd9650892),LL(0xad9425a1,0x38a0d964), LL(0x4a8d4d7e,0x277abcf2),LL(0xb806ce9e,0x4ccd16b1),LL(0x7570d473,0x82ff40f0),LL(0xdf130780,0x57491414), + LL(0xa96ef42b,0x9f1f39f2),LL(0x107f1321,0x1fd967ed),LL(0x29d4767e,0x93832497),LL(0x3fa9e796,0x7761a38b), LL(0x66318df2,0x3e408c59),LL(0x41745f03,0x9283ca44),LL(0x2cce1a86,0xfedf8fa3),LL(0xb44600b4,0x8363860d), + LL(0x45f45a89,0x3dbfde55),LL(0x26ce399c,0x8800c860),LL(0xc25e9479,0xfb25e8da),LL(0xf7d367a2,0x6ff0d6cb), LL(0xa93f9890,0x70b0ba36),LL(0x49bd5a80,0xc07ca403),LL(0xed54d1aa,0x5f4feda6),LL(0x671ad0b4,0xfa1e2efd), + LL(0x8c56e7aa,0xda465467),LL(0x25e45bc0,0x39d04cdc),LL(0xaf21c637,0x26661bd6),LL(0xb55ddfa5,0xf757ff5c), LL(0x4394eb20,0x07318fd1),LL(0x2bcf3ad1,0xe010b19d),LL(0x8e5c7e7f,0x71e2031c),LL(0xedbfda69,0xee35f346), + LL(0x5d8f6fab,0x8d8d4120),LL(0xabed09c8,0x5e420839),LL(0x4aacbb1e,0x5120e079),LL(0xec1bc996,0xf7e840f8), LL(0x9707c3bb,0xd921d63b),LL(0xae891a71,0x3ab4b8b8),LL(0x73bb2278,0xbe465756),LL(0x553ee91c,0x776ce040), + LL(0x88222e0a,0x86f07c2e),LL(0xdf97816e,0x3f3688f1),LL(0xa6df9d3a,0x20d2d944),LL(0xb2cb925a,0xff399057), LL(0x27f1de19,0x010c747e),LL(0x7fc1fbc3,0xbe940669),LL(0x877ef709,0x3ab94600),LL(0x8f4c8a8e,0x9af40a6b), + LL(0x713f023a,0xf7c0f202),LL(0xd0a8dc63,0xbe0bf3db),LL(0x64a41337,0x09789926),LL(0x2c2823cf,0xbb4a8964), LL(0xb90e45c6,0x9279cb27),LL(0x382564ac,0x80283fd3),LL(0xfa5f0bcd,0x3a746b01),LL(0x0afaf10a,0x28667a8e), + LL(0x015d5295,0xeccfd0ee),LL(0x73ce8e21,0xbd6678a5),LL(0x336ecb65,0x132a87f2),LL(0xbe7dc659,0x09de4efc), LL(0x6f69b3bd,0xbedadd10),LL(0xe8303650,0x357c61e2),LL(0xa45777e6,0x6b3c613a),LL(0x08d41179,0x51dd30ad), + LL(0xf98feac3,0xa7b53f3f),LL(0xf9497319,0xe8e00328),LL(0x0ca20b40,0x1f3b080d),LL(0xe19b088e,0x06dc5456), LL(0x0dce02cb,0x1f3f18d7),LL(0x6fd1ade9,0x2d215544),LL(0x055550d0,0x4c6de38c),LL(0xf33f4973,0x5d535e6f), + LL(0x744c033d,0xdcfd4163),LL(0x76fc420a,0x0706a490),LL(0x394f5b6d,0xdc9db55c),LL(0xe040a093,0x1a050a62), LL(0xd0ab26f3,0x60367ebb),LL(0xc3d91820,0xb9c07239),LL(0xa3e32db2,0x14a8bed5),LL(0xd49f37dd,0x23b19cd3), + LL(0xea6c85ce,0xd048c64f),LL(0xd5716cfe,0x8aefff19),LL(0xab85bdcf,0x199fddb1),LL(0xbaea49d0,0x3f592e7e), LL(0xf1d58ff6,0x8c8decb6),LL(0x7fe8f425,0x02598a99),LL(0x64a93fd6,0xe4c73ae2),LL(0x878db06b,0x208a0f61), + LL(0x27c4a266,0xff0272fe),LL(0x69e7c6a2,0xccfc96ae),LL(0x8e78d74a,0xbd7e715f),LL(0x32ed35bc,0xd04ae9a4), LL(0x05614c5f,0x302af413),LL(0x33943b5a,0x98176637),LL(0x8a58cfd8,0xa4d1c9b2),LL(0xac2f3f79,0xf0ebd5f4), + LL(0xfdc7945f,0xebadb010),LL(0x03750a4b,0x62c9cff0),LL(0xa0c85b9d,0x75192383),LL(0x16eb0bf9,0x2aba7b53), LL(0xa4c06f9a,0x93d4adaa),LL(0x5f8e482c,0x573a86a2),LL(0xe791a79f,0x109c6fdc),LL(0xb37eeec2,0xd9ed02ce), + LL(0x7dd63c8b,0x7b1fb4b4),LL(0x22493b49,0xae6e2767),LL(0x6a411bc9,0x5ef6beb7),LL(0xe1bf4242,0x4d88918d), LL(0x02a97fbc,0x7ba26f8c),LL(0x7f41c518,0xf45b2a50),LL(0x83249e23,0x6c35fb69),LL(0x7a5778cc,0xc4a95134), + LL(0x08287cf7,0x6173f860),LL(0xfac3a444,0xdcfc71d9),LL(0x079ce3c9,0x894f3b33),LL(0x916b661c,0x842bf7da), LL(0xa758a243,0x94299d6f),LL(0xb242389a,0x0e23f984),LL(0xc03a7aa2,0x653050f0),LL(0x9559ad9c,0x2ec3041b), + LL(0x97cf6e9b,0xa61dd499),LL(0x448fa6c6,0xfd090f38),LL(0x39b126bf,0x4f1b75ac),LL(0x1ef1a280,0xb48d0372), LL(0xf2b2941f,0xe40c310d),LL(0x8d9d5ace,0x5b9a7369),LL(0x7ad9ad95,0xbe0415c1),LL(0xa8510622,0xffd864b6), + LL(0x898f28e8,0x2aceddcd),LL(0xba89a51f,0xa0cfc30a),LL(0xe105e448,0xd87db983),LL(0x5e5ea6fb,0x16ba795e), LL(0x352ad094,0x5f48e45a),LL(0x55fd75e7,0x1971a10f),LL(0xfd1c8d68,0xfb0f1767),LL(0x86df0665,0x904229d9), + LL(0xe87ab22b,0xc2c88671),LL(0x33611a50,0xcbe384a1),LL(0xad2eb708,0x38eec58e),LL(0x86d7bdee,0xaa19b174), LL(0x51832b61,0xa9f416d7),LL(0x355e7b6d,0x10b751ff),LL(0x4ff07a5a,0x6dd52063),LL(0x4e3505c1,0x6a6090c1), + LL(0xd4c80f29,0x53addd1c),LL(0x0d3d793e,0xe76d668b),LL(0x191eedd9,0xbdcdc4c9),LL(0x0f8e4877,0x80675320), LL(0x32f5661b,0xc41426dd),LL(0x06199185,0x9fcbe1ac),LL(0x404a1207,0x62fa2198),LL(0x33c8190e,0xc742fdc2), + LL(0x778ee765,0x16ec1b96),LL(0xe29d992d,0xda656f58),LL(0xb4369e7f,0x5393775b),LL(0x0674fc45,0x512f5c7b), LL(0x60efa8e0,0x55b8bd38),LL(0x155b57ab,0x1ab6d2df),LL(0xe26ad439,0xed0aa777),LL(0xd9b04376,0x5b16333e), + LL(0x8fc7ea72,0x321119d3),LL(0x7211ef45,0x390b4ef5),LL(0x1feda1a2,0x289f3945),LL(0x605c8596,0xcee9cb33), LL(0x971b6897,0x91109e96),LL(0x19701ea7,0xdf70c173),LL(0xa92c6b2b,0xa07d0ecd),LL(0xa9eab766,0xf8eb97fe), + LL(0x0e3cf9e8,0xbb2cf63b),LL(0xdda02b26,0xffa6c503),LL(0x9cb18efd,0x42c1ec1a),LL(0xc45d5b22,0x13cdda9c), LL(0xc820cdf5,0x6b3baf33),LL(0x610c8bfc,0xa337bc5e),LL(0x06a9ca6b,0x88186818),LL(0xa0c455af,0x382a34ee), + LL(0xe8fc59df,0x725006c9),LL(0xf929c670,0x0d46b697),LL(0x893a9f6e,0x7bd6eceb),LL(0x1cd04e5a,0xf25aa637), LL(0xf6612d4a,0xf1563d79),LL(0x5efc49d8,0x8c9372cf),LL(0x96c5bdc5,0x09cc0513),LL(0xd3cc34d8,0x70f19d46), + LL(0xfdfbe16c,0xe62f6891),LL(0xdc60110b,0x8b7db2fd),LL(0xf7868674,0x3557bff8),LL(0x95a638d6,0x2b414c8e), LL(0x6d19ac65,0x3b6610ac),LL(0xd641b0ea,0x20864204),LL(0x892161fb,0xee372a46),LL(0x4125868a,0xc7c5bd87), + LL(0xa61ee957,0x5edc6afc),LL(0xd37faed4,0xa4374ba1),LL(0x1e52b0ab,0xf0684f46),LL(0x2a007b66,0x0812cbca), LL(0xe68c4893,0xf3442afd),LL(0x2d9dd9a2,0xb02ac6df),LL(0x068c08bb,0xa4fe98dc),LL(0x7795e2e9,0xfcd5dc05), + LL(0xa0f55cd8,0x28983aee),LL(0xe96cf557,0xb390daf4),LL(0x3f119098,0xbfd2f5ab),LL(0x6386c0ad,0xed114587), LL(0x69539392,0x578995b9),LL(0x36b880ab,0xc8a77948),LL(0xe4c8b560,0x7e03cfb6),LL(0x06cdcbe0,0x018cd4db), + LL(0xb006f8d5,0xbd7f2e3a),LL(0xd6d9f30e,0xf25d1718),LL(0x1b22ae3d,0x9ef6e2ee),LL(0x416154ab,0x89a2695d), LL(0xda261e39,0x1975e0c8),LL(0xda2c2031,0x8fe66aed),LL(0x97e1e00c,0x6f93f839),LL(0xa742b328,0xcba9a773), + LL(0x3417df8b,0x9529fec1),LL(0x54e314b1,0x37a27cd9),LL(0x65f94a63,0x93feb0f8),LL(0xb5e029c1,0x65978b84), LL(0x81b705f1,0x576fd830),LL(0x688e8c52,0x37d07a37),LL(0x332838dc,0x3b91d360),LL(0xb0b14a94,0xcca9cbf8), + LL(0x8b63b669,0x86f18c44),LL(0x6972d2d1,0x53c6eba6),LL(0x8cff59bc,0x2a522d8c),LL(0x6ed25ce5,0xbc181d15), LL(0x5feb0eca,0x913f173d),LL(0xa207bd71,0x34273f8d),LL(0xfa1715ae,0x41b7572e),LL(0x7f16f4ae,0x8a8ffea2), + LL(0xf95bdf78,0x2b852908),LL(0xa26328b9,0xa75adbb3),LL(0xdae21d25,0x992ac179),LL(0x78e14467,0x8c99927a), LL(0x0c16e0c2,0x23fb2fee),LL(0xdbcb5f4e,0x58e797bb),LL(0xa07bd7de,0x33d6956e),LL(0x7172d36a,0xc921fdb3), + LL(0x158267b5,0x035f1744),LL(0xa291374d,0xc7495f33),LL(0x4a41a6a0,0xe07db2f5),LL(0xd1238792,0xfdb2987e), LL(0x49741ce6,0x616df624),LL(0x8a693880,0x90ecd21b),LL(0x341fe21b,0x447c729d),LL(0xc012a8ab,0x06ad3c90), + LL(0xddfd6b5a,0x13dc4fa9),LL(0x64cfc0f3,0x238a1add),LL(0xc34a2b1e,0x874a3c2f),LL(0x0deb1dd4,0x427b6e3c), LL(0x876f2621,0x78a1ad1d),LL(0x252f6837,0x34f9207c),LL(0x047d667b,0x1c812fbb),LL(0x3ee03ba7,0xc3512ea3), + LL(0x527a1b55,0x762de5f0),LL(0xae3221af,0x7873d692),LL(0xb112d35f,0xa8ac73c7),LL(0x815414f6,0x1d118c30), LL(0x865ab6f6,0xbc686118),LL(0xecf8c02d,0x01e75348),LL(0xe6220bf9,0x9b131840),LL(0xa67512b5,0x3d72dac4), + LL(0xaf95e16e,0xd9e49ecc),LL(0x1e2aa105,0x1297c560),LL(0xa1a5e8c2,0x925301ac),LL(0x990ab503,0x3b0ea863), LL(0x15f258c4,0x7860b660),LL(0x397253e4,0xa4497040),LL(0x14a4774d,0x88562ed0),LL(0x7adbd093,0x325d8b0d), + LL(0x41e24010,0xd4df8df2),LL(0x580031be,0xe7cb8663),LL(0xd7fc7e5f,0xd653593a),LL(0xe9f1fe9d,0x429a8863), LL(0x63e71ced,0x18a0a709),LL(0xa498140e,0x39d9316d),LL(0x40f40117,0x44466cff),LL(0x64602832,0x58d27cd6), + LL(0x86018a70,0xf4a4c22b),LL(0x6d703f04,0x7a4d4102),LL(0xb424b0fb,0x4f5a0037),LL(0x322b1876,0xfb591cfd), LL(0x632e0f56,0xb45798b0),LL(0xfdcbcf20,0x83ef9feb),LL(0x115749ac,0x0a23b09c),LL(0x946248f8,0x3b950273), + LL(0x1e13eaee,0x5ed75e68),LL(0x09dafdb9,0xbebd4744),LL(0x69941fc4,0x8b46621f),LL(0x91129bc0,0x1fd3c13f), LL(0xb7b9da22,0x371448d0),LL(0xd87a4742,0xd452ccea),LL(0xf91c38b9,0xe2f04778),LL(0xbd516bfe,0xfb443a5d), + LL(0x044d666b,0xd7bd4056),LL(0x2a9b17c4,0xb4546ffd),LL(0x818fe55a,0xf66765ae),LL(0x1b5dc7a0,0xc375126c), LL(0xc1a81c63,0xe9a7ed20),LL(0xf8cf06b9,0xaef2e23d),LL(0x3e67b95b,0xf4536865),LL(0x24309537,0x25cbb5a6), + LL(0x3256c020,0x8a230e68),LL(0x215dca7b,0x4a33e462),LL(0x2935b6d1,0xefef4936),LL(0x852c39f4,0xb383df4e), LL(0x57c21e90,0x197ddd77),LL(0x2164127f,0x236f98dd),LL(0xbbd61847,0x464b86ec),LL(0xfb89d515,0x107a387c), + LL(0x400d66d5,0xe01e50b7),LL(0x5f864426,0x4377af2b),LL(0xf8fe847a,0xde21c49a),LL(0x887c0674,0xc133e58f), LL(0xd2fda17c,0xda5b4c3b),LL(0xfed8fe68,0x24157f13),LL(0x8b6bb6bf,0x1c4483f3),LL(0xcf1bed73,0x940fab9e), + LL(0x3c15c7e5,0xce3fca79),LL(0x066de109,0xb83fce10),LL(0x0cd5a04a,0xbd42ed01),LL(0x407fcb03,0xba5446b8), LL(0xe5d35bda,0x4a8cb929),LL(0xbff8631f,0x6338fd7e),LL(0x4656a8cd,0xc85d4ee4),LL(0x92c99820,0x83b1f39a), + LL(0x7e90c823,0x153fa4d4),LL(0x15326196,0xc15809ba),LL(0x6eb4b379,0x320b8fe9),LL(0x58704d9e,0x27cc07c0), LL(0xf13d6ee7,0x301840b2),LL(0xc6d8c930,0xf1f6530f),LL(0x96a22034,0x3e9254ea),LL(0xaf5b8a2e,0xf8c0ee68), + LL(0xb8207fde,0x88e9e44e),LL(0x29bc1310,0xdea11cbd),LL(0x9c9d7df7,0xa20c2f17),LL(0xbceac495,0x2a954927), LL(0x2a58d6ba,0x3f405f5c),LL(0x2ac9aeaa,0x64df5364),LL(0xe8aa74a5,0xb618f6db),LL(0x74ef61e3,0x22dadc7f), + LL(0x9cfdc4cd,0x306ee832),LL(0x40698a5b,0xaff53321),LL(0x89567341,0x98893443),LL(0xac7c68ec,0xdfefbdd4), LL(0x3261a582,0xd3da7094),LL(0x62ce96e7,0xd23e3fa5),LL(0xd773337e,0x62c060c0),LL(0xa041f910,0x5cb2beca), + LL(0x7e8215d8,0xe21ab479),LL(0x923b4b27,0x84384686),LL(0x6a3d21ef,0xa93c08fe),LL(0x2fa6de1c,0x7bd96248), LL(0xca6de3e0,0xb858ecd7),LL(0x47c9fced,0x466a48c8),LL(0xc708239e,0x23ca9b75),LL(0xb5bbe833,0x860d553d), + LL(0x9e76e71d,0x45804f1a),LL(0x51e59be2,0x9fdb8b8d),LL(0x3bbc2a19,0xa76db4b7),LL(0x96f82cd0,0xaebb47ee), LL(0x97b1dd04,0x7a9b95b5),LL(0x5f0b1d7c,0xcc149a8d),LL(0x47a50eec,0xbba40e4d),LL(0x56b72539,0x4e635d70), + LL(0xb18659c4,0x31c40e90),LL(0x6f694b35,0x08026224),LL(0xe0cd6e15,0x8ed3d7b8),LL(0x9293cb36,0x157e2a9d), LL(0x96e54583,0x7b457bb1),LL(0x2609c44d,0x75647498),LL(0x970a8cf2,0x54667671),LL(0x3af72572,0x3b7da9c8), + LL(0x4d63473a,0x8fbba977),LL(0x23001221,0x7af5af43),LL(0xea29d97e,0x99093197),LL(0xfa564089,0x4409f6a9), LL(0x2f70e06f,0x64fd1cda),LL(0x2e9d55ea,0x8b7c83a6),LL(0x6385fcef,0x0dffbe4b),LL(0x7a6fe72d,0x4513f584), + LL(0xba1de4ae,0x6a64f166),LL(0x89069fbd,0x1f8550a9),LL(0xda7ef7fc,0x72b411fd),LL(0x829ea712,0xa185d2c3), LL(0xccc1868d,0x82f5ffb8),LL(0xff9fafa9,0xb484473a),LL(0x089132ed,0xe1857f3c),LL(0x08ef378f,0xdad885a9), + LL(0x7af9e2aa,0xbdbdfc0e),LL(0x95486202,0x366c07bb),LL(0xfc9d979f,0x37040d45),LL(0xa0f80630,0xf279ed10), LL(0x8f31b39c,0x27855261),LL(0xf26f91cb,0xea0c3b1c),LL(0xb38c050f,0x90b4e8c2),LL(0x1623ab47,0x7acb26b1), + LL(0xa4a064d2,0xb6cc3cd9),LL(0x97245482,0xa410880c),LL(0x3a6e6a1f,0xfb470e11),LL(0x93f347e4,0xf19080b1), LL(0xb75a53d9,0x23253dcf),LL(0x9c95d567,0x55047049),LL(0x7b20202a,0x8c75631e),LL(0x834b8380,0x58fccf32), + LL(0x243dddde,0xaf6bdbd8),LL(0xcf38f705,0xa3ca3e2c),LL(0xca38c9a2,0xa2357b4b),LL(0x6eba095b,0x8bf0d270), LL(0x9d998070,0xe4a43b7c),LL(0x8469214c,0xdf412faa),LL(0x000f1802,0xd2578cc4),LL(0xf8515863,0x2feb563f), + LL(0x5022112c,0xe66ce02a),LL(0x1461b1c6,0x8415df81),LL(0xad247c38,0xc2546e6a),LL(0x9a9c74d6,0x4b9788e6), LL(0xa22be3e8,0x9d0cb2e0),LL(0x295f76ad,0x15db086c),LL(0xa2337670,0x9758f99b),LL(0x9ab57f54,0x61ae09bb), + LL(0x93926a37,0x7af4d4aa),LL(0xf25cadb4,0xa895f386),LL(0xc6f4f514,0x90e13821),LL(0x4eef97ab,0x46738d95), LL(0xf0b479a2,0x66f559f3),LL(0x3262fb2b,0x9ea62dcd),LL(0x6a857025,0x91a39a5e),LL(0xbb3e6e11,0x11bdd19a), + LL(0x9353cc19,0xfa411fd6),LL(0x94cd2276,0x275d094c),LL(0x25243d1b,0xe2069b22),LL(0x630c8cbc,0x9f02f1e2), LL(0x379b6b63,0x85c942fd),LL(0xbdcc9307,0x293dcf87),LL(0xdc212ca8,0x56856d8e),LL(0x23a0c56d,0x1927e931), + LL(0x9c2f8b66,0xacfed288),LL(0x386ad1e3,0x20f6b94e),LL(0xdcbeff77,0x0e622304),LL(0x5978f2f6,0x67e895fa), LL(0x20029bfe,0x12a63bde),LL(0x8d968b8c,0x0ed75b6c),LL(0x57cec33e,0x611739ee),LL(0x42b9fc44,0xeffaae72), + LL(0x971a90a9,0xa7de79ce),LL(0x4fead0d5,0x529bd8a2),LL(0x9a1a43ef,0x78434c30),LL(0x4f3c848c,0x904d1db2), LL(0x6d4234ad,0xedb3c11e),LL(0x5975e9a0,0x4e0c9ec4),LL(0xff16ec74,0xc51236db),LL(0x36d09231,0xde652cff), + LL(0xe60a0bc5,0x0d7c18b7),LL(0x9d7df012,0xaf041383),LL(0x47d4cfd0,0x9c0ff3f4),LL(0x3d97bac7,0x64c7e6c2), LL(0x8cb44d50,0x239d2500),LL(0xbba96026,0x47189764),LL(0x31ddca37,0x22449328),LL(0xfb7c29ef,0xa53a1886), + LL(0x97a3789b,0x2515b665),LL(0x540ea258,0x825c5031),LL(0x09a5b24b,0x76680656),LL(0x60fb8bcc,0x833c240f), LL(0x01e55cc7,0x758e0b10),LL(0x8d260572,0x8b799c48),LL(0x6c5dd0cd,0x0981a802),LL(0x1b9c6cc9,0x6f6da55d), + LL(0x8c4d503a,0x3457b685),LL(0x009a7a94,0xc537730f),LL(0xd01dfdff,0x334d46b4),LL(0x15e20bc7,0x3e5dc6a8), LL(0x6ce8b8ab,0x1833b0bf),LL(0xc57a4292,0xe21b99ae),LL(0x1713ba15,0x743cb595),LL(0xe0bb44a7,0x550e41bc), + LL(0x2f8ebcf5,0xf356917a),LL(0x953f056c,0x6f2c400b),LL(0xdd84bb48,0x09d9ac41),LL(0xa61e98e3,0x50dc7a8e), LL(0x3d3a6776,0x1179a9d3),LL(0x16de8b3e,0xdda312e7),LL(0xce6e2bea,0x62a8b7c3),LL(0x645e4ca0,0x2b00036c), +}, +/* digit=16 base_pwr=2^112 */ +{ + LL(0xab6cf0b4,0x9ad2cbd7),LL(0xf13d1ddf,0x7a1e67f4),LL(0x746003ba,0xa58f0c73),LL(0xa64a8fcc,0x8263e888), LL(0xbe2452f7,0x535cbe37),LL(0x6ae81a76,0x93125766),LL(0x3a553701,0x7d2ed0ab),LL(0xb0717d78,0x93d7e7df), + LL(0xf9cf03ba,0x61bc013c),LL(0xfeee3a78,0x36223b88),LL(0x3d7e4c95,0x86efc923),LL(0x965625e4,0xaf3801be), LL(0x3f32fd9d,0xa7bba141),LL(0x4e564acb,0x70724dec),LL(0xb7edcac1,0x52587f32),LL(0xb3969985,0x0b1cd94c), + LL(0x661fbdab,0x9f08407a),LL(0x58e52151,0xc4d7c536),LL(0x63dfe954,0xa3765bce),LL(0xac2dddd1,0xc6829bfb), LL(0xdc6e4487,0x97393f65),LL(0xbf04c930,0x9ba29422),LL(0x18838c0a,0x493c6914),LL(0x4b2f35cd,0x41b137ff), + LL(0x4e1c5e60,0xc9e4aa24),LL(0x13253d51,0x54bb5289),LL(0x9bbabe53,0xf4a86ab3),LL(0x6ac0aa64,0xd561feae), LL(0x1911bad7,0x27a896ab),LL(0x64337303,0x9cb22b98),LL(0x161f6928,0xf14262fb),LL(0x59ba6c9f,0x1661885c), + LL(0xb82574db,0x4666ebd3),LL(0x8d8af3f6,0xc5e86672),LL(0x209319bf,0xcc645205),LL(0x3834d1a8,0xc183c12e), LL(0x49eb0f40,0x533d73da),LL(0x6aca649e,0x3bcab0bc),LL(0xe39e8361,0xa02f4c41),LL(0xa89bdc85,0x2391e7ae), + LL(0x608cbe2f,0x88067c5e),LL(0xf16c22f2,0xcdec82f6),LL(0xf1faf9dc,0x80aa719a),LL(0x2340185c,0x261fe951), LL(0x9713e72e,0xcb411366),LL(0x6d8a2a46,0xdb1e405e),LL(0x11106ce0,0xed174757),LL(0xf71c0e69,0x6d70cf6e), + LL(0xcf707c76,0xb5310322),LL(0x40b4b7d7,0x3a1eb2ff),LL(0xb1a2d26d,0xb83259fb),LL(0x799720c0,0xa83ffb0f), LL(0x0bedb326,0xeecb1928),LL(0xe9271715,0x4473e820),LL(0x2f2d71a9,0x506e6d20),LL(0x4319756d,0xe7b253b1), + LL(0xf576cb3c,0x27e19335),LL(0xdfb3b78f,0xe16e4573),LL(0x63da0001,0xaf96d785),LL(0xf7444c5e,0xb38deafd), LL(0xc0eb0e28,0xaca6b38c),LL(0x7fe41b98,0xa6ca3541),LL(0x18965b31,0xfeb37b47),LL(0x597d5bc6,0x739cc322), + LL(0x4cb1fbc3,0x82776041),LL(0x8e2a3ad1,0xcdaa873d),LL(0xc01318bf,0xb5f87b34),LL(0x229cb81e,0x0c692268), LL(0xa53089f5,0xb0724016),LL(0x05415313,0xb2976a53),LL(0xcee8fdf2,0x436eab75),LL(0xd82b13e5,0x8794e1a6), + LL(0xd5516e3d,0x0d51a072),LL(0x4b2fdb3c,0x7bae61ce),LL(0x550728ee,0x0d987e89),LL(0xee6778db,0xfd5a656e), LL(0xbb4d9d7a,0x942ee623),LL(0x2dc1baf8,0xfc06d64b),LL(0x47c3dc8e,0x5244fcd8),LL(0x8568653e,0x5e37e156), + LL(0x048c8355,0xe5c2c6ff),LL(0xa0474046,0x480872ec),LL(0x7ff92484,0x67e3089d),LL(0x29971b3e,0xdc071893), LL(0x5a63e8ad,0x3857db2b),LL(0x5f2e0a09,0xf617d94e),LL(0x5844de79,0x267e9818),LL(0x861f5f92,0xfdb103b2), + LL(0x1570d6e9,0xb969bd3c),LL(0xe0fb517e,0x7350b9db),LL(0x55aa543b,0x083b142e),LL(0xaa2bc581,0x424757be), LL(0x69ea3302,0x4bd50f64),LL(0xed4c8288,0x053dcf83),LL(0xc118ac52,0xac2b3074),LL(0xe76ca88b,0x57f066a8), + LL(0x0a3207cb,0xb9ac28fd),LL(0x205829b0,0x0ec2ad13),LL(0x4f403b64,0x76216e56),LL(0x6621dd5c,0x7eaef662), LL(0x4b06ac54,0x9e0cc836),LL(0x9648523c,0x16ac3c6c),LL(0x08eec1d8,0xe1208a1a),LL(0xbe054a54,0x1e90b3a2), + LL(0x23a836cb,0xdfab7f92),LL(0x6f7674c8,0x624d6bd2),LL(0xea06210a,0xc34a914c),LL(0xf26c4f23,0xba5314ec), LL(0xa33a11cd,0xd440b196),LL(0x75eb951f,0xf81ab63e),LL(0x39350f0c,0x05ebb91a),LL(0x92e9528f,0x3f3c08ec), + LL(0x4fe6f4e6,0x54ff8844),LL(0x79b7ba49,0x217c0e02),LL(0xbf3a4179,0x13c4372b),LL(0xa1434264,0x6e5ad10b), LL(0x62bd8ff2,0xc8426540),LL(0x85fe6ef1,0x7c3dd284),LL(0x05da0e84,0x2c59b300),LL(0x17468e18,0xf303ed94), + LL(0xa211ffd3,0xe19fac99),LL(0x3f1f6bca,0x408f9424),LL(0xa5648244,0x1f5b76d1),LL(0x95b2bd67,0xef3942e8), LL(0xb538f1d7,0x1b9dee7f),LL(0x444b8f85,0x1cb78620),LL(0xcb8ea6a3,0x9f8ecd63),LL(0xb9d3b71f,0xca111b2e), + LL(0xbdc4e8e2,0xff83d71e),LL(0x3f76a9d5,0x43745ddb),LL(0xa25856ee,0x72db22a9),LL(0x5e9a9ff7,0xf34d5aa2), LL(0xbc529902,0x01f6b5f3),LL(0x086f4867,0xadf5d31e),LL(0xca556b56,0xbd88674f),LL(0xfdc81625,0xfd00120d), + LL(0xfdde77f6,0x90fbaba0),LL(0x559ec6e7,0x266d3bfe),LL(0xc8094357,0x372acf54),LL(0x6c61bb78,0x772bd8e4), LL(0x1af9aefc,0xcb2ac592),LL(0x5b178386,0xacc3dc9b),LL(0x23438463,0x09963084),LL(0x8359f1e6,0xae84f973), + LL(0xa4cee642,0xc3b19aa0),LL(0xb19a918f,0xcd5ca5c8),LL(0xe67cb207,0x46ac0d2e),LL(0x73ffebf2,0x2ae45e10), LL(0x10ef065c,0xf84aad8e),LL(0x32a7e903,0xa0af57fa),LL(0x43d346dc,0x42295904),LL(0x7f170965,0x8d6f711d), + LL(0xb110cffe,0x11aa7070),LL(0x9755605d,0x091a100d),LL(0xd27d86a6,0xc5a0c654),LL(0xdb30feaa,0x1031a244), LL(0xc02228d9,0x36804045),LL(0x8b746039,0x1877fc67),LL(0xe09bb238,0xba554015),LL(0x1de9b40d,0xc50d8f92), + LL(0x032f7a2c,0x29e40d88),LL(0x1d315ec2,0x514b56dd),LL(0x61778f04,0x9052652e),LL(0xe1a1c195,0x0d2bc606), LL(0xb05043ae,0x375fd7ec),LL(0x6eba4d1b,0x03b82577),LL(0xc349b39a,0x8e61b567),LL(0xb35fc43b,0xa670973a), + LL(0x5571b4a7,0x80c05ca7),LL(0x8a4af0ba,0x95d14f49),LL(0x67bf4290,0x96767cdb),LL(0x46870ef1,0xb293372f), LL(0x1afe1027,0xc6494405),LL(0x9019c4c2,0x9f027a1c),LL(0x188a593a,0xa392ac59),LL(0xfcb6e1ca,0x68acca2f), + LL(0x68ed921b,0xd8f86cbe),LL(0x712d2c07,0x24679ac2),LL(0x4e672cd9,0x18fbdb21),LL(0x51d1f8e1,0x401bb718), LL(0xaa8da4a1,0x688792e1),LL(0x3ca93d06,0xedf9266f),LL(0xaed484df,0x5ddba14a),LL(0xb0ea10a5,0xa5dab102), + LL(0x833396ea,0xd397edcd),LL(0xed5e6747,0x78a75693),LL(0x1a5f8260,0xf2c844ba),LL(0x5fb9fec5,0xbcafe59d), LL(0xd3147e7e,0xa2413d5f),LL(0xafdf26cd,0x130dd9e3),LL(0x9ad1abde,0x44be87ec),LL(0x6e77fbe8,0xe925c495), + LL(0xf26ced16,0x07ce8d96),LL(0x86ef7306,0x36c85643),LL(0xc7e3d409,0x62545902),LL(0x2ed4d38e,0x1747bf4a), LL(0x55adc839,0x6fe6fc3d),LL(0x8eaf64a8,0x20a3cc09),LL(0x622887b1,0xc1e9b766),LL(0xc41ac659,0x7b9d2f96), + LL(0xf2a65e45,0xfdb897ce),LL(0x97889eb8,0x0c09c905),LL(0xe4becf5b,0xa15df10f),LL(0xccef7e40,0x14a3d4fe), LL(0xa8fc67bd,0xedaa11f6),LL(0x5d185b42,0x7bf6fe9b),LL(0x6f9cb5c9,0x7bb9f1f5),LL(0xf97ea9cd,0x1b4ab74e), + LL(0x07638d62,0xe9ebf11d),LL(0xa78cf538,0x413a4a87),LL(0x570dd371,0x93785f86),LL(0xfb48063c,0xba431a91), LL(0x4ed4e5fa,0xf1f2ea5b),LL(0x5308325a,0x91a72c47),LL(0xc9ea6acb,0x4e6518e7),LL(0x208f67e3,0xfeaf4c3c), + LL(0x2c16bb1a,0x98c5d768),LL(0xee31dc08,0xbf91b62d),LL(0x33a54959,0xe9ad408d),LL(0x38b7170b,0x9d754a64), LL(0xd9d6da2b,0x106db7bc),LL(0xadd533af,0xf556cbb4),LL(0xf16d3b58,0x62db0de0),LL(0x1fa579ba,0x78a1b0be), + LL(0x7b552058,0xda96740b),LL(0x626c4d93,0x0c689cc6),LL(0xaf68e53b,0xee3dd5c9),LL(0x134d763b,0x78653a9f), LL(0x3ca5aa67,0xec9c1b72),LL(0x7d56992e,0x67471dac),LL(0xad1d8580,0x0a97dffe),LL(0x0063c040,0x11c7d93d), + LL(0x6e90b157,0xb79e355c),LL(0xd9c894c4,0x2c06edcb),LL(0x71a75ed7,0x9b931897),LL(0x8e95ad91,0xd7f00247), LL(0xb85bf054,0xfce1b489),LL(0x503b38bf,0xa3ffb8fd),LL(0xe0fe2ec9,0xe7ea3ad4),LL(0x0049865d,0x0f32f520), + LL(0xcff21b51,0x33afa324),LL(0x62a1cd24,0x3d6847d7),LL(0x0b06ce2f,0xf534e159),LL(0xae7cdae0,0x24d27b3d), LL(0x4ad68ab5,0xb727db29),LL(0xb63c0bc9,0x7e8e47e3),LL(0x02389039,0xe81f3122),LL(0x88e6a17c,0x0c281f52), + LL(0x091e1c4c,0x3cc00e21),LL(0x867ccc75,0xd500db44),LL(0xf5ebbbe4,0xa8e2e84b),LL(0xc4279ac0,0xc3266881), LL(0x7a170658,0x2e8fb4de),LL(0x51da4a2e,0x219c5ec1),LL(0xeeacee19,0xda69a3fd),LL(0x30462243,0x9d4c6fbd), + LL(0xa978c29e,0x43673fe8),LL(0x5861bbc1,0x6e825c95),LL(0xdba8e7ba,0xb41d1435),LL(0xb885d004,0x0f286f78), LL(0xee57436f,0xea42b7fd),LL(0xef7e29c7,0xcdae14bc),LL(0x24251056,0x50cff3f0),LL(0x6f6e8cb1,0xf60809fe), + LL(0x12932e53,0xee9f1d15),LL(0x167d5097,0xa6e55cd6),LL(0x9d926359,0x5df8816d),LL(0x797b7eca,0x108e2117), LL(0x91921587,0x7ba20319),LL(0xad23652e,0x304138e4),LL(0x51ebc32f,0x73d0ed57),LL(0xf01d0fc3,0xe0c10a38), + LL(0x78c49b19,0x14c6b72f),LL(0x3b7c7418,0x4f952b7e),LL(0xa2d019bf,0x3fe75d21),LL(0x7ca33e87,0x4837bfd2), LL(0x3946e7ea,0x4597729b),LL(0x4c37ea10,0xbe22c14a),LL(0xd7909474,0x91106c7c),LL(0xbf5551a1,0xfbf1e7db), + LL(0x55ffea13,0x8e06336c),LL(0x0a1f99f5,0x0deaeda0),LL(0xfda98fc9,0x9b738c4b),LL(0xa59c98ba,0x061cc613), LL(0xb477692c,0x5ceb5b83),LL(0x1fcc473b,0x5db77559),LL(0x83df476c,0x77214b62),LL(0x427ea01d,0x2ffac971), + LL(0x49fd0ba7,0xf29f600b),LL(0x7233ef79,0x1106f8b2),LL(0xe8a0ca35,0x706bc171),LL(0xacbff08b,0x4da7a9e6), LL(0x7725f97c,0x17c2fa4e),LL(0xe84a5095,0xab459314),LL(0x6b24d47e,0x01556f14),LL(0xb016dc1a,0x01399059), + LL(0x28eca6c6,0x154b84c7),LL(0xd9084e68,0x88ed8612),LL(0x00bf9b5b,0x4dfd5080),LL(0xba9a0cca,0x853cd8ab), LL(0x8af0e94b,0x8cbf9bd8),LL(0x83035d16,0x50782b73),LL(0x4f44533c,0x694d3e65),LL(0xa6e534eb,0x155d4bf4), + LL(0xee908b6b,0x9028e2ab),LL(0xa6743060,0x36e5aac0),LL(0x3c37d6f1,0xd26f5a51),LL(0x33729b9e,0x8483703e), LL(0x2e5f82a5,0xf27a6603),LL(0xca55d187,0x33bf2bdc),LL(0x7724a85f,0x894c415c),LL(0xa2ea178d,0x9255d416), + LL(0x0a6dc5b9,0x35ecb4e2),LL(0x51c54ed2,0x8b3fc2c8),LL(0x9eede13d,0x059f86eb),LL(0x791dd5eb,0xa796c750), LL(0xea88555b,0xb2f33680),LL(0x1245348c,0x92730950),LL(0xd1e63bfb,0x1a5545f8),LL(0xbebb7858,0xfebc9a14), + LL(0x6bdf0c84,0x13cce767),LL(0xa1d341fa,0x1aa9dc07),LL(0x1ee6fa43,0xd46e8ff6),LL(0x4b1dda64,0x4198e5d6), LL(0x2782abd1,0xe82a8134),LL(0xb6d64830,0xe6f7b1b4),LL(0x7f0fb374,0xabe00274),LL(0x7494d7d3,0xf1a8e2b7), + LL(0xf274f296,0xd16b0d9e),LL(0x65246ee9,0x3c94a7ac),LL(0x91ec2262,0xd32c32da),LL(0x83116ec1,0x04c7bb90), LL(0x78524a06,0x70fa0406),LL(0x07df8064,0x8d2d5176),LL(0xe2c8d48a,0x13e589f2),LL(0x122aed4e,0x3b110ac4), + LL(0x34e972cf,0xe8e0eb52),LL(0xfb3a77fe,0xc082944a),LL(0x6a32c23b,0xcdaff7a3),LL(0xc37b4a2c,0x88cc568d), LL(0xe27b2552,0xc9979a9c),LL(0xd6ef51f9,0x8612ae7d),LL(0xef4e8f85,0x7bf0f937),LL(0x3f12d45c,0x2f360a58), + LL(0x9b336663,0x3ec9d0e3),LL(0xb1438d2b,0x5ac2df38),LL(0xff93fde4,0x7f2de910),LL(0xd92534ba,0xbbc460da), LL(0x59a94ab9,0x74de3159),LL(0xc45b80dc,0xd51cfd32),LL(0x6e5b2397,0x9f1f349c),LL(0x995f7271,0xbdbd16ed), + LL(0xf59709a6,0x4a7efc1c),LL(0x4b3db99a,0x74e2760d),LL(0x7726a2e1,0xa7238e9e),LL(0x1a376013,0x47764208), LL(0x7e33ebc0,0xbc96f396),LL(0xc9e4ec0d,0x31e159e6),LL(0x6a2ab9f6,0x26a5aef2),LL(0x320eeea7,0x23add07c), + LL(0x833b45b6,0xa79a97c9),LL(0xc51885e6,0xb08da907),LL(0xae8d5659,0x23f5e651),LL(0x1faff2f2,0x1eb0be48), LL(0xa1e090da,0xe414ee3d),LL(0x7fcb664f,0x16e4f8fa),LL(0x98c36865,0x7a15a7e4),LL(0xaf89dacf,0xea60e8fd), + LL(0x86c1a4b4,0x4e009f45),LL(0x769644ad,0x78c1bebf),LL(0x0b4b3501,0xa41b480f),LL(0x57f0a0e9,0x98be5037), LL(0x3af24657,0x06934887),LL(0x2b6260f9,0xe2503ddb),LL(0xd1d0caaa,0x37c936c2),LL(0x16431f50,0xd371e991), + LL(0x6087c5e5,0xd9621d16),LL(0xc53a8bc5,0xae49c2ce),LL(0xcad314cd,0xd7868882),LL(0xaa57af18,0xfde10dc7), LL(0x3800f397,0x3fa8a60d),LL(0x388b333c,0xcec8ae7b),LL(0x85fa8129,0xefd8d692),LL(0x90776c32,0x33d5685b), + LL(0x65971a6e,0x47ecec0a),LL(0xad7c5755,0xe8a20bbe),LL(0x87372016,0xbeed0a4d),LL(0x1d9b8dc0,0xd0d499bb), LL(0x2800907d,0xf4ce27cd),LL(0x8622bbb7,0x07a30b77),LL(0x77e264db,0x7532f435),LL(0xd64f0710,0xfdd1a9c3), + LL(0xa6543720,0x92ca210f),LL(0x5bb6985a,0x2f19ed66),LL(0xf9399b43,0x08a4ac61),LL(0x757f241d,0x0b7bac5d), LL(0x3763c20d,0x93ef27cc),LL(0xa86b1f05,0xda3b206e),LL(0xd62467c0,0x8f19c74a),LL(0x6a3ad263,0x3ec5ef6d), + LL(0x2bc8b9f0,0x249aa636),LL(0x7f70990c,0x0fca7318),LL(0x6f038497,0x6d4aabc5),LL(0x5afaaaef,0x4647f72b), LL(0x7bf90444,0xc7cbe03a),LL(0xcac2efb0,0x6beb69ac),LL(0xbb3c6dc0,0x58544eba),LL(0x96aefc2f,0x569cdcd6), + LL(0x5e4c950d,0x2e8a4c57),LL(0x4dd32002,0x6f5341d7),LL(0x6efa5908,0xd0345db6),LL(0xf1d2bbe6,0x4b043197), LL(0xe8730bae,0xde8a4cb6),LL(0xa485cb62,0x9a89231f),LL(0xfcd9bcd4,0xb24ace89),LL(0x3ed5801d,0x01892cc0), + LL(0x413408f9,0x80ce2f30),LL(0xf8773b6a,0xaf67343a),LL(0xdd6ade17,0x91acc6d2),LL(0xe5eb3def,0x9d2ffeca), LL(0x50b029fd,0x72f8af06),LL(0x79c0aabd,0x339c802c),LL(0xafc0a6ad,0x46161fff),LL(0xbac9a2d4,0x1046d9f8), + LL(0xab920e51,0x2f12eb06),LL(0x2892e552,0xfc004900),LL(0x13e61154,0x9aadf93e),LL(0xabcfd127,0x4468da94), LL(0x152f220e,0x6a5d3ffe),LL(0x4737fe79,0xe6260c23),LL(0x5e6b4251,0x8b5dd1c9),LL(0x9af02b98,0x044f0656), + LL(0xa97ff366,0x434d475c),LL(0x2c4bcc46,0xbae8db8e),LL(0xf9777251,0x2ba43a8b),LL(0xdd019f1a,0x7ff430a5), LL(0x630064ba,0x65e9f290),LL(0x7e871c0e,0xfc57a54e),LL(0x5791ae48,0x54107bbb),LL(0x5c334de0,0xdfce137f), + LL(0xaed5be73,0xab65c8f6),LL(0x174bf00b,0x838c3958),LL(0xf1c7e594,0x27c57199),LL(0x0d02fae6,0x62643d81), LL(0x5f4431fa,0xc1e70c12),LL(0xb2b41f7e,0xfac86124),LL(0xf0108e3c,0x062ac35a),LL(0xa43d3a28,0xd7d34dfc), + LL(0x3143de4d,0xc40fb44a),LL(0xd2e0f9ae,0x06eac4ed),LL(0x95d9a69a,0x998f3211),LL(0xe950bd2e,0xb268f6a0), LL(0x1e9d4e40,0xadfab210),LL(0x73ce9324,0xc453a68c),LL(0x80881171,0x5e2f2544),LL(0xee7e543e,0xe4f596db), + LL(0x76b6698e,0x77f48e4e),LL(0x227365c6,0x47b5165f),LL(0x14ef39e6,0xf56ec8d4),LL(0x74ce46fa,0x1638d647), LL(0x08aa8b9a,0x244d0fac),LL(0x298326c9,0x98ccc4d0),LL(0xce0d2983,0x492d7661),LL(0x73158cda,0x728b3e3f), + LL(0xc4948011,0x7959ca67),LL(0x08425a38,0x32044ae9),LL(0xb1070c2b,0x05a7a6a7),LL(0xcc129ba5,0x34ed541f), LL(0xb2f1c3e2,0x4b6bf65c),LL(0xd0d8aec8,0x6f090ce6),LL(0xd4fe39c1,0x11ade23a),LL(0xa5a35528,0x50510c08), + LL(0xad6fd7c6,0xb7e2a5de),LL(0x2745dca8,0x9d691939),LL(0xad053184,0xff669c38),LL(0xecd0703e,0x394ca6b7), LL(0x60b15e75,0x59e32e80),LL(0x13c14864,0x82dde889),LL(0x64d4f086,0x0fd1624c),LL(0xc9893d7f,0x7fb502a7), + LL(0x711479a1,0x59b86bcf),LL(0xc40b44bc,0xfd4bc4d8),LL(0x988100c3,0x2fae18f5),LL(0x615867d7,0xe4af2f4f), LL(0xbe479e28,0x7d45e1e8),LL(0xa04798a5,0x547accbd),LL(0x1c458b5e,0xe88a85b1),LL(0x6032f0cc,0xe144f7f2), + LL(0x3f807365,0xad5276d3),LL(0xb318a6ea,0x5b6519e7),LL(0x2d0fcf50,0x5889cbb5),LL(0x2bdab4e0,0xdce91cab), LL(0x41b78954,0x17b6249f),LL(0x6f10449b,0xc9320b65),LL(0xf264ae8f,0xe38a7cc0),LL(0x52b85829,0xaab8803e), + LL(0xdd97973c,0x63668621),LL(0xd04138c7,0x5aaedce7),LL(0x1762874c,0x8e8e6614),LL(0x163fc862,0xd0cefcf4), LL(0xffed1ace,0x0ebe0048),LL(0x7a8c2673,0x070c3348),LL(0x9b0d3fd7,0xb801d159),LL(0x922d4842,0xf1d55911), + LL(0x680dcbf9,0xf0acf768),LL(0x4f0a51df,0x5072b825),LL(0xd88df9c5,0x3a74751c),LL(0x1cc1a332,0x9d20f989), LL(0x6926c34a,0x4e90042b),LL(0x00766880,0x5c728b1e),LL(0xf76e9dcb,0xf2e3bfe8),LL(0x15a125ae,0xd9822f0a), +}, +/* digit=17 base_pwr=2^119 */ +{ + LL(0xf51b14b0,0xbf84db58),LL(0xa39a79f0,0xdf73ccf5),LL(0x2b5a1f11,0x0ce1e584),LL(0x185fc400,0x841fa6a3), LL(0x2455c32a,0x94b09c68),LL(0xbfa71cc3,0x383c9bde),LL(0x1e797929,0xb6381486),LL(0x623d0a5d,0x33036faf), + LL(0x90f17cba,0x41b6cf7c),LL(0x30c7c5f4,0x5d655ff4),LL(0x4ccc7f38,0xc64f29d5),LL(0x6124a79e,0xf28e8531), LL(0x67bf1e98,0x1efa8d51),LL(0x5d7a33b0,0x8610027f),LL(0xcb9a40a4,0x35fe2bb2),LL(0x43d50a0b,0xc5cc1bf1), + LL(0x46e33870,0x84dbc605),LL(0x843c4e1e,0x23d8d2e5),LL(0x4cf8b569,0x69964b5e),LL(0xe0c546a5,0x2a5228e8), LL(0x96d6e111,0x4c0467ed),LL(0xa12bd298,0x25764cdf),LL(0xfbaaad46,0x92a3e7fa),LL(0xd12fa469,0x08ac1d36), + LL(0xa32106c2,0x60ae2bbf),LL(0x3e917750,0xef155b2a),LL(0x13853a30,0x5567c3c7),LL(0xeddb305b,0xa6be8290), LL(0xade26eec,0x2db58c21),LL(0x003c17ed,0xfa3c895c),LL(0x6293f8a2,0x96ab0de1),LL(0xac3710c6,0xbd2365ec), + LL(0x6aa24f73,0x93ea8553),LL(0xe0410c40,0xf75140d0),LL(0xaff0f7f2,0x760cfa2f),LL(0x3e580d68,0xc6dfb3c7), LL(0xc16d39e2,0x25fc2091),LL(0x19e1d5e2,0xa05b0c81),LL(0x62bbec7a,0xd4d223d8),LL(0xf293f34a,0x11a93775), + LL(0xe194c642,0x9ab03e73),LL(0x789e3c85,0x607b7106),LL(0x4bdacd55,0x952aab02),LL(0x21cc6084,0x31ca3ee2), LL(0x1c6b93f9,0xd3149b2b),LL(0xead930f8,0xcbc5ef3b),LL(0x22872630,0xed04984f),LL(0x6c4b6fe2,0xef5d052d), + LL(0x6010ffa2,0x808ae6c0),LL(0x1143166a,0x88b6fcd8),LL(0x5ab945ec,0xa2780263),LL(0x36db5012,0x4777b4aa), LL(0x059aa3c7,0x2156bf83),LL(0x2a660260,0xcbef6fb7),LL(0x8b366ce5,0x189fa221),LL(0x08290914,0xd6f5bdaa), + LL(0x57028677,0xd2028d05),LL(0xce9aabdf,0x90eebeeb),LL(0x06d4e5d0,0xab977aee),LL(0xf9361873,0x7a98c527), LL(0xb7c2474d,0xe49b1251),LL(0x5f3e7b02,0xcdaf2a36),LL(0x6fe54af1,0x638bcaf4),LL(0x1dac06b7,0xfec42624), + LL(0x3741a88b,0x422be225),LL(0x5304f139,0x1f3b82c3),LL(0x181c2fc2,0x101eab8e),LL(0x5898163c,0x8522738e), LL(0x2d2bac1b,0x0372d05f),LL(0x1d1f3c42,0xb65c786c),LL(0x64e2f5b3,0xbd59694b),LL(0x24c5671b,0xf1c424bf), + LL(0x1eafe37b,0xda738cf5),LL(0x30dd7c2b,0x503eac24),LL(0x11dd77af,0xf9b7b7a5),LL(0xe9dcfe7c,0x0ade03af), LL(0xf479e3b5,0x489bd34a),LL(0x030a33f3,0x993ab403),LL(0x9fb64068,0xaef322bf),LL(0x0e27f110,0xa47cc71b), + LL(0xefab99c8,0x1c445554),LL(0xa7f10e58,0x7c3c51e7),LL(0x78a87474,0xaa8b43ee),LL(0x2418475a,0x037d6397), LL(0x10324911,0xc9c751fe),LL(0x3e0797d4,0x3d65d9e0),LL(0x7dea2a63,0x98b68d2b),LL(0xf4afca19,0xa211ed3b), + LL(0xc63b9e75,0xe19ff8f8),LL(0x0d7d130a,0x43f6b4fc),LL(0x7c8490b7,0xdba3385d),LL(0x0252c14a,0x97889df7), LL(0xb2f18b9f,0xfccfca86),LL(0xc3a87422,0xf092ff9e),LL(0x67474838,0xf96dd675),LL(0x5bad2e9f,0x039e8287), + LL(0x52e041f6,0x7ed85e70),LL(0xcfdeb19f,0x3d6ef1e7),LL(0x0d9ac66e,0x9f9fe399),LL(0x16cb8554,0x5825e7bf), LL(0xd954a4d5,0xecffdf90),LL(0x20678fc5,0x8617ffdd),LL(0x666df77b,0x3e974054),LL(0xb5d92788,0x748379d1), + LL(0x2da32c0a,0x46a60911),LL(0xb2676ca3,0xb2e1ac32),LL(0x17614dc6,0xfb74093f),LL(0x3f27f965,0xf44939e4), LL(0xc922422b,0x4656a402),LL(0x3ff5c56f,0xd60a55ba),LL(0xab9aa62e,0x0d061b41),LL(0xaca3acd2,0xc9ceacfe), + LL(0xd946003b,0x056d5718),LL(0x2c7815f3,0xf8530d6d),LL(0x706536b8,0xbae14342),LL(0x2b901188,0x45c96dda), LL(0xc64ed946,0x386d88b6),LL(0x6c00f1c2,0xb7017022),LL(0xec8988df,0x28519811),LL(0x5a05cffc,0x3b011fe2), + LL(0x515f954c,0x4f581d47),LL(0x7f470a40,0x145f925b),LL(0x736feaaf,0xfee6b6b0),LL(0x2ea5743b,0xf90744af), LL(0xa2f36f56,0x4d8e8cea),LL(0xe3ed4007,0x4239a6ce),LL(0xd515e6db,0x0906b5bd),LL(0x8ac973d1,0x53622990), + LL(0xeb2fe229,0x472ceb94),LL(0x6a121363,0x0775ed41),LL(0x761ddb38,0xc0492e07),LL(0xaef9be2f,0x80c24d51), LL(0xdcba73a1,0xa2a3982b),LL(0x4e26d062,0xe0d83978),LL(0xcd41c930,0x794959a8),LL(0x70131161,0x7d2a88d7), + LL(0xf4f966da,0x48f93fc3),LL(0xed5b6487,0xf92691a0),LL(0xada2c1fc,0xc5a93e5d),LL(0x4b7d9243,0x4a7aca52), LL(0xd7c5598b,0x810aba93),LL(0x25109638,0x98f9ead2),LL(0xa388481a,0xe8c6e893),LL(0xe91ce74b,0x56e96b9b), + LL(0xd935f591,0xfa1e5dc3),LL(0x555eb816,0x985bb06c),LL(0xc4d14e69,0x6478c518),LL(0xc7f47349,0x48afbdbc), LL(0x26fed96c,0xbde90933),LL(0xcd468186,0xf9b96f41),LL(0x730e8518,0x22de6a29),LL(0x915db842,0x7a3dc912), + LL(0xfc1f9449,0x8d13b665),LL(0xdd4bba75,0x6e9932a9),LL(0x564083da,0xa90ce8e5),LL(0xbbf7989d,0x8a7cf362), LL(0x1b07ee2f,0x652eccb7),LL(0x6857a141,0x0c0dcf1a),LL(0xb7bfb43e,0xa87ec410),LL(0x82b8d179,0xaebdb7e7), + LL(0x625a24dd,0xeb3bc468),LL(0x463b1f89,0x7e45e47b),LL(0x00c75a48,0xc3013535),LL(0x13778807,0xafea920d), LL(0x22dcef16,0x0d1e9277),LL(0x86cecfd6,0xa2a10f67),LL(0xd7160bf2,0xad40e29c),LL(0xeac1265e,0xe78e6589), + LL(0x0c62c041,0xd3a24310),LL(0x6c03c747,0x4d27344a),LL(0x7d3ee9d1,0x0b19e4a6),LL(0xcd90de33,0x9cf2eccd), LL(0xfda636a9,0x673a9d1f),LL(0xa86ee501,0xb7349981),LL(0xe43766ed,0x11ca1e49),LL(0xe3ff3b08,0x0806af6f), + LL(0x8a01f119,0x21304338),LL(0xf3cb268f,0x58a6d3be),LL(0xe37d7851,0x40ceacca),LL(0xef5b81e8,0x18694595), LL(0x84bad32a,0x35678ed7),LL(0xd1624256,0x4f280f92),LL(0xfb28709c,0xdecb1f1e),LL(0x164911d7,0x2a7f3048), + LL(0x579d8a41,0x32551d31),LL(0x60a5ee33,0x754c7c24),LL(0x6a88f85f,0x2c53fbff),LL(0x2c7a36a0,0x6ad0bda7), LL(0x15724d6c,0x8b3674f8),LL(0xb9b7b34a,0x614727ce),LL(0x82ca9cd7,0x384fba98),LL(0x0c566025,0x8ef4343c), + LL(0x64886c98,0x5645fefb),LL(0x0f5c29e8,0x702befb3),LL(0x46de1523,0x6d74a7e0),LL(0xb1302163,0xcb2bcdb9), LL(0xab4ca69b,0xe65cff39),LL(0xf2d4f6ec,0xeacb7103),LL(0x1770d3ef,0x15826c2d),LL(0x3f710600,0x38b008f1), + LL(0x4bc7dccb,0xc68450cb),LL(0x9e5f2400,0xb5f11b26),LL(0x9c3a833b,0x2af58e9e),LL(0xa058abaa,0xb60e2672), LL(0x75b080c0,0xe891bf8c),LL(0x2434bf38,0x5b09b276),LL(0x700b8739,0x0d90a040),LL(0xe69f4a0b,0x995cb042), + LL(0x44a56b84,0xe30df0a1),LL(0x1ead5a62,0xbaf92d16),LL(0x6e0193a4,0xe214a062),LL(0xe9758b9e,0xd41de5bc), LL(0x732d82d5,0xcf214213),LL(0xf949f07b,0xaa1421f6),LL(0xf7fb101c,0x5f38c91e),LL(0x2a3e41e4,0x47ce2ec2), + LL(0x240c7897,0x6bb34768),LL(0x7b45473e,0x80ff54ea),LL(0x82fe5aac,0x16acd40f),LL(0x4350449f,0xa3e76f52), LL(0xacacbeb9,0xf7a3579e),LL(0x7bc40732,0x9791e0e0),LL(0xbc58cb9d,0xb26da7b5),LL(0x987e18f4,0x11d9fc80), + LL(0x1d8e0d34,0xc3c189a8),LL(0x2d42e0b5,0x3011097c),LL(0x94ab9371,0x4e385932),LL(0x0c237147,0x79e0c2ce), LL(0x7172e6ce,0xc9f17122),LL(0x9b89a008,0xf8d73b1d),LL(0xa945995d,0x91690c6b),LL(0xc15306c6,0x089eb941), + LL(0x12ac8df5,0xee5f526d),LL(0x3bf94c65,0xf1dd23f7),LL(0x81a3cb0e,0x594ceaac),LL(0x9757cc8b,0x07d41d3b), LL(0xfc5603d5,0x9eb0081d),LL(0x57bd230c,0xfb5d3298),LL(0xcde3f845,0xf2c0402e),LL(0x41e8aba6,0xa2defd67), + LL(0x2dd9573d,0xb300802a),LL(0x60c1ded3,0x64e401a5),LL(0x8ab1d3d8,0x19d4a677),LL(0xcca04f74,0x3c2092f2), LL(0xac40056a,0xf4827ba5),LL(0x9c09ddc2,0x49d4cf22),LL(0xdbf20277,0xb2b00f6b),LL(0x5b281e9b,0xc9ac48d4), + LL(0x32efbbce,0x648d6674),LL(0xe9639719,0x64a6c2b3),LL(0x30662e7d,0x38c04657),LL(0x352c9184,0x15d1d7ca), LL(0xcc3020cc,0x70e8630c),LL(0xb09f038f,0xe4b56c9c),LL(0xfe76a744,0xdb9cb5ed),LL(0x6947b988,0x4c85f020), + LL(0x29d8add4,0x7e500126),LL(0xbfaf6d7e,0xdbcfd295),LL(0x38df80be,0xc1a1c228),LL(0xf606ce3d,0xcfa6272a), LL(0x8e0af540,0xbf2a5720),LL(0x5b599ab0,0xb9c544fd),LL(0xd0a22c9a,0xd6dc994d),LL(0xd23e4c0e,0xa8a12acf), + LL(0xba588a5e,0x41f7ac85),LL(0xccdb9687,0x5425fa00),LL(0xec9398f0,0x12fbce76),LL(0x4f550b9b,0x2ad69251), LL(0xbb318636,0x120ff0f2),LL(0x01ecd90b,0x9378346c),LL(0xd0ba149b,0x1b98fe99),LL(0xc9c481c8,0xd69d5462), + LL(0x959e428e,0x11c79184),LL(0xcff227cc,0x9de61a8d),LL(0x1e09b860,0x144dfdcd),LL(0xf8ebe350,0x110c3a47), LL(0xfadf86b0,0x59e574dc),LL(0xcf3b8d30,0xe6ff6e12),LL(0x19c77143,0xe2d512fc),LL(0x60279af1,0x63461543), + LL(0x32b4d371,0xff65189c),LL(0x0faf5ba7,0x022fecca),LL(0x414707b4,0xd08fe9bf),LL(0x722d5fd2,0x0ef8af2b), LL(0x4e6fa14a,0xbef06063),LL(0xcca29177,0x1c41f752),LL(0x65091fe1,0x17dc7e18),LL(0x23f13c18,0x693d72d2), + LL(0xce8e2d30,0xce88eb02),LL(0xe972faca,0x7071f98a),LL(0x549c38ee,0xb7388d61),LL(0x0b788b8c,0x7cfccee2), LL(0xcb93b5e8,0xdc470705),LL(0xab96d485,0xea053c18),LL(0xd634c9b3,0x70e96456),LL(0xd5999cf2,0x2c58c20b), + LL(0xa77c1767,0xcd392b3c),LL(0x7c4e6bd9,0x14471fab),LL(0x75c905ff,0x312e1547),LL(0xace47038,0x45764654), LL(0x8fc3d697,0xa34a0b0e),LL(0xd309ed3a,0x5d9ad31a),LL(0x0918f957,0xbba340c0),LL(0x31fd72a1,0x768e06e8), + LL(0x3e1a4a54,0x77e5dd92),LL(0x3fdbc1e1,0x0970719f),LL(0xb0371fe2,0xd4f1da6f),LL(0xfd7f895a,0x3635f433), LL(0x411c8e6f,0x0e8e40e6),LL(0xec18103c,0x31d126bd),LL(0xc299d7cc,0x415a0cc1),LL(0x3a8e97f1,0xdf528e7b), + LL(0xeed95e91,0x4551a8c7),LL(0x32bcfb03,0x8de89888),LL(0x2eac5c3a,0x25da4f5f),LL(0x5f88d63f,0x6d0b2e25), LL(0x575d6145,0x8d158d14),LL(0x345f62b0,0xe5601a6b),LL(0x113c6895,0x6f951699),LL(0xb87e50ef,0x79e29fd5), + LL(0xd5fa51ff,0xf1ab215c),LL(0xaf2c3094,0x4fc5c4ea),LL(0x2c006042,0x1baeda40),LL(0x3e30e75f,0xcdfcc37c), LL(0x467f57eb,0xdd64e5dd),LL(0x22902d21,0xa5b13731),LL(0x1c52cb7b,0x856866dd),LL(0x16a08caa,0x05cf0f7a), + LL(0x533b4d09,0xa46e8a55),LL(0x4e073af1,0xfc803998),LL(0xe0d589c3,0x8e3825c8),LL(0x4c1daef3,0x505e8e5d), LL(0xc5f3db12,0x9f8363b1),LL(0x74f569e2,0xe7d46700),LL(0x4d68461a,0x551fd2ed),LL(0xa8bbe83d,0x26248da5), + LL(0x65681dbd,0x8d90c47f),LL(0x2200ba6b,0xe726d25e),LL(0x65a3bc9b,0xa2fe408f),LL(0x9c443b57,0x94a80457), LL(0x07364677,0x95f7f024),LL(0xdaf0fb34,0xe9d9bc87),LL(0x5588e979,0xe9082548),LL(0xa0e61ff2,0xede1f94d), + LL(0x45e1c230,0xcb89a1e8),LL(0x50a15304,0xee014c23),LL(0x2bab57e1,0xf25d8ffa),LL(0x26223c6e,0x8a920680), LL(0xaadf7e6a,0xc5abb7af),LL(0x9e7d8da5,0xcb57c893),LL(0x7d589a91,0x839bcda0),LL(0x77e82027,0x1fa774c0), + LL(0xba6504d7,0xeca669cf),LL(0x6845e47d,0x7bf09544),LL(0x607b3641,0x5eb6c33e),LL(0x64bab450,0xf445556e), LL(0x86096fde,0xed0b1c02),LL(0x8ea41693,0x2c5ba666),LL(0x37ec248d,0xe578b315),LL(0xf64ed28f,0x97ef44fe), + LL(0xce419462,0xfa5a6c46),LL(0x9cce80e9,0x29336dc9),LL(0xeee7617f,0x9e9054b9),LL(0xf3d51cba,0xcea9a100), LL(0x13267ec6,0xc3cce5e8),LL(0xa4e807e7,0x650c8383),LL(0x9b2726dc,0x1338e22e),LL(0xbf79b47a,0x220c50b2), + LL(0xa0e0962a,0xe160d496),LL(0xe1ed5cdc,0xe1a26460),LL(0x31427c62,0x9a1ed8c3),LL(0xe99a096a,0x65ef5300), LL(0x4e3ad558,0x38abea5f),LL(0x0880ba0c,0x03bb15e9),LL(0x0141b036,0x1e6dda7e),LL(0x5bf37669,0xd31b08bf), + LL(0x68da20d2,0x948e0366),LL(0x4108fe36,0x36998a24),LL(0xf9d6563b,0x7606e6ed),LL(0xe42172ba,0xcf7cbdd3), LL(0xa1265b99,0x2335a9a4),LL(0x30ac3f69,0x64776cdc),LL(0xa59b595e,0x04040362),LL(0x2cbc03cd,0x82df96b9), + LL(0x6cea2796,0xe9d18c7f),LL(0xe1ea7e35,0x3112c4f6),LL(0x5f8a786d,0xf9cbc205),LL(0x2097da0d,0x36cc6d42), LL(0x2153e665,0x54093350),LL(0xce937bb9,0xebe9db0f),LL(0xd95942f8,0x9d1a5972),LL(0xd4bd5c74,0x81c1f94a), + LL(0xaa04152e,0x61dc7318),LL(0x95e5ec9f,0xdf636db1),LL(0x48090850,0x64a80d46),LL(0xce890a30,0x2b37679e), LL(0xff6025e3,0x9f46d5b9),LL(0xf24534dd,0x6eed5a44),LL(0xf740a84b,0xc56b5cb1),LL(0x228cc826,0xb4641c28), + LL(0xaf62b943,0x676289be),LL(0x1eae5409,0xe3f3810c),LL(0x04b5be78,0x73613f32),LL(0x398b556c,0xe6359179), LL(0xc0263f77,0x6a342b12),LL(0xc10a6db5,0x6b093bbd),LL(0x29832fb9,0x8f3fc90d),LL(0xff03b2ff,0xb3f2d8fc), + LL(0x64457331,0x1de7bd1c),LL(0x43bb1380,0x0a03a06b),LL(0x8bf17419,0x6720cc3d),LL(0x33938d5a,0x2627c7da), LL(0x8d98f34c,0x204da058),LL(0x51cbd284,0x80e29f46),LL(0xa46f93d5,0x11b22dd4),LL(0xe971a61a,0xd7341655), + LL(0xee69f782,0x36a748b7),LL(0x94f08ac0,0xa3740020),LL(0xc36099f3,0x383fb245),LL(0x00137fdc,0xa7cb0ef9), LL(0x6e1dd2e5,0x5371052f),LL(0x7976a1d3,0xed3ab7b5),LL(0x9df822e6,0xb0119c0d),LL(0x358685d1,0xafd2a477), + LL(0x4ae1103c,0x82879cb0),LL(0x94385be6,0x61cd6ca8),LL(0xd85d4a62,0x7c551809),LL(0xb318d965,0x9632ac5f), LL(0xe1340605,0x67baad2c),LL(0xac6ed4f7,0x39c2c8c7),LL(0x71211c2f,0x42c4a7b1),LL(0x9bf758f6,0x43c778bb), + LL(0xf519acb2,0x2dc8fc39),LL(0x08eff177,0xd3c30a6d),LL(0x5144484b,0xf889c021),LL(0xca376af3,0x01b82327), LL(0xd3e71253,0x168a0b2f),LL(0x3f9ff89d,0x5e92c6ba),LL(0x5b4c6844,0x8c74c132),LL(0x33de6858,0x707c4a40), + LL(0x9c36dd9e,0xb13f6abd),LL(0x9b3aa9f5,0x4baaef52),LL(0xcd156392,0x0a4fa929),LL(0x6506f42f,0xde0f1956), LL(0x150d4ee7,0xe43dd7f0),LL(0x7247f552,0xf7afe7db),LL(0x9072b450,0x9abc8d1c),LL(0xc9a8e159,0x5d0645d5), + LL(0x01c6f17a,0x863d3e8f),LL(0xdf080690,0x3a0575ac),LL(0x2b0fb150,0xcad62d87),LL(0x625c35c6,0xa1f54744), LL(0x41fe59ec,0x7d3bcec3),LL(0x169f1e04,0x0fd3e40e),LL(0x2ed9aa4b,0xbde8c827),LL(0x13046c6e,0x71562ee6), + LL(0xe9acac7a,0xaf049c5c),LL(0x261dd422,0x7efec06c),LL(0x095564c4,0xa530fbfd),LL(0x2a57af79,0x000c0c82), LL(0x2ce1315c,0x9f79868f),LL(0x1b5d575e,0x0dd99453),LL(0x1e534cfd,0xf1a49419),LL(0xed7e8b39,0xc7de8756), + LL(0x3ed2ccb2,0xef61f5c8),LL(0x34af2a15,0x032ee766),LL(0x9f69ae9d,0xe0692ed5),LL(0xf64900df,0xd34fc2d5), LL(0xaca6d51b,0x1c51c950),LL(0xa7717dfb,0x10ae0fb2),LL(0xa7ec7ca8,0x9fa305f7),LL(0xb5728214,0xb215a8ab), + LL(0x8819505b,0x62628fdf),LL(0x004ba54e,0x3cefd86c),LL(0xc571da3d,0xa17bed74),LL(0x93a5faa5,0x362dfef6), LL(0xf8aeea05,0x1bee6899),LL(0x16f18b7a,0xd7bf7e31),LL(0x1cb7685c,0x3f3cf39d),LL(0xe2e57c8e,0x1df41f23), + LL(0xe2fd94f1,0x8f62ecb8),LL(0x4c30a178,0x652099c9),LL(0x4262e9e6,0xaa2454e1),LL(0x2015d4a9,0x7f0d440f), LL(0xbb5b39fa,0xa2c76313),LL(0x1ab47bb3,0x46e57ab2),LL(0x8697e682,0xd181f444),LL(0x33273dfe,0x55db129e), + LL(0xe71d029f,0xda188361),LL(0xb5def631,0x3e3e19da),LL(0x087ad30b,0x7431f513),LL(0x9f27c84e,0x2537887e), LL(0xac9df89d,0x0c228c62),LL(0x10031289,0xdcd2c5e9),LL(0x0321d1b6,0x5cc76782),LL(0x6cb3d600,0x4e460bdf), + LL(0x9a870166,0x6f356aab),LL(0x497d4ac0,0x21aecb3b),LL(0xf0495ef1,0xd981a4b0),LL(0x0fb7704b,0x615e8bff), LL(0x8478bf12,0xc148e8ea),LL(0x364eee52,0x7011ec5b),LL(0xf692bc12,0xd9075965),LL(0xe622ad51,0x3019c824), + LL(0xec83c953,0x349e4873),LL(0x3a21ef0a,0xb4f59fb3),LL(0x40f7d93e,0x3872d314),LL(0xc2568c82,0x479e1d02), LL(0x65d43d22,0xd7e4dc9a),LL(0xe775efa8,0xcc068e81),LL(0x326defa6,0xb78ccae9),LL(0x2da64956,0x8f92b296), +}, +/* digit=18 base_pwr=2^126 */ +{ + LL(0xdea227ee,0xb721f8d5),LL(0x3dda8ba0,0xf48c766c),LL(0xe43e3520,0x0583d94b),LL(0xe1d898b6,0xebda36c9), LL(0x6627adaa,0x1808286a),LL(0x9938368e,0x19c4c620),LL(0xf750949f,0xe0dbd707),LL(0x0cf356d9,0xcadf4bea), + LL(0x2dc890a7,0xf5de2126),LL(0x95aa75a3,0x76b7b675),LL(0x2a070b32,0x475fc143),LL(0x8e31d68f,0x7429a646), LL(0x09be3dca,0xec3a9aaa),LL(0xaf780ed7,0x07e119a9),LL(0x64fd96c4,0x62125625),LL(0xe8e80577,0xb571494f), + LL(0x5228d735,0x955ee349),LL(0x8fc5d4b6,0xa04ef2bb),LL(0x3600814f,0x0c532891),LL(0x59f85bd4,0x41f1f637), LL(0xe3dcdfb4,0x72f1d731),LL(0x3aa5edb3,0x28a4ddb9),LL(0xf702dcdb,0x116a68e1),LL(0x3bde657e,0x1975bc42), + LL(0x8a914b50,0x7b9f561a),LL(0x9154d377,0x2bf7130e),LL(0x519b4c35,0x6800f696),LL(0x568b4c56,0xc9e65040), LL(0x6d98a331,0x30706e00),LL(0xe211ce1e,0x781a12f6),LL(0x40562e5f,0x1fff9e3d),LL(0x8c166747,0x6356cf46), + LL(0x429945a7,0x80e87329),LL(0xb7ab06ad,0xc619fe17),LL(0x6fd86b17,0x9116bc2e),LL(0xb9116aac,0x64a41877), LL(0x32ba4f3b,0xe3ed867e),LL(0x68b4ebe6,0x013e263b),LL(0xe779e4ec,0x305ebfe7),LL(0x50178251,0x5536d45d), + LL(0x8873a93d,0x5abb939f),LL(0x8c4c9cb1,0x0263ba48),LL(0x6b78a4b5,0x36764b8d),LL(0x28bebc1e,0x205bb45d), LL(0xae89dcd5,0x16df4bb0),LL(0x316fadb7,0x85994670),LL(0x3af3c724,0x71f75664),LL(0xe8520c9c,0x43e30313), + LL(0x29e91921,0x3ab9ec54),LL(0xe3299f47,0xd931436e),LL(0xb89cd49f,0xb56da7bf),LL(0xcff7f637,0x90623412), LL(0x714022de,0x751e7944),LL(0x2c338262,0x86bcc342),LL(0x314c23bb,0x85f6a9bc),LL(0x1f0a3991,0xedbe8e74), + LL(0x003b40dd,0x7a748d63),LL(0x3951b7ae,0x8a682402),LL(0x704a91b0,0x41e92dd9),LL(0x858cd3ea,0x2dfb3eb9), LL(0xf5094667,0xc3c2af35),LL(0x7435aa2d,0xffa287dc),LL(0x7462714f,0xd03f3979),LL(0x203e5b0e,0xdb550f67), + LL(0xe241ed0c,0x6df7801b),LL(0xb642fd3a,0xb52c0a3f),LL(0x1977a29d,0xdd35e1cf),LL(0xa661404c,0x8e793d60), LL(0x6b9442ae,0x393e2b87),LL(0x2aa6b707,0x123b893a),LL(0xdb8d306a,0xeec88682),LL(0xce847879,0x92c2d93d), + LL(0x80ec63b4,0x725f1e7d),LL(0x74113de0,0xcb8f53d9),LL(0xb819f730,0x2132a072),LL(0xb4c61f06,0xfabf3c47), LL(0x2cb243d8,0x79c1bc86),LL(0x757e3600,0x442833c5),LL(0x4e918b8a,0xfa4f69ad),LL(0x73bc193e,0x5816f3f3), + LL(0x30f40e93,0xc671c7a4),LL(0x5c51cfa4,0x6041aa03),LL(0x2fac25d7,0x3a713549),LL(0x24a7df01,0xf5053237), LL(0xd29f4ec5,0x99efb34a),LL(0x71d2cb1b,0x74810523),LL(0xf3a029ab,0xacefaf8f),LL(0x069d9545,0xc82e4f5a), + LL(0xd3341d80,0xd759549d),LL(0x31a2a0a4,0x079e9fa7),LL(0x2a164f75,0x75da56c7),LL(0xbeefc182,0x9313ef5a), LL(0xbde130ad,0x0aa365b6),LL(0x98411180,0x44265977),LL(0xaa26466a,0xa65373f7),LL(0x2e2cf404,0x1a43bee6), + LL(0xb37a9390,0xe029ed6d),LL(0x34970065,0x5c2351ca),LL(0x1c46d72c,0x7c4f3c30),LL(0x7262ce20,0x09ce770a), LL(0xdd58a9f8,0x0cfeefad),LL(0x408addaa,0x06797d79),LL(0x05aed325,0x76a87c06),LL(0x8a46d0c6,0xe002b672), + LL(0x05b6e1a4,0xcf77ea31),LL(0xa5d92b00,0x3bf900bc),LL(0xdccfe144,0x05996d8c),LL(0x951a602c,0x73d4dfd7), LL(0x0ed8885d,0x033f3959),LL(0x36400817,0x8332dc73),LL(0x2d8ebda7,0x96372295),LL(0xb5da0c67,0x3fb32cf6), + LL(0x3e36defc,0xcb521d65),LL(0xa67f00f0,0xc293d170),LL(0xfb35bd06,0x6a3a2fd4),LL(0x0bd490a5,0x537937dd), LL(0xc274ee5a,0x898d94bc),LL(0x7515b5e7,0xdc70f9bd),LL(0x3749900f,0xa94673db),LL(0x49ad3b04,0x3e6e2af0), + LL(0x207eecd9,0xb9dae1b8),LL(0xec07b47c,0xd3f50d63),LL(0x364292da,0x02b4d909),LL(0xfc35975b,0x919a6df3), LL(0xb616452e,0xb41ed4aa),LL(0x5cfc6abb,0xe58689cd),LL(0xf389b025,0xeac325d9),LL(0x8f255de5,0x45ceb1e6), + LL(0x5e46cdff,0xda4a0715),LL(0x0f6c761c,0x8a860a55),LL(0x5fe1eef1,0xe1395274),LL(0xf7bc535f,0x256e296a), LL(0x2755dd27,0xf3d4b06c),LL(0xbb530c26,0x3ced6ee5),LL(0x96ba599d,0x73249ad7),LL(0xe8a66027,0x5de8dab3), + LL(0xc2f97e01,0xa4892840),LL(0x427945be,0xbe0dbe49),LL(0xa57d4e4f,0x6fd86a7b),LL(0x04a2e778,0x7f56c3e0), LL(0xffc13d49,0x734708cc),LL(0x788d31fe,0x3c1d9413),LL(0x8d3e4c36,0xfe85545b),LL(0x8815129c,0xcca441fc), + LL(0x15e3d172,0x2e2095e2),LL(0x64b43e81,0xc0c8d3c4),LL(0xc68e802e,0x084557ab),LL(0x30d239b9,0xa6b73590), LL(0xb67b0548,0x61ec00a9),LL(0xb8ab138d,0x630059de),LL(0x36ca9888,0x800abf01),LL(0x9517149e,0xe26d644a), + LL(0x58bf21d9,0x775d5a98),LL(0xdbeab706,0x00eb6846),LL(0x8232d477,0x9d714c9f),LL(0xb70f91c2,0x7cde2c3e), LL(0xe9871f0c,0xe6d0a8ce),LL(0x19e8444a,0x902bc60b),LL(0xff0cd43a,0x8651ed57),LL(0xd480d222,0x4418cc07), + LL(0xf3cbe01d,0xb5e0c7e3),LL(0xe43adcdf,0xbf4a899f),LL(0x78f8f79d,0xb89b022c),LL(0xf42c797c,0x79cbbf97), LL(0x59d53cc1,0x46d73cc5),LL(0x4ffca67c,0x99f683e6),LL(0x98865e5b,0x527c16ec),LL(0xf68f8ee0,0xc844b70f), + LL(0xc9854994,0xcffcccc0),LL(0x74926d5d,0x4aafcc15),LL(0x835aea59,0xeb084832),LL(0x20df21cf,0xcb317b5f), LL(0xe43d1853,0x3c45b084),LL(0xb93b9167,0xd12c9411),LL(0x19316bdf,0xb0901982),LL(0xd11ab5e2,0x76bfa2ac), + LL(0x4e84d3e9,0x22bf23cb),LL(0xd1572d4a,0x96ec9f8e),LL(0x080ba39a,0x31594ae4),LL(0xadc6bae4,0x105b5677), LL(0xa644e230,0x501e45dd),LL(0x64573126,0xeb571f27),LL(0xa36ac1ef,0x1fc3d478),LL(0x327c7da7,0xbd5fcee8), + LL(0x34a70bfe,0x1b2b1885),LL(0xa36345c5,0xcfa421f7),LL(0x6f322ae9,0x2f33f4cc),LL(0x4dabb7a0,0xdac0bb75), LL(0x923cea0a,0xfba35536),LL(0x6d9cb50c,0xc16f73e5),LL(0x25812c96,0x23216dc6),LL(0x3d7ab424,0x82945e67), + LL(0x0796605d,0x829577b2),LL(0x5026907f,0x47fa0978),LL(0x2d0f68b2,0x99701169),LL(0xbc1e46db,0xa0d24be4), LL(0x2eb2ac98,0xcf409c2e),LL(0x97f3ff5c,0x7b59c3c5),LL(0x81ed7f02,0x2f4576bd),LL(0x10399c22,0xe41339e5), + LL(0x2ecce0e6,0x562d7744),LL(0x9a1656c2,0x1afc3869),LL(0x86200621,0x5714820e),LL(0x566da805,0xee36f7b6), LL(0x6e5a2a06,0xe6694104),LL(0x8caabaab,0xd4390b74),LL(0x93b0d142,0x9db20998),LL(0x7926baf3,0xe1811b81), + LL(0x08bc1965,0xd578f2ed),LL(0x35f00d5d,0x9a7e31e2),LL(0xc9007327,0x3725b65c),LL(0x29c36f38,0x157cfe95), LL(0x23a521d7,0xb1c3d0f1),LL(0xb8a9ae08,0x3e65fb7c),LL(0x690b8f78,0xed48bcf9),LL(0x90d5dfde,0xe5f46b2c), + LL(0x0b6da2b6,0x14aebb35),LL(0x7b65ee55,0x91fef336),LL(0x1a0a004d,0xdb77b57b),LL(0x23aef1f7,0x1c59b628), LL(0x3ec88d18,0xa79c8c89),LL(0x4fde31f1,0x52cca38a),LL(0xcf4e30b6,0xe2f64a94),LL(0x37ff1cbb,0x2b4cdbd7), + LL(0x0b566632,0xcb542f68),LL(0x676fae9f,0xedab69a6),LL(0xc45cb6f0,0xc4531e0b),LL(0xb88fe4a5,0xf967ec6e), LL(0x2919785d,0x4ab4e645),LL(0x7a17b20f,0x2dcaefca),LL(0xda7afaa0,0x65c89c05),LL(0x4dafc6a2,0x59ea00e9), + LL(0x8eb43733,0xa6362bf8),LL(0x12011803,0xae2dddc1),LL(0x0bb2aaf8,0xbbf516b1),LL(0xd8de21a3,0x9f2627e9), LL(0x43a20b74,0xaf30439a),LL(0x4ce86408,0xac7e07b0),LL(0x7c10566b,0xc54cdff2),LL(0x6279af0a,0xe3ee0622), + LL(0xf7770f95,0x57d09708),LL(0x123e020b,0x6f0ba223),LL(0x6cd41559,0x6c123fb9),LL(0x6fb30f58,0xc54f5c65), LL(0xbbf7101c,0x5e168af3),LL(0xce974455,0xf6d6dbdb),LL(0x88313516,0xa001f3b9),LL(0xdfb4ac20,0xe6e4a26d), + LL(0x506f7dcd,0x74e7b7fc),LL(0x5d037d69,0x985e8546),LL(0x1ec8d374,0xff00a4da),LL(0x505b4180,0x8c339ae3), LL(0x3a5f71c4,0x78bcd4f2),LL(0x67ac3e9f,0x2fb4d99f),LL(0xee65dad1,0x7dd25aa6),LL(0xb62c34dc,0x2fd63fc2), + LL(0xf7700192,0xdee42663),LL(0x2c3248e9,0x9925a206),LL(0x2ea9f052,0x4a55a55d),LL(0x16ac67fe,0xe1d6efcd), LL(0x9bb02415,0x7f82246d),LL(0x72cd7a6c,0x2fadbb9b),LL(0x712004dc,0xe977a037),LL(0xb3c9f4b9,0xe8c449b2), + LL(0x861ea138,0xa2cb838a),LL(0x356ae003,0xfcbe219a),LL(0x1838504f,0x15c02496),LL(0x0769d5dc,0x58cef52c), LL(0xb3fef999,0x7e94ff7d),LL(0x04e4fc87,0xf55501e0),LL(0xc05430dc,0xcdb5fd36),LL(0x778c5cd4,0x49872453), + LL(0x1b5e7ace,0x4c4855ff),LL(0xb159fe74,0x89fc6309),LL(0x3c9ebbe2,0xaca00404),LL(0x866bf867,0x4c030591), LL(0x9b18a535,0xa7e8f599),LL(0x5c0a0a44,0x9203ebfc),LL(0x463207c9,0xbf1b30cc),LL(0x9d135aeb,0x90b59001), + LL(0x794cb3ab,0xedc44d04),LL(0x0ad7be70,0xb3baa475),LL(0x6c09fc91,0xb7d8c7c5),LL(0xf45a5bd6,0x2a362d71), LL(0x8cf3e5a6,0x36e308c3),LL(0x0a649c31,0x4caf2cd1),LL(0xb3c501c7,0xbae328f5),LL(0x83a0eeb3,0x2efeca03), + LL(0x7086093a,0xc3a27585),LL(0x6d686d83,0x78e86515),LL(0xedf0def6,0x18cf3ac1),LL(0x5a1d6cf4,0x2f6a56da), LL(0x30084873,0x350c822e),LL(0x65843610,0x82d48087),LL(0xf393ecd1,0xa4e752c1),LL(0xeeb74f25,0xe3034d6d), + LL(0xb8b0c5c7,0x1793727c),LL(0x7ec9ce37,0xde561ca6),LL(0x6190f612,0xd9eddc50),LL(0xca89a191,0xb52dc77c), LL(0x4bf1e87a,0x990010b2),LL(0x15b91691,0x073136b2),LL(0x15546011,0x50111261),LL(0x0196cb8d,0x17d48864), + LL(0xfd61d824,0x7ec44104),LL(0xf088d3db,0x213550ef),LL(0xacbbb608,0x5e8d321f),LL(0x39312b64,0xc317c1f8), LL(0x27de4329,0x7a4a1cd0),LL(0xf9b135e4,0xbfb33f07),LL(0x59b94480,0xcf82b639),LL(0x70b118e6,0xca62d957), + LL(0x2b1d45fb,0x95b2ff03),LL(0x2570686c,0x472dd56c),LL(0xd3d50e32,0x4fbae8a0),LL(0x65796a08,0xa31c65dd), LL(0x037ce5bb,0xe261f6f8),LL(0xd042073b,0x3b7816bf),LL(0xbfba45f8,0x6d0ebbee),LL(0xc9522e36,0xf2d99979), + LL(0x77cb5b0c,0x707f2a18),LL(0xdfc02b82,0x954b5a91),LL(0xc20ae04b,0x246b9a55),LL(0x9dd79f93,0xa1486775), LL(0xc11f6d8e,0xd4092830),LL(0x267a4dab,0x74ca482f),LL(0x9c58706f,0xe3c80bb6),LL(0x099154c1,0x245f04b7), + LL(0xf149259f,0x3a4b25b5),LL(0x65ccbe91,0xeac735f8),LL(0x572788a4,0x260e749f),LL(0xe34d40cb,0x30b9c736), LL(0xf524a17f,0x65981d50),LL(0xcddbbefc,0x6c462f5d),LL(0xa1e57312,0x245bfa18),LL(0x46dc8ae0,0x3b4b003c), + LL(0x5d262a35,0xb1958797),LL(0xffafd8c5,0x83f6e604),LL(0xbc2e0801,0x60843f9c),LL(0xc783ad3d,0x11d85ac1), LL(0x2e016e43,0x1ce477dd),LL(0xfb4a0201,0x2b628f06),LL(0xbf4f77d7,0x897b7f62),LL(0x10277d8a,0x52e04f22), + LL(0x5f3f0d6a,0x17132351),LL(0x59a96c4d,0x13c9e064),LL(0x86f05ae8,0xc73892b0),LL(0x4212ad65,0x94545c8a), LL(0x3dc4984c,0x0591b091),LL(0xf2ec1ca9,0x06845698),LL(0xb3ac894b,0xb0e1e1d0),LL(0xa7c915cd,0x962ca1da), + LL(0x95331bd5,0xb0640de8),LL(0x478c1b6d,0x2544348a),LL(0x5647a67e,0x3c3bd415),LL(0x5b20e5fb,0xd7970ef8), LL(0xe06b4fa6,0xd6e6f6be),LL(0x871390ff,0x5ae29e5e),LL(0x7256daa1,0xc7924188),LL(0x59f61750,0xfae5e501), + LL(0xd1ef1d2b,0xfac83ece),LL(0x554736da,0xa567060c),LL(0x1dba8bc7,0x697571f4),LL(0x553fbcfc,0xd3fc5aeb), LL(0x9755fab0,0xe665970a),LL(0xb5537da8,0x30fbe8d9),LL(0x97c2b5f0,0x7a7d0013),LL(0x1b700a02,0x9fea5c9c), + LL(0xe9a377da,0xcfc0166e),LL(0xac502375,0xcc78f3d8),LL(0xba64c3b7,0x803fbbda),LL(0x4d70cc42,0xe53c7d6b), LL(0x5189b7da,0x6b927bba),LL(0x8b05322a,0x2c86253b),LL(0xf3869873,0x333e7491),LL(0x4b492879,0x9308348a), + LL(0xb9ab0a36,0x39bfa2a8),LL(0x18f71ac7,0x560f80a6),LL(0x45e24412,0xca9b265a),LL(0x8e2ddac3,0x6796bece), LL(0x17bfcabb,0x87f1eee5),LL(0x195c9bb2,0x624db4d9),LL(0x2b4db6d2,0xf7110fcf),LL(0xb432d19d,0x41d3fb0d), + LL(0x73554a3c,0x3344ea7d),LL(0x830a3881,0x4c968dad),LL(0x687f71ec,0x5df71ad2),LL(0x259cbc07,0x4c4df41f), LL(0xeb541d72,0x8d12d2e0),LL(0xa20fb162,0x94c0dab6),LL(0x1eda0516,0x9bbc2524),LL(0xdd7871ff,0x696c924e), + LL(0x1db84dc1,0x97efb495),LL(0x03cbfbf8,0x7d293ce5),LL(0xbc48d007,0x79e25d3e),LL(0x8591a1ea,0xc900a580), LL(0xd37508c3,0xf0277a09),LL(0xe84557bf,0xbf583aa4),LL(0xd8228591,0x2e258d60),LL(0x117da3a9,0xb037e17c), + LL(0x243d588d,0x4b35355e),LL(0xcce2539e,0xbe6dfa36),LL(0x4843c9da,0xa57d5823),LL(0xf59348fa,0xe3d91511), LL(0x2791c08f,0xb5d1395c),LL(0xf6fdcc93,0x04129e5d),LL(0x0f53087b,0x635a63ba),LL(0xf237612e,0x66da6bec), + LL(0x22755420,0xc3d052e5),LL(0xd7a1bd35,0xc37a9b47),LL(0x9b347e02,0xf19613f3),LL(0xbbda7ae0,0xee84dbac), LL(0x3a85f2e5,0x603be21d),LL(0xff679451,0x5f0927c2),LL(0x8674f8d7,0x799013ad),LL(0x00f465e5,0x17b248d3), + LL(0x96ca19de,0x2a29135f),LL(0x957d1844,0xc8e56e32),LL(0xa11a4349,0x935e7eaf),LL(0x741b73d3,0x717308e1), LL(0x7233a9df,0x40477acb),LL(0xd2c83b72,0x7a78dac2),LL(0x2c5d79d2,0xfb882461),LL(0x76f44fa0,0x984505fb), + LL(0xdfdc4a9d,0x5cdded16),LL(0x3f0ff597,0x4cbea135),LL(0x8a79078e,0x38daf27a),LL(0xce1bbf0e,0xb4b0085d), LL(0x86f19fd0,0xb6b0d8d7),LL(0x1778ca6a,0xe0fdcdae),LL(0x0b26b9b5,0x257c7df9),LL(0x141dcafc,0x4b82422c), + LL(0x4d3cf148,0xcf8a2dad),LL(0x5f17e914,0xf1a4e292),LL(0x60de8f64,0xc40755bb),LL(0x8718f49d,0x412449f8), LL(0x8737b6cb,0xdabb9968),LL(0x6236ea05,0xdd94ae81),LL(0x05c5aca2,0xb5223cd0),LL(0x762210ed,0x6b81bd33), + LL(0x5d4164df,0x1f0921db),LL(0x8d4a35df,0xf6fdb08f),LL(0xc602d4d8,0x1efcf3c7),LL(0x057f3aa0,0xa2ecd9e6), LL(0xeb4fcba2,0x13a6c576),LL(0x13130559,0x16425bd4),LL(0x416b4968,0xa9eac848),LL(0x2119600e,0x617c32a9), + LL(0x0bb49e40,0x1a84eca5),LL(0xbc2310b3,0x2ed98d25),LL(0x5edbc719,0xad191f88),LL(0x0376ae08,0xd8d667d5), LL(0xf0b4fe29,0xb855a8ee),LL(0xe75354f7,0xc3fe79fb),LL(0x403b651e,0x1ee9b9e6),LL(0x2baa2c6e,0x99ddbb3c), + LL(0xeccce37d,0xc6a84c47),LL(0x038c9821,0x71a05a24),LL(0x9a6353d8,0x8d32194c),LL(0xcf0a1462,0x14cd3ea6), LL(0x7bdbe521,0x40d70aa2),LL(0x95c80cd8,0x200f0b21),LL(0x3efdf656,0x4c79dab9),LL(0xa981d8b5,0xafa44e4c), + LL(0xa7111315,0x811b9387),LL(0x7590c35d,0x0255a234),LL(0xf1af875c,0xb18e87c0),LL(0xced5cc1f,0x0a930b41), LL(0x96094a55,0x6ff4fca4),LL(0x6a9dc519,0x74095b88),LL(0xafa4894a,0x44492273),LL(0xa2e6f56e,0x54f16f88), + LL(0x34485e31,0xd613fbb4),LL(0xd2464242,0xc716c370),LL(0x1644f2e1,0x21535837),LL(0xbe417c3a,0x7719474b), LL(0x2045d2be,0x31bfb158),LL(0xf50e6828,0x10855524),LL(0x98a67af1,0xdb9490ad),LL(0x1c281ff3,0x41a34aa6), + LL(0xa8bf2580,0x87109ba8),LL(0x2d7eb52d,0x70c2e936),LL(0xfb3fc109,0xefe9fe2c),LL(0x780526bf,0xfd3f4d7b), LL(0x9ed0c3bc,0x6f9a48d8),LL(0x5d8205b2,0x0aec850f),LL(0x1c6a13ef,0xa378f8c6),LL(0x9d10e11b,0xac02f367), + LL(0x3b9bbf54,0x79c6b396),LL(0x42779c58,0xfb586d71),LL(0x889eecb3,0x5d975728),LL(0x434537d8,0xda2ec867), LL(0x62f31813,0x15a3c9c3),LL(0x3c30433e,0xc4b357c8),LL(0xc464e972,0xf26d281f),LL(0x4512ffcf,0x99fa49e7), + LL(0x725b9753,0x456db1b2),LL(0xb42941c5,0xec501760),LL(0x7d6d406f,0xd822a9d5),LL(0x7bbcd4d6,0x4bb7a820), LL(0xcc96a5b7,0x079b1fe0),LL(0x24aa4901,0xf83e5755),LL(0x20da7fcb,0x317cdd1d),LL(0x93b04a81,0x487fd706), + LL(0xe43332ef,0x43e0671f),LL(0x441c2218,0x71c5dd5b),LL(0xe922ba18,0x4c1d2c1f),LL(0xd619cb67,0x558e9c2f), LL(0x1ec51255,0xd04acde0),LL(0xaf824507,0x824b3740),LL(0x744c6afe,0x62d1b9de),LL(0xab0d52e3,0xb99616db), +}, +/* digit=19 base_pwr=2^133 */ +{ + LL(0x7f6a1cda,0x5ec9c084),LL(0x823d6350,0x68839c14),LL(0x03bad007,0xcbbb678b),LL(0x4788854e,0x6a727255), LL(0xef5c7294,0xc747fea2),LL(0x4875e775,0x74852778),LL(0xaa61a893,0xad7b8e8b),LL(0x40da98b1,0x18ff3335), + LL(0x5529ec80,0xa51e9f4f),LL(0x6fd146d1,0x0420274a),LL(0x8e300c2c,0xbbf1ab66),LL(0x41653fea,0x2d0b3a9d), LL(0x23a495b9,0x2be2180f),LL(0x5415d73b,0x6ef3c374),LL(0xc67ae4fc,0x1d3e1ec8),LL(0x98d31f5f,0xa5839e9c), + LL(0x37d77c01,0xf54114d6),LL(0x41023c87,0xc2e18a4b),LL(0x9e6e1221,0x6fa6c3d3),LL(0x410e48f9,0x9a6cf4e2), LL(0xb181828f,0xe0881140),LL(0x78cb7833,0x17c6df29),LL(0xa7cd2367,0xc1eb8df1),LL(0xca89f922,0xb78f1c8d), + LL(0xd0d42887,0xf25d4777),LL(0x2b7a2707,0x4b489218),LL(0x2d3966fe,0x1b4dbf9b),LL(0x41ae2bec,0x4bac5f48), LL(0x1733964e,0x68db2733),LL(0x6a814a69,0xa10c5dff),LL(0xa9898348,0x84ebdaf0),LL(0xa74da3f4,0x60e46823), + LL(0x93420649,0x452b6b1d),LL(0x6ed5d7f6,0x9dd6452b),LL(0xe687b577,0x4a9b8fa1),LL(0x854c49d7,0x1e203166), LL(0xa45feba8,0xf523667e),LL(0x5f9f4a56,0x9ecb4d44),LL(0x7fb1c641,0xb8655a5f),LL(0x87c26201,0x5516401a), + LL(0x0d2face6,0x24677754),LL(0xa8ade59c,0xd9f7da7f),LL(0x7fa7df06,0x27e3ad77),LL(0xf60395ad,0x35a4caf0), LL(0xe4e701ac,0xfaef231c),LL(0x23755489,0x9e135976),LL(0x43554ad3,0x7caa73ab),LL(0x94f0d878,0x9d8554d9), + LL(0xa85b81d5,0xe42040ce),LL(0x40fa9631,0x4d28aca7),LL(0x7e04b755,0x076fed3d),LL(0x1129ce4c,0xdde3d347), LL(0x1179af95,0x77f785d7),LL(0xf74e0672,0x4782f842),LL(0x0b4597cb,0xbd068cc1),LL(0x8f4c65b7,0x3d6d4b2a), + LL(0xf9066d73,0xe0642d18),LL(0xa098b3bf,0xbe1d2ec3),LL(0x21b4954c,0xefee860c),LL(0x27b629bb,0x4d7c4e6d), LL(0x8e8b81b0,0xcd8f1e03),LL(0x7fe77eb0,0x4a80168e),LL(0xce247c73,0x4d977591),LL(0x857e0356,0x9b30c9f2), + LL(0x2940e9de,0xc02495ba),LL(0xb6d2b72c,0x357299f5),LL(0x06a9c2e4,0x132b4c63),LL(0x084d8c67,0xe90a90c5), LL(0xace1b471,0x0f0c9e94),LL(0xf1e3d8f6,0x769457e1),LL(0xd71118c6,0xc4c30ce3),LL(0x6b652a3d,0xdb5fd8d6), + LL(0x4def5978,0x090df107),LL(0x2d8a5f3a,0x1abcfa32),LL(0xa34b70db,0x2976b012),LL(0xfa5e75b9,0x90f541d4), LL(0x37a6e9a0,0x50c991a9),LL(0x903bffda,0xf51e8693),LL(0x8d344776,0xa2697ab4),LL(0xe34a7850,0x77134fe8), + LL(0xa72597ac,0x723e5d3d),LL(0x4269aff7,0x4a49847a),LL(0x443b8db6,0x75ad9088),LL(0xa51d80a1,0x9b7d00d5), LL(0xe5e04ac2,0xce1c7049),LL(0x2a792bde,0xb8c2793c),LL(0xe410e175,0xde9220a0),LL(0x9401bc2a,0x4b3a9b85), + LL(0xf037d15f,0xc7eaf2c5),LL(0xc7afbf8b,0x410b627e),LL(0xd7bedf50,0x243cdb79),LL(0xbe6512d0,0x04813b51), LL(0x26beca2f,0x2fb77cab),LL(0x7baa3099,0xbb601975),LL(0x40bda4d0,0x8c327e59),LL(0x13c23444,0x85b9c764), + LL(0x08ed59d8,0x26960d9c),LL(0x4a72854d,0x9b76dced),LL(0xfdc3b7f5,0xca2f579a),LL(0x6cae8b4f,0xac27028a), LL(0x42326aa5,0x48fd1a49),LL(0x5759c63f,0xb95fdb4f),LL(0xe0a96abf,0x27655358),LL(0x36ed53b0,0x26d38b64), + LL(0xfc6d1f3e,0x03cfdd49),LL(0x15adaba0,0x20af5886),LL(0x754dd268,0x74c6c943),LL(0x7977717e,0xe7d52cdf), LL(0x3b414dd2,0x9a81d440),LL(0xd790a4c7,0x697c7b4a),LL(0xedbce1f2,0xb1b7735f),LL(0xbefa7210,0xbd90e63f), + LL(0x7ab207d1,0x2e2b0dad),LL(0x9b373211,0x89abbd83),LL(0x8e35e2bb,0x45d34ebc),LL(0x064856f6,0x67ba3ac5), LL(0xa52c7676,0xb5527dbe),LL(0x71294012,0x906fb217),LL(0xab305260,0x65fca552),LL(0x14ee193b,0x89ac52a3), + LL(0x88c06b1c,0x673aead4),LL(0x49d9d4e8,0xea8af420),LL(0xcb9e86bf,0xa7b4409a),LL(0x5414aa56,0x49f76f71), LL(0x8c13857a,0x6603c801),LL(0xce742384,0x7c26f1c2),LL(0x2a665719,0x042fb224),LL(0xe175b0c6,0x2619f254), + LL(0x7c092397,0x5b3b71ea),LL(0xf18c29ae,0xd9087023),LL(0x2008841d,0x48dbecbd),LL(0x22622bba,0x658c998e), LL(0x578e463f,0x38a2cc6d),LL(0xcbb88796,0x7002380f),LL(0x71695101,0xc545baff),LL(0xce65b49c,0x064a0500), + LL(0xb1ae0398,0x3651d926),LL(0x4ace0e86,0x33c9ea8f),LL(0x1a6debd7,0x481fab1b),LL(0x4d365031,0x65b58a79), LL(0x811e8f01,0xb73ec84b),LL(0x51342ef2,0xb6aa3955),LL(0x9efcdbcc,0xdbce3d9f),LL(0xcfbf2a4f,0x5791b35f), + LL(0x6eaad1f0,0x67024158),LL(0x0063ae25,0xe8dbaa88),LL(0x9fedc144,0x6d2051cc),LL(0x18b5e86d,0x136c2ab1), LL(0xc89241d4,0x3b2d3d63),LL(0x4a82dec6,0x843cfa3d),LL(0xf0a5f163,0x64fa5860),LL(0x1ae3be83,0x2d9b6095), + LL(0xb01a91e5,0x75f97753),LL(0xcd0d8cac,0xd374dfa2),LL(0x8eb72ba0,0xe5dbffef),LL(0xd7b8a624,0x61049807), LL(0xa39277d3,0x9c8b5e93),LL(0x3b1cc635,0x6e5ba593),LL(0x21cde059,0x8bd0a69e),LL(0x071ec0c8,0xd0a19b53), + LL(0xd1bb088d,0x8c87785a),LL(0x7e249c39,0xd801d5a6),LL(0x8688914f,0x002ee598),LL(0x6b68413d,0x52b014fc), LL(0x507946df,0xaf1d7e88),LL(0x84ccebf1,0xa38e436f),LL(0xaa86a4b6,0x37d9b946),LL(0xc506a394,0x55da0db6), + LL(0x02b900bd,0x856928c3),LL(0x7bc6a67b,0x9eb926a3),LL(0xd0f39446,0x2f4d392d),LL(0x01c49daa,0xb12f2761), LL(0x13874ac7,0x07b8d23f),LL(0x1efaa157,0xa473ef4c),LL(0xdf8cf2ab,0x550765f6),LL(0xd23d3750,0xeba88504), + LL(0x2434fa2e,0xf05791d4),LL(0x4e2a05ea,0x8c0899c3),LL(0x898bc9b0,0x40a53bdd),LL(0x40c8bf7c,0x6c255f6f), LL(0xe164b910,0x203db8c5),LL(0xc1c4de69,0x070baaee),LL(0x5df5c0a7,0x89660629),LL(0xdb364b99,0x0b9c2f4b), + LL(0x44bb5a79,0x012c6994),LL(0x9bd1fdc0,0xf5928e0c),LL(0x3ce49191,0xd30b8a97),LL(0xe3a05dd3,0x52792b85), LL(0x1d3d69c3,0x0da08916),LL(0xed59a28d,0x931759e8),LL(0x6ca05485,0x412148d9),LL(0x3d6e9964,0xb1517aa0), + LL(0xde75812d,0x15204ba9),LL(0x5698b03f,0x49e377e0),LL(0x05c9072e,0xe7790d41),LL(0xdba28e80,0xf79adbed), LL(0x4644840d,0x6aad9f96),LL(0x2e0a695b,0xc3f3d032),LL(0xaa4aa737,0x3eb739d2),LL(0x37d8d520,0x45c6b665), + LL(0x9917cb85,0xc3ba2408),LL(0xd7bf6304,0x1c729ffb),LL(0xcc160245,0x56b9935e),LL(0xe03cb227,0x42379567), LL(0xb66bfc5d,0x2dc20028),LL(0x95de8ed3,0xfaf7d224),LL(0x3214024e,0xa7541158),LL(0x50aabdb6,0x2f7755d8), + LL(0x7ea9b93a,0xb74ac27b),LL(0xa2e0516c,0xc1c5a8fe),LL(0x6b64f56f,0xe9f4f222),LL(0x8fbc4a64,0xf3c0c7fb), LL(0xa16edc23,0x43ac0ac2),LL(0x6d086e9e,0x0e26e4ad),LL(0x5bc0961f,0x5b8ef949),LL(0xd2b77c29,0xa0d16d39), + LL(0x78845d09,0x50b43efa),LL(0xcb3acdd9,0x3899e1be),LL(0x18d4ec31,0xa93a28e3),LL(0x0a66fe47,0x18a4eeed), LL(0x87333831,0xd7a7bf46),LL(0xdbe14699,0xbbf5c1a8),LL(0x80b9c9d0,0xf2a3da73),LL(0x82bceb4e,0x133c138a), + LL(0x335a923a,0xcfd4b885),LL(0x8fc82f3b,0xf9b69b3f),LL(0x8784c35c,0x08908b60),LL(0xd843b66e,0x76bf1082), LL(0xbb57a641,0x1ba730bf),LL(0x34e9f095,0x3bb4a8d7),LL(0xc28d5414,0x0342d32b),LL(0xcfd99e1a,0x8fb13cbf), + LL(0x1d02f47c,0x3845e507),LL(0x14ef0b26,0x4d77af89),LL(0x5ef578d9,0x93454480),LL(0xbdc408ec,0x23138c57), LL(0x47cf528a,0xdac833ed),LL(0x29d7cf20,0xd18e9865),LL(0xcdc8e55a,0x93208743),LL(0x724025a0,0xbfe570c8), + LL(0x3aee838e,0xb75c3de0),LL(0xe0f21f23,0x29304886),LL(0x82791daf,0xe46792ab),LL(0x3f124394,0x3d798d92), LL(0x29a6fb5e,0x2446dc81),LL(0xbd68c23a,0x2446e5b3),LL(0x689b1176,0xe1b5c76d),LL(0x9a852082,0x3fb66661), + LL(0xd9b45206,0x8d6fbcc7),LL(0xeabc4640,0x00ab735d),LL(0x810e37d1,0x428c7017),LL(0x27af5718,0xa4365872), LL(0x0a910146,0x8f195823),LL(0x0ff76704,0xc13ccdd7),LL(0x44d6f1c8,0x59d34ad6),LL(0x795b61b4,0xd3dfa6b2), + LL(0x12eea439,0x1ec08010),LL(0x7b2cd52a,0xafbbea32),LL(0x68cfe98b,0x99428f9a),LL(0x95628fe7,0x4ff9a5bc), LL(0x7ac41e9a,0x212baeb7),LL(0x29206e86,0x595cf03f),LL(0x733f37c4,0x4b62a429),LL(0x4d3cb6a6,0xa1fac4ae), + LL(0x1aed3c45,0x2d6cb0e6),LL(0x4e6da48d,0xf6703493),LL(0x2d13f9c1,0xa0036fb4),LL(0x7fe3ea2e,0x7db5078a), LL(0xd5992163,0x152a1fc0),LL(0x744b44ff,0xd63270e9),LL(0xf177c075,0x56730292),LL(0x17c3e08c,0x470f5e72), + LL(0xecb927f5,0xbf53d223),LL(0x629e8aa1,0xc80fbc1b),LL(0x24d72477,0xed59f186),LL(0x38811583,0xc266f5a6), LL(0x7c404560,0xc6f37bc1),LL(0x0c5b68e9,0xd58c10e5),LL(0x916e8f3c,0x696de793),LL(0x56a7781f,0x7298af8e), + LL(0xb16679d5,0xaf063553),LL(0x4316ed7e,0xa509f449),LL(0xb53cc0e2,0xe3d6ec43),LL(0x16ba34cd,0x9e957ce0), LL(0x7857d80d,0x2b0c7fbc),LL(0x3daffbf3,0xc2c671fe),LL(0x0d251d41,0xebcbf012),LL(0xffef45f5,0xedcfe7f7), + LL(0x334a1734,0xf5b66555),LL(0xe505f4bb,0x4354ccfa),LL(0x52a59260,0x6ee0b5b9),LL(0x5a699a93,0xb7bb64c1), LL(0x6de84422,0x85e34c0e),LL(0x8bbe0560,0xca9bacfe),LL(0x952a52d2,0xa08c780f),LL(0x3919176b,0x0e794b05), + LL(0x154d282d,0x8a496598),LL(0xdc34508c,0xb2999dc4),LL(0x9db4410a,0xfc304fe3),LL(0xe1bc07c8,0xbc09aee4), LL(0xef6d497d,0x1d2f0147),LL(0x96488fc1,0x3b9e06e0),LL(0x34cb97a7,0x37635d04),LL(0x8757f955,0x9a294b89), + LL(0x59508819,0x38c568ac),LL(0x46e15b82,0x854370fc),LL(0xee57f0b4,0x9f676404),LL(0x8f45319c,0x268854cc), LL(0x63746274,0x4256d25c),LL(0x0496cf9c,0x0a553821),LL(0x15e2fc17,0xb6bf27de),LL(0x99bd538a,0x6848f83a), + LL(0x1685e460,0x00e15d0a),LL(0x155d00b6,0x6fae8b37),LL(0xdc561456,0x277126d8),LL(0x6bf70c63,0x331c02e5), LL(0x515f39b7,0xc9b7da4e),LL(0x966c2060,0xb7e0d135),LL(0xc401f926,0x9a801457),LL(0xffb0137e,0xcc560825), + LL(0x5c7e38fc,0xbcfac5f8),LL(0x174e97ba,0xd542c1a4),LL(0x0bb507b8,0xbea67b1e),LL(0x3b782fd8,0xf008cc2c), LL(0x0aa329bc,0x865834da),LL(0x2b6db70a,0x0fd746f2),LL(0x65fbe439,0x8e72e5f7),LL(0x005295ee,0xac23881d), + LL(0xad9d013c,0xc2c45fef),LL(0x71c311f9,0x0df74277),LL(0x6bb32b66,0x69caf967),LL(0xb8e4a3e5,0x9fbd32ff), LL(0x78c0c439,0x39d94e31),LL(0xffa4b625,0x7489a8f0),LL(0x8aac717c,0x59af0ec3),LL(0xa12d996f,0xdd3b470e), + LL(0x8da3fef0,0x6d60cb97),LL(0x044d64fc,0x5164d722),LL(0xfc21305b,0xefe06ead),LL(0xceed89c1,0x72b4c45e), LL(0x8cabf0df,0x072cf1dc),LL(0xa5371d3e,0x0a0d7c0c),LL(0x2ae831d5,0xb13ba707),LL(0x269f189e,0x7702c3c5), + LL(0xc8239fe7,0xfb8e903e),LL(0x524f213c,0x5805c2ef),LL(0x70645f7f,0xdf056e45),LL(0x454c4577,0xfe10ecfb), LL(0x990dc567,0x422126da),LL(0xbf55cd81,0x95a5d753),LL(0x8c2688ed,0x2705a00c),LL(0x2f8f91af,0xd079ecb4), + LL(0x2b69a2c8,0x8cd13fa0),LL(0x36b657b8,0x7b0f310a),LL(0x251c595b,0xa7247cfd),LL(0x5a36e4b1,0xda352dc8), LL(0xf43312de,0x588d2e88),LL(0xdb9f6dec,0xef80a48f),LL(0x3fb2d6e3,0x39583634),LL(0x5a46bc46,0x0fbfa769), + LL(0xfe701598,0x3570a3f2),LL(0xac815fbb,0xd1d0d091),LL(0xd7f2b1b2,0x4d7bfadd),LL(0x66496326,0x509298d4), LL(0xcad9fb50,0xb7accafc),LL(0x9c592dee,0xcdbcb762),LL(0x6888482a,0xfe47a3b1),LL(0xe8b8c133,0x312be210), + LL(0x00167f93,0xc474b07f),LL(0xa637f35e,0x19457000),LL(0x5005d8a1,0x3eafa14e),LL(0xadf25f29,0x2a84723a), LL(0xa741cf9e,0x2c9d7ebb),LL(0xc3913acf,0x94024dc2),LL(0x97b98f1f,0xac2db91d),LL(0x46a7bf92,0xfb9a0502), + LL(0x6487a5d4,0x8874ffb5),LL(0x2f53e25f,0xc02a12b5),LL(0x416ba8fc,0x38654a57),LL(0x0c0b25d6,0x226356f2), LL(0x6030f2ac,0x34f2eaa6),LL(0x9cea9176,0xb788baa1),LL(0x4e912104,0x66fbe9f7),LL(0x39a69e3d,0x982ef71d), + LL(0xbbe5733a,0x9f361d17),LL(0x1988f31e,0xc79569a0),LL(0x9e0f52fe,0xf2b96ecb),LL(0x80235136,0xc78e44dc), LL(0x8462ef4f,0x96053ab5),LL(0x81506701,0xf83c1f6d),LL(0xa65c09e9,0xc7313eb1),LL(0x4efcf558,0xf5dfaa4a), + LL(0xe65ede91,0x8b4819e4),LL(0x6dc0a533,0x5a5824ba),LL(0xb4c930f8,0x89d18b20),LL(0xfcefa378,0xaad7a5d8), LL(0x298dba63,0x2ef790c2),LL(0xe90c322f,0x3e4b31b6),LL(0x52ce2ee4,0xa257bb81),LL(0xd39c36bb,0xb8c2966e), + LL(0x487719c7,0x13954df8),LL(0x791b00e7,0xcb0f7ae5),LL(0xc8d21faf,0x367a1cad),LL(0x3fbd8a7c,0x44dd204d), LL(0x5f67ec30,0x778fdb56),LL(0x5de5caeb,0xfb288790),LL(0xca53300c,0x310b4d56),LL(0x325c54b1,0x37dbb7c4), + LL(0xfe771ef7,0xc80c83a4),LL(0x1c1c1b92,0xe212050f),LL(0xf09c666f,0x0f12bb88),LL(0x10a2eca2,0x8ec5f396), LL(0x90a22eb7,0xdaf96996),LL(0x450de941,0xeb77eee5),LL(0x58fb0165,0x13823c58),LL(0x31272111,0x2157ba6e), + LL(0x2b4f9e7e,0x110ee33e),LL(0xf682d48f,0x7e1b550b),LL(0x3e17cb9b,0x8fd8c6c1),LL(0xe1843894,0x91cfbcf7), LL(0x2917b1c7,0x5fc64346),LL(0xba86d14a,0x06f56d0f),LL(0xaf219f21,0xb8874d88),LL(0x11ab8b0b,0xf8803b37), + LL(0xbe12841e,0x7e63cf63),LL(0xbc90765a,0x9c9cc421),LL(0x1084fa84,0x0264a597),LL(0x252a9bbe,0xce260a60), LL(0x2fefa4f2,0xfaff225c),LL(0x05bd09b0,0x02b900ad),LL(0x11b1b81c,0x631e5cfb),LL(0x0a193140,0x4d93de46), + LL(0xe3173750,0xd92a710a),LL(0x671a3833,0xd712d3a1),LL(0x4116e26b,0xbc9caad1),LL(0xa72fbd71,0xeb24f658), LL(0x9055f802,0x3986a207),LL(0xe2707793,0x212446f8),LL(0x1721b395,0x602541d6),LL(0xb07160c2,0x4099a2e6), + LL(0x2369ce91,0x765390f6),LL(0x5754d219,0x2dc37639),LL(0x7c018afb,0xbc552369),LL(0x35bf6b66,0xca835077), LL(0x61d4b0a6,0x61b83e43),LL(0x27cf66c5,0x8f87f597),LL(0x9357cbf2,0xace57840),LL(0xabe47fb7,0x24834481), + LL(0xdb3c6e47,0xa434c950),LL(0xaa1da775,0x1f479519),LL(0xf14f9d5e,0x338c9cd2),LL(0x1e75f72e,0x4666ce7e), LL(0xe56564e5,0x4fce4d95),LL(0x89e0ff6f,0x0db55ed5),LL(0x00190b73,0x88796e85),LL(0x454e31d0,0xfdf6492a), + LL(0xb9ed6e3b,0x30cb3fbe),LL(0xde8f0544,0x5c796282),LL(0xb6af89bc,0xe11b36bd),LL(0xec439d95,0x0a91cf73), LL(0x0a93fe1c,0xbbe74a5e),LL(0xa5d75083,0xcf1f376f),LL(0xf7725460,0x6718bce5),LL(0xa316d17f,0x6654d7b1), + LL(0x0393aa3b,0xdaa925e5),LL(0x9446cdbd,0x81217e18),LL(0xa7afc408,0x07708483),LL(0x44709dfe,0xa4c76c4f), LL(0x3a1c412b,0x72557d71),LL(0xb49b0e1c,0xeb4c2648),LL(0xe4d6c002,0xcdd24b77),LL(0x77113e0d,0x3384ea5b), + LL(0x6a10a9ea,0x906fb748),LL(0x0a3b0e89,0x46cda42e),LL(0x7ae4ad43,0x10b9096d),LL(0x3bf2afea,0xe1f23996), LL(0x0dd82d19,0xcb50b941),LL(0x832d93a0,0x008e593c),LL(0xd86a71e0,0x0b1fb0e6),LL(0xb1730860,0x75f2aa6b), + LL(0x7efc480a,0xed5d4d7c),LL(0xc76c64de,0x500b9d8c),LL(0xec4fc026,0x28904003),LL(0xdec8b315,0xe41b3f23), LL(0x70c06860,0xa9b5caff),LL(0x28343b2d,0x5cb9a4d1),LL(0x9986a0c3,0xec157abd),LL(0xb5fc67e9,0xbcad3bc6), + LL(0x13aa9c17,0x6e64dd26),LL(0x271aef54,0xa347c4a2),LL(0x883d90bf,0x47b26cb9),LL(0xe1c412c9,0xe84d9c6a), LL(0x1c67439f,0xd2eacc10),LL(0xc61b2b5d,0xd7797bb3),LL(0x8ebdb4be,0x0deda652),LL(0xac3fc2f4,0x9e04455d), + LL(0x27c86688,0xbbfc6e69),LL(0xa1715a33,0xf7cf2947),LL(0x47bc6409,0xe047a3e3),LL(0x6f2a5b28,0xefeb573a), LL(0xd105ba3b,0xbf3ea3af),LL(0x426c6482,0x5f01b4c2),LL(0x968390b1,0x778a5240),LL(0x72bcf6a6,0xc9c71625), + LL(0x6fd8b309,0x698ec2c9),LL(0xa055809f,0x512ea17a),LL(0x8822943c,0x28cb44e7),LL(0xdeb7d3e6,0x434dc709), LL(0x1be76434,0xb8b324d1),LL(0x382ff0b1,0x7cf24ed3),LL(0x2905e726,0xda8265fe),LL(0xee6c3abc,0xd57b3915), +}, +/* digit=20 base_pwr=2^140 */ +{ + LL(0xd2a819b5,0xf9010095),LL(0x48f2f653,0x5291aaf9),LL(0xf0afe366,0xfa533907),LL(0x8e279e27,0x88a58ecf), LL(0xfae130bc,0x0f077127),LL(0xf8a54c75,0xee9ccf1a),LL(0xbed82b6a,0x38a6783e),LL(0xed414524,0x9a1acb3d), + LL(0xd9c12e2a,0xe4e53cee),LL(0x7fc1308f,0x11983fc1),LL(0x892c2d0f,0x3eb4d84d),LL(0x74499723,0xa0bfc1ca), LL(0x0145176b,0x708344d9),LL(0x6f12e75b,0xbb2988e0),LL(0xada67545,0xdf73cead),LL(0x2bb8f989,0xf37069d1), + LL(0x9cc17f65,0xa24a35e6),LL(0x89d9abe0,0xc49b3e9a),LL(0x2fc09ae3,0x82f40303),LL(0x002cc587,0xbffe7d4d), LL(0x424ef713,0x5511f4e6),LL(0xa658f660,0xb86bf654),LL(0x1c8baea2,0x623388d9),LL(0x33656759,0x60664a71), + LL(0xd8447e16,0x18996198),LL(0x662171dd,0x17195d76),LL(0xf448b8e6,0x28cfe6a1),LL(0x0658c923,0x8a3c2823), LL(0x9c35e852,0x0c548d89),LL(0x2b378157,0xadf1cd2f),LL(0xf30113b6,0x999e41af),LL(0x9cf4696f,0xf87515a5), + LL(0x9778aa8e,0x6c332c55),LL(0xd1b8d8b2,0x290ae3ea),LL(0xbf533883,0x3e2bfa0b),LL(0x1a523ee2,0xe48e3747), LL(0x50fde3ed,0x4d40f1d5),LL(0x48710433,0xb57e695b),LL(0x1b241f3f,0xa4101258),LL(0x3042cabc,0xa0cabf7b), + LL(0xedfea522,0x68eb19c7),LL(0xa400db7b,0x68e028b8),LL(0xa8f03a08,0x6cd97bf7),LL(0xf442fe36,0x09f4d266), LL(0x5d713a1f,0x1ac77f91),LL(0x2f58ccb5,0x356e3a35),LL(0xf8ddc47d,0x31d657f1),LL(0x90092115,0xfea7aede), + LL(0x4ad49f66,0x2aeba1d2),LL(0x9d40861b,0x16ff2bad),LL(0x7da225f5,0x25464f37),LL(0x1ffc3f0b,0xa2fe66cc), LL(0xac757f41,0x74074d7f),LL(0xcd0a2c20,0x5c85d3d1),LL(0xc974b266,0xccda2a05),LL(0xcc10a04f,0x5c2e2511), + LL(0x510d515f,0x01ea2535),LL(0x489e7856,0xc861c54c),LL(0x680d17bc,0x9bc8485b),LL(0x819ccc86,0x71472c11), LL(0x0e9b5d8b,0xa7ef9485),LL(0xd029720d,0x698c9fe8),LL(0x61f50161,0x6ce987d1),LL(0x9d240bf6,0x035f6f32), + LL(0x44ec2bed,0xe7c03c9d),LL(0x76cf95c5,0x0bc4f4a2),LL(0x88f014ee,0x0722d57c),LL(0x76fa941b,0xae406348), LL(0x23ee068d,0x046424df),LL(0xe8c130c5,0xd30b6530),LL(0x554f149d,0x17b69098),LL(0x92f95b71,0x887e04f7), + LL(0x941c1244,0x414e7371),LL(0x94f1da50,0x1d48fe53),LL(0x6519802a,0xc18bcd89),LL(0x48925019,0xfae7c2d8), LL(0xf2ece2af,0x0f311ddf),LL(0x0a779f79,0x7e8e0e08),LL(0xb6207944,0x47daa5f9),LL(0xefd08d6e,0xf29dc331), + LL(0x23e48f60,0x9c096e19),LL(0x8dd36f0c,0xbcc6fe53),LL(0xbb86a9ca,0x452e60f9),LL(0xed16cf06,0xad35f732), LL(0x2bf445f7,0xcbdd01a2),LL(0xf60ce893,0xb7848e94),LL(0x2939a977,0x5e65e8ca),LL(0x63cfa5e4,0x304ebedc), + LL(0x252cc655,0x79bae721),LL(0xc4743792,0xa3b9a4e5),LL(0x36fdba1c,0xf32dcfeb),LL(0x7ac19885,0xadbd0c1f), LL(0xdc42a2cd,0xefb4fb68),LL(0x2289a71f,0x78b1ca37),LL(0x87fc6df4,0x7e1f70fe),LL(0x90a9faec,0x8d024301), + LL(0x46cd4141,0x37c08672),LL(0x1a60d8e5,0x3c0fed17),LL(0x0f56fea1,0xab18bf06),LL(0x372e757b,0x879ee748), LL(0x1d280206,0x84b19b80),LL(0xd96ac240,0xa40d7ce3),LL(0xfea42ebc,0x5d493fb1),LL(0x40d79bbd,0x9a5fdafd), + LL(0x383b371c,0x790c0b30),LL(0x676f8168,0x6dae5df9),LL(0x4c584948,0x101bb4fe),LL(0x55faafeb,0xe3d7e99f), LL(0x134c2e3b,0xd2c9aefa),LL(0x79e27788,0x0aa2a71f),LL(0x7ed0a606,0x4082f7a6),LL(0x6a1be308,0x843c12bb), + LL(0x56e9e473,0xae72ee74),LL(0x743e16ee,0xcecde6c1),LL(0x7c48ca04,0x9a06f105),LL(0x5f822a31,0x79179cd2), LL(0xe3530605,0x570d3eeb),LL(0x4c7b03b0,0xbacb30c3),LL(0x0eea0cb4,0x0a8fe254),LL(0x2cdf203a,0xa052a555), + LL(0x9c34971b,0xee031587),LL(0xe76545cf,0x5829eb07),LL(0x33a81bb9,0xb7a3a6ae),LL(0x49c9f710,0xff42daff), LL(0xbffb951b,0x894eae85),LL(0xce70f324,0x815fe3e2),LL(0x428b1f12,0x636564cb),LL(0xa029b0bd,0x722e0050), + LL(0xd373a65b,0xf45cb816),LL(0x6078d95e,0xf2210e00),LL(0x20d2924a,0xf767d7a6),LL(0x25b66987,0x06d6b552), LL(0x790563a1,0x5c4a3999),LL(0x3c85510c,0xcea00a91),LL(0xd2db6297,0x7e37da9c),LL(0xf67303e8,0xfca4735f), + LL(0xaf76f475,0x324ca06e),LL(0x76391adb,0x3367845e),LL(0xa26fe169,0x222aa1ce),LL(0x7ede94c7,0xb15a8665), LL(0x6b6a1f33,0x5b736342),LL(0x8562f392,0x25db61e1),LL(0xf2066206,0xfd4d720d),LL(0x82c555c3,0x26ef773f), + LL(0xfde6caa3,0xb6e35b3a),LL(0x87fabf4a,0x34eb5e13),LL(0x86236a62,0x4ad68635),LL(0x28510f8f,0x2651d3e6), LL(0xe0873ba6,0x88073e34),LL(0x22f63746,0x3becce70),LL(0x7c08dac6,0xff8f9b61),LL(0x8c28aa65,0xc8b45a9c), + LL(0xd87b59dc,0xe09c063b),LL(0xcbbdd4ec,0xf3e4b9ef),LL(0x4855a43e,0x1b6b1793),LL(0x4ada74ac,0x594d5565), LL(0xb410c5ef,0x10ee400f),LL(0x35695fe9,0xfc118113),LL(0x8f75d723,0x766cfe48),LL(0xff63aa76,0xc72023eb), + LL(0x9df9a165,0xc503a858),LL(0x851acc4b,0x9b1099ef),LL(0x66202ca0,0x9246c61a),LL(0x81390ccd,0xaba97788), LL(0xba9e2785,0x3309fa65),LL(0x2220f385,0xbc0388be),LL(0x00ddc8ba,0x94c01a9e),LL(0xbccfdec8,0xaa54aed9), + LL(0x059fc0d6,0x1a959c58),LL(0xf518e1c1,0xd0f34c38),LL(0xb53be8fe,0x38aa2b1d),LL(0xacdc872f,0xd95a2a19), LL(0xb4140bd6,0x97bde382),LL(0x4cfd5718,0x4084ba9d),LL(0xfd22450c,0xed016bfa),LL(0xa5d1f5bc,0xf00cdccf), + LL(0x111696ea,0x905114cc),LL(0x3a46e782,0x1f58a4d3),LL(0xa5e57fa0,0x899d1856),LL(0x68c45c2f,0x25186954), LL(0xfa6e3eec,0x806deb4a),LL(0x65a063a6,0x3c358d48),LL(0x3feacdcd,0xce28ed1f),LL(0xaaa8e601,0xef9ee31c), + LL(0x87c1c66b,0xddd4fe3d),LL(0xb3dbfac5,0xfc2b063e),LL(0x20c81dc5,0x52d37cd0),LL(0x083b5f53,0xb628f163), LL(0x7e42860b,0xd9295094),LL(0x307316ab,0xb877a744),LL(0x6b8d99b6,0xadec0d2d),LL(0x190bc675,0xa75183bd), + LL(0x4ad6bd44,0x2b1e0215),LL(0x9e020c66,0xda01ad52),LL(0x0c2913d9,0x65afd73d),LL(0xf0035373,0x67024b45), LL(0x4d308206,0xf501bb4c),LL(0x77e2e936,0xfa020c88),LL(0x936476a3,0x662b72bd),LL(0xbae57d17,0x07f76845), + LL(0xf34ca404,0x77a43055),LL(0x4eebc853,0x8e403294),LL(0x402fde89,0xe19ee69a),LL(0xfe00df56,0x9092acd0), LL(0xfb225f92,0x640c035c),LL(0xdce3aa84,0x92d94246),LL(0x971e9886,0x7fe8d3f9),LL(0x014b2a74,0xc569905e), + LL(0x7b7c299b,0xbafb8c4d),LL(0xd534cd21,0x3d289c60),LL(0xd311dee4,0x95e7032b),LL(0x6e8892a4,0xac0c46dd), LL(0xe5bd6486,0x9fedef00),LL(0x99f703aa,0x3f4d8daa),LL(0xf0c0ecd2,0x78e47925),LL(0xfdac73de,0x8f143c2b), + LL(0xc14bd094,0x1f88f5a9),LL(0x99d9532b,0x6cc19e43),LL(0x639ba66c,0x6e474499),LL(0xf5d06b03,0x5d9a283b), LL(0xaa25dbb5,0xc7e8164f),LL(0xf03faec8,0x7ab42a48),LL(0x647a0d72,0x4135765b),LL(0xe196b571,0x9562a676), + LL(0xa720cc20,0x62cc4c05),LL(0x13fa1ad2,0x9ed3f637),LL(0x7f59bac9,0xe5816f51),LL(0xb6884359,0x738e1544), LL(0x34d0fb02,0x83bb2666),LL(0x8014c57b,0x0e582c6b),LL(0x145e2bff,0xbb4069ae),LL(0x4f5f1d7d,0xd1965cdf), + LL(0x3cead86d,0xaf77f98b),LL(0x0e51cbd8,0x0ba278bd),LL(0xac2ebb7c,0xf11f20f6),LL(0xc9992b55,0xafd2333f), LL(0x322472b6,0x425dd0e4),LL(0x0958215e,0x0027a74a),LL(0x4cf7e0e4,0xddb301e7),LL(0xcbb70c2e,0xd0656ed5), + LL(0x0e7662e8,0xa40f629f),LL(0xe399a5ca,0xdaa85755),LL(0x7297010c,0x4c119aba),LL(0xe5df7140,0x4a4a6a43), LL(0x474f7873,0x6d90d303),LL(0xd1f8f867,0xc5b0e19c),LL(0x4f6dc217,0x188bcae6),LL(0x6777357f,0x51ce999a), + LL(0x41aeb39f,0xdfc9578b),LL(0x7dd55c1f,0xeeda86fe),LL(0xfb814075,0xd4b8fc54),LL(0x33a1317c,0x12e32a78), LL(0x2fd217d1,0xeb79cd2b),LL(0xdbd07638,0x5f5f20c0),LL(0x53dc7d8b,0xfc57643a),LL(0xf08350e2,0x65126014), + LL(0x871b0d3d,0x737ef5b4),LL(0xae3143a5,0x6b7e04ce),LL(0xb7ae12b9,0x0e5ab52e),LL(0xdb66ee0e,0x1a956daa), LL(0xeaa7042e,0x59657e47),LL(0xbf84a2cf,0xbbc35318),LL(0x78679b8b,0xef55429c),LL(0x60cb7678,0xef92df9d), + LL(0x1dd267d6,0x17655580),LL(0xeb0bc1fa,0x00a3ec71),LL(0x50514840,0xafa0a256),LL(0xf161c685,0x68c28d0c), LL(0xb1c766dc,0x069f7862),LL(0xd5ad4568,0x6868a463),LL(0x70e46d7d,0xf9c3d670),LL(0x6c875260,0xd2432cc9), + LL(0x088cecd9,0x534c3425),LL(0xb4e34c6c,0x3f1818e6),LL(0x028f153b,0x3aedf0a8),LL(0x50d9433a,0xe0a1cb9d), LL(0xe523b764,0x9b4e225f),LL(0xe5f8542c,0xcba6cba9),LL(0xa8f6b81e,0x59c307e4),LL(0x01bb44fc,0x36abf4b7), + LL(0xdd62528c,0xf7692c14),LL(0xdf57773e,0x0d4a8341),LL(0xc9b4f968,0xece6957d),LL(0x52779586,0x82eda200), LL(0x2f06ec6b,0xb902c488),LL(0x91a876f0,0x127dd7ba),LL(0x33ad0c13,0x06eb96d8),LL(0xfc5985ce,0xd7394080), + LL(0x661aaa4d,0x624c8f61),LL(0x6717a3e1,0x6fe10a11),LL(0x53168ad0,0x6c288c53),LL(0x8b52d037,0x91b8779b), LL(0x1b5b0ab9,0x89e664d4),LL(0xf30d47d3,0x9f69b44f),LL(0x03176019,0xfe67cad5),LL(0xb346a205,0xb83efd48), + LL(0xaeea0c91,0x63fc4863),LL(0xdb56004b,0xbabf9042),LL(0xa9917def,0xdb19f2ee),LL(0x54c3fae1,0x1d12f2dc), LL(0x55e36d40,0x7bb496af),LL(0x6be63b27,0x1f6c11f8),LL(0xcaf9a5b9,0x96d79804),LL(0x0648051c,0x03a085c4), + LL(0xb56baf4c,0x3b54c223),LL(0x559c1fc1,0x04af8c4c),LL(0xabd3cebb,0x05d55266),LL(0xf865e262,0xd2d3ae9b), LL(0xedfedc54,0x3bd3ca3a),LL(0x922776c4,0x30a6ff1c),LL(0x1616a6f2,0xfecd8845),LL(0x94948d8c,0x4e7bc2e8), + LL(0xedca784b,0x16e0d824),LL(0x67ea1eea,0x84584f98),LL(0x8625626b,0xeceb1418),LL(0xc34fc1f3,0xa487cf9f), LL(0xa57cec36,0x4ecfedd2),LL(0xd24a0709,0x08624865),LL(0x6a48f3ee,0x47bb1909),LL(0xc69bc041,0x54c5dd0c), + LL(0x7527166e,0x15a291e6),LL(0x4a9a8315,0x8a92370d),LL(0xda584bd6,0xe9fe705d),LL(0x3625a669,0xed441dc3), LL(0x3063f2de,0xa57929ce),LL(0x6348cc31,0x2809fe4b),LL(0x04cc19c0,0x92041d54),LL(0xb62c1f94,0xd7c227fc), + LL(0xcd0d497c,0xecfeee53),LL(0x128818a8,0x8d1ea9fd),LL(0x2ae4725d,0xb5cf2c28),LL(0xc6abad3a,0x7de9f967), LL(0xb14a183c,0xc64a11fc),LL(0xd5777d77,0x7f14d0fe),LL(0x12957444,0xbe79846c),LL(0x0e3257ca,0x4cf23abf), + LL(0x6e01b48e,0x8da0fd8d),LL(0x5ee87ca4,0x63a7ff16),LL(0x5cc96b94,0x90dff4d3),LL(0x406fc905,0xff1b41c3), LL(0x3ac71c41,0xdd932925),LL(0xcf65e59d,0xec57f1b8),LL(0x3ce0512b,0xa3116d6f),LL(0xa2e28316,0x3b46fd3c), + LL(0x60156a5e,0x5a6c0314),LL(0x55d46fd0,0xfab3afe3),LL(0x9846f0db,0x4617926c),LL(0x121ef237,0xc2d5a447), LL(0xf1cda3b1,0x789498d1),LL(0xccd64aac,0xa195cf03),LL(0x9440be2b,0xe8d1a162),LL(0x3ad5373e,0x7399890a), + LL(0x4fbf1899,0x65dcea2f),LL(0x44ee1a5a,0x44d9c8ab),LL(0x406880fb,0x2e94f8c8),LL(0x51faab7d,0x70732bad), LL(0xf1e92b52,0xd69309dd),LL(0x3c7685d0,0x25f9a675),LL(0x1dbfbaa0,0x3604f30b),LL(0x2ff28c22,0x5ac0001b), + LL(0x52762d8d,0x648ec4fa),LL(0x0cef95f8,0x4fc248c6),LL(0xe5fbb57d,0xfc0f7030),LL(0x5ff2db51,0x2e644729), LL(0x3775471c,0xd85877ec),LL(0x6076a271,0xe2580058),LL(0x09cb3873,0x58a4a24f),LL(0xb142da8c,0xb412928b), + LL(0x5997987a,0x1da7964b),LL(0x1825d97b,0x69765ff0),LL(0x4c97095c,0xde8ae407),LL(0xbb59316c,0xb257a968), LL(0xcf2dfbd2,0x80e5240d),LL(0x1fccd0e7,0x2b3b04b0),LL(0x8ff1093e,0x949f1234),LL(0x65f62273,0xa4df3290), + LL(0xd0058ffa,0x305b7479),LL(0x180b0de6,0xe459ecff),LL(0x8ca0585f,0xfbe00c08),LL(0xc3dd4fa0,0xc169e23a), LL(0x44026f6e,0x65d9009a),LL(0x1d96fe58,0xbbc258c3),LL(0x328ed1e0,0xd7ed379c),LL(0x23970884,0xe8b45744), + LL(0xed1095b5,0x2f44c8ce),LL(0xc59404aa,0x25725b0d),LL(0xa273e09f,0xea926278),LL(0x529143d5,0x102b120b), LL(0x81174d10,0xbd2c012d),LL(0x4e8333ad,0x0bf5cf89),LL(0xb2f60645,0x6b93e3b0),LL(0xf38df3ce,0x040298b8), + LL(0xb89e18fd,0x6433b6fc),LL(0x6bd6af88,0x48d6584a),LL(0x0e1747a5,0x46c8a061),LL(0x1ed79faa,0xe225d3cd), LL(0x5c28a48b,0x6c579abb),LL(0xda3889d6,0xc7a5ff4d),LL(0x008febdf,0x037ebc4b),LL(0xa7c5cbc9,0x03b60593), + LL(0xdcaa3319,0x0840804d),LL(0xb7481f45,0x38b0f084),LL(0x112e794e,0xfdb059c9),LL(0xe1afb614,0xb62bce05), LL(0x53be7c02,0xc15035b6),LL(0x153ee8e5,0x66fc7106),LL(0x8258727f,0x27fd2ea4),LL(0xb470105e,0x8e012416), + LL(0xd7711aee,0x3d24685b),LL(0x021bab69,0x66a83c3b),LL(0x5501d69d,0x6e1112a7),LL(0x068b0504,0x2219fe0b), LL(0xa926ab1b,0xaaa553c1),LL(0x56d6ca58,0x1c81af95),LL(0x221ef447,0x0a997380),LL(0xf5f55487,0x881a62fa), + LL(0x4f1b618a,0xf88fa0bd),LL(0xcbac98e8,0xb20e161c),LL(0x3bc6a7ad,0x443352b5),LL(0x0fd5748a,0xbc8e03ff), LL(0x0ca427fc,0x64006aff),LL(0x7cbbda99,0x1a477593),LL(0x1a347c47,0x21ef1afd),LL(0xdee162b6,0xfe056287), + LL(0x797a0b14,0x9d4eb7da),LL(0x951c4bd0,0xe4e01a46),LL(0x7fe354a6,0xaf8fa17f),LL(0xc430b12b,0xd71f160c), LL(0x83d46be0,0x5bb68437),LL(0x619bba86,0x99d10d82),LL(0xf4327042,0x95c2219d),LL(0x9c19ab57,0xdace2322), + LL(0xc8750fe7,0x88abbc67),LL(0xd3abe7d2,0x81ab300a),LL(0x45aa8948,0x62a6d8d5),LL(0x5d4ce8c3,0x76175bbd), LL(0x8ea70976,0x095cb181),LL(0xf7e62a19,0x785de3fc),LL(0xed11a7fe,0xc478bce8),LL(0x1528aee2,0xb7e5993b), + LL(0x76c32e4b,0xb9ec58d7),LL(0x2dbc9a61,0xef815613),LL(0x5e07410d,0x372c3856),LL(0x033276d0,0xa1b16510), LL(0x82640d26,0xd8589581),LL(0x9053fff0,0x1cb98180),LL(0xc1ff11f1,0x41519ce7),LL(0x666431e4,0x2f21a48f), + LL(0xe83ee840,0x2c223ed1),LL(0x1e7cf4dc,0x833ae708),LL(0xacd13385,0xec8853d8),LL(0x6a7a8cb1,0x559115ab), LL(0xeb184e71,0xe2f4ab2a),LL(0xc10194df,0x679abbce),LL(0x3aca0828,0x10199c84),LL(0x978cc1d6,0x7474e113), + LL(0x44e8eb9a,0xa4460ef1),LL(0x828aa4bf,0x4cde5260),LL(0x249bff50,0xd3d23790),LL(0x6bc7fbbc,0x2e6660da), LL(0x61494df0,0x3e3cc146),LL(0x0bcda8ba,0x6e9a1571),LL(0x096e00b7,0x68ce233e),LL(0x5106c85b,0x247a5c49), + LL(0x55fc5757,0xe6f0cb5c),LL(0xb7585799,0x452682b9),LL(0x869e747e,0x84509dfe),LL(0x8d23be04,0x904366e5), LL(0xb0f72c6d,0x7324a14d),LL(0x1913a9ff,0x9fbe3116),LL(0x428a6b5d,0x2f9fa62a),LL(0xf8a34d9e,0x8039270f), + LL(0x407aec78,0x0e3ce7ae),LL(0x826458cd,0x4d935d3d),LL(0xfc6f46d4,0xf75db7db),LL(0x88586874,0x3ab7ba68), LL(0x9a198b50,0xec92749f),LL(0xefc51cdb,0x0ffc7681),LL(0xe17bc0e3,0x951406d5),LL(0xc898a018,0x39cd2d07), + LL(0xf2f79af6,0x9dc3803c),LL(0x0a56cd68,0x292f3164),LL(0xf6fbdbdf,0xdcac21f9),LL(0x23e9e959,0x6f9ce2a4), LL(0x970f6c34,0x2011d221),LL(0x9e2decfb,0xd2e63711),LL(0x118ff327,0x19c7a489),LL(0xbb6e534e,0xe19d7e83), + LL(0xbd1a426b,0xc685389a),LL(0x8c679952,0x432ff7b0),LL(0xc5e2687f,0x516cbdfa),LL(0xba1eac8f,0x8242405d), LL(0x0b09854e,0x63af3152),LL(0x231ec979,0xcecd0faa),LL(0x7273f0b2,0x4746733f),LL(0x8f001365,0x69b28d87), + LL(0xc6f2623c,0x0d87d506),LL(0x86c40ed2,0xd209a9c6),LL(0x0fa20f3b,0xa5b7fde2),LL(0x4f5b2129,0x54550dc5), LL(0xfeddaa1b,0x36884047),LL(0xd899a29f,0x51398fa0),LL(0xcdf11867,0x14a416be),LL(0x3e466b62,0x86351ac6), + LL(0x39bb481a,0xd63e91e1),LL(0x99984155,0xdcdc072a),LL(0xd2d8e622,0x9fce6e38),LL(0x8e8c8034,0xbf6978b6), LL(0x8c37990a,0xaa1ae874),LL(0x0e749b86,0xd1f0e068),LL(0xcbdc7c12,0x5aa303b1),LL(0xc9130211,0x9a78baaf), +}, +/* digit=21 base_pwr=2^147 */ +{ + LL(0xb3e2087b,0x5eeba910),LL(0x44a61a33,0xbd016dd3),LL(0x48cd5c0f,0xffd1f081),LL(0x2e6a8e94,0x041c6aa0), LL(0xc4ac3d91,0xe09c35c5),LL(0x634767a4,0x58298105),LL(0x1040c2b5,0x6120e7cb),LL(0xa713589f,0x32a661ef), + LL(0xbd74c70e,0x5a056a90),LL(0x8af672f3,0x44f7d00d),LL(0xef4e9a48,0xdc25ab68),LL(0xfdfb1069,0xadd15cc3), LL(0x9f3033bf,0xb1f4fd28),LL(0xebb8b8a7,0x088a49bb),LL(0xa8d2861c,0xea485869),LL(0x6b977fb5,0x46dbfdaf), + LL(0xd88ae888,0x04e6461e),LL(0x9be2d7ad,0x112d204a),LL(0xdb558427,0x952dc813),LL(0x27e35200,0x39b01652), LL(0xff02cdbb,0x8b89bfce),LL(0x3e854e4c,0x1381a99b),LL(0x999efd2b,0x68185218),LL(0x86dc62e1,0xeb41e1bb), + LL(0x02d0aaff,0xa264ef40),LL(0x6e679fe2,0xa678c07d),LL(0xfd88bdce,0xcff13be7),LL(0x617badb8,0x9a8efe8d), LL(0xad5a22f4,0x1388a815),LL(0xfec398b3,0x8f821400),LL(0xff4fc2da,0x85a6a565),LL(0x858dd4f3,0x681f0181), + LL(0x91ee75bc,0xdc870745),LL(0x64f20e50,0xbadbf940),LL(0x49d3d417,0xf3ea437f),LL(0xc02109d0,0x7bebd868), LL(0xd16bb240,0xe6c8d93c),LL(0xfdab9bbd,0x2087141a),LL(0x20a3b470,0x8dba80ff),LL(0x29d3a8d7,0x960a0c7b), + LL(0xf8ec1151,0xae61b637),LL(0xaadc8545,0x415dd36b),LL(0x69d0985a,0xed21d176),LL(0x97893f50,0xc4d062af), LL(0x337b81f9,0x4d93ba1a),LL(0xb7c163a2,0xb995fe9e),LL(0x5416e4ed,0x447eff3b),LL(0x0bf4a8e7,0xd7660300), + LL(0x56d9e00f,0x9e14c6a2),LL(0xfa1f60e0,0xa228491c),LL(0x8782a9be,0xd540713e),LL(0xdcd55e21,0x5d3fcce8), LL(0x35c87b90,0xa176c34e),LL(0xf9508f35,0xc1d80aa1),LL(0x92302d47,0x14f7e7fc),LL(0x2b076e72,0x459372ba), + LL(0x4e933b19,0x44168fbc),LL(0xe54ea969,0xaf2db74c),LL(0xaeacbb56,0x36fade13),LL(0x84e6cd1d,0x29708665), LL(0xb692df97,0x6f7ff1e1),LL(0x6ae66307,0x5a68c1a2),LL(0xe7685f20,0x85bc544c),LL(0x0f65eeec,0xb3f42e6d), + LL(0x5b91b644,0xef209f44),LL(0x50cb02b6,0x808b930a),LL(0x099f684f,0xc5da5e86),LL(0x4330c2d8,0xd8f1dbcc), LL(0xd8608776,0x52e8cab5),LL(0x16e56f5d,0x13c89771),LL(0xb135282b,0x7d7d802a),LL(0xe9be8a20,0x69762c39), + LL(0x2a08a1dc,0x13f6bbad),LL(0x7f2dba7a,0xa7131e4a),LL(0x7864f5a3,0x751dce48),LL(0x08135109,0xc5af1b45), LL(0x4f08636e,0x3c4d75f7),LL(0x2e251e48,0x9949b2f5),LL(0x9bd98853,0xd0497977),LL(0x909b0e84,0x09d8e627), + LL(0x4ceff1c9,0x505753ee),LL(0x460710ca,0x03ca4571),LL(0x5480abc0,0x0cf72dee),LL(0xc19c8ef3,0x55d5a30e), LL(0x86541f6f,0x9e47641b),LL(0x10c9d6fb,0x89b2e48f),LL(0x0860915c,0x9d16382b),LL(0xf54b337f,0x770ac417), + LL(0x77ef7f67,0x366d0781),LL(0x2b6340c9,0xfefec947),LL(0x097acf63,0x7ce3a056),LL(0xaf306dec,0x26538c7c), LL(0x287dc8d1,0x8a8bb55e),LL(0x448823ae,0x9431095b),LL(0x7970fc51,0x8358087a),LL(0x413509ac,0x95299959), + LL(0x8b0911d4,0xb165f92a),LL(0xbfb37459,0xdde855ee),LL(0x3d9ce36e,0xe672eed4),LL(0x74bae261,0xf7da91e5), LL(0xb741c8e6,0x1f67323c),LL(0xc92c91ce,0x8efd4661),LL(0x78e73c42,0x556f0b1a),LL(0x16101f96,0x7d326b7f), + LL(0xfb48bd3a,0x8814ef0b),LL(0xc508309e,0x1bbbe13e),LL(0x67709c10,0x7ddaf061),LL(0x6436f655,0x82b67847), LL(0x03712e64,0x2a5601c6),LL(0x3e3f9b2e,0xac1f0362),LL(0x09184b5d,0xcc7e6a09),LL(0xb4625149,0x1258b265), + LL(0x384a6b54,0xd9f21461),LL(0x6cfe9311,0xde483161),LL(0x889f43cc,0x593dae45),LL(0xedee221b,0x8454335b), LL(0x3a2cbced,0x90f3fb43),LL(0xcc8dcb75,0x895ed692),LL(0x14233aa7,0x9857d719),LL(0x48166d5f,0x91b1a2ab), + LL(0x675b47a0,0xfbf7033a),LL(0x6542378f,0xcb3669c4),LL(0x125ec248,0x96abb0f7),LL(0x795fc346,0x6d5d2047), LL(0x8f5cffb6,0xa6c6c9e8),LL(0xbea5ee09,0xb968f2c7),LL(0x844ffd6f,0x2f2ce735),LL(0x27e40ac8,0x7931b877), + LL(0x2b63d538,0xe1f62dcf),LL(0xf44d7bf9,0x395681dd),LL(0x54aec359,0xf02eedf7),LL(0xa0ad5eb7,0xc64b6233), LL(0x346b086a,0xc65093c7),LL(0xe957b243,0xfcf8ecc9),LL(0x1ca48020,0xe1accffa),LL(0x4047bbeb,0xe1f29792), + LL(0x9fc6be25,0xb1097d40),LL(0x923eb7b4,0x02d33d19),LL(0x1f58f545,0x9e25200c),LL(0xda51efcb,0x2ffae306), LL(0xc0b011f2,0x7e6d76c1),LL(0xf680676b,0xedbd8398),LL(0x8d7fc8c2,0x38517fc2),LL(0x5c3ab05c,0x55a7fcf9), + LL(0x8e6dd02d,0x047e2422),LL(0x1f290d6a,0x7b3bf0e6),LL(0x6a99a6d0,0xbcf326fc),LL(0x2eef8232,0x1e3f38fa), LL(0x15bac529,0x9890780e),LL(0x9f143ba0,0x94202e0e),LL(0x885e4ed5,0xbd574712),LL(0x396f938d,0x2404c223), + LL(0xacde8286,0xd54d401c),LL(0xe7af01fd,0x80397794),LL(0xf615a8eb,0x94457d07),LL(0xd22d9ef7,0x34680480), LL(0x2c489ccf,0x04d4b302),LL(0xc3673dae,0x11dea4bd),LL(0x58cdfe41,0x8fbb4df5),LL(0x0f10a70e,0x49425184), + LL(0x077a59ce,0x831b977a),LL(0x894627f3,0xee08fb0c),LL(0x2f8553f0,0x21360507),LL(0x0487171b,0xca77ccd1), LL(0x07e11059,0xc17d20c2),LL(0xbe613256,0xcf74be6b),LL(0xa5fe18c1,0x06f185e6),LL(0x2b57ce3e,0x8d2cf4f5), + LL(0xc9c983e7,0x7179273c),LL(0x153f58d8,0xc7d27357),LL(0x4f400bd4,0xc0273069),LL(0x26262553,0x23309c7f), LL(0x712d0314,0xf26b6e11),LL(0xf96ee39a,0xb925cebf),LL(0x73944251,0x6df57108),LL(0x589d90aa,0x95419b24), + LL(0x796a8ee2,0x57a1bcc5),LL(0x2acee09d,0x22a22530),LL(0x66fa2911,0xa4c2cc03),LL(0xd85f13dc,0x9cc2b7fa), LL(0xce152790,0xf2498b8a),LL(0x1caf39d1,0xd8406007),LL(0x84c0822f,0x7ff50064),LL(0x155f1280,0xaf14ca4b), + LL(0x89b781c2,0x113f094b),LL(0x013833a5,0x996bf893),LL(0xc0b9cf6d,0x26bc6210),LL(0x6a88f1cf,0x18e2d3ac), LL(0xa21a2d35,0xc0ff2b3c),LL(0xa79e918e,0x409c2598),LL(0xb6917e22,0xffcf65a0),LL(0xbb4f8f3c,0x8036897f), + LL(0x9ec27fd7,0xac660365),LL(0x0c56cbb1,0x3c5ca1a9),LL(0xbe9e9ec7,0x01c5dce1),LL(0x386edb4a,0xdc21b01a), LL(0x4b1dde01,0x47e02a92),LL(0x44af3e0b,0x0613b7ca),LL(0x1c445b6f,0x644ac708),LL(0x87243e2a,0xb5566f0f), + LL(0xba9f354a,0x5b244172),LL(0xeb653a5e,0xaca4e9d3),LL(0x514809f2,0x6ff6904a),LL(0x96595230,0xf87a329b), LL(0x8d4bd051,0x39ebe6eb),LL(0x07d17d59,0x66f05f5c),LL(0xe0f81731,0xfa1ee673),LL(0xd12804a9,0xf41c1042), + LL(0xacd14cf5,0x1c4a655a),LL(0xef47548f,0xdc72f5bc),LL(0x0b3ee6c7,0xab07ceff),LL(0xbb501a28,0xcfa88319), LL(0xd8f03f7c,0xcec9c2e2),LL(0xe0c98d62,0x3098d752),LL(0x0a8681b3,0xa41a0794),LL(0x23587932,0x0e588076), + LL(0x5ef86f7c,0x4617dc66),LL(0xcedb5377,0x51de8430),LL(0x737381b6,0x0dda704a),LL(0x008f4671,0x83a44653), LL(0x38401c11,0x71bbb73e),LL(0x4894d378,0x879fe49c),LL(0xeab186a2,0x8875eef9),LL(0x12a382a9,0xedefe278), + LL(0x13b897fd,0x95ef41b8),LL(0x2a98ddd9,0xfefd495f),LL(0x680b12e8,0x09cbccfc),LL(0x167da5dc,0xc1888a21), LL(0x3bb290b4,0x2a204912),LL(0xd9613190,0xdcac95fc),LL(0x709c76f7,0x4df94f62),LL(0xa5cea926,0xc8c3a8ab), + LL(0x37a2b813,0x15c876b2),LL(0x9c3c821c,0x9b52803e),LL(0xcb3d6ff1,0x40f2268c),LL(0xa1573601,0x689f1696), LL(0x8e921f56,0x8d7566dd),LL(0xd992335a,0x5d8a990c),LL(0x20dc4f4b,0x6339153a),LL(0xdc5d06ab,0x0b07419c), + LL(0x97c201f9,0xe9cc014d),LL(0xa635f472,0xec04a52e),LL(0xa538a84f,0x6aac504a),LL(0x5762fe7c,0x4d0288e3), LL(0x34cbd09a,0xaa8539f0),LL(0x2619bcf7,0x6f7e0e94),LL(0x0dd338d0,0x178303dd),LL(0x8326f40e,0x6b58c2b1), + LL(0xfe73e699,0x98bb15ec),LL(0x47526489,0x7533abdc),LL(0x491dcc6d,0x4b269607),LL(0x77187363,0x325ec2a0), LL(0x7e9ab865,0x766faa19),LL(0xc25a9448,0x1c105b4a),LL(0x0531b5ba,0x0b6b8963),LL(0x2db1a579,0x32691f11), + LL(0x643e479c,0x24d90a57),LL(0xb98578df,0x048b27cb),LL(0xe53bed53,0x0600f93f),LL(0x0aac585f,0x1fd57dfc), LL(0x71d0e4e0,0xc3d72121),LL(0xf612fc4e,0x5ff10dfb),LL(0xb5a7ec79,0x9edf4b23),LL(0xd87706ab,0x975165c7), + LL(0x7095c3c4,0x8b99db04),LL(0x897faf50,0x65196441),LL(0xdd5b64cb,0x5d23d7d9),LL(0xe95fe601,0xec734b06), LL(0x0b5fcde9,0x03a5f53f),LL(0xebe35310,0x0186ad22),LL(0x84846603,0xe9a65eef),LL(0xa7c6e5be,0xe99e5188), + LL(0xf0887da6,0xa917327d),LL(0xe3f9fa70,0x49965f78),LL(0x4f10b31d,0x02ed227d),LL(0xb6120be5,0x535b4386), LL(0xcc1bf98a,0xdff21a8a),LL(0xeb1634bc,0x5b52a09a),LL(0xa3f61fa2,0x60f8690d),LL(0xb863c790,0x58a02566), + LL(0x5c6b2929,0xf9b90a9e),LL(0x22fca36e,0xd552e84c),LL(0x9eabcb58,0x6b23da4f),LL(0x5d4136dc,0x01111d07), LL(0xb3642a09,0xfaa80059),LL(0x5f49d533,0x1de667f4),LL(0x17525176,0xb3268776),LL(0xda729fde,0x75b0b102), + LL(0x6e9fe6ed,0x4ec7f678),LL(0x2717f8b0,0x28d29578),LL(0xd4cc149f,0x6a713c37),LL(0x7dfdf8c6,0x4804e04f), LL(0x5c931aa6,0xe7c6daab),LL(0xa0394f29,0x793e411d),LL(0x79ed9819,0xc0741c0d),LL(0x24d5d992,0x3f2ba70b), + LL(0xca9c987a,0xa61dc03f),LL(0xe64b50c1,0x78201cb8),LL(0x1861f4e4,0x45a23c25),LL(0xc4ee5d82,0x10f19f4f), LL(0xf3f055f4,0xf1520547),LL(0x006ccf49,0x69ae26b3),LL(0x33d8d4ad,0xe96eec0b),LL(0x48a4fc2c,0x00765f0c), + LL(0xa3976c07,0xad47e14e),LL(0xd905b6b4,0x82b1f882),LL(0x91382bac,0x7a1b9d73),LL(0x18178290,0xcc84a820), LL(0xb4e845ab,0x1123c6f6),LL(0xb92e3b08,0x63216635),LL(0x183879fb,0x748be745),LL(0xa73e9ada,0x7f20e1f0), + LL(0x9224c152,0x05de3e11),LL(0xea8fda4e,0x2fa9a474),LL(0xf48055ec,0xf5c8df05),LL(0x9e23a599,0x48bbf43a), LL(0x148086db,0xf593f034),LL(0xef0a2b62,0x0173a87a),LL(0x3fbabb6f,0x90ef0132),LL(0x21ade107,0x56ced09a), + LL(0x73f1d3e0,0xcf1ce892),LL(0x22424580,0x765236c6),LL(0xd939d063,0x0d223937),LL(0x7cb2fe2f,0x9a21beda), LL(0x1ce3a7fc,0xa559a571),LL(0x1b060dd5,0x7fd6b255),LL(0xc5afdf1a,0x4dfbd210),LL(0x1239368a,0xa74751ce), + LL(0x6d9a3eec,0x93acdd06),LL(0x9832dcfd,0x7d97f794),LL(0x0cc645ca,0xdafa9a44),LL(0xcfee0817,0x1da27ddf), LL(0x01b8dd49,0x0c1e6319),LL(0xd91aeace,0x8267e508),LL(0x87f43f20,0x86a2cedc),LL(0x07db2f24,0x7dd0e670), + LL(0x9db25177,0x8ea1e973),LL(0xab8802df,0x659cccb8),LL(0x004940ab,0x2bd39c65),LL(0xd9419db5,0x57676876), LL(0x6d6f237c,0xd52058a3),LL(0xfb4a9a7b,0xd9812dcd),LL(0x53bec56e,0x879890d1),LL(0x7ac5d9d9,0x17b7f151), + LL(0x1ec6db6c,0x2db3f5df),LL(0xafdf29b0,0xe9a3b18f),LL(0xe63a9ae9,0xda633d62),LL(0x38d13c8c,0x0922b16d), LL(0x7462c8e6,0xaeb7e270),LL(0xa01b6984,0xa98c96d8),LL(0x297c242f,0x5586e0d3),LL(0xff587596,0xbeddd1ab), + LL(0xc02ea084,0x79ac33ce),LL(0x8e02ae2f,0xe7d06753),LL(0x94d526b8,0x05fffd7d),LL(0x5ebc46d0,0x4590d655), LL(0x855f85e6,0xfb79c066),LL(0x7400ed08,0xbb3f0a6d),LL(0x67fb3683,0x46f4c3cd),LL(0xd19804cf,0x62fc1931), + LL(0xd1b6f356,0x0480e772),LL(0x56320242,0xa5810f25),LL(0x64073c03,0x6cf6c9c3),LL(0x46a6bfbc,0x7dfe137b), LL(0xba59baf8,0xa5633fa0),LL(0x5fd4929a,0xb703e5db),LL(0xd7515518,0x09eef835),LL(0xa0e3b067,0x2e596aa8), + LL(0x8649bb99,0x793831fc),LL(0x5ba4c1b6,0x91cb0057),LL(0x270ec9e8,0x44e93dbd),LL(0xd139d219,0xbf2ed01a), LL(0xc9d68198,0x39697e05),LL(0xde2b6894,0xf04439cf),LL(0x1e6b8e6d,0x65b7a04a),LL(0xce35ae6d,0xce3e9425), + LL(0x9f102fb3,0x041e0aff),LL(0x106ae748,0x91b3a87c),LL(0xc426fa5d,0xfd969804),LL(0x28f95b76,0xe624f1cd), LL(0x34f2ea56,0x6fe28cce),LL(0xd230f37c,0xdea55947),LL(0xf92f2742,0xd5e336f2),LL(0x1899c751,0x86852e3c), + LL(0xa5d1bd04,0x5ef2a63b),LL(0xb6ca2b79,0x5f4721a2),LL(0x9f484f78,0xbdb27b7c),LL(0xb085b4ed,0x2b07bf5b), LL(0x501b62ab,0x96b8ae73),LL(0x3ba64e23,0x0b1e003a),LL(0x93024347,0x43f9ec00),LL(0xae180a03,0x3c8c0c7e), + LL(0x8c0b21d4,0x58c72237),LL(0x2b15a1fa,0x9d51a996),LL(0xec755eda,0xf5201743),LL(0x933800fb,0x0c845fa3), LL(0x0e82418e,0xb6b66cdb),LL(0x3ae3eeb7,0x875258e5),LL(0x1a8f2b3e,0xf2c30b1e),LL(0x250f3328,0xa10b3843), + LL(0xc47c53f8,0x9f449967),LL(0x8775e16e,0x5dfe8c76),LL(0x336f2194,0xb02813a1),LL(0x5636498b,0x90ad3ad5), LL(0xc7c647e0,0x095acf96),LL(0x1f57c069,0xc90ef12b),LL(0x1fb85cc1,0x52f51878),LL(0x25a125ad,0x582cfd67), + LL(0x0d43ffad,0x53b4bfc7),LL(0x04dcf047,0x143b0b48),LL(0xd4500bf4,0x65d16216),LL(0x9ab1e4cd,0x960c7910), LL(0xe1d08c70,0x38b7ef7e),LL(0x9806e01e,0x64ae69e1),LL(0x6796b923,0x07468184),LL(0x70af1e64,0x6480887a), + LL(0x02384b34,0x4eb2d6fb),LL(0x05be47f3,0xb29337a8),LL(0x6b744f9d,0xfec96fc0),LL(0xc8c9afc3,0xc3de2fb0), LL(0xcc6dd0a5,0xe8ccc3eb),LL(0x71d7de7a,0x0329a9b9),LL(0xe357c4f9,0x459fbc8c),LL(0x025fdc97,0x80287f50), + LL(0xa089583d,0xedf1b0aa),LL(0xfb08add3,0xb1ad1a57),LL(0xe1ae76c1,0xd6826d03),LL(0x541462c8,0x3070cd2e), LL(0x83e6f4da,0x7b03c859),LL(0x24bdb487,0x5b39a809),LL(0x453bebb7,0x70017570),LL(0xb8ebbfc6,0xfe4e6206), + LL(0x106defe3,0xbb8a1899),LL(0x8683287a,0x6f23dc7a),LL(0x65d96aed,0x2cf01995),LL(0xdda4ea18,0x4e4cf7e9), LL(0xd2d0316b,0x72ad201f),LL(0x61de6cd4,0xd6451150),LL(0xc84856be,0x12432dbf),LL(0xd2a8378a,0xdd4dca98), + LL(0xbf881f9e,0xe70af958),LL(0xc4e58ec4,0xd4cd35ad),LL(0x5a531924,0x3889d3d9),LL(0xb4ce15ec,0xac657424), LL(0xf41e1344,0xdbe384ca),LL(0x5ab8bb08,0x9a1aed23),LL(0x8561df1d,0x375a041f),LL(0xb7685c1c,0x19f7a238), + LL(0xa4ba6317,0x8ba59933),LL(0x271f4aa0,0x0c44b6df),LL(0xbd64e922,0x51f4e88f),LL(0x9095769f,0x7279df94), LL(0xeaf8c8d3,0x098c17b6),LL(0x1aa841d1,0xe602ff2c),LL(0x8b63ce81,0xbe4e4926),LL(0xfcc79573,0x85de277a), + LL(0x5b8304db,0x38253d40),LL(0xe422af76,0x58c50c3b),LL(0xbf95c27a,0x7f7ec0d1),LL(0x6041df33,0xcb7c3a8c), LL(0x35364c89,0xc55595c0),LL(0x2a6eb1e6,0xd1a72aa7),LL(0xdeb98a3d,0x1fa941de),LL(0xeff46690,0x1e9607ab), + LL(0xad46a05a,0x6633e398),LL(0xb585e241,0xb99e5784),LL(0xea558424,0xd63106a4),LL(0x5df0e501,0xf0a5f939), LL(0x59dacce3,0xba17aaef),LL(0xe907c457,0x03dc5a07),LL(0xa9800bc3,0xa59f6d63),LL(0x364e1ef7,0x294a3827), + LL(0xdd191356,0x741bbab9),LL(0xc43954a4,0xe8fe9161),LL(0x65341d90,0x6a711fa9),LL(0xadef2d82,0x09bd0faa), LL(0x21ffc303,0x2112f27e),LL(0x395b69e2,0xcd2214dd),LL(0x8670b06f,0xe4b503c9),LL(0xc4e13ef4,0x219a678a), + LL(0x4a993816,0xc4020eff),LL(0x1bac14d5,0x00a9f5de),LL(0xeba7c3a4,0xd00fce1f),LL(0x14b537ab,0x2c6d4993), LL(0x6b898739,0xe9b2b540),LL(0x29dbf826,0xae53e6e3),LL(0xc8438b2c,0x634606c7),LL(0xfabfd429,0x268a9ee4), + LL(0x173b5583,0xb0486aae),LL(0xbf222673,0xf88a2f80),LL(0x0b3178c8,0x49c56f76),LL(0xd77d1406,0xeab47059), LL(0x993b1a7a,0x95035846),LL(0xa9b83efa,0xd6446e94),LL(0xc4424fa8,0x1d1a71ce),LL(0x3d08b8d2,0x8d814c4d), + LL(0x7b9374ac,0xbc3ed8d2),LL(0x77a3c020,0x8dd2d56d),LL(0x97efca8d,0x93ada735),LL(0x37974cd3,0x072bb2d0), LL(0x7bd74e40,0xa7c86e7e),LL(0x5b52e0ed,0x7bff5613),LL(0x053af1f1,0xc8d0bb30),LL(0x840bcb7d,0xc5bdb8f9), + LL(0x41690d1c,0xabdf5f73),LL(0xf0edac8c,0x0e857a78),LL(0x8238cfb0,0x59f40fcf),LL(0x511d41d2,0xdcb54f67), LL(0x0e645117,0x3f036ac8),LL(0x7af5fdcc,0xdc4e833e),LL(0x3d7bab2c,0x67d859b2),LL(0x5f8b32bd,0x92489b23), +}, +/* digit=22 base_pwr=2^154 */ +{ + LL(0xb9e2f9f8,0xe412aaf7),LL(0x0ff419ac,0x0484c1aa),LL(0x417bcb90,0x9d944989),LL(0xfe7318ca,0x2b73dbe3), LL(0x52dd7b0a,0xb91b71e5),LL(0x3954afeb,0xd61f8eea),LL(0xa07e3958,0xaaeab13c),LL(0x02a1ff49,0xde442032), + LL(0x0b054a0f,0x8292d96d),LL(0x74b9077a,0xa978af88),LL(0xfff1d49f,0x70bd185b),LL(0x0279eab1,0xbe6d0844), LL(0xb8ed07e9,0xa8fffe45),LL(0xcb920e55,0x714824a1),LL(0xaf1bb143,0xcd5c628a),LL(0x7637dbb7,0xd151afcd), + LL(0x62d7ee7c,0x83fb0f37),LL(0x9a3bcb7e,0x58c2282f),LL(0xeac2ca5a,0x79f77476),LL(0x579a262b,0x7e80c351), LL(0xedb4f0fc,0x19e67272),LL(0x1fbbe9fe,0xe142bb31),LL(0x95ea6cc1,0x5c7d7cce),LL(0xabfdcf7f,0x6465a380), + LL(0x5a26a1d4,0xa433bd2e),LL(0xd1c2d78c,0x1148bb1d),LL(0x64102515,0x4aae419e),LL(0x66489384,0xd03b9939), LL(0xd61a9919,0xe21d58b1),LL(0x4a0ef3d4,0x17618c36),LL(0x6fe8c0dd,0x2519020d),LL(0x00b87a75,0x48d837d6), + LL(0x426c1aa6,0xe6e067ab),LL(0xb11d1280,0x431579d2),LL(0x2ead6552,0xb926943f),LL(0x057fed1f,0x8fd692bf), LL(0xe9a98fae,0xed11c0ed),LL(0x9bcb2abd,0xe2bc967a),LL(0x68729b8e,0x1b388d66),LL(0x6f74563d,0x2144d67c), + LL(0x03fcd3bf,0xbe519757),LL(0xc8c7b62f,0x3f9dbd8d),LL(0xfc476e0e,0xce91fce6),LL(0x2715393a,0x2f140c73), LL(0xf11da35b,0x8a149a94),LL(0x5367030d,0xf6a2be5e),LL(0x0269def3,0xb68c0d82),LL(0x8eecb775,0x32d58819), + LL(0x32845ab0,0xccea6f53),LL(0x2541c834,0x792bc041),LL(0xb1336aa7,0xd726425f),LL(0x3ddd6256,0x85b1d21e), LL(0xd9b1ba0b,0xd575bfa8),LL(0xb778b77a,0xd23084e2),LL(0x44bb1010,0xd44e7399),LL(0xa91623fc,0x3d665388), + LL(0x3f11fc00,0x5cfd3a69),LL(0x8bc8eade,0x1f2b5d01),LL(0xa6b9f7ae,0x5160359b),LL(0xfa696463,0x1e2601dc), LL(0x915f6084,0x7f5ac6d2),LL(0x679176d5,0x6e387789),LL(0xae26abee,0x7fb99f4b),LL(0xaa409d22,0x4798a2fc), + LL(0x5965615c,0x582164f7),LL(0x0472cbeb,0x2c9dfb60),LL(0x2266724f,0x36eacc3f),LL(0x5fcb8868,0x253eb08c), LL(0x760c15b3,0x749a0577),LL(0x5686b036,0x71e4ce1e),LL(0xb710196a,0x47893a8f),LL(0xdf51c4e8,0xe27dfbac), + LL(0xffb3df08,0xc9536d6b),LL(0x6dde9e09,0xc95169ce),LL(0xcc085766,0xcb050de7),LL(0x0df088dc,0x92fce77e), LL(0x88781592,0x10c124ca),LL(0xc81030f3,0x6429d30b),LL(0x09e20c50,0x2e37721d),LL(0xf3e3d604,0x43e7f9ca), + LL(0x5b095e01,0xa277a87e),LL(0x83a51a95,0x968bc951),LL(0x53aff355,0x3b375d45),LL(0xe1ebac06,0xb79d7cce), LL(0x022995b4,0xd929e1a6),LL(0x28164ff7,0x228cf7f4),LL(0x5d3e4608,0x7bd12900),LL(0x2f97ebd8,0xc57ac873), + LL(0x86b383b5,0xc192342d),LL(0x706b01d5,0xe85f303f),LL(0x88cdcb89,0x19e19213),LL(0x2ce0de2a,0xe88f1943), LL(0xe453aecc,0xf6fcf8cf),LL(0x9a67b49f,0x0dcd10b8),LL(0xafece961,0xb93d5b4d),LL(0xc39d0b53,0xe232f34a), + LL(0x30735384,0x1b8f6cc3),LL(0xe4f26c08,0xc35c5a82),LL(0xba98f626,0x9e0c933b),LL(0x4c70aed7,0x49868100), LL(0xb7f26c66,0x711a3aad),LL(0x7dac506b,0x786ea28d),LL(0x43935657,0xd3a7ab1e),LL(0xd1b69e9e,0xda7f5c1f), + LL(0x0e6c8579,0xc08c85e5),LL(0x8d991759,0x29d04ad4),LL(0x3a8ccd69,0xbae8f163),LL(0x1790a49c,0xade66539), LL(0x45915cc1,0xf9f5bc8c),LL(0x4f2b18c3,0x63461cf0),LL(0xd236e848,0xceb75a9c),LL(0x847ce6c2,0xac653e3b), + LL(0xdb088764,0xb93b3032),LL(0xa78e5943,0x567fe1c3),LL(0xe359cb34,0xba7a7acf),LL(0xe2c3827e,0x38f4fbfd), LL(0xc90abad2,0x761c36d4),LL(0x75027c02,0xac1af4e7),LL(0xd4715572,0x95e6d01c),LL(0xd621145d,0x5b06cf39), + LL(0x64ca2efc,0x799acd7c),LL(0x4e0bcb6c,0x3397a15b),LL(0x0358a26c,0xb9b10ced),LL(0x4b8ddfaa,0x0a30dbbe), LL(0xe20f6fac,0xa70e9712),LL(0xd11451b0,0x87c7f732),LL(0xd5eece8f,0xf0c967b1),LL(0xab370e2d,0xbc62882a), + LL(0x59ddb7cb,0x134fb08e),LL(0x3ae8f816,0xe937c663),LL(0x802ed184,0x083f73a7),LL(0x8cd69f8d,0xd4badd85), LL(0x987f389e,0x2d8bfaf5),LL(0x4454b1f2,0x5338c056),LL(0x2f104468,0xdce38439),LL(0x83c5278b,0xffd94d27), + LL(0x5628ad08,0x8740af50),LL(0x8b1284e8,0x30a233db),LL(0x57acc8cd,0xb3982d73),LL(0x37c5ff03,0x211d53d3), LL(0xf6578d40,0xb6371f1b),LL(0xa80dec53,0x7f749bea),LL(0xa9816ec0,0xe6b3f730),LL(0xf5423ec6,0xd26832fd), + LL(0x63e27b64,0x80127368),LL(0xd2d21879,0x17b7a4b2),LL(0x43cf40d4,0x7dcced37),LL(0x97cf7c4c,0x999bbb80), LL(0x6bafa0b0,0x191c84e5),LL(0x917f6b17,0x1d08c049),LL(0xf4715c99,0x02e5fe53),LL(0x0658f1de,0xa92c6085), + LL(0x16a010bc,0xe9c0ba85),LL(0xea4f3e8e,0x2fd90fba),LL(0x4570a1e5,0x8af18371),LL(0x7cca9004,0xe869e8f7), LL(0x2dd83019,0xe2c8afb7),LL(0xfd99b386,0xb877995d),LL(0xf5adab87,0x1e3efc16),LL(0xaa3b191a,0x93105fe4), + LL(0xae504c31,0x21690dca),LL(0x698f629d,0x2d51ead4),LL(0x724c9cbf,0x2af3eef1),LL(0x81a0d4aa,0xa6181e60), LL(0xa94f6b05,0x580982c7),LL(0x48653ad7,0xe8bea903),LL(0xa608598d,0x0270614c),LL(0x3d0d5360,0xa7cae0f0), + LL(0x96067f64,0x81407687),LL(0x77a62d7d,0xab2c2706),LL(0xae19786b,0xbe9c1edf),LL(0x887814eb,0xa313f2b2), LL(0x08fd3c04,0xe2bc4c1f),LL(0xe5a9d032,0x25387129),LL(0x8fbc5030,0x7b3ced22),LL(0xadbf1bdc,0xc22bea3b), + LL(0x7b1308da,0x4f6b6b6d),LL(0xd0e33069,0x0f2faaaf),LL(0x0d3677c4,0xb461990f),LL(0x0e6a876b,0x55c9df43), LL(0x316d252a,0x5ce9aaa4),LL(0x0e8e5097,0x7d98a813),LL(0x9aa3343e,0x047ecd13),LL(0x939277e1,0x15cc7072), + LL(0x0a020be7,0x305165d1),LL(0xf66eaf8b,0x48560411),LL(0xffd2380e,0x5ff898dd),LL(0x784b4b11,0x7da35f08), LL(0x38fd05c7,0x50f53e2c),LL(0x47ada3a5,0x64b3ee82),LL(0x678995de,0x672ae316),LL(0xdfe96605,0x74707460), + LL(0x441e7150,0xb346dc71),LL(0x55fd483c,0xd9505e7a),LL(0x94302331,0xca96e59f),LL(0x801930cf,0xcfde701c), LL(0x73c31e5d,0x02fc9936),LL(0x8cda0b51,0x4ef53a55),LL(0xa269a1f3,0xa934e268),LL(0x7cca8542,0x7ba4e5e0), + LL(0xa2ae339c,0x4c6408f9),LL(0x5a70ba33,0xf9ea4cb2),LL(0x5cac2af4,0x3eaa9364),LL(0x95eaea09,0x62686d46), LL(0x3e771722,0x5196e88f),LL(0x7108b198,0x749518e8),LL(0x29b25254,0x394107c4),LL(0x3a315aad,0xf9945ac1), + LL(0xaab9dbe5,0xce15c84d),LL(0x3940eb15,0xebb54d52),LL(0xa2fdd11d,0x69b649c7),LL(0x3f6ade80,0x4e2d1782), LL(0x2327f7d8,0x0f53ac9c),LL(0xc79eb564,0xf6158d6e),LL(0x4536f5c1,0x2903bfc0),LL(0xfb9e9e07,0x0a25518b), + LL(0x62a0b0ed,0x70cbce8b),LL(0x0abbc9be,0x92f5dc33),LL(0xf369c2d6,0xbb92b7d3),LL(0x79ef83e1,0x70dd90c8), LL(0x7937ab45,0xe0b33153),LL(0xc054af6d,0x3a8d1f74),LL(0xb05ebfc4,0x35cf7380),LL(0x58c2cd0c,0xefb8dac2), + LL(0x7d665d26,0xe7316f99),LL(0x800fba6f,0x59a7ead9),LL(0x08a2cb88,0xfa4d2a2a),LL(0xb441995d,0x2e7d3bab), LL(0x93046f2b,0x390988c9),LL(0x08869cf5,0xfd95b86e),LL(0x9a76537b,0x0185b6be),LL(0xb6cd3d59,0xa89563bd), + LL(0xecb1ad25,0xe79a4f63),LL(0x6948504d,0x1857cec7),LL(0xa497922f,0x03b7b3ad),LL(0x38930f36,0x9df2f2e4), LL(0x4bb5927c,0x355e4a7a),LL(0x636ec349,0x5ad3fd47),LL(0xc41b19ca,0x5400730d),LL(0x555afa93,0xbfeabac1), + LL(0x6cca58b7,0xb6232083),LL(0x76d0c53e,0x55faae6b),LL(0x40a8eb5a,0x64ef60e2),LL(0xe8f22c94,0xc68bc678), LL(0x10a0416e,0x5156dc1c),LL(0x5c2037e4,0xac779644),LL(0xc7162aaa,0xd2e30925),LL(0x2cf21e2f,0x7bb5275f), + LL(0x0c11e65a,0x7722cb40),LL(0x68ff2be5,0xc94a7f52),LL(0x8d9f9352,0x420085cc),LL(0xca4b2544,0x4addb986), LL(0x06264a47,0x3c6ceac0),LL(0xe2b48ccc,0xebc01a03),LL(0xea94fef2,0xc430e7ab),LL(0xbd94aa8a,0x973bb6f0), + LL(0x3225b585,0xd60e5feb),LL(0x01b56ad1,0x6cbab39c),LL(0x37d6d1b4,0xcb55a9cc),LL(0xfbce1d89,0xd7288c1e), LL(0x162d4b46,0xcb516843),LL(0x15edb910,0xf0aca3a6),LL(0x08a6685a,0xdb998b55),LL(0x07811873,0x16b442e6), + LL(0xa1a7e0c2,0xa9badd09),LL(0x9f813289,0x0a9a339b),LL(0xd4cda45b,0xabf1793f),LL(0xc7378a84,0xa9830a12), LL(0xd28165b1,0x1ae11c32),LL(0xf71bca14,0xbfd49ace),LL(0xfc035476,0x9a3990df),LL(0x6c32b72a,0x0fd2b153), + LL(0x3541b5ae,0xceece835),LL(0x8256c750,0x2f7429f5),LL(0x88104f8c,0x456c3478),LL(0x8b23da06,0x8a435588), LL(0xd817ce6a,0x6b6c14f2),LL(0xf35ab86a,0x83bf0acb),LL(0x364b83fd,0xdadb89ba),LL(0x5cfecaf3,0x2c8fcf90), + LL(0x20d12c92,0xa90f77ca),LL(0x69d1739c,0x2e278e0e),LL(0x5c1f9e82,0x29d24b44),LL(0x647c59b1,0xbf4fb4cb), LL(0x90ffd733,0x9c8ea39d),LL(0xf14db3fc,0xe37a1352),LL(0x8f3e1dca,0x3c9164a2),LL(0xaec86440,0x515c16f2), + LL(0x5c483906,0x736fee4c),LL(0xa3f651c7,0x2325cabb),LL(0x35b94e45,0x582324df),LL(0x45598c64,0xeacedb3a), LL(0xde9ea8cd,0x674e1740),LL(0x89d2b975,0x30f2f423),LL(0x9c8abe45,0x330bd76d),LL(0x5371c0c4,0xb97e89f6), + LL(0xb7569543,0xb1769248),LL(0xd85f4d72,0xd29cc9d2),LL(0x10a5b6dd,0x89e1fd0c),LL(0xa693a796,0x501be0ae), LL(0xe490e600,0xc70965b6),LL(0x1bb6c5cd,0xf518f8af),LL(0x76f6daa2,0xf51d40bb),LL(0x5ec7849c,0x83a83b67), + LL(0x6d8aa314,0x0fe0d975),LL(0xea664a8c,0x9bf9aed5),LL(0x96fad9aa,0xef8bb989),LL(0x04a0e441,0xd07dce35), LL(0xb3c5eb81,0x53bd2a16),LL(0xaf178b66,0x49e29fe2),LL(0x24dced32,0x62cf7a62),LL(0x0f541e36,0xcc111fba), + LL(0xda9dd111,0xc93cd7c1),LL(0x28c9c1b4,0x56b625ab),LL(0x3769f3a2,0xeff436ae),LL(0xcbd31a17,0xa0d8d46b), LL(0xc80dc873,0x241693fa),LL(0x3cd579ab,0x56083f64),LL(0x33fbd431,0x12ee753b),LL(0xd66c283a,0x1bde60ad), + LL(0x0243cd83,0x0db508dd),LL(0x1349307c,0x3b12c134),LL(0x61d86bda,0x8296aa6d),LL(0x630adc96,0x1d5c8a4f), LL(0xa30a8ae6,0x9d01dc28),LL(0x1dab8168,0xc555a743),LL(0x7abe577a,0x61fe0d14),LL(0xc8c93bb7,0xe26aa4d8), + LL(0xda2bab5b,0xfb4b03bf),LL(0x79b4e6c0,0xfbd49089),LL(0x86806aa4,0xda1a0108),LL(0xdc078112,0x281f76ae), LL(0xe0fbd693,0x9f662594),LL(0x49ec4ee0,0x1da897b0),LL(0xfc7d1578,0x20d52a97),LL(0x6b1f4ab4,0xdbf8d157), + LL(0x3b97d1e3,0xfc0a5936),LL(0x1aa091b6,0x00f0f283),LL(0x13aadeb0,0x505e183e),LL(0xa55b3f8a,0xe28041ad), LL(0x086c2d23,0x2e0f76da),LL(0xf2c5eceb,0x815b147d),LL(0x673ba5f2,0x02066c02),LL(0xce043d4d,0xb85d6a8a), + LL(0x113890f6,0xd5f023a3),LL(0xa9d2491b,0xaa4f9058),LL(0x16d175a3,0x6d82393e),LL(0x671e2aed,0x1d1e00b2), LL(0x40018bae,0xd47c4f28),LL(0x7b30838f,0xd08eac83),LL(0x5dfe910d,0xa0fde631),LL(0x5c66d5c6,0xfc16adf7), + LL(0x18d8c6b1,0x0ed2a8a2),LL(0x632b5b07,0x67ee6037),LL(0x21a89b8d,0x7eed42e5),LL(0x33e6da02,0xd99942cf), LL(0x39971405,0x759ec79e),LL(0x174dca4c,0x669a92c7),LL(0x9d1e7c55,0x85935ed7),LL(0xa82055c0,0x5f3f9e68), + LL(0x56aa5af3,0xab0507c8),LL(0x1bd2726f,0x354cac5d),LL(0xb864816f,0x46e85e16),LL(0xd1840add,0xef2548f6), LL(0xc3842f43,0xe494ea07),LL(0xedf6c13a,0xa6169c4a),LL(0xa460e30b,0x65d9cca3),LL(0x31e7dfc3,0xa6848e4f), + LL(0x5c8109dd,0x4309f315),LL(0xc5799833,0x7a4ec14e),LL(0xa8132b78,0xcb768a63),LL(0xb416c77c,0x229106d1), LL(0xded02f41,0x1ca71df6),LL(0xc1a1fc66,0xb6365d3e),LL(0x1431d1fa,0xf7c432a1),LL(0xa5654387,0x30364500), + LL(0xd5b13b2e,0xc9ed0cf8),LL(0xd18d5a28,0xdbd541bb),LL(0x754de9d2,0x6b78c887),LL(0x54651568,0x7d32fedb), LL(0x0d37c339,0x7f319680),LL(0x37d70b76,0x22304d1f),LL(0x6fb5e555,0x01b2709e),LL(0xfd5d1708,0x978b0d3e), + LL(0x96bc118d,0x83206b9d),LL(0xec7bfc1c,0xb1a4d7bf),LL(0xb6b41502,0x753f98a6),LL(0x4c5187ce,0x41139110), LL(0x587a8213,0x56e9e218),LL(0xad9aefd0,0x3b39955b),LL(0xb9947ceb,0x7428b03f),LL(0xbe8bda29,0xbbe82668), + LL(0x5c4b4c63,0x5142e8ba),LL(0xe92ee291,0x90c3e2e3),LL(0x8f6a076d,0x6947a55a),LL(0x61964435,0x9acdeec1), LL(0x181dac35,0x56bc8e4c),LL(0x7a824372,0x4f4f2c0a),LL(0xc1033f6b,0xd1958b99),LL(0xc83ecf98,0xeeaa6604), + LL(0xaca52cb3,0xe43c0b44),LL(0x75443f14,0x12446426),LL(0xddcc00b4,0x0d14e885),LL(0x6cfe5734,0xb0f5f11d), LL(0x1013afcb,0x0e160164),LL(0xed9f4535,0x4f570ca9),LL(0x73a307ad,0xe5162a12),LL(0x3321ae54,0x6a431695), + LL(0x5ae301b4,0xa6c7b0c5),LL(0xbd2d3f1d,0x6f5d42b1),LL(0x15c0c94b,0x4eb12c09),LL(0x28618c41,0xf1c40386), LL(0xc0f55c25,0x30302333),LL(0xbd1c19f0,0xa5e41426),LL(0xcfcc66f8,0xd5d4d4d7),LL(0x449253c5,0xcfdf3039), + LL(0xb30ec0ff,0x17b0eb72),LL(0x5e6424f9,0xbce593e2),LL(0x2a73184e,0xa5d82937),LL(0xebe58773,0x23d2857a), LL(0x067e1eac,0xe3f0f676),LL(0x50509d7f,0x073ded2d),LL(0xca405a7e,0xc22af8f0),LL(0x6df6a46c,0x7a4ef592), + LL(0x97067006,0xf9cb0178),LL(0x489d2a39,0x9ae132af),LL(0x6a2da1c1,0xc7c46b35),LL(0xd95850c9,0x0993353b), LL(0xa25d52ef,0x6c313a57),LL(0x93c852c3,0xa6bdb2b2),LL(0x7e9e296d,0x27ed916b),LL(0xc7aeb09b,0x10b58337), + LL(0xecebe36e,0x78800c35),LL(0x2234ce8a,0xd93e2423),LL(0xfa95019f,0xe4cf5cee),LL(0x71e13748,0x21396d37), LL(0x0c32fdad,0xeb028350),LL(0x61f1652b,0x31645697),LL(0xf6677491,0x9e1c6e0b),LL(0x74176c12,0x4d18f2e5), + LL(0x3832d713,0x78d559bf),LL(0xb6e00e15,0x04f0b57b),LL(0xe80add3a,0xd6c9cb16),LL(0x5c7b1d70,0xeabfabc5), LL(0x98a62cc3,0x40570866),LL(0x4abb2b1a,0x39ef8ff1),LL(0x0c19959c,0xadb40548),LL(0x388b1f7c,0xd61632d7), + LL(0xd73b7d50,0xd1f9b736),LL(0x560bf0aa,0x652ed78e),LL(0x50e3fc4f,0x58e71e33),LL(0x55df1ad1,0xbfaf5f44), LL(0x9106744f,0xefe8893b),LL(0x356d1fe9,0xabfbd51e),LL(0x9eb1cbaf,0xab03570b),LL(0x3919012c,0x92cfe2e4), + LL(0xb6f7c64d,0x7671e5fb),LL(0x6e0a44b7,0xf040c039),LL(0x62b36088,0xf430f593),LL(0x94c7c0ac,0xa85b4bc9), LL(0x16b54fff,0x07d5c40c),LL(0xc53a3788,0x47aa73ee),LL(0x7000d61e,0xa63c5b36),LL(0x91b9f09f,0x04e8f53d), + LL(0x87dc6a3d,0x7e48021d),LL(0x28ae0f74,0xa2b5516b),LL(0x705132e2,0x84412003),LL(0xe243d1fa,0xc55f69cf), LL(0x6a8f80bd,0x758c0f71),LL(0xd09b719d,0x69ecf887),LL(0xa9b45194,0x51b100f0),LL(0x90ae0769,0x1fb9ef66), + LL(0x30fcdfd2,0xfee82fab),LL(0x36a6990b,0xf36185be),LL(0x3d33027b,0x88f343f6),LL(0x38ae16c6,0xb775dcbb), LL(0x85a82e45,0xa107b9f0),LL(0xde6b9806,0xaff8b0ae),LL(0x0392fad0,0x3cd3980f),LL(0xf3cf7650,0xdd829fc6), + LL(0x0dc8d031,0x177190cc),LL(0x7fc491eb,0x3e21cd25),LL(0x0d929039,0xea0cc90e),LL(0x1dfc37b3,0x5f7e6292), LL(0xe23bdd04,0x66dd6dde),LL(0x64fa490a,0x70e7a317),LL(0x10a03dd8,0x59c90f81),LL(0x96d58314,0x425ee6ce), + LL(0x5f896ed1,0x868001eb),LL(0x91dad4fd,0xc4c003f5),LL(0xd9ef80b4,0xfb4782b2),LL(0x323e4fc5,0xb9edb975), LL(0x53ef4ccc,0xa2ec9b6c),LL(0xa77922b6,0x4af8b2ca),LL(0x6697874b,0x73850e89),LL(0x3568523f,0x76e0fd72), + LL(0xe9c400a6,0x64799f46),LL(0xa9c245de,0x6c5176e7),LL(0x93503700,0xbd97c80c),LL(0xffbe539f,0xa92d9ee5), LL(0x8376bb3b,0x76003d14),LL(0xac564679,0x2e75cc77),LL(0x3a333970,0x126af6c7),LL(0x6b6604bd,0xdbfd0133), + LL(0x24424a48,0x11cf4c2e),LL(0x37d4471c,0x843c73ee),LL(0x617a488b,0xb3047fc5),LL(0xe3cf861c,0xf2a91709), LL(0x1c3a60f7,0x84444421),LL(0x26679148,0x74787a36),LL(0x53d9404b,0x115fbd06),LL(0x6244cef0,0x70fd3365), +}, +/* digit=23 base_pwr=2^161 */ +{ + LL(0x2b574b7f,0x76695c9b),LL(0xc369b6be,0xcca80405),LL(0xe3108ded,0x1f4bae99),LL(0xea133fce,0x9e715ce2), LL(0x54c2ee1c,0x60d52055),LL(0x1680742e,0x56bab301),LL(0x3fe438b9,0xa409b5f6),LL(0x8036f7ce,0xe3a8e4d0), + LL(0x247fdfdf,0xe1d7ec0f),LL(0x4a23d1dc,0xfb9d90e7),LL(0x190fdc41,0x7012eb2c),LL(0xddced48c,0x5c2bbff6), LL(0x68cd7feb,0x8a93426a),LL(0x6b4854e1,0xb5963962),LL(0xe772bbd8,0x8ac72b8e),LL(0xa6b3040a,0xc10d24d2), + LL(0x94d5f347,0x8fdfef16),LL(0x2b04af0a,0xf3189490),LL(0x6d2ca633,0x30e3da7a),LL(0x4803814a,0x8d002aea), LL(0x95a0bfe9,0xc15e311f),LL(0x4b4cc50c,0x2891ec7e),LL(0x8834df25,0x0936fed8),LL(0x78e00289,0x7e5d7dbf), + LL(0xfbfcf1b5,0xb9a92d78),LL(0xe8427d74,0x17ce4fab),LL(0xac66e74e,0xbae98ffd),LL(0x145bb5e5,0x6d548304), LL(0x0992abe1,0xbf3dc603),LL(0xbefdc5c5,0x318cfbda),LL(0x59f8efb8,0xbb5fa37d),LL(0x4ef5bef8,0x347874a0), + LL(0xbf68688b,0xdf552b01),LL(0x8f96a57a,0x2fc542cb),LL(0x4edb340e,0x5a731b61),LL(0x181cf578,0x5143d103), LL(0x2cc936b6,0x749ab511),LL(0x0dd355c2,0xbc94c053),LL(0xa3900fa2,0xa825eff5),LL(0xc1dc2b31,0x60a909a3), + LL(0xaf5bcab5,0x59b33c78),LL(0x496fbcdf,0x0053d789),LL(0xd7883bc1,0x5a5afe02),LL(0xfa66951d,0xec9afe78), LL(0x728e56a6,0x38f28b83),LL(0x78cafb9d,0x21d0b6ac),LL(0x7042e327,0xd43996bc),LL(0x7c31c145,0x60686637), + LL(0x3d919304,0xe1f8d2e6),LL(0x456be82a,0x09cf437c),LL(0xf0c21973,0x6a01dae8),LL(0x246d9ef8,0x8bffcda8), LL(0x5d853975,0x7e03a0d4),LL(0x32533ba3,0xc3800ca8),LL(0xf02ce43c,0xd77152cc),LL(0x6392089a,0xb8bc17a6), + LL(0x4b4558fb,0x6f5fcb61),LL(0x1f2545aa,0x9602597b),LL(0xabe5e469,0xfd89ab3f),LL(0xfb2e16bc,0xf1daeea2), LL(0x3a12940f,0xe699acd7),LL(0x4d7c7311,0x24980f6c),LL(0x336c8ec6,0x4a5cf975),LL(0x8c27d3dc,0x8e180e32), + LL(0xd36cb503,0xafb66269),LL(0x754fdd67,0xe98b07d2),LL(0x5a1fe9bf,0x1e0b425b),LL(0x24fc4a85,0xb4ac13e9), LL(0xc05a9c3f,0xef693781),LL(0x5c0124dc,0x266c1216),LL(0x64ee22e2,0x7f3184c4),LL(0xcdb5f1a9,0x3f985fb3), + LL(0xfc01efaa,0xb258cd5f),LL(0x0775588e,0x861688b1),LL(0xfa46eae0,0x72184b18),LL(0x5003404a,0xd17c9dea), LL(0x92e7bf9e,0xa8791966),LL(0x7891ac50,0x049c63cb),LL(0x5d46b33d,0x2ed32928),LL(0x0623595a,0x49d1bfbf), + LL(0x36c8e3e9,0x9f871470),LL(0xb20d610d,0xdec7eb98),LL(0x7b151f4e,0x15b9326f),LL(0x04005d02,0xa624c23e), LL(0xd9cacded,0x89fc2a8e),LL(0x9a2c3a00,0x9eb8defa),LL(0xe8d7eab7,0x7c5dc2d6),LL(0xeb0a77cf,0x48fa5403), + LL(0xbf033733,0xcc4c31d0),LL(0xef211c17,0xf37d0072),LL(0xae35b246,0x8967fe49),LL(0x5cb1aa9b,0x8c4cbd66), LL(0x04840da3,0xab0097db),LL(0x5828733e,0x3946faec),LL(0x87d64045,0x96c6531e),LL(0x83bc0d0e,0x893d3780), + LL(0x53bec0dc,0xf833e355),LL(0x2803a655,0xc9ff7280),LL(0x42b99b53,0x300ff7aa),LL(0x6a7c3f2c,0x3b48a8db), LL(0xf617f8aa,0xf78c21d9),LL(0xcbe4d565,0x23684cb7),LL(0x7514e9a0,0xf64ae9c8),LL(0x8429d8ba,0x4ff5483c), + LL(0x5cb18391,0xdedab351),LL(0x769ae948,0xd3126ffc),LL(0xd3546ad9,0x6c2f9ba8),LL(0x69aabfb7,0x4567e48a), LL(0xaa284747,0x6fbe29b0),LL(0x98af4f2f,0x3185f0db),LL(0x5b4c14e3,0xf2a958a2),LL(0x27d04855,0x106150c5), + LL(0x68a19ca9,0x60a3b4fb),LL(0xfac47c70,0x65c5719a),LL(0x973e4cfd,0xe228e088),LL(0xcb63c89f,0x122a2429), LL(0xbaea08f7,0x39fda97e),LL(0x621c12cb,0xe7da5324),LL(0xff9b3c84,0x569c8a51),LL(0x4c3b8d54,0x5ab8bb6d), + LL(0x00e25a95,0x4f02ece4),LL(0x7ac1732e,0xef947402),LL(0x51149260,0xecdb65ac),LL(0xa9180d51,0x6043aa29), LL(0x852deca0,0x07fc92bd),LL(0x15237c8d,0xf3338297),LL(0xe84b3f38,0xecfb0e76),LL(0x6b89af17,0x21f2f5c5), + LL(0x9659963f,0xf7aec268),LL(0xa0cb213c,0x67fb5260),LL(0x66d931b7,0x5daa0fef),LL(0x34d309ff,0x95457a7e), LL(0xc21285b6,0xe7cf1a56),LL(0x244e11b4,0xcbff9b08),LL(0xc0ecce3d,0xd79ee62d),LL(0x8267c254,0xe3f20739), + LL(0x037ef2d3,0xee06dd39),LL(0xd522f762,0x790d1b0f),LL(0xf30c47d0,0xf0659106),LL(0xb5fdc6b5,0xcd83214b), LL(0x6593b717,0xc8621660),LL(0xfe3fa381,0xb10a6d99),LL(0xab254244,0xa5c3224c),LL(0x5854b18e,0xd15287e6), + LL(0x225806ae,0x6bf9594c),LL(0x57e554f2,0x75a97e21),LL(0x82b00b16,0x0ea199f3),LL(0x5389c90f,0xde81a726), LL(0x86922afe,0x8503609e),LL(0x254b75c3,0x6778ad88),LL(0xf3e660ba,0x6bc2ac1b),LL(0x209c04a4,0x7efc1550), + LL(0x2528ec51,0x6e90b6a5),LL(0x0548389e,0x9196a7c9),LL(0x7b5b5dde,0xf7e285c1),LL(0x223d4837,0x6335a624), LL(0x412d19c4,0x8acef5af),LL(0x9783256b,0xb22808a5),LL(0xf53e4b62,0x6ea3daaa),LL(0xfa7bada4,0x7ca4c51b), + LL(0xe4d3115e,0x3e40461e),LL(0x3646fc40,0x24889b50),LL(0xfa26ccf7,0x39e0eb1e),LL(0xa82af350,0xfcad5d47), LL(0x4862b1fd,0x90037503),LL(0x1a79283c,0x88e937e8),LL(0x9a0127fb,0x16dd07c0),LL(0x39fca31a,0xac62a168), + LL(0xa294dac9,0x26542e2a),LL(0x2a5dcfe8,0xefab45af),LL(0xe642bbe8,0x6166857d),LL(0xff6290a8,0x3f3ad480), LL(0x5f50633f,0x435d4c2b),LL(0x84451c8b,0x36da60a7),LL(0x261612e4,0x00f5e2e4),LL(0x2d04786a,0xe4318273), + LL(0x2c175edb,0x192bcda5),LL(0x59a6f637,0x74681e0a),LL(0x2d244985,0x696df08b),LL(0xfcf577c6,0xde61a87c), LL(0xf2c9de81,0xcbd2ceab),LL(0xd36162e8,0x878f06ce),LL(0xb3d22955,0xc4f312e0),LL(0xe903efee,0x736ed43f), + LL(0xca9bf60f,0x2c687134),LL(0xbc7da3a5,0x2473ea8f),LL(0xb45fb57e,0xf54ef685),LL(0x3383cadb,0x594e8445), LL(0x4a7df4bb,0xe1edd3fb),LL(0xc17c2c92,0xa783d987),LL(0xcf8fcba8,0x0d498637),LL(0x3acd6e4c,0xdebd801d), + LL(0x34d3761e,0x2ade8a7c),LL(0xd825cd19,0xc591c889),LL(0x39b42dec,0x3ffd60ba),LL(0xfd9674dc,0x136d4902), LL(0xda4842c4,0x373a70f8),LL(0x3f078bfd,0x3208c485),LL(0xef608639,0x3587f871),LL(0xf04e46ed,0xf990ab0f), + LL(0xa83a8450,0x39d542ab),LL(0xdacb7c65,0x634b9198),LL(0x82486a05,0x680cef78),LL(0x16eaf88b,0xab1d4d77), LL(0x699c7aa5,0x5e605279),LL(0x3c40a07f,0x7e37906f),LL(0xfb6926e3,0x4ae84ad8),LL(0xe2ebc73b,0x236b5f07), + LL(0x9e0939a5,0xa94e50ab),LL(0x2d9e10e2,0xabeed810),LL(0x4e6423d3,0xea8190fb),LL(0x17acb62c,0xc739d209), LL(0x6fdbe8dc,0xae38106e),LL(0x63204138,0x1c6532d7),LL(0xbb7d0510,0x03af879d),LL(0x8cd2b1a4,0x1d76faf0), + LL(0xd77386cc,0x2fcdaf9b),LL(0xe32d2633,0x30f9f5a4),LL(0x382e7298,0xa4fc8189),LL(0x588af205,0x946923a1), LL(0x114f2beb,0x2c527a79),LL(0x077762eb,0xa2ca55d3),LL(0xcc85e41e,0xe4b2eb7c),LL(0x89346ada,0x4b5938d2), + LL(0x4c2084cf,0x8e94e741),LL(0xa839ecb4,0x4ef32d29),LL(0x802f0897,0xc5371755),LL(0xc49ae8a1,0xb0274ff1), LL(0x417bff62,0xf7716d1c),LL(0x918f9555,0x6efb0748),LL(0x7aeb1e8d,0x7d3bb9c8),LL(0x20d51e18,0xee9bd5e1), + LL(0xd52033b1,0xfaf0a1a5),LL(0xb8626432,0x7967d3f4),LL(0x5574dc0e,0xe837ca4b),LL(0x2c11d8ff,0xf7eae237), LL(0x87dc4007,0xc0f2f1fa),LL(0x8dfb51f7,0xf5f1f153),LL(0x5bd9ac7f,0xa64b10ae),LL(0xa2198841,0xb3c2ba37), + LL(0x66c1ee7b,0x5a7ebac5),LL(0xdba62ea8,0x59e06f4c),LL(0x30944ef3,0xa2ea165e),LL(0x3e21385b,0xfd5c7dfa), LL(0xe3bb110d,0x4a012c73),LL(0x4fb2fdf3,0x16d85219),LL(0x7cad0594,0x1aac7f11),LL(0x4b098d9f,0xea7f7dbf), + LL(0x7fd181e7,0x88abaa5c),LL(0xca3ad1eb,0x136a0c9f),LL(0xf394aab5,0xe6e5e6c2),LL(0x9349e4a5,0x84d697d4), LL(0xf76f4b3b,0x8215578b),LL(0x12feeb5f,0x81a1cec6),LL(0x3e876bc3,0x5d336eb7),LL(0x071892ca,0xe8afdcb5), + LL(0x3da8d94c,0x22f16f6b),LL(0x2d150069,0x28b276c5),LL(0x643d3e58,0x49d20441),LL(0x3da3a7fb,0x3450c84a), LL(0x442ca3e3,0x8f5bf388),LL(0x9e615382,0xca31411c),LL(0x7798675f,0xbe63e34d),LL(0xd1ea01e1,0x551eb64d), + LL(0x34a00e27,0x1738a83b),LL(0xbf58ce70,0xe7591d15),LL(0x57d806d8,0xde2ace5a),LL(0xd0338020,0xe89e8110), LL(0x4e25756c,0x935ed5de),LL(0x46d0f00b,0x07ef8c2f),LL(0xa659592a,0xa28e5fb4),LL(0x7fa4986a,0xcb45c622), + LL(0x74de493c,0x6b7df066),LL(0x79aa5258,0x4d6bdaef),LL(0xe2b255ed,0xe9709c34),LL(0x7d0e7443,0xdba2653a), LL(0xa00eb3e4,0xeb8da5c8),LL(0x7ab0e45c,0xe978228e),LL(0x9d551a51,0x3a31bafd),LL(0x403352f5,0x1de0e9cf), + LL(0x23ddd51c,0xb94d5478),LL(0x130e78e3,0x7c215c91),LL(0xed547bce,0x556b92e0),LL(0x909f5c6f,0x0072da6b), LL(0xf0dc846b,0x4ec71b11),LL(0xbf7baaa1,0xd0f3b3b4),LL(0x47770705,0x896391c5),LL(0x66732587,0x41fe5736), + LL(0x4acd3c51,0x02a7e3e3),LL(0xd30407b3,0x217df736),LL(0xe47c33cb,0x503a31ae),LL(0x4912bbb0,0xe3186392), LL(0x75a5df9a,0x2491a08a),LL(0xc09294ad,0x2882f937),LL(0x979ad9f9,0xe2576b69),LL(0x26dc1ffc,0xf44ddc15), + LL(0x968268ae,0x7dad21d4),LL(0xbe9c6fc0,0x07378e90),LL(0x2b329579,0x9406a872),LL(0x761f10ae,0xb27b5c51), LL(0xd04cf60b,0xf5dad2f9),LL(0xdf950997,0x3154dff5),LL(0xd8534a9a,0xaaec9d30),LL(0xac43f212,0x4ac722f5), + LL(0x46464c70,0x722882f4),LL(0x6c3c702e,0x9b9b5226),LL(0x8325964e,0x4e3974bb),LL(0xaa0c5227,0xd3ceff9d), LL(0x9534dba5,0xd530c8f9),LL(0xbc751878,0xd26e547b),LL(0xea79b19a,0x184a3527),LL(0x74f1cdc4,0x8dab9214), + LL(0xc051e9f6,0x708abc8c),LL(0x4be2d9ca,0x75194e9f),LL(0xd6ab5348,0x031d69c1),LL(0x78b0e490,0x1785990e), LL(0xf6c41f8e,0xd825f125),LL(0x0fbf2fe6,0x429924ea),LL(0xfb87161e,0x53c044be),LL(0x0651d153,0xa3bbdf1b), + LL(0xec6ecb9c,0xda660697),LL(0xddb8c619,0x51b4a5fd),LL(0x230fbffb,0x80b87520),LL(0x8848da9d,0xa0587430), LL(0x864c2502,0x98715939),LL(0xaf973396,0x2b10cbfb),LL(0x09572b5f,0x28675184),LL(0x39adf777,0x0a40cdef), + LL(0x3ead6eef,0x2efa3bb4),LL(0xd1b9fe65,0xbd76b425),LL(0x5e527201,0x95f006cd),LL(0x38a7dc3f,0x00890f3b), LL(0x3a7ce6be,0x84ffa014),LL(0x89541c2e,0x3406aaa0),LL(0x9559d989,0x430542b6),LL(0xb53bddd8,0x9b427b08), + LL(0x49639170,0x2182bd91),LL(0x3299ae83,0xb9fb2b42),LL(0x423b7ea2,0xbc993d59),LL(0xc110039e,0x03e416ac), LL(0x3ffe24aa,0x90c2269a),LL(0x1c322c49,0x421ea02d),LL(0x0ef8fa01,0x40677b1c),LL(0xc59407d4,0xa1acd239), + LL(0x8f14decc,0xb8cd4f40),LL(0x69e16a6b,0x95e90d87),LL(0xc3c38fd3,0x85dcf163),LL(0x0c01f90a,0xf4fb87ba), LL(0xdcd0f994,0x8274f825),LL(0x2e6bf7d8,0x4c685fa5),LL(0x3d928011,0xc87d8847),LL(0xf9efa96a,0x9add0105), + LL(0x50db3113,0xed39152b),LL(0xb794e6b4,0x6b523496),LL(0x84630b17,0x6bb241b6),LL(0x1de3ae08,0x6e9f8ae0), LL(0xd94ce4fe,0x97bd7c09),LL(0x9e61057a,0xe887b02c),LL(0xc62c27fa,0x853e8feb),LL(0x01600ed6,0x3f9d951a), + LL(0xb57b9742,0x3e957b36),LL(0x82b72110,0x92bfd61e),LL(0xfdce7ec4,0x108b450b),LL(0xcc29c494,0xd8af107a), LL(0x47688c92,0x8d67ff70),LL(0x28b9b681,0x57f42933),LL(0xaaf8a48d,0xbbc98ef3),LL(0xe2d549b6,0x14113b1a), + LL(0x0b412b3c,0x1172b259),LL(0x1d42a63e,0xaf86ca6f),LL(0x83660d24,0x5f893135),LL(0x5a21a441,0xe7bfe9a8), LL(0x4ee5122e,0xecd0aa5b),LL(0x5e4df46e,0xbb68654c),LL(0x5e243845,0x0c3e820b),LL(0x5c46bfa5,0x042b1895), + LL(0x894f7f16,0x791b2085),LL(0xb5c353fb,0x42eb80f2),LL(0xdf8db0d4,0x377777f7),LL(0x34c42ef2,0x023c0963), LL(0xa34cb6d0,0xba05eb5e),LL(0x55cd1242,0xffb8b01e),LL(0x87cd9f24,0xeab6ff7d),LL(0xab3c09fc,0x175e94c9), + LL(0x7075fd9d,0x6dc68140),LL(0x4b203c44,0x63851566),LL(0x871d1be7,0x3071e924),LL(0x85ee9cd9,0xe6285b56), LL(0x4bcf8edc,0x738dd629),LL(0x4ace75f5,0xf3a36813),LL(0x3cf6feb4,0x37a09e34),LL(0x2cd0c8af,0x4c2eaef7), + LL(0x16205f2a,0xd945a28b),LL(0xabadde7a,0xfe9112a7),LL(0x2bbf97c2,0x7db6c5ee),LL(0xb5b54833,0x3eb84a8f), LL(0x273007d9,0x9732a49f),LL(0xc6a2e3ef,0xe61431c0),LL(0x10a101da,0x88aa1a06),LL(0xb972cc61,0x64b94de3), + LL(0xf8402027,0xe79eb6aa),LL(0xea6e7157,0xbb1fa5e3),LL(0x4ebdbe4b,0x457f33a2),LL(0x7a61b393,0xf4e955e0), LL(0x698d37cf,0x578e2e64),LL(0x82ecbb69,0xbb139e23),LL(0xcfe8d05f,0x268d0291),LL(0x625fa854,0x7dcfef41), + LL(0x9c4da5e3,0xe21d5b8f),LL(0x10bf3df1,0xb5e22209),LL(0x437bf2c6,0xb04dd106),LL(0x1d055404,0x807c5d04), LL(0x2c06fd15,0x6e983206),LL(0xed63ea25,0x773450af),LL(0x95c8dca3,0xc2dae106),LL(0xd82229e8,0x5323f6ba), + LL(0x57c062bb,0x647fabee),LL(0xcd5210ac,0xcd6adee7),LL(0x181f674f,0x11b4df3b),LL(0xf2a92b48,0x4e23bf4e), LL(0x84a83d6f,0xeea34e2e),LL(0x9cb197e5,0xeaa09d51),LL(0x845e5008,0x7f36a278),LL(0x1581c0ab,0x41fa9b52), + LL(0x23d1206a,0x58917f67),LL(0x11062b8d,0xc04601ce),LL(0xf31f7326,0xdcc60fb6),LL(0x4b071708,0xc5aeef46), LL(0xdc6939eb,0x5364069e),LL(0x034a1052,0x44bd15a2),LL(0x62a307fe,0x8177eeb1),LL(0x1907ad16,0x451ae4e7), + LL(0x27eb3193,0x80e49544),LL(0xaf88f4c9,0xd788e57a),LL(0xd944e00a,0xf062c60f),LL(0xeb4a609f,0x504463e6), LL(0x74f13c8b,0x3593ad20),LL(0xc50bce88,0xdc7c5a35),LL(0xb657d1f9,0xa6336115),LL(0x591425ef,0x18d14e5d), + LL(0x1454f76e,0x73896725),LL(0x425c87a9,0x52772de4),LL(0xc6efb7d6,0xe59e4516),LL(0xd76bbc11,0xdddb8bf3), LL(0xc6fd2066,0x1acbebd9),LL(0x1d7082ea,0x88c3b525),LL(0x6d69cea3,0x6a3b3d62),LL(0x8d065405,0xdbf73dfa), + LL(0x4a7bd06e,0xd659c8d6),LL(0x7bd10bb0,0x67867520),LL(0x97838647,0x7c4e3be5),LL(0xc5891864,0x545c7144), LL(0xfa78d62c,0xf64e1031),LL(0xfa71692b,0x1f046593),LL(0x71310c47,0xd35a9cb7),LL(0x0ea84922,0x10911b96), + LL(0x93a9f5ac,0x5647310d),LL(0x6c05eedb,0xa6785861),LL(0x43950b68,0x2f5aa7c8),LL(0xa9d03b3a,0x57580907), LL(0x42e15fe3,0xd581049b),LL(0x916c4e88,0x55dcf9d2),LL(0x27d1a183,0x87ebfd13),LL(0xf5aaa51e,0x13aee909), + LL(0x3b9fc03e,0xa651959d),LL(0x98997a74,0x05c28772),LL(0xae2e4a65,0x73e047f4),LL(0x783aa072,0x359e6c45), LL(0x7a04b710,0x1124e9f0),LL(0x6d2053f2,0xd35094de),LL(0x2575dab0,0x0d57d976),LL(0x69171229,0x822256fc), + LL(0x3d19de1c,0xbd46937a),LL(0x6f0be84d,0x71feede4),LL(0x7c4dc4b3,0xca205366),LL(0xe3e851cb,0xfbb97d0d), LL(0x2066e9a4,0x0270b5ea),LL(0x42ae150b,0xeade87ff),LL(0x8eb1bafa,0x9a7f9e81),LL(0x0eb5f68e,0xcb374aaf), + LL(0xd5525ab2,0xa5841c9a),LL(0x03e02cd0,0x3eed9ba8),LL(0x279fca98,0x29449bca),LL(0x3f450c92,0x4990ec0f), LL(0xbecbba58,0xa241a8e3),LL(0x2eb47817,0xd0e2487c),LL(0x8300837d,0x6db7d420),LL(0x2d7f59ef,0x78872895), + LL(0x1314fc73,0x1b3d5033),LL(0xe710aded,0x2cf4cd42),LL(0x6f4026b7,0x9159bc5d),LL(0x2e62cc45,0x403f947b), LL(0x47d97843,0x18d6ac70),LL(0x0694f7eb,0x69d5faaa),LL(0x6932e0f0,0x7711535c),LL(0x6ebd1488,0xc85c9616), + LL(0xd3542212,0x558e3750),LL(0x02921066,0x21fe02d7),LL(0x46b90554,0x1636a1a2),LL(0x0108cc04,0x8acf01ed), LL(0xb4d60d37,0x57a2b16a),LL(0x91f4fdb4,0x3301a33b),LL(0x8e09b548,0x70dc3d3a),LL(0x079c0c2f,0x35ae7d07), + LL(0x978f92cc,0x95792f06),LL(0x23196752,0xb11574d3),LL(0xb8cfcac1,0xc3249711),LL(0xcf93af67,0x2061c767), LL(0x2f63dbe7,0xeff09a1b),LL(0x48091edd,0x527776b6),LL(0x19bba5a9,0xf0fa985e),LL(0x66ae3221,0xc54f89f3), +}, +/* digit=24 base_pwr=2^168 */ +{ + LL(0x6a436476,0xbc5a6284),LL(0x35dbb9cb,0x6fcc2313),LL(0x5012ffbf,0xa77d2d9f),LL(0x4ae4bd14,0xcc25e9f4), LL(0x1a5e40c6,0xd17fcfc4),LL(0xff085322,0x7d716a5f),LL(0xee3077c4,0x9dcbc50b),LL(0xdb4a6e61,0xebfe953c), + LL(0xd3d777d7,0xe7e66f2f),LL(0xcf1a6b09,0x3519dc64),LL(0xdbf88dcf,0x0df07beb),LL(0xacd4e105,0x17b09654), LL(0x4e70c783,0xcbd7acd0),LL(0x96b9d577,0xda66e747),LL(0xe3e52f8a,0x6d0488a1),LL(0x6ff71c1b,0x3ec0fd11), + LL(0xbe4f2782,0x75474cb6),LL(0x41c2c0cd,0x10ef5e6b),LL(0x6a65e29c,0x592c6b06),LL(0xd12d0608,0x4d424662), LL(0xb1a714fe,0xf5280949),LL(0x1199f802,0x52697bcc),LL(0xe6a4ff3a,0xc68ba4f8),LL(0x351849ce,0x25a5380f), + LL(0x573ec6f5,0x33207f69),LL(0x67bd2e8b,0x7ecc4bbe),LL(0x8ffe2420,0xa07acd34),LL(0xa13f9cdd,0x0a957eb8), LL(0x9ec9c0c5,0x0bc7f95b),LL(0x6a8578cd,0xd82147cc),LL(0x9e61923c,0x07a2e7c5),LL(0x32e83f25,0x591eb066), + LL(0x957c94fa,0xaaa61588),LL(0x364911fb,0x6a2bc707),LL(0xc4907b19,0x09771450),LL(0x9694ccc4,0x4cc48773), LL(0x50c878ac,0x9db6216e),LL(0x6f3031f1,0x6e89210c),LL(0xced0d41e,0xb711dcbf),LL(0x0fbf9751,0xe39bfe3e), + LL(0x764636b5,0x18fd7a45),LL(0xb75d48f3,0xe437ee86),LL(0x60a80177,0xe323bb18),LL(0xbc94c0ea,0xedc3c8f3), LL(0xec8cb0cf,0xd8351164),LL(0x2472936d,0xccdd8829),LL(0x58059756,0xa8db1b85),LL(0xd55c184a,0x4eda8cf8), + LL(0x2923b8cb,0xdfb5727d),LL(0xe6773d5e,0x6e793e5c),LL(0xa0641165,0x8ecc901b),LL(0xd6da5095,0x6077ab26), LL(0x6b127d9d,0x00669b0c),LL(0xd63e2e1f,0x8140e4e0),LL(0x9641b6a2,0x1ad5b03c),LL(0x9baed7b0,0x44299f88), + LL(0x1ea4a056,0x1736296d),LL(0xd77811ba,0x6f74702c),LL(0x432dd74b,0x5c927548),LL(0xe7a194ab,0x9cc73271), LL(0xd6328dca,0x0f035ede),LL(0x28db755e,0x5292aa39),LL(0xa0192a4a,0xb5488385),LL(0xdfc6895c,0x6e7d2fa8), + LL(0x5d8bbec9,0xfa912a0a),LL(0x0087edb3,0x7051140a),LL(0x64865e5b,0x5293672b),LL(0xc82c48d5,0x6e8448c9), LL(0xa2c437b3,0xeece41cb),LL(0x21ce1ef4,0x148967d2),LL(0x6b05c2a5,0xf14391fa),LL(0x8fed2f1f,0x15ff5fc9), + LL(0x4557b49f,0x18ae5e74),LL(0x3db266b2,0xe33760c6),LL(0xb1b249b5,0xd5d830c7),LL(0xc5fff531,0x24c665b9), LL(0xc57df7c0,0x6b304406),LL(0xc3958e89,0x59706667),LL(0x790a5483,0xbf590ff2),LL(0x5ce77aaa,0xbcaea5a5), + LL(0x80ceb559,0x8578a002),LL(0xd8d61946,0x3639aadf),LL(0xadd3bb00,0x3fd52d94),LL(0xe09a8ce3,0x16c27846), LL(0x294c7967,0x75cfd6c6),LL(0x59195034,0xfb9b7f37),LL(0xaa972a86,0xae687a99),LL(0xebd2394e,0x04bdefdb), + LL(0x2f96144d,0x8e245a19),LL(0x3b61e5ab,0xc740d348),LL(0x293ddb25,0x8703710e),LL(0x2bbf8f63,0xf4bb6ac0), LL(0xde3b5805,0x86396457),LL(0x65d29e63,0x607022db),LL(0xcc930fe3,0xad0a0cdc),LL(0x1626abf6,0xd9997ebb), + LL(0x2a510565,0x2d872d17),LL(0x0357ba07,0x3e682079),LL(0xebfaf203,0x49edd962),LL(0xf81eda20,0x3a13edfb), LL(0x7a75f2d5,0x87b5b5e1),LL(0xddfd9511,0xf04de2b8),LL(0xcfc5c5ff,0xf29a1569),LL(0x07160ed3,0xa3995532), + LL(0xcb2b061b,0xb6247469),LL(0x2f10fe1e,0xe75c5351),LL(0xd20e1bf7,0xbaf44963),LL(0x2d93babf,0x216cb6ab), LL(0xf5109e45,0x7e0b655c),LL(0x6657450d,0xdcc712fc),LL(0xd51fc733,0xe06c408e),LL(0xed9c0912,0x85b11f96), + LL(0x37365c9b,0x954cb91c),LL(0xb2f74fe7,0xe0eaa047),LL(0x15716541,0x9af74b86),LL(0xf73dc7bd,0x4da06207), LL(0xe07890a1,0xdb0d089e),LL(0x73902f91,0x5bf09681),LL(0xa897f0fe,0x14e1710c),LL(0x3605b1c2,0x191ec9a1), + LL(0x0133903b,0x271b2e2a),LL(0xe495ee32,0x5b3686f2),LL(0x0c991f28,0x89bcc974),LL(0x34f93b8a,0xadd20cce), LL(0x680b65b6,0x5f5a1768),LL(0xaad41c40,0x0c453ab8),LL(0xa7fb4269,0xd479630f),LL(0x52c4e929,0x60039d01), + LL(0xff860883,0x0d8d112c),LL(0x723c6e29,0xe1dce5c9),LL(0x191ad70e,0xc19eadae),LL(0x62ce0e64,0x4af8194d), LL(0xcc81415c,0xf207bfb0),LL(0x008495c8,0x3ab92f3b),LL(0xfdb9534b,0xe7250e17),LL(0x6c0c1d1c,0xba67e9b8), + LL(0x072c793f,0x117ae3ff),LL(0x9fb3091e,0x5243e6ea),LL(0x31a59e39,0xf93ad514),LL(0xc93c1891,0x8ce9cfb0), LL(0x1ed08b0e,0xbfcbf901),LL(0xb53d687d,0x4d13cf2a),LL(0x5d81e4ad,0x25aa82db),LL(0x63c3cb41,0xd12f01f5), + LL(0xf8d1333a,0x1e799084),LL(0x653bcd0a,0x30c96c55),LL(0x44b5195c,0x9cf130fd),LL(0x13c77763,0x4cffc531), LL(0x9430619f,0x082287f8),LL(0xb08ce0d9,0x78bb037d),LL(0x3affe8e8,0x2e69d512),LL(0xba9ec693,0xe9dbb263), + LL(0x62f132b5,0x67b66ad8),LL(0xbeb47184,0x70318d2b),LL(0xf50a0e98,0x46c429ea),LL(0xe2b3542c,0xd7e32eba), LL(0xe096b4b7,0x625c1ce9),LL(0x389fd4dd,0x09221351),LL(0xfb0ee85a,0x08dc02d2),LL(0x853cd901,0x98c0ba7d), + LL(0x0deb1d99,0x88a0cd6d),LL(0x79a6b90c,0x989e4962),LL(0x24dd89d5,0xf5d19b95),LL(0xb37cf19e,0x189e5230), LL(0xb0c5fefa,0x84a607b8),LL(0xd8c7fbd1,0xe48450c9),LL(0x46479ad7,0x178f9b56),LL(0xcbcd2ae5,0x7d6a36c6), + LL(0x71ae6516,0x95a4d51f),LL(0x566e2171,0x0363349f),LL(0xed1f2fc7,0x4d4bb4b0),LL(0xf10fa10c,0xde435aaf), LL(0xb76e3b6e,0x711258a9),LL(0x2792e0b3,0x9a640eeb),LL(0x5fab8617,0x7953ead8),LL(0xdd64702a,0xd4b6d248), + LL(0x2d672209,0x95bbe528),LL(0xb6926b8a,0xfcc53cfc),LL(0x57659f87,0x05814190),LL(0x08d25069,0x4836e93b), LL(0x6a5ad81e,0xd1eb2006),LL(0xaf0d37f8,0x4bee145a),LL(0xd31ce6cb,0xd44362ad),LL(0x936c1060,0xdc03e581), + LL(0x16fcb889,0x13cffce9),LL(0xac7e709a,0xed7e6683),LL(0x5896e541,0xb655d098),LL(0xb92a6204,0x07124356), LL(0xa8f50043,0xa2ae43c8),LL(0x68731891,0xeb39255c),LL(0x3d9c408b,0xe07be0ad),LL(0x0b4f5c3a,0x0db7904f), + LL(0x4d70bb81,0x7ddc0235),LL(0x5347797a,0xe3b323c3),LL(0x3536deee,0x3536cd9d),LL(0x001bfd25,0x579b6894), LL(0xebe2922e,0x58ad5301),LL(0x92a88d43,0xe0aa2cae),LL(0x4409e205,0x24567a3b),LL(0x2258f0cb,0x3cece61a), + LL(0x3babf4f6,0x8da5cf46),LL(0x81fff8e6,0xb37428d9),LL(0x48495d23,0xcda1ff77),LL(0x34f392ad,0x98f9208f), LL(0x5bc88514,0x931f5b37),LL(0xcb375921,0xd49971be),LL(0xb5c01fab,0x9dcd4986),LL(0xc1ab1c94,0xcc26ec02), + LL(0xb4b874d6,0x34e8087d),LL(0x9d0a3761,0x224fc277),LL(0x3f7e5159,0xacc1f258),LL(0x8966d593,0xc82d71ec), LL(0x7dcd691a,0x5b1f9f40),LL(0xba28f416,0xd8fafdae),LL(0x43b6d90f,0xe8622ae6),LL(0x9ec71d5b,0xec13fce7), + LL(0xfd2e8214,0x07b6aeb8),LL(0x4cbc297a,0x813e718e),LL(0x81fd6931,0xfac0dfab),LL(0x3c48ffd7,0xa1fe8821), LL(0x85e03c08,0xd2715c18),LL(0x977c57f0,0xb6e4418a),LL(0x73418cde,0xfaa79ea4),LL(0x171e2a89,0x6ab8c25b), + LL(0x4ec7cf05,0x2800445c),LL(0xb66c6200,0x8e74a7b0),LL(0x481db950,0x081b1177),LL(0xb89f7c02,0x526d051c), LL(0x5c29c905,0x3c830942),LL(0x44c15ce5,0xbfbd9e3e),LL(0xa29472e6,0x6055c949),LL(0xa37c4912,0xab0010c7), + LL(0x5b7d3647,0xeb8492be),LL(0x1ee31caf,0x0b4cfd7b),LL(0x4b46304b,0x81cfcde2),LL(0xc554a5bc,0x968df75d), LL(0x8d0e043c,0x7ce78806),LL(0x345ea27c,0x1e896819),LL(0x6e287603,0xe040c19c),LL(0x138e8ece,0xa581856f), + LL(0xc354a9d6,0xe49f6558),LL(0xc0cfb2d3,0xc4ad763a),LL(0x1b76b8f3,0x4be2143b),LL(0xd0ad0247,0xa8caae14), LL(0x928b0ae5,0xcfe96bd5),LL(0x7724f8e4,0xcf5051f7),LL(0xec4af64a,0x9128916f),LL(0xcb437bfb,0xc211ff4b), + LL(0xbce59c0f,0xee6e8134),LL(0xd59f7f86,0x3d068b4c),LL(0x96283457,0xafa2753c),LL(0x1aedcbf0,0x453fe33c), LL(0x483c0b1a,0x781294c8),LL(0x5c2ad1ee,0x9e6f5133),LL(0x69383e0b,0x2a77b6ce),LL(0xfa9f0142,0xcb5a83ab), + LL(0x3b0e027f,0x2318aa98),LL(0xc2c68dd5,0xdea716a3),LL(0x9f548eb3,0x3f75c46d),LL(0x96120de9,0x71642513), LL(0xdbee488e,0xf733614c),LL(0xaad077f4,0xdf940026),LL(0x94a840cb,0xeda9c098),LL(0x393be3b9,0x5108bf0b), + LL(0x39980cee,0x137c08b0),LL(0x0839112b,0x2e31bba0),LL(0xba614ea3,0x9ec73de2),LL(0xd17822c0,0xd0bca8d4), LL(0x50b7805d,0x5d9f7482),LL(0x298becf6,0x16035a80),LL(0xd7c318e7,0x46571500),LL(0xd0ee6956,0x6bd30919), + LL(0xb2e13320,0x5c0ad747),LL(0xda47666d,0xe7f7f71e),LL(0x318a8e8e,0xce322037),LL(0xe9f84dd6,0xf15232ae), LL(0x915a03b7,0xc59709c5),LL(0x9a3040b4,0x2e2000f7),LL(0x8398a5a9,0x41955f77),LL(0x7086b69e,0xa8e6620e), + LL(0x8344224b,0x63acd70e),LL(0xc3145159,0x966efefc),LL(0xf5e0f955,0x406619ec),LL(0xec6de618,0xedd0efc9), LL(0xb2580ed4,0x6fe3e34e),LL(0x4139b95e,0x9d8875b5),LL(0x8e5be187,0x85baf0c1),LL(0x09553886,0x549cefca), + LL(0xae9ef2cc,0xc965b2a2),LL(0x15afee63,0xd43079fb),LL(0x076cdb05,0x02b8794a),LL(0xa0d1a953,0xd0ae7321), LL(0x2ac5fff0,0x5a8b5281),LL(0xcdda362d,0x73437d67),LL(0x1a95ff87,0x1866b2b9),LL(0x0420b3e1,0x5ff11398), + LL(0x92284adf,0x0d43b92c),LL(0x4da4c4a7,0x81425367),LL(0xdf17641a,0xc8093c56),LL(0xb5ccd14d,0xc418f19d), LL(0x506762ed,0xaad98608),LL(0xddb2c829,0xb6f45297),LL(0xd395692a,0xd0e49176),LL(0x3b1073d3,0xc05b4e27), + LL(0xe5808e53,0xe8ca133b),LL(0x06a64b56,0x6105cd0e),LL(0x53cf6d7e,0x89a64669),LL(0x1bebfea5,0xe281ca2d), LL(0x324b25d8,0x98ee67ac),LL(0xdca154ec,0x2227631f),LL(0x4406e8ba,0xa242c5a1),LL(0x49250026,0xced39f05), + LL(0xdd77d731,0xd256dd83),LL(0x7414d0c0,0x2faa6a0e),LL(0x3b90f004,0xa2e0f928),LL(0x8719bfd4,0x019bb3ef), LL(0xe2d515c2,0x3f4f6109),LL(0xbf88d7a6,0xb50a9907),LL(0x015ac4de,0x8e5fbc2d),LL(0xe78a2117,0x96992421), + LL(0x26e53df3,0x321e6086),LL(0xf42b2508,0x07eb1d15),LL(0x0ef22bc2,0x7b552108),LL(0x00f3e571,0x9eedb828), LL(0x6f0e883c,0x556abbaf),LL(0x40473ead,0x8025770b),LL(0x6ece1cc8,0x2fdab965),LL(0x00ec1adc,0xba07cf89), + LL(0x4be5ad18,0xefec4deb),LL(0xd59fa732,0x16625be8),LL(0x6808cdf7,0xffee542e),LL(0xd7a9f29b,0x85c19ef3), LL(0x82dc1ae3,0xca4ac1f9),LL(0xca5e8f58,0xa6c726d1),LL(0x66960edd,0x0bcc3d58),LL(0x56f94ea8,0x8e8445d0), + LL(0x938e64c9,0xd4d0177b),LL(0xf9a0288f,0x8d0199f1),LL(0x14a226c0,0x9176d559),LL(0xa00aea02,0x13b373ee), LL(0x6b629fea,0xc63b2d79),LL(0xa7e0cc42,0x36df7c09),LL(0x40bdbc8e,0x4628ba4f),LL(0x0de296f2,0x7f5b0228), + LL(0x3c63d73f,0xb0598130),LL(0x0431550e,0x55e59f61),LL(0x6693eb8c,0x6f2e109d),LL(0x470b10fe,0x3602ba82), LL(0x5ec7f357,0x3acd0af4),LL(0xb071c758,0xfa7479f4),LL(0xe13652c9,0xbf47caa0),LL(0xf5f5eca9,0x6fa139bb), + LL(0x8c0e197e,0xfa149b84),LL(0x60ae7755,0xca31714c),LL(0x8ccc4241,0x934ed1af),LL(0x781a024e,0x39772769), LL(0xbe24eb34,0x9f07dfb1),LL(0x0a3dac06,0xfa8a9c60),LL(0x8e410ce7,0x08fbbe21),LL(0x396a9702,0xea55fb96), + LL(0xf18882bb,0x4422bc58),LL(0x0ddd0dd7,0x1ccb7b47),LL(0xf40ea941,0x828580a8),LL(0x0db78350,0xf9ec9728), LL(0x1612f28a,0x2823b4fd),LL(0x82b26487,0x96dc3e29),LL(0x2497420a,0x1740fdae),LL(0x322f1c6f,0x3bb39dfa), + LL(0x4cb19878,0xf32a21e6),LL(0x9277c80b,0xeac04097),LL(0x13380801,0x67178d8f),LL(0x34bf8872,0xfe5e2694), LL(0x327129d3,0x8278bad4),LL(0x941c4e5c,0xb42a3f9b),LL(0x39de36f0,0x04eefb7d),LL(0x8d967703,0xed2aab7f), + LL(0x72aa1c89,0xa3283a2c),LL(0x2a4d513e,0x1969613e),LL(0xddd5ea18,0x0d4c0347),LL(0x43cee5fe,0xbbad9ce4), LL(0x57313b49,0xe8c050a8),LL(0xff09bf31,0x3b91c3cc),LL(0x610395cb,0xe6e5ab6d),LL(0xdeb31bef,0xfc36cde0), + LL(0x5d43c8a7,0x76f806f2),LL(0x63b7c746,0x08a64cb2),LL(0x45256a2a,0xb6cdcdab),LL(0x9bebae90,0x640f67ea), LL(0xcf016971,0x682eeeb6),LL(0x50f59261,0x4d16d566),LL(0xf41db99d,0xdaca66bb),LL(0xf8f04d96,0xccdb3da0), + LL(0xcf41b164,0x7c228cae),LL(0xedbefa7c,0x40bef27f),LL(0xecb43685,0x4efdd6c2),LL(0xa834a50b,0x4d0fa367), LL(0xb87f7ec7,0x2ec9c445),LL(0x23170d0f,0xc3663ced),LL(0xc5b47b29,0x189872e4),LL(0x746d6a13,0xf8047387), + LL(0xb75ac898,0x753837d3),LL(0x91959a78,0xaee88a60),LL(0xe6f59621,0xf46b0f6e),LL(0x10d981c8,0x0e92e271), LL(0x8d578b6d,0x610d0f80),LL(0xb4d9b9de,0x962bd7bb),LL(0x84a0c394,0xbe26960d),LL(0x3b5bd996,0x142a0c75), + LL(0x0be95497,0x442bb39a),LL(0x0f33c9de,0xce5d2c60),LL(0x283dc751,0x1ce0d08c),LL(0x79b3c1a8,0x106ed588), LL(0x7f8ee4d7,0x4b2e29c6),LL(0x08bbd660,0x7d61e3bb),LL(0x1e964a3e,0x11504dc5),LL(0xc77a957a,0x31544a52), + LL(0xcd7d0dac,0x1fc4161e),LL(0x370c15c9,0x83733f27),LL(0x853758cc,0x224976de),LL(0x47c1ab78,0x1bbb7730), LL(0x19c89029,0x94a3b697),LL(0x37dfc44f,0x031432f0),LL(0xd88090cb,0xf84593ac),LL(0x65bcfee8,0x381b51bc), + LL(0x10b412b7,0x38dac75b),LL(0xc7e06d08,0x6df5c9a1),LL(0x0e08c41c,0x9c6d8068),LL(0xc3600f4f,0x1544e3c5), LL(0x9c83e0a1,0xf827a48d),LL(0x06bcb3c4,0xd8539228),LL(0x6268cf12,0x149862b3),LL(0x6ec4e354,0x4829ee56), + LL(0xb712a1f9,0x44b2c3bf),LL(0xc90852af,0xe556b78a),LL(0x906a13b6,0x50f6de2e),LL(0x568a1293,0x1744efd5), LL(0x2b5745a1,0x942ad99e),LL(0xca362913,0x0f100bd9),LL(0x91e96cde,0xd9b6ad51),LL(0x5a2f88e9,0x4aa440bc), + LL(0x57a10070,0x53c4c956),LL(0xae6e4872,0x7d1be72e),LL(0xd427eda4,0xb704009c),LL(0x5f39b7d8,0x3e0aa93f), LL(0x3153a757,0xdea1ab48),LL(0x9ee60ead,0x10a070e7),LL(0xe6c916bf,0xd6a6e92d),LL(0xbd7bb216,0x02b1e0e6), + LL(0xb49138a3,0x6efb5f1b),LL(0xe88d2db0,0x11f7a9be),LL(0x3233df5b,0x0b9a2b11),LL(0x1824fcc5,0x0688afda), LL(0x5ff97f9a,0xcf1ea2a5),LL(0x4998e602,0xe8ad7b15),LL(0xa455aad1,0xdb4ae67e),LL(0x74a27ff3,0x823ac090), + LL(0x2573443f,0x5c431060),LL(0x94258714,0x92f9f9ab),LL(0xb1283d2e,0x1548fe21),LL(0x5c5be5f9,0xf86fe50b), LL(0x520c5fc6,0xd20dfc8a),LL(0x53b5e7c5,0x6e721dd9),LL(0x8f2a8969,0x8ef7eee5),LL(0x62d07bdf,0xe894859f), + LL(0x1cfc6627,0xaf279176),LL(0x483755e9,0x94b8cff4),LL(0x0fda4bcb,0xa5916f70),LL(0x47ba65f3,0x9c5318d0), LL(0x636cd7e3,0x9e9c8e54),LL(0x54c49da3,0x5c64a261),LL(0x690e932c,0x04d7ff61),LL(0xc84b0b78,0x92a357b3), + LL(0xc6f3bd8d,0x47f6144c),LL(0x71c19265,0xdf7b1ee4),LL(0x3fd5c30f,0xa7ea37f1),LL(0x79fa08cf,0xdc2d890b), LL(0x2fd40236,0x9813bced),LL(0x432dde17,0xa8a1055f),LL(0x7772c727,0x70011f47),LL(0x2e2e802f,0x965c130a), + LL(0xf5bd4ac5,0x31a6aca7),LL(0xd825db6f,0x83995bde),LL(0xfe521833,0xcbf20325),LL(0x0278f4a0,0x8dcd25a1), LL(0x5f2293ea,0xf1e83d97),LL(0x52317ad3,0x1717876b),LL(0x14181928,0x0df62167),LL(0x2fe203ce,0x24adfd6e), + LL(0x797f25ff,0x1d264af0),LL(0xd22e3da1,0x2cb7cc17),LL(0xe0016a19,0x10c4b51a),LL(0xd82b2a86,0x5956ce8f), LL(0xa3d4780e,0xdef0fefc),LL(0x6e92b93a,0x97e693ab),LL(0x20bcc98f,0x8fa3f4fa),LL(0xf9182867,0x4fc004f1), + LL(0x93e73961,0x1a206da3),LL(0x1e7db32c,0x37d75a90),LL(0x0455b815,0xa39f0db1),LL(0xb69ee770,0x841646e0), LL(0x0939f065,0xadb0aaaa),LL(0x0b147d7a,0x5608613b),LL(0x470f6875,0x84ce1a4c),LL(0x7983050e,0x501de5fe), + LL(0xc3d8ed98,0x19915b26),LL(0x9a66a6e5,0xf451e57a),LL(0x30dab6a3,0x29843607),LL(0x3d1a1ebb,0x1710267c), LL(0xe11d88c0,0xce4ecfd4),LL(0x11ce026a,0x12fc2787),LL(0x691227de,0x9801cecd),LL(0x76ce6dae,0x517a92f3), +}, +/* digit=25 base_pwr=2^175 */ +{ + LL(0x648c48e5,0x821b0fdf),LL(0x9f45a433,0x689e6d56),LL(0x2e572855,0xa5a9dca8),LL(0x8adfb547,0xb0f07eb7), LL(0x552c8d55,0x48ecb166),LL(0xce854171,0xfe3fc268),LL(0xeeee9bc0,0x323af5eb),LL(0x41ae1c80,0x0666a2a3), + LL(0x9ff262fb,0xa06d20bc),LL(0xd075868b,0xcba032fd),LL(0x943fd973,0x70376026),LL(0xe35c5e02,0x81c57cba), LL(0xba871f1b,0x1964e700),LL(0x6b265f57,0xf03a8c04),LL(0x0b950259,0xc8ebc912),LL(0xad32ca8b,0xd2b0ee30), + LL(0x89c8e719,0xe01bf0c2),LL(0xb2f4cdb0,0xbce1e20f),LL(0xa1053ca5,0x8c38eeaf),LL(0x7cd633a5,0x8c2d85ef), LL(0x9b53cdb1,0x75695364),LL(0x447eb1a5,0x5e999741),LL(0xdbd88626,0x6d6b2d88),LL(0x21876357,0x87eaf045), + LL(0xdeec441e,0x2c88f1ff),LL(0xd01b2157,0xab52096b),LL(0x6c45cf5c,0x37eee275),LL(0x0520ecaa,0xa070d24e), LL(0x546b9fd3,0x61d15bd1),LL(0x2c96db1c,0x3276fb74),LL(0xb95b29b7,0xc5c1b041),LL(0xbd7d3254,0xe18008db), + LL(0x98dfb69a,0xd56ae44f),LL(0x609d941c,0xd5f66b0b),LL(0xb91b5245,0xca6b6d35),LL(0x7b3f98a6,0x98e3a4e3), LL(0xf358c56a,0x0715dfa6),LL(0x36a66c64,0x3b02ff21),LL(0xcb22cbd3,0x737b1401),LL(0x6b8e9624,0x9dd15f5b), + LL(0xd360d017,0x25f5a71d),LL(0x29b0ed73,0x4c0779b5),LL(0x9825a018,0xc662fedc),LL(0x61d4add0,0xeee89125), LL(0x92163d14,0x1543814d),LL(0x27370d3c,0x79f2376f),LL(0xcbe1af7a,0xf80c6963),LL(0xeb9e41f7,0xf2d521bc), + LL(0xc1805864,0xe241619f),LL(0xb2de204a,0x6f1d6166),LL(0x50e68d0b,0x13c3f912),LL(0xc4a24f5a,0x32eb021d), LL(0x0e78c588,0x3f1452f5),LL(0xc9971e98,0xa267bf19),LL(0xe801c021,0x77a231a7),LL(0xc2666e80,0xf363c9b3), + LL(0xae309a0a,0xb8eb0bf0),LL(0x375b8fbc,0xa9f52f58),LL(0x1a4993b7,0xb8e4f948),LL(0x8f73c292,0x50ce578e), LL(0x02e503d6,0x2437a4a6),LL(0xe4c68ea3,0x20cdfc50),LL(0x3616f348,0xfec5993b),LL(0xc0c420df,0x5d96b4c5), + LL(0xcca0c48a,0x6b71cdf0),LL(0xc1aea033,0x00e71b54),LL(0x69f6d107,0x247f5baa),LL(0x050c3704,0x4e3ec504), LL(0x7a438e93,0xf2b2be8a),LL(0xa331e01e,0x240b632d),LL(0x91150675,0x61e66557),LL(0x95a99a28,0x32364134), + LL(0xd3399e1e,0x5e5de136),LL(0xfe2f8b75,0xe38bab00),LL(0x3a77db29,0x736126de),LL(0xf2aa121e,0x7b0d1865), LL(0xdecf9cde,0x5545e45e),LL(0x2318be70,0x9608ebce),LL(0xfa55b0e5,0xe6596006),LL(0xbc4b6ca0,0x0c8c2f41), + LL(0x92025945,0xda1c5c7a),LL(0x5d3b0775,0xb114ba22),LL(0xcedb69a0,0x11cc6888),LL(0x0f83c772,0x4365bea8), LL(0xbda8dbe3,0x006fe80b),LL(0xc2d3d266,0x334adcb6),LL(0x1521de1c,0x8c92c084),LL(0x78d8f72c,0x57873ef9), + LL(0x3b64dcd7,0xcfb0a7d0),LL(0x558c9d55,0xf4c2f1fc),LL(0xa0fbc656,0x110c2db2),LL(0xef5b6bea,0x3cad85ca), LL(0x4e0b1230,0x7099dd0e),LL(0x098a2fcd,0xc769b937),LL(0x1e1e7407,0x9209f550),LL(0x1ba7cb47,0x1b47255d), + LL(0x2c01b596,0xd8aed0cd),LL(0x30efcda3,0x1a1a2e11),LL(0x36b1a5b5,0xf771f93b),LL(0x14fcd251,0x2ea34e3d), LL(0xfd893979,0x6895cb31),LL(0x14f556b4,0x10b1d2c9),LL(0x6430bfa8,0x835fdf7e),LL(0x24bf4ba5,0x1f4bbef5), + LL(0xd562b5f1,0xbc805aa5),LL(0x35dac658,0x7101b9da),LL(0xddc28e5a,0x5b7f211d),LL(0xd3d1cd0a,0xea89f24c), LL(0x7567c80d,0xbaaa9ef5),LL(0x9a60c5ee,0xe0d1f26d),LL(0xab36cd64,0xc88a044c),LL(0x1b125de6,0xb8e03d02), + LL(0x3a707a66,0xda0c1047),LL(0x0c692d44,0x76ddb98f),LL(0xb15b7254,0xeccae586),LL(0xe7e82423,0xeadc1b51), LL(0x7c3cb698,0xd6779ff2),LL(0xdf6e7da6,0x0e271cb4),LL(0x45900023,0xeacf34c3),LL(0x03da2ba5,0xafd017ad), + LL(0x27c7e6eb,0x49266998),LL(0x6625bc7f,0x84ffa372),LL(0x05c9cb15,0xedec9247),LL(0x8075b84e,0xcfad0b90), LL(0xbc0898d3,0x94bed316),LL(0x11f92525,0x02481eec),LL(0x0d7e59d7,0x19896e1b),LL(0xf2bb3129,0xa06adb6c), + LL(0x62a0a690,0x1539228e),LL(0x8ae02bda,0x98ac50b9),LL(0xe5cf21b9,0xaf233c85),LL(0xd6a9f599,0x943348d3), LL(0xdb363eaa,0xf5a2f2d1),LL(0x7a8ea96b,0xe917e2c5),LL(0xbf5c8293,0xc80b56c8),LL(0xcdbb5c4f,0xcfc1c24f), + LL(0xfbddf07b,0x7812dce2),LL(0x0186013a,0xd4af2f9b),LL(0x6fe8d485,0x1fadcd16),LL(0xc968f0b7,0xc3c2cd95), LL(0x778bff58,0xdbdd2ef0),LL(0x8706da34,0x67369204),LL(0xb8e70e35,0x31cf3a66),LL(0xd333801f,0x0b9e5cc5), + LL(0xf7177c4a,0x1212a811),LL(0x2d379e12,0x9e266ec3),LL(0x2e8bbbf7,0xc7382848),LL(0xa973be5f,0x3f3f1dc1), LL(0x786e727e,0x534d04de),LL(0x225497dc,0xfd7a5fbb),LL(0xb63b6320,0x3c03a7fd),LL(0x5dc76e05,0xe77f8985), + LL(0x265f8b8f,0xe8d14f32),LL(0xb90549c9,0xfeaab021),LL(0x081ccea6,0x7cd36751),LL(0x1f1e8f7a,0x7a001441), LL(0x1fdfd622,0x2e87b8a2),LL(0x8bb4f812,0xe76138ce),LL(0x71e03be4,0x9a5e8722),LL(0x153e0a5f,0x795e60f3), + LL(0xd0eb7d4c,0x11d28438),LL(0x4254a845,0x147884e1),LL(0x2a8693fb,0x6795f20f),LL(0xee01bd1a,0x5a10d535), LL(0x218c0513,0xe39982c9),LL(0x1d4e6ab5,0x6c23e5be),LL(0x0f424e7c,0x20a8c27f),LL(0x3bbb486f,0x74ae9998), + LL(0xb90ce3a1,0x3fae61be),LL(0x571c968b,0xf0f5a1e4),LL(0x7780d91b,0x6b9dded8),LL(0x7597e866,0x10f60ce2), LL(0xf1eb7d1c,0xf268ed02),LL(0x6030bf9b,0xa49b5a46),LL(0x251f8676,0xc939c4e7),LL(0xe2b9928f,0xbdfe5036), + LL(0xbccf7f43,0x5abfbcc2),LL(0x28c560af,0xb22067b6),LL(0x04c6a2da,0xecf07771),LL(0x8c4ae7dc,0xa2bf88db), LL(0x616675e8,0x172396f2),LL(0x8bfcfbc2,0x9abbb19c),LL(0xe85edd21,0x52e26c06),LL(0xa65de52f,0xfca4c4e0), + LL(0x281d58be,0x255e2d10),LL(0x3614ed6c,0x93ec2934),LL(0x6dc71abe,0x36d6cc15),LL(0xf592ae78,0xaa2ad1ef), LL(0xcc9291fb,0x39a82740),LL(0x102600d8,0x6812b80f),LL(0x50c511d5,0x64f4843c),LL(0x03445793,0x28f5795e), + LL(0x29f20b0c,0x2c566372),LL(0x9e24474c,0xb168ca7a),LL(0xabe37949,0xfadd8f80),LL(0x4cd69856,0xafa1bea2), LL(0x46713b88,0x5ce6ed80),LL(0x4b3bb84d,0xaf8b5fb3),LL(0x29d53349,0x134e5120),LL(0xcdcedefa,0x1214f4f0), + LL(0x4bb405b9,0xc346821b),LL(0xddd624d6,0x753afa86),LL(0xc7c014e3,0x15fe543c),LL(0x43d08964,0x6b3c0c5d), LL(0x745221aa,0xc77c8fb0),LL(0x152995c9,0x3e144fce),LL(0xa61b96bc,0x57089907),LL(0x5e05c1ee,0xd19a912c), + LL(0xa6ddd20b,0x7bcdc697),LL(0x2d5090f3,0xcb07e229),LL(0xf089607e,0x76afc803),LL(0x637dae27,0x9f7a88b9), LL(0x3bd20d78,0x1352d8bd),LL(0x5ea79d4c,0xede1a780),LL(0xf389e31d,0x59a8222b),LL(0x5c09f3d4,0xed066aa6), + LL(0x684529d3,0xade16197),LL(0x96a2a159,0x97bed904),LL(0x1b695d68,0xdd3da765),LL(0x02fecb9e,0xb8fa37e8), LL(0xbc0f7b99,0x1af4311c),LL(0x2a492a7e,0x600bdd46),LL(0x45dc9d16,0x6aa9cb30),LL(0xc0b93019,0xaa494815), + LL(0xba052dd8,0x1211834b),LL(0x86822bf1,0xcdc0208e),LL(0x8c8362a0,0x515eebd4),LL(0x9b90cf96,0x9ea7b9f5), LL(0x3a0a5a48,0x8418fe34),LL(0x331a2db1,0x654d3c32),LL(0xafde743c,0x22362ddf),LL(0x6f6ee3ba,0x617a89e8), + LL(0xb7deb988,0xed5f3d04),LL(0xbbc8a6b2,0x31c2c9e6),LL(0x81a3f184,0x8faa80e1),LL(0x51ecc548,0xa7183488), LL(0xa3780d0a,0xe67512d0),LL(0x822db54d,0x9f868036),LL(0xe555beab,0x6c74490a),LL(0xd989d6be,0xe747e666), + LL(0xdf8cd308,0xf8346dd6),LL(0x4745cd8e,0xe7ca105f),LL(0x31055db8,0xee059c58),LL(0x18b38aa0,0x90f4053a), LL(0x41081a21,0xbb2e7fc3),LL(0x45b33a71,0x3602525e),LL(0x2b411945,0xff21f2aa),LL(0x064ccb11,0xbeaadbd3), + LL(0xfe94629d,0xc35f6950),LL(0x9f860b15,0x1cbaa935),LL(0xf24f8f15,0x29b4bcd3),LL(0xd29c8458,0x0ae5b06a), LL(0x1b6c2df1,0xa645c31d),LL(0xd804facc,0x640b0990),LL(0x122b33e6,0x7a4a7f59),LL(0x7479b828,0x94bb0b2b), + LL(0xc4cd4887,0x0567272a),LL(0xfc8e4b0b,0x676d6962),LL(0x8661c0c2,0xa712b020),LL(0x279454a7,0x660e6aff), LL(0x1cd25bfd,0xe1295106),LL(0x077496a8,0x7096885c),LL(0x3006ab7b,0xdbc47c92),LL(0x509205f3,0x498761fa), + LL(0xe85ecfee,0x5d1eaeca),LL(0x534f38f5,0x9fcddeed),LL(0x8af32f70,0x4d34ec80),LL(0x24b3b4e3,0x476dffc9), LL(0x8bbcda9f,0xb45cd869),LL(0xdf684c2d,0x3b0079e7),LL(0x765cd483,0xcaf3eeb5),LL(0x63945b62,0x0b9e25e6), + LL(0x06492e0a,0xfd73833e),LL(0x9507ea57,0x4d2937e1),LL(0xcf562953,0x3e532c2e),LL(0x81ca80c3,0xe4baa2d4), LL(0x28d22139,0x4699e5c4),LL(0x6b1c665a,0x69aab900),LL(0x641016ac,0xf6a37330),LL(0x5f3b7c71,0x335f14cb), + LL(0xfacd904f,0x94a6c868),LL(0x2ec2bf99,0xb1127cc4),LL(0xa4b72d69,0x0ccfceb3),LL(0x55172f5b,0x16b786a3), LL(0xe093a729,0x51ebe029),LL(0xc40c4487,0xf57f4a1e),LL(0xa8ed5a3d,0x8aaf0dd6),LL(0x811f35d6,0x617c51f7), + LL(0x11e98d29,0x18c7ac62),LL(0x2c904ea8,0x71c578c4),LL(0x3c4ef8bd,0x4626b0ad),LL(0xa390be8b,0x121eb676), LL(0x154e297d,0xcb7249f5),LL(0xc2288ba0,0x678ad966),LL(0x57cc9cbc,0x3c2ab066),LL(0x80c8fbda,0xe32c1d45), + LL(0xf0b35526,0xd2f152cb),LL(0x13877dfb,0xc7f75fd4),LL(0xe83ca4a2,0x8603feff),LL(0xcd680589,0x6be89bb3), LL(0x45e1f141,0x5650549e),LL(0xa55ffadc,0x7dab03b8),LL(0x2dc5d31f,0x342edda4),LL(0x9af8105a,0xa97451ac), + LL(0x705b8fd7,0x796e1fe3),LL(0x02d131b8,0x6252a7ba),LL(0x086c3099,0x3db2ab14),LL(0x9db0ce72,0xeb763df5), LL(0x52b62fa5,0xe7b57bab),LL(0x88b820bd,0x6076d449),LL(0x1b660123,0xc43e1f61),LL(0x189eace5,0xc802d40b), + LL(0x341309a1,0x1f2a2a91),LL(0x414db96b,0x8680be67),LL(0xc846e288,0x65dd0396),LL(0xb0bbea85,0x8a1d871e), LL(0x8ff931c6,0x623e2408),LL(0xe14c5941,0x4933ffda),LL(0xb2cbff67,0x72688986),LL(0x8cf79450,0xe51504d8), + LL(0xfeba1168,0x50cd0a3f),LL(0xcd833df8,0x08d2e0fe),LL(0x0a4370ed,0xdbd60827),LL(0x66f4f58d,0x010cf800), LL(0x144e9656,0xffa29252),LL(0x9d1e9d61,0x90b896a2),LL(0x81f7b4d3,0x1802257c),LL(0x595612a5,0xd7758e8b), + LL(0x241b4dd2,0x751882d8),LL(0xfe177abe,0x7dae3003),LL(0xee6fe1cd,0x8f4d5dc4),LL(0xb08f625d,0x93a9cd5b), LL(0xf91cc442,0xa4d6ee1a),LL(0x594d172f,0xe05976cd),LL(0x6e762b2e,0xfb4064c6),LL(0x51a0156d,0xb2068ad9), + LL(0x24f06e82,0x0d2d5b26),LL(0x8c85a9a9,0xad70f276),LL(0x0ed413cb,0x00ede5d5),LL(0x927064d2,0x245be28b), LL(0x2af70d77,0x06eb2825),LL(0x52b0592b,0x472af630),LL(0xd881d50e,0x493afd98),LL(0x1189c989,0x56fa76a8), + LL(0xfaa974f7,0x775665d2),LL(0xc3f54eff,0xe395ccdb),LL(0x3fc83a7f,0xf0a40e4e),LL(0x4c00087a,0xc3b11d22), LL(0xddb50678,0xef8d2f06),LL(0x6cd5f681,0x6e41f315),LL(0xa1b97891,0x7c9d7a3d),LL(0xa0a41260,0x8b297d75), + LL(0x3806a30a,0xca44b65c),LL(0x61a6206e,0x125c5702),LL(0x87003e1e,0x311842a2),LL(0x4513d726,0xe049a7d0), LL(0x7b123469,0x8022c2d0),LL(0x86294393,0x76533934),LL(0x892e7bc4,0x6a6e84e7),LL(0xdb2007fe,0x7daf8b11), + LL(0x923e185c,0x092d1914),LL(0x3def87c2,0x5ec11237),LL(0x18742a51,0x38019e96),LL(0x4808ca10,0xe05ea79e), LL(0x134cbf9b,0x1fc8ae26),LL(0x01b4c1c4,0x14054672),LL(0x64051972,0x32abf912),LL(0x1af62fca,0x0edaa925), + LL(0x3c47d01a,0x58fa82e2),LL(0x780762c6,0xdb12a452),LL(0xfdbf4683,0x16d5a733),LL(0x2f798deb,0x1d7e8507), LL(0x9eab12f7,0x259aa9b9),LL(0x91261397,0xb13e6e41),LL(0x32602f2e,0x564706fa),LL(0x9c2283ef,0x50daef9c), + LL(0xf07a196e,0x9275f219),LL(0xbb8fcd35,0xfc58ebea),LL(0xbad69c11,0x5d1025f1),LL(0x1605c11b,0xcf364154), LL(0x2992276c,0x427bd117),LL(0x6a73cbb3,0x5545bec5),LL(0x133f3266,0x86855c2f),LL(0x67d9e5b2,0xb3d753d1), + LL(0xc9fb343b,0x2134b384),LL(0xb0e12b7a,0xb572f5d6),LL(0x392d24fe,0x7ee5852f),LL(0xc4f285f9,0x73559fae), LL(0x7711c525,0x269cb9e7),LL(0xf00d5606,0x4badfc52),LL(0xb465df15,0xef66d726),LL(0xaa4a301b,0x83eb59a3), + LL(0xed329b12,0xdb406469),LL(0xd933eb45,0x6eb95cc9),LL(0x6b638bdd,0xe2dabfa4),LL(0x031df114,0x7a5d0098), LL(0x38dbfaaf,0xe22d8f3e),LL(0xd79d1ce1,0x2306fd54),LL(0x7acb7cce,0xda324535),LL(0x88f61a1e,0xde6fcc16), + LL(0xb730fe5c,0xaf3e4894),LL(0x28adf897,0x7a3e4a7d),LL(0xb160ae0e,0x352c0069),LL(0xee52c58a,0x225cfb67), LL(0x96b2505f,0x12391b71),LL(0x3758141d,0x8d811bee),LL(0x8cd82e11,0xc941524d),LL(0xbb83a251,0x0feb26a5), + LL(0x76da8411,0x60ad0665),LL(0x88d4a968,0xe3c033d9),LL(0xde120078,0x767b3c05),LL(0x9f31e1e8,0xab7da95a), LL(0xb93e7cb7,0x7ad9b263),LL(0xfd626ea3,0x280f6bc3),LL(0x62713cad,0x746c3945),LL(0x3a4edce8,0xfa2b4599), + LL(0x10ab7f93,0x8792d0cb),LL(0xc25a2a86,0xfa38d031),LL(0x08b028e8,0x6914db0b),LL(0x383cab40,0x75a98aa0), LL(0x6da884bf,0x462e6b6d),LL(0xd3aa74b1,0x2b0f682b),LL(0x5cee0a83,0xb3b7995e),LL(0x3cce609a,0xe99fca2b), + LL(0x45451744,0x342c41c9),LL(0xc81be29f,0xb00d3c24),LL(0x022e8d27,0xd1e64d86),LL(0xbcf67326,0x404550be), LL(0xc8aab829,0xc7c510f0),LL(0xa90c605d,0xb61ae647),LL(0x02db8602,0x582ad9c9),LL(0x71cb4397,0x732b19ed), + LL(0x265e5369,0xea097c35),LL(0x9d5ea687,0xea7c368f),LL(0x8fcae7f1,0x7fc3b213),LL(0x49c54942,0x641daa3f), LL(0x404c39a6,0x0696372b),LL(0x87b4b181,0x56815716),LL(0xfca24eb8,0xa6e156b3),LL(0xd078a39c,0xf278eeae), + LL(0xac762dbe,0x046566d1),LL(0x625ed2e8,0x662ef0f6),LL(0x650e4764,0x15499e72),LL(0x84edf50e,0x361ccef0), LL(0x1f4a2200,0x2441f6f4),LL(0xdb730d58,0xf36fff06),LL(0x3c01edc7,0xcc18624d),LL(0x8a77e5bb,0x4889078f), + LL(0x75f8dd8a,0x02294e3b),LL(0xfc4113c5,0x5f6f6057),LL(0x6f699f18,0xb5300e0d),LL(0x639dc977,0x52cce358), LL(0x328fd50b,0x5dbe59b8),LL(0x39d73c2f,0x81500be6),LL(0x96ae313d,0x409ac4d7),LL(0x5b16c316,0x15205b7b), + LL(0xfc688c09,0xe272300c),LL(0xbdf71f2d,0xb412cf39),LL(0xf85b23d4,0xe3ab9c44),LL(0x7b662694,0x5c14085c), LL(0x9956d07b,0x24b0b385),LL(0x30b2c82d,0xfa8ea968),LL(0x6d403b58,0xd443b2aa),LL(0xe7fc8d57,0x6da53ecb), + LL(0xdfdf488f,0x29655314),LL(0xadc57e2b,0xb418943d),LL(0x6395a287,0xbaf090f1),LL(0xd62f5b38,0x8fdb4fc8), LL(0x371c9db1,0x115653c0),LL(0x96463359,0x6f5e1f39),LL(0x825e6273,0x106aaf1e),LL(0x398cbe1b,0xba22b7db), + LL(0x62b6bf7e,0x3b545300),LL(0x5bb6f993,0x495d7d27),LL(0x3f00290b,0xf558fc5d),LL(0x2cfc2381,0xdddbeb3e), LL(0x65c79326,0xca402179),LL(0x33b1973c,0x376ce4ac),LL(0x9b30749a,0xd6e65ae4),LL(0x5f54bf5a,0xdf68ee04), + LL(0x4cfdb41a,0xa982948d),LL(0xf2a7b4b3,0xddd1d3ba),LL(0x581aaba1,0xf52a6b33),LL(0x894ebf68,0xc3258264), LL(0x84665ac1,0x26c32c27),LL(0x20119b0e,0xda0190eb),LL(0xb86745c1,0x4a599db7),LL(0x58964b41,0xf9570f50), + LL(0xe0648365,0xb34d039b),LL(0x5c5f61e1,0x2cd7fde0),LL(0xbc6b08cc,0x76f514a3),LL(0x18a3cabf,0xc957b50d), LL(0x2334cd1f,0x775fc56a),LL(0x67ec91c6,0x7bfe3864),LL(0x35ad3a9a,0x99037daa),LL(0xb7ca5657,0x17ffe391), + LL(0xfef04aef,0x19f6d369),LL(0xd1876f8c,0x8030b467),LL(0x3cd7878f,0xa014be02),LL(0x3358c943,0x03c22a58), LL(0x2a257094,0x3c77f083),LL(0xd962a04f,0x47386957),LL(0x82da3329,0x768da40c),LL(0x458219cf,0x1507350d), + LL(0x4397ee7c,0xf460aed3),LL(0x36fbc7fe,0xf249e4cc),LL(0xaab03dfe,0xc42d9da8),LL(0x435ab9f3,0xa3d73ce3), LL(0x3813a3f3,0x86dddbc3),LL(0xb79c32a3,0x86d5779a),LL(0x028a2c3f,0x7c3d9aff),LL(0xb1add2bf,0xc687e71b), +}, +/* digit=26 base_pwr=2^182 */ +{ + LL(0x09b3fed3,0x4612a562),LL(0x3579966a,0xf296c17a),LL(0x07960971,0xa124a36f),LL(0x380c4a05,0x6d03b214), LL(0x70f1f268,0xcb0746e2),LL(0x9341aea4,0xcc9b47ff),LL(0x6d2f59cc,0x1b3662d5),LL(0xd4b1a15d,0xa6c65b2d), + LL(0xcccb0a4b,0xf96c113a),LL(0x3615f016,0x24c26bba),LL(0xeead2f5b,0x52fe115a),LL(0x0d7aaabb,0x85623d26), LL(0x31a2564f,0x50791fd0),LL(0xcd0d59a4,0x3659974d),LL(0x7a8b7466,0x2cffdb74),LL(0x514787b0,0xcf6b36e5), + LL(0x4ab1ccd2,0x8afccd36),LL(0x1c03ab29,0x67314635),LL(0xd7ff3a32,0x458f36bf),LL(0xfcf71648,0x70e9e789), LL(0xa6e904cf,0xf3764534),LL(0xf4bdd378,0x2d6130b1),LL(0x1ca5ce34,0xc61c98fb),LL(0xa4a684f5,0xda11f502), + LL(0xb6223f04,0x8d9daa41),LL(0x841c3fab,0x803c9c0e),LL(0xc50b42cf,0x60eee3f9),LL(0x77298193,0xaf4a7a5a), LL(0xbf809ad6,0xd379c2e1),LL(0xf67c0ff2,0x903ab4b1),LL(0x90f8e637,0xc779d7ed),LL(0x2cf3d363,0x968b0cc0), + LL(0xacf51940,0xaadfa857),LL(0x50156581,0x0c789d1e),LL(0x62cff8f4,0x5e79cef7),LL(0x65eb0d49,0x54cdaba9), LL(0x3321c57e,0xdf7a5828),LL(0xa21a51a6,0x8571e6e2),LL(0xc3726e69,0x0b9b482b),LL(0x1d92b657,0x3bc201e3), + LL(0x8a3b4cf8,0x271c58bb),LL(0x717eb539,0x269fc422),LL(0x5b381fe1,0xe82644e9),LL(0xcb62982f,0x27fb0822), LL(0x5b5ec726,0xb0acd51c),LL(0xea4eff73,0xfd01053d),LL(0x00b11c80,0x465311dd),LL(0x2ed8460c,0xe50a8615), + LL(0x7b2243a0,0x3eade5eb),LL(0x77424d11,0xa59ec933),LL(0xf5c7c3b7,0x65a8e1aa),LL(0x0c1db536,0x008399fa), LL(0xfb194a74,0x80b20e97),LL(0x43be90dc,0x2316fb9b),LL(0x0da4d913,0xb2773b23),LL(0xce973d27,0x945d0671), + LL(0xb79f82af,0x64ca871c),LL(0x2dab52f6,0x31304b02),LL(0x928239a7,0x1825ab54),LL(0x8e4ad736,0x740413b2), LL(0x44071d19,0xc5c5d3fa),LL(0x3f0b2da8,0x83e438f1),LL(0xc70a1981,0xfd759448),LL(0x565ebae3,0x13e0c7ee), + LL(0x26bd7c0a,0x31b74b0a),LL(0xd280cb56,0x66e0e8e8),LL(0x3d1c83d2,0x086795e6),LL(0x396ecf25,0x59e678da), LL(0xf015a36e,0xab3c8d74),LL(0xadc03171,0x0d19aed3),LL(0x5a263686,0xc83b787f),LL(0x9057ed63,0x46b94ad0), + LL(0x90979da2,0xfbf783a7),LL(0xa335c784,0xf04dd6a0),LL(0x87d93c4c,0x6e3c2554),LL(0x47994eb3,0xe3e6b289), LL(0x1b74ba16,0x473c0684),LL(0xabe84e1c,0x4e959eb4),LL(0x7c4a67b7,0xdc3bfd51),LL(0x5095bd6e,0xb4e3cb85), + LL(0x3229fb05,0x96fc11f0),LL(0x4b36c83a,0x598227e4),LL(0xd46fca66,0xdc69ad06),LL(0x703ad6be,0x14cc98e5), LL(0x6b22cd50,0xf0fdd142),LL(0xf89c1a5d,0x9b821fe2),LL(0x829f9a74,0xa3762dca),LL(0xf0c320cc,0xf65a584a), + LL(0x5568f242,0x58f4eaba),LL(0x029afc1f,0x83b0c37b),LL(0x994d7dfc,0x93de2d27),LL(0xb1679532,0x0d9a6edb), LL(0x95f085b0,0x3b834279),LL(0xa299355f,0x46ebac98),LL(0x044427f8,0x0212e489),LL(0xa2f37d0e,0xf9e4ce34), + LL(0xfdc9e233,0x0fa328d6),LL(0x51ae732f,0xd5c8afab),LL(0x83c00cee,0x85e59553),LL(0x87505db4,0x9fce31f9), LL(0x7069d066,0x33ea5eb6),LL(0xf01c0ce9,0x10e32a39),LL(0x0c4f1a2e,0xf170233c),LL(0xbd4cb366,0x8a907760), + LL(0x79bf05e3,0xda593421),LL(0xce49a5bd,0x7730907a),LL(0x09be5c7b,0x0dfb8a97),LL(0x23eb936e,0x6f50c692), LL(0xcb18ff1a,0xc6160551),LL(0x661cc384,0xfa1d23fd),LL(0x7ddec262,0xfef12307),LL(0xb15af580,0xd1aca960), + LL(0x2ee50fbd,0x7eab8a59),LL(0xbe1e7a42,0xe7f71845),LL(0x6121e573,0x5f46a511),LL(0x38ff7eba,0xa25dacbf), LL(0xf58f047c,0xe8aefcc7),LL(0xb538aace,0xc343aaa7),LL(0x3c340b1f,0x3e58cdda),LL(0x1fb98ccb,0xb0e9867c), + LL(0xef7750f0,0x034dd314),LL(0x22da84d7,0x2ceaa705),LL(0xfc0d647b,0x4561a254),LL(0xbbe01157,0x81cf0915), LL(0x34b798eb,0x547a3d4e),LL(0x8b1c7544,0xbb5dd625),LL(0xc8194168,0x94fee01b),LL(0xfaeb010b,0xdb4c25ff), + LL(0xe4d4a176,0x1ff217fa),LL(0xaf87f4f5,0x8b46e6c2),LL(0x89734273,0xcf658775),LL(0x52746de9,0x73c4390d), LL(0xb01c7a06,0xb5c84899),LL(0xedd9ef63,0xfa5ffe4d),LL(0xa1a8b2d4,0x28a313c5),LL(0xdaf5a33f,0xadd45f47), + LL(0x1fdb8694,0xc2dc9d13),LL(0x9a90b4d1,0xaa5e026c),LL(0x208cbfa5,0x5edffd39),LL(0x72a4d6cc,0xf095b3fb), LL(0x6645fcc1,0xbfca4e10),LL(0x92408c6a,0x14b872ac),LL(0xd0b82d2d,0x3d9261e1),LL(0x0294e75b,0x13e4ecb6), + LL(0x3ac2ab9d,0xabd4541c),LL(0x4d5d1531,0x025355b2),LL(0xfb726ab8,0x3d85f67c),LL(0x6d6fc6bc,0x56e26c82), LL(0x495e05a0,0xb24608bb),LL(0xe5afdc5d,0x840e0978),LL(0x248727e2,0x2cc543b5),LL(0x3bc8c021,0xe48146da), + LL(0x530c98b7,0xa1b36baf),LL(0x5acf023b,0x04503d7b),LL(0x21de1503,0x96bc4449),LL(0xd2a9c89f,0xbb8a122f), LL(0xd5d4b133,0x66df99df),LL(0xc97d3e52,0x1bb4a13b),LL(0x79b318d6,0xdab370f3),LL(0x9f18552e,0xfa6c823e), + LL(0x6388a194,0xe5b27e78),LL(0xc88ba441,0x13270523),LL(0x4fecfef5,0x9f309fbf),LL(0x10afee60,0x72cd374b), LL(0x93dfe3af,0x16bd0e2e),LL(0x24bc7e8e,0x7e92096a),LL(0xfec7f0bb,0x144fdf82),LL(0xe1f765f7,0x5d1d4598), + LL(0x72c67697,0xb6b91efc),LL(0xb2487905,0xc7a2ceaf),LL(0x7fb24d99,0x4a4c9e63),LL(0x4d742089,0x7ed373ac), LL(0x9149ac54,0x3f9e6ae1),LL(0x0611efc8,0x64fd7fef),LL(0x3d779af6,0x1c38da32),LL(0x0a1681f5,0x6893691b), + LL(0x50a0fa72,0xbac29978),LL(0xba55c665,0x98d5c82e),LL(0x2d4b76bc,0xf3e5b58e),LL(0x90615b32,0xfae27d9a), LL(0xd49b2500,0xb93bc327),LL(0xbbc213cd,0x7d9d4bff),LL(0xd1ee81c4,0xf985fe72),LL(0x381f9e48,0x6e2a94d1), + LL(0x14fb9624,0x1f09b225),LL(0xca4229d7,0x2eba4ff8),LL(0x21dc8c19,0x5b159dd1),LL(0xb1aa553e,0x1e1f968f), LL(0xc7674d52,0x6ea25976),LL(0x7b283501,0x98e73adc),LL(0xd39468c2,0x7cfce0e1),LL(0x08438a62,0x7aad0af9), + LL(0xb2a3dde2,0x2291cdd0),LL(0xf77a0aa4,0x3a625d50),LL(0x5fbc5a0a,0x3be0fba2),LL(0xe794bf46,0x67b7598a), LL(0x531ad772,0x3673d805),LL(0x03e8479f,0xf9a9b392),LL(0x2e16a126,0x142d264c),LL(0x5a2f6f2c,0xc20409ac), + LL(0xcd43f273,0xd9d84438),LL(0xbda7be72,0xfecc561d),LL(0x241b7ec2,0xc4b113c6),LL(0x40dba9e3,0xfc5bc32b), LL(0xd56bca47,0x70853d39),LL(0xa5306217,0x2b9a902d),LL(0x2017bfd0,0x2bb1836d),LL(0xcd1c2768,0x829ce116), + LL(0x697097f5,0x42d5fcf8),LL(0x1e936db5,0xc1fe7be6),LL(0xcb6a81d4,0xcbc5cdcc),LL(0xafef5ffa,0xab1e4ecb), LL(0xb933c216,0x3cbbdf76),LL(0x503607e2,0xdb5808da),LL(0x6bc96246,0x5bdaab7c),LL(0x68274629,0x91e5d17c), + LL(0x2eb1db21,0xa3cd09f6),LL(0x92c3e3e1,0xbe370485),LL(0x6aa43da5,0xeb51fa29),LL(0xd726625e,0x2c7fa809), LL(0xf0ec0e99,0x90c6786f),LL(0x08135cbf,0xd315af33),LL(0x1504751b,0xc1b60172),LL(0x0e28781a,0x88674e2d), + LL(0xed74e633,0x6aa74055),LL(0x7d06ce02,0xc44e740f),LL(0xa33b8d5e,0x8b40bc5e),LL(0x20f00f14,0x42d3539f), LL(0x3307ef15,0xd9f1f5cd),LL(0xc8599bcc,0xa9fe4dfb),LL(0xefa80b8d,0x31cb6703),LL(0x53bb73fe,0x4172b46d), + LL(0x20e4c321,0x85a70280),LL(0x5ac075f3,0x999a0d07),LL(0x7bdb478c,0x59a62b62),LL(0x573c403b,0x9aeb710a), LL(0x950bb8fc,0x1c099614),LL(0x5dc09741,0xc1efafab),LL(0x7296a74b,0x0de58ca5),LL(0xf5be2ec4,0x657116a4), + LL(0xcb199b77,0x0ce52f0f),LL(0xbcd11438,0xdcdc5cb9),LL(0x4777327b,0x587a68ff),LL(0x1cc6fbb3,0x55d9abb7), LL(0x9eeb28a9,0xf1970b82),LL(0x4ceef00f,0xe1ab4e14),LL(0xf7462893,0x184d3fb6),LL(0xc8ea54fd,0x9942a008), + LL(0x1e33b2a3,0x1fee0f77),LL(0x9f789870,0xd4bed81f),LL(0x6ef05b7e,0x6396feea),LL(0x2640b62a,0x9c5d6a01), LL(0x6834bea4,0x170cfec9),LL(0xe131feca,0x68d16728),LL(0x00affb4d,0x4be9c5d6),LL(0x99a6f256,0xe34a423c), + LL(0x09b9ed61,0x1a254e4a),LL(0x30b10207,0x902bc066),LL(0x62121f53,0xd2d5ed01),LL(0x30f1b518,0x0ba86811), LL(0xabe139c9,0x7916c132),LL(0x62c4f337,0xb3a30fe0),LL(0xaa5693be,0x85d0a769),LL(0xe3c7687b,0x2d414379), + LL(0x94958719,0x92b0cb3c),LL(0x4ec6575d,0xb78aa37b),LL(0x4f1bf26a,0xd035aae1),LL(0xd31d5108,0x1383992d), LL(0x92bdd6f5,0x53ecc535),LL(0x08c622ca,0xa9925ff6),LL(0x916d890c,0xcaa3146e),LL(0xb9c10220,0x8cd0f12e), + LL(0x7e12a730,0xcb6ad82b),LL(0xac9485db,0x3f89047c),LL(0xfea2d970,0x6f926117),LL(0x46a19ecb,0x87b0cd9d), LL(0x01e45bf6,0x98bb5b02),LL(0x2ed7716d,0xfc814620),LL(0x4f5caa95,0x8d6808cf),LL(0x082f799e,0x3b57df03), + LL(0x2df84ca2,0x469e1854),LL(0x64aac069,0x00dd62eb),LL(0x88d9efff,0x7d3ee9ce),LL(0xbb830ffc,0x9faed6a2), LL(0xd2d74f58,0xd073aac1),LL(0x2d44199e,0xf69e96b4),LL(0x83ed62ca,0x6cb3a3b1),LL(0xd799acf8,0x472489fd), + LL(0xb63a36cc,0x5f84382d),LL(0x92d5b175,0x6ba1de87),LL(0x516101b7,0x25aab130),LL(0x5f039793,0x6f69c3fc), LL(0x89e3da4f,0xd28439ee),LL(0x5e6b2b61,0x8cb40a0e),LL(0xe3d6650d,0xdfa55805),LL(0x0be59fd2,0x2651f6c7), + LL(0x140d01c8,0x290e0044),LL(0x62ea488f,0x78afa0a4),LL(0x91eaa932,0xc4e39971),LL(0xfe2e79dc,0x8a9ef3a2), LL(0x50705b7e,0xdcfae315),LL(0xd4be3d75,0x73324dca),LL(0x03a91415,0x900bdd43),LL(0xedfdc74d,0xc3ed02ed), + LL(0xf22b4a66,0x509bd1d6),LL(0xb78d264b,0xfd8ed371),LL(0xa419134f,0x562b2d3a),LL(0x7a57a51e,0x80a2c274), LL(0x8c662472,0xebba5317),LL(0xa0be71fb,0xebafedf2),LL(0xb77899c8,0x0c5b9c1c),LL(0xc4888cb5,0x82448008), + LL(0x78401c3b,0xb795ea00),LL(0xa85ab971,0x86776990),LL(0x185739da,0xdd81393b),LL(0x58136c97,0x76d0031f), LL(0x641d39d1,0x6aceaa56),LL(0x39be7ca8,0x918844c7),LL(0xe18efc54,0xa63993f7),LL(0x4af0f30a,0xb5369150), + LL(0x3d04af4f,0x9bc2068c),LL(0xa7796ed2,0xf309dff9),LL(0x4e15b6a2,0x46e9a59d),LL(0xc22ef488,0x617aaeba), LL(0xa15cf0cb,0xd91a8f90),LL(0xc30fb779,0xc6ce12a4),LL(0xb9d0a7ff,0xf3b80254),LL(0x6e9b6fa1,0x32a63bf9), + LL(0x546fe4a8,0x3e1ac837),LL(0x1279c7ef,0x91ed89a5),LL(0xc73e9dea,0x8eb7b88e),LL(0x18238af0,0x96d07205), LL(0xe96abf80,0x56ebf306),LL(0x52c4b10f,0x5088ce24),LL(0xc979137f,0x65293176),LL(0x228d300a,0x824642fb), + LL(0x7836aea5,0x968963a8),LL(0xfabbfac1,0x2d4c556c),LL(0xd3f9977a,0xa4c389bb),LL(0x99b4ccb6,0x2e8b2818), LL(0x6cb67df6,0xc1fd8565),LL(0xa72d2be8,0x0ac57d2a),LL(0xb8224ead,0xa51ce6b8),LL(0xf417d744,0x33f7b468), + LL(0xf9f0bdf4,0xcf8c80af),LL(0xd3222dd6,0x0728f880),LL(0x653afc12,0x436188a3),LL(0x3c7940bb,0x0f8bf160), LL(0x424dcd2a,0xdc18c13f),LL(0x20d3cd1f,0x038c1842),LL(0x7b12fd42,0xed7f86a5),LL(0x7aaf1881,0xa75ab77b), + LL(0xdf0574e2,0x5c3d7612),LL(0x719414ce,0x2eeeeb6f),LL(0x90349fc4,0x797c5771),LL(0x2232eb33,0x0d850f73), LL(0x2638c051,0x0a0744f3),LL(0xb6e7dbfa,0x739e6278),LL(0x659fc5f5,0xa77f286d),LL(0x9654b0eb,0xb18b7cf1), + LL(0x6062e78e,0x5a2089ac),LL(0xdfa6fb44,0x152f1804),LL(0xb61e6faa,0xe8a404b4),LL(0x08d06ea8,0x4774d30f), LL(0x3c359648,0xd7119b91),LL(0x09473ff7,0x850b02bd),LL(0x936b7868,0x4db6f9a0),LL(0xae38c3c5,0x84064dd5), + LL(0xfe448461,0x294d6831),LL(0x42cd2105,0xc3c6f446),LL(0x3a2fdcae,0xa4412eb0),LL(0x3d5a9181,0x394c3774), LL(0x5ca87c4b,0x58f19024),LL(0x89ad5685,0xba1879db),LL(0x803c2589,0x43c55c6a),LL(0xa8249c65,0xae1fad20), + LL(0xe0aff809,0x4929e89f),LL(0x1769a00a,0x19755ec2),LL(0xc242f335,0x3b6a207b),LL(0x090edab0,0xeca054ef), LL(0xcd9e1c26,0x217e9c8b),LL(0x35d4ac57,0x917c2ecd),LL(0xad33911d,0xdc869d5d),LL(0x2e828bd7,0x22d9d860), + LL(0xf38dfaa1,0x89262252),LL(0xeb9cd8d7,0x155c96ce),LL(0xed5ebcc4,0xb0082b5d),LL(0x17182086,0x7b6f9203), LL(0xee92aa6d,0xaefe28aa),LL(0x9aaaa0eb,0xbe67090c),LL(0x2f8ef18d,0x88c5fbf1),LL(0xdd1fd65f,0xbdc8bef1), + LL(0xa9c7b483,0xfb7052f5),LL(0xbd6c8a99,0x49634258),LL(0xc9f424f8,0x1410a747),LL(0xe9805723,0xfda0a304), LL(0x0879bd30,0x1a438bd3),LL(0x7f6903cb,0xed09a9d3),LL(0x57e53497,0x920878f8),LL(0xa7fca0ed,0x87a12968), + LL(0x38590ca1,0x7c8207cb),LL(0xfae885c2,0x4cf52db1),LL(0xe8dc711f,0x6cf384c4),LL(0x221dc698,0x6fea20ff), LL(0xa07bb79f,0x6af56700),LL(0x33ca79c6,0xc7da3b52),LL(0xd05eb519,0x3a214691),LL(0x93d4f089,0xea94c4f1), + LL(0xba51f002,0x734039d0),LL(0xce206406,0xc45e2042),LL(0x4b3c3d53,0xc0e75dbb),LL(0x55b1b97c,0x3a701272), LL(0xd6addb6c,0xec856e95),LL(0xf283aae1,0xb63fe8c6),LL(0x405788d1,0x148fb239),LL(0xe0181912,0x42e7148b), + LL(0x7de07978,0x00bddcdd),LL(0x3c2e0a27,0xac79b657),LL(0xdf1dd3dd,0x94024ba6),LL(0x0bac41ad,0xcddeb357), LL(0x500c4f4b,0x51ec3dd7),LL(0xd31c8fbe,0xf00d594f),LL(0x373a3e93,0x6b8c6f43),LL(0xfc2b6be9,0x891ba3a5), + LL(0xddd72e36,0x3928225a),LL(0xcee362c1,0x1e6a63bf),LL(0xc5eb404c,0x317b78f4),LL(0x67c5e6b3,0xb882736b), LL(0x1f2f07aa,0xb1da56ce),LL(0xff83b633,0xab3c4fbe),LL(0x0ceeab99,0x9cc32f1c),LL(0x1062070e,0xf1dead0d), + LL(0x8a3e79c4,0x49ea0d9b),LL(0xec9f16d1,0x4e7abe3f),LL(0x5549ade0,0x19bda1c6),LL(0xe5885734,0xaae756a5), LL(0xcc2a1aaf,0xb3cff8ce),LL(0xf896ca47,0x812eebff),LL(0x9b2e1123,0x0951b2bb),LL(0xdef6d6a9,0x7f245699), + LL(0x1be7ef41,0xa1331e95),LL(0x9fa1be62,0xd1f0c3c3),LL(0x4383e451,0xb1d8295e),LL(0x9f08bc14,0x658d8a84), LL(0x3ba4b85b,0xb0587aef),LL(0x481cbb27,0xb519c587),LL(0x040d8f06,0x2b975db6),LL(0x1691d809,0x399f6417), + LL(0x7c6204fb,0x207a0e46),LL(0x62c3e9d7,0xe30f1420),LL(0x792f8208,0x6127b782),LL(0xb0d3fca9,0x38f806ab), LL(0x2ff46c64,0x38248542),LL(0x926ec166,0xc18ffe85),LL(0xc0c133fa,0xfd268866),LL(0xb93770e6,0xb7f63f5a), + LL(0xb13afb71,0xd8f1db26),LL(0x32a790de,0x5c5627eb),LL(0xdf50b6f8,0x7f41bc1d),LL(0x92d4c803,0x49d4ef17), LL(0xe8530065,0x577f909f),LL(0xe630ff2d,0x482cdede),LL(0x14f54de8,0x682c8c6a),LL(0xb4079343,0xe6b5a504), + LL(0xe58bde6b,0x00d927fc),LL(0xf34841f4,0x65d85f03),LL(0x2ac001d8,0x265aec02),LL(0x2dfe518d,0x1b785666), LL(0xc01e6e47,0x76142488),LL(0xdd5648dc,0x8e8b2044),LL(0xb3a340b3,0x2c422006),LL(0x3dd67b22,0xa5392113), + LL(0xa1567aaa,0xbd08d05b),LL(0x02acbec6,0x84a55e43),LL(0x5d898af0,0x744ffd21),LL(0x6682e78a,0x38067622), LL(0xffd08522,0xf3696ff2),LL(0x2bf02466,0x49dd0060),LL(0x59c3e65d,0xc9e0d1a5),LL(0x0a37fc25,0x29537f56), + LL(0xa5f6b17a,0x6f6cb9eb),LL(0x9c55857e,0xc1854320),LL(0x45dacc6e,0x959585c6),LL(0xe5f4e930,0xf4e97c94), LL(0x57d2a492,0x966deb5f),LL(0x55d2df12,0x98256831),LL(0xaa457eca,0xfdd65534),LL(0x03551474,0x76dbb021), + LL(0x09d9b4aa,0x0aeefee9),LL(0x784ca675,0x30fea11a),LL(0xff1d381a,0x56b4b509),LL(0x9fce40da,0xd1b26fea), LL(0x48d22911,0x4835b911),LL(0x8bbe57e8,0x6aaac57a),LL(0x19d02037,0xc8882792),LL(0x3ee49afa,0x301e0aa6), + LL(0x00e6b020,0x1641ce6b),LL(0xeac7cad8,0x846b97de),LL(0x61aa6886,0x9b74bfd8),LL(0xb0fa37ac,0xdd95e765), LL(0xf848a83b,0xda0cde52),LL(0x355b3528,0xd2cc831d),LL(0x5e22238f,0xc7fd2e03),LL(0xab9a6c34,0x6d5373fa), + LL(0xd8247f13,0x5dfc2874),LL(0xe3c11f56,0xc211a7a1),LL(0xa2503b97,0x7512563f),LL(0x5c007c82,0x124cd984), LL(0x491cd249,0x4f6eb682),LL(0xa683359d,0xaf4f70a3),LL(0xcc302b62,0x2f1dfe71),LL(0xe57fbf56,0x83c474bb), +}, +/* digit=27 base_pwr=2^189 */ +{ + LL(0x916a8016,0x43af7ab7),LL(0x532bfb9c,0xf93d487f),LL(0xe2174971,0xa5f9af3c),LL(0x2d59b4d4,0xd1b9cf1f), LL(0x44f4eb91,0x4a779418),LL(0xc226edc5,0x6a131fac),LL(0x80d4bb33,0x472ab897),LL(0x2f6ca1fe,0xb69687a5), + LL(0xfabd066a,0xffa73ca2),LL(0xf9c78bfd,0x494e03a8),LL(0xff55cfef,0xe585a878),LL(0xd7053784,0x00770b1f), LL(0x056fe70b,0xdec4da4a),LL(0x57bd444f,0xe37395d8),LL(0x685df668,0x666250d4),LL(0xbe6cc583,0x0549569e), + LL(0xab11639e,0x87629830),LL(0xa4488d53,0x869dd3ba),LL(0xbaf06eb6,0x10fe1c0b),LL(0x1687ac37,0x99034839), LL(0x7f1ffe7b,0x38418377),LL(0x25bd7c57,0x3334a74c),LL(0x7008ba67,0xc57cb7ed),LL(0xc1e4e12d,0x384c12d0), + LL(0xdb4bdb35,0xf48cdca6),LL(0x74d913a7,0x6bc23aec),LL(0x12ed94d5,0x8f0ccd9d),LL(0x86db09e7,0xe4aabd12), LL(0x1e948326,0x0cbff31a),LL(0x17a479a2,0xcf68c47c),LL(0xca7686f1,0x3cced8e2),LL(0x4eb62669,0x15ed1e99), + LL(0xbdb0c561,0xc373ab4b),LL(0x6a9066a7,0x15082022),LL(0x62d31801,0x330a60c3),LL(0xe35bea57,0x53d97f09), LL(0x9c5dbb92,0xf204e006),LL(0xf831262a,0xfb9a8219),LL(0x42136174,0x3468ae41),LL(0x0e03218e,0x0f8fb5bc), + LL(0x4ad8bba6,0x90337499),LL(0xe3ecb618,0xdb71e1fb),LL(0x3cf2a8ad,0x6955e874),LL(0xed691fee,0x594501f5), LL(0xd29bd364,0x7e2baef3),LL(0x6f766759,0x5cbd91ac),LL(0xb2201a96,0xaba54aaa),LL(0xcfa392ab,0x2cfea457), + LL(0x86f8f7da,0xa4da4162),LL(0xcbc0b934,0x88d70b86),LL(0xacff4f7b,0x9df02795),LL(0xc65ef81b,0x0fc80219), LL(0xa299ca0f,0x32d457de),LL(0x0896427b,0x97081b35),LL(0x41bab6b4,0x92d6c309),LL(0x73b8d601,0x5d5e56f3), + LL(0x202bde39,0xfb3992a4),LL(0x3d6bab98,0x2549f564),LL(0x87712512,0x0b564642),LL(0x7fde7e50,0xd52442b4), LL(0xa3d3e16e,0xa6cefd08),LL(0xc83b29bd,0x5b194f0a),LL(0x906dec8c,0x6db0edd8),LL(0x02570c1e,0x7a090959), + LL(0x4c41eb53,0xf6f74fcc),LL(0x5b944a6c,0xd07678a9),LL(0xb80677ea,0xf53bf11d),LL(0xbc5900f8,0x569a5761), LL(0xd3d4de91,0x34e5bba8),LL(0x8361f73e,0xc5774804),LL(0x59abdbd5,0xd637d3dd),LL(0x8772b615,0x64a81bf9), + LL(0x7f3d83ab,0x78bb12ea),LL(0x573f9b99,0xca22c31c),LL(0x2aed4c39,0x4283c173),LL(0x39f32bdb,0xda054c1d), LL(0x1da2cbd7,0x2ead717e),LL(0x62390b41,0x747d67cd),LL(0x6b9666a6,0x43739d9c),LL(0x8c827b12,0xb84e2f22), + LL(0xc0312773,0x0e4ac2b1),LL(0xe53f068e,0x571cfc75),LL(0x42bfe41e,0x6c44df85),LL(0x627e30bb,0xe7d2edb9), LL(0x0dd5cedc,0x9c2e4fd6),LL(0x0f7d22d7,0xe2d885ef),LL(0x1329bcfd,0x44b0b5db),LL(0xba1c96f6,0x006e872f), + LL(0x7e952317,0xdbadab5d),LL(0xc2a5bcaa,0xab849ed4),LL(0x1e72dbb1,0xe3acbb74),LL(0x5d4b7cb7,0xbf42c3d3), LL(0x3d748639,0xebe967b5),LL(0xc03af7a1,0x1fe93db5),LL(0xa944ea06,0x2ab14596),LL(0x76655c09,0xfb05a759), + LL(0x6f8a532b,0x5117890c),LL(0x59430c5b,0x2f57781f),LL(0x79e07b84,0xe70968b3),LL(0xe86d7223,0x05df2305), LL(0x31e32933,0x57af0dc5),LL(0x84afc419,0x5473e34a),LL(0x03d5feb4,0xa7337a42),LL(0x1b1c6bd8,0xd85c8602), + LL(0x753008e6,0x25ca1891),LL(0x5f0ff93a,0x4338ec98),LL(0xddd30a7c,0xd2ba8557),LL(0x09c51794,0xb4b65361), LL(0xd1cbc66e,0xfbb51399),LL(0xe53bca50,0x28853781),LL(0xfd5a9aaa,0x5b797232),LL(0x5b88c4f3,0x6249afd7), + LL(0xba6918a0,0xcc5ab6cb),LL(0x8fb65c7d,0x9f824ec1),LL(0x56b18754,0x4796d80b),LL(0x67721520,0x4c83d371), LL(0x63b03348,0xd77c373c),LL(0x54f27457,0x91930e5e),LL(0xaf40c03f,0x83f97370),LL(0x34eea661,0x65b55872), + LL(0xeb10175e,0x310695d0),LL(0xcd236aa1,0x79aaa6ea),LL(0x3edfff40,0xf78539ff),LL(0x02cd6063,0x2369c517), LL(0x5c8631ff,0x81e43ae5),LL(0x216a60bd,0x065e8212),LL(0xe761a5f9,0x225cb473),LL(0xab6de6fa,0x695ef860), + LL(0x7d7d98d4,0x03536a46),LL(0x18413673,0xa17d3a69),LL(0x295ae303,0xa6ddcd46),LL(0x61beae2b,0x86de0bbd), LL(0x7699458e,0xdd73dfcc),LL(0xb53f88dd,0x827deba5),LL(0x42a9a11c,0x213c376b),LL(0x12c73975,0xc854fd72), + LL(0x15ac27ff,0x1fa96547),LL(0xf49b6c9a,0xcb0dc17b),LL(0x709dd202,0xa3e44853),LL(0xcfe2bbea,0xd3905c5f), LL(0x6c35ce9c,0xb01e5799),LL(0x900ef600,0x0063e7ac),LL(0xfffa5cc0,0x8c70b87e),LL(0x74230b0c,0xebd76d34), + LL(0xed5f8529,0x914eec9e),LL(0xe8edf477,0x7a65ffd3),LL(0x70c74bee,0xf0cb206d),LL(0xd1b02e01,0x03445ff1), LL(0xe5dbf791,0x664ca356),LL(0x254e69c4,0xd678d4ae),LL(0x8617386b,0x370c9f0f),LL(0xfdcd985d,0x42af7a0c), + LL(0x83c3da54,0x8c4b5009),LL(0x4c8a87c8,0x086a7ec5),LL(0xaa166c4c,0x9ba0b368),LL(0xa658ac1c,0xa279670f), LL(0x5d0544da,0xc49f49bd),LL(0x15cb0b41,0x28c22323),LL(0xa4834d71,0x86293dfa),LL(0xd1e1d63b,0x283e191d), + LL(0xca188555,0x0cad6519),LL(0x0cbd0c5c,0x323ce5da),LL(0x38560254,0x6b7d2be1),LL(0x1696b9b9,0xb05ed385), LL(0x9ae59f92,0x8ce4b5a7),LL(0x4f7e61a3,0xabe5ff33),LL(0xdbfeb302,0xae15a3cc),LL(0x837fde82,0x691b1129), + LL(0x2e6d116b,0xb60b31f3),LL(0xecab5aa9,0xd49e9d11),LL(0x6787f23d,0x3e95f844),LL(0xa12f4846,0x2ab8834f), LL(0x5b6359cc,0xe70e2ab1),LL(0x9322a047,0x7a6349e9),LL(0x6c1e483a,0xc01e424c),LL(0x92bd5d1b,0x424b2027), + LL(0x254e49a3,0x8a6e6766),LL(0x97e70d58,0xb8d85d42),LL(0xb51b3abc,0xa859082f),LL(0xe7bb828a,0x2850573b), LL(0x7bfe8021,0x47cc95b2),LL(0x5853f12c,0x7c28fe9e),LL(0x10c0f389,0xe5fb0558),LL(0xdaf0a7e7,0xb99a639f), + LL(0xf60ee3e5,0xa6b9e6c9),LL(0xa236377f,0xb397af7f),LL(0x7da4af71,0xb7a318ac),LL(0x0a9d39fb,0xae64b613), LL(0x902b3411,0x66ce6c74),LL(0x5a199e53,0xea256a70),LL(0x550fb76f,0x8dcddd89),LL(0x03e70f9c,0x9443b477), + LL(0x142113a6,0x1787b8a5),LL(0x180aec95,0xa58b6c61),LL(0x947ff26d,0xcc381420),LL(0x3d8b8c36,0x22520e8f), LL(0xef2cc6ef,0x192ee945),LL(0xe9ca0c7a,0xea52afee),LL(0xe6e30d93,0x5970d794),LL(0x57c786ac,0x0a325e42), + LL(0x33ca1226,0x5e2dddf8),LL(0x588cb1e3,0x18e624b9),LL(0x21809265,0xf3ba597a),LL(0x5d575728,0x90247702), LL(0xc1f918db,0x48a5bf7b),LL(0xd6840541,0x17d1efaf),LL(0x3e2e754d,0x13dfe6fe),LL(0x707a531f,0xc471e16a), + LL(0x97d34b48,0x79085bbd),LL(0xc2e9bea9,0xfa5ba99d),LL(0x6c5a6dc2,0x70b9c9fc),LL(0x4e94c5db,0x4e042213), LL(0x25ebb95f,0x4a37b41f),LL(0x055d79fb,0x24691010),LL(0x3f572a8f,0xdaff9352),LL(0xf327ec2a,0xe63d55b0), + LL(0xdebd5116,0xc5a86d3c),LL(0xa2ddef2a,0xd547fe08),LL(0x6a149f12,0xbabb617f),LL(0x8a766128,0x14f69a1b), LL(0x48236f77,0xb83a1477),LL(0x35711279,0xd0d81be1),LL(0x5eab1c3a,0x706f9067),LL(0x16a1ffaf,0x8c4823f1), + LL(0xaff5ea89,0xd845c68b),LL(0x6b75eadb,0xa276eaeb),LL(0xcc230ec1,0x2d0fc819),LL(0xedaaf1f2,0xdfad96e8), LL(0x40868254,0x0f25dcbf),LL(0x5babd7f9,0x53bbe31e),LL(0xcf804a8d,0x7f8afc48),LL(0x5f9b9a0d,0x7f4922ef), + LL(0xd7422804,0x703cbf6d),LL(0x83349bdd,0xe5df61f3),LL(0x77d285ad,0x0fa3d8cd),LL(0x2e88e15e,0xe990f9e5), LL(0x8561d8a6,0x40ec61f7),LL(0x16650305,0x7fc498a6),LL(0x8e5beabf,0xa3bf5cb4),LL(0x76ae0350,0xfaa52008), + LL(0xe4fc3e72,0x99e24318),LL(0x2079c616,0x9241c8ab),LL(0x9584a258,0xefa5bf38),LL(0x1eebb098,0xd7b770b5), LL(0xe1fc18a7,0x28b714a3),LL(0x5b83dd9a,0xf0426bd2),LL(0x291b28ee,0x956d8972),LL(0x6eb553ff,0x8bb8cbde), + LL(0x95298003,0x396cfe2d),LL(0xad8412fc,0xcaa66550),LL(0x83997dd3,0xf41d0215),LL(0x45534587,0x7066e356), LL(0x5b6de0d7,0x0d5b5c3e),LL(0xcecd5f26,0x8ead45d0),LL(0xd252ae50,0xe2f24e2c),LL(0x815150bf,0xf71e5d4f), + LL(0x54527ce5,0x3872685d),LL(0x91fd99ee,0x59b343ae),LL(0x3462cc0c,0xd621d027),LL(0x8dbfbcf4,0xfa42481f), LL(0xaf7ae918,0xda481a9e),LL(0x7c909a18,0xfd5fd37c),LL(0x805fb7b7,0xa5ebb7bf),LL(0x165200b1,0xeac65687), + LL(0x7cef9b97,0x56302866),LL(0xae3ddb64,0x8f662dd6),LL(0x60c1aa98,0x90cb4e87),LL(0x986fb3bc,0x33f9fc60), LL(0x974593cd,0x76f41ecc),LL(0x6e0f01e8,0xb19501f9),LL(0x25760dd5,0x587d9035),LL(0x9391032e,0xa31c971c), + LL(0x95c9a84f,0x7650e3b1),LL(0x78c66087,0xbb83ea93),LL(0xdfcf1365,0xda08a04c),LL(0xca0b84a4,0xd23daeba), LL(0x2ca3bd2b,0xf89d395d),LL(0x6e53fc93,0x779e2aaf),LL(0x34216082,0xc0fc7dc8),LL(0x42a66691,0x6cd8bdf6), + LL(0x0fe014cf,0x836a2cf3),LL(0x0c08373d,0xdde5fc22),LL(0xcb3b2b54,0xc4fa2387),LL(0xe2aa434a,0x96253732), LL(0x1d502ce8,0x4c4f5979),LL(0xb6df40c4,0xf046f5a9),LL(0xac6b75b5,0xc7d05765),LL(0xb69f3c34,0xae1cd887), + LL(0x49b86680,0xafed4be6),LL(0x14f70463,0x17b75fa5),LL(0x90b7c07f,0xb12e8051),LL(0x39a8e99d,0xe2c8cf2b), LL(0xd5fdb65b,0x984744c4),LL(0xa28942e4,0xd8b1c012),LL(0x46693fb2,0x295d0199),LL(0xa0a3b4fa,0x5ab3a305), + LL(0x26755b3f,0x3c191023),LL(0xb6c084de,0x75f35df1),LL(0x63e6286b,0x30640e66),LL(0xd2c6c059,0x3b3720ec), LL(0x6ea837be,0x2c821a0f),LL(0x84f23bd0,0x238c4d93),LL(0x390ea4f5,0xbdc40703),LL(0xae68a2db,0xcb207d0a), + LL(0xe25f098f,0x487d18bd),LL(0x9ab84e10,0x39018023),LL(0x8b7ab4a2,0xaa19aa62),LL(0x89f08fbd,0xcb9cdebe), LL(0x2ca57917,0x26a4c9eb),LL(0xda92ce1b,0xaadfd472),LL(0xdaa907db,0x32b592d8),LL(0x7d6f995e,0x9bbebacc), + LL(0xe1d88c25,0xa27a4735),LL(0x9bd66b67,0x339905e1),LL(0x62af9942,0xa9bfa0ed),LL(0x2e2cb83c,0xd94dd9e0), LL(0xab28e268,0x279d8fda),LL(0x51a97518,0xf28ab69b),LL(0x9691f33e,0xce9bd2ea),LL(0x74be3d64,0xb9e8b2fe), + LL(0xabefa07d,0x35072fab),LL(0x7b51ba8e,0x1c2ba05c),LL(0xd32d6bf5,0x3bb1ec56),LL(0x5d7bd7dc,0x326bdfdc), LL(0xd95bdcb1,0x33f4f4f6),LL(0x453ef338,0x781bfd34),LL(0x1ef61a66,0x4d210cad),LL(0x2799bcc7,0x6ae7bb14), + LL(0x194f4d6a,0xb105e5ec),LL(0x52b77f08,0x204a5480),LL(0xa328ab98,0x13f4e022),LL(0xb7f9a240,0xa56863c4), LL(0xce4cf7bd,0x2780c9a7),LL(0xc497fdf3,0xf98e3f58),LL(0xf52738fc,0x635b8bc6),LL(0x58937500,0xc5fd89b8), + LL(0x75e98a64,0x57070428),LL(0x946f094b,0x66aabaae),LL(0x06d37944,0x7d2376e8),LL(0x09319f13,0x9b316827), LL(0xa77eb79b,0xbbde59a8),LL(0xf451fde0,0xb7f35bbb),LL(0x64aa79fd,0xb2f7914e),LL(0x9f68a486,0x4d2944b3), + LL(0xc1a7e537,0xbd8a92de),LL(0x4fc930a3,0x76695e9a),LL(0xbcb4153b,0x1b75f9eb),LL(0xf6485404,0xf5a34d2d), LL(0x26853a8e,0xe09ee965),LL(0x9dbb319a,0x63de8595),LL(0xda079d6d,0xbbbc1b07),LL(0xdfa71b9d,0x5956bb3d), + LL(0x209cbcc3,0x69709306),LL(0xe3360429,0xbe2a08d0),LL(0x92a58752,0xd377a9fe),LL(0x997bc322,0x37e175ea), LL(0x042ff2e4,0xfe355d4d),LL(0x4c4babd3,0x4332ef31),LL(0x2314b1af,0x634429c2),LL(0x91a7d5e5,0xae6e8275), + LL(0x250a1476,0x134a39c7),LL(0x08994f0c,0xec9bb642),LL(0xd38704cd,0x2a9e0ac0),LL(0x536a4ad0,0x16490507), LL(0x7c8dbfeb,0xc7f747d2),LL(0xc0bb24ac,0x91e67dd2),LL(0x959eca45,0x2dfc6c8a),LL(0xc54fefe8,0x78bafaf0), + LL(0x5da056f3,0xf3eb2d1b),LL(0x3b89c967,0xda14b631),LL(0xcb51f621,0x80923b1c),LL(0x6609791c,0xc3d5fd1f), LL(0x817b1063,0x68ad7bef),LL(0xa1f0b00c,0x3775b686),LL(0x6c7f0dc1,0xb207c9a5),LL(0xa9b91fff,0xb7c30a7d), + LL(0x8b9f8e8c,0x9274c090),LL(0x24e94ce1,0xa3757610),LL(0x4f0f3ec1,0x8f2b1f2c),LL(0x3938d26f,0x02e53bb2), LL(0x701e5ae8,0x90a3da2c),LL(0xa271dcca,0x60c2eaca),LL(0x31fb2372,0xc9c08e39),LL(0xb838908a,0xcaa3245e), + LL(0xa6a6a275,0x2e168b0b),LL(0x0030ef6b,0x986a30a3),LL(0x170ab683,0x79f768f9),LL(0xff70981e,0x7296fd6f), LL(0x13a323cd,0xbab6fedf),LL(0x186e9813,0xa86ec0dd),LL(0xcd56e7d5,0xd9f8db04),LL(0xaa8b1c96,0x47b20676), + LL(0xf1fb3b03,0xdff4574e),LL(0x1051f9fc,0x41a1f765),LL(0x7f289a4e,0x35779aee),LL(0x11c96180,0x93bd54c9), LL(0x37b95c67,0x1485074a),LL(0x0865b2f0,0x0b01af95),LL(0x90ce0b41,0x43033ffe),LL(0x71504d6f,0xffd6e34c), + LL(0x1aa946c8,0xb380cd60),LL(0x806b2e19,0x7f7cc73b),LL(0x2db88e6d,0xc17df7d8),LL(0x072e5416,0x7b767ca2), LL(0x0ad6134b,0xbb42d3ed),LL(0x640df8af,0x5444339f),LL(0x5bc73112,0x7e7c7e7b),LL(0xf899dba4,0xe8f139b4), + LL(0x43a06bf3,0xd13b436d),LL(0x773e4863,0xe43f8567),LL(0x56b814d7,0x35555cd5),LL(0xd429ccc8,0x54af8e53), LL(0x82ae0477,0xc346718f),LL(0xbe02c7a8,0x301fb382),LL(0xd2a70595,0xcd65b3b2),LL(0x5aad01d6,0xcfcff499), + LL(0x589feca8,0xd0fcc076),LL(0x7c603ed8,0x7b2b93c7),LL(0x6ddfc3b8,0x2dda7a8c),LL(0x74723d99,0x678d66e9), LL(0x6db60b07,0x0f7e4215),LL(0xc0bfa2f9,0x40666848),LL(0x8e116caf,0x70b46b5c),LL(0xfba46d90,0xbd753511), + LL(0x019d8279,0xe48374cd),LL(0x309b0fc6,0x7d40e6e2),LL(0x9dec7a42,0x226435ee),LL(0x4243e7d0,0x818e79cb), LL(0x54658634,0x3d7376d7),LL(0x9f8727ac,0xa40cafeb),LL(0x81f556bc,0xdc1d09f0),LL(0x63223573,0x32ca7367), + LL(0x5810a27d,0x92e10f91),LL(0x1fdf969f,0x6fb34bad),LL(0x657a067e,0xe5c2b2ff),LL(0x382ba37a,0x173c0900), LL(0x86d87c1e,0xdd5113c8),LL(0xcaf77294,0x56a2ca9d),LL(0x666a9821,0x9f956881),LL(0xa3b18c0f,0xc4bcafc7), + LL(0x2b02578b,0xb100f338),LL(0x64b2c607,0x4716339e),LL(0x5b161179,0x92c923ae),LL(0x0df442a0,0xada2e4da), LL(0x47f85474,0x4d4b90c5),LL(0x824e3195,0xa378bf79),LL(0x2478a0d4,0x4469339d),LL(0x0c1e69e2,0x0972e788), + LL(0x72edc384,0x1aedd761),LL(0x9898d672,0xcabcd976),LL(0xba814ca2,0xd370aa7a),LL(0xe88eca9c,0x20fa58db), LL(0x45a7ab8d,0x1540ada9),LL(0xbdca94fc,0x8dcf9860),LL(0xaa9df4f4,0xf0187e2c),LL(0x54a49576,0x9a197dc3), + LL(0xb4a1f341,0xb54f5cb2),LL(0xfe32827b,0x1439caf0),LL(0xd36783f5,0x3c1a356d),LL(0xc56a6e47,0x284e2f15), LL(0x4dcfaddf,0xc6abad59),LL(0x082bb2b4,0xe82993f7),LL(0x23655955,0x3cb46972),LL(0x992551e3,0x8ab06385), + LL(0xdaa13ab3,0xcbd6cb99),LL(0x2dc1333d,0x01375bbd),LL(0x972c4440,0x638a7f20),LL(0x24dcb1cc,0x150665c6), LL(0x1ea989c6,0x4044e12f),LL(0x61012ea3,0x204c4eba),LL(0xac2719c1,0x78b8edaa),LL(0x2ab50d99,0x6772643d), + LL(0x606d63de,0x94604146),LL(0x693aadc8,0xa876d9b0),LL(0x667044ff,0xf7401ffb),LL(0xb599ecb4,0xab98d73e), LL(0xda5cbee3,0xe2b2048f),LL(0xa2b3da50,0x526e3aa1),LL(0xb4ad2073,0x4d0885e3),LL(0x644a1a19,0x916ce3d2), + LL(0x96930e8d,0x952b5747),LL(0xb0cf7f5f,0x2a489fd6),LL(0xa8b3b538,0xbff4b59b),LL(0x6aff1cbe,0xba0e03ff), LL(0xd56b2285,0xfa614adc),LL(0x50d58e62,0x2305edd4),LL(0xe36877e9,0xb349fdce),LL(0x43a6103b,0x5f808fc2), + LL(0x86493abe,0x66d8404b),LL(0x9b08ff7d,0x18c92d3d),LL(0x89754762,0x6a60ab6b),LL(0x8233dee7,0xec69fd4c), LL(0x06beadfa,0x32449242),LL(0xe0df7084,0x421caf1e),LL(0xd7969339,0x6f89693b),LL(0xfa30a7a9,0xb9a53713), + LL(0x11556d9a,0xf89d9bf5),LL(0xee8cf993,0xe4e9c5f0),LL(0x17ed9a7e,0xe5b2a323),LL(0x93e80c9e,0xd4db3920), LL(0x1fda3726,0xae857864),LL(0xa3e88485,0xe5cb36a3),LL(0xf495b9a8,0xa6b85205),LL(0x38f3b180,0xc1be0108), + LL(0x36a1f3a8,0x79d0585b),LL(0x913ba5f2,0xa3d8f17f),LL(0x225acf11,0x1eaee5d6),LL(0x0d32de79,0xd4dfd0a2), LL(0x6b3ceff3,0x0cec324b),LL(0xab447870,0x3acc6dec),LL(0xb9c759ac,0xabbf7e6d),LL(0xa5196938,0x0d5c1f47), +}, +/* digit=28 base_pwr=2^196 */ +{ + LL(0x45e7ea91,0x781a2157),LL(0xacadfc40,0x4da3f86d),LL(0x162cd393,0xc81d6c7d),LL(0xad6e60fc,0x2c38a2a1), LL(0xf753479d,0x575b25d6),LL(0xbdec6025,0xc914e08e),LL(0x492d5547,0xf81cea34),LL(0xfb1b6969,0x6bbb8bb1), + LL(0x1279504c,0x1ee8082c),LL(0x2c92ffb7,0xa466abb2),LL(0x3e81c7e2,0x4118b26a),LL(0xfc60e33a,0x1a76cc50), LL(0x5736d7ae,0x34998bc2),LL(0xbd1ef993,0x20b39558),LL(0x5fbf2525,0xd669e2ae),LL(0x01cc7626,0xbf956ec6), + LL(0xb0ccbaa5,0xce817029),LL(0x279b78a6,0x57ef5bd2),LL(0x4df45d89,0xc9283747),LL(0x2ec4bfd3,0xe86b91a8), LL(0xfe565915,0xe5ab4c6d),LL(0x7c58a042,0xe6574716),LL(0x6301c4bc,0xe141deda),LL(0x8084513a,0x2f95d561), + LL(0xeecede3d,0xdc424508),LL(0x386440d0,0x11889b35),LL(0x98de0d77,0x7b229f93),LL(0x300a7447,0x73fced8a), LL(0xe31c8f88,0xf75e1c79),LL(0xbb277e4f,0x8db20bdd),LL(0x2b87c02c,0x8ded0a70),LL(0x4d164c1a,0x166281b5), + LL(0xeedd8e0c,0x887356cf),LL(0xe44c012b,0x8afab37f),LL(0xe4aa3eb6,0x0795935f),LL(0xda6dfa57,0x9b9efc0c), LL(0xa8ab0840,0x0ff0f8aa),LL(0xc8561605,0x0f3a4b63),LL(0xd5db9315,0x2ca911ef),LL(0xc8ded9f8,0xef70e5ba), + LL(0xa6aae58b,0x443d9209),LL(0x274edda3,0x3d0798e8),LL(0xc2be3c9a,0x5c2d462c),LL(0x439882dc,0xb5488239), LL(0x977d4de4,0x6391bb41),LL(0x1e8245c4,0x7fd91040),LL(0x3b093dc2,0x1a6d3c71),LL(0x7b22fe12,0x423a4e3a), + LL(0x3a9a04a3,0xe3156f40),LL(0x297d9aff,0x9b32c4e5),LL(0x62a89850,0x7e0b401e),LL(0xa84ef082,0xffbf542e), LL(0xf990caf5,0x377cc0e0),LL(0xec88ea9b,0x02704343),LL(0x63f96a51,0x846fd46c),LL(0xe9855c47,0x37f5cebf), + LL(0xe6ad29dc,0xbd140bd8),LL(0x6a04da28,0x7dca4b10),LL(0xade05b33,0xa84feafc),LL(0x7630aacf,0x44d031f8), LL(0xcdee269c,0x18af2fa6),LL(0x8697a40b,0x1e40571b),LL(0xf0e5f826,0xf71d44ad),LL(0xa434cfe6,0x2a47ddf9), + LL(0xad17cc54,0x22b97078),LL(0xf2c105b2,0x223732dc),LL(0xe284fae8,0x25168336),LL(0xb356407b,0x41b1bb94), LL(0x89933a11,0x299e7d7a),LL(0xff7dd9f6,0x19e13d3c),LL(0xf23d7ca7,0x9517bd16),LL(0x1eb978a4,0x9e5e9e34), + LL(0x5fa3f92f,0x4c222dae),LL(0xed489ca7,0xd5e38e84),LL(0x70ea613d,0x3d81aca4),LL(0xbe4e88f6,0xc7bed301), LL(0x0757d8db,0x6fd5a7bf),LL(0x7a9181b0,0x1472441d),LL(0x5a90b66f,0x78b78753),LL(0xabdae620,0xe3fd5e91), + LL(0x84535653,0xea6a77d8),LL(0x81d7e667,0x8d241deb),LL(0xfaf4ef1b,0x1af73798),LL(0x3e0dae27,0x5e1ae728), LL(0x2f7450b5,0x6a67088c),LL(0xda9cb3c6,0x7bccbe06),LL(0x5b808e05,0x520fabab),LL(0x702b247b,0x84222f68), + LL(0xe0bd7ef2,0x2471546a),LL(0x656a62a3,0x27d310dc),LL(0xad35da30,0xb8014eca),LL(0x7f35cd7a,0xbdfdcd82), LL(0x040ae645,0xf1e4d51f),LL(0xf42a4d9b,0x672ffadf),LL(0x2d0be1c0,0x9d874370),LL(0xc6e55471,0xcc3671c6), + LL(0xbb9c9667,0x39aa705c),LL(0xc51f661d,0x8c3e584a),LL(0xe570769c,0xe5645b1d),LL(0xbc97abf4,0x81923fda), LL(0x0caac97c,0x51d64f64),LL(0xff847f4a,0x45c17651),LL(0x8cbfa2c7,0xc7a6eaf9),LL(0xba8ab893,0x6c2ab9f7), + LL(0xf435624e,0xbdaa2c7b),LL(0x1d961058,0xc113e971),LL(0xa2021a1c,0xb230f1b0),LL(0x521a4816,0x6b34e1ff), LL(0x9b874f4d,0x159dc24d),LL(0xbeaab169,0xeaa0f951),LL(0xb56f4916,0x4f38733f),LL(0xdc9d3ac7,0x4ee689db), + LL(0x7bf8d03b,0x720254bb),LL(0xd31d7679,0x78b0e6d6),LL(0xf130d7b0,0x848fb878),LL(0xd3ba625a,0xe8e478ec), LL(0x100dfefb,0xb0ce9168),LL(0xe5098aa8,0xfe1463ab),LL(0xa11ec558,0xf780ac38),LL(0x8e474b9f,0x92f15c52), + LL(0x46410cb1,0x3b3892d3),LL(0x03a5a136,0x72097f22),LL(0x98de068d,0xdb3a1b80),LL(0x4b1a3890,0xfb7438e4), LL(0x3839d3d9,0x8a10d5ea),LL(0xf4bd8126,0xd9ad034d),LL(0xd4800261,0x07d108ef),LL(0x9c5d6c52,0x978d98ba), + LL(0xecb9ce1c,0x63ae69e1),LL(0x51b28f39,0x70d2b437),LL(0x77f848a2,0xc15696b6),LL(0xd8ab4d76,0x6b6e60f4), LL(0x030bf112,0x33a581a4),LL(0xc5e74a76,0x9cdb1a6e),LL(0x7a950053,0x6c6f6ec4),LL(0xb04ebcff,0xd47dc472), + LL(0x5e0970df,0xe85ca76a),LL(0x78988af2,0x74448d98),LL(0x81620019,0x5227649b),LL(0xaabc2027,0x47e2ac62), LL(0xfbffedf2,0xfea15155),LL(0x3b4cb501,0xa565c484),LL(0xd830cece,0x4c523be5),LL(0xc321a440,0x2e2de6bc), + LL(0x8d69887d,0xa7d62771),LL(0x4e138de4,0xf9d8ac67),LL(0x9fcb0a09,0xad3fbc08),LL(0xbfc3bc9a,0xcaabb0b0), LL(0xb1c20604,0x84646bc3),LL(0xd1574260,0xf1059ac4),LL(0xeefff298,0x5c15c6a2),LL(0xf3b0a393,0x7975ede6), + LL(0x27c2343a,0x0ea9d355),LL(0x4b32e339,0xe21c75e4),LL(0xa7fc353a,0x1438785e),LL(0xe9a1dd56,0x0b8d64ba), LL(0x75347c02,0xcacf9b64),LL(0xcaad57aa,0xf788c83e),LL(0x36ecf2e0,0x90df1ab8),LL(0xf45070ac,0x4db604a3), + LL(0xb4c4ed93,0xbc76e168),LL(0x85b65a6c,0x07177b5e),LL(0x00d21309,0x41e3c275),LL(0x76a48f42,0xcc9678e4), LL(0xb1c6256f,0x3a04d197),LL(0xb2cc7330,0x940920a9),LL(0x2523d52f,0x990e4da8),LL(0x5a59d733,0x34709b24), + LL(0x8e745028,0x2f0da81c),LL(0xcd5668ab,0x32b5f384),LL(0xee538e7e,0x82744a5a),LL(0xf3eb2516,0x1b019bab), LL(0xd79d735f,0xccbd28fb),LL(0x85f90aa2,0x0bb54a6e),LL(0x9a69ecaf,0xacf5552f),LL(0xd1f1e30b,0xbc51ee85), + LL(0xfa25193d,0x12bf8b0b),LL(0x5ba4b3c8,0x3f0f51b0),LL(0x66181f23,0xc1b65deb),LL(0xc0156b03,0xfeb037f9), LL(0xa9dc59ed,0xdd7a0a8c),LL(0x7b57e018,0x20b5c8ea),LL(0xefaadad5,0x0c3ebc94),LL(0x18758eba,0x146d05b6), + LL(0x09c7b43c,0xcb952e41),LL(0x1c1b8fb6,0x7f7a0ae3),LL(0x331dfb05,0xbca8a9cf),LL(0xe0db9d7d,0x4a1db4a1), LL(0xe5b9c892,0x988d36a3),LL(0x010ad00e,0x64640e55),LL(0xc011bffd,0x4c33c7e8),LL(0xa0ad217b,0x5d7cf370), + LL(0x71f3df52,0xbaf8b74a),LL(0xa5995b20,0x300963bc),LL(0xd6c27636,0x695cf7ee),LL(0x03ac244e,0x74d4d3a1), LL(0xc898e5bb,0xddba3bd6),LL(0xfe3499f7,0x27573a89),LL(0x4b0a6c98,0x666b4415),LL(0xaa4ccfaa,0xf4f3e8c5), + LL(0x1a5b919b,0x5f136875),LL(0x670d4b04,0xed8eb5db),LL(0x0d0d73bf,0x4cd83d19),LL(0xbdf22579,0xd2a5c62a), LL(0xc2d04c2b,0x8c41be16),LL(0xbf9ad465,0x5aa33bc4),LL(0x5e00d922,0x36e20646),LL(0x00b70e17,0x9df21e7c), + LL(0xd440af4d,0x0601e630),LL(0x963e87dc,0x4aab0d33),LL(0x36d39000,0x2712abdb),LL(0xf9147e2a,0x856d7e3b), LL(0xc8e5d2f4,0xadc4a96a),LL(0x2e70c206,0xac3e5336),LL(0x6f6f3d0e,0x1ee7d838),LL(0xead72426,0x4674ef20), + LL(0x6af5f580,0x3a804dd8),LL(0xd74ea5ce,0x724a756b),LL(0x0432d854,0x0c2968d0),LL(0xa4f262fe,0xe3be03f3), LL(0xc84c22bb,0xe446692a),LL(0x9647650d,0x156b3168),LL(0xb5d3d62a,0x4e06bc39),LL(0x80eea174,0xf99d4fec), + LL(0xc08f1144,0x3a2b7ae8),LL(0x12dae8d6,0x35e65bf9),LL(0xae3892b5,0xfa0af1cf),LL(0xac408112,0xa57062dc), LL(0x24bf1af9,0xef6a9ec3),LL(0x5decd8bc,0xdda3b476),LL(0x7bed3775,0x9314a36c),LL(0x60aa296e,0x9e254b0e), + LL(0x65b9cf2c,0x8be2de80),LL(0xcb3b96cf,0x1b110df6),LL(0x18957e21,0x0f647a12),LL(0x4f907766,0xa1e11238), LL(0xc5528977,0x751a0d82),LL(0x9a4b1260,0x958d8738),LL(0x773658ee,0x99087543),LL(0xf19f74cf,0x18148bbe), + LL(0x0a19a374,0x5f50ef19),LL(0x6bdd3392,0xc5bc4160),LL(0xb80ad74c,0x1bdf5e4b),LL(0xed7e68c8,0xc40ec2f7), LL(0xdecef5b8,0xedd7dd6a),LL(0x896c95a3,0x3d29a1cb),LL(0x70ad41d4,0xfa84c325),LL(0xc398c177,0x6a577072), + LL(0x7375f2de,0x4f942d01),LL(0x8aa1523a,0x968a7608),LL(0x377e5c4c,0x55dc7da6),LL(0x282b540e,0xb75fff53), LL(0xfd4b6951,0xfee35c15),LL(0xf04ddfae,0x6d1d64f6),LL(0xaf7c8714,0x320f1769),LL(0x482ba6fd,0x2b5f86a4), + LL(0x1ab9986b,0xcf691cb7),LL(0x7377ba6b,0x42913d71),LL(0x1e47bf08,0x120b4601),LL(0x764b2661,0xfb514e52), LL(0xa140ae04,0x371c0155),LL(0x2e186763,0x94e65b70),LL(0xd5764306,0x5e440f7b),LL(0x7b8a5eeb,0x3411dadf), + LL(0xf0e3e158,0x6c25e519),LL(0xe8898c80,0x46ee66d6),LL(0xec4f9b03,0xa0e9d4b1),LL(0x126c1f31,0xba48d97c), LL(0xbdbf0928,0xb9f96818),LL(0x7f51cb48,0x293ce87d),LL(0x76f09d38,0x077a7420),LL(0xedea4c81,0xc71cb875), + LL(0x9ddd1485,0xfeda750d),LL(0x51c10504,0x987876dc),LL(0x75ec7922,0x4d0253f8),LL(0xc676b336,0xbcc15e39), LL(0xb9370740,0x33d533d8),LL(0xcb8c88ab,0xc5c482db),LL(0xc7c08a75,0x1ff3f223),LL(0x401b00fd,0xccfaf564), + LL(0x6ac9757c,0x6ba93d3a),LL(0xec2c92a0,0xff09b546),LL(0xc5960be8,0x95d3436c),LL(0x69029082,0x90b7e8cb), LL(0xdb6b32e5,0xbdd1e2b9),LL(0xfd47ad85,0xf4d2e43b),LL(0xcb005dbe,0x8923251e),LL(0x662912e7,0xc21368a0), + LL(0x062d205c,0xc7ce2963),LL(0x9542b831,0x1e8f812f),LL(0x818c322d,0x4f8a7915),LL(0xfb678809,0x50073cba), LL(0x0cb91b3e,0xed7b5237),LL(0x60d3fe6b,0x22d1fa41),LL(0x2d690f75,0x3de39063),LL(0xf164ec1f,0x12b2e39e), + LL(0x332f408f,0xa28a0d83),LL(0x6a054db1,0xe6d9406c),LL(0x5ddd64e0,0x67369b76),LL(0x02b21c2d,0x6d671707), LL(0xac42170f,0xb9ad3368),LL(0xe5802ffa,0x5e8f5277),LL(0xd9b4a0a9,0x1b4468fb),LL(0x96c24331,0x0daf8269), + LL(0xc09ad26d,0x976c2f23),LL(0x19c68d38,0xd47afe88),LL(0xd3d8d84f,0x0e96c03b),LL(0x0932b2fe,0xe05b5fd8), LL(0x347fbbbd,0x13931043),LL(0xb0ccc752,0xe0fa842f),LL(0xc75bf745,0x7295ee0f),LL(0xb0aa9d61,0xebaae0dc), + LL(0x6355564c,0xb392d49b),LL(0x887c5a18,0x57e2f166),LL(0x230a278a,0x88b3a014),LL(0x4c194449,0x088e4908), LL(0x43d6af69,0xc6cd309f),LL(0x589a7f7e,0x394445e3),LL(0x031e7c08,0x0610077a),LL(0xa3519f78,0xd05547cc), + LL(0x926e26ed,0x0123b543),LL(0x62d06da6,0xcd430b80),LL(0x0dcd6db5,0xddb182d0),LL(0x8eb6e010,0x724c9bce), LL(0x50a4a597,0x985a2f0f),LL(0x900f2a49,0x35f2427f),LL(0x13cbf187,0xce6136fe),LL(0x1086c2aa,0xc893bdee), + LL(0x07eca624,0xe2410ccb),LL(0xddf9afb0,0xeda92913),LL(0x5bb66033,0x8fc0cfd0),LL(0x0509ffc8,0x0ab7d29b), LL(0xb3d4f10a,0xc063b004),LL(0xeb8cf642,0xed94a955),LL(0xa272ac4d,0xacfb2f14),LL(0xc4ebbf0b,0x10f2c91a), + LL(0x06ea04eb,0x73f6e02e),LL(0x8b97ea93,0xb969e8f8),LL(0x0cd48657,0xa9b27472),LL(0x99264937,0xe1a874ec), LL(0xf794332d,0x34e677a4),LL(0x5ee2daea,0x5e67865e),LL(0xe6886879,0x3fe02b91),LL(0x0f9776ad,0xe113432f), + LL(0x6a2c47d1,0x37567306),LL(0x62feb54a,0xf66df9b8),LL(0x3e07ce56,0xf734ee37),LL(0x659809fd,0x50c4982d), LL(0x9daf8faa,0xe2fa768f),LL(0x8b9fd7c3,0x66088ddc),LL(0x333683c6,0xb8265661),LL(0xdff2a0a7,0xe7dacf81), + LL(0x5e3da06c,0x1e99d6bd),LL(0xbae05a25,0xbd50e15c),LL(0x802d7b40,0x47a0d997),LL(0x193ef621,0x0a25b51b), LL(0x148ee5a3,0x24d3d4f4),LL(0x022a9df0,0x7012618f),LL(0xf68e648f,0xb3777339),LL(0xd7544352,0xcdfb557f), + LL(0x1f912c5f,0x4b0b2d46),LL(0x957515d9,0xddaf929a),LL(0x0ae46856,0x29e4bf1f),LL(0x44e32ab0,0x158b4c85), LL(0x7c48d2d2,0x17935398),LL(0x6f2430bc,0xe4ab6300),LL(0x0d8b24d4,0x71dd7284),LL(0xfc21d7e4,0xd9303af1), + LL(0x450f7f6d,0x816c616f),LL(0x3306df19,0x17875d8e),LL(0x087e86e0,0x7ce8d4a5),LL(0x36251f01,0xa53970ac), LL(0xfc98edaf,0x2037f12c),LL(0xabf72b6f,0xc359a382),LL(0x85130fa6,0x06acf1a6),LL(0xadfe4344,0x08f45064), + LL(0xdd857b31,0xc01e1f3b),LL(0xc9513734,0x92c2263a),LL(0x589327b8,0x562652d5),LL(0x96a1c164,0xa8edd065), LL(0x79f8df8d,0x2cbf8f98),LL(0x40847dde,0x3d5cf771),LL(0x597c0622,0x69b08ee4),LL(0x8a868f2a,0xfff18c4d), + LL(0xf5ad0686,0x28bca3d2),LL(0x2d4eef7b,0xf7992f89),LL(0x3977e15d,0xab10b9cc),LL(0x2db8ef03,0x47912ca1), LL(0xdf27884b,0x1f3e70e6),LL(0x0e9d8efa,0xdd9bb81e),LL(0x279e27f6,0x97a83b6f),LL(0x24daf922,0x47e259fb), + LL(0x124e71be,0x49eb72bc),LL(0x3a6778ba,0x01dba001),LL(0x3be03050,0x8d02baec),LL(0x6dd6c8ef,0xe3571b3c), LL(0x2cc11ffe,0x6e1ffbac),LL(0xf4e2e6f0,0x6d725c75),LL(0xf2b53a58,0x96c31b45),LL(0x97f1634b,0xa0e38dd7), + LL(0x143ce001,0xe8507959),LL(0x8b49cc63,0xad9a9f52),LL(0x8438b0fa,0x950fd33d),LL(0xbe0cbdf6,0x2b294c00), LL(0x937b00ce,0xb2076b47),LL(0x78041498,0x026153a1),LL(0xe9e53d27,0xe958f12d),LL(0xe8f8fad9,0xf49e1124), + LL(0x2bca0ae1,0xb78a5b74),LL(0xcccdc3d3,0x35180dec),LL(0xa97e519f,0x15e4fba5),LL(0xf5b8340e,0xe49dac9d), LL(0xe5978024,0xdbd8ed3a),LL(0xeb105505,0xd181f26a),LL(0x29f57098,0x38364818),LL(0x3900171a,0xd674fe1f), + LL(0xf1bd5803,0x5a2ff729),LL(0xeda23387,0x53de7261),LL(0xf0dc417c,0x7f1d84c8),LL(0x5360fa80,0xa65694a7), LL(0x96ed36e6,0x356e4518),LL(0x406bfd36,0x127a52de),LL(0xde925d04,0xb575a98e),LL(0xc0627c4f,0x35fb44be), + LL(0x471e745a,0xc85f2c69),LL(0x6213d79e,0x1c01e1ea),LL(0x2f5081f0,0x95ea99a1),LL(0xc3367864,0xdb38bd3e), LL(0xd8880436,0x0e8cafec),LL(0xf9c63d09,0x1d59fd74),LL(0x7f875dbb,0xe57b0b4f),LL(0x77084bd7,0xe266c939), + LL(0x2fc1f909,0x0e289c5a),LL(0x86c4fc40,0xece9d225),LL(0x5d79b4b3,0xe0a56fbe),LL(0xd4489041,0x2b96fae7), LL(0xe23c85e7,0x0f66316b),LL(0xadfef0c2,0x2d1a3c78),LL(0x9fbce9cd,0x1aece4ad),LL(0x6c32d32d,0xccd0f334), + LL(0xfb9ba6dd,0x958d7a5c),LL(0xe673275d,0xa0052032),LL(0x7f978d07,0x514ffd9d),LL(0x450b76e1,0x544bbce9), LL(0x6b5201b6,0xeaa25d74),LL(0x74d082a5,0x7528a4ea),LL(0x66609e27,0xa08c8d31),LL(0xda7c6fd9,0x5150d1be), + LL(0x39930618,0x864f5b4c),LL(0xcebb516e,0xe71e7f1a),LL(0xebf1f8ac,0xaeee7fa5),LL(0x0ea827c6,0x6efcad4a), LL(0x74e21dd8,0x6e0f4ecb),LL(0xf33a7939,0xc5311600),LL(0xa4d93fc4,0xdf62f3c3),LL(0x9a18476d,0xd3b62727), + LL(0xc0e1256b,0x0b54f5e6),LL(0x97ba9afa,0xe8987efb),LL(0x41d11c15,0x4b6ea064),LL(0x79b79f0f,0xfed7017e), LL(0x5bd04e40,0x5a6bcf9e),LL(0x8fd3b4bd,0xf3090153),LL(0x82240648,0xa23b5acb),LL(0xb16cf033,0x61d9a8b1), + LL(0xc9fbee1e,0x2feb1706),LL(0xd7e07918,0xfaa4cd69),LL(0x447cba7a,0x28562c58),LL(0xa61a1064,0x727926c4), LL(0x97ac7eff,0x1b32db7f),LL(0x452253ce,0xfd968b22),LL(0x5cdd3217,0x69d1842f),LL(0x26f4007d,0xba7689da), + LL(0x141c8b35,0x16445a64),LL(0x73c61779,0xc11c3101),LL(0x485300ee,0xa5aa0d18),LL(0x1cc02bf0,0x531b6de1), LL(0xc4efeb2c,0xf8b94155),LL(0xd015a9c8,0x83632663),LL(0xcba18b7f,0xc369b3ce),LL(0xc29e0f9b,0xe11b3ef6), + LL(0x903ca95b,0x1a5e9bf2),LL(0xa50cb332,0x2d9aefc6),LL(0xb29ce693,0xb5670264),LL(0xab1d7b7e,0x806d08ac), LL(0xc9107eac,0xcbdfdf28),LL(0x6cdf12ac,0xa8086243),LL(0x903d5999,0xe7d9c315),LL(0xc079d951,0x4379820b), + LL(0xbf1edf4c,0xe789ecad),LL(0x47bc7752,0xec086811),LL(0xc2fc8798,0xeea2eeb8),LL(0xe031a96b,0x763183e0), LL(0xf9a6bfaf,0xc7daf0b2),LL(0x4b957cf7,0x1a2a7ffb),LL(0xbf2d2e7d,0xa483c7c8),LL(0x58ff7f9c,0xf96921fc), + LL(0x574ee010,0x41386185),LL(0x2780c649,0x62e6a1d8),LL(0x60f2516e,0xdec553af),LL(0x7a04eb11,0x5b091537), LL(0x67eb90c5,0x1b53e9dd),LL(0xddfda333,0xc390a23a),LL(0x480568aa,0xdd4e7c6d),LL(0x59ccbe61,0xd6c1e8a8), + LL(0x9107901b,0x1c6fd7a9),LL(0xa211d116,0x5dc4a41e),LL(0xaf1b78a8,0x597e94e7),LL(0x53afcb6a,0xe72da34d), LL(0x74512c24,0xbc364db7),LL(0xb2811e91,0xc26a8fb9),LL(0x290469b1,0xfdd39d7f),LL(0x20612535,0x84515392), +}, +/* digit=29 base_pwr=2^203 */ +{ + LL(0x1539cf31,0x7fe996a0),LL(0x0ded7c6e,0x4a3f729a),LL(0x3016f614,0x86f1f299),LL(0x86cb9163,0xc3d44e18), LL(0x558fa36c,0x96984531),LL(0x369c89d6,0x58e8bf05),LL(0xf9ee923f,0x287da114),LL(0xec271fbc,0x2032e984), + LL(0xd39207ad,0x91b8579d),LL(0x0b1fe916,0x6f62c725),LL(0xd89e01bf,0x0f1599ac),LL(0x4d1e5843,0x8d9bb86d), LL(0x726e38d1,0x348b90d4),LL(0x52a8c6b9,0xb824a1ca),LL(0xb1d2f6f4,0x984d9309),LL(0x431ec12e,0xefa485b7), + LL(0x9d616a5c,0x24cafa66),LL(0x4c9d0ea8,0xc1c7445f),LL(0x90bee7b6,0xf733e085),LL(0xd251d2ba,0xa2f3ece3), LL(0x66aeba6c,0x6e422a45),LL(0x37c1337f,0x35e99b16),LL(0x6d4f8d03,0x52d0fdf7),LL(0x79c92672,0xa043420c), + LL(0x76ac1925,0x99725607),LL(0x3442fc58,0x086449db),LL(0x2e311e74,0x8dbab920),LL(0x7ea25561,0x29dee69b), LL(0x19a7cd6c,0x5a62b6ee),LL(0x0d0dd5a0,0xba38cc4c),LL(0x166d0ff1,0x779279e5),LL(0xf48b3dae,0x0eef53cc), + LL(0x0f82c6a6,0x0463dcaa),LL(0x11d7d6d8,0x75dfc96d),LL(0x6c100d92,0x61f05e7b),LL(0xe13eabb4,0xa118e548), LL(0xdcdf06b5,0xcc77e3c8),LL(0x6ac25960,0x902d37d6),LL(0x347d7116,0x967d9993),LL(0x9ae33561,0xd2828650), + LL(0x8c7c6d89,0x955b7840),LL(0x42c2555f,0xbfa78bc8),LL(0xa69c3165,0x8c56ae3d),LL(0xe33bb1bc,0x72b20e72), LL(0xd1aa6416,0x686870b4),LL(0x7db03cdd,0xf000040b),LL(0xb0a0fd40,0xd25b16a9),LL(0x36815f1f,0xeb89e932), + LL(0x349b549c,0xb3e5e912),LL(0x086c4e74,0x801f788e),LL(0x0082ae92,0xafb9ea4f),LL(0x0d740026,0x4e8f27a4), LL(0x05f4a6ac,0xc4f8285a),LL(0x0adcd58c,0xefea5297),LL(0xc52f8c21,0x9d5b6ae5),LL(0xe97af4dd,0x92622a7a), + LL(0x79f34a8a,0x39b43935),LL(0x30046435,0x61acf55f),LL(0x3f05fdb1,0xf0a23fe6),LL(0x0c4fa7ff,0x7d6baee1), LL(0xe2daf735,0x253f62b6),LL(0x2948637b,0xe370ead8),LL(0xd84e6206,0xda57c16a),LL(0x0dd22ad3,0xf19ffe09), + LL(0x95bf2003,0x701acab2),LL(0x9dff6efc,0x50e4e10a),LL(0x43b95430,0xe637bcf0),LL(0x85050cbc,0xac45cd3e), LL(0x80639e4d,0xc2ebff64),LL(0x3056f603,0xe5af1fb5),LL(0x08b17132,0x302791d5),LL(0xed517904,0x87775ac4), + LL(0x4263a566,0xfe64ed1e),LL(0x1d5e8f55,0x735bbee4),LL(0x8294342c,0x9ac61915),LL(0xd4904935,0x0f522e5a), LL(0x7c1e11f4,0x2ee883b5),LL(0xf0c237f4,0x0a2ce30f),LL(0x8d955086,0xf4a7157b),LL(0x022dc2db,0x7ec0462e), + LL(0xca391b0b,0x562fb75b),LL(0x3bb1efd6,0x13030aac),LL(0x347f44fe,0x305d9831),LL(0x94b2615b,0x9f70c1ad), LL(0x4162ff22,0xaaf935f4),LL(0xa68d160e,0x2b20f047),LL(0x39222d1b,0x30d52a97),LL(0x6551642f,0x051223b1), + LL(0x39620daa,0xae65a5c7),LL(0x6f7c078f,0x8ef6f93f),LL(0xb0177db8,0xb06d52bc),LL(0x68fdf535,0x915cdd08), LL(0xc5183222,0x0070d150),LL(0x7817a2ae,0x2b6495cd),LL(0x0b194f0b,0x3ce47614),LL(0x513bfdfb,0x2eec6acf), + LL(0xf3dbd34d,0x725dbede),LL(0x3621fc75,0x01c4412a),LL(0x3c07f048,0x17bd68de),LL(0x62e735eb,0x117df57e), LL(0xb249c407,0xb1596c6d),LL(0xd46c55c4,0xa878f56a),LL(0xb8aa0cb4,0x33385670),LL(0x800ec887,0xc7faa80e), + LL(0xd7daf836,0x2cd2814f),LL(0x0d616922,0x877b72b7),LL(0xdb066012,0xea73ca1b),LL(0xb0d4159d,0xbe336c7b), LL(0x0f8fcd76,0xb993b07f),LL(0x8a593562,0x5fdceaba),LL(0xf691ec19,0x716595fb),LL(0x8e68e3c0,0x51a77f61), + LL(0x7a7c18db,0xe9e4cdfe),LL(0x7b4f69b7,0x967d3575),LL(0xa9a434c1,0x6dd350a1),LL(0x00c79ba7,0xb92cdef9), LL(0xa6bb0f93,0x7a762493),LL(0x8158ad36,0x6c18cdc2),LL(0xc529ecfd,0xa0bd83e3),LL(0x3962f96d,0x98363c59), + LL(0x1d63aa7f,0xd80f45a5),LL(0xb3b32da2,0x8d5eba75),LL(0xa4708858,0x0ef233df),LL(0x52161c61,0x74c3f4f7), LL(0xe6420de4,0xfa9bfe6b),LL(0x97dd86d5,0x96c0c501),LL(0xcfce233b,0x28e6827b),LL(0x58e74d63,0x035cc9a9), + LL(0x7948782d,0x9ba64bf4),LL(0x80d9ce1a,0x5e5b7c72),LL(0xf51df862,0x7b9435db),LL(0xb4dd2421,0xe74ab6e8), LL(0x60954c75,0xb0d704db),LL(0x0b59ae5b,0xd31c5145),LL(0xd99ba307,0xe0ff4660),LL(0x986bd82b,0x1a3800fd), + LL(0x509a0a50,0xe7e06ab7),LL(0xe4539885,0xbdf63778),LL(0x16ddb433,0xf888320f),LL(0x18e18998,0x0f108304), LL(0xfa834b14,0x27e7ffd6),LL(0xc68b9434,0x16de9a71),LL(0x4d360436,0x53a12e2c),LL(0x5e110b02,0x5ad2c986), + LL(0x3cf53e0c,0x3439443c),LL(0x1d65a7a3,0xfeae29b0),LL(0x78ad7d78,0x1e7774f6),LL(0x6fee368c,0x0c79fb01), LL(0xe4faf3ee,0xbec71de1),LL(0x263868e8,0x1a88f3e5),LL(0x90e91a8c,0x975d8381),LL(0x0f999c60,0x69c5a65d), + LL(0x8b884857,0xbd3360d8),LL(0x31b7c579,0x04190413),LL(0x142cc145,0x40dd9229),LL(0xdad0b2df,0xb5faab94), LL(0x52df4831,0x3e7d7921),LL(0x228bf67d,0xcf5bd1ed),LL(0xc4980085,0xd8669635),LL(0x1c71903d,0x094b8973), + LL(0xc4abb028,0x493a7a3d),LL(0xb4ab8e35,0x0e1a8fac),LL(0x017aa5f2,0x26094ca2),LL(0x021476cb,0x94fcb8b1), LL(0x4abf3bcd,0x57f101f9),LL(0x2d7f12a8,0x1ac2c125),LL(0x2e42789c,0x575259d9),LL(0x22471eb3,0xa64a4a4b), + LL(0xe1c00144,0xcc02304d),LL(0x754734b2,0x6269dfb9),LL(0xf14fbc81,0x72e7a183),LL(0x2a05caa2,0xd92a5b1c), LL(0x15efc2fb,0xd593492e),LL(0xd8dd458b,0x1ace7dca),LL(0xaef2ae81,0x576b4bc8),LL(0x351b397e,0x6de6a2db), + LL(0x656cf9ab,0x73f13b48),LL(0xaee7e01d,0xc18df1c9),LL(0x560355e7,0x30fb5155),LL(0x9ad059d5,0xd2c9a0ee), LL(0x5e5e0c7c,0xd9f89936),LL(0xf0a6c9d7,0x5d0a2cbd),LL(0x58fa9be9,0x3c2c497d),LL(0x6ac61a2f,0xe6c6fcf2), + LL(0x35607bc4,0xf7ec89e3),LL(0x9946bf52,0x17ca00ca),LL(0x180c8bd8,0xee46be5b),LL(0xb2873893,0xd29d5eb0), LL(0x97487b3c,0x348ac939),LL(0xfeef78ce,0xc18f0ceb),LL(0xf797cce5,0xfc648dca),LL(0x442148d7,0xe2467e0c), + LL(0xda6dbaf6,0x8e201ee7),LL(0xabd0490c,0xc1a93ee4),LL(0x4de7c210,0xfd0007bf),LL(0x083ffce0,0x02eccb8b), LL(0x97844c8d,0xbba82bbb),LL(0x2747a430,0xb7ff954c),LL(0x18fb5f29,0xb05f0584),LL(0xee7c263f,0x35a29cf5), + LL(0x25282da8,0x5fd84efd),LL(0x7682db7c,0xc1fc84c1),LL(0x4bb291e6,0x8422b56a),LL(0x66a56078,0xce379feb), LL(0xe7f045a0,0x1c3c581e),LL(0x6b3f89ac,0x8f42985d),LL(0xa6b2ba59,0x112839e9),LL(0xc2a7b29a,0x3f0c7269), + LL(0x79bd3046,0xecdadb6f),LL(0x9617ff6e,0x669f559b),LL(0x68928ca9,0x242bb14d),LL(0xc19cafcc,0x28e2b0cb), LL(0x81330593,0xfb7d8954),LL(0x9fbf8665,0x5c3741fd),LL(0xc3b93e86,0xaf49e83a),LL(0x32822548,0xd60ecf7d), + LL(0x7cfb37cd,0x4bf36759),LL(0xdb7af2ed,0x94b0c7f0),LL(0xebf8b461,0x2f1bebf6),LL(0x073e5c18,0x90ebc9c7), LL(0x3774e905,0xe431c793),LL(0xe03265bb,0xb8a4bc2f),LL(0xfabb629e,0x0bee0825),LL(0x84557170,0xbd1481dc), + LL(0xe1a010a0,0xa2257b58),LL(0x4688bb89,0x43f5451c),LL(0x91b96371,0xb87a5ff0),LL(0xde3c7b25,0x445dd02f), LL(0x51a0964c,0x44c0c080),LL(0x9afdcefa,0xb0c3190e),LL(0x0044d258,0x14cc65ad),LL(0x374fdd44,0x8c500b3e), + LL(0x51b07812,0xed8d840f),LL(0x76530691,0xd414a4a2),LL(0x1468ef8d,0x9db9d138),LL(0x292b3870,0xfc6b7434), LL(0xc9d7ad96,0x80b66797),LL(0x2a9c1e99,0x81e74eb6),LL(0x9e92f64b,0x48657d9a),LL(0x4c851ddd,0xf5c60075), + LL(0xd99d5cfe,0x08fa89be),LL(0x4db4addf,0x78b1f26e),LL(0x3523ead9,0x03237177),LL(0x6a281494,0x0147af5c), LL(0x916836b0,0x8db3952a),LL(0xfd365650,0x0632b102),LL(0xccb3f2f1,0x3854a8e9),LL(0x586ad427,0x5048486c), + LL(0x17a86e18,0x22de9979),LL(0xbe029111,0xe2ac2321),LL(0x35cc5a17,0xbfd34397),LL(0x525e13cf,0x7a93461f), LL(0x5122d6f1,0xd433542c),LL(0x833982c7,0x41d2d9de),LL(0x8ec24d27,0xe9f1f29a),LL(0xf3b99d58,0x4ae251f3), + LL(0x10adb458,0x7234dd24),LL(0x88379ef5,0x0e4b6567),LL(0x748dba5d,0x3007df15),LL(0x35103772,0x1485ef01), LL(0x29c2382f,0xe21a9dc9),LL(0x6b6c1c8d,0xcf7e0c24),LL(0x30550c0a,0xf8a71820),LL(0xb797de2e,0xb30e5c0f), + LL(0x03705145,0xbe136119),LL(0xf94aadc7,0xe6d1f720),LL(0x255f5297,0x38ce1872),LL(0xc3143f58,0xbbba4793), LL(0x0984e265,0xda5345fe),LL(0xd895e0d7,0xe93989d6),LL(0xcaab40a3,0xb7392b18),LL(0x65e754fc,0x4a586963), + LL(0xa3afd381,0xb3e88445),LL(0x693ad961,0xa6cbab0a),LL(0x257d56dc,0x64d51359),LL(0xbbde137a,0xf9e70fcc), LL(0xadd016b1,0xa33872fa),LL(0x7344f234,0xd1d263d2),LL(0x24ba41b2,0xc2d51210),LL(0xe4ab65cb,0x8c9c830c), + LL(0x175b4039,0x3b47563c),LL(0x116b2025,0x53521dfd),LL(0x1a9f1cca,0xe4f3aa89),LL(0xe7cb1d2b,0xcc73485c), LL(0xbf58fe30,0xa6ca61ef),LL(0x531a2b6a,0x5d50e15d),LL(0x22611c31,0x71cfdb41),LL(0x61e3d46a,0x0dc15533), + LL(0x479074ba,0xb363c60b),LL(0x24cb405d,0x2a4d8f4c),LL(0x646b7f0a,0x3d3bee13),LL(0x5571af63,0xdfa9194c), LL(0xee76521c,0x951a61a7),LL(0x65eda1f1,0x67466ba5),LL(0x69ebc7ea,0xe41d33b8),LL(0xd4f4848f,0x8b6c992d), + LL(0xa5003eaa,0x3572faac),LL(0xabf54df1,0x01e36500),LL(0xac6f3af7,0x6622f12f),LL(0x0a8bb122,0xb5d7c17f), LL(0x240286b1,0xd1fc1b99),LL(0xad968ede,0x519d52ce),LL(0xece28bb4,0xcd1e7d0c),LL(0x93f0b097,0x64ffc699), + LL(0x25af7d81,0xb18d51f8),LL(0x19820fb2,0x8d0bb08f),LL(0xaa344723,0xe9f45919),LL(0x5f9e0501,0x558f18ea), LL(0x07cc79dc,0x56eff076),LL(0xd5fa9783,0xf171e880),LL(0x8be7f1fe,0xd5fb41f3),LL(0xd6fe9afc,0x19a34620), + LL(0x7d8a042a,0x74c2696b),LL(0x54230ded,0xcf4908c3),LL(0xdb32943b,0x98a870d8),LL(0x52f33e07,0x181cbe5c), LL(0x93709d8b,0x4d9d1172),LL(0x2b2b7939,0xb800c292),LL(0xa8920f60,0xd5a1fb7a),LL(0xbf7df622,0x8d0a7725), + LL(0xe9415cf4,0x83a370cf),LL(0x62a4ff4d,0x9f24d1e1),LL(0x0a6ff7cb,0xca33914b),LL(0xda1d1aaf,0x2576f2d8), LL(0xb4793101,0xbb2668bd),LL(0xca990b4f,0xb576672c),LL(0xff1d3988,0xfa165b5f),LL(0xba8c9e2c,0x273d5b18), + LL(0x720a5b3f,0x13594ae5),LL(0x2e65454c,0x38c4e04a),LL(0x55d0d903,0xc5b55d98),LL(0xf72db301,0xfabeb890), LL(0x2f3deaa2,0xe471f1d5),LL(0xc5ade08d,0x3f8d39f5),LL(0x6baf9d1a,0xe08486a4),LL(0xe5140d3b,0x77c6d30e), + LL(0xd23d4e09,0x828db96a),LL(0x84dcac15,0x2de4856d),LL(0xa6ac856d,0x313c7f8b),LL(0xfe7dea98,0x7c9f671c), LL(0xfebe9e72,0x4d6c14a5),LL(0x6014be55,0x185ac4e6),LL(0x5ed64e23,0x42809988),LL(0xbd6440fe,0xdc9395a1), + LL(0x24108055,0x10169080),LL(0x38961403,0xfe0d9cb0),LL(0xceb87d29,0xf88e6a48),LL(0x69618944,0x0365ca2f), LL(0x9fb59ec9,0x1504647e),LL(0xa4aadbb7,0xb6486b3b),LL(0x22ef3214,0xfe8701af),LL(0x5f56d985,0x4c895bc1), + LL(0x2e1e68d2,0x6fdc6cb6),LL(0x13f07350,0x0689b22b),LL(0x6d62eb1f,0xba94416b),LL(0x98996d72,0x5a2fcbba), LL(0x04b2afed,0x2ca2a2e9),LL(0x0bf61008,0x5b62c764),LL(0x37f4d486,0x30074e57),LL(0x31865287,0x4e02be2a), + LL(0x6842ab16,0x401cfb89),LL(0x5b2eb304,0x440fb52d),LL(0xd22eaa61,0x3245fd38),LL(0x373f201e,0x252120e8), LL(0xb2e724c9,0x4d253f5c),LL(0x27e5b5e4,0x9428d6be),LL(0x6785ee9c,0x00d4c598),LL(0x56208d4b,0x0b7fc5f9), + LL(0x92310137,0x4426665d),LL(0xfee8da95,0x75b96cd3),LL(0xb561c6d8,0xaaaac6c3),LL(0x3f09e1d9,0x0784a3c5), LL(0xdcac620b,0xac78c064),LL(0x119b8d90,0x49dd5f02),LL(0x57e5caf4,0xf1f5ebf2),LL(0x0eb825e2,0xd8a9fa2d), + LL(0xbfb6a2fd,0x3553633a),LL(0xa0c9ce9a,0x06533515),LL(0x04c71728,0x6decd9e8),LL(0x980b29bd,0xcbc0df55), LL(0x31826d15,0x17b1b559),LL(0x1c5cae17,0xc96ed7d7),LL(0x88cda83e,0x24f58740),LL(0x0c69f40f,0x9e2ee1bc), + LL(0x9e5604ed,0x138ebf0f),LL(0xf229f097,0x0577f4c2),LL(0x9762825f,0x0a44f975),LL(0xdd085e55,0x113b8639), LL(0x73acc59e,0x4be02fee),LL(0xada7a17d,0x7829f288),LL(0x84fb30d4,0x086bd736),LL(0xe5338eca,0xb2f120ee), + LL(0xfb778d2f,0x21701393),LL(0x6441fd75,0xd46bc61e),LL(0x135b55bc,0x466671de),LL(0x51c0f145,0xee1d9cbb), LL(0x6d9ce27c,0x7a7bce67),LL(0x26d82b1d,0xa8c9b1e0),LL(0x4c87bd6e,0x250bee03),LL(0xd3829702,0xd6b02f71), + LL(0x0e555d98,0xf14b3748),LL(0x6f775e78,0xf795e62a),LL(0x8f46de18,0xe9a4e4ac),LL(0xc5ab76ef,0x773bd32a), LL(0x5264cae9,0x4f2dcc68),LL(0xc63a6419,0x453b627e),LL(0xe441c6d9,0xc3aeddd1),LL(0x3027b8f3,0x669500b7), + LL(0x88d601e5,0x06b93413),LL(0x76c4483c,0x0e996e87),LL(0x00eb0c21,0xe2ff3a6d),LL(0xf4690674,0x86ec3a73), LL(0xe9f82ca7,0x673d123e),LL(0xbf611d0c,0x952c2765),LL(0x3676497d,0x26ed9a68),LL(0x9d29cefc,0x2c9c0049), + LL(0x2ae73af6,0x0b8c12fe),LL(0x6455c8e1,0x555b0ab3),LL(0x4804b006,0xd2f49f03),LL(0x02e829a0,0x408a22bc), LL(0xf2832c53,0xde2a59cf),LL(0x96a54082,0x01332439),LL(0xbbd38f9f,0x11dc4ab6),LL(0xa24764b5,0x0248fd93), + LL(0x1374972a,0xc7774c12),LL(0x92764b41,0xc7355966),LL(0x23143092,0x31c10ea5),LL(0x9070137f,0xe89d9f88), LL(0xa504d91e,0x7d074406),LL(0x70b7aa8c,0xc5210379),LL(0xea799dd8,0xa67904f8),LL(0xe7b02c04,0x81e6516b), + LL(0xb08cc6fe,0x18daf05f),LL(0xf59d49f6,0xfbbd3061),LL(0x93a78581,0x5429b117),LL(0x1906df65,0x795a4465), LL(0xd51a7866,0x643c37e3),LL(0x663a17b1,0x69b8118d),LL(0x3e8a2c53,0x5e385989),LL(0x50f007d2,0xbc18c2ea), + LL(0xb616aa15,0x4adec20a),LL(0xea085548,0x99f77e49),LL(0xc01b9a33,0x9108c205),LL(0x6ef3bcef,0x298fbeb1), LL(0xefd8ba0e,0xdf1a8d2e),LL(0xe9756e7b,0xf0ec9492),LL(0x7ff5fbc3,0x4fd33389),LL(0x03ac8371,0x122a6bfb), + LL(0x90d66732,0x7d053c8c),LL(0xf9b2909f,0x83f26571),LL(0x66cba4b6,0x350dd6d0),LL(0x40d0d47d,0x8c71c17a), LL(0x4d0be34a,0x3bf85053),LL(0xe11bd49f,0x91ae4f59),LL(0xa22c648f,0xf8a38b41),LL(0x58abaaea,0xcb96620e), + LL(0xa7fabcf5,0xa55cee46),LL(0x79c8fbce,0xd16a8b92),LL(0xcbf048bf,0x26ad700b),LL(0x47bb5f1d,0x83b3ce11), LL(0x6b310318,0x31a48f46),LL(0x00612ef3,0x13a7f781),LL(0xa18db234,0xcd840f2a),LL(0x30611c74,0x3be2a7a8), + LL(0x2b1c0447,0xbdf37cb2),LL(0xfe71722d,0x7f572382),LL(0x25535e86,0x085b3566),LL(0x3f5b9cc2,0xb5b43063), LL(0xdee66228,0x7c7cff51),LL(0xb676fd6e,0xe29236ae),LL(0xab0cdb1a,0xf0c0105e),LL(0x06b52812,0x0adc9d6e), + LL(0x483baf0f,0xc9e6ca97),LL(0xf9bf5055,0x09b063bf),LL(0xfc5a407f,0x8c4c6b2a),LL(0x99a6f540,0xe29cb487), LL(0xcb9a2758,0x18b72239),LL(0x8a5ed308,0xa0ae9f10),LL(0x6e402657,0x2a2cb603),LL(0xaf6f4d14,0x9c7f52cf), + LL(0x70ca9046,0x0ed032e7),LL(0x59cac9e9,0xe4b0b1d3),LL(0x18462dfd,0xd12c87b0),LL(0xbb8860dd,0xa25a23ee), LL(0x507fa3d9,0x6c9a8676),LL(0x218f325f,0xc6bb96c4),LL(0x2386b7b2,0xe141bbb8),LL(0xd4183c77,0xf86a72d0), + LL(0xaece96b6,0x35537f86),LL(0x63f7e1fa,0x83aa1df9),LL(0x7ac4aaf2,0xa39ab4aa),LL(0x8a202375,0xb8d0ffa6), LL(0x86514cd8,0xd916df09),LL(0x11902747,0x71f905b3),LL(0x8c744f32,0x6388c2ee),LL(0xa5431096,0x6282e1f5), + LL(0x7c388413,0x14bfa765),LL(0x7b4437aa,0x95dd04d9),LL(0x3c39d7c3,0xdf6ca849),LL(0x0c2ddf38,0x85cb1123), LL(0xc401529c,0xf7766d86),LL(0x99a4d031,0xe33416a8),LL(0xb874ace4,0x5c507c3f),LL(0xdad6fcb0,0x0e3a42b6), + LL(0x47920742,0x402da460),LL(0xb45f94cc,0xb142d6ef),LL(0x76608dd4,0xc2d613e8),LL(0x5d75d4b5,0xa2c06cdd), LL(0x3c564ff4,0xa1951bc5),LL(0xad1d5ecd,0xe60f126b),LL(0x702135ad,0xa634e765),LL(0x8df44695,0xa5a56a6e), +}, +/* digit=30 base_pwr=2^210 */ +{ + LL(0x9e2207b4,0x234b8c7a),LL(0xf7ee9f62,0x1f724f30),LL(0xc58e21b6,0xfa908ca2),LL(0xa74296ae,0x55587744), LL(0x02911ae1,0x7dbe9130),LL(0x9d3af02e,0xc2075433),LL(0x0f3955a1,0x505b724b),LL(0xcaeced66,0x480e1a92), + LL(0x446d9f66,0xb20f6128),LL(0xc354b5a1,0xd6e06b14),LL(0x63558aac,0xa72d287d),LL(0xae68a8fd,0x4819be29), LL(0x205fbdf2,0xb024c324),LL(0x210927f9,0x2fca94e7),LL(0xbe658f80,0x74798be7),LL(0xef07c046,0x618e07f1), + LL(0xb35a8c3d,0xfba715fc),LL(0xed1beba8,0xc2548193),LL(0x2ceb663c,0xb956c6dd),LL(0xaacafe85,0x13d4ddbe), LL(0x30a29cc3,0x2f8275b5),LL(0xf51b39ef,0x10432e15),LL(0x2509b2d0,0xd6c9277c),LL(0x849b946c,0x4ee0d4c3), + LL(0x54b01bbc,0x547ba946),LL(0x055d4821,0x7c56c36d),LL(0x05575f20,0x8e933620),LL(0x3a621cf4,0xaec65be9), LL(0x46287937,0x820b96df),LL(0x733c67e7,0x35cea883),LL(0x58cf3e05,0x30366a3a),LL(0x2da39773,0x2580d565), + LL(0xba4417ed,0x7717c42f),LL(0x654c1086,0xb2d66fc7),LL(0x57503cd8,0x07fe918e),LL(0x3cacf74f,0xf9385159), LL(0x63063029,0x157d9081),LL(0x659034cf,0x79c84c08),LL(0xa8048cb9,0x02976610),LL(0x03e81417,0xef822006), + LL(0x22e489c6,0x5fb5dd4d),LL(0x81e167e9,0x9a06d9c2),LL(0x6b974c90,0x83fc248f),LL(0x7110dca6,0xb78cab72), LL(0x370ff66a,0x73f8f311),LL(0x3b61d20f,0x8c5049eb),LL(0xc8516e05,0xaac47edb),LL(0x53f0201b,0x2ceba50d), + LL(0x0b93fbc7,0x6679dc5e),LL(0xa560bd27,0xf4457919),LL(0xb1acadc9,0x2561bfca),LL(0x46708164,0x338fbb6d), LL(0x8b9cfd27,0x9f407621),LL(0xd3123732,0xe806c1e6),LL(0x7f24a161,0xaa1eafc4),LL(0x68e6650b,0xbee3f4a1), + LL(0x5832cd6c,0x453b6181),LL(0x985e90ba,0xc002e337),LL(0x6414f686,0x4b33afde),LL(0x8511fd45,0xf9ab29e9), LL(0x6fb9a688,0x067f0972),LL(0x7202a1b3,0x7db6e14c),LL(0x73a881ab,0x0c15b6e9),LL(0xfad10660,0xc8c324e0), + LL(0x87d9f927,0xa997a6d2),LL(0xacd2f107,0x62307f24),LL(0x9c80a742,0xed7b48a5),LL(0xa7c81e7e,0xecd33ae5), LL(0xefa00a94,0xcf05c763),LL(0xd9ee5aa7,0x38844b0d),LL(0x214b293f,0x02e0b05d),LL(0x8a8a510e,0x732e776b), + LL(0x6c929e53,0x784cd909),LL(0x56a33da2,0xe436e294),LL(0xce9e06d2,0x68eeb727),LL(0xfce7e2f0,0x637890b3), LL(0xc3fde38c,0xc0681a1c),LL(0x76dda134,0x9cb729d9),LL(0x5c333ece,0xaa69eb97),LL(0x48eed8a6,0xe138a680), + LL(0x505dc701,0xd53cbd01),LL(0x6a64c3d1,0x413de346),LL(0x3170a5bf,0x91f6cde9),LL(0x8489b5fa,0x58ffdfd9), LL(0x5c584a48,0xcc0b89d7),LL(0x167f28de,0x74f8ceed),LL(0x8c878c91,0x250fa9f7),LL(0x630adfdb,0xeb960a79), + LL(0xc9489dcb,0xe43ed412),LL(0x112d084b,0xcec053a5),LL(0x664c7cd2,0x0fd4fe42),LL(0x82a917f7,0x48ee06f4), LL(0x83cd65f5,0xc5de1970),LL(0x5569c42f,0x3a176578),LL(0x4f876110,0xf24508f3),LL(0x0a415bc4,0xf350374b), + LL(0xc63aa8ad,0x9c2b11c2),LL(0x7a51c0cc,0x6ac1ae12),LL(0xe1db428f,0x75acd0d7),LL(0x19800684,0x9e391227), LL(0xb1050426,0x4f89e9c6),LL(0xdaf99eee,0x099d97cc),LL(0x1ffce97f,0x27a19ad0),LL(0x3c038d77,0x05fad057), + LL(0x8597d09c,0x96d6c678),LL(0x1e1d8b57,0x38f6336c),LL(0x6330ace7,0x1f945bef),LL(0x613f9faf,0x9d627bbb), LL(0x19176cb7,0xc0e7f21b),LL(0xbb9db710,0xf0e09be3),LL(0xc650133c,0x16b06011),LL(0xf3673d7c,0x8629b975), + LL(0x67115575,0x8c8230b2),LL(0x9c9f30c0,0x9bfc55b1),LL(0xce93fd71,0x132d0e07),LL(0x511c5947,0x08e4736e), LL(0xfe881630,0xd54a098e),LL(0x98efa501,0x8ec67a85),LL(0x2267db00,0x72975dc7),LL(0xa338290d,0x3d6fc706), + LL(0x55ade88b,0x0c891082),LL(0x4b212e85,0x0525b501),LL(0xb61362fa,0x9ede010b),LL(0x881eecac,0x52f3d088), LL(0xbc6f0ae4,0x49957b6e),LL(0x1659701d,0x25fe7263),LL(0x07b76f45,0x41e9b7f5),LL(0xbda77d42,0x5f2ad664), + LL(0xa9c418c4,0x5bdcb490),LL(0xe500a527,0xd0e2c38d),LL(0xca83fada,0x0af29f6b),LL(0x62273db6,0x1f75b1f2), LL(0x9e857e57,0x8454f751),LL(0xb9e79612,0x3fb816d1),LL(0x6412b5f3,0xbe3040ae),LL(0x843ca984,0x99535136), + LL(0x3257f19d,0xb26ec8a8),LL(0xe54dd785,0xd32dc622),LL(0xf8698ab5,0x0c52e874),LL(0x79183316,0xf9a60af5), LL(0xf7f4496a,0x38575d53),LL(0x3d5cd0de,0x33adfd1e),LL(0x7f502017,0x2133f4a1),LL(0x3e8676f8,0x46c09393), + LL(0x3fb4c7fe,0xca8a5a58),LL(0x328ff257,0x2ad58826),LL(0x13b8d08d,0xd9264875),LL(0xdc5a845a,0x661ae2b2), LL(0x49a408d3,0xd2dcaa06),LL(0x85c21e84,0x9ef164f8),LL(0xb7819b61,0x55efaf85),LL(0xf504c32a,0x9488bb1c), + LL(0x9bb777fc,0xb571518c),LL(0x82415187,0xf369c391),LL(0x2720284b,0x2d7c5dd9),LL(0x4eec41cc,0x6feab634), LL(0x24ecd0be,0x2522d5db),LL(0x00338736,0x1fca0d97),LL(0x20145279,0x74416105),LL(0x0496e925,0xf4492e1e), + LL(0xbc33b547,0xa62e09fc),LL(0xae063835,0x9434475a),LL(0xa139b769,0x51edd69f),LL(0xe5166a9d,0x17bbe224), LL(0x1b4b6c84,0x6ecb0a02),LL(0x97968c70,0x16439490),LL(0xbc8aa671,0x75af0456),LL(0x3b4411ff,0xaef056ab), + LL(0x05cef121,0x686b7714),LL(0x078f4500,0x5ad6bdf3),LL(0x072e70eb,0x56df858c),LL(0x254c0917,0xa0fc5e6f), LL(0xc15bf9cf,0x1a99de09),LL(0xd008aacb,0x8aeb587a),LL(0xb900d652,0xba2d8c53),LL(0xad0f69b6,0x60eb5d0c), + LL(0x10b27762,0x27098ff8),LL(0x13264ed3,0x33329ca9),LL(0x887e3f40,0xffceaf40),LL(0x930df9ef,0x854b8284), LL(0x7d5627be,0xdda913a8),LL(0x35e9823b,0x8eb94d64),LL(0x2eb9e9bd,0x94c527fd),LL(0xf57b9f74,0x18335b1b), + LL(0xd193a526,0x3c44dac0),LL(0xe2b2d54f,0xd0717099),LL(0xc4c67d11,0x65624fb4),LL(0xbccedad8,0x04aa7033), LL(0x31470c52,0x0c522fac),LL(0x33b05d54,0x08eb33ca),LL(0xb4565e57,0x940e0693),LL(0x7be56370,0x7e2fd553), + LL(0x12e206ff,0xf722793c),LL(0x155d3d02,0xb57e1f23),LL(0x94fc6ce3,0xd68be193),LL(0x22d4815b,0xb0f3606c), LL(0xb62d5741,0xdaf995a9),LL(0x3e8f5df5,0xa7d19980),LL(0xe4631583,0x7bcdb661),LL(0x5a97dc7e,0x013193e3), + LL(0xfc73494b,0x8210be46),LL(0x57e10efc,0x508817ee),LL(0x126f2466,0x7b6b8da2),LL(0x177bee35,0x2f3b0ec6), LL(0x48db1eef,0x5ceb71e0),LL(0xdc62b6bc,0xd989d9c3),LL(0xf78fac92,0x2cc38cb9),LL(0x955ba5f4,0xcd2a009f), + LL(0x453b668e,0x65a74191),LL(0xc081b447,0x40e9dc38),LL(0x8c3fdf2c,0x48eb63bf),LL(0x5763071a,0x7845cf66), LL(0x787754ca,0x30d9b771),LL(0x8783a05a,0x10b3729f),LL(0x6ab570d9,0xf8090b3b),LL(0x502b3558,0xc1dfbde1), + LL(0xbe4d36ec,0xa568f5d0),LL(0x28e952fe,0x1e9e5393),LL(0xeaad6b24,0x768113f9),LL(0xa8fbede9,0x2bc798fc), LL(0xaaa9010d,0x2c787f9b),LL(0x761834ca,0x32cbc77a),LL(0x032c25d8,0x449e55f7),LL(0xca6216dd,0xe824a5bf), + LL(0x17ac1130,0x3beaec52),LL(0x5e9d1aa8,0xcc28c64b),LL(0x3af8c635,0x355d68bf),LL(0xd3d1adaa,0xcd12e443), LL(0x6c2030d8,0xa456daca),LL(0x62427eff,0x0dfe5bbb),LL(0xf69e2484,0xae45325d),LL(0x7245c979,0xfc2a90ab), + LL(0xa008b446,0xc34f38e9),LL(0xaac355e0,0x5e86163d),LL(0xd586a2fa,0x61432646),LL(0x3d92e0c3,0xc68c7c8e), LL(0x020c1dd6,0xbfa8c268),LL(0x8bbcc223,0x25788741),LL(0xef62642c,0xbaf8c9a3),LL(0xa8c496d2,0x6d2f1ae5), + LL(0x44e57ce4,0x92d1c805),LL(0xaacd2100,0x34cdf4a3),LL(0x31e9c649,0xd5b89e4d),LL(0x232cfc85,0x558a6e26), LL(0xcea31a31,0xb40f3e4a),LL(0x35c5c924,0x346c1e07),LL(0x3fcede81,0x8ffedd8e),LL(0x3b55d143,0x35269ba3), + LL(0x848bdc53,0x0366065a),LL(0x078554dd,0xba2af074),LL(0x19ff3b4d,0x3c755fba),LL(0x35a22cbb,0x5ea93372), LL(0x1eb3e23b,0x0e55fe02),LL(0x765dede4,0x2626ecca),LL(0x81f445da,0x187bf094),LL(0x9df30578,0xba011017), + LL(0xd72507f2,0x81148037),LL(0x5db072d0,0x3a5841fc),LL(0xbd910aa1,0xfd631862),LL(0x23881c60,0x17b22d68), LL(0xfcc13359,0x6fa799cb),LL(0x2d39fc5a,0x55c40219),LL(0x9f1f6515,0xd50bfff6),LL(0x2e30fa1a,0x575090b5), + LL(0x9ba20c27,0x70343a0b),LL(0x749306a5,0xef34db86),LL(0x4ba85f8d,0xd7ad61d2),LL(0x7e091a33,0xe4d24ad8), LL(0xfc348493,0xbd6b49b9),LL(0x299c325d,0x4f11b543),LL(0x55036e93,0x4574a254),LL(0x676b75d9,0x534a623e), + LL(0x7d05afbd,0x54aa3d8a),LL(0x7f3f2c90,0x13349009),LL(0xa94b18aa,0xcd03de0f),LL(0x855c050d,0x13123c18), LL(0xf598b5f8,0x747c3cda),LL(0x8644df20,0x0f7ed9b6),LL(0x08d73585,0x45e010fd),LL(0xf8cec4af,0x3b0ff430), + LL(0xb028a832,0x3745a41f),LL(0xc4106172,0xcd6d2468),LL(0x1eceac6f,0x56c5a9b0),LL(0xe1e6e980,0x769c1285), LL(0xfa113196,0xbd163a36),LL(0x5840c242,0x206ffc36),LL(0x9c57ef67,0x12de1147),LL(0x03bea885,0x50260273), + LL(0x9684d63f,0x3099c21b),LL(0xc7c66691,0x06adb196),LL(0x3d63b3be,0x8464492c),LL(0x0bd38c15,0x86024ef4), LL(0x10565cbf,0x226022a2),LL(0xc9899033,0x2ae6b298),LL(0x262ffa14,0x5564856b),LL(0x7e038b55,0x9472d0e1), + LL(0xb1dd268f,0x1b17ea07),LL(0x4899352e,0x8340b9d5),LL(0x75242992,0x4f159400),LL(0xe6727e9d,0xe4392a31), LL(0xaef59026,0x4df1ef86),LL(0x950cfee6,0xe40671ff),LL(0xde4dd990,0x7b36d1cd),LL(0x3366ff4b,0x25df10a6), + LL(0x584ef631,0x83fb7e59),LL(0x91af7b6a,0xf12dd400),LL(0xe26f11c7,0x4a5ae41e),LL(0x96d90445,0xeb86d5dd), LL(0xa355d0a3,0x028ae37e),LL(0x99260127,0x3c118ef4),LL(0x76f51bd7,0xb8c7538c),LL(0x5fbadc4d,0x66b90aae), + LL(0x17dfd0cf,0x078de9df),LL(0xfe44b17c,0x938df6da),LL(0xc40bc950,0x4a09616b),LL(0xbc969aac,0x0b507845), LL(0x35f7fb82,0x23bae091),LL(0x9ad29b83,0xebc04d37),LL(0x26a3c5fa,0x9fa48a5b),LL(0xf08f3d8c,0xf67c661c), + LL(0xb2e9c3a1,0x21825747),LL(0x46c3eb43,0x3520a82e),LL(0x9646183d,0xe309ae9f),LL(0x26dac288,0xa19c31be), LL(0xc76623de,0x3c37018d),LL(0x64b51087,0x59b9a0fa),LL(0xf1954f4e,0xa32f8357),LL(0x1f6da143,0x24251df4), + LL(0x01fb07d0,0x825c61cf),LL(0xf2f0243c,0x69ae93fd),LL(0x0943f7bd,0xd507c99e),LL(0x463ee64a,0x5e6dfb09), LL(0x29afd00b,0x10a3c32a),LL(0xbe8cbada,0x92179b5f),LL(0x7d89f9a6,0x7bebad0a),LL(0xd13b3073,0x7ba9bbf6), + LL(0x6481cc75,0xfc23c215),LL(0xfeca7532,0x6a654801),LL(0x0fed841f,0x20785ec0),LL(0x25269b21,0xcb612be9), LL(0x414a0fab,0xe9a9c09b),LL(0x6b4fa0dd,0x5404c7a7),LL(0xcb418588,0xde62dae8),LL(0xc594334e,0x2d80afd4), + LL(0x95366a44,0xfe454df1),LL(0x755cf8b2,0xda7626c3),LL(0x41397051,0x4446f0ab),LL(0x70eb8b23,0xd1788064), LL(0x977b040a,0xbc7737f1),LL(0x57590edb,0xbfb39418),LL(0x343a7333,0xb094b4a8),LL(0xeb91372f,0xb15912ce), + LL(0x0b56002c,0x584e1d5e),LL(0xaa0cb90f,0x1460ce24),LL(0x8f7ffcb6,0x58f0c144),LL(0xbe0d802e,0x56e39f33), LL(0x529458d0,0xb02a6edb),LL(0xa730f9d5,0xa0fbae74),LL(0x1bf69928,0xd98c0ac5),LL(0x796f12e9,0x5c9f888f), + LL(0x22e065c8,0x749207b0),LL(0x88c61143,0x6e0232a4),LL(0x837adda6,0x27f30808),LL(0xd0c215d5,0x0b748853), LL(0xbf076ba7,0x97bc4008),LL(0xf157f4d2,0xadae0275),LL(0x8bcba88b,0x394e5d7a),LL(0x23ef50ad,0xf995ec14), + LL(0xaa9b60a9,0x6b207f9c),LL(0x52f9979f,0xcd7509c1),LL(0x0834e0ad,0xe3e8f6dc),LL(0xcd5b1314,0x6e2a4165), LL(0xfd60d975,0x073a2db3),LL(0x2c053b7a,0x5ad92ca4),LL(0xfba97ae8,0xceb10220),LL(0xd265e913,0xab82f6a0), + LL(0xaa68a13d,0xc7a755ad),LL(0x10dd277a,0x56c13360),LL(0xdef56183,0xbbcf6411),LL(0xb863a4e1,0xebffe360), LL(0x814e8aec,0x67ff26e5),LL(0xa0804732,0x90553561),LL(0xad5fe672,0x407396ac),LL(0x11ad53af,0x053a068b), + LL(0xc652cb95,0xb518dd04),LL(0x57e2b99f,0xc818563a),LL(0xb96432a7,0x217cf87d),LL(0x8cc2fdcd,0x7fdc35be), LL(0x4effaebf,0x8c2ef271),LL(0xf427c7c2,0x21879369),LL(0x5197ba08,0xd80ebbea),LL(0xfc6f4c66,0x1b00db45), + LL(0x3828a5c0,0x99b9d2be),LL(0xd24a69e8,0xa8855350),LL(0x3ceaa821,0x2f919695),LL(0x04296439,0x89390c91), LL(0xc5cf8a0c,0xc12b3852),LL(0x73afc431,0xdcf234ea),LL(0xf4adf01b,0xdddf5568),LL(0x1b426097,0x2d04fc76), + LL(0xcb27c5e0,0x02a21dd5),LL(0xa6b2f9b3,0x01b842c3),LL(0xd8bd7a07,0xefbd483e),LL(0xd13a781e,0x0220825e), LL(0xde802c17,0x8aa029a0),LL(0x3a3f0fbf,0xb62fcd6e),LL(0xe9635f48,0x80558aff),LL(0x65dbeb2d,0xbdc6851d), + LL(0xb5412271,0x99f48286),LL(0xe242a8a3,0xa53ef798),LL(0xc0371086,0x41d18606),LL(0xfcb6d1aa,0x5df3379c), LL(0x00a7a13e,0x53f2f5a1),LL(0x2bf51e2a,0x3565a6eb),LL(0x930c5a71,0xa2832b52),LL(0xee2abfcb,0x66071ec7), + LL(0x3496a532,0x75ce0a56),LL(0xbe0d69b7,0xa316dfbb),LL(0x353e94fc,0x35438d6a),LL(0x1e0ce775,0xf53433c1), LL(0x22ff3a1d,0x47ea3e8f),LL(0xcd7ccdb6,0x60ebfba8),LL(0x33c475d0,0x47c6b6e2),LL(0xb7959fd5,0xd18637e7), + LL(0xa1ae3404,0x8d7a35ce),LL(0x75b832bf,0xf15c71d6),LL(0x98b9d24b,0x65047419),LL(0x0dcf73f4,0x28625a55), LL(0xc7c99478,0x5aa9dce8),LL(0x0bde8d53,0x752d1625),LL(0x93e99ee4,0x7255ecfa),LL(0x22706f48,0x1c53bf71), + LL(0x4d478014,0x28335451),LL(0x3f392c0a,0xd64b05ff),LL(0x4fba1661,0x1d9ac89d),LL(0x34828cd8,0x281a0ffb), LL(0x577ed419,0x07abacdd),LL(0x3cfb2c56,0xa66949f5),LL(0x847ebe65,0x38e69105),LL(0x44d6236d,0x8fbbba5a), + LL(0x725ef820,0x0c85bd64),LL(0x25a152a7,0x4ef91524),LL(0xb019cebf,0x5237ef0e),LL(0xc9a7724f,0x48203f41), LL(0xc55fc0d4,0x1f61885c),LL(0xbcb3daeb,0x2c4dd07a),LL(0x4b7dafc5,0x9855d5e7),LL(0x5f3769af,0xd76e6fdf), + LL(0xbb547be6,0xb834df1a),LL(0x3e7a9586,0x43056b12),LL(0x4375fc7e,0x7459e0bb),LL(0x9c85fc6b,0x5f5f295a), LL(0xbb23b709,0x3f2d2bb7),LL(0x955983ce,0x0b53bd8c),LL(0xfaf68dcc,0x5aee93df),LL(0x509f09dc,0x5575770c), + LL(0x40b1b744,0x2bf23c0c),LL(0x9a5bb913,0x524154bb),LL(0x296bdb2e,0xb0e93d76),LL(0xda0b2925,0xb3c71f5b), LL(0x0c617939,0x8e77ae7a),LL(0x1aca9b0a,0x2bfea97e),LL(0x7897c5a8,0x8e3317c9),LL(0x4cee2716,0x850ddefb), + LL(0x107d9186,0x684ceee9),LL(0x0082c312,0x48708423),LL(0x6c556897,0x5300137c),LL(0x7e99bc76,0x6d464401), LL(0x8808ca2b,0x6b11e1e3),LL(0xcca6433e,0xedd30eee),LL(0xaa072ff0,0xa9099f60),LL(0x5830f69d,0x774662ec), + LL(0xf94547d9,0x0770355c),LL(0x42967865,0xb5041edb),LL(0xe585a93b,0x169a6274),LL(0xd04d6a81,0x06cebf5e), LL(0x2ebc1791,0x0a59450f),LL(0x765ac18a,0x69fd006e),LL(0xa54f7e7a,0x4711ec9c),LL(0x819c6af9,0xd72c8d58), + LL(0xb5418e15,0x89c97c6c),LL(0xa558a854,0xd520b03c),LL(0x0d76773a,0xe3c24aca),LL(0x67e5110e,0xc4deb5ce), LL(0xcbb04ba4,0x5bb40152),LL(0xde1b628a,0x672563b6),LL(0x2e8d9e54,0xaec916aa),LL(0x3c60ac70,0xa4e8cb47), + LL(0x452d5064,0x54a03e39),LL(0x1e7bb355,0x1e405c2d),LL(0x3bbd3ab0,0x2ab2d5df),LL(0xdbc9fbd8,0x0808410e), LL(0x27f23f6f,0x4180ceea),LL(0xba1d6beb,0x2b965b35),LL(0xf66d6546,0x14f1f010),LL(0xf85cfb4a,0xefdca6a8), + LL(0x6614c1c0,0x69e6188e),LL(0xe07cb7f8,0x00bd1531),LL(0x4bb7ee68,0x1b90f515),LL(0x51abb1f3,0x8afdf466), LL(0xb5f34316,0xf59a7327),LL(0x64c7bf22,0x43c3c19d),LL(0xcdb00a2b,0xb275733f),LL(0x602915ba,0x0160df79), + LL(0x1baea574,0x1ae4ee9a),LL(0x03ae5168,0x0d922f28),LL(0xca691124,0x07df28fd),LL(0x8dd457c4,0x5aad2f31), LL(0x137384ca,0xe0d4f443),LL(0x6620ea8c,0xd93d424a),LL(0x5067797a,0x21d544d3),LL(0x9d8a15bc,0xc8a8cc99), +}, +/* digit=31 base_pwr=2^217 */ +{ + LL(0x941d80a3,0x610f0e26),LL(0xad36514e,0x30927879),LL(0x98f22601,0xaa2dfd48),LL(0x88c8b0f6,0xbc5b31b7), LL(0x6c841cc8,0xb1281f37),LL(0x5a412b84,0xdae16719),LL(0x828f210d,0x9ec1f6c8),LL(0xe8d92901,0x1935d576), + LL(0xaf3840f2,0x47247921),LL(0xdf3fcdfc,0x348325d2),LL(0xc43961bd,0xef578508),LL(0x1bd98c29,0x7d5e8ccd), LL(0xf8a30164,0x59cdba10),LL(0x7cb8c653,0x0757408f),LL(0xc3056ef4,0xcd7ed73f),LL(0xfb99cd1b,0xd28e7cc1), + LL(0x6bb62286,0xa8a67494),LL(0xe7d87467,0x8d6ef816),LL(0xf673b6d5,0x3529f938),LL(0x8bbf101b,0xf5c0ee76), LL(0x49fdc949,0x3768ed61),LL(0xcf405ee0,0x53b6999e),LL(0x1718e51a,0xbf0108a0),LL(0x5181ebd7,0x38e609ec), + LL(0xd8595159,0x82051640),LL(0x579a3876,0x30e1c706),LL(0x0298a67c,0x091154c6),LL(0x51132d27,0x76d9a9c9), LL(0x5c661a4d,0xe41de8b7),LL(0x2a6dcbaf,0xf24b5e96),LL(0xd714e045,0x1ed4cb0c),LL(0x0c187c70,0x605926a4), + LL(0xf34b1c93,0x97672559),LL(0xe0b43506,0xa256be98),LL(0xe1a98eb3,0x7fcdd412),LL(0x295a061b,0x7fcfcd84), LL(0xcc2386cf,0xddbac22b),LL(0x928c2556,0x7741adb7),LL(0x4e6e1288,0x3a2bb869),LL(0x025bb4a1,0x53ed11da), + LL(0x4108c8e2,0xb114bd67),LL(0x3deb8e23,0x85948c6b),LL(0xd0e9434c,0x6a9e05d9),LL(0xb9c4fd70,0x395060b7), LL(0x18893751,0xa0ccfd16),LL(0xbbf65477,0xa941ff60),LL(0x59423e35,0x34ada238),LL(0x7e570058,0x4ba7a7d1), + LL(0x869ae596,0x3d05d455),LL(0x93368325,0x92a15400),LL(0x62eb7ffa,0xbd64ae0a),LL(0xd34b2c59,0x3f263a7a), LL(0xa22244e1,0xe95eece3),LL(0x706fc500,0x39ccef58),LL(0x22f1d2e6,0x39a88f93),LL(0x6d47c670,0x1ec796b3), + LL(0xaa1ff4af,0x1558e0f2),LL(0x390503a4,0x61f43487),LL(0x3c4f76f1,0x66164732),LL(0x9e13432e,0x50d0706e), LL(0xf5eba0fb,0x5f1a87ca),LL(0x80bda2c5,0x28a95c0f),LL(0x12ae6462,0x10d693e0),LL(0xf45e6ba6,0x79871340), + LL(0x887051c0,0x8abf0cad),LL(0xb3c6b540,0xd09f571d),LL(0xe30ab25d,0x3fb2e16b),LL(0x539e8bc4,0x12e057a7), LL(0x733c2597,0x6efe71ce),LL(0xe71058ac,0x72fa0df5),LL(0xccc037bf,0x49f14d06),LL(0xceb3eb6c,0x9a3ceb03), + LL(0x4195370a,0x9895e908),LL(0x927345e7,0xa75007e5),LL(0xd3850711,0x00b4c212),LL(0xdfee8b34,0x76e4060d), LL(0x184c1d07,0x15801862),LL(0x302f5711,0x234e39c0),LL(0x6aa74204,0x4c0bd387),LL(0x6f496836,0x0515eddc), + LL(0xc849afbe,0xa9fd0cb5),LL(0xcad5c0aa,0x041df5ba),LL(0xddff259e,0x9a54af37),LL(0x9b550a8e,0xa3f156bf), LL(0x7e3298d4,0x4df2d33d),LL(0x65ff0e1a,0x0957a0a0),LL(0x1e2b3a45,0xff7fb43d),LL(0x1a73285a,0xb86d386a), + LL(0x28b18e93,0x6e283c47),LL(0x4b4132ed,0x5458b92f),LL(0xba674332,0x7026345e),LL(0x5c9fc32d,0xc8e38151), LL(0x58e7b4fe,0xd6aaf8e1),LL(0x4267253a,0x3e77a5c9),LL(0xa0949607,0x6441cba2),LL(0xdee20b2e,0xfa205185), + LL(0xf5b44600,0x64f3d576),LL(0xef5c8446,0xf12125db),LL(0x487a0116,0x1467539b),LL(0xf380229a,0x3aa0fa49), LL(0xd79f36dc,0xcc6586f1),LL(0x1b9a0b42,0xebcf653d),LL(0x9c1df729,0x68af006d),LL(0xa7903ee6,0x507e055a), + LL(0xafd8ac9b,0xd1b48ef8),LL(0x3b5f6b51,0xd8920af7),LL(0x983339c8,0x9629e789),LL(0xfa9248d3,0xbfd2d787), LL(0x9a078882,0xb50ca302),LL(0xf5cb0529,0x1c34f848),LL(0x1646a9f8,0xb9b01519),LL(0x80d53f9d,0xc9e3679e), + LL(0x1af3e5f2,0x5a63e822),LL(0xff58e3d1,0x05480ad8),LL(0xd6b3626b,0x2d241643),LL(0xc1eda15f,0x33b15660), LL(0x8528e5d6,0x3e74f855),LL(0xf63188f4,0xafb6dc9a),LL(0xaeeb1d32,0x0cac44cb),LL(0xa627eff8,0x50661046), + LL(0x64b49667,0xadc4b012),LL(0x1e05f760,0xa4bdafa7),LL(0xf185d27a,0x171b28b3),LL(0x33425747,0x987e5163), LL(0xc3864a65,0x7c42ac4e),LL(0xbf449c12,0x2dae1bb8),LL(0x06965832,0x680d9743),LL(0x7e31d9f4,0x6ac1ef01), + LL(0x579d6ae4,0xdef57433),LL(0xd5240bf9,0xe055b087),LL(0x90a5e069,0xe4dbbe60),LL(0xddb3dc15,0x2161d5fe), LL(0xda297b71,0x7d303012),LL(0xd468046c,0x04481034),LL(0x0ac93c6c,0xaa94d5bb),LL(0xd8d8f53a,0x95bacd45), + LL(0x3e03e895,0x790a5d6f),LL(0x44fa5a81,0x27efd502),LL(0xe5998b32,0xd9d35230),LL(0xf22ade19,0xb36a0c07), LL(0xf979a2fe,0x46ec8691),LL(0xced8cb94,0xa67ba933),LL(0x2f856ab3,0x00d07245),LL(0x3c925dae,0xadc9ff42), + LL(0x563038a5,0x0e4eaa25),LL(0x8a8f6483,0xfef7e89c),LL(0xace61af8,0x50433633),LL(0x2e1a3515,0x8a1589e0), LL(0x5fdcb1ac,0x99f21e29),LL(0xc9a466da,0x8fd2d411),LL(0xf56b7f13,0x55323c6f),LL(0x5cff438c,0xa016d64a), + LL(0xdc05b5cc,0x3e3dfcbc),LL(0xfc3c70ec,0xc1956ca8),LL(0xe63f02df,0x7dbbd169),LL(0x240b87c8,0x95206689), LL(0x1aa6d48a,0x7bacda5e),LL(0x39280f78,0x51dcf19f),LL(0x660abac2,0x1511ae04),LL(0xd905af53,0x3a95adc9), + LL(0xea464737,0x0c8c4330),LL(0x34fc4b51,0x989c09c4),LL(0xe2cf3376,0x1852120d),LL(0x25c04de3,0x5a1cb8a8), LL(0x75fe7596,0x50486f98),LL(0x223030b1,0x8cd78d2e),LL(0xcfa1ab11,0x524cb8f8),LL(0x5a15b0b9,0xa716ea3f), + LL(0xb902d114,0x7618e95e),LL(0x084ebf5d,0x0a1a4146),LL(0xe3f87683,0xdfb909e9),LL(0x4107410c,0xa0b7eee1), LL(0xf02b0e12,0xa45a551c),LL(0x9efccb9f,0xceabbfd2),LL(0x740f4e3a,0xb0d1b6bc),LL(0x4cbfd0de,0xfc737250), + LL(0x32452b0e,0x3fad2d9e),LL(0xf523527d,0xb4e659fe),LL(0x6c0ff353,0xf0dcd701),LL(0xd67b6f98,0x28f06e2a), LL(0x82a789b4,0x2d0c36ce),LL(0x49c0d54e,0x20e577da),LL(0xae38dd0e,0x8d1d5c7f),LL(0x894d9143,0x72e01399), + LL(0x3958e055,0xf7806856),LL(0x5df44aee,0xac35ee40),LL(0x97c18b8d,0x2b478913),LL(0xfa2586cd,0x5396824e), LL(0x1b23f8c4,0x22b37b25),LL(0xcdecdefa,0xf9ced36e),LL(0xc2fc39c0,0x28c3bee5),LL(0x6d9db32b,0xa1731fae), + LL(0xbc3e2c91,0xa0445fa7),LL(0x75a4aa72,0xa1ab6955),LL(0xbbe0a1c7,0xf0cd61c6),LL(0x0123bc52,0x923c3b69), LL(0xafd7c4bc,0x818ad28c),LL(0x28b15b05,0x7c229224),LL(0x1f78a4f4,0xecde7efb),LL(0x03ef3ab3,0x550d68e7), + LL(0xfc5f8c35,0x0371021d),LL(0x0ed2b06e,0x4440aa1e),LL(0x9ba7247d,0x70c8ede9),LL(0x84f23fde,0x0d2b6ed3), LL(0x5ff4478c,0xd0119d95),LL(0xf79c69d5,0x66152d27),LL(0x02afd13b,0x56d8bea4),LL(0x15bb938a,0x035efe5f), + LL(0x2ccaa425,0xc5ca7d08),LL(0xeeee9376,0xc8c69ea6),LL(0x493a2051,0xb22cfe59),LL(0xdc7b90fb,0xcb50e618), LL(0xe05a8705,0x0f6fdf2b),LL(0x4814df31,0x081f3fe7),LL(0xeb1e3e76,0x6fefe18a),LL(0x03e06a50,0x81910050), + LL(0xdb45bfea,0x8a801df1),LL(0x7a828cf6,0x8c7fe1fd),LL(0x8d173cfd,0x1c1868b5),LL(0x0dbde1c8,0xe18f0a36), LL(0x9ac345b6,0x3b29ed64),LL(0x9dcd07a5,0xd56d5956),LL(0xc6813a88,0xf4191570),LL(0xeda3af42,0x39033ebc), + LL(0xad5d215d,0xdee5591b),LL(0xafbe5a28,0x9cfa11c6),LL(0x1823c28f,0x73d0f1e2),LL(0xafab1f67,0x75d49925), LL(0x7c521448,0x61c81e2c),LL(0x4a96edb5,0xc547be6f),LL(0x4ca368b3,0xccb9fc59),LL(0x04fc3303,0x175ebe48), + LL(0xfce42989,0x507620cf),LL(0x9abfadb2,0xf236e043),LL(0xab36ab58,0x381c50c3),LL(0xae22c6a3,0xed4cb73e), LL(0x2158dc4c,0xa68a2827),LL(0xe9fa53ff,0x1715ac43),LL(0xfa266797,0xb02fdf73),LL(0x7eefb203,0x3079f3c7), + LL(0x7f7545bd,0x0a41fb94),LL(0xcb923ace,0x6b9dd022),LL(0x3bea2541,0x582c7ff5),LL(0x5ecdbe2d,0x992f2379), LL(0xfe17bdca,0x821f1670),LL(0x2626bdde,0x521c06f2),LL(0x1864ca0b,0x6292748c),LL(0x1bc74d8b,0x554d4ece), + LL(0xea3d4446,0x745d4f74),LL(0x40ad1c7f,0xa439f178),LL(0x51374e92,0xc95d9510),LL(0x90229008,0x75870e9f), LL(0xc54e7e81,0x3fec98c2),LL(0x94b3860b,0xef537ee9),LL(0x40bfc8f6,0x139dd834),LL(0x0f114403,0x20b51364), + LL(0x30b4b4db,0x4752a49f),LL(0x8c3c90e0,0xdfbb8b17),LL(0x70f0b16a,0x60c8915b),LL(0x40528319,0x5e395000), LL(0xa641f2e3,0x8a1624c7),LL(0xbb4ca0dc,0x3c9925c6),LL(0x2c3152b5,0x2aae6edb),LL(0x08b896ff,0x8dbac580), + LL(0xe5a36bc8,0xe0516205),LL(0x3295707b,0xd7714332),LL(0x51c3513f,0x61db6804),LL(0xab552df8,0xf2ee6e20), LL(0x353c17f0,0x5ddcfa99),LL(0x046d5fd4,0x65687a2f),LL(0xfd1ccad4,0xef567e9f),LL(0xa0238b70,0x7cd5f7dd), + LL(0x92c01197,0x96fba79e),LL(0x83b50e70,0x46a9f2de),LL(0xfe287169,0x7efcbbb2),LL(0x4528d67d,0xe30d60cb), LL(0x6cb04d3a,0x88fed0cc),LL(0x0221ceb8,0x63eb9d0d),LL(0x748b5813,0xc6954e9f),LL(0x5c96e897,0xceef2bd8), + LL(0x85648f04,0x99503ae2),LL(0x923e87d7,0xeee51f99),LL(0xb6560ceb,0x90908fca),LL(0x80e0f6b3,0xafad5926), LL(0xaea32cf9,0xa50f31f3),LL(0xa74ae92d,0x7ea17064),LL(0xcda71d1a,0x0675ccc1),LL(0x1e0a464a,0xd1e3b630), + LL(0x2442872d,0xa361f2b7),LL(0x46e52c97,0xb21bcd39),LL(0x85574630,0x1405f89c),LL(0x8e0a96ab,0x0da7bfbd), LL(0x4220f57b,0x48af06c2),LL(0x6a333e4f,0x772a9b12),LL(0x6f712eb8,0x3afc661e),LL(0x2eba8817,0x29deff6c), + LL(0xd8c69e5a,0xbab680de),LL(0xe93daf10,0xf8615abb),LL(0xcef6fae6,0x7455ea1d),LL(0x868455fd,0xac0a30ea), LL(0xe47d628a,0xae967b17),LL(0x65f1f482,0xa6d703e2),LL(0x0bfcc371,0x2723a965),LL(0x6db4a042,0x9b06cc14), + LL(0xa77c8b21,0xa973d738),LL(0xc008f2ed,0x9a981f80),LL(0xaf27cdb3,0xecc7bbcb),LL(0xb5cb693a,0x514db964), LL(0xe75c93d1,0x24125414),LL(0x1f00d53c,0xd9308c0e),LL(0x831eba6d,0xdb56d155),LL(0x672b86f1,0x29eefc2c), + LL(0xdd13b3c9,0x332f6ab6),LL(0xe371f873,0x70e052f6),LL(0x125712ab,0x05740742),LL(0xb3512100,0x4239152d), LL(0x80b22915,0x98355eaa),LL(0xb896f6fa,0xd0e263ec),LL(0x442b4c8f,0x9378a8a6),LL(0xf65795bb,0x40c2b546), + LL(0xd572ead8,0x0cfa46ed),LL(0x78361300,0xb9b4abdb),LL(0x8c102020,0x5fe63ef1),LL(0x785a4b54,0x1805c84e), LL(0x805cb642,0x147cf487),LL(0x487e581f,0x87cf50aa),LL(0x9eaebcd0,0xe942fa5b),LL(0xd1af71f2,0x06d4fa96), + LL(0xc4fc3823,0x20c1a770),LL(0x85140885,0xcdffd09e),LL(0x6b3592e9,0x27ce78ab),LL(0x8ba82008,0xb8e8c15e), LL(0xfef74187,0x5fe8f3f0),LL(0x77ce808d,0x8e85a3a5),LL(0xc7395f64,0x8447dc69),LL(0x1181b854,0xae90769f), + LL(0x456114c8,0x54adc101),LL(0x9ca6a9c1,0xe7962b76),LL(0x909410a4,0x3f0e77fb),LL(0x9e2e44f9,0xe18151cd), LL(0x2cf6e29e,0x5e510a0a),LL(0xb1836b07,0x136896ab),LL(0x0fe11010,0x3ad4fdec),LL(0xdbddf038,0x35b36790), + LL(0x75903df9,0x7c4f5a68),LL(0x2f5b7193,0x3e9cb056),LL(0x591a4524,0x745e9452),LL(0x1a056e15,0xc406ad44), LL(0xa69e11ef,0x2e93edf2),LL(0x73a1cb88,0xa28b82fd),LL(0x1225c3d5,0xdc1c9cda),LL(0xa5569794,0x86e9a994), + LL(0x5b092dde,0xd698506e),LL(0xd1ca8b06,0x076a4c82),LL(0x2ef2bc6f,0x4516033b),LL(0xd78fa65f,0x0574c792), LL(0x735bb362,0xa3b1c3d8),LL(0x0da54317,0x22fca7a4),LL(0x60aaebb6,0x3e7ae709),LL(0x937638c1,0x42417d54), + LL(0x1dfe8b0e,0x32f00a5d),LL(0x8dcdbdbc,0x8ea5e8e1),LL(0x6b30ea52,0x38df57cb),LL(0xe94c30ca,0xd325aa1c), LL(0xdce4d256,0x7aa04a9d),LL(0x74c7db6b,0x78e98cd3),LL(0x443d5c9f,0x631475a8),LL(0x7adfbceb,0x34e5c73a), + LL(0x9f1e8828,0x7fb69bab),LL(0xc84149e3,0xcadc78be),LL(0x1fe86af8,0xe9424ecc),LL(0xbc504ea8,0x13160cc8), LL(0x4c96a680,0xcb380078),LL(0x845faae5,0x006fb9d8),LL(0x1e0e66d1,0xc6a64277),LL(0x428f526d,0x13f77d6e), + LL(0x28474530,0x9f80fe8c),LL(0xdb7fec00,0x5649a173),LL(0xd9cb05ca,0xdeed5bf4),LL(0xd7077c41,0x14b1a3a9), LL(0x096883ec,0x4c2ed239),LL(0x44ae671d,0xd550edfe),LL(0xf7b7362a,0xb233e5dc),LL(0x4fd464f2,0x32c15820), + LL(0x68880bf9,0x0ecb18f7),LL(0xaf230a34,0x53468bed),LL(0x370cd6ef,0xe3ba97b9),LL(0x3516d77e,0xf5cdabf4), LL(0x11462032,0x08d78a56),LL(0xd583ccc5,0x1393fa93),LL(0x0c1b3514,0x52af7f5d),LL(0x188ca043,0xf48cac66), + LL(0x5461a1d1,0x2524c8dd),LL(0x91b6e707,0x6eee8101),LL(0xca2fe87e,0x209fece6),LL(0x9ac56706,0x50b35727), LL(0xec373bb2,0x651a6701),LL(0x1a4c2e84,0x881de85b),LL(0xcfdb47d5,0x4892861d),LL(0x5cdc4424,0x5ae2e653), + LL(0xa1f90dd9,0xc58f4f59),LL(0xfcf158a4,0xa5584f85),LL(0xab072a7a,0xbde86fb0),LL(0x268bae62,0x7c69e25a), LL(0x44fc7b3e,0xee3478f3),LL(0x6b7d3647,0xec148394),LL(0xe1c8c0ca,0x2a542ebf),LL(0x161dc0c1,0x63d1d635), + LL(0x57ab9282,0x769acdbe),LL(0x2a119cb9,0x9c338971),LL(0x125e5b4c,0x049e366f),LL(0xf0c8fde4,0x3aec68e0), LL(0x324cefda,0x9d95b6e5),LL(0x704014b5,0x844cce33),LL(0x6a6bb216,0x03920a61),LL(0xf379db8e,0xd69d17e3), + LL(0xc5e386e5,0x1924ac16),LL(0xd64953c3,0x62373a48),LL(0x47f4e4a4,0x5b1f7d64),LL(0xffa115fd,0xc043b5b5), LL(0x87fb16b0,0xb2a2656e),LL(0xd8cd79a6,0xcac56b9b),LL(0xcc19d3af,0x544971f6),LL(0x0fd63db9,0xf539244b), + LL(0xfbf4d232,0x0f052d3c),LL(0x7a2a7280,0x6b3c8366),LL(0x48079b9f,0xaa6579db),LL(0xa4d9edcf,0xc5beb93d), LL(0x0f1599a3,0x8ad58825),LL(0x5f3f640b,0x3f3a2634),LL(0x9032fd7c,0xda15393a),LL(0xac0e7136,0x97c10230), + LL(0x599785ee,0xfa32ef9f),LL(0x6b4c7a65,0xe1ed3b28),LL(0x2da1dcdd,0xcee1af27),LL(0x6861e2c2,0x4e480c11), LL(0x9c8ad8c3,0x35b5ec42),LL(0x3fc55f23,0xfd07f6a4),LL(0xea76d444,0xab18ead2),LL(0x22ba099a,0xcb8bde14), + LL(0xc61ae967,0x252e6a81),LL(0x72a2e1e6,0xaf11042c),LL(0x1a211ef8,0xb353902a),LL(0xc99a25fc,0x644d16e0), LL(0x5b67e48a,0x637fd606),LL(0x51a0b665,0xfa570963),LL(0x7ee072b8,0xaa661c73),LL(0xf2e0a727,0xde1eb4fe), + LL(0x22ed7ee6,0x56096a0c),LL(0x5825908b,0x31aaf403),LL(0xbfa02db6,0xfd5f6ba7),LL(0xff798900,0x85f4f9a9), LL(0x4a0cd878,0xa0997d56),LL(0xb1b6982e,0xdd76909c),LL(0xeccf338e,0x874fab15),LL(0x4ce82bb1,0x5e072b3c), + LL(0x6dd0d997,0x5dbe883f),LL(0x41765fb6,0xa32117f2),LL(0x7d87fc5e,0x59ca4da3),LL(0xb95ec918,0xc91002cd), LL(0x6548248f,0xd53bc123),LL(0x6c6d1e0e,0xef10a373),LL(0x99d9893f,0xafb2d760),LL(0xce0ba0ca,0xb77c1f1b), + LL(0xcfb9f6b2,0xabce362c),LL(0x35f9be91,0xe6e108d2),LL(0x7187fa9d,0xb2331290),LL(0xfc7ddce6,0xdcd1f4fd), LL(0x9086eb29,0x3a129991),LL(0x53a56d57,0xb0730520),LL(0xabd421bd,0x9fcdf4cf),LL(0x08f3e8e0,0x96271270), + LL(0x401e0217,0x951ea7e2),LL(0x733f637b,0xa4d1d708),LL(0x4f4cd676,0xc75170f4),LL(0x832f0b4d,0x568279ba), LL(0x25c17ab7,0xda4c01f7),LL(0xfa30e1b9,0xfcc13028),LL(0xacba57ec,0x4d1d8f71),LL(0xef6b3913,0x0c7971cf), + LL(0xc014f166,0xdf16e73d),LL(0xf96f2c30,0xd5796183),LL(0x3f70dd7c,0xd13ee9f7),LL(0xdac738c5,0x3f9aa0dd), LL(0xad021e28,0xa200c7e4),LL(0x08414fd0,0x982abae3),LL(0xc3779882,0x76d16a8c),LL(0xe70a6ff5,0x41563d33), + LL(0x4b553a17,0xdbb9656e),LL(0xd9c87aa1,0x96af21a0),LL(0x7bd9a625,0x2de13a03),LL(0xfeb1fec2,0x29f8c49b), LL(0x1a4ce44a,0x84e2df47),LL(0x548b39ee,0x83bb2965),LL(0x94d996eb,0x38b91cce),LL(0x9441ae0b,0x41e0a3cd), + LL(0xdaa92f34,0x720d30d8),LL(0x06f30fbb,0xba587579),LL(0x4c96ad59,0x24f74676),LL(0x0d33bd5f,0xf40493f7), LL(0x126a7267,0x9068c3e9),LL(0x18927490,0xa51099df),LL(0xa9cfe02f,0x27452423),LL(0xb8749653,0xcfd035be), + LL(0xfda6a4a9,0x0dd9bc2a),LL(0x0106ae0e,0xdba0178a),LL(0x4969a4bb,0x3820c9f5),LL(0x99fbc715,0x5031e9fd), LL(0xc193d942,0x642a030a),LL(0x454cbb39,0xdc3d6ab7),LL(0x1c8fa77c,0x507c17b9),LL(0xe3642a95,0x8465bcc8), +}, +/* digit=32 base_pwr=2^224 */ +{ + LL(0xc25dfad3,0xe74e265b),LL(0x493f44b6,0xd03630b9),LL(0xbfd6d473,0xb3270892),LL(0x1c5ee992,0x5b2d9543), LL(0xa36f7c5f,0xeeb94537),LL(0x8ab0b81d,0x9befc01d),LL(0x188b45e5,0x483cdb08),LL(0x01e4648b,0x44c753b7), + LL(0xb2411618,0xee43bc87),LL(0xf07924c4,0x08754bd2),LL(0x4ac92557,0xef205033),LL(0xee0387f4,0x6e7e4fe6), LL(0x76961d0e,0x51f3e2e2),LL(0x37eac10f,0x2b69d417),LL(0x73757a88,0x36d0f45f),LL(0x2b0c7d35,0x38b967e5), + LL(0xb31fa779,0x94ba8fc4),LL(0x0f13036e,0x8024dc85),LL(0x82d754b7,0xfda2af63),LL(0xae9ea9ae,0x4a784242), LL(0xf9887947,0x67dd14ab),LL(0xcd555a0a,0x7f2ecfc4),LL(0xf63a46aa,0xb37c4244),LL(0xff71b4b5,0xd032cfc1), + LL(0x6b8a6a97,0x0aef84c1),LL(0x0b2bca36,0xd2e7f3de),LL(0x5b174d43,0x721c6c09),LL(0xd52ccc5b,0x5719cf31), LL(0x3adf9517,0x6c7361f0),LL(0xabe20ff5,0x1e264169),LL(0x69eacc0e,0x01f9d997),LL(0xc2e635d2,0x721eba63), + LL(0x25df8bb5,0x4225e9c8),LL(0xb5752d7e,0x931f721e),LL(0x0a3b281d,0x3c4ed475),LL(0x4a4668be,0xcf927682), LL(0x75b7e90c,0x1b7f358e),LL(0xb7a29b9a,0x06e5c24d),LL(0xa167f2c8,0x0058967a),LL(0xa4ee62d3,0x9f1a6fb9), + LL(0x278291f1,0xca899c4f),LL(0xf4e64c1d,0x69a90324),LL(0x8d62916e,0x46cc5d42),LL(0xec1007cc,0x3c802e65), LL(0x6219cfbb,0xdadcf2aa),LL(0xd10258b2,0x942870dc),LL(0xa5e142af,0x77264e68),LL(0x089cc7a3,0xf25675e2), + LL(0x7336aa16,0x177e8a3b),LL(0xbc5c622c,0x5a92cc2d),LL(0x1789e029,0x33a35a2c),LL(0x4e4d5573,0x6f91306e), LL(0xda0a46f5,0xe5a2a581),LL(0x42640bba,0xfb532bed),LL(0x4a7b3ae4,0x88ff0f11),LL(0xb8ff7a71,0x2223e7b6), + LL(0x5d21d261,0x75933133),LL(0xcabb1fbd,0xa336289a),LL(0x631b3b61,0x797db2f3),LL(0xd7e6a511,0xc2cedb25), LL(0x10355332,0xb8806f34),LL(0x5d0ae37f,0xe5f1fb4a),LL(0x5d17c5c7,0x57cf26a5),LL(0x68c43ec3,0x82e8df47), + LL(0xf86bd784,0x70fa23eb),LL(0x51b0ce75,0x711a9dbb),LL(0x82170008,0x83bb4a90),LL(0x630602dc,0x8f096ee9), LL(0x7f15e77a,0x7d275fc9),LL(0xfe727ec7,0x63516a6a),LL(0x1dce9d38,0x6b06827a),LL(0x023b31c2,0xa01a5382), + LL(0x886209b8,0x12537433),LL(0xc5a11b32,0xb7875fa8),LL(0xbd61176d,0xfa63cb99),LL(0x33378ebb,0xebb204ea), LL(0x70c135f6,0xf29a29a0),LL(0xfa29d69f,0xf53941e9),LL(0x9917da42,0xab97b39a),LL(0x45947ae4,0x4677cfea), + LL(0x0f6dd908,0xd4668cff),LL(0x987e0769,0x48bb09ed),LL(0x8d64b6fd,0x794ed298),LL(0xfac845da,0xaf89d530), LL(0x2d06e70d,0x57445649),LL(0x079e70a7,0xe2a1a8c2),LL(0xf524fc03,0xd2ef1779),LL(0xb137bb1b,0xeaccaacc), + LL(0x5d279f42,0x34d8ed87),LL(0x1cd68904,0x4dd5344c),LL(0x24abd550,0xb558b71d),LL(0x40df135e,0x3728e850), LL(0xcfe86519,0x9329e2b2),LL(0xac74cde2,0x48ad17fb),LL(0x30b388b5,0x2ad61b22),LL(0xfaea71e1,0xebcbc1ad), + LL(0x35990d9d,0x50d7b19e),LL(0x6eb70243,0xb17138e5),LL(0xaa8ae7e6,0xb61618f6),LL(0xabce12c6,0xedee15b0), LL(0xcc7205fc,0xa99ce250),LL(0x69e0d75c,0xe438efc9),LL(0x5084b390,0x1feb6a10),LL(0x9c80d42d,0x7b348954), + LL(0xe4b68140,0x67ac89d5),LL(0xc9b092af,0x34afd23b),LL(0xfe1ad661,0xad65cae9),LL(0xe02d884c,0x4f402947), LL(0x6b1c40c1,0xd0a48fcc),LL(0x8961487b,0xf950c9f7),LL(0x206d1752,0xdb1cd811),LL(0xe99fd891,0x863b0ded), + LL(0xbb2a4515,0xd3aad8c2),LL(0x797e223c,0xc93c8cb8),LL(0x12a77d46,0x0f471e49),LL(0x600872b6,0xa2ac9434), LL(0x915f730b,0x6fb1c7ef),LL(0xd254d363,0x9fb72401),LL(0x6b44796a,0xf521e33a),LL(0x97c9fafb,0xb7ed2e8d), + LL(0xffb5e7ce,0x60d41128),LL(0xaecb96c2,0xdbd8b542),LL(0x0b5ca788,0x029ab3dd),LL(0x190eb38c,0x8b1148a2), LL(0x69fb1924,0x59048db8),LL(0xb18391a8,0xcd2149f0),LL(0xfed311b9,0x6bece5b6),LL(0x9ffd29b9,0x5edbe9b9), + LL(0x1156ded2,0x53810556),LL(0x721f3e68,0xf812ce5d),LL(0x7ccdc8cb,0x50504d40),LL(0xc60fa4fc,0xb559ba08), LL(0x1d6bd879,0x862a83d9),LL(0x836e26ba,0x2f8f653b),LL(0xeb26ca11,0x8587e6df),LL(0x8c8aaf7b,0x127bd905), + LL(0xd67d9902,0xe26e690d),LL(0xb58e7e78,0x1a6061f4),LL(0x480dd4d1,0x960ef741),LL(0x75589610,0x7fd09736), LL(0x855a8b2b,0x5a20a1a2),LL(0x355b4e0f,0x3ed68662),LL(0xe76595b4,0xd3786f45),LL(0x0bdedcfb,0x72a6999d), + LL(0x6a175646,0x4e48e843),LL(0xe05dc02d,0xde53c427),LL(0x97d31bc6,0x9728a4c5),LL(0x5bb3bd37,0x01a07129), LL(0xa74a0fcc,0x83c08a98),LL(0xbc345df8,0x233e400f),LL(0xcc3e0edb,0x9578c5f2),LL(0xf144a31f,0x0fe89df2), + LL(0x14c5a2cc,0x308098a0),LL(0xba40c0bc,0xeda5a59d),LL(0xb718a5ae,0x0b10f7e0),LL(0x5b8ad9ba,0xdaf7da8c), LL(0x87394cde,0xddc71285),LL(0xe43458d3,0x9bdb27cd),LL(0x4bd7c11c,0xc698d972),LL(0x3540be14,0x2ee97fbc), + LL(0x72f98422,0x2c704995),LL(0xef8661c5,0xfc71fee2),LL(0xce08043e,0x6574e022),LL(0x5143733c,0x3d17162e), LL(0x730e5b80,0x3bf0b448),LL(0x7cf94b5e,0x56de346a),LL(0x6c797797,0xfa87a53e),LL(0x6487d014,0xe8b9edfa), + LL(0x7be60b03,0x09e74387),LL(0xec8750db,0x2277ebc3),LL(0x7aeaa545,0xf1e9d594),LL(0x44c03394,0x41564562), LL(0x4de9f7ec,0x57943adc),LL(0x2a220cd5,0x09dd58f9),LL(0x06973808,0xdf848ec8),LL(0xd3950024,0xf1d5def1), + LL(0x5a8707e5,0xd089eba5),LL(0xb0b90ebe,0x914046cb),LL(0x63fe6bc2,0xb01180b2),LL(0x7ede9d83,0x1ffbc968), LL(0x3c52c09f,0xe16d336f),LL(0xdf40338d,0x32270ecb),LL(0x7eec7039,0xb55ff5c6),LL(0x38a63fab,0xb5ffb314), + LL(0xee18ffec,0x3e9f284f),LL(0x1d1b4e80,0x702d97f5),LL(0x214c4da1,0x2005ee57),LL(0x2f5ea2f4,0x1c210413), LL(0xa4149949,0xd24a486c),LL(0x23c8e201,0x3869a339),LL(0x0149992e,0x00f6e410),LL(0xf0a367dd,0x54e97b46), + LL(0xe169de5c,0xd967726c),LL(0x6a0fcd03,0xa3e81f93),LL(0xdb1b1733,0x171faa9d),LL(0x3828e41b,0x0bbb5e91), LL(0xf0828387,0x789a7b2e),LL(0xfca60b9b,0x9465cc16),LL(0xab630d23,0xcb58e90a),LL(0xa339d4b4,0xe7d30293), + LL(0x18e75428,0x0bcac958),LL(0x9a95900a,0xd2f1554a),LL(0x03846833,0xc63c2afb),LL(0x6d1e8753,0x703d0220), LL(0x04a357a2,0x47f5fe57),LL(0xcdc17255,0xaafba53e),LL(0x821af8d5,0x8f94c8eb),LL(0x35e37920,0x4d9918bc), + LL(0xe32dd067,0xc029bd84),LL(0xf77f8962,0x25982357),LL(0x510b7cfb,0x7af256ca),LL(0x446925d7,0xca397f37), LL(0xe0614e1e,0xb3dc7be5),LL(0xbbc4cc93,0x3b64cd27),LL(0xfb99bbc9,0xbd762df5),LL(0x04d7177f,0xc1ef0d4d), + LL(0x65e75ed6,0x77b6d3d6),LL(0x53053b45,0xbe59c8da),LL(0x54fe92cc,0x054d089f),LL(0x6fa4758f,0x2f2327e0), LL(0x5d2b5a01,0x948cf03f),LL(0x9c23b83e,0x47544c4c),LL(0x6c128d69,0x338590fa),LL(0x76842160,0x5724008d), + LL(0xc4f063e6,0x4cbeb18e),LL(0x9c2f826c,0x507ba094),LL(0x6f4e49f3,0x0e877a6e),LL(0x34f56868,0x050c2040), LL(0x0f119e25,0x8fd667c4),LL(0x13b47d3f,0x881dd34d),LL(0xca8e9a6a,0x2a6b636d),LL(0x107ea18c,0x67b081fb), + LL(0x84af55d9,0xd3a46367),LL(0xd7626b67,0x0e709a00),LL(0x4c6dfc8e,0x135725fa),LL(0x133a6e20,0xbf6328d9), LL(0xa87031f2,0xa4b743b4),LL(0x13825d07,0x62e90e67),LL(0xb85f3c45,0x7004028e),LL(0x11751be0,0x0465c502), + LL(0x8a5ab076,0x4d5d467f),LL(0xf4fb8a45,0x9aa3f414),LL(0x5dc1fa84,0x9fa0422e),LL(0xd02cfd2b,0x3205c05f), LL(0x078836b6,0x3eac28fa),LL(0xfc3ff573,0x53bc0189),LL(0x00b02100,0x2c45ef09),LL(0x34360ef7,0x61bc02ae), + LL(0x532e8d6a,0xeb5593e7),LL(0xf02a1ee4,0x94092904),LL(0x200496c0,0x379b32e8),LL(0x360a27c8,0x46fb6e9e), LL(0x62005158,0x8a3377ba),LL(0x0de3f191,0x1a3266c1),LL(0xc94d2127,0xe60fad96),LL(0x646302f3,0x41553dd1), + LL(0x377e0766,0x88bf0bfa),LL(0xe75bf57b,0x870a24db),LL(0x79e77976,0xc133cb49),LL(0xf43b6f18,0x2f14924d), LL(0xaa94cd73,0xe561dc90),LL(0xd6eb695d,0x8c420eb2),LL(0x2f04ef79,0x99e41ba8),LL(0x71e6d054,0x7f427bdf), + LL(0x10bde8ce,0x7304bb25),LL(0xe48b16f8,0x5dbc4325),LL(0x8796db7b,0x47d17ab2),LL(0x94c77832,0x83426817), LL(0x9878ace2,0x6781850e),LL(0x019e97aa,0x7f747b90),LL(0x949f9b08,0xa0545c85),LL(0x244bc083,0xe0a0bbf8), + LL(0xa1f38ea6,0x8cb53666),LL(0x4989a568,0x9be29ff6),LL(0x083a7fcd,0xbc5a7f87),LL(0x44ca10f6,0x90d0129c), LL(0xd724b7e2,0x1ad274bb),LL(0xcad5f069,0xa5290cbd),LL(0x86a4e0a9,0x886b1a7c),LL(0x8d8fb13f,0xd2481b5a), + LL(0x4f606ac5,0x80075fb2),LL(0xbfc10e7f,0xf984b5a2),LL(0xf056142f,0xd3d91aea),LL(0x4afdc017,0x770bee0b), LL(0x6c49c827,0x3c42ca88),LL(0x0aaa3139,0xb620c4e8),LL(0xad87890c,0xac6b512d),LL(0x0eb61f92,0xaee62df7), + LL(0x21dad9ec,0xcf0f37fc),LL(0xc52e24c1,0xd780d315),LL(0x23a2b699,0x0263bcab),LL(0x9714b577,0xdc8dcd2f), LL(0x55622b11,0xeb16eca8),LL(0x01118edf,0x94b3d649),LL(0xec66879d,0x6bafea64),LL(0xc4ab9f48,0xc35739c0), + LL(0xf3232370,0x082ccf53),LL(0x71407825,0x01b55dd3),LL(0x4f7f4038,0x86e0fe94),LL(0xb04159e9,0x1a623675), LL(0xbc4df337,0xf908ca59),LL(0x816162ce,0x1b4f1ffe),LL(0x2d60e05b,0xb5128952),LL(0xd38cbdf7,0xb47ca0eb), + LL(0x8ee38219,0xdccba22f),LL(0x9fbb36ff,0xc9436453),LL(0x8ac12c9d,0x83cecbf5),LL(0xf4cb1ebf,0x591191b5), LL(0xf03c1632,0x693cf383),LL(0xcb6abaca,0xaebd3f9b),LL(0x0fa26e7a,0x1427c154),LL(0x01bf37af,0x4f0de894), + LL(0xd88da2a6,0x4e497acf),LL(0xe5c86482,0x8014a215),LL(0xcf94ee40,0xa627d78f),LL(0x9ca36aa3,0x7647708d), LL(0x87e108c8,0x3d4e8bb1),LL(0x516f8b28,0xacdc3223),LL(0x1d955038,0x74e4d436),LL(0xedd68905,0x7e4a198c), + LL(0xc4bfbad1,0x41dc4bdb),LL(0x85964942,0xfd1121b1),LL(0x0c0d85ff,0xe462eb9c),LL(0x2b012d88,0xade1ccb3), LL(0x318f2aa3,0x2eec3503),LL(0xdec8a13e,0x656b44da),LL(0xcda13a8c,0x90b7aac8),LL(0x214a530f,0xe7f3a5ff), + LL(0x159060b9,0xa0c8062a),LL(0xd9305873,0xc19f2608),LL(0xc9609521,0x0d6213c4),LL(0x9aec4539,0xde2b9134), LL(0xaeddf0a6,0x4a2a6476),LL(0x5cf2e85d,0x89222dff),LL(0x084a0245,0xad92a1d3),LL(0x2138063f,0x29644a60), + LL(0xb8164832,0x5b57a05b),LL(0x885ce4d1,0xecf6620f),LL(0x045d3b88,0xde28ed2f),LL(0xb4502308,0x3eb11759), LL(0x4d9f94b8,0xe97f1db2),LL(0xeb83f016,0xfa248583),LL(0xcda53ba0,0x63a273b4),LL(0xa228b7b9,0x9692973a), + LL(0xb6707cbd,0x5968cb12),LL(0x5c1a2b4d,0x1895ccb4),LL(0x37f0b240,0xff309157),LL(0xb90875c2,0x374d983e), LL(0xc4e815e7,0x22fc40c6),LL(0x98d18506,0xf2db27be),LL(0xaa9ae62e,0x2854a948),LL(0x79e39df1,0xd614a722), + LL(0xb3501c19,0xebeec551),LL(0xd89cefca,0xe2b878eb),LL(0x6b4cd6bc,0xa0a34757),LL(0x70bfdf88,0x0159129c), LL(0x489502ca,0x26fa3e53),LL(0x285be050,0x7932084f),LL(0x71912b0c,0xfe4998f4),LL(0xc60b88b7,0x3dce0a87), + LL(0xc718ee5c,0x5b93edb0),LL(0xbb075836,0xb93a225f),LL(0x7aa0595c,0x87a08c94),LL(0xc31e3249,0x401d2620), LL(0xdae2cdb9,0xbe6928b4),LL(0x5a226630,0x4b68e106),LL(0xc9d32e4f,0xdc38c2fc),LL(0x26542f89,0xc51a6245), + LL(0x1757f3c4,0x5fb37c1b),LL(0x89128aa4,0xa27d6c02),LL(0x5e629309,0x3b74f56f),LL(0x2f7aeef2,0x24b5ad84), LL(0xbdc89596,0x54a962cc),LL(0xcc2f3d5d,0x6e8bccf8),LL(0x312e9241,0x4c1df22c),LL(0xfc30f0dc,0x8ffe6b0d), + LL(0xa6ec0fe4,0x670431a2),LL(0x35964572,0x49da0b42),LL(0x9dda5c39,0xbb12d1b0),LL(0x72d3de51,0x64170fe1), LL(0xa4a2f5d9,0xea8b2b16),LL(0xe590be92,0xde1bad64),LL(0xf0b9b0b5,0xb7f93581),LL(0xe115d67e,0xb007f4dd), + LL(0x415732d4,0xab9d7523),LL(0x905ec0fe,0x2951149d),LL(0x74350478,0x94bb2c63),LL(0xe9b1ada4,0xe6b63bfd), LL(0x13e8528f,0xd09b4d4b),LL(0x685bf239,0x6bed3d25),LL(0x1a14b7ce,0x83023ad9),LL(0xd0505d6b,0x4bffff63), + LL(0x8bb1cfa0,0x2ccc180a),LL(0x3a09c912,0x70c18508),LL(0x5878201c,0x318c41c2),LL(0x64c01149,0xb9f207b1), LL(0xc58287d9,0x89fdd9ee),LL(0x05c43da0,0xdb6fa8db),LL(0x311a34a1,0xc31354f0),LL(0xf1521976,0xccfbaddb), + LL(0x0c5e8388,0xf4175f75),LL(0xa81226cf,0x7e090ce8),LL(0xeda6a1ab,0x5209107e),LL(0x7e5ccefd,0xf0a263cb), LL(0x10c704a1,0x9fe05a36),LL(0xcf133aee,0x3784d7ca),LL(0x37af86c8,0x066c3116),LL(0xd7ebeb8a,0xbf32ca04), + LL(0xa9b5bab4,0x0447a950),LL(0x41bb1f1c,0x3b2f98bd),LL(0x59c62f08,0xd89bbdd7),LL(0x3ded069b,0x26bab370), LL(0x69ea63ae,0xb0db4ca5),LL(0x9133df68,0x57b32f32),LL(0x5a17efbe,0xc79a22d0),LL(0xf8ae3c2d,0x576976a3), + LL(0x9d02d212,0x5754198b),LL(0x230d0213,0x9cc9e61e),LL(0x92889e33,0x76772179),LL(0xf5df6cba,0xb1246608), LL(0x8d491280,0x821766bc),LL(0x96bd3df5,0xe148f470),LL(0xed753b73,0xc1e9fc70),LL(0xd6cecfc5,0x840e40ed), + LL(0x93e2f3a0,0x03874679),LL(0x5b646b64,0x462e5abf),LL(0xd7ae0e67,0x6fb19eda),LL(0xc3d2dddf,0x01e8a27f), LL(0x4bacfe2d,0xc9e69639),LL(0x712e8afb,0xbc3a134e),LL(0x8af6d30f,0x5d943a86),LL(0x443c942c,0x65eb5f99), + LL(0x2339e348,0xf5000308),LL(0xeb0d80e6,0xd69b7693),LL(0x5b9d220b,0x7b00b43b),LL(0x497bbcf9,0xde0dfc80), LL(0x0c2e851f,0xcfe2e3f3),LL(0x7e91d378,0xef7793d1),LL(0x9d266a5b,0x9e43eeac),LL(0x1766c5c1,0x9c81d68b), + LL(0xf6a4d560,0x121db320),LL(0x073582a7,0xcd0a4f03),LL(0x6e841041,0xbf469f9a),LL(0x5eb2d753,0x4314f0f6), LL(0x8c498414,0x09021001),LL(0x859275b7,0xf63d00ee),LL(0xf1c0385a,0x228fa809),LL(0x694c3318,0x44259d51), + LL(0xa2ad4eac,0xb0a5d5fe),LL(0xabdedf11,0xbb950010),LL(0x6264c601,0x081024ce),LL(0xaefb4115,0x6cc7faf2), LL(0x8692a7a4,0x90511289),LL(0x60596012,0x2bef4135),LL(0x0f0becb6,0xfec5209a),LL(0xd1ceb42e,0xad0907a6), + LL(0xf517372c,0x6cde3f21),LL(0x26131459,0x9acd4f09),LL(0x491f59d7,0xf3629a43),LL(0x41a037dd,0xe944561a), LL(0x826d1b5c,0x07beeabe),LL(0x3a1476cd,0x0728a907),LL(0x7d4a1abf,0xa91f41a0),LL(0xa7a119c4,0xdf58ed06), + LL(0xba701704,0x19990669),LL(0x47b67175,0x8aa3f76b),LL(0xdd0a6e9a,0x8bccff3e),LL(0x24f49029,0x4173fcda), LL(0x61c18233,0x2a688911),LL(0x78b9fa8f,0xdf54b239),LL(0x37596f40,0x714cf627),LL(0x24e6a879,0x2c73ddba), + LL(0xf2547f19,0x1538fd36),LL(0x0e7e84ee,0xd85c4730),LL(0x306f5fc0,0x00799e9f),LL(0x49ce114c,0xfccc6a37), LL(0x3fe08120,0xf9cff5e8),LL(0xc2be9f27,0xdf876a1f),LL(0x6939fdb9,0xe817c72e),LL(0xd34d0e43,0x244a1800), + LL(0x78fa7f11,0x41e83eef),LL(0xba6367e5,0xecaa250c),LL(0x8def6ae6,0x9c420347),LL(0x250b9e58,0x99efb3b1), LL(0x79b2298c,0xdaf311ee),LL(0x69b6dff3,0xb49200cf),LL(0x559e51f5,0x5c7f17bb),LL(0x424be7e9,0x117d0cbe), + LL(0x36e3af54,0x290a35c4),LL(0xe3a643b1,0xd2326cd8),LL(0x3580f9ee,0xc208b2b3),LL(0x4464a9e0,0x2419c661), LL(0xbccb2759,0x87123d3a),LL(0x1a77d469,0x5d36fcf3),LL(0x49b07e5a,0x5aafd58a),LL(0x6b71e237,0xf534595b), + LL(0x6705039f,0x0f0d3161),LL(0xca701676,0x7282b08c),LL(0x13796941,0xb05e8c3e),LL(0xfca06e08,0x5250012e), LL(0x980c5ea3,0x7eb2341a),LL(0xa41defb2,0x92f5aeb1),LL(0x0e62453f,0x203244e0),LL(0x96181756,0x74341218), + LL(0xe12a94ab,0x3b0cd36f),LL(0xb5ad7c48,0xf364b3b9),LL(0x8e768469,0x96a7a2a7),LL(0x1bbc7cc5,0xccc31c7e), LL(0x080dbb92,0xe70ad5d0),LL(0x56fb0f1f,0xfb201e92),LL(0x29d99f57,0xdfce7a1e),LL(0x06457da5,0xc12a02b0), +}, +/* digit=33 base_pwr=2^231 */ +{ + LL(0x2a80f39c,0xdea72ba6),LL(0x68cbe088,0xcb2174b1),LL(0xd6bd1cc1,0x9c73ec69),LL(0xf20dcce6,0x6a2dbe20), LL(0xeeaae9da,0x20a5150b),LL(0x9df630da,0xc935e85d),LL(0xa1634cd8,0x2147144f),LL(0x44f3af02,0x5eccb56c), + LL(0xc0e2b70a,0xf77a79cf),LL(0xee8cbae7,0x2569c8bc),LL(0xfadb18fc,0x392a5dbe),LL(0x3ce6a0ff,0x59bc96b4), LL(0x8b551005,0x287f04f4),LL(0xa44b2bd8,0x7efe3aa5),LL(0x6ac447d7,0x0e9cb8ed),LL(0x7783bdd0,0x9b4eb10a), + LL(0xb981d96f,0x793c4880),LL(0xd56fb2a6,0xf719d828),LL(0x8149057e,0x9fcc236f),LL(0xb4d65c2b,0x318c63ec), LL(0x5f95c5de,0x5269c1d7),LL(0xd0efd6bc,0x33b3745f),LL(0x4ae87c64,0xace344d5),LL(0xdd30ba2c,0x238809d6), + LL(0x71192348,0x3cc32acc),LL(0x3f17ef60,0x545401bf),LL(0xcde25b0e,0xe209a493),LL(0x663abab9,0x5c11886b), LL(0x28ec7c90,0xe61a81b1),LL(0x75b57f5c,0x18b125a6),LL(0xfad91696,0x86d1b45a),LL(0xa4c3f7ff,0xb31a786d), + LL(0xf45831d8,0x2fd4cd72),LL(0x8be40d9f,0x85978fa6),LL(0xa9301111,0x38106329),LL(0x9e5979ee,0x1527e462), LL(0x76c5fc8a,0x97f71c7e),LL(0xf1f33056,0x205fa473),LL(0xa6546a05,0x7bb9d24e),LL(0xf84c4d35,0x0e282a5c), + LL(0x59471f1f,0x59d21896),LL(0xf6303573,0x2e613dec),LL(0x78bf5a4b,0xa7995794),LL(0xbf19fbe5,0x20adf6b5), LL(0x1574d34d,0x3a48c95f),LL(0x09323ceb,0x95488f09),LL(0x552df9cf,0x450aee7f),LL(0x53557500,0xdf016f7a), + LL(0x2da8a2a6,0xf2acedc6),LL(0x2f4a0632,0x03fc8cf8),LL(0x5b82f03a,0xe7ff136b),LL(0x9e88c421,0xd5841c4d), LL(0x7eef63f0,0x75a4d66f),LL(0x2865c14b,0x92091ade),LL(0x64fe7ba3,0x7060474c),LL(0xfe30cb3e,0x4056724c), + LL(0x8d9fceb6,0x38cf4c6f),LL(0xab528f38,0x11e85f78),LL(0x52303b2b,0xe2896d25),LL(0xed68c605,0xf929675a), LL(0x10c708a9,0xfbd22374),LL(0x40d7e5a7,0x4682ca17),LL(0x9041047f,0x4242b5c5),LL(0x0f9c6840,0xaf571053), + LL(0xa56af433,0x713b2bbb),LL(0x5e82f947,0x45aaf2ce),LL(0x106283c7,0x9882571a),LL(0x9b9c3c3c,0x37de12ca), LL(0xbef10529,0xcb463af2),LL(0xd771236c,0xe18d763d),LL(0x62935de3,0xb47a69ca),LL(0x9a41e09a,0x4798e91f), + LL(0x8e93edd5,0x89696697),LL(0xb7ea4f45,0x35cdb8e1),LL(0xfed33d87,0x36f8305d),LL(0x625642d6,0x57623440), LL(0x945dd7d6,0xdfd9b580),LL(0x731739bc,0x965ffcb5),LL(0x637bf127,0x34588e1f),LL(0x539d21c7,0x936c0ba0), + LL(0x71640eed,0x70832099),LL(0x3ff407e3,0x916b1952),LL(0x88440bc0,0x4cd58881),LL(0xc280e977,0xd9fcb83d), LL(0xdf6cda83,0x0d3df9db),LL(0x3d55047e,0xc629414e),LL(0xc16b84c9,0xe05738a8),LL(0xe8783570,0xf4bdc724), + LL(0x9a93a5c9,0x7d876a59),LL(0xa8d12f61,0x026be75c),LL(0xe9b2aa43,0xe49900ed),LL(0xb3a68dad,0x44d6dc80), LL(0x7d23e11b,0xf96b116b),LL(0xb6814209,0x12791212),LL(0x6cc65956,0x3e2807cf),LL(0xf405ffae,0xcc606ca7), + LL(0x5df47226,0x5484b2c5),LL(0x8802da81,0xfbaf9042),LL(0x087adadc,0x84146315),LL(0x58d593b3,0x6adbcbc1), LL(0x68b97533,0xc1fb3896),LL(0x954cc1b7,0xa6919aac),LL(0x27a4ddd0,0xf301b2e4),LL(0xdf1a07b1,0xa15c16eb), + LL(0xc145a6c7,0xb36c017d),LL(0x968798da,0xcca64382),LL(0x8d0eff5d,0xd13b6376),LL(0x2206e681,0x06e39e2d), LL(0x3add517a,0x1d9dffa4),LL(0x10d95fef,0xe670e6c8),LL(0xf1c7c7a8,0x0ecb51ab),LL(0x74945305,0xf17dff51), + LL(0xb00d9c0f,0xf71b09b1),LL(0x9c72c80a,0xc719cf62),LL(0xe00a49a1,0x310c5aeb),LL(0x1b33c5e6,0xd01285e5), LL(0x05aa6eb7,0x7b23e7c7),LL(0x6bc88677,0xf84188b1),LL(0x64be321a,0x7e034cb5),LL(0xe884323f,0x270df734), + LL(0xe5137d20,0x218e68f9),LL(0x0f7e70ad,0x79588cba),LL(0x58b86b0a,0xb6d37f52),LL(0x7cc591fe,0xcb281c98), LL(0x8fe40e06,0x30e03fed),LL(0xed9ca793,0x394ded95),LL(0xbcd3a3da,0xf1d22cdd),LL(0x0c591130,0xcb88cb27), + LL(0x8ff0cbf4,0x67786ba3),LL(0x0565d337,0x85738a44),LL(0xaf9a667b,0x9d3b35ec),LL(0x8f5f540a,0x45a17512), LL(0xade5a5ba,0xf1ae5171),LL(0x39869be4,0x720e2823),LL(0x5352d84b,0x6893f14a),LL(0xc784dc20,0x919a4f15), + LL(0xf7ae5a67,0x36136612),LL(0xeaff0924,0x11f43d1c),LL(0x39449b96,0xcfee088c),LL(0x70c42ff6,0x3dc48359), LL(0xbf208b67,0x4072683a),LL(0xbe15d18f,0x35a7c2be),LL(0xe2c3391b,0xe61d2748),LL(0x39921d95,0x0a4109b1), + LL(0x05545cfc,0xe2cd131b),LL(0x3ae20d7f,0xa898da2c),LL(0x50dc4c61,0x501cd849),LL(0x3374e7f0,0x10e287d4), LL(0x38aea879,0x90d6326f),LL(0xef43fa08,0xc48d9af7),LL(0x6c20f168,0xf8f4886a),LL(0x23ccac4b,0xc5d34a86), + LL(0xb3d7004e,0x72357752),LL(0x817bd377,0x167db0ed),LL(0xdfb64d05,0x5d45b3da),LL(0xf0b414ac,0xed4b7fc4), LL(0x0bf1dd64,0xc178941b),LL(0x8fe835a5,0x43feac17),LL(0x6a014609,0xe1c23a17),LL(0xd5e23bd5,0x63255991), + LL(0xd7dfec55,0xefc76468),LL(0xc0831696,0xb1bc3fee),LL(0x5f52433b,0x0996811b),LL(0x799649fc,0x6b8b6daa), LL(0xab518b64,0x6e9f7cb6),LL(0x38a3a2ab,0x6a67a009),LL(0x928209e2,0xe55de954),LL(0x3da81142,0x98b6d0a7), + LL(0xe3f832e8,0xdec30331),LL(0xe50fa9e3,0xa9b77f3b),LL(0x5167c6a6,0x20febc21),LL(0x76fb0f13,0x0ce07d1a), LL(0xe796f8a3,0x9745dead),LL(0xd95deba6,0x2cb4eb1f),LL(0x4caf2afe,0x062e7cac),LL(0x16ace879,0xf50ce065), + LL(0x1d99d3e7,0xdec8954b),LL(0xa48262c7,0x5287e954),LL(0xcc3530de,0x1c6fbd17),LL(0x53af4211,0x6bcbea50), LL(0x4dce058d,0xe3533bca),LL(0xfc9cdf00,0x6fe62e64),LL(0xe8ec4cf9,0xee29fdec),LL(0xc8d52f80,0x7361797d), + LL(0xf4e36023,0xb1d858da),LL(0x73e6dee1,0x4a1282ce),LL(0xce1d71cc,0x6ba8f8ba),LL(0xcbbd8eb9,0xf5b7d6b4), LL(0x5aed382b,0x60f8bd50),LL(0x3f3a46b1,0x47b40519),LL(0x8a997d93,0xaed13bb9),LL(0x4dc6e35d,0x6cc2260e), + LL(0xccf915d9,0x173bfcdd),LL(0xc2d46f6e,0xad4525e1),LL(0xcdd2382b,0xb7ecec0b),LL(0xd2b76c84,0x01ae8291), LL(0xbec6b980,0x2d1e2a91),LL(0x7008a00c,0x1b0040be),LL(0x7d555120,0x6ac708d7),LL(0x0d745eef,0xa6017568), + LL(0x1ed38ef4,0x735e3511),LL(0xcebe5a8c,0x7c97f284),LL(0x24fecbac,0xd4059313),LL(0xde18c42c,0xf874ca4b), LL(0xdbb829b6,0x9ab736a8),LL(0x82ff128d,0xe914bdde),LL(0xfd0f362b,0x6e949bab),LL(0xffea2e79,0x275824cf), + LL(0x8cc52417,0x81f57245),LL(0x2f274090,0xed0a9079),LL(0xfdd0ba2f,0x98c3372e),LL(0x3ae99478,0x49820f41), LL(0xce373d3e,0x1c47e09f),LL(0x6dd12846,0x875d7920),LL(0x15d5bbb1,0x7a9e7973),LL(0x6d227962,0x48512656), + LL(0x199241e3,0x2c167c88),LL(0x7209ca37,0x98c1df6a),LL(0xde89e412,0x09a1583f),LL(0xc792de48,0xc19ed5b9), LL(0x74dc0834,0xb8dd1b1d),LL(0xa04456e9,0x9d458529),LL(0xad0ad39d,0x66ef5463),LL(0xe641edc5,0x8d7df4a1), + LL(0x6bd322e4,0x97815de2),LL(0xc1f77fb3,0x0bf6fc83),LL(0x8b4f7152,0x49378167),LL(0xbf0a1712,0xfdd476ef), LL(0xf2f9883a,0xe87e1977),LL(0x9ad2d034,0xdbb2fcbf),LL(0x64e1a4c6,0x5afdd161),LL(0x3e435191,0x0e43f911), + LL(0x42253804,0xde2d1ee6),LL(0xdaf13e57,0x6def6ceb),LL(0x05423bab,0xae09fd4f),LL(0xad46e409,0x6f6c17b8), LL(0x6c345cd3,0x966fa09d),LL(0x47abc35d,0x6c8aa1e9),LL(0xe015a566,0x02991686),LL(0xcd2f925d,0x39b3aeee), + LL(0x9119c117,0xf9cda92a),LL(0xf4f833e1,0x7b21ce82),LL(0xe4f99193,0x87517bf5),LL(0x4eb412f9,0x1b7ddec9), LL(0x6b077498,0x7a30dd57),LL(0x0ec44230,0xe060625f),LL(0xb0e5446b,0x0f355dc4),LL(0xbbd2df28,0xdf324d65), + LL(0x649966a5,0x28c7eb34),LL(0x26639e19,0x97587f4f),LL(0x0bce0f38,0x0724cc00),LL(0x4ae6280a,0x63578add), LL(0xc7fd6a1a,0xf1beaa57),LL(0x7b017e35,0x83b1a533),LL(0xefdf2ed1,0x01c027e3),LL(0xd2d31852,0xf373d4ea), + LL(0x65b8f5d7,0xe568acb6),LL(0x1240a545,0xea8ce1b8),LL(0x555fac44,0xb95b0db2),LL(0x768333dc,0x01d18170), LL(0xab1798ad,0xf938b55e),LL(0x999a7e5b,0x73a0d9dd),LL(0x57fd9b51,0xd2359bb5),LL(0x77fb4e5e,0x20f1d4fd), + LL(0x932dc388,0xf5efd71f),LL(0x21a37385,0x40f86819),LL(0xff935ef3,0x05395fb2),LL(0x1b615e8e,0xc2ee43ac), LL(0xe82d509a,0xa3bb6518),LL(0x30b93347,0x3a87d5a2),LL(0x5b130bcc,0xac0a5ad0),LL(0x9154d73a,0x91fe8fdd), + LL(0xdeb203a2,0x677d7d48),LL(0x8b0168e1,0x4d4108fe),LL(0xddc3d24c,0x16be4ad1),LL(0x9865df69,0x9b0ea387), LL(0x4c50ec70,0x16daf932),LL(0x478c96a3,0xa4799bda),LL(0x7114d3bb,0x4ef24d3f),LL(0x46e6bbdc,0x30a31509), + LL(0x97f3cb4b,0x60137187),LL(0x0a29d865,0xf2b66d8f),LL(0x60064a5c,0x93a4a37a),LL(0xe8c3cf47,0x7dee9bed), LL(0x0b7ee8b8,0x748833ce),LL(0x56f89483,0xc07f2f6d),LL(0xd24b406f,0xd71a40d8),LL(0xebbb7655,0xbe3b2e8f), + LL(0x4a536998,0xa23c2b05),LL(0xa9be2e14,0xdcaf45b3),LL(0xfe346ad1,0x515ad15f),LL(0xb7847640,0xb9c06a18), LL(0xf35bff4a,0x8552eb06),LL(0x2b7a29f5,0x4fb792e7),LL(0xa41a38b4,0x1cce2af5),LL(0x02b42414,0xde68bd0d), + LL(0x7cd66728,0x8124d6e2),LL(0x55efbadd,0x5906d1b4),LL(0x827f2741,0x7e17855a),LL(0x12c6966c,0xab525dfb), LL(0x758e0cd3,0x065ae99a),LL(0x517318a9,0x0dcb8f5d),LL(0x42441f5e,0x48756645),LL(0xd79d535e,0x03859154), + LL(0x8217e4bf,0x99bb28cd),LL(0x8291e54d,0xd6aed2e5),LL(0x1c92a65e,0x8f9067e3),LL(0x1540b9b5,0x120890ea), LL(0xec60a215,0x227d7c86),LL(0x556d8c65,0xb6609e85),LL(0x47f8c8a3,0xa6a26c37),LL(0xf1204bdc,0x4c850fe3), + LL(0x42db4eb8,0x25f7e61a),LL(0x3d62869d,0xfdf05575),LL(0x52b31c23,0x8b36a744),LL(0x1a5e8d4c,0x83b83c89), LL(0x5d9208bf,0x72d38dd3),LL(0x8cf7b6f4,0xbeb8873b),LL(0xcf90bcb6,0xa3ec5c36),LL(0x9a6d5fe7,0x35adda6f), + LL(0xf61c68d9,0x7312423d),LL(0x20bcaf77,0xb1c4e10f),LL(0xf168ee57,0x4df2850d),LL(0x180985e1,0xed07a4de), LL(0x2fba1f23,0xcb353d6b),LL(0x778cc15e,0x00ea9094),LL(0x20857170,0x4967faaa),LL(0xd7153bc4,0x9ff70dbe), + LL(0x59f62fc6,0x49eb7994),LL(0x3c91862d,0x5f459faf),LL(0x46d8f2e0,0x1c10f621),LL(0x252954e7,0x7e669c9a), LL(0xa83f6c57,0x4ccf659a),LL(0xec0a0a03,0xdc2b77eb),LL(0x2cc6b8a2,0xcf09ad07),LL(0xa97aa2d0,0x231960fc), + LL(0xde227de8,0xc0609130),LL(0xf1d7ddf1,0x40d2691c),LL(0xf9a73890,0x60349cf4),LL(0xf9968132,0x3f50005d), LL(0xf16f44b9,0xb4be853e),LL(0x799caac5,0x48bf4804),LL(0x3c562849,0xe6a64876),LL(0x854f283f,0x2f4d487f), + LL(0x159484c4,0x64b77e39),LL(0x523e1529,0xd419d4bd),LL(0x143dcf7d,0x1bf9510c),LL(0xed5cb4e1,0xa85bea71), LL(0xec715818,0x73a4cfd2),LL(0x67f475f5,0x88b11d0e),LL(0x4d12361c,0xbfe170d8),LL(0x00a0f979,0x9fc48e64), + LL(0x65682105,0x6a8bb2dd),LL(0x00bd952a,0xc1362a9c),LL(0xa6013753,0xef5b3d89),LL(0x8fdfa22a,0xc87bbacb), LL(0x31bb19e4,0x74fbdfc0),LL(0x32bfe260,0x7d058029),LL(0xe53da990,0x54a4cce4),LL(0x822da672,0x01acdff6), + LL(0x95597766,0xd2a2d484),LL(0xd43dc7fd,0x5960ac1f),LL(0x8d6db685,0xcf095b6f),LL(0xa85618f3,0x87232088), LL(0x34753c7c,0x91497a48),LL(0xd6353024,0xf682e372),LL(0x0c9b271c,0x7889ceda),LL(0x18340951,0x7126504e), + LL(0x967c8a60,0xf786b821),LL(0xc17f3d99,0xfce01b37),LL(0x1f2a8575,0xe23c00a1),LL(0xab6ff8a0,0x7f56aa1b), LL(0xd193dfcb,0xdb73869d),LL(0xd644733e,0xbec02c94),LL(0xf7b43261,0x283117bc),LL(0xb4108e39,0x920acf5d), + LL(0xe49aebb8,0x33f1ef5e),LL(0x0fcea2c1,0x9ead51e4),LL(0xf8503f28,0x1f800a68),LL(0x34a75f67,0x78818531), LL(0xb70ffb27,0x1aeb3760),LL(0xcb6309e9,0x1cca590a),LL(0x7170d241,0x8d09f360),LL(0xa0e0d0f8,0xbc970b5b), + LL(0x31d038a3,0x2ec93eea),LL(0x5153f8a2,0x3482a0d7),LL(0x6641b5d8,0xedcbe914),LL(0xe516e387,0xc086e61b), LL(0x9b875513,0x03814266),LL(0x37340a4f,0x6d37fee3),LL(0xe5d17ab7,0xcf78515e),LL(0x4119a759,0x0c7cd830), + LL(0x54924618,0xbd49062b),LL(0x41e7e7a3,0x34c44f45),LL(0x706bd0af,0x0039f3d2),LL(0x0be9a628,0x146cadc6), LL(0x57d48746,0x6d5d5020),LL(0x82caf4b0,0x0ea43f7b),LL(0x8a064d34,0x11a08927),LL(0x95638fa2,0x30c0ef40), + LL(0x602a871b,0x4b950c04),LL(0x6a731537,0xf50cb1ef),LL(0xcbe5e4ef,0xb87a1cd3),LL(0x3dd1c601,0xb1fc4894), LL(0xa516617a,0xdf402711),LL(0xaaf63c65,0x5bdd1d67),LL(0x6e559bd9,0x020d1062),LL(0x81ec09fc,0x4dec26d0), + LL(0xeeeeb2bc,0x7b91fafd),LL(0x33aaf2c4,0x56290f98),LL(0x79c7bf9e,0x57abbd27),LL(0x2b1e1ecf,0x568bdee6), LL(0x470f1d01,0x58f8c80c),LL(0x1b9cb76b,0xeecfe398),LL(0x311a0634,0xc0ffa4de),LL(0x0ae99877,0x425fcd13), + LL(0xf7bd0748,0x1964c681),LL(0x9d920471,0xebcca16f),LL(0xab4aa03e,0xa72b40cb),LL(0xa05624fc,0x4397d6af), LL(0xa94fca0a,0x372d522c),LL(0x3035b9fc,0xe1010d60),LL(0x4f788d44,0x9f1f00cc),LL(0x6a88b672,0xfd00ec75), + LL(0x2983aef7,0x53706702),LL(0x9b458edb,0xa5f67b0b),LL(0x7db93ca8,0x10789b90),LL(0xfd27cd55,0x885346f0), LL(0x2ebb5f15,0x3af5b0c8),LL(0x2a36b2a7,0x282e4c4a),LL(0xa6d88bd4,0x2f9d5d8b),LL(0x9856b7aa,0x6f016bda), + LL(0xa8198c1d,0x990ae53e),LL(0xa07e7ac5,0x295beceb),LL(0x48c2d246,0x576f790f),LL(0xe3ea9864,0xe99ab2ae), LL(0x43e2d400,0xcf4959f2),LL(0x7a39dfea,0xdd1d8fad),LL(0xfcd7fda0,0xdd6ff9c2),LL(0xb6ace55e,0x61c25b3e), + LL(0xb4dcddad,0xf94742af),LL(0x44601959,0xc49cfa21),LL(0x30c18470,0x07b3f1d1),LL(0x6e6afc82,0x2736cb99), LL(0xe24a8785,0x401fb234),LL(0x074f51ea,0x9af8ba40),LL(0xa9faed0c,0xe1acc646),LL(0xc9667008,0xd5a5f789), + LL(0x68c3ab8f,0xc6436514),LL(0xfe8d6b46,0x6fa0d734),LL(0xaf7f49c7,0xe5fccbfc),LL(0xbebcc58c,0x42c88c53), LL(0xe2a0f7f2,0x7d2e2fed),LL(0x36a18b26,0x694eb76c),LL(0x6b0f657b,0xf0e6ae43),LL(0x48f1ece7,0x8a0f6255), + LL(0x8674bfee,0xd594c168),LL(0xac7d5ebd,0xe59ad38d),LL(0x21645a1e,0x080a6b97),LL(0xf221b37b,0xb900f0e1), LL(0x04cab97d,0x562dabce),LL(0x6f472462,0x5c308741),LL(0xc7c4cba8,0xa5d87e23),LL(0x9b061062,0x5237fe16), + LL(0x222021c1,0xeddfbeb4),LL(0x4e7a2a8e,0xa4fe57d0),LL(0x2de56c47,0x0fbf6bdb),LL(0x6fcebc6c,0x819588e7), LL(0xdf041e3a,0x14196961),LL(0x40cd4f23,0x76a31437),LL(0x8e1a877d,0x44acd14d),LL(0x37d7b7de,0x227a35c6), + LL(0x842a9534,0xe1934f1d),LL(0x53ed73e2,0x7a2ed2c1),LL(0x3903924b,0xcffedd58),LL(0xb306431d,0x7c9dbf55), LL(0x56e06ab5,0x61a72f10),LL(0x616bc5cb,0xb46cf5cc),LL(0xf7c22216,0xecf07e10),LL(0xd9364b3a,0xa4bddad9), + LL(0xda8b1c93,0x548b95b2),LL(0xa1e1c0cb,0xc09a9598),LL(0x21d80851,0xedd80ef1),LL(0xc283f047,0x4684c439), LL(0x87333da3,0x07ca41f3),LL(0xca79a8f4,0x173ec4de),LL(0xb4aec6eb,0x89ce06f2),LL(0x15aaf7f0,0xfe6b0e92), + LL(0x7c1b9ed3,0xdab8876d),LL(0xa2606f83,0x88aba90f),LL(0xbebaf9f6,0xcd21a408),LL(0x0042a162,0x09da6696), LL(0x2d66ccf6,0x4a9b8b21),LL(0x44d5a648,0x34c74904),LL(0x3b0e9564,0xf3fe98e9),LL(0x221aa4a5,0xe4a8a352), + LL(0x26c2b53e,0x6278b4b5),LL(0x1b1708ea,0x4ddf26ce),LL(0x6eb0d845,0x704207af),LL(0x0f5862ef,0x60533de3), LL(0xe54393c0,0x2b5945dd),LL(0x145ea298,0x55941df2),LL(0xc240f654,0xe2b500b6),LL(0xcf9f6934,0x5a49d8f1), + LL(0x27502203,0xfe8d5468),LL(0x58ade316,0x985039d4),LL(0x0a687415,0xefd373f1),LL(0x43526774,0xefccb791), LL(0x0f4497d9,0xeef8d46e),LL(0x1601ab9a,0x4152df71),LL(0xe47b2ad1,0x4250cd2f),LL(0xfb048180,0xa2b63fa5), +}, +/* digit=34 base_pwr=2^238 */ +{ + LL(0x787d1f1c,0xd8a6cb6f),LL(0x3d219a66,0x427bac94),LL(0x383146b0,0x51d7d49f),LL(0x7863d781,0x8164b77f), LL(0x2f9631b8,0x1646b084),LL(0x849388df,0xef5b3aa8),LL(0xe58cd383,0x60536422),LL(0xf43ea3a0,0xb079d911), + LL(0xcb73887e,0x504ac041),LL(0xc3ce3a33,0xf878b618),LL(0x56393e75,0x57ef73d5),LL(0xd276c08c,0xe4372d2e), LL(0x0924cf58,0xfd9bc894),LL(0xaaa317e2,0xfa2a4deb),LL(0x79608da5,0xe51edccc),LL(0x8cd4b960,0xadcc68fa), + LL(0xf8e156c7,0xaa66c201),LL(0x1ab2e3fe,0x7c7cf22e),LL(0x0a677d85,0xe479c393),LL(0xb87c412b,0xc0cd340f), LL(0xf95ff321,0x2b2bcef4),LL(0xb8409952,0x65da11c9),LL(0xeb67eb9c,0x143a2218),LL(0xe53508e4,0x8919ff25), + LL(0xa9e0eeae,0x6f154f09),LL(0xab05a657,0x2246e6fe),LL(0x1045b85d,0x4d7c1c81),LL(0xd3bb7432,0xde99ea37), LL(0x63184ff4,0x058f8187),LL(0xd134bfc3,0x2a223421),LL(0x23120320,0x1560dbed),LL(0x76a3de9c,0x37243c95), + LL(0xd36a81b1,0xb8f3851a),LL(0xbdad7ad9,0xfbc62bfc),LL(0x561e0f8c,0xf68215c7),LL(0x1bcf765b,0x894131d1), LL(0x45c5d736,0x8da01f9e),LL(0x7484e0c1,0x025de05c),LL(0x6858b504,0x62f4c66c),LL(0xd6dc5f93,0x754b85d6), + LL(0x822a3de0,0x5b37cecc),LL(0xa98a37c2,0x422e49b1),LL(0xbe41e927,0x3ef53d89),LL(0xf4d5bffa,0x0994dd11), LL(0xf7eacca3,0xa62ea556),LL(0x7c746025,0x37b4e230),LL(0xa8e14253,0xb4291e37),LL(0x2a2b666c,0x2bfc9eaa), + LL(0xc26e5588,0xf604604a),LL(0xa7ec3971,0xf75816ff),LL(0x26a30a6d,0x859e9ec7),LL(0xa1a5b815,0x2ce57b66), LL(0xd65e8ec2,0xc7aa4df4),LL(0xa5d82ede,0xbab6b3bb),LL(0x7b088314,0x7a11b25d),LL(0xc2c636ac,0x501a3891), + LL(0xe256b02b,0x9f116c8f),LL(0xfa5946e0,0x71495693),LL(0xc335452a,0xeb9696ff),LL(0x4971162e,0x01ca5929), LL(0xc0f28e72,0xee0a1f50),LL(0x70d8df1a,0x2baac62c),LL(0xf49110f8,0xcf65d297),LL(0x9a45e16a,0x041dbb01), + LL(0x5e1410c0,0x8db69426),LL(0xa70d0268,0xb21f3c6a),LL(0xbac0ddac,0x64a3c30e),LL(0x66a2d33a,0xdcebdedc), LL(0xa519de21,0xc5dcd769),LL(0x19322c69,0xa692b6a0),LL(0x154fca13,0x454add5b),LL(0x4935eba2,0xd2281cf0), + LL(0xf2602323,0xb5f44fe7),LL(0x5d68a3db,0x772fb6a6),LL(0x76eec37a,0xf519c5d4),LL(0xada6c3f4,0xbc8e9a15), LL(0xf18effee,0x9cd2a2f2),LL(0x1808ab42,0x9601c142),LL(0x0480ad18,0x05d110f7),LL(0xef6a7f33,0x5f7e0721), + LL(0xe6409e21,0x1afbeaec),LL(0x317f7967,0xf6714651),LL(0x80124751,0x34cd21ff),LL(0x931d9639,0xf85c70ec), LL(0x1ca19094,0x4e26bef6),LL(0x0b841b9a,0xc513f66b),LL(0xb9b41001,0xe25507bd),LL(0x94f49f7c,0xd77fee94), + LL(0xd39e1ee4,0x20b19223),LL(0x4e3e6c2c,0xc8832a2c),LL(0xa3a45c34,0x64a8f43d),LL(0x21fb291b,0x52a05eef), LL(0xe4b68e38,0x10d3e24a),LL(0xee2d8a40,0x5289120a),LL(0x425b7da8,0x33836b98),LL(0xb00c64e1,0x5bd418f3), + LL(0xd511c3f8,0x10e92e5a),LL(0x18b62b7d,0x17f1301d),LL(0x97f0fcae,0xf710b02d),LL(0xbd394477,0x8b1030f6), LL(0xe5aab897,0x49040009),LL(0xce75b4d3,0xfdb23ac1),LL(0xf2b70e1b,0x7a43d904),LL(0xf94fa56f,0xdc09e995), + LL(0xd075dd65,0x9f314e85),LL(0xb9e26b8d,0xc0d39ce0),LL(0xfdc3b678,0xd3f6778e),LL(0xfc8497df,0xce6573e9), LL(0x67abaf7a,0x1f4535f8),LL(0xa47dd948,0x80706dab),LL(0xc059242b,0x670ae5bc),LL(0xcf5f9308,0x3a29bc73), + LL(0x8af2bf74,0xd2f8e297),LL(0x6c48bbec,0x98dbb443),LL(0xeb448447,0x211a3a96),LL(0x5af4a2c0,0x88ffb240), LL(0x9cdf9e20,0x1959dd34),LL(0xf34627e0,0xa4d0d839),LL(0xf00057cc,0xa5cecad3),LL(0xc5d97b18,0x22f32cce), + LL(0xcedc2c97,0x31a02241),LL(0x2b632641,0xf0f5489b),LL(0xcbfb588f,0xb09091dd),LL(0x5d9478e7,0x5ffd0f38), LL(0xdae35eda,0x13f141a1),LL(0x62f0b26c,0xd25563a6),LL(0x1b9dde18,0x80014b17),LL(0x7da49b36,0x9fcf8f81), + LL(0x93519f31,0x68aac84a),LL(0xc0b3660a,0xe14c35c1),LL(0x08195bc5,0x29f447dd),LL(0x10bba62f,0xc61fbbe6), LL(0x4ed8621a,0xc471624c),LL(0x0950a4c6,0x8005f67f),LL(0x93a2a33e,0xdfc3b3e5),LL(0x3c1d0e42,0x9c3c815e), + LL(0x93904766,0x1ed1aedb),LL(0x376fd0bc,0xcd5e0cf6),LL(0x90d03033,0xdd4c3378),LL(0xd85dca30,0xde39db01), LL(0xe6fab58b,0x49d01dc2),LL(0x6d449f51,0xd16d7940),LL(0xd20a95e6,0x3fb6cf8e),LL(0xbbeeccb1,0x0b10a596), + LL(0x0005acd3,0x06ceaa62),LL(0x47555053,0x09db6b28),LL(0x7e7d18d7,0x45d84a85),LL(0x229ad33e,0x33c28b02), LL(0x72e4f34c,0x1e5a6b52),LL(0xb64fa831,0x81eefbe6),LL(0x2aa209aa,0x4983b84a),LL(0x38d6a8d6,0x20777198), + LL(0x40096f25,0xbe993805),LL(0xec820131,0x900d4bdd),LL(0x2a993f9c,0x2170cfd3),LL(0x2dfe1007,0xa0e3d894), LL(0x0e7df109,0x600d0b5a),LL(0x47fde3dd,0xc904985a),LL(0xcb89816a,0x15597a84),LL(0xb9dfeb9e,0x8ac8b027), + LL(0x6450a179,0x5c9211bc),LL(0xf6333f95,0xd448a70a),LL(0x824e1d7f,0xe9c9a964),LL(0x15750ae4,0xc47d3f3c), LL(0xadcf9482,0x959f776b),LL(0xe741ceb3,0x00557ffe),LL(0x353d7898,0x8b69d3f6),LL(0x45cfa492,0x6b4d80d3), + LL(0x30c313da,0xc33ead78),LL(0x67eee139,0x86f96c3a),LL(0x08611b15,0x0c6675c7),LL(0x60620c27,0xf9ee695d), LL(0xd70c9258,0xb35d438c),LL(0xa5e7a4b1,0x1bc2b1e7),LL(0xef92f629,0x38d257f8),LL(0x79fd1eb0,0x090af73a), + LL(0xf59342e5,0x96ebd1f0),LL(0x4d053375,0xd4869362),LL(0x5fab54aa,0x7db504e2),LL(0x6e8e43fb,0x17c0801e), LL(0x136b1941,0xd3904d62),LL(0x28a43bd1,0x5932b753),LL(0xacb35572,0x551d895e),LL(0x1a6fdfbe,0x3f7a8a46), + LL(0xf7a2df83,0x9e3ea4fd),LL(0x64524d44,0x8b68b26b),LL(0x126aee21,0x74caeeab),LL(0x915d9e1c,0x590a00a5), LL(0x49b90eff,0x5ae2a6ab),LL(0x2df4fe51,0x74b4cb1e),LL(0x07fcb6ed,0x0306ed11),LL(0x502f5b30,0x564ebe2e), + LL(0x0c89e9ba,0x5a09a32e),LL(0x84f2466d,0x967f9dfb),LL(0x26a1a8a0,0x8b27416c),LL(0xc3158a18,0x1c21ef95), LL(0x2be23ae9,0xa7ee1ad8),LL(0x4daa1fcf,0x1f312d04),LL(0x44f9c7d7,0x6782f843),LL(0xe19e2681,0xb12ea2bf), + LL(0xd20578af,0xd2e43cbf),LL(0xbb5819b4,0x5566460a),LL(0xb658c03c,0x86f6c860),LL(0x62d42d82,0xc8d90309), LL(0xcb883ceb,0x7975a5f3),LL(0xdcded5a1,0xf6f5cf0f),LL(0xd3eb810b,0x25554fb1),LL(0xa596c7c6,0x3df7536b), + LL(0x83de31cd,0x255ca136),LL(0x7795eb96,0x7ac532ee),LL(0xb12bc235,0xfa9d83a9),LL(0x4b287a83,0x7df5d231), LL(0xb4f19fce,0xb2eaaaf6),LL(0x1a045f6a,0x7caabfb0),LL(0xb1449e6a,0x6d1b7f40),LL(0x12d22c82,0x24ae41da), + LL(0xc0a9d128,0xb0f7a0c3),LL(0xaed0d3bd,0x2adc34d3),LL(0x13e778e6,0x4ebf5778),LL(0xbb8476ba,0xd3b89bd0), LL(0x37413953,0xe09eb528),LL(0xd8ba3471,0x952b705c),LL(0x86a79c09,0xcaa81ade),LL(0x7e0e7b2a,0xc08eed3d), + LL(0xc80b4196,0x313fb103),LL(0x88c7ac81,0x25449ece),LL(0x24f16fa2,0xa6cb9ad3),LL(0x728a0c4b,0x4602c441), LL(0x5a000a9c,0xc3366f88),LL(0xef8778bd,0x146623e3),LL(0xf0773fdc,0x184ba0b1),LL(0xaecd8d63,0xe1d115ef), + LL(0xae165e6c,0x420d5473),LL(0x108d8575,0xefe137cd),LL(0x6fcff7d9,0x15378c57),LL(0xc1f5b601,0x49c48099), LL(0xf68473f1,0x1b0e3aee),LL(0xd320720d,0xa78329bb),LL(0xdca54cad,0x385e521b),LL(0x5c5b8d60,0x478ce06f), + LL(0xca7c4d4b,0x215d7d33),LL(0xa095366c,0x773f3ab3),LL(0x7afeeaa1,0x668e0d11),LL(0x4878d8a3,0x410cd205), LL(0xb2800646,0x2748fd98),LL(0x73a1dbef,0xf1183786),LL(0x7567ed3a,0xecc31bd2),LL(0x0ceb3873,0x775210df), + LL(0x9a8f42ff,0x2ea0c2bc),LL(0x4a1c029a,0x62974240),LL(0x9e4dd41b,0x5ee5f5f6),LL(0x2e110249,0x5b1bba80), LL(0x78da8016,0x5ac4eadb),LL(0x1809f79f,0xc2978780),LL(0xe3f8c0de,0x39d2dbce),LL(0x064d3ba9,0x7fb4b5fc), + LL(0xcd481ab4,0x038a736d),LL(0x396888eb,0xc4b15c5c),LL(0xd421f36f,0x459a896d),LL(0x47f54663,0x6058b90f), LL(0xafefebe5,0x0a5f6771),LL(0xa5b7c2ca,0x45c97ab2),LL(0x85139ca4,0x6d547af9),LL(0xa29d71cb,0x6db218de), + LL(0xfb956184,0xca6e0e7b),LL(0x1f660ac6,0x6682b6e3),LL(0x8b21bceb,0x3959e396),LL(0x632cf9c8,0x0459fd46), LL(0x74f296bb,0xc741250c),LL(0x990dbefa,0x29b9cacf),LL(0xfc35bdf7,0x5065d818),LL(0xa551dc04,0xeb8e9e1b), + LL(0x11befe9e,0x4f7d6f7d),LL(0x7478fdee,0xa88f1fce),LL(0xafa688e3,0x39b1e053),LL(0xe16847e0,0x562a0d6e), LL(0x34c26d14,0xf6044e4b),LL(0x7df61b90,0x5ebe8727),LL(0x6b5e5a39,0xa82a4de4),LL(0xfb9d296c,0xc916b0ba), + LL(0x2e1dc01e,0x029f1cb2),LL(0xfc429483,0x7699d92e),LL(0x154560f0,0xee0e425a),LL(0x787b6641,0x3f5cdfe6), LL(0xe5f6794e,0x726d87bb),LL(0x23aecad2,0x97d73588),LL(0x09ca351c,0x47f4f5b9),LL(0x57dc5e3b,0xd742ef4b), + LL(0x71411a86,0xccd2209d),LL(0x2223e6ce,0x94d57663),LL(0x66c7950c,0x228a7400),LL(0x54dd4e37,0x2d00ef6e), LL(0xd60f66be,0x9ea5daf3),LL(0x8aca724f,0x743c58a5),LL(0x44e38446,0x1f638406),LL(0x92ef6bb0,0x06314bb0), + LL(0xbb05589d,0xa7459e7f),LL(0xbfa913d7,0xc3a39592),LL(0xdf07b190,0x27dbabee),LL(0xd2ee62ff,0x1c8a2f33), LL(0xe31e8d63,0x60c8bcb8),LL(0xce410061,0xea1604d1),LL(0x3d7f7a98,0x55e8cfee),LL(0xebc64102,0x49efc316), + LL(0x41934914,0x04c86d8e),LL(0xab7facd4,0x26667c76),LL(0xa71a8916,0x319158db),LL(0x114fff43,0xb802942d), LL(0x8ce544f5,0x5efdef7b),LL(0x70e870c1,0xf531c718),LL(0x4d92071d,0x4b9a5f1b),LL(0x60cc48b6,0xbe767cf2), + LL(0x717381ea,0xbf389d37),LL(0x06bc5bcb,0xefd9e984),LL(0x67ff1110,0xcc8bc960),LL(0xb05612e4,0xd3414c0b), LL(0x927fad1a,0x084e5f05),LL(0x438e241f,0x999bd581),LL(0xfaa4fab8,0x0c917602),LL(0x95080657,0xda0520d2), + LL(0xce2f1af2,0x3160f928),LL(0x364f56e4,0x61186d84),LL(0x25fa68f0,0xe36a5fc0),LL(0x774c584b,0x9e6f66bd), LL(0x9ecb449a,0x2611bba4),LL(0xec5a0667,0xb1e0b341),LL(0x6cddb6c3,0x336de76d),LL(0x65a18f95,0x9668b5b3), + LL(0x7c3ec388,0x1ff6c81f),LL(0x40a8e2d0,0x53545b05),LL(0x14ae31d6,0x990a3cc5),LL(0x063a2995,0x769b4c26), LL(0x039e279f,0xcea238f4),LL(0x732fb38e,0xbfc5cfb9),LL(0x82fa05d8,0x99f5a33c),LL(0x69c42686,0x274dc741), + LL(0x76af2af7,0x193338ee),LL(0x6914ae66,0x0488c19f),LL(0x5fc58bf4,0x8d197f4e),LL(0xf0e61d4b,0x23de54df), LL(0x44a165e1,0x547dd09f),LL(0x1c2d5471,0x99878065),LL(0x39b311db,0xb2cabfad),LL(0x4b61a7eb,0x0aed63d9), + LL(0xbe8110ef,0x03713ac5),LL(0x50f989d3,0xaab1917d),LL(0x358fe8b0,0x0d80fe98),LL(0xa7a1f8e3,0xf6e874c5), LL(0xdeb42398,0x05650fd8),LL(0x1c44de73,0xbad3e085),LL(0x1c27f3c2,0x5369135f),LL(0xa7fc74ac,0x14bc04f8), + LL(0xb5dae291,0x18cbf622),LL(0x9356b88c,0xce290570),LL(0x39eba4e6,0x61bbb446),LL(0x980fee37,0xa79c291b), LL(0x19960cc6,0xd9f18006),LL(0x0ce98896,0xb0823f41),LL(0x1377df6f,0xf2bc612e),LL(0xc0b0e71c,0x1c07bded), + LL(0x37211fd5,0xffbf9841),LL(0x04a81410,0xbd704a6b),LL(0x6abf1c67,0x653cd2ee),LL(0x40681621,0x73ab8aa1), LL(0x271ada5c,0xc0bae4fd),LL(0xc46f189d,0xf567cae8),LL(0xa5535334,0xd183cb27),LL(0xe53c530c,0xcbf133f7), + LL(0xedd6a17e,0x32e53f78),LL(0xa2194fae,0x6ce6da9a),LL(0x58cd3586,0xa89b8054),LL(0x43b520a5,0x0037febb), LL(0x653e2c0b,0xbe67a2cf),LL(0x50301f52,0xc07a1ed1),LL(0xf5ea954f,0xf98b2b60),LL(0x7af6c499,0xfa6da95d), + LL(0xe3889cb1,0x44892091),LL(0xd45ae338,0x123fc555),LL(0x02a63128,0x2bc4a9ef),LL(0xa1dbb436,0xb72012c9), LL(0x556a0b46,0x8c75f7b3),LL(0x5b7608a4,0xe4c6f46c),LL(0x38fce20f,0xb36abf68),LL(0xbf6c21e1,0xb5a8e657), + LL(0xcecd5963,0x9ceaeefe),LL(0x6105fc29,0xe84f200d),LL(0x8591e346,0xc28981a9),LL(0x207001f1,0x0be4e931), LL(0x88616b18,0x31399d9d),LL(0x238c626e,0x3dac9f55),LL(0x65574274,0x0213fca7),LL(0x827aa853,0xa3560244), + LL(0x1ca99134,0x3ffbfeeb),LL(0xd07a2dac,0x0a4b56f6),LL(0x75417a6b,0x01795eca),LL(0x18a5fb22,0xe2a6dd9c), LL(0x8aca0cd8,0x13c97586),LL(0x7c323c52,0x3c2bb26e),LL(0xe38319bf,0xa3688cae),LL(0x4c88726a,0xe04b44b4), + LL(0xb0a88a4c,0xfed864d0),LL(0x6b1fa305,0x3e6cf152),LL(0x00e18e4a,0x8416b5f0),LL(0xfa4cd8f2,0x3a7603ca), LL(0x7ec750ef,0x8b04d5ff),LL(0x1c1ced05,0xe1867f9b),LL(0xdac2f8c1,0x87ffd0fb),LL(0x08b3cdca,0xc9ebe420), + LL(0x029c247e,0x5028a4fd),LL(0xa5ae3e76,0xd6225a43),LL(0xf970817e,0xfb3fa71c),LL(0x9ab4aef1,0x74216809), LL(0xa39c2f13,0xca81ee99),LL(0x86a97827,0xa8336e42),LL(0xb6489555,0xb75aff99),LL(0xe565435c,0x005b2338), + LL(0x524bdb34,0xbaee27bb),LL(0x82e47e71,0xbf22e1c9),LL(0x97491139,0x6ab1d712),LL(0x2cf4cbff,0xf420ce06), LL(0xb2b0c86a,0x9f96a2fc),LL(0xabeb7335,0x42765dd9),LL(0x45b7e044,0x7c223bb7),LL(0x1794e144,0xce3f9245), + LL(0xf3ee5c4e,0xa0a15b27),LL(0x54622215,0x1721c5bf),LL(0xada5a99c,0x0003fd16),LL(0xdbdccc7b,0x8e96dd56), LL(0x43f83748,0xd1abdc0b),LL(0x0f5ce74b,0x71cac4a6),LL(0xd46717ad,0xb8539aff),LL(0xb99661d9,0xeb65c589), + LL(0x85e89e17,0x66b4df3b),LL(0x6fc30672,0xc94fad66),LL(0x81d90df8,0xfd2aa80f),LL(0xbd8234c1,0xed73a163), LL(0x72eb45dd,0xe1a2c0b9),LL(0x902b5ca9,0x417e355d),LL(0xd5128812,0xa8f55aaa),LL(0x3c14cb79,0x4826b934), + LL(0x394d7a92,0xeae495e3),LL(0xb90faec0,0xcba23153),LL(0xf6d9d80c,0xd687c821),LL(0x8bff3082,0x951dada2), LL(0x701708ad,0x4e74f1f0),LL(0xdd2134f2,0xa6333cd1),LL(0x04665f7c,0xeea276cf),LL(0xae74c17a,0x527257fc), + LL(0xe51b53bd,0xeb3fd493),LL(0x69ec567e,0xae7807db),LL(0x5de15fd0,0xa50124aa),LL(0x1336f055,0x781bfe70), LL(0xd70a0dfc,0xb5729a74),LL(0x9f50c1a3,0x89da37f3),LL(0xcd8e6c1c,0x6e063297),LL(0x181d0271,0x17eb6ec1), + LL(0xe4e52a8c,0x36e7251a),LL(0x94705324,0x3acfe89b),LL(0xbc130c3b,0xaa94f06e),LL(0x309ae25a,0x01b5e44c), LL(0x0f61b55b,0xb72160f2),LL(0xe7bbc3f2,0xbef61953),LL(0x1bf138a1,0x96734d7a),LL(0x08c25135,0xdaa6186c), + LL(0xf34534a2,0xa3b031b2),LL(0xde46f581,0x44136619),LL(0x6d379647,0x4d0ed04b),LL(0xbb2b6735,0x4879d90d), LL(0x590156e0,0x8f7e031a),LL(0xf42bbc53,0x28428354),LL(0x5c5b791e,0x1cbed33c),LL(0x4cfc5562,0x17571645), + LL(0x7f76462f,0x8392350a),LL(0x0c216ccb,0x659ce7db),LL(0x047e35d5,0xe87a78b7),LL(0x6e0862d6,0x307c4861), LL(0xe70741bd,0xd444fb86),LL(0xfea1abe2,0x1138a886),LL(0x62b79c4f,0x4695397d),LL(0x003130ee,0x11aaf588), + LL(0x3a11712b,0x53bdda6d),LL(0x40fba3d2,0x30c384bd),LL(0x50ea38be,0x63039585),LL(0x3da9738a,0x7f110eca), LL(0x5b68c01e,0xbd701fc6),LL(0xcc48f38d,0xd23f3e8f),LL(0xf8b9bb65,0x6e2557eb),LL(0xa3dafc8f,0x29ceb4b6), + LL(0x4b6b7705,0x24659686),LL(0x4aca2b43,0x04143a8a),LL(0x975e06d8,0x3baed256),LL(0x3e834249,0x846fb3c9), LL(0x75f6770a,0x7890761e),LL(0x203c78fd,0x1187920e),LL(0x6b26281f,0x9b06c3a9),LL(0xa98215e1,0x3fe3dccd), + LL(0x4f33655e,0x099d7d7a),LL(0x662fb55a,0x1ba571e6),LL(0xcbc497f0,0x1a0d0147),LL(0x2862ff38,0xa94218ae), LL(0x5ce08047,0x1b0f919b),LL(0x2baf46cd,0x9a3ac37a),LL(0x8964cc68,0x76b7a03a),LL(0x4d3e1a40,0x5aed8c6d), + LL(0x7f034ff4,0x6607179c),LL(0x3781eac2,0xefb8fcd9),LL(0x7b022138,0xfa57f8a9),LL(0x56ab6039,0xc5bb9f1d), LL(0xe4d2ab7f,0xf9027e24),LL(0x77a9e364,0x3d67ad71),LL(0x1f7f487d,0xc579e70c),LL(0x2a7e6bd0,0x7fefc894), +}, +/* digit=35 base_pwr=2^245 */ +{ + LL(0xa45cfd31,0x2cb91662),LL(0x16f65cfe,0x09dd56d3),LL(0x14f3de51,0x983e005d),LL(0x210f64fc,0xb9dc05b0), LL(0x885eafe5,0x22790afd),LL(0x7444bdec,0xbd5213d3),LL(0x8987300a,0x289dca92),LL(0xb3960b76,0x69fb2ac2), + LL(0x9ae7540f,0xe3274886),LL(0x6131e921,0xd7386631),LL(0xf2a360c8,0x2e3d4fd8),LL(0x3d9d41e0,0xb20a59b6), LL(0x99082a34,0x72b67eae),LL(0x51819470,0xfad6aa7d),LL(0xa2d1d007,0x7c299b9a),LL(0x8100bed0,0xc1f841e0), + LL(0x43e90ebd,0x2c1f7d4c),LL(0x1fc72b07,0x58b78107),LL(0xaf94f402,0xda8503e1),LL(0x59f244b0,0xfbb724b7), LL(0xfcd8755a,0x2fcd2186),LL(0x868482b7,0x7407cdee),LL(0x349be3d5,0x4d62f578),LL(0xdcc6202c,0x4a012544), + LL(0x151ffc08,0xb8a414d2),LL(0x740d6b55,0xaa79acf0),LL(0xcdf472ab,0xeeab0104),LL(0xa3aa5f1d,0x5014a8c1), LL(0x33f13425,0x8c743405),LL(0x57eb54d4,0x2b776b49),LL(0x548a723b,0x3a0cc4ac),LL(0xc79fe63a,0x65aae6f3), + LL(0xee5e579c,0xe8b388f2),LL(0x991c03d4,0x31cc9373),LL(0x567bfa7c,0x53eed518),LL(0x67f985ed,0x267e282d), LL(0xb4763ea0,0xc435fd22),LL(0xe39b7703,0xead83837),LL(0x094ba5b4,0x806daad5),LL(0x45842672,0xa738a847), + LL(0x9984c4c2,0x99421b42),LL(0xd35c7bbd,0x1a3bce27),LL(0x3563b09e,0xe51ae6f6),LL(0x8d9c9fbf,0x8e67853b), LL(0x6b2100b5,0xca8784da),LL(0x98879bba,0xe89a24f7),LL(0xe286b039,0xe901b45c),LL(0xf50384bd,0x23dedbb8), + LL(0x5cbf7df2,0x4728cbdb),LL(0x6764329e,0xed274fdf),LL(0x642d199a,0xc2af1a07),LL(0x17a50e7e,0x5d665659), LL(0xfaa5eb82,0x7babf4bc),LL(0x99fe4026,0xd3bcfc67),LL(0x607d9f41,0xaa5d2648),LL(0x967efac1,0x7405c071), + LL(0xdfa782a4,0x79447ef9),LL(0x74cd9500,0x6dadc8e1),LL(0xdc38f762,0x0574020e),LL(0xe2ee7a14,0x17596d7e), LL(0x9e1f8adc,0x9ef75af7),LL(0xa4791da0,0x5ac5f216),LL(0x7b7b5d80,0x1583226b),LL(0xa21c26cc,0x59f3f053), + LL(0xf95e30d9,0xd80e7fdc),LL(0x0a3a3616,0xecf5041c),LL(0x03043fa6,0x50b93b8b),LL(0xae262ad6,0xa31a2aa4), LL(0xd63cd98d,0x1468b370),LL(0xdc07a367,0xfb89cc65),LL(0x4d47b59f,0x6cf1df6b),LL(0x1b6350fe,0xab451a99), + LL(0x8c124dff,0xeb74554d),LL(0x21be0be0,0x781a8c4d),LL(0xe3510068,0xfaacc154),LL(0xd6238265,0x16655d65), LL(0x0466134a,0xba46d27b),LL(0x3101e283,0x1a3f51b9),LL(0x096ec237,0xc08298a9),LL(0xc69cfb5b,0x46248627), + LL(0x81a0500f,0xf9e7a5a4),LL(0xbd2e03e7,0x92db27d5),LL(0x82899e3c,0x3dcce4f6),LL(0xf39a39c7,0x861f1797), LL(0x69dc8961,0x175b2430),LL(0xdc67953e,0x93d2a88e),LL(0x92d794d6,0xa40f3704),LL(0x3526eeaf,0x607019f0), + LL(0x22f37d65,0xf20e163b),LL(0x32cf180a,0x70fd00c8),LL(0x0b17244e,0xff1a97d2),LL(0xacedb33a,0x9a5a141b), LL(0xcc16bbb4,0xf03dd868),LL(0xa40e44e9,0x9b15372d),LL(0x15ac397f,0xd5ba6436),LL(0xc821f6b7,0xb1a886d4), + LL(0x4b7b4e21,0xbe3aacda),LL(0x66b56729,0xad9829fe),LL(0xd541cc1a,0x78965cef),LL(0x7d17631e,0x414bfea7), LL(0xc64dd621,0xf55835d9),LL(0xef644d93,0xa0ebf68b),LL(0xc8a40021,0x01d15340),LL(0x42b99aa0,0x00ae640d), + LL(0x6881e64f,0x92321ee2),LL(0x5267bdd3,0xaccab5c8),LL(0x5927647b,0x0c1f87ea),LL(0x162c6d86,0x0093d07e), LL(0x389c711d,0x49868df4),LL(0xc11e1f37,0xe68d69ae),LL(0xb4207246,0xa40e7aa8),LL(0xce832395,0x4ae8d126), + LL(0x86450cc0,0x5f9b128a),LL(0xc8ec07e6,0x88f76293),LL(0x179702b8,0x0762f293),LL(0x4910006d,0xb5696102), LL(0x35fe0505,0x3951291b),LL(0xce8d7056,0x70f75a5c),LL(0x2eb13369,0x4541beaf),LL(0xa643316c,0x7060a749), + LL(0x49c879a5,0xee16abd0),LL(0xa47ac42e,0x844874a7),LL(0x3c9c2326,0xee3f8a20),LL(0xdeaed33b,0x99a12054), LL(0x63b333ae,0x4814a15b),LL(0x9d923fa0,0xee9f28a5),LL(0x33b1b1ef,0x5b0cd250),LL(0x8346d928,0x3ccc39b9), + LL(0x002bec95,0xf5c1000e),LL(0xf63528c2,0x2ba2f18c),LL(0xcdcec15a,0x8102f6c8),LL(0xbb13d14a,0xab7effcd), LL(0xfcd3787c,0x183e0ba2),LL(0x2f4a7fc0,0xae70635e),LL(0x760bbc96,0x473ed37f),LL(0x8a8efb39,0xf0ea0acf), + LL(0x29b526a9,0x63cea36c),LL(0x9d03f3db,0xcdb31613),LL(0xd57cca8e,0xa3891096),LL(0xa14a8ffc,0x646418a9), LL(0x8075291f,0x10f8906b),LL(0x2c618bf6,0x8221d941),LL(0x8a5da4df,0x1dc1ae7a),LL(0x8a8cc8bc,0xb66b96e3), + LL(0xfe3551b4,0xe4da7e48),LL(0xad9b3827,0xe6891cc9),LL(0x6b37b99f,0xb266733f),LL(0xfd5d1219,0xfccce911), LL(0x7262b8cc,0xe5a47c4b),LL(0xe656af49,0x5d349caf),LL(0x7e04e48e,0x7a3a4a28),LL(0x80ea7d03,0x7c39a68e), + LL(0xbee0d434,0xf35d5e32),LL(0x0b536161,0x9651f3d9),LL(0x72cb370c,0x42634cc9),LL(0x406b3457,0xa7764026), LL(0x65d53d80,0xec7525bd),LL(0xadcc8b05,0xf44a1bca),LL(0xda112ddc,0x12ef8427),LL(0x20a0f78f,0x796a65b3), + LL(0x6bd5b0ab,0x12726e24),LL(0x8242fe07,0x9e441467),LL(0xde2bea52,0x4b52e276),LL(0x10422c2c,0x3a76b6b4), LL(0xb4e496b9,0x71f14945),LL(0xf36dce4f,0xd20f04b0),LL(0x2b310e90,0xa0e57d8d),LL(0x32ec8f38,0x59eb7737), + LL(0xaaf6619e,0x20a19834),LL(0x691a538e,0x633b94e8),LL(0x92cdf395,0xea1a8985),LL(0x4349b971,0xa3a01c57), LL(0x30822c59,0x0d65192a),LL(0xa522ae8c,0x93a5152d),LL(0x0e1aa4bc,0x5b09a7a3),LL(0x8d3b97a9,0xdd2588f3), + LL(0x5b62a3a5,0xafa1f62a),LL(0xa9ace9c5,0xbded10e6),LL(0xbf6e7fb2,0x9d03e061),LL(0x4b87177a,0x60c564a8), LL(0xc22c14c1,0x36be1308),LL(0x9425b6bb,0xeeda57e8),LL(0x36af38c2,0x5ddaae14),LL(0xecdc2911,0x1695464b), + LL(0x161e13e7,0x4b795e1d),LL(0x907e7069,0x0f9abc20),LL(0x54522fe7,0xfb3be618),LL(0x1938134e,0x9e2d0f37), LL(0xd292c6b0,0xb8dc7c36),LL(0xc1e77895,0xbafbf59c),LL(0x1b6c55f3,0x7d0132cd),LL(0xf609f087,0xefa02ed9), + LL(0x03519f9f,0x4bfe6aeb),LL(0xdab4c075,0x248e19a0),LL(0x69429f29,0x83ee803d),LL(0x8190ce56,0xdbbe31e2), LL(0x6b787a5d,0x3ba735d2),LL(0x1818070c,0xfa021185),LL(0xa3683cee,0x9b653000),LL(0xe9517ba2,0xfc3c7907), + LL(0x88d94f69,0x6521c92f),LL(0x7b52da8d,0x3950e9e8),LL(0x8ee64a88,0xadb81700),LL(0xf73994fe,0x8ccbfa3c), LL(0xb048e71e,0xb780ab12),LL(0xe2aeb607,0x52879e7b),LL(0x3237554f,0xef04b1ed),LL(0xe1d5a5ef,0xaeba6a96), + LL(0x266f7e93,0xedb58542),LL(0x5ea02852,0x9a1b8057),LL(0x5beb3fbd,0x1963c6f2),LL(0x1ad52473,0xf4183355), LL(0x6faed2f4,0xca772e9e),LL(0x3cf8fd1f,0x937eddd0),LL(0xc1d49dac,0xb3255376),LL(0xe670d3cc,0x549c2119), + LL(0x3b6cd199,0x10edbf39),LL(0x75644d6a,0xe9479223),LL(0xd6e8cc36,0x36cfba92),LL(0xfe00d80a,0xa37b1d91), LL(0xdeb5ef4a,0x3aadf918),LL(0xd3893df2,0x5bb2ca4d),LL(0x6569ab8b,0xa776000e),LL(0x1cf64905,0x4fb2308f), + LL(0x273731c2,0x04da4d09),LL(0x23c05518,0x1d4a61fe),LL(0x0d5206e5,0x201098a3),LL(0x06430c82,0xd9a7ad4e), LL(0x36f7f462,0x56df0d06),LL(0x44c81042,0x2c067f3d),LL(0xc453d28e,0x01193bc9),LL(0x45ce6e64,0xcdf5af5d), + LL(0x0f7d8d12,0x9992ce1a),LL(0x0e5e4542,0xa7c46a61),LL(0x057802ba,0x3fcc0647),LL(0xc7dccbe2,0xa78f73d8), LL(0xf138dc6d,0x67f37b94),LL(0x650a9002,0x89330885),LL(0x68aa24c7,0xf661caf2),LL(0xbf73c435,0x47732bcd), + LL(0x3b04622e,0xb9ba5f91),LL(0x477d420a,0x24265f73),LL(0x0d44cb89,0x5da6ddb0),LL(0x151fc40b,0x9f8cb8b6), LL(0x9b9f2613,0x81b6956b),LL(0xebb917df,0x37419206),LL(0x2bb7a709,0xdb9cfc16),LL(0xbacd3fb7,0x7a800aa3), + LL(0xd93f6e1a,0xf8ea9359),LL(0x3d41c118,0x729005d4),LL(0x7cb641af,0x4c293410),LL(0x895e8e78,0x6b2b4671), LL(0x5958fad3,0x2a1251d0),LL(0x78619fe4,0xb69bc2be),LL(0xd911d318,0xd74df34c),LL(0x15102704,0x5def8378), + LL(0x08268482,0xb19ea17a),LL(0x1c37e5d1,0x14591196),LL(0x7640df9c,0xe0e12d2e),LL(0x8c941274,0x8fd6bd4d), LL(0xdcd142b1,0xc3f9f120),LL(0x78dfe6b0,0x106c49ac),LL(0xcfd9b542,0x243c8e93),LL(0x0a2c5fe6,0x6758062d), + LL(0x15f2f638,0xee5a99e8),LL(0x13979ab6,0xb95b008d),LL(0xacfcca6a,0x7fd03105),LL(0xe4ced1b3,0x6af914a4), LL(0xa25f8627,0x8bef3d0f),LL(0xf9b2f931,0x21bae309),LL(0x2195a839,0xe85dee2b),LL(0xa3baeb25,0x46ad0ad9), + LL(0x022b62a9,0x6d8e40f8),LL(0x90b5cd33,0x4a6bbabf),LL(0xffa89bb2,0x53481e6b),LL(0x22003cc2,0xd674b3b3), LL(0x004a2aa6,0xc71a0a85),LL(0xb5404657,0x86df9697),LL(0xc74e80cc,0x407727f4),LL(0x950a7b08,0x39c13926), + LL(0xd74472a4,0x26bee75a),LL(0x2eb6f0d6,0xbf7c4ea0),LL(0x608bea48,0x689a5de5),LL(0x29d513f8,0x5b383892), LL(0xda457cf9,0x49fee2c2),LL(0x62d523d3,0x7fc0aee7),LL(0xb636a46e,0x5bf447de),LL(0x8194766e,0xda3efd98), + LL(0xd382756d,0xa77c3ad2),LL(0x0fa55315,0xc0eaa9de),LL(0xb1df90e3,0xe68d0a51),LL(0x01d1d8a7,0x0994e8c7), LL(0xa91bfed0,0x4f898bc3),LL(0xab6025df,0x1c2a3e46),LL(0x8b269271,0x37bd5c37),LL(0x8b97f0af,0x4e07f5ca), + LL(0x97923d14,0xe346b5aa),LL(0x9e0bd9c4,0xa8549f61),LL(0x40113a60,0x78e59d6b),LL(0xed8a0fc6,0xe3015fb2), LL(0x8b43288a,0xfc56a08f),LL(0xcae6c18a,0xcbdb8cae),LL(0x5f4423db,0xcb147c44),LL(0x10f361c1,0xa6aaa6c9), + LL(0x7caf702a,0x6be86c0c),LL(0x736f6dac,0x2188e83c),LL(0x59ba2af9,0x40b5ed25),LL(0xab8018c3,0x76211894), LL(0xf5b0b048,0x0c1c532f),LL(0xe3200521,0x7503aca9),LL(0xdfa7eb2d,0xb9325d85),LL(0x2edbb68f,0xe6c25a00), + LL(0x8c673c89,0xf9ff5867),LL(0x099c7bae,0x4925a046),LL(0xdbb1e1b6,0x0b3bf59a),LL(0x30ae084f,0xc7e9d9f2), LL(0x0fa1776f,0x70982396),LL(0x624c897b,0xb2e1b98f),LL(0x6c3534d5,0xa9a6407d),LL(0xa4dc3f63,0x5e22319b), + LL(0x2431dc01,0xc2f0bf3f),LL(0xc2cfb315,0x478f797d),LL(0x3b3ae0c5,0x6559f59c),LL(0xe18e74a8,0x7e95aa62), LL(0xd3fce912,0xf2a94006),LL(0xe1bd96ce,0x7f1b57a2),LL(0xa3d7b828,0x55028ad0),LL(0x4f09fe92,0xadae7e92), + LL(0x757b418f,0x2174c736),LL(0x3661d54d,0xd904ba43),LL(0x63218ecb,0x0281f912),LL(0xc50c8eb6,0x5fd03ba0), LL(0x896a5aea,0x29626906),LL(0xe55ee73f,0xab4d3f27),LL(0xedfd1991,0x3db1c43d),LL(0xa3f9c340,0x498cc31a), + LL(0x4fe75d33,0xa43bdec1),LL(0x66ae5d4f,0x5b067dfb),LL(0x464c8239,0x84581814),LL(0x503a52ea,0x2f10557f), LL(0xa10fbb90,0x21c4c180),LL(0xf79d5e02,0x33b191ee),LL(0xb499478e,0x6dee3881),LL(0xbfbd56fa,0x27dfef0b), + LL(0x28be2d62,0x671a3dd7),LL(0x050897ff,0x06f2f4c2),LL(0xb7c4587d,0xd92bdab6),LL(0xfd8d5160,0xd2253a16), LL(0xf1c098b1,0x64f6e4ae),LL(0x11ea7255,0x005a3939),LL(0xdab542e5,0x2ed4eb92),LL(0x50c5e874,0x26920bc1), + LL(0x5d0bc87c,0x93e8f58a),LL(0xb2b29b4b,0xaa4d313e),LL(0x01b2096f,0x3e175dec),LL(0x1cf31783,0x6c560972), LL(0x73b76f6b,0x9d41aca2),LL(0x5f1d4b12,0xa2454cf5),LL(0x65b35eea,0xa5615196),LL(0x70af4fde,0xf241e516), + LL(0x65061472,0x5255e91b),LL(0x5bdbb257,0x6ef98d2d),LL(0xc74c7b2c,0x0d1d1ab1),LL(0x2e9febde,0x9ffb9fdf), LL(0x6c50bf24,0x853f3b9f),LL(0x6fbd22bd,0x3d369594),LL(0xbcdad9a9,0x4d281126),LL(0xdc46ddc1,0x99eb62b6), + LL(0x4b10c402,0x5aa8c8b2),LL(0x473af61d,0x2e79f595),LL(0xce360f37,0x96153360),LL(0x66bc29dd,0x16dffe22), LL(0x1137f9c3,0x35536eb1),LL(0xe2a6a47a,0xd636ecad),LL(0xb499f840,0x83cdf214),LL(0xd247f18c,0x3642c77c), + LL(0x916ef527,0x4d906a2e),LL(0x293dc085,0xadeb94d0),LL(0x1491da3e,0x03a07801),LL(0x0b84d2eb,0x177dceae), LL(0x7b691e0c,0x61e5a3c1),LL(0xd172cea3,0x47d40bd7),LL(0x8ca76bce,0x7d0646ad),LL(0xc64d635f,0x90b030a9), + LL(0x97118df2,0x71eca8e7),LL(0x3ac9536b,0x2cd48f70),LL(0x89fb4d72,0x9ffd991d),LL(0xebf781fb,0xd49006bc), LL(0xd3e60da1,0x688af07f),LL(0x619063b7,0x5f74aa46),LL(0xa40d313f,0x44fcbeb3),LL(0x326faaa4,0x0ed5908b), + LL(0xf41ec05d,0xe836d537),LL(0x221b0c32,0x01eaf207),LL(0x72f8c904,0x1d6a0bb6),LL(0xdfd74641,0xa6ef58b2), LL(0x811bd6cb,0xbb855ceb),LL(0x05408eab,0x7b1c8b71),LL(0x4187fb7f,0xd24d709e),LL(0x8b30a9be,0x283d647d), + LL(0xf9f0d6e6,0x6d9d3793),LL(0xb1c06b19,0x02fc3ddb),LL(0x94d9abec,0x8ff86793),LL(0x24705873,0x1f20bba2), LL(0x0021b290,0x74eebc12),LL(0x35b6c157,0xd859521e),LL(0x431aea79,0x2201aa41),LL(0x90da1a75,0x79c1caaf), + LL(0x6e412a6a,0xcd6abab7),LL(0xb4c58b05,0x82399139),LL(0xa3b55538,0xdf416966),LL(0x679882d3,0x2b2d546f), LL(0xf9145657,0x17425cbc),LL(0xe1b8247e,0x3cc6735f),LL(0x57edd04c,0x13e50c56),LL(0x1b85b7cb,0xc8723137), + LL(0xdc0ab9d5,0x907b5b02),LL(0x4ab23b78,0x5617fb7f),LL(0xe8f449cd,0x7ae8ff03),LL(0x174e0e22,0x86d3ff17), LL(0xbf1e9f8d,0x22cb7f69),LL(0x0b0c62f0,0x12f0abbe),LL(0x537f658c,0xc8315981),LL(0xc467f2b4,0x43da2770), + LL(0x5b9e88ef,0x3ef9bb81),LL(0x3a8e51f2,0xb8526318),LL(0xf8d744ac,0x2e47cb7f),LL(0x510aaa7c,0x63d6dc16), LL(0xb40ccc41,0x54da7cdb),LL(0x402b2ad9,0xdecbe5fd),LL(0x34c8f225,0x14c6f15c),LL(0xc6559496,0x6d8b2342), + LL(0x66fea635,0xa4b72281),LL(0x22f248a8,0x55f5c27f),LL(0x0959cd01,0x3ced1483),LL(0xb53bdf42,0xcc6469db), LL(0x1e460645,0x2bb2346f),LL(0x9d7535e7,0x4d8573c6),LL(0x49cd2d68,0x988cddd5),LL(0xb9835538,0x785c4a70), + LL(0x1f6e396c,0xb08337b3),LL(0x49a782f3,0x6166b21e),LL(0x8ec9b974,0x1ac6198b),LL(0x0bb44d3d,0xee2e3446), LL(0x35039dd9,0xdb283740),LL(0x29f5c692,0x7c708f95),LL(0x98ddb466,0x8914cce0),LL(0xd446f3cf,0x8bb1b9f1), + LL(0xee0933a3,0xa9dea222),LL(0x4b26049e,0x2538bd43),LL(0xbdcafae2,0x18741aca),LL(0x16b0f4bb,0xe0f830f7), LL(0x902caefa,0x0479ec95),LL(0xdcda9e64,0x1f858937),LL(0x515c4089,0xe75b4f7b),LL(0x2eb91b51,0xb78afde4), + LL(0x18949935,0x1eebe3e9),LL(0xba092037,0xde8deaa9),LL(0x93609411,0xd43cf4ef),LL(0xc2d7b76e,0xe0fdb1e4), LL(0x4e34b4bd,0x1d3191a5),LL(0x9ccc4c26,0x106d92f1),LL(0x29a2a6d1,0x1a404ef6),LL(0xc598f481,0x3338bc9c), + LL(0xe3fcbf71,0x3945e39d),LL(0x9c89ab61,0x123b082c),LL(0x0f9f3c37,0xc7477f77),LL(0x7dbcc077,0x408c0c7a), LL(0x3654f98c,0x6c4d99f5),LL(0x05299a1a,0x276a007a),LL(0x23e2d7d0,0xabd4b8ea),LL(0x86017545,0xe05a5f3a), + LL(0xa11b03cd,0xde3b885c),LL(0x8df5d64e,0x46ef0755),LL(0xbf3f085d,0x112a49d6),LL(0x198ff32f,0xf6ebf441), LL(0x7feae481,0x581c00d8),LL(0xcfde5b2f,0xf2b43827),LL(0x9b7358f2,0x3ceb7f8f),LL(0x55fe7117,0x95761fbd), + LL(0xdc04773c,0x305836fa),LL(0xb3c4873c,0x66324504),LL(0x55b130de,0x5d878c1f),LL(0x8ad49a9b,0x96e9b28c), LL(0x76d70429,0xd1a707b8),LL(0xaa402e90,0xaff33f93),LL(0xedbfb28f,0x733d6256),LL(0xa75d2342,0x9e421a7c), + LL(0xc02e49c1,0xdf86b254),LL(0xb56d308a,0x6bb53867),LL(0x73f29561,0x771dde4b),LL(0x8bf28e5f,0x96eaf73e), LL(0x06fbb550,0x9b1ee6be),LL(0x97d4a4e8,0xe09fec77),LL(0xd5aa84fd,0x93bdcd60),LL(0xd457ab9c,0x3fa8d3a0), + LL(0xa0a2e52c,0x315b32b1),LL(0x3bbcb61d,0xe7e50b2d),LL(0x5e5c6e11,0x8a55cc0e),LL(0x961295ef,0xc2bfa998), LL(0x66e996d1,0x4a5ab3bb),LL(0x4886a421,0x22c42e4f),LL(0x4850e0a4,0xa0cdd364),LL(0xc64ed713,0x7682d38d), + LL(0xa2c539e4,0xe31575c2),LL(0xa756daf9,0x0bac5dcd),LL(0x91f55a12,0xe917cecf),LL(0xe96f6299,0x1e96433b), LL(0x3700d8fb,0xeec7c71c),LL(0xdc9b4444,0x9a1d2965),LL(0xcf74f19c,0x3d2c6970),LL(0xac5e0d6b,0x3b444c48), +}, +/* digit=36 base_pwr=2^252 */ +{ + LL(0x8ccb854c,0xe563cefd),LL(0x65b0c45a,0xf5452cdb),LL(0x9c37f743,0xb3c78769),LL(0x95d444ab,0x34e9d192), LL(0x52ff26b7,0x29347946),LL(0x9b94d642,0x70d6ecfa),LL(0xfdaffb8f,0x7d201858),LL(0x45dcdc71,0xc288719d), + LL(0x0728a2eb,0xc695469d),LL(0xc433d11c,0x7b46244e),LL(0xf106c08e,0x4a8b99ba),LL(0x63422083,0x7989794f), LL(0xd4fc5696,0x82218867),LL(0x3c79cdb8,0x6b021f28),LL(0xb26d5049,0x5ff7bbea),LL(0xa7261628,0xb78611ca), + LL(0x531313d7,0x5a75f961),LL(0x66dcdc9e,0x85a1f4db),LL(0x6460e991,0xae3026b9),LL(0x17ecf7cc,0x7d467bef), LL(0x05118708,0x8a0dbf67),LL(0xf3b2f1c9,0x54bfa368),LL(0xf2c0e4e0,0xa9fc9d5c),LL(0x5e93611b,0xa8c2ad11), + LL(0xaa1256bd,0x3ef1faf0),LL(0x9e4631de,0x0f224545),LL(0xde9c2676,0x69cb9800),LL(0x95782b24,0x26019816), LL(0xa66c0ccd,0x945c172c),LL(0xb440719a,0x6c25f635),LL(0xa49f681a,0x917d5dba),LL(0xb2dc5df4,0xc0cad047), + LL(0x5960ef1c,0xd45bcf4c),LL(0x8c6979d5,0xbabcb16d),LL(0xae9090d6,0x8e3be750),LL(0xac0eb728,0x9481d261), LL(0x0d6a7d46,0x46b436cd),LL(0x1f976501,0x6eb1a6a3),LL(0xdbe1064f,0x5984ffa2),LL(0xf809dc20,0xe6575fb1), + LL(0x4d974a81,0xf0426d80),LL(0x97a74be6,0x61304f0f),LL(0xa9486531,0x2346ff98),LL(0xf53d781a,0xa1242cca), LL(0x97355f15,0x482f03df),LL(0xbd6058cf,0xc607ed33),LL(0x68aefe28,0x03bc8cd4),LL(0x851307e4,0xa6e7de5a), + LL(0xc6af7d44,0x2c07df0f),LL(0xb15a9188,0x310b251f),LL(0xd3e15c2f,0xd42661ce),LL(0x1b4d8313,0x5198fd90), LL(0xda8368a1,0x7a6062cd),LL(0x5e9c2542,0x1a905d11),LL(0xdae37cee,0x1d752b70),LL(0x16bf84ca,0x3ed8c1a5), + LL(0xeecc2f22,0x5190fb0f),LL(0x698d8e60,0x3df210f3),LL(0xf5f3ce72,0xcce57d3a),LL(0x312b8fc6,0xb2fb6223), LL(0x71867c84,0x79947005),LL(0xbe139ebe,0x141cd92c),LL(0x5de7944e,0x415efc9e),LL(0x45821058,0xae9ee919), + LL(0x5bf363dc,0xd696e1d9),LL(0x8251449c,0x6a1bcfc0),LL(0xa5fa53e9,0xa1b82dff),LL(0xeef05378,0x6c56b5be), LL(0xc0e74dc3,0xaf9efe4c),LL(0xe5c1f1a0,0x3d9a7ae9),LL(0x2823c3e5,0x34b38577),LL(0x41fbabac,0x69f297dc), + LL(0xd74c5a65,0xf01aff98),LL(0x1951a915,0x97993104),LL(0x723096a6,0x8b211915),LL(0xa769ef1f,0xf85910c4), LL(0x8ddc0eb4,0x30cefb9e),LL(0xbb09607b,0xd5957eef),LL(0x2355b499,0x2e139c9c),LL(0xc1789013,0x5749531d), + LL(0x5475f2d2,0x1603ca64),LL(0x0a336508,0x57190e0e),LL(0xcea7d558,0x2203b703),LL(0xfb5503e3,0xf16eba4d), LL(0xb7344a98,0x62e2ce3d),LL(0x9a4efa7a,0xebf5b243),LL(0x1c914064,0x96212455),LL(0xbe5bbc07,0xd2c5e31c), + LL(0x06c30b28,0x2b5f2f77),LL(0xbc9823d3,0x0931841d),LL(0xadfa6fdb,0xd16fb08b),LL(0xd6fd441e,0x8892bae2), LL(0x2e576983,0x3fc64630),LL(0x07b05529,0x08c60fb6),LL(0x7afc1d4d,0x32b283b1),LL(0xa2f0e37f,0xc9c56965), + LL(0x4644e173,0x8e719178),LL(0xf88b43ff,0x4c2a11ec),LL(0x7d3ddbb3,0xb13644e6),LL(0xc3d8703c,0xd4746056), LL(0x55dca667,0x6611395f),LL(0x27c91d73,0x63596712),LL(0xea2ff489,0x4ca68a87),LL(0x337adc1d,0x2864a816), + LL(0x224d4f21,0x8aa830ae),LL(0x9f7845dc,0xda6c122e),LL(0xfb240793,0xb0c61ffc),LL(0xce8580e9,0xf4df6842), LL(0x0a990dc7,0x94372aaa),LL(0x5ce1aa24,0x42968cd3),LL(0x4df363a5,0x177c5ff0),LL(0x68c4546f,0xa8c3f737), + LL(0xbd21c524,0xc69750d5),LL(0x22a6c4ae,0xbf3b4857),LL(0xe2883a1d,0xcefcbb98),LL(0xae13f22b,0x6ffef743), LL(0x5defea01,0x6316ba60),LL(0x4ba63810,0x0a89e6a7),LL(0x15ab0e11,0x7f9af1de),LL(0x385911c9,0x6247ca15), + LL(0x32f9eaf5,0x6f7b1a6a),LL(0xacfc13dc,0x2c440f94),LL(0x66b18adf,0x2cf39bc5),LL(0x9f01533f,0xb9939fe8), LL(0x383a6450,0x031c4553),LL(0xf0102087,0x16d96ad3),LL(0x501f1360,0xcbd6fa95),LL(0x65f96c08,0x667d3ea0), + LL(0x68a1a680,0xa5a7cbfa),LL(0x42041db7,0xf131d779),LL(0xd85d377f,0xbefee3ac),LL(0x3b62dfa2,0x6d0ed6b7), LL(0x1baacfbd,0xef683f0f),LL(0xc976cebd,0xc586c4f2),LL(0x3b163339,0x3a4120dc),LL(0xc79e5c1f,0x9ac9b950), + LL(0xe294926a,0xaf1ff35f),LL(0xa2103168,0x2703bab8),LL(0x658a52bf,0xc645560a),LL(0xe466fd97,0x5ff3ccd9), LL(0x54867f14,0xe62fdc01),LL(0x9cdba39e,0x435ef950),LL(0x92828acc,0x2a7bbffd),LL(0xfe763981,0xe7538fdb), + LL(0x8bfe9773,0xedf45173),LL(0x471b8b9c,0xd187fa01),LL(0x78fa54df,0x34506c35),LL(0xc2767589,0x73cab9fd), LL(0x6726f305,0xf8f76c65),LL(0x8de332b2,0xea45012d),LL(0x87970e03,0xb746f40d),LL(0x1ba8fbd6,0xb2b2279a), + LL(0x21147dbc,0x79cdc610),LL(0x9939a3cc,0x738ef680),LL(0x8101bd8b,0xd66d6ce6),LL(0x09323caa,0x65612acb), LL(0x10310a29,0x6874b372),LL(0x5ee9ecfa,0x3cf30f0a),LL(0x8cfe1df8,0x4e1026ad),LL(0xd5989af5,0x75a153f7), + LL(0x8b8e0c49,0xc362ccee),LL(0xb533f3dd,0x8adfc0d2),LL(0xa109572e,0xe02ab03b),LL(0xfd3066ec,0x06efacdc), LL(0x3fa28700,0xf136a8ba),LL(0x308cceb9,0x48a1e987),LL(0x68253387,0xe8ee7c03),LL(0xc2b463c7,0x47febbe8), + LL(0x39a5c4d3,0x485195f2),LL(0xa26241ec,0xf42e000e),LL(0xcd05368d,0x08c64f90),LL(0x857cdbdb,0x46fbd381), LL(0x4c7e16ae,0xf711df8b),LL(0xe4edea42,0x95637e46),LL(0xad171465,0x2df8b206),LL(0x4bccedce,0xa31ea895), + LL(0x50743bb6,0x28dbcb77),LL(0xf9cf84b9,0x13d12f8e),LL(0xc8f7d408,0x39e3d3af),LL(0xeba591d4,0x5824117f), LL(0x1bead2d6,0xd8ef7c9a),LL(0xcaf53dd7,0x9003a559),LL(0x174cb9a9,0x33b2365c),LL(0xadb33afb,0x1149d080), + LL(0xaea9bd3c,0x55231d00),LL(0xfdf3f015,0x07e107c9),LL(0xec9d8fce,0xf535947d),LL(0xbba349a7,0x8b64ed8a), LL(0x049301df,0xdd5881fd),LL(0xe6490fd0,0xefac9c43),LL(0x73740a78,0xd9902852),LL(0x942c326c,0x6eef3724), + LL(0x5cfb3c8c,0x5671a6e9),LL(0x0ea29721,0x040aabd2),LL(0xeac8da18,0x24e92ca6),LL(0xa31170c3,0xc34d3d79), LL(0xb061e416,0xf81dd15f),LL(0x85f80af0,0xff7be70e),LL(0xade45cd4,0xa9faba4b),LL(0x505fddd4,0x42a6ab05), + LL(0x0a793534,0x17d5821d),LL(0xce0ade43,0x9e094e54),LL(0xc42cb4d2,0xa127fb6d),LL(0xdb12dc99,0x43865428), LL(0x59e3bfc1,0xb6b1b347),LL(0x1ec5b810,0x0b0076a9),LL(0xa6864982,0xbf2dd17a),LL(0x9d523c87,0x0c45947f), + LL(0x4c5dd59e,0x9f53372f),LL(0xca5ce09f,0x3d0ceaea),LL(0x7c0337fb,0xf3ff88e8),LL(0xfaa022c7,0xb4fa4593), LL(0xd65ea54d,0x575240a7),LL(0xadb92fb0,0xa4ec0a39),LL(0x79429eb1,0xc20e737c),LL(0x69addec4,0xcea931d1), + LL(0x3e09f46a,0x7a29011f),LL(0x0e578a5b,0x9c36865e),LL(0x71d805f4,0x8746ea51),LL(0xe12d3024,0xf024de85), LL(0x15a7f6be,0xc397b46c),LL(0x1b0580d7,0x612db6fb),LL(0xf736d087,0xe5342f76),LL(0x8c1e844c,0x65276853), + LL(0x113841a5,0xedf48adc),LL(0xe5c482f0,0xc21b67e1),LL(0x684a540b,0xe43b0138),LL(0xa5d4b266,0xc4f2782b), LL(0x397f3664,0x184e240c),LL(0x0d8788f8,0x968e89e7),LL(0x377e18bf,0xec3eba1a),LL(0x36002652,0x4d03cbbc), + LL(0x1005a953,0x21eedee7),LL(0x75ba987e,0xc178ddf1),LL(0xc4ba43f6,0xd0d577f6),LL(0x4d6f24fd,0x9486f46c), LL(0xc5421895,0x3d33c574),LL(0x842e52ab,0x5be6cb4c),LL(0x9debc9ff,0x3809690d),LL(0xa84a5b6f,0xe4b1c692), + LL(0xd7e18b57,0x58b966ad),LL(0x77c94715,0x7ff0b61e),LL(0xf06add82,0x0e295883),LL(0x65c7f5a4,0x7c3c04fd), LL(0x60223be5,0x4ea92660),LL(0x89262bfd,0x5d843a57),LL(0x36da11c0,0x35bf4aef),LL(0xaf859eb1,0xa6692f14), + LL(0xa12fdf41,0xca1fc13b),LL(0x8224f5d2,0xd798c04b),LL(0x1dd5872b,0x22f4594e),LL(0x1bddfda8,0xdee12df5), LL(0xed83420a,0x96473ff0),LL(0x8daa27f4,0xf41cf1c7),LL(0xaecefd8a,0x2772cd56),LL(0x4902b47f,0xd5ddaf18), + LL(0xc0798101,0xff77551f),LL(0x26946bda,0x8baa01d6),LL(0x100525f2,0xd0087e47),LL(0x4c0de308,0x521d6254), LL(0x9bbce049,0x4a0f45eb),LL(0xa6c6b96e,0x5ee33cbe),LL(0xd6a22345,0x9a6af4b7),LL(0x38b1b406,0x0d0d35e7), + LL(0xbbedc29b,0x9e71252d),LL(0xcad1455e,0x3aa70bb6),LL(0x42a1778c,0xa406fb7a),LL(0xf0897613,0xd94f9646), LL(0xf57f66c8,0x5256370f),LL(0x4432f679,0x95891e35),LL(0xbcb6b3d3,0x75d6423a),LL(0x2367483f,0x79d9ea01), + LL(0x9efb0473,0x1e36ccc6),LL(0xdfdc0cec,0x3e64b034),LL(0x028bb238,0x13bfd326),LL(0x209edd95,0x171e9d96), LL(0x07b22424,0xda258380),LL(0xd41b8023,0xe31e97f6),LL(0x7269cecd,0xdd4ed390),LL(0x12d5cec6,0x810fb3c8), + LL(0xbabeec88,0x2f956519),LL(0x455baf52,0xb0350c52),LL(0x48d5abf1,0xa7fb548a),LL(0xca5e2d9f,0xcb81bd0c), LL(0xa6d17b19,0xda5ecd39),LL(0x508e5149,0xd2588bab),LL(0xc3e23cfd,0x1a30cff5),LL(0xf89f8712,0x2dd398b4), + LL(0x5b304005,0x2a911800),LL(0xd9dece69,0xd091be7a),LL(0xf6cabc89,0x147e93da),LL(0x44935824,0x7eac2018), LL(0x32f5de9b,0xd4aaf2be),LL(0xd9396cd1,0xe302bc41),LL(0x2c069d1a,0x3c2794cf),LL(0xa9d433ae,0xf9197eaa), + LL(0x4445e8c2,0x98f822ef),LL(0x1383ece8,0xc578360e),LL(0x01869457,0xa5372c12),LL(0x787d6644,0x1c6ed00d), LL(0x86531814,0x77fb08cd),LL(0x63a70db8,0xeff6ee26),LL(0x80976119,0x980be153),LL(0xd69d60c5,0x534a09bd), + LL(0x759dba20,0x71a58b0c),LL(0x679c0b40,0x34d5f06c),LL(0xceed2f9f,0xdc0e7e5f),LL(0x48808edb,0xaaa5996e), LL(0xbcdd88e5,0x8ca96ff0),LL(0xc37c2b46,0x91b02d67),LL(0x95526319,0xbe4f3948),LL(0x89be56d1,0x4315c7f2), + LL(0xdc85bba1,0xa312a3c0),LL(0x431ca797,0x3328fa8e),LL(0x68fd219a,0x5438bf1c),LL(0x85837d74,0x98812c6f), LL(0xf8c96d49,0xe88c4913),LL(0xc2442aca,0xcc62e79c),LL(0x046655f1,0x4ef3c7d4),LL(0xdadab1ea,0x04a362ed), + LL(0x30a199cf,0x975e2f3c),LL(0x014a165a,0x831e04a9),LL(0xaa126719,0x1e1d3c53),LL(0x1bf707a0,0xc42661e0), LL(0xaa2da264,0x295b0738),LL(0x65d4ba34,0xb45f5ed8),LL(0x9f3938fa,0x27fb5a12),LL(0xcb26f86c,0x25fba614), + LL(0xcf3c1c4d,0x6bd41981),LL(0xa0dedafd,0xd6f9239c),LL(0xae55b97f,0x46882526),LL(0x81b628d4,0x8e6fa994), LL(0xdc0aa158,0xbdb314dd),LL(0x12ba2a17,0x35343678),LL(0x32e2e431,0xac018e83),LL(0xe65cc63e,0x43a64e35), + LL(0x0b6603ea,0x887f3a2a),LL(0x76b2673f,0xe015426c),LL(0x27edfe8a,0x59dc5530),LL(0x68d9ebf3,0xea9eacf3), LL(0xcc3e07ca,0x40301c8e),LL(0x0f57a2e6,0xd8cb9b5b),LL(0x60ec5864,0x542e6b52),LL(0x17f6affe,0xb8791dd6), + LL(0x798d9993,0x6735bd1c),LL(0xd5da393c,0x006d8b25),LL(0x49e6d0d2,0x1d675bdb),LL(0x8607f99e,0x331d9a10), LL(0x9dc4cd07,0x4ff8ab74),LL(0x64ea3192,0xa87d4ae1),LL(0x41196b5b,0xdde0d92e),LL(0xb2e010eb,0xa15ad47b), + LL(0xa5522a75,0x23e6003f),LL(0x84afa749,0xc6ef3f1b),LL(0x146d10a3,0x9a723f75),LL(0x119106b0,0x5fa99480), LL(0xc0013dba,0x01d500db),LL(0x548edbe0,0x10b30ada),LL(0xb04ffc6b,0xb2eb046e),LL(0x64f25ee2,0xa57088f3), + LL(0x83a068a3,0xc0c919c3),LL(0xfbde282f,0x8139559d),LL(0x9fec9a99,0x4e2b5d13),LL(0xfbefa7e6,0x53bad712), LL(0x2860bd4f,0xa6befe0d),LL(0x0011bd15,0x6ea0ae15),LL(0x2bce3779,0xc1ef3463),LL(0x5d742dbb,0xc09ecb30), + LL(0xf73db19d,0x29526afd),LL(0x6a029a40,0x7c02c905),LL(0xde5a48ba,0xa778460f),LL(0x77c105f6,0xda05993e), LL(0xc9ddece9,0xb6d599f9),LL(0x0cfc33ca,0x9f9df668),LL(0xa0aa67a8,0xdcd8ef4f),LL(0xc3f4d178,0x31277019), + LL(0x53e86ae1,0x98e05abf),LL(0x3850830d,0xc1dc4d90),LL(0xe06bc33c,0xbd7fd806),LL(0xacf1286f,0x1ac330d6), LL(0xe1588c1e,0x28ce2303),LL(0x1b7e9c19,0xdc25e54b),LL(0x4b7149f2,0x11e51e49),LL(0xb5c7fa25,0x551b8391), + LL(0x1bf69873,0xa2fc251c),LL(0x2aec1574,0x099b7b53),LL(0x7c53296a,0x9ff98156),LL(0xa2dc60de,0xaf3f8d08), LL(0x59b72d6c,0x18dd295c),LL(0xe75f44fc,0x165c9063),LL(0x427a0c55,0x9046ee7c),LL(0xc79ffdb3,0x317ea24d), + LL(0x0ef0447d,0x6835a315),LL(0x8068e7c7,0xb2b9c786),LL(0x0e646af5,0xe6352714),LL(0x442baaa0,0xc5554a91), LL(0x6d0ba1ea,0x671febc5),LL(0x0cf649ed,0x44f9ef7b),LL(0x0c1dac6b,0x4aa0cd61),LL(0x6e393e68,0x865f3c23), + LL(0xa71dee29,0xf6886bcd),LL(0xda44ffae,0x934b0455),LL(0x016d6039,0xda7621c4),LL(0x3ad35493,0xf36c41bf), LL(0xe5f6ab8d,0x9063135e),LL(0x47bdc0a8,0xb0e8eaba),LL(0x4c737cf3,0x62530616),LL(0x64f6b6cb,0x8046423e), + LL(0x7958e3dc,0x11e50ad7),LL(0xb57234ab,0x4dab4e16),LL(0xe0916210,0x6ccfe2c6),LL(0x80f49d40,0x4d5dbc3b), LL(0xef1b2b1b,0x2b8ff368),LL(0x752fea2a,0xf2afb326),LL(0x0246e36b,0xffa48ea7),LL(0x589b7444,0x3a4bae9b), + LL(0x6ff3efcf,0x80ff984a),LL(0x56b77b47,0x7af53f30),LL(0x9320cae6,0x1f1c33b0),LL(0x26fc4ad4,0xce1f1c48), LL(0xad350ee5,0x9cac662b),LL(0xe27a7dbd,0xf4c72fff),LL(0x703184e5,0xd766f986),LL(0x7c5b241e,0x36d3efd5), + LL(0xf7ff5804,0xd4d6e358),LL(0x8f5e0bf6,0xa832b302),LL(0x453d9a22,0x4b3d73f7),LL(0xdf938705,0xb4dae072), LL(0x92401620,0x6bff7b2e),LL(0x9bfa61cd,0x96b8494e),LL(0xb74dc1e5,0x4bcda341),LL(0xc19c393d,0x383fe3d2), + LL(0x077e8821,0xa375fb70),LL(0xc17eb9bc,0xea35e04b),LL(0x7c4dd076,0x941d21ba),LL(0x3d0c3d8a,0x916c0a59), LL(0x15b2cf47,0x2c1304e3),LL(0xd0c955c0,0x9233ebf3),LL(0x2b2fc935,0x77acdd07),LL(0xc04276bf,0xd71b6a7a), + LL(0xd2ee8d68,0x789ea49b),LL(0x0a84a920,0x89552b46),LL(0x1a4ea456,0xe629d5de),LL(0x22ddd405,0xddfefe87), LL(0x1cdb9e7b,0x3d56f697),LL(0xa8bf715b,0x95a861b0),LL(0x7896c993,0xb01248d6),LL(0x01a3085c,0x3c4e3d98), + LL(0x9085b360,0x674939e1),LL(0xb589a287,0xae67dea9),LL(0x2bfdcfc9,0xc563856f),LL(0x313b685d,0x62fa9a80), LL(0x7ad501d9,0x36ff33d9),LL(0x730ab349,0xf8bab4dd),LL(0xc46ba69d,0x18fd59f3),LL(0xe65278e9,0x81e08665), + LL(0xeb8a1e84,0x5a5e803f),LL(0x47243604,0x5b4eef35),LL(0x393d6cdf,0x0ee71ee0),LL(0xc3a9c6db,0xde4d9dea), LL(0x64466b53,0x0c14c376),LL(0x89e3b45e,0xc2ce9642),LL(0x54a2de21,0x6aa8012f),LL(0x29b6bc2c,0x519759c1), + LL(0xe4667322,0x17768527),LL(0xac83b2ea,0x09fdfe4d),LL(0x04a0d5f5,0xd422125d),LL(0x2b86b310,0x02e8ff96), LL(0xd7ee97af,0xf033628d),LL(0x7d72e0e6,0x778a846c),LL(0x882f63d6,0x06fde613),LL(0x8d434f14,0x9e258b0d), + LL(0xccdcd600,0x5cdda529),LL(0x033c4535,0x37038b38),LL(0x391c1d7d,0xd6a1d639),LL(0x31d4ce6b,0x4f6489e4), LL(0x5754e08c,0xd1b82f17),LL(0x75db7bd6,0x7df268ee),LL(0xad14dcfa,0x1e4a1202),LL(0xccfb9b77,0x7ab92ce2), + LL(0x23aef997,0x61388e03),LL(0x06440ce3,0x9981f5bf),LL(0xc67d0edd,0x8d7631da),LL(0xc0a93516,0xc6ea593f), LL(0xee841b38,0x064a06e0),LL(0x521ce83f,0x0d1d4f57),LL(0x70df2613,0xf7a0e0c3),LL(0x84c071ab,0x1506cccb), + LL(0x328565e9,0x42a138ec),LL(0xb8130d16,0xe16b4578),LL(0x45ba251a,0x0628ff22),LL(0x210e22e8,0x016a84ca), LL(0x94592d43,0x8ba14bb4),LL(0x785274a5,0xffee4308),LL(0x01354b75,0x01fc21ab),LL(0x7e424674,0xc37ce45f), + LL(0xa7fe2735,0x71e153af),LL(0xc307721f,0x000fcee9),LL(0x805b56e3,0x3b189004),LL(0x7f504d9b,0x2f1435aa), LL(0xa083bd72,0xd9aa1eba),LL(0x720ccf3d,0xf1145036),LL(0x4084fa32,0x95b29e27),LL(0x01f94f0c,0x8862d213), + LL(0x1510a406,0x23fc5ddf),LL(0xc9f0e98d,0x475a78f4),LL(0xe72843a0,0xb6d681c4),LL(0x4a00c5a6,0xa90af2a4), LL(0xa34f4412,0x95fc6d45),LL(0xe7f5d703,0x60f9c0e2),LL(0xad110925,0x2bc0642b),LL(0xbe24a4d5,0x79abfc10), +} +}; +#endif /* _DISABLE_ECP_SM2_HARDCODED_BP_TBL_ */ +#endif /* _IPP_DATA */ + + +IPP_OWN_DEFN (const cpPrecompAP*, gfpec_precom_sm2_fun, (void)) +{ + static cpPrecompAP t = { + /* w */ 7, + /* select function */ p256r1_select_ap_w7, + /* precomputed data */ (BNU_CHUNK_T*)precomputed_ec_sm2 + }; + return &t; +}; diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3ca.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm3ca.c new file mode 100644 index 000000000..d62e4eb90 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3ca.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// cpFinalizeSM3() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" + +IPP_OWN_DEFN (void, cpFinalizeSM3, (DigestSHA1 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u processedMsgLen)) +{ + /* local buffer and it length */ + Ipp8u buffer[MBS_SM3*2]; + int bufferLen = inpLen < (MBS_SM3-(int)MLR_SM3)? MBS_SM3 : MBS_SM3*2; + + /* copy rest of message into internal buffer */ + CopyBlock(inpBuffer, buffer, inpLen); + + /* padd message */ + buffer[inpLen++] = 0x80; + PadBlock(0, buffer+inpLen, (cpSize)(bufferLen-inpLen-(int)MLR_SM3)); + + /* put processed message length in bits */ + processedMsgLen = ENDIANNESS64(processedMsgLen<<3); + ((Ipp64u*)(buffer+bufferLen))[-1] = processedMsgLen; + + /* copmplete hash computation */ + UpdateSM3(pHash, buffer, bufferLen, sm3_cnt); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3duplicate.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm3duplicate.c new file mode 100644 index 000000000..e2726225e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3duplicate.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsSM3Duplicate() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSM3Duplicate +// +// Purpose: Clone SM3 state. +// +// Returns: Reason: +// ippStsNullPtrErr pSrcState == NULL +// pDstState == NULL +// ippStsContextMatchErr pSrcState->idCtx != idCtxSM3 +// pDstState->idCtx != idCtxSM3 +// ippStsNoErr no errors +// +// Parameters: +// pSrcState pointer to the source SM3 state +// pDstState pointer to the target SM3 state +// +// Note: +// pDstState may to be uninitialized by ippsSM3Init() +// +*F*/ +IPPFUN(IppStatus, ippsSM3Duplicate,(const IppsSM3State* pSrcState, IppsSM3State* pDstState)) +{ + /* test state pointers */ + IPP_BAD_PTR2_RET(pSrcState, pDstState); + IPP_BADARG_RET(!HASH_VALID_ID(pSrcState, idCtxSM3), ippStsContextMatchErr); + + /* copy state */ + CopyBlock(pSrcState, pDstState, sizeof(IppsSM3State)); + HASH_SET_ID(pDstState, idCtxSM3); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3final.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm3final.c new file mode 100644 index 000000000..904c6b1b5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3final.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsSM3Final() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" + +/*F* +// Name: ippsSM3Final +// +// Purpose: Stop message digesting and return digest. +// +// Returns: Reason: +// ippStsNullPtrErr pState == NULL +// pMD == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSM3 +// ippStsNoErr no errors +// +// Parameters: +// pMD address of the output digest +// pState pointer to the SM3 state +// +*F*/ +IPPFUN(IppStatus, ippsSM3Final,(Ipp8u* pMD, IppsSM3State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSM3), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pMD); + + cpFinalizeSM3(HASH_VALUE(pState), HASH_BUFF(pState), HASH_BUFFIDX(pState), HASH_LENLO(pState)); + /* convert hash into big endian */ + ((Ipp32u*)pMD)[0] = ENDIANNESS32(HASH_VALUE(pState)[0]); + ((Ipp32u*)pMD)[1] = ENDIANNESS32(HASH_VALUE(pState)[1]); + ((Ipp32u*)pMD)[2] = ENDIANNESS32(HASH_VALUE(pState)[2]); + ((Ipp32u*)pMD)[3] = ENDIANNESS32(HASH_VALUE(pState)[3]); + ((Ipp32u*)pMD)[4] = ENDIANNESS32(HASH_VALUE(pState)[4]); + ((Ipp32u*)pMD)[5] = ENDIANNESS32(HASH_VALUE(pState)[5]); + ((Ipp32u*)pMD)[6] = ENDIANNESS32(HASH_VALUE(pState)[6]); + ((Ipp32u*)pMD)[7] = ENDIANNESS32(HASH_VALUE(pState)[7]); + + /* re-init hash value */ + HASH_BUFFIDX(pState) = 0; + HASH_LENLO(pState) = 0; + sm3_hashInit(HASH_VALUE(pState)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3getsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm3getsize.c new file mode 100644 index 000000000..0c8ffbf14 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3getsize.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsSM3GetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSM3GetSize +// +// Purpose: Returns size (bytes) of IppsSM3State state. +// +// Returns: Reason: +// ippStsNullPtrErr pSize == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to state size +// +*F*/ +IPPFUN(IppStatus, ippsSM3GetSize,(int* pSize)) +{ + /* test pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = sizeof(IppsSM3State); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3gettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm3gettag.c new file mode 100644 index 000000000..be45f8344 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3gettag.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsSM3GetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" + +/*F* +// Name: ippsSM3GetTag +// +// Purpose: Compute digest based on current state. +// Note, that futher digest update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSM3 +// ippStsLengthErr max_SHA_digestLen < tagLen <1 +// ippStsNoErr no errors +// +// Parameters: +// pTag address of the output digest +// tagLen length of digest +// pState pointer to the SHS state +// +*F*/ +IPPFUN(IppStatus, ippsSM3GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSM3State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSM3), ippStsContextMatchErr); + + /* test digest pointer */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSM3)idCtx != idCtxSM3 +// ippStsNoErr no errors +// +// Parameters: +// pState pointer hash state +// pBuffer pointer to the destination buffer +// +*F*/ +IPPFUN(IppStatus, ippsSM3Pack,(const IppsSM3State* pState, Ipp8u* pBuffer)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSM3), ippStsContextMatchErr); + + CopyBlock(pState, pBuffer, sizeof(IppsSM3State)); + IppsSM3State* pCopy = (IppsSM3State*)pBuffer; + HASH_RESET_ID(pCopy, idCtxSM3); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3stuff.h b/plugin/ippcp/library/src/sources/ippcp/pcpsm3stuff.h new file mode 100644 index 000000000..937687b46 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3stuff.h @@ -0,0 +1,96 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// SM3 methods and constants +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +#if !defined _PCP_SM3_STUFF_H +#define _PCP_SM3_STUFF_H + +/* SM3 constants */ +static const Ipp32u sm3_iv[] = { + 0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600, + 0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E}; + +static __ALIGN16 const Ipp32u sm3_cnt[] = { + 0x79CC4519,0xF3988A32,0xE7311465,0xCE6228CB,0x9CC45197,0x3988A32F,0x7311465E,0xE6228CBC, + 0xCC451979,0x988A32F3,0x311465E7,0x6228CBCE,0xC451979C,0x88A32F39,0x11465E73,0x228CBCE6, + 0x9D8A7A87,0x3B14F50F,0x7629EA1E,0xEC53D43C,0xD8A7A879,0xB14F50F3,0x629EA1E7,0xC53D43CE, + 0x8A7A879D,0x14F50F3B,0x29EA1E76,0x53D43CEC,0xA7A879D8,0x4F50F3B1,0x9EA1E762,0x3D43CEC5, + 0x7A879D8A,0xF50F3B14,0xEA1E7629,0xD43CEC53,0xA879D8A7,0x50F3B14F,0xA1E7629E,0x43CEC53D, + 0x879D8A7A,0x0F3B14F5,0x1E7629EA,0x3CEC53D4,0x79D8A7A8,0xF3B14F50,0xE7629EA1,0xCEC53D43, + 0x9D8A7A87,0x3B14F50F,0x7629EA1E,0xEC53D43C,0xD8A7A879,0xB14F50F3,0x629EA1E7,0xC53D43CE, + 0x8A7A879D,0x14F50F3B,0x29EA1E76,0x53D43CEC,0xA7A879D8,0x4F50F3B1,0x9EA1E762,0x3D43CEC5 +}; + +IPP_OWN_DEFN (static void, sm3_hashInit, (void* pHash)) +{ + /* setup initial digest */ + ((Ipp32u*)pHash)[0] = sm3_iv[0]; + ((Ipp32u*)pHash)[1] = sm3_iv[1]; + ((Ipp32u*)pHash)[2] = sm3_iv[2]; + ((Ipp32u*)pHash)[3] = sm3_iv[3]; + ((Ipp32u*)pHash)[4] = sm3_iv[4]; + ((Ipp32u*)pHash)[5] = sm3_iv[5]; + ((Ipp32u*)pHash)[6] = sm3_iv[6]; + ((Ipp32u*)pHash)[7] = sm3_iv[7]; +} + +IPP_OWN_DEFN (static void, sm3_hashUpdate, (void* pHash, const Ipp8u* pMsg, int msgLen)) +{ + UpdateSM3(pHash, pMsg, msgLen, sm3_cnt); +} + +IPP_OWN_DEFN (static void, sm3_hashOctString, (Ipp8u* pMD, void* pHashVal)) +{ + /* convert hash into big endian */ + ((Ipp32u*)pMD)[0] = ENDIANNESS32(((Ipp32u*)pHashVal)[0]); + ((Ipp32u*)pMD)[1] = ENDIANNESS32(((Ipp32u*)pHashVal)[1]); + ((Ipp32u*)pMD)[2] = ENDIANNESS32(((Ipp32u*)pHashVal)[2]); + ((Ipp32u*)pMD)[3] = ENDIANNESS32(((Ipp32u*)pHashVal)[3]); + ((Ipp32u*)pMD)[4] = ENDIANNESS32(((Ipp32u*)pHashVal)[4]); + ((Ipp32u*)pMD)[5] = ENDIANNESS32(((Ipp32u*)pHashVal)[5]); + ((Ipp32u*)pMD)[6] = ENDIANNESS32(((Ipp32u*)pHashVal)[6]); + ((Ipp32u*)pMD)[7] = ENDIANNESS32(((Ipp32u*)pHashVal)[7]); +} + +IPP_OWN_DEFN (static void, sm3_msgRep, (Ipp8u* pDst, Ipp64u lenLo, Ipp64u lenHi)) +{ + IPP_UNREFERENCED_PARAMETER(lenHi); + lenLo = ENDIANNESS64(lenLo<<3); + ((Ipp64u*)(pDst))[0] = lenLo; +} + +#define cpFinalizeSM3 OWNAPI(cpFinalizeSM3) + IPP_OWN_DECL (void, cpFinalizeSM3, (DigestSHA1 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u processedMsgLen)) + +#endif /* #if !defined _PCP_SM3_STUFF_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3unpack.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm3unpack.c new file mode 100644 index 000000000..07114e929 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3unpack.c @@ -0,0 +1,58 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsSM3Unpack() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +/*F* +// Name: ippsSM3Unpack +// +// Purpose: Unpack buffer content into the initialized context. +// +// Returns: Reason: +// ippStsNullPtrErr pBuffer == NULL +// pState == NULL +// ippStsNoErr no errors +// +// Parameters: +// pBuffer pointer to the input buffer +// pState pointer hash state +// +*F*/ +IPPFUN(IppStatus, ippsSM3Unpack,(const Ipp8u* pBuffer, IppsSM3State* pState)) +{ + /* test pointers */ + IPP_BAD_PTR2_RET(pState, pBuffer); + + CopyBlock(pBuffer, pState, sizeof(IppsSM3State)); + HASH_SET_ID(pState, idCtxSM3); + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsm3update.c b/plugin/ippcp/library/src/sources/ippcp/pcpsm3update.c new file mode 100644 index 000000000..dfd3f2417 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsm3update.c @@ -0,0 +1,113 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsSM3Update() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" + +/*F* +// Name: ippsSM3Update +// +// Purpose: Updates intermediate digest based on input stream. +// +// Returns: Reason: +// ippStsNullPtrErr pSrc == NULL +// pState == NULL +// ippStsContextMatchErr pState->idCtx != idCtxSM3 +// ippStsLengthErr len <0 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the input stream +// len input stream length +// pState pointer to the SM3 state +// +*F*/ +IPPFUN(IppStatus, ippsSM3Update,(const Ipp8u* pSrc, int len, IppsSM3State* pState)) +{ + /* test state pointer and ID */ + IPP_BAD_PTR1_RET(pState); + IPP_BADARG_RET(!HASH_VALID_ID(pState, idCtxSM3), ippStsContextMatchErr); + + /* test input length */ + IPP_BADARG_RET((len<0), ippStsLengthErr); + /* test source pointer */ + IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr); + + /* + // handle non empty message + */ + if(len) { + int procLen; + + int idx = HASH_BUFFIDX(pState); + Ipp8u* pBuffer = HASH_BUFF(pState); + Ipp64u lenLo = HASH_LENLO(pState) + (Ipp64u)len; + + /* if non empty internal buffer filling */ + if(idx) { + /* copy from input stream to the internal buffer as match as possible */ + procLen = IPP_MIN(len, (MBS_SM3-idx)); + CopyBlock(pSrc, pBuffer+idx, procLen); + + /* update message pointer and length */ + idx += procLen; + pSrc += procLen; + len -= procLen; + + /* update digest if buffer full */ + if( MBS_SM3 == idx) { + UpdateSM3(HASH_VALUE(pState), pBuffer, MBS_SM3, sm3_cnt); + idx = 0; + } + } + + /* main message part processing */ + procLen = len & ~(MBS_SM3-1); + if(procLen) { + UpdateSM3(HASH_VALUE(pState), pSrc, procLen, sm3_cnt); + pSrc += procLen; + len -= procLen; + } + + /* store rest of message into the internal buffer */ + if(len) { + CopyBlock(pSrc, pBuffer, len); + idx += len; + } + + /* update length of processed message */ + HASH_LENLO(pState) = lenLo; + HASH_BUFFIDX(pState) = idx; + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4.h new file mode 100644 index 000000000..d40d8dee7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4.h @@ -0,0 +1,185 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Internal Definitions and +// Internal SMS4 Function Prototypes +// +// +*/ + +#if !defined(_PCP_SMS4_H) +#define _PCP_SMS4_H + +#include "owncp.h" +#include "pcpmask_ct.h" + +/* SMS4 round keys number */ +#define SMS4_ROUND_KEYS_NUM (32) + +#if SMS4_ROUND_KEYS_NUM != 32 + #error SMS4_ROUND_KEYS_NUM must be equal 32 +#endif + +struct _cpSMS4 { + Ipp32u idCtx; /* SMS4 spec identifier */ + Ipp32u enc_rkeys[SMS4_ROUND_KEYS_NUM]; /* enc round keys */ + Ipp32u dec_rkeys[SMS4_ROUND_KEYS_NUM]; /* dec round keys */ +}; + +/* +// access macros +*/ +#define SMS4_SET_ID(ctx) ((ctx)->idCtx = (Ipp32u)idCtxSMS4 ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define SMS4_RK(ctx) ((ctx)->enc_rkeys) +#define SMS4_ERK(ctx) ((ctx)->enc_rkeys) +#define SMS4_DRK(ctx) ((ctx)->dec_rkeys) + +/* SMS4 data block size (bytes) */ +#define MBS_SMS4 (16) + +#if MBS_SMS4 != 16 + #error MBS_SMS4 must be equal 16 +#endif + +/* valid SMS4 context ID */ +#define VALID_SMS4_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxSMS4) + +/* alignment of AES context */ +#define SMS4_ALIGNMENT (4) + +/* size of SMS4 context */ +__INLINE int cpSizeofCtx_SMS4(void) +{ + return sizeof(IppsSMS4Spec); +} + +/* SMS4 constants */ +extern const __ALIGN64 Ipp8u SMS4_Sbox[16*16]; +extern const Ipp32u SMS4_FK[4]; +extern const Ipp32u SMS4_CK[32]; + +////////////////////////////////////////////////////////////////////////////////////////////////////// +/* S-box substitution (endian dependent!) */ + +#include "pcpbnuimpl.h" +#define SELECTION_BITS ((sizeof(BNU_CHUNK_T)/sizeof(Ipp8u)) -1) + +__INLINE Ipp8u getSboxValue(Ipp8u x) +{ + BNU_CHUNK_T selection = 0; + const Ipp8u* SboxEntry = SMS4_Sbox; + + Ipp32u i; + for (i = 0; i> 8) & 0xFF) <<8); + y |= (Ipp32u)(getSboxValue((x>>16) & 0xFF) <<16); + y |= (Ipp32u)(getSboxValue((x>>24) & 0xFF) <<24); + return y; +} + +/* key expansion transformation: + - linear Linear + - mixer Mix (permutation T in the SMS4 standart phraseology) +*/ +__INLINE Ipp32u cpExpKeyLinear_SMS4(Ipp32u x) +{ + return x^ROL32(x,13)^ROL32(x,23); +} + +__INLINE Ipp32u cpExpKeyMix_SMS4(Ipp32u x) +{ + return cpExpKeyLinear_SMS4( cpSboxT_SMS4(x) ); +} + +/* cipher transformations: + - linear Linear + - mixer Mix (permutation T in the SMS4 standart phraseology) +*/ +__INLINE Ipp32u cpCipherLinear_SMS4(Ipp32u x) +{ + return x^ROL32(x,2)^ROL32(x,10)^ROL32(x,18)^ROL32(x,24); +} + +__INLINE Ipp32u cpCipherMix_SMS4(Ipp32u x) +{ + return cpCipherLinear_SMS4( cpSboxT_SMS4(x) ); +} +////////////////////////////////////////////////////////////////////////////////////////////// + + +#define cpSMS4_Cipher OWNAPI(cpSMS4_Cipher) + IPP_OWN_DECL (void, cpSMS4_Cipher, (Ipp8u* otxt, const Ipp8u* itxt, const Ipp32u* pRoundKeys)) + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) +#define cpSMS4_SetRoundKeys_aesni OWNAPI(cpSMS4_SetRoundKeys_aesni) + IPP_OWN_DECL (void, cpSMS4_SetRoundKeys_aesni, (Ipp32u* pRounKey, const Ipp8u* pSecretKey)) + +#define cpSMS4_ECB_aesni_x1 OWNAPI(cpSMS4_ECB_aesni_x1) + IPP_OWN_DECL (void, cpSMS4_ECB_aesni_x1, (Ipp8u* pOut, const Ipp8u* pInp, const Ipp32u* pRKey)) +#define cpSMS4_ECB_aesni OWNAPI(cpSMS4_ECB_aesni) + IPP_OWN_DECL (int, cpSMS4_ECB_aesni, (Ipp8u* pDst, const Ipp8u* pSrc, int nLen, const Ipp32u* pRKey)) +#define cpSMS4_CBC_dec_aesni OWNAPI(cpSMS4_CBC_dec_aesni) + IPP_OWN_DECL (int, cpSMS4_CBC_dec_aesni, (Ipp8u* pDst, const Ipp8u* pSrc, int nLen, const Ipp32u* pRKey, Ipp8u* pIV)) +#define cpSMS4_CTR_aesni OWNAPI(cpSMS4_CTR_aesni) + IPP_OWN_DECL (int, cpSMS4_CTR_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr)) + +#if (_IPP>=_IPP_H9) || (_IPP32E>=_IPP32E_L9) +#define cpSMS4_ECB_aesni_x12 OWNAPI(cpSMS4_ECB_aesni_x12) + IPP_OWN_DECL (int, cpSMS4_ECB_aesni_x12, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) +#define cpSMS4_CBC_dec_aesni_x12 OWNAPI(cpSMS4_CBC_dec_aesni_x12) + IPP_OWN_DECL (int, cpSMS4_CBC_dec_aesni_x12, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV)) +#define cpSMS4_CTR_aesni_x4 OWNAPI(cpSMS4_CTR_aesni_x4) + IPP_OWN_DECL (int, cpSMS4_CTR_aesni_x4, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr)) + +#if (_IPP32E>=_IPP32E_K1) +#if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + +#define cpSMS4_ECB_gfni_x1 OWNAPI(cpSMS4_ECB_gfni_x1) + IPP_OWN_DECL (void, cpSMS4_ECB_gfni_x1, (Ipp8u* pOut, const Ipp8u* pInp, const Ipp32u* pRKey)) +#define cpSMS4_ECB_gfni512 OWNAPI(cpSMS4_ECB_gfni512) + IPP_OWN_DECL (int, cpSMS4_ECB_gfni512, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) +#define cpSMS4_CBC_dec_gfni512 OWNAPI(cpSMS4_CBC_dec_gfni512) + IPP_OWN_DECL (int, cpSMS4_CBC_dec_gfni512, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV)) +#define cpSMS4_CTR_gfni512 OWNAPI(cpSMS4_CTR_gfni512) + IPP_OWN_DECL (int, cpSMS4_CTR_gfni512, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr)) +#define cpSMS4_CFB_dec_gfni512 OWNAPI(cpSMS4_CFB_dec_gfni512) + IPP_OWN_DECL (void, cpSMS4_CFB_dec_gfni512, (Ipp8u* pOut, const Ipp8u* pInp, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV)) + +#endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ +#endif /* (_IPP32E>=_IPP32E_K1) */ + +#endif /* (_IPP>=_IPP_H9) || (_IPP32E>=_IPP32E_L9) */ + +#endif + +#define cpProcessSMS4_ctr OWNAPI(cpProcessSMS4_ctr) + IPP_OWN_DECL (IppStatus, cpProcessSMS4_ctr, (const Ipp8u* pSrc, Ipp8u* pDst, int dataLen, const IppsSMS4Spec* pCtx, Ipp8u* pCtrValue, int ctrNumBitSize)) + +#endif /* _PCP_SMS4_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cbc_gfni.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cbc_gfni.c new file mode 100644 index 000000000..044c451f5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cbc_gfni.c @@ -0,0 +1,1267 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 ECB decryption +// +// Contents: +// cpSMS4_ECB_gfni512() +// cpSMS4_CBC_dec_gfni512x48() +// cpSMS4_CBC_dec_gfni512x32() +// cpSMS4_CBC_dec_gfni512x16() +// cpSMS4_CBC_dec_gfni128x12() +// cpSMS4_CBC_dec_gfni128x8() +// cpSMS4_CBC_dec_gfni128x4() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +#if (_IPP32E>=_IPP32E_K1) + +#if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + +#include "pcpsms4_gfni.h" + +static +int cpSMS4_CBC_dec_gfni512x48(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV); +static +int cpSMS4_CBC_dec_gfni512x32(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV); +static +int cpSMS4_CBC_dec_gfni512x16(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV); +static +int cpSMS4_CBC_dec_gfni128x12(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV); +static +int cpSMS4_CBC_dec_gfni128x8(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV); +static +int cpSMS4_CBC_dec_gfni128x4(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV); + +/* +// 64*MBS_SMS4 bytes processing +*/ + +IPP_OWN_DEFN (int, cpSMS4_CBC_dec_gfni512, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV)) +{ + __ALIGN16 __m512i TMP[21]; + + __m128i IV = _mm_loadu_si128((__m128i*)(pIV)); // Non-secret data + + int processedLen = len - (len % (64 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (64 * MBS_SMS4), pInp += (64 * MBS_SMS4), pOut += (64 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 32)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 36)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 40)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 44)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 48)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 52)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 56)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 60)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + TMP[12] = _mm512_xor_si512(_mm512_xor_si512(TMP[12], TMP[2]), L512(TMP[2])); + TMP[16] = _mm512_xor_si512(_mm512_xor_si512(TMP[16], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + TMP[13] = _mm512_xor_si512(_mm512_xor_si512(TMP[13], TMP[2]), L512(TMP[2])); + TMP[17] = _mm512_xor_si512(_mm512_xor_si512(TMP[17], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + TMP[14] = _mm512_xor_si512(_mm512_xor_si512(TMP[14], TMP[2]), L512(TMP[2])); + TMP[18] = _mm512_xor_si512(_mm512_xor_si512(TMP[18], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + TMP[15] = _mm512_xor_si512(_mm512_xor_si512(TMP[15], TMP[2]), L512(TMP[2])); + TMP[19] = _mm512_xor_si512(_mm512_xor_si512(TMP[19], TMP[3]), L512(TMP[3])); + } + + pRKey -= 32; + + /* Prepare the first block for xor*/ + + TMP[20] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[20] = _mm512_alignr_epi64(TMP[20], TMP[20], 6); + TMP[20] = _mm512_inserti64x2(TMP[20], IV, 0); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[4] = _mm512_xor_si512(TMP[0], TMP[20]); + TMP[5] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*3))); + TMP[6] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*7))); + TMP[7] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*11))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[8] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*15))); + TMP[9] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*19))); + TMP[10] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*23))); + TMP[11] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*27))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[12] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*31))); + TMP[13] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*35))); + TMP[14] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*39))); + TMP[15] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*43))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[16] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*47))); + TMP[17] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*51))); + TMP[18] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*55))); + TMP[19] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*59))); + + IV = _mm_loadu_si128((__m128i*)(pInp+MBS_SMS4*63)); // Ciphertext, non-secret data + + _mm512_storeu_si512((__m512i*)(pOut), TMP[4]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[5]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[6]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[7]); + + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), TMP[8]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), TMP[9]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), TMP[10]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), TMP[11]); + + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 32), TMP[12]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 36), TMP[13]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 40), TMP[14]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 44), TMP[15]); + + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 48), TMP[16]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 52), TMP[17]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 56), TMP[18]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 60), TMP[19]); + } + + _mm_storeu_si128((__m128i*)(pIV), IV); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len){ + if(len < 256){ + processedLen += cpSMS4_CBC_dec_gfni128x12(pOut, pInp, len, pRKey, pIV); + return processedLen; + } + processedLen += cpSMS4_CBC_dec_gfni512x48(pOut, pInp, len, pRKey, pIV); + } + + return processedLen; +} + +/* +// 48*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_CBC_dec_gfni512x48(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m512i TMP[17]; + + __m128i IV = _mm_loadu_si128((__m128i*)(pIV)); // Non-secret data + + int processedLen = len - (len % (48 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (48 * MBS_SMS4), pInp += (48 * MBS_SMS4), pOut += (48 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 32)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 36)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 40)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 44)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + TMP[12] = _mm512_xor_si512(_mm512_xor_si512(TMP[12], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + TMP[13] = _mm512_xor_si512(_mm512_xor_si512(TMP[13], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + TMP[14] = _mm512_xor_si512(_mm512_xor_si512(TMP[14], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + TMP[15] = _mm512_xor_si512(_mm512_xor_si512(TMP[15], TMP[2]), L512(TMP[2])); + } + + pRKey -= 32; + + /* Prepare the first block for xor*/ + + TMP[16] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[16] = _mm512_alignr_epi64(TMP[16], TMP[16], 6); + TMP[16] = _mm512_inserti64x2(TMP[16], IV, 0); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[4] = _mm512_xor_si512(TMP[0], TMP[16]); + TMP[5] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*3))); + TMP[6] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*7))); + TMP[7] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*11))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[8] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*15))); + TMP[9] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*19))); + TMP[10] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*23))); + TMP[11] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*27))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[12] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*31))); + TMP[13] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*35))); + TMP[14] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*39))); + TMP[15] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*43))); + + IV = _mm_loadu_si128((__m128i*)(pInp+MBS_SMS4*47)); // Ciphertext, non-secret data + + _mm512_storeu_si512((__m512i*)(pOut), TMP[4]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[5]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[6]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[7]); + + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), TMP[8]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), TMP[9]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), TMP[10]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), TMP[11]); + + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 32), TMP[12]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 36), TMP[13]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 40), TMP[14]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 44), TMP[15]); + } + + _mm_storeu_si128((__m128i*)(pIV), IV); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_CBC_dec_gfni512x32(pOut, pInp, len, pRKey, pIV); + + return processedLen; +} + +/* +// 32*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_CBC_dec_gfni512x32(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m512i TMP[13]; + + __m128i IV = _mm_loadu_si128((__m128i*)(pIV)); // Non-secret data + + int processedLen = len - (len % (32 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (32 * MBS_SMS4), pInp += (32 * MBS_SMS4), pOut += (32 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + } + + pRKey -= 32; + + /* Prepare the first block for xor*/ + + TMP[12] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[12] = _mm512_alignr_epi64(TMP[12], TMP[12], 6); + TMP[12] = _mm512_inserti64x2(TMP[12], IV, 0); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[4] = _mm512_xor_si512(TMP[0], TMP[12]); + TMP[5] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*3))); + TMP[6] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*7))); + TMP[7] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*11))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[8] = _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*15))); + TMP[9] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*19))); + TMP[10] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*23))); + TMP[11] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*27))); + + IV = _mm_loadu_si128((__m128i*)(pInp+MBS_SMS4*31)); // Ciphertext, non-secret data + + _mm512_storeu_si512((__m512i*)(pOut), TMP[4]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[5]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[6]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[7]); + + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), TMP[8]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), TMP[9]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), TMP[10]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), TMP[11]); + } + + _mm_storeu_si128((__m128i*)(pIV), IV); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_CBC_dec_gfni512x16(pOut, pInp, len, pRKey, pIV); + + return processedLen; +} + +/* +// 16*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_CBC_dec_gfni512x16(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m512i TMP[9]; + + __m128i IV = _mm_loadu_si128((__m128i*)(pIV)); // Non-secret data + + int processedLen = len - (len % (16 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (16 * MBS_SMS4), pInp += (16 * MBS_SMS4), pOut += (16 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + TMP[8] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[8] = _mm512_alignr_epi64(TMP[8], TMP[8], 6); + TMP[8] = _mm512_inserti64x2(TMP[8], IV, 0); + + TMP[4] = _mm512_xor_si512(TMP[0], TMP[8]); + TMP[5] = _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*3))); + TMP[6] = _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*7))); + TMP[7] = _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp+MBS_SMS4*11))); + + IV = _mm_loadu_si128((__m128i*)(pInp+MBS_SMS4*15)); // Ciphertext, non-secret data + + _mm512_storeu_si512((__m512i*)(pOut), TMP[4]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[5]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[6]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[7]); + } + + _mm_storeu_si128((__m128i*)(pIV), IV); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_CBC_dec_gfni128x12(pOut, pInp, len, pRKey, pIV); + + return processedLen; +} + +/* +// 12*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_CBC_dec_gfni128x12(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m128i TMP[19]; + TMP[3] = _mm_loadu_si128((__m128i*)(pIV)); + + int processedLen = len -(len % (12*MBS_SMS4)); + int n; + for(n=0; n= 1920) */ + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmdecrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmdecrypt.c new file mode 100644 index 000000000..ea6753130 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmdecrypt.c @@ -0,0 +1,188 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsSMS4_CCMDecrypt() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4authccm.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4_CCMDecrypt +// +// Purpose: Decrypts data and updates authentication tag. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr !VALID_SMS4CCM_ID() +// ippStsLengthErr if exceed overall length of message is being processed +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the cipher text beffer +// pDst pointer to the plane text bubber +// len length of the bugger +// pCtx pointer to the CCM context +// +*F*/ + +/* +// +// NOTE +// +// We consider to not spend time for further optimizing of this algoritm because it is not widely using. +// There is two ways for further optimization: +// - Add parallel processing of CTR cipher. Performance advantages can be achieved by parallel processing of a big number of blocks. +// - Try to decreace the memory reading/writing operation number, eg combine two calls of one block encryption +// function to single call that procees two blocks with the same key. Performance advantages can be achieved by +// reducing of reading/writing operations number, because we do not need to read the key twice in single loop. +// +*/ + +IPPFUN(IppStatus, ippsSMS4_CCMDecrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsSMS4_CCMState* pCtx)) +{ + /* test pCtx pointer */ + IPP_BAD_PTR1_RET(pCtx); + + /* test state ID */ + IPP_BADARG_RET(!VALID_SMS4CCM_ID(pCtx), ippStsContextMatchErr); + + /* test source/destination data */ + IPP_BAD_PTR2_RET(pSrc, pDst); + + /* test message length */ + IPP_BADARG_RET(len<0 || SMS4CCM_LENPRO(pCtx)+(Ipp64u)len >SMS4CCM_MSGLEN(pCtx), ippStsLengthErr); + + /* + // enctypt payload and update MAC + */ + if(len) { + /* SMS4 context */ + IppsSMS4Spec* pSMS4 = SMS4CCM_CIPHER(pCtx); + + /* buffer for secret data */ + __ALIGN16 Ipp32u TMP[3*(MBS_SMS4/sizeof(Ipp32u))+6]; + + /* + MAC size = MBS_SMS4/sizeof(Ipp32u) + CTR size = MBS_SMS4/sizeof(Ipp32u) + S size = MBS_SMS4/sizeof(Ipp32u) + flag size = 1 + qLen size = 1 + tmpLen size = 1 + counterVal size = 1 + counterEnc size = 2 + */ + + Ipp32u* MAC = TMP; + Ipp32u* CTR = TMP + MBS_SMS4/sizeof(Ipp32u); + Ipp32u* S = TMP + 2*(MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* flag = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* qLen = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 1; + Ipp32u* tmpLen = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 2; + Ipp32u* counterVal = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 3; + Ipp32u* counterEnc = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 4; + + *flag = (Ipp32u)( SMS4CCM_LENPRO(pCtx) &(MBS_SMS4-1) ); + + /* extract from the state */ + CopyBlock16(SMS4CCM_MAC(pCtx), MAC); + CopyBlock16(SMS4CCM_CTR0(pCtx), CTR); + CopyBlock16(SMS4CCM_Si(pCtx), S); + *counterVal = SMS4CCM_COUNTER(pCtx); + + /* extract qLen */ + *qLen = (((Ipp8u*)CTR)[0] &0x7) +1; /* &0x7 just to fix KW issue */ + + if(*flag) { + *tmpLen = (Ipp32u)( IPP_MIN(len, MBS_SMS4-1) ); + XorBlock(pSrc, (Ipp8u*)S+*flag, pDst, (Ipp32s)(*tmpLen)); + + /* copy as much input as possible into the internal buffer*/ + CopyBlock(pDst, SMS4CCM_BLK(pCtx)+*flag, (cpSize)(*tmpLen)); + + /* update MAC */ + if(*flag+*tmpLen == MBS_SMS4) { + XorBlock16(MAC, SMS4CCM_BLK(pCtx), MAC); + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + } + + SMS4CCM_LENPRO(pCtx) += *tmpLen; + pSrc += *tmpLen; + pDst += *tmpLen; + len -= *tmpLen; + } + + while(len >= MBS_SMS4) { + /* increment counter and format counter block */ + *counterVal+=1; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)(*qLen), *counterVal), ((Ipp8u*)CTR)+MBS_SMS4-*qLen, (cpSize)(*qLen)); + /* encode counter block */ + cpSMS4_Cipher((Ipp8u*)S, (Ipp8u*)CTR, SMS4_RK(pSMS4)); + + /* store cipher text */ + XorBlock16(pSrc, S, pDst); + + /* update MAC */ + XorBlock16(MAC, pDst, MAC); + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + + SMS4CCM_LENPRO(pCtx) += MBS_SMS4; + pSrc += MBS_SMS4; + pDst += MBS_SMS4; + len -= MBS_SMS4; + } + + if(len) { + /* increment counter and format counter block */ + *counterVal+=1; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)(*qLen), *counterVal), ((Ipp8u*)CTR)+MBS_SMS4-*qLen, (cpSize)(*qLen)); + /* encode counter block */ + cpSMS4_Cipher((Ipp8u*)S, (Ipp8u*)CTR, SMS4_RK(pSMS4)); + + /* store cipher text */ + XorBlock(pSrc, S, pDst, len); + + /* workaround to avoid false positive stringop-overflow error on gcc10.1 and gcc11.1 */ + len = ( IPP_MIN(len, MBS_SMS4-1) ); + + /* store partial data block */ + CopyBlock(pDst, SMS4CCM_BLK(pCtx), len); + + SMS4CCM_LENPRO(pCtx) += (Ipp64u)len; + } + + /* update state */ + CopyBlock16(MAC, SMS4CCM_MAC(pCtx)); + CopyBlock16(S, SMS4CCM_Si(pCtx)); + SMS4CCM_COUNTER(pCtx) = *counterVal; + + /* clear secret data */ + PurgeBlock(TMP, sizeof(TMP)); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmencrypt.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmencrypt.c new file mode 100644 index 000000000..a371278bb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmencrypt.c @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives. Cryptography Primitives. +// +// Context: +// ippsSMS4_CCMEncrypt() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4authccm.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4_CCMEncrypt +// +// Purpose: Encrypts data and updates authentication tag. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx== NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr !VALID_SMS4CCM_ID() +// ippStsLengthErr if exceed overall length of message is being processed +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the plane text beffer +// pDst pointer to the cipher text bubber +// len length of the buffer +// pCtx pointer to the CCM context +// +*F*/ + +/* +// +// NOTE +// +// We consider to not spend time for further optimizing of this algoritm because it is not widely using. +// There is two ways for further optimization: +// - Add parallel processing of CTR cipher. Performance advantages can be achieved by parallel processing of a big number of blocks. +// - Try to decreace the memory reading/writing operation number, eg combine two calls of one block encryption +// function to single call that procees two blocks with the same key. Performance advantages can be achieved by +// reducing of reading/writing operations number, because we do not need to read the key twice in single loop. +// +*/ + +IPPFUN(IppStatus, ippsSMS4_CCMEncrypt,(const Ipp8u* pSrc, Ipp8u* pDst, int len, IppsSMS4_CCMState* pCtx)) +{ + /* test pCtx pointer */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!VALID_SMS4CCM_ID(pCtx), ippStsContextMatchErr); + + /* test source/destination data */ + IPP_BAD_PTR2_RET(pSrc, pDst); + + /* test message length */ + IPP_BADARG_RET(len<0 || SMS4CCM_LENPRO(pCtx)+(Ipp64u)len >SMS4CCM_MSGLEN(pCtx), ippStsLengthErr); + + /* + // enctypt payload and update MAC + */ + if(len) { + /* SMS4 context */ + IppsSMS4Spec* pSMS4 = SMS4CCM_CIPHER(pCtx); + + /* buffer for secret data */ + __ALIGN16 Ipp32u TMP[3*(MBS_SMS4/sizeof(Ipp32u))+6]; + + /* + MAC size = MBS_SMS4/sizeof(Ipp32u) + CTR size = MBS_SMS4/sizeof(Ipp32u) + S size = MBS_SMS4/sizeof(Ipp32u) + flag size = 1 + qLen size = 1 + tmpLen size = 1 + counterVal size = 1 + counterEnc size = 2 + */ + + Ipp32u* MAC = TMP; + Ipp32u* CTR = TMP + MBS_SMS4/sizeof(Ipp32u); + Ipp32u* S = TMP + 2*(MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* flag = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* qLen = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 1; + Ipp32u* tmpLen = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 2; + Ipp32u* counterVal = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 3; + Ipp32u* counterEnc = TMP + 3*(MBS_SMS4/sizeof(Ipp32u)) + 4; + + *flag = (Ipp32u)( SMS4CCM_LENPRO(pCtx) &(MBS_SMS4-1) ); + + /* extract from the state */ + CopyBlock16(SMS4CCM_MAC(pCtx), MAC); + CopyBlock16(SMS4CCM_CTR0(pCtx), CTR); + CopyBlock16(SMS4CCM_Si(pCtx), S); + *counterVal = SMS4CCM_COUNTER(pCtx); + + /* extract qLen */ + *qLen = (((Ipp8u*)CTR)[0] &0x7) +1; /* &0x7 just to fix KW issue */ + + if(*flag) { + *tmpLen = IPP_MIN((Ipp32u)len, MBS_SMS4-1); + + /* copy as much input as possible into the internal buffer*/ + CopyBlock(pSrc, SMS4CCM_BLK(pCtx)+*flag, (cpSize)(*tmpLen)); + + XorBlock(pSrc, (Ipp8u*)S+*flag, pDst, (cpSize)(*tmpLen)); + + /* update MAC */ + if(*flag+*tmpLen == MBS_SMS4) { + XorBlock16(MAC, SMS4CCM_BLK(pCtx), MAC); + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + } + + SMS4CCM_LENPRO(pCtx) += (Ipp32u)*tmpLen; + pSrc += *tmpLen; + pDst += *tmpLen; + len -= *tmpLen; + } + + while(len >= MBS_SMS4) { + /* update MAC */ + XorBlock16(MAC, pSrc, MAC); + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + + /* increment counter and format counter block */ + *counterVal+=1; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)(*qLen), *counterVal), ((Ipp8u*)CTR)+MBS_SMS4-*qLen, (Ipp32s)(*qLen)); + /* encode counter block */ + cpSMS4_Cipher((Ipp8u*)S, (Ipp8u*)CTR, SMS4_RK(pSMS4)); + + /* store cipher text */ + XorBlock16(pSrc, S, pDst); + + SMS4CCM_LENPRO(pCtx) += MBS_SMS4; + pSrc += MBS_SMS4; + pDst += MBS_SMS4; + len -= MBS_SMS4; + } + + if(len) { + /* workaround to avoid false positive stringop-overflow error on gcc10.1 and gcc11.1 */ + len = ( IPP_MIN(len, MBS_SMS4-1) ); + + /* store partial data block */ + CopyBlock(pSrc, SMS4CCM_BLK(pCtx), len); + + /* increment counter and format counter block */ + *counterVal+=1; + CopyBlock(CounterEnc(counterEnc, (Ipp32s)(*qLen), *counterVal), ((Ipp8u*)CTR)+MBS_SMS4-*qLen, (Ipp32s)(*qLen)); + /* encode counter block */ + cpSMS4_Cipher((Ipp8u*)S, (Ipp8u*)CTR, SMS4_RK(pSMS4)); + + /* store cipher text */ + XorBlock(pSrc, S, pDst, len); + + SMS4CCM_LENPRO(pCtx) += (Ipp64u)len; + } + + /* update state */ + CopyBlock16(MAC, SMS4CCM_MAC(pCtx)); + CopyBlock16(S, SMS4CCM_Si(pCtx)); + SMS4CCM_COUNTER(pCtx) = *counterVal; + + /* clear secret data */ + PurgeBlock(TMP, sizeof(TMP)); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmgetsize.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmgetsize.c new file mode 100644 index 000000000..ee30b10d1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmgetsize.c @@ -0,0 +1,54 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// SMS4-CCM implementation. +// +// Content: +// ippsSMS4_CCMGetSize() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4authccm.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4_CCMGetSize +// +// Purpose: Returns size of SMS4-CCM state (bytes). +// +// Returns: Reason: +// ippStsNullPtrErr pSzie == NULL +// ippStsNoErr no errors +// +// Parameters: +// pSize pointer to the size of CCM (in bytes) +// +*F*/ +IPPFUN(IppStatus, ippsSMS4_CCMGetSize,(int * pSize)) +{ + /* test size's pointer */ + IPP_BAD_PTR1_RET(pSize); + + *pSize = cpSizeofCtx_SMS4CCM(); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmgettag.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmgettag.c new file mode 100644 index 000000000..a031d3f22 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmgettag.c @@ -0,0 +1,100 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// SMS4-CCM implementation. +// +// Content: +// ippsSMS4_CCMGetTag() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4authccm.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4_CCMGetTag +// +// Purpose: Compute message auth tag and return one. +// Note, that futher encryption/decryption and auth tag update is possible +// +// Returns: Reason: +// ippStsNullPtrErr pTag == NULL +// pCtx == NULL +// ippStsContextMatchErr !VALID_SMS4CCM_ID() +// ippStsLengthErr MBS_SMS4 < tagLen +// 1 > tagLen +// ippStsNoErr no errors +// +// Parameters: +// pTag pointer to the output authenticated tag +// tagLen requested length of the tag +// pCtx pointer to the CCM context +// +*F*/ +IPPFUN(IppStatus, ippsSMS4_CCMGetTag,(Ipp8u* pTag, int tagLen, const IppsSMS4_CCMState* pCtx)) +{ + /* test pCtx pointer */ + IPP_BAD_PTR1_RET(pCtx); + + /* test state ID */ + IPP_BADARG_RET(!VALID_SMS4CCM_ID(pCtx), ippStsContextMatchErr); + + /* test tag (pointer and length) */ + IPP_BAD_PTR1_RET(pTag); + IPP_BADARG_RET((Ipp32u)tagLen>SMS4CCM_TAGLEN(pCtx) || tagLen<1, ippStsLengthErr); + + { + __ALIGN16 Ipp32u TMP[2*(MBS_SMS4/sizeof(Ipp32u)) + 1]; + /* + MAC size = MBS_SMS4/sizeof(Ipp32u) + BLK size = MBS_SMS4/sizeof(Ipp32u) + flag size = 1 + */ + + Ipp32u* MAC = TMP; + Ipp32u* BLK = TMP + (MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* flag = TMP + 2*(MBS_SMS4/sizeof(Ipp32u)); + + *flag = (Ipp32u)( SMS4CCM_LENPRO(pCtx) &(MBS_SMS4-1) ); + + CopyBlock16(SMS4CCM_MAC(pCtx), MAC); + + if(*flag) { + /* SMS4 context */ + IppsSMS4Spec* pSMS4 = SMS4CCM_CIPHER(pCtx); + + FillBlock16(0, NULL,BLK, 0); + CopyBlock(SMS4CCM_BLK(pCtx), (Ipp8u*)BLK, (cpSize)(*flag)); + + XorBlock16(MAC, BLK, MAC); + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + + } + + XorBlock(MAC, SMS4CCM_S0(pCtx), pTag, tagLen); + + /* clear secret data */ + PurgeBlock(TMP, sizeof(TMP)); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccminit.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccminit.c new file mode 100644 index 000000000..8449731f5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccminit.c @@ -0,0 +1,71 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// SMS4-CCM implementation. +// +// Content: +// ippsSMS4_CCMInit() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4authccm.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4_CCMInit +// +// Purpose: Init SMS4-CCM state. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// ippStsMemAllocErr size of buffer is not match fro operation +// ippStsLengthErr keyLen < 16 +// ippStsNoErr no errors +// +// Parameters: +// pKey pointer to the secret key +// keyLen length of secret key (in bytes) +// pCtx pointer to initialized as CCM context +// ctxSize available size (in bytes) of buffer above +// +*F*/ +IPPFUN(IppStatus, ippsSMS4_CCMInit,(const Ipp8u* pKey, int keyLen, + IppsSMS4_CCMState* pCtx, int ctxSize)) +{ + /* test pCtx pointer */ + IPP_BAD_PTR1_RET(pCtx); + + /* test available size of context buffer */ + IPP_BADARG_RET(ctxSize13), ippStsLengthErr); + + /* test AAD pointer if defined */ + IPP_BADARG_RET(adLen<0, ippStsLengthErr); + if(adLen) + IPP_BAD_PTR1_RET(pAD); + + /* init for new message */ + SMS4CCM_LENPRO(pCtx) = 0; + SMS4CCM_COUNTER(pCtx) = 0; + + { + /* setup encoder function */ + IppsSMS4Spec* pSMS4 = SMS4CCM_CIPHER(pCtx); + + __ALIGN16 Ipp32u TMP[4*(MBS_SMS4/sizeof(Ipp32u)) + 8]; + /* + MAC size = MBS_SMS4/sizeof(Ipp32u) + CTR size = MBS_SMS4/sizeof(Ipp32u) + block size = 2*MBS_SMS4/sizeof(Ipp32u) + qLen size = 1 + qLenEnc size = 1 + tagLenEnc size = 1 + payloadLen size = 2 + adLenEnc size = 3 + */ + + Ipp32u* MAC = TMP; + Ipp32u* CTR = TMP + (MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* block = TMP + 2*(MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* qLen = TMP + 4*(MBS_SMS4/sizeof(Ipp32u)); + Ipp32u* qLenEnc = TMP + 4*(MBS_SMS4/sizeof(Ipp32u)) + 1; + Ipp32u* tagLenEnc = TMP + 4*(MBS_SMS4/sizeof(Ipp32u)) + 2; + Ipp32u* payloadLen = TMP + 4*(MBS_SMS4/sizeof(Ipp32u)) + 3; + Ipp32u* adLenEnc = TMP + 4*(MBS_SMS4/sizeof(Ipp32u)) + 5; + + /* + // prepare the 1-st input block B0 and encode + */ + *qLen = (Ipp32u)( (MBS_SMS4-1) - ivLen); + *qLenEnc = *qLen-1; + + *tagLenEnc = (SMS4CCM_TAGLEN(pCtx)-2)>>1; + + *((Ipp64u*)payloadLen) = SMS4CCM_MSGLEN(pCtx); + + ((Ipp8u*)MAC)[0] = (Ipp8u)( (Ipp32u)((adLen!=0) <<6) + (*tagLenEnc<<3) + *qLenEnc); /* flags */ + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + MAC[2] = ENDIANNESS(IPP_HIDWORD(*((Ipp64u*)payloadLen))); + MAC[3] = ENDIANNESS(IPP_LODWORD(*((Ipp64u*)payloadLen))); + #else + MAC[2] = IPP_HIDWORD(*((Ipp64u*)payloadLen)); + MAC[3] = IPP_LODWORD(*((Ipp64u*)payloadLen)); + #endif + CopyBlock(pIV, ((Ipp8u*)MAC)+1, ivLen); + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + + /* setup CTR0 */ + FillBlock16(0, NULL,CTR, 0); + ((Ipp8u*)CTR)[0] = (Ipp8u)(*qLenEnc); /* flags */ + CopyBlock(pIV, ((Ipp8u*)CTR)+1, ivLen); + CopyBlock16(CTR, SMS4CCM_CTR0(pCtx)); + + /* compute and store S0=ENC(CTR0) */ + cpSMS4_Cipher(SMS4CCM_S0(pCtx), (Ipp8u*)CTR, SMS4_RK(pSMS4)); + + /* + // update MAC by the AD + */ + if(adLen) { + /* encode length of associated data */ + Ipp8u* adLenEncPtr; + int adLenEncSize; + + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + adLenEnc[1] = ENDIANNESS(IPP_HIDWORD(adLen)); + adLenEnc[2] = ENDIANNESS(IPP_LODWORD(adLen)); + #else + adLenEnc[1] = IPP_HIDWORD(adLen); + adLenEnc[2] = IPP_LODWORD(adLen); + #endif + + if(adLen >= 0xFF00) { + adLenEncSize = 6; + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + adLenEnc[1] = 0xFEFFFFFF; + #else + adLenEnc[1] = 0xFFFFFFFE; + #endif + } + else { + adLenEncSize= 2; + } + adLenEncPtr = (Ipp8u*)adLenEnc+3*sizeof(Ipp32u)-adLenEncSize; + + /* prepare first formatted block of Header */ + CopyBlock(adLenEncPtr, block, adLenEncSize); + FillBlock16(0,pAD, (Ipp8u*)block+adLenEncSize, IPP_MIN((MBS_SMS4-adLenEncSize), adLen)); + + /* and update MAC */ + MAC[0] ^= block[0]; + MAC[1] ^= block[1]; + MAC[2] ^= block[2]; + MAC[3] ^= block[3]; + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + + /* update MAC the by rest of addition data */ + if( (adLen+adLenEncSize) > MBS_SMS4 ) { + pAD += (MBS_SMS4-adLenEncSize); + adLen -= (MBS_SMS4-adLenEncSize); + while(adLen >= MBS_SMS4) { + CopyBlock16(pAD, block); + MAC[0] ^= block[0]; + MAC[1] ^= block[1]; + MAC[2] ^= block[2]; + MAC[3] ^= block[3]; + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + + pAD += MBS_SMS4; + adLen -= MBS_SMS4; + } + + if(adLen) { + FillBlock16(0, pAD, block, (int)adLen); + MAC[0] ^= block[0]; + MAC[1] ^= block[1]; + MAC[2] ^= block[2]; + MAC[3] ^= block[3]; + cpSMS4_Cipher((Ipp8u*)MAC, (Ipp8u*)MAC, SMS4_RK(pSMS4)); + } + } + } + + SMS4CCM_COUNTER(pCtx) = 0; + CopyBlock16(MAC, SMS4CCM_MAC(pCtx)); + + /* clear secret data */ + PurgeBlock(TMP, sizeof(TMP)); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmtaglen.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmtaglen.c new file mode 100644 index 000000000..32aad50f3 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ccmtaglen.c @@ -0,0 +1,63 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Purpose: +// Cryptography Primitive. +// SMS4-CCM implementation. +// +// Content: +// ippsSMS4_CCMTagLen() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4authccm.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4_CCMTagLen +// +// Purpose: Setup length of the tag. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// ippStsContextMatchErr !VALID_SMS4CCM_ID() +// ippStsLengthErr MBS_SMS4 < tagLen || tagLen < 4 +// or odd value of tagLen +// ippStsNoErr no errors +// +// Parameters: +// tagLen length in bytes of the requested tag +// pCtx pointer to the CCM context +// +*F*/ +IPPFUN(IppStatus, ippsSMS4_CCMTagLen,(int tagLen, IppsSMS4_CCMState* pCtx)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + IPP_BADARG_RET(!VALID_SMS4CCM_ID(pCtx), ippStsContextMatchErr); + + /* test tag length */ + IPP_BADARG_RET(tagLen>MBS_SMS4 || tagLen<4 || tagLen&1, ippStsLengthErr); + + /* init for new message */ + SMS4CCM_TAGLEN(pCtx) = (Ipp32u)tagLen; + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cfb_gfni.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cfb_gfni.c new file mode 100644 index 000000000..3a16b139c --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cfb_gfni.c @@ -0,0 +1,1597 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* This software and the related documents are Intel copyrighted materials, and your use of them is governed by +* the express license under which they were provided to you ('License'). Unless the License provides otherwise, +* you may not use, modify, copy, publish, distribute, disclose or transmit this software or the related +* documents without Intel's prior written permission. +* This software and the related documents are provided as is, with no express or implied warranties, other than +* those that are expressly stated in the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 CFB decryption +// +// Contents: +// cpSMS4_CFB_gfni512() +// cpSMS4_CFB_gfni512x48() +// cpSMS4_CFB_gfni512x32() +// cpSMS4_CFB_gfni512x16() +// cpSMS4_CFB_gfni128x12() +// cpSMS4_CFB_gfni128x8() +// cpSMS4_CFB_gfni128x4() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +#if (_IPP32E>=_IPP32E_K1) +#if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + +#include "pcpsms4_gfni.h" + +static +void cpSMS4_CFB_dec_gfni512x48(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV); +static +void cpSMS4_CFB_dec_gfni512x32(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV); +static +void cpSMS4_CFB_dec_gfni512x16(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV); +static +void cpSMS4_CFB_dec_gfni128x12(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV); +static +void cpSMS4_CFB_dec_gfni128x8(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV); +static +void cpSMS4_CFB_dec_gfni128x4(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV); + +__FORCEINLINE Ipp64u broadcast_16to64(Ipp16u mask16) +{ + Ipp64u mask64 = (Ipp64u)mask16; + mask64 = (mask64 << 48) | (mask64 << 32) | (mask64 << 16) | mask64; + return mask64; +} + +__FORCEINLINE __m512i getInputBlocks(__m128i * const currentState, const __m512i * const pCipherBlocks, __mmask16 blocksCompressMask) +{ + /* extract 128-bit cipher blocks */ + __m128i c0 = _mm512_extracti64x2_epi64(*pCipherBlocks, 0); + __m128i c1 = _mm512_extracti64x2_epi64(*pCipherBlocks, 1); + __m128i c2 = _mm512_extracti64x2_epi64(*pCipherBlocks, 2); + __m128i c3 = _mm512_extracti64x2_epi64(*pCipherBlocks, 3); + + /* InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit */ + __m128i inpBlk0 = *currentState; + /* drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits */ + __m128i inpBlk1 = _mm_mask_compress_epi8(c0, blocksCompressMask, inpBlk0); + __m128i inpBlk2 = _mm_mask_compress_epi8(c1, blocksCompressMask, inpBlk1); + __m128i inpBlk3 = _mm_mask_compress_epi8(c2, blocksCompressMask, inpBlk2); + + /* next InputBlock ready */ + *currentState = _mm_mask_compress_epi8(c3, blocksCompressMask, inpBlk3); + + /* inserts */ + __m512i inpBlk512 = _mm512_setzero_si512(); + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0x03, inpBlk0); /* 0000 0011 */ + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0x0C, inpBlk1); /* 0000 1100 */ + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0x30, inpBlk2); /* 0011 0000 */ + inpBlk512 = _mm512_mask_broadcast_i64x2(inpBlk512, 0xC0, inpBlk3); /* 1100 0000 */ + + return inpBlk512; +} + +/* +// 64*cfbBlkSize bytes processing +*/ + +IPP_OWN_DEFN (void, cpSMS4_CFB_dec_gfni512, (Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV)) +{ + __ALIGN16 __m512i TMP[24]; + + /* + // TMP[0..15] - decrypted text blocks + // TMP[16..19] - key + // TMP[20..23] - temp out + */ + + const int bytesPerLoad512 = 4 * cfbBlkSize; + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + int processedLen = len - (len % (64 * cfbBlkSize)); + int blocks; + + /* load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register */ + __mmask64 kLsbMask64 = broadcast_16to64((Ipp16u)(0xFFFF << (16-cfbBlkSize))); + /* same mask to load in MSB parts */ + __mmask64 kMsbMask64 = broadcast_16to64(~blocksCompressMask); + + /* load IV */ + __m128i currentState = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + for (blocks = len / cfbBlkSize; blocks >= (64); blocks -= (64)) { + /* load cipher blocks to LSB parts of registers */ + __m512i ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 0 * bytesPerLoad512); + __m512i ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 1 * bytesPerLoad512); + __m512i ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 2 * bytesPerLoad512); + __m512i ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 3 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[0], TMP[1], TMP[2], TMP[3], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 4 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 5 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 6 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 7 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 8 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 9 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 10 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 11 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 12 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 13 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 14 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 15 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + int itr; + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[19] = TMP[18] = TMP[17] = TMP[16] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[1] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[2] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[3] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[5] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[6] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[7] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[9] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[10]); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[11]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[13]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[14]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[15]); + /* Sbox */ + TMP[16] = sBox512(TMP[16]); + TMP[17] = sBox512(TMP[17]); + TMP[18] = sBox512(TMP[18]); + TMP[19] = sBox512(TMP[19]); + /* Sbox done, now L */ + TMP[0] = _mm512_xor_si512(_mm512_xor_si512(TMP[0], TMP[16]), L512(TMP[16])); + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[17]), L512(TMP[17])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[18]), L512(TMP[18])); + TMP[12] = _mm512_xor_si512(_mm512_xor_si512(TMP[12], TMP[19]), L512(TMP[19])); + + /* initial xors */ + TMP[19] = TMP[18] = TMP[17] = TMP[16] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[2] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[3] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[0] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[6] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[7] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[4] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[10]); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[11]); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[8] ); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[14]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[15]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[12]); + /* Sbox */ + TMP[16] = sBox512(TMP[16]); + TMP[17] = sBox512(TMP[17]); + TMP[18] = sBox512(TMP[18]); + TMP[19] = sBox512(TMP[19]); + /* Sbox done, now L */ + TMP[1] = _mm512_xor_si512(_mm512_xor_si512(TMP[1], TMP[16]), L512(TMP[16])); + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[17]), L512(TMP[17])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[18]), L512(TMP[18])); + TMP[13] = _mm512_xor_si512(_mm512_xor_si512(TMP[13], TMP[19]), L512(TMP[19])); + + /* initial xors */ + TMP[19] = TMP[18] = TMP[17] = TMP[16] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[3] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[0] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[1] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[7] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[4] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[5] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[11]); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[8] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[9] ); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[15]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[12]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[13]); + /* Sbox */ + TMP[16] = sBox512(TMP[16]); + TMP[17] = sBox512(TMP[17]); + TMP[18] = sBox512(TMP[18]); + TMP[19] = sBox512(TMP[19]); + /* Sbox done, now L */ + TMP[2] = _mm512_xor_si512(_mm512_xor_si512(TMP[2], TMP[16]), L512(TMP[16])); + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[17]), L512(TMP[17])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[18]), L512(TMP[18])); + TMP[14] = _mm512_xor_si512(_mm512_xor_si512(TMP[14], TMP[19]), L512(TMP[19])); + + /* initial xors */ + TMP[19] = TMP[18] = TMP[17] = TMP[16] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[0] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[1] ); + TMP[16] = _mm512_xor_si512(TMP[16], TMP[2] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[4] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[5] ); + TMP[17] = _mm512_xor_si512(TMP[17], TMP[6] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[8] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[9] ); + TMP[18] = _mm512_xor_si512(TMP[18], TMP[10]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[12]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[13]); + TMP[19] = _mm512_xor_si512(TMP[19], TMP[14]); + /* Sbox */ + TMP[16] = sBox512(TMP[16]); + TMP[17] = sBox512(TMP[17]); + TMP[18] = sBox512(TMP[18]); + TMP[19] = sBox512(TMP[19]); + /* Sbox done, now L */ + TMP[3] = _mm512_xor_si512(_mm512_xor_si512(TMP[3], TMP[16]), L512(TMP[16])); + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[17]), L512(TMP[17])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[18]), L512(TMP[18])); + TMP[15] = _mm512_xor_si512(_mm512_xor_si512(TMP[15], TMP[19]), L512(TMP[19])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[20], TMP[21], TMP[22], TMP[23], TMP[0], TMP[1], TMP[2], TMP[3]); + TMP[20] = _mm512_shuffle_epi8(TMP[20], M512(swapBytes)); + TMP[21] = _mm512_shuffle_epi8(TMP[21], M512(swapBytes)); + TMP[22] = _mm512_shuffle_epi8(TMP[22], M512(swapBytes)); + TMP[23] = _mm512_shuffle_epi8(TMP[23], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 0 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 1 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 2 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 3 * bytesPerLoad512); + + TMP[20] = _mm512_xor_si512(ciphBytes0, TMP[20]); + TMP[21] = _mm512_xor_si512(ciphBytes1, TMP[21]); + TMP[22] = _mm512_xor_si512(ciphBytes2, TMP[22]); + TMP[23] = _mm512_xor_si512(ciphBytes3, TMP[23]); + + _mm512_mask_compressstoreu_epi8(pDst + 0 * bytesPerLoad512, kMsbMask64, TMP[20]); + _mm512_mask_compressstoreu_epi8(pDst + 1 * bytesPerLoad512, kMsbMask64, TMP[21]); + _mm512_mask_compressstoreu_epi8(pDst + 2 * bytesPerLoad512, kMsbMask64, TMP[22]); + _mm512_mask_compressstoreu_epi8(pDst + 3 * bytesPerLoad512, kMsbMask64, TMP[23]); + + TRANSPOSE_OUT_512(TMP[20], TMP[21], TMP[22], TMP[23], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[20] = _mm512_shuffle_epi8(TMP[20], M512(swapBytes)); + TMP[21] = _mm512_shuffle_epi8(TMP[21], M512(swapBytes)); + TMP[22] = _mm512_shuffle_epi8(TMP[22], M512(swapBytes)); + TMP[23] = _mm512_shuffle_epi8(TMP[23], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 4 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 5 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 6 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 7 * bytesPerLoad512); + + TMP[20] = _mm512_xor_si512(ciphBytes0, TMP[20]); + TMP[21] = _mm512_xor_si512(ciphBytes1, TMP[21]); + TMP[22] = _mm512_xor_si512(ciphBytes2, TMP[22]); + TMP[23] = _mm512_xor_si512(ciphBytes3, TMP[23]); + + _mm512_mask_compressstoreu_epi8(pDst + 4 * bytesPerLoad512, kMsbMask64, TMP[20]); + _mm512_mask_compressstoreu_epi8(pDst + 5 * bytesPerLoad512, kMsbMask64, TMP[21]); + _mm512_mask_compressstoreu_epi8(pDst + 6 * bytesPerLoad512, kMsbMask64, TMP[22]); + _mm512_mask_compressstoreu_epi8(pDst + 7 * bytesPerLoad512, kMsbMask64, TMP[23]); + + TRANSPOSE_OUT_512(TMP[20], TMP[21], TMP[22], TMP[23], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[20] = _mm512_shuffle_epi8(TMP[20], M512(swapBytes)); + TMP[21] = _mm512_shuffle_epi8(TMP[21], M512(swapBytes)); + TMP[22] = _mm512_shuffle_epi8(TMP[22], M512(swapBytes)); + TMP[23] = _mm512_shuffle_epi8(TMP[23], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 8 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 9 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 10 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 11 * bytesPerLoad512); + + TMP[20] = _mm512_xor_si512(ciphBytes0, TMP[20]); + TMP[21] = _mm512_xor_si512(ciphBytes1, TMP[21]); + TMP[22] = _mm512_xor_si512(ciphBytes2, TMP[22]); + TMP[23] = _mm512_xor_si512(ciphBytes3, TMP[23]); + + _mm512_mask_compressstoreu_epi8(pDst + 8 * bytesPerLoad512, kMsbMask64, TMP[20]); + _mm512_mask_compressstoreu_epi8(pDst + 9 * bytesPerLoad512, kMsbMask64, TMP[21]); + _mm512_mask_compressstoreu_epi8(pDst + 10 * bytesPerLoad512, kMsbMask64, TMP[22]); + _mm512_mask_compressstoreu_epi8(pDst + 11 * bytesPerLoad512, kMsbMask64, TMP[23]); + + TRANSPOSE_OUT_512(TMP[20], TMP[21], TMP[22], TMP[23], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[20] = _mm512_shuffle_epi8(TMP[20], M512(swapBytes)); + TMP[21] = _mm512_shuffle_epi8(TMP[21], M512(swapBytes)); + TMP[22] = _mm512_shuffle_epi8(TMP[22], M512(swapBytes)); + TMP[23] = _mm512_shuffle_epi8(TMP[23], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 12 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 13 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 14 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 15 * bytesPerLoad512); + + TMP[20] = _mm512_xor_si512(ciphBytes0, TMP[20]); + TMP[21] = _mm512_xor_si512(ciphBytes1, TMP[21]); + TMP[22] = _mm512_xor_si512(ciphBytes2, TMP[22]); + TMP[23] = _mm512_xor_si512(ciphBytes3, TMP[23]); + + _mm512_mask_compressstoreu_epi8(pDst + 12 * bytesPerLoad512, kMsbMask64, TMP[20]); + _mm512_mask_compressstoreu_epi8(pDst + 13 * bytesPerLoad512, kMsbMask64, TMP[21]); + _mm512_mask_compressstoreu_epi8(pDst + 14 * bytesPerLoad512, kMsbMask64, TMP[22]); + _mm512_mask_compressstoreu_epi8(pDst + 15 * bytesPerLoad512, kMsbMask64, TMP[23]); + + pSrc += 16 * bytesPerLoad512; + pDst += 16 * bytesPerLoad512; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i],TMP[i]); + } + + len -= processedLen; + + if (len){ + _mm_storeu_si128((__m128i*)(pIV), currentState); + cpSMS4_CFB_dec_gfni512x48(pDst, pSrc, len, cfbBlkSize, pRKey, pIV); + } + +} + +/* +// 48*cfbBlkSize bytes processing +*/ + +static +void cpSMS4_CFB_dec_gfni512x48(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m512i TMP[19]; + + /* + // TMP[0..11] - decrypted text blocks + // TMP[12..14] - key + // TMP[15..18] - temp out + */ + + const int bytesPerLoad512 = 4 * cfbBlkSize; + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + int processedLen = len - (len % (48 * cfbBlkSize)); + int blocks; + + /* load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register */ + __mmask64 kLsbMask64 = broadcast_16to64((Ipp16u)(0xFFFF << (16-cfbBlkSize))); + /* same mask to load in MSB parts */ + __mmask64 kMsbMask64 = broadcast_16to64(~blocksCompressMask); + + /* load IV */ + __m128i currentState = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + for (blocks = len / cfbBlkSize; blocks >= (48); blocks -= (48)) { + /* load cipher blocks to LSB parts of registers */ + __m512i ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 0 * bytesPerLoad512); + __m512i ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 1 * bytesPerLoad512); + __m512i ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 2 * bytesPerLoad512); + __m512i ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 3 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[0], TMP[1], TMP[2], TMP[3], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 4 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 5 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 6 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 7 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 8 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 9 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 10 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 11 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + int itr; + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[14] = TMP[13] = TMP[12] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[1] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[2] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[3] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[5] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[6] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[7] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[9] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[10]); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[11]); + /* Sbox */ + TMP[12] = sBox512(TMP[12]); + TMP[13] = sBox512(TMP[13]); + TMP[14] = sBox512(TMP[14]); + /* Sbox done, now L */ + TMP[0] = _mm512_xor_si512(_mm512_xor_si512(TMP[0], TMP[12]), L512(TMP[12])); + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[13]), L512(TMP[13])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[14]), L512(TMP[14])); + + /* initial xors */ + TMP[14] = TMP[13] = TMP[12] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[2] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[3] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[0] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[6] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[7] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[4] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[10]); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[11]); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[8] ); + /* Sbox */ + TMP[12] = sBox512(TMP[12]); + TMP[13] = sBox512(TMP[13]); + TMP[14] = sBox512(TMP[14]); + /* Sbox done, now L */ + TMP[1] = _mm512_xor_si512(_mm512_xor_si512(TMP[1], TMP[12]), L512(TMP[12])); + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[13]), L512(TMP[13])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[14]), L512(TMP[14])); + + /* initial xors */ + TMP[14] = TMP[13] = TMP[12] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[3] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[0] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[1] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[7] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[4] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[5] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[11]); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[8] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[9] ); + /* Sbox */ + TMP[12] = sBox512(TMP[12]); + TMP[13] = sBox512(TMP[13]); + TMP[14] = sBox512(TMP[14]); + /* Sbox done, now L */ + TMP[2] = _mm512_xor_si512(_mm512_xor_si512(TMP[2], TMP[12]), L512(TMP[12])); + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[13]), L512(TMP[13])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[14]), L512(TMP[14])); + + /* initial xors */ + TMP[14] = TMP[13] = TMP[12] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[0] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[1] ); + TMP[12] = _mm512_xor_si512(TMP[12], TMP[2] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[4] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[5] ); + TMP[13] = _mm512_xor_si512(TMP[13], TMP[6] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[8] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[9] ); + TMP[14] = _mm512_xor_si512(TMP[14], TMP[10]); + /* Sbox */ + TMP[12] = sBox512(TMP[12]); + TMP[13] = sBox512(TMP[13]); + TMP[14] = sBox512(TMP[14]); + /* Sbox done, now L */ + TMP[3] = _mm512_xor_si512(_mm512_xor_si512(TMP[3], TMP[12]), L512(TMP[12])); + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[13]), L512(TMP[13])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[14]), L512(TMP[14])); + } + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[15], TMP[16], TMP[17], TMP[18], TMP[0], TMP[1], TMP[2], TMP[3]); + TMP[15] = _mm512_shuffle_epi8(TMP[15], M512(swapBytes)); + TMP[16] = _mm512_shuffle_epi8(TMP[16], M512(swapBytes)); + TMP[17] = _mm512_shuffle_epi8(TMP[17], M512(swapBytes)); + TMP[18] = _mm512_shuffle_epi8(TMP[18], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 0 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 1 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 2 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 3 * bytesPerLoad512); + + TMP[15] = _mm512_xor_si512(ciphBytes0, TMP[15]); + TMP[16] = _mm512_xor_si512(ciphBytes1, TMP[16]); + TMP[17] = _mm512_xor_si512(ciphBytes2, TMP[17]); + TMP[18] = _mm512_xor_si512(ciphBytes3, TMP[18]); + + _mm512_mask_compressstoreu_epi8(pDst + 0 * bytesPerLoad512, kMsbMask64, TMP[15]); + _mm512_mask_compressstoreu_epi8(pDst + 1 * bytesPerLoad512, kMsbMask64, TMP[16]); + _mm512_mask_compressstoreu_epi8(pDst + 2 * bytesPerLoad512, kMsbMask64, TMP[17]); + _mm512_mask_compressstoreu_epi8(pDst + 3 * bytesPerLoad512, kMsbMask64, TMP[18]); + + TRANSPOSE_OUT_512(TMP[15], TMP[16], TMP[17], TMP[18], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[15] = _mm512_shuffle_epi8(TMP[15], M512(swapBytes)); + TMP[16] = _mm512_shuffle_epi8(TMP[16], M512(swapBytes)); + TMP[17] = _mm512_shuffle_epi8(TMP[17], M512(swapBytes)); + TMP[18] = _mm512_shuffle_epi8(TMP[18], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 4 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 5 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 6 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 7 * bytesPerLoad512); + + TMP[15] = _mm512_xor_si512(ciphBytes0, TMP[15]); + TMP[16] = _mm512_xor_si512(ciphBytes1, TMP[16]); + TMP[17] = _mm512_xor_si512(ciphBytes2, TMP[17]); + TMP[18] = _mm512_xor_si512(ciphBytes3, TMP[18]); + + _mm512_mask_compressstoreu_epi8(pDst + 4 * bytesPerLoad512, kMsbMask64, TMP[15]); + _mm512_mask_compressstoreu_epi8(pDst + 5 * bytesPerLoad512, kMsbMask64, TMP[16]); + _mm512_mask_compressstoreu_epi8(pDst + 6 * bytesPerLoad512, kMsbMask64, TMP[17]); + _mm512_mask_compressstoreu_epi8(pDst + 7 * bytesPerLoad512, kMsbMask64, TMP[18]); + + TRANSPOSE_OUT_512(TMP[15], TMP[16], TMP[17], TMP[18], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[15] = _mm512_shuffle_epi8(TMP[15], M512(swapBytes)); + TMP[16] = _mm512_shuffle_epi8(TMP[16], M512(swapBytes)); + TMP[17] = _mm512_shuffle_epi8(TMP[17], M512(swapBytes)); + TMP[18] = _mm512_shuffle_epi8(TMP[18], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 8 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 9 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 10 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 11 * bytesPerLoad512); + + TMP[15] = _mm512_xor_si512(ciphBytes0, TMP[15]); + TMP[16] = _mm512_xor_si512(ciphBytes1, TMP[16]); + TMP[17] = _mm512_xor_si512(ciphBytes2, TMP[17]); + TMP[18] = _mm512_xor_si512(ciphBytes3, TMP[18]); + + _mm512_mask_compressstoreu_epi8(pDst + 8 * bytesPerLoad512, kMsbMask64, TMP[15]); + _mm512_mask_compressstoreu_epi8(pDst + 9 * bytesPerLoad512, kMsbMask64, TMP[16]); + _mm512_mask_compressstoreu_epi8(pDst + 10 * bytesPerLoad512, kMsbMask64, TMP[17]); + _mm512_mask_compressstoreu_epi8(pDst + 11 * bytesPerLoad512, kMsbMask64, TMP[18]); + + pSrc += 12 * bytesPerLoad512; + pDst += 12 * bytesPerLoad512; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i],TMP[i]); + } + + len -= processedLen; + + if (len){ + _mm_storeu_si128((__m128i*)(pIV), currentState); + cpSMS4_CFB_dec_gfni512x32(pDst, pSrc, len, cfbBlkSize, pRKey, pIV); + } + +} + +/* +// 32*cfbBlkSize bytes processing +*/ + +static +void cpSMS4_CFB_dec_gfni512x32(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m512i TMP[15]; + + /* + // TMP[0..7] - decrypted text blocks + // TMP[8..9] - key + // TMP[10..14] - temp out + */ + + const int bytesPerLoad512 = 4 * cfbBlkSize; + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + int processedLen = len - (len % (32 * cfbBlkSize)); + int blocks; + + /* load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register */ + __mmask64 kLsbMask64 = broadcast_16to64((Ipp16u)(0xFFFF << (16-cfbBlkSize))); + /* same mask to load in MSB parts */ + __mmask64 kMsbMask64 = broadcast_16to64(~blocksCompressMask); + + /* load IV */ + __m128i currentState = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + for (blocks = len / cfbBlkSize; blocks >= (32); blocks -= (32)) { + /* load cipher blocks to LSB parts of registers */ + __m512i ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 0 * bytesPerLoad512); + __m512i ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 1 * bytesPerLoad512); + __m512i ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 2 * bytesPerLoad512); + __m512i ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 3 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[0], TMP[1], TMP[2], TMP[3], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 4 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 5 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 6 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 7 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + + int itr; + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[9] = TMP[8] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[1] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[2] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[3] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[5] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[6] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[7] ); + /* Sbox */ + TMP[8] = sBox512(TMP[8]); + TMP[9] = sBox512(TMP[9]); + /* Sbox done, now L */ + TMP[0] = _mm512_xor_si512(_mm512_xor_si512(TMP[0], TMP[8]), L512(TMP[8])); + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[9]), L512(TMP[9])); + + /* initial xors */ + TMP[9] = TMP[8] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[2] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[3] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[0] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[6] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[7] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[4] ); + /* Sbox */ + TMP[8] = sBox512(TMP[8]); + TMP[9] = sBox512(TMP[9]); + /* Sbox done, now L */ + TMP[1] = _mm512_xor_si512(_mm512_xor_si512(TMP[1], TMP[8]), L512(TMP[8])); + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[9]), L512(TMP[9])); + + /* initial xors */ + TMP[9] = TMP[8] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[3] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[0] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[1] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[7] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[4] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[5] ); + /* Sbox */ + TMP[8] = sBox512(TMP[8]); + TMP[9] = sBox512(TMP[9]); + /* Sbox done, now L */ + TMP[2] = _mm512_xor_si512(_mm512_xor_si512(TMP[2], TMP[8]), L512(TMP[8])); + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[9]), L512(TMP[9])); + + /* initial xors */ + TMP[9] = TMP[8] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[0] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[1] ); + TMP[8] = _mm512_xor_si512(TMP[8], TMP[2] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[4] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[5] ); + TMP[9] = _mm512_xor_si512(TMP[9], TMP[6] ); + /* Sbox */ + TMP[8] = sBox512(TMP[8]); + TMP[9] = sBox512(TMP[9]); + /* Sbox done, now L */ + TMP[3] = _mm512_xor_si512(_mm512_xor_si512(TMP[3], TMP[8]), L512(TMP[8])); + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[9]), L512(TMP[9])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[10], TMP[11], TMP[12], TMP[13], TMP[0], TMP[1], TMP[2], TMP[3]); + TMP[10] = _mm512_shuffle_epi8(TMP[10], M512(swapBytes)); + TMP[11] = _mm512_shuffle_epi8(TMP[11], M512(swapBytes)); + TMP[12] = _mm512_shuffle_epi8(TMP[12], M512(swapBytes)); + TMP[13] = _mm512_shuffle_epi8(TMP[13], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 0 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 1 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 2 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 3 * bytesPerLoad512); + + TMP[10] = _mm512_xor_si512(ciphBytes0, TMP[10]); + TMP[11] = _mm512_xor_si512(ciphBytes1, TMP[11]); + TMP[12] = _mm512_xor_si512(ciphBytes2, TMP[12]); + TMP[13] = _mm512_xor_si512(ciphBytes3, TMP[13]); + + _mm512_mask_compressstoreu_epi8(pDst + 0 * bytesPerLoad512, kMsbMask64, TMP[10]); + _mm512_mask_compressstoreu_epi8(pDst + 1 * bytesPerLoad512, kMsbMask64, TMP[11]); + _mm512_mask_compressstoreu_epi8(pDst + 2 * bytesPerLoad512, kMsbMask64, TMP[12]); + _mm512_mask_compressstoreu_epi8(pDst + 3 * bytesPerLoad512, kMsbMask64, TMP[13]); + + TRANSPOSE_OUT_512(TMP[10], TMP[11], TMP[12], TMP[13], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[10] = _mm512_shuffle_epi8(TMP[10], M512(swapBytes)); + TMP[11] = _mm512_shuffle_epi8(TMP[11], M512(swapBytes)); + TMP[12] = _mm512_shuffle_epi8(TMP[12], M512(swapBytes)); + TMP[13] = _mm512_shuffle_epi8(TMP[13], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 4 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 5 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 6 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 7 * bytesPerLoad512); + + TMP[10] = _mm512_xor_si512(ciphBytes0, TMP[10]); + TMP[11] = _mm512_xor_si512(ciphBytes1, TMP[11]); + TMP[12] = _mm512_xor_si512(ciphBytes2, TMP[12]); + TMP[13] = _mm512_xor_si512(ciphBytes3, TMP[13]); + + _mm512_mask_compressstoreu_epi8(pDst + 4 * bytesPerLoad512, kMsbMask64, TMP[10]); + _mm512_mask_compressstoreu_epi8(pDst + 5 * bytesPerLoad512, kMsbMask64, TMP[11]); + _mm512_mask_compressstoreu_epi8(pDst + 6 * bytesPerLoad512, kMsbMask64, TMP[12]); + _mm512_mask_compressstoreu_epi8(pDst + 7 * bytesPerLoad512, kMsbMask64, TMP[13]); + + pSrc += 8 * bytesPerLoad512; + pDst += 8 * bytesPerLoad512; + + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i],TMP[i]); + } + + len -= processedLen; + + if (len){ + _mm_storeu_si128((__m128i*)(pIV), currentState); + cpSMS4_CFB_dec_gfni512x16(pDst, pSrc, len, cfbBlkSize, pRKey, pIV); + } + +} + +/* +// 16*cfbBlkSize bytes processing +*/ + +static +void cpSMS4_CFB_dec_gfni512x16(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m512i TMP[9]; + + /* + // TMP[0..3] - decrypted text blocks + // TMP[4] - key + // TMP[5..8] - temp out + */ + + const int bytesPerLoad512 = 4 * cfbBlkSize; + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + int processedLen = len - (len % (16 * cfbBlkSize)); + int blocks; + + /* load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register */ + __mmask64 kLsbMask64 = broadcast_16to64((Ipp16u)(0xFFFF << (16-cfbBlkSize))); + /* same mask to load in MSB parts */ + __mmask64 kMsbMask64 = broadcast_16to64(~blocksCompressMask); + + /* load IV */ + __m128i currentState = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + for (blocks = len / cfbBlkSize; blocks >= (16); blocks -= (16)) { + /* load cipher blocks to LSB parts of registers */ + __m512i ciphBytes0 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 0 * bytesPerLoad512); + __m512i ciphBytes1 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 1 * bytesPerLoad512); + __m512i ciphBytes2 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 2 * bytesPerLoad512); + __m512i ciphBytes3 = _mm512_maskz_expandloadu_epi8(kLsbMask64, pSrc + 3 * bytesPerLoad512); + + /* prepare InputBlocks for decryption */ + ciphBytes0 = getInputBlocks(¤tState, &ciphBytes0, blocksCompressMask); + ciphBytes1 = getInputBlocks(¤tState, &ciphBytes1, blocksCompressMask); + ciphBytes2 = getInputBlocks(¤tState, &ciphBytes2, blocksCompressMask); + ciphBytes3 = getInputBlocks(¤tState, &ciphBytes3, blocksCompressMask); + + ciphBytes0 = _mm512_shuffle_epi8(ciphBytes0, M512(swapBytes)); + ciphBytes1 = _mm512_shuffle_epi8(ciphBytes1, M512(swapBytes)); + ciphBytes2 = _mm512_shuffle_epi8(ciphBytes2, M512(swapBytes)); + ciphBytes3 = _mm512_shuffle_epi8(ciphBytes3, M512(swapBytes)); + + TRANSPOSE_INP_512(TMP[0], TMP[1], TMP[2], TMP[3], ciphBytes0, ciphBytes1, ciphBytes2, ciphBytes3); + int itr; + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[4] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[1]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[2]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[3]); + /* Sbox */ + TMP[4] = sBox512(TMP[4]); + /* Sbox done, now L */ + TMP[0] = _mm512_xor_si512(_mm512_xor_si512(TMP[0], TMP[4]), L512(TMP[4])); + + /* initial xors */ + TMP[4] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[2]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[3]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[0]); + /* Sbox */ + TMP[4] = sBox512(TMP[4]); + /* Sbox done, now L */ + TMP[1] = _mm512_xor_si512(_mm512_xor_si512(TMP[1], TMP[4]), L512(TMP[4])); + + /* initial xors */ + TMP[4] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[3]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[0]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[1]); + /* Sbox */ + TMP[4] = sBox512(TMP[4]); + /* Sbox done, now L */ + TMP[2] = _mm512_xor_si512(_mm512_xor_si512(TMP[2], TMP[4]), L512(TMP[4])); + + /* initial xors */ + TMP[4] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[0]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[1]); + TMP[4] = _mm512_xor_si512(TMP[4], TMP[2]); + /* Sbox */ + TMP[4] = sBox512(TMP[4]); + /* Sbox done, now L */ + TMP[3] = _mm512_xor_si512(_mm512_xor_si512(TMP[3], TMP[4]), L512(TMP[4])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[5], TMP[6], TMP[7], TMP[8], TMP[0], TMP[1], TMP[2], TMP[3]); + TMP[5] = _mm512_shuffle_epi8(TMP[5], M512(swapBytes)); + TMP[6] = _mm512_shuffle_epi8(TMP[6], M512(swapBytes)); + TMP[7] = _mm512_shuffle_epi8(TMP[7], M512(swapBytes)); + TMP[8] = _mm512_shuffle_epi8(TMP[8], M512(swapBytes)); + + /* load cipher blocks to MSB parts of registers */ + ciphBytes0 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 0 * bytesPerLoad512); + ciphBytes1 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 1 * bytesPerLoad512); + ciphBytes2 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 2 * bytesPerLoad512); + ciphBytes3 = _mm512_maskz_expandloadu_epi8(kMsbMask64, pSrc + 3 * bytesPerLoad512); + + TMP[5] = _mm512_xor_si512(ciphBytes0, TMP[5]); + TMP[6] = _mm512_xor_si512(ciphBytes1, TMP[6]); + TMP[7] = _mm512_xor_si512(ciphBytes2, TMP[7]); + TMP[8] = _mm512_xor_si512(ciphBytes3, TMP[8]); + + _mm512_mask_compressstoreu_epi8(pDst + 0 * bytesPerLoad512, kMsbMask64, TMP[5]); + _mm512_mask_compressstoreu_epi8(pDst + 1 * bytesPerLoad512, kMsbMask64, TMP[6]); + _mm512_mask_compressstoreu_epi8(pDst + 2 * bytesPerLoad512, kMsbMask64, TMP[7]); + _mm512_mask_compressstoreu_epi8(pDst + 3 * bytesPerLoad512, kMsbMask64, TMP[8]); + + pSrc += 4 * bytesPerLoad512; + pDst += 4 * bytesPerLoad512; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i],TMP[i]); + } + + len -= processedLen; + + if (len){ + _mm_storeu_si128((__m128i*)(pIV), currentState); + cpSMS4_CFB_dec_gfni128x12(pDst, pSrc, len, cfbBlkSize, pRKey, pIV); + } + +} + +/* +// 12*cfbBlkSize bytes processing +*/ + +static +void cpSMS4_CFB_dec_gfni128x12(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m128i TMP[15]; + + /* + // TMP[0..11] - decrypted text blocks + // TMP[12..14] - key + */ + + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + int processedLen = len - (len % (12 * cfbBlkSize)); + int blocks; + + /* load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register */ + __mmask16 kLsbMask16 = (Ipp16u)(0xFFFF << (16-cfbBlkSize)); + /* same mask to load in MSB parts */ + __mmask16 kMsbMask16 = ~blocksCompressMask; + + /* load IV */ + __m128i IV128 = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + __m128i currentState = IV128; + + for (blocks = len / cfbBlkSize; blocks >= (12); blocks -= (12)) { + + /* load cipher blocks to LSB parts of registers */ + __m128i ciphBytes0 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 0 * cfbBlkSize); + __m128i ciphBytes1 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 1 * cfbBlkSize); + __m128i ciphBytes2 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 2 * cfbBlkSize); + __m128i ciphBytes3 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 3 * cfbBlkSize); + + /* InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit */ + TMP[0] = currentState; + /* drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits */ + TMP[1] = _mm_mask_compress_epi8(ciphBytes0, blocksCompressMask, TMP[0]); + TMP[2] = _mm_mask_compress_epi8(ciphBytes1, blocksCompressMask, TMP[1]); + TMP[3] = _mm_mask_compress_epi8(ciphBytes2, blocksCompressMask, TMP[2]); + + /* next InputBlock ready */ + currentState = _mm_mask_compress_epi8(ciphBytes3, blocksCompressMask, TMP[3]); + + TMP[0] = _mm_shuffle_epi8(TMP[0], M128(swapBytes)); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8(TMP[2], M128(swapBytes)); + TMP[3] = _mm_shuffle_epi8(TMP[3], M128(swapBytes)); + TRANSPOSE_INP_128(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12]); /* TMP[12] - buffer */ + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 4 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 5 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 6 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 7 * cfbBlkSize); + + /* InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit */ + TMP[4] = currentState; + /* drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits */ + TMP[5] = _mm_mask_compress_epi8(ciphBytes0, blocksCompressMask, TMP[4]); + TMP[6] = _mm_mask_compress_epi8(ciphBytes1, blocksCompressMask, TMP[5]); + TMP[7] = _mm_mask_compress_epi8(ciphBytes2, blocksCompressMask, TMP[6]); + + /* next InputBlock ready */ + currentState = _mm_mask_compress_epi8(ciphBytes3, blocksCompressMask, TMP[7]); + + TMP[4] = _mm_shuffle_epi8(TMP[4], M128(swapBytes)); + TMP[5] = _mm_shuffle_epi8(TMP[5], M128(swapBytes)); + TMP[6] = _mm_shuffle_epi8(TMP[6], M128(swapBytes)); + TMP[7] = _mm_shuffle_epi8(TMP[7], M128(swapBytes)); + TRANSPOSE_INP_128(TMP[4], TMP[5], TMP[6], TMP[7], TMP[12]); /* TMP[12] - buffer */ + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 8 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 9 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 10 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 11 * cfbBlkSize); + + /* InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit */ + TMP[8] = currentState; + /* drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits */ + TMP[9] = _mm_mask_compress_epi8(ciphBytes0, blocksCompressMask, TMP[8] ); + TMP[10] = _mm_mask_compress_epi8(ciphBytes1, blocksCompressMask, TMP[9] ); + TMP[11] = _mm_mask_compress_epi8(ciphBytes2, blocksCompressMask, TMP[10]); + + /* next InputBlock ready */ + currentState = _mm_mask_compress_epi8(ciphBytes3, blocksCompressMask, TMP[11]); + + TMP[8] = _mm_shuffle_epi8(TMP[8], M128(swapBytes)); + TMP[9] = _mm_shuffle_epi8(TMP[9], M128(swapBytes)); + TMP[10] = _mm_shuffle_epi8(TMP[10], M128(swapBytes)); + TMP[11] = _mm_shuffle_epi8(TMP[11], M128(swapBytes)); + TRANSPOSE_INP_128(TMP[8], TMP[9], TMP[10], TMP[11], TMP[12]); /* TMP[12] - buffer */ + + + int itr; + for(itr=0; itr<8; itr++, pRKey+=4) { + /* initial xors */ + TMP[13] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[0]), 0); + TMP[14] = TMP[13]; + TMP[12] = TMP[13]; + TMP[12] = _mm_xor_si128(TMP[12], TMP[1] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[2] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[3] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[5] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[6] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[7] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[9] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[10]); + TMP[14] = _mm_xor_si128(TMP[14], TMP[11]); + /* Sbox */ + TMP[12] = sBox128(TMP[12]); + TMP[13] = sBox128(TMP[13]); + TMP[14] = sBox128(TMP[14]); + /* Sbox done, now L */ + TMP[0] = _mm_xor_si128(_mm_xor_si128(TMP[0], TMP[12]), L128(TMP[12])); + TMP[4] = _mm_xor_si128(_mm_xor_si128(TMP[4], TMP[13]), L128(TMP[13])); + TMP[8] = _mm_xor_si128(_mm_xor_si128(TMP[8], TMP[14]), L128(TMP[14])); + + /* initial xors */ + TMP[13] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[1]), 0); + TMP[14] = TMP[13]; + TMP[12] = TMP[13]; + TMP[12] = _mm_xor_si128(TMP[12], TMP[2] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[3] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[0] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[6] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[7] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[4] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[10]); + TMP[14] = _mm_xor_si128(TMP[14], TMP[11]); + TMP[14] = _mm_xor_si128(TMP[14], TMP[8] ); + /* Sbox */ + TMP[12] = sBox128(TMP[12]); + TMP[13] = sBox128(TMP[13]); + TMP[14] = sBox128(TMP[14]); + /* Sbox done, now L */ + TMP[1] = _mm_xor_si128(_mm_xor_si128(TMP[1], TMP[12]), L128(TMP[12])); + TMP[5] = _mm_xor_si128(_mm_xor_si128(TMP[5], TMP[13]), L128(TMP[13])); + TMP[9] = _mm_xor_si128(_mm_xor_si128(TMP[9], TMP[14]), L128(TMP[14])); + + /* initial xors */ + TMP[13] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[2]), 0); + TMP[14] = TMP[13]; + TMP[12] = TMP[13]; + TMP[12] = _mm_xor_si128(TMP[12], TMP[3] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[0] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[1] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[7] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[4] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[5] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[11]); + TMP[14] = _mm_xor_si128(TMP[14], TMP[8] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[9] ); + /* Sbox */ + TMP[12] = sBox128(TMP[12]); + TMP[13] = sBox128(TMP[13]); + TMP[14] = sBox128(TMP[14]); + /* Sbox done, now L */ + TMP[2] = _mm_xor_si128(_mm_xor_si128(TMP[2], TMP[12]), L128(TMP[12])); + TMP[6] = _mm_xor_si128(_mm_xor_si128(TMP[6], TMP[13]), L128(TMP[13])); + TMP[10] = _mm_xor_si128(_mm_xor_si128(TMP[10], TMP[14]), L128(TMP[14])); + + /* initial xors */ + TMP[13] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[3]), 0); + TMP[14] = TMP[13]; + TMP[12] = TMP[13]; + TMP[12] = _mm_xor_si128(TMP[12], TMP[0] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[1] ); + TMP[12] = _mm_xor_si128(TMP[12], TMP[2] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[4] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[5] ); + TMP[13] = _mm_xor_si128(TMP[13], TMP[6] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[8] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[9] ); + TMP[14] = _mm_xor_si128(TMP[14], TMP[10]); + /* Sbox */ + TMP[12] = sBox128(TMP[12]); + TMP[13] = sBox128(TMP[13]); + TMP[14] = sBox128(TMP[14]); + /* Sbox done, now L */ + TMP[3] = _mm_xor_si128(_mm_xor_si128(TMP[3], TMP[12]), L128(TMP[12])); + TMP[7] = _mm_xor_si128(_mm_xor_si128(TMP[7], TMP[13]), L128(TMP[13])); + TMP[11] = _mm_xor_si128(_mm_xor_si128(TMP[11], TMP[14]), L128(TMP[14])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_128(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12]); /* TMP[12] - buffer */ + /* Order of blocks is inverted */ + + TMP[3] = _mm_shuffle_epi8(TMP[3], M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8(TMP[2], M128(swapBytes)); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + TMP[0] = _mm_shuffle_epi8(TMP[0], M128(swapBytes)); + + ciphBytes0 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 0 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 1 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 2 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 3 * cfbBlkSize); + + TMP[3] = _mm_xor_si128(ciphBytes0, TMP[3]); + TMP[2] = _mm_xor_si128(ciphBytes1, TMP[2]); + TMP[1] = _mm_xor_si128(ciphBytes2, TMP[1]); + TMP[0] = _mm_xor_si128(ciphBytes3, TMP[0]); + + _mm_mask_compressstoreu_epi8(pDst + 0 * cfbBlkSize, kMsbMask16, TMP[3]); + _mm_mask_compressstoreu_epi8(pDst + 1 * cfbBlkSize, kMsbMask16, TMP[2]); + _mm_mask_compressstoreu_epi8(pDst + 2 * cfbBlkSize, kMsbMask16, TMP[1]); + _mm_mask_compressstoreu_epi8(pDst + 3 * cfbBlkSize, kMsbMask16, TMP[0]); + + TRANSPOSE_OUT_128(TMP[4], TMP[5], TMP[6], TMP[7], TMP[12]); /* TMP[12] - buffer */ + /* Order of blocks is inverted */ + + TMP[7] = _mm_shuffle_epi8(TMP[7], M128(swapBytes)); + TMP[6] = _mm_shuffle_epi8(TMP[6], M128(swapBytes)); + TMP[5] = _mm_shuffle_epi8(TMP[5], M128(swapBytes)); + TMP[4] = _mm_shuffle_epi8(TMP[4], M128(swapBytes)); + + ciphBytes0 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 4 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 5 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 6 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 7 * cfbBlkSize); + + TMP[7] = _mm_xor_si128(ciphBytes0, TMP[7]); + TMP[6] = _mm_xor_si128(ciphBytes1, TMP[6]); + TMP[5] = _mm_xor_si128(ciphBytes2, TMP[5]); + TMP[4] = _mm_xor_si128(ciphBytes3, TMP[4]); + + _mm_mask_compressstoreu_epi8(pDst + 4 * cfbBlkSize, kMsbMask16, TMP[7]); + _mm_mask_compressstoreu_epi8(pDst + 5 * cfbBlkSize, kMsbMask16, TMP[6]); + _mm_mask_compressstoreu_epi8(pDst + 6 * cfbBlkSize, kMsbMask16, TMP[5]); + _mm_mask_compressstoreu_epi8(pDst + 7 * cfbBlkSize, kMsbMask16, TMP[4]); + + TRANSPOSE_OUT_128(TMP[8], TMP[9], TMP[10], TMP[11], TMP[12]); /* TMP[12] - buffer */ + /* Order of blocks is inverted */ + + TMP[11] = _mm_shuffle_epi8(TMP[11], M128(swapBytes)); + TMP[10] = _mm_shuffle_epi8(TMP[10], M128(swapBytes)); + TMP[9] = _mm_shuffle_epi8(TMP[9], M128(swapBytes)); + TMP[8] = _mm_shuffle_epi8(TMP[8], M128(swapBytes)); + + ciphBytes0 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 8 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 9 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 10 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 11 * cfbBlkSize); + + TMP[11] = _mm_xor_si128(ciphBytes0, TMP[11]); + TMP[10] = _mm_xor_si128(ciphBytes1, TMP[10]); + TMP[9] = _mm_xor_si128(ciphBytes2, TMP[9]); + TMP[8] = _mm_xor_si128(ciphBytes3, TMP[8]); + + _mm_mask_compressstoreu_epi8(pDst + 8 * cfbBlkSize, kMsbMask16, TMP[11]); + _mm_mask_compressstoreu_epi8(pDst + 9 * cfbBlkSize, kMsbMask16, TMP[10]); + _mm_mask_compressstoreu_epi8(pDst + 10 * cfbBlkSize, kMsbMask16, TMP[9]); + _mm_mask_compressstoreu_epi8(pDst + 11 * cfbBlkSize, kMsbMask16, TMP[8]); + + pSrc += 12 * cfbBlkSize; + pDst += 12 * cfbBlkSize; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm_setzero_si128(); //_mm_xor_si128(TMP[i],TMP[i]); + } + + len -= processedLen; + + if (len){ + _mm_storeu_si128((__m128i*)(pIV), currentState); + cpSMS4_CFB_dec_gfni128x8(pDst, pSrc, len, cfbBlkSize, pRKey, pIV); + } +} + +/* +// 8*cfbBlkSize bytes processing +*/ + +static +void cpSMS4_CFB_dec_gfni128x8(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV) +{ + + __ALIGN16 __m128i TMP[10]; + + /* + // TMP[0..7] - decrypted text blocks + // TMP[8..9] - key + */ + + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + int processedLen = len - (len % (8 * cfbBlkSize)); + int blocks; + + /* load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register */ + __mmask16 kLsbMask16 = (Ipp16u)(0xFFFF << (16-cfbBlkSize)); + /* same mask to load in MSB parts */ + __mmask16 kMsbMask16 = ~blocksCompressMask; + + /* load IV */ + __m128i currentState = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + for (blocks = len / cfbBlkSize; blocks >= (8); blocks -= (8)) { + + /* load cipher blocks to LSB parts of registers */ + __m128i ciphBytes0 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 0 * cfbBlkSize); + __m128i ciphBytes1 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 1 * cfbBlkSize); + __m128i ciphBytes2 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 2 * cfbBlkSize); + __m128i ciphBytes3 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 3 * cfbBlkSize); + + /* InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit */ + TMP[0] = currentState; + /* drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits */ + TMP[1] = _mm_mask_compress_epi8(ciphBytes0, blocksCompressMask, TMP[0]); + TMP[2] = _mm_mask_compress_epi8(ciphBytes1, blocksCompressMask, TMP[1]); + TMP[3] = _mm_mask_compress_epi8(ciphBytes2, blocksCompressMask, TMP[2]); + + /* next InputBlock ready */ + currentState = _mm_mask_compress_epi8(ciphBytes3, blocksCompressMask, TMP[3]); + + TMP[0] = _mm_shuffle_epi8(TMP[0], M128(swapBytes)); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8(TMP[2], M128(swapBytes)); + TMP[3] = _mm_shuffle_epi8(TMP[3], M128(swapBytes)); + TRANSPOSE_INP_128(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8]); /* TMP[8] - buffer */ + + /* load cipher blocks to LSB parts of registers */ + ciphBytes0 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 4 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 5 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 6 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 7 * cfbBlkSize); + + /* InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit */ + TMP[4] = currentState; + /* drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits */ + TMP[5] = _mm_mask_compress_epi8(ciphBytes0, blocksCompressMask, TMP[4]); + TMP[6] = _mm_mask_compress_epi8(ciphBytes1, blocksCompressMask, TMP[5]); + TMP[7] = _mm_mask_compress_epi8(ciphBytes2, blocksCompressMask, TMP[6]); + + /* next InputBlock ready */ + currentState = _mm_mask_compress_epi8(ciphBytes3, blocksCompressMask, TMP[7]); + + TMP[4] = _mm_shuffle_epi8(TMP[4], M128(swapBytes)); + TMP[5] = _mm_shuffle_epi8(TMP[5], M128(swapBytes)); + TMP[6] = _mm_shuffle_epi8(TMP[6], M128(swapBytes)); + TMP[7] = _mm_shuffle_epi8(TMP[7], M128(swapBytes)); + TRANSPOSE_INP_128(TMP[4], TMP[5], TMP[6], TMP[7], TMP[8]); /* TMP[8] - buffer */ + + int itr; + for(itr=0; itr<8; itr++, pRKey+=4) { + /* initial xors */ + TMP[9] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[0]), 0); + TMP[8] = TMP[9]; + TMP[8] = _mm_xor_si128(TMP[8], TMP[1] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[2] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[3] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[5] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[6] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[7] ); + /* Sbox */ + TMP[8] = sBox128(TMP[8]); + TMP[9] = sBox128(TMP[9]); + /* Sbox done, now L */ + TMP[0] = _mm_xor_si128(_mm_xor_si128(TMP[0], TMP[8]), L128(TMP[8])); + TMP[4] = _mm_xor_si128(_mm_xor_si128(TMP[4], TMP[9]), L128(TMP[9])); + + /* initial xors */ + TMP[9] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[1]), 0); + TMP[8] = TMP[9]; + TMP[8] = _mm_xor_si128(TMP[8], TMP[2] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[3] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[0] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[6] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[7] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[4] ); + /* Sbox */ + TMP[8] = sBox128(TMP[8]); + TMP[9] = sBox128(TMP[9]); + /* Sbox done, now L */ + TMP[1] = _mm_xor_si128(_mm_xor_si128(TMP[1], TMP[8]), L128(TMP[8])); + TMP[5] = _mm_xor_si128(_mm_xor_si128(TMP[5], TMP[9]), L128(TMP[9])); + + /* initial xors */ + TMP[9] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[2]), 0); + TMP[8] = TMP[9]; + TMP[8] = _mm_xor_si128(TMP[8], TMP[3] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[0] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[1] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[7] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[4] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[5] ); + /* Sbox */ + TMP[8] = sBox128(TMP[8]); + TMP[9] = sBox128(TMP[9]); + /* Sbox done, now L */ + TMP[2] = _mm_xor_si128(_mm_xor_si128(TMP[2], TMP[8]), L128(TMP[8])); + TMP[6] = _mm_xor_si128(_mm_xor_si128(TMP[6], TMP[9]), L128(TMP[9])); + + /* initial xors */ + TMP[9] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[3]), 0); + TMP[8] = TMP[9]; + TMP[8] = _mm_xor_si128(TMP[8], TMP[0] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[1] ); + TMP[8] = _mm_xor_si128(TMP[8], TMP[2] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[4] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[5] ); + TMP[9] = _mm_xor_si128(TMP[9], TMP[6] ); + /* Sbox */ + TMP[8] = sBox128(TMP[8]); + TMP[9] = sBox128(TMP[9]); + /* Sbox done, now L */ + TMP[3] = _mm_xor_si128(_mm_xor_si128(TMP[3], TMP[8]), L128(TMP[8])); + TMP[7] = _mm_xor_si128(_mm_xor_si128(TMP[7], TMP[9]), L128(TMP[9])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_128(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8]); /* TMP[8] - buffer */ + /* Order of blocks is inverted */ + + TMP[3] = _mm_shuffle_epi8(TMP[3], M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8(TMP[2], M128(swapBytes)); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + TMP[0] = _mm_shuffle_epi8(TMP[0], M128(swapBytes)); + + ciphBytes0 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 0 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 1 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 2 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 3 * cfbBlkSize); + + TMP[3] = _mm_xor_si128(ciphBytes0, TMP[3]); + TMP[2] = _mm_xor_si128(ciphBytes1, TMP[2]); + TMP[1] = _mm_xor_si128(ciphBytes2, TMP[1]); + TMP[0] = _mm_xor_si128(ciphBytes3, TMP[0]); + + _mm_mask_compressstoreu_epi8(pDst + 0 * cfbBlkSize, kMsbMask16, TMP[3]); + _mm_mask_compressstoreu_epi8(pDst + 1 * cfbBlkSize, kMsbMask16, TMP[2]); + _mm_mask_compressstoreu_epi8(pDst + 2 * cfbBlkSize, kMsbMask16, TMP[1]); + _mm_mask_compressstoreu_epi8(pDst + 3 * cfbBlkSize, kMsbMask16, TMP[0]); + + TRANSPOSE_OUT_128(TMP[4], TMP[5], TMP[6], TMP[7], TMP[8]); /* TMP[8] - buffer */ + /* Order of blocks is inverted */ + + TMP[7] = _mm_shuffle_epi8(TMP[7], M128(swapBytes)); + TMP[6] = _mm_shuffle_epi8(TMP[6], M128(swapBytes)); + TMP[5] = _mm_shuffle_epi8(TMP[5], M128(swapBytes)); + TMP[4] = _mm_shuffle_epi8(TMP[4], M128(swapBytes)); + + ciphBytes0 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 4 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 5 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 6 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 7 * cfbBlkSize); + + TMP[7] = _mm_xor_si128(ciphBytes0, TMP[7]); + TMP[6] = _mm_xor_si128(ciphBytes1, TMP[6]); + TMP[5] = _mm_xor_si128(ciphBytes2, TMP[5]); + TMP[4] = _mm_xor_si128(ciphBytes3, TMP[4]); + + _mm_mask_compressstoreu_epi8(pDst + 4 * cfbBlkSize, kMsbMask16, TMP[7]); + _mm_mask_compressstoreu_epi8(pDst + 5 * cfbBlkSize, kMsbMask16, TMP[6]); + _mm_mask_compressstoreu_epi8(pDst + 6 * cfbBlkSize, kMsbMask16, TMP[5]); + _mm_mask_compressstoreu_epi8(pDst + 7 * cfbBlkSize, kMsbMask16, TMP[4]); + + pSrc += 8 * cfbBlkSize; + pDst += 8 * cfbBlkSize; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm_setzero_si128(); //_mm_xor_si128(TMP[i],TMP[i]); + } + + len -= processedLen; + + if (len){ + _mm_storeu_si128((__m128i*)(pIV), currentState); + cpSMS4_CFB_dec_gfni128x4(pDst, pSrc, len, cfbBlkSize, pRKey, pIV); + } +} + +/* +// 4*cfbBlkSize bytes processing +*/ + +static +void cpSMS4_CFB_dec_gfni128x4(Ipp8u* pDst, const Ipp8u* pSrc, int len, int cfbBlkSize, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m128i TMP[5]; + + /* + // TMP[0..3] - decrypted text blocks + // TMP[4] - key + */ + + const Ipp16u blocksCompressMask = (Ipp16u)(0xFFFF << cfbBlkSize); + + int processedLen = len - (len % (4 * cfbBlkSize)); + int blocks; + + /* load masks; allows to load 4 source blocks of cfbBlkSize each (in bytes) to LSB parts of 128-bit lanes in 512-bit register */ + __mmask16 kLsbMask16 = (Ipp16u)(0xFFFF << (16-cfbBlkSize)); + /* same mask to load in MSB parts */ + __mmask16 kMsbMask16 = ~blocksCompressMask; + + /* load IV */ + __m128i currentState = _mm_maskz_loadu_epi64(0x03 /* load 128-bit */, pIV); + + for (blocks = len / cfbBlkSize; blocks >= (4); blocks -= (4)) { + + /* load cipher blocks to LSB parts of registers */ + __m128i ciphBytes0 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 0 * cfbBlkSize); + __m128i ciphBytes1 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 1 * cfbBlkSize); + __m128i ciphBytes2 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 2 * cfbBlkSize); + __m128i ciphBytes3 = _mm_maskz_expandloadu_epi8(kLsbMask16, pSrc + 3 * cfbBlkSize); + + /* InpBlk_j = LSB_(b-s)(InpBlk_(j-1)) | C_(j-1); b = 128 bit, s = 8*cfbBlkSize bit */ + TMP[0] = currentState; + /* drop MSB bits (size = cfbBlkSize) from the inpBlk_i (by mask) and append c_(i-1) to LSB bits */ + TMP[1] = _mm_mask_compress_epi8(ciphBytes0, blocksCompressMask, TMP[0]); + TMP[2] = _mm_mask_compress_epi8(ciphBytes1, blocksCompressMask, TMP[1]); + TMP[3] = _mm_mask_compress_epi8(ciphBytes2, blocksCompressMask, TMP[2]); + + /* next InputBlock ready */ + currentState = _mm_mask_compress_epi8(ciphBytes3, blocksCompressMask, TMP[3]); + + TMP[0] = _mm_shuffle_epi8(TMP[0], M128(swapBytes)); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8(TMP[2], M128(swapBytes)); + TMP[3] = _mm_shuffle_epi8(TMP[3], M128(swapBytes)); + TRANSPOSE_INP_128(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4]); /* TMP[4] - buffer */ + + int itr; + for(itr=0; itr<8; itr++, pRKey+=4) { + /* initial xors */ + TMP[4] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[0]), 0); + TMP[4] = _mm_xor_si128(TMP[4], TMP[1] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[2] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[3] ); + /* Sbox */ + TMP[4] = sBox128(TMP[4]); + /* Sbox done, now L */ + TMP[0] = _mm_xor_si128(_mm_xor_si128(TMP[0], TMP[4]), L128(TMP[4])); + + /* initial xors */ + TMP[4] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[1]), 0); + TMP[4] = _mm_xor_si128(TMP[4], TMP[2] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[3] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[0] ); + /* Sbox */ + TMP[4] = sBox128(TMP[4]); + /* Sbox done, now L */ + TMP[1] = _mm_xor_si128(_mm_xor_si128(TMP[1], TMP[4]), L128(TMP[4])); + + /* initial xors */ + TMP[4] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[2]), 0); + TMP[4] = _mm_xor_si128(TMP[4], TMP[3] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[0] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[1] ); + /* Sbox */ + TMP[4] = sBox128(TMP[4]); + /* Sbox done, now L */ + TMP[2] = _mm_xor_si128(_mm_xor_si128(TMP[2], TMP[4]), L128(TMP[4])); + + /* initial xors */ + TMP[4] = _mm_shuffle_epi32(_mm_cvtsi32_si128((Ipp32s)pRKey[3]), 0); + TMP[4] = _mm_xor_si128(TMP[4], TMP[0] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[1] ); + TMP[4] = _mm_xor_si128(TMP[4], TMP[2] ); + /* Sbox */ + TMP[4] = sBox128(TMP[4]); + /* Sbox done, now L */ + TMP[3] = _mm_xor_si128(_mm_xor_si128(TMP[3], TMP[4]), L128(TMP[4])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_128(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4]); /* TMP[4] - buffer */ + /* Order of blocks is inverted */ + + TMP[3] = _mm_shuffle_epi8(TMP[3], M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8(TMP[2], M128(swapBytes)); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + TMP[0] = _mm_shuffle_epi8(TMP[0], M128(swapBytes)); + + ciphBytes0 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 0 * cfbBlkSize); + ciphBytes1 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 1 * cfbBlkSize); + ciphBytes2 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 2 * cfbBlkSize); + ciphBytes3 = _mm_maskz_expandloadu_epi8(kMsbMask16, pSrc + 3 * cfbBlkSize); + + TMP[3] = _mm_xor_si128(ciphBytes0, TMP[3]); + TMP[2] = _mm_xor_si128(ciphBytes1, TMP[2]); + TMP[1] = _mm_xor_si128(ciphBytes2, TMP[1]); + TMP[0] = _mm_xor_si128(ciphBytes3, TMP[0]); + + _mm_mask_compressstoreu_epi8(pDst + 0 * cfbBlkSize, kMsbMask16, TMP[3]); + _mm_mask_compressstoreu_epi8(pDst + 1 * cfbBlkSize, kMsbMask16, TMP[2]); + _mm_mask_compressstoreu_epi8(pDst + 2 * cfbBlkSize, kMsbMask16, TMP[1]); + _mm_mask_compressstoreu_epi8(pDst + 3 * cfbBlkSize, kMsbMask16, TMP[0]); + + pSrc += 4 * cfbBlkSize; + pDst += 4 * cfbBlkSize; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm_setzero_si128(); //_mm_xor_si128(TMP[i],TMP[i]); + } + + len -= processedLen; + + if (len){ + _mm_storeu_si128((__m128i*)(pIV), currentState); + } +} + +#endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cipher.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cipher.c new file mode 100644 index 000000000..710abf4f2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_cipher.c @@ -0,0 +1,79 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpSMS4_Cipher() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + + +//#include "owndefs.h" +static void cpSMS4_ECB_gpr_x1(Ipp8u* otxt, const Ipp8u* itxt, const Ipp32u* pRoundKeys) +{ + __ALIGN16 Ipp32u buff[4 + SMS4_ROUND_KEYS_NUM]; + buff[0] = HSTRING_TO_U32(itxt); + buff[1] = HSTRING_TO_U32(itxt+sizeof(Ipp32u)); + buff[2] = HSTRING_TO_U32(itxt+sizeof(Ipp32u)*2); + buff[3] = HSTRING_TO_U32(itxt+sizeof(Ipp32u)*3); + { + int nr; + for(nr=0; nr < SMS4_ROUND_KEYS_NUM; nr++) { + buff[4+nr] = buff[nr] ^ cpCipherMix_SMS4(buff[nr+1]^buff[nr+2]^buff[nr+3]^pRoundKeys[nr]); + } + } + U32_TO_HSTRING(otxt, buff[4 + SMS4_ROUND_KEYS_NUM - 1]); + U32_TO_HSTRING(otxt+sizeof(Ipp32u), buff[4 + SMS4_ROUND_KEYS_NUM - 2]); + U32_TO_HSTRING(otxt+sizeof(Ipp32u)*2, buff[4 + SMS4_ROUND_KEYS_NUM - 3]); + U32_TO_HSTRING(otxt+sizeof(Ipp32u)*3, buff[4 + SMS4_ROUND_KEYS_NUM - 4]); + + /* clear secret data */ + PurgeBlock(buff, sizeof(buff)); +} + +IPP_OWN_DEFN (void, cpSMS4_Cipher, (Ipp8u* otxt, const Ipp8u* itxt, const Ipp32u* pRoundKeys)) +{ + #if (_IPP32E>=_IPP32E_K1) + #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + if (IsFeatureEnabled(ippCPUID_AVX512GFNI)){ + cpSMS4_ECB_gfni_x1(otxt, itxt, pRoundKeys); + return; + } + else + #endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ + #endif + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)){ + cpSMS4_ECB_aesni_x1(otxt, itxt, pRoundKeys); + return; + } + else + #endif + { + cpSMS4_ECB_gpr_x1(otxt, itxt, pRoundKeys); + return; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ctr_gfni.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ctr_gfni.c new file mode 100644 index 000000000..6a9cb7d9d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ctr_gfni.c @@ -0,0 +1,1427 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 ECB decryption +// +// Contents: +// cpSMS4_CTR_gfni512() +// cpSMS4_CTR_gfni512x48() +// cpSMS4_CTR_gfni512x32() +// cpSMS4_CTR_gfni512x16() +// cpSMS4_CTR_gfni128x12() +// cpSMS4_CTR_gfni128x8() +// cpSMS4_CTR_gfni128x4() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +#if (_IPP32E>=_IPP32E_K1) + +#if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + +#include "pcpsms4_gfni.h" + +static __ALIGN32 Ipp8u endiannes_swap[] = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3, + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3, + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3, + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3}; + +static __ALIGN32 Ipp8u endiannes[] = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0, + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0, + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0, + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; + +static __ALIGN16 Ipp8u first_inc[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +static __ALIGN16 Ipp8u next_inc[] = {4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +static __ALIGN16 Ipp8u one128[] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +__INLINE __m512i inc512(__m512i x, Ipp8u* increment) +{ + __m512i t = _mm512_add_epi64(x, M512(increment)); + __mmask8 carryMask = _mm512_cmplt_epu64_mask(t, x); + carryMask = (__mmask8)(carryMask << 1); + t = _mm512_add_epi64(t, _mm512_mask_set1_epi64(_mm512_setzero_si512(), carryMask, 1)); + + return t; +} + +__INLINE __m128i inc128(__m128i x) +{ + __m128i t = _mm_add_epi64(x, M128(one128)); + x = _mm_cmpeq_epi64(t, _mm_setzero_si128()); + t = _mm_sub_epi64(t, _mm_slli_si128(x, sizeof(Ipp64u))); + return t; +} + +static +int cpSMS4_CTR_gfni512x48(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr); +static +int cpSMS4_CTR_gfni512x32(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr); +static +int cpSMS4_CTR_gfni512x16(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr); +static +int cpSMS4_CTR_gfni128x12(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr); +static +int cpSMS4_CTR_gfni128x8(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr); +static +int cpSMS4_ECB_gfni128x4(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr); + +/* +// 64*MBS_SMS4 bytes processing +*/ + +IPP_OWN_DEFN (int, cpSMS4_CTR_gfni512, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr)) +{ + int processedLen = len - (len % (64 * MBS_SMS4)); + int n; + + if(processedLen){ + + __ALIGN16 __m512i TMP[23]; + + // TMP[20] - ctr + // TMP[21] - ctrMask + // TMP[22] - ctrUnch + + TMP[20] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtr)); + TMP[21] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtrMask)); + + /* read string counter and convert to numerical */ + TMP[20] = _mm512_shuffle_epi8(TMP[20], M512(endiannes)); + + /* read string mask and convert to numerical */ + TMP[21] = _mm512_shuffle_epi8(TMP[21], M512(endiannes)); + + /* upchanged counter bits */ + TMP[22] = _mm512_andnot_si512(TMP[21], TMP[20]); + + /* first incremention */ + TMP[20] = inc512(TMP[20], first_inc); + + TMP[20] = _mm512_and_si512(TMP[21], TMP[20]); + + for (n = 0; n < processedLen; n += (64 * MBS_SMS4), pInp += (64 * MBS_SMS4), pOut += (64 * MBS_SMS4)) { + int itr; + + TMP[0] = TMP[20]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[20] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[0], TMP[21])); + TMP[1] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[1], TMP[21])); + TMP[2] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[2], TMP[21])); + TMP[3] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[3], TMP[21])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = TMP[20]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[20] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[0], TMP[21])); + TMP[1] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[1], TMP[21])); + TMP[2] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[2], TMP[21])); + TMP[3] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[3], TMP[21])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = TMP[20]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[20] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[0], TMP[21])); + TMP[1] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[1], TMP[21])); + TMP[2] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[2], TMP[21])); + TMP[3] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[3], TMP[21])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = TMP[20]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[20] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[0], TMP[21])); + TMP[1] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[1], TMP[21])); + TMP[2] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[2], TMP[21])); + TMP[3] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[3], TMP[21])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + TMP[12] = _mm512_xor_si512(_mm512_xor_si512(TMP[12], TMP[2]), L512(TMP[2])); + TMP[16] = _mm512_xor_si512(_mm512_xor_si512(TMP[16], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + TMP[13] = _mm512_xor_si512(_mm512_xor_si512(TMP[13], TMP[2]), L512(TMP[2])); + TMP[17] = _mm512_xor_si512(_mm512_xor_si512(TMP[17], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + TMP[14] = _mm512_xor_si512(_mm512_xor_si512(TMP[14], TMP[2]), L512(TMP[2])); + TMP[18] = _mm512_xor_si512(_mm512_xor_si512(TMP[18], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + TMP[15] = _mm512_xor_si512(_mm512_xor_si512(TMP[15], TMP[2]), L512(TMP[2])); + TMP[19] = _mm512_xor_si512(_mm512_xor_si512(TMP[19], TMP[3]), L512(TMP[3])); + + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 32), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 32)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 36), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 36)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 40), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 40)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 44), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 44)))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 48), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 48)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 52), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 52)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 56), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 56)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 60), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 60)))); + + } + + /* Save counter */ + TMP[20] = _mm512_xor_si512(TMP[22], _mm512_and_si512(TMP[20], TMP[21])); + TMP[20] = _mm512_shuffle_epi8(TMP[20], M512(endiannes)); + _mm_storeu_si128((__m128i*)pCtr, _mm512_castsi512_si128(TMP[20])); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_xor_si512(TMP[i], TMP[i]); + } + + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_CTR_gfni512x48(pOut, pInp, len, pRKey, pCtrMask, pCtr); + + return processedLen; +} + +/* +// 48*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_CTR_gfni512x48(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr) +{ + int processedLen = len - (len % (48 * MBS_SMS4)); + int n; + + if(processedLen){ + + __ALIGN16 __m512i TMP[19]; + + // TMP[16] - ctr + // TMP[17] - ctrMask + // TMP[18] - ctrUnch + + TMP[16] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtr)); + TMP[17] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtrMask)); + + /* read string counter and convert to numerical */ + TMP[16] = _mm512_shuffle_epi8(TMP[16], M512(endiannes)); + + /* read string mask and convert to numerical */ + TMP[17] = _mm512_shuffle_epi8(TMP[17], M512(endiannes)); + + /* upchanged counter bits */ + TMP[18] = _mm512_andnot_si512(TMP[17], TMP[16]); + + /* first incremention */ + TMP[16] = inc512(TMP[16], first_inc); + + TMP[16] = _mm512_and_si512(TMP[17], TMP[16]); + + for (n = 0; n < processedLen; n += (48 * MBS_SMS4), pInp += (48 * MBS_SMS4), pOut += (48 * MBS_SMS4)) { + int itr; + + TMP[0] = TMP[16]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[16] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[0], TMP[17])); + TMP[1] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[1], TMP[17])); + TMP[2] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[2], TMP[17])); + TMP[3] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[3], TMP[17])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = TMP[16]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[16] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[0], TMP[17])); + TMP[1] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[1], TMP[17])); + TMP[2] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[2], TMP[17])); + TMP[3] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[3], TMP[17])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = TMP[16]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[16] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[0], TMP[17])); + TMP[1] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[1], TMP[17])); + TMP[2] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[2], TMP[17])); + TMP[3] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[3], TMP[17])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + TMP[12] = _mm512_xor_si512(_mm512_xor_si512(TMP[12], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + TMP[13] = _mm512_xor_si512(_mm512_xor_si512(TMP[13], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + TMP[14] = _mm512_xor_si512(_mm512_xor_si512(TMP[14], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + TMP[15] = _mm512_xor_si512(_mm512_xor_si512(TMP[15], TMP[2]), L512(TMP[2])); + + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 32), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 32)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 36), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 36)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 40), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 40)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 44), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 44)))); + + } + + /* Save counter */ + TMP[16] = _mm512_xor_si512(TMP[18], _mm512_and_si512(TMP[16], TMP[17])); + TMP[16] = _mm512_shuffle_epi8(TMP[16], M512(endiannes)); + _mm_storeu_si128((__m128i*)pCtr, _mm512_castsi512_si128(TMP[16])); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_xor_si512(TMP[i], TMP[i]); + } + + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_CTR_gfni512x32(pOut, pInp, len, pRKey, pCtrMask, pCtr); + + return processedLen; +} + +/* +// 32*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_CTR_gfni512x32(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr) +{ + int processedLen = len - (len % (32 * MBS_SMS4)); + int n; + + if(processedLen){ + + __ALIGN16 __m512i TMP[15]; + + // TMP[12] - ctr + // TMP[13] - ctrMask + // TMP[14] - ctrUnch + + TMP[12] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtr)); + TMP[13] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtrMask)); + + /* read string counter and convert to numerical */ + TMP[12] = _mm512_shuffle_epi8(TMP[12], M512(endiannes)); + + /* read string mask and convert to numerical */ + TMP[13] = _mm512_shuffle_epi8(TMP[13], M512(endiannes)); + + /* upchanged counter bits */ + TMP[14] = _mm512_andnot_si512(TMP[13], TMP[12]); + + /* first incremention */ + TMP[12] = inc512(TMP[12], first_inc); + + TMP[12] = _mm512_and_si512(TMP[13], TMP[12]); + + for (n = 0; n < processedLen; n += (32 * MBS_SMS4), pInp += (32 * MBS_SMS4), pOut += (32 * MBS_SMS4)) { + int itr; + + TMP[0] = TMP[12]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[12] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[0], TMP[13])); + TMP[1] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[1], TMP[13])); + TMP[2] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[2], TMP[13])); + TMP[3] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[3], TMP[13])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = TMP[12]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[12] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[0], TMP[13])); + TMP[1] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[1], TMP[13])); + TMP[2] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[2], TMP[13])); + TMP[3] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[3], TMP[13])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)))); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)))); + + } + + /* Save counter */ + TMP[12] = _mm512_xor_si512(TMP[14], _mm512_and_si512(TMP[12], TMP[13])); + TMP[12] = _mm512_shuffle_epi8(TMP[12], M512(endiannes)); + _mm_storeu_si128((__m128i*)pCtr, _mm512_castsi512_si128(TMP[12])); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_xor_si512(TMP[i], TMP[i]); + } + + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_CTR_gfni512x16(pOut, pInp, len, pRKey, pCtrMask, pCtr); + + return processedLen; +} + +/* +// 16*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_CTR_gfni512x16(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr) +{ + int processedLen = len - (len % (16 * MBS_SMS4)); + int n; + + if(processedLen){ + + __ALIGN16 __m512i TMP[11]; + + // TMP[8] - ctr + // TMP[9] - ctrMask + // TMP[10] - ctrUnch + + TMP[8] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtr)); + TMP[9] = _mm512_broadcast_i64x2(_mm_loadu_si128((__m128i*)pCtrMask)); + + /* read string counter and convert to numerical */ + TMP[8] = _mm512_shuffle_epi8(TMP[8], M512(endiannes)); + + /* read string mask and convert to numerical */ + TMP[9] = _mm512_shuffle_epi8(TMP[9], M512(endiannes)); + + /* upchanged counter bits */ + TMP[10] = _mm512_andnot_si512(TMP[9], TMP[8]); + + /* first incremention */ + TMP[8] = inc512(TMP[8], first_inc); + + TMP[8] = _mm512_and_si512(TMP[9], TMP[8]); + + for (n = 0; n < processedLen; n += (16 * MBS_SMS4), pInp += (16 * MBS_SMS4), pOut += (16 * MBS_SMS4)) { + int itr; + + TMP[0] = TMP[8]; + TMP[1] = inc512(TMP[0], next_inc); + TMP[2] = inc512(TMP[1], next_inc); + TMP[3] = inc512(TMP[2], next_inc); + TMP[8] = inc512(TMP[3], next_inc); + + TMP[0] = _mm512_xor_si512(TMP[10], _mm512_and_si512(TMP[0], TMP[9])); + TMP[1] = _mm512_xor_si512(TMP[10], _mm512_and_si512(TMP[1], TMP[9])); + TMP[2] = _mm512_xor_si512(TMP[10], _mm512_and_si512(TMP[2], TMP[9])); + TMP[3] = _mm512_xor_si512(TMP[10], _mm512_and_si512(TMP[3], TMP[9])); + + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(endiannes_swap)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(endiannes_swap)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(endiannes_swap)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(endiannes_swap)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + + _mm512_storeu_si512((__m512i*)(pOut), _mm512_xor_si512(TMP[0], _mm512_loadu_si512((__m512i*)(pInp)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), _mm512_xor_si512(TMP[1], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), _mm512_xor_si512(TMP[2], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)))); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), _mm512_xor_si512(TMP[3], _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)))); + } + + /* Save counter */ + TMP[8] = _mm512_xor_si512(TMP[10], _mm512_and_si512(TMP[8], TMP[9])); + TMP[8] = _mm512_shuffle_epi8(TMP[8], M512(endiannes)); + _mm_storeu_si128((__m128i*)pCtr, _mm512_castsi512_si128(TMP[8])); + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_xor_si512(TMP[i], TMP[i]); + } + + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_CTR_gfni128x12(pOut, pInp, len, pRKey, pCtrMask, pCtr); + + return processedLen; +} + +/* +// 12*MBS_SMS4 processing +*/ + +static +int cpSMS4_CTR_gfni128x12(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr) +{ + int processedLen = len - (len % (12 * MBS_SMS4)); + int n; + + if(processedLen){ + + __ALIGN16 __m128i TMP[22]; + + // TMP[15] - ctr + // TMP[16] - ctrMask + // TMP[17] - ctrUnch + + TMP[15] = _mm_loadu_si128((__m128i*)pCtr); + TMP[16] = _mm_loadu_si128((__m128i*)pCtrMask); + + TMP[16] = _mm_shuffle_epi8(TMP[16], M128(endiannes)); + TMP[15] = _mm_shuffle_epi8(TMP[15], M128(endiannes)); + TMP[17] = _mm_andnot_si128(TMP[16], TMP[15]); + + for(n=0; n= 1920) */ + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_decrypt_cbc.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_decrypt_cbc.c new file mode 100644 index 000000000..db773b00f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_decrypt_cbc.c @@ -0,0 +1,104 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpDecryptSMS4_cbc() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" +#include "pcpsms4_decrypt_cbc.h" + +/*F* +// Name: cpDecryptSMS4_cbc +// +// Purpose: SMS4-CBC decryption. +// +// Parameters: +// pIV pointer to the initialization vector +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// dataLen input/output buffer length (in bytes) +// pCtx pointer to the SMS4 context +// +*F*/ +IPP_OWN_DEFN (void, cpDecryptSMS4_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int dataLen, const IppsSMS4Spec* pCtx)) +{ + const Ipp32u* pRoundKeys = SMS4_DRK(pCtx); + + __ALIGN16 Ipp32u TMP[2*(MBS_SMS4/sizeof(Ipp32u))]; + + /* + iv size = MBS_SMS4/sizeof(Ipp32u) + tmp size = MBS_SMS4/sizeof(Ipp32u) + */ + + Ipp32u* iv = TMP; + Ipp32u* tmp = TMP + (MBS_SMS4/sizeof(Ipp32u)); + + /* copy IV */ + CopyBlock16(pIV, iv); + + /* do decryption */ + #if (_IPP32E>=_IPP32E_K1) + #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + if (IsFeatureEnabled(ippCPUID_AVX512GFNI)) { + int processedLen = cpSMS4_CBC_dec_gfni512(pDst, pSrc, dataLen, pRoundKeys, (Ipp8u*)iv); + pSrc += processedLen; + pDst += processedLen; + dataLen -= processedLen; + } + else + #endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ + #endif /* (_IPP32E>=_IPP32E_K1) */ + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)) { + int processedLen = cpSMS4_CBC_dec_aesni(pDst, pSrc, dataLen, pRoundKeys, (Ipp8u*)iv); + pSrc += processedLen; + pDst += processedLen; + dataLen -= processedLen; + } + #endif + + for(; dataLen>0; dataLen-=MBS_SMS4, pSrc+=MBS_SMS4, pDst+=MBS_SMS4) { + + cpSMS4_Cipher((Ipp8u*)tmp, (Ipp8u*)pSrc, pRoundKeys); + + tmp[0] ^= iv[0]; + tmp[1] ^= iv[1]; + tmp[2] ^= iv[2]; + tmp[3] ^= iv[3]; + + iv[0] = ((Ipp32u*)pSrc)[0]; + iv[1] = ((Ipp32u*)pSrc)[1]; + iv[2] = ((Ipp32u*)pSrc)[2]; + iv[3] = ((Ipp32u*)pSrc)[3]; + + CopyBlock16(tmp, pDst); + } + + /* clear secret data */ + PurgeBlock(TMP, sizeof(TMP)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_decrypt_cbc.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_decrypt_cbc.h new file mode 100644 index 000000000..7db166af0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_decrypt_cbc.h @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpDecryptSMS4_cbc() +// +*/ + +#include "owncp.h" + +#if !defined _PCP_SMS4_DECRYPT_CBC_H +#define _PCP_SMS4_DECRYPT_CBC_H + +#define cpDecryptSMS4_cbc OWNAPI(cpDecryptSMS4_cbc) + IPP_OWN_DECL (void, cpDecryptSMS4_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int dataLen, const IppsSMS4Spec* pCtx)) + +#endif /* #if !defined _PCP_SMS4_DECRYPT_CBC_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_gfni.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_gfni.c new file mode 100644 index 000000000..193a9125b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_gfni.c @@ -0,0 +1,1170 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 ECB decryption +// +// Contents: +// cpSMS4_ECB_gfni512() +// cpSMS4_ECB_gfni512x48() +// cpSMS4_ECB_gfni512x32() +// cpSMS4_ECB_gfni512x16() +// cpSMS4_ECB_gfni128x12() +// cpSMS4_ECB_gfni128x8() +// cpSMS4_ECB_gfni128x4() +// cpSMS4_ECB_gfni128x4() +// cpSMS4_ECB_gfni128_tail() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +#if (_IPP32E>=_IPP32E_K1) + +#if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + +#include "pcpsms4_gfni.h" + + +static +int cpSMS4_ECB_gfni512x48(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey); +static +int cpSMS4_ECB_gfni512x32(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey); +static +int cpSMS4_ECB_gfni512x16(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey); +static +int cpSMS4_ECB_gfni128x12(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey); +static +int cpSMS4_ECB_gfni128x8(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey); +static +int cpSMS4_ECB_gfni128x4(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey); +static +int cpSMS4_ECB_gfni128_tail(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey); + +/* +// 64*MBS_SMS4 bytes processing +*/ + +IPP_OWN_DEFN (int, cpSMS4_ECB_gfni512, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) +{ + __ALIGN16 __m512i TMP[20]; + + int processedLen = len - (len % (64 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (64 * MBS_SMS4), pInp += (64 * MBS_SMS4), pOut += (64 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 32)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 36)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 40)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 44)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 48)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 52)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 56)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 60)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[16], TMP[17], TMP[18], TMP[19], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + TMP[12] = _mm512_xor_si512(_mm512_xor_si512(TMP[12], TMP[2]), L512(TMP[2])); + TMP[16] = _mm512_xor_si512(_mm512_xor_si512(TMP[16], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + TMP[13] = _mm512_xor_si512(_mm512_xor_si512(TMP[13], TMP[2]), L512(TMP[2])); + TMP[17] = _mm512_xor_si512(_mm512_xor_si512(TMP[17], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[19]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + TMP[14] = _mm512_xor_si512(_mm512_xor_si512(TMP[14], TMP[2]), L512(TMP[2])); + TMP[18] = _mm512_xor_si512(_mm512_xor_si512(TMP[18], TMP[3]), L512(TMP[3])); + + /* initial xors */ + TMP[3] = TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[16]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[17]); + TMP[3] = _mm512_xor_si512(TMP[3], TMP[18]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + TMP[3] = sBox512(TMP[3]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + TMP[15] = _mm512_xor_si512(_mm512_xor_si512(TMP[15], TMP[2]), L512(TMP[2])); + TMP[19] = _mm512_xor_si512(_mm512_xor_si512(TMP[19], TMP[3]), L512(TMP[3])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 32), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 36), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 40), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 44), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[16], TMP[17], TMP[18], TMP[19]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 48), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 52), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 56), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 60), TMP[3]); + } + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len){ + if(len < 256){ + processedLen += cpSMS4_ECB_gfni128x12(pOut, pInp, len, pRKey); + return processedLen; + } + processedLen += cpSMS4_ECB_gfni512x48(pOut, pInp, len, pRKey); + } + + return processedLen; +} + +/* +// 48*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_ECB_gfni512x48(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey) +{ + __ALIGN16 __m512i TMP[16]; + + int processedLen = len - (len % (48 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (48 * MBS_SMS4), pInp += (48 * MBS_SMS4), pOut += (48 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 32)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 36)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 40)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 44)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[12], TMP[13], TMP[14], TMP[15], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + TMP[12] = _mm512_xor_si512(_mm512_xor_si512(TMP[12], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + TMP[13] = _mm512_xor_si512(_mm512_xor_si512(TMP[13], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[15]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + TMP[14] = _mm512_xor_si512(_mm512_xor_si512(TMP[14], TMP[2]), L512(TMP[2])); + + /* initial xors */ + TMP[2] = TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[12]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[13]); + TMP[2] = _mm512_xor_si512(TMP[2], TMP[14]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + TMP[2] = sBox512(TMP[2]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + TMP[15] = _mm512_xor_si512(_mm512_xor_si512(TMP[15], TMP[2]), L512(TMP[2])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[12], TMP[13], TMP[14], TMP[15]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 32), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 36), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 40), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 44), TMP[3]); + } + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_ECB_gfni512x32(pOut, pInp, len, pRKey); + + return processedLen; +} + +/* +// 32*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_ECB_gfni512x32(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey) +{ + __ALIGN16 __m512i TMP[12]; + + int processedLen = len - (len % (32 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (32 * MBS_SMS4), pInp += (32 * MBS_SMS4), pOut += (32 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 16)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 20)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 24)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 28)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[8], TMP[9], TMP[10], TMP[11], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + TMP[8] = _mm512_xor_si512(_mm512_xor_si512(TMP[8], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + TMP[9] = _mm512_xor_si512(_mm512_xor_si512(TMP[9], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[11]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + TMP[10] = _mm512_xor_si512(_mm512_xor_si512(TMP[10], TMP[1]), L512(TMP[1])); + + /* initial xors */ + TMP[1] = TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[8]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[9]); + TMP[1] = _mm512_xor_si512(TMP[1], TMP[10]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + TMP[1] = sBox512(TMP[1]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + TMP[11] = _mm512_xor_si512(_mm512_xor_si512(TMP[11], TMP[1]), L512(TMP[1])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[3]); + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[8], TMP[9], TMP[10], TMP[11]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 16), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 20), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 24), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 28), TMP[3]); + } + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_ECB_gfni512x16(pOut, pInp, len, pRKey); + + return processedLen; +} + +/* +// 16*MBS_SMS4 bytes processing +*/ + +static +int cpSMS4_ECB_gfni512x16(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey) +{ + __ALIGN16 __m512i TMP[8]; + + int processedLen = len - (len % (16 * MBS_SMS4)); + int n; + for (n = 0; n < processedLen; n += (16 * MBS_SMS4), pInp += (16 * MBS_SMS4), pOut += (16 * MBS_SMS4)) { + int itr; + + TMP[0] = _mm512_loadu_si512((__m512i*)(pInp)); + TMP[1] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 4)); + TMP[2] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 8)); + TMP[3] = _mm512_loadu_si512((__m512i*)(pInp + MBS_SMS4 * 12)); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + TRANSPOSE_INP_512(TMP[4], TMP[5], TMP[6], TMP[7], TMP[0], TMP[1], TMP[2], TMP[3]); + + for (itr = 0; itr < 8; itr++, pRKey += 4) { + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[0]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[4] = _mm512_xor_si512(_mm512_xor_si512(TMP[4], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[1]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[5] = _mm512_xor_si512(_mm512_xor_si512(TMP[5], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[2]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[7]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[6] = _mm512_xor_si512(_mm512_xor_si512(TMP[6], TMP[0]), L512(TMP[0])); + + /* initial xors */ + TMP[0] = _mm512_set1_epi32((Ipp32s)pRKey[3]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[4]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[5]); + TMP[0] = _mm512_xor_si512(TMP[0], TMP[6]); + /* Sbox */ + TMP[0] = sBox512(TMP[0]); + /* Sbox done, now L */ + TMP[7] = _mm512_xor_si512(_mm512_xor_si512(TMP[7], TMP[0]), L512(TMP[0])); + } + + pRKey -= 32; + + TRANSPOSE_OUT_512(TMP[0], TMP[1], TMP[2], TMP[3], TMP[4], TMP[5], TMP[6], TMP[7]); + TMP[0] = _mm512_shuffle_epi8(TMP[0], M512(swapBytes)); + TMP[1] = _mm512_shuffle_epi8(TMP[1], M512(swapBytes)); + TMP[2] = _mm512_shuffle_epi8(TMP[2], M512(swapBytes)); + TMP[3] = _mm512_shuffle_epi8(TMP[3], M512(swapBytes)); + _mm512_storeu_si512((__m512i*)(pOut), TMP[0]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 4), TMP[1]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 8), TMP[2]); + _mm512_storeu_si512((__m512i*)(pOut + MBS_SMS4 * 12), TMP[3]); + } + + /* clear secret data */ + for (unsigned int i = 0; i < sizeof(TMP) / sizeof(TMP[0]); ++i) { + TMP[i] = _mm512_setzero_si512(); //_mm512_xor_si512(TMP[i], TMP[i]); + } + + len -= processedLen; + if (len) + processedLen += cpSMS4_ECB_gfni128x12(pOut, pInp, len, pRKey); + + return processedLen; +} + +/* +// 12*MBS_SMS4 processing +*/ + +static +int cpSMS4_ECB_gfni128x12(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey) +{ + __ALIGN16 __m128i TMP[15]; + + int processedLen = len -(len % (12*MBS_SMS4)); + int n; + for(n=0; n= 1920) */ + +#endif /* _IPP32E>=_IPP32E_K1 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_x1_aesni.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_x1_aesni.c new file mode 100644 index 000000000..72c38e7b2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_x1_aesni.c @@ -0,0 +1,114 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 ECB encryption/decryption +// +// Contents: +// cpSMS4_ECB_aesni_x1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + +#include "pcpsms4_y8cn.h" + +/* +// 1*MBS_SMS4 processing +*/ + +IPP_OWN_DEFN (void, cpSMS4_ECB_aesni_x1, (Ipp8u* pOut, const Ipp8u* pInp, const Ipp32u* pRKey)) +{ + __ALIGN16 __m128i TMP[6]; + /* + TMP[0] = T + TMP[1] = K0 + TMP[2] = K1 + TMP[3] = K2 + TMP[4] = K3 + TMP[5] = key4 + */ + + TMP[1] = _mm_shuffle_epi8( _mm_cvtsi32_si128(((Ipp32s*)pInp)[0]), M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8( _mm_cvtsi32_si128(((Ipp32s*)pInp)[1]), M128(swapBytes)); + TMP[3] = _mm_shuffle_epi8( _mm_cvtsi32_si128(((Ipp32s*)pInp)[2]), M128(swapBytes)); + TMP[4] = _mm_shuffle_epi8( _mm_cvtsi32_si128(((Ipp32s*)pInp)[3]), M128(swapBytes)); + + int itr; + for(itr=0; itr<8; itr++, pRKey+=4) { + TMP[5] = _mm_loadu_si128((__m128i*)pRKey); + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0x00); /* broadcast(key4 TMP[0]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[1] = _mm_xor_si128(_mm_xor_si128(TMP[1], TMP[0]), L(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0x55); /* broadcast(key4 TMP[1]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[2] = _mm_xor_si128(_mm_xor_si128(TMP[2], TMP[0]), L(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0xAA); /* broadcast(key4 TMP[2]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[3] = _mm_xor_si128(_mm_xor_si128(TMP[3], TMP[0]), L(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0xFF); /* broadcast(key4 TMP[3]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[4] = _mm_xor_si128(_mm_xor_si128(TMP[4], TMP[0]), L(TMP[0])); + } + + ((Ipp32u*)(pOut))[0] = (Ipp32u)_mm_cvtsi128_si32(_mm_shuffle_epi8(TMP[4], M128(swapBytes))); + ((Ipp32u*)(pOut))[1] = (Ipp32u)_mm_cvtsi128_si32(_mm_shuffle_epi8(TMP[3], M128(swapBytes))); + ((Ipp32u*)(pOut))[2] = (Ipp32u)_mm_cvtsi128_si32(_mm_shuffle_epi8(TMP[2], M128(swapBytes))); + ((Ipp32u*)(pOut))[3] = (Ipp32u)_mm_cvtsi128_si32(_mm_shuffle_epi8(TMP[1], M128(swapBytes))); + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm_xor_si128(TMP[i],TMP[i]); + } +} + +#endif /* _IPP_P8, _IPP32E_Y8 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_x1_gfni.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_x1_gfni.c new file mode 100644 index 000000000..16ab55e55 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_ecb_x1_gfni.c @@ -0,0 +1,119 @@ +/******************************************************************************* +* Copyright (C) 2020 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 ECB encryption/decryption +// +// Contents: +// cpSMS4_ECB_gfni_x1() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +#if (_IPP32E>=_IPP32E_K1) + +#if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + +#include "pcpsms4_gfni.h" + +IPP_OWN_DEFN (void, cpSMS4_ECB_gfni_x1, (Ipp8u* pOut, const Ipp8u* pInp, const Ipp32u* pRKey)) +{ + __ALIGN16 __m128i TMP[6]; + /* + TMP[0] = T + TMP[1] = K0 + TMP[2] = K1 + TMP[3] = K2 + TMP[4] = K3 + TMP[5] = key4 + */ + + TMP[1] = _mm_loadu_si128((__m128i*)pInp); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + + TMP[2] = _mm_alignr_epi32(TMP[1], TMP[1], 1); + TMP[3] = _mm_alignr_epi32(TMP[1], TMP[1], 2); + TMP[4] = _mm_alignr_epi32(TMP[1], TMP[1], 3); + + int itr; + for(itr=0; itr<8; itr++, pRKey+=4) { + TMP[5] = _mm_loadu_si128((__m128i*)pRKey); + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0x00); /* broadcast(key4 TMP[0]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + /* Sbox */ + TMP[0] = sBox128(TMP[0]); + /* Sbox done, now L */ + TMP[1] = _mm_xor_si128(_mm_xor_si128(TMP[1], TMP[0]), L128(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0x55); /* broadcast(key4 TMP[1]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + /* Sbox */ + TMP[0] = sBox128(TMP[0]); + /* Sbox done, now L */ + TMP[2] = _mm_xor_si128(_mm_xor_si128(TMP[2], TMP[0]), L128(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0xAA); /* broadcast(key4 TMP[2]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + /* Sbox */ + TMP[0] = sBox128(TMP[0]); + /* Sbox done, now L */ + TMP[3] = _mm_xor_si128(_mm_xor_si128(TMP[3], TMP[0]), L128(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0xFF); /* broadcast(key4 TMP[3]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + /* Sbox */ + TMP[0] = sBox128(TMP[0]); + /* Sbox done, now L */ + TMP[4] = _mm_xor_si128(_mm_xor_si128(TMP[4], TMP[0]), L128(TMP[0])); + } + + TMP[0] = _mm_unpacklo_epi32(TMP[2], TMP[1]); + TMP[5] = _mm_unpacklo_epi32(TMP[4], TMP[3]); + TMP[1] = _mm_unpacklo_epi64(TMP[5], TMP[0]); + + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + + _mm_storeu_si128((__m128i*)pOut, TMP[1]); + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm_xor_si128(TMP[i],TMP[i]); + } +} + +#endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ + +#endif /* (_IPP32E>=_IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_encrypt_cbc.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_encrypt_cbc.c new file mode 100644 index 000000000..16e4778cb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_encrypt_cbc.c @@ -0,0 +1,73 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpEncryptSMS4_cbc() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" +#include "pcpsms4_encrypt_cbc.h" + +/*F* +// +// Name: cpEncryptSMS4_cbc +// +// Purpose: SMS4-CBC encryption. +// +// Parameters: +// pIV pointer to the initialization vector +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// dataLen input/output buffer length (in bytes) +// pCtx pointer to the SMS4 context +// +*F*/ +IPP_OWN_DEFN (void, cpEncryptSMS4_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int dataLen, const IppsSMS4Spec* pCtx)) +{ + const Ipp32u* pRoundKeys = SMS4_RK(pCtx); + + /* read IV */ + __ALIGN16 Ipp32u iv[MBS_SMS4/sizeof(Ipp32u)]; + CopyBlock16(pIV, iv); + + /* do encryption */ + for(; dataLen>0; dataLen-=MBS_SMS4, pSrc+=MBS_SMS4, pDst+=MBS_SMS4) { + iv[0] ^= ((Ipp32u*)pSrc)[0]; + iv[1] ^= ((Ipp32u*)pSrc)[1]; + iv[2] ^= ((Ipp32u*)pSrc)[2]; + iv[3] ^= ((Ipp32u*)pSrc)[3]; + + cpSMS4_Cipher(pDst, (Ipp8u*)iv, pRoundKeys); + + iv[0] = ((Ipp32u*)pDst)[0]; + iv[1] = ((Ipp32u*)pDst)[1]; + iv[2] = ((Ipp32u*)pDst)[2]; + iv[3] = ((Ipp32u*)pDst)[3]; + } + + /* clear secret data */ + PurgeBlock(iv, sizeof(iv)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_encrypt_cbc.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_encrypt_cbc.h new file mode 100644 index 000000000..70dc8acb0 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_encrypt_cbc.h @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpEncryptSMS4_cbc() +// +*/ + +#include "owncp.h" + +#if !defined _PCP_SMS4_ENCRYPT_CBC_H +#define _PCP_SMS4_ENCRYPT_CBC_H + +#define cpEncryptSMS4_cbc OWNAPI(cpEncryptSMS4_cbc) + IPP_OWN_DECL (void, cpEncryptSMS4_cbc, (const Ipp8u* pIV, const Ipp8u* pSrc, Ipp8u* pDst, int dataLen, const IppsSMS4Spec* pCtx)) + +#endif /* #if !defined _PCP_SMS4_ENCRYPT_CBC_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_gfni.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_gfni.h new file mode 100644 index 000000000..ce085c7aa --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_gfni.h @@ -0,0 +1,302 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// sBox() +// L() +// TRANSPOSE_INP() +// TRANSPOSE_OUT() +// +*/ + +#ifndef __SMS4_SBOX_GFNI512_H_ +#define __SMS4_SBOX_GFNI512_H_ + +#include "owndefs.h" +#include "owncp.h" + +#if (_IPP32E>=_IPP32E_K1) + +#if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + +static __ALIGN64 Ipp8u swapBytes[] = { 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12 }; +/* +// Not used in current pipeline +static __ALIGN32 Ipp8u permMask256[] = {0x00,0x00,0x00,0x00, 0x04,0x00,0x00,0x00, 0x01,0x00,0x00,0x00, 0x05,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00, 0x06,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x07,0x00,0x00,0x00}; +*/ + +static __ALIGN64 Ipp8u permMask_in[] = {0,0x00,0x00,0x00, 4,0x00,0x00,0x00, 8,0x00,0x00,0x00, 12,0x00,0x00,0x00, + 1,0x00,0x00,0x00, 5,0x00,0x00,0x00, 9,0x00,0x00,0x00, 13,0x00,0x00,0x00, + 2,0x00,0x00,0x00, 6,0x00,0x00,0x00, 10,0x00,0x00,0x00, 14,0x00,0x00,0x00, + 3,0x00,0x00,0x00, 7,0x00,0x00,0x00, 11,0x00,0x00,0x00, 15,0x00,0x00,0x00 }; + +static __ALIGN64 Ipp8u permMask_out[] = {12,0x00,0x00,0x00, 8,0x00,0x00,0x00, 4,0x00,0x00,0x00, 0,0x00,0x00,0x00, + 13,0x00,0x00,0x00, 9,0x00,0x00,0x00, 5,0x00,0x00,0x00, 1,0x00,0x00,0x00, + 14,0x00,0x00,0x00, 10,0x00,0x00,0x00, 6,0x00,0x00,0x00, 2,0x00,0x00,0x00, + 15,0x00,0x00,0x00, 11,0x00,0x00,0x00, 7,0x00,0x00,0x00, 3,0x00,0x00,0x00}; + +static __ALIGN64 Ipp8u affineIn[] = { 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34 }; +static __ALIGN64 Ipp8u affineOut[] = { 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7 }; + +#define M512(mem) (*((__m512i*)(mem))) +#define M256(mem) (*((__m256i*)(mem))) +#define M128(mem) (*((__m128i*)(mem))) + +/* +// +// GF(256) is isomorfic. +// Encoding/decoding data of SM4 and AES are elements of GF(256). +// The difference in representation only. +// (It happend due to using different generating polynomials in SM4 and AES representations). +// Doing data conversion from SM4 to AES domain +// lets use AES specific intrinsics to perform less expensive SMS4 S-box computation. +// +// Original SMS4 S-box algorithm is converted to the following: +// +// - transform data from SMS4 representation to AES representation +// - compute S-box value +// - transform data back from AES representation to SMS4 representation +// +*/ + +/* +// sBox +*/ + +__FORCEINLINE __m512i sBox512(__m512i block) +{ + block = _mm512_gf2p8affine_epi64_epi8(block, M512(affineIn), 0x65); + block = _mm512_gf2p8affineinv_epi64_epi8(block, M512(affineOut), 0xd3); + return block; +} + +/* +// Not used in current pipeline +__FORCEINLINE __m256i sBox256(__m256i block) +{ + block = _mm256_gf2p8affine_epi64_epi8(block, M256(affineIn), 0x65); + block = _mm256_gf2p8affineinv_epi64_epi8(block, M256(affineOut), 0xd3); + return block; + +} +*/ + +__FORCEINLINE __m128i sBox128(__m128i block) +{ + block = _mm_gf2p8affine_epi64_epi8(block, M128(affineIn), 0x65); + block = _mm_gf2p8affineinv_epi64_epi8(block, M128(affineOut), 0xd3); + return block; + +} + +/* +// L +*/ + +__FORCEINLINE __m512i L512(__m512i x) +{ + __m512i rolled0 = _mm512_rol_epi32(x, 2); + __m512i rolled1 = _mm512_rol_epi32(x, 10); + __m512i temp = _mm512_xor_si512(rolled0, rolled1); + __m512i rolled2 = _mm512_rol_epi32(x, 18); + __m512i rolled3 = _mm512_rol_epi32(x, 24); + __m512i res = _mm512_ternarylogic_epi32(temp, rolled2, rolled3, 0x96); + return res; +} + +/* +// Not used in current pipeline +__FORCEINLINE __m256i L256(__m256i x) +{ + __m256i T = _mm256_xor_si256(_mm256_slli_epi32(x, 2), _mm256_srli_epi32(x,30)); + + T = _mm256_xor_si256(T, _mm256_slli_epi32 (x,10)); + T = _mm256_xor_si256(T, _mm256_srli_epi32 (x,22)); + + T = _mm256_xor_si256(T, _mm256_slli_epi32 (x,18)); + T = _mm256_xor_si256(T, _mm256_srli_epi32 (x,14)); + + T = _mm256_xor_si256(T, _mm256_slli_epi32 (x,24)); + T = _mm256_xor_si256(T, _mm256_srli_epi32 (x, 8)); + return T; +} +*/ + +__FORCEINLINE __m128i L128(__m128i x) +{ + __m128i rolled0 = _mm_rol_epi32(x, 2); + __m128i rolled1 = _mm_rol_epi32(x, 10); + __m128i temp = _mm_xor_si128(rolled1, rolled0); + __m128i rolled2 = _mm_rol_epi32(x, 18); + __m128i rolled3 = _mm_rol_epi32(x, 24); + __m128i res = _mm_ternarylogic_epi32(temp, rolled2, rolled3, 0x96); + return res; +} + + +/* +// TRANSPOSE_INP +*/ + +/* +// inp: T0, T1, T2, T3 +// out: K0, K1, K2, K3 +*/ +#define TRANSPOSE_INP_512(K0,K1,K2,K3, T0,T1,T2,T3) \ + K0 = _mm512_unpacklo_epi32(T0, T1); \ + K1 = _mm512_unpacklo_epi32(T2, T3); \ + K2 = _mm512_unpackhi_epi32(T0, T1); \ + K3 = _mm512_unpackhi_epi32(T2, T3); \ + \ + T0 = _mm512_unpacklo_epi64(K0, K1); \ + T1 = _mm512_unpacklo_epi64(K2, K3); \ + T2 = _mm512_unpackhi_epi64(K0, K1); \ + T3 = _mm512_unpackhi_epi64(K2, K3); \ + \ + K2 = _mm512_permutexvar_epi32(M512(permMask_in), T1); \ + K1 = _mm512_permutexvar_epi32(M512(permMask_in), T2); \ + K3 = _mm512_permutexvar_epi32(M512(permMask_in), T3); \ + K0 = _mm512_permutexvar_epi32(M512(permMask_in), T0) + +/* +// inp: T0, T1, T2, T3 +// out: K0, K1, K2, K3 +*/ + +/* +// Not used in current pipeline +#define TRANSPOSE_INP_256(K0,K1,K2,K3, T0,T1,T2,T3) \ + K0 = _mm256_unpacklo_epi32(T0, T1); \ + K1 = _mm256_unpacklo_epi32(T2, T3); \ + K2 = _mm256_unpackhi_epi32(T0, T1); \ + K3 = _mm256_unpackhi_epi32(T2, T3); \ + \ + T0 = _mm256_unpacklo_epi64(K0, K1); \ + T1 = _mm256_unpacklo_epi64(K2, K3); \ + T2 = _mm256_unpackhi_epi64(K0, K1); \ + T3 = _mm256_unpackhi_epi64(K2, K3); \ + \ + K2 = _mm256_permutevar8x32_epi32(T1, M256(permMask256)); \ + K1 = _mm256_permutevar8x32_epi32(T2, M256(permMask256)); \ + K3 = _mm256_permutevar8x32_epi32(T3, M256(permMask256)); \ + K0 = _mm256_permutevar8x32_epi32(T0, M256(permMask256)) +*/ + +#define TRANSPOSE_INP_128(K0,K1,K2,K3, T) \ + T = _mm_unpacklo_epi32(K0, K1); \ + K1 = _mm_unpackhi_epi32(K0, K1); \ + K0 = _mm_unpacklo_epi32(K2, K3); \ + K3 = _mm_unpackhi_epi32(K2, K3); \ + \ + K2 = _mm_unpacklo_epi64(K1, K3); \ + K3 = _mm_unpackhi_epi64(K1, K3); \ + K1 = _mm_unpackhi_epi64(T, K0); \ + K0 = _mm_unpacklo_epi64(T, K0) + +/* +// TRANSPOSE_OUT +*/ + +/* +// inp: K0, K1, K2, K3 +// out: T0, T1, T2, T3 +*/ + +#define TRANSPOSE_OUT_512(T0,T1,T2,T3, K0,K1,K2,K3) \ + T0 = _mm512_shuffle_i32x4(K0, K1, 0x44); \ + T1 = _mm512_shuffle_i32x4(K0, K1, 0xee); \ + T2 = _mm512_shuffle_i32x4(K2, K3, 0x44); \ + T3 = _mm512_shuffle_i32x4(K2, K3, 0xee); \ + \ + K0 = _mm512_shuffle_i32x4(T0, T2, 0x88); \ + K1 = _mm512_shuffle_i32x4(T0, T2, 0xdd); \ + K2 = _mm512_shuffle_i32x4(T1, T3, 0x88); \ + K3 = _mm512_shuffle_i32x4(T1, T3, 0xdd); \ + \ + K0 = _mm512_permutexvar_epi32(M512(permMask_out), K0);\ + K1 = _mm512_permutexvar_epi32(M512(permMask_out), K1);\ + K2 = _mm512_permutexvar_epi32(M512(permMask_out), K2);\ + K3 = _mm512_permutexvar_epi32(M512(permMask_out), K3);\ + \ +T0=K0,T1=K1,T2=K2,T3=K3 + + +/* +// inp: K0, K1, K2, K3 +// out: T0, T1, T2, T3 +*/ + +/* +// Not used in current pipeline +#define TRANSPOSE_OUT_256(T0,T1,T2,T3, K0,K1,K2,K3) \ + T0 = _mm256_unpacklo_epi32(K1, K0); \ + T1 = _mm256_unpacklo_epi32(K3, K2); \ + T2 = _mm256_unpackhi_epi32(K1, K0); \ + T3 = _mm256_unpackhi_epi32(K3, K2); \ + \ + K0 = _mm256_unpacklo_epi64(T1, T0); \ + K1 = _mm256_unpacklo_epi64(T3, T2); \ + K2 = _mm256_unpackhi_epi64(T1, T0); \ + K3 = _mm256_unpackhi_epi64(T3, T2); \ + \ + T0 = _mm256_permute2x128_si256(K0, K2, 0x20); \ + T1 = _mm256_permute2x128_si256(K1, K3, 0x20); \ + T2 = _mm256_permute2x128_si256(K0, K2, 0x31); \ + T3 = _mm256_permute2x128_si256(K1, K3, 0x31) +*/ + +#define TRANSPOSE_OUT_128(K0,K1,K2,K3, T) \ + T = _mm_unpacklo_epi32(K1, K0); \ + K0 = _mm_unpackhi_epi32(K1, K0); \ + K1 = _mm_unpacklo_epi32(K3, K2); \ + K3 = _mm_unpackhi_epi32(K3, K2); \ + \ + K2 = _mm_unpackhi_epi64(K1, T); \ + T = _mm_unpacklo_epi64(K1, T); \ + K1 = _mm_unpacklo_epi64(K3, K0); \ + K0 = _mm_unpackhi_epi64(K3, K0); \ + K3 = T + +//#define PR(X) printf("%08u %08u %08u %08u | %08u %08u %08u %08u | %08u %08u %08u %08u | %08u %08u %08u %08u\n",\ +// X.m512i_u32[0], X.m512i_u32[1], X.m512i_u32[2],\ +// X.m512i_u32[3], X.m512i_u32[4], X.m512i_u32[5],\ +// X.m512i_u32[6], X.m512i_u32[7], X.m512i_u32[8],\ +// X.m512i_u32[9], X.m512i_u32[10], X.m512i_u32[11],\ +// X.m512i_u32[12], X.m512i_u32[13], X.m512i_u32[14],\ +// X.m512i_u32[15]); + +#endif + +#endif /* if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ + +#endif /* __SMS4_SBOX_GFNI512_H_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_l9cn.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_l9cn.h new file mode 100644 index 000000000..8bf27d02f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_l9cn.h @@ -0,0 +1,186 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// affine() +// sBox() +// L() +// TRANSPOSE_INP() +// TRANSPOSE_OUT() +// +*/ + +#if (_IPP>=_IPP_H9) || (_IPP32E>=_IPP32E_L9) + +#ifndef __SMS4_SBOX_L9_H_ +#define __SMS4_SBOX_L9_H_ + +#include "owndefs.h" +#include "owncp.h" + +static __ALIGN32 Ipp8u inpMaskLO[] = {0x65,0x41,0xfd,0xd9,0x0a,0x2e,0x92,0xb6,0x0f,0x2b,0x97,0xb3,0x60,0x44,0xf8,0xdc, + 0x65,0x41,0xfd,0xd9,0x0a,0x2e,0x92,0xb6,0x0f,0x2b,0x97,0xb3,0x60,0x44,0xf8,0xdc}; +static __ALIGN32 Ipp8u inpMaskHI[] = {0x00,0xc9,0x67,0xae,0x80,0x49,0xe7,0x2e,0x4a,0x83,0x2d,0xe4,0xca,0x03,0xad,0x64, + 0x00,0xc9,0x67,0xae,0x80,0x49,0xe7,0x2e,0x4a,0x83,0x2d,0xe4,0xca,0x03,0xad,0x64}; +static __ALIGN32 Ipp8u outMaskLO[] = {0xd3,0x59,0x38,0xb2,0xcc,0x46,0x27,0xad,0x36,0xbc,0xdd,0x57,0x29,0xa3,0xc2,0x48, + 0xd3,0x59,0x38,0xb2,0xcc,0x46,0x27,0xad,0x36,0xbc,0xdd,0x57,0x29,0xa3,0xc2,0x48}; +static __ALIGN32 Ipp8u outMaskHI[] = {0x00,0x50,0x14,0x44,0x89,0xd9,0x9d,0xcd,0xde,0x8e,0xca,0x9a,0x57,0x07,0x43,0x13, + 0x00,0x50,0x14,0x44,0x89,0xd9,0x9d,0xcd,0xde,0x8e,0xca,0x9a,0x57,0x07,0x43,0x13}; + +static __ALIGN32 Ipp8u maskSrows[] = {0x00,0x0d,0x0a,0x07,0x04,0x01,0x0e,0x0b,0x08,0x05,0x02,0x0f,0x0c,0x09,0x06,0x03, + 0x00,0x0d,0x0a,0x07,0x04,0x01,0x0e,0x0b,0x08,0x05,0x02,0x0f,0x0c,0x09,0x06,0x03}; + +static __ALIGN16 Ipp8u encKey[] = {0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63}; + +static __ALIGN32 Ipp8u lowBits4[] = {0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f}; + +static __ALIGN32 Ipp8u swapBytes[] = {3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12, + 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12}; + +static __ALIGN32 Ipp8u permMask[] = {0x00,0x00,0x00,0x00, 0x04,0x00,0x00,0x00, 0x01,0x00,0x00,0x00, 0x05,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00, 0x06,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x07,0x00,0x00,0x00}; + +static __ALIGN32 Ipp8u affineIn[] = { 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, + 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34 }; +static __ALIGN32 Ipp8u affineOut[] = { 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, + 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7 }; + +#define M256(mem) (*((__m256i*)((Ipp8u*)(mem)))) +#define M128(mem) (*((__m128i*)((Ipp8u*)(mem)))) + +/* +// +// AES and SMS4 ciphers both based on composite field GF(2^8). +// This affine transformation transforms 16 bytes +// from SMS4 representation to AES representation or vise versa +// depending on passed masks. +// +*/ + +__FORCEINLINE __m256i affine(__m256i x, __m256i maskLO, __m256i maskHI) +{ + __m256i T1 = _mm256_and_si256(_mm256_srli_epi64(x, 4), M256(lowBits4)); + __m256i T0 = _mm256_and_si256(x, M256(lowBits4)); + T0 = _mm256_shuffle_epi8(maskLO, T0); + T1 = _mm256_shuffle_epi8(maskHI, T1); + return _mm256_xor_si256(T0, T1); +} + +__FORCEINLINE __m256i AES_ENC_LAST(__m256i x, __m128i key) +{ + __m128i t0 = _mm256_extracti128_si256(x, 0); + __m128i t1 = _mm256_extracti128_si256(x, 1); + t0 = _mm_aesenclast_si128(t0, key); + t1 = _mm_aesenclast_si128(t1, key); + x = _mm256_inserti128_si256(x, t0, 0); + x = _mm256_inserti128_si256(x, t1, 1); + return x; +} + +/* +// +// GF(256) is isomorfic. +// Encoding/decoding data of SM4 and AES are elements of GF(256). +// The difference in representation only. +// (It happend due to using different generating polynomials in SM4 and AES representations). +// Doing data conversion from SM4 to AES domain +// lets use AES specific intrinsics to perform less expensive SMS4 S-box computation. +// +// Original SMS4 S-box algorithm is converted to the following: +// +// - transform data from SMS4 representation to AES representation +// - compute S-box value using _mm_aesenclast_si128 with special key +// - re-shuffle data after _mm_aesenclast_si128 that shuffle it inside +// - transform data back from AES representation to SMS4 representation +// +*/ + +__FORCEINLINE __m256i sBox(__m256i block) +{ + block = affine(block, M256(inpMaskLO), M256(inpMaskHI)); + block = AES_ENC_LAST(block, M128(encKey)); + block = _mm256_shuffle_epi8(block, M256(maskSrows)); + block = affine(block, M256(outMaskLO), M256(outMaskHI)); + + return block; +} + +__FORCEINLINE __m256i L(__m256i x) +{ + __m256i T = _mm256_xor_si256(_mm256_slli_epi32(x, 2), _mm256_srli_epi32(x,30)); + + T = _mm256_xor_si256(T, _mm256_slli_epi32 (x,10)); + T = _mm256_xor_si256(T, _mm256_srli_epi32 (x,22)); + + T = _mm256_xor_si256(T, _mm256_slli_epi32 (x,18)); + T = _mm256_xor_si256(T, _mm256_srli_epi32 (x,14)); + + T = _mm256_xor_si256(T, _mm256_slli_epi32 (x,24)); + T = _mm256_xor_si256(T, _mm256_srli_epi32 (x, 8)); + return T; +} + +/* +// inp: T0, T1, T2, T3 +// out: K0, K1, K2, K3 +*/ +#define TRANSPOSE_INP(K0,K1,K2,K3, T0,T1,T2,T3) \ + K0 = _mm256_unpacklo_epi32(T0, T1); \ + K1 = _mm256_unpacklo_epi32(T2, T3); \ + K2 = _mm256_unpackhi_epi32(T0, T1); \ + K3 = _mm256_unpackhi_epi32(T2, T3); \ + \ + T0 = _mm256_unpacklo_epi64(K0, K1); \ + T1 = _mm256_unpacklo_epi64(K2, K3); \ + T2 = _mm256_unpackhi_epi64(K0, K1); \ + T3 = _mm256_unpackhi_epi64(K2, K3); \ + \ + K2 = _mm256_permutevar8x32_epi32(T1, M256(permMask)); \ + K1 = _mm256_permutevar8x32_epi32(T2, M256(permMask)); \ + K3 = _mm256_permutevar8x32_epi32(T3, M256(permMask)); \ + K0 = _mm256_permutevar8x32_epi32(T0, M256(permMask)) + +/* +// inp: K0, K1, K2, K3 +// out: T0, T1, T2, T3 +*/ +#define TRANSPOSE_OUT(T0,T1,T2,T3, K0,K1,K2,K3) \ + T0 = _mm256_unpacklo_epi32(K1, K0); \ + T1 = _mm256_unpacklo_epi32(K3, K2); \ + T2 = _mm256_unpackhi_epi32(K1, K0); \ + T3 = _mm256_unpackhi_epi32(K3, K2); \ + \ + K0 = _mm256_unpacklo_epi64(T1, T0); \ + K1 = _mm256_unpacklo_epi64(T3, T2); \ + K2 = _mm256_unpackhi_epi64(T1, T0); \ + K3 = _mm256_unpackhi_epi64(T3, T2); \ + \ + T0 = _mm256_permute2x128_si256(K0, K2, 0x20); \ + T1 = _mm256_permute2x128_si256(K1, K3, 0x20); \ + T2 = _mm256_permute2x128_si256(K0, K2, 0x31); \ + T3 = _mm256_permute2x128_si256(K1, K3, 0x31) + +#endif /* __SMS4_SBOX_L9_H_ */ + +#endif /* _IPP_G9, _IPP32E_L9 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ctr.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ctr.c new file mode 100644 index 000000000..b915ed5de --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ctr.c @@ -0,0 +1,187 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpProcessSMS4_ctr() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +/* +// SMS4-CTR processing. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pCtrValue ==NULL +// ippStsContextMatchErr !VALID_SMS4_ID() +// ippStsLengthErr len <1 +// ippStsCTRSizeErr 128 < ctrNumBitSize < 1 +// ippStsCTRSizeErr data blocks number > 2^ctrNumBitSize +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// dataLen input/output buffer length (in bytes) +// pCtx pointer to rge SMS4 context +// pCtrValue pointer to the counter block +// ctrNumBitSize counter block size (bits) +// +// Note: +// counter will updated on return +// +*/ +IPP_OWN_DEFN (IppStatus, cpProcessSMS4_ctr, (const Ipp8u* pSrc, Ipp8u* pDst, int dataLen, const IppsSMS4Spec* pCtx, Ipp8u* pCtrValue, int ctrNumBitSize)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_SMS4_ID(pCtx), ippStsContextMatchErr); + + /* test source, target and counter block pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pCtrValue); + /* test stream length */ + IPP_BADARG_RET((dataLen<1), ippStsLengthErr); + + /* test counter block size */ + IPP_BADARG_RET(((MBS_SMS4*8)= 8 * sizeof(int) - 5 + // function can process data with any possible + // passed dataLen without counter overflow + */ + + int dataBlocksNum = dataLen >> 4; + if(dataLen & 15){ + dataBlocksNum++; + } + + IPP_BADARG_RET(dataBlocksNum > (1 << ctrNumBitSize), ippStsCTRSizeErr); + } + + { + __ALIGN16 Ipp8u TMP[2*MBS_SMS4+1]; + + /* + maskIV size = MBS_SMS4 + output size = MBS_SMS4 + counter size = MBS_SMS4 + maskValue size = 1 + */ + + Ipp8u* output = TMP; + Ipp8u* counter = TMP + MBS_SMS4; + + /* copy counter */ + CopyBlock16(pCtrValue, counter); + + /* do CTR processing */ + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + + Ipp8u* maskIV = TMP; + /* output is not used together with maskIV, so this is why buffer for both values is the same */ + Ipp8u* maskValue = TMP + 2*MBS_SMS4; + + if(dataLen>=4*MBS_SMS4) { + /* construct ctr mask */ + int n; + int maskPosition = (MBS_SMS4*8-ctrNumBitSize)/8; + *maskValue = (Ipp8u)(0xFF >> (MBS_SMS4*8-ctrNumBitSize)%8 ); + + for(n=0; n=_IPP32E_K1) + #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + if (IsFeatureEnabled(ippCPUID_AVX512GFNI)) { + processedLen = cpSMS4_CTR_gfni512(pDst, pSrc, dataLen, SMS4_RK(pCtx), maskIV, counter); + } + else + #endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ + #endif /* (_IPP32E>=_IPP32E_K1) */ + if(IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)) { + processedLen = cpSMS4_CTR_aesni(pDst, pSrc, dataLen, SMS4_RK(pCtx), maskIV, counter); + } + + pSrc += processedLen; + pDst += processedLen; + dataLen -= processedLen; + + } + #endif + + { + + /* block-by-block processing */ + while(dataLen>= MBS_SMS4) { + /* encrypt counter block */ + cpSMS4_Cipher((Ipp8u*)output, (Ipp8u*)counter, SMS4_RK(pCtx)); + /* compute ciphertext block */ + XorBlock16(pSrc, output, pDst); + /* increment counter block */ + StdIncrement(counter,MBS_SMS4*8, ctrNumBitSize); + + pSrc += MBS_SMS4; + pDst += MBS_SMS4; + dataLen -= MBS_SMS4; + } + + /* last data block processing */ + if(dataLen) { + /* encrypt counter block */ + cpSMS4_Cipher((Ipp8u*)output, (Ipp8u*)counter, SMS4_RK(pCtx)); + /* compute ciphertext block */ + XorBlock(pSrc, output, pDst,dataLen); + /* increment counter block */ + StdIncrement((Ipp8u*)counter,MBS_SMS4*8, ctrNumBitSize); + } + + } + + /* update counter */ + CopyBlock16(counter, pCtrValue); + + /* clear secret data */ + PurgeBlock(TMP, sizeof(TMP)); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ofb8.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ofb8.c new file mode 100644 index 000000000..97bd924d4 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ofb8.c @@ -0,0 +1,81 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpProcessSMS4_ofb8() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" +#include "pcpsms4_process_ofb8.h" + +/* +// SMS4-OFB ecnryption/decryption +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// dataLen input/output buffer length (in bytes) +// ofbBlkSize ofb block size (in bytes) +// pCtx pointer to the AES context +// pIV pointer to the initialization vector +*/ +IPP_OWN_DEFN (void, cpProcessSMS4_ofb8, (const Ipp8u *pSrc, Ipp8u *pDst, int dataLen, int ofbBlkSize, const IppsSMS4Spec* pCtx, Ipp8u* pIV)) +{ + __ALIGN16 Ipp32u tmpInpOut[2*MBS_SMS4/sizeof(Ipp32u)]; + + CopyBlock16(pIV, tmpInpOut); + + while(dataLen>=ofbBlkSize) { + /* block-by-block processing */ + cpSMS4_Cipher((Ipp8u*)tmpInpOut+MBS_SMS4, (Ipp8u*)tmpInpOut, SMS4_RK(pCtx)); + + /* store output and shift inpBuffer for the next OFB operation */ + if(ofbBlkSize==MBS_SMS4) { + ((Ipp32u*)pDst)[0] = tmpInpOut[0+MBS_SMS4/sizeof(Ipp32u)]^((Ipp32u*)pSrc)[0]; + ((Ipp32u*)pDst)[1] = tmpInpOut[1+MBS_SMS4/sizeof(Ipp32u)]^((Ipp32u*)pSrc)[1]; + ((Ipp32u*)pDst)[2] = tmpInpOut[2+MBS_SMS4/sizeof(Ipp32u)]^((Ipp32u*)pSrc)[2]; + ((Ipp32u*)pDst)[3] = tmpInpOut[3+MBS_SMS4/sizeof(Ipp32u)]^((Ipp32u*)pSrc)[3]; + tmpInpOut[0] = tmpInpOut[0+MBS_SMS4/sizeof(Ipp32u)]; + tmpInpOut[1] = tmpInpOut[1+MBS_SMS4/sizeof(Ipp32u)]; + tmpInpOut[2] = tmpInpOut[2+MBS_SMS4/sizeof(Ipp32u)]; + tmpInpOut[3] = tmpInpOut[3+MBS_SMS4/sizeof(Ipp32u)]; + } + else { + XorBlock(pSrc, tmpInpOut+MBS_SMS4/sizeof(Ipp32u), pDst, ofbBlkSize); + CopyBlock16((Ipp8u*)tmpInpOut+ofbBlkSize, tmpInpOut); + } + + pSrc += ofbBlkSize; + pDst += ofbBlkSize; + dataLen -= ofbBlkSize; + } + + /* update pIV */ + CopyBlock16((Ipp8u*)tmpInpOut, pIV); + + /* clear secret data */ + PurgeBlock(tmpInpOut, sizeof(tmpInpOut)); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ofb8.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ofb8.h new file mode 100644 index 000000000..5b5a61579 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_process_ofb8.h @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// cpProcessSMS4_ofb8() +// +*/ + +#include "owncp.h" + +#if !defined _PCP_SMS4_PROCESS_OFB8_H +#define _PCP_SMS4_PROCESS_OFB8_H + +#define cpProcessSMS4_ofb8 OWNAPI(cpProcessSMS4_ofb8) + IPP_OWN_DECL (void, cpProcessSMS4_ofb8, (const Ipp8u *pSrc, Ipp8u *pDst, int dataLen, int ofbBlkSize, const IppsSMS4Spec* pCtx, Ipp8u* pIV)) + +#endif /* #if !defined _PCP_SMS4_PROCESS_OFB8_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4_y8cn.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_y8cn.h new file mode 100644 index 000000000..cb00754ab --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4_y8cn.h @@ -0,0 +1,161 @@ +/******************************************************************************* +* Copyright (C) 2019 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// affine() +// sBox() +// L() +// TRANSPOSE_INP() +// TRANSPOSE_OUT() +// +*/ + +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + +#ifndef __SMS4_SBOX_Y8_H_ +#define __SMS4_SBOX_Y8_H_ + +#include "owndefs.h" +#include "owncp.h" + +static __ALIGN16 Ipp8u inpMaskLO[] = {0x65,0x41,0xfd,0xd9,0x0a,0x2e,0x92,0xb6,0x0f,0x2b,0x97,0xb3,0x60,0x44,0xf8,0xdc}; +static __ALIGN16 Ipp8u inpMaskHI[] = {0x00,0xc9,0x67,0xae,0x80,0x49,0xe7,0x2e,0x4a,0x83,0x2d,0xe4,0xca,0x03,0xad,0x64}; +static __ALIGN16 Ipp8u outMaskLO[] = {0xd3,0x59,0x38,0xb2,0xcc,0x46,0x27,0xad,0x36,0xbc,0xdd,0x57,0x29,0xa3,0xc2,0x48}; +static __ALIGN16 Ipp8u outMaskHI[] = {0x00,0x50,0x14,0x44,0x89,0xd9,0x9d,0xcd,0xde,0x8e,0xca,0x9a,0x57,0x07,0x43,0x13}; + +static __ALIGN16 Ipp8u encKey[] = {0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63}; +static __ALIGN16 Ipp8u maskSrows[] = {0x00,0x0d,0x0a,0x07,0x04,0x01,0x0e,0x0b,0x08,0x05,0x02,0x0f,0x0c,0x09,0x06,0x03}; + +static __ALIGN16 Ipp8u lowBits4[] = {0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f}; + +static __ALIGN16 Ipp8u swapBytes[] = {3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12}; + +static __ALIGN16 Ipp8u affineIn[] = { 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34, 0x52,0xBC,0x2D,0x02,0x9E,0x25,0xAC,0x34 }; +static __ALIGN16 Ipp8u affineOut[] = { 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7, 0x19,0x8b,0x6c,0x1e,0x51,0x8e,0x2d,0xd7 }; + +#define M128(mem) (*((__m128i*)((Ipp8u*)(mem)))) + +/* +// +// AES and SMS4 ciphers both based on composite field GF(2^8). +// This affine transformation transforms 16 bytes +// from SMS4 representation to AES representation or vise versa +// depending on passed masks. +// +*/ + +__FORCEINLINE __m128i affine(__m128i x, __m128i maskLO, __m128i maskHI) +{ + __m128i T1 = _mm_and_si128(_mm_srli_epi64(x, 4), M128(lowBits4)); + __m128i T0 = _mm_and_si128(x, M128(lowBits4)); + T0 = _mm_shuffle_epi8(maskLO, T0); + T1 = _mm_shuffle_epi8(maskHI, T1); + return _mm_xor_si128(T0, T1); +} + +/* +// +// GF(256) is isomorfic. +// Encoding/decoding data of SM4 and AES are elements of GF(256). +// The difference in representation only. +// (It happend due to using different generating polynomials in SM4 and AES representations). +// Doing data conversion from SM4 to AES domain +// lets use AES specific intrinsics to perform less expensive SMS4 S-box computation. +// +// Original SMS4 S-box algorithm is converted to the following: +// +// - transform data from SMS4 representation to AES representation +// - compute S-box value using _mm_aesenclast_si128 with special key +// - re-shuffle data after _mm_aesenclast_si128 that shuffle it inside +// - transform data back from AES representation to SMS4 representation +// +*/ + +__FORCEINLINE __m128i sBox(__m128i block) +{ + block = affine(block, M128(inpMaskLO), M128(inpMaskHI)); + block = _mm_aesenclast_si128(block, M128(encKey)); + block = _mm_shuffle_epi8(block, M128(maskSrows)); + block = affine(block, M128(outMaskLO), M128(outMaskHI)); + + return block; +} + +#if (_IPP==_IPP_I0) || (_IPP32E==_IPP32E_N0) +__FORCEINLINE __m128i L(__m128i x) +{ + __m128i T = _mm_slli_epi32(x, 2); + T = _mm_xor_si128(T, _mm_srli_epi32(x, 30)); + + T = _mm_xor_si128(T, _mm_slli_epi32(x, 10)); + T = _mm_xor_si128(T, _mm_srli_epi32(x, 22)); + + T = _mm_xor_si128(T, _mm_slli_epi32(x, 18)); + T = _mm_xor_si128(T, _mm_srli_epi32(x, 14)); + + T = _mm_xor_si128(T, _mm_slli_epi32(x, 24)); + T = _mm_xor_si128(T, _mm_srli_epi32(x, 8)); + return T; +} +#else +static __ALIGN16 Ipp8u ROL8[] = { 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 }; +static __ALIGN16 Ipp8u ROL16[] = { 2,3,0,1, 6,7,4,5, 10,11,8,9, 14,15,12,13 }; +static __ALIGN16 Ipp8u ROL24[] = { 1,2,3,0, 5,6,7,4, 9,10,11,8, 13,14,15,12 }; + +__FORCEINLINE __m128i L(__m128i x) +{ + __m128i rol2 = _mm_xor_si128(_mm_slli_epi32(x, 2), _mm_srli_epi32(x, 30)); + __m128i rol24 = _mm_shuffle_epi8(x, M128(ROL24)); + __m128i rol10 = _mm_shuffle_epi8(rol2, M128(ROL8)); + __m128i rol18 = _mm_shuffle_epi8(rol2, M128(ROL16)); + __m128i R = _mm_xor_si128(rol24, _mm_xor_si128(rol18, _mm_xor_si128(rol2, rol10))); + return R; +} +#endif + +#define TRANSPOSE_INP(K0,K1,K2,K3, T) \ + T = _mm_unpacklo_epi32(K0, K1); \ + K1 = _mm_unpackhi_epi32(K0, K1); \ + K0 = _mm_unpacklo_epi32(K2, K3); \ + K3 = _mm_unpackhi_epi32(K2, K3); \ + \ + K2 = _mm_unpacklo_epi64(K1, K3); \ + K3 = _mm_unpackhi_epi64(K1, K3); \ + K1 = _mm_unpackhi_epi64(T, K0); \ + K0 = _mm_unpacklo_epi64(T, K0) + +#define TRANSPOSE_OUT(K0,K1,K2,K3, T) \ + T = _mm_unpacklo_epi32(K1, K0); \ + K0 = _mm_unpackhi_epi32(K1, K0); \ + K1 = _mm_unpacklo_epi32(K3, K2); \ + K3 = _mm_unpackhi_epi32(K3, K2); \ + \ + K2 = _mm_unpackhi_epi64(K1, T); \ + T = _mm_unpacklo_epi64(K1, T); \ + K1 = _mm_unpacklo_epi64(K3, K0); \ + K0 = _mm_unpackhi_epi64(K3, K0); \ + K3 = T + +#endif /* __SMS4_SBOX_Y8_H_ */ + +#endif /* _IPP_P8, _IPP32E_Y8 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4authccm.h b/plugin/ippcp/library/src/sources/ippcp/pcpsms4authccm.h new file mode 100644 index 000000000..f27c8f716 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4authccm.h @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (C) 2017 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Message Authentication Algorithm +// Internal Definitions and Internal Functions Prototypes +// +// +*/ + +#if !defined(_CP_SMS4_CCM_H) +#define _CP_SMS4_CCM_H + +#include "pcpsms4.h" + +struct _cpSMS4_CCM { + Ipp32u idCtx; /* CCM ID */ + + Ipp64u msgLen; /* length of message to be processed */ + Ipp64u lenProcessed; /* message length has been processed */ + Ipp32u tagLen; /* length of authentication tag */ + Ipp32u counterVal; /* currnt couter value */ + Ipp8u ctr0[MBS_SMS4]; /* counter value */ + Ipp8u s0[MBS_SMS4]; /* S0 = ENC(CTR0) content */ + Ipp8u si[MBS_SMS4]; /* Si = ENC(CTRi) content */ + Ipp8u blk[MBS_SMS4]; /* temporary data container */ + Ipp8u mac[MBS_SMS4]; /* current MAC value */ + + Ipp8u cipher[sizeof(IppsSMS4Spec)]; +}; + +/* alignment */ +#define SMS4CCM_ALIGNMENT ((int)(sizeof(void*))) + +/* +// access macros +*/ +#define SMS4CCM_SET_ID(stt) ((stt)->idCtx = (Ipp32u)idCtxAESCCM ^ (Ipp32u)IPP_UINT_PTR(stt)) +#define SMS4CCM_MSGLEN(stt) ((stt)->msgLen) +#define SMS4CCM_LENPRO(stt) ((stt)->lenProcessed) +#define SMS4CCM_TAGLEN(stt) ((stt)->tagLen) +#define SMS4CCM_COUNTER(stt) ((stt)->counterVal) +#define SMS4CCM_CTR0(stt) ((stt)->ctr0) +#define SMS4CCM_S0(stt) ((stt)->s0) +#define SMS4CCM_Si(stt) ((stt)->si) +#define SMS4CCM_BLK(stt) ((stt)->blk) +#define SMS4CCM_MAC(stt) ((stt)->mac) +#define SMS4CCM_CIPHER(stt) (IppsSMS4Spec*)(&((stt)->cipher)) + +/* valid context ID */ +#define VALID_SMS4CCM_ID(ctx) ((((ctx)->idCtx) ^ (Ipp32u)IPP_UINT_PTR((ctx))) == (Ipp32u)idCtxAESCCM) + +static int cpSizeofCtx_SMS4CCM(void) +{ + return sizeof(IppsSMS4_CCMState); +} + +/* Counter block formatter */ +static +Ipp8u* CounterEnc(Ipp32u* pBuffer, int fmt, Ipp64u counter) +{ + #if (IPP_ENDIAN == IPP_LITTLE_ENDIAN) + pBuffer[0] = ENDIANNESS(IPP_HIDWORD(counter)); + pBuffer[1] = ENDIANNESS(IPP_LODWORD(counter)); + #else + pBuffer[0] = IPP_HIDWORD(counter); + pBuffer[1] = IPP_LODWORD(counter); + #endif + return (Ipp8u*)pBuffer + 8 - fmt; +} + +#endif /* _CP_SMS4_CCM_H*/ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4cbcl9cn.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4cbcl9cn.c new file mode 100644 index 000000000..ded5ccff1 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4cbcl9cn.c @@ -0,0 +1,239 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 CBC decryption +// +// Contents: +// cpSMS4_CBC_dec_aesni() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" + +#if (_IPP>=_IPP_H9) || (_IPP32E>=_IPP32E_L9) + +#include "pcpsms4_l9cn.h" + +IPP_OWN_DEFN (int, cpSMS4_CBC_dec_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV)) +{ + __ALIGN16 __m256i TMP[17]; + /* + TMP[ 0] = T0 + TMP[ 1] = T1 + TMP[ 2] = T2 + TMP[ 3] = T3 + TMP[ 4] = K0 + TMP[ 5] = K1 + TMP[ 6] = K2 + TMP[ 7] = K3 + TMP[ 8] = P0 + TMP[ 9] = P1 + TMP[10] = P2 + TMP[11] = P3 + TMP[12] = Q0 + TMP[13] = Q1 + TMP[14] = Q2 + TMP[15] = Q3 + TMP[16] = IV + */ + + TMP[16] = _mm256_castsi128_si256(_mm_loadu_si128((__m128i*)(pIV))); + + int processedLen = len -(len % (24*MBS_SMS4)); + int n; + for(n=0; n=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + +#include "pcpsms4_y8cn.h" + +/* +// 4*MBS_SMS4 processing +*/ + +static int cpSMS4_CBC_dec_aesni_x4(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV) +{ + __ALIGN16 __m128i TMP[9]; + /* + TMP[0] = T + TMP[1] = T0 + TMP[2] = T1 + TMP[3] = T2 + TMP[4] = T3 + TMP[5] = K0 + TMP[6] = K1 + TMP[7] = K2 + TMP[8] = K3 + */ + TMP[1] = _mm_loadu_si128((__m128i*)(pIV)); + + int processedLen = len & -(4*MBS_SMS4); + int n; + for(n=0; n=_IPP_H9) || (_IPP32E>=_IPP32E_L9) +IPP_OWN_DEFN (int, cpSMS4_CBC_dec_aesni_x12, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV)) +#else +IPP_OWN_DEFN (int, cpSMS4_CBC_dec_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, Ipp8u* pIV)) +#endif +{ + __ALIGN16 __m128i TMP[19]; + /* + TMP[ 0] = T + TMP[ 1] = U + TMP[ 2] = V + TMP[ 3] = T0 + TMP[ 4] = T1 + TMP[ 5] = T2 + TMP[ 6] = T3 + TMP[ 7] = K0 + TMP[ 8] = K1 + TMP[ 9] = K2 + TMP[10] = K3 + TMP[11] = P0 + TMP[12] = P1 + TMP[13] = P2 + TMP[14] = P3 + TMP[15] = Q0 + TMP[16] = Q1 + TMP[17] = Q2 + TMP[18] = Q3 + */ + TMP[3] = _mm_loadu_si128((__m128i*)(pIV)); + + int processedLen = len -(len % (12*MBS_SMS4)); + int n; + for(n=0; n=_IPP_H9) || (_IPP32E>=_IPP32E_L9) + +#include "pcpsms4_l9cn.h" + +static __ALIGN32 Ipp8u endiannes_swap[] = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3, + 12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3}; + +static __ALIGN32 Ipp8u endiannes[] = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0, + 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; + +static __ALIGN32 Ipp8u two256[] = {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +static __ALIGN16 Ipp8u one256[] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +__INLINE __m128i inc128(__m128i x) +{ + __m128i t = _mm_add_epi64(x, M128(one256)); + x = _mm_cmpeq_epi64(t, _mm_setzero_si128()); + t = _mm_sub_epi64(t, _mm_slli_si128(x, sizeof(Ipp64u))); + return t; +} + +__INLINE __m256i inc256(__m256i x) +{ + __m256i t = _mm256_add_epi64(x, M256(two256)); + x = _mm256_cmpeq_epi64(t, _mm256_setzero_si256()); + t = _mm256_sub_epi64(t, _mm256_slli_si256(x, sizeof(Ipp64u))); + return t; +} +__INLINE __m256i inc256_2(__m256i x) +{ + __m256i t = _mm256_add_epi64(x, M256(one256)); + x = _mm256_cmpeq_epi64(t, _mm256_setzero_si256()); + t = _mm256_sub_epi64(t, _mm256_slli_si256(x, sizeof(Ipp64u))); + + t = _mm256_add_epi64(t, M256(one256)); + x = _mm256_cmpeq_epi64(t, _mm256_setzero_si256()); + t = _mm256_sub_epi64(t, _mm256_slli_si256(x, sizeof(Ipp64u))); + return t; +} + +IPP_OWN_DEFN (int, cpSMS4_CTR_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr)) +{ + int processedLen = len & -(16*MBS_SMS4); + + if(processedLen) { + int n; + + __ALIGN16 __m256i TMP[16]; + /* + TMP[ 0] = T0 + TMP[ 1] = T1 + TMP[ 2] = T2 + TMP[ 3] = T3 + TMP[ 4] = K0 + TMP[ 5] = K1 + TMP[ 6] = K2 + TMP[ 7] = K3 + TMP[ 8] = P0 + TMP[ 9] = P1 + TMP[10] = P2 + TMP[11] = P3 + TMP[12] = ctr + TMP[13] = mask + TMP[14] = unch + */ + + /* read string counter and convert to numerical */ + TMP[12] = _mm256_shuffle_epi8(_mm256_castsi128_si256(_mm_loadu_si128((__m128i*)pCtr)), M256(endiannes)); + + /* read string mask and convert to numerical */ + TMP[13] = _mm256_shuffle_epi8(_mm256_castsi128_si256(_mm_loadu_si128((__m128i*)pCtrMask)), M256(endiannes)); + + /* upchanged counter bits */ + TMP[14] = _mm256_andnot_si256(TMP[13], TMP[12]); + + TMP[12] = _mm256_inserti128_si256(TMP[12], inc128(_mm256_castsi256_si128(TMP[12])), 1); + TMP[13]= _mm256_inserti128_si256(TMP[13], _mm256_castsi256_si128(TMP[13]), 1); + TMP[14]= _mm256_inserti128_si256(TMP[14], _mm256_castsi256_si128(TMP[14]), 1); + TMP[12] = _mm256_and_si256(TMP[12], TMP[13]); + + for(n=0; n=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + +#include "pcpsms4_y8cn.h" + +static __ALIGN16 Ipp8u one128[] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +static __ALIGN16 Ipp8u endiannes[] = {15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0}; +static __ALIGN16 Ipp8u endiannes_swap[] = {12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3}; + +__INLINE __m128i inc128(__m128i x) +{ + __m128i t = _mm_add_epi64(x, M128(one128)); + x = _mm_cmpeq_epi64(t, _mm_setzero_si128()); + t = _mm_sub_epi64(t, _mm_slli_si128(x, sizeof(Ipp64u))); + return t; +} + +#if (_IPP>=_IPP_H9) || (_IPP32E>=_IPP32E_L9) +IPP_OWN_DEFN (int, cpSMS4_CTR_aesni_x4, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr)) +#else +IPP_OWN_DEFN (int, cpSMS4_CTR_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey, const Ipp8u* pCtrMask, Ipp8u* pCtr)) +#endif +{ + __ALIGN16 __m128i TMP[8]; + /* + TMP[ 0] = T + TMP[ 1] = K0 + TMP[ 2] = K1 + TMP[ 3] = K2 + TMP[ 4] = K3 + TMP[ 5] = ctrUnchanged + TMP[ 6] = ctrMask + TMP[ 7] = ctr + */ + + int processedLen = len & -(4*MBS_SMS4); + int n; + + TMP[6] = _mm_loadu_si128((__m128i*)pCtrMask); + TMP[7] = _mm_loadu_si128((__m128i*)pCtr); + + TMP[6] = _mm_shuffle_epi8(TMP[6], M128(endiannes)); + TMP[7] = _mm_shuffle_epi8(TMP[7], M128(endiannes)); + TMP[5] = _mm_andnot_si128(TMP[6], TMP[7]); + + for(n=0; ncfbBlkSize || cfbBlkSize>MBS_SMS4) +// ippStsUnderRunErr 0!=(len%cfbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// cfbBlkSize CFB block size (in bytes) +// pCtx pointer to the SMS4 context +// pIV pointer to the initialization vector +// +*F*/ +static +void cpDecryptSMS4_cfb(const Ipp8u* pIV, + const Ipp8u* pSrc, Ipp8u* pDst, int nBlocks, int cfbBlkSize, + const IppsSMS4Spec* pCtx) +{ + __ALIGN16 Ipp32u TMP[3*MBS_SMS4/sizeof(Ipp32u)]; + + /* + tmpInp size = 2*MBS_SMS4/sizeof(Ipp32u) + tmpOut size = MBS_SMS4/sizeof(Ipp32u) + */ + + Ipp32u* tmpInp = TMP; + Ipp32u* tmpOut = TMP + 2*MBS_SMS4/sizeof(Ipp32u); + + /* read IV */ + CopyBlock16(pIV, tmpInp); + + /* decrypt data block-by-block of cfbLen each */ + while(nBlocks) { + /* decryption */ + cpSMS4_Cipher((Ipp8u*)tmpOut, (Ipp8u*)tmpInp, SMS4_RK(pCtx)); + + /* store output and put feedback into the input buffer (tmpInp) */ + if( cfbBlkSize==MBS_SMS4 && pSrc!=pDst) { + ((Ipp32u*)pDst)[0] = tmpOut[0]^((Ipp32u*)pSrc)[0]; + ((Ipp32u*)pDst)[1] = tmpOut[1]^((Ipp32u*)pSrc)[1]; + ((Ipp32u*)pDst)[2] = tmpOut[2]^((Ipp32u*)pSrc)[2]; + ((Ipp32u*)pDst)[3] = tmpOut[3]^((Ipp32u*)pSrc)[3]; + + tmpInp[0] = ((Ipp32u*)pSrc)[0]; + tmpInp[1] = ((Ipp32u*)pSrc)[1]; + tmpInp[2] = ((Ipp32u*)pSrc)[2]; + tmpInp[3] = ((Ipp32u*)pSrc)[3]; + } + else { + int n; + for(n=0; ncfbBlkSize) || (MBS_SMS4=_IPP32E_K1) + #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + if (IsFeatureEnabled(ippCPUID_AVX512GFNI)) { + + __ALIGN16 Ipp8u IV[MBS_SMS4]; + CopyBlock16(pIV, IV); + + if(len/cfbBlkSize >= 4) + { + cpSMS4_CFB_dec_gfni512(pDst, pSrc, len, cfbBlkSize, (Ipp32u*)SMS4_RK(pCtx), IV); /* pipeline */ + + int processedLen = len - (len % (4*cfbBlkSize)); + pSrc += processedLen; + pDst += processedLen; + len = len - processedLen; + } + if(len) + { + cpDecryptSMS4_cfb(IV, pSrc, pDst, len/cfbBlkSize, cfbBlkSize, pCtx); /* tail */ + } + } + else + #endif + #endif + { + cpDecryptSMS4_cfb(pIV, pSrc, pDst, len/cfbBlkSize, cfbBlkSize, pCtx); + } + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptctr.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptctr.c new file mode 100644 index 000000000..56808aff6 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptctr.c @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// ippsSMS4DecryptCTR() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4DecryptCTR +// +// Purpose: SMS4-CRT encryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pCtrValue ==NULL +// ippStsContextMatchErr !VALID_SMS4_ID() +// ippStsLengthErr len <1 +// ippStsCTRSizeErr 128 < ctrNumBitSize < 1 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// pCtx pointer to rge SMS4 context +// pCtrValue pointer to the counter block +// ctrNumBitSize counter block size (bits) +// +// Note: +// counter will updated on return +// +*F*/ + +IPPFUN(IppStatus, ippsSMS4DecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx, + Ipp8u* pCtrValue, int ctrNumBitSize)) +{ + return cpProcessSMS4_ctr(pSrc, pDst, len, pCtx, pCtrValue, ctrNumBitSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptecb.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptecb.c new file mode 100644 index 000000000..ed3b1d839 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptecb.c @@ -0,0 +1,95 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// ippsSMS4DecryptECB() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +/*F* +// Name: ippsSMS4DecryptECB +// +// Purpose: SMS4-ECB decryption. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr !VALID_SMS4_ID() +// ippStsLengthErr len <1 +// ippStsUnderRunErr 0!=(len%MBS_SMS4) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// pCtx pointer to the SMS4 context +// +*F*/ +IPPFUN(IppStatus, ippsSMS4DecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsSMS4Spec* pCtx)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_SMS4_ID(pCtx), ippStsContextMatchErr); + + /* test source and target buffer pointers */ + IPP_BAD_PTR2_RET(pSrc, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test stream integrity */ + IPP_BADARG_RET((len&(MBS_SMS4-1)), ippStsUnderRunErr); + + /* do encryption */ + #if (_IPP32E>=_IPP32E_K1) + #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + if (IsFeatureEnabled(ippCPUID_AVX512GFNI)) { + int processedLen = cpSMS4_ECB_gfni512(pDst, pSrc, len, SMS4_DRK(pCtx)); + pSrc += processedLen; + pDst += processedLen; + len -= processedLen; + } + else + #endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920)) */ + #endif /* (_IPP32E>=_IPP32E_K1) */ + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)) { + int processedLen = cpSMS4_ECB_aesni(pDst, pSrc, len, SMS4_DRK(pCtx)); + pSrc += processedLen; + pDst += processedLen; + len -= processedLen; + } + else + #endif + + for(; len>0; len-=MBS_SMS4, pSrc+=MBS_SMS4, pDst+=MBS_SMS4) + cpSMS4_Cipher(pDst, pSrc, SMS4_DRK(pCtx)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptofb.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptofb.c new file mode 100644 index 000000000..e68e667ac --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4decryptofb.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// ippsSMS4DecryptOFB() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" +#include "pcpsms4_process_ofb8.h" + +/*F* +// Name: ippsSMS4DecryptOFB +// +// Purpose: Decrypts byte data stream according to SMS4 in OFB mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_SMS4_ID() +// ippStsLengthErr len <1 +// ippStsOFBSizeErr (1>ofbBlkSize || ofbBlkSize>MBS_SMS4) +// ippStsUnderRunErr (len%ofbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// ofbBlkSize OFB block size (in bytes) +// pCtx pointer to the SMS4 context +// pIV pointer to the initialization vector +*F*/ +IPPFUN(IppStatus, ippsSMS4DecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsSMS4Spec* pCtx, + Ipp8u* pIV)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_SMS4_ID(pCtx), ippStsContextMatchErr); + + /* test source, target buffers and initialization pointers */ + IPP_BAD_PTR3_RET(pSrc, pIV, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test OFB value */ + IPP_BADARG_RET(((1>ofbBlkSize) || (MBS_SMS4=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + +#include "pcpsms4_y8cn.h" + +/* +// (1-3)*MBS_SMS4 processing +*/ + +static int cpSMS4_ECB_aesni_tail(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey) +{ + __ALIGN16 __m128i TMP[6]; + /* + TMP[0] = T + TMP[1] = K0 + TMP[2] = K1 + TMP[3] = K2 + TMP[4] = K3 + TMP[5] = key4 + */ + + TMP[2] = _mm_setzero_si128(); + TMP[3] = _mm_setzero_si128(); + TMP[4] = _mm_setzero_si128(); + + switch (len) { + case (3*MBS_SMS4): + TMP[3] = _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)(pInp+2*MBS_SMS4)), M128(swapBytes)); + case (2*MBS_SMS4): + TMP[2] = _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)(pInp+1*MBS_SMS4)), M128(swapBytes)); + case (1*MBS_SMS4): + TMP[1] = _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)(pInp+0*MBS_SMS4)), M128(swapBytes)); + break; + default: return 0; + } + TRANSPOSE_INP(TMP[1],TMP[2],TMP[3],TMP[4], TMP[0]); + + { + int itr; + for(itr=0; itr<8; itr++, pRKey+=4) { + TMP[5] = _mm_loadu_si128((__m128i*)pRKey); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0x00); /* broadcast(key4 TMP[0]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[1] = _mm_xor_si128(_mm_xor_si128(TMP[1], TMP[0]), L(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0x55); /* broadcast(key4 TMP[1]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[2] = _mm_xor_si128(_mm_xor_si128(TMP[2], TMP[0]), L(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0xAA); /* broadcast(key4 TMP[2]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[3] = _mm_xor_si128(_mm_xor_si128(TMP[3], TMP[0]), L(TMP[0])); + + /* initial xors */ + TMP[0] = _mm_shuffle_epi32(TMP[5], 0xFF); /* broadcast(key4 TMP[3]) */ + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now L */ + TMP[4] = _mm_xor_si128(_mm_xor_si128(TMP[4], TMP[0]), L(TMP[0])); + } + } + + TRANSPOSE_OUT(TMP[1],TMP[2],TMP[3],TMP[4], TMP[0]); + TMP[4] = _mm_shuffle_epi8(TMP[4], M128(swapBytes)); + TMP[3] = _mm_shuffle_epi8(TMP[3], M128(swapBytes)); + TMP[2] = _mm_shuffle_epi8(TMP[2], M128(swapBytes)); + TMP[1] = _mm_shuffle_epi8(TMP[1], M128(swapBytes)); + + switch (len) { + case (3*MBS_SMS4): + _mm_storeu_si128((__m128i*)(pOut+2*MBS_SMS4), TMP[2]); + case (2*MBS_SMS4): + _mm_storeu_si128((__m128i*)(pOut+1*MBS_SMS4), TMP[3]); + case (1*MBS_SMS4): + _mm_storeu_si128((__m128i*)(pOut+0*MBS_SMS4), TMP[4]); + break; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm_xor_si128(TMP[i],TMP[i]); + } + + return len; +} + +/* +// 4*MBS_SMS4 processing +*/ +static +int cpSMS4_ECB_aesni_x4(Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey) +{ + __ALIGN16 __m128i TMP[5]; + /* + TMP[0] = T + TMP[1] = K0 + TMP[2] = K1 + TMP[3] = K2 + TMP[4] = K3 + */ + int processedLen = len & -(4*MBS_SMS4); + int n; + for(n=0; n=_IPP_H9) || (_IPP32E>=_IPP32E_L9) +#define cpSMS4_ECB_aesni_x12 OWNAPI(cpSMS4_ECB_aesni_x12) + IPP_OWN_DECL (int, cpSMS4_ECB_aesni_x12, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) + IPP_OWN_DEFN (int, cpSMS4_ECB_aesni_x12, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) +#else +#define cpSMS4_ECB_aesni OWNAPI(cpSMS4_ECB_aesni) + IPP_OWN_DECL (int, cpSMS4_ECB_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) + IPP_OWN_DEFN (int, cpSMS4_ECB_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) +#endif +{ + __ALIGN16 __m128i TMP[15]; + /* + TMP[ 0] = T + TMP[ 1] = U + TMP[ 2] = V + TMP[ 3] = K0 + TMP[ 4] = K1 + TMP[ 5] = K2 + TMP[ 6] = K3 + TMP[ 7] = P0 + TMP[ 8] = P1 + TMP[ 9] = P2 + TMP[10] = P3 + TMP[11] = Q0 + TMP[12] = Q1 + TMP[13] = Q2 + TMP[14] = Q3 + */ + + int processedLen = len -(len % (12*MBS_SMS4)); + int n; + for(n=0; n=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + +#include "pcpsms4_y8cn.h" + +__INLINE __m128i Ltag(__m128i x) +{ + __m128i T = _mm_slli_epi32(x, 13); + T = _mm_xor_si128(T, _mm_srli_epi32 (x,19)); + T = _mm_xor_si128(T, _mm_slli_epi32 (x,23)); + T = _mm_xor_si128(T, _mm_srli_epi32 (x, 9)); + return T; +} + +/* +// compute round keys +*/ + +#define cpSMS4_SetRoundKeys_aesni OWNAPI(cpSMS4_SetRoundKeys_aesni) + IPP_OWN_DECL (void, cpSMS4_SetRoundKeys_aesni, (Ipp32u* pRoundKey, const Ipp8u* pSecretKey)) + +IPP_OWN_DEFN (void, cpSMS4_SetRoundKeys_aesni, (Ipp32u* pRoundKey, const Ipp8u* pSecretKey)) +{ + __ALIGN16 __m128i TMP[5]; + /* + TMP[0] = T + TMP[1] = K0 + TMP[2] = K1 + TMP[3] = K2 + TMP[4] = K3 + */ + TMP[1] = _mm_cvtsi32_si128((Ipp32s)(ENDIANNESS32(((Ipp32u*)pSecretKey)[0]) ^ SMS4_FK[0])); + TMP[2] = _mm_cvtsi32_si128((Ipp32s)(ENDIANNESS32(((Ipp32u*)pSecretKey)[1]) ^ SMS4_FK[1])); + TMP[3] = _mm_cvtsi32_si128((Ipp32s)(ENDIANNESS32(((Ipp32u*)pSecretKey)[2]) ^ SMS4_FK[2])); + TMP[4] = _mm_cvtsi32_si128((Ipp32s)(ENDIANNESS32(((Ipp32u*)pSecretKey)[3]) ^ SMS4_FK[3])); + + const Ipp32u* pCK = SMS4_CK; + + int itr; + for(itr=0; itr<8; itr++) { + /* initial xors */ + TMP[0] = _mm_cvtsi32_si128((Ipp32s)pCK[0]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now Ltag */ + TMP[1] = _mm_xor_si128(_mm_xor_si128(TMP[1], TMP[0]), Ltag(TMP[0])); + pRoundKey[0] = (Ipp32u)_mm_cvtsi128_si32(TMP[1]); + + /* initial xors */ + TMP[0] = _mm_cvtsi32_si128((Ipp32s)pCK[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now Ltag */ + TMP[2] = _mm_xor_si128(_mm_xor_si128(TMP[2], TMP[0]), Ltag(TMP[0])); + pRoundKey[1] = (Ipp32u)_mm_cvtsi128_si32(TMP[2]); + + /* initial xors */ + TMP[0] = _mm_cvtsi32_si128((Ipp32s)pCK[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[4]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now Ltag */ + TMP[3] = _mm_xor_si128(_mm_xor_si128(TMP[3], TMP[0]), Ltag(TMP[0])); + pRoundKey[2] = (Ipp32u)_mm_cvtsi128_si32(TMP[3]); + + /* initial xors */ + TMP[0] = _mm_cvtsi32_si128((Ipp32s)pCK[3]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[1]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[2]); + TMP[0] = _mm_xor_si128(TMP[0], TMP[3]); + /* Sbox */ + TMP[0] = sBox(TMP[0]); + /* Sbox done, now Ltag */ + TMP[4] = _mm_xor_si128(_mm_xor_si128(TMP[4], TMP[0]), Ltag(TMP[0])); + pRoundKey[3] = (Ipp32u)_mm_cvtsi128_si32(TMP[4]); + + pCK += 4; + pRoundKey += 4; + } + + /* clear secret data */ + for(Ipp32u i = 0; i < sizeof(TMP)/sizeof(TMP[0]); i++){ + TMP[i] = _mm_xor_si128(TMP[i],TMP[i]); + } +} + +#endif /* _IPP_P8, _IPP32E_Y8 */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4ecbl9cn.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4ecbl9cn.c new file mode 100644 index 000000000..6314ba8af --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4ecbl9cn.c @@ -0,0 +1,223 @@ +/******************************************************************************* +* Copyright (C) 2014 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 ECB decryption +// +// Contents: +// cpSMS4_ECB_aesni() +// +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" + +#if (_IPP>=_IPP_H9) || (_IPP32E>=_IPP32E_L9) + +#include "pcpsms4_l9cn.h" + +IPP_OWN_DEFN (int, cpSMS4_ECB_aesni, (Ipp8u* pOut, const Ipp8u* pInp, int len, const Ipp32u* pRKey)) +{ + __ALIGN16 __m256i TMP[16]; + /* + TMP[ 0] = T0 + TMP[ 1] = T1 + TMP[ 2] = T2 + TMP[ 3] = T3 + TMP[ 4] = K0 + TMP[ 5] = K1 + TMP[ 6] = K2 + TMP[ 7] = K3 + TMP[ 8] = P0 + TMP[ 9] = P1 + TMP[10] = P2 + TMP[11] = P3 + TMP[12] = Q0 + TMP[13] = Q1 + TMP[14] = Q2 + TMP[15] = Q3 + */ + + int processedLen = len -(len % (24*MBS_SMS4)); + int n; + for(n=0; ncfbBlkSize || cfbBlkSize>MBS_SMS4) +// ippStsUnderRunErr 0!=(len%cfbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// cfbBlkSize CFB block size (in bytes) +// pCtx pointer to the SMS4 context +// pIV pointer to the initialization vector +// +*F*/ +IPPFUN(IppStatus, ippsSMS4EncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsSMS4Spec* pCtx, + const Ipp8u* pIV)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_SMS4_ID(pCtx), ippStsContextMatchErr); + + /* test source, target buffers and initialization pointers */ + IPP_BAD_PTR3_RET(pSrc, pIV, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test CFB value */ + IPP_BADARG_RET(((1>cfbBlkSize) || (MBS_SMS4=cfbBlkSize) { + int n; + + /* encryption */ + cpSMS4_Cipher((Ipp8u*)tmpOut, (Ipp8u*)tmpInp, SMS4_RK(pCtx)); + + /* store output and put feedback into the input buffer (tmpInp) */ + if( cfbBlkSize==MBS_SMS4 && pSrc!=pDst) { + tmpInp[0] = ((Ipp32u*)pDst)[0] = tmpOut[0]^((Ipp32u*)pSrc)[0]; + tmpInp[1] = ((Ipp32u*)pDst)[1] = tmpOut[1]^((Ipp32u*)pSrc)[1]; + tmpInp[2] = ((Ipp32u*)pDst)[2] = tmpOut[2]^((Ipp32u*)pSrc)[2]; + tmpInp[3] = ((Ipp32u*)pDst)[3] = tmpOut[3]^((Ipp32u*)pSrc)[3]; + } + else { + for(n=0; n=_IPP32E_K1) + #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) + if (IsFeatureEnabled(ippCPUID_AVX512GFNI)) { + int processedLen = cpSMS4_ECB_gfni512(pDst, pSrc, len, SMS4_ERK(pCtx)); + pSrc += processedLen; + pDst += processedLen; + len -= processedLen; + } + else + #endif /* #if defined (__INTEL_COMPILER) || defined (__INTEL_LLVM_COMPILER) || !defined (_MSC_VER) || (_MSC_VER >= 1920) */ + #endif /* (_IPP32E>=_IPP32E_K1) */ + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)) { + int processedLen = cpSMS4_ECB_aesni(pDst, pSrc, len, SMS4_ERK(pCtx)); + pSrc += processedLen; + pDst += processedLen; + len -= processedLen; + } + else + #endif + + for(; len>0; len-=MBS_SMS4, pSrc+=MBS_SMS4, pDst+=MBS_SMS4) + cpSMS4_Cipher(pDst, pSrc, SMS4_RK(pCtx)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpsms4encryptofb.c b/plugin/ippcp/library/src/sources/ippcp/pcpsms4encryptofb.c new file mode 100644 index 000000000..28c4f1e1a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpsms4encryptofb.c @@ -0,0 +1,78 @@ +/******************************************************************************* +* Copyright (C) 2013 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SMS4 encryption/decryption +// +// Contents: +// ippsSMS4EncryptOFB() +// +*/ + +#include "owncp.h" +#include "pcpsms4.h" +#include "pcptool.h" +#include "pcpsms4_process_ofb8.h" + +/*F* +// Name: ippsSMS4EncryptOFB +// +// Purpose: Encrypts byte data stream according to SMS4 in OFB mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx == NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr !VALID_SMS4_ID() +// ippStsLengthErr len <1 +// ippStsOFBSizeErr (1>ofbBlkSize || ofbBlkSize>MBS_SMS4) +// ippStsUnderRunErr (len%ofbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data buffer +// pDst pointer to the target data buffer +// len input/output buffer length (in bytes) +// ofbBlkSize OFB block size (in bytes) +// pCtx pointer to the SMS4 context +// pIV pointer to the initialization vector +*F*/ +IPPFUN(IppStatus, ippsSMS4EncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsSMS4Spec* pCtx, + Ipp8u* pIV)) +{ + /* test context */ + IPP_BAD_PTR1_RET(pCtx); + /* test the context ID */ + IPP_BADARG_RET(!VALID_SMS4_ID(pCtx), ippStsContextMatchErr); + + /* test source, target buffers and initialization pointers */ + IPP_BAD_PTR3_RET(pSrc, pIV, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test OFB value */ + IPP_BADARG_RET(((1>ofbBlkSize) || (MBS_SMS4=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + if(IsFeatureEnabled(ippCPUID_AES) || IsFeatureEnabled(ippCPUID_AVX2VAES)) + cpSMS4_SetRoundKeys_aesni(SMS4_RK(pCtx), pSecretKey); + else + #endif + cpSMS4_SetRoundKeys(SMS4_RK(pCtx), pSecretKey); + + /* set deccryption round keys */ + { + int n; + for(n=0; n < SMS4_ROUND_KEYS_NUM; n++) { + SMS4_DRK(pCtx)[n] = SMS4_RK(pCtx)[SMS4_ROUND_KEYS_NUM - n-1]; + } + } + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcptdesctrca.c b/plugin/ippcp/library/src/sources/ippcp/pcptdesctrca.c new file mode 100644 index 000000000..98eab5cbd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcptdesctrca.c @@ -0,0 +1,180 @@ +/******************************************************************************* +* Copyright (C) 2004 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Encrypt/Decrypt byte data stream according to TDES (CTR mode) +// +// Contents: +// ippsTDESEncryptCTR() +// ippsTDESDecryptCTR() +// +// +*/ + +#include "owndefs.h" + +#include "owncp.h" +#include "pcpdes.h" +#include "pcptool.h" + +static +IppStatus TDES_CTR(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pCtrValue, int ctrNumBitSize) +{ + Ipp64u counter; + Ipp64u output; + + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + /* test source, target and counter block pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pCtrValue); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test counter block size */ + IPP_BADARG_RET(((MBS_DES*8)= MBS_DES) { + /* encrypt counter block */ + output = Cipher_DES(counter, DES_EKEYS(pCtx1), DESspbox); + output = Cipher_DES(output, DES_DKEYS(pCtx2), DESspbox); + output = Cipher_DES(output, DES_EKEYS(pCtx3), DESspbox); + /* compute ciphertext block */ + XorBlock8(pSrc, &output, pDst); + /* encrement counter block */ + StdIncrement((Ipp8u*)&counter,MBS_DES*8, ctrNumBitSize); + + pSrc += MBS_DES; + pDst += MBS_DES; + len -= MBS_DES; + } + /* + // encrypt last data block + */ + if(len) { + /* encrypt counter block */ + output = Cipher_DES(counter, DES_EKEYS(pCtx1), DESspbox); + output = Cipher_DES(output, DES_DKEYS(pCtx2), DESspbox); + output = Cipher_DES(output, DES_EKEYS(pCtx3), DESspbox); + /* compute ciphertext block */ + XorBlock(pSrc, &output, pDst,len); + /* encrement counter block */ + StdIncrement((Ipp8u*)&counter,MBS_DES*8, ctrNumBitSize); + } + + /* update counter */ + CopyBlock8(&counter, pCtrValue); + + return ippStsNoErr; +} + +/*F* +// Name: ippsTDESEncryptCTR +// +// Purpose: Encrypt byte data stream according to TDES in CTR mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx1 == NULL +// pCtx2 == NULL +// pCtx3 == NULL +// pSrc == NULL +// pDst == NULL +// pCtrValue ==NULL +// ippStsContextMatchErr pCtx1->idCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr len <1 +// ippStsCTRSizeErr 64 < ctrNumBitSize < 1 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data stream +// pDst pointer to the target data stream +// len plaintext stream length (bytes) +// pCtx1-pCtx3 DES contexts +// pCtrValue pointer to the counter block +// ctrNumBitSize counter block size (bits) +// +// Note: +// counter will updated on return +// +*F*/ + +IPPFUN(IppStatus, ippsTDESEncryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pCtrValue, int ctrNumBitSize)) +{ + return TDES_CTR(pSrc,pDst,len, pCtx1,pCtx2,pCtx3, pCtrValue,ctrNumBitSize); +} + +/*F* +// Name: ippsTDESDecryptCTR +// +// Purpose: Decrypt byte data stream according to TDES in CTR mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx1 == NULL +// pCtx2 == NULL +// pCtx3 == NULL +// pSrc == NULL +// pDst == NULL +// pCtrValue ==NULL +// ippStsContextMatchErr pCtx1->idCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr len <1 +// ippStsCTRSizeErr 64 < ctrNumBitSize < 1 +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data stream +// pDst pointer to the target data stream +// len plaintext stream length (bytes) +// pCtx1-pCtx3 DES contexts +// pCtrValue pointer to the counter block +// ctrNumBitSize counter block size (bits) +// +// Note: +// counter will updated on return +// +*F*/ + +IPPFUN(IppStatus, ippsTDESDecryptCTR,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pCtrValue, int ctrNumBitSize)) +{ + return TDES_CTR(pSrc,pDst,len, pCtx1,pCtx2,pCtx3, pCtrValue,ctrNumBitSize); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcptdesdecryptcbcca.c b/plugin/ippcp/library/src/sources/ippcp/pcptdesdecryptcbcca.c new file mode 100644 index 000000000..3ae32426e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcptdesdecryptcbcca.c @@ -0,0 +1,129 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Decrypt byte data stream according to TDES (CBC mode) +// +// Contents: +// ippsTDESDecryptCBC() +// +// +*/ + +#include "owndefs.h" + +#include "owncp.h" +#include "pcpdes.h" +#include "pcptool.h" + + +/*F* +// Name: ippsTDESDecryptCBC +// +// Purpose: Decrypt byte data stream according to TDES in CBC mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx1 == NULL +// pCtx2 == NULL +// pCtx3 == NULL +// pSrc == NULL +// pDst == NULL +// ippStsContextMatchErr pCtx1->idCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr length <1 +// ippStsUnderRunErr (length&7) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data stream +// pDst pointer to the target byte data stream +// length plaintext stream length (bytes) +// pCtx1-3 pointers to the DES context +// pIV pointer to the init vector +// padding the padding scheme indicator +// +*F*/ +IPPFUN(IppStatus, ippsTDESDecryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsPadding padding)) +{ + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + /* test source and destination pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pIV); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + + /* force ippPaddingNONE padding */ + if(ippPaddingNONE!=padding) + padding = ippPaddingNONE; + /* test stream integrity */ + //IPP_BADARG_RET(((length&7) && (ippPaddingNONE==padding)), ippStsUnderRunErr); + IPP_BADARG_RET((len&7), ippStsUnderRunErr); + + { + int nBlocks = len/MBS_DES; + + /* read IV */ + Ipp64u iv; + CopyBlock8(pIV, &iv); + + /* misaligned source and/or target */ + /*if( (IPP_UINT_PTR(pSrc) & 0x7) || (IPP_UINT_PTR(pDst) & 0x7) ) {*/ + if( (IPP_UINT_PTR(pSrc) & 0x7) || (IPP_UINT_PTR(pDst) & 0x7) || pSrc==pDst) { + int n; + for(n=0; nidCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr len <1 +// ippStsCFBSizeErr (1>cfbBlkSize || cfbBlkSize>MBS_DES) +// ippStsUnderRunErr (len%cfbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data stream +// pDst pointer to the target byte data stream +// len plaintext stream length (bytes) +// cfbBlkSize CFB block size (bytes) +// pCtx1-3 pointers to the DES context +// pIV pointer to the init vector +// padding the padding scheme indicator +// +*F*/ +IPPFUN(IppStatus, ippsTDESDecryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsPadding padding)) +{ + Ipp64u inpBuffer[2]; + Ipp64u outBuffer; + + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + /* test source and destination pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pIV); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test CFB value */ + IPP_BADARG_RET(((1>cfbBlkSize) || (MBS_DES=cfbBlkSize) { + int n; + + /* decryption */ + outBuffer = Cipher_DES(inpBuffer[0], DES_EKEYS(pCtx1), DESspbox); + outBuffer = Cipher_DES(outBuffer, DES_DKEYS(pCtx2), DESspbox); + outBuffer = Cipher_DES(outBuffer, DES_EKEYS(pCtx3), DESspbox); + + /* store output and put feedback into the buffer */ + for(n=0; nidCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr length < 1 +// ippStsUnderRunErr (length & 7) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data stream +// pDst pointer to the target byte data stream +// length plaintext stream length (bytes) +// pCtx1-3 pointers to the DES context +// padding the padding scheme indicator +// +*F*/ +IPPFUN(IppStatus, ippsTDESDecryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + IppsPadding padding)) +{ + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + /* test source and destination pointers */ + IPP_BAD_PTR2_RET(pSrc, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + + /* force ippPaddingNONE padding */ + if(ippPaddingNONE!=padding) + padding = ippPaddingNONE; + /* test stream integrity */ + IPP_BADARG_RET((len&7), ippStsUnderRunErr); + + { + int nBlocks = len/MBS_DES; + + /* misaligned source and/or target */ + if( (IPP_UINT_PTR(pSrc) & 0x7) || (IPP_UINT_PTR(pDst) & 0x7) ) { + int n; + for(n=0; nidCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr length <1 +// ippStsUnderRunErr (length & 7) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data stream +// pDst pointer to the target byte data stream +// length plaintext strem length (bytes) +// pCtx1-3 pointers to the DES context +// pIV pointer to the init vector +// padding the padding scheme indicator +// +*F*/ +IPPFUN(IppStatus, ippsTDESEncryptCBC,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsPadding padding)) +{ + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + /* test source and destination pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pIV); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + + /* force ippPaddingNONE padding */ + if(ippPaddingNONE!=padding) + padding = ippPaddingNONE; + /* test stream integrity */ + //IPP_BADARG_RET(((length&7) && (ippPaddingNONE==padding)), ippStsUnderRunErr); + IPP_BADARG_RET((len&7), ippStsUnderRunErr); + + { + int nBlocks = len/MBS_DES; + + /* read IV */ + Ipp64u iv; + CopyBlock8(pIV, &iv); + + /* misaligned source and/or target */ + /*if( (IPP_UINT_PTR(pSrc) & 0x7) || (IPP_UINT_PTR(pDst) & 0x7) ) {*/ + if( (IPP_UINT_PTR(pSrc) & 0x7) || (IPP_UINT_PTR(pDst) & 0x7) || pSrc==pDst) { + int n; + for(n=0; nidCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr len <1 +// ippStsCFBSizeErr (1>cfbBlkSize || cfbBlkSize>MBS_DES) +// ippStsUnderRunErr (len%cfbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data stream +// pDst pointer to the target byte data stream +// len plaintext stream length (bytes) +// cfbBlkSize CFB block size (bytes) +// pCtx1-3 pointers to the DES context +// pIV pointer to the init vector +// padding the padding scheme indicator +// +*F*/ +IPPFUN(IppStatus, ippsTDESEncryptCFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, + const IppsDESSpec* pCtx1, const IppsDESSpec* pCtx2, const IppsDESSpec* pCtx3, + const Ipp8u* pIV, + IppsPadding padding)) +{ + Ipp64u inpBuffer; + Ipp64u outBuffer; + + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + /* test source and destination pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pIV); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test CFB value */ + IPP_BADARG_RET(((1>cfbBlkSize) || (MBS_DES=cfbBlkSize) { + int n; + + /* encryption */ + outBuffer = Cipher_DES(inpBuffer, DES_EKEYS(pCtx1), DESspbox); + outBuffer = Cipher_DES(outBuffer, DES_DKEYS(pCtx2), DESspbox); + outBuffer = Cipher_DES(outBuffer, DES_EKEYS(pCtx3), DESspbox); + + /* store output and put feedback into the buffer */ + for(n=0; nidCtx != idCtxDES +// pCtx2->idCtx != idCtxDES +// pCtx3->idCtx != idCtxDES +// ippStsLengthErr length <1 +// ippStsUnderRunErr (length&7) && (ippPaddingNONE==padding) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source byte data stream +// pDst pointer to the target byte data stream +// length plaintext stream length (bytes) +// pCtx1-3 pointers to the DES context +// padding the padding scheme indicator +// +*F*/ +IPPFUN(IppStatus, ippsTDESEncryptECB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + IppsPadding padding)) +{ + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + /* test source and destination pointers */ + IPP_BAD_PTR2_RET(pSrc, pDst); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + + /* force ippPaddingNONE padding */ + if(ippPaddingNONE!=padding) + padding = ippPaddingNONE; + /* test stream integrity */ + //IPP_BADARG_RET(((length&7) && (ippPaddingNONE==padding)), ippStsUnderRunErr); + IPP_BADARG_RET((len&7), ippStsUnderRunErr); + + { + int nBlocks = len/MBS_DES; + + /* misaligned source and/or target */ + if( (IPP_UINT_PTR(pSrc) & 0x7) || (IPP_UINT_PTR(pDst) & 0x7) ) { + int n; + for(n=0; n=ofbBlkSize) { + /* block-by-block processing */ + outBuffer = Cipher_DES(inpBuffer, DES_EKEYS(pCtx1), DESspbox); + outBuffer = Cipher_DES(outBuffer, DES_DKEYS(pCtx2), DESspbox); + outBuffer = Cipher_DES(outBuffer, DES_EKEYS(pCtx3), DESspbox); + + /* store output */ + XorBlock(pSrc, &outBuffer, pDst, ofbBlkSize); + + /* shift inpBuffer for the next OFB operation */ + if(MBS_DES==ofbBlkSize) + inpBuffer = outBuffer; + else + #if (IPP_ENDIAN == IPP_BIG_ENDIAN) + inpBuffer = LSL64(inpBuffer, ofbBlkSize*8) + |LSR64(outBuffer, 64-ofbBlkSize*8); + #else + inpBuffer = LSR64(inpBuffer, ofbBlkSize*8) + |LSL64(outBuffer, 64-ofbBlkSize*8); + #endif + + pSrc += ofbBlkSize; + pDst += ofbBlkSize; + len -= ofbBlkSize; + } + + /* update pIV */ + CopyBlock8(&inpBuffer, pIV); +} + + +/*F* +// Name: ippsTDESEncryptOFB +// +// Purpose: Encrypts byte data stream according to TDES in OFB mode. +// +// Returns: Reason: +// ippStsNullPtrErr pCtx1== NULL +// pCtx2== NULL +// pCtx3== NULL +// pSrc == NULL +// pDst == NULL +// pIV == NULL +// ippStsContextMatchErr pCtx->idCtx != idCtxRijndael +// ippStsLengthErr len <1 +// ippStsOFBSizeErr (1>ofbBlkSize || ofbBlkSize>MBS_DES) +// ippStsUnderRunErr (len%ofbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data stream +// pDst pointer to the target data stream +// len plaintext stream length (bytes) +// ofbBlkSize OFB block size (bytes) +// pCtx1,.. DES contexts +// pIV pointer to the initialization vector +// +*F*/ +IPPFUN(IppStatus, ippsTDESEncryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pIV)) +{ + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + /* test context validity */ + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + + /* test source and destination pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pIV); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test OFB value */ + IPP_BADARG_RET(((1>ofbBlkSize) || (MBS_DESidCtx != idCtxRijndael +// ippStsLengthErr len <1 +// ippStsOFBSizeErr (1>ofbBlkSize || ofbBlkSize>MBS_DES) +// ippStsUnderRunErr (len%ofbBlkSize) +// ippStsNoErr no errors +// +// Parameters: +// pSrc pointer to the source data stream +// pDst pointer to the target data stream +// len plaintext stream length (bytes) +// ofbBlkSize OFB block size (bytes) +// pCtx1,.. DES contexts +// pIV pointer to the initialization vector +// +*F*/ + +IPPFUN(IppStatus, ippsTDESDecryptOFB,(const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, + const IppsDESSpec* pCtx1, + const IppsDESSpec* pCtx2, + const IppsDESSpec* pCtx3, + Ipp8u* pIV)) +{ + /* test contexts */ + IPP_BAD_PTR3_RET(pCtx1, pCtx2, pCtx3); + + /* test context validity */ + IPP_BADARG_RET(!VALID_DES_ID(pCtx1), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx2), ippStsContextMatchErr); + IPP_BADARG_RET(!VALID_DES_ID(pCtx3), ippStsContextMatchErr); + + /* test source and destination pointers */ + IPP_BAD_PTR3_RET(pSrc, pDst, pIV); + /* test stream length */ + IPP_BADARG_RET((len<1), ippStsLengthErr); + /* test OFB value */ + IPP_BADARG_RET(((1>ofbBlkSize) || (MBS_DES=_IPP_W7) || (_IPP32E>=_IPP32E_M7)) +__INLINE void PurgeBlock(void* pDst, int len) +{ + int n; + for(n=0; n> (blkBitSize -numSize)%8 ); + + int i; + Ipp32u carry = 1; + for(i=BITS2WORD8_SIZE(blkBitSize)-1; i>=0; i--) { + int d = maskPosition - i; + Ipp8u mask = (Ipp8u)(maskVal | cpIsMsb_ct((BNU_CHUNK_T)d)); + + Ipp32u x = pCounter[i] + carry; + Ipp8u y = pCounter[i]; + pCounter[i] = (Ipp8u)((y & ~mask) | (x & mask)); + + maskVal &= cpIsMsb_ct((BNU_CHUNK_T)d); + + carry = (x>>8) & 0x1; + } +} + +/* vb */ +__INLINE void ompStdIncrement64( void* pInitCtrVal, void* pCurrCtrVal, + int ctrNumBitSize, int n ) +{ + int k; + Ipp64u cntr; + Ipp64u temp; + Ipp64s item; + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + ( ( Ipp8u* )&cntr )[k] = ( ( Ipp8u* )pInitCtrVal )[7 - k]; + #else + for( k = 0; k < 8; k++ ) + ( ( Ipp8u* )&cntr )[k] = ( ( Ipp8u* )pInitCtrVal )[k]; + #endif + + if( ctrNumBitSize == 64 ) + { + cntr += ( Ipp64u )n; + } + else + { + Ipp64u mask = CONST_64(0xFFFFFFFFFFFFFFFF) >> ( 64 - ctrNumBitSize ); + Ipp64u save = cntr & ( ~mask ); + Ipp64u bndr = ( Ipp64u )1 << ctrNumBitSize; + + temp = cntr & mask; + cntr = temp + ( Ipp64u )n; + + if( cntr > bndr ) + { + item = ( Ipp64s )n - ( Ipp64s )( bndr - temp ); + + while( item > 0 ) + { + cntr = ( Ipp64u )item; + item -= ( Ipp64s )bndr; + } + } + + cntr = save | ( cntr & mask ); + } + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + ( ( Ipp8u* )pCurrCtrVal )[7 - k] = ( ( Ipp8u* )&cntr )[k]; + #else + for( k = 0; k < 8; k++ ) + ( ( Ipp8u* )pCurrCtrVal )[k] = ( ( Ipp8u* )&cntr )[k]; + #endif +} + + +/* vb */ +__INLINE void ompStdIncrement128( void* pInitCtrVal, void* pCurrCtrVal, + int ctrNumBitSize, int n ) +{ + int k; + Ipp64u low; + Ipp64u hgh; + Ipp64u flag; + Ipp64u mask = CONST_64(0xFFFFFFFFFFFFFFFF); + Ipp64u save = 0; + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )&low )[k] = ( ( Ipp8u* )pInitCtrVal )[15 - k]; + ( ( Ipp8u* )&hgh )[k] = ( ( Ipp8u* )pInitCtrVal )[7 - k]; + } + #else + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )&low )[k] = ( ( Ipp8u* )pInitCtrVal )[8 + k]; + ( ( Ipp8u* )&hgh )[k] = ( ( Ipp8u* )pInitCtrVal )[k]; + } + #endif + + if( ctrNumBitSize == 64 ) + { + low += ( Ipp64u )n; + } + else if( ctrNumBitSize < 64 ) + { + Ipp64u bndr; + Ipp64u cntr; + Ipp64s item; + + mask >>= ( 64 - ctrNumBitSize ); + save = low & ( ~mask ); + cntr = ( low & mask ) + ( Ipp64u )n; + + if( ctrNumBitSize < 31 ) + { + bndr = ( Ipp64u )1 << ctrNumBitSize; + + if( cntr > bndr ) + { + item = ( Ipp64s )( ( Ipp64s )n - ( ( Ipp64s )bndr - + ( Ipp64s )( low & mask ) ) ); + + while( item > 0 ) + { + cntr = ( Ipp64u )item; + item -= ( Ipp64s )bndr; + } + } + } + + low = save | ( cntr & mask ); + } + else + { + flag = ( low >> 63 ); + + if( ctrNumBitSize != 128 ) + { + mask >>= ( 128 - ctrNumBitSize ); + save = hgh & ( ~mask ); + hgh &= mask; + } + + low += ( Ipp64u )n; + + if( flag != ( low >> 63 ) ) hgh++; + + if( ctrNumBitSize != 128 ) + { + hgh = save | ( hgh & mask ); + } + } + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )pCurrCtrVal )[15 - k] = ( ( Ipp8u* )&low )[k]; + ( ( Ipp8u* )pCurrCtrVal )[7 - k] = ( ( Ipp8u* )&hgh )[k]; + } + #else + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )pCurrCtrVal )[8 + k] = ( ( Ipp8u* )&low )[k]; + ( ( Ipp8u* )pCurrCtrVal )[k] = ( ( Ipp8u* )&hgh )[k]; + } + #endif +} + +#if 0 +/* vb */ +__INLINE void ompStdIncrement192( void* pInitCtrVal, void* pCurrCtrVal, + int ctrNumBitSize, int n ) +{ + int k; + Ipp64u low; + Ipp64u mdl; + Ipp64u hgh; + Ipp64u flag; + Ipp64u mask = CONST_64(0xFFFFFFFFFFFFFFFF); + Ipp64u save; + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )&low )[k] = ( ( Ipp8u* )pInitCtrVal )[23 - k]; + ( ( Ipp8u* )&mdl )[k] = ( ( Ipp8u* )pInitCtrVal )[15 - k]; + ( ( Ipp8u* )&hgh )[k] = ( ( Ipp8u* )pInitCtrVal )[7 - k]; + } + #else + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )&low )[k] = ( ( Ipp8u* )pInitCtrVal )[16 + k]; + ( ( Ipp8u* )&mdl )[k] = ( ( Ipp8u* )pInitCtrVal )[8 + k]; + ( ( Ipp8u* )&hgh )[k] = ( ( Ipp8u* )pInitCtrVal )[k]; + } + #endif + + if( ctrNumBitSize == 64 ) + { + low += ( Ipp64u )n; + } + else if( ctrNumBitSize == 128 ) + { + flag = ( low >> 63 ); + low += ( Ipp64u )n; + if( flag != ( low >> 63 ) ) mdl++; + } + else if( ctrNumBitSize == 192 ) + { + flag = ( low >> 63 ); + low += ( Ipp64u )n; + + if( flag != ( low >> 63 ) ) + { + flag = ( mdl >> 63 ); + mdl++; + if( flag != ( mdl >> 63 ) ) hgh++; + } + } + else if( ctrNumBitSize < 64 ) + { + Ipp64u bndr; + Ipp64u cntr; + Ipp64s item; + + mask >>= ( 64 - ctrNumBitSize ); + save = low & ( ~mask ); + cntr = ( low & mask ) + ( Ipp64u )n; + + if( ctrNumBitSize < 31 ) + { + bndr = ( Ipp64u )1 << ctrNumBitSize; + + if( cntr > bndr ) + { + item = ( Ipp64s )( ( Ipp64s )n - ( ( Ipp64s )bndr - + ( Ipp64s )( low & mask ) ) ); + + while( item > 0 ) + { + cntr = ( Ipp64u )item; + item -= ( Ipp64s )bndr; + } + } + } + + low = save | ( cntr & mask ); + } + else if( ctrNumBitSize < 128 ) + { + flag = ( low >> 63 ); + mask >>= ( 128 - ctrNumBitSize ); + save = mdl & ( ~mask ); + mdl &= mask; + low += ( Ipp64u )n; + if( flag != ( low >> 63 ) ) mdl++; + mdl = save | ( mdl & mask ); + } + else + { + flag = ( low >> 63 ); + mask >>= ( 192 - ctrNumBitSize ); + save = hgh & ( ~mask ); + hgh &= mask; + low += ( Ipp64u )n; + + if( flag != ( low >> 63 ) ) + { + flag = ( mdl >> 63 ); + mdl++; + if( flag != ( mdl >> 63 ) ) hgh++; + } + + hgh = save | ( hgh & mask ); + } + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )pCurrCtrVal )[23 - k] = ( ( Ipp8u* )&low )[k]; + ( ( Ipp8u* )pCurrCtrVal )[15 - k] = ( ( Ipp8u* )&mdl )[k]; + ( ( Ipp8u* )pCurrCtrVal )[7 - k] = ( ( Ipp8u* )&hgh )[k]; + } + #else + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )pCurrCtrVal )[16 + k] = ( ( Ipp8u* )&low )[k]; + ( ( Ipp8u* )pCurrCtrVal )[8 + k] = ( ( Ipp8u* )&mdl )[k]; + ( ( Ipp8u* )pCurrCtrVal )[k] = ( ( Ipp8u* )&hgh )[k]; + } + #endif +} +#endif + +#if 0 +/* vb */ +__INLINE void ompStdIncrement256( void* pInitCtrVal, void* pCurrCtrVal, + int ctrNumBitSize, int n ) +{ + int k; + Ipp64u low; + Ipp64u mdl; + Ipp64u mdm; + Ipp64u hgh; + Ipp64u flag; + Ipp64u mask = CONST_64(0xFFFFFFFFFFFFFFFF); + Ipp64u save; + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )&low )[k] = ( ( Ipp8u* )pInitCtrVal )[31 - k]; + ( ( Ipp8u* )&mdl )[k] = ( ( Ipp8u* )pInitCtrVal )[23 - k]; + ( ( Ipp8u* )&mdm )[k] = ( ( Ipp8u* )pInitCtrVal )[15 - k]; + ( ( Ipp8u* )&hgh )[k] = ( ( Ipp8u* )pInitCtrVal )[7 - k]; + } + #else + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )&low )[k] = ( ( Ipp8u* )pInitCtrVal )[24 + k]; + ( ( Ipp8u* )&mdl )[k] = ( ( Ipp8u* )pInitCtrVal )[16 + k]; + ( ( Ipp8u* )&mdm )[k] = ( ( Ipp8u* )pInitCtrVal )[8 + k]; + ( ( Ipp8u* )&hgh )[k] = ( ( Ipp8u* )pInitCtrVal )[k]; + } + #endif + + if( ctrNumBitSize == 64 ) + { + low += ( Ipp64u )n; + } + else if( ctrNumBitSize == 128 ) + { + flag = ( low >> 63 ); + low += ( Ipp64u )n; + if( flag != ( low >> 63 ) ) mdl++; + } + else if( ctrNumBitSize == 192 ) + { + flag = ( low >> 63 ); + low += ( Ipp64u )n; + + if( flag != ( low >> 63 ) ) + { + flag = ( mdl >> 63 ); + mdl++; + if( flag != ( mdl >> 63 ) ) hgh++; + } + } + else if( ctrNumBitSize == 256 ) + { + flag = ( low >> 63 ); + low += ( Ipp64u )n; + + if( flag != ( low >> 63 ) ) + { + flag = ( mdl >> 63 ); + mdl++; + + if( flag != ( mdl >> 63 ) ) + { + flag = ( mdm >> 63 ); + mdm++; + if( flag != ( mdm >> 63 ) ) hgh++; + } + } + } + else if( ctrNumBitSize < 64 ) + { + Ipp64u bndr; + Ipp64u cntr; + Ipp64s item; + + mask >>= ( 64 - ctrNumBitSize ); + save = low & ( ~mask ); + cntr = ( low & mask ) + ( Ipp64u )n; + + if( ctrNumBitSize < 31 ) + { + bndr = ( Ipp64u )1 << ctrNumBitSize; + + if( cntr > bndr ) + { + item = ( Ipp64s )( ( Ipp64s )n - ( ( Ipp64s )bndr - + ( Ipp64s )( low & mask ) ) ); + + while( item > 0 ) + { + cntr = ( Ipp64u )item; + item -= ( Ipp64s )bndr; + } + } + } + + low = save | ( cntr & mask ); + } + else if( ctrNumBitSize < 128 ) + { + flag = ( low >> 63 ); + mask >>= ( 128 - ctrNumBitSize ); + save = mdl & ( ~mask ); + mdl &= mask; + low += ( Ipp64u )n; + if( flag != ( low >> 63 ) ) mdl++; + mdl = save | ( mdl & mask ); + } + else if( ctrNumBitSize < 192 ) + { + flag = ( low >> 63 ); + mask >>= ( 192 - ctrNumBitSize ); + save = mdm & ( ~mask ); + mdm &= mask; + low += ( Ipp64u )n; + + if( flag != ( low >> 63 ) ) + { + flag = ( mdl >> 63 ); + mdl++; + if( flag != ( mdl >> 63 ) ) mdm++; + } + + mdm = save | ( mdm & mask ); + } + else + { + flag = ( low >> 63 ); + mask >>= ( 256 - ctrNumBitSize ); + save = hgh & ( ~mask ); + hgh &= mask; + low += ( Ipp64u )n; + + if( flag != ( low >> 63 ) ) + { + flag = ( mdl >> 63 ); + mdl++; + + if( flag != ( mdl >> 63 ) ) + { + flag = ( mdm >> 63 ); + mdm++; + if( flag != ( mdm >> 63 ) ) hgh++; + } + } + + hgh = save | ( hgh & mask ); + } + + #if( IPP_ENDIAN == IPP_LITTLE_ENDIAN ) + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )pCurrCtrVal )[31 - k] = ( ( Ipp8u* )&low )[k]; + ( ( Ipp8u* )pCurrCtrVal )[23 - k] = ( ( Ipp8u* )&mdl )[k]; + ( ( Ipp8u* )pCurrCtrVal )[15 - k] = ( ( Ipp8u* )&mdm )[k]; + ( ( Ipp8u* )pCurrCtrVal )[7 - k] = ( ( Ipp8u* )&hgh )[k]; + } + #else + for( k = 0; k < 8; k++ ) + { + ( ( Ipp8u* )pCurrCtrVal )[24 + k] = ( ( Ipp8u* )&low )[k]; + ( ( Ipp8u* )pCurrCtrVal )[16 + k] = ( ( Ipp8u* )&mdl )[k]; + ( ( Ipp8u* )pCurrCtrVal )[8 + k] = ( ( Ipp8u* )&mdm )[k]; + ( ( Ipp8u* )pCurrCtrVal )[k] = ( ( Ipp8u* )&hgh )[k]; + } + #endif +} +#endif + +#endif /* _CP_TOOL_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcptrngenhwca.c b/plugin/ippcp/library/src/sources/ippcp/pcptrngenhwca.c new file mode 100644 index 000000000..5af412b94 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcptrngenhwca.c @@ -0,0 +1,202 @@ +/******************************************************************************* +* Copyright (C) 2015 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// TRNG Functions +// +// Contents: +// ippsTRNGenHW() +// ippsTRNGenHW_BN() +// +// +*/ + +#include "owndefs.h" + +#include "owncp.h" +#include "pcpbn.h" +#include "pcptool.h" + +#if ((_IPP>=_IPP_G9) || (_IPP32E>=_IPP32E_E9)) +static int cpSeed_hw_sample(BNU_CHUNK_T* pSample) +{ +#define LOCAL_COUNTER (320) /* this constant has been tuned manually */ + int n; + int success = 0; + for(n=0; n=_IPP32E_E9) +static int cpSeed_hw_sample32(Ipp32u* pSample) +{ +#define LOCAL_COUNTER (320) /* this constant has been tuned manually */ + int n; + int success = 0; + for(n=0; n=_IPP32E_E9) + if( bufLen%((Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u))) ) { + if( !cpSeed_hw_sample32(pRand)) { + return 0; + } + } + #endif + return 1; +} +#endif + +/*F* +// Name: ippsTRNGenRDSEED +// +// Purpose: Generates a true random bit sequence +// based on Intel® instruction RDSEED of the specified nBits length. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pRand +// +// ippStsLengthErr 1 > nBits +// +// ippStsNotSupportedModeErr unsupported rdrand instruction +// +// ippStsErr random bit sequence can't be generated +// +// ippStsNoErr no error +// +// Parameters: +// pRand pointer to the buffer +// nBits number of bits be requested +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsTRNGenRDSEED,(Ipp32u* pRand, int nBits, void* pCtx)) +{ + /* test PRNG buffer */ + IPP_BAD_PTR1_RET(pRand); + + /* test sizes */ + IPP_BADARG_RET(nBits< 1, ippStsLengthErr); + + IPP_UNREFERENCED_PARAMETER(pCtx); + + #if ((_IPP>=_IPP_G9) || (_IPP32E>=_IPP32E_E9)) + if( IsFeatureEnabled(ippCPUID_RDSEED) ) { + cpSize rndSize = BITS2WORD32_SIZE(nBits); + Ipp32u rndMask = MAKEMASK32(nBits); + + if(cpSeedHW_buffer(pRand, rndSize)) { + pRand[rndSize-1] &= rndMask; + return ippStsNoErr; + } + else + return ippStsErr; + } + /* unsupported rdrand instruction */ + else + #endif + IPP_ERROR_RET(ippStsNotSupportedModeErr); +} + + +/*F* +// Name: ippsTRNGenRDSEED_BN +// +// Purpose: Generates a true random big number +// based on Intel® instruction RDSEED of the specified nBits length. +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pRand +// +// ippStsLengthErr 1 > nBits +// nBits > BN_ROOM(pRand) +// +// ippStsNotSupportedModeErr unsupported rdrand instruction +// +// ippStsErr random big number can't be generated +// +// ippStsNoErr no error +// +// Parameters: +// pRand pointer to the big number +// nBits number of bits be requested +// pCtx pointer to the context +*F*/ +IPPFUN(IppStatus, ippsTRNGenRDSEED_BN,(IppsBigNumState* pRand, int nBits, void* pCtx)) +{ + /* test random BN */ + IPP_BAD_PTR1_RET(pRand); + IPP_BADARG_RET(!BN_VALID_ID(pRand), ippStsContextMatchErr); + + /* test sizes */ + IPP_BADARG_RET(nBits< 1, ippStsLengthErr); + IPP_BADARG_RET(nBits> BN_ROOM(pRand)*BNU_CHUNK_BITS, ippStsLengthErr); + + IPP_UNREFERENCED_PARAMETER(pCtx); + + #if ((_IPP>=_IPP_G9) || (_IPP32E>=_IPP32E_E9)) + if( IsFeatureEnabled(ippCPUID_RDSEED) ) { + BNU_CHUNK_T* pRandBN = BN_NUMBER(pRand); + cpSize rndSize = BITS_BNU_CHUNK(nBits); + BNU_CHUNK_T rndMask = MASK_BNU_CHUNK(nBits); + + if(cpSeedHW_buffer((Ipp32u*)pRandBN, rndSize*(Ipp32s)(sizeof(BNU_CHUNK_T)/sizeof(Ipp32u)))) { + pRandBN[rndSize-1] &= rndMask; + + FIX_BNU(pRandBN, rndSize); + BN_SIZE(pRand) = rndSize; + BN_SIGN(pRand) = ippBigNumPOS; + + return ippStsNoErr; + } + else + return ippStsErr; + } + + /* unsupported rdrand instruction */ + else + #endif + IPP_ERROR_RET(ippStsNotSupportedModeErr); +} diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpvariant.h b/plugin/ippcp/library/src/sources/ippcp/pcpvariant.h new file mode 100644 index 000000000..611d9f350 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpvariant.h @@ -0,0 +1,419 @@ +/******************************************************************************* +* Copyright (C) 2005 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Intel® Integrated Performance Primitives Cryptography (Intel® IPP Cryptography) +// +// Purpose: +// Define ippCP variant +// +// +*/ + +#if !defined(_CP_VARIANT_H) +#define _CP_VARIANT_H + +/* +// set _AES_NI_ENABLING_ +*/ +#if defined _IPP_AES_NI_ + #if (_IPP_AES_NI_ == 0) + #define _AES_NI_ENABLING_ _FEATURE_OFF_ + #elif (_IPP_AES_NI_ == 1) + #define _AES_NI_ENABLING_ _FEATURE_ON_ + #else + #error Define _IPP_AES_NI_=0 or 1 or omit _IPP_AES_NI_ at all + #endif +#else + #if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + #define _AES_NI_ENABLING_ _FEATURE_TICKTOCK_ + #else + #define _AES_NI_ENABLING_ _FEATURE_OFF_ + #endif +#endif + +/* +// select AES safe implementation +*/ +#define _ALG_AES_SAFE_COMPACT_SBOX_ (1) +#define _ALG_AES_SAFE_COMPOSITE_GF_ (2) + +#if (_AES_NI_ENABLING_==_FEATURE_ON_) + #define _ALG_AES_SAFE_ _FEATURE_OFF_ +#else + #if (_IPP>=_IPP_V8) || (_IPP32E>=_IPP32E_U8) + #define _ALG_AES_SAFE_ _ALG_AES_SAFE_COMPOSITE_GF_ + #else + #define _ALG_AES_SAFE_ _ALG_AES_SAFE_COMPACT_SBOX_ + //#define _ALG_AES_SAFE_ _ALG_AES_SAFE_COMPOSITE_GF_ + #endif +#endif + +/* +// AES Noise +// Enable mitigation when dispatching available to +// Intel® Advanced Encryption Standard New Instructions (Intel® AES-NI) - _AES_NI_ENABLING_ != _FEATURE_OFF_ +// or vector extensions of Intel® AES-NI - _IPP32E >=_IPP32E_K1 +*/ +#ifndef IPP_AES_PROB_NOISE +#define IPP_AES_PROB_NOISE _FEATURE_ON_ +#endif + +#if (IPP_AES_PROB_NOISE == _FEATURE_ON_) + #if ((_AES_NI_ENABLING_ != _FEATURE_OFF_) || (_IPP32E >=_IPP32E_K1)) + #define _AES_PROB_NOISE _FEATURE_ON_ + #else + #define _AES_PROB_NOISE _FEATURE_OFF_ + #endif +#else + #define _AES_PROB_NOISE _FEATURE_OFF_ +#endif + +/* +// if there is no outside assignment +// set _SHA_NI_ENABLING_ based on CPU specification +*/ +#if !defined(_SHA_NI_ENABLING_) +#if (_IPP>=_IPP_P8) || (_IPP32E>=_IPP32E_Y8) + #define _SHA_NI_ENABLING_ _FEATURE_TICKTOCK_ +#else + #define _SHA_NI_ENABLING_ _FEATURE_OFF_ +#endif +#endif + +/* +// set/reset _ADCOX_NI_ENABLING_ +*/ +#if (_IPP32E>=_IPP32E_L9) + #if !defined(_ADCOX_NI_ENABLING_) + #define _ADCOX_NI_ENABLING_ _FEATURE_TICKTOCK_ + #endif +#else + #undef _ADCOX_NI_ENABLING_ + #define _ADCOX_NI_ENABLING_ _FEATURE_OFF_ +#endif + +/* +// Intel IPP Cryptography supports several hash algorithms by default: +// SHA-1 +// SHA-256 +// SHA-224 (or SHA256/224 by the FIPS180-4 classification) +// SHA-512 +// SHA-384 (or SHA512/384 by the FIPS180-4 classification) +// MD5 +// SM3 +// +// By default all hash algorithms are included in Intel IPP Cryptography. +// +// If one need excludes code of particular hash, just define +// suitable _DISABLE_ALG_XXX, where XXX name of the hash algorithm +// +*/ +#if !defined(_DISABLE_ALG_SHA1_) +#define _ENABLE_ALG_SHA1_ /* SHA1 on */ +#else +# undef _ENABLE_ALG_SHA1_ /* SHA1 off */ +#endif + +#if !defined(_DISABLE_ALG_SHA256_) +# define _ENABLE_ALG_SHA256_ /* SHA256 on */ +#else +# undef _ENABLE_ALG_SHA256_ /* SHA256 off */ +#endif + +#if !defined(_DISABLE_ALG_SHA224_) +# define _ENABLE_ALG_SHA224_ /* SHA224 on */ +#else +# undef _ENABLE_ALG_SHA224_ /* SHA224 off */ +#endif + +#if !defined(_DISABLE_ALG_SHA512_) +# define _ENABLE_ALG_SHA512_ /* SHA512 on */ +#else +# undef _ENABLE_ALG_SHA512_ /* SHA512 off */ +#endif + +#if !defined(_DISABLE_ALG_SHA384_) +# define _ENABLE_ALG_SHA384_ /* SHA384 on */ +#else +# undef _ENABLE_ALG_SHA384_ /* SHA384 off */ +#endif + +#if !defined(_DISABLE_ALG_SHA512_224_) +# define _ENABLE_ALG_SHA512_224_ /* SHA512/224 on */ +#else +# undef _ENABLE_ALG_SHA512_224_ /* SHA512/224 off */ +#endif + +#if !defined(_DISABLE_ALG_SHA512_256_) +# define _ENABLE_ALG_SHA512_256_ /* SHA512/256 on */ +#else +# undef _ENABLE_ALG_SHA512_256_ /* SHA512/256 off */ +#endif + +#if !defined(_DISABLE_ALG_MD5_) +# define _ENABLE_ALG_MD5_ /* MD5 on */ +#else +# undef _ENABLE_ALG_MD5_ /* MD5 off */ +#endif + +#if !defined(_DISABLE_ALG_SM3_) +# define _ENABLE_ALG_SM3_ /* SM3 on */ +#else +# undef _ENABLE_ALG_SM3_ /* SM3 off */ +#endif + +/* +// SHA1 plays especial role in Intel IPP Cryptography. +// Thus Intel IPP Cryptography random generator and +// therefore prime number generator are based on SHA1. +// So, do no exclude SHA1 from the active list of hash algorithms +*/ +#if defined(_DISABLE_ALG_SHA1_) +#undef _DISABLE_ALG_SHA1_ +#endif + +/* +// Because of performane reason hash algorithms are implemented in form +// of unroller cycle and therefore these implementations are big enough. +// Intel IPP Cryptography supports "compact" implementation of some basic hash algorithms: +// SHA-1 +// SHA-256 +// SHA-512 +// SM3 +// +// Define any +// _ALG_SHA1_COMPACT_ +// _ALG_SHA256_COMPACT_ +// _ALG_SHA512_COMPACT_ +// _ALG_SM3_COMPACT_ +// +// to select "compact" implementation of particular hash algorithm. +// Intel IPP Cryptography does not define "compact" implementation by default. +// +// Don't know what performance degradation leads "compact" +// in comparison with default Intel IPP Cryptography implementation. +// +// Note: the definition like _ALG_XXX_COMPACT_ has effect +// if and only if Intel IPP Cryptography instance is _PX or _MX +*/ +//#define _ALG_SHA1_COMPACT_ +//#define _ALG_SHA256_COMPACT_ +//#define _ALG_SHA512_COMPACT_ +//#define _ALG_SM3_COMPACT_ +//#undef _ALG_SHA1_COMPACT_ +//#undef _ALG_SHA256_COMPACT_ +//#undef _ALG_SHA512_COMPACT_ +//#undef _ALG_SM3_COMPACT_ + + +/* +// BN arithmetic: +// - do/don't use special implementation of sqr instead of usual multication +// - do/don't use Karatsuba multiplication alg +*/ +#define _USE_SQR_ /* use implementaton of sqr */ +#if !defined(_DISABLE_WINDOW_EXP_) + #define _USE_WINDOW_EXP_ /* use fixed window exponentiation */ +#endif + + +/* +// RSA: +// - do/don't use version 1 style mitigation of CBA +// - do/don't use own style mitigation of CBA +// - do/don't use Folding technique for RSA-1204 implementation +*/ +#define xUSE_VERSION1_CBA_MITIGATION_ /* not use (version 1) mitigation of CBA */ +#define _USE_IPP_OWN_CBA_MITIGATION_ /* use (own) mitigation of CBA */ +#define xUSE_FOLD_MONT512_ /* use folding technique in RSA-1024 case */ + + +/* +// Intel IPP Cryptography supports different implementation of NIST's (standard) EC over GF(0): +// P-128 (IppECCPStd128r1, IppECCPStd128r2) +// P-192 (IppECCPStd192r1) +// P-224 (IppECCPStd224r1) +// P-256 (IppECCPStd256r1) +// P-384 (IppECCPStd384r1) +// P-521 (IppECCPStd521r1) +// +// If one need replace the particular implementation by abritrary one +// assign _ECP_IMP_ARBIRTRARY_ to suitable symbol +// +// _ECP_IMPL_ARBIRTRARY_ means that implementtaion does not use any curve specific, +// provide the same (single) code for any type curve +// +// _ECP_IMPL_SPECIFIC_ means that implementation uses specific modular reduction +// based on prime structure; +// most of NIST's cures (p128, p192, p224, p256, p384, p521) are uses +// such kind of reduction procedure; +// in contrast with _ECP_IMPL_ARBIRTRARY_ and _ECP_IMPL_MFM_ +// this type of implementation uses point representation in REGULAR residual +// (not Montgometry!!) domain +// +// _ECP_IMPL_MFM_ means that implementation uses "Montgomary Friendly Modulus" (primes); +// p256 and sm2 are using such kind of optimization +*/ +#define _ECP_IMPL_NONE_ 0 +#define _ECP_IMPL_ARBIRTRARY_ 1 +#define _ECP_IMPL_SPECIFIC_ 2 +#define _ECP_IMPL_MFM_ 3 + +#if !defined(_ECP_112R1_) +#if !defined(_DISABLE_ECP_112R1_) +# define _ECP_112R1_ _ECP_IMPL_ARBIRTRARY_ +#else +# define _ECP_112R1_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_112R2_) +#if !defined(_DISABLE_ECP_112R2_) +# define _ECP_112R2_ _ECP_IMPL_ARBIRTRARY_ +#else +# define _ECP_112R2_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_160R1_) +#if !defined(_DISABLE_ECP_160R1_) +# define _ECP_160R1_ _ECP_IMPL_ARBIRTRARY_ +#else +# define _ECP_160R1_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_160R2_) +#if !defined(_DISABLE_ECP_160R2_) +# define _ECP_160R2_ _ECP_IMPL_ARBIRTRARY_ +#else +# define _ECP_160R2_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_128R1_) +#if !defined(_DISABLE_ECP_128R1_) +# define _ECP_128R1_ _ECP_IMPL_SPECIFIC_ +#else +# define _ECP_128R1_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_128R2_) +#if !defined(_DISABLE_ECP_128R2_) +# define _ECP_128R2_ _ECP_IMPL_SPECIFIC_ +#else +# define _ECP_128R2_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_192_) +#if !defined(_DISABLE_ECP_192_) +# if (_IPP32E >= _IPP32E_M7) || (_IPP >= _IPP_P8) +# define _ECP_192_ _ECP_IMPL_MFM_ +# else +# define _ECP_192_ _ECP_IMPL_SPECIFIC_ +# endif +#else +# define _ECP_192_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_224_) +#if !defined(_DISABLE_ECP_224_) +# if (_IPP32E >= _IPP32E_M7) || (_IPP >= _IPP_P8) +# define _ECP_224_ _ECP_IMPL_MFM_ +# else +# define _ECP_224_ _ECP_IMPL_SPECIFIC_ +# endif +#else +# define _ECP_224_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_256_) +#if !defined(_DISABLE_ECP_256_) +# if (_IPP32E >= _IPP32E_M7) || (_IPP >= _IPP_P8) +# define _ECP_256_ _ECP_IMPL_MFM_ +# else +# define _ECP_256_ _ECP_IMPL_SPECIFIC_ +# endif +#else +# define _ECP_256_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_384_) +#if !defined(_DISABLE_ECP_384_) +# if (_IPP32E >= _IPP32E_M7) || (_IPP >= _IPP_P8) +# define _ECP_384_ _ECP_IMPL_MFM_ +# else +# define _ECP_384_ _ECP_IMPL_SPECIFIC_ +# endif +#else +# define _ECP_384_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_521_) +#if !defined(_DISABLE_ECP_521_) +# if (_IPP32E >= _IPP32E_M7) || (_IPP >= _IPP_P8) +# define _ECP_521_ _ECP_IMPL_MFM_ +# else +# define _ECP_521_ _ECP_IMPL_SPECIFIC_ +# endif +#else +# define _ECP_521_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_SM2_) +#if !defined(_DISABLE_ECP_SM2_) +# if (_IPP32E >= _IPP32E_M7) || (_IPP >= _IPP_P8) +# define _ECP_SM2_ _ECP_IMPL_MFM_ +# else +# define _ECP_SM2_ _ECP_IMPL_SPECIFIC_ +# endif +#else +# define _ECP_SM2_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_ECP_BN_) +#if !defined(_DISABLE_ECP_BN_) +# define _ECP_BN_ _ECP_IMPL_ARBIRTRARY_ +#else +# define _ECP_BN_ _ECP_IMPL_NONE_ +#endif +#endif + +#if !defined(_DISABLE_ECP_GENERAL_) +# define _ECP_GENERAL_ _ECP_IMPL_ARBIRTRARY_ +#else +# define _ECP_GENERAL_ _ECP_IMPL_NONE_ +#endif + + +/* +// EC over GF(p): +// - do/don't use mitigation of CBA +*/ +#define _USE_ECCP_SSCM_ /* use SSCM ECCP */ + +#endif /* _CP_VARIANT_H */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpver.c b/plugin/ippcp/library/src/sources/ippcp/pcpver.c new file mode 100644 index 000000000..130ee5774 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpver.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel® Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +*/ + +#include "owndefs.h" +#include "ippcpdefs.h" +#include "owncp.h" +#include "pcpver.h" +#include "pcpname.h" + +#define GET_LIBRARY_NAME( cpu, is ) #cpu, IPP_LIB_SHORTNAME() " " is " (" #cpu ")" + +static const IppLibraryVersion ippcpLibVer = { + /* major, minor, update (ex-majorBuild) */ + BASE_VERSION(), +#if defined IPP_REVISION + IPP_REVISION, +#else + 0, +#endif /* IPP_REVISION */ + /* targetCpu[4] */ +#if ( _IPP_ARCH == _IPP_ARCH_IA32 ) || ( _IPP_ARCH == _IPP_ARCH_LP32 ) + #if ( _IPP == _IPP_M5 ) /* Intel® Quark(TM) processor - ia32 */ + GET_LIBRARY_NAME( m5, "586" ) + #elif ( _IPP == _IPP_H9 ) /* Intel® Advanced Vector Extensions 2 - ia32 */ + GET_LIBRARY_NAME( h9, "AVX2" ) + #elif ( _IPP == _IPP_G9 ) /* Intel® Advanced Vector Extensions - ia32 */ + GET_LIBRARY_NAME( g9, "AVX" ) + #elif ( _IPP == _IPP_P8 ) /* Intel® Streaming SIMD Extensions 4.2 (Intel® SSE4.2) - ia32 */ + GET_LIBRARY_NAME( p8, "SSE4.2" ) + #elif ( _IPP == _IPP_S8 ) /* Supplemental Streaming SIMD Extensions 3 + Intel® instruction MOVBE - ia32 */ + GET_LIBRARY_NAME( s8, "Atom" ) + #elif ( _IPP == _IPP_V8 ) /* Supplemental Streaming SIMD Extensions 3 - ia32 */ + GET_LIBRARY_NAME( v8, "SSSE3" ) + #elif ( _IPP == _IPP_W7 ) /* Intel® Streaming SIMD Extensions 2 - ia32 */ + GET_LIBRARY_NAME( w7, "SSE2" ) + #else + GET_LIBRARY_NAME( px, "PX" ) + #endif + +#elif ( _IPP_ARCH == _IPP_ARCH_EM64T ) || ( _IPP_ARCH == _IPP_ARCH_LP64 ) + #if ( _IPP32E == _IPP32E_K1 ) /* Intel® Advanced Vector Extensions 512 (formerly Icelake) - intel64 */ + GET_LIBRARY_NAME( k1, "AVX-512F/CD/BW/DQ/VL/SHA/VBMI/VBMI2/IFMA/GFNI/VAES/VCLMUL" ) + #elif ( _IPP32E == _IPP32E_K0 ) /* Intel® Advanced Vector Extensions 512 (formerly Skylake) - intel64 */ + GET_LIBRARY_NAME( k0, "AVX-512F/CD/BW/DQ/VL" ) + #elif ( _IPP32E == _IPP32E_N0 ) /* Intel® Advanced Vector Extensions 512 (formerly codenamed Knights Landing) - intel64 */ + GET_LIBRARY_NAME( n0, "AVX-512F/CD/ER/PF" ) + #elif ( _IPP32E == _IPP32E_E9 ) /* Intel® Advanced Vector Extensions - intel64 */ + GET_LIBRARY_NAME( e9, "AVX" ) + #elif ( _IPP32E == _IPP32E_L9 ) /* Intel® Advanced Vector Extensions 2 - intel64 */ + GET_LIBRARY_NAME( l9, "AVX2" ) + #elif ( _IPP32E == _IPP32E_Y8 ) /* Intel® Streaming SIMD Extensions 4.2 - intel64 */ + GET_LIBRARY_NAME( y8, "SSE4.2" ) + #elif ( _IPP32E == _IPP32E_N8 ) /* Supplemental Streaming SIMD Extensions 3 + Intel® instruction MOVBE - intel64 */ + GET_LIBRARY_NAME( n8, "Atom" ) + #elif ( _IPP32E == _IPP32E_U8 ) /* Supplemental Streaming SIMD Extensions 3 - intel64 */ + GET_LIBRARY_NAME( u8, "SSSE3" ) + #elif ( _IPP32E == _IPP32E_M7 ) /* Intel® Streaming SIMD Extensions 3 (Intel® SSE3) */ + GET_LIBRARY_NAME( m7, "SSE3" ) + #else + GET_LIBRARY_NAME( mx, "PX" ) + #endif +#endif + ,STR_VERSION() /* release Version */ + ,__DATE__ //BuildDate +}; + +IPPFUN( const IppLibraryVersion*, ippcpGetLibVersion, ( void )){ + return &ippcpLibVer; +}; + +/*////////////////////////// End of file "pcpver.c" ////////////////////////// */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpver.h b/plugin/ippcp/library/src/sources/ippcp/pcpver.h new file mode 100644 index 000000000..835261afd --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpver.h @@ -0,0 +1,31 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// Intel(R) Integrated Performance Primitives +// Cryptographic Primitives (ippcp) +// +// Purpose: Describes the version of ippCP +// +*/ + + +#include "ippver.h" +#define BUILD() 1043 +#define VERSION() BASE_VERSION(),BUILD() + +/* ////////////////////////// End of file "pcpver.h" ///////////////////////// */ diff --git a/plugin/ippcp/library/src/sources/ippcp/pcpver.rc b/plugin/ippcp/library/src/sources/ippcp/pcpver.rc new file mode 100644 index 000000000..1269d8049 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/pcpver.rc @@ -0,0 +1,30 @@ +/******************************************************************************* +* Copyright (C) 2002 Intel Corporation +* +* Licensed under the Apache License, Version 2.0 (the 'License'); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an 'AS IS' BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions +* and limitations under the License. +* +*******************************************************************************/ + +/* +// +// Created: Tue Feb 5 17:02:02 2002 +// +*/ + + +#include "pcpver.h" +#include "pcpname.h" +#include "ippres.gen" + +/* ////////////////////////////// End of file /////////////////////////////// */ + diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_nsm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_nsm2.c new file mode 100644 index 000000000..0f35705c2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_nsm2.c @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (C) 2017 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "sm2/ifma_arith_method_sm2.h" +#include "sm2/ifma_arith_psm2.h" +#include "sm2/ifma_arith_nsm2.h" + +IPP_OWN_DEFN(ifmaArithMethod*, gsArithGF_nsm2_avx512, (void)) { + static ifmaArithMethod m = { + /* import_to52 = */ fesm2_convert_radix64_radix52, + /* export_to64 = */ fesm2_convert_radix52_radix64, + /* encode = */ fesm2_to_mont_norder, + /* decode = */ fesm2_from_mont_norder, + /* mul = */ fesm2_mul_norder, + /* mul_dual = */ 0, + /* sqr = */ 0, + /* sqr_dual = */ 0, + /* norm = */ ifma_norm52, + /* norm_dual = */ ifma_norm52_dual, + /* lnorm = */ ifma_lnorm52, + /* lnorm_dual = */ ifma_lnorm52_dual, + /* add = */ fesm2_add_norder_norm, + /* sub = */ fesm2_sub_norder_norm, + /* neg = */ 0, + /* div2 = */ 0, + /* inv = */ fesm2_inv_norder_norm, + /* red = */ fesm2_fast_reduction_norder}; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_psm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_psm2.c new file mode 100644 index 000000000..91228be60 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_psm2.c @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (C) 2017 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "sm2/ifma_arith_method_sm2.h" +#include "sm2/ifma_arith_psm2.h" + +IPP_OWN_DEFN(ifmaArithMethod*, gsArithGF_psm2_avx512, (void)) { + static ifmaArithMethod m = { + /* import_to52 = */ fesm2_convert_radix64_radix52, + /* export_to64 = */ fesm2_convert_radix52_radix64, + /* encode = */ fesm2_to_mont, + /* decode = */ fesm2_from_mont, + /* mul = */ fesm2_mul, + /* mul_dual = */ fesm2_mul_dual, + /* sqr = */ fesm2_sqr, + /* sqr_dual = */ fesm2_sqr_dual, + /* norm = */ ifma_norm52, + /* norm_dual = */ ifma_norm52_dual, + /* lnorm = */ ifma_lnorm52, + /* lnorm_dual = */ ifma_lnorm52_dual, + /* add = */ 0, + /* sub = */ 0, + /* neg = */ fesm2_neg_norm, + /* div2 = */ fesm2_div2_norm, + /* inv = */ fesm2_inv_norm, + /* red = */ 0}; + + return &m; +} + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_sm2.h b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_sm2.h new file mode 100644 index 000000000..211e91bba --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_method_sm2.h @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (C) 2017 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#ifndef IFMA_ARITH_METHOD_SM2_H_ +#define IFMA_ARITH_METHOD_SM2_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "owncp.h" +#include "ecnist/ifma_alias_avx512.h" +#include "ecnist/ifma_arith_method.h" + +/* Pre-defined AVX512IFMA ISA based methods */ +#define gsArithGF_psm2_avx512 OWNAPI(gsArithGF_psm2_avx512) +IPP_OWN_DECL(ifmaArithMethod*, gsArithGF_psm2_avx512, (void)) + +#define gsArithGF_nsm2_avx512 OWNAPI(gsArithGF_nsm2_avx512) +IPP_OWN_DECL(ifmaArithMethod*, gsArithGF_nsm2_avx512, (void)) + +#endif /* #if (_IPP32E >= _IPP32E_K1) */ + +#endif /* #ifndef IFMA_ARITH_METHOD_SM2_H_ */ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_nsm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_nsm2.c new file mode 100644 index 000000000..e2e5b1c32 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_nsm2.c @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "sm2/ifma_arith_nsm2.h" +#include "sm2/ifma_arith_psm2.h" +#include "sm2/ifma_defs_sm2.h" + +/* + * EC SM2 base point order + * in 2^52 radix + */ +static const __ALIGN64 Ipp64u nsm2_x1[PSM2_LEN52] = { + 0x000bf40939d54123, 0x0006b21c6052b53b, 0x000fffffff7203df, 0x000fffffffffffff, 0x0000fffffffeffff}; + +/* k0 = -( (1/nsm2) mod 2^DIGIT_SIZE_52 ) mod 2^DIGIT_SIZE_52 */ +static const Ipp64u nsm2_k0 = 0x000f9e8872350975; + +/* r = 2^((52*8)) mod nsm2 */ +static const __ALIGN64 Ipp64u nsm2_r[PSM2_LEN52] = { + 0x00062abedd000000, 0x00006cb726ecad3c, 0x00056c361b698a7e, 0x0000000008dfc209, 0x0000010000000000}; + +/* To Montgomery conversion constant + * rr = 2^((52*6)*2) mod nsm2 + */ +static const __ALIGN64 Ipp64u nsm2_rr[PSM2_LEN52] = { + 0x000643f5455b3830, 0x000c453935b521eb, 0x0009ec21d42b082e, 0x0004d74634238016, 0x0000ca6ea35cbdde}; + +static const __ALIGN64 Ipp64u ones[PSM2_LEN52] = { + 0x1, 0x0, 0x0, 0x0}; + +#define MULT_ROUND(R, A, B, IDX) \ + const fesm2 Bi##R##IDX = permutexvar_i8(idx##IDX, (B)); \ + const fesm2 amBiLo##R##IDX = madd52lo_i64(zero, (A), Bi##R##IDX); \ + fesm2 tr##R##IDX = madd52hi_i64(zero, (A), Bi##R##IDX); \ + { \ + /* low */ \ + (R) = add_i64((R), amBiLo##R##IDX); \ + const fesm2 R0 = permutexvar_i8(idx0, (R)); \ + const fesm2 u = madd52lo_i64(zero, R0, K0); /* u = R0 * K0 */ \ + tr##R##IDX = madd52hi_i64(tr##R##IDX, N, u); \ + (R) = madd52lo_i64((R), N, u); \ + /* shift */ \ + const fesm2 carryone = maskz_srai_i64(maskone, (R), DIGIT_SIZE_52); \ + tr##R##IDX = add_i64(tr##R##IDX, carryone); \ + (R) = maskz_permutexvar_i8(mask_sr64, idx_sr64, (R)); \ + /* hi */ \ + (R) = add_i64((R), tr##R##IDX); \ + } + +/* R = (A*B) - no normalization (in radix 2^52) */ +IPP_OWN_DEFN(fesm2, fesm2_mul_norder, (const fesm2 a, const fesm2 b)) { + const fesm2 N = FESM2_LOADU(nsm2_x1); /* p */ + const fesm2 K0 = set1_i64(nsm2_k0); + const fesm2 zero = setzero_i64(); + const mask8 maskone = 0x1; + /* index broadcast */ + const fesm2 idx0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const fesm2 idx1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const fesm2 idx2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const fesm2 idx3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const fesm2 idx4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const fesm2 idx5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + + /* shift right 64 bit line [R >> 64] */ + const mask64 mask_sr64 = 0x00FFFFFFFFFFFFFF; + const fesm2 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + fesm2 r = setzero_i64(); + /* PSM2 + * m' mod b = 1 + * + * Algorithm + * a[] b[] - input data ((in radix 2^52)) m[] - module nsm2 + * + * when u = R[0]*m' mod b + * 1) R = R + a[] * b[i] (lo) + * 2) R = R + m[] * u (lo) + * 3) R = R >> 64 + * 4) R = R + a[] * b[i] (hi) + * 5) R = R + m[] * u (hi) + */ + /* one round = O(32) */ + MULT_ROUND(r, a, b, 0) + MULT_ROUND(r, a, b, 1) + MULT_ROUND(r, a, b, 2) + MULT_ROUND(r, a, b, 3) + MULT_ROUND(r, a, b, 4) + MULT_ROUND(r, a, b, 5) + + return r; +} + +IPP_OWN_DEFN(fesm2, fesm2_add_norder_norm, (const fesm2 a, const fesm2 b)) { + const fesm2 zero = setzero_i64(); + const fesm2 N = FESM2_LOADU(nsm2_x1); + + /* r = a + b */ + fesm2 r = add_i64(a, b); + r = ifma_lnorm52(r); + + /* t = r - N */ + fesm2 t = sub_i64(r, N); + t = ifma_norm52(t); + + /* lt = t < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(t, DIGIT_SIZE_52 - 1), _MM_CMPINT_LT); + const mask8 mask = (mask8)((mask8)0 - ((lt >> 4) & 1)); + + /* maks != 0 ? a : r */ + r = mask_mov_i64(t, mask, r); + return r; +} +IPP_OWN_DEFN(fesm2, fesm2_sub_norder_norm, (const fesm2 a, const fesm2 b)) { + const fesm2 zero = setzero_i64(); + const fesm2 N = FESM2_LOADU(nsm2_x1); + /* r = a - b */ + fesm2 r = sub_i64(a, b); + r = ifma_norm52(r); + + /* t = r + M */ + fesm2 t = add_i64(r, N); + t = ifma_lnorm52(t); + + /* lt = r < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(r, DIGIT_SIZE_52 - 1), _MM_CMPINT_LT); + const mask8 mask = (mask8)((mask8)0 - ((lt >> 4) & 1)); + /* mask != 0 ? t : r */ + r = mask_mov_i64(r, mask, t); + + return r; +} + +IPP_OWN_DEFN(fesm2, fesm2_fast_reduction_norder, (const fesm2 a)) { + const fesm2 zero = setzero_i64(); + const fesm2 N = FESM2_LOADU(nsm2_x1); + + fesm2 r = sub_i64(a, N); + r = ifma_norm52(r); + + const mask8 lt = cmp_i64_mask(zero, srli_i64(r, DIGIT_SIZE_52 - 1), _MM_CMPINT_LT); + const mask8 mask = (mask8)((mask8)0 - ((lt >> 4) & 1)); + + /* maks != 0 ? a : r */ + r = mask_mov_i64(r, mask, a); + return r; +} + +IPP_OWN_DEFN(fesm2, fesm2_to_mont_norder, (const fesm2 a)) { + const fesm2 RR = FESM2_LOADU(nsm2_rr); + const fesm2 r = fesm2_mul_norder(a, RR); + return ifma_lnorm52(r); +} + +IPP_OWN_DEFN(fesm2, fesm2_from_mont_norder, (const fesm2 a)) { + const fesm2 ONE = FESM2_LOADU(ones); + fesm2 r = fesm2_mul_norder(a, ONE); + r = ifma_lnorm52(r); + r = fesm2_fast_reduction_norder(r); + return r; +} + +__INLINE fesm2 mul_norder_norm(const fesm2 a, const fesm2 b) { + const fesm2 r = fesm2_mul_norder(a, b); + return ifma_lnorm52(r); +} + +__INLINE fesm2 sqr_norder_norm(const fesm2 a) { + const fesm2 r = fesm2_mul_norder(a, a); + return ifma_lnorm52(r); +} + +#define SIZE_TBL (16) + +#define sqr(R, A) (R) = sqr_norder_norm((A)) +#define mul(R, A, B) (R) = mul_norder_norm((A), (B)) + +IPP_OWN_DEFN(fesm2, fesm2_inv_norder_norm, (const fesm2 z)) { + + const fesm2 r_norder = FESM2_LOADU(nsm2_r); + int i; + + // pwr_z_Tbl[i][] = z^i, i=0,..,15 + __ALIGN64 fesm2 pwr_z_Tbl[SIZE_TBL]; + + pwr_z_Tbl[0] = r_norder; + pwr_z_Tbl[1] = z; + + for (i = 2; i < SIZE_TBL; i += 2) { + sqr(pwr_z_Tbl[i], pwr_z_Tbl[i / 2]); + mul(pwr_z_Tbl[i + 1], pwr_z_Tbl[i], z); + } + + // pwr = (nsm2-2) in big endian + const Ipp8u pwr[] = "\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x72\x03\xDF\x6B\x21\xC6\x05\x2B" + "\x53\xBB\xF4\x09\x39\xD5\x41\x21"; + // init r = 1 + fesm2 r = pwr_z_Tbl[0]; + + for (i = 0; i < 32; ++i) { + const int v = pwr[i]; + const int hi = (v >> 4) & 0xF; + const int lo = v & 0xF; + + sqr(r, r); + sqr(r, r); + sqr(r, r); + sqr(r, r); + if (hi) + mul(r, r, pwr_z_Tbl[hi]); + sqr(r, r); + sqr(r, r); + sqr(r, r); + sqr(r, r); + if (lo) + mul(r, r, pwr_z_Tbl[lo]); + } + return r; +} + +#undef SIZE_TBL +#undef sqr +#undef mul + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_nsm2.h b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_nsm2.h new file mode 100644 index 000000000..198a044f2 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_nsm2.h @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ +#if !defined(_IFMA_ARITH_NSM2_H_) +#define _IFMA_ARITH_NSM2_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "sm2/ifma_defs_sm2.h" + +/** + * \brief + * + * Montgomery multiplication + * + * a * b * R mod n, where R = 2^(6*52) mod n + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + * \return value no normalization + */ +IPP_OWN_DECL(fesm2, fesm2_mul_norder, (const fesm2 a, const fesm2 b)) + +/** + * \brief + * + * A + B (mod n) + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + * \return value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_add_norder_norm, (const fesm2 a, const fesm2 b)) + +/** + * \brief + * + * A + B (mod n) + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + * \return value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_sub_norder_norm, (const fesm2 a, const fesm2 b)) + +/** + * \brief + * + * Conversion to Montgomery domain modulo n (subgroup order). + * + * a * R mod n, where R = 2^(6*52) mod n + * + * \param[in] a value (in radix 2^52) + * \return value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_to_mont_norder, (const fesm2 a)) + +/** + * \brief + * + * Reduction modulo n (subgroup order). + * + * (a >= n) ? a - n : a + * + * \param[in] a value (in radix 2^52) + * \return value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_fast_reduction_norder, (const fesm2 a)) + +/** + * \brief + * + * Conversion from Montgomery domain modulo n (subgroup order). + * + * a mod n + * + * \param[in] a value (radix 2^52) + * \return value (radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_from_mont_norder, (const fesm2 a)) + +/** + * \brief + * + * Modular inverse modulo n (subgroup order). + * + * 1/z mod n + * + * \param[in] z value (in radix 2^52) + * \return value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_inv_norder_norm, (const fesm2 z)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ARITH_NSM2_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_psm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_psm2.c new file mode 100644 index 000000000..40033b3f7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_psm2.c @@ -0,0 +1,388 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "sm2/ifma_arith_psm2.h" +#include "sm2/ifma_defs_sm2.h" + +/* modulus psm2 = 2^256 - 2^224 - 2^96 + 2^64 - 1 */ +static const __ALIGN64 Ipp64u psm2_x1[PSM2_LEN52] = { + 0x000fffffffffffff, 0x000ff00000000fff, 0x000fffffffffffff, 0x000fffffffffffff, 0x0000fffffffeffff}; + +/* 4*p */ +static const __ALIGN64 Ipp64u psm2_x4[PSM2_LEN52] = { + 0x000ffffffffffffc, 0x000fc00000003fff, 0x000fffffffffffff, 0x000fffffffffffff, 0x0003fffffffbffff}; + +/* to Montgomery conversion constant + * rr = 2^((PSM2_LEN52*DIGIT_SIZE)*2) mod psm2 + */ +/* rr = 2^(52*6*2) mod psm2 */ +static const __ALIGN64 Ipp64u psm2_rr[PSM2_LEN52] = { + 0x0006000000070000, 0x000fffffd0000000, 0x00000400000003ff, 0x0000000000300000, 0x0000000800000003}; + +static const __ALIGN64 Ipp64u ones[PSM2_LEN52] = { + 0x1, 0x0, 0x0, 0x0, 0x0}; + + +/* R = (A/2) mod M */ +IPP_OWN_DEFN(fesm2, fesm2_div2_norm, (const fesm2 a)) { + const fesm2 M = FESM2_LOADU(psm2_x1); + const fesm2 zero = setzero_i64(); + const fesm2 one = set1_i64(1LL); + + const mask8 is_last_one = cmp_i64_mask(and_i64(a, one), zero, _MM_CMPINT_EQ); + const mask8 mask = (mask8)((is_last_one & 1) - 1); + + fesm2 r = mask_add_i64(a, mask, a, M); + r = ifma_lnorm52(r); + + /* 1-bit shift right */ + /* extract last bite + >> 64 */ + const mask64 mask_shift = 0xFFFFFFFF; + const fesm2 idx_shift = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + fesm2 shift_right = maskz_permutexvar_i8(mask_shift, idx_shift, and_i64(r, one)); + /* set last bit is first byte (52 radix) */ + shift_right = slli_i64(shift_right, DIGIT_SIZE_52 - 1); + /* join first new bite */ + r = srli_i64(r, 1); /* create slot by first bite 1111 -> 0111 */ + r = add_i64(r, shift_right); /* join first and other bite */ + + return r; +} + +IPP_OWN_DEFN(fesm2, fesm2_neg_norm, (const fesm2 a)) { + const fesm2 M4 = FESM2_LOADU(psm2_x4); + + /* a == 0 ? 0xFF : 0 */ + const mask8 mask_zero = FESM2_IS_ZERO(a); + + /* r = 4*p - a */ + fesm2 r = mask_sub_i64(a, (mask8)(~mask_zero), M4, a); + r = ifma_norm52(r); + return r; +} + +#define MULT_ROUND(R, A, B, IDX) \ + const fesm2 Bi##R##IDX = permutexvar_i8(idx##IDX, (B)); \ + const fesm2 amBiLo##R##IDX = madd52lo_i64(zero, (A), Bi##R##IDX); \ + fesm2 tr##R##IDX = madd52hi_i64(zero, (A), Bi##R##IDX); \ + { \ + /* low */ \ + (R) = add_i64((R), amBiLo##R##IDX); \ + const fesm2 u = permutexvar_i8(idx0, (R)); /* u = R0 * 1 */ \ + tr##R##IDX = madd52hi_i64(tr##R##IDX, M, u); \ + (R) = madd52lo_i64((R), M, u); \ + /* shift */ \ + const fesm2 carryone = maskz_srai_i64(maskone, (R), DIGIT_SIZE_52); \ + tr##R##IDX = add_i64(tr##R##IDX, carryone); \ + (R) = maskz_permutexvar_i8(mask_sr64, idx_sr64, (R)); \ + /* hi */ \ + (R) = add_i64((R), tr##R##IDX); \ + } + +/* R = (A*B) - no normalization (in radix 2^52) */ +IPP_OWN_DEFN(fesm2, fesm2_mul, (const fesm2 a, const fesm2 b)) { + const fesm2 M = FESM2_LOADU(psm2_x1); /* p */ + const fesm2 zero = setzero_i64(); + const mask8 maskone = 0x1; + /* index broadcast */ + const fesm2 idx0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const fesm2 idx1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const fesm2 idx2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const fesm2 idx3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const fesm2 idx4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const fesm2 idx5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + + /* shift right 64 bit line [R >> 64] */ + const mask64 mask_sr64 = 0x00FFFFFFFFFFFFFF; + const fesm2 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + fesm2 r = setzero_i64(); + /* PSM2 + * m' mod b = 1 + * + * Algorithm + * a[] b[] - input data ((in radix 2^52)) m[] - module psm2 + * + * when u = R[0]*m' mod b + * 1) R = R + a[] * b[i] (lo) + * 2) R = R + m[] * u (lo) + * 3) R = R >> 64 + * 4) R = R + a[] * b[i] (hi) + * 5) R = R + m[] * u (hi) + */ + /* one round = O(32) */ + MULT_ROUND(r, a, b, 0) + MULT_ROUND(r, a, b, 1) + MULT_ROUND(r, a, b, 2) + MULT_ROUND(r, a, b, 3) + MULT_ROUND(r, a, b, 4) + MULT_ROUND(r, a, b, 5) + + return r; +} + +IPP_OWN_DEFN(void, fesm2_mul_dual, + (fesm2 pr1[], const fesm2 a1, const fesm2 b1, + fesm2 pr2[], const fesm2 a2, const fesm2 b2)) { + const fesm2 M = FESM2_LOADU(psm2_x1); /* p */ + const fesm2 zero = setzero_i64(); + const mask8 maskone = 0x1; + /* index broadcast */ + const fesm2 idx0 = set_i64(REPL8(0x0706050403020100)); // 7, 6, 5, 4, 3, 2, 1, 0 + const fesm2 idx1 = set_i64(REPL8(0x0f0e0d0c0b0a0908)); // 15, 14, 13, 12, 11, 10, 9, 8 + const fesm2 idx2 = set_i64(REPL8(0x1716151413121110)); // 23, 22, 21, 20, 19, 18, 17, 16 + const fesm2 idx3 = set_i64(REPL8(0x1f1e1d1c1b1a1918)); // 31, 30, 29, 28, 27, 26, 25, 24 + const fesm2 idx4 = set_i64(REPL8(0x2726252423222120)); // 39, 38, 37, 36, 35, 34, 33, 32 + const fesm2 idx5 = set_i64(REPL8(0x2f2e2d2c2b2a2928)); // 47, 46, 45, 44, 43, 42, 41, 40 + + /* shift right 64 bit line [R >> 64] */ + const mask64 mask_sr64 = 0x00FFFFFFFFFFFFFF; + const fesm2 idx_sr64 = set_i64(0x0, // 0, 0, 0, 0, 0, 0, 0, 0 + 0x3f3e3d3c3b3a3938, // 63, 62, 61, 60, 59, 58, 57, 56 + 0x3736353433323130, // 55, 54, 53, 52, 51, 50, 49, 48 + 0x2f2e2d2c2b2a2928, // 47, 46, 45, 44, 43, 42, 41, 40 + 0x2726252423222120, // 39, 38, 37, 36, 35, 34, 33, 32 + 0x1f1e1d1c1b1a1918, // 31, 30, 29, 28, 27, 26, 25, 24 + 0x1716151413121110, // 23, 22, 21, 20, 19, 18, 17, 16 + 0x0f0e0d0c0b0a0908); // 15, 14, 13, 12, 11, 10, 9, 8 + + fesm2 r1, r2; + r1 = r2 = setzero_i64(); + /* PSM2 + * m' mod b = 1 + * + * Algorithm + * a[] b[] - input data ((in radix 2^52)) m[] - module psm2 + * + * when u = R[0]*m' mod b + * 1) R = R + a[] * b[i] (lo) + * 2) R = R + m[] * u (lo) + * 3) R = R >> 64 + * 4) R = R + a[] * b[i] (hi) + * 5) R = R + m[] * u (hi) + */ + /* one round = O(32) */ + MULT_ROUND(r1, a1, b1, 0) + MULT_ROUND(r2, a2, b2, 0) + MULT_ROUND(r1, a1, b1, 1) + MULT_ROUND(r2, a2, b2, 1) + MULT_ROUND(r1, a1, b1, 2) + MULT_ROUND(r2, a2, b2, 2) + MULT_ROUND(r1, a1, b1, 3) + MULT_ROUND(r2, a2, b2, 3) + MULT_ROUND(r1, a1, b1, 4) + MULT_ROUND(r2, a2, b2, 4) + MULT_ROUND(r1, a1, b1, 5) + MULT_ROUND(r2, a2, b2, 5) + + *pr1 = r1; + *pr2 = r2; + return; +} + +IPP_OWN_DEFN(fesm2, fesm2_to_mont, (const fesm2 a)) { + const fesm2 RR = FESM2_LOADU(psm2_rr); + + fesm2 r = fesm2_mul(a, RR); + return ifma_lnorm52(r); +} + +static fesm2 fesm2_fast_reduction(const fesm2 a) { + const fesm2 M = FESM2_LOADU(psm2_x1); + const fesm2 zero = setzero_i64(); + + /* r = a - M */ + fesm2 r = sub_i64(a, M); + r = ifma_norm52(r); + + /* 1 < 0 */ + const mask8 lt = cmp_i64_mask(zero, srli_i64(r, DIGIT_SIZE_52 - 1), _MM_CMPINT_LT); + const mask8 mask = (mask8)((mask8)0 - ((lt >> 4) & 1)); + + /* maks != 0 ? a : r */ + r = mask_mov_i64(r, mask, a); + return r; +} + +IPP_OWN_DEFN(fesm2, fesm2_from_mont, (const fesm2 a)) { + const fesm2 ONE = FESM2_LOADU(ones); + + /* from mont */ + fesm2 r = fesm2_mul(a, ONE); + r = ifma_lnorm52(r); + r = fesm2_fast_reduction(r); + return r; +} + +__INLINE fesm2 fesm2_mul_norm(const fesm2 a, const fesm2 b) { + fesm2 r = fesm2_mul(a, b); + return ifma_lnorm52(r); +} + +__INLINE fesm2 fesm2_sqr_norm(const fesm2 a) { + fesm2 r = fesm2_sqr(a); + return ifma_lnorm52(r); +} + +#define mul(R, A, B) (R) = fesm2_mul_norm((A), (B)) +#define sqr(R, A) (R) = fesm2_sqr_norm((A)) +#define mul_dual(R1, A1, B1, R2, A2, B2) \ + fesm2_mul_dual(&(R1), (A1), (B1), &(R2), (A2), (B2)); \ + ifma_lnorm52_dual(&(R1), (R1), &(R2), (R2)); + +__INLINE fesm2 fesm2_sqr_ntimes(const fesm2 a, int n) { + fesm2 r = a; + for (; n > 0; --n) + sqr(r, r); + return r; +} + +#define sqr_ntimes(R, A, N) (R) = fesm2_sqr_ntimes((A), (N)) + +IPP_OWN_DEFN(fesm2, fesm2_inv_norm, (const fesm2 z)) { + + fesm2 tmp1, tmp2, D, E, F; + tmp1 = tmp2 = D = E = F = setzero_i64(); + fesm2 r; + r = setzero_i64(); + + sqr(tmp1, z); + mul(F, tmp1, z); /* F = z^3 */ + sqr_ntimes(tmp2, F, 2); /* tmp2 = z^0xC */ + /**/ + mul_dual(D, tmp2, z, /* D = z^0xD */ + E, tmp2, tmp1); /* E = z^0xE */ + mul(F, tmp2, F); /* F = z^0xF */ + /**/ + sqr_ntimes(tmp2, F, 4); /* tmp2 = z^0xF0 */ + /**/ + mul_dual(D, tmp2, D, /* D = z^0xFD */ + E, tmp2, E); /* E = z^0xFE */ + mul(F, tmp2, F); /* F = z^0xFF */ + /**/ + sqr_ntimes(tmp2, F, 8); /* tmp2 = z^0xFF00 */ + mul_dual(D, tmp2, D, /* D = z^0xFFFD */ + E, tmp2, E); /* E = z^0xFFFE */ + mul(F, tmp2, F); /* F = z^0xFFFF */ + /**/ + sqr_ntimes(tmp2, F, 16); /* tmp2 = z^0xFFFF0000 */ + mul_dual(D, tmp2, D, /* D = z^0xFFFFFFFD */ + E, tmp2, E); /* E = z^0xFFFFFFFE */ + mul(F, tmp2, F); /* F = z^0xFFFFFFFF */ + /**/ + /**/ + /* z ^ FFFFFFFE 00000000 */ + sqr_ntimes(r, E, 32); + /* z ^ FFFFFFFE FFFFFFFF */ + mul(r, r, F); + /* z ^ FFFFFFFE FFFFFFFF 00000000 */ + sqr_ntimes(r, r, 32); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF */ + mul(r, r, F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF 00000000 */ + sqr_ntimes(r, r, 32); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF */ + mul(r, r, F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 00000000 */ + sqr_ntimes(r, r, 32); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF */ + mul(r, r, F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 00000000 */ + sqr_ntimes(r, r, 64); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF */ + mul(r, r, F); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF 00000000 */ + sqr_ntimes(r, r, 32); + /* z ^ FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFD */ + mul(r, r, D); + return r; +} + +IPP_OWN_DEFN(fesm2, fesm2_convert_radix64_radix52, (const Ipp64u* a)) { + /* load mask to register */ + const mask8 mask_load = 0x0F; + const fesm2 mask_rad52 = set1_i64(DIGIT_MASK_52); + /* set data */ + const fesm2 idx16 = set_i64(0x001f001f00170016, // 31, 31, 23, 22, + 0x0016001500140013, // 22, 21, 20, 19, + 0x0013001200110010, // 19, 18, 17, 16, + 0x0010000f000e000d, // 16, 15, 14, 13, + 0x000c000b000a0009, // 12, 11, 10, 9, + 0x0009000800070006, // 9, 8, 7, 6, + 0x0006000500040003, // 6, 5, 4, 3, + 0x0003000200010000); // 3, 2, 1, 0 + const fesm2 shift_right = set_i64(12LL, 8LL, 4LL, 0LL, 12LL, 8LL, 4LL, 0LL); + + fesm2 r = maskz_loadu_i64(mask_load, a); + r = permutexvar_i16(idx16, r); + r = srlv_i64(r, shift_right); + r = and_i64(mask_rad52, r); + return r; +} + +IPP_OWN_DEFN(void, fesm2_convert_radix52_radix64, (Ipp64u * out, const fesm2 a)) { + /* mask store */ + const mask8 mask_store = 0x0F; + const fesm2 shift_left = set_i64(4LL, 0LL, 4LL, 0LL, 4LL, 0LL, 4LL, 0LL); + const fesm2 idx_up8 = set_i64(0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3e3d3c3b, // {63,63,63,63,62,61,60,59} + 0x3737363534333231, // {55,55,54,53,52,51,50,49} + 0x302e2d2c2b2a2928, // {48,46,45,44,43,42,41,40} + 0x1f1f1f1f1f1f1e1d, // {31,31,31,31,31,31,30,29} + 0x1717171716151413, // {23,23,23,23,22,21,20,19} + 0x0f0f0f0e0d0c0b0a, // {15,15,15,14,13,12,11,10} + 0x0706050403020100); // { 7, 6, 5, 4, 3, 2, 1, 0} + + const fesm2 idx_down8 = set_i64(0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3f3f3f3f3f3f3f3f, // {63,63,63,63,63,63,63,63} + 0x3a39383737373737, // {58,57,56,55,55,55,55,55} + 0x2727272727272726, // {39,39,39,39,39,39,39,38} + 0x2524232221201f1f, // {37,36,35,34,33,32,31,31} + 0x1c1b1a1918171717, // {28,27,26,25,24,23,23,23} + 0x1211100f0f0f0f0f, // {18,17,16,15,15,15,15,15} + 0x0908070707070707); // { 9, 8, 7, 7, 7, 7, 7, 7} + + fesm2 r = a; + + r = sllv_i64(r, shift_left); + fesm2 T = permutexvar_i8(idx_up8, r); + r = permutexvar_i8(idx_down8, r); + r = or_i64(r, T); + mask_storeu_i64(out, mask_store, r); + return; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_psm2.h b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_psm2.h new file mode 100644 index 000000000..cd71a2f14 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_arith_psm2.h @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ +#if !defined(_IFMA_ARITH_PSM2_H_) +#define _IFMA_ARITH_PSM2_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_alias_avx512.h" +#include "sm2/ifma_defs_sm2.h" +#include + + +/** + * \brief + * compute R = (-A) enhanced Montgomery (Gueron modification group operation) + * \param[in] a value (in radix 2^52) + * \return fesm2 value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_neg_norm, (const fesm2 a)) + +/** + * \brief + * + * Montgomery multiplication + * + * a * b * r mod n, where r = 2^(6*52) mod n + * + * Note: final normalization to 2^52 radix is not performed and shall be + * handled separately. + * + * \param[in] a first value (in radix 2^52) + * \param[in] b second value (in radix 2^52) + * \return fesm2 not normalization value + */ +IPP_OWN_DECL(fesm2, fesm2_mul, (const fesm2 a, const fesm2 b)) + +/** + * \brief + * + * Montgomery multiplication + * + * a * a * r mod n, where r = 2^(6*52) mod n + * + * Note: final normalization to 2^52 radix is not performed and shall be + * handled separately. + * + * \param[in] a value (in radix 2^52) + * \return fesm2 not normalization value + */ +__INLINE IPP_OWN_DEFN(fesm2, fesm2_sqr, (const fesm2 a)) { + return fesm2_mul(a, a); +} + +/** + * \brief + * + * Dual Montgomery multiplication without final normalization to 2^52 radix. + * (two independent multiplications) + * + * a1 * b1 * R mod p + * a2 * b2 * R mod p, where R = 2^(6*52) mod p + * + * \param[out] pr1 ptr first value no normalization + * \param[in] a1 value first (in radix 2^52) + * \param[in] b1 value second (in radix 2^52) + * \param[out] pr2 ptr second value no normalization + * \param[in] a2 value first (in radix 2^52) + * \param[in] b2 value second (in radix 2^52) + */ +IPP_OWN_DECL(void, fesm2_mul_dual, (fesm2 pr1[], const fesm2 a1, const fesm2 b1, fesm2 pr2[], const fesm2 a2, const fesm2 b2)) + +/** + * \brief + * + * Dual Montgomery multiplication without final normalization to 2^52 radix. + * (two independent multiplications) + * + * a1 * a1 * R mod p + * a2 * a2 * R mod p, where R = 2^(6*52) mod p + * + * \param[out] pr1 ptr first value no normalization + * \param[in] a1 value (in radix 2^52) + * \param[out] pr2 ptr second value no normalization + * \param[in] a2 value (in radix 2^52) + */ +__INLINE IPP_OWN_DEFN(void, fesm2_sqr_dual, (fesm2 pr1[], const fesm2 a1, fesm2 pr2[], const fesm2 a2)) { + fesm2_mul_dual(pr1, a1, a1, pr2, a2, a2); + return; +} + +/* R = A + B */ +#define fesm2_add_no_red(A, B) add_i64((A), (B)) + +/* R = A - B */ +#define fesm2_sub_no_red(A, B) sub_i64((A), (B)) + +/** + * \brief + * R = A/2 + * \param[in] a value (in radix 2^52) + * \return fe384 value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_div2_norm, (const fesm2 a)) + +/** + * \brief + * + * Modular inverse modulo p. + * + * 1/z mod p + * + * \param[in] z value (in radix 2^52) + * \return fesm2 value (in radix 2^52) + */ +IPP_OWN_DECL(fesm2, fesm2_inv_norm, (const fesm2 z)) + +/** + * \brief + * + * Conversion to Montgomery domain modulo p. + * + * a * r mod p, where r = 2^(6*52) mod p + * + * \param[in] a value (in radix 2^52) + * \return fesm2 value in Montgomery domain + */ +IPP_OWN_DECL(fesm2, fesm2_to_mont, (const fesm2 a)) + +/** + * \brief + * + * Conversion from Montgomery domain modulo p. + * + * a mod p + * + * \param[in] a value (in radix 2^52) + * \return fesm2 value from Montgomery + */ +IPP_OWN_DECL(fesm2, fesm2_from_mont, (const fesm2 a)) + +/** + * \brief + * convert radix 64 to (in radix 2^52) + * \param[in] arad64 ptr array size (6) + * \return fesm2 value in register 52 + */ +IPP_OWN_DECL(fesm2, fesm2_convert_radix64_radix52, (const Ipp64u* a)) + +/** + * \brief + * convert (in radix 2^52) to radix 64 + * \param[out] rrad64 ptr array size (6) + * \param[in] arad52 value (in radix 2^52) + */ +IPP_OWN_DECL(void, fesm2_convert_radix52_radix64, (Ipp64u * out, const fesm2 a)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ARITH_PSM2_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_defs_sm2.h b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_defs_sm2.h new file mode 100644 index 000000000..0bbd8e25d --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_defs_sm2.h @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ +#if !defined(_IFMA_DEFS_SM2_H_) +#define _IFMA_DEFS_SM2_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "ecnist/ifma_alias_avx512.h" + +typedef m512 fesm2; + +#define DIGIT_MASK_52 (0xFFFFFFFFFFFFF) +#define DIGIT_SIZE_52 (52) +#define PSM2_LEN52 (5) +#define PSM2_LEN64 (4) + +#define REPL8(e) e, e, e, e, e, e, e, e + +/* from Montgomery conversion constant + * one + */ +static const __ALIGN64 Ipp64u PSM2_ONE52[PSM2_LEN52] = {0x1, 0x0, 0x0, 0x0, 0x0}; + +/* Montgomery(1) + * r = 2^(PSM2_LEN52*DIGIT_SIZE) mod psm2 + */ +/* r = 2^(52*6) mod psm2 */ +static const __ALIGN64 Ipp64u PSM2_R[PSM2_LEN52] = { + 0x0000000001000000, 0x000ffff000000010, 0x0000ffffffffffff, 0x0000000000000000, 0x0000010000000000}; + +/** + * \brief + * check is most significant bit + * \return mask8 + * 0xFF - is equal one + * 0x00 - is no equal one + */ +__INLINE mask8 sm2_is_msb(const mask8 a) { + return (mask8)((mask8)0 - (a >> 7)); +} + +/** + * \brief + * check is zero input value + * \param[in] value + * \return mask8 + * 0xFF - is zero value + * 0x00 - no equal zero + */ +__INLINE mask8 sm2_is_zero_i64(const m512 a) { + const mask8 mask = cmp_i64_mask(a, setzero_i64(), _MM_CMPINT_NE); + return sm2_is_msb((~mask & (mask - 1))); +} + +#define FESM2_LOADU(A) maskz_loadu_i64(0x1F, (A)) +#define FESM2_IS_ZERO(A) sm2_is_zero_i64((A)) +#define FESM2_CMP_MASK(A, B, ENUM_CMP) cmp_i64_mask((A), (B), (ENUM_CMP)) +#define FESM2_MASK_MOV(R, SRC, MASK, A) (R) = mask_mov_i64((SRC), (MASK), (A)) + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_DEFS_SM2_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_addpoint_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_addpoint_sm2.c new file mode 100644 index 000000000..22a3c9f15 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_addpoint_sm2.c @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "sm2/ifma_arith_method_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_AddPoint_sm2_avx512, + (IppsGFpECPoint * pR, + const IppsGFpECPoint* pP, + const IppsGFpECPoint* pQ, + IppsGFpECState* pEC)) { + gsModEngine* pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod* pmeth = (ifmaArithMethod*)GFP_METHOD_ALT(pME); + + __ALIGN64 PSM2_POINT_IFMA P, R; + + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + if (pP == pQ) { + gesm2_dbl(&R, &P); + } else { + __ALIGN64 PSM2_POINT_IFMA Q; + recode_point_to_mont52(&Q, ECP_POINT_DATA(pQ), pPool, pmeth, pME); + + gesm2_add(&R, &P, &Q); + } + + recode_point_to_mont64(pR, &R, pPool, pmeth, pME); + + cpGFpReleasePool(3, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_dh_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_dh_sm2.c new file mode 100644 index 000000000..d15d807fb --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_dh_sm2.c @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "sm2/ifma_defs_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" +#include "sm2/ifma_arith_method_sm2.h" + +IPP_OWN_DEFN(int, gfec_SharedSecretDH_sm2_avx512, + (IppsGFpECPoint * pR, + const IppsGFpECPoint* pP, + const BNU_CHUNK_T* pScalar, + int scalarLen, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) { + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine* pME = GFP_PMA(ECP_GFP(pEC)); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod* pmeth = (ifmaArithMethod*)GFP_METHOD_ALT(pME); + + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Copy scalar */ + BNU_CHUNK_T* pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 PSM2_POINT_IFMA P52, R52; + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + + /* Convert point coordinates to a new Montgomery domain */ + recode_point_to_mont52(&P52, ECP_POINT_DATA(pP), pPool, pmeth, pME); + + gesm2_mul(&R52, &P52, (Ipp8u*)pExtendedScalar, orderBits); + + /* Check if the point - point to infinity */ + const mask8 is_zero_z = FESM2_IS_ZERO(R52.z); + int finite_point = ((mask8)0xFF != is_zero_z); + + /* Get X affine coordinate */ + gesm2_to_affine(/* x = */ &(R52.x), /* y = */ NULL, /* a = */ &R52); + + R52.x = p_from_mont(R52.x); + from_radix52(ECP_POINT_X(pR), R52.x); + + cpGFpReleasePool(5, pME); + + return finite_point; + } +} + +#endif // IPP32E >= _IPP32E_K1 diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_mulpoint_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_mulpoint_sm2.c new file mode 100644 index 000000000..45ca91739 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_mulpoint_sm2.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "sm2/ifma_arith_method_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_MulPoint_sm2_avx512, + (IppsGFpECPoint * pR, + const IppsGFpECPoint* pP, + const BNU_CHUNK_T* pScalar, + int scalarLen, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine* pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod* pmeth = (ifmaArithMethod*)GFP_METHOD_ALT(pME); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + const int elemLen = GFP_PELEN(pME); + + BNU_CHUNK_T* pPool = cpGFpGetPool(5, pME); + BNU_CHUNK_T* pExtendedScalar = pPool; /* 2 pool elem to hold scalar */ + BNU_CHUNK_T* pPointPool = pPool + 2 * elemLen; /* 3 pool elem to to hold 3 point coordinates */ + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 PSM2_POINT_IFMA P, R; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pP), pPointPool, pmeth, pME); + + gesm2_mul(&R, &P, (Ipp8u*)pExtendedScalar, orderBits); + + recode_point_to_mont64(pR, &R, pPointPool, pmeth, pME); + + cpGFpReleasePool(5, pME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_on_curve_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_on_curve_sm2.c new file mode 100644 index 000000000..7b36cb995 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_on_curve_sm2.c @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include +#include + +IPP_OWN_DEFN(int, gfec_point_on_curve_sm2_avx512, (const IppsGFpECPoint *pPoint, IppsGFpECState *pEC)) +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + + __ALIGN64 PSM2_POINT_IFMA P; + + recode_point_to_mont52(&P, ECP_POINT_DATA(pPoint), pPool /* 3 elem */, pmeth, pME); + + const int onCurve = gesm2_is_on_curve(&P, /* use_jproj_coord = */ !IS_ECP_AFFINE_POINT(pPoint)); + + cpGFpReleasePool(3, pME); + return onCurve; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_pubkey_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_pubkey_sm2.c new file mode 100644 index 000000000..63b973b0b --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_pubkey_sm2.c @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "sm2/ifma_ecpoint_sm2.h" +#include "sm2/ifma_arith_psm2.h" +#include "sm2/ifma_arith_method_sm2.h" + +IPP_OWN_DEFN(IppsGFpECPoint*, gfec_PubKey_sm2_avx512, + (IppsGFpECPoint * pR, + const BNU_CHUNK_T* pScalar, + int scalarLen, IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) { + FIX_BNU(pScalar, scalarLen); + { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + gsModEngine* pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine* nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod* pmeth = (ifmaArithMethod*)GFP_METHOD_ALT(pME); + + BNU_CHUNK_T* pPool = cpGFpGetPool(5, nME); + BNU_CHUNK_T* pExtendedScalar = pPool; + BNU_CHUNK_T* pPointPool = pExtendedScalar + 2 * GFP_FELEN(pME); + + /* Copy scalar */ + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, pScalar, scalarLen); + + __ALIGN64 PSM2_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + + if (ECP_PREMULBP(pEC)) { + gesm2_mul_base(&R, (Ipp8u*)pExtendedScalar); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 PSM2_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPointPool /* 3 elem */, pmeth, pME); + + gesm2_mul(&R, &G52, (Ipp8u*)pExtendedScalar, orderBits); + } + + recode_point_to_mont64(pR, &R, pPointPool /* 3 elem */, pmeth, pME); + + cpGFpReleasePool(5, nME); + + ECP_POINT_FLAGS(pR) = gfec_IsPointAtInfinity(pR) ? 0 : ECP_FINITE_POINT; + return pR; + } +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_sign_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_sign_sm2.c new file mode 100644 index 000000000..0763d3340 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_sign_sm2.c @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" +#include "pcpgfpstuff.h" + +#include "sm2/ifma_defs_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" +#include "sm2/ifma_arith_method_sm2.h" + + +IPP_OWN_DEFN(IppStatus, gfec_Sign_sm2_avx512, + (const IppsBigNumState* pMsgDigest, + const IppsBigNumState* pRegPrivate, + IppsBigNumState* pEphPrivate, + IppsBigNumState* pSignR, IppsBigNumState* pSignS, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppStatus sts = ippStsNoErr; + + gsModEngine* pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine* nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + + ifmaArithMethod* pmeth = (ifmaArithMethod*)GFP_METHOD_ALT(pME); + ifmaArithMethod* nmeth = (ifmaArithMethod*)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_add n_add = nmeth->add; + ifma_add n_sub = nmeth->sub; + ifma_inv n_inv = nmeth->inv; + ifma_red n_red = nmeth->red; + + fesm2 sign_r, sign_s; + sign_r = sign_s = setzero_i64(); + + /* compute r-component + * 1) (x1,y1) = [s]G + * 2) r = (e + x1) mod n + */ + /* 1) (x1,y1) = [s]G */ + /* copy scalar */ + BNU_CHUNK_T* pExtendedScalar = cpGFpGetPool(2, pME); + cpGFpElementCopyPad(pExtendedScalar, orderLen + 1, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + + __ALIGN64 PSM2_POINT_IFMA P; + + if (ECP_PREMULBP(pEC)) { + gesm2_mul_base(&P, (Ipp8u*)pExtendedScalar); + } else { + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + + /* Convert base point to a new Montgomery domain */ + __ALIGN64 PSM2_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool, pmeth, pME); + + gesm2_mul(&P, &G52, (Ipp8u*)pExtendedScalar, orderBits); + + cpGFpReleasePool(3, pME); + } + + /* extract affine P.x */ + gesm2_to_affine(/* x = */ &(P.x), /* y = */ NULL, /* a = */ &P); + P.x = p_from_mont(P.x); + P.x = n_red(P.x); + + /* 2) r = (e + x1) mod n */ + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pME); + fesm2 msg = setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + msg = to_radix52((Ipp64u*)pTmp); + msg = n_red(msg); /* reduce just in case */ + + msg = n_to_mont(msg); + P.x = n_to_mont(P.x); + + sign_r = n_add(msg, P.x); + /* check r == 0 or r + k == n(0) */ + /* r == 0 */ + const mask8 sign_r_err_zeros = FESM2_IS_ZERO(sign_r); + /* r + k == 0 */ + /* extract k */ + fesm2 eph_key = setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pEphPrivate), BN_SIZE(pEphPrivate)); + eph_key = to_radix52((Ipp64u*)pTmp); + eph_key = n_to_mont(eph_key); + + fesm2 t; + t = n_add(eph_key, sign_r); + + const mask8 rpk_err_zeros = FESM2_IS_ZERO(t); + + if (((mask8)0xFF == sign_r_err_zeros) || ((mask8)0xFF == rpk_err_zeros)) + sts = ippStsEphemeralKeyErr; + + fesm2 reg_key = setzero_i64(); + ZEXPAND_COPY_BNU(pTmp, orderLen, BN_NUMBER(pRegPrivate), BN_SIZE(pRegPrivate)); + reg_key = to_radix52((Ipp64u*)pTmp); + + const fesm2 one = FESM2_LOADU(PSM2_ONE52); + + t = n_to_mont(one); + reg_key = n_to_mont(reg_key); + + sign_s = n_mul(sign_r, reg_key); /* sign_s = r * d */ + reg_key = n_add(reg_key, t); /* reg_key = 1 + d */ + reg_key = n_inv(reg_key); /* reg_key = (1 + d)^(-1) */ + sign_s = n_sub(eph_key, sign_s); /* sign_s = (k - r * d) */ + sign_s = n_mul(sign_s, reg_key); /* sign_s = (1 + d)^(-1) * (k - r * d) */ + + sign_s = n_from_mont(sign_s); + sign_r = n_from_mont(sign_r); + + const mask8 is_zero = (mask8)(FESM2_IS_ZERO(sign_r) | FESM2_IS_ZERO(sign_s)); + if ((mask8)0xFF == is_zero) + sts = ippStsEphemeralKeyErr; + + // return sign_s + from_radix52((Ipp64u*)pTmp, sign_s); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignS), BN_SIZE(pSignS), pTmp, orderLen); + // return sign_r + from_radix52((Ipp64u*)pTmp, sign_r); + ZEXPAND_COPY_BNU(BN_NUMBER(pSignR), BN_SIZE(pSignR), pTmp, orderLen); + + /* clear secret data */ + clear_secrets(&eph_key, &(P.x), &t); + clear_secrets(&sign_r, &sign_s, ®_key); + + /* clear buffer */ + cpGFpReleasePool(3, pME); /* pExtendedScalar(2) + tmp(1) */ + return sts; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_verify_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_verify_sm2.c new file mode 100644 index 000000000..efb8606e5 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ec_verify_sm2.c @@ -0,0 +1,148 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +#include "sm2/ifma_arith_method_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" + +IPP_OWN_DEFN(IppECResult, gfec_Verify_sm2_avx512, + (const IppsBigNumState* pMsgDigest, + const IppsGFpECPoint* pRegPublic, + const IppsBigNumState* pSignR, const IppsBigNumState* pSignS, + IppsGFpECState* pEC, + Ipp8u* pScratchBuffer)) { + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + IppECResult verifyResult = ippECInvalidSignature; + + gsModEngine* pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine* nME = ECP_MONT_R(pEC); + + const int orderBits = ECP_ORDBITSIZE(pEC); + const int orderLen = BITS_BNU_CHUNK(orderBits); + const int elemLen = GFP_FELEN(pME); + + ifmaArithMethod* pmeth = (ifmaArithMethod*)GFP_METHOD_ALT(pME); + ifmaArithMethod* nmeth = (ifmaArithMethod*)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod p) */ + ifma_decode p_from_mont = pmeth->decode; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_add n_add = nmeth->add; + ifma_red n_red = nmeth->red; + + /* init message | sign_r | sing_s */ + fesm2 msg, sign_r, sign_s, t; + msg = sign_r = sign_s = t = setzero_i64(); + + /* buffer extract msg */ + BNU_CHUNK_T* pPool = cpGFpGetPool(3, pME); + BNU_CHUNK_T* pBufMsg = pPool; + BNU_CHUNK_T* pBufSignR = pPool + elemLen; + BNU_CHUNK_T* pBufSignS = pPool + 2 * elemLen; + + ZEXPAND_COPY_BNU(pBufMsg, orderLen, BN_NUMBER(pMsgDigest), BN_SIZE(pMsgDigest)); + ZEXPAND_COPY_BNU(pBufSignS, orderLen, BN_NUMBER(pSignS), BN_SIZE(pSignS)); + ZEXPAND_COPY_BNU(pBufSignR, orderLen, BN_NUMBER(pSignR), BN_SIZE(pSignR)); + + /* radix64 -> radix52 */ + msg = to_radix52((Ipp64u*)pBufMsg); + msg = n_red(msg); /* reduce just in case */ + sign_r = to_radix52((Ipp64u*)pBufSignR); + sign_s = to_radix52((Ipp64u*)pBufSignS); + + /* Convert public point to proper Montgomery domain and 2^52 radix */ + __ALIGN64 PSM2_POINT_IFMA P; + recode_point_to_mont52(&P, ECP_POINT_DATA(pRegPublic), pPool /* 3 elem */, pmeth, pME); + + /* compute t = (r + s) mod n */ + t = n_to_mont(sign_r); + sign_s = n_to_mont(sign_s); + + t = n_add(sign_s, t); + + t = n_from_mont(t); + /* check zeros t != 0 */ + const mask8 sign_err_mask = FESM2_IS_ZERO(t); + if ((mask8)0xFF == sign_err_mask) + verifyResult = ippECInvalidSignature; + + BNU_CHUNK_T* pExtendedS = cpGFpGetPool(2, pME); + BNU_CHUNK_T* pExtendedT = cpGFpGetPool(2, pME); + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pME); + + /* compute [s]G + t[P] */ + + /* copmute [s]G */ + __ALIGN64 PSM2_POINT_IFMA sG; + /* create s */ + cpGFpElementCopyPad(pExtendedS, orderLen + 1, pBufSignS, orderLen); + if (ECP_PREMULBP(pEC)) { + gesm2_mul_base(&sG, (Ipp8u*)pExtendedS); + } else { + /* Convert base point to a new Montgomery domain */ + __ALIGN64 PSM2_POINT_IFMA G52; + recode_point_to_mont52(&G52, ECP_G(pEC), pPool /* 3 elem */, pmeth, pME); + + gesm2_mul(&sG, &G52, (Ipp8u*)pExtendedS, orderBits); + } + + /* create t */ + from_radix52((Ipp64u*)pTmp, t); + cpGFpElementCopyPad(pExtendedT, orderLen + 1, pTmp, orderLen); + /* compute [t]P */ + gesm2_mul(&P, &P, (Ipp8u*)pExtendedT, orderBits); + /* compute [s]G + [t]P */ + gesm2_add(&P, &P, &sG); + + fesm2 sign_r_restore; + /* extract X affine coordinate */ + gesm2_to_affine(/* x = */ &sign_r_restore, /* y = */ NULL, &P); + sign_r_restore = p_from_mont(sign_r_restore); + /* x = x mod n */ + sign_r_restore = n_red(sign_r_restore); + + /* R = (e + x1) mod n */ + msg = n_to_mont(msg); + sign_r_restore = n_to_mont(sign_r_restore); + + sign_r_restore = n_add(msg, sign_r_restore); + + sign_r_restore = n_from_mont(sign_r_restore); + + const mask8 mask_ok = cmp_i64_mask(sign_r_restore, sign_r, _MM_CMPINT_EQ); + if ((mask8)0xFF == mask_ok) + verifyResult = ippECValid; + + cpGFpReleasePool(8, pME); + + return verifyResult; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecpoint_sm2.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecpoint_sm2.c new file mode 100644 index 000000000..c22874e27 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecpoint_sm2.c @@ -0,0 +1,748 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" + +#include "sm2/ifma_arith_psm2.h" +#include "sm2/ifma_defs_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" + +/* 2*p */ +static const __ALIGN64 Ipp64u psm2_x2[PSM2_LEN52] = { + 0x000ffffffffffffe, 0x000fe00000001fff, 0x000fffffffffffff, 0x000fffffffffffff, 0x0001fffffffdffff}; +/* 4*p */ +static const __ALIGN64 Ipp64u psm2_x4[PSM2_LEN52] = { + 0x000ffffffffffffc, 0x000fc00000003fff, 0x000fffffffffffff, 0x000fffffffffffff, 0x0003fffffffbffff}; +/* 6*p */ +static const __ALIGN64 Ipp64u psm2_x6[PSM2_LEN52] = { + 0x000ffffffffffffa, 0x000fa00000005fff, 0x000fffffffffffff, 0x000fffffffffffff, 0x0005fffffff9ffff}; +/* 8*p */ +static const __ALIGN64 Ipp64u psm2_x8[PSM2_LEN52] = { + 0x000ffffffffffff8, 0x000f800000007fff, 0x000fffffffffffff, 0x000fffffffffffff, 0x0007fffffff7ffff}; + +/* Mont(a) = a*r mod psm2, where r = 2^(6*52) mod psm2 */ +static const __ALIGN64 Ipp64u psm2_a[PSM2_LEN52] = { + 0x000ffffffcffffff, 0x000ff03000000fcf, 0x000cffffffffffff, 0x000fffffffffffff, 0x0000fcfffffeffff}; + +/* Mont(b) = b*r mod psm2, where r = 2^(6*52) mod psm2 */ +static const __ALIGN64 Ipp64u psm2_b[PSM2_LEN52] = { + 0x00040fe188de30c4, 0x00012da4d9019422, 0x000b0dc519344af3, 0x000a51c3c71cf379, 0x00005130aa45505e}; + + +#define add(R, A, B) (R) = fesm2_add_no_red((A), (B)) +#define sub(R, A, B) (R) = fesm2_sub_no_red((A), (B)) +#define mul(R, A, B) (R) = fesm2_mul((A), (B)) +#define sqr(R, A) (R) = fesm2_sqr((A)) +#define div2(R, A) (R) = fesm2_div2_norm((A)) +#define norm(R, A) (R) = ifma_norm52((A)) +#define lnorm(R, A) (R) = ifma_lnorm52((A)) +#define inv(R, A) (R) = fesm2_inv_norm((A)) +#define from_mont(R, A) (R) = fesm2_from_mont((A)) +/* duplicate mult/sqr/norm */ +#define mul_dual(R1, A1, B1, R2, A2, B2) fesm2_mul_dual(&(R1), (A1), (B1), &(R2), (A2), (B2)) +#define sqr_dual(R1, A1, R2, A2) fesm2_sqr_dual(&(R1), (A1), &(R2), (A2)) +#define norm_dual(R1, A1, R2, A2) ifma_norm52_dual(&(R1), (A1), &(R2), (A2)) +#define lnorm_dual(R1, A1, R2, A2) ifma_lnorm52_dual(&(R1), (A1), &(R2), (A2)) + +IPP_OWN_DEFN(void, gesm2_to_affine, (fesm2 prx[], fesm2 pry[], const PSM2_POINT_IFMA* a)) { + + fesm2 z1, z2, z3; + z1 = z2 = z3 = setzero_i64(); + + inv(z1, a->z); /* 1/z */ + sqr(z2, z1); /* (1/z)^2 */ + lnorm(z2, z2); /**/ + + /* x = x/z^2 */ + if (NULL != prx) { + mul(*prx, a->x, z2); /* x = x/z^2 */ + lnorm(*prx, *prx); /**/ + } + /* y = y/z^3 */ + if (NULL != pry) { + mul(z3, z1, z2); /* (1/z)^3 */ + lnorm(z3, z3); /**/ + mul(*pry, a->y, z3); /* y = y/z^3 */ + lnorm(*pry, *pry); /**/ + } + + return; +} + +IPP_OWN_DEFN(void, gesm2_dbl, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p)) { + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * l1 = 3x^2 + a*z^4 = (if sm2 a = -3) = 3*(x^2 - z^4) = 3*(x - z^2)*(x + z^2) + * z2 = 2*y*z + * l2 = 4*x*y^2 + * x2 = l1^2 - 2*l2 + * l3 = 8*y^4 + * y2 = l1*(l2 - x2) - l3 + * + * sum aripmetic: 8 mul; 9 add/sub; 1 div2. + */ + const fesm2* x1 = &p->x; + const fesm2* y1 = &p->y; + const fesm2* z1 = &p->z; + + fesm2 x2; + fesm2 y2; + fesm2 z2; + x2 = y2 = z2 = setzero_i64(); + + fesm2 T, U, V, A, B, H; + T = U = V = setzero_i64(); + A = B = H = setzero_i64(); + + const fesm2 M2 = FESM2_LOADU(psm2_x2); /* 2*p */ + const fesm2 M4 = FESM2_LOADU(psm2_x4); /* 4*p */ + const fesm2 M8 = FESM2_LOADU(psm2_x8); /* 8*p */ + + add(T, *y1, *y1); /* T = 2*y1 */ + lnorm(T, T); /**/ + /*=====*/ + sqr_dual(V, T, /* V = 4*y1^2 */ + U, *z1); /* U = z1^2 */ + /*=====*/ + sub(B, *x1, U); /* B = 2*p + x1 - z1^2 */ + add(B, B, M2); /**/ + add(U, *x1, U); /* U = x1 + z1^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(V, V, /**/ + U, U); /**/ + norm(B, B); /**/ + /*=====*/ + mul_dual(A, V, *x1, /* A = 4*x1*y1^2 */ + B, B, U); /* B = (x1 - z1^2)*(x1 + z1^2) */ + /*=====*/ + add(x2, A, A); /* x2 = 8*x1*y1^2 (4p) */ + add(H, B, B); /**/ + add(B, B, H); /* B(l1) = 3*(x1 - z1^2)*(x1 + z1^2) */ + /*=====*/ + /* normalization */ + lnorm(B, B); /**/ + /*=====*/ + sqr_dual(U, B, /* U = l1^2 */ + y2, V); /* y2 = 16*y^2 */ + /*=====*/ + sub(x2, U, x2); /* x2 = 4*p + l1^2 - 2*l2 */ + add(x2, x2, M4); /**/ + div2(y2, y2); /**/ + /*=====*/ + sub(U, A, x2); /* U = 8*p + l2 - x2 */ + add(U, U, M8); /**/ + /*=====*/ + /* normalization */ + norm(U, U); /**/ + /*=====*/ + mul_dual(z2, T, *z1, /* z2 = 2*y1*z1 */ + U, U, B); /* U = B(l1)*(A(l2) - x2) */ + /*=====*/ + sub(y2, U, y2); /* y2 = 2*p + B(l1)*(A(l2) - x2) - y2(l3) */ + add(y2, y2, M2); /**/ + /*=====*/ + /* normalization */ + norm_dual(r->x, x2, /**/ + r->y, y2); /**/ + lnorm(r->z, z2); /**/ + return; +} + +IPP_OWN_DEFN(void, gesm2_add, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p, const PSM2_POINT_IFMA* q)) { + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * + * A = x1*z2^2 B = x2*z1^2 C = y1*z2^3 D = y2*z1^3 + * E = B - A F = D - C + * x3 = -E^3 - 2*A*E^2 + F^2 + * y3 = -C*E^3 + F*(A*E^2 - x3) + * z3 = z1*z2*E + */ + const fesm2* x1 = &p->x; + const fesm2* y1 = &p->y; + const fesm2* z1 = &p->z; + const mask8 p_is_inf = FESM2_IS_ZERO(p->z); + + const fesm2* x2 = &q->x; + const fesm2* y2 = &q->y; + const fesm2* z2 = &q->z; + const mask8 q_is_inf = FESM2_IS_ZERO(q->z); + + fesm2 x3; + fesm2 y3; + fesm2 z3; + x3 = y3 = z3 = setzero_i64(); + + const fesm2 M2 = FESM2_LOADU(psm2_x2); /* 2*p */ + const fesm2 M4 = FESM2_LOADU(psm2_x4); /* 4*p */ + const fesm2 M8 = FESM2_LOADU(psm2_x8); /* 8*p */ + + fesm2 U1, U2, S1, S2, H, R; + U1 = U2 = S1 = setzero_i64(); + S2 = H = R = setzero_i64(); + + mul_dual(S1, *y1, *z2, /* s1 = y1*z2 */ + U1, *z2, *z2); /* u1 = z2^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(S1, S1, /**/ + U1, U1); /**/ + /*=====*/ + mul_dual(S2, *y2, *z1, /* s2 = y2*z1 */ + U2, *z1, *z1); /* u2 = z1^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(S2, S2, /**/ + U2, U2); /**/ + /*=====*/ + mul_dual(S1, S1, U1, /* s1 = y1*z2^3 (C) */ + S2, S2, U2); /* s2 = y2*z1^3 (D) */ + /*=====*/ + /* normalization */ + lnorm_dual(S1, S1, /**/ + S2, S2); /* (need by correct compute F = D - C) */ + /*=====*/ + mul_dual(U1, *x1, U1, /* u1 = x1*z2^2 (A) */ + U2, *x2, U2); /* u2 = x2*z1^2 (B) */ + /*=====*/ + /* normalization */ + lnorm_dual(U1, U1, /**/ + U2, U2); /**/ + /*=====*/ + sub(R, S2, S1); /* r = D - C (F) */ + sub(H, U2, U1); /* h = B - A (E) */ + + /* checking the equality of X and Y coordinates (D - C == 0) and (B - A == 0) */ + const mask8 f_are_zero = FESM2_IS_ZERO(R); + const mask8 e_are_zero = FESM2_IS_ZERO(H); + const mask8 point_is_equal = ((e_are_zero & f_are_zero) & (~p_is_inf) & (~q_is_inf)); + + __ALIGN64 PSM2_POINT_IFMA r2; + r2.x = r2.y = r2.z = setzero_i64(); + if ((mask8)0xFF == point_is_equal) { + gesm2_dbl(&r2, p); + } + + add(R, R, M2); /**/ + add(H, H, M2); /**/ + /*=====*/ + /* normalization */ + norm_dual(R, R, /**/ + H, H); /**/ + /**/ + mul_dual(z3, *z1, *z2, /* z3 = z1*z2 */ + U2, H, H); /* u2 = E^2 */ + /*=====*/ + /* normalization */ + lnorm_dual(z3, z3, /**/ + U2, U2); /**/ + /**/ + mul_dual(z3, z3, H, /* z3 = (z1*z2)*E */ + S2, R, R); /* s2 = F^2 */ + mul(H, H, U2); /* h = E^3 */ + /*=====*/ + /* normalization */ + lnorm(H, H); /**/ + /*=====*/ + mul(U1, U1, U2); /* u1 = A*E^2 */ + sub(x3, S2, H); /* x3 = F^2 - E^3 */ + add(x3, x3, M2); /**/ + add(U2, U1, U1); /* u2 = 2*A*E^2 */ + mul(S1, S1, H); /* s1 = C*E^3 */ + sub(x3, x3, U2); /* x3 = (F^2 - E^3) -2*A*E^2 */ + add(x3, x3, M4); /**/ + /*=====*/ + sub(y3, U1, x3); /* y3 = A*E^2 - x3 */ + add(y3, y3, M8); /**/ + /*=====*/ + /* normalization */ + norm(y3, y3); /**/ + /**/ + mul(y3, y3, R); /* y3 = F*(A*E^2 - x3) */ + sub(y3, y3, S1); /* y3 = F*(A*E^2 - x3) - C*E^3 */ + add(y3, y3, M2); + + /* normalization */ + norm_dual(x3, x3, /**/ + y3, y3); /**/ + lnorm(z3, z3); /**/ + + /* T = p_is_inf ? q : T */ + FESM2_MASK_MOV(x3, x3, p_is_inf, *x2); + FESM2_MASK_MOV(y3, y3, p_is_inf, *y2); + FESM2_MASK_MOV(z3, z3, p_is_inf, *z2); + + /* T = q_is_inf ? p : T */ + FESM2_MASK_MOV(x3, x3, q_is_inf, *x1); + FESM2_MASK_MOV(y3, y3, q_is_inf, *y1); + FESM2_MASK_MOV(z3, z3, q_is_inf, *z1); + + /* r = point_is_equal ? r2 : T */ + FESM2_MASK_MOV(x3, x3, point_is_equal, r2.x); + FESM2_MASK_MOV(y3, y3, point_is_equal, r2.y); + FESM2_MASK_MOV(z3, z3, point_is_equal, r2.z); + + r->x = x3; + r->y = y3; + r->z = z3; + + return; +} + +IPP_OWN_DEFN(void, gesm2_add_affine, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p, const PSM2_AFFINE_POINT_IFMA* q)) { + /* + * Algorithm (Gueron - Enhanced Montgomery Multiplication) + * + * A = x1 B = x2*z1^2 C = y1 D = y2*z1^3 + * E = B - A(x1) F = D - C(y1) + * x3 = -E^3 - 2*A(x1)*E^2 + F^2 + * y3 = -C(y1)*E^3 + F*(A(x1)*E^2 - x3) + * z3 = z1*E + */ + /* coordinates of p (jacobian projective) */ + const fesm2* x1 = &p->x; + const fesm2* y1 = &p->y; + const fesm2* z1 = &p->z; + const mask8 p_is_inf = FESM2_IS_ZERO(p->z); + + /* coodinate of q (affine) */ + const fesm2* x2 = &q->x; + const fesm2* y2 = &q->y; + const mask8 q_is_inf = (FESM2_IS_ZERO(q->x) & FESM2_IS_ZERO(q->y)); + + fesm2 x3; + fesm2 y3; + fesm2 z3; + x3 = y3 = z3 = setzero_i64(); + + const fesm2 M2 = FESM2_LOADU(psm2_x2); /* 2*p */ + const fesm2 M4 = FESM2_LOADU(psm2_x4); /* 4*p */ + const fesm2 M8 = FESM2_LOADU(psm2_x8); /* 8*p */ + + fesm2 U2, S2, H, R; + U2 = S2 = H = R = setzero_i64(); + + mul_dual(R, *z1, *z1, /* R = z1^2 */ + S2, *y2, *z1); /* S2 = y2*z1 */ + /*=====*/ + lnorm_dual(R, R, /**/ + S2, S2); /**/ + /*=====*/ + mul_dual(U2, *x2, R, /* U2 = x2*z1^2 (B) */ + S2, S2, R); /* S2 = y2*z1^3 (D) */ + /**/ + sub(H, U2, *x1); /* H = B - A (E) */ + add(H, H, M8); /**/ + sub(R, S2, *y1); /* R = D - C (F) */ + add(R, R, M4); /**/ + /*=====*/ + norm_dual(H, H, /**/ + R, R); /**/ + /**/ + mul(z3, H, *z1); /* z3 = z1*E */ + /**/ + sqr_dual(U2, H, /* U2 = E^2 */ + S2, R); /* S2 = F^2 */ + /**/ + lnorm(U2, U2); /**/ + /**/ + mul(H, H, U2); /* H = E^3 */ + /**/ + lnorm(H, H); /**/ + /**/ + mul_dual(U2, U2, *x1, /* U2 = A*E^2 */ + y3, H, *y1); /* y3 = C*E^3 */ + /**/ + add(x3, U2, U2); /* x2 = 2*A*E^2 */ + sub(x3, S2, x3); /* x3 = F^2 - 2*A*E^2 */ + add(x3, x3, M4); /**/ + sub(x3, x3, H); /* x3 = F^2 - 2*A*E^2 - E^3 */ + add(x3, x3, M2); /**/ + /**/ + sub(U2, U2, x3); /* U2 = A*E^2 - x3 */ + add(U2, U2, M8); /**/ + norm(U2, U2); /**/ + mul(U2, U2, R); /* U2 = F*(A*E^2 - x3) */ + sub(y3, U2, y3); /* y3 = F*(A*E^2 - x3) - C*E^2 */ + add(y3, y3, M2); /**/ + + /* normalization */ + norm_dual(x3, x3, /**/ + y3, y3); /**/ + lnorm(z3, z3); /**/ + + const fesm2 ONE = FESM2_LOADU(PSM2_R); + /* T = p_is_inf ? q : T */ + FESM2_MASK_MOV(x3, x3, p_is_inf, *x2); + FESM2_MASK_MOV(y3, y3, p_is_inf, *y2); + FESM2_MASK_MOV(z3, z3, p_is_inf, ONE); + + /* T = q_is_inf ? p : T */ + FESM2_MASK_MOV(x3, x3, q_is_inf, *x1); + FESM2_MASK_MOV(y3, y3, q_is_inf, *y1); + FESM2_MASK_MOV(z3, z3, q_is_inf, *z1); + + r->x = x3; + r->y = y3; + r->z = z3; + return; +} + +IPP_OWN_DEFN(int, gesm2_is_on_curve, (const PSM2_POINT_IFMA* p, const int use_jproj_coords)) { + /* + * Algorithm + * + * y^2 = x^3 + a*x + b (1) + * + * if input + * * Jacobian projection coordinate (x,y,z) - represent by (x/z^2,y/z^3,1) + * * Affine coodinate (x/z^2,y/z^3,z/z=1) + * + * mult formala (1) by z^6 + * + * y^2 = x^3 + a*x*z^4 + b*z^6 + */ + const fesm2 M6 = FESM2_LOADU(psm2_x6); + const fesm2 a = FESM2_LOADU(psm2_a); + const fesm2 b = FESM2_LOADU(psm2_b); + + fesm2 rh, Z4, Z6, tmp; + rh = Z4 = Z6 = tmp = setzero_i64(); + + sqr(rh, p->x); /* rh = x^2 */ + /* rh = x*(x^2 + a*z^4) + b*z^6 = x*(x^2 - 3*z^4) + b*z^6 */ + if (0 != use_jproj_coords) { + sqr(tmp, p->z); /* tmp = z^2 */ + lnorm(tmp, tmp); /**/ + /**/ + sqr(Z4, tmp); /* z4 = z^4 */ + lnorm(Z4, Z4); /**/ + mul(Z6, Z4, tmp); /* z6 = z^6 */ + lnorm(Z6, Z6); /**/ + /**/ + add(tmp, Z4, Z4); /* tmp = 2*z^4 */ + add(tmp, tmp, Z4); /* tmp = 3*z^4 */ + /**/ + sub(rh, rh, tmp); /* rh = x^2 - 3*z^4 */ + add(rh, rh, M6); /**/ + norm(rh, rh); /**/ + /**/ + mul_dual(rh, rh, p->x, /* rh = x*(x^2 - 3*z^4) */ + tmp, Z6, b); /* tmp = b*z^6 */ + /**/ + add(rh, rh, tmp); /* rh = x*(x^2 - 3*z^4) + b*z^6 */ + } + /* rh = x*(x^2 + a) + b */ + else { + add(rh, rh, a); /* rh = x^2 + a */ + lnorm(rh, rh); /**/ + mul(rh, rh, p->x); /* rh = x*(x^2 + a) */ + add(rh, rh, b); /* rh = x*(x^2 + a) + b */ + } + lnorm(rh, rh); /**/ + + /* rl = Y^2 */ + sqr(tmp, p->y); /* tmp = y^2 */ + lnorm(tmp, tmp); /**/ + + /* from mont */ + from_mont(tmp, tmp); + from_mont(rh, rh); + + const mask8 mask = FESM2_CMP_MASK(rh, tmp, _MM_CMPINT_EQ); + return (mask == 0xFF) ? 1 : 0; +} + +#undef add +#undef sub +#undef mul +#undef sqr +#undef div2 +#undef norm +#undef from_mont +#undef mul_dual +#undef sqr_dual +#undef norm_dual + +static __NOINLINE void clear_secret_context(Ipp16u* wval, + Ipp32s* chunk_no, Ipp32s* chunk_shift, + Ipp8u* sign, Ipp8u* digit, + PSM2_POINT_IFMA* R, PSM2_POINT_IFMA* H, + PSM2_AFFINE_POINT_IFMA* A) { + *wval = 0; + *chunk_no = 0; + *chunk_shift = 0; + *sign = 0; + *digit = 0; + + if (NULL != R) + (*R).x = (*R).y = (*R).z = setzero_i64(); + if (NULL != H) + (*H).x = (*H).y = (*H).z = setzero_i64(); + if (NULL != A) + (*A).x = (*A).y = setzero_i64(); + return; +} + +__INLINE mask8 is_eq_mask(const Ipp32s a, const Ipp32s b) { + const Ipp32s eq = a ^ b; + const Ipp32s v = ~eq & (eq - 1); + const Ipp32s msb = 0 - (v >> (sizeof(a) * 8 - 1)); + return (mask8)(0 - msb); +} + +#define WIN_SIZE (5) + +static void table_get_point(PSM2_POINT_IFMA* r, const Ipp32s digit, const PSM2_POINT_IFMA tbl[]) { + const Ipp32s idx = digit - 1; + + __ALIGN64 PSM2_POINT_IFMA R; + R.x = R.y = R.z = setzero_i64(); + + for (Ipp32s n = 0; n < (1 << (WIN_SIZE - 1)); ++n) { + const mask8 mask = is_eq_mask(n, idx); + + FESM2_MASK_MOV(R.x, R.x, mask, tbl[n].x); + FESM2_MASK_MOV(R.y, R.y, mask, tbl[n].y); + FESM2_MASK_MOV(R.z, R.z, mask, tbl[n].z); + } + + r->x = R.x; + r->y = R.y; + r->z = R.z; + return; +} + +#define dbl_point gesm2_dbl +#define add_point gesm2_add +#define neg_coord(R, A) (R) = fesm2_neg_norm((A)) +#define add_point_affine gesm2_add_affine + +/* r = n*P = (P + P + ... + P) */ +IPP_OWN_DEFN(void, gesm2_mul, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p, const Ipp8u* pExtendedScalar, const int scalarBitSize)) { + /* default params */ + __ALIGN64 PSM2_POINT_IFMA tbl[(1 << (WIN_SIZE - 1))]; + + __ALIGN64 PSM2_POINT_IFMA R; + __ALIGN64 PSM2_POINT_IFMA H; + + fesm2 negHy; + negHy = setzero_i64(); + R.x = R.y = R.z = setzero_i64(); + H.x = H.y = H.z = setzero_i64(); + + /* compute tbl[] = [n]P, n = 1, ... , 2^(win_size - 1) + * tbl[2*n] = tbl[2*n - 1] + p + * tbl[2*n + 1] = [2]*tbl[n] + */ + /* tbl[0] = p */ + tbl[0].x = p->x; + tbl[0].y = p->y; + tbl[0].z = p->z; + + /* tbl[1] = [2]*p */ + dbl_point(/* r = */ (tbl + 1), /* a = */ p); + for (int n = 1; n < ((1 << (WIN_SIZE - 1)) / 2); ++n) { + add_point(/* r = */ (tbl + 2 * n), /* a = */ (tbl + 2 * n - 1), /* b = */ p); + dbl_point(/* r = */ (tbl + 2 * n + 1), /* a = */ (tbl + n)); + } + + Ipp16u wval; + Ipp8u digit, sign; + mask8 mask_neg; + const Ipp32s mask = ((1 << (WIN_SIZE + 1)) - 1); /* mask 0b111111 */ + Ipp32s bit = scalarBitSize - (scalarBitSize % WIN_SIZE); + + Ipp32s chunk_no = (bit - 1) / 8; + Ipp32s chunk_shift = (bit - 1) % 8; + + if (0 != bit) { + wval = *((Ipp16u*)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + } else { + wval = 0; + } + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, /* w = */ WIN_SIZE); + table_get_point(/* r = */ &R, /* digit = */ (Ipp32s)digit, /* tbl = */ tbl); + + for (bit -= WIN_SIZE; bit >= WIN_SIZE; bit -= WIN_SIZE) { + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u*)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, /* w = */ WIN_SIZE); + table_get_point(/* r = */ &H, /* idx = */ (Ipp32s)digit, /* tbl = */ tbl); + + neg_coord(negHy, H.y); + + mask_neg = (mask8)(~(sign - 1)); + FESM2_MASK_MOV(H.y, H.y, mask_neg, negHy); + add_point(/* r = */ &R, /* a = */ &R, /* b = */ &H); + } + + /* last window */ + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); + dbl_point(&R, &R); +#if (WIN_SIZE == 5) + dbl_point(&R, &R); +#endif + + wval = *((Ipp16u*)(pExtendedScalar + 0)); + wval = (wval << 1) & mask; + + booth_recode(/* sign = */ &sign, /* digit = */ &digit, /* in = */ (Ipp8u)wval, /* w = */ WIN_SIZE); + table_get_point(/* r = */ &H, /* idx = */ (Ipp32s)digit, /* tbl = */ tbl); + + neg_coord(negHy, H.y); + + mask_neg = (mask8)(~(sign - 1)); + FESM2_MASK_MOV(H.y, H.y, mask_neg, negHy); + + add_point(/* r = */ &R, /* a = */ &R, /* b = */ &H); + + r->x = R.x; + r->y = R.y; + r->z = R.z; + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, &H, NULL); + return; +} + +#include "sm2/ifma_ecprecomp7_sm2.h" + +/* affine */ +#define BP_WIN_SIZE BASE_POINT_WIN_SIZE +#define BP_N_ENTRY BASE_POINT_N_ENTRY + +__INLINE void extract_point_affine(PSM2_AFFINE_POINT_IFMA* r, + const SINGLE_PSM2_AFFINE_POINT_IFMA* tbl, + const Ipp32s digit) { + const Ipp32s idx = digit - 1; + + __ALIGN64 PSM2_AFFINE_POINT_IFMA R; + R.x = R.y = setzero_i64(); + + for (Ipp32s n = 0; n < (1 << ((BP_WIN_SIZE)-1)); ++n, ++tbl) { + const mask8 mask = is_eq_mask(n, idx); + + FESM2_MASK_MOV(R.x, R.x, mask, FESM2_LOADU(tbl->x)); + FESM2_MASK_MOV(R.y, R.y, mask, FESM2_LOADU(tbl->y)); + } + + r->x = R.x; + r->y = R.y; + return; +} + +IPP_OWN_DEFN(void, gesm2_select_ap_w7_ifma, (BNU_CHUNK_T * pAffinePoint, const BNU_CHUNK_T* pTable, int index)) { + __ALIGN64 PSM2_AFFINE_POINT_IFMA ap; + + extract_point_affine(&ap, (SINGLE_PSM2_AFFINE_POINT_IFMA*)pTable, index); + + ap.x = fesm2_from_mont(ap.x); + ap.y = fesm2_from_mont(ap.y); + + fesm2_convert_radix52_radix64(pAffinePoint, ap.x); + fesm2_convert_radix52_radix64(pAffinePoint + PSM2_LEN64, ap.y); +} + +IPP_OWN_DEFN(void, gesm2_mul_base, (PSM2_POINT_IFMA * r, const Ipp8u* pExtendedScalar)) { + const SINGLE_PSM2_AFFINE_POINT_IFMA* tbl = &ifma_ec_sm2_bp_precomp[0][0]; + + __ALIGN64 PSM2_POINT_IFMA R; + __ALIGN64 PSM2_AFFINE_POINT_IFMA A; + fesm2 Ty; + R.x = R.y = R.z = setzero_i64(); + A.x = A.y = setzero_i64(); + Ty = setzero_i64(); + + Ipp16u wval; + Ipp8u digit, sign; + const Ipp32s mask = ((1 << (BP_WIN_SIZE + 1)) - 1); /* mask 0b11111 */ + Ipp32s bit = 0; + Ipp32s chunk_no, chunk_shift; + + wval = *((Ipp16u*)(pExtendedScalar + 0)); + wval = (Ipp16u)((wval << 1) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + neg_coord(Ty, A.y); + mask8 mask_neg = (mask8)(~(sign - 1)); + FESM2_MASK_MOV(A.y, A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + + for (bit += BP_WIN_SIZE; bit <= 256; bit += BP_WIN_SIZE) { + chunk_no = (bit - 1) / 8; + chunk_shift = (bit - 1) % 8; + + wval = *((Ipp16u*)(pExtendedScalar + chunk_no)); + wval = (Ipp16u)((wval >> chunk_shift) & mask); + + booth_recode(&sign, &digit, (Ipp8u)wval, BP_WIN_SIZE); + extract_point_affine(&A, tbl, (Ipp32s)digit); + tbl += BP_N_ENTRY; + + /* A = sign == 1 ? -A : A */ + neg_coord(Ty, A.y); + mask_neg = (mask8)(~(sign - 1)); + FESM2_MASK_MOV(A.y, A.y, mask_neg, Ty); + + /* R += A */ + add_point_affine(&R, &R, &A); + } + + r->x = R.x; + r->y = R.y; + r->z = R.z; + + /* clear secret data */ + clear_secret_context(&wval, + &chunk_no, &chunk_shift, + &sign, &digit, + &R, NULL, &A); + return; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecpoint_sm2.h b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecpoint_sm2.h new file mode 100644 index 000000000..682fd3a1e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecpoint_sm2.h @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +/* Paper referenced in this header: + * + * [1] "Enhanced Montgomery Multiplication" DOI:10.1155/2008/583926 + * + */ + +#if !defined(_IFMA_ECPOINT_SM2_H_) +#define _IFMA_ECPOINT_SM2_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "sm2/ifma_arith_psm2.h" +#include "pcpbnuimpl.h" + +/* SM2 point (x,y,z) */ +typedef struct PSM2_POINT_IFMA { + fesm2 x; + fesm2 y; + fesm2 z; +} PSM2_POINT_IFMA; + +/* SM2 affine point (x,y) */ +typedef struct PSM2_AFFINE_POINT_IFMA { + fesm2 x; + fesm2 y; +} PSM2_AFFINE_POINT_IFMA; + +/** + * \brief + * + * compute R = [pExtendedScalar]*P = (P + P + ... + P) + * + * \param[out] r point (in radix 2^52) + * \param[in] p point (in radix 2^52) + * \param[in] pExtendedScalar ptr Extended scalar + * \param[in] scalarBitSize size bits scalar + */ +IPP_OWN_DECL(void, gesm2_mul, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p, const Ipp8u* pExtendedScalar, const int scalarBitSize)) + +/** + * \brief + * + * compute R = [pExtendedScalar]*BasePoint + * + * \param[out] r point (in radix 2^52) + * \param pExtendedScalar ptr scaler (length 256 bits) + */ +IPP_OWN_DECL(void, gesm2_mul_base, (PSM2_POINT_IFMA * r, const Ipp8u* pExtendedScalar)) + +/** + * \brief + * + * convert point to affine coordinate + * + * \param[out] r point affine coordinate + * \param[in] a point + */ +IPP_OWN_DECL(void, gesm2_to_affine, (fesm2 px[], fesm2 py[], const PSM2_POINT_IFMA* a)) + +/** + * \brief + * + * check point on curve SM2 + * + * \param[in] p point (in radix 2^52) + * \param[in] use_jproj_coords is Jacobian Projection coordinate or Affine Coordinate + * \return int 1 - is true | 0 - is false + */ +IPP_OWN_DECL(int, gesm2_is_on_curve, (const PSM2_POINT_IFMA* p, const int use_jproj_coords)) + +/** + * \brief + * + * compute double point SM2 (Enhanced Montgomery Algorithm) + * + * \param[out] r point + * \param[in] p value point (in radix 2^52) + */ +IPP_OWN_DECL(void, gesm2_dbl, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p)) + +/** + * \brief + * + * compute add point SM2 (Enhanced Montgomery Algorithm) + * + * \param[out] r point + * \param[in] p first point (in radix 2^52) + * \param[in] q second point (in radix 2^52) + */ +IPP_OWN_DECL(void, gesm2_add, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p, const PSM2_POINT_IFMA* q)) + +/** + * \brief + * + * compute add point affine SM2 (Enhanced Montgomery Algorithm) + * + * \param[out] r point + * \param[in] p first point (in radix 2^52) + * \param[in] q second affine point (in radix 2^52) + */ +IPP_OWN_DECL(void, gesm2_add_affine, (PSM2_POINT_IFMA * r, const PSM2_POINT_IFMA* p, const PSM2_AFFINE_POINT_IFMA* q)) + +/** + * \brief + * + * Extracts affine point from the precomputed table. + * + * \param[out] pAffinePoint array of x and y coordinates of affine point in 2^64 radix + * \param[in] pTable pointer to a precomputed table + * \param[in] index index of desired point in the table + */ +IPP_OWN_DECL(void, gesm2_select_ap_w7_ifma, (BNU_CHUNK_T * pAffinePoint, const BNU_CHUNK_T* pTable, int index)) + +#include "sm2/ifma_arith_method_sm2.h" +#include "gsmodstuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" + +__INLINE void recode_point_to_mont52(PSM2_POINT_IFMA* pR, + const BNU_CHUNK_T* pP, + BNU_CHUNK_T* pPool, + ifmaArithMethod* method, + gsModEngine* pME) { + ifma_import to_radix52 = method->import_to52; + ifma_encode p_to_mont = method->encode; + + const int elemLen = GFP_FELEN(pME); + + BNU_CHUNK_T* pX = pPool; + BNU_CHUNK_T* pY = pPool + elemLen; + BNU_CHUNK_T* pZ = pPool + 2 * elemLen; + + GFP_METHOD(pME)->decode(pX, pP, pME); + GFP_METHOD(pME)->decode(pY, pP + elemLen, pME); + GFP_METHOD(pME)->decode(pZ, pP + 2 * elemLen, pME); + + pR->x = to_radix52((Ipp64u*)pX); + pR->y = to_radix52((Ipp64u*)pY); + pR->z = to_radix52((Ipp64u*)pZ); + + pR->x = p_to_mont(pR->x); + pR->y = p_to_mont(pR->y); + pR->z = p_to_mont(pR->z); +} + +__INLINE void recode_point_to_mont64(IppsGFpECPoint* pR, + PSM2_POINT_IFMA* pP, + BNU_CHUNK_T* pPool, + ifmaArithMethod* method, + gsModEngine* pME) { + ifma_export to_radix64 = method->export_to64; + ifma_decode p_from_mont = method->decode; + + const int elemLen = GFP_PELEN(pME); + BNU_CHUNK_T* pX = pPool; + BNU_CHUNK_T* pY = pPool + elemLen; + BNU_CHUNK_T* pZ = pPool + 2 * elemLen; + + pP->x = p_from_mont(pP->x); + pP->y = p_from_mont(pP->y); + pP->z = p_from_mont(pP->z); + + to_radix64((Ipp64u*)pX, pP->x); + to_radix64((Ipp64u*)pY, pP->y); + to_radix64((Ipp64u*)pZ, pP->z); + + GFP_METHOD(pME)->encode(ECP_POINT_X(pR), pX, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Y(pR), pY, pME); + GFP_METHOD(pME)->encode(ECP_POINT_Z(pR), pZ, pME); +} + +#endif // (_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ECPOINT_SM2_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecprecomp7_sm2.h b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecprecomp7_sm2.h new file mode 100644 index 000000000..e0cb44e5f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_ecprecomp7_sm2.h @@ -0,0 +1,2536 @@ +/******************************************************************************* + * Copyright (C) 2021 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ +#if !defined(_IFMA_ECPRECOMP7_SM2_H_) +#define _IFMA_ECPRECOMP7_SM2_H_ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "pcpgfpecstuff.h" + +#include "sm2/ifma_defs_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" + +typedef struct SINGLE_PSM2_AFFINE_POINT_IFMA { + __ALIGN64 Ipp64u x[PSM2_LEN52]; + __ALIGN64 Ipp64u y[PSM2_LEN52]; +} SINGLE_PSM2_AFFINE_POINT_IFMA; + +#define BASE_POINT_WIN_SIZE (7) +#define BASE_POINT_N_ENTRY (1 << ((BASE_POINT_WIN_SIZE)-1)) + +extern const __ALIGN64 SINGLE_PSM2_AFFINE_POINT_IFMA ifma_ec_sm2_bp_precomp[37][BASE_POINT_N_ENTRY]; + +#if !defined(_DISABLE_ECP_SM2_HARDCODED_BP_TBL_) + +const __ALIGN64 SINGLE_PSM2_AFFINE_POINT_IFMA ifma_ec_sm2_bp_precomp[][BASE_POINT_N_ENTRY] = { +{ +/* digit=0 [{1,2,3,..,}]*([2^0]*G) */ + {{0x0001167a5f72d7b5,0x000c43181404d9e9,0x000e6dbd3aaf42f3,0x00024c3c33e7981e,0x0000654979a299ac}, {0x0003cd65d4e5a49b,0x0008384568872dd6,0x0008f0fffbcf430c,0x0002a48f8c1f5e57,0x00009272f196066e}}, + {{0x000d7e9c18d8240f,0x000aaa6e417d56a0,0x000a3b0e4550d595,0x00088cd2483bdc9b,0x0000832b6de84b57}, {0x00047e746600a032,0x000d7b7693b68c19,0x000859275c90d69f,0x0007157acccbd8d3,0x00005bc85177169b}}, + {{0x000019fd6c2ea279,0x000d0917cb6254a3,0x000a0b6907791b62,0x000eb4a0a2676528,0x0000d038c8d3308c}, {0x0008ad3478846130,0x000f770c6ce91902,0x000bb07902d865c4,0x000c13c97f40aa52,0x00002d50aa9bfa6d}}, + {{0x0000dc8e3b19766a,0x000581f7eeae6605,0x000039ddf04401d9,0x0009f9020487ea28,0x00001ca3fd26b4a0}, {0x000ffc31c595b91b,0x000797e67a87e986,0x000aec6fb58321c6,0x000cf70ed1de135e,0x0000a8e2c4f05632}}, + {{0x000f443ef3733cb4,0x000cb3ff75fcd620,0x000231240b46fe4f,0x000f5f4c515aa58f,0x0000acee1008bf1e}, {0x000b4152768f6bb9,0x0003d1943d948337,0x000e5ea1cf8e42ac,0x0002258efb30f4bb,0x0000df40ee234c36}}, + {{0x0005e74ca112a1cc,0x0001baaf82ba6ba8,0x0005e46613dca025,0x000e34db6b1274a2,0x0000e903fc536e5d}, {0x000568bc9800f516,0x000a645b374d537b,0x00007f00118f53d1,0x00030e9848fbf6d2,0x0000221155fdf8ec}}, + {{0x000bf492e195f07f,0x0001de5ebffe884b,0x0003c307b8018431,0x000fe18c50b89419,0x00000a1adeda69ac}, {0x000ba05a8f672532,0x0000d327ed0e66d2,0x000ea11a5c476cbf,0x000d99baf0e449a2,0x000006fdeeeb922b}}, + {{0x00015c2fc0eb2070,0x0007a5b1df1b6701,0x000a3428b0cdb816,0x00087df9e90be6f2,0x0000f4f38ed34143}, {0x00077fd5f39cf758,0x000c519eaa1d82ae,0x0001c9fb549748ab,0x0008f3382693b350,0x00003b68d86b6f9a}}, + {{0x0007d88740be6daa,0x000b882728e34867,0x000622fa36cfdf7c,0x0008669b48e5e049,0x000008f7936983b4}, {0x00022a6c24b493eb,0x0000a36e3e719ce8,0x0008bd29b04cc229,0x000a6e96963c563a,0x0000711254fc6553}}, + {{0x000e8237d906e272,0x00063b15d4a3f432,0x00085b93464a3fd4,0x00088728eecdb60d,0x000063eef3231b13}, {0x00031bbfda8cd29f,0x0004821c3dc4be1e,0x000a4a6263ce10f0,0x000dd716508c65d1,0x000015073445b5d7}}, + {{0x00083da169291613,0x0009c670b0bce154,0x00080eed9d6a0bfd,0x0005092677557c8c,0x00003202222cfd8a}, {0x00028398a7eae7b7,0x000180bd61f72bf5,0x0001683a9ec60b3b,0x0002c587d5dd8402,0x00006a86e659db9f}}, + {{0x00090ea13d89cc69,0x000255069e37462b,0x00018fe68620e964,0x0008d4f0789f3850,0x000031ef3cf56a9d}, {0x0006bd39ee352fe8,0x0000667570e4332b,0x000673b80d8ed70b,0x000385ffafa48d5c,0x0000a591652ce762}}, + {{0x000c80c9d04d2808,0x0005a9a32d8f64e3,0x000dc6453311458c,0x000bc2b2e7da2bdf,0x00002cb3a3b11de1}, {0x0005fa508acb12e2,0x0007d33fce2e44d4,0x0004849da0dcd4c6,0x000ec55f9aef09eb,0x0000eae191c31b26}}, + {{0x000f8babeb190812,0x0000a4e094c1dc30,0x000ced3824c7aa66,0x00074d0533f194a6,0x000002c062f92d6f}, {0x000f6cd2b110e9a8,0x00091ab321a1a47f,0x000bbc8af71c2e8f,0x0009b55adfe0c027,0x0000ebfab3c299b6}}, + {{0x000df89411540793,0x000923289e1ea4d0,0x000ac9ab62313957,0x000ddf2219c14e38,0x000002798dfc11cf}, {0x000c5c1e9ea4d4d6,0x000aa6fced9ad262,0x0008fa2e93406f8c,0x000885947d9be66a,0x000020846630e236}}, + {{0x000d01076ee1cd74,0x000cd5a581b2d20c,0x00093f74bd090be1,0x000f4639d7121d6b,0x0000c74662a9ce8e}, {0x000a4759c17b4394,0x000acd91ba3bb8a6,0x0000bf7a5d3f3801,0x0003c5c62b07e323,0x000082838a70c166}}, + {{0x000e33014346c3a9,0x000095088fa55ffb,0x000107c9d987c4a3,0x000f2b6584a31dd2,0x0000ff8f6b14a019}, {0x000da3bda2d72e1e,0x000953e595c8241b,0x00053ede9ccb4205,0x000cdc439cbf5da2,0x000018a52a7858cd}}, + {{0x000617c54f3a57d1,0x0009e6cda402d38f,0x000dcba397c6a7df,0x00017bfe48ed8eea,0x0000a909b54de6b4}, {0x000b7154885c6b51,0x00052ad21227839e,0x00060f8cff874f5d,0x0007e8e972e6a3a7,0x0000255f5e75e5e0}}, + {{0x0002d8e3f61e46a0,0x000ef8a682a8116e,0x00086b27e23bfa6a,0x0009e513f9b9e970,0x0000e27f60beec8c}, {0x0003246dbc6eb4e8,0x000255fe0d47ce4e,0x0003d805a7b4087e,0x0009af4f3ee12d06,0x0000dffd18b1c09a}}, + {{0x0008e3e09541188e,0x0006b0d2ff10201a,0x000abedec872090a,0x00069c20e3d876d4,0x000087ecb8de0f7b}, {0x000da6987805758b,0x00077a3929596b9a,0x00032632c2a7c1aa,0x0007d153d274c1de,0x000090621fde36d4}}, + {{0x000f01e019ea2472,0x000266cb630aa808,0x0000f49041d7deaa,0x0009350681611dea,0x00003d0a0dce821b}, {0x000abe5cc3f2bfb4,0x000d5418bd40f896,0x000e02ff3a27ab02,0x000e86399ce4ac99,0x000049d0896d001d}}, + {{0x000dbc0b894bb4f4,0x0002e20681014988,0x0001f9c1e48b7e8e,0x0006bcc8cbd44336,0x0000923926eb0c2c}, {0x000005bcfa05f5a4,0x000429e49d6299a7,0x000c78170090ecdb,0x0005f7927afb6fed,0x00000a0af6725bb3}}, + {{0x000f6ae59570ee69,0x000423cbdcc1639d,0x00074bb372d8a3e0,0x0006915c4c7c42e7,0x0000354c77faf967}, {0x0001bb84d9312a64,0x000a22b967527d11,0x0000bbd1e7d36ed8,0x0006f2599638cb07,0x000082f920f072ba}}, + {{0x000668304566ea9f,0x000c5a73b2b5ea29,0x0001b72e0dfb6f53,0x00068c65d19de7a9,0x0000b028d8339d06}, {0x000f529385702e1f,0x000b15aaaac89ff3,0x000446feccaf4f3e,0x000f06e44bc53bc2,0x00009f9c624cb5d9}}, + {{0x000e53aa7d49eafb,0x000cdac9d5e2826d,0x000fe4b7a2a6312c,0x0008cfdc13addc3d,0x0000b1d9952c6972}, {0x00071e68556c226a,0x000774683bb5d64a,0x000bb10c1848b985,0x0003d48c9d605474,0x000068340188b965}}, + {{0x00092bed74888d36,0x000cbce275c0fb58,0x000e72fe273b12ce,0x0002e80de91707e7,0x0000db762f73c5fb}, {0x0003605d1822de60,0x000264f60af612d9,0x000d43631ab3bd6b,0x0004629df73fd298,0x0000cfe82714262c}}, + {{0x000746a77aa308aa,0x0001a9c30737acc0,0x0002eb6e3ed4ce48,0x000f943a95bb54ee,0x00006010a8bdd232}, {0x000560e7e5cf332c,0x000be9efdeac35b0,0x000f8b7e87813782,0x0002181fb9421fe7,0x00000340a99e9269}}, + {{0x0007671e24561bb4,0x00000d8f762de2a3,0x00001886c3580ffe,0x0007956cd67f42a4,0x00002cf5abf25b97}, {0x000de5ed1dcc00e4,0x000478255fa3c47b,0x000bf3c02988a494,0x0007bba59141f96f,0x000072ac7d2040d2}}, + {{0x0003afcc938edfa0,0x000981cc61252576,0x000913c163700794,0x00002d5bdecb033c,0x0000e4e3c5ff4d82}, {0x0001d8f4668b50d7,0x0007cd2a51338b78,0x000edd0f0b7e280a,0x000f0bbe8dc91387,0x0000219bfbb5cbf8}}, + {{0x0007c9d827edc576,0x000d568cf9f5796f,0x0003c6b070fad2a5,0x000143c45bc8ac15,0x0000c8cc3708f7a1}, {0x000c780d9d193ed6,0x0007191b007b950e,0x000ab8ba8c708175,0x000ad5467340f445,0x000052592b31e902}}, + {{0x000802fb3eb3d841,0x000e04d04b1868a7,0x000982cd2e03b6ec,0x0001b9a36069a7ab,0x00006f98bd625e59}, {0x0004e2dfb27220ca,0x0007d60b11ba4ebf,0x000e42ff9a6e1785,0x000e36f3b18c612a,0x0000d89ac35c73c0}}, + {{0x00050e3e71fd4a23,0x000f7f7b071198b5,0x000ba19d01ea4efc,0x000f0a982d78af40,0x00007cfcfdcb0d03}, {0x0001c52fadb094b5,0x000950490fa2f5bb,0x0003b956e911832b,0x00047e33b5297cf4,0x0000601800188ccc}}, + {{0x00091c76dcf25dc1,0x00000084b5c6b0ec,0x0008cb89c5ee1953,0x000f206fba6c6844,0x00001903b72eb3c3}, {0x0009f9329b4a17d7,0x0005e366f36057c5,0x0007b0a7b8ab0858,0x000734400dfb20ce,0x0000db8842f3d9d8}}, + {{0x0003c17aa0e9a859,0x000f26b39a949a9e,0x000ca30e12c38332,0x000068df9575c1e1,0x00009178ba1bca31}, {0x0001ea1386258de0,0x000e8ea2a8ea6306,0x00082a7454b4a9cb,0x0000492d7ad24091,0x00003d94af9fb739}}, + {{0x000bd0a4c60f2724,0x000c9bd244c18bc3,0x000063be261d339f,0x00071ad908da622a,0x0000c90f49d55404}, {0x0005922faeaab30b,0x00008552e7fd4231,0x00008fb1810871af,0x000375b0f859ed94,0x000046581a19632a}}, + {{0x0002eab5669ebb2b,0x0004708bb2fef9b6,0x000fe7fc9aa83744,0x00090c3213ee8cc1,0x00003abf92585915}, {0x0009761c3595cedf,0x0006a92651244ab0,0x000f2886cba43860,0x000a8ac5d83b89ab,0x0000e8dc6841ec1d}}, + {{0x0009fed874184a69,0x000fdea655ea6c93,0x000d96c14ff60a53,0x000268939458e5ff,0x000084dc3eef11b9}, {0x00041b5b6de8e246,0x0007a0b14c452ccd,0x00027d8f16bd2bb6,0x0009b725bb028dc2,0x0000572ecdca9ee2}}, + {{0x000130b4de2895f9,0x0005f439cc75e202,0x0002c214bff765f8,0x0000651a5b628ccb,0x0000c56a9a48fe00}, {0x0004695e9be17d1b,0x00041f854faac0fd,0x0009ccfdbc214556,0x00069ae44fdcdb03,0x00007edcab584c41}}, + {{0x000e3590f168d2b1,0x000339e9acab36da,0x000f5f613429ffb6,0x00023e7d6983b7a2,0x00005c48a5be3e59}, {0x000d83804d41f76e,0x000c0e774de782a4,0x0004cbc3ab5f71cc,0x000ae8e01b15b054,0x00003bee4f4f1362}}, + {{0x000b014c73ee1325,0x00054d9da08a3283,0x00083663a292e2bc,0x000c2fa93b16ed9d,0x0000813ab0c77049}, {0x000434a3b15969fc,0x000b5b49bda3732d,0x0005c2f25b7357d1,0x000ce9480b6457d5,0x000006200abb3a4c}}, + {{0x00045b268a2411df,0x0005891671a913cc,0x0003cf1240da7743,0x000b948d5605bba5,0x00004b4552738e3d}, {0x000ea61903ca09a3,0x000f0db2771a4bd7,0x000aad4157e88d82,0x00061433957627a5,0x00004ab7fd350a66}}, + {{0x000e4964e7611bb9,0x000295adae74d432,0x000d8cac7948a4d6,0x000c3da9c7112bb3,0x0000028720a3c72b}, {0x000903eadc6af862,0x000266a7dbde62a9,0x000bbdd6677a6604,0x0007c5f888f772fc,0x0000717d5496d7ca}}, + {{0x000a1261ea8c6488,0x000ca2d55afe929b,0x0003b29c6c19e3fc,0x000283f973ccef5c,0x0000a10539a87a90}, {0x000b7937899af0f6,0x00050bf36f6aa1c7,0x00060f93ea46df3f,0x000a0668b373f1cd,0x0000948b79142119}}, + {{0x00008f8d46c0616e,0x0005754a372e43dd,0x000bc0c92bf53994,0x000a2a74df8df2cb,0x0000da1b4aba6922}, {0x000b4c696835e3a0,0x000565c909e53769,0x000987ddf078fecb,0x00008f50f3a8e25c,0x0000ab1518d04d06}}, + {{0x000cc1c4cbf2eada,0x0000b07cccf2a3b4,0x00073637b5075beb,0x0002cbb01aff4f89,0x0000cbdd0a13bdae}, {0x000af408e2bf7bff,0x000a5c0ca6d44b87,0x000590425f3ca33c,0x0002bced68c4d27e,0x0000860daa597e7f}}, + {{0x0006fe7e8c09b138,0x00085228df4d5e7c,0x000d0b002f39288d,0x0009113f99774834,0x0000f38034f3008a}, {0x000e75ecfbf60757,0x000c0515ee009c8c,0x0001dffbf3bde851,0x0003cd7b9f7b0540,0x00001d4b51f20fec}}, + {{0x000f73502b13dfd6,0x0000f6bfe31b4bdb,0x0004c8f0f3d24ad0,0x000df99852ba6e75,0x00007531d7f6850f}, {0x00076e3627f19150,0x000acfbce9c4ce08,0x00036c4b44a54a01,0x00043b9b4580491e,0x000069d8a672d2ae}}, + {{0x00006262266ce0ea,0x0007ceb468278ecf,0x0007246abb7f770e,0x00070c62b11c5a9f,0x00004d940c70f297}, {0x000a1dd93504b336,0x000c58ae56addebf,0x0002c8778a299d26,0x000826f34db89297,0x0000216c1d191d4f}}, + {{0x000d757d105035e9,0x0000892525eeeea3,0x000b8207d3ab24fe,0x000dd86c38699063,0x000048ba86d3e9a8}, {0x000543f2cf2834f5,0x000c4f1160cf0568,0x000be874b4e8fd83,0x00084d925a64595e,0x0000d3990d091ae1}}, + {{0x000e9af8e18b884c,0x00003c1132459043,0x000b64b2b57c9247,0x000641003b9843a4,0x00006be6b120ee1b}, {0x0008b29a50338313,0x0007739485c6ac24,0x00020bd7e43e2261,0x000cd2f42c7c7494,0x000007104b3c5bab}}, + {{0x00075df6aa322652,0x0008438ee19c58e7,0x000f0e751ca64953,0x000ee2cc1ceff8f3,0x0000007cbe08fafc}, {0x0005d3fe7d60d02b,0x000f86971b9f6cc4,0x000af3ff81584de1,0x000e38e96e8b86ad,0x0000c8a5afe65086}}, + {{0x000c0c2ef468013e,0x000447a6a3e240d9,0x000ce19f2d3f4f80,0x000f5b1d82e8fa8a,0x0000a47b981fb33a}, {0x0006f55f89eb0100,0x000573f986d93e93,0x00003f8e75c98dfb,0x000a00d1be6eb587,0x00006025306d77dc}}, + {{0x0005004985706114,0x0003a99c2255a574,0x00039ede58b41f12,0x00057962df076847,0x00004155be8eedab}, {0x0000393d7b59e2eb,0x0004af37b669d889,0x0001361a3ce556fd,0x000088c50176ce1a,0x0000ab255f00efdc}}, + {{0x000f2508973a0049,0x000e1a9999674ce0,0x000b7ed788a7049c,0x00076b0df4215b78,0x00003fc339599f2f}, {0x0008a181cc31d786,0x00004b008af5a09e,0x0006e20a280096e6,0x000aefa786ef0ad9,0x0000708a7fb34b8e}}, + {{0x000ecd84e8002ca5,0x0006e4c51e07c6d3,0x000605339c03f827,0x000e29d372b2ef6b,0x00009294965e1f2c}, {0x0008e0d1f90738b6,0x000ea3c21f6272c6,0x0002e51519ef8f60,0x000ea3fdf6d43936,0x00004958f256a93e}}, + {{0x0002ae43cded4986,0x0008c0786370d1e5,0x000d72bfe828c06d,0x000de1ca387f03fa,0x0000fe77288924ef}, {0x0005c10049922062,0x0001e1b0f661a1bf,0x00078e2792579aa8,0x000f50251dd874f6,0x0000e1fb6309e4fc}}, + {{0x000ccd7fbba38366,0x0006a2f5d13d7662,0x0000c2887037a707,0x000822e131ce6676,0x0000ab184d3f7174}, {0x0000417ce21feaac,0x000ba6783f71e187,0x000c16456fd30111,0x0002534b61beb5bb,0x000057298cddd196}}, + {{0x000938b88b271119,0x000cdf7ba43a3002,0x0008b28d3c70b643,0x000ff1e445a0b19e,0x0000e8d8708505a0}, {0x000b509b7bcaa8da,0x0004889cc6d3bc35,0x000c1b8dbbb4f0d8,0x00076ce646be6d56,0x000064c9e731d2c4}}, + {{0x00068a9aaae04721,0x00049c19bd83c3bb,0x000c97a89201474f,0x0007e36f61e60b19,0x00008e006d3601e3}, {0x000264283d8cd6ac,0x000a26d694677ca3,0x00050811d256561a,0x000f93bb86344083,0x0000be34e422eda5}}, + {{0x000f8047fec93faa,0x00073131b791a8e2,0x00020dd5c4c96fd6,0x000b598413ee227a,0x000003f52b6a9a3c}, {0x0000a3aa35db586e,0x000e80870eb165fc,0x000407776015d23f,0x00014524d484ac18,0x00007d7bd4527603}}, + {{0x0007d6e92e359c6f,0x000b32a6697b084d,0x00085cc819e78cf5,0x000e64343264911a,0x0000b8665b43083e}, {0x000987117e217dc3,0x000f6ea5f2ff0fb6,0x000d0aba23bc49fd,0x000e1da50005ab33,0x00006631cedcfd42}}, + {{0x0006861e633bad54,0x0009090870f777a7,0x000efcf8e7ed6758,0x00048f60795ddd3e,0x000066e4b07a455f}, {0x00057bcc2dcfcebf,0x0009631b8b2b3172,0x000c4e0e7bda1bfd,0x00084c79157e95b6,0x0000dfc62d4f9b9e}}, + {{0x000229bde0a25f6d,0x000c029e3fcf95af,0x000222ea492c862b,0x000ec26fcddc3afe,0x00003df0533d4aef}, {0x00093afe4a6dc67d,0x000928563cb37395,0x000db3baa6ee4ad4,0x0006c1219f41b8f6,0x0000aed543421b6f}}, + {{0x0003d9b4b1683537,0x00027fca4ce53d4f,0x000429ff213ff55b,0x000978dcef44d3df,0x0000c87265aec8bc}, {0x0008adaee633517a,0x0000f9e83600b2c5,0x00046726aded6663,0x000c242380cd02ed,0x00003bc51cfc7e49}}, +}, +{ +/* digit=1 [{1,2,3,..,}]*([2^7]*G) */ + {{0x0003f6205b429ade,0x0008bf1c0a4e32ae,0x00022c7d1370668b,0x0006f3f11ba4f98a,0x00003ef4e616f3e6}, {0x000eda7e2acd29f6,0x000cb5cda51a38f4,0x0007e42471db7ebf,0x0003a61d62c9b445,0x000045ac20585b53}}, + {{0x000e1431a0e449d7,0x000b00a18c82a340,0x0009ce6b623dbfa8,0x000726ce7b22b908,0x0000257d316c6584}, {0x000316fa44c65236,0x000abdf21e2c9a6a,0x000fa681abf2e073,0x00024b68464198dd,0x0000b20d3821b191}}, + {{0x00047be60cbe754a,0x000f718c602db135,0x00077d7fb8185623,0x0007f9aeed67c8ab,0x0000af29dafc6215}, {0x000785ec118bf7e4,0x000eb16620c35dba,0x000199925c15e48d,0x000c1ccda92fa080,0x000033aa09cb45cd}}, + {{0x0008bb37bbc8eaff,0x000c954d84c1ba41,0x00006d707a0a6cc6,0x00064269baff481a,0x00008b85ca90fd0e}, {0x000470e9650bf952,0x0004614637082390,0x000f1b05fe17e127,0x000e19ae44e27a58,0x0000d28ce5f3ca66}}, + {{0x00030cd9e7bba66b,0x0002a47d0f6c9f6f,0x000f98fa70856f4b,0x0006d7ae2af062ff,0x0000407848c30d3a}, {0x000ad179dbe5e183,0x00081bb63f0280dd,0x000e0af2bc5b9ef5,0x000814831cfa3aa4,0x000057f28a37fd0a}}, + {{0x000045cccc33ac82,0x00041300a514028b,0x000e69aa5701e6de,0x0005a99b5c0bae0a,0x0000570e393aab01}, {0x0008b5223fabe3c9,0x00035b4958105bd7,0x00093e95309ea81e,0x00079468e41e71fc,0x00006d2120c20644}}, + {{0x0008216623c8051a,0x000974d15e695a2b,0x0000ed4105279fa7,0x000b0efdc15ffcce,0x00008407c2795c45}, {0x000e93eb01f7bc66,0x000aabb5b8017b63,0x00053f362f01a15a,0x000e5aaeaf3866d1,0x00003fe8d5b0e2a0}}, + {{0x0007e4a6bab88bb5,0x000ac749feb21e8b,0x00068a9ac9915331,0x0005411d793c48f8,0x00004c41659fc83e}, {0x0006563f1f63710c,0x000b29b8e532f2ea,0x000f494986fd6c33,0x00009638f46578c7,0x0000487d3b7f6df0}}, + {{0x00099ffa74b0a131,0x00003c57e9ff5e74,0x00041fcef932469d,0x000943242ecc22d1,0x00006e8a53cc4b10}, {0x00053e70b02ce3d3,0x0000f7bfea4c6526,0x000f62519e5d6a4f,0x000cebfd7945f306,0x00003029e98b8415}}, + {{0x000328a51d2191fb,0x000aa9835ebb3353,0x0006ddec4b72ed65,0x000c31d009d2f054,0x00005adafdcd98fa}, {0x00033a5443f17c91,0x000464a519cce4e8,0x00062cd2554ecc5b,0x00047ccb6657f4ba,0x0000ea376f2b8440}}, + {{0x0008bc857ba2453a,0x000354b27eeba2be,0x0003efa1af80516d,0x0009be57220a5103,0x0000fe282dac550a}, {0x000b6dd98b001e61,0x0001d5dc16564000,0x000e0a4e87ba6cd5,0x0004d1decf33a87f,0x0000a1f0885f20c6}}, + {{0x0005611ee5405eb8,0x0008bb358c3e290d,0x0008f2d2f416d96a,0x000e3a8b7a6840bc,0x0000f3c09d0c0771}, {0x0001b7ebe5a31b29,0x000072918a3d173b,0x000c77a4349cc89d,0x000dea0ec6082dba,0x0000e943c639dfbb}}, + {{0x0009c5a35b857733,0x000b43af66b31410,0x000618bc27427626,0x000dd611df52cb1b,0x0000dea20d731f39}, {0x000a53863aaa59ac,0x000287d564c29a15,0x000e07486f27f2f6,0x000cc58c64e300dd,0x00008bb7806200b4}}, + {{0x000e6cf633beb827,0x0007541ee6485223,0x000f064e09c8e331,0x000479c4a2008653,0x000005672dd401d9}, {0x0002ef49575fc255,0x000fb1756ee1946b,0x000faaa78a620586,0x00078458d74c45db,0x0000286229ac59c2}}, + {{0x000f183d4950bd4e,0x0006829e2dd608d3,0x00024b281ebe2bef,0x0005d5ac1a775b95,0x0000ffcbf6fa1b5d}, {0x000c6f7a38b05932,0x0009a4d54018e45e,0x000735a43f67590e,0x0006365280498d29,0x000083d04586749b}}, + {{0x000a36193b229fdd,0x000d6a1f04e7a9d7,0x000b81137c112f74,0x0001d75822a9a12a,0x000092df75029907}, {0x000e19344b0a3b18,0x0004947df3b965bf,0x0003ac1801a2dec0,0x00014686de82c871,0x000005c6bebc40f7}}, + {{0x0003e45d0a32fcee,0x0005a7fa4a4a3aeb,0x0004023d27d3a94b,0x000a1159700a2516,0x0000f05f61efb8e4}, {0x00094cf5c5dd948a,0x000c6eb880b4b16a,0x000f504d1ef5ec3c,0x000cd2d4d99cf64d,0x0000e533ca08d4f2}}, + {{0x00022bc0f01f06e1,0x0001254579a83be0,0x000ba95a583c43a3,0x00031de06bd83e20,0x00002d83f0a341da}, {0x000a009dec653ef8,0x000a9def081681f6,0x00021b6942705a2a,0x00043026da1504f9,0x0000091f0e90b112}}, + {{0x000572cecfe7bf86,0x000ee8278a5f0508,0x0006508e5c6e542b,0x000b6af13a5bbd8f,0x0000f885cd1a4781}, {0x0008a541d84528e9,0x000447f8ada787a5,0x0006f2151fe114b5,0x000878e13175c476,0x0000495badfdb204}}, + {{0x000325396578ba7e,0x000f1d5b140820f9,0x000f5534905a956f,0x000b7ba771977a8d,0x00007dbdca2d6fc5}, {0x00060a74da50d8cb,0x0006557137368856,0x000e0eaff086fcbc,0x00033a7ba6c24de9,0x0000d539d80b8c55}}, + {{0x000e7fac53e5832a,0x000d1e7a73f7e66c,0x0009be7bb912cbb5,0x00008b9b169f23f1,0x00005bf337922a53}, {0x0002b5e9ce1f9bdc,0x0008af5eaec7f01a,0x000e559ad53c6d06,0x000d4b81bd375c03,0x000065d670d2c170}}, + {{0x000cf320046dae34,0x0003dc84af3ffc3d,0x0009110ca683092d,0x000d3d8dc44ef5dd,0x0000146ddfa12279}, {0x00091848ad843b2e,0x000e677ff21f464c,0x0008d7eea9091dcf,0x00044e760768c865,0x00001e2755ed17fc}}, + {{0x0008a20903a4deda,0x00053f20c8da65f4,0x000dc571a79e0955,0x000122dd7b74cc0e,0x00001f3b1489237b}, {0x00074eec705b4e7f,0x000b345d9736c54a,0x0000f9d3c9235647,0x0009c2ee431a3c33,0x0000a634b54e5906}}, + {{0x0008d3493802aedd,0x0007f6143720a39a,0x00079ce8e3d24e2a,0x000b745b17663a59,0x0000ba7c742c42b4}, {0x00008e23e6376d36,0x000eb442027cbdff,0x0004192ba0107cd9,0x000f3d3711d81bbe,0x00001954cdd874dd}}, + {{0x0008536eb6e977e0,0x00031c30a317f04a,0x000150b5cecb8ce9,0x0006ae3ac0b43e66,0x0000c0d72af52624}, {0x0005a628eb6b6cae,0x0002cf4928e1e625,0x00001afda0667e5a,0x0007f4265f3de227,0x0000cf11f93b8c0d}}, + {{0x0001910c3b106232,0x000b54c4e6c94ee9,0x000dbb97ce7d0b7e,0x000f00a7d4aefda2,0x00000a5704423357}, {0x00005307a4979c43,0x00049a5bc7522d2f,0x00044591f664b2c8,0x0004e020b15ed1b9,0x0000304591f7dbd2}}, + {{0x0002e01cb8acccaf,0x000db23b53a5142b,0x00077554ae226c41,0x000098d0174d7152,0x000044df36341e6f}, {0x000ed3679f629911,0x0008282c8aa57cdc,0x00046fbfad702a88,0x000e5b3ac8eb84b0,0x000001d5d3e16826}}, + {{0x000a64b76a2ec18e,0x00078c3aead2a764,0x000aeda893a50823,0x000054515bd98ad9,0x0000ae9054cb0356}, {0x000b64e7f5d86a85,0x00000fd39ede8e65,0x000fd4dbcfc6de80,0x0002a0a6b04984a9,0x00003c88762946cd}}, + {{0x0002fee193a647ca,0x000b670c4033ee6b,0x0001643aa02f7b4a,0x00087114e66f3146,0x0000e357bcb2874d}, {0x0008627cf129e3fd,0x000a292529e30056,0x000cf7e52e3bc05f,0x0005f1b5d8d50c49,0x0000864bce4c6e0f}}, + {{0x000ad7991fa05182,0x0004decea29a2582,0x000bb694041f373a,0x000e6989d82ab62b,0x0000931b87e7d76c}, {0x0005776952079845,0x0006358770640105,0x00085f9043a52233,0x000f00fdcb296a03,0x000059005bf4862b}}, + {{0x000cc11e5684c1b7,0x000e3f8f8bc1e41e,0x0008eb1d9286e66e,0x0000297b1812feac,0x000066f0a15d3e34}, {0x00096054a3178eff,0x0000bc29acc99c03,0x00023c25e83fcc7b,0x000147c408a07b0d,0x0000ddb2c5c07623}}, + {{0x000976011b1bc461,0x00060f0107f30719,0x0007818994a2a18f,0x0000776333ff85ee,0x00003e669ead7d8f}, {0x00054bbcc73bbbba,0x0000ed0af38e5638,0x00005b56c91358c0,0x000b3df90dff2123,0x0000265625f4bbba}}, + {{0x000db00f4b4772bf,0x000145e2b12b3c1c,0x0003c88be095cc1c,0x00090b61b8a4923a,0x0000344af5ccf9cd}, {0x0009dcc691662dd8,0x000962a4096193de,0x000145eaab6e7b80,0x000a2e933dee45c3,0x0000dda44baf48fb}}, + {{0x000d5d161871cf5e,0x000bf96b711c1622,0x0001b7c2140db6c3,0x0004fb357c8e120a,0x000091f47ad1dff2}, {0x0001508663c0622f,0x00026c2d6643c86f,0x000fb96dbf23d874,0x000f766581d547ca,0x0000da7eebc0a4d0}}, + {{0x000c00bde07e9500,0x00040dcbd4ee582e,0x000af33a5075386f,0x0006f9598d9f545b,0x0000ff588a64a467}, {0x000a474e6ea6e85c,0x0001ea51b156b584,0x000fb3e7504d1e38,0x00007f044e32f572,0x0000d5ab75d376b9}}, + {{0x000b47dc0dc20f02,0x00003326e2aa2b72,0x000a2cd6bec5fb3e,0x0007365f285de9ba,0x00008bcea35cebfd}, {0x0002605ff74f7a52,0x0003aafb4968c25b,0x000ac9d2a2b84e45,0x00004ff873ba7a11,0x000063946120e765}}, + {{0x000ea745b0f8807a,0x000e9d8587aa16bb,0x0001307a4103df44,0x000b78e0498dc118,0x00004e9d7e40f8a1}, {0x0008dcff7bc5f923,0x00065ad9cdec8732,0x0008b45d8a3f4963,0x000ca219f7b76513,0x0000644e1c93afd0}}, + {{0x000d04a8b55db72c,0x000f435dabbc4a91,0x0008fcbaeb67078e,0x000bbdfc9b2f2124,0x000019e43abb0f65}, {0x0003be91f3aae668,0x000f8a9736725587,0x00016e8f3bc10c21,0x00040ec4a74ee5e2,0x0000c0d08c02ae5a}}, + {{0x0006ce7146590851,0x00020187d3713eba,0x000d38a163074e6b,0x000cdbf349943c34,0x000053c9b5c6d74f}, {0x000e1b66247a7101,0x00069c95293b8e92,0x000d7308e5ba5fc1,0x000136280b9ebeb8,0x00008f80fc44a55d}}, + {{0x000b576e500ea398,0x000b82245cf3e7b2,0x0008f9cbc2bec6cc,0x0001d58f77345037,0x0000cdd0554e6eea}, {0x000cc7ccaae38d62,0x000534c4be5c6035,0x0000fc56156e4977,0x0004f1cf337aea39,0x0000ee6f49181e94}}, + {{0x00079d789c195287,0x00027477408790a6,0x0000930aceb86101,0x0006cbe2723b0edd,0x0000392b0905f00d}, {0x00088b89f8858b86,0x0007f3db1a0ba159,0x000ffe03a89fc719,0x0000201ba5da50ba,0x00006a863f2cd455}}, + {{0x0001a4387e58a913,0x000648acceb75521,0x0007521152b339f5,0x000d2dd874036bbb,0x000041757e920823}, {0x000a54437646ae42,0x00019047e92f959e,0x0006f40a3de71463,0x00075397ce58940c,0x0000ebb7ab93546a}}, + {{0x000a1b010e4aab26,0x000e3c5617a973ad,0x00044532982b8675,0x000a969681bed3c3,0x00007d4f1ae7cdba}, {0x0009ae9fffe1232f,0x000e65305444e20d,0x0006fe785b41f639,0x0004120e08eac5d0,0x0000aaa419560e8f}}, + {{0x000758b9c8293920,0x0008c6cbfbe97afe,0x000e690a1af49bfb,0x0004203981fcd743,0x00000b943f7aa23d}, {0x000f5a347a711abb,0x000b1d90df6603b8,0x000e12a3bbabc3a5,0x0008154f4b9ee0a5,0x0000c0badc5131ea}}, + {{0x000d8fbf079db722,0x0003ab9c82633610,0x000e51bbae11705a,0x0004eff476c3420f,0x0000c6baf02761a6}, {0x0009a0b4c2b16f08,0x00045aaf34d60563,0x0007d8efd5c37a31,0x0002406427c1b59a,0x00008f17aca33851}}, + {{0x00076f86426c3280,0x00065a8f5c36655c,0x000a66bb836ec14c,0x000111b0275c4c04,0x00005124ac1a1510}, {0x0005aa9d9a40b2c9,0x0002362d7acf7364,0x00073b575ab0d288,0x00008cff853212bd,0x0000e58faa0c1f04}}, + {{0x0001293d9c195932,0x000eef2d6ea5365d,0x00041ddd78506af1,0x0002081d18e3a2ee,0x0000175ed7253823}, {0x000cab1223717464,0x00081eaf69bff654,0x000231c48aeca4f3,0x000a6a4d3a8f27aa,0x00008dde1551daa6}}, + {{0x000901ca13309f4b,0x000cc1b25d3b7455,0x000e3ab715f6fdc0,0x00089282b9a04c15,0x0000c045df01cfee}, {0x000d75e0c168f76d,0x000e0171344f2fd0,0x0005435774ec19e9,0x00056bece16d3efb,0x0000be9d895f073b}}, + {{0x000a4a40e4749395,0x0003734cc0308f44,0x000ce52d8c15a3ea,0x000e8df3075e4632,0x00004bbedaed5c68}, {0x00006feb5915c0d9,0x000949c11a211e9d,0x00019a13bc8bd809,0x000ff23cfa204cd8,0x0000b0ba02c5fdd1}}, + {{0x00054deaaba5d8eb,0x000a6f6362a3502a,0x0007aa9e44e1e1d7,0x000cb2b299a780e5,0x000070536c702e08}, {0x00097282cef3adbd,0x000014bed566650a,0x000e5203d864d70e,0x000ddd1dc2014b85,0x00008605d670e497}}, + {{0x0000ad950d9dd8e2,0x0001a65713c77ad9,0x0003175ee249e6a4,0x00060f1892e877fa,0x0000ea9facbe9436}, {0x0009dfd972df6c3e,0x000cbedb2b8203e3,0x00058343fdd04e5e,0x0003d97ebfc1bf8d,0x00003e108caa72ac}}, + {{0x000b277b4f2aa16d,0x0008230545a5016c,0x0002e2769b2435ab,0x0002779964fdc84e,0x00002e12bff6b35c}, {0x0006dbbcbe4dd215,0x0009cf4e0ff812c7,0x0000e963f1c305f5,0x0005e69a0be36a64,0x00007762740fc054}}, + {{0x000c36a9138a7f68,0x0008470ee63806de,0x000cb7255647a569,0x0007fd1b252fccff,0x00007c9171f47258}, {0x00097ff34fc8093d,0x0008de7129a90bdd,0x0000a742e5f26310,0x00051c078b3f740a,0x00003fd65a14fa19}}, + {{0x000341e2c79fcc59,0x000d996d461221d7,0x000e9d32b3c02d65,0x000bf9b355c0b280,0x0000b04f743f16ea}, {0x000c8edc4bc3438f,0x00096016b5362987,0x00010d7d0315dd2e,0x000a6516e8c2661c,0x00009b5fb13a3567}}, + {{0x000012645f461429,0x00093cfe4e77bfe0,0x0000678940510b04,0x000c3c83e76847ae,0x0000aff2f45006a2}, {0x000568a45e9f4ac7,0x00003ec5016c2bdf,0x0000224802e6c323,0x0008a3781ba7f616,0x0000b608cbc8aa43}}, + {{0x0006e23886af7a22,0x0004d87701710104,0x000dd4329762ec47,0x000b0c85a529a29f,0x0000ca8eb75290d6}, {0x000944765a1f3112,0x0004526223465ae1,0x0008b3e5061d9db9,0x000c05c301f5a96a,0x00003eea325d3356}}, + {{0x000ea3fbc35ccbaf,0x0003d0980f8881d4,0x000742058b853b8f,0x000a93c1cd768f5a,0x0000aed3d20d113d}, {0x000f0613da6d40d8,0x000bfc5a47958e97,0x00078f3cffc06a56,0x000231aedfc6fba6,0x0000fe6d947b0cd3}}, + {{0x000959b0ed60b577,0x000f5ec0253c6f66,0x0008e5689b3f8d47,0x00064ea48fbc6376,0x000021581d29868b}, {0x0009abba118e8524,0x000b62a3b710d54d,0x00007ed07686fcbc,0x0002ac100d616b1a,0x00008f7e4edf5463}}, + {{0x000afd83d0bbed45,0x0009a4a423d92e83,0x0007efe97713bc6d,0x0002864fd29134cd,0x0000f105bf080515}, {0x00099d5c6362bc3b,0x000301adc72d227d,0x0007d741e5cbbe71,0x0003e8ec90a2b500,0x00002cb9449eed3c}}, + {{0x0007431dacc6cd8f,0x000327d0afc47ee7,0x0004cf1e41610068,0x00016c7df373dad7,0x00000042e51a0bb4}, {0x0000030244d5b5c0,0x00046436c0b767e7,0x000a283bcb615adb,0x0001f3281f151893,0x00002a5797383854}}, + {{0x000aa5a92ffbb0f3,0x000ddf4779f321c1,0x000d9726ba60bd3b,0x000141269fac0c6a,0x00009d33c89d1a6a}, {0x0001d981b6db934f,0x00097c858d13b960,0x00095003d1097326,0x000b1547c517a25b,0x000006db28fb4238}}, + {{0x00014be21fa8ba83,0x000723ee01b8bba9,0x00053235fc70e3a3,0x000854ee045851bf,0x000076061a1e3082}, {0x0000ed8989d0ade3,0x000e0475957e0684,0x0000b493f0327c6c,0x000c0eec5255cb9c,0x0000fb2ef57cd978}}, + {{0x0006e16fd686583d,0x00057ec048801ddf,0x00069f1cc520e3ff,0x000612fe4ef3e986,0x000004ce0c5522b7}, {0x00081124788f63ea,0x000409a1a13cbddd,0x000c67aaf921c06f,0x000d218fe7051bf6,0x00008b2ed76302fe}}, + {{0x000dfc779262f1ac,0x000f6f4b5df8fd32,0x000451c354acf03a,0x000b9cf87bbf3a89,0x0000202b08c85e13}, {0x000e0f0ccae32d7b,0x000d462b52f30d47,0x000ccba62aab00b8,0x0004cba64588a6eb,0x000032bdcd539457}}, +}, +{ +/* digit=2 [{1,2,3,..,}]*([2^14]*G) */ + {{0x000da81d1a2da736,0x00040521de498b84,0x0001c2d52e2068c9,0x00034dcbf6d4ec10,0x0000ea5880b663f8}, {0x0006df66b322ab71,0x000871f17ecb7ffc,0x0000f54419e4a898,0x00008b81cf1e389b,0x00007a05a6db6c73}}, + {{0x000d667d4f8e5a50,0x0005f26536b3c801,0x0004a16346a9cdbf,0x000ccbcf92ba9de0,0x0000fd5b3900eedf}, {0x00033c3069b93deb,0x000cf3b7ce8ad20c,0x000bd324a9a9bcab,0x000e5cfb2329a308,0x000095f2c48470ed}}, + {{0x0004bce015ccff87,0x000eb34d4a8f11bc,0x000721bc1cd438c9,0x0000827146cb5b70,0x0000a843732fe483}, {0x0001dd088c05eae6,0x0007da74df7bf31b,0x00093d301e85027f,0x0005ab37a147b28f,0x0000a2d230e7336c}}, + {{0x0007c5babcf7ea0d,0x000569819d685897,0x00078e0634866c49,0x0003879a283042ba,0x0000ab406b710c6e}, {0x000d69f7c9fd8080,0x000e1dc73087360a,0x000d64b5dfb2ca8d,0x00033828902da352,0x00009013008cdbe0}}, + {{0x000c1bee4cf1095b,0x000bd1666a4b713a,0x000b431e3d19fcc0,0x000938196d536753,0x00009b8e71621624}, {0x000a316451576162,0x000c76ddc87f3039,0x000e232d808e2b09,0x0006544735ee9f1f,0x000087a1d181f421}}, + {{0x000997691124b333,0x000d451eb882ca26,0x0000f886014ca42e,0x000749cbae97f712,0x000066796b2b5be8}, {0x00085f944d025c08,0x0007702f28a19d3f,0x000e61bdac26a8c0,0x000db2ea8aad567e,0x00008078a3f854ce}}, + {{0x00007ba56ac78d16,0x0009448f1d1d7ddb,0x000b3a1404a747c0,0x000254738fd1d565,0x00000fc34247734c}, {0x000dcc5f098ff4c6,0x000ef2299588fd1a,0x000526f2f3ca3291,0x000225dc6ae0385c,0x0000d29a013f2711}}, + {{0x000264880c2de156,0x000947380fee3995,0x0003cc64079cf1c7,0x0008da6ea4de174d,0x000003341f9f4354}, {0x000e8151f6e4ad1b,0x000bc54650c77ccc,0x000de287aa666044,0x000db0e21e16b6f4,0x0000efb7d194ac4c}}, + {{0x0007348efe215c9e,0x000a931c79ae7459,0x000bc87a3f8399b5,0x000a1bcc9091643d,0x0000c57a72438223}, {0x000cbcc9f0323ea7,0x0003f4633ae285d5,0x00075e694b36151f,0x000d0d5c1d1a3493,0x0000014dccf8288a}}, + {{0x00030900d2988954,0x0003e2d547c4b1d6,0x0003d769a258c9fd,0x00064ff7bf5754d0,0x00000bcff2e3a601}, {0x000995fcc5b48583,0x0002cf93957e8bcd,0x000d37ccadf3bf57,0x00031fc7dc53bffe,0x000071bb6556f9f8}}, + {{0x000f0306abec554b,0x000c8bc468067e3f,0x000d6238fc116a66,0x00069b8bd7796b94,0x0000a6558eced667}, {0x000af21c707b4feb,0x000a2aa0e68fd01b,0x0006f4d94f62eeee,0x0000ccb1d1af09d8,0x00003f1221391f32}}, + {{0x000eb563bf3376c9,0x0008f5d8ea00637f,0x000675ed8c7dbfa9,0x00051a85bac437f4,0x000037bf89c8189d}, {0x000ba46a66de87e9,0x000d24fe7e880662,0x000a387ef19a5076,0x0004953dbcdc6eb5,0x0000e2e1c4016e3e}}, + {{0x000f9b9bb42c0485,0x000ff2e8def6906c,0x000dacfee25d0f89,0x0001242fe1bc12ce,0x0000ba97a0a64232}, {0x0001c99c56cf201c,0x000d455c2ed2dbcd,0x000509787b117d3b,0x00095af8690b3a9b,0x0000417bd19de076}}, + {{0x000424aaeb3b91d4,0x000a998c13da2eb4,0x000c3d55be8eaf2e,0x000e03205c693bdb,0x0000fd5cf1c45d66}, {0x000d0f0a7ea7323d,0x0005a0440c0cb913,0x000e433cbef81c62,0x000ea78c3ad814d5,0x000070dbb0fed04a}}, + {{0x00090203a46ae630,0x0001c021ff3b323e,0x0008f647e46c84d1,0x00057306c16c8124,0x0000a93f9c553d27}, {0x0007068a29d80ae0,0x00066d1e92ca2f02,0x000d3c68f1fe6df3,0x000db0092823efe5,0x000043f0b8b11afd}}, + {{0x000ab7a126c29381,0x000d4f017773e3eb,0x00051c6ad9458693,0x0004188703c92ac9,0x00008d7d6ab30ed3}, {0x000fcc5e3f382814,0x0000f7ef5c71c3f7,0x0007acea6adea02a,0x000f418dc0bf1f23,0x0000b54ae9a11e38}}, + {{0x0002f3a2514a57f2,0x000755bd0ab98c69,0x000170e5611bc333,0x0001ad1373538876,0x0000a7a18cb1378a}, {0x0001b5efeee3ae1e,0x00054b58ddc3cceb,0x00036b1de1bda0d1,0x00035fe338e63f0a,0x000007514aeac9d8}}, + {{0x00012e9031f0a5ba,0x000cc72344d0cb10,0x000f9f81fac388f1,0x000819ec8de87114,0x000074f23945d20f}, {0x0003e7f085b71746,0x00040c6c0934c56a,0x00090588b97228a8,0x000b5a380052b408,0x0000fac86ae9306a}}, + {{0x000c5184d549deec,0x000d52b46bc9e417,0x000192f5462b2c21,0x000c8f8e355f7d23,0x0000cd177410648a}, {0x000d55e33cdefe21,0x000c7275af172a79,0x000eebe63c04f4ee,0x0007c713ff4aa0b7,0x00008d8307613e4b}}, + {{0x0004d3cd58e4d852,0x0006bab993f02b8b,0x00026693cfd3cf03,0x000af4e6d5408547,0x0000c2aabff8fa45}, {0x000a3c809ae43c50,0x000cf7a0f723e79e,0x00046edbbfbdccc1,0x000982a8cd0b6af1,0x00002b1e5a091517}}, + {{0x000fd07201deffac,0x00025809cadf872a,0x000cb98046995509,0x000ff21f4ff84d98,0x0000963d2bcbfe56}, {0x0002499093a6be69,0x000585326f80abc8,0x000f80d703b9d497,0x0001bfd4d58fc0e7,0x00004a60473ceb19}}, + {{0x000e5caaad4486b4,0x0005d1e24444b21e,0x000d3ed0c0b72819,0x000f982fc3cff018,0x00004ba520fa8898}, {0x000a25bbc397a8af,0x0002998611e20d76,0x000406e1ccb223d3,0x000b86f4e2652aa2,0x00009c27f8856e6a}}, + {{0x0009fc879466ceba,0x0001f18b2f8e875d,0x000210013a7160b9,0x000c7186305ed045,0x0000eb43ec41e200}, {0x0002cb32611aaefe,0x000c458e587ba1f1,0x0002c7fb38833b1b,0x0008800e363b5a76,0x00002467a594f1ce}}, + {{0x000404e6c71b8202,0x000e48bf41f295b4,0x0003bbd6407bf067,0x000844a0d45ccf07,0x0000dfc2ca06446e}, {0x0004dedc225205ce,0x00035847c15238fa,0x0001bcdcdbedad65,0x000bf3d178a82808,0x0000a8e3bc0a11ca}}, + {{0x0000c6ae5018d027,0x000a419015aee791,0x000bdfb1d84f73ff,0x000d4b9963b67b87,0x0000485df021db40}, {0x000ff3d64526fc0f,0x000809d05281ec5e,0x00034417b79ccca5,0x0008a68f1ced9e92,0x000084c11d3c4c8d}}, + {{0x000c1ee614663ebd,0x000eefc957140edb,0x0004cb8ebdd6ee14,0x000c319463886ccb,0x00003f1f77e17b13}, {0x0008c813d019b2ae,0x000ae3a496d29903,0x000b0b3353a94e2a,0x000af96c39382e3b,0x0000a718f3f170b3}}, + {{0x000c164496ab3d67,0x0006ea56a382dda6,0x000036dc6d5437ab,0x0008c51072a7b515,0x0000956b614be2c0}, {0x00073c805d2be046,0x000e2a99459dcad8,0x0005bf1a2e6a28d1,0x00042bc725dbc286,0x0000b972c00e8d03}}, + {{0x000aa44ce9e0496f,0x000a7518060ed141,0x000452f518ef97a7,0x000abccfd1dc35d3,0x000044605da47e0c}, {0x000f1fba3870f0ae,0x000ece7c99396b4b,0x000488733ee9559f,0x000e5da54cf3f91b,0x0000a28e5309a1c9}}, + {{0x0006d871fcfa1706,0x000e3b101284285a,0x0002d9406b0f302d,0x000121cb8a49debb,0x0000c65e2ed97a1e}, {0x0005b77a782ee91a,0x000a18fff5f1afba,0x0000590abfa71329,0x000f8f32227e83f1,0x000050dde9b93ce1}}, + {{0x0009607b794f0285,0x000f0c89ef49400c,0x00029e7554b7902b,0x000a03702d679b84,0x000027d77adc7fb0}, {0x000c9a2c835846f8,0x000d19300fc32289,0x000389f09dc87369,0x000449f520da060a,0x0000929d2a527a1a}}, + {{0x000d034270025e0c,0x0009dc6d5d8f5f46,0x0008b8bd0e581906,0x00031cd1e56e8bfe,0x0000ed5db268c8c6}, {0x000d7cfa60528665,0x0003499dd0753176,0x000a49d661bee9a9,0x00055f095fcec179,0x000078f295389204}}, + {{0x00010c7a09f07b72,0x00054a4f28f770b2,0x0000ebb86416fc49,0x000e678562cc3429,0x0000c146c66ed941}, {0x0006c78f44e0f9a9,0x000ed0e1730b01d2,0x000dd20b61e67d48,0x0004e94705fe8cc4,0x00004cb9e577978b}}, + {{0x0005b05d6914ffce,0x000bbcbc25e829c9,0x00064f5723a4258e,0x0009424439122bbc,0x000062a0f760a317}, {0x0008e2d3db0cdd63,0x0006e0a06d9aac8f,0x000ef51a43b76bd2,0x000e313b4e84259e,0x0000cd05a227ffe3}}, + {{0x0007a74f56626479,0x000ed3a968075def,0x0002063cf858014f,0x00060623e3b51455,0x0000d8a825e00c73}, {0x000803d1b3ff54bb,0x00057ca25942c21f,0x000b4932e5b4a102,0x0003a09d5ae52fa2,0x00001c461ac9803f}}, + {{0x000b28d11887efae,0x000ea168fa1b64e1,0x000b56a252fe844a,0x000dfae103e32b3d,0x000025b4f7dea5d3}, {0x000947e940ce1f1b,0x000ca48aa1767741,0x000a6ef9a8c24921,0x000739056310da94,0x0000c91e4f7cec0d}}, + {{0x000631d5545c61d7,0x000e9f1a5c65d6fa,0x00046c01c5cb2c3e,0x000b12160108765b,0x0000037e6b0239be}, {0x000f48f86beaf031,0x00003582003a33aa,0x0005101c310ecee8,0x000a3f604e6cbfb5,0x0000370d71300c7c}}, + {{0x0000b578f398f5c2,0x0002684aeddb0ff5,0x000a40bb38f9bc76,0x0008d0e81bf9c714,0x00005ffb3646b97a}, {0x0006781ae38091b4,0x0003bde34988e66e,0x00063bae09eddb66,0x0000f7f47a3c3027,0x0000045549bcc1b5}}, + {{0x000293017d41f805,0x00015b6e5b119f8a,0x0007fe0ad1dcef79,0x000dcb03d2f4f593,0x0000bc5de02b9ec2}, {0x000fe4bde4a50c54,0x00075fbe79e7001c,0x000f666fd4f9eba0,0x00036e2014942d8c,0x0000174ec1b3aeae}}, + {{0x000fca2c37292e34,0x000df0d50a803e6a,0x0009860576e3da8a,0x00016b82c8491f1a,0x0000f908c5eb3698}, {0x0007bce061481fee,0x0004ca0326e92580,0x0004ef03e64401e2,0x000e3e3b0b3335a2,0x00006a363fee2346}}, + {{0x0009631af51f3820,0x000310bcf577dfc0,0x0009a7fe9a4d5c89,0x0006e8e893b8e850,0x00004aa3176b18d3}, {0x000fe9e9998db107,0x00088de616ddcf17,0x0003cbbbcb14c557,0x00003faac8272dc8,0x0000f37f11c6d949}}, + {{0x000ba3b57ca7d9fb,0x000fd143f3a1d7db,0x000b58fe1aeb5b1f,0x0000b20f07391ec2,0x000053738f59c6e1}, {0x00071b4df4657720,0x00037c87c0c02e8f,0x00048a4dda850a8e,0x000c2bbecdb49b0f,0x00001e0e88fb7249}}, + {{0x00038cdac58335c3,0x000c66df86cb8aa1,0x000a5efe055d4c77,0x0008683ad1af4476,0x00001273e06eec8a}, {0x000a2ce980ef2516,0x000377fed539bad2,0x000293912c3a97cd,0x0005bf11b26fc0b7,0x00002701f2738b12}}, + {{0x0003ba8b2493b148,0x0007d81bf2ec5d3b,0x000ba5926cd37918,0x00003b04098e8707,0x0000993e2bf0b8df}, {0x000b9e789a25168f,0x00011110cc4fd0b4,0x000f73b82fcc0949,0x00025b8664697e9b,0x00008b52da34d004}}, + {{0x000c26b8aa6f79d5,0x000e067dcfb9770c,0x000edbc74258b6a8,0x0008a01b52d4c4ee,0x0000e4bcfdfaa83b}, {0x000fb6562627da7f,0x00009f556e31fea7,0x000812774e7e1710,0x00049a0c8d511a79,0x0000bbd260be01ec}}, + {{0x000722aab36249e1,0x0000a40db721fc3e,0x000026a00c5e1911,0x000d74549b846153,0x0000b622aadebdd0}, {0x000ca6686c5b5ea1,0x000292c7cbcce6e4,0x000fead6468bad0d,0x000bbc79632dbaa5,0x00008d702b3a959e}}, + {{0x000945ee8039f7f9,0x000e245d6a8c7bdc,0x00087d06e54cdf17,0x000783d6f1f6930d,0x0000551ed8a2334d}, {0x0008ab5b4cc0c954,0x000c9e84281ae650,0x0000185519e20a39,0x0007ef592eb5d96e,0x0000ec44157cc235}}, + {{0x000fa33716016f7e,0x000e46af2f5045d6,0x000a09af49a8fdb5,0x000e43c6a1cc8371,0x0000c277d0e603e7}, {0x00075a70fd1e4ccb,0x000139ebdaf3db97,0x000de03d23466af0,0x000a4a43866e1ef2,0x0000fdf225ba7f64}}, + {{0x000f14821c351edd,0x00021666bac77433,0x00028a88c1031a4f,0x00003eb20264c266,0x0000b50cc08ac4a3}, {0x000b467364f7c8ff,0x0009bc822547761a,0x000838d0cd7ef0bb,0x0004c66a947c25a3,0x0000d8d71347dba3}}, + {{0x000a2a39c57739c8,0x0003badbd20048ba,0x0002c2455087a0da,0x000600d3308eeb44,0x000035ab7e73bb70}, {0x00039893a9299ac7,0x000e1e5fae8a6704,0x00048b6bc37d45c8,0x0006000cec119be8,0x00002354d9fe710d}}, + {{0x00044539e0bf2fd6,0x0009b8e02b90f648,0x000d689709228660,0x0002c31506185413,0x000035c1a6a9b616}, {0x0002e4cfa6e7a7b9,0x000883f5b421e0bd,0x0006decae0701125,0x000ca3d924eb9b7e,0x00008973fbb6a139}}, + {{0x00084810bd80b472,0x000c9d87096bfb22,0x000213dd306a948b,0x000f10fc1ad42d95,0x00008adbd51369b8}, {0x0005716e1bc7e9cd,0x000e88f207a0a817,0x00081194cb775ec2,0x0000051502eda484,0x00001655fde650e6}}, + {{0x0002d8529ab17664,0x000febdd18efe4ef,0x0008f93d5bb9e7aa,0x0005bd5b6398956a,0x00003781ce087bdb}, {0x000adb3daf55c56c,0x00037ad269a5439a,0x000db01176c3f26d,0x0003e296872f7e7c,0x0000033a30fcd1df}}, + {{0x000bd6335284b84e,0x0008f43880ca626c,0x000925adb6bbaeb5,0x000a46b04a59bffa,0x0000f0ff8d1a11f0}, {0x000a185a6e7f82fb,0x000f677d6d0f0bf9,0x000fe783b2b1463c,0x0001df2e23eaa59a,0x0000740f8798259e}}, + {{0x000c722cfd41d7fc,0x00094d23f0bdd09a,0x000c4e6261ce5297,0x000c7c34230caad3,0x000087ee7f4ba1d9}, {0x000c5464bb31d104,0x000cc2b2971e1826,0x0006075a6c6d5093,0x00046ca459e99e4e,0x0000a65a1fb97994}}, + {{0x000c644d48d918fa,0x000a94d0bf8c23b4,0x0006cfb155d1a0ec,0x000071c4322d7bc1,0x00001f3bfe3fb2c5}, {0x000783f98fc491e3,0x000a7c0a39281925,0x0008235ca69e46fd,0x0008ae01fc9d169e,0x0000ca900548dc79}}, + {{0x000bda541349a39a,0x000c425a2a1aa23c,0x000962d9a09f1913,0x000462f7c27405d0,0x0000bde10d8a970c}, {0x000e683472ead4af,0x000cb9cfd08a2467,0x0009aeb8afaa4737,0x000ded0ac9c9a0d3,0x0000ce90da220b05}}, + {{0x0008f648f58227f8,0x0008836fa6d3184c,0x000e3ba47dcb6caa,0x000da665bec76370,0x0000b6a20603deac}, {0x000582c5e925265f,0x00046c9943a97cef,0x000568b96c2b5af9,0x000cc39e771b3bdd,0x0000841b94d6bf73}}, + {{0x000bf54149dde419,0x000a87dd1b4541dc,0x000e114d1eae42db,0x000618a1da2ae53e,0x0000d375cfe5fb7d}, {0x000c7151c5ec6dc1,0x0006021ec84fcd40,0x000c06e7f03abd0c,0x000e5abab6ac4a9f,0x000092cc4d88e993}}, + {{0x0004a400aa461c13,0x000fbb8169ed26cc,0x00035b80cc32eeed,0x000c0e53577fae15,0x0000c26d785c466c}, {0x00060512ceba4cd9,0x0004d5dbd6d77e63,0x0003d73e01830fe7,0x000f552a7971b6cb,0x0000ff6234aaf953}}, + {{0x000264d6ed5d6a7c,0x000e0ce67dac839d,0x0009760722497bcc,0x000fa7d6b7f1b9b1,0x0000412325c4dc51}, {0x0006aab96f5c6a1f,0x00010838ccd0083c,0x000477f4aed2a7fc,0x0003b9babdf5da39,0x0000b6954a4db685}}, + {{0x000b9720f5c665de,0x0007b936adb439b1,0x000f941b1f83f35f,0x000b862417afe4c2,0x0000bf88e1af3c59}, {0x0003fc188202f659,0x0002281f3bbbe4c4,0x0002a4f2f7105f4f,0x000558633d4e7b95,0x000028d27173eaf4}}, + {{0x00076bd78c722e88,0x0001551700e67635,0x00094f20827e73e4,0x000aef9bcfe57d6e,0x000097aad46ac9e8}, {0x000fb4432357b1de,0x0002f28bc7ebf10c,0x000ebcc31c6cab55,0x00039f2999933d7e,0x0000f5102b0ca303}}, + {{0x000a7e1a8ba693a5,0x000ba49ec02c239a,0x00067e4df2c98264,0x0004249f27435ecc,0x0000c02baa7777ec}, {0x000e994e304f2110,0x00083fbacc530a15,0x000fefab6e1cec97,0x000590dcbf287767,0x0000795c0592733f}}, + {{0x000984b1ef514e65,0x000ebd81411e2260,0x00032dfef40dafe3,0x00094956e4f8c6ae,0x0000136ba04fa012}, {0x0009ccee49a09296,0x00064c3b8e8e0968,0x000892b26d304e0f,0x000a112d29d432b7,0x00003ed12545e12b}}, +}, +{ +/* digit=3 [{1,2,3,..,}]*([2^21]*G) */ + {{0x000ce669fe8edc64,0x000977cc52c3285c,0x00000d67ed46f754,0x00061b80f9f0ec69,0x000012dbd13ccd38}, {0x000807b39e2a78af,0x000206aed104adae,0x0004dbd4a5d72c92,0x000027f3b3295361,0x0000693ac17f9250}}, + {{0x000f594afa4a4a7e,0x0000f5b4b990ac34,0x0006399e2ee44b8b,0x000b41f7bd0670ff,0x0000001c5d479361}, {0x000a8e6617658623,0x00048daa039ef32b,0x0006f48d6ebc6748,0x00037741a7683353,0x000042075593bdb8}}, + {{0x000094eefdd302c8,0x0009c460befb138c,0x00020963d227f072,0x000d142da3f15ca9,0x0000ba9e641f3b9d}, {0x000e401530c93b7d,0x00059744a3037da9,0x0003796f4979883e,0x00016795e7569395,0x00000c613cf9d65c}}, + {{0x000b20d1bb21d958,0x000fae479a31475e,0x000d97dd75179a2e,0x000145b32680eacd,0x00006b0a592db55e}, {0x00009e2a418bd004,0x0006a13ebcb0ebbf,0x0002fc81c9f8657b,0x000a128ce6f290ff,0x0000c2bf7d73e0f4}}, + {{0x00034ee8f7ca2841,0x000957847db5272e,0x00051343550a99c6,0x00027dce2b87e02c,0x000008e06a87c6fb}, {0x0003e4982cf177a8,0x0006fef4d4a55e9c,0x000544e47582945f,0x00026aa21056b319,0x0000bff078406896}}, + {{0x00002033f3eacba9,0x0001ecdd9087e29c,0x0005322e2493e6b9,0x000f6eadf4905da2,0x000016f929c8a045}, {0x00059f8488967f6f,0x0007be7575f06e12,0x000d9b6612dab69a,0x000892e6af43919b,0x00009097672f7684}}, + {{0x00083aac2d553230,0x000e2ff837639a05,0x0009af89299438f4,0x0004cfd3b1df4866,0x0000926c091d5ae1}, {0x000a5356cab1f151,0x00008a0b5e8d9e9f,0x0001ca41a7e71ebf,0x000839a4f0b024e7,0x000062a46f632c13}}, + {{0x000b21b7651b535d,0x000ed1ed8043c9bb,0x000ce1e1641850f3,0x000ddb9452c21474,0x00004ffeff4a6ad3}, {0x000dfe0c1b878ca7,0x0005170036f8309a,0x00092f2e778c4742,0x0002eb6f51aac2f0,0x00008b0fb8da7185}}, + {{0x000858780433abbd,0x00033774b30fce56,0x00038782098ecd9b,0x00099b6cee29ec01,0x00008890c1e6e660}, {0x000f67858c8ce86a,0x000d24efffce7d38,0x000387b8a9346a50,0x000711dcd7ef98b7,0x000069a697b171f9}}, + {{0x0003d469b1729fe4,0x0003a650ac09ae3b,0x0007f3ea0e2a6394,0x00028ea3015db36d,0x0000ff7f5572ee9d}, {0x000e9e34a5b7a36a,0x000b713b7a4042cc,0x000b2865c4506a15,0x000d73147264da3a,0x0000d28e88eb3d3c}}, + {{0x000c180b52f9cd55,0x00035dbd16da5551,0x0005671d63efc307,0x000d083bc2c9bef2,0x000077cd3b33b7bc}, {0x00016701d2c8f290,0x000af20f7a38f325,0x000c4fa1e8432fcd,0x000902477a71103f,0x0000c13307631946}}, + {{0x000a6de9599a5692,0x000b8cbb1dad4d5d,0x000317ddb4c6dcc3,0x000820def3a0ba2c,0x0000523c6f46afb3}, {0x000507a5b0666ce8,0x00009a4e67dd5fa6,0x0001f27b937bc419,0x000e17182d353469,0x000013aba876630c}}, + {{0x000e231e63f86155,0x0001ac0dd78b9590,0x00056fcf6a929cf7,0x000aff49a7e599c7,0x0000f2beae09c341}, {0x000c54d7d94bca5d,0x000460a94c47dce4,0x0002a0654f786ff2,0x000ef6bb318918dd,0x000043199fd3902e}}, + {{0x000672c94de6b79d,0x00065b645d1cb3c6,0x0006de9aae65c98a,0x00020c93993596a1,0x0000084850324b2b}, {0x0007470e2ed88727,0x00078a44113efdd4,0x000588cca7c8e729,0x00036e449a848413,0x000086370e30c8fe}}, + {{0x000cabc373c129c0,0x000b795474aefcee,0x00074d1801c4d4d6,0x0000903a019fb1d5,0x000090a24a4b2a71}, {0x000bcf6d4c7ea10b,0x00045a7dff3768f0,0x000f699905cf4cac,0x0004d37be1302ac8,0x000059f9ed7615c4}}, + {{0x0004954a8c5f8491,0x00036d6e05110de4,0x0001ebf0a61838fb,0x0003c617a5d05e90,0x0000931b4242abcb}, {0x00055e87db36946f,0x000d5c8c8d5ff47c,0x0001d34b9a502d72,0x000abe95f6140f42,0x0000eef1dfbb044d}}, + {{0x000af702fdfc658e,0x0009b5edcfe4f6b2,0x0003916044a0e71b,0x0009253d633d18f7,0x000067827258be5d}, {0x0002270c1591a40c,0x000aac7e34119c0c,0x0005718100a44dc3,0x0007de482d9958a4,0x0000936a6e932f8e}}, + {{0x00002d829e0de935,0x000d2b09417b0748,0x000bfb976a3c1581,0x000b232260ee014c,0x0000912559287882}, {0x000a3a2e63eb8e6a,0x000cdebf51672313,0x00079a1f51566a56,0x000a7c04a1f1a9ec,0x000070a867c7854d}}, + {{0x0008953d6fbc948f,0x000f59036928cf85,0x00092b62a61d026f,0x000b727b9d2522d8,0x0000d4740c141ba6}, {0x000e7258d3488637,0x000fa4f6dd639d25,0x000c32176d124824,0x000ef5dc0aae73c5,0x0000a6763062fc85}}, + {{0x000816180ac7b35c,0x0005671668988232,0x000293310c1fe0fe,0x000d24b7b7e35a0a,0x0000fbc7f7dfa8ee}, {0x00002f829b61fff0,0x0004af7a42839a1d,0x000ff28e0716b31b,0x0006c53c4262a0be,0x0000eeadb1a1ce5d}}, + {{0x00015f1a3129e10f,0x000af2b4e6c937c8,0x0002977a7267764a,0x00073c6a478a6c0d,0x0000cb95cba1c483}, {0x0009a10260d9eee0,0x00063e1488dd8e2c,0x000bef43bc3079ea,0x00087b3e5515d1e2,0x000027a54dfc6c17}}, + {{0x000bb05b171e260f,0x0000312f11202e54,0x000cbd9782e9eb34,0x0007071408c05d3f,0x00007b0ad44d5ffa}, {0x0008e0fdb6bdc2ae,0x00083bcf267acc86,0x000abae442a4c99c,0x000059d8f7232875,0x0000d3f091a78c65}}, + {{0x00025e9ecbca3bd5,0x0005b277501df3f8,0x00002e53470ab011,0x000c2c5c9f5f0879,0x00001e324f25d94a}, {0x0002c87b5f5c096e,0x0003690c467cfb66,0x00083478fe443b48,0x000ffa57d95db742,0x000084fcea7f7f1a}}, + {{0x000be1e8d816e34a,0x0005ed0373a139a1,0x0005503eb6c76567,0x000d72c0a0c0fe38,0x00000930e2800fd6}, {0x000a839aa5e6043c,0x0001feb1c5709e13,0x00063fa936978e73,0x0001cc67e25bec26,0x0000b4bdbcf0e7e5}}, + {{0x00063de507ea770d,0x000de8db50e250d4,0x0003df144efaa8e2,0x000948957b939cd8,0x0000f00ebd59ede6}, {0x00058f76309396a2,0x00070b764deb6457,0x0001c9d75c4c6c1f,0x0009d4bd7c9c7109,0x000094ab2f959459}}, + {{0x0008e62912bb0c69,0x0007715b88eb025b,0x0008b374d95a85ef,0x0008d1ee3692017d,0x0000e00546935947}, {0x00067e18f669c1a6,0x00031e71bb112d7b,0x000f45f7f358f9cd,0x0002a153c6281ddf,0x00009ce24d9faa21}}, + {{0x000f23a149bca110,0x0006b07752dadb87,0x00012f665e907d38,0x0000550047f8ad59,0x0000a6b2737c88e3}, {0x000df2eae0d2d96f,0x000d847b47f5dc0c,0x0008afaaf8da34d4,0x0000c0a53b08c91b,0x0000e0c5963803ea}}, + {{0x000040a69d08ead8,0x0005d6ad8eece93f,0x000e87e8da444df5,0x000e5f2b193b1fa2,0x00000036b7fac7e9}, {0x0004a15b7ebad244,0x00033aabbc15474c,0x000fda83a8c245cb,0x000c2ef6f58e5947,0x0000ab5619ed45b0}}, + {{0x0006744b238ad74a,0x00032c3f045f7417,0x000a0cd8d1dfa1dd,0x00031dc9d44dabde,0x000084c351aa16ef}, {0x00066dbbbd4b79cd,0x0004a96d5540a264,0x000654e5bf972fe2,0x000124ed39cff7e8,0x000006fad5584afd}}, + {{0x0009b54ae4ccf190,0x0006b5139c106a36,0x0000e8f52cd3cb71,0x000bf08f80ab4008,0x000063ecb5195105}, {0x000e88b3133f9c79,0x000eeb2da83f3530,0x00079992670c5be7,0x000c619c9d672568,0x00009c94c9c60e0b}}, + {{0x0002d3810e75db98,0x0005272729ef9b4f,0x0007ff48b8893550,0x00078145eb9f842d,0x0000b7c621d7385a}, {0x000e48f3bca9cf86,0x000b8618ffd026ad,0x000e625e5d56e39f,0x000ab106e697de51,0x0000a9125a0d4e5c}}, + {{0x000447e9cc831545,0x00039cab5ded44d9,0x000acfe1552fee6f,0x0002053a733d2726,0x0000d8fb9153c30d}, {0x000e7b29e73a90d1,0x000b934edb6a2c09,0x00051fd35387a394,0x000def08b496427e,0x00005f85a2688694}}, + {{0x000424e8f9ba0b93,0x0007cc5433ef7479,0x0002d758a3e8cabd,0x0002c570b4f000a1,0x0000648310308664}, {0x00091a20f1e32de3,0x00041f7fce3ececd,0x0006f7a6a4a18ef2,0x0007a40a6f273f95,0x00006d7bc3eb35a4}}, + {{0x000d62c3c0d878cc,0x000bd2f14f772133,0x000506fc0d074a1e,0x00053b069efcbcf3,0x000054da173b382d}, {0x0006a1152b4b6ab6,0x00077d56291d93b5,0x000356e41211a144,0x000cf742c41cc0cc,0x0000d44d93647521}}, + {{0x000f6db69902561b,0x0009788fc670cdc9,0x00011bc01617c072,0x0001039ee89bce70,0x0000cfeb4e30a91c}, {0x0008f453c12e47f9,0x0008ce538b6874d1,0x00013f0f3dd733fa,0x000df596b652acc4,0x0000070c70ded8f9}}, + {{0x0002577943ed1947,0x000c51f97d56ec8b,0x000635b321c1dce6,0x000f4c0548ac452f,0x0000108844a039c5}, {0x000d188c05a8f588,0x000c907ce36d8dc7,0x000454c24921477f,0x000444f341fa52c4,0x0000a2d7f2d74a60}}, + {{0x0004981202326049,0x0009f23af30ee110,0x000d64a57e4877b7,0x0008d66d3bca95de,0x0000aa95f1b4aaaf}, {0x000957488a1fa688,0x000248ced945f9d8,0x00053e4500e34b51,0x0004ec08199ff786,0x0000dc704075eeaf}}, + {{0x000432d7fec902b7,0x000dcb98903b6701,0x000d7b52267dcb60,0x000413111b403207,0x00001357bed41bd7}, {0x0003d756c1125098,0x000a7a9535cc50ee,0x00098d003854c0f0,0x0004962fbbd5ae57,0x00004841bca8d5b6}}, + {{0x000e30c76057eb58,0x00068ca7bfadc9c6,0x000b3aae0116da0a,0x0004e7debde602db,0x0000de60723a0a04}, {0x000c372afe5f7c62,0x00098fdeab5ccde3,0x000b5f5be690997e,0x0002ac9676df4a3c,0x000028ff6485238f}}, + {{0x000d7abe5b2e9d52,0x0002ffa22191deca,0x0001b9811b5540a1,0x000d459ea5db7dd7,0x00007563c3351050}, {0x000a75fab5e73768,0x00027ca2af62afa4,0x00063a4216da6470,0x000fd71b1066c376,0x0000728e0ecfca8f}}, + {{0x000cadd177056db7,0x0007112b5eaff3d4,0x0003bc769207538f,0x0007fbd0b226cdcd,0x0000d68a971cb7ae}, {0x000d3db0039f89bc,0x0001dce3018f0114,0x0000cd40c9ae9f18,0x000bb3ef18abf742,0x0000e4c4353ecb88}}, + {{0x000fdced3ed27960,0x000a90267c9be8cd,0x0001590535eb2ae4,0x0007701b0fc0c04a,0x00000a023e8bb8a0}, {0x00066947177447ea,0x000e06cde38d8e01,0x0001fff605dcc55c,0x000c26be22dda145,0x0000b32e709b81ae}}, + {{0x000518964e0c5fd9,0x00008a23f3ad0b05,0x00008aad44cb4866,0x000c136a024b9aaa,0x000067192f7f61c3}, {0x000aa96177525e8e,0x0006f03cf1735dcf,0x000d9114dd244865,0x000888ad108db4cf,0x0000aec1bfd08a5e}}, + {{0x000ab3806cce7241,0x000c1ce423887790,0x0000a059a1dfabf2,0x000a244b273397bb,0x00003d65f2a93933}, {0x000a60d1b06036f8,0x000cea8ca3b592d5,0x000964a2fa69559d,0x000e4b4a59647493,0x000017ee9471a84d}}, + {{0x00014f6deef40534,0x000a82e14d3d8207,0x00033d6449a055d1,0x000d431c43f7ed5f,0x00002ed0948cf9d7}, {0x0005e0389a99f1ac,0x000c7cbdce132937,0x0000397e12268f39,0x0003760a23c2f5d9,0x0000c935abac75ea}}, + {{0x00052b1e1073e1a5,0x000f84a0c1c1455f,0x000d942637ad068c,0x000010f8a702108f,0x00002c64ff56f96c}, {0x000b9a16d727e0b6,0x000acf06fe3379e5,0x0005d2bc212790e2,0x000afddcb18846f9,0x00004d030329bc97}}, + {{0x00000106b178893e,0x0007ae2c3659cf4c,0x0007128b98eaa6be,0x000d0f17c825e01d,0x0000fd2e94e765ff}, {0x000797e208c8a081,0x000d12668d49e74a,0x000cbfb9b2628f2c,0x000072932fe4d074,0x00002abae9bd73bf}}, + {{0x000793e3b6b83b30,0x00064f8714d7bcdf,0x0000861188ceb25a,0x000836b57f887559,0x0000aa70f4c39c97}, {0x000e5a6ccef975d5,0x00068bb3df26c700,0x000b1425b20bccac,0x0001beb2c7708823,0x0000c3e597f24036}}, + {{0x000920b4d475bedf,0x000601c20860a37a,0x0001a6c7768b0a63,0x0009437bdf506d72,0x0000de3d4aed0bf9}, {0x00051b6900b359cf,0x000cbfe3d2fe1e07,0x0002762542109347,0x0009d5d83f981349,0x00002085a33e208c}}, + {{0x000b427915cb2d9c,0x000fec8d33d25907,0x000a6b6f878fe209,0x0004da0927589135,0x00008ba9de943b1c}, {0x000a09fab0991dff,0x00080c1e31c86c33,0x0006792b45738377,0x00022fbfabbfabf8,0x00000b81945640ae}}, + {{0x0007aa27ff722866,0x00095500f6877413,0x0003805fcb9e8eeb,0x000097b2ddfcf0b7,0x0000906494cfde74}, {0x0001dad9278c86af,0x0001a53f73534dfe,0x00017c8e51d0b3ee,0x000e2264fe779fe2,0x0000f9399f5c2391}}, + {{0x000f2b9a899efa35,0x00044c5bebbb0c89,0x000f7a937ed79daf,0x000d8393645c3d73,0x000002e30297a15c}, {0x00000d05a8de6267,0x000f1c09869fb65a,0x00001a95369da17e,0x0001d8284f596a68,0x0000a54eb42f428d}}, + {{0x0007afd35e423eb1,0x000207737f624bca,0x0000589345b1b05d,0x000841ab44d9b3f6,0x0000856926f19438}, {0x00031d759bbd89f1,0x000491c56f96ea9e,0x000d5c66b3d428f8,0x0008f65ae85d04dd,0x0000fe7d32eb79df}}, + {{0x0006c9eef207e08f,0x0001e7e6e201fa79,0x00066ba39be6e809,0x000ae2ff6bec79f1,0x0000b616f14c0f5e}, {0x000a3da1546202dd,0x0000e77aab41895a,0x00093e7c9fe3e873,0x00005f4a80c70b54,0x0000548eeadf6f0a}}, + {{0x000cc1a29a108d50,0x0006ccd7dab0a262,0x000ec67c8390b012,0x0005dcb4c64bcf06,0x0000f259d55a3603}, {0x000d5ece299782c2,0x0007a0a1dc54ab27,0x000dd366a6679ec3,0x000a9f22b1d8fa56,0x00000463c1d0eece}}, + {{0x000e0e293cec1e79,0x000efc99ec7f6002,0x000ea6e4722d8500,0x000d2880f2620157,0x000054e88ff06240}, {0x0008fcb8d2e2a682,0x000bb41a29a94f41,0x000046598dbf7cca,0x000fc1c555e4fa70,0x0000e866a08c23df}}, + {{0x00055eaf0cd106ed,0x000eac0ffa583fe3,0x00075d5cb5db3a43,0x00068fdd48ba02fb,0x000000f80f6d4c38}, {0x000dffd39b9c5153,0x000091f21f2463a0,0x000a549ca0718f92,0x00093a5a7c8b59ed,0x000071141a9807b8}}, + {{0x0007357890dd4e38,0x000ad26368db2df2,0x000025d8495c27cf,0x000ff989f1617b78,0x000034d4937f3648}, {0x00079875fcdf6a41,0x0003bafc7add2319,0x00065054796a385e,0x00063f88333b6cfe,0x0000ba555751f971}}, + {{0x00044e669582dd15,0x000609ef7f52438b,0x00028c7c925d34d3,0x00088a39d0f09e7f,0x00001aa149662b55}, {0x000de74ef350ef69,0x00050efa2a33bc70,0x0004e9b4ca36537b,0x000f476a52619b28,0x0000e5cc6e2e16b7}}, + {{0x000740b19e406537,0x0001128987018afd,0x0008c9ef1e3cfcf5,0x000147c2788d343a,0x000000bd40c703bc}, {0x0006907b78203587,0x00054432615b4606,0x000a2fae0e3938e1,0x000420ac9fc4cd7e,0x000061a1a83680d7}}, + {{0x0001e1652f266287,0x0002072786662748,0x0004d6d5004b921b,0x0009798d1624a8c9,0x0000a6c2afe78ace}, {0x000b4716993415ad,0x0000b70c175d0b87,0x0003efa55ba75b9e,0x0009da493ef2cd19,0x0000967d0431319d}}, + {{0x0001bb3328972e05,0x00081d050273498c,0x000b43e91b4aea4e,0x0009d7c51b0b14e4,0x000036a831285442}, {0x00092962275aebf9,0x000ceea0fb01f9e0,0x000ea5a49dab5109,0x00062df927cf2354,0x0000f8845418f676}}, + {{0x000f39d3d76f2654,0x0008b5cef1752354,0x0002c38aeabb3b6c,0x00065abb0b5fd32d,0x00009a4a07ce1f25}, {0x0005648873cbfad2,0x000e64e5d115d4b3,0x000e40d2e3544b37,0x000823b6b1a1b049,0x0000420db940926a}}, + {{0x000a61e31101b401,0x000b74d28dad2d7c,0x0008f99381581fb1,0x0006d98a29dc712e,0x000046c5f42fff53}, {0x000011451423b3eb,0x0003c0d9f657b72f,0x0000ef292dbb3276,0x0002a7c4929e7744,0x0000ee6ba08f8841}}, +}, +{ +/* digit=4 [{1,2,3,..,}]*([2^28]*G) */ + {{0x000c50fdfbffcbfe,0x000a12ee6bc0d5f3,0x000d1eb16b2119f0,0x0003b21259ba1e92,0x000095afdef8cbeb}, {0x000584520b9e2c92,0x0008610feb591e96,0x000754802ab80276,0x00031ea8ecb90bdd,0x000002948477a4c6}}, + {{0x000fc6d460d9c206,0x00024b68998b6f02,0x000fc9a84a798355,0x0003bd99ba516a43,0x0000f1c752d2f2ce}, {0x000717f6e91c96f3,0x000ba1ff04750021,0x0000101ff724bb9d,0x0000f57875a3b062,0x00001911b2aa36f6}}, + {{0x000c9dbce96a690e,0x00020a9b23952efd,0x000ece1eda0be426,0x0003e42c87d6e797,0x00004250a5772078}, {0x000f792fd6216e65,0x00011a4a7752b22b,0x0004f0652e1c761c,0x0007d6395f3037f3,0x00000f9718cd45f8}}, + {{0x0004c7f57ef9e74f,0x0007af373f4ee836,0x000f3d49fd3a3dde,0x00003bd7ef68deb6,0x000023a2d231ebcd}, {0x000eca838c637b01,0x0002f973dfd6c576,0x0000dfe2ab1c805e,0x0005a94572e7fda6,0x00009401440f369a}}, + {{0x0007d74400024b40,0x0001f5b00db08719,0x0004509077de17a2,0x000354c8eb4c5624,0x000076dc0dfdda91}, {0x0004925d7e16e234,0x000e71fb7a5cd3e3,0x000628461ccda123,0x0001e761ca242827,0x000040a6ef696001}}, + {{0x000e553f6d124300,0x000275d95d682353,0x000d2b82b5b6dca7,0x000d63f3a355d098,0x0000ae0d057f7ca3}, {0x0001f9e4577d877b,0x000c3279477c834c,0x000c7e5cafae2064,0x000a2108248735aa,0x0000554c8dbd94eb}}, + {{0x000176969fce95fd,0x000241c5aa6dc450,0x000beb9be4d5ea44,0x0006fb48576985bc,0x0000dd0c88c86a87}, {0x0008fffa1635a744,0x00014b52e79efa78,0x0008c0387af837e9,0x000b1463f31ea88f,0x00003e02994385b3}}, + {{0x000adf82eec10655,0x0006da35576881ff,0x0001f3593b826072,0x0005479f5a9118fc,0x000081b7ed8887c5}, {0x0009f9ff322cf7ed,0x000a52f29f0216a2,0x000a1c6f5503a339,0x000087e4359a783f,0x00001f2f7550b63d}}, + {{0x000d2b7c76e70230,0x000cac6501adec50,0x000d15eb9ef1627f,0x0007ec71504ac4d0,0x0000e8e72360119c}, {0x000a6a690fe5719f,0x0000b2a6adf1eff9,0x0008001065e53180,0x000c3e7128f929d5,0x0000a8ed05310b1d}}, + {{0x0000184375155611,0x000680c6035cb9d5,0x0009cd9ebedaf7db,0x000025f68ebbaadd,0x00009b22d47c19e6}, {0x0009ed7e238ec156,0x00087ebb00fe3165,0x000f4fc1d9495e60,0x000a7fb7a835fe31,0x0000cbc5fbf249f5}}, + {{0x000ddaf091b1a54d,0x0005aa18a0a22a3e,0x0008c82e61dfde58,0x000ef6fe2926ccce,0x00006f8bf537ed18}, {0x000f182c887d4a0e,0x00001be42965f456,0x000e7c978127d1ce,0x000537d0a1d9e889,0x0000569de4dc738d}}, + {{0x000fa89a0e74e6d0,0x0003d52a6a5b2e22,0x0009d6028cb9cb9c,0x000868143cf11bcb,0x0000f98ceb8beb7c}, {0x0004f0bd89ceabf3,0x000d3055f6bc7d18,0x0000611f84ca8c91,0x0009ceb37e7fcea7,0x00002ab69d8e4537}}, + {{0x0006164be8ef810c,0x000c68f62e3a73d7,0x00042132ea0f220f,0x0009b931a8cfae76,0x0000120e0489c3ff}, {0x000056c882e544e9,0x000dba82d21f227a,0x0003f4d8ead76b96,0x000524458fba4ab8,0x0000af5f9fc5fd38}}, + {{0x00084efca06ca980,0x000f34de85805779,0x000729e45600bd35,0x000abe8d8f71256b,0x0000c757c5918e10}, {0x000d8a877f78c2e4,0x0008eba882fe2edb,0x000ff0a632610953,0x00000ba6c1759a7a,0x0000b96a1b55892e}}, + {{0x0007062382d80b8a,0x000852b7fcb37ae6,0x0000105dffe9b512,0x000554b3f092abdf,0x000049e87155c674}, {0x00073628f54f8dad,0x000eba81d77012b6,0x0001176a2e46bb7e,0x000f52d8011507b0,0x0000fc7de4c283a2}}, + {{0x0000a3774b40ba51,0x000d2e1cc3a9ee5d,0x000566b1a46d5ccf,0x00059f07988c4721,0x0000c80b4f9aef60}, {0x000f16c5f230e80a,0x000da03ec1812abb,0x00006315b4b346ed,0x000fedf2b2d744df,0x000097e8aa16c20a}}, + {{0x000d6e10aa7185cb,0x000017ccc3b062e6,0x00011d8ad8b90450,0x000f8e927aa95f45,0x0000358b43fc06a6}, {0x0001d5d7e36dcfc2,0x000fc29193e72912,0x00012443b6776098,0x0009b04e627380b4,0x0000fd059fca40f2}}, + {{0x00006b777ce58f01,0x000345cefa37e057,0x00050cf438f95f41,0x0008ee0abf1f45d9,0x0000d3ab82dfe23f}, {0x000dec2fdf1e1687,0x0003a9ada1e3f0b0,0x000621bc115b07d9,0x00091804b5c24dae,0x00005a536309e580}}, + {{0x0001a1f36d5a3e11,0x0008dc2f815e7fc9,0x000a6ab5b38987d7,0x00005ba64e516fa6,0x0000e35f790ff4a1}, {0x0000a6a16d83c088,0x0006ceefab1c6182,0x000449d91c98968f,0x0007bb24e4313214,0x0000f72073843b6f}}, + {{0x000bdb5454f13c39,0x000a22272f00d7ab,0x0002e178a51c5620,0x0007ffab23452bb1,0x000095fe77e2c7ec}, {0x0005269f7a15d9c8,0x00096a8c061d84bd,0x0004524b8f8eebd0,0x000df15fadf6f11d,0x000006922729d2f3}}, + {{0x0003db3cfadbe550,0x0007ea332972b6cb,0x000375df17c3205b,0x0003d308348750d8,0x0000156569ad36a1}, {0x0005c1e5a6730825,0x000935b88ef2de6e,0x000bf9f4cdfbcd4a,0x000c1aa110289f97,0x0000e8b4b218715f}}, + {{0x00047831dd65d665,0x00061c4f2c50ca7b,0x000e125f3749ad4c,0x000d6b6dedd6ee5b,0x00008f3560aa418f}, {0x0004cca576eb6ef0,0x0006bf234f5421e2,0x0002931e2453d90c,0x000a5a30ba21d2d2,0x0000f40aef62be5b}}, + {{0x000906e3dcb95765,0x0003952a2d0bb27c,0x00071e7a288f483b,0x0000b33851620f5e,0x000049133fb7e046}, {0x0006fedc5361d7ed,0x000097bdcdbabe80,0x000b57799cd31b0b,0x000f7bdbe9c25b69,0x00005ac7039c2b9c}}, + {{0x000b6b867e927375,0x000fa63b9d79dc5c,0x0006f3e1b3db6fd1,0x0007c0d5e633292b,0x00008252bcf8f282}, {0x000208df42a98b04,0x000321910210d248,0x000c2cc0bbf1cf7e,0x000fda998a5ce085,0x00004661e9931c1c}}, + {{0x0003ff64af040144,0x0000271a4dc2976c,0x000f713650222aaa,0x000a7b0407b2fb4a,0x0000de28d8759197}, {0x00046b6fabd1d7f3,0x000f4abb6a1aa945,0x0000e83a29065344,0x000c3009a559142d,0x00004e4b62383c59}}, + {{0x0009e0629876866b,0x000baa1e5ef979af,0x000344a68c0b5f09,0x000b007ac8563053,0x00009d8b747143ec}, {0x000042138fad570e,0x000f593e59ae3704,0x000886949e418ec7,0x00095cfd231c4091,0x0000cff10c404233}}, + {{0x0006585937313d7d,0x000c05513277642a,0x0003aea43c3c0b6e,0x000f848100f54c99,0x0000872c0c47c3fb}, {0x00097cc55eb26b25,0x0002361e834684ad,0x000dd6b60df38d56,0x000f85fa83e5f219,0x000080ec5b9b7a9b}}, + {{0x0008e57fdd7ade46,0x00059b24d6140c44,0x00002d217ca3f679,0x000cabad76479b8f,0x000088094d742238}, {0x0000f8a7e3617373,0x00035946e4869acc,0x000c11e58b0c0758,0x00047a937c7d9950,0x00006d8fa5650507}}, + {{0x0003e42674ed11ef,0x000404828d8b786a,0x000696d9b1c4a0b2,0x000a64d22d72fb93,0x000014d70fab6fd3}, {0x000db48af8bdb685,0x0000a04eb44f8247,0x000dd01bf9cf8243,0x0005d612508a37df,0x00003b03be491bcb}}, + {{0x00052e217a1d1fb3,0x000e03733ad7df0e,0x0003c7441a511a17,0x000e3fe73bb6fe95,0x0000c210edd71197}, {0x000e1c3b3b5b574a,0x000d784c56ae9c1b,0x0002719fec3c39ba,0x000ac883f91c7e72,0x0000596cbb0e72a7}}, + {{0x00087a7c47d16487,0x0007c27d1eee4af9,0x000efb643de140a8,0x000af19f4764d9f4,0x000015e713bb998e}, {0x000e86dcbb8a91af,0x00012fcbf8d52174,0x00004c90675aec42,0x000d6fee55cd1165,0x0000473a26dbefc9}}, + {{0x00036638b477ef6d,0x000889bef8c0d8f8,0x000f69f8ac86759b,0x0002c5990ba889fc,0x000077c230155958}, {0x000318fe4ed774b1,0x000943b1be4baa60,0x000ee1a405a3bdc0,0x000f93f1b2f417c0,0x0000d8aff7c79fd5}}, + {{0x000ab61ec541eea4,0x0001ddc9914833ea,0x000ddea233e07a02,0x00092d963c34f544,0x000044eff2fab1eb}, {0x000151dc44d86278,0x0003f0a1ebb24397,0x000d4968c888b6c7,0x000fdf950aa9dbd8,0x00009aceb5a6375e}}, + {{0x0008f88f4b8f4675,0x0003e1eb007bd2ce,0x00071e4c30d657d9,0x000e4cd8527b3006,0x0000e64c785f241a}, {0x00060c0a55cbc596,0x000f64194d67dbb6,0x000a74f7e445f24d,0x0008892b9bf8cc55,0x000087103038e47a}}, + {{0x000c4132cd9b183d,0x000612f382df8229,0x000787543d725563,0x0008dc0dafa6bf3a,0x000054b1d9938b00}, {0x000909776b50d022,0x000e79e83c7dbff4,0x000339f55e1b465e,0x000b542cad7a0e54,0x0000ba6a0a29e068}}, + {{0x000468725b4544cb,0x000d798fc46027b3,0x00037c0fef8d6693,0x0001f562e64ba62d,0x0000f4f40675932d}, {0x000d29eb4b2b5d30,0x00096664493a478f,0x000a8ba7c916705b,0x000ac523815da842,0x00002363b3a920b8}}, + {{0x0005576b1b9c4387,0x00012f0b382afb58,0x00090cf5e15b9217,0x000e25c7b242acfc,0x000019252c1e86b5}, {0x000d5ad8a3d0a645,0x000eeaf47eba0955,0x000f27b0e1492667,0x000c14fd914315df,0x00004f8a7c6076b0}}, + {{0x000807ac46701c33,0x000b8d6d492ad054,0x000c5c86829eeafe,0x0003db877d68abd2,0x0000fca131606089}, {0x00046fb59b42ee1f,0x0003ac322ebe5b5b,0x000567698797e76a,0x0003c7d91f0f74fd,0x0000c77ff2c96539}}, + {{0x0002670ed84701aa,0x0009919671d435d3,0x0006aa77f196a6d1,0x0009ff14771936f5,0x000045e8ec81d56d}, {0x0008ff7e385075a2,0x00053a57ae34859f,0x000496f4ac1269ed,0x000ab1e97fce260b,0x0000bc829794fbcc}}, + {{0x000727a64762c5b0,0x00023d5228f62cfc,0x000f9e44f2954c41,0x0006a900f293a819,0x00009324b17896cd}, {0x00027fe6fe89cd5b,0x000c3c1764b979f4,0x000d84375a0a4d5f,0x0007be72e67bd8fe,0x00007978b94bf0c7}}, + {{0x000014848f08e5f8,0x0000dc08a46d3f0d,0x000f2f51cd2de0cd,0x000f26442abb9c85,0x0000b1f0caf156bd}, {0x0001a678227aedd6,0x000363358fbe9f6c,0x000e8c01632b677f,0x00025feaa88fbae1,0x0000dd95784a0bf0}}, + {{0x00036ab62c9baf2f,0x000e3a0427cc9a23,0x000a9a0ba77b1f0f,0x000b2ba599b2ab1c,0x00006167aaef6883}, {0x0000834b4a11c2b3,0x0007e5fdfd466b81,0x000b1bdee8b8d4df,0x0001c6c0b819a31b,0x00006b8ce7712b3e}}, + {{0x000472ce5ee2aa98,0x000a7c8a447852c7,0x000e5e562934541d,0x000111e5956b46a2,0x0000c2def91e1de2}, {0x0004c70da2035d12,0x0009ecf24750f0ed,0x000774bd31fbde41,0x000bef51f1644a0a,0x000075f1a69ccb8d}}, + {{0x000a76901a375370,0x000534a3899464c4,0x000e1bd64649cb25,0x0008de028a8fda1f,0x0000afcf366ebe08}, {0x0003cc2fe33a0853,0x000c655169d3adba,0x0008bacebd18e2f2,0x0001722b708df59d,0x0000673842d3ffb5}}, + {{0x00084f5b5b4155b8,0x0003bee12769b41d,0x000d7c141a89a9b9,0x000f02731f3e90d4,0x0000f5807b7dec20}, {0x000e4d79f5f291c3,0x0007e1820075ebee,0x000d095ee31719b1,0x000e77b13e98787c,0x00009bacf15e8239}}, + {{0x00021e1ade0c9f13,0x0006baad0ce722d7,0x000d6be87abd4fcc,0x000228a81f7554c5,0x0000e992ec32bf51}, {0x000dfe81a7d3c300,0x00060efd94bfa623,0x0007abb915ac1f99,0x0001008b04e471a8,0x00006a6dfb158b1c}}, + {{0x000895918d9c587c,0x000b90d8c07b4267,0x000ab468e989eec5,0x00096f5f2fd3207a,0x00000c4fd8f7ddf2}, {0x0008b1cd86dd7ac0,0x000a8a8ab83f3bab,0x0005768923fb00d7,0x0001e0496024dfd8,0x000093c337f8280a}}, + {{0x000f2f33fb1ed546,0x000f5524877cacf3,0x0009dec562c094ff,0x0002af42d6955bb6,0x000051aac6f16c54}, {0x000f747f4566c18d,0x0000f500d0f779ed,0x0009bf4c72dfb961,0x000237be0f508927,0x00009d1af0421cb4}}, + {{0x000a30ddfb3c9567,0x00044273b206d755,0x000b8261642fa0c9,0x000999c462c3d5ec,0x0000e5cfff9087cb}, {0x0007f4092bba64cd,0x0003c030e85f29c6,0x0000dcbcd00ede6d,0x0001f5c5ab9995bb,0x0000d909fe94ac39}}, + {{0x0004393c8401d21e,0x0008419e515f55e0,0x000b70a2c970650a,0x000812aa1988dfb2,0x00004579ea7e0f77}, {0x00001ae0b356ff64,0x000a67b2f4f8d464,0x0004e4808c24fb2c,0x0003cc7049b70ecf,0x0000d988de6931b1}}, + {{0x0005205bc1daf6aa,0x000b46ea4ce6aedd,0x0001b36b71d5ade6,0x000c684feda79817,0x0000c1b97fd8fcc2}, {0x00015296e4680f82,0x00039c979c619a51,0x00019b0dc58bdb9c,0x000edbf5165245ca,0x0000dda5f64c3464}}, + {{0x0002da59de36c6d3,0x000dc41490e573d0,0x000197752e9c3c3d,0x000caf7729881db7,0x00005781ea0add88}, {0x000709293651cc16,0x000b2ea5e1c2adf9,0x000040381b05df36,0x000cd96512965ec0,0x0000cf761e9b4f6f}}, + {{0x00012f98f1b3e1b2,0x00055f5544270463,0x000c9e4a1d2b7326,0x00007925876fdd82,0x000074ea097a9061}, {0x0006e346721dc27b,0x000037acb54bd914,0x00011e8654a4af5d,0x000c7efafad16cfe,0x0000f0e1c71ca6c9}}, + {{0x00056bad8c8fb6bb,0x000d537ea4bef324,0x000e9fd62945dd49,0x000f97b5d567fef7,0x000086c5b4120ca3}, {0x0002cbc8de7435c4,0x000ef4e32422c90f,0x000915725631070d,0x00056753035060bb,0x0000ac9120611153}}, + {{0x0001ce2ea4b332e4,0x0008a88d39b03943,0x000be58c21e92546,0x000b8614d72a258c,0x0000d6dccab15931}, {0x0000f4d58db96687,0x0009b295553ee450,0x0000bd38d9439d07,0x000760d9baad6913,0x00000af15cbf9b45}}, + {{0x000e116715a75218,0x000ee37a35141d7c,0x000d96ee6c976ad7,0x00008be27249f510,0x0000dd9663c48776}, {0x000806b3a6abaec9,0x000974d53433737a,0x00034026f2f4f6f0,0x0003631542622247,0x000033f84d61ede9}}, + {{0x0005789811a3ae5f,0x000145466230de30,0x00035f272f8c7bcd,0x0008464d6e1bcc51,0x0000c0b21060c721}, {0x00056b9c81e33e1a,0x000ecf8a7f58e633,0x000b78291f065f2b,0x000e115598fa93ae,0x000008d4d5dc0246}}, + {{0x00023976b401d760,0x0006a4914be6b70b,0x000cd32b79cb8bde,0x0001ffab9c10c28c,0x000071ebaf4d93ce}, {0x00025fddbaeca2e7,0x0008b2280bebff24,0x000a3891662f455e,0x000cee7ab7537d72,0x00000da3f309f420}}, + {{0x000d2fa921a168a7,0x0002e4b7b670cfd8,0x0001d3d2b35868fd,0x000fd4925f10a54f,0x0000d3ce9bd12974}, {0x000176530f52e7e9,0x0005ca6a8cc32d2c,0x00019482b90bd81b,0x000cd9a2087e9855,0x0000804eb315a666}}, + {{0x0002197860bc9037,0x000d8b8123349561,0x0003876dc1f987c0,0x000583fb6e6ef179,0x00008cb21fa0cf30}, {0x000fc89c021518a8,0x0001fe3269ddefc5,0x000e6ecf600526c8,0x00082dc869beeb1a,0x0000ceed4cbeee27}}, + {{0x0000659ae15c0cff,0x000524432040fd35,0x000c95fbcb5411e2,0x00010634f1a87377,0x00003ae2a14e5951}, {0x000c01abc86960db,0x0007837753dd90d3,0x000b3a5cbd54cd6d,0x00025ee3849235af,0x00005aead12b08c4}}, + {{0x000b7d73502d7d8e,0x000d7454261868b3,0x000e46fbdbc13c21,0x000713844ea5cc30,0x000049be3239b611}, {0x0002b0432aea713a,0x000625e8db9e6204,0x000d1b612358a422,0x000bb2de468b3935,0x0000d73f40958c1c}}, + {{0x000ef0b57b47fd09,0x0005a747602a55e1,0x000ef3a6ec69c95a,0x000a9812736cac28,0x000000509d742fc3}, {0x000649cba516376b,0x000241310dde1462,0x000486dad6e304cf,0x00067a74ba5dd344,0x000076e637f5c43c}}, + {{0x00011c2158de7341,0x0007322124e7a4f5,0x00002187b24db413,0x0007c89cf37f3770,0x00005c2bbc1a94be}, {0x000c3a8a2a94c5d1,0x000019673c8091ee,0x000a670f1d766afb,0x000dcaf7cc3d5518,0x000067e6f9927685}}, +}, +{ +/* digit=5 [{1,2,3,..,}]*([2^35]*G) */ + {{0x00005700bcae739d,0x00002be037d24753,0x00015b109f3a7bb3,0x000e43f9da256a61,0x000093ad7b5eea05}, {0x0009fd0396309d30,0x00051affa8b57a31,0x0009e17000aa55be,0x000584057dd782f4,0x00008fc1c3299638}}, + {{0x000d93c48b3b2619,0x00080481131fe4d5,0x0004069419aa8668,0x0002802c3872251d,0x0000e0421b9f2df1}, {0x000bdc567515ba99,0x000aa60a7a56df82,0x000c254922dcad79,0x0003014dbea6f756,0x00003529c91e3e54}}, + {{0x000f4cead9303d8e,0x0007da2afde793dd,0x0006deeafd0c52d0,0x0002cee4e07a6bb6,0x0000805a8d0d1862}, {0x000bb34d90f85393,0x00081fd23389603e,0x000a4addd74321cb,0x000ce7a3c9e82e99,0x0000dd06c08d7e68}}, + {{0x0004e4b39f1a7fc3,0x000685bd324dc746,0x00077329f942afb5,0x0004c07e4ddb8995,0x0000a7edd72789c7}, {0x0005b61b34ef6322,0x0000a0c0708326c5,0x000423a1ac63d4b6,0x000e55cca0e0f401,0x00009daa63d66c01}}, + {{0x000d5fa96476c552,0x0001a9871f6885b5,0x0004ffaab3c7c9d1,0x000d4603f8de64d8,0x00007b2e031462b5}, {0x0008c9e92f0c5787,0x000de242f7202665,0x0003c82030726817,0x0006a6a3eaa87186,0x00003c95078f22e7}}, + {{0x00023916557f453e,0x0004ae26a44583ee,0x000fb5b0a3af5dde,0x0008c41782c4831c,0x0000ea56bb04a5ee}, {0x0000d169d9ff58e9,0x0007dac5db5ca14c,0x00004bf3faad365c,0x000cefa7842801b9,0x0000c473429c32cd}}, + {{0x000d3a6e10d62089,0x0002e7b29cd9afa4,0x000148cd51c8b2ae,0x000a75007bff9823,0x000091ea2803d58f}, {0x000a6e1d7cd54ba9,0x00012006683ca3d4,0x0006b0cc5578ac68,0x0005cbf6720ff656,0x0000c9b8e7ae81da}}, + {{0x0009db6d2b5b0c57,0x0000d45183dbc273,0x000c532d1cd3ebe1,0x000638b8aa1df7af,0x0000d1b32952af42}, {0x0005152b969da4ab,0x000ffc53c8ae6a5a,0x000f8a7ed96e444b,0x00021fa7d3dcb0a7,0x00009f0fef615ad7}}, + {{0x000b2a69f40c9752,0x000d9c51b7ec3baa,0x0003ed0013ffe154,0x000b0917e419d1a5,0x000087bc5ca8dc9f}, {0x0006dfe0e70f6230,0x000bdcab123ee058,0x0001e5900c76841c,0x0001e44fe0b74ae1,0x00003adc613ad53b}}, + {{0x00063c9f8355c127,0x0001540eb5653460,0x000b854039ff3d78,0x0008ae7c2d9a955b,0x00009ca4d64c814d}, {0x0001356a07c69e07,0x000e21ebd8080839,0x000a3b9495398a52,0x000846dcfe86a411,0x0000787df0a13b19}}, + {{0x00027c45c73a8764,0x0001414547d3af8f,0x000fb60a1bb40672,0x0004ae7a70f5fd99,0x000082531e392b1b}, {0x000da4c7c8966027,0x0005e83a98dbec18,0x000a67cc1dd3e148,0x000d57deb57d902c,0x0000f11b0aa60752}}, + {{0x0007d863d57f3414,0x000fe1509dc623ed,0x0008df4273550cea,0x00065f9b96e5fcb4,0x00009ae9885ba4ab}, {0x000ac350b383e5bd,0x000a0f46498bc168,0x000a58596f3b798e,0x000fe6aeb0539155,0x000054e1d4ea8874}}, + {{0x0003b275d29dc04d,0x0007d76747fcb13b,0x000306ea3b2fe9b6,0x000e902e3d618276,0x0000789aaa24ff3b}, {0x000d025585e1c78e,0x000596e4aecfcc94,0x0004f5b5dff9c8eb,0x000695d3ac036938,0x0000d2e6787c6ac0}}, + {{0x000ccd3ce60d460f,0x00007ea73fe2e166,0x000b13997331a00f,0x000bf84382342cbf,0x00007e70f6af3225}, {0x000335bae3648d46,0x0005c252c9be9d30,0x000b173ced6a5a93,0x00062cd16c887a31,0x00002a4f9fbbbf9f}}, + {{0x0005a47a979741b1,0x0009565bbf2dd4e9,0x000af96bbcbc82aa,0x00026bf44f9cd822,0x00004b2b149910a4}, {0x00050f9cdf45d19a,0x0001eda90005e40d,0x0000abd40b1a8e66,0x000244881e5b8a56,0x00000e73a53fe7c9}}, + {{0x0001dd32de445aa6,0x0001fc91cf2f9f3c,0x000cf76c57384160,0x0006f62abd1f13b2,0x000052e2ed7e3fc4}, {0x000d88787f35a985,0x000e2148e3be1e7a,0x0007b25528a99e57,0x00035b65281c2f4e,0x0000c1eb2107c6cd}}, + {{0x00035d5a8c2927bb,0x0008de6d2b0185a1,0x00024afffb21509f,0x00056b3b64117f50,0x000014162b8f15d3}, {0x00024513d05bd8b3,0x000434f9385172af,0x0001a1f98c4d653f,0x0005e9ef0660e5cd,0x0000273cbf1678a5}}, + {{0x0005911351a59103,0x000e04b05be68d91,0x0004a7bede129f38,0x000a1a51eec3037b,0x00009215fc231a08}, {0x000dd81523b72a23,0x000894715cc1a87c,0x00091f600ab80cef,0x0005a0ab3eca37dc,0x0000b2bc149ce4ad}}, + {{0x00068d2c36fd9f9f,0x0002973c5be71204,0x000e5a97f4bb36f9,0x000f1907757b63c9,0x0000fcc1fbc2fc33}, {0x000eb5cac213cead,0x0001c14e861adc28,0x000f903943fc7081,0x000da639df6e310f,0x000040d070b3e432}}, + {{0x000d7619d49860f4,0x000ea16ce8ca2f98,0x000f7a39c2b109d7,0x00055c8ae1632632,0x00003a28a5876314}, {0x000509cc3ed28df0,0x000cc59ccd51ee9a,0x000cdc1784ba5cb3,0x0005898cfd78caf0,0x00008e1987ffc9c4}}, + {{0x0006780551ed5362,0x0000162b85d37aab,0x00052c0a5dccf49a,0x0000008978e8fe28,0x00002aef7a358742}, {0x0003eaf9eb9304c7,0x0002bc6376029477,0x000c2b67f2b6f818,0x00045ae346f21474,0x0000533e9491e7ee}}, + {{0x000821aa8c6a2ac8,0x000818984232ecee,0x00008bcff77eddc2,0x000f1868ed1e27bd,0x000057062274e3c7}, {0x000f1f1e845f219e,0x0006638746018c4b,0x00079c20a4d39735,0x0003878465feda34,0x0000ad6855572cb6}}, + {{0x0009354b24d7ada1,0x0001567cc35e0245,0x000f79c525b386c1,0x00013a1c4fe295fd,0x0000734ae5333989}, {0x00049712b0342f42,0x000a478fead6dbc2,0x00041f2ad87713c3,0x00037135a752173d,0x0000b5a42c879097}}, + {{0x00066a43e3dbd58e,0x000729043504c8bd,0x0001dfe5e88ce125,0x000b8e4a214027f1,0x0000e0bfff41c734}, {0x000497d8ef9bff74,0x000dfbd8ec3dde6c,0x0009dae39fbaeced,0x000c615eeff4aecd,0x00000b575a8087f6}}, + {{0x0006858fe09d95af,0x000e54554313a7ae,0x0003adbfb75fad76,0x0006af4c0e89f84b,0x0000cbc199841374}, {0x000d3daf04bee219,0x0002f16c60fc3b73,0x0000bf406b089be7,0x0004df5aec57f12e,0x0000f4b714839375}}, + {{0x0001a7b34a992617,0x000262b67fd16035,0x000f4cded03bd337,0x000a495f4d446c82,0x0000de7f0ecd39ef}, {0x0004309127b7e470,0x000333eca6abb6e3,0x000e251b37d1836e,0x000e19b24cc67dda,0x00006986f3fce1fe}}, + {{0x00006b3c165ba83e,0x00040763b7168cd5,0x0005b2089849d3ee,0x000158864b408e50,0x0000d1e7c3c11ba3}, {0x000951b1022b0811,0x000a6ba9409ee8d0,0x00082031e38d13ee,0x000986a7af0f043e,0x0000cf5bbfcacd65}}, + {{0x0006ed33eb976593,0x000cb73bb5996a5d,0x000a8d40797d331a,0x0008195eab513d66,0x0000745011a8ad57}, {0x0009172aa1b56b55,0x000681e0477e446e,0x0004dd55b38c0636,0x00046c34beadb245,0x0000f622ee53fa27}}, + {{0x0007b0a3ab20cf47,0x0005b6ecbe5bf999,0x0009b3cdaea41415,0x000dddb1a4af7693,0x0000c87b4d02be99}, {0x00044162383848a6,0x0009bae35ed444fc,0x000b61b91b37a6bb,0x000c991cfe2a21c2,0x000005e9cfbed62a}}, + {{0x000a1a9489a1a5ec,0x000ce2cc85fbf558,0x000f2223a8aee3ca,0x000478fc82ab4b29,0x0000ce60dd26d1b6}, {0x000dc4d8f75b7e43,0x000c8e7ae5cb1be6,0x0009bc9a205da2e2,0x0000b9d8f07fbb11,0x000007c9c2797b7d}}, + {{0x000ba6fe16b74a37,0x000c9ef80b1e2a3a,0x0009b6ba80ac3749,0x000a58cf3522eba3,0x00004f2c5f7bc7fd}, {0x000ae382cb1abc5b,0x0005df37a1e6cd6d,0x0004f4dd227488b9,0x000587f8906c8701,0x0000c94e7603d61a}}, + {{0x000f31b12c8e946f,0x00041998676a0cd3,0x00012cccc0790516,0x000d05413f948da8,0x0000915d9bc125cc}, {0x000631c24a7ac56f,0x000cc7dbbc6a8f6e,0x000a263d88d9b845,0x000ac140e423d536,0x0000abcdfb4c1ede}}, + {{0x00036dfe301d6bcf,0x000976515927a0af,0x000260fcbb9fec72,0x000d7a1d042bcb4e,0x00003986716d1e65}, {0x0007a8b84e008f31,0x0001a9e0bbf32708,0x0003023c184225e5,0x000006bbd97e7f72,0x00007a8476f8c3f8}}, + {{0x000200faf183b044,0x00091921123920f6,0x000df3ccbb457e6d,0x0001c38fa6eba464,0x0000347d78c4d002}, {0x000b2f467c70d83f,0x000a9b0ee2ba361f,0x000def1984834b5b,0x0006757a81659a0a,0x00005cf0e1308d83}}, + {{0x00041ecde4f12ba0,0x00055e2ab6f60ccc,0x000400171094c76e,0x0001f83d982ca07e,0x0000bfd8343191ee}, {0x000f9f86ae6ad522,0x000bd01e24ac8cdd,0x000622bbda9e9819,0x000bfccf5e80a139,0x0000ea19704218e6}}, + {{0x000fb670adeb0531,0x000a2e1cb11d95f2,0x0002237733ba53d6,0x0002af7a4f5b85d2,0x0000d11b8b4df863}, {0x000f21077157d779,0x00029dae46ae076e,0x000ef1a942676f1f,0x000698d2955c21b4,0x0000366784d1b5f8}}, + {{0x000d37ab64d1b8a3,0x00048a552398fb88,0x0001d701426c97ce,0x00054721bdb66fec,0x0000bdc35f96e76d}, {0x000480bc0f59b636,0x000445d5741bd54e,0x00007a408f26f505,0x0003f9d9158c7ff6,0x0000ff89ff1faf90}}, + {{0x000bc2333e034b3a,0x00064dea255dc2e1,0x000153b1d74a371a,0x0009201c2dd539c2,0x00008464ef965378}, {0x0003be3e2d7ffc4f,0x000a0233bf14077a,0x0002bb433fcdcb11,0x000fb8623c1e9373,0x0000767ed200d1a8}}, + {{0x00082d0bd4f64295,0x0009f5eb0d7a40a1,0x000e40bed0984111,0x0000c3c234be2868,0x0000a55bb693492a}, {0x00003589e0e1c59a,0x000b79f78b50c3dd,0x0008e289bb712956,0x0000c85c99d84cfa,0x0000a5af77c7b795}}, + {{0x0006c6e73e758063,0x000aa4c0ca07be80,0x000a771d1a3c2b89,0x000f8e30bbd4d1f2,0x0000707591fefd22}, {0x000baf90e9d177b6,0x0002f80643449531,0x000fa11454675837,0x0002074957d79a89,0x000023d4bf71171b}}, + {{0x00012ff13201e572,0x0001c2d35ca8a962,0x0009211dfb91e1bb,0x000d6b83cbe76c57,0x00005b47bc9b1b75}, {0x000cf3690ccde132,0x000203bdc7c14ed2,0x0009be86fc27ebba,0x0004eba9b9fc557d,0x000081e537c1cfda}}, + {{0x000edfee74727d78,0x000980a22c07efda,0x000b10e358fad228,0x0005c368538ea7ce,0x0000b7ca5d8c2865}, {0x0006c1397b278758,0x000841d382b260a7,0x00040b29c25b9e45,0x00049b72f524c365,0x00001fffd1819be9}}, + {{0x000e1fe027315046,0x000e4a8e9ae005a4,0x000e29dad879e0cf,0x000713338832c69a,0x00003efed8d22203}, {0x000e9be0c541ee45,0x00043c0e163d6976,0x0006689793657bcd,0x0008f5b80673d362,0x0000c7348859135d}}, + {{0x00072bc3bd04c059,0x0008da4e3ff7f4d9,0x00070f0f1e03cebe,0x0004a82cb1df491d,0x0000cff4a142a9a8}, {0x0007a0aa0adfeeed,0x000d8ea5a8781ca7,0x000f8a9d70def5c5,0x0005f0e216119383,0x000056865c8536c9}}, + {{0x000c2b7335282880,0x000df2155af305ab,0x0003cc18f696a952,0x0003e94feda61624,0x0000074ce58fe838}, {0x000d1423175154af,0x000fe1ae0cacb704,0x0006b7521866fd89,0x000dc49d637a4c2f,0x00008dccfc32bf4d}}, + {{0x00058b746d6febb7,0x00056fdc8cde8233,0x000c5724a2fcaf62,0x0002c41d3479ab73,0x0000cd65f0ee0ad5}, {0x0004b4965d7be852,0x0006736dfdce5b87,0x00022e44ee30b9ff,0x000510f3c1fd2443,0x0000b17b0a94a0b8}}, + {{0x000ed9da5acaa517,0x000e2d9bc48b2b20,0x0009589a56d9ec6e,0x0000cd50699c9cf1,0x0000c0682f67c25b}, {0x000ad83acc2d9df4,0x000b491d3a194ec3,0x000f43e0aa5860a7,0x0008825d7c9356bf,0x0000ffd010d5ac2b}}, + {{0x000ad7d4257077af,0x0007d06b6e41f434,0x00081d274d0d97bc,0x000d46b97f058b8a,0x00008141f09a57ee}, {0x00059c2c95a92ba2,0x0004dbd7225bde57,0x0005ec9647f39a2e,0x000a46b029f14b8e,0x0000e8a3e62f0c3d}}, + {{0x000af97ab489033e,0x0005ffc2cbd90b39,0x000bc39c20e78840,0x000b48cd3c1d2d1a,0x000065f064cee3fc}, {0x000a3b79e03ee91a,0x000d739b8fffef5d,0x0008d7784f339ddf,0x000a02d5cc657cb5,0x00001fb78c5705a2}}, + {{0x000fe19eecc5e624,0x000306f9bcd832a1,0x000b535333e9171a,0x0000a14c3dd19f34,0x0000bfd509e3ec8f}, {0x000d131ff598e707,0x000efce0b7cd59b2,0x00008b2e08b38876,0x00028c0e783e18dd,0x0000a91d85b2dfd9}}, + {{0x0004382f883cfa65,0x00007fc08c3e7142,0x00031d2cf6a1e10f,0x000b73831dee9409,0x0000a725ec88ef3c}, {0x000e45138849f25c,0x000af48749f6cddb,0x000d14475f1cac00,0x0002cabd31e17b50,0x0000d48626e3da74}}, + {{0x000d0de0ff499960,0x0003fbfcf664ef0c,0x000452faffdd7772,0x0005d14882e7b0ee,0x0000b786850a0512}, {0x000390625f2d5fad,0x00097f518ec1a4a5,0x0002f3d039da3312,0x0001a9edc17472da,0x000096d8837d422c}}, + {{0x00098d1cd3290a63,0x0009e70dc26c34ec,0x000fb8080a9ca335,0x000e643ad8d71805,0x00009473d89368fb}, {0x0003a8f3f95413da,0x0006d4ba18760cd3,0x00015ad17f92f4f3,0x000ce2649cf662d6,0x00004e46841f615b}}, + {{0x000d33f7c64c592a,0x000b6794f7501394,0x000df640f443e759,0x0001115b48de8e41,0x0000a085e12aedd8}, {0x0008c0b7e2b229ef,0x000b6d02a9baf2c0,0x00022cc20ae9044c,0x000e8d6e6ca27b62,0x00005703e8b98911}}, + {{0x0002cefc1f02f736,0x000540270033b3e8,0x0003ceb47e84f986,0x000e14fc35ec1c12,0x0000f46085bdda1b}, {0x000cbc25542ce047,0x0005a07add73f5e2,0x000320971ec0822e,0x00035a98911e32d6,0x0000881d02f4e758}}, + {{0x000387b347fbdee2,0x0006458ebef829c1,0x000f7bdfa33f4d8a,0x0002883778b30bae,0x0000a57a86aa56f3}, {0x0001ee174ceb06c4,0x000b005d309fccfd,0x0004d56aaf05a383,0x0007b122e2a74e83,0x00003ae917835919}}, + {{0x000b2e078e41d080,0x000d82af788420d2,0x00062fb2b0bd6d30,0x0000d29e31188cbe,0x0000fb42bc94f44b}, {0x0003accbe6f8e771,0x0007513275c93443,0x000099c782740df3,0x000b459fad4b877a,0x000033181c9bb1c4}}, + {{0x000dde73fb0eda0e,0x0008f6af3e12a3b0,0x00070b40f538cf4b,0x000dfc9a8cad561c,0x00005c1801d14801}, {0x0002dc79588dc298,0x0009f476f2307348,0x00070463a39ee33f,0x00014bb90225bd9b,0x000010b40545d203}}, + {{0x00036dc7a7be1464,0x00010d064c152673,0x00019582bc150f70,0x000cb20deb2fe94d,0x00003c415ba4f212}, {0x000985f73eec9d69,0x000f765a6fccae60,0x00097f2f3c826fb7,0x00047dd07d59c9ae,0x0000707066e8983c}}, + {{0x00041a35ed2eefac,0x0003a0fbcccb63d2,0x000fd5d39ee7f02c,0x000d05a5130a3242,0x0000bbb31c95b0bc}, {0x000ca4ba534b4c07,0x000fbe96ffe723e0,0x000b5137627b8873,0x00053eb426e6c7a7,0x0000febe40fcfcba}}, + {{0x000346e0b45a707b,0x0009552613f225f5,0x000803741bd4eedf,0x000933cc8d49c2e1,0x0000a0a7a1802a2d}, {0x00015993942ef2d8,0x000a6714ab7c1ec9,0x00037e0ce22b32c3,0x000ffe9aeaab9bc3,0x000007042cafe458}}, + {{0x000b755d669d39d8,0x000c3024b484f11d,0x00034f49b01e2ce1,0x0008ed0468857e28,0x0000254a9385fdf0}, {0x00055e07a3d440f8,0x00042678ee665499,0x000d14e839ec6cdb,0x00015ef57c3c712e,0x0000ed2a33990852}}, + {{0x000957be96b408de,0x0001ebc7fea66f42,0x000ee42926b6ac46,0x0000b4e4cb455b9f,0x00007fb272c87861}, {0x0005ea64c175d75c,0x000e57ab709e7669,0x000f97d844601eea,0x000524f6c42043f9,0x0000257150f4b193}}, + {{0x00019b55359a6996,0x00066ea8746126f1,0x0003984c698d3b0b,0x000148d30ea757f0,0x0000a5a62e68d1b0}, {0x000b1ceb549a8926,0x000f6127020a2f62,0x000cb3fd49371a21,0x000f1e9c3dfc9693,0x0000f10737a457e3}}, +}, +{ +/* digit=6 [{1,2,3,..,}]*([2^42]*G) */ + {{0x0008da4ebfceed2f,0x000160ab87632830,0x000a7a776b62d8f6,0x0004161d81461a65,0x0000d2503d370ab1}, {0x000a3a28b12e059b,0x0006dba7a43ef9af,0x000eb449b66afd29,0x000b4f497099cf91,0x0000b740d849144f}}, + {{0x000d1cb14db150ae,0x000c2825db119cee,0x000e5fa06f3d8cd3,0x0001519236fc45ff,0x000017232f7c8181}, {0x0008b9e65214d82e,0x000a8d9bebd6dcfe,0x000c1e6f59806e97,0x000d0a1cae163880,0x0000454a197aa771}}, + {{0x000fb2e99ff222fe,0x0002f6cd6bc0c742,0x00011048d43a1261,0x0002bc6c0346ba52,0x00000874002068cc}, {0x000d17dfae243b95,0x000e8b373c9aa0e8,0x000e84c66747a444,0x0002560f7e0b8280,0x0000dcfd670f7595}}, + {{0x0002524b949e4535,0x00090f56a6cde629,0x00006c5056ca68db,0x00087837cf37f5e8,0x0000287aeba17f2c}, {0x000194d41a0f7a82,0x000aff261f9d588b,0x0006ee54936659f4,0x0003de1c86018de4,0x00005bb7bee891ac}}, + {{0x000dd4596bac0c33,0x000a79383e647f24,0x00062bfb0f5a73be,0x00082923eee62853,0x00009c04543340c6}, {0x0004c782a0e9f2c3,0x000e03645715f5f5,0x000fa691a3c1b9a6,0x000e7ab9adcc6de5,0x0000db83ee04ac86}}, + {{0x000d23467ed57309,0x000db8f9d25bed94,0x000dbe922092fe90,0x000764e90499c35e,0x0000cd06d43dbfbb}, {0x0000064077438554,0x0001c32ae4be0845,0x00061d2fcaebf091,0x000c4346a089d960,0x000055f71e1c5a73}}, + {{0x0002f96218c9d5a6,0x0001641dd16123d0,0x0008ab2e1526c4ed,0x0003e09ffc5e3edf,0x0000df1e41035c68}, {0x00077bcd67728b89,0x00047ee4e6273040,0x000cb877fdbfcf62,0x000eff21cb5a44a2,0x00003511953a16ce}}, + {{0x000409ffca73851f,0x000c3de29624b94e,0x0002a47c5c60b925,0x000e16665847cd08,0x00008e7f8ebd9097}, {0x000eeb9e98545750,0x0000ce814b1f1ed6,0x000b01ac8d35a5c3,0x00075837d8e25100,0x0000c3c5bd7d279b}}, + {{0x00076e1d283c6ce1,0x000f7174959c50ba,0x000dc4eaecd286d4,0x000634535982fee9,0x00009158cb09e7d4}, {0x00017b5f6cd33044,0x0002969dcb333eca,0x0005d0e40dd7519e,0x0006b515ebd579a2,0x000024e41aff93ab}}, + {{0x000040ff1375951b,0x000a1e839dda7393,0x0006bb352da54b3b,0x0002ae6c9597e201,0x0000d9dbd47572b3}, {0x00056e9021dda66f,0x000e6fe0123fc320,0x0007cca3903d3977,0x000ef0e68cdaccaf,0x0000bb4084bf66da}}, + {{0x000d2f201031c945,0x000b772e503d6e75,0x00042cdc17bd8ed3,0x0007777ce2a48632,0x00005c328a9c3027}, {0x00070c96d90b6fdf,0x0006762cff8288de,0x00001a6ce10f17ed,0x0004b60b2595dea4,0x0000d81fe47c8c90}}, + {{0x000c39102e4fe37e,0x0007b23e92ab7da2,0x000353e2a4aa27de,0x000cc7a3fc098e3d,0x00002536baff989e}, {0x000be55df78b163c,0x000cb15a4f900b15,0x000738e13e4be770,0x000cf45a8c0b1e35,0x0000d1c8b85e4c20}}, + {{0x000d8a6f91768025,0x000780bb92a70307,0x000ec75e9f0a4627,0x00018b3f31d5783a,0x0000ef5c08e724f6}, {0x00056b23247f3db8,0x00038ade392d9748,0x000a43483fdba1d5,0x000a5c1dc4f1a93d,0x0000b35fcbd53c35}}, + {{0x0006e5b5f09bd9de,0x0000bc9fb162290f,0x000034f2dbce94c6,0x000c8626fd489944,0x0000d0a4061eae30}, {0x000b78b3bd8a273d,0x0009de5ae80b923c,0x000eef67b29524b2,0x00014e750cd4e68d,0x000073f7f21962fc}}, + {{0x000877c7f92f06b5,0x000b95cee57a30e3,0x000ffcb286123ae9,0x00022d50fbf6547e,0x00004800675d1bc9}, {0x0009b9e818f59d1a,0x00077d2030cdc4a4,0x0003a9ed390ee53a,0x0001df3669085b25,0x0000f51fe98bf18b}}, + {{0x000ccbecccc94f0b,0x0008c99893a55b13,0x00041516d980406a,0x00012ad64445dc39,0x000003dcb08f3616}, {0x000905907009deb2,0x000ded15742863c2,0x0003a9de2612f089,0x0003f2f1e316164a,0x000095cdb1f35323}}, + {{0x00048f32683a1106,0x0003a7a5b3460224,0x000343e47d7bd6af,0x000126c091046994,0x00005de2a5b586f7}, {0x000254188f58af50,0x00060974a069758d,0x00091651f61f3bac,0x000a319e608f0298,0x000076b7f2c0358b}}, + {{0x00000d3f381e3ef3,0x000ceeb6c1dc33a4,0x0002adde75fa3959,0x0009beae4a15a271,0x0000d91f39a52916}, {0x0006e68167f8436b,0x000613d0010f1b08,0x0003bdc583de98b5,0x0008ced07b396a51,0x0000f5f1ccd47883}}, + {{0x00053474745b4111,0x0008d69ab64986d6,0x00028504062204bd,0x0000eca3a2c7a367,0x0000a183bd071463}, {0x000618d9a29310fd,0x000c586fd5dfd7f9,0x00026b628f55ea0d,0x000e9141be7be638,0x00009ab70426722c}}, + {{0x000f4c6b7f0b2b2e,0x000b35498ad70152,0x00093c54616a18ed,0x000e4887a4d5a30c,0x0000c8ce85111073}, {0x000b61623a4c2109,0x0007aaf6df31d435,0x000e6d28f6f0b661,0x00010c63d8f4fd58,0x0000a716f19ad118}}, + {{0x0009cc90fff48c76,0x0001a62b3ac032a0,0x000b5de11f98ce03,0x00066f2164aead02,0x0000da752ba1afdb}, {0x000d7ff20909c958,0x00089515a1f95adc,0x000675794b9fa634,0x000e20f2564f7acb,0x0000bcf3634218fa}}, + {{0x000e4e170e87d63e,0x00033b1ac864b298,0x000d6cac3ba652e6,0x0003f216dfe43c73,0x00000994b53a9850}, {0x000ef04ead3ef321,0x000f6d077d47a1c2,0x00091df581572494,0x0004bc458f8e24b3,0x0000c2de27be5104}}, + {{0x0004d336eb2b06dc,0x000d438af59f9816,0x00086b544e2a7565,0x0008feca007deaa8,0x000038b1c05044a7}, {0x000eacd2e1baa833,0x000ab3d6f9a39bf7,0x0005f9a26b4a4cd8,0x0007fe97e08d97c1,0x0000e07374b44b2d}}, + {{0x0004dd2e81908fd2,0x00053362700b61c4,0x00047b4115ede230,0x000e824902002b8e,0x0000fbcc6260def8}, {0x0003325697f653d2,0x0008966e57020f8d,0x0003416143080196,0x0004c4d2fd9b6e91,0x00007ade93e02f1e}}, + {{0x000ecd682caa18e1,0x000f70d2a0a391d9,0x0002000a80040e56,0x000857d371f72e8b,0x000053775b161201}, {0x000f90ea5eb901bc,0x0009364d5c28a36b,0x00005a3daaeff7bb,0x000133f544a030cc,0x0000c4cbbce12e0b}}, + {{0x000f8c9fcc7163d1,0x000572b83e473108,0x000bba1ec860c1e4,0x0001e09ceb4984ee,0x00008bbae4d3fd8e}, {0x0000e95aa9b6fff8,0x00013bf54498bb71,0x00098c0dc39f81a0,0x000f4d5f47a7767f,0x000053d12f97e872}}, + {{0x0000a32458403bc2,0x00082b711c5a4e92,0x000be5918eedb420,0x0007560f86f6b115,0x00009eef65546fcf}, {0x00081bcf351ff9e7,0x00039fdb3c33d733,0x0000221a9d2cfe38,0x0009978c093d8420,0x00008091d026a7bf}}, + {{0x00007fce2951dfdb,0x0009b16e29e1fefc,0x000e24c61a1bc2dc,0x00064ec20795b0f7,0x00006867bc74d613}, {0x000ea7544ff9e1a7,0x000863bcedd14dac,0x000776fbd052c35f,0x000040b845e5e89f,0x00008d3631aa2f1a}}, + {{0x00078cb5cf75d160,0x00082adcd531e19f,0x0001f334ec5d686b,0x0007bcfc67e75339,0x000083292fd5cb3c}, {0x000ca0f2c79e4395,0x000d7220b49dc04c,0x000d3bf945b11bd7,0x000dced7c2b83ea6,0x00005baf7714ff68}}, + {{0x0003508c06e840d9,0x000135b5a2b19028,0x000ee969d63b1a38,0x000161e84ec50423,0x0000f2fa14216578}, {0x0004bfe086722bf4,0x0003cf085472f45e,0x000dfda75e905f33,0x00079bdd9d624bac,0x0000fae3603f75ba}}, + {{0x000ee7df45826065,0x000159449fe4f3af,0x0001d996e565d3d7,0x000672368612ab1d,0x0000b960776c83e6}, {0x000d3ecc1939a703,0x0009f6c9772241da,0x00098eef9abac2b5,0x00032adbadd70bae,0x000062ee5f76ad58}}, + {{0x000fd21287e5c826,0x0009b0b6759542e3,0x00065f7682b53c33,0x000431f1b099e8c5,0x0000215359e247e6}, {0x000ecefb66ae71b0,0x000c047b9bdf08b0,0x0005d0993282cf6b,0x0001c428f51699c8,0x00006ac5644d7483}}, + {{0x0008a6bf88a12bc8,0x000cdb7063092912,0x0001649711d448cf,0x000792826cbe6242,0x0000b333087bceb8}, {0x0006b67ab7ffab12,0x00025a16516d0184,0x000c86a31293dd6e,0x000a457b718e848d,0x00005e930921509d}}, + {{0x00045277b9938fd7,0x000e086e2c20dff9,0x0007dce3453814e0,0x000e253ca6ba6c61,0x0000f538b78fd25f}, {0x0008e6179f3b912f,0x00078b639a80001e,0x000414bf793b6324,0x000bb8e28cac8f71,0x000031ad39adcade}}, + {{0x000a465f76d43f56,0x00090150ef7afe7d,0x000b2300b65a46dc,0x000e4e184f9a0661,0x0000561c2fc130d9}, {0x0000a143683c7212,0x0009a56843b2c208,0x0005135d6f7b6c2b,0x0000a908bec8776a,0x000034f7ab83b724}}, + {{0x0008c05b480c3297,0x0005a07fc36b2bc3,0x00097924fce51403,0x00007eaa739b3ab6,0x0000265fbf04966b}, {0x0002950b0f740005,0x0008cf8940d2564d,0x0005fd0c6b2dbfd1,0x000c6ce9a6b44dbe,0x000084a9579b81e7}}, + {{0x000e916369db82e0,0x00020510f751afcf,0x000eed18f269af1a,0x00013c1ce9324e71,0x00008683d69fc1e4}, {0x0004e5889623baec,0x0009ba4018b294b8,0x000e6bfb3c0b24e6,0x000bb0651dbdf225,0x000027ab085ca68d}}, + {{0x000f09a4ab6c3aaa,0x000de01cb3ba63c4,0x000e95f1d210e7b4,0x000f3a8d12cf38b4,0x000018d1e9f0e6ad}, {0x0005dfe6cbc23716,0x000aa7708956bd51,0x000a734e02a987f9,0x000198b26b6caa0c,0x000066d2bdfa41f7}}, + {{0x0009b8808e884a94,0x00056a949ba89d55,0x0006dd0557bc07d6,0x000df3f286c34b23,0x0000010cc2c61658}, {0x0003c84869304a8b,0x000c4e02538c802a,0x00014310ac59c7a8,0x0004e213a3299cbe,0x00008091b8c7dd4c}}, + {{0x00066d7d54bb7037,0x0009fc78a9ea064d,0x000c8c718ecb6d4e,0x000b29b0b388df47,0x00005ce278ce6360}, {0x000615c03685384f,0x0001493d593abf47,0x0007bd22554fbd0f,0x000cda5b2fbacf9b,0x00000be25106f6db}}, + {{0x000db548aff3dd66,0x0009fc3e222a2257,0x00021af9576355f5,0x00038fa46dacfcf1,0x0000a39c02de3477}, {0x000e5949738ae55b,0x0002b82b325aa2c3,0x000316cfaab2be69,0x000c3155c811feef,0x000094001c4354f9}}, + {{0x000e52c880cebefd,0x000fbac37dc45285,0x00047d8233836931,0x000393a52c077d39,0x0000f2cef1dcb976}, {0x0004fff652069879,0x000f14bd96afc0f1,0x000d7647c5393c35,0x000b655fa3d54814,0x0000b31085f87723}}, + {{0x000c64f583e1f402,0x000473a19323b48d,0x000d2fce8f8f79be,0x000cd0f61edb557d,0x00009ba886a6747e}, {0x000f6589946073be,0x00002e0d1b415ede,0x000135675a16d9b8,0x0002cee38fd0b032,0x0000a1d1db71309c}}, + {{0x0008a92ead7f3bdd,0x000ea3397552948c,0x000df72673192c3a,0x0006ba2de5b32e77,0x00009c0d4111e5a8}, {0x000bd04137e03344,0x00089b4162fd10fb,0x000ebd666ce66159,0x00064d877840eaad,0x0000381e39594fa2}}, + {{0x00000628e098c674,0x0009cdcbf9ca0680,0x000c9f9fe4c5a3c1,0x0000f7b96570ef82,0x0000049c1cd347b3}, {0x000fb672fa7243a5,0x000c2b46489362bf,0x0009a950e91645d7,0x000e29f1b1a58485,0x000003188482ca65}}, + {{0x000e8a5a08e6c7c8,0x000d1896d6be3d81,0x000632895b101d4c,0x00031a37b4f35e11,0x00007da1f2d7abe7}, {0x000576beeab98952,0x000748d0ccd0c23e,0x000b5c50c67fca2a,0x000936a558e370e5,0x0000985eec700203}}, + {{0x00037f6ba08ad439,0x0006926c8ad8398f,0x000df38a044b9452,0x0009463c48a42ddf,0x0000a860dd55a6b4}, {0x000d162812b222ed,0x000fd854816b2dad,0x000e65262e4eb660,0x0005a5b527b029ea,0x0000175bad33bdec}}, + {{0x0002c3da8cbbe229,0x000aa90abc735562,0x000bb0db89d0e690,0x0003454c1c36d6e8,0x000036f4e1df9931}, {0x0000ad2fb609c4b6,0x000745f01f277c0a,0x0004f07d4ce8634e,0x0007939a3356bbf7,0x00009fa9bbd0303c}}, + {{0x000834bdba6935df,0x00068b5bf0655c17,0x00009c8960d66e80,0x000b3b6460148a4f,0x0000f945f0f28aea}, {0x00008c5ad9f47c68,0x00079e9a1df4281a,0x000eb5d36cee9dce,0x000d177605462f15,0x0000bdcbfae25681}}, + {{0x0004c6b9e03db771,0x0001da5fbc75f102,0x000950b5e2ab475f,0x00073cbe4e444a5a,0x0000bd5871471640}, {0x000d74a1ca5ad868,0x00048ec67d0c8551,0x00000d3328df82c8,0x000e5f6f20f8912a,0x00002e0fe080c362}}, + {{0x0001c3d6d6d5d264,0x000b218027996557,0x0001970f15dafe9f,0x0000511096cf81f4,0x0000c9526de03ea1}, {0x0001e30dad4e3f37,0x0003aaa14b7782f7,0x0000539fa89532b3,0x000cc848b2ec61a4,0x00002b6f09d9ff2f}}, + {{0x000dfdd25cf29291,0x000dda0092de30ae,0x0000a4e132261624,0x0007de7dd4994fc6,0x00001c40532fba17}, {0x00018feb438b5b0b,0x0003e95815fe08be,0x000948087b006e4d,0x0005efbc2a9ef7a4,0x000009e6d587a5d6}}, + {{0x000969e4f9206d0f,0x00075a33642fbb5e,0x0001c4b5d8ec63ca,0x000a4b54ef559a14,0x00009b489e45d4b8}, {0x00079fd87810f9e3,0x00005eec7620bd39,0x000e3eca2d32cf90,0x000386a4932bc4fd,0x000080d2dfd12b4c}}, + {{0x0002bab6b693b018,0x0005396af6ef38e8,0x000153f766a56bc4,0x00059f4479f1c4a8,0x000065854adf0b46}, {0x000ca7e73f59716e,0x0006eb462570ba76,0x0001e66b58a3ff32,0x0007e313f7e7d714,0x000075a290729d59}}, + {{0x00062bf29147d07f,0x000b71338d29fb95,0x000a83b78c68c915,0x0008e5f7bbf7376c,0x00002d08e6ebdc2b}, {0x000022479e069a78,0x000529a2b2914757,0x00012616758d3d5f,0x00000b75f51a9a10,0x00005ca72d9581a1}}, + {{0x00056185d307f683,0x000a74cb99c3929c,0x000b06852fc4967f,0x00067199709504e7,0x000075f08dbc7f90}, {0x0007d8f5aec63809,0x00005c9d1e1a8854,0x000031b69a7b3391,0x000d26bf93901560,0x00004fd890aed914}}, + {{0x000e962e74fa42b4,0x0008b6eef166545e,0x000872fa7032fb4a,0x000897ad192d20e0,0x000094230f24ef1d}, {0x00071573ec958b1f,0x000ed4a294849e47,0x000b5bb10b0cb9ef,0x000c1bd82e65ac22,0x0000021aaa1f3222}}, + {{0x0003cf15c474b96e,0x0009e70fb75491a6,0x00055261629d3ef4,0x000ccabb565167c7,0x0000cc5624a31510}, {0x000841e7e25d97e2,0x000c7e403d770905,0x000be67912255f30,0x000c36beb19eb409,0x000000ba1f7537e3}}, + {{0x00022bdb04b10d27,0x000bf434239c52db,0x0008d4498f41ccfa,0x00035c025e14818a,0x0000e4cd009815c9}, {0x000292bfc4a245f8,0x00097364e9de7d60,0x000cb48c1de328ef,0x0007e4db08fe9d56,0x0000d6112b78e540}}, + {{0x000831ddebf9598e,0x000979bb92d0eac8,0x0000cfca46f5cab4,0x000b6015ad2f7772,0x0000d41fe36ef39c}, {0x0003a2ea9b69dc25,0x00042dff273b08cb,0x000f81461d1ffb14,0x000a4c36404a0c68,0x0000bd4f3b25d7e1}}, + {{0x000b52447a59ca38,0x000412904d355b9b,0x0009d306c9363867,0x00067f6caa01f11d,0x0000041bf277bf17}, {0x0009fef689c4169e,0x000e3dc4bfdf9266,0x0004eceb55ee1f01,0x0002944c74b71d64,0x000046d3fb3b5264}}, + {{0x000d89c6b8902588,0x0004a43fc1846231,0x0001866a88efa1d1,0x000fa61d29d42923,0x00004af39ae87686}, {0x000be51bae53ac07,0x0008423ad27f8d1c,0x0003aa54acb70da7,0x0007b8f235bf292c,0x00000305b9d0943e}}, + {{0x000514fe38c4f7de,0x000b829401fdb149,0x000db76997df5622,0x000f807d9447624a,0x00005ac0b00fbb71}, {0x000727b2d9749d3e,0x0001289dda4509a3,0x000629016714c594,0x000780af9268e465,0x00007f6db4424a1f}}, + {{0x0002aae6462c8c00,0x000054a3be95cf37,0x000ef28c0b873e69,0x000af8ca81887394,0x0000225ad865d446}, {0x000ef44f58dd3666,0x000173b419047734,0x0004dbd8a69723d0,0x000254b9684a7eec,0x00008b1aa366d4f9}}, +}, +{ +/* digit=7 [{1,2,3,..,}]*([2^49]*G) */ + {{0x0001aeed239f4556,0x00049d4ddf57cac1,0x0001d2a819808334,0x00000b6a5d2670cb,0x00000f2e4aea4ac9}, {0x000c8f8ccc05367c,0x0002818771212a6d,0x00085497ca404a57,0x000d31fe2406ea3f,0x000066d75813b43b}}, + {{0x000510a53ce5c73d,0x000fc461cc13581a,0x000c24ae8baba850,0x000a7dee213f3d39,0x0000f50e637950f1}, {0x000bbff69e5103db,0x000a85cb5f3beadb,0x000a70f73cee5aaa,0x000c947b2cc95a87,0x0000ba0e771ec061}}, + {{0x00040300d97bfe32,0x0006a033e7779a90,0x0006d553f95b3008,0x0007b47c5e9b61ac,0x0000021b54e152ca}, {0x000c553aa7a3a110,0x00046dd1c7ec0c1e,0x000577c34df1edd3,0x000d7165340112a0,0x0000d5fa7bfd90cc}}, + {{0x000f022a7558380e,0x0001ba7b90f5fdee,0x000e0da2bcb36cce,0x0007745bd4959204,0x0000dd2eac35ad01}, {0x0002c8521c0c5af3,0x0003ad91885450a0,0x000fb8b9f94c617a,0x0001771d86ee2b64,0x000058a7459f4852}}, + {{0x00087c696cede771,0x000a6d45b0f224af,0x000936b54c8b1b48,0x0008998378d19198,0x000043233bf94432}, {0x000fa637bed26bac,0x0005c18a17d7bb9a,0x00086ab22583df2c,0x000cd022a04cdac7,0x000073f0dad5030b}}, + {{0x0004aef507316508,0x0005e17245c6d9b5,0x000bfb309240aa80,0x000b0fce93d46ee3,0x0000cb28ae82deb4}, {0x00028ce7431d4cf7,0x000e6de34e2fd644,0x00027a4a239496d1,0x0005695b9f53f16f,0x000026a63f905548}}, + {{0x000eeda91a8f07be,0x00010b8144a4e27f,0x0005df4bc4b7698c,0x000c15c892204fe5,0x0000de3f93a307f0}, {0x000af35ec993e2fe,0x0004c71f0d310b53,0x000194dcb0a3be66,0x00024460840d4b9a,0x0000015279dfb876}}, + {{0x000dc97176f5fc32,0x00084c41f3ea9f74,0x000fcdfe91636818,0x000109e6007a66ed,0x0000d9337c74353b}, {0x0000aa28be36eb52,0x000f0a17aefcc5c9,0x00073205c1bdaa3f,0x000aa1cff6aa02da,0x0000e49689d28f4f}}, + {{0x000568b08146d249,0x00059da996f8b53d,0x000b5c2a3f70a11c,0x0005b73182b847ef,0x0000b7cbc8379d11}, {0x0001c6a0bb8a4a9a,0x000842be45b2e521,0x00032433b189ace9,0x000b9407f99f918b,0x000034002e73cc09}}, + {{0x0002b2c99ae289bb,0x0005a8aa4e3f5fdd,0x00024d4d0bab6201,0x00089e755c5401ca,0x0000536b9ff65767}, {0x000b91bfbcc62323,0x0004d65e1912fdcd,0x0003cb2f76182d10,0x0009c80f7ce8e668,0x0000cec3a67b10da}}, + {{0x000a8bf6d5778d03,0x000fbd801fe4d51f,0x00093d2ccba1f75b,0x000c28520bd7ebc8,0x00004d0d1b357aba}, {0x000f08f86aeb0018,0x000603f6c973af40,0x0004f47cd1006667,0x00016f77b47974d8,0x000047e82a24dcfe}}, + {{0x0005d1ddd12aa937,0x000401ffeda864d3,0x000e540c0684a675,0x000cbc4f9b990931,0x0000df6e60528b00}, {0x0001f5e0ad0b56b8,0x0006c70bafd39118,0x00050a6ae9d54b72,0x0004803e3bbc4682,0x0000b9184d9f5217}}, + {{0x000608dde1c5dff6,0x000b8a3467306f98,0x000e8e6eacb62013,0x000117376a795382,0x00002bc99d4c1ce7}, {0x000805d31cafc6c2,0x000ec33f2e2c8ccc,0x0007d9e547cce509,0x00073b8f1902fa58,0x0000c31805d21dfa}}, + {{0x000140b741887605,0x000490cd29bd1c0f,0x0007f308ee8d7d25,0x000275aecba30f74,0x0000780fa9561b0c}, {0x0007bfafab75c4b5,0x000f2bd8d7c718e3,0x00065faa7126ee22,0x00084992c17bc317,0x0000c7fdce2c0389}}, + {{0x0006e725b1a6606d,0x000e6576abca1b85,0x0003e60b5a32ce43,0x000b5e491da7eb02,0x0000f4529d1fd659}, {0x000f1cd618e6a1c1,0x0003d3b5f111ef6f,0x000aee2dc2902aa9,0x000819dbfeafe73b,0x00003af3de73bc78}}, + {{0x0008ffd479c62248,0x000654fd6beb4d68,0x000ebb327cc04add,0x00075d822732ea65,0x000044a14f2a186a}, {0x0002035bf8fb9958,0x00026d9f7591361a,0x000e0a6a62a3e29f,0x00023597cfb7041b,0x00007ddf6f52755e}}, + {{0x0001437de25e2c58,0x000a749e6e860bd4,0x0004848f10153cd7,0x00021532257cb78b,0x000082b7e982d724}, {0x000a791c09ebadfa,0x0009cc48599d4809,0x0007f5347df19150,0x0003790eb5e46213,0x0000eda7a00a335a}}, + {{0x000cb72c3119f7b8,0x0006335b4e574c18,0x000df0fee556561f,0x000efa728a3e48e9,0x00001de12a3aa369}, {0x0007bd62de5ff0d8,0x0009cb8e1debaebc,0x0000eeafa40c9382,0x00041ab5aef3f42a,0x0000f23bb1d172a9}}, + {{0x000007ee68dddd09,0x00041db7068d3bd9,0x000c45236df97f5e,0x000b27fec3b2979c,0x0000781fbd0bf529}, {0x00048429ebf0462b,0x00018b77dddaa659,0x00040b96a20bdeb6,0x0009b32be3321f34,0x0000677d50046519}}, + {{0x00093f5b430ae985,0x00063b607652d48b,0x0004cb9ee7647460,0x0008bed34ed097f7,0x000006e6a9aa175f}, {0x000dc50978b6e14f,0x0001b2110553d449,0x0005ca3c3412890a,0x0005f156e99a5a79,0x000027e794aaa77a}}, + {{0x000337bb4674f974,0x000faaf40bb50fe2,0x0001da97103f3a93,0x000f86ae5da89eac,0x00000d28934fa09e}, {0x000fe143abd373e0,0x0004d19798f1348e,0x0005faddb07be1f3,0x0000fce18709f123,0x0000a65d7f258bb4}}, + {{0x000ec2ea13bf8a9f,0x000fff94d1c2fc03,0x0004a5e758d72c01,0x000c2538fcb23537,0x0000519f25ad891e}, {0x000031644a896ea4,0x00095a8473f8d465,0x000e93c5c4dacb49,0x000ebe7a4d3ac4e1,0x00006a7515c98397}}, + {{0x00003531ef7c3513,0x000151a1adfcb1a2,0x0000fe90dea9dc2c,0x0003b8148c62d66d,0x0000b432f7beeb90}, {0x0009b4a3a3eb7360,0x000233afcef8ad73,0x000553d8625eca21,0x000dda60321e643d,0x00001b01349d116e}}, + {{0x00018c3569e6b0ee,0x00024b0d2fb5954c,0x000a0ecb65c4006a,0x000a62dc0f497e6e,0x0000b96b836c3a3f}, {0x00010ca5b00f3cf2,0x000d5a4d44403cb8,0x000ca83b4a082049,0x00032849181d8221,0x00007f7edd74f65f}}, + {{0x00010a1af882102e,0x0002f1c8b66b8d50,0x000cb8b5c86b5ba5,0x000aa20f54bd38af,0x00001096c5fa2608}, {0x00026d294ccad71f,0x000702638eb68c00,0x000abeba69f87807,0x0007937a69ba5105,0x00008964bbd724b0}}, + {{0x000ea9ea2bf0fdf7,0x000eb49d812be215,0x0005067fc7c83d3f,0x000764be2c803ded,0x00001fb9b50ab062}, {0x0006b70932d37f40,0x000d09395b17d0e8,0x0003a6022e7f0771,0x0000b27ee57052e5,0x0000c6cf1f16992b}}, + {{0x000add9e8bef59b2,0x000614c0c4be9be8,0x000e8fd1ff296e27,0x00093497783204fe,0x0000741476659093}, {0x000e8eb504b04abb,0x0001bcf379fb506d,0x000b9b91e1361604,0x00058b7cb22333c0,0x00002497bd48c840}}, + {{0x0004e4dfa0cd999d,0x0008b8d7ba3d9c29,0x000f6ce974ea95f3,0x000c95eb8a425f3a,0x0000f716a99f71ea}, {0x000edb51e52dc87b,0x000b25a37471e30f,0x000e4f019949d742,0x0001d40be1fa0a07,0x0000f2656c3c690d}}, + {{0x000f1a6bbf53c9fe,0x00054f2c7694ab45,0x0003232eb20d9b90,0x0006e109a9e361f4,0x0000bc91dee0ee17}, {0x000789bdbed0ccfa,0x0008288b3f1bee5f,0x00028f5d1ef0caa0,0x000ca42aeac3f01c,0x00006007b363bf84}}, + {{0x0006f0a64f93a622,0x000b3a5637862d42,0x000380c6ee69a504,0x000e6fa7057de947,0x0000433d4e4199f5}, {0x00023cf1f314c175,0x0009f1ff15bc3feb,0x0009fc8449252302,0x0000e595c6fae70e,0x00004481bce01d84}}, + {{0x000f51b3f1021673,0x00053d64db91443d,0x0008e54c650a1225,0x000220d157dc4221,0x0000a3341db93f5c}, {0x000f3d7a5bd331cf,0x00098ff4240a45b9,0x0007ceab2fcf47cf,0x00096f888d766253,0x0000ef3c60ed0577}}, + {{0x00097e010ff08ddf,0x000968240b00767f,0x0008602279b7acee,0x00099242875c872d,0x000019a7093413c4}, {0x00062417e2d75285,0x0005d70899ba18c1,0x00020ca0eb040adf,0x000bc187c981b514,0x00008b8cf4318d4f}}, + {{0x00080a709a32342a,0x0002965305d1f38d,0x000bf1feb4d161e5,0x0008904dcd385285,0x00009237da3aa1a2}, {0x000aa5a46cea858c,0x0009ce6d6f2234ac,0x000c28dcf76092ac,0x000e838a0ac0bd91,0x000030791072687a}}, + {{0x000accda4225c342,0x00029636e0fff56b,0x00021ccb1fb397b9,0x000dc741822beffb,0x0000d48cbd35cefc}, {0x0006d5bfe9ba3d6a,0x000225360b6d5563,0x000741b6001dfac4,0x0009b486b1b23b18,0x0000ef14d08ff4e9}}, + {{0x000f90e78c1f3bb0,0x0009b6f85de2028b,0x00037d91cf6b7783,0x000a3f03a27b6beb,0x000069ac8d736c15}, {0x0000c62e806bd30b,0x000056746a7ab9f6,0x0007ab1b6c245999,0x0000fe72037ecf0c,0x00008ca60c732f21}}, + {{0x000abe30741481cf,0x00040b18ce478cd1,0x000e7f8c34c982fe,0x000f0fe79cffb728,0x000074960aec39c4}, {0x00066aa9050b893e,0x0000122edd8925c8,0x00092c673fe40d52,0x0004b39f8c9033a8,0x0000ce1891820586}}, + {{0x00005206bf1ee33b,0x0000e4979d7a9a80,0x0009b650b8c12ac8,0x00054e4da9f88d79,0x00008aec7e264a80}, {0x000ae68f7b28d79c,0x000387cef16ca493,0x00089b6b0a4dc3e4,0x0003e40509431dcd,0x0000bbe744fec78a}}, + {{0x0005978ad410ef01,0x00014cc3515d61f0,0x000a46f70afcb4b4,0x00041970a01aa3fe,0x0000884ec45da55a}, {0x00063b35165dbca5,0x000cbc71ac33d0cd,0x000e4c38ef210420,0x000cf3a0f23b9fb7,0x00008858d7174d5f}}, + {{0x0000478139115bed,0x00093f433881438c,0x000447a7d8813dc2,0x0001188cb8732df2,0x0000f920508aa0d1}, {0x000bdd9b8248baca,0x00051a0fda74f21a,0x0004f3bd406ce881,0x000c164428836dd4,0x00000a2424cb008e}}, + {{0x00089b69fbbbca39,0x000b1669463edd19,0x000ccb304c3b438d,0x000a7733db961ef9,0x00006f2d432afb6d}, {0x000acc1b78bef59c,0x0000abcdba630ae8,0x000bcad61d6beb51,0x000b213bab1c81a0,0x0000f6c677215aa6}}, + {{0x000314509f77691d,0x000070083e4fdae3,0x000d7f1f5feb96d3,0x000a7d9f0c18c1cf,0x00001b7ddfe0651f}, {0x000db98fcc9de7a6,0x00069a529dcdc450,0x00097718843d4122,0x000d3e0ad913fe75,0x000005594f0670c8}}, + {{0x000e4506cab3068a,0x000d1d2494770a89,0x00030ec9b9955748,0x000846ab8cbf8946,0x00007c89daf9778a}, {0x000acec4f4606444,0x00078c364d73231b,0x000fe41c31286866,0x0005d3f1ce47c3d8,0x0000e365480c68c0}}, + {{0x0003e4160b45a121,0x0003baef5d6683e7,0x0004dd85a1e42102,0x00071f5e34c234f5,0x000091f9fbced850}, {0x0007767771328099,0x000d49be9c6b664d,0x000a38f38d829f06,0x000ec330eedef076,0x000026c48800340e}}, + {{0x000736dd0e1d6e43,0x0005022facfe3f4c,0x000191340b7da1b5,0x000d914f559d6ff2,0x00004e994ce30fd5}, {0x0002295702306bc8,0x00057ed0842bb003,0x0002112cacc1577d,0x000b4491fdafe49f,0x0000ad39b895860d}}, + {{0x0007eec37bfa3de4,0x000b16863791d4ec,0x00079f652f765dc5,0x000986d0c1bbc9c3,0x00002abf602df07d}, {0x0001e932edcf3171,0x000edb53f5fb229b,0x0009b60fc290f0be,0x00091a4acbc35e94,0x0000ba30ad68659e}}, + {{0x000dd8d9660b26f8,0x000350ca1223a663,0x00032ab3d4eba231,0x0002804991c779fe,0x000099f830e34a06}, {0x0000e71d3111ffed,0x000005ce14589dcb,0x000f365f377370cd,0x000623a24a8ccbf5,0x0000059fbf358ace}}, + {{0x0003a4098bbc3934,0x00004dcd090a5572,0x0005a7255ffc94fe,0x000185dfe7e5e6b6,0x0000bee85029ef3f}, {0x0002743db2177911,0x000d5e6bd9ce4510,0x000caa6d30f32aac,0x000f4f7b671a2e7f,0x00004304bbc2b68c}}, + {{0x000a04d9e64e4d35,0x0002ec1e1c9b0135,0x0000551455e12027,0x0002be716a3c508b,0x000085f4f1c5deaa}, {0x000fae6e86f4a15b,0x000864a7631005d0,0x000975559b3bb56e,0x000c45a95a184010,0x000086bd840e2d14}}, + {{0x0000c3fb351ec55d,0x000a716ba8612e75,0x000373c466979ea0,0x00032b4b9a776a63,0x00005a8b35671cd3}, {0x0002093dd7493ce9,0x00006ec41ba2b630,0x00026128f18e92b4,0x0006d1dd3049143e,0x00008405ec34615a}}, + {{0x0005e208a0356f29,0x000e456a9eac7617,0x0001f6a6f856d9b0,0x0008e436387a6c14,0x0000127cd283e4d8}, {0x00000f6a32221562,0x00012f58a6e1e3b9,0x000372ba690134c2,0x0000101938ae6152,0x0000a86d5af405d0}}, + {{0x000699670a64b1ab,0x0001fbf935745441,0x0002aba2b5b797e6,0x0007c9bbf9463769,0x0000dba14e270cb8}, {0x00013412230852bc,0x00022cfc37cc9c35,0x0006bb6af3ec8fc8,0x000ff9c5283e7b80,0x0000a3777b633ffa}}, + {{0x0004f15ce0554be8,0x000ecfa3ddcbe763,0x00055667be6039ae,0x0001a5485efcc93e,0x0000e042ceb13077}, {0x000e81d073599e34,0x000d6585f158bd8f,0x000f7f92cec7e3c7,0x000d61a31bb59a5b,0x000045f686d482c7}}, + {{0x0004eda272cf63fa,0x000636f1a9b8a218,0x000e1b6bb618ea24,0x000da926f4254f89,0x0000afeb6d402035}, {0x000c73357c46ecb5,0x000afe899f44ab86,0x0006183a62887e7c,0x0002c32e74795194,0x00001a51e3704cb7}}, + {{0x00044bb9b131bcf7,0x0006417f905f29da,0x000271aea17d6518,0x000225822f44b473,0x0000442a5c8529e6}, {0x00050fa2d6e447c8,0x0000dfcafbd2ec61,0x000f4ccd550401ca,0x0006a0f1350b7a4f,0x00001ec4502e2e21}}, + {{0x000bd15bf9662113,0x000335bcb1799bcd,0x00031ca94fd47034,0x000e1949d595cf1e,0x00001a8e934c2d2e}, {0x00034f38faa8ec78,0x000cbe16f46d9dc4,0x000bae7880239684,0x000b553e8a39b8ef,0x0000f6b6e14a3ec7}}, + {{0x000b937dc23032aa,0x0003d9c256e1f314,0x0009f15c9e65fc03,0x00090371034ea18b,0x00003c9a3c47dcaf}, {0x000484226b0c9336,0x0005daf367bd47e5,0x000896a1e101650b,0x00011d3fe8f106a5,0x000030553fa62618}}, + {{0x000620f5d69edeec,0x000d7a4eec8de791,0x000287a787907f50,0x0005ea68c4827aaa,0x00001a26fe08385c}, {0x0003a8e0e67d376e,0x000c9cb8e62ecdd8,0x0006423b3147defe,0x000bab0d5392e6ea,0x000093a79e3c20b0}}, + {{0x000e6ca8c201225a,0x000d361ddc9c9290,0x000842db93584608,0x000de2a6a6a74023,0x000052a66d55df1d}, {0x000ae8c9463e80db,0x000b580b54c73462,0x000d39a08482e062,0x000d4f4e9168d66b,0x0000432fa82c4408}}, + {{0x000cd6a07c166baa,0x000d0aab204c73a5,0x000f172b51bb0308,0x0000f224f298465e,0x0000bcb5fbbe0394}, {0x0003887f31da1be4,0x000fab42c7ea084b,0x000288810250c3d3,0x000243da8e6bf318,0x00006e11ea969a39}}, + {{0x00042beab44de79b,0x000d1bdf4e1ef56f,0x00092d95c84dc218,0x000ac84ec350fbab,0x000078c07677a9e8}, {0x0004fbd04103d16e,0x0008505240255fd8,0x000f4c2e83bf1669,0x0000f248fbf6016d,0x00003b3a59853adf}}, + {{0x0004d0bc9d68c082,0x00028f23db2991b1,0x0003cc0616167f9d,0x000e770931c7b4b1,0x0000da5ad5d2e0b8}, {0x000d6695dfec5d44,0x000981be910db292,0x000c7ac75239d091,0x000574e433511309,0x000082d8c29306e3}}, + {{0x0002be7195675921,0x000957bf6119ef73,0x000d96cb0c4d5c87,0x0006f8fa6a706d42,0x000021e1cb73d95a}, {0x00093b14fe798a38,0x000ad3f85e91623b,0x00033662ce9ac003,0x000caedbca9b36c8,0x000092ff41dd7e0c}}, + {{0x00076b51b75fec0d,0x000340db61af3e02,0x000abd899caf72bb,0x000472cd7bd7ae60,0x00007641cac436d9}, {0x000f1a178cf6f1cc,0x000000d23b7cffb0,0x000f77b796e5b6e4,0x000f33328af949d5,0x000010f779508865}}, + {{0x000eb802f32faab8,0x000060554f3b532e,0x0005ecce4b511538,0x000343924e7bc29d,0x0000c15966b6c62f}, {0x000f12a31d85149e,0x000702536a1b1333,0x0006deae7e597135,0x000a1cb884c1d3a3,0x00008b957c6d3bc7}}, +}, +{ +/* digit=8 [{1,2,3,..,}]*([2^56]*G) */ + {{0x000a0db802ad8e2a,0x000198c71fc20913,0x0001af4b76762aa1,0x000d0991a59e2221,0x0000724ce9039cad}, {0x000bf205e5876d57,0x000c736f68df81c5,0x000ab6ba1fb2636b,0x000ffe34868e7098,0x0000261df12d1037}}, + {{0x0003fb0efa0b1ffd,0x000a3fc568975624,0x000bdb4591f15f6b,0x000439654edf2cac,0x000003491ab55faf}, {0x000f3c88c630e16f,0x000e7a922cea29a0,0x00036b058547f279,0x00065d2986844536,0x0000159df225491f}}, + {{0x00016886aba2e444,0x0002ff5dc5081177,0x000694e142d2637f,0x000aae0245602bd1,0x000056094e9d2d91}, {0x000aac623d3970d5,0x000712ba9937c039,0x0003188e393e6d1a,0x000724cb6f2c4b0b,0x000051c7142d857d}}, + {{0x000a6c4126387d4f,0x0000d207fd54b018,0x0002d2c2fa82305e,0x0005af7f76e4d82a,0x00007991440733c6}, {0x0008b1ad2efa1bdb,0x000aa0154ec58403,0x000b501e885ff98a,0x000882de171aa384,0x00007914f6044142}}, + {{0x000ab01c6935b4f9,0x00003b6de76d230d,0x0004d5a6213a18df,0x0007963145617526,0x0000823e1682c1e6}, {0x0005e79ac9b872f3,0x0003ce7021be0c18,0x000c686947c500e0,0x0000a6319f616513,0x000045678a89295e}}, + {{0x0000c88440eaa722,0x000e347df565ba08,0x0000930155047bb6,0x0009d6475a78682d,0x0000591de4ffe082}, {0x000f7732b9087359,0x0001861be64be6ff,0x0005a48107286612,0x000bbfcd5daff943,0x0000410a05140a8b}}, + {{0x0003711d4a4e4fe6,0x0003fe30c63f29e9,0x000a2de989dabddd,0x000323866f1580ec,0x0000b9de281a175a}, {0x00007a398f7e9455,0x000debaed06f5308,0x0001392b17b31e3a,0x000de3ce5bf10e00,0x0000f2a8f37e8d28}}, + {{0x000eef460cea0d86,0x00080c089ea3e5c6,0x000d79ed4ba91ad4,0x000b168d4eb1f87a,0x00004c8dd11d9a52}, {0x0007631e210a2732,0x000522f1cfd893f3,0x000c313c40f24058,0x000538b4a53f3f1b,0x0000805ea5ac03cd}}, + {{0x000f2b4d9647871e,0x000698c6a70f2bf6,0x0000618fa5bbc040,0x000f35bdaacafdb1,0x00004d56a93f6a15}, {0x0002747db37534d4,0x000940549a7cacd3,0x0006eb9286c071e0,0x00086eb8426639ff,0x0000fb0a02399634}}, + {{0x000263cc8597555e,0x0000bcd376a4bf19,0x00078d8efc8cd230,0x000ecce815e792d7,0x0000672dbeb03db9}, {0x000ca483874e7dcc,0x00062391ae793e10,0x000b5a3cd1e05af9,0x00033f3361c5cc5e,0x00001ee94edad6df}}, + {{0x000e3a27b278aaf5,0x000acb57977526c7,0x0006911103ffb78e,0x000ed702ab4ad712,0x000051d4dd701893}, {0x00006061e1dd4f36,0x00024dbe375be15b,0x0000d19abf430996,0x00010fcc798197c9,0x0000dd790c374a6f}}, + {{0x000330e15cde34f8,0x000d285ca782df9c,0x00013e0f4ad9ca71,0x000b872d7e70e9f4,0x00009c965ed8166e}, {0x0006bfdf82982e7b,0x00029a67518e8d8e,0x000332d8a97d85f5,0x00001948637867f7,0x00005ff8016f7f28}}, + {{0x0004eddddb576a2e,0x000f99c20d415c51,0x00088bdcb245ef5e,0x000767739e179128,0x00007e8feed3b2d1}, {0x00060bf9c8d8bd74,0x0004fe343ddabcce,0x000534d9ae42b1a0,0x000cb78d550b1cb4,0x000062a4b409550d}}, + {{0x000c9aa9f5ec19fa,0x00036bab280e495f,0x000ec8135bd5fe5a,0x000257848b5c6e13,0x0000761ea009ba1c}, {0x000dd3c7a0d41127,0x000e4675e99a1705,0x00055926d841432c,0x000ebb9724b23770,0x000008204e2070fe}}, + {{0x0004bd37f61b0433,0x0007488b1baf6c6a,0x0001ff33dd611c9d,0x0003daff36d77f21,0x000012e12b486b0e}, {0x000d3d308ad3a01e,0x000cffbd52d205a0,0x000a3c9d1ddc263a,0x0008c49be3889951,0x0000c3cbb88dc5e4}}, + {{0x0008494d5ac38a60,0x000d1abd383b64d1,0x0008d5867de2630a,0x000e7c899c27a88d,0x0000cc4dc229cdf4}, {0x000e69248c51c51f,0x0001de98813939c0,0x000c9fc3540049af,0x0005acb02b92dd45,0x000015dbe915bf51}}, + {{0x00030100f6fd2798,0x000b5cc6b3f2de4c,0x0002cc9a1693c61a,0x0009d7cd8f059e65,0x00002cf62e1b8fd2}, {0x000b441e397cce3e,0x0004b8ee5b2a90b6,0x0001f1bf731ac8fe,0x00044622a0067d97,0x00007c2cb7412bf5}}, + {{0x0005ded4da08c914,0x000c57bc50d57705,0x000c17c0e5e74346,0x000674093e88cce1,0x00009d958b500cee}, {0x00011fd4c2ef91c2,0x0003d68c5fc39edf,0x000a3b166dbadb86,0x000c83e5a523a4dd,0x0000e1e7d5670101}}, + {{0x000e3abd49188ad4,0x00088dffda2a80be,0x000f3b05945c192d,0x0000c7b93d42d6a9,0x000002b90dd3fd2b}, {0x000346bd29b792b4,0x000c03609852e2b4,0x0009c492438fc4c5,0x000f90a6d5d4b916,0x0000d555a212879b}}, + {{0x000fdb47bd87a424,0x0008b5138112db69,0x0008d1d2f115354e,0x0005bc50db48e3da,0x0000aac2eb70e66f}, {0x00051bc6aba63664,0x000e262acc9ce72b,0x000438ba3085117e,0x000822be56bb230f,0x00006d5cca79124d}}, + {{0x00053f5fe3dc39cc,0x000b414d5f67bdc8,0x00046b348c10dd5e,0x000770a76e02dbd6,0x000009c3240fcb02}, {0x0008fb52645c9dfe,0x000c18c396fe8d53,0x00092dad0baa2238,0x00018629d37c8b0c,0x0000c60386360546}}, + {{0x0004a8de81e01bee,0x0007f8321592e20c,0x0006931b55bb7970,0x00076794a7e10024,0x00005ebf25e72a07}, {0x000483a0f5a9edca,0x0002bb646d9e6312,0x000e37073230f82d,0x0002517b5dddff68,0x000029ce765a98e3}}, + {{0x0000ae6e544c6ea6,0x000b57855552f6d8,0x000b8a5e25ebab2d,0x0003d955707f9c00,0x00007b357c483d08}, {0x0005361eff79a535,0x000156e0268e623e,0x000996462124b446,0x000a24e231e90f3c,0x0000bd6b1f150e05}}, + {{0x00040b77de486a19,0x000cf6c03fc07914,0x00036c6bfd63554f,0x000429473dad2c7a,0x0000929e308049f7}, {0x00070a9c2bbc1283,0x000621dd51016272,0x000eed7cf3413478,0x00025a8e63501e29,0x00003512397dbb12}}, + {{0x0006891e7084f0f2,0x000fd6a38da9e393,0x000256ae79ed2f3d,0x000d874a6b4d7cd2,0x00007695b9534b5e}, {0x0006e9d024eb60ec,0x000c40f326d7afea,0x000852c01e0e4684,0x00071b37bae69e1e,0x0000a388523fa1cc}}, + {{0x0007b4d81320b2e9,0x00042b4678e1317e,0x00031c45fcb6ea5c,0x000c542ee5785311,0x00009b995cc107ba}, {0x000eaebcec18878a,0x000a9849b1c2e018,0x000ad5438bae1123,0x0007805e180c0e02,0x00002ce8e4160ee9}}, + {{0x0003c9f0bf831b63,0x000e9bbb471a25f2,0x000ed4ce91f1e7dd,0x0008472d76956795,0x00005e67d84a19be}, {0x000eab76f5a65259,0x00060239051663e7,0x000a9f4ea42d2626,0x000b8a344f8f5d2c,0x0000bb99d60d6793}}, + {{0x0008053bb8d37d24,0x0000355c03827c18,0x000a8454066ad23b,0x000f6d341b9405ea,0x00009fdcc57978a0}, {0x0004e26d8aafb17b,0x000c4ec79ef02ddf,0x00008c46fe8c88b8,0x00016777aec8ea64,0x00005ea6fe832ac5}}, + {{0x0003b361878c3d3d,0x0007921447678781,0x0009b469595fe31b,0x00055924b0bcc3b2,0x00003e4b82a2e59e}, {0x0007f61727308214,0x000569f22b76dbd2,0x000233c6e2a1b59a,0x000e7aa7cea941b6,0x0000a51665729aa9}}, + {{0x000cc4b553fbe60d,0x000b1cc8f5672bc8,0x0004471a809c494b,0x000e7ff3633cdd40,0x000094b3115ecf90}, {0x000e7e954727f93d,0x000b292aa6dd5242,0x000798c3d8b2f132,0x0009e8fae560b438,0x00009604a24394ff}}, + {{0x00074df40c36a876,0x0008139bcd46117f,0x000f04c1dd9ab144,0x0007151706edf335,0x0000ca29fddf0c9f}, {0x00077943d7b52cc2,0x0005759e0b8ef052,0x000c4fbae923b66a,0x000b4312d8827f47,0x0000b2cac97b4362}}, + {{0x000ba3b3d8c333e3,0x00084249ddfc6f82,0x000412b21bbeeda4,0x0003f2feb78ebe73,0x00000f4a98190b90}, {0x0002b13fcaefd68e,0x000db2497727d8a1,0x00050310717e05a5,0x0009b4f4db117595,0x00002bad33ee056c}}, + {{0x000aa899669a94d0,0x0001eab7a00c5660,0x000041a733d2c8c1,0x0009450c1e253b75,0x000017bf47981a80}, {0x000f809d4fd21a7d,0x000be6533241ae79,0x000d829dd7bdcd33,0x000be78a25e57321,0x0000c09f94cc338d}}, + {{0x000f8d0a468848c5,0x00047b41a21d9ca1,0x000bc0e5b17c3f9a,0x00029374333d5705,0x000030912604ccc2}, {0x00008d0d6ceeefc1,0x0002a8c72cc8005f,0x000e6cd79d355262,0x00085d0e66445e88,0x0000b6ec8a4e04c2}}, + {{0x000dbc54066477ec,0x0000a8c5bea950c1,0x000684204e2e4f7e,0x00086fee8955629f,0x00009b1f71580e9d}, {0x00087fc2c0029688,0x00027479146bdc72,0x000667694cbc6782,0x000b7b2f7af3baef,0x0000f7f90385b159}}, + {{0x000bb32253f3a82d,0x000b3a639c9cb63d,0x000360890138bc41,0x00057b610a116196,0x0000ab4e04b9e339}, {0x000ae727cbd17ddf,0x000a2b1a48784582,0x0004ee4100db6d3b,0x0008cb38cff9eb42,0x000029b0c8dd23a8}}, + {{0x0005ed5e3f62c22d,0x00032b06f482bc86,0x000b2a80097544a1,0x000c7f76ed319dc3,0x000088eb3caa8336}, {0x000408416a3468e2,0x000cfcaa5c73b399,0x0002ccb5869caecf,0x000834622f2f7c10,0x00003ebea2e23bae}}, + {{0x000f634159c3f145,0x0001a314fd75ceb9,0x0009e502cefadb01,0x00082007b8010960,0x00008a2bf184a15c}, {0x000886d3ec835a82,0x00004bf7840e310a,0x000d8eaf18c9f355,0x000c84d39c35be1c,0x00003fa5437b08b0}}, + {{0x000e7c76ba48af4d,0x000a39c3a01a8fd9,0x000c62e23ddb4853,0x000913a6ec0c12f0,0x0000b9479a5d516f}, {0x000b51d7e32dbba9,0x0001abd8aa7d25f0,0x000afffda4d3a475,0x000270e67e9ae172,0x0000c1fa7bf9b1fb}}, + {{0x000931c17cdd8a73,0x000e0448a021a8ba,0x000920e03df7fecf,0x0001bcbd374eea3f,0x0000c62edf80f11e}, {0x0001ce6736088569,0x0003c0fe97f45d51,0x000ddb622fb70fe3,0x00042189193abf63,0x0000bace900bcb83}}, + {{0x000f81a878a56754,0x0004f75c479fee4a,0x0000afb5829b49ce,0x0005854186889ece,0x000032530cbd047d}, {0x000be7c429c1cf6a,0x000cc541d81ed275,0x000d999296d29cc7,0x00011ced6e04b532,0x00007aeadda8e71a}}, + {{0x0001699a94bbbc79,0x0000b3ed33d3b98c,0x00012db7668dbab9,0x0004d7e3a0ec5fbf,0x00002de225c570ce}, {0x0005c39338ab6850,0x000f612c245ee97d,0x0000222a78aa03b1,0x0001e27e4e3af28d,0x0000e34817cbf8ba}}, + {{0x0006fd6e8a4a3f4a,0x00070c75489636df,0x0002579d316b0e9f,0x000fe12b5fb3bc1f,0x0000fe57d4f72a95}, {0x0009a194ceff9331,0x000354f75a487036,0x0004549b046aab24,0x00032749a77772fd,0x0000f44e63c940f8}}, + {{0x000f73f8f359b8e8,0x0003626aa63db40c,0x0000ebb81b7bdea9,0x000ce970626f7e55,0x0000c692abaa0eb5}, {0x0009cffcdb9d6804,0x000f4c9bb068b774,0x0004adbce122a50e,0x000b00be247e3384,0x00009320ea728f86}}, + {{0x000300cb47746a83,0x000d765cce2bcb1c,0x000afbb2ba8b05a6,0x000c89050d56aac6,0x0000f10deb3e6496}, {0x000f6adeb5e3c3ca,0x00005b59f7d73f44,0x00034333fd8fef09,0x000cccc06179b892,0x0000d42424834343}}, + {{0x000cd7b1178680b4,0x00067205cb9300e2,0x00022f86af9a63f5,0x000dce7ea9cb6c53,0x00004736f3842b23}, {0x00053bf6f5d17905,0x0001af4b062f5ef8,0x000c8e412a224d5f,0x00097adffffe0026,0x00003f676531b201}}, + {{0x00046ade65aa0b35,0x000ab957bcc5a7c6,0x00021fd3aa044a8d,0x0002d742145aae3e,0x0000d79efcd7c6e3}, {0x0006479ffb6a9280,0x000fcff2758345e5,0x000cd168eaebbf6e,0x0001d311cb1cf204,0x0000d5fd7233e385}}, + {{0x00021f9564df392e,0x0000cdfbb4120dea,0x000697ef6773fc9e,0x000b33b64b26b1f1,0x00002ed2ba1b7d83}, {0x00069e6145eab824,0x0008a8dbc68bf47f,0x0005827d6b1acd9f,0x0009476929807897,0x0000cb8cab70e2ce}}, + {{0x000ed39da3052f0f,0x000d683870bcdc6f,0x000c41480005e7ed,0x000791569848974f,0x0000beac60351f97}, {0x00001799275b950a,0x000212527d574202,0x000173d93889bee7,0x000bea8685758a76,0x0000cfa1096d830e}}, + {{0x0006dbc7d5bcd224,0x00049799a90fe43e,0x000bf8e13f9e8a5d,0x000a40e9cc8d918c,0x0000f177852be5ed}, {0x000b278ab0123dd5,0x00010994e23c910c,0x00023635812c11f7,0x0002ee5d1ffddf6d,0x00000572865c55b3}}, + {{0x0007eec59607df89,0x000f6fc041bea2df,0x00025c8a86ba453c,0x0000ffdb8cd4fc82,0x000014b0c0ae3f77}, {0x000cb43d27069607,0x0001c526ab3aa02c,0x000c9d06bf4b1f88,0x0001c5df41cbbb56,0x00004c4747afd9b5}}, + {{0x000a373fd41c7efb,0x00008eee150edc52,0x00072492cd833b3f,0x000e6300f3ccb31b,0x0000df8c0cc0bc7d}, {0x000a3eb385d47b1a,0x0009bb3430739063,0x0004ff4afb3a8a1d,0x000739f02eb25348,0x0000cc1efa44f33c}}, + {{0x0000f4a61e1db8d0,0x000240c3ad0a8e2b,0x00003e752f6d15cf,0x000f1a4cb501fcec,0x0000253b9aa06d6b}, {0x00012854f610f356,0x000b9e867e0b0f0d,0x000cb4fae8d8d727,0x000e686ca560b0d7,0x0000fb6839787c32}}, + {{0x0008c30ba2a7b38c,0x0002c05a1e186e3f,0x000aa6ac9caa3aff,0x0002b57828d97c22,0x0000aa7fc12f8eff}, {0x000efe970785dc5d,0x0009dc8818f3ac30,0x0009c0b682ad0746,0x0008e4675851d1cb,0x00008a8897cf8c31}}, + {{0x0001252f65cf5ee5,0x00088f29ac5a604d,0x000ac9bbce3667bf,0x0006a0c6475eb601,0x00004bbc154f2060}, {0x0008776fe257543c,0x000a239d34de6a98,0x0009a87768ce62b2,0x000fab0fe16c0d6f,0x0000926673d22d5d}}, + {{0x000b2b3ad94a7b97,0x0008fed58b128f18,0x0008946706b30053,0x000479259ca13ce2,0x00006d23f69d840e}, {0x00025e4177e33430,0x0001bec8e41e4120,0x000d93e910ab22df,0x0009ade579d0c842,0x0000e273816addac}}, + {{0x00002ccc6fe7dff9,0x0009b502353dbed7,0x000ac7e295c845f3,0x000f70849f73ac4d,0x0000cd4776c48c6e}, {0x000669075bd0861c,0x000bd7cfe206c5c1,0x000ed7294a8a2fda,0x000631c9abfc3e62,0x0000ac1761b8c654}}, + {{0x00056155c59e3804,0x000fc6e8eea72563,0x000b382c5c09c5a2,0x0005601fb0724e41,0x0000a8641a0b7d43}, {0x0006e955b7a680f5,0x0009f5c576494068,0x0003be93435b2e37,0x00051a6a679fa13c,0x0000a5238a3c9d8f}}, + {{0x000957c5dad3b707,0x0006a860fe3b104b,0x0003bcab2013b711,0x000909be66aeae78,0x000014befe48deb9}, {0x0009073742c9ed9e,0x000a54923d3e39f5,0x000340d1ddd320c1,0x000b66ed03354572,0x0000f7d8e0dc288b}}, + {{0x000a09a0d72bae2a,0x000846530c949b89,0x000fc27421739535,0x000c46467b80b4a2,0x000049fd2b8b03fa}, {0x00047f3041803387,0x000a220b9b0be858,0x00019bcc545b9dc6,0x000a8ba2614c8a67,0x0000f019df8137ad}}, + {{0x00091858054e09c5,0x000179f271fdc8ca,0x000544ccb6eaaa79,0x000a8115523b3f72,0x00000e9b891c122a}, {0x000c7af09e9c2711,0x000a1a2a3a281d16,0x000a7927fc4edb0f,0x000f2cb10b6c326f,0x0000487e43472560}}, + {{0x000c0c37e2cff914,0x0006f180c765eabb,0x0003ddc4575d45d5,0x0008a0dd271d5c6a,0x00006393dbeb0d29}, {0x0008b4d194b3cc34,0x00073b2327d37a43,0x00016dc625fb4e30,0x000d1937f15f8154,0x0000fbc9f81b7d07}}, + {{0x000db8bec3a5d60d,0x000e4aa12f4eec94,0x00084204e9449ca2,0x00024cefe7cfc0d6,0x00000c8fbdf94de6}, {0x000813864f28dbf2,0x0004ab156ec6f5ad,0x0006721654073837,0x000938a6d1b62c4a,0x000068b432494983}}, + {{0x0007e91a84283e66,0x000bd6aeeb6f7400,0x0008a39d7929a015,0x0005543ca7019543,0x00009dac0d6ff2a3}, {0x00049431bd9902dd,0x0008243c9a6f36ef,0x000314d8d81ff65b,0x000423dd900e14c6,0x00000a4a34591300}}, +}, +{ +/* digit=9 [{1,2,3,..,}]*([2^63]*G) */ + {{0x000383af5664e7e2,0x000b6de6b7968a12,0x0009f4c5338a7675,0x000c15b898bae977,0x0000425a4bff82b8}, {0x00042e3b2dda3220,0x000b8c25241d990c,0x000f6aea17aabb56,0x0005ec6348df82e9,0x00006ce9658aa8d7}}, + {{0x00002787f882d1b1,0x000092838067fd23,0x000e893587ab9dde,0x00080ecb05c101f9,0x0000374fdfb598bc}, {0x000b09697248eb9b,0x0007e7ad923f4c84,0x000109184ce9bdb8,0x00013b128cf5cebe,0x0000ec24ef3b3889}}, + {{0x000944e7099b0bd8,0x000b1d537ca60adf,0x0008486e846852bf,0x00068d48e47fc8c7,0x00000d6c7de2929b}, {0x000987a8e27182cf,0x00074222fc3b99be,0x0007d0d1d309bede,0x00052f53cb0aad2d,0x0000f65f3dd24bca}}, + {{0x00020afe823378bd,0x000482dc3af323ad,0x000605e6877ccdc1,0x000ae077795ffeb9,0x0000845b442d429d}, {0x000ff1016818e3da,0x00066b078681d060,0x00031508ce71189e,0x000e406443b1e66f,0x0000623d9847ce12}}, + {{0x000cd6f7fd3f5519,0x00031e2aad87484a,0x00089654d2767308,0x0009ab132e31f05e,0x00006d3deb114a4e}, {0x000838481a653456,0x00035a31e914dead,0x000e292969158f5a,0x00028101fed010c0,0x000004a96f918ab8}}, + {{0x000bdfb703ba17af,0x0002cc4c9c4a5470,0x000b10c4a0a49397,0x0009166a2be76243,0x00000e3312fbbc81}, {0x000e0d4441ca1098,0x0007c4cf80735a8e,0x000250bc8597d46c,0x000ae9d302662bb7,0x00000b98758a9150}}, + {{0x00029cb244f2a00b,0x00002a5ca85559c2,0x0003d6204ed00e65,0x0003736e24ccaea9,0x00004d64bcfaa3e4}, {0x000b99a1975140f1,0x00011452dcfbdbb7,0x0003320cd47e6913,0x0008d1132c93a100,0x0000c845f62ed4f9}}, + {{0x0007c03d7c90a692,0x000ff6139f403262,0x000a916341661a22,0x000a50f3c701c63f,0x0000fc4a23f87ab0}, {0x000307b826279712,0x00040ecc37944070,0x000d90e024f1cfb4,0x000986d684936aed,0x00008b59b0818a0a}}, + {{0x0003cc56e8a58cfb,0x000ef645720b7ad2,0x0002b007e30ba2a1,0x000aa9db14cb4a09,0x0000d1f68b371a1c}, {0x000e1ce22bb53b31,0x000e06d532c443f4,0x000a47f15e80c1ce,0x0009bcc885a253d1,0x000061f7667f031a}}, + {{0x0001ec094d82f598,0x000e76868c8fc9f8,0x0006eb6e2aa85998,0x000f863c0b776229,0x00009ebfbdd5d6cf}, {0x000c395d97adaf8f,0x0009b131054a3d02,0x000c908ef314a2c3,0x000dc1eabe4e52a9,0x0000074223caa8fa}}, + {{0x000960a997f80b8f,0x0002574eeafbe347,0x00063a35458a6961,0x000959c7e7364dc5,0x0000b4cf05fd40e6}, {0x00049a6133af3f0b,0x000e62fe5ab6cc23,0x000fab20cf050c2f,0x000bba8ca2cf4997,0x0000e6736055bfbc}}, + {{0x000ef812191ed798,0x000315e7a6df324a,0x0005ddb2427d462b,0x000068f036fe19e2,0x00006eb983703d74}, {0x0008114f4f93c566,0x000e92bd193d9efe,0x000ee2b5a701a0ba,0x00003dff40a1ad85,0x000032ba327506a3}}, + {{0x000e85754a60d6f8,0x00078cd09cea9b87,0x000d99e0a120c995,0x0002e2c46af84652,0x0000cdebf2e2b109}, {0x00059f3155bc92d0,0x0008b8beca561249,0x000b156131d692d6,0x000046cab8309442,0x0000e1db93bb8bc3}}, + {{0x00091e5ece80aac8,0x0004c050f1825938,0x0006020f5726a25c,0x000a35ec48344664,0x00007fd9893709dd}, {0x000c9bc10425f548,0x000d2a56bcbf5675,0x000da5191679c8a3,0x000303a7e6e78063,0x0000f14860aa1e8d}}, + {{0x000bc50407ea0a28,0x00025007431b93e1,0x00055d0ffd5cf6dd,0x000aa71a55e8c0ac,0x0000f7f913113bea}, {0x000075d17988cb54,0x000b0f10950926bc,0x000b82f37b6b32bf,0x000e90e2937113ba,0x000081507f1a3652}}, + {{0x0001af7dc8c1da8f,0x0006951c6c9cc65d,0x00013a9509e4508a,0x0005bfe1ccb78920,0x00009fd6a67c65bc}, {0x0007a0698fe8bfa1,0x0005330e47adbc82,0x0008c7bae1477953,0x000e2a4028e9aefe,0x0000e977aa9f875a}}, + {{0x0003cf64d646bbcd,0x0000731b0f3ca569,0x000d322aebf578d1,0x0003eed7bffd65bc,0x000052a965205742}, {0x000bf947dfca9551,0x00086f7f3c853793,0x0007560c93ea9354,0x000c6925cdcceabd,0x00006d6f1ca191c5}}, + {{0x0007f133182d35c5,0x0000458e49b6d3bf,0x000ddcb73784e7a6,0x000a6aac37769247,0x0000fb26f76fabcf}, {0x0001ec3853bf14c5,0x000e7aa2a072ab68,0x000d7447c7e088fe,0x0000ff4d93e78cd8,0x00009fe9f418ede6}}, + {{0x000bd19d394d62fe,0x0008b38a0d8f64ab,0x000d938764136c16,0x000f4e72039b4ef6,0x0000849491679644}, {0x0009ba557055c06f,0x000dc7bdb007a9d4,0x000ba1745af2aec2,0x00015963a29318d7,0x00004187f01e40d3}}, + {{0x0003790c271585da,0x000ed5ad056f666e,0x000ee31740b9f498,0x000f8992c64d1268,0x000057c0938d8ebd}, {0x000298e2374bea71,0x0009768daf973b0c,0x000a2d513284e305,0x000c9eaf3e9e5fe2,0x00001291b298bd83}}, + {{0x00007ba27d3f2f53,0x0003b984e0b60811,0x0008eb875a3de64e,0x0004b33536bb951e,0x00007b9dec8b54be}, {0x00097920a0321af4,0x00038ad145d78b4c,0x000398b33b4205a3,0x000662f72f46d835,0x000081db115da0a1}}, + {{0x000d732092e35463,0x000b86781f2b173c,0x0003cc924b3fdc2a,0x0000dd4011f8eec0,0x0000d8fea672cc8d}, {0x000be33d826c6f6a,0x000a55623182076b,0x000d30071e7711f0,0x0002af15f3579d49,0x00000e7e0ed76e1b}}, + {{0x000d7abf4bb64eed,0x000c77dcee5b655c,0x000413063595edf1,0x0008c03bde3f3ddd,0x00008473cd3eaabc}, {0x00009fca27519070,0x0001a00dfd0763f0,0x00073571029941ca,0x000cb885e258bba0,0x00006ca17e26473d}}, + {{0x000a5610e0e8924f,0x000ff65b0e50d4e0,0x000400c48de61d42,0x0003ab903b10a4ed,0x0000007b9332ca3a}, {0x000f94cac8105ccf,0x000774a0a98a0b7d,0x0006b6f26564134a,0x0001f89637e2a236,0x000050ac987f5af1}}, + {{0x000a8d78638737d8,0x000c7cba5d96bf5f,0x000baf6465e23c9b,0x000bce6625837e83,0x00001f7b1951beb4}, {0x000cfde3643f8760,0x0007e0b1a62f4c1b,0x0009f918acc64067,0x000b46863c488c82,0x00007eeb70136714}}, + {{0x00038b733005eaec,0x00069bc862a3754b,0x00082e20a6c7da3d,0x00057108fdec85db,0x000022986577100b}, {0x00050a08db1555eb,0x00042a9d5da8256d,0x000025309b01beb5,0x000ddfa119befeff,0x0000030fdcce76ca}}, + {{0x0005d057caacf707,0x0003d6856c44b3cf,0x000bb66402bb6e67,0x0005d6fcf6d21aa4,0x000073ffa1ebc9a8}, {0x0007b52ffeaf8928,0x000b35e49a37db24,0x00070c9914f1e14d,0x0001ec5174b1f793,0x000068dbdc6a0007}}, + {{0x0002077a6effe60c,0x000e9ae84ebb9b28,0x000a90020b39c7e9,0x000c72996fc825a4,0x00009d2dd8f89811}, {0x000de4719ce198b8,0x0002073bd8ffd842,0x00091284580c3d61,0x0001c29d754578eb,0x0000e5723eaf004a}}, + {{0x000ea43768534f8b,0x00051abc588d36b7,0x00095d1fc7b73df0,0x00059713790bd820,0x00009bab617eb6a4}, {0x000918138f1334ab,0x000287a8ecff86f3,0x0007dc27cafd58e0,0x00090f2bea43a4a5,0x0000876309bff8e0}}, + {{0x00040a23110d738d,0x000d4d107a0cd20e,0x000fdfb6a9c754af,0x000106b9828ccb2c,0x000019c605440704}, {0x00026be98b9211c5,0x000da44d15bd9119,0x000db2afb42c11b6,0x000ef7dcddaea218,0x000006a2d4b20f0a}}, + {{0x0001358309571482,0x0001812df972a300,0x000a8cab38d53d41,0x00080cc32e21acfa,0x0000e6a672ed9fd1}, {0x000d45c4e36faaca,0x000be60297f9cf33,0x00070c34df7f4d7f,0x00001dcb91ebe024,0x0000d911f768257a}}, + {{0x0007255a2e0c5dd5,0x000d22bbbf673853,0x000ab32207a670b8,0x0008fe78ebe9b99c,0x0000fdde390be12b}, {0x000115f1b1cf88b4,0x000fc8cd1c7f9323,0x00039787a00aa2bd,0x00052384bc65bc2a,0x0000b21156bb8e1d}}, + {{0x0007c6bedf5eb992,0x000ccfb71e9c6a08,0x000a23eae9cb1f72,0x0007b145f4b20c36,0x0000cdd6cd364c1c}, {0x0002b96009e153bf,0x0000791667fd4b16,0x0006d6b0e682b36d,0x000dce91c1e9f97c,0x0000b3acb50ee02e}}, + {{0x000ffd490f51cbae,0x00013a606f79d85e,0x0009bf4dbe0ae081,0x000c1de9ba256a47,0x000044c5bde85698}, {0x0003bc53c7a38530,0x000bb62a6e6e5c80,0x000103b8eb6cc532,0x000dc7a5791e202a,0x0000707bc1728e28}}, + {{0x0000b00ef08771e0,0x0001e0a13ee687b0,0x0001b533b57773fb,0x0009a5ccaa4259f9,0x0000b79966f77917}, {0x0003e85beb00e9ce,0x000df3ff0394ced9,0x000c6bf70673db5a,0x0003f1d646c1a702,0x00007ad3795a15d2}}, + {{0x0009e4bc97bc7da4,0x000771d5ff2a522f,0x000985f8205c96c1,0x000f2cc4eaadd196,0x00002c57d9e6d752}, {0x000d1929233b3620,0x000e75373d1e4ac7,0x000b30d44f4b9421,0x0007bf6bda441140,0x0000bfb154cbcad3}}, + {{0x00070a4205b81469,0x0009a9885929e3d4,0x000ad5364994946f,0x000dfb6f3fb7423e,0x000003c1097c2e3a}, {0x000dc4ea3c0c73f6,0x0000a781ef8a533b,0x0008fa9cfdfb0cba,0x0000a169994d9edc,0x00004caf3b9da044}}, + {{0x0007bff77c009156,0x000b45f526c72d31,0x0009ca544fe44325,0x000af0abe60485f3,0x0000d0555feb6700}, {0x0009417bc4ccc145,0x0008e6c415362ec1,0x000df5ddfbceb3a1,0x000947ada3efdb22,0x00000c675f6c474d}}, + {{0x0001b02ff106393d,0x0009ab788c98851e,0x0004e8fd1bb09653,0x000a43a2d782d5da,0x00008c9f428680c1}, {0x000ad17045780bde,0x0001b95cdcc517cc,0x00061b333987fc28,0x00047c5787ae170a,0x0000f427985ca04d}}, + {{0x0008761292146075,0x000a0cf3aec278b9,0x000329f90f12cd22,0x000d72cb478d1718,0x000082d33765d490}, {0x000d6264ebe63b58,0x000388509017bfc0,0x00049f0b28500032,0x00044eb2df475953,0x000023dc015fc527}}, + {{0x0001a099d4037afa,0x000c7d2a4f51d503,0x0000b909ab658722,0x0002f75dc1387e94,0x000054c7cceb78bd}, {0x00084d3f96fe1299,0x00029004be5e603f,0x0009034366d312d5,0x00042265d0b7585f,0x00003b342c682c11}}, + {{0x000abe562108741f,0x00090edafcb0db97,0x00050a1e77625189,0x000612928f4ef0b5,0x000028436f533db9}, {0x00066a445e95a984,0x00061b7395817080,0x0008a14b66b45ca8,0x000fda5f298d70b3,0x00009d4a0366568d}}, + {{0x00099ff0ea5b0fba,0x000aa38e73001b62,0x00067dc4c57987d3,0x0006d5467cc55ce3,0x000040e6da53b93b}, {0x0009e490c345dc3c,0x00054155af276568,0x0009f77de77c956b,0x00064f912443ecdb,0x000013d1f2e35d2f}}, + {{0x00069dc8827b81ba,0x000ff2e3d5a36319,0x000f13ca81af30b3,0x000d3db2c866e0bb,0x00001728b7fa6e1d}, {0x0006d11ba4e53cde,0x0008c3f44d47dc80,0x000de776c71aa9a6,0x000377d5cb45efd5,0x000001fc46a09355}}, + {{0x000b7f02f609bf48,0x000d851c333890b5,0x0009646d5de532e0,0x00050dd82571cd4d,0x0000381d38f402a4}, {0x000a13f8fe5abf74,0x000e980cfbe80cee,0x000d8244e4e987e1,0x0002547265bb3560,0x00003bb71799807c}}, + {{0x000711e9d0717f73,0x00098bcbfceb725e,0x000af2faf4e210f9,0x000aaffcf4b3dad3,0x00001d7b1680a432}, {0x000a9fc79b356741,0x0009b13d5198f7a8,0x000714c9efebfbdc,0x000e9183ee381471,0x00008113de151b1d}}, + {{0x000b068e8dac101f,0x00082a77a77808b1,0x0005fe83ee2d68db,0x0009cd82fcc849c8,0x0000ced2c5678a6b}, {0x0002eaa12ebbd351,0x0006fe07a1b126f4,0x000c1b353de97cf6,0x000303776ab40f94,0x000029ea20475cdb}}, + {{0x0001c2d1586be5b9,0x000cc911b89d6385,0x00075acf780e9258,0x0000604f7cd421d7,0x0000cadd878a2dad}, {0x000218369356e650,0x0001634ebb7f5e99,0x000cda3a8202c34c,0x000abf90720028f5,0x0000fd4e963d3750}}, + {{0x0000f0db1730827b,0x000d644fc900fdd6,0x00037410dd37db24,0x000309b2d883f43c,0x00003acdbdd5534d}, {0x000703eac7e1a004,0x00004f5796e43be6,0x0008988176129b8d,0x00003dd7ccc20dde,0x00003c8ca33f4853}}, + {{0x000d0c1c7047f195,0x0002fc7ed2afa267,0x00088562adc95dd6,0x000098dd5add39ac,0x000066c878035e61}, {0x0004fefb47537004,0x000a5a743ef55e47,0x00047591d972f249,0x0009adda486006ed,0x00007c2df25f0a81}}, + {{0x00056ba80ce1e1cc,0x000e67cf1faba833,0x00089e7a051528a4,0x000c6753125898cd,0x0000607dcedb32bc}, {0x0009d23e8c6cd3f2,0x000ffcb09ace85e4,0x000b7d6c1505f623,0x000df6e74aae2597,0x0000001f7693e568}}, + {{0x0002f4fb58a08ff9,0x000b22b767ddd77a,0x00020e33dc68c924,0x0007b51b436b1d3d,0x000015859ad34f0d}, {0x000bb551c67e100c,0x00072572c5dcce84,0x000057987a70e414,0x0002b07c8616056a,0x0000bd0d7de543e1}}, + {{0x00091ff11bfcf2c7,0x000d9646c09265fc,0x0000510cfe52d918,0x0008aa8cca65d05a,0x00007afc5385da20}, {0x0005903d91d0fa38,0x00048cd25652dd29,0x000688d81a6042f6,0x0009e3be9a92ed90,0x00005df7150a5df5}}, + {{0x000edbae38271e0a,0x0008b5cc06bce54a,0x0001bfd7a369474c,0x000e44e3c9d39cd5,0x0000e2bf2cdfd46d}, {0x00082c92389f1ca3,0x0005c88dcb5d5b81,0x000a825a0e26bc70,0x00005671cf4bee96,0x00000b65e1f6a6a6}}, + {{0x000a928368d1a456,0x0000e11cb329d7af,0x00041e0414116b46,0x000a28451a71e385,0x000027ce6313e7a8}, {0x000e5e5782687675,0x000f0685af014510,0x000d3b826aac14a7,0x000bdffd100fad1e,0x000080ca2ea3195d}}, + {{0x000a01041994c103,0x000f47a314e14992,0x00008ef0842886db,0x000927a87388d695,0x0000b98c4ff30fce}, {0x00097d3fcc147238,0x000a8c29c45c7e2f,0x000f67220c5a2e9c,0x00037e0bd4619da3,0x0000189f33c99079}}, + {{0x0006fce6fd4eb1d2,0x00096d33c1253a1c,0x000e10ffc8333657,0x0002c4acbc619c17,0x00003e3f4c29d31b}, {0x00042a47b0149578,0x000ebc09d858af7b,0x000c49e700d501cc,0x000b440ce075301f,0x0000f231d5f803e1}}, + {{0x000ef3caffa4bdec,0x0002ac777c54035b,0x0003cd0bc68eba77,0x00045b2505bebe91,0x0000e4644ce7cd8b}, {0x00042777579dea15,0x000298fca9661f18,0x000590619d9f2264,0x00054720eabbb3fc,0x0000e6455a9be8fb}}, + {{0x000a577c0e475eea,0x000d6bc1436c96d9,0x00016236e94d021e,0x00008c00a8850a9b,0x00004b2d015d7f50}, {0x000c9dc4c6f4a38c,0x00028553656de8a8,0x000a90c362732682,0x0002bf3d15dd9142,0x000052c5e5dfbb42}}, + {{0x0000cbe5411c8dfd,0x0008a17b7a24b8c2,0x000b9b87fd8cb545,0x0005e6a11f9fc178,0x00006c1feb2d790c}, {0x000c58e0b0881f88,0x0003c321556f92f3,0x000a34013603d060,0x000d70aff166a927,0x0000d99e1e8e4319}}, + {{0x00020a329430fd34,0x00091b753e241ff6,0x000dc9b1f4a806fc,0x000873c09454c63f,0x000053aade33de2d}, {0x000c8ed7cf2adaa3,0x0009418f8a188df3,0x000e4faf13fb7d84,0x000bef84861cf96d,0x0000860acea4d6d0}}, + {{0x0001d18705dde70a,0x00011272a18859a9,0x00033f5014638a28,0x0009304080653c0b,0x00008c599a15b5b1}, {0x0001a5a4482a49b3,0x00092f456786cb4c,0x00064ba9b7822d73,0x00018755a97a72d7,0x0000b095c5fcf342}}, + {{0x00068b2d8952a5dc,0x0001384c32454373,0x0001e2922c3926d4,0x000aa3dca16b1fa7,0x000037a2bd72600f}, {0x0000a741ebdedfbf,0x000e23ed58f44104,0x0007baa3fe459532,0x00006a13286a4d62,0x00000256f65a8e61}}, + {{0x0009fdf904d40a4c,0x000a46face48942e,0x00021d60e882feb0,0x000dd0396add6456,0x0000900d2cd7fcc5}, {0x000a7b9be3cfc441,0x0003708a50df4de0,0x00082f25a62b3146,0x0008d616896ec237,0x0000efc52dd341af}}, +}, +{ +/* digit=10 [{1,2,3,..,}]*([2^70]*G) */ + {{0x00074cd669b25cd3,0x00058c67881c256b,0x000c2d070504e035,0x000ce9e47e328af1,0x0000334f9064ef41}, {0x000e26a1c2dcf305,0x0006722062f65cf3,0x000d10bc4005653d,0x000d490fca65ad22,0x000019179d890699}}, + {{0x00026e7838ac11e5,0x000e2a5a280f9fc4,0x0004127710bbdb6c,0x000c0919081aeb17,0x00009d3642b34a2e}, {0x0002ad9a69ff2662,0x000684c317570d7d,0x00000f6f3f188512,0x0005163b33b1c24b,0x0000d7b1d0e34234}}, + {{0x0009ff3fb1c1c89c,0x0005aabccb1a5742,0x0002d53a4eef7623,0x000053470aedff2d,0x00002e085185e01f}, {0x0003bc9f5fe3ea55,0x000e66ca1fc53dfa,0x000605f7ffc83fe6,0x000716623aa4d317,0x0000f64c0b56ddf9}}, + {{0x000674732b26ecaa,0x0006a9b93619c51b,0x0000bd8947d766ea,0x000f1f8da8cf9566,0x000039fdfa96c371}, {0x0008371eaa4eb5cf,0x000f1c2fe16a83bd,0x0006b6beb3c7b8ee,0x0003dfb56c848ff3,0x0000baf4cad5a849}}, + {{0x000b862c0fdd559d,0x0003472c11580706,0x0008b856520b2638,0x0006879e81a90197,0x000029294aa97e5e}, {0x0001e0f85a0008ae,0x000842f061b6095f,0x000af5f1784d787b,0x000532b513ddfaa0,0x000056317941cc65}}, + {{0x000d1d3a33d19d98,0x000d7df2ca8dcb4f,0x0007f4e6b5456b29,0x000f5ae912a132ae,0x00000f2c9a6887a5}, {0x000e27431535c2c9,0x00023aba1f2ffbd4,0x00049250f22df234,0x000935fba35d186e,0x0000929b2503d242}}, + {{0x000c9391c1b57c4b,0x000d954532e6f2ad,0x0004d08859d320c1,0x0004f4b4c12b6234,0x0000d868d83b4346}, {0x0000ea15c6c613ad,0x000238397325f0de,0x0000c2f9dc73b139,0x0004b7db504ce64c,0x0000dc963c4af5aa}}, + {{0x0005e02dca527597,0x000576587c548e0b,0x000cc2767c475cfc,0x000859476ce6a9bd,0x0000665715a85b0c}, {0x000b469bab32bb4d,0x000d0b6de7c31b91,0x0002327265da0fa4,0x00047cf1f57b245a,0x00006cda9501707b}}, + {{0x0008d572808b4fc0,0x00011694ede0e70b,0x000f8b71405a8e19,0x00015233c02d5353,0x0000ab4ce2e44ab2}, {0x000c47dfd222e80b,0x0008cc293dda614c,0x0002292f07c1d085,0x0006cbfeae2c20e7,0x000061ec173fa523}}, + {{0x000876bc63806f07,0x00024d66914b313a,0x0008170d851534d4,0x000b76faa20f3de5,0x0000aab05f61a766}, {0x000664f3ab471d0d,0x00011fdc64a701f2,0x000ea68223acb6e7,0x00013a23fabc7bb1,0x000090227c181a7d}}, + {{0x000ce1496c8edd99,0x000b6594d679e5a6,0x0002b74d6e54b8ba,0x0003a13ee780ee06,0x00000955d9961a01}, {0x000cd19a119ac211,0x00082f7e73061c51,0x0007bf37a3de8103,0x0005363b406e5945,0x00006f8f87f664ee}}, + {{0x000815967b132401,0x00064ecccb2576eb,0x0005d3b7d625290b,0x000ec5d6f358953e,0x0000a5226a7375ae}, {0x000abb11ef347a92,0x0007143ccb0f7b41,0x000c82f4ddf3c9db,0x0000dfd73dd924bb,0x000087da47b38012}}, + {{0x000aa601588458f9,0x0000975e5cf241d9,0x00060b80ec71bf1f,0x00029fcc1fb01f45,0x0000823f9d230d8f}, {0x000657c67a86fd8d,0x00034e709b0f413d,0x000642ec3286cfe5,0x000ba7caac701a18,0x0000fa3bb61f6852}}, + {{0x000801b0303fe8c1,0x000fbe0cde9a2307,0x000713051354d6fb,0x0006e735aff62229,0x000025ef6c00b818}, {0x000306588dd6cb80,0x000a99185c90f436,0x000ae928b4ff1484,0x0000b1c883be31ae,0x0000a9c05acf7be6}}, + {{0x000b28128cceb413,0x00082eab515e529c,0x000d8b8e887dd9a3,0x0002d5b9d67b20e6,0x00008b59180e89cb}, {0x00059e2abcbade3b,0x0006184d19e316ec,0x00044d27ee72fc4a,0x000c67731c05e18c,0x0000a8c4db3ec2d5}}, + {{0x00048bb35989f3d6,0x0009b3067fb4c320,0x0001a0ffbcfe88ff,0x000004e03be2c82f,0x0000fcbfa01af932}, {0x000f814e7e4cf8e6,0x00024ee9f240c53f,0x00086fc0004f7b88,0x0000ac34de98e74d,0x00007917ef356057}}, + {{0x000c6c4a11a11477,0x000d8b1cf6d0d720,0x000694efa1c1285e,0x000e0c1350e984be,0x000078cb9118b03f}, {0x000bf89c99dbbb29,0x0004fbfdfc88574b,0x000eee84278a2c53,0x0008ff0a649b25e5,0x00003d025e893279}}, + {{0x00037a391d54688c,0x000c7c592115f719,0x0007653bbcda0dcf,0x000a69f5817c7617,0x000029a05f07e803}, {0x000753fad30733d0,0x00072bd1849daff3,0x0002fca30fa2fd8a,0x0007feecaa47e99b,0x0000b0731727e7c5}}, + {{0x0005a21b38ecce44,0x0006e415c2abd742,0x0002c0e950133c0d,0x00000ea72b809264,0x00003015ecb9ba58}, {0x000360d2878775ae,0x000bc41c8e4f6d21,0x0003c10aa67f95a8,0x000900e292f6829e,0x0000a4ee43081d92}}, + {{0x000fe9693df562e6,0x0002fad17b8b0aa9,0x0003de3c362eb368,0x000d534ef25783ce,0x0000ebda4537f429}, {0x0003627aba553bd5,0x00097af716fc435e,0x00095a844547dbf0,0x00093eb262399131,0x0000588e07a230c3}}, + {{0x000af60d3202fb41,0x0004c8c7c74a1d4e,0x0009e5b39057f717,0x000f7cf49850c859,0x00008d151014d7b0}, {0x0008fa60b07a5144,0x000d9ab459ce85f3,0x00097edc90f40721,0x0000fbad27012797,0x00005754882b9450}}, + {{0x000dbfc225b16955,0x000deb78b51638a3,0x000458d99f09b93c,0x00061e32d72821e7,0x0000340498c56d86}, {0x0004bf05323cf76a,0x0002ff7ffc746f1f,0x0007d6ce5b44bb0a,0x000c88717795b069,0x000004ab2bd3e89f}}, + {{0x000605a2ca22e4c3,0x0008ac2d7351ad97,0x000eab2e88f2760d,0x00021fc887db7e2e,0x000029bc5ec3ebf3}, {0x00086560b7317f55,0x0004d18b91ce9d01,0x000b6f646f4fb8e4,0x0002a1695833078c,0x0000d6a694f08f66}}, + {{0x000c95e3b72c81be,0x000e8a03275a6b4a,0x000d6b09aa4f69a1,0x0002be1ee61ad29f,0x00002844ca4e17dd}, {0x000e76f8794eee2d,0x00087cd0bdb33924,0x00040e3f2ddfa70f,0x00072fa4a906265c,0x0000b96580f51259}}, + {{0x000023b688cad9cb,0x00076df8951487ec,0x00010c9cdd6ac550,0x000ae554e43a52b9,0x0000fef35226f5fe}, {0x000cbe7fdb2ed39f,0x000a0a5e1bf9b554,0x0009afefe7699601,0x000c50b5d7563445,0x0000010fb3404117}}, + {{0x000279f9137ac6ab,0x000249953bb50af7,0x0000826f6345477d,0x000865968a387bb2,0x000005a5cf531199}, {0x000c5268a915e259,0x0009720c4f4b65a7,0x000b7b99cd26125c,0x00058b59772469f6,0x0000853ae820ffe3}}, + {{0x0006b4b6ec89e3e9,0x000333d0ff1c8c17,0x00059b5dc3204606,0x0005662b172727c1,0x000080e1bebb1c71}, {0x00018894c4864ef8,0x000a9eca02e2c6e8,0x000cab3d09dad501,0x00060af51c7c848e,0x000047e4fa35bc16}}, + {{0x000570befacb28ea,0x0008743dc8f455c5,0x000f40096cf59c5c,0x0004b182c494694d,0x00003c0fc958c313}, {0x0003107f39793424,0x0000cce996b712e9,0x0000246006fd67c3,0x0007be905a6fad26,0x0000fbfc527a687c}}, + {{0x00095e1c222ce3ef,0x0005747315cd6f47,0x000423b7afe75d5e,0x00019bbc54314d23,0x0000ef8b8f77d09c}, {0x000803127214c810,0x00015ffb94e2fbe1,0x0006d06ac1164fef,0x000f30476727cb12,0x0000a8113857ebf7}}, + {{0x00087efddf19eaed,0x000e96b6e5f5f6d7,0x000ece472e89ecf0,0x000c927cc82cb9ae,0x00000feebacc040c}, {0x00099970ce1340b7,0x00074081fa310631,0x000f300ce340cba2,0x000a1055a8739566,0x0000fa0cef064603}}, + {{0x000082c59b5bc93f,0x000b65fc16a6d50a,0x0004bee2ba80b4cf,0x00016533174cf7dd,0x00006aceb571e5f7}, {0x000006d350847cb5,0x0008616d7f8911a7,0x0008b0f735565146,0x000122795d2872d6,0x00007b8ca3d3efb5}}, + {{0x0000a88e8800df98,0x00025448903b908a,0x0004349a5a375804,0x0005b13ac924efa4,0x0000a5e450fd59f3}, {0x000055716f999f92,0x000de9af288dca33,0x00069f12c2367b4d,0x000284d0897fc5ab,0x00004fc4fac80274}}, + {{0x000eb7eb35f2a934,0x000d353268becc03,0x0000a4174b282d2d,0x000f5ddd6356402d,0x0000e7ffa1bdee1a}, {0x000aaa4d2ca7e708,0x000704fc0f9760eb,0x000357060cd33f91,0x000d81e7eb1971de,0x00003d746cad3a0a}}, + {{0x0005e0ddb5450c74,0x0002a674a2e0aec2,0x000bc7d3441bdd25,0x00079a58f6e1b7da,0x00001d2cad53a42d}, {0x00076a79d2639d68,0x0003f32fc3bfb513,0x0002bfdf25a3776e,0x0005d91a51232583,0x00009aba866b1079}}, + {{0x0001534fdb96049f,0x000d73c129cc545a,0x000caf544a6dce8e,0x000d95f07d61f6ae,0x0000dcef4f010d17}, {0x0003b9847259e03f,0x000e08eaf94b5a31,0x0000a320a3862f66,0x000f35bfb4c3fc13,0x00003ce88af25ac5}}, + {{0x00084f5111ed5705,0x000b79be0976a8d9,0x0009ab22e7a6498e,0x000cda52cf1ba030,0x000013d88452929f}, {0x0006f21a33ad72d6,0x000e27b4947e3ec9,0x0000022021b0fa2a,0x0009c5f35557b5e4,0x0000f01ef8814f2f}}, + {{0x000c2442542799ce,0x000f9b3064143739,0x000f1d943ee0b9f4,0x000e26265a704416,0x0000e87d46c8a352}, {0x000a8e3615322bd7,0x0008190d24dbc6d6,0x0003d81377ed07b0,0x00056a2a112749e9,0x000094697b190dce}}, + {{0x0004cf425219eac2,0x0002cb6fb9207e1b,0x000cc82f73e79b1e,0x00073ae27f3c4a54,0x0000554f3a88ed84}, {0x0006de42a1700f2e,0x00006f9c40687f07,0x00093ba557a83e9c,0x0000a11fbe078a85,0x0000e7643032099a}}, + {{0x000f9abfe9907a6c,0x0007cc63f2dfda1c,0x000bac69ee3043cc,0x00041648aa637938,0x0000bbada2c4f2c0}, {0x0001495c9e6f03da,0x000fb7b4eda11e13,0x000b4954affd78b1,0x0009d34c115f6b0b,0x00000db881c07854}}, + {{0x00029e61ad8613f5,0x000c9ddb326c11c4,0x000869e2813f8b2e,0x0000b0117db8ee3a,0x0000dda75e5f5ffb}, {0x00073327c49cc58a,0x000d0c3da6be20e6,0x00070dd5c65cada3,0x000ef461959c8261,0x0000fa5cb2cf4faa}}, + {{0x000e000a34fd0c8a,0x00058901bb98ca77,0x0006eb2905cd2973,0x0003336dda93946a,0x0000934ccf97e513}, {0x000c1d692b201b8a,0x000f029af6321234,0x0008d9dfac9c7c2b,0x000f582d8679e67a,0x00008046ce69fc1a}}, + {{0x000ab8eb6e0336a9,0x0006ea229cba0232,0x000dedbcad54fcf3,0x000667a7a0cc9245,0x00000a2c42237703}, {0x000b601fbb80bfde,0x000a2c63fd8939e8,0x00049e20428365e9,0x0007aca1417dd6d7,0x00003f11af7e1f8b}}, + {{0x0002330b4c09a0de,0x000902a37b9c9a53,0x00036cda4e95cf6e,0x0005ec789015573d,0x000029deb51579af}, {0x00020a37b9ea8e07,0x000799397a517f13,0x000557b7511fa4f0,0x0004370b092cc886,0x00004fe2aea14013}}, + {{0x000b5c6a9db98dcc,0x000dd04a3aba71dd,0x0006608f14057254,0x0006b8b756359d19,0x0000c4455860c9f8}, {0x000a2e774f5cc99b,0x000300a46307126b,0x000302ddbaa681cb,0x000535fc96dbf608,0x0000c681d0076c06}}, + {{0x0004d84c9e62370a,0x000a69eb6fa1f9bb,0x0000ef588241feb6,0x000245740d6249c1,0x0000be2d5006f181}, {0x00041f73dee49528,0x000c00da95bad9d3,0x0000e049a1eb457a,0x0001bbb11190a486,0x0000110d97c60ffd}}, + {{0x0009877303f6c251,0x000a1c17dc10f282,0x000bb8dca73e7560,0x000a683b3ec4fd74,0x0000a9f75e1bb560}, {0x000919d9da696d60,0x000d217fedcd3ac2,0x0006adcd9d53df79,0x000215470c8bf19e,0x0000b0f430bfb8a1}}, + {{0x0004ec0bc6dcdfa8,0x00046693c98632a8,0x000bba59e9150cd8,0x00022c245639b8fc,0x00003d4bb7590c93}, {0x0004d6a04c6abc20,0x00066201cd556fb0,0x0001e5e4afc3d001,0x000ae07774cab315,0x00003d6c82521fe2}}, + {{0x000c32cbecb96f49,0x000a3005ab64ddcf,0x000baf06df924953,0x0005e8ae7d321d49,0x0000b2d331a8c32b}, {0x000d67cb123fdcbb,0x00088a617dcd4f59,0x000e94c2e5129661,0x0008ad46352e5f1a,0x0000d5565de6b48f}}, + {{0x000e6659b3560d39,0x000ffa229f90747e,0x00023180522e466d,0x0004d6c4a3f828c0,0x0000e455d80ec3ff}, {0x000e2eebf20d3aec,0x000c736f73d855fb,0x0002184b7e5febc1,0x000b11155c63fc28,0x0000a428c274cade}}, + {{0x0001c636e5373dbe,0x00086eb6f714bd17,0x000e1b6a90d860ea,0x00060dc93cbac42b,0x0000d34c45c4c0f5}, {0x000659cadd09b1eb,0x000ccdb20e3300d0,0x000141729d71e84b,0x00060e782510dc77,0x0000ec0565e653b0}}, + {{0x0009e4d6e92f36d7,0x000825cbda73f299,0x000665eeb18db8b5,0x00018f9cfee6e9a6,0x0000ca23779281ee}, {0x0005db4b1418ca14,0x00024447b1c7f54f,0x0004f104fcae5744,0x00000ab06a6080e1,0x00001054c45b9651}}, + {{0x00055d5f2446ec83,0x000467a9ebe2680a,0x000c77fc1761cda9,0x0005aa015446cd46,0x00001c27acc7da7f}, {0x00077703a89b1b78,0x000cd191b9b97518,0x00013cfd2ff9eac2,0x000e94ceb77c72d1,0x0000fb9cf6eb1afc}}, + {{0x000c0193744cd46e,0x0008b3ceea178d94,0x00014a628cfe494b,0x0009d6820be8421f,0x000094afe6f01bc6}, {0x000e28b4eda452b7,0x000538785cad4748,0x00037da88fc3c7e7,0x0009fc488a0a24ad,0x0000cc96f2897d92}}, + {{0x000f9f92b892fabe,0x000e8fb2e6bf1cfd,0x00099f05d11cf6a7,0x000c3b1597b79e80,0x0000a26740afb0a3}, {0x0003b35d8b31a83f,0x000396846e25cbc8,0x00082f6f006b2f50,0x000a658d89e03e35,0x0000db716db3d591}}, + {{0x000d177e1fa4ed0a,0x000dd5607e4daf0e,0x000573a2cc2358b6,0x0002b7ee7eca899a,0x00003a1628589e78}, {0x000f908d149527d0,0x0002262175b94b20,0x00013e200c0bcd10,0x0003975b06898fb3,0x00008491f71c53a0}}, + {{0x0002d700f31b0e00,0x00019237b591c539,0x0009fe9bccb246e6,0x000017bf39be6432,0x000028e4046f6380}, {0x00046c9c0d21521f,0x000fd73f252bbf1a,0x00043fdf02581ac2,0x000babf43b3c4272,0x00001a5ee9169a81}}, + {{0x000e5448aa1f7350,0x000f3edd6264a716,0x000253daee2205fe,0x000b4e7addb5be46,0x000055192f8f04cf}, {0x000b2643882ff890,0x000c409401a9d5ae,0x000413e0c8a16ec1,0x0002f7f8a4fe486c,0x000089973c8ecdb6}}, + {{0x000af3487f6b18cd,0x0008a3d07d2ec763,0x0000e5a1521e2961,0x000427104e65b30c,0x0000bdacad3f1ac8}, {0x000145358f37a6dd,0x000d004a44da735c,0x0009eebe68dd299b,0x0006b05a62c5ac63,0x00000ac76876f8b1}}, + {{0x0008acf5a8209bcb,0x000560df7a62c194,0x000c1fb14acfeda4,0x000df2c2224f5fad,0x00003404df8d5798}, {0x0009a77b70e54968,0x000520108a2364b0,0x00015fccaf6ebdf0,0x000566e36cd047b8,0x00005e46d74586d1}}, + {{0x000844d8e8ce5587,0x00092279b1356b90,0x00091add341ad4ae,0x000a7d2fa10f0f42,0x0000148c77380f8c}, {0x000496d6691d4cc8,0x000782bb8243fd56,0x000627db185c1156,0x000a5418645f44bd,0x0000d506007bdf79}}, + {{0x0000bd279fead68e,0x00056182e4e75be9,0x000dd1b6509c30b6,0x000ed8c47b692128,0x0000f5fe87abfda7}, {0x0003143dc3675e1a,0x000c502b0a119eb5,0x0004fe0aff458d3c,0x000a31f46a7b233d,0x00005acb343f0376}}, + {{0x0002d15eee0e0d34,0x0003d148684f5225,0x000cdbe9722216f4,0x000c5cce42f45a7d,0x0000e205d19ad51e}, {0x0000f64c68b5fa7c,0x000058e30f053866,0x000a6c9cb5f06a10,0x000f6f5287fecaf3,0x00001883d276db11}}, + {{0x000527672331c67e,0x000a87a64576176e,0x000c391a5c3662b4,0x0006c076cdba095c,0x0000f9220fdeba1e}, {0x000ccfc868b90cca,0x0008290a8b4bca9a,0x0000e92873faa03c,0x0009492e8d17378b,0x0000a47f8c64e176}}, + {{0x00028cb6de5ee8de,0x000cd5efcb0928d3,0x00077e0ccf78a9c3,0x0001c402efb29bef,0x0000459ba0ccaa24}, {0x00015eff8dc3bb71,0x0001926d930b21d2,0x000c2f8d6a0caf81,0x000f17b13725955f,0x00005d65bf7dfab7}}, +}, +{ +/* digit=11 [{1,2,3,..,}]*([2^77]*G) */ + {{0x000f9aa8775da137,0x000593a6332e3942,0x000acdfba04c12e0,0x00036116cc38b202,0x00008a8960a21793}, {0x0002d21251bfcee2,0x000d5d5e4ebe7fd4,0x000ecd2b4f06757e,0x0004179312209cb9,0x0000116a47ce63c7}}, + {{0x000fff36dfdd5049,0x000f7ce6110d0407,0x00098a9fc7cb9e1f,0x000926e424e2d9ea,0x0000835121b0ef1b}, {0x000d9bfa74da96b0,0x0002cd0f068f3fbe,0x000fb3442f781253,0x00047bf2a224f7f4,0x00003b3786a0183b}}, + {{0x000297122b1f3105,0x000638dba8324c9a,0x0007684493f6706f,0x0006825bd6946011,0x0000954fb43f082f}, {0x0009146aaba29f01,0x0004e9c6324aadf7,0x0008d8428f5d9954,0x00015d922efe9529,0x0000d292e4285a89}}, + {{0x000eda370bf670ce,0x000eff959124f0b7,0x000cac220c098413,0x000042e12faaaa26,0x0000895133539985}, {0x000e3efc5819a77d,0x00057c57c1941637,0x000d0cc10c5d3a74,0x0002ffae97c4601b,0x0000cc0b9439604c}}, + {{0x000eebc15ab85274,0x00019d13c980241c,0x0003a82e05366ff3,0x000eab4894fa90a8,0x0000f875d5053ef5}, {0x000f960988cc3ea5,0x000ead66986792b7,0x0002473220ad7ea6,0x000afad402fea6ab,0x0000112495728583}}, + {{0x000f4636a79fb44b,0x00090857f24b3d06,0x0000bd52a5b7cd91,0x00064839569b4ec8,0x0000d1b1ac7d83e4}, {0x000a69c7aac7f865,0x0006f8fb84cd4b3a,0x000b5e37812c149e,0x00091eb184db0903,0x000048acff136f66}}, + {{0x0001299f5efe435e,0x000b7f1400ac2880,0x00059719edb65124,0x000c51a678fab01d,0x0000165002ee9aa8}, {0x000bbf3f226f941d,0x00011de495d3deba,0x0007d94842b6a345,0x0003d2d9919c7098,0x00000d6590e37520}}, + {{0x0004ee9ebab5f9c3,0x000ee5aa2862cfa0,0x0000825883683453,0x0005a0745585d074,0x00009825b8191988}, {0x000e1d078fb65329,0x00028cc58f8e9d76,0x000caa6ecd94a45d,0x000e336d0acf4acd,0x0000622e82ce2bfc}}, + {{0x000008a44a2706aa,0x00041b1add588771,0x0007569a605cb923,0x000def6163a01430,0x0000a568614fb2eb}, {0x000f81a9ffce874d,0x0004c0a48585c4da,0x000233e6225a5f0a,0x000d30ea80e24f54,0x000012a0f8a98988}}, + {{0x000b7355cdc2f284,0x000d2a27b9adaef6,0x00093f3b59e1ed0c,0x000b746910956189,0x0000c77d5df71c8b}, {0x0001803652237193,0x000739b9537fbfa5,0x000a62d938c3a3e5,0x00058e9ebd4a1293,0x00008b4fbeec3446}}, + {{0x00052179751d0b7d,0x0000f901f8a82fe0,0x000136ce503fb389,0x000dba5498f02145,0x0000cb7cf9a661f9}, {0x0007016c2992806e,0x0001add3eb9fc4a7,0x000307dc5f99dbd8,0x0004c304da7f5ed0,0x00006fb20bdf58fc}}, + {{0x000325b563f62c26,0x00088e338763fd2e,0x00070b882d81d583,0x00086a60eec0789c,0x00000900a5d21f5d}, {0x000b2fb282b41ea8,0x00039ddb91517ee8,0x000f77556d931d68,0x000bf902f126e703,0x0000b19f00d7d3a7}}, + {{0x000110e849fc28b5,0x000b011096883b49,0x0007657f512d21a5,0x00011f76afc44bf5,0x0000746d7f32aaff}, {0x000037a74dc795a3,0x0002395a1c198937,0x000a8ef1664ed39e,0x000c26cdb84ee945,0x0000696b907f6d28}}, + {{0x0009d6f7600276fa,0x0006d3198ab29dd7,0x0005cb1d12f3e169,0x000f3329a912fc79,0x000030c403e7632d}, {0x0005a8f5ede17ddb,0x000859c12cf6284f,0x000881ae76605fac,0x0003ae8ff98c78aa,0x000023ec368ec733}}, + {{0x000130cefa1d5675,0x000a003664f802bf,0x0004bd36ef9058a3,0x000a3113c314fc7c,0x00002389880af8c5}, {0x0007ec1959838d48,0x000fb01ed3b95705,0x000f59b95a2c3c69,0x000e21c93ecb7a35,0x0000427f7b9b8f6f}}, + {{0x00004ae4288bb5a2,0x00037f3270264a85,0x00010b20b51cafa3,0x000a0e9e414efa30,0x0000157a33e62123}, {0x000d80dd6415cd8e,0x00020677cad8cac6,0x000c9fbc4f37610d,0x000d6dae155e1c85,0x00001d0a4ba60f48}}, + {{0x00067d8c0e279e91,0x0008245afbee6855,0x00078ddecf33ca01,0x0007946ed3edf19b,0x0000f617d59ab035}, {0x0007945ae089290f,0x0005fe0200f2c492,0x000bf24784884e8b,0x000928852fe9c760,0x0000ffcb8771fa43}}, + {{0x00066fd3da53da79,0x000b479eb0a7ecd0,0x000b2d549c3fc2d9,0x000b9c3ae4337ac7,0x0000ad4d200fc335}, {0x000f93463a303081,0x00096441398584c8,0x0008f0df55fc6eb7,0x0006d5481aed496a,0x000038658e97f52a}}, + {{0x0009033a9a9ec889,0x00029548d2a17999,0x000b47721fa1d736,0x0008158e33920d87,0x0000045c74a58e24}, {0x000307917a0bc1d9,0x000057635c548972,0x0000f6f88a032dce,0x000d42aa81563402,0x00004682835e5a05}}, + {{0x000ff28d04ebc165,0x000507686c2c4e6f,0x00063dcb51fce3da,0x000d9fe06896b6ea,0x00002e5ce05439c7}, {0x0009d2e6bdf7eace,0x0000afa52e93e883,0x000674e412921b90,0x000bce92640a5a16,0x00008b7c0dd9fa63}}, + {{0x00028f0d3d5e18ee,0x000c30590eb006cf,0x000aec8faba412fc,0x00093e1f0888bc96,0x0000616d1fdc8348}, {0x00044c101c5f2508,0x00006dc12d0c3c51,0x000280f9293afec0,0x00028d276ff0f7e6,0x00004cf82b9fbef0}}, + {{0x000644eb6ad3daea,0x000f9da617bed4fa,0x000591916a0aea40,0x0004a62c8bc21622,0x0000b14787fa4323}, {0x00029dbaddcfdc82,0x0007d2c3a56f1f85,0x000d278b64ee5284,0x0007a85b4f7a0572,0x00004776f3f249a9}}, + {{0x0009bdc6a9c5425d,0x000a74cb2e08037a,0x000c41e34d0fdfda,0x000259c1bfad07fa,0x0000ef71695d1f87}, {0x0003cd312e6c539f,0x000dfe79874c3b10,0x000e03e026c03074,0x000366d7932c1541,0x000049edec49dd5a}}, + {{0x00048153ce2a6ced,0x0005cb374595998b,0x0001d374c1a016c7,0x00056bdfd770e4d1,0x0000152c3e66158d}, {0x0004234660137887,0x000baf4ea70fc909,0x0007a4061d5c4126,0x000a704f10817eaf,0x0000e2581ebc91a6}}, + {{0x000b859e2c097385,0x00023910a6cd24e1,0x000b5f1edfe2b5b0,0x000a39c796e06e2c,0x000061b222422caf}, {0x000f6e990b5ae344,0x0000276106c10652,0x000091bb1af35abd,0x00082644cec3093f,0x00005d1cd36bc1c2}}, + {{0x000fc1520ced10f5,0x0003010001daedfa,0x000eaefb25ebd7e8,0x0001d7614a3f50ef,0x0000f52e9b2b27ec}, {0x000b038acc2e629a,0x00014e35ab802696,0x0004c8730d623772,0x000307b05e87064d,0x00000c762bd34c12}}, + {{0x000e308ddcbf0bd1,0x000b96a5dc0cf082,0x0006cc07a52337c2,0x000fe84ae58e4cfb,0x0000659e706d98c1}, {0x0002ec7dd17741b3,0x000486171f471006,0x0002a5bee3b6d6b9,0x000eb91bd92dd984,0x0000975826a09b31}}, + {{0x0003c9292ce02260,0x000d0dd17ee212fc,0x000bd9b2da2e3c4b,0x00035318456b64ac,0x0000a1961934d45b}, {0x0007febf09ab4caf,0x000002c812353920,0x000942e1afcfb9c6,0x000a778eaf0948fc,0x000043ec3002cc4d}}, + {{0x00064b180a723820,0x0001aa42c8b77ff8,0x000fb95a1ada2085,0x000241ea27c78812,0x0000c96b8e900b7d}, {0x000a8792d5ec82d4,0x0000509cd684235d,0x000785d18e35f6ca,0x000788a287dd65ad,0x0000e9f2d7e56386}}, + {{0x000b08a242d1b6d6,0x00041b0fd09c63e7,0x0000cea65281d8c2,0x000dd0e09cd34ca3,0x0000cac233c630e7}, {0x000013f31fa41372,0x00054e81b46f3496,0x0006319dc9ade00f,0x000f520220b1fc74,0x0000e2b1a530749c}}, + {{0x000606de55192498,0x000c5809c40aa334,0x00096632d3890f16,0x0007e02bad0a1796,0x00005d185bd38bc9}, {0x00077cab67b3412d,0x00046a2cdd3292a0,0x000c830a347d5c0a,0x0000aa324c123aca,0x0000685c38fa87b6}}, + {{0x00038414a19d3175,0x000e6a1704e8a59a,0x00040b43fbe48253,0x000ce06f982b9219,0x0000d5b7bcfbcfc2}, {0x000713f4576e6000,0x00031b8ba82c39f1,0x00005f1c4af7d65c,0x000c3034d34805c2,0x0000f4899f930218}}, + {{0x0009d84b49c30b6d,0x000c425a60175a5c,0x0000a9f29180d182,0x0006fad47d4cfa1a,0x0000b40b136882cc}, {0x000d6a7c603f3345,0x0001bae3d9f84dde,0x0002e1b29542ed45,0x000b004616436a00,0x000003fa1413eddf}}, + {{0x000cfbbd57abdae4,0x00020fc5888c8737,0x000a4476d73cd5c7,0x000218725a0deed8,0x00005bf9e51796ff}, {0x0002e189a1751dcb,0x0001228d9683dc50,0x00093baabf58f351,0x0000af8fdceae65b,0x0000cc7a48df0733}}, + {{0x0003e0d34f77c46d,0x000fbc6edb0f3c88,0x000068e756b0e5b0,0x000e78037099eec3,0x000038e0b3c5fb3d}, {0x000f6109612e790d,0x0001867cb2863958,0x000f3a5af9ead942,0x000e99527c7a360b,0x0000669299225f30}}, + {{0x000378d02aded289,0x0003c0423ea0efed,0x00076140c21c9274,0x000f78ad1a14b332,0x0000f0a890144187}, {0x00021349cb6cb96e,0x00056d9c9076e14a,0x000e9750cf7a0c30,0x000eb4b264c96979,0x0000fb23ad7c9708}}, + {{0x00082f88233a37da,0x000d23f23abb42d1,0x0004b3734df9d345,0x000d6521d54ea368,0x000059fae532d7b1}, {0x0007515524ef218e,0x00007a73ae6b69e7,0x00058efc608d1521,0x00074e26beb85e78,0x0000aca7c3b8b78d}}, + {{0x000c9e891767e9cc,0x000a6db0fc3a5dec,0x000195eb1598acc5,0x00005382d1cca30d,0x0000094de8c7a92f}, {0x000eb3338b3392a9,0x00013886c546dc13,0x0000d496c04db373,0x000adde62bf2b9c8,0x00002f299eed9137}}, + {{0x0008bd479af2b8a7,0x000ea590b94dddfb,0x0009b3b12d8c5034,0x000cf0e1ced752cf,0x0000b36722ea39b4}, {0x00069628a0877b3a,0x00015bad064c4d30,0x0008ac446518bb7f,0x0006b03992b46ea9,0x000065fc30503fde}}, + {{0x000bc2015b83fd15,0x000dc269799522b1,0x000b535f20b2820a,0x00069a5142759c76,0x00006f2ac98f9822}, {0x00083169e636983e,0x000e591e55c80622,0x0005a4241aa4d2a1,0x000591cfdd294197,0x00007b55447387c4}}, + {{0x0003498722f42f3f,0x000a59410f413e15,0x00032a6354667481,0x0002956d7b04af7f,0x00006a645082d4e9}, {0x0000da5be5d8d302,0x00093df7e7583fbf,0x000d7c2be3abd8e1,0x000a000194d9418a,0x00000149bc9eb3d2}}, + {{0x000f986a073e3517,0x000f9b73f9e38de2,0x000a58bf2571610c,0x000b0af920fb7224,0x00003d4b8dd4ddf2}, {0x00030e4ce112c73f,0x0003bf36e1c67f91,0x0003453afe2dc80e,0x0005ac201a013e91,0x0000c59ce10e30f2}}, + {{0x0003b1cdc7f8928d,0x000ebc41452df139,0x0007451137f6868d,0x00053ce9613ed210,0x0000649aaa42f694}, {0x000b7ba1a932b30b,0x000f2a4924b83721,0x00040f1f33138c74,0x0003dd58146c6cea,0x0000e7f4ae83e138}}, + {{0x00085f185870b6bf,0x000b92eed3fa9528,0x000d2b635e2b8998,0x0007568a94e9d333,0x00000526592b1491}, {0x0008aab3be513b25,0x00045303376d3cfa,0x0007c72c989eae8c,0x0001f30e65c1f409,0x00005b94d4c0e401}}, + {{0x0003d066fe100843,0x00074d0b7004bb28,0x000967116b79d60d,0x000cb60757a89246,0x0000029e71f8c407}, {0x00065bff0dfe7d8a,0x000f7f471826dacf,0x0005753bb87557ed,0x000d529de1afaaf7,0x00003c27f0415370}}, + {{0x000c10c40e0ad658,0x000d03d36ac61fc1,0x000143c6a50f0060,0x000b87a02cab6659,0x0000aa0ac941392a}, {0x00077a9d795672d8,0x0009caada373a423,0x000f29a04260b72e,0x0002e8475833e9de,0x0000035e64a7ec99}}, + {{0x0001b1e50eb884d8,0x000fb550dec7d443,0x00015188fa1435ef,0x000fed29334dd65c,0x0000cd2d5a342204}, {0x00054e8f171c4219,0x000d2a2a4537bac5,0x000bde4f44854e54,0x000cf4c3773aace3,0x0000a962593e8aa2}}, + {{0x000a77a80d8d4ad6,0x00075f34cbc4dbca,0x00009e3fe02abb2c,0x0008ca980524452e,0x00006411b8d00213}, {0x0001764627b7712a,0x00023948a2b5cb5a,0x000858785cea3d52,0x0002036e6e748680,0x00000042eb925ac7}}, + {{0x000751674ece9ae9,0x000a512b2c44e9c8,0x000e88fccc205168,0x0002c75cd9811607,0x0000f9001ef938ff}, {0x000ac81e5a48ef97,0x0002e0109b2bb3fd,0x0008c3273e7e9d5a,0x0007b2dcb6ff8d2a,0x0000cc1bdbc8ee70}}, + {{0x00056fa2bf280369,0x000a9e2e674b01be,0x000c71f07ded96d9,0x000002b55134dba0,0x0000dd1195c38794}, {0x000266f2f86721fc,0x000adda42ae0dc28,0x000d8561fa395767,0x0008fd2270c1219d,0x0000d0cfc1b86620}}, + {{0x000bf27baf63ff66,0x00009ebc66252bbd,0x00081af1cacfa286,0x0007812dbb29b31b,0x0000fb9396e63aab}, {0x000ada1d38323f82,0x000ad4f13aa595b7,0x0001d791ee24a41d,0x000c0b1e03dfd84e,0x00007cfadee3c277}}, + {{0x000f91b24c3fdcf9,0x000dc39512d9d6c2,0x00079ea474581c15,0x000b3037480385b4,0x0000d036170f05a4}, {0x000567ff9990c1cf,0x000c52022e9733fd,0x000e053c243f4d6a,0x000e8d640b9aa656,0x000085f487e4d5f7}}, + {{0x00091898d9f31562,0x000dfbe0453c7472,0x0009e6b7f7af420e,0x0004b20e2b916673,0x0000164bef06f4b6}, {0x000b80fc51993f6f,0x000c34d3d86975a3,0x000ff3c930f61aa4,0x000b4918539af658,0x000059a8d10c4494}}, + {{0x00066e89fdfd1ee2,0x000e2e6e602e0282,0x000d5c751cb890ad,0x0005b84b04a46bd2,0x0000ce8ef41b6ed0}, {0x000a5fa420cfae5a,0x000f8b6e315d4386,0x000903ae604fd4ff,0x0004b04a393c9fe1,0x0000cd608fd28510}}, + {{0x000b3e82dc9c8f33,0x00059d7a2a568260,0x000ec023ab8ab819,0x000b4672639387f7,0x00002043db1d435e}, {0x0003a6c41ed2e7cf,0x00005ab1014aa9f9,0x0007dc38d75705e1,0x0004e061bd047969,0x0000eb648e51640a}}, + {{0x000f0f57c547a961,0x000d990237650041,0x0004510d6c34d742,0x00063c4132ff339a,0x0000408528595bcf}, {0x000a71c3fe658de8,0x0001c3cf64c2960f,0x000e6a5c2ae5ee0f,0x000e11651433eea4,0x00003984cde74fca}}, + {{0x0000003ac6f58504,0x000341671c32ea49,0x0002b8921facbf78,0x0004fa3c67b6d380,0x0000873d3817bc08}, {0x0000d0e2edff3bef,0x000ceefbd4439499,0x0008b941acf60583,0x00068f3529a5a269,0x000098b50bd525cf}}, + {{0x000a25873e60025a,0x00053855a627b0b2,0x0005a4f0d708e8e4,0x000b258de1632834,0x00003056505bfd84}, {0x00090d0a530bf0e6,0x00043c0c25a53dab,0x000f5fa79e358944,0x000b501d65285c91,0x000077599220aadc}}, + {{0x000decde86b39648,0x0003ad7ad0f350fc,0x000fe462f1844e2c,0x0003d39cc52142ca,0x00007a06c317b146}, {0x000867e4dc14e8c7,0x000ff41bcd37d80a,0x00032c5b0675151c,0x000653c449373f36,0x00005a57dc103d6d}}, + {{0x0000a2a7c0db9bfc,0x00011c2811b663de,0x0007ec267d1c9049,0x000b23256ba8b300,0x0000534d306792e2}, {0x00026c1d52004b5a,0x0007a3f4dc127efd,0x000d195c762760cc,0x000221924b8c8b14,0x000026c7b7eb7f67}}, + {{0x0002f18ed29ebf14,0x00098c2b10a9d4ab,0x000a74882a5d041b,0x000d5bf9c651a0c2,0x000088a4278579c9}, {0x00051235c715721d,0x0000e9dced4d4ef7,0x000ee67bd5212bc6,0x000d93da86c0e051,0x00006c0ebc2e5127}}, + {{0x00070438f33a86ab,0x0006a9c27c7efe20,0x0005fcfb1eb8742d,0x000157f616499b3f,0x0000133c81b68e98}, {0x00010f66856c8633,0x000cda9e424d843f,0x000454d474e9ef7f,0x000d084addbbba56,0x0000f1d7dd5fa3c0}}, + {{0x000d7b41a5dc9f16,0x0009ef12f95203b7,0x00013189c2fc91e0,0x000aec2347a9cef1,0x00002719ff12516e}, {0x000d3b82a3b61af6,0x000df7f38b308736,0x000bf80445b12e06,0x0000c743ba9b2725,0x00005ba45f8b88ed}}, + {{0x000261f56f9e574d,0x000455263e563df4,0x000e18043b012748,0x0002a907208773a4,0x0000ddabf1b7aae1}, {0x000554210f1c434d,0x0002ff3445d34069,0x000445f11b6f9f3a,0x000dae4831b39805,0x0000edfbc2a2b1d5}}, +}, +{ +/* digit=12 [{1,2,3,..,}]*([2^84]*G) */ + {{0x000c554483b6753e,0x0006801db8f9d305,0x000886fd9162b06d,0x000476456139bb92,0x0000ea4a8915ea88}, {0x0008d47007a48524,0x000e4818a4c5c808,0x00015a22cdb69736,0x0005f81ca589aaf2,0x00001d936a1d6f7b}}, + {{0x000ab2dcbd28cd7d,0x000a1162cfc4011b,0x000cc1af050d89ce,0x000063b3e8402465,0x000083d0e91f2d65}, {0x000f946464985316,0x000f0b6261148253,0x00038d8cb0463eb2,0x000a2eaf46232053,0x0000d3acff868021}}, + {{0x000dd5140afb7993,0x000bd8f7f093f0f0,0x000c26e525fd4cce,0x0006ac8e6399e015,0x0000a1f765c42a88}, {0x000b1ca956564f4b,0x00094bcd0652818d,0x0009c185081d8880,0x0008442cde2c9ec7,0x000025a44064aecd}}, + {{0x000f5f559bf4a74e,0x00050b61dbdb8ccb,0x0007c812ac18b374,0x0005a3f24ba94aac,0x00004f5dad1bf4c0}, {0x000b7e537d97e833,0x0002de512f6471df,0x00071b5884053ab5,0x00043d89f56b8b9d,0x0000c58226e7c64c}}, + {{0x000f0f17bc532082,0x000fed58cc574ab4,0x000e10b8d86bc64e,0x0007d2b3542fc362,0x0000a757378d0112}, {0x0006ccd629ef57cc,0x000f7b5d9c080f6f,0x00088029c11069f6,0x0000bff2e914dc87,0x00000558c2f6e839}}, + {{0x000da9445a23fc09,0x000605eeb8c005a6,0x000fff46275f912d,0x00078b2667155c28,0x000052569c27476d}, {0x0000ed991150c753,0x0003d9531b755efa,0x00075e9f483c52f1,0x00031dab94d69b7c,0x0000df793c3e38af}}, + {{0x0005af0c0e6e3ad8,0x000fa2bd1fd197e3,0x00019540b108b614,0x0001cf02f81fa984,0x0000838602012d96}, {0x00015ecd5143acca,0x000e93ececd5fb07,0x0004ae6741960659,0x00087c273955714a,0x0000f440efd280a5}}, + {{0x000e7c32fd3348a4,0x000777077b4c8efe,0x000fe73e11c88faa,0x000b96ecece59c8d,0x000009715b464a77}, {0x000aa5d14df28d16,0x0005301318185b7c,0x0005350981bb9857,0x0009644ee837ada5,0x00006a9819ff80d1}}, + {{0x000a414f9b65e700,0x0008351d28b72fc0,0x000807cb5eaeea1e,0x0005c55f09163a37,0x000086eb6b36bd63}, {0x00044698cc2a4ea8,0x000466e5324dbb10,0x000664773c425160,0x0003514ef5e7b9d3,0x0000bfc6b8578654}}, + {{0x000f3a37768912e9,0x000fade19cf47741,0x0004368c97f7e0cd,0x000b78a509039326,0x0000e3961c3955f3}, {0x000d1b5709e33830,0x000bcb212af98fb2,0x00071b5c07cebb92,0x000dab556ee7dd40,0x000022c98a5e5d55}}, + {{0x0007c40f3d55f440,0x0005850ab4bcb8d7,0x0005dc2904c0ecd9,0x000fc094f9552e74,0x000065bde9a45b12}, {0x0001b213e07d2a05,0x000dac491152e816,0x000bbb468a73324f,0x00022eaf5017795a,0x00000333c55c0892}}, + {{0x0002fde94b3766cf,0x0007174a526e10e3,0x00046da5e56aac35,0x000ac2d0c1c51f5e,0x000035efc2472eb4}, {0x000da0a323be075b,0x000717ec17895a91,0x0008ad7c571d2b3c,0x000bf89dbcd26f41,0x00006d4343245d6e}}, + {{0x000dc2eac62fb9f5,0x00084e51c141aa70,0x0009798c2bb7e6c3,0x0002dbd11d4a05b6,0x000074f72cf5e639}, {0x000fd435dd15c827,0x000425e3562b0e0d,0x000886af23f9d33f,0x000b98eee1982216,0x00002d9339f90269}}, + {{0x00046ab0a3564848,0x000023087b4fdedc,0x000aa974dfa3f8b2,0x000c5683df032518,0x00008d37e3dd003e}, {0x000b497bcaf07eb2,0x000a80cfce97a4ae,0x000e8c971e5379fe,0x0009ba740afedac2,0x000087c1f6eafee3}}, + {{0x00083a26aac344f6,0x00074201b2856380,0x0007578c50361026,0x0005b40a8a67be24,0x0000605b8627889a}, {0x000aabd30a19439e,0x000ca53f88dd0bbf,0x0004a3ee818767c1,0x0006663ec91f08b6,0x0000bcc3862cf387}}, + {{0x00084ddfe58cda46,0x0003b276513902f5,0x00002aed28befe9b,0x00072ae88c3c7ae7,0x00004c8c2205288a}, {0x0001cb844e502e5a,0x0000d9ae644c5df9,0x000c1aa51015e574,0x000a6be30714bc7d,0x0000f41ed76cc10d}}, + {{0x00033bb53beeec19,0x00007eefd1662fa0,0x00011a9bf3b2cd1d,0x000d5a31a0c88f70,0x000032688031e363}, {0x00016c08ae3a3eca,0x00015b3281e6f092,0x0008a75e39d7d5a3,0x0000909972d7b786,0x0000c65def428795}}, + {{0x00005874e890e300,0x00041d95ddabcf98,0x000368cbf916f257,0x0002fcdd589ca455,0x0000f2d91af1373c}, {0x0001207d3f06d40e,0x000b5b5367021a75,0x000f49339cc99d98,0x000d3d50f580d82b,0x0000a7749f8b2793}}, + {{0x00086dac65846f84,0x000b8b184a18be90,0x000f50dfc9f9163e,0x000bdfa618f3c6e4,0x0000afe515af4887}, {0x000e16cfa60c51e7,0x0009ee647322d93d,0x000691d42a467932,0x0002e56863b1a893,0x0000c8721a2b5b90}}, + {{0x000ee5987897056a,0x0006fff7338cc84d,0x0003cd0a29f7d1a7,0x000f4c1eeec55391,0x00008625bca9aef8}, {0x000f0fe0533242d8,0x000ddebee7314e38,0x00034542be2dc785,0x000311e6d17be942,0x0000a2343b6a2094}}, + {{0x0004301cf477c5cd,0x0002ab6a3d1b7d53,0x00030cd8103b9cfb,0x00095e6e96f2ce03,0x000038fbea44936b}, {0x000b90a008acc54b,0x000a8904b3609016,0x000c686bd1acda20,0x0000e048114fd494,0x00005ab0f4d4d8f9}}, + {{0x000bdef90ead4f46,0x0007246d293b9ec5,0x000303573d9de112,0x000f45aadc6dc3d3,0x00001af5d644db85}, {0x000f4601e63bbd49,0x000a087a714b4af8,0x0000935870f2f324,0x000f960a6914e009,0x000012ad683418ae}}, + {{0x0003354792bcf5ae,0x00007f41be3c88c1,0x000c142b47e1eca6,0x000ddebdc8cbf3a6,0x00008e5a41a3acc1}, {0x000d1ff364d640ad,0x00071b7bbff3b08e,0x0009b246ca485c01,0x0001f1e241e73b86,0x00008915bc9ac6a8}}, + {{0x000cb418d14bdcd6,0x00009b819b92ec5f,0x000ecaff2142a74c,0x00019578fa6a421a,0x0000cda9a55a8acc}, {0x0006359363a78d5a,0x0000ebce5d6e8f57,0x0005c404f6dc243f,0x00056438b0c481d8,0x000021f1152ba645}}, + {{0x0003438f3e2fc0c3,0x0002778ec5d0bef6,0x0000bab2acfaf639,0x000a613040995c34,0x00009c33c69e3d8f}, {0x000a7896b97bf0fb,0x000d924183025e51,0x000de7e95ff5c9f9,0x000871ae0c7dd05b,0x000034587b2ddc5e}}, + {{0x000a79da8f271b1b,0x000381332a91ce35,0x00037e9d38ecec65,0x0005eaabd737de2e,0x0000827fb571e37a}, {0x0002f6167f95c9a9,0x000a0030b5abafa6,0x00086b6bf174705e,0x0009211f763fc83d,0x0000ded86cb103bd}}, + {{0x000f7cf342886a76,0x000e724e6bc2322c,0x000265932e8929ba,0x0005ba669f694ca2,0x0000767c25712d5f}, {0x000c9821f6a99f7f,0x0005f36eff86ec2b,0x0005ed3486fe21b9,0x00084100857e6f4b,0x00003ba09b776464}}, + {{0x000a956c6538d32b,0x000ce0ebaa99bb77,0x0006e54dfc273705,0x000ca26fc41d2862,0x0000ec59f9c31c58}, {0x0005dddbc05f1be4,0x000eabd6ef105f32,0x00011aa76a1b687f,0x000ce473e0cb49ae,0x0000f0197e08a6ca}}, + {{0x0006580b23d6fb8b,0x0002f22ce000c4dc,0x00088dc5c9518521,0x00070c22efb775fe,0x0000e08eaf386d96}, {0x0000f9e5bdd09ac2,0x0000337c16dba3d8,0x0000363489849e43,0x0001c3c9be67c37a,0x0000d611ceba3199}}, + {{0x0009d284701935ec,0x0004f56adc223b4e,0x000d1eee70422ff8,0x000e16a6f16e99eb,0x00005bde8bd944aa}, {0x000c5e0516c8252f,0x000bdb9bbaf3e0fa,0x000b35adb2dccf13,0x00031f937c0cb137,0x00004bea07b8f8ab}}, + {{0x000bf359cf0ad3be,0x000eb4ce9011d0d0,0x000eac2cdc3b6101,0x0008c802272d1fdc,0x0000ce74ad8a8b66}, {0x000e8fac38d80fc9,0x000537f10c1a619e,0x000432c10ce4a266,0x0002836eede88f40,0x0000bf1a37e07a03}}, + {{0x0002775c8d90f0f3,0x00029d5b535f043e,0x0009d75c2586f7e6,0x000648a06f699957,0x0000735f63f9f6b8}, {0x00040e7726af474e,0x000bd520fc28421c,0x000f156aa1f46680,0x000b48b41f5251e1,0x000071b7c6df2177}}, + {{0x0001cfc4cbfca31b,0x000f57ed1f1f84af,0x000d23dc50912828,0x000085f1b1048a1b,0x000002a9d0f5f8e3}, {0x000caf1497eea594,0x000546369358a96e,0x0007ce467f4e2dcf,0x000867022d181302,0x0000af96b3e41c15}}, + {{0x000872dc000aeb4a,0x000cc793dc01eb7b,0x0004d8c005622aa4,0x000edbf05a0f117e,0x0000cda49f07a17d}, {0x000c8c1f58a0f7cc,0x000e8d9b661613ce,0x000639e32b5f0a90,0x000ecad3e495fbb0,0x00009ea83415cbfa}}, + {{0x000d0c201f5ce32c,0x00016577157dbc72,0x00073d070c744357,0x0002426c39bbf87d,0x000042537dcae3af}, {0x00021ce869d0da00,0x0007377f351b6617,0x000d8fe45a48f43b,0x000cfafa73e6ae19,0x0000ed3189970de3}}, + {{0x000ae762be466e04,0x00021e7720f0ade5,0x0002843c06a19691,0x00013fc0033576f0,0x00004a129decc0c4}, {0x0008e8867fa59016,0x0002d5e9a56b0dc7,0x000237f5a534e8d8,0x000fa748cb4f9d00,0x00005d9983dbb9d4}}, + {{0x0007d12937513371,0x000403b7cbdf14b2,0x000bcfac2b7fb8e8,0x000d9866bfdce003,0x0000db5c06aff71a}, {0x00031018effa29e8,0x00004fbcf727d6a1,0x00022a8553be0ad9,0x000bf7969cfb64da,0x0000e985eacf416f}}, + {{0x0008e834cedc78a2,0x0005c97f5478967f,0x000c186a2a467c85,0x0009469dee8aa6cd,0x00006d837221b315}, {0x000629dbdec3f949,0x000478eadc28ad1d,0x000bcf7c9c16219c,0x000b53383eac76a4,0x0000c5ec8b33a0e5}}, + {{0x00007c0f0e12ca94,0x00018bf91307ba11,0x00071d9ab1a24d3f,0x0007747bf130fd05,0x000079c81e5f13b5}, {0x0005fa3e80924361,0x000c57f2b1fbeef3,0x000248ba50a359ac,0x000af11a98df62ec,0x0000363f004297c0}}, + {{0x00019cde83118148,0x000e64cb25d0fba2,0x000c4ad7b162ac09,0x00058e222b481ca1,0x00000cc2a53bbb20}, {0x0002508860462ab2,0x000b158a37864da9,0x00086722e4f10c86,0x000d14158a829423,0x0000e4fb785f8862}}, + {{0x00027d333d753d0e,0x00099a2600a68bd8,0x0002fa817222a7a3,0x000b8713381a4c58,0x00008f9cd717634e}, {0x0004b7b30e02de62,0x00075c3ea937f197,0x0002821c922ac428,0x000a3c40e3d9b177,0x000003323a2e093f}}, + {{0x000fc05a7e4d4e55,0x0008f1cefec7348f,0x000192a2b46ee68b,0x000353c77d99e99d,0x00009d818e97658d}, {0x000392d3e49f6104,0x000248caf3c8ec9a,0x0003023ca2d7b6c1,0x000b2c8a0f354f8b,0x000074921f13eab8}}, + {{0x000df76d07f39331,0x0003d350ece61581,0x00081c9e57d42e69,0x0000f9cb516a8c9e,0x0000d6335e12edb9}, {0x00090961506c4c3b,0x0005bc7192868ceb,0x0007bcc0497dec67,0x0002067339d0df2b,0x0000cdd06eb70f33}}, + {{0x000f7ed789462fbf,0x0007ef672b19b20b,0x000e33cd81a16b1f,0x000f12f89df2aa89,0x00005dea3af5b77f}, {0x000838649cd0da1e,0x000c5bfcd2a2c5be,0x000c32ff1d3c1e34,0x000f06839599cfa2,0x00007239d0120da8}}, + {{0x0000e69d0c2b5ec3,0x000b79db1e73bda6,0x0008b9c4a330f8b4,0x00035cddc5f73aa3,0x000006f789e69775}, {0x000bfed204c713d0,0x00093bf9b2e7bd72,0x000422f0f0282a2f,0x000a48b205e175a1,0x0000d820622b824f}}, + {{0x000e515a23d90057,0x00022d89b47f4c3f,0x0000548b05e86278,0x0000426dc052b635,0x00005bef95a0b629}, {0x000089b8f8a1e0dd,0x000c7a412f79fcbb,0x0002f0be65d47bba,0x000090db03dec5f6,0x000085fb777a8161}}, + {{0x0007aaf19ae92fdd,0x000b5b9b429c59f5,0x000ef392e01cd435,0x000166a7e522b3e3,0x0000ce727a8ae2ac}, {0x000a5bed9bc9a546,0x000c27594ab2b1ac,0x0008e070e66e8389,0x0007d19f80cafd14,0x00005a8fbc95dc3f}}, + {{0x000cc3bbb7c912f1,0x000bff31beae296c,0x000fa0357fab8a10,0x000dfefdef6e8a9e,0x00002f8fc87142a5}, {0x00042101a914d6cc,0x00008a1ca0911556,0x000418ad615b500e,0x0002d61e09ea4513,0x0000e1df01fe2923}}, + {{0x000e5cc99cf67fd2,0x000ce5fb36c081a0,0x0006e1396618f51d,0x00059123402398bd,0x00009ecfd4e3d980}, {0x000e341bff7f018d,0x000c1f6950d1ea13,0x00091e965892d500,0x0004e189b9fe1910,0x000072842d82d9d7}}, + {{0x000cf638f90465fb,0x000755cc7173d4dc,0x000b1dada810c125,0x00004d9dfedee32d,0x0000d16f02f61958}, {0x000aa8044614721e,0x000015fccdbc214b,0x00003a0873eb45a7,0x000b58c3b0135086,0x0000180d15fc5f69}}, + {{0x000a048c4901672a,0x000b2340b7ff98dd,0x000caf804fb759b4,0x00075f5cad446960,0x0000319c7e6dceb2}, {0x000b09071211838a,0x000d7c9c2382267d,0x000bf6ab01dd36cd,0x0008da89262c392f,0x000032c1ea49aea1}}, + {{0x000deaa5ca6ee65f,0x0004c1800a9c59a9,0x000680184e358c6c,0x0008d4ad86de1415,0x00000b504795d3b3}, {0x000795b139b52e54,0x000ee69f5a0fce3c,0x000b814ff6a9423d,0x000cb742a66e5645,0x0000032d10e19448}}, + {{0x00072569564d217a,0x000429fd0889deee,0x0004319cdca4ef8f,0x000f3e3b6ac95065,0x0000f32517aa4f71}, {0x000b21b117693d29,0x000183555154e948,0x0005077940c71c7c,0x000c0754bdaf53be,0x0000cc60c2cdf8eb}}, + {{0x000b43f7dce0b1b4,0x0009c72824968563,0x00065de307f4a3b5,0x000b7842c8a92f9e,0x00002c0e25912368}, {0x0004adf586027566,0x0004f78ce7e8eca4,0x000a94b38a6951fd,0x0008f5eaddabfb1b,0x0000f4735e8fe842}}, + {{0x0002dc3c7e725420,0x000d3f88fcc2867c,0x000ecf5483ea2af7,0x000783793f2f306b,0x000045bad8bfd57e}, {0x0002ca4b36818218,0x000835b27feb5f63,0x000453187115ad6a,0x000070eab7ca7b7a,0x0000719ffe4782c5}}, + {{0x0000593929af0d40,0x000e5664a3d91ab9,0x0001e9eb544e57b3,0x000d2f624b4757ae,0x000032347a13f3b4}, {0x000d1da32f451911,0x000266acc7aa2e45,0x00091a4d237ee7c0,0x000dc21ed6afba7a,0x000010b7c3ccaa69}}, + {{0x0001d7c699cfaf4f,0x0007ca6c922936b5,0x000449a44405d498,0x000f2f24d9456a6c,0x00003f6e5ffdbb14}, {0x00037c452dfb4b57,0x000926a4b56d7971,0x000a9f7ea115ed0a,0x000d5afaa27d8ea2,0x00003adc089d4a10}}, + {{0x000d5a0f6239d756,0x00018c596b9e37b8,0x0003af1688d17ce9,0x0005a37b04b307bf,0x00007aa9f6053a7f}, {0x00074342f5e14850,0x000fbae0c42ca37b,0x0000e1ec491136fe,0x0000eb4e610854f1,0x0000f0ebf7930ca3}}, + {{0x0007b6e75a63ab1b,0x0001d7cbd366e9fe,0x000fda58c355abe3,0x00062d68e49464a8,0x0000bcb1280d5e57}, {0x000777d197806999,0x000a9ecf9715de06,0x000f6afd589c8aee,0x0004af4e62d3ff71,0x00006b88426b88bc}}, + {{0x00074d1d902ef8eb,0x000cdb0df8d05362,0x000e73dab4f8bd22,0x000917798e1bb263,0x0000747ec50844e3}, {0x00053692d52a05db,0x000f6ca8d9b29727,0x000f02477bc17e87,0x000f3a1726632e3b,0x00003ce08d4ab050}}, + {{0x00048d2262daaba8,0x000aa837e39f0f7c,0x0009320f1da31454,0x000ea364915f9041,0x00002e8921d77b9b}, {0x000423a958563826,0x000a3497921fbf0a,0x0000461a0e93409b,0x000ec5b86536c442,0x0000775d4ee0d067}}, + {{0x0004ed2cae04d7ad,0x000171ad7cb36930,0x000d2d311bc08ed7,0x000f695e13619e36,0x0000d2e0eeab2d2e}, {0x000ee6772c62de91,0x000baa1b52e55366,0x00004bce2a244410,0x00054fc30c34b0bc,0x000005c73893a90c}}, + {{0x000cccf4a1a0cca9,0x000722bdc2035d63,0x00057bd07cf346bb,0x000f316c79ae4fd5,0x0000ac63d30daba2}, {0x000ff39d838e4cd7,0x000204741c2e1f2e,0x00069d840c3461d8,0x000a84505593db6d,0x0000741dc28c944a}}, + {{0x0000876a8b27f44b,0x0008bb19870aa30b,0x000f8e9ec31cc2ec,0x0004c4e60731153a,0x0000c55b52b0033d}, {0x00089b1ed9e1929b,0x000e314409183cd1,0x000e19b9a4f6719c,0x0007dd490b7456b3,0x00001a8b428feb17}}, +}, +{ +/* digit=13 [{1,2,3,..,}]*([2^91]*G) */ + {{0x00023862936ccd46,0x000c9f3bb8a5bfc7,0x000ca23157985ce2,0x00081bc9abd0a0d9,0x0000af5b9895adc3}, {0x0005faaee4832a45,0x000d59f64358253c,0x00046da055a2f27c,0x000f568dc06afc75,0x00002ba011d7eeb2}}, + {{0x00055fc1cf25ca24,0x00020e1d348934fe,0x0002536cb0ab57ca,0x000233ee745fbe8e,0x00003e16abce68d9}, {0x000e1c0522422409,0x000a5979e6309e7a,0x00066b196881b4f7,0x000c1edac5fd108b,0x0000142c6726f6ee}}, + {{0x000c2137390618df,0x000be970f27a0fee,0x0002f4c961a17241,0x000f8a198a977f70,0x0000195907ddcf67}, {0x000f379501c8471f,0x00059ed6d515c9a1,0x000bb63a198210a5,0x0001b9124b243403,0x0000ed746bd02b9c}}, + {{0x0006e74ded67841b,0x0004cc8fd37f409b,0x0002803b1af55986,0x000c3bf000b91399,0x00007ceb09bcb37f}, {0x000f8d459310a1cb,0x0007593dba573a77,0x000ed294ac4fff32,0x00092052bf2f7fbb,0x0000fe022e7f7a32}}, + {{0x000c7a6ac040f2fb,0x00055a54b073122b,0x0003e7acd6ce751a,0x000107d66c28518c,0x00003aeca2c1f0ec}, {0x00033bbbdafae2cc,0x0009f8fa7af36884,0x000dd647c01943c3,0x00009696d6c87579,0x00001c20d14c8db3}}, + {{0x000a61a0c68f6032,0x0006a9123a83491a,0x000bd0c5a9dc2dd5,0x000db59a99946a29,0x000081228cdb3c43}, {0x000cd2ebd0599303,0x000f84227c8ed033,0x0009053e94a3bae2,0x00069f434a9ed1b1,0x00002474f03f1410}}, + {{0x000126dbaaed16c2,0x0009899463a3470c,0x000eb820a2fb87f6,0x00066fd977557dc9,0x0000a9950295b8de}, {0x000646dbf257d07b,0x000e7a4e19ec84a4,0x0006a7eaee3f42b8,0x00025c05ee05cfcd,0x000057200c018815}}, + {{0x000d1bc968cdc161,0x0009f62c0803d083,0x0007eca12854bc1a,0x0008683a5785328d,0x000052551f11c77b}, {0x0005bb2ee4edb660,0x0002b2b5a388ab4d,0x0004ac3bf9559546,0x0003650232668dd4,0x0000b1b0d76d1f17}}, + {{0x00004047d03bfb04,0x000267ecceeb6096,0x00091101feb19ab6,0x00010ef35c6beedb,0x00003595d5f45735}, {0x0004e8ad3b49694d,0x000206d570226401,0x0007f45f06b32f3d,0x000807cfb7433dee,0x0000c15e03794afd}}, + {{0x000e7a6211af3d16,0x000c95e02ef4989f,0x000bbdf2c96b6185,0x000b8ad9fd10ece4,0x00003291adf91780}, {0x0003b209aa3794c1,0x0008e8ddaca35358,0x00074558fbaca474,0x00087d9bbf1f277d,0x0000f61a073f7b35}}, + {{0x000d8adb85ee3f83,0x000ebd78bd46cfa0,0x00011af45006aa9f,0x000c03cb789b856f,0x000038718b3de225}, {0x000b87d218ea96d0,0x0008296dd64f240a,0x000a55d762afba77,0x0000c106f6b48540,0x00001637a1067f29}}, + {{0x000fe903a2ddee0b,0x000c2147304ab5b6,0x000bce46578683be,0x000529212a7403d4,0x00000a0c11ee7628}, {0x0002eeb8c98226d4,0x000acd7eace9cfb7,0x0007ed1f6bef5b8a,0x000c572a94bfb860,0x0000fb6e6fd9f827}}, + {{0x000129845c7d39d8,0x000c08fc8d104a0a,0x00091c5df9c60f44,0x000c84addd4d5bba,0x0000117fecbad4ea}, {0x000e5b606f925139,0x00040714a55c0cef,0x000e33820c14e7e6,0x0000982da6e9998e,0x0000df370032e21c}}, + {{0x000f523358513503,0x0001fd64adfb3997,0x0006889ad5e8f89b,0x000efd415f1bcdca,0x00000dc5193d322a}, {0x0006d6646cc33bcf,0x000bc53d4982b948,0x0008f8e8fa9ce266,0x00054acf5820c0d5,0x0000307c2eb0ed58}}, + {{0x000613f329e775c2,0x00074e8d77c0eda9,0x000f3edcede373e6,0x000303ea32e7c5f4,0x0000ace4b9dce770}, {0x000d62a55c54561d,0x0004408d9c3361f9,0x0005d18ac4c51c97,0x00082e094177a277,0x00004c611cafa47c}}, + {{0x000f298db093d970,0x000d8fc659552b85,0x0004088b59c6d6fc,0x00017f0a2d06747c,0x000086eba0701cbd}, {0x0003e9934facc02a,0x000b5a33252cc71a,0x000700d0a64d5a86,0x000a74776c01c506,0x00000d58cf6a3492}}, + {{0x000e24841127be4d,0x0006109c01c62f85,0x0009d1e24f0d7950,0x000f9906c5f8998d,0x0000d14baa86e1ba}, {0x0006495cd2b7045c,0x00079b660d67c95c,0x000b91fd538bc207,0x000698f1bfde9d01,0x000069d46f82ef5f}}, + {{0x00054cb598765316,0x0003c6ee2235eecf,0x0001d05682fcdb79,0x0000cf6e6100f9ff,0x0000dc6262cd1fb3}, {0x0002721130ab0425,0x000fd66b83432c4b,0x00068d04d701f922,0x000c56e867326ed1,0x0000fa2450fdaf47}}, + {{0x000e18b2b572c025,0x0007aabc185629d1,0x00011115af0a8c3d,0x00059e153c5e496b,0x00006571350e5f65}, {0x0000804bcbbda06e,0x000ba4057dba77c0,0x0005a19dc3818e66,0x00007db6d31ee3f2,0x00008435030e7d57}}, + {{0x00046d989cf9775b,0x00008bbdbfa6a9e1,0x0004e3b35a8bc449,0x000972cffc49e7a3,0x000053ed79153d43}, {0x0008b080e14ff257,0x000ace79b7fe22f9,0x00059f0939c733aa,0x0000aeb72dd048de,0x00002619ceb8b79a}}, + {{0x0001e4f65ecf7496,0x000ae8ee251022a3,0x000790a0b8ce447b,0x000e5b7dc58d2831,0x00004c7c03b41e33}, {0x0008b362b8088d3b,0x000cbcb87bd9c6d1,0x000cb48e67cf5c74,0x00069f85efc38c53,0x00003fa36fb3ee0e}}, + {{0x00043ceed8105788,0x00090734b644bac6,0x00036bb8ea2711c0,0x000b3810041eb459,0x000093c69a1b4b83}, {0x00084710540e3d01,0x000d719e03fd4f77,0x0005e622babf321d,0x0007b11922ccf87d,0x000096e359a83944}}, + {{0x000fc5fc73da9b5d,0x000b1595fc9ab291,0x0005a95066904c34,0x00015959fe032bdc,0x0000b4b92b11f12d}, {0x00034add676f593d,0x000519f1f0786c3b,0x000697738b1c970a,0x0009584fb4963dc9,0x00001084921d81d4}}, + {{0x000b5da661dacece,0x000f6b0cd23bd2f4,0x0001cb076a96cfbf,0x000ee755e6ddc3ce,0x00006cb5574c3f61}, {0x0003a2123b371d00,0x00074a4a55ca4cdf,0x000b8d605f7131d5,0x00082c751d8514b8,0x0000089e6493eacc}}, + {{0x0001884e243e59de,0x0008f13be7d12276,0x00090809ee25d4f7,0x00092c13560a056d,0x0000cbd0fd7048aa}, {0x000c7cf11455b365,0x000880bcf192c1c8,0x000ee71e5bebb543,0x0001694d7bdb0baa,0x00000e46da8bb58a}}, + {{0x000ef46c771c87f8,0x000f7f262a6e438d,0x00050eb2f306408e,0x0009c80d5cc4d430,0x0000385ce31c91e8}, {0x000059abc1a67c19,0x0002e387ea4cab0c,0x0003e03c8b9bbf51,0x0005c84742501cfa,0x0000918e418e3d1d}}, + {{0x00022bbef09486e0,0x00010f5c122211d7,0x000b2de7adf0502a,0x00049b5ef8799064,0x0000cd147024c20b}, {0x00090d67f2d70c08,0x0001cc8fbaf0cafb,0x0001547cd4a1a267,0x000146a52fc4ab4f,0x0000fe8ec3c3592c}}, + {{0x0007c5d6d28ee3f0,0x000c1f5e25a2d30a,0x0005a067148ab16a,0x000b0e3e550cbb99,0x0000cdbad202b2a5}, {0x00093875ccf1d8a9,0x0005756ac2a6bcdb,0x000720061b8c60e4,0x0005ffd19c95c274,0x00006cf02b509a1c}}, + {{0x00091e12337f16c0,0x000c7393588f049a,0x000c7530b5c0408c,0x000e8d167beb1eb4,0x0000bb3b2a2771f5}, {0x0000d4b2f53140be,0x0001dd263d66660e,0x000799cccb650354,0x000900827c699d37,0x00001ecf8af970a8}}, + {{0x000b005909514a74,0x000ecbe20fc8996c,0x0008fe96ae8999fe,0x00053c02484ea215,0x000081ece97b1b2e}, {0x000b646f679d3fed,0x0005b8da2343f2fe,0x0006cabdc877b5b6,0x0000406a1d29230e,0x0000aedcbd3b6bca}}, + {{0x00043b54f4b39c27,0x000d249a5720a07d,0x0002cb9000f597f6,0x0003ab0ac7a0dc36,0x0000fc9c13cdf3e6}, {0x000c0eb22fd82d5c,0x0003b8a81a1aedd4,0x000364a7c0e3f20e,0x00046fbf635e9939,0x0000c199b407168e}}, + {{0x000014cc44058054,0x0004050153cddf02,0x000dba3274172b05,0x000f0217ddb34198,0x000092ae38e923a0}, {0x000179277af42fa1,0x000c90d55c033ee8,0x0000a9f8725ae26f,0x000fd2debf1b8171,0x0000ce7e032b9a99}}, + {{0x000a44861b8554c2,0x0000a3a94aeb35be,0x0003e71fba83aa07,0x0001d959d8dc768f,0x0000eb913a4c91a2}, {0x000e183a28b0b33c,0x00088becfd84e460,0x000c958afe20d5c9,0x0004b5d299882015,0x0000649765aefe9f}}, + {{0x000230fd8633e864,0x0001f08ee9e87f37,0x000e6f193bf5b4b2,0x000cde4fcb7532ce,0x0000104b82017ce0}, {0x000132f59550b517,0x0009ea49ea36c092,0x00091a39ec7cc727,0x000b70bfe7e175f2,0x000021a2ab8b1372}}, + {{0x000eab9e1005ec21,0x000f75e979b06cba,0x000c6a4d8a9df400,0x000a67cc9a2af77f,0x000035cd470f6031}, {0x00096537b57815e9,0x00097e2741ed2894,0x0009a6fac39520fe,0x00003d6cc06b9003,0x0000eee76b0b2e06}}, + {{0x000f7b48f6edb04b,0x0005a929e3038237,0x000f7857536e7673,0x000901ecac573596,0x00004eb199d3fae8}, {0x000d3cac11a43ab4,0x0000d55fddc2f291,0x0007aa2635d37480,0x000ab944155f4673,0x000043238379f1ee}}, + {{0x000de044927b3f1d,0x000241bc54ae6068,0x0001082ef75dcd95,0x000d7d5dae8d8aba,0x0000eb60878f5e1f}, {0x000c905f7e55fe92,0x0001e240bd8a7772,0x000081d2630467e4,0x00059a6904f58040,0x0000ecaa62c1a4d8}}, + {{0x000e9f68575333da,0x000f00ecfae86bca,0x0009f8c83e13f2bc,0x000c5c3e371a2ec9,0x000037a85cb421a7}, {0x0005b5a329bbed02,0x00045419c8fd74f1,0x0009823120e28310,0x0007e3cdd91afbd7,0x0000839b1b682506}}, + {{0x0006e9d3ccc341ba,0x0002150f316b25f3,0x00080a38e4c7c7e3,0x0003c01f7e4d50a7,0x0000c3ea0d40f57c}, {0x0001c7b30f55321e,0x000e7d20d94bdaea,0x000a029fadf45df8,0x00097ee167f6b768,0x00002aa6cc9459c7}}, + {{0x000c17a91f1ba0e5,0x0009787593f0d015,0x000f9ce851544d29,0x0000a7d6fd2eac07,0x00006e42a2d03161}, {0x00047f0cf39d2dc2,0x000e394ce9aef618,0x000c79ad7bb38167,0x0007952cfa312fd5,0x00006e9508b6606b}}, + {{0x0004a9337b6501f3,0x00038724b1274086,0x0004b9735e20280a,0x0005a7b1685a2355,0x000049e5df053c39}, {0x0003d8976fcc51f6,0x000f211285be64a1,0x000a5a1dce61af27,0x000534f6c0f84385,0x0000330e4e187016}}, + {{0x000e341cd1abcafb,0x0009212e247ca60e,0x000d11cf4928ec27,0x00068275c242a86e,0x0000701b7f29cc07}, {0x000113f0cb2d0c5e,0x000a0e15728ff118,0x000ce069dd37a910,0x000e33fbaf062392,0x0000da9bf4139bfe}}, + {{0x000d893ecc8a3843,0x000aee3422fc03c4,0x000bc5cc45125f34,0x0003fa03d850b732,0x0000d9db328e612b}, {0x00093a198c9fdc42,0x0008d59f8b1b219f,0x000cf49c0b2febe9,0x00075e07a055d8a4,0x000070db58a14b84}}, + {{0x0001b49f9f74da4b,0x00079c277b30b6ae,0x0007a713eb7573ce,0x0004bdf55e41397d,0x0000c4c19bd84865}, {0x000931c026a86997,0x000de2bca5cf171e,0x000656b2300e38bb,0x000d5f65e8930d8b,0x0000ceba324ca80b}}, + {{0x0000f392145ceee1,0x000cec5519c0f83f,0x000ccf35a80091ac,0x0003f61fdd589fd8,0x0000aeb32670044b}, {0x000c35391cc68921,0x0007d7a227dab6a6,0x000a75a4bbb2c563,0x0004940e0441f13d,0x00000acf8254d41e}}, + {{0x000b7c2475bc8687,0x000275d5d3d4a8e7,0x000998b4c20aa04c,0x000a5a3f2c0804e0,0x0000f72faa30ab18}, {0x000cd37890ebf796,0x0000909c43568186,0x000ac20ea2015287,0x0002acdab79ef3d0,0x00008e23170d603d}}, + {{0x0001b7430856e702,0x000e326886326e48,0x000c9d6b951f2e59,0x0004074d31e623cd,0x0000e0b17d35a649}, {0x000830e9a2c52388,0x000c4af19a13dffa,0x0006e6405881b51b,0x000b8fb31e1b7bc8,0x0000bc0283606a6b}}, + {{0x000cd1399b0fbf20,0x0003ae7bfaaa7476,0x000515068398a2ea,0x000ccf4a67748a0f,0x000052c9dbaa0de7}, {0x000b107df0bab755,0x0000bf5cd043bd9d,0x000ca0aad0f46f5d,0x000122d95fa8e659,0x00004b88235175a9}}, + {{0x00063c7b5bcf7a13,0x000e4a0fcad630a2,0x0002e5101cfd5a29,0x0009bffc7f24c1e2,0x00003d1eff35a181}, {0x00005715a33e4b08,0x000243d6669d649c,0x000cac16fe982911,0x000ca0d08374e968,0x00008326799f5651}}, + {{0x0005bba6afc5ab95,0x000f1153dd46fad0,0x0005a6b8ed84540e,0x00031d26cc136a2a,0x00007c4b8712243d}, {0x00093b3f4bd9ae24,0x00099ed80b28abfd,0x000a5a784db8f876,0x0006abdfb9bb8a47,0x00007c9037ec1306}}, + {{0x0008517c194a6c3b,0x000ff8b4e080bad5,0x00095ef1ab25163b,0x000fd601840b3f70,0x0000f57e65fa20a0}, {0x000761f8718a4635,0x000026a37b1da3f5,0x0007d62b14f1d622,0x000a97dd8bb7dfe2,0x0000b65d15c8388c}}, + {{0x000fb630f9f3c36b,0x0003514f1507f908,0x000709730fc5a09d,0x0001a551491ecda3,0x0000eace9768d59b}, {0x0005fa0c62ba40c9,0x00057a73f9217bef,0x0000e19c42c546db,0x0005238d4079ca10,0x0000ca0c26f55313}}, + {{0x000ef817c3b2618c,0x000516c3678b7d65,0x000af4eab31e6d46,0x0005e838846fbf7e,0x0000cf31a0360563}, {0x000d8d7395cabd57,0x0003bfdfda36daaf,0x000e52df3d83d332,0x000c0c667a2f6684,0x0000e1a16cbedcfb}}, + {{0x0009566376fcec40,0x0004537333dd7cc5,0x00051d3c0941a4af,0x0000dbfb72206ff2,0x0000e6496b4df3a2}, {0x000340da7a61207b,0x000de24d61e2c6b0,0x000afa106554c6de,0x000514a942394f93,0x0000959becd8bae7}}, + {{0x000e7c288392edd9,0x000e09e87173c5d5,0x000badf27f43f861,0x0000875f56cbbdc6,0x000059011eb4dd0b}, {0x000b4176f01cea75,0x000d52c23a0d6c81,0x000f0b5d771b4b78,0x000415b0fd29a184,0x00006d4d765d5cff}}, + {{0x0004fbf6e5ab1c10,0x000c5e16117aed34,0x000068ab71d61e70,0x000d5853f76aac64,0x000041afad97ee21}, {0x000f2590f3380ea0,0x0000057fe06e1782,0x000ac009aab5f995,0x0008523a89866ffc,0x000010ad3182779e}}, + {{0x000edf9d8e340aa5,0x00013c432c9525be,0x000c5b0938e52347,0x000f7f2b547dc9ce,0x0000337edbcd4751}, {0x0005f8d089a8d34f,0x000849d94da27c6b,0x00021344d3091355,0x00019ae8dccbb520,0x00003db4afef5bb0}}, + {{0x000221483572979c,0x000f488d38f240cc,0x00001d197443feef,0x0007cba0ff6fdd65,0x0000c8ed1a1e245f}, {0x00043ac345ea9f35,0x0007ed4c13607cff,0x000ee8dc785c5171,0x000ce453e3b03a22,0x00000d9cd4fd626e}}, + {{0x0000e350ac33d68a,0x000cd316d7ea5a59,0x000d601e37ae8df2,0x000a613a4ef1b40d,0x0000b969a55dfd9c}, {0x000b7d820baae471,0x000789e5546e638d,0x000adea90d131722,0x000588b4bafc01bb,0x000020136f521961}}, + {{0x000719f9325b2400,0x0005ba8ad2510bfb,0x000c18046ed327c0,0x000dae7c4bb581f8,0x0000f5c43bf2821c}, {0x00064d2b8967b272,0x000ff2fc977093bf,0x000e43bcf14f6a54,0x000c6150374246de,0x0000edc1c38954d2}}, + {{0x000d28e4579a1c60,0x000a23ad0bc91684,0x000159efe0e89838,0x00013c18b907beb2,0x0000f982933523bf}, {0x0005a3d80fcaa3fd,0x000e71da29914720,0x000260190947110d,0x00044d6527935a8d,0x0000b8cdec4b3dda}}, + {{0x00078460ca8fa191,0x000f5396fa5eb6d6,0x000f8451a2349560,0x00008834935f4c4c,0x00009300128571d5}, {0x000dab31e4ba5a79,0x00014b60c848233f,0x0007e000ae8f45d3,0x000156c4a44930f5,0x0000e9ee0a99bbad}}, + {{0x000d5403bff252a4,0x0003c2c93f8b1649,0x0002ae1a111254e6,0x0008a652e0510e35,0x0000025872deaf32}, {0x000f49fcd577ca3c,0x000a66df694207c9,0x00088c106ad78c7e,0x000eacacb6deef66,0x0000ae91691d5244}}, + {{0x000a1a6556a90c69,0x000f247842e0528e,0x00055287f1f99c51,0x0000834918eed56d,0x0000addf95032778}, {0x0001770d1ffbb4c6,0x0006ee9a94d1ca36,0x000a5c9aeb4f8224,0x0002c9a6b1ea0ae2,0x0000815b08430763}}, +}, +{ +/* digit=14 [{1,2,3,..,}]*([2^98]*G) */ + {{0x000dc06264c6edf0,0x000ee76ada9f8a5a,0x00093a29ac0d4b89,0x000bd589805d8eab,0x0000a3f857d466c7}, {0x0008cdc0af4d7692,0x0003a4587e2c7fe4,0x000068fb7ac8249d,0x000cf84bb97b33ee,0x000025f782d1e221}}, + {{0x0007b344d830d611,0x00090706b372f099,0x0007c5d82081ecfb,0x00062e5f1d371461,0x0000630e68f8309b}, {0x000027ecab0d0e7b,0x0008eeffeefc38fb,0x0005a3f00f139e51,0x0006235555687383,0x0000000539130fe6}}, + {{0x000a7d994abc3339,0x000eada42542f0dd,0x000d2774877be20f,0x000d3e01fd92532d,0x000045b905b58c4b}, {0x000f4f6018764c26,0x000b906b0e9ad737,0x0005a7ddd213dad2,0x000979cb47e139ca,0x00007e5ac0e28093}}, + {{0x0005bb244b1a7745,0x0004d3be15ecec3f,0x0006b92215c50b54,0x0005c2343f4af69d,0x000061a0fb33d6b8}, {0x000996c8fb6c5f4c,0x000f7c15d9d2bd46,0x0001d8db7e469c42,0x000997e76e202eb9,0x000079e3e7b012a6}}, + {{0x0004e3dba4f34c34,0x00037e53915042c8,0x0002eb606a8d77ef,0x0004eacde90607b9,0x00001bf86bfff708}, {0x000dcfe17dc51185,0x000be051f4755508,0x00005d090cce6cc7,0x000d86e74d036824,0x000003082999813d}}, + {{0x0008952a021a9b5f,0x000accd265a08868,0x0006f5e0a1762020,0x0001ec077c5bca7f,0x000051a150e7a0c8}, {0x000c4dedb17071d6,0x00091d7d3367b9a8,0x000cb4a59fc13868,0x000144624e29dd68,0x00004aa6d75f039a}}, + {{0x000a3fa97e6e0640,0x000d7477c822e5cb,0x0006d71cfa74fbe6,0x0003b6e7f42fe5a5,0x0000e15e3b313245}, {0x0003747e55840168,0x0000f0b46d9f18e2,0x00012b245efd94b3,0x000e0e8bb7ed74b5,0x000071a6634049eb}}, + {{0x000afafb42e29add,0x00018d9ad91573de,0x0009c54ad6e3aa89,0x0007703a1f57b2de,0x00004626948ca4b6}, {0x000abbb815e6ca50,0x00035b40f7f54940,0x000a08f33a48dad8,0x00084e31e14799ef,0x000095a109d11471}}, + {{0x00002547eca94470,0x0004a32c671602cc,0x00040116a86806e6,0x000e8db86a0dfb11,0x0000467b5c6238db}, {0x00065c7b3957d267,0x000579251baa175c,0x00083f53398cd355,0x00066bef5f51a807,0x0000599690598dba}}, + {{0x000a1e066f254055,0x000e6ae221534d5b,0x0008d3bb91428e24,0x000b46795bd47970,0x000023f090e0e98d}, {0x000018f58c20dcc8,0x00068a6f249e38a2,0x000915d4db72af54,0x000729b41ac98972,0x00001f3ec32bf5b1}}, + {{0x000c30853828ecc8,0x00003ae49031a5b0,0x00016d35710f0304,0x000166de6aa30f87,0x00000b38f0b6be3c}, {0x000422386ba22348,0x000d2a6b4a859201,0x00069a2f618226b7,0x000dabb6b9065ae6,0x0000a1c3854e2ba7}}, + {{0x00086a14823ea47f,0x0000554a1c55f1c1,0x000a974aa782f893,0x0008ae49b3fe8e67,0x0000129a2c97602f}, {0x000d903dd777718a,0x000e76223c4293a4,0x0009a1637ef4efe8,0x0000b2f996c38d78,0x0000dfebadce6272}}, + {{0x000d950e92810589,0x000774dfa90b0136,0x000039faf2b175ce,0x000e185a260a83db,0x0000561f8e4b6c93}, {0x000ebf0e2fe28b50,0x00034acbe16edd05,0x000320d07af8414a,0x0004430be5fad27f,0x00000ee98f0868da}}, + {{0x000cae8c6791947b,0x00007996853c4c82,0x00019a0f47f2509f,0x00004935af953959,0x000027cd71f58bb6}, {0x00083fd8bc62211c,0x0009bfefe89d61da,0x000ddddf3c87eab0,0x00047e03a5e0f6f5,0x00008b3c456c5505}}, + {{0x000137df36f714f4,0x000582323ed21aa9,0x000cc68386a00b41,0x000bbd594ecffcce,0x0000cecf5b089abd}, {0x000983eaea96fcfe,0x000b24d12f6ae33a,0x00053fa16977b26c,0x0005befbcf594bb7,0x000088d8f7495883}}, + {{0x0007b8acedb9388e,0x000400efbaa8ca48,0x0000a06b17cd0588,0x000a7400dc760aec,0x000015cdfa858e76}, {0x000e7f3b8048b0e3,0x000ffae832778b42,0x0006b52cfbc15e64,0x0000d578158f0142,0x0000af7e47c0508f}}, + {{0x0008eb22823149ed,0x0009745fbd4f13e8,0x00047180965d7326,0x000b40df9c9b9a8f,0x0000c9f0be3c6954}, {0x000a28f9b361f46a,0x000c072e07a5a9d2,0x0000f2ed0ac3a2dc,0x000392aaeebda466,0x0000336c3e9cacdf}}, + {{0x000d1d43afceea08,0x000616a9cef394de,0x00024432a5bde0a6,0x00043191915f59c4,0x00002f62d7e1fcac}, {0x000fa75ea0b786d5,0x000a12c9de645b54,0x000d5287986117cc,0x0002a68bb817b967,0x00001ceae3eadae0}}, + {{0x000b7ef5b2d3b2f1,0x000000070d048432,0x000c6c03e4e7e07b,0x000c7ff417809ed3,0x000025fe6da4c479}, {0x000e17e440a00118,0x000671aa9008cffe,0x000c32ed6a56c499,0x000f577463eea607,0x0000831162ce69d7}}, + {{0x000e4805943376fa,0x000b1eca3608d8c9,0x000ed34782092af8,0x000ccd599e1ef20e,0x00008d7322137ad2}, {0x000f359d5c8c0d56,0x00038757adcde109,0x000514301b31564f,0x0003bb5fcb028045,0x000004f028be60c4}}, + {{0x00058323cd637177,0x00028200d4cf1cd6,0x00046e38835c4220,0x000d0b6ca712117f,0x000024a80f8a1923}, {0x0009bb310add934b,0x0009b0984f44f959,0x000603516ff5e5c7,0x000bbee13c21257e,0x000090eda9f674c5}}, + {{0x00005458fc6dd126,0x0000947af627b5ab,0x0008f966ca449c6d,0x000b0cc003e78cf1,0x00008256aa596830}, {0x000a0e079d35b70a,0x0009940a5f36cb04,0x0000c3f2d26877d1,0x000730ed00d82660,0x0000ab865b6523ff}}, + {{0x0009177f2d61f6a6,0x00066af811bf4a06,0x0003b1c247bd378c,0x00062465ea93b39f,0x00009171cdde60f3}, {0x00095252b216763b,0x000749e6bd882dfc,0x000ff92142ce99f9,0x0000524b31478981,0x00009b67920e8098}}, + {{0x000f5eab873e5982,0x00002b05e8702523,0x0009e3071bab7eec,0x00049dcb63dd8dd0,0x000065a0588f39b8}, {0x000f19f79a322046,0x000b6ebf2f4ddf97,0x0002dafc0af5691a,0x000d2c5d445ac1d5,0x00000c9570bf9541}}, + {{0x0008c920c8a7eca8,0x00034d2fb0311be7,0x0001335f7aa6a1a4,0x0005a8062bc8fbb6,0x0000934c72c41287}, {0x00035614cdaa4860,0x000b9d9596f7a99a,0x0008ec39c47104fc,0x000fd127b936a44b,0x0000930bd26ecf89}}, + {{0x00031bd38f4959f4,0x000209f43efcc5ff,0x000222f36c2b77df,0x0005f4ea5ceeacfd,0x0000dad55f834b8f}, {0x000abbbfbb9bf288,0x00085dc8869ed851,0x000c867e63c03f7e,0x0008257f770d1a05,0x0000ee1f000730c6}}, + {{0x000b8711de100539,0x0006ad95dfe207b6,0x0006cb512680143a,0x000f506e2c18fddb,0x0000bce3ca0378e8}, {0x0004eb8130d57fba,0x000fa5840b8715bb,0x000c84823eaae39c,0x000b26629e9d3145,0x00003031a8c8c1af}}, + {{0x000fec3fb7df9633,0x000f793017b5239e,0x000d417edfbe62de,0x0003a2bd4ed6d43f,0x00005cfa222922a4}, {0x000cd26d9111ed55,0x000332b5b95f6de9,0x00094dce34d4e23d,0x000ea1652aaebfcb,0x0000a74a2880fcc4}}, + {{0x000b85e6b698c60f,0x0006bd05bb9009a9,0x00080f4cd386aba1,0x000414fc79987378,0x000022a41cd0ade5}, {0x000386b37f02931d,0x000144ed3b36adc8,0x000831113fcbf024,0x00062655c85d148e,0x0000abf8c2abb579}}, + {{0x0008a280beb3d98e,0x00022e4dceaef7f5,0x00019e2cd5a2c67e,0x000d97b0a1fc4ced,0x0000ccb55ec7430e}, {0x000927ea8db4dbb2,0x00054287f738760d,0x0009e0694ad868fc,0x0009547719050c59,0x0000b8bd54ad1b07}}, + {{0x000b919915296235,0x000b9440eecccfab,0x0000df1d4f7f9db7,0x000fd803b66d2b79,0x000021f810f61fb8}, {0x000374ab0babbfca,0x000b1da810b6567a,0x00007019ae31b3a4,0x000e6dc732421879,0x0000aee1fd5d3d9e}}, + {{0x0003dca799b1e8c7,0x000498f64369d75b,0x0009b0643f842b8f,0x0001b609c435b8d7,0x00009e18a4dc6dd7}, {0x00093f286cd43de1,0x00000522ebfb1d7b,0x000981ef58ef5f5c,0x0009a7c511d1c979,0x0000079e84ba8d07}}, + {{0x000e22bd3c256aa8,0x0002fd4c94bbe5d5,0x000ad29c666de35f,0x00035e3b865874b6,0x0000224e3c128523}, {0x000d5f4d614945e5,0x0007845bb7831b45,0x00099e134cb89357,0x0005ec39f9f5f9ca,0x00002f887fca2984}}, + {{0x000ef0e4412d59f4,0x00035ee9036e0f4d,0x000ddd0c48d53893,0x0000fc472a1ce74a,0x0000a17b9b8404fa}, {0x0003f18afac2a705,0x000d43fe74db5f3c,0x000c2267174d55ce,0x0000895e0f14e108,0x00005dd34a549d92}}, + {{0x00026468b946678b,0x000bad393b4640d4,0x0009805afa144f1f,0x0005586d58b328cd,0x0000b5a443e9ccf4}, {0x00058637fc0a22d1,0x000e069b47544588,0x00019ddb88467c90,0x000d6df432509399,0x0000e17ce7f02ef7}}, + {{0x00091620e2b9010e,0x0003b1a55e8e98b3,0x000c2c0459f0e8a3,0x0001e1dcfff42fc9,0x0000dd65a82c1053}, {0x000a151f4aca9977,0x000c1b7e25a6edab,0x00038c1f361d8bb1,0x00000cd30261823d,0x000058c4491cd6bb}}, + {{0x0001b0cb59285f27,0x0000f4ffe44d5c38,0x0003e8dac0335ca3,0x00035f7325d84a82,0x00005079b33341fc}, {0x00012eba3b28d558,0x0004bcc94ac65271,0x000e2e85b998a96e,0x000224df60868980,0x000070d7cdb23165}}, + {{0x0004ee5b665a2bf1,0x000dc11697de8321,0x000e9fb2b99d4d00,0x000b6248a3b6b7cc,0x0000ebb83a1c6e31}, {0x0000e7f18e605d33,0x0006d595cf04d7a0,0x0008c209f036abd3,0x000f7b5e7c03f37f,0x0000202f91c41e8d}}, + {{0x0005fed58160235b,0x0004f5fcdab49aa8,0x000ad6f5b0d663cd,0x00046955fcc1cc31,0x000055aa92af2c90}, {0x0003cc5ae6b06c50,0x00057eaea58e748e,0x00014924cb8d73af,0x000859aefc2fbb85,0x0000055f1f24388c}}, + {{0x000b0ed88e1a7efb,0x000e7ceefbfc0fce,0x0006d857cea82848,0x000cba7abdcd838d,0x0000ec1dae8cead4}, {0x00000a669ceda0f7,0x00011d3126dfc250,0x000f4b9ca2e7c1e0,0x0009b84cbfd34e07,0x000040e4bcfea9b1}}, + {{0x0003f728819ea128,0x000b06e16cf36161,0x0002919408897f08,0x000e528858cfd6a6,0x000058155bc25fd9}, {0x000ae2986292c0c6,0x000167af291c84aa,0x000e79cb6ec4f1f0,0x000c81fd358f1993,0x0000ce475e3b0ba1}}, + {{0x000f785374d12d02,0x00012d98caadc70a,0x000d42f2a8babbf5,0x0006c2fa867fbae1,0x000053850d2b0795}, {0x000def812567bf3a,0x000d771344b51fe6,0x0006e684f2a6edf9,0x000c5e0a73f6690e,0x0000e282dbcf75a6}}, + {{0x0006d9be5836ecb2,0x00020a13c0defb0b,0x000e52387a145e68,0x000f89ba1fac2f4a,0x000009824d57a58e}, {0x000dae8413ed668b,0x000ade3adc47d3d5,0x00080a12938ac94a,0x0001e632ee79ec52,0x0000a4e43332753f}}, + {{0x0003b2a5bc9d9932,0x000a0b017d90e7c9,0x0008d33771f5faba,0x0001f007e829cfb3,0x0000a6756330d4e3}, {0x00071776f7f71d2a,0x0006552d8f758b90,0x0004bfebc559f745,0x000c49858fe49424,0x000017dcb740493d}}, + {{0x00036a95aead4696,0x0008faa7b0da3af4,0x000525e90dec1412,0x0008746bab082157,0x00007f8eaf99f609}, {0x0009610fdfd3120b,0x000a43ab469f1ec9,0x0009ad77bd19d496,0x000fd9a9a5d8758d,0x0000da7732d94025}}, + {{0x000ed2476d66cd25,0x000cfb4dafef99b7,0x000305d194636025,0x000c900c1346a4a9,0x0000bf0491ebcdab}, {0x00076b6079e2c2ca,0x0008b0b6c5b084b1,0x000dc7edc14533fe,0x0006f61b6cefcf0f,0x00003ee45c6b478a}}, + {{0x00092f1d816eabc1,0x000722ec5d199636,0x000d057ce2867339,0x000d5e74d26433eb,0x0000e5c102c41805}, {0x000cee82359f79ac,0x0007e6aa805964ea,0x000dc458eb929320,0x00072db27bd3f9bb,0x0000da2bf8fef359}}, + {{0x0002a01a0a8db27a,0x000a64fac978817d,0x00003993bedf7365,0x000f0423b74a2535,0x0000333bccf9f3ef}, {0x00020cdf3fdfc059,0x00040b069a38f55f,0x000d5dce6c8fed38,0x0006a5e2563db264,0x000065193986cacc}}, + {{0x0008add2e2366c41,0x0007d5b50c4b1c42,0x000492b8899d7804,0x0004015c2e9b786c,0x0000f1dfde4b6b08}, {0x000d8bfe14c5f775,0x000829260c708e76,0x0005519b1411e966,0x000b9c856fae8b5d,0x000022c66ad8a1ce}}, + {{0x000b24afec4eb474,0x0009ba269084ce0e,0x000929f95b4dc777,0x000103abb56c569f,0x000039c57b19bb9e}, {0x0009031d0f495421,0x000062aa769f5f16,0x0007f07c0d92f631,0x000de2bef7db92f6,0x0000309aec890e63}}, + {{0x000cd3221ad58754,0x0002a8fe3bfffc16,0x0007b21f1823e90d,0x000f9fd19412d4c9,0x00004e8e63528a95}, {0x000e5d23d1dae12b,0x000a643cacc7fff1,0x000061101366f4ce,0x0007da91960c70f9,0x0000b2e33c5a3b2c}}, + {{0x0000f0bc9de883e4,0x000832bc530773e8,0x000d6df7a905063c,0x000a3c143b5a28fe,0x0000e8befcc34662}, {0x0007800fa2c481ae,0x0000406435301c79,0x000f58b02d2a187a,0x00023349b0fc5eaf,0x000039152a95f548}}, + {{0x000eef8fa126aaf1,0x00086d7f5322c9ce,0x000e1277f0f736ba,0x00079b9f64d938c5,0x00003a4c8e990669}, {0x000b0604ed199f47,0x000bb8abe33c1b87,0x0009c5ec77b8ec2a,0x00068db6e60ca7ff,0x0000e2cbee08542a}}, + {{0x00097c18666cd322,0x00082e95d7c8b9ef,0x00093771f688714b,0x00001533c086020f,0x000059d210c8cad6}, {0x000146ca0174b83e,0x00073cf08052cb68,0x0003514a6f0317c9,0x000ee2740ce05a48,0x0000abd0c44aba33}}, + {{0x0007d09b4e2c6759,0x00045d92c0b09bb7,0x0009f5fadb7aa0a8,0x0006eb2aa8468c02,0x0000370e2b02e3bd}, {0x00010c5a05206771,0x0008d7564df22bf1,0x000eb5eadfc154a9,0x00080f2066bbcc22,0x00004986aca010b1}}, + {{0x000304ad640228e4,0x000ac74a48b12e47,0x000d9f11db8146e2,0x0005ae640f64bb3f,0x0000acaf40843993}, {0x000ef32dfa787e99,0x000d6ba59fa31a9d,0x0002fd7827169dbc,0x0007a251119b89c6,0x0000bb57c8e0e96e}}, + {{0x000a64d08043f76e,0x000da608af1ec1fc,0x0006d54e3eb16ab7,0x000343e63bacf520,0x0000468f9a504a0b}, {0x0005095ccc8689fe,0x000dbfc0d9ad075a,0x0007a7114b6bd402,0x0007cde5f2d4add3,0x0000ebcb63ead038}}, + {{0x000f2b16e394b9b4,0x00089a6e75339f88,0x0008cab78c7f95ab,0x000401234f291dc7,0x0000822d72a3dc49}, {0x000c53f4bd8392a2,0x0002d49a448fe0fe,0x000a59bac7adae0d,0x00085a96b5bb8fca,0x0000dd8cc17c987b}}, + {{0x0007f9fe72d2861b,0x000fbe6490d8b0f2,0x000f57650932916c,0x0009a9e1d65e06ec,0x0000368b49073e56}, {0x0000a09ec18478ba,0x000abce485c1be25,0x0009c2fd23e9d0cb,0x00070b0b05a40e0a,0x0000c0ac2a141ed4}}, + {{0x000b7f57b5a811f1,0x00003a332880bf5a,0x000f6ed2c331b72a,0x000c931b13881ef1,0x0000c494779169fb}, {0x000ff8589c026ea0,0x0007bf5b9f354528,0x0006516d66583a3c,0x000f0465c5c1aa93,0x0000533827189b9f}}, + {{0x0005d47b7457ae62,0x000e4dc51a1c0b6e,0x000a10b057309d30,0x000b80ea82422056,0x00006b7b1f3b4fd2}, {0x0008248dfe28471d,0x000da74653e6332f,0x000c48220afb600a,0x0002c84e00411034,0x00009c3060c6f37c}}, + {{0x0005a2209fb690bc,0x0001a6a994eb0794,0x00095af9bd66e6b6,0x000d3705c195b4b5,0x000080dddd3881f8}, {0x000d168d5bdbac0a,0x0004b0d2f72778b2,0x000fe8afb40cf8e5,0x0002a796b74d05e5,0x0000b591f243ce3f}}, + {{0x00024db163540742,0x000b30cc20fd6460,0x00051c51aa345835,0x0005a09a17bb71d1,0x0000277fb5139649}, {0x000d2c2542771796,0x0004d1f708634ac1,0x000d7e0ba72c1b8a,0x000e347e4f17f54b,0x00005fbc77bc2e9a}}, + {{0x000e083726268248,0x0003e07229767fec,0x00046e11f43b98b1,0x000a62eb12d4a2ea,0x00004a6f742ff8c1}, {0x000d16b330001ec8,0x0003aebe7cce5d32,0x000632924719bb7c,0x00039e6ff7ca5c15,0x0000f3e8d249e5fe}}, +}, +{ +/* digit=15 [{1,2,3,..,}]*([2^105]*G) */ + {{0x000f55e0ced7400f,0x0003959d5ee8a6a9,0x000d3d46dd0617bd,0x000c3976364d4eee,0x00005d6544ad3ddd}, {0x0007dfe795845bb1,0x00083b8c79468842,0x000dc535a3e15078,0x000da895f764d5c3,0x0000ff1d2743a1cf}}, + {{0x0003913423373fef,0x00099abec687f2cd,0x000c07192b34ea8e,0x0003509d102ac466,0x0000f4fa4a09c2d6}, {0x000f87ba71f45a5c,0x0001a2d1230874fd,0x000228058781f14e,0x000e8a4b4499f2d0,0x0000de5d3cffbca3}}, + {{0x0002e2e7392ec41e,0x000f0600583807b9,0x00044309ceb93a1b,0x0001bd4299d5f2dc,0x0000d341d792fd4f}, {0x000f7da2004fe859,0x000e680815368116,0x0000f675be924d2d,0x00063913a6fbfc35,0x00005c62b2743092}}, + {{0x0008a0d964e634ff,0x00016c532fb1c163,0x0001f4d76384f515,0x000adb344233bc23,0x000006bf9a0792cb}, {0x0007491415365c1b,0x000c3dd1431327e5,0x00020f4fe2b3068d,0x00070d4734ccd16b,0x000095b95b5bf075}}, + {{0x000761a38bb70b8b,0x0002166f263692b7,0x000d87e0b6acdec9,0x000d4767e1fd967e,0x0000224a8eaf9729}, {0x000363860e37a986,0x0008c4b2e8807f28,0x0004c4d7e510f286,0x000ce1a869283ca4,0x0000c3368915a32c}}, + {{0x000ff0d6cc67c43e,0x0004588de301c896,0x000096bf10683593,0x0005e94798800c86,0x00006f62ea26dac2}, {0x000a1e2efe6138ff,0x0008a3848069990f,0x000443db897dd7cb,0x00054d1aac07ca40,0x0000b2c088eca6ed}}, + {{0x000757ff5dacb5df,0x0003409dfa108aaf,0x000d1d3c5b1d8fa4,0x00021c63739d04cd,0x000002d31bfad6af}, {0x000e35f347dbf5cd,0x0006989679f1e20e,0x000e1a052e17f4f1,0x0005c7e7fe010b19,0x0000b14dd7d01c8e}}, + {{0x0007e840f9e4040a,0x0000a26798b65abf,0x000aa3d54ac179a9,0x000acbb1e5e42083,0x0000903524ea794a}, {0x00076ce040ccabc9,0x000befaca5bfabb7,0x000925f5fab22e60,0x000bb22783ab4b8b,0x00005d8af2205673}}, + {{0x000f399058b20522,0x0000dd5d61d0c0af,0x0002ded111c639bc,0x000df9d3a3f3688f,0x0000b2d2d7fb44a6}, {0x000af40a6c2a4094,0x000fe11fdb14a199,0x000a1ab6062e9058,0x0007ef709be94066,0x0000fa64f9da0087}}, + {{0x000b4a8964e772ad,0x000159d89cc553ab,0x000c8bf365c823e9,0x000a41337be0bf3d,0x000033f0eb462664}, {0x0008667a8e33616b,0x000bb9985acdac62,0x0003608bdf3a9d74,0x0005f0bcd80283fd,0x0000986dd5d601fa}}, + {{0x0009de4efcc85c15,0x00096f139013d950,0x00057dacdd1eab4d,0x0006ecb65bd6678a,0x000055db869cf233}, {0x0001dd30ad5ab142,0x000ee6314b871bd5,0x00033a0d66fdc7ae,0x0005777e6357c61e,0x000026c5eda33aa4}}, + {{0x0006dc5456e8775c,0x00046e911188ec30,0x00090025c7708950,0x000a20b40e8e0032,0x0000e507b2640d0c}, {0x000d535e705092a7,0x0006166bd3b5bcb5,0x0004cd250c59127e,0x0005550d02d21554,0x0000e39d008a8c05}}, + {{0x000a050a62fa45aa,0x000e1007a06593d1,0x000091014c6dbd3d,0x0004f5b6d0706a49,0x0000f6d6e35f5c39}, {0x0003b19cd3f850d4,0x000b5e7d85a52f32,0x0009e78ab4f434d5,0x000e32db2b9c0723,0x0000b10cf992d5a3}}, + {{0x000f592e7efa4378,0x0000fd0f0290dce3,0x000a14ca9b7d8b33,0x00085bdcf8aefff1,0x00004f13e355b1ab}, {0x00008a0f61a817bf,0x0009c5549bdd0f62,0x0009a0730387141b,0x000a93fd602598a9,0x0000cd8cdef9e264}}, + {{0x00004ae9a503381f,0x000a859248c8366d,0x000f3a32b04731ef,0x00078d74accfc96a,0x000061c0b6905f8e}, {0x0000ebd5f59d1b15,0x000331d6846375ff,0x00082480114edc5a,0x00058cfd89817663,0x00006f41ecdeb28a}}, + {{0x000aba7b5341a587,0x000bbbdbc220d5f2,0x00002e2f859f0298,0x000c85b9d62c9cff,0x00004cb6beaa83a0}, {0x0009ed02cf8d6bf1,0x0009bdb17547e9ad,0x0003397b4afb4753,0x00091a79f573a86a,0x0000919e0860dce7}}, + {{0x000d88918e2f47d3,0x000f6264e8e698b4,0x00076fd1ccd75cde,0x000411bc9ae6e276,0x0000d08e3e91b76a}, {0x0004a951353f00ca,0x000e856c3a8b5bcc,0x000143eb164cf5f9,0x000249e23f45b2a5,0x000001ab36c56983}}, + {{0x00042bf7db15975d,0x0005d84f2911ff78,0x000a7eef9c1ef2df,0x0009ce3c9dcfc71d,0x0000f79ee6983307}, {0x000ec3041bc41cb1,0x0004a53e33bf1432,0x0004e1053cb62983,0x0003a7aa20e23f98,0x0000b8294d01f0c0}}, + {{0x00048d0372d37ea5,0x0007626c450c99bb,0x0008f91caa38c50f,0x000b126bffd090f3,0x0000f3229a1aac39}, {0x000fd864b7a8296a,0x00036564a892a1ff,0x000a8d75bf858c5d,0x000d9ad955b9a736,0x0000da662d7fc17a}}, + {{0x0006ba795e751920,0x000846f147608e81,0x000ad1441e7d892d,0x00005e448a0cfc30,0x00005a4d96d983e1}, {0x00004229da172130,0x000ea801e09a0949,0x000fe63f9fc0e627,0x0001c8d681971a10,0x00004012304767fd}}, + {{0x000a19b17530f16f,0x00043fcb789432ba,0x0001dd7acbc549a0,0x0002eb708cbe384a,0x00006369e0348ead}, {0x000a6090c1b89596,0x0001c1598ed95616,0x000f9fbf0c2ef829,0x000f07a5a10b751f,0x000083266ab6634f}}, + {{0x00006753208ff59b,0x00024fc44d274298,0x000b8da4cc5e633c,0x0001eedd9e76d668,0x0000984dc35fc919}, {0x000742fdc2fb0b16,0x0003f1a37ea501bc,0x000ccd5c8f47f7dc,0x0004a12079fcbe1a,0x0000d15e05379840}}, + {{0x00012f5c7b57a458,0x000171b1fea8f655,0x000933ccf5a81d61,0x000369e7fda656f5,0x0000c0ab37cf5bb4}, {0x000b16333f34c676,0x000fff92c2932e05,0x000f70718aea2f68,0x0006ad4391ab6d2d,0x0000b621d11d77e2}}, + {{0x000ee9cb342f4650,0x0009e9f60819a72c,0x000640fbba78926d,0x000eda1a2390b4ef,0x0000ca57e589451f}, {0x0008eb97ffa2d64f,0x0005596f4451997f,0x0004125bb6a63afb,0x0002c6b2bdf70c17,0x00006643535dcda9}}, + {{0x0003cdda9cd82b35,0x000509e3611c4e81,0x0003f16e05c37f8a,0x000b18efdffa6c50,0x0000bf1aed211a9c}, {0x00082a34eed8ee8a,0x0000444ef3243f53,0x000e9936c0eb0c00,0x000a9ca6ba337bc5,0x00009e6106f21806}}, + {{0x00025aa6380f2af4,0x0005491d9d165dff,0x0008eb846ca78f20,0x0003a9f6e0d46b69,0x0000928b01e0eb89}, {0x0000f19d4744bdd2,0x0007232b1a35b4a7,0x000fcfede71fc522,0x000c5bdc58c9372c,0x00001f4e89d71396}}, + {{0x000b414c8ec0e785,0x000a1033d145c6c2,0x000e07a15d9a7bd5,0x0008686748b7db2f,0x000064f63f44f8f7}, {0x0007c5bd8808eb44,0x0009724642e6865c,0x00059e076e717c8b,0x0002161fb2086420,0x000012f7226e4689}}, + {{0x000812cbca321347,0x000e632740ba2570,0x0001db927a9e88dc,0x00052b0aba4374ba,0x000031227b96461e}, {0x000cd5dc06746bbe,0x0000cf772208a93f,0x00002a73b5a86ada,0x0008c08bbb02ac6e,0x0000f0196a56dc06}}, + {{0x000d114588509806,0x000fb66505d56d8e,0x0005d67e3ade8c1e,0x000119098b390daf,0x000036106afbab3f}, {0x00018cd4db085aa0,0x00060de60f8f3920,0x0008384555865e57,0x000c8b560c8a7794,0x0000bb865e6fb6e4}}, + {{0x0009a2695dcb03be,0x00082dce5033ad58,0x0009607c5c6bfee0,0x00022ae3df25d171,0x00000969faa0ee1b}, {0x000ba9a77472ec5a,0x00093546739c439c,0x000ea5d5c7a4c0b8,0x000e1e00c8fe66ae,0x00009ce280523997}}, + {{0x0005978b851b77b5,0x000283c18a02a8b6,0x0009ba7aa0364b0a,0x000f94a6337a27cd,0x000046af7665f865}, {0x000ca9cbf97d5b16,0x0002237045beff1c,0x00083538584b0821,0x0002838dc37d07a3,0x00008db8ece96033}}, + {{0x000c181d162aea79,0x000e82e60793d69b,0x0007258aefe6f5c3,0x000ff59bc53c6eba,0x0000fb553ca68c8c}, {0x000a8ffea309a6f3,0x0000b9a56441bca8,0x000e2c97bc141056,0x0001715ae34273f8,0x0000514b5e4a2efa}}, + {{0x000c99927b057ad6,0x0006c8df3e109788,0x00042efcbb33a466,0x000e21d25a75adbb,0x0000e29ea59779da}, {0x000921fdb43a94d1,0x0000339d1820fc2c,0x000ca4ed5d01956e,0x0007bd7de58e797b,0x00001e6e6b666ea0}}, + {{0x000db2987fced620,0x0009ec446ac47b5f,0x0004a043cfcbd482,0x00041a6a0c7495f3,0x000012af53d2f54a}, {0x0006ad3c90c6bfe5,0x0009e9382b437e60,0x000b911675112180,0x0001fe21b90ecd21,0x00003c0b3c579d34}}, + {{0x00027b6e3c50668c,0x0006d6d8d96df5a4,0x000da74b2f2f21c7,0x0004a2b1e238a1ad,0x000010d7b0c82fc3}, {0x0003512ea402316a,0x000e879853dbc21c,0x000ce88096dab781,0x0007d667b34f9207,0x00004b1eb299bb04}}, + {{0x000d118c309e65a1,0x000fabfb4147a551,0x0002cb43addff781,0x00012d35f7873d69,0x000027471214c7b1}, {0x000d72dac4e3e7ed,0x0007353a272c9f63,0x00092a6b9af262dd,0x000220bf901e7534,0x00007a7efb0540e6}}, + {{0x000b0ea863d4195d,0x0005368db7c846e3,0x00005939496972ef,0x000a5e8c21297c56,0x000067666c5eaca1}, {0x00025d8b0dad395b,0x000865268b8fdc43,0x00006bcfdef1f33c,0x000a4774da449704,0x0000a1358f89d014}}, + {{0x00029a88642c8c87,0x0008c8e1555b9104,0x00039a9aba22bed1,0x000fc7e5fe7cb866,0x00000202dfe03ad7}, {0x0008d27cd6bd32a5,0x000cf32a6b477ed5,0x000dfd6a90e47d00,0x000f4011739d9316,0x000009017911ff40}}, + {{0x000b591cfe2d8435,0x000da2d587d5570f,0x000368c95c0226cf,0x00024b0fb7a4d410,0x0000747cde3537b4}, {0x000b950273cff74b,0x000e13c9336c4563,0x000c3960d19448b9,0x0005749ac83ef9fe,0x00006bda1afb9c11}}, + {{0x000fd3c13fb0e65d,0x000fa286d2d8dee1,0x000429aebef8efe9,0x000941fc4bebd474,0x0000003c2cbf1f69}, {0x000b443a5eb895a6,0x000b471ff243422f,0x000bd3be819ff465,0x0001c38b9d452cce,0x00005d9b85ed78f9}}, + {{0x000375126cded2da,0x00007e9257a8c6bc,0x000dee102a30f31b,0x0008fe55ab4546ff,0x00000dd53a3fae81}, {0x0005cbb5a649fc4a,0x000817a77abd2632,0x000e1e9abc600dd8,0x00067b95baef2e23,0x0000de3e4fb2653e}}, + {{0x000383df4f38b019,0x0004818f9a6a720b,0x0002d4e1a9ca0f4f,0x00035b6d14a33e46,0x000044289f623629}, {0x00007a387d0c040d,0x000b1fa4bbe11901,0x000d31de4afc1507,0x000d61847236f98d,0x000092524f93ecbb}}, + {{0x000133e59049afec,0x0005726f65d7ad5c,0x000c20ba29b6689a,0x000fe847a4377af2,0x00000527d1b09af8}, {0x00040fab9f632b99,0x000399c6fd2087c9,0x000492e8aa07a977,0x0006bb6bf24157f1,0x0000127f701cf38b}}, + {{0x000a5446b8fad411,0x00094c04141b6e5b,0x0000c0c227c20ebf,0x000d5a04ab83fce1,0x0000bcb816fe010c}, {0x0003b1f39b167b8b,0x000508ecf57d0da8,0x000f43aa56b9dd56,0x00056a8cd6338fd7,0x0000bbded8d9e446}}, + {{0x0007cc07c0803c55,0x000f213fe5473232,0x000a3cfe69566daf,0x000b4b379c15809b,0x00005eb247e4e96e}, {0x0008c0ee69a81c78,0x000ca494920f6e7f,0x0000bf99b798df73,0x000a22034f1f6531,0x000097e6aeccea96}}, + {{0x000a954927e7800d,0x000a826d0a072de2,0x000d54515c3845d4,0x0009d7df7dea11cb,0x0000bd898c3c179c}, {0x0002dadc7f97ca3e,0x000c0dc928e98ba2,0x00044da48b29b42f,0x000aa74a564df536,0x0000634de334dbe8}}, + {{0x000fefbdd58c6c26,0x000505d10919ecdd,0x00022059482fdceb,0x000567341aff5332,0x0000c224f55a4389}, {0x000cb2becafcf4b7,0x00068c9356cee825,0x0005bf8155b2741c,0x00073337ed23e3fa,0x0000db5fb517c0d7}}, + {{0x000bd96248ab8040,0x0009230d301d5d87,0x00070e14ad7011c1,0x0003d21ef8438468,0x00006554bc48fe6a}, {0x00060d553e3bc93d,0x000d4998ea4a6e08,0x0008cdd7522b6e14,0x00008239e466a48c,0x0000715f93d875c7}}, + {{0x000ebb47ef45b374,0x0007b2b58c3731da,0x000e00a0e3d0dc78,0x000bc2a199fdb8b8,0x0000bfed2128b73b}, {0x000e635d70a51a82,0x000ba44f2975b044,0x000dad6e7aecd152,0x000a50eeccc149a8,0x0000aa60be904d47}}, + {{0x00057e2a9da811f5,0x000d8f3097464c41,0x000484e775d2c457,0x000cd6e150802622,0x0000d436e5ccb8e0}, {0x000b7da9c87674cf,0x000a0e9207076833,0x000861876e15b63c,0x0000a8cf27564749,0x00003acadb457197}}, + {{0x000409f6aa3e6037,0x000e9cd0f03103a4,0x0003670a08cb8a11,0x00029d97e7af5af4,0x000033d7696897ea}, {0x000513f584bf83dc,0x00003556fed046f4,0x000673b14b6edf6d,0x00085fcef8b7c83a,0x0000b1cd839a4b63}}, + {{0x000185d2c4242479,0x00097a295f96baea,0x000a2a8c7280ed03,0x0007ef7fc1f8550a,0x0000d696d88afdda}, {0x000ad885a9e3c7bd,0x000370ee8f9c98dd,0x000bda7835528be5,0x0009132edb484473,0x000039c54d3c3c08}}, + {{0x000279ed119371f3,0x00001fce787efaaf,0x000c87c24f135eb6,0x0009d979f366c07b,0x000041ca760045fc}, {0x000acb26b190eed1,0x000fcaffe42e29c7,0x000d6d3ab87c3da8,0x0008c050fea0c3b1,0x0000f921a3b9c2b3}}, + {{0x00019080b28583c8,0x00084271f1c9cd2f,0x000d88b4d5344abf,0x0006e6a1fa410880,0x00009780cad6113a}, {0x0008fccf32dc4852,0x000c09cdb1201d95,0x0009f592a499a670,0x00020202a5504704,0x0000b368bdb51e7b}}, + {{0x000bf0d270faaadb,0x000e467299302de8,0x000d5b29c9761e25,0x00038c9a2a3ca3e2,0x0000cc9ce0564bca}, {0x000feb5640283cae,0x000933c755cd2702,0x000ab454778cdcf5,0x0000f1802df412fa,0x0000a3fa943ac400}}, + {{0x000b9788e6e633fd,0x000544369ee142c4,0x00015ff93aad8109,0x000247c388415df8,0x0000bda8886b6aad}, {0x0001ae09bbfc6389,0x0003224a5c85ae86,0x000c8b0d806937c2,0x00033767015db086,0x00001093bc829ba2}}, + {{0x0006738d95956325,0x0006c14fe2f45374,0x000738d03b49c9e4,0x000f4f514a895f38,0x00004126445d21c6}, {0x0001bdd19accfc3f,0x000c75923b83aa21,0x000d4420ccc62233,0x0008570259ea62dc,0x0000ac5e9fd95e6a}}, + {{0x000f02f1e3020f7e,0x000abf391444e199,0x000d33d014595d4d,0x000243d1b275d094,0x00009fe416192225}, {0x000927e9313cc8ae,0x00007cbfad2bd631,0x0007d6f47c38a96a,0x000212ca8293dcf8,0x00009e934e1b8edc}}, + {{0x0007e895fac16188,0x000c48ddace03666,0x000ea05367de0677,0x000beff7720f6b94,0x0000f0cfc3ab04dc}, {0x000ffaae7332b4aa,0x000376aed4df1fee,0x000d7d9139fe5560,0x000cec33e0ed75b6,0x0000b793cbe3ee57}}, + {{0x00004d1db2df89a2,0x000fe1bb790eea99,0x0002e037ee87f71a,0x0001a43ef529bd8a,0x00003f57ccee309a}, {0x000e652d001535bf,0x000531e580c75add,0x000537db16a02484,0x00016ec744e0c9ec,0x000031da47f5dbff}}, + {{0x0004c7e6c2a25fa1,0x000d2f543aa6ac56,0x00040245d6d44b13,0x000d4cfd0af04138,0x00008a3e6f94f447}, {0x00053a1887a0b642,0x0004e78ebfe0b50a,0x000560e378ad1f19,0x000ddca374718976,0x000076c2fad52831}}, + {{0x00033c240fe437af,0x0004155b36bc99b8,0x0001d74ac6678611,0x000a5b24b825c503,0x0000dc5a9fb55609}, {0x000f6da55d8b0a12,0x00077b276db4ac76,0x0008fc93aacf912a,0x0005dd0cd8b799c4,0x000026948bba026c}}, + {{0x000e5dc6a8543fd2,0x000c1dd380d7e3a3,0x000f3ef8413c4a39,0x0001dfdffc537730,0x00006f878d18b4d0}, {0x00050e41bd35c986,0x000f502371f32ab5,0x000f1a88844ef8ee,0x00013ba15e21b99a,0x000064aa063b9517}}, + {{0x0000dc7a8ef6fb13,0x00029eb3893a9f55,0x000be61b7ffb9975,0x00084bb486f2c400,0x00007200d4bf41dd}, {0x000b00036c8f5e50,0x000f666addc17762,0x000741de8eaa75d7,0x0006e2beadda312e,0x00000cf20707c3ce}}, +}, +{ +/* digit=16 [{1,2,3,..,}]*([2^112]*G) */ + {{0x000263e88928ae78,0x0005b4e82be78b48,0x000573a10668411d,0x0006003ba7a1e67f,0x000055ce3d847374}, {0x0003d7e7e0444965,0x0003b5779daedf79,0x0006fec0025603ce,0x0005537019312576,0x000058c17835ab3a}}, + {{0x000f3801bf458e27,0x000267db440dcbaa,0x0009ae263c36f812,0x0007e4c9536223b8,0x0000a3cc7df0233d}, {0x000b1cd94cbeb372,0x00039f4807f8b9d0,0x000c597324185b52,0x000edcac170724de,0x0000d2110bf132b7}}, + {{0x0006829bfc72b079,0x0001d7df36f44abc,0x00071f67bd4d4b36,0x000dfe954c4d7c53,0x0000ce1626d4ce63}, {0x0001b137ff8ce06d,0x00074664f8dd7874,0x000300b6012fe268,0x000838c0a9ba2942,0x0000ccd61cd61418}}, + {{0x000561feaf4022a9,0x00054750df9b560d,0x0009e8873c0034a5,0x000babe5354bb528,0x00001434cb13b39b}, {0x000661885c701bf4,0x000024ea8f5c6d71,0x00087a94fb5f8163,0x0001f69289cb22b9,0x0000fc615e56fb16}}, + {{0x000183c12ef9b892,0x000bca4be6ce2dbc,0x00034f0eb5247e9b,0x0009319bfc5e8667,0x0000d7c61ce40520}, {0x000391e7aecc2dc4,0x000502b7dbd4b402,0x000c8e5c4c4cfbd9,0x0009e83613bcab0b,0x0000346c5d1041e3}}, + {{0x00061fe951496001,0x000940d172cbd2f2,0x0007178c0c43ab46,0x000faf9dccdec82f,0x0000adca0a729af1}, {0x000d70cf6f648cdd,0x00020f732870a2e6,0x000edafaf9b5c25d,0x000106ce0db1e405,0x0000d951a4245711}}, + {{0x00083ffb1021d71b,0x0002312ad996176a,0x000fe8f4b2e72ec8,0x000a2d26d3a1eb2f,0x0000d0da0974fbb1}, {0x0007b253b22acbc9,0x0008e75e121ea26e,0x0001d0d96ac731e4,0x0002d71a94473e82,0x00001f7b3a36202f}}, + {{0x00038deafeaad237,0x000df374aa4943cb,0x00049341a28d1f25,0x000da0001e16e457,0x00005d5a690e8563}, {0x00039cc322cd1a1e,0x0000e69f3d0f0287,0x0001f380debb0624,0x000965b31a6ca354,0x0000e9cbcd994718}}, + {{0x000c6922682f05da,0x00017d91dac21c30,0x000d9a935d39a514,0x0001318bfcdaa873,0x000086e4fe5534c0}, {0x000794e1a75fbff5,0x000536f457094f58,0x00038cd634ba889d,0x000e8fdf2b2976a5,0x00008ca32ea075ce}}, + {{0x000d5a656febc1de,0x0001902e98f903df,0x000f488a40aafbb9,0x0000728ee7bae61c,0x00004af95a5c8955}, {0x000e37e156e3a046,0x0004accd7ad577a5,0x000b8bf99c4f1997,0x000c3dc8efc06d64,0x00009535e542d847}}, + {{0x000c071894059e33,0x000e16afeee5055d,0x000d7c4e58da0f59,0x000f92484480872e,0x0000d26d813b9d7f}, {0x000db103b383d063,0x0003a77d69385adf,0x000f5cdf0dbbbe77,0x00044de79f617d94,0x000045aa4efb1858}}, + {{0x00024757beec731d,0x000827d28fdb9e94,0x000c2342a93d6395,0x000aa543b7350b9d,0x00003ff4ae312e55}, {0x0007f066a93f5d0f,0x000b7bb2a8d24025,0x0004453ce9313341,0x00018ac52053dcf8,0x000034eb883f74c1}}, + {{0x000eaef662e4d0d3,0x000059a256134cb7,0x00039f0720131fce,0x000403b640ec2ad1,0x0000bf5af241564f}, {0x000e90b3a2dc95fd,0x00011936e70af541,0x000cb4d905df5c12,0x000eec1d816ac3c6,0x0000f7bdb6871a08}}, + {{0x000a5314edacbf64,0x000cea476e8d2cbb,0x000329c989b5d217,0x00006210a624d6bd,0x0000117009f54cea}, {0x000f3c08ecd2255b,0x00003a9d114b6cd3,0x000eb5279e0c672a,0x000350f0cf81ab63,0x00007bd811141a39}}, + {{0x000e5ad10c0f9e13,0x000ca384048e1e66,0x0002e8128b54f642,0x0003a4179217c0e0,0x00007023624a2bbf}, {0x000303ed950a4a7b,0x000f2ab587314f2f,0x000579025c85df88,0x000da0e847c3dd28,0x0000ad36a42e0005}}, + {{0x000f3942e984ec00,0x00069b01d25ffd3e,0x00052e58aeb37752,0x000648244408f942,0x000050a44776d1a5}, {0x000a111b2f83e4d2,0x000a55031541fd7c,0x00010e5caab3d571,0x0008ea6a31cb7862,0x00004f23739f63cb}}, + {{0x00034d5aa351e7fa,0x000767b6bdceee2f,0x000c32c404785e1e,0x0005856ee43745dd,0x00009ac4c31ca9a2}, {0x000d00120efac828,0x000cbe4c18a7102f,0x000f056f5a74ffbe,0x000556b56adf5d31,0x000034b8508f4fca}}, + {{0x00072bd8e4e38d94,0x00066bc1a50e3f67,0x000eccca9fcbfd5d,0x000094357266d3bf,0x00005d1ab86354c8}, {0x000e84f97431deeb,0x000b71de91ac3fca,0x000c099c7cfa4e84,0x000438463acc3dc9,0x00005a3b751b8423}}, + {{0x000ae45e109ee44a,0x000869005ea9c422,0x0008dc7eefa037b1,0x0007cb207cd5ca5c,0x000002e590572ee6}, {0x000d6f711e0c867a,0x000b67004688c5c8,0x000ac0175a217761,0x000d346dca0af57f,0x0000834eafd30443}}, + {{0x000031a244eb62a0,0x0006e2bc5ae2ffe1,0x000da78702a1ecdb,0x0007d86a6091a100,0x0000efb1036654d2}, {0x00050d8f92e2f743,0x000f3b2dd2ae5d9c,0x00085081efcb5469,0x0009bb2381877fc6,0x0000a09d4c8315e0}}, + {{0x000d2bc606eecd87,0x000ce811461f32c0,0x000d2a5d24c90b85,0x000778f04514b56d,0x00009c7f1fec2e61}, {0x000670973b59d05b,0x0009bb1567fe8aea,0x0008152ae455eabf,0x00049b39a03b8257,0x000076e8321067c3}}, + {{0x000293372ff91a46,0x0006b775c576ea7b,0x000a3cde27e9c747,0x000bf429095d14f4,0x0000218f90c2db67}, {0x0008acca306563ab,0x00024d4b59a65276,0x000cf8c68ef2c300,0x0008a593a9f027a1,0x0000fb08f6575918}}, + {{0x00001bb71891edaf,0x00064a5d6ffe31b4,0x0002b148e3202aca,0x000672cd924679ac,0x0000f9aae98a214e}, {0x0005dab10356c4c1,0x000a2de53c8e3a1a,0x000fe283ee091971,0x000d484dfedf9266,0x0000a8b4a0624aae}}, + {{0x000cafe59e1c69e4,0x000ec2f66c9b2eab,0x0004aa0e4ce53351,0x0005f826078a7569,0x0000640f3228ba1a}, {0x000925c496579dc0,0x00038c97b76be7ee,0x00049904eb6310b9,0x000d1abde130dd9e,0x00007e9c5c47ec9a}}, + {{0x000747bf4a461c92,0x000604cac505b161,0x00039e37325036a3,0x000e3d40936c8564,0x0000d8a870eb02c7}, {0x000b9d2f973fb7f5,0x000c1a615f5d3397,0x000a0a4c943f3401,0x0002887b120a3cc0,0x0000f101a1ac6662}}, + {{0x0004a3d4fee19353,0x00015d011130b451,0x0005ac2c73b7caa8,0x000becf5b0c09c90,0x00003f82f1440fe4}, {0x000b4ab74f14c961,0x000bba7943306bd1,0x000b78631291e728,0x0009cb5c97bf6fe9,0x00001c908352f56f}}, + {{0x000a431a92b58b20,0x000f68a51d86d62b,0x000861d00fcae533,0x0000dd371413a4a8,0x0000cf49037f8657}, {0x000eaf4c3d1f3eb4,0x000521e2f9631faf,0x000851b77e971282,0x000ea6acb91a72c4,0x0000206da3cce7c9}}, + {{0x000d754a64d62c61,0x000ee0355ea5a1a9,0x000e8ba7266cd17c,0x000a54959bf91b62,0x000070bfd9a18d33}, {0x0008a1b0be98472a,0x00030fe418fb02b7,0x00052676e46d3013,0x0006d3b58f556cbb,0x000078fb2237e0f1}}, + {{0x0008653a9f8bb2b0,0x000e96befa270587,0x0006dad18832ede3,0x00068e53b0c689cc,0x0000db79f085c9af}, {0x0001c7d93d122b99,0x000db352a7a11671,0x000c8f1e726becff,0x0001d858067471da,0x00007d1cc378fead}}, + {{0x0007f002486685af,0x000e214080b0257d,0x000cb1b8970c4633,0x000a75ed72c06edc,0x0000da0218c79771}, {0x000f32f5200f7c7b,0x0003a69a8df75540,0x000d5f6e2ddffd2b,0x000fe2ec9a3ffb8f,0x00007df766b5d4e0}}, + {{0x0004d27b3dd34f56,0x0007de6fca2c5512,0x000787744861e22c,0x00006ce2f3d6847d,0x00001ec88437590b}, {0x000c281f52950ec0,0x0007bd6b5c7cab50,0x0003c2642b1c400e,0x0003890397e8e47e,0x0000cf7d2df12202}}, + {{0x0003266882874e03,0x000a89e81d0194cc,0x000549a334f700e7,0x000ebbbe4d500db4,0x0000433030eb4bf5}, {0x000d4c6fbdcd9292,0x000d720ac8474589,0x0001ef26b9eb5ed5,0x000acee19219c5ec,0x000001a7fc35fdee}}, + {{0x000f286f78c7ae3f,0x0000f6fe1ca839e0,0x0005678a2b39fbed,0x000a8e7ba6e825c9,0x00007d7bcb5335db}, {0x00060809ff657696,0x00043fe88e0ad6ff,0x000de58633c659b1,0x000251056cdae14b,0x0000b0b64689f024}}, + {{0x00008e21178a099f,0x0009afd88898f531,0x0006270b71af681a,0x000926359a6e55cd,0x0000e1e802206d9d}, {0x0000c10a39d0de19,0x00011dfc0b3fc87e,0x00058de46f676bbf,0x000ebc32f304138e,0x0000fd44af065751}}, + {{0x000837bfd2c4dafe,0x000f55cb3e99d194,0x000e83b433ea9169,0x000d019bf4f952b7,0x00005a04c25b21a2}, {0x000bf1e7dcbb4739,0x000c3be7dffaeeaf,0x000b4829d1ec04ec,0x000909474be22c14,0x00007e4c57a57cd7}}, + {{0x00061cc613abb95e,0x000cb58aa468c130,0x0000103c600933a2,0x000a98fc90deaeda,0x0000ce472cea4bfd}, {0x000ffac971727969,0x000fb1241fe002c2,0x00094fc710ac9f69,0x000df476c5db7755,0x00008ee99ab46283}}, + {{0x000da7a9e6fa679a,0x00050244f9571a74,0x0002bfdb99609f5f,0x000a0ca351106f8b,0x0000726ad35b71e8}, {0x0001399059b1506c,0x000d5f4c5d58d7c0,0x0004e983e0eec7d9,0x00024d47eab45931,0x000073b2a5db146b}}, + {{0x00053cd8ac3fd6e5,0x000911ae915c1c68,0x00035e452713cfe5,0x000bf9b5b88ed861,0x0000768dd4358000}, {0x00055d4bf4bc4280,0x000cfe3ceae694b1,0x00039860a90b33a4,0x00044533c50782b7,0x0000e0258fbe654f}}, + {{0x000483703eb7f60b,0x0007d6d369a806b8,0x00012af7a09ec39b,0x00037d6f136e5aac,0x0000dd8a6565513c}, {0x000255d417353feb,0x0007cebf91f97a59,0x000d5caba59e9564,0x00024a85f33bf2bd,0x0000a4be8c2c5c77}}, + {{0x000796c75120b49d,0x0008a90e9b928b9a,0x0008f95c1622af0a,0x000ede13d8b3fc2c,0x00003c265423eb9e}, {0x000ebc9a15bd7812,0x000ae6b2d10435bf,0x00011101cea171ae,0x000e63bfb9273095,0x00006dd7cd57f8d1}}, + {{0x000198e5d68cb6c0,0x000c190df284c844,0x0007e36c27d05eea,0x000e6fa431aa9dc0,0x00003b61254ff61e}, {0x0001a8e2b8663dba,0x000587bc144f1d1f,0x0005a87f2ae85cbf,0x0000fb374e6f7b1b,0x00008c121dbc747f}}, + {{0x0004c7bb9087d92a,0x0007c0e6a9bc8960,0x000c69ec2a7a547c,0x000ec22623c94a7a,0x0000525b055cda91}, {0x000b110ac44d3bf8,0x000f1422b1652063,0x000642f08b288324,0x000c8d48a8d2d517,0x000012612181f2e2}}, + {{0x0008cc568e4c47a0,0x00034c3e8a1d2cf8,0x000b8406ce8cac5c,0x00032c23bc082944,0x0000bb19f797a36a}, {0x000f360a586e48de,0x0006e44743247522,0x000e06255c5208aa,0x0004e8f858612ae7,0x0000b4ea39d737ef}}, + {{0x000bc460db94e995,0x00005080649d163b,0x00096d07ee0617ef,0x00093fde45ac2df3,0x00009614177e10ff}, {0x000dbd16ee571c89,0x000a36b028cc1b9b,0x0003821897ca0e3d,0x0005b2397d51cfd3,0x00005ff63bbd9c6e}}, + {{0x000776420861ada2,0x0005c1493e967a64,0x000d92b3fba264b6,0x00026a2e174e2760,0x00001c08d1309e77}, {0x0003add07c55bcbf,0x000e21a28772cc02,0x0006ed92bc89eea5,0x0002ab9f631e159e,0x0000237c626df26a}}, + {{0x000eb0be483e60b1,0x0008a8144da94b61,0x0007e3c9442ec74a,0x0008d5659b08da90,0x00003a62569751ae}, {0x000a60e8fe99eac3,0x000c83f07f5cddae,0x000b6a2c4f4d939e,0x000c3686516e4f8f,0x0000ce14006ae498}}, + {{0x0008be5037f0aef1,0x000400d9612b3b49,0x00000f5494e4a5f1,0x0004b350178c1bec,0x00002194ca390f0b}, {0x000371e991e9b508,0x00066f5513d3e57d,0x000bfed44a8a1cd6,0x000d0caaae2503dd,0x0000e2217e3ec2d1}}, + {{0x000de10dc8a838bc,0x000cb4db84f09e5f,0x000fc31b998d83b9,0x000d314cdae49c2c,0x0000e17fbf4482ca}, {0x0003d5685bc44cd4,0x00011b173b41f973,0x000b6c609b97d020,0x000fa8129cec8ae7,0x00008eb425aa9285}}, + {{0x0000d499bbee7027,0x000794e7726f36ed,0x000f7e50f1106588,0x000372016e8a20bb,0x00007cad5d314d87}, {0x000dd1a9c4d420b0,0x0002e0853dfe07df,0x000883f4657bcb1d,0x000e264db07a30b7,0x0000d54953a43577}}, + {{0x000b7bac5d80fad0,0x00044b2255967200,0x0006673244b80849,0x000399b432f19ed6,0x00007a899f7c61f9}, {0x000ec5ef6da900c1,0x000f95e8e63010d3,0x000ee7310e72fe29,0x0002467c0da3b206,0x0000d1381a884ad6}}, + {{0x000647f72ba142a2,0x000510a8a8617f04,0x0008c5b890377f95,0x0000384970fca731,0x00001b0e8d4dc56f}, {0x00069cdcd6ed4bd9,0x000dc638ead2b445,0x000d215fcc875e7a,0x0003c6dc06beb69a,0x00000645a027babb}}, + {{0x000b0431983cd6ed,0x00007bf2175a80d4,0x000798d7519a205d,0x000fa59086f5341d,0x00007f0d0b4ab66e}, {0x0001892cc0405eac,0x000cbf6a8145fae0,0x000fa60ef8231d5f,0x000d9bcd49a89231,0x0000ddf2a97a89fc}}, + {{0x000d2ffecb831b3c,0x0006c64be18ccf99,0x000b95a73a3566b9,0x0006ade17af67343,0x0000bb14c802d2dd}, {0x000046d9f8cb107c,0x000510d859fadfd1,0x000c8a0784b62dc2,0x000c0a6ad339c802,0x0000cd11269bffaf}}, + {{0x000468da94f038ab,0x000bb71bb5963514,0x00006cfbbfe6dae2,0x000e61154fc00490,0x0000bc8ae6a43e13}, {0x00044f06569f3f31,0x0006aa775eff10e0,0x00034b8704d0054d,0x0006b4251e6260c2,0x0000ef2a9d02c95e}}, + {{0x000ff430a65cf5cf,0x000e5b64c8a24667,0x000eac3ffcec204e,0x000777251bae8db8,0x0000c0889a098bf9}, {0x000fce13803c0161,0x000401026ff03bad,0x000f5e552f8dc21d,0x00091ae48fc57a54,0x0000609011dcbb57}}, + {{0x0002643d816f6738,0x000c3753f6e86736,0x000879b02d8cb868,0x000c7e594838c395,0x000067972ca999f1}, {0x0007d34dfd7c1088,0x0004614e333a9fad,0x00058a876d7b6624,0x000108e3cfac8612,0x000025823b4b5af0}}, + {{0x000268f6a19bb9b3,0x00070a8958a2b4db,0x000e8549f04fad60,0x000d9a69a06eac4e,0x0000d03548e51195}, {0x0004f596dcd373eb,0x00006334b296340e,0x000d58c42a009c79,0x000881171c453a68,0x00001b31a3104480}}, + {{0x000638d6478b071d,0x000d506ebaf4c8e1,0x000f38ac3c0decc2,0x000ef39e647b5165,0x0000428075e5d414}, {0x00028b3e3fe5a0cb,0x0009c6c2309c09a7,0x00009c0e65089762,0x0000d298398ccc4d,0x00001a2ece4161ce}}, + {{0x0004ed542000ffef,0x0006547c39491113,0x00093d2fae58456c,0x000070c2b32044ae,0x0000c506a795a7b1}, {0x0000510c08f5f461,0x0004b53bcfd62e25,0x00072129bad0f10f,0x000fe39c16f090ce,0x00003107a2433ad4}}, + {{0x00094ca6b8261d16,0x00015268752c1c63,0x000960928360a4b3,0x0000531849d69193,0x0000f72583b238ad}, {0x000fb502a8493e40,0x0006bd817731e757,0x000993764b0c236c,0x000d4f08682dde88,0x000027590fa24c64}}, + {{0x0004af2f50460797,0x000d37f2b0ce2a1e,0x0009a8ba740bbb10,0x0008100c3fd4bc4d,0x00002775b5aff598}, {0x000144f7f34177e8,0x000d1f57ccfb628e,0x000e818c9097dd78,0x000458b5e547accb,0x0000c02a026db11c}}, + {{0x000ce91cac08c3d1,0x0002b2736bca265d,0x00089001c395d92d,0x0000fcf505b6519e,0x00008c614d9cb52d}, {0x000ab8803efd70d8,0x0007c604446b154a,0x000619c8c4d96a6e,0x00064ae8fc9320b6,0x000068e0fb54c0f2}}, + {{0x0000cefcf4e70ec5,0x0004e2cf688d23cd,0x0008a11035bb79a6,0x00062874c5aaedce,0x000057759d2b1417}, {0x0001d559128402a1,0x00048367bea79cef,0x00096c617f84a0eb,0x0000d3fd7070c334,0x0000553c0472599b}}, + {{0x000d20f989b9e29c,0x00099deae2b2ff99,0x0005ec2b4b690d6e,0x0008df9c55072b82,0x0000bbf457111cd8}, {0x0009822f0aef2354,0x00029207a036f4ad,0x000ed9f8978a6431,0x0006e9dcb5c728b1,0x0000b9e20713e8f7}}, +}, +{ +/* digit=17 [{1,2,3,..,}]*([2^119]*G) */ + {{0x00041fa6a39c7f6a,0x0009eb5589baab08,0x000627ba2093d7e4,0x0005a1f11df73ccf,0x0000a3a9614f842b}, {0x0003036faf95407a,0x000a6b88f15492a3,0x000ef2aa8c72f6ed,0x000797929383c9bd,0x00000d4b788e861e}}, + {{0x00028e853253b32c,0x000764a3d3e50baf,0x000523564b25a2db,0x000cc7f385d655ff,0x0000d11a0255d54c}, {0x0005cc1bf209a125,0x000965f5e1df998c,0x000023464fa162cf,0x0009a40a48610028,0x0000fd3f9f50b2cb}}, + {{0x000a5228e90b176f,0x0000c1c3bcbc9702,0x0005ae8e770765a1,0x000f8b56923d8d2e,0x00008e74adba5e4c}, {0x0008ac1d36d9dbc1,0x0000bb6bcfb20110,0x000fa9d7efcf1d34,0x000aaad4625764cd,0x0000a06c7fa8fafb}}, + {{0x0006be82919499b2,0x0005b2e0e8754c2a,0x000ae54ff9e14e89,0x000853a30ef155b2,0x0000ecea0175c713}, {0x000d2365ed695a76,0x0009c344487f8ecb,0x000cbd5f7dd9d9ec,0x00093f8a2fa3c895,0x0000b4000583e162}}, + {{0x0006dfb3c80537c1,0x000928b656a8e73c,0x0001a720c007d242,0x000f0f7f2f75140d,0x0000307b44bb2faf}, {0x0001a93776043d2a,0x000131bbd300fe21,0x00012b8b0d581890,0x000bbec7aa05b0c8,0x0000c0d90f4dd862}}, + {{0x0001ca3ee253969f,0x0009e918dfe27423,0x0006aa687b67bc7c,0x000dacd55607b710,0x000066e8c14a024b}, {0x000f5d052e5ba875,0x0000afcc0c31ef9e,0x000cda3636263f60,0x000872630cbc5ef3,0x00001148ad0d4f22}}, + {{0x000777b4aa7e5304,0x0003615e1bdfba24,0x000858bacb14b766,0x000b945ec88b6fcd,0x0000bd20cb06635a}, {0x0006f5bdaadf1ec6,0x000c7d8267bddc7d,0x0008015bc00a297f,0x000366ce5cbef6fb,0x0000bef7be68218b}}, + {{0x000a98c52873cedd,0x000a4dce333a9777,0x000c49337107cb38,0x000d4e5d090eebee,0x00009c1f6657ee06}, {0x000ec426251c702c,0x000182c9b521b4df,0x00075e02a1270247,0x000e54af1cdaf2a3,0x0000dc7ffbf6f46f}}, + {{0x000522738eddba89,0x000f79659871f8b8,0x0003d82764c79ac3,0x0001c2fc21f3b82c,0x0000caedd9348e18}, {0x0001c424c016898b,0x000369f16a2211bf,0x000d0ee361012838,0x000e2f5b3b65c786,0x0000dbd3e2f44b64}}, + {{0x000ade03aff4bb02,0x0008b4529f4e17b0,0x00043bbb7fdbc450,0x000dd77af503eac2,0x00002cee72b9a511}, {0x00047cc71bb2a4b8,0x000c42f41d52bb5a,0x0003a786fb0e56c3,0x000b64068993ab40,0x00002c6197dabf9f}}, + {{0x00037d63972795aa,0x0009bbdc815efc80,0x0007ab6e71ef405c,0x000a874747c3c51e,0x0000f1d220edee78}, {0x000211ed3c96c1b7,0x0001bc179709211a,0x0000e0198510be77,0x000ea2a633d65d9e,0x0000562f78442b7d}}, + {{0x0007889df799db5f,0x000ba012c603f759,0x000ca505b101e3f2,0x0008490b743f6b4f,0x000042757e975d7c}, {0x00039e82875f4bb1,0x000f8ff53a5da9f0,0x000ec746f6aa587c,0x000474838f092ff9,0x00002758b9877567}}, + {{0x000825e7bf6ef16d,0x000e3b0e3eed4f65,0x00082804995e95a3,0x0009ac66e3d6ef1e,0x0000140e9150990d}, {0x00048379d22a5ca1,0x00006beaef803d57,0x000d94eb0997a2d9,0x0006df77b8617ffd,0x00005a68f3e15466}}, + {{0x00044939e5337133,0x000022bfa31f90af,0x0003a6b0a68785ce,0x000614dc6b2e1ac3,0x00004b2ee53c3f17}, {0x0009ceacff767259,0x000500352afe92bc,0x000b09c4726df2fa,0x0009aa62ed60a55b,0x0000d183787441ab}}, + {{0x0005c96dda71597f,0x000683e67ec813b4,0x000d724183cd30fd,0x0006536b8f8530d6,0x0000632c3ac24270}, {0x000b011fe29506ef,0x00057d43147ea463,0x0002a70211a49273,0x0008988dfb701702,0x0000debd588711ec}}, + {{0x00090744b027acb8,0x000909729b2dd4cf,0x000c784e4eef7dfd,0x0006feaaf145f925,0x0000ec26936eb073}, {0x0003622990de2b9d,0x0000059c4c7d2565,0x000f374f6997d858,0x00015e6db4239a6c,0x000061e73252bdd5}}, + {{0x0000c24d522fbc0b,0x000a942bb73d7298,0x0001ead460b4f626,0x0001ddb380775ed4,0x000081f005390776}, {0x000d2a88d7ed3d9a,0x000a953ef7cd9a17,0x0008cb51593a12b6,0x00041c930e0d8397,0x0000396686f3a8cd}}, + {{0x000a7aca5295f85c,0x000d1715f010ada4,0x000137d62ed99476,0x000a2c1fcf92691a,0x0000965ba19a5dad}, {0x0006e96b9c400652,0x000a0f797bf078b5,0x00027bfa01d46a27,0x00088481a98f9ead,0x0000e828cd3a93a3}}, + {{0x0008afbdbd10a431,0x000d106c891c4914,0x000c9e0e75d3c212,0x000d14e69985bb06,0x000006751cf618c4}, {0x000a3dc9130b9b81,0x000c1201b63586c7,0x000247844a994f46,0x0000e8518f9b96f4,0x0000552e79eb2973}}, + {{0x000a7cf36346748c,0x0004f02b5ab08498,0x000a67c8add8490b,0x0004083da6e9932a,0x000000ef8174e556}, {0x000ebdb7e8317689,0x0009dcee991652fa,0x000b17155928e7e7,0x000bfb43e0c0dcf1,0x000061d9f54d10b7}}, + {{0x000fea920dc3621a,0x0004c5a9ef80adda,0x000bf625b196feb3,0x000c75a487e45e47,0x00001586634f3500}, {0x00078e658ad24f8b,0x000b7ec508d6416e,0x00086e5d355ff7df,0x000160bf2a2a10f6,0x0000e97f906d9cd7}}, + {{0x000cf2ecce6a83cb,0x0002141a1def5419,0x000b08f6b415a133,0x0003ee9d14d27344,0x000001759dafa67d}, {0x000806af6fec05ea,0x000d7b011a04ca90,0x0001b07594714b39,0x0003766edb734998,0x000077fdd00849e4}}, + {{0x000869459607c4c7,0x000c4a2823d2a191,0x000f0c346c25108b,0x0007d785158a6d3b,0x00007e489373cae3}, {0x000a7f304840c842,0x000a08f43f2912a2,0x0002fbe1729e4bb0,0x00028709c4f280f9,0x0000201f93611efb}}, + {{0x000ad0bda7974af4,0x0005389c05296416,0x0004cb76abda5ecf,0x00088f85f754c7c2,0x000047c39eefff6a}, {0x000ef4343c9b4a94,0x000d4bb7a27b96c8,0x000f48abe786978c,0x000ca9cd7614727c,0x000061d39a4e9882}}, + {{0x000b2bcdba7c5bef,0x0002040e82c7d98c,0x0003da87f7a20776,0x000de1523702befb,0x00001de9d096e046}, {0x0008b008f178210e,0x0000448332b989b3,0x00042b84ffde25ce,0x00070d3efeacb710,0x0000f18da37a2d17}}, + {{0x00060e26735666d2,0x000fc57f5610acbb,0x0007546d4a7366dc,0x0003a833bb5f11b2,0x00001d815c609e9c}, {0x00095cb0437ffbfa,0x0000948f5b486c09,0x0006bd916f7bcf31,0x0000b87395b09b27,0x00004e8d8c9a4070}}, + {{0x00041de5bdbd9371,0x0007be38711fa84d,0x0006f2cb401fcc83,0x0000193a4baf92d1,0x00005c9fa811626e}, {0x0007ce2ec2720c70,0x0008351012112d54,0x000741181f3df95f,0x000fb101caa1421f,0x0000a6d145391ef7}}, + {{0x0003e76f52e737b3,0x0008b153cd4c597a,0x000b1f2cb690af03,0x000fe5aac80ff54e,0x0000f1fde4870f82}, {0x0001d9fc80aa5815,0x000701e0254a9b91,0x00008d9e03b39021,0x00058cb9d9791e0e,0x0000755cc5bcb5bc}}, + {{0x0009e0c2ce860434,0x000fad99789d9347,0x000ca723a383cfe4,0x000ab93713011097,0x000015d43c8d3294}, {0x00089eb941c9f1c0,0x00077e0a78126ce0,0x000da428594a8b44,0x00045995df8d73b1,0x0000085b5acc6ba9}}, + {{0x0007d41d3b9f2be9,0x0001e317380a4f50,0x000743cd69a185b7,0x000a3cb0ef1dd23f,0x0000c6f878d3ac81}, {0x0002defd67e4c7a9,0x000b3b6178e5ad5a,0x0008fa9c2073e098,0x000e3f845fb5d329,0x00000ed787e92ecd}}, + {{0x000c2092f308c0e2,0x000cf372518753d3,0x00059ce271c67fa0,0x000b1d3d864e401a,0x000067229588778a}, {0x0009ac48d524d467,0x00099d0876b9e6ac,0x000365b626974faa,0x000f2027749d4cf2,0x000070d784766bdb}}, + {{0x0005d1d7ca4afe69,0x000f7a9e7f152ce1,0x0003ff356ee399b9,0x000662e7d64a6c2b,0x00004e83beaf5730}, {0x000c85f020b5cda9,0x0001bec166277cc4,0x000cfd24f3afda30,0x00076a744e4b56c9,0x0000a9916a5eedfe}}, + {{0x000fa6272bc5acf5,0x000cefa642bb8d4c,0x00068f5594a97456,0x000df80bedbcfd29,0x000069874eb72838}, {0x0008a12ad07adf76,0x000a250132b7f40a,0x000e03fac5809168,0x000a22c9ab9c544f,0x0000df51bc0f4dd0}}, + {{0x000ad692517a2b9d,0x000b734402ced5e2,0x0000f7b228d8914c,0x0009398f05425fa0,0x0000ec8d276b76ec}, {0x00069d5463a061d6,0x000728f1acfb036d,0x000cd88a2d6ddbd4,0x000ba149b9378346,0x00002bbbfad499d0}}, + {{0x00010c3a4809f81d,0x000743c8ba6258e1,0x000de0fe62140ab3,0x00009b8609de61a8,0x0000981e461acd1e}, {0x0003461543c36db0,0x0000f993771d6b06,0x00033281a273ba0d,0x000c77143e6ff6e1,0x000035a642c2fc19}}, + {{0x000ef8af2b81260e,0x0007770b18ec5710,0x000a1ea80ad37192,0x0004707b4022fecc,0x0000fe51b5f7bf41}, {0x00093d72d28d2eae,0x0009b90c140f34a6,0x000335e00449e2e1,0x000091fe11c41f75,0x0000eaa50b2c1865}}, + {{0x000cfccee288755a,0x00076204618d3307,0x000b666fc9acda01,0x0009c38ee7071f98,0x00006f3fade76154}, {0x000c58c20c01f25e,0x000a2f9c9a157e82,0x0008d7ef9691b1e0,0x00034c9b3ea053c1,0x0000fe72dbc256d6}}, + {{0x0005764654f25ab6,0x0009ae7b52161674,0x000bc1c4b22e7a1d,0x000c905ff14471fa,0x00008d2388cb4775}, {0x00068e06e8a88b79,0x0007d25e7385d977,0x000b4997f422d547,0x00018f9575d9ad31,0x00008a642eb9c009}}, + {{0x000635f43433b57d,0x000665e0a64cd543,0x000f7611b6157565,0x000371fe20970719,0x00008f08a7576fb0}, {0x000f528e7c19e126,0x000d86a273b686fd,0x000ecb6a9eb7491c,0x00099d7cc31d126b,0x00006d5b3b32c1c2}}, + {{0x000d0b2e25cc9404,0x0007ea222455a916,0x00089fc82928a4da,0x000ac5c3a8de8988,0x000064f26e535f2e}, {0x0009e29fd63260f0,0x000dd3e24fc71457,0x000bae4202864593,0x0003c6895e5601a6,0x0000c5a1f6069911}}, + {{0x000dfcc37d0c2daa,0x00007dfc9cca7ffc,0x000b7d28f4112fdc,0x0000060424fc5c4e,0x0000dc27dc84402c}, {0x0005cf0f7a1c6f9c,0x00072632a0fbbeb0,0x0001285f3c9bf405,0x00052cb7ba5b1373,0x000024a1d802dd1c}}, + {{0x00005e8e5d9c7c3d,0x00038f7b6bf10095,0x00089e65c94ef08c,0x000d589c3fc80399,0x0000512ab462c8e0}, {0x0006248da5cee075,0x0004b0bf71366122,0x00009b19f788483f,0x00068461ae7d4670,0x0000e3240047ed4d}}, + {{0x0004a8045830ec3f,0x000ff27347bdebd9,0x000eb6a8bec329d4,0x000a3bc9be726d25,0x0000afd3ea7f8f65}, {0x000de1f94e8ec819,0x0000fd5786e2d77e,0x0008c8d2f48236de,0x00088e979e9d9bc8,0x00004177d03e4855}}, + {{0x000a920680b0b442,0x000dd67952d80308,0x0003db335984f1ab,0x000ab57e1ee014c2,0x0000efa311d1fa2b}, {0x000fa774c0978f94,0x000d6ef134fea6a1,0x0003be2502663d93,0x000589a91cb57c89,0x0000e81b2b61a07d}}, + {{0x000445556f590009,0x0001d606164fbd7f,0x00055c8b39ec5161,0x0007b36417bf0954,0x0000bfb7b6cc3e60}, {0x0007ef44ff8e3e17,0x000ee02f7cb58de9,0x000726935b92e359,0x000ec248d2c5ba66,0x00008f73b6ca1537}}, + {{0x000ea9a101c27ebd,0x00088450bc2d762c,0x000a6b7821eaee2f,0x000e7617f29336dc,0x0000bc610f11b9ee}, {0x00020c50b2e18605,0x0009a3531a079c62,0x0003c6f4589a8346,0x0002726dc650c838,0x00002cf4bee72e9b}}, + {{0x0005ef53014f895c,0x000dd9551573a2a6,0x000147dcafddcafa,0x000427c62e1a2646,0x00006be9a834c331}, {0x00031b08c02f0e7f,0x000609f1f2c5658d,0x0009db9bc2cb949f,0x00041b03603bb15e,0x0000294d7c597e01}}, + {{0x000f7cbdd4b39e30,0x0007591b53bf0d2c,0x00051085bc0a78af,0x000d6563b36998a2,0x00008f29a516edf9}, {0x0002df96b9af9b9a,0x000aceaf18ac1998,0x000cb38bd6224ff1,0x0009b595e64776cd,0x000086b39f9d62a5}}, + {{0x0006cc6d42576447,0x000663d1585e0963,0x000718b6eb780a69,0x0008a786d3112c4f,0x000050513009055f}, {0x0001c1f94b567f55,0x0008f04cad491658,0x00005055750428c6,0x0005942f8ebe9db1,0x0000bff399ae72d9}}, + {{0x000b37679ef9c071,0x0007c79b043a42e2,0x0001c11d543e3065,0x000090850df636db,0x0000cf5e687e4648}, {0x0004641c28d6f0e4,0x0009d91286f41e3b,0x0005a6a95105c1d3,0x00040a84b6eed5a4,0x00004f9c5c40b1f7}}, + {{0x000635917a1fc0e6,0x000de448fa1d343e,0x000d04e3e582a0ed,0x000b5be78e3f3810,0x0000e69322253204}, {0x0003f2d8fdb2f68b,0x000dd150d2fb477b,0x000e74fd46b26937,0x000832fb96b093bb,0x0000fd4236540d29}}, + {{0x000627c7da59bb55,0x0004a420a8a1e312,0x000b69e2db5a517b,0x000f174190a03a06,0x000034c0dc213d8b}, {0x0007341656c0a5bc,0x0004601ccf3374cd,0x000728ffe8da09bf,0x0006f93d580e29f4,0x000070d257e9d4a4}}, + {{0x0007cb0ef9a7de8e,0x000c7be468b6982a,0x00013cbb99b936ba,0x0006099f3a374002,0x0000d5e01e4045c3}, {0x000fd2a477e5592a,0x0008ab788c4a8e5a,0x00062949464a88f7,0x000f822e6ed3ab7b,0x000049956ac60d9d}}, + {{0x000632ac60494b85,0x000755001958b3c9,0x00092a6b084635a0,0x0005d4a6261cd6ca,0x0000c5c5a09d09d8}, {0x0003c778bbdfbed1,0x0000571017535054,0x0007f0364db303b2,0x000211c2f39c2c8c,0x0000b2228378b171}}, + {{0x0001b82327cbef8e,0x0006712292a1eb20,0x000d0aa8149ef800,0x00044484bd3c30a6,0x00001bc4794e2151}, {0x00007c4a40a45ab2,0x00072ef2f8c60537,0x000ab01c42dd4a68,0x0004c68445e92c6b,0x00009930cf73325b}}, + {{0x000e0f195743160d,0x0005e665920d09ed,0x00037949c34c1646,0x0001563924baaef5,0x0000864d65b629cd}, {0x000d0645d626af27,0x000b919ee5e27e75,0x000bcf4e3b28ade6,0x00072b450f7afe7d,0x00002fc16bb41c90}}, + {{0x0001f5474504517d,0x0007449fd75747aa,0x000d80fd4dd4e899,0x0000fb1503a0575a,0x00000bcf27aa872b}, {0x0001562ee6845a9b,0x0003adcbda3beec7,0x000e87f54cea9040,0x000d9aa4b0fd3e40,0x000055424363272e}}, + {{0x00000c0c822a63bb,0x0004adabf48f17a0,0x000c2629e0a4d95c,0x0005564c47efec06,0x0000fbcf94b6fd09}, {0x0007de8757b55d12,0x000113777841f5cc,0x0003e33bdeb58cf8,0x000534cfd0dd9945,0x000091a701a6191e}}, + {{0x00034fc2d6c998c3,0x000f5f1753a09b2d,0x000707feecebe5aa,0x00069ae9d032ee76,0x0000b6aa01f1d59f}, {0x000215a8ac67882a,0x0004aa4451eab1bb,0x0003598726a6d1c4,0x000ec7ca810ae0fb,0x0000c1072b2ff7a7}}, + {{0x00062dfef6c9d3f9,0x00089e8be45575b3,0x000c3679a444f608,0x00071da3d3cefd86,0x00009c6b4fe674c5}, {0x000df41f2400d99b,0x000e475f7d54f051,0x000134e5aa9dfed3,0x000b7685cd7bf7e3,0x0000b240168e9d1c}}, + {{0x000f0d440f9f2318,0x000c0a943da7cf17,0x0009cb3de587af78,0x00062e9e6652099c,0x0000b949476ce142}, {0x0005db129e890250,0x000a0753258e9fa5,0x0002708f8e51d5ee,0x00097e68246e57ab,0x00009d5a84444486}}, + {{0x000537887ec45f50,0x0004ae322bdb29f2,0x000adb167eb07940,0x0007ad30b3e3e19d,0x0000cd3891451308}, {0x000e460bdfbaf9e1,0x0006182f1a4179d4,0x00095e491e6878d6,0x00021d1b6dcd2c5e,0x0000e017c1488203}}, + {{0x00015e8bff7115fc,0x000daac297105666,0x000baadbd6bf7eec,0x000495ef121aecb3,0x00004b4a97a0b0f0}, {0x000019c825163c75,0x00095c56e3c4a123,0x000b6668b677a76b,0x00092bc127011ec5,0x000076ef43ce65f6}}, + {{0x00079e1d0309f4a9,0x000d470e28f20534,0x000381c00c0cf6f4,0x000f7d93eb4f59fb,0x00008542677c1440}, {0x000f92b296bd38fb,0x0002503a89b42228,0x00027708a23f058b,0x0006defa6cc068e8,0x0000ed74c5c5e932}}, +}, +{ +/* digit=18 [{1,2,3,..,}]*([2^126]*G) */ + {{0x000bda36cacdb2cf,0x000910b10ef58eee,0x000d29b4c26a98fa,0x0003e3520f48c766,0x000080d336a84be4}, {0x000adf4bead7d2a2,0x0007e7f8e550baac,0x00016417827824fb,0x00050949f19c4c62,0x0000c4b8ae7907f7}}, + {{0x000429a647025b7c,0x000f6df2b6d14a77,0x000609d41bea840f,0x000070b3276b7b67,0x0000d649bb3d432a}, {0x00057149509e594e,0x0009f596b64efcab,0x000a64e95827d522,0x000fd96c407e119a,0x0000c8006ba42564}}, + {{0x0001f1f6379bea52,0x0003f11b63e85354,0x000bd1b7caedef57,0x00000814fa04ef2b,0x00000ba83d7a9136}, {0x000975bc42555421,0x0003bef8e88beb41,0x0009541ba9f5aed0,0x00002dcdb28a4ddb,0x0000c066be89e1f7}}, + {{0x0009e6504120719c,0x000a1d96a1faf50c,0x000f5b3b23b7d22a,0x0009b4c352bf7130,0x0000978872929651}, {0x000356cf46ef6d36,0x000d4b97e2b6d316,0x000745689d64bc86,0x000562e5f781a12f,0x00008e0f6cd43d40}}, + {{0x0004a418781db583,0x000ddb124e3c2a76,0x00081c4f1f2539f9,0x000d86b17c619fe1,0x000024aecc3f2e6f}, {0x000536d45da54e56,0x00008208d6bf93b5,0x000bbdebc0443405,0x00079e4ec013e263,0x0000aed5ad15e7e7}}, + {{0x00005bb45d491a70,0x0004f423f59393d2,0x0008aca8510e837a,0x00078a4b50263ba4,0x00007b7f90bb8d6b}, {0x0003e303142c350f,0x000579c8254cdd54,0x00007552b0caff31,0x000f3c7248599467,0x0000b09e2c65643a}}, + {{0x0000623413605a2a,0x000e240c98eef219,0x000f738bd35a0ab1,0x0009cd49fd931436,0x00004b15c7d1bfb8}, {0x000dbe8e750cc8c8,0x000b2cf64775adee,0x000319f210d69428,0x0004c23bb86bcc34,0x00000692bf71bc31}}, + {{0x000dfb3eb9b38812,0x00060a94cb32edd2,0x0002674cf6680001,0x0004a91b08a68240,0x0000a3f5713fd970}, {0x000b550f67fb936a,0x00009cdf975dc67d,0x000d4f8ab994e401,0x00062714fffa287d,0x000076cbd2a37974}}, + {{0x000e793d6134da7d,0x000bfbaad67700c8,0x000044bc3a9b1458,0x00077a29db52c0a4,0x0000ae12105ecf19}, {0x0002c2d93e614751,0x000a3490a4cf1ae9,0x000abd69904507c2,0x0008d306a123b893,0x0000b8500fd782db}}, + {{0x000abf3c48af855b,0x0003d34d16708b4f,0x000a6ed07a282725,0x00019f730cb8f53d,0x00004ed0b7fb72b8}, {0x000816f3f3cbd30d,0x000d59260df36d85,0x0005cd9529f3ed7d,0x000918b8a442833c,0x000032c62276ad4e}}, + {{0x000505323819ad11,0x000a66c1746fd93f,0x0004515701dbeb19,0x000ac25d76041aa0,0x000039541e46492f}, {0x00082e4f5acecbe4,0x00047f003d36ac5c,0x00043a011a75a08d,0x000a029ab7481052,0x0000a07bbb938ff3}}, + {{0x000313ef5b5203b0,0x000154281306d809,0x0007c4b68fff9649,0x000164f75079e9fa,0x0000ddc7de06c72a}, {0x000a43bee64870b2,0x00058d075707ead1,0x0007b284d06638d0,0x00026466a4426597,0x0000eaeec425f7aa}}, + {{0x0009ce770a7c3145,0x000bb6337494e900,0x000a3e657770528c,0x00046d72c5c2351c,0x00002af88081301c}, {0x000002b6736a4987,0x000c03a730f22f8e,0x000a208d941c9745,0x000aed32506797d7,0x000039e0f2030605}}, + {{0x0003d4dfd808ef40,0x0004a58fcc7a1a47,0x000d19ae0ad86492,0x000cfe1443bf900b,0x0000040e88ad8cdc}, {0x000fb32cf6f58d39,0x0004562194b4f5d3,0x000375f3350db919,0x0008ebda78332dc7,0x00005e8bc45b952d}}, + {{0x00037937dd5f4dc8,0x000ad87dee916fc5,0x0000f9f838cdd726,0x00035bd06c293d17,0x000082c987f7d4fb}, {0x000e6e2af0881b65,0x000cecc3a59895a3,0x000db383e0d7d33a,0x00049900fdc70f9b,0x0000f53161d8db37}}, + {{0x00019a6df48dd005,0x00078c392aee7d99,0x00047da22270b610,0x0004292dad3f50d6,0x00004f9084de0936}, {0x0005ceb1e6d4f40f,0x00031c3e122362e4,0x000da2cb1ca24344,0x00089b025e58689c,0x0000ccbfb734d9f3}}, + {{0x00056e296b1d2a7c,0x00059aa411c51ff2,0x000534da9f87d206,0x000e1eef18a860a5,0x0000cafe63ce745f}, {0x000de8dab4468f3a,0x0000fb7e0c6a3275,0x0006193be6dadc7b,0x000ba599d3ced6ee,0x0000dbb9b3d4d796}}, + {{0x000f56c3e083f9ab,0x0000f603effd3017,0x0009c1d0099ea92c,0x0007d4e4fbe0dbe4,0x000058f3d2157ba5}, {0x000ca441fd54b954,0x0001acfab07e949c,0x0004453173fafb5c,0x0003e4c363c1d941,0x00009a533ea85b8d}}, + {{0x0006b73590d7896f,0x000cf513e5a6272a,0x00050b6b74115ef2,0x0008e802ec0c8d3c,0x000049dfcec6abc6}, {0x00026d644b778478,0x000145e3ef68d48e,0x000f9b1877d7f703,0x000ca9888630059d,0x0000e9f78f370136}}, + {{0x000cde2c3f33edbe,0x000ec5924d163d97,0x000758c8e3452e6c,0x00032d47700eb684,0x000001d15f0a9f82}, {0x000418cc0818999e,0x0007ac6d0ed810c4,0x000b5e011052bb51,0x0000cd43a902bc60,0x00002a9eeb8b57ff}}, + {{0x0009cbbf986df839,0x000414b85d3a71d7,0x00005e069c77aa0d,0x000f8f79dbf4a89a,0x00001526933b2c78}, {0x000844b710bed445,0x000cab49b00f7c1c,0x000718415d8c3d66,0x000865e5b99f683e,0x0000f111505bec98}}, + {{0x000b317b5fec109d,0x000ee60dd74ac94c,0x00063fc3e8bcf0db,0x0005aea594aafcc1,0x00002fd718e53283}, {0x0006bfa2ad47da58,0x00065d79c62c0537,0x00022ffb34140d60,0x000316bdfd12c941,0x00008ff86a718219}}, + {{0x00005b5677be2211,0x000de539062c2e91,0x000ee1b283c1d085,0x0000ba39a96ec9f8,0x00005bef7b5be408}, {0x000d5fcee8efdc4c,0x000c2f4b6689630b,0x000821b7000e829a,0x0006ac1efeb571f2,0x0000900fa02078a3}}, + {{0x000ac0bb76286c73,0x000d00f0c3a98fed,0x00087e24013a68d6,0x000322ae9cfa421f,0x00001657a067cc6f}, {0x0002945e67c00f12,0x00008ced22dd80a8,0x0005f0311374391e,0x000812c96c16f73e,0x00008be3307fc625}}, + {{0x0000d24be55cf092,0x000bdccaaa5ce5da,0x0008f0f8dc643eb3,0x0000f68b247fa097,0x0000c0f660a3692d}, {0x00041339e5f44cd6,0x00038483a65d698e,0x00067c073941df7a,0x000ed7f027b59c3c,0x00000823924cbd81}}, + {{0x000e36f7b744a49f,0x0001e8cea2841e6e,0x000a884d4e78ac9b,0x0002006211afc386,0x0000bc9bb9210e86}, {0x0001811b825aa7d6,0x000fb8213b25406e,0x00056e2bd62d5f8f,0x000b0d142d4390b7,0x000075f859df9893}}, + {{0x00057cfe953f406d,0x0006157c97bac651,0x00024b6d0bf2ff3c,0x0000073279a7e31e,0x0000cd7666235cc9}, {0x0005f46b2d76ca4b,0x000b0c3acdad6d7e,0x000d9e9e19354299,0x0000b8f783e65fb7,0x00000c641307f969}}, + {{0x000c59b6284008a8,0x000ad0ccb64fab61,0x000697bfa47d385d,0x0000a004d91fef33,0x0000201b805d7b1a}, {0x000b4cdbd7634bf8,0x000a8b1db7c95182,0x000a7b2b0dc8df9b,0x0004e30b652cca38,0x00009346424294cf}}, + {{0x000967ec6fb1f7d1,0x00013f8595e9532f,0x000760d79b0e83e4,0x0005cb6f0edab69a,0x000015764aef0bc4}, {0x0009ea00e9a799c7,0x000ac5b817fb15d5,0x000ad401b2f89864,0x0007afaa02dcaefc,0x00008c0d626305da}}, + {{0x000f2627ea780449,0x0004d0e16afee339,0x0001b1273fed7f14,0x000b2aaf8ae2dddc,0x00008e33f95fb10b}, {0x0003ee06234667b5,0x000f276fd3a5674e,0x000130d66a2b11a9,0x00010566bac7e07b,0x00002e0bb494f27c}}, + {{0x00054f5c6635026b,0x000a5a2c274a495c,0x0003d78d5e70c783,0x000d415596f0ba22,0x0000bea114aab96c}, {0x0006e4a26ec6994e,0x0003684f55dc21ce,0x000cb57be6c33dcb,0x000313516f6d6dbd,0x00008f669b41b988}}, + {{0x000c339ae3dc8edc,0x000f91873e0a1cd8,0x0006e937184cc542,0x000c8d374985e854,0x000064db8f80da1e}, {0x000fd63fc2e60274,0x000092f545cfdc42,0x000f97827e622ee9,0x00065dad12fb4d99,0x00009f63d4cea6ee}}, + {{0x0001d6efcdf88357,0x0008d95feecaa92e,0x00070e0938b6f590,0x000a9f0529925a20,0x0000cc42d8fc5d2e}, {0x0008c449b39c8e3e,0x00018b9ff21e615e,0x000c5b91c41f334c,0x0002004dc2fadbb9,0x00006d8605de3771}}, + {{0x0008cef52c6038cb,0x000595e25e5d6385,0x000a8e39d52faa35,0x00038504ffcbe219,0x00000875f8ef9618}, {0x0009872453c11381,0x0005c29f2eb78994,0x00004e6c20daf621,0x0005430dcf55501e,0x0000288ec97e36c0}}, + {{0x000c030591d26efd,0x0004d6d48ef7dce4,0x0009fd5d0405d2b4,0x0009ebbe289fc630,0x0000f97f0f01043c}, {0x0000b590022dc8ea,0x0004f976d4fbb359,0x000cecbf9a4644fc,0x0003207c99203ebf,0x0000edece41acc46}}, + {{0x000a362d721e9089,0x000a8925abc2aab2,0x0005350debe2e21e,0x00009fc91b3baa47,0x000048d66950c56c}, {0x000efeca03b29fb8,0x000f6bfda542da62,0x000139636634ba83,0x000c501c74caf2cd,0x0000b76d82e0f5b3}}, + {{0x000f6a56da8987c3,0x000e1aae6fe463a2,0x00059cd2c45e1dbf,0x000f0def678e8651,0x0000cea256fdc1ed}, {0x0003034d6ed1ba9c,0x000d0bf5e4dac73e,0x00084887837e23c3,0x00093ecd182d4808,0x00009476a1eec1f3}}, + {{0x00052dc77d7fb769,0x00013ff38f95cc7b,0x000733f795b3e21d,0x00090f612de561ca,0x00000f59a5455061}, {0x0007d48864196b53,0x000db4e3286957a1,0x00022d8d9ef59a96,0x000546011073136b,0x0000f1697c656115}}, + {{0x000317c1f8fc48ed,0x0006c0c0118eb24c,0x0000b3a095d3b7f5,0x000bbb608213550f,0x00005d5ad61f1fac}, {0x000a62d9583b13f2,0x0003577ecca5129c,0x0008c4140f3beafb,0x000b94480bfb33f0,0x00003f0a96a83959}}, + {{0x00031c65de0895cf,0x0006825228776fba,0x000cc88cce49fb2c,0x000d50e32472dd56,0x0000e65850b7a0d3}, {0x0002d9997abc2bc7,0x000247d47511ebbf,0x0000c31ba0b5abb4,0x000ba45f83b7816c,0x0000b1293a82eebf}}, + {{0x00014867763f2007,0x000c9a238ab540ca,0x0002810892f80e56,0x0000ae04b954b5a9,0x000009638ba155c2}, {0x00045f04b72df059,0x0007c79932f148e2,0x000f4ad95262dd9a,0x00058706f74ca482,0x00007911b864b69c}}, + {{0x0000b9c737140708,0x000667edd421d9f3,0x0008968685c81d98,0x0002788a4eac735f,0x0000023a157c9f57}, {0x000b4b003c82278b,0x000a81472fd167f3,0x000e0926bf38ac74,0x000e573126c462f5,0x00001ca6838518a1}}, + {{0x0001d85ac1d95c07,0x00033d583ca23351,0x0005118833877919,0x0002e080183f6e60,0x0000ff39e0469cbc}, {0x0002e04f226307cc,0x000f4bacaf9a2435,0x00074e2a51232d0b,0x0004f77d72b628f0,0x0000acec834b62bf}}, + {{0x0004545c8ad66709,0x000cfc688d8046a9,0x0004edfdc8d75925,0x000f05ae813c9e06,0x0000f09d9f9bb086}, {0x00062ca1db3df5b7,0x000c5b5ffcee14c9,0x00098918be83ad5a,0x000ac894b0684569,0x0000a8eed798d0b3}}, + {{0x0007970ef932b7f4,0x000f2ef627b27d5d,0x000b1f232a660b84,0x00047a67e2544348,0x0000f46ef3c81556}, {0x000ae5e50254dbfc,0x0000dbc8b8f53a6f,0x000f81f9760130dd,0x00056daa15ae29e5,0x0000531c6e3d8872}}, + {{0x0003fc5aec293c17,0x000fae2a8b3062bd,0x000d294391c65007,0x000ba8bc7a567060,0x0000e892b188f41d}, {0x000fea5c9cbb5a66,0x000a06ddbfb94b09,0x000a553dda4501d5,0x000c2b5f030fbe8d,0x00009f35d7661397}}, + {{0x00053c7d6c32ad49,0x000e202b6f62edae,0x0009918ca0e11d30,0x00064c3b7cc78f3d,0x0000aeb2ed04daba}, {0x000308348ade515d,0x000a42f73385ada9,0x000c1e0d66b4b6db,0x0008698732c86253,0x000004118fd191f3}}, + {{0x000796becef5c499,0x0007cd9c3e671366,0x0006808dd995c7ed,0x000e24412560f80a,0x000092c05fbf5a45}, {0x0001d3fb0df606cc,0x000bfd721b8febb4,0x00095b3096c03c24,0x0004db6d2624db4d,0x0000abed17dbcf2b}}, + {{0x000c4df41f71eab0,0x000a65e016a9a3c4,0x000dcf582ca058e1,0x0007f71ec4c968da,0x000026cfe1cad268}, {0x00096c924f46e504,0x0004491a46f19726,0x00070b7c43b16a8b,0x000da051694c0dab,0x00004ee2a129241e}}, + {{0x000900a5814e9247,0x0005613cf2606c1c,0x0005cccca1791d81,0x00048d0077d293ce,0x00006bc874a43ebc}, {0x000037e17cc1b585,0x0001d8d11bf83c3b,0x0005987d393c01a5,0x000228591bf583aa,0x000025efdb1260d8}}, + {{0x0003d91512d96c5e,0x0007e4b4ad0fa8de,0x0007b0bb68b040c8,0x00043c9dabe6dfa3,0x00000d7ee9b62348}, {0x0006da6bed5911cd,0x0009a6ece7ff38f6,0x000e5dd83880a808,0x00053087b04129e5,0x00001bbc6c30ba0f}}, + {{0x000e84dbadaa5f56,0x000cd377815fe20e,0x0008c62698e27faa,0x000347e02c37a9b4,0x00008e9bf569f39b}, {0x0007b248d318a6ae,0x000474a21df44e51,0x00031719dd246130,0x00074f8d75f0927c,0x0000b89236c1ad86}}, + {{0x00017308e1e58e7c,0x000867db13b9dde7,0x000306f021259e44,0x0001a4349c8e56e3,0x0000b578ecfaafa1}, {0x00084505fc0f3955,0x000c9cf62fa54df9,0x00036b0d416db73b,0x0005d79d27a78dac,0x00009d0ac179612c}}, + {{0x0004b0085e82cbc7,0x000abb85d10839db,0x0005f3bffdf52af9,0x00079078e4cbea13,0x00006cbba6b97a8a}, {0x000b82422c5fa00d,0x000a3ab275192d04,0x000e62fb0c96cace,0x00026b9b5e0fdcda,0x000028851c8af90b}}, + {{0x00012449f8c83d3e,0x00021b484ffb3484,0x0002a03c330d56a3,0x000de8f64f1a4e29,0x0000968c4493bb60}, {0x000b81bd33e1a3ce,0x000aa34a593e8cb6,0x0001cdb8a73950dd,0x000c5aca2dd94ae8,0x00002196c60ad005}}, + {{0x0002ecd9e6a86c14,0x0005bf4b4d550dfa,0x000030370fc52488,0x00002d4d8f6fdb09,0x000086c76907c7c6}, {0x00017c32a9829592,0x00024cd68ba39a26,0x0004748f380234c0,0x0006b496816425bd,0x0000b82c805a4841}}, + {{0x0008d667d5dc4d15,0x00099cf2f678940d,0x000694f978881dfb,0x000dbc7192ed98d2,0x0000de896634885e}, {0x0009ddbb3cc587e7,0x000d4b22b2d17299,0x000c81311033e3ff,0x0003b651ec3fe79f,0x0000aae471a0e640}}, + {{0x0004cd3ea6e3d753,0x00060a108f5907d1,0x00041859d6c895b2,0x0006353d871a05a2,0x00000971096c4c9a}, {0x000fa44e4d592627,0x000e35522b5be21a,0x0002456c5b24ea58,0x000fdf656200f0b2,0x000002a5a001b93e}}, + {{0x000a930b41d968d7,0x0005f45cda83c150,0x00048023ce9f4ff1,0x000af875c0255a23,0x0000618af75ec0f1}, {0x0004f16f88f7d864,0x000f11b9e30e6555,0x0008bf8f34a212db,0x000a4894a74095b8,0x0000f73c218673af}}, + {{0x000719474c355ac3,0x0007767feed9b317,0x0001495f898e9455,0x00044f2e1c716c37,0x00008656ae1b3716}, {0x0001a34aa65dcb6a,0x000d0b1c27a68be4,0x000536b1b2ce4de7,0x000a67af11085552,0x00009a395ffaad98}}, + {{0x000d3f4d7c754474,0x000c22c337ab180f,0x00072abe02a8ff15,0x0003fc10970c2e93,0x00003c652e722cfb}, {0x000c02f3684913d4,0x000297055bcefbca,0x00000984f91a0cab,0x0006a13ef0aec851,0x000083ec8cccc61c}}, + {{0x000a2ec8681d7400,0x000eb2e1e27bf54d,0x00021ca664bfbd0b,0x0009eecb3fb586d7,0x0000407b0b572888}, {0x0009fa49e7df0d49,0x000c8db83e5cf139,0x0008d62a8d255ab6,0x00064e972c4b357c,0x0000b7d17a711fc4}}, + {{0x000bb7a820c7747c,0x0008591aae71b534,0x0000ffe0e9e5c12a,0x0006d406fec50176,0x0000f79f9725d57d}, {0x00087fd706dc3021,0x00069d9f06684b74,0x00056d2a20079b4b,0x000da7fcbf83e575,0x0000880dacfe1d20}}, + {{0x00058e9c302ba867,0x00031efb88acbef5,0x000b99aabe4819fa,0x00022ba1871c5dd5,0x00009777c5931fe9}, {0x00099616dc64a369,0x0002003ba21a955b,0x000169185be37b58,0x0004c6afe824b374,0x0000bfc77522de74}}, +}, +{ +/* digit=19 [{1,2,3,..,}]*([2^133]*G) */ + {{0x000a727255b1faf7,0x000452ecd6f25da6,0x0004ecafd5a5a652,0x000bad00768839c1,0x0000a47db65e8b03}, {0x0008ff333559d9cb,0x000966d9582a7941,0x000861751aab0822,0x00061a8937485277,0x0000e70755598baa}}, + {{0x000d0b3a9d6e707a,0x000deb1e6b972802,0x000a9cdc816ee683,0x000300c2c0420274,0x0000882a6225668e}, {0x0005839e9d3e56bd,0x0003671e54dd8b9a,0x0004f99975d7c4b5,0x0007ae4fc6ef3c37,0x0000fc5b94dbc8c6}}, + {{0x000a6cf4e2db7b3d,0x0005cf35c5c3f019,0x000bdb6f316a364f,0x0006e1221c2e18a4,0x0000dc4b2200d39e}, {0x00078f1c8e821915,0x00009b22f686d8fb,0x000a305a94c1ab12,0x000cd236717c6df2,0x0000b14404a2f1a7}}, + {{0x000bac5f488d5a8b,0x000732f43799d874,0x000877268650340b,0x0003966fe4b48921,0x000034a8a84a9b2d}, {0x0000e4682408320c,0x000cb0f0f018a4e6,0x000fcb65b28d1028,0x000898348a10c5df,0x0000188d1de6f0a9}}, + {{0x000e203166a36c7b,0x000b4b6efd58b491,0x000b8cf6095cca77,0x00087b5779dd6452,0x00003dee080aa1e6}, {0x000516401adcd8a2,0x000c863c78749a85,0x0004b4b58a717ce5,0x000b1c6419ecb4d4,0x00001c953dfc5f7f}}, + {{0x0005a4caf12ba860,0x0000c62e1874ce63,0x000fde52b08d1a6b,0x000a7df06d9f7da7,0x00009e538c0d777f}, {0x000d8554da32762d,0x000fb42b270d4ac9,0x0006c0faa9638fdf,0x000554ad39e13597,0x000052af20a0ab43}}, + {{0x000de3d347ef0da1,0x0000e86b94de0d5d,0x00081ede6978f54a,0x00004b7554d28aca,0x000093f67d8e3d7e}, {0x000d6d4b2accb9b0,0x000eaac44bfff953,0x000334bb519d0743,0x0004597cb4782f84,0x0000e289c03cc10b}}, + {{0x000d7c4e6d753278,0x00056ab83d3f5734,0x0003ee15022d081a,0x000b4954cbe1d2ec,0x0000296520fe0c21}, {0x000b30c9f320aecd,0x00021106ddcb4b09,0x000f1b1848a3530d,0x000247c734a80168,0x0000496e464291ce}}, + {{0x00090a90c5f1581d,0x00021f437e8ccdee,0x00069fdd47f1c872,0x000a9c2e4357299f,0x00002d0483696306}, {0x000b5fd8d746c503,0x000c8bd661cb171d,0x0002cd43b1cc7a71,0x0001118c6769457e,0x0000150b880fe3d7}}, + {{0x0000f541d58b53b7,0x0006631c29ba2789,0x0002be7fa10f036c,0x0004b70db1abcfa3,0x00008eb4ca6712a3}, {0x0007134fe95a5dc8,0x00009bfdd4921a07,0x0004074f4fc33414,0x000344776f51e869,0x000039fcc742b48d}}, + {{0x000b7d00d6409a81,0x000dd67668b16ac9,0x000adde6b0cd175b,0x0003b8db64a49847,0x000077b648118844}, {0x000b3a9b85df3c57,0x0002bc406a3f3c24,0x000c75b3c764621e,0x00010e175b8c2793,0x0000b0bdce77a0e4}}, + {{0x0004813b51c2e64e,0x00005742d51835f0,0x000ecc30fadd8650,0x000bedf50410b627,0x000021e7232979d7}, {0x0005b9c764997bfb,0x000b0468d42cf2f8,0x00060163f7fd4379,0x000bda4d0bb60197,0x0000a925ae795940}}, + {{0x000c27028b18d58d,0x0009810f017ccd8a,0x000df69987d79344,0x000c3b7f59b76dce,0x0000dae304e49afd}, {0x0006d38b645dc0df,0x0006de4e4718ba52,0x000f7e2d51a37fea,0x000a96abfb95fdb4,0x00001485263258e0}}, + {{0x0007d52ce0614c9e,0x0004e699b20813ee,0x0006fd82d87f7d47,0x0004dd26820af588,0x00005ed613674375}, {0x000d90e6407c8b58,0x00045ffbeb5f5d2b,0x000b95218b07597c,0x000bce1f2697c7b4,0x0000512e42cb5fed}}, + {{0x0007ba3ac56e0291,0x00063e80caf76d16,0x000402f16cd63473,0x00035e2bb89abbd8,0x0000bbb3d5dfbc8e}, {0x0009ac52a39e9a6b,0x000961b06920b768,0x0007fad592b5ca40,0x000305260906fb21,0x0000df04971052ab}}, + {{0x0009f76f719e0c19,0x0009462eab4521c4,0x000093d14459bb4f,0x0009e86bfea8af42,0x0000c845c0599acb}, {0x000619f255078fa3,0x00078ac8483e27a2,0x0002f48e15d94779,0x0006657197c26f1c,0x00001b0bbf55242a}}, + {{0x00058c998e87eec5,0x0009d5bf41a5e976,0x00045718c33c7d9d,0x00008841dd908702,0x000048d0cab1bd20}, {0x00064a0500d4afb9,0x000806c82de8d3f0,0x000fd2028c970708,0x0006951017002380,0x00009d99f573ff71}}, + {{0x0005b58a79b2ebda,0x00028acfec229986,0x000fb08398ff8388,0x0006debd733c9ea8,0x0000aafb0b851b1a}, {0x000791b3602750dd,0x000f1eb59cdb2015,0x0005a8c5e25286fd,0x000fcdbccb6aa395,0x0000b0031f1a9f9e}}, + {{0x00036c2ab12c2213,0x00029a74288bef01,0x000813cfd8d67fb8,0x000edc144e8dbaa8,0x00001e994264cc9f}, {0x000d9b6095487f1f,0x000fbce801322d42,0x000d781e3f5b5610,0x000a5f163843cfa3,0x000018ad797760f0}}, + {{0x000104980838bd3e,0x0001d4b775d53e56,0x00032e1224b44db2,0x000b72ba0d374dfa,0x00002d1e993def8e}, {0x0000a19b53d7c05c,0x0001f3fcbd21bd3d,0x00040bbe6188a3aa,0x000cde0596e5ba59,0x00001c6391029e21}}, + {{0x0002b014fcbe1856,0x000b95e13a2b28d5,0x0006d0d4b135f7ef,0x00088914fd801d5a,0x000039be473b9886}, {0x0005da0db71ae0b1,0x00021d1359895df5,0x000fdaa6f9a87424,0x00086a4b6a38e436,0x00004b52ba6a46aa}}, + {{0x00012f2761b2f3c5,0x000c6614fc53bbdb,0x00042cf5cddc872d,0x000f394469eb926a,0x00000be240fe2dd0}, {0x000ba88505bde5bc,0x000093955a18ec7e,0x000d0aa3265bd9f6,0x0008cf2aba473ef4,0x00005612ed21f6df}}, + {{0x000c255f6facee1e,0x00050647746dc2e6,0x0003ba4f655a3120,0x0008bc9b08c0899c,0x0000ebed9359dd89}, {0x000b9c2f4be6d27a,0x0000379fa923f100,0x000ecd610db4fb74,0x000f5c0a7070baae,0x0000e5703880295d}}, + {{0x0002792b86361989,0x000c70e0ea1d1795,0x000cee4b2945e4cc,0x000e49191f5928e0,0x00005a092513973c}, {0x0001517aa0eec014,0x00022752e7d55c3b,0x00099eab1d2d4b0f,0x000a05485931759e,0x0000052fe15cd96c}}, + {{0x00079adbeed33d6a,0x000d9bb0b38172df,0x00014e338c2cf0c2,0x000c9072e49e377e,0x00006fbab6774105}, {0x0005c6b6657d9f8b,0x0007430c8a4f90d4,0x000273d11fc0a286,0x0004aa737c3f3d03,0x000085bc56c4d2aa}}, + {{0x0002379568227447,0x000d5a076a384854,0x000c19f6f86ca3f6,0x0001602451c729ff,0x00008f792dda5ecc}, {0x000f7755d8802213,0x000bd503649e95d2,0x0004c555e4ab7e6c,0x00014024efaf7d22,0x00008f2776245832}}, + {{0x0003c0c7fc837d12,0x0000c7efb2ca73af,0x000f96a119684707,0x00064f56fc1c5a8f,0x0000616d7204226b}, {0x0000d16d3a7388e9,0x00086882de5f323a,0x000e0dd9dbd81663,0x000c0961f0e26e4a,0x000063cf17e2495b}}, + {{0x0008a4eeed230bed,0x0003d0d557870091,0x000ee3dfbcc65b1b,0x000d4ec313899e1b,0x000034cc4615e318}, {0x00033c138a95f8fe,0x000a9bbf13a3a311,0x0008ef1d5a245a64,0x000b9c9d0bbf5c1a,0x0000d9889cd87380}}, + {{0x0006bf10834f02c6,0x0006e01e457cc3a7,0x000006873fbea818,0x00084c35cf9b69b4,0x0000f15793516087}, {0x000fb13cc05f8ada,0x000cdff5bcccc418,0x0007c49b2d54eb80,0x0008d54143bb4a8d,0x0000da62cdad2bc2}}, + {{0x0003138c57e0d795,0x000edaf3c2b5f7c2,0x00093802977df609,0x000f578d94d77af8,0x000044741cd9805e}, {0x000fe570c9322596,0x000592415a9bc8ab,0x0005e9bd3fe94d08,0x000c8e55ad18e986,0x000069c5461d43cd}}, + {{0x000d798d927c8bd1,0x000814dbe62b28e3,0x00071e6bacb5f66e,0x000791daf2930488,0x00002760f363ab82}, {0x000fb66661da3b86,0x000fc1f4f6b755e3,0x0003fd1f289bbecb,0x0009b11762446e5b,0x0000e4bbf14d6d68}}, + {{0x0004365872cbe5af,0x00013550dcea306a,0x000e8ef29eb2b51f,0x0000e37d100ab735,0x00008b0e721f1781}, {0x0003dfa6b34d3b08,0x000b96fbd55f946d,0x0007e3d70db70874,0x000d6f1c8c13ccdd,0x000067a70e52d644}}, + {{0x000ff9a5bce55c35,0x0000f532d926f394,0x0002cb267ae6b423,0x000cfe98bafbbea3,0x0000a47e9ec49a68}, {0x0001fac4aeef377b,0x00065088b8ca39aa,0x000fcb1b33346e68,0x0003f37c4595cf03,0x0000553a9a1f2973}}, + {{0x000db5078afd98f1,0x0009a5b1d544b457,0x0003cc22ac17ad50,0x00013f9c1f670349,0x0000b99d9c60b42d}, {0x00070f5e725ed33e,0x000ff4e76c5e3634,0x0009bb5aa3712ced,0x00077c075d63270e,0x0000feb5464092f1}}, + {{0x000266f5a6fae80b,0x000e77cf1d11cf5c,0x000c25058047f7d4,0x000d72477c80fbc1,0x00002ae841fc8624}, {0x000298af8ec94027,0x000f332b3001e607,0x00057ef418781d9a,0x0006e8f3cd58c10e,0x0000ae32ae0e9391}}, + {{0x000e957ce0b54fb1,0x0006972fc16c8d59,0x0009e1ac6a5ec5c0,0x0003cc0e2a509f44,0x0000ae99269d43b5}, {0x000dcfe7f8edbf2d,0x000c4c38a98ab0de,0x000f2b7fe3eb2afb,0x000251d41c2c671f,0x0000eed98b1d120d}}, + {{0x0007bb64c21224ff,0x000ff9321251834b,0x000b9cc1597d501f,0x000a592604354ccf,0x0000558105b4b952}, {0x000e794b05479262,0x00063092655e2220,0x000e9a375065befc,0x0002a52d2ca9bacf,0x000070e81eda0f95}}, + {{0x000c09aee59dc5b6,0x0006cb27787722db,0x0005983dff716c05,0x000b4410ab2999dc,0x0000ae99f605e39d}, {0x000a294b8a218144,0x000f9bdcdec057d9,0x00013071db4aa486,0x000cb97a73b9e06e,0x0000df58e4a10434}}, + {{0x00068854ccb5cd86,0x00099dfa38302192,0x000c6d69b04ec80a,0x00057f0b4854370f,0x0000695534ea04ee}, {0x000848f83b02064b,0x0002521616e17746,0x00016cdfc7d6dc14,0x000e2fc170a55382,0x0000c5b8c572de15}}, + {{0x00031c02e59f130f,0x00069247772d5603,0x00074879039b6cd8,0x0005614566fae8b3,0x000048c68435d8dc}, {0x000c560826cc061b,0x000ed2785591eb7c,0x000662c22886c967,0x00001f926b7e0d13,0x0000a566862f57c4}}, + {{0x000008cc2d2b80fc,0x000f5cb30fd3cfcf,0x0005075763e6f872,0x000b507b8d542c1a,0x000005ea27771e0b}, {0x000c23881dac761e,0x000cabc5e2d0bbca,0x0002d7913f2786aa,0x000fbe4390fd746f,0x00000c3ae903f765}}, + {{0x000fbd330058a1d6,0x00002ef54fb2b3c9,0x0008118044f97ba9,0x000b32b660df7427,0x0000e5c26ccf676b}, {0x000d3b470f7e68e0,0x000e721fa57e439d,0x0001dcdffd33db06,0x000ac717c7489a8f,0x00007ed817eec38a}}, + {{0x0002b4c45f41a24e,0x00055384c01b0f07,0x00027702295b3c4e,0x00021305b5164d72,0x0000213182bcadfc}, {0x000702c3c59da1dc,0x0000a16ef0a14df7,0x000d1c39e1032dcc,0x000e831d50a0d7c0,0x0000644edd83072a}}, + {{0x000e10ecfc435d32,0x000d54284c66de7f,0x000050600e3840da,0x000645f7f5805c2f,0x0000742262a04570}, {0x000079ecb500097e,0x000b82599044767d,0x00048fcfba3571b0,0x0002688ed95a5d75,0x000064270f1e0c8c}}, + {{0x000a352dc9346c12,0x00023d6f6fd90c8d,0x000b10eb8580e708,0x0001c595b7b0f310,0x00007adb908efd25}, {0x000fbfa7696a0663,0x000ea1f8a2cafde0,0x000feb5f1555b2d3,0x000b2d6e3ef80a48,0x0000afa35e99343f}}, + {{0x00009298d4b6dbfb,0x000061e47941a985,0x0001fd13f88f9bba,0x000f2b1b2d1d0d09,0x0000fb0457f5ddd7}, {0x00012be21119e4a3,0x0008bebb0f558503,0x0002cd850fffa065,0x00088482acdbcb76,0x000045182c46b168}}, + {{0x000a84723ad876d1,0x0000f44279fae932,0x0000d0bc65997267,0x00005d8a11945700,0x0000641726724e50}, {0x000b9a05034241c4,0x0003db865000b9ef,0x0003bf2b3fd17345,0x000b98f1f94024dc,0x000095ee6f7d1d97}}, + {{0x00026356f22e6e7c,0x00024c3361929d42,0x000551b739519480,0x0006ba8fcc02a12b,0x0000c866d3c65741}, {0x00082ef71dd1d595,0x00088888e5b5dac9,0x0002351988936e99,0x000912104b788baa,0x00005b38d17ef74e}}, + {{0x00078e44dd47b196,0x0006e3a7433dd3ac,0x0000e11737fb1f59,0x0000f52fec79569a,0x0000143a6b04cb9e}, {0x0005dfaa4b44dc9f,0x0002f6a3f86504ff,0x000e7730114be502,0x0005c09e9f83c1f6,0x0000a40c0dddb1a6}}, + {{0x000ad7a5d9a7c749,0x000bd0b3e979591a,0x000b18984b0c8837,0x000c930f85a5824b,0x0000523198d420b4}, {0x0008c2966f8c5ecd,0x000c7529d2eed63b,0x0007a1cec89e0293,0x000ce2ee43e4b31b,0x00002b2eb6888152}}, + {{0x0004dd204d849aaa,0x000d7aac3dc6fc74,0x0005bdf821345352,0x000d21fafcb0f7ae,0x0000c9bb14c6adc8}, {0x0007dbb7c46a380c,0x0002f91f52fe0303,0x000095c182afa9ec,0x00053300cfb28879,0x0000759b435956ca}}, + {{0x000ec5f3969f68e0,0x000700e5f0e3ef78,0x000faae20f28d8af,0x0009c666fe212050,0x000038ae7b9b88f0}, {0x000157ba6e527edb,0x0008a283e2353b72,0x00056665a3b00c20,0x000fb0165eb77eee,0x00007f6601175858}}, + {{0x0001cfbcf87353f5,0x0001b45b7fba97e9,0x000c88529186f293,0x00017cb9b7e1b550,0x00008d032cbbc13e}, {0x0008803b380a2bc6,0x000ce0e1eebebc7f,0x0000b3070c817171,0x000219f2106f56d1,0x000043c2b31388af}}, + {{0x000e260a60f350a6,0x0006b02cac1de1ec,0x00028ab680baa38e,0x00084fa849c9cc42,0x00001ef5b54b9710}, {0x000d93de4657ad0f,0x0005315d84295f24,0x000d5350e7f70518,0x000b1b81c02b900a,0x000086bacb6bfb11}}, + {{0x000b24f6599254b3,0x0002db150c28450e,0x0002523f2e8c805a,0x00016e26bd712d3a,0x0000cb4ef15dd141}, {0x000099a2e6f10b03,0x00002209f4af5024,0x0009230a1a79e9f8,0x00021b395212446f,0x0000a9513044d617}}, + {{0x000a8350780042bb,0x000fb7e23271391c,0x000a21d82290ac12,0x000018afb2dc3763,0x0000debc97de697c}, {0x0004834481d067c4,0x000bdc1916ceca62,0x00074c52ab470d9c,0x00057cbf28f87f59,0x0000397d4d3c4093}}, + {{0x000666ce7e64dcc5,0x000bfd2765fa9474,0x0009f08475f3c2aa,0x0004f9d5e1f47951,0x0000ac986961d2f1}, {0x000df6492b43447a,0x0007e6aa220eae5f,0x000687d74899951c,0x000190b730db55ed,0x0000fbcbbde88500}}, + {{0x000a91cf73f6d56d,0x000dd4ac318013b0,0x0002e920d4b81d0e,0x000af89bc5c79628,0x000009d7f0a3bdb6}, {0x000654d7b2096ba9,0x0001bac0128551c6,0x00000c2c28355efe,0x000725460cf1f377,0x000031708465e5f7}}, + {{0x0004c76c4fe9380a,0x000c3951a5ba03ba,0x0009390e3a0d1f19,0x000afc40881217e1,0x00004df0a88e83a7}, {0x000384ea5baa9628,0x000bb158f86192b3,0x0008e81ff877e966,0x000d6c002eb4c264,0x00006978687377e4}}, + {{0x0001f239971de4e9,0x00066b14c2bc0eae,0x000eec2d481fcc62,0x000e4ad4346cda42,0x0000812e9df26d7a}, {0x0005f2aa6c2765b2,0x000c0d4e6727b197,0x000cf9203e0c7cc3,0x0006a71e0008e593,0x0000cc328562e6d8}}, + {{0x00041b3f24c2e3f2,0x0000057bc18560ae,0x000dab87a402cc26,0x0004fc026500b9d8,0x000039eb743203ec}, {0x000cad3bc772a9a3,0x0003237fe16c560b,0x0001e4e176f45fb2,0x00086a0c35cb9a4d,0x0000b15ebf1dbd99}}, + {{0x00084d9c6bca11af,0x000efba4998ed17e,0x00030f688bbf5028,0x0003d90bfa347c4a,0x00003511c41bb988}, {0x000e04455e4a4408,0x0008eb1d2233b9f9,0x0004641f70bb7f2a,0x000bdb4bed7797bb,0x0000525831ae528e}}, + {{0x000feb573b5f15b2,0x000c92dc8b2b488e,0x0008915cb16e2b26,0x000bc6409f7cf294,0x0000643f5d55e347}, {0x0009c716263c840c,0x00099899481ae3bc,0x00030c337aa831fb,0x0008390b15f01b4c,0x0000ccb40e5e4096}}, + {{0x00034dc70a22059a,0x00095bf4dd319094,0x000ae3a347a94846,0x00022943c512ea17,0x0000f04ad0dee788}, {0x00057b3916c3e773,0x0005eba57fff134d,0x00040dab29c7a71f,0x00005e7267cf24ed,0x0000d39e69d8fe29}}, +}, +{ +/* digit=20 [{1,2,3,..,}]*([2^140]*G) */ + {{0x0008a58ed016cd2c,0x0009dc5bbdaedb58,0x0009d19885238728,0x000afe3665291aaf,0x0000f811206507f0}, {0x000a1acb3e875c10,0x000b5e9738520bc9,0x000b92c017b2fc48,0x000d82b6aee9ccf1,0x000062c002883ebe}}, + {{0x0000bfc1cb150958,0x000d323c4b7d62aa,0x00022080f25a592e,0x0002c2d0f11983fc,0x0000ee53be304d89}, {0x00037069d21f2963,0x0003e06e21bb46bf,0x00016283512c9c3c,0x000a67545bb2988e,0x00005bfe9d31adad}}, + {{0x000ffe7d4dc02b42,0x000fa98dc963d65b,0x000b49d8292da276,0x000c09ae3c49b3e9,0x0000d5431f45032f}, {0x0000664a7193cbb1,0x0005b74ae8346136,0x000506bf40d18877,0x0008baea2b86bf65,0x0000caf5ff39d91c}}, + {{0x000a3c28239094f1,0x0002a7547af8d168,0x0006f05d9a001ef2,0x00048b8e617195d7,0x000046b964d7a1f4}, {0x00087515a695697f,0x000f6e306cc6952f,0x000023ac96fca948,0x0000113b6adf1cd3,0x0000162f07c0aff3}}, + {{0x00048e3747fee076,0x0006b0d9898348ee,0x000bb6470ff98685,0x000533883290ae3e,0x00002a3d0c700bbf}, {0x0000cabf7bd10d8a,0x000bc597ff059eda,0x000be93bc3ae7d83,0x000241f3fb57e695,0x000038751d9c581b}}, + {{0x0009f4d266fe37d0,0x0001760efc6d5220,0x0008adf5ade25d2e,0x000f03a0868e028b,0x00009d6b114bf7a8}, {0x000ea7aedf8eb0cf,0x0009fb1cec06b1ff,0x00062e007b93aad0,0x000ddc47d356e3a3,0x0000f4c08726f1f8}}, + {{0x0002fe66ccc2faa5,0x000e00587d9fa66a,0x000e403eece74ae7,0x000a225f516ff2ba,0x0000d7e840f4377d}, {0x000c2e2512283ec5,0x000ed6d8436ba415,0x0002293851324017,0x00074b2665c85d3d,0x000061f518ef05c9}}, + {{0x0001472c11f2e3f8,0x000f1235e29595f7,0x000cb9e5a4678386,0x0000d17bcc861c54,0x0000988eac405b68}, {0x00035f6f32a0837b,0x000a0526e17e28b0,0x0008d388e1404513,0x000f50161698c9fe,0x0000290d6d02d161}}, + {{0x000e406349253af7,0x000d0541fb134eda,0x0003250ff90e5eba,0x000f014ee0bc4f4a,0x0000642c5dcc7c88}, {0x00087e04f81b7760,0x0007fe70876a68d8,0x0001713f35bc975d,0x0004f149dd30b653,0x000069332df09855}}, + {{0x000ae7c2d9437a12,0x000c29850a20044f,0x00048fd99d2889e0,0x00019802a1d48fe5,0x0000f30505df8965}, {0x00029dc332e26e50,0x000aaad107e92aff,0x0008fd1562aaff01,0x0002079447e8e0e0,0x0000a12a48f5f9b6}}, + {{0x000d35f7339a4cc6,0x0003ce58997c960a,0x00043b09663f8920,0x00086a9cabcc6fe5,0x000039df7b26f9bb}, {0x00004ebedc941e64,0x000a6c597d5e1f73,0x0005265ba7702fac,0x00039a977b7848e9,0x0000c0f2844cca29}}, + {{0x000dbd0c20287ea4,0x0007f00fcae2255a,0x0006723143b1f47c,0x000fdba1ca3b9a4e,0x0000a61bac73eb36}, {0x000d0243021dac3d,0x000f566be9665cd8,0x0007af8bea21805e,0x000fc6df478b1ca3,0x0000ee9bcbadfe87}}, + {{0x00079ee748becd5c,0x000fb2987ffe5418,0x0007a1ffc02d6eee,0x00056fea13c0fed1,0x0000c469e61b060f}, {0x000a5fdafddb3776,0x000368241f08c069,0x000473ca9d3dc589,0x000a42ebca40d7ce,0x0000bb3880b5b1fe}}, + {{0x0003d7e9a039d299,0x000ba8ffe689e1ce,0x000a4b476b07cf06,0x0005849486dae5df,0x00008b49ee4dfe4c}, {0x00043c12bbee57f5,0x000913e24f4393b8,0x000ffe1e8a443ce5,0x000d0a6060aa2a71,0x0000c42edaeca67e}}, + {{0x0009179cd2d899c7,0x00018a17e501d737,0x0001ed55b3c10df5,0x00048ca04cecde6c,0x00000472a0b8057c}, {0x000052a555cd31c5,0x0005e9616214105a,0x0003eccda90583ec,0x000ea0cb4bacb30c,0x00008fd7c1a7540e}}, + {{0x000f42db00490cd2,0x0000c875327c51bf,0x0008e6a820cf37cd,0x000a81bb95829eb0,0x00001100b078ae33}, {0x00022e00511257b1,0x0005f34ada3e41b7,0x0003409ef3752978,0x0008b1f12815fe3e,0x00000e75bd15cb42}}, + {{0x0006d6b5522c8d1e,0x00020c4a6e6885b0,0x0000674f8eb11a13,0x000d2924af2210e0,0x0000da23f4f5a620}, {0x000ca47360f31777,0x0003d3885edeca1f,0x00023929c46c52bd,0x000db6297cea00a9,0x000049714f519cd2}}, + {{0x00015a866630391b,0x00035087f3dd975b,0x000f2793a140b12b,0x0006fe1693367845,0x00002d5263bccea2}, {0x0006ef773fa9b4cd,0x000b902c1b552332,0x0001ac526ad1de38,0x00006620625db61e,0x000003a7023f0df2}}, + {{0x000651d3e64ea2e3,0x0006a54af43e7a32,0x0003ae4c9330df34,0x000236a6234eb5e1,0x0000759979693586}, {0x0008b45a9d54dd05,0x000e8978baa36a6c,0x0000ebaa91e3142f,0x00008dac63becce7,0x000003546ca0617c}}, + {{0x00094d5565a427ca,0x0007ad634538fdc5,0x0000250b2a522b76,0x00055a43ef3e4b9f,0x000011bf92e19348}, {0x00072023ecc683ce,0x000ea22ed8cf7efc,0x0003fc8983d51051,0x00075d723fc11811,0x0000633cf0cc488f}}, + {{0x000ba977892ce284,0x000b4cf71171d65a,0x000030c443d4463c,0x000202ca09b1099f,0x000056bf294a1a66}, {0x000a54aeda67248d,0x000d88b53799a85a,0x000ecc75a25eefd9,0x000ddc8babc0388b,0x0000a2fbe4a79e00}}, + {{0x00095a2a1a8636b1,0x000233d7f690fd6d,0x0009ce730bdac772,0x0003be8fed0f34c3,0x000049bee0dc1db5}, {0x00000cdcd095ded2,0x000d8b21e3539d6f,0x000e3d0a33e83d8f,0x00022450c4084ba9,0x00008d82e03dfafd}}, + {{0x00051869548ddcc5,0x00070778339d1ea2,0x00035f5f50d6f915,0x000e57fa01f58a4d,0x0000841779dd56a5}, {0x000f9ee31d9a47c9,0x000d12d602675ece,0x0009553f46c32b16,0x000eacdcd3c358d4,0x00001f6870b61f3f}}, + {{0x000628f163be6450,0x0005cd9c95d766bb,0x000f6a04ec28e610,0x000c81dc5fc2b063,0x0000b71137ccd020}, {0x00075183bdc05d4a,0x00016d6bde53c0ba,0x0004d7c49a68f235,0x0008d99b6b877a74,0x0000336e49572d6b}}, + {{0x0007024b4657059e,0x00054cef3d11f446,0x0003050457ac1b21,0x0002913d9da01ad5,0x0000b9bcb5753d0c}, {0x0007f76845c2dce5,0x00038068a539d060,0x00087fda517cafe7,0x0006476a3fa020c8,0x00005d290857bd93}}, + {{0x000092acd18e938c,0x0000f8464b918049,0x0004df7e752475a5,0x0002fde898e40329,0x0000287032729a40}, {0x000569905ec6b4ba,0x0002cfe346da592c,0x0007a24d3ae26557,0x0001e988692d9424,0x0000d3469d8df997}}, + {{0x000c0c46de1a94d9,0x0001e6f60e7509ba,0x0001814113ff2984,0x00011dee43d289c6,0x000082b07bdc2bd3}, {0x000f143c2c8cc0b0,0x00062d458fcb4868,0x000b290b3fd69d9a,0x000c0ecd23f4d8da,0x00000b05a52925f0}}, + {{0x000d9a283c536a93,0x000606d6de13d945,0x0003f7737b671559,0x0009ba66c6cc19e4,0x00003fc1b1d79963}, {0x000562a67776f95b,0x000cad8332c80b59,0x000985a2553fa97e,0x0007a0d727ab42a4,0x0000e8b82ed15b64}}, + {{0x00038e15452a1658,0x0008ec07d0a74207,0x0007878830171954,0x00059bac99ed3f63,0x00009f0f97c7517f}, {0x0001965ce020f57a,0x000438613db8102d,0x000c51ab225ad31a,0x0005e2bff0e582c6,0x00005ddc35e3ae14}}, + {{0x000fd23340796b5e,0x000244ac37f7a6da,0x000dbe23ff187911,0x0002ebb7c0ba278b,0x0000966a8a7ef6ac}, {0x0000656ed69c1c7b,0x000dd0d9607f7b6d,0x000ad9bd90340e14,0x000f7e0e40027a74,0x00000579cf7ce74c}}, + {{0x000a4a6a443029db,0x000d35ade4c87e84,0x00062de4100e89ee,0x00097010cdaa8575,0x0000847c3b75ba72}, {0x0001ce999ab945cf,0x00008688e09a9735,0x000d23c79201d508,0x0006dc217c5b0e19,0x000019d1d199e64f}}, + {{0x0002e32a7846845b,0x0008812fb2a589f1,0x000e90b88698136a,0x000814075eeda86f,0x0000f51b3d5754fb}, {0x00051260155595b0,0x0001d15da3c67d16,0x000140e2d64ddbfd,0x000dc7d8b5f5f20c,0x0000f851ed143a53}}, + {{0x000a956daaf5fc5b,0x000e309911eb23d1,0x000ec8c6b1504ee5,0x000ae12b96b7e04c,0x0000b90457102eb7}, {0x000f92df9e505e56,0x000f4a99a48ae2ee,0x0009af17826cba30,0x000679b8bbbc3531,0x0000173fb3989c78}}, + {{0x0008c28d0d5a2453,0x0001b72c3ae14d66,0x000253ce4f0708c7,0x00051484000a3ec7,0x00009309c4f55650}, {0x0002432cca3eca7f,0x000ca9872fce7dcd,0x0004a7f072317326,0x000e46d7d6868a46,0x00002b388e557070}}, + {{0x0000a1cb9e317b0e,0x0007686d711ded9e,0x000795851809a425,0x0008f153b3f1818e,0x0000d86c68fea802}, {0x0006abf4b7386739,0x00066a8acbc7e643,0x000a1ca448e39d09,0x000f6b81ecba6cba,0x0000b3922a40e4a8}}, + {{0x0002eda200d56537,0x000c11407fd1b8c8,0x00026245193f49e0,0x000b4f9680d4a834,0x000087c24bcc7dc9}, {0x0007394081d392c6,0x0004a065b74266bd,0x000b68e1b771b55c,0x000ad0c13127dd7b,0x00004fda7e5cd833}}, + {{0x0001b8779c1d0b47,0x0005ec5490f634d9,0x0001f8d01b7ced9f,0x000168ad06fe10a1,0x0000d38933d35353}, {0x00083efd496b859f,0x000068aafd56bb9b,0x0000ab4c451c3d2d,0x0001760199f69b45,0x00004f69ed69d503}}, + {{0x000d12f2dc71d6ed,0x00042873d131f911,0x0002f868f327b8c0,0x000917defbabf904,0x0000be4cf0dfeea9}, {0x0003a085c409e88a,0x0009aeb4bfae3400,0x00086f86c0eb81fc,0x000f9a5b91f6c11f,0x0000e0a0c02204ca}}, + {{0x0002d3ae9ccb3990,0x000a386ea321f4cd,0x000d286fce5d33ba,0x000d3cebb04af8c4,0x0000fed10ee266ab}, {0x000e7bc2e8e31050,0x00057520aee8c544,0x000ce0a339acd068,0x00016a6f230a6ff1,0x000075e1ddd84516}}, + {{0x000487cfa067d791,0x000998485f2e74ba,0x00090c71ee89da30,0x00025626b84584f9,0x00009454c2a51886}, {0x0004c5dd0d1b619d,0x000adc58a1b4f365,0x0006270fe416156b,0x00048f3ee0862486,0x00004e631cb6096a}}, + {{0x000d441dc42369c4,0x000382251bd526ee,0x000e37dea0d84bc8,0x000584bd68a92370,0x00002e0d68345dda}, {0x0007c227fd8dee47,0x00048d0a275abded,0x000c3b0af42e5ba5,0x000cc19c02809fe4,0x0000921ff2645404}}, + {{0x000de9f9684495a6,0x0009aeb8877a37c7,0x000d90721210b3aa,0x000e4725d8d1ea9f,0x0000a2fa64d2282a}, {0x000cf23abf5b2492,0x000693d5625863c4,0x000f2269b836d47c,0x0009574447f14d0f,0x00008a199e166c12}}, + {{0x000f1b41c43f8b0a,0x000c5c92e76aa8ef,0x00075e03be67ce10,0x000c96b9463a7ff1,0x0000c9d06afed35c}, {0x000b46fd3cde2980,0x000abe85c9d9c413,0x00090aace2da8075,0x000e0512bec57f1b,0x000053813aed6f3c}}, + {{0x0002d5a447d4f496,0x000f4cc8b20d45ec,0x000418aa14176c8a,0x00046f0dbfab3afe,0x00007f1b0c286c98}, {0x000399890aae6ec0,0x000cfc7435ee3b17,0x0004406fd3b6b369,0x00040be2ba195cf0,0x0000499740616294}}, + {{0x0000732badc26dd7,0x00095818d5141997,0x000bb5614607b7d7,0x0006880fb44d9c8a,0x00002af102cfc840}, {0x000ac0001b8ab28c,0x00095c267369f525,0x0005973685ec0685,0x000bfbaa025f9a67,0x00003dc0b77f0b1d}}, + {{0x000e6447298e5722,0x0009fd0c41f0b8d2,0x00063b53dd21c481,0x000fbb57d4fc248c,0x00007b8a669230e5}, {0x000412928c65556d,0x000525fd21fda1cb,0x0009148934fd899b,0x000cb3873e258005,0x000018bdfa0f4f09}}, + {{0x000257a9696db0da,0x000c6e1ebe6be7ab,0x0000ca7d82e3d900,0x00097095c69765ff,0x0000d64c3bbe074c}, {0x0004df32910ad555,0x000467cc458a6d2a,0x0000c4ac0377e6db,0x000f1093e2b3b04b,0x0000049f7467348f}}, + {{0x000169e23b854731,0x000c33e4abe5efac,0x000fd974f020f438,0x000a0585fe459ecf,0x0000dc81273d088c}, {0x0008b457450c4b5f,0x000085537b7106ee,0x0004064b559c8970,0x0008ed1e0bbc258c,0x0000c9e438969c32}}, + {{0x00002b120b62bc55,0x0000bc38a5440b51,0x000dd5bf16b581d6,0x00073e09f25725b0,0x0000e14d4eb778a2}, {0x00040298b8f7908c,0x000f4748986c1100,0x00095285cc66b0b9,0x000f606450bf5cf8,0x00008763246fb0b2}}, + {{0x000225d3ce00fd73,0x000562eb7a0a5fde,0x000b4dfc8355830b,0x0001747a548d6584,0x00007847c613610e}, {0x0003b60593ab7bd1,0x0006627b0acd38b0,0x000dddee8f6a141d,0x0008febdfc7a5ff4,0x00005caefa8d4b00}}, + {{0x00062bce0697db84,0x000364744ceaf19b,0x00056d73ed4ae9f0,0x0002e794e38b0f08,0x00001b958bddc911}, {0x000e012417427134,0x000459f114d48028,0x0006a3400cfc75c0,0x00058727f66fc710,0x0000756a6e62a482}}, + {{0x000219fe0b28a503,0x0006d50aecc17ee2,0x000b2435a97443af,0x00001d69d66a83c3,0x00000f96b615a755}, {0x00081a62fb7e0fb7,0x000a7c62b16f41b8,0x0005def12d53a09a,0x0001ef4471c81af9,0x00008288a92a8022}}, + {{0x000c8e03ffcc6378,0x00014bd82b7e98ab,0x000d883a9ce80865,0x000c6a7adb20e161,0x00008a1096cab53b}, {0x000e056288dce6c5,0x000cd762fbd62fcf,0x00047ac13d2142e1,0x000347c471a47759,0x00003efed5dffd1a}}, + {{0x00071f160d9b4fc7,0x00068ccde2a4414d,0x00076c3b61dd617f,0x000e354a6e4e01a4,0x0000394adf687f7f}, {0x000ace232376e7ce,0x0002f140cec9de0d,0x00033c69dda8f7d0,0x00032704299d10d8,0x00007b0ca9ef9df4}}, + {{0x0006175bbdd36444,0x000a4a9f510cbe77,0x000b49c3438fe5f8,0x000aa894881ab300,0x000081360b1cd545}, {0x0007e5993bcd0e48,0x0006045c198c176b,0x000dafcbc3541e85,0x00011a7fe785de3f,0x00001e918704e8ed}}, + {{0x0001b16510a4e3db,0x000cec6d1df534ba,0x0003cf6dff71bd1e,0x00007410def81561,0x0000e0dc1013565e}, {0x000f21a48f9585d6,0x000c6f1ecde37262,0x0000bf75a4803ebc,0x000ff11f11cb9818,0x000073d6d772e7c1}}, + {{0x00059115abc00ba2,0x000cb26283346405,0x0008740e0a87969c,0x000d13385833ae70,0x00005dac93f5d8ac}, {0x000474e1140c01a2,0x0006c16df16ac717,0x000f357675f37a81,0x000ca0828679abbc,0x0000ea1c1b3e843a}}, + {{0x000e6660da9a2e5c,0x0000a16aaba8f9a2,0x0000b0f1059a100e,0x0009bff504cde526,0x0000976e00939024}, {0x00047a5c49758124,0x00088fcebc829f02,0x0001304805038f43,0x0006e00b76e9a157,0x0000a4de4f473e09}}, + {{0x00004366e61d6724,0x0008876389533579,0x000a479bbe7f7414,0x0009e747e452682b,0x0000eaa1b7c1fe86}, {0x000039271078dc74,0x000ee3d381ab86d8,0x0006994cd10f6bc7,0x0008a6b5d9fbe311,0x0000aea87c1a2a42}}, + {{0x000ab7ba68c31022,0x0004f457d6aca783,0x000dbd1c13359695,0x0006f46d44d935d3,0x0000ddba6dd9dbfc}, {0x0009cd2d080265cd,0x000149797b3be503,0x0002299249e3b52b,0x0007bc0e30ffc768,0x0000209779d3d5e1}}, + {{0x000f9ce2a49386cb,0x00068985f70cff66,0x000479f3b00cc1ad,0x000fbdbdf292f316,0x0000fe7032ecf9f6}, {0x00019d7e849d0bd1,0x000249cfa039b34e,0x00027fcb6b7edb80,0x0008ff327d2e6371,0x0000d2b6d3758911}}, + {{0x000242405e3c60ec,0x000e43c80b9566b8,0x00010ea9d9b080a3,0x000e2687f432ff7b,0x0000ed8dcda9fac5}, {0x0009b28d87f8b2a0,0x00043ca1256e54e6,0x000a8cd15700f2af,0x00073f0b2cecd0fa,0x0000ed3ff9133f72}}, + {{0x0004550dc5a3b02e,0x000f5412342343c5,0x0006db191c975ce2,0x000a20f3bd209a9c,0x0000ef49682be20f}, {0x0006351ac6c47b86,0x000ab813a62241b8,0x00015ecebd6574ce,0x000f1186751398fa,0x000028d91f9cbecd}}, + {{0x000f6978b74df5f8,0x0001129ebc5501ab,0x000b5901ba0c64cb,0x000d8e622dcdc072,0x0000ebedc46638d2}, {0x000a78bab0638bbc,0x000e9c428abdd0a9,0x0008a8ed5636732d,0x000dc7c12d1f0e06,0x0000c1be2ebfb1cb}}, +}, +{ +/* digit=21 [{1,2,3,..,}]*([2^147]*G) */ + {{0x00041c6aa03286f9,0x0003770815b0f7b0,0x000348c284d38d56,0x000cd5c0fbd016dd,0x0000353258e98148}, {0x0002a661efd9b9ba,0x0008dd5eaf283913,0x000595edc99487af,0x00040c2b55829810,0x00008f3adaa1cb10}}, + {{0x000dd15cc4abcc6d,0x0007acc11a85a0ea,0x000e38c7cfb75800,0x0004e9a4844f7d00,0x00002e87f21868ef}, {0x0006dbfdafb2737d,0x0007c78ecbcb6bf4,0x000c3294b6571d8c,0x000d2861c088a49b,0x0000659cbbd569a8}}, + {{0x0009b01652619368,0x00097cc76f780883,0x000ad592edff2cc9,0x000558427112d204,0x000052f6c13013db}, {0x000b41e1bc721e44,0x00022128ce489bbe,0x000c29c730081266,0x0009efd2b1381a99,0x00009dda36961899}}, + {{0x000a8efe8dfc0aac,0x0009cb206c5feff9,0x000e08f69e7003e0,0x00088bdcea678c07,0x000046cbfbe7e7fd}, {0x00081f0181edacd6,0x0007c93bfad4cf46,0x000166e29a349916,0x0004fc2da8f82140,0x00007573537b65ff}}, + {{0x000bebd8693c0ce2,0x00010dc55e193bc7,0x0000e0dde6b99ca8,0x000d3d417badbf94,0x00003a2ff7257f49}, {0x00060a0c7bbfddb5,0x00081c1118dfd409,0x000b93b5a839109c,0x000a3b4702087141,0x0000534d9835ff20}}, + {{0x0004d062b05c59a2,0x000f5879c926f51c,0x000c6face7f545ea,0x000d0985a415dd36,0x000001497b737669}, {0x0007660300e35aab,0x00062195020d6f9d,0x000f8f2766a25988,0x00016e4edb995fe9,0x0000e827d9aa3b54}}, + {{0x000d3fcce93a152b,0x00024b91cc4b50f5,0x000d575f2dc97aea,0x00082a9bea228491,0x00000b0f559c3e87}, {0x00059372ba709ae1,0x0003193c52d9a904,0x00023ee401efcc7e,0x000302d47c1d80aa,0x00002c8592c8fc92}}, + {{0x0009708665ae5753,0x0005c56a03be8192,0x000d0ebf2fcec8fd,0x000acbb56af2db74,0x000082e5523113ae}, {0x0003f42e6dc35a1d,0x000e073f338c297b,0x00031eda91747ee5,0x000685f205a68c1a,0x00005a4916714ce7}}, + {{0x0008f1dbcd1c229e,0x00061773f6f1844d,0x000b29bcde833251,0x0009f684f808b930,0x0000a5e1fcfc8609}, {0x0009762c3a5334b6,0x000547b852bd1766,0x0001805b9b973ca7,0x00035282b13c8977,0x00005ad0b2362ab1}}, + {{0x0005af1b45cdc26c,0x0000c675c4635dcc,0x000b44dcd5bf1c0a,0x00064f5a3a7131e4,0x00004f42e03a4878}, {0x0009d8e6279a73f4,0x00083cfb4946f6e0,0x000537fe046fcce8,0x000d988539949b2f,0x0000ac6abd6d779b}}, + {{0x0005d5a30f177232,0x000e2df357dbfc95,0x00019bdcb3d911f3,0x00080abc003ca457,0x00000224695fee54}, {0x00070ac4186c55f7,0x000970319fe286f7,0x000f87d49b139392,0x00060915c89b2e48,0x000098096c2f2b08}}, + {{0x0006538c7cd583fa,0x0007504a26b85672,0x000751b6cd45e59d,0x0007acf63fefec94,0x00006952679a5609}, {0x0005299959d65ea3,0x000bf04521f25d19,0x000bd9b1bd07cbc0,0x00070fc519431095,0x00000659b6ab7a79}}, + {{0x0007da91e66c9574,0x000db441e739dd4f,0x000fb78e063f2620,0x0009ce36edde855e,0x000048530862d43d}, {0x000d326b7f93428b,0x00051bd23ff3de67,0x0002465efd4d3577,0x000e73c428efd466,0x000015e8b1961a78}}, + {{0x0002b67847e6ed6e,0x000e4c4145b4f3a8,0x000f47bea8e5ec4b,0x000709c101bbbe13,0x00009d64c85e6167}, {0x000258b265c6bb03,0x00052603cb62b641,0x000250984d93deb8,0x000184b5dac1f036,0x0000af93396d0909}}, + {{0x000454335c724255,0x0003604c60816548,0x0001f152c66dc7e0,0x0009f43ccde48316,0x000077cb80034588}, {0x0001b1a2abd9c810,0x00068976064aced9,0x00035e3f6e20d90a,0x000233aa7895ed69,0x00000b721fe71914}}, + {{0x000d5d2047e6bce3,0x000c5f2809e64a06,0x0004d29f57d77556,0x0005ec248cb3669c,0x00008e7d6893f712}, {0x000931b877a115c3,0x000d470ee473cb67,0x000837d7a680ceaa,0x0004ffd6fb968f2c,0x00003fd042aa3584}}, + {{0x00064b623466f8c0,0x0008b9ac46b1538c,0x000eba98de2d82a3,0x000aec359395681d,0x0000ec5727adf754}, {0x0001f29793223a53,0x0004f341230b56ae,0x000acb4a49d60698,0x000a48020fcf8ecc,0x00007f03e722fa1c}}, + {{0x000ffae3070a4cd2,0x0006c399579ec252,0x0009c2399abb8b5b,0x00058f54502d33d1,0x0000d2a871f20c1f}, {0x0005a7fcf9b1e2ad,0x00026c80ecd64f25,0x00094c286464daa8,0x0007fc8c2edbd839,0x000055ea342cc28d}}, + {{0x000e3f38fa4d2ebb,0x000a628413f152d1,0x00063d684664336d,0x00099a6d07b3bf0e,0x00002d0a21e1fc6a}, {0x000404c2235d7455,0x0000aeab84670292,0x000ec318fdc3d200,0x0005e4ed594202e0,0x0000b11acb9c1288}}, + {{0x00046804810695a3,0x000de9ba648df863,0x00051c17067ea77a,0x00015a8eb8039779,0x0000789adb2007f6}, {0x00094251845852f8,0x000597dd3f5a4cf4,0x000e0ca98f3213e5,0x000cdfe4111dea4b,0x000092e80e45f558}}, + {{0x000a77ccd1cefee3,0x000ada8387b76cec,0x000d53bdf4c487a2,0x0008553f0ee08fb0,0x0000ecf034e8072f}, {0x000d2cf4f5b884c3,0x000eecc4f5c4d598,0x000c4b8e274becd4,0x000fe18c1cf74be6,0x000033bf7648e6a5}}, + {{0x0003309c7f4956c1,0x0004bbd8072c2e72,0x0007386ff557979f,0x000400bd4c7d2735,0x0000d3097df1694f}, {0x0005419b24eddf2b,0x000fdec834dd8149,0x00008eb07ebf4b08,0x000944251b925cec,0x0000cf5bd49c0873}}, + {{0x000cc2b7fb7521cb,0x000cfca0448c3e29,0x0000c79198983000,0x000fa291122a2253,0x0000d819e4970366}, {0x000f14ca4bc473dc,0x0009d3f09a14b90a,0x0007cbc4041d07a8,0x000c0822fd840600,0x0000cc4468dc6484}}, + {{0x0008e2d3ac836bc5,0x000fa9f064bbcc21,0x00031a1b07517bc7,0x000b9cf6d996bf89,0x00007baa282710c0}, {0x00003689803b8618,0x000b9bc669415358,0x000927d51b0e7c4e,0x000917e22409c259,0x0000bd3b557da0b6}}, + {{0x000c21b01b14908b,0x000de4a8a31f4d7d,0x0009e8787bcbe4d4,0x0009e9ec73c5ca1a,0x000065165667e1be}, {0x0005566f103c7aad,0x00068820ea33101b,0x000afa05ad1acf04,0x000445b6f0613b7c,0x00003aa0c574081c}}, + {{0x00087a329c8ed384,0x00092d62bcbb14af,0x0004e3df6cf9f17d,0x0004809f2aca4e9d,0x0000ccfeca144a51}, {0x00041c1043c54414,0x000eaa7c807bc51f,0x000cfbed8d9c0b13,0x000f8173166f05f5,0x0000edbf62fa73e0}}, + {{0x000fa8831a8af89d,0x0007f4021d8aff5c,0x000dbeefd7a8d79a,0x0003ee6c7dc72f5b,0x00004336006bff0b}, {0x000e58807631b0f9,0x0003b6ca73f467c0,0x0002ef220dd8f222,0x0008681b33098d75,0x0000a8d5cb00940a}}, + {{0x0003a4465384338c,0x0002212dac4e37c8,0x0001527f99ca46a7,0x0007381b651de843,0x0000c4920dfc4a73}, {0x000defe279009365,0x00039c537acb711e,0x000d3684b5f0845f,0x000b186a2879fe49,0x000022890953f9ea}}, + {{0x0001888a21d8062f,0x000e6963bb268fdc,0x000fec2167faac6c,0x0000b12e8fefd495,0x0000fde1d1fbfc68}, {0x0008c3a8ac6e9251,0x000f165cd203fb4c,0x000da224da3bcfee,0x0009c76f7dcac95f,0x0000d2bc8ba06270}}, + {{0x00089f169709f64c,0x000ac1b2dac6c136,0x000f04db98b2b71f,0x0003d6ff19b52803,0x0000984ae8728ccb}, {0x000b07419ce76448,0x0006d40a72dd7560,0x000ce49974f769d2,0x000dc4f4b5d8a990,0x0000484a9d5d3a20}}, + {{0x000d0288e3a46587,0x000ff69f35c7af94,0x000ef3387d56412e,0x00038a84fec04a52,0x0000600f11d74aa5}, {0x000b58c2b1ee7fb6,0x0002d3e464c1a9a6,0x000491727fa92dac,0x000d338d06f7e0e9,0x0000c00602b9dd0d}}, + {{0x00025ec2a0a97736,0x000894c54fcb0993,0x000c79b1272a0fd3,0x0001dcc6d7533abd,0x000003f49dcc0749}, {0x0002691f11601ac4,0x0004f081e7ff4653,0x000af4c3b359a421,0x00031b5ba1c105b4,0x00008a6b864d6305}}, + {{0x000fd57dfc2a81d6,0x000625b39bc719c1,0x000bd95af6db2f85,0x0003bed53048b27c,0x00005b3082cf3fe5}, {0x00075165c86fc86c,0x0002759020878e09,0x000c8d6462169c4e,0x000a7ec795ff10df,0x0000740ea7b723b5}}, + {{0x000c734b07d5d331,0x000c0fc9ac292c4e,0x000275f2fa5774f9,0x0005b64cb6519644,0x00000932f708d9dd}, {0x00099e5189916537,0x000dab579fa96e9e,0x0003d581a498ab6c,0x0008466030186ad2,0x0000487b0b95ef84}}, + {{0x00035b4387096d4f,0x0003df6e71b2ea65,0x000937553df75f29,0x00010b31d49965f7,0x00006c0c5a717d4f}, {0x0008a025671103ec,0x000e123bb180d8a5,0x000b43b65a239855,0x000f61fa25b52a09,0x0000f771fc550da3}}, + {{0x0001111d075e5253,0x0004096fe18d6290,0x000c240dc07656fa,0x000abcb58d552e84,0x0000e3c9762d4f9e}, {0x0005b0b103502350,0x0009f566340da097,0x0004d4fa8636d51a,0x0005251761de667f,0x0000e20349d77617}}, + {{0x000804e04fc602d9,0x000ef28a89d0ded4,0x00086f1cd8ffccc5,0x000cc149f28d2957,0x00001630741537d4}, {0x000f2ba70b640180,0x000b39ff8919aa63,0x000ddf64f6350c9c,0x000ed9819793e411,0x00009e24759c0d79}}, + {{0x0000f19f4fd5dffc,0x0001ceff4bc9c7a1,0x0008f73cf0116b0c,0x00061f4e478201cb,0x0000d21b82382518}, {0x0000765f0c491b5b,0x000013baad4faf40,0x000300e32e5639f7,0x000d8d4ad69ae26b,0x000039328a470b33}}, + {{0x000c84a820e49c2a,0x000632dbefb4207c,0x0003a58a5ed4c55f,0x000382bac82b1f88,0x0000b15eb7c77391}, {0x000f20e1f1265f7c,0x00061058e88c9ab7,0x0006384f1cf8b862,0x0003879fb6321663,0x0000cb9aeb634518}}, + {{0x0008bbf43ae6df99,0x000e2d6ab4528524,0x0005334bce88a401,0x0008055ec2fa9a47,0x0000d4dca87805f4}, {0x0006ced09a787cb1,0x000d0999c03d5db5,0x000b45d8fbfd1741,0x000babb6f0173a87,0x0000a2096bb2323f}}, + {{0x000a21bedb16d4bd,0x000e6b75d1d16e09,0x0006bc64045b4bcf,0x00039d063765236c,0x00000a23f6f637d9}, {0x00074751ceb98088,0x000dba263631ffca,0x0005c24d5fa3b792,0x000afdf1a7fd6b25,0x000059077c5a10c5}}, + {{0x000da27ddfed9085,0x000e4268009b9ec1,0x0004b5d55add639a,0x000c645ca7d97f79,0x0000f7c88b1f440c}, {0x000dd0e67085ac15,0x00091a87c0cc8497,0x000956ebd13e13f9,0x000f43f208267e50,0x0000950c4ee3dc87}}, + {{0x000767687730a906,0x00086fc6d094b775,0x000902ef6b5667e3,0x0004940ab659cccb,0x00002c5c7ca26500}, {0x0007b7f151927dcb,0x0003251daf1587c1,0x000e13028bcd4fe6,0x000bec56ed9812dc,0x00002b1a165bd153}}, + {{0x000922b16d41f3ed,0x0003171dcd2ee6c0,0x000fb901db1d6685,0x0003a9ae9e9a3b18,0x0000fa1c572a62e6}, {0x000eddd1acbe3647,0x00057c3b62c81e6b,0x00095ef93b30ae10,0x0007c242fa98c96d,0x00004313bd27d329}}, + {{0x000590d655a44d1d,0x0007a791be183844,0x0003d3938484d868,0x000d526b8e7d0675,0x000025aa4d1a7d94}, {0x0002fc193234941e,0x000c53450cb67e66,0x000dd6fd063acd11,0x000fb3683bb3f0a6,0x0000017b88e1cd67}}, + {{0x000dfe137bc4a4d3,0x000a6f70d1220567,0x0005d43015bd4b27,0x000073c03a5810f2,0x000038319b9cc364}, {0x000e596aa8cf3d1b,0x000eff7eb1c9ff82,0x000b8e2dfd434646,0x000515518b703e5d,0x00000fd92c1335d7}}, + {{0x000f2ed01b9068a2,0x00003e0f5e11999b,0x00081ad391d14a72,0x0000ec9e891cb005,0x000034d551dfbd27}, {0x000e3e94269c7442,0x0002bdf2d623f98c,0x0000ac69fcba079f,0x0006b8e6df04439d,0x000094022be24a1e}}, + {{0x000624f1ce0f1e4d,0x00066318ff1e2b3e,0x000cf68fd9152d17,0x00026fa5d91b3a87,0x0000450cb4e504c4}, {0x0006852e3c9f1ef5,0x000539195d3f5568,0x000858b621b8887c,0x0002f2742dea5594,0x00008e75022bf2f9}}, + {{0x000b07bf5bdb8d74,0x0005adfca4449042,0x0002e1d1ead50f78,0x000484f785f4721a,0x000049993fef7c9f}, {0x000c8c0c7eeaa416,0x000b7f465774cab3,0x000a78325aa244d0,0x0000243470b1e003,0x0000822e9e020093}}, + {{0x000c845fa39fbc60,0x0002293ec4ec1d40,0x0006379a019debff,0x000755eda9d51a99,0x00009f94dc7743ec}, {0x00010b3843c61a6b,0x0009f974867d68ea,0x0005dbef26fadbc5,0x0008f2b3e875258e,0x00006cb8dd761e1a}}, + {{0x0000ad3ad5e6e384,0x000e291dd98cff89,0x000718231c43f57a,0x0006f21945dfe8c7,0x000061970b97a133}, {0x00082cfd677dce23,0x000f52f49f824e05,0x000b7784bdd02efb,0x000b85cc1c90ef12,0x000014d0c33b781f}}, + {{0x00060c791130be5d,0x000a3b5dc85a2ad9,0x00089ae96957ee66,0x000500bf4143b0b4,0x0000de968fbf16d4}, {0x000480887ad52fa6,0x0000d040ca0e6706,0x0001fc876898a967,0x00096b92364ae69e,0x0000dedc76278467}}, + {{0x0003de2fb18ca7df,0x000864975906c34c,0x0008c99c77a4177c,0x000744f9db29337a,0x0000758b714ec06b}, {0x0000287f5082885b,0x0009f9b49e575a58,0x0009f2005dcaeb2c,0x00057c4f90329a9b,0x0000e7c828178ce3}}, + {{0x000070cd2e84852f,0x000127c1c04293d3,0x00082b797b024206,0x000ae76c1b1ad1a5,0x0000f75b079c03e1}, {0x000e4e6207b73a21,0x0008751ccacd3daf,0x000a230c168e33ef,0x0003bebb75b39a80,0x0000ce273b967045}}, + {{0x000e4cf7ea2bf1e2,0x00002aee47c0de34,0x000ad4d02064992f,0x000d96aed6f23dc7,0x00000258e1fb9565}, {0x000d4dca99aff602,0x000578622da2f6bd,0x00013f2c376d4555,0x0004856bed645115,0x000023c2392fbfc8}}, + {{0x000c65742561338a,0x0000f335e54959ea,0x000e714b02e99bd9,0x000531924d4cd35a,0x00001199bd5dd95a}, {0x0009f7a238d15ffe,0x000e09222be15441,0x000374b05d41934b,0x00061df1d9a1aed2,0x00005508ba021f85}}, + {{0x000279df95030f56,0x0000f9ea1ab0d177,0x000f99992a351c3b,0x00064e9220c44b6d,0x00003455043e8fbd}, {0x0005de277b82a5bc,0x000ac3b68530cd38,0x000ca086694c0653,0x00063ce81e602ff2,0x0000ef40f405268b}}, + {{0x000b7c3a8d2bbe19,0x0001bb32fc4ebdbc,0x000caf9eea029867,0x00095c27a58c50c3,0x0000c0ab3cd9d1bf}, {0x000e9607ac0e8a6e,0x000fc1426abde891,0x00074904b992b549,0x000b98a3dd1a72aa,0x00003c2e33afdede}}, + {{0x0000a5f93a4e96de,0x000c85e5eafc25af,0x0005a62bdb7ac424,0x000558424b99e578,0x00003c24c7e4a4ea}, {0x00094a38275f9857,0x000c9c7fa4275e32,0x00081251fc7ef065,0x000800bc303dc5a0,0x00001f0537c463a9}}, + {{0x0009bd0faab7ac3d,0x000e80f256cd6560,0x0001cdf6644f220a,0x000341d90e8fe916,0x00002d221d5ca965}, {0x00019a678ae67ba6,0x00030f33b841d032,0x000d5af5d16ce5f4,0x00070b06fcd2214d,0x00007fcb30a9c986}}, + {{0x000c6d4993412281,0x000466c0976b7162,0x000e48195e68d8b7,0x000a7c3a400a9f5d,0x00003f11324f1feb}, {0x00068a9ee5214a73,0x000895b4a3f14392,0x00035066970be472,0x000438b2cae53e6e,0x00000e849079c7c8}}, + {{0x000ab4705ac23184,0x0007e535509d183e,0x0001a9d696cd87c5,0x0003178c8f88a2f8,0x0000610bf6f3760b}, {0x000d814c4dca8a05,0x00010f8ceb1157a8,0x000537398b47d20c,0x000424fa8d6446e9,0x00001fe7a476cec4}}, + {{0x00072bb2d03ec2ff,0x00025023cd075ac0,0x000d7ecf72f0f3d6,0x000efca8d8dd2d56,0x0000a3d270a63597}, {0x0005bdb8fa49c984,0x0003984320dca40c,0x0004211099e72bd4,0x0003af1f17bff561,0x000078129a3f3005}}, + {{0x000cb54f682dd291,0x000a10b13967c1cd,0x0009cda2fbf3fcfc,0x00038cfb00e857a7,0x00003a87c6a0cf82}, {0x0002489b23f1d3cd,0x0009ca41c9084179,0x000f0d3e98ef9e8e,0x0007bab2cdc4e833,0x0000e159ac26b23d}}, +}, +{ +/* digit=22 [{1,2,3,..,}]*([2^154]*G) */ + {{0x000b73dbe429e6f4,0x000c3138ffc05f82,0x000a3b67f590e285,0x0007bcb900484c1a,0x0000aec77b3d8941}, {0x000e442032e0e61f,0x00070b271f75c0ad,0x000b1798d01dbbbd,0x0007e3958d61f8ee,0x00007c8bd0d03ca0}}, + {{0x000e6d0844c0e6f2,0x000c3284a1e580fb,0x000933260fbe850c,0x000f1d49fa978af8,0x0000f631a40a5bff}, {0x000151afce47898b,0x000d97771637ce9d,0x00029ce3be231f37,0x0001bb143714824a,0x00008614e5ed8aaf}}, + {{0x000e80c351d61ae9,0x00034e58cbd057c7,0x000018bc8ecfdb95,0x000c2ca5a58c2283,0x00007d50125d76ea}, {0x000465a381106373,0x00041f1dd517dfc6,0x000184218d7ec5e4,0x000ea6cc1e142bb3,0x0000006ce0efce95}}, + {{0x00003b993a36842c,0x0004ff423a275d4d,0x000ea1fe70c60a7c,0x0001025151148bb1,0x0000be81326d9e64}, {0x0008d837d64990b2,0x000d2db8c89e7194,0x000692e72baae2d5,0x000e8c0dd17618c3,0x00004b6ea9b40d6f}}, + {{0x000fd692bf95567f,0x00053ebad159ba68,0x000340f3a53fec60,0x000ad6552431579d,0x0000df4e7d133f2e}, {0x000144d67c90b92c,0x000167158f063ae2,0x000abd10013a5c86,0x000729b8ee2bc967,0x0000b9abf1b96668}}, + {{0x000f140c73562945,0x000cfe3add38ebf2,0x000df7dbc2a2e566,0x000476e0e3f9dbd8,0x0000ae24bb41e6fc}, {0x0002d58819c1c23f,0x000517b2f5b645b3,0x000e863c8b271901,0x00069def3f6a2be5,0x00008f784e4c8202}}, + {{0x0005b1d21ec38f34,0x000d1346ef526b08,0x0001aaf39a530ac7,0x000336aa7792bc04,0x0000759ab5765fb1}, {0x000d665388e67c77,0x000e31ff335430b3,0x0002f4df0b037e8b,0x000bb1010d23084e,0x000085bacaea9944}}, + {{0x000e2601dd188f66,0x0009e8c268296001,0x0001a9eeecbb5766,0x000b9f7ae1f2b5d0,0x00004069ef9b9ba6}, {0x000798a2fcf1d940,0x00063d59f8620844,0x0009af2a19d2299b,0x00026abee6e38778,0x00001f7192df4bae}}, + {{0x00053eb08c850a38,0x000ec6ad45b295c2,0x000029b17c77b7ec,0x00066724f2c9dfb6,0x0000f4bbf5043f22}, {0x00027dfbadc1cfc0,0x000c9c9b43c55b3e,0x000f3904abe353eb,0x00010196a71e4ce1,0x0000960958fa8fb7}}, + {{0x0002fce77ea0ed70,0x000f5ed5ec66f089,0x000f00db8587d743,0x000085766c95169c,0x00005b6bf27de7cc}, {0x0003e7f9cb37cbcf,0x000f9ff50ac46924,0x000c0bf82abe04a4,0x000e20c506429d30,0x0000cf6603411d09}}, + {{0x00079d7ccf998928,0x00053aec1803601b,0x00023b4297648463,0x000aff355968bc95,0x0000d5d4c0854553}, {0x00057ac873f512b4,0x000cd320d16e1b4c,0x0004ed91186b08c1,0x0003e4608228cf7f,0x00004c70e3dd005d}}, + {{0x00088f1944156ff7,0x00011e971438cb5e,0x000058fa1b18ee73,0x000cdcb89e85f304,0x00006e2f51891388}, {0x000232f34ba5cffe,0x00003843e83b0cce,0x00097c9aa7eaba9a,0x000ece9610dcd10b,0x00009f5f0d594daf}}, + {{0x000986810095f72f,0x0001ac29a7c24844,0x00032e78ed086800,0x00098f626c35c5a8,0x0000d83403c23bba}, {0x000a7f5c20ac35fa,0x000d88d0bbc7266d,0x000e582bac8b42d0,0x000935657786ea28,0x0000bf7fdda51e43}}, + {{0x000de66539c57709,0x00029ab48f57c79a,0x00053b7f7c92d81d,0x0008ccd6929d04ad,0x0000d6805ffa633a}, {0x000c653e3c30e224,0x000a25014af38c1a,0x0000fb9056ff7e72,0x00036e84863461cf,0x0000feff997e9cd2}}, + {{0x0008f4fbfe1bb87e,0x000b234bf5009643,0x0003e08355419bfe,0x00059cb34567fe1c,0x00007cd632f8cfe3}, {0x000b06cf3a3127e3,0x0004a9a97e2d7d25,0x0007d0094b3c4c3d,0x000715572ac1af4e,0x000097c70eb31cd4}}, + {{0x000a30dbbe55bebb,0x000acbe0f0b73fc0,0x000b583ca72ac528,0x00058a26c3397a15,0x0000690f6fc7ed03}, {0x000c62882b679996,0x000a4e77a75d9acb,0x00038d76d9db5245,0x000eece8f87c7f73,0x0000595862fdb1d5}}, + {{0x0004badd8661917d,0x0005007f84c3acbd,0x00040fa3d59ba026,0x0002ed184e937c66,0x00001369d0f0a780}, {0x000fd94d28839e74,0x00021cd14e0c49ef,0x0007442dff19b151,0x0001044685338c05,0x0000b46081f8392f}}, + {{0x00011d53d358e352,0x000ad7cfd455b082,0x000bac2fd8bbbf06,0x000acc8cd30a233d,0x0000d70c7b7f7357}, {0x00026832fec7aa71,0x0005d1d2ead1c40d,0x000b7a761f51ab79,0x000816ec07f749be,0x0000c5ae5e6830a9}}, + {{0x00099bbb81316b37,0x000eee7327744649,0x00036c6dd3fa17e1,0x000cf40d417b7a4b,0x0000cdaf38243743}, {0x00092c6085af8552,0x000765fbc2a4eb0a,0x000a3aabcb9c1f75,0x000715c991d08c04,0x000063b26b5053f4}}, + {{0x000869e8f8653478,0x000498cb16b98bce,0x000bd2b92786668b,0x00070a1e52fd90fb,0x0000fcf025fb7145}, {0x0003105fe53d4b78,0x000c7d1f08cb8199,0x000e90aa136b8d03,0x000adab87b877995,0x0000ff5b8a7416f5}}, + {{0x0006181e6127b8f3,0x000e26986975931a,0x00050fa780fda309,0x0004c9cbf2d51ead,0x00000b52ace1f172}, {0x0007cae0f0e4d834,0x000d5d6c4773705a,0x0003f0301bc79516,0x00008598de8bea90,0x000050e748954ca6}}, + {{0x000313f2b32b8c07,0x0008ad46a7a7864a,0x00071aba203009b8,0x00019786bab2c270,0x00009eea2825dfae}, {0x00022bea3c6feb06,0x00067e299123604c,0x000aa7d5ba6e907b,0x000bc50302538712,0x000018eb27f3228f}}, + {{0x0005c9df43643466,0x000f22a16dea2da5,0x000026ad0fac5dd5,0x0003677c40f2faab,0x0000af1895ff0f0d}, {0x0005cc7072a95ee8,0x0002231880e3d2a1,0x0003245ac109f07c,0x000a3343e7d98a81,0x000053adddb5139a}}, + {{0x000da35f08f5eeaa,0x000b0c8141361e77,0x000274120e93a89c,0x000d2380e4856041,0x00001a55e742ddff}, {0x00047074615459da,0x000a3cae4a32bc77,0x0002bc1e180630de,0x0008995de64b3ee8,0x000066bb84bd1667}}, + {{0x000fde701d4ff7a0,0x0000c53f426d150c,0x000b25dbb8593360,0x000302331d9505e7,0x0000ed1a8e859f94}, {0x000ba4e5e0f86f6b,0x0001e557b53b35d7,0x0006087ef1317fc7,0x00069a1f34ef53a5,0x000023a1a44d68a2}}, + {{0x0002686d46f85357,0x000f2b2aa5adc9c6,0x0002bcd92779e24e,0x000ac2af4f9ea4cb,0x00005036fdea645c}, {0x0009945ac233c5b5,0x00042cd0ab16222f,0x00096a9d0c598bc8,0x000b25254749518e,0x00006f6d06bcc429}}, + {{0x000e2d17828d97f6,0x000a6cb1d21e5e54,0x0002876e02980d80,0x000fdd11debb54d5,0x000002f74e3fc7a2}, {0x000a25518c05c3ef,0x0004a101d6408d80,0x000ed1c406f00af2,0x00036f5c1f6158d6,0x0000932ec7aec045}}, + {{0x0000dd90c8eacd14,0x00051c277d39ced7,0x00037b995a86eabb,0x00069c2d692f5dc3,0x0000aaa65fcbd3f3}, {0x000fb8dac3487ba7,0x000fd9030bc0445e,0x0005b00d8a303975,0x0005ebfc43a8d1f7,0x0000cf7e4b1a80b0}}, + {{0x000e7d3babe2bed5,0x00008ed9aa788262,0x0009ae8cf61b9b73,0x000a2cb8859a7ead,0x000009dd0bff2a08}, {0x00089563be5f62a1,0x000c60b33a1ce2ba,0x000eb11c00b2efd6,0x00076537bfd95b86,0x00001760e857be9a}}, + {{0x000df2f2e4d68602,0x0005e7f162bab259,0x0008073b4332202d,0x00097922f1857cec,0x00001ada3db5ada4}, {0x000feabac21545b5,0x00044b8366fdd7cb,0x000823597e0a8ab9,0x0001b19ca5ad3fd4,0x0000556946280dc4}}, + {{0x00068bc679af7df3,0x0004d09bd4c65b7c,0x000c3d5c8bb79f15,0x000a8eb5a55faae6,0x00000e146d53e240}, {0x000bb5275fa8a745,0x000f9bc67f8fc6e7,0x0004d7d55f437e48,0x000162aaaac77964,0x00008f7b8a4e25c7}}, + {{0x000addb9871528de,0x000efb8f6e9085a4,0x0002b3dce56c416d,0x0009f9352c94a7f5,0x0000cb572963cc8d}, {0x00073bb6f154d061,0x00094ceb155e9479,0x000479f043bcfa01,0x00094fef2ebc01a0,0x00007c190148abea}}, + {{0x0007288c1fd2f6a9,0x0007ccb5f2f0c85d,0x000cd8ddf6f0d1dc,0x000d6d1b46cbab39,0x0000a99e4c52cc37}, {0x0006b442e61e355b,0x000805cf7f7f0461,0x00062ca1fbf6d2d2,0x000a6685af0aca3a,0x000059f9cee65508}}, + {{0x0009830a1370ba94,0x00066f630ed4cc2a,0x000c49043c9c70f2,0x000cda45b0a9a339,0x0000981cac0d3fd4}, {0x000fd2b1537c0568,0x000d2df567bfdb10,0x000f06ee7b678713,0x000035476bfd49ac,0x00007e163ef8dffc}}, + {{0x000a43558915672f,0x000c1ac1fda86ae8,0x00060c9a1cd95a10,0x000104f8c2f7429f,0x00008f5ad3637888}, {0x000c8fcf90898e9a,0x000df624e89346a2,0x000c1fea87fac86a,0x0004b83fd83bf0ac,0x000084646a23ba36}}, + {{0x000f4fb4cc23cc0e,0x000d0fdfd051e92b,0x000f292128680d8b,0x0001f9e822e278e0,0x00007d4d9e59445c}, {0x00015c16f300247b,0x00007aa90db5c335,0x000342a9caef4b57,0x0003e1dcae37a135,0x0000333cb5dfa28f}}, + {{0x000acedb3b302867,0x0007a112c1fd206e,0x000c8ec52d01b8c9,0x000b94e452325cab,0x00009f884b8bdf35}, {0x00097e89f70cf04a,0x000d749d1ae5ecdb,0x00044351436bbabf,0x0008abe4530f2f42,0x0000bb3ffc216d9c}}, + {{0x00001be0aef6af88,0x0003999c0a70d435,0x0003287b2e21580a,0x000a5b6ddd29cc9d,0x0000458091850c10}, {0x0003a83b67e26fc0,0x000ea4f022126008,0x000f9f5f013525d0,0x000f6daa2f518f8a,0x000004d78d00bb76}}, + {{0x00007dce35d51eb2,0x000bd3f986bf114d,0x0006bae418c11481,0x000fad9aa9bf9aed,0x000077c4aa6b8996}, {0x000c111fbadb653d,0x000475bd860ae81c,0x00037b28ab206311,0x000dced3249e29fe,0x0000f13e34b76224}}, + {{0x0000d8d46c6cabee,0x000f1556df1e311a,0x000bc9a29620950f,0x00069f3a256b625a,0x0000845ca024ae37}, {0x000bde60adf24a88,0x000bb4cd5c340731,0x000458b3da58fa82,0x000fbd43156083f6,0x0000e80538fd3b33}}, + {{0x000d5c8a4f806766,0x000e48d81dc67831,0x000430a5bacb70bf,0x000d86bda3b12c13,0x0000e602fe106d61}, {0x00026aa4d9ab33e0,0x000174ef7d6aae6e,0x00040016264165cb,0x000be577ac555a74,0x0000910d31ed147a}}, + {{0x00081f76af0426f7,0x0008410d604b45b2,0x0009a1d45d6fd752,0x000806aa4fbd4908,0x0000c1de40f80886}, {0x000bf8d15847181c,0x000703c99e3ba93d,0x000125e520380a85,0x0007d15781da897b,0x00000c67ed4697fc}}, + {{0x00028041ae87db81,0x0009887b3bc50e3e,0x0003fd20d364a165,0x000aadeb000f0f28,0x000038d839993e13}, {0x00085d6a8b8661a7,0x000b34e820a8623b,0x000eab235775fc13,0x0003ba5f2815b147,0x0000d88868130267}}, + {{0x000d1e00b2843c2b,0x0004df08cfc65f61,0x0008c6f049ce3d0e,0x000d175a3aa4f905,0x00009ff1be643e16}, {0x000c16adf8587d83,0x000242fe78408aef,0x00047747318730e3,0x000fe910dd08eac8,0x0000bef97b69315d}}, + {{0x00099942d00d801c,0x00081d20b58aab1d,0x00083cc49dd642b9,0x000a89b8d67ee603,0x0000d28c6d5ee521}, {0x000f3f9e69075ff4,0x0001d35323720055,0x0007768d68b51dbf,0x0001e7c55669a92c,0x0000298cf352d79d}}, + {{0x000f2548f7c0a953,0x00011d0960107f3e,0x000e0af7bb667c89,0x00064816f354cac5,0x0000d50791b116b8}, {0x0006848e4fd86c6e,0x000c9b7eb17c143a,0x000b947b4f8a167c,0x00060e30ba6169c4,0x0000133e463aa3a4}}, + {{0x00029106d1d6a7ce,0x000ba4385d93bdd2,0x000ee80a9f04f720,0x000132b787a4ec14,0x00004ea21e5863a8}, {0x0000364500d59b88,0x00060f60934a7413,0x000ef1d84166c20c,0x00031d1fab6365d3,0x000088cd5fbaa114}}, + {{0x000d32fedbd19814,0x000221d0419272e7,0x000c4ec059041e52,0x0004de9d2dbd541b,0x0000443d10dc8775}, {0x00078b0d3f94e824,0x000ad40784f9f399,0x000fcf6218b57c8e,0x000b5e55522304d1,0x000047969a949e6f}}, + {{0x00011391108d6518,0x000f28d0956f98d4,0x00002d8f8d2ccf71,0x000b41502b1a4d7c,0x0000df02a4b0a6b6}, {0x000be826697a7400,0x000bbaede068213b,0x000c698316391575,0x000947ceb3b39955,0x000092ee9cb03fb9}}, + {{0x000acdeec1fc6432,0x0002bf85fe71a639,0x000483fcd152b2d9,0x0006a076d90c3e2e,0x0000f765abd75a8f}, {0x000eaa6605b6e935,0x0005d4661347735e,0x000b692ca9771efb,0x000033f6b4f4f2c0,0x00009e887ec099c1}}, + {{0x0000f5f11e1df448,0x00062268eb0e4b3b,0x0007263a3032513a,0x000cc00b41244642,0x0000522b093085dd}, {0x000a4316959d64c4,0x000aece72aeebcb6,0x000a57e25bca4137,0x000a307ad4f570ca,0x0000ea827aee1273}}, + {{0x0001c403871a258f,0x0003c3e40bd72b4f,0x0002aef142a3cf29,0x000c0c94b6f5d42b,0x0000c868d6bb0915}, {0x000fdf303a147183,0x00075f9ac83d925c,0x00078cfb4a2974c2,0x000cc66f8a5e4142,0x0000ffea4657d7cf}}, + {{0x0003d2857b0fb80c,0x00071f7a356b4ff2,0x00028236aa740396,0x00073184ebce593e,0x0000eeb59035372a}, {0x000a4ef592e84599,0x00099e31e3885ac7,0x000dca9f931251e7,0x000405a7e073ded2,0x0000ffaa7091f0ca}}, + {{0x000993353be2eb86,0x000523cb41aea060,0x000f52305f75d323,0x0002da1c19ae132a,0x000005aaaff1356a}, {0x0000b58337d86433,0x000ea1fc9f91fef1,0x0002a47dd5fb33df,0x0009e296da6bdb2b,0x0000d30051c46b7e}}, + {{0x0001396d37931aa4,0x00042fe59d13f6e2,0x0003436e3bc1ea61,0x00095019fd93e242,0x00008077ea00eefa}, {0x000d18f2e5c1305e,0x000ee6a4b029fad4,0x0007af0a58115f19,0x0006774913164569,0x0000f85f4ccc0bf6}}, + {{0x000abfabc6473ac9,0x00076f8f0f80e13e,0x000ca19fb9dad550,0x0000add3a04f0b57,0x0000371e049416e8}, {0x00061632d80ea152,0x000278e8a04dac3d,0x000220d15df178e2,0x00019959c39ef8ff,0x000054bc5557480c}}, + {{0x000faf5f45158e7a,0x000d1f1c1ad0350b,0x000f15bb4fef27d8,0x000e3fc4f652ed78,0x0000166e75983350}, {0x0002cfe2e4cbe8e4,0x0008a56c51d904f9,0x000ec83d02ce2901,0x000b1cbafabfbd51,0x00001176ec3b0b9e}}, + {{0x00085b4bca3d230c,0x000a63179d4ba4da,0x000a166590810b39,0x000b36088f040c03,0x0000773154019362}, {0x0004e8f53d96a2e5,0x000b3ce80126aff0,0x000eca232cc5998f,0x00000d61e47aa73e,0x0000dd3cdf403670}}, + {{0x00055f69d0a7a33b,0x000d34ce0392f3dc,0x000bee0d7944608b,0x0005132e2a2b5516,0x0000cb2be45b0370}, {0x000fb9ef66b067f6,0x000160aba278abd1,0x0007f0556104063a,0x000b4519469ecf88,0x0000d00218f6f0a9}}, + {{0x000775dcbbf023f3,0x00045ef40d8ecd2b,0x000eee1c75c73796,0x00033027bf36185b,0x000082791736f63d}, {0x000d829fc7d15216,0x0003028b4561845d,0x000fbbee37cd94d7,0x00092fad0aff8b0a,0x0000180e25ae0f03}}, + {{0x000f7e62927d7a9a,0x000c839904e36315,0x0005df42f47d356d,0x0009290393e21cd2,0x0000466787630e0d}, {0x00025ee6ced93469,0x000f010090774044,0x0007a7592fd8fdb2,0x000a03dd870e7a31,0x0000e332fd788110}}, + {{0x0009edb975ec2c09,0x0005175735d65d1b,0x00064bc88e72b8be,0x000ef80b4c4c003f,0x00003be7738bb2d9}, {0x0006e0fd72ac494f,0x000ecf9a7a5fdcc7,0x000b1e5a2028d854,0x00097874b4af8b2c,0x0000b21fce5d8966}}, + {{0x00092d9ee6a8ebf2,0x000f26040d80ea6a,0x000852efe4c46437,0x0005037006c5176e,0x0000866683ba0c93}, {0x000bfd0134476305,0x00040e03c13b63bd,0x0008885347ace166,0x0003339702e75cc7,0x0000f159cdfbc73a}}, + {{0x0002a9170ad6789d,0x000d2234dc9ad48f,0x000f2a7d5e25f59e,0x0007a488b843c73e,0x000027897d1cc561}, {0x0000fd3365d34202,0x00012bb48f85ef77,0x00069764c4ade689,0x000d9404b74787a3,0x000055e4a1bf0653}}, +}, +{ +/* digit=23 [{1,2,3,..,}]*([2^161]*G) */ + {{0x000e715ce388849c,0x0009bb7a2d2af7f9,0x000661db13a1607c,0x000108dedcca8040,0x0000b1a7d04a99e3}, {0x0003a8e4d163dfdc,0x0001783f0e3121ce,0x0001fa2958fee10c,0x000e438b956bab30,0x0000a007e991f63f}}, + {{0x000c2bbff739fa94,0x000c017ea854bdf5,0x0007a64f91d3bfa6,0x0000fdc41fb9d90e,0x000083aa0d7f2c19}, {0x00010d24d367c028,0x0004597010d57ebc,0x00032c5579b43146,0x00072bbd8b596396,0x0000ddf287538ee7}}, + {{0x000d002aead503ac,0x000702bbfd247478,0x0000b804d9f4d7e3,0x0002ca633f318949,0x00003505e7867a6d}, {0x000e5d7dbff73d80,0x000335f9e633fe97,0x000ec9aa42cc3a3e,0x00034df252891ec7,0x00004900747ed888}}, + {{0x000d54830481b038,0x000e2747a4cb9b56,0x000c55970078ce04,0x00066e74e17ce4fa,0x0000ea3c99c7fdac}, {0x00047874a0836e33,0x0008462862478e13,0x000af3763a660e33,0x000f8efb8318cfbd,0x0000993ecdd67d59}}, + {{0x000143d1036960c6,0x0001ffe5607a28b5,0x000be0da767df772,0x000db340e2fc542c,0x00007bc3d3e1614e}, {0x0000a909a4228534,0x000df6d0a4402b66,0x00036e7c5f663676,0x000900fa2bc94c05,0x0000d5caab23f5a3}}, + {{0x000c9afe79e70193,0x000d0fec85a37b5e,0x000a360abb585419,0x000883bc10053d78,0x000097415c9102d7}, {0x0000686637dc9a27,0x0004c4b95f42fa66,0x000cd93361d4b524,0x00042e32721d0b6a,0x00007db0d3bdbc70}}, + {{0x000bffcda8b06d6c,0x000713d8d2427048,0x000cd16bb5d30666,0x000c2197309cf437,0x0000a11a6f46e8f0}, {0x0008bc17a71c4e20,0x000a92d41371975b,0x0008eb0f5349e195,0x0002ce43cc3800ca,0x000041f3bf72ccf0}}, + {{0x0001daeea3ed0905,0x000e1bd5e3c53fbf,0x000c1100344d6a8d,0x000e5e4699602597,0x000060ea92b03fab}, {0x000e180e331a3fe2,0x00080a41fd2b20f8,0x000cdb94814472c1,0x0006c8ec624980f6,0x00000f649cdb7533}}, + {{0x0004ac13e9d9a85e,0x000ac7ff9c45703b,0x000329fbf150d4b2,0x0001fe9bfe98b07d,0x00006ef7b3a05b5a}, {0x000f985fb40d4e51,0x00028cdb30c4b3f3,0x00069b998490bd1f,0x000ee22e2266c121,0x00005d8c7fd5c464}}, + {{0x00017c9deb217fde,0x0000d74da8211aad,0x0001d8f1f679025c,0x00046eae0861688b,0x00003593982918fa}, {0x0009d1bfbf4ff519,0x00072a742f2a69e4,0x000bc2636c0fae9c,0x00046b33d049c63c,0x0000197ec842285d}}, + {{0x000624c23eaa251f,0x00071318ca3c4e9a,0x00095832234ba387,0x000151f4edec7eb9,0x000040bfde516f7b}, {0x0008fa54043404cb,0x000a18aa5c602ed4,0x000ae3268e047506,0x000d7eab79eb8def,0x0000d3b0628dd6e8}}, + {{0x000c4cbd66e8fe68,0x000dc69d604cf338,0x00037b6dd97e28fd,0x00035b246f37d007,0x00000272666649ae}, {0x00093d37810cf944,0x000a459f78ac9a38,0x000ce165aabf2ebc,0x000d640453946fae,0x00008fa3bf971e87}}, + {{0x000b48a8dba5c4e8,0x0002279adf9d8dc3,0x0000634c4f3162b0,0x000b99b53c9ff728,0x000007d5d4dfaa42}, {0x000ff5483cd41f20,0x000f99d21f8d8aa4,0x00081bda1da27bb5,0x00014e9a023684cb,0x0000f7ca6a09c875}}, + {{0x000567e48aaf12a4,0x00072c6ad9edf914,0x000cbc02cdd34885,0x000546ad9d3126ff,0x0000421b423fa8d3}, {0x00006150c5383199,0x00071eb71f6ae471,0x000ba9109ff4978e,0x0004c14e33185f0d,0x00001b2adaf1a25b}}, + {{0x00022a2429dd8dec,0x0007cd18b13b0a91,0x000b0ceea09a2c07,0x0003e4cfd65c5719,0x0000c9bfb6cc8897}, {0x000ab8bb6da6f448,0x000361113f5c0f75,0x0004bcd4ce388639,0x0009b3c84e7da532,0x0000c1fd90d251ff}}, + {{0x000043aa2a095bb7,0x000f9b9f786a3956,0x0002db051d57f81a,0x000149260ef94740,0x00007bf6371cac51}, {0x0001f2f5c58d7ca4,0x00040f7f7b148a02,0x0007371672527386,0x0004b3f38f333829,0x0000dd7a77b276e8}}, + {{0x0005457a7eca1884,0x000cbe9cc41123f9,0x000136109bbb2c81,0x000d931b767fb526,0x00007e27c293ef66}, {0x0003f2073a6659c9,0x000dc1c5bb8bcb6e,0x0009084018ee6a36,0x000ecce3dcbff9b0,0x00008f3df8af2dc0}}, + {{0x000d83214c8380e8,0x000a3ec7ffe0ad3c,0x0000a2a618aea404,0x0000c47d0790d1b1,0x00000273e67906f3}, {0x00015287e729a739,0x000c7793bec7e17d,0x000acf922b6820b6,0x000254244b10a6d9,0x000075cf6a5b4cab}}, + {{0x000e81a727320b70,0x0002224f04c96aed,0x00023666fc18bf83,0x000b00b1675a97e2,0x00003640ad09f382}, {0x000efc15509f9819,0x000644de6fa11fe7,0x0008a4478b13a59f,0x000e660ba6778ad8,0x0000f50b5ac51bf3}}, + {{0x000335a6248572ee,0x000fe809fb5fe516,0x0009687ddec290cd,0x0005b5dde9196a7c,0x00005c7d5573c17b}, {0x000ca4c51c772072,0x000a292ca0ca7c47,0x00061427ea87854a,0x0003e4b62b22808a,0x0000c0e5c44caaf5}}, + {{0x000cad5d48a4d850,0x00038d63ffac15ef,0x000132f45987e66b,0x00026ccf724889b5,0x000098deb93b1efa}, {0x000c62a168e65f44,0x000179a62036dfda,0x0008c6dbc9a4ca00,0x0000127fb88e937e,0x000082fd3c4bc09a}}, + {{0x000f3ad4813e9d65,0x000bea963f775c93,0x000f6998a46925b6,0x00042bbe8efab45a,0x000029a003ea7de6}, {0x00043182741135fa,0x000c3b74e1a693fe,0x000868769efe7061,0x0001612e436da60a,0x0000de122bdce426}}, + {{0x000e61a87ddb5720,0x000452750c03edbd,0x000b38089eb41621,0x00024498574681e0,0x00004444c5108b2d}, {0x00036ed4405c72c4,0x000be6b96571a817,0x000f46d03728b4d6,0x000d22955878f06c,0x00002f2165d6e0b3}}, + {{0x00094e84458cd24f,0x0003bef3dc9a70f5,0x000015cc27ea5fec,0x0005fb57e2473ea9,0x00002182214585b4}, {0x000ebd801e198aee,0x00041dd30f306bbd,0x0008a039acb01cbb,0x0008fcba8a783d98,0x00006a26d47437cf}}, + {{0x00036d49031103bd,0x000fe7923cfb91e1,0x0009eb93161c2874,0x000b42decc591c88,0x0000df51011dba39}, {0x000990ab10e9def1,0x000b6e7f06951c4f,0x00063898370d2788,0x0006086393208c48,0x0000fe1f66e971ef}}, + {{0x000b1d4d77c20846,0x0003b33e6323e50a,0x000985e8c9dc50c0,0x000486a05634b919,0x0000032a15357882}, {0x00036b5f08065726,0x0001971634554a52,0x000f5fabff87414c,0x0006926e37e37906,0x000043513f70d8fb}}, + {{0x000739d209dee688,0x00006a1bf22b1a5c,0x0000f4d7e2ebc0fb,0x0006423d3abeed81,0x000036c96818fb4e}, {0x000d76faf0aa49ac,0x000c17dc5923cdc1,0x000780973c293b0a,0x0007d05101c6532d,0x000094adf9339dbb}}, + {{0x00046923a1ecf415,0x000a0f9ea7f71cc9,0x0005779649d48858,0x0002e729830f9f5a,0x0000a791f0968938}, {0x000b5938d2d48da3,0x000e4a63cc188eb4,0x000352d09bbdb586,0x00085e41ea2ca55d,0x0000adb9408e7ccc}}, + {{0x0000274ff274c238,0x000cf4ed75e4ccfb,0x000a58613ca6532f,0x0002f08974ef32d2,0x00009439f94f5580}, {0x000e9bd5e20f70f3,0x0008a3a320b0c62e,0x0009802b6b371846,0x000eb1e8d6efb074,0x0000fa8cacacc87a}}, + {{0x0007eae23823fcbb,0x0007a6db12378b1f,0x0005b04d466a2702,0x00074dc0e7967d3f,0x0000380c34854b55}, {0x0003c2ba3855dc42,0x00079c231fffe07b,0x000441be0c2f630c,0x000d9ac7ff5f1f15,0x000079fc2752ae5b}}, + {{0x000d5c7dfb3b7db6,0x000f2ca2b44387bf,0x000dd902aca2989f,0x000944ef359e06f4,0x000056de67cc5e30}, {0x000a7f7dc035890b,0x000b9b3ae32060de,0x000a3a327bb2950a,0x000ad059416d8521,0x00005f50358a117c}}, + {{0x0004d697d518207c,0x0008e8767b105e78,0x00004f1169c01bf5,0x00094aab5136a0ca,0x00007aff0662c2f3}, {0x0008afdcb5efc86f,0x000e9d607a6dc3be,0x0006fbaec814892d,0x000876bc381a1cec,0x0000804cfbddb73e}}, + {{0x000450c84a71f470,0x0001720cbb4694c3,0x00056165c8b36095,0x0003d3e5828b276c,0x000045bbc6744164}, {0x00051eb64e2708b8,0x000f53a1d23ebe35,0x000cf38009d06145,0x00098675fca31411,0x00002fe56c9b4d77}}, + {{0x00089e8111b8d201,0x00028297bce0d27e,0x0006a7f74f80e76c,0x000d806d8e7591d1,0x00003296fccf5a57}, {0x000b45c6234aea5e,0x0006dbb033b176cc,0x00001216b62e1303,0x00059592a07ef8c3,0x00008ded78bdb4a6}}, + {{0x000ba2653b58b0d9,0x000642b1c2d703cd,0x0000554cb792e88c,0x000b255ed4d6bdaf,0x00007f42217534e2}, {0x000de0e9cf5e143c,0x000f7f941fa77e41,0x000e9891ce2c2bc0,0x000551a51e978228,0x0000c49845f6fd9d}}, + {{0x000072da6b911236,0x000b00c92cb9f1c0,0x00011381534f49ec,0x000547bce7c215c9,0x0000dae67dc8e0ed}, {0x0001fe5736a8717c,0x0003fdb486b086b4,0x0005017a01d7b53a,0x000770705d0f3b3b,0x0000be31d50dc547}}, + {{0x00031863932c2b1f,0x0009f501ea21d51e,0x0007b61c6b454bba,0x0007c33cb217df73,0x0000437c6550aee4}, {0x00044ddc161b29fc,0x000c0745a7be39af,0x0008b4e070c24b6d,0x0009ad9f92882f93,0x000012fd81676997}}, + {{0x00027b5c52289a6d,0x00032826de7fbaeb,0x00017117cc11f3cc,0x00032957907378e9,0x000000bca115722b}, {0x000ac722f5f70b15,0x000c503d941e10b4,0x00062a5c2c8da21e,0x000534a9a3154dff,0x000008a1f7b230d8}}, + {{0x0003ceff9e7ddb51,0x000d455c86afb70d,0x0007400b6fcc1c34,0x00025964e9b9b522,0x0000c5cc14c5bb83}, {0x000dab9215029d5f,0x00095e492977ca58,0x000c4a20aa8d4a22,0x00079b19ad26e547,0x0000d91ae79427ea}}, + {{0x000785990e90367d,0x000a07e301b6cf61,0x000f636872d8e93b,0x000ab534875194e9,0x00009e9353e6c1d6}, {0x0003bbdf1baa0db0,0x000c20a4cb66f8ea,0x000ab37b0f01de77,0x00087161e429924e,0x00006efdcdf4befb}}, + {{0x000058743128a14e,0x000e066c3cd7d9ca,0x000e7e113a4a62ae,0x0000fbffb51b4a5f,0x0000cea959c32023}, {0x000a40cdef43eec5,0x000504a425d60020,0x000bb9d80185d21f,0x000572b5f2b10cbf,0x0000666c56168409}}, + {{0x0000890f3b3930eb,0x0001779057c83ef0,0x0005d2430da067a2,0x000527201bd76b42,0x00007acf20f1cd5e}, {0x000b427b09507e58,0x0007d0ae9fe8ebe9,0x0001249697373a3b,0x00059d9893406aaa,0x0000e193839ab695}}, + {{0x0003e416acc4f41a,0x000c0e4846f77700,0x0002367dc52fe292,0x0003b7ea2b9fb2b4,0x00004b818d575942}, {0x0001acd23a6740da,0x0002e5fd8bd4aaaa,0x000dbddefe835656,0x000f8fa01421ea02,0x00000ea7a8551c0e}}, + {{0x0004fb87bb00fd80,0x00047858e175eccf,0x00085edcf225c4cf,0x000c38fd395e90d8,0x0000c586da7163c3}, {0x000add010694ccaa,0x000a11f48044f949,0x0005c948f8de7c64,0x0009280114c685fa,0x0000715d4a32473d}}, + {{0x000e9f8ae08c8338,0x000c24ac457f9136,0x0007263471950b1c,0x000630b176b52349,0x0000e8f83579b684}, {0x000f9d951a40fda3,0x00089ef984f41fe3,0x000cddfe9a94991d,0x0002c27fae887b02,0x0000f0c63c32ebc6}}, + {{0x0008af107ba4d8d5,0x0003fbb10a2c242d,0x000f5b66318b0abf,0x000ce7ec492bfd61,0x00000fb5641a0bfd}, {0x0004113b1af6e684,0x0004855508208921,0x00033ccaf19c703d,0x000f8a48d57f4293,0x0000d1b2b012f3aa}}, + {{0x0007bfe9a941e18d,0x00055afc95f9e3ce,0x000005028fe66b94,0x000660d24af86ca7,0x0000eaa16abe3583}, {0x00042b18956071d8,0x00069c5ee733a2e0,0x000c62790d044917,0x000243845bb68654,0x00003a6cb05a0b5e}}, + {{0x00023c0963370038,0x0004f22524f47160,0x0002b7ff5d5eaddf,0x0008db0d442eb80f,0x0000556e77aff7df}, {0x00075e94c9c29a9e,0x000f494e0b218d01,0x000e6d2ba70c6541,0x000cd9f24ffb8b01,0x0000c6ad519d7d87}}, + {{0x0006285b576c16f8,0x0001de9045f059de,0x00073148979af3b5,0x0001d1be76385156,0x0000309c88e12487}, {0x000c2eaef778ff77,0x0009e31d2d017dc4,0x000396fd24eca05e,0x000f6feb4f3a3681,0x0000a6b0a015343c}}, + {{0x000eb84a8ff46d92,0x000e9fb21b2cd2a3,0x0007ea66290a8efa,0x000bf97c2fe9112a,0x0000c3722457ee2b}, {0x0004b94de41e2c1a,0x00070bb0903edd96,0x00012b5c31d350a5,0x000a101dae61431c,0x000045a6d6340610}}, + {{0x0004e955e16f4b09,0x00069c988f51727f,0x0004df57c7386200,0x000bdbe4bbb1fa5e,0x000074b4ca3ca24e}, {0x000dcfef41e02f97,0x000d622895da0cf7,0x000400bcaaaab9ed,0x000e8d05fbb139e2,0x00009606bc9991cf}}, + {{0x00007c5d049d81b1,0x000af8afecbf4e38,0x0009913b9af5ff22,0x0007bf2c6b5e2220,0x0000094dcf820643}, {0x000323f6bb2b4620,0x0005b4b00c0dd155,0x00004087e0e046ba,0x000c8dca3773450b,0x0000a3ee21010695}}, + {{0x000e23bf4f40ccea,0x000d69f16f378bb4,0x00081b75cffb5728,0x0001f674fcd6adee,0x0000975281c93b18}, {0x0001fa9b52577c5b,0x0000ddc2d2be26f4,0x0001deac33380425,0x0005e5008eaa09d5,0x0000fdd6b2fd7884}}, + {{0x0005aeef4710b606,0x0009620131b1a6ac,0x000ed6b51ad3a398,0x0001f7326c04601c,0x00004fed7c15b6f3}, {0x00051ae4e75e2291,0x000b2b77e46a8eb4,0x00024864f5396c6b,0x000a307fe44bd15a,0x0000fddf9a7fb162}}, + {{0x00004463e73b8ec4,0x000f55cec5c6d935,0x000affcd58b06c2e,0x00044e00ad788e57,0x0000872bf18a0fd9}, {0x0008d14e5d71e574,0x000d2c3030bc88b1,0x0005dddd1ce58ea7,0x00057d1f9dc7c5a3,0x00004d1818d515b6}}, + {{0x000ddb8bf4b54748,0x00023305f0daf6ed,0x00052038139d4af5,0x000efb7d652772de,0x0000069ae58d16c6}, {0x000bf73dfb68fd92,0x0003fde5dff8e66d,0x0005f967c0e4a7d2,0x00069cea388c3b52,0x000000d338cf626d}}, + {{0x00045c714519e589,0x000e0913096476e5,0x0000d02d7cf59be2,0x0008386476786752,0x0000a99633c4e597}, {0x0000911b961f3964,0x000589bdb3f722c1,0x00040b0284c204f6,0x000310c471f04659,0x0000b8f29400b771}}, + {{0x0007580908012844,0x0006c059281b1ac5,0x0001c35df7e30017,0x000950b68a678586,0x0000423082ebc843}, {0x0003aee90a09598e,0x000a9913987d1e31,0x0002a51b3792cb2b,0x000d1a18355dcf9d,0x00002891458b1327}}, + {{0x00059e6c45add90c,0x00035578dc6b43e3,0x0002ce37e6ba1e8c,0x0002e4a6505c2877,0x0000b821b953f4ae}, {0x00022256fceb3969,0x000fbf38ecb4e108,0x000eef42aaee7a3b,0x00075dab0d35094d,0x000025f891427625}}, + {{0x000bb97d0edfa1ce,0x000e46b5d78101cf,0x00056ac5655ba12e,0x0004dc4b371feede,0x0000daa9c221667c}, {0x000b374aafd9ed41,0x000ac3a4679a8a4c,0x00000de55fba1126,0x000b1bafaeade880,0x00003e746cdf818e}}, + {{0x000990ec0f88d5f8,0x000288b4c7c62b24,0x00084d7118dfe4c9,0x0009fca983eed9ba,0x0000a1b21a93ca27}, {0x0008872895a60682,0x000024e18c538587,0x000ca73ba0accfc1,0x00000837dd0e2487,0x00008513be562083}}, + {{0x00003f947b6ea260,0x0001bb7a4729c734,0x00032750426849a0,0x0004026b72cf4cd4,0x0000c0fffc1c5d6f}, {0x00085c96173719aa,0x000c05910bfce43c,0x000acef18e018793,0x00032e0f069d5faa,0x00009fae2afd5c69}}, + {{0x000acf01ed8bd7cd,0x0000263477c55128,0x00078d6112535697,0x000b9055421fe02d,0x0000f1a20e6ea246}, {0x0005ae7d073d4a89,0x000bd63778b84373,0x000bc7a37abb5f3e,0x00009b5483301a33,0x000036ae26c63a8e}}, + {{0x000061c767eff576,0x000dd9ea79a1ccc2,0x0003437b2eba650c,0x000cfcac1b11574d,0x0000cfb31a0d11b8}, {0x00054f89f42bfdbc,0x000cc2703661fe7c,0x00070d58a8d1569e,0x000bba5a9527776b,0x0000161cf8545e19}}, +}, +{ +/* digit=24 [{1,2,3,..,}]*([2^168]*G) */ + {{0x000c25e9f5170aa7,0x0001f8f5338bd76c,0x00040201a3c0073f,0x00012ffbf6fcc231,0x000009be87d49f50}, {0x000bfe953dc74903,0x0003d8653153dc6e,0x0000eb06e85facca,0x0003077c47d716a6,0x00009f6514c80bee}}, + {{0x0007b09654c48577,0x0004fdb0f5200d71,0x0004e6cb015e94bb,0x000f88dcf3519dc6,0x000059d275f2ebdb}, {0x000ec0fd11aeb819,0x000c8be9fb8ae833,0x0007d57ad2893bce,0x000e52f8ada66e74,0x00002d1bbca1a1e3}}, + {{0x000d4246631e6f4c,0x00052539fdfdb824,0x000b8f0507304674,0x00065e29c10ef5e6,0x00006b779bb7066a}, {0x0005a5380f5abd81,0x000523a56e993fe2,0x000c373f30122a40,0x000a4ff3a52697bc,0x0000de214925f8e6}}, + {{0x000a957eb8abd51b,0x0001bb0ab69abf50,0x000e7252ad43d460,0x000fe24207ecc4bb,0x0000964c4fe8348f}, {0x00091eb0668c06ef,0x00037f512c2d1c55,0x000cc3a429333eb0,0x00061923cd82147c,0x00008b93a9d6c59e}}, + {{0x000cc48773e35954,0x000e214b22340fa4,0x0007830d996f413a,0x000907b196a2bc70,0x000037ecd06850c4}, {0x00039bfe3ef35b95,0x000b82f5d6ce3ace,0x000d52cc302fad75,0x000d0d41e6e89210,0x000090aa6d71bfce}}, + {{0x000dc3c8f4aa5889,0x0003a50cbedadb5e,0x0007a52111e6d592,0x000a80177e437ee8,0x0000df8d7c441860}, {0x000eda8cf92436a5,0x000296bc8560bcf4,0x0009734d2066ad91,0x000059756ccdd882,0x000043cd11c08558}}, + {{0x000077ab273751fb,0x000c255f1d1bdcb6,0x000d46eee885b68f,0x0006411656e793e5,0x0000bcc61e8b1ba0}, {0x0004299f88dfd877,0x00072838b3a069d4,0x00011a67cda79c15,0x00041b6a28140e4e,0x000038faae273c96}}, + {{0x000cc732728468c7,0x000bdfa9a3bd9569,0x000d743f442bfed7,0x0002dd74b6f74702,0x00001de0fb3c4843}, {0x000e7d2fa94e43b9,0x000e83587eed4ca6,0x00099758a506eec9,0x000192a4a5292aa3,0x000006038c3c85a0}}, + {{0x000e8448ca36b091,0x000724026db2dc96,0x000a6f0c367dc2bd,0x000865e5b7051140,0x00009f8943f82b64}, {0x0005ff5fc9a5ec8e,0x0007001fcd7a9b31,0x000237cd7ebe7ebb,0x00005c2a5148967d,0x0000e997301ffa6b}}, + {{0x0004c665b9eac65a,0x00052ba5a915a9f2,0x00066278cc6bdeae,0x000b249b5e33760c,0x0000ebc09e8ac7b1}, {0x000caea5a6199620,0x000be60abe7d7c0b,0x00088044342ec817,0x0000a54835970666,0x000050d8ef2ff279}}, + {{0x0006c27846f75d05,0x0002cbb8971b0591,0x000fef98918d6613,0x000d3bb003639aad,0x00002a37323294ad}, {0x0004bdefdbf09029,0x0000fea38bc50670,0x00075dd7401061a2,0x000972a86fb9b7f3,0x00002a9ef8a399aa}}, + {{0x0004bb6ac1207afa,0x000e9580f1b1a4df,0x0009301d506bb9e3,0x0003ddb25c740d34,0x000024a77e6b0e29}, {0x0009997ebbefc02a,0x0000f9bee7b2e05d,0x000c3f6c1d1e9c60,0x000930fe3607022d,0x0000b29cca36dccc}}, + {{0x000a13edfc3232c8,0x000071af81e3d653,0x00093d6ba80325a6,0x000faf2033e68207,0x00001c7c20a162eb}, {0x0003995532aaaf64,0x000c4aecfc68ed5a,0x00098196ea438ecb,0x000c5c5fff04de2b,0x0000069d497969cf}}, + {{0x00016cb6ab4f0071,0x0002ebe7c2a951b2,0x0001507db4c9e3b8,0x0000e1bf7e75c535,0x00006b09f4ba63d2}, {0x0005b11f97734d28,0x0006dc581c376458,0x000cec0864a46ba7,0x0001fc733dcc712f,0x0000aa53b9688ed5}}, + {{0x000da0620844de29,0x0008013f258339b4,0x00080097b1ef8c8a,0x000716541e0eaa04,0x0000c5dfd5748615}, {0x00091ec9a14f247b,0x000b9fd915415a11,0x00018caef9331112,0x00097f0fe5bf0968,0x0000636405ec0ca8}}, + {{0x000dd20ccee2cb48,0x000695b1e68483ba,0x00039267fb005c14,0x000991f285b3686f,0x0000596c8811740c}, {0x0000039d01b2c886,0x0000066b542dfb66,0x00090ad7b941b21f,0x000fb42690c453ab,0x00002b8741e90fa7}}, + {{0x000af8194dadc627,0x0001edf51bfe1834,0x0009bd348776705b,0x0001ad70ee1dce5c,0x0000b26f64d4ae19}, {0x000a67e9b9267406,0x000dbf7a60d3b5cb,0x000bbaec7f815e13,0x000b9534b3ab92f3,0x0000d60d991417fd}}, + {{0x000ce9cfb15625e8,0x000fc4db106913f8,0x000b2c9cd8cedab6,0x000a59e395243e6e,0x0000434f60bd1431}, {0x00012f01f634f2cd,0x000c40ae9ddbe0ed,0x000b866c6a73238f,0x00081e4ad4d13cf2,0x0000375a9d4fdb5d}}, + {{0x000cffc53160c73c,0x00007539809f73a4,0x0005b23b923b3241,0x000b5195c30c96c5,0x000094fdb86cfd44}, {0x0009dbb264a47a78,0x0004d93efb5e99fe,0x000e9a68933cc2c1,0x000ffe8e878bb037,0x0000f7d2e44d123a}}, + {{0x0007e32ebbba9682,0x000be1ca85ab0b5d,0x000c9697a03f4a69,0x0000a0e9870318d2,0x0000e8015aabeaf5}, {0x0008c0ba7e1dfd93,0x000f56bc29921b79,0x0001d1608f5ae798,0x0000ee85a0922135,0x00007f26d995d2fb}}, + {{0x00089e5230cc1b43,0x000be3c41cfda991,0x000292450b3d3c1d,0x000dd89d5989e496,0x0000cfc1ecde9524}, {0x000d6a36c7493761,0x00031f1678e9dfa7,0x000a563232985073,0x000479ad7e48450c,0x0000ac60c6fc5646}}, + {{0x000e435ab0cf52fb,0x000756ea25b6a16d,0x000034b17c2186b4,0x0001f2fc7036334a,0x0000bd1c9eafb0ed}, {0x0004b6d249b21b42,0x000c8600552f96ed,0x000bfc49b2fc4e76,0x000ab86179a640ee,0x0000742b6f2cd85f}}, + {{0x000836e93b510939,0x00034ecdc5de9094,0x000cfec954c59e8e,0x000659f87fcc53cf,0x0000a4568a7a9057}, {0x000c03e5826f6ff5,0x0002f83faeae31ed,0x000b8b111d7a6557,0x0001ce6cb4bee145,0x0000e343b357add3}}, + {{0x0007124356c03ca5,0x0005e9256c013890,0x0003b390b3f0ccfa,0x00096e541ed7e668,0x00005b7692759858}, {0x000db7904f1906ec,0x0009f798fee14430,0x000c762aa8e0adfd,0x0009c408beb39255,0x000089f982ccad3d}}, + {{0x00079b689457b765,0x000fea0f5b956815,0x0003aae2e20e7df7,0x00036deeee3b323c,0x0000b98cee329d35}, {0x000cece61a5f45d6,0x00042e78c9cbc2e3,0x000ecf95735d7b06,0x00009e205e0aa2ca,0x0000e5839c503b44}}, + {{0x0008f9208fcdecb3,0x00061b66dbf41f69,0x000a1af91975c299,0x000495d23b37428d,0x00003d9b8eb27748}, {0x000c26ec038dd208,0x0007733cdf67d14c,0x000f975e452454ca,0x000c01fabd49971b,0x0000982b9f5186b5}}, + {{0x00082d71ed519447,0x000dd9063242dd6c,0x00086537a94dbe4e,0x0007e5159224fc27,0x000080fe5639583f}, {0x000c13fce88adb1a,0x000bc57f2f24f1ae,0x000fa63cf0fdf9e6,0x000b6d90fd8fafda,0x000044733d44e643}}, + {{0x0001fe8821de4787,0x000ad971ee6fb14a,0x000eeebab19b43ff,0x000fd6931813e718,0x0000f9d90866ab81}, {0x000ab8c25b81d6ec,0x00085bd040950086,0x000b02351a4be98f,0x000418cdeb6e4418,0x0000e57c7e8aa473}}, + {{0x00026d051d0b0c81,0x000c03f43bb4e055,0x000108d9671ce09f,0x0001db9508e74a7b,0x00001f1327927748}, {0x000b0010c84e7c59,0x000517a0dad7005a,0x000eefc16dacdfff,0x0009472e6bfbd9e3,0x0000daaed22249a2}}, + {{0x00068df75e5be29d,0x000385fff9a99479,0x000bb571140db0d9,0x00046304b0b4cfd7,0x00001addb26ae24b}, {0x000581856fb91014,0x0001696d3fdf03ca,0x0009d9e027eb9076,0x0002876031e89681,0x00003e9950d59c6e}}, + {{0x0008caae157977b0,0x000674349dcf9d6a,0x000b699a60e8b54c,0x00076b8f3c4ad763,0x00005cc559c43b1b}, {0x000211ff4c8d557b,0x000e78905358fe5c,0x00083936f8309b2c,0x0004af64acf5051f,0x0000481e7e0c6fec}}, + {{0x00053fe33c602daf,0x0004cf85cb7ed0f4,0x000d1adf62c3095c,0x0002834573d068b4,0x00002d0fd0243c96}, {0x000b5a83acc5f984,0x000951b8242871ac,0x00042785559a72b1,0x000383e0b9e6f513,0x0000eef0713ace69}}, + {{0x0001642514077632,0x000b7843397d07f7,0x0004342ab2e8b92a,0x000548eb3dea716a,0x0000fd46ebf66d9f}, {0x000108bf0b8a44a2,0x000444151a9a68e5,0x0006fbd93700306f,0x000a840cbdf94002,0x0000c577ee629894}}, + {{0x0000bca8d5a234cb,0x0002ada976341eed,0x0000d8f5b9ffe4f4,0x000614ea32e31bba,0x00009640fc08e2ba}, {0x000bd3091a3cc172,0x000dd6813f60e5d6,0x0000955ef6102e8d,0x000c318e716035a8,0x00007083188700d7}}, + {{0x00015232afdb4a80,0x0002497d796b320f,0x000fcb99991c4603,0x0008a8e8ee7f7f71,0x000086a97ca03731}, {0x0008e6620f196d18,0x000bfb677ecebb7a,0x00084316a2c3361d,0x00098a5a92e2000f,0x0000ad5b02777783}}, + {{0x000dd0efcada3ed5,0x000bc43a9054d4be,0x000db0e54123501a,0x000e0f955966efef,0x0000e31aa4eeecf5}, {0x00049cefca5df228,0x0001b845465e6d45,0x000595d6a9287939,0x0005be1879d8875b,0x000050e3ad18c18e}}, + {{0x0000ae732271801c,0x0005b803d1ed6ccd,0x000be65e61856a37,0x0006cdb05d43079f,0x0000757438954a07}, {0x000ff113986411c7,0x00005e8c6b438f05,0x00082dcb49c55eac,0x00095ff8773437d6,0x0000797c7879b91a}}, + {{0x000418f19e79e5c2,0x000898e184288dfc,0x000811bdb644c310,0x00017641a8142536,0x0000ec41eefe56df}, {0x00005b4e27fb6bc1,0x000f8e054fba1edc,0x00089e0e1650e5e9,0x00095692ab6f4529,0x0000fbcc505276d3}}, + {{0x000281ca2dfe6dc8,0x000110de712c653e,0x000ee928158404b6,0x000cf6d7e6105cd0,0x0000d388140e6953}, {0x000ed39f0617f89f,0x00067a61a5286d8c,0x0000ab74f3f1e213,0x00006e8ba2227632,0x00002cba3b64a144}}, + {{0x00019bb3ef88b573,0x0009c9454c264310,0x000e75b084b05970,0x00090f0042faa6a0,0x0000c42b966c283b}, {0x00069924227e2345,0x00081e764b1d0c29,0x00085621fbc826d9,0x0005ac4deb50a990,0x00003a0c83012d01}}, + {{0x000eedb8289fe19d,0x000455d8703a0f39,0x00069318dd303312,0x000f22bc207eb1d1,0x00009a1b36be080e}, {0x000a07cf89baf3ea,0x000d625b41a9e3cb,0x000bfa4f0e365656,0x000ce1cc88025770,0x000065eacea3656e}}, + {{0x0005c19ef45d6b91,0x0003ff6ee7a1c188,0x00095b614626c796,0x00008cdf716625be,0x0000905d59e52e68}, {0x000e8445d0e57d94,0x00010289d5e86e38,0x000258e2d5292144,0x000960edda6c726d,0x000078f149d15866}}, + {{0x0003b373eeb3be5d,0x000008cdfd007c91,0x00020d539c7e74db,0x000a226c08d0199f,0x0000f14535325914}, {0x000f5b02288d3d99,0x000c450de2506ea7,0x000a273bce6ad41d,0x000bdbc8e36df7c0,0x00001ad366534f40}}, + {{0x000602ba827d0dcb,0x00091adbf560c3f3,0x00013a340f90f764,0x00093eb8c55e59f6,0x000080ec3bdb9d66}, {0x000fa139bc659726,0x000f737f930cd576,0x00052013011430c2,0x0003652c9fa7479f,0x00006624def0a0e1}}, + {{0x0009772769b19129,0x0009d1ada7cf07e3,0x000c9a259ebf722e,0x000cc4241ca31714,0x0000b844dffaaf8c}, {0x000a55fb9723c092,0x000761a9a645934e,0x0000f493a79cd872,0x000410ce7fa8a9c6,0x0000992cbc50218e}}, + {{0x0009ec972907a41a,0x0003f2fe9e468bbf,0x000807c9a4ff51da,0x0000ea9411ccb7b4,0x0000798a299aa8f4}, {0x000bb39dfa6de2ba,0x000d102a830388a3,0x0009be6602815a52,0x00097420a96dc3e2,0x0000698523b7ae24}}, + {{0x000e5e2695331daf,0x000aa511993e978f,0x000890d5eea027e9,0x000380801eac0409,0x0000079a353c8f13}, {0x000d2aab807ac122,0x0003153b7b007d3e,0x000c8146f9dc100f,0x000de36f0b42a3f9,0x0000837fb01d7d39}}, + {{0x000bad9ce4ff7c82,0x0001f47732d9a89b,0x000ee5faee22e6f7,0x000d5ea181969613,0x0000e30cc88547dd}, {0x000c36cde1dae9e9,0x0006bc67c475249f,0x000dfb408d12c773,0x0000395cb3b91c3c,0x0000d1c1cf946d61}}, + {{0x00040f67eafffb16,0x000b5075d48b2a76,0x0002c7c72f3112e3,0x000256a2a08a64cb,0x00007bb6c8e3ab45}, {0x000cdb3da1c5cb8b,0x0003c150935de71c,0x00071dd0d002611f,0x0001db99d4d16d56,0x000038a095f1bbf4}}, + {{0x000d0fa367f54448,0x0003146d9fd69644,0x00003ace9de42457,0x000b4368540bef28,0x00007344421ec2ec}, {0x00080473886c71dd,0x0002dbd4c0da1c7f,0x000e1b1b8096a337,0x000b47b29c3663ce,0x00009b850a4fe4c5}}, + {{0x000e92e2711f6c64,0x000b96297ee64980,0x0000a0287ce98611,0x000f59621aee88a6,0x00003a13d7736ee6}, {0x00042a0c754f85e6,0x000e90b3dd1a56d1,0x000bc903c6539c68,0x000a0c394962bd7b,0x00000c0dac7c0d84}}, + {{0x00006ed5888a2297,0x000751181c6bd971,0x00001fa29f66bddf,0x0003dc751ce5d2c6,0x000030a703678c28}, {0x0001544a52f8cedf,0x000be7386c005d73,0x000b3a1020b312a8,0x000964a3e7d61e3b,0x0000cd0a1f2cc51e}}, + {{0x000bbb7730637d22,0x000c0ee69ffebac1,0x000752c78cf96785,0x0003758cc83733f2,0x0000a885c698de85}, {0x00081b51bc9dd850,0x000b4da7bf040293,0x00006ffb160bfa60,0x0008090cb031432f,0x0000a5961de3acd8}}, + {{0x000544e3c5d8a4f3,0x000d695380f1fb71,0x0001dd2550cdfc3a,0x00008c41c6df5c9a,0x000015751273680e}, {0x000829ee56b6eed1,0x0008736e5950fa14,0x00084ee6a21b66ec,0x00068cf12d853922,0x0000aacb8733b362}}, + {{0x000744efd56dcf02,0x000d5ea49439ff91,0x000ae04d42849b3c,0x0006a13b6e556b78,0x000068bec5e02e90}, {0x000aa440bca4d3c9,0x00061e186837ca14,0x000a14da69cfee5a,0x000e96cde0f100bd,0x0000a67e8a765191}}, + {{0x000e0aa93f9d4461,0x0008116ba5c9f703,0x000eec78f1b1b2fe,0x00027eda47d1be72,0x0000185448619cd4}, {0x0002b1e0e6c02d92,0x0005c61712615570,0x0007a197ef949c1d,0x000c916bf10a070e,0x0000fd96d47b2de6}}, + {{0x000688afda1eadac,0x0005b4195e38ca30,0x000eef15dd8a8720,0x00033df5b11f7a9b,0x00009f2a47d71132}, {0x00023ac090f6dd40,0x0002214691c3f9a8,0x0005cbd3a69343c1,0x00055aad1e8ad7b1,0x000084d228267ea4}}, + {{0x00086fe50c54cbcb,0x000f653d0a7793ff,0x000c8c956c1fb89e,0x000283d2e92f9f9a,0x0000056a14c921b1}, {0x00089485a04b6501,0x00077ea06a75ec6e,0x000a3c4a6d6534de,0x0002a89696e721dd,0x00007fda5cefe58f}}, + {{0x000c5318d0e40d7e,0x000f6a538eee8279,0x0004e48a6eb9f6e1,0x000da4bcb94b8cff,0x0000c4899eed700f}, {0x0002a357b45aee63,0x00099a0087e74e39,0x0001e767f55766e7,0x0000e932c5c64a26,0x00002c5fc6626169}}, + {{0x000c2d890c562791,0x0001c4070cc2c8dd,0x00054def1b70c1f0,0x000d5c30fdf7b1ee,0x0000dbfe11c8f13f}, {0x00065c130ac48a93,0x0003ce26b496f369,0x000fd989f121c642,0x00072c727a8a1055,0x00003a348bb24777}}, + {{0x000dcd25a190461a,0x000a106657730c58,0x000f65f30110341f,0x00052183383995bd,0x0000425c381d25fe}, {0x0004adfd6e549001,0x00041290a9292ea2,0x000b76df784221ca,0x0001819281717876,0x00003c6286226714}}, + {{0x000956ce903181f9,0x000756047fd2cff5,0x00082b850c30f551,0x000016a192cb7cc1,0x0000164246ae1ae0}, {0x000fc004f248d82d,0x000270a5afc4b0e4,0x000bbe52be2cd809,0x000bcc98f97e693a,0x000059d87c21fa20}}, + {{0x00041646e13ab52e,0x00054c259320b618,0x0000a293fa0cd0bf,0x00055b81537d75a9,0x000051de543bb104}, {0x00001de5fec9a0eb,0x000afab3f9905655,0x000b5b3263792733,0x0000f68755608613,0x00000d4e6f054c47}}, + {{0x000710267c542a45,0x00079aa6faea8981,0x000ab176cd6156ab,0x000dab6a3f451e57,0x0000377dae7b0730}, {0x00017a92f3c84900,0x0003ce118d488c05,0x00076348955e451d,0x0001227de12fc278,0x0000a2604acecd69}}, +}, +{ +/* digit=25 [{1,2,3,..,}]*([2^175]*G) */ + {{0x0000f07eb83bd033,0x000c42728bc15e5b,0x0007503622eb0cfa,0x000572855689e6d5,0x0000ffe17a0fa82e}, {0x000666a2a34814bf,0x000cdc30d17ce550,0x0008d4ebe4148a9a,0x000ee9bc0fe3fc26,0x0000237a4fb4ebee}}, + {{0x0001c57cbb6521da,0x0007e013ad088fb8,0x000e523b034683c9,0x0003fd973cba032f,0x0000bdd5593a2694}, {0x0002b0ee317fe3b8,0x000b0cf3aa3671bd,0x00053dd74d87c697,0x000950259f03a8c0,0x0000bd48cf81120b}}, + {{0x000c2d85f00903b9,0x00023d280c52e198,0x00003f2253a05cf2,0x000053ca5bce1e21,0x000095953ca7afa1}, {0x0007eaf045a97253,0x000b61ef1e17ab18,0x0001cc69a1ea96f0,0x000d886265e99974,0x00009d16dd8088db}}, + {{0x000070d24ea591be,0x000ddb1395a861ea,0x000c708bf3a531a9,0x00045cf5cab52096,0x0000f8dd80a0756c}, {0x00018008dc9efd3b,0x0008df4b56e64d3e,0x00050e16e3f81f4e,0x0005b29b73276fb7,0x00003164beeb41b9}}, + {{0x0008e3a4e414233d,0x0007c6b84bc799a9,0x000bf981390050aa,0x0001b5245d5f66b0,0x00008ade8eaa35b9}, {0x000dd15f5c095ff5,0x000754ae9f8d06a9,0x0001d477cbbf72a4,0x00022cbd33b02ff2,0x0000807cdb0901cb}}, + {{0x000ee8912650bd3e,0x00053f782a39217e,0x000618997e9887ca,0x00025a0184c0779b,0x0000f717203cdc98}, {0x0002d521bdde7363,0x000c28fb3a2da14f,0x00001a0c2ef900e1,0x000e1af7a79f2377,0x0000b5d67fcc63cb}}, + {{0x0002eb021df78d51,0x000b081c9f307643,0x0006e5c92268a6e3,0x000e68d0b6f1d616,0x0000780b514a1250}, {0x000363c9b4b5ca38,0x000c14058ae8d88f,0x000abcfae84c017a,0x00001c021a267bf1,0x0000352d6c69a7e8}}, + {{0x0000ce578ee0421a,0x000ce61cdee800a5,0x00088829e74b485e,0x0004993b7a9f52f5,0x000021992713481a}, {0x000d96b4c61e5ad5,0x000c4dfe48a2ed65,0x0001425d4368e4fb,0x00016f34820cdfc5,0x0000a61d206e3b36}}, + {{0x000e3ec504534afc,0x00004ec7955c88a4,0x00050fed6537707e,0x000f6d10700e71b5,0x00000877ca57aa69}, {0x0002364134c7dfdb,0x0005855b263b3933,0x000dd5682153885c,0x000150675240b632,0x00005d29c6405791}}, + {{0x000b0d18666db72a,0x000f2d06582741e7,0x0001793ca3db5107,0x00077db29e38bab0,0x000084e11850de3a}, {0x000c8c2f41c8d79b,0x000501d15f801de0,0x000e2fa4edb21191,0x00055b0e59608ebc,0x0000e2af30fb06fa}}, + {{0x000365bea852e986,0x00023d23f18d3454,0x0002a0a0c61de9a0,0x000db69a0b114ba2,0x00001a64b5ee88ce}, {0x0007873ef9d06036,0x000df11ed48a5e35,0x00071a5b115f7948,0x00021de1c334adcb,0x0000265cf2f68415}}, + {{0x000cad85cb2c08f1,0x00013050f5bebd73,0x000c923a2320bf0c,0x000fbc656f4c2f1f,0x0000b53d151eb2a0}, {0x000b47255d36eef0,0x000a7b1171c22301,0x000724d1552a8c41,0x0001e7407c769b93,0x0000a4c8f8e5501e}}, + {{0x000ea34e3d43a020,0x000a28fe86195962,0x00015f931be0edab,0x000b1a5b51a1a2e1,0x00008f3b12193b36}, {0x000f4bbef5440b0a,0x000163cb97e2f791,0x0009344115a98d55,0x00030bfa810b1d2c,0x00009ac76ae97e64}}, + {{0x000a89f24dbe5bbf,0x00027581706f6f1e,0x000b2064b8a59052,0x000c28e5a7101b9d,0x00005819dae01ddd}, {0x0008e03d02d3f29a,0x000fbf2a1752e0db,0x000e534102f0d5bc,0x00036cd64e0d1f26,0x0000e99c7c9e4cab}}, + {{0x000adc1b52d2c43f,0x00033f467ac3b66e,0x000ff7454896c1f4,0x0005b725476ddb98,0x000076bf8f2486b1}, {0x000fd017adb3aa43,0x000cb44c8927398a,0x00058f3e9553da51,0x0009000230e271cb,0x0000539e7977c345}}, + {{0x000fad0b915022c3,0x0002106d7a523ebc,0x000335d2c80fc99c,0x000c9cb1584ffa37,0x0000e03e0f554705}, {0x00006adb6d93260c,0x00003a928e28cd3a,0x000cb2640092877a,0x0007e59d702481ee,0x000096acaf7a1b0d}}, + {{0x00043348d46add3e,0x00017b9f7c368909,0x000a1f1374adebe3,0x000cf21b998ac50b,0x00006e1a007a85e5}, {0x000fc1c2509d7d1e,0x0004e813db920aac,0x00064a506bbbc35e,0x0005c8293e917e2c,0x0000a0658874c8bf}}, + {{0x0003c2cd968d2bbe,0x000cd4c6eb2327bc,0x000bc548ced0417b,0x000e8d485d4af2f9,0x00004dacd98b166f}, {0x000b9e5cc5ded1dc,0x000ae2a98ba23580,0x000492a536faaf10,0x000e70e356736920,0x0000e510a11666b8}}, + {{0x000f3f1dc1e8b2dc,0x00066500e64a04a3,0x00036c76bbd3bb86,0x0008bbbf79e266ec,0x000021afeb04482e}, {0x00077f89864546f7,0x000725833277b7ee,0x000c09d42161b114,0x0003b6320fd7a5fb,0x00008b814a9efdb6}}, + {{0x000a001441991ea3,0x000ddf08d40e88f7,0x000233055e0b07ef,0x0001ccea6feaab02,0x0000bc15f20a5108}, {0x00095e60f38e9c6b,0x000c2ae91436b227,0x000f0513590543c5,0x000e03be4e76138c,0x00005328faf22271}}, + {{0x000a10d536481292,0x000410288d8eb4c5,0x00019c657d7affd4,0x0008693fb147884e,0x000050afa8840f2a}, {0x0004ae9998b069e2,0x000cb30712223137,0x000e91fd044e1f54,0x000424e7c6c23e5b,0x000007d112a47f0f}}, + {{0x0000f60ce2868df5,0x00049dc327eeea11,0x00046812a36db546,0x00080d91bf0f5a1e,0x000048f22bd3d877}, {0x000dfe5037a0b7e2,0x0007ecb51339b1cb,0x00071e2f0fd2d522,0x0001f8676a49b5a4,0x0000c769f1a6e725}}, + {{0x0002bf88dc2f0a70,0x000a3e68dc50f43a,0x0006cb84e98ae70a,0x000c6a2dab22067b,0x0000b91bfae77104}, {0x000ca4c4e1a302aa,0x0007c10be63cbe8f,0x000d88a1c0a2bd81,0x0005edd219abbb19,0x000010f5e51606e8}}, + {{0x000a2ad1f09fbd80,0x000db1f885fd8bea,0x0004e03fbf5c1af0,0x000c71abe93ec293,0x000068d6944c156d}, {0x0008f5795e2c39d0,0x0007de2a058c1fb2,0x000f391b7a363cec,0x000c511d56812b80,0x0000f1912e543c50}}, + {{0x000fa1bea2fc7856,0x000facf2d79b50ca,0x000b4dc605ee792c,0x000e37949b168ca7,0x0000f9f755e580ab}, {0x000214f4f0dfe3d3,0x000cb8f668d68881,0x00035d50ad3e2ab5,0x000d53349af8b5fb,0x0000eaf332242029}}, + {{0x000b3c0c5daf0c95,0x0000abd9ca770b96,0x0007491231340717,0x000c014e3753afa8,0x0000c1c50ae93cc7}, {0x00019a912d2fa053,0x000518344b1ceaad,0x000ee6c426f62582,0x0001b96bc3e144fc,0x00001b86a8ec07a6}}, + {{0x000f7a88ba02f836,0x00073dda3e59c0b9,0x0009cccb19acdf4b,0x00089607ecb07e22,0x0000e179a7fe03f0}, {0x000d066aa749105e,0x000cc15f2c1af78e,0x00014bae07f26f5c,0x00089e31dede1a78,0x00007ba2b8802bf3}}, + {{0x0008fa37e8bbf903,0x0002caeac4c26d3b,0x00054f9cd941b0e0,0x000695d6897bed90,0x0000879936aa651b}, {0x000a4948166b0278,0x0006106510d0399a,0x0006d4927293dbad,0x000dc9d16600bdd4,0x00002fd5ac433045}}, + {{0x000ea7b9f63a3889,0x00052557fcca4d89,0x000f2529e5e6ada2,0x0008362a0cdc0208,0x00008c8b9774d48c}, {0x00017a89e8d0e96d,0x000e14b6920ed486,0x00029494b799f387,0x000de743c654d3c3,0x0000a2f31f9adfaf}}, + {{0x0007183488f904f9,0x000017bbed9c088a,0x000762e0db3b3f4c,0x000a3f18431c2c9e,0x0000d188af79e181}, {0x000747e667c0d1bd,0x000e968e2a6500ae,0x000769759bb4bffe,0x00055beab9f86803,0x0000262d46060ae5}}, + {{0x0000f4053aa9a78f,0x000f79c35e544089,0x000fd839d2c910e7,0x000055db8e7ca105,0x0000db97ad2b5831}, {0x000eaadbd3c4f7a6,0x00049ef7c107421b,0x000f045e1644c17b,0x0004119453602525,0x0000e5c41998aa2b}}, + {{0x000ae5b06add8234,0x000ece621122e9d0,0x0005aa6bbb8095fb,0x0004f8f151cbaa93,0x0000c30736f0d3f2}, {0x0004bb0b2c0934c3,0x0007af112376af19,0x00016cc005f81abf,0x0002b33e6640b099,0x000054837f425912}}, + {{0x00060e6aff8da2bf,0x0007b2b372a89876,0x0003629cb60a2cfb,0x00061c0c2676d696,0x0000a734b56f2086}, {0x00098761fa9a1967,0x000560b82b8f4fd4,0x000c50fbf8a331bb,0x00006ab7b7096885,0x0000ee75dde39230}}, + {{0x00076dffc96c21b4,0x00063017c3d1bee4,0x000d9abd38be81d2,0x000f32f709fcddee,0x0000acb956a0808a}, {0x000b9e25e66f3281,0x00033831c8a599f0,0x0007eb06721417f1,0x0005cd4833b0079e,0x0000493a266fb576}}, + {{0x0004baa2d5668523,0x00003689fc40b0ae,0x000279c28d2c7f3e,0x0005629534d2937e,0x000098a4d84f2ecf}, {0x00035f14cb929a91,0x00061f8963790393,0x00009e7b7b25a5d5,0x0001016ac69aab90,0x00003d893e043064}}, + {{0x0006b786a36bceb5,0x000f6c58efedb4f1,0x0004457a463ce9bd,0x000b72d69b1127cc,0x0000fe789e83b3a4}, {0x00017c51f7e29b87,0x0001531fdf820296,0x000f2588967ed30b,0x000ed5a3df57f4a1,0x0000ce6d4a94d6a8}}, + {{0x00021eb676b5af75,0x0006aeb5c3a18291,0x00043eaf051ebc58,0x0004ef8bd71c578c,0x000001fbd625ad3c}, {0x00032c1d4663f519,0x00045aeb159107de,0x0007a554a8e64c3b,0x000cc9cbc678ad96,0x000020a01fc96657}}, + {{0x000be89bb43950a1,0x0005817b762b4266,0x00047f7019afa059,0x0003ca4a2c7f75fd,0x00003dbf549fffe8}, {0x00097451ad446c62,0x00064f101758f41a,0x00094ed44c88f148,0x000c5d31f7dab03b,0x000007789b3fa42d}}, + {{0x000b763df689270c,0x000edece73483d7e,0x000aee476fae171e,0x0006c30996252a7b,0x000068c6d9b71408}, {0x000802d40be0a180,0x000279f7214afa5c,0x000a50baf4c90054,0x0006601236076d44,0x0000f1a4df9f611b}}, + {{0x000a1d871f3ad971,0x0001471f93998a18,0x0007cb6b4089cfe6,0x00046e2888680be6,0x0000a4a0b67496c8}, {0x00051504d9720c99,0x000b82f1dec98c6e,0x000bc6615e19ef35,0x000cbff674933ffd,0x000029e4752286b2}}, + {{0x00010cf8006801ed,0x000ff3f96b824680,0x000ece9035f8b7c1,0x0004370ed08d2e0f,0x00008e43d7f5270a}, {0x0007758e8c30cba1,0x000a4c5e382f556d,0x000374942bed58f8,0x000f7b4d390b896a,0x00003148cdc67c81}}, + {{0x0003a9cd5c44392f,0x000e47bdfe21ed29,0x000491c1481a25a7,0x0006fe1cd7dae300,0x0000b9d3868cc4ee}, {0x0002068ada03a6a0,0x0000340f5762442b,0x000e0b53a208f677,0x000762b2ee05976c,0x000047fee704c66e}}, + {{0x00045be28bb6cc47,0x000bf9a6e2427822,0x0006b0e18c349f9d,0x000d413cbad70f27,0x00005db7ba2cd50e}, {0x0006fa76a8688440,0x000f17cc272cd775,0x0000a9aacfd31874,0x00081d50e472af63,0x000031b1bf3d98d8}}, + {{0x0003b11d230fb125,0x0006dafeaf84ff7c,0x000c87a66c21c356,0x000c83a7fe395ccd,0x00009e0055334e3f}, {0x000b297d762bcd8f,0x0004090b1e777788,0x0005f7ff73f79031,0x000b978916e41f31,0x0000d6a86b093da1}}, + {{0x000049a7d1255d7e,0x0008c8b12a9250ae,0x000341efc83f0f58,0x000003e1e125c570,0x0000f75675c0a287}, {0x000daf8b1258cf93,0x000cabe2242a1697,0x000503d8cea55b42,0x0002e7bc47653393,0x000010c33e17e789}}, + {{0x00005ea79f286771,0x000e27569d6a75ce,0x00081e4e2f605135,0x000742a515ec1123,0x0000af60690f9618}, {0x000edaa92529d0d8,0x000dd00e97be79b0,0x0002108f6ae93abe,0x0000519721405467,0x0000ef5c7cd11264}}, + {{0x000d7e85074cf812,0x0000fdaef4fbe1a1,0x00029585e7cd8874,0x000bf4683db12a45,0x0000f263cdb933fd}, {0x0000daef9cecfd73,0x0002d1cb1ad9ff75,0x0001e2010333c1bd,0x000602f2eb13e6e4,0x00008c434479fa32}}, + {{0x000f364154e53c02,0x000b2c50b3e176ec,0x000b8ac60e89a87b,0x000d69c11fc58ebe,0x000070424c27f1ba}, {0x0003d753d21bb139,0x000b6450de0ee6cb,0x00061e4b1f84aa55,0x0003f32665545bec,0x000084a236952f13}}, + {{0x0003559faf384825,0x00038d591b30f3b7,0x00072436cb28e627,0x0002d24feb572f5d,0x0000a8b72daa2f39}, {0x0003eb59a42e3589,0x000e94348dc3c258,0x000373f8afa9d0e6,0x00065df154badfc5,0x0000c01d9c6026b4}}, + {{0x000a5d00987d7af1,0x00054d16fb7aa127,0x000a5390ebddde5e,0x000638bdd6eb95cc,0x0000ad6055b0a46b}, {0x000e6fcc176765e6,0x000a926d17614afd,0x0005b60ce8f86b23,0x000cb7cce2306fd5,0x00003641982b357a}}, + {{0x00025cfb6810afc0,0x0000d2ca6813e5c2,0x000d4b0af3ff9d91,0x00060ae0e7a3e4a7,0x0000f245dbc069b1}, {0x000feb26a5cb6ec8,0x000bccbcb43885f0,0x000e47433ac2cdbc,0x000d82e118d811be,0x0000f794b01a4d8c}}, + {{0x000b7da95b4aaf8b,0x000e80a2c2af911a,0x000a345252c2ffde,0x000120078e3c033d,0x000043c12ac705de}, {0x000a2b459a347a22,0x0008ec984c45ab7f,0x0004f78db43cb528,0x000713cad280f6bc,0x000082a8e65b4562}}, + {{0x0005a98aa0ade635,0x0007b2a62c54a937,0x00023803b526bfcf,0x000b028e8fa38d03,0x0000e116fb100b08}, {0x00099fca2c266e2a,0x000cb41473a5abfe,0x000cbd4a3edc82fc,0x000ee0a832b0f682,0x0000c6da25c35e5c}}, + {{0x00004550befd3bc3,0x000b40a480954444,0x00050861335df122,0x0002e8d27b00d3c2,0x0000e5cf22108602}, {0x00032b19ede4f65d,0x0005402e3b45b297,0x00081c377a4b3990,0x000db8602b61ae64,0x0000853d2136c902}}, + {{0x00041daa3fade2f3,0x000c4f5787b60696,0x0000017c50c733ce,0x000cae7f1ea7c369,0x0000822da6a5138f}, {0x000278eeafc2f192,0x000da7b7d5aa7a6f,0x00077a2da02fd70e,0x000a24eb85681571,0x00004c69d2e8b3fc}}, + {{0x00061ccef0bb0ac3,0x0005ae0f16b6abe3,0x0006987ba1d88953,0x0000e4764662ef0f,0x0000fed054617265}, {0x000889078fd300ed,0x000dc644c4935004,0x000723fc14e7aeb9,0x00001edc7f36fff0,0x00004b9f194f4d3c}}, + {{0x0002cce358b66aac,0x00016e2bf8e318a5,0x00084f0df71d65c7,0x000699f185f6f605,0x0000d06b9aba0d6f}, {0x0005205b7b70371e,0x0001c3cc258b70b1,0x00064ef797aab8d5,0x000ae313d81500be,0x000091b0d1e2d796}}, + {{0x000c14085cd77a2e,0x00055b024ee5e095,0x000a1a0b278a5dd8,0x0005b23d4b412cf3,0x0000f1bb25ca44f8}, {0x000da53ecc55a1cc,0x00040b943b5047b6,0x00089e5806f90cad,0x000403b58fa8ea96,0x00002429e57eaa6d}}, + {{0x000fdb4fc9660aab,0x000ae4b79d49d8f8,0x000e3da0cdf3ff94,0x00095a287b418943,0x00000220fb3bf163}, {0x000a22b7dbf3af75,0x00010e4436d28b1b,0x000a5068eb344ae3,0x0005e62736f5e1f3,0x0000f7041a241e82}}, + {{0x000ddbeb3f0ad80e,0x00075c157deb17ed,0x00083992e4d16850,0x00000290b495d7d2,0x0000c100310a5d3f}, {0x000f68ee053ebdad,0x000e0742709e626d,0x000d131a85412994,0x00030749a376ce4a,0x00006015a407e49b}}, + {{0x00032582654c7441,0x00053280089731ac,0x000bb5cd371832d1,0x0001aaba1ddd1d3b,0x0000ce419eac3358}, {0x0009570f5151ed5a,0x00076d6327900c1f,0x000c1968aa5e7f59,0x0006745c1da0190e,0x0000929c46f7b7b8}}, + {{0x000957b50de1fb7f,0x000cd8dfe690465c,0x000125b716eecbf0,0x0006b08cc2cd7fde,0x0000cd58f093a3bc}, {0x0007ffe391cfca39,0x0001ad8536a941f1,0x00047fec75582f2a,0x000ad3a9a7bfe386,0x0000e968cdb6aa35}}, + {{0x0003c22a58371af3,0x0009c11c7d557ef0,0x0007d54999e44d4f,0x000d7878f8030b46,0x00009bd72fb1023c}, {0x000507350d5a894e,0x0000975cf9c22941,0x0007ee69d55c81fa,0x000da33294738695,0x0000dcd116f20c82}}, + {{0x0003d73ce3e731f6,0x00067ef5c65f87ca,0x000cdad304e237bb,0x000b03dfef249e4c,0x0000d7ab5f93a8aa}, {0x000687e71c7835b9,0x000ada6bfddeaf3c,0x000b7e2419bf388b,0x0008a2c3f86d5779,0x0000dbf47353ff02}}, +}, +{ +/* digit=26 [{1,2,3,..,}]*([2^182]*G) */ + {{0x000d03b214a50ffc,0x000ef4d64a402d36,0x000aa27d487e7e1e,0x000960971f296c17,0x00001a46349f6f07}, {0x0006c65b2e7b77fc,0x000e7b3f579f668a,0x00003a0809d29fb8,0x0002f59cccc9b480,0x00008b96ae5ed56d}}, + {{0x0005623d2692dce7,0x000bb1439ee234b8,0x000abb782d3d06e6,0x000ad2f5b24c26bb,0x0000e1e5daf85aee}, {0x000f6b36e620b2be,0x000a6ea10ef984fc,0x000e9c789089a1c0,0x0008b74663659974,0x0000964db299747a}}, + {{0x0000e9e78a6de0fd,0x000e2abdcd0cfd27,0x00058ced92b387f3,0x000ff3a326731463,0x0000d2b37033bfd7}, {0x000a11f5037eb879,0x000c93128308bcfd,0x0002cecfc87b981c,0x000a5ce342d6130b,0x0000f944d511fb1c}}, + {{0x000f4a7a5b2673fb,0x0002ae68fae4404a,0x000f3366ba0604c7,0x0000b42cf803c9c0,0x0000ee8762def9c5}, {0x00068b0cc0c37ee0,0x0009620fc01bad69,0x00028d071cb3006d,0x000f8e637903ab4b,0x0000248af8b7ed90}}, + {{0x0004cdaba9bab8b8,0x000b4adf23c61405,0x000ea4e3112b10ca,0x000cff8f40c789d1,0x0000f3193286f762}, {0x000bc201e35954b8,0x0000e44d9cd0d7e3,0x0002dddc5389fd0d,0x000726e698571e6e,0x00003a64f0002bc3}}, + {{0x0007fb0822f35da0,0x000f09896ddacf82,0x00029979bd5bf27e,0x000381fe1269fc42,0x000052db83e4e95b}, {0x00050a861613e2cc,0x0001b06477bfb26e,0x000ecf598588df85,0x000b11c80fd01053,0x0000225a35dddd00}}, + {{0x00008399fa0ca14f,0x0009af16e80f4a00,0x000377c5e70b4acb,0x000c7c3b7a59ec93,0x000030724a30aaf5}, {0x00045d067262f443,0x0004b25982507749,0x000bd81b974e4f49,0x000a4d9132316fb9,0x00009a156b7e230d}}, + {{0x00040413b3024eea,0x0005d69b55098af7,0x0002a1af66a8f315,0x0008239a731304b0,0x0000e91a74955492}, {0x0003e0c7ee6a3f82,0x0008e0bd9c79b191,0x000152ebf5971c24,0x0000a198183e438f,0x0000d267b51648c7}}, + {{0x0009e678da935547,0x000192f9368350a5,0x00092c6744306b26,0x0001c83d266e0e8e,0x0000ff9bbcdce63d}, {0x0006b94ad0d71138,0x0007aa419046b6e4,0x0003f4797c423b94,0x0002636860d19aed,0x0000349f4cb07f5a}}, + {{0x0003e6b28a2b8001,0x000d21d65179ca2e,0x0001871c7a0e4390,0x000d93c4cf04dd6a,0x00003d99bc265487}, {0x0004e3cb86057988,0x000c2fe15fb3216b,0x000560cc19a197d1,0x0004a67b74e959eb,0x0000f4e1b585517c}}, + {{0x0004cc98e585076f,0x000e80aad228c051,0x0004600361200736,0x0006fca66598227e,0x0000a461711c06d4}, {0x00065a584be71d79,0x000f1f684055450f,0x0003eef672a8e1c0,0x0009f9a749b821fe,0x0000188a93a6ca82}}, + {{0x000d9a6edbbf0204,0x0007fde9666ee420,0x000b10356afb0a5c,0x0004d7dfc83b0c37,0x00000e52e0312799}, {0x0009e4ce359cd84b,0x000bf43f9183ab0f,0x00099c7e0393de76,0x0004427f846ebac9,0x0000439eeb2f8904}}, + {{0x000fce31fa271e8f,0x00085dcd6ab53339,0x000bf17ca52896f3,0x000c00ceed5c8afa,0x0000aead04245383}, {0x000a90776147dd2a,0x0001155288ca6668,0x000a7aac8449f137,0x0004f1a2e10e32a3,0x0000c8394d4d3c0c}}, + {{0x000f50c692933c5a,0x000c78ee682abe36,0x000b3d9a6c4ffe44,0x000be5c7b7730907,0x000000a137e49709}, {0x0001aca96183079e,0x000f9f04811611ad,0x000e37c96ce57770,0x000dec262fa1d23f,0x0000e281f8c1077d}}, + {{0x00025dacbfdb5d2b,0x00008995387e4bda,0x0006607c2701b7ab,0x00021e573e7f7184,0x00007a3aa3d01161}, {0x0000e9867cd0a313,0x000894b24ebf17cb,0x00086622314b0868,0x000340b1fc343aaa,0x0000480efbe0da3c}}, + {{0x0001cf09163daf1a,0x000e3feb1c836f08,0x0005a4a98decbf2d,0x0000d647b2ceaa70,0x00006d8310bc54fc}, {0x000b4c2600d63727,0x0003e4d5e8071ebd,0x000666689b444f65,0x000194168bb5dd62,0x00000c6b36071bc8}}, + {{0x0003c4390dc638a6,0x00084ed1e9bfb767,0x0003234c2e027266,0x0007342738b46e6c,0x0000f7959e2d7589}, {0x000dd45f4888ca02,0x000eb5127527806a,0x000e9bae4eab90bd,0x000a8b2d4fa5ffe4,0x000087b16d15c5a1}}, + {{0x000095b3fc633a8a,0x0007316bca0fc94f,0x000d8b2668cd3581,0x0008cbfa5aa5e026,0x0000c8c21a873920}, {0x0003e4ecb61679d4,0x000355a4fcc28c11,0x000ca6257920c25f,0x000b82d2d14b872a,0x000011540c35e1d0}}, + {{0x0006e26c82c45233,0x0001a997670789d5,0x0002a43f81b41944,0x000726ab8025355b,0x00003f01d8297cfb}, {0x00048146db204a06,0x000c7e02913ffa0e,0x0009ca312337ee0e,0x0008727e2840e097,0x0000fc4d0f49b524}}, + {{0x000b8a12308e33da,0x000337ec4d8beb7b,0x000c1659146b745d,0x000de150304503d7,0x0000d024f01e4921}, {0x000a6c823f9984d7,0x000eea03c4fda33f,0x000cc3e9c09105f7,0x000b318d61bb4a13,0x00006e743847f379}}, + {{0x0002cd374b837d25,0x0006c2ce00b7c947,0x00043b58db8cf662,0x000ecfef51327052,0x0000ac22adc4bf4f}, {0x000d1d45993f14ab,0x000739554cb38af5,0x000a81d9c426f8b4,0x000c7f0bb7e92096,0x00009053648a82fe}}, + {{0x000ed373accc4794,0x0003f4fa67ee2977,0x0000311becb2042d,0x000b24d99c7a2ceb,0x000036169432637f}, {0x000893691b72a9eb,0x000ecc61e9fc1546,0x000f6ea558e349b4,0x000779af664fd7fe,0x0000108ee2c5323d}}, + {{0x000ae27d9b8b43d8,0x000f3dcc55d2272f,0x000fb53844004b23,0x0004b76bc98d5c82,0x0000ce7f298d8e2d}, {0x000e2a94d1a64a33,0x00061562e50f2006,0x000029eca89ef15b,0x000ee81c47d9d4c0,0x00001a9fd03172d1}}, + {{0x000e1f968fcfc9eb,0x00006954531ab241,0x0008e861c066d0b4,0x000dc8c192eba4ff,0x0000ce2adf88d121}, {0x000aad0af982f095,0x000e37d4476b8527,0x000cf5d53ffa76e5,0x0009468c298e73ad,0x00005bffed75e1d3}}, + {{0x0007b7598b4f4c18,0x0008c456357c5e26,0x00015f31642f0a26,0x000bc5a0a3a625d5,0x0000d18b2d13a25f}, {0x00020409ad1c3378,0x000465836e75f72c,0x0002c5ec514b90a3,0x00016a126f9a9b39,0x0000d930609e4c2e}}, + {{0x000c5bc32c3d376d,0x000ee0c900c8573f,0x000eba03819e1ab3,0x0001b7ec2fecc561,0x00001001e880c624}, {0x00029ce1174fb908,0x000642285b2c2478,0x000e27cd432e3da1,0x00017bfd02b9a902,0x00007f7b6a8b6d20}}, + {{0x000b1e4ecc5b0dae,0x0005c2c0e62e9f5a,0x0006c9b1bc80f2c5,0x0006a81d4c1fe7be,0x0000c726d37bcccb}, {0x0001e5d17cfa0d17,0x00024f9bf26ab169,0x000ae21bd95ea4e3,0x000c96246db5808d,0x0000a655e7c27c6b}}, + {{0x000c7fa80a03a60a,0x0006bec2b0bd1212,0x0005bf438beb7af3,0x000a43da5be37048,0x000068eef804296a}, {0x0008674e2d968fc6,0x000f0425a5c48998,0x0003907aaaec9eee,0x00004751bd315af3,0x0000485845c77215}}, + {{0x0002d3539f63c362,0x0004eb689b184334,0x000fbfda21a18b97,0x0003b8d5ec44e740,0x0000b3ef041e5ea3}, {0x000172b46d952e28,0x000695f9dd9c7154,0x000c09cc503a2dad,0x000a80b8da9fe4df,0x00006bc6f98f03ef}}, + {{0x000aeb710af227b1,0x00042752ebd12219,0x0007f5abe6fddce3,0x000db478c999a0d0,0x0000464bcddc627b}, {0x00057116a55b2f45,0x000c46f39dc73fc6,0x000bc331ade611c7,0x00096a74bc1efafa,0x0000696914d1a572}}, + {{0x0005d9abb772a0a7,0x0002a585878f4775,0x000a12aabfef29ac,0x00077327bdcdc5cb,0x00006acb1b0fff47}, {0x000942a009622cf5,0x00060793cbe33a99,0x0004e6319018ba81,0x000462893e1ab4e1,0x0000067a7a34b6f7}}, + {{0x000c5d6a01c29e20,0x000c5755b9592a39,0x00003bd60271462e,0x000f05b7ed4bed82,0x00002c26351eea6e}, {0x00034a423d7cf134,0x000f08beb438aa4e,0x0009c47c4106b0b3,0x000affb4d68d1672,0x000093c8daf9d600}}, + {{0x000ba868113c9a1d,0x0000338cd1fd0610,0x00063c596a184b17,0x000121f53902bc06,0x00002a0f700a0162}, {0x000d41437a1108ab,0x00028b89ad88ec92,0x0000900636b15cde,0x0005693beb3a30fe,0x0000f596d95269aa}}, + {{0x000383992de6a0ea,0x0001c0eadf49d191,0x000b6249f08b65ce,0x0001bf26ab78aa37,0x000036b6d694e14f}, {0x000cd0f12f4691f3,0x000c7064c2be3f58,0x0006959713f90dad,0x0006d890ca9925ff,0x0000501135076e91}}, + {{0x0007b0cd9dce526c,0x000768dafc03b308,0x000d34455379120c,0x000a2d9703f89047,0x0000693de4cd17fe}, {0x000b57df03438758,0x000d3febe5d03f63,0x00006a2f5070a0ea,0x0005caa95fc81462,0x0000a1d0ef60cf4f}}, + {{0x000faed6a35b31e6,0x00027b0d2c666a29,0x000c0459970c0221,0x000d9efff00dd62e,0x00009fd870cfce88}, {0x00072489fe1ebe36,0x00056c3b41919584,0x00047468a39ca80d,0x000ed62caf69e96b,0x0000f68b71d9b183}}, + {{0x000f69c3fcce6d5b,0x000cf30e7ccdbcc6,0x0008023f7571be87,0x0006101b76ba1de8,0x00008ff4180c3051}, {0x000651f6c7323796,0x000d92757ac444f2,0x000e84bd2228de69,0x000d6650d8cb40a0,0x00009a11dcee05e3}}, + {{0x000a9ef3a388cd6d,0x00079a08b3f94c88,0x0004ed893c32273c,0x000eaa93278afa0a,0x0000804db1067191}, {0x0003ed02eeb1eaca,0x000aa269e85917ec,0x000b98ab4063caf8,0x000a9141573324dc,0x00003c41f6a74303}}, + {{0x0000a2c274fafa67,0x0007661f730e3668,0x0002382fe8bfcaf3,0x00019134ffd8ed37,0x0000935125943aa4}, {0x000244800946cd0c,0x000df0e459918728,0x00032302f204b042,0x0007899c8ebafedf,0x0000be5328a81cb7}}, + {{0x0006d0031fcee36f,0x00055e0a95cad3b7,0x00011f2abc910fa9,0x0005739da8677699,0x0000b7ac64a83b18}, {0x0005369151002784,0x0009d0563f5b5d1b,0x0007eef50df8b5bf,0x0008efc54918844c,0x00005ba66117f7e1}}, + {{0x00017aaebb23a9a3,0x000fad1195b0c4f6,0x000a08f41d8d5df0,0x00015b6a2f309dff,0x0000436a93489d4e}, {0x0002a63bf9a141ab,0x000fe97001b45cb3,0x0004f5b5f37347b5,0x000d0a7ffc6ce12a,0x00009b94f9ad54b9}}, + {{0x0006d07205aef3fc,0x0005231a57be8a89,0x0005a94a39f4563e,0x0003e9dea91ed89a,0x0000f63dabb48ec7}, {0x00024642fba4d373,0x000230b44974c808,0x0004d50af40a7979,0x00079137f5088ce2,0x00000609fca476c9}}, + {{0x000e8b2818c83ff4,0x0002f8faff6baa52,0x000d294722da303e,0x000f9977a2d4c556,0x0000cf6d037dbbd3}, {0x0003f7b469280f8b,0x0005bfc44a6f2f63,0x000adb24e051b615,0x000224ead0ac57d2,0x0000adcd2c71b8b8}}, + {{0x000f8bf1604c0532,0x000c14fadeb8bf40,0x0000e2ae1f370c05,0x0003afc120728f88,0x00001b8f66baa365}, {0x00075ab77c2209cf,0x000d8c32043fe2aa,0x0002c82e849b56c7,0x00012fd42038c184,0x0000fe0f8955a57b}}, + {{0x000d850f732fb7fa,0x000609faf4d7ae20,0x000f7f1924417e70,0x000349fc42eeeeb6,0x0000a6a934517190}, {0x00018b7cf247e02d,0x000f500de589351b,0x0009687358eba05b,0x0009fc5f5739e627,0x0000ddef5f556d65}}, + {{0x000774d30f504541,0x000f79d101da68e4,0x0005271bce5362f0,0x0001e6faa152f180,0x0000b838e945b4b6}, {0x0004064dd6323f11,0x0005ebb09f685488,0x000d8d4d8dcd854a,0x0006b7868850b02b,0x00009b7ff60aa093}}, + {{0x00094c377476a6c8,0x000f8bd879dbc613,0x00067c19587966a7,0x0002fdcaec3c6f44,0x0000f61ae7f6b03a}, {0x000e1fad21564449,0x0002c030664334ba,0x000c37cd03a60116,0x0003c2589ba1879d,0x0000869a09a56a80}}, + {{0x000ca054eff5af2f,0x000c2afeb00c909e,0x00030409f4f95238,0x00042f33519755ec,0x0000a031194f7bc2}, {0x0002d9d860515c64,0x000282b7c41b8262,0x000d58ae84b75001,0x00033911d917c2ec,0x0000382de3015dad}}, + {{0x000b6f92039287b2,0x000424f610648a17,0x000f670c6adaa03e,0x0005ebcc4155c96c,0x00008a428fdd5ded}, {0x000dc8bef29ae895,0x000feb853aa156db,0x000d58735fdd8c1d,0x0008ef18dbe67090,0x00005223ae90f12f}}, + {{0x000da0a305e720fa,0x000a9efc2a6ba83f,0x0009bb0d2d9ee4f0,0x000f424f84963425,0x000028fb31a147c9}, {0x0007a129692f9dca,0x0002c69d8dbf3308,0x0004070a2d33c240,0x000e53497ed09a9d,0x000056c1a642f857}}, + {{0x000fea20ff9207e7,0x000cdcba65125a16,0x00026ad2a6c19e9f,0x000dc711f4cf52db,0x000097fefb6bc4e8}, {0x000a94c4f27e69b5,0x000570e2212029fe,0x00031e5f3eb7feca,0x0005eb519c7da3b5,0x00007bb88afb91d0}}, + {{0x000a7012729021cb,0x000f25e2a3025023,0x000308907678c8f1,0x0003c3d53c45e204,0x0000ef510928bb4b}, {0x0002e7148c22ff2d,0x0008709b3aeae6c4,0x0007356abf6dcc9d,0x0005788d1b63fe8c,0x00009e378edf3940}}, + {{0x000ddeb357d98af5,0x0001e85a4558478c,0x00080a0cbd7e0c6a,0x0001dd3ddac79b65,0x0000056d8d40a6df}, {0x00091ba3a685470f,0x000a930cac5404b8,0x00005c3833644e17,0x0003a3e93f00d595,0x00008ff0d37e4337}}, + {{0x000882736c20485a,0x00008eebd8ed436b,0x00008765d62ca0ee,0x000eb404c1e6a63c,0x00001f51c3d2f4c5}, {0x0001dead0e0240b4,0x0005dc01cee53aaf,0x000ff1626340c23c,0x000eeab99ab3c4fb,0x00001c9f03e31c0c}}, + {{0x000ae756a6906fad,0x00063f4f9ceccc4a,0x000097866d772f72,0x00049ade04e7abe4,0x0000daaa2d4ec655}, {0x000f24569a5e1b2d,0x000cf346e0eedaf7,0x000077bb20e192c6,0x0002e1123812eec0,0x000043676cdfbb9b}}, + {{0x00058d8a85049646,0x000da101751a9416,0x0004052f48e7403b,0x00083e451d1f0c3c,0x000099b66e6f5e43}, {0x00099f641750313c,0x00052d7eb737c5b3,0x000781bc1f3ec6ea,0x0000d8f06b519c58,0x0000207bc899b604}}, + {{0x0008f806abe9cc03,0x0000a9a929601fb3,0x00009bbbf082d14e,0x0002f8208e30f142,0x0000554af3ba8279}, {0x0007f63f5b712db0,0x000f5e6bec6bc64b,0x00064a6500c0f15b,0x000c133fac18ffe8,0x0000426e543866c0}}, + {{0x0009d4ef17dca9b7,0x000a30ed49144714,0x000b7c7c7ff66bc6,0x00050b6f85c5627e,0x00001b5beb731ddf}, {0x0006b5a5059abd38,0x000239a4d95c865e,0x000fcce6a4320b87,0x000f54de8482cded,0x00004902e9c46a14}}, + {{0x000b7856664976a7,0x00078969c15376b1,0x00040ec0985a2ed7,0x000c001d865d85f0,0x0000f36fd193022a}, {0x0005392113e30f9c,0x0009f74dd0ed247a,0x0005828f69efb3ea,0x000a340b38e8b204,0x0000360f51bc06b3}}, + {{0x00080676229e895d,0x000b73902cd1daa3,0x00033ab334e9238b,0x000898af084a55e4,0x0000ad12d95a215d}, {0x0009537f56338b7b,0x0006b9ccc450a222,0x00005543a3bcfda1,0x000c3e65d49dd006,0x00007bfd6c4ca559}}, + {{0x0004e97c95dade65,0x000a255cb184c7af,0x0001913f02135561,0x000dacc6ec185432,0x0000c67073eac645}, {0x0006dbb0217a30c4,0x000ff3ddda1e0927,0x0001ccae8f3399c2,0x000457eca9825683,0x00009678071934aa}}, + {{0x0001b26feb7180b0,0x0003efd985904aad,0x000b49ff165faabd,0x0001d381a30fea11,0x0000c5c8356509ff}, {0x00001e0aa66f02a5,0x000536ad9cf84113,0x000abbdc628e871a,0x000d020376aaac57,0x0000a1378acc9219}}, + {{0x000d95e7668e901f,0x000060472569120d,0x000fc85db23dc73c,0x000aa6886846b97d,0x0000132a04ded861}, {0x000d5373fb18ede0,0x0004a57df5ac83b6,0x000da2aea92385a7,0x00022238fd2cc831,0x00002fe0eb0e035e}}, + {{0x00024cd9846e4d56,0x000a4f069d729131,0x0001f60df8dab9fc,0x000503b97c211a7a,0x000006e35fac3fa2}, {0x0003c474bc694434,0x00075c5dfd89e498,0x00042a47aa5934ee,0x000302b62af4f70a,0x00001298623271cc}}, +}, +{ +/* digit=27 [{1,2,3,..,}]*([2^189]*G) */ + {{0x0001b9cf1fff1383,0x0002e979256fd16d,0x000024e5cabb7109,0x000174971f93d488,0x0000f4a50d323ce2}, {0x00069687a5e60329,0x00035725ef1c291b,0x000d78bd756a79e4,0x000d4bb336a131fa,0x0000a42d2de19780}}, + {{0x0000770b1fd77c42,0x00073832340c46a0,0x0008fa3e971dd6ac,0x00055cfef494e03a,0x0000a4bd01ea78ff}, {0x000549569ec3b61c,0x0009fab41b9cb0b0,0x00085d069aee9d31,0x0005df668e37395d,0x0000222a186cd468}}, + {{0x0009034839af8af4,0x00043f6fb866f9e9,0x000b3d4bd58c9dea,0x000f06eb6869dd3b,0x000070c089100bba}, {0x00084c12d0fa30f3,0x00063a684ef0b7b3,0x000c5e098f27fa26,0x00008ba673334a74,0x0000febfadaaed70}}, + {{0x0004aabd136b85c6,0x000e5936fc61535e,0x000d5983d0ba7b67,0x000ed94d56bc23ae,0x0000fafa92939d12}, {0x0005ed1e9964a345,0x0001980b9f13e261,0x000c2d91983b5b76,0x0007686f1cf68c47,0x000002a1721de2ca}}, + {{0x0003d97f0a373569,0x0009541867b5c615,0x0002be69e5b1a6cf,0x000d318011508202,0x0000616a3fc9c362}, {0x000f8fb5bc1d92d7,0x000014a7ecae4920,0x000a07c0dbe70008,0x000136174fb9a821,0x00004a51fb854142}}, + {{0x00094501f646ae21,0x00093a3042a9aa65,0x000c3d31b80e7d9c,0x000f2a8addb71e1f,0x0000e4b00409743c}, {0x000cfea457fca237,0x000419bd5f99c642,0x000c9c750bb14dcf,0x000201a965cbd91a,0x000003a84781aab2}}, + {{0x000fc80219d626fa,0x0003948b0d1fdda0,0x0006db88bb4e6b39,0x000ff4f7b88d70b8,0x00003574172195ac}, {0x000d5e56f3d1172c,0x0002cead1829e0f5,0x000565f4996ea68d,0x000bab6b497081b3,0x0000f563edef0941}}, + {{0x00052442b55502c1,0x00010eecb291d39d,0x0005128fee4d7b18,0x0007125122549f56,0x0000056059074287}, {0x000a0909597c6015,0x00008af2773cc6e7,0x000b42443316a926,0x0006dec8c5b194f0,0x000077ea1102d890}}, + {{0x00069a576212f358,0x000506a394e93535,0x0009b22ea1ceb350,0x0000677ead07678a,0x00005b082f491db8}, {0x0004a81bf9ec1ad2,0x00071aee7ba0c916,0x0004e80a1337bc58,0x000abdbd5c577480,0x00000fc252a5dd59}}, + {{0x000a054c1e13f877,0x0003dcc6b450cabd,0x000d3144e7b6b2ae,0x000ed4c39ca22c31,0x0000f9567c38732a}, {0x00084e2f2344d0aa,0x000ec5ad8d221d7b,0x000e1a873a63bb2f,0x0009666a6747d67c,0x0000358844479c6b}}, + {{0x0007d2edba4a511e,0x000f2f775e00973e,0x0006cd11f44770c8,0x000bfe41e571cfc7,0x000075b695fd8542}, {0x00006e872fba8b1e,0x000e6a6534ab0dc0,0x000f0febaa07564a,0x00029bcfde2d885e,0x000025ff3bd3db13}}, + {{0x000f42c3d41c8e40,0x00027896206e317b,0x000581e8807e38f9,0x00072dbb1ab849ed,0x00008c003afb741e}, {0x000b05a75a716b03,0x000c35acc098339f,0x0006bb409efb624e,0x00044ea061fe93db,0x0000639c1c4896a9}}, + {{0x0005df2305ee4c95,0x000fb06813dbe2b0,0x000f5f222f613984,0x000e07b842f57781,0x000029d555fdb379}, {0x00085c8602f378f1,0x00078c23e6a3833d,0x000b5d0c4a1b72cb,0x000d5feb45473e34,0x0000db9aac6b4203}}, + {{0x0004b65361be7b6a,0x0002f2fb6b49ee6b,0x000913c64c9b2f8f,0x000d30a7c4338ec9,0x0000f69135ef57dd}, {0x000249afd7bdd274,0x000d7c213f9526e6,0x000247857a28573d,0x0005a9aaa2885378,0x0000cb194be632fd}}, + {{0x000c83d371b3f5e8,0x000cb5a067330a04,0x0001dc3a2fef33cc,0x000b187549f824ec,0x000091fb8cc00b56}, {0x0005b558729aa3fe,0x000dcc9c90c35486,0x000ebaa7ccca0c6a,0x00040c03f91930e5,0x0000d41e9d7170af}}, + {{0x000369c517263725,0x000f5b9c4d8f25e2,0x000af08d2fb833d3,0x000dfff4079aaa6e,0x00007b1dbc5eff3e}, {0x00095ef86114ccdf,0x000218447b952ff6,0x00028ac9591e2d52,0x00061a5f9065e821,0x00005b37299373e7}}, + {{0x0006de0bbde89cb9,0x000178894e0dfd48,0x00099f1f42306512,0x0005ae303a17d3a6,0x0000e98f7a864629}, {0x000854fd72db1c36,0x00018599b7d0f8ec,0x00067d94864ff03b,0x000a9a11c827deba,0x0000e7fc586d6b42}}, + {{0x0003905c60a37318,0x00020e672390fffd,0x000cc82bc8f9ef8c,0x0009dd202cb0dc17,0x00004b4757605370}, {0x000bd76d355ffa78,0x00062640c3b569ce,0x000d7be663352441,0x000fa5cc00063e7a,0x000041ec6b307eff}}, + {{0x0003445ff1d4f48d,0x00019ad186af8290,0x0003ec32546962ff,0x000c74bee7a65ffd,0x0000f3c5bfad6d70}, {0x0002af7a0d407d12,0x0003b49a55ee5914,0x000e67fde3d1641a,0x00017386bd678d4a,0x00006a7789b10f86}}, + {{0x000279671048d213,0x000fbf93af1c754a,0x0005ef03eed832a3,0x000166c4c086a7ec,0x00002ce472c668aa}, {0x00083e191dfa1fef,0x0001f9f62e555da2,0x00033e09245f9681,0x000834d7128c2232,0x00005980492cfaa4}}, + {{0x00005ed385c6f58d,0x0001e940322f855b,0x000abd1bdfe12344,0x000560254323ce5d,0x00003f3272b8e138}, {0x00091b1129ec9aef,0x000937dae4ab0926,0x0003b89972cd1064,0x000feb302abe5ff3,0x0000ac9ab092ccdb}}, + {{0x000ab8834fcbe7cb,0x00079a36285466b2,0x00021763ddf9573a,0x00087f23dd49e9d1,0x0000960a7dc34467}, {0x00024b2027d5087d,0x0008789865adccc4,0x0009d56dc06f79cb,0x0001e483a7a6349e,0x0000439526bf4c6c}}, + {{0x000850573c100bd9,0x000e92a154270a32,0x0002c03764947229,0x0001b3abcb8d85d4,0x0000c6b864e12fb5}, {0x00099a63a0948b0b,0x0003d11e7737521b,0x000f11ee54cc22bd,0x000c0f3897c28fe9,0x0000887a86105810}}, + {{0x000e64b613b901f0,0x00020b63d0cf3e5a,0x0000509aed92b157,0x000a4af71b397af8,0x00000f70a508ac7d}, {0x000443b477982ac4,0x0007bfcf80070119,0x0000ee5d52ca6ab5,0x0000fb76fea256a7,0x00001425f8a18955}}, + {{0x0002520e8f5fdd9a,0x0004415b44379a62,0x00013a5cfb245513,0x0007ff26da58b6c6,0x0000c62c15ae2094}, {0x000a325e4261f9e4,0x0006f038d32e2ef0,0x000ef3fc6abc70f6,0x000e30d93ea52afe,0x0000eebb6abb94e6}}, + {{0x0000247702ed7bce,0x00034f5464e44269,0x0009e8b128e5bb85,0x00080926518e624b,0x00002be136277a21}, {0x000471e16b34ec34,0x00012108d0ce4dbc,0x00009af5e6abb920,0x0002e754d17d1efb,0x00008a48cc1afe3e}}, + {{0x000e0422139c98e7,0x00020a9fb3a64484,0x000e10ede0bcc79d,0x0005a6dc2fa5ba99,0x0000ef0d52b0fc6c}, {0x00063d55b1d96541,0x0009f6d4c86785fe,0x0000eb9acfac3d5f,0x000572a8f2469101,0x0000dcb464d4523f}}, + {{0x0004f69a1b9f6cfb,0x000ce213f5056161,0x0008b7d48946501e,0x000149f12d547fe0,0x0000445a285c7f6a}, {0x000c4823f1a2ea23,0x0001385a5394c778,0x0001c1b9366acedc,0x000ab1c3ad0d81be,0x0000a11359b3675e}}, + {{0x000fad96e9cd5888,0x000b7a1e29d6289d,0x000c4b2381c4c5f0,0x000230ec1a276eae,0x0000dbfa685019cc}, {0x000f4922efdee4bc,0x00075cf61a1c6547,0x000edaf4fae86ec1,0x000804a8d53bbe31,0x0000fd5e6fb848cf}}, + {{0x000990f9e61819db,0x000a087bf284d04e,0x00046cc595c29ec5,0x000d285ade5df61f,0x00004427bdb3cd77}, {0x000aa52009715323,0x00064ee140eb5a6f,0x0007110a230db79a,0x0005beabf7fc498a,0x00005a15127fb48e}}, + {{0x0007b770b5f6a321,0x000f362ee591d72d,0x000bf83136cbb8cd,0x00084a2589241c8a,0x00004ee648e03895}, {0x000bb8cbdefa6e1f,0x00067c4e78df9a78,0x0002e73ca978976c,0x0001b28eef0426bd,0x0000de8fdba87229}}, + {{0x000066e356b5ba28,0x00042d6df6f58037,0x00011deaf6527ec0,0x000997dd3caa6655,0x0000dea9d72a1583}, {0x00071e5d50786fae,0x000acede2fe32d7f,0x0001c5ebbc758eac,0x00052ae508ead45d,0x0000105b61fc2cd2}}, + {{0x000a424820880205,0x000253ccc5077e5f,0x000f8c3fe20dc632,0x00062cc0c59b343a,0x0000155e23d52734}, {0x000ac65688011857,0x0001b16ae629218e,0x000d6756f09ff09a,0x0005fb7b7fd5fd37,0x000039a7040ebf80}}, + {{0x0003f9fc60cc69b0,0x000dc05b085eb973,0x0006e237d7c4ee9f,0x000c1aa988f662dd,0x00001d5d34fe8760}, {0x00031c971d36ad9a,0x00021af6097f9cda,0x000a112b99050a85,0x000760dd5b19501f,0x00004b8f2b2a3525}}, + {{0x00023daebb9c4933,0x00067f5f980754fd,0x00044b040f42405c,0x000cf1365bb83ea9,0x0000607651d34cdf}, {0x000cd8bdf6af7f24,0x0009f667d24992b6,0x000fdb2cba8a3b43,0x000216082779e2aa,0x000088707ba1c834}}, + {{0x000625373378cf7a,0x0006fbf97109acf9,0x0002a22d6e706614,0x0003b2b54dde5fc2,0x00007e3dc99d87cb}, {0x000e1cd88864bc14,0x00094f0b89418e8a,0x000a64fc194c02ee,0x0006b75b5f046f5a,0x0000bd2c8c6b65ac}}, + {{0x0002c8cf2c1c71b8,0x00034ba2d46ae80e,0x0005f7bfd38ee996,0x000b7c07f17b75fa,0x0000c9cda0385190}, {0x000ab3a305fb5758,0x000f9bedaa65e5b5,0x0002fd3ce5ea38ea,0x000693fb2d8b1c01,0x00000024b4599946}}, + {{0x000b3720ed0dfde1,0x000d03618777a3f3,0x0001f1f7a5cb0edf,0x000e6286b75f35df,0x0000463e61ef6663}, {0x000b207d0b79891f,0x000bc03f51f18bec,0x00045012b8dadaea,0x0000ea4f5238c4d9,0x0000e7374d260339}}, + {{0x000b9cdebf558d6e,0x000a7fe8cd19b8fc,0x000466552cced26d,0x0007ab4a23901802,0x00007cffa718628b}, {0x000bbebacd192e54,0x000631e137725179,0x0003765188e7a414,0x000a907dbaadfd47,0x00002b4be3e6d8da}}, + {{0x00094dd9e1077a92,0x000ff54da5dfa25d,0x000275244547d0a6,0x000af9942339905e,0x00001db13a32ed62}, {0x0009e8b2ff2ea6f0,0x000ccdb7c81f268b,0x000c0b9228169c5b,0x00091f33ef28ab69,0x000063fd42c2ea96}}, + {{0x00026bdfdc8fe7b7,0x00006cf1c07e97d3,0x000cadbd9a6a9283,0x0002d6bf51c2ba05,0x0000b8cb99a356d3}, {0x000ae7bb14928177,0x000b0e246da65b16,0x0004b026ae4c5b8e,0x000f61a66781bfd3,0x0000dbdfa283ad1e}}, + {{0x00056863c55d6206,0x0008826bbed476aa,0x0000f81fe2cd68ff,0x00028ab98204a548,0x0000057156e622a3}, {0x0005fd89b91e90fe,0x0003deeafbbf9bdc,0x00098a9587ab8014,0x0002738fcf98e3f5,0x0000b981ec89c6f5}}, + {{0x000b316827a46307,0x000a300d18683649,0x000f2fa071726038,0x000d3794466aabaa,0x00003b21867de806}, {0x000d2944b3ec91e9,0x000fdf4baecce9b4,0x000c417b42945b46,0x000aa79fdb7f35bb,0x00003a9f897a4e64}}, + {{0x0005a34d2eebeba1,0x000e6afd5bc4437f,0x000b456c7dd1b3d2,0x000b4153b76695e9,0x00003307619aebbc}, {0x000956bb3e38fdd6,0x0000426ed87648e5,0x0005f711ecd8c046,0x000079d6d63de859,0x0000dbf4b9f107da}}, + {{0x0007e175ead15d39,0x000561b4f3f83c33,0x00011b177a1402ec,0x000a58752be2a08d,0x00000da4d4e2fe92}, {0x000e6e8276401658,0x00032d6c4199ae4a,0x0001faba2e498fdd,0x00014b1af4332ef3,0x00005ba35a81c223}}, + {{0x000649050769b34f,0x00083bfbb56c5761,0x00021ee2541366b4,0x0008704cdec9bb64,0x0000d7945159c0d3}, {0x0008bafaf13e0aea,0x00036e13e82d5eb7,0x000339761f9d8d47,0x0009eca4591e67dd,0x0000d96c07568a95}}, + {{0x0003d5fd2029df76,0x000a5fb33c0e0f3c,0x0001ff5fc68759f4,0x00051f621da14b63,0x00003caa71b11ccb}, {0x0007c30a7e617c2a,0x0009b711ffee663b,0x000759b3ba8a1266,0x0007f0dc13775b68,0x00007e1383f3a56c}}, + {{0x0002e53bb23c1e0e,0x00092de4f81808c0,0x000027ce8893cbad,0x0000f3ec1a375761,0x000021cb492d2c4f}, {0x000aa3245f82dbb4,0x00069cced42a6e8c,0x000b6d15012948dc,0x000fb237260c2eac,0x0000ea4c9c423931}}, + {{0x000296fd70720795,0x000229b349f0d757,0x000372c7ecdb2d87,0x0000ab683986a30a,0x00008eebfefdf917}, {0x0007b20676f23d23,0x0001b68216600cd4,0x000d60209e8a6542,0x00056e7d5a86ec0d,0x00000dcc35fe04cd}}, + {{0x0003bd54c9a586b6,0x000b8854c7485039,0x0005a40f4ec5f1bd,0x000289a4e41a1f76,0x000049dafe50ee7f}, {0x000fd6e34d712730,0x00053fcc6922c67f,0x0006083c963c85d5,0x000ce0b410b01af9,0x0000bcb42a6ffe90}}, + {{0x000b767ca282a4d0,0x00020bd980476c87,0x000bfbe1aabbbaaf,0x000b88e6d7f7cc73,0x0000b94422c7d82d}, {0x0008f139b5e18b15,0x000af37294afe4be,0x00004cff3264b3dc,0x000c73112544433a,0x00005a6007937b5b}}, + {{0x0004af8e5428d95b,0x00010191ac710f35,0x0007cbedd6b7a565,0x000b814d7e43f856,0x00001c5e2eb7d556}, {0x000fcff49a2a7cf6,0x00072f558310e77c,0x00038dd2bc421df3,0x000a70595301fb38,0x000070f7e2a9b2d2}}, + {{0x00078d66e9dbffa4,0x000fd8c7ca048a86,0x0007e3eda5c2456e,0x000dfc3b87b2b93c,0x00008309da1e8c6d}, {0x000d753512b919a2,0x000af02b49c6907b,0x00097e34d80b0b22,0x000116caf4066684,0x0000a329ce0d5c8e}}, + {{0x00018e79cbc3d261,0x0005c013dcb21798,0x0002b229899226c7,0x000ec7a427d40e6e,0x00009be63696ee9d}, {0x0002ca736795eca8,0x000ab6fbe78de343,0x000bd2519b13a095,0x000f556bca40cafe,0x0000db7209b1f081}}, + {{0x00073c09004f67ac,0x000b29108a8f67d1,0x000d371b9f9fcb0c,0x0007a067e6fb34ba,0x00007b352a5eff65}, {0x0004bcafc8686e3b,0x0009f001e6a411ec,0x000e8fb4225c8102,0x0006a982156a2ca9,0x0000d80803a38166}}, + {{0x000da2e4dabb9727,0x000355d6f6b308ba,0x000f1255aae1bef5,0x0001611794716339,0x00007b4e604aae5b}, {0x000972e788159151,0x000fa3d326703740,0x00098bc1191d5969,0x00078a0d4a378bf7,0x00006a59fa849d24}}, + {{0x0000fa58dc098923,0x000a1856964a0842,0x0006b9932f4e037c,0x000814ca2cabcd97,0x000078dcf9cd7aba}, {0x000a197dc3eebe13,0x00042e556e9988d9,0x000157e412bf69e5,0x0009df4f48dcf986,0x00003aded6912caa}}, + {{0x00084e2f15edb89d,0x000ca9cc6e956412,0x00012680b1917ab9,0x0006783f51439caf,0x00005d29d2d26dd3}, {0x000ab0638623d5b5,0x000fed329f9f8df8,0x000792dc163a5fd0,0x000655955e82993f,0x000069608a1e7223}}, + {{0x00050665c639e317,0x0007cd3a0be23b31,0x000d42c79903f0b3,0x0002c444001375bb,0x0000929d6d962097}, {0x000772643d922771,0x000edf18c8218c66,0x000ac87392e06af9,0x0002719c1204c4eb,0x0000d70ae05eaaac}}, + {{0x000b98d73f6132c3,0x0002d06ff3aa0dea,0x000114d3850749fa,0x0007044ffa876d9b,0x0000f45872e2fb66}, {0x00016ce3d2f5b6fd,0x0001dbce4a5c1e39,0x00023420be2346fc,0x000ad2073526e3aa,0x0000ec42bf82e3b4}}, + {{0x000a0e0400250d20,0x00073477185ee8db,0x00076add835f002a,0x000b3b5382a489fd,0x0000bee501d59ba8}, {0x000f808fc2a3269f,0x0005a1a324483855,0x0004b0561e253e07,0x0006877e92305edd,0x0000fe56709ccee3}}, + {{0x000c69fd4d6e9ddc,0x0001efe17ab5ebee,0x000e8772fcc9e90c,0x00075476218c92d3,0x000034d8fe876b89}, {0x0009a53714b3d5de,0x000392d52e8cffab,0x000f9a84a7982c75,0x000969339421caf1,0x0000be235f473bd7}}, + {{0x0004db392168c345,0x000a7d3a892289ad,0x0001c36832b48c85,0x000ed9a7ee4e9c5f,0x0000c04e75e82317}, {0x0001be0108fab1b2,0x000295b25288526c,0x000465a6858de779,0x00095b9a8e5cb36a,0x000089a16a0405f4}}, + {{0x0004dfd0a2e212af,0x00036b8548f44a8d,0x0000661b76948703,0x0005acf11a3d8f18,0x00001c00c194d622}, {0x000d5c1f47b27588,0x0009b03b8c767f30,0x000cb8a097b7b205,0x000c759ac3acc6de,0x0000805e35066db9}}, +}, +{ +/* digit=28 [{1,2,3,..,}]*([2^196]*G) */ + {{0x000c38a2a1d9a703,0x00081b56c40e7912,0x000dd8e69ee22588,0x0002cd3934da3f86,0x00009ea1c46f7d16}, {0x000bbb8bb266d6f5,0x0008f24907c529d6,0x000f29a7ebd75276,0x0002d5547c914e08,0x00001c5ef3df3449}}, + {{0x000a76cc5116d7af,0x000eadafba1a14c1,0x00024709cc081b48,0x00081c7e2a466abb,0x00008b57f0616a3e}, {0x000f956ec6c161e4,0x00000fb95d4f3aeb,0x00097cb468593666,0x000bf252520b3955,0x0000ed97cbc6ae5f}}, + {{0x00086b91a9173051,0x0002f80999c69a5e,0x000310070a4efd46,0x000f45d8957ef5bd,0x00007ce05888474d}, {0x000f95d561b01a26,0x0009d0c4e3c33152,0x0006abee75a4662f,0x00001c4bce657471,0x00009c915c04da63}}, + {{0x0003fced8aa40761,0x000b87e4ac77d3d7,0x0005ac612e5b0c4c,0x000de0d7711889b3,0x0000d21f2a009398}, {0x00066281b56378cd,0x00067c47fa3c2881,0x000dd18a00054474,0x00087c02c8db20bd,0x0000cff165d7702b}}, + {{0x000b9efc0d760cf6,0x00050c278d0980c9,0x00007feafd3862e1,0x000aa3eb68afab38,0x0000647da2895fe4}, {0x000f70e5bbb84fbf,0x000d1eef05b4940e,0x0004b7c6fbbfd8cf,0x000db93150f3a4b6,0x0000b3e4f8d0efd5}}, + {{0x0005488239f8e105,0x00014cfadc9e08bb,0x0008dc975fdc87d6,0x000be3c9a3d0798e,0x000016550e4b2cc2}, {0x00023a4e3abd5d4c,0x000b906da2001e44,0x000060bc93fedeb4,0x000093dc27fd9104,0x00004cd7ca88713b}}, + {{0x000fbf542fa80e44,0x0005f10928bc0a3f,0x0006293cef2e8b64,0x000a898509b32c4e,0x0000b22619841e62}, {0x0007f5cec0217b2b,0x0001d20d8159ff53,0x0004247eb95b2102,0x000f96a510270434,0x000007a5eaff6c63}}, + {{0x0004d031f8bb00dc,0x000b5e02bac4ddc4,0x0000aed50c213344,0x000e05b337dca4b1,0x0000c86350c6fcad}, {0x000a47ddf9ce7cad,0x000feacff71799c2,0x000bb0df8204bce3,0x000e5f8261e40571,0x0000e0c599f1adf0}}, + {{0x0001b1bb94f507fc,0x000b0e3b80fd0544,0x000d3472c146d60f,0x00084fae8223732d,0x0000101a1e7f36e2}, {0x000e5e9e34bd1816,0x000f545cc7b24119,0x000d9ddc782a4857,0x0003d7ca719e13d3,0x0000d9522fd316f2}}, + {{0x0007bed302860d5b,0x000b5abd9969e2fc,0x0005b5076fa90a70,0x000ea613dd5e38e8,0x0000f8c38f07a470}, {0x0003fd5e928fd844,0x0008d2c777f94dbe,0x000e5e8ee0421bb0,0x00090b66f1472441,0x0000b3088fcb535a}}, + {{0x000e1ae7289c2895,0x00025afe82ac1535,0x000bdff2cd902878,0x000f4ef1b8d241de,0x00004fb71fcc98fa}, {0x0004222f68f44d53,0x0002c233b26fdb58,0x00075ebee32eda92,0x000808e057bccbe0,0x0000e4465cfeab5b}}, + {{0x000dfdcd833d339a,0x00020e7a389e4f2b,0x000d23683025a3a7,0x00035da3027d310d,0x0000fdf534e8caad}, {0x000c3671c7931bc6,0x000295770ef2045c,0x0000c060bf62b8ca,0x0000be1c0672ffae,0x00003930a309702d}}, + {{0x0001923fdb3e29eb,0x0001b817d72ab678,0x000b46b1a5f7f642,0x00070769c8c3e584,0x0000d0238e461de5}, {0x000c2ab9f826b572,0x000076be5f5577c6,0x00026baf39420c61,0x000bfa2c745c1765,0x00008bee5c5cf98c}}, + {{0x000b34e1ffbd4f2a,0x000747c36e6384e6,0x000188caf2580fc4,0x000021a1cc113e97,0x0000166f801bb0a2}, {0x000ee689dc2b83c4,0x000fc7170038b4d4,0x00020d913b44f23a,0x0006f4916eaa0f95,0x0000a37abc373fb5}}, + {{0x0008e478edbc9edb,0x000b6cdbf59f53be,0x0007bc01ef6645bc,0x00030d7b078b0e6d,0x000048412e9378f1}, {0x0002f15c532138a7,0x000dc14eed557fb9,0x000c77fae6fb3f15,0x0001ec558fe1463a,0x0000f318b95338a1}}, + {{0x000b7438e5468e71,0x000caedffb29bb1f,0x0002ff19da1a8652,0x000de068d72097f2,0x00007621c88c8098}, {0x00078d98bb33eb05,0x000422f044eced99,0x000e8c4b19e1266e,0x000800261d9ad034,0x00000d3bbc0defd4}}, + {{0x000b6e60f54419ae,0x000b6eca8a0201c6,0x0007bd20f02e3c59,0x000f848a270d2b43,0x00006c057044b677}, {0x00047dc47384cc81,0x0003e307e3f7012d,0x000f9a650ee8e3f4,0x0009500539cdb1a6,0x000072f13befc47a}}, + {{0x0007e2ac62f29ecc,0x000c7076b6aa4df4,0x0008c07b37559318,0x00062001974448d9,0x00008a44c6309b81}, {0x000e2de6bcf14f8a,0x000f4990ab063f22,0x0004697a9bbec1c2,0x00030cecea565c48,0x0000fd3da1c5e5d8}}, + {{0x000aabb0b18a6f6d,0x000e3c002fa1b7dc,0x000818bf3e956799,0x000cb0a09f9d8ac6,0x00004c37af29089f}, {0x000975ede76d2691,0x0000edc449b75047,0x00054acd30477815,0x000fff298f1059ac,0x00007ac93c57a2ee}}, + {{0x000b8d64baf52f42,0x000b09a3292f23a0,0x000456c047f3f84b,0x000fc353ae21c75e,0x0000110967ba5ea7}, {0x000db604a4420675,0x0000bc0332e07024,0x000f18635c4ebf20,0x000ecf2e0f788c83,0x000050d2e58fb836}}, + {{0x000c9678e5433b08,0x00070837189e593c,0x000f524cd351331b,0x000d2130907177b5,0x000027851eca7500}, {0x0004709b248eca72,0x000a87322fbb36f3,0x0009e73d0e54945e,0x00023d52f940920a,0x00005827d8bfa825}}, + {{0x000b019bac0eecc0,0x000cc707f8790281,0x0004e858045722f8,0x000538e7e32b5f38,0x0000c291610a5aee}, {0x000c51ee868e43d1,0x0000b754959a25fb,0x000f424af9289eaf,0x00069ecaf0bb54a6,0x0000923b39262f9a}}, + {{0x000eb037fabec5a2,0x000f5113b5f773df,0x00015a54ebc1d2d4,0x000181f233f0f51b,0x0000fe807bffeb66}, {0x00046d05b62ce294,0x00098d67cf9c5ed1,0x000a8fc4e5cef5ef,0x000aadad520b5c8e,0x00007039215094ef}}, + {{0x000a1db4a22af952,0x000cb9edece623c4,0x000366394458ac70,0x0001dfb057f7a0ae,0x00001fe7a1fbcf33}, {0x000d7cf370fe2a14,0x0005732e78fb4925,0x00055e87c37f393a,0x00011bffd64640e5,0x0000ec4a5ddbe8c0}}, + {{0x0004d4d3a17880f7,0x000daa8f972e8527,0x000d1a6e2ec1bea4,0x000c27636300963b,0x0000efe1ddeeeed6}, {0x0004f3e8c69f40b8,0x0000b1029582dbbf,0x000af32882bd8807,0x0000a6c9827573a8,0x00007105abfc154b}}, + {{0x0002a5c62b9097eb,0x0008d4989c3a69bd,0x000c39b3112f1d05,0x0000d73bfed8eb5d,0x0000a4dd7028190d}, {0x000df21e7c9ea92c,0x000cb9a2427202b9,0x00055d8cf2e18cf8,0x00000d9225aa33bc,0x000093d58b32465e}}, + {{0x00056d7e3c7e81fc,0x00063f455beb34d8,0x00041bac0617ff16,0x000d390004aab0d3,0x000066a594a7db36}, {0x000674ef21314c13,0x000cd499799bff44,0x000674e5b127989b,0x0006f3d0eac3e533,0x0000475033eb386f}}, + {{0x0003be03f488b066,0x000afe3e2458f80e,0x000cbb0ca9c1df72,0x00032d854724a756,0x0000f294d9ced004}, {0x00099d4fed7a8bf1,0x0000a3d4dc031bbf,0x00098fe4b4fa6535,0x000d3d62a156b316,0x000061c892ad39b5}}, + {{0x00057062dd51b0e3,0x000fb0b6ede2e44a,0x0009b84b4bb2e66b,0x0003892b535e65bf,0x0000f04bbbd4cfae}, {0x000e254b0efecf74,0x000c7b425efa6f99,0x0006fc1223cb5014,0x000ed3775dda3b47,0x00007d91e4176c7b}}, + {{0x0001e11238f17189,0x00055477448462ca,0x00076d1ca907db73,0x000957e211b110df,0x00009f00d6031218}, {0x0008148bbf09b400,0x00081c3bb9e89771,0x0008b25f9e1f66b9,0x0003658ee958d873,0x00008ea2bc754377}}, + {{0x00040ec2f8b18d2b,0x0005720588c7874c,0x00012febf68a4ccf,0x0000ad74cc5bc416,0x0000c0cd6c894bb8}, {0x000a5770732df031,0x0009df7b0dec4b86,0x000bf3c40616b170,0x000ad41d43d29a1c,0x0000eb2874f42570}}, + {{0x00075fff53df8b53,0x00080ad93ea9fdeb,0x00094201518d77bf,0x0007e5c4c968a760,0x0000623567d0a637}, {0x000b5f86a4738b2d,0x000027189c03c512,0x00071bad6653470f,0x0007c87146d1d64f,0x0000a1a59a4469af}}, + {{0x000b514e53719c74,0x0004263a91d246bf,0x00026ec908be45b4,0x00047bf0842913d7,0x0000b483a7ba011e}, {0x000411dadfaf9c39,0x0005f75f1a475043,0x0000622a4242b2a6,0x00076430694e65b7,0x0000cb0de0487bd5}}, + {{0x000a48d97cccb4f8,0x000039d242ee958b,0x0007a2d265fc7e92,0x0004f9b0346ee66d,0x0000ae6d9eccb1ec}, {0x00071cb876b50704,0x000b3a208b80528c,0x000e466e83bea7e3,0x000f09d38293ce87,0x0000f7bc81782076}}, + {{0x000cc15e3a833811,0x00027d31aa50385b,0x000d0e82633ec551,0x000ec7922987876d,0x000070d03a64f875}, {0x000cfaf5650d15f6,0x0003473ac211140c,0x000c98877e0f73f0,0x000c08a75c5c482d,0x0000622d09e823c7}}, + {{0x0000b7e8cbf9ba79,0x000cd6e710efc7c9,0x00077ce47b6bd4ab,0x000960be8ff09b54,0x00004e8f8dbc6cc5}, {0x00021368a1283c7b,0x000f518b32eb7e5c,0x000cbf5b162623fa,0x000005dbef4d2e43,0x000088b15fa01ecb}}, + {{0x0000073cbb4b6ec4,0x000b0a7babe5c5c5,0x000fe549f4ecc335,0x0008c322d1e8f812,0x0000c49af93d1581}, {0x0002b2e39f0417cf,0x0003d9808a14c3e1,0x00017386e20adee0,0x000690f7522d1fa4,0x0000be41fb5f632d}}, + {{0x000d671707701933,0x000297bc3160d8f6,0x000cd76c64b8a53c,0x000dd64e0e6d9406,0x000034d74fce765d}, {0x000daf8269a471c5,0x00075ff07d0520f0,0x0007f32fb264506f,0x000b4a0a95e8f527,0x00009abfb62dfbd9}}, + {{0x00005b5fd8e98e12,0x000e14ad70cc06de,0x0008fa21ed10a09e,0x000d8d84fd47afe8,0x0000d6f824d23bd3}, {0x000baae0dd9c557e,0x000ad65982a3dbde,0x00009c77a82ec43d,0x0005bf745e0fa843,0x00003f0eeb6c0fc7}}, + {{0x00088e490854a78d,0x00018930eadc94c0,0x0006910aa320ffac,0x0000a278a57e2f16,0x000051dd5b2d1423}, {0x00005547cd73a6e7,0x000cfd1d02fc869d,0x000428efc74b6a1e,0x0001e7c08394445e,0x00004579b6ee7a03}}, + {{0x00024c9bcf01037b,0x0009474916aabed7,0x0000d51d09748fda,0x000cd6db5cd430b8,0x0000dfdeb4fdd00d}, {0x000893bdeed91a80,0x000f120778a2597c,0x000058a2e837a8e0,0x000cbf18735f2428,0x000099a77bb6fe13}}, + {{0x000ab7d29b0fc1d2,0x0000c2ff82ad4240,0x0003e8b1824be74b,0x000b66033eda9291,0x0000639f82a1d05b}, {0x0000f2c91ad5de88,0x0006ee9ddf6690a1,0x0005fc7fbf5d854f,0x00072ac4ded94a95,0x00002682d9b714a2}}, + {{0x0001a874ed7acebe,0x00029408c1b46ebe,0x00096d405f800d1d,0x000d48657b969e8f,0x000025248132720c}, {0x000113432ff0aab9,0x000ed7506e97a2de,0x000f3ff61e19447d,0x0008868795e67865,0x0000dd308ae491e6}}, + {{0x0000c4982db65ca2,0x0007cd8b3cfa5d15,0x0008b3c34d779cee,0x00007ce56f66df9b,0x00002bad9190373e}, {0x0007dacf82c7cd70,0x000170cd5e21faae,0x000d737aa745c2ed,0x0003683c666088dd,0x00002a7ff3c66133}}, + {{0x000a25b51b2364ab,0x000cca23ad8f56c0,0x000cc5060f4037d8,0x0002d7b40bd50e15,0x00003c6b05849780}, {0x000dfb5580a54f98,0x00017736f3f4da3c,0x000fd025f36ffc28,0x0008e648f7012618,0x0000d358c70b39f6}}, + {{0x00058b4c855a6e77,0x00057c0c522b55f1,0x000aab00625e8fee,0x000e46856ddaf929,0x0000358453361f0a}, {0x0009303af2d55212,0x0002aa5a6f6c0d2d,0x000148546bae13b5,0x0008b24d4e4ab630,0x0000d7472f84840d}}, + {{0x00053970acdb5e8f,0x0007fc269b0f06da,0x000ed8404fc5b791,0x0007e86e017875d8,0x0000ae584763a508}, {0x0008f45064b6f293,0x00033c845a65aaf0,0x0002b4eb7bd3ce36,0x000130fa6c359a38,0x0000a8bd9f84a685}}, + {{0x0008edd0663f8f91,0x000dfd59df5ea31a,0x000b723f079a56bf,0x0009327b892c2263,0x0000ca95b5e3d558}, {0x000ff18c4e8a781b,0x0001e49ef80c48df,0x000240760a2bb746,0x0007c06223d5cf77,0x000078f428a9e459}}, + {{0x0007912ca1754a1b,0x00092318062eb864,0x000974e01c1c5675,0x00077e15df7992f8,0x0000a5205ad4cc39}, {0x0007e259fb6cbd53,0x00069eb726a354b4,0x000e567fe8f54419,0x0009e27f6dd9bb81,0x00001e04658e6f27}}, + {{0x0003571b3d512de4,0x0003b7ec1208dbee,0x00021dbe93f6b7c2,0x000e0305001dba00,0x00002cde309eec3b}, {0x0000e38dd838d4f1,0x0005ed3f3ec2efea,0x000695c674c80611,0x000b53a586d725c7,0x000023cf980c45f2}}, + {{0x000b294c00e93609,0x00036582b06d7012,0x0002b6731864a65d,0x00038b0faad9a9f5,0x0000f77e45dc3d84}, {0x00049e1125dd970b,0x0006521b5e3f5cef,0x00026ca225bd9b00,0x000e53d27026153a,0x0000ffc6effc2de9}}, + {{0x00049dac9eda55e0,0x0008ed551742ae1e,0x000db16b7071ad42,0x0007e519f35180de,0x0000acf03adba5a9}, {0x000674fe200f7515,0x000041ad6226b24d,0x000bc185532514d9,0x000f57098d181f26,0x00003a47ab5d1829}}, + {{0x00065694a7f9b78f,0x000f181f805c903a,0x000293f8c82ead90,0x000dc417c53de726,0x00002878d513c8f0}, {0x0005fb44bef65dc1,0x000c159a08f75e63,0x000e766741f4f5d0,0x000925d04127a52d,0x00000eabd36a8ede}}, + {{0x000b38bd3f9e6f35,0x000a429a8af3f5ad,0x000b3d4c94dd8b95,0x0005081f01c01e1e,0x0000a43459cea12f}, {0x000266c93a596f15,0x000fbb27f18ef36e,0x0005dc2d06428594,0x000875dbb1d59fd7,0x0000123eea204f7f}}, + {{0x000b96fae7ffdf8b,0x0002c722fe26e092,0x0005b25bf727e271,0x00079b4b3ece9d22,0x000029e084fabe5d}, {0x000cd0f3353903c6,0x0000436a938bfe7c,0x00097acfe3f67b99,0x000bce9cd2d1a3c7,0x00006253f0aaad9f}}, + {{0x00044bbce9995733,0x000f073624473dd5,0x00033abee446da98,0x000978d07a005203,0x0000caeaa7309d7f}, {0x000150d1bf2bcd41,0x000ccb53f84c0b65,0x000ac6215464c51e,0x000609e277528a4e,0x000098cc59ce3166}}, + {{0x000efcad4a7da4d5,0x0008301bbee31186,0x000b3db7feb894f7,0x000f1f8ace71e7f1,0x0000112c9354a5eb}, {0x0003b627286dce6e,0x00095a30713afd8d,0x0001c6f0a0610827,0x000d93fc4c531160,0x0000964d3161c3a4}}, + {{0x000ed7017f788ea0,0x00094674852856bf,0x000c96919c78850c,0x000d11c15e8987ef,0x00008ec3fd406441}, {0x0001d9a8b2134698,0x000beec4889b6406,0x0003f1ad5d6f0bd8,0x000240648f309015,0x0000e5b581f2cb82}}, + {{0x00027926c5189337,0x0002741b168b71e7,0x000a4a599fdcd605,0x0007cba7afaa4cd6,0x00002940e9635844}, {0x000a7689dae16a8a,0x000dba4b641f4ffb,0x0002ff98dda84226,0x000dd3217fd968b2,0x0000584b3c0e2f5c}}, + {{0x00031b6de16fdb99,0x0008582a440f2355,0x0001c6e1855a3304,0x0005300eec11c310,0x0000d21585a61848}, {0x00011b3ef7a3b94e,0x000505e21369d2ce,0x0004b130e8bfbb57,0x000a18b7f8363266,0x000093672301cecb}}, + {{0x00006d08ad2b8a84,0x000174564b2255b8,0x00072579bbdec57c,0x0009ce6932d9aefc,0x00002be0f18664b2}, {0x000379820c03f35b,0x000b81cc51d23ac4,0x0003b05894b88c59,0x0003d5999a808624,0x00005debcd1e1590}}, + {{0x00063183e156632d,0x00095cc68bbb24c7,0x0001bdedfb33c7bb,0x000fc8798ec08681,0x00004d45061bb8c2}, {0x00096921fd5268a1,0x0006fb5a73e1eaff,0x000c44fe9ef420da,0x0002d2e7d1a2a7ff,0x000099f6ec68c8bf}}, + {{0x000b091537d50e00,0x0004c4d8240e0105,0x00088289db80bb3d,0x000f2516e62e6a1d,0x000049b3d353af60}, {0x0006c1e8a9308ea7,0x000a834375ce9c5d,0x000bb4bf8bdb7520,0x0000568aac390a23,0x00000b0ddd236d48}}, + {{0x00072da34e3add6e,0x000a25b562a221be,0x000f893f7463701f,0x0001b78a85dc4a41,0x0000b8945c02e7af}, {0x0004515392a4b278,0x0007224cf9eb4248,0x000a36d27223dc97,0x0000469b1c26a8fb,0x0000c8a286157f29}}, +}, +{ +/* digit=29 [{1,2,3,..,}]*([2^203]*G) */ + {{0x0003d44e194a9fdf,0x0002786ca99f031c,0x000ad1c1ca8706b5,0x00016f6144a3f729,0x00007cd191d19930}, {0x000032e9850c5a09,0x00064ac49359a6c2,0x000556cf735b82bf,0x000ee923f58e8bf0,0x00004134d7aa14f9}}, + {{0x000d9bb86ddaba10,0x000af2ff8d7f7ad8,0x000598bba183ded6,0x0009e01bf6f62c72,0x0000b0e9cfa9acd8}, {0x000fa485b832c346,0x000511c3faaf2d1e,0x000b424d4c7077aa,0x000d2f6f4b824a1c,0x0000e6cb10d909b1}}, + {{0x0002f3ece47545bf,0x000cc82281bab5ca,0x000fef90fb8bf71c,0x000bee7b6c1c7445,0x00009f6c799f8590}, {0x000043420d1a0c68,0x00050384ca2526ca,0x0006d804758be80b,0x0004f8d0335e99b1,0x00007f6cdd65f76d}}, + {{0x0009dee69ba8813b,0x000aa6bce2ade252,0x000b5e21e2f41814,0x000311e74086449d,0x0000fd363bf4202e}, {0x000eef53cd037a91,0x000f421162d3c6c0,0x000c1bfd296d4eed,0x0006d0ff1ba38cc4,0x00007b7b0d0ae516}}, + {{0x000118e549825790,0x00087608d2b36a6a,0x000db2f0bc20e5a2,0x000100d9275dfc96,0x0000fde447ee7b6c}, {0x00028286516d65bb,0x00018776f794bb5d,0x00073d44dfb1675b,0x0007d7116902d37d,0x0000b303e3549334}}, + {{0x0002b20e7355edc0,0x00029cd368ead897,0x0008b57463d27897,0x0009c3165bfa78bc,0x00002fe2446e3da6}, {0x000b89e933220b48,0x000cf81af9f1c16e,0x000c693a260f9ee9,0x000a0fd40f000040,0x000052f4665ea9b0}}, + {{0x000e8f27a45c0327,0x000e86dd8982d9c4,0x000e56fb7618c159,0x00082ae92801f788,0x0000cb0bbd114f00}, {0x0002622a7b7bdd1f,0x0001cde8a1787ac9,0x00079d3f0007ae73,0x0002f8c21efea529,0x000059193889e5c5}}, + {{0x000d6baee189bb56,0x000e053f037f48a7,0x000fad7013164603,0x00005fdb161acf55,0x0000e17a5d95e63f}, {0x00019ffe09ff7228,0x0008cace368cf35f,0x00091ae861843311,0x0004e6206e370ead,0x0000ddd9c9e96ad8}}, + {{0x000c45cd3f314ad9,0x000d67364744703a,0x000b4a453c3af51f,0x000b9543050e4e10,0x0000fc178295f043}, {0x0007775ac574c8d3,0x000779f0b9acb4d8,0x0005b7ce50c8b03d,0x000b17132e5af1fb,0x0000c9a4f064d508}}, + {{0x000f522e5ae3e277,0x00035c35e812e660,0x00042cb0bdb0d2f5,0x00094342c735bbee,0x0000907ea8901582}, {0x000ec0462e80ee09,0x0004686fb3008f47,0x00006f827e223116,0x0009550860a2ce31,0x00000a75951e7b8d}}, + {{0x000f70c1ae342323,0x00018ad9615f80b9,0x000cdb22b183eae2,0x0007f44fe13030aa,0x0000096480bb3134}, {0x00051223b16a6387,0x0009942d6ff78220,0x0007ab9f39c0104a,0x000222d1b2b20f04,0x0000e09b38b19739}}, + {{0x00015cdd08fa5ad2,0x0009abe3f073baa9,0x000000d8e4981763,0x000177db88ef6f94,0x00003eaac824bcb0}, {0x000eec6acf802868,0x000ce8144efca222,0x000da7040d7d51ac,0x000194f0b2b6495c,0x0000cabd0cde140b}}, + {{0x00017df57e74652b,0x000f4607f76a84d1,0x000a479ff1f3d544,0x00007f04801c4412,0x0000698c2293de3c}, {0x0007faa80f480970,0x000345e6a405407c,0x000b9c66fdd33168,0x000aa0cb4a878f56,0x0000967b41c670b8}}, + {{0x000e336c7c6f0782,0x00096d368d37636b,0x0007cb94d59ddda6,0x000066012877b72b,0x00001a597b4c1bdb}, {0x0001a77f61e01063,0x000941d2f7f6a765,0x000adc00b4c447fc,0x00091ec195fdceab,0x0000225175f8fbf6}}, + {{0x00092cdef9b9f47a,0x0006904c0879edbb,0x0006347c48b0eaac,0x000a434c1967d357,0x0000a127c7caa1a9}, {0x0008363c59d19935,0x0001d39d521da939,0x0003198ee98fb3d9,0x00029ecfd6c18cdc,0x0000c77256b8e3c5}}, + {{0x0004c3f4f7c6da11,0x00061ad5689997f7,0x00062877229a2a25,0x0007088588d5eba7,0x000058d5cc44dfa4}, {0x00035cc9a95c4417,0x0004bc289fdf6e40,0x00019b3a507f5383,0x000ce233b96c0c50,0x00000c852a997bcf}}, + {{0x00074ab6e99c27db,0x000700add209d2de,0x0003682485035083,0x0001df8625e5b7c7,0x00000b17bc10dbf5}, {0x000a3800fdb2a3d9,0x000dcddadf173751,0x00052591af594942,0x0009ba307d31c514,0x00002993a31f60d9}}, + {{0x000f10830427f20c,0x000f3b328a7fe500,0x0008f3641b8a00c1,0x000ddb433bdf6377,0x00009d207a3e0f16}, {0x000ad2c986b8e3d4,0x0000a50419f77145,0x0002215e5dba85f9,0x00036043616de9a7,0x0000890c85022c4d}}, + {{0x000c79fb017c6831,0x0007a3ac08d0d0c0,0x000029dfa2a4a427,0x000ad7d78feae29b,0x00008d9adfa5f678}, {0x0009c5a65d795f42,0x000b9846b9bb1ee6,0x00058ffe0f45ce60,0x000e91a8c1a88f3e,0x0000be10bcc58190}}, + {{0x0005faab9590cb5e,0x0001342fabcea57b,0x0003e7b2710e9804,0x0002cc1450419041,0x000074d1a8f02914}, {0x00094b897325bd19,0x00008ae2d222f310,0x000d2bd77ff05aef,0x000980085cf5bd1e,0x0000b0fe23af35c4}}, + {{0x0004fcb8b197112f,0x000f08c2d9a81289,0x000d49a846e64b4e,0x0007aa5f20e1a8fa,0x00007cbd1a7ba201}, {0x00064a4a4bc89168,0x0001fad822dd3cda,0x0005d3c95cf37a38,0x00042789c1ac2c12,0x0000ff1fe3c1d92e}}, + {{0x00092a5b1d033025,0x000fa30de8fdc44d,0x000a4e718fcef607,0x0004fbc816269dfb,0x0000bf7617c683f1}, {0x000de6a2dba301dc,0x000825272ede6fb6,0x000b46c3e8670aae,0x000f2ae811ace7dc,0x000059fa6d27c8ae}}, + {{0x0002c9a0ef6d99fa,0x0009458f7d2ffabd,0x000a81b1810c0ec1,0x0000355e7c18df1c,0x0000c49e954b5556}, {0x0006c6fcf3518d17,0x000b3430cd0f57ce,0x000ed76dc6ca44be,0x000fa9be95d0a2cb,0x0000228db9607d58}}, + {{0x00029d5eb1852497,0x000c231b03be4c4d,0x000b6be41e03aa73,0x0000c8bd817ca00c,0x000045736b555b18}, {0x0002467e0d2667c6,0x000112c70e0b53ce,0x000ce135f6da78ac,0x00097cce5c18f0ce,0x0000e522cc53caf7}}, + {{0x0002eccb8b0b2cc8,0x0001b5ccf40f2f60,0x0004aebd14979660,0x000e7c210c1a93ee,0x00006c082ccfbf4d}, {0x0005a29cf6241ec3,0x00051c57365898d3,0x000c5cea4126aa24,0x000fb5f29b7ff954,0x000035d47dc88418}}, + {{0x000e379fec34dd00,0x000af10f04b2da8c,0x000244ba7b67c67d,0x000b291e6c1fc84c,0x000064b8ffb56a4b}, {0x000f0c726a01b425,0x0000ab4e63c20a03,0x000daa4bfc15dee4,0x000b2ba598f42985,0x00000412dc5ee9a6}}, + {{0x0008e2b0cbea7f60,0x0008aa38f3dd0462,0x000bbefab03aae77,0x000928ca9669f559,0x0000980eab114d68}, {0x00060ecf7e0890f4,0x000add678a21193d,0x000e75ce55e32dff,0x000b93e865c3741f,0x0000c6b7dadc3ac3}}, + {{0x0000ebc9c7982a25,0x000c291e4d112cd9,0x00016c66bcb45331,0x000f8b46194b0c7f,0x0000dfc74610f6eb}, {0x000d1481dd4169f3,0x00038b5f60af605b,0x00009d46e7986887,0x000bb629eb8a4bc3,0x00004d4d57fb25fa}}, + {{0x00045dd030229a4b,0x000f628bf05c5a04,0x000c8ae68bb98061,0x000b9637143f5451,0x000055db14aaf091}, {0x000c500b3ec39fe8,0x0009d418e00ae4c8,0x000f274dda387c10,0x00044d258b0c3190,0x000082d86c4dad00}}, + {{0x000c6b74352596ac,0x000bbda2c19cc12f,0x000372be7ac616b8,0x00068ef8dd414a4a,0x0000a5c3507d3814}, {0x0005c60076424b1e,0x0008521878c8f96f,0x000720621f0ecd3b,0x00092f64b81e74eb,0x0000538ab09b9a9e}}, + {{0x000147af5c6b6fc3,0x0009d626e2d99fe0,0x000e4efc5d3b7322,0x00023ead978b1f26,0x0000f06e93347735}, {0x000048486ca8b31c,0x00068bde8b51ab05,0x00034d7e9ebce61e,0x000b3f2f10632b10,0x000093e107c4e9cc}}, + {{0x000a93461fccf159,0x000ac594ab715187,0x00023895d730753c,0x000cc5a17e2ac232,0x0000ef8cc49c9735}, {0x000ae251f43e9bef,0x000f1381286e7f14,0x000ece1bd4bbc7ec,0x000c24d2741d2d9d,0x00004d288de19a8e}}, + {{0x000485ef01499626,0x0001422c7178e581,0x00079cbd8df6a745,0x0008dba5d0e4b656,0x000073799e051574}, {0x00030e5c106aa63a,0x0007bb8bf1bfe2fb,0x00051e7a789d99b2,0x000550c0acf7e0c2,0x00003f634d522030}}, + {{0x000bba47947ece86,0x0009f8484a1cb45b,0x0001b504f55b8127,0x0005f5297e6d1f72,0x0000ecb79c9e7225}, {0x000a586963b03fbe,0x0009a9a594524654,0x000722ee4a3b403a,0x000ab40a3e93989d,0x0000606778e918ca}}, + {{0x0009e70fcdb5c523,0x0009777edeab081f,0x000b6321e92e6fc6,0x0007d56dca6cbab0,0x0000481a9a365925}, {0x000c9c830d7147e8,0x000d7ed3c882eb18,0x0002ffe1754187e3,0x000ba41b2d1d263d,0x0000d9341cfa1024}}, + {{0x000c73485db43e65,0x00072de631cdb39c,0x000dddde68822312,0x0009f1cca53521df,0x00008999320f891a}, {0x000dc155336fa529,0x00035bc4fb3d5300,0x000d60db809e08ae,0x000611c315d50e15,0x00009de175044122}}, + {{0x000fa9194d351ac8,0x00074be1275acbad,0x000d047459aa08d5,0x0006b7f0a2a4d8f4,0x0000b07256b61364}, {0x000b6c992e60611d,0x000e5798e15351c8,0x0005f15a3b1f6a0e,0x000ebc7ea67466ba,0x0000be447e50b869}}, + {{0x0005d7c17fc06372,0x000ab2ce49cccaab,0x000161cd0f703ffe,0x0006f3af701e3650,0x0000a22686632fac}, {0x0004ffc699f8f077,0x000cbff2b120fb16,0x000f1296557865ec,0x000e28bb4519d52c,0x000031c60ef40cec}}, + {{0x00058f18eab52d1d,0x000560d708260815,0x000f6f11289d112b,0x0003447238d0bb08,0x0000ec9f217619aa}, {0x0009a34620f0a1e1,0x0008b55172a98dc1,0x0000ef9ddda42dee,0x000e7f1fef171e88,0x00001dc69d22f38b}}, + {{0x00081cbe5c6b0ffc,0x000a70f127a082a1,0x00036c3fcc49c7b5,0x00032943bcf4908c,0x00006403b86cd8db}, {0x000d0a77264c886d,0x000074c46e8308b8,0x0002b835f05f0d1b,0x000920f60b800c29,0x000049222a687aa8}}, + {{0x000576f2d8ff940d,0x0008af6e9ad4ff42,0x0001881bf2265dc0,0x0006ff7cb9f24d1e,0x000088c9c79e4b0a}, {0x00073d5b18e1c9f9,0x00006a4d2af38012,0x000cf1d6666875b3,0x0001d3988b576672,0x000045dbe0545fff}}, + {{0x000abeb891f1ec6b,0x000fd53801df03ff,0x000b2923fddd0a86,0x000d0d90338c4e04,0x000093b7a1c89855}, {0x0007c6d30f5cdae0,0x000fec5d2630aa27,0x00063d74b39cc985,0x000af9d1a3f8d39f,0x00004b3d5f66a46b}}, + {{0x000c9f671d7b1d51,0x000a34d571ffd097,0x000e017c1332810b,0x000ac856d2de4856,0x0000b5ac59d08ba6}, {0x000c9395a299f7d6,0x000550364c6c872d,0x00073ca853f70ad0,0x000d64e23185ac4e,0x0000a0dc786f885e}}, + {{0x000365ca2f6cc753,0x0001950b7492d550,0x00003bfbde327978,0x000b87d29fe0d9cb,0x0000746555bd48ce}, {0x000c895bc1abe035,0x0003dbcf3d569c94,0x000bf1343778745b,0x000ef3214b6486b3,0x000047aa6736af22}}, + {{0x000a2fcbbaf2c939,0x000d9fb3b552fd25,0x000b6e203f0b0875,0x00062eb1f0689b22,0x00002dad5d7a6b6d}, {0x000e02be2a7f8910,0x000f4be85299fed4,0x000459f8ce325e28,0x000f4d4865b62c76,0x0000b1af905e5737}}, + {{0x00052120e85c6041,0x0001ba10be26a162,0x000d804fd3ec775c,0x0002eaa61440fb52,0x0000068ea63e38d2}, {0x000b7fc5f961a053,0x000cc635146d1c90,0x000e33657bdda345,0x00085ee9c9428d6b,0x0000446275189867}}, + {{0x000784a3c5468e85,0x00047984ba27c370,0x0004066d7e5a8330,0x00061c6d875b96cd,0x00009ef1394bc3b5}, {0x0008a9fa2de76220,0x000e636f54a420bd,0x0002ea4587bdbb30,0x000e5caf449dd5f0,0x000010d9580bf257}}, + {{0x000bc0df5663cc09,0x0008ce45bea99fdc,0x00066c8aadefcd5e,0x000c717280653351,0x000013d1b8e2e804}, {0x000e2ee1bcaa98d5,0x000a89c86e998159,0x0007ba8b8fd3241b,0x000cda83ec96ed7d,0x0000cbcf8e5c4088}}, + {{0x00013b8639ee43e4,0x0001cd5b01220ed1,0x0003036576d0f097,0x00062825f0577f4c,0x00008ef888dd7597}, {0x0002f120ef9824af,0x000bdfedb88169eb,0x00096098c26c3113,0x000fb30d47829f28,0x0000b9a090863684}}, + {{0x000e1d9cbc3fde8e,0x00004d7bb98ff2fe,0x000f525f9a307331,0x0005b55bcd46bc61,0x0000018644ffde13}, {0x0006b02f72aa32c6,0x00064f4c36a1c7cd,0x0000fd885a8f4dfe,0x00087bd6ea8c9b1e,0x000074cf3eb4034c}}, + {{0x00073bd32b3ce74a,0x000ae1cd16e13987,0x000ae6b331a3b6f6,0x00046de18f795e62,0x00001b268c2eac8f}, {0x00069500b796bcb9,0x00084b0bba811e96,0x000f2ccf64d07f55,0x00041c6d9453b627,0x0000ab5a6b96d1e4}}, + {{0x0006ec3a747b5540,0x000399f0d80c1e58,0x0007fdb082affb22,0x000eb0c210e996e8,0x0000e95e547a6d00}, {0x000c9c0049c9c5cf,0x000e0f520325da72,0x0005ebfd1d560466,0x00076497d952c276,0x000045f0b3696836}}, + {{0x00008a22bc43724c,0x0003c41e774eef64,0x0003a4dfeb9d0e74,0x00004b006555b0ab,0x00005d1666eb0348}, {0x000248fd93a49062,0x000be3c4df2ca530,0x000998ee3e168071,0x000d38f9f0133243,0x000048b66cacb6bb}}, + {{0x00089d9f89790db3,0x0005f889a66e42ae,0x00077b13eaca57e7,0x000143092c735596,0x000008aacec1a523}, {0x0001e6516c69967d,0x0006f9a3b6e5c1e8,0x0009f29dfbf864b7,0x000799dd8c521037,0x000071100f81f8ea}}, + {{0x00095a4465926123,0x000cefa1e2ba3fe7,0x00026ef78e5b31e1,0x000a78581fbbd306,0x0000cae68ad41793}, {0x000c18c2eb0d08ca,0x0003ef8c811ae66b,0x000e2252da9bb52c,0x0008a2c5369b8118,0x0000bd6b4123893e}}, + {{0x00098fbeb198837b,0x0007e591d932f152,0x000a139813f9b9d2,0x0001b9a3399f77e4,0x0000a1298c3d05c0}, {0x00022a6bfb15d6ef,0x0001033da01cb0e1,0x0002fb9fda76e2c7,0x000f5fbc3f0ec949,0x00006c65aa22897f}}, + {{0x000c71c17acd4295,0x0001011c393d2328,0x000286245219bdd6,0x000cba4b683f2657,0x0000f802506bd066}, {0x000b96620f24420c,0x000fa4428c9d74ac,0x000aacb236ad94a3,0x0002c648f91ae4f5,0x0000fa1ce59741a2}}, + {{0x0003b3ce11cb6f2d,0x0004d34dc8b8ff58,0x0002fd7cc9dfed18,0x000f048bfd16a8b9,0x00002ef21c9d0bcb}, {0x000be2a7a86c43c4,0x000ab9dfeed3f183,0x00013c43d69b6205,0x0008db23413a7f78,0x00001d39c7d32aa1}}, + {{0x0005b43063f50fcd,0x000194e360c3747b,0x0003b425a290fd4f,0x000535e867f57238,0x000025fd6b026625}, {0x000adc9d6e1191c5,0x00026e3cd549d280,0x000ec1539adc8332,0x0000cdb1ae29236a,0x0000810251d55eab}}, + {{0x00029cb4887c43a9,0x000bf0ecbf8060fe,0x0000dc5c04dd638d,0x0005a407f09b063c,0x0000c90890142afc}, {0x000c7f52d04bee9f,0x0006e697fab88589,0x000126de25d7c826,0x000402657a0ae9f1,0x0000e4761b55036e}}, + {{0x00025a23ef5de284,0x00092f812e80c46a,0x0003fc24edd7ca58,0x000462dfde4b0b1d,0x0000cd2f0f0bb018}, {0x00086a72d1cc82af,0x000c2a483fcf4d9f,0x000519f9a53040b2,0x00086b7b2c6bb96c,0x000049adc46ab823}}, + {{0x0008d0ffa742f123,0x000a2df6bdd73b6b,0x000a1cc8e1a0bf73,0x000c4aaf283aa1df,0x00001ce68bd7aa7a}, {0x000282e1f607c5f2,0x000ef137e8b5ad86,0x00037413093d7e59,0x000744f3271f905b,0x00008c6b4eb4ee8c}}, + {{0x0005cb112391f8f0,0x0008641ea3f94138,0x000a010f48cd20ed,0x00039d7c395dd04d,0x00005c716598493c}, {0x000e3a42b6e9113f,0x00069cfdaf0139c0,0x0008a7df12e8d24d,0x00074ace4e33416a,0x0000674561bb3fb8}}, + {{0x0002c06cde003641,0x0007882475bc642a,0x0000572001a99da3,0x000608dd4b142d6f,0x000093c30c54e876}, {0x0005a56a6f3399b1,0x000625608bc9ef4a,0x000c52c2c93c2f89,0x0002135ade60f126,0x000004d9ce986570}}, +}, +{ +/* digit=30 [{1,2,3,..,}]*([2^210]*G) */ + {{0x0005587744fc9b0d,0x0002235a186fab45,0x00014d4716a6ca8e,0x0008e21b61f724f3,0x0000f3f72b99a2c5}, {0x00080e1a9312fb07,0x0007d9cef9613e14,0x0003e5490ac148ab,0x0003955a1c207543,0x0000f96356794b0f}}, + {{0x000819be29f68267,0x00009fe4deb38664,0x00050b6e73cb6078,0x000558aacd6e06b1,0x0000279daf8f7d63}, {0x00018e07f25095c8,0x0008331cfc9f5f26,0x000782972feb9f2c,0x000658f802fca94e,0x000038c50f53e7be}}, + {{0x0003d4ddbebe9fdc,0x000143df4bab03d1,0x000400f0c967a672,0x000eb663cc254819,0x00004477f6a2dd2c}, {0x000ee0d4c3d37c69,0x00009f15d2633c34,0x000643fc0eb2b41e,0x00009b2d010432e1,0x000030aa45907c25}}, + {{0x000ec65be9e92878,0x000c55c6b87a3bca,0x000db423a40a8edd,0x000575f207c56c36,0x0000de77bbae2005}, {0x000580d56553246c,0x0002d79f3040d372,0x000398bd3d4cafaf,0x000cf3e0535cea88,0x0000d8835ad63a58}}, + {{0x000938515a35e548,0x000bad5845ecfedf,0x00085e8461dfb3c4,0x000503cd8b2d66fc,0x0000a93de3d98e57}, {0x000f822006f36a34,0x000a47a6f9bfc29e,0x0009551254d51965,0x000048cb979c84c0,0x00001df6019a10a8}}, + {{0x00078cab73289d88,0x000b9d9fa4701c6b,0x0003396e135bd0c6,0x000974c909a06d9c,0x000019ac99ac8f6b}, {0x000ceba50d80dbc5,0x0001303b634316a2,0x000b684d771cc7e9,0x000516e058c5049e,0x0000292ba043dbc8}}, + {{0x00038fbb6d7a003c,0x0005cf09193bfc73,0x0009d8f07894acea,0x000acadc9f445791,0x0000d19f61fbcab1}, {0x000ee3f4a227ca59,0x000da7f63d2a427b,0x000791f62bd40826,0x00024a161e806c1e,0x0000add1e908c47f}}, + {{0x0009ab29ea7ebd27,0x0005e96d975a66cf,0x00089209baa3ca4d,0x00014f686c002e33,0x00002fc9f0d6de64}, {0x0008c324e1c3942b,0x0000f90ac257b88c,0x000d3ac5c6940150,0x000a881ab7db6e14,0x000041cfa9e1e973}}, + {{0x000cd33ae6949b59,0x000c4ebf33ea027e,0x000599a62bed515f,0x00080a74262307f2,0x0000658216a1a59c}, {0x00032e776bfdb8c8,0x00017f7f1e742947,0x000e4d1cd2135990,0x0004b293f38844b0,0x00007a0099785d21}}, + {{0x00037890b4606073,0x000bb550c322b536,0x0004ba1bce567534,0x0009e06d2e436e29,0x0000a4c94f2a27ce}, {0x000138a6812a277f,0x000f29b99d6648ce,0x000a581647b50956,0x000333ece9cb729d,0x000027d4916a975c}}, + {{0x0008ffdfd9dd8995,0x000722772d432015,0x0006c364a3ab59c6,0x00070a5bf413de34,0x0000d46f8062e931}, {0x000b960a7a4ea0ea,0x000695d0db76048e,0x000e021533582f16,0x000878c9174f8cee,0x00005573b093f78c}}, + {{0x0008ee06f4cb971e,0x000eb1dfdb17fcb4,0x00055a1b0f4066e7,0x0004c7cd2cec053a,0x0000ebdb6c1c4266}, {0x000350374bfd9193,0x0007524863bd2f5f,0x000948b9fb7ad01f,0x0008761103a17657,0x000010efd69bf34f}}, + {{0x000e391227b7b918,0x000179b0e8190ad9,0x0003188ad2f3b5ab,0x000db428f6ac1ae1,0x0000ac2d65e8d7e1}, {0x0005fad05741fe5d,0x000766f6f06a7260,0x000ce0f46f458b8d,0x000fce97f099d97c,0x0000ce699ff7d01f}}, + {{0x000d627bbbfea21b,0x00065bc86f5b59c9,0x000cbb800712f816,0x00030ace738f6336,0x00006b1e3676ef63}, {0x000629b9767990f6,0x0002ea49f8676b78,0x000441c77086b44f,0x00050133cf0e09be,0x0000f290415611c6}}, + {{0x0008e4736e5a00cc,0x00089440d1089750,0x0001a583a42edd9e,0x00093fd719bfc55b,0x0000b56d2dda07ce}, {0x000d6fc706e0a7f0,0x00032881de026303,0x0005d65f6c087882,0x00067db008ec67a8,0x000014533f4dc722}}, + {{0x0002f3d088db12bd,0x000fcf97a9b2b8b5,0x00019e14ff0d94a7,0x0001362fa0525b50,0x00003579f0be0bb6}, {0x000f2ad6651cd253,0x000f8099f9cb7e45,0x000375844682073c,0x000b76f4525fe726,0x0000a75ebc0af507}}, + {{0x000f75b1f2819cef,0x000f19e282729c41,0x000e04765719be03,0x00083fadad0e2c38,0x0000a88c8f8e6bca}, {0x00095351371d8ffa,0x000a01a80f584579,0x0002533ae7490891,0x00012b5f33fb816d,0x0000bbdbc03aae64}}, + {{0x0009a60af672be3e,0x000fbb1bf99b39df,0x0003def3e27b2b86,0x000698ab5d32dc62,0x00000c7f112674f8}, {0x0006c0939385470a,0x000d3c072ad3f6a4,0x000e841d647176dd,0x00050201733adfd1,0x00008ba67afea17f}}, + {{0x00061ae2b3427567,0x000dea4fd3f60fe6,0x000698aad50aa6e4,0x000b8d08d2ad5882,0x00000e1b9baf7513}, {0x000488bb1d898d7e,0x0006ce8c0168ad39,0x00091a4ad9a1c7e1,0x000819b619ef164f,0x000047df7d2d85b7}}, + {{0x000feab634bed6f8,0x0009357dce07ffc6,0x0001f22c07bc045d,0x00020284bf369c39,0x000000ec5355d927}, {0x0004492e1ef8e017,0x000bebc2c0cb9bef,0x0007f47cb55429b9,0x0001452791fca0d9,0x0000446d21780520}}, + {{0x0007bbe224fcd24c,0x00073d7bf6169471,0x000ac5c21a5a8b44,0x00039b7699434475,0x0000c24ec0229fa1}, {0x000ef056abea3468,0x0001b5631170484a,0x00014686e31baa0f,0x0008aa6711643949,0x0000ab5fe36c56bc}}, + {{0x0000fc5e6fc64867,0x0007fa43f868a21a,0x0003a88ba36f8db7,0x0002e70eb5ad6bdf,0x0000871d27ec8c07}, {0x0000eb5d0d0dfac6,0x00046fcb36133cf6,0x000b30f407d7c7a9,0x00000d6528aeb587,0x0000c3c8285253b9}}, + {{0x00054b828518597c,0x0008972f858fb628,0x00099871d157ba17,0x0007e3f4033329ca,0x00007518282b4088}, {0x0008335b1c0daefa,0x000b28c6fa72dbe1,0x00044e1cdd57d324,0x000b9e9bd8eb94d6,0x000090a27421fd2e}}, + {{0x0004aa7033c1794b,0x000b58d101a5a260,0x0009e75d4582f913,0x000c67d11d071709,0x00000c26db9ab4c4}, {0x000e2fd553fa1538,0x00092583731d4527,0x000ab1e032a78837,0x000565e5708eb33c,0x0000c48e233e93b4}}, + {{0x0000f3606cd3c7e1,0x000f9cf3f1a25ffb,0x0003c6509d6f19f6,0x000fc6ce3b57e1f2,0x0000c8aa53c29394}, {0x00013193e35bc970,0x00071c65a63e7410,0x00003fc0f1d93591,0x000631583a7d1998,0x000061d7972661e4}}, + {{0x000f3b0ec646b6fc,0x000ab80b5bc4d4b2,0x000e871c1dc2998c,0x0006f2466508817e,0x0000fbc22289a212}, {0x000d2a00a06285a6,0x000173fe65578efc,0x0004a98cb75bf247,0x0008fac92d989d9c,0x0000948f4932b9f7}}, + {{0x000845cf66cfa8d6,0x000482a7592908e7,0x000938c783adbd0a,0x0003fdf2c40e9dc3,0x000081189439bf8c}, {0x0001dfbde2120af3,0x000ec8f666c61cac,0x000049635e3b8104,0x000b570d910b372a,0x00003b0a13fe3b6a}}, + {{0x000bc798fcd4c386,0x000e2d3e989b0ec2,0x000354b0ebfb4e64,0x000ad6b241e9e539,0x0000e64b4499f9ea}, {0x000824a5c0b286bc,0x00095daf822450de,0x000b5e3cda89f6da,0x0002c25d832cbc77,0x00009df72511f703}}, + {{0x000d12e444a0e491,0x000990d76c78030c,0x000c2baffeec0fbc,0x000f8c635cc28c64,0x0000eed641f9bf3a}, {0x000c2a90ac6e705a,0x000a41dfdafd6d8f,0x000c5e6d0fab169c,0x0009e24840dfe5bb,0x0000261cb58c5df6}}, + {{0x00068c7c8f041f5d,0x000195a9be95746c,0x000e714fd26f00e2,0x00086a2fa5e86163,0x00005265628346d5}, {0x000d2f1ae615f3b1,0x0005881ec186cd66,0x0001f8ebdd09686d,0x00062642c2578874,0x0000b8d0ec7aa3ef}}, + {{0x00058a6e2678b76a,0x000c3decc2e12e45,0x000400578f26b5fe,0x000e9c64934cdf4a,0x0000ac4e70084d31}, {0x0005269ba3707c6c,0x0000ea75e26ae313,0x00076aec64c7ef65,0x000cede81346c1e0,0x0000e7007b498e3f}}, + {{0x000ea93372944b60,0x00032e7f0407c535,0x0004662e884f3908,0x000ff3b4dba2af07,0x00002dd0c0bfba19}, {0x000a01101857f415,0x00002e9c6bfcd3bb,0x000b305efdfbac49,0x000f445da2626ecc,0x0000907070059481}}, + {{0x0007b22d683b3a49,0x0009bcf9beabef21,0x000c7562a038a49c,0x000910aa13a5841f,0x0000c9389d6162bd}, {0x00075090b585818a,0x0009316773fa9595,0x0009848a8d0f9dd8,0x0001f651555c4021,0x0000d05a8d89f69f}}, + {{0x0004d24ad962db65,0x000543238c6a727e,0x00075965517dee3d,0x000a85f8def34db8,0x00000d3a88c6d24b}, {0x00034a623ebab5d8,0x000bf7b417eac935,0x00037ce6949c24d6,0x000036e934f11b54,0x000018002a7a5455}}, + {{0x0003123c18986e41,0x0004271e4976ebd1,0x0009925168a8da06,0x0004b18aa1334900,0x00002665721f0fa9}, {0x000b0ff43133deb8,0x00000a9c1b9fdf83,0x0006c154d3516d4b,0x000d735850f7ed9b,0x0000e079bec8fd08}}, + {{0x00069c12865882fc,0x0008d9957a5ac327,0x00093aac73f8192c,0x000ceac6fcd6d246,0x000006af48a5b01e}, {0x000026027353e4aa,0x000e1c3a62c87965,0x0006a866c4b5c0d4,0x00057ef67206ffc3,0x0000f866c2bb479c}}, + {{0x0006024ef491d5db,0x0004e2704aefb3f8,0x00074dc8b5853c6d,0x00063b3be06adb19,0x00000a163a242c3d}, {0x000472d0e212765c,0x000adbffde000bf9,0x00095dfc6114a063,0x0002ffa142ae6b29,0x00003767dae16b26}}, + {{0x0004392a32caaba8,0x00067d4e7317e8fe,0x00062cd25f60018a,0x0002429928340b9d,0x0000d019c13c0075}, {0x0005df10a659460f,0x000ede055af81262,0x000fbaec0f8c8158,0x0004dd990e40671f,0x0000f1d47ce0cdde}}, + {{0x000b86d5de825fda,0x000827ad5ef1c31e,0x00017d3651481ad4,0x0006f11c7f12dd40,0x000023ccbabe1ee2}, {0x0006b90aaec673e6,0x000becfdce1eaa36,0x0004ffdf0bd56245,0x000f51bd73c118ef,0x0000fc7f3b398c76}}, + {{0x000b507845c7e712,0x00083994ff8becf0,0x000b099529c1c424,0x0000bc950938df6d,0x0000f211f0736bc4}, {0x00067c661de70ba3,0x0001d734eec5882f,0x0008914f01a0144a,0x000a3c5faebc04d3,0x0000aa86b02d5b26}}, + {{0x00019c31bec876f4,0x0001988ea72cfa1a,0x000ee8601d01485d,0x00046183d3520a82,0x000047ab80a29f96}, {0x0004251df44392bf,0x000a29983d364de2,0x000a88da2e7b5ba4,0x000954f4e59b9a0f,0x000037e6c24257f1}}, + {{0x000e6dfb09a4ace1,0x00047c55d4e26d05,0x000e515e1f45c89b,0x00043f7bd69ae93f,0x00005479b4aa9e09}, {0x000ba9bbf74ce4ec,0x000f332dccae40b7,0x00003a3676d0e1de,0x00089f9a692179b6,0x00006ac8d0990a7d}}, + {{0x000b612be9f087c7,0x0005d2b73fa0575c,0x0002ca2ba11c214a,0x000ed841f6a65480,0x00000b110025c00f}, {0x000d80afd4f314e3,0x000f3c64e352cab2,0x000798d050b2af3d,0x0004185885404c7a,0x000023d177bde8cb}}, + {{0x000178806542640b,0x000d88c52d25f44d,0x000446d579176f30,0x000397051da7626c,0x00008886aafbab41}, {0x00015912cf9cea49,0x0006e21fa90bb0ab,0x000908b221aaa808,0x0003a7333bfb3941,0x0000ff4d7efda834}}, + {{0x0006e39f3414f11f,0x0009d29f664e12c5,0x000500f05843165b,0x0007ffcb61460ce2,0x0000626de1e0448f}, {0x000c9f888fd60e9b,0x000814b7c85bdd05,0x000503d082652999,0x000f69928a0fbae7,0x000079af9aa5c51b}}, + {{0x000b748853dc369e,0x0001d5c46a9c7c80,0x0004943a99974554,0x0007adda66e0232a,0x0000290429a60883}, {0x000995ec151d853c,0x0008ff3a1822fa7f,0x0006eaede0e6bbab,0x000cba88badae027,0x0000c256d3997a8b}}, + {{0x000e2a41663b8554,0x00092366f160ca96,0x0001c123d905387b,0x00034e0adcd7509c,0x00007b1f6e4adc08}, {0x000b82f6a17de8df,0x00016127f77fa75a,0x0004d788321ad9a0,0x000a97ae85ad92ca,0x0000b54c99e120fb}}, + {{0x000bffe361a46388,0x000fa4c0605193de,0x0000fcdd0adb800a,0x000f5618356c1336,0x0000436032ec11de}, {0x00053a068b16e75a,0x0007a5a6a6730ec0,0x0001a5ba4dbd79ac,0x0005fe6729055356,0x00003a575af0acad}}, + {{0x000fdc35bf0c9f33,0x000da45b9b398957,0x000ad7beef5e41db,0x0006432a7c818563,0x00008c2e1c2b7db9}, {0x000b00db46177027,0x0003e2b378f87bf1,0x000a0f28a308889e,0x00097ba082187936,0x0000acef7ee2ea51}}, + {{0x0009390c918d6270,0x000362caac635c08,0x00015b8376799de3,0x000eaa821a885535,0x0000cabcf406953c}, {0x000d04fc7648475d,0x00098dc7d882d0c2,0x000aa0b4c0a7dc6d,0x000adf01bdcf234e,0x00000e2626b268f4}}, + {{0x000220825ed35afa,0x0009576f7cccbe00,0x0003a8d37c11d3dc,0x000bd7a0701b842c,0x00007dc318423ed8}, {0x000dc6851e23a270,0x0001482baddbc17b,0x000ef80594dcf07c,0x000635f48b62fcd6,0x00004ba3f7faffe9}}, + {{0x000df3379d5aaa09,0x00053e95a9719715,0x00094035e04096ab,0x000371086a53ef79,0x0000479c7b8f06c0}, {0x0006071ec85431de,0x000b4d8ac75c33e6,0x000b91fc3cf2421d,0x0000c5a713565a6e,0x000093f6b5095293}}, + {{0x00053433c213411b,0x000f19421558a32f,0x000cb3419d7893da,0x0003e94fca316dfb,0x0000374884a86a35}, {0x00018637e8891bd7,0x000dda699e3631dd,0x00099f03059dff7f,0x000c475d060ebfba,0x0000bdd0e28de233}}, + {{0x0008625a553631ce,0x000a9796b7c66042,0x00069e1a8d149b49,0x000b9d24bf15c71d,0x0000499b36421998}, {0x000c53bf713ec42e,0x0004b77890566781,0x000528324cc47d1a,0x000e99ee4752d162,0x0000b9b11a1afa93}}, + {{0x00081a0ffb5c9c9c,0x000e055f0aae4142,0x000f67533c055cb5,0x000ba1661d64b05f,0x0000d37a37649d4f}, {0x000fbbba5ad491dd,0x000cf8282ecf7198,0x0005ccb6e6b04c81,0x0007ebe65a66949f,0x0000c80d786e0584}}, + {{0x0008203f4211c7b1,0x0002f22609747204,0x00046dc191e8d62d,0x00019cebf4ef9152,0x00009163ffa00eb0}, {0x00076e6fe036a5d9,0x000f17c8eb9e7d4d,0x000b94224aca7e98,0x0007dafc52c4dd07,0x00008fcefbaee74b}}, + {{0x000f5f295afbe525,0x000dabfbf6f56e65,0x00029dd9bee154ba,0x00075fc7e43056b1,0x0000c6703f05bb43}, {0x000575770ca61480,0x00034ab150f37095,0x000ceacefada8fcc,0x000f68dcc0b53bd8,0x0000e9010313dffa}}, + {{0x0003c71f5c8dd248,0x00064afb2df6f44b,0x000c4e22d86f05fd,0x0006bdb2e524154b,0x0000823ebb857629}, {0x00050ddefbd1fc06,0x000d57e3a6573398,0x000e9fd87a05db65,0x00097c5a82bfea97,0x000012602f1dc978}}, + {{0x000d464401ebe000,0x000aae7249d91866,0x00036dc90713e6e6,0x0005568974870842,0x0000783ee0137c6c}, {0x00074662eccf7759,0x000d7f6b891712b7,0x000f43eca62ac342,0x000072ff0edd30ee,0x00008a7880f860aa}}, + {{0x0006cebf5ed71c29,0x0009efe22291ed90,0x000b496537c3d7bd,0x00085a93bb5041ed,0x0000dfedb68b74e5}, {0x00072c8d5958c8f8,0x000afb5d5f31f91d,0x000f4d874ee28bf5,0x0004f7e7a69fd006,0x0000529fdae49ca5}}, + {{0x0004deb5cf2cc3c6,0x0008c9d887dc815c,0x000d6a375e22f1ae,0x00076773ad520b03,0x0000de108610ca0d}, {0x0004e8cb47e14977,0x000ad0aea66d4a4a,0x000783042dd19814,0x0008d9e54672563b,0x0000b890128daa2e}}, + {{0x000808410ee3d23c,0x000392a615b14640,0x000d2683f464306a,0x000bd3ab01e405c2,0x0000e70e8511df3b}, {0x000fdca6a9e839a1,0x000c9403fb89e6fe,0x0006a9fa129439dd,0x0006d65462b965b3,0x0000f3fd2b9110f6}}, + {{0x000afdf466dca9a6,0x000ca27896b1bc08,0x00026b7aac5ebb91,0x000b7ee6800bd153,0x000059f83a9b154b}, {0x000160df796189f5,0x00088ae54694e160,0x000d66289e9c55c3,0x000b00a2b43c3c19,0x00003413ff683fcd}}, + {{0x000aad2f31e88186,0x0004568332d1f745,0x00085e5b8099a8b9,0x0006911240d922f2,0x0000f5f060aefdca}, {0x0008a8cc9a6632e2,0x00009a8ad40a2cac,0x000b2ec9b7267e5f,0x00067797ad93d424,0x000056880826d350}}, +}, +{ +/* digit=31 [{1,2,3,..,}]*([2^217]*G) */ + {{0x000c5b31b84523e2,0x000be6e4ef99ea3b,0x000a69918305e9d7,0x000f226013092787,0x0000aeef51df4898}, {0x000935d577020efe,0x00047c06a751ec81,0x0009737700fb9a01,0x0008f210ddae1671,0x000078a0d0f4c882}}, + {{0x000d5e8ccd993818,0x0000454160028f27,0x00035c9e5ac962fe,0x0003961bd348325d,0x0000f7888f9d08c4}, {0x00028e7cc2ce2849,0x000864e2a7ab864d,0x00004f4743155567,0x000056ef40757409,0x0000de9ba7203fc3}}, + {{0x0005c0ee77817ffe,0x000841cea362486f,0x0007dd9962de3465,0x00073b6d58d6ef81,0x000092b6a9f738f6}, {0x0008e609ec8a67f5,0x000d874bf95d4493,0x000f082668cc88ea,0x00018e51a53b6999,0x0000c44968fda017}}, + {{0x0006d9a9c9c7ecd6,0x0004277106c7b597,0x0006ce73e23fd318,0x00098a67c30e1c70,0x0000f0d0fe2ac602}, {0x00005926a46c71a3,0x0006512eff4774d6,0x00068ac6f253f036,0x00014e045f24b5e9,0x0000148b466e0cd7}}, + {{0x000fcfcd84a929d3,0x0002ad54a2149937,0x00096084028ac0c1,0x000a98eb3a256be9,0x0000a028f7a712e1}, {0x0003ed11da5648c6,0x000765175dac0cf5,0x0007e6793730e016,0x0006e12887741adb,0x00007b90747e694e}}, + {{0x00095060b7f3155e,0x000baaf4df36ae23,0x000b773beedb6ad9,0x000e9434c85948c6,0x0000285db363d9d0}, {0x000ba7a7d1c9fea8,0x000fd444e8a8f514,0x0001079dfc491f23,0x000423e35a941ff6,0x000029feac4a3859}}, + {{0x000f263a7b127166,0x000ffda74297f963,0x0000d25cbda01050,0x000eb7ffa92a1540,0x0000d4cfd6140a62}, {0x000ec796b38c0f5d,0x000b3301612e7e11,0x00088f375bb456a6,0x000f1d2e639ccef5,0x000023c5b7ec9322}}, + {{0x0000d0706eeee3b3,0x0002383bb3c41af5,0x000789d57412b36c,0x0004f76f161f4348,0x00009d54f9fa323c}, {0x00098713416de57e,0x000f289880622fb7,0x000ffa44b6065378,0x000ae646228a95c0,0x0000e77ebc11e012}}, + {{0x0002e057a7667ee3,0x000980621f16ec01,0x000dc6a70ce7de5d,0x0000ab25dd09f571,0x00006ba631c46be3}, {0x000a3ceb0468f0d6,0x0005cca0a4b4f979,0x0006814d43b03db2,0x000c037bf72fa0df,0x000070b2e22306cc}}, + {{0x0006e4060e56d291,0x00073f9eac2a60a7,0x000609574bf57884,0x000850711a75007e,0x00004257875312d3}, {0x000515eddc745f56,0x0008085a3ecc7070,0x0000354544ed84c9,0x000a74204234e39c,0x000012c06b29876a}}, + {{0x0003f156c03f4661,0x00016f589034ebea,0x000b6ec7176a4552,0x000ff259e041df5b,0x00004ed99b1037dd}, {0x00086d386ad2e060,0x000fad2ab5238d4b,0x00011e6c46846865,0x0002b3a450957a0a,0x0000c5d260143d1e}}, + {{0x0008e38152258344,0x000fef5032e4a93c,0x00001424b43ecac7,0x0006743325458b93,0x00007f95a9785eba}, {0x000a205186d9025c,0x000035a7fe558fef,0x000a3c8776c0b58d,0x0009496073e77a5c,0x0000b53d4427a2a0}}, + {{0x000aa0fa4a2e211c,0x000f72cc7932a003,0x000c29fd7e905873,0x0007a0116f12125d,0x0000e442886f9b48}, {0x00007e055af80e44,0x000c596df90f2dc5,0x000d6c18109d73f5,0x0001df729ebcf653,0x00004160bd446d9c}}, + {{0x000fd2d788ba6520,0x000d76ff5738c9bb,0x0007fb3242d9cc46,0x0003339c8d8920af,0x00005c508f078998}, {0x0009e3679f4ab8a7,0x000e2634f4ee182c,0x0009bfae6cc835e1,0x00046a9f81c34f84,0x00003d0468bc1916}}, + {{0x0003b15660f59ef7,0x00088c12554eef23,0x0009330a3a321c51,0x000b3626b05480ad,0x0000c022c30d43d6}, {0x0000661046f68e00,0x000e80e8e9ae5d65,0x000b4697993ae49c,0x000eb1d32afb6dc9,0x00003f033a44cbae}}, + {{0x00087e5163cbc0a8,0x00006ae98f3ee679,0x0007b68448c3e107,0x00085d27aa4bdafa,0x0000aae2dbd0b3f1}, {0x000ac1ef01e8f3c8,0x000854cda9282656,0x00092a068b13fa74,0x0009658322dae1bb,0x0000f651015f4306}}, + {{0x000161d5feff15b2,0x00050345887b8e42,0x0007f685e1f8bca9,0x000a5e069e055b08,0x000014e3f1706090}, {0x0005bacd466e93c2,0x00024cc6b95b9719,0x00056a22d1b25609,0x000c93c6c0448103,0x000081192897bb0a}}, + {{0x00036a0c08a594ea,0x0003b66986efe95b,0x0002f86466896b35,0x000998b3227efd50,0x0000227f683c30e5}, {0x000dc9ff42ea5c5c,0x000e34f0f1d46fea,0x00047ca2cad6837e,0x000856ab3a67ba93,0x0000f0eb2cce452f}}, + {{0x000a1589e0b82fbe,0x000de449e007aa58,0x000d14a4ee633c68,0x000e61af8fef7e89,0x0000f60872f433ac}, {0x000016d64afd1619,0x00060de62c698aca,0x000269bb3d24f6f1,0x0006b7f138fd2d41,0x0000d75248556ff5}}, + {{0x0005206689b92bee,0x000843322d9c7cc9,0x0009915cd7756249,0x0003f02dfc1956ca,0x00005236e7bf69e6}, {0x000a95adca139b5d,0x0008994070b778a3,0x000f73bdbd4254b2,0x0000abac251dcf19,0x00001d28ad0b0466}}, + {{0x000a1cb8a87fdd06,0x00090886a6941375,0x00048f1903f9324c,0x000cf3376989c09c,0x00008b982f180de2}, {0x000716ea40012c9a,0x0001f5874d1db96a,0x000ec9471af0aa5e,0x000a1ab118cd78d2,0x0000f9537952f8cf}}, + {{0x0000b7eee1e1bf2f,0x000297cd743a214a,0x0006a906ae3eb720,0x000f876830a1a414,0x0000eec17838e9e3}, {0x000c737251493343,0x00025cba6f7cb12f,0x00039b703deff11a,0x0000f4e3aceabbfd,0x00002ffa04f9bc74}}, + {{0x0008f06e2aff6bdd,0x0009c7332d94e0e2,0x000f1e13c0a81628,0x0000ff353b4e659f,0x0000c3f048b4016c}, {0x0002e01399fc2da4,0x000c7348679e5b47,0x000abca0e8e7b659,0x00038dd0e20e577d,0x0000dd894b007fae}}, + {{0x000396824f4dbc09,0x000ef06eb9cd7555,0x0000b18acd3df1a5,0x000c18b8dac35ee4,0x00001c7903921397}, {0x0001731faf0f10d2,0x0002d760c1326c4a,0x000f6f5ffea89051,0x000fc39c0f9ced36,0x0000da37d490e5c2}}, + {{0x00023c3b69935ff7,0x0001b3e28de35919,0x000607e0e5dba168,0x000e0a1c7a1ab695,0x0000bc842d58c6bb}, {0x00050d68e758fca3,0x0000ca556db21bc5,0x00047dbec3ec857a,0x00078a4f47c22922,0x00009b45db21fb1f}}, + {{0x000d2b6ed3921dae,0x000414a6a41de350,0x000e1bfe1f418863,0x000a7247d4440aa1,0x0000b202e69be99b}, {0x00035efe5f191a91,0x000303646d9b68c0,0x0007fafb6834e5cd,0x000afd13b66152d2,0x0000e96ff34fa402}}, + {{0x000b50e619a7cc77,0x0000dee84fe2d25c,0x0007ba3f798fa246,0x0003a2051c8c69ea,0x00001559f9755949}, {0x000191005085716a,0x00048db5ae91d058,0x0007c9a5df811350,0x0001e3e76081f3fe,0x0000a0f5614b8aeb}}, + {{0x00018f0a36ef4ceb,0x000febaebf8d4eae,0x000e5c11972c983d,0x000173cfd8c7fe1f,0x0000ff0b6553b58d}, {0x0009033ebd26a6ee,0x0009ca7741c57b63,0x0006d6d0466228cd,0x000813a88d56d595,0x0000001ac00370c6}}, + {{0x0005d49926257fb8,0x00077f587dd695d7,0x00072592f34e8e90,0x00023c28f9cfa11c,0x00008d9950a9e218}, {0x00075ebe481c5af1,0x00050e45ff723481,0x000f61f5abfd66c4,0x000a368b3c547be6,0x00004be914ed594c}}, + {{0x000d4cb73f9b6f7d,0x000e6906174ac89e,0x0004880c64f0fe98,0x00036ab58f236e04,0x0000e2d38bcdc3ab}, {0x000079f3c7af69a5,0x000d95f71ef374c3,0x00041a7447c72579,0x0002667971715ac4,0x0000cb5f998473fa}}, + {{0x00092f2379f7fce1,0x000b91a877864bd9,0x000364c15e47690f,0x000ea25416b9dd02,0x0000a7502960f53b}, {0x00054d4ece71149c,0x00063a28d0321ca5,0x00027b740cac9de6,0x00064ca0b521c06f,0x000059d3a7108c18}}, + {{0x0005870ea005a99e,0x000ded4e493a6467,0x0008b6342b1f047f,0x000374e92a439f17,0x0000a8cf07331051}, {0x0000b513642fc657,0x000dc5e958827812,0x0009b568996f4efd,0x000bfc8f6ef537ee,0x00006743642f3440}}, + {{0x000e3950009e8bd3,0x000279e9228e1db5,0x0007ea75e0e087a5,0x000f0b16adfbb8b1,0x000019ff54645b70}, {0x000dbac58096735c,0x000bb470fce96e38,0x00074907665c92ce,0x0003152b53c9925c,0x00007fc121cadb2c}}, + {{0x0002ee6e219e439c,0x0008fe4475fcfc8f,0x00032583de9c8ba6,0x000c3513fd771433,0x00001a001f040451}, {0x000cd5f7de1cf983,0x00085bb184294f07,0x000f814357b1fe00,0x0001ccad465687a2,0x00004f0c50019ffd}}, + {{0x00030d60cc283637,0x0007dd26a89da97e,0x000f66c26f3bdc24,0x00028716946a9f2d,0x000049a732f2b2fe}, {0x000eef2bd92b8614,0x000b8f3412a393ac,0x000dd110fa90e595,0x0008b581363eb9d0,0x000070f21b629f74}}, + {{0x000fad5927308e4f,0x00030bb54d64004a,0x000a41ebe0fe1a31,0x000560cebeee51f9,0x0000dac11edecab6}, {0x0001e3b630efedfc,0x00077c2beb530f9d,0x0005792e9f5dc319,0x000a71d1a7ea1706,0x00007af663c8c1cd}}, + {{0x000da7bfbd9bb256,0x00088f98890312d0,0x0009548cec55316c,0x000574630b21bcd3,0x000068afb84e9c85}, {0x0009deff6c589987,0x0008e55e9876e7b2,0x000294123dbb7769,0x000712eb8772a9b1,0x0000839395ed1e6f}}, + {{0x000c0a30eb328e86,0x000d5f3a638185aa,0x000c9547dffb413a,0x000f6fae6f8615ab,0x0000e8a6e4701dce}, {0x000b06cc1508bb6c,0x0001b02dbc1f68a9,0x000300f8c0971c4b,0x000fcc371a6d703e,0x0000572fdf15650b}}, + {{0x00014db965071922,0x0003fd3a06369215,0x00011156ac525f3f,0x00027cdb39a981f8,0x00009ff3e0ddcbaf}, {0x0009eefc2c911a83,0x000dae8564210d12,0x000e48efd1688b3d,0x0001eba6dd9308c0,0x00001e6c71545583}}, + {{0x000239152df58a36,0x0008b88e7897dc94,0x000725ab0da0e680,0x0005712ab70e052f,0x00002dfafe3d4212}, {0x0000c2b547371a4b,0x000f4634997de154,0x000cf959ac418e8c,0x0002b4c8fd0e263e,0x000002ca92f3a644}}, + {{0x000805c84e906013,0x000919f4512d7d81,0x000b903bdb4e8554,0x000102020b9b4abd,0x0000a2f04651f18c}, {0x0006d4fa96d8846c,0x00065f0a7d84a420,0x000a4f5352b5e62c,0x000aebcd087cf50a,0x000089c1c7665b9e}}, + {{0x0008e8c15f4490e1,0x000c711806b5723b,0x000f3dfcc9e3ac69,0x0003592e9cdffd09,0x0000676c5f59ab6b}, {0x000e90769fc0122e,0x000ab513ee51387a,0x0006265ef72c716a,0x000395f648e85a3a,0x0000f4445a0a69c7}}, + {{0x00018151ce7faf96,0x0000532c5b17ec8e,0x00077e27fb8ef2dc,0x0009410a4e7962b7,0x0000c7bebe0dfb90}, {0x0005b36791119157,0x000f9791b658b9e3,0x000be736d2983a2e,0x000e11010136896a,0x0000c94c6654ec0f}}, + {{0x000406ad44de0c1b,0x000c823978422f9c,0x0006f3621ed79654,0x0001a45243e9cb05,0x00005a526aaf5259}, {0x0006e9a9952c4041,0x000855d7a5dd0ef8,0x000dfa8b751cd3ea,0x00025c3d5a28b82f,0x00002a085cddda12}}, + {{0x000574c792dd046d,0x000f5db7e04c0de0,0x0002d73f5299ae27,0x000f2bc6f076a4c8,0x0000f2221a703b2e}, {0x0002417d54d5b7b6,0x000fc839da3fd624,0x00044fe6c06c3727,0x000aaebb622fca7a,0x00001614329d0960}}, + {{0x000325aa1dbc71da,0x0003a3f618cb10ed,0x000260f367d91c3c,0x00030ea528ea5e8e,0x0000e7f55131cb6b}, {0x0004e5c73aafc584,0x00007632d1f4e563,0x0003a9ada2a5f580,0x0003d5c9f78e98cd,0x00002612d9f9a844}}, + {{0x0003160cc8cf665b,0x000e9e2cfb82d281,0x000edb5756ac3c06,0x000e86af8cadc78b,0x000071b8a8a9cc1f}, {0x0003f77d6e5686cf,0x0005209f60fd7801,0x0008985728540dc7,0x0000e66d1006fb9d,0x0000dc1d2d11771e}}, + {{0x0004b1a3a9ebb91f,0x00079e23c8e26301,0x0003f0318faa7688,0x000cb05ca5649a17,0x0000ebcaa67af4d9}, {0x0002c158208295bd,0x000371886d2c6ec3,0x000e776fbf3d9c03,0x000b7362ad550edf,0x00001334c9a2dcf7}}, + {{0x0005cdabf52ae483,0x000f0023da388f9f,0x000ea4f0b62843e1,0x0000cd6ef53468be,0x0000740e9f1ab937}, {0x00048cac670d194c,0x00029ef042cd432f,0x0004ca10792b2164,0x0001b35141393fa9,0x0000aa5fc8cb5d0c}}, + {{0x0000b35727eb78be,0x0002fb568e8e3d15,0x0001e26a3e2ebfea,0x0002fe87e6eee810,0x00002e0c18aae6ca}, {0x000ae2e653b7bf2a,0x000aaae347811b25,0x000b752f14d7c1f6,0x000db47d5881de85,0x0000780051b01dcf}}, + {{0x000c69e25aa2f590,0x000fcfeff037dd97,0x0006795b3afeec1a,0x000072a7aa5584f8,0x0000bd60ddffb0ab}, {0x0003d1d63579ef96,0x00038bdcb0ce53e6,0x0004cf4f0c7d0452,0x000c8c0caec14839,0x0000f6a443c4bfe1}}, + {{0x000aec68e12bb566,0x000cadd2bf62c823,0x000164fe059a6763,0x0005e5b4c9c33897,0x0000c530539c6f12}, {0x00069d17e4ca16f3,0x00092006835fcdad,0x000446dd2c99910f,0x0006bb216844cce3,0x000072cda8fd616a}}, + {{0x000043b5b6bfe4cb,0x000c16005febbe5c,0x0009968d097918c5,0x000f4e4a462373a4,0x0000b41b04486447}, {0x000539244c050f62,0x000a32282ebb4b0f,0x000cce069df1c278,0x00019d3afcac56b9,0x0000055958d3f6cc}}, + {{0x0005beb93e6a98a7,0x0001afe915c2b32c,0x00073fe92bbdb3df,0x000079b9f6b3c836,0x00000e14fe20db48}, {0x0007c1023143cf73,0x000f8f3cb4626a39,0x0004f700663c36e3,0x00032fd7c3f3a263,0x0000681de4ac3a90}}, + {{0x000e480c11b6a9ee,0x000d18da2ed97ee4,0x0008b99486776294,0x000a1dcdde1ed3b2,0x0000d4858b9d272d}, {0x000b8bde14ee45e7,0x000f52dae44f1c3c,0x00050b513d37586f,0x00076d444fd07f6a,0x0000af995ed1d2ea}}, + {{0x00044d16e12de73c,0x0008fa09833ad676,0x000cd6eff8c6eec8,0x000211ef8af11042,0x0000dde13acc2a1a}, {0x000e1eb4ffd0ff5c,0x0007d068a68888ad,0x00042fbf6b645660,0x000e072b8fa57096,0x0000277b6578737e}}, + {{0x0005f4f9aa856e82,0x000f2619d7efce68,0x0003de1a8a355582,0x000a02db631aaf40,0x0000ab82cdeda7bf}, {0x000e072b3caaef56,0x000a8199f1d82785,0x000d0fbdc36aed81,0x000cf338edd76909,0x0000ee323f0115ec}}, + {{0x00091002ce826ecb,0x0005070eb620e97c,0x00030a866284171d,0x00087fc5ea32117f,0x0000e6dc3918a37d}, {0x00077c1f1c8587bf,0x0006106dfc0658fb,0x000423e93d2aa347,0x000d9893fef10a37,0x0000e7353a966099}}, + {{0x000cd1f4fed94fd1,0x000122df66a25b2d,0x000312cbb38fa84c,0x00087fa9de6e108d,0x0000e58b82e39071}, {0x00062712709f1afb,0x0008220f16bf0299,0x0000e9cc7fc74306,0x000d421bdb073052,0x0000513ee8efcfab}}, + {{0x00068279bad9b185,0x000b327666c7d175,0x0008c9c1dd36184d,0x0004cd676a4d1d70,0x000008a102f5f44f}, {0x000c7971cffbe4aa,0x0003a2729dcd0b70,0x000906aa5389c9b7,0x000ba57ecfcc1302,0x0000e349023971ac}}, + {{0x000f9aa0de1a61d9,0x0001f5fa5b318663,0x00043909cd0eb9de,0x00070dd7cd579618,0x0000a3eba0c2f73f}, {0x0001563d342860ad,0x00037b084a171284,0x000349978d04890b,0x000779882982abae,0x0000299f32178cc3}}, + {{0x0009f8c49c28aac3,0x00063d222aa77172,0x000103c13f3dda6b,0x000d9a62596af21a,0x00005e568bfd037b}, {0x0001e0a3cdd62251,0x0008c79442a934a4,0x0005966bddbc1924,0x000d996eb83bb296,0x0000d90edb6dce94}}, + {{0x00040493f8013851,0x000ede0d970de34f,0x0009faf7a3b27f40,0x00096ad59ba58757,0x000057262f97764c}, {0x000fd035bf8844cc,0x0005a298a25a667c,0x000fe862aa4f48dd,0x000cfe02fa51099d,0x000012af89f023a9}}, + {{0x000031e9fdea2db1,0x000832d1378f3a95,0x000a5138980ba7d5,0x00069a4bbdba0178,0x000013224e7af549}, {0x000465bcc967c9e7,0x0002d4159c9f2428,0x0007c9b27802478e,0x0008fa77cdc3d6ab,0x00005eb845feb91c}}, +}, +{ +/* digit=32 [{1,2,3,..,}]*([2^224]*G) */ + {{0x000b2d9543778c7e,0x0000f184ad17cd35,0x0009a46cd9fa03ad,0x000d6d473d03630b,0x0000d62ab38692bf}, {0x0004c753b746abb8,0x000a9805cc3c45f4,0x000dcf780bd4f09d,0x0008b45e59befc01,0x0000428ee8930818}}, + {{0x000e7e4fe75c81d7,0x00043a055bf3f186,0x00035ef774abdc47,0x000c9255708754bd,0x0000dc4ba227334a}, {0x0008b967e563c5e5,0x0005ffd12d0380e3,0x000770a428f47d00,0x000757a882b69d41,0x00001a9a96d95f73}}, + {{0x000a784242f916eb,0x0003881ba08bc794,0x0005598b45b14359,0x000d754b78024dc8,0x0000f1f6b99a6382}, {0x000032cfc2cfa484,0x000c8e929e3f547d,0x00059d8829cc674e,0x0003a46aa7f2ecfc,0x0000788320c644f6}}, + {{0x000719cf322c469b,0x000508f3f43cf975,0x000e62459967e01c,0x000174d43d2e7f3d,0x00008d9e6307095b}, {0x00021eba643504f0,0x000978c05daa5177,0x000a1e00ca592f59,0x000eacc0e1e26416,0x00003636fec99769}}, + {{0x000f92768319d8df,0x00052450c06acb5c,0x000f8507a4008c6c,0x0003b281d931f721,0x0000415627b3750a}, {0x000f1a6fba4408d2,0x00097d431af170c9,0x000e56bd0b53c06d,0x00067f2c806e5c24,0x00008d4461687aa1}}, + {{0x000c802e66289036,0x000a3e8fef25bf13,0x000531667a83b699,0x00062916e69a9032,0x0000326f5c93428d}, {0x00025675e2faf33d,0x000b9c7672692bbf,0x000dc358ce94e379,0x000e142af942870d,0x00008672198b68a5}}, + {{0x000f91306ebdde85,0x000deccb55825166,0x000e2bed929a65cb,0x00089e0295a92cc2,0x0000e1f181df2c17}, {0x000223e7b6db2362,0x0001fcafee6e4f52,0x000d6487f3719ea2,0x0007b3ae4fb532be,0x000028642271114a}}, + {{0x0002cedb269ab580,0x000d60cc26c5261c,0x000b8d89fae34d79,0x0001b3b61a336289,0x000038143332f363}, {0x0002e8df47ebad1e,0x000adec248835328,0x000adff3c2c72144,0x00017c5c7e5f1fb4,0x00000b437c44a55d}}, + {{0x000f096ee9f20f71,0x0002602065c66848,0x000be0ba3d5ed400,0x000170008711a9db,0x0000c675cabb9082}, {0x00001a5382a25585,0x0009146dcc0627aa,0x000b9e8cd2497f62,0x000ce9d3863516a6,0x0000450d5c077a1d}}, + {{0x000bb204eb1ee993,0x0000248697876b8e,0x0009b153201c458b,0x00061176db7875fa,0x0000a7194d5e99bd}, {0x000677cfea8c0c4a,0x000a3b5e4b4ebf64,0x000a40a1a68a382e,0x00017da42f53941e,0x0000cf37a3fd9a99}}, + {{0x000f89d531aa521b,0x000d2cd651bbe08a,0x000e4807dc9acf2e,0x00064b6fd48bb09e,0x00000c23a0ed988d}, {0x000accaacd9c0465,0x000107b9102820de,0x0002f26b1b74087c,0x00024fc03e2a1a8c,0x0000e96ef37c79f5}}, + {{0x000728e8507807fb,0x0000036e51fa4423,0x000c53ff715475b8,0x000abd5504dd5344,0x0000af2d60b21d24}, {0x000bcbc1aee6b633,0x0005403e9323219e,0x000c98408f908e14,0x000b388b548ad17f,0x000090118c4e2230}}, + {{0x000dee15b199bc28,0x000c3ec9bdce59de,0x00065ca517f3fca5,0x0008ae7e6b17138e,0x0000784fd240f6aa}, {0x000b34895517b55d,0x000b5fbb4bca8fc7,0x0009e51560b1461d,0x00084b390e438efc,0x00008237a0c71050}}, + {{0x000f4029482f6db1,0x000118db548d0404,0x000c18f0bbf747da,0x0001ad66134afd23,0x000094dcd37be9fe}, {0x00063b0dee6fdae6,0x00067ddfb415ac18,0x00080f9c5669ba44,0x0006d1752f950c9f,0x0000804af7be1120}}, + {{0x0002ac943502b506,0x0004a8db8753f15a,0x00091c2ab67133b3,0x000a77d46c93c8cb,0x0000eb11fc244912}, {0x0007ed2e8e4fb729,0x000c26141a84a0bb,0x00028a4201f1077b,0x00044796a9fb7240,0x00008a44d90c3a6b}}, + {{0x000b1148a2a41ffc,0x000c4865b95ebce8,0x000339dcdf6479e2,0x0005ca788dbd8b54,0x00002ea6baafdd0b}, {0x000edbe9b9fed913,0x000b6fe6b2206245,0x0001105f7b61f901,0x000d311b9cd2149f,0x0000736ac5f8b6fe}}, + {{0x000559ba097b695f,0x000aa4c95ed7fd2b,0x000e2778f8711990,0x000cdc8cbf812ce5,0x000005cbb9ac407c}, {0x00027bd9059f0688,0x00032d37e6550791,0x000b95e9ffc012b5,0x00026ca112f8f653,0x000081248e6edfeb}}, + {{0x000fd09736f5292d,0x000fed6e1546c027,0x0005355f15af57c6,0x0000dd4d11a6061f,0x0000478b38244148}, {0x0002a6999d7e8576,0x0007e0506d5152b7,0x0002a801e7ac65ff,0x0006595b43ed6866,0x00009951fde545e7}}, + {{0x0001a071295d542e,0x000a51a0cc328460,0x0007e1fe3156a9fc,0x000d31bc6de53c42,0x000060f47cd2c597}, {0x000fe89df3012d41,0x0002da5a61ccecc0,0x000fcc1cfbeb7505,0x0003e0edb233e400,0x00001296a606f2cc}}, + {{0x000af7da8d3682b4,0x0007212de42eeccd,0x000e95389b488c0b,0x00018a5aeeda5a59,0x0000474193abe0b7}, {0x000ee97fbc642a3d,0x000cfc9230f0fde2,0x000e131dd8901307,0x000d7c11c9bdb27c,0x0000d12ac316724b}}, + {{0x000d17162e8e5a89,0x000bc66e49efb223,0x00032c9d77f37db3,0x00008043efc71fee,0x00006af3cf6922ce}, {0x0008b9edfb4d41be,0x000844d25cc9d80e,0x000b65b33958a078,0x00079779756de346,0x00001047c9633e6c}}, + {{0x0001564562861678,0x0007624f5cf93034,0x00042ddd963d4ea7,0x000eaa5452277ebc,0x0000f778004d947a}, {0x0001d5def2c56adf,0x0003ae9887f18ecf,0x000a1bf7ebc72b29,0x00097380809dd58f,0x000017a4ef6dc806}}, + {{0x000ffbc9689eda66,0x000883cbbaca1e51,0x000bd0b4d8274f68,0x000fe6bc2914046c,0x0000ec4eebe6b263}, {0x0005ffb314eea5f2,0x000725a4dacce9fb,0x000c953fe6a21a13,0x000ec703932270ec,0x0000c0a405e7c67e}}, + {{0x000c2104134b7fa7,0x000cb3ca29958ec1,0x0005393c52936dfd,0x0004c4da1702d97f,0x0000076b85955721}, {0x0004e97b47458ce3,0x000b0255e87b6495,0x000978b25d48c2ed,0x00049992e3869a33,0x0000244683c71001}}, + {{0x000bbb5e9143e442,0x00055db9d859c5c0,0x000375cb2b951190,0x0001b1733a3e81f9,0x0000ac5b03ec9ddb}, {0x0007d302948b0cd7,0x0004f9a6575ac87e,0x0007e4790e2f1bd4,0x000630d239465cc1,0x0000495665c00aab}}, + {{0x00003d0220dd5b89,0x00050373b8bcb287,0x000b0ad2922a78e9,0x000846833d2f1554,0x000074a397b3fb03}, {0x000d9918bc837c91,0x000769a8126c6a24,0x000f1b5a8b117dd9,0x0001af8d5aafba53,0x0000dd131159eb82}}, + {{0x000a397f380ea2a5,0x000e34cd48b2b67c,0x0008c1b9089a0492,0x0000b7cfb2598235,0x00000f8994fbca51}, {0x0001ef0d4dc6c624,0x0009298199b2a1ec,0x00087db3d9e0b8b3,0x00099bbc93b64cd2,0x0000cd843c51f5fb}}, + {{0x000f2327e09ec79d,0x00048f5c71fc1d62,0x000a82286325e75b,0x000fe92ccbe59c8d,0x00006fa414a59f54}, {0x000724008dcda821,0x00010b18f8339015,0x000cf347b8cc0b11,0x000128d6947544c4,0x0000ee012db1fa6c}}, + {{0x00050c20403a0188,0x000194e8aeedbe60,0x0004a13ba2ac81b4,0x0004e49f3507ba09,0x0000a84889026e6f}, {0x0007b081fb782f23,0x00008c896e27b256,0x000d7b64ff3aa055,0x0008e9a6a881dd34,0x000087a29a866dca}}, + {{0x000f6328d9d29d96,0x000d08db211bfd9b,0x000196c59440e6de,0x0006dfc8e0e709a0,0x0000f9e5f4bbfa4c}, {0x000465c50215dae0,0x0005eb2929551f20,0x000717e82209b62c,0x0005f3c4562e90e6,0x0000e285dee28eb8}}, + {{0x000205c0600232bd,0x000431f8827f3763,0x000527014aa51d8a,0x000c1fa849aa3f41,0x00008ba1d2ff2e5d}, {0x0001bc02ae95f211,0x000374b719625b66,0x000a5dfbf82172e2,0x000b0210053bc018,0x0000a5c238000900}}, + {{0x0006fb6e9e7d0596,0x000bb48d628f76a4,0x000537258d83215f,0x0000496c09409290,0x000066b4a0c8e820}, {0x0001553dd1a5b840,0x00079e8bc4811584,0x00014f392f62ee96,0x0004d21271a3266c,0x0000c58bc7ed96c9}}, + {{0x000f14924e235001,0x0007aac142e06662,0x000c167087c97cfa,0x000e77976870a24d,0x000066e483cc4979}, {0x000f427bdff1294c,0x000acb0b96b81737,0x0003562de53d5748,0x00004ef798c420eb,0x0000348b0d67a82f}}, + {{0x00034268181809e0,0x000330cf8b408ce8,0x000667cd7f1007cc,0x00096db7b5dbc432,0x00004a5fdb5ab287}, {0x0000a0bbf904ec7c,0x0004515938c30e2e,0x0000e23f53a28bcd,0x0009f9b087f747b9,0x00007ca540d88594}}, + {{0x0000d0129cd59a23,0x00046c9cc596ba69,0x0006da59b804d17f,0x0003a7fcd9be29ff,0x00009391f4a28708}, {0x0002481b5b5fd7cc,0x0002560774cebe2d,0x000e9d1e0bc3a862,0x000a4e0a9a5290cb,0x00009ae842e67c86}}, + {{0x00070bee0bc209ae,0x0001fa68d56bcc57,0x000336ccfc8acb05,0x00056142ff984b5a,0x00002395e2c8eaf0}, {0x000ee62df7bd9c4d,0x000e990aead7b27a,0x0008b9905f304af8,0x00087890cb620c4e,0x00008a6a079e2dad}}, + {{0x000c8dcd3073a282,0x000eccbae3857ecd,0x0006a1bbf1f16623,0x000a2b699d780d31,0x0000a776063eab23}, {0x00035739c18802d9,0x0008be6cd5f5211c,0x0009c468c8a0afc2,0x00066879d94b3d64,0x000009f3b2c364ec}}, + {{0x000a623675caa390,0x00028de287f93701,0x00038ba2ae9ab86e,0x0007f403801b55dd,0x00005f51848e944f}, {0x00047ca0ec88095e,0x000876d34449537b,0x000f35de03bacc95,0x00060e05b1b4f1ff,0x0000e43d1be7522d}}, + {{0x00091191b64ddcb0,0x000c0794106d2195,0x0003f8ccc8b5d196,0x000c12c9dc943645,0x000075d1ab7bf58a}, {0x000f0de89450cd20,0x0002aef9f6ef6324,0x000c1a78a35e6afc,0x000a26e7aaebd3f9,0x00004364f4e1540f}}, + {{0x000647708e12eadb,0x000e541c5a2c7a67,0x00065c0fd50feaec,0x00094ee408014a21,0x000031b912b28fcf}, {0x000e4a198d6c20a2,0x00014241bc066c87,0x0003cfb9a4b52b25,0x000955038acdc322,0x000092e10576361d}}, + {{0x000de1ccb3d8e2fa,0x0007927ebdcc0d1a,0x0002337815f56cdd,0x0000d85fffd1121b,0x00003cbd45e59c0c}, {0x0007f3a600093df9,0x0008803285131a3e,0x000bc6bc473d5036,0x000a13a8c656b44d,0x00000f99f5a3c8cd}}, + {{0x000e2b91357917d6,0x0004af49c788ab9d,0x0009b75be9a83bb4,0x000609521c19f260,0x00006e8679e9c4c9}, {0x0009644a604a9c50,0x0006a166441a0a62,0x000f865732bd6b62,0x0004a024589222df,0x00009ff82ef1d308}}, + {{0x000eb11759f3013a,0x000c301c5150e323,0x000fc70dfc2b0fa7,0x0005d3b88ecf6620,0x000062d12a272f04}, {0x000692973b38bb4e,0x000d47714e446b89,0x0004821687518ba7,0x000a53ba0fa24858,0x0000f49c5dc1b4cd}}, + {{0x00074d983ef0560e,0x00040d3c61a6ebd3,0x00049367c38c1271,0x000f0b2401895ccb,0x000001ef869f5737}, {0x000614a7234ff845,0x000dea374efd0e7d,0x000f6ee62c289cdf,0x0009ae62ef2db27b,0x000014784cee48aa}}, + {{0x000159129c7218f2,0x000a4b541372a190,0x000bd9f602675cae,0x0004cd6bce2b878e,0x00002512bc39576b}, {0x000dce0a8803d993,0x000c6cb44bb6fca3,0x000f6629ead7ed05,0x000912b0c7932084,0x00004002232bf471}}, + {{0x00001d2621033b58,0x0001f8fc3dd965c4,0x000ffb247e571eb2,0x000a0595cb93a225,0x00006a8adbe4947a}, {0x00051a6245eb6e91,0x000576eef743cb9c,0x00071f3cc875e4bd,0x000d32e4f4b68e10,0x0000cfc7a753fcc9}}, + {{0x0004b5ad8454309c,0x0006a96c32757c42,0x0002adc838288f2e,0x000629309a27d6c0,0x0000768fa5916f5e}, {0x000ffe6b0e8c2f5b,0x00052be31993a968,0x00095c2da86b50da,0x0002e92416e8bccf,0x0000ead84d4d2c31}}, + {{0x0004170fe1d6eaee,0x0000fc0d00121e46,0x000299ad5553d9d8,0x000da5c3949da0b4,0x00003391fdbfb09d}, {0x000007f4de911dcb,0x000013813852ad9b,0x00059598b370cba1,0x000b9b0b5de1bad6,0x00005d49170081f0}}, + {{0x0006b63bfed067e9,0x000222470ef49d4e,0x000e7714fcfc954f,0x0003504782951149,0x0000a36523156374}, {0x000bffff641c505c,0x000a9e6f797f68f4,0x0005b45bf19da0eb,0x00014b7ce6bed3d2,0x0000cf9f5296d91a}}, + {{0x0009f207b21eb218,0x00028586cffb7a0b,0x0008f3fbd0c3918c,0x00078201c70c1850,0x0000fb503e59c258}, {0x000cfbaddcbe4dc7,0x000f3120734c0d9c,0x000bd2bfeb7c7b4f,0x0001a34a1db6fa8d,0x00005381611bf031}}, + {{0x0000a263cc6eff32,0x0002da89d5f5188f,0x000998b48a9b7274,0x000a6a1ab7e090ce,0x0000c9c108427eed}, {0x000f32ca05971eb5,0x000453079a84fa1b,0x000b8e4604f377cc,0x000af86c83784d7c,0x00008f9d8ae61637}}, + {{0x0006bab37064a7ba,0x000afe0450e00b42,0x000d6875d28c4234,0x000c62f083b2f98b,0x00000c3d4377d759}, {0x00076976a45017b2,0x000880119d2b1ae5,0x0002e89d560ca989,0x00017efbe57b32f3,0x0000d217b1d4d05a}}, + {{0x0001246609a703d2,0x0008581f5ff0012b,0x000ed431681c4d33,0x000889e339cc9e61,0x0000c41d7af37992}, {0x00040e40ee5add10,0x00035ce326c02808,0x00011acb7ee358e6,0x000753b73e148f47,0x0000b41cc70c70ed}}, + {{0x0001e8a27fc5bb80,0x00023f9ce2773a00,0x000f5d4d0de3c75a,0x000ae0e67462e5ab,0x00005f356d1edad7}, {0x0005eb5f99aa27f3,0x000299fa1850b2d6,0x000ed719ea950e23,0x000f6d30fbc3a134,0x0000c607bc2d868a}}, + {{0x000e0dfc812789b9,0x000bf86fbb02a48d,0x0004c91b7d673e7b,0x0009d220bd69b769,0x00007aa28a6d3b5b}, {0x000c81d68bb3e89c,0x000a9675845e91f9,0x00021b13aa03e749,0x000266a5bef7793d,0x00004d522c8aac9d}}, + {{0x000314f0f6a1c7c8,0x0008a2a54dd0d604,0x00034a4a739d70d0,0x000841041cd0a4f0,0x00004a610e679a6e}, {0x0004259d51ad71d0,0x00042afded7b4144,0x000ec9b81308724e,0x000c0385af63d00e,0x000069d0017809f1}}, + {{0x000cc7faf31bc33c,0x000170b86ea12ac6,0x000118a6da045fa1,0x00064c601bb95001,0x00000823d360ce62}, {0x000d0907a77ed7bb,0x000c5e207baeca4a,0x00060d6267b9621f,0x0000becb62bef413,0x0000d67d9cdb9a0f}}, + {{0x000944561b2ae48d,0x0007606ca32aa2ce,0x000a0f576a73ae7e,0x0001f59d79acd4f0,0x0000f91e47274349}, {0x000f58ed0786fa06,0x00003b6fb73155cd,0x0008196d63d3af60,0x0004a1abf0728a90,0x0000cc301947a07d}}, + {{0x000173fcda66688d,0x000968f54078a044,0x000b892a6e4f3e8d,0x0000a6e9a8aa3f76,0x000003f2358c3edd}, {0x000c73ddba515a86,0x00031571066fc332,0x0009a52dd8494f4f,0x000596f40df54b23,0x000033c2a77c2737}}, + {{0x000ccc6a38469a7b,0x0000dfeabba0419f,0x00010b4aef255f07,0x0006f5fc0d85c473,0x0000844714199f30}, {0x00044a1800f79726,0x00003e748495b202,0x000fe708b728cd1d,0x00039fdb9df876a1,0x000044dfaeed2e69}}, + {{0x0009efb3b1befb52,0x000dd3db9ff2d119,0x000d54531b9666f3,0x000ef6ae6ecaa250,0x00000a5b3d55478d}, {0x00017d0cbe53c8f4,0x000f93025e9358c1,0x000f7b33ecb21d3e,0x0009e51f5b49200c,0x0000a7b0480bbb55}}, + {{0x000419c661687e70,0x000df62ce653f542,0x000907c00a126d6e,0x00080f9eed2326cd,0x0000422a8722b335}, {0x000534595c60a63b,0x0001ede5c24ec59f,0x00040fac2dc4f284,0x000b07e5a5d36fcf,0x000093bb56108a49}}, + {{0x000250012f4ef06f,0x0009f321814949f5,0x000d1cc017a50bad,0x0007969417282b08,0x000037ff4efb3e13}, {0x00043412190a4c29,0x0004b018dc035a37,0x0002185201cb14ca,0x00062453f92f5aeb,0x00006f2a7e6de00e}}, + {{0x000cc31c7ee87f99,0x0004ff0f8aafbabc,0x000a827098c656c9,0x000768469f364b3b,0x0000447f273ba78e}, {0x00012a02b0c76f80,0x000531f409e3b92c,0x0003182511cfed50,0x000d99f57fb201e9,0x000056a73dfa1e29}}, +}, +{ +/* digit=33 [{1,2,3,..,}]*([2^231]*G) */ + {{0x000a2dbe215c3b8b,0x000f884ce45689c6,0x0001d2f99ea9d0b4,0x000bd1cc1cb2174b,0x000007f8af7769d6}, {0x000eccb56ca3c064,0x000c39f4aea85da5,0x000dfcc2e6466598,0x000634cd8c935e85,0x00006ec507784fa1}}, + {{0x0009bc96b496a337,0x0001a1b2a3f800a5,0x000d4849519c3461,0x000db18fc2569c8b,0x0000b3cfcd94befa}, {0x000b4eb10b12d26e,0x000c1e97882a2059,0x00063f99dce2a002,0x000c447d77efe3aa,0x0000db216f26ed6a}}, + {{0x00018c63ece662c0,0x000a493d31f196f3,0x000906fc16932e12,0x00049057ef719d82,0x000018862ee36f81}, {0x00038809d700b8c4,0x0007c005edd01de2,0x000ff477e0932f9a,0x000e87c6433b3745,0x000003ad9c08d54a}}, + {{0x000c11886bc24c43,0x000e560aecce0485,0x000f9b2977cba2fd,0x000e25b0e545401b,0x000025a455e793cd}, {0x00031a786e57de70,0x0007942d10e0c90b,0x000728cff7ca8ade,0x000d9169618b125a,0x00006ddeb0245afa}}, + {{0x000527e462b3815e,0x000471040d6d3d81,0x0006a10bf201ce2e,0x00030111185978fa,0x000050eb91c129a9}, {0x000e282a5d067477,0x00069217051858a0,0x0004001b5ab39043,0x000546a05205fa47,0x000092822e494ea6}}, + {{0x0000adf6b5dfc7f2,0x00013e0797f2d1f2,0x000d16de2c2918ec,0x000bf5a4b2e613de,0x00009b8761499478}, {0x000f016f7b3256e4,0x0003de3e31def4dd,0x0009e833ac658d9e,0x0002df9cf95488f0,0x00007b7761d27f55}}, + {{0x0005841c4e740ce0,0x000b177b99bc2a6d,0x000904ce22809135,0x00082f03a03fc8cf,0x0000705c0bf36b5b}, {0x000056724d3e873d,0x000a122406826f04,0x000e68bc339873d5,0x000fe7ba392091ad,0x00008baee7844c64}}, + {{0x000929675be6922d,0x0001213a70da1b6f,0x0009a47bf6932638,0x000303b2b11e85f7,0x000061c91b9a2552}, {0x000f571053bef378,0x0008b2051d390a9a,0x0007f02ef5fb0b6e,0x00041047f4682ca1,0x00009401362dc590}}, + {{0x0007de12cad37a4f,0x00067f0d1f0a5333,0x000e96610c120cd7,0x0006283c745aaf2c,0x0000076bfca61a10}, {0x000798e91fe1dac9,0x0001ad2dd163c294,0x000e1f0a0c8c6588,0x000935de3e18d763,0x0000ba965532ca62}}, + {{0x0007623440b9b877,0x000a956d4db76d55,0x00020f4c8385ebbf,0x000d33d8735cdb8e,0x000016f0b0a75dfe}, {0x00036c0ba0e7092d,0x000d6dfad54aad69,0x00060683455d3376,0x0007bf127965ffcb,0x0000681b61bb1f63}}, + {{0x0009fcb83e9c7da1,0x000095ad4e66dedd,0x000319f0c0213304,0x000440bc0916b195,0x0000b5e953298188}, {0x0004bdc725dd35fc,0x0002eb60236de83f,0x000f3212cba2f5b6,0x0006b84c9c629414,0x000096bd8d34a8c1}}, + {{0x0004d6dc80f87d6a,0x000f7d8a2163bc94,0x000ceda80be2312d,0x000b2aa43026be75,0x00002edd166aede9}, {0x000c606ca8c0666c,0x00010c2bcbd751bc,0x000382e1aeb1ed71,0x000c659561279121,0x000056fe8e73cf6c}}, + {{0x000adbcbc1c3b15f,0x00046039a4313266,0x0002f2dea642ad5a,0x0007adadcfbaf904,0x00007547c5c21508}, {0x00015c16ec80761e,0x0003fa9e8435733a,0x000d36a8d8a3a115,0x000a4ddd0a6919aa,0x00009e7377d0e427}}, + {{0x0006e39e2d28ea84,0x000e750985b22c70,0x00029d6b3707d572,0x0000eff5dcca6438,0x0000aefa25e7768d}, {0x00017dff52661252,0x0005251d4caff7af,0x000902575f409232,0x000c7c7a8e670e6c,0x00005774dda3abf1}}, + {{0x00001285e5eb464b,0x000cecbc4c7510fd,0x00036c854df0124e,0x0000a49a1c719cf6,0x0000cc1c52a5ebe0}, {0x00070df7350f9229,0x0001991f61845b72,0x000192d67dac63a8,0x000be321af84188b,0x0000748d9575b564}}, + {{0x000b281c9947edae,0x000fa609d25cf20c,0x000adaa68d459e53,0x000b86b0a79588cb,0x000097fec12d5258}, {0x000b88cb27d7e1dc,0x00050c5b8023206c,0x0006b92572ba3d39,0x000d3a3da394ded9,0x000058c9b408ddbc}}, + {{0x0005a17512d500c9,0x000bf90baf002f44,0x00044b074849f6d7,0x0009a667b85738a4,0x00001d723bfeecaf}, {0x00019a4f16591f2b,0x0002d5b54c67aba9,0x0003cb20eafab933,0x00052d84b720e282,0x000036c1b31c4a53}}, + {{0x000dc48359ae88b3,0x00095b94925a7673,0x000d28c38c7da6d7,0x000449b9611f43d1,0x0000507e76bb8c39}, {0x000a4109b143d327,0x00085897b4d64670,0x000ec856db407a04,0x000c3391b35a7c2b,0x00004729f04e48e2}}, + {{0x0000e287d444576f,0x000fa46c0fcedfc1,0x000c4bc495541641,0x000dc4c61a898da2,0x0000c49474474950}, {0x0005d34a86e99ff6,0x000dde84f0eb279c,0x0008b517448eb4a2,0x00020f168c48d9af,0x0000d2e2947e6a6c}}, + {{0x000d4b7fc5ddff94,0x0008b8cd5d76c4ee,0x000e6ec7533c62e9,0x000b64d05167db0e,0x0000723b4547dadf}, {0x0003255992390795,0x000cf88d2ea48646,0x0007f30d8f37975a,0x00001460943feac1,0x0000681ac9cf176a}}, + {{0x000b8b6daae521b7,0x000adbdf2be35556,0x000f2c0e8441695d,0x00052433bb1bc3fe,0x0000a6eeb8381b5f}, {0x0008b6d0a7d65ee1,0x0008d0ed4f2aa649,0x0009d15a7352ac47,0x0008209e26a67a00,0x0000eabbbcca5492}}, + {{0x000ce07d1a83db8c,0x0001217601ca6e80,0x000bf1f026fe55be,0x00067c6a6a9b77f3,0x00002da4da482151}, {0x00050ce0660bb9c8,0x000c647dbdd30a3f,0x0000ce6acc0badf2,0x000af2afe2cb4eb2,0x0000df11e844ac4c}}, + {{0x000bcbea50bf7b2c,0x000d6fa5e1ea7e76,0x0005104e4d183277,0x0003530de5287e95,0x000061dbeae917cc}, {0x000361797e3c36a8,0x0006a4c11975d8d7,0x00056ffe587eac28,0x000ec4cf96fe62e6,0x0000ff2a60a5ece8}}, + {{0x0005b7d6b5c17565,0x000e725336dfb23f,0x000f699eb5967d95,0x0001d71cc4a1282c,0x00006f2d1e5dbace}, {0x000cc2260eba8909,0x000a041a0642f2b6,0x0009abfc6cbfaebf,0x000997d9347b4051,0x00006c695a44b98a}}, + {{0x0001ae8291d465ef,0x000694bf89326d90,0x0001c482f1ffe9f3,0x000d2382bad4525e,0x0000168c52db0bcd}, {0x0006017568b375d4,0x00089290b50e580a,0x000f160a15743a92,0x0005551201b0040b,0x0000581e3cdcd77d}}, + {{0x000874ca4cd68d8e,0x000f8c4484600f4f,0x0005c73324d85176,0x000fecbac7c97f28,0x000079aa93211324}, {0x00075824d0274253,0x00064d8b475d6b62,0x000eaa57375d9aa1,0x0000f362be914bdd,0x00004995d6eeabfd}}, + {{0x0009820f41846ba3,0x0000604085981174,0x000978a94fd1bcdf,0x000d0ba2fed0a907,0x0000ba1d2eda2efd}, {0x0008512656b5739f,0x000594918c39e3e4,0x0000b6224e9c896a,0x000d5bbb1875d792,0x0000b93012187315}}, + {{0x00019ed5ba8931b4,0x0005acd90608de3c,0x000b33a89ff0f3a9,0x00089e41298c1df6,0x00000292d30c3fde}, {0x000d7df4a273bfe2,0x000087b011c26348,0x000a2dc24b8b9f1f,0x0000ad39d9d45852,0x000067daaf3663ad}}, + {{0x000dd476f0bcde8e,0x00074f1aef494e4f,0x0004bfcbf6a3568b,0x0004f71520bf6fc8,0x00000306160f678b}, {0x000e43f9114c874a,0x0006a66a6723e3a0,0x000fa916c94626c1,0x000e1a4c6dbb2fcb,0x0000a2a7851b6164}}, + {{0x000f6c17b91cb2fb,0x000022d25723d046,0x000c4a5d56108b74,0x000423bab6def6ce,0x0000c2cabcf84f05}, {0x0009b3aeef06e341,0x00032ae65511bd33,0x0009815f724c639f,0x00015a5666c8aa1e,0x00004c097c5786e0}}, + {{0x000b7ddec96a31f1,0x000bb6126e7d0171,0x0003107612ab4881,0x000f991937b21ce8,0x0000c2f1836cf5e4}, {0x000f324d669b052c,0x000bbf0d0024898d,0x000fedf68f963603,0x000e5446be060625,0x00008eaa3a89c4b0}}, + {{0x0003578addae3db2,0x0001256b65bb4a56,0x000f89bb28f673ae,0x000ce0f3897587f4,0x0000e7b5627e000b}, {0x000373d4ebc646ed,0x000c26c01b67d1af,0x00046e755320c491,0x000df2ed183b1a53,0x00003dc80714e3ef}}, + {{0x0001d181707854b5,0x000e045ed6440d70,0x0008141226b65beb,0x0005fac44ea8ce1b,0x00004d31afc2b255}, {0x0000f1d4fd98ed23,0x0000361122a75ad2,0x000dba8c53597134,0x000fd9b5173a0d9d,0x00005c6b22beb557}}, + {{0x0002ee43acde4fa2,0x0003572b4de2188c,0x0009e491b7321151,0x000935ef340f8681,0x00003ae38901b2ff}, {0x0001fe8fde235367,0x0003c3ac4d9e99a9,0x0002c2b7c3253510,0x000130bcc3a87d5a,0x000018cf5dc1d05b}}, + {{0x000b0ea388337482,0x0005bc0ab3d81a29,0x000f26100c68ffe3,0x000c3d24c4d4108f,0x0000f14a32ccd1dd}, {0x0000a315097789d0,0x000b428d4c71c703,0x000a782fabac5dc1,0x00014d3bba4799bd,0x0000e5c67c1d3f71}}, + {{0x000dee9bee66b26b,0x00040993141604b7,0x000f8818745348d7,0x000064a5cf2b66d8,0x000035fa570e7a60}, {0x000e3b2e90a9f6a4,0x000a93d618844b8b,0x000e1533c3136043,0x0004b406fc07f2f6,0x0000e68110e4d8d2}}, + {{0x0009c06a197144e0,0x000a0ebd90e8998b,0x0004637e982d59c0,0x000346ad1dcaf45b,0x000059c29fb15ffe}, {0x000e68bd0de11ce1,0x0000ef9123f1e4ad,0x000809e2e7028807,0x0001a38b44fb792e,0x000021fdeb0bf5a4}}, + {{0x000b525dfbbe18f4,0x0006ce6bebd7328a,0x0005014218d893eb,0x0007f27415906d1b,0x0000683c30795a82}, {0x0003859154db22e4,0x0003c459a6b28d30,0x000d54f8a9fdddf8,0x000441f5e0dcb8f5,0x0000b323984a4542}}, + {{0x00020890ea27494a,0x000e1e35ace9abf1,0x0005949a7637aefb,0x00092a65ed6aed2e,0x00009fb6d9b1e31c}, {0x000c850fe43da55b,0x000c7a2aebb47154,0x0005a1f29c49139d,0x000f8c8a3b6609e8,0x0000c0e447c73747}}, + {{0x0003b83c899e16c9,0x0007290a4c485b88,0x0005c11ac3264056,0x000b31c23fdf0557,0x0000d6294d704452}, {0x0005adda6fd01b3a,0x000ed638d76cebf3,0x000bc2a591640d40,0x00090bcb6beb8873,0x00005774079636cf}}, + {{0x000d07a4df05112a,0x000c75ef10b3ed9e,0x00000dc454558b1b,0x00068ee57b1c4e11,0x0000c05303af0df1}, {0x000ff70dbf770c49,0x00078abb8add6239,0x00051783cf1da24a,0x00085717000ea909,0x000083c07443aa20}}, + {{0x000e669c9aa38ff1,0x000cdf9b6663ec67,0x000fbaf822c76f14,0x000d8f2e05f459fa,0x000081bfa0e72146}, {0x00031960fccc9403,0x000079ddbab69572,0x000c0f236afff64a,0x000c6b8a2dc2b77e,0x0000cd9b9db0072c}}, + {{0x000f50005e38e681,0x00011d2a53bfce83,0x000d3127de4fb9f7,0x000a7389040d2691,0x000090991b1df4f9}, {0x000f4d487fb49c70,0x000acbf3cd2d4b92,0x0004a8e9f3453a0d,0x00056284948bf480,0x0000bf9b42b8763c}}, + {{0x00085bea7295b89f,0x00032c67fdbe5c4a,0x000dfa99ff9b5214,0x0003dcf7dd419d4b,0x000053b1b1f00c14}, {0x000fc48e64a06587,0x000c86e4c0bd1189,0x000f07b904597445,0x00012361c88b11d0,0x0000de6046f7d84d}}, + {{0x00087bbacc585b5c,0x00054110d0cc505c,0x000cc9394ff5fa6b,0x000013753c1362a9,0x0000f747b69989a6}, {0x0001acdff683da86,0x00085c9ade093e40,0x0009346cc256f729,0x0003da9907d05802,0x000068d87f52e4e5}}, + {{0x00072320892f7939,0x000ecfb65e03e668,0x00005b60e8867af8,0x0006db6855960ac2,0x00007cfe82946f8d}, {0x000126504e895a59,0x00082f9ab1ae37c7,0x0003475b8072a97d,0x0009b271cf682e37,0x0000a001e427da0c}}, + {{0x000f56aa1c2ac6a2,0x000b0056bb5e8607,0x000840d5e7b5a2f6,0x0002a8575fce01b3,0x0000bd0d02a2a11f}, {0x00020acf5e461b5d,0x000143f8b7882cb9,0x0005684f429c8f84,0x000b43261bec02c9,0x0000976e4c74bcf7}}, + {{0x0008818531ad28e4,0x0004e2d377207b87,0x0004885027f26899,0x000503f289ead51e,0x000098cca8ee68f8}, {0x000c970b5c5d77dc,0x000080459981f27b,0x000b87fa1544bbcc,0x00070d2411cca590,0x000054ea81cf6071}}, + {{0x000086e61ca59dc9,0x00021cd8c326fa3c,0x000811dadebe13e0,0x00041b5d83482a0d,0x0000a49369b21466}, {0x000c7cd8304d967f,0x000e9364df0d6130,0x000343b0e27f449a,0x000d17ab76d37fee,0x00008a1d0ed05ee5}}, + {{0x00046cadc6205653,0x000ab65343bf3181,0x000556549569c932,0x0006bd0af34c44f4,0x0000ee209046d270}, {0x0000c0ef40c6247e,0x000dedf91b009463,0x000bb38be3f102c0,0x000064d340ea43f7,0x0000e2d7c507278a}}, + {{0x0001fc4894efce0e,0x000d16f705c791bb,0x00001c6f5dcb8966,0x000e5e4eff50cb1f,0x000096a8482ad3cb}, {0x000dec26d0cfd830,0x0003040d53e317a4,0x0007f8e26336612c,0x000559bd95bdd1d6,0x0000ccd1e540626e}}, + {{0x00068bdee681a9fd,0x00019176d44b5bc5,0x00088a36d1aaa6b0,0x000c7bf9e56290f9,0x0000b5d955ba2779}, {0x00025fcd134d4965,0x0005ff8f9c5b8014,0x00085dfc847e63e2,0x0001a0634eecfe39,0x00008b0e4909de31}}, + {{0x000397d6afe3edfb,0x000ead213cf0c484,0x000fe129db20b9ba,0x0004aa03eebcca16,0x0000ac8b193bcbab}, {0x000d00ec766789a2,0x00007b641c6280af,0x00012d36a671a1b6,0x000788d44e1010d6,0x0000e906a8a2cc4f}}, + {{0x00085346f1857b14,0x0003410a4089af78,0x000c2398d5cc5098,0x000b93ca8a5f67b0,0x00004695f3af907d}, {0x000f016bdb075823,0x00067ed27633c156,0x000a99381e81d34c,0x000d88bd4282e4c4,0x00008536f5808ba6}}, + {{0x00099ab2afcd854b,0x0007d8eda94411de,0x000c8a192d747cf5,0x000c2d246295bece,0x00001424f4c40f48}, {0x0001c25b3f186f40,0x0003eb32b7394006,0x000ddbfc3b2985f6,0x000d7fda0dd1d8fa,0x00009df5df39c2fc}}, + {{0x000736cb9995a1c8,0x0003f161f3b15ad2,0x00016b96e4f367b2,0x000c18470c49cfa2,0x00001b9d55b9d130}, {0x0005a5f78a9f0c67,0x00021aa433e2085d,0x0000dcf549740986,0x000faed0c9af8ba4,0x00009380b92d46a9}}, + {{0x0002c88c54018551,0x00029c0673e5a8f4,0x00054155f79a8500,0x0007f49c76fa0d73,0x0000e0e7821cfcaf}, {0x000a0f6255d3014f,0x0001c980f9fa8f28,0x000cc0b0ed7bc620,0x0000f657b694eb76,0x00003dc3e7fd436b}}, + {{0x000900f0e2ab22a4,0x0007485db521beeb,0x000e657e4f9fc7b6,0x000645a1ee59ad38,0x00005db32d0f9721}, {0x000237fe16ed3e0e,0x000bbb7178cab7d5,0x0001c17f2278f133,0x000c4cba85c30874,0x00007993168c23c7}}, + {{0x00019588e7f16445,0x0007acc30bbdcc18,0x0000d00fb3765dae,0x000e56c47a4fe57d,0x0000540123b0db2d}, {0x00027a35c65a51ed,0x000209b84b2313a2,0x0007634784e94bf1,0x0001a877d76a3143,0x0000a49efebe4d8e}}, + {{0x000c9dbf562fa402,0x00091c7548693347,0x0001d08b33389499,0x00003924b7a2ed2c,0x000073ffa2df5839}, {0x0004bddada7df426,0x0007a35d8ec44b5a,0x000d0629a0a53add,0x000c22216b46cf5c,0x0000156ae4a410f7}}, + {{0x000684c43a0908b4,0x0008578d18268934,0x0008e8668505170f,0x000d80851c09a959,0x000081f6e0c2f121}, {0x000e6b0e93141606,0x0003960731d37a3f,0x000fc8e4b7861d75,0x000aec6eb173ec4d,0x0000839de40cf2b4}}, + {{0x0009da66960a1d07,0x00027d771fe97d30,0x000fac3ad619dafb,0x000baf9f688aba90,0x0000f8d73eab08be}, {0x0004a8a35306c347,0x0002ece26a385f6e,0x0005297e499a6cb6,0x0000e956434c7490,0x0000f8fac1dfe93b}}, + {{0x0000533de36faba0,0x00016d1b717153e6,0x000e7b6a46cd71d1,0x000b0d8454ddf26c,0x0000d2dfeda7af6e}, {0x000a49d8f229e942,0x000aeebbb5a51c05,0x00026ea87b89faf8,0x00040f65455941df,0x0000270c9e42b6c2}}, + {{0x000fccb792331f1f,0x000bbd5f4310303e,0x0005487a9aa841df,0x000687415985039d,0x00000722f292f10a}, {0x0002b63fa69dbac1,0x00055c77189d6d9a,0x0001b8b7eb40e9fd,0x0007b2ad14152df7,0x000026e00b8e2fe4}}, +}, +{ +/* digit=34 [{1,2,3,..,}]*([2^238]*G) */ + {{0x000164b77ff9c88f,0x000a2ef7eb4901c8,0x0004be8651e6510a,0x0003146b0427bac9,0x0000014ba0639f38}, {0x000079d912a4b87c,0x00053718addb5b8b,0x0009350d61f10a85,0x0008cd383ef5b3aa,0x0000b3050be022e5}}, + {{0x0004372d2fb6aded,0x000801214c59b7ee,0x0009a805676222c1,0x000393e75f878b61,0x0000bc0e9d60d556}, {0x000dcc68fb3aa122,0x0008198ce83ad58a,0x000c586f80dd8a70,0x000608da5fa2a4de,0x00005c1fbffecc79}}, + {{0x0000cd3410794975,0x00002f17f97e1c7c,0x000edb80180e62e3,0x000677d857c7cf22,0x00003c5dc338930a}, {0x000919ff266e4f08,0x000d7ce8b10eb218,0x000a415a98781060,0x00067eb9c65da11c,0x00000a82892a18eb}}, + {{0x000e99ea38b2555e,0x000c2d0f78b90aed,0x000f899f908f42d0,0x00045b85d2246e6f,0x00006affd17a8110}, {0x0007243c95adc81b,0x0005ff1b55034f43,0x00020858fc587c33,0x0001203202a22342,0x000031c328f6ed23}}, + {{0x00094131d1a510a8,0x000fb492e59d9b18,0x000d46eeacaad4c2,0x0001e0f8cfbc62bf,0x00002d9b92bdc756}, {0x00054b85d74c27e5,0x0007ec6f99df2367,0x000ce9d06698647c,0x00058b504025de05,0x00006aaf1cab6c68}}, + {{0x000994dd11fe6a9d,0x0008eba83bfa0e00,0x0001b31f14d4500d,0x00041e927422e49b,0x00000c3d5fda89be}, {0x000bfc9eaa562805,0x0000baca1c2c7a32,0x0000a870fecfd05a,0x000e1425337b4e23,0x0000170a512337a8}}, + {{0x000ce57b66ce8b33,0x00017e3f3e322882,0x000fd4d1b4d897aa,0x000a30a6df75816f,0x00007c5429d1c726}, {0x00001a389212e06f,0x0008462c37e1fc25,0x000bf5f267708a70,0x000088314bab6b3b,0x00003e8cf2215d7b}}, + {{0x0001ca59294b3b6f,0x0008266971b412b0,0x0003fc23a009e882,0x00035452a7149569,0x00005836d205ffc3}, {0x00041dbb019e639c,0x000004f228ef2720,0x000c74f69a1c8850,0x0009110f82baac62,0x00006c6dc96e97f4}}, + {{0x000cebdedd438eb2,0x00067491a855ec0d,0x000b83f8e144f459,0x000c0ddacb21f3c6,0x000017a832750eba}, {0x0002281cf11b5e08,0x000c27889bbd621d,0x0000eb5a495a0f12,0x0004fca13a692b6a,0x00009360a8e55b15}}, + {{0x000c8e9a166a355e,0x00013d1882ac523b,0x000719f73df1639b,0x000eec37a772fb6a,0x00000b5f4f23d476}, {0x000f7e07224ee886,0x00021d0a2a679ee5,0x00027786b2648c3d,0x00080ad189601c14,0x00005554b996f704}}, + {{0x00085c70ed8b7a07,0x00080ff5ac69721f,0x000229dbea53ae19,0x000124751f671465,0x000026c04728ff80}, {0x00077fee956c748e,0x0005e60b02d0294d,0x000be3040a2ee31b,0x000b41001c513f66,0x0000124ec995bdb9}}, + {{0x0002a05eef749b88,0x000bb345f0296e45,0x000ca0decb1b42ac,0x000a45c34c8832a2,0x00000ad9447c3da3}, {0x000bd418f40be07d,0x0004656d8d611385,0x000b4a01a333c0e0,0x0005b7da85289120,0x0000d53f63e89842}}, + {{0x000b1030f7484975,0x00072638cc84ef88,0x000da3c65c73ce22,0x000f0fcae17f1301,0x00006f3f5a252d97}, {0x000c09e996d5598f,0x000a57310512997d,0x0002aa7f9e694253,0x000b70e1bfdb23ac,0x0000064f9d6804f2}}, + {{0x000e6573eacaea0b,0x000e59b058bd265c,0x00018847df779bb5,0x000c3b678c0d39ce,0x0000ca9ee0828efd}, {0x000a29bc7409894f,0x000c8845e22607a3,0x000bdea795bbeea4,0x00059242b80706da,0x00007c709434bcc0}}, + {{0x0008ffb240e3f455,0x0008556a6fe6a748,0x0003f5486e2d2ded,0x00044844798dbb44,0x000001050e8f96eb}, {0x0002f32ccee8cca7,0x0005765b412f7202,0x000a163954aedf33,0x0000057cca4d0d83,0x0000e78e9b71d3f0}}, + {{0x000ffd0f38bd9188,0x0009b09114aa4975,0x000b8b6035798f34,0x000fb588ff0f5489,0x0000206e2219ddcb}, {0x000fcf8f821d742a,0x000dc1fbd6f34da9,0x000702c041ed9195,0x0009dde18d25563a,0x0000b89d7575171b}}, + {{0x00061fbbe6d6db62,0x0006e63bc763d31c,0x000286d321f07966,0x000195bc5e14c35c,0x00001600cfa9dd08}, {0x000c3c815ed8598f,0x0006fed767ed31a9,0x000fa58d2625008e,0x000a2a33e8005f67,0x0000a1b81d42e593}}, + {{0x000e39db02b697a5,0x00078d8dcf8a266d,0x000715a9abbdf72f,0x000d03033cd5e0cf,0x00003393e3d87890}, {0x000b10a596c6ff72,0x000ea2c1ffb438b0,0x0000785544e805be,0x0000a95e6d16d794,0x00004806b6418ed2}}, + {{0x0003c28b02565d5e,0x0007d5fa9a84ed33,0x00087b17db552969,0x0007d18d709db6b2,0x0000409c35a8857e}, {0x0000777198594e1a,0x00013ba1996d94c2,0x0006d6c719c95731,0x000a209aa81eefbe,0x00006ea2d1d24a2a}}, + {{0x0000e3d894cee1e8,0x000477071278725a,0x000e8d65d9c5ec97,0x000993f9c900d4bd,0x00009bf052b7d32a}, {0x000ac8b02844a89b,0x000f631c9d556098,0x000ad2c6940519ec,0x00089816ac904985,0x0000c65a021584cb}}, + {{0x00047d3f3cd9f24a,0x0001c7f8a5e5779c,0x000bbab07ed17207,0x0004e1d7fd448a70,0x000021c3bbf36482}, {0x000b4d80d3b11d25,0x0001b97fcb26f826,0x000f528f4f86db6f,0x0003d789800557ff,0x0000663c86f8f635}}, + {{0x0009ee695e5a5075,0x000b919d6729edaf,0x000b61dd4a9723a0,0x000611b1586f96c3,0x00008566b6eac708}, {0x00090af73a830815,0x000615254047d580,0x0007aef29bec2d5a,0x00092f6291bc2b1e,0x0000eabbda6cf8ef}}, + {{0x0007c0801e864ec4,0x00015d26f447ee51,0x000264c5b394057a,0x000ab54aad486936,0x00001a0403c8e25f}, {0x000f7a8a4659ea6a,0x0002d1bb980af413,0x0003681ec617ee00,0x000b355725932b75,0x000004af07f35eac}}, + {{0x00090a00a5ea679e,0x00042580d3b41835,0x000bbd5c4dea2f9c,0x0006aee218b68b26,0x0000c25f328cab12}, {0x00064ebe2ea67e19,0x000017ca33af5ff5,0x000e8443bc7fab12,0x000fcb6ed74b4cb1,0x00005ea985061107}}, + {{0x000c21ef95df3779,0x0002c982d5270ba1,0x000ba11436031d1f,0x000a1a8a0967f9df,0x0000ae6a5eba6c26}, {0x00012ea2c092ccc9,0x0004117991571e9b,0x0004fed8c28f898c,0x000f9c7d71f312d0,0x000041fa4fc14344}}, + {{0x0008d9030a2bad30,0x00069b5a65848afc,0x000b84311cbe35b8,0x00058c03c5566460,0x00008cb2a3f860b6}, {0x000df7536be38e1b,0x0006d87e7fa21eb3,0x00001ad6290d1f0c,0x000eb810bf6f5cf1,0x00003208e36ab1d3}}, + {{0x000df5d231c91e4c,0x0001b04babfe5cd7,0x000ef58bbdc77085,0x0002bc2357ac532e,0x0000b5c3bbcfa9b1}, {0x0004ae41da37806e,0x000d71c7d7131ce2,0x00003eb2a144c5bc,0x000449e6a7caabfb,0x00005ca49bed40b1}}, + {{0x0003b89bd18f3d12,0x00016f2316cbf28d,0x000482896f8e6c7c,0x000e778e62adc34d,0x00008bddfc697813}, {0x00008eed3e3e9d68,0x0002fe9f8a3d153c,0x000d994921af5ead,0x000a79c09952b705,0x000069094582de86}}, + {{0x000602c441b88cd0,0x000bcc20f7e71964,0x000ececa70c2a3c9,0x000f16fa225449ec,0x00008d5f586ad324}, {0x0001d115f0909ea3,0x000fc97c961679ce,0x0004d1588ead7203,0x000773fdc146623e,0x000053a8ea43b1f0}}, + {{0x0009c4809a0bba36,0x00009d9a25c286c4,0x000d5a52060f0403,0x000cff7d9efe137c,0x00009b20f1c2576f}, {0x00078ce06fa3e86d,0x000c77f529c06f14,0x000c1aad527c7769,0x000a54cada78329b,0x0000cfdc46bf1bdc}}, + {{0x00010cd2058985aa,0x000552e40f6a34b4,0x0003e1a2087169d6,0x000feeaa1773f3ab,0x0000a8f013b7117a}, {0x00075210df843d49,0x00035b92e42bd467,0x0006eaf3ecce3434,0x00067ed3af118378,0x000053710064d275}}, + {{0x000b1bba80892cbc,0x000c43c116286ff5,0x0000a537bd1a5cb1,0x0004dd41b6297424,0x0000c9e812b1f69e}, {0x000fb4b5fc8601f1,0x00025def2d88f167,0x000097bead9b6112,0x000f8c0dec297878,0x0000a5bfd4cccee3}}, + {{0x000058b90fa84dff,0x000b95e24fa1bb46,0x000c99c141fa4b7f,0x00021f36fc4b15c5,0x000072ede8886dd4}, {0x000db218df104f8a,0x000d8929fa061e56,0x00031369dba8acfc,0x000139ca445c97ab,0x0000aa7da404f985}}, + {{0x000459fd466786f7,0x0000835940e6a840,0x000323c0080d2d9b,0x00021bceb6682b6e,0x00000ea0e0da968b}, {0x000b8e9e1c90e07a,0x00000efe4121cbbe,0x0000849c5d166c93,0x00035bdf729b9cad,0x000020e1465218fc}}, + {{0x00062a0d6f379255,0x000b70dda2ca99e5,0x000ecaa30b5d30e5,0x000a688e3a88f1fc,0x00004f71443553af}, {0x000916b0bbc4b3da,0x000778f700e9314c,0x0008470ccc4bf1a1,0x0005e5a395ebe872,0x0000286cde27e46b}}, + {{0x000f5cdfe6b7d846,0x00082cb76457a1e3,0x000f3b9f74697b1a,0x0004560f07699d92,0x000028a5e6885a15}, {0x000742ef4c2f1f4d,0x000e56fb6d72c4ed,0x0008faf1ba1dca49,0x000ca351c97d7358,0x000087771442b909}}, + {{0x000d00ef6e81de3d,0x0006e2eef62dd862,0x00034f24d63d21af,0x000c7950c94d5766,0x0000a5a468b10066}, {0x0006314bb09920b7,0x00046433ceeafbe0,0x000590fbbe003195,0x000e38446743c58a,0x000060b8843b0644}}, + {{0x000c8a2f33ef7892,0x000014bcb8cc69d1,0x0002dc33430b7a34,0x00007b190c3a3959,0x00003317543deedf}, {0x0009efc31735b604,0x000fda1ad6889634,0x00021830c3784c8e,0x0007f7a98ea1604d,0x0000198b9ed3ee3d}}, + {{0x000802942dc95293,0x0006c607840b614b,0x0007638241011618,0x0001a891626667c7,0x000070fae3ebdba7}, {0x000e767cf31f42c5,0x00037886da27ff5b,0x00092f5eedb3bfca,0x00092071df531c71,0x0000a96add241b4d}}, + {{0x0003414c0c83975e,0x000af2aeddc23ead,0x0004d9fda7d76f8e,0x000ff1110efd9e98,0x0000f15023276067}, {0x000a0520d36f0d27,0x00065322372861ad,0x00021d9344f19d56,0x000a4fab8999bd58,0x00002a7b9e9d02fa}}, + {{0x000e6f66be15bbbf,0x000516ab8735bf29,0x0004d4bebda1a8ad,0x000fa68f061186d8,0x000009f9261ec025}, {0x000668b5b3fc0a45,0x0004af0a2c0ff9a9,0x000282c2bc1a8bb3,0x000ddb6c3b1e0b34,0x0000492f782c6d6c}}, + {{0x00069b4c267cd575,0x000f0f8ff694e887,0x0005b7442ef62630,0x000ae31d653545b0,0x0000bc15dfb1c514}, {0x00074dc7419111ed,0x0005eb2728c3a9f2,0x00099a7d7ad03866,0x000fa05d8bfc5cfb,0x0000c82b07903c82}}, + {{0x0003de54e014c472,0x000560e61eab8f72,0x000f8cf303460a19,0x000c58bf40488c19,0x00002ba1ddf14e5f}, {0x000aed63d9564f0b,0x00077c5ee525ae10,0x0005271ab84a9fdf,0x000b311db9987806,0x0000c50919caad39}}, + {{0x0006e874c69e8a6d,0x00032ff1ff6a3eff,0x000e47e1fe98ab13,0x0008fe8b0aab1917,0x0000a9ac0b6b9835}, {0x0004bc04f8bcb879,0x00083e021fbaa981,0x00053100e36bad61,0x00027f3c2bad3e08,0x0000a510218c5f1c}}, + {{0x00079c291c3fac17,0x000e406762ecb91a,0x00013af2e1a7b0db,0x000eba4e6ce29057,0x000053a167cb4639}, {0x000c07bdeddcb8a5,0x00067183cdd67c61,0x000128f146849aa2,0x00077df6fb0823f4,0x00000acf75062e13}}, + {{0x0003ab8aa1b413a0,0x000ad9f830d7fd57,0x000b78539eb24027,0x000bf1c67bd704a6,0x0000c3195072ee6a}, {0x000bf133f8b12d87,0x000380475ed535cc,0x000990604c95a5f7,0x000535334f567cae,0x00000582b15227a5}}, + {{0x000037febb43ed1f,0x0005fbda9e9827e0,0x000aa2514e69769a,0x000cd35866ce6da9,0x000060ec889f5458}, {0x000a6da95e75646d,0x0006670efd9bf0bf,0x00024a9dc8b0395e,0x000ea954fc07a1ed,0x0000f86eef9860f5}}, + {{0x00072012ca58fbc7,0x000d4c78a8cd5b1b,0x00068b7af601e664,0x000a63128123fc55,0x00000084c070ef02}, {0x0005a8e658751508,0x000195ae0550346b,0x000d111eeefc4be2,0x000fce20fe4c6f46,0x00003a287fc76838}}, + {{0x000be4e9312c54eb,0x000f0cda2786e630,0x000d6ceae55abd5a,0x00091e346e84f200,0x000022eede6ca985}, {0x000356024525d0aa,0x00045586290c118a,0x0005c6e264b2b3b4,0x0005742743dac9f5,0x00009827e4a6a765}}, + {{0x0002a6dd9cfb4cd8,0x000f94e215cb934e,0x0007b3210b4858a1,0x000417a6b0a4b56f,0x0000befcc636ca75}, {0x00004b44b52cd3b7,0x000e7d15df655d8e,0x000f5c7d81066051,0x0008319bf3c2bb26,0x00001fd03c43aee3}}, + {{0x000a7603cb34c2dc,0x0003d057be5ae4c3,0x0002a595a6d0f925,0x000e18e4a3e6cf15,0x0000bdb8d991f000}, {0x0009ebe420d29fb1,0x000a2deac279fefc,0x000be608d12593b8,0x000c2f8c1e1867f9,0x0000eb5a9f81fbda}}, + {{0x000421680a0ed616,0x00052f2f3c60e7e7,0x000419cfa67feadd,0x00070817ed6225a4,0x0000fc0a15bd1cf9}, {0x00005b2338e5c066,0x0003160bddbc9130,0x000287049b60afe7,0x000489555a8336e4,0x0000959d1b6599b6}}, + {{0x000420ce0721159a,0x000f3b431364134f,0x000a77054c77e7e2,0x000491139bf22e1c,0x0000068bc7711297}, {0x000e3f9245e5d473,0x00083b6ccdc556ac,0x000a7a2b057ab72b,0x000b7e04442765dd,0x00008a61f6aeb745}}, + {{0x000e96dd576a73a9,0x00026d0897ab34e8,0x000fe2f8ff6c7c7e,0x000a5a99c1721c5b,0x0000d26a77a616ad}, {0x000b65c58aa4fc27,0x0003d809efc1048e,0x0006fac2acd58b42,0x0006717ad71cac4a,0x0000645d4fc1ffd4}}, + {{0x000d73a164aaf5d6,0x00013d6daf2c817e,0x00075d36a7d62437,0x000d90df8c94fad6,0x000026a8207e0f81}, {0x000826b934843b84,0x0008b84eeafc1dd4,0x000dd85215de1db7,0x000128812417e355,0x0000ae2d30deaad5}}, + {{0x00051dada3211cde,0x000c64018309c929,0x00044e2d5c6376e3,0x000d9d80ccba2315,0x000025f7a4a621f6}, {0x00027257fd00e719,0x000b2f36f2fefad5,0x00022f938ceefce9,0x000665f7ca6333cd,0x000077ef898fcf04}}, + {{0x00081bfe708b52ee,0x000c42359c865bd7,0x000be20854eefe76,0x000e15fd0ae7807d,0x0000c6305412aa5d}, {0x0007eb6ec1300871,0x0009cb3a7019cfc1,0x0003b73c3064cd8f,0x0008e6c1c89da37f,0x0000329e0ea397cd}}, + {{0x0001b5e44c3250c6,0x00006ceb294648c0,0x000b962637706782,0x000130c3b3acfe89,0x0000a6dce5b66ebc}, {0x000aa6186ce36869,0x000b1852bf94c5bd,0x0004c261dc5ebfe3,0x000f138a1bef6195,0x0000a279dbb67a1b}}, + {{0x000879d90e03a540,0x00098a4ef9ff4a24,0x000a26c0ce8f5edb,0x0003796474413661,0x00004350b4104b6d}, {0x000757164564536b,0x00057d4f4adebe01,0x00050b82d298dc7a,0x0005b791e2842835,0x0000a781123e3c5c}}, + {{0x00007c48619e84ab,0x00097a8e0f19b2f3,0x000b3c9db52cf19a,0x0007e35d5659ce7d,0x00003886ff23b704}, {0x0001aaf58811dc26,0x0002bfed52b1bbd1,0x0007104ca16ad476,0x000b79c4f1138a88,0x00007658715f7d62}}, + {{0x000f110ecabcba82,0x0004da27d56ef2b7,0x000dc00cb29c9167,0x000ea38be30c384b,0x0000551fbe178550}, {0x0009ceb4b6cda9b1,0x0001c0f8dbf0f1e2,0x000ff617a844614b,0x000b9bb65d23f3e8,0x0000463bcf08ebf8}}, + {{0x00046fb3c9c2f2f6,0x000d8bc887881058,0x000acf39df0c62e8,0x0005e06d804143a8,0x000012fea1c85697}, {0x000fe3dccde965f2,0x0008b508c90850a3,0x000e602055cb2212,0x00026281f1187920,0x0000af846cb5a96b}}, + {{0x00094218aed1a517,0x0007bcb7d8e4e5ea,0x00070f71ce083200,0x000c497f01ba571e,0x0000e6ebb21847cb}, {0x000aed8c6da82ba6,0x000ab2db4b4da475,0x000a869cd33a684d,0x00064cc689a3ac37,0x0000ae1ee3463a89}}, + {{0x0005bb9f1e1c66ff,0x000777e629c50f4c,0x0009fd3d89dfbcb2,0x000022138efb8fcd,0x00005816bef7a97b}, {0x000fefc894aa6e34,0x000e9903a64777f7,0x0001f799abf92380,0x0007f487d3d67ad7,0x0000656fe81b0c1f}}, +}, +{ +/* digit=35 [{1,2,3,..,}]*([2^245]*G) */ + {{0x0009dc05b0daeb6a,0x0007ab1c9719331b,0x0003d0d262ae4dc8,0x000f3de5109dd56d,0x0000ad73296a5d14}, {0x0009fb2ac31d9136,0x000163a6acd79e56,0x0003de3fe8aed60f,0x00087300abd5213d,0x000039462f009289}}, + {{0x00020a59b6efa79b,0x00089cfab3fb90fb,0x0002133c42d820c4,0x000a360c8d738663,0x0000971de4ead8f2}, {0x0001f841e142f900,0x0003ccd560f2a34c,0x000e1379d650f3b7,0x000d1d007fad6aa7,0x0000b1bf229b9aa2}}, + {{0x000bb724b855a969,0x000c193ee3fa5bdf,0x00081b7e4fbe8611,0x00094f40258b7810,0x000069302e6ce1af}, {0x000a01254526c745,0x0004141d611305a4,0x000ed085a7fc0c93,0x0009be3d57407cde,0x000071742a3a7834}}, + {{0x000014a8c1f3bf07,0x00073102160f5085,0x0000c42214175c4e,0x000f472abaa79acf,0x0000dfe26a0804cd}, {0x0005aae6f42d4acd,0x0001a1106a667256,0x0009bd963bc85414,0x0008a723b2b776b4,0x00002e675791ac54}}, + {{0x00067e282d8e77ae,0x0000ec55fe6a99c2,0x0003bf9a2c0250ad,0x0007bfa7c31cc937,0x00001ae266831856}, {0x000738a847ecbcce,0x00022dac7b970a0a,0x00088ad41f4b09ba,0x0004ba5b4ead8383,0x0000ba6d2a78d509}}, + {{0x000e67853c1c0424,0x000ba067d80a0c28,0x000861c400f926de,0x00063b09e1a3bce2,0x0000fc011f0af635}, {0x0003dedbb918e260,0x0000921523ea0b52,0x0007bc667773bf8b,0x00086b039e89a24f,0x00007701e4145ce2}}, + {{0x000d665659750b64,0x000d981e7b419f25,0x000fc4ca88f75ecd,0x0002d199aed274fd,0x0000d837ba7e0764}, {0x000405c0720a84bb,0x000ef4af02130827,0x00080e040098122a,0x0007d9f41d3bcfc6,0x000033b4e1e14860}}, + {{0x0007596d7efa47e7,0x000f87ae55f9ba41,0x00018c27027f5c32,0x00038f7626dadc8e,0x000092ffbbe90edc}, {0x0009f3f053fc1017,0x00081a3a20f73dc5,0x0006fe6d0df44113,0x0007b5d805ac5f21,0x0000201193396b7b}}, + {{0x00031a2aa5514055,0x000aa37a81ddbd9a,0x000cad5460bb8634,0x000043fa6ecf5041,0x00007ba1f9908b03}, {0x000b451a99c6a86b,0x00003d70f946e8da,0x0006874cbe002fcc,0x00047b59ffb89cc6,0x000098339a4a6b4d}}, + {{0x0006655d65ec88df,0x000d6e79f896eff1,0x000d38236946c197,0x000510068781a8c4,0x0000cbe735a054e3}, {0x00062486280cc181,0x000cd52f7a4924a4,0x0009772668ab80e3,0x0006ec2371a3f51b,0x000083cd4419a909}}, + {{0x00061f179879b951,0x000df0c07e6ff0f8,0x0006434d1b7fed81,0x000899e3c92db27d,0x00005fb78635f682}, {0x00007019f0959708,0x000123fd44581616,0x000f3cd7af2e4c82,0x000d794d693d2a88,0x0000a039a63f0492}}, + {{0x000a5a141c4747c7,0x000c91edbabb6659,0x0008cd292c269efb,0x00017244e70fd00c,0x00005746625ed20b}, {0x0001a886d579ca7d,0x000ce93524c3eb4b,0x000e55b6cbbeb85f,0x000ac397f9b15372,0x00008d4f84e13615}}, + {{0x00014bfea7be6361,0x0000f328d17ed214,0x000ea80165d13b52,0x00041cc1aad9829f,0x0000c636f9bdefd5}, {0x0000ae640d4367fe,0x000cfcc82e5d8210,0x000bf012b1a13811,0x000a40021a0ebf68,0x0000ad45395140c8}}, + {{0x000093d07e16c03e,0x0008c6451c1a84f0,0x000852fb8e51a85e,0x00027647baccab5c,0x00000422dfc5ea59}, {0x000ae8d127196bf4,0x000b0cd1f307d1d4,0x000f0c06f05e1809,0x000207246e68d69a,0x0000bcbd7a6ea8b4}}, + {{0x0005696102fe7961,0x000128787cbabc0b,0x00047e5568e8a8ab,0x0009702b888f7629,0x00007005dc539317}, {0x000060a74a16a3d8,0x00059d11f5a2d057,0x000d3eee179fdf94,0x000b1336970f75a5,0x0000b65be596af2e}}, + {{0x0009a12055784ff3,0x0007e7ad17886a59,0x00083e1be483ccc5,0x0009c2326844874a,0x000091668f7d203c}, {0x000ccc39b9c01312,0x00079a1a3a021ae3,0x0005da5e7959cb5b,0x000b1b1efee9f28a,0x0000e21b1fe45033}}, + {{0x000b7effce6692d1,0x000d13f99991b95a,0x000da1b42890b0d4,0x000cec15a2ba2f18,0x000018e795c7c8cd}, {0x0000ea0ad07b7906,0x00006d2815a727cf,0x000f20348a8fa2cd,0x0000bbc96ae70635,0x000009c2b7d97f76}}, + {{0x00046418aa05aea8,0x00032c224067ea96,0x000401680c850519,0x0007cca8ecdb3161,0x0000a6a937b896d5}, {0x00066b96e440f85f,0x00058873f7cca1fb,0x0001e2cd22d99b85,0x0005da4df8221d94,0x0000a05eba0d7a8a}}, + {{0x000ccce912fa29fb,0x0009036040b56b4f,0x000aaa682139e237,0x00037b99fe6891cc,0x00002cac906e3f6b}, {0x000c39a68efd2423,0x000f8bc753e95cc7,0x0000629055d8668e,0x00004e48e5d349cb,0x000092775e6d287e}}, + {{0x0007764026e7e174,0x000920bd6ff6034a,0x0009b2c9a18833c8,0x000cb370c9651f3d,0x00007e2a44c0c972}, {0x00096a65b39a0b5d,0x0001d09cbc9e0807,0x000b2736f0b90d16,0x000112ddcf44a1bc,0x000042acfae127da}}, + {{0x000a76b6b44ab8e2,0x0009970211cceab3,0x0007bcb9b4bb22b4,0x0002bea529e44146,0x0000e0960bc476de}, {0x0009eb77378cd806,0x000d80e280c90b95,0x00014d594586a4dd,0x000310e90d20f04b,0x0000702dbd838d2b}}, + {{0x0003a01c57e6e9d5,0x00050dcc40c8c9ea,0x00090cba6fe563eb,0x000cdf395633b94e,0x0000c9d1045e8592}, {0x000d2588f46a6120,0x000b035c6210c59d,0x000e8248377f9aa0,0x0001aa4bc93a5152,0x00009dc56ac7a30e}}, + {{0x0000c564a8ac4c7c,0x0000d81af1627a56,0x00070a724e6dfb29,0x0006e7fb2bded10e,0x00002349505c61bf}, {0x000695464c03716f,0x0003bbcbebaa5c11,0x0008aabafd07239a,0x000af38c2eeda57e,0x00005d614c1d1436}}, + {{0x000e2d0f37b76522,0x00070e55eb8f1e79,0x00012eab7fa064b1,0x000522fe70f9abc2,0x000086b2a1081854}, {0x000fa02edae5aa1f,0x0006c5bece8a7b0e,0x000db187a76faee6,0x0006c55f3bafbf59,0x00006262ab51cd1b}}, + {{0x000bbe31e35d4f00,0x0003907a6029f9fd,0x0001b672f257cd8f,0x000429f29248e19a,0x000039e13d803d69}, {0x000c3c7908e58df4,0x000b0c985ea865df,0x00061454801424f8,0x000683ceefa02118,0x0000ab80f32400a3}}, + {{0x000ccbfa3d84058f,0x0005df204d3c0698,0x0009081ed4ca5c5b,0x000e64a883950e9e,0x00003c31bda6008e}, {0x000eba6a97909010,0x000507b1fb8d71ea,0x000c9169209e9956,0x00037554f52879e7,0x0000877f94c1ed32}}, + {{0x00041833560eed57,0x000a8ec17822793f,0x000852b85ba8088a,0x000eb3fbd9a1b805,0x0000c928511df25b}, {0x00049c211a3b0cf4,0x000018434a1def45,0x000091951e39b0e8,0x000d49dac937eddd,0x0000e6ee324776c1}}, + {{0x00037b1d92a17bf5,0x00096a699f0dc99a,0x000418df6afc0eee,0x000e8cc36e947922,0x00009cd84baf92d6}, {0x000fb2308f6ca879,0x0004189720d764a4,0x000e233b6e8157a4,0x00069ab8b5bb2ca4,0x000095141e790e65}}, + {{0x0009a7ad4edfeab9,0x00058ba474c78c2d,0x000efd6802660b1d,0x0005206e51d4a61f,0x0000d0fffb51a30d}, {0x000df5af5e13c41d,0x0007aa82333d762c,0x000e12bdbf9f9cad,0x00053d28e2c067f3,0x0000c214dd58c9c4}}, + {{0x00078f73d96f6c3f,0x0009940a0114e12a,0x0001b5edb91b616f,0x0007802baa7c46a6,0x0000bbaf38454705}, {0x0007732bce06e6f0,0x0003fc6ea51ec6d4,0x0005ac7dbbd02767,0x000aa24c78933088,0x000003fd48baf268}}, + {{0x000f8cb8b6b4ac7c,0x00022da8657e62e9,0x0003e709fac0ceda,0x00044cb8924265f7,0x0000c2125359b00d}, {0x000a800aa4354d4a,0x000d4c76651dc137,0x0007663922833c83,0x000b7a7093741920,0x00005c10ea46162b}}, + {{0x000b2b4671f489d4,0x00020e7e4b59a1a6,0x0004a86d078a8249,0x000b641af729005d,0x0000ea40b308107c}, {0x000def837872ffaa,0x0007857e65950d35,0x000ed651235c3f22,0x00011d318b69bc2b,0x00007d4a4d9d4cd9}}, + {{0x000fd6bd4e1c6acf,0x000b32bebbbb5828,0x0006ac0ea31f3e32,0x00040df9c1459119,0x0000c2fd4bfc2e76}, {0x000758062d718466,0x00050f36b4cdcb16,0x000ce037ecddce26,0x000d9b542106c49a,0x00001395c0f493cf}}, + {{0x000af914a54fc7e6,0x0006b42c62b10386,0x000d7e90af5bd329,0x000fcca6ab95b008,0x000058cf981705ac}, {0x0006ad0ad9ea67f5,0x0002735b7f791274,0x000a4060040b2faa,0x00095a83921bae30,0x0000ffd2c5e32b21}}, + {{0x000674b3b3f874f0,0x0007d4409b672a9d,0x0000672a80e68f8e,0x000a89bb24a6bbac,0x0000764bbd0e6bff}, {0x0009c13926cecbb4,0x000855e317e76a63,0x0007ef017f7e5c24,0x0004e80cc86df969,0x00002f0f42dbf4c7}}, + {{0x000b383892850d4c,0x000fac8523726a45,0x000089ef29685093,0x0008bea48bf7c4ea,0x00008aeda7a9e560}, {0x000a3efd995bd374,0x00059297e7208f9d,0x00083d14216bcb93,0x00036a46e7fc0aee,0x000007b7c7bbdeb6}}, + {{0x000994e8c70b66c1,0x000130bc81bb46d0,0x000e193a3bdca94e,0x000df90e3c0eaa9d,0x00006ef1f3cb51b1}, {0x000e07f5cad99fe6,0x0007bf8cf7c18d04,0x0006f9681ba9db21,0x0002692711c2a3e4,0x00007a115d42378b}}, + {{0x0003015fb3d08b6f,0x000c4f6c706ce14e,0x0002810d3977d0d0,0x000113a60a8549f6,0x00007a49710c6b40}, {0x0006aaa6c9b79e08,0x00001c5d3a5208aa,0x000f719168540d4a,0x0004423dbcbdb8ca,0x00008b82b284445f}}, + {{0x000621189521a131,0x00084775b0e3f2a7,0x000ce99086411768,0x000ba2af92188e83,0x00005862571e2559}, {0x0006c25a01159e10,0x000092ee012a048e,0x000ac9e25f213af8,0x000a7eb2d7503aca,0x000090ced06d85df}}, + {{0x0007e9d9f2f897e2,0x000607493cf5a89c,0x0006d18655a12aad,0x000b1e1b64925a04,0x00004203d3d79adb}, {0x000e22319c02fe70,0x00061fa0ca3076f5,0x000fc06ebb171574,0x0003534d5b2e1b98,0x0000ffaca4b07d6c}}, + {{0x000e95aa6360241f,0x00033dbc40dbd017,0x000e41655d78a47f,0x0003ae0c5478f797,0x00000bc57e149c3b}, {0x000dae7e92fcb87d,0x0003e73d7446c12a,0x00038f6c156141b3,0x000d7b8287f1b57a,0x00002551bb07d0a3}}, + {{0x000fd03ba124dcca,0x0005595509e778f5,0x0003963210ede681,0x000218ecbd904ba4,0x000057275ec31263}, {0x00098cc31aed8686,0x0002beb9be3d4ea4,0x00082eebaa59cd5c,0x000fd1991ab4d3f2,0x00005b2b384a3ded}}, + {{0x000f10557f7f4aa8,0x0003141d09cb5332,0x000b95beb2cef476,0x0004c82395b067df,0x00006a03a2c01446}, {0x0007dfef0be79d46,0x0001874b97275902,0x000f1f7d4d0de182,0x00099478e33b191e,0x000006558b7e81b4}}, + {{0x0002253a17cfb28b,0x0008ebf590ba262d,0x0002d72dd21664a7,0x000c4587d06f2f4c,0x000078a8de65b6b7}, {0x0006920bc17757f4,0x000cced7a68a4b12,0x0009387c7e16b5bc,0x000b542e5005a393,0x000035a62cdf92da}}, + {{0x000c560972894920,0x0000c17d3c2a87c6,0x000f1f08a4bdb0dc,0x000b2096faa4d313,0x0000f5c7607dec01}, {0x000241e51762f134,0x000fb8b10c63b6bf,0x0006515f30290df0,0x000b35eeaa2454cf,0x0000f60852859665}}, + {{0x000ffb9fdfce9b8b,0x000d43b966a89729,0x000dfbd7523680f5,0x0004c7b2c6ef98d2,0x0000bddbb8a5b1c7}, {0x0009eb62b7763240,0x00018e7f61e7f249,0x000509a885746186,0x000dad9a93d36959,0x000078c35a5126bc}}, + {{0x0006dffe227d9c28,0x000f28fcd749c021,0x00055e1af43fc164,0x000360f372e79f59,0x00000013b15b60ce}, {0x000642c77d088ab9,0x000603408ad40c33,0x000e18e96bf7079b,0x00099f840d636eca,0x0000098c58ab14b4}}, + {{0x00077dceae2302a1,0x0003c806e6c54271,0x000040bb8f335915,0x00091da3eadeb94d,0x00009926a3190114}, {0x0000b030aa56fd94,0x0000717246b8a0c9,0x00086222ff4d2833,0x000a76bce47d40bd,0x000009d403daad8c}}, + {{0x00049006bdc08788,0x0002a29d68a05f2d,0x00010f595a285de4,0x000fb4d722cd48f7,0x0000b96085211d89}, {0x000ed5908b41453b,0x0009af492a0d2a10,0x00067065f4429afa,0x0000d313f5f74aa4,0x00002f8641f9b3a4}}, + {{0x0006ef58b386c69e,0x0001a846d58225da,0x0007c90a64e5c80e,0x000f8c90401eaf20,0x0000f4a430a9b672}, {0x00083d647db36e0e,0x000066dcdadc8cb2,0x00012d7df32946b6,0x00087fb7f7b1c8b7,0x00003c85bb7e9e41}}, + {{0x000f20bba2439114,0x0008ff1b65fc2e61,0x000bd0e126bb920d,0x000d9abec02fc3dd,0x000015d3897b9394}, {0x0009c1cab00a9be5,0x000d661f585cd907,0x000eaf788c0705c8,0x0001aea79d859521,0x0000252c9d8f4143}}, + {{0x000b2d546f92c5d7,0x0003d47db7b536a2,0x0009dff2df753503,0x000b555388239913,0x00004372074066a3}, {0x0008723137e3f7e9,0x0001485151c6d57c,0x0000aa2a55b532c8,0x000edd04c3cc6736,0x000002f7dcf55657}}, + {{0x0006d3ff179e220d,0x00068eb3de8acd58,0x000fd1863a8fa7c9,0x000f449cd5617fb7,0x00003a190b0c03e8}, {0x0003da277108421a,0x00071f8b6dc858d4,0x000e4ee68a60e733,0x0007f658c12f0abb,0x000025d073738153}}, + {{0x0003d6dc16b4e186,0x000656aa6bd02ef6,0x00089e652e089004,0x000d744acb852631,0x000092e329517ff8}, {0x000d8b234333e0b7,0x0001098802c15416,0x000dadb64e1c1b30,0x000c8f225decbe5f,0x0000d948a7a85c34}}, + {{0x000c6469dc81a049,0x00001a4e55e5d35c,0x000fef56b28459f3,0x00059cd0155f5c27,0x00001ebe8d5d8309}, {0x00085c4a7131df9f,0x00088fdec6667457,0x000715d18057e535,0x000cd2d684d8573c,0x0000a9ca6c7cd549}}, + {{0x000e2e3446f9e281,0x000846c258bb86ce,0x000f37d5b739bc37,0x000c9b9746166b21,0x00008414a89a8b8e}, {0x000bb1b9f25ff8ad,0x0002a4dd50af0d98,0x0005b5a78084af6f,0x000ddb4667c708f9,0x0000c1e90d79e098}}, + {{0x0000f830f7f7a925,0x000962af6600ea3e,0x00042c1e3595c08f,0x000cafae22538bd4,0x0000b3101d3fcabd}, {0x00078afde4e64419,0x00007b0a9e895fab,0x000894659c483333,0x0005c40891f85893,0x000036cd9f687b51}}, + {{0x0000fdb1e5a3d569,0x0009b0374bf3035e,0x000a9b06d21be1c3,0x000609411de8deaa,0x00005478125def93}, {0x000338bc9cf8d1b1,0x0008608556303bd3,0x0001d00508c2e2ca,0x000a2a6d1106d92f,0x00001e1311fff629}}, + {{0x00008c0c7abe48cc,0x000a32325b3f3714,0x000cdd15b7dbb702,0x0009f3c37123b082,0x0000f285904b770f}, {0x00005a5f3b665bd4,0x0000eb9cff9258ce,0x000ae583f954f24f,0x000e2d7d0276a007,0x00008112308cea23}}, + {{0x0006ebf442107be7,0x0007b1a909f1ccdf,0x000684e1ca8ff7cb,0x0003f085d46ef075,0x00007121a630d6bf}, {0x0005761fbdeb7490,0x000711a947654819,0x000865547aecae1a,0x0007358f2f2b4382,0x0000d528600f8f9b}}, + {{0x0006e9b28d21be4d,0x000d16dba462a3c9,0x00054aae39c8bb2c,0x000b130de6632450,0x0000287f45d91f55}, {0x000e421a7d459f3d,0x0002a3b3137c7299,0x00044882490d7904,0x000bfb28faff33f9,0x0000bfb8dc9f56ed}}, + {{0x0006eaf73f22dd85,0x00040159d50c4c19,0x00084c5827c96b79,0x000f295616bb5386,0x00009e99fb634b73}, {0x000fa8d3a114007f,0x000921cf2fb36503,0x0007d77d78896f76,0x000aa84fde09fec7,0x00003da7be4c60d5}}, + {{0x0002bfa99958d23f,0x000c81847d0a62cc,0x000dfe7c5fb5c76d,0x0005c6e11e7e50b2,0x000088e3280b0e5e}, {0x000682d38e3cd1aa,0x0008a2d2a17ecd17,0x000fbf0977af10a9,0x00050e0a422c42e4,0x0000a1dd9f7d6448}}, + {{0x000e96433c0805a5,0x000d7869abf94e41,0x000dc5ed1e35cc84,0x000f55a120bac5dc,0x0000d5f11d73cf91}, {0x000b444c48e7a259,0x000d3d34f5e7ffb3,0x000617df908d9b25,0x00074f19c9a1d296,0x0000b424cec270cf}}, +}, +{ +/* digit=36 [{1,2,3,..,}]*([2^252]*G) */ + {{0x0004e9d192cabe16,0x000136ac20d6f4c3,0x000b9a9a95ed7b38,0x00037f743f5452cd,0x00003e7e859d699c}, {0x000288719e08654e,0x00055a84a99d8b7c,0x000b5e1d47df6f11,0x000affb8f70d6ecf,0x00000f85856658fd}}, + {{0x000989794fdccb99,0x000664d2a5d09eb7,0x000f3dbd4a6c29d7,0x00006c08e7b46244,0x0000d3275732baf1}, {0x00078611cb5eac27,0x0009d9c76502f96b,0x0008f3ffdf832947,0x0006d50496b021f2,0x0000f3bea3e2eab2}}, + {{0x000d467bef953373,0x000f071bddfa0d77,0x000be423588d7262,0x00060e99185a1f4d,0x0000bc436399b964}, {0x0008c2ad1207560e,0x0002054fdbb7908a,0x00099c759edae8a1,0x000c0e4e054bfa36,0x00002db152ab5cf2}}, + {{0x0006019816bb79c3,0x00025d9ee9893bd2,0x0005c447c9f4d46a,0x0009c26760f22454,0x00003b25455b00de}, {0x0000cad04873a72e,0x00074e432c4decdc,0x0006750b41e24738,0x0009f681a6c25f63,0x00003d05248bbaa4}}, + {{0x000481d262409089,0x00085ea18d0661c9,0x000e20eb4c37806a,0x0009090d6babcb16,0x00008acecc7050ae}, {0x0006575fb2de613b,0x000121a2f094246e,0x000405eec4b33ebe,0x000e1064f6eb1a6a,0x0000d337e63aa2db}}, + {{0x0001242ccb9661a4,0x000e4b4b735a681a,0x000038cb78b1e57f,0x00048653161304f1,0x0000e5b9a8a398a9}, {0x0006e7de5b2bfae6,0x0000b846b3a7915a,0x000464483729cd42,0x000aefe28c607ed3,0x00003f2fb772d468}}, + {{0x000198fd906ce680,0x000617f59c8fd445,0x000002f38f184755,0x000e15c2f310b252,0x0000a4410ce1ced3}, {0x000ed8c1a5559846,0x000e72884eb22a13,0x00019d74e6e7911f,0x000e37cee1a905d1,0x00006f730d7170da}}, + {{0x0002fb6223e426f1,0x00089ec0aa53e22b,0x00041c88f08382bc,0x000f3ce723df210f,0x0000eab10c6e3af5}, {0x000e9ee919f420f9,0x0007feb7d658384a,0x000d6cb287d7bf16,0x000e7944e141cd92,0x000072357ff59e5d}}, + {{0x000c56b5bf5b4709,0x000351a00ac5adc6,0x0000eea7fa5bc587,0x000fa53e96a1bcfc,0x000037fcff36ffa5}, {0x0009f297dcabee43,0x000a97014f90ac36,0x000a4fb4897cf19a,0x00023c3e53d9a7ae,0x000088e0a1c87728}}, + {{0x00085910c59fc2ff,0x000edd337895b65f,0x000511aab9da9784,0x0003096a69799310,0x0000e52ae4181572}, {0x000749531e18c1e3,0x0008b80751a2bb45,0x00001252b398f247,0x00055b499d5957ef,0x00003146d57f9c23}}, + {{0x00016eba4eecc3be,0x000ce1567b234d2f,0x000efba21f561158,0x000a7d55857190e0,0x0000320ec77503ce}, {0x0002c5e31d91219f,0x0008a202612ab98d,0x00046d14dd97213e,0x000914064ebf5b24,0x0000252742c3551c}}, + {{0x000892bae35f8fff,0x0007393a7330c288,0x000e452adeb6025c,0x000fa6fdb0931841,0x00000230ffaf8bad}, {0x0009c569666cb64c,0x00028c9c1a11d83c,0x0006d175be8ee2b7,0x000fc1d4d08c60fb,0x0000e59f68cfb17a}}, + {{0x0004746057984cd0,0x0000120adf81173d,0x000dccffa456524a,0x0003ddbb34c2a11e,0x000094498314e67d}, {0x000864a8165bdf84,0x0001548f9fd22672,0x0002502dc589998c,0x0002ff4896359671,0x000033a8860e87ea}}, + {{0x0004df6843c364e9,0x000b16a5ee86621f,0x000f9457ae1f592d,0x000240793da6c122,0x00002d742b08fcfb}, {0x0008c3f73811884b,0x0007e71f910c2c7a,0x000405a5a15bfcfb,0x000f363a542968cd,0x0000a72904aaf04d}}, + {{0x000ffef7441e12e9,0x00042919f0edc246,0x000792a5bbf274ab,0x000883a1dbf3b485,0x00006fed0fa498e2}, {0x000247ca159aa0db,0x000cb4ac34f0f016,0x0007adee02259b6f,0x000ab0e110a89e6a,0x0000df1a3bccde15}}, + {{0x0009939fe95894f3,0x0006d80da64f7f5b,0x0005668fb3c50e7c,0x000b18adf2c440f9,0x00002885888ec566}, {0x00067d3ea0cc76aa,0x000b0b26bc3ba506,0x0004568d5f276915,0x0001f136016d96ad,0x0000a9984da49550}}, + {{0x000d0ed6b7a871b6,0x000ab42c02ff0806,0x0009af12f46ee10a,0x0005d377ff131d77,0x00005a677099acd8}, {0x000ac9b951626815,0x0009abdb942babd9,0x00036440880eb706,0x000163339c586c4f,0x0000709ca935dc3b}}, + {{0x000ff3ccda445aca,0x000f0859e39c86a5,0x00090203fe429386,0x0008a52bf2703bab,0x0000720aa0200a65}, {0x0007538fdce5c9c9,0x00015246ebcb614e,0x0001842f337ae4a6,0x000828acc435ef95,0x00005e104588fd92}}, + {{0x0003cab9fe36412f,0x000c67555bd68737,0x0001bae6459ab06a,0x000fa54dfd187fa0,0x0000876a919b3578}, {0x0002b2279ace5b23,0x00067ca98cbd005b,0x000e40955a4d14a0,0x000970e03ea45012,0x00007185a2170d87}}, + {{0x0005612acb6e9367,0x0000244b28116bc6,0x0000fe9ace978300,0x00001bd8b738ef68,0x0000764500d3e681}, {0x0005a153f84b39ee,0x0004d79c4f71c297,0x000ad48b40f23e0d,0x000fe1df83cf30f0,0x0000ed994a14ad8c}}, + {{0x0006efacdd042013,0x0003311876df9490,0x0002bc23a0bac093,0x00009572e8adfc0d,0x0000c9e44ac33ba1}, {0x0007febbe90ab31f,0x0000bd134ef68004,0x0007788b8aa2b3eb,0x00025338748a1e98,0x0000b0f3a19b0368}}, + {{0x0006fbd381cc78af,0x00071706d2d15d34,0x000ee95e156dcdce,0x00005368df42e000,0x00005cd53efe90cd}, {0x00031ea895eeeb96,0x000ccf55d9280aea,0x0007880c92d842de,0x00017146595637e4,0x0000641ce44806ad}}, + {{0x000824118043c9a3,0x0005cf70caa98b65,0x000f51f396391481,0x000f7d40813d12f8,0x0000547dad76afc8}, {0x000149d080befd0b,0x000b7195cedc7d61,0x0009dc3f0e5886a2,0x0004cb9a99003a55,0x00007bf2af415c17}}, + {{0x000b64ed8b470837,0x000667567a1863c8,0x000a8958dda010c6,0x0009d8fce07e107c,0x0000333c3dcb7dec}, {0x000eef3725031b69,0x000b3d8017798df6,0x0004553846f57184,0x000740a78efac9c4,0x000091dcab915273}}, + {{0x00034d3d7a665eae,0x000176ef69c8e8cc,0x0002d1efd49af983,0x000c8da18040aabd,0x00003d8b47daa6ea}, {0x0002a6ab05930688,0x000ae5a1d5b5c164,0x000ec89eb5f6487d,0x000e45cd4ff7be70,0x0000da3d01424bad}}, + {{0x00038654291e9930,0x0005df3ebe005344,0x00051191326bf2e8,0x0002cb4d29e094e5,0x0000c2bfc12b6dc4}, {0x000c45947fa997d1,0x000efc7b04beec10,0x00092b0b4c905403,0x0008649820b0076a,0x00000768c5a27aa6}}, + {{0x0004fa4594af9a68,0x000599a9cc36d9eb,0x000b7f57263399f3,0x0000337fb3d0ceae,0x00005ca399f0e87c}, {0x000ea931d2385710,0x0001ed59e07954dc,0x000a7c626181c100,0x000429eb1a4ec0a3,0x000096fa65837c79}}, + {{0x000024de86d1520e,0x00030986cb7e66af,0x000efe7c68e15b56,0x000d805f49c36865,0x0000ab5898f85171}, {0x0005276853f145ec,0x000381824620abe6,0x000b802ce92b4fb6,0x00036d087612db6f,0x0000a0d67a1b76f7}}, + {{0x0004f2782c6ac72a,0x0003cafa67117a5c,0x0002aab6fb1c93c9,0x0004a540bc21b67e,0x0000934f022b3868}, {0x000d03cbbc8303f2,0x0004a4fb67b44644,0x00075a8b54b44e4e,0x0007e18bf968e89e,0x00000f6f42ac1a37}}, + {{0x000486f46ce1f619,0x000037a2e0f90539,0x00020a418cea6f5e,0x000ba43f6c178ddf,0x00006ab2cb90f6c4}, {0x0004b1c6938cfc22,0x00020e13845f695e,0x000d68e0193de57e,0x000ebc9ff5be6cb4,0x000002c5058b0d9d}}, + {{0x000c3c04fde203fa,0x0005baff5dd91577,0x000ef4054c12be81,0x0006add827ff0b61,0x0000a1f02d5283f0}, {0x0006692f1555eecd,0x000c44b0a336ee5a,0x00082f8f5b11fe2e,0x000da11c05d843a5,0x0000c68bae17ef36}}, + {{0x000ee12df5fabf2b,0x000be45a670b441d,0x000c610623c7e5fd,0x000d5872bd798c04,0x00009e1db3844e1d}, {0x0005ddaf191ee063,0x000f3d7cea2df0ad,0x00086387d70cdf49,0x000cefd8af41cf1c,0x00009846533056ae}}, + {{0x00021d62549e2b45,0x00037cb224e3c015,0x000678b1ce2f4b85,0x0000525f28baa01d,0x00005d6e33c34710}, {0x000d0d35e745bee9,0x000f90455fdf7490,0x000eb3d3ef5582c0,0x000a223455ee33cb,0x0000ede029ddb7d6}}, + {{0x00094f9647c9d90c,0x0009ae5f214b69bd,0x0007a420dba58efa,0x000a1778c3aa70bb,0x00005b6de0077a42}, {0x0009d9ea019d4132,0x0007f0e583e34c87,0x0005be0ce07a75bd,0x000b6b3d395891e3,0x0000411317743abc}}, + {{0x00071e9d9637bd7b,0x000aa30673d89731,0x0004f6faaa823ed5,0x0008bb2383e64b03,0x00002b4b7d4e2602}, {0x00010fb3c893e582,0x00051b773cca2248,0x0007552b33ebecfb,0x00069cecde31e97f,0x00008f7134559072}}, + {{0x000b81bd0d95dfea,0x000920c24df0288c,0x000310dd6c5ef9f3,0x000d5abf1b0350c5,0x0000ad3ddb3e8a48}, {0x000dd398b526731f,0x0005384805e5c192,0x000b7e61e9fed2fe,0x000e23cfdd2588ba,0x0000c740a3eef5c3}}, + {{0x000eac2018c33f78,0x0006fe797f0c8057,0x000b588aee816f24,0x000cabc89d091be7,0x00003cd7be0bdaf6}, {0x0009197eaba2edb2,0x000261290082c9bf,0x0002d252eb7c7e7f,0x000069d1ae302bc4,0x000059df1546cf2c}}, + {{0x000c6ed00d94ec36,0x00088e1af59b2c21,0x000e2ff2bcf61175,0x000869457c578360,0x0000523a23621201}, {0x00034a09be29e76a,0x000690f5c6bae145,0x0006b6f117764e98,0x000976119eff6ee2,0x000083c1f34b5380}}, + {{0x000aa5996ef32628,0x000199d82779220a,0x000d1241a4aeba26,0x000ed2f9f34d5f06,0x00004acf34a65fce}, {0x000315c7f2ccd41e,0x000c5fdf0096ae54,0x00080691f3391667,0x00052631991b02d6,0x0000c48b23574895}}, + {{0x0008812c701e04a9,0x0002050be8112a19,0x000edb9dd4072896,0x000fd219a3328fa8,0x0000e4723d681c68}, {0x0004a362eddf7e14,0x000fa26194b59490,0x000cc6e78db8c366,0x0006655f1cc62e79,0x0000d82e71dbd404}}, + {{0x00042661e0e01d69,0x000365b508430cfc,0x0009c570783ab355,0x000126719831e04a,0x000080fe3aa553aa}, {0x0005fba614f1229e,0x000ff23b90b04642,0x00088bd06048f481,0x0003938fab45f5ed,0x000081191df8129f}}, + {{0x000e6fa9951025d2,0x00041ecbf164a4d8,0x000d2f4e8491ed8a,0x00055b97fd6f9239,0x00006956adf726ae}, {0x0003a64e362a0314,0x000daa7b2078d584,0x00085660784da40f,0x000e2e4313534367,0x000074d604a28332}}, + {{0x000a9eacf4537898,0x0002535b7ed6beae,0x000d61511432f159,0x000edfe8ae015426,0x0000e7ad54ed3027}, {0x0008791dd6d06fcd,0x000cbb7fbce3acab,0x000bc7d0c0bc5826,0x000ec5864d8cb9b5,0x0000d5249e385260}}, + {{0x00031d9a10b92593,0x000b60bc06806933,0x000608f7d34ced3d,0x000e6d0d2006d8b2,0x0000aed68ceedb49}, {0x00015ad47c543ae5,0x000bbf84989e807a,0x00020645060e02d8,0x000196b5ba87d4ae,0x000068321bbe2e41}}, + {{0x000fa99480713a9b,0x00006bf34178f755,0x000be4593bc93577,0x0006d10a3c6ef3f1,0x0000310bacda7514}, {0x00057088f40a62e7,0x0005ee7b59e56baa,0x000af9ff64d366c7,0x0004ffc6b10b30ad,0x0000d6bd4deb6eb0}}, + {{0x0003bad7134faa7e,0x000c0b033f5eaa35,0x000e4f98ff42bcb8,0x000ec9a998139559,0x0000f99dd5db139f}, {0x00009ecb311e12f8,0x0002adc0a4dc54fc,0x0005c0b088460433,0x000ce37796ea0ae1,0x0000ece0022c632b}}, + {{0x000a05993f51c69f,0x00070bea577129dd,0x00064408337ea113,0x0005a48ba7c02c90,0x000035f93ee50fde}, {0x0001277019f51c41,0x0006adfd4c1abe93,0x00083e23a3e47aca,0x000aa67a89f9df66,0x000092d1f5304fa0}}, + {{0x000ac330d6c7b459,0x00082e88c3411e11,0x00005313b3e445d1,0x0006bc33cc1dc4d9,0x00004685343106e0}, {0x00051b83920ae37d,0x0001c71d6750f1e5,0x000b709a1faade96,0x0007149f2dc25e54,0x0000b71cc89b494b}}, + {{0x000f3f8d09521bed,0x0008512c9daab73a,0x0003da2ba27d45d8,0x00053296a099b7b5,0x0000e7f2156e567c}, {0x00017ea24df91ea0,0x000270e60988d6c3,0x000418dde749e07d,0x0007a0c55165c906,0x00000189658e7c42}}, + {{0x0005554a920980f5,0x0004d83056f4f7dc,0x000745be3258ac61,0x000646af5b2b9c78,0x000032efb61c140e}, {0x00065f3c23f4987a,0x00029a1787327ea8,0x000b93558610d559,0x0001dac6b44f9ef7,0x00008c3f3947610c}}, + {{0x00036c41c02e3f96,0x000c00d78de5829f,0x0006cdb1416e315b,0x0006d6039934b045,0x00005408b5b7c401}, {0x000046423ee53cf9,0x000ca2000b9b28d8,0x000ac80402e6f559,0x000737cf3b0e8eab,0x00000a478fff164c}}, + {{0x000d5dbc3bce5259,0x000a79bab068adc4,0x000702cff0e692d9,0x0009162104dab4e1,0x00007c3b223bc6e0}, {0x000a4bae9b92e722,0x00066cd5c34091b3,0x0006af7b98c5842b,0x00046e36bf2afb32,0x0000e0928bb0a702}}, + {{0x000e1f1c48f51b67,0x000e3017ad888cfc,0x000124d6978fa7fb,0x00020cae67af53f3,0x00001d14379ab093}, {0x0006d3efd5b32f13,0x0008955fa05fbe53,0x0000194e6d931907,0x0003184e5f4c7300,0x0000f48a960c8670}}, + {{0x0004dae073946e67,0x00069e56390f104b,0x00034438ec69b46a,0x0003d9a22a832b30,0x000078dfabdaf745}, {0x00083fe3d2f9dc1d,0x000b45b9863f9203,0x000ed43a45a02d9b,0x0004dc1e596b8494,0x00001045a9c041b7}}, + {{0x00016c0a59ce7847,0x0003816390641219,0x000c52eac415e082,0x0004dd076ea35e04,0x0000e4629568ba7c}, {0x00071b6a7b975de1,0x0007b677e54ee47d,0x0004a7e4c03aec55,0x0002fc9359233ebf,0x00003b0f0abe072b}}, + {{0x000dfefe8800dcd2,0x0007813d211bb68d,0x0006e883a7a79b7c,0x0004ea45689552b4,0x00008de706a7de1a}, {0x000c4e3d983df145,0x000fdfedeea597b3,0x0000e50daef33ef9,0x00096c99395a861b,0x0000f4ee038dd678}}, + {{0x0002fa9a80943602,0x000a160fc4fb1606,0x000a18843d079884,0x000fdcfc9ae67dea,0x0000de5999876f2b}, {0x0001e086666832ff,0x000ac7312a202d98,0x000df4eb39af1d51,0x0006ba69df8bab4d,0x00004f813058f3c4}}, + {{0x000e4d9deba1f764,0x00046544992ba84d,0x00062571d3ef1e08,0x0003d6cdf5b4eef3,0x0000c6b0de82e039}, {0x00019759c17b4e15,0x0007eb4e8f856535,0x0002db7b0e1f35cb,0x000a2de21c2ce964,0x0000ede5f6162f54}}, + {{0x0002e8ff962e6fb2,0x0003791b5f6c1220,0x000daf6cb28042fd,0x000a0d5f509fdfe4,0x0000a70291c45d04}, {0x000e258b0e2b68da,0x000b17fac85bdaf9,0x000d1b986bf47d76,0x0002f63d6778a846,0x0000223266c01388}}, + {{0x000f6489e4813958,0x00073454ba37e004,0x000852a0cf198eb2,0x0001c1d7d37038b3,0x00005057db2e3939}, {0x000ab92ce347b4c8,0x000ca340fa0188c7,0x000ef094a8b99eb3,0x00014dcfa7df268e,0x00005a65feda02ad}}, + {{0x0006ea594087938e,0x000c2c29c1b6b97c,0x000fcd2e662321e1,0x0007d0edd9981f5b,0x0000571509bfdac6}, {0x000506cccb99c73e,0x000781554bcdd381,0x00076723b50a8b0a,0x000df26130d1d4f5,0x00007791681ec370}}, + {{0x00016a84ca2278a7,0x0005b22100cbee90,0x0008b97d91e063af,0x000ba251ae16b457,0x0000b228a1a62245}, {0x00037ce46041bf2a,0x0009154529a0343c,0x00093bcf590509e3,0x000354b75ffee430,0x0000d443bb4bab01}}, + {{0x000f1435aaae6483,0x000a104f999a4352,0x0009f21ba7c9f131,0x0005b56e3000fcee,0x000045e97d130480}, {0x000862d2138a5c21,0x0006da716279c728,0x0006fa6fa150dba3,0x00084fa32f114503,0x000020200ebf2740}}, + {{0x00090af2a4f30bb8,0x000233a2204ec06a,0x000572fbdc316dfd,0x0002843a0475a78f,0x00004ba9e239c4e7}, {0x0009abfc1137d0a0,0x00011346b7ea4127,0x000361a1d3145421,0x00011092560f9c0e,0x0000e66391042bad}}, +} +}; + +#endif //(_DISABLE_ECP_SM2_HARDCODED_BP_TBL_) + +IPP_OWN_DEFN(const cpPrecompAP *, gfpec_precom_sm2_radix52_fun, (void)) { + static cpPrecompAP t = { + /* w = */ BASE_POINT_WIN_SIZE, + /* select_function = */ gesm2_select_ap_w7_ifma, + /* precomputed_data = */ (BNU_CHUNK_T *)ifma_ec_sm2_bp_precomp + }; + return &t; +} + +#endif //(_IPP32E >= _IPP32E_K1) + +#endif // _IFMA_ECPRECOMP7_SM2_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_sm2_key_exchange_shared_key.c b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_sm2_key_exchange_shared_key.c new file mode 100644 index 000000000..ff33a1363 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/ifma_sm2_key_exchange_shared_key.c @@ -0,0 +1,264 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" + +#if (_IPP32E >= _IPP32E_K1) + +#include "sm2/sm2_stuff.h" + +#include "sm2/ifma_defs_sm2.h" +#include "sm2/ifma_ecpoint_sm2.h" +#include "sm2/ifma_arith_method_sm2.h" + + +/* clang-format off */ +__INLINE void ifma_sm2_set_affine_point_radix52(PSM2_POINT_IFMA *rp, + const BNU_CHUNK_T *x, const BNU_CHUNK_T *y, + ifmaArithMethod *method) +/* clang-format on */ +{ + ifma_import to_radix52 = method->import_to52; + ifma_encode p_to_mont = method->encode; + + rp->x = to_radix52(x); + rp->y = to_radix52(y); + + rp->x = p_to_mont(rp->x); + rp->y = p_to_mont(rp->y); + rp->z = FESM2_LOADU(PSM2_R); + + return; +} + +/* clang-format off */ +__INLINE void ifma_sm2_get_affine(BNU_CHUNK_T *x, BNU_CHUNK_T *y, + const PSM2_POINT_IFMA* p, + ifmaArithMethod* method) +/* clang-format on */ +{ + /* extract affine coordinate */ + fesm2 loc_x, loc_y; + gesm2_to_affine(/* x = */ &loc_x, /* y = */ &loc_y, /* p = */ p); + + ifma_export to_radix64 = method->export_to64; + ifma_decode p_from_mont = method->decode; + + loc_x = p_from_mont(loc_x); + loc_y = p_from_mont(loc_y); + + to_radix64((Ipp64u *)x, loc_x); + to_radix64((Ipp64u *)y, loc_y); + + return; +} + +/* clang-format off */ +IPP_OWN_DEFN(IppStatus, gfec_key_exchange_sm2_shared_key_avx512, (Ipp8u* pSharedKey, const int sharedKeySize, + Ipp8u* pSSelf, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pEphPrvKey, + IppsGFpECKeyExchangeSM2State *pKE, Ipp8u* pScratchBuffer)) +/* clang-format on */ +{ + IPP_UNREFERENCED_PARAMETER(pScratchBuffer); + + const IppsKeyExchangeRoleSM2 role = EC_SM2_KEY_EXCH_ROLE(pKE); + + const IppsGFpECPoint *pPubKey = (ippKESM2Requester == role) ? EC_SM2_KEY_EXCH_PUB_KEY_USER_B(pKE) : EC_SM2_KEY_EXCH_PUB_KEY_USER_A(pKE); + const IppsGFpECPoint *pSelfEphPubKey = (ippKESM2Requester == role) ? EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE) : EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE); + const Ipp8u firstNum = (ippKESM2Requester == role) ? 0x03 : 0x02; + + IppStatus sts = ippStsNoErr; + + IppsGFpECState *pEC = EC_SM2_KEY_EXCH_EC(pKE); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + gsModEngine *nME = ECP_MONT_R(pEC); + + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemBytes = (elemBits + 7) / 8; /* size Bytes */ + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + ifmaArithMethod *pmeth = (ifmaArithMethod *)GFP_METHOD_ALT(pME); + ifmaArithMethod *nmeth = (ifmaArithMethod *)GFP_METHOD_ALT(nME); + + ifma_import to_radix52 = pmeth->import_to52; + ifma_export from_radix52 = pmeth->export_to64; + + /* Mod engine (mod n - subgroup order) */ + ifma_encode n_to_mont = nmeth->encode; + ifma_decode n_from_mont = nmeth->decode; + ifma_mul n_mul = nmeth->mul; + ifma_add n_add = nmeth->add; + + /* check that Ephemeral Public and Private Keys are related (R(a/b)=r(a/b)G) */ + /* Ephemeral Private Key -> r(a/b) */ + IppsGFpECPoint pTmpPoint; + cpEcGFpInitPoint(&pTmpPoint, cpEcGFpGetPool(1, pEC), 0, pEC); + BNU_CHUNK_T *pDataEphPrv = BN_NUMBER(pEphPrvKey); + gfec_PubKey_sm2_avx512(&pTmpPoint, pDataEphPrv, BN_SIZE(pEphPrvKey), pEC, pScratchBuffer); // r(a/b)*G + int result = gfec_ComparePoint(&pTmpPoint, pSelfEphPubKey, pEC); // R(a/b) == r(a/b)G + cpEcGFpReleasePool(1, pEC); + IPP_BADARG_RET(!result, ippStsEphemeralKeyErr); + + /* create buffer data (it needes further use compute tmp_p) + * -> SM3( x(u/v)(0) || Za(1) || Zb(2) || xa(3) || ya(4) || xb(5) || yb(6) ) + */ + BNU_CHUNK_T *pDataBuff = cpGFpGetPool(7, pME); + BNU_CHUNK_T *xuv = pDataBuff; /* x(u/v)(0) */ + BNU_CHUNK_T *za = pDataBuff + 1 * elemSize; /* Za(1) */ + BNU_CHUNK_T *zb = pDataBuff + 2 * elemSize; /* Za(1) */ + BNU_CHUNK_T *xa = pDataBuff + 3 * elemSize; /* xa(3) */ + BNU_CHUNK_T *ya = pDataBuff + 4 * elemSize; /* ya(4) */ + BNU_CHUNK_T *xb = pDataBuff + 5 * elemSize; /* xb(5) */ + BNU_CHUNK_T *yb = pDataBuff + 6 * elemSize; /* yb(6) */ + + PSM2_POINT_IFMA Ra; /* ephemeral public key User A */ + PSM2_POINT_IFMA Rb; /* ephemeral public key User B */ + PSM2_POINT_IFMA P; /* public key User (A/B) */ + + /* convert to Montgomery IFMA SM2 */ + /* extract -> xa | ya | xb | yb */ + BNU_CHUNK_T *_xa_ = za; /* use Za(1) */ + /* 2) x(a/b)` = 2^w + (x(a/b) & (2^w – 1)) */ + /* point to affine coordinate */ + cpSM2KE_get_affine_ext_euclid(/* x = */ xa, /* y = */ ya, /* p = */ EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE), /* pEC = */ pEC); + /* set affine coordinate radix 52 */ + ifma_sm2_set_affine_point_radix52(/* rp = */ &Ra, /* x= */ xa, /* y = */ ya, pmeth); + /* reduction x = 2^w + ( x & (2^w - 1) ) */ + cpSM2KE_reduction_x2w(_xa_, xa, pEC); + /* to big endian */ + cpSM2KE_xy_to_BE(xa, ya, pEC); + + BNU_CHUNK_T *_xb_ = zb; /* use Zb(2) */ + /* 4) x(b/a)` = 2^w + ( x(b/a) & (2^w – 1) ) */ + cpSM2KE_get_affine_ext_euclid(/* x = */ xb, /* y = */ yb, /* p = */ EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE), /* pEC = */ pEC); + /* set affine coordinate radix 52 */ + ifma_sm2_set_affine_point_radix52(/* rp = */ &Rb, /* x = */ xb, /* y = */ yb, pmeth); + /* reduction x = 2^w + ( x & (2^w - 1) ) */ + cpSM2KE_reduction_x2w(_xb_, xb, pEC); + /* to big endian */ + cpSM2KE_xy_to_BE(xb, yb, pEC); + + BNU_CHUNK_T *pPool = cpGFpGetPool(3, pME); + recode_point_to_mont52(&P, ECP_POINT_DATA(pPubKey), pPool /* 3 elem */, pmeth, pME); + cpGFpReleasePool(3, pME); /* pPool(3) */ + + /* extract to role */ + BNU_CHUNK_T *_xf_ = (ippKESM2Requester == role) ? _xa_ : _xb_; + BNU_CHUNK_T *_xs_ = (ippKESM2Requester == role) ? _xb_ : _xa_; + PSM2_POINT_IFMA *R = (ippKESM2Requester == role) ? &Rb : &Ra; + + /* 3) t(a/b) = ( d(a/b) + x(a/b)`*r(a/b) ) mod n */ + fesm2 d, r, x1; + d = r = x1 = setzero_i64(); + /* preparation d(a/b) */ + d = to_radix52((const Ipp64u *)BN_NUMBER(pPrvKey)); + d = n_to_mont(d); + /* preparation r(a/b) */ + r = to_radix52((const Ipp64u *)pDataEphPrv); + r = n_to_mont(r); + /* preparation x(a/b)` */ + x1 = to_radix52((const Ipp64u *)_xf_); + x1 = n_to_mont(x1); + /* compute */ + r = n_mul(x1, r); /* r = x(a/b)`r(a/b) */ + d = n_add(d, r); /* t = ( d(a/b) + x(a/b)`*r(a/b) ) */ + /* t -> convert form Montgomery */ + d = n_from_mont(d); + + /* 5) U/V = [h*t(a/b)]( P(b/a) + [x(b/a)`]R(b/a) ) = ( x(u/v), y(u/v) ) */ + const int scalarBits = ((elemBits + 1) / 2); + gesm2_mul(R, R, (const Ipp8u *)_xs_, scalarBits); /* R = [x(b/a)`]R(b/a) */ + gesm2_add(&P, &P, R); /* P = P(b/a) + [x(b/a)`]R(b/a) */ + BNU_CHUNK_T *pScalar = xuv; /* use buffer x(u/v)(0) and Za(1) */ + from_radix52((Ipp64u *)pScalar, d); + pScalar[elemSize] = 0u; /* extended scalar - add 0 -> R = [scalar]P */ + gesm2_mul(&P, &P, (const Ipp8u *)pScalar, elemBits); /* P = [h*t(a/b)]( P(b/a) + [x(b/a)`]R(b/a) ) */ + + /* check U/V == 0 */ + const mask8 is_zero = (mask8)(FESM2_IS_ZERO(P.x) & FESM2_IS_ZERO(P.y) & FESM2_IS_ZERO(P.y)); + if ((mask8)0xFF == is_zero) + sts = ippStsEphemeralKeyErr; + + /* extract x(u/v) ,y(u/v) */ + ifma_sm2_get_affine(/* x = */ EC_SM2_KEY_EXCH_POINT_X(pKE), + /* y = */ EC_SM2_KEY_EXCH_POINT_Y(pKE), + /* p = */ &P, + pmeth); + cpSM2KE_xy_to_BE(/* x = */ EC_SM2_KEY_EXCH_POINT_X(pKE), /* y = */ EC_SM2_KEY_EXCH_POINT_Y(pKE), pEC); + + /* Precompute Hash */ + Ipp8u *pBuff = (Ipp8u *)pDataBuff; + /* tmp_p = SM3( x(u/v) || Za || Zb || xa || ya || xb || yb ) */ + /* copy x(u/v)(0) */ + cpSM2_CopyBlock(xuv, (const Ipp8u *)EC_SM2_KEY_EXCH_POINT_X(pKE), elemBytes); + /* copy Za(1) */ + cpSM2_CopyBlock(za, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(pKE), IPP_SM3_DIGEST_BYTESIZE); + /* copy Zb(2) */ + cpSM2_CopyBlock(zb, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(pKE), IPP_SM3_DIGEST_BYTESIZE); + /* xa || ya || xb || yb - is exists */ + + const int sizeS_SM3 = elemBytes + 2 * IPP_SM3_DIGEST_BYTESIZE + 4 * elemBytes; /* 224 bytes */ + + /* copy to next operation */ + cpSM2KE_compute_hash_SM3(EC_SM2_KEY_EXCH_PRECOM_HASH(pKE), pBuff, sizeS_SM3); + + if ((NULL != pSSelf) && (ippStsNoErr == sts)) { + /* 6) S(a/b) = SM3( 0x0(3/2) || y(u/v) || tmp_p ) */ + /* copy 0x0(3/2) */ + pBuff[0] = firstNum; + /* copy y(u/v) */ + cpSM2_CopyBlock(pBuff + 1, (const Ipp8u *)EC_SM2_KEY_EXCH_POINT_Y(pKE), elemBytes); + /* copy tmp_p */ + cpSM2_CopyBlock(pBuff + 1 + elemBytes, EC_SM2_KEY_EXCH_PRECOM_HASH(pKE), IPP_SM3_DIGEST_BYTESIZE); + + const int sizeSab_SM3 = 1 + elemBytes + IPP_SM3_DIGEST_BYTESIZE; /* 65 bytes */ + cpSM2KE_compute_hash_SM3(pSSelf, pBuff, sizeSab_SM3); + } + + /* compute KDF */ + /* 7) K(a/b) = KDF(x(u/v) || y(u/v) || Za || Zb, klen) */ + /* copy x(u/v)(0)*/ + cpSM2_CopyBlock(xuv, (const Ipp8u *)EC_SM2_KEY_EXCH_POINT_X(pKE), elemBytes); /* slot x(u/v)(0) */ + /* copy y(u/v)(1) */ + cpSM2_CopyBlock(za, (const Ipp8u *)EC_SM2_KEY_EXCH_POINT_Y(pKE), elemBytes); /* slot Za(1) */ + /* copy Za(2) */ + cpSM2_CopyBlock(zb, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(pKE), IPP_SM3_DIGEST_BYTESIZE); /* slot Zb(2) */ + /* copy Zb(3) */ + cpSM2_CopyBlock(xa, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(pKE), IPP_SM3_DIGEST_BYTESIZE); /* slot xa(3) */ + + const int sizeKab_KDF = 2 * elemBytes + 2 * IPP_SM3_DIGEST_BYTESIZE; /* 128 bytes */ + + /* set pointer start */ + pBuff = (Ipp8u *)pDataBuff; + + /* compute KDF */ + KDF_sm3(pSharedKey, sharedKeySize, (const Ipp8u *)pBuff, sizeKab_KDF); + + cpGFpReleasePool(7, pME); + /* clear Ephemeral Private Key */ + cpBN_zero(pEphPrvKey); + /* clear secret register */ + PurgeBlock(&r, sizeof(r)); + PurgeBlock(&d, sizeof(d)); + + return sts; +} + +#endif // (_IPP32E >= _IPP32E_K1) diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_decrypt_ext.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_decrypt_ext.c new file mode 100644 index 000000000..94c5272b7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_decrypt_ext.c @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_stuff.h" + +#define CHECK_PRIVATE_KEY(KEY) \ + IPP_BAD_PTR1_RET((KEY)) \ + IPP_BADARG_RET(!BN_VALID_ID((KEY)), ippStsContextMatchErr) \ + IPP_BADARG_RET(BN_NEGATIVE((KEY)), ippStsInvalidPrivateKey) \ + /* test if 0 < pPrivateA < Order */ \ + IPP_BADARG_RET(0 == gfec_CheckPrivateKey((KEY), pEC), ippStsInvalidPrivateKey) + +/** + * @brief + * Decryption message text based SM2 elliptic curve + * Implemenation based on standart: + * GM/T 0003.4-2012 SM2 + * Public key cryptographic algorithm SM2 based on elliptic curves + * Part 4: Public key encryption algorithm + * @param [out] pOut message decryption + * @param [in] maxOutLen available message size buffer + * @param [out] pOutSize message size fill container + * 0 - if the function ends with an error, + * other (>0) - if the function ends with OK + * @param [in] pInp pointer cipher text + * @param [in] inpLen cipher size + * @param [in] pPrvKey private key + * @param [in] pEC context elliptic curve + * @param [in] pScratchBuffer supported buffer + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pOut | pOutSize | pInp | pPrvKey | pEC | pScratchBuffer is NULL + * ippStsContextMatchErr - if pEC no valid ID | pEC no exists SUBGROUP + * ippStsNotSupportedModeErr - if pEC no supported (n|p) modulus arithmetic + * ippStsBadArgErr - if + * * maxOutLen < 0 + * * inpLen < (len(PC) + 2*len(x) + len(SM3)) + * ippStsInvalidPrivateKey - if test is failed 0 < pPrvKey < Order + * + */ +/* clang-format off */ +IPPFUN(IppStatus, ippsGFpECDecryptSM2_Ext, (Ipp8u *pOut, int maxOutLen, + int *pOutSize, + const Ipp8u *pInp, int inpLen, + const IppsBigNumState *pPrvKey, + IppsGFpECState *pEC, Ipp8u *pScratchBuffer)) +/* clang-format on */ +{ + + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemBytes = (elemBits + 7) / 8; /* size Bytes */ + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + /* buffer */ + IPP_BAD_PTR1_RET(pScratchBuffer) + + /* check cipher text */ + IPP_BAD_PTR1_RET(pInp) + /* size */ + const int ciph_PC_size = 1; + const int ciph_xy_size = 2 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize; + const int ciph_hash_size = IPP_SM3_DIGEST_BYTESIZE; + const int min_ciph_size = ciph_PC_size + ciph_xy_size + ciph_hash_size; + IPP_BADARG_RET(!(inpLen >= min_ciph_size), ippStsOutOfRangeErr) + + /* message */ + IPP_BAD_PTR1_RET(pOut) + /* the cipher text condition guarantees a positive or zero maxOutLen */ + const int ciph_msg_size = inpLen - min_ciph_size; + IPP_BADARG_RET(!(maxOutLen >= ciph_msg_size), ippStsOutOfRangeErr) + + /* out message size */ + IPP_BAD_PTR1_RET(pOutSize) + /* zeros */ + *pOutSize = 0; + + /* private key */ + CHECK_PRIVATE_KEY(pPrvKey) + + { + IppStatus sts = ippStsInvalidPoint; // pointer input if invalid -> status out + int finitPoint = 0; + + const Ipp8u *pC1_PC = pInp; + const Ipp8u *pC1_xy = pC1_PC + ciph_PC_size; + const Ipp8u *pC3 = pC1_xy + ciph_xy_size; + const Ipp8u *pC2 = pC3 + ciph_hash_size; + + IppsGFpECPoint R; + cpEcGFpInitPoint(&R, cpEcGFpGetPool(1, pEC), 0, pEC); + /* step1: extract C1 from C */ + BNU_CHUNK_T *pBuff = cpGFpGetPool(2, pME); + BNU_CHUNK_T *pC1_x = pBuff; + BNU_CHUNK_T *pC1_y = pC1_x + elemSize; + + /* copy coordinate point */ + COPY_BNU(pC1_x, (BNU_CHUNK_T *)(pC1_xy), elemSize); + COPY_BNU(pC1_y, (BNU_CHUNK_T *)(pC1_xy + elemBytes), elemSize); + /* convert big endian -> little endian */ + cpSM2KE_reverse_inplace((Ipp8u *)pC1_x, elemBytes); + cpSM2KE_reverse_inplace((Ipp8u *)pC1_y, elemBytes); + /* convert to Montgomery */ + GFP_METHOD(pME)->encode(pC1_x, pC1_x, pME); + GFP_METHOD(pME)->encode(pC1_y, pC1_y, pME); + + /* step 2 (standart) - check valid input coordinate x|y */ + finitPoint = gfec_SetPoint(ECP_POINT_DATA(&R), pC1_x, pC1_y, pEC); + ECP_POINT_FLAGS(&R) = finitPoint ? (ECP_AFFINE_POINT | ECP_FINITE_POINT) : 0; + + if (finitPoint && (0 != gfec_IsPointOnCurve(&R, pEC))) { + sts = ippStsNoErr; + /* step 3 (standart): [db]C1 = (x2,y2) */ + ippsGFpECMulPoint(&R, pPrvKey, &R, pEC, pScratchBuffer); + + BNU_CHUNK_T *pX = pBuff; + BNU_CHUNK_T *pY = pX + elemSize; + + gfec_GetPoint(pX, pY, &R, pEC); + GFP_METHOD(pME)->decode(pX, pX, pME); + GFP_METHOD(pME)->decode(pY, pY, pME); + + cpSM2KE_reverse_inplace((Ipp8u *)pX, elemBytes); + cpSM2KE_reverse_inplace((Ipp8u *)pY, elemBytes); + + /* step 4 (standart): t = KDF(x2 || y2, klen) */ + KDF_sm3(pOut, ciph_msg_size, (Ipp8u *)pBuff, 2 * elemBytes); + + /* step 5 (standart): M` = C2 (x) t */ + for (int i = 0; i < ciph_msg_size; ++i) { + pOut[i] = pOut[i] ^ pC2[i]; + } + + /* step 6 (standart): u = Hash(x2 || M` || y2) */ + static IppsHashState_rmf ctx; + + Ipp8u u[IPP_SM3_DIGEST_BYTESIZE]; + ippsHashInit_rmf(&ctx, ippsHashMethod_SM3()); + /* x2 */ + ippsHashUpdate_rmf((Ipp8u *)pX, elemBytes, &ctx); + /* M */ + ippsHashUpdate_rmf(pOut, ciph_msg_size, &ctx); + /* y2 */ + ippsHashUpdate_rmf((Ipp8u *)pY, elemBytes, &ctx); + /* C3 */ + ippsHashFinal_rmf(u, &ctx); + + if (0 == EquBlock(u, pC3, IPP_SM3_DIGEST_BYTESIZE)) { + PurgeBlock(pOut, ciph_msg_size); + } else { + *pOutSize = ciph_msg_size; + } + + PurgeBlock(u, IPP_SM3_DIGEST_BYTESIZE); + } + + cpGFpReleasePool(2, pME); + cpEcGFpReleasePool(1, pEC); /* release R from the pool */ + return sts; + } +} + +#undef CHECK_PRIVATE_KEY diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_decrypt_ext_dec_msg_size.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_decrypt_ext_dec_msg_size.c new file mode 100644 index 000000000..995b02f8e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_decrypt_ext_dec_msg_size.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_stuff.h" + +/** + * @brief ippsGFpECDecryptSM2_Ext_DecMsgSize + * Get Message Size data by Decrypt SM2 + * Implemenation based on standart: + * GM/T 0003.4-2012 SM2 + * Public key cryptographic algorithm SM2 based on elliptic curves + * Part 4: Public key encryption algorithm + * @param [in] pEC Context Elliptic Curve + * @param [in] ctMsgSize cipher size + * @param [out] pSize size allocation bytes by Key Exchange Context + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC or pSize is NULL + * ippStsContextMatchErr - if pEC no valid ID or no exists SUBGROUP + * ippStsBagArgErr - if cipher < 0 or ctMsgSize - (C1 + C3) < 0 + */ +IPPFUN(IppStatus, ippsGFpECDecryptSM2_Ext_DecMsgSize, (const IppsGFpECState *pEC, int ctMsgSize, int *pSize)) +{ + /* check Context Elliptic Curve */ + IPP_BAD_PTR2_RET(pEC, pSize); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + /* check chiper size */ + IPP_BADARG_RET(!(ctMsgSize >= 0), ippStsOutOfRangeErr) + const int ciph_PC_size = 1; + const int ciph_xy_size = 2 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize; + const int ciph_hash_size = IPP_SM3_DIGEST_BYTESIZE; + + const int size = ctMsgSize - (ciph_PC_size + ciph_xy_size + ciph_hash_size); + + /* if size < 0 -> pSize = 0 + call ippStsBadArgErr */ + *pSize = 0; + IPP_BADARG_RET(!(size >= 0), ippStsOutOfRangeErr) + + *pSize = size; + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_encrypt_ext.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_encrypt_ext.c new file mode 100644 index 000000000..ab5949c5e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_encrypt_ext.c @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_stuff.h" + +#define CHECK_PUBLIC_KEY(KEY) \ + IPP_BAD_PTR1_RET((KEY)) \ + IPP_BADARG_RET(!ECP_POINT_VALID_ID((KEY)), ippStsContextMatchErr) \ + IPP_BADARG_RET(ECP_POINT_FELEN((KEY)) != GFP_FELEN(pME), ippStsOutOfRangeErr) \ + IPP_BADARG_RET(0 == gfec_IsPointOnCurve((KEY), pEC), ippStsInvalidPoint) + +#define CHECK_PRIVATE_KEY(KEY) \ + IPP_BAD_PTR1_RET((KEY)) \ + IPP_BADARG_RET(!BN_VALID_ID((KEY)), ippStsContextMatchErr) \ + IPP_BADARG_RET(BN_NEGATIVE((KEY)), ippStsInvalidPrivateKey) \ + /* test if 0 < pPrivateA < Order */ \ + IPP_BADARG_RET(0 == gfec_CheckPrivateKey((KEY), pEC), ippStsInvalidPrivateKey) + +/** + * @brief + * Encryption message text based SM2 elliptic curve + * Implemenation based on standart: + * GM/T 0003.4-2012 SM2 + * Public key cryptographic algorithm SM2 based on elliptic curves + * Part 4: Public key encryption algorithm + * @param [out] pOut pointer output cipher text + * @param [in] maxOutLen available cipher size container + * @param [out] pOutSize size of the ciphertext filled in the container + * 0 - if the function ends with an error, + * other (>0) - if the function ends with OK + * @param [in] pInp pointer message encrypt + * @param [in] inpLen message size encrypt + * @param [in] pPublicKey public key + * @param [in out] pEhpPublicKey (!) will be cleared at the end (!) Ephemeral Public Key + * @param [in out] pEphPrvKey (!) will be cleared at the end (!) Ephemeral Private Key + * @param [in] pEC context elliptic curve + * @param [in] pScratchBuffer supported buffer + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if + * pEC | pScratchBuffer | pInp | pOut | pOutSize | pPublicKey | pEphPublicKey | pEphPrvKey + * is NULL + * ippStsContextMatchErr - if pEC no valid ID | pEC no exists SUBGROUP + * ippStsNotSupportedModeErr - if pEC no supported (n|p) modulus arithmetic + * ippStsBadArgErr - if + * * inpLen < 0 + * * maxOutLen < (len(PC) + 2*len(x) + len(SM3)) + * ippStsInvalidPrivateKey - if test is failed 0 < pEphPrvKey < Order + * ippStsInvalidPoint - if no in curve Pub Key and Ephemeral Public Key + */ +/* clang-format off */ +IPPFUN(IppStatus, ippsGFpECEncryptSM2_Ext, (Ipp8u *pOut, int maxOutLen, + int *pOutSize, + const Ipp8u *pInp, int inpLen, + const IppsGFpECPoint *pPublicKey, + IppsGFpECPoint *pEphPublicKey, IppsBigNumState *pEphPrvKey, + IppsGFpECState *pEC, Ipp8u *pScratchBuffer)) +/* clang-format on */ +{ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemBytes = (elemBits + 7) / 8; /* size Bytes */ + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + /* buffer */ + IPP_BAD_PTR1_RET(pScratchBuffer) + + /* check msg size */ + IPP_BAD_PTR1_RET(pInp) + /* check size */ + IPP_BADARG_RET(!(inpLen >= 0), ippStsOutOfRangeErr) + + /* chiper text */ + IPP_BAD_PTR2_RET(pOut, pOutSize) + /* init zeros out cipher text */ + *pOutSize = 0; + /* check size */ + const int ciph_PC_size = 1; + const int ciph_xy_size = (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize * 2; + const int ciph_hash_size = IPP_SM3_DIGEST_BYTESIZE; + const int ciph_msg_size = inpLen; + IPP_BADARG_RET(!(maxOutLen >= (ciph_PC_size + ciph_xy_size + ciph_msg_size + ciph_hash_size)), ippStsOutOfRangeErr) + + /* check Public | Private key */ + /* private */ + CHECK_PRIVATE_KEY(pEphPrvKey) + /* public */ + /* step 3: S = [h]Pb -> if Pb valid point and h != 0 -> S valid */ + CHECK_PUBLIC_KEY(pPublicKey) + CHECK_PUBLIC_KEY(pEphPublicKey) + + /* check that user's Ephemeral Public and Private Keys are related (C1=[k]G) */ + IppsGFpECPoint pTmpPoint; + cpEcGFpInitPoint(&pTmpPoint, cpEcGFpGetPool(1, pEC), 0, pEC); + ippsGFpECPublicKey(pEphPrvKey, &pTmpPoint, pEC, pScratchBuffer); // k*G + int result = gfec_ComparePoint(&pTmpPoint, pEphPublicKey, pEC); // C1 == [k]G ? + cpEcGFpReleasePool(1, pEC); // Release pool before the possible exit + IPP_BADARG_RET(!result, ippStsEphemeralKeyErr); + + { + IppStatus sts = ippStsNoErr; + /* init pointer C = C1 || C2 || C3 */ + Ipp8u *pC1_PC = pOut; + Ipp8u *pC1_xy = pC1_PC + ciph_PC_size; + Ipp8u *pC3 = pC1_xy + ciph_xy_size; + Ipp8u *pC2 = pC3 + ciph_hash_size; + + /* point elliptic curve */ + IppsGFpECPoint R; + cpEcGFpInitPoint(&R, cpEcGFpGetPool(1, pEC), 0, pEC); + BNU_CHUNK_T *pX = NULL; + BNU_CHUNK_T *pY = NULL; + + /* step 2: C1 = PC || x1 || y1 */ + pC1_PC[0] = 0x04; + + pX = (BNU_CHUNK_T *)(pC1_xy); + pY = pX + elemSize; + + gfec_GetPoint(pX, pY, pEphPublicKey, pEC); + GFP_METHOD(pME)->decode(pX, pX, pME); + GFP_METHOD(pME)->decode(pY, pY, pME); + cpSM2KE_reverse_inplace((Ipp8u *)pX, elemBytes); + cpSM2KE_reverse_inplace((Ipp8u *)pY, elemBytes); + + /* step 4: [k]Pb = (x2,y2) */ + ippsGFpECMulPoint(pPublicKey, pEphPrvKey, &R, pEC, pScratchBuffer); + /* step 5: t = KDF(x2||y2, klen) */ + BNU_CHUNK_T *pBuff = cpGFpGetPool(2, pME); + + pX = pBuff; + pY = pX + elemSize; + + gfec_GetPoint(pX, pY, &R, pEC); + GFP_METHOD(pME)->decode(pX, pX, pME); + GFP_METHOD(pME)->decode(pY, pY, pME); + + cpSM2KE_reverse_inplace((Ipp8u *)pX, elemBytes); + cpSM2KE_reverse_inplace((Ipp8u *)pY, elemBytes); + + KDF_sm3(pC2, ciph_msg_size, (Ipp8u *)pBuff, 2 * elemBytes); + + /* step 6: C2 = M (x) t */ + for (int i = 0; i < ciph_msg_size; ++i) { + pC2[i] = pC2[i] ^ pInp[i]; + } + + /* step 7: C3 = Hash(x2 || M || y2) */ + static IppsHashState_rmf ctx; + + ippsHashInit_rmf(&ctx, ippsHashMethod_SM3()); + /* x2 */ + ippsHashUpdate_rmf((Ipp8u *)pX, elemBytes, &ctx); + /* M */ + ippsHashUpdate_rmf(pInp, ciph_msg_size, &ctx); + /* y2 */ + ippsHashUpdate_rmf((Ipp8u *)pY, elemBytes, &ctx); + /* C3 */ + ippsHashFinal_rmf(pC3, &ctx); + + /* set output size data */ + if (sts == ippStsNoErr) { + *pOutSize = ciph_PC_size + ciph_xy_size + ciph_msg_size + ciph_hash_size; + } + /* zeros Public | Private Key */ + cpBN_zero(pEphPrvKey); + gfec_SetPointAtInfinity(pEphPublicKey); + + cpGFpReleasePool(2, pME); + cpEcGFpReleasePool(1, pEC); /* release R from the pool */ + return sts; + } +} + +#undef CHECK_PRIVATE_KEY +#undef CHECK_PUBLIC_KEY diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_encrypt_ext_enc_msg_size.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_encrypt_ext_enc_msg_size.c new file mode 100644 index 000000000..2d153fc7e --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_encrypt_ext_enc_msg_size.c @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_stuff.h" + +/** + * @brief ippsGFpECEncryptSM2_Ext_EncMsgSize + * Implemenation based on standart: + * GM/T 0003.4-2012 SM2 + * Public key cryptographic algorithm SM2 based on elliptic curves + * Part 4: Public key encryption algorithm + * Get Cipher Size data by Encrypt SM2 + * @param [in] pEC Context Elliptic Curve + * @param [in] ctMsgSize chipher text message size + * @param [out] pSize size allocation bytes by Key Exchange Context + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC or pSize is NULL + * ippStsContextMatchErr - if pEC no valid ID or no exists SUBGROUP + * ippStsBagArgErr - if message size < 0 + */ +IPPFUN(IppStatus, ippsGFpECEncryptSM2_Ext_EncMsgSize, (const IppsGFpECState *pEC, int ctMsgSize, int *pSize)) +{ + /* check Context Elliptic Curve */ + IPP_BAD_PTR2_RET(pEC, pSize); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + /* check message size */ + IPP_BADARG_RET(!(ctMsgSize >= 0), ippStsOutOfRangeErr) + + { + const int ciph_PC_size = 1; + const int ciph_xy_size = 2 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize; + const int ciph_hash_size = IPP_SM3_DIGEST_BYTESIZE; + const int ciph_msg_size = ctMsgSize; + + const int size = ciph_PC_size /* PC */ + + ciph_xy_size /* Point (x,y) */ + + ciph_hash_size /* SM3 */ + + ciph_msg_size; /* message size */ + + *pSize = size; + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_confirmation.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_confirmation.c new file mode 100644 index 000000000..cb71039af --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_confirmation.c @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_key_exchange_method.h" +#include "sm2/sm2_stuff.h" + +/** + * @brief ippsGFpECKeyExchangeSM2_Confirm + * this step Optional in protocol SM2 Key Exchange - Confirmation Peer data + * see standart: + * [GBT.32918.3-2016] Public Key cryptographic algorithm SM2 based on elliptic curves + * Part 3: Key exchange protocol + * 6.2 Process of key exchange protocol + * stack compute[standart link]: + * [user A| user B] + * 8) S(1/2) = SM3( 0x0(2/3) || y(u/v) || tmp_p ) [step 9| step 10] + * when tmp_p - precomute in SharedKey step + * @param [in] pSPeer S(b/a) peer data confirmation + * @param [out] pStatus status confirmation + * 1 is succsessfull or 0 is bad confirmation + * @param [in] pKE constrex Key Excange + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC | pKE | pSPeer | pStatus is NULL + * ippStsContextMatchErr - if pEC no valid ID | pEC no exists SUBGROUP + * ippStsNotSupportedModeErr - if pEC no supported (n|p) modulus arithmetic + * ippStsRangeErr - if BitSize(pEC) < IPP_SM3_DIGEST_BITSIZE + * ippStsBadArgErr - if role(pKE) no equal ippKESM2Requester|ippKESM2Responder + */ +/* clang-format off */ +IPPFUN(IppStatus, ippsGFpECKeyExchangeSM2_Confirm, (const Ipp8u pSPeer[IPP_SM3_DIGEST_BYTESIZE], + int* pStatus, + IppsGFpECKeyExchangeSM2State* pKE)) +/* clang-format on */ +{ + /* check Key Exchange */ + IPP_BAD_PTR1_RET(pKE); + /* check id */ + IPP_BADARG_RET(!EC_SM2_KEY_EXCH_VALID_ID(pKE), ippStsContextMatchErr); + /* check User Role */ + const IppsKeyExchangeRoleSM2 role = EC_SM2_KEY_EXCH_ROLE(pKE); + IPP_BADARG_RET(((ippKESM2Requester != role) && (ippKESM2Responder != role)), ippStsBadArgErr); + + /* check Elliptic Curve */ + IppsGFpECState *pEC = EC_SM2_KEY_EXCH_EC(pKE); + + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + /* check bitsize >= SM3_DIGSET */ + IPP_BADARG_RET(!(ECP_ORDBITSIZE(pEC) >= IPP_SM3_DIGEST_BITSIZE), ippStsRangeErr); + + /* check call Setup */ + /* check init Public Key | Ephemeral Public Key */ + IPP_BADARG_RET( NULL == EC_SM2_KEY_EXCH_PUB_KEY_USER_A(pKE) || + NULL == EC_SM2_KEY_EXCH_PUB_KEY_USER_B(pKE) || + NULL == EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE) || + NULL == EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE), ippStsContextMatchErr) + + /* check pSPeer */ + IPP_BAD_PTR1_RET(pSPeer); + + /* check status */ + IPP_BAD_PTR1_RET(pStatus); + + + const Ipp8u firstNum = (ippKESM2Requester == role) ? 0x02 : 0x03; + + { + /* extract data Elliptic Curve */ + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemBytes = (elemBits + 7) / 8; /* size Bytes */ + + /* buffer */ + BNU_CHUNK_T *pDataBuff = cpGFpGetPool(3, pME); + Ipp8u *pBuff = (Ipp8u *)pDataBuff; + + /* 8) S(1/2) = SM3( 0x0(2/3) || y(u/v) || tmp_p ) */ + /* copy 0x0(2/3) */ + pBuff[0] = firstNum; /* set first number (role) */ + /* copy y(u/v) */ + cpSM2_CopyBlock(pBuff + 1, (const Ipp8u *)EC_SM2_KEY_EXCH_POINT_Y(pKE), elemBytes); + /* copy Precomp Hash */ + cpSM2_CopyBlock(pBuff + 1 + elemBytes, (const Ipp8u *)EC_SM2_KEY_EXCH_PRECOM_HASH(pKE), IPP_SM3_DIGEST_BYTESIZE); + + const int sizeSab_SM3 = 1 + elemBytes + IPP_SM3_DIGEST_BYTESIZE; + cpSM2KE_compute_hash_SM3(pBuff, pBuff, sizeSab_SM3); + + /* pS == S(1/2) */ + *pStatus = EquBlock((Ipp8u *)pBuff, pSPeer, IPP_SM3_DIGEST_BYTESIZE) ? 1 : 0; + + cpGFpReleasePool(3, pME); + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_get_size.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_get_size.c new file mode 100644 index 000000000..871cf9ce7 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_get_size.c @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_key_exchange_method.h" +#include "sm2/sm2_stuff.h" + +/** + * @brief ippsGFpECKeyExchangeSM2_GetSize + * Get Size allocation bytes by Key Exchange Conntext + * @param [in] pEC Context Elliptic Curve + * @param [out] pSize size allocation bytes by Key Exchange Context + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC or pSize is NULL + * ippStsContextMatchErr - if pEC no valid ID or no exists SUBGROUP + */ +IPPFUN(IppStatus, ippsGFpECKeyExchangeSM2_GetSize, (const IppsGFpECState *pEC, int *pSize)) +{ + + IPP_BAD_PTR2_RET(pEC, pSize); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + { + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + const int size = (Ipp32s)sizeof(IppsGFpECKeyExchangeSM2State) /* Key Exchange SM2 struct */ + + (Ipp32s)sizeof(IppsGFpECPoint) + 3 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize /* User A Public Key + Data */ + + (Ipp32s)sizeof(IppsGFpECPoint) + 3 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize /* User B Public Key + Data */ + + (Ipp32s)sizeof(IppsGFpECPoint) + 3 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize /* User A Ephemeral Public Key + Data */ + + (Ipp32s)sizeof(IppsGFpECPoint) + 3 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize /* User B Ephemeral Public Key + Data */ + + (Ipp32s)sizeof(Ipp8u) * IPP_SM3_DIGEST_BYTESIZE /* Za [User A] */ + + (Ipp32s)sizeof(Ipp8u) * IPP_SM3_DIGEST_BYTESIZE /* Zb [User B] */ + + (Ipp32s)sizeof(Ipp8u) * IPP_SM3_DIGEST_BYTESIZE /* Precompute Hash */ + + (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize /* [U/V].x */ + + (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize; /* [U/V].y */ + + *pSize = size; + return ippStsNoErr; + } +} \ No newline at end of file diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_init.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_init.c new file mode 100644 index 000000000..12d0243e9 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_init.c @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_key_exchange_method.h" +#include "sm2/sm2_stuff.h" + +/** + * @brief ippsGFpECKeyExchangeSM2_Init + * initial Key Exchange Context + * see standart: + * [GBT.32918.3-2016] Public Key cryptographic algorithm SM2 based on elliptic curves + * Part 3: Key exchange protocol + * @param [out] pKE context Key Exchange + * @param [in] role User(A|B) role (ippKESM2Requester|ippKESM2Responder) + * @param [in] pEC conext Elliptic Curve + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC | pKE is NULL + * ippStsContextMatchErr - if pEC no valid ID or no exists SUBGROUP + * ippStsNotSupportedModeErr - if pEC no supported n or p modulus arithmetic + * ippStsRangeErr - if BitSize(pEC) < IPP_SM3_DIGEST_BITSIZE + * ippStsBadArgErr - if role no equal ippKESM2Requester|ippKESM2Responder + */ +IPPFUN(IppStatus, ippsGFpECKeyExchangeSM2_Init, (IppsGFpECKeyExchangeSM2State * pKE, IppsKeyExchangeRoleSM2 role, IppsGFpECState *pEC)) +{ + /* check Elliptic Curve */ + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + /* check support Mode arithmetic */ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + /* check bitsize >= SM3_DIGSET */ + IPP_BADARG_RET(!(ECP_ORDBITSIZE(pEC) >= IPP_SM3_DIGEST_BITSIZE), ippStsRangeErr); + + /* check Key Exchange */ + IPP_BAD_PTR1_RET(pKE); + + /* check User Role */ + IPP_BADARG_RET(((ippKESM2Requester != role) && (ippKESM2Responder != role)), ippStsBadArgErr); + + { + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + /* set id */ + EC_SM2_KEY_EXCH_SET_ID(pKE); + + /* set role [User A| User B] */ + EC_SM2_KEY_EXCH_ROLE(pKE) = role; + + /* set context EC */ + EC_SM2_KEY_EXCH_EC(pKE) = pEC; + + /* set zero pointer to public key */ + /* public key */ + EC_SM2_KEY_EXCH_PUB_KEY_USER_A(pKE) = NULL; + EC_SM2_KEY_EXCH_PUB_KEY_USER_B(pKE) = NULL; + /* ephemera key */ + EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE) = NULL; + EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE) = NULL; + + Ipp8u *ptr = (Ipp8u *)(pKE); + ptr += (Ipp32s)sizeof(IppsGFpECKeyExchangeSM2State); + + /* skip Public Key Space */ + ptr += 4 * ((Ipp32s)sizeof(IppsGFpECPoint) + 3 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize); + + /* set Za (user id hash) */ + EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(pKE) = ptr; + PurgeBlock(ptr, IPP_SM3_DIGEST_BYTESIZE); + ptr += IPP_SM3_DIGEST_BYTESIZE; + + /* set Zb (user id hash) */ + EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(pKE) = ptr; + PurgeBlock(ptr, IPP_SM3_DIGEST_BYTESIZE); + ptr += IPP_SM3_DIGEST_BYTESIZE; + + /* set Precompute Hash */ + EC_SM2_KEY_EXCH_PRECOM_HASH(pKE) = ptr; + PurgeBlock(ptr, IPP_SM3_DIGEST_BYTESIZE); + ptr += IPP_SM3_DIGEST_BYTESIZE; + + /* set Point(X,Y) */ + EC_SM2_KEY_EXCH_POINT_PTR(pKE) = (BNU_CHUNK_T *)ptr; + + ZEXPAND_BNU(EC_SM2_KEY_EXCH_POINT_X(pKE), 0, elemSize); + ZEXPAND_BNU(EC_SM2_KEY_EXCH_POINT_Y(pKE), 0, elemSize); + + return ippStsNoErr; + } +} diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_method.h b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_method.h new file mode 100644 index 000000000..29655d538 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_method.h @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ +#ifndef _SM2_KEY_EXCHANGE_METHOD_H_ +#define _SM2_KEY_EXCHANGE_METHOD_H_ + +#include "owncp.h" +#include "pcpbnuimpl.h" +#include "pcpgfpecstuff.h" + +/* +// EC over GF(p) Key Exchange SM2 context +*/ +typedef struct _GFpECKeyExchangeSM2 { + Ipp32u idCtx; /* context identifier */ + IppsKeyExchangeRoleSM2 role; /* role User A(request) or B(response) */ + IppsGFpECState *pEC; /* Elliptic Curve data context */ + IppsGFpECPoint *pPubKeyReqA; /* Pa[User A] - Public Key */ + IppsGFpECPoint *pPubKeyRespB; /* Pb[User B] - Public Key */ + IppsGFpECPoint *pEphPubKeyReqA; /* Ra[User A] - Ephemeral Public Key */ + IppsGFpECPoint *pEphPubKeyRespB; /* Rb[User B] - Ephemeral Public Key */ + Ipp8u *pZReqA; /* Za[User A] - User ID Hash */ + Ipp8u *pZRespB; /* Zb[User B] - User ID Hash */ + Ipp8u *pPrecHash; /* Precompute Hash - SM3( x(u/v) || Za || Zb || xa || ya || xb || yb ) */ + BNU_CHUNK_T *pPointXYBigEndian; /* U/V */ +} GFpECKeyExchangeSM2; + + +/* +// Context Access Macros +*/ +/* clang-format off */ +#define EC_SM2_KEY_EXCH_ID(ctx) ((ctx)->idCtx) +#define EC_SM2_KEY_EXCH_SET_ID(ctx) (EC_SM2_KEY_EXCH_ID(ctx) = (Ipp32u)idCtxGFPECKE ^ (Ipp32u)IPP_UINT_PTR(ctx)) +#define EC_SM2_KEY_EXCH_VALID_ID(ctx) ((EC_SM2_KEY_EXCH_ID(ctx) ^ (Ipp32u)IPP_UINT_PTR(ctx)) == (Ipp32u)idCtxGFPECKE) +#define EC_SM2_KEY_EXCH_ROLE(ctx) ((ctx)->role) +#define EC_SM2_KEY_EXCH_EC(ctx) ((ctx)->pEC) +#define EC_SM2_KEY_EXCH_PUB_KEY_USER_A(ctx) ((ctx)->pPubKeyReqA) +#define EC_SM2_KEY_EXCH_PUB_KEY_USER_B(ctx) ((ctx)->pPubKeyRespB) +#define EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(ctx) ((ctx)->pEphPubKeyReqA) +#define EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(ctx) ((ctx)->pEphPubKeyRespB) +#define EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(ctx) ((ctx)->pZReqA) +#define EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(ctx) ((ctx)->pZRespB) +#define EC_SM2_KEY_EXCH_PRECOM_HASH(ctx) ((ctx)->pPrecHash) +#define EC_SM2_KEY_EXCH_POINT_PTR(ctx) ((ctx)->pPointXYBigEndian) +#define EC_SM2_KEY_EXCH_POINT_X(ctx) ((ctx)->pPointXYBigEndian) +#define EC_SM2_KEY_EXCH_POINT_Y(ctx) ((ctx)->pPointXYBigEndian + GFP_FELEN(GFP_PMA(ECP_GFP(EC_SM2_KEY_EXCH_EC(ctx)))) ) +/* clang-format on */ + +#endif // _SM2_KEY_EXCHANGE_METHOD_H_ diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_setup.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_setup.c new file mode 100644 index 000000000..10b229e60 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_setup.c @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "pcpgfpecstuff.h" +#include "sm2/sm2_key_exchange_method.h" +#include "sm2/sm2_stuff.h" + +#define CHECK_PUBLIC_KEY(KEY) \ + IPP_BAD_PTR1_RET((KEY)) \ + IPP_BADARG_RET(!ECP_POINT_VALID_ID((KEY)), ippStsContextMatchErr) \ + IPP_BADARG_RET(ECP_POINT_FELEN((KEY)) != GFP_FELEN(pME), ippStsOutOfRangeErr) \ + IPP_BADARG_RET(0 == gfec_IsPointOnCurve((KEY), pEC), ippStsInvalidPoint) + + +/** + * @brief ippsGFpECKeyExchangeSM2_Setup + * setup Key Exchange Context (add Za | Zb | Pa | Pb | Ra | Rb) + * see standart: + * [GBT.32918.3-2016] Public Key cryptographic algorithm SM2 based on elliptic curves + * Part 3: Key exchange protocol + * @param [in] pZSelf (self) user ID hash Z (copy) + * @param [in] pZPeer (peer) user ID hash Z (copy) + * @param [in] pPublicKeySelf (self) public key (copy) + * @param [in] pPublicKeyPeer (peer) public key (copy) + * @param [in] pEphPublicKeySelf (self) ephemeral public key (copy) + * @param [in] pEphPublicKeyPeer (peer) ephemeral public key (copy) + * @param [out] pKE constext + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC | pKE is NULL + * ippStsContextMatchErr - if pEC no valid ID | pEC no exists SUBGROUP + * ippStsNotSupportedModeErr - if pEC no supported (n|p) modulus arithmetic + * ippStsRangeErr - if BitSize(pEC) < IPP_SM3_DIGEST_BITSIZE + * ippStsBadArgErr - if role(pKE) no equal ippKESM2Requester|ippKESM2Responder + * ippStsInvalidPoint - if no in curve Pub Key (User A|B) | Eph Pub Key (User A|B) + */ +/* clang-format off */ +IPPFUN(IppStatus, ippsGFpECKeyExchangeSM2_Setup, (const Ipp8u pZSelf[IPP_SM3_DIGEST_BYTESIZE], + const Ipp8u pZPeer[IPP_SM3_DIGEST_BYTESIZE], + const IppsGFpECPoint *pPublicKeySelf, + const IppsGFpECPoint *pPublicKeyPeer, + const IppsGFpECPoint *pEphPublicKeySelf, + const IppsGFpECPoint *pEphPublicKeyPeer, + IppsGFpECKeyExchangeSM2State *pKE)) +/* clang-format on */ +{ + /* check Key Exchange */ + IPP_BAD_PTR1_RET(pKE); + /* check id */ + IPP_BADARG_RET(!EC_SM2_KEY_EXCH_VALID_ID(pKE), ippStsContextMatchErr); + /* check User Role */ + const IppsKeyExchangeRoleSM2 role = EC_SM2_KEY_EXCH_ROLE(pKE); + IPP_BADARG_RET(((ippKESM2Requester != role) && (ippKESM2Responder != role)), ippStsBadArgErr); + + /* check Za | Zb */ + IPP_BAD_PTR2_RET(pZSelf, pZPeer); + + /* check Elliptic Curve */ + IppsGFpECState *pEC = EC_SM2_KEY_EXCH_EC(pKE); + + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + /* check bitsize >= SM3_DIGSET */ + IPP_BADARG_RET(!(ECP_ORDBITSIZE(pEC) >= IPP_SM3_DIGEST_BITSIZE), ippStsRangeErr); + + /* check data User A */ + /* public and ephemeral public key */ + CHECK_PUBLIC_KEY(pPublicKeySelf) + CHECK_PUBLIC_KEY(pEphPublicKeySelf) + + /* check data User B */ + /* public and ephemeral public key */ + CHECK_PUBLIC_KEY(pPublicKeyPeer) + CHECK_PUBLIC_KEY(pEphPublicKeyPeer) + + { + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + /* init pointer copy User A|B */ + Ipp8u *pCopyZSelf = (ippKESM2Requester == role) ? EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(pKE) : EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(pKE); + Ipp8u *pCopyZPeer = (ippKESM2Requester == role) ? EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(pKE) : EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(pKE); + /* copy Za and Zb */ + cpSM2_CopyBlock(pCopyZSelf, pZSelf, IPP_SM3_DIGEST_BYTESIZE); + cpSM2_CopyBlock(pCopyZPeer, pZPeer, IPP_SM3_DIGEST_BYTESIZE); + + /* init ptr pointer */ + /* User A */ + const IppsGFpECPoint *loc_pub_key_user_a = (ippKESM2Requester == role) ? pPublicKeySelf : pPublicKeyPeer; + const IppsGFpECPoint *loc_eph_pub_key_user_a = (ippKESM2Requester == role) ? pEphPublicKeySelf : pEphPublicKeyPeer; + /* User B */ + const IppsGFpECPoint *loc_pub_key_user_b = (ippKESM2Requester == role) ? pPublicKeyPeer : pPublicKeySelf; + const IppsGFpECPoint *loc_eph_pub_key_user_b = (ippKESM2Requester == role) ? pEphPublicKeyPeer : pEphPublicKeySelf; + /* Copy Pointer User A|B */ + const Ipp32s size_struct_point = (Ipp32s)sizeof(IppsGFpECPoint); + const Ipp32s size_data_point = 3 * (Ipp32s)sizeof(BNU_CHUNK_T) * elemSize; + + Ipp8u *ptr = (Ipp8u *)(pKE) + sizeof(IppsGFpECKeyExchangeSM2State); + + /* Public key User A */ + EC_SM2_KEY_EXCH_PUB_KEY_USER_A(pKE) = (IppsGFpECPoint *)ptr; + ptr += size_struct_point; + cpSM2KE_CopyPointData(EC_SM2_KEY_EXCH_PUB_KEY_USER_A(pKE), (BNU_CHUNK_T *)ptr, loc_pub_key_user_a, pEC); + ptr += size_data_point; + /* Ephemeral Public Key User A */ + EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE) = (IppsGFpECPoint *)ptr; + ptr += size_struct_point; + cpSM2KE_CopyPointData(EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE), (BNU_CHUNK_T *)ptr, loc_eph_pub_key_user_a, pEC); + ptr += size_data_point; + /* Public key User B */ + EC_SM2_KEY_EXCH_PUB_KEY_USER_B(pKE) = (IppsGFpECPoint *)ptr; + ptr += size_struct_point; + cpSM2KE_CopyPointData(EC_SM2_KEY_EXCH_PUB_KEY_USER_B(pKE), (BNU_CHUNK_T *)ptr, loc_pub_key_user_b, pEC); + ptr += size_data_point; + /* Ephemeral Public Key User B */ + EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE) = (IppsGFpECPoint *)ptr; + ptr += size_struct_point; + cpSM2KE_CopyPointData(EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE), (BNU_CHUNK_T *)ptr, loc_eph_pub_key_user_b, pEC); + + return ippStsNoErr; + } +} + +#undef CHECK_PUBLIC_KEY diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_shared_key.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_shared_key.c new file mode 100644 index 000000000..c805f304a --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_key_exchange_shared_key.c @@ -0,0 +1,310 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owncp.h" +#include "owndefs.h" +#include "sm2/sm2_key_exchange_method.h" +#include "sm2/sm2_stuff.h" + +#define CHECK_PRIVATE_KEY(KEY) \ + IPP_BAD_PTR1_RET((KEY)) \ + IPP_BADARG_RET(!BN_VALID_ID((KEY)), ippStsContextMatchErr) \ + IPP_BADARG_RET(BN_NEGATIVE((KEY)), ippStsInvalidPrivateKey) \ + /* test if 0 < pPrivateA < Order */ \ + IPP_BADARG_RET(0 == gfec_CheckPrivateKey((KEY), pEC), ippStsInvalidPrivateKey) + +/** + * @brief ippsGFpECKeyExchangeSM2_SharedKey + * compute x(u/v) | y(u/v) | precomHash | shared key + * see standart: + * [GBT.32918.3-2016] Public Key cryptographic algorithm SM2 based on elliptic curves + * Part 3: Key exchange protocol + * 6.2 Process of key exchange protocol + * stack compute[standart link]: + * [user A| user B] + * 2) x(a/b)` = 2^w + (x(a/b) & (2^w – 1)) [step 4| step 3] + * 3) t(a/b) = (d(a/b) + x(a/b)`*r(a/b) ) mod n [step 5| step 4] + * 4) x(b/a)` = 2^w + ( x(b/a) & (2^w – 1) ) [step 6| step 5] + * 5) U/V = [h*t(a/b)]( P(b/a) + [x(b/a)`]R(b/a) ) = ( x(u/v), y(u/v) ) [step 7| step 6] + * tmp_p = SM3( x(u/v) || Za || Zb || xa || ya || xb || yb ) + * 6) S(a/b) = SM3( 0x0(3/2) || y(u/v) || tmp_p ) [step 10| step 8] + * 7) K(a/b) = KDF(x(u/v) || y(u/v) || Za || Zb, klen) [step 8| step 7] + * @param [out] pSharedKey shared key [K(a/b) = KDF(x(u/v) || y(u/v) || Za || Zb, klen)] + * @param [in] sharedKeySize length shared key + * @param [out] pSSelf (may be == NULL) self data confirmation + * @param [in] pPrvKey private key + * @param [in] pEphPrvKey ephemeral private key (!) will be cleared at the end if function successfully competed (!) + * @param [out] pKE context Key Exchange (save x(u/v) | y(u/v) | precompHash ) + * @param [in] pScratchBuffer supported buffer + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC | pKE | pSharedKey | pPrvKey | PEphPrvKey | pSB is NULL + * ippStsContextMatchErr - if pEC no valid ID | pEC no exists SUBGROUP + * ippStsNotSupportedModeErr - if pEC no supported (n|p) modulus arithmetic + * ippStsRangeErr - if BitSize(pEC) < IPP_SM3_DIGEST_BITSIZE + * ippStsBadArgErr - if role(pKE) no equal ippKESM2Requester|ippKESM2Responder or sharedKeySize <= 0 + * ippStsInvalidPrivateKey - if test is failed 0 < pPrvKey|pEphPrvKey < Order + * ippStsEphemeralKeyErr - if test is failed pEphPrvKey == pEphPublicKeySelf*G or if calculated U(V) is an + * infinity point, U/V = [h*t(a/b)]( P(b/a) + [x(b/a)`]R(b/a) ) = ( x(u/v), y(u/v) ) + */ +/* clang-format off */ +IPPFUN(IppStatus, ippsGFpECKeyExchangeSM2_SharedKey, (Ipp8u* pSharedKey, int sharedKeySize, + Ipp8u* pSSelf, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pEphPrvKey, + IppsGFpECKeyExchangeSM2State *pKE, Ipp8u* pScratchBuffer)) +/* clang-format on */ +{ + /* check Key Exchange */ + IPP_BAD_PTR1_RET(pKE); + /* check id */ + IPP_BADARG_RET(!EC_SM2_KEY_EXCH_VALID_ID(pKE), ippStsContextMatchErr); + /* check User Role */ + const IppsKeyExchangeRoleSM2 role = EC_SM2_KEY_EXCH_ROLE(pKE); + IPP_BADARG_RET(((ippKESM2Requester != role) && (ippKESM2Responder != role)), ippStsBadArgErr); + + /* check Elliptic Curve */ + IppsGFpECState *pEC = EC_SM2_KEY_EXCH_EC(pKE); + + IPP_BAD_PTR1_RET(pEC); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); /* base P */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr); + gsModEngine *nME = ECP_MONT_R(pEC); /* base N */ + IPP_BADARG_RET(1 < GFP_EXTDEGREE(nME), ippStsNotSupportedModeErr); + /* check bitsize >= SM3_DIGSET */ + IPP_BADARG_RET(!(ECP_ORDBITSIZE(pEC) >= IPP_SM3_DIGEST_BITSIZE), ippStsRangeErr); + + /* check call Setup */ + /* check init Public Key | Ephemeral Public Key */ + IPP_BADARG_RET( NULL == EC_SM2_KEY_EXCH_PUB_KEY_USER_A(pKE) || + NULL == EC_SM2_KEY_EXCH_PUB_KEY_USER_B(pKE) || + NULL == EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE) || + NULL == EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE), ippStsContextMatchErr) + + /* check Shared Key */ + IPP_BAD_PTR1_RET(pSharedKey); + /* [GBT.32918.3-2016] Public Key cryptographic algorithm SM2 based on elliptic curves + * Part 3: Key exchange protocol + * 5.4.3 Key derivation function + * (0 < sharedKeySize) - (+) check + * (sharedKeySize < (2^32 - 1)*log2(n) ) - NO NEED if use INT input data type + */ + IPP_BADARG_RET(!(sharedKeySize > 0), ippStsOutOfRangeErr); + + /* check buffer */ + IPP_BAD_PTR1_RET(pScratchBuffer); + + /* check Private Key */ + CHECK_PRIVATE_KEY(pPrvKey) + + /* check Ephemeral Private Key */ + CHECK_PRIVATE_KEY(pEphPrvKey) + +#if (_IPP32E >= _IPP32E_K1) + if (IsFeatureEnabled(ippCPUID_AVX512IFMA) && (cpID_PrimeTPM_SM2 == ECP_MODULUS_ID(pEC))) { + const IppStatus sts = gfec_key_exchange_sm2_shared_key_avx512(pSharedKey, sharedKeySize, pSSelf, pPrvKey, pEphPrvKey, pKE, pScratchBuffer); + return sts; + } +#endif // (_IPP32E >= _IPP32E_K1) + { + IppStatus sts = ippStsNoErr; + + /* setup Public | Ephemeral Public */ + const IppsGFpECPoint *pPubKey = (ippKESM2Requester == role) ? EC_SM2_KEY_EXCH_PUB_KEY_USER_B(pKE) : EC_SM2_KEY_EXCH_PUB_KEY_USER_A(pKE); + const IppsGFpECPoint *pEphPubKey = (ippKESM2Requester == role) ? EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE) : EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE); + const IppsGFpECPoint *pSelfEphPubKey = (ippKESM2Requester == role) ? EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE) : EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE); + const Ipp8u firstNum = (ippKESM2Requester == role) ? 0x03 : 0x02; + + /* check that Ephemeral Public and Private Keys are related (R(a/b)=r(a/b)G) */ + IppsGFpECPoint pTmpPoint; + cpEcGFpInitPoint(&pTmpPoint, cpEcGFpGetPool(1, pEC), 0, pEC); + BNU_CHUNK_T *pDataEphPrv = BN_NUMBER(pEphPrvKey); // Ephemeral Private Key -> r(a/b) + gfec_MulBasePoint(&pTmpPoint, pDataEphPrv, BN_SIZE(pEphPrvKey), pEC, pScratchBuffer); // r(a/b)*G + int result = gfec_ComparePoint(&pTmpPoint, pSelfEphPubKey, pEC); // R(a/b) == r(a/b)G ? + cpEcGFpReleasePool(1, pEC); // Release pool before the possible exit + IPP_BADARG_RET(!result, ippStsEphemeralKeyErr); + + /* extract data Elliptic Curve */ + BNU_CHUNK_T *pOrder = MOD_MODULUS(nME); /* data oreder */ + const int ordLen = MOD_LEN(nME); /* len order */ + + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemBytes = (elemBits + 7) / 8; /* size Bytes */ + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + + /* create buffer data (it needes further use compute tmp_p) + * -> SM3( x(u/v)(0) || Za(1) || Zb(2) || xa(3) || ya(4) || xb(5) || yb(6) ) + */ + BNU_CHUNK_T *pDataBuff = cpGFpGetPool(7, pME); + BNU_CHUNK_T *_pXY_ = cpEcGFpGetPool(1, pEC); /* elem 3 */ + /* 2) x(a/b)` = 2^w + (x(a/b) & (2^w – 1)) */ + BNU_CHUNK_T *xa = pDataBuff + 3 * elemSize; /* xa(3) */ + BNU_CHUNK_T *ya = pDataBuff + 4 * elemSize; /* ya(4) */ + BNU_CHUNK_T *_xa_ = _pXY_; + /* point to affine coordinate */ + cpSM2KE_get_affine_ext_euclid(/* x = */ xa, /* y = */ ya, /* p = */ EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_A(pKE), /* pEC = */ pEC); + /* reduction x = 2^w + ( x & (2^w - 1) ) */ + cpSM2KE_reduction_x2w(_xa_, xa, pEC); + /* to big endian */ + cpSM2KE_xy_to_BE(xa, ya, pEC); + /* 4) x(b/a)` = 2^w + ( x(b/a) & (2^w – 1) ) */ + BNU_CHUNK_T *xb = pDataBuff + 5 * elemSize; /* xb(5) */ + BNU_CHUNK_T *yb = pDataBuff + 6 * elemSize; /* yb(6) */ + BNU_CHUNK_T *_xb_ = _pXY_ + elemSize; + /* point to affine coordinate */ + cpSM2KE_get_affine_ext_euclid(/* x = */ xb, /* y = */ yb, /* p = */ EC_SM2_KEY_EXCH_EPH_PUB_KEY_USER_B(pKE), /* pEC = */ pEC); + /* reduction x = 2^w + ( x & (2^w - 1) ) */ + cpSM2KE_reduction_x2w(_xb_, xb, pEC); + /* to big endian */ + cpSM2KE_xy_to_BE(xb, yb, pEC); + + BNU_CHUNK_T *_xf_ = (ippKESM2Requester == role) ? _xa_ : _xb_; + BNU_CHUNK_T *_xs_ = (ippKESM2Requester == role) ? _xb_ : _xa_; + + /* 3) t(a/b) = (d(a/b) + x(a/b)`*r(a/b) ) mod n */ + BNU_CHUNK_T *t = pDataBuff + elemSize; /* temporary use slot Za(1) */ + /* Private key -> d(a/b) */ + BNU_CHUNK_T *pTmpPrv = pDataBuff; /* temporary use slot x(u/v)(0) */ + cpGFpElementCopy(pTmpPrv, BN_NUMBER(pPrvKey), elemSize); + GFP_METHOD(nME)->encode(pTmpPrv, pTmpPrv, nME); + /* Ephemeral Private Key -> r(a/b) */ + GFP_METHOD(nME)->encode(pDataEphPrv, pDataEphPrv, nME); + /* x(a/b)` */ + GFP_METHOD(nME)->encode(_xf_, _xf_, nME); + + GFP_METHOD(nME)->mul(pDataEphPrv, pDataEphPrv, _xf_, nME); /* x(a/b)`*r(a/b) mod n */ + BNU_CHUNK_T *pBuffTmp = pDataBuff + 2 * elemSize; /* temporary use slot Zb(2) */ + cpModAdd_BNU(t, pDataEphPrv, pTmpPrv, pOrder, ordLen, pBuffTmp); /* (d(a/b) + x(a/b)`*r(a/b) ) mod n */ + + /* 5) U/V = [h*t(a/b)]( P(b/a) + [x(b/a)`]R(b/a) ) = ( x(u/v), y(u/v) ) */ + /* [x(b/a)`]R(b/a) */ + const int scalarBits = ((elemBits + 1) / 2); + cpEcGFpInitPoint(&pTmpPoint, cpEcGFpGetPool(1, pEC), 0, pEC); + gfec_point_mul(ECP_POINT_X(&pTmpPoint), ECP_POINT_X(pEphPubKey), (Ipp8u *)_xs_, scalarBits, pEC, pScratchBuffer); + /* P(b/a) + [x(b/a)`]R(b/a) */ + gfec_point_add(ECP_POINT_X(&pTmpPoint), ECP_POINT_X(&pTmpPoint), ECP_POINT_X(pPubKey), pEC); + + /* h*t(a/b) */ + BNU_CHUNK_T *pCofactor = ECP_COFACTOR(pEC); + const int cofactorLen = cpGFpElementLen(pCofactor, elemSize); + + if (!GFP_IS_ONE(pCofactor, cofactorLen)) { + cpMontMul_BNU_EX(t, t, elemSize, pCofactor, cofactorLen, nME); + } + GFP_METHOD(nME)->decode(t, t, nME); + /* we can do this because slot Zb(2) not Use Now */ + cpGFpElementCopyPad(t, elemSize + 1, t, elemSize); + /* U/V = [h*t(a/b)]( P(b/a) + [x(b/a)`]R(b/a) ) = ( x(u/v), y(u/v) ) */ + gfec_point_mul(ECP_POINT_X(&pTmpPoint), ECP_POINT_X(&pTmpPoint), (Ipp8u *)t, elemBits, pEC, pScratchBuffer); + /* check U/V == 0 */ + ECP_POINT_FLAGS(&pTmpPoint) = gfec_IsPointAtInfinity(&pTmpPoint) ? 0 : ECP_FINITE_POINT; + if(ECP_POINT_FLAGS(&pTmpPoint) == 0) { + sts = ippStsEphemeralKeyErr; + } + + /* extract Affine Coordinate X|Y */ + /* save x(u/v), y(u/v) */ + BNU_CHUNK_T *x_af = EC_SM2_KEY_EXCH_POINT_X(pKE); + BNU_CHUNK_T *y_af = EC_SM2_KEY_EXCH_POINT_Y(pKE); + /* point to affine coordinate */ + cpSM2KE_get_affine_ext_euclid(/* x = */ x_af, /* y = */ y_af, /* p = */ &pTmpPoint, /* pEC = */ pEC); + /* to big endian */ + cpSM2KE_xy_to_BE(x_af, y_af, pEC); + + /* Precompute Hash */ + Ipp8u *pBuff = (Ipp8u *)pDataBuff; + /* tmp_p = SM3( x(u/v) || Za || Zb || xa || ya || xb || yb ) */ + /* copy x(u/v)(0) */ + cpSM2_CopyBlock(pBuff, (const Ipp8u *)x_af, elemBytes); + pBuff += elemBytes; + /* copy Za(1) */ + cpSM2_CopyBlock(pBuff, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(pKE), IPP_SM3_DIGEST_BYTESIZE); + pBuff += IPP_SM3_DIGEST_BYTESIZE; + /* copy Zb(2) */ + cpSM2_CopyBlock(pBuff, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(pKE), IPP_SM3_DIGEST_BYTESIZE); + pBuff += IPP_SM3_DIGEST_BYTESIZE; + /* recopy xa */ + cpSM2_CopyBlock(pBuff, (const Ipp8u *)xa, elemBytes); + pBuff += elemBytes; + /* recopy ya */ + cpSM2_CopyBlock(pBuff, (const Ipp8u *)ya, elemBytes); + pBuff += elemBytes; + /* recopy xb */ + cpSM2_CopyBlock(pBuff, (const Ipp8u *)xb, elemBytes); + pBuff += elemBytes; + /* recopy yb */ + cpSM2_CopyBlock(pBuff, (const Ipp8u *)yb, elemBytes); + + /* set pointer start */ + pBuff = (Ipp8u *)pDataBuff; + + const int sizeS_SM3 = elemBytes + 2 * IPP_SM3_DIGEST_BYTESIZE + 4 * elemBytes; + + /* copy to next operation */ + cpSM2KE_compute_hash_SM3(EC_SM2_KEY_EXCH_PRECOM_HASH(pKE), pBuff, sizeS_SM3); + + /* check U/V == 0 and S == NULL */ + if ((NULL != pSSelf) && IS_ECP_FINITE_POINT(&pTmpPoint)) { + /* 6) S(a/b) = SM3( 0x0(3/2) || y(u/v) || tmp_p ) */ + /* copy 0x0(3/2) */ + pBuff[0] = firstNum; + /* copy y(u/v) */ + cpSM2_CopyBlock(pBuff + 1, (const Ipp8u *)y_af, elemBytes); + /* copy tmp_p */ + cpSM2_CopyBlock(pBuff + 1 + elemBytes, EC_SM2_KEY_EXCH_PRECOM_HASH(pKE), IPP_SM3_DIGEST_BYTESIZE); + + const int sizeSab_SM3 = 1 + elemBytes + IPP_SM3_DIGEST_BYTESIZE; + cpSM2KE_compute_hash_SM3(pSSelf, pBuff, sizeSab_SM3); + } + + /* compute KDF */ + /* 7) K(a/b) = KDF(x(u/v) || y(u/v) || Za || Zb, klen) */ + /* copy x(u/v)(0)*/ + cpSM2_CopyBlock(pBuff, (const Ipp8u *)EC_SM2_KEY_EXCH_POINT_X(pKE), elemBytes); + pBuff += elemBytes; + /* copy y(u/v)(1) */ + cpSM2_CopyBlock(pBuff, (const Ipp8u *)EC_SM2_KEY_EXCH_POINT_Y(pKE), elemBytes); + pBuff += elemBytes; + /* copy Za(2) */ + cpSM2_CopyBlock(pBuff, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_A(pKE), IPP_SM3_DIGEST_BYTESIZE); + pBuff += IPP_SM3_DIGEST_BYTESIZE; + /* copy Zb(3) */ + cpSM2_CopyBlock(pBuff, EC_SM2_KEY_EXCH_USER_ID_HASH_USER_B(pKE), IPP_SM3_DIGEST_BYTESIZE); + + const int sizeKab_KDF = 2 * elemBytes + 2 * IPP_SM3_DIGEST_BYTESIZE; + + /* set pointer start */ + pBuff = (Ipp8u *)pDataBuff; + + /* compute KDF */ + KDF_sm3(pSharedKey, sharedKeySize, (const Ipp8u *)pBuff, sizeKab_KDF); + + /* free buffers */ + cpEcGFpReleasePool(2, pEC); + cpGFpReleasePool(7, pME); + + /* clear Ephemeral Private Key */ + cpBN_zero(pEphPrvKey); + + return sts; + } +} + +#undef CHECK_PRIVATE_KEY diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_message_representation.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_message_representation.c new file mode 100644 index 000000000..779e6af14 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_message_representation.c @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// Digesting message according to SM3 +// +// Contents: +// ippsGFpECMessageRepresentationSM2() +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpsm3stuff.h" +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" +#include "gsmodstuff.h" +#include "sm2/sm2_stuff.h" + + +/* clang-format off */ +IPPFUN(IppStatus, ippsGFpECMessageRepresentationSM2, (IppsBigNumState * pMsgDigest, + const Ipp8u* pMsg, int msgLen, + const Ipp8u* pUserID, int userIDLen, + const IppsGFpECPoint* pRegPublic, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +/* clang-format on */ +{ + IppsGFpState *pGF; + gsModEngine *pGFE; + + /* check curve data */ + IPP_BAD_PTR1_RET(pEC); + IPP_BAD_PTR1_RET(pScratchBuffer); + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr); + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr); + + /* check Message */ + IPP_BAD_PTR1_RET(pMsg); + /* check border (msgLen > 0) */ + IPP_BADARG_RET(!(msgLen > 0), ippStsOutOfRangeErr); + + /* check message digest */ + IPP_BAD_PTR1_RET(pMsgDigest); + IPP_BADARG_RET(!BN_VALID_ID(pMsgDigest), ippStsContextMatchErr); + /* make sure bitsize(pMsgDigest) <= bitsize(order) */ + IPP_BADARG_RET(!(cpBN_bitsize(pMsgDigest) <= ECP_ORDBITSIZE(pEC)), ippStsMessageErr); + + /* check User ID */ + IPP_BAD_PTR1_RET(pUserID); + /* check border (userIDLen > 0) */ + IPP_BADARG_RET(!(userIDLen > 0), ippStsOutOfRangeErr); + + pGF = ECP_GFP(pEC); + pGFE = GFP_PMA(pGF); + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pGFE), ippStsNotSupportedModeErr); + + /* check Public Key */ + IPP_BAD_PTR1_RET(pRegPublic); + IPP_BADARG_RET(!ECP_POINT_VALID_ID(pRegPublic), ippStsContextMatchErr); + IPP_BADARG_RET(ECP_POINT_FELEN(pRegPublic) != GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + Ipp8u Za[IPP_SM3_DIGEST_BYTESIZE]; + /* compute Za = SM3( ENTL || ID || a || b || xG || yG || xA || yA ) */ + const IppStatus sts = ippsGFpECUserIDHashSM2((Ipp8u *)Za, pUserID, userIDLen, pRegPublic, pEC, pScratchBuffer); + if(ippStsNoErr != sts){ + return sts; + } + + /* e = SM3(Za || M) */ + static IppsHashState_rmf ctx; + + ippsHashInit_rmf(&ctx, ippsHashMethod_SM3()); + /* Za */ + ippsHashUpdate_rmf(Za, sizeof(Za), &ctx); + /* M */ + ippsHashUpdate_rmf(pMsg, msgLen, &ctx); + + /* final */ + ippsHashFinal_rmf((Ipp8u *)(BN_NUMBER(pMsgDigest)), &ctx); + BN_SIGN(pMsgDigest) = ippBigNumPOS; + + /* clear stack data */ + PurgeBlock(Za, sizeof(Za)); + + return ippStsNoErr; +} diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_stuff.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_stuff.c new file mode 100644 index 000000000..27079128f --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_stuff.c @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" +#include "owncp.h" +#include "gsmodstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcpsm3stuff.h" +#include "pcptool.h" + +#include "sm2/sm2_stuff.h" + +/** + * @brief + * compute Za digest = SM3( ENTL || ID || a || b || xG || yG || xA || yA ) + * @param [out] pZa_digest (Za) output digest Za + * @param [in] p_user_id (ID) data user ID + * @param [in] user_id_len (ENTL) length user ID + * @param [in] elem_len length element bytes + * @param [in] a (a) coefficient a of Elliptic Curve + * @param [in] b (b) coefficient b of Elliptic Curve + * @param [in] Gx (Gx) base point coordinate X of Elliptic Curve + * @param [in] Gy (Gy) base point coordinate Y of Elliptic Curve + * @param [in] pub_key_x (xA) public point coordinate X + * @param [in] pub_key_y (yA) public point coordinate Y + */ +/* clang-format off */ +IPP_OWN_DEFN(IppStatus, computeZa_user_id_hash_sm2, (Ipp8u * pZa_digest, + const Ipp8u *p_user_id, const int user_id_len, + const int elem_len, + const Ipp8u *a, const Ipp8u *b, + const Ipp8u *Gx, const Ipp8u *Gy, + const Ipp8u *pub_key_x, const Ipp8u *pub_key_y)) +/* clang-format on */ +{ + /* check pointer Za Digest | user id */ + IPP_BAD_PTR2_RET(pZa_digest, p_user_id); + /* check border (user_id_len > 0) | (elem_len > 0) */ + IPP_BADARG_RET(!(user_id_len > 0) || !(elem_len > 0), ippStsBadArgErr); + /* check (user_id_len*8 <= 0xFFFF) ~ (user_id_len <= 0x1FFF) for two bytes overflow. + user_id_len*8 operation will be executed in algorithm's flow */ + IPP_BADARG_RET(user_id_len > 0x1FFF, ippStsBadArgErr); + /* param curve: a, b, Gx, Gy */ + IPP_BAD_PTR2_RET(a, b); + IPP_BAD_PTR2_RET(Gx, Gy); + /* Public X|Y */ + IPP_BAD_PTR2_RET(pub_key_x, pub_key_y) + + static IppsHashState_rmf ctx; + + ippsHashInit_rmf(&ctx, ippsHashMethod_SM3()); + + /* compute Za = SM3( ENTL || ID || a || b || xG || yG || xA || yA ) */ + /* ENLT */ + const Ipp16u entl = ((user_id_len * 8) & 0xFFFF); + Ipp8u ENTL[sizeof(Ipp16u)]; + ENTL[0] = (Ipp8u)(entl >> 8); + ENTL[1] = (Ipp8u)(entl & 0xFF); + ippsHashUpdate_rmf(ENTL, sizeof(ENTL), &ctx); + /* ID */ + ippsHashUpdate_rmf(p_user_id, user_id_len, &ctx); + /* a */ + ippsHashUpdate_rmf(a, elem_len, &ctx); + /* b */ + ippsHashUpdate_rmf(b, elem_len, &ctx); + /* Gx */ + ippsHashUpdate_rmf(Gx, elem_len, &ctx); + /* Gy */ + ippsHashUpdate_rmf(Gy, elem_len, &ctx); + /* Px */ + ippsHashUpdate_rmf(pub_key_x, elem_len, &ctx); + /* Py */ + ippsHashUpdate_rmf(pub_key_y, elem_len, &ctx); + + /* final */ + ippsHashFinal_rmf(pZa_digest, &ctx); + + /* clear stack data */ + PurgeBlock(ENTL, sizeof(ENTL)); + + return ippStsNoErr; +} + +#define SIZE_CT (4) + +__INLINE void convert_ct_to_big_endian(Ipp8u pCt[SIZE_CT], const Ipp32u ct) +{ + pCt[0] = (Ipp8u)(ct >> 24); + pCt[1] = (Ipp8u)(ct >> 16); + pCt[2] = (Ipp8u)(ct >> 8); + pCt[3] = (Ipp8u)(ct); + return; +} + +/** + * @brief compute KDF base by SM3 hash + * @param [out] pKDF pointer output KDF + * @param [in] kdf_len length KDF + * @param [in] pZ data Z to create KDF + * @param [in] z_len length Z data + * bound kdf_len in standart: + * + */ +IPP_OWN_DEFN(IppStatus, KDF_sm3, (Ipp8u * pKDF, int kdf_len, const Ipp8u *pZ, const int z_len)) +{ + /* check pointer input */ + IPP_BAD_PTR2_RET(pKDF, pZ); + /* [GBT.32918.3-2016] Public Key cryptographic algorithm SM2 based on elliptic curves Part 3: Key exchange protocol + * 5.4.3 Key derivation function + * kdf_len < (2^32 - 1) * 2^5 = 2^37 - 32 [bytes] + * BUT if input INT type - NO NEED check this border + */ + /* check border (kdf_len >= 0) */ + IPP_BADARG_RET(!(kdf_len >= 0), ippStsBadArgErr); + /* check border (z_len > 0) */ + IPP_BADARG_RET(!(z_len > 0), ippStsBadArgErr); + + /* if kdf > 0 */ + if (kdf_len > 0) { + /* buffer */ + Ipp8u buff[IPP_SM3_DIGEST_BYTESIZE]; + + // step (a) + Ipp8u pCt[SIZE_CT]; + + const Ipp32u n = (Ipp32u)((kdf_len + IPP_SM3_DIGEST_BYTESIZE - 1) / IPP_SM3_DIGEST_BYTESIZE) + 1u; /* add 1 - loop start 1 */ + + /* init copy output len */ + int num_copy = IPP_SM3_DIGEST_BYTESIZE; + + static IppsHashState_rmf ctx; + ippsHashInit_rmf(&ctx, ippsHashMethod_SM3()); + + /* compute length K = Ha1 || Ha2 || ... */ + // step (b) + for (Ipp32u i = 1u; i < n; ++i) { + // step (b.1) -> Hai = H(Z || ct) + /* Z */ + ippsHashUpdate_rmf(pZ, z_len, &ctx); + /* ct */ + convert_ct_to_big_endian(pCt, i); + ippsHashUpdate_rmf(pCt, sizeof(pCt), &ctx); + /* auto init of end function - no need call in start loop */ + ippsHashFinal_rmf(buff, &ctx); + /* copy result */ + if ((i == n - 1u) && (0 != kdf_len % IPP_SM3_DIGEST_BYTESIZE)) { + num_copy = kdf_len % IPP_SM3_DIGEST_BYTESIZE; + } + cpSM2_CopyBlock(pKDF, buff, num_copy); + + /* update copy next reult */ + pKDF += num_copy; + kdf_len -= num_copy; + } + + /* clear stack data */ + PurgeBlock(buff, sizeof(buff)); + PurgeBlock(pCt, sizeof(pCt)); + } + + return ippStsNoErr; +} + +#undef SIZE_CT diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_stuff.h b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_stuff.h new file mode 100644 index 000000000..83d060234 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_stuff.h @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +/* +// +// Purpose: +// Cryptography Primitive. +// SM2 support function +// +// Contents: +// SM2 methods and constants +// +*/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" +#include "pcpeccp.h" +#include "pcpgfpecstuff.h" +#include "pcpsm3stuff.h" +#include "sm2/sm2_key_exchange_method.h" + +#if !defined _SM2_STUFF_H +#define _SM2_STUFF_H + +#define cpSM2_CopyBlock(DST, SRC, SIZE) CopyBlock((SRC), (DST), (SIZE)) + +/** + * @brief + * reverse inplace array ( Little Endian to Big Endian data ) + * @param[in out] arr array data + * @param[in] len length array + */ +__INLINE void cpSM2KE_reverse_inplace(Ipp8u *arr, const int len) +{ +#define SWAPXOR(x, y) \ + (x) ^= (y); \ + (y) ^= (x); \ + (x) ^= (y); + + for (int i = 0; i < len / 2; ++i) { + SWAPXOR(arr[i], arr[len - 1 - i]) + } + return; +#undef SWAPXOR +} + +/** + * @brief cpSM2KE_CopyPointData + * init and copy Pointer + * @param[out] r point in Elliptic Curve + * @param[in] data buffer init pointer data + * @param[in] p point copy + * @param[in] pEC context Elliptic Curve + */ +__INLINE void cpSM2KE_CopyPointData(IppsGFpECPoint *r, BNU_CHUNK_T *data, const IppsGFpECPoint *p, const IppsGFpECState *pEC) +{ + ECP_POINT_SET_ID(r); + cpEcGFpInitPoint(r, data, ECP_POINT_FLAGS(p), pEC); + gfec_CopyPoint(r, p, ECP_POINT_FELEN(p)); + return; +} + +/** + * @brief + * reduction for the SM2 Key Exchange standard + * x` = 2^w + (x & (2^w – 1)) + * when + * w = log2(n)/2 - 1, n - number bytes order + * @param[out] r reduction value x` + * @param[in] a value x + * @param[in] pEC context Elliptic Curve + */ +__INLINE void cpSM2KE_reduction_x2w(BNU_CHUNK_T *r, const BNU_CHUNK_T *a, const IppsGFpECState *pEC) +{ + const gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemSize = GFP_FELEN(pME); /* size BNU_CHUNK */ + /* compute w = [log2(n)/2 - 1] */ + const int w = ((elemBits + 1) / 2 - 1); + + /* compute copy BNU_CHUNK */ + const int num_copy_bc = (w + (BNU_CHUNK_BITS - 1)) / BNU_CHUNK_BITS; + const int num_bit_shift = (w - (num_copy_bc - 1) * BNU_CHUNK_BITS); + const BNU_CHUNK_T vadd = (BNU_CHUNK_T)(1ULL << num_bit_shift); + const BNU_CHUNK_T mask = (BNU_CHUNK_T)(vadd - 1); + + ZEXPAND_COPY_BNU(r, elemSize, a, num_copy_bc); + r[num_copy_bc - 1] = (r[num_copy_bc - 1] & mask) + vadd; + return; +} + +/* clang-format off */ +__INLINE void cpSM2KE_get_affine_ext_euclid(BNU_CHUNK_T *x, BNU_CHUNK_T *y, + const IppsGFpECPoint *p, + IppsGFpECState *pEC) +/* clang-format on */ +{ + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + + gfec_GetPoint(x, y, p, pEC); + GFP_METHOD(pME)->decode(x, x, pME); + GFP_METHOD(pME)->decode(y, y, pME); + return; +} + +__INLINE void cpSM2KE_xy_to_BE(BNU_CHUNK_T *x, BNU_CHUNK_T *y, const IppsGFpECState *pEC) +{ + const gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemBytes = (elemBits + 7) / 8; /* size Bytes */ + + cpSM2KE_reverse_inplace((Ipp8u *)x, elemBytes); + cpSM2KE_reverse_inplace((Ipp8u *)y, elemBytes); + return; +} + +/** + * @brief + * comput SM3 hash by message + * @param[out] r hash SM3 compute + * @param[in] a hashing an array data + * @param[in] numBytes numers bytes + */ +__INLINE void cpSM2KE_compute_hash_SM3(Ipp8u *r, const Ipp8u *a, const int numBytes) +{ + static IppsHashState_rmf ctx; + + /* init */ + ippsHashInit_rmf(&ctx, ippsHashMethod_SM3()); + /* update hash */ + ippsHashUpdate_rmf(a, numBytes, &ctx); + /* final */ + ippsHashFinal_rmf(r, &ctx); + return; +} + +/* clang-format off */ +/* compute Za digest = SM3( ENTL || ID || a || b || xG || yG || xA || yA ) */ +#define computeZa_user_id_hash_sm2 OWNAPI(computeZa_user_id_hash_sm2) +IPP_OWN_DECL(IppStatus, computeZa_user_id_hash_sm2, (Ipp8u * pZa_digest, + const Ipp8u* p_user_id, const int user_id_len, + const int elem_len, + const Ipp8u* a, const Ipp8u* b, + const Ipp8u* Gx, const Ipp8u* Gy, + const Ipp8u* pub_key_x, const Ipp8u* pub_key_y)) + +/* KDF sm3 */ +#define KDF_sm3 OWNAPI(KDF_sm3) +IPP_OWN_DECL(IppStatus, KDF_sm3, (Ipp8u * pKDF, int kdf_len, + const Ipp8u* pZ, const int z_len)) + +/* IFMA optimization SM2 Key Exchange Shared Key */ +#define gfec_key_exchange_sm2_shared_key_avx512 OWNAPI(gfec_key_exchange_sm2_shared_key_avx512) + +IPP_OWN_DECL(IppStatus, gfec_key_exchange_sm2_shared_key_avx512, (Ipp8u* pSharedKey, const int sharedKeySize, + Ipp8u* pSSelf, + const IppsBigNumState* pPrvKey, + IppsBigNumState* pEphPrvKey, + IppsGFpECKeyExchangeSM2State *pKE, Ipp8u* pScratchBuffer)) +/* clang-format on */ + +#endif // _SM2_STUFF_H diff --git a/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_user_id_hash.c b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_user_id_hash.c new file mode 100644 index 000000000..5a7900619 --- /dev/null +++ b/plugin/ippcp/library/src/sources/ippcp/sm2/sm2_user_id_hash.c @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (C) 2022 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the 'License'); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an 'AS IS' BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * + *******************************************************************************/ + +#include "owndefs.h" +#include "owncp.h" +#include "pcpgfpstuff.h" +#include "pcpgfpecstuff.h" +#include "sm2/sm2_stuff.h" + + +/** + * @brief ippsGFpECUserIDHashSM2 + * compute digest Za = SM3( ENTL||IDA||a||b||Gx||Gy||Px||Py) + * @param [out] pZaDigest digest Za + * @param [in] pUserID user ID data + * @param [in] userIDLen length user ID data + * @param [in] pPublicKey public key + * @param [in] pEC context Elliptic Curve + * @param [in] pScratchBuffer supported buffer + * @return + * ippStsNoErr - successful + * ippStsNullPtrErr - if pEC | pUserID | pPublicKey is NULL + * ippStsContextMatchErr - if pEC no valid ID | pEC | ID pPublic Key no exists SUBGROUP + * ippStsNotSupportedModeErr - if pEC no supported (n|p) modulus arithmetic + * ippStsInvalidPoint - if no in curve Pub Key + * ippStsBadArgErr - if userIDLen <= 0 or the number representing the userIDLen in bits + * exceed two bytes (user_id_len*8 > 0xFFFF) + * ippStsOutOfRangeErr - if userIDLen <= 0 or public key length is out of range + */ +/* clang-format off */ +IPPFUN(IppStatus, ippsGFpECUserIDHashSM2, (Ipp8u * pZaDigest, + const Ipp8u* pUserID, int userIDLen, + const IppsGFpECPoint* pPublicKey, + IppsGFpECState* pEC, Ipp8u* pScratchBuffer)) +/* clang-format on */ +{ + + /* check curve data */ + IPP_BAD_PTR1_RET(pEC) + IPP_BAD_PTR1_RET(pScratchBuffer) + IPP_BADARG_RET(!VALID_ECP_ID(pEC), ippStsContextMatchErr) + IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr) + + gsModEngine *pME = GFP_PMA(ECP_GFP(pEC)); + IPP_BADARG_RET(1 < GFP_EXTDEGREE(pME), ippStsNotSupportedModeErr) + + /* check Za return */ + IPP_BAD_PTR1_RET(pZaDigest) + + /* check User ID */ + IPP_BAD_PTR1_RET(pUserID) + /* check border (userIDLen > 0) */ + IPP_BADARG_RET(!(userIDLen > 0), ippStsOutOfRangeErr); + + /* check Public Key */ + IPP_BAD_PTR1_RET(pPublicKey) + IPP_BADARG_RET(!ECP_POINT_VALID_ID(pPublicKey), ippStsContextMatchErr) + IPP_BADARG_RET(ECP_POINT_FELEN(pPublicKey) != GFP_FELEN(pME), ippStsOutOfRangeErr) + IPP_BADARG_RET(0 == gfec_IsPointOnCurve(pPublicKey, pEC), ippStsInvalidPoint); + + IppStatus ret = ippStsNoErr; + + const int elemBits = GFP_FEBITLEN(pME); /* size Bits */ + const int elemBytes = (elemBits + 7) / 8; /* size Bytes */ + const int elemLen = GFP_FELEN(pME); /* size BNU_CHUNK */ + + BNU_CHUNK_T *pDataBuff = cpGFpGetPool(6, pME); + /* param curve : a,b,Gx,Gy */ + BNU_CHUNK_T *pA = pDataBuff; + BNU_CHUNK_T *pB = pDataBuff + 1 * elemLen; + BNU_CHUNK_T *pGx = pDataBuff + 2 * elemLen; + BNU_CHUNK_T *pGy = pDataBuff + 3 * elemLen; + /* Public X | Y */ + BNU_CHUNK_T *pX = pDataBuff + 4 * elemLen; + BNU_CHUNK_T *pY = pDataBuff + 5 * elemLen; + + /* get affine coordinate X | Y */ + gfec_GetPoint(/* pX = */ pX, /* pY = */ pY, /* pPoint = */ pPublicKey, /* pEC = */ pEC); + + /* decode */ + GFP_METHOD(pME)->decode(pX, pX, pME); + GFP_METHOD(pME)->decode(pY, pY, pME); + GFP_METHOD(pME)->decode(pA, ECP_A(pEC), pME); + GFP_METHOD(pME)->decode(pB, ECP_B(pEC), pME); + GFP_METHOD(pME)->decode(pGx, ECP_G(pEC), pME); + GFP_METHOD(pME)->decode(pGy, ECP_G(pEC) + elemLen, pME); + + /* convert Little Endian to Big Endian */ + cpSM2KE_reverse_inplace((Ipp8u *)pX, elemBytes); /* X */ + cpSM2KE_reverse_inplace((Ipp8u *)pY, elemBytes); /* Y */ + cpSM2KE_reverse_inplace((Ipp8u *)pA, elemBytes); /* a */ + cpSM2KE_reverse_inplace((Ipp8u *)pB, elemBytes); /* b */ + cpSM2KE_reverse_inplace((Ipp8u *)pGx, elemBytes); /* Gx */ + cpSM2KE_reverse_inplace((Ipp8u *)pGy, elemBytes); /* Gy */ + + /* create hash */ + ret = computeZa_user_id_hash_sm2(pZaDigest, + /* p_user_id = */ pUserID, + /* user_id_len = */ userIDLen, + /* elem_len = */ elemBytes, + /* a = */ (Ipp8u *)pA, + /* b = */ (Ipp8u *)pB, + /* Gx = */ (Ipp8u *)pGx, + /* Gy = */ (Ipp8u *)pGy, + /* px = */ (Ipp8u *)pX, + /* py = */ (Ipp8u *)pY); + + cpGFpReleasePool(6, pME); + + return ret; +} diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/app.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/app.py new file mode 100644 index 000000000..269a1827f --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/app.py @@ -0,0 +1,118 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import os +import json + +from PyQt5.QtCore import QEvent, Qt +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QMainWindow, QWidget, QGridLayout, QFileDialog, QMessageBox, QDesktopWidget + +from tool import utils +from gui.selection_panel import SelectionPanel +from gui.custom_functions_panel import CustomFunctionsPanel +from gui.settings_panel import SettingsPanel +from gui.controller import Controller + + +class MainAppWindow(QMainWindow): + def __init__(self): + super(MainAppWindow, self).__init__() + self.setWindowIcon(QIcon('icon.ico')) + self.setWindowTitle('Intel(R) Integrated Performance Primitives Custom Library Tool') + + project_menu = self.menuBar() + + open_action = project_menu.addAction('Open project') + save_action = project_menu.addAction('Save project') + save_as_action = project_menu.addAction('Save project as...') + + self.settings_panel = SettingsPanel() + self.selection_panel = SelectionPanel(self.settings_panel) + self.custom_functions_panel = CustomFunctionsPanel(self.settings_panel) + + self.controller = Controller(self, + self.settings_panel, + self.selection_panel, + self.custom_functions_panel) + + widget = QWidget() + self.setCentralWidget(widget) + + layout = QGridLayout() + layout.addWidget(self.settings_panel, 0, 0, 1, 3) + layout.addWidget(self.selection_panel, 1, 0) + layout.addWidget(self.controller, 1, 1, Qt.AlignCenter) + layout.addWidget(self.custom_functions_panel, 1, 2) + widget.setLayout(layout) + + open_action.triggered.connect(self.on_open) + save_action.triggered.connect(self.on_save) + save_as_action.triggered.connect(self.on_save_as) + + self.project = '' + self.show() + + def on_open(self): + while True: + extension = 'CLT project (*' + utils.PROJECT_EXTENSION + ')' + chosen_path = QFileDialog.getOpenFileName(self, + 'Open project', + '', + extension, + options=QFileDialog.DontResolveSymlinks)[0] + if not chosen_path: + return + elif os.path.islink(chosen_path): + QMessageBox.information(self, 'ERROR!', 'Please, select not a symlink') + continue + else: + self.project = chosen_path + break + + with open(self.project, 'r') as project_file: + configs = json.load(project_file) + self.controller.set_configs(configs) + + def on_save(self): + return self.on_save_as(self.project) + + def on_save_as(self, project): + self.controller.get_selected_configs() + + if not project: + extension = 'CLT project (*' + utils.PROJECT_EXTENSION + ')' + project = QFileDialog.getSaveFileName(self, 'Save project as...', '', extension)[0] + if not project: + return + else: + self.project = project + + if utils.CONFIGS[utils.PACKAGE]: + utils.CONFIGS[utils.PACKAGE] = utils.CONFIGS[utils.PACKAGE].root + + with open(project, 'w') as project_file: + json.dump(utils.CONFIGS, project_file) + + def event(self, e): + if e.type() == QEvent.Show: + qt_rectangle = self.frameGeometry() + center_point = QDesktopWidget().availableGeometry().center() + qt_rectangle.moveCenter(center_point) + self.move(qt_rectangle.topLeft()) + + return super().event(e) diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/controller.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/controller.py new file mode 100644 index 000000000..996f6566e --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/controller.py @@ -0,0 +1,204 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import os + +from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QFileDialog, QMessageBox, QLabel, QCheckBox + +import tool +from tool import utils +from tool.core import build, generate_script + + +class Controller(QWidget): + def change_state(function): + def wrapper(self, *args): + function(self, *args) + self.check_current_state() + + return wrapper + + def __init__(self, parent, settings, left_side_menu, right_side_menu): + super().__init__() + self.parent = parent + self.settings = settings + self.left = left_side_menu + self.right = right_side_menu + + self.to_right = QPushButton('>>') + self.to_left = QPushButton('<<') + + layout = QVBoxLayout() + layout.addWidget(self.to_right) + layout.addWidget(self.to_left) + self.setLayout(layout) + + self.status_message = QLabel() + self.parent.statusBar().addWidget(self.status_message) + + self.to_right.pressed.connect(self.on_right_press) + self.to_left.pressed.connect(self.on_left_press) + self.settings.package_changed.connect(self.check_current_state) + self.left.autobuild.connect(self.autobuild) + self.right.save_script.connect(self.save_build_script) + + self.settings.init_settings() + + @change_state + def on_right_press(self): + function = self.left.functions_list.currentItem() + if function: + self.left.remove_function(function.text()) + self.right.add_function(function.text()) + + @change_state + def on_left_press(self): + function = self.right.functions_list.currentItem() + if function: + self.right.remove_function(function.text()) + self.left.add_function(function.text()) + + def check_current_state(self): + state = self.get_current_state() + + if state == utils.ENABLE_GENERATION_RULES: + self.enable_generation(True) + self.status_message.setText("Ready to build custom library") + else: + self.enable_generation(False) + differences = dict(utils.ENABLE_GENERATION_RULES.items() - state.items()) + self.status_message.setText("Select " + sorted(differences, key=len)[0]) + + def enable_generation(self, flag): + self.left.autobuild_button.setEnabled(flag) + self.right.save_script_button.setEnabled(flag) + + def autobuild(self): + self.get_selected_configs() + + extension = 'Dynamic library (*' + utils.DYNAMIC_LIB_EXTENSION[utils.HOST_SYSTEM] + ')' + chosen_path = QFileDialog.getSaveFileName(self, + 'Save custom library as...', + utils.CONFIGS[utils.CUSTOM_LIBRARY_NAME], + extension)[0] + if not chosen_path: + return + else: + utils.CONFIGS[utils.CUSTOM_LIBRARY_NAME] = os.path.basename(os.path.splitext(chosen_path)[0]) + utils.CONFIGS[utils.OUTPUT_PATH] = os.path.dirname(chosen_path) + + self.parent.setDisabled(True) + QMessageBox.information(self, + 'Build', + 'Building will start after this window is closed. ' + 'Please, wait until process is done.') + success = build() + QMessageBox.information(self, + 'Success' if success else 'Failure', + 'Build completed!' if success else 'Build failed!') + self.parent.setDisabled(False) + + def save_build_script(self): + self.get_selected_configs() + + extension = 'Script (*' + utils.BATCH_EXTENSIONS[utils.HOST_SYSTEM] + ')' + script_path = QFileDialog.getSaveFileName(self, + 'Save build script as...', + utils.CONFIGS[utils.BUILD_SCRIPT_NAME], + extension)[0] + if not script_path: + return + else: + utils.CONFIGS[utils.BUILD_SCRIPT_NAME] = os.path.basename(os.path.splitext(script_path)[0] + + utils.BATCH_EXTENSIONS[utils.HOST_SYSTEM]) + utils.CONFIGS[utils.OUTPUT_PATH] = os.path.dirname(script_path) + + success = generate_script() + QMessageBox.information(self, + 'Success' if success else 'Failure', + 'Generation completed!' if success else 'Generation failed!') + + def get_current_state(self): + return {utils.HAVE_PACKAGE : not self.settings.package.broken, + utils.HAVE_FUNCTIONS : bool(self.right.functions_list.count())} + + def get_selected_configs(self): + """ + Collecting all user-specified information about future dynamic library into dictionary + """ + if not self.settings.package.broken: + custom_library_name = (self.right.lib_name.text() if self.right.lib_name.text() else + utils.CONFIGS[utils.CUSTOM_LIBRARY_NAME]) + functions_list = [] + for i in range(self.right.functions_list.count()): + functions_list.append(self.right.functions_list.item(i).text()) + + architecture = (utils.IA32 if self.settings.ia32.isChecked() else utils.INTEL64) + thread_mode = (utils.SINGLE_THREADED if self.settings.single_threaded.isChecked() else utils.MULTI_THREADED) + + if self.settings.tbb.isChecked(): + tl_type = utils.TBB + elif self.settings.omp.isChecked(): + tl_type = utils.OPENMP + else: + tl_type = '' + + custom_cpu_set = [self.settings.get_formatted_button_name(cpu) + for cpu in self.settings.custom_dispatch.findChildren(QCheckBox) if cpu.isChecked()] + + utils.set_configs_dict(package=self.settings.package, + functions_list=functions_list, + architecture=architecture, + thread_mode=thread_mode, + threading_layer_type=tl_type, + custom_library_name=custom_library_name, + custom_cpu_set=custom_cpu_set) + + @change_state + def set_configs(self, configs): + self.settings.package = tool.package.Package(configs[utils.PACKAGE]) + self.settings.init_settings() + + if configs[utils.ARCHITECTURE] == utils.IA32: + self.settings.ia32.setChecked(True) + if configs[utils.ARCHITECTURE] == utils.INTEL64: + self.settings.intel64.setChecked(True) + + if configs[utils.THREAD_MODE] == utils.SINGLE_THREADED: + self.settings.single_threaded.setChecked(True) + if configs[utils.THREAD_MODE] == utils.MULTI_THREADED: + self.settings.multi_threaded.setChecked(True) + + if configs[utils.THREADING_LAYER] == utils.TBB: + self.settings.tbb.setChecked(True) + if configs[utils.THREADING_LAYER] == utils.OPENMP: + self.settings.omp.setChecked(True) + + if configs[utils.CUSTOM_CPU_SET]: + self.settings.custom_dispatch.setChecked(True) + self.settings.on_switch_custom_dispatch() + for cpu in self.settings.custom_dispatch.findChildren(QCheckBox): + cpu_name = self.settings.get_formatted_button_name(cpu) + if cpu_name in configs[utils.CUSTOM_CPU_SET]: + cpu.setChecked(True) + + self.right.lib_name.setText(configs[utils.CUSTOM_LIBRARY_NAME]) + + self.right.reset() + for function in configs[utils.FUNCTIONS_LIST]: + self.left.remove_function(function) + self.right.add_function(function) diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/custom_functions_panel.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/custom_functions_panel.py new file mode 100644 index 000000000..bcba75149 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/custom_functions_panel.py @@ -0,0 +1,67 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +from PyQt5 import QtCore +from PyQt5.QtWidgets import QWidget, QLineEdit, QListWidget, QPushButton, QVBoxLayout, QListWidgetItem + + +class CustomFunctionsPanel(QWidget): + save_script = QtCore.pyqtSignal() + + def __init__(self, settings): + super().__init__() + self.settings = settings + + # Initializing GUI elements + self.lib_name = QLineEdit() + self.functions_list = QListWidget() + self.save_script_button = QPushButton('Save build script') + + # Preparing elements by giving initial values and etc + self.lib_name.setPlaceholderText('Custom library name...') + + # Setting all widgets in their places + layout = QVBoxLayout() + layout.addWidget(self.lib_name) + layout.addWidget(self.functions_list) + layout.addWidget(self.save_script_button) + self.setLayout(layout) + + self.save_script_button.clicked.connect(self.on_save_script) + self.settings.package_changed.connect(self.reset) + + def on_save_script(self): + self.save_script.emit() + + def reset(self): + self.functions_list.clear() + + def add_function(self, function): + """ + Adds new function to required list + + :param function: name if function + """ + self.functions_list.addItem(QListWidgetItem(function)) + + def remove_function(self, function): + """ + Removes function from left list + """ + item = self.functions_list.findItems(function, QtCore.Qt.MatchExactly) + if item: + self.functions_list.takeItem(self.functions_list.row(item[0])) diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/selection_panel.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/selection_panel.py new file mode 100644 index 000000000..f2b214be4 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/selection_panel.py @@ -0,0 +1,133 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import copy + +from PyQt5 import QtCore +from PyQt5.QtWidgets import QWidget, QComboBox, QLineEdit, QListWidget, QPushButton, QVBoxLayout, QListWidgetItem + +from tool import utils + + +class SelectionPanel(QWidget): + autobuild = QtCore.pyqtSignal() + + def __init__(self, settings): + super().__init__() + self.settings = settings + + # Initializing GUI elements + self.domains_list = QComboBox(self) + self.search = QLineEdit(self) + self.functions_list = QListWidget(self) + self.autobuild_button = QPushButton('Autobuild') + + # Preparing elements by giving initial values, etc + self.setMinimumHeight(500) + self.search.setPlaceholderText('Search...') + + # Setting all widgets in their places + layout = QVBoxLayout() + layout.addWidget(self.domains_list) + layout.addWidget(self.search) + layout.addWidget(self.functions_list) + layout.addWidget(self.autobuild_button) + self.setLayout(layout) + + self.domains_list.activated[str].connect(self.on_select_domain) + self.search.textEdited.connect(self.on_search) + self.autobuild_button.clicked.connect(self.on_autobuild) + self.settings.package_changed.connect(self.init_selection_panel) + self.settings.tl_changed.connect(self.refresh) + + def init_selection_panel(self): + if not self.settings.package.broken: + self.functions_dict = copy.deepcopy(self.settings.package.functions) + self.search.setEnabled(True) + self.refresh() + else: + self.search.setEnabled(False) + self.reset() + + def refresh(self): + self.domains_type = (self.settings.package.type if not self.settings.tl_group.isChecked() + else utils.THREADING_LAYER) + domains_list = self.functions_dict[self.domains_type].keys() + self.set_widget_items(self.domains_list, domains_list) + self.on_select_domain() + + def on_select_domain(self): + self.current_domain = self.domains_list.currentText() + self.on_search(self.search.text()) + + def on_search(self, search_request): + self.set_widget_items(self.functions_list, + [entry for entry in self.functions_dict[self.domains_type][self.current_domain] + if search_request.upper() in entry.upper()]) + + def on_autobuild(self): + self.autobuild.emit() + + def set_widget_items(self, widget, items): + """ + Adds items to widget + :param widget: widget + :param items: list of strings + """ + widget.clear() + widget.addItems(items) + + def reset(self): + self.domains_list.clear() + self.functions_list.clear() + + def add_function(self, function): + """ + Adds new function to required list + + :param function: name if function + """ + domain_type, domain, index = self.find_function(function) + self.functions_dict[domain_type][domain].insert(index, function) + if domain == self.current_domain: + self.functions_list.insertItem(index, QListWidgetItem(function)) + self.on_search(self.search.text()) + + def remove_function(self, function): + """ + Removes function from left list + """ + domain_type, domain, index = self.find_function(function) + self.functions_dict[domain_type][domain].remove(function) + if self.current_domain == domain: + item = self.functions_list.findItems(function, QtCore.Qt.MatchExactly) + if item: + self.functions_list.takeItem(self.functions_list.row(item[0])) + + def find_function(self, function_name): + previous_domain = '' + initial_functions_dict = self.settings.package.functions + + for domain_type, domain, function in utils.walk_dict(initial_functions_dict): + if domain != previous_domain: + index = 0 + + if function_name == function: + return domain_type, domain, index + elif function in self.functions_dict[domain_type][domain]: + previous_domain = domain + index = self.functions_dict[domain_type][domain].index(function) + 1 diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/settings_panel.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/settings_panel.py new file mode 100644 index 000000000..86f127400 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/gui/settings_panel.py @@ -0,0 +1,204 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import re + +from PyQt5 import QtCore +from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QGroupBox, QRadioButton, QCheckBox, QGridLayout, \ + QVBoxLayout, QFileDialog, QMessageBox + +import tool +from tool import utils + + +class SettingsPanel(QWidget): + package_changed = QtCore.pyqtSignal() + tl_changed = QtCore.pyqtSignal() + + def __init__(self): + super().__init__() + + # Initializing GUI elements + self.current_package = QLabel() + self.select_package = QPushButton('Select package') + + self.settings = QGroupBox('Settings') + + self.arch_group = QGroupBox('Architecture') + self.ia32 = QRadioButton('IA32') + self.intel64 = QRadioButton('Intel(R) 64') + + self.thread_group = QGroupBox('Thread mode') + self.single_threaded = QRadioButton('Single-threaded') + self.multi_threaded = QRadioButton('Multi-threaded') + + self.tl_group = QGroupBox('Threading layer') + self.tbb = QRadioButton('TBB') + self.omp = QRadioButton('OpenMP') + + self.custom_dispatch = QGroupBox('Custom dispatcher') + self.sse2 = QCheckBox('SSE2') + self.sse3 = QCheckBox('SSE3') + self.ssse3 = QCheckBox('SSSE3') + self.sse42 = QCheckBox('SSE4.2') + self.avx = QCheckBox('AVX') + self.avx2 = QCheckBox('AVX2') + self.avx512f = QCheckBox('AVX512F') + self.avx512bw = QCheckBox('AVX512BW') + self.avx512ifma = QCheckBox('AVX512IFMA') + + self.tl_group.setCheckable(True) + self.custom_dispatch.setCheckable(True) + + self.select_package.setFixedWidth(130) + + # Setting all widgets in their places + layout = QGridLayout() + layout.addWidget(self.select_package, 0, 0) + layout.addWidget(self.current_package, 0, 1) + layout.addWidget(self.settings, 1, 0, 1, 3) + self.setLayout(layout) + + settings_layout = QGridLayout() + settings_layout.addWidget(self.arch_group, 0, 0) + settings_layout.addWidget(self.thread_group, 0, 1) + settings_layout.addWidget(self.tl_group, 0, 2) + settings_layout.addWidget(self.custom_dispatch, 0, 3) + self.settings.setLayout(settings_layout) + + arch_layout = QVBoxLayout() + arch_layout.addWidget(self.intel64) + arch_layout.addWidget(self.ia32) + self.arch_group.setLayout(arch_layout) + + thread_layout = QVBoxLayout() + thread_layout.addWidget(self.single_threaded) + thread_layout.addWidget(self.multi_threaded) + self.thread_group.setLayout(thread_layout) + + tl_layout = QVBoxLayout() + tl_layout.addWidget(self.tbb) + tl_layout.addWidget(self.omp) + self.tl_group.setLayout(tl_layout) + + custom_dispatch_layout = QGridLayout() + + custom_dispatch_layout.addWidget(self.sse2, 1, 0) + custom_dispatch_layout.addWidget(self.sse3, 1, 1) + custom_dispatch_layout.addWidget(self.ssse3, 1, 2) + custom_dispatch_layout.addWidget(self.sse42, 1, 3) + + custom_dispatch_layout.addWidget(self.avx, 2, 0) + custom_dispatch_layout.addWidget(self.avx2, 2, 1) + custom_dispatch_layout.addWidget(self.avx512f, 2, 2) + custom_dispatch_layout.addWidget(self.avx512bw, 2, 3) + custom_dispatch_layout.addWidget(self.avx512ifma, 2, 4) + + self.custom_dispatch.setLayout(custom_dispatch_layout) + + self.select_package.clicked.connect(self.on_select_package) + self.ia32.toggled.connect(lambda checked: checked and self.on_switch_arch()) + self.intel64.toggled.connect(lambda checked: checked and self.on_switch_arch()) + self.tl_group.clicked.connect(self.on_switch_tl) + self.custom_dispatch.clicked.connect(self.on_switch_custom_dispatch) + + root = tool.package.get_package_path() + self.package = tool.package.Package(root) + + def init_settings(self): + self.current_package.setText('Current package: ' + self.package.name) + self.disable_widgets() + + if not self.package.broken: + arch_flags = {arch: any([self.package.features[arch][thread] for thread in utils.THREAD_MODES]) + for arch in utils.ARCHITECTURES} + self.refresh_group(self.arch_group, flags_dict=arch_flags) + + self.package_changed.emit() + + def on_switch_arch(self): + self.current_arch = (utils.IA32 if self.ia32.isChecked() else utils.INTEL64) + + self.refresh_group(self.thread_group, flags_dict=self.package.features[self.current_arch]) + self.refresh_group(self.tl_group, flags_dict=self.package.features[self.current_arch]) + self.on_switch_custom_dispatch() + + def on_switch_tl(self): + self.refresh_group(self.tl_group, flags_dict=self.package.features[self.current_arch]) + self.tl_changed.emit() + + def on_switch_custom_dispatch(self): + self.refresh_group(self.custom_dispatch, + search_list=utils.SUPPORTED_CPUS[self.package.type][self.current_arch][utils.HOST_SYSTEM]) + + def on_select_package(self): + while True: + chosen_path = QFileDialog.getExistingDirectory(self, 'Select package') + if not chosen_path: + break + + package = tool.package.Package(chosen_path) + if package.broken: + QMessageBox.information(self, 'ERROR!', package.error_message) + else: + self.package = package + self.init_settings() + break + + def refresh_group(self, group, flags_dict={}, search_list=[]): + group.setDisabled(True) + + for button in group.findChildren(QRadioButton) + group.findChildren(QCheckBox): + button_name = self.get_formatted_button_name(button) + + if flags_dict and flags_dict[button_name] or button_name in search_list: + group.setEnabled(True) + if not group.isCheckable() or group.isCheckable() and group.isChecked(): + button.setEnabled(True) + continue + + button.setChecked(False) + button.setEnabled(False) + + self.check_group(group) + + def check_group(self, group): + if not any([button.isChecked() for button in group.findChildren(QRadioButton)]): + for radiobutton in group.findChildren(QRadioButton): + if radiobutton.isEnabled(): + radiobutton.setChecked(True) + break + + for checkbox in group.findChildren(QCheckBox): + checkbox.setChecked(checkbox.isEnabled()) + + def disable_widgets(self): + for group in self.settings.findChildren(QGroupBox): + for button in group.findChildren(QRadioButton): + button.setAutoExclusive(False) + button.setChecked(False) + button.setAutoExclusive(True) + + for button in group.findChildren(QCheckBox): + button.setChecked(False) + + group.setChecked(False) + group.setEnabled(False) + + def get_formatted_button_name(self, button): + button_name = button.text().replace('(R)', '') + return re.sub('[^\w-]', '', button_name.lower()) diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/icon.ico b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/icon.ico new file mode 100644 index 000000000..53c57c42f Binary files /dev/null and b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/icon.ico differ diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/main.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/main.py new file mode 100644 index 000000000..5f6716549 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/main.py @@ -0,0 +1,166 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import sys +import os +from argparse import ArgumentParser, RawTextHelpFormatter + +import tool.package +from tool import utils +from tool.core import build, generate_script + + +if __name__ == '__main__': + utils.set_host_system() + + args_parser = ArgumentParser(formatter_class=RawTextHelpFormatter) + args_parser.add_argument('-c', '--console', + help='Turns on console version.\n' + 'Custom Library Tool is running in GUI mode by default', + action='store_true') + + console_args = args_parser.add_argument_group('Console mode options') + console_args.add_argument('-g', '--generate', + help='Generate build script without building custom dynamic library', + action='store_true') + console_args.add_argument('-n', '--name', + help='Name of custom dynamic library', + default=utils.CONFIGS[utils.CUSTOM_LIBRARY_NAME]) + console_args.add_argument('-p', '--output_path', + help='Path to output directory', + default=utils.CONFIGS[utils.OUTPUT_PATH]) + console_args.add_argument('-root', + help='Path to specified ' + utils.PACKAGE_NAME[utils.IPP] + + '\nor ' + utils.PACKAGE_NAME[utils.IPPCP] + ' package') + console_args.add_argument('-f', '--functions', + help='Functions that has to be in dynamic library (appendable)', + nargs='+', + metavar='FUNCTION') + console_args.add_argument('-ff', '--functions_file', + help='Load custom functions list from text file') + console_args.add_argument('-arch', '--architecture', + help='Target architecture', + choices=utils.ARCHITECTURES, + default='intel64') + console_args.add_argument('-mt', '--multi-threaded', + help='Build multi-threaded dynamic library', + action='store_true') + console_args.add_argument('-tl', '--threading_layer_type', + help='Build dynamic library with selected threading layer type', + choices=utils.TL_TYPES) + console_args.add_argument('-d', '--custom_dispatcher', + help='Build dynamic library with custom dispatcher.\n' + 'Set of CPUs can be any combination of the following:\n' + + utils.PACKAGE_NAME[utils.IPP] + ':\n' + '\tIA32 architecture - ' + ' '.join(utils.SUPPORTED_CPUS[utils.IPP] + [utils.IA32] + [utils.HOST_SYSTEM]) + '\n' + + '\tIntel 64 architecture - ' + ' '.join(utils.SUPPORTED_CPUS[utils.IPP] + [utils.INTEL64] + [utils.HOST_SYSTEM]) + '\n' + + utils.PACKAGE_NAME[utils.IPPCP] + ':\n' + '\tIA32 architecture - ' + ' '.join(utils.SUPPORTED_CPUS[utils.IPPCP] + [utils.IA32] + [utils.HOST_SYSTEM]) + '\n' + + '\tIntel 64 architecture - ' + ' '.join(utils.SUPPORTED_CPUS[utils.IPPCP] + [utils.INTEL64] + [utils.HOST_SYSTEM]), + nargs='+', + metavar='CPU') + console_args.add_argument('--prefix', + help='Rename functions in custom dispatcher with specified prefix', + default='') + + args = args_parser.parse_args() + + if args.console: + print('Intel(R) Integrated Performance Primitives Custom Library Tool console version is on...') + + functions_list = [] + if args.functions_file: + with open(args.functions_file, 'r') as functions_file: + functions_list += map(lambda x: x.replace('\n', ''), functions_file.readlines()) + if args.functions: + functions_list += args.functions + if not functions_list: + sys.exit("Please, specify functions that has to be in dynamic library by using -f or -ff options") + + if args.root: + root = args.root + if not os.path.exists(root): + sys.exit("Error: specified package path " + args.root + " doesn't exist") + else: + root = tool.package.get_package_path() + if not os.path.exists(root): + sys.exit("Error: cannot find " + utils.PACKAGE_NAME[utils.IPP] + ' or ' + + utils.PACKAGE_NAME[utils.IPPCP] + " package. " + "Please, specify IPPROOT or IPPCRYPTOROOT by using -root option") + + package = tool.package.Package(root) + print('Current package: ' + package.name) + + architecture = args.architecture + thread_mode = (utils.MULTI_THREADED if args.multi_threaded else utils.SINGLE_THREADED) + threading_layer_type = args.threading_layer_type + + error = package.errors[architecture][thread_mode] + if error: + sys.exit('Error: ' + error) + if threading_layer_type: + error = package.errors[architecture][threading_layer_type] + if error: + sys.exit('Error: ' + error) + + custom_cpu_set = [] + if args.custom_dispatcher: + for cpu in args.custom_dispatcher: + if cpu not in utils.SUPPORTED_CPUS[package.type][architecture][utils.HOST_SYSTEM]: + sys.exit("Error: " + cpu + " isn't supported for " + utils.PACKAGE_NAME[package.type] + ' ' + + utils.HOST_SYSTEM + ' ' + architecture) + custom_cpu_set = args.custom_dispatcher + prefix = args.prefix + + custom_library_name = args.name + output_path = os.path.abspath(args.output_path) + if not os.path.exists(output_path): + os.makedirs(output_path) + + utils.set_configs_dict(package=package, + functions_list=functions_list, + architecture=architecture, + thread_mode=thread_mode, + threading_layer_type=threading_layer_type, + custom_library_name=custom_library_name, + output_path=output_path, + custom_cpu_set=custom_cpu_set, + prefix=prefix) + + if args.generate: + success = generate_script() + print('Generation', 'completed!' if success else 'failed!') + else: + success = build() + + if not success: + exit(1) + else: + from PyQt5.QtWidgets import QApplication + from gui.app import MainAppWindow + + app = QApplication(sys.argv) + ex = MainAppWindow() + sys.exit(app.exec_()) diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/requirements.txt b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/requirements.txt new file mode 100644 index 000000000..be36e3736 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/requirements.txt @@ -0,0 +1,2 @@ +PyQt5==5.15.9 + diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tests/functions_tests.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tests/functions_tests.py new file mode 100644 index 000000000..86f4a6020 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tests/functions_tests.py @@ -0,0 +1,86 @@ +""" +Copyright 2019-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import os +import shutil +import unittest +from sys import platform + +import tests.utils +from tool.core import generate_script, build + + +class FunctionalityTests(unittest.TestCase): + functions = ['ippccGetLibVersion', + 'ippdcGetLibVersion', + 'ippchGetLibVersion', + 'ippsGetLibVersion'] + domains = ['ippcc', + 'ippdc', + 'ippch', + 'ipps', + 'ippcore', + 'ippvm'] + + def generator_assertion(self): + self.assertTrue(os.path.exists('./tmp'), 'Temporary folder does not exist') + self.assertTrue(os.path.exists('./tmp/main.c'), 'main.c file was not generated') + self.assertTrue(os.path.exists('./tmp/' + tests.utils.EXPORT_FILES[tests.utils.HOST_SYSTEM]), + 'Export file was not generated') + self.assertTrue(os.path.exists('./tmp/' + + tests.utils.BUILD_SCRIPT[tests.utils.INTEL64][tests.utils.HOST_SYSTEM]), + 'Build script was not generated') + + @classmethod + def setUpClass(cls): + if platform == "linux" or platform == "linux2": + tests.utils.HOST_SYSTEM = tests.utils.LINUX + elif platform == "darwin": + tests.utils.HOST_SYSTEM = tests.utils.MACOSX + elif platform == "win32": + tests.utils.HOST_SYSTEM = tests.utils.WINDOWS + + @classmethod + def tearDown(self): + if os.path.exists(tests.utils.TEMPORARY_FOLDER): + shutil.rmtree(tests.utils.TEMPORARY_FOLDER, ignore_errors=True) + + def test_generation(self): + generate_script(tests.utils.HOST_SYSTEM, + tests.utils.HOST_SYSTEM, + self.functions, + tests.utils.TEMPORARY_FOLDER, + 'tmp_dll', + self.domains, + tests.utils.INTEL64, + False) + self.generator_assertion() + + def test_build(self): + self.assertTrue(build(tests.utils.HOST_SYSTEM, + tests.utils.HOST_SYSTEM, + self.functions, + os.path.abspath(tests.utils.TEMPORARY_FOLDER), + 'tmp_dll', + self.domains, + tests.utils.INTEL64, + False, + os.environ['COMPILERS_AND_LIBRARIES'])) + + +if __name__ == '__main__': + unittest.main() diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tests/utils.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tests/utils.py new file mode 100644 index 000000000..ea3289b81 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tests/utils.py @@ -0,0 +1,58 @@ +""" +Copyright 2019-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +HOST_SYSTEM = '' + +WINDOWS = 'Windows' +LINUX = 'Linux' +MACOSX = 'MacOSX' + +TEMPORARY_FOLDER = './tmp' + +INTEL64 = 'intel64' +IA32 = 'ia32' + +BUILD_SCRIPT = { + INTEL64: { + WINDOWS: 'intel64.bat', + LINUX: 'intel64.sh', + MACOSX: 'intel64.sh' + }, + IA32: { + WINDOWS: 'ia32.bat', + LINUX: 'ia32.sh', + MACOSX: 'ia32.sh' + } +} + +EXPORT_FILES = { + WINDOWS: 'export.def', + LINUX: 'export.def', + MACOSX: 'export.lib-export' +} + +LIBRARIES_EXTENSIONS = { + WINDOWS: '.dll', + LINUX: '.so', + MACOSX: '.dy' +} + +LIBRARIES_PREFIX = { + WINDOWS: '', + LINUX: 'lib', + MACOSX: 'lib' +} diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/core.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/core.py new file mode 100644 index 000000000..f6a323d67 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/core.py @@ -0,0 +1,89 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" + +import os +from subprocess import call # nosec + +from tool import utils +from tool.generators import main_file_generator, EXPORT_GENERATORS, build_script_generator, custom_dispatcher_generator, \ + rename_header_generator + + +def generate_script(): + """ + Generates build script + """ + host = utils.HOST_SYSTEM + configs = utils.CONFIGS + + package = configs[utils.PACKAGE] + functions_list = configs[utils.FUNCTIONS_LIST] + output_path = configs[utils.OUTPUT_PATH] + + if not os.path.exists(output_path): + os.makedirs(output_path) + + with open(os.path.join(output_path, utils.MAIN_FILE_NAME), 'w') as main_file: + main_file.write(main_file_generator()) + + if configs[utils.CUSTOM_CPU_SET]: + disp_folder = os.path.join(output_path, 'custom_dispatcher', configs[utils.ARCHITECTURE]) + if not os.path.exists(disp_folder): + os.makedirs(disp_folder) + + functions_with_custom_disp = [] + for function in functions_list: + if function not in package.functions_without_dispatcher: + disp_file_path = os.path.join(disp_folder, + utils.CUSTOM_DISPATCHER_FILE_NAME.format(function=function)) + functions_with_custom_disp.append(function) + + with open(disp_file_path, 'w') as disp_file: + disp_file.write(custom_dispatcher_generator(function)) + + if configs[utils.PREFIX]: + with open(os.path.join(disp_folder, utils.RENAME_HEADER_NAME), 'w') as rename_header: + rename_header.write(rename_header_generator(functions_with_custom_disp)) + + functions_list = [configs[utils.PREFIX] + func if func in functions_with_custom_disp else func + for func in functions_list] + + with open(os.path.join(output_path, utils.EXPORT_FILE[host]), 'w') as export_file: + EXPORT_GENERATORS[host](export_file, functions_list) + + script_path = os.path.join(output_path, configs[utils.BUILD_SCRIPT_NAME]) + with open(script_path, 'w') as build_script: + build_script.write(build_script_generator()) + os.chmod(script_path, 0o744) + + return os.path.exists(script_path) + + +def build(): + """ + Builds dynamic library + + :return: True if build was successful and False in the opposite case + """ + success = generate_script() + if not success: + return False + + error = call([os.path.join(utils.CONFIGS[utils.OUTPUT_PATH], + utils.CONFIGS[utils.BUILD_SCRIPT_NAME])]) + return False if error else True diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/generators.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/generators.py new file mode 100644 index 000000000..078c73340 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/generators.py @@ -0,0 +1,224 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +from tool import utils +from tool.generators_utils import * + + +def main_file_generator(): + return MAIN_FILE[utils.HOST_SYSTEM].format(package_type=utils.CONFIGS[PACKAGE].type.lower()) + + +def create_windows_export_file(export_file, functions_list): + """ + Creates export file for Windows + + :param export_file: object that is returned by open function + :param functions_list: list of functions for dynamic library + """ + export_file.write('EXPORTS\n\n') + export_file.writelines(map(lambda x: x + '\n', functions_list)) + + +def create_linux_export_file(export_file, functions_list): + """ + Creates Linux export file + + :param export_file: + :param functions_list: + :return: + """ + export_file.writelines(map(lambda x: 'EXTERN(' + x + ')\n', functions_list)) + export_file.write('\nVERSION\n' + '{\n' + ' {\n' + ' global:\n' + + ''.join( + map(lambda x: ' ' + x + ';\n', functions_list)) + + ' local:* ;\n' + ' };\n' + '}\n') + + +def create_macosx_export_file(export_file, functions_list): + """ + Creates MacOSX export file + + :param export_file: object that is returned by open function + :param functions_list: list of functions for dynamic library + """ + export_file.writelines(map(lambda x: '_' + x + '\n', functions_list)) + + +EXPORT_GENERATORS = { + WINDOWS: create_windows_export_file, + LINUX: create_linux_export_file, + MACOSX: create_macosx_export_file +} + + +def custom_dispatcher_generator(function): + package = utils.CONFIGS[PACKAGE] + arch = utils.CONFIGS[ARCHITECTURE] + include_lines = INCLUDE_STR.format(header_name=package.type.lower() + '.h') + + dispatcher = '' + dispatcher += func_dispatcher_generator(arch, function) + + ippe = utils.DOMAINS[IPP]['ippe'] + if ippe in package.functions[IPP].keys() and \ + function in package.functions[IPP][ippe]: + include_lines += INCLUDE_STR.format(header_name='ippe.h') + + return CUSTOM_DISPATCHER_FILE.format(include_lines=include_lines, + architecture=ARCHITECTURE_DEFINE[arch], + features=FEATURES[arch], + dispatcher=dispatcher) + + +def rename_header_generator(functions_list): + package = utils.CONFIGS[PACKAGE] + prefix = utils.CONFIGS[PREFIX] + + defs_header = ('defs.h' if package.type == IPP or package.type == IPPCP else 'base.h') + content = INCLUDE_STR.format(header_name=package.type.lower() + defs_header) + for function in functions_list: + declaration = package.declarations[function].replace(function, prefix + function) + content += RENAME_FORMAT.format(declaration=declaration, + function=function, + prefix=prefix) + + return content + + +def func_dispatcher_generator(arch, function): + package_type = utils.CONFIGS[PACKAGE].type + declarations = utils.CONFIGS[PACKAGE].declarations[function] + ippfun = declarations.replace('IPPAPI', 'IPPFUN').replace(function, utils.CONFIGS[PREFIX] + function) + + args = utils.get_match(utils.FUNCTION_NAME_REGEX, declarations, 'args').split(',') + args = [utils.get_match(utils.ARGUMENT_REGEX, arg, 'arg') for arg in args] + args = ', '.join(args) + + ippapi = '' + dispatching_scheme = '' + for cpu in CPUID.keys(): + if cpu not in utils.CONFIGS[CUSTOM_CPU_SET]: + continue + + cpuid = CPUID[cpu] + cpu_code = CPU[cpu][arch] + + function_with_cpu_code = cpu_code + '_' + function + ippapi += declarations.replace(function, function_with_cpu_code) + '\n' + + dispatching_scheme += DISPATCHING_SCHEME_FORMAT.format(cpuid=cpuid, + function=function_with_cpu_code, + args=args) + + ret_type = utils.get_match(utils.FUNCTION_NAME_REGEX, declarations, 'ret_type') + ret_value = get_dict_value(RETURN_VALUES, ret_type) + + dispatching_scheme += ' return ' + ret_value + ';\n' + if not ret_value: + dispatching_scheme = dispatching_scheme.replace('return', '') + + return FUNCTION_DISPATCHER.format(ippapi=ippapi, + ippfun=ippfun, + package_type=package_type.lower(), + dispatching_scheme=dispatching_scheme) + + +def build_script_generator(): + """ + Generates script for building custom dynamic library + :return: String that represents script + """ + host = utils.HOST_SYSTEM + configs = utils.CONFIGS + + package = configs[PACKAGE] + output_path = configs[OUTPUT_PATH] + + arch = configs[ARCHITECTURE] + thread = configs[THREAD_MODE] + tl = configs[THREADING_LAYER] + + root_type = (IPPROOT if package.type == IPP else IPPCRYPTOROOT) + + if package.env_script: + force_flag = '' + if 'setvars' in package.env_script: + force_flag = '--force' + + env_commands = CALL_ENV_SCRIPT_COMMAND[host].format(env_script=package.env_script, + arch=arch, + force_flag=force_flag) + else: + env_commands = SET_ENV_COMMAND[host].format(env_var=root_type, + path=package.root) + if ADDITIONAL_ENV[host]: + env_commands += '\n' + ADDITIONAL_ENV[host] + + compiler = COMPILERS[host] + + cmp_flags = COMPILERS_FLAGS[host][arch] + if tl == OPENMP and host == WINDOWS: + cmp_flags += ' /openmp' + + c_files = MAIN_FILE_NAME + if configs[utils.CUSTOM_CPU_SET]: + c_files += ' ' + os.path.join('custom_dispatcher', arch, '*.c') + + compile_command = COMPILE_COMMAND_FORMAT[host].format(compiler=compiler, + cmp_flags=cmp_flags, + root_type=root_type, + c_files=c_files) + + linker = LINKERS[host] + link_flags = LINKER_FLAGS[host][arch] + custom_library = LIB_PREFIX[host] + configs[CUSTOM_LIBRARY_NAME] + export_file = EXPORT_FILE[host] + + ipp_libraries = package.libraries[arch][thread] + if tl: + ipp_libraries = package.libraries[arch][tl] + ipp_libraries + ipp_libraries = [lib.replace(package.root, ENV_VAR[host].format(env_var=root_type)) + for lib in ipp_libraries] + ipp_libraries = ' '.join('"{0}"'.format(lib) for lib in ipp_libraries) + + exp_libs = EXP_LIBS[host][thread] + if tl and EXP_LIBS[host][tl] not in exp_libs: + exp_libs += ' ' + EXP_LIBS[host][tl] + + sys_libs_path = SYS_LIBS_PATH[host][arch] + + link_command = LINK_COMMAND_FORMAT[host].format(linker=linker, + link_flags=link_flags, + custom_library=custom_library, + export_file=export_file, + ipp_libraries=ipp_libraries, + exp_libs=exp_libs, + sys_libs_path=sys_libs_path,) + + return BUILD_SCRIPT[host].format(architecture=arch, + threading=thread.lower(), + output_path=output_path, + custom_library=custom_library, + env_commands=env_commands, + compile_command=compile_command, + link_command=link_command) diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/generators_utils.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/generators_utils.py new file mode 100644 index 000000000..3efda3506 --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/generators_utils.py @@ -0,0 +1,326 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" + +from tool.utils import * + +ENV_VAR = { + WINDOWS : '%{env_var}%', + LINUX : '${{{env_var}}}', + MACOSX : '${{{env_var}}}' +} + +CALL_ENV_SCRIPT_COMMAND = { + WINDOWS : 'call "{env_script}" {arch} {force_flag}', + LINUX : 'source "{env_script}" -arch {arch} {force_flag}', + MACOSX : 'source "{env_script}" -arch {arch} {force_flag}' +} + +SET_ENV_COMMAND = { + WINDOWS : 'set "{env_var}={path}"', + LINUX : 'export "{env_var}={path}"', + MACOSX : 'export "{env_var}={path}"' +} + +ADDITIONAL_ENV = { + WINDOWS : '', + LINUX : 'export LIBRARY_PATH=$LD_LIBRARY_PATH:$LIBRARY_PATH', + MACOSX : 'export LIBRARY_PATH=$DYLD_LIBRARY_PATH:$LIBRARY_PATH' +} + +COMPILERS = { + WINDOWS : 'cl.exe', + LINUX : 'g++', + MACOSX : 'clang' +} + +LINKERS = { + WINDOWS : 'link.exe', + LINUX : 'g++', + MACOSX : 'clang' +} + +COMPILERS_FLAGS = { + WINDOWS: { + INTEL64 : '/c /MP /MT /GS /sdl /O2', + IA32 : '/c /MP /MT /GS /sdl /O2' + }, + LINUX: { + INTEL64: '-c -m64 -fPIC -fPIE -fstack-protector-strong ' + + '-fstack-protector -O2 -D_FORTIFY_SOURCE=2 ' + + '-Wformat -Wformat-security', + IA32: '-c -m32 -fPIC -fPIE -fstack-protector-strong ' + + '-fstack-protector -O2 -D_FORTIFY_SOURCE=2 ' + + '-Wformat -Wformat-security' + }, + MACOSX: { + INTEL64 : '-c -m64', + IA32 : '-c -m32' + } +} + +LINKER_FLAGS = { + WINDOWS: { + INTEL64 : '/MACHINE:X64 /NXCompat /DynamicBase ', + IA32 : '/MACHINE:X86 /SafeSEH /NXCompat /DynamicBase' + }, + LINUX: { + INTEL64 : '-z noexecstack -z relro -z now', + IA32 : '-m32 -z noexecstack -z relro -z now' + }, + MACOSX: { + INTEL64: '-dynamiclib -single_module ' + + '-flat_namespace -headerpad_max_install_names ' + + '-current_version 2017.0 -compatibility_version 2017.0', + IA32: '-dynamical -single_module ' + + '-flat_namespace -headerpad_max_install_names ' + + '-current_version 2017.0 -compatibility_version 2017.0' + } +} + +COMPILE_COMMAND_FORMAT = { + WINDOWS: '{compiler} {cmp_flags} ' + '/I "%{root_type}%\\include" ' + '{c_files}', + LINUX: '{compiler} {cmp_flags}' + ' -I "${root_type}/include" ' + '{c_files}', + MACOSX: '{compiler} {cmp_flags} ' + '-I "${root_type}/include" ' + '{c_files}' +} + +LINK_COMMAND_FORMAT = { + WINDOWS: '{linker} /DLL {link_flags} /VERBOSE:SAFESEH ' + '/DEF:"{export_file}" *.obj ' + '/OUT:"{custom_library}.dll" /IMPLIB:"{custom_library}.lib" ' + '{ipp_libraries} ' + '{exp_libs}', + LINUX: '{linker} -shared {link_flags} ' + '"{export_file}" *.o ' + '-o "{custom_library}.so" ' + '{ipp_libraries} ' + '-L"{sys_libs_path}" -lc -lm {exp_libs}', + MACOSX: '{linker} {link_flags} ' + '-install_name @rpath/{custom_library}.dylib ' + '-o "{custom_library}.dylib" ' + '-exported_symbols_list "{export_file}" *.o ' + '{ipp_libraries} ' + '-lgcc_s.1 -lm {exp_libs}' +} + +SYS_LIBS_PATH = { + WINDOWS: { + INTEL64 : '', + IA32 : '', + }, + LINUX: { + INTEL64 : '$SYSROOT/lib64', + IA32 : '$SYSROOT/lib' + }, + MACOSX: { + INTEL64 : '', + IA32 : '' + } +} + +EXP_LIBS = { + WINDOWS: { + SINGLE_THREADED : '', + MULTI_THREADED : 'libiomp5md.lib', + TBB : 'tbb.lib', + OPENMP : 'libiomp5md.lib' + }, + LINUX: { + SINGLE_THREADED : '', + MULTI_THREADED : '-liomp5', + TBB : '-ltbb', + OPENMP : '-liomp5' + }, + MACOSX: { + SINGLE_THREADED : '', + MULTI_THREADED : '-liomp5', + TBB : '"${TBBROOT}/lib/libtbb.dylib"', + OPENMP : '-liomp5' + } +} + +MAIN_FILE = { + WINDOWS: "#include \n" + "#include \"{package_type}.h\"\n\n" + "int WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\n" + "{{\n" + " switch (fdwReason)\n" + " {{\n" + " case DLL_PROCESS_ATTACH:\n" + " {package_type}Init(); break;\n" + " case DLL_THREAD_ATTACH: break;\n" + " case DLL_THREAD_DETACH: break;\n" + " case DLL_PROCESS_DETACH: break;\n" + " default: break;\n" + " }}\n" + " return 1;\n" + " UNREFERENCED_PARAMETER(hinstDLL);\n" + " UNREFERENCED_PARAMETER(lpvReserved);\n" + "}}\n", + LINUX: "#include \"{package_type}.h\"\n\n" + "int _init(void)\n" + "{{\n" + " {package_type}Init();\n" + " return 1;\n" + "}}\n\n" + "void _fini(void)\n" + "{{\n" + "}}\n", + MACOSX: "#include \"{package_type}.h\"\n\n" + "__attribute__((constructor)) void initializer( void )\n" + "{{\n" + " static int initialized = 0;\n" + " if (!initialized)\n" + " {{\n" + " initialized = 1;\n" + " }}\n\n" + " {package_type}Init();\n" + " return;\n" + "}}\n\n" + "__attribute__((destructor)) void destructor()\n" + "{{\n" + "}}\n" +} + +CUSTOM_DISPATCHER_FILE = '{include_lines}\n'\ + '#ifndef IPP_CALL\n' \ + '#define IPP_CALL IPP_STDCALL\n' \ + '#endif\n'\ + '#define IPPFUN(type,name,arg) extern type IPP_CALL name arg\n\n'\ + '#ifndef NULL\n'\ + '#ifdef __cplusplus\n'\ + '#define NULL 0\n'\ + '#else\n'\ + '#define NULL ((void *)0)\n'\ + '#endif\n'\ + '#endif\n\n'\ + '{architecture}\n'\ + '{features}\n'\ + '#ifdef __cplusplus\n'\ + 'extern "C" {{\n'\ + '#endif\n\n'\ + '{dispatcher}'\ + '#ifdef __cplusplus\n'\ + '}}\n'\ + '#endif\n\n'\ + '#endif\n' + +RENAME_FORMAT = '\n\n{declaration}\n' \ + '#define {function} {prefix}{function}' + +INCLUDE_STR = '#include "{header_name}"\n' + +ARCHITECTURE_DEFINE = { + IA32 : '#if !defined (_M_AMD64) && !defined (__x86_64__)', + INTEL64 : '#if defined (_M_AMD64) || defined (__x86_64__)' +} + +FEATURES = { + IA32: '', + INTEL64: '\n#define AVX3I_FEATURES ( ippCPUID_SHA|ippCPUID_AVX512VBMI|' + 'ippCPUID_AVX512VBMI2|ippCPUID_AVX512IFMA|ippCPUID_AVX512GFNI|' + 'ippCPUID_AVX512VAES|ippCPUID_AVX512VCLMUL )\n' + '#define AVX3X_FEATURES ( ippCPUID_AVX512F|ippCPUID_AVX512CD|' + 'ippCPUID_AVX512VL|ippCPUID_AVX512BW|ippCPUID_AVX512DQ )\n' + '#define AVX3M_FEATURES ( ippCPUID_AVX512F|ippCPUID_AVX512CD|' + 'ippCPUID_AVX512PF|ippCPUID_AVX512ER )\n' +} + +FUNCTION_DISPATCHER = '{ippapi}\n'\ + '{ippfun}\n'\ + '{{\n'\ + ' Ipp64u _features;\n'\ + ' _features = {package_type}GetEnabledCpuFeatures();\n\n'\ + '{dispatching_scheme}'\ + '}}\n\n' + +DISPATCHING_SCHEME_FORMAT = ' if( {cpuid} == ( _features & {cpuid} )) {{\n'\ + ' return {function}( {args} );\n'\ + ' }} else \n' + +RETURN_VALUES = { + 'IppStatus' : 'ippStsCpuNotSupportedErr', + 'IppiRect' : '(IppiRect) { IPP_MIN_32S / 2, IPP_MIN_32S / 2, ' + 'IPP_MAX_32S, IPP_MAX_32S }', + 'void' : '', + 'default' : 'NULL' +} + +BUILD_SCRIPT = { + WINDOWS: ':: Generates {threading} dynamic library ' + + 'for {architecture} architecture\n' + + '@echo off\n' + + 'set "OUTPUT_PATH={output_path}"\n' + + 'if not exist %OUTPUT_PATH% mkdir %OUTPUT_PATH%\n' + + 'if exist "{custom_library}.dll" del "{custom_library}.dll"\n\n' + + 'setlocal\n' + + '{env_commands}\n' + + 'cd /d %OUTPUT_PATH%\n' + + '{compile_command}\n' + + '{link_command}\n' + + 'endlocal\n\n' + + 'if %ERRORLEVEL%==0 (\n' + + ' echo Build completed!\n' + + ' del /s /q /f *.obj > nul\n' + + ' exit /b 0\n' + + ') else (\n' + + ' echo Build failed!\n' + + ' exit /b 1\n' + + ')', + LINUX: '#!/bin/bash\n' + + '# Generates {threading} dynamic library ' + + 'for {architecture} architecture\n' + + 'OUTPUT_PATH="{output_path}"\n' + + 'mkdir -p $OUTPUT_PATH\n' + + 'cd $OUTPUT_PATH\n\n' + + 'rm -rf "{custom_library}.so"\n\n' + + '{env_commands}\n' + + '{compile_command}\n' + + '{link_command}\n' + + 'if [ $? == 0 ]; then\n' + + ' echo Build completed!\n' + + ' rm -rf *.o\n' + + ' exit 0\n' + + 'else\n' + + ' echo Build failed!\n' + + ' exit 1\n' + + 'fi', + MACOSX: '#!/bin/bash\n' + + '# Generates {threading} dynamic library ' + + 'for {architecture} architecture\n' + + 'OUTPUT_PATH="{output_path}"\n' + + 'mkdir -p $OUTPUT_PATH\n' + + 'cd $OUTPUT_PATH\n\n' + + 'rm -rf "{custom_library}.dylib"\n\n' + + '{env_commands}\n' + + '{compile_command}\n' + + '{link_command}\n\n' + + 'if [ $? == 0 ]; then\n' + + ' echo Build completed!\n' + + ' rm -rf *.o\n' + + ' exit 0\n' + + 'else\n' + + ' echo Build failed!\n' + + ' exit 1\n' + + 'fi' +} diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/package.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/package.py new file mode 100644 index 000000000..da1f96f3d --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/package.py @@ -0,0 +1,231 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import os +from collections import defaultdict + +from tool import utils + + +class Package: + def __init__(self, path): + self.root = path + self.headers_dir = os.path.join(self.root, 'include') + self.libraries_dir = os.path.join(self.root, 'lib') + + self.headers = utils.nested_dict_init() + self.functions = utils.nested_dict_init() + self.declarations = defaultdict() + + self.libraries = utils.nested_dict_init() + self.features = utils.nested_dict_init() + self.errors = utils.nested_dict_init() + + self.functions_without_dispatcher = [] + + self.set_type() + self.set_env_script() + + self.set_headers_functions_declarations_dicts() + self.set_libraries_features_errors_dicts(self.type, utils.THREAD_MODES) + self.set_libraries_features_errors_dicts(utils.THREADING_LAYER, utils.TL_TYPES) + + self.package_validation() + self.set_name() + + def set_type(self): + header = os.path.join(self.headers_dir, 'ippcp.h') + self.type = (utils.IPP if not os.path.exists(header) else utils.IPPCP) + + def set_name(self): + self.name = 'None' + version = self.get_version() + + if not self.broken: + self.name = utils.PACKAGE_NAME[self.type] + ' Version ' + version + + def get_version(self): + version = '' + header = os.path.join(self.headers_dir, 'ippversion.h') + + for line in utils.get_lines_from_file(header): + version = utils.get_match(utils.VERSION_REGEX, line, 'ver') + if version: + break + if not version: + version = 'None' + + version = self.parse_version_string(version, header) + + return version + + def parse_version_string(self, version, header): + while True: + macros = utils.get_match(utils.STR_MACROS_REGEX, version, 'macros') + if not macros: + break + + macros_value = '' + for line in utils.get_lines_from_file(header): + if macros in line: + macros_value = line.split(macros, 1)[1].strip() + break + + version = version.replace('STR(' + macros + ')', macros_value) + + while True: + c_string = utils.get_match(utils.C_STRING_REGEX, version, 'string') + if not c_string: + break + + c_string_value = utils.get_match(utils.C_STRING_VALUE_REGEX, c_string, 'value') + version = version.replace(c_string, c_string_value) + + return version + + def set_env_script(self): + paths_to_search = [] + batch_extension = utils.BATCH_EXTENSIONS[utils.HOST_SYSTEM] + + components_install_dir = utils.get_match(utils.COMPONENTS_INSTALL_DIR_REGEX, self.root, 'path') + if components_install_dir: + paths_to_search.append(os.path.join(components_install_dir, 'setvars' + batch_extension)) + paths_to_search.append(os.path.join(components_install_dir, 'bin', 'compilervars' + batch_extension)) + paths_to_search.append(os.path.join(self.root, 'bin', self.type.lower() + 'vars' + batch_extension)) + paths_to_search.append(os.path.join(self.root, 'env', 'vars' + batch_extension)) + + self.env_script = utils.get_first_existing_path_in_list(paths_to_search) + + def set_headers_functions_declarations_dicts(self): + if not os.path.exists(self.headers_dir): + return + + headers = [header for header in os.listdir(self.headers_dir) if '.h' in header] + + for header in headers: + domain_type, domain = self.get_type_and_domain(header) + if not domain: + continue + + functions_list = [] + incomplete_function = '' + for line in utils.get_lines_from_file(os.path.join(self.headers_dir, header)): + if incomplete_function: + self.declarations[incomplete_function] += ' ' + " ".join(line.split()) + incomplete_function = self.get_function_if_incomplete(incomplete_function) + continue + + function = utils.get_match(utils.FUNCTION_NAME_REGEX, line, 'function_name') + if not function: + continue + functions_list.append(function) + self.declarations[function] = " ".join(line.split()) + incomplete_function = self.get_function_if_incomplete(function) + + if not functions_list: + continue + + self.headers[domain_type][domain] = header + + domain_name = utils.DOMAINS[domain_type][domain] + if domain_name not in self.functions[domain_type]: + self.functions[domain_type][domain_name] = functions_list + else: + self.functions[domain_type][domain_name] += functions_list + + if header == 'ippcpdefs.h' or \ + domain_type == utils.THREADING_LAYER or \ + domain == 'ippcore': + self.functions_without_dispatcher += functions_list + + def set_libraries_features_errors_dicts(self, domains_type, thread_types): + host = utils.HOST_SYSTEM + + for arch in utils.ARCHITECTURES: + for thread_type in thread_types: + self.libraries[arch][thread_type] = [] + path_to_libraries = self.get_path_to_libraries(arch, thread_type) + + for domain in utils.DOMAINS[domains_type].keys(): + lib_name = utils.LIB_PREFIX[host] + \ + domain + \ + utils.STATIC_LIB_POSTFIX[host] + \ + utils.LIB_POSTFIX[thread_type] + \ + utils.STATIC_LIB_EXTENSION[host] + + lib_path = os.path.join(path_to_libraries, + lib_name) + + if os.path.exists(lib_path): + self.libraries[arch][thread_type].append(lib_path) + elif not domain == 'ippe': + self.libraries[arch][thread_type].clear() + break + + self.features[arch][thread_type] = bool(self.libraries[arch][thread_type]) + self.errors[arch][thread_type] = self.check_headers_and_libs(arch, domains_type, thread_type) + + def package_validation(self): + self.broken = True + self.error_message = self.errors[utils.INTEL64][utils.SINGLE_THREADED] + + for arch in utils.ARCHITECTURES: + for thread in utils.THREAD_MODES: + if self.features[arch][thread]: + self.broken = False + return + + def get_type_and_domain(self, header): + domain_type = (self.type if '_tl' not in header else utils.THREADING_LAYER) + for domain in utils.DOMAINS[domain_type].keys(): + if domain in header: + return domain_type, domain + return '', '' + + def get_function_if_incomplete(self, function): + if self.declarations[function].count('(') != self.declarations[function].count(')'): + return function + return '' + + def get_path_to_libraries(self, arch, thread_type): + paths_to_search = [os.path.join(self.libraries_dir, arch), + os.path.join(self.libraries_dir, arch + '_' + utils.HOST_SYSTEM[:3].lower()), + self.libraries_dir] + paths_to_search = [utils.PATH_TO_LIBRARIES[thread_type].format(libs_arch_dir=path) + for path in paths_to_search] + + return utils.get_first_existing_path_in_list(paths_to_search) + + def check_headers_and_libs(self, arch, domains_type, thread_type): + for domain in utils.DOMAINS[domains_type].keys(): + if domains_type not in self.headers.keys() or \ + (domain not in self.headers[domains_type].keys() and not domain == 'ippe'): + return "Broken package - cannot find header files for " + domains_type + " functions" + + if not self.libraries[arch][thread_type]: + return "Cannot find " + thread_type + " libraries for " + arch + " architecture" + + return '' + + +def get_package_path(): + current_path = os.path.realpath(__file__) + paths_to_search = [utils.get_match(utils.PATH_TO_PACKAGE_REGEX, current_path, 'path'), + utils.get_env(utils.IPPROOT), + utils.get_env(utils.IPPCRYPTOROOT)] + + return utils.get_first_existing_path_in_list(paths_to_search) diff --git a/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/utils.py b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/utils.py new file mode 100644 index 000000000..33e57932a --- /dev/null +++ b/plugin/ippcp/library/src/tools/ipp_custom_library_tool_python/tool/utils.py @@ -0,0 +1,348 @@ +""" +Copyright 2018-2021 Intel Corporation. + +This software and the related documents are Intel copyrighted materials, and +your use of them is governed by the express license under which they were +provided to you (License). Unless the License provides otherwise, you may not +use, modify, copy, publish, distribute, disclose or transmit this software or +the related documents without Intel's prior written permission. + +This software and the related documents are provided as is, with no express +or implied warranties, other than those that are expressly stated in the +License. + +License: +http://software.intel.com/en-us/articles/intel-sample-source-code-license-agr +eement/ +""" +import os +import sys +import re +from platform import system +from collections import defaultdict + +WINDOWS = 'Windows' +LINUX = 'Linux' +MACOSX = 'MacOS' +HOST_SYSTEM = None +SUPPORTED_SYSTEMS = [WINDOWS, LINUX, MACOSX] + +IA32 = 'ia32' +INTEL64 = 'intel64' +ARCHITECTURES = [IA32, INTEL64] + +SINGLE_THREADED = 'single-threaded' +MULTI_THREADED = 'multi-threaded' +THREAD_MODES = [SINGLE_THREADED, MULTI_THREADED] + +TBB = 'tbb' +OPENMP = 'openmp' +TL_TYPES = [TBB, OPENMP] + +PATH_TO_PACKAGE_REGEX = '(?P.*)\Wtools\W.*' +COMPONENTS_INSTALL_DIR_REGEX = '(?P.*)\Wipp.*' +VERSION_REGEX = '.*VERSION_STR\s*(?P.*)\s*' +STR_MACROS_REGEX = '.*STR\((?P\S*)\).*' +C_STRING_REGEX = '.*(\S|^)(?P\s*".*"\s*)(\S|$).*' +C_STRING_VALUE_REGEX = '.*"(?P.*)".*' +FUNCTION_NAME_REGEX = 'IPPAPI\s*\(\s*(?P.*?)\s*,' \ + '\s*(?P\S*)\s*,' \ + '\s*\(?(?P.*?)\s*\)?\s*\)?\s*$' +ARGUMENT_REGEX = '.*\W*\w+\W*\s+\W*(?P[^\W\d]+\w*)\W*?' + +CUSTOM_LIBRARY_NAME = 'Custom library name' +BUILD_SCRIPT_NAME = 'Build script name' +OUTPUT_PATH = 'Output path' +FUNCTIONS_LIST = 'Functions list' +PACKAGE = 'Package' +ARCHITECTURE = 'Architecture' +THREAD_MODE = 'Thread mode' +THREADING_LAYER = 'Threading layer' +CUSTOM_CPU_SET = 'Custom CPU set' +PREFIX = 'Prefix' + +CONFIGS = { + CUSTOM_LIBRARY_NAME : 'custom_library', + BUILD_SCRIPT_NAME : '', + OUTPUT_PATH : '.', + FUNCTIONS_LIST : [], + PACKAGE : '', + ARCHITECTURE : '', + THREAD_MODE : '', + THREADING_LAYER : '', + CUSTOM_CPU_SET : [], + PREFIX : '' +} + +IPP = 'IPP' +IPPCP = 'IPPCP' + +IPPROOT = 'IPPROOT' +IPPCRYPTOROOT = 'IPPCRYPTOROOT' + +PACKAGE_NAME = { + IPP : 'Intel(R) Integrated Performance Primitives', + IPPCP : 'Intel(R) Integrated Performance Primitives Cryptography' +} + +DOMAINS = { + IPP: { + 'ippcc' : 'Color Conversion', + 'ippch' : 'String Operations', + 'ippcv' : 'Computer Vision', + 'ippdc' : 'Data Compression', + 'ippe' : 'Embedded Functionality', + 'ippi' : 'Image Processing', + 'ipps' : 'Signal Processing', + 'ippvm' : 'Vector Math', + 'ippcore' : 'Core' + }, + IPPCP: { + 'ippcp' : 'Cryptography' + }, + THREADING_LAYER: { + 'ippcc' : 'Color Conversion TL', + 'ippcv' : 'Computer Vision TL', + 'ippi' : 'Image Processing TL', + 'ippcore' : 'Core TL' + } +} + +SSE2 = 'sse2' +SSE3 = 'sse3' +SSSE3 = 'ssse3' +SSE42 = 'sse42' +AVX = 'avx' +AVX2 = 'avx2' +AVX512F = 'avx512f' +AVX512BW = 'avx512bw' +AVX512IFMA = 'avx512ifma' + +CPU = { + SSE2: { + IA32 : 'w7', + INTEL64 : '' + }, + SSE3: { + IA32 : '', + INTEL64 : 'm7' + }, + SSSE3: { + IA32 : 's8', + INTEL64 : 'n8' + }, + SSE42: { + IA32 : 'p8', + INTEL64 : 'y8' + }, + AVX: { + IA32 : 'g9', + INTEL64 : 'e9' + }, + AVX2: { + IA32 : 'h9', + INTEL64 : 'l9' + }, + AVX512F: { + IA32 : '', + INTEL64 : 'n0' + }, + AVX512BW: { + IA32 : '', + INTEL64 : 'k0' + }, + AVX512IFMA: { + IA32 : '', + INTEL64 : 'k1' + } +} + +SUPPORTED_CPUS = { + IPP: { + IA32: { + WINDOWS : [SSE2, SSSE3, SSE42, AVX, AVX2], + LINUX : [SSE2, SSSE3, SSE42, AVX, AVX2], + MACOSX : [] + }, + INTEL64: { + WINDOWS : [SSE3, SSSE3, SSE42, AVX, AVX2, AVX512BW], + LINUX : [SSE3, SSSE3, SSE42, AVX, AVX2, AVX512F, AVX512BW], + MACOSX : [SSE42, AVX, AVX2, AVX512BW] + } + }, + IPPCP: { + IA32: { + WINDOWS : [SSE2, SSSE3, SSE42, AVX, AVX2], + LINUX : [SSE2, SSSE3, SSE42, AVX, AVX2], + MACOSX : [] + }, + INTEL64: { + WINDOWS : [SSE3, SSSE3, SSE42, AVX, AVX2, AVX512BW, AVX512IFMA], + LINUX : [SSE3, SSSE3, SSE42, AVX, AVX2, AVX512F, AVX512BW, AVX512IFMA], + MACOSX : [SSE42, AVX, AVX2, AVX512BW, AVX512IFMA] + } + } +} + +CPUID = { + AVX512IFMA : 'AVX3I_FEATURES', + AVX512BW : 'AVX3X_FEATURES', + AVX512F : 'AVX3M_FEATURES', + AVX2 : 'ippCPUID_AVX2', + AVX : 'ippCPUID_AVX', + SSE42 : 'ippCPUID_SSE42', + SSSE3 : 'ippCPUID_SSSE3', + SSE3 : 'ippCPUID_SSE3', + SSE2 : 'ippCPUID_SSE2', +} + +PATH_TO_LIBRARIES = { + SINGLE_THREADED : '{libs_arch_dir}', + MULTI_THREADED : '{libs_arch_dir}/threaded', + TBB : '{libs_arch_dir}/tl/' + TBB, + OPENMP : '{libs_arch_dir}/tl/' + OPENMP +} + +LIB_PREFIX = { + WINDOWS : '', + LINUX : 'lib', + MACOSX : 'lib' +} + +LIB_POSTFIX = { + SINGLE_THREADED : '', + MULTI_THREADED : '', + TBB: '_tl_tbb', + OPENMP: '_tl_omp' +} + +STATIC_LIB_POSTFIX = { + WINDOWS : 'mt', + LINUX : '', + MACOSX : '' +} + +STATIC_LIB_EXTENSION = { + WINDOWS : '.lib', + LINUX : '.a', + MACOSX : '.a' +} + +DYNAMIC_LIB_EXTENSION = { + WINDOWS : '.dll', + LINUX : '.so', + MACOSX : '.dylib' +} + +BUILD_SCRIPT_NAME_FORMAT = { + WINDOWS : 'build_{name}_{arch}.bat', + LINUX : 'build_{name}_{arch}.sh', + MACOSX : 'build_{name}_{arch}.sh' +} + +BATCH_EXTENSIONS = { + WINDOWS : '.bat', + LINUX : '.sh', + MACOSX : '.sh' +} + +MAIN_FILE_NAME = 'main.c' +CUSTOM_DISPATCHER_FILE_NAME = '{function}.c' +RENAME_HEADER_NAME = 'rename.h' + +EXPORT_FILE = { + WINDOWS : 'export.def', + LINUX : 'export.def', + MACOSX : 'export.lib-export' +} + +PROJECT_EXTENSION = '.cltproj' + +HAVE_PACKAGE = 'package...' +HAVE_FUNCTIONS = 'functions that has to be in dynamic library... ' + +ENABLE_GENERATION_RULES = { + HAVE_PACKAGE : True, + HAVE_FUNCTIONS : True, +} + + +def set_host_system(): + host_system = system() + + if host_system == 'Darwin': + host_system = MACOSX + if host_system not in SUPPORTED_SYSTEMS: + sys.exit("Error: Intel(R) Integrated Performance Primitives Custom Library Tool isn't supported for OS " + + host_system) + + global HOST_SYSTEM + HOST_SYSTEM = host_system + + +def set_configs_dict(package, + functions_list, + architecture, + thread_mode, + threading_layer_type, + custom_library_name=CONFIGS[CUSTOM_LIBRARY_NAME], + build_script_name=CONFIGS[BUILD_SCRIPT_NAME], + output_path=CONFIGS[OUTPUT_PATH], + custom_cpu_set=CONFIGS[CUSTOM_CPU_SET], + prefix=CONFIGS[PREFIX]): + CONFIGS[CUSTOM_LIBRARY_NAME] = custom_library_name + CONFIGS[OUTPUT_PATH] = output_path + CONFIGS[FUNCTIONS_LIST] = functions_list + CONFIGS[PACKAGE] = package + CONFIGS[ARCHITECTURE] = architecture + CONFIGS[THREAD_MODE] = thread_mode + CONFIGS[THREADING_LAYER] = threading_layer_type + CONFIGS[CUSTOM_CPU_SET] = custom_cpu_set + CONFIGS[PREFIX] = prefix + + if not build_script_name: + build_script_name = BUILD_SCRIPT_NAME_FORMAT[HOST_SYSTEM].format(name=custom_library_name, arch=architecture) + CONFIGS[BUILD_SCRIPT_NAME] = build_script_name + + +def get_first_existing_path_in_list(paths_list): + for path in paths_list: + if os.path.exists(path): + return path + return '' + + +def get_lines_from_file(file_path): + if os.path.exists(file_path): + with open(file_path, 'r') as file: + return file.readlines() + else: + return [] + + +def get_env(env_var): + return os.environ[env_var] if os.getenv(env_var) and os.path.exists(os.environ[env_var]) else '' + + +def get_match(regex, string, group): + return re.match(regex, string).group(group) if re.compile(regex).match(string) else '' + + +def nested_dict_init(): + return defaultdict(lambda: defaultdict()) + + +def walk_dict(dictionary): + for key, value in dictionary.items(): + if type(value) == type(dict()) or type(value) == type(defaultdict()): + for entire in walk_dict(value): + yield (key,) + entire + elif type(value) == type(list()): + for elem in value: + yield key, elem + else: + yield key, value + + +def get_dict_value(dictionary, key): + return dictionary[key] if key in dictionary.keys() else dictionary['default']